diff --git a/.dir-locals.el b/.dir-locals.el index d8827a669a4..ab6208b6983 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -5,11 +5,11 @@ (fill-column . 78) (indent-tabs-mode . t) (tab-width . 4))) - (dsssl-mode . ((indent-tabs-mode . nil))) - (nxml-mode . ((indent-tabs-mode . nil))) + (nxml-mode . ((fill-column . 78) + (indent-tabs-mode . nil))) (perl-mode . ((perl-indent-level . 4) - (perl-continued-statement-offset . 4) - (perl-continued-brace-offset . 4) + (perl-continued-statement-offset . 2) + (perl-continued-brace-offset . -2) (perl-brace-offset . 0) (perl-brace-imaginary-offset . 0) (perl-label-offset . -2) diff --git a/.gitattributes b/.gitattributes index bdbcdb560af..3ac99972812 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,7 +14,6 @@ README.* conflict-marker-size=32 # Certain data files that contain special whitespace, and other special cases *.data -whitespace contrib/pgcrypto/sql/pgp-armor.sql whitespace=-blank-at-eol -doc/bug.template whitespace=space-before-tab,-blank-at-eof,blank-at-eol src/backend/catalog/sql_features.txt whitespace=space-before-tab,blank-at-eof,-blank-at-eol # Test output files that contain extra whitespace diff --git a/COPYRIGHT b/COPYRIGHT index 33e6e4842ad..fe7c3857327 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,7 +1,7 @@ PostgreSQL Database Management System (formerly known as Postgres, then as Postgres95) -Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group Portions Copyright (c) 1994, The Regents of the University of California diff --git a/GNUmakefile.in b/GNUmakefile.in index dc76a5d11dd..9dc373c79cc 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -63,10 +63,12 @@ distclean maintainer-clean: @rm -rf autom4te.cache/ rm -f config.cache config.log config.status GNUmakefile -check check-tests installcheck installcheck-parallel installcheck-tests: +check check-tests installcheck installcheck-parallel installcheck-tests: CHECKPREP_TOP=src/test/regress +check check-tests installcheck installcheck-parallel installcheck-tests: submake-generated-headers $(MAKE) -C src/test/regress $@ $(call recurse,check-world,src/test src/pl src/interfaces/ecpg contrib src/bin,check) +$(call recurse,checkprep, src/test src/pl src/interfaces/ecpg contrib src/bin) $(call recurse,installcheck-world,src/test src/pl src/interfaces/ecpg contrib src/bin,installcheck) @@ -78,7 +80,6 @@ GNUmakefile: GNUmakefile.in $(top_builddir)/config.status distdir = postgresql-$(VERSION) dummy = =install= -garbage = =* "#"* ."#"* *~* *.orig *.rej core postgresql-* dist: $(distdir).tar.gz $(distdir).tar.bz2 rm -rf $(distdir) @@ -127,4 +128,10 @@ distcheck: dist rm -rf $(distdir) $(dummy) @echo "Distribution integrity checks out." -.PHONY: dist distdir distcheck docs install-docs world check-world install-world installcheck-world +headerscheck: submake-generated-headers + $(top_srcdir)/src/tools/pginclude/headerscheck $(top_srcdir) $(abs_top_builddir) + +cpluspluscheck: submake-generated-headers + $(top_srcdir)/src/tools/pginclude/cpluspluscheck $(top_srcdir) $(abs_top_builddir) + +.PHONY: dist distdir distcheck docs install-docs world check-world install-world installcheck-world headerscheck cpluspluscheck diff --git a/Makefile b/Makefile index c400854cd3d..99dcfff654d 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ all check install installdirs installcheck installcheck-parallel uninstall clean \ if [ x"$${GMAKE+set}" = xset ]; then \ echo "Using GNU make found at $${GMAKE}"; \ - unset MAKEFLAGS; unset MAKELEVEL; \ + unset MAKELEVEL; \ $${GMAKE} $@ ; \ else \ echo "You must use GNU make to build PostgreSQL." ; \ diff --git a/aclocal.m4 b/aclocal.m4 index a517e949f15..bfd34ecec8c 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -4,6 +4,7 @@ m4_include([config/ax_prog_perl_modules.m4]) m4_include([config/ax_pthread.m4]) m4_include([config/c-compiler.m4]) m4_include([config/c-library.m4]) +m4_include([config/check_decls.m4]) m4_include([config/docbook.m4]) m4_include([config/general.m4]) m4_include([config/libtool.m4]) diff --git a/config/ac_func_accept_argtypes.m4 b/config/ac_func_accept_argtypes.m4 index ee28bacf4b0..178ef678183 100644 --- a/config/ac_func_accept_argtypes.m4 +++ b/config/ac_func_accept_argtypes.m4 @@ -43,8 +43,8 @@ AC_DEFUN([AC_FUNC_ACCEPT_ARGTYPES], [AC_CACHE_VAL(ac_cv_func_accept_arg1,dnl [AC_CACHE_VAL(ac_cv_func_accept_arg2,dnl [AC_CACHE_VAL(ac_cv_func_accept_arg3,dnl - [for ac_cv_func_accept_return in 'int' 'unsigned int PASCAL' 'SOCKET WSAAPI'; do - for ac_cv_func_accept_arg1 in 'int' 'unsigned int' 'SOCKET'; do + [for ac_cv_func_accept_return in 'int' 'SOCKET WSAAPI' 'unsigned int PASCAL'; do + for ac_cv_func_accept_arg1 in 'int' 'SOCKET' 'unsigned int'; do for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do AC_COMPILE_IFELSE([AC_LANG_SOURCE( diff --git a/config/ax_pthread.m4 b/config/ax_pthread.m4 index f6445a6ffa8..5fbf9fe0d68 100644 --- a/config/ax_pthread.m4 +++ b/config/ax_pthread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS @@ -19,10 +19,10 @@ # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" @@ -30,8 +30,8 @@ # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -67,7 +67,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see . +# with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -82,12 +82,13 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 21 +#serial 24 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no @@ -98,20 +99,23 @@ ax_pthread_ok=no # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) - if test x"$ax_pthread_ok" = xno; then + if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -124,7 +128,7 @@ fi # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -133,14 +137,14 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 -# -pthreads: Solaris/gcc +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which -# is present but should not be used directly) +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ @@ -148,6 +152,14 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt case $host_os in + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable @@ -174,42 +186,144 @@ case $host_os in solaris*) - # Newer versions of Solaris require the "-mt -lpthread" pair, and we - # check that first. On some older versions, libc contains stubbed + # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So - # we'll look for -pthreads and -lpthread shortly thereafter. + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-mt,pthread -pthreads -pthread pthread $ax_pthread_flags" + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" ;; esac -# Older versions of Clang only give a warning instead of an error for an -# unrecognized option, unless we specify -Werror. (We throw in some extra -# Clang warning flags for good measure.) - -AC_CACHE_CHECK([if compiler needs certain flags to reject unknown flags], - [ax_cv_PTHREAD_REJECT_UNKNOWN], - [ax_cv_PTHREAD_REJECT_UNKNOWN=unknown - save_CFLAGS="$CFLAGS" - ax_pthread_extra_flags="-Wunknown-warning-option -Wunused-command-line-argument" - CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wfoobaz -foobaz" - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], - [ax_cv_PTHREAD_REJECT_UNKNOWN="-Werror $ax_pthread_extra_flags"], - [ax_cv_PTHREAD_REJECT_UNKNOWN=no]) - CFLAGS="$save_CFLAGS" +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi ]) -ax_pthread_extra_flags= -AS_IF([test "x$ax_cv_PTHREAD_REJECT_UNKNOWN" != "xno"], - [ax_pthread_extra_flags="$ax_cv_PTHREAD_REJECT_UNKNOWN"]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +fi # $ax_pthread_clang = yes - case $flag in +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; @@ -221,27 +335,27 @@ for flag in $ax_pthread_flags; do ;; -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) - if test x"$ax_pthread_config" = xno; then continue; fi + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we @@ -252,7 +366,11 @@ for flag in $ax_pthread_flags; do # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; @@ -261,16 +379,14 @@ for flag in $ax_pthread_flags; do pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) + [ax_pthread_ok=yes], + []) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) - if test "x$ax_pthread_ok" = xyes; then - break; - fi + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" @@ -278,49 +394,41 @@ done fi # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [ax_cv_PTHREAD_JOINABLE_ATTR=$attr; break], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) - AS_IF([test "$ax_cv_PTHREAD_JOINABLE_ATTR" != unknown && \ - test "$ax_cv_PTHREAD_JOINABLE_ATTR" != PTHREAD_CREATE_JOINABLE], + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant - uses a non-standard name on your system.])]) + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) - AC_CACHE_CHECK([if more special flags are required for pthreads], + AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no - ax_pthread_special_flags_added=no - AC_EGREP_CPP([AX_PTHREAD_NEED_SPECIAL_FLAG], - [ -# if !defined(_REENTRANT) && !defined(_THREAD_SAFE) - AX_PTHREAD_NEED_SPECIAL_FLAG -# endif - ], - [case $host_os in - aix* | freebsd*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_THREAD_SAFE" - ;; - darwin* | hpux* | osf* | solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_REENTRANT" - ;; - esac - ]) + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], @@ -334,23 +442,26 @@ if test "x$ax_pthread_ok" = xyes; then [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then + if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], - [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], - [#handle absolute path differently from PATH based program lookup - AS_CASE(["x$CC"], - [x/*], - [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], - [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi @@ -363,7 +474,7 @@ AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then +if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 index ba5c40db01c..71b645839db 100644 --- a/config/c-compiler.m4 +++ b/config/c-compiler.m4 @@ -19,24 +19,38 @@ fi])# PGAC_C_SIGNED # PGAC_C_PRINTF_ARCHETYPE # ----------------------- -# Set the format archetype used by gcc to check printf type functions. We -# prefer "gnu_printf", which includes what glibc uses, such as %m for error -# strings and %lld for 64 bit long longs. GCC 4.4 introduced it. It makes a -# dramatic difference on Windows. +# Select the format archetype to be used by gcc to check printf-type functions. +# We prefer "gnu_printf", as that most closely matches the features supported +# by src/port/snprintf.c (particularly the %m conversion spec). However, +# on some NetBSD versions, that doesn't work while "__syslog__" does. +# If all else fails, use "printf". AC_DEFUN([PGAC_PRINTF_ARCHETYPE], [AC_CACHE_CHECK([for printf format archetype], pgac_cv_printf_archetype, +[pgac_cv_printf_archetype=gnu_printf +PGAC_TEST_PRINTF_ARCHETYPE +if [[ "$ac_archetype_ok" = no ]]; then + pgac_cv_printf_archetype=__syslog__ + PGAC_TEST_PRINTF_ARCHETYPE + if [[ "$ac_archetype_ok" = no ]]; then + pgac_cv_printf_archetype=printf + fi +fi]) +AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype], +[Define to best printf format archetype, usually gnu_printf if available.]) +])# PGAC_PRINTF_ARCHETYPE + +# Subroutine: test $pgac_cv_printf_archetype, set $ac_archetype_ok to yes or no +AC_DEFUN([PGAC_TEST_PRINTF_ARCHETYPE], [ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes AC_COMPILE_IFELSE([AC_LANG_PROGRAM( -[extern int -pgac_write(int ignore, const char *fmt,...) -__attribute__((format(gnu_printf, 2, 3)));], [])], - [pgac_cv_printf_archetype=gnu_printf], - [pgac_cv_printf_archetype=printf]) -ac_c_werror_flag=$ac_save_c_werror_flag]) -AC_DEFINE_UNQUOTED([PG_PRINTF_ATTRIBUTE], [$pgac_cv_printf_archetype], - [Define to gnu_printf if compiler supports it, else printf.]) -])# PGAC_PRINTF_ARCHETYPE +[extern void pgac_write(int ignore, const char *fmt,...) +__attribute__((format($pgac_cv_printf_archetype, 2, 3)));], +[pgac_write(0, "error %s: %m", "foo");])], + [ac_archetype_ok=yes], + [ac_archetype_ok=no]) +ac_c_werror_flag=$ac_save_c_werror_flag +])# PGAC_TEST_PRINTF_ARCHETYPE # PGAC_TYPE_64BIT_INT(TYPE) @@ -259,60 +273,6 @@ AC_DEFINE(HAVE__BUILTIN_TYPES_COMPATIBLE_P, 1, fi])# PGAC_C_TYPES_COMPATIBLE -# PGAC_C_BUILTIN_BSWAP16 -# ------------------------- -# Check if the C compiler understands __builtin_bswap16(), -# and define HAVE__BUILTIN_BSWAP16 if so. -AC_DEFUN([PGAC_C_BUILTIN_BSWAP16], -[AC_CACHE_CHECK(for __builtin_bswap16, pgac_cv__builtin_bswap16, -[AC_COMPILE_IFELSE([AC_LANG_SOURCE( -[static unsigned long int x = __builtin_bswap16(0xaabb);] -)], -[pgac_cv__builtin_bswap16=yes], -[pgac_cv__builtin_bswap16=no])]) -if test x"$pgac_cv__builtin_bswap16" = xyes ; then -AC_DEFINE(HAVE__BUILTIN_BSWAP16, 1, - [Define to 1 if your compiler understands __builtin_bswap16.]) -fi])# PGAC_C_BUILTIN_BSWAP16 - - - -# PGAC_C_BUILTIN_BSWAP32 -# ------------------------- -# Check if the C compiler understands __builtin_bswap32(), -# and define HAVE__BUILTIN_BSWAP32 if so. -AC_DEFUN([PGAC_C_BUILTIN_BSWAP32], -[AC_CACHE_CHECK(for __builtin_bswap32, pgac_cv__builtin_bswap32, -[AC_COMPILE_IFELSE([AC_LANG_SOURCE( -[static unsigned long int x = __builtin_bswap32(0xaabbccdd);] -)], -[pgac_cv__builtin_bswap32=yes], -[pgac_cv__builtin_bswap32=no])]) -if test x"$pgac_cv__builtin_bswap32" = xyes ; then -AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1, - [Define to 1 if your compiler understands __builtin_bswap32.]) -fi])# PGAC_C_BUILTIN_BSWAP32 - - - -# PGAC_C_BUILTIN_BSWAP64 -# ------------------------- -# Check if the C compiler understands __builtin_bswap64(), -# and define HAVE__BUILTIN_BSWAP64 if so. -AC_DEFUN([PGAC_C_BUILTIN_BSWAP64], -[AC_CACHE_CHECK(for __builtin_bswap64, pgac_cv__builtin_bswap64, -[AC_COMPILE_IFELSE([AC_LANG_SOURCE( -[static unsigned long int x = __builtin_bswap64(0xaabbccddeeff0011);] -)], -[pgac_cv__builtin_bswap64=yes], -[pgac_cv__builtin_bswap64=no])]) -if test x"$pgac_cv__builtin_bswap64" = xyes ; then -AC_DEFINE(HAVE__BUILTIN_BSWAP64, 1, - [Define to 1 if your compiler understands __builtin_bswap64.]) -fi])# PGAC_C_BUILTIN_BSWAP64 - - - # PGAC_C_BUILTIN_CONSTANT_P # ------------------------- # Check if the C compiler understands __builtin_constant_p(), @@ -409,22 +369,30 @@ fi])# PGAC_C_COMPUTED_GOTO -# PGAC_C_VA_ARGS -# -------------- -# Check if the C compiler understands C99-style variadic macros, -# and define HAVE__VA_ARGS if so. -AC_DEFUN([PGAC_C_VA_ARGS], -[AC_CACHE_CHECK(for __VA_ARGS__, pgac_cv__va_args, -[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], -[#define debug(...) fprintf(stderr, __VA_ARGS__) -debug("%s", "blarg"); -])], -[pgac_cv__va_args=yes], -[pgac_cv__va_args=no])]) -if test x"$pgac_cv__va_args" = xyes ; then -AC_DEFINE(HAVE__VA_ARGS, 1, - [Define to 1 if your compiler understands __VA_ARGS__ in macros.]) -fi])# PGAC_C_VA_ARGS +# PGAC_CHECK_BUILTIN_FUNC +# ----------------------- +# This is similar to AC_CHECK_FUNCS(), except that it will work for compiler +# builtin functions, as that usually fails to. +# The first argument is the function name, eg [__builtin_clzl], and the +# second is its argument list, eg [unsigned long x]. The current coding +# works only for a single argument named x; we might generalize that later. +# It's assumed that the function's result type is coercible to int. +# On success, we define "HAVEfuncname" (there's usually more than enough +# underscores already, so we don't add another one). +AC_DEFUN([PGAC_CHECK_BUILTIN_FUNC], +[AC_CACHE_CHECK(for $1, pgac_cv$1, +[AC_LINK_IFELSE([AC_LANG_PROGRAM([ +int +call$1($2) +{ + return $1(x); +}], [])], +[pgac_cv$1=yes], +[pgac_cv$1=no])]) +if test x"${pgac_cv$1}" = xyes ; then +AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE$1]), 1, + [Define to 1 if your compiler understands $1.]) +fi])# PGAC_CHECK_BUILTIN_FUNC @@ -588,7 +556,7 @@ AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT32_CAS], [pgac_cv_gcc_sync_int32_cas="yes"], [pgac_cv_gcc_sync_int32_cas="no"])]) if test x"$pgac_cv_gcc_sync_int32_cas" = x"yes"; then - AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int *, int, int).]) + AC_DEFINE(HAVE_GCC__SYNC_INT32_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int *, int, int).]) fi])# PGAC_HAVE_GCC__SYNC_INT32_CAS # PGAC_HAVE_GCC__SYNC_INT64_CAS @@ -603,7 +571,7 @@ AC_DEFUN([PGAC_HAVE_GCC__SYNC_INT64_CAS], [pgac_cv_gcc_sync_int64_cas="yes"], [pgac_cv_gcc_sync_int64_cas="no"])]) if test x"$pgac_cv_gcc_sync_int64_cas" = x"yes"; then - AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_compare_and_swap(int64 *, int64, int64).]) + AC_DEFINE(HAVE_GCC__SYNC_INT64_CAS, 1, [Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64).]) fi])# PGAC_HAVE_GCC__SYNC_INT64_CAS # PGAC_HAVE_GCC__ATOMIC_INT32_CAS @@ -635,7 +603,7 @@ AC_DEFUN([PGAC_HAVE_GCC__ATOMIC_INT64_CAS], [pgac_cv_gcc_atomic_int64_cas="yes"], [pgac_cv_gcc_atomic_int64_cas="no"])]) if test x"$pgac_cv_gcc_atomic_int64_cas" = x"yes"; then - AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int *, int64).]) + AC_DEFINE(HAVE_GCC__ATOMIC_INT64_CAS, 1, [Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, int64).]) fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS # PGAC_SSE42_CRC32_INTRINSICS diff --git a/config/c-library.m4 b/config/c-library.m4 index 34b25081a6e..6f2b0fbb4e6 100644 --- a/config/c-library.m4 +++ b/config/c-library.m4 @@ -82,23 +82,23 @@ AH_VERBATIM(GETTIMEOFDAY_1ARG_, # PGAC_FUNC_STRERROR_R_INT # --------------------------- -# Check if strerror_r() returns an int (SUSv3) rather than a char * (GNU libc) -# If so, define STRERROR_R_INT +# Check if strerror_r() returns int (POSIX) rather than char * (GNU libc). +# If so, define STRERROR_R_INT. +# The result is uncertain if strerror_r() isn't provided, +# but we don't much care. AC_DEFUN([PGAC_FUNC_STRERROR_R_INT], [AC_CACHE_CHECK(whether strerror_r returns int, pgac_cv_func_strerror_r_int, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], -[#ifndef _AIX -int strerror_r(int, char *, size_t); -#else -/* Older AIX has 'int' for the third argument so we don't test the args. */ -int strerror_r(); -#endif])], +[[char buf[100]; + switch (strerror_r(1, buf, sizeof(buf))) + { case 0: break; default: break; } +]])], [pgac_cv_func_strerror_r_int=yes], [pgac_cv_func_strerror_r_int=no])]) if test x"$pgac_cv_func_strerror_r_int" = xyes ; then AC_DEFINE(STRERROR_R_INT, 1, - [Define to 1 if strerror_r() returns a int.]) + [Define to 1 if strerror_r() returns int.]) fi ])# PGAC_FUNC_STRERROR_R_INT @@ -171,129 +171,6 @@ AC_DEFUN([PGAC_STRUCT_ADDRINFO], ])])# PGAC_STRUCT_ADDRINFO -# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER -# --------------------------------------- -# Determine which length modifier snprintf uses for long long int. We -# handle ll, q, and I64. The result is in shell variable -# LONG_LONG_INT_MODIFIER. -# -# MinGW uses '%I64d', though gcc throws a warning with -Wall, -# while '%lld' doesn't generate a warning, but doesn't work. -# -AC_DEFUN([PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER], -[AC_MSG_CHECKING([snprintf length modifier for long long int]) -AC_CACHE_VAL(pgac_cv_snprintf_long_long_int_modifier, -[for pgac_modifier in 'll' 'q' 'I64'; do -AC_RUN_IFELSE([AC_LANG_SOURCE([[#include -#include -typedef long long int ac_int64; -#define INT64_FORMAT "%${pgac_modifier}d" - -ac_int64 a = 20000001; -ac_int64 b = 40000005; - -int does_int64_snprintf_work() -{ - ac_int64 c; - char buf[100]; - - if (sizeof(ac_int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} - -int -main() { - return (! does_int64_snprintf_work()); -}]])], -[pgac_cv_snprintf_long_long_int_modifier=$pgac_modifier; break], -[], -[pgac_cv_snprintf_long_long_int_modifier=cross; break]) -done])dnl AC_CACHE_VAL - -LONG_LONG_INT_MODIFIER='' - -case $pgac_cv_snprintf_long_long_int_modifier in - cross) AC_MSG_RESULT([cannot test (not on host machine)]);; - ?*) AC_MSG_RESULT([$pgac_cv_snprintf_long_long_int_modifier]) - LONG_LONG_INT_MODIFIER=$pgac_cv_snprintf_long_long_int_modifier;; - *) AC_MSG_RESULT(none);; -esac])# PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER - - -# PGAC_FUNC_SNPRINTF_ARG_CONTROL -# --------------------------------------- -# Determine if snprintf supports %1$ argument selection, e.g. %5$ selects -# the fifth argument after the printf format string. -# This is not in the C99 standard, but in the Single Unix Specification (SUS). -# It is used in our language translation strings. -# -AC_DEFUN([PGAC_FUNC_SNPRINTF_ARG_CONTROL], -[AC_MSG_CHECKING([whether snprintf supports argument control]) -AC_CACHE_VAL(pgac_cv_snprintf_arg_control, -[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include -#include - -int main() -{ - char buf[100]; - - /* can it swap arguments? */ - snprintf(buf, 100, "%2\$d %1\$d", 3, 4); - if (strcmp(buf, "4 3") != 0) - return 1; - return 0; -}]])], -[pgac_cv_snprintf_arg_control=yes], -[pgac_cv_snprintf_arg_control=no], -[pgac_cv_snprintf_arg_control=cross]) -])dnl AC_CACHE_VAL -AC_MSG_RESULT([$pgac_cv_snprintf_arg_control]) -])# PGAC_FUNC_SNPRINTF_ARG_CONTROL - -# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT -# --------------------------------------- -# Determine if snprintf supports the z length modifier for printing -# size_t-sized variables. That's supported by C99 and POSIX but not -# all platforms play ball, so we must test whether it's working. -# -AC_DEFUN([PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT], -[AC_MSG_CHECKING([whether snprintf supports the %z modifier]) -AC_CACHE_VAL(pgac_cv_snprintf_size_t_support, -[AC_RUN_IFELSE([AC_LANG_SOURCE([[#include -#include - -int main() -{ - char bufz[100]; - char buf64[100]; - - /* - * Print the largest unsigned number fitting in a size_t using both %zu - * and the previously-determined format for 64-bit integers. Note that - * we don't run this code unless we know snprintf handles 64-bit ints. - */ - bufz[0] = '\0'; /* in case snprintf fails to emit anything */ - snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0)); - snprintf(buf64, sizeof(buf64), "%" INT64_MODIFIER "u", - (unsigned PG_INT64_TYPE) ~((size_t) 0)); - if (strcmp(bufz, buf64) != 0) - return 1; - return 0; -}]])], -[pgac_cv_snprintf_size_t_support=yes], -[pgac_cv_snprintf_size_t_support=no], -[pgac_cv_snprintf_size_t_support=cross]) -])dnl AC_CACHE_VAL -AC_MSG_RESULT([$pgac_cv_snprintf_size_t_support]) -])# PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT - - # PGAC_TYPE_LOCALE_T # ------------------ # Check for the locale_t type and find the right header file. macOS diff --git a/config/check_decls.m4 b/config/check_decls.m4 new file mode 100644 index 00000000000..f1b90c54301 --- /dev/null +++ b/config/check_decls.m4 @@ -0,0 +1,116 @@ +# config/check_decls.m4 + +# This file redefines the standard Autoconf macro _AC_CHECK_DECL_BODY, +# and adds a supporting function _AC_UNDECLARED_WARNING, to make +# AC_CHECK_DECLS behave correctly when checking for built-in library +# functions with clang. + +# This is based on commit 82ef7805faffa151e724aa76c245ec590d174580 +# in the Autoconf git repository. We can drop it if they ever get +# around to releasing a new version of Autoconf. In the meantime, +# it's distributed under Autoconf's license: + +# This file is part of Autoconf. This program is free +# software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# Under Section 7 of GPL version 3, you are granted additional +# permissions described in the Autoconf Configure Script Exception, +# version 3.0, as published by the Free Software Foundation. +# +# You should have received a copy of the GNU General Public License +# and a copy of the Autoconf Configure Script Exception along with +# this program; see the files COPYINGv3 and COPYING.EXCEPTION +# respectively. If not, see . + +# Written by David MacKenzie, with help from +# Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, +# Roland McGrath, Noah Friedman, david d zuhn, and many others. + + +# _AC_UNDECLARED_WARNING +# ---------------------- +# Set ac_[]_AC_LANG_ABBREV[]_decl_warn_flag=yes if the compiler uses a warning, +# not a more-customary error, to report some undeclared identifiers. Fail when +# an affected compiler warns also on valid input. _AC_PROG_PREPROC_WORKS_IFELSE +# solves a related problem. +AC_DEFUN([_AC_UNDECLARED_WARNING], +[# The Clang compiler raises a warning for an undeclared identifier that matches +# a compiler builtin function. All extant Clang versions are affected, as of +# Clang 3.6.0. Test a builtin known to every version. This problem affects the +# C and Objective C languages, but Clang does report an error under C++ and +# Objective C++. +# +# Passing -fno-builtin to the compiler would suppress this problem. That +# strategy would have the advantage of being insensitive to stray warnings, but +# it would make tests less realistic. +AC_CACHE_CHECK([how $[]_AC_CC[] reports undeclared, standard C functions], +[ac_cv_[]_AC_LANG_ABBREV[]_decl_report], +[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [(void) strchr;])], + [AS_IF([test -s conftest.err], [dnl + # For AC_CHECK_DECL to react to warnings, the compiler must be silent on + # valid AC_CHECK_DECL input. No library function is consistently available + # on freestanding implementations, so test against a dummy declaration. + # Include always-available headers on the off chance that they somehow + # elicit warnings. + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([dnl +#include +#include +#include +#include +extern void ac_decl (int, char *);], +[@%:@ifdef __cplusplus + (void) ac_decl ((int) 0, (char *) 0); + (void) ac_decl; +@%:@else + (void) ac_decl; +@%:@endif +])], + [AS_IF([test -s conftest.err], + [AC_MSG_FAILURE([cannot detect from compiler exit status or warnings])], + [ac_cv_[]_AC_LANG_ABBREV[]_decl_report=warning])], + [AC_MSG_FAILURE([cannot compile a simple declaration test])])], + [AC_MSG_FAILURE([compiler does not report undeclared identifiers])])], + [ac_cv_[]_AC_LANG_ABBREV[]_decl_report=error])]) + +case $ac_cv_[]_AC_LANG_ABBREV[]_decl_report in + warning) ac_[]_AC_LANG_ABBREV[]_decl_warn_flag=yes ;; + *) ac_[]_AC_LANG_ABBREV[]_decl_warn_flag= ;; +esac +])# _AC_UNDECLARED_WARNING + +# _AC_CHECK_DECL_BODY +# ------------------- +# Shell function body for AC_CHECK_DECL. +m4_define([_AC_CHECK_DECL_BODY], +[ AS_LINENO_PUSH([$[]1]) + # Initialize each $ac_[]_AC_LANG_ABBREV[]_decl_warn_flag once. + AC_DEFUN([_AC_UNDECLARED_WARNING_]_AC_LANG_ABBREV, + [_AC_UNDECLARED_WARNING])dnl + AC_REQUIRE([_AC_UNDECLARED_WARNING_]_AC_LANG_ABBREV)dnl + [as_decl_name=`echo $][2|sed 's/ *(.*//'`] + [as_decl_use=`echo $][2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`] + AC_CACHE_CHECK([whether $as_decl_name is declared], [$[]3], + [ac_save_werror_flag=$ac_[]_AC_LANG_ABBREV[]_werror_flag + ac_[]_AC_LANG_ABBREV[]_werror_flag="$ac_[]_AC_LANG_ABBREV[]_decl_warn_flag$ac_[]_AC_LANG_ABBREV[]_werror_flag" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$[]4], +[@%:@ifndef $[]as_decl_name +@%:@ifdef __cplusplus + (void) $[]as_decl_use; +@%:@else + (void) $[]as_decl_name; +@%:@endif +@%:@endif +])], + [AS_VAR_SET([$[]3], [yes])], + [AS_VAR_SET([$[]3], [no])]) + ac_[]_AC_LANG_ABBREV[]_werror_flag=$ac_save_werror_flag]) + AS_LINENO_POP +])# _AC_CHECK_DECL_BODY diff --git a/config/config.guess b/config/config.guess index faa63aa9429..79d1317f52b 100644 --- a/config/config.guess +++ b/config/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2017-05-11' +timestamp='2019-03-04' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-05-11' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2017-05-11' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,8 +84,6 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 - # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a @@ -96,34 +94,38 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$driver" + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi @@ -132,14 +134,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + set_cc_for_build + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +151,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,30 +178,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -208,10 +217,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -219,46 +228,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi-}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -310,28 +328,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -343,7 +352,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -370,19 +379,19 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build + set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. @@ -395,13 +404,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -410,25 +419,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -439,44 +448,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -485,23 +494,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -527,17 +536,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -554,7 +563,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -566,14 +575,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -584,7 +593,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -598,7 +607,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -607,18 +616,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -633,28 +642,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in + case "$sc_cpu_version" in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in + case "$sc_kernel_bits" in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -687,13 +696,13 @@ EOF exit (0); } EOF - (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = hppa2.0w ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -712,15 +721,15 @@ EOF HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -745,11 +754,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -758,7 +767,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -766,9 +775,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -793,128 +802,120 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi + else + echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf + fi exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin + echo x86_64-pc-cygwin exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + *:Minix:*:*) + echo "$UNAME_MACHINE"-unknown-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -928,140 +929,168 @@ EOF esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; k1om:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" exit ;; riscv32:Linux:*:* | riscv64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1075,34 +1104,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1112,12 +1141,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1127,9 +1156,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1149,9 +1178,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1171,9 +1200,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1182,28 +1211,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1214,7 +1243,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1234,23 +1263,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1269,49 +1298,56 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" exit ;; SX-ACE:SUPER-UX:*:*) - echo sxace-nec-superux${UNAME_RELEASE} + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub @@ -1322,7 +1358,7 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` @@ -1330,22 +1366,25 @@ EOF UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-*:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" exit ;; NSR-*:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" exit ;; NSX-*:NONSTOP_KERNEL:*:*) - echo nsx-tandem-nsk${UNAME_RELEASE} + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1354,18 +1393,19 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. + # shellcheck disable=SC2154 if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1386,14 +1426,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1402,32 +1442,171 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'` + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; + *:Unleashed:*:*) + echo "$UNAME_MACHINE"-unknown-unleashed"$UNAME_RELEASE" + exit ;; +esac + +# No uname command or uname output not recognized. +set_cc_for_build +cat > "$dummy.c" < +#include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); +#endif + +#if defined (vax) +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) /* >= ULTRIX4 */ + printf ("mips-dec-ultrix4\n"); exit (0); +#else +#if defined(ULTRIX3) || defined(ultrix3) || defined(SIGLOST) + printf ("mips-dec-ultrix3\n"); exit (0); +#endif +#endif +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config/config.sub b/config/config.sub index 40ea5dfe115..f53af5a2da7 100644 --- a/config/config.sub +++ b/config/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2017 Free Software Foundation, Inc. +# Copyright 1992-2019 Free Software Foundation, Inc. -timestamp='2017-04-02' +timestamp='2019-01-05' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2017-04-02' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2017-04-02' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -57,7 +57,7 @@ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2017 Free Software Foundation, Inc. +Copyright 1992-2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -89,12 +89,12 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -110,1252 +110,1167 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | cloudabi*-eabi* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + *-*-*-*) + basic_machine=$field1-$field2 + os=$field3-$field4 ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \ + | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + os=linux-android + ;; + *) + basic_machine=$field1-$field2 + os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + os= + ;; + *) + basic_machine=$field1 + os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + os=bsd + ;; + a29khif) + basic_machine=a29k-amd + os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=scout + ;; + alliant) + basic_machine=fx80-alliant + os= + ;; + altos | altos3068) + basic_machine=m68k-altos + os= + ;; + am29k) + basic_machine=a29k-none + os=bsd + ;; + amdahl) + basic_machine=580-amdahl + os=sysv + ;; + amiga) + basic_machine=m68k-unknown + os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=bsd + ;; + aros) + basic_machine=i386-pc + os=aros + ;; + aux) + basic_machine=m68k-apple + os=aux + ;; + balance) + basic_machine=ns32k-sequent + os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=linux + ;; + cegcc) + basic_machine=arm-unknown + os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=bsd + ;; + convex-c2) + basic_machine=c2-convex + os=bsd + ;; + convex-c32) + basic_machine=c32-convex + os=bsd + ;; + convex-c34) + basic_machine=c34-convex + os=bsd + ;; + convex-c38) + basic_machine=c38-convex + os=bsd + ;; + cray) + basic_machine=j90-cray + os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + os= + ;; + da30) + basic_machine=m68k-da30 + os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + os= + ;; + delta88) + basic_machine=m88k-motorola + os=sysv3 + ;; + dicos) + basic_machine=i686-pc + os=dicos + ;; + djgpp) + basic_machine=i586-pc + os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=ose + ;; + gmicro) + basic_machine=tron-gmicro + os=sysv + ;; + go32) + basic_machine=i386-pc + os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=hms + ;; + harris) + basic_machine=m88k-harris + os=sysv3 + ;; + hp300) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=hpux + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=proelf + ;; + i386mach) + basic_machine=i386-mach + os=mach + ;; + vsta) + basic_machine=i386-pc + os=vsta + ;; + isi68 | isi) + basic_machine=m68k-isi + os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=sysv + ;; + merlin) + basic_machine=ns32k-utek + os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + os=coff + ;; + morphos) + basic_machine=powerpc-unknown + os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=moxiebox + ;; + msdos) + basic_machine=i386-pc + os=msdos + ;; + msys) + basic_machine=i686-pc + os=msys + ;; + mvs) + basic_machine=i370-ibm + os=mvs + ;; + nacl) + basic_machine=le32-unknown + os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=newsos + ;; + news1000) + basic_machine=m68030-sony + os=newsos + ;; + necv70) + basic_machine=v70-nec + os=sysv + ;; + nh3000) + basic_machine=m68k-harris + os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=cxux + ;; + nindy960) + basic_machine=i960-intel + os=nindy + ;; + mon960) + basic_machine=i960-intel + os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=ose + ;; + os68k) + basic_machine=m68k-none + os=os68k + ;; + paragon) + basic_machine=i860-intel + os=osf + ;; + parisc) + basic_machine=hppa-unknown + os=linux + ;; + pw32) + basic_machine=i586-unknown + os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=rdos + ;; + rdos32) + basic_machine=i386-pc + os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=coff + ;; + sa29200) + basic_machine=a29k-amd + os=udi + ;; + sei) + basic_machine=mips-sei + os=seiux + ;; + sequent) + basic_machine=i386-sequent + os= + ;; + sps7) + basic_machine=m68k-bull + os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + os= + ;; + stratus) + basic_machine=i860-stratus + os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + os= + ;; + sun2os3) + basic_machine=m68000-sun + os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + os= + ;; + sun3os3) + basic_machine=m68k-sun + os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + os= + ;; + sun4os3) + basic_machine=sparc-sun + os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + os= + ;; + sv1) + basic_machine=sv1-cray + os=unicos + ;; + symmetry) + basic_machine=i386-sequent + os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=unicos + ;; + t90) + basic_machine=t90-cray + os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + os=tpf + ;; + udi29k) + basic_machine=a29k-amd + os=udi + ;; + ultra3) + basic_machine=a29k-nyu + os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=none + ;; + vaxv) + basic_machine=vax-dec + os=sysv + ;; + vms) + basic_machine=vax-dec + os=vms + ;; + vxworks960) + basic_machine=i960-wrs + os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=vxworks + ;; + xbox) + basic_machine=i686-pc + os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + os=unicos + ;; + *) + basic_machine=$1 + os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | ba \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | e2k | epiphany \ - | fido | fr30 | frv | ft32 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia16 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa32r6 | mipsisa32r6el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64r6 | mipsisa64r6el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pru \ - | pyramid \ - | riscv32 | riscv64 \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | visium \ - | wasm32 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - leon|leon[3-9]) - basic_machine=sparc-$basic_machine - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + op50n) + cpu=hppa1.1 + vendor=oki ;; - ms1) - basic_machine=mt-unknown + op60c) + cpu=hppa1.1 + vendor=oki ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + orion105) + cpu=clipper + vendor=highlevel ;; - xscaleeb) - basic_machine=armeb-unknown + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - - xscaleel) - basic_machine=armel-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | ba-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | e2k-* | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa32r6-* | mipsisa32r6el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64r6-* | mipsisa64r6el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | or1k*-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pru-* \ - | pyramid-* \ - | riscv32-* | riscv64-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | visium-* \ - | wasm32-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - asmjs) - basic_machine=asmjs-unknown - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola + cpu=m68k + vendor=motorola ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - e500v[12]) - basic_machine=powerpc-unknown - os=$os"spe" - ;; - e500v[12]-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - os=$os"spe" - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + os=${os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + os=solaris2 ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + os=${os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi + cpu=mips + vendor=sgi case $os in - -irix*) + irix*) ;; *) - os=-irix4 + os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - moxiebox) - basic_machine=moxie-unknown - os=-moxiebox - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl + cpu=m68000 + vendor=convergent ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos + cpu=mips + vendor=sony + os=newsos ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next + next | m*-next) + cpu=m68k + vendor=next case $os in - -nextstep* ) + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + os=nextstep2 ;; *) - os=-nextstep3 + os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - nsx-tandem) - basic_machine=nsx-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 + cpu=m68k + vendor=tti ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould + cpu=pn + vendor=gould ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + cpu=i386 + vendor=ibm ;; rm[46]00) - basic_machine=mips-siemens + cpu=mips + vendor=siemens ;; rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown + cpu=romp + vendor=ibm ;; sde) - basic_machine=mipsisa32-sde - os=-elf + cpu=mipsisa32 + vendor=sde + os=${os:-elf} ;; - sei) - basic_machine=mips-sei - os=-seiux + simso-wrs) + cpu=sparclite + vendor=wrs + os=vxworks ;; - sequent) - basic_machine=i386-sequent + tower | tower-32) + cpu=m68k + vendor=ncr ;; - sh) - basic_machine=sh-hitachi - os=-hms + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - sh5el) - basic_machine=sh5le-unknown + w65) + cpu=w65 + vendor=wdc ;; - sh64) - basic_machine=sh64-unknown + w89k-*) + cpu=hppa1.1 + vendor=winbond + os=proelf ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks + none) + cpu=none + vendor=none ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - spur) - basic_machine=spur-unknown + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - st2000) - basic_machine=m68k-tandem + + *-*) + # shellcheck disable=SC2162 + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv64 \ + | rl78 | romp | rs6000 | rx \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1363,200 +1278,246 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if [ x$os != x ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux + # First match some system type aliases that might get confused + # with valid system types. + # solaris* is a basic system type, with this one exception. + auroraux) + os=auroraux ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` + bluegene*) + os=cnk ;; - -solaris) - os=-solaris2 + solaris1 | solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; - -svr4*) - os=-sysv4 + solaris) + os=solaris2 ;; - -unixware*) - os=-sysv4.2uw + unixware*) + os=sysv4.2uw ;; - -gnu/linux*) + gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + es1800*) + os=ose + ;; + # Some version numbers need modification + chorusos*) + os=chorusos + ;; + isc) + os=isc2.2 + ;; + sco6) + os=sco5v6 + ;; + sco5) + os=sco3.2v5 + ;; + sco4) + os=sco3.2v4 + ;; + sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + ;; + sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + scout) + # Don't match below + ;; + sco*) + os=sco3.2v2 + ;; + psos*) + os=psos + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* | -cloudabi* | -sortix* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) + # Each alternative MUST end in a * to match a version number. + # sysv* is not here because it comes later, after sysvr4. + gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | kopensolaris* | plan9* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | knetbsd* | mirbsd* | netbsd* \ + | bitrig* | openbsd* | solidbsd* | libertybsd* \ + | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \ + | linux-newlib* | linux-musl* | linux-uclibc* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* \ + | morphos* | superux* | rtmk* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi*) # Remember, each alternative MUST END IN *, to match a version number. ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) + qnx*) + case $cpu in + x86 | i*86) ;; *) - os=-nto$os + os=nto-$os ;; esac ;; - -nto-qnx*) + hiux*) + os=hiuxwe2 ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` + nto-qnx*) ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + sim | xray | os68k* | v88r* \ + | windows* | osx | abug | netware* | os9* \ + | macos* | mpw* | magic* | mmixware* | mon960* | lnews*) ;; - -linux-dietlibc) - os=-linux-dietlibc + linux-dietlibc) + os=linux-dietlibc ;; - -linux*) + linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + lynx*178) + os=lynxos178 ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + lynx*5) + os=lynxos5 ;; - -opened*) - os=-openedition + lynx*) + os=lynxos ;; - -os400*) - os=-os400 + mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` ;; - -wince*) - os=-wince + opened*) + os=openedition ;; - -osfrose*) - os=-osfrose + os400*) + os=os400 ;; - -osf*) - os=-osf + sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; - -utek*) - os=-bsd + sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; - -dynix*) - os=-bsd + wince*) + os=wince ;; - -acis*) - os=-aos + utek*) + os=bsd ;; - -atheos*) - os=-atheos + dynix*) + os=bsd ;; - -syllable*) - os=-syllable + acis*) + os=aos ;; - -386bsd) - os=-bsd + atheos*) + os=atheos ;; - -ctix* | -uts*) - os=-sysv + syllable*) + os=syllable + ;; + 386bsd) + os=bsd ;; - -nova*) - os=-rtmk-nova + ctix* | uts*) + os=sysv ;; - -ns2 ) - os=-nextstep2 + nova*) + os=rtmk-nova ;; - -nsk*) - os=-nsk + ns2) + os=nextstep2 + ;; + nsk*) + os=nsk ;; # Preserve the version number of sinix5. - -sinix5.*) + sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf + sinix*) + os=sysv4 ;; - -triton*) - os=-sysv3 + tpf*) + os=tpf ;; - -oss*) - os=-sysv3 + triton*) + os=sysv3 ;; - -svr4) - os=-sysv4 + oss*) + os=sysv3 ;; - -svr3) - os=-sysv3 + svr4*) + os=sysv4 ;; - -sysvr4) - os=-sysv4 + svr3) + os=sysv3 ;; - # This must come after -sysvr4. - -sysv*) + sysvr4) + os=sysv4 ;; - -ose*) - os=-ose + # This must come after sysvr4. + sysv*) ;; - -es1800*) - os=-ose + ose*) + os=ose ;; - -xenix) - os=-xenix + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) + os=mint ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint + zvmoe) + os=zvmoe ;; - -aros*) - os=-aros + dicos*) + os=dicos ;; - -zvmoe) - os=-zvmoe + pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $cpu in + arm*) + os=eabi + ;; + *) + os=elf + ;; + esac ;; - -dicos*) - os=-dicos + nacl*) ;; - -nacl*) + ios) ;; - -ios) + none) ;; - -none) + *-eabi) ;; *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1572,264 +1533,265 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + os=linux ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; pru-*) - os=-elf + os=elf ;; *-be) - os=-beos - ;; - *-haiku) - os=-haiku + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) +case $vendor in + unknown) case $os in - -riscix*) + riscix*) vendor=acorn ;; - -sunos*) + sunos*) vendor=sun ;; - -cnk*|-aix*) + cnk*|-aix*) vendor=ibm ;; - -beos*) + beos*) vendor=be ;; - -hpux*) + hpux*) vendor=hp ;; - -mpeix*) + mpeix*) vendor=hp ;; - -hiux*) + hiux*) vendor=hitachi ;; - -unos*) + unos*) vendor=crds ;; - -dgux*) + dgux*) vendor=dg ;; - -luna*) + luna*) vendor=omron ;; - -genix*) + genix*) vendor=ns ;; - -mvs* | -opened*) + clix*) + vendor=intergraph + ;; + mvs* | opened*) vendor=ibm ;; - -os400*) + os400*) vendor=ibm ;; - -ptx*) + ptx*) vendor=sequent ;; - -tpf*) + tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + vxsim* | vxworks* | windiss*) vendor=wrs ;; - -aux*) + aux*) vendor=apple ;; - -hms*) + hms*) vendor=hitachi ;; - -mpw* | -macos*) + mpw* | macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *mint | mint[0-9]* | *MiNT | MiNT[0-9]*) vendor=atari ;; - -vos*) + vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config/llvm.m4 b/config/llvm.m4 index e25ffec661b..a5f4a9af448 100644 --- a/config/llvm.m4 +++ b/config/llvm.m4 @@ -1,11 +1,11 @@ # config/llvm.m4 # PGAC_LLVM_SUPPORT -# --------------- +# ----------------- # # Look for the LLVM installation, check that it's new enough, set the # corresponding LLVM_{CFLAGS,CXXFLAGS,BINPATH} and LDFLAGS -# variables. Also verifies that CLANG is available, to transform C +# variables. Also verify that CLANG is available, to transform C # into bitcode. # AC_DEFUN([PGAC_LLVM_SUPPORT], @@ -13,7 +13,7 @@ AC_DEFUN([PGAC_LLVM_SUPPORT], AC_REQUIRE([AC_PROG_AWK]) AC_ARG_VAR(LLVM_CONFIG, [path to llvm-config command]) - PGAC_PATH_PROGS(LLVM_CONFIG, llvm-config llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9) + PGAC_PATH_PROGS(LLVM_CONFIG, llvm-config llvm-config-7 llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9) # no point continuing if llvm wasn't found if test -z "$LLVM_CONFIG"; then @@ -31,7 +31,7 @@ AC_DEFUN([PGAC_LLVM_SUPPORT], # need clang to create some bitcode files AC_ARG_VAR(CLANG, [path to clang compiler to generate bitcode]) - PGAC_PATH_PROGS(CLANG, clang clang-6.0 clang-5.0 clang-4.0 clang-3.9) + PGAC_PATH_PROGS(CLANG, clang clang-7 clang-6.0 clang-5.0 clang-4.0 clang-3.9) if test -z "$CLANG"; then AC_MSG_ERROR([clang not found, but required when compiling --with-llvm, specify with CLANG=]) fi @@ -91,14 +91,7 @@ AC_DEFUN([PGAC_LLVM_SUPPORT], LLVM_BINPATH=`$LLVM_CONFIG --bindir` - # Check which functionality is present - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS" - AC_CHECK_DECLS([LLVMOrcGetSymbolAddressIn, LLVMOrcRegisterGDB, LLVMOrcRegisterPerf], [], [], [[#include ]]) - AC_CHECK_DECLS([LLVMGetHostCPUName], [], [], [[#include ]]) - CPPFLAGS="$SAVE_CPPFLAGS" - - # LLVM_CONFIG, CLANG are already output via AC_ARG_VAR +dnl LLVM_CONFIG, CLANG are already output via AC_ARG_VAR AC_SUBST(LLVM_LIBS) AC_SUBST(LLVM_CPPFLAGS) AC_SUBST(LLVM_CFLAGS) @@ -106,3 +99,22 @@ AC_DEFUN([PGAC_LLVM_SUPPORT], AC_SUBST(LLVM_BINPATH) ])# PGAC_LLVM_SUPPORT + + +# PGAC_CHECK_LLVM_FUNCTIONS +# ------------------------- +# +# Check presence of some optional LLVM functions. +# (This shouldn't happen until we're ready to run AC_CHECK_DECLS tests; +# because PGAC_LLVM_SUPPORT runs very early, it's not an appropriate place.) +# +AC_DEFUN([PGAC_CHECK_LLVM_FUNCTIONS], +[ + # Check which functionality is present + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS" + AC_CHECK_DECLS([LLVMOrcGetSymbolAddressIn], [], [], [[#include ]]) + AC_CHECK_DECLS([LLVMGetHostCPUName, LLVMGetHostCPUFeatures], [], [], [[#include ]]) + AC_CHECK_DECLS([LLVMCreateGDBRegistrationListener, LLVMCreatePerfJITEventListener], [], [], [[#include ]]) + CPPFLAGS="$SAVE_CPPFLAGS" +])# PGAC_CHECK_LLVM_FUNCTIONS diff --git a/config/perl.m4 b/config/perl.m4 index caefb0705e7..059e31c4766 100644 --- a/config/perl.m4 +++ b/config/perl.m4 @@ -5,6 +5,7 @@ # -------------- AC_DEFUN([PGAC_PATH_PERL], [PGAC_PATH_PROGS(PERL, perl) +AC_ARG_VAR(PERL, [Perl program])dnl if test "$PERL"; then pgac_perl_version=`$PERL -v 2>/dev/null | sed -n ['s/This is perl.*v[a-z ]*\([0-9]\.[0-9][0-9.]*\).*$/\1/p']` diff --git a/config/prep_buildtree b/config/prep_buildtree index 5b72c392f68..a0eabd3dee2 100644 --- a/config/prep_buildtree +++ b/config/prep_buildtree @@ -33,7 +33,7 @@ for item in `find "$sourcetree" -type d \( \( -name CVS -prune \) -o \( -name .g fi done -for item in `find "$sourcetree" -name Makefile -print -o -name GNUmakefile -print`; do +for item in `find "$sourcetree" -name Makefile -print -o -name GNUmakefile -print | grep -v "$sourcetree/doc/src/sgml/images/"`; do filename=`expr "$item" : "$sourcetree\(.*\)"` if test ! -f "${item}.in"; then if cmp "$item" "$buildtree/$filename" >/dev/null 2>&1; then : ; else diff --git a/config/programs.m4 b/config/programs.m4 index aa84bfdb9e4..90ff9447bdd 100644 --- a/config/programs.m4 +++ b/config/programs.m4 @@ -56,7 +56,7 @@ if test -z "$BISON"; then *** PostgreSQL then you do not need to worry about this, because the Bison *** output is pre-generated.)]) fi -# We don't need AC_SUBST(BISON) because PGAC_PATH_PROGS did it +dnl We don't need AC_SUBST(BISON) because PGAC_PATH_PROGS did it AC_SUBST(BISONFLAGS) ])# PGAC_PATH_BISON @@ -179,11 +179,11 @@ for pgac_rllib in $READLINE_ORDER ; do for pgac_lib in "" " -ltermcap" " -lncurses" " -lcurses" ; do LIBS="${pgac_rllib}${pgac_lib} $pgac_save_LIBS" AC_TRY_LINK_FUNC([readline], [[ - # Older NetBSD, OpenBSD, and Irix have a broken linker that does not + # Older NetBSD and OpenBSD have a broken linker that does not # recognize dependent libraries; assume curses is needed if we didn't # find any dependency. case $host_os in - netbsd* | openbsd* | irix*) + netbsd* | openbsd*) if test x"$pgac_lib" = x"" ; then pgac_lib=" -lcurses" fi ;; @@ -245,6 +245,7 @@ AC_DEFUN([PGAC_CHECK_GETTEXT], AC_CHECK_HEADER([libintl.h], [], [AC_MSG_ERROR([header file is required for NLS])]) PGAC_PATH_PROGS(MSGFMT, msgfmt) + AC_ARG_VAR(MSGFMT, [msgfmt program for NLS])dnl if test -z "$MSGFMT"; then AC_MSG_ERROR([msgfmt is required for NLS]) fi diff --git a/config/python.m4 b/config/python.m4 index 587bca99d52..c51aa4e332e 100644 --- a/config/python.m4 +++ b/config/python.m4 @@ -8,8 +8,16 @@ # ---------------- # Look for Python and set the output variable 'PYTHON' if found, # fail otherwise. +# +# As the Python 3 transition happens and PEP 394 isn't updated, we +# need to cater to systems that don't have unversioned "python" by +# default. Some systems ship with "python3" by default and perhaps +# have "python" in an optional package. Some systems only have +# "python2" and "python3", in which case it's reasonable to prefer the +# newer version. AC_DEFUN([PGAC_PATH_PYTHON], -[PGAC_PATH_PROGS(PYTHON, python) +[PGAC_PATH_PROGS(PYTHON, [python python3 python2]) +AC_ARG_VAR(PYTHON, [Python program])dnl if test x"$PYTHON" = x""; then AC_MSG_ERROR([Python not found]) fi diff --git a/config/tcl.m4 b/config/tcl.m4 index a4bf231947f..9de31a57156 100644 --- a/config/tcl.m4 +++ b/config/tcl.m4 @@ -5,6 +5,7 @@ AC_DEFUN([PGAC_PATH_TCLSH], [PGAC_PATH_PROGS(TCLSH, [tclsh tcl tclsh8.6 tclsh86 tclsh8.5 tclsh85 tclsh8.4 tclsh84]) +AC_ARG_VAR(TCLSH, [Tcl interpreter program (tclsh)])dnl if test x"$TCLSH" = x""; then AC_MSG_ERROR([Tcl shell not found]) fi @@ -13,6 +14,10 @@ fi # PGAC_PATH_TCLCONFIGSH([SEARCH-PATH]) # ------------------------------------ +# If the user doesn't specify $TCL_CONFIG_SH directly, search for it in +# the list of directories passed as parameter (from --with-tclconfig). +# If no list is given, try the Tcl shell's $auto_path. + AC_DEFUN([PGAC_PATH_TCLCONFIGSH], [AC_REQUIRE([PGAC_PATH_TCLSH])[]dnl AC_BEFORE([$0], [PGAC_PATH_TKCONFIGSH])[]dnl @@ -24,7 +29,14 @@ if test -z "$TCL_CONFIG_SH"; then set X $pgac_test_dirs; shift if test $[#] -eq 0; then test -z "$TCLSH" && AC_MSG_ERROR([unable to locate tclConfig.sh because no Tcl shell was found]) - set X `echo 'puts $auto_path' | $TCLSH`; shift + pgac_test_dirs=`echo 'puts $auto_path' | $TCLSH` + # On newer macOS, $auto_path frequently doesn't include the place + # where tclConfig.sh actually lives. Append that to the end, so as not + # to break cases where a non-default Tcl installation is being used. + if test -d "$PG_SYSROOT/System/Library/Frameworks/Tcl.framework" ; then + pgac_test_dirs="$pgac_test_dirs $PG_SYSROOT/System/Library/Frameworks/Tcl.framework" + fi + set X $pgac_test_dirs; shift fi for pgac_dir do diff --git a/configure b/configure index 56f18dfbc26..b3c92764be8 100755 --- a/configure +++ b/configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PostgreSQL 11devel. +# Generated by GNU Autoconf 2.69 for PostgreSQL 13devel. # -# Report bugs to . +# Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -11,7 +11,7 @@ # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # -# Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Copyright (c) 1996-2019, PostgreSQL Global Development Group ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## @@ -269,10 +269,10 @@ fi $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: pgsql-bugs@postgresql.org about your system, including -$0: any error possibly output before this message. Then -$0: install a modern shell, or manually run the script -$0: under such a shell if you do have one." +$0: pgsql-bugs@lists.postgresql.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi exit 1 fi @@ -582,9 +582,9 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PostgreSQL' PACKAGE_TARNAME='postgresql' -PACKAGE_VERSION='11devel' -PACKAGE_STRING='PostgreSQL 11devel' -PACKAGE_BUGREPORT='pgsql-bugs@postgresql.org' +PACKAGE_VERSION='13devel' +PACKAGE_STRING='PostgreSQL 13devel' +PACKAGE_BUGREPORT='pgsql-bugs@lists.postgresql.org' PACKAGE_URL='' ac_unique_file="src/backend/access/common/heaptuple.c" @@ -627,6 +627,7 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS vpath_build +PG_SYSROOT PG_VERSION_NUM PROVE FOP @@ -649,7 +650,6 @@ PG_CRC32C_OBJS CFLAGS_ARMV8_CRC32C CFLAGS_SSE42 have_win32_dbghelp -HAVE_IPV6 LIBOBJS UUID_LIBS LDAP_LIBS_BE @@ -658,6 +658,9 @@ PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CC ax_pthread_config +EGREP +GREP +SED ZIC python_additional_libs python_libspec @@ -668,6 +671,7 @@ python_majorversion PYTHON perl_embed_ldflags perl_embed_ccflags +perl_includespec perl_useshrplib perl_privlibexp perl_archlibexp @@ -695,9 +699,6 @@ with_gnu_ld LD LDFLAGS_SL LDFLAGS_EX -ELF_SYS -EGREP -GREP with_zlib with_system_tzdata with_libxslt @@ -730,6 +731,7 @@ CPP BITCODE_CXXFLAGS BITCODE_CFLAGS CFLAGS_VECTOR +PERMIT_DECLARATION_AFTER_STATEMENT LLVM_BINPATH LLVM_CXXFLAGS LLVM_CFLAGS @@ -759,7 +761,6 @@ GENHTML LCOV GCOV enable_debug -enable_strong_random enable_rpath default_port WANTED_LANGUAGES @@ -827,7 +828,6 @@ with_pgport enable_rpath enable_spinlocks enable_atomics -enable_strong_random enable_debug enable_profiling enable_coverage @@ -887,8 +887,13 @@ PKG_CONFIG_PATH PKG_CONFIG_LIBDIR ICU_CFLAGS ICU_LIBS +XML2_CONFIG LDFLAGS_EX -LDFLAGS_SL' +LDFLAGS_SL +PERL +PYTHON +MSGFMT +TCLSH' # Initialize some variables set by options. @@ -1429,7 +1434,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PostgreSQL 11devel to adapt to many kinds of systems. +\`configure' configures PostgreSQL 13devel to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1494,7 +1499,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PostgreSQL 11devel:";; + short | recursive ) echo "Configuration of PostgreSQL 13devel:";; esac cat <<\_ACEOF @@ -1510,7 +1515,6 @@ Optional Features: executables --disable-spinlocks do not use spinlocks --disable-atomics do not use atomic operations - --disable-strong-random do not use a strong random number source --enable-debug build with debugging symbols (-g) --enable-profiling build with profiling enabled --enable-coverage build with coverage testing instrumentation @@ -1587,13 +1591,18 @@ Some influential environment variables: path overriding pkg-config's built-in search path ICU_CFLAGS C compiler flags for ICU, overriding pkg-config ICU_LIBS linker flags for ICU, overriding pkg-config + XML2_CONFIG path to xml2-config utility LDFLAGS_EX extra linker flags for linking executables only LDFLAGS_SL extra linker flags for linking shared libraries only + PERL Perl program + PYTHON Python program + MSGFMT msgfmt program for NLS + TCLSH Tcl interpreter program (tclsh) Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to . +Report bugs to . _ACEOF ac_status=$? fi @@ -1656,14 +1665,14 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PostgreSQL configure 11devel +PostgreSQL configure 13devel generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. -Copyright (c) 1996-2018, PostgreSQL Global Development Group +Copyright (c) 1996-2019, PostgreSQL Global Development Group _ACEOF exit fi @@ -1748,52 +1757,6 @@ fi } # ac_fn_cxx_try_compile -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- -# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. -ac_fn_c_check_decl () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - as_decl_name=`echo $2|sed 's/ *(.*//'` - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -#ifndef $as_decl_name -#ifdef __cplusplus - (void) $as_decl_use; -#else - (void) $as_decl_name; -#endif -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_decl - # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1947,9 +1910,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ---------------------------------------- ## -## Report this to pgsql-bugs@postgresql.org ## -## ---------------------------------------- ##" +( $as_echo "## ---------------------------------------------- ## +## Report this to pgsql-bugs@lists.postgresql.org ## +## ---------------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac @@ -2401,11 +2364,61 @@ rm -f conftest.val as_fn_set_status $ac_retval } # ac_fn_c_compute_int + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + # Initialize each $ac_[]_AC_LANG_ABBREV[]_decl_warn_flag once. + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_werror_flag=$ac_c_werror_flag + ac_c_werror_flag="$ac_c_decl_warn_flag$ac_c_werror_flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_werror_flag +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PostgreSQL $as_me 11devel, which was +It was created by PostgreSQL $as_me 13devel, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2956,7 +2969,7 @@ PostgreSQL has apparently not been ported to your platform yet. To try a manual configuration, look into the src/template directory for a similar platform and use the '--with-template=' option. -Please also contact to see about +Please also contact to see about rectifying this. Include the above 'checking host system type...' line. ******************************************************************* @@ -3266,34 +3279,6 @@ fi -# -# Random number generation -# - - -# Check whether --enable-strong-random was given. -if test "${enable_strong_random+set}" = set; then : - enableval=$enable_strong_random; - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - as_fn_error $? "no argument expected for --enable-strong-random option" "$LINENO" 5 - ;; - esac - -else - enable_strong_random=yes - -fi - - - - # # --enable-debug adds -g to compiler flags # @@ -4425,6 +4410,190 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +#include + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + +fi + + + +# Error out if the compiler does not support C99, as the codebase +# relies on that. +if test "$ac_cv_prog_cc_c99" = no; then + as_fn_error $? "C compiler \"$CC\" does not support C99" "$LINENO" 5 +fi + ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4763,8 +4932,7 @@ fi -if test "$with_llvm" = yes ; then - for ac_prog in gawk mawk nawk awk +for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4806,12 +4974,14 @@ fi test -n "$AWK" && break done +if test "$with_llvm" = yes; then : + if test -z "$LLVM_CONFIG"; then - for ac_prog in llvm-config llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9 + for ac_prog in llvm-config llvm-config-7 llvm-config-6.0 llvm-config-5.0 llvm-config-4.0 llvm-config-3.9 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4882,7 +5052,7 @@ fi # need clang to create some bitcode files if test -z "$CLANG"; then - for ac_prog in clang clang-6.0 clang-5.0 clang-4.0 clang-3.9 + for ac_prog in clang clang-7 clang-6.0 clang-5.0 clang-4.0 clang-3.9 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -4994,58 +5164,7 @@ fi LLVM_BINPATH=`$LLVM_CONFIG --bindir` - # Check which functionality is present - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS" - ac_fn_c_check_decl "$LINENO" "LLVMOrcGetSymbolAddressIn" "ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" "#include -" -if test "x$ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "LLVMOrcRegisterGDB" "ac_cv_have_decl_LLVMOrcRegisterGDB" "#include -" -if test "x$ac_cv_have_decl_LLVMOrcRegisterGDB" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_LLVMORCREGISTERGDB $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "LLVMOrcRegisterPerf" "ac_cv_have_decl_LLVMOrcRegisterPerf" "#include -" -if test "x$ac_cv_have_decl_LLVMOrcRegisterPerf" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_LLVMORCREGISTERPERF $ac_have_decl -_ACEOF - - ac_fn_c_check_decl "$LINENO" "LLVMGetHostCPUName" "ac_cv_have_decl_LLVMGetHostCPUName" "#include -" -if test "x$ac_cv_have_decl_LLVMGetHostCPUName" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_LLVMGETHOSTCPUNAME $ac_have_decl -_ACEOF - - CPPFLAGS="$SAVE_CPPFLAGS" - # LLVM_CONFIG, CLANG are already output via AC_ARG_VAR @@ -5053,7 +5172,7 @@ _ACEOF -fi +fi # fi unset CFLAGS @@ -5142,6 +5261,7 @@ if test "$GCC" = yes -a "$ICC" = no; then CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith" CXXFLAGS="-Wall -Wpointer-arith" # These work in some but not all gcc versions + save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wdeclaration-after-statement, for CFLAGS" >&5 $as_echo_n "checking whether ${CC} supports -Wdeclaration-after-statement, for CFLAGS... " >&6; } @@ -5182,17 +5302,24 @@ if test x"$pgac_cv_prog_CC_cflags__Wdeclaration_after_statement" = x"yes"; then fi - # -Wdeclaration-after-statement isn't applicable for C++ + # -Wdeclaration-after-statement isn't applicable for C++. Specific C files + # disable it, so AC_SUBST the negative form. + PERMIT_DECLARATION_AFTER_STATEMENT= + if test x"$save_CFLAGS" != x"$CFLAGS"; then + PERMIT_DECLARATION_AFTER_STATEMENT=-Wno-declaration-after-statement + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wendif-labels, for CFLAGS" >&5 -$as_echo_n "checking whether ${CC} supports -Wendif-labels, for CFLAGS... " >&6; } -if ${pgac_cv_prog_CC_cflags__Wendif_labels+:} false; then : + # Really don't want VLAs to be used in our dialect of C + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Werror=vla, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Werror=vla, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Werror_vla+:} false; then : $as_echo_n "(cached) " >&6 else pgac_save_CFLAGS=$CFLAGS pgac_save_CC=$CC CC=${CC} -CFLAGS="${CFLAGS} -Wendif-labels" +CFLAGS="${CFLAGS} -Werror=vla" ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5207,19 +5334,60 @@ main () } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv_prog_CC_cflags__Wendif_labels=yes + pgac_cv_prog_CC_cflags__Werror_vla=yes else - pgac_cv_prog_CC_cflags__Wendif_labels=no + pgac_cv_prog_CC_cflags__Werror_vla=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="$pgac_save_CFLAGS" CC="$pgac_save_CC" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wendif_labels" >&5 -$as_echo "$pgac_cv_prog_CC_cflags__Wendif_labels" >&6; } -if test x"$pgac_cv_prog_CC_cflags__Wendif_labels" = x"yes"; then - CFLAGS="${CFLAGS} -Wendif-labels" +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Werror_vla" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Werror_vla" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Werror_vla" = x"yes"; then + CFLAGS="${CFLAGS} -Werror=vla" +fi + + + # -Wvla is not applicable for C++ + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wendif-labels, for CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wendif-labels, for CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wendif_labels+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS} -Wendif-labels" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wendif_labels=yes +else + pgac_cv_prog_CC_cflags__Wendif_labels=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wendif_labels" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wendif_labels" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wendif_labels" = x"yes"; then + CFLAGS="${CFLAGS} -Wendif-labels" fi @@ -5815,6 +5983,7 @@ fi # We want to suppress clang's unhelpful unused-command-line-argument warnings # but gcc won't complain about unrecognized -Wno-foo switches, so we have to # test for the positive form and if that works, add the negative form + NOT_THE_CFLAGS="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS" >&5 $as_echo_n "checking whether ${CC} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS... " >&6; } if ${pgac_cv_prog_CC_cflags__Wunused_command_line_argument+:} false; then : @@ -5857,6 +6026,93 @@ fi if test -n "$NOT_THE_CFLAGS"; then CFLAGS="$CFLAGS -Wno-unused-command-line-argument" fi + # Similarly disable useless truncation warnings from gcc 8+ + NOT_THE_CFLAGS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wformat-truncation, for NOT_THE_CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wformat-truncation, for NOT_THE_CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wformat_truncation+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${NOT_THE_CFLAGS} -Wformat-truncation" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wformat_truncation=yes +else + pgac_cv_prog_CC_cflags__Wformat_truncation=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wformat_truncation" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wformat_truncation" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wformat_truncation" = x"yes"; then + NOT_THE_CFLAGS="${NOT_THE_CFLAGS} -Wformat-truncation" +fi + + + if test -n "$NOT_THE_CFLAGS"; then + CFLAGS="$CFLAGS -Wno-format-truncation" + fi + NOT_THE_CFLAGS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wstringop-truncation, for NOT_THE_CFLAGS" >&5 +$as_echo_n "checking whether ${CC} supports -Wstringop-truncation, for NOT_THE_CFLAGS... " >&6; } +if ${pgac_cv_prog_CC_cflags__Wstringop_truncation+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${NOT_THE_CFLAGS} -Wstringop-truncation" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__Wstringop_truncation=yes +else + pgac_cv_prog_CC_cflags__Wstringop_truncation=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wstringop_truncation" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__Wstringop_truncation" >&6; } +if test x"$pgac_cv_prog_CC_cflags__Wstringop_truncation" = x"yes"; then + NOT_THE_CFLAGS="${NOT_THE_CFLAGS} -Wstringop-truncation" +fi + + + if test -n "$NOT_THE_CFLAGS"; then + CFLAGS="$CFLAGS -Wno-stringop-truncation" + fi elif test "$ICC" = yes; then # Intel's compiler has a bug/misoptimization in checking for # division by NAN (NaN == 0), -mp1 fixes it, so add it to the CFLAGS. @@ -6697,6 +6953,39 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi +# Defend against clang being used on x86-32 without SSE2 enabled. As current +# versions of clang do not understand -fexcess-precision=standard, the use of +# x87 floating point operations leads to problems like isinf possibly returning +# false for a value that is infinite when converted from the 80bit register to +# the 8byte memory representation. +# +# Only perform the test if the compiler doesn't understand +# -fexcess-precision=standard, that way a potentially fixed compiler will work +# automatically. +if test "$pgac_cv_prog_CC_cflags__fexcess_precision_standard" = no; then +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__) +choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + as_fn_error $? "Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc." "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -7912,7 +8201,7 @@ $as_echo_n "checking for XML2_CONFIG... " >&6; } $as_echo "$XML2_CONFIG" >&6; } fi - if test -n "$XML2_CONFIG"; then + if test -n "$XML2_CONFIG"; then for pgac_option in `$XML2_CONFIG --cflags`; do case $pgac_option in -I*|-D*) CPPFLAGS="$CPPFLAGS $pgac_option";; @@ -8017,247 +8306,84 @@ fi # -# Elf +# Assignments # -# Assume system is ELF if it predefines __ELF__ as 1, -# otherwise believe host_os based default. -case $host_os in - freebsd1*|freebsd2*) elf=no;; - freebsd3*|freebsd4*) elf=yes;; -esac +CPPFLAGS="$CPPFLAGS $INCLUDES" +LDFLAGS="$LDFLAGS $LIBDIRS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 +$as_echo_n "checking for ld used by GCC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${ac_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi + IFS="$ac_save_ifs" else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if __ELF__ - yes -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - ELF_SYS=true -else - if test "X$elf" = "Xyes" ; then - ELF_SYS=true -else - ELF_SYS= -fi -fi -rm -f conftest* - - - -# -# Assignments -# - -CPPFLAGS="$CPPFLAGS $INCLUDES" -LDFLAGS="$LDFLAGS $LIBDIRS" - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 -$as_echo_n "checking for ld used by GCC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case "$ac_prog" in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${ac_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - ac_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - ac_cv_path_LD="$LD" # Let the user override the test with a path. + ac_cv_path_LD="$LD" # Let the user override the test with a path. fi fi @@ -9040,48 +9166,6 @@ else $as_echo "no, using $LN_S" >&6; } fi -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then @@ -9224,7 +9308,6 @@ $as_echo "$as_me: WARNING: *** PostgreSQL then you do not need to worry about this, because the Bison *** output is pre-generated.)" >&2;} fi -# We don't need AC_SUBST(BISON) because PGAC_PATH_PROGS did it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flex" >&5 @@ -9414,6 +9497,15 @@ You might have to rebuild your Perl installation. Refer to the documentation for details. Use --without-perl to disable building PL/Perl." "$LINENO" 5 fi + # On most platforms, archlibexp is also where the Perl include files live ... + perl_includespec="-I$perl_archlibexp/CORE" + # ... but on newer macOS versions, we must use -iwithsysroot to look + # under $PG_SYSROOT + if test \! -f "$perl_archlibexp/CORE/perl.h" ; then + if test -f "$PG_SYSROOT$perl_archlibexp/CORE/perl.h" ; then + perl_includespec="-iwithsysroot $perl_archlibexp/CORE" + fi + fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLAGS recommended by Perl" >&5 $as_echo_n "checking for CFLAGS recommended by Perl... " >&6; } @@ -9459,7 +9551,7 @@ fi if test "$with_python" = yes; then if test -z "$PYTHON"; then - for ac_prog in python + for ac_prog in python python3 python2 do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -9729,39 +9821,235 @@ fi # other libraries can pull in the pthread functions as a side-effect. We # want to use the -pthread or similar flags directly, and not rely on # the side-effects of linking with some other library. -# -# note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER -# invocation below is the first one in the script, and autoconf generates -# additional code for that, which must not be inside the if-block. AS_IF -# knows how to do that. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi else - ac_cv_header_stdc=no + ac_cv_path_SED=$SED fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -if test $ac_cv_header_stdc = yes; then +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9868,6 +10156,7 @@ if test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"; then : + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -9883,10 +10172,14 @@ ax_pthread_ok=no # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + if test "x$PTHREAD_CC" != "x"; then : + CC="$PTHREAD_CC" +fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 $as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } @@ -9915,12 +10208,13 @@ rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } - if test x"$ax_pthread_ok" = xno; then + if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -9933,7 +10227,7 @@ fi # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. -ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt -mthreads pthread --thread-safe pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -9942,14 +10236,14 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 -# -pthreads: Solaris/gcc +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which -# is present but should not be used directly) +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ @@ -9957,6 +10251,14 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt case $host_os in + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable @@ -9991,63 +10293,184 @@ rm -f conftest* solaris*) - # Newer versions of Solaris require the "-mt -lpthread" pair, and we - # check that first. On some older versions, libc contains stubbed + # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So - # we'll look for -pthreads and -lpthread shortly thereafter. + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +if test "x$GCC" = "xyes"; then : + ax_pthread_flags="-pthread -pthreads $ax_pthread_flags" +fi + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; - ax_pthread_flags="-mt,pthread -pthreads -pthread pthread $ax_pthread_flags" + *) + ax_pthread_check_macro="--" ;; esac +if test "x$ax_pthread_check_macro" = "x--"; then : + ax_pthread_check_cond=0 +else + ax_pthread_check_cond="!defined($ax_pthread_check_macro)" +fi -# Older versions of Clang only give a warning instead of an error for an -# unrecognized option, unless we specify -Werror. (We throw in some extra -# Clang warning flags for good measure.) +# Are we compiling with Clang? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler needs certain flags to reject unknown flags" >&5 -$as_echo_n "checking if compiler needs certain flags to reject unknown flags... " >&6; } -if ${ax_cv_PTHREAD_REJECT_UNKNOWN+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 +$as_echo_n "checking whether $CC is Clang... " >&6; } +if ${ax_cv_PTHREAD_CLANG+:} false; then : $as_echo_n "(cached) " >&6 else - ax_cv_PTHREAD_REJECT_UNKNOWN=unknown - save_CFLAGS="$CFLAGS" - ax_pthread_extra_flags="-Wunknown-warning-option -Wunused-command-line-argument" - CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wfoobaz -foobaz" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -int foo(void); -int -main () -{ -foo() - ; - return 0; -} +/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_PTHREAD_REJECT_UNKNOWN="-Werror $ax_pthread_extra_flags" +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then : + ax_cv_PTHREAD_CLANG=yes +fi +rm -f conftest* + + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG" >&6; } +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 +$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } +if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then : + $as_echo_n "(cached) " >&6 else - ax_cv_PTHREAD_REJECT_UNKNOWN=no + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + if test "x$ax_pthread_try" = "xunknown"; then : + break fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS="$save_CFLAGS" + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_link="$ax_pthread_2step_ac_link" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main(void){return 0;} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_REJECT_UNKNOWN" >&5 -$as_echo "$ax_cv_PTHREAD_REJECT_UNKNOWN" >&6; } -ax_pthread_extra_flags= -if test "x$ax_cv_PTHREAD_REJECT_UNKNOWN" != "xno"; then : - ax_pthread_extra_flags="$ax_cv_PTHREAD_REJECT_UNKNOWN" +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + if test "x$ax_pthread_try" = "x"; then : + ax_pthread_try=no +fi + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 +$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +fi # $ax_pthread_clang = yes - case $flag in +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in none) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 $as_echo_n "checking whether pthreads work without any flags... " >&6; } @@ -10061,9 +10484,9 @@ $as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; } ;; -*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5 -$as_echo_n "checking whether pthreads work with $flag... " >&6; } - PTHREAD_CFLAGS="$flag" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 +$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } + PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) @@ -10105,22 +10528,24 @@ $as_echo "no" >&6; } fi - if test x"$ax_pthread_config" = xno; then continue; fi + if test "x$ax_pthread_config" = "xno"; then : + continue +fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5 -$as_echo_n "checking for the pthreads library -l$flag... " >&6; } - PTHREAD_LIBS="-l$flag" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 +$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } + PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we @@ -10131,9 +10556,13 @@ $as_echo_n "checking for the pthreads library -l$flag... " >&6; } # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; } int @@ -10155,14 +10584,14 @@ fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 $as_echo "$ax_pthread_ok" >&6; } - if test "x$ax_pthread_ok" = xyes; then - break; - fi + if test "x$ax_pthread_ok" = "xyes"; then : + break +fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" @@ -10170,11 +10599,11 @@ done fi # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 @@ -10183,20 +10612,20 @@ if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_PTHREAD_JOINABLE_ATTR=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { -int attr = $attr; return attr /* ; */ +int attr = $ax_pthread_attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ax_cv_PTHREAD_JOINABLE_ATTR=$attr; break + ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext @@ -10205,44 +10634,29 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 $as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } - if test "$ax_cv_PTHREAD_JOINABLE_ATTR" != unknown && \ - test "$ax_cv_PTHREAD_JOINABLE_ATTR" != PTHREAD_CREATE_JOINABLE; then : + if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"; then : cat >>confdefs.h <<_ACEOF #define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR _ACEOF + ax_pthread_joinable_attr_defined=yes + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5 -$as_echo_n "checking if more special flags are required for pthreads... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 +$as_echo_n "checking whether more special flags are required for pthreads... " >&6; } if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then : $as_echo_n "(cached) " >&6 else ax_cv_PTHREAD_SPECIAL_FLAGS=no - ax_pthread_special_flags_added=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# if !defined(_REENTRANT) && !defined(_THREAD_SAFE) - AX_PTHREAD_NEED_SPECIAL_FLAG -# endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "AX_PTHREAD_NEED_SPECIAL_FLAG" >/dev/null 2>&1; then : - case $host_os in - aix* | freebsd*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_THREAD_SAFE" - ;; - darwin* | hpux* | osf* | solaris*) - ax_cv_PTHREAD_SPECIAL_FLAGS="-D_REENTRANT" - ;; - esac - -fi -rm -f conftest* - + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 @@ -10280,23 +10694,26 @@ rm -f core conftest.err conftest.$ac_objext \ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 $as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } - if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then : + if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"; then : $as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h + ax_pthread_prio_inherit_defined=yes + fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant - if test "x$GCC" != xyes; then + if test "x$GCC" != "xyes"; then case $host_os in aix*) case "x/$CC" in #( x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : #handle absolute path differently from PATH based program lookup - case "x$CC" in #( + case "x$CC" in #( x/*) : if as_fn_executable_p ${CC}_r; then : PTHREAD_CC="${CC}_r" @@ -10361,7 +10778,7 @@ test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then +if test "x$ax_pthread_ok" = "xyes"; then $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h @@ -10424,12 +10841,10 @@ else int main () { -#ifndef _AIX -int strerror_r(int, char *, size_t); -#else -/* Older AIX has 'int' for the third argument so we don't test the args. */ -int strerror_r(); -#endif +char buf[100]; + switch (strerror_r(1, buf, sizeof(buf))) + { case 0: break; default: break; } + ; return 0; } @@ -10738,12 +11153,9 @@ if test "$ac_res" != no; then : fi -# We only use libld in port/dynloader/aix.c -case $host_os in - aix*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ldopen" >&5 -$as_echo_n "checking for library containing ldopen... " >&6; } -if ${ac_cv_search_ldopen+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getopt_long" >&5 +$as_echo_n "checking for library containing getopt_long... " >&6; } +if ${ac_cv_search_getopt_long+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS @@ -10756,16 +11168,16 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #ifdef __cplusplus extern "C" #endif -char ldopen (); +char getopt_long (); int main () { -return ldopen (); +return getopt_long (); ; return 0; } _ACEOF -for ac_lib in '' ld; do +for ac_lib in '' getopt gnugetopt; do if test -z "$ac_lib"; then ac_res="none required" else @@ -10773,76 +11185,18 @@ for ac_lib in '' ld; do LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_ldopen=$ac_res + ac_cv_search_getopt_long=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext - if ${ac_cv_search_ldopen+:} false; then : + if ${ac_cv_search_getopt_long+:} false; then : break fi done -if ${ac_cv_search_ldopen+:} false; then : +if ${ac_cv_search_getopt_long+:} false; then : else - ac_cv_search_ldopen=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ldopen" >&5 -$as_echo "$ac_cv_search_ldopen" >&6; } -ac_res=$ac_cv_search_ldopen -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing getopt_long" >&5 -$as_echo_n "checking for library containing getopt_long... " >&6; } -if ${ac_cv_search_getopt_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char getopt_long (); -int -main () -{ -return getopt_long (); - ; - return 0; -} -_ACEOF -for ac_lib in '' getopt gnugetopt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_getopt_long=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_getopt_long+:} false; then : - break -fi -done -if ${ac_cv_search_getopt_long+:} false; then : - -else - ac_cv_search_getopt_long=no + ac_cv_search_getopt_long=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS @@ -10855,62 +11209,6 @@ if test "$ac_res" != no; then : fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt" >&5 -$as_echo_n "checking for library containing crypt... " >&6; } -if ${ac_cv_search_crypt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char crypt (); -int -main () -{ -return crypt (); - ; - return 0; -} -_ACEOF -for ac_lib in '' crypt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_crypt=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_crypt+:} false; then : - break -fi -done -if ${ac_cv_search_crypt+:} false; then : - -else - ac_cv_search_crypt=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt" >&5 -$as_echo "$ac_cv_search_crypt" >&6; } -ac_res=$ac_cv_search_crypt -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 $as_echo_n "checking for library containing shm_open... " >&6; } if ${ac_cv_search_shm_open+:} false; then : @@ -11346,11 +11644,11 @@ return readline (); _ACEOF if ac_fn_c_try_link "$LINENO"; then : - # Older NetBSD, OpenBSD, and Irix have a broken linker that does not + # Older NetBSD and OpenBSD have a broken linker that does not # recognize dependent libraries; assume curses is needed if we didn't # find any dependency. case $host_os in - netbsd* | openbsd* | irix*) + netbsd* | openbsd*) if test x"$pgac_lib" = x"" ; then pgac_lib=" -lcurses" fi ;; @@ -11759,7 +12057,7 @@ done # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it # doesn't have these OpenSSL 1.1.0 functions. So check for individual # functions. - for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL + for ac_func in OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -12406,7 +12704,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h fi -for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h +for ac_header in atomic.h copyfile.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -13278,28 +13576,57 @@ $as_echo_n "checking for printf format archetype... " >&6; } if ${pgac_cv_printf_archetype+:} false; then : $as_echo_n "(cached) " >&6 else - ac_save_c_werror_flag=$ac_c_werror_flag + pgac_cv_printf_archetype=gnu_printf +ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern int -pgac_write(int ignore, const char *fmt,...) -__attribute__((format(gnu_printf, 2, 3))); +extern void pgac_write(int ignore, const char *fmt,...) +__attribute__((format($pgac_cv_printf_archetype, 2, 3))); int main () { +pgac_write(0, "error %s: %m", "foo"); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_archetype_ok=yes +else + ac_archetype_ok=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +if [ "$ac_archetype_ok" = no ]; then + pgac_cv_printf_archetype=__syslog__ + ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +extern void pgac_write(int ignore, const char *fmt,...) +__attribute__((format($pgac_cv_printf_archetype, 2, 3))); +int +main () +{ +pgac_write(0, "error %s: %m", "foo"); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv_printf_archetype=gnu_printf + ac_archetype_ok=yes else - pgac_cv_printf_archetype=printf + ac_archetype_ok=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag + + if [ "$ac_archetype_ok" = no ]; then + pgac_cv_printf_archetype=printf + fi +fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_printf_archetype" >&5 $as_echo "$pgac_cv_printf_archetype" >&6; } @@ -13544,78 +13871,6 @@ if test x"$pgac_cv__types_compatible" = xyes ; then $as_echo "#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1" >>confdefs.h -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap16" >&5 -$as_echo_n "checking for __builtin_bswap16... " >&6; } -if ${pgac_cv__builtin_bswap16+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -static unsigned long int x = __builtin_bswap16(0xaabb); - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv__builtin_bswap16=yes -else - pgac_cv__builtin_bswap16=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap16" >&5 -$as_echo "$pgac_cv__builtin_bswap16" >&6; } -if test x"$pgac_cv__builtin_bswap16" = xyes ; then - -$as_echo "#define HAVE__BUILTIN_BSWAP16 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5 -$as_echo_n "checking for __builtin_bswap32... " >&6; } -if ${pgac_cv__builtin_bswap32+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -static unsigned long int x = __builtin_bswap32(0xaabbccdd); - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv__builtin_bswap32=yes -else - pgac_cv__builtin_bswap32=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap32" >&5 -$as_echo "$pgac_cv__builtin_bswap32" >&6; } -if test x"$pgac_cv__builtin_bswap32" = xyes ; then - -$as_echo "#define HAVE__BUILTIN_BSWAP32 1" >>confdefs.h - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap64" >&5 -$as_echo_n "checking for __builtin_bswap64... " >&6; } -if ${pgac_cv__builtin_bswap64+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -static unsigned long int x = __builtin_bswap64(0xaabbccddeeff0011); - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv__builtin_bswap64=yes -else - pgac_cv__builtin_bswap64=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap64" >&5 -$as_echo "$pgac_cv__builtin_bswap64" >&6; } -if test x"$pgac_cv__builtin_bswap64" = xyes ; then - -$as_echo "#define HAVE__BUILTIN_BSWAP64 1" >>confdefs.h - fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_constant_p" >&5 $as_echo_n "checking for __builtin_constant_p... " >&6; } @@ -13708,38 +13963,6 @@ if test x"$pgac_cv_computed_goto" = xyes ; then $as_echo "#define HAVE_COMPUTED_GOTO 1" >>confdefs.h -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __VA_ARGS__" >&5 -$as_echo_n "checking for __VA_ARGS__... " >&6; } -if ${pgac_cv__va_args+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -#define debug(...) fprintf(stderr, __VA_ARGS__) -debug("%s", "blarg"); - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - pgac_cv__va_args=yes -else - pgac_cv__va_args=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__va_args" >&5 -$as_echo "$pgac_cv__va_args" >&6; } -if test x"$pgac_cv__va_args" = xyes ; then - -$as_echo "#define HAVE__VA_ARGS 1" >>confdefs.h - fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } @@ -14303,12 +14526,49 @@ fi fi -# On PPC, check if assembler supports LWARX instruction's mutex hint bit case $host_cpu in + x86_64) + # On x86_64, check if we can compile a popcntq instruction + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports x86_64 popcntq" >&5 +$as_echo_n "checking whether assembler supports x86_64 popcntq... " >&6; } +if ${pgac_cv_have_x86_64_popcntq+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +long long x = 1; long long r; + __asm__ __volatile__ (" popcntq %1,%0\n" : "=q"(r) : "rm"(x)); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_have_x86_64_popcntq=yes +else + pgac_cv_have_x86_64_popcntq=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_x86_64_popcntq" >&5 +$as_echo "$pgac_cv_have_x86_64_popcntq" >&6; } + if test x"$pgac_cv_have_x86_64_popcntq" = xyes ; then + +$as_echo "#define HAVE_X86_64_POPCNTQ 1" >>confdefs.h + + fi + ;; ppc*|powerpc*) + # On PPC, check if assembler supports LWARX instruction's mutex hint bit { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports lwarx hint bit" >&5 $as_echo_n "checking whether assembler supports lwarx hint bit... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +if ${pgac_cv_have_ppc_mutex_hint+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -14326,7 +14586,8 @@ else pgac_cv_have_ppc_mutex_hint=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_ppc_mutex_hint" >&5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_have_ppc_mutex_hint" >&5 $as_echo "$pgac_cv_have_ppc_mutex_hint" >&6; } if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then @@ -14544,7 +14805,6 @@ fi fi -# Check for largefile support (must be after AC_SYS_LARGEFILE) # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. @@ -14676,8 +14936,8 @@ else if ${ac_cv_func_accept_arg3+:} false; then : $as_echo_n "(cached) " >&6 else - for ac_cv_func_accept_return in 'int' 'unsigned int PASCAL' 'SOCKET WSAAPI'; do - for ac_cv_func_accept_arg1 in 'int' 'unsigned int' 'SOCKET'; do + for ac_cv_func_accept_return in 'int' 'SOCKET WSAAPI' 'unsigned int PASCAL'; do + for ac_cv_func_accept_arg1 in 'int' 'SOCKET' 'unsigned int'; do for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14827,7 +15087,7 @@ fi LIBS_including_readline="$LIBS" LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'` -for ac_func in cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll posix_fallocate pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range utime utimes wcstombs_l +for ac_func in cbrt clock_gettime copyfile fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memset_s memmove poll posix_fallocate ppoll pstat pthread_is_threaded_np readlink setproctitle setproctitle_fast setsid shm_open strchrnul strsignal symlink sync_file_range uselocale utime utimes wcstombs_l do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -14840,24 +15100,255 @@ fi done -ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" -if test "x$ac_cv_func_fseeko" = xyes; then : - $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h - +# These typically are compiler builtins, for which AC_CHECK_FUNCS fails. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap16" >&5 +$as_echo_n "checking for __builtin_bswap16... " >&6; } +if ${pgac_cv__builtin_bswap16+:} false; then : + $as_echo_n "(cached) " >&6 else - case " $LIBOBJS " in - *" fseeko.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fseeko.$ac_objext" - ;; -esac - -fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int +call__builtin_bswap16(int x) +{ + return __builtin_bswap16(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_bswap16=yes +else + pgac_cv__builtin_bswap16=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap16" >&5 +$as_echo "$pgac_cv__builtin_bswap16" >&6; } +if test x"${pgac_cv__builtin_bswap16}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_BSWAP16 1 +_ACEOF + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5 +$as_echo_n "checking for __builtin_bswap32... " >&6; } +if ${pgac_cv__builtin_bswap32+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +call__builtin_bswap32(int x) +{ + return __builtin_bswap32(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_bswap32=yes +else + pgac_cv__builtin_bswap32=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap32" >&5 +$as_echo "$pgac_cv__builtin_bswap32" >&6; } +if test x"${pgac_cv__builtin_bswap32}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_BSWAP32 1 +_ACEOF + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap64" >&5 +$as_echo_n "checking for __builtin_bswap64... " >&6; } +if ${pgac_cv__builtin_bswap64+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +call__builtin_bswap64(long int x) +{ + return __builtin_bswap64(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_bswap64=yes +else + pgac_cv__builtin_bswap64=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap64" >&5 +$as_echo "$pgac_cv__builtin_bswap64" >&6; } +if test x"${pgac_cv__builtin_bswap64}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_BSWAP64 1 +_ACEOF + +fi +# We assume that we needn't test all widths of these explicitly: +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_clz" >&5 +$as_echo_n "checking for __builtin_clz... " >&6; } +if ${pgac_cv__builtin_clz+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +call__builtin_clz(unsigned int x) +{ + return __builtin_clz(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_clz=yes +else + pgac_cv__builtin_clz=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_clz" >&5 +$as_echo "$pgac_cv__builtin_clz" >&6; } +if test x"${pgac_cv__builtin_clz}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_CLZ 1 +_ACEOF + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_ctz" >&5 +$as_echo_n "checking for __builtin_ctz... " >&6; } +if ${pgac_cv__builtin_ctz+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +call__builtin_ctz(unsigned int x) +{ + return __builtin_ctz(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_ctz=yes +else + pgac_cv__builtin_ctz=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_ctz" >&5 +$as_echo "$pgac_cv__builtin_ctz" >&6; } +if test x"${pgac_cv__builtin_ctz}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_CTZ 1 +_ACEOF + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_popcount" >&5 +$as_echo_n "checking for __builtin_popcount... " >&6; } +if ${pgac_cv__builtin_popcount+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +call__builtin_popcount(unsigned int x) +{ + return __builtin_popcount(x); +} +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + pgac_cv__builtin_popcount=yes +else + pgac_cv__builtin_popcount=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_popcount" >&5 +$as_echo "$pgac_cv__builtin_popcount" >&6; } +if test x"${pgac_cv__builtin_popcount}" = xyes ; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BUILTIN_POPCOUNT 1 +_ACEOF + +fi + +ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes; then : + $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" fseeko.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fseeko.$ac_objext" + ;; +esac + +fi -case $host_os in - # NetBSD uses a custom fseeko/ftello built on fsetpos/fgetpos - # Mingw uses macros to access Win32 API calls - netbsd*|mingw*) + +case $host_os in + # NetBSD uses a custom fseeko/ftello built on fsetpos/fgetpos + # Mingw uses macros to access Win32 API calls + netbsd*|mingw*) $as_echo "#define HAVE_FSEEKO 1" >>confdefs.h @@ -14936,7 +15427,96 @@ esac # posix_fadvise() is a no-op on Solaris, so don't incur function overhead # by calling it, 2009-04-02 # http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c -if test "$PORTNAME" != "solaris"; then +# The Clang compiler raises a warning for an undeclared identifier that matches +# a compiler builtin function. All extant Clang versions are affected, as of +# Clang 3.6.0. Test a builtin known to every version. This problem affects the +# C and Objective C languages, but Clang does report an error under C++ and +# Objective C++. +# +# Passing -fno-builtin to the compiler would suppress this problem. That +# strategy would have the advantage of being insensitive to stray warnings, but +# it would make tests less realistic. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how $CC reports undeclared, standard C functions" >&5 +$as_echo_n "checking how $CC reports undeclared, standard C functions... " >&6; } +if ${ac_cv_c_decl_report+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +(void) strchr; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if test -s conftest.err; then : + # For AC_CHECK_DECL to react to warnings, the compiler must be silent on + # valid AC_CHECK_DECL input. No library function is consistently available + # on freestanding implementations, so test against a dummy declaration. + # Include always-available headers on the off chance that they somehow + # elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +extern void ac_decl (int, char *); +int +main () +{ +#ifdef __cplusplus + (void) ac_decl ((int) 0, (char *) 0); + (void) ac_decl; +#else + (void) ac_decl; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if test -s conftest.err; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot detect from compiler exit status or warnings +See \`config.log' for more details" "$LINENO" 5; } +else + ac_cv_c_decl_report=warning +fi +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compile a simple declaration test +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "compiler does not report undeclared identifiers +See \`config.log' for more details" "$LINENO" 5; } +fi +else + ac_cv_c_decl_report=error +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_decl_report" >&5 +$as_echo "$ac_cv_c_decl_report" >&6; } + +case $ac_cv_c_decl_report in + warning) ac_c_decl_warn_flag=yes ;; + *) ac_c_decl_warn_flag= ;; +esac + +if test "$PORTNAME" != "solaris"; then : + for ac_func in posix_fadvise do : ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" @@ -14960,7 +15540,8 @@ cat >>confdefs.h <<_ACEOF #define HAVE_DECL_POSIX_FADVISE $ac_have_decl _ACEOF -fi + +fi # fi ac_fn_c_check_decl "$LINENO" "fdatasync" "ac_cv_have_decl_fdatasync" "#include " @@ -15019,7 +15600,30 @@ cat >>confdefs.h <<_ACEOF _ACEOF -HAVE_IPV6=no +ac_fn_c_check_decl "$LINENO" "RTLD_GLOBAL" "ac_cv_have_decl_RTLD_GLOBAL" "#include +" +if test "x$ac_cv_have_decl_RTLD_GLOBAL" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_RTLD_GLOBAL $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "RTLD_NOW" "ac_cv_have_decl_RTLD_NOW" "#include +" +if test "x$ac_cv_have_decl_RTLD_NOW" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_RTLD_NOW $ac_have_decl +_ACEOF + + ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "$ac_includes_default #include " @@ -15027,11 +15631,9 @@ if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : $as_echo "#define HAVE_IPV6 1" >>confdefs.h - HAVE_IPV6=yes fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PS_STRINGS" >&5 $as_echo_n "checking for PS_STRINGS... " >&6; } if ${pgac_cv_var_PS_STRINGS+:} false; then : @@ -15068,97 +15670,6 @@ $as_echo "#define HAVE_PS_STRINGS 1" >>confdefs.h fi -# We use our snprintf.c emulation if either snprintf() or vsnprintf() -# is missing. Yes, there are machines that have only one. We may -# also decide to use snprintf.c if snprintf() is present but does not -# have all the features we need --- see below. - -if test "$PORTNAME" = "win32"; then - # Win32 gets snprintf.c built unconditionally. - # - # To properly translate all NLS languages strings, we must support the - # *printf() %$ format, which allows *printf() arguments to be selected - # by position in the translated string. - # - # libintl versions < 0.13 use the native *printf() functions, and Win32 - # *printf() doesn't understand %$, so we must use our /port versions, - # which do understand %$. libintl versions >= 0.13 include their own - # *printf versions on Win32. The libintl 0.13 release note text is: - # - # C format strings with positions, as they arise when a translator - # needs to reorder a sentence, are now supported on all platforms. - # On those few platforms (NetBSD and Woe32) for which the native - # printf()/fprintf()/... functions don't support such format - # strings, replacements are provided through . - # - # We could use libintl >= 0.13's *printf() if we were sure that we had - # a litint >= 0.13 at runtime, but seeing that there is no clean way - # to guarantee that, it is best to just use our own, so we are sure to - # get %$ support. In include/port.h we disable the *printf() macros - # that might have been defined by libintl. - # - # We do this unconditionally whether NLS is used or not so we are sure - # that all Win32 libraries and binaries behave the same. - pgac_need_repl_snprintf=yes -else - pgac_need_repl_snprintf=no - for ac_func in snprintf -do : - ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" -if test "x$ac_cv_func_snprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SNPRINTF 1 -_ACEOF - -else - pgac_need_repl_snprintf=yes -fi -done - - for ac_func in vsnprintf -do : - ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" -if test "x$ac_cv_func_vsnprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VSNPRINTF 1 -_ACEOF - -else - pgac_need_repl_snprintf=yes -fi -done - -fi - - -# Check whether declares snprintf() and vsnprintf(); if not, -# include/c.h will provide declarations. Note this is a separate test -# from whether the functions exist in the C library --- there are -# systems that have the functions but don't bother to declare them :-( - -ac_fn_c_check_decl "$LINENO" "snprintf" "ac_cv_have_decl_snprintf" "$ac_includes_default" -if test "x$ac_cv_have_decl_snprintf" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_SNPRINTF $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "vsnprintf" "ac_cv_have_decl_vsnprintf" "$ac_includes_default" -if test "x$ac_cv_have_decl_vsnprintf" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_VSNPRINTF $ac_have_decl -_ACEOF - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for isinf" >&5 $as_echo_n "checking for isinf... " >&6; } if ${ac_cv_func_isinf+:} false; then : @@ -15215,14 +15726,27 @@ done fi -ac_fn_c_check_func "$LINENO" "crypt" "ac_cv_func_crypt" -if test "x$ac_cv_func_crypt" = xyes; then : - $as_echo "#define HAVE_CRYPT 1" >>confdefs.h +ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + $as_echo "#define HAVE_DLOPEN 1" >>confdefs.h else case " $LIBOBJS " in - *" crypt.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS crypt.$ac_objext" + *" dlopen.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS dlopen.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero" +if test "x$ac_cv_func_explicit_bzero" = xyes; then : + $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" explicit_bzero.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext" ;; esac @@ -15293,6 +15817,32 @@ esac fi +ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread" +if test "x$ac_cv_func_pread" = xyes; then : + $as_echo "#define HAVE_PREAD 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" pread.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS pread.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" +if test "x$ac_cv_func_pwrite" = xyes; then : + $as_echo "#define HAVE_PWRITE 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" pwrite.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS pwrite.$ac_objext" + ;; +esac + +fi + ac_fn_c_check_func "$LINENO" "random" "ac_cv_func_random" if test "x$ac_cv_func_random" = xyes; then : $as_echo "#define HAVE_RANDOM 1" >>confdefs.h @@ -15326,20 +15876,7 @@ if test "x$ac_cv_func_srandom" = xyes; then : else case " $LIBOBJS " in *" srandom.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS srandom.$ac_objext" - ;; -esac - -fi - -ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" -if test "x$ac_cv_func_strerror" = xyes; then : - $as_echo "#define HAVE_STRERROR 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" strerror.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strerror.$ac_objext" + *) LIBOBJS="$LIBOBJS srandom.$ac_objext" ;; esac @@ -15384,7 +15921,39 @@ esac fi +ac_fn_c_check_func "$LINENO" "strtof" "ac_cv_func_strtof" +if test "x$ac_cv_func_strtof" = xyes; then : + $as_echo "#define HAVE_STRTOF 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strtof.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtof.$ac_objext" + ;; +esac + +fi + + + +case $host_os in + # Cygwin and (apparently, based on test results) Mingw both + # have a broken strtof(), so substitute the same replacement + # code we use with VS2013. That's not a perfect fix, since + # (unlike with VS2013) it doesn't avoid double-rounding, but + # we have no better options. To get that, though, we have to + # force the file to be compiled despite HAVE_STRTOF. + mingw*|cygwin*) + case " $LIBOBJS " in + *" strtof.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtof.$ac_objext" + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: On $host_os we will use our strtof wrapper." >&5 +$as_echo "$as_me: On $host_os we will use our strtof wrapper." >&6;} + ;; +esac case $host_os in @@ -15484,9 +16053,9 @@ esac fi -# Solaris' getopt() doesn't do what we want for long options, so always use -# our version on that platform. -if test "$PORTNAME" = "solaris"; then +# On OpenBSD and Solaris, getopt() doesn't do what we want for long options +# (i.e., allow '-' as a flag character), so use our version on those platforms. +if test "$PORTNAME" = "openbsd" -o "$PORTNAME" = "solaris"; then case " $LIBOBJS " in *" getopt.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS getopt.$ac_objext" @@ -15514,6 +16083,17 @@ fi # Win32 (really MinGW) support if test "$PORTNAME" = "win32"; then + for ac_func in _configthreadlocale +do : + ac_fn_c_check_func "$LINENO" "_configthreadlocale" "ac_cv_func__configthreadlocale" +if test "x$ac_cv_func__configthreadlocale" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE__CONFIGTHREADLOCALE 1 +_ACEOF + +fi +done + ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = xyes; then : $as_echo "#define HAVE_GETTIMEOFDAY 1" >>confdefs.h @@ -15615,24 +16195,6 @@ esac fi -ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include -/* NetBSD declares sys_siglist in unistd.h. */ -#ifdef HAVE_UNISTD_H -# include -#endif - -" -if test "x$ac_cv_have_decl_sys_siglist" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_SYS_SIGLIST $ac_have_decl -_ACEOF - - ac_fn_c_check_func "$LINENO" "syslog" "ac_cv_func_syslog" if test "x$ac_cv_func_syslog" = xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default" @@ -15710,7 +16272,7 @@ $as_echo "#define HAVE_INT_OPTRESET 1" >>confdefs.h fi -for ac_func in strtoll strtoq +for ac_func in strtoll __strtoll strtoq do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -15722,7 +16284,7 @@ _ACEOF fi done -for ac_func in strtoull strtouq +for ac_func in strtoull __strtoull strtouq do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -15734,6 +16296,28 @@ _ACEOF fi done +# strto[u]ll may exist but not be declared +ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtoll" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOLL $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default" +if test "x$ac_cv_have_decl_strtoull" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRTOULL $ac_have_decl +_ACEOF + if test "$with_icu" = yes; then ac_save_CPPFLAGS=$CPPFLAGS @@ -15752,6 +16336,73 @@ fi CPPFLAGS=$ac_save_CPPFLAGS fi +if test "$with_llvm" = yes; then + + # Check which functionality is present + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $LLVM_CPPFLAGS" + ac_fn_c_check_decl "$LINENO" "LLVMOrcGetSymbolAddressIn" "ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" "#include +" +if test "x$ac_cv_have_decl_LLVMOrcGetSymbolAddressIn" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "LLVMGetHostCPUName" "ac_cv_have_decl_LLVMGetHostCPUName" "#include +" +if test "x$ac_cv_have_decl_LLVMGetHostCPUName" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_LLVMGETHOSTCPUNAME $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "LLVMGetHostCPUFeatures" "ac_cv_have_decl_LLVMGetHostCPUFeatures" "#include +" +if test "x$ac_cv_have_decl_LLVMGetHostCPUFeatures" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_LLVMGETHOSTCPUFEATURES $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "LLVMCreateGDBRegistrationListener" "ac_cv_have_decl_LLVMCreateGDBRegistrationListener" "#include +" +if test "x$ac_cv_have_decl_LLVMCreateGDBRegistrationListener" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "LLVMCreatePerfJITEventListener" "ac_cv_have_decl_LLVMCreatePerfJITEventListener" "#include +" +if test "x$ac_cv_have_decl_LLVMCreatePerfJITEventListener" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER $ac_have_decl +_ACEOF + + CPPFLAGS="$SAVE_CPPFLAGS" + +fi + # Lastly, restore full LIBS list and check for readline/libedit symbols LIBS="$LIBS_including_readline" @@ -15854,54 +16505,6 @@ fi # Run tests below here # -------------------- -# Force use of our snprintf if system's doesn't do arg control -# See comment above at snprintf test for details. -if test "$enable_nls" = yes -a "$pgac_need_repl_snprintf" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf supports argument control" >&5 -$as_echo_n "checking whether snprintf supports argument control... " >&6; } -if ${pgac_cv_snprintf_arg_control+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - pgac_cv_snprintf_arg_control=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int main() -{ - char buf[100]; - - /* can it swap arguments? */ - snprintf(buf, 100, "%2\$d %1\$d", 3, 4); - if (strcmp(buf, "4 3") != 0) - return 1; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_snprintf_arg_control=yes -else - pgac_cv_snprintf_arg_control=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_arg_control" >&5 -$as_echo "$pgac_cv_snprintf_arg_control" >&6; } - - if test $pgac_cv_snprintf_arg_control != yes ; then - pgac_need_repl_snprintf=yes - fi -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether long int is 64 bits" >&5 $as_echo_n "checking whether long int is 64 bits... " >&6; } @@ -16080,161 +16683,19 @@ cat >>confdefs.h <<_ACEOF _ACEOF -# If we found "long int" is 64 bits, assume snprintf handles it. If -# we found we need to use "long long int", better check. We cope with -# snprintfs that use %lld, %qd, or %I64d as the format. If none of these -# work, fall back to our own snprintf emulation (which we know uses %lld). - -if test "$HAVE_LONG_LONG_INT_64" = yes ; then - if test $pgac_need_repl_snprintf = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking snprintf length modifier for long long int" >&5 -$as_echo_n "checking snprintf length modifier for long long int... " >&6; } -if ${pgac_cv_snprintf_long_long_int_modifier+:} false; then : - $as_echo_n "(cached) " >&6 -else - for pgac_modifier in 'll' 'q' 'I64'; do -if test "$cross_compiling" = yes; then : - pgac_cv_snprintf_long_long_int_modifier=cross; break -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -typedef long long int ac_int64; -#define INT64_FORMAT "%${pgac_modifier}d" - -ac_int64 a = 20000001; -ac_int64 b = 40000005; - -int does_int64_snprintf_work() -{ - ac_int64 c; - char buf[100]; - - if (sizeof(ac_int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} - -int -main() { - return (! does_int64_snprintf_work()); -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_snprintf_long_long_int_modifier=$pgac_modifier; break -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -done -fi - -LONG_LONG_INT_MODIFIER='' - -case $pgac_cv_snprintf_long_long_int_modifier in - cross) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot test (not on host machine)" >&5 -$as_echo "cannot test (not on host machine)" >&6; };; - ?*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_long_long_int_modifier" >&5 -$as_echo "$pgac_cv_snprintf_long_long_int_modifier" >&6; } - LONG_LONG_INT_MODIFIER=$pgac_cv_snprintf_long_long_int_modifier;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; };; -esac - if test "$LONG_LONG_INT_MODIFIER" = ""; then - # Force usage of our own snprintf, since system snprintf is broken - pgac_need_repl_snprintf=yes - LONG_LONG_INT_MODIFIER='ll' - fi - else - # Here if we previously decided we needed to use our own snprintf - LONG_LONG_INT_MODIFIER='ll' - fi +# Select the printf length modifier that goes with that, too. +if test x"$pg_int64_type" = x"long long int" ; then + INT64_MODIFIER='"ll"' else - # Here if we are not using 'long long int' at all - LONG_LONG_INT_MODIFIER='l' + INT64_MODIFIER='"l"' fi -INT64_MODIFIER="\"$LONG_LONG_INT_MODIFIER\"" - cat >>confdefs.h <<_ACEOF #define INT64_MODIFIER $INT64_MODIFIER _ACEOF -# Also force use of our snprintf if the system's doesn't support the %z flag. -if test "$pgac_need_repl_snprintf" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether snprintf supports the %z modifier" >&5 -$as_echo_n "checking whether snprintf supports the %z modifier... " >&6; } -if ${pgac_cv_snprintf_size_t_support+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - pgac_cv_snprintf_size_t_support=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include - -int main() -{ - char bufz[100]; - char buf64[100]; - - /* - * Print the largest unsigned number fitting in a size_t using both %zu - * and the previously-determined format for 64-bit integers. Note that - * we don't run this code unless we know snprintf handles 64-bit ints. - */ - bufz[0] = '\0'; /* in case snprintf fails to emit anything */ - snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0)); - snprintf(buf64, sizeof(buf64), "%" INT64_MODIFIER "u", - (unsigned PG_INT64_TYPE) ~((size_t) 0)); - if (strcmp(bufz, buf64) != 0) - return 1; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - pgac_cv_snprintf_size_t_support=yes -else - pgac_cv_snprintf_size_t_support=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_snprintf_size_t_support" >&5 -$as_echo "$pgac_cv_snprintf_size_t_support" >&6; } - - if test "$pgac_cv_snprintf_size_t_support" != yes; then - pgac_need_repl_snprintf=yes - fi -fi - -# Now we have checked all the reasons to replace snprintf -if test $pgac_need_repl_snprintf = yes; then - -$as_echo "#define USE_REPL_SNPRINTF 1" >>confdefs.h - - case " $LIBOBJS " in - *" snprintf.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS snprintf.$ac_objext" - ;; -esac - -fi - # has to be down here, rather than with the other builtins, because # the test uses PG_INT64_TYPE. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_mul_overflow" >&5 @@ -17344,46 +17805,6 @@ fi fi -# In order to detect at runtime, if the ARM CRC Extension is available, -# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have -# everything we need for that. -for ac_func in getauxval -do : - ac_fn_c_check_func "$LINENO" "getauxval" "ac_cv_func_getauxval" -if test "x$ac_cv_func_getauxval" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETAUXVAL 1 -_ACEOF - -fi -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ - -#ifndef AT_HWCAP -#error AT_HWCAP not defined -#endif -#ifndef HWCAP_CRC32 -#error HWCAP_CRC32 not defined -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - HAVE_HWCAP_CRC32=1 -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - # Select CRC-32C implementation. # # If we are targeting a processor that has Intel SSE 4.2 instructions, we can @@ -17414,9 +17835,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" && if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then USE_ARMV8_CRC32C=1 else - # ARM CRC Extension, with runtime check? The getauxval() function and - # HWCAP_CRC32 are needed for the runtime check. - if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then + # ARM CRC Extension, with runtime check? + if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1 else # fall back to slicing-by-8 algorithm, which doesn't require any @@ -17648,7 +18068,7 @@ fi # in the template or configure command line. # If not selected manually, try to select a source automatically. -if test "$enable_strong_random" = "yes" && test x"$USE_OPENSSL_RANDOM" = x"" && test x"$USE_WIN32_RANDOM" = x"" && test x"$USE_DEV_URANDOM" = x"" ; then +if test x"$USE_OPENSSL_RANDOM" = x"" && test x"$USE_WIN32_RANDOM" = x"" && test x"$USE_DEV_URANDOM" = x"" ; then if test x"$with_openssl" = x"yes" ; then USE_OPENSSL_RANDOM=1 elif test "$PORTNAME" = "win32" ; then @@ -17682,42 +18102,28 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking which random number source to use" >&5 $as_echo_n "checking which random number source to use... " >&6; } -if test "$enable_strong_random" = yes ; then - if test x"$USE_OPENSSL_RANDOM" = x"1" ; then +if test x"$USE_OPENSSL_RANDOM" = x"1" ; then $as_echo "#define USE_OPENSSL_RANDOM 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: OpenSSL" >&5 $as_echo "OpenSSL" >&6; } - elif test x"$USE_WIN32_RANDOM" = x"1" ; then +elif test x"$USE_WIN32_RANDOM" = x"1" ; then $as_echo "#define USE_WIN32_RANDOM 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows native" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Windows native" >&5 $as_echo "Windows native" >&6; } - elif test x"$USE_DEV_URANDOM" = x"1" ; then +elif test x"$USE_DEV_URANDOM" = x"1" ; then $as_echo "#define USE_DEV_URANDOM 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: /dev/urandom" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: /dev/urandom" >&5 $as_echo "/dev/urandom" >&6; } - else - as_fn_error $? " -no source of strong random numbers was found -PostgreSQL can use OpenSSL or /dev/urandom as a source of random numbers, -for authentication protocols. You can use --disable-strong-random to use a -built-in pseudo random number generator, but that may be insecure." "$LINENO" 5 - fi - -$as_echo "#define HAVE_STRONG_RANDOM 1" >>confdefs.h - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: weak builtin PRNG" >&5 -$as_echo "weak builtin PRNG" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: -*** Not using a strong random number source may be insecure." >&5 -$as_echo "$as_me: WARNING: -*** Not using a strong random number source may be insecure." >&2;} + as_fn_error $? " +no source of strong random numbers was found +PostgreSQL can use OpenSSL or /dev/urandom as a source of random numbers." "$LINENO" 5 fi # If not set in template file, set bytes to use libc memset() @@ -17853,7 +18259,7 @@ $as_echo_n "checking for MSGFMT... " >&6; } $as_echo "$MSGFMT" >&6; } fi - if test -z "$MSGFMT"; then + if test -z "$MSGFMT"; then as_fn_error $? "msgfmt is required for NLS" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msgfmt flags" >&5 @@ -18049,7 +18455,14 @@ if test -z "$TCL_CONFIG_SH"; then set X $pgac_test_dirs; shift if test $# -eq 0; then test -z "$TCLSH" && as_fn_error $? "unable to locate tclConfig.sh because no Tcl shell was found" "$LINENO" 5 - set X `echo 'puts $auto_path' | $TCLSH`; shift + pgac_test_dirs=`echo 'puts $auto_path' | $TCLSH` + # On newer macOS, $auto_path frequently doesn't include the place + # where tclConfig.sh actually lives. Append that to the end, so as not + # to break cases where a non-default Tcl installation is being used. + if test -d "$PG_SYSROOT/System/Library/Frameworks/Tcl.framework" ; then + pgac_test_dirs="$pgac_test_dirs $PG_SYSROOT/System/Library/Frameworks/Tcl.framework" + fi + set X $pgac_test_dirs; shift fi for pgac_dir do @@ -18098,7 +18511,7 @@ fi # check for if test "$with_perl" = yes; then ac_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$perl_archlibexp/CORE" + CPPFLAGS="$CPPFLAGS $perl_includespec" ac_fn_c_check_header_compile "$LINENO" "perl.h" "ac_cv_header_perl_h" "#include " if test "x$ac_cv_header_perl_h" = xyes; then : @@ -18217,13 +18630,13 @@ $as_echo "$XMLLINT" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DocBook XML V4.2" >&5 -$as_echo_n "checking for DocBook XML V4.2... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DocBook XML V4.5" >&5 +$as_echo_n "checking for DocBook XML V4.5... " >&6; } if ${pgac_cv_check_docbook+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.xml < + test @@ -18781,6 +19194,15 @@ _ACEOF +# If we are inserting PG_SYSROOT into CPPFLAGS, do so symbolically not +# literally, so that it's possible to override it at build time using +# a command like "make ... PG_SYSROOT=path". This has to be done after +# we've finished all configure checks that depend on CPPFLAGS. +if test x"$PG_SYSROOT" != x; then + CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"` +fi + + # Begin output steps @@ -18829,7 +19251,7 @@ fi ac_config_files="$ac_config_files GNUmakefile src/Makefile.global" -ac_config_links="$ac_config_links src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template}" +ac_config_links="$ac_config_links src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template}" if test "$PORTNAME" = "win32"; then @@ -19353,7 +19775,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PostgreSQL $as_me 11devel, which was +This file was extended by PostgreSQL $as_me 13devel, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19417,13 +19839,13 @@ $config_links Configuration commands: $config_commands -Report bugs to ." +Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PostgreSQL config.status 11devel +PostgreSQL config.status 13devel configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -19550,10 +19972,8 @@ do "src/backend/port/tas.s") CONFIG_LINKS="$CONFIG_LINKS src/backend/port/tas.s:src/backend/port/tas/${tas_file}" ;; "GNUmakefile") CONFIG_FILES="$CONFIG_FILES GNUmakefile" ;; "src/Makefile.global") CONFIG_FILES="$CONFIG_FILES src/Makefile.global" ;; - "src/backend/port/dynloader.c") CONFIG_LINKS="$CONFIG_LINKS src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c" ;; "src/backend/port/pg_sema.c") CONFIG_LINKS="$CONFIG_LINKS src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION}" ;; "src/backend/port/pg_shmem.c") CONFIG_LINKS="$CONFIG_LINKS src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION}" ;; - "src/include/dynloader.h") CONFIG_LINKS="$CONFIG_LINKS src/include/dynloader.h:src/backend/port/dynloader/${template}.h" ;; "src/include/pg_config_os.h") CONFIG_LINKS="$CONFIG_LINKS src/include/pg_config_os.h:src/include/port/${template}.h" ;; "src/Makefile.port") CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;; "check_win32_symlinks") CONFIG_COMMANDS="$CONFIG_COMMANDS check_win32_symlinks" ;; diff --git a/configure.in b/configure.in index da02a56ec66..0d16c1a9711 100644 --- a/configure.in +++ b/configure.in @@ -17,13 +17,13 @@ dnl Read the Autoconf manual for details. dnl m4_pattern_forbid(^PGAC_)dnl to catch undefined macros -AC_INIT([PostgreSQL], [11devel], [pgsql-bugs@postgresql.org]) +AC_INIT([PostgreSQL], [13devel], [pgsql-bugs@lists.postgresql.org]) m4_if(m4_defn([m4_PACKAGE_VERSION]), [2.69], [], [m4_fatal([Autoconf version 2.69 is required. Untested combinations of 'autoconf' and PostgreSQL versions are not recommended. You can remove the check from 'configure.in' but it is then your responsibility whether the result works or not.])]) -AC_COPYRIGHT([Copyright (c) 1996-2018, PostgreSQL Global Development Group]) +AC_COPYRIGHT([Copyright (c) 1996-2019, PostgreSQL Global Development Group]) AC_CONFIG_SRCDIR([src/backend/access/common/heaptuple.c]) AC_CONFIG_AUX_DIR(config) AC_PREFIX_DEFAULT(/usr/local/pgsql) @@ -79,7 +79,7 @@ PostgreSQL has apparently not been ported to your platform yet. To try a manual configuration, look into the src/template directory for a similar platform and use the '--with-template=' option. -Please also contact to see about +Please also contact to see about rectifying this. Include the above 'checking host system type...' line. ******************************************************************* @@ -193,13 +193,6 @@ PGAC_ARG_BOOL(enable, spinlocks, yes, PGAC_ARG_BOOL(enable, atomics, yes, [do not use atomic operations]) -# -# Random number generation -# -PGAC_ARG_BOOL(enable, strong-random, yes, - [do not use a strong random number source]) -AC_SUBST(enable_strong_random) - # # --enable-debug adds -g to compiler flags # @@ -358,6 +351,14 @@ case $template in esac AC_PROG_CC([$pgac_cc_list]) +AC_PROG_CC_C99() + +# Error out if the compiler does not support C99, as the codebase +# relies on that. +if test "$ac_cv_prog_cc_c99" = no; then + AC_MSG_ERROR([C compiler "$CC" does not support C99]) +fi + AC_PROG_CXX([$pgac_cxx_list]) # Check if it's Intel's compiler, which (usually) pretends to be gcc, @@ -383,9 +384,10 @@ AC_SUBST(SUN_STUDIO_CC) PGAC_ARG_BOOL(with, llvm, no, [build with LLVM based JIT support], [AC_DEFINE([USE_LLVM], 1, [Define to 1 to build with LLVM based JIT support. (--with-llvm)])]) AC_SUBST(with_llvm) -if test "$with_llvm" = yes ; then - PGAC_LLVM_SUPPORT() -fi +dnl must use AS_IF here, else AC_REQUIRES inside PGAC_LLVM_SUPPORT malfunctions +AS_IF([test "$with_llvm" = yes], [ + PGAC_LLVM_SUPPORT() +]) # fi unset CFLAGS @@ -474,8 +476,18 @@ if test "$GCC" = yes -a "$ICC" = no; then CFLAGS="-Wall -Wmissing-prototypes -Wpointer-arith" CXXFLAGS="-Wall -Wpointer-arith" # These work in some but not all gcc versions + save_CFLAGS=$CFLAGS PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement]) - # -Wdeclaration-after-statement isn't applicable for C++ + # -Wdeclaration-after-statement isn't applicable for C++. Specific C files + # disable it, so AC_SUBST the negative form. + PERMIT_DECLARATION_AFTER_STATEMENT= + if test x"$save_CFLAGS" != x"$CFLAGS"; then + PERMIT_DECLARATION_AFTER_STATEMENT=-Wno-declaration-after-statement + fi + AC_SUBST(PERMIT_DECLARATION_AFTER_STATEMENT) + # Really don't want VLAs to be used in our dialect of C + PGAC_PROG_CC_CFLAGS_OPT([-Werror=vla]) + # -Wvla is not applicable for C++ PGAC_PROG_CC_CFLAGS_OPT([-Wendif-labels]) PGAC_PROG_CXX_CFLAGS_OPT([-Wendif-labels]) PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute]) @@ -498,10 +510,22 @@ if test "$GCC" = yes -a "$ICC" = no; then # We want to suppress clang's unhelpful unused-command-line-argument warnings # but gcc won't complain about unrecognized -Wno-foo switches, so we have to # test for the positive form and if that works, add the negative form + NOT_THE_CFLAGS="" PGAC_PROG_CC_VAR_OPT(NOT_THE_CFLAGS, [-Wunused-command-line-argument]) if test -n "$NOT_THE_CFLAGS"; then CFLAGS="$CFLAGS -Wno-unused-command-line-argument" fi + # Similarly disable useless truncation warnings from gcc 8+ + NOT_THE_CFLAGS="" + PGAC_PROG_CC_VAR_OPT(NOT_THE_CFLAGS, [-Wformat-truncation]) + if test -n "$NOT_THE_CFLAGS"; then + CFLAGS="$CFLAGS -Wno-format-truncation" + fi + NOT_THE_CFLAGS="" + PGAC_PROG_CC_VAR_OPT(NOT_THE_CFLAGS, [-Wstringop-truncation]) + if test -n "$NOT_THE_CFLAGS"; then + CFLAGS="$CFLAGS -Wno-stringop-truncation" + fi elif test "$ICC" = yes; then # Intel's compiler has a bug/misoptimization in checking for # division by NAN (NaN == 0), -mp1 fixes it, so add it to the CFLAGS. @@ -601,6 +625,24 @@ choke me @%:@endif])], [], [AC_MSG_ERROR([do not put -ffast-math in CFLAGS])]) fi +# Defend against clang being used on x86-32 without SSE2 enabled. As current +# versions of clang do not understand -fexcess-precision=standard, the use of +# x87 floating point operations leads to problems like isinf possibly returning +# false for a value that is infinite when converted from the 80bit register to +# the 8byte memory representation. +# +# Only perform the test if the compiler doesn't understand +# -fexcess-precision=standard, that way a potentially fixed compiler will work +# automatically. +if test "$pgac_cv_prog_CC_cflags__fexcess_precision_standard" = no; then +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ +@%:@if defined(__clang__) && defined(__i386__) && !defined(__SSE2_MATH__) +choke me +@%:@endif +])], [], +[AC_MSG_ERROR([Compiling PostgreSQL with clang, on 32bit x86, requires SSE2 support. Use -msse2 or use gcc.])]) +fi + AC_PROG_CPP AC_SUBST(GCC) @@ -882,6 +924,7 @@ PGAC_ARG_BOOL(with, libxml, no, [build with XML support], if test "$with_libxml" = yes ; then PGAC_PATH_PROGS(XML2_CONFIG, xml2-config) + AC_ARG_VAR(XML2_CONFIG, [path to xml2-config utility])dnl if test -n "$XML2_CONFIG"; then for pgac_option in `$XML2_CONFIG --cflags`; do case $pgac_option in @@ -921,30 +964,6 @@ PGAC_ARG_BOOL(with, zlib, yes, [do not use Zlib]) AC_SUBST(with_zlib) -# -# Elf -# - -# Assume system is ELF if it predefines __ELF__ as 1, -# otherwise believe host_os based default. -case $host_os in - freebsd1*|freebsd2*) elf=no;; - freebsd3*|freebsd4*) elf=yes;; -esac - -AC_EGREP_CPP(yes, -[#if __ELF__ - yes -#endif -], -[ELF_SYS=true], -[if test "X$elf" = "Xyes" ; then - ELF_SYS=true -else - ELF_SYS= -fi]) -AC_SUBST(ELF_SYS) - # # Assignments # @@ -979,7 +998,6 @@ AC_SUBST(install_bin) PGAC_PATH_PROGS(TAR, tar) AC_PROG_LN_S -AC_PROG_AWK AC_PROG_MKDIR_P # When Autoconf chooses install-sh as mkdir -p program it tries to generate # a relative path to it in each makefile where it substitutes it. This clashes @@ -1003,6 +1021,16 @@ You might have to rebuild your Perl installation. Refer to the documentation for details. Use --without-perl to disable building PL/Perl.]) fi + # On most platforms, archlibexp is also where the Perl include files live ... + perl_includespec="-I$perl_archlibexp/CORE" + # ... but on newer macOS versions, we must use -iwithsysroot to look + # under $PG_SYSROOT + if test \! -f "$perl_archlibexp/CORE/perl.h" ; then + if test -f "$PG_SYSROOT$perl_archlibexp/CORE/perl.h" ; then + perl_includespec="-iwithsysroot $perl_archlibexp/CORE" + fi + fi + AC_SUBST(perl_includespec)dnl PGAC_CHECK_PERL_EMBED_CCFLAGS PGAC_CHECK_PERL_EMBED_LDFLAGS fi @@ -1034,11 +1062,11 @@ fi # other libraries can pull in the pthread functions as a side-effect. We # want to use the -pthread or similar flags directly, and not rely on # the side-effects of linking with some other library. -# -# note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER -# invocation below is the first one in the script, and autoconf generates -# additional code for that, which must not be inside the if-block. AS_IF -# knows how to do that. + +dnl note: We have to use AS_IF here rather than plain if. The AC_CHECK_HEADER +dnl invocation below is the first one in the script, and autoconf generates +dnl additional code for that, which must not be inside the if-block. AS_IF +dnl knows how to do that. AS_IF([test "$enable_thread_safety" = yes -a "$PORTNAME" != "win32"], [ # then AX_PTHREAD # set thread flags @@ -1089,14 +1117,7 @@ AC_SEARCH_LIBS(setproctitle, util) AC_SEARCH_LIBS(dlopen, dl) AC_SEARCH_LIBS(socket, [socket ws2_32]) AC_SEARCH_LIBS(shl_load, dld) -# We only use libld in port/dynloader/aix.c -case $host_os in - aix*) - AC_SEARCH_LIBS(ldopen, ld) - ;; -esac AC_SEARCH_LIBS(getopt_long, [getopt gnugetopt]) -AC_SEARCH_LIBS(crypt, crypt) AC_SEARCH_LIBS(shm_open, rt) AC_SEARCH_LIBS(shm_unlink, rt) AC_SEARCH_LIBS(clock_gettime, [rt posix4]) @@ -1166,7 +1187,7 @@ if test "$with_openssl" = yes ; then # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it # doesn't have these OpenSSL 1.1.0 functions. So check for individual # functions. - AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data RAND_OpenSSL]) + AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data]) # OpenSSL versions before 1.1.0 required setting callback functions, for # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock() # function was removed. @@ -1248,7 +1269,34 @@ AC_SUBST(UUID_LIBS) AC_HEADER_STDBOOL -AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/ipc.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h]) +AC_CHECK_HEADERS(m4_normalize([ + atomic.h + copyfile.h + fp_class.h + getopt.h + ieeefp.h + ifaddrs.h + langinfo.h + mbarrier.h + poll.h + sys/epoll.h + sys/ipc.h + sys/prctl.h + sys/procctl.h + sys/pstat.h + sys/resource.h + sys/select.h + sys/sem.h + sys/shm.h + sys/sockio.h + sys/tas.h + sys/un.h + termios.h + ucred.h + utime.h + wchar.h + wctype.h +])) # On BSD, test for net/if.h will fail unless sys/socket.h # is included first. @@ -1411,13 +1459,9 @@ PGAC_C_FUNCNAME_SUPPORT PGAC_C_STATIC_ASSERT PGAC_C_TYPEOF PGAC_C_TYPES_COMPATIBLE -PGAC_C_BUILTIN_BSWAP16 -PGAC_C_BUILTIN_BSWAP32 -PGAC_C_BUILTIN_BSWAP64 PGAC_C_BUILTIN_CONSTANT_P PGAC_C_BUILTIN_UNREACHABLE PGAC_C_COMPUTED_GOTO -PGAC_C_VA_ARGS PGAC_STRUCT_TIMEZONE PGAC_UNION_SEMUN PGAC_STRUCT_SOCKADDR_UN @@ -1469,16 +1513,29 @@ Use --without-zlib to disable zlib support.])], [#include ]) fi -# On PPC, check if assembler supports LWARX instruction's mutex hint bit case $host_cpu in + x86_64) + # On x86_64, check if we can compile a popcntq instruction + AC_CACHE_CHECK([whether assembler supports x86_64 popcntq], + [pgac_cv_have_x86_64_popcntq], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], + [long long x = 1; long long r; + __asm__ __volatile__ (" popcntq %1,%0\n" : "=q"(r) : "rm"(x));])], + [pgac_cv_have_x86_64_popcntq=yes], + [pgac_cv_have_x86_64_popcntq=no])]) + if test x"$pgac_cv_have_x86_64_popcntq" = xyes ; then + AC_DEFINE(HAVE_X86_64_POPCNTQ, 1, [Define to 1 if the assembler supports X86_64's POPCNTQ instruction.]) + fi + ;; ppc*|powerpc*) - AC_MSG_CHECKING([whether assembler supports lwarx hint bit]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], + # On PPC, check if assembler supports LWARX instruction's mutex hint bit + AC_CACHE_CHECK([whether assembler supports lwarx hint bit], + [pgac_cv_have_ppc_mutex_hint], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [int a = 0; int *p = &a; int r; __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p));])], [pgac_cv_have_ppc_mutex_hint=yes], - [pgac_cv_have_ppc_mutex_hint=no]) - AC_MSG_RESULT([$pgac_cv_have_ppc_mutex_hint]) + [pgac_cv_have_ppc_mutex_hint=no])]) if test x"$pgac_cv_have_ppc_mutex_hint" = xyes ; then AC_DEFINE(HAVE_PPC_LWARX_MUTEX_HINT, 1, [Define to 1 if the assembler supports PPC's LWARX mutex hint bit.]) fi @@ -1498,7 +1555,7 @@ if test "$PORTNAME" != "win32"; then AH_VERBATIM([_DARWIN_USE_64_BIT_INODE],[]) fi -# Check for largefile support (must be after AC_SYS_LARGEFILE) +dnl Check for largefile support (must be after AC_SYS_LARGEFILE) AC_CHECK_SIZEOF([off_t]) # If we don't have largefile support, can't handle segsize >= 2GB. @@ -1528,7 +1585,45 @@ PGAC_FUNC_WCSTOMBS_L LIBS_including_readline="$LIBS" LIBS=`echo "$LIBS" | sed -e 's/-ledit//g' -e 's/-lreadline//g'` -AC_CHECK_FUNCS([cbrt clock_gettime dlopen fdatasync getifaddrs getpeerucred getrlimit mbstowcs_l memmove poll posix_fallocate pstat pthread_is_threaded_np readlink setproctitle setsid shm_open symlink sync_file_range utime utimes wcstombs_l]) +AC_CHECK_FUNCS(m4_normalize([ + cbrt + clock_gettime + copyfile + fdatasync + getifaddrs + getpeerucred + getrlimit + mbstowcs_l + memset_s + memmove + poll + posix_fallocate + ppoll + pstat + pthread_is_threaded_np + readlink + setproctitle + setproctitle_fast + setsid + shm_open + strchrnul + strsignal + symlink + sync_file_range + uselocale + utime + utimes + wcstombs_l +])) + +# These typically are compiler builtins, for which AC_CHECK_FUNCS fails. +PGAC_CHECK_BUILTIN_FUNC([__builtin_bswap16], [int x]) +PGAC_CHECK_BUILTIN_FUNC([__builtin_bswap32], [int x]) +PGAC_CHECK_BUILTIN_FUNC([__builtin_bswap64], [long int x]) +# We assume that we needn't test all widths of these explicitly: +PGAC_CHECK_BUILTIN_FUNC([__builtin_clz], [unsigned int x]) +PGAC_CHECK_BUILTIN_FUNC([__builtin_ctz], [unsigned int x]) +PGAC_CHECK_BUILTIN_FUNC([__builtin_popcount], [unsigned int x]) AC_REPLACE_FUNCS(fseeko) case $host_os in @@ -1544,24 +1639,24 @@ esac # posix_fadvise() is a no-op on Solaris, so don't incur function overhead # by calling it, 2009-04-02 # http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/posix_fadvise.c -if test "$PORTNAME" != "solaris"; then +dnl must use AS_IF here, else AC_REQUIRES inside AC_CHECK_DECLS malfunctions +AS_IF([test "$PORTNAME" != "solaris"], [ AC_CHECK_FUNCS(posix_fadvise) AC_CHECK_DECLS(posix_fadvise, [], [], [#include ]) -fi +]) # fi AC_CHECK_DECLS(fdatasync, [], [], [#include ]) AC_CHECK_DECLS([strlcat, strlcpy, strnlen]) # This is probably only present on macOS, but may as well check always AC_CHECK_DECLS(F_FULLFSYNC, [], [], [#include ]) -HAVE_IPV6=no +AC_CHECK_DECLS([RTLD_GLOBAL, RTLD_NOW], [], [], [#include ]) + AC_CHECK_TYPE([struct sockaddr_in6], - [AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if you have support for IPv6.]) - HAVE_IPV6=yes], + [AC_DEFINE(HAVE_IPV6, 1, [Define to 1 if you have support for IPv6.])], [], [$ac_includes_default #include ]) -AC_SUBST(HAVE_IPV6) AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS], [AC_LINK_IFELSE([AC_LANG_PROGRAM( @@ -1577,53 +1672,6 @@ if test "$pgac_cv_var_PS_STRINGS" = yes ; then fi -# We use our snprintf.c emulation if either snprintf() or vsnprintf() -# is missing. Yes, there are machines that have only one. We may -# also decide to use snprintf.c if snprintf() is present but does not -# have all the features we need --- see below. - -if test "$PORTNAME" = "win32"; then - # Win32 gets snprintf.c built unconditionally. - # - # To properly translate all NLS languages strings, we must support the - # *printf() %$ format, which allows *printf() arguments to be selected - # by position in the translated string. - # - # libintl versions < 0.13 use the native *printf() functions, and Win32 - # *printf() doesn't understand %$, so we must use our /port versions, - # which do understand %$. libintl versions >= 0.13 include their own - # *printf versions on Win32. The libintl 0.13 release note text is: - # - # C format strings with positions, as they arise when a translator - # needs to reorder a sentence, are now supported on all platforms. - # On those few platforms (NetBSD and Woe32) for which the native - # printf()/fprintf()/... functions don't support such format - # strings, replacements are provided through . - # - # We could use libintl >= 0.13's *printf() if we were sure that we had - # a litint >= 0.13 at runtime, but seeing that there is no clean way - # to guarantee that, it is best to just use our own, so we are sure to - # get %$ support. In include/port.h we disable the *printf() macros - # that might have been defined by libintl. - # - # We do this unconditionally whether NLS is used or not so we are sure - # that all Win32 libraries and binaries behave the same. - pgac_need_repl_snprintf=yes -else - pgac_need_repl_snprintf=no - AC_CHECK_FUNCS(snprintf, [], pgac_need_repl_snprintf=yes) - AC_CHECK_FUNCS(vsnprintf, [], pgac_need_repl_snprintf=yes) -fi - - -# Check whether declares snprintf() and vsnprintf(); if not, -# include/c.h will provide declarations. Note this is a separate test -# from whether the functions exist in the C library --- there are -# systems that have the functions but don't bother to declare them :-( - -AC_CHECK_DECLS([snprintf, vsnprintf]) - - dnl Cannot use AC_CHECK_FUNC because isinf may be a macro AC_CACHE_CHECK([for isinf], ac_cv_func_isinf, [AC_LINK_IFELSE([AC_LANG_PROGRAM([ @@ -1642,7 +1690,37 @@ else AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break]) fi -AC_REPLACE_FUNCS([crypt fls getopt getrusage inet_aton mkdtemp random rint srandom strerror strlcat strlcpy strnlen]) +AC_REPLACE_FUNCS(m4_normalize([ + dlopen + explicit_bzero + fls + getopt + getrusage + inet_aton + mkdtemp + pread + pwrite + random + rint + srandom + strlcat + strlcpy + strnlen + strtof +])) + +case $host_os in + # Cygwin and (apparently, based on test results) Mingw both + # have a broken strtof(), so substitute the same replacement + # code we use with VS2013. That's not a perfect fix, since + # (unlike with VS2013) it doesn't avoid double-rounding, but + # we have no better options. To get that, though, we have to + # force the file to be compiled despite HAVE_STRTOF. + mingw*|cygwin*) + AC_LIBOBJ([strtof]) + AC_MSG_NOTICE([On $host_os we will use our strtof wrapper.]) + ;; +esac case $host_os in @@ -1676,9 +1754,9 @@ else AC_LIBOBJ(getopt_long) fi -# Solaris' getopt() doesn't do what we want for long options, so always use -# our version on that platform. -if test "$PORTNAME" = "solaris"; then +# On OpenBSD and Solaris, getopt() doesn't do what we want for long options +# (i.e., allow '-' as a flag character), so use our version on those platforms. +if test "$PORTNAME" = "openbsd" -o "$PORTNAME" = "solaris"; then AC_LIBOBJ(getopt) fi @@ -1691,6 +1769,7 @@ fi # Win32 (really MinGW) support if test "$PORTNAME" = "win32"; then + AC_CHECK_FUNCS(_configthreadlocale) AC_REPLACE_FUNCS(gettimeofday) AC_LIBOBJ(dirmod) AC_LIBOBJ(kill) @@ -1719,14 +1798,6 @@ if test "$PORTNAME" = "cygwin"; then AC_LIBOBJ(dirmod) fi -AC_CHECK_DECLS([sys_siglist], [], [], -[#include -/* NetBSD declares sys_siglist in unistd.h. */ -#ifdef HAVE_UNISTD_H -# include -#endif -]) - AC_CHECK_FUNC(syslog, [AC_CHECK_HEADER(syslog.h, [AC_DEFINE(HAVE_SYSLOG, 1, [Define to 1 if you have the syslog interface.])])]) @@ -1749,8 +1820,10 @@ if test x"$pgac_cv_var_int_optreset" = x"yes"; then AC_DEFINE(HAVE_INT_OPTRESET, 1, [Define to 1 if you have the global variable 'int optreset'.]) fi -AC_CHECK_FUNCS([strtoll strtoq], [break]) -AC_CHECK_FUNCS([strtoull strtouq], [break]) +AC_CHECK_FUNCS([strtoll __strtoll strtoq], [break]) +AC_CHECK_FUNCS([strtoull __strtoull strtouq], [break]) +# strto[u]ll may exist but not be declared +AC_CHECK_DECLS([strtoll, strtoull]) if test "$with_icu" = yes; then ac_save_CPPFLAGS=$CPPFLAGS @@ -1763,6 +1836,10 @@ if test "$with_icu" = yes; then CPPFLAGS=$ac_save_CPPFLAGS fi +if test "$with_llvm" = yes; then + PGAC_CHECK_LLVM_FUNCTIONS() +fi + # Lastly, restore full LIBS list and check for readline/libedit symbols LIBS="$LIBS_including_readline" @@ -1791,31 +1868,10 @@ for the exact reason.]])], # Run tests below here # -------------------- -# Force use of our snprintf if system's doesn't do arg control -# See comment above at snprintf test for details. -if test "$enable_nls" = yes -a "$pgac_need_repl_snprintf" = no; then - PGAC_FUNC_SNPRINTF_ARG_CONTROL - if test $pgac_cv_snprintf_arg_control != yes ; then - pgac_need_repl_snprintf=yes - fi -fi - - dnl Check to see if we have a working 64-bit integer type. -dnl This breaks down into two steps: -dnl (1) figure out if the compiler has a 64-bit int type with working -dnl arithmetic, and if so -dnl (2) see whether snprintf() can format the type correctly. (Currently, -dnl snprintf is the only library routine we really need for int8 support.) -dnl It's entirely possible to have a compiler that handles a 64-bit type -dnl when the C library doesn't; this is fairly likely when using gcc on -dnl an older platform, for example. -dnl If there is no native snprintf() or it does not handle the 64-bit type, -dnl we force our own version of snprintf() to be used instead. -dnl Note this test must be run after our initial check for snprintf/vsnprintf. - -dnl As of Postgres 8.4, we no longer support compilers without a working -dnl 64-bit type. But we still handle the case of snprintf being broken. +dnl Since Postgres 8.4, we no longer support compilers without a working +dnl 64-bit type; but we have to determine whether that type is called +dnl "long int" or "long long int". PGAC_TYPE_64BIT_INT([long int]) @@ -1833,46 +1889,15 @@ fi AC_DEFINE_UNQUOTED(PG_INT64_TYPE, $pg_int64_type, [Define to the name of a signed 64-bit integer type.]) -# If we found "long int" is 64 bits, assume snprintf handles it. If -# we found we need to use "long long int", better check. We cope with -# snprintfs that use %lld, %qd, or %I64d as the format. If none of these -# work, fall back to our own snprintf emulation (which we know uses %lld). - -if test "$HAVE_LONG_LONG_INT_64" = yes ; then - if test $pgac_need_repl_snprintf = no; then - PGAC_FUNC_SNPRINTF_LONG_LONG_INT_MODIFIER - if test "$LONG_LONG_INT_MODIFIER" = ""; then - # Force usage of our own snprintf, since system snprintf is broken - pgac_need_repl_snprintf=yes - LONG_LONG_INT_MODIFIER='ll' - fi - else - # Here if we previously decided we needed to use our own snprintf - LONG_LONG_INT_MODIFIER='ll' - fi +# Select the printf length modifier that goes with that, too. +if test x"$pg_int64_type" = x"long long int" ; then + INT64_MODIFIER='"ll"' else - # Here if we are not using 'long long int' at all - LONG_LONG_INT_MODIFIER='l' + INT64_MODIFIER='"l"' fi -INT64_MODIFIER="\"$LONG_LONG_INT_MODIFIER\"" - AC_DEFINE_UNQUOTED(INT64_MODIFIER, $INT64_MODIFIER, - [Define to the appropriate snprintf length modifier for 64-bit ints.]) - -# Also force use of our snprintf if the system's doesn't support the %z flag. -if test "$pgac_need_repl_snprintf" = no; then - PGAC_FUNC_SNPRINTF_SIZE_T_SUPPORT - if test "$pgac_cv_snprintf_size_t_support" != yes; then - pgac_need_repl_snprintf=yes - fi -fi - -# Now we have checked all the reasons to replace snprintf -if test $pgac_need_repl_snprintf = yes; then - AC_DEFINE(USE_REPL_SNPRINTF, 1, [Use replacement snprintf() functions.]) - AC_LIBOBJ(snprintf) -fi + [Define to the appropriate printf length modifier for 64-bit ints.]) # has to be down here, rather than with the other builtins, because # the test uses PG_INT64_TYPE. @@ -2014,22 +2039,6 @@ if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then fi AC_SUBST(CFLAGS_ARMV8_CRC32C) -# In order to detect at runtime, if the ARM CRC Extension is available, -# we will do "getauxval(AT_HWCAP) & HWCAP_CRC32". Check if we have -# everything we need for that. -AC_CHECK_FUNCS([getauxval]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ -#include -#include -], [ -#ifndef AT_HWCAP -#error AT_HWCAP not defined -#endif -#ifndef HWCAP_CRC32 -#error HWCAP_CRC32 not defined -#endif -])], [HAVE_HWCAP_CRC32=1]) - # Select CRC-32C implementation. # # If we are targeting a processor that has Intel SSE 4.2 instructions, we can @@ -2060,9 +2069,8 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" && if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then USE_ARMV8_CRC32C=1 else - # ARM CRC Extension, with runtime check? The getauxval() function and - # HWCAP_CRC32 are needed for the runtime check. - if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$ac_cv_func_getauxval" = x"yes" && test x"$HAVE_HWCAP_CRC32" = x"1"; then + # ARM CRC Extension, with runtime check? + if test x"$pgac_armv8_crc32c_intrinsics" = x"yes"; then USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK=1 else # fall back to slicing-by-8 algorithm, which doesn't require any @@ -2154,7 +2162,7 @@ fi # in the template or configure command line. # If not selected manually, try to select a source automatically. -if test "$enable_strong_random" = "yes" && test x"$USE_OPENSSL_RANDOM" = x"" && test x"$USE_WIN32_RANDOM" = x"" && test x"$USE_DEV_URANDOM" = x"" ; then +if test x"$USE_OPENSSL_RANDOM" = x"" && test x"$USE_WIN32_RANDOM" = x"" && test x"$USE_DEV_URANDOM" = x"" ; then if test x"$with_openssl" = x"yes" ; then USE_OPENSSL_RANDOM=1 elif test "$PORTNAME" = "win32" ; then @@ -2169,28 +2177,19 @@ if test "$enable_strong_random" = "yes" && test x"$USE_OPENSSL_RANDOM" = x"" && fi AC_MSG_CHECKING([which random number source to use]) -if test "$enable_strong_random" = yes ; then - if test x"$USE_OPENSSL_RANDOM" = x"1" ; then - AC_DEFINE(USE_OPENSSL_RANDOM, 1, [Define to use OpenSSL for random number generation]) - AC_MSG_RESULT([OpenSSL]) - elif test x"$USE_WIN32_RANDOM" = x"1" ; then - AC_DEFINE(USE_WIN32_RANDOM, 1, [Define to use native Windows API for random number generation]) - AC_MSG_RESULT([Windows native]) - elif test x"$USE_DEV_URANDOM" = x"1" ; then - AC_DEFINE(USE_DEV_URANDOM, 1, [Define to use /dev/urandom for random number generation]) - AC_MSG_RESULT([/dev/urandom]) - else - AC_MSG_ERROR([ -no source of strong random numbers was found -PostgreSQL can use OpenSSL or /dev/urandom as a source of random numbers, -for authentication protocols. You can use --disable-strong-random to use a -built-in pseudo random number generator, but that may be insecure.]) - fi - AC_DEFINE(HAVE_STRONG_RANDOM, 1, [Define to use have a strong random number source]) +if test x"$USE_OPENSSL_RANDOM" = x"1" ; then + AC_DEFINE(USE_OPENSSL_RANDOM, 1, [Define to use OpenSSL for random number generation]) + AC_MSG_RESULT([OpenSSL]) +elif test x"$USE_WIN32_RANDOM" = x"1" ; then + AC_DEFINE(USE_WIN32_RANDOM, 1, [Define to use native Windows API for random number generation]) + AC_MSG_RESULT([Windows native]) +elif test x"$USE_DEV_URANDOM" = x"1" ; then + AC_DEFINE(USE_DEV_URANDOM, 1, [Define to use /dev/urandom for random number generation]) + AC_MSG_RESULT([/dev/urandom]) else - AC_MSG_RESULT([weak builtin PRNG]) - AC_MSG_WARN([ -*** Not using a strong random number source may be insecure.]) + AC_MSG_ERROR([ +no source of strong random numbers was found +PostgreSQL can use OpenSSL or /dev/urandom as a source of random numbers.]) fi # If not set in template file, set bytes to use libc memset() @@ -2224,7 +2223,7 @@ fi # check for if test "$with_perl" = yes; then ac_save_CPPFLAGS=$CPPFLAGS - CPPFLAGS="$CPPFLAGS -I$perl_archlibexp/CORE" + CPPFLAGS="$CPPFLAGS $perl_includespec" AC_CHECK_HEADER(perl.h, [], [AC_MSG_ERROR([header file is required for Perl])], [#include ]) # While we're at it, check that we can link to libperl. @@ -2257,7 +2256,7 @@ fi # Check for DocBook and tools # PGAC_PATH_XMLLINT -PGAC_CHECK_DOCBOOK(4.2) +PGAC_CHECK_DOCBOOK(4.5) PGAC_PATH_PROGS(DBTOEPUB, dbtoepub) PGAC_PATH_PROGS(XSLTPROC, xsltproc) PGAC_PATH_PROGS(FOP, fop) @@ -2359,6 +2358,15 @@ $AWK '{printf "%d%04d", $1, $2}'`"] AC_DEFINE_UNQUOTED(PG_VERSION_NUM, $PG_VERSION_NUM, [PostgreSQL version as a number]) AC_SUBST(PG_VERSION_NUM) +# If we are inserting PG_SYSROOT into CPPFLAGS, do so symbolically not +# literally, so that it's possible to override it at build time using +# a command like "make ... PG_SYSROOT=path". This has to be done after +# we've finished all configure checks that depend on CPPFLAGS. +if test x"$PG_SYSROOT" != x; then + CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"` +fi +AC_SUBST(PG_SYSROOT) + # Begin output steps @@ -2397,10 +2405,8 @@ AC_SUBST(vpath_build) AC_CONFIG_FILES([GNUmakefile src/Makefile.global]) AC_CONFIG_LINKS([ - src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} - src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template} ]) diff --git a/contrib/adminpack/Makefile b/contrib/adminpack/Makefile index afcfac41038..689aca1b38f 100644 --- a/contrib/adminpack/Makefile +++ b/contrib/adminpack/Makefile @@ -5,7 +5,7 @@ OBJS = adminpack.o $(WIN32RES) PG_CPPFLAGS = -I$(libpq_srcdir) EXTENSION = adminpack -DATA = adminpack--1.0.sql adminpack--1.0--1.1.sql +DATA = adminpack--1.0.sql adminpack--1.0--1.1.sql adminpack--1.1--2.0.sql PGFILEDESC = "adminpack - support functions for pgAdmin" REGRESS = adminpack diff --git a/contrib/adminpack/adminpack--1.0--1.1.sql b/contrib/adminpack/adminpack--1.0--1.1.sql index 22eeee2ffa3..bb581653e0d 100644 --- a/contrib/adminpack/adminpack--1.0--1.1.sql +++ b/contrib/adminpack/adminpack--1.0--1.1.sql @@ -3,49 +3,4 @@ -- complain if script is sourced in psql, rather than via ALTER EXTENSION \echo Use "ALTER EXTENSION adminpack UPDATE TO '1.1'" to load this file. \quit -/* *********************************************** - * Administrative functions for PostgreSQL - * *********************************************** */ - -/* generic file access functions */ - -CREATE OR REPLACE FUNCTION pg_catalog.pg_file_write(text, text, bool) -RETURNS bigint -AS 'MODULE_PATHNAME', 'pg_file_write_v1_1' -LANGUAGE C VOLATILE STRICT; - -REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_write(text, text, bool) FROM PUBLIC; - -CREATE OR REPLACE FUNCTION pg_catalog.pg_file_rename(text, text, text) -RETURNS bool -AS 'MODULE_PATHNAME', 'pg_file_rename_v1_1' -LANGUAGE C VOLATILE; - -REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_rename(text, text, text) FROM PUBLIC; - -CREATE OR REPLACE FUNCTION pg_catalog.pg_file_rename(text, text) -RETURNS bool -AS 'SELECT pg_catalog.pg_file_rename($1, $2, NULL::pg_catalog.text);' -LANGUAGE SQL VOLATILE STRICT; - -CREATE OR REPLACE FUNCTION pg_catalog.pg_file_unlink(text) -RETURNS bool -AS 'MODULE_PATHNAME', 'pg_file_unlink_v1_1' -LANGUAGE C VOLATILE STRICT; - -REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_unlink(text) FROM PUBLIC; - -CREATE OR REPLACE FUNCTION pg_catalog.pg_logdir_ls() -RETURNS setof record -AS 'MODULE_PATHNAME', 'pg_logdir_ls_v1_1' -LANGUAGE C VOLATILE STRICT; - -REVOKE EXECUTE ON FUNCTION pg_catalog.pg_logdir_ls() FROM PUBLIC; - -/* These functions are now in the backend and callers should update to use those */ - -DROP FUNCTION pg_file_read(text, bigint, bigint); - -DROP FUNCTION pg_file_length(text); - -DROP FUNCTION pg_logfile_rotate(); +REVOKE EXECUTE ON FUNCTION pg_catalog.pg_logfile_rotate() FROM PUBLIC; diff --git a/contrib/adminpack/adminpack--1.1--2.0.sql b/contrib/adminpack/adminpack--1.1--2.0.sql new file mode 100644 index 00000000000..ceaeafa3789 --- /dev/null +++ b/contrib/adminpack/adminpack--1.1--2.0.sql @@ -0,0 +1,51 @@ +/* contrib/adminpack/adminpack--1.1--2.0.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION adminpack UPDATE TO '2.0'" to load this file. \quit + +/* *********************************************** + * Administrative functions for PostgreSQL + * *********************************************** */ + +/* generic file access functions */ + +CREATE OR REPLACE FUNCTION pg_catalog.pg_file_write(text, text, bool) +RETURNS bigint +AS 'MODULE_PATHNAME', 'pg_file_write_v1_1' +LANGUAGE C VOLATILE STRICT; + +REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_write(text, text, bool) FROM PUBLIC; + +CREATE OR REPLACE FUNCTION pg_catalog.pg_file_rename(text, text, text) +RETURNS bool +AS 'MODULE_PATHNAME', 'pg_file_rename_v1_1' +LANGUAGE C VOLATILE; + +REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_rename(text, text, text) FROM PUBLIC; + +CREATE OR REPLACE FUNCTION pg_catalog.pg_file_rename(text, text) +RETURNS bool +AS 'SELECT pg_catalog.pg_file_rename($1, $2, NULL::pg_catalog.text);' +LANGUAGE SQL VOLATILE STRICT; + +CREATE OR REPLACE FUNCTION pg_catalog.pg_file_unlink(text) +RETURNS bool +AS 'MODULE_PATHNAME', 'pg_file_unlink_v1_1' +LANGUAGE C VOLATILE STRICT; + +REVOKE EXECUTE ON FUNCTION pg_catalog.pg_file_unlink(text) FROM PUBLIC; + +CREATE OR REPLACE FUNCTION pg_catalog.pg_logdir_ls() +RETURNS setof record +AS 'MODULE_PATHNAME', 'pg_logdir_ls_v1_1' +LANGUAGE C VOLATILE STRICT; + +REVOKE EXECUTE ON FUNCTION pg_catalog.pg_logdir_ls() FROM PUBLIC; + +/* These functions are now in the backend and callers should update to use those */ + +DROP FUNCTION pg_file_read(text, bigint, bigint); + +DROP FUNCTION pg_file_length(text); + +DROP FUNCTION pg_logfile_rotate(); diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c index 2ce337e7b5a..e88f0a7a165 100644 --- a/contrib/adminpack/adminpack.c +++ b/contrib/adminpack/adminpack.c @@ -3,7 +3,7 @@ * adminpack.c * * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * Author: Andreas Pflug * @@ -298,7 +298,7 @@ pg_file_rename_internal(text *file1, text *file2, text *file3) fn2 = convert_and_check_filename(file2, false); if (file3 == NULL) - fn3 = 0; + fn3 = NULL; else fn3 = convert_and_check_filename(file3, false); @@ -320,7 +320,7 @@ pg_file_rename_internal(text *file1, text *file2, text *file3) return false; } - rc = access(fn3 ? fn3 : fn2, 2); + rc = access(fn3 ? fn3 : fn2, W_OK); if (rc >= 0 || errno != ENOENT) { ereport(ERROR, @@ -502,7 +502,7 @@ pg_logdir_ls_internal(FunctionCallInfo fcinfo) fctx = palloc(sizeof(directory_fctx)); - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "starttime", TIMESTAMPOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "filename", diff --git a/contrib/adminpack/adminpack.control b/contrib/adminpack/adminpack.control index 71f6ad5ddf9..12569dcdd71 100644 --- a/contrib/adminpack/adminpack.control +++ b/contrib/adminpack/adminpack.control @@ -1,6 +1,6 @@ # adminpack extension comment = 'administrative functions for PostgreSQL' -default_version = '1.1' +default_version = '2.0' module_pathname = '$libdir/adminpack' relocatable = false schema = pg_catalog diff --git a/contrib/amcheck/Makefile b/contrib/amcheck/Makefile index c5764b544fd..dcec3b85203 100644 --- a/contrib/amcheck/Makefile +++ b/contrib/amcheck/Makefile @@ -4,7 +4,7 @@ MODULE_big = amcheck OBJS = verify_nbtree.o $(WIN32RES) EXTENSION = amcheck -DATA = amcheck--1.0--1.1.sql amcheck--1.0.sql +DATA = amcheck--1.1--1.2.sql amcheck--1.0--1.1.sql amcheck--1.0.sql PGFILEDESC = "amcheck - function for verifying relation integrity" REGRESS = check check_btree diff --git a/contrib/amcheck/amcheck--1.1--1.2.sql b/contrib/amcheck/amcheck--1.1--1.2.sql new file mode 100644 index 00000000000..883530dec74 --- /dev/null +++ b/contrib/amcheck/amcheck--1.1--1.2.sql @@ -0,0 +1,19 @@ +/* contrib/amcheck/amcheck--1.1--1.2.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "ALTER EXTENSION amcheck UPDATE TO '1.2'" to load this file. \quit + +-- In order to avoid issues with dependencies when updating amcheck to 1.2, +-- create new, overloaded version of the 1.1 function signature + +-- +-- bt_index_parent_check() +-- +CREATE FUNCTION bt_index_parent_check(index regclass, + heapallindexed boolean, rootdescend boolean) +RETURNS VOID +AS 'MODULE_PATHNAME', 'bt_index_parent_check' +LANGUAGE C STRICT PARALLEL RESTRICTED; + +-- Don't want this to be available to public +REVOKE ALL ON FUNCTION bt_index_parent_check(regclass, boolean, boolean) FROM PUBLIC; diff --git a/contrib/amcheck/amcheck.control b/contrib/amcheck/amcheck.control index 469048403db..c6e310046d4 100644 --- a/contrib/amcheck/amcheck.control +++ b/contrib/amcheck/amcheck.control @@ -1,5 +1,5 @@ # amcheck extension comment = 'functions for verifying relation integrity' -default_version = '1.1' +default_version = '1.2' module_pathname = '$libdir/amcheck' relocatable = true diff --git a/contrib/amcheck/expected/check_btree.out b/contrib/amcheck/expected/check_btree.out index ed80ac46648..d7480fc96dc 100644 --- a/contrib/amcheck/expected/check_btree.out +++ b/contrib/amcheck/expected/check_btree.out @@ -1,7 +1,12 @@ --- minimal test, basically just verifying that amcheck CREATE TABLE bttest_a(id int8); CREATE TABLE bttest_b(id int8); CREATE TABLE bttest_multi(id int8, data int8); +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); +-- Stabalize tests +ALTER TABLE bttest_a SET (autovacuum_enabled = false); +ALTER TABLE bttest_b SET (autovacuum_enabled = false); +ALTER TABLE bttest_multi SET (autovacuum_enabled = false); +ALTER TABLE delete_test_table SET (autovacuum_enabled = false); INSERT INTO bttest_a SELECT * FROM generate_series(1, 100000); INSERT INTO bttest_b SELECT * FROM generate_series(100000, 1, -1); INSERT INTO bttest_multi SELECT i, i%2 FROM generate_series(1, 100000) as i; @@ -9,9 +14,9 @@ CREATE INDEX bttest_a_idx ON bttest_a USING btree (id); CREATE INDEX bttest_b_idx ON bttest_b USING btree (id); CREATE UNIQUE INDEX bttest_multi_idx ON bttest_multi USING btree (id) INCLUDE (data); -CREATE ROLE bttest_role; +CREATE ROLE regress_bttest_role; -- verify permissions are checked (error due to function not callable) -SET ROLE bttest_role; +SET ROLE regress_bttest_role; SELECT bt_index_check('bttest_a_idx'::regclass); ERROR: permission denied for function bt_index_check SELECT bt_index_parent_check('bttest_a_idx'::regclass); @@ -20,11 +25,11 @@ RESET ROLE; -- we, intentionally, don't check relation permissions - it's useful -- to run this cluster-wide with a restricted account, and as tested -- above explicit permission has to be granted for that. -GRANT EXECUTE ON FUNCTION bt_index_check(regclass) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_check(regclass, boolean) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass, boolean) TO bttest_role; -SET ROLE bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_check(regclass) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_check(regclass, boolean) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass, boolean) TO regress_bttest_role; +SET ROLE regress_bttest_role; SELECT bt_index_check('bttest_a_idx'); bt_index_check ---------------- @@ -104,25 +109,62 @@ SELECT bt_index_check('bttest_multi_idx'); (1 row) --- more expansive test for index with included columns -SELECT bt_index_parent_check('bttest_multi_idx', true); +-- more expansive tests for index with included columns +SELECT bt_index_parent_check('bttest_multi_idx', true, true); bt_index_parent_check ----------------------- (1 row) --- repeat expansive test for index built using insertions +-- repeat expansive tests for index built using insertions TRUNCATE bttest_multi; INSERT INTO bttest_multi SELECT i, i%2 FROM generate_series(1, 100000) as i; -SELECT bt_index_parent_check('bttest_multi_idx', true); +SELECT bt_index_parent_check('bttest_multi_idx', true, true); bt_index_parent_check ----------------------- (1 row) +-- +-- Test for multilevel page deletion/downlink present checks, and rootdescend +-- checks +-- +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990; +VACUUM delete_test_table; +SELECT bt_index_parent_check('delete_test_table_pkey', true); + bt_index_parent_check +----------------------- + +(1 row) + +-- +-- BUG #15597: must not assume consistent input toasting state when forming +-- tuple. Bloom filter must fingerprint normalized index tuple representation. +-- +CREATE TABLE toast_bug(buggy text); +ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE plain; +-- pg_attribute entry for toasty.buggy will have plain storage: +CREATE INDEX toasty ON toast_bug(buggy); +-- Whereas pg_attribute entry for toast_bug.buggy now has extended storage: +ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE extended; +-- Insert compressible heap tuple (comfortably exceeds TOAST_TUPLE_THRESHOLD): +INSERT INTO toast_bug SELECT repeat('a', 2200); +-- Should not get false positive report of corruption: +SELECT bt_index_check('toasty', true); + bt_index_check +---------------- + +(1 row) + -- cleanup DROP TABLE bttest_a; DROP TABLE bttest_b; DROP TABLE bttest_multi; -DROP OWNED BY bttest_role; -- permissions -DROP ROLE bttest_role; +DROP TABLE delete_test_table; +DROP TABLE toast_bug; +DROP OWNED BY regress_bttest_role; -- permissions +DROP ROLE regress_bttest_role; diff --git a/contrib/amcheck/sql/check_btree.sql b/contrib/amcheck/sql/check_btree.sql index 4ca9d2d0ed1..9a1987598da 100644 --- a/contrib/amcheck/sql/check_btree.sql +++ b/contrib/amcheck/sql/check_btree.sql @@ -1,7 +1,13 @@ --- minimal test, basically just verifying that amcheck CREATE TABLE bttest_a(id int8); CREATE TABLE bttest_b(id int8); CREATE TABLE bttest_multi(id int8, data int8); +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); + +-- Stabalize tests +ALTER TABLE bttest_a SET (autovacuum_enabled = false); +ALTER TABLE bttest_b SET (autovacuum_enabled = false); +ALTER TABLE bttest_multi SET (autovacuum_enabled = false); +ALTER TABLE delete_test_table SET (autovacuum_enabled = false); INSERT INTO bttest_a SELECT * FROM generate_series(1, 100000); INSERT INTO bttest_b SELECT * FROM generate_series(100000, 1, -1); @@ -12,10 +18,10 @@ CREATE INDEX bttest_b_idx ON bttest_b USING btree (id); CREATE UNIQUE INDEX bttest_multi_idx ON bttest_multi USING btree (id) INCLUDE (data); -CREATE ROLE bttest_role; +CREATE ROLE regress_bttest_role; -- verify permissions are checked (error due to function not callable) -SET ROLE bttest_role; +SET ROLE regress_bttest_role; SELECT bt_index_check('bttest_a_idx'::regclass); SELECT bt_index_parent_check('bttest_a_idx'::regclass); RESET ROLE; @@ -23,11 +29,11 @@ RESET ROLE; -- we, intentionally, don't check relation permissions - it's useful -- to run this cluster-wide with a restricted account, and as tested -- above explicit permission has to be granted for that. -GRANT EXECUTE ON FUNCTION bt_index_check(regclass) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_check(regclass, boolean) TO bttest_role; -GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass, boolean) TO bttest_role; -SET ROLE bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_check(regclass) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_check(regclass, boolean) TO regress_bttest_role; +GRANT EXECUTE ON FUNCTION bt_index_parent_check(regclass, boolean) TO regress_bttest_role; +SET ROLE regress_bttest_role; SELECT bt_index_check('bttest_a_idx'); SELECT bt_index_parent_check('bttest_a_idx'); RESET ROLE; @@ -63,17 +69,46 @@ COMMIT; -- normal check outside of xact for index with included columns SELECT bt_index_check('bttest_multi_idx'); --- more expansive test for index with included columns -SELECT bt_index_parent_check('bttest_multi_idx', true); +-- more expansive tests for index with included columns +SELECT bt_index_parent_check('bttest_multi_idx', true, true); --- repeat expansive test for index built using insertions +-- repeat expansive tests for index built using insertions TRUNCATE bttest_multi; INSERT INTO bttest_multi SELECT i, i%2 FROM generate_series(1, 100000) as i; -SELECT bt_index_parent_check('bttest_multi_idx', true); +SELECT bt_index_parent_check('bttest_multi_idx', true, true); + +-- +-- Test for multilevel page deletion/downlink present checks, and rootdescend +-- checks +-- +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990; +VACUUM delete_test_table; +SELECT bt_index_parent_check('delete_test_table_pkey', true); + +-- +-- BUG #15597: must not assume consistent input toasting state when forming +-- tuple. Bloom filter must fingerprint normalized index tuple representation. +-- +CREATE TABLE toast_bug(buggy text); +ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE plain; +-- pg_attribute entry for toasty.buggy will have plain storage: +CREATE INDEX toasty ON toast_bug(buggy); +-- Whereas pg_attribute entry for toast_bug.buggy now has extended storage: +ALTER TABLE toast_bug ALTER COLUMN buggy SET STORAGE extended; +-- Insert compressible heap tuple (comfortably exceeds TOAST_TUPLE_THRESHOLD): +INSERT INTO toast_bug SELECT repeat('a', 2200); +-- Should not get false positive report of corruption: +SELECT bt_index_check('toasty', true); -- cleanup DROP TABLE bttest_a; DROP TABLE bttest_b; DROP TABLE bttest_multi; -DROP OWNED BY bttest_role; -- permissions -DROP ROLE bttest_role; +DROP TABLE delete_test_table; +DROP TABLE toast_bug; +DROP OWNED BY regress_bttest_role; -- permissions +DROP ROLE regress_bttest_role; diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c index be0206d58ed..05e7d678ed4 100644 --- a/contrib/amcheck/verify_nbtree.c +++ b/contrib/amcheck/verify_nbtree.c @@ -14,7 +14,7 @@ * that every visible heap tuple has a matching index tuple. * * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/amcheck/verify_nbtree.c @@ -25,6 +25,8 @@ #include "access/htup_details.h" #include "access/nbtree.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/index.h" @@ -33,6 +35,7 @@ #include "lib/bloomfilter.h" #include "miscadmin.h" #include "storage/lmgr.h" +#include "storage/smgr.h" #include "utils/memutils.h" #include "utils/snapmgr.h" @@ -44,6 +47,8 @@ PG_MODULE_MAGIC; * block per level, which is bound by the range of BlockNumber: */ #define InvalidBtreeLevel ((uint32) InvalidBlockNumber) +#define BTreeTupleGetNKeyAtts(itup, rel) \ + Min(IndexRelationGetNumberOfKeyAttributes(rel), BTreeTupleGetNAtts(itup, rel)) /* * State associated with verifying a B-Tree index @@ -65,10 +70,14 @@ typedef struct BtreeCheckState /* B-Tree Index Relation and associated heap relation */ Relation rel; Relation heaprel; + /* rel is heapkeyspace index? */ + bool heapkeyspace; /* ShareLock held on heap/index, rather than AccessShareLock? */ bool readonly; /* Also verifying heap has no unindexed tuples? */ bool heapallindexed; + /* Also making sure non-pivot tuples can be found by new search? */ + bool rootdescend; /* Per-page context */ MemoryContext targetcontext; /* Buffer access strategy */ @@ -91,6 +100,10 @@ typedef struct BtreeCheckState /* Bloom filter fingerprints B-Tree index */ bloom_filter *filter; + /* Bloom filter fingerprints downlink blocks within tree */ + bloom_filter *downlinkfilter; + /* Right half of incomplete split marker */ + bool rightsplit; /* Debug counter */ int64 heaptuplespresent; } BtreeCheckState; @@ -114,32 +127,46 @@ PG_FUNCTION_INFO_V1(bt_index_check); PG_FUNCTION_INFO_V1(bt_index_parent_check); static void bt_index_check_internal(Oid indrelid, bool parentcheck, - bool heapallindexed); + bool heapallindexed, bool rootdescend); static inline void btree_index_checkable(Relation rel); +static inline bool btree_index_mainfork_expected(Relation rel); static void bt_check_every_level(Relation rel, Relation heaprel, - bool readonly, bool heapallindexed); + bool heapkeyspace, bool readonly, bool heapallindexed, + bool rootdescend); static BtreeLevel bt_check_level_from_leftmost(BtreeCheckState *state, - BtreeLevel level); + BtreeLevel level); static void bt_target_page_check(BtreeCheckState *state); -static ScanKey bt_right_page_check_scankey(BtreeCheckState *state); -static void bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, - ScanKey targetkey); +static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state); +static void bt_downlink_check(BtreeCheckState *state, BTScanInsert targetkey, + BlockNumber childblock); +static void bt_downlink_missing_check(BtreeCheckState *state); static void bt_tuple_present_callback(Relation index, HeapTuple htup, - Datum *values, bool *isnull, - bool tupleIsAlive, void *checkstate); + Datum *values, bool *isnull, + bool tupleIsAlive, void *checkstate); +static IndexTuple bt_normalize_tuple(BtreeCheckState *state, + IndexTuple itup); +static bool bt_rootdescend(BtreeCheckState *state, IndexTuple itup); static inline bool offset_is_negative_infinity(BTPageOpaque opaque, - OffsetNumber offset); + OffsetNumber offset); +static inline bool invariant_l_offset(BtreeCheckState *state, BTScanInsert key, + OffsetNumber upperbound); static inline bool invariant_leq_offset(BtreeCheckState *state, - ScanKey key, - OffsetNumber upperbound); -static inline bool invariant_geq_offset(BtreeCheckState *state, - ScanKey key, - OffsetNumber lowerbound); -static inline bool invariant_leq_nontarget_offset(BtreeCheckState *state, - Page other, - ScanKey key, - OffsetNumber upperbound); + BTScanInsert key, + OffsetNumber upperbound); +static inline bool invariant_g_offset(BtreeCheckState *state, BTScanInsert key, + OffsetNumber lowerbound); +static inline bool invariant_l_nontarget_offset(BtreeCheckState *state, + BTScanInsert key, + BlockNumber nontargetblock, + Page nontarget, + OffsetNumber upperbound); static Page palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum); +static inline BTScanInsert bt_mkscankey_pivotsearch(Relation rel, + IndexTuple itup); +static ItemId PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, + Page page, OffsetNumber offset); +static inline ItemPointer BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, + IndexTuple itup, bool nonpivot); /* * bt_index_check(index regclass, heapallindexed boolean) @@ -159,7 +186,7 @@ bt_index_check(PG_FUNCTION_ARGS) if (PG_NARGS() == 2) heapallindexed = PG_GETARG_BOOL(1); - bt_index_check_internal(indrelid, false, heapallindexed); + bt_index_check_internal(indrelid, false, heapallindexed, false); PG_RETURN_VOID(); } @@ -178,11 +205,14 @@ bt_index_parent_check(PG_FUNCTION_ARGS) { Oid indrelid = PG_GETARG_OID(0); bool heapallindexed = false; + bool rootdescend = false; - if (PG_NARGS() == 2) + if (PG_NARGS() >= 2) heapallindexed = PG_GETARG_BOOL(1); + if (PG_NARGS() == 3) + rootdescend = PG_GETARG_BOOL(2); - bt_index_check_internal(indrelid, true, heapallindexed); + bt_index_check_internal(indrelid, true, heapallindexed, rootdescend); PG_RETURN_VOID(); } @@ -191,7 +221,8 @@ bt_index_parent_check(PG_FUNCTION_ARGS) * Helper for bt_index_[parent_]check, coordinating the bulk of the work. */ static void -bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed) +bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, + bool rootdescend) { Oid heapid; Relation indrel; @@ -213,7 +244,7 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed) */ heapid = IndexGetRelation(indrelid, true); if (OidIsValid(heapid)) - heaprel = heap_open(heapid, lockmode); + heaprel = table_open(heapid, lockmode); else heaprel = NULL; @@ -222,12 +253,12 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed) * with heap relation locked first to prevent deadlocking). In hot * standby mode this will raise an error when parentcheck is true. * - * There is no need for the usual indcheckxmin usability horizon test here, - * even in the heapallindexed case, because index undergoing verification - * only needs to have entries for a new transaction snapshot. (If this is - * a parentcheck verification, there is no question about committed or - * recently dead heap tuples lacking index entries due to concurrent - * activity.) + * There is no need for the usual indcheckxmin usability horizon test + * here, even in the heapallindexed case, because index undergoing + * verification only needs to have entries for a new transaction snapshot. + * (If this is a parentcheck verification, there is no question about + * committed or recently dead heap tuples lacking index entries due to + * concurrent activity.) */ indrel = index_open(indrelid, lockmode); @@ -245,8 +276,22 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed) /* Relation suitable for checking as B-Tree? */ btree_index_checkable(indrel); - /* Check index, possibly against table it is an index on */ - bt_check_every_level(indrel, heaprel, parentcheck, heapallindexed); + if (btree_index_mainfork_expected(indrel)) + { + bool heapkeyspace; + + RelationOpenSmgr(indrel); + if (!smgrexists(indrel->rd_smgr, MAIN_FORKNUM)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("index \"%s\" lacks a main relation fork", + RelationGetRelationName(indrel)))); + + /* Check index, possibly against table it is an index on */ + heapkeyspace = _bt_heapkeyspace(indrel); + bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck, + heapallindexed, rootdescend); + } /* * Release locks early. That's ok here because nothing in the called @@ -255,7 +300,7 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed) */ index_close(indrel, lockmode); if (heaprel) - heap_close(heaprel, lockmode); + table_close(heaprel, lockmode); } /* @@ -284,12 +329,34 @@ btree_index_checkable(Relation rel) errdetail("Index \"%s\" is associated with temporary relation.", RelationGetRelationName(rel)))); - if (!IndexIsValid(rel->rd_index)) + if (!rel->rd_index->indisvalid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot check index \"%s\"", RelationGetRelationName(rel)), - errdetail("Index is not valid"))); + errdetail("Index is not valid."))); +} + +/* + * Check if B-Tree index relation should have a file for its main relation + * fork. Verification uses this to skip unlogged indexes when in hot standby + * mode, where there is simply nothing to verify. + * + * NB: Caller should call btree_index_checkable() before calling here. + */ +static inline bool +btree_index_mainfork_expected(Relation rel) +{ + if (rel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED || + !RecoveryInProgress()) + return true; + + ereport(NOTICE, + (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), + errmsg("cannot verify unlogged index \"%s\" during recovery, skipping", + RelationGetRelationName(rel)))); + + return false; } /* @@ -316,8 +383,8 @@ btree_index_checkable(Relation rel) * parent/child check cannot be affected.) */ static void -bt_check_every_level(Relation rel, Relation heaprel, bool readonly, - bool heapallindexed) +bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, + bool readonly, bool heapallindexed, bool rootdescend) { BtreeCheckState *state; Page metapage; @@ -335,19 +402,30 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, /* * Initialize state for entire verification operation */ - state = palloc(sizeof(BtreeCheckState)); + state = palloc0(sizeof(BtreeCheckState)); state->rel = rel; state->heaprel = heaprel; + state->heapkeyspace = heapkeyspace; state->readonly = readonly; state->heapallindexed = heapallindexed; + state->rootdescend = rootdescend; if (state->heapallindexed) { + int64 total_pages; int64 total_elems; uint64 seed; - /* Size Bloom filter based on estimated number of tuples in index */ - total_elems = (int64) state->rel->rd_rel->reltuples; + /* + * Size Bloom filter based on estimated number of tuples in index, + * while conservatively assuming that each block must contain at least + * MaxIndexTuplesPerPage / 5 non-pivot tuples. (Non-leaf pages cannot + * contain non-pivot tuples. That's okay because they generally make + * up no more than about 1% of all pages in the index.) + */ + total_pages = RelationGetNumberOfBlocks(rel); + total_elems = Max(total_pages * (MaxIndexTuplesPerPage / 5), + (int64) state->rel->rd_rel->reltuples); /* Random seed relies on backend srandom() call to avoid repetition */ seed = random(); /* Create Bloom filter to fingerprint index */ @@ -356,10 +434,13 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, /* * Register our own snapshot in !readonly case, rather than asking - * IndexBuildHeapScan() to do this for us later. This needs to happen - * before index fingerprinting begins, so we can later be certain that - * index fingerprinting should have reached all tuples returned by - * IndexBuildHeapScan(). + * table_index_build_scan() to do this for us later. This needs to + * happen before index fingerprinting begins, so we can later be + * certain that index fingerprinting should have reached all tuples + * returned by table_index_build_scan(). + * + * In readonly case, we also check for problems with missing + * downlinks. A second Bloom filter is used for this. */ if (!state->readonly) { @@ -370,13 +451,13 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, * READ COMMITTED mode. A new snapshot is guaranteed to have all * the entries it requires in the index. * - * We must defend against the possibility that an old xact snapshot - * was returned at higher isolation levels when that snapshot is - * not safe for index scans of the target index. This is possible - * when the snapshot sees tuples that are before the index's - * indcheckxmin horizon. Throwing an error here should be very - * rare. It doesn't seem worth using a secondary snapshot to avoid - * this. + * We must defend against the possibility that an old xact + * snapshot was returned at higher isolation levels when that + * snapshot is not safe for index scans of the target index. This + * is possible when the snapshot sees tuples that are before the + * index's indcheckxmin horizon. Throwing an error here should be + * very rare. It doesn't seem worth using a secondary snapshot to + * avoid this. */ if (IsolationUsesXactSnapshot() && rel->rd_index->indcheckxmin && !TransactionIdPrecedes(HeapTupleHeaderGetXmin(rel->rd_indextuple->t_data), @@ -386,8 +467,30 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, errmsg("index \"%s\" cannot be verified using transaction snapshot", RelationGetRelationName(rel)))); } + else + { + /* + * Extra readonly downlink check. + * + * In readonly case, we know that there cannot be a concurrent + * page split or a concurrent page deletion, which gives us the + * opportunity to verify that every non-ignorable page had a + * downlink one level up. We must be tolerant of interrupted page + * splits and page deletions, though. This is taken care of in + * bt_downlink_missing_check(). + */ + state->downlinkfilter = bloom_create(total_pages, work_mem, seed); + } } + Assert(!state->rootdescend || state->readonly); + if (state->rootdescend && !state->heapkeyspace) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot verify that tuples from index \"%s\" can each be found by an independent index search", + RelationGetRelationName(rel)), + errhint("Only B-Tree version 4 indexes support rootdescend verification."))); + /* Create context for page */ state->targetcontext = AllocSetContextCreate(CurrentMemoryContext, "amcheck context", @@ -426,6 +529,12 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, current.istruerootlevel = true; while (current.leftmost != P_NONE) { + /* + * Leftmost page on level cannot be right half of incomplete split. + * This can go stale immediately in !readonly case. + */ + state->rightsplit = false; + /* * Verify this level, and get left most page for next level down, if * not at leaf level @@ -447,21 +556,32 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, if (state->heapallindexed) { IndexInfo *indexinfo = BuildIndexInfo(state->rel); - HeapScanDesc scan; + TableScanDesc scan; + + /* Report on extra downlink checks performed in readonly case */ + if (state->readonly) + { + ereport(DEBUG1, + (errmsg_internal("finished verifying presence of downlink blocks within index \"%s\" with bitset %.2f%% set", + RelationGetRelationName(rel), + 100.0 * bloom_prop_bits_set(state->downlinkfilter)))); + bloom_free(state->downlinkfilter); + } /* - * Create our own scan for IndexBuildHeapScan(), rather than getting it - * to do so for us. This is required so that we can actually use the - * MVCC snapshot registered earlier in !readonly case. + * Create our own scan for table_index_build_scan(), rather than + * getting it to do so for us. This is required so that we can + * actually use the MVCC snapshot registered earlier in !readonly + * case. * - * Note that IndexBuildHeapScan() calls heap_endscan() for us. + * Note that table_index_build_scan() calls heap_endscan() for us. */ - scan = heap_beginscan_strat(state->heaprel, /* relation */ - snapshot, /* snapshot */ - 0, /* number of keys */ - NULL, /* scan key */ - true, /* buffer access strategy OK */ - true); /* syncscan OK? */ + scan = table_beginscan_strat(state->heaprel, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + true, /* buffer access strategy OK */ + true); /* syncscan OK? */ /* * Scan will behave as the first scan of a CREATE INDEX CONCURRENTLY @@ -490,8 +610,8 @@ bt_check_every_level(Relation rel, Relation heaprel, bool readonly, RelationGetRelationName(state->rel), RelationGetRelationName(state->heaprel)); - IndexBuildHeapScan(state->heaprel, state->rel, indexinfo, true, - bt_tuple_present_callback, (void *) state, scan); + table_index_build_scan(state->heaprel, state->rel, indexinfo, true, false, + bt_tuple_present_callback, (void *) state, scan); ereport(DEBUG1, (errmsg_internal("finished verifying presence of " INT64_FORMAT " tuples from table \"%s\" with bitset %.2f%% set", @@ -564,6 +684,25 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) if (P_IGNORE(opaque)) { + /* + * Since there cannot be a concurrent VACUUM operation in readonly + * mode, and since a page has no links within other pages + * (siblings and parent) once it is marked fully deleted, it + * should be impossible to land on a fully deleted page in + * readonly mode. See bt_downlink_check() for further details. + * + * The bt_downlink_check() P_ISDELETED() check is repeated here so + * that pages that are only reachable through sibling links get + * checked. + */ + if (state->readonly && P_ISDELETED(opaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("downlink or sibling link points to deleted block in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Block=%u left block=%u left link from block=%u.", + current, leftcurrent, opaque->btpo_prev))); + if (P_RIGHTMOST(opaque)) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), @@ -615,9 +754,11 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) ItemId itemid; /* Internal page -- downlink gets leftmost on next level */ - itemid = PageGetItemId(state->target, P_FIRSTDATAKEY(opaque)); + itemid = PageGetItemIdCareful(state, state->targetblock, + state->target, + P_FIRSTDATAKEY(opaque)); itup = (IndexTuple) PageGetItem(state->target, itemid); - nextleveldown.leftmost = ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)); + nextleveldown.leftmost = BTreeInnerTupleGetDownLink(itup); nextleveldown.level = opaque->btpo.level - 1; } else @@ -639,6 +780,10 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) */ } + /* + * readonly mode can only ever land on live pages and half-dead pages, + * so sibling pointers should always be in mutual agreement + */ if (state->readonly && opaque->btpo_prev != leftcurrent) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), @@ -668,6 +813,13 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) errmsg("circular link chain found in block %u of index \"%s\"", current, RelationGetRelationName(state->rel)))); + /* + * Record if page that is about to become target is the right half of + * an incomplete page split. This can go stale immediately in + * !readonly case. + */ + state->rightsplit = P_INCOMPLETE_SPLIT(opaque); + leftcurrent = current; current = opaque->btpo_next; @@ -687,24 +839,31 @@ bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level) * target page: * * - That every "real" data item is less than or equal to the high key, which - * is an upper bound on the items on the pages (where there is a high key at - * all -- pages that are rightmost lack one). + * is an upper bound on the items on the page. Data items should be + * strictly less than the high key when the page is an internal page. * - * - That within the page, every "real" item is less than or equal to the item - * immediately to its right, if any (i.e., that the items are in order within - * the page, so that the binary searches performed by index scans are sane). + * - That within the page, every data item is strictly less than the item + * immediately to its right, if any (i.e., that the items are in order + * within the page, so that the binary searches performed by index scans are + * sane). * - * - That the last item stored on the page is less than or equal to the first - * "real" data item on the page to the right (if such a first item is + * - That the last data item stored on the page is strictly less than the + * first data item on the page to the right (when such a first item is * available). * - * Furthermore, when state passed shows ShareLock held, and target page is - * internal page, function also checks: + * - Various checks on the structure of tuples themselves. For example, check + * that non-pivot tuples have no truncated attributes. * - * - That all child pages respect downlinks lower bound. + * Furthermore, when state passed shows ShareLock held, function also checks: + * + * - That all child pages respect strict lower bound from parent's pivot + * tuple. + * + * - That downlink to block was encountered in parent where that's expected. + * (Limited to heapallindexed readonly callers.) * * This is also where heapallindexed callers use their Bloom filter to - * fingerprint IndexTuples. + * fingerprint IndexTuples for later table_index_build_scan() verification. * * Note: Memory allocated in this routine is expected to be released by caller * resetting state->targetcontext. @@ -722,43 +881,39 @@ bt_target_page_check(BtreeCheckState *state) elog(DEBUG2, "verifying %u items on %s block %u", max, P_ISLEAF(topaque) ? "leaf" : "internal", state->targetblock); - - /* Check the number of attributes in high key if any */ + /* + * Check the number of attributes in high key. Note, rightmost page + * doesn't contain a high key, so nothing to check + */ if (!P_RIGHTMOST(topaque)) { - if (!_bt_check_natts(state->rel, state->target, P_HIKEY)) - { - ItemId itemid; - IndexTuple itup; - char *itid, - *htid; + ItemId itemid; + IndexTuple itup; - itemid = PageGetItemId(state->target, P_HIKEY); + /* Verify line pointer before checking tuple */ + itemid = PageGetItemIdCareful(state, state->targetblock, + state->target, P_HIKEY); + if (!_bt_check_natts(state->rel, state->heapkeyspace, state->target, + P_HIKEY)) + { itup = (IndexTuple) PageGetItem(state->target, itemid); - itid = psprintf("(%u,%u)", state->targetblock, P_HIKEY); - htid = psprintf("(%u,%u)", - ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)), - ItemPointerGetOffsetNumberNoCheck(&(itup->t_tid))); - ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("wrong number of index tuple attributes for index \"%s\"", + errmsg("wrong number of high key index tuple attributes in index \"%s\"", RelationGetRelationName(state->rel)), - errdetail_internal("Index tid=%s natts=%u points to %s tid=%s page lsn=%X/%X.", - itid, - BTreeTupGetNAtts(itup, state->rel), + errdetail_internal("Index block=%u natts=%u block type=%s page lsn=%X/%X.", + state->targetblock, + BTreeTupleGetNAtts(itup, state->rel), P_ISLEAF(topaque) ? "heap" : "index", - htid, (uint32) (state->targetlsn >> 32), (uint32) state->targetlsn))); } } - /* * Loop over page items, starting from first non-highkey item, not high - * key (if any). Also, immediately skip "negative infinity" real item (if - * any). + * key (if any). Most tests are not performed for the "negative infinity" + * real item (if any). */ for (offset = P_FIRSTDATAKEY(topaque); offset <= max; @@ -766,19 +921,21 @@ bt_target_page_check(BtreeCheckState *state) { ItemId itemid; IndexTuple itup; - ScanKey skey; size_t tupsize; + BTScanInsert skey; + bool lowersizelimit; CHECK_FOR_INTERRUPTS(); - itemid = PageGetItemId(state->target, offset); + itemid = PageGetItemIdCareful(state, state->targetblock, + state->target, offset); itup = (IndexTuple) PageGetItem(state->target, itemid); tupsize = IndexTupleSize(itup); /* * lp_len should match the IndexTuple reported length exactly, since - * lp_len is completely redundant in indexes, and both sources of tuple - * length are MAXALIGN()'d. nbtree does not use lp_len all that + * lp_len is completely redundant in indexes, and both sources of + * tuple length are MAXALIGN()'d. nbtree does not use lp_len all that * frequently, and is surprisingly tolerant of corrupt lp_len fields. */ if (tupsize != ItemIdGetLength(itemid)) @@ -791,10 +948,11 @@ bt_target_page_check(BtreeCheckState *state) tupsize, ItemIdGetLength(itemid), (uint32) (state->targetlsn >> 32), (uint32) state->targetlsn), - errhint("This could be a torn page problem"))); + errhint("This could be a torn page problem."))); /* Check the number of index tuple attributes */ - if (!_bt_check_natts(state->rel, state->target, offset)) + if (!_bt_check_natts(state->rel, state->heapkeyspace, state->target, + offset)) { char *itid, *htid; @@ -806,30 +964,123 @@ bt_target_page_check(BtreeCheckState *state) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("wrong number of index tuple attributes for index \"%s\"", + errmsg("wrong number of index tuple attributes in index \"%s\"", RelationGetRelationName(state->rel)), errdetail_internal("Index tid=%s natts=%u points to %s tid=%s page lsn=%X/%X.", itid, - BTreeTupGetNAtts(itup, state->rel), + BTreeTupleGetNAtts(itup, state->rel), P_ISLEAF(topaque) ? "heap" : "index", htid, (uint32) (state->targetlsn >> 32), (uint32) state->targetlsn))); } + /* Fingerprint downlink blocks in heapallindexed + readonly case */ + if (state->heapallindexed && state->readonly && !P_ISLEAF(topaque)) + { + BlockNumber childblock = BTreeInnerTupleGetDownLink(itup); + + bloom_add_element(state->downlinkfilter, + (unsigned char *) &childblock, + sizeof(BlockNumber)); + } + /* - * Don't try to generate scankey using "negative infinity" garbage - * data on internal pages + * Don't try to generate scankey using "negative infinity" item on + * internal pages. They are always truncated to zero attributes. */ if (offset_is_negative_infinity(topaque, offset)) continue; + /* + * Readonly callers may optionally verify that non-pivot tuples can + * each be found by an independent search that starts from the root + */ + if (state->rootdescend && P_ISLEAF(topaque) && + !bt_rootdescend(state, itup)) + { + char *itid, + *htid; + + itid = psprintf("(%u,%u)", state->targetblock, offset); + htid = psprintf("(%u,%u)", + ItemPointerGetBlockNumber(&(itup->t_tid)), + ItemPointerGetOffsetNumber(&(itup->t_tid))); + + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("could not find tuple using search from root page in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Index tid=%s points to heap tid=%s page lsn=%X/%X.", + itid, htid, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + } + /* Build insertion scankey for current page offset */ - skey = _bt_mkscankey(state->rel, itup); + skey = bt_mkscankey_pivotsearch(state->rel, itup); + + /* + * Make sure tuple size does not exceed the relevant BTREE_VERSION + * specific limit. + * + * BTREE_VERSION 4 (which introduced heapkeyspace rules) requisitioned + * a small amount of space from BTMaxItemSize() in order to ensure + * that suffix truncation always has enough space to add an explicit + * heap TID back to a tuple -- we pessimistically assume that every + * newly inserted tuple will eventually need to have a heap TID + * appended during a future leaf page split, when the tuple becomes + * the basis of the new high key (pivot tuple) for the leaf page. + * + * Since the reclaimed space is reserved for that purpose, we must not + * enforce the slightly lower limit when the extra space has been used + * as intended. In other words, there is only a cross-version + * difference in the limit on tuple size within leaf pages. + * + * Still, we're particular about the details within BTREE_VERSION 4 + * internal pages. Pivot tuples may only use the extra space for its + * designated purpose. Enforce the lower limit for pivot tuples when + * an explicit heap TID isn't actually present. (In all other cases + * suffix truncation is guaranteed to generate a pivot tuple that's no + * larger than the first right tuple provided to it by its caller.) + */ + lowersizelimit = skey->heapkeyspace && + (P_ISLEAF(topaque) || BTreeTupleGetHeapTID(itup) == NULL); + if (tupsize > (lowersizelimit ? BTMaxItemSize(state->target) : + BTMaxItemSizeNoHeapTid(state->target))) + { + char *itid, + *htid; + + itid = psprintf("(%u,%u)", state->targetblock, offset); + htid = psprintf("(%u,%u)", + ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)), + ItemPointerGetOffsetNumberNoCheck(&(itup->t_tid))); + + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("index row size %zu exceeds maximum for index \"%s\"", + tupsize, RelationGetRelationName(state->rel)), + errdetail_internal("Index tid=%s points to %s tid=%s page lsn=%X/%X.", + itid, + P_ISLEAF(topaque) ? "heap" : "index", + htid, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + } /* Fingerprint leaf page tuples (those that point to the heap) */ if (state->heapallindexed && P_ISLEAF(topaque) && !ItemIdIsDead(itemid)) - bloom_add_element(state->filter, (unsigned char *) itup, tupsize); + { + IndexTuple norm; + + norm = bt_normalize_tuple(state, itup); + bloom_add_element(state->filter, (unsigned char *) norm, + IndexTupleSize(norm)); + /* Be tidy */ + if (norm != itup) + pfree(norm); + } /* * * High key check * @@ -850,9 +1101,35 @@ bt_target_page_check(BtreeCheckState *state) * grandparents (as well as great-grandparents, and so on). We don't * go to those lengths because that would be prohibitively expensive, * and probably not markedly more effective in practice. + * + * On the leaf level, we check that the key is <= the highkey. + * However, on non-leaf levels we check that the key is < the highkey, + * because the high key is "just another separator" rather than a copy + * of some existing key item; we expect it to be unique among all keys + * on the same level. (Suffix truncation will sometimes produce a + * leaf highkey that is an untruncated copy of the lastleft item, but + * never any other item, which necessitates weakening the leaf level + * check to <=.) + * + * Full explanation for why a highkey is never truly a copy of another + * item from the same level on internal levels: + * + * While the new left page's high key is copied from the first offset + * on the right page during an internal page split, that's not the + * full story. In effect, internal pages are split in the middle of + * the firstright tuple, not between the would-be lastleft and + * firstright tuples: the firstright key ends up on the left side as + * left's new highkey, and the firstright downlink ends up on the + * right side as right's new "negative infinity" item. The negative + * infinity tuple is truncated to zero attributes, so we're only left + * with the downlink. In other words, the copying is just an + * implementation detail of splitting in the middle of a (pivot) + * tuple. (See also: "Notes About Data Representation" in the nbtree + * README.) */ if (!P_RIGHTMOST(topaque) && - !invariant_leq_offset(state, skey, P_HIKEY)) + !(P_ISLEAF(topaque) ? invariant_leq_offset(state, skey, P_HIKEY) : + invariant_l_offset(state, skey, P_HIKEY))) { char *itid, *htid; @@ -878,11 +1155,10 @@ bt_target_page_check(BtreeCheckState *state) * * Item order check * * * Check that items are stored on page in logical order, by checking - * current item is less than or equal to next item (if any). + * current item is strictly less than next item (if any). */ if (OffsetNumberNext(offset) <= max && - !invariant_leq_offset(state, skey, - OffsetNumberNext(offset))) + !invariant_l_offset(state, skey, OffsetNumberNext(offset))) { char *itid, *htid, @@ -897,7 +1173,9 @@ bt_target_page_check(BtreeCheckState *state) OffsetNumberNext(offset)); /* Reuse itup to get pointed-to heap location of second item */ - itemid = PageGetItemId(state->target, OffsetNumberNext(offset)); + itemid = PageGetItemIdCareful(state, state->targetblock, + state->target, + OffsetNumberNext(offset)); itup = (IndexTuple) PageGetItem(state->target, itemid); nhtid = psprintf("(%u,%u)", ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)), @@ -939,13 +1217,13 @@ bt_target_page_check(BtreeCheckState *state) */ else if (offset == max) { - ScanKey rightkey; + BTScanInsert rightkey; /* Get item in next/right page */ rightkey = bt_right_page_check_scankey(state); if (rightkey && - !invariant_geq_offset(state, rightkey, max)) + !invariant_g_offset(state, rightkey, max)) { /* * As explained at length in bt_right_page_check_scankey(), @@ -989,11 +1267,19 @@ bt_target_page_check(BtreeCheckState *state) */ if (!P_ISLEAF(topaque) && state->readonly) { - BlockNumber childblock = ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)); + BlockNumber childblock = BTreeInnerTupleGetDownLink(itup); - bt_downlink_check(state, childblock, skey); + bt_downlink_check(state, skey, childblock); } } + + /* + * * Check if page has a downlink in parent * + * + * This can only be checked in heapallindexed + readonly case. + */ + if (state->heapallindexed && state->readonly) + bt_downlink_missing_check(state); } /* @@ -1012,11 +1298,12 @@ bt_target_page_check(BtreeCheckState *state) * Note that !readonly callers must reverify that target page has not * been concurrently deleted. */ -static ScanKey +static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state) { BTPageOpaque opaque; ItemId rightitem; + IndexTuple firstitup; BlockNumber targetnext; Page rightpage; OffsetNumber nline; @@ -1114,9 +1401,9 @@ bt_right_page_check_scankey(BtreeCheckState *state) * continued existence of target block as non-ignorable (not half-dead or * deleted) implies that target page was not merged into from the right by * deletion; the key space at or after target never moved left. Target's - * parent either has the same downlink to target as before, or a <= + * parent either has the same downlink to target as before, or a < * downlink due to deletion at the left of target. Target either has the - * same highkey as before, or a highkey <= before when there is a page + * same highkey as before, or a highkey < before when there is a page * split. (The rightmost concurrently-split-from-target-page page will * still have the same highkey as target was originally found to have, * which for our purposes is equivalent to target's highkey itself never @@ -1173,7 +1460,8 @@ bt_right_page_check_scankey(BtreeCheckState *state) if (P_ISLEAF(opaque) && nline >= P_FIRSTDATAKEY(opaque)) { /* Return first data item (if any) */ - rightitem = PageGetItemId(rightpage, P_FIRSTDATAKEY(opaque)); + rightitem = PageGetItemIdCareful(state, targetnext, rightpage, + P_FIRSTDATAKEY(opaque)); } else if (!P_ISLEAF(opaque) && nline >= OffsetNumberNext(P_FIRSTDATAKEY(opaque))) @@ -1182,8 +1470,8 @@ bt_right_page_check_scankey(BtreeCheckState *state) * Return first item after the internal page's "negative infinity" * item */ - rightitem = PageGetItemId(rightpage, - OffsetNumberNext(P_FIRSTDATAKEY(opaque))); + rightitem = PageGetItemIdCareful(state, targetnext, rightpage, + OffsetNumberNext(P_FIRSTDATAKEY(opaque))); } else { @@ -1204,8 +1492,8 @@ bt_right_page_check_scankey(BtreeCheckState *state) * Return first real item scankey. Note that this relies on right page * memory remaining allocated. */ - return _bt_mkscankey(state->rel, - (IndexTuple) PageGetItem(rightpage, rightitem)); + firstitup = (IndexTuple) PageGetItem(rightpage, rightitem); + return bt_mkscankey_pivotsearch(state->rel, firstitup); } /* @@ -1218,8 +1506,8 @@ bt_right_page_check_scankey(BtreeCheckState *state) * verification this way around is much more practical. */ static void -bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, - ScanKey targetkey) +bt_downlink_check(BtreeCheckState *state, BTScanInsert targetkey, + BlockNumber childblock) { OffsetNumber offset; OffsetNumber maxoffset; @@ -1268,7 +1556,8 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, /* * Verify child page has the downlink key from target page (its parent) as - * a lower bound. + * a lower bound; downlink must be strictly less than all keys on the + * page. * * Check all items, rather than checking just the first and trusting that * the operator class obeys the transitive law. @@ -1277,21 +1566,73 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, copaque = (BTPageOpaque) PageGetSpecialPointer(child); maxoffset = PageGetMaxOffsetNumber(child); + /* + * Since there cannot be a concurrent VACUUM operation in readonly mode, + * and since a page has no links within other pages (siblings and parent) + * once it is marked fully deleted, it should be impossible to land on a + * fully deleted page. + * + * It does not quite make sense to enforce that the page cannot even be + * half-dead, despite the fact the downlink is modified at the same stage + * that the child leaf page is marked half-dead. That's incorrect because + * there may occasionally be multiple downlinks from a chain of pages + * undergoing deletion, where multiple successive calls are made to + * _bt_unlink_halfdead_page() by VACUUM before it can finally safely mark + * the leaf page as fully dead. While _bt_mark_page_halfdead() usually + * removes the downlink to the leaf page that is marked half-dead, that's + * not guaranteed, so it's possible we'll land on a half-dead page with a + * downlink due to an interrupted multi-level page deletion. + * + * We go ahead with our checks if the child page is half-dead. It's safe + * to do so because we do not test the child's high key, so it does not + * matter that the original high key will have been replaced by a dummy + * truncated high key within _bt_mark_page_halfdead(). All other page + * items are left intact on a half-dead page, so there is still something + * to test. + */ + if (P_ISDELETED(copaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("downlink to deleted page found in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Parent block=%u child block=%u parent page lsn=%X/%X.", + state->targetblock, childblock, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + for (offset = P_FIRSTDATAKEY(copaque); offset <= maxoffset; offset = OffsetNumberNext(offset)) { /* * Skip comparison of target page key against "negative infinity" - * item, if any. Checking it would indicate that it's not an upper - * bound, but that's only because of the hard-coding within - * _bt_compare(). + * item, if any. Checking it would indicate that it's not a strict + * lower bound, but that's only because of the hard-coding for + * negative infinity items within _bt_compare(). + * + * If nbtree didn't truncate negative infinity tuples during internal + * page splits then we'd expect child's negative infinity key to be + * equal to the scankey/downlink from target/parent (it would be a + * "low key" in this hypothetical scenario, and so it would still need + * to be treated as a special case here). + * + * Negative infinity items can be thought of as a strict lower bound + * that works transitively, with the last non-negative-infinity pivot + * followed during a descent from the root as its "true" strict lower + * bound. Only a small number of negative infinity items are truly + * negative infinity; those that are the first items of leftmost + * internal pages. In more general terms, a negative infinity item is + * only negative infinity with respect to the subtree that the page is + * at the root of. + * + * See also: bt_rootdescend(), which can even detect transitive + * inconsistencies on cousin leaf pages. */ if (offset_is_negative_infinity(copaque, offset)) continue; - if (!invariant_leq_nontarget_offset(state, child, - targetkey, offset)) + if (!invariant_l_nontarget_offset(state, targetkey, childblock, child, + offset)) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("down-link lower bound invariant violated for index \"%s\"", @@ -1306,7 +1647,195 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, } /* - * Per-tuple callback from IndexBuildHeapScan, used to determine if index has + * Checks if page is missing a downlink that it should have. + * + * A page that lacks a downlink/parent may indicate corruption. However, we + * must account for the fact that a missing downlink can occasionally be + * encountered in a non-corrupt index. This can be due to an interrupted page + * split, or an interrupted multi-level page deletion (i.e. there was a hard + * crash or an error during a page split, or while VACUUM was deleting a + * multi-level chain of pages). + * + * Note that this can only be called in readonly mode, so there is no need to + * be concerned about concurrent page splits or page deletions. + */ +static void +bt_downlink_missing_check(BtreeCheckState *state) +{ + BTPageOpaque topaque = (BTPageOpaque) PageGetSpecialPointer(state->target); + ItemId itemid; + IndexTuple itup; + Page child; + BTPageOpaque copaque; + uint32 level; + BlockNumber childblk; + + Assert(state->heapallindexed && state->readonly); + Assert(!P_IGNORE(topaque)); + + /* No next level up with downlinks to fingerprint from the true root */ + if (P_ISROOT(topaque)) + return; + + /* + * Incomplete (interrupted) page splits can account for the lack of a + * downlink. Some inserting transaction should eventually complete the + * page split in passing, when it notices that the left sibling page is + * P_INCOMPLETE_SPLIT(). + * + * In general, VACUUM is not prepared for there to be no downlink to a + * page that it deletes. This is the main reason why the lack of a + * downlink can be reported as corruption here. It's not obvious that an + * invalid missing downlink can result in wrong answers to queries, + * though, since index scans that land on the child may end up + * consistently moving right. The handling of concurrent page splits (and + * page deletions) within _bt_moveright() cannot distinguish + * inconsistencies that last for a moment from inconsistencies that are + * permanent and irrecoverable. + * + * VACUUM isn't even prepared to delete pages that have no downlink due to + * an incomplete page split, but it can detect and reason about that case + * by design, so it shouldn't be taken to indicate corruption. See + * _bt_pagedel() for full details. + */ + if (state->rightsplit) + { + ereport(DEBUG1, + (errcode(ERRCODE_NO_DATA), + errmsg("harmless interrupted page split detected in index %s", + RelationGetRelationName(state->rel)), + errdetail_internal("Block=%u level=%u left sibling=%u page lsn=%X/%X.", + state->targetblock, topaque->btpo.level, + topaque->btpo_prev, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + return; + } + + /* Target's downlink is typically present in parent/fingerprinted */ + if (!bloom_lacks_element(state->downlinkfilter, + (unsigned char *) &state->targetblock, + sizeof(BlockNumber))) + return; + + /* + * Target is probably the "top parent" of a multi-level page deletion. + * We'll need to descend the subtree to make sure that descendant pages + * are consistent with that, though. + * + * If the target page (which must be non-ignorable) is a leaf page, then + * clearly it can't be the top parent. The lack of a downlink is probably + * a symptom of a broad problem that could just as easily cause + * inconsistencies anywhere else. + */ + if (P_ISLEAF(topaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("leaf index block lacks downlink in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Block=%u page lsn=%X/%X.", + state->targetblock, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + + /* Descend from the target page, which is an internal page */ + elog(DEBUG1, "checking for interrupted multi-level deletion due to missing downlink in index \"%s\"", + RelationGetRelationName(state->rel)); + + level = topaque->btpo.level; + itemid = PageGetItemIdCareful(state, state->targetblock, state->target, + P_FIRSTDATAKEY(topaque)); + itup = (IndexTuple) PageGetItem(state->target, itemid); + childblk = BTreeInnerTupleGetDownLink(itup); + for (;;) + { + CHECK_FOR_INTERRUPTS(); + + child = palloc_btree_page(state, childblk); + copaque = (BTPageOpaque) PageGetSpecialPointer(child); + + if (P_ISLEAF(copaque)) + break; + + /* Do an extra sanity check in passing on internal pages */ + if (copaque->btpo.level != level - 1) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("downlink points to block in index \"%s\" whose level is not one level down", + RelationGetRelationName(state->rel)), + errdetail_internal("Top parent/target block=%u block pointed to=%u expected level=%u level in pointed to block=%u.", + state->targetblock, childblk, + level - 1, copaque->btpo.level))); + + level = copaque->btpo.level; + itemid = PageGetItemIdCareful(state, childblk, child, + P_FIRSTDATAKEY(copaque)); + itup = (IndexTuple) PageGetItem(child, itemid); + childblk = BTreeInnerTupleGetDownLink(itup); + /* Be slightly more pro-active in freeing this memory, just in case */ + pfree(child); + } + + /* + * Since there cannot be a concurrent VACUUM operation in readonly mode, + * and since a page has no links within other pages (siblings and parent) + * once it is marked fully deleted, it should be impossible to land on a + * fully deleted page. See bt_downlink_check() for further details. + * + * The bt_downlink_check() P_ISDELETED() check is repeated here because + * bt_downlink_check() does not visit pages reachable through negative + * infinity items. Besides, bt_downlink_check() is unwilling to descend + * multiple levels. (The similar bt_downlink_check() P_ISDELETED() check + * within bt_check_level_from_leftmost() won't reach the page either, + * since the leaf's live siblings should have their sibling links updated + * to bypass the deletion target page when it is marked fully dead.) + * + * If this error is raised, it might be due to a previous multi-level page + * deletion that failed to realize that it wasn't yet safe to mark the + * leaf page as fully dead. A "dangling downlink" will still remain when + * this happens. The fact that the dangling downlink's page (the leaf's + * parent/ancestor page) lacked a downlink is incidental. + */ + if (P_ISDELETED(copaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("downlink to deleted leaf page found in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Top parent/target block=%u leaf block=%u top parent/target lsn=%X/%X.", + state->targetblock, childblk, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); + + /* + * Iff leaf page is half-dead, its high key top parent link should point + * to what VACUUM considered to be the top parent page at the instant it + * was interrupted. Provided the high key link actually points to the + * target page, the missing downlink we detected is consistent with there + * having been an interrupted multi-level page deletion. This means that + * the subtree with the target page at its root (a page deletion chain) is + * in a consistent state, enabling VACUUM to resume deleting the entire + * chain the next time it encounters the half-dead leaf page. + */ + if (P_ISHALFDEAD(copaque) && !P_RIGHTMOST(copaque)) + { + itemid = PageGetItemIdCareful(state, childblk, child, P_HIKEY); + itup = (IndexTuple) PageGetItem(child, itemid); + if (BTreeTupleGetTopParent(itup) == state->targetblock) + return; + } + + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("internal index block lacks downlink in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Block=%u level=%u page lsn=%X/%X.", + state->targetblock, topaque->btpo.level, + (uint32) (state->targetlsn >> 32), + (uint32) state->targetlsn))); +} + +/* + * Per-tuple callback from table_index_build_scan, used to determine if index has * all the entries that definitely should have been observed in leaf pages of * the target index (that is, all IndexTuples that were fingerprinted by our * Bloom filter). All heapallindexed checks occur here. @@ -1331,7 +1860,7 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, * verification, just in case it's a cross-page invariant issue, though that * isn't particularly likely. * - * IndexBuildHeapScan() expects to be able to find the root tuple when a + * table_index_build_scan() expects to be able to find the root tuple when a * heap-only tuple (the live tuple at the end of some HOT chain) needs to be * indexed, in order to replace the actual tuple's TID with the root tuple's * TID (which is what we're actually passed back here). The index build heap @@ -1347,7 +1876,7 @@ bt_downlink_check(BtreeCheckState *state, BlockNumber childblock, * setting will probably also leave the index in a corrupt state before too * long, the problem is nonetheless that there is heap corruption.) * - * Heap-only tuple handling within IndexBuildHeapScan() works in a way that + * Heap-only tuple handling within table_index_build_scan() works in a way that * helps us to detect index tuples that contain the wrong values (values that * don't match the latest tuple in the HOT chain). This can happen when there * is no superseding index tuple due to a faulty assessment of HOT safety, @@ -1365,41 +1894,24 @@ bt_tuple_present_callback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *checkstate) { BtreeCheckState *state = (BtreeCheckState *) checkstate; - IndexTuple itup; + IndexTuple itup, + norm; Assert(state->heapallindexed); - /* - * Generate an index tuple for fingerprinting. - * - * Index tuple formation is assumed to be deterministic, and IndexTuples - * are assumed immutable. While the LP_DEAD bit is mutable in leaf pages, - * that's ItemId metadata, which was not fingerprinted. (There will often - * be some dead-to-everyone IndexTuples fingerprinted by the Bloom filter, - * but we only try to detect the absence of needed tuples, so that's okay.) - * - * Note that we rely on deterministic index_form_tuple() TOAST compression. - * If index_form_tuple() was ever enhanced to compress datums out-of-line, - * or otherwise varied when or how compression was applied, our assumption - * would break, leading to false positive reports of corruption. For now, - * we don't decompress/normalize toasted values as part of fingerprinting. - * - * In future, non-pivot index tuples might get use of - * BT_N_KEYS_OFFSET_MASK. Then binary representation of index tuple linked - * to particular heap tuple might vary and meeds to be normalized before - * bloom filter lookup. - */ + /* Generate a normalized index tuple for fingerprinting */ itup = index_form_tuple(RelationGetDescr(index), values, isnull); itup->t_tid = htup->t_self; + norm = bt_normalize_tuple(state, itup); /* Probe Bloom filter -- tuple should be present */ - if (bloom_lacks_element(state->filter, (unsigned char *) itup, - IndexTupleSize(itup))) + if (bloom_lacks_element(state->filter, (unsigned char *) norm, + IndexTupleSize(norm))) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("heap tuple (%u,%u) from table \"%s\" lacks matching index tuple within index \"%s\"", - ItemPointerGetBlockNumberNoCheck(&(itup->t_tid)), - ItemPointerGetOffsetNumberNoCheck(&(itup->t_tid)), + ItemPointerGetBlockNumber(&(itup->t_tid)), + ItemPointerGetOffsetNumber(&(itup->t_tid)), RelationGetRelationName(state->heaprel), RelationGetRelationName(state->rel)), !state->readonly @@ -1408,6 +1920,190 @@ bt_tuple_present_callback(Relation index, HeapTuple htup, Datum *values, state->heaptuplespresent++; pfree(itup); + /* Cannot leak memory here */ + if (norm != itup) + pfree(norm); +} + +/* + * Normalize an index tuple for fingerprinting. + * + * In general, index tuple formation is assumed to be deterministic by + * heapallindexed verification, and IndexTuples are assumed immutable. While + * the LP_DEAD bit is mutable in leaf pages, that's ItemId metadata, which is + * not fingerprinted. Normalization is required to compensate for corner + * cases where the determinism assumption doesn't quite work. + * + * There is currently one such case: index_form_tuple() does not try to hide + * the source TOAST state of input datums. The executor applies TOAST + * compression for heap tuples based on different criteria to the compression + * applied within btinsert()'s call to index_form_tuple(): it sometimes + * compresses more aggressively, resulting in compressed heap tuple datums but + * uncompressed corresponding index tuple datums. A subsequent heapallindexed + * verification will get a logically equivalent though bitwise unequal tuple + * from index_form_tuple(). False positive heapallindexed corruption reports + * could occur without normalizing away the inconsistency. + * + * Returned tuple is often caller's own original tuple. Otherwise, it is a + * new representation of caller's original index tuple, palloc()'d in caller's + * memory context. + * + * Note: This routine is not concerned with distinctions about the + * representation of tuples beyond those that might break heapallindexed + * verification. In particular, it won't try to normalize opclass-equal + * datums with potentially distinct representations (e.g., btree/numeric_ops + * index datums will not get their display scale normalized-away here). + * Normalization may need to be expanded to handle more cases in the future, + * though. For example, it's possible that non-pivot tuples could in the + * future have alternative logically equivalent representations due to using + * the INDEX_ALT_TID_MASK bit to implement intelligent deduplication. + */ +static IndexTuple +bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup) +{ + TupleDesc tupleDescriptor = RelationGetDescr(state->rel); + Datum normalized[INDEX_MAX_KEYS]; + bool isnull[INDEX_MAX_KEYS]; + bool toast_free[INDEX_MAX_KEYS]; + bool formnewtup = false; + IndexTuple reformed; + int i; + + /* Easy case: It's immediately clear that tuple has no varlena datums */ + if (!IndexTupleHasVarwidths(itup)) + return itup; + + for (i = 0; i < tupleDescriptor->natts; i++) + { + Form_pg_attribute att; + + att = TupleDescAttr(tupleDescriptor, i); + + /* Assume untoasted/already normalized datum initially */ + toast_free[i] = false; + normalized[i] = index_getattr(itup, att->attnum, + tupleDescriptor, + &isnull[i]); + if (att->attbyval || att->attlen != -1 || isnull[i]) + continue; + + /* + * Callers always pass a tuple that could safely be inserted into the + * index without further processing, so an external varlena header + * should never be encountered here + */ + if (VARATT_IS_EXTERNAL(DatumGetPointer(normalized[i]))) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("external varlena datum in tuple that references heap row (%u,%u) in index \"%s\"", + ItemPointerGetBlockNumber(&(itup->t_tid)), + ItemPointerGetOffsetNumber(&(itup->t_tid)), + RelationGetRelationName(state->rel)))); + else if (VARATT_IS_COMPRESSED(DatumGetPointer(normalized[i]))) + { + formnewtup = true; + normalized[i] = PointerGetDatum(PG_DETOAST_DATUM(normalized[i])); + toast_free[i] = true; + } + } + + /* Easier case: Tuple has varlena datums, none of which are compressed */ + if (!formnewtup) + return itup; + + /* + * Hard case: Tuple had compressed varlena datums that necessitate + * creating normalized version of the tuple from uncompressed input datums + * (normalized input datums). This is rather naive, but shouldn't be + * necessary too often. + * + * Note that we rely on deterministic index_form_tuple() TOAST compression + * of normalized input. + */ + reformed = index_form_tuple(tupleDescriptor, normalized, isnull); + reformed->t_tid = itup->t_tid; + + /* Cannot leak memory here */ + for (i = 0; i < tupleDescriptor->natts; i++) + if (toast_free[i]) + pfree(DatumGetPointer(normalized[i])); + + return reformed; +} + +/* + * Search for itup in index, starting from fast root page. itup must be a + * non-pivot tuple. This is only supported with heapkeyspace indexes, since + * we rely on having fully unique keys to find a match with only a single + * visit to a leaf page, barring an interrupted page split, where we may have + * to move right. (A concurrent page split is impossible because caller must + * be readonly caller.) + * + * This routine can detect very subtle transitive consistency issues across + * more than one level of the tree. Leaf pages all have a high key (even the + * rightmost page has a conceptual positive infinity high key), but not a low + * key. Their downlink in parent is a lower bound, which along with the high + * key is almost enough to detect every possible inconsistency. A downlink + * separator key value won't always be available from parent, though, because + * the first items of internal pages are negative infinity items, truncated + * down to zero attributes during internal page splits. While it's true that + * bt_downlink_check() and the high key check can detect most imaginable key + * space problems, there are remaining problems it won't detect with non-pivot + * tuples in cousin leaf pages. Starting a search from the root for every + * existing leaf tuple detects small inconsistencies in upper levels of the + * tree that cannot be detected any other way. (Besides all this, this is + * probably also useful as a direct test of the code used by index scans + * themselves.) + */ +static bool +bt_rootdescend(BtreeCheckState *state, IndexTuple itup) +{ + BTScanInsert key; + BTStack stack; + Buffer lbuf; + bool exists; + + key = _bt_mkscankey(state->rel, itup); + Assert(key->heapkeyspace && key->scantid != NULL); + + /* + * Search from root. + * + * Ideally, we would arrange to only move right within _bt_search() when + * an interrupted page split is detected (i.e. when the incomplete split + * bit is found to be set), but for now we accept the possibility that + * that could conceal an inconsistency. + */ + Assert(state->readonly && state->rootdescend); + exists = false; + stack = _bt_search(state->rel, key, &lbuf, BT_READ, NULL); + + if (BufferIsValid(lbuf)) + { + BTInsertStateData insertstate; + OffsetNumber offnum; + Page page; + + insertstate.itup = itup; + insertstate.itemsz = MAXALIGN(IndexTupleSize(itup)); + insertstate.itup_key = key; + insertstate.bounds_valid = false; + insertstate.buf = lbuf; + + /* Get matching tuple on leaf page */ + offnum = _bt_binsrch_insert(state->rel, &insertstate); + /* Compare first >= matching item on leaf page, if any */ + page = BufferGetPage(lbuf); + if (offnum <= PageGetMaxOffsetNumber(page) && + _bt_compare(state->rel, key, page, offnum) == 0) + exists = true; + _bt_relbuf(state->rel, lbuf); + } + + _bt_freestack(stack); + pfree(key); + + return exists; } /* @@ -1430,9 +2126,9 @@ offset_is_negative_infinity(BTPageOpaque opaque, OffsetNumber offset) * infinity item is either first or second line item, or there is none * within page. * - * "Negative infinity" tuple is a special corner case of pivot tuples, - * it has zero attributes while rest of pivot tuples have nkeyatts number - * of attributes. + * Negative infinity items are a special case among pivot tuples. They + * always have zero attributes, while all other pivot tuples always have + * nkeyatts attributes. * * Right-most pages don't have a high key, but could be said to * conceptually have a "positive infinity" high key. Thus, there is a @@ -1446,65 +2142,181 @@ offset_is_negative_infinity(BTPageOpaque opaque, OffsetNumber offset) return !P_ISLEAF(opaque) && offset == P_FIRSTDATAKEY(opaque); } +/* + * Does the invariant hold that the key is strictly less than a given upper + * bound offset item? + * + * Verifies line pointer on behalf of caller. + * + * If this function returns false, convention is that caller throws error due + * to corruption. + */ +static inline bool +invariant_l_offset(BtreeCheckState *state, BTScanInsert key, + OffsetNumber upperbound) +{ + ItemId itemid; + int32 cmp; + + Assert(key->pivotsearch); + + /* Verify line pointer before checking tuple */ + itemid = PageGetItemIdCareful(state, state->targetblock, state->target, + upperbound); + /* pg_upgrade'd indexes may legally have equal sibling tuples */ + if (!key->heapkeyspace) + return invariant_leq_offset(state, key, upperbound); + + cmp = _bt_compare(state->rel, key, state->target, upperbound); + + /* + * _bt_compare() is capable of determining that a scankey with a + * filled-out attribute is greater than pivot tuples where the comparison + * is resolved at a truncated attribute (value of attribute in pivot is + * minus infinity). However, it is not capable of determining that a + * scankey is _less than_ a tuple on the basis of a comparison resolved at + * _scankey_ minus infinity attribute. Complete an extra step to simulate + * having minus infinity values for omitted scankey attribute(s). + */ + if (cmp == 0) + { + BTPageOpaque topaque; + IndexTuple ritup; + int uppnkeyatts; + ItemPointer rheaptid; + bool nonpivot; + + ritup = (IndexTuple) PageGetItem(state->target, itemid); + topaque = (BTPageOpaque) PageGetSpecialPointer(state->target); + nonpivot = P_ISLEAF(topaque) && upperbound >= P_FIRSTDATAKEY(topaque); + + /* Get number of keys + heap TID for item to the right */ + uppnkeyatts = BTreeTupleGetNKeyAtts(ritup, state->rel); + rheaptid = BTreeTupleGetHeapTIDCareful(state, ritup, nonpivot); + + /* Heap TID is tiebreaker key attribute */ + if (key->keysz == uppnkeyatts) + return key->scantid == NULL && rheaptid != NULL; + + return key->keysz < uppnkeyatts; + } + + return cmp < 0; +} + /* * Does the invariant hold that the key is less than or equal to a given upper * bound offset item? * + * Caller should have verified that upperbound's line pointer is consistent + * using PageGetItemIdCareful() call. + * * If this function returns false, convention is that caller throws error due * to corruption. */ static inline bool -invariant_leq_offset(BtreeCheckState *state, ScanKey key, +invariant_leq_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber upperbound) { - int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(state->rel); int32 cmp; - cmp = _bt_compare(state->rel, nkeyatts, key, state->target, upperbound); + Assert(key->pivotsearch); + + cmp = _bt_compare(state->rel, key, state->target, upperbound); return cmp <= 0; } /* - * Does the invariant hold that the key is greater than or equal to a given - * lower bound offset item? + * Does the invariant hold that the key is strictly greater than a given lower + * bound offset item? + * + * Caller should have verified that lowerbound's line pointer is consistent + * using PageGetItemIdCareful() call. * * If this function returns false, convention is that caller throws error due * to corruption. */ static inline bool -invariant_geq_offset(BtreeCheckState *state, ScanKey key, - OffsetNumber lowerbound) +invariant_g_offset(BtreeCheckState *state, BTScanInsert key, + OffsetNumber lowerbound) { - int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(state->rel); int32 cmp; - cmp = _bt_compare(state->rel, nkeyatts, key, state->target, lowerbound); + Assert(key->pivotsearch); + + cmp = _bt_compare(state->rel, key, state->target, lowerbound); + + /* pg_upgrade'd indexes may legally have equal sibling tuples */ + if (!key->heapkeyspace) + return cmp >= 0; - return cmp >= 0; + /* + * No need to consider the possibility that scankey has attributes that we + * need to force to be interpreted as negative infinity. _bt_compare() is + * able to determine that scankey is greater than negative infinity. The + * distinction between "==" and "<" isn't interesting here, since + * corruption is indicated either way. + */ + return cmp > 0; } /* - * Does the invariant hold that the key is less than or equal to a given upper + * Does the invariant hold that the key is strictly less than a given upper * bound offset item, with the offset relating to a caller-supplied page that - * is not the current target page? Caller's non-target page is typically a - * child page of the target, checked as part of checking a property of the - * target page (i.e. the key comes from the target). + * is not the current target page? + * + * Caller's non-target page is a child page of the target, checked as part of + * checking a property of the target page (i.e. the key comes from the + * target). Verifies line pointer on behalf of caller. * * If this function returns false, convention is that caller throws error due * to corruption. */ static inline bool -invariant_leq_nontarget_offset(BtreeCheckState *state, - Page nontarget, ScanKey key, - OffsetNumber upperbound) +invariant_l_nontarget_offset(BtreeCheckState *state, BTScanInsert key, + BlockNumber nontargetblock, Page nontarget, + OffsetNumber upperbound) { - int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(state->rel); + ItemId itemid; int32 cmp; - cmp = _bt_compare(state->rel, nkeyatts, key, nontarget, upperbound); + Assert(key->pivotsearch); - return cmp <= 0; + /* Verify line pointer before checking tuple */ + itemid = PageGetItemIdCareful(state, nontargetblock, nontarget, + upperbound); + cmp = _bt_compare(state->rel, key, nontarget, upperbound); + + /* pg_upgrade'd indexes may legally have equal sibling tuples */ + if (!key->heapkeyspace) + return cmp <= 0; + + /* See invariant_l_offset() for an explanation of this extra step */ + if (cmp == 0) + { + IndexTuple child; + int uppnkeyatts; + ItemPointer childheaptid; + BTPageOpaque copaque; + bool nonpivot; + + child = (IndexTuple) PageGetItem(nontarget, itemid); + copaque = (BTPageOpaque) PageGetSpecialPointer(nontarget); + nonpivot = P_ISLEAF(copaque) && upperbound >= P_FIRSTDATAKEY(copaque); + + /* Get number of keys + heap TID for child/non-target item */ + uppnkeyatts = BTreeTupleGetNKeyAtts(child, state->rel); + childheaptid = BTreeTupleGetHeapTIDCareful(state, child, nonpivot); + + /* Heap TID is tiebreaker key attribute */ + if (key->keysz == uppnkeyatts) + return key->scantid == NULL && childheaptid != NULL; + + return key->keysz < uppnkeyatts; + } + + return cmp < 0; } /* @@ -1525,6 +2337,7 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) Buffer buffer; Page page; BTPageOpaque opaque; + OffsetNumber maxoffset; page = palloc(BLCKSZ); @@ -1571,9 +2384,13 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("version mismatch in index \"%s\": file version %d, " - "current version %d, minimal supported version %d", + "current version %d, minimum supported version %d", RelationGetRelationName(state->rel), - metad->btm_version, BTREE_VERSION, BTREE_MIN_VERSION))); + metad->btm_version, BTREE_VERSION, + BTREE_MIN_VERSION))); + + /* Finished with metapage checks */ + return page; } /* @@ -1586,12 +2403,66 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) errmsg("invalid leaf page level %u for block %u in index \"%s\"", opaque->btpo.level, blocknum, RelationGetRelationName(state->rel)))); - if (blocknum != BTREE_METAPAGE && !P_ISLEAF(opaque) && - !P_ISDELETED(opaque) && opaque->btpo.level == 0) + if (!P_ISLEAF(opaque) && !P_ISDELETED(opaque) && + opaque->btpo.level == 0) ereport(ERROR, (errcode(ERRCODE_INDEX_CORRUPTED), errmsg("invalid internal page level 0 for block %u in index \"%s\"", - opaque->btpo.level, RelationGetRelationName(state->rel)))); + blocknum, RelationGetRelationName(state->rel)))); + + /* + * Sanity checks for number of items on page. + * + * As noted at the beginning of _bt_binsrch(), an internal page must have + * children, since there must always be a negative infinity downlink + * (there may also be a highkey). In the case of non-rightmost leaf + * pages, there must be at least a highkey. + * + * This is correct when pages are half-dead, since internal pages are + * never half-dead, and leaf pages must have a high key when half-dead + * (the rightmost page can never be deleted). It's also correct with + * fully deleted pages: _bt_unlink_halfdead_page() doesn't change anything + * about the target page other than setting the page as fully dead, and + * setting its xact field. In particular, it doesn't change the sibling + * links in the deletion target itself, since they're required when index + * scans land on the deletion target, and then need to move right (or need + * to move left, in the case of backward index scans). + */ + maxoffset = PageGetMaxOffsetNumber(page); + if (maxoffset > MaxIndexTuplesPerPage) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("Number of items on block %u of index \"%s\" exceeds MaxIndexTuplesPerPage (%u)", + blocknum, RelationGetRelationName(state->rel), + MaxIndexTuplesPerPage))); + + if (!P_ISLEAF(opaque) && maxoffset < P_FIRSTDATAKEY(opaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("internal block %u in index \"%s\" lacks high key and/or at least one downlink", + blocknum, RelationGetRelationName(state->rel)))); + + if (P_ISLEAF(opaque) && !P_RIGHTMOST(opaque) && maxoffset < P_HIKEY) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("non-rightmost leaf block %u in index \"%s\" lacks high key item", + blocknum, RelationGetRelationName(state->rel)))); + + /* + * In general, internal pages are never marked half-dead, except on + * versions of Postgres prior to 9.4, where it can be valid transient + * state. This state is nonetheless treated as corruption by VACUUM on + * from version 9.4 on, so do the same here. See _bt_pagedel() for full + * details. + * + * Internal pages should never have garbage items, either. + */ + if (!P_ISLEAF(opaque) && P_ISHALFDEAD(opaque)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("internal page block %u in index \"%s\" is half-dead", + blocknum, RelationGetRelationName(state->rel)), + errhint("This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it."))); if (!P_ISLEAF(opaque) && P_HAS_GARBAGE(opaque)) ereport(ERROR, @@ -1601,3 +2472,102 @@ palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum) return page; } + +/* + * _bt_mkscankey() wrapper that automatically prevents insertion scankey from + * being considered greater than the pivot tuple that its values originated + * from (or some other identical pivot tuple) in the common case where there + * are truncated/minus infinity attributes. Without this extra step, there + * are forms of corruption that amcheck could theoretically fail to report. + * + * For example, invariant_g_offset() might miss a cross-page invariant failure + * on an internal level if the scankey built from the first item on the + * target's right sibling page happened to be equal to (not greater than) the + * last item on target page. The !pivotsearch tiebreaker in _bt_compare() + * might otherwise cause amcheck to assume (rather than actually verify) that + * the scankey is greater. + */ +static inline BTScanInsert +bt_mkscankey_pivotsearch(Relation rel, IndexTuple itup) +{ + BTScanInsert skey; + + skey = _bt_mkscankey(rel, itup); + skey->pivotsearch = true; + + return skey; +} + +/* + * PageGetItemId() wrapper that validates returned line pointer. + * + * Buffer page/page item access macros generally trust that line pointers are + * not corrupt, which might cause problems for verification itself. For + * example, there is no bounds checking in PageGetItem(). Passing it a + * corrupt line pointer can cause it to return a tuple/pointer that is unsafe + * to dereference. + * + * Validating line pointers before tuples avoids undefined behavior and + * assertion failures with corrupt indexes, making the verification process + * more robust and predictable. + */ +static ItemId +PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, Page page, + OffsetNumber offset) +{ + ItemId itemid = PageGetItemId(page, offset); + + if (ItemIdGetOffset(itemid) + ItemIdGetLength(itemid) > + BLCKSZ - sizeof(BTPageOpaqueData)) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("line pointer points past end of tuple space in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Index tid=(%u,%u) lp_off=%u, lp_len=%u lp_flags=%u.", + block, offset, ItemIdGetOffset(itemid), + ItemIdGetLength(itemid), + ItemIdGetFlags(itemid)))); + + /* + * Verify that line pointer isn't LP_REDIRECT or LP_UNUSED, since nbtree + * never uses either. Verify that line pointer has storage, too, since + * even LP_DEAD items should within nbtree. + */ + if (ItemIdIsRedirected(itemid) || !ItemIdIsUsed(itemid) || + ItemIdGetLength(itemid) == 0) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("invalid line pointer storage in index \"%s\"", + RelationGetRelationName(state->rel)), + errdetail_internal("Index tid=(%u,%u) lp_off=%u, lp_len=%u lp_flags=%u.", + block, offset, ItemIdGetOffset(itemid), + ItemIdGetLength(itemid), + ItemIdGetFlags(itemid)))); + + return itemid; +} + +/* + * BTreeTupleGetHeapTID() wrapper that lets caller enforce that a heap TID must + * be present in cases where that is mandatory. + * + * This doesn't add much as of BTREE_VERSION 4, since the INDEX_ALT_TID_MASK + * bit is effectively a proxy for whether or not the tuple is a pivot tuple. + * It may become more useful in the future, when non-pivot tuples support their + * own alternative INDEX_ALT_TID_MASK representation. + */ +static inline ItemPointer +BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, IndexTuple itup, + bool nonpivot) +{ + ItemPointer result = BTreeTupleGetHeapTID(itup); + BlockNumber targetblock = state->targetblock; + + if (result == NULL && nonpivot) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("block %u or its right sibling block or child block in index \"%s\" contains non-pivot tuple that lacks a heap TID", + targetblock, RelationGetRelationName(state->rel)))); + + return result; +} diff --git a/contrib/auth_delay/auth_delay.c b/contrib/auth_delay/auth_delay.c index ad047b365f2..b7ad7448d5e 100644 --- a/contrib/auth_delay/auth_delay.c +++ b/contrib/auth_delay/auth_delay.c @@ -2,7 +2,7 @@ * * auth_delay.c * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/auth_delay/auth_delay.c diff --git a/contrib/auto_explain/auto_explain.c b/contrib/auto_explain/auto_explain.c index ea4f957cfa0..a9536c2de05 100644 --- a/contrib/auto_explain/auto_explain.c +++ b/contrib/auto_explain/auto_explain.c @@ -3,7 +3,7 @@ * auto_explain.c * * - * Copyright (c) 2008-2018, PostgreSQL Global Development Group + * Copyright (c) 2008-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/auto_explain/auto_explain.c @@ -14,8 +14,10 @@ #include +#include "access/parallel.h" #include "commands/explain.h" #include "executor/instrument.h" +#include "jit/jit.h" #include "utils/guc.h" PG_MODULE_MAGIC; @@ -27,7 +29,9 @@ static bool auto_explain_log_verbose = false; static bool auto_explain_log_buffers = false; static bool auto_explain_log_triggers = false; static bool auto_explain_log_timing = true; +static bool auto_explain_log_settings = false; static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT; +static int auto_explain_log_level = LOG; static bool auto_explain_log_nested_statements = false; static double auto_explain_sample_rate = 1; @@ -39,29 +43,44 @@ static const struct config_enum_entry format_options[] = { {NULL, 0, false} }; +static const struct config_enum_entry loglevel_options[] = { + {"debug5", DEBUG5, false}, + {"debug4", DEBUG4, false}, + {"debug3", DEBUG3, false}, + {"debug2", DEBUG2, false}, + {"debug1", DEBUG1, false}, + {"debug", DEBUG2, true}, + {"info", INFO, false}, + {"notice", NOTICE, false}, + {"warning", WARNING, false}, + {"log", LOG, false}, + {NULL, 0, false} +}; + /* Current nesting depth of ExecutorRun calls */ static int nesting_level = 0; +/* Is the current top-level query to be sampled? */ +static bool current_query_sampled = false; + +#define auto_explain_enabled() \ + (auto_explain_log_min_duration >= 0 && \ + (nesting_level == 0 || auto_explain_log_nested_statements) && \ + current_query_sampled) + /* Saved hook values in case of unload */ static ExecutorStart_hook_type prev_ExecutorStart = NULL; static ExecutorRun_hook_type prev_ExecutorRun = NULL; static ExecutorFinish_hook_type prev_ExecutorFinish = NULL; static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; -/* Is the current query sampled, per backend */ -static bool current_query_sampled = true; - -#define auto_explain_enabled() \ - (auto_explain_log_min_duration >= 0 && \ - (nesting_level == 0 || auto_explain_log_nested_statements)) - void _PG_init(void); void _PG_fini(void); static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags); static void explain_ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, - uint64 count, bool execute_once); + ScanDirection direction, + uint64 count, bool execute_once); static void explain_ExecutorFinish(QueryDesc *queryDesc); static void explain_ExecutorEnd(QueryDesc *queryDesc); @@ -96,6 +115,17 @@ _PG_init(void) NULL, NULL); + DefineCustomBoolVariable("auto_explain.log_settings", + "Log modified configuration parameters affecting query planning.", + NULL, + &auto_explain_log_settings, + false, + PGC_SUSET, + 0, + NULL, + NULL, + NULL); + DefineCustomBoolVariable("auto_explain.log_verbose", "Use EXPLAIN VERBOSE for plan logging.", NULL, @@ -141,6 +171,18 @@ _PG_init(void) NULL, NULL); + DefineCustomEnumVariable("auto_explain.log_level", + "Log level for the plan.", + NULL, + &auto_explain_log_level, + LOG, + loglevel_options, + PGC_SUSET, + 0, + NULL, + NULL, + NULL); + DefineCustomBoolVariable("auto_explain.log_nested_statements", "Log nested statements.", NULL, @@ -209,14 +251,25 @@ static void explain_ExecutorStart(QueryDesc *queryDesc, int eflags) { /* - * For rate sampling, randomly choose top-level statement. Either all - * nested statements will be explained or none will. + * At the beginning of each top-level statement, decide whether we'll + * sample this statement. If nested-statement explaining is enabled, + * either all nested statements will be explained or none will. + * + * When in a parallel worker, we should do nothing, which we can implement + * cheaply by pretending we decided not to sample the current statement. + * If EXPLAIN is active in the parent session, data will be collected and + * reported back to the parent, and it's no business of ours to interfere. */ - if (auto_explain_log_min_duration >= 0 && nesting_level == 0) - current_query_sampled = (random() < auto_explain_sample_rate * - MAX_RANDOM_VALUE); + if (nesting_level == 0) + { + if (auto_explain_log_min_duration >= 0 && !IsParallelWorker()) + current_query_sampled = (random() < auto_explain_sample_rate * + ((double) MAX_RANDOM_VALUE + 1)); + else + current_query_sampled = false; + } - if (auto_explain_enabled() && current_query_sampled) + if (auto_explain_enabled()) { /* Enable per-node instrumentation iff log_analyze is required. */ if (auto_explain_log_analyze && (eflags & EXEC_FLAG_EXPLAIN_ONLY) == 0) @@ -235,7 +288,7 @@ explain_ExecutorStart(QueryDesc *queryDesc, int eflags) else standard_ExecutorStart(queryDesc, eflags); - if (auto_explain_enabled() && current_query_sampled) + if (auto_explain_enabled()) { /* * Set up to track total elapsed time in ExecutorRun. Make sure the @@ -306,7 +359,7 @@ explain_ExecutorFinish(QueryDesc *queryDesc) static void explain_ExecutorEnd(QueryDesc *queryDesc) { - if (queryDesc->totaltime && auto_explain_enabled() && current_query_sampled) + if (queryDesc->totaltime && auto_explain_enabled()) { double msec; @@ -328,12 +381,15 @@ explain_ExecutorEnd(QueryDesc *queryDesc) es->timing = (es->analyze && auto_explain_log_timing); es->summary = es->analyze; es->format = auto_explain_log_format; + es->settings = auto_explain_log_settings; ExplainBeginOutput(es); ExplainQueryText(es, queryDesc); ExplainPrintPlan(es, queryDesc); if (es->analyze && auto_explain_log_triggers) ExplainPrintTriggers(es, queryDesc); + if (es->costs) + ExplainPrintJITSummary(es, queryDesc); ExplainEndOutput(es); /* Remove last line break */ @@ -353,7 +409,7 @@ explain_ExecutorEnd(QueryDesc *queryDesc) * reported. This isn't ideal but trying to do it here would * often result in duplication. */ - ereport(LOG, + ereport(auto_explain_log_level, (errmsg("duration: %.3f ms plan:\n%s", msec, es->str->data), errhidestmt(true))); diff --git a/contrib/bloom/Makefile b/contrib/bloom/Makefile index 13bd397b705..146878870ec 100644 --- a/contrib/bloom/Makefile +++ b/contrib/bloom/Makefile @@ -9,6 +9,10 @@ PGFILEDESC = "bloom access method - signature file based index" REGRESS = bloom +# Disable TAP tests for this module for now, as these are unstable on several +# buildfarm environments. +# TAP_TESTS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) @@ -19,6 +23,3 @@ top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - -wal-check: temp-install - $(prove_check) diff --git a/contrib/bloom/blcost.c b/contrib/bloom/blcost.c index fa0f17a217f..f9fe57fb845 100644 --- a/contrib/bloom/blcost.c +++ b/contrib/bloom/blcost.c @@ -3,7 +3,7 @@ * blcost.c * Cost estimate function for bloom indexes. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blcost.c @@ -13,7 +13,6 @@ #include "postgres.h" #include "fmgr.h" -#include "optimizer/cost.h" #include "utils/selfuncs.h" #include "bloom.h" @@ -28,19 +27,15 @@ blcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *qinfos; GenericCosts costs; - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); - MemSet(&costs, 0, sizeof(costs)); /* We have to visit all index tuples anyway */ costs.numIndexTuples = index->tuples; /* Use generic estimate */ - genericcostestimate(root, path, loop_count, qinfos, &costs); + genericcostestimate(root, path, loop_count, &costs); *indexStartupCost = costs.indexStartupCost; *indexTotalCost = costs.indexTotalCost; diff --git a/contrib/bloom/blinsert.c b/contrib/bloom/blinsert.c index 4afdea7c9a3..4b2186b8dda 100644 --- a/contrib/bloom/blinsert.c +++ b/contrib/bloom/blinsert.c @@ -3,7 +3,7 @@ * blinsert.c * Bloom index build and insert functions. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blinsert.c @@ -14,6 +14,7 @@ #include "access/genam.h" #include "access/generic_xlog.h" +#include "access/tableam.h" #include "catalog/index.h" #include "miscadmin.h" #include "storage/bufmgr.h" @@ -36,7 +37,7 @@ typedef struct int64 indtuples; /* total number of tuples indexed */ MemoryContext tmpCtx; /* temporary memory context reset after each * tuple */ - char data[BLCKSZ]; /* cached page */ + PGAlignedBlock data; /* cached page */ int count; /* number of tuples in cached page */ } BloomBuildState; @@ -52,7 +53,7 @@ flushCachedPage(Relation index, BloomBuildState *buildstate) state = GenericXLogStart(index); page = GenericXLogRegisterBuffer(state, buffer, GENERIC_XLOG_FULL_IMAGE); - memcpy(page, buildstate->data, BLCKSZ); + memcpy(page, buildstate->data.data, BLCKSZ); GenericXLogFinish(state); UnlockReleaseBuffer(buffer); } @@ -63,13 +64,13 @@ flushCachedPage(Relation index, BloomBuildState *buildstate) static void initCachedPage(BloomBuildState *buildstate) { - memset(buildstate->data, 0, BLCKSZ); - BloomInitPage(buildstate->data, 0); + memset(buildstate->data.data, 0, BLCKSZ); + BloomInitPage(buildstate->data.data, 0); buildstate->count = 0; } /* - * Per-tuple callback from IndexBuildHeapScan. + * Per-tuple callback for table_index_build_scan. */ static void bloomBuildCallback(Relation index, HeapTuple htup, Datum *values, @@ -84,7 +85,7 @@ bloomBuildCallback(Relation index, HeapTuple htup, Datum *values, itup = BloomFormTuple(&buildstate->blstate, &htup->t_self, values, isnull); /* Try to add next item to cached page */ - if (BloomPageAddItem(&buildstate->blstate, buildstate->data, itup)) + if (BloomPageAddItem(&buildstate->blstate, buildstate->data.data, itup)) { /* Next item was added successfully */ buildstate->count++; @@ -98,7 +99,7 @@ bloomBuildCallback(Relation index, HeapTuple htup, Datum *values, initCachedPage(buildstate); - if (!BloomPageAddItem(&buildstate->blstate, buildstate->data, itup)) + if (!BloomPageAddItem(&buildstate->blstate, buildstate->data.data, itup)) { /* We shouldn't be here since we're inserting to the empty page */ elog(ERROR, "could not add new bloom tuple to empty page"); @@ -141,9 +142,9 @@ blbuild(Relation heap, Relation index, IndexInfo *indexInfo) initCachedPage(&buildstate); /* Do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, - bloomBuildCallback, (void *) &buildstate, - NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + bloomBuildCallback, (void *) &buildstate, + NULL); /* Flush last page if needed (it will be, unless heap was empty) */ if (buildstate.count > 0) diff --git a/contrib/bloom/bloom.h b/contrib/bloom/bloom.h index 3973ac75e8f..010148eb032 100644 --- a/contrib/bloom/bloom.h +++ b/contrib/bloom/bloom.h @@ -3,7 +3,7 @@ * bloom.h * Header for bloom index. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/bloom.h @@ -17,7 +17,7 @@ #include "access/generic_xlog.h" #include "access/itup.h" #include "access/xlog.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "fmgr.h" /* Support procedures numbers */ @@ -137,6 +137,7 @@ typedef struct BloomMetaPageData typedef struct BloomState { FmgrInfo hashFn[INDEX_MAX_KEYS]; + Oid collations[INDEX_MAX_KEYS]; BloomOptions opts; /* copy of options on index's metapage */ int32 nColumns; @@ -188,26 +189,26 @@ extern bool blvalidate(Oid opclassoid); /* index access method interface functions */ extern bool blinsert(Relation index, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern IndexScanDesc blbeginscan(Relation r, int nkeys, int norderbys); extern int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern void blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void blendscan(IndexScanDesc scan); extern IndexBuildResult *blbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void blbuildempty(Relation index); extern IndexBulkDeleteResult *blbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *blvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern bytea *bloptions(Datum reloptions, bool validate); extern void blcostestimate(PlannerInfo *root, IndexPath *path, - double loop_count, Cost *indexStartupCost, - Cost *indexTotalCost, Selectivity *indexSelectivity, - double *indexCorrelation, double *indexPages); + double loop_count, Cost *indexStartupCost, + Cost *indexTotalCost, Selectivity *indexSelectivity, + double *indexCorrelation, double *indexPages); #endif diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c index 0744d74de75..49e364ac12d 100644 --- a/contrib/bloom/blscan.c +++ b/contrib/bloom/blscan.c @@ -3,7 +3,7 @@ * blscan.c * Bloom index scan functions. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blscan.c @@ -76,7 +76,7 @@ blendscan(IndexScanDesc scan) } /* - * Insert all matching tuples into to a bitmap. + * Insert all matching tuples into a bitmap. */ int64 blgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) diff --git a/contrib/bloom/blutils.c b/contrib/bloom/blutils.c index 6b2b9e37426..dbb24cb5b24 100644 --- a/contrib/bloom/blutils.c +++ b/contrib/bloom/blutils.c @@ -3,7 +3,7 @@ * blutils.c * Bloom index utilities. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1990-1993, Regents of the University of California * * IDENTIFICATION @@ -60,7 +60,8 @@ _PG_init(void) /* Option for length of signature */ add_int_reloption(bl_relopt_kind, "length", "Length of signature in bits", - DEFAULT_BLOOM_LENGTH, 1, MAX_BLOOM_LENGTH); + DEFAULT_BLOOM_LENGTH, 1, MAX_BLOOM_LENGTH, + AccessExclusiveLock); bl_relopt_tab[0].optname = "length"; bl_relopt_tab[0].opttype = RELOPT_TYPE_INT; bl_relopt_tab[0].offset = offsetof(BloomOptions, bloomLength); @@ -71,7 +72,8 @@ _PG_init(void) snprintf(buf, sizeof(buf), "col%d", i + 1); add_int_reloption(bl_relopt_kind, buf, "Number of bits generated for each index column", - DEFAULT_BLOOM_BITS, 1, MAX_BLOOM_BITS); + DEFAULT_BLOOM_BITS, 1, MAX_BLOOM_BITS, + AccessExclusiveLock); bl_relopt_tab[i + 1].optname = MemoryContextStrdup(TopMemoryContext, buf); bl_relopt_tab[i + 1].opttype = RELOPT_TYPE_INT; @@ -132,6 +134,7 @@ blhandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = blcostestimate; amroutine->amoptions = bloptions; amroutine->amproperty = NULL; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = blvalidate; amroutine->ambeginscan = blbeginscan; amroutine->amrescan = blrescan; @@ -163,6 +166,7 @@ initBloomState(BloomState *state, Relation index) fmgr_info_copy(&(state->hashFn[i]), index_getprocinfo(index, i + 1, BLOOM_HASH_PROC), CurrentMemoryContext); + state->collations[i] = index->rd_indcollation[i]; } /* Initialize amcache if needed with options from metapage */ @@ -267,7 +271,7 @@ signValue(BloomState *state, BloomSignatureWord *sign, Datum value, int attno) * different columns will be mapped into different bits because of step * above */ - hashVal = DatumGetInt32(FunctionCall1(&state->hashFn[attno], value)); + hashVal = DatumGetInt32(FunctionCall1Coll(&state->hashFn[attno], state->collations[attno], value)); mySrand(hashVal ^ myRand()); for (j = 0; j < state->opts.bitSize[attno]; j++) @@ -339,7 +343,7 @@ BloomPageAddItem(BloomState *state, Page page, BloomTuple *tuple) /* * Allocate a new page (either by recycling, or by extending the index file) * The returned buffer is already pinned and exclusive-locked - * Caller is responsible for initializing the page by calling BloomInitBuffer + * Caller is responsible for initializing the page by calling BloomInitPage */ Buffer BloomNewBuffer(Relation index) diff --git a/contrib/bloom/blvacuum.c b/contrib/bloom/blvacuum.c index 7530a664abc..0c33d1e1951 100644 --- a/contrib/bloom/blvacuum.c +++ b/contrib/bloom/blvacuum.c @@ -3,7 +3,7 @@ * blvacuum.c * Bloom VACUUM functions. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blvacuum.c diff --git a/contrib/bloom/blvalidate.c b/contrib/bloom/blvalidate.c index 7235f123073..e9bd1b4f03e 100644 --- a/contrib/bloom/blvalidate.c +++ b/contrib/bloom/blvalidate.c @@ -3,7 +3,7 @@ * blvalidate.c * Opclass validator for bloom. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/bloom/blvalidate.c diff --git a/contrib/bloom/expected/bloom.out b/contrib/bloom/expected/bloom.out index 5ab9e34f823..dae12a7d3e7 100644 --- a/contrib/bloom/expected/bloom.out +++ b/contrib/bloom/expected/bloom.out @@ -5,6 +5,7 @@ CREATE TABLE tst ( ); INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series(1,2000) i; CREATE INDEX bloomidx ON tst USING bloom (i, t) WITH (col1 = 3); +ALTER INDEX bloomidx SET (length=80); SET enable_seqscan=on; SET enable_bitmapscan=off; SET enable_indexscan=off; diff --git a/contrib/bloom/sql/bloom.sql b/contrib/bloom/sql/bloom.sql index 32755f2b1a5..4733e1e7050 100644 --- a/contrib/bloom/sql/bloom.sql +++ b/contrib/bloom/sql/bloom.sql @@ -7,6 +7,7 @@ CREATE TABLE tst ( INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series(1,2000) i; CREATE INDEX bloomidx ON tst USING bloom (i, t) WITH (col1 = 3); +ALTER INDEX bloomidx SET (length=80); SET enable_seqscan=on; SET enable_bitmapscan=off; diff --git a/contrib/bloom/t/001_wal.pl b/contrib/bloom/t/001_wal.pl index 1b319c993c9..0f2628b5575 100644 --- a/contrib/bloom/t/001_wal.pl +++ b/contrib/bloom/t/001_wal.pl @@ -16,7 +16,7 @@ sub test_index_replay # Wait for standby to catch up my $applname = $node_standby->name; my $caughtup_query = -"SELECT pg_current_wal_lsn() <= write_lsn FROM pg_stat_replication WHERE application_name = '$applname';"; + "SELECT pg_current_wal_lsn() <= write_lsn FROM pg_stat_replication WHERE application_name = '$applname';"; $node_master->poll_query_until('postgres', $caughtup_query) or die "Timed out while waiting for standby 1 to catch up"; @@ -36,6 +36,7 @@ sub test_index_replay my $standby_result = $node_standby->safe_psql("postgres", $queries); is($master_result, $standby_result, "$test_name: query result matches"); + return; } # Initialize master node @@ -57,7 +58,7 @@ sub test_index_replay $node_master->safe_psql("postgres", "CREATE EXTENSION bloom;"); $node_master->safe_psql("postgres", "CREATE TABLE tst (i int4, t text);"); $node_master->safe_psql("postgres", -"INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series(1,100000) i;" + "INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series(1,100000) i;" ); $node_master->safe_psql("postgres", "CREATE INDEX bloomidx ON tst USING bloom (i, t) WITH (col1 = 3);"); @@ -74,7 +75,7 @@ sub test_index_replay test_index_replay("vacuum $i"); my ($start, $end) = (100001 + ($i - 1) * 10000, 100000 + $i * 10000); $node_master->safe_psql("postgres", -"INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series($start,$end) i;" + "INSERT INTO tst SELECT i%10, substr(md5(i::text), 1, 1) FROM generate_series($start,$end) i;" ); test_index_replay("insert $i"); } diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c index a660681e581..2ecf7a2d87c 100644 --- a/contrib/btree_gin/btree_gin.c +++ b/contrib/btree_gin/btree_gin.c @@ -10,6 +10,7 @@ #include "utils/bytea.h" #include "utils/cash.h" #include "utils/date.h" +#include "utils/float.h" #include "utils/inet.h" #include "utils/numeric.h" #include "utils/timestamp.h" @@ -88,6 +89,7 @@ gin_btree_extract_query(FunctionCallInfo fcinfo, case BTGreaterEqualStrategyNumber: case BTGreaterStrategyNumber: *ptr_partialmatch = true; + /* FALLTHROUGH */ case BTEqualStrategyNumber: entries[0] = datum; break; @@ -483,8 +485,12 @@ GIN_SUPPORT(anyenum, false, leftmostvalue_enum, gin_enum_cmp) static Datum leftmostvalue_uuid(void) { - /* palloc0 will create the UUID with all zeroes: "00000000-0000-0000-0000-000000000000" */ - pg_uuid_t *retval = (pg_uuid_t *) palloc0(sizeof(pg_uuid_t)); + /* + * palloc0 will create the UUID with all zeroes: + * "00000000-0000-0000-0000-000000000000" + */ + pg_uuid_t *retval = (pg_uuid_t *) palloc0(sizeof(pg_uuid_t)); + return UUIDPGetDatum(retval); } @@ -493,7 +499,8 @@ GIN_SUPPORT(uuid, false, leftmostvalue_uuid, uuid_cmp) static Datum leftmostvalue_name(void) { - NameData* result = (NameData *) palloc0(NAMEDATALEN); + NameData *result = (NameData *) palloc0(NAMEDATALEN); + return NameGetDatum(result); } diff --git a/contrib/btree_gist/btree_ts.c b/contrib/btree_gist/btree_ts.c index 18740cad383..49d1849d889 100644 --- a/contrib/btree_gist/btree_ts.c +++ b/contrib/btree_gist/btree_ts.c @@ -9,6 +9,7 @@ #include "btree_utils_num.h" #include "utils/builtins.h" #include "utils/datetime.h" +#include "utils/float.h" typedef struct { diff --git a/contrib/btree_gist/btree_utils_num.c b/contrib/btree_gist/btree_utils_num.c index 29b0faf997f..7564a403c7d 100644 --- a/contrib/btree_gist/btree_utils_num.c +++ b/contrib/btree_gist/btree_utils_num.c @@ -185,10 +185,10 @@ gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, const gbtree_nin c.upper = &cur[tinfo->size]; /* if out->lower > cur->lower, adopt cur as lower */ if (tinfo->f_gt(o.lower, c.lower, flinfo)) - memcpy((void *) o.lower, (void *) c.lower, tinfo->size); + memcpy(unconstify(GBT_NUMKEY *, o.lower), c.lower, tinfo->size); /* if out->upper < cur->upper, adopt cur as upper */ if (tinfo->f_lt(o.upper, c.upper, flinfo)) - memcpy((void *) o.upper, (void *) c.upper, tinfo->size); + memcpy(unconstify(GBT_NUMKEY *, o.upper), c.upper, tinfo->size); } return out; @@ -206,10 +206,10 @@ gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, const gbtree_ninfo *tinfo GBT_NUMKEY_R b1, b2; - b1.lower = &(((GBT_NUMKEY *) a)[0]); - b1.upper = &(((GBT_NUMKEY *) a)[tinfo->size]); - b2.lower = &(((GBT_NUMKEY *) b)[0]); - b2.upper = &(((GBT_NUMKEY *) b)[tinfo->size]); + b1.lower = &(a[0]); + b1.upper = &(a[tinfo->size]); + b2.lower = &(b[0]); + b2.upper = &(b[tinfo->size]); return (tinfo->f_eq(b1.lower, b2.lower, flinfo) && tinfo->f_eq(b1.upper, b2.upper, flinfo)); @@ -227,8 +227,8 @@ gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo, FmgrInfo * if (!DatumGetPointer(*u)) { *u = PointerGetDatum(palloc0(tinfo->indexsize)); - memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]), (void *) rd.lower, tinfo->size); - memcpy((void *) &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]), (void *) rd.upper, tinfo->size); + memcpy(&(((GBT_NUMKEY *) DatumGetPointer(*u))[0]), rd.lower, tinfo->size); + memcpy(&(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]), rd.upper, tinfo->size); } else { @@ -236,10 +236,10 @@ gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, const gbtree_ninfo *tinfo, FmgrInfo * ur.lower = &(((GBT_NUMKEY *) DatumGetPointer(*u))[0]); ur.upper = &(((GBT_NUMKEY *) DatumGetPointer(*u))[tinfo->size]); - if (tinfo->f_gt((void *) ur.lower, (void *) rd.lower, flinfo)) - memcpy((void *) ur.lower, (void *) rd.lower, tinfo->size); - if (tinfo->f_lt((void *) ur.upper, (void *) rd.upper, flinfo)) - memcpy((void *) ur.upper, (void *) rd.upper, tinfo->size); + if (tinfo->f_gt(ur.lower, rd.lower, flinfo)) + memcpy(unconstify(GBT_NUMKEY *, ur.lower), rd.lower, tinfo->size); + if (tinfo->f_lt(ur.upper, rd.upper, flinfo)) + memcpy(unconstify(GBT_NUMKEY *, ur.upper), rd.upper, tinfo->size); } } diff --git a/contrib/btree_gist/btree_utils_num.h b/contrib/btree_gist/btree_utils_num.h index d7945f856c8..50907b3b5c6 100644 --- a/contrib/btree_gist/btree_utils_num.h +++ b/contrib/btree_gist/btree_utils_num.h @@ -110,26 +110,26 @@ do { \ extern Interval *abs_interval(Interval *a); extern bool gbt_num_consistent(const GBT_NUMKEY_R *key, const void *query, - const StrategyNumber *strategy, bool is_leaf, - const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + const StrategyNumber *strategy, bool is_leaf, + const gbtree_ninfo *tinfo, FmgrInfo *flinfo); extern float8 gbt_num_distance(const GBT_NUMKEY_R *key, const void *query, - bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + bool is_leaf, const gbtree_ninfo *tinfo, FmgrInfo *flinfo); extern GIST_SPLITVEC *gbt_num_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, - const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + const gbtree_ninfo *tinfo, FmgrInfo *flinfo); extern GISTENTRY *gbt_num_compress(GISTENTRY *entry, const gbtree_ninfo *tinfo); extern GISTENTRY *gbt_num_fetch(GISTENTRY *entry, const gbtree_ninfo *tinfo); extern void *gbt_num_union(GBT_NUMKEY *out, const GistEntryVector *entryvec, - const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + const gbtree_ninfo *tinfo, FmgrInfo *flinfo); extern bool gbt_num_same(const GBT_NUMKEY *a, const GBT_NUMKEY *b, - const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + const gbtree_ninfo *tinfo, FmgrInfo *flinfo); extern void gbt_num_bin_union(Datum *u, GBT_NUMKEY *e, - const gbtree_ninfo *tinfo, FmgrInfo *flinfo); + const gbtree_ninfo *tinfo, FmgrInfo *flinfo); #endif diff --git a/contrib/btree_gist/btree_utils_var.h b/contrib/btree_gist/btree_utils_var.h index 15d847c1394..1f2ca43e6bc 100644 --- a/contrib/btree_gist/btree_utils_var.h +++ b/contrib/btree_gist/btree_utils_var.h @@ -52,22 +52,22 @@ extern GBT_VARKEY *gbt_var_key_copy(const GBT_VARKEY_R *u); extern GISTENTRY *gbt_var_compress(GISTENTRY *entry, const gbtree_vinfo *tinfo); extern GBT_VARKEY *gbt_var_union(const GistEntryVector *entryvec, int32 *size, - Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); extern bool gbt_var_same(Datum d1, Datum d2, Oid collation, - const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + const gbtree_vinfo *tinfo, FmgrInfo *flinfo); extern float *gbt_var_penalty(float *res, const GISTENTRY *o, const GISTENTRY *n, - Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); extern bool gbt_var_consistent(GBT_VARKEY_R *key, const void *query, - StrategyNumber strategy, Oid collation, bool is_leaf, - const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + StrategyNumber strategy, Oid collation, bool is_leaf, + const gbtree_vinfo *tinfo, FmgrInfo *flinfo); extern GIST_SPLITVEC *gbt_var_picksplit(const GistEntryVector *entryvec, GIST_SPLITVEC *v, - Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + Oid collation, const gbtree_vinfo *tinfo, FmgrInfo *flinfo); extern void gbt_var_bin_union(Datum *u, GBT_VARKEY *e, Oid collation, - const gbtree_vinfo *tinfo, FmgrInfo *flinfo); + const gbtree_vinfo *tinfo, FmgrInfo *flinfo); #endif diff --git a/contrib/btree_gist/expected/bit.out b/contrib/btree_gist/expected/bit.out index 8606baf366e..e57871f310b 100644 --- a/contrib/btree_gist/expected/bit.out +++ b/contrib/btree_gist/expected/bit.out @@ -68,9 +68,9 @@ SELECT count(*) FROM bittmp WHERE a > '011011000100010111011000110000100'; SET enable_bitmapscan=off; EXPLAIN (COSTS OFF) SELECT a FROM bittmp WHERE a BETWEEN '1000000' and '1000001'; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------- Index Only Scan using bitidx on bittmp - Index Cond: ((a >= B'1000000'::"bit") AND (a <= B'1000001'::"bit")) + Index Cond: ((a >= '1000000'::"bit") AND (a <= '1000001'::"bit")) (2 rows) diff --git a/contrib/btree_gist/expected/cash.out b/contrib/btree_gist/expected/cash.out index cacbd718541..7fbc7355929 100644 --- a/contrib/btree_gist/expected/cash.out +++ b/contrib/btree_gist/expected/cash.out @@ -1,5 +1,5 @@ -- money check -CREATE TABLE moneytmp (a money) WITH OIDS; +CREATE TABLE moneytmp (a money); \copy moneytmp from 'data/cash.data' SET enable_seqscan=on; SELECT count(*) FROM moneytmp WHERE a < '22649.64'; diff --git a/contrib/btree_gist/expected/float4.out b/contrib/btree_gist/expected/float4.out index abbd9eef4e8..dfe732049e6 100644 --- a/contrib/btree_gist/expected/float4.out +++ b/contrib/btree_gist/expected/float4.out @@ -33,11 +33,11 @@ SELECT count(*) FROM float4tmp WHERE a > -179.0; (1 row) SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; - a | ?column? -----------+---------- - -179 | 0 - -189.024 | 10.0239 - -158.177 | 20.8226 + a | ?column? +------------+----------- + -179 | 0 + -189.02386 | 10.023865 + -158.17741 | 20.822586 (3 rows) CREATE INDEX float4idx ON float4tmp USING gist ( a ); @@ -82,10 +82,10 @@ SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; (3 rows) SELECT a, a <-> '-179.0' FROM float4tmp ORDER BY a <-> '-179.0' LIMIT 3; - a | ?column? -----------+---------- - -179 | 0 - -189.024 | 10.0239 - -158.177 | 20.8226 + a | ?column? +------------+----------- + -179 | 0 + -189.02386 | 10.023865 + -158.17741 | 20.822586 (3 rows) diff --git a/contrib/btree_gist/expected/float8.out b/contrib/btree_gist/expected/float8.out index 5111dbdfaea..ebd0ef3d689 100644 --- a/contrib/btree_gist/expected/float8.out +++ b/contrib/btree_gist/expected/float8.out @@ -33,11 +33,11 @@ SELECT count(*) FROM float8tmp WHERE a > -1890.0; (1 row) SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; - a | ?column? ---------------+------------ - -1890 | 0 - -2003.634512 | 113.634512 - -1769.73634 | 120.26366 + a | ?column? +--------------+-------------------- + -1890 | 0 + -2003.634512 | 113.63451200000009 + -1769.73634 | 120.26366000000007 (3 rows) CREATE INDEX float8idx ON float8tmp USING gist ( a ); @@ -82,10 +82,10 @@ SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; (3 rows) SELECT a, a <-> '-1890.0' FROM float8tmp ORDER BY a <-> '-1890.0' LIMIT 3; - a | ?column? ---------------+------------ - -1890 | 0 - -2003.634512 | 113.634512 - -1769.73634 | 120.26366 + a | ?column? +--------------+-------------------- + -1890 | 0 + -2003.634512 | 113.63451200000009 + -1769.73634 | 120.26366000000007 (3 rows) diff --git a/contrib/btree_gist/expected/inet.out b/contrib/btree_gist/expected/inet.out index 905f55d740b..c323d903da4 100644 --- a/contrib/btree_gist/expected/inet.out +++ b/contrib/btree_gist/expected/inet.out @@ -64,18 +64,16 @@ SELECT count(*) FROM inettmp WHERE a > '89.225.196.191'::inet; 386 (1 row) -VACUUM inettmp; +VACUUM ANALYZE inettmp; -- gist_inet_ops lacks a fetch function, so this should not be index-only scan EXPLAIN (COSTS OFF) SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet; - QUERY PLAN --------------------------------------------------------- + QUERY PLAN +-------------------------------------------------- Aggregate - -> Bitmap Heap Scan on inettmp - Recheck Cond: (a = '89.225.196.191'::inet) - -> Bitmap Index Scan on inetidx - Index Cond: (a = '89.225.196.191'::inet) -(5 rows) + -> Index Scan using inetidx on inettmp + Index Cond: (a = '89.225.196.191'::inet) +(3 rows) SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet; count @@ -88,14 +86,12 @@ CREATE INDEX ON inettmp USING gist (a gist_inet_ops, a inet_ops); -- likewise here (checks for core planner bug) EXPLAIN (COSTS OFF) SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet; - QUERY PLAN --------------------------------------------------------- + QUERY PLAN +---------------------------------------------------- Aggregate - -> Bitmap Heap Scan on inettmp - Recheck Cond: (a = '89.225.196.191'::inet) - -> Bitmap Index Scan on inettmp_a_a1_idx - Index Cond: (a = '89.225.196.191'::inet) -(5 rows) + -> Index Scan using inettmp_a_a1_idx on inettmp + Index Cond: (a = '89.225.196.191'::inet) +(3 rows) SELECT count(*) FROM inettmp WHERE a = '89.225.196.191'::inet; count diff --git a/contrib/btree_gist/expected/oid.out b/contrib/btree_gist/expected/oid.out index ffa90c3c3c7..776bbb10267 100644 --- a/contrib/btree_gist/expected/oid.out +++ b/contrib/btree_gist/expected/oid.out @@ -1,64 +1,66 @@ -- oid check SET enable_seqscan=on; -SELECT count(*) FROM moneytmp WHERE oid < ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +CREATE TEMPORARY TABLE oidtmp (oid oid); +INSERT INTO oidtmp SELECT g.i::oid FROM generate_series(1, 1000) g(i); +SELECT count(*) FROM oidtmp WHERE oid < 17; count ------- - 372 + 16 (1 row) -SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid <= 17; count ------- - 373 + 17 (1 row) -SELECT count(*) FROM moneytmp WHERE oid = ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid = 17; count ------- 1 (1 row) -SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid >= 17; count ------- - 228 + 984 (1 row) -SELECT count(*) FROM moneytmp WHERE oid > ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid > 17; count ------- - 227 + 983 (1 row) -CREATE INDEX oididx ON moneytmp USING gist ( oid ); +CREATE INDEX oididx ON oidtmp USING gist ( oid ); SET enable_seqscan=off; -SELECT count(*) FROM moneytmp WHERE oid < ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid < 17; count ------- - 372 + 16 (1 row) -SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid <= 17; count ------- - 373 + 17 (1 row) -SELECT count(*) FROM moneytmp WHERE oid = ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid = 17; count ------- 1 (1 row) -SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid >= 17; count ------- - 228 + 984 (1 row) -SELECT count(*) FROM moneytmp WHERE oid > ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid > 17; count ------- - 227 + 983 (1 row) diff --git a/contrib/btree_gist/expected/varbit.out b/contrib/btree_gist/expected/varbit.out index 538ace85c90..ede36bc3ead 100644 --- a/contrib/btree_gist/expected/varbit.out +++ b/contrib/btree_gist/expected/varbit.out @@ -68,9 +68,9 @@ SELECT count(*) FROM varbittmp WHERE a > '1110100111010'::varbit; SET enable_bitmapscan=off; EXPLAIN (COSTS OFF) SELECT a FROM bittmp WHERE a BETWEEN '1000000' and '1000001'; - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------- Index Only Scan using bitidx on bittmp - Index Cond: ((a >= B'1000000'::"bit") AND (a <= B'1000001'::"bit")) + Index Cond: ((a >= '1000000'::"bit") AND (a <= '1000001'::"bit")) (2 rows) diff --git a/contrib/btree_gist/sql/cash.sql b/contrib/btree_gist/sql/cash.sql index 0e037984e1b..4526cc4f0aa 100644 --- a/contrib/btree_gist/sql/cash.sql +++ b/contrib/btree_gist/sql/cash.sql @@ -1,6 +1,6 @@ -- money check -CREATE TABLE moneytmp (a money) WITH OIDS; +CREATE TABLE moneytmp (a money); \copy moneytmp from 'data/cash.data' diff --git a/contrib/btree_gist/sql/inet.sql b/contrib/btree_gist/sql/inet.sql index 08952f2c449..4b8d354b00e 100644 --- a/contrib/btree_gist/sql/inet.sql +++ b/contrib/btree_gist/sql/inet.sql @@ -30,7 +30,7 @@ SELECT count(*) FROM inettmp WHERE a >= '89.225.196.191'::inet; SELECT count(*) FROM inettmp WHERE a > '89.225.196.191'::inet; -VACUUM inettmp; +VACUUM ANALYZE inettmp; -- gist_inet_ops lacks a fetch function, so this should not be index-only scan EXPLAIN (COSTS OFF) diff --git a/contrib/btree_gist/sql/oid.sql b/contrib/btree_gist/sql/oid.sql index fd03b82bd44..c9358234ce9 100644 --- a/contrib/btree_gist/sql/oid.sql +++ b/contrib/btree_gist/sql/oid.sql @@ -2,26 +2,29 @@ SET enable_seqscan=on; -SELECT count(*) FROM moneytmp WHERE oid < ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +CREATE TEMPORARY TABLE oidtmp (oid oid); +INSERT INTO oidtmp SELECT g.i::oid FROM generate_series(1, 1000) g(i); -SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid < 17; -SELECT count(*) FROM moneytmp WHERE oid = ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid <= 17; -SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid = 17; -SELECT count(*) FROM moneytmp WHERE oid > ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid >= 17; -CREATE INDEX oididx ON moneytmp USING gist ( oid ); +SELECT count(*) FROM oidtmp WHERE oid > 17; + +CREATE INDEX oididx ON oidtmp USING gist ( oid ); SET enable_seqscan=off; -SELECT count(*) FROM moneytmp WHERE oid < ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid < 17; -SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid <= 17; -SELECT count(*) FROM moneytmp WHERE oid = ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid = 17; -SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid >= 17; -SELECT count(*) FROM moneytmp WHERE oid > ( SELECT oid FROM moneytmp WHERE a = '22649.64' ); +SELECT count(*) FROM oidtmp WHERE oid > 17; diff --git a/contrib/citext/Makefile b/contrib/citext/Makefile index e32a7de9464..e37dcf9b584 100644 --- a/contrib/citext/Makefile +++ b/contrib/citext/Makefile @@ -3,7 +3,9 @@ MODULES = citext EXTENSION = citext -DATA = citext--1.4.sql citext--1.4--1.5.sql \ +DATA = citext--1.4.sql \ + citext--1.5--1.6.sql \ + citext--1.4--1.5.sql \ citext--1.3--1.4.sql \ citext--1.2--1.3.sql citext--1.1--1.2.sql \ citext--1.0--1.1.sql citext--unpackaged--1.0.sql diff --git a/contrib/citext/citext--1.5--1.6.sql b/contrib/citext/citext--1.5--1.6.sql new file mode 100644 index 00000000000..32268983aef --- /dev/null +++ b/contrib/citext/citext--1.5--1.6.sql @@ -0,0 +1,12 @@ +/* contrib/citext/citext--1.5--1.6.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION citext UPDATE TO '1.6'" to load this file. \quit + +CREATE FUNCTION citext_hash_extended(citext, int8) +RETURNS int8 +AS 'MODULE_PATHNAME' +LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; + +ALTER OPERATOR FAMILY citext_ops USING hash ADD + FUNCTION 2 citext_hash_extended(citext, int8); diff --git a/contrib/citext/citext.c b/contrib/citext/citext.c index 2c0e48e2bc1..a4adafe8958 100644 --- a/contrib/citext/citext.c +++ b/contrib/citext/citext.c @@ -3,10 +3,10 @@ */ #include "postgres.h" -#include "access/hash.h" #include "catalog/pg_collation.h" #include "utils/builtins.h" #include "utils/formatting.h" +#include "utils/hashutils.h" #include "utils/varlena.h" PG_MODULE_MAGIC; @@ -153,6 +153,26 @@ citext_hash(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +PG_FUNCTION_INFO_V1(citext_hash_extended); + +Datum +citext_hash_extended(PG_FUNCTION_ARGS) +{ + text *txt = PG_GETARG_TEXT_PP(0); + uint64 seed = PG_GETARG_INT64(1); + char *str; + Datum result; + + str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID); + result = hash_any_extended((unsigned char *) str, strlen(str), seed); + pfree(str); + + /* Avoid leaking memory for toasted inputs */ + PG_FREE_IF_COPY(txt, 0); + + PG_RETURN_DATUM(result); +} + /* * ================== * OPERATOR FUNCTIONS diff --git a/contrib/citext/citext.control b/contrib/citext/citext.control index 4cd6e09331f..a872a3f012b 100644 --- a/contrib/citext/citext.control +++ b/contrib/citext/citext.control @@ -1,5 +1,5 @@ # citext extension comment = 'data type for case-insensitive character strings' -default_version = '1.5' +default_version = '1.6' module_pathname = '$libdir/citext' relocatable = true diff --git a/contrib/citext/expected/citext.out b/contrib/citext/expected/citext.out index 95373182af5..96800be9c03 100644 --- a/contrib/citext/expected/citext.out +++ b/contrib/citext/expected/citext.out @@ -222,6 +222,18 @@ SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; t (1 row) +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + -- Do some tests using a table and index. CREATE TEMP TABLE try ( name citext PRIMARY KEY @@ -1829,7 +1841,7 @@ SELECT regexp_match('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citex -- g is not allowed SELECT regexp_match('foobarbequebazmorebarbequetoo'::citext, '(BAR)(BEQUE)'::citext, 'g') AS "error"; -ERROR: regexp_match does not support the global option +ERROR: regexp_match() does not support the "global" option HINT: Use the regexp_matches function instead. CONTEXT: SQL function "regexp_match" statement 1 SELECT regexp_matches('foobarbequebaz'::citext, '(bar)(beque)') = ARRAY[ 'bar', 'beque' ] AS t; @@ -2336,8 +2348,8 @@ SELECT * WHERE t.id IS NULL OR m.id IS NULL; id | name | id | name ----+------+----+------ - 2 | two | | | | 2 | Two + 2 | two | | (2 rows) REFRESH MATERIALIZED VIEW CONCURRENTLY citext_matview; @@ -2597,7 +2609,7 @@ SELECT citext_pattern_ge('b'::citext, 'A'::citext) AS true; t (1 row) --- Multi-byte tests below are diabled like the sanity tests above. +-- Multi-byte tests below are disabled like the sanity tests above. -- Uncomment to run them. -- Test ~<~ and ~<=~ SELECT 'a'::citext ~<~ 'B'::citext AS t; diff --git a/contrib/citext/expected/citext_1.out b/contrib/citext/expected/citext_1.out index 855ec3f10b7..33e3676d3c4 100644 --- a/contrib/citext/expected/citext_1.out +++ b/contrib/citext/expected/citext_1.out @@ -222,6 +222,18 @@ SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; t (1 row) +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + -- Do some tests using a table and index. CREATE TEMP TABLE try ( name citext PRIMARY KEY @@ -1829,7 +1841,7 @@ SELECT regexp_match('foobarbequebaz'::citext, '(BAR)(BEQUE)'::citext, 'c'::citex -- g is not allowed SELECT regexp_match('foobarbequebazmorebarbequetoo'::citext, '(BAR)(BEQUE)'::citext, 'g') AS "error"; -ERROR: regexp_match does not support the global option +ERROR: regexp_match() does not support the "global" option HINT: Use the regexp_matches function instead. CONTEXT: SQL function "regexp_match" statement 1 SELECT regexp_matches('foobarbequebaz'::citext, '(bar)(beque)') = ARRAY[ 'bar', 'beque' ] AS t; @@ -2336,8 +2348,8 @@ SELECT * WHERE t.id IS NULL OR m.id IS NULL; id | name | id | name ----+------+----+------ - 2 | two | | | | 2 | Two + 2 | two | | (2 rows) REFRESH MATERIALIZED VIEW CONCURRENTLY citext_matview; @@ -2597,7 +2609,7 @@ SELECT citext_pattern_ge('b'::citext, 'A'::citext) AS true; t (1 row) --- Multi-byte tests below are diabled like the sanity tests above. +-- Multi-byte tests below are disabled like the sanity tests above. -- Uncomment to run them. -- Test ~<~ and ~<=~ SELECT 'a'::citext ~<~ 'B'::citext AS t; diff --git a/contrib/citext/sql/citext.sql b/contrib/citext/sql/citext.sql index 2732be436dc..261b73cfa6c 100644 --- a/contrib/citext/sql/citext.sql +++ b/contrib/citext/sql/citext.sql @@ -89,6 +89,15 @@ SELECT citext_cmp('aardvark'::citext, 'aardVark'::citext) AS zero; SELECT citext_cmp('AARDVARK'::citext, 'AARDVARK'::citext) AS zero; SELECT citext_cmp('B'::citext, 'a'::citext) > 0 AS true; +-- Check the citext_hash() and citext_hash_extended() function explicitly. +SELECT v as value, citext_hash(v)::bit(32) as standard, + citext_hash_extended(v, 0)::bit(32) as extended0, + citext_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::citext), ('PostgreSQL'), ('eIpUEtqmY89'), ('AXKEJBTK'), + ('muop28x03'), ('yi3nm0d73')) x(v) +WHERE citext_hash(v)::bit(32) != citext_hash_extended(v, 0)::bit(32) + OR citext_hash(v)::bit(32) = citext_hash_extended(v, 1)::bit(32); + -- Do some tests using a table and index. CREATE TEMP TABLE try ( @@ -801,7 +810,7 @@ SELECT citext_pattern_ge('b'::citext, 'a'::citext) AS true; SELECT citext_pattern_ge('B'::citext, 'a'::citext) AS true; SELECT citext_pattern_ge('b'::citext, 'A'::citext) AS true; --- Multi-byte tests below are diabled like the sanity tests above. +-- Multi-byte tests below are disabled like the sanity tests above. -- Uncomment to run them. -- Test ~<~ and ~<=~ diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile index accb7d28a39..5e7b524dc22 100644 --- a/contrib/cube/Makefile +++ b/contrib/cube/Makefile @@ -9,7 +9,9 @@ DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql \ cube--unpackaged--1.0.sql PGFILEDESC = "cube - multidimensional cube data type" -REGRESS = cube +HEADERS = cubedata.h + +REGRESS = cube cube_sci EXTRA_CLEAN = y.tab.c y.tab.h diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c index d96ca1ec1fd..b7203668760 100644 --- a/contrib/cube/cube.c +++ b/contrib/cube/cube.c @@ -8,13 +8,12 @@ #include "postgres.h" -#include #include #include "access/gist.h" #include "access/stratnum.h" #include "utils/array.h" -#include "utils/builtins.h" +#include "utils/float.h" #include "cubedata.h" @@ -101,7 +100,7 @@ bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy); bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy); /* -** Auxiliary funxtions +** Auxiliary functions */ static double distance_1D(double a1, double a2, double b1, double b2); static bool cube_is_point_internal(NDBOX *cube); @@ -152,6 +151,13 @@ cube_a_f8_f8(PG_FUNCTION_ARGS) errmsg("cannot work with arrays containing NULLs"))); dim = ARRNELEMS(ur); + if (dim > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("can't extend cube"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); + if (ARRNELEMS(ll) != dim) ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), @@ -209,6 +215,12 @@ cube_a_f8(PG_FUNCTION_ARGS) errmsg("cannot work with arrays containing NULLs"))); dim = ARRNELEMS(ur); + if (dim > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array is too long"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); dur = ARRPTR(ur); @@ -243,6 +255,13 @@ cube_subset(PG_FUNCTION_ARGS) dx = (int32 *) ARR_DATA_PTR(idx); dim = ARRNELEMS(idx); + if (dim > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array is too long"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); + size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); @@ -571,7 +590,7 @@ g_cube_picksplit(PG_FUNCTION_ARGS) v->spl_nright++; } } - *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */ + *left = *right = FirstOffsetNumber; /* sentinel value */ v->spl_ldatum = PointerGetDatum(datum_l); v->spl_rdatum = PointerGetDatum(datum_r); @@ -1361,9 +1380,10 @@ g_cube_distance(PG_FUNCTION_ARGS) if (coord <= 2 * DIM(cube)) { /* dimension index */ - int index = (coord - 1) / 2; + int index = (coord - 1) / 2; + /* whether this is upper bound (lower bound otherwise) */ - bool upper = ((coord - 1) % 2 == 1); + bool upper = ((coord - 1) % 2 == 1); if (IS_POINT(cube)) { @@ -1596,9 +1616,10 @@ cube_coord_llur(PG_FUNCTION_ARGS) if (coord <= 2 * DIM(cube)) { /* dimension index */ - int index = (coord - 1) / 2; + int index = (coord - 1) / 2; + /* whether this is upper bound (lower bound otherwise) */ - bool upper = ((coord - 1) % 2 == 1); + bool upper = ((coord - 1) % 2 == 1); if (IS_POINT(cube)) { @@ -1615,8 +1636,8 @@ cube_coord_llur(PG_FUNCTION_ARGS) else { /* - * Return zero if coordinate is out of bound. That reproduces logic of - * how cubes with low dimension number are expanded during GiST + * Return zero if coordinate is out of bound. That reproduces logic + * of how cubes with low dimension number are expanded during GiST * indexing. */ result = 0.0; @@ -1754,6 +1775,13 @@ cube_c_f8(PG_FUNCTION_ARGS) int size; int i; + if (DIM(cube) + 1 > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("can't extend cube"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); + if (IS_POINT(cube)) { size = POINT_SIZE((DIM(cube) + 1)); @@ -1795,6 +1823,13 @@ cube_c_f8_f8(PG_FUNCTION_ARGS) int size; int i; + if (DIM(cube) + 1 > CUBE_MAX_DIM) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("can't extend cube"), + errdetail("A cube cannot have more than %d dimensions.", + CUBE_MAX_DIM))); + if (IS_POINT(cube) && (x1 == x2)) { size = POINT_SIZE((DIM(cube) + 1)); diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y index 1b65fa967c0..deb2efdc0da 100644 --- a/contrib/cube/cubeparse.y +++ b/contrib/cube/cubeparse.y @@ -7,7 +7,7 @@ #include "postgres.h" #include "cubedata.h" -#include "utils/builtins.h" +#include "utils/float.h" /* All grammar constructs return strings */ #define YYSTYPE char * diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out index 6378db3004e..5b89cb1a26b 100644 --- a/contrib/cube/expected/cube.out +++ b/contrib/cube/expected/cube.out @@ -62,90 +62,6 @@ SELECT '-1.0'::cube AS cube; (-1) (1 row) -SELECT '1e27'::cube AS cube; - cube ---------- - (1e+27) -(1 row) - -SELECT '-1e27'::cube AS cube; - cube ----------- - (-1e+27) -(1 row) - -SELECT '1.0e27'::cube AS cube; - cube ---------- - (1e+27) -(1 row) - -SELECT '-1.0e27'::cube AS cube; - cube ----------- - (-1e+27) -(1 row) - -SELECT '1e+27'::cube AS cube; - cube ---------- - (1e+27) -(1 row) - -SELECT '-1e+27'::cube AS cube; - cube ----------- - (-1e+27) -(1 row) - -SELECT '1.0e+27'::cube AS cube; - cube ---------- - (1e+27) -(1 row) - -SELECT '-1.0e+27'::cube AS cube; - cube ----------- - (-1e+27) -(1 row) - -SELECT '1e-7'::cube AS cube; - cube ---------- - (1e-07) -(1 row) - -SELECT '-1e-7'::cube AS cube; - cube ----------- - (-1e-07) -(1 row) - -SELECT '1.0e-7'::cube AS cube; - cube ---------- - (1e-07) -(1 row) - -SELECT '-1.0e-7'::cube AS cube; - cube ----------- - (-1e-07) -(1 row) - -SELECT '1e-300'::cube AS cube; - cube ----------- - (1e-300) -(1 row) - -SELECT '-1e-300'::cube AS cube; - cube ------------ - (-1e-300) -(1 row) - SELECT 'infinity'::cube AS cube; cube ------------ @@ -164,40 +80,22 @@ SELECT 'NaN'::cube AS cube; (NaN) (1 row) -SELECT '1234567890123456'::cube AS cube; - cube ------------------------- - (1.23456789012346e+15) -(1 row) - -SELECT '+1234567890123456'::cube AS cube; - cube ------------------------- - (1.23456789012346e+15) -(1 row) - -SELECT '-1234567890123456'::cube AS cube; - cube -------------------------- - (-1.23456789012346e+15) -(1 row) - SELECT '.1234567890123456'::cube AS cube; - cube ---------------------- - (0.123456789012346) + cube +---------------------- + (0.1234567890123456) (1 row) SELECT '+.1234567890123456'::cube AS cube; - cube ---------------------- - (0.123456789012346) + cube +---------------------- + (0.1234567890123456) (1 row) SELECT '-.1234567890123456'::cube AS cube; - cube ----------------------- - (-0.123456789012346) + cube +----------------------- + (-0.1234567890123456) (1 row) -- simple lists (points) @@ -520,6 +418,17 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); ERROR: Index out of bounds SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]); ERROR: Index out of bounds +-- test for limits: this should pass +SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100))); + cube_subset +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6) +(1 row) + +-- and this should fail +SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101))); +ERROR: array is too long +DETAIL: A cube cannot have more than 100 dimensions. -- -- Test point processing -- @@ -592,6 +501,7 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8 -- -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- +-- create too big cube from literal select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube; ERROR: invalid input syntax for cube LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0... @@ -602,6 +512,34 @@ ERROR: invalid input syntax for cube LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0... ^ DETAIL: A cube cannot have more than 100 dimensions. +-- from an array +select cube(array(SELECT 0 as a FROM generate_series(1,101))); +ERROR: array is too long +DETAIL: A cube cannot have more than 100 dimensions. +select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101))); +ERROR: can't extend cube +DETAIL: A cube cannot have more than 100 dimensions. +-- extend cube beyond limit +-- this should work +select cube(array(SELECT 0 as a FROM generate_series(1,100))); + cube +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +(1 row) + +select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))); + cube +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +(1 row) + +-- this should fail +select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0); +ERROR: can't extend cube +DETAIL: A cube cannot have more than 100 dimensions. +select cube(cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))), 0, 0); +ERROR: can't extend cube +DETAIL: A cube cannot have more than 100 dimensions. -- -- testing the operators -- @@ -1005,9 +943,9 @@ SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube); (1 row) SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube); - cube_distance ------------------- - 140.762210837994 + cube_distance +-------------------- + 140.76221083799445 (1 row) -- Test of cube function (text to cube) @@ -1418,8 +1356,9 @@ SELECT cube_size('(42,137)'::cube); 0 (1 row) --- Test of distances +-- Test of distances (euclidean distance may not be bit-exact) -- +SET extra_float_digits = 0; SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube); cube_distance --------------- @@ -1432,6 +1371,7 @@ SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e; 5 (1 row) +RESET extra_float_digits; SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube); distance_chebyshev -------------------- @@ -1619,6 +1559,7 @@ RESET enable_bitmapscan; INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases SET enable_seqscan = false; -- Test different metrics +SET extra_float_digits = 0; SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; c | dist -------------------------+------------------ @@ -1629,6 +1570,7 @@ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c (1444, 403),(1346, 344) | 846 (5 rows) +RESET extra_float_digits; SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; c | dist -------------------------+------ @@ -1813,6 +1755,7 @@ SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upp -- Same queries with sequential scan (should give the same results as above) RESET enable_seqscan; SET enable_indexscan = OFF; +SET extra_float_digits = 0; SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; c | dist -------------------------+------------------ @@ -1823,6 +1766,7 @@ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c (1444, 403),(1346, 344) | 846 (5 rows) +RESET extra_float_digits; SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; c | dist -------------------------+------ diff --git a/contrib/cube/expected/cube_2.out b/contrib/cube/expected/cube_2.out deleted file mode 100644 index 75fe405c497..00000000000 --- a/contrib/cube/expected/cube_2.out +++ /dev/null @@ -1,2006 +0,0 @@ --- --- Test cube datatype --- -CREATE EXTENSION cube; --- Check whether any of our opclasses fail amvalidate -SELECT amname, opcname -FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod -WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); - amname | opcname ---------+--------- -(0 rows) - --- --- testing the input and output functions --- --- Any number (a one-dimensional point) -SELECT '1'::cube AS cube; - cube ------- - (1) -(1 row) - -SELECT '-1'::cube AS cube; - cube ------- - (-1) -(1 row) - -SELECT '1.'::cube AS cube; - cube ------- - (1) -(1 row) - -SELECT '-1.'::cube AS cube; - cube ------- - (-1) -(1 row) - -SELECT '.1'::cube AS cube; - cube -------- - (0.1) -(1 row) - -SELECT '-.1'::cube AS cube; - cube --------- - (-0.1) -(1 row) - -SELECT '1.0'::cube AS cube; - cube ------- - (1) -(1 row) - -SELECT '-1.0'::cube AS cube; - cube ------- - (-1) -(1 row) - -SELECT '1e27'::cube AS cube; - cube ----------- - (1e+027) -(1 row) - -SELECT '-1e27'::cube AS cube; - cube ------------ - (-1e+027) -(1 row) - -SELECT '1.0e27'::cube AS cube; - cube ----------- - (1e+027) -(1 row) - -SELECT '-1.0e27'::cube AS cube; - cube ------------ - (-1e+027) -(1 row) - -SELECT '1e+27'::cube AS cube; - cube ----------- - (1e+027) -(1 row) - -SELECT '-1e+27'::cube AS cube; - cube ------------ - (-1e+027) -(1 row) - -SELECT '1.0e+27'::cube AS cube; - cube ----------- - (1e+027) -(1 row) - -SELECT '-1.0e+27'::cube AS cube; - cube ------------ - (-1e+027) -(1 row) - -SELECT '1e-7'::cube AS cube; - cube ----------- - (1e-007) -(1 row) - -SELECT '-1e-7'::cube AS cube; - cube ------------ - (-1e-007) -(1 row) - -SELECT '1.0e-7'::cube AS cube; - cube ----------- - (1e-007) -(1 row) - -SELECT '-1.0e-7'::cube AS cube; - cube ------------ - (-1e-007) -(1 row) - -SELECT '1e-300'::cube AS cube; - cube ----------- - (1e-300) -(1 row) - -SELECT '-1e-300'::cube AS cube; - cube ------------ - (-1e-300) -(1 row) - -SELECT 'infinity'::cube AS cube; - cube ------------- - (Infinity) -(1 row) - -SELECT '-infinity'::cube AS cube; - cube -------------- - (-Infinity) -(1 row) - -SELECT 'NaN'::cube AS cube; - cube -------- - (NaN) -(1 row) - -SELECT '1234567890123456'::cube AS cube; - cube -------------------------- - (1.23456789012346e+015) -(1 row) - -SELECT '+1234567890123456'::cube AS cube; - cube -------------------------- - (1.23456789012346e+015) -(1 row) - -SELECT '-1234567890123456'::cube AS cube; - cube --------------------------- - (-1.23456789012346e+015) -(1 row) - -SELECT '.1234567890123456'::cube AS cube; - cube ---------------------- - (0.123456789012346) -(1 row) - -SELECT '+.1234567890123456'::cube AS cube; - cube ---------------------- - (0.123456789012346) -(1 row) - -SELECT '-.1234567890123456'::cube AS cube; - cube ----------------------- - (-0.123456789012346) -(1 row) - --- simple lists (points) -SELECT '()'::cube AS cube; - cube ------- - () -(1 row) - -SELECT '1,2'::cube AS cube; - cube --------- - (1, 2) -(1 row) - -SELECT '(1,2)'::cube AS cube; - cube --------- - (1, 2) -(1 row) - -SELECT '1,2,3,4,5'::cube AS cube; - cube ------------------ - (1, 2, 3, 4, 5) -(1 row) - -SELECT '(1,2,3,4,5)'::cube AS cube; - cube ------------------ - (1, 2, 3, 4, 5) -(1 row) - --- double lists (cubes) -SELECT '(),()'::cube AS cube; - cube ------- - () -(1 row) - -SELECT '(0),(0)'::cube AS cube; - cube ------- - (0) -(1 row) - -SELECT '(0),(1)'::cube AS cube; - cube ---------- - (0),(1) -(1 row) - -SELECT '[(0),(0)]'::cube AS cube; - cube ------- - (0) -(1 row) - -SELECT '[(0),(1)]'::cube AS cube; - cube ---------- - (0),(1) -(1 row) - -SELECT '(0,0,0,0),(0,0,0,0)'::cube AS cube; - cube --------------- - (0, 0, 0, 0) -(1 row) - -SELECT '(0,0,0,0),(1,0,0,0)'::cube AS cube; - cube ---------------------------- - (0, 0, 0, 0),(1, 0, 0, 0) -(1 row) - -SELECT '[(0,0,0,0),(0,0,0,0)]'::cube AS cube; - cube --------------- - (0, 0, 0, 0) -(1 row) - -SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube; - cube ---------------------------- - (0, 0, 0, 0),(1, 0, 0, 0) -(1 row) - --- invalid input: parse errors -SELECT ''::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT ''::cube AS cube; - ^ -DETAIL: syntax error at end of input -SELECT 'ABC'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT 'ABC'::cube AS cube; - ^ -DETAIL: syntax error at or near "A" -SELECT '[]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[]'::cube AS cube; - ^ -DETAIL: syntax error at or near "]" -SELECT '[()]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[()]'::cube AS cube; - ^ -DETAIL: syntax error at or near "]" -SELECT '[(1)]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1)]'::cube AS cube; - ^ -DETAIL: syntax error at or near "]" -SELECT '[(1),]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1),]'::cube AS cube; - ^ -DETAIL: syntax error at or near "]" -SELECT '[(1),2]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1),2]'::cube AS cube; - ^ -DETAIL: syntax error at or near "2" -SELECT '[(1),(2),(3)]'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1),(2),(3)]'::cube AS cube; - ^ -DETAIL: syntax error at or near "," -SELECT '1,'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '1,'::cube AS cube; - ^ -DETAIL: syntax error at end of input -SELECT '1,2,'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '1,2,'::cube AS cube; - ^ -DETAIL: syntax error at end of input -SELECT '1,,2'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '1,,2'::cube AS cube; - ^ -DETAIL: syntax error at or near "," -SELECT '(1,)'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,)'::cube AS cube; - ^ -DETAIL: syntax error at or near ")" -SELECT '(1,2,)'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2,)'::cube AS cube; - ^ -DETAIL: syntax error at or near ")" -SELECT '(1,,2)'::cube AS cube; -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,,2)'::cube AS cube; - ^ -DETAIL: syntax error at or near "," --- invalid input: semantic errors and trailing garbage -SELECT '[(1),(2)],'::cube AS cube; -- 0 -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1),(2)],'::cube AS cube; - ^ -DETAIL: syntax error at or near "," -SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1 -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1,2,3),(2,3)]'::cube AS cube; - ^ -DETAIL: Different point dimensions in (1,2,3) and (2,3). -SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1 -ERROR: invalid input syntax for cube -LINE 1: SELECT '[(1,2),(1,2,3)]'::cube AS cube; - ^ -DETAIL: Different point dimensions in (1,2) and (1,2,3). -SELECT '(1),(2),'::cube AS cube; -- 2 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1),(2),'::cube AS cube; - ^ -DETAIL: syntax error at or near "," -SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2,3),(2,3)'::cube AS cube; - ^ -DETAIL: Different point dimensions in (1,2,3) and (2,3). -SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2),(1,2,3)'::cube AS cube; - ^ -DETAIL: Different point dimensions in (1,2) and (1,2,3). -SELECT '(1,2,3)ab'::cube AS cube; -- 4 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2,3)ab'::cube AS cube; - ^ -DETAIL: syntax error at or near "a" -SELECT '(1,2,3)a'::cube AS cube; -- 5 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2,3)a'::cube AS cube; - ^ -DETAIL: syntax error at or near "a" -SELECT '(1,2)('::cube AS cube; -- 5 -ERROR: invalid input syntax for cube -LINE 1: SELECT '(1,2)('::cube AS cube; - ^ -DETAIL: syntax error at or near "(" -SELECT '1,2ab'::cube AS cube; -- 6 -ERROR: invalid input syntax for cube -LINE 1: SELECT '1,2ab'::cube AS cube; - ^ -DETAIL: syntax error at or near "a" -SELECT '1 e7'::cube AS cube; -- 6 -ERROR: invalid input syntax for cube -LINE 1: SELECT '1 e7'::cube AS cube; - ^ -DETAIL: syntax error at or near "e" -SELECT '1,2a'::cube AS cube; -- 7 -ERROR: invalid input syntax for cube -LINE 1: SELECT '1,2a'::cube AS cube; - ^ -DETAIL: syntax error at or near "a" -SELECT '1..2'::cube AS cube; -- 7 -ERROR: invalid input syntax for cube -LINE 1: SELECT '1..2'::cube AS cube; - ^ -DETAIL: syntax error at or near ".2" -SELECT '-1e-700'::cube AS cube; -- out of range -ERROR: "-1e-700" is out of range for type double precision -LINE 1: SELECT '-1e-700'::cube AS cube; - ^ --- --- Testing building cubes from float8 values --- -SELECT cube(0::float8); - cube ------- - (0) -(1 row) - -SELECT cube(1::float8); - cube ------- - (1) -(1 row) - -SELECT cube(1,2); - cube ---------- - (1),(2) -(1 row) - -SELECT cube(cube(1,2),3); - cube ---------------- - (1, 3),(2, 3) -(1 row) - -SELECT cube(cube(1,2),3,4); - cube ---------------- - (1, 3),(2, 4) -(1 row) - -SELECT cube(cube(cube(1,2),3,4),5); - cube ---------------------- - (1, 3, 5),(2, 4, 5) -(1 row) - -SELECT cube(cube(cube(1,2),3,4),5,6); - cube ---------------------- - (1, 3, 5),(2, 4, 6) -(1 row) - --- --- Test that the text -> cube cast was installed. --- -SELECT '(0)'::text::cube; - cube ------- - (0) -(1 row) - --- --- Test the float[] -> cube cast --- -SELECT cube('{0,1,2}'::float[], '{3,4,5}'::float[]); - cube ---------------------- - (0, 1, 2),(3, 4, 5) -(1 row) - -SELECT cube('{0,1,2}'::float[], '{3}'::float[]); -ERROR: UR and LL arrays must be of same length -SELECT cube(NULL::float[], '{3}'::float[]); - cube ------- - -(1 row) - -SELECT cube('{0,1,2}'::float[]); - cube ------------ - (0, 1, 2) -(1 row) - -SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]); - cube_subset ---------------------------- - (5, 3, 1, 1),(8, 7, 6, 6) -(1 row) - -SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]); - cube_subset --------------- - (5, 3, 1, 1) -(1 row) - -SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); -ERROR: Index out of bounds -SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]); -ERROR: Index out of bounds --- --- Test point processing --- -SELECT cube('(1,2),(1,2)'); -- cube_in - cube --------- - (1, 2) -(1 row) - -SELECT cube('{0,1,2}'::float[], '{0,1,2}'::float[]); -- cube_a_f8_f8 - cube ------------ - (0, 1, 2) -(1 row) - -SELECT cube('{5,6,7,8}'::float[]); -- cube_a_f8 - cube --------------- - (5, 6, 7, 8) -(1 row) - -SELECT cube(1.37); -- cube_f8 - cube --------- - (1.37) -(1 row) - -SELECT cube(1.37, 1.37); -- cube_f8_f8 - cube --------- - (1.37) -(1 row) - -SELECT cube(cube(1,1), 42); -- cube_c_f8 - cube ---------- - (1, 42) -(1 row) - -SELECT cube(cube(1,2), 42); -- cube_c_f8 - cube ------------------ - (1, 42),(2, 42) -(1 row) - -SELECT cube(cube(1,1), 42, 42); -- cube_c_f8_f8 - cube ---------- - (1, 42) -(1 row) - -SELECT cube(cube(1,1), 42, 24); -- cube_c_f8_f8 - cube ------------------ - (1, 42),(1, 24) -(1 row) - -SELECT cube(cube(1,2), 42, 42); -- cube_c_f8_f8 - cube ------------------ - (1, 42),(2, 42) -(1 row) - -SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8 - cube ------------------ - (1, 42),(2, 24) -(1 row) - --- --- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. --- -select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube; -ERROR: invalid input syntax for cube -LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0... - ^ -DETAIL: A cube cannot have more than 100 dimensions. -select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube; -ERROR: invalid input syntax for cube -LINE 1: select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0... - ^ -DETAIL: A cube cannot have more than 100 dimensions. --- --- testing the operators --- --- equality/inequality: --- -SELECT '24, 33.20'::cube = '24, 33.20'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '24, 33.20'::cube != '24, 33.20'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '24, 33.20'::cube = '24, 33.21'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '24, 33.20'::cube != '24, 33.21'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool; - bool ------- - f -(1 row) - --- "lower than" / "greater than" --- (these operators are not useful for anything but ordering) --- -SELECT '1'::cube > '2'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '1'::cube < '2'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '1,1'::cube > '1,2'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '1,1'::cube < '1,2'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube > '(2,0),(3,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube < '(2,0),(3,1)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool; - bool ------- - f -(1 row) - --- "overlap" --- -SELECT '1'::cube && '1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '1'::cube && '2'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1,1,1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1,1),(2,2,2)]'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1),(2,2)]'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(2,1,1),(2,2,2)]'::cube AS bool; - bool ------- - f -(1 row) - --- "contained in" (the left operand is the cube entirely enclosed by --- the right operand): --- -SELECT '0'::cube <@ '0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0,0'::cube <@ '0,0,0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0'::cube <@ '0,0,1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0,0'::cube <@ '0,0,1'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '1,0,0'::cube <@ '0,0,1'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(1,0,0),(0,0,1)'::cube <@ '(1,0,0),(0,0,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(1,0,0),(0,0,1)'::cube <@ '(-1,-1,-1),(1,1,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(1,0,0),(0,0,1)'::cube <@ '(-1,-1,-1,-1),(1,1,1,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0'::cube <@ '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '1'::cube <@ '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '-1'::cube <@ '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube <@ '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube <@ '(-1,-1),(1,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-2),(1)'::cube <@ '(-1),(1)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(-2),(1)'::cube <@ '(-1,-1),(1,1)'::cube AS bool; - bool ------- - f -(1 row) - --- "contains" (the left operand is the cube that entirely encloses the --- right operand) --- -SELECT '0'::cube @> '0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0,0'::cube @> '0,0,0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0,1'::cube @> '0,0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '0,0,1'::cube @> '0,0,0'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '0,0,1'::cube @> '1,0,0'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(1,0,0),(0,0,1)'::cube @> '(1,0,0),(0,0,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1,-1,-1),(1,1,1)'::cube @> '(1,0,0),(0,0,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1,-1,-1,-1),(1,1,1,1)'::cube @> '(1,0,0),(0,0,1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube @> '0'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube @> '1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube @> '-1'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube @> '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1,-1),(1,1)'::cube @> '(-1),(1)'::cube AS bool; - bool ------- - t -(1 row) - -SELECT '(-1),(1)'::cube @> '(-2),(1)'::cube AS bool; - bool ------- - f -(1 row) - -SELECT '(-1,-1),(1,1)'::cube @> '(-2),(1)'::cube AS bool; - bool ------- - f -(1 row) - --- Test of distance function --- -SELECT cube_distance('(0)'::cube,'(2,2,2,2)'::cube); - cube_distance ---------------- - 4 -(1 row) - -SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube); - cube_distance ---------------- - 0.5 -(1 row) - -SELECT cube_distance('(2,3,4)'::cube,'(2,3,4)'::cube); - cube_distance ---------------- - 0 -(1 row) - -SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube); - cube_distance ---------------- - 190 -(1 row) - -SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube); - cube_distance ------------------- - 140.762210837994 -(1 row) - --- Test of cube function (text to cube) --- -SELECT cube('(1,1.2)'::text); - cube ----------- - (1, 1.2) -(1 row) - -SELECT cube(NULL); - cube ------- - -(1 row) - --- Test of cube_dim function (dimensions stored in cube) --- -SELECT cube_dim('(0)'::cube); - cube_dim ----------- - 1 -(1 row) - -SELECT cube_dim('(0,0)'::cube); - cube_dim ----------- - 2 -(1 row) - -SELECT cube_dim('(0,0,0)'::cube); - cube_dim ----------- - 3 -(1 row) - -SELECT cube_dim('(42,42,42),(42,42,42)'::cube); - cube_dim ----------- - 3 -(1 row) - -SELECT cube_dim('(4,8,15,16,23),(4,8,15,16,23)'::cube); - cube_dim ----------- - 5 -(1 row) - --- Test of cube_ll_coord function (retrieves LL coordinate values) --- -SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1); - cube_ll_coord ---------------- - -1 -(1 row) - -SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 2); - cube_ll_coord ---------------- - -2 -(1 row) - -SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3); - cube_ll_coord ---------------- - 0 -(1 row) - -SELECT cube_ll_coord('(1,2),(1,2)'::cube, 1); - cube_ll_coord ---------------- - 1 -(1 row) - -SELECT cube_ll_coord('(1,2),(1,2)'::cube, 2); - cube_ll_coord ---------------- - 2 -(1 row) - -SELECT cube_ll_coord('(1,2),(1,2)'::cube, 3); - cube_ll_coord ---------------- - 0 -(1 row) - -SELECT cube_ll_coord('(42,137)'::cube, 1); - cube_ll_coord ---------------- - 42 -(1 row) - -SELECT cube_ll_coord('(42,137)'::cube, 2); - cube_ll_coord ---------------- - 137 -(1 row) - -SELECT cube_ll_coord('(42,137)'::cube, 3); - cube_ll_coord ---------------- - 0 -(1 row) - --- Test of cube_ur_coord function (retrieves UR coordinate values) --- -SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1); - cube_ur_coord ---------------- - 2 -(1 row) - -SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 2); - cube_ur_coord ---------------- - 1 -(1 row) - -SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3); - cube_ur_coord ---------------- - 0 -(1 row) - -SELECT cube_ur_coord('(1,2),(1,2)'::cube, 1); - cube_ur_coord ---------------- - 1 -(1 row) - -SELECT cube_ur_coord('(1,2),(1,2)'::cube, 2); - cube_ur_coord ---------------- - 2 -(1 row) - -SELECT cube_ur_coord('(1,2),(1,2)'::cube, 3); - cube_ur_coord ---------------- - 0 -(1 row) - -SELECT cube_ur_coord('(42,137)'::cube, 1); - cube_ur_coord ---------------- - 42 -(1 row) - -SELECT cube_ur_coord('(42,137)'::cube, 2); - cube_ur_coord ---------------- - 137 -(1 row) - -SELECT cube_ur_coord('(42,137)'::cube, 3); - cube_ur_coord ---------------- - 0 -(1 row) - --- Test of cube_is_point --- -SELECT cube_is_point('(0)'::cube); - cube_is_point ---------------- - t -(1 row) - -SELECT cube_is_point('(0,1,2)'::cube); - cube_is_point ---------------- - t -(1 row) - -SELECT cube_is_point('(0,1,2),(0,1,2)'::cube); - cube_is_point ---------------- - t -(1 row) - -SELECT cube_is_point('(0,1,2),(-1,1,2)'::cube); - cube_is_point ---------------- - f -(1 row) - -SELECT cube_is_point('(0,1,2),(0,-1,2)'::cube); - cube_is_point ---------------- - f -(1 row) - -SELECT cube_is_point('(0,1,2),(0,1,-2)'::cube); - cube_is_point ---------------- - f -(1 row) - --- Test of cube_enlarge (enlarging and shrinking cubes) --- -SELECT cube_enlarge('(0)'::cube, 0, 0); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(0)'::cube, 0, 1); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(0)'::cube, 0, 2); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(2),(-2)'::cube, 0, 4); - cube_enlarge --------------- - (-2),(2) -(1 row) - -SELECT cube_enlarge('(0)'::cube, 1, 0); - cube_enlarge --------------- - (-1),(1) -(1 row) - -SELECT cube_enlarge('(0)'::cube, 1, 1); - cube_enlarge --------------- - (-1),(1) -(1 row) - -SELECT cube_enlarge('(0)'::cube, 1, 2); - cube_enlarge ------------------ - (-1, -1),(1, 1) -(1 row) - -SELECT cube_enlarge('(2),(-2)'::cube, 1, 4); - cube_enlarge -------------------------------- - (-3, -1, -1, -1),(3, 1, 1, 1) -(1 row) - -SELECT cube_enlarge('(0)'::cube, -1, 0); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(0)'::cube, -1, 1); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(0)'::cube, -1, 2); - cube_enlarge --------------- - (0) -(1 row) - -SELECT cube_enlarge('(2),(-2)'::cube, -1, 4); - cube_enlarge --------------- - (-1),(1) -(1 row) - -SELECT cube_enlarge('(0,0,0)'::cube, 1, 0); - cube_enlarge ------------------------- - (-1, -1, -1),(1, 1, 1) -(1 row) - -SELECT cube_enlarge('(0,0,0)'::cube, 1, 2); - cube_enlarge ------------------------- - (-1, -1, -1),(1, 1, 1) -(1 row) - -SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 1, 2); - cube_enlarge ------------------ - (-4, -3),(3, 8) -(1 row) - -SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 3, 2); - cube_enlarge ------------------- - (-6, -5),(5, 10) -(1 row) - -SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -1, 2); - cube_enlarge ------------------ - (-2, -1),(1, 6) -(1 row) - -SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2); - cube_enlarge ---------------------- - (-0.5, 1),(-0.5, 4) -(1 row) - -SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -23, 5); - cube_enlarge --------------- - (42, 0, 0) -(1 row) - -SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -24, 5); - cube_enlarge --------------- - (42, 0, 0) -(1 row) - --- Test of cube_union (MBR for two cubes) --- -SELECT cube_union('(1,2),(3,4)'::cube, '(5,6,7),(8,9,10)'::cube); - cube_union ----------------------- - (1, 2, 0),(8, 9, 10) -(1 row) - -SELECT cube_union('(1,2)'::cube, '(4,2,0,0)'::cube); - cube_union ---------------------------- - (1, 2, 0, 0),(4, 2, 0, 0) -(1 row) - -SELECT cube_union('(1,2),(1,2)'::cube, '(4,2),(4,2)'::cube); - cube_union ---------------- - (1, 2),(4, 2) -(1 row) - -SELECT cube_union('(1,2),(1,2)'::cube, '(1,2),(1,2)'::cube); - cube_union ------------- - (1, 2) -(1 row) - -SELECT cube_union('(1,2),(1,2)'::cube, '(1,2,0),(1,2,0)'::cube); - cube_union ------------- - (1, 2, 0) -(1 row) - --- Test of cube_inter --- -SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (16,15)'::cube); -- intersects - cube_inter ------------------ - (3, 4),(10, 11) -(1 row) - -SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (6,5)'::cube); -- includes - cube_inter ---------------- - (3, 4),(6, 5) -(1 row) - -SELECT cube_inter('(1,2),(10,11)'::cube, '(13,14), (16,15)'::cube); -- no intersection - cube_inter -------------------- - (13, 14),(10, 11) -(1 row) - -SELECT cube_inter('(1,2),(10,11)'::cube, '(3,14), (16,15)'::cube); -- no intersection, but one dimension intersects - cube_inter ------------------- - (3, 14),(10, 11) -(1 row) - -SELECT cube_inter('(1,2),(10,11)'::cube, '(10,11), (16,15)'::cube); -- point intersection - cube_inter ------------- - (10, 11) -(1 row) - -SELECT cube_inter('(1,2,3)'::cube, '(1,2,3)'::cube); -- point args - cube_inter ------------- - (1, 2, 3) -(1 row) - -SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args - cube_inter ---------------------- - (5, 6, 3),(1, 2, 3) -(1 row) - --- Test of cube_size --- -SELECT cube_size('(4,8),(15,16)'::cube); - cube_size ------------ - 88 -(1 row) - -SELECT cube_size('(42,137)'::cube); - cube_size ------------ - 0 -(1 row) - --- Test of distances --- -SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube); - cube_distance ---------------- - 5 -(1 row) - -SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e; - d_e ------ - 5 -(1 row) - -SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube); - distance_chebyshev --------------------- - 4 -(1 row) - -SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c; - d_c ------ - 4 -(1 row) - -SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube); - distance_taxicab ------------------- - 7 -(1 row) - -SELECT '(1,1)'::cube <#> '(4,5)'::cube as d_t; - d_t ------ - 7 -(1 row) - --- zero for overlapping -SELECT cube_distance('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube); - cube_distance ---------------- - 0 -(1 row) - -SELECT distance_chebyshev('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube); - distance_chebyshev --------------------- - 0 -(1 row) - -SELECT distance_taxicab('(2,2),(10,10)'::cube, '(0,0),(5,5)'::cube); - distance_taxicab ------------------- - 0 -(1 row) - --- coordinate access -SELECT cube(array[10,20,30], array[40,50,60])->1; - ?column? ----------- - 10 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])->1; - ?column? ----------- - 40 -(1 row) - -SELECT cube(array[10,20,30], array[40,50,60])->6; - ?column? ----------- - 60 -(1 row) - -SELECT cube(array[10,20,30], array[40,50,60])->0; -ERROR: cube index 0 is out of bounds -SELECT cube(array[10,20,30], array[40,50,60])->7; -ERROR: cube index 7 is out of bounds -SELECT cube(array[10,20,30], array[40,50,60])->-1; -ERROR: cube index -1 is out of bounds -SELECT cube(array[10,20,30], array[40,50,60])->-6; -ERROR: cube index -6 is out of bounds -SELECT cube(array[10,20,30])->3; - ?column? ----------- - 30 -(1 row) - -SELECT cube(array[10,20,30])->6; - ?column? ----------- - 30 -(1 row) - -SELECT cube(array[10,20,30])->-6; -ERROR: cube index -6 is out of bounds --- "normalized" coordinate access -SELECT cube(array[10,20,30], array[40,50,60])~>1; - ?column? ----------- - 10 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])~>1; - ?column? ----------- - 10 -(1 row) - -SELECT cube(array[10,20,30], array[40,50,60])~>2; - ?column? ----------- - 40 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])~>2; - ?column? ----------- - 40 -(1 row) - -SELECT cube(array[10,20,30], array[40,50,60])~>3; - ?column? ----------- - 20 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])~>3; - ?column? ----------- - 20 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])~>0; -ERROR: zero cube index is not defined -SELECT cube(array[40,50,60], array[10,20,30])~>4; - ?column? ----------- - 50 -(1 row) - -SELECT cube(array[40,50,60], array[10,20,30])~>(-1); - ?column? ----------- - -10 -(1 row) - --- Load some example data and build the index --- -CREATE TABLE test_cube (c cube); -\copy test_cube from 'data/test_cube.data' -CREATE INDEX test_cube_ix ON test_cube USING gist (c); -SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' ORDER BY c; - c --------------------------- - (337, 455),(240, 359) - (759, 187),(662, 163) - (1444, 403),(1346, 344) - (1594, 1043),(1517, 971) - (2424, 160),(2424, 81) -(5 rows) - --- Test sorting -SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c; - c --------------------------- - (337, 455),(240, 359) - (759, 187),(662, 163) - (1444, 403),(1346, 344) - (1594, 1043),(1517, 971) - (2424, 160),(2424, 81) -(5 rows) - --- Test index-only scans -SET enable_bitmapscan = false; -EXPLAIN (COSTS OFF) -SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)' ORDER BY c; - QUERY PLAN --------------------------------------------------------- - Sort - Sort Key: c - -> Index Only Scan using test_cube_ix on test_cube - Index Cond: (c <@ '(3000, 1000),(0, 0)'::cube) -(4 rows) - -SELECT c FROM test_cube WHERE c <@ '(3000,1000),(0,0)' ORDER BY c; - c -------------------------- - (337, 455),(240, 359) - (759, 187),(662, 163) - (1444, 403),(1346, 344) - (2424, 160),(2424, 81) -(4 rows) - -RESET enable_bitmapscan; --- Test kNN -INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases -SET enable_seqscan = false; --- Test different metrics -SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------------------ - (337, 455),(240, 359) | 0 - (1, 1) | 140.007142674936 - (759, 187),(662, 163) | 162 - (948, 1201),(907, 1156) | 772.000647668122 - (1444, 403),(1346, 344) | 846 -(5 rows) - -SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------ - (337, 455),(240, 359) | 0 - (1, 1) | 99 - (759, 187),(662, 163) | 162 - (948, 1201),(907, 1156) | 656 - (1444, 403),(1346, 344) | 846 -(5 rows) - -SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------ - (337, 455),(240, 359) | 0 - (759, 187),(662, 163) | 162 - (1, 1) | 198 - (1444, 403),(1346, 344) | 846 - (369, 1457),(278, 1409) | 909 -(5 rows) - --- Test sorting by coordinates -SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound - ?column? | c -----------+--------------------------- - 0 | (0, 100000) - 1 | (1, 1) - 3 | (54, 38679),(3, 38602) - 15 | (83, 10271),(15, 10265) - 64 | (122, 46832),(64, 46762) - 92 | (167, 17214),(92, 17184) - 107 | (161, 24465),(107, 24374) - 120 | (162, 26040),(120, 25963) - 138 | (154, 4019),(138, 3990) - 175 | (259, 1850),(175, 1820) - 179 | (207, 40886),(179, 40879) - 204 | (288, 49588),(204, 49571) - 226 | (270, 32616),(226, 32607) - 235 | (318, 31489),(235, 31404) - 240 | (337, 455),(240, 359) -(15 rows) - -SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound - ?column? | c -----------+--------------------------- - 0 | (0, 100000) - 1 | (1, 1) - 54 | (54, 38679),(3, 38602) - 83 | (83, 10271),(15, 10265) - 122 | (122, 46832),(64, 46762) - 154 | (154, 4019),(138, 3990) - 161 | (161, 24465),(107, 24374) - 162 | (162, 26040),(120, 25963) - 167 | (167, 17214),(92, 17184) - 207 | (207, 40886),(179, 40879) - 259 | (259, 1850),(175, 1820) - 270 | (270, 29508),(264, 29440) - 270 | (270, 32616),(226, 32607) - 288 | (288, 49588),(204, 49571) - 318 | (318, 31489),(235, 31404) -(15 rows) - -SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound - ?column? | c -----------+--------------------------- - 0 | (100000) - 1 | (1, 1) - 6 | (30333, 50),(30273, 6) - 43 | (43301, 75),(43227, 43) - 51 | (19650, 142),(19630, 51) - 81 | (2424, 160),(2424, 81) - 108 | (3449, 171),(3354, 108) - 109 | (18037, 155),(17941, 109) - 114 | (28511, 208),(28479, 114) - 118 | (19946, 217),(19941, 118) - 139 | (16906, 191),(16816, 139) - 163 | (759, 187),(662, 163) - 181 | (22684, 266),(22656, 181) - 213 | (24423, 255),(24360, 213) - 222 | (45989, 249),(45910, 222) -(15 rows) - -SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound - ?column? | c -----------+--------------------------- - 0 | (100000) - 1 | (1, 1) - 50 | (30333, 50),(30273, 6) - 75 | (43301, 75),(43227, 43) - 142 | (19650, 142),(19630, 51) - 155 | (18037, 155),(17941, 109) - 160 | (2424, 160),(2424, 81) - 171 | (3449, 171),(3354, 108) - 187 | (759, 187),(662, 163) - 191 | (16906, 191),(16816, 139) - 208 | (28511, 208),(28479, 114) - 217 | (19946, 217),(19941, 118) - 249 | (45989, 249),(45910, 222) - 255 | (24423, 255),(24360, 213) - 266 | (22684, 266),(22656, 181) -(15 rows) - -SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound - ?column? | c -----------+------------------------------- - -100000 | (100000) - -49951 | (50027, 49230),(49951, 49214) - -49937 | (49980, 35004),(49937, 34963) - -49927 | (49985, 6436),(49927, 6338) - -49908 | (49999, 27218),(49908, 27176) - -49905 | (49954, 1340),(49905, 1294) - -49902 | (49944, 25163),(49902, 25153) - -49898 | (49981, 34876),(49898, 34786) - -49897 | (49957, 43390),(49897, 43384) - -49848 | (49853, 18504),(49848, 18503) - -49818 | (49902, 41752),(49818, 41746) - -49810 | (49907, 30225),(49810, 30158) - -49808 | (49843, 5175),(49808, 5145) - -49805 | (49887, 24274),(49805, 24184) - -49798 | (49847, 7128),(49798, 7067) -(15 rows) - -SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound - ?column? | c -----------+------------------------------- - -100000 | (100000) - -50027 | (50027, 49230),(49951, 49214) - -49999 | (49999, 27218),(49908, 27176) - -49985 | (49985, 6436),(49927, 6338) - -49981 | (49981, 34876),(49898, 34786) - -49980 | (49980, 35004),(49937, 34963) - -49957 | (49957, 43390),(49897, 43384) - -49954 | (49954, 1340),(49905, 1294) - -49944 | (49944, 25163),(49902, 25153) - -49907 | (49907, 30225),(49810, 30158) - -49902 | (49902, 41752),(49818, 41746) - -49887 | (49887, 24274),(49805, 24184) - -49853 | (49853, 18504),(49848, 18503) - -49847 | (49847, 7128),(49798, 7067) - -49843 | (49843, 5175),(49808, 5145) -(15 rows) - -SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound - ?column? | c -----------+------------------------------- - -100000 | (0, 100000) - -49992 | (30746, 50040),(30727, 49992) - -49987 | (36311, 50073),(36258, 49987) - -49934 | (3531, 49962),(3463, 49934) - -49915 | (17954, 49975),(17865, 49915) - -49914 | (2168, 50012),(2108, 49914) - -49913 | (31287, 49923),(31236, 49913) - -49885 | (21551, 49983),(21492, 49885) - -49878 | (43925, 49912),(43888, 49878) - -49849 | (19128, 49932),(19112, 49849) - -49844 | (38266, 49852),(38233, 49844) - -49836 | (14913, 49873),(14849, 49836) - -49834 | (37595, 49849),(37581, 49834) - -49830 | (46151, 49848),(46058, 49830) - -49818 | (29261, 49910),(29247, 49818) -(15 rows) - -SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound - ?column? | c -----------+------------------------------- - -100000 | (0, 100000) - -50073 | (36311, 50073),(36258, 49987) - -50040 | (30746, 50040),(30727, 49992) - -50012 | (2168, 50012),(2108, 49914) - -49983 | (21551, 49983),(21492, 49885) - -49975 | (17954, 49975),(17865, 49915) - -49962 | (3531, 49962),(3463, 49934) - -49932 | (19128, 49932),(19112, 49849) - -49923 | (31287, 49923),(31236, 49913) - -49912 | (43925, 49912),(43888, 49878) - -49910 | (29261, 49910),(29247, 49818) - -49873 | (14913, 49873),(14849, 49836) - -49858 | (20007, 49858),(19921, 49778) - -49852 | (38266, 49852),(38233, 49844) - -49849 | (37595, 49849),(37581, 49834) -(15 rows) - --- Same queries with sequential scan (should give the same results as above) -RESET enable_seqscan; -SET enable_indexscan = OFF; -SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------------------ - (337, 455),(240, 359) | 0 - (1, 1) | 140.007142674936 - (759, 187),(662, 163) | 162 - (948, 1201),(907, 1156) | 772.000647668122 - (1444, 403),(1346, 344) | 846 -(5 rows) - -SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------ - (337, 455),(240, 359) | 0 - (1, 1) | 99 - (759, 187),(662, 163) | 162 - (948, 1201),(907, 1156) | 656 - (1444, 403),(1346, 344) | 846 -(5 rows) - -SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5; - c | dist --------------------------+------ - (337, 455),(240, 359) | 0 - (759, 187),(662, 163) | 162 - (1, 1) | 198 - (1444, 403),(1346, 344) | 846 - (369, 1457),(278, 1409) | 909 -(5 rows) - -SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound - ?column? | c -----------+--------------------------- - 0 | (0, 100000) - 1 | (1, 1) - 3 | (54, 38679),(3, 38602) - 15 | (83, 10271),(15, 10265) - 64 | (122, 46832),(64, 46762) - 92 | (167, 17214),(92, 17184) - 107 | (161, 24465),(107, 24374) - 120 | (162, 26040),(120, 25963) - 138 | (154, 4019),(138, 3990) - 175 | (259, 1850),(175, 1820) - 179 | (207, 40886),(179, 40879) - 204 | (288, 49588),(204, 49571) - 226 | (270, 32616),(226, 32607) - 235 | (318, 31489),(235, 31404) - 240 | (337, 455),(240, 359) -(15 rows) - -SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound - ?column? | c -----------+--------------------------- - 0 | (0, 100000) - 1 | (1, 1) - 54 | (54, 38679),(3, 38602) - 83 | (83, 10271),(15, 10265) - 122 | (122, 46832),(64, 46762) - 154 | (154, 4019),(138, 3990) - 161 | (161, 24465),(107, 24374) - 162 | (162, 26040),(120, 25963) - 167 | (167, 17214),(92, 17184) - 207 | (207, 40886),(179, 40879) - 259 | (259, 1850),(175, 1820) - 270 | (270, 29508),(264, 29440) - 270 | (270, 32616),(226, 32607) - 288 | (288, 49588),(204, 49571) - 318 | (318, 31489),(235, 31404) -(15 rows) - -SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound - ?column? | c -----------+--------------------------- - 0 | (100000) - 1 | (1, 1) - 6 | (30333, 50),(30273, 6) - 43 | (43301, 75),(43227, 43) - 51 | (19650, 142),(19630, 51) - 81 | (2424, 160),(2424, 81) - 108 | (3449, 171),(3354, 108) - 109 | (18037, 155),(17941, 109) - 114 | (28511, 208),(28479, 114) - 118 | (19946, 217),(19941, 118) - 139 | (16906, 191),(16816, 139) - 163 | (759, 187),(662, 163) - 181 | (22684, 266),(22656, 181) - 213 | (24423, 255),(24360, 213) - 222 | (45989, 249),(45910, 222) -(15 rows) - -SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound - ?column? | c -----------+--------------------------- - 0 | (100000) - 1 | (1, 1) - 50 | (30333, 50),(30273, 6) - 75 | (43301, 75),(43227, 43) - 142 | (19650, 142),(19630, 51) - 155 | (18037, 155),(17941, 109) - 160 | (2424, 160),(2424, 81) - 171 | (3449, 171),(3354, 108) - 187 | (759, 187),(662, 163) - 191 | (16906, 191),(16816, 139) - 208 | (28511, 208),(28479, 114) - 217 | (19946, 217),(19941, 118) - 249 | (45989, 249),(45910, 222) - 255 | (24423, 255),(24360, 213) - 266 | (22684, 266),(22656, 181) -(15 rows) - -SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound - ?column? | c -----------+------------------------------- - -100000 | (100000) - -49951 | (50027, 49230),(49951, 49214) - -49937 | (49980, 35004),(49937, 34963) - -49927 | (49985, 6436),(49927, 6338) - -49908 | (49999, 27218),(49908, 27176) - -49905 | (49954, 1340),(49905, 1294) - -49902 | (49944, 25163),(49902, 25153) - -49898 | (49981, 34876),(49898, 34786) - -49897 | (49957, 43390),(49897, 43384) - -49848 | (49853, 18504),(49848, 18503) - -49818 | (49902, 41752),(49818, 41746) - -49810 | (49907, 30225),(49810, 30158) - -49808 | (49843, 5175),(49808, 5145) - -49805 | (49887, 24274),(49805, 24184) - -49798 | (49847, 7128),(49798, 7067) -(15 rows) - -SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound - ?column? | c -----------+------------------------------- - -100000 | (100000) - -50027 | (50027, 49230),(49951, 49214) - -49999 | (49999, 27218),(49908, 27176) - -49985 | (49985, 6436),(49927, 6338) - -49981 | (49981, 34876),(49898, 34786) - -49980 | (49980, 35004),(49937, 34963) - -49957 | (49957, 43390),(49897, 43384) - -49954 | (49954, 1340),(49905, 1294) - -49944 | (49944, 25163),(49902, 25153) - -49907 | (49907, 30225),(49810, 30158) - -49902 | (49902, 41752),(49818, 41746) - -49887 | (49887, 24274),(49805, 24184) - -49853 | (49853, 18504),(49848, 18503) - -49847 | (49847, 7128),(49798, 7067) - -49843 | (49843, 5175),(49808, 5145) -(15 rows) - -SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound - ?column? | c -----------+------------------------------- - -100000 | (0, 100000) - -49992 | (30746, 50040),(30727, 49992) - -49987 | (36311, 50073),(36258, 49987) - -49934 | (3531, 49962),(3463, 49934) - -49915 | (17954, 49975),(17865, 49915) - -49914 | (2168, 50012),(2108, 49914) - -49913 | (31287, 49923),(31236, 49913) - -49885 | (21551, 49983),(21492, 49885) - -49878 | (43925, 49912),(43888, 49878) - -49849 | (19128, 49932),(19112, 49849) - -49844 | (38266, 49852),(38233, 49844) - -49836 | (14913, 49873),(14849, 49836) - -49834 | (37595, 49849),(37581, 49834) - -49830 | (46151, 49848),(46058, 49830) - -49818 | (29261, 49910),(29247, 49818) -(15 rows) - -SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound - ?column? | c -----------+------------------------------- - -100000 | (0, 100000) - -50073 | (36311, 50073),(36258, 49987) - -50040 | (30746, 50040),(30727, 49992) - -50012 | (2168, 50012),(2108, 49914) - -49983 | (21551, 49983),(21492, 49885) - -49975 | (17954, 49975),(17865, 49915) - -49962 | (3531, 49962),(3463, 49934) - -49932 | (19128, 49932),(19112, 49849) - -49923 | (31287, 49923),(31236, 49913) - -49912 | (43925, 49912),(43888, 49878) - -49910 | (29261, 49910),(29247, 49818) - -49873 | (14913, 49873),(14849, 49836) - -49858 | (20007, 49858),(19921, 49778) - -49852 | (38266, 49852),(38233, 49844) - -49849 | (37595, 49849),(37581, 49834) -(15 rows) - -RESET enable_indexscan; diff --git a/contrib/cube/expected/cube_sci.out b/contrib/cube/expected/cube_sci.out new file mode 100644 index 00000000000..488499ac8ea --- /dev/null +++ b/contrib/cube/expected/cube_sci.out @@ -0,0 +1,106 @@ +--- +--- Testing cube output in scientific notation. This was put into separate +--- test, because has platform-depending output. +--- +SELECT '1e27'::cube AS cube; + cube +--------- + (1e+27) +(1 row) + +SELECT '-1e27'::cube AS cube; + cube +---------- + (-1e+27) +(1 row) + +SELECT '1.0e27'::cube AS cube; + cube +--------- + (1e+27) +(1 row) + +SELECT '-1.0e27'::cube AS cube; + cube +---------- + (-1e+27) +(1 row) + +SELECT '1e+27'::cube AS cube; + cube +--------- + (1e+27) +(1 row) + +SELECT '-1e+27'::cube AS cube; + cube +---------- + (-1e+27) +(1 row) + +SELECT '1.0e+27'::cube AS cube; + cube +--------- + (1e+27) +(1 row) + +SELECT '-1.0e+27'::cube AS cube; + cube +---------- + (-1e+27) +(1 row) + +SELECT '1e-7'::cube AS cube; + cube +--------- + (1e-07) +(1 row) + +SELECT '-1e-7'::cube AS cube; + cube +---------- + (-1e-07) +(1 row) + +SELECT '1.0e-7'::cube AS cube; + cube +--------- + (1e-07) +(1 row) + +SELECT '-1.0e-7'::cube AS cube; + cube +---------- + (-1e-07) +(1 row) + +SELECT '1e-300'::cube AS cube; + cube +---------- + (1e-300) +(1 row) + +SELECT '-1e-300'::cube AS cube; + cube +----------- + (-1e-300) +(1 row) + +SELECT '1234567890123456'::cube AS cube; + cube +------------------------- + (1.234567890123456e+15) +(1 row) + +SELECT '+1234567890123456'::cube AS cube; + cube +------------------------- + (1.234567890123456e+15) +(1 row) + +SELECT '-1234567890123456'::cube AS cube; + cube +-------------------------- + (-1.234567890123456e+15) +(1 row) + diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql index f599e7f7c03..7f8b2e39799 100644 --- a/contrib/cube/sql/cube.sql +++ b/contrib/cube/sql/cube.sql @@ -22,26 +22,9 @@ SELECT '.1'::cube AS cube; SELECT '-.1'::cube AS cube; SELECT '1.0'::cube AS cube; SELECT '-1.0'::cube AS cube; -SELECT '1e27'::cube AS cube; -SELECT '-1e27'::cube AS cube; -SELECT '1.0e27'::cube AS cube; -SELECT '-1.0e27'::cube AS cube; -SELECT '1e+27'::cube AS cube; -SELECT '-1e+27'::cube AS cube; -SELECT '1.0e+27'::cube AS cube; -SELECT '-1.0e+27'::cube AS cube; -SELECT '1e-7'::cube AS cube; -SELECT '-1e-7'::cube AS cube; -SELECT '1.0e-7'::cube AS cube; -SELECT '-1.0e-7'::cube AS cube; -SELECT '1e-300'::cube AS cube; -SELECT '-1e-300'::cube AS cube; SELECT 'infinity'::cube AS cube; SELECT '-infinity'::cube AS cube; SELECT 'NaN'::cube AS cube; -SELECT '1234567890123456'::cube AS cube; -SELECT '+1234567890123456'::cube AS cube; -SELECT '-1234567890123456'::cube AS cube; SELECT '.1234567890123456'::cube AS cube; SELECT '+.1234567890123456'::cube AS cube; SELECT '-.1234567890123456'::cube AS cube; @@ -125,6 +108,12 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]); SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]); SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]); +-- test for limits: this should pass +SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,100))); +-- and this should fail +SELECT cube_subset(cube('(6,7,8),(6,7,8)'), array(SELECT 1 as a FROM generate_series(1,101))); + + -- -- Test point processing @@ -144,9 +133,21 @@ SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8 -- -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- - +-- create too big cube from literal select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube; select '(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)'::cube; +-- from an array +select cube(array(SELECT 0 as a FROM generate_series(1,101))); +select cube(array(SELECT 0 as a FROM generate_series(1,101)),array(SELECT 0 as a FROM generate_series(1,101))); + +-- extend cube beyond limit +-- this should work +select cube(array(SELECT 0 as a FROM generate_series(1,100))); +select cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))); +-- this should fail +select cube(cube(array(SELECT 0 as a FROM generate_series(1,100))), 0); +select cube(cube(array(SELECT 0 as a FROM generate_series(1,100)),array(SELECT 0 as a FROM generate_series(1,100))), 0, 0); + -- -- testing the operators @@ -335,10 +336,12 @@ SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args SELECT cube_size('(4,8),(15,16)'::cube); SELECT cube_size('(42,137)'::cube); --- Test of distances +-- Test of distances (euclidean distance may not be bit-exact) -- +SET extra_float_digits = 0; SELECT cube_distance('(1,1)'::cube, '(4,5)'::cube); SELECT '(1,1)'::cube <-> '(4,5)'::cube as d_e; +RESET extra_float_digits; SELECT distance_chebyshev('(1,1)'::cube, '(4,5)'::cube); SELECT '(1,1)'::cube <=> '(4,5)'::cube as d_c; SELECT distance_taxicab('(1,1)'::cube, '(4,5)'::cube); @@ -394,7 +397,9 @@ INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some c SET enable_seqscan = false; -- Test different metrics +SET extra_float_digits = 0; SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; +RESET extra_float_digits; SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5; @@ -411,7 +416,9 @@ SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upp -- Same queries with sequential scan (should give the same results as above) RESET enable_seqscan; SET enable_indexscan = OFF; +SET extra_float_digits = 0; SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5; +RESET extra_float_digits; SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5; SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5; SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound diff --git a/contrib/cube/sql/cube_sci.sql b/contrib/cube/sql/cube_sci.sql new file mode 100644 index 00000000000..35a540779a8 --- /dev/null +++ b/contrib/cube/sql/cube_sci.sql @@ -0,0 +1,22 @@ +--- +--- Testing cube output in scientific notation. This was put into separate +--- test, because has platform-depending output. +--- + +SELECT '1e27'::cube AS cube; +SELECT '-1e27'::cube AS cube; +SELECT '1.0e27'::cube AS cube; +SELECT '-1.0e27'::cube AS cube; +SELECT '1e+27'::cube AS cube; +SELECT '-1e+27'::cube AS cube; +SELECT '1.0e+27'::cube AS cube; +SELECT '-1.0e+27'::cube AS cube; +SELECT '1e-7'::cube AS cube; +SELECT '-1e-7'::cube AS cube; +SELECT '1.0e-7'::cube AS cube; +SELECT '-1.0e-7'::cube AS cube; +SELECT '1e-300'::cube AS cube; +SELECT '-1e-300'::cube AS cube; +SELECT '1234567890123456'::cube AS cube; +SELECT '+1234567890123456'::cube AS cube; +SELECT '-1234567890123456'::cube AS cube; diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index c6460688486..e432457e2d5 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -9,7 +9,7 @@ * Shridhar Daithankar * * contrib/dblink/dblink.c - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * * Permission to use, copy, modify, and distribute this software and its @@ -37,7 +37,9 @@ #include "libpq-fe.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/reloptions.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_foreign_data_wrapper.h" @@ -58,7 +60,6 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" #include "utils/varlena.h" PG_MODULE_MAGIC; @@ -88,12 +89,12 @@ typedef struct storeInfo static Datum dblink_record_internal(FunctionCallInfo fcinfo, bool is_async); static void prepTuplestoreResult(FunctionCallInfo fcinfo); static void materializeResult(FunctionCallInfo fcinfo, PGconn *conn, - PGresult *res); + PGresult *res); static void materializeQueryResult(FunctionCallInfo fcinfo, - PGconn *conn, - const char *conname, - const char *sql, - bool fail); + PGconn *conn, + const char *conname, + const char *sql, + bool fail); static PGresult *storeQueryResult(volatile storeInfo *sinfo, PGconn *conn, const char *sql); static void storeRow(volatile storeInfo *sinfo, PGresult *res, bool first); static remoteConn *getConnectionByName(const char *name); @@ -113,14 +114,14 @@ static char *generate_relation_name(Relation rel); static void dblink_connstr_check(const char *connstr); static void dblink_security_check(PGconn *conn, remoteConn *rconn); static void dblink_res_error(PGconn *conn, const char *conname, PGresult *res, - bool fail, const char *fmt,...) pg_attribute_printf(5, 6); + bool fail, const char *fmt,...) pg_attribute_printf(5, 6); static char *get_connect_string(const char *servername); static char *escape_param_str(const char *from); static void validate_pkattnums(Relation rel, - int2vector *pkattnums_arg, int32 pknumatts_arg, - int **pkattnums, int *pknumatts); + int2vector *pkattnums_arg, int32 pknumatts_arg, + int **pkattnums, int *pknumatts); static bool is_valid_dblink_option(const PQconninfoOption *options, - const char *option, Oid context); + const char *option, Oid context); static int applyRemoteGucs(PGconn *conn); static void restoreLocalGucs(int nestlevel); @@ -849,7 +850,7 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, PGresult *res) * need a tuple descriptor representing one TEXT column to return * the command status string as our result tuple */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status", TEXTOID, -1, 0); ntuples = 1; @@ -981,13 +982,11 @@ materializeQueryResult(FunctionCallInfo fcinfo, { ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; PGresult *volatile res = NULL; - volatile storeInfo sinfo; + volatile storeInfo sinfo = {0}; /* prepTuplestoreResult must have been called previously */ Assert(rsinfo->returnMode == SFRM_Materialize); - /* initialize storeInfo to empty */ - memset((void *) &sinfo, 0, sizeof(sinfo)); sinfo.fcinfo = fcinfo; PG_TRY(); @@ -1032,7 +1031,7 @@ materializeQueryResult(FunctionCallInfo fcinfo, * need a tuple descriptor representing one TEXT column to return * the command status string as our result tuple */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status", TEXTOID, -1, 0); attinmeta = TupleDescGetAttInMetadata(tupdesc); @@ -1526,7 +1525,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS) /* * need a tuple descriptor representing one INT and one TEXT column */ - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "position", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "colname", @@ -1904,7 +1903,7 @@ dblink_get_notify(PG_FUNCTION_ARGS) per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; oldcontext = MemoryContextSwitchTo(per_query_ctx); - tupdesc = CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS, false); + tupdesc = CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "notify_name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "be_pid", @@ -2048,7 +2047,7 @@ get_pkey_attnames(Relation rel, int16 *indnkeyatts) tupdesc = rel->rd_att; /* Prepare to scan pg_index for entries having indrelid = this rel. */ - indexRelation = heap_open(IndexRelationId, AccessShareLock); + indexRelation = table_open(IndexRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_index_indrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -2077,7 +2076,7 @@ get_pkey_attnames(Relation rel, int16 *indnkeyatts) } systable_endscan(scan); - heap_close(indexRelation, AccessShareLock); + table_close(indexRelation, AccessShareLock); return result; } @@ -2501,7 +2500,7 @@ get_rel_from_relname(text *relname_text, LOCKMODE lockmode, AclMode aclmode) AclResult aclresult; relvar = makeRangeVarFromNameList(textToQualifiedNameList(relname_text)); - rel = heap_openrv(relvar, lockmode); + rel = table_openrv(relvar, lockmode); aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), aclmode); diff --git a/contrib/dblink/expected/dblink.out b/contrib/dblink/expected/dblink.out index dfd49b937e8..6ceabb453c0 100644 --- a/contrib/dblink/expected/dblink.out +++ b/contrib/dblink/expected/dblink.out @@ -1154,7 +1154,7 @@ FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int); SELECT * FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int); -ERROR: invalid input syntax for integer: "not an int" +ERROR: invalid input syntax for type integer: "not an int" -- Make sure that the local settings have retained their values in spite -- of shenanigans on the connection. SHOW datestyle; diff --git a/contrib/dict_int/dict_int.c b/contrib/dict_int/dict_int.c index 56ede37089e..628b9769c32 100644 --- a/contrib/dict_int/dict_int.c +++ b/contrib/dict_int/dict_int.c @@ -3,7 +3,7 @@ * dict_int.c * Text search dictionary for integers * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/dict_int/dict_int.c diff --git a/contrib/dict_xsyn/dict_xsyn.c b/contrib/dict_xsyn/dict_xsyn.c index a79ece240ce..509e14aee07 100644 --- a/contrib/dict_xsyn/dict_xsyn.c +++ b/contrib/dict_xsyn/dict_xsyn.c @@ -3,7 +3,7 @@ * dict_xsyn.c * Extended synonym dictionary * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/dict_xsyn/dict_xsyn.c diff --git a/contrib/earthdistance/expected/earthdistance.out b/contrib/earthdistance/expected/earthdistance.out index 89022491cb6..26a843c3faa 100644 --- a/contrib/earthdistance/expected/earthdistance.out +++ b/contrib/earthdistance/expected/earthdistance.out @@ -882,11 +882,12 @@ SELECT earth_box(ll_to_earth(90,180), -- -- Test the recommended constraints. -- -SELECT is_point(ll_to_earth(0,0)); -ERROR: function is_point(earth) does not exist -LINE 1: SELECT is_point(ll_to_earth(0,0)); - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT cube_is_point(ll_to_earth(0,0)); + cube_is_point +--------------- + t +(1 row) + SELECT cube_dim(ll_to_earth(0,0)) <= 3; ?column? ---------- @@ -900,11 +901,12 @@ SELECT abs(cube_distance(ll_to_earth(0,0), '(0)'::cube) / earth() - 1) < t (1 row) -SELECT is_point(ll_to_earth(30,60)); -ERROR: function is_point(earth) does not exist -LINE 1: SELECT is_point(ll_to_earth(30,60)); - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT cube_is_point(ll_to_earth(30,60)); + cube_is_point +--------------- + t +(1 row) + SELECT cube_dim(ll_to_earth(30,60)) <= 3; ?column? ---------- @@ -918,11 +920,12 @@ SELECT abs(cube_distance(ll_to_earth(30,60), '(0)'::cube) / earth() - 1) < t (1 row) -SELECT is_point(ll_to_earth(60,90)); -ERROR: function is_point(earth) does not exist -LINE 1: SELECT is_point(ll_to_earth(60,90)); - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT cube_is_point(ll_to_earth(60,90)); + cube_is_point +--------------- + t +(1 row) + SELECT cube_dim(ll_to_earth(60,90)) <= 3; ?column? ---------- @@ -936,11 +939,12 @@ SELECT abs(cube_distance(ll_to_earth(60,90), '(0)'::cube) / earth() - 1) < t (1 row) -SELECT is_point(ll_to_earth(-30,-90)); -ERROR: function is_point(earth) does not exist -LINE 1: SELECT is_point(ll_to_earth(-30,-90)); - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. +SELECT cube_is_point(ll_to_earth(-30,-90)); + cube_is_point +--------------- + t +(1 row) + SELECT cube_dim(ll_to_earth(-30,-90)) <= 3; ?column? ---------- @@ -985,7 +989,7 @@ HINT: You can drop extension cube instead. create table foo (f1 cube, f2 int); drop extension cube; -- fail, foo.f1 requires it ERROR: cannot drop extension cube because other objects depend on it -DETAIL: table foo column f1 depends on type cube +DETAIL: column f1 of table foo depends on type cube HINT: Use DROP ... CASCADE to drop the dependent objects too. drop table foo; drop extension cube; @@ -1039,15 +1043,15 @@ create extension cube with schema c; create table foo (f1 c.cube, f2 int); drop extension cube; -- fail, foo.f1 requires it ERROR: cannot drop extension cube because other objects depend on it -DETAIL: table foo column f1 depends on type c.cube +DETAIL: column f1 of table foo depends on type c.cube HINT: Use DROP ... CASCADE to drop the dependent objects too. drop schema c; -- fail, cube requires it ERROR: cannot drop schema c because other objects depend on it DETAIL: extension cube depends on schema c -table foo column f1 depends on type c.cube +column f1 of table foo depends on type c.cube HINT: Use DROP ... CASCADE to drop the dependent objects too. drop extension cube cascade; -NOTICE: drop cascades to table foo column f1 +NOTICE: drop cascades to column f1 of table foo \d foo Table "public.foo" Column | Type | Collation | Nullable | Default diff --git a/contrib/earthdistance/sql/earthdistance.sql b/contrib/earthdistance/sql/earthdistance.sql index 860450276f6..41455612175 100644 --- a/contrib/earthdistance/sql/earthdistance.sql +++ b/contrib/earthdistance/sql/earthdistance.sql @@ -282,19 +282,19 @@ SELECT earth_box(ll_to_earth(90,180), -- Test the recommended constraints. -- -SELECT is_point(ll_to_earth(0,0)); +SELECT cube_is_point(ll_to_earth(0,0)); SELECT cube_dim(ll_to_earth(0,0)) <= 3; SELECT abs(cube_distance(ll_to_earth(0,0), '(0)'::cube) / earth() - 1) < '10e-12'::float8; -SELECT is_point(ll_to_earth(30,60)); +SELECT cube_is_point(ll_to_earth(30,60)); SELECT cube_dim(ll_to_earth(30,60)) <= 3; SELECT abs(cube_distance(ll_to_earth(30,60), '(0)'::cube) / earth() - 1) < '10e-12'::float8; -SELECT is_point(ll_to_earth(60,90)); +SELECT cube_is_point(ll_to_earth(60,90)); SELECT cube_dim(ll_to_earth(60,90)) <= 3; SELECT abs(cube_distance(ll_to_earth(60,90), '(0)'::cube) / earth() - 1) < '10e-12'::float8; -SELECT is_point(ll_to_earth(-30,-90)); +SELECT cube_is_point(ll_to_earth(-30,-90)); SELECT cube_dim(ll_to_earth(-30,-90)) <= 3; SELECT abs(cube_distance(ll_to_earth(-30,-90), '(0)'::cube) / earth() - 1) < '10e-12'::float8; diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c index 2cf09aecf6e..549821ca84c 100644 --- a/contrib/file_fdw/file_fdw.c +++ b/contrib/file_fdw/file_fdw.c @@ -3,7 +3,7 @@ * file_fdw.c * foreign-data wrapper for server-side flat files (or programs). * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/file_fdw/file_fdw.c @@ -18,6 +18,7 @@ #include "access/htup_details.h" #include "access/reloptions.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/pg_authid.h" #include "catalog/pg_foreign_table.h" #include "commands/copy.h" @@ -28,11 +29,10 @@ #include "foreign/foreign.h" #include "miscadmin.h" #include "nodes/makefuncs.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/planmain.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" #include "utils/memutils.h" #include "utils/rel.h" #include "utils/sampling.h" @@ -117,49 +117,49 @@ PG_FUNCTION_INFO_V1(file_fdw_validator); * FDW callback routines */ static void fileGetForeignRelSize(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); + RelOptInfo *baserel, + Oid foreigntableid); static void fileGetForeignPaths(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); + RelOptInfo *baserel, + Oid foreigntableid); static ForeignScan *fileGetForeignPlan(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid, - ForeignPath *best_path, - List *tlist, - List *scan_clauses, - Plan *outer_plan); + RelOptInfo *baserel, + Oid foreigntableid, + ForeignPath *best_path, + List *tlist, + List *scan_clauses, + Plan *outer_plan); static void fileExplainForeignScan(ForeignScanState *node, ExplainState *es); static void fileBeginForeignScan(ForeignScanState *node, int eflags); static TupleTableSlot *fileIterateForeignScan(ForeignScanState *node); static void fileReScanForeignScan(ForeignScanState *node); static void fileEndForeignScan(ForeignScanState *node); static bool fileAnalyzeForeignTable(Relation relation, - AcquireSampleRowsFunc *func, - BlockNumber *totalpages); + AcquireSampleRowsFunc *func, + BlockNumber *totalpages); static bool fileIsForeignScanParallelSafe(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); /* * Helper functions */ static bool is_valid_option(const char *option, Oid context); static void fileGetOptions(Oid foreigntableid, - char **filename, - bool *is_program, - List **other_options); + char **filename, + bool *is_program, + List **other_options); static List *get_file_fdw_attribute_options(Oid relid); static bool check_selective_binary_conversion(RelOptInfo *baserel, - Oid foreigntableid, - List **columns); + Oid foreigntableid, + List **columns); static void estimate_size(PlannerInfo *root, RelOptInfo *baserel, - FileFdwPlanState *fdw_private); + FileFdwPlanState *fdw_private); static void estimate_costs(PlannerInfo *root, RelOptInfo *baserel, - FileFdwPlanState *fdw_private, - Cost *startup_cost, Cost *total_cost); -static int file_acquire_sample_rows(Relation onerel, int elevel, - HeapTuple *rows, int targrows, - double *totalrows, double *totaldeadrows); + FileFdwPlanState *fdw_private, + Cost *startup_cost, Cost *total_cost); +static int file_acquire_sample_rows(Relation onerel, int elevel, + HeapTuple *rows, int targrows, + double *totalrows, double *totaldeadrows); /* @@ -360,8 +360,7 @@ fileGetOptions(Oid foreigntableid, ForeignServer *server; ForeignDataWrapper *wrapper; List *options; - ListCell *lc, - *prev; + ListCell *lc; /* * Extract options from FDW objects. We ignore user mappings because @@ -387,7 +386,6 @@ fileGetOptions(Oid foreigntableid, */ *filename = NULL; *is_program = false; - prev = NULL; foreach(lc, options) { DefElem *def = (DefElem *) lfirst(lc); @@ -395,17 +393,16 @@ fileGetOptions(Oid foreigntableid, if (strcmp(def->defname, "filename") == 0) { *filename = defGetString(def); - options = list_delete_cell(options, lc, prev); + options = foreach_delete_current(options, lc); break; } else if (strcmp(def->defname, "program") == 0) { *filename = defGetString(def); *is_program = true; - options = list_delete_cell(options, lc, prev); + options = foreach_delete_current(options, lc); break; } - prev = lc; } /* @@ -438,7 +435,7 @@ get_file_fdw_attribute_options(Oid relid) List *options = NIL; - rel = heap_open(relid, AccessShareLock); + rel = table_open(relid, AccessShareLock); tupleDesc = RelationGetDescr(rel); natts = tupleDesc->natts; @@ -480,7 +477,7 @@ get_file_fdw_attribute_options(Oid relid) } } - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* * Return DefElem only when some column(s) have force_not_null / @@ -556,6 +553,10 @@ fileGetForeignPaths(PlannerInfo *root, * Create a ForeignPath node and add it as only possible path. We use the * fdw_private list of the path to carry the convert_selectively option; * it will be propagated into the fdw_private list of the Plan node. + * + * We don't support pushing join clauses into the quals of this path, but + * it could still have required parameterization due to LATERAL refs in + * its tlist. */ add_path(baserel, (Path *) create_foreignscan_path(root, baserel, @@ -564,7 +565,7 @@ fileGetForeignPaths(PlannerInfo *root, startup_cost, total_cost, NIL, /* no pathkeys */ - NULL, /* no outer rel either */ + baserel->lateral_relids, NULL, /* no extra plan */ coptions)); @@ -727,8 +728,7 @@ fileIterateForeignScan(ForeignScanState *node) */ ExecClearTuple(slot); found = NextCopyFrom(festate->cstate, NULL, - slot->tts_values, slot->tts_isnull, - NULL); + slot->tts_values, slot->tts_isnull); if (found) ExecStoreVirtualTuple(slot); @@ -892,7 +892,7 @@ check_selective_binary_conversion(RelOptInfo *baserel, } /* Convert attribute numbers to column names. */ - rel = heap_open(foreigntableid, AccessShareLock); + rel = table_open(foreigntableid, AccessShareLock); tupleDesc = RelationGetDescr(rel); while ((attnum = bms_first_member(attrs_used)) >= 0) @@ -919,6 +919,13 @@ check_selective_binary_conversion(RelOptInfo *baserel, /* Skip dropped attributes (probably shouldn't see any here). */ if (attr->attisdropped) continue; + + /* + * Skip generated columns (COPY won't accept them in the column + * list) + */ + if (attr->attgenerated) + continue; *columns = lappend(*columns, makeString(pstrdup(attname))); } } @@ -934,7 +941,7 @@ check_selective_binary_conversion(RelOptInfo *baserel, numattrs++; } - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* If there's a whole-row reference, fail: we need all the columns. */ if (has_wholerow) @@ -1148,7 +1155,7 @@ file_acquire_sample_rows(Relation onerel, int elevel, MemoryContextReset(tupcontext); MemoryContextSwitchTo(tupcontext); - found = NextCopyFrom(cstate, NULL, values, nulls, NULL); + found = NextCopyFrom(cstate, NULL, values, nulls); MemoryContextSwitchTo(oldcontext); diff --git a/contrib/file_fdw/input/file_fdw.source b/contrib/file_fdw/input/file_fdw.source index a5e79a4549a..45b728eeb3d 100644 --- a/contrib/file_fdw/input/file_fdw.source +++ b/contrib/file_fdw/input/file_fdw.source @@ -189,6 +189,12 @@ SELECT tableoid::regclass, * FROM p1; SELECT tableoid::regclass, * FROM p2; DROP TABLE pt; +-- generated column tests +CREATE FOREIGN TABLE gft1 (a int, b text, c text GENERATED ALWAYS AS ('foo') STORED) SERVER file_server +OPTIONS (format 'csv', filename '@abs_srcdir@/data/list1.csv', delimiter ','); +SELECT a, c FROM gft1; +DROP FOREIGN TABLE gft1; + -- privilege tests SET ROLE regress_file_fdw_superuser; SELECT * FROM agg_text ORDER BY a; diff --git a/contrib/file_fdw/output/file_fdw.source b/contrib/file_fdw/output/file_fdw.source index 853c9f9b28b..52b4d5f1df7 100644 --- a/contrib/file_fdw/output/file_fdw.source +++ b/contrib/file_fdw/output/file_fdw.source @@ -375,6 +375,17 @@ SELECT tableoid::regclass, * FROM p2; (3 rows) DROP TABLE pt; +-- generated column tests +CREATE FOREIGN TABLE gft1 (a int, b text, c text GENERATED ALWAYS AS ('foo') STORED) SERVER file_server +OPTIONS (format 'csv', filename '@abs_srcdir@/data/list1.csv', delimiter ','); +SELECT a, c FROM gft1; + a | c +---+-------- + 1 | _null_ + 1 | _null_ +(2 rows) + +DROP FOREIGN TABLE gft1; -- privilege tests SET ROLE regress_file_fdw_superuser; SELECT * FROM agg_text ORDER BY a; diff --git a/contrib/fuzzystrmatch/dmetaphone.c b/contrib/fuzzystrmatch/dmetaphone.c index 16e4c66167b..f2f16bc883a 100644 --- a/contrib/fuzzystrmatch/dmetaphone.c +++ b/contrib/fuzzystrmatch/dmetaphone.c @@ -52,7 +52,7 @@ /***************************** COPYRIGHT NOTICES *********************** Most of this code is directly from the Text::DoubleMetaphone perl module -version 0.05 available from http://www.cpan.org. +version 0.05 available from https://www.cpan.org/. It bears this copyright notice: @@ -191,7 +191,7 @@ dmetaphone_alt(PG_FUNCTION_ARGS) (v = (t*)repalloc((v),((n)*sizeof(t)))) /* - * Don't do pfree - it seems to cause a segv sometimes - which might have just + * Don't do pfree - it seems to cause a SIGSEGV sometimes - which might have just * been caused by reloading the module in development. * So we rely on context cleanup - Tom Lane says pfree shouldn't be necessary * in a case like this. diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.c b/contrib/fuzzystrmatch/fuzzystrmatch.c index 05774658dc8..b8992f7c3cb 100644 --- a/contrib/fuzzystrmatch/fuzzystrmatch.c +++ b/contrib/fuzzystrmatch/fuzzystrmatch.c @@ -6,7 +6,7 @@ * Joe Conway * * contrib/fuzzystrmatch/fuzzystrmatch.c - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * * metaphone() diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile index ab7fef39793..b29d02b1372 100644 --- a/contrib/hstore/Makefile +++ b/contrib/hstore/Makefile @@ -5,12 +5,16 @@ OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \ $(WIN32RES) EXTENSION = hstore -DATA = hstore--1.4.sql hstore--1.4--1.5.sql \ +DATA = hstore--1.4.sql \ + hstore--1.5--1.6.sql \ + hstore--1.4--1.5.sql \ hstore--1.3--1.4.sql hstore--1.2--1.3.sql \ hstore--1.1--1.2.sql hstore--1.0--1.1.sql \ hstore--unpackaged--1.0.sql PGFILEDESC = "hstore - key/value pair data type" +HEADERS = hstore.h + REGRESS = hstore ifdef USE_PGXS diff --git a/contrib/hstore/expected/hstore.out b/contrib/hstore/expected/hstore.out index f0d421602d5..4f1db01b3eb 100644 --- a/contrib/hstore/expected/hstore.out +++ b/contrib/hstore/expected/hstore.out @@ -1515,3 +1515,15 @@ select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_jso {"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}] (1 row) +-- Check the hstore_hash() and hstore_hash_extended() function explicitly. +SELECT v as value, hstore_hash(v)::bit(32) as standard, + hstore_hash_extended(v, 0)::bit(32) as extended0, + hstore_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'), + ('e => 012345'), ('g => 2.345e+4')) x(v) +WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32) + OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32); + value | standard | extended0 | extended1 +-------+----------+-----------+----------- +(0 rows) + diff --git a/contrib/hstore/hstore--1.5--1.6.sql b/contrib/hstore/hstore--1.5--1.6.sql new file mode 100644 index 00000000000..c5a2bae02ff --- /dev/null +++ b/contrib/hstore/hstore--1.5--1.6.sql @@ -0,0 +1,12 @@ +/* contrib/hstore/hstore--1.5--1.6.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION hstore UPDATE TO '1.6'" to load this file. \quit + +CREATE FUNCTION hstore_hash_extended(hstore, int8) +RETURNS int8 +AS 'MODULE_PATHNAME','hstore_hash_extended' +LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; + +ALTER OPERATOR FAMILY hash_hstore_ops USING hash ADD + FUNCTION 2 hstore_hash_extended(hstore, int8); diff --git a/contrib/hstore/hstore.control b/contrib/hstore/hstore.control index 8a719475b82..93688cdd83c 100644 --- a/contrib/hstore/hstore.control +++ b/contrib/hstore/hstore.control @@ -1,5 +1,5 @@ # hstore extension comment = 'data type for storing sets of (key, value) pairs' -default_version = '1.5' +default_version = '1.6' module_pathname = '$libdir/hstore' relocatable = true diff --git a/contrib/hstore/hstore_compat.c b/contrib/hstore/hstore_compat.c index b95ce9b4aaa..1d4e7484e4d 100644 --- a/contrib/hstore/hstore_compat.c +++ b/contrib/hstore/hstore_compat.c @@ -238,34 +238,35 @@ hstoreUpgrade(Datum orig) HStore *hs = (HStore *) PG_DETOAST_DATUM(orig); int valid_new; int valid_old; - bool writable; /* Return immediately if no conversion needed */ - if ((hs->size_ & HS_FLAG_NEWVERSION) || - hs->size_ == 0 || + if (hs->size_ & HS_FLAG_NEWVERSION) + return hs; + + /* Do we have a writable copy? If not, make one. */ + if ((void *) hs == (void *) DatumGetPointer(orig)) + hs = (HStore *) PG_DETOAST_DATUM_COPY(orig); + + if (hs->size_ == 0 || (VARSIZE(hs) < 32768 && HSE_ISFIRST((ARRPTR(hs)[0])))) + { + HS_SETCOUNT(hs, HS_COUNT(hs)); + HS_FIXSIZE(hs, HS_COUNT(hs)); return hs; + } valid_new = hstoreValidNewFormat(hs); valid_old = hstoreValidOldFormat(hs); - /* Do we have a writable copy? */ - writable = ((void *) hs != (void *) DatumGetPointer(orig)); if (!valid_old || hs->size_ == 0) { if (valid_new) { /* - * force the "new version" flag and the correct varlena length, - * but only if we have a writable copy already (which we almost - * always will, since short new-format values won't come through - * here) + * force the "new version" flag and the correct varlena length. */ - if (writable) - { - HS_SETCOUNT(hs, HS_COUNT(hs)); - HS_FIXSIZE(hs, HS_COUNT(hs)); - } + HS_SETCOUNT(hs, HS_COUNT(hs)); + HS_FIXSIZE(hs, HS_COUNT(hs)); return hs; } else @@ -302,15 +303,10 @@ hstoreUpgrade(Datum orig) elog(WARNING, "ambiguous hstore value resolved as hstore-new"); /* - * force the "new version" flag and the correct varlena length, but - * only if we have a writable copy already (which we almost always - * will, since short new-format values won't come through here) + * force the "new version" flag and the correct varlena length. */ - if (writable) - { - HS_SETCOUNT(hs, HS_COUNT(hs)); - HS_FIXSIZE(hs, HS_COUNT(hs)); - } + HS_SETCOUNT(hs, HS_COUNT(hs)); + HS_FIXSIZE(hs, HS_COUNT(hs)); return hs; #else elog(WARNING, "ambiguous hstore value resolved as hstore-old"); @@ -318,13 +314,8 @@ hstoreUpgrade(Datum orig) } /* - * must have an old-style value. Overwrite it in place as a new-style one, - * making sure we have a writable copy first. + * must have an old-style value. Overwrite it in place as a new-style one. */ - - if (!writable) - hs = (HStore *) PG_DETOAST_DATUM_COPY(orig); - { int count = hs->size_; HEntry *new_entries = ARRPTR(hs); diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c index 6d24d2f468a..6a885f2926f 100644 --- a/contrib/hstore/hstore_gist.c +++ b/contrib/hstore/hstore_gist.c @@ -19,9 +19,6 @@ typedef char BITVEC[SIGLEN]; typedef char *BITVECP; -#define SIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) ) - - #define LOOPBYTE \ for(i=0;i1, b => t, c => null, d=> 12 ('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4'); select json_agg(q) from test_json_agg q; select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q; + +-- Check the hstore_hash() and hstore_hash_extended() function explicitly. +SELECT v as value, hstore_hash(v)::bit(32) as standard, + hstore_hash_extended(v, 0)::bit(32) as extended0, + hstore_hash_extended(v, 1)::bit(32) as extended1 +FROM (VALUES (NULL::hstore), (''), ('"a key" =>1'), ('c => null'), + ('e => 012345'), ('g => 2.345e+4')) x(v) +WHERE hstore_hash(v)::bit(32) != hstore_hash_extended(v, 0)::bit(32) + OR hstore_hash(v)::bit(32) = hstore_hash_extended(v, 1)::bit(32); diff --git a/contrib/hstore_plperl/Makefile b/contrib/hstore_plperl/Makefile index f63cba27456..5076e21e0ee 100644 --- a/contrib/hstore_plperl/Makefile +++ b/contrib/hstore_plperl/Makefile @@ -4,7 +4,6 @@ MODULE_big = hstore_plperl OBJS = hstore_plperl.o $(WIN32RES) PGFILEDESC = "hstore_plperl - hstore transform for plperl" -PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plperl -I$(top_srcdir)/contrib/hstore EXTENSION = hstore_plperl hstore_plperlu DATA = hstore_plperl--1.0.sql hstore_plperlu--1.0.sql @@ -13,10 +12,12 @@ REGRESS = hstore_plperl hstore_plperlu create_transform EXTRA_INSTALL = contrib/hstore ifdef USE_PGXS +PG_CPPFLAGS = -I$(includedir_server)/extension PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else +PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plperl -I$(top_srcdir)/contrib subdir = contrib/hstore_plperl top_builddir = ../.. include $(top_builddir)/src/Makefile.global @@ -34,8 +35,5 @@ rpathdir = $(perl_archlibexp)/CORE SHLIB_LINK += $(perl_embed_ldflags) endif -# As with plperl we need to make sure that the CORE directory is included -# last, probably because it sometimes contains some header files with names -# that clash with some of ours, or with some that we include, notably on -# Windows. -override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) -I$(perl_archlibexp)/CORE +# As with plperl we need to include the perl_includespec directory last. +override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec) diff --git a/contrib/hstore_plperl/expected/hstore_plperl.out b/contrib/hstore_plperl/expected/hstore_plperl.out index 25fc506c23f..1ab09a94cda 100644 --- a/contrib/hstore_plperl/expected/hstore_plperl.out +++ b/contrib/hstore_plperl/expected/hstore_plperl.out @@ -41,6 +41,25 @@ SELECT test2arr(); {"\"a\"=>\"1\", \"b\"=>\"boo\", \"c\"=>NULL","\"d\"=>\"2\""} (1 row) +-- check error cases +CREATE OR REPLACE FUNCTION test2() RETURNS hstore +LANGUAGE plperl +TRANSFORM FOR TYPE hstore +AS $$ +return 42; +$$; +SELECT test2(); +ERROR: cannot transform non-hash Perl value to hstore +CONTEXT: PL/Perl function "test2" +CREATE OR REPLACE FUNCTION test2() RETURNS hstore +LANGUAGE plperl +TRANSFORM FOR TYPE hstore +AS $$ +return [1, 2]; +$$; +SELECT test2(); +ERROR: cannot transform non-hash Perl value to hstore +CONTEXT: PL/Perl function "test2" DROP FUNCTION test2(); DROP FUNCTION test2arr(); DROP EXTENSION hstore_plperl; diff --git a/contrib/hstore_plperl/hstore_plperl.c b/contrib/hstore_plperl/hstore_plperl.c index 6bc3bb37fc3..1316b0500be 100644 --- a/contrib/hstore_plperl/hstore_plperl.c +++ b/contrib/hstore_plperl/hstore_plperl.c @@ -1,11 +1,9 @@ #include "postgres.h" -#undef _ - #include "fmgr.h" +#include "hstore/hstore.h" #include "plperl.h" #include "plperl_helpers.h" -#include "hstore.h" PG_MODULE_MAGIC; @@ -101,7 +99,8 @@ Datum plperl_to_hstore(PG_FUNCTION_ARGS) { dTHX; - HV *hv = (HV *) SvRV((SV *) PG_GETARG_POINTER(0)); + SV *in = (SV *) PG_GETARG_POINTER(0); + HV *hv; HE *he; int32 buflen; int32 i; @@ -109,6 +108,17 @@ plperl_to_hstore(PG_FUNCTION_ARGS) HStore *out; Pairs *pairs; + /* Dereference references recursively. */ + while (SvROK(in)) + in = SvRV(in); + + /* Now we must have a hash. */ + if (SvTYPE(in) != SVt_PVHV) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errmsg("cannot transform non-hash Perl value to hstore")))); + hv = (HV *) in; + pcount = hv_iterinit(hv); pairs = palloc(pcount * sizeof(Pairs)); diff --git a/contrib/hstore_plperl/sql/hstore_plperl.sql b/contrib/hstore_plperl/sql/hstore_plperl.sql index 9398aedfbbd..ad1db7eae17 100644 --- a/contrib/hstore_plperl/sql/hstore_plperl.sql +++ b/contrib/hstore_plperl/sql/hstore_plperl.sql @@ -31,6 +31,25 @@ $$; SELECT test2arr(); +-- check error cases +CREATE OR REPLACE FUNCTION test2() RETURNS hstore +LANGUAGE plperl +TRANSFORM FOR TYPE hstore +AS $$ +return 42; +$$; + +SELECT test2(); + +CREATE OR REPLACE FUNCTION test2() RETURNS hstore +LANGUAGE plperl +TRANSFORM FOR TYPE hstore +AS $$ +return [1, 2]; +$$; + +SELECT test2(); + DROP FUNCTION test2(); DROP FUNCTION test2arr(); diff --git a/contrib/hstore_plpython/Makefile b/contrib/hstore_plpython/Makefile index b81735ab910..6877e7a072c 100644 --- a/contrib/hstore_plpython/Makefile +++ b/contrib/hstore_plpython/Makefile @@ -4,19 +4,21 @@ MODULE_big = hstore_plpython$(python_majorversion) OBJS = hstore_plpython.o $(WIN32RES) PGFILEDESC = "hstore_plpython - hstore transform for plpython" -PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plpython $(python_includespec) -I$(top_srcdir)/contrib/hstore -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"' - EXTENSION = hstore_plpythonu hstore_plpython2u hstore_plpython3u DATA = hstore_plpythonu--1.0.sql hstore_plpython2u--1.0.sql hstore_plpython3u--1.0.sql REGRESS = hstore_plpython REGRESS_PLPYTHON3_MANGLE := $(REGRESS) +PG_CPPFLAGS = $(python_includespec) -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"' + ifdef USE_PGXS +PG_CPPFLAGS += -I$(includedir_server)/extension PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else +PG_CPPFLAGS += -I$(top_srcdir)/src/pl/plpython -I$(top_srcdir)/contrib subdir = contrib/hstore_plpython top_builddir = ../.. include $(top_builddir)/src/Makefile.global diff --git a/contrib/hstore_plpython/hstore_plpython.c b/contrib/hstore_plpython/hstore_plpython.c index 218e6612b14..93705f0d54c 100644 --- a/contrib/hstore_plpython/hstore_plpython.c +++ b/contrib/hstore_plpython/hstore_plpython.c @@ -3,7 +3,7 @@ #include "fmgr.h" #include "plpython.h" #include "plpy_typeio.h" -#include "hstore.h" +#include "hstore/hstore.h" PG_MODULE_MAGIC; @@ -128,9 +128,9 @@ Datum plpython_to_hstore(PG_FUNCTION_ARGS) { PyObject *dict; - volatile PyObject *items_v = NULL; - int32 pcount; - HStore *out; + PyObject *volatile items; + Py_ssize_t pcount; + HStore *volatile out; dict = (PyObject *) PG_GETARG_POINTER(0); if (!PyMapping_Check(dict)) @@ -139,14 +139,13 @@ plpython_to_hstore(PG_FUNCTION_ARGS) errmsg("not a Python mapping"))); pcount = PyMapping_Size(dict); - items_v = PyMapping_Items(dict); + items = PyMapping_Items(dict); PG_TRY(); { int32 buflen; - int32 i; + Py_ssize_t i; Pairs *pairs; - PyObject *items = (PyObject *) items_v; pairs = palloc(pcount * sizeof(*pairs)); @@ -177,17 +176,18 @@ plpython_to_hstore(PG_FUNCTION_ARGS) pairs[i].isnull = false; } } - Py_DECREF(items_v); pcount = hstoreUniquePairs(pairs, pcount, &buflen); out = hstorePairs(pairs, pcount, buflen); } PG_CATCH(); { - Py_DECREF(items_v); + Py_DECREF(items); PG_RE_THROW(); } PG_END_TRY(); + Py_DECREF(items); + PG_RETURN_POINTER(out); } diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index b689eb7dedf..f03fdf9add9 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -85,12 +85,6 @@ typedef struct #define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) ) -/* - * types for functions - */ -typedef ArrayType *(*formarray) (ArrayType *, ArrayType *); -typedef void (*formfloat) (ArrayType *, float *); - /* * useful functions */ diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c index 911d18023b9..e5a8011daf8 100644 --- a/contrib/intarray/_int_gist.c +++ b/contrib/intarray/_int_gist.c @@ -12,6 +12,17 @@ #define GETENTRY(vec,pos) ((ArrayType *) DatumGetPointer((vec)->vector[(pos)].key)) +/* + * Control the maximum sparseness of compressed keys. + * + * The upper safe bound for this limit is half the maximum allocatable array + * size. A lower bound would give more guarantees that pathological data + * wouldn't eat excessive CPU and memory, but at the expense of breaking + * possibly working (after a fashion) indexes. + */ +#define MAXNUMELTS (Min((MaxAllocSize / sizeof(Datum)),((MaxAllocSize - ARR_OVERHEAD_NONULLS(1)) / sizeof(int)))/2) +/* or: #define MAXNUMELTS 1000000 */ + /* ** GiST support methods */ @@ -85,8 +96,13 @@ g_int_consistent(PG_FUNCTION_ARGS) retval = inner_int_contains(query, (ArrayType *) DatumGetPointer(entry->key)); else - retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), - query); + { + /* + * Unfortunately, because empty arrays could be anywhere in + * the index, we must search the whole tree. + */ + retval = true; + } break; default: retval = false; @@ -141,11 +157,13 @@ g_int_compress(PG_FUNCTION_ARGS) GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval; ArrayType *r; - int len; + int len, + lenr; int *dr; int i, - min, + j, cand; + int64 min; if (entry->leafkey) { @@ -186,23 +204,65 @@ g_int_compress(PG_FUNCTION_ARGS) dr = ARRPTR(r); - for (i = len - 1; i >= 0; i--) - dr[2 * i] = dr[2 * i + 1] = dr[i]; + /* + * "len" at this point is the number of ranges we will construct. + * "lenr" is the number of ranges we must eventually remove by + * merging, we must be careful to remove no more than this number. + */ + lenr = len - MAXNUMRANGE; + + /* + * Initially assume we can merge consecutive ints into a range. but we + * must count every value removed and stop when lenr runs out + */ + for (j = i = len - 1; i > 0 && lenr > 0; i--, j--) + { + int r_end = dr[i]; + int r_start = r_end; - len *= 2; + while (i > 0 && lenr > 0 && dr[i - 1] == r_start - 1) + --r_start, --i, --lenr; + dr[2 * j] = r_start; + dr[2 * j + 1] = r_end; + } + /* just copy the rest, if any, as trivial ranges */ + for (; i >= 0; i--, j--) + dr[2 * j] = dr[2 * j + 1] = dr[i]; + + if (++j) + { + /* + * shunt everything down to start at the right place + */ + memmove((void *) &dr[0], (void *) &dr[2 * j], 2 * (len - j) * sizeof(int32)); + } + + /* + * make "len" be number of array elements, not ranges + */ + len = 2 * (len - j); cand = 1; while (len > MAXNUMRANGE * 2) { - min = INT_MAX; + min = PG_INT64_MAX; for (i = 2; i < len; i += 2) - if (min > (dr[i] - dr[i - 1])) + if (min > ((int64) dr[i] - (int64) dr[i - 1])) { - min = (dr[i] - dr[i - 1]); + min = ((int64) dr[i] - (int64) dr[i - 1]); cand = i; } memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int32)); len -= 2; } + + /* + * check sparseness of result + */ + lenr = internal_size(dr, len); + if (lenr < 0 || lenr > MAXNUMELTS) + ereport(ERROR, + (errmsg("data is too sparse, recreate index using gist__intbig_ops opclass instead"))); + r = resize_intArrayType(r, len); retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r), @@ -260,6 +320,9 @@ g_int_decompress(PG_FUNCTION_ARGS) din = ARRPTR(in); lenr = internal_size(din, lenin); + if (lenr < 0 || lenr > MAXNUMELTS) + ereport(ERROR, + (errmsg("compressed array is too big, recreate index using gist__intbig_ops opclass instead"))); r = new_intArrayType(lenr); dr = ARRPTR(r); diff --git a/contrib/intarray/_int_selfuncs.c b/contrib/intarray/_int_selfuncs.c index 4c3f60c1dd4..aebffae66c2 100644 --- a/contrib/intarray/_int_selfuncs.c +++ b/contrib/intarray/_int_selfuncs.c @@ -3,7 +3,7 @@ * _int_selfuncs.c * Functions for selectivity estimation of intarray operators * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,7 +35,7 @@ PG_FUNCTION_INFO_V1(_int_matchsel); static Selectivity int_query_opr_selec(ITEM *item, Datum *values, float4 *freqs, - int nmncelems, float4 minfreq); + int nmncelems, float4 minfreq); static int compare_val_int4(const void *a, const void *b); /* @@ -43,7 +43,7 @@ static int compare_val_int4(const void *a, const void *b); * * The default array selectivity operators for the @>, && and @< operators * work fine for integer arrays. However, if we tried to just use arraycontsel - * and arracontjoinsel directly as the cost estimator functions for our + * and arraycontjoinsel directly as the cost estimator functions for our * operators, they would not work as intended, because they look at the * operator's OID. Our operators behave exactly like the built-in anyarray * versions, but we must tell the cost estimator functions which built-in diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c index ee8fb64a478..fde8d15e2c2 100644 --- a/contrib/intarray/_int_tool.c +++ b/contrib/intarray/_int_tool.c @@ -3,6 +3,8 @@ */ #include "postgres.h" +#include + #include "catalog/pg_type.h" #include "_int.h" @@ -220,7 +222,17 @@ ArrayType * new_intArrayType(int num) { ArrayType *r; - int nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num; + int nbytes; + + /* if no elements, return a zero-dimensional array */ + if (num <= 0) + { + Assert(num == 0); + r = construct_empty_array(INT4OID); + return r; + } + + nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num; r = (ArrayType *) palloc0(nbytes); @@ -237,19 +249,22 @@ new_intArrayType(int num) ArrayType * resize_intArrayType(ArrayType *a, int num) { - int nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num; + int nbytes; int i; /* if no elements, return a zero-dimensional array */ - if (num == 0) + if (num <= 0) { - ARR_NDIM(a) = 0; + Assert(num == 0); + a = construct_empty_array(INT4OID); return a; } if (num == ARRNELEMS(a)) return a; + nbytes = ARR_DATA_OFFSET(a) + sizeof(int) * num; + a = (ArrayType *) repalloc(a, nbytes); SET_VARSIZE(a, nbytes); @@ -277,16 +292,18 @@ copy_intArrayType(ArrayType *a) int internal_size(int *a, int len) { - int i, - size = 0; + int i; + int64 size = 0; for (i = 0; i < len; i += 2) { if (!i || a[i] != a[i - 1]) /* do not count repeated range */ - size += a[i + 1] - a[i] + 1; + size += (int64) (a[i + 1]) - (int64) (a[i]) + 1; } - return size; + if (size > (int64) INT_MAX || size < (int64) INT_MIN) + return -1; /* overflow */ + return (int) size; } /* unique-ify elements of r in-place ... r must be sorted already */ diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c index de7bc82a234..2a20abecc6c 100644 --- a/contrib/intarray/_intbig_gist.c +++ b/contrib/intarray/_intbig_gist.c @@ -5,6 +5,7 @@ #include "access/gist.h" #include "access/stratnum.h" +#include "port/pg_bitutils.h" #include "_int.h" @@ -19,27 +20,6 @@ PG_FUNCTION_INFO_V1(g_intbig_penalty); PG_FUNCTION_INFO_V1(g_intbig_picksplit); PG_FUNCTION_INFO_V1(g_intbig_union); PG_FUNCTION_INFO_V1(g_intbig_same); - -/* Number of one-bits in an unsigned byte */ -static const uint8 number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - PG_FUNCTION_INFO_V1(_intbig_in); PG_FUNCTION_INFO_V1(_intbig_out); @@ -207,12 +187,7 @@ g_intbig_compress(PG_FUNCTION_ARGS) static int32 sizebitvec(BITVECP sign) { - int32 size = 0, - i; - - LOOPBYTE - size += number_of_ones[(unsigned char) sign[i]]; - return size; + return pg_popcount(sign, SIGLEN); } static int @@ -225,7 +200,8 @@ hemdistsign(BITVECP a, BITVECP b) LOOPBYTE { diff = (unsigned char) (a[i] ^ b[i]); - dist += number_of_ones[diff]; + /* Using the popcount functions here isn't likely to win */ + dist += pg_number_of_ones[diff]; } return dist; } @@ -591,7 +567,13 @@ g_intbig_consistent(PG_FUNCTION_ARGS) } } else - retval = _intbig_overlap((GISTTYPE *) DatumGetPointer(entry->key), query); + { + /* + * Unfortunately, because empty arrays could be anywhere in + * the index, we must search the whole tree. + */ + retval = true; + } break; default: retval = false; diff --git a/contrib/intarray/bench/create_test.pl b/contrib/intarray/bench/create_test.pl index f3262df05b2..d2c678bb53c 100755 --- a/contrib/intarray/bench/create_test.pl +++ b/contrib/intarray/bench/create_test.pl @@ -83,4 +83,5 @@ sub copytable while (<$fff>) { print; } close $fff; print "\\.\n"; + return; } diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out index 0a5dd463acb..c92a56524a3 100644 --- a/contrib/intarray/expected/_int.out +++ b/contrib/intarray/expected/_int.out @@ -151,6 +151,30 @@ SELECT '{-1,3,1}'::int[] & '{1,2}'; {1} (1 row) +SELECT '{1}'::int[] & '{2}'::int[]; + ?column? +---------- + {} +(1 row) + +SELECT array_dims('{1}'::int[] & '{2}'::int[]); + array_dims +------------ + +(1 row) + +SELECT ('{1}'::int[] & '{2}'::int[]) = '{}'::int[]; + ?column? +---------- + t +(1 row) + +SELECT ('{}'::int[] & '{}'::int[]) = '{}'::int[]; + ?column? +---------- + t +(1 row) + --test query_int SELECT '1'::query_int; query_int @@ -407,6 +431,18 @@ SELECT count(*) from test__int WHERE a @> '{20,23}'; 12 (1 row) +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; + count +------- + 10 +(1 row) + +SELECT count(*) from test__int WHERE a = '{73,23,20}'; + count +------- + 1 +(1 row) + SELECT count(*) from test__int WHERE a @@ '50&68'; count ------- @@ -425,6 +461,19 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; 21 (1 row) +SELECT count(*) from test__int WHERE a @@ '20 | !21'; + count +------- + 6566 +(1 row) + +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + count +------- + 6343 +(1 row) + +SET enable_seqscan = off; -- not all of these would use index by default CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); SELECT count(*) from test__int WHERE a && '{23,50}'; count @@ -456,6 +505,18 @@ SELECT count(*) from test__int WHERE a @> '{20,23}'; 12 (1 row) +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; + count +------- + 10 +(1 row) + +SELECT count(*) from test__int WHERE a = '{73,23,20}'; + count +------- + 1 +(1 row) + SELECT count(*) from test__int WHERE a @@ '50&68'; count ------- @@ -474,6 +535,18 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; 21 (1 row) +SELECT count(*) from test__int WHERE a @@ '20 | !21'; + count +------- + 6566 +(1 row) + +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + count +------- + 6343 +(1 row) + DROP INDEX text_idx; CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); SELECT count(*) from test__int WHERE a && '{23,50}'; @@ -506,6 +579,18 @@ SELECT count(*) from test__int WHERE a @> '{20,23}'; 12 (1 row) +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; + count +------- + 10 +(1 row) + +SELECT count(*) from test__int WHERE a = '{73,23,20}'; + count +------- + 1 +(1 row) + SELECT count(*) from test__int WHERE a @@ '50&68'; count ------- @@ -524,6 +609,18 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; 21 (1 row) +SELECT count(*) from test__int WHERE a @@ '20 | !21'; + count +------- + 6566 +(1 row) + +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + count +------- + 6343 +(1 row) + DROP INDEX text_idx; CREATE INDEX text_idx on test__int using gin ( a gin__int_ops ); SELECT count(*) from test__int WHERE a && '{23,50}'; @@ -556,6 +653,18 @@ SELECT count(*) from test__int WHERE a @> '{20,23}'; 12 (1 row) +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; + count +------- + 10 +(1 row) + +SELECT count(*) from test__int WHERE a = '{73,23,20}'; + count +------- + 1 +(1 row) + SELECT count(*) from test__int WHERE a @@ '50&68'; count ------- @@ -574,3 +683,16 @@ SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; 21 (1 row) +SELECT count(*) from test__int WHERE a @@ '20 | !21'; + count +------- + 6566 +(1 row) + +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + count +------- + 6343 +(1 row) + +RESET enable_seqscan; diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql index 44e1a729b4f..6ca7e3cca7e 100644 --- a/contrib/intarray/sql/_int.sql +++ b/contrib/intarray/sql/_int.sql @@ -30,6 +30,10 @@ SELECT '{123,623,445}'::int[] | 1623; SELECT '{123,623,445}'::int[] | '{1623,623}'; SELECT '{123,623,445}'::int[] & '{1623,623}'; SELECT '{-1,3,1}'::int[] & '{1,2}'; +SELECT '{1}'::int[] & '{2}'::int[]; +SELECT array_dims('{1}'::int[] & '{2}'::int[]); +SELECT ('{1}'::int[] & '{2}'::int[]) = '{}'::int[]; +SELECT ('{}'::int[] & '{}'::int[]) = '{}'::int[]; --test query_int @@ -81,9 +85,15 @@ SELECT count(*) from test__int WHERE a @@ '23|50'; SELECT count(*) from test__int WHERE a @> '{23,50}'; SELECT count(*) from test__int WHERE a @@ '23&50'; SELECT count(*) from test__int WHERE a @> '{20,23}'; +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; +SELECT count(*) from test__int WHERE a = '{73,23,20}'; SELECT count(*) from test__int WHERE a @@ '50&68'; SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}'; SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; +SELECT count(*) from test__int WHERE a @@ '20 | !21'; +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + +SET enable_seqscan = off; -- not all of these would use index by default CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); @@ -92,9 +102,13 @@ SELECT count(*) from test__int WHERE a @@ '23|50'; SELECT count(*) from test__int WHERE a @> '{23,50}'; SELECT count(*) from test__int WHERE a @@ '23&50'; SELECT count(*) from test__int WHERE a @> '{20,23}'; +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; +SELECT count(*) from test__int WHERE a = '{73,23,20}'; SELECT count(*) from test__int WHERE a @@ '50&68'; SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}'; SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; +SELECT count(*) from test__int WHERE a @@ '20 | !21'; +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; DROP INDEX text_idx; CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); @@ -104,9 +118,13 @@ SELECT count(*) from test__int WHERE a @@ '23|50'; SELECT count(*) from test__int WHERE a @> '{23,50}'; SELECT count(*) from test__int WHERE a @@ '23&50'; SELECT count(*) from test__int WHERE a @> '{20,23}'; +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; +SELECT count(*) from test__int WHERE a = '{73,23,20}'; SELECT count(*) from test__int WHERE a @@ '50&68'; SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}'; SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; +SELECT count(*) from test__int WHERE a @@ '20 | !21'; +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; DROP INDEX text_idx; CREATE INDEX text_idx on test__int using gin ( a gin__int_ops ); @@ -116,6 +134,12 @@ SELECT count(*) from test__int WHERE a @@ '23|50'; SELECT count(*) from test__int WHERE a @> '{23,50}'; SELECT count(*) from test__int WHERE a @@ '23&50'; SELECT count(*) from test__int WHERE a @> '{20,23}'; +SELECT count(*) from test__int WHERE a <@ '{73,23,20}'; +SELECT count(*) from test__int WHERE a = '{73,23,20}'; SELECT count(*) from test__int WHERE a @@ '50&68'; SELECT count(*) from test__int WHERE a @> '{20,23}' or a @> '{50,68}'; SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; +SELECT count(*) from test__int WHERE a @@ '20 | !21'; +SELECT count(*) from test__int WHERE a @@ '!20 & !21'; + +RESET enable_seqscan; diff --git a/contrib/isn/Makefile b/contrib/isn/Makefile index ab6b175f9a7..c3600dac300 100644 --- a/contrib/isn/Makefile +++ b/contrib/isn/Makefile @@ -7,6 +7,9 @@ DATA = isn--1.1.sql isn--1.1--1.2.sql \ isn--1.0--1.1.sql isn--unpackaged--1.0.sql PGFILEDESC = "isn - data types for international product numbering standards" +# the other .h files are data tables, we don't install those +HEADERS_isn = isn.h + REGRESS = isn ifdef USE_PGXS diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c index 897d83e0ca3..0c2cac7d52b 100644 --- a/contrib/isn/isn.c +++ b/contrib/isn/isn.c @@ -4,7 +4,7 @@ * PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC) * * Author: German Mendez Bravo (Kronuz) - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/isn/isn.c diff --git a/contrib/isn/isn.h b/contrib/isn/isn.h index 29632d85185..d572149d2af 100644 --- a/contrib/isn/isn.h +++ b/contrib/isn/isn.h @@ -4,7 +4,7 @@ * PostgreSQL type definitions for ISNs (ISBN, ISMN, ISSN, EAN13, UPC) * * Author: German Mendez Bravo (Kronuz) - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/isn/isn.h diff --git a/contrib/jsonb_plperl/Makefile b/contrib/jsonb_plperl/Makefile index eb6d1deb7df..b43c8ed97bd 100644 --- a/contrib/jsonb_plperl/Makefile +++ b/contrib/jsonb_plperl/Makefile @@ -35,8 +35,5 @@ rpathdir = $(perl_archlibexp)/CORE SHLIB_LINK += $(perl_embed_ldflags) endif -# As with plperl we need to make sure that the CORE directory is included -# last, probably because it sometimes contains some header files with names -# that clash with some of ours, or with some that we include, notably on -# Windows. -override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) -I$(perl_archlibexp)/CORE +# As with plperl we need to include the perl_includespec directory last. +override CPPFLAGS := $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec) diff --git a/contrib/jsonb_plperl/expected/jsonb_plperl.out b/contrib/jsonb_plperl/expected/jsonb_plperl.out index 99a2e8e135d..5a73485ac06 100644 --- a/contrib/jsonb_plperl/expected/jsonb_plperl.out +++ b/contrib/jsonb_plperl/expected/jsonb_plperl.out @@ -39,6 +39,20 @@ SELECT testSVToJsonb(); 1 (1 row) +CREATE FUNCTION testUVToJsonb() RETURNS jsonb +LANGUAGE plperl +TRANSFORM FOR TYPE jsonb +as $$ +$val = ~0; +return $val; +$$; +-- this might produce either 18446744073709551615 or 4294967295 +SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb); + ?column? +---------- + t +(1 row) + -- this revealed a bug in the original implementation CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb LANGUAGE plperl @@ -52,16 +66,39 @@ SELECT testRegexpResultToJsonb(); 0 (1 row) -CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb +-- this revealed a different bug +CREATE FUNCTION testTextToJsonbObject(text) RETURNS jsonb +LANGUAGE plperl +TRANSFORM FOR TYPE jsonb +AS $$ +my $x = shift; +return {a => $x}; +$$; +SELECT testTextToJsonbObject('abc'); + testtexttojsonbobject +----------------------- + {"a": "abc"} +(1 row) + +SELECT testTextToJsonbObject(NULL); + testtexttojsonbobject +----------------------- + {"a": null} +(1 row) + +CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb LANGUAGE plperl TRANSFORM FOR TYPE jsonb AS $$ +# can't use Data::Dumper, but let's at least check for unexpected ref type +die 'unexpected '.(ref($_[0]) || 'not a').' reference' + if ref($_[0]) ne $_[1]; return $_[0]; $$; -SELECT roundtrip('null'); - roundtrip ------------ - null +SELECT roundtrip('null') is null; + ?column? +---------- + t (1 row) SELECT roundtrip('1'); @@ -71,7 +108,7 @@ SELECT roundtrip('1'); (1 row) SELECT roundtrip('1E+131071'); -ERROR: cannot convert infinite value to jsonb +ERROR: cannot convert infinity to jsonb CONTEXT: PL/Perl function "roundtrip" SELECT roundtrip('-1'); roundtrip @@ -115,91 +152,97 @@ SELECT roundtrip('false'); 0 (1 row) -SELECT roundtrip('[]'); +SELECT roundtrip('[]', 'ARRAY'); roundtrip ----------- [] (1 row) -SELECT roundtrip('[null, null]'); +SELECT roundtrip('[null, null]', 'ARRAY'); roundtrip -------------- [null, null] (1 row) -SELECT roundtrip('[1, 2, 3]'); +SELECT roundtrip('[1, 2, 3]', 'ARRAY'); roundtrip ----------- [1, 2, 3] (1 row) -SELECT roundtrip('[-1, 2, -3]'); +SELECT roundtrip('[-1, 2, -3]', 'ARRAY'); roundtrip ------------- [-1, 2, -3] (1 row) -SELECT roundtrip('[1.2, 2.3, 3.4]'); +SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY'); roundtrip ----------------- [1.2, 2.3, 3.4] (1 row) -SELECT roundtrip('[-1.2, 2.3, -3.4]'); +SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY'); roundtrip ------------------- [-1.2, 2.3, -3.4] (1 row) -SELECT roundtrip('["string1", "string2"]'); +SELECT roundtrip('["string1", "string2"]', 'ARRAY'); roundtrip ------------------------ ["string1", "string2"] (1 row) -SELECT roundtrip('{}'); +SELECT roundtrip('[["string1", "string2"]]', 'ARRAY'); + roundtrip +-------------------------- + [["string1", "string2"]] +(1 row) + +SELECT roundtrip('{}', 'HASH'); roundtrip ----------- {} (1 row) -SELECT roundtrip('{"1": null}'); +SELECT roundtrip('{"1": null}', 'HASH'); roundtrip ------------- {"1": null} (1 row) -SELECT roundtrip('{"1": 1}'); +SELECT roundtrip('{"1": 1}', 'HASH'); roundtrip ----------- {"1": 1} (1 row) -SELECT roundtrip('{"1": -1}'); +SELECT roundtrip('{"1": -1}', 'HASH'); roundtrip ----------- {"1": -1} (1 row) -SELECT roundtrip('{"1": 1.1}'); +SELECT roundtrip('{"1": 1.1}', 'HASH'); roundtrip ------------ {"1": 1.1} (1 row) -SELECT roundtrip('{"1": -1.1}'); +SELECT roundtrip('{"1": -1.1}', 'HASH'); roundtrip ------------- {"1": -1.1} (1 row) -SELECT roundtrip('{"1": "string1"}'); +SELECT roundtrip('{"1": "string1"}', 'HASH'); roundtrip ------------------ {"1": "string1"} (1 row) -SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); +SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH'); roundtrip --------------------------------- {"1": {"2": [3, 4, 5]}, "2": 3} @@ -207,4 +250,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); \set VERBOSITY terse \\ -- suppress cascade details DROP EXTENSION plperl CASCADE; -NOTICE: drop cascades to 6 other objects +NOTICE: drop cascades to 8 other objects diff --git a/contrib/jsonb_plperl/expected/jsonb_plperlu.out b/contrib/jsonb_plperl/expected/jsonb_plperlu.out index 8053cf6aa80..dff316cf984 100644 --- a/contrib/jsonb_plperl/expected/jsonb_plperlu.out +++ b/contrib/jsonb_plperl/expected/jsonb_plperlu.out @@ -39,6 +39,20 @@ SELECT testSVToJsonb(); 1 (1 row) +CREATE FUNCTION testUVToJsonb() RETURNS jsonb +LANGUAGE plperlu +TRANSFORM FOR TYPE jsonb +as $$ +$val = ~0; +return $val; +$$; +-- this might produce either 18446744073709551615 or 4294967295 +SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb); + ?column? +---------- + t +(1 row) + -- this revealed a bug in the original implementation CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb LANGUAGE plperlu @@ -52,154 +66,210 @@ SELECT testRegexpResultToJsonb(); 0 (1 row) -CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb +-- this revealed a different bug +CREATE FUNCTION testTextToJsonbObject(text) RETURNS jsonb +LANGUAGE plperlu +TRANSFORM FOR TYPE jsonb +AS $$ +my $x = shift; +return {a => $x}; +$$; +SELECT testTextToJsonbObject('abc'); + testtexttojsonbobject +----------------------- + {"a": "abc"} +(1 row) + +SELECT testTextToJsonbObject(NULL); + testtexttojsonbobject +----------------------- + {"a": null} +(1 row) + +CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb LANGUAGE plperlu TRANSFORM FOR TYPE jsonb AS $$ +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Indent = 0; +elog(INFO, Dumper($_[0])); +die 'unexpected '.(ref($_[0]) || 'not a').' reference' + if ref($_[0]) ne $_[1]; return $_[0]; $$; -SELECT roundtrip('null'); - roundtrip ------------ - null +SELECT roundtrip('null') is null; +INFO: $VAR1 = undef; + ?column? +---------- + t (1 row) SELECT roundtrip('1'); +INFO: $VAR1 = '1'; roundtrip ----------- 1 (1 row) -SELECT roundtrip('1E+131071'); -ERROR: cannot convert infinite value to jsonb -CONTEXT: PL/Perl function "roundtrip" +-- skip because Data::Dumper produces a platform-dependent spelling of infinity +-- SELECT roundtrip('1E+131071'); SELECT roundtrip('-1'); +INFO: $VAR1 = '-1'; roundtrip ----------- -1 (1 row) SELECT roundtrip('1.2'); +INFO: $VAR1 = '1.2'; roundtrip ----------- 1.2 (1 row) SELECT roundtrip('-1.2'); +INFO: $VAR1 = '-1.2'; roundtrip ----------- -1.2 (1 row) SELECT roundtrip('"string"'); +INFO: $VAR1 = 'string'; roundtrip ----------- "string" (1 row) SELECT roundtrip('"NaN"'); +INFO: $VAR1 = 'NaN'; roundtrip ----------- "NaN" (1 row) SELECT roundtrip('true'); +INFO: $VAR1 = '1'; roundtrip ----------- 1 (1 row) SELECT roundtrip('false'); +INFO: $VAR1 = '0'; roundtrip ----------- 0 (1 row) -SELECT roundtrip('[]'); +SELECT roundtrip('[]', 'ARRAY'); +INFO: $VAR1 = []; roundtrip ----------- [] (1 row) -SELECT roundtrip('[null, null]'); +SELECT roundtrip('[null, null]', 'ARRAY'); +INFO: $VAR1 = [undef,undef]; roundtrip -------------- [null, null] (1 row) -SELECT roundtrip('[1, 2, 3]'); +SELECT roundtrip('[1, 2, 3]', 'ARRAY'); +INFO: $VAR1 = ['1','2','3']; roundtrip ----------- [1, 2, 3] (1 row) -SELECT roundtrip('[-1, 2, -3]'); +SELECT roundtrip('[-1, 2, -3]', 'ARRAY'); +INFO: $VAR1 = ['-1','2','-3']; roundtrip ------------- [-1, 2, -3] (1 row) -SELECT roundtrip('[1.2, 2.3, 3.4]'); +SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY'); +INFO: $VAR1 = ['1.2','2.3','3.4']; roundtrip ----------------- [1.2, 2.3, 3.4] (1 row) -SELECT roundtrip('[-1.2, 2.3, -3.4]'); +SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY'); +INFO: $VAR1 = ['-1.2','2.3','-3.4']; roundtrip ------------------- [-1.2, 2.3, -3.4] (1 row) -SELECT roundtrip('["string1", "string2"]'); +SELECT roundtrip('["string1", "string2"]', 'ARRAY'); +INFO: $VAR1 = ['string1','string2']; roundtrip ------------------------ ["string1", "string2"] (1 row) -SELECT roundtrip('{}'); +SELECT roundtrip('[["string1", "string2"]]', 'ARRAY'); +INFO: $VAR1 = [['string1','string2']]; + roundtrip +-------------------------- + [["string1", "string2"]] +(1 row) + +SELECT roundtrip('{}', 'HASH'); +INFO: $VAR1 = {}; roundtrip ----------- {} (1 row) -SELECT roundtrip('{"1": null}'); +SELECT roundtrip('{"1": null}', 'HASH'); +INFO: $VAR1 = {'1' => undef}; roundtrip ------------- {"1": null} (1 row) -SELECT roundtrip('{"1": 1}'); +SELECT roundtrip('{"1": 1}', 'HASH'); +INFO: $VAR1 = {'1' => '1'}; roundtrip ----------- {"1": 1} (1 row) -SELECT roundtrip('{"1": -1}'); +SELECT roundtrip('{"1": -1}', 'HASH'); +INFO: $VAR1 = {'1' => '-1'}; roundtrip ----------- {"1": -1} (1 row) -SELECT roundtrip('{"1": 1.1}'); +SELECT roundtrip('{"1": 1.1}', 'HASH'); +INFO: $VAR1 = {'1' => '1.1'}; roundtrip ------------ {"1": 1.1} (1 row) -SELECT roundtrip('{"1": -1.1}'); +SELECT roundtrip('{"1": -1.1}', 'HASH'); +INFO: $VAR1 = {'1' => '-1.1'}; roundtrip ------------- {"1": -1.1} (1 row) -SELECT roundtrip('{"1": "string1"}'); +SELECT roundtrip('{"1": "string1"}', 'HASH'); +INFO: $VAR1 = {'1' => 'string1'}; roundtrip ------------------ {"1": "string1"} (1 row) -SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); +SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH'); +INFO: $VAR1 = {'1' => {'2' => ['3','4','5']},'2' => '3'}; roundtrip --------------------------------- {"1": {"2": [3, 4, 5]}, "2": 3} @@ -207,4 +277,4 @@ SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); \set VERBOSITY terse \\ -- suppress cascade details DROP EXTENSION plperlu CASCADE; -NOTICE: drop cascades to 6 other objects +NOTICE: drop cascades to 8 other objects diff --git a/contrib/jsonb_plperl/jsonb_plperl.c b/contrib/jsonb_plperl/jsonb_plperl.c index 837bae2ab50..04b04df953f 100644 --- a/contrib/jsonb_plperl/jsonb_plperl.c +++ b/contrib/jsonb_plperl/jsonb_plperl.c @@ -1,11 +1,7 @@ #include "postgres.h" -#include #include -/* Defined by Perl */ -#undef _ - #include "fmgr.h" #include "plperl.h" #include "plperl_helpers.h" @@ -18,7 +14,7 @@ static SV *Jsonb_to_SV(JsonbContainer *jsonb); static JsonbValue *SV_to_JsonbValue(SV *obj, JsonbParseState **ps, bool is_elem); -static SV * +static SV * JsonbValue_to_SV(JsonbValue *jbv) { dTHX; @@ -26,13 +22,14 @@ JsonbValue_to_SV(JsonbValue *jbv) switch (jbv->type) { case jbvBinary: - return newRV(Jsonb_to_SV(jbv->val.binary.data)); + return Jsonb_to_SV(jbv->val.binary.data); case jbvNumeric: { char *str = DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(jbv->val.numeric))); SV *result = newSVnv(SvNV(cstr2sv(str))); + pfree(str); return result; } @@ -42,6 +39,7 @@ JsonbValue_to_SV(JsonbValue *jbv) char *str = pnstrdup(jbv->val.string.val, jbv->val.string.len); SV *result = cstr2sv(str); + pfree(str); return result; } @@ -81,7 +79,7 @@ Jsonb_to_SV(JsonbContainer *jsonb) (r = JsonbIteratorNext(&it, &tmp, true)) != WJB_DONE) elog(ERROR, "unexpected jsonb token: %d", r); - return newRV(JsonbValue_to_SV(&v)); + return JsonbValue_to_SV(&v); } else { @@ -93,7 +91,7 @@ Jsonb_to_SV(JsonbContainer *jsonb) av_push(av, JsonbValue_to_SV(&v)); } - return (SV *) av; + return newRV((SV *) av); } case WJB_BEGIN_OBJECT: @@ -118,7 +116,7 @@ Jsonb_to_SV(JsonbContainer *jsonb) } } - return (SV *) hv; + return newRV((SV *) hv); } default: @@ -191,12 +189,29 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem) case SVt_PVHV: return HV_to_JsonbValue((HV *) in, jsonb_state); - case SVt_NULL: - out.type = jbvNull; - break; - default: - if (SvIOK(in)) + if (!SvOK(in)) + { + out.type = jbvNull; + } + else if (SvUOK(in)) + { + /* + * If UV is >=64 bits, we have no better way to make this + * happen than converting to text and back. Given the low + * usage of UV in Perl code, it's not clear it's worth working + * hard to provide alternate code paths. + */ + const char *strval = SvPV_nolen(in); + + out.type = jbvNumeric; + out.val.numeric = + DatumGetNumeric(DirectFunctionCall3(numeric_in, + CStringGetDatum(strval), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + } + else if (SvIOK(in)) { IV ival = SvIV(in); @@ -209,10 +224,22 @@ SV_to_JsonbValue(SV *in, JsonbParseState **jsonb_state, bool is_elem) { double nval = SvNV(in); + /* + * jsonb doesn't allow infinity or NaN (per JSON + * specification), but the numeric type that is used for the + * storage accepts NaN, so we have to prevent it here + * explicitly. We don't really have to check for isinf() + * here, as numeric doesn't allow it and it would be caught + * later, but it makes for a nicer error message. + */ if (isinf(nval)) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - (errmsg("cannot convert infinite value to jsonb")))); + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + (errmsg("cannot convert infinity to jsonb")))); + if (isnan(nval)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + (errmsg("cannot convert NaN to jsonb")))); out.type = jbvNumeric; out.val.numeric = @@ -254,7 +281,7 @@ jsonb_to_plperl(PG_FUNCTION_ARGS) Jsonb *in = PG_GETARG_JSONB_P(0); SV *sv = Jsonb_to_SV(&in->root); - return PointerGetDatum(newRV(sv)); + return PointerGetDatum(sv); } diff --git a/contrib/jsonb_plperl/jsonb_plperlu--1.0.sql b/contrib/jsonb_plperl/jsonb_plperlu--1.0.sql index 99b8644e3b6..aa84b37bef7 100644 --- a/contrib/jsonb_plperl/jsonb_plperlu--1.0.sql +++ b/contrib/jsonb_plperl/jsonb_plperlu--1.0.sql @@ -1,19 +1,19 @@ -/* contrib/json_plperl/jsonb_plperl--1.0.sql */ +/* contrib/jsonb_plperl/jsonb_plperlu--1.0.sql */ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION jsonb_plperlu" to load this file. \quit -CREATE FUNCTION jsonb_to_plperl(val internal) RETURNS internal +CREATE FUNCTION jsonb_to_plperlu(val internal) RETURNS internal LANGUAGE C STRICT IMMUTABLE -AS 'MODULE_PATHNAME'; +AS 'MODULE_PATHNAME', 'jsonb_to_plperl'; -CREATE FUNCTION plperl_to_jsonb(val internal) RETURNS jsonb +CREATE FUNCTION plperlu_to_jsonb(val internal) RETURNS jsonb LANGUAGE C STRICT IMMUTABLE -AS 'MODULE_PATHNAME'; +AS 'MODULE_PATHNAME', 'plperl_to_jsonb'; CREATE TRANSFORM FOR jsonb LANGUAGE plperlu ( - FROM SQL WITH FUNCTION jsonb_to_plperl(internal), - TO SQL WITH FUNCTION plperl_to_jsonb(internal) + FROM SQL WITH FUNCTION jsonb_to_plperlu(internal), + TO SQL WITH FUNCTION plperlu_to_jsonb(internal) ); COMMENT ON TRANSFORM FOR jsonb LANGUAGE plperlu IS 'transform between jsonb and Perl'; diff --git a/contrib/jsonb_plperl/sql/jsonb_plperl.sql b/contrib/jsonb_plperl/sql/jsonb_plperl.sql index 8b0a8764afa..a5b2cffe6b7 100644 --- a/contrib/jsonb_plperl/sql/jsonb_plperl.sql +++ b/contrib/jsonb_plperl/sql/jsonb_plperl.sql @@ -34,6 +34,18 @@ $$; SELECT testSVToJsonb(); +CREATE FUNCTION testUVToJsonb() RETURNS jsonb +LANGUAGE plperl +TRANSFORM FOR TYPE jsonb +as $$ +$val = ~0; +return $val; +$$; + +-- this might produce either 18446744073709551615 or 4294967295 +SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb); + + -- this revealed a bug in the original implementation CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb LANGUAGE plperl @@ -45,15 +57,31 @@ $$; SELECT testRegexpResultToJsonb(); -CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb +-- this revealed a different bug +CREATE FUNCTION testTextToJsonbObject(text) RETURNS jsonb +LANGUAGE plperl +TRANSFORM FOR TYPE jsonb +AS $$ +my $x = shift; +return {a => $x}; +$$; + +SELECT testTextToJsonbObject('abc'); +SELECT testTextToJsonbObject(NULL); + + +CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb LANGUAGE plperl TRANSFORM FOR TYPE jsonb AS $$ +# can't use Data::Dumper, but let's at least check for unexpected ref type +die 'unexpected '.(ref($_[0]) || 'not a').' reference' + if ref($_[0]) ne $_[1]; return $_[0]; $$; -SELECT roundtrip('null'); +SELECT roundtrip('null') is null; SELECT roundtrip('1'); SELECT roundtrip('1E+131071'); SELECT roundtrip('-1'); @@ -65,23 +93,24 @@ SELECT roundtrip('"NaN"'); SELECT roundtrip('true'); SELECT roundtrip('false'); -SELECT roundtrip('[]'); -SELECT roundtrip('[null, null]'); -SELECT roundtrip('[1, 2, 3]'); -SELECT roundtrip('[-1, 2, -3]'); -SELECT roundtrip('[1.2, 2.3, 3.4]'); -SELECT roundtrip('[-1.2, 2.3, -3.4]'); -SELECT roundtrip('["string1", "string2"]'); - -SELECT roundtrip('{}'); -SELECT roundtrip('{"1": null}'); -SELECT roundtrip('{"1": 1}'); -SELECT roundtrip('{"1": -1}'); -SELECT roundtrip('{"1": 1.1}'); -SELECT roundtrip('{"1": -1.1}'); -SELECT roundtrip('{"1": "string1"}'); - -SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); +SELECT roundtrip('[]', 'ARRAY'); +SELECT roundtrip('[null, null]', 'ARRAY'); +SELECT roundtrip('[1, 2, 3]', 'ARRAY'); +SELECT roundtrip('[-1, 2, -3]', 'ARRAY'); +SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY'); +SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY'); +SELECT roundtrip('["string1", "string2"]', 'ARRAY'); +SELECT roundtrip('[["string1", "string2"]]', 'ARRAY'); + +SELECT roundtrip('{}', 'HASH'); +SELECT roundtrip('{"1": null}', 'HASH'); +SELECT roundtrip('{"1": 1}', 'HASH'); +SELECT roundtrip('{"1": -1}', 'HASH'); +SELECT roundtrip('{"1": 1.1}', 'HASH'); +SELECT roundtrip('{"1": -1.1}', 'HASH'); +SELECT roundtrip('{"1": "string1"}', 'HASH'); + +SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH'); \set VERBOSITY terse \\ -- suppress cascade details diff --git a/contrib/jsonb_plperl/sql/jsonb_plperlu.sql b/contrib/jsonb_plperl/sql/jsonb_plperlu.sql index 9287f7672f7..c68ef7308a9 100644 --- a/contrib/jsonb_plperl/sql/jsonb_plperlu.sql +++ b/contrib/jsonb_plperl/sql/jsonb_plperlu.sql @@ -34,6 +34,18 @@ $$; SELECT testSVToJsonb(); +CREATE FUNCTION testUVToJsonb() RETURNS jsonb +LANGUAGE plperlu +TRANSFORM FOR TYPE jsonb +as $$ +$val = ~0; +return $val; +$$; + +-- this might produce either 18446744073709551615 or 4294967295 +SELECT testUVToJsonb() IN ('18446744073709551615'::jsonb, '4294967295'::jsonb); + + -- this revealed a bug in the original implementation CREATE FUNCTION testRegexpResultToJsonb() RETURNS jsonb LANGUAGE plperlu @@ -45,17 +57,37 @@ $$; SELECT testRegexpResultToJsonb(); -CREATE FUNCTION roundtrip(val jsonb) RETURNS jsonb +-- this revealed a different bug +CREATE FUNCTION testTextToJsonbObject(text) RETURNS jsonb +LANGUAGE plperlu +TRANSFORM FOR TYPE jsonb +AS $$ +my $x = shift; +return {a => $x}; +$$; + +SELECT testTextToJsonbObject('abc'); +SELECT testTextToJsonbObject(NULL); + + +CREATE FUNCTION roundtrip(val jsonb, ref text = '') RETURNS jsonb LANGUAGE plperlu TRANSFORM FOR TYPE jsonb AS $$ +use Data::Dumper; +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Indent = 0; +elog(INFO, Dumper($_[0])); +die 'unexpected '.(ref($_[0]) || 'not a').' reference' + if ref($_[0]) ne $_[1]; return $_[0]; $$; -SELECT roundtrip('null'); +SELECT roundtrip('null') is null; SELECT roundtrip('1'); -SELECT roundtrip('1E+131071'); +-- skip because Data::Dumper produces a platform-dependent spelling of infinity +-- SELECT roundtrip('1E+131071'); SELECT roundtrip('-1'); SELECT roundtrip('1.2'); SELECT roundtrip('-1.2'); @@ -65,23 +97,24 @@ SELECT roundtrip('"NaN"'); SELECT roundtrip('true'); SELECT roundtrip('false'); -SELECT roundtrip('[]'); -SELECT roundtrip('[null, null]'); -SELECT roundtrip('[1, 2, 3]'); -SELECT roundtrip('[-1, 2, -3]'); -SELECT roundtrip('[1.2, 2.3, 3.4]'); -SELECT roundtrip('[-1.2, 2.3, -3.4]'); -SELECT roundtrip('["string1", "string2"]'); - -SELECT roundtrip('{}'); -SELECT roundtrip('{"1": null}'); -SELECT roundtrip('{"1": 1}'); -SELECT roundtrip('{"1": -1}'); -SELECT roundtrip('{"1": 1.1}'); -SELECT roundtrip('{"1": -1.1}'); -SELECT roundtrip('{"1": "string1"}'); - -SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}'); +SELECT roundtrip('[]', 'ARRAY'); +SELECT roundtrip('[null, null]', 'ARRAY'); +SELECT roundtrip('[1, 2, 3]', 'ARRAY'); +SELECT roundtrip('[-1, 2, -3]', 'ARRAY'); +SELECT roundtrip('[1.2, 2.3, 3.4]', 'ARRAY'); +SELECT roundtrip('[-1.2, 2.3, -3.4]', 'ARRAY'); +SELECT roundtrip('["string1", "string2"]', 'ARRAY'); +SELECT roundtrip('[["string1", "string2"]]', 'ARRAY'); + +SELECT roundtrip('{}', 'HASH'); +SELECT roundtrip('{"1": null}', 'HASH'); +SELECT roundtrip('{"1": 1}', 'HASH'); +SELECT roundtrip('{"1": -1}', 'HASH'); +SELECT roundtrip('{"1": 1.1}', 'HASH'); +SELECT roundtrip('{"1": -1.1}', 'HASH'); +SELECT roundtrip('{"1": "string1"}', 'HASH'); + +SELECT roundtrip('{"1": {"2": [3, 4, 5]}, "2": 3}', 'HASH'); \set VERBOSITY terse \\ -- suppress cascade details diff --git a/contrib/jsonb_plpython/jsonb_plpython.c b/contrib/jsonb_plpython/jsonb_plpython.c index 548826f592f..776cf7c8b9b 100644 --- a/contrib/jsonb_plpython/jsonb_plpython.c +++ b/contrib/jsonb_plpython/jsonb_plpython.c @@ -5,6 +5,7 @@ #include "plpy_typeio.h" #include "utils/jsonb.h" #include "utils/fmgrprotos.h" +#include "utils/numeric.h" PG_MODULE_MAGIC; @@ -25,7 +26,7 @@ static PyObject *decimal_constructor; static PyObject *PLyObject_FromJsonbContainer(JsonbContainer *jsonb); static JsonbValue *PLyObject_ToJsonbValue(PyObject *obj, - JsonbParseState **jsonb_state, bool is_elem); + JsonbParseState **jsonb_state, bool is_elem); #if PY_MAJOR_VERSION >= 3 typedef PyObject *(*PLyUnicode_FromStringAndSize_t) @@ -132,7 +133,7 @@ PLyObject_FromJsonbValue(JsonbValue *jsonbValue) } /* - * PLyObject_FromJsonb + * PLyObject_FromJsonbContainer * * Transform JsonbContainer to PyObject. */ @@ -163,56 +164,91 @@ PLyObject_FromJsonbContainer(JsonbContainer *jsonb) } else { - /* array in v */ + PyObject *volatile elem = NULL; + result = PyList_New(0); if (!result) return NULL; - while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) + PG_TRY(); { - if (r == WJB_ELEM) + while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) { - PyObject *elem = PLyObject_FromJsonbValue(&v); + if (r != WJB_ELEM) + continue; + + elem = PLyObject_FromJsonbValue(&v); PyList_Append(result, elem); Py_XDECREF(elem); + elem = NULL; } } + PG_CATCH(); + { + Py_XDECREF(elem); + Py_XDECREF(result); + PG_RE_THROW(); + } + PG_END_TRY(); } break; case WJB_BEGIN_OBJECT: - result = PyDict_New(); - if (!result) - return NULL; - - while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) { - if (r == WJB_KEY) - { - PyObject *key = PLyString_FromJsonbValue(&v); - - if (!key) - return NULL; + PyObject *volatile result_v = PyDict_New(); + PyObject *volatile key = NULL; + PyObject *volatile val = NULL; - r = JsonbIteratorNext(&it, &v, true); + if (!result_v) + return NULL; - if (r == WJB_VALUE) + PG_TRY(); + { + while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) { - PyObject *value = PLyObject_FromJsonbValue(&v); + if (r != WJB_KEY) + continue; + + key = PLyString_FromJsonbValue(&v); + if (!key) + { + Py_XDECREF(result_v); + result_v = NULL; + break; + } + + if ((r = JsonbIteratorNext(&it, &v, true)) != WJB_VALUE) + elog(ERROR, "unexpected jsonb token: %d", r); - if (!value) + val = PLyObject_FromJsonbValue(&v); + if (!val) { Py_XDECREF(key); - return NULL; + key = NULL; + Py_XDECREF(result_v); + result_v = NULL; + break; } - PyDict_SetItem(result, key, value); - Py_XDECREF(value); - } + PyDict_SetItem(result_v, key, val); + Py_XDECREF(key); + key = NULL; + Py_XDECREF(val); + val = NULL; + } + } + PG_CATCH(); + { + Py_XDECREF(result_v); Py_XDECREF(key); + Py_XDECREF(val); + PG_RE_THROW(); } + PG_END_TRY(); + + result = result_v; } break; @@ -233,20 +269,15 @@ static JsonbValue * PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state) { Py_ssize_t pcount; - JsonbValue *out = NULL; - - /* We need it volatile, since we use it after longjmp */ - volatile PyObject *items_v = NULL; + PyObject *volatile items; + JsonbValue *volatile out; pcount = PyMapping_Size(obj); - items_v = PyMapping_Items(obj); + items = PyMapping_Items(obj); PG_TRY(); { Py_ssize_t i; - PyObject *items; - - items = (PyObject *) items_v; pushJsonbValue(jsonb_state, WJB_BEGIN_OBJECT, NULL); @@ -278,11 +309,13 @@ PLyMapping_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state) } PG_CATCH(); { - Py_DECREF(items_v); + Py_DECREF(items); PG_RE_THROW(); } PG_END_TRY(); + Py_DECREF(items); + return out; } @@ -297,17 +330,30 @@ PLySequence_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state) { Py_ssize_t i; Py_ssize_t pcount; + PyObject *volatile value = NULL; pcount = PySequence_Size(obj); pushJsonbValue(jsonb_state, WJB_BEGIN_ARRAY, NULL); - for (i = 0; i < pcount; i++) + PG_TRY(); { - PyObject *value = PySequence_GetItem(obj, i); + for (i = 0; i < pcount; i++) + { + value = PySequence_GetItem(obj, i); + Assert(value); - (void) PLyObject_ToJsonbValue(value, jsonb_state, true); + (void) PLyObject_ToJsonbValue(value, jsonb_state, true); + Py_XDECREF(value); + value = NULL; + } } + PG_CATCH(); + { + Py_XDECREF(value); + PG_RE_THROW(); + } + PG_END_TRY(); return pushJsonbValue(jsonb_state, WJB_END_ARRAY, NULL); } @@ -325,8 +371,13 @@ PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum) PG_TRY(); { - num = DatumGetNumeric(DirectFunctionCall3(numeric_in, - CStringGetDatum(str), 0, -1)); + Datum numd; + + numd = DirectFunctionCall3(numeric_in, + CStringGetDatum(str), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + num = DatumGetNumeric(numd); } PG_CATCH(); { @@ -338,6 +389,16 @@ PLyNumber_ToJsonbValue(PyObject *obj, JsonbValue *jbvNum) pfree(str); + /* + * jsonb doesn't allow NaN (per JSON specification), so we have to prevent + * it here explicitly. (Infinity is also not allowed in jsonb, but + * numeric_in above already catches that.) + */ + if (numeric_is_nan(num)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + (errmsg("cannot convert NaN to jsonb")))); + jbvNum->type = jbvNumeric; jbvNum->val.numeric = num; @@ -373,13 +434,13 @@ PLyObject_ToJsonbValue(PyObject *obj, JsonbParseState **jsonb_state, bool is_ele out->type = jbvNull; else if (PyString_Check(obj) || PyUnicode_Check(obj)) PLyString_ToJsonbValue(obj, out); - /* - * PyNumber_Check() returns true for booleans, so boolean check should come - * first. - */ + + /* + * PyNumber_Check() returns true for booleans, so boolean check should + * come first. + */ else if (PyBool_Check(obj)) { - out = palloc(sizeof(JsonbValue)); out->type = jbvBool; out->val.boolean = (obj == Py_True); } diff --git a/contrib/ltree/Makefile b/contrib/ltree/Makefile index c101603e6cd..416c8da3127 100644 --- a/contrib/ltree/Makefile +++ b/contrib/ltree/Makefile @@ -9,6 +9,8 @@ EXTENSION = ltree DATA = ltree--1.1.sql ltree--1.0--1.1.sql ltree--unpackaged--1.0.sql PGFILEDESC = "ltree - hierarchical label data type" +HEADERS = ltree.h + REGRESS = ltree ifdef USE_PGXS diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c index 28bf7ad9634..c33ac4eedd2 100644 --- a/contrib/ltree/_ltree_gist.c +++ b/contrib/ltree/_ltree_gist.c @@ -9,6 +9,8 @@ #include "access/gist.h" #include "access/stratnum.h" +#include "port/pg_bitutils.h" + #include "crc32.h" #include "ltree.h" @@ -23,26 +25,6 @@ PG_FUNCTION_INFO_V1(_ltree_consistent); #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key)) #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) -/* Number of one-bits in an unsigned byte */ -static const uint8 number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) ) @@ -209,12 +191,7 @@ _ltree_union(PG_FUNCTION_ARGS) static int32 sizebitvec(BITVECP sign) { - int32 size = 0, - i; - - ALOOPBYTE - size += number_of_ones[(unsigned char) sign[i]]; - return size; + return pg_popcount((const char *) sign, ASIGLEN); } static int @@ -227,7 +204,8 @@ hemdistsign(BITVECP a, BITVECP b) ALOOPBYTE { diff = (unsigned char) (a[i] ^ b[i]); - dist += number_of_ones[diff]; + /* Using the popcount functions here isn't likely to win */ + dist += pg_number_of_ones[diff]; } return dist; } diff --git a/contrib/ltree/expected/ltree.out b/contrib/ltree/expected/ltree.out index 3d5737d41b1..82269309056 100644 --- a/contrib/ltree/expected/ltree.out +++ b/contrib/ltree/expected/ltree.out @@ -259,6 +259,24 @@ SELECT lca('{1.2.3,1.2.3.4.5.6}'); 1.2 (1 row) +SELECT lca('{1.2.3}'); + lca +----- + 1.2 +(1 row) + +SELECT lca('{1}'), lca('{1}') IS NULL; + lca | ?column? +-----+---------- + | f +(1 row) + +SELECT lca('{}') IS NULL; + ?column? +---------- + t +(1 row) + SELECT lca('1.la.2.3','1.2.3.4.5.6'); lca ----- diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c index b6d2deb1af4..62172d5ea14 100644 --- a/contrib/ltree/lquery_op.c +++ b/contrib/ltree/lquery_op.c @@ -50,7 +50,7 @@ getlexeme(char *start, char *end, int *len) } bool - compare_subnode(ltree_level *t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend) +compare_subnode(ltree_level *t, char *qn, int len, int (*cmpptr) (const char *, const char *, size_t), bool anyend) { char *endt = t->name + t->len; char *endq = qn + len; diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h index e4b8c84fa62..366e58004c7 100644 --- a/contrib/ltree/ltree.h +++ b/contrib/ltree/ltree.h @@ -155,13 +155,13 @@ Datum ltree_textadd(PG_FUNCTION_ARGS); /* Util function */ Datum ltree_in(PG_FUNCTION_ARGS); -bool ltree_execute(ITEM *curitem, void *checkval, - bool calcnot, bool (*chkcond) (void *checkval, ITEM *val)); +bool ltree_execute(ITEM *curitem, void *checkval, + bool calcnot, bool (*chkcond) (void *checkval, ITEM *val)); int ltree_compare(const ltree *a, const ltree *b); bool inner_isparent(const ltree *c, const ltree *p); -bool compare_subnode(ltree_level *t, char *q, int len, - int (*cmpptr) (const char *, const char *, size_t), bool anyend); +bool compare_subnode(ltree_level *t, char *q, int len, + int (*cmpptr) (const char *, const char *, size_t), bool anyend); ltree *lca_inner(ltree **a, int len); int ltree_strncasecmp(const char *a, const char *b, size_t s); diff --git a/contrib/ltree/ltree_op.c b/contrib/ltree/ltree_op.c index d62ca02521b..df61c63180c 100644 --- a/contrib/ltree/ltree_op.c +++ b/contrib/ltree/ltree_op.c @@ -45,17 +45,24 @@ ltree_compare(const ltree *a, const ltree *b) ltree_level *bl = LTREE_FIRST(b); int an = a->numlevel; int bn = b->numlevel; - int res = 0; while (an > 0 && bn > 0) { + int res; + if ((res = memcmp(al->name, bl->name, Min(al->len, bl->len))) == 0) { if (al->len != bl->len) return (al->len - bl->len) * 10 * (an + 1); } else + { + if (res < 0) + res = -1; + else + res = 1; return res * 10 * (an + 1); + } an--; bn--; @@ -146,7 +153,7 @@ inner_isparent(const ltree *c, const ltree *p) { if (cl->len != pl->len) return false; - if (memcmp(cl->name, pl->name, cl->len)) + if (memcmp(cl->name, pl->name, cl->len) != 0) return false; pn--; @@ -402,22 +409,34 @@ ltree_textadd(PG_FUNCTION_ARGS) PG_RETURN_POINTER(r); } +/* + * Common code for variants of lca(), find longest common ancestor of inputs + * + * Returns NULL if there is no common ancestor, ie, the longest common + * prefix is empty. + */ ltree * lca_inner(ltree **a, int len) { int tmp, - num = ((*a)->numlevel) ? (*a)->numlevel - 1 : 0; - ltree **ptr = a + 1; - int i, - reslen = LTREE_HDRSIZE; + num, + i, + reslen; + ltree **ptr; ltree_level *l1, *l2; ltree *res; - + if (len <= 0) + return NULL; /* no inputs? */ if ((*a)->numlevel == 0) - return NULL; + return NULL; /* any empty input means NULL result */ + + /* num is the length of the longest common ancestor so far */ + num = (*a)->numlevel - 1; + /* Compare each additional input to *a */ + ptr = a + 1; while (ptr - a < len) { if ((*ptr)->numlevel == 0) @@ -428,11 +447,12 @@ lca_inner(ltree **a, int len) { l1 = LTREE_FIRST(*a); l2 = LTREE_FIRST(*ptr); - tmp = num; + tmp = Min(num, (*ptr)->numlevel - 1); num = 0; - for (i = 0; i < Min(tmp, (*ptr)->numlevel - 1); i++) + for (i = 0; i < tmp; i++) { - if (l1->len == l2->len && memcmp(l1->name, l2->name, l1->len) == 0) + if (l1->len == l2->len && + memcmp(l1->name, l2->name, l1->len) == 0) num = i + 1; else break; @@ -443,6 +463,8 @@ lca_inner(ltree **a, int len) ptr++; } + /* Now compute size of result ... */ + reslen = LTREE_HDRSIZE; l1 = LTREE_FIRST(*a); for (i = 0; i < num; i++) { @@ -450,6 +472,7 @@ lca_inner(ltree **a, int len) l1 = LEVEL_NEXT(l1); } + /* ... and construct it by copying from *a */ res = (ltree *) palloc0(reslen); SET_VARSIZE(res, reslen); res->numlevel = num; diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c index 56bf39d145b..054c5d93356 100644 --- a/contrib/ltree/ltxtquery_io.c +++ b/contrib/ltree/ltxtquery_io.c @@ -166,7 +166,7 @@ pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval } /* - * This function is used for query_txt parsing + * This function is used for query text parsing */ static void pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag) @@ -368,7 +368,7 @@ queryin(char *buf) state.str = tmp; } - /* set user friendly-operand view */ + /* set user-friendly operand view */ memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen); pfree(state.op); diff --git a/contrib/ltree/sql/ltree.sql b/contrib/ltree/sql/ltree.sql index e9f74909a64..846b04e48ee 100644 --- a/contrib/ltree/sql/ltree.sql +++ b/contrib/ltree/sql/ltree.sql @@ -54,6 +54,9 @@ SELECT lca('{la.2.3,1.2.3.4.5.6,""}') IS NULL; SELECT lca('{la.2.3,1.2.3.4.5.6}') IS NULL; SELECT lca('{1.la.2.3,1.2.3.4.5.6}'); SELECT lca('{1.2.3,1.2.3.4.5.6}'); +SELECT lca('{1.2.3}'); +SELECT lca('{1}'), lca('{1}') IS NULL; +SELECT lca('{}') IS NULL; SELECT lca('1.la.2.3','1.2.3.4.5.6'); SELECT lca('1.2.3','1.2.3.4.5.6'); SELECT lca('1.2.2.3','1.2.3.4.5.6'); diff --git a/contrib/ltree_plpython/Makefile b/contrib/ltree_plpython/Makefile index 7e988c79935..ce2c0cd2e2f 100644 --- a/contrib/ltree_plpython/Makefile +++ b/contrib/ltree_plpython/Makefile @@ -4,19 +4,21 @@ MODULE_big = ltree_plpython$(python_majorversion) OBJS = ltree_plpython.o $(WIN32RES) PGFILEDESC = "ltree_plpython - ltree transform for plpython" -PG_CPPFLAGS = -I$(top_srcdir)/src/pl/plpython $(python_includespec) -I$(top_srcdir)/contrib/ltree -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"' - EXTENSION = ltree_plpythonu ltree_plpython2u ltree_plpython3u DATA = ltree_plpythonu--1.0.sql ltree_plpython2u--1.0.sql ltree_plpython3u--1.0.sql REGRESS = ltree_plpython REGRESS_PLPYTHON3_MANGLE := $(REGRESS) +PG_CPPFLAGS = $(python_includespec) -DPLPYTHON_LIBNAME='"plpython$(python_majorversion)"' + ifdef USE_PGXS +PG_CPPFLAGS += -I$(includedir_server)/extension PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else +PG_CPPFLAGS += -I$(top_srcdir)/src/pl/plpython -I$(top_srcdir)/contrib subdir = contrib/ltree_plpython top_builddir = ../.. include $(top_builddir)/src/Makefile.global diff --git a/contrib/ltree_plpython/ltree_plpython.c b/contrib/ltree_plpython/ltree_plpython.c index e88636a0a96..b254aa558d1 100644 --- a/contrib/ltree_plpython/ltree_plpython.c +++ b/contrib/ltree_plpython/ltree_plpython.c @@ -2,7 +2,7 @@ #include "fmgr.h" #include "plpython.h" -#include "ltree.h" +#include "ltree/ltree.h" PG_MODULE_MAGIC; diff --git a/contrib/oid2name/.gitignore b/contrib/oid2name/.gitignore index fdefde108dd..0410fb7afad 100644 --- a/contrib/oid2name/.gitignore +++ b/contrib/oid2name/.gitignore @@ -1 +1,3 @@ /oid2name + +/tmp_check/ diff --git a/contrib/oid2name/Makefile b/contrib/oid2name/Makefile index 3eef8f60bea..361a80a7a12 100644 --- a/contrib/oid2name/Makefile +++ b/contrib/oid2name/Makefile @@ -6,6 +6,8 @@ PGAPPICON = win32 PROGRAM = oid2name OBJS = oid2name.o $(WIN32RES) +TAP_TESTS = 1 + PG_CPPFLAGS = -I$(libpq_srcdir) PG_LIBS_INTERNAL = $(libpq_pgport) diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c index 63e360c4c56..fa1e7959e77 100644 --- a/contrib/oid2name/oid2name.c +++ b/contrib/oid2name/oid2name.c @@ -11,9 +11,12 @@ #include "catalog/pg_class_d.h" +#include "common/logging.h" #include "fe_utils/connect.h" #include "libpq-fe.h" #include "pg_getopt.h" +#include "getopt_long.h" + /* an extensible array to keep track of elements to show */ typedef struct @@ -60,9 +63,30 @@ void sql_exec_dumpalltbspc(PGconn *, struct options *); void get_opts(int argc, char **argv, struct options *my_opts) { + static struct option long_options[] = { + {"dbname", required_argument, NULL, 'd'}, + {"host", required_argument, NULL, 'h'}, + {"host", required_argument, NULL, 'H'}, /* deprecated */ + {"filenode", required_argument, NULL, 'f'}, + {"indexes", no_argument, NULL, 'i'}, + {"oid", required_argument, NULL, 'o'}, + {"port", required_argument, NULL, 'p'}, + {"quiet", no_argument, NULL, 'q'}, + {"tablespaces", no_argument, NULL, 's'}, + {"system-objects", no_argument, NULL, 'S'}, + {"table", required_argument, NULL, 't'}, + {"username", required_argument, NULL, 'U'}, + {"version", no_argument, NULL, 'V'}, + {"extended", no_argument, NULL, 'x'}, + {"help", no_argument, NULL, '?'}, + {NULL, 0, NULL, 0} + }; + int c; const char *progname; + int optindex; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); /* set the defaults */ @@ -93,7 +117,7 @@ get_opts(int argc, char **argv, struct options *my_opts) } /* get opts */ - while ((c = getopt(argc, argv, "H:p:U:d:t:o:f:qSxish")) != -1) + while ((c = getopt_long(argc, argv, "d:f:h:H:io:p:qsSt:U:x", long_options, &optindex)) != -1) { switch (c) { @@ -102,39 +126,40 @@ get_opts(int argc, char **argv, struct options *my_opts) my_opts->dbname = pg_strdup(optarg); break; - /* specify one tablename to show */ - case 't': - add_one_elt(optarg, my_opts->tables); - break; - - /* specify one Oid to show */ - case 'o': - add_one_elt(optarg, my_opts->oids); - break; - /* specify one filenode to show */ case 'f': add_one_elt(optarg, my_opts->filenodes); break; - /* don't show headers */ - case 'q': - my_opts->quiet = true; - break; - /* host to connect to */ - case 'H': + case 'H': /* deprecated */ + case 'h': my_opts->hostname = pg_strdup(optarg); break; + /* also display indexes */ + case 'i': + my_opts->indexes = true; + break; + + /* specify one Oid to show */ + case 'o': + add_one_elt(optarg, my_opts->oids); + break; + /* port to connect to on remote host */ case 'p': my_opts->port = pg_strdup(optarg); break; - /* username */ - case 'U': - my_opts->username = pg_strdup(optarg); + /* don't show headers */ + case 'q': + my_opts->quiet = true; + break; + + /* dump tablespaces only */ + case 's': + my_opts->tablespaces = true; break; /* display system tables */ @@ -142,9 +167,14 @@ get_opts(int argc, char **argv, struct options *my_opts) my_opts->systables = true; break; - /* also display indexes */ - case 'i': - my_opts->indexes = true; + /* specify one tablename to show */ + case 't': + add_one_elt(optarg, my_opts->tables); + break; + + /* username */ + case 'U': + my_opts->username = pg_strdup(optarg); break; /* display extra columns */ @@ -152,21 +182,19 @@ get_opts(int argc, char **argv, struct options *my_opts) my_opts->extended = true; break; - /* dump tablespaces only */ - case 's': - my_opts->tablespaces = true; - break; - - case 'h': - help(progname); - exit(0); - break; - default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } } + + if (optind < argc) + { + fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), + progname, argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } } static void @@ -176,22 +204,24 @@ help(const char *progname) "Usage:\n" " %s [OPTION]...\n" "\nOptions:\n" - " -d DBNAME database to connect to\n" - " -f FILENODE show info for table with given file node\n" - " -H HOSTNAME database server host or socket directory\n" - " -i show indexes and sequences too\n" - " -o OID show info for table with given OID\n" - " -p PORT database server port number\n" - " -q quiet (don't show headers)\n" - " -s show all tablespaces\n" - " -S show system objects too\n" - " -t TABLE show info for named table\n" - " -U NAME connect as specified database user\n" - " -V, --version output version information, then exit\n" - " -x extended (show additional columns)\n" - " -?, --help show this help, then exit\n" + " -f, --filenode=FILENODE show info for table with given file node\n" + " -i, --indexes show indexes and sequences too\n" + " -o, --oid=OID show info for table with given OID\n" + " -q, --quiet quiet (don't show headers)\n" + " -s, --tablespaces show all tablespaces\n" + " -S, --system-objects show system objects too\n" + " -t, --table=TABLE show info for named table\n" + " -V, --version output version information, then exit\n" + " -x, --extended extended (show additional columns)\n" + " -?, --help show this help, then exit\n" + "\nConnection options:\n" + " -d, --dbname=DBNAME database to connect to\n" + " -h, --host=HOSTNAME database server host or socket directory\n" + " -H same as -h, deprecated option\n" + " -p, --port=PORT database server port number\n" + " -U, --username=USERNAME connect as specified database user\n" "\nThe default action is to show all database OIDs.\n\n" - "Report bugs to .\n", + "Report bugs to .\n", progname, progname); } @@ -300,8 +330,8 @@ sql_conn(struct options *my_opts) if (!conn) { - fprintf(stderr, "%s: could not connect to database %s\n", - "oid2name", my_opts->dbname); + pg_log_error("could not connect to database %s", + my_opts->dbname); exit(1); } @@ -319,8 +349,8 @@ sql_conn(struct options *my_opts) /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr, "%s: could not connect to database %s: %s", - "oid2name", my_opts->dbname, PQerrorMessage(conn)); + pg_log_error("could not connect to database %s: %s", + my_opts->dbname, PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -328,8 +358,8 @@ sql_conn(struct options *my_opts) res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, "oid2name: could not clear search_path: %s\n", - PQerrorMessage(conn)); + pg_log_error("could not clear search_path: %s", + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); exit(-1); @@ -362,8 +392,8 @@ sql_exec(PGconn *conn, const char *todo, bool quiet) /* check and deal with errors */ if (!res || PQresultStatus(res) > 2) { - fprintf(stderr, "oid2name: query failed: %s\n", PQerrorMessage(conn)); - fprintf(stderr, "oid2name: query was: %s\n", todo); + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_error("query was: %s", todo); PQclear(res); PQfinish(conn); diff --git a/contrib/oid2name/t/001_basic.pl b/contrib/oid2name/t/001_basic.pl new file mode 100644 index 00000000000..fa2c5743f63 --- /dev/null +++ b/contrib/oid2name/t/001_basic.pl @@ -0,0 +1,12 @@ +use strict; +use warnings; + +use TestLib; +use Test::More tests => 8; + +######################################### +# Basic checks + +program_help_ok('oid2name'); +program_version_ok('oid2name'); +program_options_handling_ok('oid2name'); diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile index e5a581f141b..cfe01297fb0 100644 --- a/contrib/pageinspect/Makefile +++ b/contrib/pageinspect/Makefile @@ -5,7 +5,7 @@ OBJS = rawpage.o heapfuncs.o btreefuncs.o fsmfuncs.o \ brinfuncs.o ginfuncs.o hashfuncs.o $(WIN32RES) EXTENSION = pageinspect -DATA = pageinspect--1.6--1.7.sql \ +DATA = pageinspect--1.7--1.8.sql pageinspect--1.6--1.7.sql \ pageinspect--1.5.sql pageinspect--1.5--1.6.sql \ pageinspect--1.4--1.5.sql pageinspect--1.3--1.4.sql \ pageinspect--1.2--1.3.sql pageinspect--1.1--1.2.sql \ diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c index f4f0dea860f..04140eccb84 100644 --- a/contrib/pageinspect/brinfuncs.c +++ b/contrib/pageinspect/brinfuncs.c @@ -2,7 +2,7 @@ * brinfuncs.c * Functions to investigate BRIN indexes * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/brinfuncs.c @@ -41,7 +41,7 @@ typedef struct brin_column_state static Page verify_brin_page(bytea *raw_page, uint16 type, - const char *strtype); + const char *strtype); Datum brin_page_type(PG_FUNCTION_ARGS) diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index 558a8c41f49..8d27c9b0f6f 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -30,6 +30,7 @@ #include "pageinspect.h" #include "access/nbtree.h" +#include "access/relation.h" #include "catalog/namespace.h" #include "catalog/pg_am.h" #include "funcapi.h" @@ -429,7 +430,7 @@ bt_page_items_bytea(PG_FUNCTION_ARGS) if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be superuser to use pageinspect functions")))); + (errmsg("must be superuser to use raw page functions")))); if (SRF_IS_FIRSTCALL()) { @@ -560,10 +561,10 @@ bt_metap(PG_FUNCTION_ARGS) * Get values of extended metadata if available, use default values * otherwise. */ - if (metad->btm_version == BTREE_VERSION) + if (metad->btm_version >= BTREE_NOVAC_VERSION) { values[j++] = psprintf("%u", metad->btm_oldest_btpo_xact); - values[j++] = psprintf("%lf", metad->btm_last_cleanup_num_heap_tuples); + values[j++] = psprintf("%f", metad->btm_last_cleanup_num_heap_tuples); } else { diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out index 2aaa4df53b1..07c2dcd7714 100644 --- a/contrib/pageinspect/expected/btree.out +++ b/contrib/pageinspect/expected/btree.out @@ -5,7 +5,7 @@ CREATE INDEX test1_a_idx ON test1 USING btree (a); SELECT * FROM bt_metap('test1_a_idx'); -[ RECORD 1 ]-----------+------- magic | 340322 -version | 3 +version | 4 root | 1 level | 0 fastroot | 1 diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out index 5edb6500859..b6aea0124bb 100644 --- a/contrib/pageinspect/expected/page.out +++ b/contrib/pageinspect/expected/page.out @@ -82,11 +82,113 @@ SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); (1 row) +-- If we freeze the only tuple on test1, the infomask should +-- always be the same in all test runs. we show raw flags by +-- default: HEAP_XMIN_COMMITTED and HEAP_XMIN_INVALID. +VACUUM FREEZE test1; +SELECT t_infomask, t_infomask2, raw_flags, combined_flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); + t_infomask | t_infomask2 | raw_flags | combined_flags +------------+-------------+-----------------------------------------------------------+-------------------- + 2816 | 2 | {HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_XMAX_INVALID} | {HEAP_XMIN_FROZEN} +(1 row) + +-- output the decoded flag HEAP_XMIN_FROZEN instead +SELECT t_infomask, t_infomask2, raw_flags, combined_flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); + t_infomask | t_infomask2 | raw_flags | combined_flags +------------+-------------+-----------------------------------------------------------+-------------------- + 2816 | 2 | {HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID,HEAP_XMAX_INVALID} | {HEAP_XMIN_FROZEN} +(1 row) + +-- tests for decoding of combined flags +-- HEAP_XMAX_SHR_LOCK = (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK) +SELECT * FROM heap_tuple_infomask_flags(x'0050'::int, 0); + raw_flags | combined_flags +---------------------------------------------+---------------------- + {HEAP_XMAX_KEYSHR_LOCK,HEAP_XMAX_EXCL_LOCK} | {HEAP_XMAX_SHR_LOCK} +(1 row) + +-- HEAP_XMIN_FROZEN = (HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID) +SELECT * FROM heap_tuple_infomask_flags(x'0300'::int, 0); + raw_flags | combined_flags +-----------------------------------------+-------------------- + {HEAP_XMIN_COMMITTED,HEAP_XMIN_INVALID} | {HEAP_XMIN_FROZEN} +(1 row) + +-- HEAP_MOVED = (HEAP_MOVED_IN | HEAP_MOVED_OFF) +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); + raw_flags | combined_flags +--------------------------------+---------------- + {HEAP_MOVED_OFF,HEAP_MOVED_IN} | {HEAP_MOVED} +(1 row) + +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); + raw_flags | combined_flags +--------------------------------+---------------- + {HEAP_MOVED_OFF,HEAP_MOVED_IN} | {HEAP_MOVED} +(1 row) + +-- test all flags of t_infomask and t_infomask2 +SELECT unnest(raw_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; + unnest +----------------------- + HEAP_COMBOCID + HEAP_HASEXTERNAL + HEAP_HASNULL + HEAP_HASOID_OLD + HEAP_HASVARWIDTH + HEAP_HOT_UPDATED + HEAP_KEYS_UPDATED + HEAP_MOVED_IN + HEAP_MOVED_OFF + HEAP_ONLY_TUPLE + HEAP_UPDATED + HEAP_XMAX_COMMITTED + HEAP_XMAX_EXCL_LOCK + HEAP_XMAX_INVALID + HEAP_XMAX_IS_MULTI + HEAP_XMAX_KEYSHR_LOCK + HEAP_XMAX_LOCK_ONLY + HEAP_XMIN_COMMITTED + HEAP_XMIN_INVALID +(19 rows) + +SELECT unnest(combined_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; + unnest +-------------------- + HEAP_MOVED + HEAP_XMAX_SHR_LOCK + HEAP_XMIN_FROZEN +(3 rows) + +-- no flags at all +SELECT * FROM heap_tuple_infomask_flags(0, 0); + raw_flags | combined_flags +-----------+---------------- + {} | {} +(1 row) + +-- no combined flags +SELECT * FROM heap_tuple_infomask_flags(x'0010'::int, 0); + raw_flags | combined_flags +-------------------------+---------------- + {HEAP_XMAX_KEYSHR_LOCK} | {} +(1 row) + DROP TABLE test1; --- check that using any of these functions with a partitioned table would fail +-- check that using any of these functions with a partitioned table or index +-- would fail create table test_partitioned (a int) partition by range (a); +create index test_partitioned_index on test_partitioned (a); select get_raw_page('test_partitioned', 0); -- error about partitioned table ERROR: cannot get raw page from partitioned table "test_partitioned" +select get_raw_page('test_partitioned_index', 0); -- error about partitioned index +ERROR: cannot get raw page from partitioned index "test_partitioned_index" -- a regular table which is a member of a partition set should work though create table test_part1 partition of test_partitioned for values from ( 1 ) to (100); select get_raw_page('test_part1', 0); -- get farther and error about empty table diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c index 86e8075845e..4b3c5968184 100644 --- a/contrib/pageinspect/fsmfuncs.c +++ b/contrib/pageinspect/fsmfuncs.c @@ -9,7 +9,7 @@ * there's hardly any use case for using these without superuser-rights * anyway. * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/fsmfuncs.c diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c index d42609c5777..229f9f9a2ee 100644 --- a/contrib/pageinspect/ginfuncs.c +++ b/contrib/pageinspect/ginfuncs.c @@ -2,7 +2,7 @@ * ginfuncs.c * Functions to investigate the content of GIN indexes * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/ginfuncs.c diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c index 99b61b8669f..9374c4aabc4 100644 --- a/contrib/pageinspect/hashfuncs.c +++ b/contrib/pageinspect/hashfuncs.c @@ -2,7 +2,7 @@ * hashfuncs.c * Functions to investigate the content of HASH indexes * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/hashfuncs.c @@ -18,7 +18,9 @@ #include "catalog/pg_am.h" #include "funcapi.h" #include "miscadmin.h" +#include "utils/array.h" #include "utils/builtins.h" +#include "utils/rel.h" PG_FUNCTION_INFO_V1(hash_page_type); PG_FUNCTION_INFO_V1(hash_page_stats); @@ -96,18 +98,22 @@ verify_hash_page(bytea *raw_page, int flags) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("page is not a hash meta page"))); + break; case LH_BUCKET_PAGE | LH_OVERFLOW_PAGE: ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("page is not a hash bucket or overflow page"))); + break; case LH_OVERFLOW_PAGE: ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("page is not a hash overflow page"))); + break; default: elog(ERROR, "hash page of type %08x not in mask %08x", pagetype, flags); + break; } } diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c index 7438257c5bb..02e2ab9997a 100644 --- a/contrib/pageinspect/heapfuncs.c +++ b/contrib/pageinspect/heapfuncs.c @@ -15,7 +15,7 @@ * there's hardly any use case for using these without superuser-rights * anyway. * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/heapfuncs.c @@ -28,13 +28,29 @@ #include "pageinspect.h" #include "access/htup_details.h" +#include "access/relation.h" #include "funcapi.h" +#include "catalog/pg_am_d.h" #include "catalog/pg_type.h" #include "miscadmin.h" +#include "port/pg_bitutils.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/rel.h" +/* + * It's not supported to create tuples with oids anymore, but when pg_upgrade + * was used to upgrade from an older version, tuples might still have an + * oid. Seems worthwhile to display that. + */ +#define HeapTupleHeaderGetOidOld(tup) \ +( \ + ((tup)->t_infomask & HEAP_HASOID_OLD) ? \ + *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ + : \ + InvalidOid \ +) + /* * bits_to_text @@ -241,8 +257,8 @@ heap_page_items(PG_FUNCTION_ARGS) else nulls[11] = true; - if (tuphdr->t_infomask & HEAP_HASOID) - values[12] = HeapTupleHeaderGetOid(tuphdr); + if (tuphdr->t_infomask & HEAP_HASOID_OLD) + values[12] = HeapTupleHeaderGetOidOld(tuphdr); else nulls[12] = true; } @@ -298,13 +314,16 @@ tuple_data_split_internal(Oid relid, char *tupdata, TupleDesc tupdesc; /* Get tuple descriptor from relation OID */ - rel = relation_open(relid, NoLock); - tupdesc = CreateTupleDescCopyConstr(rel->rd_att); - relation_close(rel, NoLock); + rel = relation_open(relid, AccessShareLock); + tupdesc = RelationGetDescr(rel); raw_attrs = initArrayResult(BYTEAOID, CurrentMemoryContext, false); nattrs = tupdesc->natts; + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); + if (nattrs < (t_infomask2 & HEAP_NATTS_MASK)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), @@ -317,7 +336,6 @@ tuple_data_split_internal(Oid relid, char *tupdata, bytea *attr_data = NULL; attr = TupleDescAttr(tupdesc, i); - is_null = (t_infomask & HEAP_HASNULL) && att_isnull(i, t_bits); /* * Tuple header can specify less attributes than tuple descriptor as @@ -327,6 +345,8 @@ tuple_data_split_internal(Oid relid, char *tupdata, */ if (i >= (t_infomask2 & HEAP_NATTS_MASK)) is_null = true; + else + is_null = (t_infomask & HEAP_HASNULL) && att_isnull(i, t_bits); if (!is_null) { @@ -386,6 +406,8 @@ tuple_data_split_internal(Oid relid, char *tupdata, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("end of tuple reached without looking at all its data"))); + relation_close(rel, AccessShareLock); + return makeArrayResult(raw_attrs, CurrentMemoryContext); } @@ -473,3 +495,129 @@ tuple_data_split(PG_FUNCTION_ARGS) PG_RETURN_ARRAYTYPE_P(res); } + +/* + * heap_tuple_infomask_flags + * + * Decode into a human-readable format t_infomask and t_infomask2 associated + * to a tuple. All the flags are described in access/htup_details.h. + */ +PG_FUNCTION_INFO_V1(heap_tuple_infomask_flags); + +Datum +heap_tuple_infomask_flags(PG_FUNCTION_ARGS) +{ +#define HEAP_TUPLE_INFOMASK_COLS 2 + Datum values[HEAP_TUPLE_INFOMASK_COLS]; + bool nulls[HEAP_TUPLE_INFOMASK_COLS]; + uint16 t_infomask = PG_GETARG_INT16(0); + uint16 t_infomask2 = PG_GETARG_INT16(1); + int cnt = 0; + ArrayType *a; + int bitcnt; + Datum *flags; + TupleDesc tupdesc; + HeapTuple tuple; + + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to use raw page functions"))); + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + bitcnt = pg_popcount((const char *) &t_infomask, sizeof(uint16)) + + pg_popcount((const char *) &t_infomask2, sizeof(uint16)); + + /* Initialize values and NULL flags arrays */ + MemSet(values, 0, sizeof(values)); + MemSet(nulls, 0, sizeof(nulls)); + + /* If no flags, return a set of empty arrays */ + if (bitcnt <= 0) + { + values[0] = PointerGetDatum(construct_empty_array(TEXTOID)); + values[1] = PointerGetDatum(construct_empty_array(TEXTOID)); + tuple = heap_form_tuple(tupdesc, values, nulls); + PG_RETURN_DATUM(HeapTupleGetDatum(tuple)); + } + + /* build set of raw flags */ + flags = (Datum *) palloc0(sizeof(Datum) * bitcnt); + + /* decode t_infomask */ + if ((t_infomask & HEAP_HASNULL) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_HASNULL"); + if ((t_infomask & HEAP_HASVARWIDTH) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_HASVARWIDTH"); + if ((t_infomask & HEAP_HASEXTERNAL) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_HASEXTERNAL"); + if ((t_infomask & HEAP_HASOID_OLD) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_HASOID_OLD"); + if ((t_infomask & HEAP_XMAX_KEYSHR_LOCK) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_KEYSHR_LOCK"); + if ((t_infomask & HEAP_COMBOCID) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_COMBOCID"); + if ((t_infomask & HEAP_XMAX_EXCL_LOCK) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_EXCL_LOCK"); + if ((t_infomask & HEAP_XMAX_LOCK_ONLY) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_LOCK_ONLY"); + if ((t_infomask & HEAP_XMIN_COMMITTED) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_COMMITTED"); + if ((t_infomask & HEAP_XMIN_INVALID) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_INVALID"); + if ((t_infomask & HEAP_XMAX_COMMITTED) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_COMMITTED"); + if ((t_infomask & HEAP_XMAX_INVALID) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_INVALID"); + if ((t_infomask & HEAP_XMAX_IS_MULTI) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_IS_MULTI"); + if ((t_infomask & HEAP_UPDATED) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_UPDATED"); + if ((t_infomask & HEAP_MOVED_OFF) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_MOVED_OFF"); + if ((t_infomask & HEAP_MOVED_IN) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_MOVED_IN"); + + /* decode t_infomask2 */ + if ((t_infomask2 & HEAP_KEYS_UPDATED) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_KEYS_UPDATED"); + if ((t_infomask2 & HEAP_HOT_UPDATED) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_HOT_UPDATED"); + if ((t_infomask2 & HEAP_ONLY_TUPLE) != 0) + flags[cnt++] = CStringGetTextDatum("HEAP_ONLY_TUPLE"); + + /* build value */ + Assert(cnt <= bitcnt); + a = construct_array(flags, cnt, TEXTOID, -1, false, 'i'); + values[0] = PointerGetDatum(a); + + /* + * Build set of combined flags. Use the same array as previously, this + * keeps the code simple. + */ + cnt = 0; + MemSet(flags, 0, sizeof(Datum) * bitcnt); + + /* decode combined masks of t_infomask */ + if ((t_infomask & HEAP_XMAX_SHR_LOCK) == HEAP_XMAX_SHR_LOCK) + flags[cnt++] = CStringGetTextDatum("HEAP_XMAX_SHR_LOCK"); + if ((t_infomask & HEAP_XMIN_FROZEN) == HEAP_XMIN_FROZEN) + flags[cnt++] = CStringGetTextDatum("HEAP_XMIN_FROZEN"); + if ((t_infomask & HEAP_MOVED) == HEAP_MOVED) + flags[cnt++] = CStringGetTextDatum("HEAP_MOVED"); + + /* Build an empty array if there are no combined flags */ + if (cnt == 0) + a = construct_empty_array(TEXTOID); + else + a = construct_array(flags, cnt, TEXTOID, -1, false, 'i'); + pfree(flags); + values[1] = PointerGetDatum(a); + + /* Returns the record as Datum */ + tuple = heap_form_tuple(tupdesc, values, nulls); + PG_RETURN_DATUM(HeapTupleGetDatum(tuple)); +} diff --git a/contrib/pageinspect/pageinspect--1.7--1.8.sql b/contrib/pageinspect/pageinspect--1.7--1.8.sql new file mode 100644 index 00000000000..2a7c4b35165 --- /dev/null +++ b/contrib/pageinspect/pageinspect--1.7--1.8.sql @@ -0,0 +1,16 @@ +/* contrib/pageinspect/pageinspect--1.7--1.8.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pageinspect UPDATE TO '1.8'" to load this file. \quit + +-- +-- heap_tuple_infomask_flags() +-- +CREATE FUNCTION heap_tuple_infomask_flags( + t_infomask integer, + t_infomask2 integer, + raw_flags OUT text[], + combined_flags OUT text[]) +RETURNS record +AS 'MODULE_PATHNAME', 'heap_tuple_infomask_flags' +LANGUAGE C STRICT PARALLEL SAFE; diff --git a/contrib/pageinspect/pageinspect.control b/contrib/pageinspect/pageinspect.control index dcfc61f22dc..f8cdf526c65 100644 --- a/contrib/pageinspect/pageinspect.control +++ b/contrib/pageinspect/pageinspect.control @@ -1,5 +1,5 @@ # pageinspect extension comment = 'inspect the contents of database pages at a low level' -default_version = '1.7' +default_version = '1.8' module_pathname = '$libdir/pageinspect' relocatable = true diff --git a/contrib/pageinspect/pageinspect.h b/contrib/pageinspect/pageinspect.h index ab7d5d66cd1..0a660ad6254 100644 --- a/contrib/pageinspect/pageinspect.h +++ b/contrib/pageinspect/pageinspect.h @@ -3,7 +3,7 @@ * pageinspect.h * Common functions for pageinspect. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/pageinspect.h diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 72f1d21e1b7..f08f62f72da 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -5,7 +5,7 @@ * * Access-method specific inspection functions are in separate files. * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pageinspect/rawpage.c @@ -18,6 +18,7 @@ #include "pageinspect.h" #include "access/htup_details.h" +#include "access/relation.h" #include "catalog/namespace.h" #include "catalog/pg_type.h" #include "funcapi.h" @@ -32,7 +33,7 @@ PG_MODULE_MAGIC; static bytea *get_raw_page_internal(text *relname, ForkNumber forknum, - BlockNumber blkno); + BlockNumber blkno); /* @@ -102,7 +103,7 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno) if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be superuser to use raw functions")))); + (errmsg("must be superuser to use raw page functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); @@ -128,6 +129,11 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno) (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot get raw page from partitioned table \"%s\"", RelationGetRelationName(rel)))); + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot get raw page from partitioned index \"%s\"", + RelationGetRelationName(rel)))); /* * Reject attempts to read non-local temporary relations; we would be diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql index 8f35830e067..bd049aeb247 100644 --- a/contrib/pageinspect/sql/page.sql +++ b/contrib/pageinspect/sql/page.sql @@ -31,11 +31,48 @@ SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bi SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); +-- If we freeze the only tuple on test1, the infomask should +-- always be the same in all test runs. we show raw flags by +-- default: HEAP_XMIN_COMMITTED and HEAP_XMIN_INVALID. +VACUUM FREEZE test1; + +SELECT t_infomask, t_infomask2, raw_flags, combined_flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); + +-- output the decoded flag HEAP_XMIN_FROZEN instead +SELECT t_infomask, t_infomask2, raw_flags, combined_flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); + +-- tests for decoding of combined flags +-- HEAP_XMAX_SHR_LOCK = (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK) +SELECT * FROM heap_tuple_infomask_flags(x'0050'::int, 0); +-- HEAP_XMIN_FROZEN = (HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID) +SELECT * FROM heap_tuple_infomask_flags(x'0300'::int, 0); +-- HEAP_MOVED = (HEAP_MOVED_IN | HEAP_MOVED_OFF) +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); + +-- test all flags of t_infomask and t_infomask2 +SELECT unnest(raw_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; +SELECT unnest(combined_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; + +-- no flags at all +SELECT * FROM heap_tuple_infomask_flags(0, 0); +-- no combined flags +SELECT * FROM heap_tuple_infomask_flags(x'0010'::int, 0); + DROP TABLE test1; --- check that using any of these functions with a partitioned table would fail +-- check that using any of these functions with a partitioned table or index +-- would fail create table test_partitioned (a int) partition by range (a); +create index test_partitioned_index on test_partitioned (a); select get_raw_page('test_partitioned', 0); -- error about partitioned table +select get_raw_page('test_partitioned_index', 0); -- error about partitioned index -- a regular table which is a member of a partition set should work though create table test_part1 partition of test_partitioned for values from ( 1 ) to (100); diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c index d3d9ff36761..c3fb5a9c085 100644 --- a/contrib/passwordcheck/passwordcheck.c +++ b/contrib/passwordcheck/passwordcheck.c @@ -3,7 +3,7 @@ * passwordcheck.c * * - * Copyright (c) 2009-2018, PostgreSQL Global Development Group + * Copyright (c) 2009-2019, PostgreSQL Global Development Group * * Author: Laurenz Albe * @@ -26,10 +26,14 @@ PG_MODULE_MAGIC; +/* Saved hook value in case of unload */ +static check_password_hook_type prev_check_password_hook = NULL; + /* passwords shorter than this will be rejected */ #define MIN_PWD_LENGTH 8 extern void _PG_init(void); +extern void _PG_fini(void); /* * check_password @@ -55,6 +59,11 @@ check_password(const char *username, Datum validuntil_time, bool validuntil_null) { + if (prev_check_password_hook) + prev_check_password_hook(username, shadow_pass, + password_type, validuntil_time, + validuntil_null); + if (password_type != PASSWORD_TYPE_PLAINTEXT) { /* @@ -133,5 +142,16 @@ void _PG_init(void) { /* activate password checks when the module is loaded */ + prev_check_password_hook = check_password_hook; check_password_hook = check_password; } + +/* + * Module unload function + */ +void +_PG_fini(void) +{ + /* uninstall hook */ + check_password_hook = prev_check_password_hook; +} diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c index b410aafa5a9..1bd579fcbb0 100644 --- a/contrib/pg_buffercache/pg_buffercache_pages.c +++ b/contrib/pg_buffercache/pg_buffercache_pages.c @@ -99,7 +99,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS) elog(ERROR, "incorrect number of output arguments"); /* Construct a tuple descriptor for the result rows. */ - tupledesc = CreateTemplateTupleDesc(expected_tupledesc->natts, false); + tupledesc = CreateTemplateTupleDesc(expected_tupledesc->natts); TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid", INT4OID, -1, 0); TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode", diff --git a/contrib/pg_freespacemap/pg_freespacemap.c b/contrib/pg_freespacemap/pg_freespacemap.c index 7d939a7d207..b82cab2d97e 100644 --- a/contrib/pg_freespacemap/pg_freespacemap.c +++ b/contrib/pg_freespacemap/pg_freespacemap.c @@ -8,6 +8,7 @@ */ #include "postgres.h" +#include "access/relation.h" #include "funcapi.h" #include "storage/freespace.h" diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index bb28e237d17..38ae240c551 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -16,7 +16,7 @@ * relevant database in turn. The former keeps running after the * initial prewarm is complete to update the dump file periodically. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_prewarm/autoprewarm.c @@ -25,9 +25,10 @@ */ #include "postgres.h" + #include -#include "access/heapam.h" +#include "access/relation.h" #include "access/xact.h" #include "catalog/pg_class.h" #include "catalog/pg_type.h" @@ -73,9 +74,9 @@ typedef struct AutoPrewarmSharedState /* Following items are for communication with per-database worker */ dsm_handle block_info_handle; Oid database; - int64 prewarm_start_idx; - int64 prewarm_stop_idx; - int64 prewarmed_blocks; + int prewarm_start_idx; + int prewarm_stop_idx; + int prewarmed_blocks; } AutoPrewarmSharedState; void _PG_init(void); @@ -86,7 +87,7 @@ PG_FUNCTION_INFO_V1(autoprewarm_start_worker); PG_FUNCTION_INFO_V1(autoprewarm_dump_now); static void apw_load_buffers(void); -static int64 apw_dump_now(bool is_bgworker, bool dump_unlogged); +static int apw_dump_now(bool is_bgworker, bool dump_unlogged); static void apw_start_master_worker(void); static void apw_start_database_worker(void); static bool apw_init_shmem(void); @@ -180,8 +181,8 @@ autoprewarm_main(Datum main_arg) { LWLockRelease(&apw_state->lock); ereport(LOG, - (errmsg("autoprewarm worker is already running under PID %d", - apw_state->bgworker_pid))); + (errmsg("autoprewarm worker is already running under PID %lu", + (unsigned long) apw_state->bgworker_pid))); return; } apw_state->bgworker_pid = MyProcPid; @@ -206,8 +207,6 @@ autoprewarm_main(Datum main_arg) /* Periodically dump buffers until terminated. */ while (!got_sigterm) { - int rc; - /* In case of a SIGHUP, just reload the configuration. */ if (got_sighup) { @@ -218,10 +217,10 @@ autoprewarm_main(Datum main_arg) if (autoprewarm_interval <= 0) { /* We're only dumping at shutdown, so just wait forever. */ - rc = WaitLatch(&MyProc->procLatch, - WL_LATCH_SET | WL_POSTMASTER_DEATH, - -1L, - PG_WAIT_EXTENSION); + (void) WaitLatch(&MyProc->procLatch, + WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, + -1L, + PG_WAIT_EXTENSION); } else { @@ -247,16 +246,14 @@ autoprewarm_main(Datum main_arg) } /* Sleep until the next dump time. */ - rc = WaitLatch(&MyProc->procLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - delay_in_ms, - PG_WAIT_EXTENSION); + (void) WaitLatch(&MyProc->procLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + delay_in_ms, + PG_WAIT_EXTENSION); } - /* Reset the latch, bail out if postmaster died, otherwise loop. */ + /* Reset the latch, loop. */ ResetLatch(&MyProc->procLatch); - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); } /* @@ -274,7 +271,7 @@ static void apw_load_buffers(void) { FILE *file = NULL; - int64 num_elements, + int num_elements, i; BlockInfoRecord *blkinfo; dsm_segment *seg; @@ -290,8 +287,8 @@ apw_load_buffers(void) { LWLockRelease(&apw_state->lock); ereport(LOG, - (errmsg("skipping prewarm because block dump file is being written by PID %d", - apw_state->pid_using_dumpfile))); + (errmsg("skipping prewarm because block dump file is being written by PID %lu", + (unsigned long) apw_state->pid_using_dumpfile))); return; } LWLockRelease(&apw_state->lock); @@ -317,7 +314,7 @@ apw_load_buffers(void) } /* First line of the file is a record count. */ - if (fscanf(file, "<<" INT64_FORMAT ">>\n", &num_elements) != 1) + if (fscanf(file, "<<%d>>\n", &num_elements) != 1) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read from file \"%s\": %m", @@ -336,7 +333,7 @@ apw_load_buffers(void) &blkinfo[i].tablespace, &blkinfo[i].filenode, &forknum, &blkinfo[i].blocknum) != 5) ereport(ERROR, - (errmsg("autoprewarm block dump file is corrupted at line " INT64_FORMAT, + (errmsg("autoprewarm block dump file is corrupted at line %d", i + 1))); blkinfo[i].forknum = forknum; } @@ -355,40 +352,40 @@ apw_load_buffers(void) /* Get the info position of the first block of the next database. */ while (apw_state->prewarm_start_idx < num_elements) { - uint32 i = apw_state->prewarm_start_idx; - Oid current_db = blkinfo[i].database; + int j = apw_state->prewarm_start_idx; + Oid current_db = blkinfo[j].database; /* - * Advance the prewarm_stop_idx to the first BlockRecordInfo that does + * Advance the prewarm_stop_idx to the first BlockInfoRecord that does * not belong to this database. */ - i++; - while (i < num_elements) + j++; + while (j < num_elements) { - if (current_db != blkinfo[i].database) + if (current_db != blkinfo[j].database) { /* - * Combine BlockRecordInfos for global objects with those of + * Combine BlockInfoRecords for global objects with those of * the database. */ if (current_db != InvalidOid) break; - current_db = blkinfo[i].database; + current_db = blkinfo[j].database; } - i++; + j++; } /* * If we reach this point with current_db == InvalidOid, then only - * BlockRecordInfos belonging to global objects exist. We can't + * BlockInfoRecords belonging to global objects exist. We can't * prewarm without a database connection, so just bail out. */ if (current_db == InvalidOid) break; /* Configure stop point and database for next per-database worker. */ - apw_state->prewarm_stop_idx = i; + apw_state->prewarm_stop_idx = j; apw_state->database = current_db; Assert(apw_state->prewarm_start_idx < apw_state->prewarm_stop_idx); @@ -415,8 +412,7 @@ apw_load_buffers(void) /* Report our success. */ ereport(LOG, - (errmsg("autoprewarm successfully prewarmed " INT64_FORMAT - " of " INT64_FORMAT " previously-loaded blocks", + (errmsg("autoprewarm successfully prewarmed %d of %d previously-loaded blocks", apw_state->prewarmed_blocks, num_elements))); } @@ -427,7 +423,7 @@ apw_load_buffers(void) void autoprewarm_database_main(Datum main_arg) { - uint32 pos; + int pos; BlockInfoRecord *block_info; Relation rel = NULL; BlockNumber nblocks = 0; @@ -557,13 +553,14 @@ autoprewarm_database_main(Datum main_arg) * Dump information on blocks in shared buffers. We use a text format here * so that it's easy to understand and even change the file contents if * necessary. + * Returns the number of blocks dumped. */ -static int64 +static int apw_dump_now(bool is_bgworker, bool dump_unlogged) { - uint32 i; + int num_blocks; + int i; int ret; - int64 num_blocks; BlockInfoRecord *block_info_array; BufferDesc *bufHdr; FILE *file; @@ -580,12 +577,12 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) { if (!is_bgworker) ereport(ERROR, - (errmsg("could not perform block dump because dump file is being used by PID %d", - apw_state->pid_using_dumpfile))); + (errmsg("could not perform block dump because dump file is being used by PID %lu", + (unsigned long) apw_state->pid_using_dumpfile))); ereport(LOG, - (errmsg("skipping block dump because it is already being performed by PID %d", - apw_state->pid_using_dumpfile))); + (errmsg("skipping block dump because it is already being performed by PID %lu", + (unsigned long) apw_state->pid_using_dumpfile))); return 0; } @@ -630,7 +627,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) errmsg("could not open file \"%s\": %m", transient_dump_file_path))); - ret = fprintf(file, "<<" INT64_FORMAT ">>\n", num_blocks); + ret = fprintf(file, "<<%d>>\n", num_blocks); if (ret < 0) { int save_errno = errno; @@ -640,7 +637,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) errno = save_errno; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write to file \"%s\" : %m", + errmsg("could not write to file \"%s\": %m", transient_dump_file_path))); } @@ -663,7 +660,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) errno = save_errno; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write to file \"%s\" : %m", + errmsg("could not write to file \"%s\": %m", transient_dump_file_path))); } } @@ -683,7 +680,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) errno = save_errno; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not close file \"%s\" : %m", + errmsg("could not close file \"%s\": %m", transient_dump_file_path))); } @@ -691,8 +688,7 @@ apw_dump_now(bool is_bgworker, bool dump_unlogged) apw_state->pid_using_dumpfile = InvalidPid; ereport(DEBUG1, - (errmsg("wrote block details for " INT64_FORMAT " blocks", - num_blocks))); + (errmsg("wrote block details for %d blocks", num_blocks))); return num_blocks; } @@ -717,8 +713,8 @@ autoprewarm_start_worker(PG_FUNCTION_ARGS) if (pid != InvalidPid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("autoprewarm worker is already running under PID %d", - pid))); + errmsg("autoprewarm worker is already running under PID %lu", + (unsigned long) pid))); apw_start_master_worker(); @@ -727,11 +723,14 @@ autoprewarm_start_worker(PG_FUNCTION_ARGS) /* * SQL-callable function to perform an immediate block dump. + * + * Note: this is declared to return int8, as insurance against some + * very distant day when we might make NBuffers wider than int. */ Datum autoprewarm_dump_now(PG_FUNCTION_ARGS) { - int64 num_blocks; + int num_blocks; apw_init_shmem(); @@ -741,7 +740,7 @@ autoprewarm_dump_now(PG_FUNCTION_ARGS) } PG_END_ENSURE_ERROR_CLEANUP(apw_detach_shmem, 0); - PG_RETURN_INT64(num_blocks); + PG_RETURN_INT64((int64) num_blocks); } /* @@ -841,6 +840,7 @@ apw_start_database_worker(void) worker.bgw_flags = BGWORKER_SHMEM_ACCESS | BGWORKER_BACKEND_DATABASE_CONNECTION; worker.bgw_start_time = BgWorkerStart_ConsistentState; + worker.bgw_restart_time = BGW_NEVER_RESTART; strcpy(worker.bgw_library_name, "pg_prewarm"); strcpy(worker.bgw_function_name, "autoprewarm_database_main"); strcpy(worker.bgw_name, "autoprewarm worker"); @@ -869,7 +869,7 @@ do { \ return -1; \ else if (a->fld > b->fld) \ return 1; \ -} while(0); +} while(0) /* * apw_compare_blockinfo @@ -883,8 +883,8 @@ do { \ static int apw_compare_blockinfo(const void *p, const void *q) { - BlockInfoRecord *a = (BlockInfoRecord *) p; - BlockInfoRecord *b = (BlockInfoRecord *) q; + const BlockInfoRecord *a = (const BlockInfoRecord *) p; + const BlockInfoRecord *b = (const BlockInfoRecord *) q; cmp_member_elem(database); cmp_member_elem(tablespace); diff --git a/contrib/pg_prewarm/pg_prewarm.c b/contrib/pg_prewarm/pg_prewarm.c index 3cbb7c2b889..f3deb47a97b 100644 --- a/contrib/pg_prewarm/pg_prewarm.c +++ b/contrib/pg_prewarm/pg_prewarm.c @@ -3,7 +3,7 @@ * pg_prewarm.c * prewarming utilities * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_prewarm/pg_prewarm.c @@ -15,7 +15,7 @@ #include #include -#include "access/heapam.h" +#include "access/relation.h" #include "fmgr.h" #include "miscadmin.h" #include "storage/bufmgr.h" @@ -36,7 +36,7 @@ typedef enum PREWARM_BUFFER } PrewarmType; -static char blockbuffer[BLCKSZ]; +static PGAlignedBlock blockbuffer; /* * pg_prewarm(regclass, mode text, fork text, @@ -178,7 +178,7 @@ pg_prewarm(PG_FUNCTION_ARGS) for (block = first_block; block <= last_block; ++block) { CHECK_FOR_INTERRUPTS(); - smgrread(rel->rd_smgr, forkNumber, block, blockbuffer); + smgrread(rel->rd_smgr, forkNumber, block, blockbuffer.data); ++blocks_done; } } diff --git a/contrib/pg_standby/pg_standby.c b/contrib/pg_standby/pg_standby.c index cb785971a98..031b1b5cd58 100644 --- a/contrib/pg_standby/pg_standby.c +++ b/contrib/pg_standby/pg_standby.c @@ -58,7 +58,6 @@ char *triggerPath; /* where to find the trigger file? */ char *xlogFilePath; /* where we are going to restore to */ char *nextWALFileName; /* the file we need to get from archive */ char *restartWALFileName; /* the file from which we can restart restore */ -char *priorWALFileName; /* the file we need to get from archive */ char WALFilePath[MAXPGPATH * 2]; /* the file path including archive */ char restoreCommand[MAXPGPATH]; /* run this to restore */ char exclusiveCleanupFileName[MAXFNAMELEN]; /* the file we need to get @@ -94,7 +93,6 @@ int restoreCommandType; #define XLOG_DATA 0 #define XLOG_HISTORY 1 -#define XLOG_BACKUP_LABEL 2 int nextWALFileType; #define SET_RESTORE_COMMAND(cmd, arg1, arg2) \ @@ -116,7 +114,7 @@ static bool SetWALSegSize(void); * accessible directory. If you want to make other assumptions, * such as using a vendor-specific archive and access API, these * routines are the ones you'll need to change. You're - * encouraged to submit any changes to pgsql-hackers@postgresql.org + * encouraged to submit any changes to pgsql-hackers@lists.postgresql.org * or personally to the current maintainer. Those changes may be * folded in to later versions of this program. */ @@ -211,15 +209,9 @@ CustomizableNextWALFileReady(void) } /* - * If it's a backup file, return immediately. If it's a regular file - * return only if it's the right size already. + * Return only if it's the right size already. */ - if (IsBackupHistoryFileName(nextWALFileName)) - { - nextWALFileType = XLOG_BACKUP_LABEL; - return true; - } - else if (WalSegSz > 0 && stat_buf.st_size == WalSegSz) + if (WalSegSz > 0 && stat_buf.st_size == WalSegSz) { #ifdef WIN32 @@ -408,9 +400,7 @@ SetWALSegSize(void) { bool ret_val = false; int fd; - - /* malloc this buffer to ensure sufficient alignment: */ - char *buf = (char *) pg_malloc(XLOG_BLCKSZ); + PGAlignedXLogBlock buf; Assert(WalSegSz == -1); @@ -418,14 +408,13 @@ SetWALSegSize(void) { fprintf(stderr, "%s: could not open WAL file \"%s\": %s\n", progname, WALFilePath, strerror(errno)); - pg_free(buf); return false; } errno = 0; - if (read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ) + if (read(fd, buf.data, XLOG_BLCKSZ) == XLOG_BLCKSZ) { - XLogLongPageHeader longhdr = (XLogLongPageHeader) buf; + XLogLongPageHeader longhdr = (XLogLongPageHeader) buf.data; WalSegSz = longhdr->xlp_seg_size; @@ -462,7 +451,6 @@ SetWALSegSize(void) fflush(stderr); close(fd); - pg_free(buf); return ret_val; } @@ -622,11 +610,11 @@ usage(void) printf(" -w MAXWAITTIME max seconds to wait for a file (0=no limit) (default=0)\n"); printf(" -?, --help show this help, then exit\n"); printf("\n" - "Main intended use as restore_command in recovery.conf:\n" + "Main intended use as restore_command in postgresql.conf:\n" " restore_command = 'pg_standby [OPTION]... ARCHIVELOCATION %%f %%p %%r'\n" "e.g.\n" " restore_command = 'pg_standby /mnt/server/archiverdir %%f %%p %%r'\n"); - printf("\nReport bugs to .\n"); + printf("\nReport bugs to .\n"); } #ifndef WIN32 diff --git a/contrib/pg_stat_statements/Makefile b/contrib/pg_stat_statements/Makefile index 39b368b70eb..051ce46f0c5 100644 --- a/contrib/pg_stat_statements/Makefile +++ b/contrib/pg_stat_statements/Makefile @@ -4,7 +4,8 @@ MODULE_big = pg_stat_statements OBJS = pg_stat_statements.o $(WIN32RES) EXTENSION = pg_stat_statements -DATA = pg_stat_statements--1.4.sql pg_stat_statements--1.4--1.5.sql \ +DATA = pg_stat_statements--1.4.sql pg_stat_statements--1.6--1.7.sql \ + pg_stat_statements--1.5--1.6.sql pg_stat_statements--1.4--1.5.sql \ pg_stat_statements--1.3--1.4.sql pg_stat_statements--1.2--1.3.sql \ pg_stat_statements--1.1--1.2.sql pg_stat_statements--1.0--1.1.sql \ pg_stat_statements--unpackaged--1.0.sql diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out b/contrib/pg_stat_statements/expected/pg_stat_statements.out index 5318c3550c7..6787ec1efda 100644 --- a/contrib/pg_stat_statements/expected/pg_stat_statements.out +++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out @@ -354,6 +354,93 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; SELECT pg_stat_statements_reset() | 1 | 1 (5 rows) +-- +-- queries with locking clauses +-- +CREATE TABLE pgss_a (id integer PRIMARY KEY); +CREATE TABLE pgss_b (id integer PRIMARY KEY, a_id integer REFERENCES pgss_a); +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +-- control query +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id; + id | id | a_id +----+----+------ +(0 rows) + +-- test range tables +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_a; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_a, pgss_b; -- matches plain "FOR UPDATE" + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b, pgss_a; + id | id | a_id +----+----+------ +(0 rows) + +-- test strengths +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR NO KEY UPDATE; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR SHARE; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR KEY SHARE; + id | id | a_id +----+----+------ +(0 rows) + +-- test wait policies +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE NOWAIT; + id | id | a_id +----+----+------ +(0 rows) + +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE SKIP LOCKED; + id | id | a_id +----+----+------ +(0 rows) + +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + calls | query +-------+------------------------------------------------------------------------------------------ + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR KEY SHARE + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR NO KEY UPDATE + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR SHARE + 2 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE NOWAIT + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_a + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b, pgss_a + 1 | SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE SKIP LOCKED + 1 | SELECT pg_stat_statements_reset() +(11 rows) + +DROP TABLE pgss_a, pgss_b CASCADE; -- -- utility commands -- @@ -395,4 +482,202 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; SELECT pg_stat_statements_reset() | 1 | 1 (8 rows) +-- +-- Track user activity and reset them +-- +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + +CREATE ROLE regress_stats_user1; +CREATE ROLE regress_stats_user2; +SET ROLE regress_stats_user1; +SELECT 1 AS "ONE"; + ONE +----- + 1 +(1 row) + +SELECT 1+1 AS "TWO"; + TWO +----- + 2 +(1 row) + +RESET ROLE; +SET ROLE regress_stats_user2; +SELECT 1 AS "ONE"; + ONE +----- + 1 +(1 row) + +SELECT 1+1 AS "TWO"; + TWO +----- + 2 +(1 row) + +RESET ROLE; +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +-----------------------------------+-------+------ + CREATE ROLE regress_stats_user1 | 1 | 0 + CREATE ROLE regress_stats_user2 | 1 | 0 + RESET ROLE | 2 | 0 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT pg_stat_statements_reset() | 1 | 1 + SET ROLE regress_stats_user1 | 1 | 0 + SET ROLE regress_stats_user2 | 1 | 0 +(10 rows) + +-- +-- Don't reset anything if any of the parameter is NULL +-- +SELECT pg_stat_statements_reset(NULL); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +------------------------------------------------------------------------------+-------+------ + CREATE ROLE regress_stats_user1 | 1 | 0 + CREATE ROLE regress_stats_user2 | 1 | 0 + RESET ROLE | 2 | 0 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT pg_stat_statements_reset($1) | 1 | 1 + SELECT pg_stat_statements_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 1 | 10 + SET ROLE regress_stats_user1 | 1 | 0 + SET ROLE regress_stats_user2 | 1 | 0 +(12 rows) + +-- +-- remove query ('SELECT $1+$2 AS "TWO"') executed by regress_stats_user2 +-- in the current_database +-- +SELECT pg_stat_statements_reset( + (SELECT r.oid FROM pg_roles AS r WHERE r.rolname = 'regress_stats_user2'), + (SELECT d.oid FROM pg_database As d where datname = current_database()), + (SELECT s.queryid FROM pg_stat_statements AS s + WHERE s.query = 'SELECT $1+$2 AS "TWO"' LIMIT 1)); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +----------------------------------------------------------------------------------+-------+------ + CREATE ROLE regress_stats_user1 | 1 | 0 + CREATE ROLE regress_stats_user2 | 1 | 0 + RESET ROLE | 2 | 0 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1 AS "ONE" | 1 | 1 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT pg_stat_statements_reset( +| 1 | 1 + (SELECT r.oid FROM pg_roles AS r WHERE r.rolname = $1), +| | + (SELECT d.oid FROM pg_database As d where datname = current_database()),+| | + (SELECT s.queryid FROM pg_stat_statements AS s +| | + WHERE s.query = $2 LIMIT $3)) | | + SELECT pg_stat_statements_reset($1) | 1 | 1 + SELECT pg_stat_statements_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 2 | 22 + SET ROLE regress_stats_user1 | 1 | 0 + SET ROLE regress_stats_user2 | 1 | 0 +(12 rows) + +-- +-- remove query ('SELECT $1 AS "ONE"') executed by two users +-- +SELECT pg_stat_statements_reset(0,0,s.queryid) + FROM pg_stat_statements AS s WHERE s.query = 'SELECT $1 AS "ONE"'; + pg_stat_statements_reset +-------------------------- + + +(2 rows) + +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +----------------------------------------------------------------------------------+-------+------ + CREATE ROLE regress_stats_user1 | 1 | 0 + CREATE ROLE regress_stats_user2 | 1 | 0 + RESET ROLE | 2 | 0 + SELECT $1+$2 AS "TWO" | 1 | 1 + SELECT pg_stat_statements_reset( +| 1 | 1 + (SELECT r.oid FROM pg_roles AS r WHERE r.rolname = $1), +| | + (SELECT d.oid FROM pg_database As d where datname = current_database()),+| | + (SELECT s.queryid FROM pg_stat_statements AS s +| | + WHERE s.query = $2 LIMIT $3)) | | + SELECT pg_stat_statements_reset($1) | 1 | 1 + SELECT pg_stat_statements_reset($1,$2,s.queryid) +| 1 | 2 + FROM pg_stat_statements AS s WHERE s.query = $3 | | + SELECT pg_stat_statements_reset() | 1 | 1 + SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 3 | 34 + SET ROLE regress_stats_user1 | 1 | 0 + SET ROLE regress_stats_user2 | 1 | 0 +(11 rows) + +-- +-- remove query of a user (regress_stats_user1) +-- +SELECT pg_stat_statements_reset(r.oid) + FROM pg_roles AS r WHERE r.rolname = 'regress_stats_user1'; + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +----------------------------------------------------------------------------------+-------+------ + CREATE ROLE regress_stats_user1 | 1 | 0 + CREATE ROLE regress_stats_user2 | 1 | 0 + RESET ROLE | 2 | 0 + SELECT pg_stat_statements_reset( +| 1 | 1 + (SELECT r.oid FROM pg_roles AS r WHERE r.rolname = $1), +| | + (SELECT d.oid FROM pg_database As d where datname = current_database()),+| | + (SELECT s.queryid FROM pg_stat_statements AS s +| | + WHERE s.query = $2 LIMIT $3)) | | + SELECT pg_stat_statements_reset($1) | 1 | 1 + SELECT pg_stat_statements_reset($1,$2,s.queryid) +| 1 | 2 + FROM pg_stat_statements AS s WHERE s.query = $3 | | + SELECT pg_stat_statements_reset() | 1 | 1 + SELECT pg_stat_statements_reset(r.oid) +| 1 | 1 + FROM pg_roles AS r WHERE r.rolname = $1 | | + SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C" | 4 | 45 + SET ROLE regress_stats_user2 | 1 | 0 +(10 rows) + +-- +-- reset all +-- +SELECT pg_stat_statements_reset(0,0,0); + pg_stat_statements_reset +-------------------------- + +(1 row) + +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + query | calls | rows +----------------------------------------+-------+------ + SELECT pg_stat_statements_reset(0,0,0) | 1 | 1 +(1 row) + +-- +-- cleanup +-- +DROP ROLE regress_stats_user1; +DROP ROLE regress_stats_user2; DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.5--1.6.sql b/contrib/pg_stat_statements/pg_stat_statements--1.5--1.6.sql new file mode 100644 index 00000000000..4f8c7f7ee8a --- /dev/null +++ b/contrib/pg_stat_statements/pg_stat_statements--1.5--1.6.sql @@ -0,0 +1,7 @@ +/* contrib/pg_stat_statements/pg_stat_statements--1.5--1.6.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.6'" to load this file. \quit + +-- Execution is only allowed for superusers, fixing issue with 1.5. +REVOKE EXECUTE ON FUNCTION pg_stat_statements_reset() FROM pg_read_all_stats; diff --git a/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql new file mode 100644 index 00000000000..6fc3fed4c93 --- /dev/null +++ b/contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql @@ -0,0 +1,22 @@ +/* contrib/pg_stat_statements/pg_stat_statements--1.6--1.7.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pg_stat_statements UPDATE TO '1.7'" to load this file. \quit + +/* First we have to remove them from the extension */ +ALTER EXTENSION pg_stat_statements DROP FUNCTION pg_stat_statements_reset(); + +/* Then we can drop them */ +DROP FUNCTION pg_stat_statements_reset(); + +/* Now redefine */ +CREATE FUNCTION pg_stat_statements_reset(IN userid Oid DEFAULT 0, + IN dbid Oid DEFAULT 0, + IN queryid bigint DEFAULT 0 +) +RETURNS void +AS 'MODULE_PATHNAME', 'pg_stat_statements_reset_1_7' +LANGUAGE C STRICT PARALLEL SAFE; + +-- Don't want this to be available to non-superusers. +REVOKE ALL ON FUNCTION pg_stat_statements_reset(Oid, Oid, bigint) FROM PUBLIC; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 928673498af..221b47298ce 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -48,7 +48,7 @@ * in the file to be read or written while holding only shared lock. * * - * Copyright (c) 2008-2018, PostgreSQL Global Development Group + * Copyright (c) 2008-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pg_stat_statements/pg_stat_statements.c @@ -61,7 +61,6 @@ #include #include -#include "access/hash.h" #include "catalog/pg_authid.h" #include "executor/instrument.h" #include "funcapi.h" @@ -76,7 +75,9 @@ #include "storage/ipc.h" #include "storage/spin.h" #include "tcop/utility.h" +#include "utils/acl.h" #include "utils/builtins.h" +#include "utils/hashutils.h" #include "utils/memutils.h" PG_MODULE_MAGIC; @@ -289,6 +290,7 @@ void _PG_init(void); void _PG_fini(void); PG_FUNCTION_INFO_V1(pg_stat_statements_reset); +PG_FUNCTION_INFO_V1(pg_stat_statements_reset_1_7); PG_FUNCTION_INFO_V1(pg_stat_statements_1_2); PG_FUNCTION_INFO_V1(pg_stat_statements_1_3); PG_FUNCTION_INFO_V1(pg_stat_statements); @@ -298,45 +300,46 @@ static void pgss_shmem_shutdown(int code, Datum arg); static void pgss_post_parse_analyze(ParseState *pstate, Query *query); static void pgss_ExecutorStart(QueryDesc *queryDesc, int eflags); static void pgss_ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, - uint64 count, bool execute_once); + ScanDirection direction, + uint64 count, bool execute_once); static void pgss_ExecutorFinish(QueryDesc *queryDesc); static void pgss_ExecutorEnd(QueryDesc *queryDesc); static void pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, - ProcessUtilityContext context, ParamListInfo params, - QueryEnvironment *queryEnv, - DestReceiver *dest, char *completionTag); + ProcessUtilityContext context, ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, char *completionTag); static uint64 pgss_hash_string(const char *str, int len); static void pgss_store(const char *query, uint64 queryId, - int query_location, int query_len, - double total_time, uint64 rows, - const BufferUsage *bufusage, - pgssJumbleState *jstate); + int query_location, int query_len, + double total_time, uint64 rows, + const BufferUsage *bufusage, + pgssJumbleState *jstate); static void pg_stat_statements_internal(FunctionCallInfo fcinfo, - pgssVersion api_version, - bool showtext); + pgssVersion api_version, + bool showtext); static Size pgss_memsize(void); static pgssEntry *entry_alloc(pgssHashKey *key, Size query_offset, int query_len, - int encoding, bool sticky); + int encoding, bool sticky); static void entry_dealloc(void); static bool qtext_store(const char *query, int query_len, - Size *query_offset, int *gc_count); + Size *query_offset, int *gc_count); static char *qtext_load_file(Size *buffer_size); static char *qtext_fetch(Size query_offset, int query_len, - char *buffer, Size buffer_size); + char *buffer, Size buffer_size); static bool need_gc_qtexts(void); static void gc_qtexts(void); -static void entry_reset(void); +static void entry_reset(Oid userid, Oid dbid, uint64 queryid); static void AppendJumble(pgssJumbleState *jstate, - const unsigned char *item, Size size); + const unsigned char *item, Size size); static void JumbleQuery(pgssJumbleState *jstate, Query *query); static void JumbleRangeTable(pgssJumbleState *jstate, List *rtable); +static void JumbleRowMarks(pgssJumbleState *jstate, List *rowMarks); static void JumbleExpr(pgssJumbleState *jstate, Node *node); static void RecordConstLocation(pgssJumbleState *jstate, int location); static char *generate_normalized_query(pgssJumbleState *jstate, const char *query, - int query_loc, int *query_len_p, int encoding); + int query_loc, int *query_len_p, int encoding); static void fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, - int query_loc); + int query_loc); static int comp_location(const void *a, const void *b); @@ -623,7 +626,7 @@ pgss_shmem_startup(void) /* * Remove the persisted stats file so it's not included in - * backups/replication slaves, etc. A new file will be written on next + * backups/replication standbys, etc. A new file will be written on next * shutdown. * * Note: it's okay if the PGSS_TEXT_FILE is included in a basebackup, @@ -641,19 +644,19 @@ pgss_shmem_startup(void) read_error: ereport(LOG, (errcode_for_file_access(), - errmsg("could not read pg_stat_statement file \"%s\": %m", + errmsg("could not read file \"%s\": %m", PGSS_DUMP_FILE))); goto fail; data_error: ereport(LOG, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("ignoring invalid data in pg_stat_statement file \"%s\"", + errmsg("ignoring invalid data in file \"%s\"", PGSS_DUMP_FILE))); goto fail; write_error: ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_TEXT_FILE))); fail: if (buffer) @@ -760,7 +763,7 @@ pgss_shmem_shutdown(int code, Datum arg) error: ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_DUMP_FILE ".tmp"))); if (qbuffer) free(qbuffer); @@ -785,7 +788,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query) Assert(query->queryId == UINT64CONST(0)); /* Safety check... */ - if (!pgss || !pgss_hash) + if (!pgss || !pgss_hash || !pgss_enabled()) return; /* @@ -1147,8 +1150,18 @@ pgss_store(const char *query, uint64 queryId, * For utility statements, we just hash the query string to get an ID. */ if (queryId == UINT64CONST(0)) + { queryId = pgss_hash_string(query, query_len); + /* + * If we are unlucky enough to get a hash of zero(invalid), use + * queryID as 2 instead, queryID 1 is already in use for normal + * statements. + */ + if (queryId == UINT64CONST(0)) + queryId = UINT64CONST(2); + } + /* Set up key for hashtable search */ key.userid = GetUserId(); key.dbid = MyDatabaseId; @@ -1292,16 +1305,32 @@ pgss_store(const char *query, uint64 queryId, } /* - * Reset all statement statistics. + * Reset statement statistics corresponding to userid, dbid, and queryid. + */ +Datum +pg_stat_statements_reset_1_7(PG_FUNCTION_ARGS) +{ + Oid userid; + Oid dbid; + uint64 queryid; + + userid = PG_GETARG_OID(0); + dbid = PG_GETARG_OID(1); + queryid = (uint64) PG_GETARG_INT64(2); + + entry_reset(userid, dbid, queryid); + + PG_RETURN_VOID(); +} + +/* + * Reset statement statistics. */ Datum pg_stat_statements_reset(PG_FUNCTION_ARGS) { - if (!pgss || !pgss_hash) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("pg_stat_statements must be loaded via shared_preload_libraries"))); - entry_reset(); + entry_reset(0, 0, 0); + PG_RETURN_VOID(); } @@ -1870,7 +1899,7 @@ qtext_store(const char *query, int query_len, error: ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_TEXT_FILE))); if (fd >= 0) @@ -1912,7 +1941,7 @@ qtext_load_file(Size *buffer_size) if (errno != ENOENT) ereport(LOG, (errcode_for_file_access(), - errmsg("could not read pg_stat_statement file \"%s\": %m", + errmsg("could not read file \"%s\": %m", PGSS_TEXT_FILE))); return NULL; } @@ -1922,7 +1951,7 @@ qtext_load_file(Size *buffer_size) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not stat pg_stat_statement file \"%s\": %m", + errmsg("could not stat file \"%s\": %m", PGSS_TEXT_FILE))); CloseTransientFile(fd); return NULL; @@ -1938,7 +1967,7 @@ qtext_load_file(Size *buffer_size) ereport(LOG, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), - errdetail("Could not allocate enough memory to read pg_stat_statement file \"%s\".", + errdetail("Could not allocate enough memory to read file \"%s\".", PGSS_TEXT_FILE))); CloseTransientFile(fd); return NULL; @@ -1957,14 +1986,17 @@ qtext_load_file(Size *buffer_size) if (errno) ereport(LOG, (errcode_for_file_access(), - errmsg("could not read pg_stat_statement file \"%s\": %m", + errmsg("could not read file \"%s\": %m", PGSS_TEXT_FILE))); free(buf); CloseTransientFile(fd); return NULL; } - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", PGSS_TEXT_FILE))); *buffer_size = stat.st_size; return buf; @@ -2087,7 +2119,7 @@ gc_qtexts(void) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_TEXT_FILE))); goto gc_fail; } @@ -2117,7 +2149,7 @@ gc_qtexts(void) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_TEXT_FILE))); hash_seq_term(&hash_seq); goto gc_fail; @@ -2135,14 +2167,14 @@ gc_qtexts(void) if (ftruncate(fileno(qfile), extent) != 0) ereport(LOG, (errcode_for_file_access(), - errmsg("could not truncate pg_stat_statement file \"%s\": %m", + errmsg("could not truncate file \"%s\": %m", PGSS_TEXT_FILE))); if (FreeFile(qfile)) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not write pg_stat_statement file \"%s\": %m", + errmsg("could not write file \"%s\": %m", PGSS_TEXT_FILE))); qfile = NULL; goto gc_fail; @@ -2202,7 +2234,7 @@ gc_qtexts(void) if (qfile == NULL) ereport(LOG, (errcode_for_file_access(), - errmsg("could not write new pg_stat_statement file \"%s\": %m", + errmsg("could not recreate file \"%s\": %m", PGSS_TEXT_FILE))); else FreeFile(qfile); @@ -2228,22 +2260,67 @@ gc_qtexts(void) } /* - * Release all entries. + * Release entries corresponding to parameters passed. */ static void -entry_reset(void) +entry_reset(Oid userid, Oid dbid, uint64 queryid) { HASH_SEQ_STATUS hash_seq; pgssEntry *entry; FILE *qfile; + long num_entries; + long num_remove = 0; + pgssHashKey key; + + if (!pgss || !pgss_hash) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("pg_stat_statements must be loaded via shared_preload_libraries"))); LWLockAcquire(pgss->lock, LW_EXCLUSIVE); + num_entries = hash_get_num_entries(pgss_hash); - hash_seq_init(&hash_seq, pgss_hash); - while ((entry = hash_seq_search(&hash_seq)) != NULL) + if (userid != 0 && dbid != 0 && queryid != UINT64CONST(0)) + { + /* If all the parameters are available, use the fast path. */ + key.userid = userid; + key.dbid = dbid; + key.queryid = queryid; + + /* Remove the key if exists */ + entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_REMOVE, NULL); + if (entry) /* found */ + num_remove++; + } + else if (userid != 0 || dbid != 0 || queryid != UINT64CONST(0)) { - hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL); + /* Remove entries corresponding to valid parameters. */ + hash_seq_init(&hash_seq, pgss_hash); + while ((entry = hash_seq_search(&hash_seq)) != NULL) + { + if ((!userid || entry->key.userid == userid) && + (!dbid || entry->key.dbid == dbid) && + (!queryid || entry->key.queryid == queryid)) + { + hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL); + num_remove++; + } + } } + else + { + /* Remove all entries. */ + hash_seq_init(&hash_seq, pgss_hash); + while ((entry = hash_seq_search(&hash_seq)) != NULL) + { + hash_search(pgss_hash, &entry->key, HASH_REMOVE, NULL); + num_remove++; + } + } + + /* All entries are removed? */ + if (num_entries != num_remove) + goto release_lock; /* * Write new empty query file, perhaps even creating a new one to recover @@ -2254,7 +2331,7 @@ entry_reset(void) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not create pg_stat_statement file \"%s\": %m", + errmsg("could not create file \"%s\": %m", PGSS_TEXT_FILE))); goto done; } @@ -2263,7 +2340,7 @@ entry_reset(void) if (ftruncate(fileno(qfile), 0) != 0) ereport(LOG, (errcode_for_file_access(), - errmsg("could not truncate pg_stat_statement file \"%s\": %m", + errmsg("could not truncate file \"%s\": %m", PGSS_TEXT_FILE))); FreeFile(qfile); @@ -2273,6 +2350,7 @@ entry_reset(void) /* This counts as a query text garbage collection for our purposes */ record_gc_qtexts(); +release_lock: LWLockRelease(pgss->lock); } @@ -2353,7 +2431,7 @@ JumbleQuery(pgssJumbleState *jstate, Query *query) JumbleExpr(jstate, (Node *) query->sortClause); JumbleExpr(jstate, query->limitOffset); JumbleExpr(jstate, query->limitCount); - /* we ignore rowMarks */ + JumbleRowMarks(jstate, query->rowMarks); JumbleExpr(jstate, query->setOperations); } @@ -2403,6 +2481,8 @@ JumbleRangeTable(pgssJumbleState *jstate, List *rtable) case RTE_NAMEDTUPLESTORE: APP_JUMB_STRING(rte->enrname); break; + case RTE_RESULT: + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); break; @@ -2410,6 +2490,26 @@ JumbleRangeTable(pgssJumbleState *jstate, List *rtable) } } +/* + * Jumble a rowMarks list + */ +static void +JumbleRowMarks(pgssJumbleState *jstate, List *rowMarks) +{ + ListCell *lc; + + foreach(lc, rowMarks) + { + RowMarkClause *rowmark = lfirst_node(RowMarkClause, lc); + if (!rowmark->pushedDown) + { + APP_JUMB(rowmark->rti); + APP_JUMB(rowmark->strength); + APP_JUMB(rowmark->waitPolicy); + } + } +} + /* * Jumble an expression tree * @@ -2504,14 +2604,14 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) JumbleExpr(jstate, (Node *) expr->aggfilter); } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - JumbleExpr(jstate, (Node *) aref->refupperindexpr); - JumbleExpr(jstate, (Node *) aref->reflowerindexpr); - JumbleExpr(jstate, (Node *) aref->refexpr); - JumbleExpr(jstate, (Node *) aref->refassgnexpr); + JumbleExpr(jstate, (Node *) sbsref->refupperindexpr); + JumbleExpr(jstate, (Node *) sbsref->reflowerindexpr); + JumbleExpr(jstate, (Node *) sbsref->refexpr); + JumbleExpr(jstate, (Node *) sbsref->refassgnexpr); } break; case T_FuncExpr: @@ -2852,6 +2952,7 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) /* we store the string name because RTE_CTE RTEs need it */ APP_JUMB_STRING(cte->ctename); + APP_JUMB(cte->ctematerialized); JumbleQuery(jstate, castNode(Query, cte->ctequery)); } break; @@ -3074,8 +3175,8 @@ fill_in_constant_lengths(pgssJumbleState *jstate, const char *query, /* initialize the flex scanner --- should match raw_parser() */ yyscanner = scanner_init(query, &yyextra, - ScanKeywords, - NumScanKeywords); + &ScanKeywords, + ScanKeywordTokens); /* we don't want to re-emit any escape string warnings */ yyextra.escape_string_warning = false; diff --git a/contrib/pg_stat_statements/pg_stat_statements.control b/contrib/pg_stat_statements/pg_stat_statements.control index 193fcdfafa0..14cb4223543 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.control +++ b/contrib/pg_stat_statements/pg_stat_statements.control @@ -1,5 +1,5 @@ # pg_stat_statements extension comment = 'track execution statistics of all SQL statements executed' -default_version = '1.5' +default_version = '1.7' module_pathname = '$libdir/pg_stat_statements' relocatable = true diff --git a/contrib/pg_stat_statements/sql/pg_stat_statements.sql b/contrib/pg_stat_statements/sql/pg_stat_statements.sql index a8361fd1bff..8b527070d46 100644 --- a/contrib/pg_stat_statements/sql/pg_stat_statements.sql +++ b/contrib/pg_stat_statements/sql/pg_stat_statements.sql @@ -177,6 +177,37 @@ SELECT PLUS_ONE(1); SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; +-- +-- queries with locking clauses +-- +CREATE TABLE pgss_a (id integer PRIMARY KEY); +CREATE TABLE pgss_b (id integer PRIMARY KEY, a_id integer REFERENCES pgss_a); + +SELECT pg_stat_statements_reset(); + +-- control query +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id; + +-- test range tables +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_a; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_a, pgss_b; -- matches plain "FOR UPDATE" +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE OF pgss_b, pgss_a; + +-- test strengths +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR NO KEY UPDATE; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR SHARE; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR KEY SHARE; + +-- test wait policies +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE NOWAIT; +SELECT * FROM pgss_a JOIN pgss_b ON pgss_b.a_id = pgss_a.id FOR UPDATE SKIP LOCKED; + +SELECT calls, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + +DROP TABLE pgss_a, pgss_b CASCADE; + -- -- utility commands -- @@ -195,4 +226,68 @@ DROP FUNCTION PLUS_TWO(INTEGER); SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; +-- +-- Track user activity and reset them +-- +SELECT pg_stat_statements_reset(); +CREATE ROLE regress_stats_user1; +CREATE ROLE regress_stats_user2; + +SET ROLE regress_stats_user1; + +SELECT 1 AS "ONE"; +SELECT 1+1 AS "TWO"; + +RESET ROLE; +SET ROLE regress_stats_user2; + +SELECT 1 AS "ONE"; +SELECT 1+1 AS "TWO"; + +RESET ROLE; +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- Don't reset anything if any of the parameter is NULL +-- +SELECT pg_stat_statements_reset(NULL); +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- remove query ('SELECT $1+$2 AS "TWO"') executed by regress_stats_user2 +-- in the current_database +-- +SELECT pg_stat_statements_reset( + (SELECT r.oid FROM pg_roles AS r WHERE r.rolname = 'regress_stats_user2'), + (SELECT d.oid FROM pg_database As d where datname = current_database()), + (SELECT s.queryid FROM pg_stat_statements AS s + WHERE s.query = 'SELECT $1+$2 AS "TWO"' LIMIT 1)); +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- remove query ('SELECT $1 AS "ONE"') executed by two users +-- +SELECT pg_stat_statements_reset(0,0,s.queryid) + FROM pg_stat_statements AS s WHERE s.query = 'SELECT $1 AS "ONE"'; +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- remove query of a user (regress_stats_user1) +-- +SELECT pg_stat_statements_reset(r.oid) + FROM pg_roles AS r WHERE r.rolname = 'regress_stats_user1'; +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- reset all +-- +SELECT pg_stat_statements_reset(0,0,0); +SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C"; + +-- +-- cleanup +-- +DROP ROLE regress_stats_user1; +DROP ROLE regress_stats_user2; + DROP EXTENSION pg_stat_statements; diff --git a/contrib/pg_trgm/expected/pg_strict_word_trgm.out b/contrib/pg_trgm/expected/pg_strict_word_trgm.out index 43898a3b980..1e1ee16ce95 100644 --- a/contrib/pg_trgm/expected/pg_strict_word_trgm.out +++ b/contrib/pg_trgm/expected/pg_strict_word_trgm.out @@ -1,6 +1,8 @@ DROP INDEX trgm_idx2; \copy test_trgm3 from 'data/trgm2.data' ERROR: relation "test_trgm3" does not exist +-- reduce noise +set extra_float_digits = 0; select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <<% t order by sml desc, t; t | sml -------------------------------------+---------- diff --git a/contrib/pg_trgm/expected/pg_trgm.out b/contrib/pg_trgm/expected/pg_trgm.out index 6efc54356a1..b3e709f4962 100644 --- a/contrib/pg_trgm/expected/pg_trgm.out +++ b/contrib/pg_trgm/expected/pg_trgm.out @@ -10,6 +10,8 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); --backslash is used in tests below, installcheck will fail if --standard_conforming_string is off set standard_conforming_strings=on; +-- reduce noise +set extra_float_digits = 0; select show_trgm(''); show_trgm ----------- diff --git a/contrib/pg_trgm/expected/pg_word_trgm.out b/contrib/pg_trgm/expected/pg_word_trgm.out index bed61c4922a..936d489390e 100644 --- a/contrib/pg_trgm/expected/pg_word_trgm.out +++ b/contrib/pg_trgm/expected/pg_word_trgm.out @@ -1,5 +1,7 @@ CREATE TABLE test_trgm2(t text COLLATE "C"); \copy test_trgm2 from 'data/trgm2.data' +-- reduce noise +set extra_float_digits = 0; select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t; t | sml -------------------------------------+---------- diff --git a/contrib/pg_trgm/sql/pg_strict_word_trgm.sql b/contrib/pg_trgm/sql/pg_strict_word_trgm.sql index 98e0d379f85..ce0791f29b7 100644 --- a/contrib/pg_trgm/sql/pg_strict_word_trgm.sql +++ b/contrib/pg_trgm/sql/pg_strict_word_trgm.sql @@ -2,6 +2,9 @@ DROP INDEX trgm_idx2; \copy test_trgm3 from 'data/trgm2.data' +-- reduce noise +set extra_float_digits = 0; + select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <<% t order by sml desc, t; select t,strict_word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <<% t order by sml desc, t; select t,strict_word_similarity('Baykal',t) as sml from test_trgm2 where t %>> 'Baykal' order by sml desc, t; diff --git a/contrib/pg_trgm/sql/pg_trgm.sql b/contrib/pg_trgm/sql/pg_trgm.sql index 96ae542320d..08459e64c30 100644 --- a/contrib/pg_trgm/sql/pg_trgm.sql +++ b/contrib/pg_trgm/sql/pg_trgm.sql @@ -9,6 +9,9 @@ WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); --standard_conforming_string is off set standard_conforming_strings=on; +-- reduce noise +set extra_float_digits = 0; + select show_trgm(''); select show_trgm('(*&^$@%@'); select show_trgm('a b c'); diff --git a/contrib/pg_trgm/sql/pg_word_trgm.sql b/contrib/pg_trgm/sql/pg_word_trgm.sql index 4b1db9706a9..d9fa1c55e5e 100644 --- a/contrib/pg_trgm/sql/pg_word_trgm.sql +++ b/contrib/pg_trgm/sql/pg_word_trgm.sql @@ -2,6 +2,9 @@ CREATE TABLE test_trgm2(t text COLLATE "C"); \copy test_trgm2 from 'data/trgm2.data' +-- reduce noise +set extra_float_digits = 0; + select t,word_similarity('Baykal',t) as sml from test_trgm2 where 'Baykal' <% t order by sml desc, t; select t,word_similarity('Kabankala',t) as sml from test_trgm2 where 'Kabankala' <% t order by sml desc, t; select t,word_similarity('Baykal',t) as sml from test_trgm2 where t %> 'Baykal' order by sml desc, t; diff --git a/contrib/pg_trgm/trgm.h b/contrib/pg_trgm/trgm.h index f0ab50dd05c..0fd600d5810 100644 --- a/contrib/pg_trgm/trgm.h +++ b/contrib/pg_trgm/trgm.h @@ -134,7 +134,7 @@ extern float4 cnt_sml(TRGM *trg1, TRGM *trg2, bool inexact); extern bool trgm_contained_by(TRGM *trg1, TRGM *trg2); extern bool *trgm_presence_map(TRGM *query, TRGM *key); extern TRGM *createTrgmNFA(text *text_re, Oid collation, - TrgmPackedGraph **graph, MemoryContext rcontext); + TrgmPackedGraph **graph, MemoryContext rcontext); extern bool trigramsMatchGraph(TrgmPackedGraph *graph, bool *check); #endif /* __TRGM_H__ */ diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 53e6830ab1b..e79db8a4f03 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -7,6 +7,7 @@ #include "access/stratnum.h" #include "fmgr.h" +#include "port/pg_bitutils.h" typedef struct @@ -39,26 +40,6 @@ PG_FUNCTION_INFO_V1(gtrgm_same); PG_FUNCTION_INFO_V1(gtrgm_penalty); PG_FUNCTION_INFO_V1(gtrgm_picksplit); -/* Number of one-bits in an unsigned byte */ -static const uint8 number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - Datum gtrgm_in(PG_FUNCTION_ARGS) @@ -292,7 +273,11 @@ gtrgm_consistent(PG_FUNCTION_ARGS) case SimilarityStrategyNumber: case WordSimilarityStrategyNumber: case StrictWordSimilarityStrategyNumber: - /* Similarity search is exact. (Strict) word similarity search is inexact */ + + /* + * Similarity search is exact. (Strict) word similarity search is + * inexact + */ *recheck = (strategy != SimilarityStrategyNumber); nlimit = index_strategy_get_limit(strategy); @@ -630,12 +615,7 @@ gtrgm_same(PG_FUNCTION_ARGS) static int32 sizebitvec(BITVECP sign) { - int32 size = 0, - i; - - LOOPBYTE - size += number_of_ones[(unsigned char) sign[i]]; - return size; + return pg_popcount(sign, SIGLEN); } static int @@ -648,7 +628,8 @@ hemdistsign(BITVECP a, BITVECP b) LOOPBYTE { diff = (unsigned char) (a[i] ^ b[i]); - dist += number_of_ones[diff]; + /* Using the popcount functions here isn't likely to win */ + dist += pg_number_of_ones[diff]; } return dist; } diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c index b572d087d83..0d4614e9c8a 100644 --- a/contrib/pg_trgm/trgm_op.c +++ b/contrib/pg_trgm/trgm_op.c @@ -48,14 +48,14 @@ typedef struct /* Trigram bound type */ typedef uint8 TrgmBound; -#define TRGM_BOUND_LEFT (0x01) /* trigram is left bound of word */ -#define TRGM_BOUND_RIGHT (0x02) /* trigram is right bound of word */ +#define TRGM_BOUND_LEFT 0x01 /* trigram is left bound of word */ +#define TRGM_BOUND_RIGHT 0x02 /* trigram is right bound of word */ /* Word similarity flags */ -#define WORD_SIMILARITY_CHECK_ONLY (0x01) /* if set then only check existence - * of similar search pattern in text */ -#define WORD_SIMILARITY_STRICT (0x02) /* force bounds of extent to match - * word bounds */ +#define WORD_SIMILARITY_CHECK_ONLY 0x01 /* only check existence of similar + * search pattern in text */ +#define WORD_SIMILARITY_STRICT 0x02 /* force bounds of extent to match + * word bounds */ /* * Module load callback @@ -65,7 +65,7 @@ _PG_init(void) { /* Define custom GUC variables. */ DefineCustomRealVariable("pg_trgm.similarity_threshold", - "Sets the threshold used by the %% operator.", + "Sets the threshold used by the % operator.", "Valid range is 0.0 .. 1.0.", &similarity_threshold, 0.3, @@ -77,7 +77,7 @@ _PG_init(void) NULL, NULL); DefineCustomRealVariable("pg_trgm.word_similarity_threshold", - "Sets the threshold used by the <%% operator.", + "Sets the threshold used by the <% operator.", "Valid range is 0.0 .. 1.0.", &word_similarity_threshold, 0.6, @@ -89,7 +89,7 @@ _PG_init(void) NULL, NULL); DefineCustomRealVariable("pg_trgm.strict_word_similarity_threshold", - "Sets the threshold used by the <<%% operator.", + "Sets the threshold used by the <<% operator.", "Valid range is 0.0 .. 1.0.", &strict_word_similarity_threshold, 0.5, @@ -144,7 +144,7 @@ index_strategy_get_limit(StrategyNumber strategy) break; } - return 0.0; /* keep compiler quiet */ + return 0.0; /* keep compiler quiet */ } /* @@ -496,13 +496,13 @@ iterate_word_similarity(int *trg2indexes, /* Select appropriate threshold */ threshold = (flags & WORD_SIMILARITY_STRICT) ? - strict_word_similarity_threshold : - word_similarity_threshold; + strict_word_similarity_threshold : + word_similarity_threshold; /* - * Consider first trigram as initial lower bount for strict word similarity, - * or initialize it later with first trigram present for plain word - * similarity. + * Consider first trigram as initial lower bound for strict word + * similarity, or initialize it later with first trigram present for plain + * word similarity. */ lower = (flags & WORD_SIMILARITY_STRICT) ? 0 : -1; @@ -533,7 +533,7 @@ iterate_word_similarity(int *trg2indexes, * plain word similarity */ if ((flags & WORD_SIMILARITY_STRICT) ? (bounds[i] & TRGM_BOUND_RIGHT) - : found[trgindex]) + : found[trgindex]) { int prev_lower, tmp_ulen2, @@ -597,8 +597,8 @@ iterate_word_similarity(int *trg2indexes, smlr_max = Max(smlr_max, smlr_cur); /* - * if we only check that word similarity is greater than - * threshold we do not need to calculate a maximum similarity. + * if we only check that word similarity is greater than threshold + * we do not need to calculate a maximum similarity. */ if ((flags & WORD_SIMILARITY_CHECK_ONLY) && smlr_max >= threshold) break; @@ -653,7 +653,7 @@ calc_word_similarity(char *str1, int slen1, char *str2, int slen2, ulen1; int *trg2indexes; float4 result; - TrgmBound *bounds; + TrgmBound *bounds; protect_out_of_mem(slen1 + slen2); diff --git a/contrib/pg_trgm/trgm_regexp.c b/contrib/pg_trgm/trgm_regexp.c index 547e7c094f8..3ad5731ae80 100644 --- a/contrib/pg_trgm/trgm_regexp.c +++ b/contrib/pg_trgm/trgm_regexp.c @@ -181,7 +181,7 @@ * 7) Mark state 3 final because state 5 of source NFA is marked as final. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -202,7 +202,7 @@ /* * Uncomment (or use -DTRGM_REGEXP_DEBUG) to print debug info, * for exploring and debugging the algorithm implementation. - * This produces three graph files in /tmp, in Graphviz .dot format. + * This produces three graph files in /tmp, in Graphviz .gv format. * Some progress information is also printed to postmaster stderr. */ /* #define TRGM_REGEXP_DEBUG */ @@ -441,9 +441,9 @@ typedef struct struct TrgmPackedGraph { /* - * colorTrigramsCount and colorTrigramsGroups contain information about - * how trigrams are grouped into color trigrams. "colorTrigramsCount" is - * the count of color trigrams and "colorTrigramGroups" contains number of + * colorTrigramsCount and colorTrigramGroups contain information about how + * trigrams are grouped into color trigrams. "colorTrigramsCount" is the + * count of color trigrams and "colorTrigramGroups" contains number of * simple trigrams for each color trigram. The array of simple trigrams * (stored separately from this struct) is ordered so that the simple * trigrams for each color trigram are consecutive, and they're in order @@ -478,9 +478,9 @@ typedef struct /* prototypes for private functions */ static TRGM *createTrgmNFAInternal(regex_t *regex, TrgmPackedGraph **graph, - MemoryContext rcontext); + MemoryContext rcontext); static void RE_compile(regex_t *regex, text *text_re, - int cflags, Oid collation); + int cflags, Oid collation); static void getColorInfo(regex_t *regex, TrgmNFA *trgmNFA); static bool convertPgWchar(pg_wchar c, trgm_mb_char *result); static void transformGraph(TrgmNFA *trgmNFA); @@ -489,7 +489,7 @@ static void addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key); static void addKeyToQueue(TrgmNFA *trgmNFA, TrgmStateKey *key); static void addArcs(TrgmNFA *trgmNFA, TrgmState *state); static void addArc(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key, - TrgmColor co, TrgmStateKey *destKey); + TrgmColor co, TrgmStateKey *destKey); static bool validArcLabel(TrgmStateKey *key, TrgmColor co); static TrgmState *getState(TrgmNFA *trgmNFA, TrgmStateKey *key); static bool prefixContains(TrgmPrefix *prefix1, TrgmPrefix *prefix2); @@ -1013,9 +1013,7 @@ addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key) { regex_arc_t *arcs; TrgmStateKey destKey; - ListCell *cell, - *prev, - *next; + ListCell *cell; int i, arcsCount; @@ -1030,13 +1028,10 @@ addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key) * redundancy. We can drop either old key(s) or the new key if we find * redundancy. */ - prev = NULL; - cell = list_head(state->enterKeys); - while (cell) + foreach(cell, state->enterKeys) { TrgmStateKey *existingKey = (TrgmStateKey *) lfirst(cell); - next = lnext(cell); if (existingKey->nstate == key->nstate) { if (prefixContains(&existingKey->prefix, &key->prefix)) @@ -1050,15 +1045,10 @@ addKey(TrgmNFA *trgmNFA, TrgmState *state, TrgmStateKey *key) * The new key covers this old key. Remove the old key, it's * no longer needed once we add this key to the list. */ - state->enterKeys = list_delete_cell(state->enterKeys, - cell, prev); + state->enterKeys = foreach_delete_current(state->enterKeys, + cell); } - else - prev = cell; } - else - prev = cell; - cell = next; } /* No redundancy, so add this key to the state's list */ @@ -2187,8 +2177,8 @@ printSourceNFA(regex_t *regex, TrgmColorInfo *colors, int ncolors) appendStringInfoString(&buf, "}\n"); { - /* dot -Tpng -o /tmp/source.png < /tmp/source.dot */ - FILE *fp = fopen("/tmp/source.dot", "w"); + /* dot -Tpng -o /tmp/source.png < /tmp/source.gv */ + FILE *fp = fopen("/tmp/source.gv", "w"); fprintf(fp, "%s", buf.data); fclose(fp); @@ -2249,8 +2239,8 @@ printTrgmNFA(TrgmNFA *trgmNFA) appendStringInfoString(&buf, "}\n"); { - /* dot -Tpng -o /tmp/transformed.png < /tmp/transformed.dot */ - FILE *fp = fopen("/tmp/transformed.dot", "w"); + /* dot -Tpng -o /tmp/transformed.png < /tmp/transformed.gv */ + FILE *fp = fopen("/tmp/transformed.gv", "w"); fprintf(fp, "%s", buf.data); fclose(fp); @@ -2340,8 +2330,8 @@ printTrgmPackedGraph(TrgmPackedGraph *packedGraph, TRGM *trigrams) appendStringInfoString(&buf, "}\n"); { - /* dot -Tpng -o /tmp/packed.png < /tmp/packed.dot */ - FILE *fp = fopen("/tmp/packed.dot", "w"); + /* dot -Tpng -o /tmp/packed.png < /tmp/packed.gv */ + FILE *fp = fopen("/tmp/packed.gv", "w"); fprintf(fp, "%s", buf.data); fclose(fp); diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c index 944dea66fc8..75b6d96440b 100644 --- a/contrib/pg_visibility/pg_visibility.c +++ b/contrib/pg_visibility/pg_visibility.c @@ -3,13 +3,14 @@ * pg_visibility.c * display visibility map information and page-level visibility bits * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * contrib/pg_visibility/pg_visibility.c *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/visibilitymap.h" #include "catalog/pg_type.h" @@ -20,6 +21,7 @@ #include "storage/procarray.h" #include "storage/smgr.h" #include "utils/rel.h" +#include "utils/snapmgr.h" PG_MODULE_MAGIC; @@ -49,10 +51,10 @@ PG_FUNCTION_INFO_V1(pg_truncate_visibility_map); static TupleDesc pg_visibility_tupdesc(bool include_blkno, bool include_pd); static vbits *collect_visibility_data(Oid relid, bool include_pd); static corrupt_items *collect_corrupt_items(Oid relid, bool all_visible, - bool all_frozen); + bool all_frozen); static void record_corrupt_item(corrupt_items *items, ItemPointer tid); static bool tuple_all_visible(HeapTuple tup, TransactionId OldestXmin, - Buffer buffer); + Buffer buffer); static void check_relation_relkind(Relation rel); /* @@ -292,7 +294,7 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS) ReleaseBuffer(vmbuffer); relation_close(rel, AccessShareLock); - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "all_visible", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "all_frozen", INT8OID, -1, 0); tupdesc = BlessTupleDesc(tupdesc); @@ -381,6 +383,8 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); Relation rel; + ForkNumber fork; + BlockNumber block; rel = relation_open(relid, AccessExclusiveLock); @@ -390,7 +394,12 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS) RelationOpenSmgr(rel); rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber; - visibilitymap_truncate(rel, 0); + block = visibilitymap_prepare_truncate(rel, 0); + if (BlockNumberIsValid(block)) + { + fork = VISIBILITYMAP_FORKNUM; + smgrtruncate(rel->rd_smgr, &fork, 1, &block); + } if (RelationNeedsWAL(rel)) { @@ -416,7 +425,7 @@ pg_truncate_visibility_map(PG_FUNCTION_ARGS) * here and when we sent the messages at our eventual commit. However, * we're currently only sending a non-transactional smgr invalidation, * which will have been posted to shared memory immediately from within - * visibilitymap_truncate. Therefore, there should be no race here. + * smgr_truncate. Therefore, there should be no race here. * * The reason why it's desirable to release the lock early here is because * of the possibility that someone will need to use this to blow away many @@ -447,7 +456,7 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd) ++maxattr; if (include_pd) ++maxattr; - tupdesc = CreateTemplateTupleDesc(maxattr, false); + tupdesc = CreateTemplateTupleDesc(maxattr); if (include_blkno) TupleDescInitEntry(tupdesc, ++a, "blkno", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, ++a, "all_visible", BOOLOID, -1, 0); diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile index 573bc6df79a..1313b664087 100644 --- a/contrib/pgcrypto/Makefile +++ b/contrib/pgcrypto/Makefile @@ -59,6 +59,9 @@ SHLIB_LINK += $(filter -leay32, $(LIBS)) SHLIB_LINK += -lws2_32 endif +# Upstream uses a larger subset of C99. +imath.o: CFLAGS+=$(PERMIT_DECLARATION_AFTER_STATEMENT) + rijndael.o: rijndael.tbl rijndael.tbl: diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c index ed07fc46064..6efaa609c9d 100644 --- a/contrib/pgcrypto/crypt-des.c +++ b/contrib/pgcrypto/crypt-des.c @@ -11,7 +11,7 @@ * binaries of libcrypt exportable from the USA * * Adapted for FreeBSD-4.0 by Mark R V Murray - * this file should now *only* export crypt_des(), in order to make + * this file should now *only* export px_crypt_des(), in order to make * a module that can be optionally included in libcrypt. * * Redistribution and use in source and binary forms, with or without diff --git a/contrib/pgcrypto/expected/hmac-sha1.out b/contrib/pgcrypto/expected/hmac-sha1.out index d5f1cf25972..de605b804eb 100644 --- a/contrib/pgcrypto/expected/hmac-sha1.out +++ b/contrib/pgcrypto/expected/hmac-sha1.out @@ -1,5 +1,5 @@ -- --- HMAC-MD5 +-- HMAC-SHA1 -- SELECT encode(hmac( 'Hi There', diff --git a/contrib/pgcrypto/expected/pgp-compression_1.out b/contrib/pgcrypto/expected/pgp-compression_1.out deleted file mode 100644 index 655830ae140..00000000000 --- a/contrib/pgcrypto/expected/pgp-compression_1.out +++ /dev/null @@ -1,42 +0,0 @@ --- --- PGP compression support --- -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- - -ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+ -DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA== -=tbSn ------END PGP MESSAGE----- -'), 'key', 'expect-compress-algo=1'); - pgp_sym_decrypt ------------------ - Secret message -(1 row) - -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'), - 'key', 'expect-compress-algo=0'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'), - 'key', 'expect-compress-algo=1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'), - 'key', 'expect-compress-algo=2'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- level=0 should turn compression off -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret message', 'key', - 'compress-algo=2, compress-level=0'), - 'key', 'expect-compress-algo=0'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. diff --git a/contrib/pgcrypto/expected/pgp-decrypt.out b/contrib/pgcrypto/expected/pgp-decrypt.out index 2dabfaf7b0e..e8250b090ab 100644 --- a/contrib/pgcrypto/expected/pgp-decrypt.out +++ b/contrib/pgcrypto/expected/pgp-decrypt.out @@ -1,5 +1,5 @@ -- --- pgp_descrypt tests +-- pgp decrypt tests -- -- Checking ciphers select pgp_sym_decrypt(dearmor(' diff --git a/contrib/pgcrypto/expected/pgp-decrypt_1.out b/contrib/pgcrypto/expected/pgp-decrypt_1.out deleted file mode 100644 index f3df4e618ad..00000000000 --- a/contrib/pgcrypto/expected/pgp-decrypt_1.out +++ /dev/null @@ -1,424 +0,0 @@ --- --- pgp_descrypt tests --- --- Checking ciphers -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.blowfish.sha1.mdc.s2k3.z0 - -jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS -yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE= -=JcP+ ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest -UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA== -=XtrP ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes192.sha1.mdc.s2k3.z0 - -jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI -5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g== -=rCZt ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes256.sha1.mdc.s2k3.z0 - -jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/ -lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog== -=fB6S ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - --- Checking MDC modes -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.nomdc.s2k3.z0 - -jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+ -u9YkgfJfsuRJmgQ9tmo= -=60ui ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE -8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q== -=moGf ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - --- Checking hashes -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.md5.mdc.s2k3.z0 - -jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO -KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA== -=NyLk ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m -/PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw== -=FxbQ ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - --- Checking S2K modes -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k0.z0 - -jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw -Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw== -=YvkV ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k1.z0 - -jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK -4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz -=dbXm ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl -z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg== -=VJKg ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes192.sha1.mdc.s2k0.z0 - -jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E -Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw== -=cg+i ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes192.sha1.mdc.s2k1.z0 - -jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9 -7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt -=aHmC ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes192.sha1.mdc.s2k3.z0 - -jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv -q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw== -=K0LS ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes256.sha1.mdc.s2k0.z0 - -jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu -rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w== -=RGts ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes256.sha1.mdc.s2k1.z0 - -jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO -+KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR -=SUrU ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes256.sha1.mdc.s2k3.z0 - -jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+ -4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA== -=XZrG ------END PGP MESSAGE----- -'), 'foobar'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - --- Checking longer passwords -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi -tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw== -=XKKG ------END PGP MESSAGE----- -'), '0123456789abcdefghij'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6 -CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg== -=gWDh ------END PGP MESSAGE----- -'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt -FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q== -=OxOF ------END PGP MESSAGE----- -'), 'x'); - pgp_sym_decrypt ------------------ - Secret message. -(1 row) - --- Checking various data -select encode(digest(pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat1.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8 -Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg== -=W/ik ------END PGP MESSAGE----- -'), '0123456789abcdefghij'), 'sha1'), 'hex'); - encode ------------------------------------------- - 0225e3ede6f2587b076d021a189ff60aad67e066 -(1 row) - --- expected: 0225e3ede6f2587b076d021a189ff60aad67e066 -select encode(digest(pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat2.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB -SaV9L04ky1qECNDx3XjnoKLC+H7IOQ== -=Fxen ------END PGP MESSAGE----- -'), '0123456789abcdefghij'), 'sha1'), 'hex'); - encode ------------------------------------------- - da39a3ee5e6b4b0d3255bfef95601890afd80709 -(1 row) - --- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709 -select encode(digest(pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: dat3.aes.sha1.mdc.s2k3.z0 - -jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8 -gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk -73Hb8m1yRhQK -=ivrD ------END PGP MESSAGE----- -'), '0123456789abcdefghij'), 'sha1'), 'hex'); - encode ------------------------------------------- - 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c -(1 row) - --- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c --- Checking CRLF -select encode(digest(pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: crlf mess - -ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms -a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs -=mBP9 ------END PGP MESSAGE----- -'), 'key', 'convert-crlf=0'), 'sha1'), 'hex'); - encode ------------------------------------------- - 9353062be7720f1446d30b9e75573a4833886784 -(1 row) - --- expected: 9353062be7720f1446d30b9e75573a4833886784 -select encode(digest(pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- -Comment: crlf mess - -ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms -a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs -=mBP9 ------END PGP MESSAGE----- -'), 'key', 'convert-crlf=1'), 'sha1'), 'hex'); - encode ------------------------------------------- - 7efefcab38467f7484d6fa43dc86cf5281bd78e2 -(1 row) - --- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2 --- check BUG #11905, problem with messages 6 less than a power of 2. -select pgp_sym_decrypt(pgp_sym_encrypt(repeat('x',65530),'1'),'1') = repeat('x',65530); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- expected: true --- Negative tests --- Decryption with a certain incorrect key yields an apparent Literal Data --- packet reporting its content to be binary data. Ciphertext source: --- iterative pgp_sym_encrypt('secret', 'key') until the random prefix gave --- rise to that property. -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- - -ww0EBwMCxf8PTrQBmJdl0jcB6y2joE7GSLKRv7trbNsF5Z8ou5NISLUg31llVH/S0B2wl4bvzZjV -VsxxqLSPzNLAeIspJk5G -=mSd/ ------END PGP MESSAGE----- -'), 'wrong-key', 'debug=1'); -NOTICE: dbg: prefix_init: corrupt prefix -NOTICE: dbg: parse_literal_data: data type=b -NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr -ERROR: Wrong key or corrupt data --- Routine text/binary mismatch. -select pgp_sym_decrypt(pgp_sym_encrypt_bytea('P', 'key'), 'key', 'debug=1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- Decryption with a certain incorrect key yields an apparent BZip2-compressed --- plaintext. Ciphertext source: iterative pgp_sym_encrypt('secret', 'key') --- until the random prefix gave rise to that property. -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- - -ww0EBwMC9rK/dMkF5Zlt0jcBlzAQ1mQY2qYbKYbw8h3EZ5Jk0K2IiY92R82TRhWzBIF/8cmXDPtP -GXsd65oYJZp3Khz0qfyn -=Nmpq ------END PGP MESSAGE----- -'), 'wrong-key', 'debug=1'); -NOTICE: dbg: prefix_init: corrupt prefix -NOTICE: dbg: parse_compressed_data: bzip2 unsupported -NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr -ERROR: Wrong key or corrupt data --- Routine use of BZip2 compression. Ciphertext source: --- echo x | gpg --homedir /nonexistent --personal-compress-preferences bzip2 \ --- --personal-cipher-preferences aes --no-emit-version --batch \ --- --symmetric --passphrase key --armor -select pgp_sym_decrypt(dearmor(' ------BEGIN PGP MESSAGE----- - -jA0EBwMCRhFrAKNcLVJg0mMBLJG1cCASNk/x/3dt1zJ+2eo7jHfjgg3N6wpB3XIe -QCwkWJwlBG5pzbO5gu7xuPQN+TbPJ7aQ2sLx3bAHhtYb0i3vV9RO10Gw++yUyd4R -UCAAw2JRIISttRHMfDpDuZJpvYo= -=AZ9M ------END PGP MESSAGE----- -'), 'key', 'debug=1'); -NOTICE: dbg: parse_compressed_data: bzip2 unsupported -ERROR: Unsupported compression algorithm diff --git a/contrib/pgcrypto/expected/pgp-encrypt_1.out b/contrib/pgcrypto/expected/pgp-encrypt_1.out deleted file mode 100644 index 72f346414ab..00000000000 --- a/contrib/pgcrypto/expected/pgp-encrypt_1.out +++ /dev/null @@ -1,161 +0,0 @@ --- --- PGP encrypt --- --- ensure consistent test output regardless of the default bytea format -SET bytea_output TO escape; -select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- check whether the defaults are ok -select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), - 'key', 'expect-cipher-algo=aes128, - expect-disable-mdc=0, - expect-sess-key=0, - expect-s2k-mode=3, - expect-s2k-digest-algo=sha1, - expect-compress-algo=0 - '); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- maybe the expect- stuff simply does not work -select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), - 'key', 'expect-cipher-algo=bf, - expect-disable-mdc=1, - expect-sess-key=1, - expect-s2k-mode=0, - expect-s2k-digest-algo=md5, - expect-compress-algo=1 - '); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- bytea as text -select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- text as bytea -select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- algorithm change -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'), - 'key', 'expect-cipher-algo=bf'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'), - 'key', 'expect-cipher-algo=aes128'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'), - 'key', 'expect-cipher-algo=aes192'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- s2k change -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'), - 'key', 'expect-s2k-mode=0'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'), - 'key', 'expect-s2k-mode=1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'), - 'key', 'expect-s2k-mode=3'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- s2k count change -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'), - 'key', 'expect-s2k-count=1024'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- s2k_count rounds up -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'), - 'key', 'expect-s2k-count=65000000'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- s2k digest change -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'), - 'key', 'expect-s2k-digest-algo=md5'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'), - 'key', 'expect-s2k-digest-algo=sha1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- sess key -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'), - 'key', 'expect-sess-key=0'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'), - 'key', 'expect-sess-key=1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'), - 'key', 'expect-sess-key=1, expect-cipher-algo=bf'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'), - 'key', 'expect-sess-key=1, expect-cipher-algo=aes192'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'), - 'key', 'expect-sess-key=1, expect-cipher-algo=aes256'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- no mdc -select pgp_sym_decrypt( - pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'), - 'key', 'expect-disable-mdc=1'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- crlf -select encode(pgp_sym_decrypt_bytea( - pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'), - 'key'), 'hex'); -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- conversion should be lossless -select encode(digest(pgp_sym_decrypt( - pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'), - 'key', 'convert-crlf=1'), 'sha1'), 'hex') as result, - encode(digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. diff --git a/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out b/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out deleted file mode 100644 index 6da4c6da413..00000000000 --- a/contrib/pgcrypto/expected/pgp-pubkey-encrypt_1.out +++ /dev/null @@ -1,62 +0,0 @@ --- --- PGP Public Key Encryption --- --- ensure consistent test output regardless of the default bytea format -SET bytea_output TO escape; --- successful encrypt/decrypt -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=1; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=2; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=3; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=6; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- try with rsa-sign only -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=4; -ERROR: No encryption key found --- try with secret key -select pgp_pub_decrypt( - pgp_pub_encrypt('Secret msg', dearmor(seckey)), - dearmor(seckey)) -from keytbl where keytbl.id=1; -ERROR: Refusing to encrypt with secret key --- does text-to-bytea works -select pgp_pub_decrypt_bytea( - pgp_pub_encrypt('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=1; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. --- and bytea-to-text? -select pgp_pub_decrypt( - pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)), - dearmor(seckey)) -from keytbl where keytbl.id=1; -ERROR: generating random data is not supported by this build -DETAIL: This functionality requires a source of strong random numbers. -HINT: You need to rebuild PostgreSQL using --enable-strong-random. diff --git a/contrib/pgcrypto/imath.c b/contrib/pgcrypto/imath.c index cd528bfd836..6936d2cdcaf 100644 --- a/contrib/pgcrypto/imath.c +++ b/contrib/pgcrypto/imath.c @@ -1,90 +1,110 @@ -/* imath version 1.3 */ +/*------------------------------------------------------------------------- + * + * imath.c + * + * Last synchronized from https://github.com/creachadair/imath/tree/v1.29, + * using the following procedure: + * + * 1. Download imath.c and imath.h of the last synchronized version. Remove + * "#ifdef __cplusplus" blocks, which upset pgindent. Run pgindent on the + * two files. Filter the two files through "unexpand -t4 --first-only". + * Diff the result against the PostgreSQL versions. As of the last + * synchronization, changes were as follows: + * + * - replace malloc(), realloc() and free() with px_ versions + * - redirect assert() to Assert() + * - #undef MIN, #undef MAX before defining them + * - remove includes covered by c.h + * - rename DEBUG to IMATH_DEBUG + * - replace stdint.h usage with c.h equivalents + * - suppress MSVC warning 4146 + * - add required PG_USED_FOR_ASSERTS_ONLY + * + * 2. Download a newer imath.c and imath.h. Transform them like in step 1. + * Apply to these files the diff you saved in step 1. Look for new lines + * requiring the same kind of change, such as new malloc() calls. + * + * 3. Configure PostgreSQL using --without-openssl. Run "make -C + * contrib/pgcrypto check". + * + * 4. Update this header comment. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * contrib/pgcrypto/imath.c + * + * Upstream copyright terms follow. + *------------------------------------------------------------------------- + */ + /* Name: imath.c Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger - Info: Id: imath.c 21 2006-04-02 18:58:36Z sting - - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* contrib/pgcrypto/imath.c */ #include "postgres.h" -#include "px.h" + #include "imath.h" +#include "px.h" #undef assert #define assert(TEST) Assert(TEST) -#define TRACEABLE_CLAMP 0 -#define TRACEABLE_FREE 0 - -/* {{{ Constants */ const mp_result MP_OK = 0; /* no error, all is well */ -const mp_result MP_FALSE = 0; /* boolean false */ -const mp_result MP_TRUE = -1; /* boolean true */ -const mp_result MP_MEMORY = -2; /* out of memory */ +const mp_result MP_FALSE = 0; /* boolean false */ +const mp_result MP_TRUE = -1; /* boolean true */ +const mp_result MP_MEMORY = -2; /* out of memory */ const mp_result MP_RANGE = -3; /* argument out of range */ -const mp_result MP_UNDEF = -4; /* result undefined */ -const mp_result MP_TRUNC = -5; /* output truncated */ +const mp_result MP_UNDEF = -4; /* result undefined */ +const mp_result MP_TRUNC = -5; /* output truncated */ const mp_result MP_BADARG = -6; /* invalid null argument */ +const mp_result MP_MINERR = -6; const mp_sign MP_NEG = 1; /* value is strictly negative */ -const mp_sign MP_ZPOS = 0; /* value is non-negative */ +const mp_sign MP_ZPOS = 0; /* value is non-negative */ static const char *s_unknown_err = "unknown result code"; -static const char *s_error_msg[] = { - "error code 0", - "boolean true", - "out of memory", - "argument out of range", - "result undefined", - "output truncated", - "invalid null argument", - NULL -}; - -/* }}} */ - -/* Optional library flags */ -#define MP_CAP_DIGITS 1 /* flag bit to capitalize letter digits */ - -/* Argument checking macros - Use CHECK() where a return value is required; NRCHECK() elsewhere */ -#define CHECK(TEST) assert(TEST) -#define NRCHECK(TEST) assert(TEST) - -/* {{{ Logarithm table for computing output sizes */ +static const char *s_error_msg[] = {"error code 0", "boolean true", + "out of memory", "argument out of range", + "result undefined", "output truncated", +"invalid argument", NULL}; /* The ith entry of this table gives the value of log_i(2). An integer value n requires ceil(log_i(n)) digits to be represented in base i. Since it is easy to compute lg(n), by counting bits, we can compute log_i(n) = lg(n) * log_i(2). + + The use of this table eliminates a dependency upon linkage against + the standard math libraries. + + If MP_MAX_RADIX is increased, this table should be expanded too. */ static const double s_log2[] = { - 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* 0 1 2 3 */ - 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ + 0.000000000, 0.000000000, 1.000000000, 0.630929754, /* (D)(D) 2 3 */ + 0.500000000, 0.430676558, 0.386852807, 0.356207187, /* 4 5 6 7 */ 0.333333333, 0.315464877, 0.301029996, 0.289064826, /* 8 9 10 11 */ 0.278942946, 0.270238154, 0.262649535, 0.255958025, /* 12 13 14 15 */ 0.250000000, 0.244650542, 0.239812467, 0.235408913, /* 16 17 18 19 */ @@ -92,136 +112,242 @@ static const double s_log2[] = { 0.218104292, 0.215338279, 0.212746054, 0.210309918, /* 24 25 26 27 */ 0.208014598, 0.205846832, 0.203795047, 0.201849087, /* 28 29 30 31 */ 0.200000000, 0.198239863, 0.196561632, 0.194959022, /* 32 33 34 35 */ - 0.193426404, 0.191958720, 0.190551412, 0.189200360, /* 36 37 38 39 */ - 0.187901825, 0.186652411, 0.185449023, 0.184288833, /* 40 41 42 43 */ - 0.183169251, 0.182087900, 0.181042597, 0.180031327, /* 44 45 46 47 */ - 0.179052232, 0.178103594, 0.177183820, 0.176291434, /* 48 49 50 51 */ - 0.175425064, 0.174583430, 0.173765343, 0.172969690, /* 52 53 54 55 */ - 0.172195434, 0.171441601, 0.170707280, 0.169991616, /* 56 57 58 59 */ - 0.169293808, 0.168613099, 0.167948779, 0.167300179, /* 60 61 62 63 */ - 0.166666667 + 0.193426404, /* 36 */ }; -/* }}} */ -/* {{{ Various macros */ - /* Return the number of digits needed to represent a static value */ #define MP_VALUE_DIGITS(V) \ -((sizeof(V)+(sizeof(mp_digit)-1))/sizeof(mp_digit)) + ((sizeof(V) + (sizeof(mp_digit) - 1)) / sizeof(mp_digit)) /* Round precision P to nearest word boundary */ -#define ROUND_PREC(P) ((mp_size)(2*(((P)+1)/2))) +static inline mp_size +s_round_prec(mp_size P) +{ + return 2 * ((P + 1) / 2); +} /* Set array P of S digits to zero */ -#define ZERO(P, S) \ -do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P);memset(p__,0,i__);}while(0) +static inline void +ZERO(mp_digit *P, mp_size S) +{ + mp_size i__ = S * sizeof(mp_digit); + mp_digit *p__ = P; + + memset(p__, 0, i__); +} /* Copy S digits from array P to array Q */ -#define COPY(P, Q, S) \ -do{mp_size i__=(S)*sizeof(mp_digit);mp_digit *p__=(P),*q__=(Q);\ -memcpy(q__,p__,i__);}while(0) +static inline void +COPY(mp_digit *P, mp_digit *Q, mp_size S) +{ + mp_size i__ = S * sizeof(mp_digit); + mp_digit *p__ = P; + mp_digit *q__ = Q; -/* Reverse N elements of type T in array A */ -#define REV(T, A, N) \ -do{T *u_=(A),*v_=u_+(N)-1;while(u_ 1 && (*dz_-- == 0)) --uz_;MP_USED(z_)=uz_;}while(0) -#endif +/* Reverse N elements of unsigned char in A. */ +static inline void +REV(unsigned char *A, int N) +{ + unsigned char *u_ = A; + unsigned char *v_ = u_ + N - 1; + + while (u_ < v_) + { + unsigned char xch = *u_; + + *u_++ = *v_; + *v_-- = xch; + } +} + +/* Strip leading zeroes from z_ in-place. */ +static inline void +CLAMP(mp_int z_) +{ + mp_size uz_ = MP_USED(z_); + mp_digit *dz_ = MP_DIGITS(z_) + uz_ - 1; + + while (uz_ > 1 && (*dz_-- == 0)) + --uz_; + z_->used = uz_; +} +/* Select min/max. */ #undef MIN #undef MAX -#define MIN(A, B) ((B)<(A)?(B):(A)) -#define MAX(A, B) ((B)>(A)?(B):(A)) -#define SWAP(T, A, B) do{T t_=(A);A=(B);B=t_;}while(0) - -#define TEMP(K) (temp + (K)) -#define SETUP(E, C) \ -do{if((res = (E)) != MP_OK) goto CLEANUP; ++(C);}while(0) +static inline int +MIN(int A, int B) +{ + return (B < A ? B : A); +} +static inline mp_size +MAX(mp_size A, mp_size B) +{ + return (B > A ? B : A); +} -#define CMPZ(Z) \ -(((Z)->used==1&&(Z)->digits[0]==0)?0:((Z)->sign==MP_NEG)?-1:1) +/* Exchange lvalues A and B of type T, e.g. + SWAP(int, x, y) where x and y are variables of type int. */ +#define SWAP(T, A, B) \ + do { \ + T t_ = (A); \ + A = (B); \ + B = t_; \ + } while (0) -#define UMUL(X, Y, Z) \ -do{mp_size ua_=MP_USED(X),ub_=MP_USED(Y);mp_size o_=ua_+ub_;\ -ZERO(MP_DIGITS(Z),o_);\ -(void) s_kmul(MP_DIGITS(X),MP_DIGITS(Y),MP_DIGITS(Z),ua_,ub_);\ -MP_USED(Z)=o_;CLAMP(Z);}while(0) +/* Declare a block of N temporary mpz_t values. + These values are initialized to zero. + You must add CLEANUP_TEMP() at the end of the function. + Use TEMP(i) to access a pointer to the ith value. + */ +#define DECLARE_TEMP(N) \ + struct { \ + mpz_t value[(N)]; \ + int len; \ + mp_result err; \ + } temp_ = { \ + .len = (N), \ + .err = MP_OK, \ + }; \ + do { \ + for (int i = 0; i < temp_.len; i++) { \ + mp_int_init(TEMP(i)); \ + } \ + } while (0) + +/* Clear all allocated temp values. */ +#define CLEANUP_TEMP() \ + CLEANUP: \ + do { \ + for (int i = 0; i < temp_.len; i++) { \ + mp_int_clear(TEMP(i)); \ + } \ + if (temp_.err != MP_OK) { \ + return temp_.err; \ + } \ + } while (0) + +/* A pointer to the kth temp value. */ +#define TEMP(K) (temp_.value + (K)) + +/* Evaluate E, an expression of type mp_result expected to return MP_OK. If + the value is not MP_OK, the error is cached and control resumes at the + cleanup handler, which returns it. +*/ +#define REQUIRE(E) \ + do { \ + temp_.err = (E); \ + if (temp_.err != MP_OK) goto CLEANUP; \ + } while (0) + +/* Compare value to zero. */ +static inline int +CMPZ(mp_int Z) +{ + if (Z->used == 1 && Z->digits[0] == 0) + return 0; + return (Z->sign == MP_NEG) ? -1 : 1; +} -#define USQR(X, Z) \ -do{mp_size ua_=MP_USED(X),o_=ua_+ua_;ZERO(MP_DIGITS(Z),o_);\ -(void) s_ksqr(MP_DIGITS(X),MP_DIGITS(Z),ua_);MP_USED(Z)=o_;CLAMP(Z);}while(0) +static inline mp_word +UPPER_HALF(mp_word W) +{ + return (W >> MP_DIGIT_BIT); +} +static inline mp_digit +LOWER_HALF(mp_word W) +{ + return (mp_digit) (W); +} -#define UPPER_HALF(W) ((mp_word)((W) >> MP_DIGIT_BIT)) -#define LOWER_HALF(W) ((mp_digit)(W)) -#define HIGH_BIT_SET(W) ((W) >> (MP_WORD_BIT - 1)) -#define ADD_WILL_OVERFLOW(W, V) ((MP_WORD_MAX - (V)) < (W)) +/* Report whether the highest-order bit of W is 1. */ +static inline bool +HIGH_BIT_SET(mp_word W) +{ + return (W >> (MP_WORD_BIT - 1)) != 0; +} -/* }}} */ +/* Report whether adding W + V will carry out. */ +static inline bool +ADD_WILL_OVERFLOW(mp_word W, mp_word V) +{ + return ((MP_WORD_MAX - V) < W); +} /* Default number of digits allocated to a new mp_int */ -static mp_size default_precision = 64; +static mp_size default_precision = 8; + +void +mp_int_default_precision(mp_size size) +{ + assert(size > 0); + default_precision = size; +} /* Minimum number of digits to invoke recursive multiply */ static mp_size multiply_threshold = 32; -/* Default library configuration flags */ -static mp_word mp_flags = MP_CAP_DIGITS; +void +mp_int_multiply_threshold(mp_size thresh) +{ + assert(thresh >= sizeof(mp_word)); + multiply_threshold = thresh; +} /* Allocate a buffer of (at least) num digits, or return NULL if that couldn't be done. */ static mp_digit *s_alloc(mp_size num); -#if TRACEABLE_FREE +/* Release a buffer of digits allocated by s_alloc(). */ static void s_free(void *ptr); -#else -#define s_free(P) px_free(P) -#endif /* Insure that z has at least min digits allocated, resizing if necessary. Returns true if successful, false if out of memory. */ -static int s_pad(mp_int z, mp_size min); +static bool s_pad(mp_int z, mp_size min); -/* Normalize by removing leading zeroes (except when z = 0) */ -#if TRACEABLE_CLAMP -static void s_clamp(mp_int z); -#endif +/* Ensure Z has at least N digits allocated. */ +static inline mp_result +GROW(mp_int Z, mp_size N) +{ + return s_pad(Z, N) ? MP_OK : MP_MEMORY; +} /* Fill in a "fake" mp_int on the stack with a given value */ -static void s_fake(mp_int z, int value, mp_digit vbuf[]); +static void s_fake(mp_int z, mp_small value, mp_digit vbuf[]); +static void s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]); /* Compare two runs of digits of given length, returns <0, 0, >0 */ static int s_cdig(mp_digit *da, mp_digit *db, mp_size len); /* Pack the unsigned digits of v into array t */ -static int s_vpack(int v, mp_digit t[]); +static int s_uvpack(mp_usmall v, mp_digit t[]); /* Compare magnitudes of a and b, returns <0, 0, >0 */ static int s_ucmp(mp_int a, mp_int b); /* Compare magnitudes of a and v, returns <0, 0, >0 */ -static int s_vcmp(mp_int a, int v); +static int s_vcmp(mp_int a, mp_small v); +static int s_uvcmp(mp_int a, mp_usmall uv); /* Unsigned magnitude addition; assumes dc is big enough. Carry out is returned (no memory allocated). */ -static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +static mp_digit s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); /* Unsigned magnitude subtraction. Assumes dc is big enough. */ -static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +static void s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); /* Unsigned recursive multiplication. Assumes dc is big enough. */ -static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +static int s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); /* Unsigned magnitude multiplication. Assumes dc is big enough. */ -static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b); +static void s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b); /* Unsigned recursive squaring. Assumes dc is big enough. */ static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a); @@ -236,8 +362,7 @@ static void s_dadd(mp_int a, mp_digit b); static void s_dmul(mp_int a, mp_digit b); /* Single digit multiplication on buffers; assumes dc is big enough. */ -static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, - mp_size size_a); +static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a); /* Single digit division. Replaces a with the quotient, returns the remainder. */ @@ -264,7 +389,7 @@ static int s_dp2k(mp_int z); static int s_isp2(mp_int z); /* Set z to 2^k. May allocate; returns false in case this fails. */ -static int s_2expt(mp_int z, int k); +static int s_2expt(mp_int z, mp_small k); /* Normalize a and b for division, returns normalization constant */ static int s_norm(mp_int a, mp_int b); @@ -279,17 +404,17 @@ static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2); /* Modular exponentiation, using Barrett reduction */ static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); -/* Unsigned magnitude division. Assumes |a| > |b|. Allocates - temporaries; overwrites a with quotient, b with remainder. */ -static mp_result s_udiv(mp_int a, mp_int b); +/* Unsigned magnitude division. Assumes |a| > |b|. Allocates temporaries; + overwrites a with quotient, b with remainder. */ +static mp_result s_udiv_knuth(mp_int a, mp_int b); -/* Compute the number of digits in radix r required to represent the - given value. Does not account for sign flags, terminators, etc. */ +/* Compute the number of digits in radix r required to represent the given + value. Does not account for sign flags, terminators, etc. */ static int s_outlen(mp_int z, mp_size r); -/* Guess how many digits of precision will be needed to represent a - radix r value of the specified number of digits. Returns a value - guaranteed to be no smaller than the actual number required. */ +/* Guess how many digits of precision will be needed to represent a radix r + value of the specified number of digits. Returns a value guaranteed to be + no smaller than the actual number required. */ static mp_size s_inlen(int len, mp_size r); /* Convert a character to a digit value in radix r, or @@ -302,177 +427,161 @@ static char s_val2ch(int v, int caps); /* Take 2's complement of a buffer in place */ static void s_2comp(unsigned char *buf, int len); -/* Convert a value to binary, ignoring sign. On input, *limpos is the - bound on how many bytes should be written to buf; on output, *limpos - is set to the number of bytes actually written. */ +/* Convert a value to binary, ignoring sign. On input, *limpos is the bound on + how many bytes should be written to buf; on output, *limpos is set to the + number of bytes actually written. */ static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad); -#if 0 -/* Dump a representation of the mp_int to standard output */ -void s_print(char *tag, mp_int z); -void s_print_buf(char *tag, mp_digit *buf, mp_size num); -#endif - -/* {{{ get_default_precision() */ - -mp_size -mp_get_default_precision(void) +/* Multiply X by Y into Z, ignoring signs. Requires that Z have enough storage + preallocated to hold the result. */ +static inline void +UMUL(mp_int X, mp_int Y, mp_int Z) { - return default_precision; -} - -/* }}} */ - -/* {{{ mp_set_default_precision(s) */ - -void -mp_set_default_precision(mp_size s) -{ - NRCHECK(s > 0); + mp_size ua_ = MP_USED(X); + mp_size ub_ = MP_USED(Y); + mp_size o_ = ua_ + ub_; - default_precision = (mp_size) ROUND_PREC(s); + ZERO(MP_DIGITS(Z), o_); + (void) s_kmul(MP_DIGITS(X), MP_DIGITS(Y), MP_DIGITS(Z), ua_, ub_); + Z->used = o_; + CLAMP(Z); } -/* }}} */ - -/* {{{ mp_get_multiply_threshold() */ - -mp_size -mp_get_multiply_threshold(void) +/* Square X into Z. Requires that Z have enough storage to hold the result. */ +static inline void +USQR(mp_int X, mp_int Z) { - return multiply_threshold; -} - -/* }}} */ + mp_size ua_ = MP_USED(X); + mp_size o_ = ua_ + ua_; -/* {{{ mp_set_multiply_threshold(s) */ - -void -mp_set_multiply_threshold(mp_size s) -{ - multiply_threshold = s; + ZERO(MP_DIGITS(Z), o_); + (void) s_ksqr(MP_DIGITS(X), MP_DIGITS(Z), ua_); + Z->used = o_; + CLAMP(Z); } -/* }}} */ - -/* {{{ mp_int_init(z) */ - mp_result mp_int_init(mp_int z) { - return mp_int_init_size(z, default_precision); -} + if (z == NULL) + return MP_BADARG; -/* }}} */ + z->single = 0; + z->digits = &(z->single); + z->alloc = 1; + z->used = 1; + z->sign = MP_ZPOS; -/* {{{ mp_int_alloc() */ + return MP_OK; +} mp_int mp_int_alloc(void) { mp_int out = px_alloc(sizeof(mpz_t)); - assert(out != NULL); - out->digits = NULL; - out->used = 0; - out->alloc = 0; - out->sign = 0; + if (out != NULL) + mp_int_init(out); return out; } -/* }}} */ - -/* {{{ mp_int_init_size(z, prec) */ - mp_result mp_int_init_size(mp_int z, mp_size prec) { - CHECK(z != NULL); + assert(z != NULL); - prec = (mp_size) ROUND_PREC(prec); - prec = MAX(prec, default_precision); + if (prec == 0) + { + prec = default_precision; + } + else if (prec == 1) + { + return mp_int_init(z); + } + else + { + prec = s_round_prec(prec); + } - if ((MP_DIGITS(z) = s_alloc(prec)) == NULL) + z->digits = s_alloc(prec); + if (MP_DIGITS(z) == NULL) return MP_MEMORY; z->digits[0] = 0; - MP_USED(z) = 1; - MP_ALLOC(z) = prec; - MP_SIGN(z) = MP_ZPOS; + z->used = 1; + z->alloc = prec; + z->sign = MP_ZPOS; return MP_OK; } -/* }}} */ - -/* {{{ mp_int_init_copy(z, old) */ - mp_result mp_int_init_copy(mp_int z, mp_int old) { - mp_result res; - mp_size uold, - target; + assert(z != NULL && old != NULL); - CHECK(z != NULL && old != NULL); + mp_size uold = MP_USED(old); - uold = MP_USED(old); - target = MAX(uold, default_precision); + if (uold == 1) + { + mp_int_init(z); + } + else + { + mp_size target = MAX(uold, default_precision); + mp_result res = mp_int_init_size(z, target); - if ((res = mp_int_init_size(z, target)) != MP_OK) - return res; + if (res != MP_OK) + return res; + } - MP_USED(z) = uold; - MP_SIGN(z) = MP_SIGN(old); + z->used = uold; + z->sign = old->sign; COPY(MP_DIGITS(old), MP_DIGITS(z), uold); return MP_OK; } -/* }}} */ - -/* {{{ mp_int_init_value(z, value) */ - mp_result -mp_int_init_value(mp_int z, int value) +mp_int_init_value(mp_int z, mp_small value) { - mp_result res; - - CHECK(z != NULL); - - if ((res = mp_int_init(z)) != MP_OK) - return res; + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - return mp_int_set_value(z, value); + s_fake(&vtmp, value, vbuf); + return mp_int_init_copy(z, &vtmp); } -/* }}} */ - -/* {{{ mp_int_set_value(z, value) */ - mp_result -mp_int_set_value(mp_int z, int value) +mp_int_init_uvalue(mp_int z, mp_usmall uvalue) { - mp_size ndig; - - CHECK(z != NULL); - - /* How many digits to copy */ - ndig = (mp_size) MP_VALUE_DIGITS(value); + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; - if (!s_pad(z, ndig)) - return MP_MEMORY; + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_init_copy(z, &vtmp); +} - MP_USED(z) = (mp_size) s_vpack(value, MP_DIGITS(z)); - MP_SIGN(z) = (value < 0) ? MP_NEG : MP_ZPOS; +mp_result +mp_int_set_value(mp_int z, mp_small value) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(value)]; - return MP_OK; + s_fake(&vtmp, value, vbuf); + return mp_int_copy(&vtmp, z); } -/* }}} */ +mp_result +mp_int_set_uvalue(mp_int z, mp_usmall uvalue) +{ + mpz_t vtmp; + mp_digit vbuf[MP_VALUE_DIGITS(uvalue)]; -/* {{{ mp_int_clear(z) */ + s_ufake(&vtmp, uvalue, vbuf); + return mp_int_copy(&vtmp, z); +} void mp_int_clear(mp_int z) @@ -482,34 +591,26 @@ mp_int_clear(mp_int z) if (MP_DIGITS(z) != NULL) { - s_free(MP_DIGITS(z)); - MP_DIGITS(z) = NULL; + if (MP_DIGITS(z) != &(z->single)) + s_free(MP_DIGITS(z)); + + z->digits = NULL; } } -/* }}} */ - -/* {{{ mp_int_free(z) */ - void mp_int_free(mp_int z) { - NRCHECK(z != NULL); - - if (z->digits != NULL) - mp_int_clear(z); + assert(z != NULL); - px_free(z); + mp_int_clear(z); + px_free(z); /* note: NOT s_free() */ } -/* }}} */ - -/* {{{ mp_int_copy(a, c) */ - mp_result mp_int_copy(mp_int a, mp_int c) { - CHECK(a != NULL && c != NULL); + assert(a != NULL && c != NULL); if (a != c) { @@ -524,17 +625,13 @@ mp_int_copy(mp_int a, mp_int c) dc = MP_DIGITS(c); COPY(da, dc, ua); - MP_USED(c) = ua; - MP_SIGN(c) = MP_SIGN(a); + c->used = ua; + c->sign = a->sign; } return MP_OK; } -/* }}} */ - -/* {{{ mp_int_swap(a, c) */ - void mp_int_swap(mp_int a, mp_int c) { @@ -544,90 +641,71 @@ mp_int_swap(mp_int a, mp_int c) *a = *c; *c = tmp; + + if (MP_DIGITS(a) == &(c->single)) + a->digits = &(a->single); + if (MP_DIGITS(c) == &(a->single)) + c->digits = &(c->single); } } -/* }}} */ - -/* {{{ mp_int_zero(z) */ - void mp_int_zero(mp_int z) { - NRCHECK(z != NULL); + assert(z != NULL); z->digits[0] = 0; - MP_USED(z) = 1; - MP_SIGN(z) = MP_ZPOS; + z->used = 1; + z->sign = MP_ZPOS; } -/* }}} */ - -/* {{{ mp_int_abs(a, c) */ - mp_result mp_int_abs(mp_int a, mp_int c) { - mp_result res; + assert(a != NULL && c != NULL); - CHECK(a != NULL && c != NULL); + mp_result res; if ((res = mp_int_copy(a, c)) != MP_OK) return res; - MP_SIGN(c) = MP_ZPOS; + c->sign = MP_ZPOS; return MP_OK; } -/* }}} */ - -/* {{{ mp_int_neg(a, c) */ - mp_result mp_int_neg(mp_int a, mp_int c) { - mp_result res; + assert(a != NULL && c != NULL); - CHECK(a != NULL && c != NULL); + mp_result res; if ((res = mp_int_copy(a, c)) != MP_OK) return res; if (CMPZ(c) != 0) - MP_SIGN(c) = 1 - MP_SIGN(a); + c->sign = 1 - MP_SIGN(a); return MP_OK; } -/* }}} */ - -/* {{{ mp_int_add(a, b, c) */ - mp_result mp_int_add(mp_int a, mp_int b, mp_int c) { - mp_size ua, - ub, - uc, - max; - - CHECK(a != NULL && b != NULL && c != NULL); + assert(a != NULL && b != NULL && c != NULL); - ua = MP_USED(a); - ub = MP_USED(b); - uc = MP_USED(c); - max = MAX(ua, ub); + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size max = MAX(ua, ub); if (MP_SIGN(a) == MP_SIGN(b)) { /* Same sign -- add magnitudes, preserve sign of addends */ - mp_digit carry; - if (!s_pad(c, max)) return MP_MEMORY; - carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - uc = max; + mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + mp_size uc = max; if (carry) { @@ -638,50 +716,55 @@ mp_int_add(mp_int a, mp_int b, mp_int c) ++uc; } - MP_USED(c) = uc; - MP_SIGN(c) = MP_SIGN(a); + c->used = uc; + c->sign = a->sign; } else { /* Different signs -- subtract magnitudes, preserve sign of greater */ + int cmp = s_ucmp(a, b); /* magnitude comparision, sign ignored */ + + /* + * Set x to max(a, b), y to min(a, b) to simplify later code. A + * special case yields zero for equal magnitudes. + */ mp_int x, y; - int cmp = s_ucmp(a, b); /* magnitude comparison, sign ignored */ - /* Set x to max(a, b), y to min(a, b) to simplify later code */ - if (cmp >= 0) + if (cmp == 0) { - x = a; - y = b; + mp_int_zero(c); + return MP_OK; } - else + else if (cmp < 0) { x = b; y = a; } + else + { + x = a; + y = b; + } if (!s_pad(c, MP_USED(x))) return MP_MEMORY; /* Subtract smaller from larger */ s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - MP_USED(c) = MP_USED(x); + c->used = x->used; CLAMP(c); /* Give result the sign of the larger */ - MP_SIGN(c) = MP_SIGN(x); + c->sign = x->sign; } return MP_OK; } -/* }}} */ - -/* {{{ mp_int_add_value(a, value, c) */ - mp_result -mp_int_add_value(mp_int a, int value, mp_int c) +mp_int_add_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -691,35 +774,23 @@ mp_int_add_value(mp_int a, int value, mp_int c) return mp_int_add(a, &vtmp, c); } -/* }}} */ - -/* {{{ mp_int_sub(a, b, c) */ - mp_result mp_int_sub(mp_int a, mp_int b, mp_int c) { - mp_size ua, - ub, - uc, - max; + assert(a != NULL && b != NULL && c != NULL); - CHECK(a != NULL && b != NULL && c != NULL); - - ua = MP_USED(a); - ub = MP_USED(b); - uc = MP_USED(c); - max = MAX(ua, ub); + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size max = MAX(ua, ub); if (MP_SIGN(a) != MP_SIGN(b)) { /* Different signs -- add magnitudes and keep sign of a */ - mp_digit carry; - if (!s_pad(c, max)) return MP_MEMORY; - carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); - uc = max; + mp_digit carry = s_uadd(MP_DIGITS(a), MP_DIGITS(b), MP_DIGITS(c), ua, ub); + mp_size uc = max; if (carry) { @@ -730,20 +801,20 @@ mp_int_sub(mp_int a, mp_int b, mp_int c) ++uc; } - MP_USED(c) = uc; - MP_SIGN(c) = MP_SIGN(a); + c->used = uc; + c->sign = a->sign; } else { /* Same signs -- subtract magnitudes */ + if (!s_pad(c, max)) + return MP_MEMORY; mp_int x, y; mp_sign osign; - int cmp = s_ucmp(a, b); - if (!s_pad(c, max)) - return MP_MEMORY; + int cmp = s_ucmp(a, b); if (cmp >= 0) { @@ -762,21 +833,17 @@ mp_int_sub(mp_int a, mp_int b, mp_int c) osign = 1 - osign; s_usub(MP_DIGITS(x), MP_DIGITS(y), MP_DIGITS(c), MP_USED(x), MP_USED(y)); - MP_USED(c) = MP_USED(x); + c->used = x->used; CLAMP(c); - MP_SIGN(c) = osign; + c->sign = osign; } return MP_OK; } -/* }}} */ - -/* {{{ mp_int_sub_value(a, value, c) */ - mp_result -mp_int_sub_value(mp_int a, int value, mp_int c) +mp_int_sub_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -786,21 +853,10 @@ mp_int_sub_value(mp_int a, int value, mp_int c) return mp_int_sub(a, &vtmp, c); } -/* }}} */ - -/* {{{ mp_int_mul(a, b, c) */ - mp_result mp_int_mul(mp_int a, mp_int b, mp_int c) { - mp_digit *out; - mp_size osize, - ua, - ub, - p = 0; - mp_sign osign; - - CHECK(a != NULL && b != NULL && c != NULL); + assert(a != NULL && b != NULL && c != NULL); /* If either input is zero, we can shortcut multiplication */ if (mp_int_compare_zero(a) == 0 || mp_int_compare_zero(b) == 0) @@ -810,21 +866,24 @@ mp_int_mul(mp_int a, mp_int b, mp_int c) } /* Output is positive if inputs have same sign, otherwise negative */ - osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; + mp_sign osign = (MP_SIGN(a) == MP_SIGN(b)) ? MP_ZPOS : MP_NEG; /* - * If the output is not equal to any of the inputs, we'll write the - * results there directly; otherwise, allocate a temporary space. + * If the output is not identical to any of the inputs, we'll write the + * results directly; otherwise, allocate a temporary space. */ - ua = MP_USED(a); - ub = MP_USED(b); - osize = MAX(ua, ub); + mp_size ua = MP_USED(a); + mp_size ub = MP_USED(b); + mp_size osize = MAX(ua, ub); + osize = 4 * ((osize + 1) / 2); + mp_digit *out; + mp_size p = 0; + if (c == a || c == b) { - p = ROUND_PREC(osize); - p = MAX(p, default_precision); + p = MAX(s_round_prec(osize), default_precision); if ((out = s_alloc(p)) == NULL) return MP_MEMORY; @@ -847,24 +906,21 @@ mp_int_mul(mp_int a, mp_int b, mp_int c) */ if (out != MP_DIGITS(c)) { - s_free(MP_DIGITS(c)); - MP_DIGITS(c) = out; - MP_ALLOC(c) = p; + if ((void *) MP_DIGITS(c) != (void *) c) + s_free(MP_DIGITS(c)); + c->digits = out; + c->alloc = p; } - MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + c->used = osize; /* might not be true, but we'll fix it ... */ CLAMP(c); /* ... right here */ - MP_SIGN(c) = osign; + c->sign = osign; return MP_OK; } -/* }}} */ - -/* {{{ mp_int_mul_value(a, value, c) */ - mp_result -mp_int_mul_value(mp_int a, int value, mp_int c) +mp_int_mul_value(mp_int a, mp_small value, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -874,45 +930,39 @@ mp_int_mul_value(mp_int a, int value, mp_int c) return mp_int_mul(a, &vtmp, c); } -/* }}} */ - -/* {{{ mp_int_mul_pow2(a, p2, c) */ - mp_result -mp_int_mul_pow2(mp_int a, int p2, mp_int c) +mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c) { - mp_result res; + assert(a != NULL && c != NULL && p2 >= 0); - CHECK(a != NULL && c != NULL && p2 >= 0); + mp_result res = mp_int_copy(a, c); - if ((res = mp_int_copy(a, c)) != MP_OK) + if (res != MP_OK) return res; if (s_qmul(c, (mp_size) p2)) + { return MP_OK; + } else + { return MP_MEMORY; + } } -/* }}} */ - -/* {{{ mp_int_sqr(a, c) */ - mp_result mp_int_sqr(mp_int a, mp_int c) { - mp_digit *out; - mp_size osize, - p = 0; - - CHECK(a != NULL && c != NULL); + assert(a != NULL && c != NULL); /* Get a temporary buffer big enough to hold the result */ - osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); + mp_size osize = (mp_size) 4 * ((MP_USED(a) + 1) / 2); + mp_size p = 0; + mp_digit *out; if (a == c) { - p = ROUND_PREC(osize); + p = s_round_prec(osize); p = MAX(p, default_precision); if ((out = s_alloc(p)) == NULL) @@ -935,39 +985,35 @@ mp_int_sqr(mp_int a, mp_int c) */ if (out != MP_DIGITS(c)) { - s_free(MP_DIGITS(c)); - MP_DIGITS(c) = out; - MP_ALLOC(c) = p; + if ((void *) MP_DIGITS(c) != (void *) c) + s_free(MP_DIGITS(c)); + c->digits = out; + c->alloc = p; } - MP_USED(c) = osize; /* might not be true, but we'll fix it ... */ + c->used = osize; /* might not be true, but we'll fix it ... */ CLAMP(c); /* ... right here */ - MP_SIGN(c) = MP_ZPOS; + c->sign = MP_ZPOS; return MP_OK; } -/* }}} */ - -/* {{{ mp_int_div(a, b, q, r) */ - mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) { - int cmp, - last = 0, - lg; + assert(a != NULL && b != NULL && q != r); + + int cmp; mp_result res = MP_OK; - mpz_t temp[2]; mp_int qout, rout; - mp_sign sa = MP_SIGN(a), - sb = MP_SIGN(b); - - CHECK(a != NULL && b != NULL && q != r); + mp_sign sa = MP_SIGN(a); + mp_sign sb = MP_SIGN(b); if (CMPZ(b) == 0) + { return MP_UNDEF; + } else if ((cmp = s_ucmp(a, b)) < 0) { /* @@ -995,7 +1041,7 @@ mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) q->digits[0] = 1; if (sa != sb) - MP_SIGN(q) = MP_NEG; + q->sign = MP_NEG; } return MP_OK; @@ -1006,37 +1052,41 @@ mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) * quotient and remainder, but q and r are allowed to be NULL or to * overlap with the inputs. */ + DECLARE_TEMP(2); + int lg; + if ((lg = s_isp2(b)) < 0) { - if (q && b != q && (res = mp_int_copy(a, q)) == MP_OK) + if (q && b != q) { + REQUIRE(mp_int_copy(a, q)); qout = q; } else { - qout = TEMP(last); - SETUP(mp_int_init_copy(TEMP(last), a), last); + REQUIRE(mp_int_copy(a, TEMP(0))); + qout = TEMP(0); } - if (r && a != r && (res = mp_int_copy(b, r)) == MP_OK) + if (r && a != r) { + REQUIRE(mp_int_copy(b, r)); rout = r; } else { - rout = TEMP(last); - SETUP(mp_int_init_copy(TEMP(last), b), last); + REQUIRE(mp_int_copy(b, TEMP(1))); + rout = TEMP(1); } - if ((res = s_udiv(qout, rout)) != MP_OK) - goto CLEANUP; + REQUIRE(s_udiv_knuth(qout, rout)); } else { - if (q && (res = mp_int_copy(a, q)) != MP_OK) - goto CLEANUP; - if (r && (res = mp_int_copy(a, r)) != MP_OK) - goto CLEANUP; + if (q) + REQUIRE(mp_int_copy(a, q)); + if (r) + REQUIRE(mp_int_copy(a, r)); if (q) s_qdiv(q, (mp_size) lg); @@ -1049,203 +1099,184 @@ mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r) /* Recompute signs for output */ if (rout) { - MP_SIGN(rout) = sa; + rout->sign = sa; if (CMPZ(rout) == 0) - MP_SIGN(rout) = MP_ZPOS; + rout->sign = MP_ZPOS; } if (qout) { - MP_SIGN(qout) = (sa == sb) ? MP_ZPOS : MP_NEG; + qout->sign = (sa == sb) ? MP_ZPOS : MP_NEG; if (CMPZ(qout) == 0) - MP_SIGN(qout) = MP_ZPOS; + qout->sign = MP_ZPOS; } - if (q && (res = mp_int_copy(qout, q)) != MP_OK) - goto CLEANUP; - if (r && (res = mp_int_copy(rout, r)) != MP_OK) - goto CLEANUP; - -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); - + if (q) + REQUIRE(mp_int_copy(qout, q)); + if (r) + REQUIRE(mp_int_copy(rout, r)); + CLEANUP_TEMP(); return res; } -/* }}} */ - -/* {{{ mp_int_mod(a, m, c) */ - mp_result mp_int_mod(mp_int a, mp_int m, mp_int c) { - mp_result res; - mpz_t tmp; - mp_int out; + DECLARE_TEMP(1); + mp_int out = (m == c) ? TEMP(0) : c; - if (m == c) + REQUIRE(mp_int_div(a, m, NULL, out)); + if (CMPZ(out) < 0) { - if ((res = mp_int_init(&tmp)) != MP_OK) - return res; - - out = &tmp; + REQUIRE(mp_int_add(out, m, c)); } else { - out = c; + REQUIRE(mp_int_copy(out, c)); } - - if ((res = mp_int_div(a, m, NULL, out)) != MP_OK) - goto CLEANUP; - - if (CMPZ(out) < 0) - res = mp_int_add(out, m, c); - else - res = mp_int_copy(out, c); - -CLEANUP: - if (out != c) - mp_int_clear(&tmp); - - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - - -/* {{{ mp_int_div_value(a, value, q, r) */ - mp_result -mp_int_div_value(mp_int a, int value, mp_int q, int *r) +mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r) { - mpz_t vtmp, - rtmp; + mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; - mp_result res; - if ((res = mp_int_init(&rtmp)) != MP_OK) - return res; s_fake(&vtmp, value, vbuf); - if ((res = mp_int_div(a, &vtmp, q, &rtmp)) != MP_OK) - goto CLEANUP; + DECLARE_TEMP(1); + REQUIRE(mp_int_div(a, &vtmp, q, TEMP(0))); if (r) - (void) mp_int_to_int(&rtmp, r); /* can't fail */ + (void) mp_int_to_int(TEMP(0), r); /* can't fail */ -CLEANUP: - mp_int_clear(&rtmp); - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_div_pow2(a, p2, q, r) */ - mp_result -mp_int_div_pow2(mp_int a, int p2, mp_int q, mp_int r) +mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r) { - mp_result res = MP_OK; + assert(a != NULL && p2 >= 0 && q != r); - CHECK(a != NULL && p2 >= 0 && q != r); + mp_result res = MP_OK; if (q != NULL && (res = mp_int_copy(a, q)) == MP_OK) + { s_qdiv(q, (mp_size) p2); + } if (res == MP_OK && r != NULL && (res = mp_int_copy(a, r)) == MP_OK) + { s_qmod(r, (mp_size) p2); + } return res; } -/* }}} */ - -/* {{{ mp_int_expt(a, b, c) */ - mp_result -mp_int_expt(mp_int a, int b, mp_int c) +mp_int_expt(mp_int a, mp_small b, mp_int c) { - mpz_t t; - mp_result res; - unsigned int v = abs(b); - - CHECK(b >= 0 && c != NULL); + assert(c != NULL); + if (b < 0) + return MP_RANGE; - if ((res = mp_int_init_copy(&t, a)) != MP_OK) - return res; + DECLARE_TEMP(1); + REQUIRE(mp_int_copy(a, TEMP(0))); (void) mp_int_set_value(c, 1); + unsigned int v = labs(b); + while (v != 0) { if (v & 1) { - if ((res = mp_int_mul(c, &t, c)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_mul(c, TEMP(0), c)); } v >>= 1; if (v == 0) break; - if ((res = mp_int_sqr(&t, &t)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); } -CLEANUP: - mp_int_clear(&t); - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_expt_value(a, b, c) */ - mp_result -mp_int_expt_value(int a, int b, mp_int c) +mp_int_expt_value(mp_small a, mp_small b, mp_int c) { - mpz_t t; - mp_result res; - unsigned int v = abs(b); - - CHECK(b >= 0 && c != NULL); + assert(c != NULL); + if (b < 0) + return MP_RANGE; - if ((res = mp_int_init_value(&t, a)) != MP_OK) - return res; + DECLARE_TEMP(1); + REQUIRE(mp_int_set_value(TEMP(0), a)); (void) mp_int_set_value(c, 1); + unsigned int v = labs(b); + while (v != 0) { if (v & 1) { - if ((res = mp_int_mul(c, &t, c)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_mul(c, TEMP(0), c)); } v >>= 1; if (v == 0) break; - if ((res = mp_int_sqr(&t, &t)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); } -CLEANUP: - mp_int_clear(&t); - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ +mp_result +mp_int_expt_full(mp_int a, mp_int b, mp_int c) +{ + assert(a != NULL && b != NULL && c != NULL); + if (MP_SIGN(b) == MP_NEG) + return MP_RANGE; + + DECLARE_TEMP(1); + REQUIRE(mp_int_copy(a, TEMP(0))); -/* {{{ mp_int_compare(a, b) */ + (void) mp_int_set_value(c, 1); + for (unsigned ix = 0; ix < MP_USED(b); ++ix) + { + mp_digit d = b->digits[ix]; + + for (unsigned jx = 0; jx < MP_DIGIT_BIT; ++jx) + { + if (d & 1) + { + REQUIRE(mp_int_mul(c, TEMP(0), c)); + } + + d >>= 1; + if (d == 0 && ix + 1 == MP_USED(b)) + break; + REQUIRE(mp_int_sqr(TEMP(0), TEMP(0))); + } + } + + CLEANUP_TEMP(); + return MP_OK; +} int mp_int_compare(mp_int a, mp_int b) { - mp_sign sa; + assert(a != NULL && b != NULL); - CHECK(a != NULL && b != NULL); + mp_sign sa = MP_SIGN(a); - sa = MP_SIGN(a); if (sa == MP_SIGN(b)) { int cmp = s_ucmp(a, b); @@ -1255,93 +1286,89 @@ mp_int_compare(mp_int a, mp_int b) * both negative, the sense is reversed. */ if (sa == MP_ZPOS) + { return cmp; + } else + { return -cmp; - + } + } + else if (sa == MP_ZPOS) + { + return 1; } else { - if (sa == MP_ZPOS) - return 1; - else - return -1; + return -1; } } -/* }}} */ - -/* {{{ mp_int_compare_unsigned(a, b) */ - int mp_int_compare_unsigned(mp_int a, mp_int b) { - NRCHECK(a != NULL && b != NULL); + assert(a != NULL && b != NULL); return s_ucmp(a, b); } -/* }}} */ - -/* {{{ mp_int_compare_zero(z) */ - int mp_int_compare_zero(mp_int z) { - NRCHECK(z != NULL); + assert(z != NULL); if (MP_USED(z) == 1 && z->digits[0] == 0) + { return 0; + } else if (MP_SIGN(z) == MP_ZPOS) + { return 1; + } else + { return -1; + } } -/* }}} */ - -/* {{{ mp_int_compare_value(z, value) */ - int -mp_int_compare_value(mp_int z, int value) +mp_int_compare_value(mp_int z, mp_small value) { - mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; - int cmp; + assert(z != NULL); - CHECK(z != NULL); + mp_sign vsign = (value < 0) ? MP_NEG : MP_ZPOS; if (vsign == MP_SIGN(z)) { - cmp = s_vcmp(z, value); + int cmp = s_vcmp(z, value); - if (vsign == MP_ZPOS) - return cmp; - else - return -cmp; + return (vsign == MP_ZPOS) ? cmp : -cmp; } else { - if (value < 0) - return 1; - else - return -1; + return (value < 0) ? 1 : -1; } } -/* }}} */ +int +mp_int_compare_uvalue(mp_int z, mp_usmall uv) +{ + assert(z != NULL); -/* {{{ mp_int_exptmod(a, b, m, c) */ + if (MP_SIGN(z) == MP_NEG) + { + return -1; + } + else + { + return s_uvcmp(z, uv); + } +} mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) { - mp_result res; - mp_size um; - mpz_t temp[3]; - mp_int s; - int last = 0; - - CHECK(a != NULL && b != NULL && c != NULL && m != NULL); + assert(a != NULL && b != NULL && c != NULL && m != NULL); /* Zero moduli and negative exponents are not considered. */ if (CMPZ(m) == 0) @@ -1349,13 +1376,17 @@ mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) if (CMPZ(b) < 0) return MP_RANGE; - um = MP_USED(m); - SETUP(mp_int_init_size(TEMP(0), 2 * um), last); - SETUP(mp_int_init_size(TEMP(1), 2 * um), last); + mp_size um = MP_USED(m); + + DECLARE_TEMP(3); + REQUIRE(GROW(TEMP(0), 2 * um)); + REQUIRE(GROW(TEMP(1), 2 * um)); + + mp_int s; if (c == b || c == m) { - SETUP(mp_int_init_size(TEMP(2), 2 * um), last); + REQUIRE(GROW(TEMP(2), 2 * um)); s = TEMP(2); } else @@ -1363,30 +1394,17 @@ mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c) s = c; } - if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_mod(a, m, TEMP(0))); + REQUIRE(s_brmu(TEMP(1), m)); + REQUIRE(s_embar(TEMP(0), b, m, TEMP(1), s)); + REQUIRE(mp_int_copy(s, c)); - if ((res = s_brmu(TEMP(1), m)) != MP_OK) - goto CLEANUP; - - if ((res = s_embar(TEMP(0), b, m, TEMP(1), s)) != MP_OK) - goto CLEANUP; - - res = mp_int_copy(s, c); - -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); - - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_exptmod_evalue(a, value, m, c) */ - mp_result -mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c) +mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -1396,13 +1414,8 @@ mp_int_exptmod_evalue(mp_int a, int value, mp_int m, mp_int c) return mp_int_exptmod(a, &vtmp, m, c); } -/* }}} */ - -/* {{{ mp_int_exptmod_bvalue(v, b, m, c) */ - mp_result -mp_int_exptmod_bvalue(int value, mp_int b, - mp_int m, mp_int c) +mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c) { mpz_t vtmp; mp_digit vbuf[MP_VALUE_DIGITS(value)]; @@ -1412,20 +1425,11 @@ mp_int_exptmod_bvalue(int value, mp_int b, return mp_int_exptmod(&vtmp, b, m, c); } -/* }}} */ - -/* {{{ mp_int_exptmod_known(a, b, m, mu, c) */ - mp_result -mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) +mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, + mp_int c) { - mp_result res; - mp_size um; - mpz_t temp[2]; - mp_int s; - int last = 0; - - CHECK(a && b && m && c); + assert(a && b && m && c); /* Zero moduli and negative exponents are not considered. */ if (CMPZ(m) == 0) @@ -1433,12 +1437,16 @@ mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) if (CMPZ(b) < 0) return MP_RANGE; - um = MP_USED(m); - SETUP(mp_int_init_size(TEMP(0), 2 * um), last); + DECLARE_TEMP(2); + mp_size um = MP_USED(m); + + REQUIRE(GROW(TEMP(0), 2 * um)); + + mp_int s; if (c == b || c == m) { - SETUP(mp_int_init_size(TEMP(1), 2 * um), last); + REQUIRE(GROW(TEMP(1), 2 * um)); s = TEMP(1); } else @@ -1446,68 +1454,41 @@ mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) s = c; } - if ((res = mp_int_mod(a, m, TEMP(0))) != MP_OK) - goto CLEANUP; - - if ((res = s_embar(TEMP(0), b, m, mu, s)) != MP_OK) - goto CLEANUP; - - res = mp_int_copy(s, c); + REQUIRE(mp_int_mod(a, m, TEMP(0))); + REQUIRE(s_embar(TEMP(0), b, m, mu, s)); + REQUIRE(mp_int_copy(s, c)); -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); - - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_redux_const(m, c) */ - mp_result mp_int_redux_const(mp_int m, mp_int c) { - CHECK(m != NULL && c != NULL && m != c); + assert(m != NULL && c != NULL && m != c); return s_brmu(c, m); } -/* }}} */ - -/* {{{ mp_int_invmod(a, m, c) */ - mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c) { - mp_result res; - mp_sign sa; - int last = 0; - mpz_t temp[2]; - - CHECK(a != NULL && m != NULL && c != NULL); + assert(a != NULL && m != NULL && c != NULL); if (CMPZ(a) == 0 || CMPZ(m) <= 0) return MP_RANGE; - sa = MP_SIGN(a); /* need this for the result later */ - - for (last = 0; last < 2; ++last) - if ((res = mp_int_init(TEMP(last))) != MP_OK) - goto CLEANUP; + DECLARE_TEMP(2); - if ((res = mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_egcd(a, m, TEMP(0), TEMP(1), NULL)); if (mp_int_compare_value(TEMP(0), 1) != 0) { - res = MP_UNDEF; - goto CLEANUP; + REQUIRE(MP_UNDEF); } /* It is first necessary to constrain the value to the proper range */ - if ((res = mp_int_mod(TEMP(1), m, TEMP(1))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_mod(TEMP(1), m, TEMP(1))); /* * Now, if 'a' was originally negative, the value we have is actually the @@ -1515,136 +1496,112 @@ mp_int_invmod(mp_int a, mp_int m, mp_int c) * have to subtract from the modulus. Otherwise, the value is okay as it * stands. */ - if (sa == MP_NEG) - res = mp_int_sub(m, TEMP(1), c); + if (MP_SIGN(a) == MP_NEG) + { + REQUIRE(mp_int_sub(m, TEMP(1), c)); + } else - res = mp_int_copy(TEMP(1), c); - -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); + { + REQUIRE(mp_int_copy(TEMP(1), c)); + } - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_gcd(a, b, c) */ - /* Binary GCD algorithm due to Josef Stein, 1961 */ mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c) { - int ca, - cb, - k = 0; - mpz_t u, - v, - t; - mp_result res; + assert(a != NULL && b != NULL && c != NULL); - CHECK(a != NULL && b != NULL && c != NULL); + int ca = CMPZ(a); + int cb = CMPZ(b); - ca = CMPZ(a); - cb = CMPZ(b); if (ca == 0 && cb == 0) + { return MP_UNDEF; + } else if (ca == 0) + { return mp_int_abs(b, c); + } else if (cb == 0) + { return mp_int_abs(a, c); + } - if ((res = mp_int_init(&t)) != MP_OK) - return res; - if ((res = mp_int_init_copy(&u, a)) != MP_OK) - goto U; - if ((res = mp_int_init_copy(&v, b)) != MP_OK) - goto V; + DECLARE_TEMP(3); + REQUIRE(mp_int_copy(a, TEMP(0))); + REQUIRE(mp_int_copy(b, TEMP(1))); + + TEMP(0)->sign = MP_ZPOS; + TEMP(1)->sign = MP_ZPOS; - MP_SIGN(&u) = MP_ZPOS; - MP_SIGN(&v) = MP_ZPOS; + int k = 0; { /* Divide out common factors of 2 from u and v */ - int div2_u = s_dp2k(&u), - div2_v = s_dp2k(&v); + int div2_u = s_dp2k(TEMP(0)); + int div2_v = s_dp2k(TEMP(1)); k = MIN(div2_u, div2_v); - s_qdiv(&u, (mp_size) k); - s_qdiv(&v, (mp_size) k); + s_qdiv(TEMP(0), (mp_size) k); + s_qdiv(TEMP(1), (mp_size) k); } - if (mp_int_is_odd(&u)) + if (mp_int_is_odd(TEMP(0))) { - if ((res = mp_int_neg(&v, &t)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_neg(TEMP(1), TEMP(2))); } else { - if ((res = mp_int_copy(&u, &t)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_copy(TEMP(0), TEMP(2))); } for (;;) { - s_qdiv(&t, s_dp2k(&t)); + s_qdiv(TEMP(2), s_dp2k(TEMP(2))); - if (CMPZ(&t) > 0) + if (CMPZ(TEMP(2)) > 0) { - if ((res = mp_int_copy(&t, &u)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_copy(TEMP(2), TEMP(0))); } else { - if ((res = mp_int_neg(&t, &v)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_neg(TEMP(2), TEMP(1))); } - if ((res = mp_int_sub(&u, &v, &t)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_sub(TEMP(0), TEMP(1), TEMP(2))); - if (CMPZ(&t) == 0) + if (CMPZ(TEMP(2)) == 0) break; } - if ((res = mp_int_abs(&u, c)) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_abs(TEMP(0), c)); if (!s_qmul(c, (mp_size) k)) - res = MP_MEMORY; - -CLEANUP: - mp_int_clear(&v); -V: mp_int_clear(&u); -U: mp_int_clear(&t); + REQUIRE(MP_MEMORY); - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_egcd(a, b, c, x, y) */ - -/* This is the binary GCD algorithm again, but this time we keep track - of the elementary matrix operations as we go, so we can get values - x and y satisfying c = ax + by. +/* This is the binary GCD algorithm again, but this time we keep track of the + elementary matrix operations as we go, so we can get values x and y + satisfying c = ax + by. */ mp_result -mp_int_egcd(mp_int a, mp_int b, mp_int c, - mp_int x, mp_int y) -{ - int k, - last = 0, - ca, - cb; - mpz_t temp[8]; - mp_result res; +mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y) +{ + assert(a != NULL && b != NULL && c != NULL && (x != NULL || y != NULL)); - CHECK(a != NULL && b != NULL && c != NULL && - (x != NULL || y != NULL)); + mp_result res = MP_OK; + int ca = CMPZ(a); + int cb = CMPZ(b); - ca = CMPZ(a); - cb = CMPZ(b); if (ca == 0 && cb == 0) + { return MP_UNDEF; + } else if (ca == 0) { if ((res = mp_int_abs(b, c)) != MP_OK) @@ -1665,20 +1622,17 @@ mp_int_egcd(mp_int a, mp_int b, mp_int c, /* * Initialize temporaries: A:0, B:1, C:2, D:3, u:4, v:5, ou:6, ov:7 */ - for (last = 0; last < 4; ++last) - { - if ((res = mp_int_init(TEMP(last))) != MP_OK) - goto CLEANUP; - } - TEMP(0)->digits[0] = 1; - TEMP(3)->digits[0] = 1; - - SETUP(mp_int_init_copy(TEMP(4), a), last); - SETUP(mp_int_init_copy(TEMP(5), b), last); + DECLARE_TEMP(8); + REQUIRE(mp_int_set_value(TEMP(0), 1)); + REQUIRE(mp_int_set_value(TEMP(3), 1)); + REQUIRE(mp_int_copy(a, TEMP(4))); + REQUIRE(mp_int_copy(b, TEMP(5))); /* We will work with absolute values here */ - MP_SIGN(TEMP(4)) = MP_ZPOS; - MP_SIGN(TEMP(5)) = MP_ZPOS; + TEMP(4)->sign = MP_ZPOS; + TEMP(5)->sign = MP_ZPOS; + + int k = 0; { /* Divide out common factors of 2 from u and v */ int div2_u = s_dp2k(TEMP(4)), @@ -1689,8 +1643,8 @@ mp_int_egcd(mp_int a, mp_int b, mp_int c, s_qdiv(TEMP(5), k); } - SETUP(mp_int_init_copy(TEMP(6), TEMP(4)), last); - SETUP(mp_int_init_copy(TEMP(7), TEMP(5)), last); + REQUIRE(mp_int_copy(TEMP(4), TEMP(6))); + REQUIRE(mp_int_copy(TEMP(5), TEMP(7))); for (;;) { @@ -1700,10 +1654,8 @@ mp_int_egcd(mp_int a, mp_int b, mp_int c, if (mp_int_is_odd(TEMP(0)) || mp_int_is_odd(TEMP(1))) { - if ((res = mp_int_add(TEMP(0), TEMP(7), TEMP(0))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(1), TEMP(6), TEMP(1))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_add(TEMP(0), TEMP(7), TEMP(0))); + REQUIRE(mp_int_sub(TEMP(1), TEMP(6), TEMP(1))); } s_qdiv(TEMP(0), 1); @@ -1716,10 +1668,8 @@ mp_int_egcd(mp_int a, mp_int b, mp_int c, if (mp_int_is_odd(TEMP(2)) || mp_int_is_odd(TEMP(3))) { - if ((res = mp_int_add(TEMP(2), TEMP(7), TEMP(2))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(3), TEMP(6), TEMP(3))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_add(TEMP(2), TEMP(7), TEMP(2))); + REQUIRE(mp_int_sub(TEMP(3), TEMP(6), TEMP(3))); } s_qdiv(TEMP(2), 1); @@ -1728,157 +1678,163 @@ mp_int_egcd(mp_int a, mp_int b, mp_int c, if (mp_int_compare(TEMP(4), TEMP(5)) >= 0) { - if ((res = mp_int_sub(TEMP(4), TEMP(5), TEMP(4))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(0), TEMP(2), TEMP(0))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(1), TEMP(3), TEMP(1))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_sub(TEMP(4), TEMP(5), TEMP(4))); + REQUIRE(mp_int_sub(TEMP(0), TEMP(2), TEMP(0))); + REQUIRE(mp_int_sub(TEMP(1), TEMP(3), TEMP(1))); } else { - if ((res = mp_int_sub(TEMP(5), TEMP(4), TEMP(5))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(2), TEMP(0), TEMP(2))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_sub(TEMP(3), TEMP(1), TEMP(3))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_sub(TEMP(5), TEMP(4), TEMP(5))); + REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); + REQUIRE(mp_int_sub(TEMP(3), TEMP(1), TEMP(3))); } if (CMPZ(TEMP(4)) == 0) { - if (x && (res = mp_int_copy(TEMP(2), x)) != MP_OK) - goto CLEANUP; - if (y && (res = mp_int_copy(TEMP(3), y)) != MP_OK) - goto CLEANUP; + if (x) + REQUIRE(mp_int_copy(TEMP(2), x)); + if (y) + REQUIRE(mp_int_copy(TEMP(3), y)); if (c) { if (!s_qmul(TEMP(5), k)) { - res = MP_MEMORY; - goto CLEANUP; + REQUIRE(MP_MEMORY); } - - res = mp_int_copy(TEMP(5), c); + REQUIRE(mp_int_copy(TEMP(5), c)); } break; } } -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); - - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ +mp_result +mp_int_lcm(mp_int a, mp_int b, mp_int c) +{ + assert(a != NULL && b != NULL && c != NULL); + + /* + * Since a * b = gcd(a, b) * lcm(a, b), we can compute lcm(a, b) = (a / + * gcd(a, b)) * b. + * + * This formulation insures everything works even if the input variables + * share space. + */ + DECLARE_TEMP(1); + REQUIRE(mp_int_gcd(a, b, TEMP(0))); + REQUIRE(mp_int_div(a, TEMP(0), TEMP(0), NULL)); + REQUIRE(mp_int_mul(TEMP(0), b, TEMP(0))); + REQUIRE(mp_int_copy(TEMP(0), c)); -/* {{{ mp_int_divisible_value(a, v) */ + CLEANUP_TEMP(); + return MP_OK; +} -int -mp_int_divisible_value(mp_int a, int v) +bool +mp_int_divisible_value(mp_int a, mp_small v) { - int rem = 0; + mp_small rem = 0; if (mp_int_div_value(a, v, NULL, &rem) != MP_OK) - return 0; - + { + return false; + } return rem == 0; } -/* }}} */ - -/* {{{ mp_int_is_pow2(z) */ - int mp_int_is_pow2(mp_int z) { - CHECK(z != NULL); + assert(z != NULL); return s_isp2(z); } -/* }}} */ - -/* {{{ mp_int_sqrt(a, c) */ - +/* Implementation of Newton's root finding method, based loosely on a patch + contributed by Hal Finkel + modified by M. J. Fromberger. + */ mp_result -mp_int_sqrt(mp_int a, mp_int c) +mp_int_root(mp_int a, mp_small b, mp_int c) { - mp_result res = MP_OK; - mpz_t temp[2]; - int last = 0; + assert(a != NULL && c != NULL && b > 0); - CHECK(a != NULL && c != NULL); + if (b == 1) + { + return mp_int_copy(a, c); + } + bool flips = false; - /* The square root of a negative value does not exist in the integers. */ if (MP_SIGN(a) == MP_NEG) - return MP_UNDEF; + { + if (b % 2 == 0) + { + return MP_UNDEF; /* root does not exist for negative a with + * even b */ + } + else + { + flips = true; + } + } - SETUP(mp_int_init_copy(TEMP(last), a), last); - SETUP(mp_int_init(TEMP(last)), last); + DECLARE_TEMP(5); + REQUIRE(mp_int_copy(a, TEMP(0))); + REQUIRE(mp_int_copy(a, TEMP(1))); + TEMP(0)->sign = MP_ZPOS; + TEMP(1)->sign = MP_ZPOS; for (;;) { - if ((res = mp_int_sqr(TEMP(0), TEMP(1))) != MP_OK) - goto CLEANUP; + REQUIRE(mp_int_expt(TEMP(1), b, TEMP(2))); - if (mp_int_compare_unsigned(a, TEMP(1)) == 0) + if (mp_int_compare_unsigned(TEMP(2), TEMP(0)) <= 0) break; - if ((res = mp_int_copy(a, TEMP(1))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_div(TEMP(1), TEMP(0), TEMP(1), NULL)) != MP_OK) - goto CLEANUP; - if ((res = mp_int_add(TEMP(0), TEMP(1), TEMP(1))) != MP_OK) - goto CLEANUP; - if ((res = mp_int_div_pow2(TEMP(1), 1, TEMP(1), NULL)) != MP_OK) - goto CLEANUP; - - if (mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) - break; - if ((res = mp_int_sub_value(TEMP(0), 1, TEMP(0))) != MP_OK) - goto CLEANUP; - if (mp_int_compare_unsigned(TEMP(0), TEMP(1)) == 0) - break; + REQUIRE(mp_int_sub(TEMP(2), TEMP(0), TEMP(2))); + REQUIRE(mp_int_expt(TEMP(1), b - 1, TEMP(3))); + REQUIRE(mp_int_mul_value(TEMP(3), b, TEMP(3))); + REQUIRE(mp_int_div(TEMP(2), TEMP(3), TEMP(4), NULL)); + REQUIRE(mp_int_sub(TEMP(1), TEMP(4), TEMP(4))); - if ((res = mp_int_copy(TEMP(1), TEMP(0))) != MP_OK) - goto CLEANUP; + if (mp_int_compare_unsigned(TEMP(1), TEMP(4)) == 0) + { + REQUIRE(mp_int_sub_value(TEMP(4), 1, TEMP(4))); + } + REQUIRE(mp_int_copy(TEMP(4), TEMP(1))); } - res = mp_int_copy(TEMP(0), c); + REQUIRE(mp_int_copy(TEMP(1), c)); -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); + /* If the original value of a was negative, flip the output sign. */ + if (flips) + (void) mp_int_neg(c, c); /* cannot fail */ - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ mp_int_to_int(z, out) */ - mp_result -mp_int_to_int(mp_int z, int *out) +mp_int_to_int(mp_int z, mp_small *out) { - unsigned int uv = 0; - mp_size uz; - mp_digit *dz; - mp_sign sz; + assert(z != NULL); - CHECK(z != NULL); + /* Make sure the value is representable as a small integer */ + mp_sign sz = MP_SIGN(z); - /* Make sure the value is representable as an int */ - sz = MP_SIGN(z); - if ((sz == MP_ZPOS && mp_int_compare_value(z, INT_MAX) > 0) || - mp_int_compare_value(z, INT_MIN) < 0) + if ((sz == MP_ZPOS && mp_int_compare_value(z, MP_SMALL_MAX) > 0) || + mp_int_compare_value(z, MP_SMALL_MIN) < 0) + { return MP_RANGE; + } - uz = MP_USED(z); - dz = MP_DIGITS(z) + uz - 1; + mp_usmall uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z) + uz - 1; + mp_small uv = 0; while (uz > 0) { @@ -1888,33 +1844,56 @@ mp_int_to_int(mp_int z, int *out) } if (out) - *out = (sz == MP_NEG) ? -(int) uv : (int) uv; + *out = (mp_small) ((sz == MP_NEG) ? -uv : uv); return MP_OK; } -/* }}} */ - -/* {{{ mp_int_to_string(z, radix, str, limit) */ - mp_result -mp_int_to_string(mp_int z, mp_size radix, - char *str, int limit) +mp_int_to_uint(mp_int z, mp_usmall *out) { - mp_result res; - int cmp = 0; + assert(z != NULL); - CHECK(z != NULL && str != NULL && limit >= 2); + /* Make sure the value is representable as an unsigned small integer */ + mp_size sz = MP_SIGN(z); - if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) + if (sz == MP_NEG || mp_int_compare_uvalue(z, MP_USMALL_MAX) > 0) + { return MP_RANGE; + } + + mp_size uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z) + uz - 1; + mp_usmall uv = 0; + + while (uz > 0) + { + uv <<= MP_DIGIT_BIT / 2; + uv = (uv << (MP_DIGIT_BIT / 2)) | *dz--; + --uz; + } + + if (out) + *out = uv; + + return MP_OK; +} + +mp_result +mp_int_to_string(mp_int z, mp_size radix, char *str, int limit) +{ + assert(z != NULL && str != NULL && limit >= 2); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); + + int cmp = 0; if (CMPZ(z) == 0) { - *str++ = s_val2ch(0, mp_flags & MP_CAP_DIGITS); + *str++ = s_val2ch(0, 1); } else { + mp_result res; mpz_t tmp; char *h, *t; @@ -1938,7 +1917,7 @@ mp_int_to_string(mp_int z, mp_size radix, break; d = s_ddiv(&tmp, (mp_digit) radix); - *str++ = s_val2ch(d, mp_flags & MP_CAP_DIGITS); + *str++ = s_val2ch(d, 1); } t = str - 1; @@ -1956,26 +1935,22 @@ mp_int_to_string(mp_int z, mp_size radix, *str = '\0'; if (cmp == 0) + { return MP_OK; + } else + { return MP_TRUNC; + } } -/* }}} */ - -/* {{{ mp_int_string_len(z, radix) */ - mp_result mp_int_string_len(mp_int z, mp_size radix) { - int len; - - CHECK(z != NULL); - - if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) - return MP_RANGE; + assert(z != NULL); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); - len = s_outlen(z, radix) + 1; /* for terminator */ + int len = s_outlen(z, radix) + 1; /* for terminator */ /* Allow for sign marker on negatives */ if (MP_SIGN(z) == MP_NEG) @@ -1984,31 +1959,19 @@ mp_int_string_len(mp_int z, mp_size radix) return len; } -/* }}} */ - -/* {{{ mp_int_read_string(z, radix, *str) */ - /* Read zero-terminated string into z */ mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str) { return mp_int_read_cstring(z, radix, str, NULL); - } -/* }}} */ - -/* {{{ mp_int_read_cstring(z, radix, *str, **end) */ - mp_result -mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end) +mp_int_read_cstring(mp_int z, mp_size radix, const char *str, + char **end) { - int ch; - - CHECK(z != NULL && str != NULL); - - if (radix < MP_MIN_RADIX || radix > MP_MAX_RADIX) - return MP_RANGE; + assert(z != NULL && str != NULL); + assert(radix >= MP_MIN_RADIX && radix <= MP_MAX_RADIX); /* Skip leading whitespace */ while (isspace((unsigned char) *str)) @@ -2018,17 +1981,19 @@ mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end) switch (*str) { case '-': - MP_SIGN(z) = MP_NEG; + z->sign = MP_NEG; ++str; break; case '+': ++str; /* fallthrough */ default: - MP_SIGN(z) = MP_ZPOS; + z->sign = MP_ZPOS; break; } /* Skip leading zeroes */ + int ch; + while ((ch = s_ch2val(*str, radix)) == 0) ++str; @@ -2036,7 +2001,7 @@ mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end) if (!s_pad(z, s_inlen(strlen(str), radix))) return MP_MEMORY; - MP_USED(z) = 1; + z->used = 1; z->digits[0] = 0; while (*str != '\0' && ((ch = s_ch2val(*str, radix)) >= 0)) @@ -2050,41 +2015,38 @@ mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end) /* Override sign for zero, even if negative specified. */ if (CMPZ(z) == 0) - MP_SIGN(z) = MP_ZPOS; + z->sign = MP_ZPOS; if (end != NULL) - *end = (char *) str; + *end = unconstify(char *, str); /* * Return a truncation error if the string has unprocessed characters * remaining, so the caller can tell if the whole string was done */ if (*str != '\0') + { return MP_TRUNC; + } else + { return MP_OK; + } } -/* }}} */ - -/* {{{ mp_int_count_bits(z) */ - mp_result mp_int_count_bits(mp_int z) { - mp_size nbits = 0, - uz; - mp_digit d; + assert(z != NULL); - CHECK(z != NULL); + mp_size uz = MP_USED(z); - uz = MP_USED(z); if (uz == 1 && z->digits[0] == 0) return 1; --uz; - nbits = uz * MP_DIGIT_BIT; - d = z->digits[uz]; + mp_size nbits = uz * MP_DIGIT_BIT; + mp_digit d = z->digits[uz]; while (d != 0) { @@ -2095,21 +2057,15 @@ mp_int_count_bits(mp_int z) return nbits; } -/* }}} */ - -/* {{{ mp_int_to_binary(z, buf, limit) */ - mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit) { static const int PAD_FOR_2C = 1; - mp_result res; - int limpos = limit; - - CHECK(z != NULL && buf != NULL); + assert(z != NULL && buf != NULL); - res = s_tobin(z, buf, &limpos, PAD_FOR_2C); + int limpos = limit; + mp_result res = s_tobin(z, buf, &limpos, PAD_FOR_2C); if (MP_SIGN(z) == MP_NEG) s_2comp(buf, limpos); @@ -2117,22 +2073,14 @@ mp_int_to_binary(mp_int z, unsigned char *buf, int limit) return res; } -/* }}} */ - -/* {{{ mp_int_read_binary(z, buf, len) */ - mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len) { - mp_size need, - i; - unsigned char *tmp; - mp_digit *dz; - - CHECK(z != NULL && buf != NULL && len > 0); + assert(z != NULL && buf != NULL && len > 0); /* Figure out how many digits are needed to represent this value */ - need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) return MP_MEMORY; @@ -2144,12 +2092,14 @@ mp_int_read_binary(mp_int z, unsigned char *buf, int len) */ if (buf[0] >> (CHAR_BIT - 1)) { - MP_SIGN(z) = MP_NEG; + z->sign = MP_NEG; s_2comp(buf, len); } - dz = MP_DIGITS(z); - for (tmp = buf, i = len; i > 0; --i, ++tmp) + mp_digit *dz = MP_DIGITS(z); + unsigned char *tmp = buf; + + for (int i = len; i > 0; --i, ++tmp) { s_qmul(z, (mp_size) CHAR_BIT); *dz |= *tmp; @@ -2162,20 +2112,15 @@ mp_int_read_binary(mp_int z, unsigned char *buf, int len) return MP_OK; } -/* }}} */ - -/* {{{ mp_int_binary_len(z) */ - mp_result mp_int_binary_len(mp_int z) { mp_result res = mp_int_count_bits(z); - int bytes = mp_int_unsigned_len(z); if (res <= 0) return res; - bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + int bytes = mp_int_unsigned_len(z); /* * If the highest-order bit falls exactly on a byte boundary, we need to @@ -2188,193 +2133,170 @@ mp_int_binary_len(mp_int z) return bytes; } -/* }}} */ - -/* {{{ mp_int_to_unsigned(z, buf, limit) */ - mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit) { static const int NO_PADDING = 0; - CHECK(z != NULL && buf != NULL); + assert(z != NULL && buf != NULL); return s_tobin(z, buf, &limit, NO_PADDING); } -/* }}} */ - -/* {{{ mp_int_read_unsigned(z, buf, len) */ - mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len) { - mp_size need, - i; - unsigned char *tmp; - mp_digit *dz; - - CHECK(z != NULL && buf != NULL && len > 0); + assert(z != NULL && buf != NULL && len > 0); /* Figure out how many digits are needed to represent this value */ - need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + mp_size need = ((len * CHAR_BIT) + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT; + if (!s_pad(z, need)) return MP_MEMORY; mp_int_zero(z); - dz = MP_DIGITS(z); - for (tmp = buf, i = len; i > 0; --i, ++tmp) + unsigned char *tmp = buf; + + for (int i = len; i > 0; --i, ++tmp) { (void) s_qmul(z, CHAR_BIT); - *dz |= *tmp; + *MP_DIGITS(z) |= *tmp; } return MP_OK; } -/* }}} */ - -/* {{{ mp_int_unsigned_len(z) */ - mp_result mp_int_unsigned_len(mp_int z) { mp_result res = mp_int_count_bits(z); - int bytes; if (res <= 0) return res; - bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; + int bytes = (res + (CHAR_BIT - 1)) / CHAR_BIT; return bytes; } -/* }}} */ - -/* {{{ mp_error_string(res) */ - const char * mp_error_string(mp_result res) { - int ix; - if (res > 0) return s_unknown_err; res = -res; + int ix; + for (ix = 0; ix < res && s_error_msg[ix] != NULL; ++ix) ; if (s_error_msg[ix] != NULL) + { return s_error_msg[ix]; + } else + { return s_unknown_err; + } } -/* }}} */ - /*------------------------------------------------------------------------*/ /* Private functions for internal use. These make assumptions. */ -/* {{{ s_alloc(num) */ +#if IMATH_DEBUG +static const mp_digit fill = (mp_digit) 0xdeadbeefabad1dea; +#endif static mp_digit * s_alloc(mp_size num) { mp_digit *out = px_alloc(num * sizeof(mp_digit)); - assert(out != NULL); /* for debugging */ + assert(out != NULL); +#if IMATH_DEBUG + for (mp_size ix = 0; ix < num; ++ix) + out[ix] = fill; +#endif return out; } -/* }}} */ - -/* {{{ s_realloc(old, num) */ - static mp_digit * -s_realloc(mp_digit *old, mp_size num) +s_realloc(mp_digit *old, mp_size osize, mp_size nsize) { - mp_digit *new = px_realloc(old, num * sizeof(mp_digit)); +#if IMATH_DEBUG + mp_digit *new = s_alloc(nsize); - assert(new != NULL); /* for debugging */ + assert(new != NULL); - return new; -} + for (mp_size ix = 0; ix < nsize; ++ix) + new[ix] = fill; + memcpy(new, old, osize * sizeof(mp_digit)); +#else + mp_digit *new = px_realloc(old, nsize * sizeof(mp_digit)); -/* }}} */ + assert(new != NULL); +#endif -/* {{{ s_free(ptr) */ + return new; +} -#if TRACEABLE_FREE static void s_free(void *ptr) { px_free(ptr); } -#endif - -/* }}} */ - -/* {{{ s_pad(z, min) */ -static int +static bool s_pad(mp_int z, mp_size min) { if (MP_ALLOC(z) < min) { - mp_size nsize = ROUND_PREC(min); - mp_digit *tmp = s_realloc(MP_DIGITS(z), nsize); + mp_size nsize = s_round_prec(min); + mp_digit *tmp; - if (tmp == NULL) - return 0; + if (z->digits == &(z->single)) + { + if ((tmp = s_alloc(nsize)) == NULL) + return false; + tmp[0] = z->single; + } + else if ((tmp = s_realloc(MP_DIGITS(z), MP_ALLOC(z), nsize)) == NULL) + { + return false; + } - MP_DIGITS(z) = tmp; - MP_ALLOC(z) = nsize; + z->digits = tmp; + z->alloc = nsize; } - return 1; + return true; } -/* }}} */ - -/* {{{ s_clamp(z) */ - -#if TRACEABLE_CLAMP +/* Note: This will not work correctly when value == MP_SMALL_MIN */ static void -s_clamp(mp_int z) +s_fake(mp_int z, mp_small value, mp_digit vbuf[]) { - mp_size uz = MP_USED(z); - mp_digit *zd = MP_DIGITS(z) + uz - 1; - - while (uz > 1 && (*zd-- == 0)) - --uz; + mp_usmall uv = (mp_usmall) (value < 0) ? -value : value; - MP_USED(z) = uz; + s_ufake(z, uv, vbuf); + if (value < 0) + z->sign = MP_NEG; } -#endif - -/* }}} */ - -/* {{{ s_fake(z, value, vbuf) */ static void -s_fake(mp_int z, int value, mp_digit vbuf[]) +s_ufake(mp_int z, mp_usmall value, mp_digit vbuf[]) { - mp_size uv = (mp_size) s_vpack(value, vbuf); + mp_size ndig = (mp_size) s_uvpack(value, vbuf); - z->used = uv; + z->used = ndig; z->alloc = MP_VALUE_DIGITS(value); - z->sign = (value < 0) ? MP_NEG : MP_ZPOS; + z->sign = MP_ZPOS; z->digits = vbuf; } -/* }}} */ - -/* {{{ s_cdig(da, db, len) */ - static int s_cdig(mp_digit *da, mp_digit *db, mp_size len) { @@ -2384,22 +2306,21 @@ s_cdig(mp_digit *da, mp_digit *db, mp_size len) for ( /* */ ; len != 0; --len, --dat, --dbt) { if (*dat > *dbt) + { return 1; + } else if (*dat < *dbt) + { return -1; + } } return 0; } -/* }}} */ - -/* {{{ s_vpack(v, t[]) */ - static int -s_vpack(int v, mp_digit t[]) +s_uvpack(mp_usmall uv, mp_digit t[]) { - unsigned int uv = (unsigned int) ((v < 0) ? -v : v); int ndig = 0; if (uv == 0) @@ -2417,10 +2338,6 @@ s_vpack(int v, mp_digit t[]) return ndig; } -/* }}} */ - -/* {{{ s_ucmp(a, b) */ - static int s_ucmp(mp_int a, mp_int b) { @@ -2428,41 +2345,47 @@ s_ucmp(mp_int a, mp_int b) ub = MP_USED(b); if (ua > ub) + { return 1; + } else if (ub > ua) + { return -1; + } else + { return s_cdig(MP_DIGITS(a), MP_DIGITS(b), ua); + } } -/* }}} */ - -/* {{{ s_vcmp(a, v) */ - static int -s_vcmp(mp_int a, int v) +s_vcmp(mp_int a, mp_small v) { - mp_digit vdig[MP_VALUE_DIGITS(v)]; - int ndig = 0; - mp_size ua = MP_USED(a); - - ndig = s_vpack(v, vdig); +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4146) +#endif + mp_usmall uv = (v < 0) ? -(mp_usmall) v : (mp_usmall) v; +#if _MSC_VER +#pragma warning(pop) +#endif - if (ua > ndig) - return 1; - else if (ua < ndig) - return -1; - else - return s_cdig(MP_DIGITS(a), vdig, ndig); + return s_uvcmp(a, uv); } -/* }}} */ +static int +s_uvcmp(mp_int a, mp_usmall uv) +{ + mpz_t vtmp; + mp_digit vdig[MP_VALUE_DIGITS(uv)]; -/* {{{ s_uadd(da, db, dc, size_a, size_b) */ + s_ufake(&vtmp, uv, vdig); + return s_ucmp(a, &vtmp); +} static mp_digit -s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { mp_size pos; mp_word w = 0; @@ -2495,13 +2418,9 @@ s_uadd(mp_digit *da, mp_digit *db, mp_digit *dc, return (mp_digit) w; } -/* }}} */ - -/* {{{ s_usub(da, db, dc, size_a, size_b) */ - static void -s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { mp_size pos; mp_word w = 0; @@ -2513,7 +2432,8 @@ s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, for (pos = 0; pos < size_b; ++pos, ++da, ++db, ++dc) { w = ((mp_word) MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word) *da) - w - (mp_word) *db; + (mp_word) *da) - + w - (mp_word) *db; *dc = LOWER_HALF(w); w = (UPPER_HALF(w) == 0); @@ -2523,7 +2443,8 @@ s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, for ( /* */ ; pos < size_a; ++pos, ++da, ++dc) { w = ((mp_word) MP_DIGIT_MAX + 1 + /* MP_RADIX */ - (mp_word) *da) - w; + (mp_word) *da) - + w; *dc = LOWER_HALF(w); w = (UPPER_HALF(w) == 0); @@ -2533,13 +2454,9 @@ s_usub(mp_digit *da, mp_digit *db, mp_digit *dc, assert(w == 0); } -/* }}} */ - -/* {{{ s_kmul(da, db, dc, size_a, size_b) */ - static int -s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { mp_size bot_size; @@ -2561,11 +2478,8 @@ s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, * Karatsuba algorithm to compute the product; otherwise use the normal * multiplication algorithm */ - if (multiply_threshold && - size_a >= multiply_threshold && - size_b > bot_size) + if (multiply_threshold && size_a >= multiply_threshold && size_b > bot_size) { - mp_digit *t1, *t2, *t3, @@ -2617,12 +2531,11 @@ s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, /* Assemble the output value */ COPY(t1, dc, buf_size); - carry = s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); assert(carry == 0); - carry = s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, - buf_size, buf_size); + carry = + s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); assert(carry == 0); s_free(t1); /* note t2 and t3 are just internal pointers @@ -2636,13 +2549,9 @@ s_kmul(mp_digit *da, mp_digit *db, mp_digit *dc, return 1; } -/* }}} */ - -/* {{{ s_umul(da, db, dc, size_a, size_b) */ - static void -s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, - mp_size size_a, mp_size size_b) +s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, mp_size size_a, + mp_size size_b) { mp_size a, b; @@ -2669,10 +2578,6 @@ s_umul(mp_digit *da, mp_digit *db, mp_digit *dc, } } -/* }}} */ - -/* {{{ s_ksqr(da, dc, size_a) */ - static int s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) { @@ -2682,7 +2587,8 @@ s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) mp_digit *a_top = da + bot_size; mp_digit *t1, *t2, - *t3; + *t3, + carry PG_USED_FOR_ASSERTS_ONLY; mp_size at_size = size_a - bot_size; mp_size buf_size = 2 * bot_size; @@ -2716,13 +2622,14 @@ s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) /* Assemble the output value */ COPY(t1, dc, 2 * bot_size); - (void) s_uadd(t3, dc + bot_size, dc + bot_size, - buf_size + 1, buf_size + 1); + carry = s_uadd(t3, dc + bot_size, dc + bot_size, buf_size + 1, buf_size); + assert(carry == 0); - (void) s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, - buf_size, buf_size); + carry = + s_uadd(t2, dc + 2 * bot_size, dc + 2 * bot_size, buf_size, buf_size); + assert(carry == 0); - px_free(t1); /* note that t2 and t2 are internal pointers + s_free(t1); /* note that t2 and t2 are internal pointers * only */ } @@ -2734,10 +2641,6 @@ s_ksqr(mp_digit *da, mp_digit *dc, mp_size size_a) return 1; } -/* }}} */ - -/* {{{ s_usqr(da, dc, size_a) */ - static void s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) { @@ -2800,10 +2703,6 @@ s_usqr(mp_digit *da, mp_digit *dc, mp_size size_a) } } -/* }}} */ - -/* {{{ s_dadd(a, b) */ - static void s_dadd(mp_int a, mp_digit b) { @@ -2826,14 +2725,10 @@ s_dadd(mp_int a, mp_digit b) if (w) { *da = (mp_digit) w; - MP_USED(a) += 1; + a->used += 1; } } -/* }}} */ - -/* {{{ s_dmul(a, b) */ - static void s_dmul(mp_int a, mp_digit b) { @@ -2852,14 +2747,10 @@ s_dmul(mp_int a, mp_digit b) if (w) { *da = (mp_digit) w; - MP_USED(a) += 1; + a->used += 1; } } -/* }}} */ - -/* {{{ s_dbmul(da, b, dc, size_a) */ - static void s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) { @@ -2878,10 +2769,6 @@ s_dbmul(mp_digit *da, mp_digit b, mp_digit *dc, mp_size size_a) *dc = LOWER_HALF(w); } -/* }}} */ - -/* {{{ s_ddiv(da, d, dc, size_a) */ - static mp_digit s_ddiv(mp_int a, mp_digit b) { @@ -2911,10 +2798,6 @@ s_ddiv(mp_int a, mp_digit b) return (mp_digit) w; } -/* }}} */ - -/* {{{ s_qdiv(z, p2) */ - static void s_qdiv(mp_int z, mp_size p2) { @@ -2938,9 +2821,11 @@ s_qdiv(mp_int z, mp_size p2) from = to + ndig; for (mark = ndig; mark < uz; ++mark) + { *to++ = *from++; + } - MP_USED(z) = uz - ndig; + z->used = uz - ndig; } if (nbits) @@ -2965,33 +2850,25 @@ s_qdiv(mp_int z, mp_size p2) } if (MP_USED(z) == 1 && z->digits[0] == 0) - MP_SIGN(z) = MP_ZPOS; + z->sign = MP_ZPOS; } -/* }}} */ - -/* {{{ s_qmod(z, p2) */ - static void s_qmod(mp_int z, mp_size p2) { mp_size start = p2 / MP_DIGIT_BIT + 1, rest = p2 % MP_DIGIT_BIT; mp_size uz = MP_USED(z); - mp_digit mask = (1 << rest) - 1; + mp_digit mask = (1u << rest) - 1; if (start <= uz) { - MP_USED(z) = start; + z->used = start; z->digits[start - 1] &= mask; CLAMP(z); } } -/* }}} */ - -/* {{{ s_qmul(z, p2) */ - static int s_qmul(mp_int z, mp_size p2) { @@ -3063,21 +2940,19 @@ s_qmul(mp_int z, mp_size p2) } } - MP_USED(z) = uz; + z->used = uz; CLAMP(z); return 1; } -/* }}} */ - -/* {{{ s_qsub(z, p2) */ - -/* Subtract |z| from 2^p2, assuming 2^p2 > |z|, and set z to be positive */ +/* Compute z = 2^p2 - |z|; requires that 2^p2 >= |z| + The sign of the result is always zero/positive. + */ static int s_qsub(mp_int z, mp_size p2) { - mp_digit hi = (1 << (p2 % MP_DIGIT_BIT)), + mp_digit hi = (1u << (p2 % MP_DIGIT_BIT)), *zp; mp_size tdig = (p2 / MP_DIGIT_BIT), pos; @@ -3099,16 +2974,12 @@ s_qsub(mp_int z, mp_size p2) assert(UPPER_HALF(w) != 0); /* no borrow out should be possible */ - MP_SIGN(z) = MP_ZPOS; + z->sign = MP_ZPOS; CLAMP(z); return 1; } -/* }}} */ - -/* {{{ s_dp2k(z) */ - static int s_dp2k(mp_int z) { @@ -3135,10 +3006,6 @@ s_dp2k(mp_int z) return k; } -/* }}} */ - -/* {{{ s_isp2(z) */ - static int s_isp2(mp_int z) { @@ -3167,12 +3034,8 @@ s_isp2(mp_int z) return (int) k; } -/* }}} */ - -/* {{{ s_2expt(z, k) */ - static int -s_2expt(mp_int z, int k) +s_2expt(mp_int z, mp_small k) { mp_size ndig, rest; @@ -3186,23 +3049,19 @@ s_2expt(mp_int z, int k) dz = MP_DIGITS(z); ZERO(dz, ndig); - *(dz + ndig - 1) = (1 << rest); - MP_USED(z) = ndig; + *(dz + ndig - 1) = (1u << rest); + z->used = ndig; return 1; } -/* }}} */ - -/* {{{ s_norm(a, b) */ - static int s_norm(mp_int a, mp_int b) { mp_digit d = b->digits[MP_USED(b) - 1]; int k = 0; - while (d < (mp_digit) ((mp_digit) 1 << (MP_DIGIT_BIT - 1))) + while (d < (1u << (mp_digit) (MP_DIGIT_BIT - 1))) { /* d < (MP_RADIX / 2) */ d <<= 1; ++k; @@ -3218,10 +3077,6 @@ s_norm(mp_int a, mp_int b) return k; } -/* }}} */ - -/* {{{ s_brmu(z, m) */ - static mp_result s_brmu(mp_int z, mp_int m) { @@ -3234,10 +3089,6 @@ s_brmu(mp_int z, mp_int m) return mp_int_div(z, m, z, NULL); } -/* }}} */ - -/* {{{ s_reduce(x, m, mu, q1, q2) */ - static int s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) { @@ -3276,53 +3127,47 @@ s_reduce(mp_int x, mp_int m, mp_int mu, mp_int q1, mp_int q2) return 0; /* - * If x > m, we need to back it off until it is in range. This will be + * If x > m, we need to back it off until it is in range. This will be * required at most twice. */ if (mp_int_compare(x, m) >= 0) + { (void) mp_int_sub(x, m, x); - if (mp_int_compare(x, m) >= 0) - (void) mp_int_sub(x, m, x); + if (mp_int_compare(x, m) >= 0) + { + (void) mp_int_sub(x, m, x); + } + } /* At this point, x has been properly reduced. */ return 1; } -/* }}} */ - -/* {{{ s_embar(a, b, m, mu, c) */ - -/* Perform modular exponentiation using Barrett's method, where mu is - the reduction constant for m. Assumes a < m, b > 0. */ +/* Perform modular exponentiation using Barrett's method, where mu is the + reduction constant for m. Assumes a < m, b > 0. */ static mp_result s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) { - mp_digit *db, - *dbt, - umu, - d; - mpz_t temp[3]; - mp_result res; - int last = 0; + mp_digit umu = MP_USED(mu); + mp_digit *db = MP_DIGITS(b); + mp_digit *dbt = db + MP_USED(b) - 1; - umu = MP_USED(mu); - db = MP_DIGITS(b); - dbt = db + MP_USED(b) - 1; - - while (last < 3) - { - SETUP(mp_int_init_size(TEMP(last), 4 * umu), last); - ZERO(MP_DIGITS(TEMP(last - 1)), MP_ALLOC(TEMP(last - 1))); - } + DECLARE_TEMP(3); + REQUIRE(GROW(TEMP(0), 4 * umu)); + REQUIRE(GROW(TEMP(1), 4 * umu)); + REQUIRE(GROW(TEMP(2), 4 * umu)); + ZERO(TEMP(0)->digits, TEMP(0)->alloc); + ZERO(TEMP(1)->digits, TEMP(1)->alloc); + ZERO(TEMP(2)->digits, TEMP(2)->alloc); (void) mp_int_set_value(c, 1); /* Take care of low-order digits */ while (db < dbt) { - int i; + mp_digit d = *db; - for (d = *db, i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) + for (int i = MP_DIGIT_BIT; i > 0; --i, d >>= 1) { if (d & 1) { @@ -3330,31 +3175,27 @@ s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) UMUL(c, a, TEMP(0)); if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; - goto CLEANUP; + REQUIRE(MP_MEMORY); } mp_int_copy(TEMP(0), c); } - USQR(a, TEMP(0)); assert(MP_SIGN(TEMP(0)) == MP_ZPOS); if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; - goto CLEANUP; + REQUIRE(MP_MEMORY); } assert(MP_SIGN(TEMP(0)) == MP_ZPOS); mp_int_copy(TEMP(0), a); - - } ++db; } /* Take care of highest-order digit */ - d = *dbt; + mp_digit d = *dbt; + for (;;) { if (d & 1) @@ -3362,8 +3203,7 @@ s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) UMUL(c, a, TEMP(0)); if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; - goto CLEANUP; + REQUIRE(MP_MEMORY); } mp_int_copy(TEMP(0), c); } @@ -3375,170 +3215,272 @@ s_embar(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c) USQR(a, TEMP(0)); if (!s_reduce(TEMP(0), m, mu, TEMP(1), TEMP(2))) { - res = MP_MEMORY; - goto CLEANUP; + REQUIRE(MP_MEMORY); } (void) mp_int_copy(TEMP(0), a); } -CLEANUP: - while (--last >= 0) - mp_int_clear(TEMP(last)); - - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ +/* Division of nonnegative integers + + This function implements division algorithm for unsigned multi-precision + integers. The algorithm is based on Algorithm D from Knuth's "The Art of + Computer Programming", 3rd ed. 1998, pg 272-273. -/* {{{ s_udiv(a, b) */ + We diverge from Knuth's algorithm in that we do not perform the subtraction + from the remainder until we have determined that we have the correct + quotient digit. This makes our algorithm less efficient that Knuth because + we might have to perform multiple multiplication and comparison steps before + the subtraction. The advantage is that it is easy to implement and ensure + correctness without worrying about underflow from the subtraction. -/* Precondition: a >= b and b > 0 - Postcondition: a' = a / b, b' = a % b + inputs: u a n+m digit integer in base b (b is 2^MP_DIGIT_BIT) + v a n digit integer in base b (b is 2^MP_DIGIT_BIT) + n >= 1 + m >= 0 + outputs: u / v stored in u + u % v stored in v */ static mp_result -s_udiv(mp_int a, mp_int b) -{ - mpz_t q, - r, - t; - mp_size ua, - ub, - qpos = 0; - mp_digit *da, - btop; - mp_result res = MP_OK; - int k, - skip = 0; - +s_udiv_knuth(mp_int u, mp_int v) +{ /* Force signs to positive */ - MP_SIGN(a) = MP_ZPOS; - MP_SIGN(b) = MP_ZPOS; + u->sign = MP_ZPOS; + v->sign = MP_ZPOS; + + /* Use simple division algorithm when v is only one digit long */ + if (MP_USED(v) == 1) + { + mp_digit d, + rem; - /* Normalize, per Knuth */ - k = s_norm(a, b); + d = v->digits[0]; + rem = s_ddiv(u, d); + mp_int_set_value(v, rem); + return MP_OK; + } - ua = MP_USED(a); - ub = MP_USED(b); - btop = b->digits[ub - 1]; - if ((res = mp_int_init_size(&q, ua)) != MP_OK) - return res; - if ((res = mp_int_init_size(&t, ua + 1)) != MP_OK) - goto CLEANUP; + /* + * Algorithm D + * + * The n and m variables are defined as used by Knuth. u is an n digit + * number with digits u_{n-1}..u_0. v is an n+m digit number with digits + * from v_{m+n-1}..v_0. We require that n > 1 and m >= 0 + */ + mp_size n = MP_USED(v); + mp_size m = MP_USED(u) - n; + + assert(n > 1); + /* assert(m >= 0) follows because m is unsigned. */ + + /* + * D1: Normalize. The normalization step provides the necessary condition + * for Theorem B, which states that the quotient estimate for q_j, call it + * qhat + * + * qhat = u_{j+n}u_{j+n-1} / v_{n-1} + * + * is bounded by + * + * qhat - 2 <= q_j <= qhat. + * + * That is, qhat is always greater than the actual quotient digit q, and + * it is never more than two larger than the actual quotient digit. + */ + int k = s_norm(u, v); + + /* + * Extend size of u by one if needed. + * + * The algorithm begins with a value of u that has one more digit of + * input. The normalization step sets u_{m+n}..u_0 = 2^k * u_{m+n-1}..u_0. + * If the multiplication did not increase the number of digits of u, we + * need to add a leading zero here. + */ + if (k == 0 || MP_USED(u) != m + n + 1) + { + if (!s_pad(u, m + n + 1)) + return MP_MEMORY; + u->digits[m + n] = 0; + u->used = m + n + 1; + } - da = MP_DIGITS(a); - r.digits = da + ua - 1; /* The contents of r are shared with a */ - r.used = 1; + /* + * Add a leading 0 to v. + * + * The multiplication in step D4 multiplies qhat * 0v_{n-1}..v_0. We need + * to add the leading zero to v here to ensure that the multiplication + * will produce the full n+1 digit result. + */ + if (!s_pad(v, n + 1)) + return MP_MEMORY; + v->digits[n] = 0; + + /* + * Initialize temporary variables q and t. q allocates space for m+1 + * digits to store the quotient digits t allocates space for n+1 digits to + * hold the result of q_j*v + */ + DECLARE_TEMP(2); + REQUIRE(GROW(TEMP(0), m + 1)); + REQUIRE(GROW(TEMP(1), n + 1)); + + /* D2: Initialize j */ + int j = m; + mpz_t r; + + r.digits = MP_DIGITS(u) + j; /* The contents of r are shared with u */ + r.used = n + 1; r.sign = MP_ZPOS; - r.alloc = MP_ALLOC(a); - ZERO(t.digits, t.alloc); + r.alloc = MP_ALLOC(u); + ZERO(TEMP(1)->digits, TEMP(1)->alloc); - /* Solve for quotient digits, store in q.digits in reverse order */ - while (r.digits >= da) + /* Calculate the m+1 digits of the quotient result */ + for (; j >= 0; j--) { - assert(qpos <= q.alloc); + /* D3: Calculate q' */ + /* r->digits is aligned to position j of the number u */ + mp_word pfx, + qhat; - if (s_ucmp(b, &r) > 0) - { - r.digits -= 1; - r.used += 1; + pfx = r.digits[n]; + pfx <<= MP_DIGIT_BIT / 2; + pfx <<= MP_DIGIT_BIT / 2; + pfx |= r.digits[n - 1]; /* pfx = u_{j+n}{j+n-1} */ - if (++skip > 1) - q.digits[qpos++] = 0; + qhat = pfx / v->digits[n - 1]; - CLAMP(&r); - } - else - { - mp_word pfx = r.digits[r.used - 1]; - mp_word qdigit; + /* + * Check to see if qhat > b, and decrease qhat if so. Theorem B + * guarantess that qhat is at most 2 larger than the actual value, so + * it is possible that qhat is greater than the maximum value that + * will fit in a digit + */ + if (qhat > MP_DIGIT_MAX) + qhat = MP_DIGIT_MAX; - if (r.used > 1 && (pfx < btop || r.digits[r.used - 2] == 0)) - { - pfx <<= MP_DIGIT_BIT / 2; - pfx <<= MP_DIGIT_BIT / 2; - pfx |= r.digits[r.used - 2]; + /* + * D4,D5,D6: Multiply qhat * v and test for a correct value of q + * + * We proceed a bit different than the way described by Knuth. This + * way is simpler but less efficent. Instead of doing the multiply and + * subtract then checking for underflow, we first do the multiply of + * qhat * v and see if it is larger than the current remainder r. If + * it is larger, we decrease qhat by one and try again. We may need to + * decrease qhat one more time before we get a value that is smaller + * than r. + * + * This way is less efficent than Knuth becuase we do more multiplies, + * but we do not need to worry about underflow this way. + */ + /* t = qhat * v */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); + + /* Clamp r for the comparison. Comparisons do not like leading zeros. */ + CLAMP(&r); + if (s_ucmp(TEMP(1), &r) > 0) + { /* would the remainder be negative? */ + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); + if (s_ucmp(TEMP(1), &r) > 0) + { /* would the remainder be negative? */ + assert(qhat > 0); + qhat -= 1; /* try a smaller q */ + s_dbmul(MP_DIGITS(v), (mp_digit) qhat, TEMP(1)->digits, n + 1); + TEMP(1)->used = n + 1; + CLAMP(TEMP(1)); } + assert(s_ucmp(TEMP(1), &r) <= 0 && "The mathematics failed us."); + } - qdigit = pfx / btop; - if (qdigit > MP_DIGIT_MAX) - qdigit = 1; + /* + * Unclamp r. The D algorithm expects r = u_{j+n}..u_j to always be + * n+1 digits long. + */ + r.used = n + 1; - s_dbmul(MP_DIGITS(b), (mp_digit) qdigit, t.digits, ub); - t.used = ub + 1; - CLAMP(&t); - while (s_ucmp(&t, &r) > 0) - { - --qdigit; - (void) mp_int_sub(&t, b, &t); /* cannot fail */ - } + /* + * D4: Multiply and subtract + * + * Note: The multiply was completed above so we only need to subtract + * here. + */ + s_usub(r.digits, TEMP(1)->digits, r.digits, r.used, TEMP(1)->used); - s_usub(r.digits, t.digits, r.digits, r.used, t.used); - CLAMP(&r); + /* + * D5: Test remainder + * + * Note: Not needed because we always check that qhat is the correct + * value before performing the subtract. Value cast to mp_digit to + * prevent warning, qhat has been clamped to MP_DIGIT_MAX + */ + TEMP(0)->digits[j] = (mp_digit) qhat; - q.digits[qpos++] = (mp_digit) qdigit; - ZERO(t.digits, t.used); - skip = 0; - } + /* + * D6: Add back Note: Not needed because we always check that qhat is + * the correct value before performing the subtract. + */ + + /* D7: Loop on j */ + r.digits--; + ZERO(TEMP(1)->digits, TEMP(1)->alloc); } - /* Put quotient digits in the correct order, and discard extra zeroes */ - q.used = qpos; - REV(mp_digit, q.digits, qpos); - CLAMP(&q); + /* Get rid of leading zeros in q */ + TEMP(0)->used = m + 1; + CLAMP(TEMP(0)); /* Denormalize the remainder */ - CLAMP(a); + CLAMP(u); /* use u here because the r.digits pointer is + * off-by-one */ if (k != 0) - s_qdiv(a, k); + s_qdiv(u, k); - mp_int_copy(a, b); /* ok: 0 <= r < b */ - mp_int_copy(&q, a); /* ok: q <= a */ + mp_int_copy(u, v); /* ok: 0 <= r < v */ + mp_int_copy(TEMP(0), u); /* ok: q <= u */ - mp_int_clear(&t); -CLEANUP: - mp_int_clear(&q); - return res; + CLEANUP_TEMP(); + return MP_OK; } -/* }}} */ - -/* {{{ s_outlen(z, r) */ - -/* Precondition: 2 <= r < 64 */ static int s_outlen(mp_int z, mp_size r) { - mp_result bits; - double raw; + assert(r >= MP_MIN_RADIX && r <= MP_MAX_RADIX); - bits = mp_int_count_bits(z); - raw = (double) bits * s_log2[r]; + mp_result bits = mp_int_count_bits(z); + double raw = (double) bits * s_log2[r]; return (int) (raw + 0.999999); } -/* }}} */ - -/* {{{ s_inlen(len, r) */ - static mp_size s_inlen(int len, mp_size r) { double raw = (double) len / s_log2[r]; mp_size bits = (mp_size) (raw + 0.5); - return (mp_size) ((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT); + return (mp_size) ((bits + (MP_DIGIT_BIT - 1)) / MP_DIGIT_BIT) + 1; } -/* }}} */ - -/* {{{ s_ch2val(c, r) */ - static int s_ch2val(char c, int r) { int out; + /* + * In some locales, isalpha() accepts characters outside the range A-Z, + * producing out<0 or out>=36. The "out >= r" check will always catch + * out>=36. Though nothing explicitly catches out<0, our caller reacts + * the same way to every negative return value. + */ if (isdigit((unsigned char) c)) out = c - '0'; else if (r > 10 && isalpha((unsigned char) c)) @@ -3549,39 +3491,36 @@ s_ch2val(char c, int r) return (out >= r) ? -1 : out; } -/* }}} */ - -/* {{{ s_val2ch(v, caps) */ - static char s_val2ch(int v, int caps) { assert(v >= 0); if (v < 10) + { return v + '0'; + } else { char out = (v - 10) + 'a'; if (caps) + { return toupper((unsigned char) out); + } else + { return out; + } } } -/* }}} */ - -/* {{{ s_2comp(buf, len) */ - static void s_2comp(unsigned char *buf, int len) { - int i; unsigned short s = 1; - for (i = len - 1; i >= 0; --i) + for (int i = len - 1; i >= 0; --i) { unsigned char c = ~buf[i]; @@ -3595,20 +3534,14 @@ s_2comp(unsigned char *buf, int len) /* last carry out is ignored */ } -/* }}} */ - -/* {{{ s_tobin(z, buf, *limpos) */ - static mp_result s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) { - mp_size uz; - mp_digit *dz; int pos = 0, limit = *limpos; + mp_size uz = MP_USED(z); + mp_digit *dz = MP_DIGITS(z); - uz = MP_USED(z); - dz = MP_DIGITS(z); while (uz > 0 && pos < limit) { mp_digit d = *dz++; @@ -3634,13 +3567,17 @@ s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) if (pad != 0 && (buf[pos - 1] >> (CHAR_BIT - 1))) { if (pos < limit) + { buf[pos++] = 0; + } else + { uz = 1; + } } /* Digits are in reverse order, fix that */ - REV(unsigned char, buf, pos); + REV(buf, pos); /* Return the number of bytes actually written */ *limpos = pos; @@ -3648,40 +3585,4 @@ s_tobin(mp_int z, unsigned char *buf, int *limpos, int pad) return (uz == 0) ? MP_OK : MP_TRUNC; } -/* }}} */ - -/* {{{ s_print(tag, z) */ - -#if 0 -void -s_print(char *tag, mp_int z) -{ - int i; - - fprintf(stderr, "%s: %c ", tag, - (MP_SIGN(z) == MP_NEG) ? '-' : '+'); - - for (i = MP_USED(z) - 1; i >= 0; --i) - fprintf(stderr, "%0*X", (int) (MP_DIGIT_BIT / 4), z->digits[i]); - - fputc('\n', stderr); - -} - -void -s_print_buf(char *tag, mp_digit *buf, mp_size num) -{ - int i; - - fprintf(stderr, "%s: ", tag); - - for (i = num - 1; i >= 0; --i) - fprintf(stderr, "%0*X", (int) (MP_DIGIT_BIT / 4), buf[i]); - - fputc('\n', stderr); -} -#endif - -/* }}} */ - -/* HERE THERE BE DRAGONS */ +/* Here there be dragons */ diff --git a/contrib/pgcrypto/imath.h b/contrib/pgcrypto/imath.h index 2d7a5268e5c..0e1676d04e9 100644 --- a/contrib/pgcrypto/imath.h +++ b/contrib/pgcrypto/imath.h @@ -1,61 +1,57 @@ /* - Name: imath.h - Purpose: Arbitrary precision integer arithmetic routines. - Author: M. J. Fromberger - Info: Id: imath.h 21 2006-04-02 18:58:36Z sting - - Copyright (C) 2002 Michael J. Fromberger, All Rights Reserved. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + Name: imath.h + Purpose: Arbitrary precision integer arithmetic routines. + Author: M. J. Fromberger + + Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* contrib/pgcrypto/imath.h */ #ifndef IMATH_H_ #define IMATH_H_ -/* use always 32bit digits - should some arch use 16bit digits? */ -#define USE_LONG_LONG - #include typedef unsigned char mp_sign; typedef unsigned int mp_size; typedef int mp_result; +typedef long mp_small; /* must be a signed type */ +typedef unsigned long mp_usmall; /* must be an unsigned type */ -#ifdef USE_LONG_LONG -typedef uint32 mp_digit; -typedef uint64 mp_word; -#define MP_DIGIT_MAX 0xFFFFFFFFULL -#define MP_WORD_MAX 0xFFFFFFFFFFFFFFFFULL -#else +/* Build with words as uint64 by default. */ +#ifdef USE_32BIT_WORDS typedef uint16 mp_digit; typedef uint32 mp_word; - -#define MP_DIGIT_MAX 0xFFFFUL -#define MP_WORD_MAX 0xFFFFFFFFUL +#define MP_DIGIT_MAX (PG_UINT16_MAX * 1UL) +#define MP_WORD_MAX (PG_UINT32_MAX * 1UL) +#else +typedef uint32 mp_digit; +typedef uint64 mp_word; +#define MP_DIGIT_MAX (PG_UINT32_MAX * UINT64CONST(1)) +#define MP_WORD_MAX (PG_UINT64_MAX) #endif -typedef struct mpz +typedef struct { + mp_digit single; mp_digit *digits; mp_size alloc; mp_size used; @@ -64,10 +60,26 @@ typedef struct mpz *mp_int; -#define MP_DIGITS(Z) ((Z)->digits) -#define MP_ALLOC(Z) ((Z)->alloc) -#define MP_USED(Z) ((Z)->used) -#define MP_SIGN(Z) ((Z)->sign) +static inline mp_digit * +MP_DIGITS(mp_int Z) +{ + return Z->digits; +} +static inline mp_size +MP_ALLOC(mp_int Z) +{ + return Z->alloc; +} +static inline mp_size +MP_USED(mp_int Z) +{ + return Z->used; +} +static inline mp_sign +MP_SIGN(mp_int Z) +{ + return Z->sign; +} extern const mp_result MP_OK; extern const mp_result MP_FALSE; @@ -77,134 +89,357 @@ extern const mp_result MP_RANGE; extern const mp_result MP_UNDEF; extern const mp_result MP_TRUNC; extern const mp_result MP_BADARG; +extern const mp_result MP_MINERR; + +#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) +#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +#define MP_SMALL_MIN LONG_MIN +#define MP_SMALL_MAX LONG_MAX +#define MP_USMALL_MAX ULONG_MAX + +#define MP_MIN_RADIX 2 +#define MP_MAX_RADIX 36 -#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT) -#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT) +/** Sets the default number of digits allocated to an `mp_int` constructed by + `mp_int_init_size()` with `prec == 0`. Allocations are rounded up to + multiples of this value. `MP_DEFAULT_PREC` is the default value. Requires + `ndigits > 0`. */ +void mp_int_default_precision(mp_size ndigits); -#define MP_MIN_RADIX 2 -#define MP_MAX_RADIX 36 +/** Sets the number of digits below which multiplication will use the standard + quadratic "schoolbook" multiplcation algorithm rather than Karatsuba-Ofman. + Requires `ndigits >= sizeof(mp_word)`. */ +void mp_int_multiply_threshold(mp_size ndigits); +/** A sign indicating a (strictly) negative value. */ extern const mp_sign MP_NEG; + +/** A sign indicating a zero or positive value. */ extern const mp_sign MP_ZPOS; -#define mp_int_is_odd(Z) ((Z)->digits[0] & 1) -#define mp_int_is_even(Z) !((Z)->digits[0] & 1) +/** Reports whether `z` is odd, having remainder 1 when divided by 2. */ +static inline bool +mp_int_is_odd(mp_int z) +{ + return (z->digits[0] & 1) != 0; +} -mp_size mp_get_default_precision(void); -void mp_set_default_precision(mp_size s); -mp_size mp_get_multiply_threshold(void); -void mp_set_multiply_threshold(mp_size s); +/** Reports whether `z` is even, having remainder 0 when divided by 2. */ +static inline bool +mp_int_is_even(mp_int z) +{ + return (z->digits[0] & 1) == 0; +} +/** Initializes `z` with 1-digit precision and sets it to zero. This function + cannot fail unless `z == NULL`. */ mp_result mp_int_init(mp_int z); + +/** Allocates a fresh zero-valued `mpz_t` on the heap, returning NULL in case + of error. The only possible error is out-of-memory. */ mp_int mp_int_alloc(void); + +/** Initializes `z` with at least `prec` digits of storage, and sets it to + zero. If `prec` is zero, the default precision is used. In either case the + size is rounded up to the nearest multiple of the word size. */ mp_result mp_int_init_size(mp_int z, mp_size prec); + +/** Initializes `z` to be a copy of an already-initialized value in `old`. The + new copy does not share storage with the original. */ mp_result mp_int_init_copy(mp_int z, mp_int old); -mp_result mp_int_init_value(mp_int z, int value); -mp_result mp_int_set_value(mp_int z, int value); + +/** Initializes `z` to the specified signed `value` at default precision. */ +mp_result mp_int_init_value(mp_int z, mp_small value); + +/** Initializes `z` to the specified unsigned `value` at default precision. */ +mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue); + +/** Sets `z` to the value of the specified signed `value`. */ +mp_result mp_int_set_value(mp_int z, mp_small value); + +/** Sets `z` to the value of the specified unsigned `value`. */ +mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue); + +/** Releases the storage used by `z`. */ void mp_int_clear(mp_int z); + +/** Releases the storage used by `z` and also `z` itself. + This should only be used for `z` allocated by `mp_int_alloc()`. */ void mp_int_free(mp_int z); -mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */ -void mp_int_swap(mp_int a, mp_int c); /* swap a, c */ -void mp_int_zero(mp_int z); /* z = 0 */ -mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */ -mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */ -mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */ -mp_result mp_int_add_value(mp_int a, int value, mp_int c); -mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */ -mp_result mp_int_sub_value(mp_int a, int value, mp_int c); -mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */ -mp_result mp_int_mul_value(mp_int a, int value, mp_int c); -mp_result mp_int_mul_pow2(mp_int a, int p2, mp_int c); -mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */ - -mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */ - mp_int q, mp_int r); /* r = a % b */ -mp_result mp_int_div_value(mp_int a, int value, /* q = a / value */ - mp_int q, int *r); /* r = a % value */ -mp_result mp_int_div_pow2(mp_int a, int p2, /* q = a / 2^p2 */ - mp_int q, mp_int r); /* r = q % 2^p2 */ -mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */ - -#define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R)) -mp_result mp_int_expt(mp_int a, int b, mp_int c); /* c = a^b */ -mp_result mp_int_expt_value(int a, int b, mp_int c); /* c = a^b */ - -int mp_int_compare(mp_int a, mp_int b); /* a <=> b */ -int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */ -int mp_int_compare_zero(mp_int z); /* a <=> 0 */ -int mp_int_compare_value(mp_int z, int value); /* a <=> v */ - -/* Returns true if v|a, false otherwise (including errors) */ -int mp_int_divisible_value(mp_int a, int v); - -/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */ +/** Replaces the value of `c` with a copy of the value of `a`. No new memory is + allocated unless `a` has more significant digits than `c` has allocated. */ +mp_result mp_int_copy(mp_int a, mp_int c); + +/** Swaps the values and storage between `a` and `c`. */ +void mp_int_swap(mp_int a, mp_int c); + +/** Sets `z` to zero. The allocated storage of `z` is not changed. */ +void mp_int_zero(mp_int z); + +/** Sets `c` to the absolute value of `a`. */ +mp_result mp_int_abs(mp_int a, mp_int c); + +/** Sets `c` to the additive inverse (negation) of `a`. */ +mp_result mp_int_neg(mp_int a, mp_int c); + +/** Sets `c` to the sum of `a` and `b`. */ +mp_result mp_int_add(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the sum of `a` and `value`. */ +mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the difference of `a` less `b`. */ +mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the difference of `a` less `value`. */ +mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the product of `a` and `b`. */ +mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the product of `a` and `value`. */ +mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c); + +/** Sets `c` to the product of `a` and `2^p2`. Requires `p2 >= 0`. */ +mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c); + +/** Sets `c` to the square of `a`. */ +mp_result mp_int_sqr(mp_int a, mp_int c); + +/** Sets `q` and `r` to the quotent and remainder of `a / b`. Division by + powers of 2 is detected and handled efficiently. The remainder is pinned + to `0 <= r < b`. + + Either of `q` or `r` may be NULL, but not both, and `q` and `r` may not + point to the same value. */ +mp_result mp_int_div(mp_int a, mp_int b, mp_int q, mp_int r); + +/** Sets `q` and `*r` to the quotent and remainder of `a / value`. Division by + powers of 2 is detected and handled efficiently. The remainder is pinned to + `0 <= *r < b`. Either of `q` or `r` may be NULL. */ +mp_result mp_int_div_value(mp_int a, mp_small value, mp_int q, mp_small *r); + +/** Sets `q` and `r` to the quotient and remainder of `a / 2^p2`. This is a + special case for division by powers of two that is more efficient than + using ordinary division. Note that `mp_int_div()` will automatically handle + this case, this function is for cases where you have only the exponent. */ +mp_result mp_int_div_pow2(mp_int a, mp_small p2, mp_int q, mp_int r); + +/** Sets `c` to the remainder of `a / m`. + The remainder is pinned to `0 <= c < m`. */ +mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE` if `b < 0`. */ +mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE` if `b < 0`. */ +mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power. + It returns `MP_RANGE`) if `b < 0`. */ +mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c); + +/** Sets `*r` to the remainder of `a / value`. + The remainder is pinned to `0 <= r < value`. */ +static inline +mp_result +mp_int_mod_value(mp_int a, mp_small value, mp_small *r) +{ + return mp_int_div_value(a, value, 0, r); +} + +/** Returns the comparator of `a` and `b`. */ +int mp_int_compare(mp_int a, mp_int b); + +/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their + signs. Neither `a` nor `b` is modified by the comparison. */ +int mp_int_compare_unsigned(mp_int a, mp_int b); + +/** Returns the comparator of `z` and zero. */ +int mp_int_compare_zero(mp_int z); + +/** Returns the comparator of `z` and the signed value `v`. */ +int mp_int_compare_value(mp_int z, mp_small v); + +/** Returns the comparator of `z` and the unsigned value `uv`. */ +int mp_int_compare_uvalue(mp_int z, mp_usmall uv); + +/** Reports whether `a` is divisible by `v`. */ +bool mp_int_divisible_value(mp_int a, mp_small v); + +/** Returns `k >= 0` such that `z` is `2^k`, if such a `k` exists. If no such + `k` exists, the function returns -1. */ int mp_int_is_pow2(mp_int z); -mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, - mp_int c); /* c = a^b (mod m) */ -mp_result mp_int_exptmod_evalue(mp_int a, int value, - mp_int m, mp_int c); /* c = a^v (mod m) */ -mp_result mp_int_exptmod_bvalue(int value, mp_int b, - mp_int m, mp_int c); /* c = v^b (mod m) */ -mp_result mp_int_exptmod_known(mp_int a, mp_int b, - mp_int m, mp_int mu, - mp_int c); /* c = a^b (mod m) */ +/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`. + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `value` power, modulo `m`. + It returns `MP_RANGE` if `value < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_evalue(mp_int a, mp_small value, mp_int m, mp_int c); + +/** Sets `c` to the value of `value` raised to the `b` power, modulo `m`. + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b, mp_int m, mp_int c); + +/** Sets `c` to the value of `a` raised to the `b` power, reduced modulo `m`, + given a precomputed reduction constant `mu` defined for Barrett's modular + reduction algorithm. + + It returns `MP_RANGE` if `b < 0` or `MP_UNDEF` if `m == 0`. */ +mp_result mp_int_exptmod_known(mp_int a, mp_int b, mp_int m, mp_int mu, mp_int c); + +/** Sets `c` to the reduction constant for Barrett reduction by modulus `m`. + Requires that `c` and `m` point to distinct locations. */ mp_result mp_int_redux_const(mp_int m, mp_int c); -mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */ +/** Sets `c` to the multiplicative inverse of `a` modulo `m`, if it exists. + The least non-negative representative of the congruence class is computed. + + It returns `MP_UNDEF` if the inverse does not exist, or `MP_RANGE` if `a == + 0` or `m <= 0`. */ +mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); -mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */ +/** Sets `c` to the greatest common divisor of `a` and `b`. -mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */ - mp_int x, mp_int y); /* c = ax + by */ + It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); -mp_result mp_int_sqrt(mp_int a, mp_int c); /* c = floor(sqrt(q)) */ +/** Sets `c` to the greatest common divisor of `a` and `b`, and sets `x` and + `y` to values satisfying Bezout's identity `gcd(a, b) = ax + by`. -/* Convert to an int, if representable (returns MP_RANGE if not). */ -mp_result mp_int_to_int(mp_int z, int *out); + It returns `MP_UNDEF` if the GCD is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, mp_int x, mp_int y); -/* Convert to nul-terminated string with the specified radix, writing at - most limit characters including the nul terminator */ -mp_result mp_int_to_string(mp_int z, mp_size radix, - char *str, int limit); +/** Sets `c` to the least common multiple of `a` and `b`. -/* Return the number of characters required to represent - z in the given radix. May over-estimate. */ + It returns `MP_UNDEF` if the LCM is undefined, such as for example if `a` + and `b` are both zero. */ +mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); + +/** Sets `c` to the greatest integer not less than the `b`th root of `a`, + using Newton's root-finding algorithm. + It returns `MP_UNDEF` if `a < 0` and `b` is even. */ +mp_result mp_int_root(mp_int a, mp_small b, mp_int c); + +/** Sets `c` to the greatest integer not less than the square root of `a`. + This is a special case of `mp_int_root()`. */ +static inline +mp_result +mp_int_sqrt(mp_int a, mp_int c) +{ + return mp_int_root(a, 2, c); +} + +/** Returns `MP_OK` if `z` is representable as `mp_small`, else `MP_RANGE`. + If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ +mp_result mp_int_to_int(mp_int z, mp_small *out); + +/** Returns `MP_OK` if `z` is representable as `mp_usmall`, or `MP_RANGE`. + If `out` is not NULL, `*out` is set to the value of `z` when `MP_OK`. */ +mp_result mp_int_to_uint(mp_int z, mp_usmall *out); + +/** Converts `z` to a zero-terminated string of characters in the specified + `radix`, writing at most `limit` characters to `str` including the + terminating NUL value. A leading `-` is used to indicate a negative value. + + Returns `MP_TRUNC` if `limit` was to small to write all of `z`. + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_to_string(mp_int z, mp_size radix, char *str, int limit); + +/** Reports the minimum number of characters required to represent `z` as a + zero-terminated string in the given `radix`. + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ mp_result mp_int_string_len(mp_int z, mp_size radix); -/* Read zero-terminated string into z */ +/** Reads a string of ASCII digits in the specified `radix` from the zero + terminated `str` provided into `z`. For values of `radix > 10`, the letters + `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect + to case. + + Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a + sign flag. Processing stops when a NUL or any other character out of range + for a digit in the given radix is encountered. + + If the whole string was consumed, `MP_OK` is returned; otherwise + `MP_TRUNC`. is returned. + + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str); -mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, - char **end); -/* Return the number of significant bits in z */ +/** Reads a string of ASCII digits in the specified `radix` from the zero + terminated `str` provided into `z`. For values of `radix > 10`, the letters + `A`..`Z` or `a`..`z` are accepted. Letters are interpreted without respect + to case. + + Leading whitespace is ignored, and a leading `+` or `-` is interpreted as a + sign flag. Processing stops when a NUL or any other character out of range + for a digit in the given radix is encountered. + + If the whole string was consumed, `MP_OK` is returned; otherwise + `MP_TRUNC`. is returned. If `end` is not NULL, `*end` is set to point to + the first unconsumed byte of the input string (the NUL byte if the whole + string was consumed). This emulates the behavior of the standard C + `strtol()` function. + + Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */ +mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str, char **end); + +/** Returns the number of significant bits in `z`. */ mp_result mp_int_count_bits(mp_int z); -/* Convert z to two's complement binary, writing at most limit bytes */ +/** Converts `z` to 2's complement binary, writing at most `limit` bytes into + the given `buf`. Returns `MP_TRUNC` if the buffer limit was too small to + contain the whole value. If this occurs, the contents of buf will be + effectively garbage, as the function uses the buffer as scratch space. + + The binary representation of `z` is in base-256 with digits ordered from + most significant to least significant (network byte ordering). The + high-order bit of the first byte is set for negative values, clear for + non-negative values. + + As a result, non-negative values will be padded with a leading zero byte if + the high-order byte of the base-256 magnitude is set. This extra byte is + accounted for by the `mp_int_binary_len()` function. */ mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit); -/* Read a two's complement binary value into z from the given buffer */ +/** Reads a 2's complement binary value from `buf` into `z`, where `len` is the + length of the buffer. The contents of `buf` may be overwritten during + processing, although they will be restored when the function returns. */ mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len); -/* Return the number of bytes required to represent z in binary. */ +/** Returns the number of bytes to represent `z` in 2's complement binary. */ mp_result mp_int_binary_len(mp_int z); -/* Convert z to unsigned binary, writing at most limit bytes */ +/** Converts the magnitude of `z` to unsigned binary, writing at most `limit` + bytes into the given `buf`. The sign of `z` is ignored, but `z` is not + modified. Returns `MP_TRUNC` if the buffer limit was too small to contain + the whole value. If this occurs, the contents of `buf` will be effectively + garbage, as the function uses the buffer as scratch space during + conversion. + + The binary representation of `z` is in base-256 with digits ordered from + most significant to least significant (network byte ordering). */ mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit); -/* Read an unsigned binary value into z from the given buffer */ +/** Reads an unsigned binary value from `buf` into `z`, where `len` is the + length of the buffer. The contents of `buf` are not modified during + processing. */ mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len); -/* Return the number of bytes required to represent z as unsigned output */ +/** Returns the number of bytes required to represent `z` as an unsigned binary + value in base 256. */ mp_result mp_int_unsigned_len(mp_int z); -/* Return a statically allocated string describing error code res */ +/** Returns a pointer to a brief, human-readable, zero-terminated string + describing `res`. The returned string is statically allocated and must not + be freed by the caller. */ const char *mp_error_string(mp_result res); -#if 0 -void s_print(char *tag, mp_int z); -void s_print_buf(char *tag, mp_digit *buf, mp_size num); -#endif - #endif /* end IMATH_H_ */ diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c index 16dfe725eae..db58408d4c7 100644 --- a/contrib/pgcrypto/internal.c +++ b/contrib/pgcrypto/internal.c @@ -39,25 +39,6 @@ #include "blf.h" #include "rijndael.h" -/* - * System reseeds should be separated at least this much. - */ -#define SYSTEM_RESEED_MIN (20*60) /* 20 min */ -/* - * How often to roll dice. - */ -#define SYSTEM_RESEED_CHECK_TIME (10*60) /* 10 min */ -/* - * The chance is x/256 that the reseed happens. - */ -#define SYSTEM_RESEED_CHANCE (4) /* 256/4 * 10min ~ 10h */ - -/* - * If this much time has passed, force reseed. - */ -#define SYSTEM_RESEED_MAX (12*60*60) /* 12h */ - - #ifndef MD5_DIGEST_LENGTH #define MD5_DIGEST_LENGTH 16 #endif diff --git a/contrib/pgcrypto/mbuf.h b/contrib/pgcrypto/mbuf.h index 50a989f059d..e6d754e8695 100644 --- a/contrib/pgcrypto/mbuf.h +++ b/contrib/pgcrypto/mbuf.h @@ -90,8 +90,8 @@ int mbuf_free(MBuf *mbuf); /* * Push filter */ -int pushf_create(PushFilter **res, const PushFilterOps *ops, void *init_arg, - PushFilter *next); +int pushf_create(PushFilter **res, const PushFilterOps *ops, void *init_arg, + PushFilter *next); int pushf_write(PushFilter *mp, const uint8 *data, int len); void pushf_free_all(PushFilter *mp); void pushf_free(PushFilter *mp); @@ -102,11 +102,11 @@ int pushf_create_mbuf_writer(PushFilter **mp_p, MBuf *mbuf); /* * Pull filter */ -int pullf_create(PullFilter **res, const PullFilterOps *ops, - void *init_arg, PullFilter *src); +int pullf_create(PullFilter **res, const PullFilterOps *ops, + void *init_arg, PullFilter *src); int pullf_read(PullFilter *mp, int len, uint8 **data_p); -int pullf_read_max(PullFilter *mp, int len, - uint8 **data_p, uint8 *tmpbuf); +int pullf_read_max(PullFilter *mp, int len, + uint8 **data_p, uint8 *tmpbuf); void pullf_free(PullFilter *mp); int pullf_read_fixed(PullFilter *src, int len, uint8 *dst); diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c index cac4e408ab4..15d7c9bcdc5 100644 --- a/contrib/pgcrypto/md5.c +++ b/contrib/pgcrypto/md5.c @@ -132,7 +132,7 @@ static const uint8 md5_paddat[MD5_BUFLEN] = { 0, 0, 0, 0, 0, 0, 0, 0, }; -static void md5_calc(uint8 *, md5_ctxt *); +static void md5_calc(const uint8 *, md5_ctxt *); void md5_init(md5_ctxt *ctxt) @@ -161,7 +161,7 @@ md5_loop(md5_ctxt *ctxt, const uint8 *input, unsigned len) md5_calc(ctxt->md5_buf, ctxt); for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) - md5_calc((uint8 *) (input + i), ctxt); + md5_calc(input + i, ctxt); ctxt->md5_i = len - i; memmove(ctxt->md5_buf, input + i, ctxt->md5_i); @@ -242,7 +242,7 @@ static uint32 X[16]; #endif static void -md5_calc(uint8 *b64, md5_ctxt *ctxt) +md5_calc(const uint8 *b64, md5_ctxt *ctxt) { uint32 A = ctxt->md5_sta; uint32 B = ctxt->md5_stb; @@ -250,7 +250,7 @@ md5_calc(uint8 *b64, md5_ctxt *ctxt) uint32 D = ctxt->md5_std; #ifndef WORDS_BIGENDIAN - uint32 *X = (uint32 *) b64; + const uint32 *X = (const uint32 *) b64; #else /* 4 byte words */ /* what a brute force but fast! */ diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c index f71a933407d..7d686f39402 100644 --- a/contrib/pgcrypto/openssl.c +++ b/contrib/pgcrypto/openssl.c @@ -408,7 +408,7 @@ gen_ossl_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, /* Blowfish */ /* - * Check if strong crypto is supported. Some openssl installations + * Check if strong crypto is supported. Some OpenSSL installations * support only short keys and unfortunately BF_set_key does not return any * error value. This function tests if is possible to use strong key. */ diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c index de09ececcfd..f69ae107c3a 100644 --- a/contrib/pgcrypto/pgcrypto.c +++ b/contrib/pgcrypto/pgcrypto.c @@ -34,7 +34,6 @@ #include #include "parser/scansup.h" -#include "utils/backend_random.h" #include "utils/builtins.h" #include "utils/uuid.h" @@ -423,7 +422,6 @@ PG_FUNCTION_INFO_V1(pg_random_bytes); Datum pg_random_bytes(PG_FUNCTION_ARGS) { -#ifdef HAVE_STRONG_RANDOM int len = PG_GETARG_INT32(0); bytea *res; @@ -440,9 +438,6 @@ pg_random_bytes(PG_FUNCTION_ARGS) px_THROW_ERROR(PXE_NO_RANDOM); PG_RETURN_BYTEA_P(res); -#else - px_THROW_ERROR(PXE_NO_RANDOM); -#endif } /* SQL function: gen_random_uuid() returns uuid */ @@ -451,24 +446,8 @@ PG_FUNCTION_INFO_V1(pg_random_uuid); Datum pg_random_uuid(PG_FUNCTION_ARGS) { -#ifdef HAVE_STRONG_RANDOM - uint8 *buf = (uint8 *) palloc(UUID_LEN); - - /* Generate random bits. */ - if (!pg_backend_random((char *) buf, UUID_LEN)) - px_THROW_ERROR(PXE_NO_RANDOM); - - /* - * Set magic numbers for a "version 4" (pseudorandom) UUID, see - * http://tools.ietf.org/html/rfc4122#section-4.4 - */ - buf[6] = (buf[6] & 0x0f) | 0x40; /* "version" field */ - buf[8] = (buf[8] & 0x3f) | 0x80; /* "variant" field */ - - PG_RETURN_UUID_P((pg_uuid_t *) buf); -#else - px_THROW_ERROR(PXE_NO_RANDOM); -#endif + /* redirect to built-in function */ + return gen_random_uuid(fcinfo); } static void * diff --git a/contrib/pgcrypto/pgp-compress.c b/contrib/pgcrypto/pgp-compress.c index 57efe733386..2adaf2c8755 100644 --- a/contrib/pgcrypto/pgp-compress.c +++ b/contrib/pgcrypto/pgp-compress.c @@ -117,7 +117,7 @@ compress_process(PushFilter *next, void *priv, const uint8 *data, int len) */ while (len > 0) { - st->stream.next_in = (void *) data; + st->stream.next_in = unconstify(uint8 *, data); st->stream.avail_in = len; st->stream.next_out = st->buf; st->stream.avail_out = st->buf_len; @@ -311,7 +311,7 @@ pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src) { return pullf_create(res, &decompress_filter, ctx, src); } -#else /* !HAVE_ZLIB */ +#else /* !HAVE_LIBZ */ int pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst) diff --git a/contrib/pgcrypto/pgp-decrypt.c b/contrib/pgcrypto/pgp-decrypt.c index 7d31e5354b8..4c43eb7e3ef 100644 --- a/contrib/pgcrypto/pgp-decrypt.c +++ b/contrib/pgcrypto/pgp-decrypt.c @@ -132,7 +132,7 @@ pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx) int res; uint8 *p; - /* EOF is normal here, thus we dont use GETBYTE */ + /* EOF is normal here, thus we don't use GETBYTE */ res = pullf_read(src, 1, &p); if (res < 0) return res; @@ -355,7 +355,7 @@ mdc_finish(PGP_Context *ctx, PullFilter *src, int len) if (len != 20) return PXE_PGP_CORRUPT_DATA; - /* mdc_read should not call md_update */ + /* mdc_read should not call px_md_update */ ctx->in_mdc_pkt = 1; /* read data */ @@ -423,7 +423,7 @@ static struct PullFilterOps mdc_filter = { /* * Combined Pkt reader and MDC hasher. * - * For the case of SYMENCRYPTED_MDC packet, where + * For the case of SYMENCRYPTED_DATA_MDC packet, where * the data part has 'context length', which means * that data packet ends 22 bytes before end of parent * packet, which is silly. @@ -811,8 +811,8 @@ parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt) } /* process_data_packets and parse_compressed_data call each other */ -static int process_data_packets(PGP_Context *ctx, MBuf *dst, - PullFilter *src, int allow_compr, int need_mdc); +static int process_data_packets(PGP_Context *ctx, MBuf *dst, + PullFilter *src, int allow_compr, int need_mdc); static int parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt) @@ -894,7 +894,10 @@ process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src, break; } - /* context length inside SYMENC_MDC needs special handling */ + /* + * Context length inside SYMENCRYPTED_DATA_MDC packet needs special + * handling. + */ if (need_mdc && res == PKT_CONTEXT) res = pullf_create(&pkt, &mdcbuf_filter, ctx, src); else diff --git a/contrib/pgcrypto/pgp-encrypt.c b/contrib/pgcrypto/pgp-encrypt.c index d510729e5b4..2938b4b3f5e 100644 --- a/contrib/pgcrypto/pgp-encrypt.c +++ b/contrib/pgcrypto/pgp-encrypt.c @@ -37,8 +37,6 @@ #include "px.h" #include "pgp.h" -#include "utils/backend_random.h" - #define MDC_DIGEST_LEN 20 #define STREAM_ID 0xE0 @@ -481,13 +479,12 @@ init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst) static int write_prefix(PGP_Context *ctx, PushFilter *dst) { -#ifdef HAVE_STRONG_RANDOM uint8 prefix[PGP_MAX_BLOCK + 2]; int res, bs; bs = pgp_get_cipher_block_size(ctx->cipher_algo); - if (!pg_backend_random((char *) prefix, bs)) + if (!pg_strong_random(prefix, bs)) return PXE_NO_RANDOM; prefix[bs + 0] = prefix[bs - 2]; @@ -496,9 +493,6 @@ write_prefix(PGP_Context *ctx, PushFilter *dst) res = pushf_write(dst, prefix, bs + 2); px_memset(prefix, 0, bs + 2); return res < 0 ? res : 0; -#else - return PXE_NO_RANDOM; -#endif } /* @@ -587,13 +581,9 @@ init_sess_key(PGP_Context *ctx) { if (ctx->use_sess_key || ctx->pub_key) { -#ifdef HAVE_STRONG_RANDOM ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo); - if (!pg_strong_random((char *) ctx->sess_key, ctx->sess_key_len)) + if (!pg_strong_random(ctx->sess_key, ctx->sess_key_len)) return PXE_NO_RANDOM; -#else - return PXE_NO_RANDOM; -#endif } else { @@ -628,7 +618,7 @@ pgp_encrypt(PGP_Context *ctx, MBuf *src, MBuf *dst) goto out; /* - * initialize symkey + * initialize sym_key */ if (ctx->sym_key) { diff --git a/contrib/pgcrypto/pgp-mpi-internal.c b/contrib/pgcrypto/pgp-mpi-internal.c index 545009ce199..c73f086b0be 100644 --- a/contrib/pgcrypto/pgp-mpi-internal.c +++ b/contrib/pgcrypto/pgp-mpi-internal.c @@ -57,13 +57,12 @@ mp_clear_free(mpz_t *a) static int mp_px_rand(uint32 bits, mpz_t *res) { -#ifdef HAVE_STRONG_RANDOM unsigned bytes = (bits + 7) / 8; int last_bits = bits & 7; uint8 *buf; buf = px_alloc(bytes); - if (!pg_strong_random((char *) buf, bytes)) + if (!pg_strong_random(buf, bytes)) { px_free(buf); return PXE_NO_RANDOM; @@ -83,9 +82,6 @@ mp_px_rand(uint32 bits, mpz_t *res) px_free(buf); return 0; -#else - return PXE_NO_RANDOM; -#endif } static void diff --git a/contrib/pgcrypto/pgp-pgsql.c b/contrib/pgcrypto/pgp-pgsql.c index 0984e01a14b..3feadf7b702 100644 --- a/contrib/pgcrypto/pgp-pgsql.c +++ b/contrib/pgcrypto/pgp-pgsql.c @@ -761,7 +761,7 @@ pgp_pub_decrypt_text(PG_FUNCTION_ARGS) */ /* - * Helper function for pgp_armor. Converts arrays of keys and values into + * Helper function for pg_armor. Converts arrays of keys and values into * plain C arrays, and checks that they don't contain invalid characters. */ static int diff --git a/contrib/pgcrypto/pgp-pubenc.c b/contrib/pgcrypto/pgp-pubenc.c index 44398766643..08599f09786 100644 --- a/contrib/pgcrypto/pgp-pubenc.c +++ b/contrib/pgcrypto/pgp-pubenc.c @@ -39,7 +39,6 @@ static int pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) { -#ifdef HAVE_STRONG_RANDOM uint8 *buf, *p; int pad_len = res_len - 2 - data_len; @@ -50,7 +49,7 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) buf = px_alloc(res_len); buf[0] = 0x02; - if (!pg_strong_random((char *) buf + 1, pad_len)) + if (!pg_strong_random(buf + 1, pad_len)) { px_free(buf); return PXE_NO_RANDOM; @@ -62,11 +61,11 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) { if (*p == 0) { - if (!pg_strong_random((char *) p, 1)) + if (!pg_strong_random(p, 1)) { px_memset(buf, 0, res_len); px_free(buf); - break; + return PXE_NO_RANDOM; } } if (*p != 0) @@ -78,10 +77,6 @@ pad_eme_pkcs1_v15(uint8 *data, int data_len, int res_len, uint8 **res_p) *res_p = buf; return 0; - -#else - return PXE_NO_RANDOM; -#endif } static int diff --git a/contrib/pgcrypto/pgp-s2k.c b/contrib/pgcrypto/pgp-s2k.c index a0fd8969efe..3f2f442ffcc 100644 --- a/contrib/pgcrypto/pgp-s2k.c +++ b/contrib/pgcrypto/pgp-s2k.c @@ -34,7 +34,6 @@ #include "px.h" #include "pgp.h" -#include "utils/backend_random.h" static int calc_s2k_simple(PGP_S2K *s2k, PX_MD *md, const uint8 *key, @@ -235,13 +234,13 @@ pgp_s2k_fill(PGP_S2K *s2k, int mode, int digest_algo, int count) case PGP_S2K_SIMPLE: break; case PGP_S2K_SALTED: - if (!pg_backend_random((char *) s2k->salt, PGP_S2K_SALT)) + if (!pg_strong_random(s2k->salt, PGP_S2K_SALT)) return PXE_NO_RANDOM; break; case PGP_S2K_ISALTED: - if (!pg_backend_random((char *) s2k->salt, PGP_S2K_SALT)) + if (!pg_strong_random(s2k->salt, PGP_S2K_SALT)) return PXE_NO_RANDOM; - if (!pg_backend_random((char *) &tmp, 1)) + if (!pg_strong_random(&tmp, 1)) return PXE_NO_RANDOM; s2k->iter = decide_s2k_iter(tmp, count); break; diff --git a/contrib/pgcrypto/pgp.c b/contrib/pgcrypto/pgp.c index 0800fc325d1..dd8dae1b845 100644 --- a/contrib/pgcrypto/pgp.c +++ b/contrib/pgcrypto/pgp.c @@ -54,7 +54,6 @@ struct digest_info { const char *name; int code; - const char *int_name; }; struct cipher_info diff --git a/contrib/pgcrypto/pgp.h b/contrib/pgcrypto/pgp.h index 1b6ea4c9eaf..f338523b7a6 100644 --- a/contrib/pgcrypto/pgp.h +++ b/contrib/pgcrypto/pgp.h @@ -261,8 +261,8 @@ int pgp_set_unicode_mode(PGP_Context *ctx, int mode); int pgp_get_unicode_mode(PGP_Context *ctx); int pgp_set_symkey(PGP_Context *ctx, const uint8 *key, int klen); -int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt, - const uint8 *key, int klen, int pubtype); +int pgp_set_pubkey(PGP_Context *ctx, MBuf *keypkt, + const uint8 *key, int klen, int pubtype); int pgp_get_keyid(MBuf *pgp_data, char *dst); @@ -278,17 +278,17 @@ int pgp_s2k_read(PullFilter *src, PGP_S2K *s2k); int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int klen); typedef struct PGP_CFB PGP_CFB; -int pgp_cfb_create(PGP_CFB **ctx_p, int algo, - const uint8 *key, int key_len, int recync, uint8 *iv); +int pgp_cfb_create(PGP_CFB **ctx_p, int algo, + const uint8 *key, int key_len, int resync, uint8 *iv); void pgp_cfb_free(PGP_CFB *ctx); int pgp_cfb_encrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst); int pgp_cfb_decrypt(PGP_CFB *ctx, const uint8 *data, int len, uint8 *dst); -void pgp_armor_encode(const uint8 *src, unsigned len, StringInfo dst, - int num_headers, char **keys, char **values); +void pgp_armor_encode(const uint8 *src, unsigned len, StringInfo dst, + int num_headers, char **keys, char **values); int pgp_armor_decode(const uint8 *src, int len, StringInfo dst); -int pgp_extract_armor_headers(const uint8 *src, unsigned len, - int *nheaders, char ***keys, char ***values); +int pgp_extract_armor_headers(const uint8 *src, unsigned len, + int *nheaders, char ***keys, char ***values); int pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst); int pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src); @@ -298,10 +298,10 @@ void pgp_key_free(PGP_PubKey *pk); int _pgp_read_public_key(PullFilter *pkt, PGP_PubKey **pk_p); int pgp_parse_pubenc_sesskey(PGP_Context *ctx, PullFilter *pkt); -int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, - int pkttype, PGP_Context *ctx); -int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, - int allow_ctx); +int pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len, + int pkttype, PGP_Context *ctx); +int pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, + int allow_ctx); int pgp_skip_packet(PullFilter *pkt); int pgp_expect_packet_end(PullFilter *pkt); @@ -317,10 +317,10 @@ int pgp_mpi_write(PushFilter *dst, PGP_MPI *n); int pgp_mpi_hash(PX_MD *md, PGP_MPI *n); unsigned pgp_mpi_cksum(unsigned cksum, PGP_MPI *n); -int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m, - PGP_MPI **c1, PGP_MPI **c2); -int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2, - PGP_MPI **m); +int pgp_elgamal_encrypt(PGP_PubKey *pk, PGP_MPI *m, + PGP_MPI **c1, PGP_MPI **c2); +int pgp_elgamal_decrypt(PGP_PubKey *pk, PGP_MPI *c1, PGP_MPI *c2, + PGP_MPI **m); int pgp_rsa_encrypt(PGP_PubKey *pk, PGP_MPI *m, PGP_MPI **c); int pgp_rsa_decrypt(PGP_PubKey *pk, PGP_MPI *c, PGP_MPI **m); diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c index ee40788fe71..51be0b7da17 100644 --- a/contrib/pgcrypto/px-crypt.c +++ b/contrib/pgcrypto/px-crypt.c @@ -34,7 +34,6 @@ #include "px.h" #include "px-crypt.h" -#include "utils/backend_random.h" static char * run_crypt_des(const char *psw, const char *salt, @@ -153,7 +152,7 @@ px_gen_salt(const char *salt_type, char *buf, int rounds) return PXE_BAD_SALT_ROUNDS; } - if (!pg_backend_random(rbuf, g->input_len)) + if (!pg_strong_random(rbuf, g->input_len)) return PXE_NO_RANDOM; p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); diff --git a/contrib/pgcrypto/px-crypt.h b/contrib/pgcrypto/px-crypt.h index 696902a17c3..08001a81f5e 100644 --- a/contrib/pgcrypto/px-crypt.h +++ b/contrib/pgcrypto/px-crypt.h @@ -56,27 +56,27 @@ int px_gen_salt(const char *salt_type, char *dst, int rounds); */ /* crypt-gensalt.c */ -char *_crypt_gensalt_traditional_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_extended_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_md5_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_blowfish_rn(unsigned long count, - const char *input, int size, char *output, int output_size); +char *_crypt_gensalt_traditional_rn(unsigned long count, + const char *input, int size, char *output, int output_size); +char *_crypt_gensalt_extended_rn(unsigned long count, + const char *input, int size, char *output, int output_size); +char *_crypt_gensalt_md5_rn(unsigned long count, + const char *input, int size, char *output, int output_size); +char *_crypt_gensalt_blowfish_rn(unsigned long count, + const char *input, int size, char *output, int output_size); /* disable 'extended DES crypt' */ /* #define DISABLE_XDES */ /* crypt-blowfish.c */ -char *_crypt_blowfish_rn(const char *key, const char *setting, - char *output, int size); +char *_crypt_blowfish_rn(const char *key, const char *setting, + char *output, int size); /* crypt-des.c */ char *px_crypt_des(const char *key, const char *setting); /* crypt-md5.c */ -char *px_crypt_md5(const char *pw, const char *salt, - char *dst, unsigned dstlen); +char *px_crypt_md5(const char *pw, const char *salt, + char *dst, unsigned dstlen); #endif /* _PX_CRYPT_H */ diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c index aea8e863af0..0f02fb56c4f 100644 --- a/contrib/pgcrypto/px.c +++ b/contrib/pgcrypto/px.c @@ -56,7 +56,7 @@ static const struct error_desc px_err_list[] = { {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"}, {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"}, {PXE_MCRYPT_INTERNAL, "mcrypt internal error"}, - {PXE_NO_RANDOM, "No strong random source"}, + {PXE_NO_RANDOM, "Failed to generate strong random bits"}, {PXE_DECRYPT_FAILED, "Decryption failed"}, {PXE_PGP_CORRUPT_DATA, "Wrong key or corrupt data"}, {PXE_PGP_CORRUPT_ARMOR, "Corrupt ascii-armor"}, @@ -97,17 +97,9 @@ px_THROW_ERROR(int err) { if (err == PXE_NO_RANDOM) { -#ifdef HAVE_STRONG_RANDOM ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("could not generate a random number"))); -#else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("generating random data is not supported by this build"), - errdetail("This functionality requires a source of strong random numbers."), - errhint("You need to rebuild PostgreSQL using --enable-strong-random."))); -#endif } else { diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h index cef9c4b4565..0d4722a04a0 100644 --- a/contrib/pgcrypto/px.h +++ b/contrib/pgcrypto/px.h @@ -50,9 +50,6 @@ void *px_realloc(void *p, size_t s); void px_free(void *p); #endif -/* max len of 'type' parms */ -#define PX_MAX_NAMELEN 128 - /* max salt returned */ #define PX_MAX_SALT_LEN 128 diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c index fb6a57d917c..64671ac64d9 100644 --- a/contrib/pgcrypto/sha1.c +++ b/contrib/pgcrypto/sha1.c @@ -59,16 +59,6 @@ static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; #define BCOUNT (ctxt->c.b64[0] / 8) #define W(n) (ctxt->m.b32[(n)]) -#define PUTBYTE(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - #define PUTPAD(x) \ do { \ ctxt->m.b8[(COUNT % 64)] = (x); \ diff --git a/contrib/pgcrypto/sql/hmac-sha1.sql b/contrib/pgcrypto/sql/hmac-sha1.sql index 6f741934bfd..3bc965578c5 100644 --- a/contrib/pgcrypto/sql/hmac-sha1.sql +++ b/contrib/pgcrypto/sql/hmac-sha1.sql @@ -1,5 +1,5 @@ -- --- HMAC-MD5 +-- HMAC-SHA1 -- SELECT encode(hmac( diff --git a/contrib/pgcrypto/sql/pgp-decrypt.sql b/contrib/pgcrypto/sql/pgp-decrypt.sql index f46a18f8cfd..557948d7c75 100644 --- a/contrib/pgcrypto/sql/pgp-decrypt.sql +++ b/contrib/pgcrypto/sql/pgp-decrypt.sql @@ -1,5 +1,5 @@ -- --- pgp_descrypt tests +-- pgp decrypt tests -- -- Checking ciphers diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c index 94e051d642b..a2c44a916cf 100644 --- a/contrib/pgrowlocks/pgrowlocks.c +++ b/contrib/pgrowlocks/pgrowlocks.c @@ -24,10 +24,13 @@ #include "postgres.h" +#include "access/heapam.h" #include "access/multixact.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/namespace.h" +#include "catalog/pg_am_d.h" #include "catalog/pg_authid.h" #include "funcapi.h" #include "miscadmin.h" @@ -37,7 +40,6 @@ #include "utils/builtins.h" #include "utils/rel.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" #include "utils/varlena.h" PG_MODULE_MAGIC; @@ -55,7 +57,7 @@ PG_FUNCTION_INFO_V1(pgrowlocks); typedef struct { Relation rel; - HeapScanDesc scan; + TableScanDesc scan; int ncolumns; } MyData; @@ -70,7 +72,8 @@ Datum pgrowlocks(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; - HeapScanDesc scan; + TableScanDesc scan; + HeapScanDesc hscan; HeapTuple tuple; TupleDesc tupdesc; AttInMetadata *attinmeta; @@ -99,6 +102,10 @@ pgrowlocks(PG_FUNCTION_ARGS) relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -124,7 +131,8 @@ pgrowlocks(PG_FUNCTION_ARGS) aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), RelationGetRelationName(rel)); - scan = heap_beginscan(rel, GetActiveSnapshot(), 0, NULL); + scan = table_beginscan(rel, GetActiveSnapshot(), 0, NULL); + hscan = (HeapScanDesc) scan; mydata = palloc(sizeof(*mydata)); mydata->rel = rel; mydata->scan = scan; @@ -138,27 +146,28 @@ pgrowlocks(PG_FUNCTION_ARGS) attinmeta = funcctx->attinmeta; mydata = (MyData *) funcctx->user_fctx; scan = mydata->scan; + hscan = (HeapScanDesc) scan; /* scan the relation */ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - HTSU_Result htsu; + TM_Result htsu; TransactionId xmax; uint16 infomask; /* must hold a buffer lock to call HeapTupleSatisfiesUpdate */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); htsu = HeapTupleSatisfiesUpdate(tuple, GetCurrentCommandId(false), - scan->rs_cbuf); + hscan->rs_cbuf); xmax = HeapTupleHeaderGetRawXmax(tuple->t_data); infomask = tuple->t_data->t_infomask; /* - * A tuple is locked if HTSU returns BeingUpdated. + * A tuple is locked if HTSU returns BeingModified. */ - if (htsu == HeapTupleBeingUpdated) + if (htsu == TM_BeingModified) { char **values; @@ -284,7 +293,7 @@ pgrowlocks(PG_FUNCTION_ARGS) BackendXidGetPid(xmax)); } - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); /* build a tuple */ tuple = BuildTupleFromCStrings(attinmeta, values); @@ -301,12 +310,12 @@ pgrowlocks(PG_FUNCTION_ARGS) } else { - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); } } - heap_endscan(scan); - heap_close(mydata->rel, AccessShareLock); + table_endscan(scan); + table_close(mydata->rel, AccessShareLock); SRF_RETURN_DONE(funcctx); } diff --git a/contrib/pgstattuple/expected/pgstattuple.out b/contrib/pgstattuple/expected/pgstattuple.out index a7087f6d457..9920dbfd408 100644 --- a/contrib/pgstattuple/expected/pgstattuple.out +++ b/contrib/pgstattuple/expected/pgstattuple.out @@ -48,7 +48,7 @@ select version, tree_level, from pgstatindex('test_pkey'); version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+-------------------- - 3 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN + 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN (1 row) select version, tree_level, @@ -58,7 +58,7 @@ select version, tree_level, from pgstatindex('test_pkey'::text); version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+-------------------- - 3 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN + 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN (1 row) select version, tree_level, @@ -68,7 +68,7 @@ select version, tree_level, from pgstatindex('test_pkey'::name); version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+-------------------- - 3 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN + 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN (1 row) select version, tree_level, @@ -78,7 +78,7 @@ select version, tree_level, from pgstatindex('test_pkey'::regclass); version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+-------------------- - 3 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN + 4 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN (1 row) select pg_relpages('test'); @@ -141,20 +141,23 @@ select * from pgstathashindex('test_hashidx'); select pgstatginindex('test_pkey'); ERROR: relation "test_pkey" is not a GIN index select pgstathashindex('test_pkey'); -ERROR: relation "test_pkey" is not a HASH index +ERROR: relation "test_pkey" is not a hash index select pgstatindex('test_ginidx'); ERROR: relation "test_ginidx" is not a btree index select pgstathashindex('test_ginidx'); -ERROR: relation "test_ginidx" is not a HASH index +ERROR: relation "test_ginidx" is not a hash index select pgstatindex('test_hashidx'); ERROR: relation "test_hashidx" is not a btree index select pgstatginindex('test_hashidx'); ERROR: relation "test_hashidx" is not a GIN index -- check that using any of these functions with unsupported relations will fail create table test_partitioned (a int) partition by range (a); +create index test_partitioned_index on test_partitioned(a); -- these should all fail select pgstattuple('test_partitioned'); ERROR: "test_partitioned" (partitioned table) is not supported +select pgstattuple('test_partitioned_index'); +ERROR: "test_partitioned_index" (partitioned index) is not supported select pgstattuple_approx('test_partitioned'); ERROR: "test_partitioned" is not a table or materialized view select pg_relpages('test_partitioned'); @@ -229,7 +232,7 @@ create index test_partition_hash_idx on test_partition using hash (a); select pgstatindex('test_partition_idx'); pgstatindex ------------------------------ - (3,0,8192,0,0,0,0,0,NaN,NaN) + (4,0,8192,0,0,0,0,0,NaN,NaN) (1 row) select pgstathashindex('test_partition_hash_idx'); diff --git a/contrib/pgstattuple/pgstatapprox.c b/contrib/pgstattuple/pgstatapprox.c index ef33cacec6a..636c8d40aca 100644 --- a/contrib/pgstattuple/pgstatapprox.c +++ b/contrib/pgstattuple/pgstatapprox.c @@ -3,7 +3,7 @@ * pgstatapprox.c * Bloat estimation functions * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/pgstattuple/pgstatapprox.c @@ -12,12 +12,16 @@ */ #include "postgres.h" -#include "access/visibilitymap.h" +#include "access/heapam.h" +#include "access/relation.h" #include "access/transam.h" +#include "access/visibilitymap.h" #include "access/xact.h" #include "access/multixact.h" #include "access/htup_details.h" #include "catalog/namespace.h" +#include "catalog/pg_am_d.h" +#include "commands/vacuum.h" #include "funcapi.h" #include "miscadmin.h" #include "storage/bufmgr.h" @@ -25,8 +29,6 @@ #include "storage/procarray.h" #include "storage/lmgr.h" #include "utils/builtins.h" -#include "utils/tqual.h" -#include "commands/vacuum.h" PG_FUNCTION_INFO_V1(pgstattuple_approx); PG_FUNCTION_INFO_V1(pgstattuple_approx_v1_5); @@ -287,6 +289,10 @@ pgstattuple_approx_internal(Oid relid, FunctionCallInfo fcinfo) errmsg("\"%s\" is not a table or materialized view", RelationGetRelationName(rel)))); + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); + statapprox_heap(rel, &stat); relation_close(rel, AccessShareLock); diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index 75317b96a2f..4bae176e09e 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -28,10 +28,11 @@ #include "postgres.h" #include "access/gin_private.h" -#include "access/heapam.h" #include "access/hash.h" #include "access/htup_details.h" #include "access/nbtree.h" +#include "access/relation.h" +#include "access/table.h" #include "catalog/namespace.h" #include "catalog/pg_am.h" #include "funcapi.h" @@ -601,10 +602,9 @@ pgstathashindex(PG_FUNCTION_ARGS) if (!IS_HASH(rel)) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("relation \"%s\" is not a HASH index", + errmsg("relation \"%s\" is not a hash index", RelationGetRelationName(rel)))); - /* * Reject attempts to read non-local temporary relations; we would be * likely to get wrong data since we have no visibility into the owning @@ -727,7 +727,7 @@ pgstathashindex(PG_FUNCTION_ARGS) } /* ------------------------------------------------- - * GetHashPageStatis() + * GetHashPageStats() * * Collect statistics of single hash page * ------------------------------------------------- diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index b599b6ca21a..70af43ebd5a 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -26,16 +26,17 @@ #include "access/gist_private.h" #include "access/hash.h" +#include "access/heapam.h" #include "access/nbtree.h" #include "access/relscan.h" +#include "access/tableam.h" #include "catalog/namespace.h" -#include "catalog/pg_am.h" +#include "catalog/pg_am_d.h" #include "funcapi.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "utils/builtins.h" -#include "utils/tqual.h" #include "utils/varlena.h" PG_MODULE_MAGIC; @@ -65,22 +66,22 @@ typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber, BufferAccessStrategy); static Datum build_pgstattuple_type(pgstattuple_type *stat, - FunctionCallInfo fcinfo); + FunctionCallInfo fcinfo); static Datum pgstat_relation(Relation rel, FunctionCallInfo fcinfo); static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo); static void pgstat_btree_page(pgstattuple_type *stat, - Relation rel, BlockNumber blkno, - BufferAccessStrategy bstrategy); + Relation rel, BlockNumber blkno, + BufferAccessStrategy bstrategy); static void pgstat_hash_page(pgstattuple_type *stat, - Relation rel, BlockNumber blkno, - BufferAccessStrategy bstrategy); + Relation rel, BlockNumber blkno, + BufferAccessStrategy bstrategy); static void pgstat_gist_page(pgstattuple_type *stat, - Relation rel, BlockNumber blkno, - BufferAccessStrategy bstrategy); + Relation rel, BlockNumber blkno, + BufferAccessStrategy bstrategy); static Datum pgstat_index(Relation rel, BlockNumber start, - pgstat_page pagefn, FunctionCallInfo fcinfo); + pgstat_page pagefn, FunctionCallInfo fcinfo); static void pgstat_index_page(pgstattuple_type *stat, Page page, - OffsetNumber minoff, OffsetNumber maxoff); + OffsetNumber minoff, OffsetNumber maxoff); /* * build_pgstattuple_type -- build a pgstattuple_type tuple @@ -296,6 +297,9 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo) case RELKIND_PARTITIONED_TABLE: err = "partitioned table"; break; + case RELKIND_PARTITIONED_INDEX: + err = "partitioned index"; + break; default: err = "unknown"; break; @@ -314,7 +318,8 @@ pgstat_relation(Relation rel, FunctionCallInfo fcinfo) static Datum pgstat_heap(Relation rel, FunctionCallInfo fcinfo) { - HeapScanDesc scan; + TableScanDesc scan; + HeapScanDesc hscan; HeapTuple tuple; BlockNumber nblocks; BlockNumber block = 0; /* next block to count free space in */ @@ -323,11 +328,18 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) pgstattuple_type stat = {0}; SnapshotData SnapshotDirty; + if (rel->rd_rel->relam != HEAP_TABLE_AM_OID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("only heap AM is supported"))); + /* Disable syncscan because we assume we scan from block zero upwards */ - scan = heap_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false); + scan = table_beginscan_strat(rel, SnapshotAny, 0, NULL, true, false); + hscan = (HeapScanDesc) scan; + InitDirtySnapshot(SnapshotDirty); - nblocks = scan->rs_nblocks; /* # blocks to be scanned */ + nblocks = hscan->rs_nblocks; /* # blocks to be scanned */ /* scan the relation */ while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) @@ -335,9 +347,9 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); - if (HeapTupleSatisfiesVisibility(tuple, &SnapshotDirty, scan->rs_cbuf)) + if (HeapTupleSatisfiesVisibility(tuple, &SnapshotDirty, hscan->rs_cbuf)) { stat.tuple_len += tuple->t_len; stat.tuple_count++; @@ -348,7 +360,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) stat.dead_tuple_count++; } - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); /* * To avoid physically reading the table twice, try to do the @@ -363,7 +375,7 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, - RBM_NORMAL, scan->rs_strategy); + RBM_NORMAL, hscan->rs_strategy); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); @@ -376,14 +388,14 @@ pgstat_heap(Relation rel, FunctionCallInfo fcinfo) CHECK_FOR_INTERRUPTS(); buffer = ReadBufferExtended(rel, MAIN_FORKNUM, block, - RBM_NORMAL, scan->rs_strategy); + RBM_NORMAL, hscan->rs_strategy); LockBuffer(buffer, BUFFER_LOCK_SHARE); stat.free_space += PageGetHeapFreeSpace((Page) BufferGetPage(buffer)); UnlockReleaseBuffer(buffer); block++; } - heap_endscan(scan); + table_endscan(scan); relation_close(rel, AccessShareLock); stat.table_len = (uint64) nblocks * BLCKSZ; diff --git a/contrib/pgstattuple/sql/pgstattuple.sql b/contrib/pgstattuple/sql/pgstattuple.sql index a8e341e3518..cfa540302da 100644 --- a/contrib/pgstattuple/sql/pgstattuple.sql +++ b/contrib/pgstattuple/sql/pgstattuple.sql @@ -64,8 +64,10 @@ select pgstatginindex('test_hashidx'); -- check that using any of these functions with unsupported relations will fail create table test_partitioned (a int) partition by range (a); +create index test_partitioned_index on test_partitioned(a); -- these should all fail select pgstattuple('test_partitioned'); +select pgstattuple('test_partitioned_index'); select pgstattuple_approx('test_partitioned'); select pg_relpages('test_partitioned'); select pgstatindex('test_partitioned'); diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c index fe4893a8e05..57ed5f4b905 100644 --- a/contrib/postgres_fdw/connection.c +++ b/contrib/postgres_fdw/connection.c @@ -3,7 +3,7 @@ * connection.c * Connection management functions for postgres_fdw * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/connection.c @@ -15,8 +15,8 @@ #include "postgres_fdw.h" #include "access/htup_details.h" -#include "catalog/pg_user_mapping.h" #include "access/xact.h" +#include "catalog/pg_user_mapping.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "pgstat.h" @@ -81,16 +81,16 @@ static void do_sql_command(PGconn *conn, const char *sql); static void begin_remote_xact(ConnCacheEntry *entry); static void pgfdw_xact_callback(XactEvent event, void *arg); static void pgfdw_subxact_callback(SubXactEvent event, - SubTransactionId mySubid, - SubTransactionId parentSubid, - void *arg); + SubTransactionId mySubid, + SubTransactionId parentSubid, + void *arg); static void pgfdw_inval_callback(Datum arg, int cacheid, uint32 hashvalue); static void pgfdw_reject_incomplete_xact_state_change(ConnCacheEntry *entry); static bool pgfdw_cancel_query(PGconn *conn); static bool pgfdw_exec_cleanup_query(PGconn *conn, const char *query, - bool ignore_errors); + bool ignore_errors); static bool pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, - PGresult **result); + PGresult **result); /* @@ -546,7 +546,8 @@ pgfdw_get_result(PGconn *conn, const char *query) /* Sleep until there's something to do */ wc = WaitLatchOrSocket(MyLatch, - WL_LATCH_SET | WL_SOCKET_READABLE, + WL_LATCH_SET | WL_SOCKET_READABLE | + WL_EXIT_ON_PM_DEATH, PQsocket(conn), -1L, PG_WAIT_EXTENSION); ResetLatch(MyLatch); @@ -1152,7 +1153,8 @@ pgfdw_get_cleanup_result(PGconn *conn, TimestampTz endtime, PGresult **result) /* Sleep until there's something to do */ wc = WaitLatchOrSocket(MyLatch, - WL_LATCH_SET | WL_SOCKET_READABLE | WL_TIMEOUT, + WL_LATCH_SET | WL_SOCKET_READABLE | + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, PQsocket(conn), cur_timeout, PG_WAIT_EXTENSION); ResetLatch(MyLatch); diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c index 6e2fa1420c4..431c34a4246 100644 --- a/contrib/postgres_fdw/deparse.c +++ b/contrib/postgres_fdw/deparse.c @@ -24,7 +24,7 @@ * with collations that match the remote table's columns, which we can * consider to be user error. * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/deparse.c @@ -35,9 +35,9 @@ #include "postgres_fdw.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_collation.h" #include "catalog/pg_namespace.h" @@ -48,10 +48,9 @@ #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "nodes/plannodes.h" -#include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/prep.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parsetree.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -117,81 +116,84 @@ typedef struct deparse_expr_cxt * remote server. */ static bool foreign_expr_walker(Node *node, - foreign_glob_cxt *glob_cxt, - foreign_loc_cxt *outer_cxt); + foreign_glob_cxt *glob_cxt, + foreign_loc_cxt *outer_cxt); static char *deparse_type_name(Oid type_oid, int32 typemod); /* * Functions to construct string representation of a node tree. */ static void deparseTargetList(StringInfo buf, - PlannerInfo *root, - Index rtindex, - Relation rel, - bool is_returning, - Bitmapset *attrs_used, - bool qualify_col, - List **retrieved_attrs); + RangeTblEntry *rte, + Index rtindex, + Relation rel, + bool is_returning, + Bitmapset *attrs_used, + bool qualify_col, + List **retrieved_attrs); static void deparseExplicitTargetList(List *tlist, - bool is_returning, - List **retrieved_attrs, - deparse_expr_cxt *context); + bool is_returning, + List **retrieved_attrs, + deparse_expr_cxt *context); static void deparseSubqueryTargetList(deparse_expr_cxt *context); -static void deparseReturningList(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - bool trig_after_row, - List *returningList, - List **retrieved_attrs); +static void deparseReturningList(StringInfo buf, RangeTblEntry *rte, + Index rtindex, Relation rel, + bool trig_after_row, + List *withCheckOptionList, + List *returningList, + List **retrieved_attrs); static void deparseColumnRef(StringInfo buf, int varno, int varattno, - PlannerInfo *root, bool qualify_col); + RangeTblEntry *rte, bool qualify_col); static void deparseRelation(StringInfo buf, Relation rel); static void deparseExpr(Expr *expr, deparse_expr_cxt *context); static void deparseVar(Var *node, deparse_expr_cxt *context); static void deparseConst(Const *node, deparse_expr_cxt *context, int showtype); static void deparseParam(Param *node, deparse_expr_cxt *context); -static void deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context); +static void deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context); static void deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context); static void deparseOpExpr(OpExpr *node, deparse_expr_cxt *context); static void deparseOperatorName(StringInfo buf, Form_pg_operator opform); static void deparseDistinctExpr(DistinctExpr *node, deparse_expr_cxt *context); static void deparseScalarArrayOpExpr(ScalarArrayOpExpr *node, - deparse_expr_cxt *context); + deparse_expr_cxt *context); static void deparseRelabelType(RelabelType *node, deparse_expr_cxt *context); static void deparseBoolExpr(BoolExpr *node, deparse_expr_cxt *context); static void deparseNullTest(NullTest *node, deparse_expr_cxt *context); static void deparseArrayExpr(ArrayExpr *node, deparse_expr_cxt *context); static void printRemoteParam(int paramindex, Oid paramtype, int32 paramtypmod, - deparse_expr_cxt *context); + deparse_expr_cxt *context); static void printRemotePlaceholder(Oid paramtype, int32 paramtypmod, - deparse_expr_cxt *context); + deparse_expr_cxt *context); static void deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, - deparse_expr_cxt *context); + deparse_expr_cxt *context); static void deparseLockingClause(deparse_expr_cxt *context); -static void appendOrderByClause(List *pathkeys, deparse_expr_cxt *context); +static void appendOrderByClause(List *pathkeys, bool has_final_sort, + deparse_expr_cxt *context); +static void appendLimitClause(deparse_expr_cxt *context); static void appendConditions(List *exprs, deparse_expr_cxt *context); static void deparseFromExprForRel(StringInfo buf, PlannerInfo *root, - RelOptInfo *foreignrel, bool use_alias, - Index ignore_rel, List **ignore_conds, - List **params_list); + RelOptInfo *foreignrel, bool use_alias, + Index ignore_rel, List **ignore_conds, + List **params_list); static void deparseFromExpr(List *quals, deparse_expr_cxt *context); static void deparseRangeTblRef(StringInfo buf, PlannerInfo *root, - RelOptInfo *foreignrel, bool make_subquery, - Index ignore_rel, List **ignore_conds, List **params_list); + RelOptInfo *foreignrel, bool make_subquery, + Index ignore_rel, List **ignore_conds, List **params_list); static void deparseAggref(Aggref *node, deparse_expr_cxt *context); static void appendGroupByClause(List *tlist, deparse_expr_cxt *context); static void appendAggOrderBy(List *orderList, List *targetList, - deparse_expr_cxt *context); + deparse_expr_cxt *context); static void appendFunctionName(Oid funcid, deparse_expr_cxt *context); static Node *deparseSortGroupClause(Index ref, List *tlist, bool force_colno, - deparse_expr_cxt *context); + deparse_expr_cxt *context); /* * Helper functions */ static bool is_subquery_var(Var *node, RelOptInfo *foreignrel, - int *relno, int *colno); + int *relno, int *colno); static void get_relation_column_alias_ids(Var *node, RelOptInfo *foreignrel, - int *relno, int *colno); + int *relno, int *colno); /* @@ -331,14 +333,13 @@ foreign_expr_walker(Node *node, /* Var belongs to foreign table */ /* - * System columns other than ctid and oid should not be - * sent to the remote, since we don't make any effort to - * ensure that local and remote values match (tableoid, in + * System columns other than ctid should not be sent to + * the remote, since we don't make any effort to ensure + * that local and remote values match (tableoid, in * particular, almost certainly doesn't match). */ if (var->varattno < 0 && - var->varattno != SelfItemPointerAttributeNumber && - var->varattno != ObjectIdAttributeNumber) + var->varattno != SelfItemPointerAttributeNumber) return false; /* Else check the collation */ @@ -402,34 +403,34 @@ foreign_expr_walker(Node *node, state = FDW_COLLATE_UNSAFE; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *ar = (ArrayRef *) node; + SubscriptingRef *sr = (SubscriptingRef *) node; /* Assignment should not be in restrictions. */ - if (ar->refassgnexpr != NULL) + if (sr->refassgnexpr != NULL) return false; /* - * Recurse to remaining subexpressions. Since the array + * Recurse to remaining subexpressions. Since the container * subscripts must yield (noncollatable) integers, they won't * affect the inner_cxt state. */ - if (!foreign_expr_walker((Node *) ar->refupperindexpr, + if (!foreign_expr_walker((Node *) sr->refupperindexpr, glob_cxt, &inner_cxt)) return false; - if (!foreign_expr_walker((Node *) ar->reflowerindexpr, + if (!foreign_expr_walker((Node *) sr->reflowerindexpr, glob_cxt, &inner_cxt)) return false; - if (!foreign_expr_walker((Node *) ar->refexpr, + if (!foreign_expr_walker((Node *) sr->refexpr, glob_cxt, &inner_cxt)) return false; /* - * Array subscripting should yield same collation as input, - * but for safety use same logic as for function nodes. + * Container subscripting should yield same collation as + * input, but for safety use same logic as for function nodes. */ - collation = ar->refcollid; + collation = sr->refcollid; if (collation == InvalidOid) state = FDW_COLLATE_NONE; else if (inner_cxt.state == FDW_COLLATE_SAFE && @@ -840,6 +841,55 @@ foreign_expr_walker(Node *node, return true; } +/* + * Returns true if given expr is something we'd have to send the value of + * to the foreign server. + * + * This should return true when the expression is a shippable node that + * deparseExpr would add to context->params_list. Note that we don't care + * if the expression *contains* such a node, only whether one appears at top + * level. We need this to detect cases where setrefs.c would recognize a + * false match between an fdw_exprs item (which came from the params_list) + * and an entry in fdw_scan_tlist (which we're considering putting the given + * expression into). + */ +bool +is_foreign_param(PlannerInfo *root, + RelOptInfo *baserel, + Expr *expr) +{ + if (expr == NULL) + return false; + + switch (nodeTag(expr)) + { + case T_Var: + { + /* It would have to be sent unless it's a foreign Var */ + Var *var = (Var *) expr; + PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) (baserel->fdw_private); + Relids relids; + + if (IS_UPPER_REL(baserel)) + relids = fpinfo->outerrel->relids; + else + relids = baserel->relids; + + if (bms_is_member(var->varno, relids) && var->varlevelsup == 0) + return false; /* foreign Var, so not a param */ + else + return true; /* it'd have to be a param */ + break; + } + case T_Param: + /* Params always have to be sent to the foreign server */ + return true; + default: + break; + } + return false; +} + /* * Convert type OID + typmod info into a type name we can ship to the remote * server. Someplace else had better have verified that this type name is @@ -930,8 +980,8 @@ build_tlist_to_deparse(RelOptInfo *foreignrel) void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel, List *tlist, List *remote_conds, List *pathkeys, - bool is_subquery, List **retrieved_attrs, - List **params_list) + bool has_final_sort, bool has_limit, bool is_subquery, + List **retrieved_attrs, List **params_list) { deparse_expr_cxt context; PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) rel->fdw_private; @@ -986,7 +1036,11 @@ deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *rel, /* Add ORDER BY clause if we found any useful pathkeys */ if (pathkeys) - appendOrderByClause(pathkeys, &context); + appendOrderByClause(pathkeys, has_final_sort, &context); + + /* Add LIMIT clause if necessary */ + if (has_limit) + appendLimitClause(&context); /* Add any necessary FOR UPDATE/SHARE. */ deparseLockingClause(&context); @@ -1048,11 +1102,11 @@ deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs, * Core code already has some lock on each rel being planned, so we * can use NoLock here. */ - Relation rel = heap_open(rte->relid, NoLock); + Relation rel = table_open(rte->relid, NoLock); - deparseTargetList(buf, root, foreignrel->relid, rel, false, + deparseTargetList(buf, rte, foreignrel->relid, rel, false, fpinfo->attrs_used, false, retrieved_attrs); - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -1076,7 +1130,7 @@ deparseFromExpr(List *quals, deparse_expr_cxt *context) /* Construct FROM clause */ appendStringInfoString(buf, " FROM "); deparseFromExprForRel(buf, context->root, scanrel, - (bms_num_members(scanrel->relids) > 1), + (bms_membership(scanrel->relids) == BMS_MULTIPLE), (Index) 0, NULL, context->params_list); /* Construct WHERE clause */ @@ -1099,7 +1153,7 @@ deparseFromExpr(List *quals, deparse_expr_cxt *context) */ static void deparseTargetList(StringInfo buf, - PlannerInfo *root, + RangeTblEntry *rte, Index rtindex, Relation rel, bool is_returning, @@ -1137,15 +1191,15 @@ deparseTargetList(StringInfo buf, appendStringInfoString(buf, " RETURNING "); first = false; - deparseColumnRef(buf, rtindex, i, root, qualify_col); + deparseColumnRef(buf, rtindex, i, rte, qualify_col); *retrieved_attrs = lappend_int(*retrieved_attrs, i); } } /* - * Add ctid and oid if needed. We currently don't support retrieving any - * other system columns. + * Add ctid if needed. We currently don't support retrieving any other + * system columns. */ if (bms_is_member(SelfItemPointerAttributeNumber - FirstLowInvalidHeapAttributeNumber, attrs_used)) @@ -1163,22 +1217,6 @@ deparseTargetList(StringInfo buf, *retrieved_attrs = lappend_int(*retrieved_attrs, SelfItemPointerAttributeNumber); } - if (bms_is_member(ObjectIdAttributeNumber - FirstLowInvalidHeapAttributeNumber, - attrs_used)) - { - if (!first) - appendStringInfoString(buf, ", "); - else if (is_returning) - appendStringInfoString(buf, " RETURNING "); - first = false; - - if (qualify_col) - ADD_REL_QUALIFIER(buf, rtindex); - appendStringInfoString(buf, "oid"); - - *retrieved_attrs = lappend_int(*retrieved_attrs, - ObjectIdAttributeNumber); - } /* Don't generate bad syntax if no undropped columns */ if (first && !is_returning) @@ -1262,7 +1300,7 @@ deparseLockingClause(deparse_expr_cxt *context) } /* Add the relation alias if we are here for a join relation */ - if (bms_num_members(rel->relids) > 1 && + if (bms_membership(rel->relids) == BMS_MULTIPLE && rc->strength != LCS_NONE) appendStringInfo(buf, " OF %s%d", REL_ALIAS_PREFIX, relid); } @@ -1459,7 +1497,7 @@ deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, if (fpinfo->jointype == JOIN_INNER) { *ignore_conds = list_concat(*ignore_conds, - list_copy(fpinfo->joinclauses)); + fpinfo->joinclauses); fpinfo->joinclauses = NIL; } @@ -1493,7 +1531,7 @@ deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, { Assert(fpinfo->jointype == JOIN_INNER); Assert(fpinfo->joinclauses == NIL); - appendStringInfo(buf, "%s", join_sql_o.data); + appendBinaryStringInfo(buf, join_sql_o.data, join_sql_o.len); return; } } @@ -1514,7 +1552,7 @@ deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, { Assert(fpinfo->jointype == JOIN_INNER); Assert(fpinfo->joinclauses == NIL); - appendStringInfo(buf, "%s", join_sql_i.data); + appendBinaryStringInfo(buf, join_sql_i.data, join_sql_i.len); return; } } @@ -1559,7 +1597,7 @@ deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, * Core code already has some lock on each rel being planned, so we * can use NoLock here. */ - Relation rel = heap_open(rte->relid, NoLock); + Relation rel = table_open(rte->relid, NoLock); deparseRelation(buf, rel); @@ -1571,7 +1609,7 @@ deparseFromExprForRel(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, if (use_alias) appendStringInfo(buf, " %s%d", REL_ALIAS_PREFIX, foreignrel->relid); - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -1607,7 +1645,8 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, /* Deparse the subquery representing the relation. */ appendStringInfoChar(buf, '('); deparseSelectStmtForRel(buf, root, foreignrel, NIL, - fpinfo->remote_conds, NIL, true, + fpinfo->remote_conds, NIL, + false, false, true, &retrieved_attrs, params_list); appendStringInfoChar(buf, ')'); @@ -1645,14 +1684,15 @@ deparseRangeTblRef(StringInfo buf, PlannerInfo *root, RelOptInfo *foreignrel, * deparse remote INSERT statement * * The statement text is appended to buf, and we also create an integer List - * of the columns being retrieved by RETURNING (if any), which is returned - * to *retrieved_attrs. + * of the columns being retrieved by WITH CHECK OPTION or RETURNING (if any), + * which is returned to *retrieved_attrs. */ void -deparseInsertSql(StringInfo buf, PlannerInfo *root, +deparseInsertSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *targetAttrs, bool doNothing, - List *returningList, List **retrieved_attrs) + List *withCheckOptionList, List *returningList, + List **retrieved_attrs) { AttrNumber pindex; bool first; @@ -1674,7 +1714,7 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root, appendStringInfoString(buf, ", "); first = false; - deparseColumnRef(buf, rtindex, attnum, root, false); + deparseColumnRef(buf, rtindex, attnum, rte, false); } appendStringInfoString(buf, ") VALUES ("); @@ -1699,22 +1739,23 @@ deparseInsertSql(StringInfo buf, PlannerInfo *root, if (doNothing) appendStringInfoString(buf, " ON CONFLICT DO NOTHING"); - deparseReturningList(buf, root, rtindex, rel, + deparseReturningList(buf, rte, rtindex, rel, rel->trigdesc && rel->trigdesc->trig_insert_after_row, - returningList, retrieved_attrs); + withCheckOptionList, returningList, retrieved_attrs); } /* * deparse remote UPDATE statement * * The statement text is appended to buf, and we also create an integer List - * of the columns being retrieved by RETURNING (if any), which is returned - * to *retrieved_attrs. + * of the columns being retrieved by WITH CHECK OPTION or RETURNING (if any), + * which is returned to *retrieved_attrs. */ void -deparseUpdateSql(StringInfo buf, PlannerInfo *root, +deparseUpdateSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, - List *targetAttrs, List *returningList, + List *targetAttrs, + List *withCheckOptionList, List *returningList, List **retrieved_attrs) { AttrNumber pindex; @@ -1735,15 +1776,15 @@ deparseUpdateSql(StringInfo buf, PlannerInfo *root, appendStringInfoString(buf, ", "); first = false; - deparseColumnRef(buf, rtindex, attnum, root, false); + deparseColumnRef(buf, rtindex, attnum, rte, false); appendStringInfo(buf, " = $%d", pindex); pindex++; } appendStringInfoString(buf, " WHERE ctid = $1"); - deparseReturningList(buf, root, rtindex, rel, + deparseReturningList(buf, rte, rtindex, rel, rel->trigdesc && rel->trigdesc->trig_update_after_row, - returningList, retrieved_attrs); + withCheckOptionList, returningList, retrieved_attrs); } /* @@ -1777,6 +1818,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, int nestlevel; bool first; ListCell *lc; + RangeTblEntry *rte = planner_rt_fetch(rtindex, root); /* Set up context struct for recursion */ context.root = root; @@ -1808,7 +1850,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, appendStringInfoString(buf, ", "); first = false; - deparseColumnRef(buf, rtindex, attnum, root, false); + deparseColumnRef(buf, rtindex, attnum, rte, false); appendStringInfoString(buf, " = "); deparseExpr((Expr *) tle->expr, &context); } @@ -1819,7 +1861,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, { List *ignore_conds = NIL; - appendStringInfo(buf, " FROM "); + appendStringInfoString(buf, " FROM "); deparseFromExprForRel(buf, root, foreignrel, true, rtindex, &ignore_conds, params_list); remote_conds = list_concat(remote_conds, ignore_conds); @@ -1835,8 +1877,8 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, deparseExplicitTargetList(returningList, true, retrieved_attrs, &context); else - deparseReturningList(buf, root, rtindex, rel, false, - returningList, retrieved_attrs); + deparseReturningList(buf, rte, rtindex, rel, false, + NIL, returningList, retrieved_attrs); } /* @@ -1847,7 +1889,7 @@ deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, * to *retrieved_attrs. */ void -deparseDeleteSql(StringInfo buf, PlannerInfo *root, +deparseDeleteSql(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, List *returningList, List **retrieved_attrs) @@ -1856,9 +1898,9 @@ deparseDeleteSql(StringInfo buf, PlannerInfo *root, deparseRelation(buf, rel); appendStringInfoString(buf, " WHERE ctid = $1"); - deparseReturningList(buf, root, rtindex, rel, + deparseReturningList(buf, rte, rtindex, rel, rel->trigdesc && rel->trigdesc->trig_delete_after_row, - returningList, retrieved_attrs); + NIL, returningList, retrieved_attrs); } /* @@ -1902,7 +1944,7 @@ deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, { List *ignore_conds = NIL; - appendStringInfo(buf, " USING "); + appendStringInfoString(buf, " USING "); deparseFromExprForRel(buf, root, foreignrel, true, rtindex, &ignore_conds, params_list); remote_conds = list_concat(remote_conds, ignore_conds); @@ -1918,17 +1960,19 @@ deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, deparseExplicitTargetList(returningList, true, retrieved_attrs, &context); else - deparseReturningList(buf, root, rtindex, rel, false, - returningList, retrieved_attrs); + deparseReturningList(buf, planner_rt_fetch(rtindex, root), + rtindex, rel, false, + NIL, returningList, retrieved_attrs); } /* * Add a RETURNING clause, if needed, to an INSERT/UPDATE/DELETE. */ static void -deparseReturningList(StringInfo buf, PlannerInfo *root, +deparseReturningList(StringInfo buf, RangeTblEntry *rte, Index rtindex, Relation rel, bool trig_after_row, + List *withCheckOptionList, List *returningList, List **retrieved_attrs) { @@ -1941,6 +1985,21 @@ deparseReturningList(StringInfo buf, PlannerInfo *root, bms_make_singleton(0 - FirstLowInvalidHeapAttributeNumber); } + if (withCheckOptionList != NIL) + { + /* + * We need the attrs, non-system and system, mentioned in the local + * query's WITH CHECK OPTION list. + * + * Note: we do this to ensure that WCO constraints will be evaluated + * on the data actually inserted/updated on the remote side, which + * might differ from the data supplied by the core code, for example + * as a result of remote triggers. + */ + pull_varattnos((Node *) withCheckOptionList, rtindex, + &attrs_used); + } + if (returningList != NIL) { /* @@ -1952,7 +2011,7 @@ deparseReturningList(StringInfo buf, PlannerInfo *root, } if (attrs_used != NULL) - deparseTargetList(buf, root, rtindex, rel, true, attrs_used, false, + deparseTargetList(buf, rte, rtindex, rel, true, attrs_used, false, retrieved_attrs); else *retrieved_attrs = NIL; @@ -2048,11 +2107,9 @@ deparseAnalyzeSql(StringInfo buf, Relation rel, List **retrieved_attrs) * If qualify_col is true, qualify column name with the alias of relation. */ static void -deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, +deparseColumnRef(StringInfo buf, int varno, int varattno, RangeTblEntry *rte, bool qualify_col) { - RangeTblEntry *rte; - /* We support fetching the remote side's CTID and OID. */ if (varattno == SelfItemPointerAttributeNumber) { @@ -2060,12 +2117,6 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, ADD_REL_QUALIFIER(buf, varno); appendStringInfoString(buf, "ctid"); } - else if (varattno == ObjectIdAttributeNumber) - { - if (qualify_col) - ADD_REL_QUALIFIER(buf, varno); - appendStringInfoString(buf, "oid"); - } else if (varattno < 0) { /* @@ -2077,10 +2128,7 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, Oid fetchval = 0; if (varattno == TableOidAttributeNumber) - { - rte = planner_rt_fetch(varno, root); fetchval = rte->relid; - } if (qualify_col) { @@ -2100,14 +2148,11 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, /* Required only to be passed down to deparseTargetList(). */ List *retrieved_attrs; - /* Get RangeTblEntry from array in PlannerInfo. */ - rte = planner_rt_fetch(varno, root); - /* * The lock on the relation will be held by upper callers, so it's * fine to open it with no lock here. */ - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); /* * The local name of the foreign table can not be recognized by the @@ -2134,7 +2179,7 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, } appendStringInfoString(buf, "ROW("); - deparseTargetList(buf, root, varno, rel, false, attrs_used, qualify_col, + deparseTargetList(buf, rte, varno, rel, false, attrs_used, qualify_col, &retrieved_attrs); appendStringInfoChar(buf, ')'); @@ -2142,7 +2187,7 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, if (qualify_col) appendStringInfoString(buf, " END"); - heap_close(rel, NoLock); + table_close(rel, NoLock); bms_free(attrs_used); } else @@ -2154,9 +2199,6 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, PlannerInfo *root, /* varno must not be any of OUTER_VAR, INNER_VAR and INDEX_VAR. */ Assert(!IS_SPECIAL_VARNO(varno)); - /* Get RangeTblEntry from array in PlannerInfo. */ - rte = planner_rt_fetch(varno, root); - /* * If it's a column of a foreign table, and it has the column_name FDW * option, use that value. @@ -2284,8 +2326,8 @@ deparseExpr(Expr *node, deparse_expr_cxt *context) case T_Param: deparseParam((Param *) node, context); break; - case T_ArrayRef: - deparseArrayRef((ArrayRef *) node, context); + case T_SubscriptingRef: + deparseSubscriptingRef((SubscriptingRef *) node, context); break; case T_FuncExpr: deparseFuncExpr((FuncExpr *) node, context); @@ -2337,7 +2379,7 @@ deparseVar(Var *node, deparse_expr_cxt *context) int colno; /* Qualify columns when multiple relations are involved. */ - bool qualify_col = (bms_num_members(relids) > 1); + bool qualify_col = (bms_membership(relids) == BMS_MULTIPLE); /* * If the Var belongs to the foreign relation that is deparsed as a @@ -2354,7 +2396,8 @@ deparseVar(Var *node, deparse_expr_cxt *context) if (bms_is_member(node->varno, relids) && node->varlevelsup == 0) deparseColumnRef(context->buf, node->varno, node->varattno, - context->root, qualify_col); + planner_rt_fetch(node->varno, context->root), + qualify_col); else { /* Treat like a Param */ @@ -2531,10 +2574,10 @@ deparseParam(Param *node, deparse_expr_cxt *context) } /* - * Deparse an array subscript expression. + * Deparse a container subscript expression. */ static void -deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context) +deparseSubscriptingRef(SubscriptingRef *node, deparse_expr_cxt *context) { StringInfo buf = context->buf; ListCell *lowlist_item; @@ -2567,7 +2610,7 @@ deparseArrayRef(ArrayRef *node, deparse_expr_cxt *context) { deparseExpr(lfirst(lowlist_item), context); appendStringInfoChar(buf, ':'); - lowlist_item = lnext(lowlist_item); + lowlist_item = lnext(node->reflowerindexpr, lowlist_item); } deparseExpr(lfirst(uplist_item), context); appendStringInfoChar(buf, ']'); @@ -2630,7 +2673,7 @@ deparseFuncExpr(FuncExpr *node, deparse_expr_cxt *context) { if (!first) appendStringInfoString(buf, ", "); - if (use_variadic && lnext(arg) == NULL) + if (use_variadic && lnext(node->args, arg) == NULL) appendStringInfoString(buf, "VARIADIC "); deparseExpr((Expr *) lfirst(arg), context); first = false; @@ -2958,7 +3001,7 @@ deparseAggref(Aggref *node, deparse_expr_cxt *context) first = false; /* Add VARIADIC */ - if (use_variadic && lnext(arg) == NULL) + if (use_variadic && lnext(node->args, arg) == NULL) appendStringInfoString(buf, "VARIADIC "); deparseExpr((Expr *) n, context); @@ -3122,7 +3165,8 @@ appendGroupByClause(List *tlist, deparse_expr_cxt *context) * base relation are obtained and deparsed. */ static void -appendOrderByClause(List *pathkeys, deparse_expr_cxt *context) +appendOrderByClause(List *pathkeys, bool has_final_sort, + deparse_expr_cxt *context) { ListCell *lcell; int nestlevel; @@ -3139,7 +3183,19 @@ appendOrderByClause(List *pathkeys, deparse_expr_cxt *context) PathKey *pathkey = lfirst(lcell); Expr *em_expr; - em_expr = find_em_expr_for_rel(pathkey->pk_eclass, baserel); + if (has_final_sort) + { + /* + * By construction, context->foreignrel is the input relation to + * the final sort. + */ + em_expr = find_em_expr_for_input_target(context->root, + pathkey->pk_eclass, + context->foreignrel->reltarget); + } + else + em_expr = find_em_expr_for_rel(pathkey->pk_eclass, baserel); + Assert(em_expr != NULL); appendStringInfoString(buf, delim); @@ -3159,6 +3215,33 @@ appendOrderByClause(List *pathkeys, deparse_expr_cxt *context) reset_transmission_modes(nestlevel); } +/* + * Deparse LIMIT/OFFSET clause. + */ +static void +appendLimitClause(deparse_expr_cxt *context) +{ + PlannerInfo *root = context->root; + StringInfo buf = context->buf; + int nestlevel; + + /* Make sure any constants in the exprs are printed portably */ + nestlevel = set_transmission_modes(); + + if (root->parse->limitCount) + { + appendStringInfoString(buf, " LIMIT "); + deparseExpr((Expr *) root->parse->limitCount, context); + } + if (root->parse->limitOffset) + { + appendStringInfoString(buf, " OFFSET "); + deparseExpr((Expr *) root->parse->limitOffset, context); + } + + reset_transmission_modes(nestlevel); +} + /* * appendFunctionName * Deparses function name from given function oid. diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out index e4d9469fdd3..f0c842a6078 100644 --- a/contrib/postgres_fdw/expected/postgres_fdw.out +++ b/contrib/postgres_fdw/expected/postgres_fdw.out @@ -129,13 +129,6 @@ CREATE FOREIGN TABLE ft6 ( c2 int NOT NULL, c3 text ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4'); --- A table with oids. CREATE FOREIGN TABLE doesn't support the --- WITH OIDS option, but ALTER does. -CREATE FOREIGN TABLE ft_pg_type ( - typname name, - typlen smallint -) SERVER loopback OPTIONS (schema_name 'pg_catalog', table_name 'pg_type'); -ALTER TABLE ft_pg_type SET WITH OIDS; -- =================================================================== -- tests for validator -- =================================================================== @@ -158,6 +151,7 @@ ALTER SERVER testserver1 OPTIONS ( keepalives 'value', keepalives_idle 'value', keepalives_interval 'value', + tcp_user_timeout 'value', -- requiressl 'value', sslcompression 'value', sslmode 'value', @@ -185,16 +179,15 @@ ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1'); ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \det+ - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+------------+-----------+--------------------------------------------------+------------- - public | ft1 | loopback | (schema_name 'S 1', table_name 'T 1') | - public | ft2 | loopback | (schema_name 'S 1', table_name 'T 1') | - public | ft4 | loopback | (schema_name 'S 1', table_name 'T 3') | - public | ft5 | loopback | (schema_name 'S 1', table_name 'T 4') | - public | ft6 | loopback2 | (schema_name 'S 1', table_name 'T 4') | - public | ft_pg_type | loopback | (schema_name 'pg_catalog', table_name 'pg_type') | -(6 rows) + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+-----------+---------------------------------------+------------- + public | ft1 | loopback | (schema_name 'S 1', table_name 'T 1') | + public | ft2 | loopback | (schema_name 'S 1', table_name 'T 1') | + public | ft4 | loopback | (schema_name 'S 1', table_name 'T 3') | + public | ft5 | loopback | (schema_name 'S 1', table_name 'T 4') | + public | ft6 | loopback2 | (schema_name 'S 1', table_name 'T 4') | +(5 rows) -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results @@ -244,11 +237,10 @@ ALTER FOREIGN TABLE ft2 OPTIONS (use_remote_estimate 'true'); -- =================================================================== -- single table without alias EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - QUERY PLAN ---------------------------- - Limit - -> Foreign Scan on ft1 -(2 rows) + QUERY PLAN +--------------------- + Foreign Scan on ft1 +(1 row) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -296,14 +288,12 @@ SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; -- whole-row reference EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 Output: t1.*, c3, c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.*, c3, c1 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c3 ASC NULLS LAST, "C 1" ASC NULLS LAST -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c3 ASC NULLS LAST, "C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint +(3 rows) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; t1 @@ -343,14 +333,12 @@ SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; -- with FOR UPDATE/SHARE EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - LockRows + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 101)) FOR UPDATE -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 101)) FOR UPDATE +(3 rows) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -359,14 +347,12 @@ SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; (1 row) EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - LockRows + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 102)) FOR SHARE -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 102)) FOR SHARE +(3 rows) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -679,7 +665,7 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = ANY (ARRAY[c2, 1, ("C 1" + 0)]))) (3 rows) -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- Foreign Scan on public.ft1 t1 @@ -976,6 +962,25 @@ SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; 9 (1 row) +-- ORDER BY can be shipped, though +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: c1, c2, c3, c4, c5, c6, c7, c8 + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Filter: (t1.c1 === t1.c2) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c2 ASC NULLS LAST +(6 rows) + +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+-------+------------------------------+--------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo +(1 row) + -- but let's put them in an extension ... ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int); ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int); @@ -1013,6 +1018,22 @@ SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; 9 (1 row) +-- and both ORDER BY and LIMIT can be shipped +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" OPERATOR(public.===) c2)) ORDER BY c2 ASC NULLS LAST LIMIT 1::bigint +(3 rows) + +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 +----+----+-------+------------------------------+--------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo +(1 row) + -- =================================================================== -- JOIN queries -- =================================================================== @@ -1023,15 +1044,13 @@ ANALYZE ft5; -- join two tables EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c1, t1.c3 - -> Foreign Scan - Output: t1.c1, t2.c1, t1.c3 - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST -(6 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; c1 | c1 @@ -1051,18 +1070,13 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t -- join three tables EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3, t1.c3 - -> Sort - Output: t1.c1, t2.c2, t3.c3, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3, t1.c3 - Relations: ((public.ft1 t1) INNER JOIN (public.ft2 t2)) INNER JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3, r1.c3 FROM (("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) INNER JOIN "S 1"."T 3" r4 ON (((r1."C 1" = r4.c1)))) -(9 rows) + Relations: ((public.ft1 t1) INNER JOIN (public.ft2 t2)) INNER JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3, r1.c3 FROM (("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) INNER JOIN "S 1"."T 3" r4 ON (((r1."C 1" = r4.c1)))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1082,15 +1096,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t -- left outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c1 - -> Foreign Scan - Output: t1.c1, t2.c1 - Relations: (public.ft4 t1) LEFT JOIN (public.ft5 t2) - Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST -(6 rows) + Relations: (public.ft4 t1) LEFT JOIN (public.ft5 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; c1 | c1 @@ -1110,15 +1122,13 @@ SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1. -- left outer join three tables EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1183,15 +1193,13 @@ SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE -- right outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c1 - -> Foreign Scan - Output: t1.c1, t2.c1 - Relations: (public.ft4 t2) LEFT JOIN (public.ft5 t1) - Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r2 LEFT JOIN "S 1"."T 4" r1 ON (((r1.c1 = r2.c1)))) ORDER BY r2.c1 ASC NULLS LAST, r1.c1 ASC NULLS LAST -(6 rows) + Relations: (public.ft4 t2) LEFT JOIN (public.ft5 t1) + Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r2 LEFT JOIN "S 1"."T 4" r1 ON (((r1.c1 = r2.c1)))) ORDER BY r2.c1 ASC NULLS LAST, r1.c1 ASC NULLS LAST LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; c1 | c1 @@ -1211,15 +1219,13 @@ SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2 -- right outer join three tables EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) -(6 rows) + Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1239,15 +1245,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGH -- full outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c1 - -> Foreign Scan - Output: t1.c1, t2.c1 - Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2) - Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST -(6 rows) + Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2) + Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST LIMIT 10::bigint OFFSET 45::bigint +(4 rows) SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; c1 | c1 @@ -1291,15 +1295,13 @@ SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: 1 - -> Foreign Scan - Output: 1 - Relations: (public.ft4) FULL JOIN (public.ft5) - Remote SQL: SELECT NULL FROM ((SELECT NULL FROM "S 1"."T 3" WHERE ((c1 >= 50)) AND ((c1 <= 60))) s4 FULL JOIN (SELECT NULL FROM "S 1"."T 4" WHERE ((c1 >= 50)) AND ((c1 <= 60))) s5 ON (TRUE)) -(6 rows) + Relations: (public.ft4) FULL JOIN (public.ft5) + Remote SQL: SELECT NULL FROM ((SELECT NULL FROM "S 1"."T 3" WHERE ((c1 >= 50)) AND ((c1 <= 60))) s4 FULL JOIN (SELECT NULL FROM "S 1"."T 4" WHERE ((c1 >= 50)) AND ((c1 <= 60))) s5 ON (TRUE)) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; ?column? @@ -1414,15 +1416,13 @@ SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNE -- full outer join + inner join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c1, t3.c1 - -> Foreign Scan - Output: t1.c1, t2.c1, t3.c1 - Relations: ((public.ft4 t1) INNER JOIN (public.ft5 t2)) FULL JOIN (public.ft4 t3) - Remote SQL: SELECT r1.c1, r2.c1, r4.c1 FROM (("S 1"."T 3" r1 INNER JOIN "S 1"."T 4" r2 ON (((r1.c1 = (r2.c1 + 1))) AND ((r1.c1 >= 50)) AND ((r1.c1 <= 60)))) FULL JOIN "S 1"."T 3" r4 ON (((r2.c1 = r4.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST, r4.c1 ASC NULLS LAST -(6 rows) + Relations: ((public.ft4 t1) INNER JOIN (public.ft5 t2)) FULL JOIN (public.ft4 t3) + Remote SQL: SELECT r1.c1, r2.c1, r4.c1 FROM (("S 1"."T 3" r1 INNER JOIN "S 1"."T 4" r2 ON (((r1.c1 = (r2.c1 + 1))) AND ((r1.c1 >= 50)) AND ((r1.c1 <= 60)))) FULL JOIN "S 1"."T 3" r4 ON (((r2.c1 = r4.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST, r4.c1 ASC NULLS LAST LIMIT 10::bigint +(4 rows) SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; c1 | c1 | c1 @@ -1442,15 +1442,13 @@ SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 a -- full outer join three tables EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1470,15 +1468,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL -- full outer join + right outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) -(6 rows) + Relations: ((public.ft4 t3) LEFT JOIN (public.ft2 t2)) LEFT JOIN (public.ft2 t1) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 3" r4 LEFT JOIN "S 1"."T 1" r2 ON (((r2."C 1" = r4.c1)))) LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1498,15 +1494,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT -- right outer join + full outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) FULL JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) FULL JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1526,15 +1520,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL -- full outer join + left outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t1) FULL JOIN (public.ft2 t2)) LEFT JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1554,15 +1546,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT -- left outer join + full outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t1) LEFT JOIN (public.ft2 t2)) FULL JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r1 LEFT JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) FULL JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1582,15 +1572,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL -- right outer join + left outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) LEFT JOIN (public.ft4 t3) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: ((public.ft2 t2) LEFT JOIN (public.ft2 t1)) LEFT JOIN (public.ft4 t3) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM (("S 1"."T 1" r2 LEFT JOIN "S 1"."T 1" r1 ON (((r1."C 1" = r2."C 1")))) LEFT JOIN "S 1"."T 3" r4 ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1610,15 +1598,13 @@ SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT -- left outer join + right outer join EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c2, t3.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t3.c3 - Relations: (public.ft4 t3) LEFT JOIN ((public.ft2 t1) INNER JOIN (public.ft2 t2)) - Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM ("S 1"."T 3" r4 LEFT JOIN ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ON (((r2."C 1" = r4.c1)))) -(6 rows) + Relations: (public.ft4 t3) LEFT JOIN ((public.ft2 t1) INNER JOIN (public.ft2 t2)) + Remote SQL: SELECT r1."C 1", r2.c2, r4.c3 FROM ("S 1"."T 3" r4 LEFT JOIN ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ON (((r2."C 1" = r4.c1)))) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; c1 | c2 | c3 @@ -1669,15 +1655,13 @@ SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 -- full outer join + WHERE clause with shippable extensions set EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE postgres_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: t1.c1, t2.c2, t1.c3 - -> Foreign Scan - Output: t1.c1, t2.c2, t1.c3 - Relations: (public.ft1 t1) FULL JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2.c2, r1.c3 FROM ("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) WHERE ((public.postgres_fdw_abs(r1."C 1") > 0)) -(6 rows) + Relations: (public.ft1 t1) FULL JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2.c2, r1.c3 FROM ("S 1"."T 1" r1 FULL JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) WHERE ((public.postgres_fdw_abs(r1."C 1") > 0)) LIMIT 10::bigint OFFSET 10::bigint +(4 rows) ALTER SERVER loopback OPTIONS (DROP extensions); -- full outer join + WHERE clause with shippable extensions not set @@ -1699,35 +1683,13 @@ ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); -- tests whole-row reference for row marks EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Foreign Scan - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1 - -> Sort - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Sort Key: t1.c3 USING <, t1.c1 - -> Merge Join - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1, t1.c3, t1.* - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE - -> Sort - Output: t2.c1, t2.* - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" -(26 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint FOR UPDATE OF r1 +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; c1 | c1 @@ -1746,35 +1708,13 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Foreign Scan - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1 FOR UPDATE OF r2 - -> Sort - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Sort Key: t1.c3 USING <, t1.c1 - -> Merge Join - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1, t1.c3, t1.* - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE - -> Sort - Output: t2.c1, t2.* - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE -(26 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint FOR UPDATE OF r1 FOR UPDATE OF r2 +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; c1 | c1 @@ -1794,35 +1734,13 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t -- join two tables with FOR SHARE clause EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Foreign Scan - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1 - -> Sort - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Sort Key: t1.c3 USING <, t1.c1 - -> Merge Join - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1, t1.c3, t1.* - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE - -> Sort - Output: t2.c1, t2.* - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" -(26 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint FOR SHARE OF r1 +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; c1 | c1 @@ -1841,35 +1759,13 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Foreign Scan - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1 FOR SHARE OF r2 - -> Sort - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Sort Key: t1.c3 USING <, t1.c1 - -> Merge Join - Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1, t1.c3, t1.* - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE - -> Sort - Output: t2.c1, t2.* - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE -(26 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1", r1.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint FOR SHARE OF r1 FOR SHARE OF r2 +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; c1 | c1 @@ -1888,7 +1784,7 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t -- join in CTE EXPLAIN (VERBOSE, COSTS OFF) -WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- Limit @@ -1905,7 +1801,7 @@ WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 Output: t.c1_1, t.c2_1, t.c1_3 (12 rows) -WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; c1_1 | c2_1 ------+------ 101 | 101 @@ -1923,15 +1819,13 @@ WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 -- ctid with whole-row reference EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 - -> Foreign Scan - Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 - Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) - Remote SQL: SELECT r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END, r1."C 1", r1.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST -(6 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1.ctid, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END, r1."C 1", r1.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")))) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint +(4 rows) -- SEMI JOIN, not pushed down EXPLAIN (VERBOSE, COSTS OFF) @@ -1999,27 +1893,16 @@ SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2 119 (10 rows) --- CROSS JOIN, not pushed down +-- CROSS JOIN can be pushed down EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Nested Loop - Output: t1.c1, t2.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - Remote SQL: SELECT "C 1" FROM "S 1"."T 1" - -> Materialize - Output: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - Remote SQL: SELECT "C 1" FROM "S 1"."T 1" -(15 rows) + Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) + Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) ORDER BY r1."C 1" ASC NULLS LAST, r2."C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 100::bigint +(4 rows) SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; c1 | c1 @@ -2336,74 +2219,84 @@ SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5 -- multi-way join involving multiple merge joins -- (this case used to have EPQ-related planning problems) +CREATE TABLE local_tbl (c1 int NOT NULL, c2 int NOT NULL, c3 text, CONSTRAINT local_tbl_pkey PRIMARY KEY (c1)); +INSERT INTO local_tbl SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; +ANALYZE local_tbl; SET enable_nestloop TO false; SET enable_hashjoin TO false; EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1, ft2, ft4, ft5 WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- LockRows - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, ft1.*, ft2.*, ft4.*, ft5.* - -> Foreign Scan - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, ft1.*, ft2.*, ft4.*, ft5.* - Relations: (((public.ft1) INNER JOIN (public.ft2)) INNER JOIN (public.ft4)) INNER JOIN (public.ft5) - Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8, r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8, r3.c1, r3.c2, r3.c3, r4.c1, r4.c2, r4.c3, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END, CASE WHEN (r3.*)::text IS NOT NULL THEN ROW(r3.c1, r3.c2, r3.c3) END, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4.c1, r4.c2, r4.c3) END FROM ((("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r2."C 1" < 100)) AND ((r1."C 1" < 100)))) INNER JOIN "S 1"."T 3" r3 ON (((r1.c2 = r3.c1)))) INNER JOIN "S 1"."T 4" r4 ON (((r1.c2 = r4.c1)))) FOR UPDATE OF r1 FOR UPDATE OF r2 FOR UPDATE OF r3 FOR UPDATE OF r4 - -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, ft1.*, ft2.*, ft4.*, ft5.* - Merge Cond: (ft1.c2 = ft5.c1) + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.ctid + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.ctid + Inner Unique: true + Merge Cond: (ft1.c2 = local_tbl.c1) + -> Foreign Scan + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.*, ft5.c1, ft5.c2, ft5.c3, ft5.* + Relations: (((public.ft1) INNER JOIN (public.ft2)) INNER JOIN (public.ft4)) INNER JOIN (public.ft5) + Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8, CASE WHEN (r1.*)::text IS NOT NULL THEN ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8) END, r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8, CASE WHEN (r2.*)::text IS NOT NULL THEN ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) END, r3.c1, r3.c2, r3.c3, CASE WHEN (r3.*)::text IS NOT NULL THEN ROW(r3.c1, r3.c2, r3.c3) END, r4.c1, r4.c2, r4.c3, CASE WHEN (r4.*)::text IS NOT NULL THEN ROW(r4.c1, r4.c2, r4.c3) END FROM ((("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (((r1."C 1" = r2."C 1")) AND ((r2."C 1" < 100)) AND ((r1."C 1" < 100)))) INNER JOIN "S 1"."T 3" r3 ON (((r1.c2 = r3.c1)))) INNER JOIN "S 1"."T 4" r4 ON (((r1.c2 = r4.c1)))) ORDER BY r1.c2 ASC NULLS LAST FOR UPDATE OF r1 FOR UPDATE OF r2 FOR UPDATE OF r3 FOR UPDATE OF r4 -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.* - Merge Cond: (ft1.c2 = ft4.c1) - -> Sort - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* - Sort Key: ft1.c2 - -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.*, ft5.c1, ft5.c2, ft5.c3, ft5.* + Merge Cond: (ft1.c2 = ft5.c1) + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.* + Merge Cond: (ft1.c2 = ft4.c1) + -> Sort Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* - Merge Cond: (ft1.c1 = ft2.c1) - -> Sort - Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.* - Sort Key: ft1.c1 - -> Foreign Scan on public.ft1 + Sort Key: ft1.c2 + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* + Merge Cond: (ft1.c1 = ft2.c1) + -> Sort Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100)) FOR UPDATE - -> Materialize - Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* - -> Foreign Scan on public.ft2 + Sort Key: ft1.c1 + -> Foreign Scan on public.ft1 + Output: ft1.c1, ft1.c2, ft1.c3, ft1.c4, ft1.c5, ft1.c6, ft1.c7, ft1.c8, ft1.* + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100)) FOR UPDATE + -> Materialize Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100)) ORDER BY "C 1" ASC NULLS LAST FOR UPDATE - -> Sort - Output: ft4.c1, ft4.c2, ft4.c3, ft4.* - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 + -> Foreign Scan on public.ft2 + Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c7, ft2.c8, ft2.* + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 100)) ORDER BY "C 1" ASC NULLS LAST FOR UPDATE + -> Sort Output: ft4.c1, ft4.c2, ft4.c3, ft4.* - Remote SQL: SELECT c1, c2, c3 FROM "S 1"."T 3" FOR UPDATE - -> Sort - Output: ft5.c1, ft5.c2, ft5.c3, ft5.* - Sort Key: ft5.c1 - -> Foreign Scan on public.ft5 + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3, ft4.* + Remote SQL: SELECT c1, c2, c3 FROM "S 1"."T 3" FOR UPDATE + -> Sort Output: ft5.c1, ft5.c2, ft5.c3, ft5.* - Remote SQL: SELECT c1, c2, c3 FROM "S 1"."T 4" FOR UPDATE -(41 rows) - -SELECT * FROM ft1, ft2, ft4, ft5 WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; - c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+--------+----+----+-------- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 + Sort Key: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.c2, ft5.c3, ft5.* + Remote SQL: SELECT c1, c2, c3 FROM "S 1"."T 4" FOR UPDATE + -> Index Scan using local_tbl_pkey on public.local_tbl + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.ctid +(47 rows) + +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; + c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 (10 rows) RESET enable_nestloop; RESET enable_hashjoin; +DROP TABLE local_tbl; -- check join pushdown in situations where multiple userids are involved CREATE ROLE regress_view_owner SUPERUSER; CREATE USER MAPPING FOR regress_view_owner SERVER loopback; @@ -2452,15 +2345,13 @@ SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1 ALTER VIEW v4 OWNER TO regress_view_owner; EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: ft4.c1, ft5.c2, ft5.c1 - -> Foreign Scan - Output: ft4.c1, ft5.c2, ft5.c1 - Relations: (public.ft4) LEFT JOIN (public.ft5) - Remote SQL: SELECT r6.c1, r9.c2, r9.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r9 ON (((r6.c1 = r9.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r9.c1 ASC NULLS LAST -(6 rows) + Relations: (public.ft4) LEFT JOIN (public.ft5) + Remote SQL: SELECT r6.c1, r9.c2, r9.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r9 ON (((r6.c1 = r9.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r9.c1 ASC NULLS LAST LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; c1 | c2 @@ -2517,15 +2408,13 @@ SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c ALTER VIEW v4 OWNER TO CURRENT_USER; EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: ft4.c1, t2.c2, t2.c1 - -> Foreign Scan - Output: ft4.c1, t2.c2, t2.c1 - Relations: (public.ft4) LEFT JOIN (public.ft5 t2) - Remote SQL: SELECT r6.c1, r2.c2, r2.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r2 ON (((r6.c1 = r2.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST -(6 rows) + Relations: (public.ft4) LEFT JOIN (public.ft5 t2) + Remote SQL: SELECT r6.c1, r2.c2, r2.c1 FROM ("S 1"."T 3" r6 LEFT JOIN "S 1"."T 4" r2 ON (((r6.c1 = r2.c1)))) ORDER BY r6.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST LIMIT 10::bigint OFFSET 10::bigint +(4 rows) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; c1 | c2 @@ -2552,18 +2441,13 @@ DROP ROLE regress_view_owner; -- Simple aggregates explain (verbose, costs off) select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Result + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 - -> Sort - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 - Sort Key: (count(ft1.c6)), (sum(ft1.c1)) - -> Foreign Scan - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT count(c6), sum("C 1"), avg("C 1"), min(c2), max("C 1"), stddev(c2), c2 FROM "S 1"."T 1" WHERE ((c2 < 5)) GROUP BY 7 -(9 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT count(c6), sum("C 1"), avg("C 1"), min(c2), max("C 1"), stddev(c2), c2 FROM "S 1"."T 1" WHERE ((c2 < 5)) GROUP BY 7 ORDER BY count(c6) ASC NULLS LAST, sum("C 1") ASC NULLS LAST +(4 rows) select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; count | sum | avg | min | max | stddev | sum2 @@ -2575,6 +2459,22 @@ select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (ran 100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500 (5 rows) +explain (verbose, costs off) +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT count(c6), sum("C 1"), avg("C 1"), min(c2), max("C 1"), stddev(c2), c2 FROM "S 1"."T 1" WHERE ((c2 < 5)) GROUP BY 7 ORDER BY count(c6) ASC NULLS LAST, sum("C 1") ASC NULLS LAST LIMIT 1::bigint +(4 rows) + +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; + count | sum | avg | min | max | stddev | sum2 +-------+-------+----------------------+-----+-----+--------+------- + 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 +(1 row) + -- Aggregate is not pushed down as aggregation contains random() explain (verbose, costs off) select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1; @@ -2621,16 +2521,13 @@ select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1) -- GROUP BY clause having expressions explain (verbose, costs off) select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; - QUERY PLAN ---------------------------------------------------------------------------------------- - Sort + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: ((c2 / 2)), ((sum(c2) * (c2 / 2))) - Sort Key: ((ft1.c2 / 2)) - -> Foreign Scan - Output: ((c2 / 2)), ((sum(c2) * (c2 / 2))) - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT (c2 / 2), (sum(c2) * (c2 / 2)) FROM "S 1"."T 1" GROUP BY 1 -(7 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT (c2 / 2), (sum(c2) * (c2 / 2)) FROM "S 1"."T 1" GROUP BY 1 ORDER BY (c2 / 2) ASC NULLS LAST +(4 rows) select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; ?column? | ?column? @@ -2645,18 +2542,15 @@ select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; -- Aggregates in subquery are pushed down. explain (verbose, costs off) select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; - QUERY PLAN ---------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------- Aggregate Output: count(ft1.c2), sum(ft1.c2) - -> Sort + -> Foreign Scan Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision)) - Sort Key: ft1.c2, (sum(ft1.c1)) - -> Foreign Scan - Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision)) - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT c2, sum("C 1"), sqrt("C 1") FROM "S 1"."T 1" GROUP BY 1, 3 -(9 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT c2, sum("C 1"), sqrt("C 1") FROM "S 1"."T 1" GROUP BY 1, 3 ORDER BY c2 ASC NULLS LAST, sum("C 1") ASC NULLS LAST +(6 rows) select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; count | sum @@ -2742,16 +2636,13 @@ select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2 -- Also, ORDER BY contains an aggregate function explain (verbose, costs off) select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); - QUERY PLAN ------------------------------------------------------------------------------------------------ - Sort + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: c2, c2, (sum(c1)) - Sort Key: (sum(ft1.c1)) - -> Foreign Scan - Output: c2, c2, (sum(c1)) - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT c2, c2, sum("C 1") FROM "S 1"."T 1" WHERE ((c2 > 6)) GROUP BY 1, 2 -(7 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT c2, c2, sum("C 1") FROM "S 1"."T 1" WHERE ((c2 > 6)) GROUP BY 1, 2 ORDER BY sum("C 1") ASC NULLS LAST +(4 rows) select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); c2 | c2 @@ -2764,16 +2655,13 @@ select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); -- Testing HAVING clause shippability explain (verbose, costs off) select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: c2, (sum(c1)) - Sort Key: ft2.c2 - -> Foreign Scan - Output: c2, (sum(c1)) - Relations: Aggregate on (public.ft2) - Remote SQL: SELECT c2, sum("C 1") FROM "S 1"."T 1" GROUP BY 1 HAVING ((avg("C 1") < 500::numeric)) AND ((sum("C 1") < 49800)) -(7 rows) + Relations: Aggregate on (public.ft2) + Remote SQL: SELECT c2, sum("C 1") FROM "S 1"."T 1" GROUP BY 1 HAVING ((avg("C 1") < 500::numeric)) AND ((sum("C 1") < 49800)) ORDER BY c2 ASC NULLS LAST +(4 rows) select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; c2 | sum @@ -2819,20 +2707,57 @@ select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" (10 rows) +-- Remote aggregate in combination with a local Param (for the output +-- of an initplan) can be trouble, per bug #15781 +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1; + QUERY PLAN +-------------------------------------------------- + Foreign Scan + Output: $0, (sum(ft1.c1)) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT sum("C 1") FROM "S 1"."T 1" + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum +(6 rows) + +select exists(select 1 from pg_enum), sum(c1) from ft1; + exists | sum +--------+-------- + t | 500500 +(1 row) + +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; + QUERY PLAN +--------------------------------------------------- + GroupAggregate + Output: ($0), sum(ft1.c1) + Group Key: $0 + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum + -> Foreign Scan on public.ft1 + Output: $0, ft1.c1 + Remote SQL: SELECT "C 1" FROM "S 1"."T 1" +(8 rows) + +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; + exists | sum +--------+-------- + t | 500500 +(1 row) + -- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates -- ORDER BY within aggregate, same column used to order explain (verbose, costs off) select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: (array_agg(c1 ORDER BY c1)), c2 - Sort Key: (array_agg(ft1.c1 ORDER BY ft1.c1)) - -> Foreign Scan - Output: (array_agg(c1 ORDER BY c1)), c2 - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT array_agg("C 1" ORDER BY "C 1" ASC NULLS LAST), c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) GROUP BY 2 -(7 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT array_agg("C 1" ORDER BY "C 1" ASC NULLS LAST), c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) GROUP BY 2 ORDER BY array_agg("C 1" ORDER BY "C 1" ASC NULLS LAST) ASC NULLS LAST +(4 rows) select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; array_agg @@ -2869,16 +2794,13 @@ select array_agg(c5 order by c1 desc) from ft2 where c2 = 6 and c1 < 50; -- DISTINCT within aggregate explain (verbose, costs off) select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: (array_agg(DISTINCT (t1.c1 % 5))), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5))) - -> Foreign Scan - Output: (array_agg(DISTINCT (t1.c1 % 5))), ((t2.c1 % 3)) - Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) - Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5)), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 -(7 rows) + Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) + Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5)), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 ORDER BY array_agg(DISTINCT (r1.c1 % 5)) ASC NULLS LAST +(4 rows) select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; array_agg @@ -2890,16 +2812,13 @@ select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2 -- DISTINCT combined with ORDER BY within aggregate explain (verbose, costs off) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))) - -> Foreign Scan - Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))), ((t2.c1 % 3)) - Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) - Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) ASC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 -(7 rows) + Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) + Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) ASC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 ORDER BY array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) ASC NULLS LAST) ASC NULLS LAST +(4 rows) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; array_agg @@ -2910,16 +2829,13 @@ select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft explain (verbose, costs off) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)) - -> Foreign Scan - Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)), ((t2.c1 % 3)) - Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) - Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) DESC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 -(7 rows) + Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) + Remote SQL: SELECT array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) DESC NULLS LAST), (r2.c1 % 3) FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 < 20) OR ((r1.c1 IS NULL) AND (r2.c1 < 5)))) GROUP BY 2 ORDER BY array_agg(DISTINCT (r1.c1 % 5) ORDER BY ((r1.c1 % 5)) DESC NULLS LAST) ASC NULLS LAST +(4 rows) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; array_agg @@ -2931,16 +2847,13 @@ select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 -- FILTER within aggregate explain (verbose, costs off) select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2 - Sort Key: (sum(ft1.c1) FILTER (WHERE ((ft1.c1 < 100) AND (ft1.c2 > 5)))) - -> Foreign Scan - Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2 - Relations: Aggregate on (public.ft1) - Remote SQL: SELECT sum("C 1") FILTER (WHERE (("C 1" < 100) AND (c2 > 5))), c2 FROM "S 1"."T 1" GROUP BY 2 -(7 rows) + Relations: Aggregate on (public.ft1) + Remote SQL: SELECT sum("C 1") FILTER (WHERE (("C 1" < 100) AND (c2 > 5))), c2 FROM "S 1"."T 1" GROUP BY 2 ORDER BY sum("C 1") FILTER (WHERE (("C 1" < 100) AND (c2 > 5))) ASC NULLS LAST +(4 rows) select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; sum @@ -3217,6 +3130,8 @@ select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 Remote SQL: SELECT "C 1", c2 FROM "S 1"."T 1" WHERE (("C 1" < 100)) AND ((c2 = 6)) (6 rows) +-- Update local stats on ft2 +ANALYZE ft2; -- Add into extension alter extension postgres_fdw add operator class my_op_class using btree; alter extension postgres_fdw add function my_op_cmp(a int, b int); @@ -3337,16 +3252,13 @@ select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x w -- FULL join with IS NULL check in HAVING explain (verbose, costs off) select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1 - Sort Key: (avg(t1.c1)), (sum(t2.c1)) - -> Foreign Scan - Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1 - Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) - Remote SQL: SELECT avg(r1.c1), sum(r2.c1), r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) GROUP BY 3 HAVING ((((avg(r1.c1) IS NULL) AND (sum(r2.c1) < 10)) OR (sum(r2.c1) IS NULL))) -(7 rows) + Relations: Aggregate on ((public.ft4 t1) FULL JOIN (public.ft5 t2)) + Remote SQL: SELECT avg(r1.c1), sum(r2.c1), r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) GROUP BY 3 HAVING ((((avg(r1.c1) IS NULL) AND (sum(r2.c1) < 10)) OR (sum(r2.c1) IS NULL))) ORDER BY avg(r1.c1) ASC NULLS LAST, sum(r2.c1) ASC NULLS LAST +(4 rows) select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; avg | sum @@ -3427,6 +3339,62 @@ select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum fr (2 rows) reset enable_hashagg; +-- bug #15613: bad plan for foreign table scan with lateral reference +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Nested Loop + Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" + -> Nested Loop + Output: ref_0.c2, ref_0."C 1", ref_1.c3, (ref_0.c2) + -> Index Scan using t1_pkey on "S 1"."T 1" ref_0 + Output: ref_0."C 1", ref_0.c2, ref_0.c3, ref_0.c4, ref_0.c5, ref_0.c6, ref_0.c7, ref_0.c8 + Index Cond: (ref_0."C 1" < 10) + -> Foreign Scan on public.ft1 ref_1 + Output: ref_1.c3, ref_0.c2 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE ((c3 = '00001'::text)) + -> Materialize + Output: ref_3.c3 + -> Foreign Scan on public.ft2 ref_3 + Output: ref_3.c3 + Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE ((c3 = '00001'::text)) +(15 rows) + +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + c2 | c1 | c2 | c3 +----+----+----+------- + 1 | 1 | 1 | 00001 + 2 | 2 | 2 | 00001 + 3 | 3 | 3 | 00001 + 4 | 4 | 4 | 00001 + 5 | 5 | 5 | 00001 + 6 | 6 | 6 | 00001 + 7 | 7 | 7 | 00001 + 8 | 8 | 8 | 00001 + 9 | 9 | 9 | 00001 +(9 rows) + -- Check with placeHolderVars explain (verbose, costs off) select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); @@ -4001,14 +3969,12 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass LIMIT 1; EXPLAIN (VERBOSE, COSTS OFF) SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), c1, c2, c3, c4, c5, c6, c7, c8 - -> Foreign Scan on public.ft1 t1 - Output: (tableoid)::regclass, c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" -(5 rows) + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: (tableoid)::regclass, c1, c2, c3, c4, c5, c6, c7, c8 + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" LIMIT 1::bigint +(3 rows) SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; tableoid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -4033,34 +3999,17 @@ SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; EXPLAIN (VERBOSE, COSTS OFF) SELECT ctid, * FROM ft1 t1 LIMIT 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Limit + QUERY PLAN +----------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8 - -> Foreign Scan on public.ft1 t1 - Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" LIMIT 1::bigint +(3 rows) SELECT ctid, * FROM ft1 t1 LIMIT 1; ctid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 -------+----+----+-------+------------------------------+--------------------------+----+------------+----- - (0,1) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - -EXPLAIN (VERBOSE, COSTS OFF) -SELECT oid, * FROM ft_pg_type WHERE typname = 'int4'; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft_pg_type - Output: oid, typname, typlen - Remote SQL: SELECT typname, typlen, oid FROM pg_catalog.pg_type WHERE ((typname = 'int4'::name)) -(3 rows) - -SELECT oid, * FROM ft_pg_type WHERE typname = 'int4'; - oid | typname | typlen ------+---------+-------- - 23 | int4 | 4 + (0,1) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo (1 row) -- =================================================================== @@ -4087,16 +4036,16 @@ DROP FUNCTION f_test(int); -- =================================================================== ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; SELECT * FROM ft1 WHERE c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" +ERROR: invalid input syntax for type integer: "foo" CONTEXT: column "c8" of foreign table "ft1" SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" +ERROR: invalid input syntax for type integer: "foo" CONTEXT: column "c8" of foreign table "ft1" SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" +ERROR: invalid input syntax for type integer: "foo" CONTEXT: whole-row reference to foreign table "ft1" SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR -ERROR: invalid input syntax for integer: "foo" +ERROR: invalid input syntax for type integer: "foo" CONTEXT: processing expression at position 2 in select list ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; -- =================================================================== @@ -4233,18 +4182,21 @@ explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C"; explain (verbose, costs off) select * from ft3 f, loct3 l where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo'; - QUERY PLAN ---------------------------------------------------------- - Nested Loop + QUERY PLAN +------------------------------------------------------------- + Hash Join Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 - Join Filter: ((f.f3)::text = (l.f3)::text) - -> Index Scan using loct3_f1_key on public.loct3 l - Output: l.f1, l.f2, l.f3 - Index Cond: (l.f1 = 'foo'::text) + Inner Unique: true + Hash Cond: ((f.f3)::text = (l.f3)::text) -> Foreign Scan on public.ft3 f Output: f.f1, f.f2, f.f3 Remote SQL: SELECT f1, f2, f3 FROM public.loct3 -(9 rows) + -> Hash + Output: l.f1, l.f2, l.f3 + -> Index Scan using loct3_f1_key on public.loct3 l + Output: l.f1, l.f2, l.f3 + Index Cond: (l.f1 = 'foo'::text) +(12 rows) -- =================================================================== -- test writable foreign table stuff @@ -4257,12 +4209,10 @@ INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) -> Subquery Scan on "*SELECT*" Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum - -> Limit - Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)) - -> Foreign Scan on public.ft2 ft2_1 - Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3) - Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" -(9 rows) + -> Foreign Scan on public.ft2 ft2_1 + Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3) + Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" LIMIT 20::bigint +(7 rows) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; INSERT INTO ft2 (c1,c2,c3) @@ -5367,49 +5317,49 @@ SELECT c1,c2,c3,c4 FROM ft2 ORDER BY c1; (819 rows) EXPLAIN (verbose, costs off) -INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 - Output: (tableoid)::regclass + Output: (ft2.tableoid)::regclass Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) -> Result - Output: 9999, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum (5 rows) -INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; tableoid ---------- ft2 (1 row) EXPLAIN (verbose, costs off) -UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down +UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down QUERY PLAN ------------------------------------------------------------------------------------ Update on public.ft2 Output: (tableoid)::regclass -> Foreign Update on public.ft2 - Remote SQL: UPDATE "S 1"."T 1" SET c3 = 'bar'::text WHERE (("C 1" = 9999)) + Remote SQL: UPDATE "S 1"."T 1" SET c3 = 'bar'::text WHERE (("C 1" = 1200)) (4 rows) -UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; +UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; tableoid ---------- ft2 (1 row) EXPLAIN (verbose, costs off) -DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down +DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down QUERY PLAN -------------------------------------------------------------------- Delete on public.ft2 Output: (tableoid)::regclass -> Foreign Delete on public.ft2 - Remote SQL: DELETE FROM "S 1"."T 1" WHERE (("C 1" = 9999)) + Remote SQL: DELETE FROM "S 1"."T 1" WHERE (("C 1" = 1200)) (4 rows) -DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; +DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; tableoid ---------- ft2 @@ -6009,14 +5959,12 @@ VACUUM ANALYZE "S 1"."T 1"; -- FIRST behavior here. -- ORDER BY DESC NULLS LAST options EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 Output: c1, c2, c3, c4, c5, c6, c7, c8 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS LAST, "C 1" ASC NULLS LAST -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS LAST, "C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 795::bigint +(3 rows) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -6035,14 +5983,12 @@ SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; -- ORDER BY DESC NULLS FIRST options EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 Output: c1, c2, c3, c4, c5, c6, c7, c8 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS FIRST, "C 1" ASC NULLS LAST -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS FIRST, "C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 15::bigint +(3 rows) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -6061,14 +6007,12 @@ SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; -- ORDER BY ASC NULLS FIRST options EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - Limit + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 Output: c1, c2, c3, c4, c5, c6, c7, c8 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, c4, c5, c6, c7, c8 - Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 ASC NULLS FIRST, "C 1" ASC NULLS LAST -(5 rows) + Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 ASC NULLS FIRST, "C 1" ASC NULLS LAST LIMIT 10::bigint OFFSET 15::bigint +(3 rows) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 @@ -6173,10 +6117,12 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- =================================================================== -- test WITH CHECK OPTION constraints -- =================================================================== +CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; CREATE TABLE base_tbl (a int, b int); ALTER TABLE base_tbl SET (autovacuum_enabled = 'false'); +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); CREATE FOREIGN TABLE foreign_tbl (a int, b int) - SERVER loopback OPTIONS(table_name 'base_tbl'); + SERVER loopback OPTIONS (table_name 'base_tbl'); CREATE VIEW rw_view AS SELECT * FROM foreign_tbl WHERE a < b WITH CHECK OPTION; \d+ rw_view @@ -6192,45 +6138,162 @@ View definition: WHERE foreign_tbl.a < foreign_tbl.b; Options: check_option=cascaded -INSERT INTO rw_view VALUES (0, 10); -- ok -INSERT INTO rw_view VALUES (10, 0); -- should fail +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); + QUERY PLAN +-------------------------------------------------------------------------------- + Insert on public.foreign_tbl + Remote SQL: INSERT INTO public.base_tbl(a, b) VALUES ($1, $2) RETURNING a, b + -> Result + Output: 0, 5 +(4 rows) + +INSERT INTO rw_view VALUES (0, 5); -- should fail ERROR: new row violates check option for view "rw_view" -DETAIL: Failing row contains (10, 0). +DETAIL: Failing row contains (10, 5). EXPLAIN (VERBOSE, COSTS OFF) -UPDATE rw_view SET b = 20 WHERE a = 0; -- not pushed down - QUERY PLAN --------------------------------------------------------------------------------------------------- +INSERT INTO rw_view VALUES (0, 15); + QUERY PLAN +-------------------------------------------------------------------------------- + Insert on public.foreign_tbl + Remote SQL: INSERT INTO public.base_tbl(a, b) VALUES ($1, $2) RETURNING a, b + -> Result + Output: 0, 15 +(4 rows) + +INSERT INTO rw_view VALUES (0, 15); -- ok +SELECT * FROM foreign_tbl; + a | b +----+---- + 10 | 15 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 5; + QUERY PLAN +--------------------------------------------------------------------------------------- Update on public.foreign_tbl - Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 + Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl - Output: foreign_tbl.a, 20, foreign_tbl.ctid - Remote SQL: SELECT a, ctid FROM public.base_tbl WHERE ((a < b)) AND ((a = 0)) FOR UPDATE + Output: foreign_tbl.a, (foreign_tbl.b + 5), foreign_tbl.ctid + Remote SQL: SELECT a, b, ctid FROM public.base_tbl WHERE ((a < b)) FOR UPDATE (5 rows) -UPDATE rw_view SET b = 20 WHERE a = 0; -- ok +UPDATE rw_view SET b = b + 5; -- should fail +ERROR: new row violates check option for view "rw_view" +DETAIL: Failing row contains (20, 20). EXPLAIN (VERBOSE, COSTS OFF) -UPDATE rw_view SET b = -20 WHERE a = 0; -- not pushed down - QUERY PLAN --------------------------------------------------------------------------------------------------- +UPDATE rw_view SET b = b + 15; + QUERY PLAN +--------------------------------------------------------------------------------------- Update on public.foreign_tbl - Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 + Remote SQL: UPDATE public.base_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b -> Foreign Scan on public.foreign_tbl - Output: foreign_tbl.a, '-20'::integer, foreign_tbl.ctid - Remote SQL: SELECT a, ctid FROM public.base_tbl WHERE ((a < b)) AND ((a = 0)) FOR UPDATE + Output: foreign_tbl.a, (foreign_tbl.b + 15), foreign_tbl.ctid + Remote SQL: SELECT a, b, ctid FROM public.base_tbl WHERE ((a < b)) FOR UPDATE (5 rows) -UPDATE rw_view SET b = -20 WHERE a = 0; -- should fail -ERROR: new row violates check option for view "rw_view" -DETAIL: Failing row contains (0, -20). +UPDATE rw_view SET b = b + 15; -- ok SELECT * FROM foreign_tbl; - a | b ----+---- - 0 | 20 + a | b +----+---- + 20 | 30 (1 row) DROP FOREIGN TABLE foreign_tbl CASCADE; NOTICE: drop cascades to view rw_view +DROP TRIGGER row_before_insupd_trigger ON base_tbl; DROP TABLE base_tbl; +-- test WCO for partitions +CREATE TABLE child_tbl (a int, b int); +ALTER TABLE child_tbl SET (autovacuum_enabled = 'false'); +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +CREATE FOREIGN TABLE foreign_tbl (a int, b int) + SERVER loopback OPTIONS (table_name 'child_tbl'); +CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION foreign_tbl FOR VALUES FROM (0) TO (100); +CREATE VIEW rw_view AS SELECT * FROM parent_tbl + WHERE a < b WITH CHECK OPTION; +\d+ rw_view + View "public.rw_view" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+---------+-----------+----------+---------+---------+------------- + a | integer | | | | plain | + b | integer | | | | plain | +View definition: + SELECT parent_tbl.a, + parent_tbl.b + FROM parent_tbl + WHERE parent_tbl.a < parent_tbl.b; +Options: check_option=cascaded + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 5 +(3 rows) + +INSERT INTO rw_view VALUES (0, 5); -- should fail +ERROR: new row violates check option for view "rw_view" +DETAIL: Failing row contains (10, 5). +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 15 +(3 rows) + +INSERT INTO rw_view VALUES (0, 15); -- ok +SELECT * FROM foreign_tbl; + a | b +----+---- + 10 | 15 +(1 row) + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 5; + QUERY PLAN +---------------------------------------------------------------------------------------- + Update on public.parent_tbl + Foreign Update on public.foreign_tbl + Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b + -> Foreign Scan on public.foreign_tbl + Output: foreign_tbl.a, (foreign_tbl.b + 5), foreign_tbl.ctid + Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE +(6 rows) + +UPDATE rw_view SET b = b + 5; -- should fail +ERROR: new row violates check option for view "rw_view" +DETAIL: Failing row contains (20, 20). +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 15; + QUERY PLAN +---------------------------------------------------------------------------------------- + Update on public.parent_tbl + Foreign Update on public.foreign_tbl + Remote SQL: UPDATE public.child_tbl SET b = $2 WHERE ctid = $1 RETURNING a, b + -> Foreign Scan on public.foreign_tbl + Output: foreign_tbl.a, (foreign_tbl.b + 15), foreign_tbl.ctid + Remote SQL: SELECT a, b, ctid FROM public.child_tbl WHERE ((a < b)) FOR UPDATE +(6 rows) + +UPDATE rw_view SET b = b + 15; -- ok +SELECT * FROM foreign_tbl; + a | b +----+---- + 20 | 30 +(1 row) + +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TRIGGER row_before_insupd_trigger ON child_tbl; +DROP TABLE parent_tbl CASCADE; +NOTICE: drop cascades to view rw_view +DROP FUNCTION row_before_insupd_trigfunc; -- =================================================================== -- test serial columns (ie, sequence-based defaults) -- =================================================================== @@ -6266,6 +6329,31 @@ select * from rem1; 11 | bye remote (4 rows) +-- =================================================================== +-- test generated columns +-- =================================================================== +create table gloc1 (a int, b int); +alter table gloc1 set (autovacuum_enabled = 'false'); +create foreign table grem1 ( + a int, + b int generated always as (a * 2) stored) + server loopback options(table_name 'gloc1'); +insert into grem1 (a) values (1), (2); +update grem1 set a = 22 where a = 2; +select * from gloc1; + a | b +----+---- + 1 | 2 + 22 | 44 +(2 rows) + +select * from grem1; + a | b +----+---- + 1 | 2 + 22 | 44 +(2 rows) + -- =================================================================== -- test local triggers -- =================================================================== @@ -6470,6 +6558,25 @@ SELECT * from loc1; 2 | skidoo triggered ! (2 rows) +EXPLAIN (verbose, costs off) +UPDATE rem1 set f1 = 10; -- all columns should be transmitted + QUERY PLAN +----------------------------------------------------------------------- + Update on public.rem1 + Remote SQL: UPDATE public.loc1 SET f1 = $2, f2 = $3 WHERE ctid = $1 + -> Foreign Scan on public.rem1 + Output: 10, f2, ctid, rem1.* + Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE +(5 rows) + +UPDATE rem1 set f1 = 10; +SELECT * from loc1; + f1 | f2 +----+-------------------------------- + 10 | skidoo triggered ! triggered ! + 10 | skidoo triggered ! triggered ! +(2 rows) + DELETE FROM rem1; -- Add a second trigger, to check that the changes are propagated correctly -- from trigger to trigger @@ -6582,7 +6689,7 @@ NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 NOTICE: NEW: (13,"test triggered !") ctid -------- - (0,27) + (0,29) (1 row) -- cleanup @@ -6686,10 +6793,10 @@ BEFORE UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); EXPLAIN (verbose, costs off) UPDATE rem1 set f2 = ''; -- can't be pushed down - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------- Update on public.rem1 - Remote SQL: UPDATE public.loc1 SET f2 = $2 WHERE ctid = $1 + Remote SQL: UPDATE public.loc1 SET f1 = $2, f2 = $3 WHERE ctid = $1 -> Foreign Scan on public.rem1 Output: f1, ''::text, ctid, rem1.* Remote SQL: SELECT f1, f2, ctid FROM public.loc1 FOR UPDATE @@ -6951,9 +7058,9 @@ select * from bar where f1 in (select f1 from foo) for update; QUERY PLAN ---------------------------------------------------------------------------------------------- LockRows - Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid + Output: bar.f1, bar.f2, bar.ctid, foo.ctid, bar.*, bar.tableoid, foo.*, foo.tableoid -> Hash Join - Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid + Output: bar.f1, bar.f2, bar.ctid, foo.ctid, bar.*, bar.tableoid, foo.*, foo.tableoid Inner Unique: true Hash Cond: (bar.f1 = foo.f1) -> Append @@ -6963,15 +7070,15 @@ select * from bar where f1 in (select f1 from foo) for update; Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE -> Hash - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> HashAggregate - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid Group Key: foo.f1 -> Append -> Seq Scan on public.foo - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> Foreign Scan on public.foo2 - Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 + Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 (23 rows) @@ -6989,9 +7096,9 @@ select * from bar where f1 in (select f1 from foo) for share; QUERY PLAN ---------------------------------------------------------------------------------------------- LockRows - Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid + Output: bar.f1, bar.f2, bar.ctid, foo.ctid, bar.*, bar.tableoid, foo.*, foo.tableoid -> Hash Join - Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid + Output: bar.f1, bar.f2, bar.ctid, foo.ctid, bar.*, bar.tableoid, foo.*, foo.tableoid Inner Unique: true Hash Cond: (bar.f1 = foo.f1) -> Append @@ -7001,15 +7108,15 @@ select * from bar where f1 in (select f1 from foo) for share; Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE -> Hash - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> HashAggregate - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid Group Key: foo.f1 -> Append -> Seq Scan on public.foo - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> Foreign Scan on public.foo2 - Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 + Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 (23 rows) @@ -7038,15 +7145,15 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo); -> Seq Scan on public.bar Output: bar.f1, bar.f2, bar.ctid -> Hash - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> HashAggregate - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid Group Key: foo.f1 -> Append -> Seq Scan on public.foo - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> Foreign Scan on public.foo2 - Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 + Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 -> Hash Join Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, foo.ctid, foo.*, foo.tableoid @@ -7056,15 +7163,15 @@ update bar set f2 = f2 + 100 where f1 in (select f1 from foo); Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE -> Hash - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> HashAggregate - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid Group Key: foo.f1 -> Append -> Seq Scan on public.foo - Output: foo.ctid, foo.*, foo.tableoid, foo.f1 + Output: foo.ctid, foo.f1, foo.*, foo.tableoid -> Foreign Scan on public.foo2 - Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 + Output: foo2.ctid, foo2.f1, foo2.*, foo2.tableoid Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 (39 rows) @@ -7316,12 +7423,12 @@ AFTER UPDATE OR DELETE ON bar2 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); explain (verbose, costs off) update bar set f2 = f2 + 100; - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------- Update on public.bar Update on public.bar Foreign Update on public.bar2 - Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 RETURNING f1, f2, f3 + Remote SQL: UPDATE public.loct2 SET f1 = $2, f2 = $3, f3 = $4 WHERE ctid = $1 RETURNING f1, f2, f3 -> Seq Scan on public.bar Output: bar.f1, (bar.f2 + 100), bar.ctid -> Foreign Scan on public.bar2 @@ -7370,6 +7477,81 @@ drop table bar cascade; NOTICE: drop cascades to foreign table bar2 drop table loct1; drop table loct2; +-- Test pushing down UPDATE/DELETE joins to the remote server +create table parent (a int, b text); +create table loct1 (a int, b text); +create table loct2 (a int, b text); +create foreign table remt1 (a int, b text) + server loopback options (table_name 'loct1'); +create foreign table remt2 (a int, b text) + server loopback options (table_name 'loct2'); +alter foreign table remt1 inherit parent; +insert into remt1 values (1, 'foo'); +insert into remt1 values (2, 'bar'); +insert into remt2 values (1, 'foo'); +insert into remt2 values (2, 'bar'); +analyze remt1; +analyze remt2; +explain (verbose, costs off) +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------- + Update on public.parent + Output: parent.a, parent.b, remt2.a, remt2.b + Update on public.parent + Foreign Update on public.remt1 + -> Nested Loop + Output: parent.a, (parent.b || remt2.b), parent.ctid, remt2.*, remt2.a, remt2.b + Join Filter: (parent.a = remt2.a) + -> Seq Scan on public.parent + Output: parent.a, parent.b, parent.ctid + -> Foreign Scan on public.remt2 + Output: remt2.b, remt2.*, remt2.a + Remote SQL: SELECT a, b FROM public.loct2 + -> Foreign Update + Remote SQL: UPDATE public.loct1 r4 SET b = (r4.b || r2.b) FROM public.loct2 r2 WHERE ((r4.a = r2.a)) RETURNING r4.a, r4.b, r2.a, r2.b +(14 rows) + +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; + a | b | a | b +---+--------+---+----- + 1 | foofoo | 1 | foo + 2 | barbar | 2 | bar +(2 rows) + +explain (verbose, costs off) +delete from parent using remt2 where parent.a = remt2.a returning parent; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + Delete on public.parent + Output: parent.* + Delete on public.parent + Foreign Delete on public.remt1 + -> Nested Loop + Output: parent.ctid, remt2.* + Join Filter: (parent.a = remt2.a) + -> Seq Scan on public.parent + Output: parent.ctid, parent.a + -> Foreign Scan on public.remt2 + Output: remt2.*, remt2.a + Remote SQL: SELECT a, b FROM public.loct2 + -> Foreign Delete + Remote SQL: DELETE FROM public.loct1 r4 USING public.loct2 r2 WHERE ((r4.a = r2.a)) RETURNING r4.a, r4.b +(14 rows) + +delete from parent using remt2 where parent.a = remt2.a returning parent; + parent +------------ + (1,foofoo) + (2,barbar) +(2 rows) + +-- cleanup +drop foreign table remt1; +drop foreign table remt2; +drop table loct1; +drop table loct2; +drop table parent; -- =================================================================== -- test tuple routing for foreign-table partitions -- =================================================================== @@ -7454,6 +7636,48 @@ select tableoid::regclass, * FROM itrtest; remp1 | 1 | foo (1 row) +delete from itrtest; +drop index loct1_idx; +-- Test that remote triggers work with insert tuple routing +create function br_insert_trigfunc() returns trigger as $$ +begin + new.b := new.b || ' triggered !'; + return new; +end +$$ language plpgsql; +create trigger loct1_br_insert_trigger before insert on loct1 + for each row execute procedure br_insert_trigfunc(); +create trigger loct2_br_insert_trigger before insert on loct2 + for each row execute procedure br_insert_trigfunc(); +-- The new values are concatenated with ' triggered !' +insert into itrtest values (1, 'foo') returning *; + a | b +---+----------------- + 1 | foo triggered ! +(1 row) + +insert into itrtest values (2, 'qux') returning *; + a | b +---+----------------- + 2 | qux triggered ! +(1 row) + +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; + a | b +---+------------------- + 1 | test1 triggered ! + 2 | test2 triggered ! +(2 rows) + +with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; + a | b +---+------------------- + 1 | test1 triggered ! + 2 | test2 triggered ! +(2 rows) + +drop trigger loct1_br_insert_trigger on loct1; +drop trigger loct2_br_insert_trigger on loct2; drop table itrtest; drop table loct1; drop table loct2; @@ -7518,6 +7742,188 @@ select tableoid::regclass, * FROM locp; -- The executor should not let unexercised FDWs shut down update utrtest set a = 1 where b = 'foo'; +-- Test that remote triggers work with update tuple routing +create trigger loct_br_insert_trigger before insert on loct + for each row execute procedure br_insert_trigfunc(); +delete from utrtest; +insert into utrtest values (2, 'qux'); +-- Check case where the foreign partition is a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 1 or a = 2 returning *; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Update on public.utrtest + Output: remp.a, remp.b + Foreign Update on public.remp + Update on public.locp + -> Foreign Update on public.remp + Remote SQL: UPDATE public.loct SET a = 1 WHERE (((a = 1) OR (a = 2))) RETURNING a, b + -> Seq Scan on public.locp + Output: 1, locp.b, locp.ctid + Filter: ((locp.a = 1) OR (locp.a = 2)) +(9 rows) + +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 1 or a = 2 returning *; + a | b +---+----------------- + 1 | qux triggered ! +(1 row) + +delete from utrtest; +insert into utrtest values (2, 'qux'); +-- Check case where the foreign partition isn't a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 2 returning *; + QUERY PLAN +-------------------------------------- + Update on public.utrtest + Output: locp.a, locp.b + Update on public.locp + -> Seq Scan on public.locp + Output: 1, locp.b, locp.ctid + Filter: (locp.a = 2) +(6 rows) + +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 2 returning *; + a | b +---+----------------- + 1 | qux triggered ! +(1 row) + +drop trigger loct_br_insert_trigger on loct; +-- We can move rows to a foreign partition that has been updated already, +-- but can't move rows to a foreign partition that hasn't been updated yet +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); +-- Test the former case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 returning *; + QUERY PLAN +----------------------------------------------------------------- + Update on public.utrtest + Output: remp.a, remp.b + Foreign Update on public.remp + Update on public.locp + -> Foreign Update on public.remp + Remote SQL: UPDATE public.loct SET a = 1 RETURNING a, b + -> Seq Scan on public.locp + Output: 1, locp.b, locp.ctid +(8 rows) + +update utrtest set a = 1 returning *; + a | b +---+----- + 1 | foo + 1 | qux +(2 rows) + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; + QUERY PLAN +------------------------------------------------------------------------------ + Update on public.utrtest + Output: remp.a, remp.b, "*VALUES*".column1 + Foreign Update on public.remp + Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b + Update on public.locp + -> Hash Join + Output: 1, remp.b, remp.ctid, "*VALUES*".*, "*VALUES*".column1 + Hash Cond: (remp.a = "*VALUES*".column1) + -> Foreign Scan on public.remp + Output: remp.b, remp.ctid, remp.a + Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE + -> Hash + Output: "*VALUES*".*, "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".*, "*VALUES*".column1 + -> Hash Join + Output: 1, locp.b, locp.ctid, "*VALUES*".*, "*VALUES*".column1 + Hash Cond: (locp.a = "*VALUES*".column1) + -> Seq Scan on public.locp + Output: locp.b, locp.ctid, locp.a + -> Hash + Output: "*VALUES*".*, "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".*, "*VALUES*".column1 +(24 rows) + +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; + a | b | x +---+-----+--- + 1 | foo | 1 + 1 | qux | 2 +(2 rows) + +-- Change the definition of utrtest so that the foreign partition get updated +-- after the local partition +delete from utrtest; +alter table utrtest detach partition remp; +drop foreign table remp; +alter table loct drop constraint loct_a_check; +alter table loct add check (a in (3)); +create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); +alter table utrtest attach partition remp for values in (3); +insert into utrtest values (2, 'qux'); +insert into utrtest values (3, 'xyzzy'); +-- Test the latter case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 returning *; + QUERY PLAN +----------------------------------------------------------------- + Update on public.utrtest + Output: locp.a, locp.b + Update on public.locp + Foreign Update on public.remp + -> Seq Scan on public.locp + Output: 3, locp.b, locp.ctid + -> Foreign Update on public.remp + Remote SQL: UPDATE public.loct SET a = 3 RETURNING a, b +(8 rows) + +update utrtest set a = 3 returning *; -- ERROR +ERROR: cannot route tuples into foreign table to be updated "remp" +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; + QUERY PLAN +------------------------------------------------------------------------------ + Update on public.utrtest + Output: locp.a, locp.b, "*VALUES*".column1 + Update on public.locp + Foreign Update on public.remp + Remote SQL: UPDATE public.loct SET a = $2 WHERE ctid = $1 RETURNING a, b + -> Hash Join + Output: 3, locp.b, locp.ctid, "*VALUES*".*, "*VALUES*".column1 + Hash Cond: (locp.a = "*VALUES*".column1) + -> Seq Scan on public.locp + Output: locp.b, locp.ctid, locp.a + -> Hash + Output: "*VALUES*".*, "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".*, "*VALUES*".column1 + -> Hash Join + Output: 3, remp.b, remp.ctid, "*VALUES*".*, "*VALUES*".column1 + Hash Cond: (remp.a = "*VALUES*".column1) + -> Foreign Scan on public.remp + Output: remp.b, remp.ctid, remp.a + Remote SQL: SELECT a, b, ctid FROM public.loct FOR UPDATE + -> Hash + Output: "*VALUES*".*, "*VALUES*".column1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".*, "*VALUES*".column1 +(24 rows) + +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR +ERROR: cannot route tuples into foreign table to be updated "remp" drop table utrtest; drop table loct; -- Test copy tuple routing @@ -7704,6 +8110,22 @@ drop trigger rem2_trig_row_before on rem2; drop trigger rem2_trig_row_after on rem2; drop trigger loc2_trig_row_before_insert on loc2; delete from rem2; +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +commit; +select * from rem3; + f1 | f2 +----+----- + 1 | foo + 2 | bar +(2 rows) + +drop foreign table rem3; +drop table loc3; -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== @@ -7948,7 +8370,7 @@ CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); CREATE SCHEMA import_dest5; BEGIN; DROP TYPE "Colors" CASCADE; -NOTICE: drop cascades to table import_source.t5 column Col +NOTICE: drop cascades to column Col of table import_source.t5 IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) FROM SERVER loopback INTO import_dest5; -- ERROR ERROR: type "public.Colors" does not exist @@ -8047,8 +8469,9 @@ ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; -CREATE FOREIGN TABLE ftprt2_p1 PARTITION OF fprt2 FOR VALUES FROM (0) TO (250) +CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); +ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); ANALYZE fprt2; @@ -8077,17 +8500,16 @@ SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER J 400 | 400 | 0008 (4 rows) --- left outer join + nullable clasue -EXPLAIN (COSTS OFF) +-- left outer join + nullable clause +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; - QUERY PLAN ------------------------------------------------------------------------------------ - Sort - Sort Key: t1.a, ftprt2_p1.b, ftprt2_p1.c - -> Append - -> Foreign Scan - Relations: (public.ftprt1_p1 t1) LEFT JOIN (public.ftprt2_p1 fprt2) -(5 rows) + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan + Output: t1.a, ftprt2_p1.b, ftprt2_p1.c + Relations: (public.ftprt1_p1 t1) LEFT JOIN (public.ftprt2_p1 fprt2) + Remote SQL: SELECT r5.a, r6.b, r6.c FROM (public.fprt1_p1 r5 LEFT JOIN public.fprt2_p1 r6 ON (((r5.a = r6.b)) AND ((r5.b = r6.a)) AND ((r6.a < 10)))) WHERE ((r5.a < 10)) ORDER BY r5.a ASC NULLS LAST, r6.b ASC NULLS LAST, r6.c ASC NULLS LAST +(4 rows) SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; a | b | c @@ -8099,28 +8521,42 @@ SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) 8 | | (5 rows) --- with whole-row reference +-- with whole-row reference; partitionwise join does not apply EXPLAIN (COSTS OFF) -SELECT t1,t2 FROM fprt1 t1 JOIN fprt2 t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a % 25 =0 ORDER BY 1,2; - QUERY PLAN ---------------------------------------------------------------------------------- +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; + QUERY PLAN +-------------------------------------------------------- Sort Sort Key: ((t1.*)::fprt1), ((t2.*)::fprt2) - -> Append - -> Foreign Scan - Relations: (public.ftprt1_p1 t1) INNER JOIN (public.ftprt2_p1 t2) - -> Foreign Scan - Relations: (public.ftprt1_p2 t1) INNER JOIN (public.ftprt2_p2 t2) -(7 rows) + -> Hash Full Join + Hash Cond: (t1.a = t2.b) + -> Append + -> Foreign Scan on ftprt1_p1 t1 + -> Foreign Scan on ftprt1_p2 t1_1 + -> Hash + -> Append + -> Foreign Scan on ftprt2_p1 t2 + -> Foreign Scan on ftprt2_p2 t2_1 +(11 rows) -SELECT t1,t2 FROM fprt1 t1 JOIN fprt2 t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a % 25 =0 ORDER BY 1,2; - t1 | t2 +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; + wr | wr ----------------+---------------- (0,0,0000) | (0,0,0000) + (50,50,0001) | + (100,100,0002) | (150,150,0003) | (150,150,0003) + (200,200,0004) | (250,250,0005) | (250,250,0005) + (300,300,0006) | + (350,350,0007) | (400,400,0008) | (400,400,0008) -(4 rows) + (450,450,0009) | + | (75,75,0001) + | (225,225,0004) + | (325,325,0006) + | (475,475,0009) +(14 rows) -- join with lateral reference EXPLAIN (COSTS OFF) @@ -8145,7 +8581,7 @@ SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t 400 | 400 (4 rows) --- with PHVs, partition-wise join selected but no join pushdown +-- with PHVs, partitionwise join selected but no join pushdown EXPLAIN (COSTS OFF) SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; QUERY PLAN @@ -8184,6 +8620,34 @@ SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE | | 475 | t2_phv (14 rows) +-- test FOR UPDATE; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; + QUERY PLAN +-------------------------------------------------------------- + LockRows + -> Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + -> Foreign Scan on ftprt2_p1 t2 + -> Foreign Scan on ftprt2_p2 t2_1 + -> Hash + -> Append + -> Foreign Scan on ftprt1_p1 t1 + -> Foreign Scan on ftprt1_p2 t1_1 +(12 rows) + +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; + a | b +-----+----- + 0 | 0 + 150 | 150 + 250 | 250 + 400 | 400 +(4 rows) + RESET enable_partitionwise_join; -- =================================================================== -- test partitionwise aggregates diff --git a/contrib/postgres_fdw/option.c b/contrib/postgres_fdw/option.c index 6854f1bd91e..7ea68c3ce3d 100644 --- a/contrib/postgres_fdw/option.c +++ b/contrib/postgres_fdw/option.c @@ -3,7 +3,7 @@ * option.c * FDW option handling for postgres_fdw * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/option.c diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 30e572632ee..82d8140ba25 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -3,7 +3,7 @@ * postgres_fdw.c * Foreign-data wrapper for remote PostgreSQL servers * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/postgres_fdw.c @@ -16,6 +16,7 @@ #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/pg_class.h" #include "commands/defrem.h" #include "commands/explain.h" @@ -25,16 +26,17 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/cost.h" #include "optimizer/clauses.h" +#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" #include "optimizer/tlist.h" #include "parser/parsetree.h" #include "utils/builtins.h" +#include "utils/float.h" #include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -183,6 +185,10 @@ typedef struct PgFdwModifyState /* working memory context */ MemoryContext temp_cxt; /* context for per-tuple temporary data */ + + /* for update row movement if subplan result rel */ + struct PgFdwModifyState *aux_fmstate; /* foreign-insert state, if + * created */ } PgFdwModifyState; /* @@ -244,6 +250,32 @@ typedef struct PgFdwAnalyzeState MemoryContext temp_cxt; /* context for per-tuple temporary data */ } PgFdwAnalyzeState; +/* + * This enum describes what's kept in the fdw_private list for a ForeignPath. + * We store: + * + * 1) Boolean flag showing if the remote query has the final sort + * 2) Boolean flag showing if the remote query has the LIMIT clause + */ +enum FdwPathPrivateIndex +{ + /* has-final-sort flag (as an integer Value node) */ + FdwPathPrivateHasFinalSort, + /* has-limit flag (as an integer Value node) */ + FdwPathPrivateHasLimit +}; + +/* Struct for extra information passed to estimate_path_cost_size() */ +typedef struct +{ + PathTarget *target; + bool has_final_sort; + bool has_limit; + double limit_tuples; + int64 count_est; + int64 offset_est; +} PgFdwPathExtraData; + /* * Identify the attribute where data conversion fails. */ @@ -277,178 +309,199 @@ PG_FUNCTION_INFO_V1(postgres_fdw_handler); * FDW callback routines */ static void postgresGetForeignRelSize(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); + RelOptInfo *baserel, + Oid foreigntableid); static void postgresGetForeignPaths(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); + RelOptInfo *baserel, + Oid foreigntableid); static ForeignScan *postgresGetForeignPlan(PlannerInfo *root, - RelOptInfo *foreignrel, - Oid foreigntableid, - ForeignPath *best_path, - List *tlist, - List *scan_clauses, - Plan *outer_plan); + RelOptInfo *foreignrel, + Oid foreigntableid, + ForeignPath *best_path, + List *tlist, + List *scan_clauses, + Plan *outer_plan); static void postgresBeginForeignScan(ForeignScanState *node, int eflags); static TupleTableSlot *postgresIterateForeignScan(ForeignScanState *node); static void postgresReScanForeignScan(ForeignScanState *node); static void postgresEndForeignScan(ForeignScanState *node); static void postgresAddForeignUpdateTargets(Query *parsetree, - RangeTblEntry *target_rte, - Relation target_relation); + RangeTblEntry *target_rte, + Relation target_relation); static List *postgresPlanForeignModify(PlannerInfo *root, - ModifyTable *plan, - Index resultRelation, - int subplan_index); + ModifyTable *plan, + Index resultRelation, + int subplan_index); static void postgresBeginForeignModify(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo, - List *fdw_private, - int subplan_index, - int eflags); + ResultRelInfo *resultRelInfo, + List *fdw_private, + int subplan_index, + int eflags); static TupleTableSlot *postgresExecForeignInsert(EState *estate, - ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, - TupleTableSlot *planSlot); + ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); static TupleTableSlot *postgresExecForeignUpdate(EState *estate, - ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, - TupleTableSlot *planSlot); + ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); static TupleTableSlot *postgresExecForeignDelete(EState *estate, - ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, - TupleTableSlot *planSlot); + ResultRelInfo *resultRelInfo, + TupleTableSlot *slot, + TupleTableSlot *planSlot); static void postgresEndForeignModify(EState *estate, - ResultRelInfo *resultRelInfo); + ResultRelInfo *resultRelInfo); static void postgresBeginForeignInsert(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo); + ResultRelInfo *resultRelInfo); static void postgresEndForeignInsert(EState *estate, - ResultRelInfo *resultRelInfo); + ResultRelInfo *resultRelInfo); static int postgresIsForeignRelUpdatable(Relation rel); static bool postgresPlanDirectModify(PlannerInfo *root, - ModifyTable *plan, - Index resultRelation, - int subplan_index); + ModifyTable *plan, + Index resultRelation, + int subplan_index); static void postgresBeginDirectModify(ForeignScanState *node, int eflags); static TupleTableSlot *postgresIterateDirectModify(ForeignScanState *node); static void postgresEndDirectModify(ForeignScanState *node); static void postgresExplainForeignScan(ForeignScanState *node, - ExplainState *es); + ExplainState *es); static void postgresExplainForeignModify(ModifyTableState *mtstate, - ResultRelInfo *rinfo, - List *fdw_private, - int subplan_index, - ExplainState *es); + ResultRelInfo *rinfo, + List *fdw_private, + int subplan_index, + ExplainState *es); static void postgresExplainDirectModify(ForeignScanState *node, - ExplainState *es); + ExplainState *es); static bool postgresAnalyzeForeignTable(Relation relation, - AcquireSampleRowsFunc *func, - BlockNumber *totalpages); + AcquireSampleRowsFunc *func, + BlockNumber *totalpages); static List *postgresImportForeignSchema(ImportForeignSchemaStmt *stmt, - Oid serverOid); + Oid serverOid); static void postgresGetForeignJoinPaths(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - JoinType jointype, - JoinPathExtraData *extra); + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra); static bool postgresRecheckForeignScan(ForeignScanState *node, - TupleTableSlot *slot); + TupleTableSlot *slot); static void postgresGetForeignUpperPaths(PlannerInfo *root, - UpperRelationKind stage, - RelOptInfo *input_rel, - RelOptInfo *output_rel, - void *extra); + UpperRelationKind stage, + RelOptInfo *input_rel, + RelOptInfo *output_rel, + void *extra); /* * Helper functions */ static void estimate_path_cost_size(PlannerInfo *root, - RelOptInfo *foreignrel, - List *param_join_conds, - List *pathkeys, - double *p_rows, int *p_width, - Cost *p_startup_cost, Cost *p_total_cost); + RelOptInfo *foreignrel, + List *param_join_conds, + List *pathkeys, + PgFdwPathExtraData *fpextra, + double *p_rows, int *p_width, + Cost *p_startup_cost, Cost *p_total_cost); static void get_remote_estimate(const char *sql, - PGconn *conn, - double *rows, - int *width, - Cost *startup_cost, - Cost *total_cost); + PGconn *conn, + double *rows, + int *width, + Cost *startup_cost, + Cost *total_cost); +static void adjust_foreign_grouping_path_cost(PlannerInfo *root, + List *pathkeys, + double retrieved_rows, + double width, + double limit_tuples, + Cost *p_startup_cost, + Cost *p_run_cost); static bool ec_member_matches_foreign(PlannerInfo *root, RelOptInfo *rel, - EquivalenceClass *ec, EquivalenceMember *em, - void *arg); + EquivalenceClass *ec, EquivalenceMember *em, + void *arg); static void create_cursor(ForeignScanState *node); static void fetch_more_data(ForeignScanState *node); static void close_cursor(PGconn *conn, unsigned int cursor_number); static PgFdwModifyState *create_foreign_modify(EState *estate, - ResultRelInfo *resultRelInfo, - CmdType operation, - Plan *subplan, - char *query, - List *target_attrs, - bool has_returning, - List *retrieved_attrs); + RangeTblEntry *rte, + ResultRelInfo *resultRelInfo, + CmdType operation, + Plan *subplan, + char *query, + List *target_attrs, + bool has_returning, + List *retrieved_attrs); +static TupleTableSlot *execute_foreign_modify(EState *estate, + ResultRelInfo *resultRelInfo, + CmdType operation, + TupleTableSlot *slot, + TupleTableSlot *planSlot); static void prepare_foreign_modify(PgFdwModifyState *fmstate); static const char **convert_prep_stmt_params(PgFdwModifyState *fmstate, - ItemPointer tupleid, - TupleTableSlot *slot); + ItemPointer tupleid, + TupleTableSlot *slot); static void store_returning_result(PgFdwModifyState *fmstate, - TupleTableSlot *slot, PGresult *res); + TupleTableSlot *slot, PGresult *res); static void finish_foreign_modify(PgFdwModifyState *fmstate); static List *build_remote_returning(Index rtindex, Relation rel, - List *returningList); + List *returningList); static void rebuild_fdw_scan_tlist(ForeignScan *fscan, List *tlist); static void execute_dml_stmt(ForeignScanState *node); static TupleTableSlot *get_returning_data(ForeignScanState *node); static void init_returning_filter(PgFdwDirectModifyState *dmstate, - List *fdw_scan_tlist, - Index rtindex); + List *fdw_scan_tlist, + Index rtindex); static TupleTableSlot *apply_returning_filter(PgFdwDirectModifyState *dmstate, - TupleTableSlot *slot, - EState *estate); + TupleTableSlot *slot, + EState *estate); static void prepare_query_params(PlanState *node, - List *fdw_exprs, - int numParams, - FmgrInfo **param_flinfo, - List **param_exprs, - const char ***param_values); + List *fdw_exprs, + int numParams, + FmgrInfo **param_flinfo, + List **param_exprs, + const char ***param_values); static void process_query_params(ExprContext *econtext, - FmgrInfo *param_flinfo, - List *param_exprs, - const char **param_values); -static int postgresAcquireSampleRowsFunc(Relation relation, int elevel, - HeapTuple *rows, int targrows, - double *totalrows, - double *totaldeadrows); + FmgrInfo *param_flinfo, + List *param_exprs, + const char **param_values); +static int postgresAcquireSampleRowsFunc(Relation relation, int elevel, + HeapTuple *rows, int targrows, + double *totalrows, + double *totaldeadrows); static void analyze_row_processor(PGresult *res, int row, - PgFdwAnalyzeState *astate); + PgFdwAnalyzeState *astate); static HeapTuple make_tuple_from_result_row(PGresult *res, - int row, - Relation rel, - AttInMetadata *attinmeta, - List *retrieved_attrs, - ForeignScanState *fsstate, - MemoryContext temp_context); + int row, + Relation rel, + AttInMetadata *attinmeta, + List *retrieved_attrs, + ForeignScanState *fsstate, + MemoryContext temp_context); static void conversion_error_callback(void *arg); static bool foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, - JoinType jointype, RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinPathExtraData *extra); + JoinType jointype, RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinPathExtraData *extra); static bool foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, - Node *havingQual); + Node *havingQual); static List *get_useful_pathkeys_for_relation(PlannerInfo *root, - RelOptInfo *rel); + RelOptInfo *rel); static List *get_useful_ecs_for_relation(PlannerInfo *root, RelOptInfo *rel); static void add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, - Path *epq_path); + Path *epq_path); static void add_foreign_grouping_paths(PlannerInfo *root, - RelOptInfo *input_rel, - RelOptInfo *grouped_rel, - GroupPathExtraData *extra); + RelOptInfo *input_rel, + RelOptInfo *grouped_rel, + GroupPathExtraData *extra); +static void add_foreign_ordered_paths(PlannerInfo *root, + RelOptInfo *input_rel, + RelOptInfo *ordered_rel); +static void add_foreign_final_paths(PlannerInfo *root, + RelOptInfo *input_rel, + RelOptInfo *final_rel, + FinalPathExtraData *extra); static void apply_server_options(PgFdwRelationInfo *fpinfo); static void apply_table_options(PgFdwRelationInfo *fpinfo); static void merge_fdw_options(PgFdwRelationInfo *fpinfo, - const PgFdwRelationInfo *fpinfo_o, - const PgFdwRelationInfo *fpinfo_i); + const PgFdwRelationInfo *fpinfo_o, + const PgFdwRelationInfo *fpinfo_i); /* @@ -608,10 +661,11 @@ postgresGetForeignRelSize(PlannerInfo *root, cost_qual_eval(&fpinfo->local_conds_cost, fpinfo->local_conds, root); /* - * Set cached relation costs to some negative value, so that we can detect - * when they are set to some sensible costs during one (usually the first) - * of the calls to estimate_path_cost_size(). + * Set # of retrieved rows and cached relation costs to some negative + * value, so that we can detect when they are set to some sensible values, + * during one (usually the first) of the calls to estimate_path_cost_size. */ + fpinfo->retrieved_rows = -1; fpinfo->rel_startup_cost = -1; fpinfo->rel_total_cost = -1; @@ -629,7 +683,7 @@ postgresGetForeignRelSize(PlannerInfo *root, * values in fpinfo so we don't need to do it again to generate the * basic foreign path. */ - estimate_path_cost_size(root, baserel, NIL, NIL, + estimate_path_cost_size(root, baserel, NIL, NIL, NULL, &fpinfo->rows, &fpinfo->width, &fpinfo->startup_cost, &fpinfo->total_cost); @@ -660,7 +714,7 @@ postgresGetForeignRelSize(PlannerInfo *root, set_baserel_size_estimates(root, baserel); /* Fill in basically-bogus cost estimates for use later. */ - estimate_path_cost_size(root, baserel, NIL, NIL, + estimate_path_cost_size(root, baserel, NIL, NIL, NULL, &fpinfo->rows, &fpinfo->width, &fpinfo->startup_cost, &fpinfo->total_cost); } @@ -819,6 +873,7 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel) * Pushing the query_pathkeys to the remote server is always worth * considering, because it might let us avoid a local sort. */ + fpinfo->qp_is_pushdown_safe = false; if (root->query_pathkeys) { bool query_pathkeys_ok = true; @@ -849,7 +904,10 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel) } if (query_pathkeys_ok) + { useful_pathkeys_list = list_make1(list_copy(root->query_pathkeys)); + fpinfo->qp_is_pushdown_safe = true; + } } /* @@ -929,6 +987,9 @@ postgresGetForeignPaths(PlannerInfo *root, * baserestrict conditions we were able to send to remote, there might * actually be an indexscan happening there). We already did all the work * to estimate cost and size of this path. + * + * Although this path uses no join clauses, it could still have required + * parameterization due to LATERAL refs in its tlist. */ path = create_foreignscan_path(root, baserel, NULL, /* default pathtarget */ @@ -936,7 +997,7 @@ postgresGetForeignPaths(PlannerInfo *root, fpinfo->startup_cost, fpinfo->total_cost, NIL, /* no pathkeys */ - NULL, /* no outer rel either */ + baserel->lateral_relids, NULL, /* no extra plan */ NIL); /* no fdw_private list */ add_path(baserel, (Path *) path); @@ -1091,7 +1152,7 @@ postgresGetForeignPaths(PlannerInfo *root, /* Get a cost estimate from the remote */ estimate_path_cost_size(root, baserel, - param_info->ppi_clauses, NIL, + param_info->ppi_clauses, NIL, NULL, &rows, &width, &startup_cost, &total_cost); @@ -1138,8 +1199,21 @@ postgresGetForeignPlan(PlannerInfo *root, List *fdw_recheck_quals = NIL; List *retrieved_attrs; StringInfoData sql; + bool has_final_sort = false; + bool has_limit = false; ListCell *lc; + /* + * Get FDW private data created by postgresGetForeignUpperPaths(), if any. + */ + if (best_path->fdw_private) + { + has_final_sort = intVal(list_nth(best_path->fdw_private, + FdwPathPrivateHasFinalSort)); + has_limit = intVal(list_nth(best_path->fdw_private, + FdwPathPrivateHasLimit)); + } + if (IS_SIMPLE_REL(foreignrel)) { /* @@ -1227,11 +1301,9 @@ postgresGetForeignPlan(PlannerInfo *root, /* * Ensure that the outer plan produces a tuple whose descriptor - * matches our scan tuple slot. This is safe because all scans and - * joins support projection, so we never need to insert a Result node. - * Also, remove the local conditions from outer plan's quals, lest - * they will be evaluated twice, once by the local plan and once by - * the scan. + * matches our scan tuple slot. Also, remove the local conditions + * from outer plan's quals, lest they be evaluated twice, once by the + * local plan and once by the scan. */ if (outer_plan) { @@ -1244,23 +1316,42 @@ postgresGetForeignPlan(PlannerInfo *root, */ Assert(!IS_UPPER_REL(foreignrel)); - outer_plan->targetlist = fdw_scan_tlist; - + /* + * First, update the plan's qual list if possible. In some cases + * the quals might be enforced below the topmost plan level, in + * which case we'll fail to remove them; it's not worth working + * harder than this. + */ foreach(lc, local_exprs) { - Join *join_plan = (Join *) outer_plan; Node *qual = lfirst(lc); outer_plan->qual = list_delete(outer_plan->qual, qual); /* * For an inner join the local conditions of foreign scan plan - * can be part of the joinquals as well. + * can be part of the joinquals as well. (They might also be + * in the mergequals or hashquals, but we can't touch those + * without breaking the plan.) */ - if (join_plan->jointype == JOIN_INNER) - join_plan->joinqual = list_delete(join_plan->joinqual, - qual); + if (IsA(outer_plan, NestLoop) || + IsA(outer_plan, MergeJoin) || + IsA(outer_plan, HashJoin)) + { + Join *join_plan = (Join *) outer_plan; + + if (join_plan->jointype == JOIN_INNER) + join_plan->joinqual = list_delete(join_plan->joinqual, + qual); + } } + + /* + * Now fix the subplan's tlist --- this might result in inserting + * a Result node atop the plan tree. + */ + outer_plan = change_plan_targetlist(outer_plan, fdw_scan_tlist, + best_path->path.parallel_safe); } } @@ -1271,7 +1362,8 @@ postgresGetForeignPlan(PlannerInfo *root, initStringInfo(&sql); deparseSelectStmtForRel(&sql, root, foreignrel, fdw_scan_tlist, remote_exprs, best_path->path.pathkeys, - false, &retrieved_attrs, ¶ms_list); + has_final_sort, has_limit, false, + &retrieved_attrs, ¶ms_list); /* Remember remote_exprs for possible use by postgresPlanDirectModify */ fpinfo->final_remote_exprs = remote_exprs; @@ -1343,7 +1435,7 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags) rtindex = fsplan->scan.scanrelid; else rtindex = bms_next_member(fsplan->fs_relids, -1); - rte = rt_fetch(rtindex, estate->es_range_table); + rte = exec_rt_fetch(rtindex, estate); userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); /* Get info about foreign table. */ @@ -1441,10 +1533,9 @@ postgresIterateForeignScan(ForeignScanState *node) /* * Return the next tuple. */ - ExecStoreTuple(fsstate->tuples[fsstate->next_tuple++], - slot, - InvalidBuffer, - false); + ExecStoreHeapTuple(fsstate->tuples[fsstate->next_tuple++], + slot, + false); return slot; } @@ -1581,6 +1672,7 @@ postgresPlanForeignModify(PlannerInfo *root, Relation rel; StringInfoData sql; List *targetAttrs = NIL; + List *withCheckOptionList = NIL; List *returningList = NIL; List *retrieved_attrs = NIL; bool doNothing = false; @@ -1591,16 +1683,23 @@ postgresPlanForeignModify(PlannerInfo *root, * Core code already has some lock on each rel being planned, so we can * use NoLock here. */ - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); /* * In an INSERT, we transmit all columns that are defined in the foreign - * table. In an UPDATE, we transmit only columns that were explicitly - * targets of the UPDATE, so as to avoid unnecessary data transmission. - * (We can't do that for INSERT since we would miss sending default values - * for columns not listed in the source statement.) - */ - if (operation == CMD_INSERT) + * table. In an UPDATE, if there are BEFORE ROW UPDATE triggers on the + * foreign table, we transmit all columns like INSERT; else we transmit + * only columns that were explicitly targets of the UPDATE, so as to avoid + * unnecessary data transmission. (We can't do that for INSERT since we + * would miss sending default values for columns not listed in the source + * statement, and for UPDATE if there are BEFORE ROW UPDATE triggers since + * those triggers might change values for non-target columns, in which + * case we would miss sending changed values for those columns.) + */ + if (operation == CMD_INSERT || + (operation == CMD_UPDATE && + rel->trigdesc && + rel->trigdesc->trig_update_before_row)) { TupleDesc tupdesc = RelationGetDescr(rel); int attnum; @@ -1616,9 +1715,10 @@ postgresPlanForeignModify(PlannerInfo *root, else if (operation == CMD_UPDATE) { int col; + Bitmapset *allUpdatedCols = bms_union(rte->updatedCols, rte->extraUpdatedCols); col = -1; - while ((col = bms_next_member(rte->updatedCols, col)) >= 0) + while ((col = bms_next_member(allUpdatedCols, col)) >= 0) { /* bit numbers are offset by FirstLowInvalidHeapAttributeNumber */ AttrNumber attno = col + FirstLowInvalidHeapAttributeNumber; @@ -1629,6 +1729,13 @@ postgresPlanForeignModify(PlannerInfo *root, } } + /* + * Extract the relevant WITH CHECK OPTION list if any. + */ + if (plan->withCheckOptionLists) + withCheckOptionList = (List *) list_nth(plan->withCheckOptionLists, + subplan_index); + /* * Extract the relevant RETURNING list if any. */ @@ -1653,17 +1760,19 @@ postgresPlanForeignModify(PlannerInfo *root, switch (operation) { case CMD_INSERT: - deparseInsertSql(&sql, root, resultRelation, rel, - targetAttrs, doNothing, returningList, + deparseInsertSql(&sql, rte, resultRelation, rel, + targetAttrs, doNothing, + withCheckOptionList, returningList, &retrieved_attrs); break; case CMD_UPDATE: - deparseUpdateSql(&sql, root, resultRelation, rel, - targetAttrs, returningList, + deparseUpdateSql(&sql, rte, resultRelation, rel, + targetAttrs, + withCheckOptionList, returningList, &retrieved_attrs); break; case CMD_DELETE: - deparseDeleteSql(&sql, root, resultRelation, rel, + deparseDeleteSql(&sql, rte, resultRelation, rel, returningList, &retrieved_attrs); break; @@ -1672,7 +1781,7 @@ postgresPlanForeignModify(PlannerInfo *root, break; } - heap_close(rel, NoLock); + table_close(rel, NoLock); /* * Build the fdw_private list that will be available to the executor. @@ -1700,6 +1809,7 @@ postgresBeginForeignModify(ModifyTableState *mtstate, List *target_attrs; bool has_returning; List *retrieved_attrs; + RangeTblEntry *rte; /* * Do nothing in EXPLAIN (no ANALYZE) case. resultRelInfo->ri_FdwState @@ -1718,8 +1828,13 @@ postgresBeginForeignModify(ModifyTableState *mtstate, retrieved_attrs = (List *) list_nth(fdw_private, FdwModifyPrivateRetrievedAttrs); + /* Find RTE. */ + rte = exec_rt_fetch(resultRelInfo->ri_RangeTableIndex, + mtstate->ps.state); + /* Construct an execution state. */ fmstate = create_foreign_modify(mtstate->ps.state, + rte, resultRelInfo, mtstate->operation, mtstate->mt_plans[subplan_index]->plan, @@ -1742,57 +1857,21 @@ postgresExecForeignInsert(EState *estate, TupleTableSlot *planSlot) { PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; - const char **p_values; - PGresult *res; - int n_rows; - - /* Set up the prepared statement on the remote server, if we didn't yet */ - if (!fmstate->p_name) - prepare_foreign_modify(fmstate); - - /* Convert parameters needed by prepared statement to text form */ - p_values = convert_prep_stmt_params(fmstate, NULL, slot); - - /* - * Execute the prepared statement. - */ - if (!PQsendQueryPrepared(fmstate->conn, - fmstate->p_name, - fmstate->p_nums, - p_values, - NULL, - NULL, - 0)) - pgfdw_report_error(ERROR, NULL, fmstate->conn, false, fmstate->query); + TupleTableSlot *rslot; /* - * Get the result, and check for success. - * - * We don't use a PG_TRY block here, so be careful not to throw error - * without releasing the PGresult. + * If the fmstate has aux_fmstate set, use the aux_fmstate (see + * postgresBeginForeignInsert()) */ - res = pgfdw_get_result(fmstate->conn, fmstate->query); - if (PQresultStatus(res) != - (fmstate->has_returning ? PGRES_TUPLES_OK : PGRES_COMMAND_OK)) - pgfdw_report_error(ERROR, res, fmstate->conn, true, fmstate->query); - - /* Check number of rows affected, and fetch RETURNING tuple if any */ - if (fmstate->has_returning) - { - n_rows = PQntuples(res); - if (n_rows > 0) - store_returning_result(fmstate, slot, res); - } - else - n_rows = atoi(PQcmdTuples(res)); - - /* And clean up */ - PQclear(res); - - MemoryContextReset(fmstate->temp_cxt); + if (fmstate->aux_fmstate) + resultRelInfo->ri_FdwState = fmstate->aux_fmstate; + rslot = execute_foreign_modify(estate, resultRelInfo, CMD_INSERT, + slot, planSlot); + /* Revert that change */ + if (fmstate->aux_fmstate) + resultRelInfo->ri_FdwState = fmstate; - /* Return NULL if nothing was inserted on the remote end */ - return (n_rows > 0) ? slot : NULL; + return rslot; } /* @@ -1805,70 +1884,8 @@ postgresExecForeignUpdate(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; - Datum datum; - bool isNull; - const char **p_values; - PGresult *res; - int n_rows; - - /* Set up the prepared statement on the remote server, if we didn't yet */ - if (!fmstate->p_name) - prepare_foreign_modify(fmstate); - - /* Get the ctid that was passed up as a resjunk column */ - datum = ExecGetJunkAttribute(planSlot, - fmstate->ctidAttno, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "ctid is NULL"); - - /* Convert parameters needed by prepared statement to text form */ - p_values = convert_prep_stmt_params(fmstate, - (ItemPointer) DatumGetPointer(datum), - slot); - - /* - * Execute the prepared statement. - */ - if (!PQsendQueryPrepared(fmstate->conn, - fmstate->p_name, - fmstate->p_nums, - p_values, - NULL, - NULL, - 0)) - pgfdw_report_error(ERROR, NULL, fmstate->conn, false, fmstate->query); - - /* - * Get the result, and check for success. - * - * We don't use a PG_TRY block here, so be careful not to throw error - * without releasing the PGresult. - */ - res = pgfdw_get_result(fmstate->conn, fmstate->query); - if (PQresultStatus(res) != - (fmstate->has_returning ? PGRES_TUPLES_OK : PGRES_COMMAND_OK)) - pgfdw_report_error(ERROR, res, fmstate->conn, true, fmstate->query); - - /* Check number of rows affected, and fetch RETURNING tuple if any */ - if (fmstate->has_returning) - { - n_rows = PQntuples(res); - if (n_rows > 0) - store_returning_result(fmstate, slot, res); - } - else - n_rows = atoi(PQcmdTuples(res)); - - /* And clean up */ - PQclear(res); - - MemoryContextReset(fmstate->temp_cxt); - - /* Return NULL if nothing was updated on the remote end */ - return (n_rows > 0) ? slot : NULL; + return execute_foreign_modify(estate, resultRelInfo, CMD_UPDATE, + slot, planSlot); } /* @@ -1881,70 +1898,8 @@ postgresExecForeignDelete(EState *estate, TupleTableSlot *slot, TupleTableSlot *planSlot) { - PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; - Datum datum; - bool isNull; - const char **p_values; - PGresult *res; - int n_rows; - - /* Set up the prepared statement on the remote server, if we didn't yet */ - if (!fmstate->p_name) - prepare_foreign_modify(fmstate); - - /* Get the ctid that was passed up as a resjunk column */ - datum = ExecGetJunkAttribute(planSlot, - fmstate->ctidAttno, - &isNull); - /* shouldn't ever get a null result... */ - if (isNull) - elog(ERROR, "ctid is NULL"); - - /* Convert parameters needed by prepared statement to text form */ - p_values = convert_prep_stmt_params(fmstate, - (ItemPointer) DatumGetPointer(datum), - NULL); - - /* - * Execute the prepared statement. - */ - if (!PQsendQueryPrepared(fmstate->conn, - fmstate->p_name, - fmstate->p_nums, - p_values, - NULL, - NULL, - 0)) - pgfdw_report_error(ERROR, NULL, fmstate->conn, false, fmstate->query); - - /* - * Get the result, and check for success. - * - * We don't use a PG_TRY block here, so be careful not to throw error - * without releasing the PGresult. - */ - res = pgfdw_get_result(fmstate->conn, fmstate->query); - if (PQresultStatus(res) != - (fmstate->has_returning ? PGRES_TUPLES_OK : PGRES_COMMAND_OK)) - pgfdw_report_error(ERROR, res, fmstate->conn, true, fmstate->query); - - /* Check number of rows affected, and fetch RETURNING tuple if any */ - if (fmstate->has_returning) - { - n_rows = PQntuples(res); - if (n_rows > 0) - store_returning_result(fmstate, slot, res); - } - else - n_rows = atoi(PQcmdTuples(res)); - - /* And clean up */ - PQclear(res); - - MemoryContextReset(fmstate->temp_cxt); - - /* Return NULL if nothing was deleted on the remote end */ - return (n_rows > 0) ? slot : NULL; + return execute_foreign_modify(estate, resultRelInfo, CMD_DELETE, + slot, planSlot); } /* @@ -1974,11 +1929,11 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo) { PgFdwModifyState *fmstate; - Plan *plan = mtstate->ps.plan; + ModifyTable *plan = castNode(ModifyTable, mtstate->ps.plan); + EState *estate = mtstate->ps.state; + Index resultRelation = resultRelInfo->ri_RangeTableIndex; Relation rel = resultRelInfo->ri_RelationDesc; RangeTblEntry *rte; - Query *query; - PlannerInfo *root; TupleDesc tupdesc = RelationGetDescr(rel); int attnum; StringInfoData sql; @@ -1986,19 +1941,23 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, List *retrieved_attrs = NIL; bool doNothing = false; - initStringInfo(&sql); + /* + * If the foreign table we are about to insert routed rows into is also an + * UPDATE subplan result rel that will be updated later, proceeding with + * the INSERT will result in the later UPDATE incorrectly modifying those + * routed rows, so prevent the INSERT --- it would be nice if we could + * handle this case; but for now, throw an error for safety. + */ + if (plan && plan->operation == CMD_UPDATE && + (resultRelInfo->ri_usesFdwDirectModify || + resultRelInfo->ri_FdwState) && + resultRelInfo > mtstate->resultRelInfo + mtstate->mt_whichplan) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot route tuples into foreign table to be updated \"%s\"", + RelationGetRelationName(rel)))); - /* Set up largely-dummy planner state. */ - rte = makeNode(RangeTblEntry); - rte->rtekind = RTE_RELATION; - rte->relid = RelationGetRelid(rel); - rte->relkind = RELKIND_FOREIGN_TABLE; - query = makeNode(Query); - query->commandType = CMD_INSERT; - query->resultRelation = 1; - query->rtable = list_make1(rte); - root = makeNode(PlannerInfo); - root->parse = query; + initStringInfo(&sql); /* We transmit all columns that are defined in the foreign table. */ for (attnum = 1; attnum <= tupdesc->natts; attnum++) @@ -2012,7 +1971,7 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, /* Check if we add the ON CONFLICT clause to the remote query. */ if (plan) { - OnConflictAction onConflictAction = ((ModifyTable *) plan)->onConflictAction; + OnConflictAction onConflictAction = plan->onConflictAction; /* We only support DO NOTHING without an inference specification. */ if (onConflictAction == ONCONFLICT_NOTHING) @@ -2022,12 +1981,42 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, (int) onConflictAction); } + /* + * If the foreign table is a partition, we need to create a new RTE + * describing the foreign table for use by deparseInsertSql and + * create_foreign_modify() below, after first copying the parent's RTE and + * modifying some fields to describe the foreign partition to work on. + * However, if this is invoked by UPDATE, the existing RTE may already + * correspond to this partition if it is one of the UPDATE subplan target + * rels; in that case, we can just use the existing RTE as-is. + */ + rte = exec_rt_fetch(resultRelation, estate); + if (rte->relid != RelationGetRelid(rel)) + { + rte = copyObject(rte); + rte->relid = RelationGetRelid(rel); + rte->relkind = RELKIND_FOREIGN_TABLE; + + /* + * For UPDATE, we must use the RT index of the first subplan target + * rel's RTE, because the core code would have built expressions for + * the partition, such as RETURNING, using that RT index as varno of + * Vars contained in those expressions. + */ + if (plan && plan->operation == CMD_UPDATE && + resultRelation == plan->rootRelation) + resultRelation = mtstate->resultRelInfo[0].ri_RangeTableIndex; + } + /* Construct the SQL command string. */ - deparseInsertSql(&sql, root, 1, rel, targetAttrs, doNothing, - resultRelInfo->ri_returningList, &retrieved_attrs); + deparseInsertSql(&sql, rte, resultRelation, rel, targetAttrs, doNothing, + resultRelInfo->ri_WithCheckOptions, + resultRelInfo->ri_returningList, + &retrieved_attrs); /* Construct an execution state. */ fmstate = create_foreign_modify(mtstate->ps.state, + rte, resultRelInfo, CMD_INSERT, NULL, @@ -2036,7 +2025,19 @@ postgresBeginForeignInsert(ModifyTableState *mtstate, retrieved_attrs != NIL, retrieved_attrs); - resultRelInfo->ri_FdwState = fmstate; + /* + * If the given resultRelInfo already has PgFdwModifyState set, it means + * the foreign table is an UPDATE subplan result rel; in which case, store + * the resulting state into the aux_fmstate of the PgFdwModifyState. + */ + if (resultRelInfo->ri_FdwState) + { + Assert(plan && plan->operation == CMD_UPDATE); + Assert(resultRelInfo->ri_usesFdwDirectModify == false); + ((PgFdwModifyState *) resultRelInfo->ri_FdwState)->aux_fmstate = fmstate; + } + else + resultRelInfo->ri_FdwState = fmstate; } /* @@ -2051,6 +2052,13 @@ postgresEndForeignInsert(EState *estate, Assert(fmstate != NULL); + /* + * If the fmstate has aux_fmstate set, get the aux_fmstate (see + * postgresBeginForeignInsert()) + */ + if (fmstate->aux_fmstate) + fmstate = fmstate->aux_fmstate; + /* Destroy the execution state */ finish_foreign_modify(fmstate); } @@ -2237,7 +2245,7 @@ postgresPlanDirectModify(PlannerInfo *root, * Core code already has some lock on each rel being planned, so we can * use NoLock here. */ - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); /* * Recall the qual clauses that must be evaluated remotely. (These are @@ -2323,7 +2331,7 @@ postgresPlanDirectModify(PlannerInfo *root, rebuild_fdw_scan_tlist(fscan, returningList); } - heap_close(rel, NoLock); + table_close(rel, NoLock); return true; } @@ -2361,7 +2369,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags) * ExecCheckRTEPerms() does. */ rtindex = estate->es_result_relation_info->ri_RangeTableIndex; - rte = rt_fetch(rtindex, estate->es_range_table); + rte = exec_rt_fetch(rtindex, estate); userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); /* Get info about foreign table. */ @@ -2511,10 +2519,6 @@ postgresEndDirectModify(ForeignScanState *node) ReleaseConnection(dmstate->conn); dmstate->conn = NULL; - /* close the target relation. */ - if (dmstate->resultRel) - ExecCloseScanRelation(dmstate->resultRel); - /* MemoryContext will be deleted automatically. */ } @@ -2599,8 +2603,10 @@ postgresExplainDirectModify(ForeignScanState *node, ExplainState *es) * * param_join_conds are the parameterization clauses with outer relations. * pathkeys specify the expected sort order if any for given path being costed. + * fpextra specifies additional post-scan/join-processing steps such as the + * final sort and the LIMIT restriction. * - * The function returns the cost and size estimates in p_row, p_width, + * The function returns the cost and size estimates in p_rows, p_width, * p_startup_cost and p_total_cost variables. */ static void @@ -2608,6 +2614,7 @@ estimate_path_cost_size(PlannerInfo *root, RelOptInfo *foreignrel, List *param_join_conds, List *pathkeys, + PgFdwPathExtraData *fpextra, double *p_rows, int *p_width, Cost *p_startup_cost, Cost *p_total_cost) { @@ -2617,7 +2624,9 @@ estimate_path_cost_size(PlannerInfo *root, int width; Cost startup_cost; Cost total_cost; - Cost cpu_per_tuple; + + /* Make sure the core code has set up the relation's reltarget */ + Assert(foreignrel->reltarget); /* * If the table or the server is configured to use remote estimates, @@ -2658,7 +2667,7 @@ estimate_path_cost_size(PlannerInfo *root, * baserestrictinfo plus any extra join_conds relevant to this * particular path. */ - remote_conds = list_concat(list_copy(remote_param_join_conds), + remote_conds = list_concat(remote_param_join_conds, fpinfo->remote_conds); /* @@ -2669,8 +2678,10 @@ estimate_path_cost_size(PlannerInfo *root, initStringInfo(&sql); appendStringInfoString(&sql, "EXPLAIN "); deparseSelectStmtForRel(&sql, root, foreignrel, fdw_scan_tlist, - remote_conds, pathkeys, false, - &retrieved_attrs, NULL); + remote_conds, pathkeys, + fpextra ? fpextra->has_final_sort : false, + fpextra ? fpextra->has_limit : false, + false, &retrieved_attrs, NULL); /* Get the remote estimate */ conn = GetConnection(fpinfo->user, false); @@ -2696,6 +2707,24 @@ estimate_path_cost_size(PlannerInfo *root, cost_qual_eval(&local_cost, local_param_join_conds, root); startup_cost += local_cost.startup; total_cost += local_cost.per_tuple * retrieved_rows; + + /* + * Add in tlist eval cost for each output row. In case of an + * aggregate, some of the tlist expressions such as grouping + * expressions will be evaluated remotely, so adjust the costs. + */ + startup_cost += foreignrel->reltarget->cost.startup; + total_cost += foreignrel->reltarget->cost.startup; + total_cost += foreignrel->reltarget->cost.per_tuple * rows; + if (IS_UPPER_REL(foreignrel)) + { + QualCost tlist_cost; + + cost_qual_eval(&tlist_cost, fdw_scan_tlist, root); + startup_cost -= tlist_cost.startup; + total_cost -= tlist_cost.startup; + total_cost -= tlist_cost.per_tuple * rows; + } } else { @@ -2708,26 +2737,39 @@ estimate_path_cost_size(PlannerInfo *root, Assert(param_join_conds == NIL); /* - * Use rows/width estimates made by set_baserel_size_estimates() for - * base foreign relations and set_joinrel_size_estimates() for join - * between foreign relations. + * We will come here again and again with different set of pathkeys or + * additional post-scan/join-processing steps that caller wants to + * cost. We don't need to calculate the cost/size estimates for the + * underlying scan, join, or grouping each time. Instead, use those + * estimates if we have cached them already. */ - rows = foreignrel->rows; - width = foreignrel->reltarget->width; - - /* Back into an estimate of the number of retrieved rows. */ - retrieved_rows = clamp_row_est(rows / fpinfo->local_conds_sel); - - /* - * We will come here again and again with different set of pathkeys - * that caller wants to cost. We don't need to calculate the cost of - * bare scan each time. Instead, use the costs if we have cached them - * already. - */ - if (fpinfo->rel_startup_cost > 0 && fpinfo->rel_total_cost > 0) + if (fpinfo->rel_startup_cost >= 0 && fpinfo->rel_total_cost >= 0) { + Assert(fpinfo->retrieved_rows >= 1); + + rows = fpinfo->rows; + retrieved_rows = fpinfo->retrieved_rows; + width = fpinfo->width; startup_cost = fpinfo->rel_startup_cost; run_cost = fpinfo->rel_total_cost - fpinfo->rel_startup_cost; + + /* + * If we estimate the costs of a foreign scan or a foreign join + * with additional post-scan/join-processing steps, the scan or + * join costs obtained from the cache wouldn't yet contain the + * eval costs for the final scan/join target, which would've been + * updated by apply_scanjoin_target_to_paths(); add the eval costs + * now. + */ + if (fpextra && !IS_UPPER_REL(foreignrel)) + { + /* Shouldn't get here unless we have LIMIT */ + Assert(fpextra->has_limit); + Assert(foreignrel->reloptkind == RELOPT_BASEREL || + foreignrel->reloptkind == RELOPT_JOINREL); + startup_cost += foreignrel->reltarget->cost.startup; + run_cost += foreignrel->reltarget->cost.per_tuple * rows; + } } else if (IS_JOIN_REL(foreignrel)) { @@ -2737,6 +2779,10 @@ estimate_path_cost_size(PlannerInfo *root, QualCost remote_conds_cost; double nrows; + /* Use rows/width estimates made by the core code. */ + rows = foreignrel->rows; + width = foreignrel->reltarget->width; + /* For join we expect inner and outer relations set */ Assert(fpinfo->innerrel && fpinfo->outerrel); @@ -2745,7 +2791,12 @@ estimate_path_cost_size(PlannerInfo *root, /* Estimate of number of rows in cross product */ nrows = fpinfo_i->rows * fpinfo_o->rows; - /* Clamp retrieved rows estimate to at most size of cross product */ + + /* + * Back into an estimate of the number of retrieved rows. Just in + * case this is nuts, clamp to at most nrows. + */ + retrieved_rows = clamp_row_est(rows / fpinfo->local_conds_sel); retrieved_rows = Min(retrieved_rows, nrows); /* @@ -2794,18 +2845,24 @@ estimate_path_cost_size(PlannerInfo *root, nrows = clamp_row_est(nrows * fpinfo->joinclause_sel); run_cost += nrows * remote_conds_cost.per_tuple; run_cost += fpinfo->local_conds_cost.per_tuple * retrieved_rows; + + /* Add in tlist eval cost for each output row */ + startup_cost += foreignrel->reltarget->cost.startup; + run_cost += foreignrel->reltarget->cost.per_tuple * rows; } else if (IS_UPPER_REL(foreignrel)) { + RelOptInfo *outerrel = fpinfo->outerrel; PgFdwRelationInfo *ofpinfo; - PathTarget *ptarget = foreignrel->reltarget; AggClauseCosts aggcosts; double input_rows; int numGroupCols; double numGroups = 1; - /* Make sure the core code set the pathtarget. */ - Assert(ptarget != NULL); + /* The upper relation should have its outer relation set */ + Assert(outerrel); + /* and that outer relation should have its reltarget set */ + Assert(outerrel->reltarget); /* * This cost model is mixture of costing done for sorted and @@ -2813,17 +2870,12 @@ estimate_path_cost_size(PlannerInfo *root, * strategy will be considered at remote side, thus for * simplicity, we put all startup related costs in startup_cost * and all finalization and run cost are added in total_cost. - * - * Also, core does not care about costing HAVING expressions and - * adding that to the costs. So similarly, here too we are not - * considering remote and local conditions for costing. */ - ofpinfo = (PgFdwRelationInfo *) fpinfo->outerrel->fdw_private; + ofpinfo = (PgFdwRelationInfo *) outerrel->fdw_private; - /* Get rows and width from input rel */ + /* Get rows from input rel */ input_rows = ofpinfo->rows; - width = ofpinfo->width; /* Collect statistics about aggregates for estimating costs. */ MemSet(&aggcosts, 0, sizeof(AggClauseCosts)); @@ -2849,39 +2901,87 @@ estimate_path_cost_size(PlannerInfo *root, input_rows, NULL); /* - * Number of rows expected from foreign server will be same as - * that of number of groups. + * Get the retrieved_rows and rows estimates. If there are HAVING + * quals, account for their selectivity. */ - rows = retrieved_rows = numGroups; + if (root->parse->havingQual) + { + /* Factor in the selectivity of the remotely-checked quals */ + retrieved_rows = + clamp_row_est(numGroups * + clauselist_selectivity(root, + fpinfo->remote_conds, + 0, + JOIN_INNER, + NULL)); + /* Factor in the selectivity of the locally-checked quals */ + rows = clamp_row_est(retrieved_rows * fpinfo->local_conds_sel); + } + else + { + rows = retrieved_rows = numGroups; + } + + /* Use width estimate made by the core code. */ + width = foreignrel->reltarget->width; /*----- * Startup cost includes: - * 1. Startup cost for underneath input * relation + * 1. Startup cost for underneath input relation, adjusted for + * tlist replacement by apply_scanjoin_target_to_paths() * 2. Cost of performing aggregation, per cost_agg() - * 3. Startup cost for PathTarget eval *----- */ startup_cost = ofpinfo->rel_startup_cost; + startup_cost += outerrel->reltarget->cost.startup; startup_cost += aggcosts.transCost.startup; startup_cost += aggcosts.transCost.per_tuple * input_rows; + startup_cost += aggcosts.finalCost.startup; startup_cost += (cpu_operator_cost * numGroupCols) * input_rows; - startup_cost += ptarget->cost.startup; /*----- * Run time cost includes: - * 1. Run time cost of underneath input relation + * 1. Run time cost of underneath input relation, adjusted for + * tlist replacement by apply_scanjoin_target_to_paths() * 2. Run time cost of performing aggregation, per cost_agg() - * 3. PathTarget eval cost for each output row *----- */ run_cost = ofpinfo->rel_total_cost - ofpinfo->rel_startup_cost; - run_cost += aggcosts.finalCost * numGroups; + run_cost += outerrel->reltarget->cost.per_tuple * input_rows; + run_cost += aggcosts.finalCost.per_tuple * numGroups; run_cost += cpu_tuple_cost * numGroups; - run_cost += ptarget->cost.per_tuple * numGroups; + + /* Account for the eval cost of HAVING quals, if any */ + if (root->parse->havingQual) + { + QualCost remote_cost; + + /* Add in the eval cost of the remotely-checked quals */ + cost_qual_eval(&remote_cost, fpinfo->remote_conds, root); + startup_cost += remote_cost.startup; + run_cost += remote_cost.per_tuple * numGroups; + /* Add in the eval cost of the locally-checked quals */ + startup_cost += fpinfo->local_conds_cost.startup; + run_cost += fpinfo->local_conds_cost.per_tuple * retrieved_rows; + } + + /* Add in tlist eval cost for each output row */ + startup_cost += foreignrel->reltarget->cost.startup; + run_cost += foreignrel->reltarget->cost.per_tuple * rows; } else { - /* Clamp retrieved rows estimates to at most foreignrel->tuples. */ + Cost cpu_per_tuple; + + /* Use rows/width estimates made by set_baserel_size_estimates. */ + rows = foreignrel->rows; + width = foreignrel->reltarget->width; + + /* + * Back into an estimate of the number of retrieved rows. Just in + * case this is nuts, clamp to at most foreignrel->tuples. + */ + retrieved_rows = clamp_row_est(rows / fpinfo->local_conds_sel); retrieved_rows = Min(retrieved_rows, foreignrel->tuples); /* @@ -2896,6 +2996,10 @@ estimate_path_cost_size(PlannerInfo *root, startup_cost += foreignrel->baserestrictcost.startup; cpu_per_tuple = cpu_tuple_cost + foreignrel->baserestrictcost.per_tuple; run_cost += cpu_per_tuple * foreignrel->tuples; + + /* Add in tlist eval cost for each output row */ + startup_cost += foreignrel->reltarget->cost.startup; + run_cost += foreignrel->reltarget->cost.per_tuple * rows; } /* @@ -2909,24 +3013,65 @@ estimate_path_cost_size(PlannerInfo *root, */ if (pathkeys != NIL) { - startup_cost *= DEFAULT_FDW_SORT_MULTIPLIER; - run_cost *= DEFAULT_FDW_SORT_MULTIPLIER; + if (IS_UPPER_REL(foreignrel)) + { + Assert(foreignrel->reloptkind == RELOPT_UPPER_REL && + fpinfo->stage == UPPERREL_GROUP_AGG); + adjust_foreign_grouping_path_cost(root, pathkeys, + retrieved_rows, width, + fpextra->limit_tuples, + &startup_cost, &run_cost); + } + else + { + startup_cost *= DEFAULT_FDW_SORT_MULTIPLIER; + run_cost *= DEFAULT_FDW_SORT_MULTIPLIER; + } } total_cost = startup_cost + run_cost; + + /* Adjust the cost estimates if we have LIMIT */ + if (fpextra && fpextra->has_limit) + { + adjust_limit_rows_costs(&rows, &startup_cost, &total_cost, + fpextra->offset_est, fpextra->count_est); + retrieved_rows = rows; + } + } + + /* + * If this includes the final sort step, the given target, which will be + * applied to the resulting path, might have different expressions from + * the foreignrel's reltarget (see make_sort_input_target()); adjust tlist + * eval costs. + */ + if (fpextra && fpextra->has_final_sort && + fpextra->target != foreignrel->reltarget) + { + QualCost oldcost = foreignrel->reltarget->cost; + QualCost newcost = fpextra->target->cost; + + startup_cost += newcost.startup - oldcost.startup; + total_cost += newcost.startup - oldcost.startup; + total_cost += (newcost.per_tuple - oldcost.per_tuple) * rows; } /* - * Cache the costs for scans without any pathkeys or parameterization - * before adding the costs for transferring data from the foreign server. - * These costs are useful for costing the join between this relation and - * another foreign relation or to calculate the costs of paths with - * pathkeys for this relation, when the costs can not be obtained from the - * foreign server. This function will be called at least once for every - * foreign relation without pathkeys and parameterization. + * Cache the retrieved rows and cost estimates for scans, joins, or + * groupings without any parameterization, pathkeys, or additional + * post-scan/join-processing steps, before adding the costs for + * transferring data from the foreign server. These estimates are useful + * for costing remote joins involving this relation or costing other + * remote operations on this relation such as remote sorts and remote + * LIMIT restrictions, when the costs can not be obtained from the foreign + * server. This function will be called at least once for every foreign + * relation without any parameterization, pathkeys, or additional + * post-scan/join-processing steps. */ - if (pathkeys == NIL && param_join_conds == NIL) + if (pathkeys == NIL && param_join_conds == NIL && fpextra == NULL) { + fpinfo->retrieved_rows = retrieved_rows; fpinfo->rel_startup_cost = startup_cost; fpinfo->rel_total_cost = total_cost; } @@ -2942,6 +3087,30 @@ estimate_path_cost_size(PlannerInfo *root, total_cost += fpinfo->fdw_tuple_cost * retrieved_rows; total_cost += cpu_tuple_cost * retrieved_rows; + /* + * If we have LIMIT, we should prefer performing the restriction remotely + * rather than locally, as the former avoids extra row fetches from the + * remote that the latter might cause. But since the core code doesn't + * account for such fetches when estimating the costs of the local + * restriction (see create_limit_path()), there would be no difference + * between the costs of the local restriction and the costs of the remote + * restriction estimated above if we don't use remote estimates (except + * for the case where the foreignrel is a grouping relation, the given + * pathkeys is not NIL, and the effects of a bounded sort for that rel is + * accounted for in costing the remote restriction). Tweak the costs of + * the remote restriction to ensure we'll prefer it if LIMIT is a useful + * one. + */ + if (!fpinfo->use_remote_estimate && + fpextra && fpextra->has_limit && + fpextra->limit_tuples > 0 && + fpextra->limit_tuples < fpinfo->rows) + { + Assert(fpinfo->rows > 0); + total_cost -= (total_cost - startup_cost) * 0.05 * + (fpinfo->rows - fpextra->limit_tuples) / fpinfo->rows; + } + /* Return results. */ *p_rows = rows; *p_width = width; @@ -3000,6 +3169,59 @@ get_remote_estimate(const char *sql, PGconn *conn, PG_END_TRY(); } +/* + * Adjust the cost estimates of a foreign grouping path to include the cost of + * generating properly-sorted output. + */ +static void +adjust_foreign_grouping_path_cost(PlannerInfo *root, + List *pathkeys, + double retrieved_rows, + double width, + double limit_tuples, + Cost *p_startup_cost, + Cost *p_run_cost) +{ + /* + * If the GROUP BY clause isn't sort-able, the plan chosen by the remote + * side is unlikely to generate properly-sorted output, so it would need + * an explicit sort; adjust the given costs with cost_sort(). Likewise, + * if the GROUP BY clause is sort-able but isn't a superset of the given + * pathkeys, adjust the costs with that function. Otherwise, adjust the + * costs by applying the same heuristic as for the scan or join case. + */ + if (!grouping_is_sortable(root->parse->groupClause) || + !pathkeys_contained_in(pathkeys, root->group_pathkeys)) + { + Path sort_path; /* dummy for result of cost_sort */ + + cost_sort(&sort_path, + root, + pathkeys, + *p_startup_cost + *p_run_cost, + retrieved_rows, + width, + 0.0, + work_mem, + limit_tuples); + + *p_startup_cost = sort_path.startup_cost; + *p_run_cost = sort_path.total_cost - sort_path.startup_cost; + } + else + { + /* + * The default extra cost seems too large for foreign-grouping cases; + * add 1/4th of that default. + */ + double sort_multiplier = 1.0 + (DEFAULT_FDW_SORT_MULTIPLIER + - 1.0) * 0.25; + + *p_startup_cost *= sort_multiplier; + *p_run_cost *= sort_multiplier; + } +} + /* * Detect whether we want to process an EquivalenceClass member. * @@ -3255,6 +3477,7 @@ close_cursor(PGconn *conn, unsigned int cursor_number) */ static PgFdwModifyState * create_foreign_modify(EState *estate, + RangeTblEntry *rte, ResultRelInfo *resultRelInfo, CmdType operation, Plan *subplan, @@ -3266,7 +3489,6 @@ create_foreign_modify(EState *estate, PgFdwModifyState *fmstate; Relation rel = resultRelInfo->ri_RelationDesc; TupleDesc tupdesc = RelationGetDescr(rel); - RangeTblEntry *rte; Oid userid; ForeignTable *table; UserMapping *user; @@ -3283,7 +3505,6 @@ create_foreign_modify(EState *estate, * Identify which user to do the remote access as. This should match what * ExecCheckRTEPerms() does. */ - rte = rt_fetch(resultRelInfo->ri_RangeTableIndex, estate->es_range_table); userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); /* Get info about foreign table. */ @@ -3348,9 +3569,104 @@ create_foreign_modify(EState *estate, Assert(fmstate->p_nums <= n_params); + /* Initialize auxiliary state */ + fmstate->aux_fmstate = NULL; + return fmstate; } +/* + * execute_foreign_modify + * Perform foreign-table modification as required, and fetch RETURNING + * result if any. (This is the shared guts of postgresExecForeignInsert, + * postgresExecForeignUpdate, and postgresExecForeignDelete.) + */ +static TupleTableSlot * +execute_foreign_modify(EState *estate, + ResultRelInfo *resultRelInfo, + CmdType operation, + TupleTableSlot *slot, + TupleTableSlot *planSlot) +{ + PgFdwModifyState *fmstate = (PgFdwModifyState *) resultRelInfo->ri_FdwState; + ItemPointer ctid = NULL; + const char **p_values; + PGresult *res; + int n_rows; + + /* The operation should be INSERT, UPDATE, or DELETE */ + Assert(operation == CMD_INSERT || + operation == CMD_UPDATE || + operation == CMD_DELETE); + + /* Set up the prepared statement on the remote server, if we didn't yet */ + if (!fmstate->p_name) + prepare_foreign_modify(fmstate); + + /* + * For UPDATE/DELETE, get the ctid that was passed up as a resjunk column + */ + if (operation == CMD_UPDATE || operation == CMD_DELETE) + { + Datum datum; + bool isNull; + + datum = ExecGetJunkAttribute(planSlot, + fmstate->ctidAttno, + &isNull); + /* shouldn't ever get a null result... */ + if (isNull) + elog(ERROR, "ctid is NULL"); + ctid = (ItemPointer) DatumGetPointer(datum); + } + + /* Convert parameters needed by prepared statement to text form */ + p_values = convert_prep_stmt_params(fmstate, ctid, slot); + + /* + * Execute the prepared statement. + */ + if (!PQsendQueryPrepared(fmstate->conn, + fmstate->p_name, + fmstate->p_nums, + p_values, + NULL, + NULL, + 0)) + pgfdw_report_error(ERROR, NULL, fmstate->conn, false, fmstate->query); + + /* + * Get the result, and check for success. + * + * We don't use a PG_TRY block here, so be careful not to throw error + * without releasing the PGresult. + */ + res = pgfdw_get_result(fmstate->conn, fmstate->query); + if (PQresultStatus(res) != + (fmstate->has_returning ? PGRES_TUPLES_OK : PGRES_COMMAND_OK)) + pgfdw_report_error(ERROR, res, fmstate->conn, true, fmstate->query); + + /* Check number of rows affected, and fetch RETURNING tuple if any */ + if (fmstate->has_returning) + { + n_rows = PQntuples(res); + if (n_rows > 0) + store_returning_result(fmstate, slot, res); + } + else + n_rows = atoi(PQcmdTuples(res)); + + /* And clean up */ + PQclear(res); + + MemoryContextReset(fmstate->temp_cxt); + + /* + * Return NULL if nothing was inserted/updated/deleted on the remote end + */ + return (n_rows > 0) ? slot : NULL; +} + /* * prepare_foreign_modify * Establish a prepared statement for execution of INSERT/UPDATE/DELETE @@ -3481,8 +3797,12 @@ store_returning_result(PgFdwModifyState *fmstate, fmstate->retrieved_attrs, NULL, fmstate->temp_cxt); - /* tuple will be deleted when it is cleared from the slot */ - ExecStoreTuple(newtup, slot, InvalidBuffer, true); + + /* + * The returning slot will not necessarily be suitable to store + * heaptuples directly, so allow for conversion. + */ + ExecForceStoreHeapTuple(newtup, slot, true); } PG_CATCH(); { @@ -3602,8 +3922,7 @@ build_remote_returning(Index rtindex, Relation rel, List *returningList) if (IsA(var, Var) && var->varno == rtindex && var->varattno <= InvalidAttrNumber && - var->varattno != SelfItemPointerAttributeNumber && - var->varattno != ObjectIdAttributeNumber) + var->varattno != SelfItemPointerAttributeNumber) continue; /* don't need it */ if (tlist_member((Expr *) var, tlist)) @@ -3755,7 +4074,7 @@ get_returning_data(ForeignScanState *node) dmstate->retrieved_attrs, node, dmstate->temp_cxt); - ExecStoreTuple(newtup, slot, InvalidBuffer, false); + ExecStoreHeapTuple(newtup, slot, false); } PG_CATCH(); { @@ -3834,8 +4153,6 @@ init_returning_filter(PgFdwDirectModifyState *dmstate, */ if (attrno == SelfItemPointerAttributeNumber) dmstate->ctidAttno = i; - else if (attrno == ObjectIdAttributeNumber) - dmstate->oidAttno = i; else Assert(false); dmstate->hasSystemCols = true; @@ -3863,6 +4180,7 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate, TupleTableSlot *slot, EState *estate) { + ResultRelInfo *relInfo = estate->es_result_relation_info; TupleDesc resultTupType = RelationGetDescr(dmstate->resultRel); TupleTableSlot *resultSlot; Datum *values; @@ -3872,11 +4190,9 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate, int i; /* - * Use the trigger tuple slot as a place to store the result tuple. + * Use the return tuple slot as a place to store the result tuple. */ - resultSlot = estate->es_trig_tuple_slot; - if (resultSlot->tts_tupleDescriptor != resultTupType) - ExecSetSlotDescriptor(resultSlot, resultTupType); + resultSlot = ExecGetReturningSlot(estate, relInfo); /* * Extract all the values of the scan tuple. @@ -3917,11 +4233,13 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate, ExecStoreVirtualTuple(resultSlot); /* - * If we have any system columns to return, install them. + * If we have any system columns to return, materialize a heap tuple in + * the slot from column values set above and install system columns in + * that tuple. */ if (dmstate->hasSystemCols) { - HeapTuple resultTup = ExecMaterializeSlot(resultSlot); + HeapTuple resultTup = ExecFetchSlotHeapTuple(resultSlot, true, NULL); /* ctid */ if (dmstate->ctidAttno) @@ -3932,15 +4250,6 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate, resultTup->t_self = *ctid; } - /* oid */ - if (dmstate->oidAttno) - { - Oid oid = InvalidOid; - - oid = DatumGetObjectId(old_values[dmstate->oidAttno - 1]); - HeapTupleSetOid(resultTup, oid); - } - /* * And remaining columns * @@ -4181,20 +4490,51 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, /* In what follows, do not risk leaking any PGresults. */ PG_TRY(); { + char fetch_sql[64]; + int fetch_size; + ListCell *lc; + res = pgfdw_exec_query(conn, sql.data); if (PQresultStatus(res) != PGRES_COMMAND_OK) pgfdw_report_error(ERROR, res, conn, false, sql.data); PQclear(res); res = NULL; + /* + * Determine the fetch size. The default is arbitrary, but shouldn't + * be enormous. + */ + fetch_size = 100; + foreach(lc, server->options) + { + DefElem *def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "fetch_size") == 0) + { + fetch_size = strtol(defGetString(def), NULL, 10); + break; + } + } + foreach(lc, table->options) + { + DefElem *def = (DefElem *) lfirst(lc); + + if (strcmp(def->defname, "fetch_size") == 0) + { + fetch_size = strtol(defGetString(def), NULL, 10); + break; + } + } + + /* Construct command to fetch rows from remote. */ + snprintf(fetch_sql, sizeof(fetch_sql), "FETCH %d FROM c%u", + fetch_size, cursor_number); + /* Retrieve and process rows a batch at a time. */ for (;;) { - char fetch_sql[64]; - int fetch_size; int numrows; int i; - ListCell *lc; /* Allow users to cancel long query */ CHECK_FOR_INTERRUPTS(); @@ -4205,33 +4545,7 @@ postgresAcquireSampleRowsFunc(Relation relation, int elevel, * then just adjust rowstoskip and samplerows appropriately. */ - /* The fetch size is arbitrary, but shouldn't be enormous. */ - fetch_size = 100; - foreach(lc, server->options) - { - DefElem *def = (DefElem *) lfirst(lc); - - if (strcmp(def->defname, "fetch_size") == 0) - { - fetch_size = strtol(defGetString(def), NULL, 10); - break; - } - } - foreach(lc, table->options) - { - DefElem *def = (DefElem *) lfirst(lc); - - if (strcmp(def->defname, "fetch_size") == 0) - { - fetch_size = strtol(defGetString(def), NULL, 10); - break; - } - } - /* Fetch some rows */ - snprintf(fetch_sql, sizeof(fetch_sql), "FETCH %d FROM c%u", - fetch_size, cursor_number); - res = pgfdw_exec_query(conn, fetch_sql); /* On error, report the original query, not the FETCH. */ if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -4705,7 +5019,8 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, bool is_remote_clause = is_foreign_expr(root, joinrel, rinfo->clause); - if (IS_OUTER_JOIN(jointype) && !rinfo->is_pushed_down) + if (IS_OUTER_JOIN(jointype) && + !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) { if (!is_remote_clause) return false; @@ -4787,23 +5102,23 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, { case JOIN_INNER: fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - list_copy(fpinfo_i->remote_conds)); + fpinfo_i->remote_conds); fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - list_copy(fpinfo_o->remote_conds)); + fpinfo_o->remote_conds); break; case JOIN_LEFT: fpinfo->joinclauses = list_concat(fpinfo->joinclauses, - list_copy(fpinfo_i->remote_conds)); + fpinfo_i->remote_conds); fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - list_copy(fpinfo_o->remote_conds)); + fpinfo_o->remote_conds); break; case JOIN_RIGHT: fpinfo->joinclauses = list_concat(fpinfo->joinclauses, - list_copy(fpinfo_o->remote_conds)); + fpinfo_o->remote_conds); fpinfo->remote_conds = list_concat(fpinfo->remote_conds, - list_copy(fpinfo_i->remote_conds)); + fpinfo_i->remote_conds); break; case JOIN_FULL: @@ -4864,10 +5179,11 @@ foreign_join_ok(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, fpinfo->user = NULL; /* - * Set cached relation costs to some negative value, so that we can detect - * when they are set to some sensible costs, during one (usually the - * first) of the calls to estimate_path_cost_size(). + * Set # of retrieved rows and cached relation costs to some negative + * value, so that we can detect when they are set to some sensible values, + * during one (usually the first) of the calls to estimate_path_cost_size. */ + fpinfo->retrieved_rows = -1; fpinfo->rel_startup_cost = -1; fpinfo->rel_total_cost = -1; @@ -4913,12 +5229,12 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, List *useful_pathkeys = lfirst(lc); Path *sorted_epq_path; - estimate_path_cost_size(root, rel, NIL, useful_pathkeys, + estimate_path_cost_size(root, rel, NIL, useful_pathkeys, NULL, &rows, &width, &startup_cost, &total_cost); /* - * The EPQ path must be at least as well sorted as the path itself, - * in case it gets used as input to a mergejoin. + * The EPQ path must be at least as well sorted as the path itself, in + * case it gets used as input to a mergejoin. */ sorted_epq_path = epq_path; if (sorted_epq_path != NULL && @@ -4931,16 +5247,28 @@ add_paths_with_pathkeys_for_rel(PlannerInfo *root, RelOptInfo *rel, useful_pathkeys, -1.0); - add_path(rel, (Path *) - create_foreignscan_path(root, rel, - NULL, - rows, - startup_cost, - total_cost, - useful_pathkeys, - NULL, - sorted_epq_path, - NIL)); + if (IS_SIMPLE_REL(rel)) + add_path(rel, (Path *) + create_foreignscan_path(root, rel, + NULL, + rows, + startup_cost, + total_cost, + useful_pathkeys, + rel->lateral_relids, + sorted_epq_path, + NIL)); + else + add_path(rel, (Path *) + create_foreign_join_path(root, rel, + NULL, + rows, + startup_cost, + total_cost, + useful_pathkeys, + rel->lateral_relids, + sorted_epq_path, + NIL)); } } @@ -5075,6 +5403,13 @@ postgresGetForeignJoinPaths(PlannerInfo *root, if (joinrel->fdw_private) return; + /* + * This code does not work for joins with lateral references, since those + * must have parameterized paths, which we don't generate yet. + */ + if (!bms_is_empty(joinrel->lateral_relids)) + return; + /* * Create unfinished PgFdwRelationInfo entry which is used to indicate * that the join relation is already considered, so that we won't waste @@ -5145,8 +5480,8 @@ postgresGetForeignJoinPaths(PlannerInfo *root, extra->sjinfo); /* Estimate costs for bare join relation */ - estimate_path_cost_size(root, joinrel, NIL, NIL, &rows, - &width, &startup_cost, &total_cost); + estimate_path_cost_size(root, joinrel, NIL, NIL, NULL, + &rows, &width, &startup_cost, &total_cost); /* Now update this information in the joinrel */ joinrel->rows = rows; joinrel->reltarget->width = width; @@ -5159,16 +5494,16 @@ postgresGetForeignJoinPaths(PlannerInfo *root, * Create a new join path and add it to the joinrel which represents a * join between foreign tables. */ - joinpath = create_foreignscan_path(root, - joinrel, - NULL, /* default pathtarget */ - rows, - startup_cost, - total_cost, - NIL, /* no pathkeys */ - NULL, /* no required_outer */ - epq_path, - NIL); /* no fdw_private */ + joinpath = create_foreign_join_path(root, + joinrel, + NULL, /* default pathtarget */ + rows, + startup_cost, + total_cost, + NIL, /* no pathkeys */ + joinrel->lateral_relids, + epq_path, + NIL); /* no fdw_private */ /* Add generated path into joinrel by add_path(). */ add_path(joinrel, (Path *) joinpath); @@ -5192,7 +5527,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) grouped_rel->fdw_private; PathTarget *grouping_target = grouped_rel->reltarget; PgFdwRelationInfo *ofpinfo; - List *aggvars; ListCell *lc; int i; List *tlist = NIL; @@ -5218,6 +5552,15 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, * server. All GROUP BY expressions will be part of the grouping target * and thus there is no need to search for them separately. Add grouping * expressions into target list which will be passed to foreign server. + * + * A tricky fine point is that we must not put any expression into the + * target list that is just a foreign param (that is, something that + * deparse.c would conclude has to be sent to the foreign server). If we + * do, the expression will also appear in the fdw_exprs list of the plan + * node, and setrefs.c will get confused and decide that the fdw_exprs + * entry is actually a reference to the fdw_scan_tlist entry, resulting in + * a broken plan. Somewhat oddly, it's OK if the expression contains such + * a node, as long as it's not at top level; then no match is possible. */ i = 0; foreach(lc, grouping_target->exprs) @@ -5238,6 +5581,13 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, if (!is_foreign_expr(root, grouped_rel, expr)) return false; + /* + * If it would be a foreign param, we can't put it into the tlist, + * so we have to fail. + */ + if (is_foreign_param(root, grouped_rel, expr)) + return false; + /* * Pushable, so add to tlist. We need to create a TLE for this * expression and apply the sortgroupref to it. We cannot use @@ -5253,9 +5603,11 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, else { /* - * Non-grouping expression we need to compute. Is it shippable? + * Non-grouping expression we need to compute. Can we ship it + * as-is to the foreign server? */ - if (is_foreign_expr(root, grouped_rel, expr)) + if (is_foreign_expr(root, grouped_rel, expr) && + !is_foreign_param(root, grouped_rel, expr)) { /* Yes, so add to tlist as-is; OK to suppress duplicates */ tlist = add_to_flat_tlist(tlist, list_make1(expr)); @@ -5263,12 +5615,16 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, else { /* Not pushable as a whole; extract its Vars and aggregates */ + List *aggvars; + aggvars = pull_var_clause((Node *) expr, PVC_INCLUDE_AGGREGATES); /* * If any aggregate expression is not shippable, then we - * cannot push down aggregation to the foreign server. + * cannot push down aggregation to the foreign server. (We + * don't have to check is_foreign_param, since that certainly + * won't return true for any such expression.) */ if (!is_foreign_expr(root, grouped_rel, (Expr *) aggvars)) return false; @@ -5355,7 +5711,8 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, * If aggregates within local conditions are not safe to push * down, then we cannot push down the query. Vars are already * part of GROUP BY clause which are checked above, so no need to - * access them again here. + * access them again here. Again, we need not check + * is_foreign_param for a foreign aggregate. */ if (IsA(expr, Aggref)) { @@ -5374,10 +5731,11 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, fpinfo->pushdown_safe = true; /* - * Set cached relation costs to some negative value, so that we can detect - * when they are set to some sensible costs, during one (usually the - * first) of the calls to estimate_path_cost_size(). + * Set # of retrieved rows and cached relation costs to some negative + * value, so that we can detect when they are set to some sensible values, + * during one (usually the first) of the calls to estimate_path_cost_size. */ + fpinfo->retrieved_rows = -1; fpinfo->rel_startup_cost = -1; fpinfo->rel_total_cost = -1; @@ -5396,8 +5754,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel, * postgresGetForeignUpperPaths * Add paths for post-join operations like aggregation, grouping etc. if * corresponding operations are safe to push down. - * - * Right now, we only support aggregate, grouping and having clause pushdown. */ static void postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage, @@ -5415,15 +5771,34 @@ postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage, return; /* Ignore stages we don't support; and skip any duplicate calls. */ - if (stage != UPPERREL_GROUP_AGG || output_rel->fdw_private) + if ((stage != UPPERREL_GROUP_AGG && + stage != UPPERREL_ORDERED && + stage != UPPERREL_FINAL) || + output_rel->fdw_private) return; fpinfo = (PgFdwRelationInfo *) palloc0(sizeof(PgFdwRelationInfo)); fpinfo->pushdown_safe = false; + fpinfo->stage = stage; output_rel->fdw_private = fpinfo; - add_foreign_grouping_paths(root, input_rel, output_rel, - (GroupPathExtraData *) extra); + switch (stage) + { + case UPPERREL_GROUP_AGG: + add_foreign_grouping_paths(root, input_rel, output_rel, + (GroupPathExtraData *) extra); + break; + case UPPERREL_ORDERED: + add_foreign_ordered_paths(root, input_rel, output_rel); + break; + case UPPERREL_FINAL: + add_foreign_final_paths(root, input_rel, output_rel, + (FinalPathExtraData *) extra); + break; + default: + elog(ERROR, "unexpected upper relation: %d", (int) stage); + break; + } } /* @@ -5476,9 +5851,25 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, if (!foreign_grouping_ok(root, grouped_rel, extra->havingQual)) return; + /* + * Compute the selectivity and cost of the local_conds, so we don't have + * to do it over again for each path. (Currently we create just a single + * path here, but in future it would be possible that we build more paths + * such as pre-sorted paths as in postgresGetForeignPaths and + * postgresGetForeignJoinPaths.) The best we can do for these conditions + * is to estimate selectivity on the basis of local statistics. + */ + fpinfo->local_conds_sel = clauselist_selectivity(root, + fpinfo->local_conds, + 0, + JOIN_INNER, + NULL); + + cost_qual_eval(&fpinfo->local_conds_cost, fpinfo->local_conds, root); + /* Estimate the cost of push down */ - estimate_path_cost_size(root, grouped_rel, NIL, NIL, &rows, - &width, &startup_cost, &total_cost); + estimate_path_cost_size(root, grouped_rel, NIL, NIL, NULL, + &rows, &width, &startup_cost, &total_cost); /* Now update this information in the fpinfo */ fpinfo->rows = rows; @@ -5487,21 +5878,382 @@ add_foreign_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, fpinfo->total_cost = total_cost; /* Create and add foreign path to the grouping relation. */ - grouppath = create_foreignscan_path(root, - grouped_rel, - grouped_rel->reltarget, - rows, - startup_cost, - total_cost, - NIL, /* no pathkeys */ - NULL, /* no required_outer */ - NULL, - NIL); /* no fdw_private */ + grouppath = create_foreign_upper_path(root, + grouped_rel, + grouped_rel->reltarget, + rows, + startup_cost, + total_cost, + NIL, /* no pathkeys */ + NULL, + NIL); /* no fdw_private */ /* Add generated path into grouped_rel by add_path(). */ add_path(grouped_rel, (Path *) grouppath); } +/* + * add_foreign_ordered_paths + * Add foreign paths for performing the final sort remotely. + * + * Given input_rel contains the source-data Paths. The paths are added to the + * given ordered_rel. + */ +static void +add_foreign_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel, + RelOptInfo *ordered_rel) +{ + Query *parse = root->parse; + PgFdwRelationInfo *ifpinfo = input_rel->fdw_private; + PgFdwRelationInfo *fpinfo = ordered_rel->fdw_private; + PgFdwPathExtraData *fpextra; + double rows; + int width; + Cost startup_cost; + Cost total_cost; + List *fdw_private; + ForeignPath *ordered_path; + ListCell *lc; + + /* Shouldn't get here unless the query has ORDER BY */ + Assert(parse->sortClause); + + /* We don't support cases where there are any SRFs in the targetlist */ + if (parse->hasTargetSRFs) + return; + + /* Save the input_rel as outerrel in fpinfo */ + fpinfo->outerrel = input_rel; + + /* + * Copy foreign table, foreign server, user mapping, FDW options etc. + * details from the input relation's fpinfo. + */ + fpinfo->table = ifpinfo->table; + fpinfo->server = ifpinfo->server; + fpinfo->user = ifpinfo->user; + merge_fdw_options(fpinfo, ifpinfo, NULL); + + /* + * If the input_rel is a base or join relation, we would already have + * considered pushing down the final sort to the remote server when + * creating pre-sorted foreign paths for that relation, because the + * query_pathkeys is set to the root->sort_pathkeys in that case (see + * standard_qp_callback()). + */ + if (input_rel->reloptkind == RELOPT_BASEREL || + input_rel->reloptkind == RELOPT_JOINREL) + { + Assert(root->query_pathkeys == root->sort_pathkeys); + + /* Safe to push down if the query_pathkeys is safe to push down */ + fpinfo->pushdown_safe = ifpinfo->qp_is_pushdown_safe; + + return; + } + + /* The input_rel should be a grouping relation */ + Assert(input_rel->reloptkind == RELOPT_UPPER_REL && + ifpinfo->stage == UPPERREL_GROUP_AGG); + + /* + * We try to create a path below by extending a simple foreign path for + * the underlying grouping relation to perform the final sort remotely, + * which is stored into the fdw_private list of the resulting path. + */ + + /* Assess if it is safe to push down the final sort */ + foreach(lc, root->sort_pathkeys) + { + PathKey *pathkey = (PathKey *) lfirst(lc); + EquivalenceClass *pathkey_ec = pathkey->pk_eclass; + Expr *sort_expr; + + /* + * is_foreign_expr would detect volatile expressions as well, but + * checking ec_has_volatile here saves some cycles. + */ + if (pathkey_ec->ec_has_volatile) + return; + + /* Get the sort expression for the pathkey_ec */ + sort_expr = find_em_expr_for_input_target(root, + pathkey_ec, + input_rel->reltarget); + + /* If it's unsafe to remote, we cannot push down the final sort */ + if (!is_foreign_expr(root, input_rel, sort_expr)) + return; + } + + /* Safe to push down */ + fpinfo->pushdown_safe = true; + + /* Construct PgFdwPathExtraData */ + fpextra = (PgFdwPathExtraData *) palloc0(sizeof(PgFdwPathExtraData)); + fpextra->target = root->upper_targets[UPPERREL_ORDERED]; + fpextra->has_final_sort = true; + + /* Estimate the costs of performing the final sort remotely */ + estimate_path_cost_size(root, input_rel, NIL, root->sort_pathkeys, fpextra, + &rows, &width, &startup_cost, &total_cost); + + /* + * Build the fdw_private list that will be used by postgresGetForeignPlan. + * Items in the list must match order in enum FdwPathPrivateIndex. + */ + fdw_private = list_make2(makeInteger(true), makeInteger(false)); + + /* Create foreign ordering path */ + ordered_path = create_foreign_upper_path(root, + input_rel, + root->upper_targets[UPPERREL_ORDERED], + rows, + startup_cost, + total_cost, + root->sort_pathkeys, + NULL, /* no extra plan */ + fdw_private); + + /* and add it to the ordered_rel */ + add_path(ordered_rel, (Path *) ordered_path); +} + +/* + * add_foreign_final_paths + * Add foreign paths for performing the final processing remotely. + * + * Given input_rel contains the source-data Paths. The paths are added to the + * given final_rel. + */ +static void +add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel, + RelOptInfo *final_rel, + FinalPathExtraData *extra) +{ + Query *parse = root->parse; + PgFdwRelationInfo *ifpinfo = (PgFdwRelationInfo *) input_rel->fdw_private; + PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) final_rel->fdw_private; + bool has_final_sort = false; + List *pathkeys = NIL; + PgFdwPathExtraData *fpextra; + bool save_use_remote_estimate = false; + double rows; + int width; + Cost startup_cost; + Cost total_cost; + List *fdw_private; + ForeignPath *final_path; + + /* + * Currently, we only support this for SELECT commands + */ + if (parse->commandType != CMD_SELECT) + return; + + /* + * No work if there is no FOR UPDATE/SHARE clause and if there is no need + * to add a LIMIT node + */ + if (!parse->rowMarks && !extra->limit_needed) + return; + + /* We don't support cases where there are any SRFs in the targetlist */ + if (parse->hasTargetSRFs) + return; + + /* Save the input_rel as outerrel in fpinfo */ + fpinfo->outerrel = input_rel; + + /* + * Copy foreign table, foreign server, user mapping, FDW options etc. + * details from the input relation's fpinfo. + */ + fpinfo->table = ifpinfo->table; + fpinfo->server = ifpinfo->server; + fpinfo->user = ifpinfo->user; + merge_fdw_options(fpinfo, ifpinfo, NULL); + + /* + * If there is no need to add a LIMIT node, there might be a ForeignPath + * in the input_rel's pathlist that implements all behavior of the query. + * Note: we would already have accounted for the query's FOR UPDATE/SHARE + * (if any) before we get here. + */ + if (!extra->limit_needed) + { + ListCell *lc; + + Assert(parse->rowMarks); + + /* + * Grouping and aggregation are not supported with FOR UPDATE/SHARE, + * so the input_rel should be a base, join, or ordered relation; and + * if it's an ordered relation, its input relation should be a base or + * join relation. + */ + Assert(input_rel->reloptkind == RELOPT_BASEREL || + input_rel->reloptkind == RELOPT_JOINREL || + (input_rel->reloptkind == RELOPT_UPPER_REL && + ifpinfo->stage == UPPERREL_ORDERED && + (ifpinfo->outerrel->reloptkind == RELOPT_BASEREL || + ifpinfo->outerrel->reloptkind == RELOPT_JOINREL))); + + foreach(lc, input_rel->pathlist) + { + Path *path = (Path *) lfirst(lc); + + /* + * apply_scanjoin_target_to_paths() uses create_projection_path() + * to adjust each of its input paths if needed, whereas + * create_ordered_paths() uses apply_projection_to_path() to do + * that. So the former might have put a ProjectionPath on top of + * the ForeignPath; look through ProjectionPath and see if the + * path underneath it is ForeignPath. + */ + if (IsA(path, ForeignPath) || + (IsA(path, ProjectionPath) && + IsA(((ProjectionPath *) path)->subpath, ForeignPath))) + { + /* + * Create foreign final path; this gets rid of a + * no-longer-needed outer plan (if any), which makes the + * EXPLAIN output look cleaner + */ + final_path = create_foreign_upper_path(root, + path->parent, + path->pathtarget, + path->rows, + path->startup_cost, + path->total_cost, + path->pathkeys, + NULL, /* no extra plan */ + NULL); /* no fdw_private */ + + /* and add it to the final_rel */ + add_path(final_rel, (Path *) final_path); + + /* Safe to push down */ + fpinfo->pushdown_safe = true; + + return; + } + } + + /* + * If we get here it means no ForeignPaths; since we would already + * have considered pushing down all operations for the query to the + * remote server, give up on it. + */ + return; + } + + Assert(extra->limit_needed); + + /* + * If the input_rel is an ordered relation, replace the input_rel with its + * input relation + */ + if (input_rel->reloptkind == RELOPT_UPPER_REL && + ifpinfo->stage == UPPERREL_ORDERED) + { + input_rel = ifpinfo->outerrel; + ifpinfo = (PgFdwRelationInfo *) input_rel->fdw_private; + has_final_sort = true; + pathkeys = root->sort_pathkeys; + } + + /* The input_rel should be a base, join, or grouping relation */ + Assert(input_rel->reloptkind == RELOPT_BASEREL || + input_rel->reloptkind == RELOPT_JOINREL || + (input_rel->reloptkind == RELOPT_UPPER_REL && + ifpinfo->stage == UPPERREL_GROUP_AGG)); + + /* + * We try to create a path below by extending a simple foreign path for + * the underlying base, join, or grouping relation to perform the final + * sort (if has_final_sort) and the LIMIT restriction remotely, which is + * stored into the fdw_private list of the resulting path. (We + * re-estimate the costs of sorting the underlying relation, if + * has_final_sort.) + */ + + /* + * Assess if it is safe to push down the LIMIT and OFFSET to the remote + * server + */ + + /* + * If the underlying relation has any local conditions, the LIMIT/OFFSET + * cannot be pushed down. + */ + if (ifpinfo->local_conds) + return; + + /* + * Also, the LIMIT/OFFSET cannot be pushed down, if their expressions are + * not safe to remote. + */ + if (!is_foreign_expr(root, input_rel, (Expr *) parse->limitOffset) || + !is_foreign_expr(root, input_rel, (Expr *) parse->limitCount)) + return; + + /* Safe to push down */ + fpinfo->pushdown_safe = true; + + /* Construct PgFdwPathExtraData */ + fpextra = (PgFdwPathExtraData *) palloc0(sizeof(PgFdwPathExtraData)); + fpextra->target = root->upper_targets[UPPERREL_FINAL]; + fpextra->has_final_sort = has_final_sort; + fpextra->has_limit = extra->limit_needed; + fpextra->limit_tuples = extra->limit_tuples; + fpextra->count_est = extra->count_est; + fpextra->offset_est = extra->offset_est; + + /* + * Estimate the costs of performing the final sort and the LIMIT + * restriction remotely. If has_final_sort is false, we wouldn't need to + * execute EXPLAIN anymore if use_remote_estimate, since the costs can be + * roughly estimated using the costs we already have for the underlying + * relation, in the same way as when use_remote_estimate is false. Since + * it's pretty expensive to execute EXPLAIN, force use_remote_estimate to + * false in that case. + */ + if (!fpextra->has_final_sort) + { + save_use_remote_estimate = ifpinfo->use_remote_estimate; + ifpinfo->use_remote_estimate = false; + } + estimate_path_cost_size(root, input_rel, NIL, pathkeys, fpextra, + &rows, &width, &startup_cost, &total_cost); + if (!fpextra->has_final_sort) + ifpinfo->use_remote_estimate = save_use_remote_estimate; + + /* + * Build the fdw_private list that will be used by postgresGetForeignPlan. + * Items in the list must match order in enum FdwPathPrivateIndex. + */ + fdw_private = list_make2(makeInteger(has_final_sort), + makeInteger(extra->limit_needed)); + + /* + * Create foreign final path; this gets rid of a no-longer-needed outer + * plan (if any), which makes the EXPLAIN output look cleaner + */ + final_path = create_foreign_upper_path(root, + input_rel, + root->upper_targets[UPPERREL_FINAL], + rows, + startup_cost, + total_cost, + pathkeys, + NULL, /* no extra plan */ + fdw_private); + + /* and add it to the final_rel */ + add_path(final_rel, (Path *) final_path); +} + /* * Create a tuple from the specified row of the PGresult. * @@ -5524,7 +6276,6 @@ make_tuple_from_result_row(PGresult *res, Datum *values; bool *nulls; ItemPointer ctid = NULL; - Oid oid = InvalidOid; ConversionLocation errpos; ErrorContextCallback errcallback; MemoryContext oldcontext; @@ -5607,17 +6358,6 @@ make_tuple_from_result_row(PGresult *res, ctid = (ItemPointer) DatumGetPointer(datum); } } - else if (i == ObjectIdAttributeNumber) - { - /* oid */ - if (valstr != NULL) - { - Datum datum; - - datum = DirectFunctionCall1(oidin, CStringGetDatum(valstr)); - oid = DatumGetObjectId(datum); - } - } errpos.cur_attno = 0; j++; @@ -5661,12 +6401,6 @@ make_tuple_from_result_row(PGresult *res, HeapTupleHeaderSetXmin(tuple->t_data, InvalidTransactionId); HeapTupleHeaderSetCmin(tuple->t_data, InvalidTransactionId); - /* - * If we have an OID to return, install it. - */ - if (OidIsValid(oid)) - HeapTupleSetOid(tuple, oid); - /* Clean up */ MemoryContextReset(temp_context); @@ -5695,8 +6429,6 @@ conversion_error_callback(void *arg) attname = NameStr(attr->attname); else if (errpos->cur_attno == SelfItemPointerAttributeNumber) attname = "ctid"; - else if (errpos->cur_attno == ObjectIdAttributeNumber) - attname = "oid"; relname = RelationGetRelationName(errpos->rel); } @@ -5721,7 +6453,7 @@ conversion_error_callback(void *arg) RangeTblEntry *rte; Var *var = (Var *) tle->expr; - rte = rt_fetch(var->varno, estate->es_range_table); + rte = exec_rt_fetch(var->varno, estate); if (var->varattno == 0) is_wholerow = true; @@ -5757,7 +6489,8 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel) { EquivalenceMember *em = lfirst(lc_em); - if (bms_is_subset(em->em_relids, rel->relids)) + if (bms_is_subset(em->em_relids, rel->relids) && + !bms_is_empty(em->em_relids)) { /* * If there is more than one equivalence member whose Vars are @@ -5771,3 +6504,65 @@ find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel) /* We didn't find any suitable equivalence class expression */ return NULL; } + +/* + * Find an equivalence class member expression to be computed as a sort column + * in the given target. + */ +Expr * +find_em_expr_for_input_target(PlannerInfo *root, + EquivalenceClass *ec, + PathTarget *target) +{ + ListCell *lc1; + int i; + + i = 0; + foreach(lc1, target->exprs) + { + Expr *expr = (Expr *) lfirst(lc1); + Index sgref = get_pathtarget_sortgroupref(target, i); + ListCell *lc2; + + /* Ignore non-sort expressions */ + if (sgref == 0 || + get_sortgroupref_clause_noerr(sgref, + root->parse->sortClause) == NULL) + { + i++; + continue; + } + + /* We ignore binary-compatible relabeling on both ends */ + while (expr && IsA(expr, RelabelType)) + expr = ((RelabelType *) expr)->arg; + + /* Locate an EquivalenceClass member matching this expr, if any */ + foreach(lc2, ec->ec_members) + { + EquivalenceMember *em = (EquivalenceMember *) lfirst(lc2); + Expr *em_expr; + + /* Don't match constants */ + if (em->em_is_const) + continue; + + /* Ignore child members */ + if (em->em_is_child) + continue; + + /* Match if same expression (after stripping relabel) */ + em_expr = em->em_expr; + while (em_expr && IsA(em_expr, RelabelType)) + em_expr = ((RelabelType *) em_expr)->arg; + + if (equal(em_expr, expr)) + return em->em_expr; + } + + i++; + } + + elog(ERROR, "could not find pathkey item to sort"); + return NULL; /* keep compiler quiet */ +} diff --git a/contrib/postgres_fdw/postgres_fdw.h b/contrib/postgres_fdw/postgres_fdw.h index d37cc88b6ec..6acb7dcf6cd 100644 --- a/contrib/postgres_fdw/postgres_fdw.h +++ b/contrib/postgres_fdw/postgres_fdw.h @@ -3,7 +3,7 @@ * postgres_fdw.h * Foreign-data wrapper for remote PostgreSQL servers * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/postgres_fdw.h @@ -15,7 +15,7 @@ #include "foreign/foreign.h" #include "lib/stringinfo.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "utils/relcache.h" #include "libpq-fe.h" @@ -49,6 +49,9 @@ typedef struct PgFdwRelationInfo /* Bitmap of attr numbers we need to fetch from the remote server. */ Bitmapset *attrs_used; + /* True means that the query_pathkeys is safe to push down */ + bool qp_is_pushdown_safe; + /* Cost and selectivity of local_conds. */ QualCost local_conds_cost; Selectivity local_conds_sel; @@ -56,12 +59,18 @@ typedef struct PgFdwRelationInfo /* Selectivity of join conditions */ Selectivity joinclause_sel; - /* Estimated size and cost for a scan or join. */ + /* Estimated size and cost for a scan, join, or grouping/aggregation. */ double rows; int width; Cost startup_cost; Cost total_cost; - /* Costs excluding costs for transferring data from the foreign server */ + + /* + * Estimated number of rows fetched from the foreign server, and costs + * excluding costs for transferring those rows from the foreign server. + * These are only used by estimate_path_cost_size(). + */ + double retrieved_rows; Cost rel_startup_cost; Cost rel_total_cost; @@ -92,6 +101,9 @@ typedef struct PgFdwRelationInfo /* joinclauses contains only JOIN/ON conditions for an outer join */ List *joinclauses; /* List of RestrictInfo */ + /* Upper relation information */ + UpperRelationKind stage; + /* Grouping information */ List *grouped_tlist; @@ -122,62 +134,72 @@ extern unsigned int GetPrepStmtNumber(PGconn *conn); extern PGresult *pgfdw_get_result(PGconn *conn, const char *query); extern PGresult *pgfdw_exec_query(PGconn *conn, const char *query); extern void pgfdw_report_error(int elevel, PGresult *res, PGconn *conn, - bool clear, const char *sql); + bool clear, const char *sql); /* in option.c */ -extern int ExtractConnectionOptions(List *defelems, - const char **keywords, - const char **values); +extern int ExtractConnectionOptions(List *defelems, + const char **keywords, + const char **values); extern List *ExtractExtensionList(const char *extensionsString, - bool warnOnMissing); + bool warnOnMissing); /* in deparse.c */ extern void classifyConditions(PlannerInfo *root, - RelOptInfo *baserel, - List *input_conds, - List **remote_conds, - List **local_conds); + RelOptInfo *baserel, + List *input_conds, + List **remote_conds, + List **local_conds); extern bool is_foreign_expr(PlannerInfo *root, - RelOptInfo *baserel, - Expr *expr); -extern void deparseInsertSql(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *targetAttrs, bool doNothing, List *returningList, - List **retrieved_attrs); -extern void deparseUpdateSql(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *targetAttrs, List *returningList, - List **retrieved_attrs); + RelOptInfo *baserel, + Expr *expr); +extern bool is_foreign_param(PlannerInfo *root, + RelOptInfo *baserel, + Expr *expr); +extern void deparseInsertSql(StringInfo buf, RangeTblEntry *rte, + Index rtindex, Relation rel, + List *targetAttrs, bool doNothing, + List *withCheckOptionList, List *returningList, + List **retrieved_attrs); +extern void deparseUpdateSql(StringInfo buf, RangeTblEntry *rte, + Index rtindex, Relation rel, + List *targetAttrs, + List *withCheckOptionList, List *returningList, + List **retrieved_attrs); extern void deparseDirectUpdateSql(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - RelOptInfo *foreignrel, - List *targetlist, - List *targetAttrs, - List *remote_conds, - List **params_list, - List *returningList, - List **retrieved_attrs); -extern void deparseDeleteSql(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - List *returningList, - List **retrieved_attrs); + Index rtindex, Relation rel, + RelOptInfo *foreignrel, + List *targetlist, + List *targetAttrs, + List *remote_conds, + List **params_list, + List *returningList, + List **retrieved_attrs); +extern void deparseDeleteSql(StringInfo buf, RangeTblEntry *rte, + Index rtindex, Relation rel, + List *returningList, + List **retrieved_attrs); extern void deparseDirectDeleteSql(StringInfo buf, PlannerInfo *root, - Index rtindex, Relation rel, - RelOptInfo *foreignrel, - List *remote_conds, - List **params_list, - List *returningList, - List **retrieved_attrs); + Index rtindex, Relation rel, + RelOptInfo *foreignrel, + List *remote_conds, + List **params_list, + List *returningList, + List **retrieved_attrs); extern void deparseAnalyzeSizeSql(StringInfo buf, Relation rel); extern void deparseAnalyzeSql(StringInfo buf, Relation rel, - List **retrieved_attrs); + List **retrieved_attrs); extern void deparseStringLiteral(StringInfo buf, const char *val); extern Expr *find_em_expr_for_rel(EquivalenceClass *ec, RelOptInfo *rel); +extern Expr *find_em_expr_for_input_target(PlannerInfo *root, + EquivalenceClass *ec, + PathTarget *target); extern List *build_tlist_to_deparse(RelOptInfo *foreignrel); extern void deparseSelectStmtForRel(StringInfo buf, PlannerInfo *root, - RelOptInfo *foreignrel, List *tlist, - List *remote_conds, List *pathkeys, bool is_subquery, - List **retrieved_attrs, List **params_list); + RelOptInfo *foreignrel, List *tlist, + List *remote_conds, List *pathkeys, + bool has_final_sort, bool has_limit, + bool is_subquery, + List **retrieved_attrs, List **params_list); extern const char *get_jointype_name(JoinType jointype); /* in shippable.c */ diff --git a/contrib/postgres_fdw/shippable.c b/contrib/postgres_fdw/shippable.c index 7f2ed0499c0..2b55a40db36 100644 --- a/contrib/postgres_fdw/shippable.c +++ b/contrib/postgres_fdw/shippable.c @@ -13,7 +13,7 @@ * functions or functions using nonportable collations. Those considerations * need not be accounted for here. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/postgres_fdw/shippable.c @@ -137,7 +137,7 @@ lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) /* * Return true if given object is one of PostgreSQL's built-in objects. * - * We use FirstBootstrapObjectId as the cutoff, so that we only consider + * We use FirstGenbkiObjectId as the cutoff, so that we only consider * objects with hand-assigned OIDs to be "built in", not for instance any * function or type defined in the information_schema. * @@ -154,7 +154,7 @@ lookup_shippable(Oid objectId, Oid classId, PgFdwRelationInfo *fpinfo) bool is_builtin(Oid objectId) { - return (objectId < FirstBootstrapObjectId); + return (objectId < FirstGenbkiObjectId); } /* diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql index e1df952e7af..630b803e262 100644 --- a/contrib/postgres_fdw/sql/postgres_fdw.sql +++ b/contrib/postgres_fdw/sql/postgres_fdw.sql @@ -142,14 +142,6 @@ CREATE FOREIGN TABLE ft6 ( c3 text ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4'); --- A table with oids. CREATE FOREIGN TABLE doesn't support the --- WITH OIDS option, but ALTER does. -CREATE FOREIGN TABLE ft_pg_type ( - typname name, - typlen smallint -) SERVER loopback OPTIONS (schema_name 'pg_catalog', table_name 'pg_type'); -ALTER TABLE ft_pg_type SET WITH OIDS; - -- =================================================================== -- tests for validator -- =================================================================== @@ -172,6 +164,7 @@ ALTER SERVER testserver1 OPTIONS ( keepalives 'value', keepalives_idle 'value', keepalives_interval 'value', + tcp_user_timeout 'value', -- requiressl 'value', sslcompression 'value', sslmode 'value', @@ -304,7 +297,7 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- Op EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote -- parameterized remote path for foreign table @@ -357,6 +350,11 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; +-- ORDER BY can be shipped, though +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + -- but let's put them in an extension ... ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int); ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int); @@ -370,6 +368,11 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; +-- and both ORDER BY and LIMIT can be shipped +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + -- =================================================================== -- JOIN queries -- =================================================================== @@ -501,8 +504,8 @@ SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; -- join in CTE EXPLAIN (VERBOSE, COSTS OFF) -WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -- ctid with whole-row reference EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; @@ -514,7 +517,7 @@ SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; --- CROSS JOIN, not pushed down +-- CROSS JOIN can be pushed down EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; @@ -567,15 +570,19 @@ SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5 -- multi-way join involving multiple merge joins -- (this case used to have EPQ-related planning problems) +CREATE TABLE local_tbl (c1 int NOT NULL, c2 int NOT NULL, c3 text, CONSTRAINT local_tbl_pkey PRIMARY KEY (c1)); +INSERT INTO local_tbl SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; +ANALYZE local_tbl; SET enable_nestloop TO false; SET enable_hashjoin TO false; EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1, ft2, ft4, ft5 WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; -SELECT * FROM ft1, ft2, ft4, ft5 WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 FOR UPDATE; RESET enable_nestloop; RESET enable_hashjoin; +DROP TABLE local_tbl; -- check join pushdown in situations where multiple userids are involved CREATE ROLE regress_view_owner SUPERUSER; @@ -617,6 +624,10 @@ explain (verbose, costs off) select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; +explain (verbose, costs off) +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; + -- Aggregate is not pushed down as aggregation contains random() explain (verbose, costs off) select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1; @@ -674,6 +685,16 @@ select count(*) from (select c5, count(c1) from ft1 group by c5, sqrt(c2) having explain (verbose, costs off) select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 order by 1; +-- Remote aggregate in combination with a local Param (for the output +-- of an initplan) can be trouble, per bug #15781 +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1; +select exists(select 1 from pg_enum), sum(c1) from ft1; + +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; + -- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates @@ -815,6 +836,9 @@ create operator class my_op_class for type int using btree family my_op_family a explain (verbose, costs off) select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; +-- Update local stats on ft2 +ANALYZE ft2; + -- Add into extension alter extension postgres_fdw add operator class my_op_class using btree; alter extension postgres_fdw add function my_op_cmp(a int, b int); @@ -884,6 +908,32 @@ select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum fr select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; reset enable_hashagg; +-- bug #15613: bad plan for foreign table scan with lateral reference +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + -- Check with placeHolderVars explain (verbose, costs off) select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); @@ -1002,9 +1052,6 @@ SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; EXPLAIN (VERBOSE, COSTS OFF) SELECT ctid, * FROM ft1 t1 LIMIT 1; SELECT ctid, * FROM ft1 t1 LIMIT 1; -EXPLAIN (VERBOSE, COSTS OFF) -SELECT oid, * FROM ft_pg_type WHERE typname = 'int4'; -SELECT oid, * FROM ft_pg_type WHERE typname = 'int4'; -- =================================================================== -- used in PL/pgSQL function @@ -1099,14 +1146,14 @@ DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; SELECT c1,c2,c3,c4 FROM ft2 ORDER BY c1; EXPLAIN (verbose, costs off) -INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; -INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo') RETURNING tableoid::regclass; EXPLAIN (verbose, costs off) -UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down -UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; +UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down +UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; EXPLAIN (verbose, costs off) -DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; -- can be pushed down -DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; +DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down +DELETE FROM ft2 WHERE c1 = 1200 RETURNING tableoid::regclass; -- Test UPDATE/DELETE with RETURNING on a three-table join INSERT INTO ft2 (c1,c2,c3) @@ -1262,27 +1309,74 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- test WITH CHECK OPTION constraints -- =================================================================== +CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; + CREATE TABLE base_tbl (a int, b int); ALTER TABLE base_tbl SET (autovacuum_enabled = 'false'); +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); CREATE FOREIGN TABLE foreign_tbl (a int, b int) - SERVER loopback OPTIONS(table_name 'base_tbl'); + SERVER loopback OPTIONS (table_name 'base_tbl'); CREATE VIEW rw_view AS SELECT * FROM foreign_tbl WHERE a < b WITH CHECK OPTION; \d+ rw_view -INSERT INTO rw_view VALUES (0, 10); -- ok -INSERT INTO rw_view VALUES (10, 0); -- should fail EXPLAIN (VERBOSE, COSTS OFF) -UPDATE rw_view SET b = 20 WHERE a = 0; -- not pushed down -UPDATE rw_view SET b = 20 WHERE a = 0; -- ok +INSERT INTO rw_view VALUES (0, 5); +INSERT INTO rw_view VALUES (0, 5); -- should fail EXPLAIN (VERBOSE, COSTS OFF) -UPDATE rw_view SET b = -20 WHERE a = 0; -- not pushed down -UPDATE rw_view SET b = -20 WHERE a = 0; -- should fail +INSERT INTO rw_view VALUES (0, 15); +INSERT INTO rw_view VALUES (0, 15); -- ok +SELECT * FROM foreign_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 5; +UPDATE rw_view SET b = b + 5; -- should fail +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 15; +UPDATE rw_view SET b = b + 15; -- ok SELECT * FROM foreign_tbl; DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TRIGGER row_before_insupd_trigger ON base_tbl; DROP TABLE base_tbl; +-- test WCO for partitions + +CREATE TABLE child_tbl (a int, b int); +ALTER TABLE child_tbl SET (autovacuum_enabled = 'false'); +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +CREATE FOREIGN TABLE foreign_tbl (a int, b int) + SERVER loopback OPTIONS (table_name 'child_tbl'); + +CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION foreign_tbl FOR VALUES FROM (0) TO (100); + +CREATE VIEW rw_view AS SELECT * FROM parent_tbl + WHERE a < b WITH CHECK OPTION; +\d+ rw_view + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); +INSERT INTO rw_view VALUES (0, 5); -- should fail +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15); +INSERT INTO rw_view VALUES (0, 15); -- ok +SELECT * FROM foreign_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 5; +UPDATE rw_view SET b = b + 5; -- should fail +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = b + 15; +UPDATE rw_view SET b = b + 15; -- ok +SELECT * FROM foreign_tbl; + +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TRIGGER row_before_insupd_trigger ON child_tbl; +DROP TABLE parent_tbl CASCADE; + +DROP FUNCTION row_before_insupd_trigfunc; + -- =================================================================== -- test serial columns (ie, sequence-based defaults) -- =================================================================== @@ -1298,6 +1392,20 @@ insert into rem1(f2) values('bye remote'); select * from loc1; select * from rem1; +-- =================================================================== +-- test generated columns +-- =================================================================== +create table gloc1 (a int, b int); +alter table gloc1 set (autovacuum_enabled = 'false'); +create foreign table grem1 ( + a int, + b int generated always as (a * 2) stored) + server loopback options(table_name 'gloc1'); +insert into grem1 (a) values (1), (2); +update grem1 set a = 22 where a = 2; +select * from gloc1; +select * from grem1; + -- =================================================================== -- test local triggers -- =================================================================== @@ -1445,6 +1553,11 @@ SELECT * from loc1; UPDATE rem1 set f2 = 'skidoo' RETURNING f2; SELECT * from loc1; +EXPLAIN (verbose, costs off) +UPDATE rem1 set f1 = 10; -- all columns should be transmitted +UPDATE rem1 set f1 = 10; +SELECT * from loc1; + DELETE FROM rem1; -- Add a second trigger, to check that the changes are propagated correctly @@ -1767,6 +1880,38 @@ drop table bar cascade; drop table loct1; drop table loct2; +-- Test pushing down UPDATE/DELETE joins to the remote server +create table parent (a int, b text); +create table loct1 (a int, b text); +create table loct2 (a int, b text); +create foreign table remt1 (a int, b text) + server loopback options (table_name 'loct1'); +create foreign table remt2 (a int, b text) + server loopback options (table_name 'loct2'); +alter foreign table remt1 inherit parent; + +insert into remt1 values (1, 'foo'); +insert into remt1 values (2, 'bar'); +insert into remt2 values (1, 'foo'); +insert into remt2 values (2, 'bar'); + +analyze remt1; +analyze remt2; + +explain (verbose, costs off) +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +explain (verbose, costs off) +delete from parent using remt2 where parent.a = remt2.a returning parent; +delete from parent using remt2 where parent.a = remt2.a returning parent; + +-- cleanup +drop foreign table remt1; +drop foreign table remt2; +drop table loct1; +drop table loct2; +drop table parent; + -- =================================================================== -- test tuple routing for foreign-table partitions -- =================================================================== @@ -1804,6 +1949,31 @@ insert into itrtest values (1, 'bar') on conflict (a) do update set b = excluded select tableoid::regclass, * FROM itrtest; +delete from itrtest; + +drop index loct1_idx; + +-- Test that remote triggers work with insert tuple routing +create function br_insert_trigfunc() returns trigger as $$ +begin + new.b := new.b || ' triggered !'; + return new; +end +$$ language plpgsql; +create trigger loct1_br_insert_trigger before insert on loct1 + for each row execute procedure br_insert_trigfunc(); +create trigger loct2_br_insert_trigger before insert on loct2 + for each row execute procedure br_insert_trigfunc(); + +-- The new values are concatenated with ' triggered !' +insert into itrtest values (1, 'foo') returning *; +insert into itrtest values (2, 'qux') returning *; +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; +with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; + +drop trigger loct1_br_insert_trigger on loct1; +drop trigger loct2_br_insert_trigger on loct2; + drop table itrtest; drop table loct1; drop table loct2; @@ -1836,6 +2006,75 @@ select tableoid::regclass, * FROM locp; -- The executor should not let unexercised FDWs shut down update utrtest set a = 1 where b = 'foo'; +-- Test that remote triggers work with update tuple routing +create trigger loct_br_insert_trigger before insert on loct + for each row execute procedure br_insert_trigfunc(); + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition is a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 1 or a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 1 or a = 2 returning *; + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition isn't a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 2 returning *; + +drop trigger loct_br_insert_trigger on loct; + +-- We can move rows to a foreign partition that has been updated already, +-- but can't move rows to a foreign partition that hasn't been updated yet + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- Test the former case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 returning *; +update utrtest set a = 1 returning *; + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; + +-- Change the definition of utrtest so that the foreign partition get updated +-- after the local partition +delete from utrtest; +alter table utrtest detach partition remp; +drop foreign table remp; +alter table loct drop constraint loct_a_check; +alter table loct add check (a in (3)); +create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); +alter table utrtest attach partition remp for values in (3); +insert into utrtest values (2, 'qux'); +insert into utrtest values (3, 'xyzzy'); + +-- Test the latter case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 returning *; +update utrtest set a = 3 returning *; -- ERROR + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR + drop table utrtest; drop table loct; @@ -2004,6 +2243,20 @@ drop trigger loc2_trig_row_before_insert on loc2; delete from rem2; +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +1 foo +2 bar +\. +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== @@ -2135,8 +2388,9 @@ ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; -CREATE FOREIGN TABLE ftprt2_p1 PARTITION OF fprt2 FOR VALUES FROM (0) TO (250) +CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); +ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); ANALYZE fprt2; @@ -2148,26 +2402,31 @@ EXPLAIN (COSTS OFF) SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; --- left outer join + nullable clasue -EXPLAIN (COSTS OFF) +-- left outer join + nullable clause +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; --- with whole-row reference +-- with whole-row reference; partitionwise join does not apply EXPLAIN (COSTS OFF) -SELECT t1,t2 FROM fprt1 t1 JOIN fprt2 t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a % 25 =0 ORDER BY 1,2; -SELECT t1,t2 FROM fprt1 t1 JOIN fprt2 t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a % 25 =0 ORDER BY 1,2; +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; -- join with lateral reference EXPLAIN (COSTS OFF) SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; --- with PHVs, partition-wise join selected but no join pushdown +-- with PHVs, partitionwise join selected but no join pushdown EXPLAIN (COSTS OFF) SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; +-- test FOR UPDATE; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; + RESET enable_partitionwise_join; diff --git a/contrib/seg/Makefile b/contrib/seg/Makefile index 41270f84f62..62b658e7243 100644 --- a/contrib/seg/Makefile +++ b/contrib/seg/Makefile @@ -8,6 +8,8 @@ DATA = seg--1.1.sql seg--1.1--1.2.sql seg--1.2--1.3.sql \ seg--1.0--1.1.sql seg--unpackaged--1.0.sql PGFILEDESC = "seg - line segment data type" +HEADERS = segdata.h + REGRESS = seg EXTRA_CLEAN = y.tab.c y.tab.h diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out index a289dbe5f99..80b0bca1568 100644 --- a/contrib/seg/expected/seg.out +++ b/contrib/seg/expected/seg.out @@ -1127,7 +1127,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s; 2.1 | 6.95 | 11.8 2.3 | Infinity | Infinity 2.3 | Infinity | Infinity - 2.4 | 6.85 | 11.3 + 2.4 | 6.8500004 | 11.3 2.5 | 7 | 11.5 2.5 | 7.15 | 11.8 2.6 | Infinity | Infinity @@ -1155,7 +1155,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s; 4.5 | 59.75 | 115 4.7 | 8.25 | 11.8 4.8 | 8.15 | 11.5 - 4.8 | 8.2 | 11.6 + 4.8 | 8.200001 | 11.6 4.8 | 8.65 | 12.5 4.8 | Infinity | Infinity 4.9 | 8.45 | 12 @@ -1244,7 +1244,7 @@ FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s; 9 | 10.5 | 12 9 | Infinity | Infinity 9.2 | 10.6 | 12 - 9.4 | 10.8 | 12.2 + 9.4 | 10.799999 | 12.2 9.5 | 10.75 | 12 9.5 | 10.85 | 12.2 9.5 | Infinity | Infinity diff --git a/contrib/seg/expected/seg_1.out b/contrib/seg/expected/seg_1.out deleted file mode 100644 index 48abb65bb0c..00000000000 --- a/contrib/seg/expected/seg_1.out +++ /dev/null @@ -1,1266 +0,0 @@ --- --- Test seg datatype --- -CREATE EXTENSION seg; --- Check whether any of our opclasses fail amvalidate -SELECT amname, opcname -FROM pg_opclass opc LEFT JOIN pg_am am ON am.oid = opcmethod -WHERE opc.oid >= 16384 AND NOT amvalidate(opc.oid); - amname | opcname ---------+--------- -(0 rows) - --- --- testing the input and output functions --- --- Any number -SELECT '1'::seg AS seg; - seg ------ - 1 -(1 row) - -SELECT '-1'::seg AS seg; - seg ------ - -1 -(1 row) - -SELECT '1.0'::seg AS seg; - seg ------ - 1.0 -(1 row) - -SELECT '-1.0'::seg AS seg; - seg ------- - -1.0 -(1 row) - -SELECT '1e7'::seg AS seg; - seg --------- - 1e+007 -(1 row) - -SELECT '-1e7'::seg AS seg; - seg ---------- - -1e+007 -(1 row) - -SELECT '1.0e7'::seg AS seg; - seg ----------- - 1.0e+007 -(1 row) - -SELECT '-1.0e7'::seg AS seg; - seg ------------ - -1.0e+007 -(1 row) - -SELECT '1e+7'::seg AS seg; - seg --------- - 1e+007 -(1 row) - -SELECT '-1e+7'::seg AS seg; - seg ---------- - -1e+007 -(1 row) - -SELECT '1.0e+7'::seg AS seg; - seg ----------- - 1.0e+007 -(1 row) - -SELECT '-1.0e+7'::seg AS seg; - seg ------------ - -1.0e+007 -(1 row) - -SELECT '1e-7'::seg AS seg; - seg --------- - 1e-007 -(1 row) - -SELECT '-1e-7'::seg AS seg; - seg ---------- - -1e-007 -(1 row) - -SELECT '1.0e-7'::seg AS seg; - seg ----------- - 1.0e-007 -(1 row) - -SELECT '-1.0e-7'::seg AS seg; - seg ------------ - -1.0e-007 -(1 row) - -SELECT '2e-6'::seg AS seg; - seg --------- - 2e-006 -(1 row) - -SELECT '2e-5'::seg AS seg; - seg --------- - 2e-005 -(1 row) - -SELECT '2e-4'::seg AS seg; - seg --------- - 0.0002 -(1 row) - -SELECT '2e-3'::seg AS seg; - seg -------- - 0.002 -(1 row) - -SELECT '2e-2'::seg AS seg; - seg ------- - 0.02 -(1 row) - -SELECT '2e-1'::seg AS seg; - seg ------ - 0.2 -(1 row) - -SELECT '2e-0'::seg AS seg; - seg ------ - 2 -(1 row) - -SELECT '2e+0'::seg AS seg; - seg ------ - 2 -(1 row) - -SELECT '2e+1'::seg AS seg; - seg ------ - 2e1 -(1 row) - -SELECT '2e+2'::seg AS seg; - seg ------ - 2e2 -(1 row) - -SELECT '2e+3'::seg AS seg; - seg ------ - 2e3 -(1 row) - -SELECT '2e+4'::seg AS seg; - seg ------ - 2e4 -(1 row) - -SELECT '2e+5'::seg AS seg; - seg --------- - 2e+005 -(1 row) - -SELECT '2e+6'::seg AS seg; - seg --------- - 2e+006 -(1 row) - --- Significant digits preserved -SELECT '1'::seg AS seg; - seg ------ - 1 -(1 row) - -SELECT '1.0'::seg AS seg; - seg ------ - 1.0 -(1 row) - -SELECT '1.00'::seg AS seg; - seg ------- - 1.00 -(1 row) - -SELECT '1.000'::seg AS seg; - seg -------- - 1.000 -(1 row) - -SELECT '1.0000'::seg AS seg; - seg --------- - 1.0000 -(1 row) - -SELECT '1.00000'::seg AS seg; - seg ---------- - 1.00000 -(1 row) - -SELECT '1.000000'::seg AS seg; - seg ---------- - 1.00000 -(1 row) - -SELECT '0.000000120'::seg AS seg; - seg ------------ - 1.20e-007 -(1 row) - -SELECT '3.400e5'::seg AS seg; - seg ------------- - 3.400e+005 -(1 row) - --- Digits truncated -SELECT '12.34567890123456'::seg AS seg; - seg ---------- - 12.3457 -(1 row) - --- Numbers with certainty indicators -SELECT '~6.5'::seg AS seg; - seg ------- - ~6.5 -(1 row) - -SELECT '<6.5'::seg AS seg; - seg ------- - <6.5 -(1 row) - -SELECT '>6.5'::seg AS seg; - seg ------- - >6.5 -(1 row) - -SELECT '~ 6.5'::seg AS seg; - seg ------- - ~6.5 -(1 row) - -SELECT '< 6.5'::seg AS seg; - seg ------- - <6.5 -(1 row) - -SELECT '> 6.5'::seg AS seg; - seg ------- - >6.5 -(1 row) - --- Open intervals -SELECT '0..'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0...'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0 ..'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0 ...'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '..0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '...0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '.. 0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '... 0'::seg AS seg; - seg ------- - .. 0 -(1 row) - --- Finite intervals -SELECT '0 .. 1'::seg AS seg; - seg --------- - 0 .. 1 -(1 row) - -SELECT '-1 .. 0'::seg AS seg; - seg ---------- - -1 .. 0 -(1 row) - -SELECT '-1 .. 1'::seg AS seg; - seg ---------- - -1 .. 1 -(1 row) - --- (+/-) intervals -SELECT '0(+-)1'::seg AS seg; - seg ---------- - -1 .. 1 -(1 row) - -SELECT '0(+-)1.0'::seg AS seg; - seg -------------- - -1.0 .. 1.0 -(1 row) - -SELECT '1.0(+-)0.005'::seg AS seg; - seg ----------------- - 0.995 .. 1.005 -(1 row) - -SELECT '101(+-)1'::seg AS seg; - seg ------------------- - 1.00e2 .. 1.02e2 -(1 row) - --- incorrect number of significant digits in 99.0: -SELECT '100(+-)1'::seg AS seg; - seg ----------------- - 99.0 .. 1.01e2 -(1 row) - --- invalid input -SELECT ''::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT ''::seg AS seg; - ^ -DETAIL: syntax error at end of input -SELECT 'ABC'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT 'ABC'::seg AS seg; - ^ -DETAIL: syntax error at or near "A" -SELECT '1ABC'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '1ABC'::seg AS seg; - ^ -DETAIL: syntax error at or near "A" -SELECT '1.'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '1.'::seg AS seg; - ^ -DETAIL: syntax error at or near "." -SELECT '1.....'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '1.....'::seg AS seg; - ^ -DETAIL: syntax error at or near ".." -SELECT '.1'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '.1'::seg AS seg; - ^ -DETAIL: syntax error at or near "." -SELECT '1..2.'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '1..2.'::seg AS seg; - ^ -DETAIL: syntax error at or near "." -SELECT '1 e7'::seg AS seg; -ERROR: bad seg representation -LINE 1: SELECT '1 e7'::seg AS seg; - ^ -DETAIL: syntax error at or near "e" -SELECT '1e700'::seg AS seg; -ERROR: "1e700" is out of range for type real -LINE 1: SELECT '1e700'::seg AS seg; - ^ --- --- testing the operators --- --- equality/inequality: --- -SELECT '24 .. 33.20'::seg = '24 .. 33.20'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '24 .. 33.20'::seg = '24 .. 33.21'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '24 .. 33.20'::seg != '24 .. 33.20'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '24 .. 33.20'::seg != '24 .. 33.21'::seg AS bool; - bool ------- - t -(1 row) - --- overlap --- -SELECT '1'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg && '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 ..'::seg && '0 ..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '..0'::seg && '0..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 0.1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 0'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. -0.0001'::seg && '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 ..'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 2'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg && '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg && '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - --- overlap on the left --- -SELECT '1'::seg &< '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg &< '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg &< '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool; - bool ------- - t -(1 row) - --- overlap on the right --- -SELECT '0'::seg &> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg &> '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg &> '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 2'::seg &> '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- left --- -SELECT '1'::seg << '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg << '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg << '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg << '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 0.5'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '1 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '2 .. 3'::seg AS bool; - bool ------- - t -(1 row) - --- right --- -SELECT '0'::seg >> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg >> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2'::seg >> '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2'::seg >> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 0.5'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 2'::seg >> '0 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1 .. 2'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2 .. 3'::seg >> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- "contained in" (the left value belongs within the interval specified in the right value): --- -SELECT '0'::seg <@ '0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg <@ '0 ..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg <@ '.. 0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 1'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- "contains" (the left value contains the interval specified in the right value): --- -SELECT '0'::seg @> '0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. '::seg <@ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '.. 0'::seg <@ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '-1 .. 1'::seg <@ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg <@ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- Load some example data and build the index --- -CREATE TABLE test_seg (s seg); -\copy test_seg from 'data/test_seg.data' -CREATE INDEX test_seg_ix ON test_seg USING gist (s); -EXPLAIN (COSTS OFF) -SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_seg - Recheck Cond: (s @> '1.1e1 .. 11.3'::seg) - -> Bitmap Index Scan on test_seg_ix - Index Cond: (s @> '1.1e1 .. 11.3'::seg) -(5 rows) - -SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; - count -------- - 143 -(1 row) - -SET enable_bitmapscan = false; -EXPLAIN (COSTS OFF) -SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; - QUERY PLAN ------------------------------------------------------ - Aggregate - -> Index Only Scan using test_seg_ix on test_seg - Index Cond: (s @> '1.1e1 .. 11.3'::seg) -(3 rows) - -SELECT count(*) FROM test_seg WHERE s @> '11..11.3'; - count -------- - 143 -(1 row) - -RESET enable_bitmapscan; --- Test sorting -SELECT * FROM test_seg WHERE s @> '11..11.3' GROUP BY s; - s ------------------ - .. 4.0e1 - .. >8.2e1 - .. 9.0e1 - <1.0 .. >13.0 - 1.3 .. 12.0 - 2.0 .. 11.5 - 2.1 .. 11.8 - <2.3 .. - >2.3 .. - 2.4 .. 11.3 - 2.5 .. 11.5 - 2.5 .. 11.8 - 2.6 .. - 2.7 .. 12.0 - <3.0 .. - 3 .. 5.8e1 - 3.1 .. 11.5 - 3.5 .. 11.5 - 3.5 .. 12.2 - <4.0 .. >1.2e1 - <4.0 .. - 4 .. 1.2e1 - 4.0 .. 11.7 - 4.0 .. 12.5 - 4.0 .. 13.0 - 4.0 .. 6.0e1 - 4.0 .. - 4.2 .. 11.5 - 4.2 .. 11.7 - <4.5 .. >1.2e1 - 4.5 .. 11.5 - 4.5 .. <1.2e1 - 4.5 .. >1.2e1 - 4.5 .. 12.5 - 4.5 .. 1.15e2 - 4.7 .. 11.8 - 4.8 .. 11.5 - 4.8 .. 11.6 - 4.8 .. 12.5 - 4.8 .. - 4.9 .. >1.2e1 - 4.9 .. - 5 .. 11.5 - 5 .. 1.2e1 - 5 .. 3.0e1 - 5.0 .. 11.4 - 5.0 .. 11.5 - 5.0 .. 11.6 - 5.0 .. 11.7 - 5.0 .. 12.0 - 5.0 .. >12.0 - 5.0 .. >1.2e1 - 5.2 .. 11.5 - 5.2 .. >1.2e1 - 5.25 .. >1.2e1 - 5.3 .. 11.5 - 5.3 .. 1.3e1 - 5.3 .. >9.0e1 - 5.3 .. - 5.4 .. - 5.5 .. 11.5 - 5.5 .. 11.7 - 5.5 .. 1.2e1 - 5.5 .. >1.2e1 - 5.5 .. 12.5 - 5.5 .. 13.5 - 5.5 .. - >5.5 .. - 5.7 .. - 5.9 .. - 6 .. 11.5 - 6 .. >1.2e1 - 6.0 .. 11.5 - 6.0 .. 1.3e1 - >6.0 .. <11.5 - 6.1 .. >1.2e1 - 6.1 .. - 6.2 .. >11.5 - 6.3 .. - 6.5 .. 11.5 - 6.5 .. 12.0 - 6.5 .. >12.0 - 6.5 .. - 6.6 .. - 6.7 .. 11.5 - 6.7 .. - 6.75 .. - 6.8 .. - 6.9 .. 12.2 - 6.9 .. >9.0e1 - 6.9 .. - <7.0 .. >11.5 - 7.0 .. 11.5 - 7.0 .. >11.5 - 7.0 .. - >7.15 .. - 7.2 .. 13.5 - 7.3 .. >9.0e1 - 7.3 .. - >7.3 .. - 7.4 .. 12.1 - 7.4 .. - 7.5 .. 11.5 - 7.5 .. 12.0 - 7.5 .. - 7.7 .. 11.5 - 7.7 .. - 7.75 .. - 8.0 .. 11.7 - 8.0 .. 12.0 - 8.0 .. >13.0 - 8.2 .. - 8.3 .. - 8.5 .. >11.5 - 8.5 .. 12.5 - 8.5 .. - 8.6 .. >9.9e1 - 8.7 .. 11.3 - 8.7 .. 11.7 - 8.9 .. 11.5 - 9 .. >1.2e1 - 9.0 .. 11.3 - 9.0 .. 11.5 - 9.0 .. 1.2e1 - 9.0 .. - 9.2 .. 1.2e1 - 9.4 .. 12.2 - <9.5 .. 1.2e1 - <9.5 .. >12.2 - 9.5 .. - 9.6 .. 11.5 - 9.7 .. 11.5 - 9.7 .. >1.2e1 - 9.8 .. >12.5 - <1.0e1 .. >11.6 - 10.0 .. 11.5 - 10.0 .. 12.5 - 10.0 .. >12.5 - 10.2 .. 11.8 - <10.5 .. 11.5 - 10.5 .. 11.5 - 10.5 .. <13.5 - 10.7 .. 12.3 -(143 rows) - --- Test functions -SELECT seg_lower(s), seg_center(s), seg_upper(s) -FROM test_seg WHERE s @> '11.2..11.3' OR s IS NULL ORDER BY s; - seg_lower | seg_center | seg_upper ------------+------------+----------- - -Infinity | -Infinity | 40 - -Infinity | -Infinity | 82 - -Infinity | -Infinity | 90 - 1 | 7 | 13 - 1.3 | 6.65 | 12 - 2 | 6.75 | 11.5 - 2.1 | 6.95 | 11.8 - 2.3 | Infinity | Infinity - 2.3 | Infinity | Infinity - 2.4 | 6.85 | 11.3 - 2.5 | 7 | 11.5 - 2.5 | 7.15 | 11.8 - 2.6 | Infinity | Infinity - 2.7 | 7.35 | 12 - 3 | Infinity | Infinity - 3 | 30.5 | 58 - 3.1 | 7.3 | 11.5 - 3.5 | 7.5 | 11.5 - 3.5 | 7.85 | 12.2 - 4 | 8 | 12 - 4 | Infinity | Infinity - 4 | 8 | 12 - 4 | 7.85 | 11.7 - 4 | 8.25 | 12.5 - 4 | 8.5 | 13 - 4 | 32 | 60 - 4 | Infinity | Infinity - 4.2 | 7.85 | 11.5 - 4.2 | 7.95 | 11.7 - 4.5 | 8.25 | 12 - 4.5 | 8 | 11.5 - 4.5 | 8.25 | 12 - 4.5 | 8.25 | 12 - 4.5 | 8.5 | 12.5 - 4.5 | 59.75 | 115 - 4.7 | 8.25 | 11.8 - 4.8 | 8.15 | 11.5 - 4.8 | 8.2 | 11.6 - 4.8 | 8.65 | 12.5 - 4.8 | Infinity | Infinity - 4.9 | 8.45 | 12 - 4.9 | Infinity | Infinity - 5 | 8.25 | 11.5 - 5 | 8.5 | 12 - 5 | 17.5 | 30 - 5 | 8.2 | 11.4 - 5 | 8.25 | 11.5 - 5 | 8.3 | 11.6 - 5 | 8.35 | 11.7 - 5 | 8.5 | 12 - 5 | 8.5 | 12 - 5 | 8.5 | 12 - 5.2 | 8.35 | 11.5 - 5.2 | 8.6 | 12 - 5.25 | 8.625 | 12 - 5.3 | 8.4 | 11.5 - 5.3 | 9.15 | 13 - 5.3 | 47.65 | 90 - 5.3 | Infinity | Infinity - 5.4 | Infinity | Infinity - 5.5 | 8.5 | 11.5 - 5.5 | 8.6 | 11.7 - 5.5 | 8.75 | 12 - 5.5 | 8.75 | 12 - 5.5 | 9 | 12.5 - 5.5 | 9.5 | 13.5 - 5.5 | Infinity | Infinity - 5.5 | Infinity | Infinity - 5.7 | Infinity | Infinity - 5.9 | Infinity | Infinity - 6 | 8.75 | 11.5 - 6 | 9 | 12 - 6 | 8.75 | 11.5 - 6 | 9.5 | 13 - 6 | 8.75 | 11.5 - 6.1 | 9.05 | 12 - 6.1 | Infinity | Infinity - 6.2 | 8.85 | 11.5 - 6.3 | Infinity | Infinity - 6.5 | 9 | 11.5 - 6.5 | 9.25 | 12 - 6.5 | 9.25 | 12 - 6.5 | Infinity | Infinity - 6.6 | Infinity | Infinity - 6.7 | 9.1 | 11.5 - 6.7 | Infinity | Infinity - 6.75 | Infinity | Infinity - 6.8 | Infinity | Infinity - 6.9 | 9.55 | 12.2 - 6.9 | 48.45 | 90 - 6.9 | Infinity | Infinity - 7 | 9.25 | 11.5 - 7 | 9.25 | 11.5 - 7 | 9.25 | 11.5 - 7 | Infinity | Infinity - 7.15 | Infinity | Infinity - 7.2 | 10.35 | 13.5 - 7.3 | 48.65 | 90 - 7.3 | Infinity | Infinity - 7.3 | Infinity | Infinity - 7.4 | 9.75 | 12.1 - 7.4 | Infinity | Infinity - 7.5 | 9.5 | 11.5 - 7.5 | 9.75 | 12 - 7.5 | Infinity | Infinity - 7.7 | 9.6 | 11.5 - 7.7 | Infinity | Infinity - 7.75 | Infinity | Infinity - 8 | 9.85 | 11.7 - 8 | 10 | 12 - 8 | 10.5 | 13 - 8.2 | Infinity | Infinity - 8.3 | Infinity | Infinity - 8.5 | 10 | 11.5 - 8.5 | 10.5 | 12.5 - 8.5 | Infinity | Infinity - 8.6 | 53.8 | 99 - 8.7 | 10 | 11.3 - 8.7 | 10.2 | 11.7 - 8.9 | 10.2 | 11.5 - 9 | 10.5 | 12 - 9 | 10.15 | 11.3 - 9 | 10.25 | 11.5 - 9 | 10.5 | 12 - 9 | Infinity | Infinity - 9.2 | 10.6 | 12 - 9.4 | 10.8 | 12.2 - 9.5 | 10.75 | 12 - 9.5 | 10.85 | 12.2 - 9.5 | Infinity | Infinity - 9.6 | 10.55 | 11.5 - 9.7 | 10.6 | 11.5 - 9.7 | 10.85 | 12 - 9.8 | 11.15 | 12.5 - 10 | 10.8 | 11.6 - 10 | 10.75 | 11.5 - 10 | 11.25 | 12.5 - 10 | 11.25 | 12.5 - 10.2 | 11 | 11.8 - 10.5 | 11 | 11.5 - 10.5 | 11 | 11.5 - 10.5 | 12 | 13.5 - 10.7 | 11.5 | 12.3 - | | -(144 rows) - diff --git a/contrib/sepgsql/database.c b/contrib/sepgsql/database.c index c641ec3565e..8edd3df643c 100644 --- a/contrib/sepgsql/database.c +++ b/contrib/sepgsql/database.c @@ -4,16 +4,16 @@ * * Routines corresponding to database objects * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/pg_database.h" #include "catalog/indexing.h" @@ -21,7 +21,7 @@ #include "commands/seclabel.h" #include "utils/builtins.h" #include "utils/fmgroids.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" #include "sepgsql.h" /* @@ -63,7 +63,7 @@ sepgsql_database_post_create(Oid databaseId, const char *dtemplate) * check db_database:{getattr} permission */ initStringInfo(&audit_name); - appendStringInfo(&audit_name, "%s", quote_identifier(dtemplate)); + appendStringInfoString(&audit_name, quote_identifier(dtemplate)); sepgsql_avc_check_perms_label(tcontext, SEPG_CLASS_DB_DATABASE, SEPG_DB_DATABASE__GETATTR, @@ -77,10 +77,10 @@ sepgsql_database_post_create(Oid databaseId, const char *dtemplate) * XXX - uncoming version of libselinux supports to take object name to * handle special treatment on default security label. */ - rel = heap_open(DatabaseRelationId, AccessShareLock); + rel = table_open(DatabaseRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_database_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(databaseId)); @@ -101,8 +101,8 @@ sepgsql_database_post_create(Oid databaseId, const char *dtemplate) * check db_database:{create} permission */ resetStringInfo(&audit_name); - appendStringInfo(&audit_name, "%s", - quote_identifier(NameStr(datForm->datname))); + appendStringInfoString(&audit_name, + quote_identifier(NameStr(datForm->datname))); sepgsql_avc_check_perms_label(ncontext, SEPG_CLASS_DB_DATABASE, SEPG_DB_DATABASE__CREATE, @@ -110,7 +110,7 @@ sepgsql_database_post_create(Oid databaseId, const char *dtemplate) true); systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* * Assign the default security label on the new database diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c index 9bdbd7b60f5..2892346f800 100644 --- a/contrib/sepgsql/dml.c +++ b/contrib/sepgsql/dml.c @@ -4,7 +4,7 @@ * * Routines to handle DML permission checks * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -161,12 +161,10 @@ check_relation_privileges(Oid relOid, */ if (sepgsql_getenforce() > 0) { - Oid relnamespace = get_rel_namespace(relOid); - - if (IsSystemNamespace(relnamespace) && - (required & (SEPG_DB_TABLE__UPDATE | + if ((required & (SEPG_DB_TABLE__UPDATE | SEPG_DB_TABLE__INSERT | - SEPG_DB_TABLE__DELETE)) != 0) + SEPG_DB_TABLE__DELETE)) != 0 && + IsCatalogRelationOid(relOid)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("SELinux: hardwired security policy violation"))); diff --git a/contrib/sepgsql/expected/alter.out b/contrib/sepgsql/expected/alter.out index 0948139f934..836acea33bc 100644 --- a/contrib/sepgsql/expected/alter.out +++ b/contrib/sepgsql/expected/alter.out @@ -179,9 +179,9 @@ LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_table" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column a of table regtest_table" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema.regtest_table_3" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column x of table regtest_table_3" LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema_2" LINE 1: SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" f... ^ @@ -196,9 +196,9 @@ LINE 1: ..."regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(p... QUERY: SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL) LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_table" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column a of table regtest_table" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema.regtest_table_3" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column x of table regtest_table_3" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4eq(integer,integer)" ALTER TABLE regtest_table ADD CONSTRAINT test_ck CHECK (b like '%abc%') NOT VALID; -- not supported ALTER TABLE regtest_table VALIDATE CONSTRAINT test_ck; -- not supported @@ -212,12 +212,6 @@ ALTER TABLE regtest_table ENABLE TRIGGER regtest_test_trig; -- not supported CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING; ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule; -- not supported ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule; -- not supported -ALTER TABLE regtest_table SET WITH OIDS; -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table.oid" -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid" -ALTER TABLE regtest_table SET WITHOUT OIDS; -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid" -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table.oid" ALTER TABLE regtest_table SET (fillfactor = 75); LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_table" ALTER TABLE regtest_table RESET (fillfactor); @@ -265,15 +259,8 @@ LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_re LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.p" ALTER TABLE regtest_ptable ADD CONSTRAINT test_ck CHECK (p like '%abc%') NOT VALID; -- not supported by sepgsql ALTER TABLE regtest_ptable DROP CONSTRAINT test_ck; -- not supported by sepgsql -ALTER TABLE regtest_ptable SET WITH OIDS; -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_ptable.oid" -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table_part.oid" -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.oid" -ALTER TABLE regtest_ptable SET WITHOUT OIDS; -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table_part.oid" -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.oid" -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_ptable.oid" ALTER TABLE regtest_ptable SET TABLESPACE pg_default; +LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_ptable" -- partitioned table child ALTER TABLE regtest_table_part ALTER p SET DEFAULT 'abcd'; -- not supported by sepgsql ALTER TABLE regtest_table_part ALTER p SET DEFAULT 'XYZ'; -- not supported by sepgsql diff --git a/contrib/sepgsql/expected/ddl.out b/contrib/sepgsql/expected/ddl.out index 1c0409a7a65..729111351a0 100644 --- a/contrib/sepgsql/expected/ddl.out +++ b/contrib/sepgsql/expected/ddl.out @@ -61,9 +61,9 @@ LINE 1: ALTER TABLE regtest_table ADD COLUMN z int; ^ LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.z" -CREATE TABLE regtest_table_2 (a int) WITH OIDS; +CREATE TABLE regtest_table_2 (a int); LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" -LINE 1: CREATE TABLE regtest_table_2 (a int) WITH OIDS; +LINE 1: CREATE TABLE regtest_table_2 (a int); ^ LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog" LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema" @@ -73,7 +73,6 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_reg LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.xmax" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.cmin" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.xmin" -LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.ctid" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.a" CREATE TABLE regtest_ptable (a int) PARTITION BY RANGE (a); @@ -413,8 +412,6 @@ LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsq LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="regtest_schema.regtest_view" ALTER TABLE regtest_table DROP COLUMN y; LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.y" -ALTER TABLE regtest_table_2 SET WITHOUT OIDS; -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid" ALTER TABLE regtest_ptable DROP COLUMN q CASCADE; LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_ones.q" LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_tens.q" @@ -424,10 +421,10 @@ LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regte LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable.q" DROP TABLE regtest_table; LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema" -LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="regtest_schema.regtest_table_x_seq" -LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema" LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema.regtest_table" LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema" +LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="regtest_schema.regtest_table_x_seq" +LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema" LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema.regtest_table" LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.tableoid" LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.cmax" diff --git a/contrib/sepgsql/expected/misc.out b/contrib/sepgsql/expected/misc.out index 32b3bb4f585..b2c01e03ded 100644 --- a/contrib/sepgsql/expected/misc.out +++ b/contrib/sepgsql/expected/misc.out @@ -17,8 +17,8 @@ SET client_min_messages = log; -- regular function and operators SELECT * FROM t1 WHERE x > 50 AND y like '%64%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1 column x" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1 column y" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column x of table t1" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column y of table t1" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4gt(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" x | y @@ -33,14 +33,14 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT * FROM t1p WHERE o > 50 AND p like '%64%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_ones" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_tens" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4gt(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" o | p @@ -54,8 +54,8 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT * FROM t1p_ones WHERE o > 50 AND p like '%64%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_ones" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4gt(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" o | p @@ -64,8 +64,8 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT * FROM t1p_tens WHERE o > 50 AND p like '%64%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_tens" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4gt(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" o | p @@ -80,12 +80,12 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re -- aggregate function SELECT MIN(x), AVG(x) FROM t1; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1 column x" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column x of table t1" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" min | avg -----+--------------------- 1 | 50.5000000000000000 @@ -93,16 +93,16 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT MIN(o), AVG(o) FROM t1p; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p column o" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" min | avg -----+--------------------- 0 | 49.5000000000000000 @@ -110,12 +110,12 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT MIN(o), AVG(o) FROM t1p_ones; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" min | avg -----+-------------------- 0 | 4.5000000000000000 @@ -123,12 +123,12 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT MIN(o), AVG(o) FROM t1p_tens; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" +LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.avg(integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4_avg_accum(bigint[],integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int8_avg(bigint[])" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.min(integer)" -LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4smaller(integer,integer)" min | avg -----+--------------------- 10 | 54.5000000000000000 @@ -137,8 +137,8 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re -- window function SELECT row_number() OVER (order by x), * FROM t1 WHERE y like '%86%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1 column x" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1 column y" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column x of table t1" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column y of table t1" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4eq(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.row_number()" @@ -160,14 +160,14 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT row_number() OVER (order by o), * FROM t1p WHERE p like '%86%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_ones" LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_tens" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4eq(integer,integer)" @@ -190,8 +190,8 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT row_number() OVER (order by o), * FROM t1p_ones WHERE p like '%86%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_ones" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_ones column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_ones" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_ones" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4eq(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.row_number()" @@ -202,8 +202,8 @@ LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_re SELECT row_number() OVER (order by o), * FROM t1p_tens WHERE p like '%86%'; LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="public.t1p_tens" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column o" -LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table t1p_tens column p" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column o of table t1p_tens" +LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="column p of table t1p_tens" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.textlike(pg_catalog.text,pg_catalog.text)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.int4eq(integer,integer)" LOG: SELinux: allowed { execute } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0-s0:c0.c255 tcontext=system_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="pg_catalog.row_number()" diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c index 4249ed552c8..ebfa441b47a 100644 --- a/contrib/sepgsql/hooks.c +++ b/contrib/sepgsql/hooks.c @@ -4,7 +4,7 @@ * * Entrypoints of the hooks in PostgreSQL, and dispatches the callbacks. * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c index dba0986e02a..63a2dd5cc1b 100644 --- a/contrib/sepgsql/label.c +++ b/contrib/sepgsql/label.c @@ -4,7 +4,7 @@ * * Routines to support SELinux labels (security context) * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -12,9 +12,9 @@ #include -#include "access/heapam.h" #include "access/htup_details.h" #include "access/genam.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" @@ -35,7 +35,6 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" #include "sepgsql.h" @@ -208,23 +207,16 @@ sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg) { ListCell *cell; - ListCell *prev; - ListCell *next; if (event == SUBXACT_EVENT_ABORT_SUB) { - prev = NULL; - for (cell = list_head(client_label_pending); cell; cell = next) + foreach(cell, client_label_pending) { pending_label *plabel = lfirst(cell); - next = lnext(cell); - if (plabel->subid == mySubid) client_label_pending - = list_delete_cell(client_label_pending, cell, prev); - else - prev = cell; + = foreach_delete_current(client_label_pending, cell); } } } @@ -661,7 +653,7 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS) } /* - * quote_object_names + * quote_object_name * * It tries to quote the supplied identifiers */ @@ -677,7 +669,7 @@ quote_object_name(const char *src1, const char *src2, if (src1) { temp = quote_identifier(src1); - appendStringInfo(&result, "%s", temp); + appendStringInfoString(&result, temp); if (src1 != temp) pfree((void *) temp); } @@ -727,7 +719,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) * Open the target catalog. We don't want to allow writable accesses by * other session during initial labeling. */ - rel = heap_open(catalogId, AccessShareLock); + rel = table_open(catalogId, AccessShareLock); sscan = systable_beginscan(rel, InvalidOid, false, NULL, 0, NULL); @@ -758,7 +750,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) NULL, NULL, NULL); object.classId = DatabaseRelationId; - object.objectId = HeapTupleGetOid(tuple); + object.objectId = datForm->oid; object.objectSubId = 0; break; @@ -772,7 +764,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) NULL, NULL); object.classId = NamespaceRelationId; - object.objectId = HeapTupleGetOid(tuple); + object.objectId = nspForm->oid; object.objectSubId = 0; break; @@ -797,7 +789,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) pfree(namespace_name); object.classId = RelationRelationId; - object.objectId = HeapTupleGetOid(tuple); + object.objectId = relForm->oid; object.objectSubId = 0; break; @@ -838,7 +830,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) pfree(namespace_name); object.classId = ProcedureRelationId; - object.objectId = HeapTupleGetOid(tuple); + object.objectId = proForm->oid; object.objectSubId = 0; break; @@ -881,7 +873,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) } systable_endscan(sscan); - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* diff --git a/contrib/sepgsql/launcher b/contrib/sepgsql/launcher index 45139f37504..fa449339db2 100755 --- a/contrib/sepgsql/launcher +++ b/contrib/sepgsql/launcher @@ -2,7 +2,7 @@ # # A wrapper script to launch psql command in regression test # -# Copyright (c) 2010-2018, PostgreSQL Global Development Group +# Copyright (c) 2010-2019, PostgreSQL Global Development Group # # ------------------------------------------------------------------------- diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c index c6a817d7c58..aa12dbe2367 100644 --- a/contrib/sepgsql/proc.c +++ b/contrib/sepgsql/proc.c @@ -4,16 +4,16 @@ * * Routines corresponding to procedure objects * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_namespace.h" @@ -24,8 +24,8 @@ #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" +#include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #include "sepgsql.h" @@ -56,10 +56,10 @@ sepgsql_proc_post_create(Oid functionId) * Fetch namespace of the new procedure. Because pg_proc entry is not * visible right now, we need to scan the catalog using SnapshotSelf. */ - rel = heap_open(ProcedureRelationId, AccessShareLock); + rel = table_open(ProcedureRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_proc_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(functionId)); @@ -141,7 +141,7 @@ sepgsql_proc_post_create(Oid functionId) * Cleanup */ systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); pfree(audit_name.data); pfree(tcontext); @@ -250,10 +250,10 @@ sepgsql_proc_setattr(Oid functionId) /* * Fetch newer catalog */ - rel = heap_open(ProcedureRelationId, AccessShareLock); + rel = table_open(ProcedureRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_proc_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(functionId)); @@ -305,7 +305,7 @@ sepgsql_proc_setattr(Oid functionId) ReleaseSysCache(oldtup); systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); } /* diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c index f0c22715aa5..061527559c1 100644 --- a/contrib/sepgsql/relation.c +++ b/contrib/sepgsql/relation.c @@ -4,16 +4,16 @@ * * Routines corresponding to relation/attribute objects * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/dependency.h" #include "catalog/pg_attribute.h" @@ -26,8 +26,8 @@ #include "utils/catcache.h" #include "utils/lsyscache.h" #include "utils/rel.h" +#include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #include "sepgsql.h" @@ -67,7 +67,7 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum) * Compute a default security label of the new column underlying the * specified relation, and check permission to create it. */ - rel = heap_open(AttributeRelationId, AccessShareLock); + rel = table_open(AttributeRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_attribute_attrelid, @@ -120,7 +120,7 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum) SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext); systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); pfree(tcontext); pfree(ncontext); @@ -259,10 +259,10 @@ sepgsql_relation_post_create(Oid relOid) * Fetch catalog record of the new relation. Because pg_class entry is not * visible right now, we need to scan the catalog using SnapshotSelf. */ - rel = heap_open(RelationRelationId, AccessShareLock); + rel = table_open(RelationRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_class_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid)); @@ -358,7 +358,7 @@ sepgsql_relation_post_create(Oid relOid) HeapTuple atup; Form_pg_attribute attForm; - arel = heap_open(AttributeRelationId, AccessShareLock); + arel = table_open(AttributeRelationId, AccessShareLock); ScanKeyInit(&akey, Anum_pg_attribute_attrelid, @@ -400,13 +400,13 @@ sepgsql_relation_post_create(Oid relOid) pfree(ccontext); } systable_endscan(ascan); - heap_close(arel, AccessShareLock); + table_close(arel, AccessShareLock); } pfree(rcontext); out: systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); } /* @@ -611,10 +611,10 @@ sepgsql_relation_setattr(Oid relOid) /* * Fetch newer catalog */ - rel = heap_open(RelationRelationId, AccessShareLock); + rel = table_open(RelationRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_class_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relOid)); @@ -667,7 +667,7 @@ sepgsql_relation_setattr(Oid relOid) ReleaseSysCache(oldtup); systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); } /* @@ -723,7 +723,7 @@ sepgsql_relation_setattr_extra(Relation catalog, static void sepgsql_index_modify(Oid indexOid) { - Relation catalog = heap_open(IndexRelationId, AccessShareLock); + Relation catalog = table_open(IndexRelationId, AccessShareLock); /* check db_table:{setattr} permission of the table being indexed */ sepgsql_relation_setattr_extra(catalog, @@ -731,5 +731,5 @@ sepgsql_index_modify(Oid indexOid) indexOid, Anum_pg_index_indrelid, Anum_pg_index_indexrelid); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); } diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c index bc15a36a459..4c4a90f9781 100644 --- a/contrib/sepgsql/schema.c +++ b/contrib/sepgsql/schema.c @@ -4,16 +4,16 @@ * * Routines corresponding to schema objects * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_database.h" @@ -24,7 +24,7 @@ #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" #include "sepgsql.h" @@ -56,10 +56,10 @@ sepgsql_schema_post_create(Oid namespaceId) * handle special treatment on default security label; such as special * label on "pg_temp" schema. */ - rel = heap_open(NamespaceRelationId, AccessShareLock); + rel = table_open(NamespaceRelationId, AccessShareLock); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + Anum_pg_namespace_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(namespaceId)); @@ -93,7 +93,7 @@ sepgsql_schema_post_create(Oid namespaceId) audit_name.data, true); systable_endscan(sscan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* * Assign the default security label on a new procedure diff --git a/contrib/sepgsql/selinux.c b/contrib/sepgsql/selinux.c index 47def00a460..192aabea0b3 100644 --- a/contrib/sepgsql/selinux.c +++ b/contrib/sepgsql/selinux.c @@ -5,7 +5,7 @@ * Interactions between userspace and selinux in kernelspace, * using libselinux api. * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -657,10 +657,8 @@ sepgsql_getenforce(void) /* * sepgsql_audit_log * - * It generates a security audit record. In the default, it writes out - * audit records into standard PG's logfile. It also allows to set up - * external audit log receiver, such as auditd in Linux, using the - * sepgsql_audit_hook. + * It generates a security audit record. It writes out audit records + * into standard PG's logfile. * * SELinux can control what should be audited and should not using * "auditdeny" and "auditallow" rules in the security policy. In the @@ -702,7 +700,7 @@ sepgsql_audit_log(bool denied, appendStringInfo(&buf, " %s", av_name); } } - appendStringInfo(&buf, " }"); + appendStringInfoString(&buf, " }"); /* * Call external audit module, if loaded diff --git a/contrib/sepgsql/sepgsql-regtest.te b/contrib/sepgsql/sepgsql-regtest.te index e5d65243e6b..5d9af1a0ddb 100644 --- a/contrib/sepgsql/sepgsql-regtest.te +++ b/contrib/sepgsql/sepgsql-regtest.te @@ -31,6 +31,9 @@ userdom_base_user_template(sepgsql_regtest_superuser) userdom_manage_home_role(sepgsql_regtest_superuser_r, sepgsql_regtest_superuser_t) userdom_exec_user_home_content_files(sepgsql_regtest_superuser_t) userdom_write_user_tmp_sockets(sepgsql_regtest_superuser_t) + +auth_read_passwd(sepgsql_regtest_superuser_t) + optional_policy(` postgresql_stream_connect(sepgsql_regtest_superuser_t) postgresql_unconfined(sepgsql_regtest_superuser_t) @@ -60,6 +63,9 @@ userdom_base_user_template(sepgsql_regtest_dba) userdom_manage_home_role(sepgsql_regtest_dba_r, sepgsql_regtest_dba_t) userdom_exec_user_home_content_files(sepgsql_regtest_dba_t) userdom_write_user_tmp_sockets(sepgsql_regtest_user_t) + +auth_read_passwd(sepgsql_regtest_dba_t) + optional_policy(` postgresql_admin(sepgsql_regtest_dba_t, sepgsql_regtest_dba_r) postgresql_stream_connect(sepgsql_regtest_dba_t) @@ -98,6 +104,9 @@ userdom_base_user_template(sepgsql_regtest_user) userdom_manage_home_role(sepgsql_regtest_user_r, sepgsql_regtest_user_t) userdom_exec_user_home_content_files(sepgsql_regtest_user_t) userdom_write_user_tmp_sockets(sepgsql_regtest_user_t) + +auth_read_passwd(sepgsql_regtest_user_t) + optional_policy(` postgresql_role(sepgsql_regtest_user_r, sepgsql_regtest_user_t) postgresql_stream_connect(sepgsql_regtest_user_t) @@ -126,6 +135,8 @@ userdom_manage_home_role(sepgsql_regtest_pool_r, sepgsql_regtest_pool_t) userdom_exec_user_home_content_files(sepgsql_regtest_pool_t) userdom_write_user_tmp_sockets(sepgsql_regtest_pool_t) +auth_read_passwd(sepgsql_regtest_pool_t) + type sepgsql_regtest_foo_t; type sepgsql_regtest_var_t; type sepgsql_regtest_foo_table_t; diff --git a/contrib/sepgsql/sepgsql.h b/contrib/sepgsql/sepgsql.h index 99adfc522a3..4787934650a 100644 --- a/contrib/sepgsql/sepgsql.h +++ b/contrib/sepgsql/sepgsql.h @@ -4,7 +4,7 @@ * * Definitions corresponding to SE-PostgreSQL * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -226,43 +226,43 @@ extern int sepgsql_set_mode(int new_mode); extern bool sepgsql_getenforce(void); extern void sepgsql_audit_log(bool denied, - const char *scontext, - const char *tcontext, - uint16 tclass, - uint32 audited, - const char *audit_name); + const char *scontext, + const char *tcontext, + uint16 tclass, + uint32 audited, + const char *audit_name); extern void sepgsql_compute_avd(const char *scontext, - const char *tcontext, - uint16 tclass, - struct av_decision *avd); + const char *tcontext, + uint16 tclass, + struct av_decision *avd); extern char *sepgsql_compute_create(const char *scontext, - const char *tcontext, - uint16 tclass, - const char *objname); + const char *tcontext, + uint16 tclass, + const char *objname); extern bool sepgsql_check_perms(const char *scontext, - const char *tcontext, - uint16 tclass, - uint32 required, - const char *audit_name, - bool abort_on_violation); + const char *tcontext, + uint16 tclass, + uint32 required, + const char *audit_name, + bool abort_on_violation); /* * uavc.c */ #define SEPGSQL_AVC_NOAUDIT ((void *)(-1)) extern bool sepgsql_avc_check_perms_label(const char *tcontext, - uint16 tclass, - uint32 required, - const char *audit_name, - bool abort_on_violation); + uint16 tclass, + uint32 required, + const char *audit_name, + bool abort_on_violation); extern bool sepgsql_avc_check_perms(const ObjectAddress *tobject, - uint16 tclass, - uint32 required, - const char *audit_name, - bool abort_on_violation); + uint16 tclass, + uint32 required, + const char *audit_name, + bool abort_on_violation); extern char *sepgsql_avc_trusted_proc(Oid functionId); extern void sepgsql_avc_init(void); @@ -271,10 +271,10 @@ extern void sepgsql_avc_init(void); */ extern char *sepgsql_get_client_label(void); extern void sepgsql_init_client_label(void); -extern char *sepgsql_get_label(Oid relOid, Oid objOid, int32 subId); +extern char *sepgsql_get_label(Oid classId, Oid objectId, int32 subId); extern void sepgsql_object_relabel(const ObjectAddress *object, - const char *seclabel); + const char *seclabel); /* * dml.c @@ -285,7 +285,7 @@ extern bool sepgsql_dml_privileges(List *rangeTabls, bool abort_on_violation); * database.c */ extern void sepgsql_database_post_create(Oid databaseId, - const char *dtemplate); + const char *dtemplate); extern void sepgsql_database_drop(Oid databaseId); extern void sepgsql_database_relabel(Oid databaseId, const char *seclabel); extern void sepgsql_database_setattr(Oid databaseId); @@ -308,7 +308,7 @@ extern void sepgsql_schema_rename(Oid namespaceId); extern void sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum); extern void sepgsql_attribute_drop(Oid relOid, AttrNumber attnum); extern void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, - const char *seclabel); + const char *seclabel); extern void sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum); extern void sepgsql_relation_post_create(Oid relOid); extern void sepgsql_relation_drop(Oid relOid); diff --git a/contrib/sepgsql/sql/alter.sql b/contrib/sepgsql/sql/alter.sql index 14000eaaeeb..f1144492329 100644 --- a/contrib/sepgsql/sql/alter.sql +++ b/contrib/sepgsql/sql/alter.sql @@ -134,8 +134,6 @@ CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING; ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule; -- not supported ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule; -- not supported -ALTER TABLE regtest_table SET WITH OIDS; -ALTER TABLE regtest_table SET WITHOUT OIDS; ALTER TABLE regtest_table SET (fillfactor = 75); ALTER TABLE regtest_table RESET (fillfactor); ALTER TABLE regtest_table_2 NO INHERIT regtest_table; -- not supported @@ -157,8 +155,6 @@ ALTER TABLE regtest_ptable ALTER p SET STORAGE PLAIN; ALTER TABLE regtest_ptable ADD CONSTRAINT test_ck CHECK (p like '%abc%') NOT VALID; -- not supported by sepgsql ALTER TABLE regtest_ptable DROP CONSTRAINT test_ck; -- not supported by sepgsql -ALTER TABLE regtest_ptable SET WITH OIDS; -ALTER TABLE regtest_ptable SET WITHOUT OIDS; ALTER TABLE regtest_ptable SET TABLESPACE pg_default; -- partitioned table child diff --git a/contrib/sepgsql/sql/ddl.sql b/contrib/sepgsql/sql/ddl.sql index ae431f6cd2a..3deadb62526 100644 --- a/contrib/sepgsql/sql/ddl.sql +++ b/contrib/sepgsql/sql/ddl.sql @@ -30,7 +30,7 @@ CREATE TABLE regtest_table (x serial primary key, y text); ALTER TABLE regtest_table ADD COLUMN z int; -CREATE TABLE regtest_table_2 (a int) WITH OIDS; +CREATE TABLE regtest_table_2 (a int); CREATE TABLE regtest_ptable (a int) PARTITION BY RANGE (a); CREATE TABLE regtest_ptable_ones PARTITION OF regtest_ptable FOR VALUES FROM ('0') TO ('10'); @@ -112,7 +112,6 @@ DROP SEQUENCE regtest_seq; DROP VIEW regtest_view; ALTER TABLE regtest_table DROP COLUMN y; -ALTER TABLE regtest_table_2 SET WITHOUT OIDS; ALTER TABLE regtest_ptable DROP COLUMN q CASCADE; diff --git a/contrib/sepgsql/uavc.c b/contrib/sepgsql/uavc.c index ea276ee0ccd..60fcf996539 100644 --- a/contrib/sepgsql/uavc.c +++ b/contrib/sepgsql/uavc.c @@ -6,17 +6,17 @@ * access control decisions recently used, and reduce number of kernel * invocations to avoid unnecessary performance hit. * - * Copyright (c) 2011-2018, PostgreSQL Global Development Group + * Copyright (c) 2011-2019, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/hash.h" #include "catalog/pg_proc.h" #include "commands/seclabel.h" #include "storage/ipc.h" #include "utils/guc.h" +#include "utils/hashutils.h" #include "utils/memutils.h" #include "sepgsql.h" @@ -93,24 +93,20 @@ static void sepgsql_avc_reclaim(void) { ListCell *cell; - ListCell *next; - ListCell *prev; int index; while (avc_num_caches >= avc_threshold - AVC_NUM_RECLAIM) { index = avc_lru_hint; - prev = NULL; - for (cell = list_head(avc_slots[index]); cell; cell = next) + foreach(cell, avc_slots[index]) { avc_cache *cache = lfirst(cell); - next = lnext(cell); if (!cache->hot_cache) { avc_slots[index] - = list_delete_cell(avc_slots[index], cell, prev); + = foreach_delete_current(avc_slots[index], cell); pfree(cache->scontext); pfree(cache->tcontext); @@ -123,7 +119,6 @@ sepgsql_avc_reclaim(void) else { cache->hot_cache = false; - prev = cell; } } avc_lru_hint = (avc_lru_hint + 1) % AVC_NUM_SLOTS; diff --git a/contrib/spi/Makefile b/contrib/spi/Makefile index 42aa3740c42..6bc2318e0ac 100644 --- a/contrib/spi/Makefile +++ b/contrib/spi/Makefile @@ -1,14 +1,13 @@ # contrib/spi/Makefile -MODULES = autoinc insert_username moddatetime refint timetravel +MODULES = autoinc insert_username moddatetime refint -EXTENSION = autoinc insert_username moddatetime refint timetravel +EXTENSION = autoinc insert_username moddatetime refint DATA = autoinc--1.0.sql autoinc--unpackaged--1.0.sql \ insert_username--1.0.sql insert_username--unpackaged--1.0.sql \ moddatetime--1.0.sql moddatetime--unpackaged--1.0.sql \ - refint--1.0.sql refint--unpackaged--1.0.sql \ - timetravel--1.0.sql timetravel--unpackaged--1.0.sql + refint--1.0.sql refint--unpackaged--1.0.sql PGFILEDESC = "spi - examples of using SPI and triggers" DOCS = $(addsuffix .example, $(MODULES)) diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c index b065ffa400d..adf0490f853 100644 --- a/contrib/spi/refint.c +++ b/contrib/spi/refint.c @@ -306,7 +306,7 @@ check_foreign_key(PG_FUNCTION_ARGS) /* internal error */ elog(ERROR, "check_foreign_key: too short %d (< 5) list of arguments", nargs); - nrefs = pg_atoi(args[0], sizeof(int), 0); + nrefs = pg_strtoint32(args[0]); if (nrefs < 1) /* internal error */ elog(ERROR, "check_foreign_key: %d (< 1) number of references specified", nrefs); @@ -473,9 +473,12 @@ check_foreign_key(PG_FUNCTION_ARGS) nv = SPI_getvalue(newtuple, tupdesc, fn); type = SPI_gettype(tupdesc, fn); - if ((strcmp(type, "text") && strcmp(type, "varchar") && - strcmp(type, "char") && strcmp(type, "bpchar") && - strcmp(type, "date") && strcmp(type, "timestamp")) == 0) + if (strcmp(type, "text") == 0 || + strcmp(type, "varchar") == 0 || + strcmp(type, "char") == 0 || + strcmp(type, "bpchar") == 0 || + strcmp(type, "date") == 0 || + strcmp(type, "timestamp") == 0) is_char_type = 1; #ifdef DEBUG_QUERY elog(DEBUG4, "check_foreign_key Debug value %s type %s %d", diff --git a/contrib/spi/refint.example b/contrib/spi/refint.example index d0ff7441642..299166d5041 100644 --- a/contrib/spi/refint.example +++ b/contrib/spi/refint.example @@ -5,7 +5,7 @@ CREATE TABLE A ( ); CREATE UNIQUE INDEX AI ON A (ID); ---Columns REFB of table B and REFC of C are foreign keys referenting ID of A: +--Columns REFB of table B and REFC of C are foreign keys referencing ID of A: CREATE TABLE B ( REFB int4 diff --git a/contrib/spi/timetravel--1.0.sql b/contrib/spi/timetravel--1.0.sql deleted file mode 100644 index c34ca09965b..00000000000 --- a/contrib/spi/timetravel--1.0.sql +++ /dev/null @@ -1,19 +0,0 @@ -/* contrib/spi/timetravel--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION timetravel" to load this file. \quit - -CREATE FUNCTION timetravel() -RETURNS trigger -AS 'MODULE_PATHNAME' -LANGUAGE C; - -CREATE FUNCTION set_timetravel(name, int4) -RETURNS int4 -AS 'MODULE_PATHNAME' -LANGUAGE C RETURNS NULL ON NULL INPUT; - -CREATE FUNCTION get_timetravel(name) -RETURNS int4 -AS 'MODULE_PATHNAME' -LANGUAGE C RETURNS NULL ON NULL INPUT; diff --git a/contrib/spi/timetravel--unpackaged--1.0.sql b/contrib/spi/timetravel--unpackaged--1.0.sql deleted file mode 100644 index 121bceba9b2..00000000000 --- a/contrib/spi/timetravel--unpackaged--1.0.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* contrib/spi/timetravel--unpackaged--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION timetravel FROM unpackaged" to load this file. \quit - -ALTER EXTENSION timetravel ADD function timetravel(); -ALTER EXTENSION timetravel ADD function set_timetravel(name,integer); -ALTER EXTENSION timetravel ADD function get_timetravel(name); diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c deleted file mode 100644 index 00f661e6b69..00000000000 --- a/contrib/spi/timetravel.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * contrib/spi/timetravel.c - * - * - * timetravel.c -- function to get time travel feature - * using general triggers. - * - * Modified by BÖJTHE Zoltán, Hungary, mailto:urdesobt@axelero.hu - */ -#include "postgres.h" - -#include - -#include "access/htup_details.h" -#include "catalog/pg_type.h" -#include "commands/trigger.h" -#include "executor/spi.h" -#include "miscadmin.h" -#include "utils/builtins.h" -#include "utils/nabstime.h" -#include "utils/rel.h" - -PG_MODULE_MAGIC; - -/* AbsoluteTime currabstime(void); */ - -typedef struct -{ - char *ident; - SPIPlanPtr splan; -} EPlan; - -static EPlan *Plans = NULL; /* for UPDATE/DELETE */ -static int nPlans = 0; - -typedef struct _TTOffList -{ - struct _TTOffList *next; - char name[FLEXIBLE_ARRAY_MEMBER]; -} TTOffList; - -static TTOffList *TTOff = NULL; - -static int findTTStatus(char *name); -static EPlan *find_plan(char *ident, EPlan **eplan, int *nplans); - -/* - * timetravel () -- - * 1. IF an update affects tuple with stop_date eq INFINITY - * then form (and return) new tuple with start_date eq current date - * and stop_date eq INFINITY [ and update_user eq current user ] - * and all other column values as in new tuple, and insert tuple - * with old data and stop_date eq current date - * ELSE - skip updating of tuple. - * 2. IF a delete affects tuple with stop_date eq INFINITY - * then insert the same tuple with stop_date eq current date - * [ and delete_user eq current user ] - * ELSE - skip deletion of tuple. - * 3. On INSERT, if start_date is NULL then current date will be - * inserted, if stop_date is NULL then INFINITY will be inserted. - * [ and insert_user eq current user, update_user and delete_user - * eq NULL ] - * - * In CREATE TRIGGER you are to specify start_date and stop_date column - * names: - * EXECUTE PROCEDURE - * timetravel ('date_on', 'date_off' [,'insert_user', 'update_user', 'delete_user' ] ). - */ - -#define MaxAttrNum 5 -#define MinAttrNum 2 - -#define a_time_on 0 -#define a_time_off 1 -#define a_ins_user 2 -#define a_upd_user 3 -#define a_del_user 4 - -PG_FUNCTION_INFO_V1(timetravel); - -Datum /* have to return HeapTuple to Executor */ -timetravel(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int argc; - char **args; /* arguments */ - int attnum[MaxAttrNum]; /* fnumbers of start/stop columns */ - Datum oldtimeon, - oldtimeoff; - Datum newtimeon, - newtimeoff, - newuser, - nulltext; - Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ - char *relname; /* triggered relation name */ - Relation rel; /* triggered relation */ - HeapTuple trigtuple; - HeapTuple newtuple = NULL; - HeapTuple rettuple; - TupleDesc tupdesc; /* tuple description */ - int natts; /* # of attributes */ - EPlan *plan; /* prepared plan */ - char ident[2 * NAMEDATALEN]; - bool isnull; /* to know is some column NULL or not */ - bool isinsert = false; - int ret; - int i; - - /* - * Some checks first... - */ - - /* Called by trigger manager ? */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "timetravel: not fired by trigger manager"); - - /* Should be called for ROW trigger */ - if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) - elog(ERROR, "timetravel: must be fired for row"); - - /* Should be called BEFORE */ - if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event)) - elog(ERROR, "timetravel: must be fired before event"); - - /* INSERT ? */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - isinsert = true; - - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - newtuple = trigdata->tg_newtuple; - - trigtuple = trigdata->tg_trigtuple; - - rel = trigdata->tg_relation; - relname = SPI_getrelname(rel); - - /* check if TT is OFF for this relation */ - if (0 == findTTStatus(relname)) - { - /* OFF - nothing to do */ - pfree(relname); - return PointerGetDatum((newtuple != NULL) ? newtuple : trigtuple); - } - - trigger = trigdata->tg_trigger; - - argc = trigger->tgnargs; - if (argc != MinAttrNum && argc != MaxAttrNum) - elog(ERROR, "timetravel (%s): invalid (!= %d or %d) number of arguments %d", - relname, MinAttrNum, MaxAttrNum, trigger->tgnargs); - - args = trigger->tgargs; - tupdesc = rel->rd_att; - natts = tupdesc->natts; - - for (i = 0; i < MinAttrNum; i++) - { - attnum[i] = SPI_fnumber(tupdesc, args[i]); - if (attnum[i] <= 0) - elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]); - if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID) - elog(ERROR, "timetravel (%s): attribute %s must be of abstime type", - relname, args[i]); - } - for (; i < argc; i++) - { - attnum[i] = SPI_fnumber(tupdesc, args[i]); - if (attnum[i] <= 0) - elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]); - if (SPI_gettypeid(tupdesc, attnum[i]) != TEXTOID) - elog(ERROR, "timetravel (%s): attribute %s must be of text type", - relname, args[i]); - } - - /* create fields containing name */ - newuser = CStringGetTextDatum(GetUserNameFromId(GetUserId(), false)); - - nulltext = (Datum) NULL; - - if (isinsert) - { /* INSERT */ - int chnattrs = 0; - int chattrs[MaxAttrNum]; - Datum newvals[MaxAttrNum]; - bool newnulls[MaxAttrNum]; - - oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull); - if (isnull) - { - newvals[chnattrs] = GetCurrentAbsoluteTime(); - newnulls[chnattrs] = false; - chattrs[chnattrs] = attnum[a_time_on]; - chnattrs++; - } - - oldtimeoff = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_off], &isnull); - if (isnull) - { - if ((chnattrs == 0 && DatumGetInt32(oldtimeon) >= NOEND_ABSTIME) || - (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) >= NOEND_ABSTIME)) - elog(ERROR, "timetravel (%s): %s is infinity", relname, args[a_time_on]); - newvals[chnattrs] = NOEND_ABSTIME; - newnulls[chnattrs] = false; - chattrs[chnattrs] = attnum[a_time_off]; - chnattrs++; - } - else - { - if ((chnattrs == 0 && DatumGetInt32(oldtimeon) > DatumGetInt32(oldtimeoff)) || - (chnattrs > 0 && DatumGetInt32(newvals[a_time_on]) > DatumGetInt32(oldtimeoff))) - elog(ERROR, "timetravel (%s): %s gt %s", relname, args[a_time_on], args[a_time_off]); - } - - pfree(relname); - if (chnattrs <= 0) - return PointerGetDatum(trigtuple); - - if (argc == MaxAttrNum) - { - /* clear update_user value */ - newvals[chnattrs] = nulltext; - newnulls[chnattrs] = true; - chattrs[chnattrs] = attnum[a_upd_user]; - chnattrs++; - /* clear delete_user value */ - newvals[chnattrs] = nulltext; - newnulls[chnattrs] = true; - chattrs[chnattrs] = attnum[a_del_user]; - chnattrs++; - /* set insert_user value */ - newvals[chnattrs] = newuser; - newnulls[chnattrs] = false; - chattrs[chnattrs] = attnum[a_ins_user]; - chnattrs++; - } - rettuple = heap_modify_tuple_by_cols(trigtuple, tupdesc, - chnattrs, chattrs, - newvals, newnulls); - return PointerGetDatum(rettuple); - /* end of INSERT */ - } - - /* UPDATE/DELETE: */ - oldtimeon = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_on], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_on]); - - oldtimeoff = SPI_getbinval(trigtuple, tupdesc, attnum[a_time_off], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]); - - /* - * If DELETE/UPDATE of tuple with stop_date neq INFINITY then say upper - * Executor to skip operation for this tuple - */ - if (newtuple != NULL) - { /* UPDATE */ - newtimeon = SPI_getbinval(newtuple, tupdesc, attnum[a_time_on], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_on]); - - newtimeoff = SPI_getbinval(newtuple, tupdesc, attnum[a_time_off], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[a_time_off]); - - if (oldtimeon != newtimeon || oldtimeoff != newtimeoff) - elog(ERROR, "timetravel (%s): you cannot change %s and/or %s columns (use set_timetravel)", - relname, args[a_time_on], args[a_time_off]); - } - if (oldtimeoff != NOEND_ABSTIME) - { /* current record is a deleted/updated record */ - pfree(relname); - return PointerGetDatum(NULL); - } - - newtimeoff = GetCurrentAbsoluteTime(); - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "timetravel (%s): SPI_connect returned %d", relname, ret); - - /* Fetch tuple values and nulls */ - cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); - for (i = 0; i < natts; i++) - { - cvals[i] = SPI_getbinval(trigtuple, tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; - } - - /* change date column(s) */ - cvals[attnum[a_time_off] - 1] = newtimeoff; /* stop_date eq current date */ - cnulls[attnum[a_time_off] - 1] = ' '; - - if (!newtuple) - { /* DELETE */ - if (argc == MaxAttrNum) - { - cvals[attnum[a_del_user] - 1] = newuser; /* set delete user */ - cnulls[attnum[a_del_user] - 1] = ' '; - } - } - - /* - * Construct ident string as TriggerName $ TriggeredRelationId and try to - * find prepared execution plan. - */ - snprintf(ident, sizeof(ident), "%s$%u", trigger->tgname, rel->rd_id); - plan = find_plan(ident, &Plans, &nPlans); - - /* if there is no plan ... */ - if (plan->splan == NULL) - { - SPIPlanPtr pplan; - Oid *ctypes; - char sql[8192]; - char separ = ' '; - - /* allocate ctypes for preparation */ - ctypes = (Oid *) palloc(natts * sizeof(Oid)); - - /* - * Construct query: INSERT INTO _relation_ VALUES ($1, ...) - */ - snprintf(sql, sizeof(sql), "INSERT INTO %s VALUES (", relname); - for (i = 1; i <= natts; i++) - { - ctypes[i - 1] = SPI_gettypeid(tupdesc, i); - if (!(TupleDescAttr(tupdesc, i - 1)->attisdropped)) /* skip dropped columns */ - { - snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), "%c$%d", separ, i); - separ = ','; - } - } - snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ")"); - - elog(DEBUG4, "timetravel (%s) update: sql: %s", relname, sql); - - /* Prepare plan for query */ - pplan = SPI_prepare(sql, natts, ctypes); - if (pplan == NULL) - elog(ERROR, "timetravel (%s): SPI_prepare returned %s", relname, SPI_result_code_string(SPI_result)); - - /* - * Remember that SPI_prepare places plan in current memory context - - * so, we have to save plan in Top memory context for later use. - */ - if (SPI_keepplan(pplan)) - elog(ERROR, "timetravel (%s): SPI_keepplan failed", relname); - - plan->splan = pplan; - } - - /* - * Ok, execute prepared plan. - */ - ret = SPI_execp(plan->splan, cvals, cnulls, 0); - - if (ret < 0) - elog(ERROR, "timetravel (%s): SPI_execp returned %d", relname, ret); - - /* Tuple to return to upper Executor ... */ - if (newtuple) - { /* UPDATE */ - int chnattrs = 0; - int chattrs[MaxAttrNum]; - Datum newvals[MaxAttrNum]; - char newnulls[MaxAttrNum]; - - newvals[chnattrs] = newtimeoff; - newnulls[chnattrs] = ' '; - chattrs[chnattrs] = attnum[a_time_on]; - chnattrs++; - - newvals[chnattrs] = NOEND_ABSTIME; - newnulls[chnattrs] = ' '; - chattrs[chnattrs] = attnum[a_time_off]; - chnattrs++; - - if (argc == MaxAttrNum) - { - /* set update_user value */ - newvals[chnattrs] = newuser; - newnulls[chnattrs] = ' '; - chattrs[chnattrs] = attnum[a_upd_user]; - chnattrs++; - /* clear delete_user value */ - newvals[chnattrs] = nulltext; - newnulls[chnattrs] = 'n'; - chattrs[chnattrs] = attnum[a_del_user]; - chnattrs++; - /* set insert_user value */ - newvals[chnattrs] = nulltext; - newnulls[chnattrs] = 'n'; - chattrs[chnattrs] = attnum[a_ins_user]; - chnattrs++; - } - - /* - * Use SPI_modifytuple() here because we are inside SPI environment - * but rettuple must be allocated in caller's context. - */ - rettuple = SPI_modifytuple(rel, newtuple, chnattrs, chattrs, newvals, newnulls); - } - else - /* DELETE case */ - rettuple = trigtuple; - - SPI_finish(); /* don't forget say Bye to SPI mgr */ - - pfree(relname); - return PointerGetDatum(rettuple); -} - -/* - * set_timetravel (relname, on) -- - * turn timetravel for specified relation ON/OFF - */ -PG_FUNCTION_INFO_V1(set_timetravel); - -Datum -set_timetravel(PG_FUNCTION_ARGS) -{ - Name relname = PG_GETARG_NAME(0); - int32 on = PG_GETARG_INT32(1); - char *rname; - char *d; - char *s; - int32 ret; - TTOffList *prev, - *pp; - - prev = NULL; - for (pp = TTOff; pp; prev = pp, pp = pp->next) - { - if (namestrcmp(relname, pp->name) == 0) - break; - } - if (pp) - { - /* OFF currently */ - if (on != 0) - { - /* turn ON */ - if (prev) - prev->next = pp->next; - else - TTOff = pp->next; - free(pp); - } - ret = 0; - } - else - { - /* ON currently */ - if (on == 0) - { - /* turn OFF */ - s = rname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(relname))); - if (s) - { - pp = malloc(offsetof(TTOffList, name) + strlen(rname) + 1); - if (pp) - { - pp->next = NULL; - d = pp->name; - while (*s) - *d++ = tolower((unsigned char) *s++); - *d = '\0'; - if (prev) - prev->next = pp; - else - TTOff = pp; - } - pfree(rname); - } - } - ret = 1; - } - PG_RETURN_INT32(ret); -} - -/* - * get_timetravel (relname) -- - * get timetravel status for specified relation (ON/OFF) - */ -PG_FUNCTION_INFO_V1(get_timetravel); - -Datum -get_timetravel(PG_FUNCTION_ARGS) -{ - Name relname = PG_GETARG_NAME(0); - TTOffList *pp; - - for (pp = TTOff; pp; pp = pp->next) - { - if (namestrcmp(relname, pp->name) == 0) - PG_RETURN_INT32(0); - } - PG_RETURN_INT32(1); -} - -static int -findTTStatus(char *name) -{ - TTOffList *pp; - - for (pp = TTOff; pp; pp = pp->next) - if (pg_strcasecmp(name, pp->name) == 0) - return 0; - return 1; -} - -/* -AbsoluteTime -currabstime() -{ - return GetCurrentAbsoluteTime(); -} -*/ - -static EPlan * -find_plan(char *ident, EPlan **eplan, int *nplans) -{ - EPlan *newp; - int i; - - if (*nplans > 0) - { - for (i = 0; i < *nplans; i++) - { - if (strcmp((*eplan)[i].ident, ident) == 0) - break; - } - if (i != *nplans) - return (*eplan + i); - *eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan)); - newp = *eplan + i; - } - else - { - newp = *eplan = (EPlan *) malloc(sizeof(EPlan)); - (*nplans) = i = 0; - } - - newp->ident = strdup(ident); - newp->splan = NULL; - (*nplans)++; - - return newp; -} diff --git a/contrib/spi/timetravel.control b/contrib/spi/timetravel.control deleted file mode 100644 index 9b4bb6ba046..00000000000 --- a/contrib/spi/timetravel.control +++ /dev/null @@ -1,5 +0,0 @@ -# timetravel extension -comment = 'functions for implementing time travel' -default_version = '1.0' -module_pathname = '$libdir/timetravel' -relocatable = true diff --git a/contrib/spi/timetravel.example b/contrib/spi/timetravel.example deleted file mode 100644 index 35a7f654085..00000000000 --- a/contrib/spi/timetravel.example +++ /dev/null @@ -1,81 +0,0 @@ -drop table tttest; - -create table tttest ( - price_id int4, - price_val int4, - price_on abstime, - price_off abstime -); - -create unique index tttest_idx on tttest (price_id,price_off); -alter table tttest add column q1 text; -alter table tttest add column q2 int; -alter table tttest drop column q1; - -create trigger timetravel - before insert or delete or update on tttest - for each row - execute procedure - timetravel (price_on, price_off); - -insert into tttest values (1, 1, null, null); -insert into tttest(price_id, price_val) values (2, 2); -insert into tttest(price_id, price_val,price_off) values (3, 3, 'infinity'); - -insert into tttest(price_id, price_val,price_off) values (4, 4, - abstime('now'::timestamp - '100 days'::interval)); -insert into tttest(price_id, price_val,price_on) values (3, 3, 'infinity'); -- duplicate key - -select * from tttest; -delete from tttest where price_id = 2; -select * from tttest; --- what do we see ? - --- get current prices -select * from tttest where price_off = 'infinity'; - --- change price for price_id == 3 -update tttest set price_val = 30 where price_id = 3; -select * from tttest; - --- now we want to change price_id from 3 to 5 in ALL tuples --- but this gets us not what we need -update tttest set price_id = 5 where price_id = 3; -select * from tttest; - --- restore data as before last update: -select set_timetravel('tttest', 0); -- turn TT OFF! - -select get_timetravel('tttest'); -- check status - -delete from tttest where price_id = 5; -update tttest set price_off = 'infinity' where price_val = 30; -select * from tttest; - --- and try change price_id now! -update tttest set price_id = 5 where price_id = 3; -select * from tttest; --- isn't it what we need ? - -select set_timetravel('tttest', 1); -- turn TT ON! - -select get_timetravel('tttest'); -- check status - --- we want to correct some date -update tttest set price_on = 'Jan-01-1990 00:00:01' where price_id = 5 and - price_off <> 'infinity'; --- but this doesn't work - --- try in this way -select set_timetravel('tttest', 0); -- turn TT OFF! - -select get_timetravel('tttest'); -- check status - -update tttest set price_on = '01-Jan-1990 00:00:01' where price_id = 5 and - price_off <> 'infinity'; -select * from tttest; --- isn't it what we need ? - --- get price for price_id == 5 as it was '10-Jan-1990' -select * from tttest where price_id = 5 and - price_on <= '10-Jan-1990' and price_off > '10-Jan-1990'; diff --git a/contrib/tablefunc/tablefunc.c b/contrib/tablefunc/tablefunc.c index 59f90dc9479..e31be80828e 100644 --- a/contrib/tablefunc/tablefunc.c +++ b/contrib/tablefunc/tablefunc.c @@ -10,7 +10,7 @@ * And contributors: * Nabil Sayegh * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement @@ -48,41 +48,41 @@ PG_MODULE_MAGIC; static HTAB *load_categories_hash(char *cats_sql, MemoryContext per_query_ctx); static Tuplestorestate *get_crosstab_tuplestore(char *sql, - HTAB *crosstab_hash, - TupleDesc tupdesc, - MemoryContext per_query_ctx, - bool randomAccess); + HTAB *crosstab_hash, + TupleDesc tupdesc, + MemoryContext per_query_ctx, + bool randomAccess); static void validateConnectbyTupleDesc(TupleDesc tupdesc, bool show_branch, bool show_serial); static bool compatCrosstabTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); static void compatConnectbyTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); static void get_normal_pair(float8 *x1, float8 *x2); static Tuplestorestate *connectby(char *relname, - char *key_fld, - char *parent_key_fld, - char *orderby_fld, - char *branch_delim, - char *start_with, - int max_depth, - bool show_branch, - bool show_serial, - MemoryContext per_query_ctx, - bool randomAccess, - AttInMetadata *attinmeta); + char *key_fld, + char *parent_key_fld, + char *orderby_fld, + char *branch_delim, + char *start_with, + int max_depth, + bool show_branch, + bool show_serial, + MemoryContext per_query_ctx, + bool randomAccess, + AttInMetadata *attinmeta); static void build_tuplestore_recursively(char *key_fld, - char *parent_key_fld, - char *relname, - char *orderby_fld, - char *branch_delim, - char *start_with, - char *branch, - int level, - int *serial, - int max_depth, - bool show_branch, - bool show_serial, - MemoryContext per_query_ctx, - AttInMetadata *attinmeta, - Tuplestorestate *tupstore); + char *parent_key_fld, + char *relname, + char *orderby_fld, + char *branch_delim, + char *start_with, + char *branch, + int level, + int *serial, + int max_depth, + bool show_branch, + bool show_serial, + MemoryContext per_query_ctx, + AttInMetadata *attinmeta, + Tuplestorestate *tupstore); typedef struct { @@ -867,11 +867,8 @@ get_crosstab_tuplestore(char *sql, "tuple has %d columns but crosstab " \ "returns %d.", tupdesc->natts, result_ncols))); - /* allocate space */ - values = (char **) palloc(result_ncols * sizeof(char *)); - - /* and make sure it's clear */ - memset(values, '\0', result_ncols * sizeof(char *)); + /* allocate space and make sure it's clear */ + values = (char **) palloc0(result_ncols * sizeof(char *)); for (i = 0; i < proc; i++) { diff --git a/contrib/tablefunc/tablefunc.h b/contrib/tablefunc/tablefunc.h index 7d0773f82fc..f1e75463ff7 100644 --- a/contrib/tablefunc/tablefunc.h +++ b/contrib/tablefunc/tablefunc.h @@ -10,7 +10,7 @@ * And contributors: * Nabil Sayegh * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement diff --git a/contrib/tcn/tcn.c b/contrib/tcn/tcn.c index 43bdd92749d..5355a64c5e6 100644 --- a/contrib/tcn/tcn.c +++ b/contrib/tcn/tcn.c @@ -3,7 +3,7 @@ * tcn.c * triggered change notification support for PostgreSQL * - * Portions Copyright (c) 2011-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2011-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -136,9 +136,9 @@ triggered_change_notification(PG_FUNCTION_ARGS) elog(ERROR, "cache lookup failed for index %u", indexoid); index = (Form_pg_index) GETSTRUCT(indexTuple); /* we're only interested if it is the primary key and valid */ - if (index->indisprimary && IndexIsValid(index)) + if (index->indisprimary && index->indisvalid) { - int indnkeyatts = index->indnkeyatts; + int indnkeyatts = index->indnkeyatts; if (indnkeyatts > 0) { diff --git a/contrib/test_decoding/Makefile b/contrib/test_decoding/Makefile index 1d601d8144c..4afb1d963e5 100644 --- a/contrib/test_decoding/Makefile +++ b/contrib/test_decoding/Makefile @@ -3,9 +3,18 @@ MODULES = test_decoding PGFILEDESC = "test_decoding - example of a logical decoding output plugin" -# Note: because we don't tell the Makefile there are any regression tests, -# we have to clean those result files explicitly -EXTRA_CLEAN = $(pg_regress_clean_files) +REGRESS = ddl xact rewrite toast permissions decoding_in_xact \ + decoding_into_rel binary prepared replorigin time messages \ + spill slot truncate +ISOLATION = mxact delayed_startup ondisk_startup concurrent_ddl_dml \ + oldest_xmin snapshot_transfer + +REGRESS_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf +ISOLATION_OPTS = --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf + +# Disabled because these tests require "wal_level=logical", which +# typical installcheck users do not have (e.g. buildfarm clients). +NO_INSTALLCHECK = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -18,51 +27,8 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif -# Disabled because these tests require "wal_level=logical", which -# typical installcheck users do not have (e.g. buildfarm clients). -installcheck:; - # But it can nonetheless be very helpful to run tests on preexisting # installation, allow to do so, but only if requested explicitly. -installcheck-force: regresscheck-install-force isolationcheck-install-force - -check: regresscheck isolationcheck - -submake-regress: - $(MAKE) -C $(top_builddir)/src/test/regress all - -submake-isolation: - $(MAKE) -C $(top_builddir)/src/test/isolation all - -submake-test_decoding: - $(MAKE) -C $(top_builddir)/contrib/test_decoding - -REGRESSCHECKS=ddl xact rewrite toast permissions decoding_in_xact \ - decoding_into_rel binary prepared replorigin time messages \ - spill slot truncate - -regresscheck: | submake-regress submake-test_decoding temp-install - $(pg_regress_check) \ - --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf \ - $(REGRESSCHECKS) - -regresscheck-install-force: | submake-regress submake-test_decoding temp-install - $(pg_regress_installcheck) \ - $(REGRESSCHECKS) - -ISOLATIONCHECKS=mxact delayed_startup ondisk_startup concurrent_ddl_dml - -isolationcheck: | submake-isolation submake-test_decoding temp-install - $(pg_isolation_regress_check) \ - --temp-config $(top_srcdir)/contrib/test_decoding/logical.conf \ - $(ISOLATIONCHECKS) - -isolationcheck-install-force: all | submake-isolation submake-test_decoding temp-install - $(pg_isolation_regress_installcheck) \ - $(ISOLATIONCHECKS) - -.PHONY: submake-test_decoding submake-regress check \ - regresscheck regresscheck-install-force \ - isolationcheck isolationcheck-install-force - -temp-install: EXTRA_INSTALL=contrib/test_decoding +installcheck-force: + $(pg_regress_installcheck) $(REGRESS) + $(pg_isolation_regress_installcheck) $(ISOLATION) diff --git a/contrib/test_decoding/expected/ddl.out b/contrib/test_decoding/expected/ddl.out index 79c359d6e3d..2c999fd3eb7 100644 --- a/contrib/test_decoding/expected/ddl.out +++ b/contrib/test_decoding/expected/ddl.out @@ -17,8 +17,8 @@ HINT: Replication slot names may only contain lower case letters, numbers, and SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', 'frakbar'); ERROR: could not parse value "frakbar" for parameter "include-xids" CONTEXT: slot "regression_slot", output plugin "test_decoding", in the startup callback -SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'nonexistant-option', 'frakbar'); -ERROR: option "nonexistant-option" = "frakbar" is unknown +SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'nonexistent-option', 'frakbar'); +ERROR: option "nonexistent-option" = "frakbar" is unknown CONTEXT: slot "regression_slot", output plugin "test_decoding", in the startup callback SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', 'frakbar'); ERROR: could not parse value "frakbar" for parameter "include-xids" @@ -192,52 +192,6 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc COMMIT (33 rows) --- MERGE support -BEGIN; -MERGE INTO replication_example t - USING (SELECT i as id, i as data, i as num FROM generate_series(-20, 5) i) s - ON t.id = s.id - WHEN MATCHED AND t.id < 0 THEN - UPDATE SET somenum = somenum + 1 - WHEN MATCHED AND t.id >= 0 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.*); -COMMIT; -/* display results */ -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - data --------------------------------------------------------------------------------------------------------------------------------------------------- - BEGIN - table public.replication_example: INSERT: id[integer]:-20 somedata[integer]:-20 somenum[integer]:-20 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: INSERT: id[integer]:-19 somedata[integer]:-19 somenum[integer]:-19 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: INSERT: id[integer]:-18 somedata[integer]:-18 somenum[integer]:-18 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: INSERT: id[integer]:-17 somedata[integer]:-17 somenum[integer]:-17 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: INSERT: id[integer]:-16 somedata[integer]:-16 somenum[integer]:-16 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-15 somedata[integer]:-15 somenum[integer]:-14 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-14 somedata[integer]:-14 somenum[integer]:-13 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-13 somedata[integer]:-13 somenum[integer]:-12 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-12 somedata[integer]:-12 somenum[integer]:-11 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-11 somedata[integer]:-11 somenum[integer]:-10 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-10 somedata[integer]:-10 somenum[integer]:-9 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-9 somedata[integer]:-9 somenum[integer]:-8 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-8 somedata[integer]:-8 somenum[integer]:-7 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-7 somedata[integer]:-7 somenum[integer]:-6 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-6 somedata[integer]:-6 somenum[integer]:-5 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-5 somedata[integer]:-5 somenum[integer]:-4 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-4 somedata[integer]:-4 somenum[integer]:-3 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-3 somedata[integer]:-3 somenum[integer]:-2 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-2 somedata[integer]:-2 somenum[integer]:-1 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: UPDATE: id[integer]:-1 somedata[integer]:-1 somenum[integer]:0 zaphod1[integer]:null zaphod2[integer]:null - table public.replication_example: DELETE: id[integer]:0 - table public.replication_example: DELETE: id[integer]:1 - table public.replication_example: DELETE: id[integer]:2 - table public.replication_example: DELETE: id[integer]:3 - table public.replication_example: DELETE: id[integer]:4 - table public.replication_example: DELETE: id[integer]:5 - COMMIT -(28 rows) - CREATE TABLE tr_unique(id2 serial unique NOT NULL, data int); INSERT INTO tr_unique(data) VALUES(10); ALTER TABLE tr_unique RENAME TO tr_pkey; @@ -455,6 +409,24 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc COMMIT (6 rows) +-- check that DDL in aborted subtransactions handled correctly +CREATE TABLE tr_sub_ddl(data int); +BEGIN; +SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE text; +INSERT INTO tr_sub_ddl VALUES ('blah-blah'); +ROLLBACK TO SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE bigint; +INSERT INTO tr_sub_ddl VALUES(43); +COMMIT; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +-------------------------------------------------- + BEGIN + table public.tr_sub_ddl: INSERT: data[bigint]:43 + COMMIT +(3 rows) + /* * Check whether treating a table as a catalog table works somewhat */ diff --git a/contrib/test_decoding/expected/oldest_xmin.out b/contrib/test_decoding/expected/oldest_xmin.out new file mode 100644 index 00000000000..d1b4f17e3aa --- /dev/null +++ b/contrib/test_decoding/expected/oldest_xmin.out @@ -0,0 +1,30 @@ +Parsed test spec with 2 sessions + +starting permutation: s0_begin s0_getxid s1_begin s1_insert s0_alter s0_commit s0_checkpoint s0_get_changes s0_get_changes s1_commit s0_vacuum s0_get_changes +step s0_begin: BEGIN; +step s0_getxid: SELECT txid_current() IS NULL; +?column? + +f +step s1_begin: BEGIN; +step s1_insert: INSERT INTO harvest VALUES ((1, 2, 3)); +step s0_alter: ALTER TYPE basket DROP ATTRIBUTE mangos; +step s0_commit: COMMIT; +step s0_checkpoint: CHECKPOINT; +step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +data + +step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +data + +step s1_commit: COMMIT; +step s0_vacuum: VACUUM pg_attribute; +step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +data + +BEGIN +table public.harvest: INSERT: fruits[basket]:'(1,2,3)' +COMMIT +?column? + +stop diff --git a/contrib/test_decoding/expected/replorigin.out b/contrib/test_decoding/expected/replorigin.out index 8ea4ddda977..3b249f4856f 100644 --- a/contrib/test_decoding/expected/replorigin.out +++ b/contrib/test_decoding/expected/replorigin.out @@ -2,38 +2,38 @@ SET synchronous_commit = on; CREATE TABLE origin_tbl(id serial primary key, data text); CREATE TABLE target_tbl(id serial primary key, data text); -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); pg_replication_origin_create ------------------------------ 1 (1 row) -- ensure duplicate creations fail -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); ERROR: duplicate key value violates unique constraint "pg_replication_origin_roname_index" -DETAIL: Key (roname)=(test_decoding: regression_slot) already exists. +DETAIL: Key (roname)=(regress_test_decoding: regression_slot) already exists. --ensure deletions work (once) -SELECT pg_replication_origin_create('test_decoding: temp'); +SELECT pg_replication_origin_create('regress_test_decoding: temp'); pg_replication_origin_create ------------------------------ 2 (1 row) -SELECT pg_replication_origin_drop('test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); pg_replication_origin_drop ---------------------------- (1 row) -SELECT pg_replication_origin_drop('test_decoding: temp'); -ERROR: replication origin "test_decoding: temp" does not exist +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); +ERROR: replication origin "regress_test_decoding: temp" does not exist -- various failure checks for undefined slots -select pg_replication_origin_advance('test_decoding: temp', '0/1'); -ERROR: replication origin "test_decoding: temp" does not exist -select pg_replication_origin_session_setup('test_decoding: temp'); -ERROR: replication origin "test_decoding: temp" does not exist -select pg_replication_origin_progress('test_decoding: temp', true); -ERROR: replication origin "test_decoding: temp" does not exist +select pg_replication_origin_advance('regress_test_decoding: temp', '0/1'); +ERROR: replication origin "regress_test_decoding: temp" does not exist +select pg_replication_origin_session_setup('regress_test_decoding: temp'); +ERROR: replication origin "regress_test_decoding: temp" does not exist +select pg_replication_origin_progress('regress_test_decoding: temp', true); +ERROR: replication origin "regress_test_decoding: temp" does not exist SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); ?column? ---------- @@ -57,14 +57,14 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again'); -- mark session as replaying -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); pg_replication_origin_session_setup ------------------------------------- (1 row) -- ensure we prevent duplicate setup -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); ERROR: cannot setup replication origin when one is already setup SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded'); ?column? @@ -103,19 +103,19 @@ SELECT pg_replication_origin_session_reset(); (1 row) SELECT local_id, external_id, remote_lsn, local_lsn <> '0/0' FROM pg_replication_origin_status; - local_id | external_id | remote_lsn | ?column? -----------+--------------------------------+------------+---------- - 1 | test_decoding: regression_slot | 0/AABBCCDD | t + local_id | external_id | remote_lsn | ?column? +----------+----------------------------------------+------------+---------- + 1 | regress_test_decoding: regression_slot | 0/AABBCCDD | t (1 row) -- check replication progress identified by name is correct -SELECT pg_replication_origin_progress('test_decoding: regression_slot', false); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', false); pg_replication_origin_progress -------------------------------- 0/AABBCCDD (1 row) -SELECT pg_replication_origin_progress('test_decoding: regression_slot', true); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', true); pg_replication_origin_progress -------------------------------- 0/AABBCCDD @@ -146,7 +146,7 @@ SELECT pg_drop_replication_slot('regression_slot'); (1 row) -SELECT pg_replication_origin_drop('test_decoding: regression_slot'); +SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); pg_replication_origin_drop ---------------------------- diff --git a/contrib/test_decoding/expected/rewrite.out b/contrib/test_decoding/expected/rewrite.out index 4dcd4895438..b30999c436b 100644 --- a/contrib/test_decoding/expected/rewrite.out +++ b/contrib/test_decoding/expected/rewrite.out @@ -1,6 +1,61 @@ -- predictability SET synchronous_commit = on; DROP TABLE IF EXISTS replication_example; +-- Ensure there's tables with toast datums. To do so, we dynamically +-- create a function returning a large textblob. We want tables of +-- different kinds: mapped catalog table, unmapped catalog table, +-- shared catalog table and usertable. +CREATE FUNCTION exec(text) returns void language plpgsql volatile + AS $f$ + BEGIN + EXECUTE $1; + END; +$f$; +CREATE ROLE regress_justforcomments NOLOGIN; +SELECT exec( + format($outer$CREATE FUNCTION iamalongfunction() RETURNS TEXT IMMUTABLE LANGUAGE SQL AS $f$SELECT text %L$f$$outer$, + (SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i)))); + exec +------ + +(1 row) + +SELECT exec( + format($outer$COMMENT ON FUNCTION iamalongfunction() IS %L$outer$, + iamalongfunction())); + exec +------ + +(1 row) + +SELECT exec( + format($outer$COMMENT ON ROLE REGRESS_JUSTFORCOMMENTS IS %L$outer$, + iamalongfunction())); + exec +------ + +(1 row) + +CREATE TABLE iamalargetable AS SELECT iamalongfunction() longfunctionoutput; +-- verify toast usage +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_proc'::regclass)) > 0; + ?column? +---------- + t +(1 row) + +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_description'::regclass)) > 0; + ?column? +---------- + t +(1 row) + +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_shdescription'::regclass)) > 0; + ?column? +---------- + t +(1 row) + SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); ?column? ---------- @@ -48,6 +103,10 @@ COMMIT; -- repeated rewrites in different transactions VACUUM FULL pg_class; VACUUM FULL pg_class; +-- reindexing of important relations / indexes +REINDEX TABLE pg_class; +REINDEX INDEX pg_class_oid_index; +REINDEX INDEX pg_class_tblspc_relfilenode_index; INSERT INTO replication_example(somedata, testcolumn1) VALUES (5, 3); BEGIN; INSERT INTO replication_example(somedata, testcolumn1) VALUES (6, 4); @@ -76,6 +135,23 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc COMMIT (15 rows) +-- trigger repeated rewrites of a system catalog with a toast table, +-- that previously was buggy: 20180914021046.oi7dm4ra3ot2g2kt@alap3.anarazel.de +VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; +INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (8, 6, 1); +VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; +INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (9, 7, 1); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + data +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + BEGIN + table public.replication_example: INSERT: id[integer]:9 somedata[integer]:8 text[character varying]:null testcolumn1[integer]:6 testcolumn2[integer]:null testcolumn3[integer]:1 + COMMIT + BEGIN + table public.replication_example: INSERT: id[integer]:10 somedata[integer]:9 text[character varying]:null testcolumn1[integer]:7 testcolumn2[integer]:null testcolumn3[integer]:1 + COMMIT +(6 rows) + SELECT pg_drop_replication_slot('regression_slot'); pg_drop_replication_slot -------------------------- @@ -83,3 +159,6 @@ SELECT pg_drop_replication_slot('regression_slot'); (1 row) DROP TABLE IF EXISTS replication_example; +DROP FUNCTION iamalongfunction(); +DROP FUNCTION exec(text); +DROP ROLE regress_justforcomments; diff --git a/contrib/test_decoding/expected/slot.out b/contrib/test_decoding/expected/slot.out index 21e9d56f73b..1000171530f 100644 --- a/contrib/test_decoding/expected/slot.out +++ b/contrib/test_decoding/expected/slot.out @@ -30,6 +30,8 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t2', 'tes init (1 row) +SELECT pg_create_logical_replication_slot('foo', 'nonexistent'); +ERROR: could not access file "nonexistent": No such file or directory -- here we want to start a new session and wait till old one is gone select pg_backend_pid() as oldpid \gset \c - @@ -131,3 +133,254 @@ SELECT pg_drop_replication_slot('regression_slot1'); ERROR: replication slot "regression_slot1" does not exist SELECT pg_drop_replication_slot('regression_slot2'); ERROR: replication slot "regression_slot2" does not exist +-- slot advance with physical slot, error with non-reserved slot +SELECT slot_name FROM pg_create_physical_replication_slot('regression_slot3'); + slot_name +------------------ + regression_slot3 +(1 row) + +SELECT pg_replication_slot_advance('regression_slot3', '0/0'); -- invalid LSN +ERROR: invalid target WAL LSN +SELECT pg_replication_slot_advance('regression_slot3', '0/1'); -- error +ERROR: cannot advance replication slot that has not previously reserved WAL +SELECT pg_drop_replication_slot('regression_slot3'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +-- +-- Test copy functions for logical replication slots +-- +-- Create and copy logical slots +SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot1', 'test_decoding', false); + ?column? +---------- + init +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_no_change'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin', false, 'pgoutput'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin_temp', true, 'pgoutput'); + ?column? +---------- + copy +(1 row) + +-- Check all copied slots status +SELECT + o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + slot_name | plugin | temporary | slot_name | plugin | temporary +------------+---------------+-----------+---------------------------------+---------------+----------- + orig_slot1 | test_decoding | f | copied_slot1_change_plugin | pgoutput | f + orig_slot1 | test_decoding | f | copied_slot1_change_plugin_temp | pgoutput | t + orig_slot1 | test_decoding | f | copied_slot1_no_change | test_decoding | f +(3 rows) + +-- Now we have maximum 4 replication slots. Check slots are properly +-- released even when raise error during creating the target slot. +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error +ERROR: all replication slots are in use +HINT: Free one or increase max_replication_slots. +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('orig_slot1'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot1_no_change'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot1_change_plugin'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +-- Test based on the temporary logical slot +SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot2', 'test_decoding', true); + ?column? +---------- + init +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_no_change'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin', true, 'pgoutput'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin_temp', false, 'pgoutput'); + ?column? +---------- + copy +(1 row) + +-- Check all copied slots status +SELECT + o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + slot_name | plugin | temporary | slot_name | plugin | temporary +------------+---------------+-----------+---------------------------------+---------------+----------- + orig_slot2 | test_decoding | t | copied_slot2_change_plugin | pgoutput | t + orig_slot2 | test_decoding | t | copied_slot2_change_plugin_temp | pgoutput | f + orig_slot2 | test_decoding | t | copied_slot2_no_change | test_decoding | t +(3 rows) + +-- Cannot copy a logical slot to a physical slot +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error +ERROR: cannot copy physical replication slot "orig_slot2" as a logical replication slot +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('copied_slot2_change_plugin_temp'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +-- +-- Test copy functions for physical replication slots +-- +-- Create and copy physical slots +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot1', true); + ?column? +---------- + init +(1 row) + +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', false); + ?column? +---------- + init +(1 row) + +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_no_change'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_temp', true); + ?column? +---------- + copy +(1 row) + +-- Check all copied slots status. Since all slots don't reserve WAL we check only other fields. +SELECT slot_name, slot_type, temporary FROM pg_replication_slots; + slot_name | slot_type | temporary +------------------------+-----------+----------- + orig_slot1 | physical | f + orig_slot2 | physical | f + copied_slot1_no_change | physical | f + copied_slot1_temp | physical | t +(4 rows) + +-- Cannot copy a physical slot to a logical slot +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error +ERROR: cannot copy logical replication slot "orig_slot1" as a physical replication slot +-- Cannot copy a physical slot that doesn't reserve WAL +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error +ERROR: cannot copy a replication slot that doesn't reserve WAL +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('orig_slot1'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('orig_slot2'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot1_no_change'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +-- Test based on the temporary physical slot +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', true, true); + ?column? +---------- + init +(1 row) + +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_no_change'); + ?column? +---------- + copy +(1 row) + +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_notemp', false); + ?column? +---------- + copy +(1 row) + +-- Check all copied slots status +SELECT + o.slot_name, o.temporary, c.slot_name, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + slot_name | temporary | slot_name | temporary +------------+-----------+------------------------+----------- + orig_slot2 | t | copied_slot2_no_change | t + orig_slot2 | t | copied_slot2_notemp | f +(2 rows) + +SELECT pg_drop_replication_slot('orig_slot2'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot2_no_change'); + pg_drop_replication_slot +-------------------------- + +(1 row) + +SELECT pg_drop_replication_slot('copied_slot2_notemp'); + pg_drop_replication_slot +-------------------------- + +(1 row) + diff --git a/contrib/test_decoding/expected/snapshot_transfer.out b/contrib/test_decoding/expected/snapshot_transfer.out new file mode 100644 index 00000000000..87bed03f766 --- /dev/null +++ b/contrib/test_decoding/expected/snapshot_transfer.out @@ -0,0 +1,49 @@ +Parsed test spec with 2 sessions + +starting permutation: s0_begin s0_begin_sub0 s0_log_assignment s0_sub_get_base_snap s1_produce_new_snap s0_insert s0_end_sub0 s0_commit s0_get_changes +step s0_begin: BEGIN; +step s0_begin_sub0: SAVEPOINT s0; +step s0_log_assignment: SELECT txid_current() IS NULL; +?column? + +f +step s0_sub_get_base_snap: INSERT INTO dummy VALUES (0); +step s1_produce_new_snap: ALTER TABLE harvest ADD COLUMN mangos int; +step s0_insert: INSERT INTO harvest VALUES (1, 2, 3); +step s0_end_sub0: RELEASE SAVEPOINT s0; +step s0_commit: COMMIT; +step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +data + +BEGIN +table public.dummy: INSERT: i[integer]:0 +table public.harvest: INSERT: apples[integer]:1 pears[integer]:2 mangos[integer]:3 +COMMIT +?column? + +stop + +starting permutation: s0_begin s0_begin_sub0 s0_log_assignment s0_begin_sub1 s0_sub_get_base_snap s1_produce_new_snap s0_insert s0_end_sub1 s0_end_sub0 s0_commit s0_get_changes +step s0_begin: BEGIN; +step s0_begin_sub0: SAVEPOINT s0; +step s0_log_assignment: SELECT txid_current() IS NULL; +?column? + +f +step s0_begin_sub1: SAVEPOINT s1; +step s0_sub_get_base_snap: INSERT INTO dummy VALUES (0); +step s1_produce_new_snap: ALTER TABLE harvest ADD COLUMN mangos int; +step s0_insert: INSERT INTO harvest VALUES (1, 2, 3); +step s0_end_sub1: RELEASE SAVEPOINT s1; +step s0_end_sub0: RELEASE SAVEPOINT s0; +step s0_commit: COMMIT; +step s0_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); +data + +BEGIN +table public.dummy: INSERT: i[integer]:0 +table public.harvest: INSERT: apples[integer]:1 pears[integer]:2 mangos[integer]:3 +COMMIT +?column? + +stop diff --git a/contrib/test_decoding/expected/truncate.out b/contrib/test_decoding/expected/truncate.out index be851782066..1cf2ae835c8 100644 --- a/contrib/test_decoding/expected/truncate.out +++ b/contrib/test_decoding/expected/truncate.out @@ -1,3 +1,5 @@ +-- predictability +SET synchronous_commit = on; SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); ?column? ---------- diff --git a/contrib/test_decoding/specs/concurrent_ddl_dml.spec b/contrib/test_decoding/specs/concurrent_ddl_dml.spec index e7cea37d307..d16515e6f48 100644 --- a/contrib/test_decoding/specs/concurrent_ddl_dml.spec +++ b/contrib/test_decoding/specs/concurrent_ddl_dml.spec @@ -19,7 +19,6 @@ setup { SET synchronous_commit=on; } step "s1_init" { SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); } step "s1_begin" { BEGIN; } step "s1_insert_tbl1" { INSERT INTO tbl1 (val1, val2) VALUES (1, 1); } -step "s1_insert_tbl1_3col" { INSERT INTO tbl1 (val1, val2, val3) VALUES (1, 1, 1); } step "s1_insert_tbl2" { INSERT INTO tbl2 (val1, val2) VALUES (1, 1); } step "s1_insert_tbl2_3col" { INSERT INTO tbl2 (val1, val2, val3) VALUES (1, 1, 1); } step "s1_commit" { COMMIT; } @@ -29,15 +28,8 @@ setup { SET synchronous_commit=on; } step "s2_alter_tbl1_float" { ALTER TABLE tbl1 ALTER COLUMN val2 TYPE float; } step "s2_alter_tbl1_char" { ALTER TABLE tbl1 ALTER COLUMN val2 TYPE character varying; } -step "s2_alter_tbl1_text" { ALTER TABLE tbl1 ALTER COLUMN val2 TYPE text; } step "s2_alter_tbl1_boolean" { ALTER TABLE tbl1 ALTER COLUMN val2 TYPE boolean; } -step "s2_alter_tbl1_add_int" { ALTER TABLE tbl1 ADD COLUMN val3 INTEGER; } -step "s2_alter_tbl1_add_float" { ALTER TABLE tbl1 ADD COLUMN val3 FLOAT; } -step "s2_alter_tbl1_add_char" { ALTER TABLE tbl1 ADD COLUMN val3 character varying; } -step "s2_alter_tbl1_add_boolean" { ALTER TABLE tbl1 ADD COLUMN val3 BOOLEAN; } -step "s2_alter_tbl1_add_text" { ALTER TABLE tbl1 ADD COLUMN val3 TEXT; } - step "s2_alter_tbl2_float" { ALTER TABLE tbl2 ALTER COLUMN val2 TYPE float; } step "s2_alter_tbl2_char" { ALTER TABLE tbl2 ALTER COLUMN val2 TYPE character varying; } step "s2_alter_tbl2_text" { ALTER TABLE tbl2 ALTER COLUMN val2 TYPE text; } @@ -46,7 +38,6 @@ step "s2_alter_tbl2_boolean" { ALTER TABLE tbl2 ALTER COLUMN val2 TYPE boolean; step "s2_alter_tbl2_add_int" { ALTER TABLE tbl2 ADD COLUMN val3 INTEGER; } step "s2_alter_tbl2_add_float" { ALTER TABLE tbl2 ADD COLUMN val3 FLOAT; } step "s2_alter_tbl2_add_char" { ALTER TABLE tbl2 ADD COLUMN val3 character varying; } -step "s2_alter_tbl2_add_boolean" { ALTER TABLE tbl2 ADD COLUMN val3 BOOLEAN; } step "s2_alter_tbl2_add_text" { ALTER TABLE tbl2 ADD COLUMN val3 TEXT; } step "s2_alter_tbl2_drop_3rd_col" { ALTER TABLE tbl2 DROP COLUMN val3; } step "s2_alter_tbl2_3rd_char" { ALTER TABLE tbl2 ALTER COLUMN val3 TYPE character varying; } diff --git a/contrib/test_decoding/specs/oldest_xmin.spec b/contrib/test_decoding/specs/oldest_xmin.spec new file mode 100644 index 00000000000..6cb13e85cec --- /dev/null +++ b/contrib/test_decoding/specs/oldest_xmin.spec @@ -0,0 +1,42 @@ +# Test advancement of the slot's oldest xmin + +setup +{ + SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -- must be first write in xact + DROP TYPE IF EXISTS basket; + CREATE TYPE basket AS (apples integer, pears integer, mangos integer); + DROP TABLE IF EXISTS harvest; + CREATE TABLE harvest(fruits basket); +} + +teardown +{ + DROP TABLE IF EXISTS harvest; + DROP TYPE IF EXISTS basket; + SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); +} + +session "s0" +setup { SET synchronous_commit=on; } +step "s0_begin" { BEGIN; } +step "s0_getxid" { SELECT txid_current() IS NULL; } +step "s0_alter" { ALTER TYPE basket DROP ATTRIBUTE mangos; } +step "s0_commit" { COMMIT; } +step "s0_checkpoint" { CHECKPOINT; } +step "s0_vacuum" { VACUUM pg_attribute; } +step "s0_get_changes" { SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); } + +session "s1" +setup { SET synchronous_commit=on; } +step "s1_begin" { BEGIN; } +step "s1_insert" { INSERT INTO harvest VALUES ((1, 2, 3)); } +step "s1_commit" { COMMIT; } + +# Checkpoint with following get_changes forces xmin advancement. We do +# get_changes twice because if one more xl_running_xacts record had slipped +# before our CHECKPOINT, xmin will be advanced only on this record, thus not +# reaching value needed for vacuuming corresponding pg_attribute entry. ALTER of +# composite type is a rare form of DDL which allows T1 to see the tuple which +# will be removed (xmax set) before T1 commits. That is, interlocking doesn't +# forbid modifying catalog after someone read it (and didn't commit yet). +permutation "s0_begin" "s0_getxid" "s1_begin" "s1_insert" "s0_alter" "s0_commit" "s0_checkpoint" "s0_get_changes" "s0_get_changes""s1_commit" "s0_vacuum" "s0_get_changes" diff --git a/contrib/test_decoding/specs/snapshot_transfer.spec b/contrib/test_decoding/specs/snapshot_transfer.spec new file mode 100644 index 00000000000..ae81e8f102d --- /dev/null +++ b/contrib/test_decoding/specs/snapshot_transfer.spec @@ -0,0 +1,43 @@ +# Test snapshot transfer from subxact to top-level and receival of later snaps. + +setup +{ + SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); -- must be first write in xact + DROP TABLE IF EXISTS dummy; + CREATE TABLE dummy(i int); + DROP TABLE IF EXISTS harvest; + CREATE TABLE harvest(apples int, pears int); +} + +teardown +{ + DROP TABLE IF EXISTS harvest; + DROP TABLE IF EXISTS dummy; + SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); +} + +session "s0" +setup { SET synchronous_commit=on; } +step "s0_begin" { BEGIN; } +step "s0_begin_sub0" { SAVEPOINT s0; } +step "s0_log_assignment" { SELECT txid_current() IS NULL; } +step "s0_begin_sub1" { SAVEPOINT s1; } +step "s0_sub_get_base_snap" { INSERT INTO dummy VALUES (0); } +step "s0_insert" { INSERT INTO harvest VALUES (1, 2, 3); } +step "s0_end_sub0" { RELEASE SAVEPOINT s0; } +step "s0_end_sub1" { RELEASE SAVEPOINT s1; } +step "s0_commit" { COMMIT; } +step "s0_get_changes" { SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); } + +session "s1" +setup { SET synchronous_commit=on; } +step "s1_produce_new_snap" { ALTER TABLE harvest ADD COLUMN mangos int; } + +# start top-level without base snap, get base snap in subxact, then create new +# snap and make sure it is queued. +permutation "s0_begin" "s0_begin_sub0" "s0_log_assignment" "s0_sub_get_base_snap" "s1_produce_new_snap" "s0_insert" "s0_end_sub0" "s0_commit" "s0_get_changes" + +# In previous test, we firstly associated subxact with xact and only then got +# base snap; now nest one more subxact to get snap first and only then (at +# commit) associate it with toplevel. +permutation "s0_begin" "s0_begin_sub0" "s0_log_assignment" "s0_begin_sub1" "s0_sub_get_base_snap" "s1_produce_new_snap" "s0_insert" "s0_end_sub1" "s0_end_sub0" "s0_commit" "s0_get_changes" diff --git a/contrib/test_decoding/sql/ddl.sql b/contrib/test_decoding/sql/ddl.sql index 0e608b252fa..856495c9526 100644 --- a/contrib/test_decoding/sql/ddl.sql +++ b/contrib/test_decoding/sql/ddl.sql @@ -9,7 +9,7 @@ SELECT 'init' FROM pg_create_logical_replication_slot('Invalid Name', 'test_deco -- fail twice because of an invalid parameter values SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', 'frakbar'); -SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'nonexistant-option', 'frakbar'); +SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'nonexistent-option', 'frakbar'); SELECT 'init' FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', 'frakbar'); -- succeed once @@ -93,22 +93,6 @@ COMMIT; /* display results */ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); --- MERGE support -BEGIN; -MERGE INTO replication_example t - USING (SELECT i as id, i as data, i as num FROM generate_series(-20, 5) i) s - ON t.id = s.id - WHEN MATCHED AND t.id < 0 THEN - UPDATE SET somenum = somenum + 1 - WHEN MATCHED AND t.id >= 0 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.*); -COMMIT; - -/* display results */ -SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); - CREATE TABLE tr_unique(id2 serial unique NOT NULL, data int); INSERT INTO tr_unique(data) VALUES(10); ALTER TABLE tr_unique RENAME TO tr_pkey; @@ -250,6 +234,19 @@ INSERT INTO tr_sub(path) VALUES ('5-top-1-#1'); COMMIT; +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +-- check that DDL in aborted subtransactions handled correctly +CREATE TABLE tr_sub_ddl(data int); +BEGIN; +SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE text; +INSERT INTO tr_sub_ddl VALUES ('blah-blah'); +ROLLBACK TO SAVEPOINT a; +ALTER TABLE tr_sub_ddl ALTER COLUMN data TYPE bigint; +INSERT INTO tr_sub_ddl VALUES(43); +COMMIT; + SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); diff --git a/contrib/test_decoding/sql/replorigin.sql b/contrib/test_decoding/sql/replorigin.sql index 451cd4bc3b2..8979b306160 100644 --- a/contrib/test_decoding/sql/replorigin.sql +++ b/contrib/test_decoding/sql/replorigin.sql @@ -4,19 +4,19 @@ SET synchronous_commit = on; CREATE TABLE origin_tbl(id serial primary key, data text); CREATE TABLE target_tbl(id serial primary key, data text); -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); -- ensure duplicate creations fail -SELECT pg_replication_origin_create('test_decoding: regression_slot'); +SELECT pg_replication_origin_create('regress_test_decoding: regression_slot'); --ensure deletions work (once) -SELECT pg_replication_origin_create('test_decoding: temp'); -SELECT pg_replication_origin_drop('test_decoding: temp'); -SELECT pg_replication_origin_drop('test_decoding: temp'); +SELECT pg_replication_origin_create('regress_test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); +SELECT pg_replication_origin_drop('regress_test_decoding: temp'); -- various failure checks for undefined slots -select pg_replication_origin_advance('test_decoding: temp', '0/1'); -select pg_replication_origin_session_setup('test_decoding: temp'); -select pg_replication_origin_progress('test_decoding: temp', true); +select pg_replication_origin_advance('regress_test_decoding: temp', '0/1'); +select pg_replication_origin_session_setup('regress_test_decoding: temp'); +select pg_replication_origin_progress('regress_test_decoding: temp', true); SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); @@ -31,10 +31,10 @@ SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'inc INSERT INTO origin_tbl(data) VALUES ('will be replicated, but not decoded again'); -- mark session as replaying -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); -- ensure we prevent duplicate setup -SELECT pg_replication_origin_session_setup('test_decoding: regression_slot'); +SELECT pg_replication_origin_session_setup('regress_test_decoding: regression_slot'); SELECT '' FROM pg_logical_emit_message(false, 'test', 'this message will not be decoded'); @@ -54,8 +54,8 @@ SELECT pg_replication_origin_session_reset(); SELECT local_id, external_id, remote_lsn, local_lsn <> '0/0' FROM pg_replication_origin_status; -- check replication progress identified by name is correct -SELECT pg_replication_origin_progress('test_decoding: regression_slot', false); -SELECT pg_replication_origin_progress('test_decoding: regression_slot', true); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', false); +SELECT pg_replication_origin_progress('regress_test_decoding: regression_slot', true); -- ensure reset requires previously setup state SELECT pg_replication_origin_session_reset(); @@ -68,4 +68,4 @@ INSERT INTO origin_tbl(data) VALUES ('will be replicated'); SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1', 'only-local', '1'); SELECT pg_drop_replication_slot('regression_slot'); -SELECT pg_replication_origin_drop('test_decoding: regression_slot'); +SELECT pg_replication_origin_drop('regress_test_decoding: regression_slot'); diff --git a/contrib/test_decoding/sql/rewrite.sql b/contrib/test_decoding/sql/rewrite.sql index 8a7329423de..62dead3a9b1 100644 --- a/contrib/test_decoding/sql/rewrite.sql +++ b/contrib/test_decoding/sql/rewrite.sql @@ -3,6 +3,35 @@ SET synchronous_commit = on; DROP TABLE IF EXISTS replication_example; +-- Ensure there's tables with toast datums. To do so, we dynamically +-- create a function returning a large textblob. We want tables of +-- different kinds: mapped catalog table, unmapped catalog table, +-- shared catalog table and usertable. +CREATE FUNCTION exec(text) returns void language plpgsql volatile + AS $f$ + BEGIN + EXECUTE $1; + END; +$f$; +CREATE ROLE regress_justforcomments NOLOGIN; + +SELECT exec( + format($outer$CREATE FUNCTION iamalongfunction() RETURNS TEXT IMMUTABLE LANGUAGE SQL AS $f$SELECT text %L$f$$outer$, + (SELECT repeat(string_agg(to_char(g.i, 'FM0000'), ''), 50) FROM generate_series(1, 500) g(i)))); +SELECT exec( + format($outer$COMMENT ON FUNCTION iamalongfunction() IS %L$outer$, + iamalongfunction())); +SELECT exec( + format($outer$COMMENT ON ROLE REGRESS_JUSTFORCOMMENTS IS %L$outer$, + iamalongfunction())); +CREATE TABLE iamalargetable AS SELECT iamalongfunction() longfunctionoutput; + +-- verify toast usage +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_proc'::regclass)) > 0; +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_description'::regclass)) > 0; +SELECT pg_relation_size((SELECT reltoastrelid FROM pg_class WHERE oid = 'pg_shdescription'::regclass)) > 0; + + SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); CREATE TABLE replication_example(id SERIAL PRIMARY KEY, somedata int, text varchar(120)); INSERT INTO replication_example(somedata) VALUES (1); @@ -45,6 +74,11 @@ COMMIT; VACUUM FULL pg_class; VACUUM FULL pg_class; +-- reindexing of important relations / indexes +REINDEX TABLE pg_class; +REINDEX INDEX pg_class_oid_index; +REINDEX INDEX pg_class_tblspc_relfilenode_index; + INSERT INTO replication_example(somedata, testcolumn1) VALUES (5, 3); BEGIN; @@ -57,6 +91,17 @@ COMMIT; CHECKPOINT; SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); -SELECT pg_drop_replication_slot('regression_slot'); +-- trigger repeated rewrites of a system catalog with a toast table, +-- that previously was buggy: 20180914021046.oi7dm4ra3ot2g2kt@alap3.anarazel.de +VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; +INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (8, 6, 1); +VACUUM FULL pg_proc; VACUUM FULL pg_description; VACUUM FULL pg_shdescription; VACUUM FULL iamalargetable; +INSERT INTO replication_example(somedata, testcolumn1, testcolumn3) VALUES (9, 7, 1); +SELECT data FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1'); + +SELECT pg_drop_replication_slot('regression_slot'); DROP TABLE IF EXISTS replication_example; +DROP FUNCTION iamalongfunction(); +DROP FUNCTION exec(text); +DROP ROLE regress_justforcomments; diff --git a/contrib/test_decoding/sql/slot.sql b/contrib/test_decoding/sql/slot.sql index 706340c1d8d..6d83fb26782 100644 --- a/contrib/test_decoding/sql/slot.sql +++ b/contrib/test_decoding/sql/slot.sql @@ -9,6 +9,8 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_p', 'test SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot_t2', 'test_decoding', true); +SELECT pg_create_logical_replication_slot('foo', 'nonexistent'); + -- here we want to start a new session and wait till old one is gone select pg_backend_pid() as oldpid \gset \c - @@ -68,3 +70,103 @@ SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot1', 'test_ -- both should error as they should be dropped on error SELECT pg_drop_replication_slot('regression_slot1'); SELECT pg_drop_replication_slot('regression_slot2'); + +-- slot advance with physical slot, error with non-reserved slot +SELECT slot_name FROM pg_create_physical_replication_slot('regression_slot3'); +SELECT pg_replication_slot_advance('regression_slot3', '0/0'); -- invalid LSN +SELECT pg_replication_slot_advance('regression_slot3', '0/1'); -- error +SELECT pg_drop_replication_slot('regression_slot3'); + +-- +-- Test copy functions for logical replication slots +-- + +-- Create and copy logical slots +SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot1', 'test_decoding', false); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_no_change'); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin', false, 'pgoutput'); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'copied_slot1_change_plugin_temp', true, 'pgoutput'); + +-- Check all copied slots status +SELECT + o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + +-- Now we have maximum 4 replication slots. Check slots are properly +-- released even when raise error during creating the target slot. +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error + +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('orig_slot1'); +SELECT pg_drop_replication_slot('copied_slot1_no_change'); +SELECT pg_drop_replication_slot('copied_slot1_change_plugin'); + +-- Test based on the temporary logical slot +SELECT 'init' FROM pg_create_logical_replication_slot('orig_slot2', 'test_decoding', true); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_no_change'); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin', true, 'pgoutput'); +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot2', 'copied_slot2_change_plugin_temp', false, 'pgoutput'); + +-- Check all copied slots status +SELECT + o.slot_name, o.plugin, o.temporary, c.slot_name, c.plugin, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn AND o.confirmed_flush_lsn = c.confirmed_flush_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + +-- Cannot copy a logical slot to a physical slot +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error + +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('copied_slot2_change_plugin_temp'); + +-- +-- Test copy functions for physical replication slots +-- + +-- Create and copy physical slots +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot1', true); +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', false); +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_no_change'); +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot1', 'copied_slot1_temp', true); + +-- Check all copied slots status. Since all slots don't reserve WAL we check only other fields. +SELECT slot_name, slot_type, temporary FROM pg_replication_slots; + +-- Cannot copy a physical slot to a logical slot +SELECT 'copy' FROM pg_copy_logical_replication_slot('orig_slot1', 'failed'); -- error + +-- Cannot copy a physical slot that doesn't reserve WAL +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'failed'); -- error + +-- temporary slots were dropped automatically +SELECT pg_drop_replication_slot('orig_slot1'); +SELECT pg_drop_replication_slot('orig_slot2'); +SELECT pg_drop_replication_slot('copied_slot1_no_change'); + +-- Test based on the temporary physical slot +SELECT 'init' FROM pg_create_physical_replication_slot('orig_slot2', true, true); +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_no_change'); +SELECT 'copy' FROM pg_copy_physical_replication_slot('orig_slot2', 'copied_slot2_notemp', false); + +-- Check all copied slots status +SELECT + o.slot_name, o.temporary, c.slot_name, c.temporary +FROM + (SELECT * FROM pg_replication_slots WHERE slot_name LIKE 'orig%') as o + LEFT JOIN pg_replication_slots as c ON o.restart_lsn = c.restart_lsn +WHERE + o.slot_name != c.slot_name +ORDER BY o.slot_name, c.slot_name; + +SELECT pg_drop_replication_slot('orig_slot2'); +SELECT pg_drop_replication_slot('copied_slot2_no_change'); +SELECT pg_drop_replication_slot('copied_slot2_notemp'); diff --git a/contrib/test_decoding/sql/truncate.sql b/contrib/test_decoding/sql/truncate.sql index 88f113fd5b1..5aecdf0881f 100644 --- a/contrib/test_decoding/sql/truncate.sql +++ b/contrib/test_decoding/sql/truncate.sql @@ -1,3 +1,6 @@ +-- predictability +SET synchronous_commit = on; + SELECT 'init' FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding'); CREATE TABLE tab1 (id serial unique, data int); diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c index e192d5b4ad4..6c33c4bdedb 100644 --- a/contrib/test_decoding/test_decoding.c +++ b/contrib/test_decoding/test_decoding.c @@ -3,7 +3,7 @@ * test_decoding.c * example logical decoding output plugin * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/test_decoding/test_decoding.c @@ -24,7 +24,7 @@ PG_MODULE_MAGIC; -/* These must be available to pg_dlsym() */ +/* These must be available to dlsym() */ extern void _PG_init(void); extern void _PG_output_plugin_init(OutputPluginCallbacks *cb); @@ -39,29 +39,29 @@ typedef struct } TestDecodingData; static void pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, - bool is_init); + bool is_init); static void pg_decode_shutdown(LogicalDecodingContext *ctx); static void pg_decode_begin_txn(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn); + ReorderBufferTXN *txn); static void pg_output_begin(LogicalDecodingContext *ctx, - TestDecodingData *data, - ReorderBufferTXN *txn, - bool last_write); + TestDecodingData *data, + ReorderBufferTXN *txn, + bool last_write); static void pg_decode_commit_txn(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, XLogRecPtr commit_lsn); + ReorderBufferTXN *txn, XLogRecPtr commit_lsn); static void pg_decode_change(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, Relation rel, - ReorderBufferChange *change); + ReorderBufferTXN *txn, Relation rel, + ReorderBufferChange *change); static void pg_decode_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change); static bool pg_decode_filter(LogicalDecodingContext *ctx, - RepOriginId origin_id); + RepOriginId origin_id); static void pg_decode_message(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, XLogRecPtr message_lsn, - bool transactional, const char *prefix, - Size sz, const char *message); + ReorderBufferTXN *txn, XLogRecPtr message_lsn, + bool transactional, const char *prefix, + Size sz, const char *message); void _PG_init(void) @@ -319,13 +319,6 @@ static void tuple_to_stringinfo(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, bool skip_nulls) { int natt; - Oid oid; - - /* print oid of tuple, it's not included in the TupleDesc */ - if ((oid = HeapTupleHeaderGetOid(tuple->t_data)) != InvalidOid) - { - appendStringInfo(s, " oid[oid]:%u", oid); - } /* print all columns individually */ for (natt = 0; natt < tupdesc->natts; natt++) @@ -525,9 +518,9 @@ pg_decode_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, || change->data.truncate.cascade) { if (change->data.truncate.restart_seqs) - appendStringInfo(ctx->out, " restart_seqs"); + appendStringInfoString(ctx->out, " restart_seqs"); if (change->data.truncate.cascade) - appendStringInfo(ctx->out, " cascade"); + appendStringInfoString(ctx->out, " cascade"); } else appendStringInfoString(ctx->out, " (no-flags)"); diff --git a/contrib/tsm_system_rows/tsm_system_rows.c b/contrib/tsm_system_rows/tsm_system_rows.c index 83f841f0c2e..e6dbf6bc0dc 100644 --- a/contrib/tsm_system_rows/tsm_system_rows.c +++ b/contrib/tsm_system_rows/tsm_system_rows.c @@ -17,7 +17,7 @@ * won't visit blocks added after the first scan, but that is fine since * such blocks shouldn't contain any visible tuples anyway. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,8 +32,7 @@ #include "access/tsmapi.h" #include "catalog/pg_type.h" #include "miscadmin.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "utils/sampling.h" PG_MODULE_MAGIC; @@ -46,7 +45,6 @@ typedef struct { uint32 seed; /* random seed */ int64 ntuples; /* number of tuples to return */ - int64 donetuples; /* number of tuples already returned */ OffsetNumber lt; /* last tuple returned from current block */ BlockNumber doneblocks; /* number of already-scanned blocks */ BlockNumber lb; /* last block visited */ @@ -57,21 +55,20 @@ typedef struct } SystemRowsSamplerData; static void system_rows_samplescangetsamplesize(PlannerInfo *root, - RelOptInfo *baserel, - List *paramexprs, - BlockNumber *pages, - double *tuples); + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); static void system_rows_initsamplescan(SampleScanState *node, - int eflags); + int eflags); static void system_rows_beginsamplescan(SampleScanState *node, - Datum *params, - int nparams, - uint32 seed); -static BlockNumber system_rows_nextsampleblock(SampleScanState *node); + Datum *params, + int nparams, + uint32 seed); +static BlockNumber system_rows_nextsampleblock(SampleScanState *node, BlockNumber nblocks); static OffsetNumber system_rows_nextsampletuple(SampleScanState *node, - BlockNumber blockno, - OffsetNumber maxoffset); -static bool SampleOffsetVisible(OffsetNumber tupoffset, HeapScanDesc scan); + BlockNumber blockno, + OffsetNumber maxoffset); static uint32 random_relative_prime(uint32 n, SamplerRandomState randstate); @@ -187,7 +184,6 @@ system_rows_beginsamplescan(SampleScanState *node, sampler->seed = seed; sampler->ntuples = ntuples; - sampler->donetuples = 0; sampler->lt = InvalidOffsetNumber; sampler->doneblocks = 0; /* lb will be initialized during first NextSampleBlock call */ @@ -206,10 +202,9 @@ system_rows_beginsamplescan(SampleScanState *node, * Uses linear probing algorithm for picking next block. */ static BlockNumber -system_rows_nextsampleblock(SampleScanState *node) +system_rows_nextsampleblock(SampleScanState *node, BlockNumber nblocks) { SystemRowsSamplerData *sampler = (SystemRowsSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; /* First call within scan? */ if (sampler->doneblocks == 0) @@ -221,14 +216,14 @@ system_rows_nextsampleblock(SampleScanState *node) SamplerRandomState randstate; /* If relation is empty, there's nothing to scan */ - if (scan->rs_nblocks == 0) + if (nblocks == 0) return InvalidBlockNumber; /* We only need an RNG during this setup step */ sampler_random_init_state(sampler->seed, randstate); /* Compute nblocks/firstblock/step only once per query */ - sampler->nblocks = scan->rs_nblocks; + sampler->nblocks = nblocks; /* Choose random starting block within the relation */ /* (Actually this is the predecessor of the first block visited) */ @@ -245,7 +240,7 @@ system_rows_nextsampleblock(SampleScanState *node) /* If we've read all blocks or returned all needed tuples, we're done */ if (++sampler->doneblocks > sampler->nblocks || - sampler->donetuples >= sampler->ntuples) + node->donetuples >= sampler->ntuples) return InvalidBlockNumber; /* @@ -258,7 +253,7 @@ system_rows_nextsampleblock(SampleScanState *node) { /* Advance lb, using uint64 arithmetic to forestall overflow */ sampler->lb = ((uint64) sampler->lb + sampler->step) % sampler->nblocks; - } while (sampler->lb >= scan->rs_nblocks); + } while (sampler->lb >= nblocks); return sampler->lb; } @@ -278,76 +273,27 @@ system_rows_nextsampletuple(SampleScanState *node, OffsetNumber maxoffset) { SystemRowsSamplerData *sampler = (SystemRowsSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; OffsetNumber tupoffset = sampler->lt; /* Quit if we've returned all needed tuples */ - if (sampler->donetuples >= sampler->ntuples) + if (node->donetuples >= sampler->ntuples) return InvalidOffsetNumber; - /* - * Because we should only count visible tuples as being returned, we need - * to search for a visible tuple rather than just let the core code do it. - */ - - /* We rely on the data accumulated in pagemode access */ - Assert(scan->rs_pageatatime); - for (;;) - { - /* Advance to next possible offset on page */ - if (tupoffset == InvalidOffsetNumber) - tupoffset = FirstOffsetNumber; - else - tupoffset++; - - /* Done? */ - if (tupoffset > maxoffset) - { - tupoffset = InvalidOffsetNumber; - break; - } + /* Advance to next possible offset on page */ + if (tupoffset == InvalidOffsetNumber) + tupoffset = FirstOffsetNumber; + else + tupoffset++; - /* Found a candidate? */ - if (SampleOffsetVisible(tupoffset, scan)) - { - sampler->donetuples++; - break; - } - } + /* Done? */ + if (tupoffset > maxoffset) + tupoffset = InvalidOffsetNumber; sampler->lt = tupoffset; return tupoffset; } -/* - * Check if tuple offset is visible - * - * In pageatatime mode, heapgetpage() already did visibility checks, - * so just look at the info it left in rs_vistuples[]. - */ -static bool -SampleOffsetVisible(OffsetNumber tupoffset, HeapScanDesc scan) -{ - int start = 0, - end = scan->rs_ntuples - 1; - - while (start <= end) - { - int mid = (start + end) / 2; - OffsetNumber curoffset = scan->rs_vistuples[mid]; - - if (tupoffset == curoffset) - return true; - else if (tupoffset < curoffset) - end = mid - 1; - else - start = mid + 1; - } - - return false; -} - /* * Compute greatest common divisor of two uint32's. */ diff --git a/contrib/tsm_system_time/tsm_system_time.c b/contrib/tsm_system_time/tsm_system_time.c index f0c220aa4ac..ed486c4696b 100644 --- a/contrib/tsm_system_time/tsm_system_time.c +++ b/contrib/tsm_system_time/tsm_system_time.c @@ -13,7 +13,7 @@ * However, we do what we can to reduce surprising behavior by selecting * the sampling pattern just once per query, much as in tsm_system_rows. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,17 +24,13 @@ #include "postgres.h" -#ifdef _MSC_VER -#include /* for _isnan */ -#endif #include #include "access/relscan.h" #include "access/tsmapi.h" #include "catalog/pg_type.h" #include "miscadmin.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "utils/sampling.h" #include "utils/spccache.h" @@ -59,20 +55,20 @@ typedef struct } SystemTimeSamplerData; static void system_time_samplescangetsamplesize(PlannerInfo *root, - RelOptInfo *baserel, - List *paramexprs, - BlockNumber *pages, - double *tuples); + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); static void system_time_initsamplescan(SampleScanState *node, - int eflags); + int eflags); static void system_time_beginsamplescan(SampleScanState *node, - Datum *params, - int nparams, - uint32 seed); -static BlockNumber system_time_nextsampleblock(SampleScanState *node); + Datum *params, + int nparams, + uint32 seed); +static BlockNumber system_time_nextsampleblock(SampleScanState *node, BlockNumber nblocks); static OffsetNumber system_time_nextsampletuple(SampleScanState *node, - BlockNumber blockno, - OffsetNumber maxoffset); + BlockNumber blockno, + OffsetNumber maxoffset); static uint32 random_relative_prime(uint32 n, SamplerRandomState randstate); @@ -216,10 +212,9 @@ system_time_beginsamplescan(SampleScanState *node, * Uses linear probing algorithm for picking next block. */ static BlockNumber -system_time_nextsampleblock(SampleScanState *node) +system_time_nextsampleblock(SampleScanState *node, BlockNumber nblocks) { SystemTimeSamplerData *sampler = (SystemTimeSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; instr_time cur_time; /* First call within scan? */ @@ -232,14 +227,14 @@ system_time_nextsampleblock(SampleScanState *node) SamplerRandomState randstate; /* If relation is empty, there's nothing to scan */ - if (scan->rs_nblocks == 0) + if (nblocks == 0) return InvalidBlockNumber; /* We only need an RNG during this setup step */ sampler_random_init_state(sampler->seed, randstate); /* Compute nblocks/firstblock/step only once per query */ - sampler->nblocks = scan->rs_nblocks; + sampler->nblocks = nblocks; /* Choose random starting block within the relation */ /* (Actually this is the predecessor of the first block visited) */ @@ -275,7 +270,7 @@ system_time_nextsampleblock(SampleScanState *node) { /* Advance lb, using uint64 arithmetic to forestall overflow */ sampler->lb = ((uint64) sampler->lb + sampler->step) % sampler->nblocks; - } while (sampler->lb >= scan->rs_nblocks); + } while (sampler->lb >= nblocks); return sampler->lb; } diff --git a/contrib/unaccent/expected/unaccent.out b/contrib/unaccent/expected/unaccent.out index b93105e9c7c..c1bd7cd897d 100644 --- a/contrib/unaccent/expected/unaccent.out +++ b/contrib/unaccent/expected/unaccent.out @@ -6,23 +6,35 @@ SELECT getdatabaseencoding(); UTF8 (1 row) -SET client_encoding TO 'KOI8'; +SET client_encoding TO 'UTF8'; SELECT unaccent('foobar'); unaccent ---------- foobar (1 row) -SELECT unaccent('£ÌËÁ'); +SELECT unaccent('ёлка'); unaccent ---------- - ÅÌËÁ + елка (1 row) -SELECT unaccent('³öéë'); +SELECT unaccent('ÐЖИК'); unaccent ---------- - åöéë + ЕЖИК +(1 row) + +SELECT unaccent('˃˖˗˜'); + unaccent +---------- + >+-~ +(1 row) + +SELECT unaccent('AÌ€'); -- Remove combining diacritical 0x0300 + unaccent +---------- + A (1 row) SELECT unaccent('unaccent', 'foobar'); @@ -31,16 +43,28 @@ SELECT unaccent('unaccent', 'foobar'); foobar (1 row) -SELECT unaccent('unaccent', '£ÌËÁ'); +SELECT unaccent('unaccent', 'ёлка'); + unaccent +---------- + елка +(1 row) + +SELECT unaccent('unaccent', 'ÐЖИК'); unaccent ---------- - ÅÌËÁ + ЕЖИК (1 row) -SELECT unaccent('unaccent', '³öéë'); +SELECT unaccent('unaccent', '˃˖˗˜'); unaccent ---------- - åöéë + >+-~ +(1 row) + +SELECT unaccent('unaccent', 'AÌ€'); + unaccent +---------- + A (1 row) SELECT ts_lexize('unaccent', 'foobar'); @@ -49,15 +73,27 @@ SELECT ts_lexize('unaccent', 'foobar'); (1 row) -SELECT ts_lexize('unaccent', '£ÌËÁ'); +SELECT ts_lexize('unaccent', 'ёлка'); + ts_lexize +----------- + {елка} +(1 row) + +SELECT ts_lexize('unaccent', 'ÐЖИК'); + ts_lexize +----------- + {ЕЖИК} +(1 row) + +SELECT ts_lexize('unaccent', '˃˖˗˜'); ts_lexize ----------- - {ÅÌËÁ} + {>+-~} (1 row) -SELECT ts_lexize('unaccent', '³öéë'); +SELECT ts_lexize('unaccent', 'AÌ€'); ts_lexize ----------- - {åöéë} + {A} (1 row) diff --git a/contrib/unaccent/generate_unaccent_rules.py b/contrib/unaccent/generate_unaccent_rules.py index 4b1b011861f..7a0a96e04f7 100644 --- a/contrib/unaccent/generate_unaccent_rules.py +++ b/contrib/unaccent/generate_unaccent_rules.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/python # -*- coding: utf-8 -*- # # This script builds unaccent.rules on standard output when given the @@ -20,17 +20,69 @@ # option is enabled, the XML file of this transliterator [2] -- given as a # command line argument -- will be parsed and used. # +# Ideally you should use the latest release for each data set. For +# Latin-ASCII.xml, the latest data sets released can be browsed directly +# via [3]. Note that this script is compatible with at least release 29. +# # [1] http://unicode.org/Public/8.0.0/ucd/UnicodeData.txt -# [2] http://unicode.org/cldr/trac/export/12304/tags/release-28/common/transforms/Latin-ASCII.xml +# [2] http://unicode.org/cldr/trac/export/14746/tags/release-34/common/transforms/Latin-ASCII.xml +# [3] https://unicode.org/cldr/trac/browser/tags +# BEGIN: Python 2/3 compatibility - remove when Python 2 compatibility dropped +# The approach is to be Python3 compatible with Python2 "backports". +from __future__ import print_function +from __future__ import unicode_literals +# END: Python 2/3 compatibility - remove when Python 2 compatibility dropped -import re import argparse +import codecs +import re import sys import xml.etree.ElementTree as ET +# BEGIN: Python 2/3 compatibility - remove when Python 2 compatibility dropped +if sys.version_info[0] <= 2: + # Encode stdout as UTF-8, so we can just print to it + sys.stdout = codecs.getwriter('utf8')(sys.stdout) + + # Map Python 2's chr to unichr + chr = unichr + + # Python 2 and 3 compatible bytes call + def bytes(source, encoding='ascii', errors='strict'): + return source.encode(encoding=encoding, errors=errors) +else: +# END: Python 2/3 compatibility - remove when Python 2 compatibility dropped + sys.stdout = codecs.getwriter('utf8')(sys.stdout.buffer) + +# The ranges of Unicode characters that we consider to be "plain letters". +# For now we are being conservative by including only Latin and Greek. This +# could be extended in future based on feedback from people with relevant +# language knowledge. +PLAIN_LETTER_RANGES = ((ord('a'), ord('z')), # Latin lower case + (ord('A'), ord('Z')), # Latin upper case + (0x03b1, 0x03c9), # GREEK SMALL LETTER ALPHA, GREEK SMALL LETTER OMEGA + (0x0391, 0x03a9)) # GREEK CAPITAL LETTER ALPHA, GREEK CAPITAL LETTER OMEGA + +# Combining marks follow a "base" character, and result in a composite +# character. Example: "U&'A\0300'"produces "AÌ€".There are three types of +# combining marks: enclosing (Me), non-spacing combining (Mn), spacing +# combining (Mc). We identify the ranges of marks we feel safe removing. +# References: +# https://en.wikipedia.org/wiki/Combining_character +# https://www.unicode.org/charts/PDF/U0300.pdf +# https://www.unicode.org/charts/PDF/U20D0.pdf +COMBINING_MARK_RANGES = ((0x0300, 0x0362), # Mn: Accents, IPA + (0x20dd, 0x20E0), # Me: Symbols + (0x20e2, 0x20e4),) # Me: Screen, keycap, triangle + def print_record(codepoint, letter): - print (unichr(codepoint) + "\t" + letter).encode("UTF-8") + if letter: + output = chr(codepoint) + "\t" + letter + else: + output = chr(codepoint) + + print(output) class Codepoint: def __init__(self, id, general_category, combining_ids): @@ -38,10 +90,22 @@ def __init__(self, id, general_category, combining_ids): self.general_category = general_category self.combining_ids = combining_ids +def is_mark_to_remove(codepoint): + """Return true if this is a combining mark to remove.""" + if not is_mark(codepoint): + return False + + for begin, end in COMBINING_MARK_RANGES: + if codepoint.id >= begin and codepoint.id <= end: + return True + return False + def is_plain_letter(codepoint): - """Return true if codepoint represents a plain ASCII letter.""" - return (codepoint.id >= ord('a') and codepoint.id <= ord('z')) or \ - (codepoint.id >= ord('A') and codepoint.id <= ord('Z')) + """Return true if codepoint represents a "plain letter".""" + for begin, end in PLAIN_LETTER_RANGES: + if codepoint.id >= begin and codepoint.id <= end: + return True + return False def is_mark(codepoint): """Returns true for diacritical marks (combining codepoints).""" @@ -105,14 +169,24 @@ def parse_cldr_latin_ascii_transliterator(latinAsciiFilePath): charactersSet = set() # RegEx to parse rules - rulePattern = re.compile(ur'^(?:(.)|(\\u[0-9a-fA-F]{4})) \u2192 (?:\'(.+)\'|(.+)) ;') + rulePattern = re.compile(r'^(?:(.)|(\\u[0-9a-fA-F]{4})) \u2192 (?:\'(.+)\'|(.+)) ;') # construct tree from XML transliterationTree = ET.parse(latinAsciiFilePath) transliterationTreeRoot = transliterationTree.getroot() - for rule in transliterationTreeRoot.findall("./transforms/transform/tRule"): - matches = rulePattern.search(rule.text) + # Fetch all the transliteration rules. Since release 29 of Latin-ASCII.xml + # all the transliteration rules are located in a single tRule block with + # all rules separated into separate lines. + blockRules = transliterationTreeRoot.findall("./transforms/transform/tRule") + assert(len(blockRules) == 1) + + # Split the block of rules into one element per line. + rules = blockRules[0].text.splitlines() + + # And finish the processing of each individual rule. + for rule in rules: + matches = rulePattern.search(rule) # The regular expression capture four groups corresponding # to the characters. @@ -123,7 +197,7 @@ def parse_cldr_latin_ascii_transliterator(latinAsciiFilePath): # Group 3: plain "trg" char. Empty if group 4 is not. # Group 4: plain "trg" char between quotes. Empty if group 3 is not. if matches is not None: - src = matches.group(1) if matches.group(1) is not None else matches.group(2).decode('unicode-escape') + src = matches.group(1) if matches.group(1) is not None else bytes(matches.group(2), 'UTF-8').decode('unicode-escape') trg = matches.group(3) if matches.group(3) is not None else matches.group(4) # "'" and """ are escaped @@ -162,21 +236,22 @@ def main(args): charactersSet = set() # read file UnicodeData.txt - unicodeDataFile = open(args.unicodeDataFilePath, 'r') - - # read everything we need into memory - for line in unicodeDataFile: - fields = line.split(";") - if len(fields) > 5: - # http://www.unicode.org/reports/tr44/tr44-14.html#UnicodeData.txt - general_category = fields[2] - decomposition = fields[5] - decomposition = re.sub(decomposition_type_pattern, ' ', decomposition) - id = int(fields[0], 16) - combining_ids = [int(s, 16) for s in decomposition.split(" ") if s != ""] - codepoint = Codepoint(id, general_category, combining_ids) - table[id] = codepoint - all.append(codepoint) + with codecs.open( + args.unicodeDataFilePath, mode='r', encoding='UTF-8', + ) as unicodeDataFile: + # read everything we need into memory + for line in unicodeDataFile: + fields = line.split(";") + if len(fields) > 5: + # http://www.unicode.org/reports/tr44/tr44-14.html#UnicodeData.txt + general_category = fields[2] + decomposition = fields[5] + decomposition = re.sub(decomposition_type_pattern, ' ', decomposition) + id = int(fields[0], 16) + combining_ids = [int(s, 16) for s in decomposition.split(" ") if s != ""] + codepoint = Codepoint(id, general_category, combining_ids) + table[id] = codepoint + all.append(codepoint) # walk through all the codepoints looking for interesting mappings for codepoint in all: @@ -187,9 +262,11 @@ def main(args): chr(get_plain_letter(codepoint, table).id))) elif args.noLigaturesExpansion is False and is_ligature(codepoint, table): charactersSet.add((codepoint.id, - "".join(unichr(combining_codepoint.id) + "".join(chr(combining_codepoint.id) for combining_codepoint \ in get_plain_letters(codepoint, table)))) + elif is_mark_to_remove(codepoint): + charactersSet.add((codepoint.id, None)) # add CLDR Latin-ASCII characters if not args.noLigaturesExpansion: diff --git a/contrib/unaccent/sql/unaccent.sql b/contrib/unaccent/sql/unaccent.sql index 310213994f3..2ae097ff2b8 100644 --- a/contrib/unaccent/sql/unaccent.sql +++ b/contrib/unaccent/sql/unaccent.sql @@ -3,16 +3,22 @@ CREATE EXTENSION unaccent; -- must have a UTF8 database SELECT getdatabaseencoding(); -SET client_encoding TO 'KOI8'; +SET client_encoding TO 'UTF8'; SELECT unaccent('foobar'); -SELECT unaccent('£ÌËÁ'); -SELECT unaccent('³öéë'); +SELECT unaccent('ёлка'); +SELECT unaccent('ÐЖИК'); +SELECT unaccent('˃˖˗˜'); +SELECT unaccent('AÌ€'); -- Remove combining diacritical 0x0300 SELECT unaccent('unaccent', 'foobar'); -SELECT unaccent('unaccent', '£ÌËÁ'); -SELECT unaccent('unaccent', '³öéë'); +SELECT unaccent('unaccent', 'ёлка'); +SELECT unaccent('unaccent', 'ÐЖИК'); +SELECT unaccent('unaccent', '˃˖˗˜'); +SELECT unaccent('unaccent', 'AÌ€'); SELECT ts_lexize('unaccent', 'foobar'); -SELECT ts_lexize('unaccent', '£ÌËÁ'); -SELECT ts_lexize('unaccent', '³öéë'); +SELECT ts_lexize('unaccent', 'ёлка'); +SELECT ts_lexize('unaccent', 'ÐЖИК'); +SELECT ts_lexize('unaccent', '˃˖˗˜'); +SELECT ts_lexize('unaccent', 'AÌ€'); diff --git a/contrib/unaccent/unaccent.c b/contrib/unaccent/unaccent.c index 247c202755b..fc5176e338b 100644 --- a/contrib/unaccent/unaccent.c +++ b/contrib/unaccent/unaccent.c @@ -3,7 +3,7 @@ * unaccent.c * Text search unaccent dictionary * - * Copyright (c) 2009-2018, PostgreSQL Global Development Group + * Copyright (c) 2009-2019, PostgreSQL Global Development Group * * IDENTIFICATION * contrib/unaccent/unaccent.c @@ -14,13 +14,16 @@ #include "postgres.h" #include "catalog/namespace.h" +#include "catalog/pg_ts_dict.h" #include "commands/defrem.h" #include "lib/stringinfo.h" #include "tsearch/ts_cache.h" #include "tsearch/ts_locale.h" #include "tsearch/ts_public.h" #include "utils/builtins.h" +#include "utils/lsyscache.h" #include "utils/regproc.h" +#include "utils/syscache.h" PG_MODULE_MAGIC; @@ -376,7 +379,21 @@ unaccent_dict(PG_FUNCTION_ARGS) if (PG_NARGS() == 1) { - dictOid = get_ts_dict_oid(stringToQualifiedNameList("unaccent"), false); + /* + * Use the "unaccent" dictionary that is in the same schema that this + * function is in. + */ + Oid procnspid = get_func_namespace(fcinfo->flinfo->fn_oid); + const char *dictname = "unaccent"; + + dictOid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid, + PointerGetDatum(dictname), + ObjectIdGetDatum(procnspid)); + if (!OidIsValid(dictOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("text search dictionary \"%s.%s\" does not exist", + get_namespace_name(procnspid), dictname))); strArg = 0; } else diff --git a/contrib/unaccent/unaccent.rules b/contrib/unaccent/unaccent.rules index 97f9ed47cfa..99826408ac1 100644 --- a/contrib/unaccent/unaccent.rules +++ b/contrib/unaccent/unaccent.rules @@ -399,6 +399,140 @@ ʦ ts ʪ ls Ê« lz +ʹ ' +ʺ " +Ê» ' +ʼ ' +ʽ ' +Ë‚ < +˃ > +Ë„ ^ +ˆ ^ +ˈ ' +Ë‹ ` +Ë : +Ë– + +Ë— - +Ëœ ~ +Ì€ +Ì +Ì‚ +̃ +Ì„ +Ì… +̆ +̇ +̈ +̉ +ÌŠ +Ì‹ +ÌŒ +Ì +ÌŽ +Ì +Ì +Ì‘ +Ì’ +Ì“ +Ì” +Ì• +Ì– +Ì— +̘ +Ì™ +Ìš +Ì› +Ìœ +Ì +Ìž +ÌŸ +Ì  +Ì¡ +Ì¢ +Ì£ +̤ +Ì¥ +̦ +̧ +̨ +Ì© +̪ +Ì« +̬ +Ì­ +Ì® +̯ +̰ +̱ +̲ +̳ +Ì´ +̵ +̶ +Ì· +̸ +̹ +̺ +Ì» +̼ +̽ +̾ +Ì¿ +Í€ +Í +Í‚ +̓ +Í„ +Í… +͆ +͇ +͈ +͉ +ÍŠ +Í‹ +ÍŒ +Í +ÍŽ +Í +Í +Í‘ +Í’ +Í“ +Í” +Í• +Í– +Í— +͘ +Í™ +Íš +Í› +Íœ +Í +Íž +ÍŸ +Í  +Í¡ +Í¢ +Ά Α +Έ Ε +Ή Η +Ί Ι +ÎŒ Ο +ÎŽ Î¥ +ΠΩ +Πι +Ϊ Ι +Ϋ Î¥ +ά α +έ ε +ή η +ί ι +ΰ Ï… +ÏŠ ι +Ï‹ Ï… +ÏŒ ο +Ï Ï… +ÏŽ ω РЕ Ñ‘ е á´€ A @@ -709,6 +843,207 @@ ỽ v Ỿ Y ỿ y +á¼€ α +ἠα +ἂ α +ἃ α +ἄ α +á¼… α +ἆ α +ἇ α +Ἀ Α +Ἁ Α +Ἂ Α +Ἃ Α +Ἄ Α +ἠΑ +Ἆ Α +ἠΑ +ἠε +ἑ ε +á¼’ ε +ἓ ε +á¼” ε +ἕ ε +Ἐ Ε +á¼™ Ε +Ἒ Ε +á¼› Ε +Ἔ Ε +ἠΕ +á¼  η +ἡ η +á¼¢ η +á¼£ η +ἤ η +á¼¥ η +ἦ η +á¼§ η +Ἠ Η +Ἡ Η +Ἢ Η +Ἣ Η +Ἤ Η +á¼­ Η +á¼® Η +Ἧ Η +á¼° ι +á¼± ι +á¼² ι +á¼³ ι +á¼´ ι +á¼µ ι +á¼¶ ι +á¼· ι +Ἰ Ι +á¼¹ Ι +Ἲ Ι +á¼» Ι +á¼¼ Ι +á¼½ Ι +á¼¾ Ι +Ἷ Ι +á½€ ο +ὠο +ὂ ο +ὃ ο +ὄ ο +á½… ο +Ὀ Ο +Ὁ Ο +Ὂ Ο +Ὃ Ο +Ὄ Ο +ὠΟ +á½ Ï… +ὑ Ï… +á½’ Ï… +ὓ Ï… +á½” Ï… +ὕ Ï… +á½– Ï… +á½— Ï… +á½™ Î¥ +á½› Î¥ +ὠΥ +Ὗ Î¥ +á½  ω +ὡ ω +á½¢ ω +á½£ ω +ὤ ω +á½¥ ω +ὦ ω +á½§ ω +Ὠ Ω +Ὡ Ω +Ὢ Ω +Ὣ Ω +Ὤ Ω +á½­ Ω +á½® Ω +Ὧ Ω +á½° α +á½² ε +á½´ η +á½¶ ι +ὸ ο +ὺ Ï… +á½¼ ω +á¾€ α +ᾠα +ᾂ α +ᾃ α +ᾄ α +á¾… α +ᾆ α +ᾇ α +ᾈ Α +ᾉ Α +ᾊ Α +ᾋ Α +ᾌ Α +ᾠΑ +ᾎ Α +ᾠΑ +ᾠη +ᾑ η +á¾’ η +ᾓ η +á¾” η +ᾕ η +á¾– η +á¾— η +ᾘ Η +á¾™ Η +ᾚ Η +á¾› Η +ᾜ Η +ᾠΗ +ᾞ Η +ᾟ Η +á¾  ω +ᾡ ω +á¾¢ ω +á¾£ ω +ᾤ ω +á¾¥ ω +ᾦ ω +á¾§ ω +ᾨ Ω +ᾩ Ω +ᾪ Ω +ᾫ Ω +ᾬ Ω +á¾­ Ω +á¾® Ω +ᾯ Ω +á¾° α +á¾± α +á¾² α +á¾³ α +á¾´ α +á¾¶ α +á¾· α +Ᾰ Α +á¾¹ Α +Ὰ Α +á¾¼ Α +á¿‚ η +ῃ η +á¿„ η +ῆ η +ῇ η +Ὲ Ε +Ὴ Η +ῌ Η +ῠι +á¿‘ ι +á¿’ ι +á¿– ι +á¿— ι +Ῐ Ι +á¿™ Ι +Ὶ Ι +á¿  Ï… +á¿¡ Ï… +á¿¢ Ï… +ῤ Ï +á¿¥ Ï +ῦ Ï… +á¿§ Ï… +Ῠ Î¥ +á¿© Î¥ +Ὺ Î¥ +Ῥ Ρ +ῲ ω +ῳ ω +á¿´ ω +á¿¶ ω +á¿· ω +Ὸ Ο +Ὼ Ω +ῼ Ω †- ‑ - ‒ - @@ -746,6 +1081,13 @@ â‚§ Pts ₹ Rs ₺ TL +⃠+⃞ +⃟ +⃠ +⃢ +⃣ +⃤ â„€ a/c â„ a/s â„‚ C diff --git a/contrib/uuid-ossp/uuid-ossp.c b/contrib/uuid-ossp/uuid-ossp.c index 179305b9547..f5ae915f243 100644 --- a/contrib/uuid-ossp/uuid-ossp.c +++ b/contrib/uuid-ossp/uuid-ossp.c @@ -2,7 +2,7 @@ * * UUID generation functions using the BSD, E2FS or OSSP UUID library * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * Portions Copyright (c) 2009 Andrew Gierth * diff --git a/contrib/vacuumlo/.gitignore b/contrib/vacuumlo/.gitignore index 07f6ab4fd7c..f3f0ce3d80b 100644 --- a/contrib/vacuumlo/.gitignore +++ b/contrib/vacuumlo/.gitignore @@ -1 +1,3 @@ /vacuumlo + +/tmp_check/ diff --git a/contrib/vacuumlo/Makefile b/contrib/vacuumlo/Makefile index 71106ff69c6..3efcb46735c 100644 --- a/contrib/vacuumlo/Makefile +++ b/contrib/vacuumlo/Makefile @@ -6,6 +6,8 @@ PGAPPICON = win32 PROGRAM = vacuumlo OBJS = vacuumlo.o $(WIN32RES) +TAP_TESTS = 1 + PG_CPPFLAGS = -I$(libpq_srcdir) PG_LIBS_INTERNAL = $(libpq_pgport) diff --git a/contrib/vacuumlo/t/001_basic.pl b/contrib/vacuumlo/t/001_basic.pl new file mode 100644 index 00000000000..2bfb6ce17d9 --- /dev/null +++ b/contrib/vacuumlo/t/001_basic.pl @@ -0,0 +1,9 @@ +use strict; +use warnings; + +use TestLib; +use Test::More tests => 8; + +program_help_ok('vacuumlo'); +program_version_ok('vacuumlo'); +program_options_handling_ok('vacuumlo'); diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c index 7eb474ca3e4..533e2ce33c5 100644 --- a/contrib/vacuumlo/vacuumlo.c +++ b/contrib/vacuumlo/vacuumlo.c @@ -3,7 +3,7 @@ * vacuumlo.c * This removes orphaned large objects from a database. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,9 +23,11 @@ #include "catalog/pg_class_d.h" +#include "common/logging.h" #include "fe_utils/connect.h" #include "libpq-fe.h" #include "pg_getopt.h" +#include "getopt_long.h" #define BUFSIZE 1024 @@ -108,8 +110,7 @@ vacuumlo(const char *database, const struct _param *param) conn = PQconnectdbParams(keywords, values, true); if (!conn) { - fprintf(stderr, "Connection to database \"%s\" failed\n", - database); + pg_log_error("connection to database \"%s\" failed", database); return -1; } @@ -128,8 +129,8 @@ vacuumlo(const char *database, const struct _param *param) /* check to see that the backend connection was successfully made */ if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr, "Connection to database \"%s\" failed:\n%s", - database, PQerrorMessage(conn)); + pg_log_error("connection to database \"%s\" failed: %s", + database, PQerrorMessage(conn)); PQfinish(conn); return -1; } @@ -144,8 +145,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, "Failed to set search_path:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to set search_path: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -164,8 +164,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to create temp table:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to create temp table: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -181,8 +180,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to vacuum temp table:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to vacuum temp table: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -197,9 +195,6 @@ vacuumlo(const char *database, const struct _param *param) * table formed above is ignored, and pg_largeobject will be too. If * either of these were scanned, obviously we'd end up with nothing to * delete... - * - * NOTE: the system oid column is ignored, as it has attnum < 1. This - * shouldn't matter for correctness, but it saves time. */ buf[0] = '\0'; strcat(buf, "SELECT s.nspname, c.relname, a.attname "); @@ -214,8 +209,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, "Failed to find OID columns:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to find OID columns: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -240,14 +234,14 @@ vacuumlo(const char *database, const struct _param *param) if (!schema || !table || !field) { - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("%s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); if (schema != NULL) PQfreemem(schema); - if (schema != NULL) + if (table != NULL) PQfreemem(table); - if (schema != NULL) + if (field != NULL) PQfreemem(field); return -1; } @@ -259,9 +253,8 @@ vacuumlo(const char *database, const struct _param *param) res2 = PQexec(conn, buf); if (PQresultStatus(res2) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to check %s in table %s.%s:\n", - field, schema, table); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to check %s in table %s.%s: %s", + field, schema, table, PQerrorMessage(conn)); PQclear(res2); PQclear(res); PQfinish(conn); @@ -290,8 +283,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, "begin"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to start transaction:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to start transaction: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -304,7 +296,7 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn)); + pg_log_error("DECLARE CURSOR failed: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -316,12 +308,12 @@ vacuumlo(const char *database, const struct _param *param) deleted = 0; - while (1) + do { res = PQexec(conn, buf); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, "FETCH FORWARD failed: %s", PQerrorMessage(conn)); + pg_log_error("FETCH FORWARD failed: %s", PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -349,13 +341,12 @@ vacuumlo(const char *database, const struct _param *param) { if (lo_unlink(conn, lo) < 0) { - fprintf(stderr, "\nFailed to remove lo %u: ", lo); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to remove lo %u: %s", lo, + PQerrorMessage(conn)); if (PQtransactionStatus(conn) == PQTRANS_INERROR) { success = false; - PQclear(res); - break; + break; /* out of inner for-loop */ } } else @@ -370,8 +361,8 @@ vacuumlo(const char *database, const struct _param *param) res2 = PQexec(conn, "commit"); if (PQresultStatus(res2) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to commit transaction:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to commit transaction: %s", + PQerrorMessage(conn)); PQclear(res2); PQclear(res); PQfinish(conn); @@ -381,8 +372,8 @@ vacuumlo(const char *database, const struct _param *param) res2 = PQexec(conn, "begin"); if (PQresultStatus(res2) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to start transaction:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to start transaction: %s", + PQerrorMessage(conn)); PQclear(res2); PQclear(res); PQfinish(conn); @@ -393,7 +384,7 @@ vacuumlo(const char *database, const struct _param *param) } PQclear(res); - } + } while (success); /* * That's all folks! @@ -401,8 +392,8 @@ vacuumlo(const char *database, const struct _param *param) res = PQexec(conn, "commit"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, "Failed to commit transaction:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); + pg_log_error("failed to commit transaction: %s", + PQerrorMessage(conn)); PQclear(res); PQfinish(conn); return -1; @@ -434,31 +425,47 @@ usage(const char *progname) printf("%s removes unreferenced large objects from databases.\n\n", progname); printf("Usage:\n %s [OPTION]... DBNAME...\n\n", progname); printf("Options:\n"); - printf(" -l LIMIT commit after removing each LIMIT large objects\n"); - printf(" -n don't remove large objects, just show what would be done\n"); - printf(" -v write a lot of progress messages\n"); - printf(" -V, --version output version information, then exit\n"); - printf(" -?, --help show this help, then exit\n"); + printf(" -l, --limit=LIMIT commit after removing each LIMIT large objects\n"); + printf(" -n, --dry-run don't remove large objects, just show what would be done\n"); + printf(" -v, --verbose write a lot of progress messages\n"); + printf(" -V, --version output version information, then exit\n"); + printf(" -?, --help show this help, then exit\n"); printf("\nConnection options:\n"); - printf(" -h HOSTNAME database server host or socket directory\n"); - printf(" -p PORT database server port\n"); - printf(" -U USERNAME user name to connect as\n"); - printf(" -w never prompt for password\n"); - printf(" -W force password prompt\n"); + printf(" -h, --host=HOSTNAME database server host or socket directory\n"); + printf(" -p, --port=PORT database server port\n"); + printf(" -U, --username=USERNAME user name to connect as\n"); + printf(" -w, --no-password never prompt for password\n"); + printf(" -W, --password force password prompt\n"); printf("\n"); - printf("Report bugs to .\n"); + printf("Report bugs to .\n"); } int main(int argc, char **argv) { + static struct option long_options[] = { + {"host", required_argument, NULL, 'h'}, + {"limit", required_argument, NULL, 'l'}, + {"dry-run", no_argument, NULL, 'n'}, + {"port", required_argument, NULL, 'p'}, + {"username", required_argument, NULL, 'U'}, + {"verbose", no_argument, NULL, 'v'}, + {"version", no_argument, NULL, 'V'}, + {"no-password", no_argument, NULL, 'w'}, + {"password", no_argument, NULL, 'W'}, + {"help", no_argument, NULL, '?'}, + {NULL, 0, NULL, 0} + }; + int rc = 0; struct _param param; int c; int port; const char *progname; + int optindex; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); /* Set default parameter values */ @@ -486,64 +493,59 @@ main(int argc, char **argv) } } - while (1) + while ((c = getopt_long(argc, argv, "h:l:np:U:vwW", long_options, &optindex)) != -1) { - c = getopt(argc, argv, "h:l:U:p:vnwW"); - if (c == -1) - break; - switch (c) { case '?': fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); - case ':': - exit(1); - case 'v': - param.verbose = 1; - break; - case 'n': - param.dry_run = 1; - param.verbose = 1; + case 'h': + param.pg_host = pg_strdup(optarg); break; case 'l': param.transaction_limit = strtol(optarg, NULL, 10); if (param.transaction_limit < 0) { - fprintf(stderr, - "%s: transaction limit must not be negative (0 disables)\n", - progname); + pg_log_error("transaction limit must not be negative (0 disables)"); exit(1); } break; - case 'U': - param.pg_user = pg_strdup(optarg); - break; - case 'w': - param.pg_prompt = TRI_NO; - break; - case 'W': - param.pg_prompt = TRI_YES; + case 'n': + param.dry_run = 1; + param.verbose = 1; break; case 'p': port = strtol(optarg, NULL, 10); if ((port < 1) || (port > 65535)) { - fprintf(stderr, "%s: invalid port number: %s\n", progname, optarg); + pg_log_error("invalid port number: %s", optarg); exit(1); } param.pg_port = pg_strdup(optarg); break; - case 'h': - param.pg_host = pg_strdup(optarg); + case 'U': + param.pg_user = pg_strdup(optarg); break; + case 'v': + param.verbose = 1; + break; + case 'w': + param.pg_prompt = TRI_NO; + break; + case 'W': + param.pg_prompt = TRI_YES; + break; + default: + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); } } /* No database given? Show usage */ if (optind >= argc) { - fprintf(stderr, "vacuumlo: missing required argument: database name\n"); + pg_log_error("missing required argument: database name"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c index 95e580df088..1e5b71d9a02 100644 --- a/contrib/xml2/xpath.c +++ b/contrib/xml2/xpath.c @@ -41,16 +41,16 @@ typedef struct /* local declarations */ static xmlChar *pgxmlNodeSetToText(xmlNodeSetPtr nodeset, - xmlChar *toptagname, xmlChar *septagname, - xmlChar *plainsep); + xmlChar *toptagname, xmlChar *septagname, + xmlChar *plainsep); static text *pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar *toptag, - xmlChar *septag, xmlChar *plainsep); + xmlChar *septag, xmlChar *plainsep); static xmlChar *pgxml_texttoxmlchar(text *textstring); static xmlXPathObjectPtr pgxml_xpath(text *document, xmlChar *xpath, - xpath_workspace *workspace); + xpath_workspace *workspace); static void cleanup_workspace(xpath_workspace *workspace); diff --git a/doc/bug.template b/doc/bug.template deleted file mode 100644 index 4d767bfd516..00000000000 --- a/doc/bug.template +++ /dev/null @@ -1,53 +0,0 @@ -If PostgreSQL failed to compile on your computer or you found a bug, -please fill out this form and e-mail it to pgsql-bugs@postgresql.org. - -If your bug report has security implications and you'd prefer that it not -become immediately visible in public archives, don't send it to pgsql-bugs. -Security issues can be reported privately to security@postgresql.org. - -If you not only found the problem but solved it and generated a patch -then e-mail it to pgsql-hackers@postgresql.org instead. Please use the -command "diff -c" to generate the patch. - -You may also enter a bug report at https://www.postgresql.org/ instead of -e-mailing this form. - -============================================================================ - POSTGRESQL BUG REPORT TEMPLATE -============================================================================ - - -Your name : -Your email address : - - -System Configuration: ---------------------- - Architecture (example: Intel Pentium) : - - Operating System (example: Linux 2.4.18) : - - PostgreSQL version (example: PostgreSQL 11devel): PostgreSQL 11devel - - Compiler used (example: gcc 3.3.5) : - - -Please enter a FULL description of your problem: ------------------------------------------------- - - - - - -Please describe a way to repeat the problem. Please try to provide a -concise reproducible example, if at all possible: ----------------------------------------------------------------------- - - - - - -If you know how this problem might be fixed, list the solution below: ---------------------------------------------------------------------- - - diff --git a/doc/src/sgml/.gitignore b/doc/src/sgml/.gitignore index a72b7ccb06c..acf7b4f10f7 100644 --- a/doc/src/sgml/.gitignore +++ b/doc/src/sgml/.gitignore @@ -15,6 +15,7 @@ /features-supported.sgml /features-unsupported.sgml /errcodes-table.sgml +/keywords-table.sgml /version.sgml # Assorted byproducts from building the above /postgres.xml diff --git a/doc/src/sgml/Makefile b/doc/src/sgml/Makefile index 74aac01c395..0401a515df8 100644 --- a/doc/src/sgml/Makefile +++ b/doc/src/sgml/Makefile @@ -53,10 +53,13 @@ override XSLTPROCFLAGS += --stringparam pg.version '$(VERSION)' GENERATED_SGML = version.sgml \ - features-supported.sgml features-unsupported.sgml errcodes-table.sgml + features-supported.sgml features-unsupported.sgml errcodes-table.sgml \ + keywords-table.sgml ALLSGML := $(wildcard $(srcdir)/*.sgml $(srcdir)/ref/*.sgml) $(GENERATED_SGML) +ALL_IMAGES := $(wildcard $(srcdir)/images/*.svg) + ## ## Man pages @@ -94,24 +97,21 @@ features-unsupported.sgml: $(top_srcdir)/src/backend/catalog/sql_feature_package errcodes-table.sgml: $(top_srcdir)/src/backend/utils/errcodes.txt generate-errcodes-table.pl $(PERL) $(srcdir)/generate-errcodes-table.pl $< > $@ +keywords-table.sgml: $(top_srcdir)/src/include/parser/kwlist.h $(wildcard $(srcdir)/keywords/sql*.txt) generate-keywords-table.pl + $(PERL) $(srcdir)/generate-keywords-table.pl $(srcdir) > $@ + ## ## Generation of some text files. ## ICONV = iconv -LYNX = lynx - -# The documentation may contain non-ASCII characters (mostly for -# contributor names), which lynx converts to the encoding determined -# by the current locale. To get text output that is deterministic and -# easily readable by everyone, we make lynx produce LATIN1 and then -# convert that to ASCII with transliteration for the non-ASCII characters. -# Official releases were historically built on FreeBSD, which has limited -# locale support and is very picky about locale name spelling. The -# below has been finely tuned to run on FreeBSD and Linux/glibc. +PANDOC = pandoc + INSTALL: % : %.html - $(PERL) -p -e 's, $@ + $(PANDOC) -t plain -o $@.tmp $< + $(ICONV) -f utf8 -t us-ascii//TRANSLIT $@.tmp > $@ + rm $@.tmp INSTALL.html: %.html : stylesheet-text.xsl %.xml $(XMLLINT) --noout --valid $*.xml @@ -131,24 +131,30 @@ endif html: html-stamp -html-stamp: stylesheet.xsl postgres.sgml $(ALLSGML) +html-stamp: stylesheet.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES) $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^) $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) $(wordlist 1,2,$^) + cp $(ALL_IMAGES) html/ cp $(srcdir)/stylesheet.css html/ touch $@ -htmlhelp: stylesheet-hh.xsl postgres.sgml $(ALLSGML) +htmlhelp: htmlhelp-stamp + +htmlhelp-stamp: stylesheet-hh.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES) $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^) $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(wordlist 1,2,$^) + cp $(ALL_IMAGES) htmlhelp/ + cp $(srcdir)/stylesheet.css htmlhelp/ + touch $@ # single-page HTML -postgres.html: stylesheet-html-nochunk.xsl postgres.sgml $(ALLSGML) +postgres.html: stylesheet-html-nochunk.xsl postgres.sgml $(ALLSGML) $(ALL_IMAGES) $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^) $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_FLAGS) -o $@ $(wordlist 1,2,$^) # single-page text postgres.txt: postgres.html - $(LYNX) -force_html -dump -nolist $< > $@ + $(PANDOC) -t plain -o $@ $< ## @@ -158,15 +164,17 @@ postgres.txt: postgres.html postgres.pdf: $(error Invalid target; use postgres-A4.pdf or postgres-US.pdf as targets) +XSLTPROC_FO_FLAGS += --stringparam img.src.path '$(srcdir)/' + %-A4.fo: stylesheet-fo.xsl %.sgml $(ALLSGML) $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^) - $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) --stringparam paper.type A4 -o $@ $(wordlist 1,2,$^) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type A4 -o $@ $(wordlist 1,2,$^) %-US.fo: stylesheet-fo.xsl %.sgml $(ALLSGML) $(XMLLINT) $(XMLINCLUDE) --noout --valid $(word 2,$^) - $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) --stringparam paper.type USletter -o $@ $(wordlist 1,2,$^) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type USletter -o $@ $(wordlist 1,2,$^) -%.pdf: %.fo +%.pdf: %.fo $(ALL_IMAGES) $(FOP) -fo $< -pdf $@ @@ -175,9 +183,9 @@ postgres.pdf: ## epub: postgres.epub -postgres.epub: postgres.sgml $(ALLSGML) +postgres.epub: postgres.sgml $(ALLSGML) $(ALL_IMAGES) $(XMLLINT) --noout --valid $< - $(DBTOEPUB) $< + $(DBTOEPUB) -o $@ $< ## @@ -290,7 +298,7 @@ clean: # generated SGML files rm -f $(GENERATED_SGML) # HTML Help - rm -f htmlhelp.hhp toc.hhc index.hhk + rm -rf htmlhelp/ htmlhelp-stamp # EPUB rm -f postgres.epub # Texinfo diff --git a/doc/src/sgml/README.links b/doc/src/sgml/README.links index f64b8573169..db6577d2436 100644 --- a/doc/src/sgml/README.links +++ b/doc/src/sgml/README.links @@ -1,6 +1,6 @@ -Linking within SGML documents can be confusing, so here is a summary: +Linking within DocBook documents can be confusing, so here is a summary: Intra-document Linking @@ -40,7 +40,10 @@ url= Guidelines ---------- -o If you want to supply text, use , else -o Do not use text with so the URL appears in printed output -o Specific nouns like GUC variables, SQL commands, and contrib modules - usually have xreflabels +- For an internal link, if you want to supply text, use , else + . + +- Specific nouns like GUC variables, SQL commands, and contrib modules + usually have xreflabels. + +- For an external link, use , with or without link text. diff --git a/doc/src/sgml/acronyms.sgml b/doc/src/sgml/acronyms.sgml index 638ffc9fe83..411e368a9c6 100644 --- a/doc/src/sgml/acronyms.sgml +++ b/doc/src/sgml/acronyms.sgml @@ -13,7 +13,7 @@ ANSI - + American National Standards Institute @@ -23,7 +23,7 @@ API - Application Programming Interface + Application Programming Interface @@ -32,7 +32,7 @@ ASCII - American Standard + American Standard Code for Information Interchange @@ -51,7 +51,7 @@ CA - Certificate Authority + Certificate Authority @@ -61,7 +61,7 @@ Classless + url="https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing">Classless Inter-Domain Routing @@ -71,7 +71,7 @@ CPAN - Comprehensive Perl Archive Network + Comprehensive Perl Archive Network @@ -81,7 +81,7 @@ Certificate + url="https://en.wikipedia.org/wiki/Certificate_revocation_list">Certificate Revocation List @@ -92,7 +92,7 @@ Comma + url="https://en.wikipedia.org/wiki/Comma-separated_values">Comma Separated Values @@ -121,7 +121,7 @@ Database + url="https://en.wikipedia.org/wiki/Database_administrator">Database Administrator @@ -131,7 +131,7 @@ DBI - Database Interface (Perl) + Database Interface (Perl) @@ -140,7 +140,7 @@ DBMS - Database Management + Database Management System @@ -151,7 +151,7 @@ Data + url="https://en.wikipedia.org/wiki/Data_Definition_Language">Data Definition Language, SQL commands such as CREATE TABLE, ALTER USER @@ -163,7 +163,7 @@ Data + url="https://en.wikipedia.org/wiki/Data_Manipulation_Language">Data Manipulation Language, SQL commands such as INSERT, UPDATE, DELETE @@ -175,7 +175,7 @@ Daylight + url="https://en.wikipedia.org/wiki/Daylight_saving_time">Daylight Saving Time @@ -194,7 +194,7 @@ ESQL - Embedded + Embedded SQL @@ -204,7 +204,7 @@ FAQ - Frequently Asked + Frequently Asked Questions @@ -251,7 +251,7 @@ Git + url="https://en.wikipedia.org/wiki/Git_(software)">Git @@ -260,7 +260,7 @@ GMT - Greenwich Mean Time + Greenwich Mean Time @@ -270,7 +270,7 @@ Generic + url="https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface">Generic Security Services Application Programming Interface @@ -300,7 +300,7 @@ Heap-Only + url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/backend/access/heap/README.HOT;hb=HEAD">Heap-Only Tuples @@ -311,7 +311,7 @@ International + url="https://en.wikipedia.org/wiki/International_Electrotechnical_Commission">International Electrotechnical Commission @@ -332,7 +332,7 @@ Inter-Process + url="https://en.wikipedia.org/wiki/Inter-process_communication">Inter-Process Communication @@ -342,7 +342,7 @@ ISO - International Organization for + International Organization for Standardization @@ -352,7 +352,7 @@ ISSN - International Standard + International Standard Serial Number @@ -363,7 +363,7 @@ Java + url="https://en.wikipedia.org/wiki/Java_Database_Connectivity">Java Database Connectivity @@ -394,7 +394,7 @@ Lightweight + url="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol">Lightweight Directory Access Protocol @@ -415,7 +415,7 @@ Microsoft + url="https://en.wikipedia.org/wiki/Visual_C++">Microsoft Visual C @@ -435,7 +435,7 @@ National + url="https://en.wikipedia.org/wiki/Internationalization_and_localization">National Language Support @@ -446,7 +446,7 @@ Open + url="https://en.wikipedia.org/wiki/Open_Database_Connectivity">Open Database Connectivity @@ -465,7 +465,7 @@ OLAP - Online Analytical + Online Analytical Processing @@ -475,7 +475,7 @@ OLTP - Online Transaction + Online Transaction Processing @@ -485,7 +485,7 @@ ORDBMS - Object-Relational + Object-Relational Database Management System @@ -496,7 +496,7 @@ Pluggable + url="https://en.wikipedia.org/wiki/Pluggable_Authentication_Modules">Pluggable Authentication Modules @@ -524,7 +524,7 @@ PID - Process Identifier + Process Identifier @@ -552,7 +552,7 @@ POSIX - Portable Operating + Portable Operating System Interface @@ -563,7 +563,7 @@ Relational + url="https://en.wikipedia.org/wiki/Relational_database_management_system">Relational Database Management System @@ -574,7 +574,7 @@ Request For + url="https://en.wikipedia.org/wiki/Request_for_Comments">Request For Comments @@ -584,7 +584,7 @@ SGML - Standard Generalized + Standard Generalized Markup Language @@ -612,7 +612,7 @@ SQL - Structured Query Language + Structured Query Language @@ -630,7 +630,7 @@ SSH - Secure + Secure Shell @@ -640,7 +640,7 @@ SSL - Secure Sockets Layer + Secure Sockets Layer @@ -649,7 +649,7 @@ SSPI - Security + Security Support Provider Interface @@ -659,7 +659,7 @@ SYSV - Unix System V + Unix System V @@ -669,7 +669,7 @@ Transmission + url="https://en.wikipedia.org/wiki/Transmission_Control_Protocol">Transmission Control Protocol (TCP) / Internet Protocol (IP) @@ -707,7 +707,7 @@ URL - Uniform Resource + Uniform Resource Locator @@ -718,7 +718,7 @@ Coordinated + url="https://en.wikipedia.org/wiki/Coordinated_Universal_Time">Coordinated Universal Time @@ -738,7 +738,7 @@ UTF8 - Eight-Bit Unicode + Eight-Bit Unicode Transformation Format @@ -775,7 +775,7 @@ XML - Extensible Markup + Extensible Markup Language diff --git a/doc/src/sgml/amcheck.sgml b/doc/src/sgml/amcheck.sgml index a712c86a10f..fe0fe9c186e 100644 --- a/doc/src/sgml/amcheck.sgml +++ b/doc/src/sgml/amcheck.sgml @@ -35,7 +35,7 @@ functions. - amcheck functions may be used only by superusers. + amcheck functions may only be used by superusers. @@ -55,7 +55,7 @@ bt_index_check tests that its target, a B-Tree index, respects a variety of invariants. Example usage: -test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique) +test=# SELECT bt_index_check(index => c.oid, heapallindexed => i.indisunique), c.relname, c.relpages FROM pg_index i @@ -67,7 +67,7 @@ WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog' -- Don't check temp tables, which may be from another session: AND c.relpersistence != 't' -- Function may throw an error when this is omitted: -AND i.indisready AND i.indisvalid +AND c.relkind = 'i' AND i.indisready AND i.indisvalid ORDER BY c.relpages DESC LIMIT 10; bt_index_check | relname | relpages ----------------+---------------------------------+---------- @@ -83,14 +83,13 @@ ORDER BY c.relpages DESC LIMIT 10; | pg_amop_fam_strat_index | 5 (10 rows) - This example shows a session that performs verification of every - catalog index in the database test. Details of just - the 10 largest indexes verified are displayed. Verification of - the presence of heap tuples as index tuples is requested for - unique indexes only. Since no error is raised, all indexes - tested appear to be logically consistent. Naturally, this query - could easily be changed to call - bt_index_check for every index in the + This example shows a session that performs verification of the + 10 largest catalog indexes in the database test. + Verification of the presence of heap tuples as index tuples is + requested for the subset that are unique indexes. Since no + error is raised, all indexes tested appear to be logically + consistent. Naturally, this query could easily be changed to + call bt_index_check for every index in the database where verification is supported. @@ -113,7 +112,7 @@ ORDER BY c.relpages DESC LIMIT 10; - bt_index_parent_check(index regclass, heapallindexed boolean) returns void + bt_index_parent_check(index regclass, heapallindexed boolean, rootdescend boolean) returns void bt_index_parent_check @@ -126,7 +125,11 @@ ORDER BY c.relpages DESC LIMIT 10; Optionally, when the heapallindexed argument is true, the function verifies the presence of all heap tuples that should be found within the - index. The checks that can be performed by + index, and that there are no missing downlinks in the index + structure. When the optional rootdescend + argument is true, verification re-finds + tuples on the leaf level by performing a new search from the + root page for each tuple. The checks that can be performed by bt_index_parent_check are a superset of the checks that can be performed by bt_index_check. bt_index_parent_check can be thought of as @@ -166,7 +169,7 @@ ORDER BY c.relpages DESC LIMIT 10; - Optional <parameter>heapallindexed</parameter> verification + Optional <parameter>heapallindexed</parameter> Verification When the heapallindexed argument to verification functions is true, an additional @@ -207,7 +210,7 @@ ORDER BY c.relpages DESC LIMIT 10; - Using <filename>amcheck</filename> effectively + Using <filename>amcheck</filename> Effectively amcheck can be effective at detecting various types of @@ -291,8 +294,7 @@ ORDER BY c.relpages DESC LIMIT 10; - Corruption caused by faulty RAM, and the broader memory subsystem - and operating system. + Corruption caused by faulty RAM, or the broader memory subsystem. PostgreSQL does not protect against correctable @@ -317,7 +319,7 @@ ORDER BY c.relpages DESC LIMIT 10; - Repairing corruption + Repairing Corruption No error concerning corruption raised by amcheck should ever be a false positive. amcheck raises diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml index 53f8049df38..9ffb8427bf0 100644 --- a/doc/src/sgml/arch-dev.sgml +++ b/doc/src/sgml/arch-dev.sgml @@ -114,7 +114,7 @@ - How Connections are Established + How Connections Are Established PostgreSQL is implemented using a diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml index f4d4a610ef3..a473fa8ee8b 100644 --- a/doc/src/sgml/array.sgml +++ b/doc/src/sgml/array.sgml @@ -766,9 +766,9 @@ SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 For example, elements containing curly braces, commas (or the data type's delimiter character), double quotes, backslashes, or leading or trailing whitespace must be double-quoted. Empty strings and strings matching the - word NULL must be quoted, too. To put a double quote or - backslash in a quoted array element value, use escape string syntax - and precede it with a backslash. Alternatively, you can avoid quotes and use + word NULL must be quoted, too. To put a double + quote or backslash in a quoted array element value, precede it + with a backslash. Alternatively, you can avoid quotes and use backslash-escaping to protect all data characters that would otherwise be taken as array syntax. @@ -781,27 +781,6 @@ SELECT f1[1][-2][3] AS e1, f1[1][-1][5] AS e2 non-whitespace characters of an element, is not ignored. - - - Remember that what you write in an SQL command will first be interpreted - as a string literal, and then as an array. This doubles the number of - backslashes you need. For example, to insert a text array - value containing a backslash and a double quote, you'd need to write: - -INSERT ... VALUES (E'{"\\\\","\\""}'); - - The escape string processor removes one level of backslashes, so that - what arrives at the array-value parser looks like {"\\","\""}. - In turn, the strings fed to the text data type's input routine - become \ and " respectively. (If we were working - with a data type whose input routine also treated backslashes specially, - bytea for example, we might need as many as eight backslashes - in the command to get one backslash into the stored array element.) - Dollar quoting (see ) can be - used to avoid the need to double backslashes. - - - The ARRAY constructor syntax (see diff --git a/doc/src/sgml/auto-explain.sgml b/doc/src/sgml/auto-explain.sgml index 08b67f2600b..3d619d4a3dd 100644 --- a/doc/src/sgml/auto-explain.sgml +++ b/doc/src/sgml/auto-explain.sgml @@ -54,10 +54,11 @@ LOAD 'auto_explain'; auto_explain.log_min_duration is the minimum statement execution time, in milliseconds, that will cause the statement's plan to - be logged. Setting this to zero logs all plans. Minus-one (the default) - disables logging of plans. For example, if you set it to - 250ms then all statements that run 250ms or longer - will be logged. Only superusers can change this setting. + be logged. Setting this to 0 logs all plans. + -1 (the default) disables logging of plans. For + example, if you set it to 250ms then all statements + that run 250ms or longer will be logged. Only superusers can change this + setting. @@ -169,6 +170,24 @@ LOAD 'auto_explain'; + + + auto_explain.log_settings (boolean) + + auto_explain.log_settings configuration parameter + + + + + auto_explain.log_settings controls whether information + about modified configuration options are printed when execution plan is logged. + Only options affecting query planning with value different from the built-in + default value are included in the output. This parameter is off by default. + Only superusers can change this setting. + + + + auto_explain.log_format (enum) @@ -187,6 +206,27 @@ LOAD 'auto_explain'; + + + auto_explain.log_level (enum) + + auto_explain.log_level configuration parameter + + + + + auto_explain.log_level selects the log level at which + auto_explain will log the query plan. + Valid values are DEBUG5, DEBUG4, + DEBUG3, DEBUG2, + DEBUG1, INFO, + NOTICE, WARNING, + and LOG. The default is LOG. + Only superusers can change this setting. + + + + auto_explain.log_nested_statements (boolean) diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml index 349834c35d8..bdc9026c629 100644 --- a/doc/src/sgml/backup.sgml +++ b/doc/src/sgml/backup.sgml @@ -141,7 +141,7 @@ psql dbname < psql exit with an exit status of 3 if an SQL error occurs: -psql --set ON_ERROR_STOP=on dbname < dumpfile +psql --set ON_ERROR_STOP=on dbname < dumpfile Either way, you will only have a partially restored database. Alternatively, you can specify that the whole dump should be @@ -824,8 +824,9 @@ test ! -f /mnt/server/archivedir/00000001000000A900000065 && cp pg_wal/0 way. The non-exclusive method is recommended and the exclusive one is deprecated and will eventually be removed. + - Making a non-exclusive low level backup + Making a Non-Exclusive Low-Level Backup A non-exclusive low level backup is one that allows other concurrent backups to be running (both those started using @@ -947,14 +948,27 @@ SELECT * FROM pg_stop_backup(false, true); - Making an exclusive low level backup + Making an Exclusive Low-Level Backup + + + + The exclusive backup method is deprecated and should be avoided. + Prior to PostgreSQL 9.6, this was the only + low-level method available, but it is now recommended that all users + upgrade their scripts to use non-exclusive backups. + + + The process for an exclusive backup is mostly the same as for a - non-exclusive one, but it differs in a few key steps. This type of backup - can only be taken on a primary and does not allow concurrent backups. - Prior to PostgreSQL 9.6, this - was the only low-level method available, but it is now recommended that - all users upgrade their scripts to use non-exclusive backups if possible. + non-exclusive one, but it differs in a few key steps. This type of + backup can only be taken on a primary and does not allow concurrent + backups. Moreover, because it creates a backup label file, as + described below, it can block automatic restart of the master server + after a crash. On the other hand, the erroneous removal of this + file from a backup or standby is a common mistake, which can result + in serious data corruption. If it is necessary to use this method, + the following steps may be used. @@ -1011,9 +1025,17 @@ SELECT pg_start_backup('label', true); consider during this backup. - Note that if the server crashes during the backup it may not be - possible to restart until the backup_label file has been - manually deleted from the PGDATA directory. + As noted above, if the server crashes during the backup it may not be + possible to restart until the backup_label file has + been manually deleted from the PGDATA directory. Note + that it is very important to never remove the + backup_label file when restoring a backup, because + this will result in corruption. Confusion about when it is appropriate + to remove this file is a common cause of data corruption when using this + method; be very certain that you remove the file only on an existing + master and never when building a standby or restoring a backup, even if + you are building a standby that will subsequently be promoted to a new + master. @@ -1045,18 +1067,23 @@ SELECT pg_stop_backup(); If the archive process has fallen behind because of failures of the archive command, it will keep retrying until the archive succeeds and the backup is complete. - If you wish to place a time limit on the execution of - pg_stop_backup, set an appropriate - statement_timeout value, but make note that if - pg_stop_backup terminates because of this your backup - may not be valid. + + + + When using exclusive backup mode, it is absolutely imperative to ensure + that pg_stop_backup completes successfully at the + end of the backup. Even if the backup itself fails, for example due to + lack of disk space, failure to call pg_stop_backup + will leave the server in backup mode indefinitely, causing future backups + to fail and increasing the risk of a restart failure during the time that + backup_label exists. - Backing up the data directory + Backing Up the Data Directory Some file system backup tools emit warnings or errors if the files they are trying to copy change while the copy proceeds. @@ -1220,8 +1247,11 @@ SELECT pg_stop_backup(); - Create a recovery command file recovery.conf in the cluster - data directory (see ). You might + Set recovery configuration settings in + postgresql.conf (see ) and create a file + recovery.signal in the cluster + data directory. You might also want to temporarily modify pg_hba.conf to prevent ordinary users from connecting until you are sure the recovery was successful. @@ -1232,8 +1262,8 @@ SELECT pg_stop_backup(); proceed to read through the archived WAL files it needs. Should the recovery be terminated because of an external error, the server can simply be restarted and it will continue recovery. Upon completion - of the recovery process, the server will rename - recovery.conf to recovery.done (to prevent + of the recovery process, the server will remove + recovery.signal (to prevent accidentally re-entering recovery mode later) and then commence normal database operations. @@ -1249,12 +1279,9 @@ SELECT pg_stop_backup(); - The key part of all this is to set up a recovery configuration file that + The key part of all this is to set up a recovery configuration that describes how you want to recover and how far the recovery should - run. You can use recovery.conf.sample (normally - located in the installation's share/ directory) as a - prototype. The one thing that you absolutely must specify in - recovery.conf is the restore_command, + run. The one thing that you absolutely must specify is the restore_command, which tells PostgreSQL how to retrieve archived WAL file segments. Like the archive_command, this is a shell command string. It can contain %f, which is @@ -1288,7 +1315,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' Not all of the requested files will be WAL segment files; you should also expect requests for files with a suffix of - .backup or .history. Also be aware that + .history. Also be aware that the base name of the %p path will be different from %f; do not expect them to be interchangeable. @@ -1316,7 +1343,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' If you want to recover to some previous point in time (say, right before the junior DBA dropped your main transaction table), just specify the - required stopping point in recovery.conf. You can specify + required stopping point. You can specify the stop point, known as the recovery target, either by date/time, named restore point or by completion of a specific transaction ID. As of this writing only the date/time and named restore point options @@ -1414,7 +1441,7 @@ restore_command = 'cp /mnt/server/archivedir/%f %p' that was current when the base backup was taken. If you wish to recover into some child timeline (that is, you want to return to some state that was itself generated after a recovery attempt), you need to specify the - target timeline ID in recovery.conf. You cannot recover into + target timeline ID in . You cannot recover into timelines that branched off earlier than the base backup. diff --git a/doc/src/sgml/bgworker.sgml b/doc/src/sgml/bgworker.sgml index ac71fb2c41f..bc5a52584b9 100644 --- a/doc/src/sgml/bgworker.sgml +++ b/doc/src/sgml/bgworker.sgml @@ -189,15 +189,17 @@ typedef struct BackgroundWorker Once running, the process can connect to a database by calling - BackgroundWorkerInitializeConnection(char *dbname, char *username) or - BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid). + BackgroundWorkerInitializeConnection(char *dbname, char *username, uint32 flags) or + BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags). This allows the process to run transactions and queries using the SPI interface. If dbname is NULL or dboid is InvalidOid, the session is not connected to any particular database, but shared catalogs can be accessed. If username is NULL or useroid is InvalidOid, the process will run as the superuser created - during initdb. + during initdb. If BGWORKER_BYPASS_ALLOWCONN + is specified as flags it is possible to bypass the restriction + to connect to databases not allowing user connections. A background worker can only call one of these two functions, and only once. It is not possible to switch databases. diff --git a/doc/src/sgml/biblio.sgml b/doc/src/sgml/biblio.sgml index 49530241620..bf3aebd2a88 100644 --- a/doc/src/sgml/biblio.sgml +++ b/doc/src/sgml/biblio.sgml @@ -136,6 +136,14 @@ 1988 + + <ulink url="http://standards.iso.org/ittf/PubliclyAvailableStandards/c067367_ISO_IEC_TR_19075-6_2017.zip">SQL Technical Report</ulink> + Part 6: SQL support for JavaScript Object + Notation (JSON) + First Edition + 2017 + + diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml index f7a323ef345..6523dd5032c 100644 --- a/doc/src/sgml/bki.sgml +++ b/doc/src/sgml/bki.sgml @@ -65,7 +65,7 @@ - Most Postgres developers don't need to be directly concerned with + Most PostgreSQL developers don't need to be directly concerned with the BKI file, but almost any nontrivial feature addition in the backend will require modifying the catalog header files and/or initial data files. The rest of this chapter gives some @@ -89,7 +89,7 @@ The CATALOG line can also be annotated, with some other BKI property macros described in genbki.h, to define other properties of the catalog as a whole, such as whether - it has OIDs (by default, it does). + it is a shared relation. @@ -184,16 +184,13 @@ [ -# LC_COLLATE and LC_CTYPE will be replaced at initdb time with user choices -# that might contain non-word characters, so we must double-quote them. - +# A comment could appear here. { oid => '1', oid_symbol => 'TemplateDbOid', descr => 'database\'s default template', - datname => 'template1', datdba => 'PGUID', encoding => 'ENCODING', - datcollate => '"LC_COLLATE"', datctype => '"LC_CTYPE"', datistemplate => 't', - datallowconn => 't', datconnlimit => '-1', datlastsysoid => '0', - datfrozenxid => '0', datminmxid => '1', dattablespace => '1663', - datacl => '_null_' }, + datname => 'template1', encoding => 'ENCODING', datcollate => 'LC_COLLATE', + datctype => 'LC_CTYPE', datistemplate => 't', datallowconn => 't', + datconnlimit => '-1', datlastsysoid => '0', datfrozenxid => '0', + datminmxid => '1', dattablespace => 'pg_default', datacl => '_null_' }, ] @@ -219,40 +216,44 @@ value pairs. The allowed keys are the names of the catalog's columns, plus the metadata keys oid, - oid_symbol, and descr. + oid_symbol, + array_type_oid, and descr. (The use of oid and oid_symbol - is described in - below. descr supplies a description string for - the object, which will be inserted - into pg_description + is described in below, + while array_type_oid is described in + . + descr supplies a description string for the object, + which will be inserted into pg_description or pg_shdescription as appropriate.) While the metadata keys are optional, the catalog's defined columns must all be provided, except when the catalog's .h file specifies a default value for the column. + (In the example above, the datdba field has + been omitted because pg_database.h supplies a + suitable default value for it.) - All values must be single-quoted. Escape single quotes used within - a value with a backslash. (Backslashes meant as data need not be - doubled, however; this follows Perl's rules for simple quoted - literals.) + All values must be single-quoted. Escape single quotes used within a + value with a backslash. Backslashes meant as data can, but need not, + be doubled; this follows Perl's rules for simple quoted literals. + Note that backslashes appearing as data will be treated as escapes by + the bootstrap scanner, according to the same rules as for escape string + constants (see ); for + example \t converts to a tab character. If you + actually want a backslash in the final value, you will need to write + four of them: Perl strips two, leaving \\ for the + bootstrap scanner to see. Null values are represented by _null_. - - - - - - If a value is a macro to be expanded - by initdb, it should also contain double - quotes as shown above, unless we know that no special characters can - appear within the string that will be substituted. + (Note that there is no way to create a value that is just that + string.) @@ -265,8 +266,10 @@ - To aid readability, field values that are OIDs of other catalog - entries can be represented by names rather than numeric OIDs. + Field values that are OIDs of other catalog entries should be + represented by symbolic names rather than actual numeric OIDs. + (In the example above, dattablespace + contains such a reference.) This is described in below. @@ -285,8 +288,9 @@ Within each pair of curly braces, the metadata fields oid, oid_symbol, - and descr (if present) come first, in that - order, then the catalog's own fields appear in their defined order. + array_type_oid, and descr + (if present) come first, in that order, then the catalog's own + fields appear in their defined order. @@ -354,7 +358,7 @@ also needed if the row's OID must be referenced from C code. If neither case applies, the oid metadata field can be omitted, in which case the bootstrap code assigns an OID - automatically, or leaves it zero in a catalog that has no OIDs. + automatically. In practice we usually preassign OIDs for all or none of the pre-loaded rows in a given catalog, even if only some of them are actually cross-referenced. @@ -387,15 +391,52 @@ through the catalog headers and .dat files to see which ones do not appear. You can also use the duplicate_oids script to check for mistakes. - (That script is run automatically at compile time, and will stop the - build if a duplicate is found.) + (genbki.pl will assign OIDs for any rows that + didn't get one hand-assigned to them, and it will also detect duplicate + OIDs at compile time.) + + + + When choosing OIDs for a patch that is not expected to be committed + immediately, best practice is to use a group of more-or-less + consecutive OIDs starting with some random choice in the range + 8000—9999. This minimizes the risk of OID collisions with other + patches being developed concurrently. To keep the 8000—9999 + range free for development purposes, after a patch has been committed + to the master git repository its OIDs should be renumbered into + available space below that range. Typically, this will be done + near the end of each development cycle, moving all OIDs consumed by + patches committed in that cycle at the same time. The script + renumber_oids.pl can be used for this purpose. + If an uncommitted patch is found to have OID conflicts with some + recently-committed patch, renumber_oids.pl may + also be useful for recovering from that situation. - The OID counter starts at 10000 at the beginning of a bootstrap run. - If a catalog row is in a table that requires OIDs, but no OID was - preassigned by an oid field, then it will - receive an OID of 10000 or above. + Because of this convention of possibly renumbering OIDs assigned by + patches, the OIDs assigned by a patch should not be considered stable + until the patch has been included in an official release. We do not + change manually-assigned object OIDs once released, however, as that + would create assorted compatibility problems. + + + + If genbki.pl needs to assign an OID to a catalog + entry that does not have a manually-assigned OID, it will use a value in + the range 10000—11999. The server's OID counter is set to 12000 + at the start of a bootstrap run. Thus objects created by regular SQL + commands during the later phases of bootstrap, such as objects created + while running the information_schema.sql script, + receive OIDs of 12000 or above. + + + + OIDs assigned during normal database operation are constrained to be + 16384 or higher. This ensures that the range 10000—16383 is free + for OIDs assigned automatically by genbki.pl or + during bootstrap. These automatically-assigned OIDs are not considered + stable, and may change from one installation to another. @@ -403,13 +444,14 @@ OID Reference Lookup - Cross-references from one initial catalog row to another can be written - by just writing the preassigned OID of the referenced row. But - that's error-prone and hard to understand, so for frequently-referenced - catalogs, genbki.pl provides mechanisms to write - symbolic references instead. Currently this is possible for references - to access methods, functions, operators, opclasses, opfamilies, and - types. The rules are as follows: + In principle, cross-references from one initial catalog row to another + could be written just by writing the preassigned OID of the referenced + row in the referencing field. However, that is against project + policy, because it is error-prone, hard to read, and subject to + breakage if a newly-assigned OID is renumbered. Therefore + genbki.pl provides mechanisms to write + symbolic references instead. + The rules are as follows: @@ -419,9 +461,7 @@ Use of symbolic references is enabled in a particular catalog column by attaching BKI_LOOKUP(lookuprule) to the column's definition, where lookuprule - is pg_am, pg_proc, - pg_operator, pg_opclass, - pg_opfamily, or pg_type. + is the name of the referenced catalog, e.g. pg_proc. BKI_LOOKUP can be attached to columns of type Oid, regproc, oidvector, or Oid[]; in the latter two cases it implies performing a @@ -429,6 +469,15 @@ + + + It's also permissible to attach BKI_LOOKUP(encoding) + to integer columns to reference character set encodings, which are + not currently represented as catalog OIDs, but have a set of values + known to genbki.pl. + + + In such a column, all entries must use the symbolic format except @@ -441,10 +490,11 @@ - Access methods are just represented by their names, as are types. - Type names must match the referenced pg_type - entry's typname; you do not get to use any - aliases such as integer + Most kinds of catalog objects are simply referenced by their names. + Note that type names must exactly match the + referenced pg_type + entry's typname; you do not get to use + any aliases such as integer for int4. @@ -488,7 +538,18 @@ In none of these cases is there any provision for schema-qualification; all objects created during bootstrap are - expected to be in the pg_catalog schema. + expected to be in the pg_catalog schema. + + + + + + In addition to the generic lookup mechanisms, there is a special + convention that PGNSP is replaced by the OID of + the pg_catalog schema, + and PGUID is replaced by the OID of the bootstrap + superuser role. These usages are somewhat historical but so far + there hasn't been a need to generalize them. @@ -501,6 +562,41 @@ + + Automatic Creation of Array Types + + + Most scalar data types should have a corresponding array type (that is, + a standard varlena array type whose element type is the scalar type, and + which is referenced by the typarray field of + the scalar type's pg_type + entry). genbki.pl is able to generate + the pg_type entry for the array type + automatically in most cases. + + + + To use this facility, just write an array_type_oid + => nnnn metadata field in the + scalar type's pg_type entry, specifying the OID + to use for the array type. You may then omit + the typarray field, since it will be filled + automatically with that OID. + + + + The generated array type's name is the scalar type's name with an + underscore prepended. The array entry's other fields are filled from + BKI_ARRAY_DEFAULT(value) + annotations in pg_type.h, or if there isn't one, + copied from the scalar type. (There's also a special case + for typalign.) Then + the typelem + and typarray fields of the two entries are + set to cross-reference each other. + + + Recipes for Editing Data Files @@ -599,7 +695,7 @@ Run the new script: $ cd src/include/catalog -$ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat +$ perl rewrite_dat_with_prokind.pl pg_proc.dat At this point pg_proc.dat has all three columns, prokind, @@ -679,7 +775,6 @@ $ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat tableoid bootstrap shared_relation - without_oids rowtype_oid oid (name1 = type1 @@ -731,7 +826,6 @@ $ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat The table is created as shared if shared_relation is specified. - It will have OIDs unless without_oids is specified. The table's row type OID (pg_type OID) can optionally be specified via the rowtype_oid clause; if not specified, an OID is automatically generated for it. (The rowtype_oid @@ -757,20 +851,20 @@ $ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat - close tablename + close tablename - Close the open table. The name of the table can be given as a - cross-check, but this is not required. + Close the open table. The name of the table must be given as a + cross-check. - insert OID = oid_value ( value1 value2 ... ) + insert ( oid_value value1 value2 ... ) @@ -778,17 +872,13 @@ $ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat Insert a new row into the open table using value1, value2, etc., for its column - values and oid_value for its OID. If - oid_value is zero - (0) or the clause is omitted, and the table has OIDs, then the - next available OID is assigned. + values. NULL values can be specified using the special key word - _null_. Values containing spaces must be - double quoted. + _null_. Values that do not look like + identifiers or digit strings must be double quoted. @@ -950,16 +1040,16 @@ $ perl -I ../../backend/catalog rewrite_dat_with_prokind.pl pg_proc.dat BKI Example - The following sequence of commands will create the - table test_table with OID 420, having two columns - cola and colb of type - int4 and text, respectively, and insert - two rows into the table: + The following sequence of commands will create the table + test_table with OID 420, having three columns + oid, cola and colb + of type oid, int4 and text, + respectively, and insert two rows into the table: -create test_table 420 (cola = int4, colb = text) +create test_table 420 (oid = oid, cola = int4, colb = text) open test_table -insert OID=421 ( 1 "value1" ) -insert OID=422 ( 2 _null_ ) +insert ( 421 1 "value1" ) +insert ( 422 2 _null_ ) close test_table diff --git a/doc/src/sgml/bloom.sgml b/doc/src/sgml/bloom.sgml index e13ebf80fdf..6eeaddee093 100644 --- a/doc/src/sgml/bloom.sgml +++ b/doc/src/sgml/bloom.sgml @@ -9,7 +9,7 @@ bloom provides an index access method based on - Bloom filters. + Bloom filters. @@ -51,8 +51,9 @@ length - Length of each signature (index entry) in bits. The default - is 80 bits and maximum is 4096. + Length of each signature (index entry) in bits. It is rounded up to the + nearest multiple of 16. The default is + 80 bits and the maximum is 4096. @@ -242,6 +243,20 @@ DEFAULT FOR TYPE text USING bloom AS operations in the future. + + + + bloom access method doesn't support + UNIQUE indexes. + + + + + + bloom access method doesn't support searching for + NULL values. + + diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml index f02e061bc1c..da0c9111534 100644 --- a/doc/src/sgml/brin.sgml +++ b/doc/src/sgml/brin.sgml @@ -129,17 +129,6 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was - - abstime_minmax_ops - abstime - - < - <= - = - >= - > - - int8_minmax_ops bigint @@ -388,17 +377,6 @@ LOG: request for BRIN range summarization for index "brin_wi_idx" page 128 was > - - reltime_minmax_ops - reltime - - < - <= - = - >= - > - - int2_minmax_ops smallint @@ -537,7 +515,7 @@ typedef struct BrinOpcInfo } BrinOpcInfo; BrinOpcInfo.oi_opaque can be used by the - operator class routines to pass information between support procedures + operator class routines to pass information between support functions during an index scan. @@ -587,27 +565,27 @@ typedef struct BrinOpcInfo defined by the user for other data types using equivalent definitions, without having to write any source code; appropriate catalog entries being declared is enough. Note that assumptions about the semantics of operator - strategies are embedded in the support procedures' source code. + strategies are embedded in the support functions' source code. Operator classes that implement completely different semantics are also - possible, provided implementations of the four main support procedures + possible, provided implementations of the four main support functions described above are written. Note that backwards compatibility across major - releases is not guaranteed: for example, additional support procedures might + releases is not guaranteed: for example, additional support functions might be required in later releases. To write an operator class for a data type that implements a totally - ordered set, it is possible to use the minmax support procedures + ordered set, it is possible to use the minmax support functions alongside the corresponding operators, as shown in . - All operator class members (procedures and operators) are mandatory. + All operator class members (functions and operators) are mandatory. - Procedure and Support Numbers for Minmax Operator Classes + Function and Support Numbers for Minmax Operator Classes @@ -617,19 +595,19 @@ typedef struct BrinOpcInfo - Support Procedure 1 + Support Function 1 internal function brin_minmax_opcinfo() - Support Procedure 2 + Support Function 2 internal function brin_minmax_add_value() - Support Procedure 3 + Support Function 3 internal function brin_minmax_consistent() - Support Procedure 4 + Support Function 4 internal function brin_minmax_union() @@ -659,7 +637,7 @@ typedef struct BrinOpcInfo To write an operator class for a complex data type which has values included within another type, it's possible to use the inclusion support - procedures alongside the corresponding operators, as shown + functions alongside the corresponding operators, as shown in . It requires only a single additional function, which can be written in any language. More functions can be defined for additional functionality. All operators @@ -668,7 +646,7 @@ typedef struct BrinOpcInfo
- Procedure and Support Numbers for Inclusion Operator Classes + Function and Support Numbers for Inclusion Operator Classes @@ -679,42 +657,42 @@ typedef struct BrinOpcInfo - Support Procedure 1 + Support Function 1 internal function brin_inclusion_opcinfo() - Support Procedure 2 + Support Function 2 internal function brin_inclusion_add_value() - Support Procedure 3 + Support Function 3 internal function brin_inclusion_consistent() - Support Procedure 4 + Support Function 4 internal function brin_inclusion_union() - Support Procedure 11 + Support Function 11 function to merge two elements - Support Procedure 12 + Support Function 12 optional function to check whether two elements are mergeable - Support Procedure 13 + Support Function 13 optional function to check if an element is contained within another - Support Procedure 14 + Support Function 14 optional function to check whether an element is empty @@ -803,7 +781,7 @@ typedef struct BrinOpcInfo
- Support procedure numbers 1-10 are reserved for the BRIN internal + Support function numbers 1-10 are reserved for the BRIN internal functions, so the SQL level functions start with number 11. Support function number 11 is the main function required to build the index. It should accept two arguments with the same data type as the operator class, @@ -814,11 +792,11 @@ typedef struct BrinOpcInfo - Support procedure numbers 12 and 14 are provided to support - irregularities of built-in data types. Procedure number 12 + Support function numbers 12 and 14 are provided to support + irregularities of built-in data types. Function number 12 is used to support network addresses from different families which - are not mergeable. Procedure number 14 is used to support - empty ranges. Procedure number 13 is an optional but + are not mergeable. Function number 14 is used to support + empty ranges. Function number 13 is an optional but recommended one, which allows the new value to be checked before it is passed to the union function. As the BRIN framework can shortcut some operations when the union is not changed, using this diff --git a/doc/src/sgml/btree.sgml b/doc/src/sgml/btree.sgml index ca81fbbc848..5881ea5dd6d 100644 --- a/doc/src/sgml/btree.sgml +++ b/doc/src/sgml/btree.sgml @@ -13,7 +13,7 @@ PostgreSQL includes an implementation of the - standard btree (multi-way binary tree) index data + standard btree (multi-way balanced tree) index data structure. Any data type that can be sorted into a well-defined linear order can be indexed by a btree index. The only limitation is that an index entry cannot exceed approximately one-third of a page (after TOAST @@ -228,11 +228,8 @@ B, A = B, or A > - B, respectively. The function must not - return INT_MIN for the A - < B case, - since the value may be negated before being tested for sign. A null - result is disallowed, too. + B, respectively. + A null result is disallowed: all values of the data type must be comparable. See src/backend/access/nbtree/nbtcompare.c for examples. @@ -301,7 +298,7 @@ returns bool The essential semantics of an in_range function - depend on the two boolean flag parameters. It should add or + depend on the two Boolean flag parameters. It should add or subtract base and offset, then compare val to the result, as follows: @@ -344,7 +341,7 @@ returns bool Before doing so, the function should check the sign of offset: if it is less than zero, raise - error ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE (22013) + error ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE (22013) with error text like invalid preceding or following size in window function. (This is required by the SQL standard, although nonstandard operator families might perhaps choose to ignore this @@ -433,23 +430,6 @@ returns bool - - Included attributes in B-tree indexes - - - As of PostgreSQL 11.0 there is an optional - INCLUDE clause, which allows to add non-key (included) attributes to index. - Those included attributes allow more queries to benefit from index-only scans. - We never use included attributes in ScanKeys for search. That allows us to - include into B-tree any datatypes, even those which don't have suitable - operator classes. Included columns only stored in regular tuples on leaf - pages. All pivot tuples on non-leaf pages and highkey tuples are truncated - to contain only key attributes. That helps to slightly reduce the size of - index. - - - - Implementation diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index 14aeed30763..5e71a2e8654 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -57,7 +57,7 @@ pg_am - index access methods + relation access methods @@ -67,7 +67,7 @@ pg_amproc - access method support procedures + access method support functions @@ -297,7 +297,12 @@ pg_statistic_ext - extended planner statistics + extended planner statistics (definition) + + + + pg_statistic_ext_data + extended planner statistics (built statistics) @@ -587,8 +592,9 @@ The catalog pg_am stores information about relation access methods. There is one row for each access method supported by the system. - Currently, only indexes have access methods. The requirements for index - access methods are discussed in detail in . + Currently, only tables and indexes have access methods. The requirements for table + and index access methods are discussed in detail in and + respectively. @@ -609,7 +615,7 @@ oidoid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -634,8 +640,8 @@ char - Currently always i to indicate an index access - method; other values may be allowed in future + t = table (including materialized views), + i = index. @@ -693,7 +699,7 @@ oidoid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -814,8 +820,8 @@ The catalog pg_amproc stores information about - support procedures associated with access method operator families. There - is one row for each support procedure belonging to an operator family. + support functions associated with access method operator families. There + is one row for each support function belonging to an operator family.
@@ -836,7 +842,7 @@ oidoid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -864,14 +870,14 @@ amprocnum int2 - Support procedure number + Support function number amproc regproc pg_proc.oid - OID of the procedure + OID of the function @@ -882,9 +888,9 @@ The usual interpretation of the amproclefttype and amprocrighttype fields is that they identify the left and right input types of the operator(s) - that a particular support procedure supports. For some access methods - these match the input data type(s) of the support procedure itself, for - others not. There is a notion of default support procedures for + that a particular support function supports. For some access methods + these match the input data type(s) of the support function itself, for + others not. There is a notion of default support functions for an index, which are those with amproclefttype and amprocrighttype both equal to the index operator class's opcintype. @@ -901,11 +907,11 @@ - The catalog pg_attrdef stores column default values. The main information - about columns is stored in pg_attribute - (see below). Only columns that explicitly specify a default value - (when the table is created or the column is added) will have an - entry here. + The catalog pg_attrdef stores column default + values. The main information about columns is stored in + pg_attribute. + Only columns for which a default value has been explicitly set will have + an entry here.
@@ -926,7 +932,7 @@ oidoid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -947,27 +953,13 @@ adbin pg_node_tree - The internal representation of the column default value - - - - adsrc - text - - A human-readable representation of the default value + The column default value, in nodeToString() + representation. Use pg_get_expr(adbin, adrelid) to + convert it to an SQL expression.
- - - The adsrc field is historical, and is best - not used, because it does not track outside changes that might affect - the representation of the default value. Reverse-compiling the - adbin field (with pg_get_expr for - example) is a better way to display the default value. - - @@ -1060,7 +1052,7 @@ The number of the column. Ordinary columns are numbered from 1 - up. System columns, such as oid, + up. System columns, such as ctid, have (arbitrary) negative numbers.
@@ -1143,9 +1135,11 @@ bool - This column has a default value, in which case there will be a - corresponding entry in the pg_attrdef - catalog that actually defines the value. + This column has a default expression or generation expression, in which + case there will be a corresponding entry in the + pg_attrdef catalog that actually defines the + expression. (Check attgenerated to + determine whether this is a default or a generation expression.) @@ -1173,6 +1167,17 @@ + + attgenerated + char + + + If a zero byte (''), then not a generated column. + Otherwise, s = stored. (Other values might be added + in the future.) + + + attisdropped bool @@ -1326,7 +1331,7 @@ oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -1552,7 +1557,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -1675,7 +1680,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -1725,7 +1730,10 @@ SCRAM-SHA-256$<iteration count>:&l relam oid pg_am.oid - If this is an index, the access method used (B-tree, hash, etc.) + + If this is a table or an index, the access method used (heap, + B-tree, hash, etc.) + @@ -1840,7 +1848,8 @@ SCRAM-SHA-256$<iteration count>:&l m = materialized view, c = composite type, f = foreign table, - p = partitioned table + p = partitioned table, + I = partitioned index @@ -1866,15 +1875,6 @@ SCRAM-SHA-256$<iteration count>:&l - - relhasoids - bool - - - True if we generate an OID for each row of the relation - - - relhasrules bool @@ -1899,7 +1899,9 @@ SCRAM-SHA-256$<iteration count>:&l relhassubclass bool - True if table has (or once had) any inheritance children + + True if table or index has (or once had) any inheritance children + @@ -1947,7 +1949,7 @@ SCRAM-SHA-256$<iteration count>:&l relispartition bool - True if table is a partition + True if table or index is a partition @@ -1993,10 +1995,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -2066,7 +2065,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -2100,6 +2099,13 @@ SCRAM-SHA-256$<iteration count>:&l default, c = libc, i = icu + + collisdeterministic + bool + + Is the collation deterministic? + + collencoding int4 @@ -2204,7 +2210,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -2372,14 +2378,6 @@ SCRAM-SHA-256$<iteration count>:&l triggers), list of the constrained columns - - conincluding - int2[] - pg_attribute.attnum - List of the non-constrained columns which are included into - the same index as the constrained columns - - confkey int2[] @@ -2419,14 +2417,10 @@ SCRAM-SHA-256$<iteration count>:&l conbin pg_node_tree - If a check constraint, an internal representation of the expression - - - - consrc - text - - If a check constraint, a human-readable representation of the expression + If a check constraint, an internal representation of the + expression. (It's recommended to use + pg_get_constraintdef() to extract the definition of + a check constraint.) @@ -2442,15 +2436,6 @@ SCRAM-SHA-256$<iteration count>:&l index.) - - - consrc is not updated when referenced objects - change; for example, it won't track renaming of columns. Rather than - relying on this field, it's best to use pg_get_constraintdef() - to extract the definition of a check constraint. - - - pg_class.relchecks needs to agree with the @@ -2470,7 +2455,7 @@ SCRAM-SHA-256$<iteration count>:&l The catalog pg_conversion describes - encoding conversion procedures. See + encoding conversion functions. See for more information. @@ -2492,7 +2477,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -2536,7 +2521,7 @@ SCRAM-SHA-256$<iteration count>:&l conproc regproc pg_proc.oid - Conversion procedure + Conversion function @@ -2592,7 +2577,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -2720,10 +2705,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -2822,7 +2804,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -2849,7 +2831,8 @@ SCRAM-SHA-256$<iteration count>:&l r = relation (table, view), S = sequence, f = function, - T = type + T = type, + n = schema @@ -3016,7 +2999,7 @@ SCRAM-SHA-256$<iteration count>:&l referenced object, and should be automatically dropped (regardless of RESTRICT or CASCADE mode) if the referenced object is dropped. Example: a named - constraint on a table is made autodependent on the table, so + constraint on a table is made auto-dependent on the table, so that it will go away if the table is dropped. @@ -3028,38 +3011,61 @@ SCRAM-SHA-256$<iteration count>:&l The dependent object was created as part of creation of the referenced object, and is really just a part of its internal - implementation. A DROP of the dependent object - will be disallowed outright (we'll tell the user to issue a - DROP against the referenced object, instead). A - DROP of the referenced object will be propagated - through to drop the dependent object whether - CASCADE is specified or not. Example: a trigger - that's created to enforce a foreign-key constraint is made - internally dependent on the constraint's - pg_constraint entry. + implementation. A direct DROP of the dependent + object will be disallowed outright (we'll tell the user to issue + a DROP against the referenced object, instead). + A DROP of the referenced object will result in + automatically dropping the dependent object + whether CASCADE is specified or not. If the + dependent object has to be dropped due to a dependency on some other + object being removed, its drop is converted to a drop of the referenced + object, so that NORMAL and AUTO + dependencies of the dependent object behave much like they were + dependencies of the referenced object. + Example: a view's ON SELECT rule is made + internally dependent on the view, preventing it from being dropped + while the view remains. Dependencies of the rule (such as tables it + refers to) act as if they were dependencies of the view. - DEPENDENCY_INTERNAL_AUTO (I) + DEPENDENCY_PARTITION_PRI (P) + DEPENDENCY_PARTITION_SEC (S) The dependent object was created as part of creation of the referenced object, and is really just a part of its internal - implementation. A DROP of the dependent object - will be disallowed outright (we'll tell the user to issue a - DROP against the referenced object, instead). - While a regular internal dependency will prevent - the dependent object from being dropped while any such dependencies - remain, DEPENDENCY_INTERNAL_AUTO will allow such - a drop as long as the object can be found by following any of such + implementation; however, unlike INTERNAL, + there is more than one such referenced object. The dependent object + must not be dropped unless at least one of these referenced objects + is dropped; if any one is, the dependent object should be dropped + whether or not CASCADE is specified. Also + unlike INTERNAL, a drop of some other object + that the dependent object depends on does not result in automatic + deletion of any partition-referenced object. Hence, if the drop + does not cascade to at least one of these objects via some other + path, it will be refused. (In most cases, the dependent object + shares all its non-partition dependencies with at least one + partition-referenced object, so that this restriction does not + result in blocking any cascaded delete.) + Primary and secondary partition dependencies behave identically + except that the primary dependency is preferred for use in error + messages; hence, a partition-dependent object should have one + primary partition dependency and one or more secondary partition dependencies. - Example: an index on a partition is made internal-auto-dependent on - both the partition itself as well as on the index on the parent - partitioned table; so the partition index is dropped together with - either the partition it indexes, or with the parent index it is - attached to. + Note that partition dependencies are made in addition to, not + instead of, any dependencies the object would normally have. This + simplifies ATTACH/DETACH PARTITION operations: + the partition dependencies need only be added or removed. + Example: a child partitioned index is made partition-dependent + on both the partition table it is on and the parent partitioned + index, so that it goes away if either of those is dropped, but + not otherwise. The dependency on the parent index is primary, + so that if the user tries to drop the child partitioned index, + the error message will suggest dropping the parent index instead + (not the table). @@ -3072,9 +3078,10 @@ SCRAM-SHA-256$<iteration count>:&l the referenced object (see pg_extension). The dependent object can be dropped only via - DROP EXTENSION on the referenced object. Functionally - this dependency type acts the same as an internal dependency, but - it's kept separate for clarity and to simplify pg_dump. + DROP EXTENSION on the referenced object. + Functionally this dependency type acts the same as + an INTERNAL dependency, but it's kept separate for + clarity and to simplify pg_dump. @@ -3084,10 +3091,13 @@ SCRAM-SHA-256$<iteration count>:&l The dependent object is not a member of the extension that is the - referenced object (and so should not be ignored by pg_dump), but - cannot function without it and should be dropped when the - extension itself is. The dependent object may be dropped on its - own as well. + referenced object (and so it should not be ignored + by pg_dump), but it cannot function + without the extension and should be auto-dropped if the extension is. + The dependent object may be dropped on its own as well. + Functionally this dependency type acts the same as + an AUTO dependency, but it's kept separate for + clarity and to simplify pg_dump. @@ -3109,6 +3119,19 @@ SCRAM-SHA-256$<iteration count>:&l Other dependency flavors might be needed in future. + + Note that it's quite possible for two objects to be linked by more than + one pg_depend entry. For example, a child + partitioned index would have both a partition-type dependency on its + associated partition table, and an auto dependency on each column of + that table that it indexes. This sort of situation expresses the union + of multiple dependency semantics. A dependent object can be dropped + without CASCADE if any of its dependencies satisfies + its condition for automatic dropping. Conversely, all the + dependencies' restrictions about which objects must be dropped together + must be satisfied. + + @@ -3219,7 +3242,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -3382,7 +3405,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -3485,7 +3508,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -3531,10 +3554,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -3584,7 +3604,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -3627,10 +3647,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -3752,15 +3769,16 @@ SCRAM-SHA-256$<iteration count>:&l int2 The total number of columns in the index (duplicates - pg_class.relnatts). This number includes both key and included attributes. + pg_class.relnatts); this number includes both key and included attributes indnkeyatts int2 - The number of key columns in the index. "Key columns" are ordinary - index columns (as opposed to "included" columns). + The number of key columns in the index, + not counting any included columns, which are + merely stored and do not participate in the index semantics @@ -3866,7 +3884,8 @@ SCRAM-SHA-256$<iteration count>:&l This is an array of indnatts values that indicate which table columns this index indexes. For example a value of 1 3 would mean that the first and the third table - columns make up the index key. A zero in this array indicates that the + columns make up the index entries. Key columns come before non-key + (included) columns. A zero in this array indicates that the corresponding index attribute is an expression over the table columns, rather than a simple column reference. @@ -3877,9 +3896,10 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_collation.oid - For each column in the index key, this contains the OID of the - collation to use for the index, or zero if the column is not - of a collatable data type. + For each column in the index key + (indnkeyatts values), this contains the OID + of the collation to use for the index, or zero if the column is not of + a collatable data type. @@ -3888,8 +3908,9 @@ SCRAM-SHA-256$<iteration count>:&l oidvector pg_opclass.oid - For each column in the index key, this contains the OID of - the operator class to use. See + For each column in the index key + (indnkeyatts values), this contains the OID + of the operator class to use. See pg_opclass for details. @@ -3899,7 +3920,7 @@ SCRAM-SHA-256$<iteration count>:&l int2vector - This is an array of indnatts values that + This is an array of indnkeyatts values that store per-column flag bits. The meaning of the bits is defined by the index's access method. @@ -4088,9 +4109,7 @@ SCRAM-SHA-256$<iteration count>:&l The initial access privileges; see - and - - for details + for details @@ -4133,7 +4152,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4215,10 +4234,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -4340,7 +4356,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4355,10 +4371,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -4400,7 +4413,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4422,10 +4435,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -4475,7 +4485,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4580,7 +4590,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4737,7 +4747,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -4823,8 +4833,8 @@ SCRAM-SHA-256$<iteration count>:&l char - Partitioning strategy; l = list partitioned table, - r = range partitioned table + Partitioning strategy; h = hash partitioned table, + l = list partitioned table, r = range partitioned table @@ -5147,7 +5157,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -5205,11 +5215,11 @@ SCRAM-SHA-256$<iteration count>:&l - protransform + prosupport regproc pg_proc.oid - Calls to this function can be simplified by this other function - (see ) + Optional planner support function for this function + (see ) @@ -5432,10 +5442,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -5485,7 +5492,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -5690,6 +5697,13 @@ SCRAM-SHA-256$<iteration count>:&l see . + + Unlike most system catalogs, pg_replication_origin + is shared across all databases of a cluster: there is only one copy + of pg_replication_origin per cluster, not one per + database. + + <structname>pg_replication_origin</structname> Columns @@ -5754,7 +5768,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -6362,6 +6376,28 @@ SCRAM-SHA-256$<iteration count>:&l about those tables that are readable by the current user. + + pg_statistic should not be readable by the + public, since even statistical information about a table's contents + might be considered sensitive. (Example: minimum and maximum values + of a salary column might be quite interesting.) + pg_stats + is a publicly readable view on + pg_statistic that only exposes information + about those tables that are readable by the current user. + + + + Similarly, pg_statistic_ext_data should not be + readable by the public, since the contents might be considered sensitive. + (Example: most common combination of values in columns might be quite + interesting.) + pg_stats_ext + is a publicly readable view on pg_statistic_ext_data + (after joining with pg_statistic_ext) that only exposes + information about those tables and columns that are readable by the current user. + +
<structname>pg_statistic</structname> Columns @@ -6449,6 +6485,18 @@ SCRAM-SHA-256$<iteration count>:&l + + stacollN + oid + pg_collation.oid + + The collation used to derive the statistics stored in the + Nth slot. For example, a + histogram slot for a collatable column would show the collation that + defines the sort order of the data. Zero for noncollatable data. + + + stanumbersN float4[] @@ -6488,7 +6536,7 @@ SCRAM-SHA-256$<iteration count>:&l The catalog pg_statistic_ext - holds extended planner statistics. + holds definitions of extended planner statistics. Each row in this catalog corresponds to a statistics object created with . @@ -6558,12 +6606,62 @@ SCRAM-SHA-256$<iteration count>:&l An array containing codes for the enabled statistic kinds; valid values are: d for n-distinct statistics, - f for functional dependency statistics + f for functional dependency statistics, and + m for most common values (MCV) list statistics + + +
+ + + The stxkind field is filled at creation of the + statistics object, indicating which statistic type(s) are desired. The + statistics (once computed by ANALYZE) are stored in + pg_statistic_ext_data + catalog. + + + + + <structname>pg_statistic_ext_data</structname> + + + pg_statistic_ext_data + + + + The catalog pg_statistic_ext_data + holds data for extended planner statistics defined in pg_statistic_ext. + Each row in this catalog corresponds to a statistics object + created with . + + + + <structname>pg_statistic_ext_data</structname> Columns + + + - stxndistinct + Name + Type + References + Description + + + + + + + stxoid + oid + pg_statistic_ext.oid + Extended statistic containing the definition for this data. + + + + stxdndistinct pg_ndistinct @@ -6572,7 +6670,7 @@ SCRAM-SHA-256$<iteration count>:&l - stxdependencies + stxddependencies pg_dependencies @@ -6581,16 +6679,20 @@ SCRAM-SHA-256$<iteration count>:&l + + stxdmcv + pg_mcv_list + + + MCV (most-common values) list statistics, serialized as + pg_mcv_list type. + + +
- - The stxkind field is filled at creation of the - statistics object, indicating which statistic type(s) are desired. - The fields after it are initially NULL and are filled only when the - corresponding statistic has been computed by ANALYZE. -
@@ -6608,7 +6710,7 @@ SCRAM-SHA-256$<iteration count>:&l Unlike most system catalogs, pg_subscription is - shared across all databases of a cluster: There is only one copy + shared across all databases of a cluster: there is only one copy of pg_subscription per cluster, not one per database. @@ -6636,7 +6738,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier
@@ -6817,7 +6919,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -6839,10 +6941,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -6960,7 +7059,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7169,7 +7268,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7315,7 +7414,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7398,7 +7497,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7495,7 +7594,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7569,7 +7668,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -7912,10 +8011,10 @@ SCRAM-SHA-256$<iteration count>:&l typcollation specifies the collation of the type. If the type does not support collations, this will - be zero. A base type that supports collations will have - DEFAULT_COLLATION_OID here. A domain over a - collatable type can have some other collation OID, if one was - specified for the domain. + be zero. A base type that supports collations will have a nonzero + value here, typically DEFAULT_COLLATION_OID. + A domain over a collatable type can have a collation OID different + from its base type's, if one was specified for the domain. @@ -7952,10 +8051,7 @@ SCRAM-SHA-256$<iteration count>:&l aclitem[] - Access privileges; see - and - - for details + Access privileges; see for details @@ -8081,7 +8177,7 @@ SCRAM-SHA-256$<iteration count>:&l oid oid - Row identifier (hidden attribute; must be explicitly selected) + Row identifier @@ -8272,6 +8368,11 @@ SCRAM-SHA-256$<iteration count>:&l planner statistics + + pg_stats_ext + extended planner statistics + + pg_tables tables @@ -9859,7 +9960,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx The address (LSN) of oldest WAL which still might be required by the consumer of this slot and thus won't be - automatically removed during checkpoints. + automatically removed during checkpoints. NULL + if the LSN of this slot has never been reserved. @@ -9893,11 +9995,6 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx that blanks out the password field. - - This view explicitly exposes the OID column of the underlying table, - since that is needed to do joins to other catalogs. - - <structname>pg_roles</structname> Columns @@ -10640,7 +10737,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx valuntil - abstime + timestamptz Password expiry time (only used for password authentication) @@ -10850,6 +10947,171 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx + + <structname>pg_stats_ext</structname> + + + pg_stats_ext + + + + The view pg_stats_ext provides access to + the information stored in the pg_statistic_ext + and pg_statistic_ext_data + catalogs. This view allows access only to rows of + pg_statistic_ext and pg_statistic_ext_data + that correspond to tables the user has permission to read, and therefore + it is safe to allow public read access to this view. + + + + pg_stats_ext is also designed to present the + information in a more readable format than the underlying catalogs + — at the cost that its schema must be extended whenever new types + of extended statistics are added to pg_statistic_ext. + + +
+ <structname>pg_stats_ext</structname> Columns + + + + + Name + Type + References + Description + + + + + schemaname + name + pg_namespace.nspname + Name of schema containing table + + + + tablename + name + pg_class.relname + Name of table + + + + statistics_schemaname + name + pg_namespace.nspname + Name of schema containing extended statistic + + + + statistics_name + name + pg_statistic_ext.stxname + Name of extended statistics + + + + statistics_owner + oid + pg_authid.oid + Owner of the extended statistics + + + + attnames + name[] + pg_attribute.attname + Names of the columns the extended statistics is defined on + + + + kinds + text[] + + Types of extended statistics enabled for this record + + + + n_distinct + pg_ndistinct + + N-distinct counts for combinations of column values. If greater + than zero, the estimated number of distinct values in the combination. + If less than zero, the negative of the number of distinct values divided + by the number of rows. + (The negated form is used when ANALYZE believes that + the number of distinct values is likely to increase as the table grows; + the positive form is used when the column seems to have a fixed number + of possible values.) For example, -1 indicates a unique combination of + columns in which the number of distinct combinations is the same as the + number of rows. + + + + + dependencies + pg_dependencies + + Functional dependency statistics + + + + most_common_vals + anyarray + + + A list of the most common combinations of values in the columns. + (Null if no combinations seem to be more common than any others.) + + + + + most_common_val_nulls + anyarray + + + A list of NULL flags for the most common combinations of values. + (Null when most_common_vals is.) + + + + + most_common_freqs + real[] + + + A list of the frequencies of the most common combinations, + i.e., number of occurrences of each divided by total number of rows. + (Null when most_common_vals is.) + + + + + most_common_base_freqs + real[] + + + A list of the base frequencies of the most common combinations, + i.e., product of per-value frequencies. + (Null when most_common_vals is.) + + + + +
+ + + The maximum number of entries in the array fields can be controlled on a + column-by-column basis using the ALTER TABLE SET STATISTICS + command, or globally by setting the + run-time parameter. + + + + <structname>pg_tables</structname> @@ -11119,7 +11381,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx valuntil - abstime + timestamptz Password expiry time (only used for password authentication) diff --git a/doc/src/sgml/charset.sgml b/doc/src/sgml/charset.sgml index dc3fd34a624..b672da47d0a 100644 --- a/doc/src/sgml/charset.sgml +++ b/doc/src/sgml/charset.sgml @@ -580,7 +580,7 @@ SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR"; - libc collations + libc Collations For example, the operating system might @@ -637,7 +637,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; - ICU collations + ICU Collations With ICU, it is not sensible to enumerate all possible locale names. ICU @@ -713,7 +713,7 @@ SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1; - libc collations + libc Collations New libc collations can be created like this: @@ -737,7 +737,7 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); - ICU collations + ICU Collations ICU allows collations to be customized beyond the basic language+country @@ -847,11 +847,13 @@ CREATE COLLATION german (provider = libc, locale = 'de_DE'); Note that while this system allows creating collations that ignore - case or ignore accents or similar (using - the ks key), PostgreSQL does not at the moment allow - such collations to act in a truly case- or accent-insensitive manner. Any - strings that compare equal according to the collation but are not - byte-wise equal will be sorted according to their byte values. + case or ignore accents or similar (using the + ks key), in order for such collations to act in a + truly case- or accent-insensitive manner, they also need to be declared as not + deterministic in CREATE COLLATION; + see . + Otherwise, any strings that compare equal according to the collation but + are not byte-wise equal will be sorted according to their byte values. @@ -883,6 +885,55 @@ CREATE COLLATION french FROM "fr-x-icu"; + + + Nondeterministic Collations + + + A collation is either deterministic or + nondeterministic. A deterministic collation uses + deterministic comparisons, which means that it considers strings to be + equal only if they consist of the same byte sequence. Nondeterministic + comparison may determine strings to be equal even if they consist of + different bytes. Typical situations include case-insensitive comparison, + accent-insensitive comparison, as well as comparison of strings in + different Unicode normal forms. It is up to the collation provider to + actually implement such insensitive comparisons; the deterministic flag + only determines whether ties are to be broken using bytewise comparison. + See also Unicode Technical + Standard 10 for more information on the terminology. + + + + To create a nondeterministic collation, specify the property + deterministic = false to CREATE + COLLATION, for example: + +CREATE COLLATION ndcoll (provider = icu, locale = 'und', deterministic = false); + + This example would use the standard Unicode collation in a + nondeterministic way. In particular, this would allow strings in + different normal forms to be compared correctly. More interesting + examples make use of the ICU customization facilities explained above. + For example: + +CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false); +CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-true', deterministic = false); + + + + + All standard and predefined collations are deterministic, all + user-defined collations are deterministic by default. While + nondeterministic collations give a more correct behavior, + especially when considering the full power of Unicode and its many + special cases, they also have some drawbacks. Foremost, their use leads + to a performance penalty. Also, certain operations are not possible with + nondeterministic collations, such as pattern matching operations. + Therefore, they should be used only in cases where they are specifically + wanted. + + @@ -1483,6 +1534,13 @@ $ psql -l UTF8 + + EUC_JIS_2004 + EUC_JIS_2004, + SHIFT_JIS_2004, + UTF8 + + EUC_KR EUC_KR, @@ -1538,8 +1596,7 @@ $ psql -l JOHAB - JOHAB, - UTF8 + not supported as a server encoding @@ -1645,6 +1702,11 @@ $ psql -l not supported as a server encoding + + SHIFT_JIS_2004 + not supported as a server encoding + + SQL_ASCII any (no conversion will be performed) @@ -1834,7 +1896,11 @@ RESET client_encoding; If the client character set is defined as SQL_ASCII, encoding conversion is disabled, regardless of the server's character - set. Just as for the server, use of SQL_ASCII is unwise + set. (However, if the server's character set is + not SQL_ASCII, the server will still check that + incoming data is valid for that encoding; so the net effect is as + though the client character set were the same as the server's.) + Just as for the server, use of SQL_ASCII is unwise unless you are working with all-ASCII data. diff --git a/doc/src/sgml/citext.sgml b/doc/src/sgml/citext.sgml index b1fe7101b20..85aa339d8ba 100644 --- a/doc/src/sgml/citext.sgml +++ b/doc/src/sgml/citext.sgml @@ -14,6 +14,16 @@ exactly like text. + + + Consider using nondeterministic collations (see + ) instead of this module. They + can be used for case-insensitive comparisons, accent-insensitive + comparisons, and other combinations, and they handle more Unicode special + cases correctly. + + + Rationale @@ -246,6 +256,17 @@ SELECT * FROM users WHERE nick = 'Larry'; will be invoked instead. + + + + The approach of lower-casing strings for comparison does not handle some + Unicode special cases correctly, for example when one upper-case letter + has two lower-case letter equivalents. Unicode distinguishes between + case mapping and case + folding for this reason. Use nondeterministic collations + instead of citext to handle that correctly. + + diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml index 53832d08e29..9236fc014c4 100644 --- a/doc/src/sgml/client-auth.sgml +++ b/doc/src/sgml/client-auth.sgml @@ -108,6 +108,8 @@ hostnossl database user host database user IP-address IP-mask auth-method auth-options hostssl database user IP-address IP-mask auth-method auth-options hostnossl database user IP-address IP-mask auth-method auth-options +hostgssenc database user IP-address IP-mask auth-method auth-options +hostnogssenc database user IP-address IP-mask auth-method auth-options The meaning of the fields is as follows: @@ -128,9 +130,10 @@ hostnossl database user This record matches connection attempts made using TCP/IP. - host records match either + host records match SSL or non-SSL connection - attempts. + attempts as well as GSSAPI encrypted or + non-GSSAPI encrypted connection attempts. @@ -176,6 +179,43 @@ hostnossl database user + + hostgssenc + + + This record matches connection attempts made using TCP/IP, + but only when the connection is made with GSSAPI + encryption. + + + + To make use of this option the server must be built with + GSSAPI support. Otherwise, + the hostgssenc record is ignored except for logging + a warning that it cannot match any connections. + + + + Note that the only supported + authentication methods for use + with GSSAPI encryption + are gss, reject, + and trust. + + + + + + hostnogssenc + + + This record type has the opposite behavior of hostgssenc; + it only matches connection attempts made over + TCP/IP that do not use GSSAPI encryption. + + + + database @@ -451,7 +491,8 @@ hostnossl database user Use GSSAPI to authenticate the user. This is only available for TCP/IP connections. See for details. + linkend="gssapi-auth"/> for details. It can be used in conjunction + with GSSAPI encryption. @@ -563,10 +604,17 @@ hostnossl database user In addition to the method-specific options listed below, there is one method-independent authentication option clientcert, which - can be specified in any hostssl record. When set - to 1, this option requires the client to present a valid - (trusted) SSL certificate, in addition to the other requirements of the - authentication method. + can be specified in any hostssl record. + This option can be set to verify-ca or + verify-full. Both options require the client + to present a valid (trusted) SSL certificate, while + verify-full additionally enforces that the + cn (Common Name) in the certificate matches + the username or an applicable mapping. + This behavior is similar to the cert authentication + method (see ) but enables pairing + the verification of client certificates with any authentication + method that supports hostssl entries. @@ -603,8 +651,9 @@ hostnossl database user SIGHUPSIGHUP signal. If you edit the file on an active system, you will need to signal the postmaster - (using pg_ctl reload or kill -HUP) to make it - re-read the file. + (using pg_ctl reload, calling the SQL function + pg_reload_conf(), or using kill + -HUP) to make it re-read the file. @@ -624,7 +673,7 @@ hostnossl database user non-null error fields indicate problems in the corresponding lines of the file. - + To connect to a particular database, a user must not only pass the @@ -696,15 +745,18 @@ host postgres all 192.168.12.10/32 scram-sha-256 host all mike .example.com md5 host all all .example.com scram-sha-256 -# In the absence of preceding "host" lines, these two lines will +# In the absence of preceding "host" lines, these three lines will # reject all connections from 192.168.54.1 (since that entry will be -# matched first), but allow GSSAPI connections from anywhere else -# on the Internet. The zero mask causes no bits of the host IP -# address to be considered, so it matches any host. +# matched first), but allow GSSAPI-encrypted connections from anywhere else +# on the Internet. The zero mask causes no bits of the host IP address to +# be considered, so it matches any host. Unencrypted GSSAPI connections +# (which "fall through" to the third line since "hostgssenc" only matches +# encrypted GSSAPI connections) are allowed, but only from 192.168.12.10. # # TYPE DATABASE USER ADDRESS METHOD host all all 192.168.54.1/32 reject -host all all 0.0.0.0/0 gss +hostgssenc all all 0.0.0.0/0 gss +host all all 192.168.12.10/32 gss # Allow users from 192.168.x.x hosts to connect to any database, if # they pass the ident check. If, for example, ident says the user is @@ -821,8 +873,9 @@ mymap /^(.*)@otherdomain\.com$ guest SIGHUPSIGHUP signal. If you edit the file on an active system, you will need to signal the postmaster - (using pg_ctl reload or kill -HUP) to make it - re-read the file. + (using pg_ctl reload, calling the SQL function + pg_reload_conf(), or using kill + -HUP) to make it re-read the file. @@ -859,10 +912,11 @@ omicron bryanh guest1 Authentication Methods - The following subsections describe the authentication methods in more detail. + The following sections describe the authentication methods in more detail. + - + Trust Authentication @@ -908,9 +962,9 @@ omicron bryanh guest1 for any TCP/IP connections other than those from localhost (127.0.0.1). - + - + Password Authentication @@ -1038,9 +1092,9 @@ omicron bryanh guest1 and change the authentication method specifications in pg_hba.conf to scram-sha-256. - + - + GSSAPI Authentication @@ -1050,13 +1104,16 @@ omicron bryanh guest1 GSSAPI is an industry-standard protocol for secure authentication defined in RFC 2743. - PostgreSQL supports - GSSAPI with Kerberos - authentication according to RFC 1964. GSSAPI - provides automatic authentication (single sign-on) for systems - that support it. The authentication itself is secure, but the - data sent over the database connection will be sent unencrypted unless - SSL is used. + + PostgreSQL + supports GSSAPI for use as either an encrypted, + authenticated layer, or for authentication only. + GSSAPI provides automatic authentication + (single sign-on) for systems that support it. The authentication itself is + secure. If GSSAPI encryption + (see hostgssenc) or SSL encryption are + used, the data sent along the database connection will be encrypted; + otherwise, it will not. @@ -1192,9 +1249,9 @@ omicron bryanh guest1 - + - + SSPI Authentication @@ -1310,9 +1367,9 @@ omicron bryanh guest1 - + - + Ident Authentication @@ -1391,9 +1448,9 @@ omicron bryanh guest1 since PostgreSQL does not have any way to decrypt the returned string to determine the actual user name. - + - + Peer Authentication @@ -1432,9 +1489,9 @@ omicron bryanh guest1 and Solaris. - + - + LDAP Authentication @@ -1647,7 +1704,8 @@ ldap[s]://host[:port]/ - LDAP URLs are currently only supported with OpenLDAP, not on Windows. + LDAP URLs are currently only supported with + OpenLDAP, not on Windows. @@ -1670,6 +1728,15 @@ ldap[s]://host[:port]/ldapsearchattribute=uid. + + If PostgreSQL was compiled with + OpenLDAP as the LDAP client library, the + ldapserver setting may be omitted. In that case, a + list of host names and ports is looked up via RFC 2782 DNS SRV records. + The name _ldap._tcp.DOMAIN is looked up, where + DOMAIN is extracted from ldapbasedn. + + Here is an example for a simple-bind LDAP configuration: @@ -1715,6 +1782,15 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse + + Here is an example for a search+bind configuration that uses DNS SRV + discovery to find the host name(s) and port(s) for the LDAP service for the + domain name example.net: + +host ... ldap ldapbasedn="dc=example,dc=net" + + + Since LDAP often uses commas and spaces to separate the different @@ -1723,9 +1799,9 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse - + - + RADIUS Authentication @@ -1824,9 +1900,9 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse - + - + Certificate Authentication @@ -1864,15 +1940,15 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse In a pg_hba.conf record specifying certificate authentication, the authentication option clientcert is - assumed to be 1, and it cannot be turned off since a client - certificate is necessary for this method. What the cert - method adds to the basic clientcert certificate validity test - is a check that the cn attribute matches the database - user name. + assumed to be verify-ca or verify-full, + and it cannot be turned off since a client certificate is necessary for this + method. What the cert method adds to the basic + clientcert certificate validity test is a check that the + cn attribute matches the database user name. - + - + PAM Authentication @@ -1888,7 +1964,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse connected remote host name or IP address. Therefore the user must already exist in the database before PAM can be used for authentication. For more information about PAM, please read the - + Linux-PAM Page. @@ -1928,9 +2004,9 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse LDAP or other authentication methods. - + - + BSD Authentication @@ -1963,8 +2039,7 @@ host ... ldap ldapserver=ldap.example.net ldapbasedn="dc=example, dc=net" ldapse exists by default on OpenBSD systems.
- - + Authentication Problems diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 5d5f2d23c4f..619ac8c50c8 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -51,14 +51,21 @@ In general, enclose the value in single quotes, doubling any single quotes within the value. Quotes can usually be omitted if the value is a simple number or identifier, however. + (Values that match a SQL keyword require quoting in some contexts.) Numeric (integer and floating point): - A decimal point is permitted only for floating-point parameters. - Do not use thousands separators. Quotes are not required. + Numeric parameters can be specified in the customary integer and + floating-point formats; fractional values are rounded to the nearest + integer if the parameter is of integer type. Integer parameters + additionally accept hexadecimal input (beginning + with 0x) and octal input (beginning + with 0), but these formats cannot have a fraction. + Do not use thousands separators. + Quotes are not required, except for hexadecimal input. @@ -66,7 +73,7 @@ Numeric with Unit: Some numeric parameters have an implicit unit, because they describe - quantities of memory or time. The unit might be kilobytes, blocks + quantities of memory or time. The unit might be bytes, kilobytes, blocks (typically eight kilobytes), milliseconds, seconds, or minutes. An unadorned numeric value for one of these settings will use the setting's default unit, which can be learned from @@ -81,7 +88,8 @@ - Valid memory units are kB (kilobytes), + Valid memory units are B (bytes), + kB (kilobytes), MB (megabytes), GB (gigabytes), and TB (terabytes). The multiplier for memory units is 1024, not 1000. @@ -90,12 +98,21 @@ - Valid time units are ms (milliseconds), + Valid time units are + us (microseconds), + ms (milliseconds), s (seconds), min (minutes), h (hours), and d (days). + + If a fractional value is specified with a unit, it will be rounded + to a multiple of the next smaller unit if there is one. + For example, 30.1 GB will be converted + to 30822 MB not 32319628902 B. + If the parameter is of integer type, a final rounding to integer + occurs after any units conversion. @@ -136,6 +153,8 @@ shared_buffers = 128MB identifiers or numbers must be single-quoted. To embed a single quote in a parameter value, write either two quotes (preferred) or backslash-quote. + If the file contains multiple entries for the same parameter, + all but the last one are ignored. @@ -168,18 +187,29 @@ shared_buffers = 128MB In addition to postgresql.conf, a PostgreSQL data directory contains a file postgresql.auto.confpostgresql.auto.conf, - which has the same format as postgresql.conf but should - never be edited manually. This file holds settings provided through - the command. This file is automatically - read whenever postgresql.conf is, and its settings take - effect in the same way. Settings in postgresql.auto.conf - override those in postgresql.conf. + which has the same format as postgresql.conf but + is intended to be edited automatically, not manually. This file holds + settings provided through the command. + This file is read whenever postgresql.conf is, + and its settings take effect in the same way. Settings + in postgresql.auto.conf override those + in postgresql.conf. + + + + External tools may also + modify postgresql.auto.conf. It is not + recommended to do this while the server is running, since a + concurrent ALTER SYSTEM command could overwrite + such changes. Such tools might simply append new settings to the end, + or they might choose to remove duplicate settings and/or comments + (as ALTER SYSTEM will). The system view pg_file_settings - can be helpful for pre-testing changes to the configuration file, or for + can be helpful for pre-testing changes to the configuration files, or for diagnosing problems if a SIGHUP signal did not have the desired effects. @@ -696,8 +726,7 @@ include_dir 'conf.d' The default value is three connections. The value must be less - than max_connections minus - . + than max_connections. This parameter can only be set at server start. @@ -923,6 +952,31 @@ include_dir 'conf.d' + + tcp_user_timeout (integer) + + tcp_user_timeout configuration parameter + + + + + Specifies the number of milliseconds that transmitted data may + remain unacknowledged before a connection is forcibly closed. + A value of 0 uses the system default. + This parameter is supported only on systems that support + TCP_USER_TIMEOUT; on other systems, it must be zero. + In sessions connected via a Unix-domain socket, this parameter is + ignored and always reads as zero. + + + + This parameter is not supported on Windows and on Linux version + 2.6.36 or older. + + + + + @@ -1248,7 +1302,7 @@ include_dir 'conf.d' than the client's. This parameter can only be set in the postgresql.conf file or on the server command line. - The default is true. + The default is on. @@ -1290,6 +1344,50 @@ include_dir 'conf.d' + + ssl_min_protocol_version (enum) + + ssl_min_protocol_version configuration parameter + + + + + Sets the minimum SSL/TLS protocol version to use. Valid values are + currently: TLSv1, TLSv1.1, + TLSv1.2, TLSv1.3. Older + versions of the OpenSSL library do not + support all values; an error will be raised if an unsupported setting + is chosen. Protocol versions before TLS 1.0, namely SSL version 2 and + 3, are always disabled. + + + + The default is TLSv1, mainly to support older + versions of the OpenSSL library. You might + want to set this to a higher value if all software components can + support the newer protocol versions. + + + + + + ssl_max_protocol_version (enum) + + ssl_max_protocol_version configuration parameter + + + + + Sets the maximum SSL/TLS protocol version to use. Valid values are as + for , with addition of + an empty string, which allows any protocol version. The default is to + allow any version. Setting the maximum protocol version is mainly + useful for testing or if some component has issues working with a + newer protocol. + + + + ssl_dh_params_file (string) @@ -1359,12 +1457,12 @@ include_dir 'conf.d' This parameter determines whether the passphrase command set by ssl_passphrase_command will also be called during a configuration reload if a key file needs a passphrase. If this - parameter is false (the default), then + parameter is off (the default), then ssl_passphrase_command will be ignored during a reload and the SSL configuration will not be reloaded if a passphrase is needed. That setting is appropriate for a command that requires a TTY for prompting, which might not be available when the server is - running. Setting this parameter to true might be appropriate if the + running. Setting this parameter to on might be appropriate if the passphrase is obtained from a file, for example. @@ -1630,12 +1728,11 @@ include_dir 'conf.d' enforced by the kernel (as set by ulimit -s or local equivalent), less a safety margin of a megabyte or so. The safety margin is needed because the stack depth is not checked in every - routine in the server, but only in key potentially-recursive routines - such as expression evaluation. The default setting is two - megabytes (2MB), which is conservatively small and - unlikely to risk crashes. However, it might be too small to allow - execution of complex functions. Only superusers can change this - setting. + routine in the server, but only in key potentially-recursive routines. + The default setting is two megabytes (2MB), which + is conservatively small and unlikely to risk crashes. However, + it might be too small to allow execution of complex functions. + Only superusers can change this setting. @@ -1650,6 +1747,31 @@ include_dir 'conf.d' + + shared_memory_type (enum) + + shared_memory_type configuration parameter + + + + + Specifies the shared memory implementation that the server + should use for the main shared memory region that holds + PostgreSQL's shared buffers and other + shared data. Possible values are mmap (for + anonymous shared memory allocated using mmap), + sysv (for System V shared memory allocated via + shmget) and windows (for Windows + shared memory). Not all values are supported on all platforms; the + first supported option is the default for that platform. The use of + the sysv option, which is not the default on any + platform, is generally discouraged because it typically requires + non-default kernel settings to allow for large allocations (see ). + + + + dynamic_shared_memory_type (enum) @@ -1662,9 +1784,9 @@ include_dir 'conf.d' should use. Possible values are posix (for POSIX shared memory allocated using shm_open), sysv (for System V shared memory allocated via shmget), - windows (for Windows shared memory), mmap - (to simulate shared memory using memory-mapped files stored in the - data directory), and none (to disable this feature). + windows (for Windows shared memory), + and mmap (to simulate shared memory using + memory-mapped files stored in the data directory). Not all values are supported on all platforms; the first supported option is the default for that platform. The use of the mmap option, which is not the default on any platform, @@ -1777,7 +1899,7 @@ include_dir 'conf.d' - vacuum_cost_delay (integer) + vacuum_cost_delay (floating point) vacuum_cost_delay configuration parameter @@ -1788,18 +1910,19 @@ include_dir 'conf.d' when the cost limit has been exceeded. The default value is zero, which disables the cost-based vacuum delay feature. Positive values enable cost-based vacuuming. - Note that on many systems, the effective resolution - of sleep delays is 10 milliseconds; setting - vacuum_cost_delay to a value that is - not a multiple of 10 might have the same results as setting it - to the next higher multiple of 10. When using cost-based vacuuming, appropriate values for vacuum_cost_delay are usually quite small, perhaps - 10 or 20 milliseconds. Adjusting vacuum's resource consumption - is best done by changing the other vacuum cost parameters. + less than 1 millisecond. While vacuum_cost_delay + can be set to fractional-millisecond values, such delays may not be + measured accurately on older platforms. On such platforms, + increasing VACUUM's throttled resource consumption + above what you get at 1ms will require changing the other vacuum cost + parameters. You should, nonetheless, + keep vacuum_cost_delay as small as your platform + will consistently measure; large delays are not helpful. @@ -1882,31 +2005,6 @@ include_dir 'conf.d' - - Index Vacuum - - - vacuum_cleanup_index_scale_factor (floating point) - - vacuum_cleanup_index_scale_factor configuration parameter - - - - - When no tuples were deleted from the heap, B-tree indexes might still - be scanned during VACUUM cleanup stage by two - reasons. The first reason is that B-tree index contains deleted pages - which can be recycled during cleanup. The second reason is that B-tree - index statistics is stalled. The criterion of stalled index statistics - is number of inserted tuples since previous statistics collection - is greater than vacuum_cleanup_index_scale_factor - fraction of total number of heap tuples. - - - - - - Background Writer @@ -2173,7 +2271,7 @@ include_dir 'conf.d' pool of processes established by , limited by . Note that the requested - number of workers may not actually be available at runtime. + number of workers may not actually be available at run time. If this occurs, the utility operation will run with fewer workers than expected. The default value is 2. Setting this value to 0 disables the use of parallel workers by utility @@ -3024,6 +3122,394 @@ include_dir 'conf.d' + + + Archive Recovery + + + configuration + of recovery + of a standby server + + + + This section describes the settings that apply only for the duration of + the recovery. They must be reset for any subsequent recovery you wish to + perform. + + + + Recovery covers using the server as a standby or for + executing a targeted recovery. Typically, standby mode would be used to + provide high availability and/or read scalability, whereas a targeted + recovery is used to recover from data loss. + + + + To start the server in standby mode, create a file called + standby.signalstandby.signal + in the data directory. The server will enter recovery and will not stop + recovery when the end of archived WAL is reached, but will keep trying to + continue recovery by connecting to the sending server as specified by the + primary_conninfo setting and/or by fetching new WAL + segments using restore_command. For this mode, the + parameters from this section and are of interest. + Parameters from will + also be applied but are typically not useful in this mode. + + + + To start the server in targeted recovery mode, create a file called + recovery.signalrecovery.signal + in the data directory. If both standby.signal and + recovery.signal files are created, standby mode + takes precedence. Targeted recovery mode ends when the archived WAL is + fully replayed, or when recovery_target is reached. + In this mode, the parameters from both this section and will be used. Parameters + from will not be + used. + + + + + restore_command (string) + + restore_command configuration parameter + + + + + The local shell command to execute to retrieve an archived segment of + the WAL file series. This parameter is required for archive recovery, + but optional for streaming replication. + Any %f in the string is + replaced by the name of the file to retrieve from the archive, + and any %p is replaced by the copy destination path name + on the server. + (The path name is relative to the current working directory, + i.e., the cluster's data directory.) + Any %r is replaced by the name of the file containing the + last valid restart point. That is the earliest file that must be kept + to allow a restore to be restartable, so this information can be used + to truncate the archive to just the minimum required to support + restarting from the current restore. %r is typically only + used by warm-standby configurations + (see ). + Write %% to embed an actual % character. + + + + It is important for the command to return a zero exit status + only if it succeeds. The command will be asked for file + names that are not present in the archive; it must return nonzero + when so asked. Examples: + +restore_command = 'cp /mnt/server/archivedir/%f "%p"' +restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows + + An exception is that if the command was terminated by a signal (other + than SIGTERM, which is used as part of a + database server shutdown) or an error by the shell (such as command + not found), then recovery will abort and the server will not start up. + + + + This parameter can only be set at server start. + + + + + + archive_cleanup_command (string) + + archive_cleanup_command configuration parameter + + + + + This optional parameter specifies a shell command that will be executed + at every restartpoint. The purpose of + archive_cleanup_command is to provide a mechanism for + cleaning up old archived WAL files that are no longer needed by the + standby server. + Any %r is replaced by the name of the file containing the + last valid restart point. + That is the earliest file that must be kept to allow a + restore to be restartable, and so all files earlier than %r + may be safely removed. + This information can be used to truncate the archive to just the + minimum required to support restart from the current restore. + The module + is often used in archive_cleanup_command for + single-standby configurations, for example: +archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' + Note however that if multiple standby servers are restoring from the + same archive directory, you will need to ensure that you do not delete + WAL files until they are no longer needed by any of the servers. + archive_cleanup_command would typically be used in a + warm-standby configuration (see ). + Write %% to embed an actual % character in the + command. + + + If the command returns a nonzero exit status then a warning log + message will be written. An exception is that if the command was + terminated by a signal or an error by the shell (such as command not + found), a fatal error will be raised. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + recovery_end_command (string) + + recovery_end_command configuration parameter + + + + + This parameter specifies a shell command that will be executed once only + at the end of recovery. This parameter is optional. The purpose of the + recovery_end_command is to provide a mechanism for cleanup + following replication or recovery. + Any %r is replaced by the name of the file containing the + last valid restart point, like in . + + + If the command returns a nonzero exit status then a warning log + message will be written and the database will proceed to start up + anyway. An exception is that if the command was terminated by a + signal or an error by the shell (such as command not found), the + database will not proceed with startup. + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + + + + + + + + Recovery Target + + + By default, recovery will recover to the end of the WAL log. The + following parameters can be used to specify an earlier stopping point. + At most one of recovery_target, + recovery_target_lsn, recovery_target_name, + recovery_target_time, or recovery_target_xid + can be used; if more than one of these is specified in the configuration + file, an error will be raised. + These parameters can only be set at server start. + + + + + recovery_target = 'immediate' + + recovery_target configuration parameter + + + + + This parameter specifies that recovery should end as soon as a + consistent state is reached, i.e. as early as possible. When restoring + from an online backup, this means the point where taking the backup + ended. + + + Technically, this is a string parameter, but 'immediate' + is currently the only allowed value. + + + + + + recovery_target_name (string) + + recovery_target_name configuration parameter + + + + + This parameter specifies the named restore point (created with + pg_create_restore_point()) to which recovery will proceed. + + + + + + recovery_target_time (timestamp) + + recovery_target_time configuration parameter + + + + + This parameter specifies the time stamp up to which recovery + will proceed. + The precise stopping point is also influenced by + . + + + + + + recovery_target_xid (string) + + recovery_target_xid configuration parameter + + + + + This parameter specifies the transaction ID up to which recovery + will proceed. Keep in mind + that while transaction IDs are assigned sequentially at transaction + start, transactions can complete in a different numeric order. + The transactions that will be recovered are those that committed + before (and optionally including) the specified one. + The precise stopping point is also influenced by + . + + + + + + recovery_target_lsn (pg_lsn) + + recovery_target_lsn configuration parameter + + + + + This parameter specifies the LSN of the write-ahead log location up + to which recovery will proceed. The precise stopping point is also + influenced by . This + parameter is parsed using the system data type + pg_lsn. + + + + + + + The following options further specify the recovery target, and affect + what happens when the target is reached: + + + + + recovery_target_inclusive (boolean) + + recovery_target_inclusive configuration parameter + + + + + Specifies whether to stop just after the specified recovery target + (on), or just before the recovery target + (off). + Applies when , + , or + is specified. + This setting controls whether transactions + having exactly the target WAL location (LSN), commit time, or transaction ID, respectively, will + be included in the recovery. Default is on. + + + + + + recovery_target_timeline (string) + + recovery_target_timeline configuration parameter + + + + + Specifies recovering into a particular timeline. The value can be a + numeric timeline ID or a special value. The value + current recovers along the same timeline that was + current when the base backup was taken. The + value latest recovers + to the latest timeline found in the archive, which is useful in + a standby server. latest is the default. + + + + You usually only need to set this parameter + in complex re-recovery situations, where you need to return to + a state that itself was reached after a point-in-time recovery. + See for discussion. + + + + + + recovery_target_action (enum) + + recovery_target_action configuration parameter + + + + + Specifies what action the server should take once the recovery target is + reached. The default is pause, which means recovery will + be paused. promote means the recovery process will finish + and the server will start to accept connections. + Finally shutdown will stop the server after reaching the + recovery target. + + + The intended use of the pause setting is to allow queries + to be executed against the database to check if this recovery target + is the most desirable point for recovery. + The paused state can be resumed by + using pg_wal_replay_resume() (see + ), which then + causes recovery to end. If this recovery target is not the + desired stopping point, then shut down the server, change the + recovery target settings to a later target and restart to + continue recovery. + + + The shutdown setting is useful to have the instance ready + at the exact replay point desired. The instance will still be able to + replay more WAL records (and in fact will have to replay WAL records + since the last checkpoint next time it is started). + + + Note that because recovery.signal will not be + removed when recovery_target_action is set to shutdown, + any subsequent start will end with immediate shutdown unless the + configuration is changed or the recovery.signal + file is removed manually. + + + This setting has no effect if no recovery target is set. + If is not enabled, a setting of + pause will act the same as shutdown. + + + + + + + @@ -3033,17 +3519,17 @@ include_dir 'conf.d' These settings control the behavior of the built-in streaming replication feature (see ). Servers will be either a - Master or a Standby server. Masters can send data, while Standby(s) + master or a standby server. Masters can send data, while standbys are always receivers of replicated data. When cascading replication - (see ) is used, Standby server(s) + (see ) is used, standby servers can also be senders, as well as receivers. - Parameters are mainly for Sending and Standby servers, though some - parameters have meaning only on the Master server. Settings may vary + Parameters are mainly for sending and standby servers, though some + parameters have meaning only on the master server. Settings may vary across the cluster without problems if that is required. - Sending Server(s) + Sending Servers These parameters can be set on any server that is @@ -3063,24 +3549,25 @@ include_dir 'conf.d' - Specifies the maximum number of concurrent connections from - standby servers or streaming base backup clients (i.e., the - maximum number of simultaneously running WAL sender - processes). The default is 10. The value 0 means replication is - disabled. WAL sender processes count towards the total number - of connections, so this parameter's value must be less than - minus - . - Abrupt streaming client disconnection might leave an orphaned - connection slot behind until - a timeout is reached, so this parameter should be set slightly - higher than the maximum number of expected clients so disconnected - clients can immediately reconnect. This parameter can only - be set at server start. - Also, wal_level must be set to + Specifies the maximum number of concurrent connections from standby + servers or streaming base backup clients (i.e., the maximum number of + simultaneously running WAL sender processes). The default is + 10. The value 0 means + replication is disabled. Abrupt streaming client disconnection might + leave an orphaned connection slot behind until a timeout is reached, + so this parameter should be set slightly higher than the maximum + number of expected clients so disconnected clients can immediately + reconnect. This parameter can only be set at server start. Also, + wal_level must be set to replica or higher to allow connections from standby servers. + + + When running a standby server, you must set this parameter to the + same or higher value than on the master server. Otherwise, queries + will not be allowed in the standby server. + @@ -3141,6 +3628,41 @@ include_dir 'conf.d' + + wal_init_zero (boolean) + + wal_init_zero configuration parameter + + + + + If set to on (the default), this option causes new + WAL files to be filled with zeroes. On some file systems, this ensures + that space is allocated before we need to write WAL records. However, + Copy-On-Write (COW) file systems may not benefit + from this technique, so the option is given to skip the unnecessary + work. If set to off, only the final byte is written + when the file is created so that it has the expected size. + + + + + + wal_recycle (boolean) + + wal_recycle configuration parameter + + + + + If set to on (the default), this option causes WAL + files to be recycled by renaming them, avoiding the need to create new + ones. On COW file systems, it may be faster to create new ones, so the + option is given to disable this behavior. + + + + wal_sender_timeout (integer) @@ -3152,10 +3674,14 @@ include_dir 'conf.d' Terminate replication connections that are inactive longer than the specified number of milliseconds. This is useful for the sending server to detect a standby crash or network outage. - A value of zero disables the timeout mechanism. This parameter - can only be set in - the postgresql.conf file or on the server command line. - The default value is 60 seconds. + A value of zero disables the timeout mechanism. The default value + is 60 seconds. With a cluster distributed across multiple geographic + locations, using different values per location brings more flexibility + in the cluster management. A smaller value is useful for faster + failure detection with a standby having a low-latency network + connection, and a larger value helps in judging better the health + of a standby if located on a remote location, with a high-latency + network connection. @@ -3212,9 +3738,9 @@ include_dir 'conf.d' The synchronous standbys will be those whose names appear in this list, and that are both currently connected and streaming data in real-time - (as shown by a state of streaming in the - - pg_stat_replication view). + (as shown by a state of streaming in the pg_stat_replication + view). Specifying more than one synchronous standby can allow for very high availability and protection against data loss. @@ -3223,11 +3749,12 @@ include_dir 'conf.d' application_name setting of the standby, as set in the standby's connection information. In case of a physical replication standby, this should be set in the primary_conninfo - setting in recovery.conf; the default - is walreceiver. For logical replication, this can - be set in the connection information of the subscription, and it - defaults to the subscription name. For other replication stream - consumers, consult their documentation. + setting; the default is the setting of + if set, else walreceiver. + For logical replication, this can be set in the connection + information of the subscription, and it defaults to the + subscription name. For other replication stream consumers, + consult their documentation. This parameter specifies a list of standby servers using @@ -3370,6 +3897,80 @@ ANY num_sync ( + primary_conninfo (string) + + primary_conninfo configuration parameter + + + + + Specifies a connection string to be used for the standby server + to connect with a sending server. This string is in the format + described in . If any option is + unspecified in this string, then the corresponding environment + variable (see ) is checked. If the + environment variable is not set either, then + defaults are used. + + + The connection string should specify the host name (or address) + of the sending server, as well as the port number if it is not + the same as the standby server's default. + Also specify a user name corresponding to a suitably-privileged role + on the sending server (see + ). + A password needs to be provided too, if the sender demands password + authentication. It can be provided in the + primary_conninfo string, or in a separate + ~/.pgpass file on the standby server (use + replication as the database name). + Do not specify a database name in the + primary_conninfo string. + + + This parameter can only be set at server start. + This setting has no effect if the server is not in standby mode. + + + + + primary_slot_name (string) + + primary_slot_name configuration parameter + + + + + Optionally specifies an existing replication slot to be used when + connecting to the sending server via streaming replication to control + resource removal on the upstream node + (see ). + This parameter can only be set at server start. + This setting has no effect if primary_conninfo is not + set. + + + + + + promote_trigger_file (string) + + promote_trigger_file configuration parameter + + + + + Specifies a trigger file whose presence ends recovery in the + standby. Even if this value is not set, you can still promote + the standby using pg_ctl promote or calling + pg_promote. + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + hot_standby (boolean) @@ -3461,8 +4062,9 @@ ANY num_sync ( - pg_stat_replication view. The standby will report + pg_stat_replication + view. The standby will report the last write-ahead log location it has written, the last position it has flushed to disk, and the last position it has applied. This parameter's @@ -3562,6 +4164,68 @@ ANY num_sync ( + recovery_min_apply_delay (integer) + + recovery_min_apply_delay configuration parameter + + + + + By default, a standby server restores WAL records from the + sending server as soon as possible. It may be useful to have a time-delayed + copy of the data, offering opportunities to correct data loss errors. + This parameter allows you to delay recovery by a fixed period of time, + measured in milliseconds if no unit is specified. For example, if + you set this parameter to 5min, the standby will + replay each transaction commit only when the system time on the standby + is at least five minutes past the commit time reported by the master. + + + It is possible that the replication delay between servers exceeds the + value of this parameter, in which case no delay is added. + Note that the delay is calculated between the WAL time stamp as written + on master and the current time on the standby. Delays in transfer + because of network lag or cascading replication configurations + may reduce the actual wait time significantly. If the system + clocks on master and standby are not synchronized, this may lead to + recovery applying records earlier than expected; but that is not a + major issue because useful settings of this parameter are much larger + than typical time deviations between servers. + + + The delay occurs only on WAL records for transaction commits. + Other records are replayed as quickly as possible, which + is not a problem because MVCC visibility rules ensure their effects + are not visible until the corresponding commit record is applied. + + + The delay occurs once the database in recovery has reached a consistent + state, until the standby is promoted or triggered. After that the standby + will end recovery without further waiting. + + + This parameter is intended for use with streaming replication deployments; + however, if the parameter is specified it will be honored in all cases. + + hot_standby_feedback will be delayed by use of this feature + which could lead to bloat on the master; use both together with care. + + + + Synchronous replication is affected by this setting when synchronous_commit + is set to remote_apply; every COMMIT + will need to wait to be applied. + + + + + This parameter can only be set in the postgresql.conf + file or on the server command line. + + + + @@ -3826,6 +4490,24 @@ ANY num_sync ( + enable_partition_pruning (boolean) + + enable_partition_pruning configuration parameter + + + + + Enables or disables the query planner's ability to eliminate a + partitioned table's partitions from query plans. This also controls + the planner's ability to generate query plans which allow the query + executor to remove (ignore) partitions during query execution. The + default is on. + See for details. + + + + enable_partitionwise_join (boolean) @@ -4148,7 +4830,8 @@ ANY num_sync ( ( jit_above_cost (floating point) @@ -4170,48 +4852,49 @@ ANY num_sync ( ). Performing - JIT costs time but can accelerate query execution. - + Sets the query cost above which JIT compilation is activated, if + enabled (see ). + Performing JIT costs planning time but can + accelerate query execution. + Setting this to -1 disables JIT compilation. The default is 100000. - - jit_optimize_above_cost (floating point) + + jit_inline_above_cost (floating point) - jit_optimize_above_cost configuration parameter + jit_inline_above_cost configuration parameter - Sets the planner's cutoff above which JIT compiled programs (see ) are optimized. Optimization initially - takes time, but can improve execution speed. It is not meaningful to - set this to a lower value than . - + Sets the query cost above which JIT compilation attempts to inline + functions and operators. Inlining adds planning time, but can + improve execution speed. It is not meaningful to set this to less + than jit_above_cost. + Setting this to -1 disables inlining. The default is 500000. - - jit_inline_above_cost (floating point) + + jit_optimize_above_cost (floating point) - jit_inline_above_cost configuration parameter + jit_optimize_above_cost configuration parameter - Sets the planner's cutoff above which JIT compiled programs (see ) attempt to inline functions and - operators. Inlining initially takes time, but can improve execution - speed. It is unlikely to be beneficial to set - jit_inline_above_cost below - jit_optimize_above_cost. - + Sets the query cost above which JIT compilation applies expensive + optimizations. Such optimization adds planning time, but can improve + execution speed. It is not meaningful to set this to less + than jit_above_cost, and it is unlikely to be + beneficial to set it to more + than jit_inline_above_cost. + Setting this to -1 disables expensive optimizations. The default is 500000. @@ -4414,11 +5097,11 @@ ANY num_sync ( .) Refer to for - more information on using constraint exclusion and partitioning. + more information on using constraint exclusion to implement + partitioning. @@ -4507,10 +5194,9 @@ SELECT * FROM parent WHERE key = 2400; - Determines whether JIT may be used by + Determines whether JIT compilation may be used by PostgreSQL, if available (see ). - The default is on. @@ -4623,6 +5309,34 @@ SELECT * FROM parent WHERE key = 2400; + + plan_cache_mode (enum) + + plan_cache_mode configuration parameter + + + + + Prepared statements (either explicitly prepared or implicitly + generated, for example by PL/pgSQL) can be executed using custom or + generic plans. Custom plans are made afresh for each execution + using its specific set of parameter values, while generic plans do + not rely on the parameter values and can be re-used across + executions. Thus, use of a generic plan saves planning time, but if + the ideal plan depends strongly on the parameter values then a + generic plan may be inefficient. The choice between these options + is normally made automatically, but it can be overridden + with plan_cache_mode. + The allowed values are auto (the default), + force_custom_plan and + force_generic_plan. + This setting is considered when a cached plan is to be executed, + not when it is prepared. + For more information see . + + + + @@ -4635,7 +5349,7 @@ SELECT * FROM parent WHERE key = 2400; - Where To Log + Where to Log where to log @@ -5079,32 +5793,10 @@ local0.* /var/log/postgresql - When To Log + When to Log - - client_min_messages (enum) - - client_min_messages configuration parameter - - - - - Controls which message levels are sent to the client. - Valid values are DEBUG5, - DEBUG4, DEBUG3, DEBUG2, - DEBUG1, LOG, NOTICE, - WARNING, ERROR, FATAL, - and PANIC. Each level - includes all the levels that follow it. The later the level, - the fewer messages are sent. The default is - NOTICE. Note that LOG has a different - rank here than in log_min_messages. - - - - log_min_messages (enum) @@ -5113,7 +5805,8 @@ local0.* /var/log/postgresql - Controls which message levels are written to the server log. + Controls which message + levels are written to the server log. Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, @@ -5122,7 +5815,7 @@ local0.* /var/log/postgresql follow it. The later the level, the fewer messages are sent to the log. The default is WARNING. Note that LOG has a different rank here than in - client_min_messages. + . Only superusers can change this setting. @@ -5139,7 +5832,9 @@ local0.* /var/log/postgresql Controls which SQL statements that cause an error condition are recorded in the server log. The current SQL statement is included in the log entry for any message of - the specified severity or higher. + the specified + severity + or higher. Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, @@ -5197,6 +5892,32 @@ local0.* /var/log/postgresql + + log_transaction_sample_rate (real) + + log_transaction_sample_rate configuration parameter + + + + + Set the fraction of transactions whose statements are all logged, + in addition to statements logged for other reasons. It applies to + each new transaction regardless of its statements' durations. + The default is 0, meaning not to log statements + from any additional transaction. Setting this to 1 + logs all statements for all transactions. + log_transaction_sample_rate is helpful to track a + sample of transaction. + + + + Like all statement-logging options, this option can add significant + overhead. + + + + + @@ -5288,7 +6009,7 @@ local0.* /var/log/postgresql - What To Log + What to Log @@ -5444,7 +6165,7 @@ local0.* /var/log/postgresql - The difference between setting this option and setting + The difference between enabling log_duration and setting to zero is that exceeding log_min_duration_statement forces the text of the query to be logged, but this option doesn't. Thus, if @@ -5939,8 +6660,15 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - Sets the cluster name that appears in the process title for all - server processes in this cluster. The name can be any string of less + Sets a name that identifies this database cluster (instance) for + various purposes. The cluster name appears in the process title for + all server processes in this cluster. Moreover, it is the default + application name for a standby connection (see .) + + + + The name can be any string of less than NAMEDATALEN characters (64 characters in a standard build). Only printable ASCII characters may be used in the cluster_name value. Other characters will be @@ -6200,15 +6928,16 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; log_autovacuum_min_duration (integer) - log_autovacuum_min_duration configuration parameter + log_autovacuum_min_duration + configuration parameter Causes each action executed by autovacuum to be logged if it ran for at least the specified number of milliseconds. Setting this to zero logs - all autovacuum actions. Minus-one (the default) disables logging - autovacuum actions. For example, if you set this to + all autovacuum actions. -1 (the default) disables + logging autovacuum actions. For example, if you set this to 250ms then all automatic vacuums and analyzes that run 250ms or longer will be logged. In addition, when this parameter is set to any value other than -1, a message will be @@ -6259,7 +6988,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_threshold (integer) - autovacuum_vacuum_threshold configuration parameter + autovacuum_vacuum_threshold + configuration parameter @@ -6278,7 +7008,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_analyze_threshold (integer) - autovacuum_analyze_threshold configuration parameter + autovacuum_analyze_threshold + configuration parameter @@ -6297,7 +7028,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_scale_factor (floating point) - autovacuum_vacuum_scale_factor configuration parameter + autovacuum_vacuum_scale_factor + configuration parameter @@ -6317,7 +7049,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_analyze_scale_factor (floating point) - autovacuum_analyze_scale_factor configuration parameter + autovacuum_analyze_scale_factor + configuration parameter @@ -6337,7 +7070,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_freeze_max_age (integer) - autovacuum_freeze_max_age configuration parameter + autovacuum_freeze_max_age + configuration parameter @@ -6365,7 +7099,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_multixact_freeze_max_age (integer) - autovacuum_multixact_freeze_max_age configuration parameter + autovacuum_multixact_freeze_max_age + configuration parameter @@ -6391,9 +7126,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; - autovacuum_vacuum_cost_delay (integer) + autovacuum_vacuum_cost_delay (floating point) - autovacuum_vacuum_cost_delay configuration parameter + autovacuum_vacuum_cost_delay + configuration parameter @@ -6401,7 +7137,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; Specifies the cost delay value that will be used in automatic VACUUM operations. If -1 is specified, the regular value will be used. - The default value is 20 milliseconds. + The default value is 2 milliseconds. This parameter can only be set in the postgresql.conf file or on the server command line; but the setting can be overridden for individual tables by @@ -6413,7 +7149,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; autovacuum_vacuum_cost_limit (integer) - autovacuum_vacuum_cost_limit configuration parameter + autovacuum_vacuum_cost_limit + configuration parameter @@ -6443,6 +7180,32 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; Statement Behavior + + client_min_messages (enum) + + client_min_messages configuration parameter + + + + + Controls which + message levels + are sent to the client. + Valid values are DEBUG5, + DEBUG4, DEBUG3, DEBUG2, + DEBUG1, LOG, NOTICE, + WARNING, and ERROR. + Each level includes all the levels that follow it. The later the level, + the fewer messages are sent. The default is + NOTICE. Note that LOG has a different + rank here than in . + + + INFO level messages are always sent to the client. + + + + search_path (string) @@ -6471,7 +7234,7 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; If one of the list items is the special name $user, then the schema having the name returned by - SESSION_USER is substituted, if there is such a schema + CURRENT_USER is substituted, if there is such a schema and the user has USAGE permission for it. (If not, $user is ignored.) @@ -6484,6 +7247,10 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; be searched before searching any of the path items. + Likewise, the current session's temporary-table schema, pg_temp_nnn, is always searched if it @@ -6559,6 +7326,23 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + default_table_access_method (string) + + default_table_access_method configuration parameter + + + + + This parameter specifies the default table access method to use when + creating tables or materialized views if the CREATE + command does not explicitly specify an access method, or when + SELECT ... INTO is used, which does not allow to + specify a table access method. The default is heap. + + + + default_tablespace (string) @@ -6570,7 +7354,8 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; This variable specifies the default tablespace in which to create objects (tables and indexes) when a CREATE command does - not explicitly specify a tablespace. + not explicitly specify a tablespace. It also determines the tablespace + that a partitioned relation will direct future partitions to. @@ -6966,6 +7751,47 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv; + + vacuum_cleanup_index_scale_factor (floating point) + + vacuum_cleanup_index_scale_factor + configuration parameter + + + + + Specifies the fraction of the total number of heap tuples counted in + the previous statistics collection that can be inserted without + incurring an index scan at the VACUUM cleanup stage. + This setting currently applies to B-tree indexes only. + + + + If no tuples were deleted from the heap, B-tree indexes are still + scanned at the VACUUM cleanup stage when at least one + of the following conditions is met: the index statistics are stale, or + the index contains deleted pages that can be recycled during cleanup. + Index statistics are considered to be stale if the number of newly + inserted tuples exceeds the vacuum_cleanup_index_scale_factor + fraction of the total number of heap tuples detected by the previous + statistics collection. The total number of heap tuples is stored in + the index meta-page. Note that the meta-page does not include this data + until VACUUM finds no dead tuples, so B-tree index + scan at the cleanup stage can only be skipped if the second and + subsequent VACUUM cycles detect no dead tuples. + + + + The value can range from 0 to + 10000000000. + When vacuum_cleanup_index_scale_factor is set to + 0, index scans are never skipped during + VACUUM cleanup. The default value is 0.1. + + + + + bytea_output (enum) @@ -7048,7 +7874,8 @@ SET XML OPTION { DOCUMENT | CONTENT }; gin_pending_list_limit (integer) - gin_pending_list_limit configuration parameter + gin_pending_list_limit + configuration parameter @@ -7184,16 +8011,38 @@ SET XML OPTION { DOCUMENT | CONTENT }; - This parameter adjusts the number of digits displayed for + This parameter adjusts the number of digits used for textual output of floating-point values, including float4, float8, - and geometric data types. The parameter value is added to the - standard number of digits (FLT_DIG or DBL_DIG - as appropriate). The value can be set as high as 3, to include - partially-significant digits; this is especially useful for dumping - float data that needs to be restored exactly. Or it can be set - negative to suppress unwanted digits. - See also . + and geometric data types. + + + If the value is 1 (the default) or above, float values are output in + shortest-precise format; see . The + actual number of digits generated depends only on the value being + output, not on the value of this parameter. At most 17 digits are + required for float8 values, and 9 for float4 + values. This format is both fast and precise, preserving the original + binary float value exactly when correctly read. For historical + compatibility, values up to 3 are permitted. + + If the value is zero or negative, then the output is rounded to a + given decimal precision. The precision used is the standard number of + digits for the type (FLT_DIG + or DBL_DIG as appropriate) reduced according to the + value of this parameter. (For example, specifying -1 will cause + float4 values to be output rounded to 5 significant + digits, and float8 values + rounded to 14 digits.) This format is slower and does not preserve all + the bits of the binary float value, but may be more human-readable. + + + + The meaning of this parameter, and its default value, changed + in PostgreSQL 12; + see for further discussion. + + @@ -7519,16 +8368,17 @@ SET XML OPTION { DOCUMENT | CONTENT }; - Determines which JIT provider (see ) is - used. The built-in default is llvmjit. + This variable is the name of the JIT provider library to be used + (see ). + The default is llvmjit. + This parameter can only be set at server start. + - If set to a non-existent library JIT will not be + If set to a non-existent library, JIT will not be available, but no error will be raised. This allows JIT support to be installed separately from the main PostgreSQL package. - - This parameter can only be set at server start. @@ -7830,35 +8680,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - - default_with_oids (boolean) - - default_with_oids configuration parameter - - - - - This controls whether CREATE TABLE and - CREATE TABLE AS include an OID column in - newly-created tables, if neither WITH OIDS - nor WITHOUT OIDS is specified. It also - determines whether OIDs will be included in tables created by - SELECT INTO. The parameter is off - by default; in PostgreSQL 8.0 and earlier, it - was on by default. - - - - The use of OIDs in user tables is considered deprecated, so - most installations should leave this variable disabled. - Applications that require OIDs for a particular table should - specify WITH OIDS when creating the - table. This variable can be enabled for compatibility with old - applications that do not follow this behavior. - - - - escape_string_warning (boolean) stringsescape warning @@ -8067,8 +8888,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - If true, any error will terminate the current session. By default, - this is set to false, so that only FATAL errors will terminate the + If on, any error will terminate the current session. By default, + this is set to off, so that only FATAL errors will terminate the session. @@ -8082,9 +8903,9 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - When set to true, which is the default, PostgreSQL + When set to on, which is the default, PostgreSQL will automatically reinitialize after a backend crash. Leaving this - value set to true is normally the best way to maximize the availability + value set to on is normally the best way to maximize the availability of the database. However, in some circumstances, such as when PostgreSQL is being invoked by clusterware, it may be useful to disable the restart so that the clusterware can gain @@ -8093,6 +8914,39 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + data_sync_retry (boolean) + + data_sync_retry configuration parameter + + + + + When set to off, which is the default, PostgreSQL + will raise a PANIC-level error on failure to flush modified data files + to the file system. This causes the database server to crash. This + parameter can only be set at server start. + + + On some operating systems, the status of data in the kernel's page + cache is unknown after a write-back failure. In some cases it might + have been entirely forgotten, making it unsafe to retry; the second + attempt may be reported as successful, when in fact the data has been + lost. In these circumstances, the only way to avoid data loss is to + recover from the WAL after any failure is reported, preferably + after investigating the root cause of the failure and replacing any + faulty hardware. + + + If set to on, PostgreSQL will instead + report an error but continue to run so that the data flushing + operation can be retried in a later checkpoint. Only set it to on + after investigating the operating system's treatment of buffered data + in case of write-back failure. + + + + @@ -8338,6 +9192,22 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + ssl_library (string) + + ssl_library configuration parameter + + + + + Reports the name of the SSL library that this + PostgreSQL server was built with (even if + SSL is not currently configured or in use on this instance), for + example OpenSSL, or an empty string if none. + + + + wal_block_size (integer) @@ -8361,11 +9231,8 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' - Reports the number of blocks (pages) in a WAL segment file. - The total size of a WAL segment file in bytes is equal to - wal_segment_size multiplied by wal_block_size; - by default this is 16MB. See for - more information. + Reports the size of write ahead log segments. The default value is + 16MB. See for more information. @@ -8807,9 +9674,8 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) If LLVM has the required functionality, register generated functions with GDB. This makes debugging easier. - - The default setting is off, and can only be set at - server start. + The default setting is off. + This parameter can only be set at server start. @@ -8823,11 +9689,10 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) Writes the generated LLVM IR out to the - filesystem, inside . This is only + file system, inside . This is only useful for working on the internals of the JIT implementation. - - The default setting is off, and it can only be - changed by a superuser. + The default setting is off. + This parameter can only be changed by a superuser. @@ -8840,8 +9705,8 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - Determines whether expressions are JIT compiled, subject to costing - decisions (see ). The default is + Determines whether expressions are JIT compiled, when JIT compilation + is activated (see ). The default is on. @@ -8855,13 +9720,12 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - If LLVM has the required functionality, emit required data to allow + If LLVM has the required functionality, emit the data needed to allow perf to profile functions generated by JIT. This writes out files to $HOME/.debug/jit/; the user is responsible for performing cleanup when desired. - - The default setting is off, and can only be set at - server start. + The default setting is off. + This parameter can only be set at server start. @@ -8874,9 +9738,9 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1) - Determines whether tuple deforming is JIT compiled, subject to costing - decisions (see ). The default is - on. + Determines whether tuple deforming is JIT compiled, when JIT + compilation is activated (see ). + The default is on. diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml index 844ea161c42..fed6f249328 100644 --- a/doc/src/sgml/contrib-spi.sgml +++ b/doc/src/sgml/contrib-spi.sgml @@ -65,99 +65,6 @@ - - timetravel — Functions for Implementing Time Travel - - - Long ago, PostgreSQL had a built-in time travel feature - that kept the insert and delete times for each tuple. This can be - emulated using these functions. To use these functions, - you must add to a table two columns of abstime type to store - the date when a tuple was inserted (start_date) and changed/deleted - (stop_date): - - -CREATE TABLE mytab ( - ... ... - start_date abstime, - stop_date abstime - ... ... -); - - - The columns can be named whatever you like, but in this discussion - we'll call them start_date and stop_date. - - - - When a new row is inserted, start_date should normally be set to - current time, and stop_date to infinity. The trigger - will automatically substitute these values if the inserted data - contains nulls in these columns. Generally, inserting explicit - non-null data in these columns should only be done when re-loading - dumped data. - - - - Tuples with stop_date equal to infinity are valid - now, and can be modified. Tuples with a finite stop_date cannot - be modified anymore — the trigger will prevent it. (If you need - to do that, you can turn off time travel as shown below.) - - - - For a modifiable row, on update only the stop_date in the tuple being - updated will be changed (to current time) and a new tuple with the modified - data will be inserted. Start_date in this new tuple will be set to current - time and stop_date to infinity. - - - - A delete does not actually remove the tuple but only sets its stop_date - to current time. - - - - To query for tuples valid now, include - stop_date = 'infinity' in the query's WHERE condition. - (You might wish to incorporate that in a view.) Similarly, you can - query for tuples valid at any past time with suitable conditions on - start_date and stop_date. - - - - timetravel() is the general trigger function that supports - this behavior. Create a BEFORE INSERT OR UPDATE OR DELETE - trigger using this function on each time-traveled table. Specify two - trigger arguments: the actual - names of the start_date and stop_date columns. - Optionally, you can specify one to three more arguments, which must refer - to columns of type text. The trigger will store the name of - the current user into the first of these columns during INSERT, the - second column during UPDATE, and the third during DELETE. - - - - set_timetravel() allows you to turn time-travel on or off for - a table. - set_timetravel('mytab', 1) will turn TT ON for table mytab. - set_timetravel('mytab', 0) will turn TT OFF for table mytab. - In both cases the old status is reported. While TT is off, you can modify - the start_date and stop_date columns freely. Note that the on/off status - is local to the current database session — fresh sessions will - always start out with TT ON for all tables. - - - - get_timetravel() returns the TT state for a table without - changing it. - - - - There is an example in timetravel.example. - - - autoinc — Functions for Autoincrementing Fields diff --git a/doc/src/sgml/cube.sgml b/doc/src/sgml/cube.sgml index e010305d848..c6e586270aa 100644 --- a/doc/src/sgml/cube.sgml +++ b/doc/src/sgml/cube.sgml @@ -190,7 +190,7 @@ n = 2 * k - 1 means lower bound of k-th dimension, n = 2 * k means upper bound of k-th dimension. Negative - n denotes inversed value of corresponding + n denotes the inverse value of the corresponding positive coordinate. This operator is designed for KNN-GiST support. diff --git a/doc/src/sgml/custom-scan.sgml b/doc/src/sgml/custom-scan.sgml index 24631f5f404..239ba29de72 100644 --- a/doc/src/sgml/custom-scan.sgml +++ b/doc/src/sgml/custom-scan.sgml @@ -1,7 +1,7 @@ - Writing A Custom Scan Provider + Writing a Custom Scan Provider custom scan provider @@ -37,8 +37,9 @@ A custom scan provider will typically add paths for a base relation by setting the following hook, which is called after the core code has - generated what it believes to be the complete and correct set of access - paths for the relation. + generated all the access paths it can for the relation (except for + Gather paths, which are made after this call so that they can use + partial paths added by the hook): typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, RelOptInfo *rel, @@ -82,10 +83,7 @@ typedef struct CustomPath by nodeToString, so that debugging routines that attempt to print the custom path will work as designed. methods must point to a (usually statically allocated) object implementing the required - custom path methods, of which there is currently only one. The - LibraryName and SymbolName fields must also - be initialized so that the dynamic loader can resolve them to locate the - method table. + custom path methods, of which there is currently only one. diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 67bae322878..9b6d6878eb0 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -515,14 +515,13 @@ We use the following terms below: The - scale of a numeric is the - count of decimal digits in the fractional part, to the right of - the decimal point. The precision of a - numeric is the total count of significant digits in - the whole number, that is, the number of digits to both sides of - the decimal point. So the number 23.5141 has a precision of 6 - and a scale of 4. Integers can be considered to have a scale of - zero. + precision of a numeric + is the total count of significant digits in the whole number, + that is, the number of digits to both sides of the decimal point. + The scale of a numeric is the + count of decimal digits in the fractional part, to the right of the + decimal point. So the number 23.5141 has a precision of 6 and a + scale of 4. Integers can be considered to have a scale of zero. @@ -672,13 +671,12 @@ FROM generate_series(-3.5, 3.5, 1) as x; - The data types real and double - precision are inexact, variable-precision numeric types. - In practice, these types are usually implementations of - IEEE Standard 754 for Binary Floating-Point - Arithmetic (single and double precision, respectively), to the - extent that the underlying processor, operating system, and - compiler support it. + The data types real and double precision are + inexact, variable-precision numeric types. On all currently supported + platforms, these types are implementations of IEEE + Standard 754 for Binary Floating-Point Arithmetic (single and double + precision, respectively), to the extent that the underlying processor, + operating system, and compiler support it. @@ -716,24 +714,57 @@ FROM generate_series(-3.5, 3.5, 1) as x; - On most platforms, the real type has a range of at least - 1E-37 to 1E+37 with a precision of at least 6 decimal digits. The - double precision type typically has a range of around - 1E-307 to 1E+308 with a precision of at least 15 digits. Values that - are too large or too small will cause an error. Rounding might - take place if the precision of an input number is too high. - Numbers too close to zero that are not representable as distinct - from zero will cause an underflow error. + On all currently supported platforms, the real type has a + range of around 1E-37 to 1E+37 with a precision of at least 6 decimal + digits. The double precision type has a range of around + 1E-307 to 1E+308 with a precision of at least 15 digits. Values that are + too large or too small will cause an error. Rounding might take place if + the precision of an input number is too high. Numbers too close to zero + that are not representable as distinct from zero will cause an underflow + error. + + + + By default, floating point values are output in text form in their + shortest precise decimal representation; the decimal value produced is + closer to the true stored binary value than to any other value + representable in the same binary precision. (However, the output value is + currently never exactly midway between two + representable values, in order to avoid a widespread bug where input + routines do not properly respect the round-to-even rule.) This value will + use at most 17 significant decimal digits for float8 + values, and at most 9 digits for float4 values. - The setting controls the - number of extra significant digits included when a floating point - value is converted to text for output. With the default value of - 0, the output is the same on every platform - supported by PostgreSQL. Increasing it will produce output that - more accurately represents the stored value, but may be unportable. + This shortest-precise output format is much faster to generate than the + historical rounded format. + + + + + For compatibility with output generated by older versions + of PostgreSQL, and to allow the output + precision to be reduced, the + parameter can be used to select rounded decimal output instead. Setting a + value of 0 restores the previous default of rounding the value to 6 + (for float4) or 15 (for float8) + significant decimal digits. Setting a negative value reduces the number + of digits further; for example -2 would round output to 4 or 13 digits + respectively. + + + + Any value of greater than 0 + selects the shortest-precise format. + + + + + Applications that wanted precise values have historically had to set + to 3 to obtain them. For + maximum compatibility between versions, they should continue to do so. @@ -752,9 +783,7 @@ FROM generate_series(-3.5, 3.5, 1) as x; These represent the IEEE 754 special values infinity, negative infinity, and - not-a-number, respectively. (On a machine whose - floating-point arithmetic does not follow IEEE 754, these values - will probably not work as expected.) When writing these values + not-a-number, respectively. When writing these values as constants in an SQL command, you must put quotes around them, for example UPDATE table SET x = '-Infinity'. On input, these strings are recognized in a case-insensitive manner. @@ -787,17 +816,6 @@ FROM generate_series(-3.5, 3.5, 1) as x; double precision. - - - The assumption that real and - double precision have exactly 24 and 53 bits in the - mantissa respectively is correct for IEEE-standard floating point - implementations. On non-IEEE platforms it might be off a little, but - for simplicity the same ranges of p are used - on all platforms. - - - @@ -862,7 +880,7 @@ CREATE TABLE tablename ( is equivalent to specifying: -CREATE SEQUENCE tablename_colname_seq; +CREATE SEQUENCE tablename_colname_seq AS integer; CREATE TABLE tablename ( colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') ); @@ -1297,7 +1315,7 @@ SELECT b, char_length(b) FROM test2; strings are distinguished from character strings in two ways. First, binary strings specifically allow storing octets of value zero and other non-printable - octets (usually, octets outside the range 32 to 126). + octets (usually, octets outside the decimal range 32 to 126). Character strings disallow zero octets, and also disallow any other octet values and sequences of octet values that are invalid according to the database's selected character set encoding. @@ -1309,9 +1327,10 @@ SELECT b, char_length(b) FROM test2; - The bytea type supports two external formats for - input and output: PostgreSQL's historical - escape format, and hex format. Both + The bytea type supports two + formats for input and output: hex format + and PostgreSQL's historical + escape format. Both of these are always accepted on input. The output format depends on the configuration parameter ; the default is hex. (Note that the hex format was introduced in @@ -1335,9 +1354,9 @@ SELECT b, char_length(b) FROM test2; per byte, most significant nibble first. The entire string is preceded by the sequence \x (to distinguish it from the escape format). In some contexts, the initial backslash may - need to be escaped by doubling it, in the same cases in which backslashes - have to be doubled in escape format; details appear below. - The hexadecimal digits can + need to be escaped by doubling it + (see ). + For input, the hexadecimal digits can be either upper or lower case, and whitespace is permitted between digit pairs (but not within a digit pair nor in the starting \x sequence). @@ -1349,7 +1368,7 @@ SELECT b, char_length(b) FROM test2; Example: -SELECT E'\\xDEADBEEF'; +SELECT '\xDEADBEEF'; @@ -1369,7 +1388,7 @@ SELECT E'\\xDEADBEEF'; convenient. But in practice it is usually confusing because it fuzzes up the distinction between binary strings and character strings, and also the particular escape mechanism that was chosen is - somewhat unwieldy. So this format should probably be avoided + somewhat unwieldy. Therefore, this format should probably be avoided for most new applications. @@ -1379,10 +1398,8 @@ SELECT E'\\xDEADBEEF'; values must be escaped, while all octet values can be escaped. In general, to escape an octet, convert it into its three-digit - octal value and precede it - by a backslash (or two backslashes, if writing the value as a - literal using escape string syntax). - Backslash itself (octet value 92) can alternatively be represented by + octal value and precede it by a backslash. + Backslash itself (octet decimal value 92) can alternatively be represented by double backslashes. shows the characters that must be escaped, and gives the alternative @@ -1398,7 +1415,7 @@ SELECT E'\\xDEADBEEF'; Description Escaped Input Representation Example - Output Representation + Hex Representation @@ -1406,33 +1423,33 @@ SELECT E'\\xDEADBEEF'; 0 zero octet - E'\\000' - SELECT E'\\000'::bytea; - \000 + '\000' + SELECT '\000'::bytea; + \x00 39 single quote - '''' or E'\\047' - SELECT E'\''::bytea; - ' + '''' or '\047' + SELECT ''''::bytea; + \x27 92 backslash - E'\\\\' or E'\\134' - SELECT E'\\\\'::bytea; - \\ + '\\' or '\134' + SELECT '\\'::bytea; + \x5c 0 to 31 and 127 to 255 non-printable octets - E'\\xxx' (octal value) - SELECT E'\\001'::bytea; - \001 + '\xxx' (octal value) + SELECT '\001'::bytea; + \x01 @@ -1442,41 +1459,49 @@ SELECT E'\\xDEADBEEF'; The requirement to escape non-printable octets varies depending on locale settings. In some instances you can get away - with leaving them unescaped. Note that the result in each of the examples - in was exactly one octet in - length, even though the output representation is sometimes - more than one character. + with leaving them unescaped. + + + + The reason that single quotes must be doubled, as shown + in , is that this + is true for any string literal in a SQL command. The generic + string-literal parser consumes the outermost single quotes + and reduces any pair of single quotes to one data character. + What the bytea input function sees is just one + single quote, which it treats as a plain data character. + However, the bytea input function treats + backslashes as special, and the other behaviors shown in + are implemented by + that function. - The reason multiple backslashes are required, as shown - in , is that an input - string written as a string literal must pass through two parse - phases in the PostgreSQL server. - The first backslash of each pair is interpreted as an escape - character by the string-literal parser (assuming escape string - syntax is used) and is therefore consumed, leaving the second backslash of the - pair. (Dollar-quoted strings can be used to avoid this level - of escaping.) The remaining backslash is then recognized by the - bytea input function as starting either a three - digit octal value or escaping another backslash. For example, - a string literal passed to the server as E'\\001' - becomes \001 after passing through the - escape string parser. The \001 is then sent - to the bytea input function, where it is converted - to a single octet with a decimal value of 1. Note that the - single-quote character is not treated specially by bytea, - so it follows the normal rules for string literals. (See also - .) + In some contexts, backslashes must be doubled compared to what is + shown above, because the generic string-literal parser will also + reduce pairs of backslashes to one data character; + see . - Bytea octets are sometimes escaped when output. In general, each - non-printable octet is converted into - its equivalent three-digit octal value and preceded by one backslash. - Most printable octets are represented by their standard - representation in the client character set. The octet with decimal - value 92 (backslash) is doubled in the output. + Bytea octets are output in hex + format by default. If you change + to escape, + non-printable octets are converted to their + equivalent three-digit octal value and preceded by one backslash. + Most printable octets are output by their standard + representation in the client character set, e.g.: + + +SET bytea_output = 'escape'; + +SELECT 'abc \153\154\155 \052\251\124'::bytea; + bytea +---------------- + abc klm *\251T + + + The octet with decimal value 92 (backslash) is doubled in the output. Details are in . @@ -1499,7 +1524,7 @@ SELECT E'\\xDEADBEEF'; 92 backslash \\ - SELECT E'\\134'::bytea; + SELECT '\134'::bytea; \\ @@ -1507,7 +1532,7 @@ SELECT E'\\xDEADBEEF'; 0 to 31 and 127 to 255 non-printable octets \xxx (octal value) - SELECT E'\\001'::bytea; + SELECT '\001'::bytea; \001 @@ -1515,7 +1540,7 @@ SELECT E'\\xDEADBEEF'; 32 to 126 printable octets client character set representation - SELECT E'\\176'::bytea; + SELECT '\176'::bytea; ~ @@ -1699,14 +1724,6 @@ MINUTE TO SECOND any application. - - The types abstime - and reltime are lower precision types which are used internally. - You are discouraged from using these types in - applications; these internal types - might disappear in a future release. - - Date/Time Input @@ -2407,7 +2424,7 @@ January 8 04:05:06 1999 PST linkend="view-pg-timezone-names"/>). PostgreSQL uses the widely-used IANA time zone data for this purpose, so the same time zone - names are also recognized by much other software. + names are also recognized by other software. @@ -2670,19 +2687,6 @@ P years-months- to each field if any field is negative. - - Internally interval values are stored as months, days, - and seconds. This is done because the number of days in a month - varies, and a day can have 23 or 25 hours if a daylight savings - time adjustment is involved. The months and days fields are integers - while the seconds field can store fractions. Because intervals are - usually created from constant strings or timestamp subtraction, - this storage method works well in most cases. Functions - justify_days and justify_hours are - available for adjusting days and hours that overflow their normal - ranges. - - In the verbose input format, and in some fields of the more compact input formats, field values can have fractional parts; for example @@ -2734,6 +2738,33 @@ P years-months- + + Internally interval values are stored as months, days, + and seconds. This is done because the number of days in a month + varies, and a day can have 23 or 25 hours if a daylight savings + time adjustment is involved. The months and days fields are integers + while the seconds field can store fractions. Because intervals are + usually created from constant strings or timestamp subtraction, + this storage method works well in most cases, but can cause unexpected + results: + + +SELECT EXTRACT(hours from '80 minutes'::interval); + date_part +----------- + 1 + +SELECT EXTRACT(days from '80 hours'::interval); + date_part +----------- + 0 + + + Functions justify_days and + justify_hours are available for adjusting days + and hours that overflow their normal ranges. + + @@ -2874,37 +2905,36 @@ P years-months- - Valid literal values for the true state are: + Boolean constants can be represented in SQL queries by the SQL + key words TRUE, FALSE, + and NULL. + + + + The datatype input function for type boolean accepts these + string representations for the true state: - TRUE - 't' - 'true' - 'y' - 'yes' - 'on' - '1' + true + yes + on + 1 - For the false state, the following values can be - used: + and these representations for the false state: - FALSE - 'f' - 'false' - 'n' - 'no' - 'off' - '0' + false + no + off + 0 + Unique prefixes of these strings are also accepted, for + example t or n. Leading or trailing whitespace is ignored, and case does not matter. - The key words - TRUE and FALSE are the preferred - (SQL-compliant) usage. - shows that - boolean values are output using the letters - t and f. + The datatype output function for type boolean always emits + either t or f, as shown in + . @@ -2926,6 +2956,27 @@ SELECT * FROM test1 WHERE a; t | sic est + + + The key words TRUE and FALSE are + the preferred (SQL-compliant) method for writing + Boolean constants in SQL queries. But you can also use the string + representations by following the generic string-literal constant syntax + described in , for + example 'yes'::boolean. + + + + Note that the parser automatically understands + that TRUE and FALSE are of + type boolean, but this is not so + for NULL because that can have any type. + So in some contexts you might have to cast NULL + to boolean explicitly, for + example NULL::boolean. Conversely, the cast can be + omitted from a string-literal Boolean value in contexts where the parser + can deduce that the literal must be of type boolean. + @@ -4144,16 +4195,8 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 - PostgreSQL provides storage and comparison - functions for UUIDs, but the core database does not include any - function for generating UUIDs, because no single algorithm is well - suited for every application. The module - provides functions that implement several standard algorithms. - The module also provides a generation - function for random UUIDs. - Alternatively, UUIDs could be generated by client applications or - other libraries invoked through a server-side function. + See for how to generate a UUID in + PostgreSQL. @@ -4177,15 +4220,22 @@ a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 The xml type can store well-formed documents, as defined by the XML standard, as well - as content fragments, which are defined by the - production XMLDecl? content in the XML - standard. Roughly, this means that content fragments can have + as content fragments, which are defined by reference + to the more permissive + document node + of the XQuery and XPath data model. + Roughly, this means that content fragments can have more than one top-level element or character node. The expression xmlvalue IS DOCUMENT can be used to evaluate whether a particular xml value is a full document or only a content fragment. + + Limits and compatibility notes for the xml data type + can be found in . + + Creating XML Values @@ -4254,16 +4304,6 @@ SET xmloption TO { DOCUMENT | CONTENT }; data are allowed. - - - With the default XML option setting, you cannot directly cast - character strings to type xml if they contain a - document type declaration, because the definition of XML content - fragment does not accept them. If you need to do that, either - use XMLPARSE or change the XML option. - - - @@ -4479,25 +4519,22 @@ INSERT INTO mytable VALUES(-1); -- fails Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various - system tables. OIDs are not added to user-created tables, unless - WITH OIDS is specified when the table is - created, or the - configuration variable is enabled. Type oid represents - an object identifier. There are also several alias types for - oid: regproc, regprocedure, - regoper, regoperator, regclass, - regtype, regrole, regnamespace, - regconfig, and regdictionary. - shows an overview. + system tables. + + Type oid represents an object identifier. There are also + several alias types for oid: regproc, + regprocedure, regoper, regoperator, + regclass, regtype, regrole, + regnamespace, regconfig, and + regdictionary. shows an + overview. The oid type is currently implemented as an unsigned four-byte integer. Therefore, it is not large enough to provide database-wide uniqueness in large databases, or even in large - individual tables. So, using a user-created table's OID column as - a primary key is discouraged. OIDs are best used only for - references to system tables. + individual tables. diff --git a/doc/src/sgml/datetime.sgml b/doc/src/sgml/datetime.sgml index d269aa4cc55..23561b19c97 100644 --- a/doc/src/sgml/datetime.sgml +++ b/doc/src/sgml/datetime.sgml @@ -24,7 +24,7 @@ Date/Time Input Interpretation - The date/time type inputs are all decoded using the following procedure. + Date/time input strings are decoded using the following procedure. @@ -73,20 +73,21 @@ - If the token is a text string, match up with possible strings: + If the token is an alphabetic string, match up with possible strings: - Do a binary-search table lookup for the token as a time zone - abbreviation. + See if the token matches any known time zone abbreviation. + These abbreviations are supplied by the configuration file + described in . - If not found, do a similar binary-search table lookup to match + If not found, search an internal table to match the token as either a special string (e.g., today), day (e.g., Thursday), month (e.g., January), @@ -176,6 +177,83 @@ + + Handling of Invalid or Ambiguous Timestamps + + + Ordinarily, if a date/time string is syntactically valid but contains + out-of-range field values, an error will be thrown. For example, input + specifying the 31st of February will be rejected. + + + + During a daylight-savings-time transition, it is possible for a + seemingly valid timestamp string to represent a nonexistent or ambiguous + timestamp. Such cases are not rejected; the ambiguity is resolved by + determining which UTC offset to apply. For example, supposing that the + parameter is set + to America/New_York, consider + +=> SELECT '2018-03-11 02:30'::timestamptz; + timestamptz +------------------------ + 2018-03-11 03:30:00-04 +(1 row) + + Because that day was a spring-forward transition date in that time zone, + there was no civil time instant 2:30AM; clocks jumped forward from 2AM + EST to 3AM EDT. PostgreSQL interprets the + given time as if it were standard time (UTC-5), which then renders as + 3:30AM EDT (UTC-4). + + + + Conversely, consider the behavior during a fall-back transition: + +=> SELECT '2018-11-04 02:30'::timestamptz; + timestamptz +------------------------ + 2018-11-04 02:30:00-05 +(1 row) + + On that date, there were two possible interpretations of 2:30AM; there + was 2:30AM EDT, and then an hour later after the reversion to standard + time, there was 2:30AM EST. + Again, PostgreSQL interprets the given time + as if it were standard time (UTC-5). We can force the matter by + specifying daylight-savings time: + +=> SELECT '2018-11-04 02:30 EDT'::timestamptz; + timestamptz +------------------------ + 2018-11-04 01:30:00-05 +(1 row) + + This timestamp could validly be rendered as either 2:30 UTC-4 or + 1:30 UTC-5; the timestamp output code chooses the latter. + + + + The precise rule that is applied in such cases is that an invalid + timestamp that appears to fall within a jump-forward daylight savings + transition is assigned the UTC offset that prevailed in the time zone + just before the transition, while an ambiguous timestamp that could fall + on either side of a jump-back transition is assigned the UTC offset that + prevailed just after the transition. In most time zones this is + equivalent to saying that the standard-time interpretation is + preferred when in doubt. + + + + In all cases, the UTC offset associated with a timestamp can be + specified explicitly, using either a numeric UTC offset or a time zone + abbreviation that corresponds to a fixed UTC offset. The rule just + given applies only when it is necessary to infer a UTC offset for a time + zone in which the offset varies. + + + + Date/Time Key Words @@ -553,7 +631,7 @@ is now the USA) in 1752. Thus 2 September 1752 was followed by 14 September 1752. - This is why Unix systems have the cal program + This is why Unix systems that have the cal program produce the following: diff --git a/doc/src/sgml/dblink.sgml b/doc/src/sgml/dblink.sgml index 87e14ea093d..97dc3b81292 100644 --- a/doc/src/sgml/dblink.sgml +++ b/doc/src/sgml/dblink.sgml @@ -1165,11 +1165,25 @@ dblink_error_message(text connname) returns text Return Value - Returns last error message, or an empty string if there has been + Returns last error message, or OK if there has been no error in this connection. + + Notes + + + When asynchronous queries are initiated by + dblink_send_query, the error message associated with + the connection might not get updated until the server's response message + is consumed. This typically means that dblink_is_busy + or dblink_get_result should be called prior to + dblink_error_message, so that any error generated by + the asynchronous query will be visible. + + + Examples diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index feb2ab77920..d7158c1b034 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -233,6 +233,124 @@ CREATE TABLE products ( + + Generated Columns + + + generated column + + + + A generated column is a special column that is always computed from other + columns. Thus, it is for columns what a view is for tables. There are two + kinds of generated columns: stored and virtual. A stored generated column + is computed when it is written (inserted or updated) and occupies storage + as if it were a normal column. A virtual generated column occupies no + storage and is computed when it is read. Thus, a virtual generated column + is similar to a view and a stored generated column is similar to a + materialized view (except that it is always updated automatically). + PostgreSQL currently implements only stored generated columns. + + + + To create a generated column, use the GENERATED ALWAYS + AS clause in CREATE TABLE, for example: + +CREATE TABLE people ( + ..., + height_cm numeric, + height_in numeric GENERATED ALWAYS AS (height_cm / 2.54) STORED +); + + The keyword STORED must be specified to choose the + stored kind of generated column. See for + more details. + + + + A generated column cannot be written to directly. In + INSERT or UPDATE commands, a value + cannot be specified for a generated column, but the keyword + DEFAULT may be specified. + + + + Consider the differences between a column with a default and a generated + column. The column default is evaluated once when the row is first + inserted if no other value was provided; a generated column is updated + whenever the row changes and cannot be overridden. A column default may + not refer to other columns of the table; a generation expression would + normally do so. A column default can use volatile functions, for example + random() or functions referring to the current time; + this is not allowed for generated columns. + + + + Several restrictions apply to the definition of generated columns and + tables involving generated columns: + + + + + The generation expression can only use immutable functions and cannot + use subqueries or reference anything other than the current row in any + way. + + + + + A generation expression cannot reference another generated column. + + + + + A generation expression cannot reference a system column, except + tableoid. + + + + + A generated column cannot have a column default or an identity definition. + + + + + A generated column cannot be part of a partition key. + + + + + Foreign tables can have generated columns. See for details. + + + + + + + Additional considerations apply to the use of generated columns. + + + + Generated columns maintain access privileges separately from their + underlying base columns. So, it is possible to arrange it so that a + particular role can read from a generated column but not from the + underlying base columns. + + + + + Generated columns are, conceptually, updated after + BEFORE triggers have run. Therefore, changes made to + base columns in a BEFORE trigger will be reflected in + generated columns. But conversely, it is not allowed to access + generated columns in BEFORE triggers. + + + + + + Constraints @@ -403,6 +521,59 @@ CREATE TABLE products ( ensure that a column does not contain null values, the not-null constraint described in the next section can be used. + + + + PostgreSQL does not support + CHECK constraints that reference table data other than + the new or updated row being checked. While a CHECK + constraint that violates this rule may appear to work in simple + tests, it cannot guarantee that the database will not reach a state + in which the constraint condition is false (due to subsequent changes + of the other row(s) involved). This would cause a database dump and + reload to fail. The reload could fail even when the complete + database state is consistent with the constraint, due to rows not + being loaded in an order that will satisfy the constraint. If + possible, use UNIQUE, EXCLUDE, + or FOREIGN KEY constraints to express + cross-row and cross-table restrictions. + + + + If what you desire is a one-time check against other rows at row + insertion, rather than a continuously-maintained consistency + guarantee, a custom trigger can be used + to implement that. (This approach avoids the dump/reload problem because + pg_dump does not reinstall triggers until after + reloading data, so that the check will not be enforced during a + dump/reload.) + + + + + + PostgreSQL assumes that + CHECK constraints' conditions are immutable, that + is, they will always give the same result for the same input row. + This assumption is what justifies examining CHECK + constraints only when rows are inserted or updated, and not at other + times. (The warning above about not referencing other table data is + really a special case of this restriction.) + + + + An example of a common way to break this assumption is to reference a + user-defined function in a CHECK expression, and + then change the behavior of that + function. PostgreSQL does not disallow + that, but it will not notice if there are rows in the table that now + violate the CHECK constraint. That would cause a + subsequent database dump and reload to fail. + The recommended way to handle such a change is to drop the constraint + (using ALTER TABLE), adjust the function definition, + and re-add the constraint, thereby rechecking it against all table rows. + + @@ -938,24 +1109,6 @@ CREATE TABLE circles ( - - oid - - - - OID - column - - The object identifier (object ID) of a row. This column is only - present if the table was created using WITH - OIDS, or if the - configuration variable was set at the time. This column is of type - oid (same name as the column); see for more information about the type. - - - - tableoid @@ -1049,53 +1202,12 @@ CREATE TABLE circles ( ctid will change if it is updated or moved by VACUUM FULL. Therefore ctid is useless as a long-term row - identifier. The OID, or even better a user-defined serial - number, should be used to identify logical rows. + identifier. A primary key should be used to identify logical rows. - - OIDs are 32-bit quantities and are assigned from a single - cluster-wide counter. In a large or long-lived database, it is - possible for the counter to wrap around. Hence, it is bad - practice to assume that OIDs are unique, unless you take steps to - ensure that this is the case. If you need to identify the rows in - a table, using a sequence generator is strongly recommended. - However, OIDs can be used as well, provided that a few additional - precautions are taken: - - - - - A unique constraint should be created on the OID column of each - table for which the OID will be used to identify rows. When such - a unique constraint (or unique index) exists, the system takes - care not to generate an OID matching an already-existing row. - (Of course, this is only possible if the table contains fewer - than 232 (4 billion) rows, and in practice the - table size had better be much less than that, or performance - might suffer.) - - - - - OIDs should never be assumed to be unique across tables; use - the combination of tableoid and row OID if you - need a database-wide identifier. - - - - - Of course, the tables in question must be created WITH - OIDS. As of PostgreSQL 8.1, - WITHOUT OIDS is the default. - - - - - Transaction identifiers are also 32-bit quantities. In a long-lived database it is possible for transaction IDs to wrap @@ -1189,6 +1301,29 @@ ALTER TABLE products ADD COLUMN description text; value is given (null if you don't specify a DEFAULT clause). + + + From PostgreSQL 11, adding a column with + a constant default value no longer means that each row of the table + needs to be updated when the ALTER TABLE statement + is executed. Instead, the default value will be returned the next time + the row is accessed, and applied when the table is rewritten, making + the ALTER TABLE very fast even on large tables. + + + + However, if the default value is volatile (e.g. + clock_timestamp()) + each row will need to be updated with the value calculated at the time + ALTER TABLE is executed. To avoid a potentially + lengthy update operation, particularly if you intend to fill the column + with mostly nondefault values anyway, it may be preferable to add the + column with no default, insert the correct values using + UPDATE, and then add any desired default as described + below. + + + You can also define constraints on the column at the same time, using the usual syntax: @@ -1203,17 +1338,6 @@ ALTER TABLE products ADD COLUMN description text CHECK (description <> '') correctly. - - - Adding a column with a default requires updating each row of the - table (to store the new column value). However, if no default is - specified, PostgreSQL is able to avoid - the physical update. So if you intend to fill the column with - mostly nondefault values, it's best to add the column with no default, - insert the correct values using UPDATE, and then add any - desired default as described below. - - @@ -1427,6 +1551,10 @@ ALTER TABLE products RENAME TO items; REVOKE + + ACL + + When an object is created, it is assigned an owner. The owner is normally the role that executed the creation statement. @@ -1444,11 +1572,9 @@ ALTER TABLE products RENAME TO items; EXECUTE, and USAGE. The privileges applicable to a particular object vary depending on the object's type (table, function, etc). - For complete information on the different types of privileges - supported by PostgreSQL, refer to the - reference - page. The following sections and chapters will also show you how - those privileges are used. + More detail about the meanings of these privileges appears below. + The following sections and chapters will also show you how + these privileges are used. @@ -1458,15 +1584,17 @@ ALTER TABLE products RENAME TO items; An object can be assigned to a new owner with an ALTER - command of the appropriate kind for the object, e.g. . Superusers can always do - this; ordinary roles can only do it if they are both the current owner - of the object (or a member of the owning role) and a member of the new - owning role. + command of the appropriate kind for the object, for example + +ALTER TABLE table_name OWNER TO new_owner; + + Superusers can always do this; ordinary roles can only do it if they are + both the current owner of the object (or a member of the owning role) and + a member of the new owning role. - To assign privileges, the GRANT command is + To assign privileges, the command is used. For example, if joe is an existing role, and accounts is an existing table, the privilege to update the table can be granted with: @@ -1487,7 +1615,7 @@ GRANT UPDATE ON accounts TO joe; To revoke a privilege, use the fittingly named - REVOKE command: + command: REVOKE ALL ON accounts FROM PUBLIC; @@ -1509,6 +1637,507 @@ REVOKE ALL ON accounts FROM PUBLIC; privilege. For details see the and reference pages. + + + The available privileges are: + + + + SELECT + + + Allows from + any column, or specific column(s), of a table, view, materialized + view, or other table-like object. + Also allows use of TO. + This privilege is also needed to reference existing column values in + or . + For sequences, this privilege also allows use of the + currval function. + For large objects, this privilege allows the object to be read. + + + + + + INSERT + + + Allows of a new row into a table, view, + etc. Can be granted on specific column(s), in which case + only those columns may be assigned to in the INSERT + command (other columns will therefore receive default values). + Also allows use of FROM. + + + + + + UPDATE + + + Allows of any + column, or specific column(s), of a table, view, etc. + (In practice, any nontrivial UPDATE command will + require SELECT privilege as well, since it must + reference table columns to determine which rows to update, and/or to + compute new values for columns.) + SELECT ... FOR UPDATE + and SELECT ... FOR SHARE + also require this privilege on at least one column, in addition to the + SELECT privilege. For sequences, this + privilege allows use of the nextval and + setval functions. + For large objects, this privilege allows writing or truncating the + object. + + + + + + DELETE + + + Allows of a row from a table, view, etc. + (In practice, any nontrivial DELETE command will + require SELECT privilege as well, since it must + reference table columns to determine which rows to delete.) + + + + + + TRUNCATE + + + Allows on a table, view, etc. + + + + + + REFERENCES + + + Allows creation of a foreign key constraint referencing a + table, or specific column(s) of a table. + + + + + + TRIGGER + + + Allows creation of a trigger on a table, view, etc. + + + + + + CREATE + + + For databases, allows new schemas and publications to be created within + the database. + + + For schemas, allows new objects to be created within the schema. + To rename an existing object, you must own the + object and have this privilege for the containing + schema. + + + For tablespaces, allows tables, indexes, and temporary files to be + created within the tablespace, and allows databases to be created that + have the tablespace as their default tablespace. (Note that revoking + this privilege will not alter the placement of existing objects.) + + + + + + CONNECT + + + Allows the grantee to connect to the database. This + privilege is checked at connection startup (in addition to checking + any restrictions imposed by pg_hba.conf). + + + + + + TEMPORARY + + + Allows temporary tables to be created while using the database. + + + + + + EXECUTE + + + Allows calling a function or procedure, including use of + any operators that are implemented on top of the function. This is the + only type of privilege that is applicable to functions and procedures. + + + + + + USAGE + + + For procedural languages, allows use of the language for + the creation of functions in that language. This is the only type + of privilege that is applicable to procedural languages. + + + For schemas, allows access to objects contained in the + schema (assuming that the objects' own privilege requirements are + also met). Essentially this allows the grantee to look up + objects within the schema. Without this permission, it is still + possible to see the object names, e.g. by querying system catalogs. + Also, after revoking this permission, existing sessions might have + statements that have previously performed this lookup, so this is not + a completely secure way to prevent object access. + + + For sequences, allows use of the + currval and nextval functions. + + + For types and domains, allows use of the type or domain in the + creation of tables, functions, and other schema objects. (Note that + this privilege does not control all usage of the + type, such as values of the type appearing in queries. It only + prevents objects from being created that depend on the type. The + main purpose of this privilege is controlling which users can create + dependencies on a type, which could prevent the owner from changing + the type later.) + + + For foreign-data wrappers, allows creation of new servers using the + foreign-data wrapper. + + + For foreign servers, allows creation of foreign tables using the + server. Grantees may also create, alter, or drop their own user + mappings associated with that server. + + + + + + The privileges required by other commands are listed on the + reference page of the respective command. + + + + PostgreSQL grants privileges on some types of objects to + PUBLIC by default when the objects are created. + No privileges are granted to PUBLIC by default on + tables, + table columns, + sequences, + foreign data wrappers, + foreign servers, + large objects, + schemas, + or tablespaces. + For other types of objects, the default privileges + granted to PUBLIC are as follows: + CONNECT and TEMPORARY (create + temporary tables) privileges for databases; + EXECUTE privilege for functions and procedures; and + USAGE privilege for languages and data types + (including domains). + The object owner can, of course, REVOKE + both default and expressly granted privileges. (For maximum + security, issue the REVOKE in the same transaction that + creates the object; then there is no window in which another user + can use the object.) + Also, these default privilege settings can be overridden using the + command. + + + + shows the one-letter + abbreviations that are used for these privilege types in + ACL (Access Control List) values. + You will see these letters in the output of the + commands listed below, or when looking at ACL columns of system catalogs. + + + + ACL Privilege Abbreviations + + + + Privilege + Abbreviation + Applicable Object Types + + + + + SELECT + r (read) + + LARGE OBJECT, + SEQUENCE, + TABLE (and table-like objects), + table column + + + + INSERT + a (append) + TABLE, table column + + + UPDATE + w (write) + + LARGE OBJECT, + SEQUENCE, + TABLE, + table column + + + + DELETE + d + TABLE + + + TRUNCATE + D + TABLE + + + REFERENCES + x + TABLE, table column + + + TRIGGER + t + TABLE + + + CREATE + C + + DATABASE, + SCHEMA, + TABLESPACE + + + + CONNECT + c + DATABASE + + + TEMPORARY + T + DATABASE + + + EXECUTE + X + FUNCTION, PROCEDURE + + + USAGE + U + + DOMAIN, + FOREIGN DATA WRAPPER, + FOREIGN SERVER, + LANGUAGE, + SCHEMA, + SEQUENCE, + TYPE + + + + +
+ + + summarizes the privileges + available for each type of SQL object, using the abbreviations shown + above. + It also shows the psql command + that can be used to examine privilege settings for each object type. + + + + Summary of Access Privileges + + + + Object Type + All Privileges + Default PUBLIC Privileges + psql Command + + + + + DATABASE + CTc + Tc + \l + + + DOMAIN + U + U + \dD+ + + + FUNCTION or PROCEDURE + X + X + \df+ + + + FOREIGN DATA WRAPPER + U + none + \dew+ + + + FOREIGN SERVER + U + none + \des+ + + + LANGUAGE + U + U + \dL+ + + + LARGE OBJECT + rw + none + + + + SCHEMA + UC + none + \dn+ + + + SEQUENCE + rwU + none + \dp + + + TABLE (and table-like objects) + arwdDxt + none + \dp + + + Table column + arwx + none + \dp + + + TABLESPACE + C + none + \db+ + + + TYPE + U + U + \dT+ + + + +
+ + + + aclitem + + The privileges that have been granted for a particular object are + displayed as a list of aclitem entries, where each + aclitem describes the permissions of one grantee that + have been granted by a particular grantor. For example, + calvin=r*w/hobbes specifies that the role + calvin has the privilege + SELECT (r) with grant option + (*) as well as the non-grantable + privilege UPDATE (w), both granted + by the role hobbes. If calvin + also has some privileges on the same object granted by a different + grantor, those would appear as a separate aclitem entry. + An empty grantee field in an aclitem stands + for PUBLIC. + + + + As an example, suppose that user miriam creates + table mytable and does: + +GRANT SELECT ON mytable TO PUBLIC; +GRANT SELECT, UPDATE, INSERT ON mytable TO admin; +GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw; + + Then psql's \dp command + would show: + +=> \dp mytable + Access privileges + Schema | Name | Type | Access privileges | Column privileges | Policies +--------+---------+-------+-----------------------+-----------------------+---------- + public | mytable | table | miriam=arwdDxt/miriam+| col1: +| + | | | =r/miriam +| miriam_rw=rw/miriam | + | | | admin=arw/miriam | | +(1 row) + + + + + If the Access privileges column is empty for a given + object, it means the object has default privileges (that is, its + privileges entry in the relevant system catalog is null). Default + privileges always include all privileges for the owner, and can include + some privileges for PUBLIC depending on the object + type, as explained above. The first GRANT + or REVOKE on an object will instantiate the default + privileges (producing, for + example, miriam=arwdDxt/miriam) and then modify them + per the specified request. Similarly, entries are shown in Column + privileges only for columns with nondefault privileges. + (Note: for this purpose, default privileges always means + the built-in default privileges for the object's type. An object whose + privileges have been affected by an ALTER DEFAULT + PRIVILEGES command will always be shown with an explicit + privilege entry that includes the effects of + the ALTER.) + + + + Notice that the owner's implicit grant options are not marked in the + access privileges display. A * will appear only when + grant options have been explicitly granted to someone. + @@ -1623,10 +2252,21 @@ CREATE POLICY account_managers ON accounts TO managers USING (manager = current_user); + + The policy above implicitly provides a WITH CHECK + clause identical to its USING clause, so that the + constraint applies both to rows selected by a command (so a manager + cannot SELECT, UPDATE, + or DELETE existing rows belonging to a different + manager) and to rows modified by a command (so rows belonging to a + different manager cannot be created via INSERT + or UPDATE). + + If no role is specified, or the special user name PUBLIC is used, then the policy applies to all - users on the system. To allow all users to access their own row in + users on the system. To allow all users to access only their own row in a users table, a simple policy can be used: @@ -1635,19 +2275,32 @@ CREATE POLICY user_policy ON users USING (user_name = current_user); + + This works similarly to the previous example. + + To use a different policy for rows that are being added to the table - compared to those rows that are visible, the WITH CHECK - clause can be used. This policy would allow all users to view all rows + compared to those rows that are visible, multiple policies can be + combined. This pair of policies would allow all users to view all rows in the users table, but only modify their own: -CREATE POLICY user_policy ON users - USING (true) - WITH CHECK (user_name = current_user); +CREATE POLICY user_sel_policy ON users + FOR SELECT + USING (true); +CREATE POLICY user_mod_policy ON users + USING (user_name = current_user); + + In a SELECT command, these two policies are combined + using OR, with the net effect being that all rows + can be selected. In other command types, only the second policy applies, + so that the effects are the same as before. + + Row security can also be disabled with the ALTER TABLE command. Disabling row security does not remove any policies that are @@ -2380,9 +3033,12 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC; using ALTER ROLE user SET search_path = "$user". Everyone retains the ability to create objects in the public schema, but only qualified names will - choose those objects. A user holding the CREATEROLE - privilege can undo this setting and issue arbitrary queries under the - identity of users relying on the setting. If you + choose those objects. While qualified table references are fine, calls + to functions in the public schema will be + unsafe or unreliable. Also, a user holding + the CREATEROLE privilege can undo this setting and + issue arbitrary queries under the identity of users relying on the + setting. If you create functions or extensions in the public schema or grant CREATEROLE to users not warranting this almost-superuser ability, use the first pattern instead. @@ -2393,8 +3049,10 @@ REVOKE CREATE ON SCHEMA public FROM PUBLIC; Remove the public schema from search_path in postgresql.conf. The ensuing user experience matches the previous pattern. In addition - to that pattern's implications for CREATEROLE, this - trusts database owners the same way. If you assign + to that pattern's implications for functions + and CREATEROLE, this trusts database owners + like CREATEROLE. If you create functions or + extensions in the public schema or assign the CREATEROLE privilege, CREATEDB privilege or individual database ownership to users not warranting almost-superuser access, use the @@ -2804,8 +3462,9 @@ VALUES ('Albany', NULL, NULL, 'NY'); - These deficiencies will probably be fixed in some future release, - but in the meantime considerable care is needed in deciding whether + Some functionality not implemented for inheritance hierarchies is + implemented for declarative partitioning. + Considerable care is needed in deciding whether partitioning with legacy inheritance is useful for your application.
@@ -2946,7 +3605,7 @@ VALUES ('Albany', NULL, NULL, 'NY'); divide a table into pieces called partitions. The table that is divided is referred to as a partitioned table. The specification consists of the partitioning method - and a list of columns or expressions to be used as the + and a list of columns or expressions to be used as the partition key.
@@ -2979,15 +3638,16 @@ VALUES ('Albany', NULL, NULL, 'NY'); Individual partitions are linked to the partitioned table with inheritance behind-the-scenes; however, it is not possible to use some of the - inheritance features discussed in the previous section with partitioned - tables and partitions. For example, a partition cannot have any parents - other than the partitioned table it is a partition of, nor can a regular - table inherit from a partitioned table making the latter its parent. - That means partitioned tables and partitions do not participate in - inheritance with regular tables. Since a partition hierarchy consisting - of the partitioned table and its partitions is still an inheritance - hierarchy, all the normal rules of inheritance apply as described in - with some exceptions, most notably: + generic features of inheritance (discussed below) with declaratively + partitioned tables or their partitions. For example, a partition + cannot have any parents other than the partitioned table it is a + partition of, nor can a regular table inherit from a partitioned table + making the latter its parent. That means partitioned tables and their + partitions do not participate in inheritance with regular tables. + Since a partition hierarchy consisting of the partitioned table and its + partitions is still an inheritance hierarchy, all the normal rules of + inheritance apply as described in with + some exceptions, most notably: @@ -3003,27 +3663,31 @@ VALUES ('Albany', NULL, NULL, 'NY'); Using ONLY to add or drop a constraint on only the - partitioned table is supported when there are no partitions. Once + partitioned table is supported as long as there are no partitions. Once partitions exist, using ONLY will result in an error as adding or dropping constraints on only the partitioned table, when - partitions exist, is not supported. Instead, constraints can be added - or dropped, when they are not present in the parent table, directly on - the partitions. As a partitioned table does not have any data - directly, attempts to use TRUNCATE - ONLY on a partitioned table will always return an - error. + partitions exist, is not supported. Instead, constraints on the + partitions themselves can be added and (if they are not present in the + parent table) dropped. + + + + + + As a partitioned table does not have any data directly, attempts to use + TRUNCATE ONLY on a partitioned + table will always return an error. Partitions cannot have columns that are not present in the parent. It - is neither possible to specify columns when creating partitions with - CREATE TABLE nor is it possible to add columns to + is not possible to specify columns when creating partitions with + CREATE TABLE, nor is it possible to add columns to partitions after-the-fact using ALTER TABLE. Tables may be added as a partition with ALTER TABLE ... ATTACH PARTITION - only if their columns exactly match the parent, including any - oid column. + only if their columns exactly match the parent. @@ -3044,7 +3708,7 @@ VALUES ('Albany', NULL, NULL, 'NY'); Updating the partition key of a row might cause it to be moved into a - different partition where this row satisfies its partition constraint. + different partition where this row satisfies the partition bounds. @@ -3196,7 +3860,7 @@ CREATE INDEX ON measurement (logdate); - Ensure that the + Ensure that the configuration parameter is not disabled in postgresql.conf. If it is, queries will not be optimized as desired. @@ -3292,10 +3956,49 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 the system will be able to skip the scan to validate the implicit partition constraint. Without such a constraint, the table will be scanned to validate the partition constraint while holding an - ACCESS EXCLUSIVE lock on the parent table. + ACCESS EXCLUSIVE lock on that partition + and a SHARE UPDATE EXCLUSIVE lock on the parent table. One may then drop the constraint after ATTACH PARTITION is finished, because it is no longer necessary. + + + As explained above, it is possible to create indexes on partitioned tables + and they are applied automatically to the entire hierarchy. This is very + convenient, as not only the existing partitions will become indexed, but + also any partitions that are created in the future will. One limitation is + that it's not possible to use the CONCURRENTLY + qualifier when creating such a partitioned index. To overcome long lock + times, it is possible to use CREATE INDEX ON ONLY + the partitioned table; such an index is marked invalid, and the partitions + do not get the index applied automatically. The indexes on partitions can + be created separately using CONCURRENTLY, and later + attached to the index on the parent using + ALTER INDEX .. ATTACH PARTITION. Once indexes for all + partitions are attached to the parent index, the parent index is marked + valid automatically. Example: + +CREATE INDEX measurement_usls_idx ON ONLY measurement (unitsales); + +CREATE INDEX measurement_usls_200602_idx + ON measurement_y2006m02 (unitsales); +ALTER INDEX measurement_usls_idx + ATTACH PARTITION measurement_usls_200602_idx; +... + + + This technique can be used with UNIQUE and + PRIMARY KEY constraints too; the indexes are created + implicitly when the constraint is created. Example: + +ALTER TABLE ONLY measurement ADD UNIQUE (city_id, logdate); + +ALTER TABLE measurement_y2006m02 ADD UNIQUE (city_id, logdate); +ALTER INDEX measurement_city_id_logdate_key + ATTACH PARTITION measurement_y2006m02_city_id_logdate_key; +... + + @@ -3314,37 +4017,27 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 - While primary keys are supported on partitioned tables, foreign - keys referencing partitioned tables are not supported, nor are foreign - key references from a partitioned table to some other table. + Unique constraints on partitioned tables must include all the + partition key columns. This limitation exists because + PostgreSQL can only enforce + uniqueness in each partition individually. - When an UPDATE causes a row to move from one - partition to another, there is a chance that another concurrent - UPDATE or DELETE misses this row. - Suppose session 1 is performing an UPDATE on a - partition key, and meanwhile a concurrent session 2 for which this row - is visible performs an UPDATE or - DELETE operation on this row. Session 2 can silently - miss the row if the row is deleted from the partition due to session - 1's activity. In such case, session 2's - UPDATE or DELETE, being unaware of - the row movement thinks that the row has just been deleted and concludes - that there is nothing to be done for this row. In the usual case where - the table is not partitioned, or where there is no row movement, - session 2 would have identified the newly updated row and carried out - the UPDATE/DELETE on this new row - version. + BEFORE ROW triggers, if necessary, must be defined + on individual partitions, not the partitioned table. - Row triggers, if necessary, must be defined on individual partitions, - not the partitioned table. + Mixing temporary and permanent relations in the same partition tree is + not allowed. Hence, if the partitioned table is permanent, so must be + its partitions and likewise if the partitioned table is temporary. When + using temporary relations, all members of the partition tree have to be + from the same session. @@ -3358,15 +4051,15 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 While the built-in declarative partitioning is suitable for most common use cases, there are some circumstances where a more flexible approach may be useful. Partitioning can be implemented using table - inheritance, which allows for several features which are not supported + inheritance, which allows for several features not supported by declarative partitioning, such as: - Partitioning enforces a rule that all partitions must have exactly - the same set of columns as the parent, but table inheritance allows - children to have extra columns not present in the parent. + For declarative partitioning, partitions must have exactly the same set + of columns as the partitioned table, whereas with table inheritance, + child tables may have extra columns not present in the parent. @@ -3381,8 +4074,8 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 Declarative partitioning only supports range, list and hash partitioning, whereas table inheritance allows data to be divided in a manner of the user's choosing. (Note, however, that if constraint - exclusion is unable to prune partitions effectively, query performance - will be very poor.) + exclusion is unable to prune child tables effectively, query performance + might be poor.) @@ -3404,18 +4097,18 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 We use the same measurement table we used - above. To implement it as a partitioned table using inheritance, use + above. To implement partitioning using inheritance, use the following steps: Create the master table, from which all of the - partitions will inherit. This table will contain no data. Do not + child tables will inherit. This table will contain no data. Do not define any check constraints on this table, unless you intend them - to be applied equally to all partitions. There is no point in + to be applied equally to all child tables. There is no point in defining any indexes or unique constraints on it, either. For our - example, master table is the measurement + example, the master table is the measurement table as originally defined. @@ -3425,7 +4118,7 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02 Create several child tables that each inherit from the master table. Normally, these tables will not add any columns to the set inherited from the master. Just as with declarative - partitioning, these partitions are in every way normal + partitioning, these tables are in every way normal PostgreSQL tables (or foreign tables). @@ -3443,8 +4136,8 @@ CREATE TABLE measurement_y2008m01 () INHERITS (measurement); - Add non-overlapping table constraints to the partition tables to - define the allowed key values in each partition. + Add non-overlapping table constraints to the child tables to + define the allowed key values in each. @@ -3455,18 +4148,18 @@ CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' )) CHECK ( outletID >= 100 AND outletID < 200 ) Ensure that the constraints guarantee that there is no overlap - between the key values permitted in different partitions. A common + between the key values permitted in different child tables. A common mistake is to set up range constraints like: CHECK ( outletID BETWEEN 100 AND 200 ) CHECK ( outletID BETWEEN 200 AND 300 ) - This is wrong since it is not clear which partition the key value - 200 belongs in. + This is wrong since it is not clear which child table the key + value 200 belongs in. - It would be better to instead create partitions as follows: + It would be better to instead create child tables as follows: CREATE TABLE measurement_y2006m02 ( @@ -3495,7 +4188,7 @@ CREATE TABLE measurement_y2008m01 ( - For each partition, create an index on the key column(s), + For each child table, create an index on the key column(s), as well as any other indexes you might want. CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate); @@ -3511,9 +4204,9 @@ CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate); We want our application to be able to say INSERT INTO measurement ... and have the data be redirected into the - appropriate partition table. We can arrange that by attaching + appropriate child table. We can arrange that by attaching a suitable trigger function to the master table. - If data will be added only to the latest partition, we can + If data will be added only to the latest child, we can use a very simple trigger function: @@ -3535,17 +4228,17 @@ LANGUAGE plpgsql; CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement - FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger(); + FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger(); We must redefine the trigger function each month so that it always - points to the current partition. The trigger definition does + points to the current child table. The trigger definition does not need to be updated, however. We might want to insert data and have the server automatically - locate the partition into which the row should be added. We + locate the child table into which the row should be added. We could do this with a more complex trigger function, for example: @@ -3573,7 +4266,7 @@ LANGUAGE plpgsql; The trigger definition is the same as before. Note that each IF test must exactly match the - CHECK constraint for its partition. + CHECK constraint for its child table. @@ -3584,8 +4277,8 @@ LANGUAGE plpgsql; - In practice it might be best to check the newest partition first, - if most inserts go into that partition. For simplicity we have + In practice, it might be best to check the newest child first, + if most inserts go into that child. For simplicity, we have shown the trigger's tests in the same order as in other parts of this example. @@ -3593,7 +4286,7 @@ LANGUAGE plpgsql; A different approach to redirecting inserts into the appropriate - partition table is to set up rules, instead of a trigger, on the + child table is to set up rules, instead of a trigger, on the master table. For example: @@ -3619,7 +4312,7 @@ DO INSTEAD Be aware that COPY ignores rules. If you want to use COPY to insert data, you'll need to copy into the - correct partition table rather than into the master. COPY + correct child table rather than directly into the master. COPY does fire triggers, so you can use it normally if you use the trigger approach. @@ -3635,25 +4328,25 @@ DO INSTEAD Ensure that the configuration parameter is not disabled in - postgresql.conf. - If it is, queries will not be optimized as desired. + postgresql.conf; otherwise + child tables may be accessed unnecessarily. - As we can see, a complex partitioning scheme could require a + As we can see, a complex table hierarchy could require a substantial amount of DDL. In the above example we would be creating - a new partition each month, so it might be wise to write a script that + a new child table each month, so it might be wise to write a script that generates the required DDL automatically. - Partition Maintenance + Maintenance for Inheritance Partitioning - To remove old data quickly, simply drop the partition that is no longer + To remove old data quickly, simply drop the child table that is no longer necessary: DROP TABLE measurement_y2006m02; @@ -3661,7 +4354,7 @@ DROP TABLE measurement_y2006m02; - To remove the partition from the partitioned table but retain access to + To remove the child table from the inheritance hierarchy table but retain access to it as a table in its own right: @@ -3670,8 +4363,8 @@ ALTER TABLE measurement_y2006m02 NO INHERIT measurement; - To add a new partition to handle new data, create an empty partition - just as the original partitions were created above: + To add a new child table to handle new data, create an empty child table + just as the original children were created above: CREATE TABLE measurement_y2008m02 ( @@ -3679,9 +4372,10 @@ CREATE TABLE measurement_y2008m02 ( ) INHERITS (measurement); - Alternatively, one may want to create the new table outside the partition - structure, and make it a partition after the data is loaded, checked, - and transformed. + Alternatively, one may want to create and populate the new child table + before adding it to the table hierarchy. This could allow data to be + loaded, checked, and transformed before being made visible to queries on + the parent table. CREATE TABLE measurement_y2008m02 @@ -3699,7 +4393,7 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement; Caveats - The following caveats apply to partitioned tables implemented using + The following caveats apply to partitioning implemented using inheritance: @@ -3707,19 +4401,27 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement; There is no automatic way to verify that all of the CHECK constraints are mutually exclusive. It is safer to create code that generates - partitions and creates and/or modifies associated objects than + child tables and creates and/or modifies associated objects than to write each by hand. - The schemes shown here assume that the partition key column(s) - of a row never change, or at least do not change enough to require - it to move to another partition. An UPDATE that attempts + Indexes and foreign key constraints apply to single tables and not + to their inheritance children, hence they have some + caveats to be aware of. + + + + + + The schemes shown here assume that the values of a row's key column(s) + never change, or at least do not change enough to require it to move to another partition. + An UPDATE that attempts to do that will fail because of the CHECK constraints. If you need to handle such cases, you can put suitable update triggers - on the partition tables, but it makes management of the structure + on the child tables, but it makes management of the structure much more complicated. @@ -3728,7 +4430,7 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement; If you are using manual VACUUM or ANALYZE commands, don't forget that - you need to run them on each partition individually. A command like: + you need to run them on each child table individually. A command like: ANALYZE measurement; @@ -3748,7 +4450,7 @@ ANALYZE measurement; Triggers or rules will be needed to route rows to the desired - partition, unless the application is explicitly aware of the + child table, unless the application is explicitly aware of the partitioning scheme. Triggers may be complicated to write, and will be much slower than the tuple routing performed internally by declarative partitioning. @@ -3759,112 +4461,210 @@ ANALYZE measurement;
- - Partitioning and Constraint Exclusion + + Partition Pruning - constraint exclusion + partition pruning - Constraint exclusion is a query optimization technique - that improves performance for partitioned tables defined in the - fashion described above (both declaratively partitioned tables and those - implemented using inheritance). As an example: + Partition pruning is a query optimization technique + that improves performance for declaratively partitioned tables. + As an example: -SET constraint_exclusion = on; +SET enable_partition_pruning = on; -- the default SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; - Without constraint exclusion, the above query would scan each of - the partitions of the measurement table. With constraint - exclusion enabled, the planner will examine the constraints of each - partition and try to prove that the partition need not + Without partition pruning, the above query would scan each of the + partitions of the measurement table. With + partition pruning enabled, the planner will examine the definition + of each partition and prove that the partition need not be scanned because it could not contain any rows meeting the query's WHERE clause. When the planner can prove this, it - excludes the partition from the query plan. + excludes (prunes) the partition from the query + plan. - You can use the EXPLAIN command to show the difference - between a plan with constraint_exclusion on and a plan - with it off. A typical unoptimized plan for this type of table setup is: - + By using the EXPLAIN command and the configuration parameter, it's + possible to show the difference between a plan for which partitions have + been pruned and one for which they have not. A typical unoptimized + plan for this type of table setup is: -SET constraint_exclusion = off; +SET enable_partition_pruning = off; EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; - - QUERY PLAN ------------------------------------------------------------------------------------------------ - Aggregate (cost=158.66..158.68 rows=1 width=0) - -> Append (cost=0.00..151.88 rows=2715 width=0) - -> Seq Scan on measurement (cost=0.00..30.38 rows=543 width=0) + QUERY PLAN +----------------------------------------------------------------------------------- + Aggregate (cost=188.76..188.77 rows=1 width=8) + -> Append (cost=0.00..181.05 rows=3085 width=0) + -> Seq Scan on measurement_y2006m02 (cost=0.00..33.12 rows=617 width=0) Filter: (logdate >= '2008-01-01'::date) - -> Seq Scan on measurement_y2006m02 measurement (cost=0.00..30.38 rows=543 width=0) - Filter: (logdate >= '2008-01-01'::date) - -> Seq Scan on measurement_y2006m03 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2006m03 (cost=0.00..33.12 rows=617 width=0) Filter: (logdate >= '2008-01-01'::date) ... - -> Seq Scan on measurement_y2007m12 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2007m11 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) + -> Seq Scan on measurement_y2007m12 (cost=0.00..33.12 rows=617 width=0) Filter: (logdate >= '2008-01-01'::date) - -> Seq Scan on measurement_y2008m01 measurement (cost=0.00..30.38 rows=543 width=0) + -> Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0) Filter: (logdate >= '2008-01-01'::date) Some or all of the partitions might use index scans instead of full-table sequential scans, but the point here is that there is no need to scan the older partitions at all to answer this query. - When we enable constraint exclusion, we get a significantly + When we enable partition pruning, we get a significantly cheaper plan that will deliver the same answer: - -SET constraint_exclusion = on; +SET enable_partition_pruning = on; EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Aggregate (cost=63.47..63.48 rows=1 width=0) - -> Append (cost=0.00..60.75 rows=1086 width=0) - -> Seq Scan on measurement (cost=0.00..30.38 rows=543 width=0) - Filter: (logdate >= '2008-01-01'::date) - -> Seq Scan on measurement_y2008m01 measurement (cost=0.00..30.38 rows=543 width=0) - Filter: (logdate >= '2008-01-01'::date) + QUERY PLAN +----------------------------------------------------------------------------------- + Aggregate (cost=37.75..37.76 rows=1 width=8) + -> Seq Scan on measurement_y2008m01 (cost=0.00..33.12 rows=617 width=0) + Filter: (logdate >= '2008-01-01'::date) - Note that constraint exclusion is driven only by CHECK - constraints, not by the presence of indexes. Therefore it isn't - necessary to define indexes on the key columns. Whether an index - needs to be created for a given partition depends on whether you - expect that queries that scan the partition will generally scan - a large part of the partition or just a small part. An index will - be helpful in the latter case but not the former. + Note that partition pruning is driven only by the constraints defined + implicitly by the partition keys, not by the presence of indexes. + Therefore it isn't necessary to define indexes on the key columns. + Whether an index needs to be created for a given partition depends on + whether you expect that queries that scan the partition will + generally scan a large part of the partition or just a small part. + An index will be helpful in the latter case but not the former. + + + + Partition pruning can be performed not only during the planning of a + given query, but also during its execution. This is useful as it can + allow more partitions to be pruned when clauses contain expressions + whose values are not known at query planning time, for example, + parameters defined in a PREPARE statement, using a + value obtained from a subquery, or using a parameterized value on the + inner side of a nested loop join. Partition pruning during execution + can be performed at any of the following times: + + + + + During initialization of the query plan. Partition pruning can be + performed here for parameter values which are known during the + initialization phase of execution. Partitions which are pruned + during this stage will not show up in the query's + EXPLAIN or EXPLAIN ANALYZE. + It is possible to determine the number of partitions which were + removed during this phase by observing the + Subplans Removed property in the + EXPLAIN output. + + + + + + During actual execution of the query plan. Partition pruning may + also be performed here to remove partitions using values which are + only known during actual query execution. This includes values + from subqueries and values from execution-time parameters such as + those from parameterized nested loop joins. Since the value of + these parameters may change many times during the execution of the + query, partition pruning is performed whenever one of the + execution parameters being used by partition pruning changes. + Determining if partitions were pruned during this phase requires + careful inspection of the loops property in + the EXPLAIN ANALYZE output. Subplans + corresponding to different partitions may have different values + for it depending on how many times each of them was pruned during + execution. Some may be shown as (never executed) + if they were pruned every time. + + + + + + + Partition pruning can be disabled using the + setting. + + + + + Execution-time partition pruning currently only occurs for the + Append and MergeAppend node types. + It is not yet implemented for the ModifyTable node + type, but that is likely to be changed in a future release of + PostgreSQL. + + + + + + Partitioning and Constraint Exclusion + + + constraint exclusion + + + + Constraint exclusion is a query optimization + technique similar to partition pruning. While it is primarily used + for partitioning implemented using the legacy inheritance method, it can be + used for other purposes, including with declarative partitioning. + + + + Constraint exclusion works in a very similar way to partition + pruning, except that it uses each table's CHECK + constraints — which gives it its name — whereas partition + pruning uses the table's partition bounds, which exist only in the + case of declarative partitioning. Another difference is that + constraint exclusion is only applied at plan time; there is no attempt + to remove partitions at execution time. + + + + The fact that constraint exclusion uses CHECK + constraints, which makes it slow compared to partition pruning, can + sometimes be used as an advantage: because constraints can be defined + even on declaratively-partitioned tables, in addition to their internal + partition bounds, constraint exclusion may be able + to elide additional partitions from the query plan. The default (and recommended) setting of - is actually neither + is neither on nor off, but an intermediate setting called partition, which causes the technique to be - applied only to queries that are likely to be working on partitioned + applied only to queries that are likely to be working on inheritance partitioned tables. The on setting causes the planner to examine CHECK constraints in all queries, even simple ones that are unlikely to benefit. - The following caveats apply to constraint exclusion, which is used by - both inheritance and partitioned tables: + The following caveats apply to constraint exclusion: + + + Constraint exclusion is only applied during query planning, unlike + partition pruning, which can also be applied during query execution. + + + Constraint exclusion only works when the query's WHERE clause contains constants (or externally supplied parameters). For example, a comparison against a non-immutable function such as CURRENT_TIMESTAMP cannot be optimized, since the - planner cannot know which partition the function value might fall + planner cannot know which child table the function's value might fall into at run time. @@ -3872,32 +4672,110 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01'; Keep the partitioning constraints simple, else the planner may not be - able to prove that partitions don't need to be visited. Use simple + able to prove that child tables might not need to be visited. Use simple equality conditions for list partitioning, or simple range tests for range partitioning, as illustrated in the preceding examples. A good rule of thumb is that partitioning constraints should contain only comparisons of the partitioning column(s) to constants - using B-tree-indexable operators, which applies even to partitioned - tables, because only B-tree-indexable column(s) are allowed in the - partition key. (This is not a problem when using declarative - partitioning, since the automatically generated constraints are simple - enough to be understood by the planner.) + using B-tree-indexable operators, because only B-tree-indexable + column(s) are allowed in the partition key. - All constraints on all partitions of the master table are examined - during constraint exclusion, so large numbers of partitions are likely - to increase query planning time considerably. Partitioning using - these techniques will work well with up to perhaps a hundred partitions; - don't try to use many thousands of partitions. + All constraints on all children of the parent table are examined + during constraint exclusion, so large numbers of children are likely + to increase query planning time considerably. So the legacy + inheritance based partitioning will work well with up to perhaps a + hundred child tables; don't try to use many thousands of children. + + + Declarative Partitioning Best Practices + + + The choice of how to partition a table should be made carefully as the + performance of query planning and execution can be negatively affected by + poor design. + + + + One of the most critical design decisions will be the column or columns + by which you partition your data. Often the best choice will be to + partition by the column or set of columns which most commonly appear in + WHERE clauses of queries being executed on the + partitioned table. WHERE clause items that match and + are compatible with the partition key can be used to prune unneeded + partitions. However, you may be forced into making other decisions by + requirements for the PRIMARY KEY or a + UNIQUE constraint. Removal of unwanted data is also a + factor to consider when planning your partitioning strategy. An entire + partition can be detached fairly quickly, so it may be beneficial to + design the partition strategy in such a way that all data to be removed + at once is located in a single partition. + + + + Choosing the target number of partitions that the table should be divided + into is also a critical decision to make. Not having enough partitions + may mean that indexes remain too large and that data locality remains poor + which could result in low cache hit ratios. However, dividing the table + into too many partitions can also cause issues. Too many partitions can + mean longer query planning times and higher memory consumption during both + query planning and execution. When choosing how to partition your table, + it's also important to consider what changes may occur in the future. For + example, if you choose to have one partition per customer and you + currently have a small number of large customers, consider the + implications if in several years you instead find yourself with a large + number of small customers. In this case, it may be better to choose to + partition by HASH and choose a reasonable number of + partitions rather than trying to partition by LIST and + hoping that the number of customers does not increase beyond what it is + practical to partition the data by. + + + + Sub-partitioning can be useful to further divide partitions that are + expected to become larger than other partitions, although excessive + sub-partitioning can easily lead to large numbers of partitions and can + cause the same problems mentioned in the preceding paragraph. + + + + It is also important to consider the overhead of partitioning during + query planning and execution. The query planner is generally able to + handle partition hierarchies with up to a few thousand partitions fairly + well, provided that typical queries allow the query planner to prune all + but a small number of partitions. Planning times become longer and memory + consumption becomes higher when more partitions remain after the planner + performs partition pruning. This is particularly true for the + UPDATE and DELETE commands. Another + reason to be concerned about having a large number of partitions is that + the server's memory consumption may grow significantly over a period of + time, especially if many sessions touch large numbers of partitions. + That's because each partition requires its metadata to be loaded into the + local memory of each session that touches it. + + + + With data warehouse type workloads, it can make sense to use a larger + number of partitions than with an OLTP type workload. + Generally, in data warehouses, query planning time is less of a concern as + the majority of processing time is spent during query execution. With + either of these two types of workload, it is important to make the right + decisions early, as re-partitioning large quantities of data can be + painfully slow. Simulations of the intended workload are often beneficial + for optimizing the partitioning strategy. Never assume that more + partitions are better than fewer partitions and vice-versa. + + + diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml index dfefa9e686c..a87e47a104d 100644 --- a/doc/src/sgml/dfunc.sgml +++ b/doc/src/sgml/dfunc.sgml @@ -1,7 +1,7 @@ - Compiling and Linking Dynamically-loaded Functions + Compiling and Linking Dynamically-Loaded Functions Before you are able to use your diff --git a/doc/src/sgml/diskusage.sgml b/doc/src/sgml/diskusage.sgml index 3708e5f3d8b..75467582e48 100644 --- a/doc/src/sgml/diskusage.sgml +++ b/doc/src/sgml/diskusage.sgml @@ -87,9 +87,9 @@ WHERE c.relname = 'customer' AND c2.oid = i.indexrelid ORDER BY c2.relname; - relname | relpages -----------------------+---------- - customer_id_indexdex | 26 + relname | relpages +-------------------+---------- + customer_id_index | 26 diff --git a/doc/src/sgml/dml.sgml b/doc/src/sgml/dml.sgml index 1e05c84fd17..97a77309554 100644 --- a/doc/src/sgml/dml.sgml +++ b/doc/src/sgml/dml.sgml @@ -112,7 +112,7 @@ INSERT INTO products (product_no, name, price) - When inserting a lot of data at the same time, considering using + When inserting a lot of data at the same time, consider using the command. It is not as flexible as the command, but is more efficient. Refer diff --git a/doc/src/sgml/docguide.sgml b/doc/src/sgml/docguide.sgml index b4338e0e73d..c99198f5e5c 100644 --- a/doc/src/sgml/docguide.sgml +++ b/doc/src/sgml/docguide.sgml @@ -57,13 +57,13 @@ structure and content of a technical document without worrying about presentation details. A document style defines how that content is rendered into one of several final forms. DocBook is - maintained by the - OASIS group. The + maintained by the + OASIS group. The official DocBook site has good introductory and reference documentation and a complete O'Reilly book for your online reading pleasure. The NewbieDoc Docbook Guide is very helpful for beginners. - The + The FreeBSD Documentation Project also uses DocBook and has some good information, including a number of style guidelines that might be worth considering. @@ -80,11 +80,11 @@ - DocBook DTD + DocBook DTD This is the definition of DocBook itself. We currently use version - 4.2; you cannot use later or earlier versions. You need + 4.5; you cannot use later or earlier versions. You need the XML variant of the DocBook DTD, not the SGML variant. @@ -187,12 +187,6 @@ pkg install docbook-xml docbook-xsl fop libxslt directory you'll need to use gmake, because the makefile provided is not suitable for FreeBSD's make. - - - More information about the FreeBSD documentation tools can be - found in the - FreeBSD Documentation Project's instructions. - @@ -220,7 +214,7 @@ apt-get install docbook-xml docbook-xsl fop libxml2-utils xsltproc If you use MacPorts, the following will get you set up: -sudo port install docbook-xml-4.2 docbook-xsl fop +sudo port install docbook-xml-4.5 docbook-xsl fop If you use Homebrew, use this: @@ -240,7 +234,7 @@ brew install docbook docbook-xsl fop like this: checking for xmllint... xmllint -checking for DocBook XML V4.2... yes +checking for DocBook XML V4.5... yes checking for dbtoepub... dbtoepub checking for xsltproc... xsltproc checking for fop... fop @@ -253,7 +247,7 @@ checking for fop... fop - Building The Documentation + Building the Documentation Once you have everything set up, change to the directory @@ -276,7 +270,7 @@ checking for fop... fop To produce HTML documentation with the stylesheet used on postgresql.org instead of the + url="https://www.postgresql.org/docs/current/">postgresql.org
instead of the default simple style use: doc/src/sgml$ make STYLE=website html @@ -364,7 +358,9 @@ ADDITIONAL_FLAGS='-Xmx1500m' corresponds to , with some minor changes to account for the different context. To recreate the file, change to the directory doc/src/sgml - and enter make INSTALL. + and enter make INSTALL. Building text output + requires Pandoc version 1.13 or newer as an + additional build tool. @@ -393,112 +389,36 @@ ADDITIONAL_FLAGS='-Xmx1500m' Documentation Authoring - SGML and DocBook do - not suffer from an oversupply of open-source authoring tools. The - most common tool set is the - Emacs/XEmacs - editor with appropriate editing mode. On some systems - these tools are provided in a typical full installation. + The documentation sources are most conveniently modified with an editor + that has a mode for editing XML, and even more so if it has some awareness + of XML schema languages so that it can know about + DocBook syntax specifically. - - Emacs/PSGML - - - PSGML is the most common and most - powerful mode for editing SGML documents. - When properly configured, it will allow you to use - Emacs to insert tags and check markup - consistency. You could use it for HTML as - well. Check the - PSGML web site for downloads, installation instructions, and - detailed documentation. - - - - There is one important thing to note with - PSGML: its author assumed that your - main SGML DTD directory - would be /usr/local/lib/sgml. If, as in the - examples in this chapter, you use - /usr/local/share/sgml, you have to - compensate for this, either by setting - SGML_CATALOG_FILES environment variable, or you - can customize your PSGML installation - (its manual tells you how). - - - - Put the following in your ~/.emacs - environment file (adjusting the path names to be appropriate for - your system): - - -; ********** for SGML mode (psgml) - -(setq sgml-omittag t) -(setq sgml-shorttag t) -(setq sgml-minimize-attributes nil) -(setq sgml-always-quote-attributes t) -(setq sgml-indent-step 1) -(setq sgml-indent-data t) -(setq sgml-parent-document nil) -(setq sgml-exposed-tags nil) -(setq sgml-catalog-files '("/usr/local/share/sgml/catalog")) - -(autoload 'sgml-mode "psgml" "Major mode to edit SGML files." t ) - - - and in the same file add an entry for SGML - into the (existing) definition for - auto-mode-alist: - -(setq - auto-mode-alist - '(("\\.sgml$" . sgml-mode) - )) - - - - - You might find that when using PSGML, a - comfortable way of working with these separate files of book - parts is to insert a proper DOCTYPE - declaration while you're editing them. If you are working on - this source, for instance, it is an appendix chapter, so you - would specify the document as an appendix instance - of a DocBook document by making the first line look like this: - - -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook V4.2//EN"> - - - This means that anything and everything that reads - SGML will get it right, and I can verify the - document with nsgmls -s docguide.sgml. (But - you need to take out that line before building the entire - documentation set.) - - + + Note that for historical reasons the documentation source files are named + with an extension .sgml even though they are now XML + files. So you might need to adjust your editor configuration to set the + correct mode. + - Other Emacs Modes + Emacs - GNU Emacs ships with a different - SGML mode, which is not quite as powerful as - PSGML, but it's less confusing and - lighter weight. Also, it offers syntax highlighting (font lock), - which can be very helpful. - src/tools/editors/emacs.samples contains - sample settings for this mode. + nXML Mode, which ships with + Emacs, is the most common mode for editing + XML documents with Emacs. + It will allow you to use Emacs to insert tags + and check markup consistency, and it supports + DocBook out of the box. Check the + nXML manual for detailed documentation. - Norm Walsh offers a - major mode - specifically for DocBook which also has font-lock and a number of features to - reduce typing. + src/tools/editors/emacs.samples contains + recommended settings for this mode. diff --git a/doc/src/sgml/earthdistance.sgml b/doc/src/sgml/earthdistance.sgml index 1f3ea6aa6e2..670fc9955f7 100644 --- a/doc/src/sgml/earthdistance.sgml +++ b/doc/src/sgml/earthdistance.sgml @@ -24,7 +24,7 @@ - Cube-based Earth Distances + Cube-Based Earth Distances Data is stored in cubes that are points (both corners are the same) using 3 @@ -60,7 +60,7 @@ - Cube-based Earthdistance Functions + Cube-Based Earthdistance Functions @@ -137,7 +137,7 @@ - Point-based Earth Distances + Point-Based Earth Distances The second part of the module relies on representing Earth locations as @@ -154,7 +154,7 @@
- Point-based Earthdistance Operators + Point-Based Earthdistance Operators diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index 98b68405207..d225eb3c20d 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -177,6 +177,19 @@ EXEC SQL CONNECT TO target AS SQL string literal, or a reference to a character variable. + + If the connection target includes any options, + those consist of + keyword=value + specifications separated by ampersands (&). + The allowed key words are the same ones recognized + by libpq (see + ). Spaces are ignored before + any keyword or value, + though not within or after one. Note that there is no way to + write & within a value. + + The connection-name is used to handle multiple connections in one program. It can be omitted if a @@ -191,7 +204,7 @@ EXEC SQL CONNECT TO target AS secure schema usage pattern, begin each session by removing publicly-writable schemas from search_path. For example, - add options=-csearch_path= + add options=-c search_path= to options, or issue EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); after connecting. This consideration is not specific to @@ -547,7 +560,7 @@ EXEC SQL COMMIT; - + EXEC SQL SET AUTOCOMMIT TO ON @@ -651,7 +664,7 @@ EXEC SQL DEALLOCATE PREPARE name; not really useful in real applications. This section explains in detail how you can pass data between your C program and the embedded SQL statements using a simple mechanism called - host variables. In an embedded SQL program we + host variables. In an embedded SQL program we consider the SQL statements to be guests in the C program code which is the host language. Therefore the variables of the C program are called host @@ -906,7 +919,7 @@ do character(n), varchar(n), text - char[n+1], VARCHAR[n+1]declared in ecpglib.h + char[n+1], VARCHAR[n+1] @@ -936,7 +949,7 @@ do bytea - char * + char *, bytea[n] @@ -1193,6 +1206,36 @@ EXEC SQL END DECLARE SECTION; + + + bytea + + + The handling of the bytea type is similar to + that of VARCHAR. The definition on an array of type + bytea is converted into a named struct for every + variable. A declaration like: + +bytea var[180]; + + is converted into: + +struct bytea_var { int len; char arr[180]; } var; + + The member arr hosts binary format + data. It can also handle '\0' as part of + data, unlike VARCHAR. + The data is converted from/to hex format and sent/received by + ecpglib. + + + + + bytea variable can be used only when + is set to hex. + + + @@ -1666,7 +1709,7 @@ while (1) - User-defined Base Types + User-Defined Base Types New user-defined base types are not directly supported by ECPG. @@ -1678,7 +1721,7 @@ while (1) Here is an example using the data type complex from the example in . The external string - representation of that type is (%lf,%lf), + representation of that type is (%f,%f), which is defined in the functions complex_in() and complex_out() functions @@ -1951,11 +1994,23 @@ EXEC SQL SELECT started, duration INTO :ts1, :iv1 FROM datetbl WHERE d=:date1; PGTYPEStimestamp_add_interval(&ts1, &iv1, &tsout); out = PGTYPEStimestamp_to_asc(&tsout); printf("Started + duration: %s\n", out); -free(out); +PGTYPESchar_free(out); ]]> + + Character Strings + + Some functions such as PGTYPESnumeric_to_asc return + a pointer to a freshly allocated character string. These results should be + freed with PGTYPESchar_free instead of + free. (This is important only on Windows, where + memory allocation and release sometimes need to be done by the same + library.) + + + The numeric Type @@ -2029,6 +2084,7 @@ char *PGTYPESnumeric_to_asc(numeric *num, int dscale); The numeric value will be printed with dscale decimal digits, with rounding applied if necessary. + The result must be freed with PGTYPESchar_free(). @@ -2419,6 +2475,7 @@ char *PGTYPESdate_to_asc(date dDate); The function receives the date dDate as its only parameter. It will output the date in the form 1999-01-18, i.e., in the YYYY-MM-DD format. + The result must be freed with PGTYPESchar_free(). @@ -2841,6 +2898,7 @@ char *PGTYPEStimestamp_to_asc(timestamp tstamp); The function receives the timestamp tstamp as its only argument and returns an allocated string that contains the textual representation of the timestamp. + The result must be freed with PGTYPESchar_free(). @@ -3349,6 +3407,7 @@ char *PGTYPESinterval_to_asc(interval *span); The function converts the interval variable that span points to into a C char*. The output looks like this example: @ 1 day 12 hours 59 mins 10 secs. + The result must be freed with PGTYPESchar_free(). @@ -4788,7 +4847,7 @@ EXEC SQL WHENEVER condition action Execute the C statement continue. This should - only be used in loops statements. if executed, will cause the flow + only be used in loops statements. if executed, will cause the flow of control to return to the top of the loop. @@ -4954,7 +5013,7 @@ struct The fields sqlcaid, - sqlcabc, + sqlabc, sqlerrp, and the remaining elements of sqlerrd and sqlwarn currently contain no useful @@ -5858,7 +5917,7 @@ ECPG = ecpg ECPGtransactionStatus(const char *connection_name) returns the current transaction status of the given connection identified by connection_name. - See and libpq's PQtransactionStatus() for details about the returned status codes. + See and libpq's for details about the returned status codes. @@ -6442,7 +6501,7 @@ DATABASE connection_target - connection_object + connection_name An optional identifier for the connection, so that it can be @@ -8182,7 +8241,7 @@ if (*(int2 *)sqldata->sqlvar[i].sqlind != 0) sqlformat - Reserved in Informix, value of PQfformat() for the field. + Reserved in Informix, value of for the field. @@ -8211,7 +8270,7 @@ if (*(int2 *)sqldata->sqlvar[i].sqlind != 0) sqlxid - Extended type of the field, result of PQftype(). + Extended type of the field, result of . diff --git a/doc/src/sgml/event-trigger.sgml b/doc/src/sgml/event-trigger.sgml index 0a8860490ad..18628c498ba 100644 --- a/doc/src/sgml/event-trigger.sgml +++ b/doc/src/sgml/event-trigger.sgml @@ -175,6 +175,14 @@ - + + ALTER DEFAULT PRIVILEGES + X + X + - + - + + ALTER EXTENSION X @@ -215,6 +223,22 @@ - + + ALTER LARGE OBJECT + X + X + - + - + + + + ALTER MATERIALIZED VIEW + X + X + - + - + + ALTER OPERATOR X @@ -247,6 +271,22 @@ - + + ALTER PROCEDURE + X + X + - + - + + + + ALTER PUBLICATION + X + X + - + - + + ALTER SCHEMA X @@ -271,6 +311,22 @@ - + + ALTER STATISTICS + X + X + - + - + + + + ALTER SUBSCRIPTION + X + X + - + - + + ALTER TABLE X @@ -344,7 +400,15 @@ - CREATE AGGREGATE + COMMENT + X + X + - + - + Only for local objects + + + CREATE ACCESS METHOD X X - @@ -352,12 +416,12 @@ - COMMENT + CREATE AGGREGATE X X - - - Only for local objects + CREATE CAST @@ -439,6 +503,14 @@ - + + CREATE MATERIALIZED VIEW + X + X + - + - + + CREATE OPERATOR X @@ -471,6 +543,22 @@ - + + CREATE PROCEDURE + X + X + - + - + + + + CREATE PUBLICATION + X + X + - + - + + CREATE RULE X @@ -511,6 +599,14 @@ - + + CREATE SUBSCRIPTION + X + X + - + - + + CREATE TABLE X @@ -591,6 +687,14 @@ - + + DROP ACCESS METHOD + X + X + X + - + + DROP AGGREGATE X @@ -679,6 +783,14 @@ - + + DROP MATERIALIZED VIEW + X + X + X + - + + DROP OPERATOR X @@ -719,6 +831,22 @@ - + + DROP PROCEDURE + X + X + X + - + + + + DROP PUBLICATION + X + X + X + - + + DROP RULE X @@ -759,6 +887,14 @@ - + + DROP SUBSCRIPTION + X + X + X + - + + DROP TABLE X @@ -847,6 +983,14 @@ - + + REFRESH MATERIALIZED VIEW + X + X + - + - + + REVOKE X @@ -1044,7 +1188,7 @@ CREATE FUNCTION noddl() RETURNS event_trigger AS 'noddl' LANGUAGE C; CREATE EVENT TRIGGER noddl ON ddl_command_start - EXECUTE PROCEDURE noddl(); + EXECUTE FUNCTION noddl(); @@ -1053,9 +1197,9 @@ CREATE EVENT TRIGGER noddl ON ddl_command_start =# \dy List of event triggers - Name | Event | Owner | Enabled | Procedure | Tags --------+-------------------+-------+---------+-----------+------ - noddl | ddl_command_start | dim | enabled | noddl | + Name | Event | Owner | Enabled | Function | Tags +-------+-------------------+-------+---------+----------+------ + noddl | ddl_command_start | dim | enabled | noddl | (1 row) =# CREATE TABLE foo(id serial); @@ -1129,7 +1273,7 @@ $$; CREATE EVENT TRIGGER no_rewrite_allowed ON table_rewrite - EXECUTE PROCEDURE no_rewrite(); + EXECUTE FUNCTION no_rewrite(); diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml index 348ae71423f..8dc2b893f7e 100644 --- a/doc/src/sgml/extend.sgml +++ b/doc/src/sgml/extend.sgml @@ -953,7 +953,7 @@ SELECT * FROM pg_extension_update_paths('extension_name - Installing Extensions using Update Scripts + Installing Extensions Using Update Scripts An extension that has been around for awhile will probably exist in @@ -1015,7 +1015,7 @@ CREATE TYPE pair AS ( k text, v text ); CREATE OR REPLACE FUNCTION pair(text, text) RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;'; -CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, PROCEDURE = pair); +CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair); -- "SET search_path" is easy to get right, but qualified names perform better. CREATE OR REPLACE FUNCTION lower(pair) @@ -1100,13 +1100,15 @@ include $(PGXS) and include the global PGXS makefile. Here is an example that builds an extension module named isbn_issn, consisting of a shared library containing - some C code, an extension control file, a SQL script, and a documentation - text file: + some C code, an extension control file, a SQL script, an include file + (only needed if other modules might need to access the extension functions + without going via SQL), and a documentation text file: MODULES = isbn_issn EXTENSION = isbn_issn DATA = isbn_issn--1.0.sql DOCS = README.isbn_issn +HEADERS_isbn_issn = isbn_issn.h PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) @@ -1220,6 +1222,48 @@ include $(PGXS) + + HEADERS + HEADERS_built + + + Files to (optionally build and) install under + prefix/include/server/$MODULEDIR/$MODULE_big. + + + Unlike DATA_built, files in HEADERS_built + are not removed by the clean target; if you want them removed, + also add them to EXTRA_CLEAN or add your own rules to do it. + + + + + + HEADERS_$MODULE + HEADERS_built_$MODULE + + + Files to install (after building if specified) under + prefix/include/server/$MODULEDIR/$MODULE, + where $MODULE must be a module name used + in MODULES or MODULE_big. + + + Unlike DATA_built, files in HEADERS_built_$MODULE + are not removed by the clean target; if you want them removed, + also add them to EXTRA_CLEAN or add your own rules to do it. + + + It is legal to use both variables for the same module, or any + combination, unless you have two module names in the + MODULES list that differ only by the presence of a + prefix built_, which would cause ambiguity. In + that (hopefully unlikely) case, you should use only the + HEADERS_built_$MODULE variables. + + + + SCRIPTS @@ -1259,6 +1303,34 @@ include $(PGXS) + + ISOLATION + + + list of isolation test cases, see below for more details + + + + + + ISOLATION_OPTS + + + additional switches to pass to + pg_isolation_regress + + + + + + TAP_TESTS + + + switch defining if TAP tests need to be run, see below + + + + NO_INSTALLCHECK @@ -1281,7 +1353,34 @@ include $(PGXS) PG_CPPFLAGS - will be added to CPPFLAGS + will be prepended to CPPFLAGS + + + + + + PG_CFLAGS + + + will be appended to CFLAGS + + + + + + PG_CXXFLAGS + + + will be appended to CXXFLAGS + + + + + + PG_LDFLAGS + + + will be prepended to LDFLAGS @@ -1379,13 +1478,42 @@ make VPATH=/path/to/extension/source/tree install have all expected files. + + The scripts listed in the ISOLATION variable are used + for tests stressing behavior of concurrent session with your module, which + can be invoked by make installcheck after doing + make install. For this to work you must have a + running PostgreSQL server. The script files + listed in ISOLATION must appear in a subdirectory + named specs/ in your extension's directory. These files + must have extension .spec, which must not be included + in the ISOLATION list in the makefile. For each test + there should also be a file containing the expected output in a + subdirectory named expected/, with the same stem and + extension .out. make installcheck + executes each test script, and compares the resulting output to the + matching expected file. Any differences will be written to the file + output_iso/regression.diffs in + diff -c format. Note that trying to run a test that is + missing its expected file will be reported as trouble, so + make sure you have all expected files. + + + + TAP_TESTS enables the use of TAP tests. Data from each + run is present in a subdirectory named tmp_check/. + See also for more details. + + The easiest way to create the expected files is to create empty files, then do a test run (which will of course report differences). Inspect the actual result files found in the results/ - directory, then copy them to expected/ if they match - what you expect from the test. + directory (for tests in REGRESS), or + output_iso/results/ directory (for tests in + ISOLATION), then copy them to + expected/ if they match what you expect from the test. diff --git a/doc/src/sgml/external-projects.sgml b/doc/src/sgml/external-projects.sgml index 89147817ec1..f94e450ef9e 100644 --- a/doc/src/sgml/external-projects.sgml +++ b/doc/src/sgml/external-projects.sgml @@ -65,7 +65,7 @@ DBD::Pg Perl Perl DBI driver - + @@ -78,7 +78,7 @@ libpqxx C++ - New-style C++ interface + C++ interface @@ -107,7 +107,7 @@ pgtclng Tcl - + @@ -146,7 +146,7 @@ There are several administration tools available for PostgreSQL. The most popular is - pgAdmin III, + pgAdmin, and there are several commercially available ones as well. @@ -205,7 +205,7 @@ PL/R R - + diff --git a/doc/src/sgml/fdwhandler.sgml b/doc/src/sgml/fdwhandler.sgml index 7b758bdf09b..6587678af2b 100644 --- a/doc/src/sgml/fdwhandler.sgml +++ b/doc/src/sgml/fdwhandler.sgml @@ -1,7 +1,7 @@ - Writing A Foreign Data Wrapper + Writing a Foreign Data Wrapper foreign data wrapper @@ -96,7 +96,7 @@ - FDW Routines For Scanning Foreign Tables + FDW Routines for Scanning Foreign Tables @@ -286,7 +286,7 @@ EndForeignScan(ForeignScanState *node); - FDW Routines For Scanning Foreign Joins + FDW Routines for Scanning Foreign Joins If an FDW supports performing foreign joins remotely (rather than @@ -309,7 +309,9 @@ GetForeignJoinPaths(PlannerInfo *root, function is called during query planning. As with GetForeignPaths, this function should generate ForeignPath path(s) for the - supplied joinrel, and call add_path to add these + supplied joinrel + (use create_foreign_join_path to build them), + and call add_path to add these paths to the set of paths considered for the join. But unlike GetForeignPaths, it is not necessary that this function succeed in creating at least one path, since paths involving local @@ -346,7 +348,7 @@ GetForeignJoinPaths(PlannerInfo *root, - FDW Routines For Planning Post-Scan/Join Processing + FDW Routines for Planning Post-Scan/Join Processing If an FDW supports performing remote post-scan/join processing, such as @@ -369,7 +371,9 @@ GetForeignUpperPaths(PlannerInfo *root, called only if all base relation(s) involved in the query belong to the same FDW. This function should generate ForeignPath path(s) for any post-scan/join processing that the FDW knows how to - perform remotely, and call add_path to add these paths to + perform remotely + (use create_foreign_upper_path to build them), + and call add_path to add these paths to the indicated upper relation. As with GetForeignJoinPaths, it is not necessary that this function succeed in creating any paths, since paths involving local processing are always possible. @@ -383,7 +387,9 @@ GetForeignUpperPaths(PlannerInfo *root, step. The extra parameter provides additional details, currently, it is set only for UPPERREL_PARTIAL_GROUP_AGG or UPPERREL_GROUP_AGG, in which case it points to a - GroupPathExtraData structure. + GroupPathExtraData structure; + or for UPPERREL_FINAL, in which case it points to a + FinalPathExtraData structure. (Note that ForeignPath paths added to output_rel would typically not have any direct dependency on paths of the input_rel, since their processing is expected @@ -398,7 +404,7 @@ GetForeignUpperPaths(PlannerInfo *root, - FDW Routines For Updating Foreign Tables + FDW Routines for Updating Foreign Tables If an FDW supports writable foreign tables, it should provide @@ -573,12 +579,14 @@ ExecForeignInsert(EState *estate, The data in the returned slot is used only if the INSERT - query has a RETURNING clause or the foreign table has - an AFTER ROW trigger. Triggers require all columns, but the - FDW could choose to optimize away returning some or all columns depending - on the contents of the RETURNING clause. Regardless, some - slot must be returned to indicate success, or the query's reported row - count will be wrong. + statement has a RETURNING clause or involves a view + WITH CHECK OPTION; or if the foreign table has + an AFTER ROW trigger. Triggers require all columns, + but the FDW could choose to optimize away returning some or all columns + depending on the contents of the RETURNING clause or + WITH CHECK OPTION constraints. Regardless, some slot + must be returned to indicate success, or the query's reported row count + will be wrong. @@ -587,6 +595,14 @@ ExecForeignInsert(EState *estate, with an error message. + + Note that this function is also called when inserting routed tuples into + a foreign-table partition or executing COPY FROM on + a foreign table, in which case it is called in a different way than it + is in the INSERT case. See the callback functions + described below that allow the FDW to support that. + + TupleTableSlot * @@ -619,12 +635,14 @@ ExecForeignUpdate(EState *estate, The data in the returned slot is used only if the UPDATE - query has a RETURNING clause or the foreign table has - an AFTER ROW trigger. Triggers require all columns, but the - FDW could choose to optimize away returning some or all columns depending - on the contents of the RETURNING clause. Regardless, some - slot must be returned to indicate success, or the query's reported row - count will be wrong. + statement has a RETURNING clause or involves a view + WITH CHECK OPTION; or if the foreign table has + an AFTER ROW trigger. Triggers require all columns, + but the FDW could choose to optimize away returning some or all columns + depending on the contents of the RETURNING clause or + WITH CHECK OPTION constraints. Regardless, some slot + must be returned to indicate success, or the query's reported row count + will be wrong. @@ -743,6 +761,13 @@ BeginForeignInsert(ModifyTableState *mtstate, NULL, no action is taken for the initialization. + + Note that if the FDW does not support routable foreign-table partitions + and/or executing COPY FROM on foreign tables, this + function or ExecForeignInsert subsequently called + must throw error as needed. + + void @@ -795,9 +820,11 @@ IsForeignRelUpdatable(Relation rel); row-by-row approach is necessary, but it can be inefficient. If it is possible for the foreign server to determine which rows should be modified without actually retrieving them, and if there are no local - triggers which would affect the operation, then it is possible to - arrange things so that the entire operation is performed on the remote - server. The interfaces described below make this possible. + structures which would affect the operation (row-level local triggers, + stored generated columns, or WITH CHECK OPTION + constraints from parent views), then it is possible to arrange things + so that the entire operation is performed on the remote server. The + interfaces described below make this possible. @@ -942,7 +969,7 @@ EndDirectModify(ForeignScanState *node); - FDW Routines For Row Locking + FDW Routines for Row Locking If an FDW wishes to support late row locking (as described @@ -984,29 +1011,31 @@ GetForeignRowMarkType(RangeTblEntry *rte, -HeapTuple +void RefetchForeignRow(EState *estate, ExecRowMark *erm, Datum rowid, + TupleTableSlot *slot, bool *updated); - Re-fetch one tuple from the foreign table, after locking it if required. + Re-fetch one tuple slot from the foreign table, after locking it if required. estate is global execution state for the query. erm is the ExecRowMark struct describing the target foreign table and the row lock type (if any) to acquire. rowid identifies the tuple to be fetched. - updated is an output parameter. + slot contains nothing useful upon call, but can be used to + hold the returned tuple. updated is an output parameter. - This function should return a palloc'ed copy of the fetched tuple, - or NULL if the row lock couldn't be obtained. The row lock - type to acquire is defined by erm->markType, which is the - value previously returned by GetForeignRowMarkType. - (ROW_MARK_REFERENCE means to just re-fetch the tuple without - acquiring any lock, and ROW_MARK_COPY will never be seen by - this routine.) + This function should store the tuple into the provided slot, or clear it if + the row lock couldn't be obtained. The row lock type to acquire is + defined by erm->markType, which is the value + previously returned by GetForeignRowMarkType. + (ROW_MARK_REFERENCE means to just re-fetch the tuple + without acquiring any lock, and ROW_MARK_COPY will + never be seen by this routine.) @@ -1018,7 +1047,7 @@ RefetchForeignRow(EState *estate, Note that by default, failure to acquire a row lock should result in - raising an error; a NULL return is only appropriate if + raising an error; returning with an empty slot is only appropriate if the SKIP LOCKED option is specified by erm->waitPolicy. @@ -1204,7 +1233,7 @@ AcquireSampleRowsFunc(Relation relation, - FDW Routines For <command>IMPORT FOREIGN SCHEMA</command> + FDW Routines for <command>IMPORT FOREIGN SCHEMA</command> @@ -1367,7 +1396,7 @@ ShutdownForeignScan(ForeignScanState *node); - FDW Routines For reparameterization of paths + FDW Routines for Reparameterization of Paths @@ -1404,6 +1433,23 @@ ReparameterizeForeignPathByChild(PlannerInfo *root, List *fdw_private, ForeignDataWrapper * +GetForeignDataWrapperExtended(Oid fdwid, bits16 flags); + + + This function returns a ForeignDataWrapper + object for the foreign-data wrapper with the given OID. A + ForeignDataWrapper object contains properties + of the FDW (see foreign/foreign.h for details). + flags is a bitwise-or'd bit mask indicating + an extra set of options. It can take the value + FDW_MISSING_OK, in which case a NULL + result is returned to the caller instead of an error for an undefined + object. + + + + +ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid); @@ -1416,6 +1462,23 @@ GetForeignDataWrapper(Oid fdwid); ForeignServer * +GetForeignServerExtended(Oid serverid, bits16 flags); + + + This function returns a ForeignServer object + for the foreign server with the given OID. A + ForeignServer object contains properties + of the server (see foreign/foreign.h for details). + flags is a bitwise-or'd bit mask indicating + an extra set of options. It can take the value + FSV_MISSING_OK, in which case a NULL + result is returned to the caller instead of an error for an undefined + object. + + + + +ForeignServer * GetForeignServer(Oid serverid); diff --git a/doc/src/sgml/features.sgml b/doc/src/sgml/features.sgml index 6c22d698673..f767bee46e5 100644 --- a/doc/src/sgml/features.sgml +++ b/doc/src/sgml/features.sgml @@ -14,9 +14,10 @@ The formal name of the SQL standard is ISO/IEC 9075 Database Language SQL. A revised version of the standard is released - from time to time; the most recent update appearing in 2011. - The 2011 version is referred to as ISO/IEC 9075:2011, or simply as SQL:2011. - The versions prior to that were SQL:2008, SQL:2003, SQL:1999, and SQL-92. Each version + from time to time; the most recent update appearing in 2016. + The 2016 version is referred to as ISO/IEC 9075:2016, or simply as SQL:2016. + The versions prior to that were SQL:2011, SQL:2008, SQL:2006, SQL:2003, + SQL:1999, and SQL-92. Each version replaces the previous one, so claims of conformance to earlier versions have no official merit. PostgreSQL development aims for @@ -78,18 +79,18 @@ - PostgreSQL supports most of the major features of SQL:2011. Out of + PostgreSQL supports most of the major features of SQL:2016. Out of 179 mandatory features required for full Core conformance, PostgreSQL conforms to at least 160. In addition, there is a long list of supported optional features. It might be worth noting that at the time of writing, no current version of any database management - system claims full conformance to Core SQL:2011. + system claims full conformance to Core SQL:2016. In the following two sections, we provide a list of those features that PostgreSQL supports, followed by a - list of the features defined in SQL:2011 which + list of the features defined in SQL:2016 which are not yet supported in PostgreSQL. Both of these lists are approximate: There might be minor details that are nonconforming for a feature that is listed as supported, and @@ -132,7 +133,7 @@ Unsupported Features - The following features defined in SQL:2011 are not + The following features defined in SQL:2016 are not implemented in this release of PostgreSQL. In a few cases, equivalent functionality is available. @@ -155,4 +156,335 @@ + + XML Limits and Conformance to SQL/XML + + + SQL/XML + limits and conformance + + + + Significant revisions to the XML-related specifications in ISO/IEC 9075-14 + (SQL/XML) were introduced with SQL:2006. + PostgreSQL's implementation of the XML data + type and related functions largely follows the earlier 2003 edition, + with some borrowing from later editions. In particular: + + + + Where the current standard provides a family of XML data types + to hold document or content in + untyped or XML Schema-typed variants, and a type + XML(SEQUENCE) to hold arbitrary pieces of XML content, + PostgreSQL provides the single + xml type, which can hold document or + content. There is no equivalent of the + standard's sequence type. + + + + + + PostgreSQL provides two functions + introduced in SQL:2006, but in variants that use the XPath 1.0 + language, rather than XML Query as specified for them in the + standard. + + + + + + + This section presents some of the resulting differences you may encounter. + + + + Queries Are Restricted to XPath 1.0 + + + The PostgreSQL-specific functions + xpath() and xpath_exists() + query XML documents using the XPath language. + PostgreSQL also provides XPath-only variants + of the standard functions XMLEXISTS and + XMLTABLE, which officially use + the XQuery language. For all of these functions, + PostgreSQL relies on the + libxml2 library, which provides only XPath 1.0. + + + + There is a strong connection between the XQuery language and XPath + versions 2.0 and later: any expression that is syntactically valid and + executes successfully in both produces the same result (with a minor + exception for expressions containing numeric character references or + predefined entity references, which XQuery replaces with the + corresponding character while XPath leaves them alone). But there is + no such connection between these languages and XPath 1.0; it was an + earlier language and differs in many respects. + + + + There are two categories of limitation to keep in mind: the restriction + from XQuery to XPath for the functions specified in the SQL standard, and + the restriction of XPath to version 1.0 for both the standard and the + PostgreSQL-specific functions. + + + + Restriction of XQuery to XPath + + + Features of XQuery beyond those of XPath include: + + + + + XQuery expressions can construct and return new XML nodes, in + addition to all possible XPath values. XPath can create and return + values of the atomic types (numbers, strings, and so on) but can + only return XML nodes that were already present in documents + supplied as input to the expression. + + + + + + XQuery has control constructs for iteration, sorting, and grouping. + + + + + + XQuery allows declaration and use of local functions. + + + + + + + Recent XPath versions begin to offer capabilities overlapping with + these (such as functional-style for-each and + sort, anonymous functions, and + parse-xml to create a node from a string), + but such features were not available before XPath 3.0. + + + + + Restriction of XPath to 1.0 + + + For developers familiar with XQuery and XPath 2.0 or later, XPath 1.0 + presents a number of differences to contend with: + + + + + The fundamental type of an XQuery/XPath expression, the + sequence, which can contain XML nodes, atomic values, + or both, does not exist in XPath 1.0. A 1.0 expression can only + produce a node-set (containing zero or more XML nodes), or a single + atomic value. + + + + + + Unlike an XQuery/XPath sequence, which can contain any desired + items in any desired order, an XPath 1.0 node-set has no + guaranteed order and, like any set, does not allow multiple + appearances of the same item. + + + The libxml2 library does seem to + always return node-sets to PostgreSQL + with their members in the same relative order they had in the + input document. Its documentation does not commit to this + behavior, and an XPath 1.0 expression cannot control it. + + + + + + + + While XQuery/XPath provides all of the types defined in XML Schema + and many operators and functions over those types, XPath 1.0 has only + node-sets and the three atomic types boolean, + double, and string. + + + + + + XPath 1.0 has no conditional operator. An XQuery/XPath expression + such as if ( hat ) then hat/@size else "no hat" + has no XPath 1.0 equivalent. + + + + + + XPath 1.0 has no ordering comparison operator for strings. Both + "cat" < "dog" and + "cat" > "dog" are false, because each is a + numeric comparison of two NaNs. In contrast, + = and != do compare the strings + as strings. + + + + + + XPath 1.0 blurs the distinction between + value comparisons and + general comparisons as XQuery/XPath define + them. Both sale/@hatsize = 7 and + sale/@customer = "alice" are existentially + quantified comparisons, true if there is + any sale with the given value for the + attribute, but sale/@taxable = false() is a + value comparison to the + effective boolean value of a whole node-set. + It is true only if no sale has + a taxable attribute at all. + + + + + + In the XQuery/XPath data model, a document + node can have either document form (i.e., exactly one + top-level element, with only comments and processing instructions + outside of it) or content form (with those constraints + relaxed). Its equivalent in XPath 1.0, the + root node, can only be in document form. + This is part of the reason an xml value passed as the + context item to any PostgreSQL + XPath-based function must be in document form. + + + + + + + The differences highlighted here are not all of them. In XQuery and + the 2.0 and later versions of XPath, there is an XPath 1.0 compatibility + mode, and the W3C lists of + function library changes + and + language changes + applied in that mode offer a more complete (but still not exhaustive) + account of the differences. The compatibility mode cannot make the + later languages exactly equivalent to XPath 1.0. + + + + + Mappings between SQL and XML Data Types and Values + + + In SQL:2006 and later, both directions of conversion between standard SQL + data types and the XML Schema types are specified precisely. However, the + rules are expressed using the types and semantics of XQuery/XPath, and + have no direct application to the different data model of XPath 1.0. + + + + When PostgreSQL maps SQL data values to XML + (as in xmlelement), or XML to SQL (as in the output + columns of xmltable), except for a few cases + treated specially, PostgreSQL simply assumes + that the XML data type's XPath 1.0 string form will be valid as the + text-input form of the SQL datatype, and conversely. This rule has the + virtue of simplicity while producing, for many data types, results similar + to the mappings specified in the standard. + + + + Where interoperability with other systems is a concern, for some data + types, it may be necessary to use data type formatting functions (such + as those in ) explicitly to + produce the standard mappings. + + + + + + + Incidental limits of the implementation + + + + This section concerns limits that are not inherent in the + libxml2 library, but apply to the current + implementation in PostgreSQL. + + + + Only <literal>BY VALUE</literal> Passing Mechanism Is Supported + + + The SQL standard defines two passing mechanisms + that apply when passing an XML argument from SQL to an XML function or + receiving a result: BY REF, in which a particular XML + value retains its node identity, and BY VALUE, in which + the content of the XML is passed but node identity is not preserved. A + mechanism can be specified before a list of parameters, as the default + mechanism for all of them, or after any parameter, to override the + default. + + + + To illustrate the difference, if + x is an XML value, these two queries in + an SQL:2006 environment would produce true and false, respectively: + + +SELECT XMLQUERY('$a is $b' PASSING BY REF x AS a, x AS b NULL ON EMPTY); +SELECT XMLQUERY('$a is $b' PASSING BY VALUE x AS a, x AS b NULL ON EMPTY); + + + + + PostgreSQL will accept + BY VALUE or BY REF in an + XMLEXISTS or XMLTABLE + construct, but it ignores them. The xml data type holds + a character-string serialized representation, so there is no node + identity to preserve, and passing is always effectively BY + VALUE. + + + + + Cannot Pass Named Parameters to Queries + + + The XPath-based functions support passing one parameter to serve as the + XPath expression's context item, but do not support passing additional + values to be available to the expression as named parameters. + + + + + No <type>XML(SEQUENCE)</type> Type + + + The PostgreSQL xml data type + can only hold a value in DOCUMENT + or CONTENT form. An XQuery/XPath expression + context item must be a single XML node or atomic value, but XPath 1.0 + further restricts it to be only an XML node, and has no node type + allowing CONTENT. The upshot is that a + well-formed DOCUMENT is the only form of XML value + that PostgreSQL can supply as an XPath + context item. + + + + + diff --git a/doc/src/sgml/file-fdw.sgml b/doc/src/sgml/file-fdw.sgml index 955a13ab7d9..4c34ad9cc92 100644 --- a/doc/src/sgml/file-fdw.sgml +++ b/doc/src/sgml/file-fdw.sgml @@ -174,9 +174,8 @@ - COPY's OIDS and - FORCE_QUOTE options are currently not supported by - file_fdw. + COPY's FORCE_QUOTE option is + currently not supported by file_fdw. @@ -188,7 +187,7 @@ Changing table-level options requires being a superuser or having the privileges of the default role pg_read_server_files (to use a filename) or - the default role pg_execute_server_programs (to use a program), + the default role pg_execute_server_program (to use a program), for security reasons: only certain users should be able to control which file is read or which program is run. In principle regular users could be allowed to change the other options, but that's not supported at present. diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index 56b8da04488..3da2365ea97 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -42,7 +42,6 @@ - @@ -90,6 +89,7 @@ + @@ -166,28 +166,16 @@ - - - - - - - - - - - - - - - + + + diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 53a40ddeecf..0aa399dc2f0 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -896,6 +896,19 @@ 2 + + + + log10 + + log10(dp or numeric) + + (same as input) + base 10 logarithm + log10(100.0) + 2 + + log(b numeric, x numeric) @@ -1136,15 +1149,19 @@
- The characteristics of the values returned by - random() depend - on the system implementation. It is not suitable for cryptographic - applications; see module for an alternative. - + The random() function uses a simple linear + congruential algorithm. It is fast but not suitable for cryptographic + applications; see the module for a more + secure alternative. + If setseed() is called, the results of + subsequent random() calls in the current session are + repeatable by re-issuing setseed() with the same + argument. + - Finally, shows the - available trigonometric functions. All trigonometric functions + shows the + available trigonometric functions. All these functions take arguments and return values of type double precision. Each of the trigonometric functions comes in two variants, one that measures angles in radians and one that @@ -1307,6 +1324,96 @@ + + shows the + available hyperbolic functions. All these functions + take arguments and return values of type double + precision. + + + + Hyperbolic Functions + + + + + Function + Description + Example + Result + + + + + + + sinh + + sinh(x) + + hyperbolic sine + sinh(0) + 0 + + + + + cosh + + cosh(x) + + hyperbolic cosine + cosh(0) + 1 + + + + + tanh + + tanh(x) + + hyperbolic tangent + tanh(0) + 0 + + + + + asinh + + asinh(x) + + inverse hyperbolic sine + asinh(0) + 0 + + + + + acosh + + acosh(x) + + inverse hyperbolic cosine + acosh(1) + 0 + + + + + atanh + + atanh(x) + + inverse hyperbolic tangent + atanh(0) + 0 + + + +
+ @@ -1776,7 +1883,7 @@ octal sequences (\nnn) and doubles backslashes. - encode(E'123\\000\\001', 'base64') + encode('123\000\001', 'base64') MTIzAAE= @@ -2100,7 +2207,7 @@ the delimiter. See for more information. - regexp_split_to_array('hello world', E'\\s+') + regexp_split_to_array('hello world', '\s+') {hello,world} @@ -2117,7 +2224,7 @@ the delimiter. See for more information. - regexp_split_to_table('hello world', E'\\s+') + regexp_split_to_table('hello world', '\s+') helloworld (2 rows) @@ -2389,18 +2496,6 @@ - - ascii_to_mic - SQL_ASCII - MULE_INTERNAL - - - - ascii_to_utf8 - SQL_ASCII - UTF8 - - big5_to_euc_tw BIG5 @@ -2671,12 +2766,6 @@ UTF8 - - mic_to_ascii - MULE_INTERNAL - SQL_ASCII - - mic_to_big5 MULE_INTERNAL @@ -2786,7 +2875,7 @@ - tcvn_to_utf8 + windows_1258_to_utf8 WIN1258 UTF8 @@ -2797,12 +2886,6 @@ UTF8 - - utf8_to_ascii - UTF8 - SQL_ASCII - - utf8_to_big5 UTF8 @@ -2954,7 +3037,7 @@ - utf8_to_tcvn + utf8_to_windows_1258 UTF8 WIN1258 @@ -3301,8 +3384,8 @@ SELECT format('Testing %s, %s, %s, %%', 'one', 'two', 'three'); SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly'); Result: INSERT INTO "Foo bar" VALUES('O''Reilly') -SELECT format('INSERT INTO %I VALUES(%L)', 'locations', E'C:\\Program Files'); -Result: INSERT INTO locations VALUES(E'C:\\Program Files') +SELECT format('INSERT INTO %I VALUES(%L)', 'locations', 'C:\Program Files'); +Result: INSERT INTO locations VALUES('C:\Program Files')
@@ -3429,7 +3512,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); concatenation - E'\\\\Post'::bytea || E'\\047gres\\000'::bytea + '\\Post'::bytea || '\047gres\000'::bytea \\Post'gres\000 @@ -3442,7 +3525,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); int Number of bytes in binary string - octet_length(E'jo\\000se'::bytea) + octet_length('jo\000se'::bytea) 5 @@ -3457,7 +3540,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Replace substring - overlay(E'Th\\000omas'::bytea placing E'\\002\\003'::bytea from 2 for 3) + overlay('Th\000omas'::bytea placing '\002\003'::bytea from 2 for 3) T\\002\\003mas @@ -3470,7 +3553,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); int Location of specified substring - position(E'\\000om'::bytea in E'Th\\000omas'::bytea) + position('\000om'::bytea in 'Th\000omas'::bytea) 3 @@ -3485,7 +3568,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Extract substring - substring(E'Th\\000omas'::bytea from 2 for 3) + substring('Th\000omas'::bytea from 2 for 3) h\000o @@ -3504,7 +3587,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytes from the start and end of string - trim(E'\\000\\001'::bytea from E'\\000Tom\\001'::bytea) + trim('\000\001'::bytea from '\000Tom\001'::bytea) Tom @@ -3547,7 +3630,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); bytes from the start and end of string - btrim(E'\\000trim\\001'::bytea, E'\\000\\001'::bytea) + btrim('\000trim\001'::bytea, '\000\001'::bytea) trim @@ -3564,7 +3647,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Decode binary data from textual representation in string. Options for format are same as in encode. - decode(E'123\\000456', 'escape') + decode('123\000456', 'escape') 123\000456 @@ -3584,7 +3667,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); octal sequences (\nnn) and doubles backslashes. - encode(E'123\\000456'::bytea, 'escape') + encode('123\000456'::bytea, 'escape') 123\000456 @@ -3599,7 +3682,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Extract bit from string - get_bit(E'Th\\000omas'::bytea, 45) + get_bit('Th\000omas'::bytea, 45) 1 @@ -3614,7 +3697,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Extract byte from string - get_byte(E'Th\\000omas'::bytea, 4) + get_byte('Th\000omas'::bytea, 4) 109 @@ -3638,7 +3721,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); binary strings, length - length(E'jo\\000se'::bytea) + length('jo\000se'::bytea) 5 @@ -3654,7 +3737,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Calculates the MD5 hash of string, returning the result in hexadecimal - md5(E'Th\\000omas'::bytea) + md5('Th\000omas'::bytea) 8ab2d3c9689aaf18​b4958c334c82d8b1 @@ -3670,7 +3753,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Set bit in string - set_bit(E'Th\\000omas'::bytea, 45, 0) + set_bit('Th\000omas'::bytea, 45, 0) Th\000omAs @@ -3686,7 +3769,7 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); Set byte in string - set_byte(E'Th\\000omas'::bytea, 4, 64) + set_byte('Th\000omas'::bytea, 4, 64) Th\000o@as @@ -3958,6 +4041,12 @@ cast(-44 as bit(12)) 111111010100 + + The pattern matching operators of all three kinds do not support + nondeterministic collations. If required, apply a different collation to + the expression to work around this limitation. + + <function>LIKE</function> @@ -4032,6 +4121,14 @@ cast(-44 as bit(12)) 111111010100 special meaning of underscore and percent signs in the pattern. + + According to the SQL standard, omitting ESCAPE + means there is no escape character (rather than defaulting to a + backslash), and a zero-length ESCAPE value is + disallowed. PostgreSQL's behavior in + this regard is therefore slightly nonstandard. + + The key word ILIKE can be used instead of LIKE to make the match case-insensitive according @@ -4050,9 +4147,9 @@ cast(-44 as bit(12)) 111111010100 - There is also the prefix operator ^@ and corresponding - starts_with function which covers cases when only - searching by beginning of the string is needed. + Also see the prefix operator ^@ and corresponding + starts_with function, which are useful in cases + where simply matching the beginning of a string is needed. @@ -4083,7 +4180,7 @@ cast(-44 as bit(12)) 111111010100 It is similar to LIKE, except that it interprets the pattern using the SQL standard's definition of a regular expression. SQL regular expressions are a curious cross - between LIKE notation and common regular + between LIKE notation and common (POSIX) regular expression notation. @@ -4167,35 +4264,81 @@ cast(-44 as bit(12)) 111111010100 - As with LIKE, a backslash disables the special meaning - of any of these metacharacters; or a different escape character can - be specified with ESCAPE. + As with LIKE, a backslash disables the special + meaning of any of these metacharacters. A different escape character + can be specified with ESCAPE, or the escape + capability can be disabled by writing ESCAPE ''. + + + + According to the SQL standard, omitting ESCAPE + means there is no escape character (rather than defaulting to a + backslash), and a zero-length ESCAPE value is + disallowed. PostgreSQL's behavior in + this regard is therefore slightly nonstandard. + + + + Another nonstandard extension is that following the escape character + with a letter or digit provides access to the escape sequences + defined for POSIX regular expressions; see + , + , and + below. Some examples: -'abc' SIMILAR TO 'abc' true -'abc' SIMILAR TO 'a' false -'abc' SIMILAR TO '%(b|d)%' true -'abc' SIMILAR TO '(b|c)%' false +'abc' SIMILAR TO 'abc' true +'abc' SIMILAR TO 'a' false +'abc' SIMILAR TO '%(b|d)%' true +'abc' SIMILAR TO '(b|c)%' false +'-abc-' SIMILAR TO '%\mabc\M%' true +'xabcy' SIMILAR TO '%\mabc\M%' false - The substring function with three parameters, - substring(string from - pattern for - escape-character), provides - extraction of a substring that matches an SQL - regular expression pattern. As with SIMILAR TO, the + The substring function with three parameters + provides extraction of a substring that matches an SQL + regular expression pattern. The function can be written according + to SQL99 syntax: + +substring(string from pattern for escape-character) + + or as a plain three-argument function: + +substring(string, pattern, escape-character) + + As with SIMILAR TO, the specified pattern must match the entire data string, or else the function fails and returns null. To indicate the part of the - pattern that should be returned on success, the pattern must contain + pattern for which the matching data sub-string is of interest, + the pattern should contain two occurrences of the escape character followed by a double quote ("). The text matching the portion of the pattern - between these markers is returned. + between these separators is returned when the match is successful. + + + + The escape-double-quote separators actually + divide substring's pattern into three independent + regular expressions; for example, a vertical bar (|) + in any of the three sections affects only that section. Also, the first + and third of these regular expressions are defined to match the smallest + possible amount of text, not the largest, when there is any ambiguity + about how much of the data string matches which pattern. (In POSIX + parlance, the first and third regular expressions are forced to be + non-greedy.) + + + + As an extension to the SQL standard, PostgreSQL + allows there to be just one escape-double-quote separator, in which case + the third regular expression is taken as empty; or no separators, in which + case the first and third regular expressions are taken as empty. @@ -4377,7 +4520,7 @@ regexp_replace('foobarbaz', 'b..', 'X') fooXbaz regexp_replace('foobarbaz', 'b..', 'X', 'g') fooXX -regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g') +regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g') fooXarYXazY @@ -4513,7 +4656,7 @@ SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab; Some examples: -SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', E'\\s+') AS foo; +SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo; foo ------- the @@ -4527,13 +4670,13 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy d dog (9 rows) -SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', E'\\s+'); +SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+'); regexp_split_to_array ----------------------------------------------- {the,quick,brown,fox,jumps,over,the,lazy,dog} (1 row) -SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; +SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo; foo ----- t @@ -4965,18 +5108,37 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; Within a bracket expression, the name of a character class enclosed in [: and :] stands - for the list of all characters belonging to that class. Standard - character class names are: alnum, - alpha, blank, - cntrl, digit, - graph, lower, - print, punct, - space, upper, - xdigit. These stand for the character classes - defined in - ctype3. - A locale can provide others. A character class cannot be used as - an endpoint of a range. + for the list of all characters belonging to that class. A character + class cannot be used as an endpoint of a range. + The POSIX standard defines these character class + names: + alnum (letters and numeric digits), + alpha (letters), + blank (space and tab), + cntrl (control characters), + digit (numeric digits), + graph (printable characters except space), + lower (lower-case letters), + print (printable characters including space), + punct (punctuation), + space (any white space), + upper (upper-case letters), + and xdigit (hexadecimal digits). + The behavior of these standard character classes is generally + consistent across platforms for characters in the 7-bit ASCII set. + Whether a given non-ASCII character is considered to belong to one + of these classes depends on the collation + that is used for the regular-expression function or operator + (see ), or by default on the + database's LC_CTYPE locale setting (see + ). The classification of non-ASCII + characters can vary across platforms even in similarly-named + locales. (But the C locale never considers any + non-ASCII characters to belong to any of these classes.) + In addition to these standard character + classes, PostgreSQL defines + the ascii character class, which contains exactly + the 7-bit ASCII set. @@ -4987,8 +5149,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; and end of a word respectively. A word is defined as a sequence of word characters that is neither preceded nor followed by word characters. A word character is an alnum character (as - defined by - ctype3) + defined by the POSIX character class described above) or an underscore. This is an extension, compatible with but not specified by POSIX 1003.2, and should be used with caution in software intended to be portable to other systems. @@ -5045,7 +5206,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo; - Regular Expression Character-entry Escapes + Regular Expression Character-Entry Escapes @@ -5186,7 +5347,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
- Regular Expression Class-shorthand Escapes + Regular Expression Class-Shorthand Escapes @@ -5380,7 +5541,7 @@ SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
- ARE Embedded-option Letters + ARE Embedded-Option Letters @@ -5809,6 +5970,145 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); + + Differences From XQuery (<literal>LIKE_REGEX</literal>) + + + LIKE_REGEX + + + + XQuery regular expressions + + + + Since SQL:2008, the SQL standard includes + a LIKE_REGEX operator that performs pattern + matching according to the XQuery regular expression + standard. PostgreSQL does not yet + implement this operator, but you can get very similar behavior using + the regexp_match() function, since XQuery + regular expressions are quite close to the ARE syntax described above. + + + + Notable differences between the existing POSIX-based + regular-expression feature and XQuery regular expressions include: + + + + + XQuery character class subtraction is not supported. An example of + this feature is using the following to match only English + consonants: [a-z-[aeiou]]. + + + + + XQuery character class shorthands \c, + \C, \i, + and \I are not supported. + + + + + XQuery character class elements + using \p{UnicodeProperty} or the + inverse \P{UnicodeProperty} are not supported. + + + + + POSIX interprets character classes such as \w + (see ) + according to the prevailing locale (which you can control by + attaching a COLLATE clause to the operator or + function). XQuery specifies these classes by reference to Unicode + character properties, so equivalent behavior is obtained only with + a locale that follows the Unicode rules. + + + + + The SQL standard (not XQuery itself) attempts to cater for more + variants of newline than POSIX does. The + newline-sensitive matching options described above consider only + ASCII NL (\n) to be a newline, but SQL would have + us treat CR (\r), CRLF (\r\n) + (a Windows-style newline), and some Unicode-only characters like + LINE SEPARATOR (U+2028) as newlines as well. + Notably, . and \s should + count \r\n as one character not two according to + SQL. + + + + + Of the character-entry escapes described in + , + XQuery supports only \n, \r, + and \t. + + + + + XQuery does not support + the [:name:] syntax + for character classes within bracket expressions. + + + + + XQuery does not have lookahead or lookbehind constraints, + nor any of the constraint escapes described in + . + + + + + The metasyntax forms described in + do not exist in XQuery. + + + + + The regular expression flag letters defined by XQuery are + related to but not the same as the option letters for POSIX + (). While the + i and q options behave the + same, others do not: + + + + XQuery's s (allow dot to match newline) + and m (allow ^ + and $ to match at newlines) flags provide + access to the same behaviors as + POSIX's n, p + and w flags, but they + do not match the behavior of + POSIX's s and m flags. + Note in particular that dot-matches-newline is the default + behavior in POSIX but not XQuery. + + + + + XQuery's x (ignore whitespace in pattern) flag + is noticeably different from POSIX's expanded-mode flag. + POSIX's x flag also + allows # to begin a comment in the pattern, + and POSIX will not ignore a whitespace character after a + backslash. + + + + + + + + + @@ -5990,7 +6290,31 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); microsecond (000000-999999) - SSSS + FF1 + tenth of second (0-9) + + + FF2 + hundredth of second (00-99) + + + FF3 + millisecond (000-999) + + + FF4 + tenth of a millisecond (0000-9999) + + + FF5 + hundredth of a millisecond (00000-99999) + + + FF6 + microsecond (000000-999999) + + + SSSS, SSSSS seconds past midnight (0-86399) @@ -6262,16 +6586,57 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); to_timestamp and to_date - skip multiple blank spaces in the input string unless the - FX option is used. For example, - to_timestamp('2000    JUN', 'YYYY MON') works, but + skip multiple blank spaces at the beginning of the input string and + around date and time values unless the FX option is used. For example, + to_timestamp(' 2000    JUN', 'YYYY MON') and + to_timestamp('2000 - JUN', 'YYYY-MON') work, but to_timestamp('2000    JUN', 'FXYYYY MON') returns an error - because to_timestamp expects one space only. + because to_timestamp expects only a single space. FX must be specified as the first item in the template. + + + A separator (a space or non-letter/non-digit character) in the template string of + to_timestamp and to_date + matches any single separator in the input string or is skipped, + unless the FX option is used. + For example, to_timestamp('2000JUN', 'YYYY///MON') and + to_timestamp('2000/JUN', 'YYYY MON') work, but + to_timestamp('2000//JUN', 'YYYY/MON') + returns an error because the number of separators in the input string + exceeds the number of separators in the template. + + + If FX is specified, a separator in the template string + matches exactly one character in the input string. But note that the + input string character is not required to be the same as the separator from the template string. + For example, to_timestamp('2000/JUN', 'FXYYYY MON') + works, but to_timestamp('2000/JUN', 'FXYYYY  MON') + returns an error because the second space in the template string consumes + the letter J from the input string. + + + + + + A TZH template pattern can match a signed number. + Without the FX option, minus signs may be ambiguous, + and could be interpreted as a separator. + This ambiguity is resolved as follows: If the number of separators before + TZH in the template string is less than the number of + separators before the minus sign in the input string, the minus sign + is interpreted as part of TZH. + Otherwise, the minus sign is considered to be a separator between values. + For example, to_timestamp('2000 -10', 'YYYY TZH') matches + -10 to TZH, but + to_timestamp('2000 -10', 'YYYY  TZH') + matches 10 to TZH. + + + Ordinary text is allowed in to_char @@ -6287,6 +6652,19 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); string; for example "XX" skips two input characters (whether or not they are XX). + + + Prior to PostgreSQL 12, it was possible to + skip arbitrary text in the input string using non-letter or non-digit + characters. For example, + to_timestamp('2000y6m1d', 'yyyy-MM-DD') used to + work. Now you can only use letter characters for this purpose. For example, + to_timestamp('2000y6m1d', 'yyyytMMtDDt') and + to_timestamp('2000y6m1d', 'yyyy"y"MM"m"DD"d"') + skip y, m, and + d. + + @@ -7125,16 +7503,25 @@ SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}'); date_trunc(text, timestamp) timestamp - Truncate to specified precision; see also + Truncate to specified precision; see date_trunc('hour', timestamp '2001-02-16 20:38:40') 2001-02-16 20:00:00 + + date_trunc(text, timestamp with time zone, text) + timestamp with time zone + Truncate to specified precision in the specified time zone; see + + date_trunc('day', timestamptz '2001-02-16 20:38:40+00', 'Australia/Sydney') + 2001-02-16 13:00:00+00 + + date_trunc(text, interval) interval - Truncate to specified precision; see also + Truncate to specified precision; see date_trunc('hour', interval '2 days 3 hours 40 minutes') 2 days 03:00:00 @@ -8024,17 +8411,19 @@ SELECT date_part('hour', INTERVAL '4 hours 3 minutes'); -date_trunc('field', source) +date_trunc(field, source [, time_zone ]) source is a value expression of type - timestamp or interval. + timestamp, timestamp with time zone, + or interval. (Values of type date and time are cast automatically to timestamp or interval, respectively.) field selects to which precision to - truncate the input value. The return value is of type - timestamp or interval - with all fields that are less significant than the + truncate the input value. The return value is likewise of type + timestamp, timestamp with time zone, + or interval, + and it has all fields that are less significant than the selected one set to zero (or one, for day and month). @@ -8058,13 +8447,39 @@ date_trunc('field', source - Examples: + When the input value is of type timestamp with time zone, + the truncation is performed with respect to a particular time zone; + for example, truncation to day produces a value that + is midnight in that zone. By default, truncation is done with respect + to the current setting, but the + optional time_zone argument can be provided + to specify a different time zone. The time zone name can be specified + in any of the ways described in . + + + + A time zone cannot be specified when processing timestamp without + time zone or interval inputs. These are always + taken at face value. + + + + Examples (assuming the local time zone is America/New_York): SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40'); Result: 2001-02-16 20:00:00 SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); Result: 2001-01-01 00:00:00 + +SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00'); +Result: 2001-02-16 00:00:00-05 + +SELECT date_trunc('day', TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40+00', 'Australia/Sydney'); +Result: 2001-02-16 08:00:00-05 + +SELECT date_trunc('hour', INTERVAL '3 days 02:47:33'); +Result: 3 days 02:00:00 @@ -8082,10 +8497,11 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); - The AT TIME ZONE construct allows conversions - of time stamps to different time zones. shows its - variants. + The AT TIME ZONE converts time + stamp without time zone to/from + time stamp with time zone, and + time values to different time zones. shows its variants.
@@ -8130,24 +8546,33 @@ SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40'); In these expressions, the desired time zone zone can be - specified either as a text string (e.g., 'PST') + specified either as a text string (e.g., 'America/Los_Angeles') or as an interval (e.g., INTERVAL '-08:00'). In the text case, a time zone name can be specified in any of the ways described in . - Examples (assuming the local time zone is PST8PDT): + Examples (assuming the local time zone is America/Los_Angeles): -SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'MST'; +SELECT TIMESTAMP '2001-02-16 20:38:40' AT TIME ZONE 'America/Denver'; Result: 2001-02-16 19:38:40-08 -SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'MST'; +SELECT TIMESTAMP WITH TIME ZONE '2001-02-16 20:38:40-05' AT TIME ZONE 'America/Denver'; Result: 2001-02-16 18:38:40 + +SELECT TIMESTAMP '2001-02-16 20:38:40-05' AT TIME ZONE 'Asia/Tokyo' AT TIME ZONE 'America/Chicago'; +Result: 2001-02-16 05:38:40 - The first example takes a time stamp without time zone and interprets it as MST time - (UTC-7), which is then converted to PST (UTC-8) for display. The second example takes - a time stamp specified in EST (UTC-5) and converts it to local time in MST (UTC-7). + The first example adds a time zone to a value that lacks it, and + displays the value using the current TimeZone + setting. The second example shifts the time stamp with time zone value + to the specified time zone, and returns the value without a time zone. + This allows storage and display of values different from the current + TimeZone setting. The third example converts + Tokyo time to Chicago time. Converting time + values to other time zones uses the currently active time zone rules + since no date is supplied. @@ -9737,10 +10162,10 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple reduce each value in the document, specified by filter to a tsvector, and then concatenate those in document order to produce a single tsvector. - filter is a jsonb array, that enumerates what kind of elements need to be included + filter is a jsonb array, that enumerates what kind of elements need to be included into the resulting tsvector. Possible values for filter are "string" (to include all string values), "numeric" (to include all numeric values in the string format), - "boolean" (to include all boolean values in the string format "true"/"false"), + "boolean" (to include all Boolean values in the string format "true"/"false"), "key" (to include all keys) or "all" (to include all above). These values can be combined together to include, e.g. all string and numeric values. @@ -10033,18 +10458,53 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple + + UUID Functions + + + UUID + generating + + + + gen_random_uuid + + + + PostgreSQL includes one function to generate a UUID: + +gen_random_uuid() returns uuid + + This function returns a version 4 (random) UUID. This is the most commonly + used type of UUID and is appropriate for most applications. + + + + The module provides additional functions that + implement other standard algorithms for generating UUIDs. + + + XML Functions + + XML Functions + + The functions and function-like expressions described in this - section operate on values of type xml. Check xml. See for information about the xml type. The function-like expressions xmlparse and xmlserialize for converting to and from - type xml are not repeated here. Use of most of these - functions requires the installation to have been built + type xml are documented there, not in this section. + + + + Use of most of these functions + requires PostgreSQL to have been built with configure --with-libxml. @@ -10239,8 +10699,8 @@ SELECT xmlelement(name foo, xmlattributes('xyz' as bar), encoding, depending on the setting of the configuration parameter . The particular behavior for individual data types is expected to evolve in order to align the - SQL and PostgreSQL data types with the XML Schema specification, - at which point a more precise description will appear. + PostgreSQL mappings with those specified in SQL:2006 and later, + as discussed in . @@ -10478,20 +10938,23 @@ SELECT xmlagg(x) FROM (SELECT * FROM test ORDER BY y DESC) AS tab; -XMLEXISTS(text PASSING BY REF xml BY REF) +XMLEXISTS(text PASSING BY { REF | VALUE } xml BY { REF | VALUE }) - The function xmlexists returns true if the - XPath expression in the first argument returns any nodes, and - false otherwise. (If either argument is null, the result is - null.) + The function xmlexists evaluates an XPath 1.0 + expression (the first argument), with the passed XML value as its context + item. The function returns false if the result of that evaluation + yields an empty node-set, true if it yields any other value. The + function returns null if any argument is null. A nonnull value + passed as the context item must be an XML document, not a content + fragment or any non-XML value. Example: TorontoOttawa'); +SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY VALUE 'TorontoOttawa'); xmlexists ------------ @@ -10501,14 +10964,14 @@ SELECT xmlexists('//town[text() = ''Toronto'']' PASSING BY REF 'Tor - The BY REF clauses have no effect in - PostgreSQL, but are allowed for SQL conformance and compatibility - with other implementations. Per SQL standard, the - first BY REF is required, the second is - optional. Also note that the SQL standard specifies - the xmlexists construct to take an XQuery - expression as first argument, but PostgreSQL currently only - supports XPath, which is a subset of XQuery. + The BY REF and BY VALUE clauses + are accepted in PostgreSQL, but are ignored, + as discussed in . + In the SQL standard, the xmlexists function + evaluates an expression in the XML Query language, + but PostgreSQL allows only an XPath 1.0 + expression, as discussed in + . @@ -10614,12 +11077,12 @@ SELECT xml_is_well_formed_document('test The function xpath_exists is a specialized form of the xpath function. Instead of returning the - individual XML values that satisfy the XPath, this function returns a - Boolean indicating whether the query was satisfied or not. This - function is equivalent to the standard XMLEXISTS predicate, + individual XML values that satisfy the XPath 1.0 expression, this function + returns a Boolean indicating whether the query was satisfied or not + (specifically, whether it produced any value other than an empty node-set). + This function is equivalent to the XMLEXISTS predicate, except that it also offers support for a namespace mapping argument. @@ -10715,7 +11179,7 @@ SELECT xpath_exists('/my:a/text()', 'test xmltable( XMLNAMESPACES(namespace uri AS namespace name, ...), - row_expression PASSING BY REF document_expression BY REF + row_expression PASSING BY { REF | VALUE } document_expression BY { REF | VALUE } COLUMNS name { type PATH column_expression DEFAULT default_expression NOT NULL | NULL | FOR ORDINALITY } , ... @@ -10724,8 +11188,8 @@ SELECT xpath_exists('/my:a/text()', 'test The xmltable function produces a table based - on the given XML value, an XPath filter to extract rows, and an - optional set of column definitions. + on the given XML value, an XPath filter to extract rows, and a + set of column definitions. @@ -10736,30 +11200,34 @@ SELECT xpath_exists('/my:a/text()', 'test - The required row_expression argument is an XPath - expression that is evaluated against the supplied XML document to - obtain an ordered sequence of XML nodes. This sequence is what - xmltable transforms into output rows. + The required row_expression argument is + an XPath 1.0 expression that is evaluated, passing the + document_expression as its context item, to + obtain a set of XML nodes. These nodes are what + xmltable transforms into output rows. No rows + will be produced if the document_expression + is null, nor if the row_expression produces + an empty node-set or any value other than a node-set. - document_expression provides the XML document to - operate on. - The BY REF clauses have no effect in PostgreSQL, - but are allowed for SQL conformance and compatibility with other - implementations. - The argument must be a well-formed XML document; fragments/forests - are not accepted. + document_expression provides the context + item for the row_expression. It must be a + well-formed XML document; fragments/forests are not accepted. + The BY REF and BY VALUE clauses + are accepted but ignored, as discussed in + . + In the SQL standard, the xmltable function + evaluates expressions in the XML Query language, + but PostgreSQL allows only XPath 1.0 + expressions, as discussed in + . The mandatory COLUMNS clause specifies the list of columns in the output table. - If the COLUMNS clause is omitted, the rows in the result - set contain a single column of type xml containing the - data matched by row_expression. - If COLUMNS is specified, each entry describes a - single column. + Each entry describes a single column. See the syntax summary above for the format. The column name and type are required; the path, default and nullability clauses are optional. @@ -10767,48 +11235,92 @@ SELECT xpath_exists('/my:a/text()', 'test A column marked FOR ORDINALITY will be populated - with row numbers matching the order in which the - output rows appeared in the original input XML document. + with row numbers, starting with 1, in the order of nodes retrieved from + the row_expression's result node-set. At most one column may be marked FOR ORDINALITY. + + + XPath 1.0 does not specify an order for nodes in a node-set, so code + that relies on a particular order of the results will be + implementation-dependent. Details can be found in + . + + + + + The column_expression for a column is an + XPath 1.0 expression that is evaluated for each row, with the current + node from the row_expression result as its + context item, to find the value of the column. If + no column_expression is given, then the + column name is used as an implicit path. + + - The column_expression for a column is an XPath expression - that is evaluated for each row, relative to the result of the - row_expression, to find the value of the column. - If no column_expression is given, then the column name - is used as an implicit path. + If a column's XPath expression returns a non-XML value (limited to + string, boolean, or double in XPath 1.0) and the column has a + PostgreSQL type other than xml, the column will be set + as if by assigning the value's string representation to the PostgreSQL + type. (If the value is a boolean, its string representation is taken + to be 1 or 0 if the output + column's type category is numeric, otherwise true or + false.) - If a column's XPath expression returns multiple elements, an error - is raised. - If the expression matches an empty tag, the result is an - empty string (not NULL). - Any xsi:nil attributes are ignored. + If a column's XPath expression returns a non-empty set of XML nodes + and the column's PostgreSQL type is xml, the column will + be assigned the expression result exactly, if it is of document or + content form. + + + A result containing more than one element node at the top level, or + non-whitespace text outside of an element, is an example of content form. + An XPath result can be of neither form, for example if it returns an + attribute node selected from the element that contains it. Such a result + will be put into content form with each such disallowed node replaced by + its string value, as defined for the XPath 1.0 + string function. + + - The text body of the XML matched by the column_expression - is used as the column value. Multiple text() nodes - within an element are concatenated in order. Any child elements, - processing instructions, and comments are ignored, but the text contents - of child elements are concatenated to the result. + A non-XML result assigned to an xml output column produces + content, a single text node with the string value of the result. + An XML result assigned to a column of any other type may not have more than + one node, or an error is raised. If there is exactly one node, the column + will be set as if by assigning the node's string + value (as defined for the XPath 1.0 string function) + to the PostgreSQL type. + + + + The string value of an XML element is the concatenation, in document order, + of all text nodes contained in that element and its descendants. The string + value of an element with no descendant text nodes is an + empty string (not NULL). + Any xsi:nil attributes are ignored. Note that the whitespace-only text() node between two non-text elements is preserved, and that leading whitespace on a text() node is not flattened. + The XPath 1.0 string function may be consulted for the + rules defining the string value of other XML node types and non-XML values. + + + + The conversion rules presented here are not exactly those of the SQL + standard, as discussed in . - If the path expression does not match for a given row but - default_expression is specified, the value resulting - from evaluating that expression is used. - If no DEFAULT clause is given for the column, - the field will be set to NULL. - It is possible for a default_expression to reference - the value of output columns that appear prior to it in the column list, - so the default of one column may be based on the value of another - column. + If the path expression returns an empty node-set + (typically, when it does not match) + for a given row, the column will be set to NULL, unless + a default_expression is specified; then the + value resulting from evaluating that expression is used. @@ -10820,20 +11332,14 @@ SELECT xpath_exists('/my:a/text()', 'test - Unlike regular PostgreSQL functions, column_expression - and default_expression are not evaluated to a simple - value before calling the function. - column_expression is normally evaluated - exactly once per input row, and default_expression - is evaluated each time a default is needed for a field. - If the expression qualifies as stable or immutable the repeat + A default_expression, rather than being + evaluated immediately when xmltable is called, + is evaluated each time a default is needed for the column. + If the expression qualifies as stable or immutable, the repeat evaluation may be skipped. - Effectively xmltable behaves more like a subquery than a - function call. This means that you can usefully use volatile functions like - nextval in default_expression, and - column_expression may depend on other parts of the - XML document. + nextval in + default_expression. @@ -10894,16 +11400,16 @@ $$ AS data; SELECT xmltable.* FROM xmlelements, XMLTABLE('/root' PASSING data COLUMNS element text); - element ----------------------- - Hello2a2 bbbCC + element +------------------------- + Hello2a2 bbbxxxCC ]]> The following example illustrates how the XMLNAMESPACES clause can be used to specify - the default namespace, and a list of additional namespaces + a list of namespaces used in the XML document as well as in the XPath expressions: JSON Functions and Operators - JSON - functions and operators + JSON + functions and operators - - shows the operators that - are available for use with the two JSON data types (see ). - + + This section describes: -
+ + + + functions and operators for processing and creating JSON data + + + + + the SQL/JSON path language + + + + + + + To learn more about the SQL/JSON standard, see + . For details on JSON types + supported in PostgreSQL, + see . + + + + Processing and Creating JSON Data + + + shows the operators that + are available for use with JSON data types (see ). + + +
<type>json</type> and <type>jsonb</type> Operators - + Operator Right Operand Type + Return type Description Example Example Result @@ -11213,6 +11747,7 @@ table2-mapping -> int + json or jsonb Get JSON array element (indexed from zero, negative integers count from the end) '[{"a":"foo"},{"b":"bar"},{"c":"baz"}]'::json->2 @@ -11221,6 +11756,7 @@ table2-mapping -> text + json or jsonb Get JSON object field by key '{"a": {"b":"foo"}}'::json->'a' {"b":"foo"} @@ -11228,6 +11764,7 @@ table2-mapping ->> int + text Get JSON array element as text '[1,2,3]'::json->>2 3 @@ -11235,6 +11772,7 @@ table2-mapping ->> text + text Get JSON object field as text '{"a":1,"b":2}'::json->>'b' 2 @@ -11242,14 +11780,16 @@ table2-mapping #> text[] - Get JSON object at specified path + json or jsonb + Get JSON object at the specified path '{"a": {"b":{"c": "foo"}}}'::json#>'{a,b}' {"c": "foo"} #>> text[] - Get JSON object at specified path as text + text + Get JSON object at the specified path as text '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}' 3 @@ -11374,6 +11914,20 @@ table2-mapping JSON arrays, negative integers count from the end) '["a", {"b":1}]'::jsonb #- '{1,b}' + + @? + jsonpath + Does JSON path return any item for the specified JSON value? + '{"a":[1,2,3,4,5]}'::jsonb @? '$.a[*] ? (@ > 2)' + + + @@ + jsonpath + Returns the result of JSON path predicate check for the specified JSON value. + Only the first item of the result is taken into account. If the + result is not Boolean, then null is returned. + '{"a":[1,2,3,4,5]}'::jsonb @@ '$.a[*] > 2' +
@@ -11387,6 +11941,16 @@ table2-mapping + + + The @? and @@ operators suppress + the following errors: lacking object field or array element, unexpected + JSON item type, datetime and numeric errors. + This behavior might be helpful while searching over JSON document + collections of varying structure. + + + shows the functions that are available for creating json and jsonb values. @@ -11647,6 +12211,36 @@ table2-mapping jsonb_pretty + + jsonb_path_exists + + + jsonb_path_exists_tz + + + jsonb_path_match + + + jsonb_path_match_tz + + + jsonb_path_query + + + jsonb_path_query_tz + + + jsonb_path_query_array + + + jsonb_path_query_array_tz + + + jsonb_path_query_first + + + jsonb_path_query_first_tz + JSON Processing Functions @@ -11903,7 +12497,7 @@ table2-mapping [{"f1":1},2,null,3] - jsonb_set(target jsonb, path text[], new_value jsonb, create_missing boolean) + jsonb_set(target jsonb, path text[], new_value jsonb , create_missing boolean) jsonb @@ -11911,10 +12505,10 @@ table2-mapping with the section designated by path replaced by new_value, or with new_value added if - create_missing is true ( default is + create_missing is true (default is true) and the item designated by path does not exist. - As with the path orientated operators, negative integers that + As with the path oriented operators, negative integers that appear in path count from the end of JSON arrays. @@ -11928,7 +12522,7 @@ table2-mapping - jsonb_insert(target jsonb, path text[], new_value jsonb, insert_after boolean) + jsonb_insert(target jsonb, path text[], new_value jsonb , insert_after boolean) jsonb @@ -11943,7 +12537,7 @@ table2-mapping designated by path is in JSONB object, new_value will be inserted only if target does not exist. As with the path - orientated operators, negative integers that appear in + oriented operators, negative integers that appear in path count from the end of JSON arrays. @@ -11981,6 +12575,130 @@ table2-mapping + + + + jsonb_path_exists(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb_path_exists_tz(target jsonb, path jsonpath , vars jsonb , silent bool) + + + boolean + + Checks whether JSON path returns any item for the specified JSON + value. + + + + jsonb_path_exists('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') + + + + true + + + + + + jsonb_path_match(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb_path_match_tz(target jsonb, path jsonpath , vars jsonb , silent bool) + + + boolean + + Returns the result of JSON path predicate check for the specified JSON value. + Only the first item of the result is taken into account. If the + result is not Boolean, then null is returned. + + + + jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min && @ <= $max))', '{"min":2,"max":4}') + + + + true + + + + + + jsonb_path_query(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb_path_query_tz(target jsonb, path jsonpath , vars jsonb , silent bool) + + + setof jsonb + + Gets all JSON items returned by JSON path for the specified JSON + value. + + + + select * from jsonb_path_query('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}'); + + + + + + jsonb_path_query +------------------ + 2 + 3 + 4 + + + + + + + + jsonb_path_query_array(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb_path_query_array_tz(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb + + Gets all JSON items returned by JSON path for the specified JSON + value and wraps result into an array. + + + + jsonb_path_query_array('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') + + + + [2, 3, 4] + + + + + + jsonb_path_query_first(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb_path_query_first_tz(target jsonb, path jsonpath , vars jsonb , silent bool) + + + jsonb + + Gets the first JSON item returned by JSON path for the specified JSON + value. Returns NULL on no results. + + + + jsonb_path_query_first('{"a":[1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2,"max":4}') + + + + 2 + +
@@ -11996,15 +12714,72 @@ table2-mapping - - In json_populate_record, json_populate_recordset, - json_to_record and json_to_recordset, - type coercion from the JSON is best effort and may not result - in desired values for some types. JSON keys are matched to - identical column names in the target row type. JSON fields that do not - appear in the target row type will be omitted from the output, and - target columns that do not match any JSON field will simply be NULL. - + + The functions + json[b]_populate_record, + json[b]_populate_recordset, + json[b]_to_record and + json[b]_to_recordset + operate on a JSON object, or array of objects, and extract the values + associated with keys whose names match column names of the output row + type. + Object fields that do not correspond to any output column name are + ignored, and output columns that do not match any object field will be + filled with nulls. + To convert a JSON value to the SQL type of an output column, the + following rules are applied in sequence: + + + + A JSON null value is converted to a SQL null in all cases. + + + + + If the output column is of type json + or jsonb, the JSON value is just reproduced exactly. + + + + + If the output column is a composite (row) type, and the JSON value is + a JSON object, the fields of the object are converted to columns of + the output row type by recursive application of these rules. + + + + + Likewise, if the output column is an array type and the JSON value is + a JSON array, the elements of the JSON array are converted to elements + of the output array by recursive application of these rules. + + + + + Otherwise, if the JSON value is a string literal, the contents of the + string are fed to the input conversion function for the column's data + type. + + + + + Otherwise, the ordinary text representation of the JSON value is fed + to the input conversion function for the column's data type. + + + + + + + While the examples for these functions use constants, the typical use + would be to reference a table in the FROM clause + and use one of its json or jsonb columns + as an argument to the function. Extracted key values can then be + referenced in other parts of the query, like WHERE + clauses and target lists. Extracting multiple values in this + way can improve performance over extracting them separately with + per-key operators. + @@ -12049,6 +12824,37 @@ table2-mapping
+ + + The jsonb_path_* functions have optional + vars and silent arguments. + + + If the vars argument is specified, it provides an + object containing named variables to be substituted into a + jsonpath expression. + + + If the silent argument is specified and has the + true value, these functions suppress the same errors + as the @? and @@ operators. + + + + + + Some of the jsonb_path_* functions have the + _tz suffix. These functions have been implemented to + support comparison of date/time values that involves implicit + timezone-aware casts. Since operations with time zones are not immutable, + these functions are qualified as stable. Their counterparts without the + suffix do not support such casts, so they are immutable and can be used for + such use-cases as expression indexes + (see ). There is no difference + between these functions for other jsonpath operations. + + + See also for the aggregate function json_agg which aggregates record @@ -12057,7 +12863,688 @@ table2-mapping into a JSON object, and their jsonb equivalents, jsonb_agg and jsonb_object_agg. + + + + The SQL/JSON Path Language + + + SQL/JSON path language + + + + SQL/JSON path expressions specify the items to be retrieved + from the JSON data, similar to XPath expressions used + for SQL access to XML. In PostgreSQL, + path expressions are implemented as the jsonpath + data type and can use any elements described in + . + + + JSON query functions and operators + pass the provided path expression to the path engine + for evaluation. If the expression matches the queried JSON data, + the corresponding SQL/JSON item is returned. + Path expressions are written in the SQL/JSON path language + and can also include arithmetic expressions and functions. + Query functions treat the provided expression as a + text string, so it must be enclosed in single quotes. + + + + A path expression consists of a sequence of elements allowed + by the jsonpath data type. + The path expression is evaluated from left to right, but + you can use parentheses to change the order of operations. + If the evaluation is successful, a sequence of SQL/JSON items + (SQL/JSON sequence) is produced, + and the evaluation result is returned to the JSON query function + that completes the specified computation. + + + + To refer to the JSON data to be queried (the + context item), use the $ sign + in the path expression. It can be followed by one or more + accessor operators, + which go down the JSON structure level by level to retrieve the + content of context item. Each operator that follows deals with the + result of the previous evaluation step. + + + + For example, suppose you have some JSON data from a GPS tracker that you + would like to parse, such as: + +{ + "track": { + "segments": [ + { + "location": [ 47.763, 13.4034 ], + "start time": "2018-10-14 10:05:14", + "HR": 73 + }, + { + "location": [ 47.706, 13.2635 ], + "start time": "2018-10-14 10:39:21", + "HR": 135 + } + ] + } +} + + + + + To retrieve the available track segments, you need to use the + .key accessor + operator for all the preceding JSON objects: + +'$.track.segments' + + + + + If the item to retrieve is an element of an array, you have + to unnest this array using the [*] operator. For example, + the following path will return location coordinates for all + the available track segments: + +'$.track.segments[*].location' + + + + + To return the coordinates of the first segment only, you can + specify the corresponding subscript in the [] + accessor operator. Note that the SQL/JSON arrays are 0-relative: + +'$.track.segments[0].location' + + + + + The result of each path evaluation step can be processed + by one or more jsonpath operators and methods + listed in . + Each method name must be preceded by a dot. For example, + you can get an array size: + +'$.track.segments.size()' + + For more examples of using jsonpath operators + and methods within path expressions, see + . + + + + When defining the path, you can also use one or more + filter expressions that work similar to the + WHERE clause in SQL. A filter expression begins with + a question mark and provides a condition in parentheses: + + +? (condition) + + + + + Filter expressions must be specified right after the path evaluation step + to which they are applied. The result of this step is filtered to include + only those items that satisfy the provided condition. SQL/JSON defines + three-valued logic, so the condition can be true, false, + or unknown. The unknown value + plays the same role as SQL NULL and can be tested + for with the is unknown predicate. Further path + evaluation steps use only those items for which filter expressions + return true. + + + + Functions and operators that can be used in filter expressions are listed + in . The path + evaluation result to be filtered is denoted by the @ + variable. To refer to a JSON element stored at a lower nesting level, + add one or more accessor operators after @. + + + + Suppose you would like to retrieve all heart rate values higher + than 130. You can achieve this using the following expression: + +'$.track.segments[*].HR ? (@ > 130)' + + + + + To get the start time of segments with such values instead, you have to + filter out irrelevant segments before returning the start time, so the + filter expression is applied to the previous step, and the path used + in the condition is different: + +'$.track.segments[*] ? (@.HR > 130)."start time"' + + + + + You can use several filter expressions on the same nesting level, if + required. For example, the following expression selects all segments + that contain locations with relevant coordinates and high heart rate values: + +'$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"' + + + + + Using filter expressions at different nesting levels is also allowed. + The following example first filters all segments by location, and then + returns high heart rate values for these segments, if available: + +'$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)' + + + + + You can also nest filter expressions within each other: + +'$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()' + + This expression returns the size of the track if it contains any + segments with high heart rate values, or an empty sequence otherwise. + + + + PostgreSQL's implementation of SQL/JSON path + language has the following deviations from the SQL/JSON standard: + + + + + + A path expression can be a Boolean predicate, although the SQL/JSON + standard allows predicates only in filters. This is necessary for + implementation of the @@ operator. For example, + the following jsonpath expression is valid in + PostgreSQL: + +'$.track.segments[*].HR < 70' + + + + + + + There are minor differences in the interpretation of regular + expression patterns used in like_regex filters, as + described in . + + + + + + Strict and Lax Modes + + When you query JSON data, the path expression may not match the + actual JSON data structure. An attempt to access a non-existent + member of an object or element of an array results in a + structural error. SQL/JSON path expressions have two modes + of handling structural errors: + + + + + + lax (default) — the path engine implicitly adapts + the queried data to the specified path. + Any remaining structural errors are suppressed and converted + to empty SQL/JSON sequences. + + + + + strict — if a structural error occurs, an error is raised. + + + + + + The lax mode facilitates matching of a JSON document structure and path + expression if the JSON data does not conform to the expected schema. + If an operand does not match the requirements of a particular operation, + it can be automatically wrapped as an SQL/JSON array or unwrapped by + converting its elements into an SQL/JSON sequence before performing + this operation. Besides, comparison operators automatically unwrap their + operands in the lax mode, so you can compare SQL/JSON arrays + out-of-the-box. An array of size 1 is considered equal to its sole element. + Automatic unwrapping is not performed only when: + + + + The path expression contains type() or + size() methods that return the type + and the number of elements in the array, respectively. + + + + + The queried JSON data contain nested arrays. In this case, only + the outermost array is unwrapped, while all the inner arrays + remain unchanged. Thus, implicit unwrapping can only go one + level down within each path evaluation step. + + + + + + + For example, when querying the GPS data listed above, you can + abstract from the fact that it stores an array of segments + when using the lax mode: + +'lax $.track.segments.location' + + + + + In the strict mode, the specified path must exactly match the structure of + the queried JSON document to return an SQL/JSON item, so using this + path expression will cause an error. To get the same result as in + the lax mode, you have to explicitly unwrap the + segments array: + +'strict $.track.segments[*].location' + + + + + + + Regular Expressions + + + LIKE_REGEX + in SQL/JSON + + + + SQL/JSON path expressions allow matching text to a regular expression + with the like_regex filter. For example, the + following SQL/JSON path query would case-insensitively match all + strings in an array that start with an English vowel: + +'$[*] ? (@ like_regex "^[aeiou]" flag "i")' + + + + + The optional flag string may include one or more of + the characters + i for case-insensitive match, + m to allow ^ + and $ to match at newlines, + s to allow . to match a newline, + and q to quote the whole pattern (reducing the + behavior to a simple substring match). + + + + The SQL/JSON standard borrows its definition for regular expressions + from the LIKE_REGEX operator, which in turn uses the + XQuery standard. PostgreSQL does not currently support the + LIKE_REGEX operator. Therefore, + the like_regex filter is implemented using the + POSIX regular expression engine described in + . This leads to various minor + discrepancies from standard SQL/JSON behavior, which are cataloged in + . + Note, however, that the flag-letter incompatibilities described there + do not apply to SQL/JSON, as it translates the XQuery flag letters to + match what the POSIX engine expects. + + + + Keep in mind that the pattern argument of like_regex + is a JSON path string literal, written according to the rules given in + . This means in particular that any + backslashes you want to use in the regular expression must be doubled. + For example, to match strings that contain only digits: + +'$ ? (@ like_regex "^\\d+$")' + + + + + + + SQL/JSON Path Operators and Methods + + + shows the operators and + methods available in jsonpath. shows the available filter + expression elements. + + + + <type>jsonpath</type> Operators and Methods + + + + Operator/Method + Description + Example JSON + Example Query + Result + + + + + + (unary) + Plus operator that iterates over the SQL/JSON sequence + {"x": [2.85, -14.7, -9.4]} + + $.x.floor() + 2, -15, -10 + + + - (unary) + Minus operator that iterates over the SQL/JSON sequence + {"x": [2.85, -14.7, -9.4]} + - $.x.floor() + -2, 15, 10 + + + + (binary) + Addition + [2] + 2 + $[0] + 4 + + + - (binary) + Subtraction + [2] + 4 - $[0] + 2 + + + * + Multiplication + [4] + 2 * $[0] + 8 + + + / + Division + [8] + $[0] / 2 + 4 + + + % + Modulus + [32] + $[0] % 10 + 2 + + + type() + Type of the SQL/JSON item + [1, "2", {}] + $[*].type() + "number", "string", "object" + + + size() + Size of the SQL/JSON item + {"m": [11, 15]} + $.m.size() + 2 + + + double() + Approximate floating-point number converted from an SQL/JSON number or a string + {"len": "1.9"} + $.len.double() * 2 + 3.8 + + + ceiling() + Nearest integer greater than or equal to the SQL/JSON number + {"h": 1.3} + $.h.ceiling() + 2 + + + floor() + Nearest integer less than or equal to the SQL/JSON number + {"h": 1.3} + $.h.floor() + 1 + + + abs() + Absolute value of the SQL/JSON number + {"z": -0.3} + $.z.abs() + 0.3 + + + datetime() + Date/time value converted from a string + ["2015-8-1", "2015-08-12"] + $[*] ? (@.datetime() < "2015-08-2". datetime()) + 2015-8-1 + + + datetime(template) + Date/time value converted from a string using the specified template + ["12:30", "18:40"] + $[*].datetime("HH24:MI") + "12:30:00", "18:40:00" + + + keyvalue() + + Sequence of object's key-value pairs represented as array of items + containing three fields ("key", + "value", and "id"). + "id" is a unique identifier of the object + key-value pair belongs to. + + {"x": "20", "y": 32} + $.keyvalue() + {"key": "x", "value": "20", "id": 0}, {"key": "y", "value": 32, "id": 0} + + + +
+ + + + The result type of datetime() and + datetime(template) + methods can be date, timetz, time, + timestamptz, or timestamp. + Both methods determine the result type dynamically. + + + The datetime() method sequentially tries ISO formats + for date, timetz, time, + timestamptz, and timestamp. It stops on + the first matching format and the corresponding data type. + + + The datetime(template) + method determines the result type by the provided template string. + + + The datetime() and + datetime(template) methods + use the same parsing rules as to_timestamp SQL + function does (see ) with three + exceptions. At first, these methods doesn't allow unmatched template + patterns. At second, only following separators are allowed in the + template string: minus sign, period, solidus, comma, apostrophe, + semicolon, colon and space. At third, separators in the template string + must exactly match the input string. + + + + + <type>jsonpath</type> Filter Expression Elements + + + + Value/Predicate + Description + Example JSON + Example Query + Result + + + + + == + Equality operator + [1, 2, 1, 3] + $[*] ? (@ == 1) + 1, 1 + + + != + Non-equality operator + [1, 2, 1, 3] + $[*] ? (@ != 1) + 2, 3 + + + <> + Non-equality operator (same as !=) + [1, 2, 1, 3] + $[*] ? (@ <> 1) + 2, 3 + + + < + Less-than operator + [1, 2, 3] + $[*] ? (@ < 2) + 1 + + + <= + Less-than-or-equal-to operator + [1, 2, 3] + $[*] ? (@ <= 2) + 1, 2 + + + > + Greater-than operator + [1, 2, 3] + $[*] ? (@ > 2) + 3 + + + >= + Greater-than-or-equal-to operator + [1, 2, 3] + $[*] ? (@ >= 2) + 2, 3 + + + true + Value used to perform comparison with JSON true literal + [{"name": "John", "parent": false}, + {"name": "Chris", "parent": true}] + $[*] ? (@.parent == true) + {"name": "Chris", "parent": true} + + + false + Value used to perform comparison with JSON false literal + [{"name": "John", "parent": false}, + {"name": "Chris", "parent": true}] + $[*] ? (@.parent == false) + {"name": "John", "parent": false} + + + null + Value used to perform comparison with JSON null value + [{"name": "Mary", "job": null}, + {"name": "Michael", "job": "driver"}] + $[*] ? (@.job == null) .name + "Mary" + + + && + Boolean AND + [1, 3, 7] + $[*] ? (@ > 1 && @ < 5) + 3 + + + || + Boolean OR + [1, 3, 7] + $[*] ? (@ < 1 || @ > 5) + 7 + + + ! + Boolean NOT + [1, 3, 7] + $[*] ? (!(@ < 5)) + 7 + + + like_regex + + Tests whether the first operand matches the regular expression + given by the second operand, optionally with modifications + described by a string of flag characters (see + ) + + ["abc", "abd", "aBdC", "abdacb", "babc"] + $[*] ? (@ like_regex "^ab.*c" flag "i") + "abc", "aBdC", "abdacb" + + + starts with + Tests whether the second operand is an initial substring of the first operand + ["John Smith", "Mary Stone", "Bob Johnson"] + $[*] ? (@ starts with "John") + "John Smith" + + + exists + Tests whether a path expression matches at least one SQL/JSON item + {"x": [1, 2], "y": [2, 4]} + strict $.* ? (exists (@ ? (@[*] > 2))) + 2, 4 + + + is unknown + Tests whether a Boolean condition is unknown + [-1, 2, 7, "infinity"] + $[*] ? ((@ > 0) is unknown) + "infinity" + + + +
+ + + When different date/time values are compared, an implicit cast is + applied. A date value can be cast to timestamp + or timestamptz, timestamp can be cast to + timestamptz, and time — to timetz. + + +
+
@@ -12346,11 +13833,20 @@ SELECT setval('foo', 42, false); Next nextval If your needs go beyond the capabilities of these conditional - expressions, you might want to consider writing a stored procedure + expressions, you might want to consider writing a server-side function in a more expressive programming language. + + + Although COALESCE, GREATEST, and + LEAST are syntactically similar to functions, they are + not ordinary functions, and thus cannot be used with explicit + VARIADIC array arguments. + + + <literal>CASE</literal> @@ -12646,14 +14142,14 @@ SELECT NULLIF(value, '(none)') ... @> contains - ARRAY[1,4,3] @> ARRAY[3,1] + ARRAY[1,4,3] @> ARRAY[3,1,3] t <@ is contained by - ARRAY[2,7] <@ ARRAY[1,7,4,2,6] + ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6] t @@ -12696,8 +14192,10 @@ SELECT NULLIF(value, '(none)') ... - Array comparisons compare the array contents element-by-element, - using the default B-tree comparison function for the element data type. + The array ordering operators (<, + >=, etc) compare the array contents + element-by-element, using the default B-tree comparison function for + the element data type, and sort based on the first difference. In multidimensional arrays the elements are visited in row-major order (last subscript varies most rapidly). If the contents of two arrays are equal but the dimensionality is @@ -12708,6 +14206,15 @@ SELECT NULLIF(value, '(none)') ... number of dimensions or subscript ranges were different.) + + The array containment operators (<@ + and @>) consider one array to be contained in + another one if each of its elements appears in the other one. + Duplicates are not treated specially, thus ARRAY[1] + and ARRAY[1,1] are each considered to contain the + other. + + See for more details about array operator behavior. See for more details about @@ -13446,7 +14953,7 @@ NULL baz(3 rows) No input arrays concatenated into array of one higher dimension (inputs must all have same dimensionality, - and cannot be empty or NULL) + and cannot be empty or null) @@ -13470,7 +14977,7 @@ NULL baz(3 rows) otherwise the same as the argument data type Yes - the average (arithmetic mean) of all input values + the average (arithmetic mean) of all non-null input values @@ -13598,7 +15105,7 @@ NULL baz(3 rows) json No - aggregates values as a JSON array + aggregates values, including nulls, as a JSON array @@ -13615,7 +15122,7 @@ NULL baz(3 rows) jsonb No - aggregates values as a JSON array + aggregates values, including nulls, as a JSON array @@ -13632,7 +15139,8 @@ NULL baz(3 rows) json No - aggregates name/value pairs as a JSON object + aggregates name/value pairs as a JSON object; values can be + null, but not names @@ -13649,7 +15157,8 @@ NULL baz(3 rows) jsonb No - aggregates name/value pairs as a JSON object + aggregates name/value pairs as a JSON object; values can be + null, but not names @@ -13659,13 +15168,13 @@ NULL baz(3 rows) max(expression) - any numeric, string, date/time, network, or enum type, + any numeric, string, date/time, network, pg_lsn, or enum type, or arrays of these types same as argument type Yes maximum value of expression across all input + class="parameter">expression across all non-null input values @@ -13677,13 +15186,13 @@ NULL baz(3 rows) min(expression) - any numeric, string, date/time, network, or enum type, + any numeric, string, date/time, network, pg_lsn, or enum type, or arrays of these types same as argument type Yes minimum value of expression across all input + class="parameter">expression across all non-null input values @@ -13705,7 +15214,7 @@ NULL baz(3 rows) same as argument types No - input values concatenated into a string, separated by delimiter + non-null input values concatenated into a string, separated by delimiter @@ -13728,7 +15237,8 @@ NULL baz(3 rows) argument data type Yes - sum of expression across all input values + sum of expression + across all non-null input values @@ -13745,7 +15255,8 @@ NULL baz(3 rows) xml No - concatenation of XML values (see also ) + concatenation of non-null XML values + (see also ) @@ -15168,8 +16679,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); The result is false if the comparison returns false for every subquery row (including the case where the subquery returns no rows). - The result is NULL if the comparison does not return true for any row, - and it returns NULL for at least one row. + The result is NULL if no comparison with a subquery row returns true, + and at least one comparison returns NULL. @@ -15194,8 +16705,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); The result of ALL is true if all rows yield true (including the case where the subquery returns no rows). The result is false if any false result is found. - The result is NULL if the comparison does not return false for any row, - and it returns NULL for at least one row. + The result is NULL if no comparison with a subquery row returns false, + and at least one comparison returns NULL. @@ -15224,8 +16735,8 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); case where the subquery returns no rows). The result is false if the comparison returns false for any subquery row. - The result is NULL if the comparison does not return false for any - subquery row, and it returns NULL for at least one row. + The result is NULL if no comparison with a subquery row returns false, + and at least one comparison returns NULL. @@ -15235,7 +16746,7 @@ WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2); - Single-row Comparison + Single-Row Comparison comparison @@ -15884,7 +17395,7 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); - System Information Functions + System Information Functions and Operators shows several @@ -16280,7 +17791,7 @@ SET search_path TO schema , sc optional parameter. The return value is NULL when the log format requested is not a configured . The - pg_current_logfiles reflects the contents of the + pg_current_logfile reflects the contents of the current_logfiles file. @@ -16349,7 +17860,7 @@ SET search_path TO schema , sc because it needs access to the predicate lock manager's shared state for a short time. - + version @@ -16360,7 +17871,7 @@ SET search_path TO schema , sc get this information from or for a machine-readable version, . Software developers should use server_version_num - (available since 8.2) or instead + (available since 8.2) or instead of parsing the text version. @@ -16815,6 +18326,130 @@ SELECT has_function_privilege('joeuser', 'myfunc(int, text)', 'execute'); be specified by name or by OID. + + shows the operators + available for the aclitem type, which is the catalog + representation of access privileges. See + for information about how to read access privilege values. + + + + acldefault + + + aclitemeq + + + aclcontains + + + aclexplode + + + makeaclitem + + + + <type>aclitem</type> Operators + + + + Operator + Description + Example + Result + + + + + + = + equal + 'calvin=r*w/hobbes'::aclitem = 'calvin=r*w*/hobbes'::aclitem + f + + + + @> + contains element + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] @> 'calvin=r*w/hobbes'::aclitem + t + + + + ~ + contains element + '{calvin=r*w/hobbes,hobbes=r*w*/postgres}'::aclitem[] ~ 'calvin=r*w/hobbes'::aclitem + t + + + + +
+ + + shows some additional + functions to manage the aclitem type. + + + + <type>aclitem</type> Functions + + + Name Return Type Description + + + + acldefault(type, + ownerId) + aclitem[] + get the default access privileges for an object belonging to ownerId + + + aclexplode(aclitem[]) + setof record + get aclitem array as tuples + + + makeaclitem(grantee, grantor, privilege, grantable) + aclitem + build an aclitem from input + + + +
+ + + acldefault returns the built-in default access + privileges for an object of type type belonging to + role ownerId. These represent the access + privileges that will be assumed when an object's ACL entry is null. + (The default access privileges are described in .) + The type parameter is a CHAR: write + 'c' for COLUMN, + 'r' for TABLE and table-like objects, + 's' for SEQUENCE, + 'd' for DATABASE, + 'f' for FUNCTION or PROCEDURE, + 'l' for LANGUAGE, + 'L' for LARGE OBJECT, + 'n' for SCHEMA, + 't' for TABLESPACE, + 'F' for FOREIGN DATA WRAPPER, + 'S' for FOREIGN SERVER, + or + 'T' for TYPE or DOMAIN. + + + + aclexplode returns an aclitem array + as a set of rows. Output columns are grantor oid, + grantee oid (0 for PUBLIC), + granted privilege as text (SELECT, ...) + and whether the privilege is grantable as boolean. + makeaclitem performs the inverse operation. + + shows functions that determine whether a certain object is visible in the @@ -17519,7 +19154,9 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id')); backward_scan - Can the index be scanned backwards? + Can the scan direction be changed in mid-scan (to + support FETCH BACKWARD on a cursor without + needing materialization)? @@ -17674,24 +19311,24 @@ SELECT collation for ('foo' COLLATE "de_DE"); - pg_describe_object(catalog_id, object_id, object_sub_id) + pg_describe_object(classid oid, objid oid, objsubid integer) text get description of a database object - pg_identify_object(catalog_id oid, object_id oid, object_sub_id integer) + pg_identify_object(classid oid, objid oid, objsubid integer) type text, schema text, name text, identity text get identity of a database object - pg_identify_object_as_address(catalog_id oid, object_id oid, object_sub_id integer) - type text, name text[], args text[] + pg_identify_object_as_address(classid oid, objid oid, objsubid integer) + type text, object_names text[], object_args text[] get external representation of a database object's address - pg_get_object_address(type text, name text[], args text[]) - catalog_id oid, object_id oid, object_sub_id int32 - get address of a database object, from its external representation + pg_get_object_address(type text, object_names text[], object_args text[]) + classid oid, objid oid, objsubid integer + get address of a database object from its external representation @@ -17699,7 +19336,9 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_describe_object returns a textual description of a database - object specified by catalog OID, object OID and a (possibly zero) sub-object ID. + object specified by catalog OID, object OID, and sub-object ID (such as + a column number within a table; the sub-object ID is zero when referring + to a whole object). This description is intended to be human-readable, and might be translated, depending on server configuration. This is useful to determine the identity of an object as stored in the @@ -17708,29 +19347,30 @@ SELECT collation for ('foo' COLLATE "de_DE"); pg_identify_object returns a row containing enough information - to uniquely identify the database object specified by catalog OID, object OID and a - (possibly zero) sub-object ID. This information is intended to be machine-readable, + to uniquely identify the database object specified by catalog OID, object OID and + sub-object ID. This information is intended to be machine-readable, and is never translated. type identifies the type of database object; schema is the schema name that the object belongs in, or NULL for object types that do not belong to schemas; - name is the name of the object, quoted if necessary, only - present if it can be used (alongside schema name, if pertinent) as a unique - identifier of the object, otherwise NULL; - identity is the complete object identity, with the precise format - depending on object type, and each part within the format being - schema-qualified and quoted as necessary. + name is the name of the object, quoted if necessary, + if the name (along with schema name, if pertinent) is sufficient to + uniquely identify the object, otherwise NULL; + identity is the complete object identity, with the + precise format depending on object type, and each name within the format + being schema-qualified and quoted as necessary. pg_identify_object_as_address returns a row containing enough information to uniquely identify the database object specified by - catalog OID, object OID and a (possibly zero) sub-object ID. The returned + catalog OID, object OID and sub-object ID. The returned information is independent of the current server, that is, it could be used to identify an identically named object in another server. type identifies the type of database object; - name and args are text arrays that together - form a reference to the object. These three columns can be passed to + object_names and object_args + are text arrays that together form a reference to the object. + These three values can be passed to pg_get_object_address to obtain the internal address of the object. This function is the inverse of pg_get_object_address. @@ -17743,10 +19383,10 @@ SELECT collation for ('foo' COLLATE "de_DE"); ones that would be used in system catalogs such as pg_depend and can be passed to other system functions such as pg_identify_object or pg_describe_object. - catalog_id is the OID of the system catalog containing the + classid is the OID of the system catalog containing the object; - object_id is the OID of the object itself, and - object_sub_id is the object sub-ID, or zero if none. + objid is the OID of the object itself, and + objsubid is the sub-object ID, or zero if none. This function is the inverse of pg_identify_object_as_address. @@ -17917,7 +19557,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); txid_status(bigint) - txid_status + text report the status of the given transaction: committed, aborted, in progress, or null if the transaction ID is too old @@ -18017,7 +19657,7 @@ SELECT collation for ('foo' COLLATE "de_DE"); - Committed transaction information + Committed Transaction Information Name Return Type Description @@ -18658,6 +20298,8 @@ SELECT set_config('log_statement_stats', 'off', false); The functions shown in assist in making on-line backups. These functions cannot be executed during recovery (except + non-exclusive pg_start_backup, + non-exclusive pg_stop_backup, pg_is_in_backup, pg_backup_start_time and pg_wal_lsn_diff). @@ -18839,7 +20481,7 @@ postgres=# select pg_start_backup('label_goes_here'); pg_create_restore_point creates a named write-ahead log record that can be used as recovery target, and returns the corresponding write-ahead log location. The given name can then be used with - to specify the point up to which + to specify the point up to which recovery will proceed. Avoid creating multiple restore points with the same name, since recovery will stop at the first one whose name matches the recovery target. @@ -18984,6 +20626,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); pg_is_wal_replay_paused + + pg_promote + pg_wal_replay_pause @@ -19014,6 +20659,24 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); True if recovery is paused. + + + pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) + + boolean + + Promotes a physical standby server. With wait + set to true (the default), the function waits until + promotion is completed or wait_seconds seconds + have passed, and returns true if promotion is + successful and false otherwise. + If wait is set to false, the + function returns true immediately after sending + SIGUSR1 to the postmaster to trigger the promotion. + This function is restricted to superusers by default, but other users + can be granted EXECUTE to run the function. + + pg_wal_replay_pause() @@ -19137,8 +20800,10 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); See , , and - for information about the underlying features. Use of these - functions is restricted to superusers. + for information about the underlying features. + Use of functions for replication origin is restricted to superusers. + Use of functions for replication slot is restricted to superusers + and users having REPLICATION privilege. @@ -19233,6 +20898,47 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); + + + + pg_copy_physical_replication_slot + + pg_copy_physical_replication_slot(src_slot_name name, dst_slot_name name , temporary boolean) + + + (slot_name name, lsn pg_lsn) + + + Copies an existing physical replication slot named src_slot_name + to a physical replication slot named dst_slot_name. + The copied physical slot starts to reserve WAL from the same LSN as the + source slot. + temporary is optional. If temporary + is omitted, the same value as the source slot is used. + + + + + + + pg_copy_logical_replication_slot + + pg_copy_logical_replication_slot(src_slot_name name, dst_slot_name name , temporary boolean , plugin name) + + + (slot_name name, lsn pg_lsn) + + + Copies an existing logical replication slot name src_slot_name + to a logical replication slot named dst_slot_name + while changing the output plugin and persistence. The copied logical slot starts + from the same LSN as the source logical slot. Both + temporary and plugin are optional. + If temporary or plugin are omitted, + the same values as the source logical slot are used. + + + @@ -19979,6 +21685,74 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); The function returns the number of new collation objects it created. +
+ Partitioning Information Functions + + + Name Return Type Description + + + + + + pg_partition_tree + pg_partition_tree(regclass) + + setof record + + List information about tables or indexes in a partition tree for a + given partitioned table or partitioned index, with one row for each + partition. Information provided includes the name of the partition, + the name of its immediate parent, a boolean value telling if the + partition is a leaf, and an integer telling its level in the hierarchy. + The value of level begins at 0 for the input table + or index in its role as the root of the partition tree, + 1 for its partitions, 2 for + their partitions, and so on. + + + + + pg_partition_ancestors + pg_partition_ancestors(regclass) + + setof regclass + + List the ancestor relations of the given partition, + including the partition itself. + + + + + pg_partition_root + pg_partition_root(regclass) + + regclass + + Return the top-most parent of a partition tree to which the given + relation belongs. + + + + +
+ + + To check the total size of the data contained in + measurement table described in + , one could use the + following query: + + + +=# SELECT pg_size_pretty(sum(pg_relation_size(relid))) AS total_size + FROM pg_partition_tree('measurement'); + total_size +------------ + 24 kB +(1 row) + + @@ -20087,8 +21861,8 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
- Note that granting users the EXECUTE privilege on the - pg_read_file(), or related, functions allows them the + Note that granting users the EXECUTE privilege on + pg_read_file(), or related functions, allows them the ability to read any file on the server which the database can read and that those reads bypass all in-database privilege checks. This means that, among other things, a user with this access is able to read the contents of the @@ -20137,6 +21911,32 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); role and may be granted to other non-superuser roles. + + + pg_ls_archive_statusdir() + + setof record + + List the name, size, and last modification time of files in the WAL + archive status directory. Access is granted to members of the + pg_monitor role and may be granted to other + non-superuser roles. + + + + + pg_ls_tmpdir(tablespace oid) + + setof record + + List the name, size, and last modification time of files in the + temporary directory for tablespace. If + tablespace is not provided, the + pg_default tablespace is used. Access is granted + to members of the pg_monitor role and may be + granted to other non-superuser roles. + + pg_read_file(filename text [, offset bigint, length bigint [, missing_ok boolean] ]) @@ -20210,6 +22010,31 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup()); GRANT. + + pg_ls_archive_statusdir + + + pg_ls_archive_statusdir returns the name, size, and + last modified time (mtime) of each file in the WAL archive status + directory pg_wal/archive_status. By default only + superusers and members of the pg_monitor role can + use this function. Access may be granted to others using + GRANT. + + + + pg_ls_tmpdir + + + pg_ls_tmpdir returns the name, size, and last modified + time (mtime) of each file in the temporary file directory for the specified + tablespace. If tablespace is + not provided, the pg_default tablespace is used. By + default only superusers and members of the pg_monitor + role can use this function. Access may be granted to others using + GRANT. + + pg_read_file @@ -20578,7 +22403,7 @@ SELECT (pg_stat_file('filename')).modification; CREATE TRIGGER z_min_update BEFORE UPDATE ON tablename -FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); +FOR EACH ROW EXECUTE FUNCTION suppress_redundant_updates_trigger(); In most cases, you would want to fire this trigger last for each row. Bearing in mind that triggers fire in name order, you would then @@ -20635,23 +22460,23 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); classid - Oid + oid OID of catalog the object belongs in objid - Oid - OID of the object in the catalog + oid + OID of the object itself objsubid integer - Object sub-id (e.g. attribute number for columns) + Sub-object ID (e.g. attribute number for a column) command_tag text - command tag + Command tag object_type @@ -20670,14 +22495,14 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); object_identity text - Text rendering of the object identity, schema-qualified. Each and every - identifier present in the identity is quoted if necessary. + Text rendering of the object identity, schema-qualified. Each + identifier included in the identity is quoted if necessary. in_extension bool - whether the command is part of an extension script + True if the command is part of an extension script command @@ -20722,29 +22547,29 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); classid - Oid + oid OID of catalog the object belonged in objid - Oid - OID the object had within the catalog + oid + OID of the object itself objsubid - int32 - Object sub-id (e.g. attribute number for columns) + integer + Sub-object ID (e.g. attribute number for a column) original bool - Flag used to identify the root object(s) of the deletion + True if this was one of the root object(s) of the deletion normal bool - Flag indicating that there's a normal dependency relationship + True if there was a normal dependency relationship in the dependency graph leading to this object @@ -20752,7 +22577,7 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); is_temporary bool - Flag indicating that the object was a temporary object. + True if this was a temporary object @@ -20781,8 +22606,8 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); object_identity text - Text rendering of the object identity, schema-qualified. Each and every - identifier present in the identity is quoted if necessary. + Text rendering of the object identity, schema-qualified. Each + identifier included in the identity is quoted if necessary. @@ -20790,17 +22615,17 @@ FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); text[] An array that, together with object_type and - address_args, - can be used by the pg_get_object_address() to + address_args, can be used by + the pg_get_object_address() function to recreate the object address in a remote server containing an - identically named object of the same kind. + identically named object of the same kind address_args text[] - Complement for address_names above. + Complement for address_names @@ -20830,7 +22655,7 @@ END $$; CREATE EVENT TRIGGER test_event_trigger_for_drops ON sql_drop - EXECUTE PROCEDURE test_event_trigger_for_drops(); + EXECUTE FUNCTION test_event_trigger_for_drops();
@@ -20847,7 +22672,7 @@ CREATE EVENT TRIGGER test_event_trigger_for_drops - Table Rewrite information + Table Rewrite Information Name Return Type Description @@ -20895,10 +22720,92 @@ $$; CREATE EVENT TRIGGER test_table_rewrite_oid ON table_rewrite - EXECUTE PROCEDURE test_event_trigger_table_rewrite_oid(); + EXECUTE FUNCTION test_event_trigger_table_rewrite_oid(); + + Statistics Information Functions + + + function + statistics + + + + PostgreSQL provides a function to inspect complex + statistics defined using the CREATE STATISTICS command. + + + + Inspecting MCV Lists + + + pg_mcv_list_items + pg_mcv_list + + + + pg_mcv_list_items returns a list of all items + stored in a multi-column MCV list, and returns the + following columns: + + + + + + Name + Type + Description + + + + + + index + int + index of the item in the MCV list + + + values + text[] + values stored in the MCV item + + + nulls + boolean[] + flags identifying NULL values + + + frequency + double precision + frequency of this MCV item + + + base_frequency + double precision + base frequency of this MCV item + + + + + + + + The pg_mcv_list_items function can be used like this: + + +SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts'; + + + Values of the pg_mcv_list can be obtained only from the + pg_statistic_ext_data.stxdmcv column. + + + + + diff --git a/doc/src/sgml/generate-errcodes-table.pl b/doc/src/sgml/generate-errcodes-table.pl index ebec43159e2..24b9d891c3b 100644 --- a/doc/src/sgml/generate-errcodes-table.pl +++ b/doc/src/sgml/generate-errcodes-table.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate the errcodes-table.sgml file from errcodes.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; diff --git a/doc/src/sgml/generate-keywords-table.pl b/doc/src/sgml/generate-keywords-table.pl new file mode 100644 index 00000000000..e948d5fb5e9 --- /dev/null +++ b/doc/src/sgml/generate-keywords-table.pl @@ -0,0 +1,122 @@ +#!/usr/bin/perl +# +# Generate the keywords table file +# Copyright (c) 2019, PostgreSQL Global Development Group + +use strict; +use warnings; + +my @sql_versions = reverse sort ('1992', '2011', '2016'); + +my $srcdir = $ARGV[0]; + +my %keywords; + +# read SQL keywords + +foreach my $ver (@sql_versions) +{ + foreach my $res ('reserved', 'nonreserved') + { + foreach my $file (glob "$srcdir/keywords/sql${ver}*-${res}.txt") + { + open my $fh, '<', $file or die; + + while (<$fh>) + { + chomp; + $keywords{$_}{$ver}{$res} = 1; + } + + close $fh; + } + } +} + +# read PostgreSQL keywords + +open my $fh, '<', "$srcdir/../../../src/include/parser/kwlist.h" or die; + +while (<$fh>) +{ + if (/^PG_KEYWORD\("(\w+)", \w+, (\w+)_KEYWORD\)/) + { + $keywords{ uc $1 }{'pg'}{ lc $2 } = 1; + } +} + +close $fh; + +# print output + +print "\n"; + +print < + <acronym>SQL</acronym> Key Words + + + + + Key Word + PostgreSQL +END + +foreach my $ver (@sql_versions) +{ + my $s = ($ver eq '1992' ? 'SQL-92' : "SQL:$ver"); + print " $s\n"; +} + +print < + + + +END + +foreach my $word (sort keys %keywords) +{ + print " \n"; + print " $word\n"; + + print " "; + if ($keywords{$word}{pg}{'unreserved'}) + { + print "non-reserved"; + } + elsif ($keywords{$word}{pg}{'col_name'}) + { + print "non-reserved (cannot be function or type)"; + } + elsif ($keywords{$word}{pg}{'type_func_name'}) + { + print "reserved (can be function or type)"; + } + elsif ($keywords{$word}{pg}{'reserved'}) + { + print "reserved"; + } + print "\n"; + + foreach my $ver (@sql_versions) + { + print " "; + if ($keywords{$word}{$ver}{'reserved'}) + { + print "reserved"; + } + elsif ($keywords{$word}{$ver}{'nonreserved'}) + { + print "non-reserved"; + } + print "\n"; + } + print " \n"; +} + +print < + +
+END diff --git a/doc/src/sgml/geqo.sgml b/doc/src/sgml/geqo.sgml index 5120dfbb424..39d2163d160 100644 --- a/doc/src/sgml/geqo.sgml +++ b/doc/src/sgml/geqo.sgml @@ -84,9 +84,19 @@ Through simulation of the evolutionary operations recombination, mutation, and selection new generations of search points are found - that show a higher average fitness than their ancestors. + that show a higher average fitness than their ancestors. + illustrates these steps. +
+ Structure of a Genetic Algorithm + + + + + +
+ According to the comp.ai.genetic FAQ it cannot be stressed too strongly that a GA is not a pure random search for a solution to a @@ -94,49 +104,6 @@ non-random (better than random). -
- Structured Diagram of a Genetic Algorithm - - - - - - P(t) - generation of ancestors at a time t - - - - P''(t) - generation of descendants at a time t - - - - - - -+=========================================+ -|>>>>>>>>>>> Algorithm GA <<<<<<<<<<<<<<| -+=========================================+ -| INITIALIZE t := 0 | -+=========================================+ -| INITIALIZE P(t) | -+=========================================+ -| evaluate FITNESS of P(t) | -+=========================================+ -| while not STOPPING CRITERION do | -| +-------------------------------------+ -| | P'(t) := RECOMBINATION{P(t)} | -| +-------------------------------------+ -| | P''(t) := MUTATION{P'(t)} | -| +-------------------------------------+ -| | P(t+1) := SELECTION{P''(t) + P(t)} | -| +-------------------------------------+ -| | evaluate FITNESS of P''(t) | -| +-------------------------------------+ -| | t := t + 1 | -+===+=====================================+ - -
diff --git a/doc/src/sgml/gin.sgml b/doc/src/sgml/gin.sgml index cc7cd1ed2c4..0182b445855 100644 --- a/doc/src/sgml/gin.sgml +++ b/doc/src/sgml/gin.sgml @@ -102,6 +102,8 @@ ?& ?| @> + @? + @@ @@ -109,6 +111,8 @@ jsonb @> + @? + @@ @@ -223,7 +227,7 @@ pmatch is an output argument for use when partial match is supported. To use it, extractQuery must allocate - an array of *nkeys bools and store its address at + an array of *nkeys bools and store its address at *pmatch. Each element of the array should be set to true if the corresponding key requires partial match, false if not. If *pmatch is set to NULL then GIN assumes partial match @@ -251,12 +255,12 @@ An operator class must also provide a function to check if an indexed item - matches the query. It comes in two flavors, a boolean consistent + matches the query. It comes in two flavors, a Boolean consistent function, and a ternary triConsistent function. triConsistent covers the functionality of both, so providing - triConsistent alone is sufficient. However, if the boolean + triConsistent alone is sufficient. However, if the Boolean variant is significantly cheaper to calculate, it can be advantageous to - provide both. If only the boolean variant is provided, some optimizations + provide both. If only the Boolean variant is provided, some optimizations that depend on refuting index items before fetching all the keys are disabled. @@ -319,11 +323,11 @@ triConsistent is similar to consistent, - but instead of booleans in the check vector, there are + but instead of Booleans in the check vector, there are three possible values for each key: GIN_TRUE, GIN_FALSE and GIN_MAYBE. GIN_FALSE and GIN_TRUE - have the same meaning as regular boolean values, while + have the same meaning as regular Boolean values, while GIN_MAYBE means that the presence of that key is not known. When GIN_MAYBE values are present, the function should only return GIN_TRUE if the item certainly matches whether or @@ -338,7 +342,7 @@ When there are no GIN_MAYBE values in the check vector, a GIN_MAYBE return value is the equivalent of setting the recheck flag in the - boolean consistent function. + Boolean consistent function. @@ -436,7 +440,8 @@ page contains either a pointer to a B-tree of heap pointers (a posting tree), or a simple list of heap pointers (a posting list) when the list is small enough to fit into a single index tuple along - with the key value. + with the key value. illustrates + these components of a GIN index. @@ -453,6 +458,15 @@ key values for different columns can be of different types. +
+ GIN Internals + + + + + +
+ GIN Fast Update Technique diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml index 44a3b2c03c5..a7eec1e9497 100644 --- a/doc/src/sgml/gist.sgml +++ b/doc/src/sgml/gist.sgml @@ -83,6 +83,7 @@ ~= + <->
@@ -696,8 +697,8 @@ my_picksplit(PG_FUNCTION_ARGS) /* * Choose where to put the index entries and update unionL and unionR - * accordingly. Append the entries to either v_spl_left or - * v_spl_right, and care about the counters. + * accordingly. Append the entries to either v->spl_left or + * v->spl_right, and care about the counters. */ if (my_choice_is_left(unionL, curl, unionR, curr)) @@ -910,7 +911,7 @@ Datum my_fetch(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - input_data_type *in = DatumGetP(entry->key); + input_data_type *in = DatumGetPointer(entry->key); fetched_data_type *fetched_data; GISTENTRY *retval; @@ -921,7 +922,7 @@ my_fetch(PG_FUNCTION_ARGS) * Convert 'fetched_data' into the a Datum of the original datatype. */ - /* fill *retval from fetch_data. */ + /* fill *retval from fetched_data. */ gistentryinit(*retval, PointerGetDatum(converted_datum), entry->rel, entry->page, entry->offset, FALSE); @@ -960,7 +961,7 @@ my_fetch(PG_FUNCTION_ARGS) Implementation - GiST buffering build + GiST Buffering Build Building large GiST indexes by simply inserting all the tuples tends to be slow, because if the index tuples are scattered across the index and the diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml index 46bf198a2ac..43bcb2a6efd 100644 --- a/doc/src/sgml/high-availability.sgml +++ b/doc/src/sgml/high-availability.sgml @@ -618,7 +618,7 @@ protocol to make nodes agree on a serializable transactional order. In standby mode, the server continuously applies WAL received from the master server. The standby server can read WAL from a WAL archive - (see ) or directly from the master + (see ) or directly from the master over a TCP connection (streaming replication). The standby server will also attempt to restore any WAL found in the standby cluster's pg_wal directory. That typically happens after a server @@ -645,7 +645,7 @@ protocol to make nodes agree on a serializable transactional order. Standby mode is exited and the server switches to normal operation when pg_ctl promote is run or a trigger file is found - (trigger_file). Before failover, + (promote_trigger_file). Before failover, any WAL immediately available in the archive or in pg_wal will be restored, but no attempt is made to connect to the master. @@ -686,20 +686,19 @@ protocol to make nodes agree on a serializable transactional order. To set up the standby server, restore the base backup taken from primary - server (see ). Create a recovery - command file recovery.conf in the standby's cluster data - directory, and turn on standby_mode. Set - restore_command to a simple command to copy files from + server (see ). Create a file + standby.signal in the standby's cluster data + directory. Set to a simple command to copy files from the WAL archive. If you plan to have multiple standby servers for high - availability purposes, set recovery_target_timeline to - latest, to make the standby server follow the timeline change + availability purposes, make sure that recovery_target_timeline is set to + latest (the default), to make the standby server follow the timeline change that occurs at failover to another standby. Do not use pg_standby or similar tools with the built-in standby mode - described here. restore_command should return immediately + described here. should return immediately if the file does not exist; the server will retry the command again if necessary. See for using tools like pg_standby. @@ -708,11 +707,11 @@ protocol to make nodes agree on a serializable transactional order. If you want to use streaming replication, fill in - primary_conninfo with a libpq connection string, including + with a libpq connection string, including the host name (or IP address) and any additional details needed to connect to the primary server. If the primary needs a password for authentication, the password needs to be specified in - primary_conninfo as well. + as well. @@ -724,7 +723,7 @@ protocol to make nodes agree on a serializable transactional order. If you're using a WAL archive, its size can be minimized using the parameter to remove files that are no + linkend="guc-archive-cleanup-command"/> parameter to remove files that are no longer required by the standby server. The pg_archivecleanup utility is designed specifically to be used with archive_cleanup_command in typical single-standby @@ -735,10 +734,9 @@ protocol to make nodes agree on a serializable transactional order. - A simple example of a recovery.conf is: + A simple example of configuration is: -standby_mode = 'on' -primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' +primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass options=''-c wal_sender_timeout=5000''' restore_command = 'cp /path/to/archive/%f %p' archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' @@ -793,8 +791,8 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r' To use streaming replication, set up a file-based log-shipping standby server as described in . The step that turns a file-based log-shipping standby into streaming replication - standby is setting primary_conninfo setting in the - recovery.conf file to point to the primary server. Set + standby is setting the primary_conninfo setting + to point to the primary server. Set and authentication options (see pg_hba.conf) on the primary so that the standby server can connect to the replication pseudo-database on the primary @@ -854,14 +852,14 @@ host replication foo 192.168.1.100/32 md5 The host name and port number of the primary, connection user name, - and password are specified in the recovery.conf file. + and password are specified in the . The password can also be set in the ~/.pgpass file on the standby (specify replication in the database field). For example, if the primary is running on host IP 192.168.1.50, port 5432, the account name for replication is foo, and the password is foopass, the administrator - can add the following line to the recovery.conf file on the + can add the following line to the postgresql.conf file on the standby: @@ -940,7 +938,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' protection. Replication slots overcome these disadvantages. - Querying and manipulating replication slots + Querying and Manipulating Replication Slots Each replication slot has a name, which can contain lower-case letters, numbers, and the underscore character. @@ -966,17 +964,15 @@ postgres=# SELECT * FROM pg_create_physical_replication_slot('node_a_slot'); -------------+----- node_a_slot | -postgres=# SELECT * FROM pg_replication_slots; - slot_name | slot_type | datoid | database | active | xmin | restart_lsn | confirmed_flush_lsn --------------+-----------+--------+----------+--------+------+-------------+--------------------- - node_a_slot | physical | | | f | | | +postgres=# SELECT slot_name, slot_type, active FROM pg_replication_slots; + slot_name | slot_type | active +-------------+-----------+-------- + node_a_slot | physical | f (1 row) To configure the standby to use this slot, primary_slot_name - should be configured in the standby's recovery.conf. - Here is a simple example: + should be configured on the standby. Here is a simple example: -standby_mode = 'on' primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass' primary_slot_name = 'node_a_slot' @@ -1028,7 +1024,7 @@ primary_slot_name = 'node_a_slot' If an upstream standby server is promoted to become new master, downstream servers will continue to stream from the new master if - recovery_target_timeline is set to 'latest'. + recovery_target_timeline is set to 'latest' (the default). @@ -1324,14 +1320,14 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - If primary restarts while commits are waiting for acknowledgement, those + If primary restarts while commits are waiting for acknowledgment, those waiting transactions will be marked fully committed once the primary database recovers. There is no way to be certain that all standbys have received all outstanding WAL data at time of the crash of the primary. Some transactions may not show as committed on the standby, even though they show as committed on the primary. The guarantee we offer is that - the application will not receive explicit acknowledgement of the + the application will not receive explicit acknowledgment of the successful commit of a transaction until the WAL data is known to be safely received by all the synchronous standbys. @@ -1361,7 +1357,7 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - Continuous archiving in standby + Continuous Archiving in Standby continuous archiving @@ -1471,14 +1467,16 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' - To trigger failover of a log-shipping standby server, - run pg_ctl promote or create a trigger - file with the file name and path specified by the trigger_file - setting in recovery.conf. If you're planning to use - pg_ctl promote to fail over, trigger_file is - not required. If you're setting up the reporting servers that are - only used to offload read-only queries from the primary, not for high - availability purposes, you don't need to promote it. + To trigger failover of a log-shipping standby server, run + pg_ctl promote, call pg_promote, + or create a trigger file with the file name and path specified by the + promote_trigger_file. If you're planning to use + pg_ctl promote or to call + pg_promote to fail over, + promote_trigger_file is not required. If you're + setting up the reporting servers that are only used to offload read-only + queries from the primary, not for high availability purposes, you don't + need to promote it.
@@ -1488,11 +1486,8 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' An alternative to the built-in standby mode described in the previous sections is to use a restore_command that polls the archive location. - This was the only option available in versions 8.4 and below. In this - setup, set standby_mode off, because you are implementing - the polling required for standby operation yourself. See the - module for a reference - implementation of this. + This was the only option available in versions 8.4 and below. See the + module for a reference implementation of this. @@ -1519,12 +1514,11 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)' The magic that makes the two loosely coupled servers work together is simply a restore_command used on the standby that, when asked for the next WAL file, waits for it to become available from - the primary. The restore_command is specified in the - recovery.conf file on the standby server. Normal recovery + the primary. Normal recovery processing would request a file from the WAL archive, reporting failure if the file was unavailable. For standby processing it is normal for the next WAL file to be unavailable, so the standby must wait for - it to appear. For files ending in .backup or + it to appear. For files ending in .history there is no need to wait, and a non-zero return code must be returned. A waiting restore_command can be written as a custom script that loops after polling for the existence of @@ -1608,9 +1602,8 @@ if (!triggered) Begin recovery on the standby server from the local WAL - archive, using a recovery.conf that specifies a - restore_command that waits as described - previously (see ). + archive, using restore_command that waits + as described previously (see ). @@ -1633,7 +1626,7 @@ if (!triggered) - Record-based Log Shipping + Record-Based Log Shipping It is also possible to implement record-based log shipping using this @@ -1774,6 +1767,11 @@ if (!triggered) Plugins and extensions - LOAD + + + UNLISTEN + + @@ -1863,7 +1861,7 @@ if (!triggered) - LISTEN, UNLISTEN, NOTIFY + LISTEN, NOTIFY @@ -1871,8 +1869,8 @@ if (!triggered) In normal operation, read-only transactions are allowed to - use LISTEN, UNLISTEN, and - NOTIFY, so Hot Standby sessions operate under slightly tighter + use LISTEN and NOTIFY, + so Hot Standby sessions operate under slightly tighter restrictions than ordinary read-only sessions. It is possible that some of these restrictions might be loosened in a future release. @@ -2105,7 +2103,7 @@ if (!triggered) If hot_standby is on in postgresql.conf - (the default value) and there is a recovery.conf + (the default value) and there is a standby.signal file present, the server will run in Hot Standby mode. However, it may take some time for Hot Standby connections to be allowed, because the server will not accept connections until it has completed @@ -2179,6 +2177,11 @@ LOG: database system is ready to accept read only connections max_locks_per_transaction + + + max_wal_senders + + max_worker_processes diff --git a/doc/src/sgml/history.sgml b/doc/src/sgml/history.sgml index 59bfdb60552..180695afd94 100644 --- a/doc/src/sgml/history.sgml +++ b/doc/src/sgml/history.sgml @@ -64,9 +64,9 @@ POSTGRES has also been used as an educational tool at several universities. Finally, Illustra Information Technologies (later merged into - Informix, + Informix, which is now owned by IBM) picked up the code and + url="https://www.ibm.com/">IBM) picked up the code and commercialized it. In late 1992, POSTGRES became the primary data manager for the diff --git a/doc/src/sgml/images/Makefile b/doc/src/sgml/images/Makefile new file mode 100644 index 00000000000..f9e356348b2 --- /dev/null +++ b/doc/src/sgml/images/Makefile @@ -0,0 +1,27 @@ +# doc/src/sgml/images/Makefile +# +# see README in this directory about image handling + +ALL_IMAGES = \ + genetic-algorithm.svg \ + gin.svg \ + pagelayout.svg + +DITAA = ditaa +DOT = dot +XSLTPROC = xsltproc + +all: $(ALL_IMAGES) + +%.svg.tmp: %.gv + $(DOT) -T svg -o $@ $< + +%.svg.tmp: %.txt + $(DITAA) -E -S --svg $< $@ + +# Post-processing for SVG files coming from other tools +# +# Use --novalid to avoid loading SVG DTD if a file specifies it, since +# it might not be available locally, and we don't need it. +%.svg: %.svg.tmp fixup-svg.xsl + $(XSLTPROC) --novalid -o $@ $(word 2,$^) $< diff --git a/doc/src/sgml/images/README b/doc/src/sgml/images/README new file mode 100644 index 00000000000..07c45802553 --- /dev/null +++ b/doc/src/sgml/images/README @@ -0,0 +1,65 @@ +Images +====== + +This directory contains images for use in the documentation. + +Creating an image +----------------- + +A variety of tools can be used to create an image. The appropriate +choice depends on the nature of the image. We prefer workflows that +involve diffable source files. + +These tools are acceptable: + +- Graphviz (https://graphviz.org/) +- Ditaa (http://ditaa.sourceforge.net/) + +We use SVG as the format for integrating the image into the ultimate +output formats of the documentation, that is, HTML, PDF, and others. +Therefore, any tool used needs to be able to produce SVG. + +This directory contains makefile rules to build SVG from common input +formats, using some common styling. + +fixup-svg.xsl applies some postprocessing to the SVG files produced by +those external tools to address assorted issues. See comments in +there, and adjust and expand as necessary. + +Both the source and the SVG output file are committed in this +directory. That way, we don't need all developers to have all the +tools installed. While we accept that there could be some gratuitous +diffs in the SVG output depending the specific tool, let's keep an eye +on that and keep it to a minimum. + +Using an image in DocBook +------------------------- + +Here is an example for using an image in DocBook: + +
+ GIN Internals + + + + + +
+ +Notes: + +- The real action is in the element, but typically a +
should be wrapped around it and an to the figure + should be put into the text somewhere. Don't just put an image into + the documentation without a link to it and an explanation of it. + +- Things are set up so that we only need one element, even + with different output formats. + +- The attribute format="SVG" is required. If you omit it, it will + still appear to work, but the stylesheets do a better job if the + image is declared as SVG explicitly. + +- The width should be set to something. This ensures that the image + is scaled to fit the page in PDF output. (Other widths than 100% + might be appropriate.) diff --git a/doc/src/sgml/images/fixup-svg.xsl b/doc/src/sgml/images/fixup-svg.xsl new file mode 100644 index 00000000000..d6c46b362e0 --- /dev/null +++ b/doc/src/sgml/images/fixup-svg.xsl @@ -0,0 +1,44 @@ + + + + + + + + + + + 0 0 + + + + + + + + + + + + none + + + + + + + + + + diff --git a/doc/src/sgml/images/genetic-algorithm.gv b/doc/src/sgml/images/genetic-algorithm.gv new file mode 100644 index 00000000000..80c354c2c8b --- /dev/null +++ b/doc/src/sgml/images/genetic-algorithm.gv @@ -0,0 +1,48 @@ +digraph { + layout=dot; + + // default values + node [shape=box, label="", fontname="sans-serif", style=filled, fillcolor=white, fontsize=8]; + graph [fontname="sans-serif"]; // must be specified separately + edge [fontname="sans-serif"]; // must be specified separately + + // an unobtrusive background color + pad="1.0, 0.5"; + bgcolor=whitesmoke; + + // layout of edges and nodes + splines=ortho; + nodesep=0.3; + ranksep=0.3; + + // nodes + a1[label="INITIALIZE t := 0"]; + a2[label="INITIALIZE P(t)"]; + a3[label="evaluate FITNESS of P(t)"]; + a4[shape="diamond", label="STOPPING CRITERION"; width=4]; + + // connect 'end' node with 'a9' node (bottom of figure) + { + rank=same; + a9[label="t := t + 1"]; + // end-symbol similar to UML notation + end[shape=doublecircle, label="end", width=0.5]; + } + + a5[label="P'(t) := RECOMBINATION{P(t)}"]; + a6[label="P''(t) := MUTATION{P'(t)}"]; + a7[label="P(t+1) := SELECTION{P''(t) + P(t)}"]; + a8[label="evaluate FITNESS of P''(t)"]; + + // edges + a1 -> a2 -> a3 -> a4; + a4 -> a5[xlabel="false ", fontsize=10]; + a4 -> end[xlabel="true ", fontsize=10]; + a5 -> a6 -> a7 -> a8 -> a9; + a4 -> a9 [dir=back]; + + // explain the notation + expl [shape=plaintext, fontsize=10, width=3.2, fillcolor=whitesmoke, + label="P(t): generation of ancestors at a time t\lP''(t): generation of descendants at a time t\l"]; + +} diff --git a/doc/src/sgml/images/genetic-algorithm.svg b/doc/src/sgml/images/genetic-algorithm.svg new file mode 100644 index 00000000000..fb9fdd1ba78 --- /dev/null +++ b/doc/src/sgml/images/genetic-algorithm.svg @@ -0,0 +1,140 @@ + + + + + +%3 + + + +a1 + +INITIALIZE t := 0 + + + +a2 + +INITIALIZE P(t) + + + +a1->a2 + + + + + +a3 + +evaluate FITNESS of P(t) + + + +a2->a3 + + + + + +a4 + +STOPPING CRITERION + + + +a3->a4 + + + + + +a9 + +t := t + 1 + + + +a4->a9 + + + + + +end + + +end + + + +a4->end + + +true   + + + +a5 + +P'(t) := RECOMBINATION{P(t)} + + + +a4->a5 + + +false    + + + +a6 + +P''(t) := MUTATION{P'(t)} + + + +a5->a6 + + + + + +a7 + +P(t+1) := SELECTION{P''(t) + P(t)} + + + +a6->a7 + + + + + +a8 + +evaluate FITNESS of P''(t) + + + +a7->a8 + + + + + +a8->a9 + + + + + +expl + +P(t): generation of ancestors at a time t +P''(t): generation of descendants at a time t + + + diff --git a/doc/src/sgml/images/gin.gv b/doc/src/sgml/images/gin.gv new file mode 100644 index 00000000000..097e91029a4 --- /dev/null +++ b/doc/src/sgml/images/gin.gv @@ -0,0 +1,93 @@ +digraph "gin" { + layout=dot; + node [label="", shape=box, style=filled, fillcolor=gray, width=1.4]; + + m1 [label="meta page"]; + + subgraph cluster01 { + label="entry tree"; + subgraph egroup1 { + rank=same; + e1; + } + subgraph egroup2 { + rank=same; + e2 -> e3 -> e4; + } + subgraph egroup3 { + rank=same; + e5 -> e6 -> e7 -> e8 -> e9; + } + e1 -> e4; + e1 -> e3; + e1 -> e2; + e2 -> e5; + e2 -> e6; + e3 -> e7; + e4 -> e8; + e4 -> e9; + + e6 [fillcolor=green, label="posting list"]; + e8 [fillcolor=green, label="posting list"]; + e9 [fillcolor=green, label="posting list"]; + } + + subgraph cluster02 { + label="posting tree"; + subgraph pgroup1 { + rank=same; + p1; + } + subgraph pgroup2 { + rank=same; + p2 -> p3; + } + p1 -> p2; + p1 -> p3; + + p2 [fillcolor=green, label="heap ptr"]; + p3 [fillcolor=green, label="heap ptr"]; + } + + subgraph cluster03 { + label="posting tree"; + subgraph pgroup3 { + rank=same; + p4; + } + + p4 [fillcolor=green, label="heap ptr"]; + } + + subgraph cluster04 { + label="posting tree"; + subgraph pgroup4 { + rank=same; + p5; + } + subgraph pgroup5 { + rank=same; + p6 -> p7; + } + p5 -> p6; + p5 -> p7; + + p6 [fillcolor=green, label="heap ptr"]; + p7 [fillcolor=green, label="heap ptr"]; + } + + subgraph cluster05 { + label="pending list"; + node [style=filled, fillcolor=red]; + n1 -> n2 -> n3 -> n4; + } + + m1 -> e1; + e5 -> p1; + e7 -> p4; + e7 -> p5; + m1 -> n1; + + e5 [style=filled, fillcolor=green4]; + e7 [style=filled, fillcolor=green4]; +} diff --git a/doc/src/sgml/images/gin.svg b/doc/src/sgml/images/gin.svg new file mode 100644 index 00000000000..04fe85ba44e --- /dev/null +++ b/doc/src/sgml/images/gin.svg @@ -0,0 +1,317 @@ + + + + + +gin + + +cluster01 + +entry tree + + +cluster02 + +posting tree + + +cluster03 + +posting tree + + +cluster04 + +posting tree + + +cluster05 + +pending list + + + +m1 + +meta page + + + +e1 + + + + +m1->e1 + + + + + +n1 + + + + +m1->n1 + + + + + +e2 + + + + +e1->e2 + + + + + +e3 + + + + +e1->e3 + + + + + +e4 + + + + +e1->e4 + + + + + +e2->e3 + + + + + +e5 + + + + +e2->e5 + + + + + +e6 + +posting list + + + +e2->e6 + + + + + +e3->e4 + + + + + +e7 + + + + +e3->e7 + + + + + +e8 + +posting list + + + +e4->e8 + + + + + +e9 + +posting list + + + +e4->e9 + + + + + +e5->e6 + + + + + +p1 + + + + +e5->p1 + + + + + +e6->e7 + + + + + +e7->e8 + + + + + +p4 + +heap ptr + + + +e7->p4 + + + + + +p5 + + + + +e7->p5 + + + + + +e8->e9 + + + + + +p2 + +heap ptr + + + +p1->p2 + + + + + +p3 + +heap ptr + + + +p1->p3 + + + + + +p2->p3 + + + + + +p6 + +heap ptr + + + +p5->p6 + + + + + +p7 + +heap ptr + + + +p5->p7 + + + + + +p6->p7 + + + + + +n2 + + + + +n1->n2 + + + + + +n3 + + + + +n2->n3 + + + + + +n4 + + + + +n3->n4 + + + + + diff --git a/doc/src/sgml/images/pagelayout.svg b/doc/src/sgml/images/pagelayout.svg new file mode 100644 index 00000000000..5b2caaf1708 --- /dev/null +++ b/doc/src/sgml/images/pagelayout.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + PageHeaderData + Item + ItemId + ItemId + Item + Special + + diff --git a/doc/src/sgml/images/pagelayout.txt b/doc/src/sgml/images/pagelayout.txt new file mode 100644 index 00000000000..40bee5d1699 --- /dev/null +++ b/doc/src/sgml/images/pagelayout.txt @@ -0,0 +1,11 @@ ++----------------+--------+--------+--------------------+ +| PageHeaderData | ItemId | ItemId +=--------> | ++----------------+---+----+---+----+ | +| | | | +| | +-----+ | +| +--+------+ | +| | | | +| v v | +| +----------+-----------------+---------+ +| <----=+ Item | Item | Special | ++----------------+----------+-----------------+---------+ diff --git a/doc/src/sgml/indexam.sgml b/doc/src/sgml/indexam.sgml index 24c3405f918..dd54c688024 100644 --- a/doc/src/sgml/indexam.sgml +++ b/doc/src/sgml/indexam.sgml @@ -3,6 +3,14 @@ Index Access Method Interface Definition + + Index Access Method + + + indexam + Index Access Method + + This chapter defines the interface between the core PostgreSQL system and index access @@ -50,8 +58,8 @@ Each index access method is described by a row in the pg_am system catalog. The pg_am entry - specifies a name and a handler function for the access - method. These entries can be created and deleted using the + specifies a name and a handler function for the index + access method. These entries can be created and deleted using the and SQL commands. @@ -112,10 +120,10 @@ typedef struct IndexAmRoutine bool ampredlocks; /* does AM support parallel scan? */ bool amcanparallel; - /* type of data stored in index, or InvalidOid if variable */ - Oid amkeytype; /* does AM support columns included with clause INCLUDE? */ bool amcaninclude; + /* type of data stored in index, or InvalidOid if variable */ + Oid amkeytype; /* interface functions */ ambuild_function ambuild; @@ -127,6 +135,7 @@ typedef struct IndexAmRoutine amcostestimate_function amcostestimate; amoptions_function amoptions; amproperty_function amproperty; /* can be NULL */ + ambuildphasename_function ambuildphasename; /* can be NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; @@ -238,7 +247,7 @@ ambuild (Relation heapRelation, but is empty. It must be filled in with whatever fixed data the access method requires, plus entries for all tuples already existing in the table. Ordinarily the ambuild function will call - IndexBuildHeapScan() to scan the table for existing tuples + table_index_build_scan() to scan the table for existing tuples and compute the keys that need to be inserted into the index. The function must return a palloc'd struct containing statistics about the new index. @@ -385,7 +394,8 @@ amcostestimate (PlannerInfo *root, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, - double *indexCorrelation); + double *indexCorrelation, + double *indexPages); Estimate the costs of an index scan. This function is described fully in , below. @@ -467,6 +477,18 @@ amproperty (Oid index_oid, int attno, +char * +ambuildphasename (int64 phasenum); + + Return the textual name of the given build phase number. + The phase numbers are those reported during an index build via the + pgstat_progress_update_param interface. + The phase names are then exposed in the + pg_stat_progress_create_index view. + + + + bool amvalidate (Oid opclassoid); @@ -613,7 +635,8 @@ amendscan (IndexScanDesc scan); End a scan and release resources. The scan struct itself should not be freed, but any locks or pins taken internally by the - access method must be released. + access method must be released, as well as any other memory allocated + by ambeginscan and other scan-related functions. @@ -718,7 +741,7 @@ amparallelrescan (IndexScanDesc scan); the TIDs of all the tuples it has been told about that match the scan keys. The access method is not involved in actually fetching those tuples from the index's parent table, nor in - determining whether they pass the scan's time qualification test or other + determining whether they pass the scan's visibility test or other conditions. @@ -987,8 +1010,9 @@ amparallelrescan (IndexScanDesc scan); using unique indexes, which are indexes that disallow multiple entries with identical keys. An access method that supports this feature sets amcanunique true. - (At present, only b-tree supports it.) Columns listed in the - INCLUDE clause are not used to enforce uniqueness. + (At present, only b-tree supports it.) Columns listed in the + INCLUDE clause are not considered when enforcing + uniqueness. @@ -1154,7 +1178,8 @@ amcostestimate (PlannerInfo *root, Cost *indexStartupCost, Cost *indexTotalCost, Selectivity *indexSelectivity, - double *indexCorrelation); + double *indexCorrelation, + double *indexPages); The first three parameters are inputs: @@ -1196,7 +1221,7 @@ amcostestimate (PlannerInfo *root, - The last four parameters are pass-by-reference outputs: + The last five parameters are pass-by-reference outputs: @@ -1235,6 +1260,15 @@ amcostestimate (PlannerInfo *root, + + + *indexPages + + + Set to number of index leaf pages + + + @@ -1282,6 +1316,11 @@ amcostestimate (PlannerInfo *root, table. + + The indexPages should be set to the number of leaf pages. + This is used to estimate the number of workers for parallel index scan. + + When loop_count is greater than one, the returned numbers should be averages expected for any one scan of the index. diff --git a/doc/src/sgml/indices.sgml b/doc/src/sgml/indices.sgml index 14a1aa56cb5..95c0a1926c5 100644 --- a/doc/src/sgml/indices.sgml +++ b/doc/src/sgml/indices.sgml @@ -281,6 +281,13 @@ SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10; For more information see . + + Like GiST, SP-GiST supports nearest-neighbor searches. + For SP-GiST operator classes that support distance ordering, the + corresponding operator is specified in the Ordering Operators + column in . + + index @@ -497,8 +504,9 @@ CREATE INDEX test2_mm_idx ON test2 (major, minor); By default, B-tree indexes store their entries in ascending order - with nulls last. This means that a forward scan of an index on - column x produces output satisfying ORDER BY x + with nulls last (table TID is treated as a tiebreaker column among + otherwise equal entries). This means that a forward scan of an + index on column x produces output satisfying ORDER BY x (or more verbosely, ORDER BY x ASC NULLS LAST). The index can also be scanned backward, producing output satisfying ORDER BY x DESC @@ -638,8 +646,7 @@ CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST); Indexes can also be used to enforce uniqueness of a column's value, or the uniqueness of the combined values of more than one column. -CREATE UNIQUE INDEX name ON table (column , ...) -[ INCLUDE (column , ...) ]; +CREATE UNIQUE INDEX name ON table (column , ...); Currently, only B-tree indexes can be declared unique. @@ -648,9 +655,7 @@ CREATE UNIQUE INDEX name ON tableINCLUDE clause aren't used to enforce constraints - (UNIQUE, PRIMARY KEY, etc). + indexed columns are equal in multiple rows. @@ -809,18 +814,20 @@ SELECT * FROM access_log WHERE url = '/index.html' AND client_ip = inet '212.78.10.32'; - A query that cannot use this index is: + Here the query's IP address is covered by the partial index. The + following query cannot use the partial index, as it uses an IP address + that is excluded from the index: SELECT * FROM access_log -WHERE client_ip = inet '192.168.100.23'; +WHERE url = '/index.html' AND client_ip = inet '192.168.100.23'; Observe that this kind of partial index requires that the common values be predetermined, so such partial indexes are best used for - data distributions that do not change. The indexes can be recreated + data distributions that do not change. Such indexes can be recreated occasionally to adjust for new data distributions, but this adds maintenance effort. @@ -971,6 +978,266 @@ CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) + + Index-Only Scans and Covering Indexes + + + index + index-only scans + + + index-only scan + + + index + covering + + + covering index + + + + All indexes in PostgreSQL + are secondary indexes, meaning that each index is + stored separately from the table's main data area (which is called the + table's heap + in PostgreSQL terminology). This means that + in an ordinary index scan, each row retrieval requires fetching data from + both the index and the heap. Furthermore, while the index entries that + match a given indexable WHERE condition are usually + close together in the index, the table rows they reference might be + anywhere in the heap. The heap-access portion of an index scan thus + involves a lot of random access into the heap, which can be slow, + particularly on traditional rotating media. (As described in + , bitmap scans try to alleviate + this cost by doing the heap accesses in sorted order, but that only goes + so far.) + + + + To solve this performance problem, PostgreSQL + supports index-only scans, which can answer + queries from an index alone without any heap access. The basic idea is + to return values directly out of each index entry instead of consulting + the associated heap entry. There are two fundamental restrictions on + when this method can be used: + + + + + The index type must support index-only scans. B-tree indexes always + do. GiST and SP-GiST indexes support index-only scans for some + operator classes but not others. Other index types have no support. + The underlying requirement is that the index must physically store, or + else be able to reconstruct, the original data value for each index + entry. As a counterexample, GIN indexes cannot support index-only + scans because each index entry typically holds only part of the + original data value. + + + + + + The query must reference only columns stored in the index. For + example, given an index on columns x + and y of a table that also has a + column z, these queries could use index-only scans: + +SELECT x, y FROM tab WHERE x = 'key'; +SELECT x FROM tab WHERE x = 'key' AND y < 42; + + but these queries could not: + +SELECT x, z FROM tab WHERE x = 'key'; +SELECT x FROM tab WHERE x = 'key' AND z < 42; + + (Expression indexes and partial indexes complicate this rule, + as discussed below.) + + + + + + + If these two fundamental requirements are met, then all the data values + required by the query are available from the index, so an index-only scan + is physically possible. But there is an additional requirement for any + table scan in PostgreSQL: it must verify that + each retrieved row be visible to the query's MVCC + snapshot, as discussed in . Visibility information + is not stored in index entries, only in heap entries; so at first glance + it would seem that every row retrieval would require a heap access + anyway. And this is indeed the case, if the table row has been modified + recently. However, for seldom-changing data there is a way around this + problem. PostgreSQL tracks, for each page in + a table's heap, whether all rows stored in that page are old enough to be + visible to all current and future transactions. This information is + stored in a bit in the table's visibility map. An + index-only scan, after finding a candidate index entry, checks the + visibility map bit for the corresponding heap page. If it's set, the row + is known visible and so the data can be returned with no further work. + If it's not set, the heap entry must be visited to find out whether it's + visible, so no performance advantage is gained over a standard index + scan. Even in the successful case, this approach trades visibility map + accesses for heap accesses; but since the visibility map is four orders + of magnitude smaller than the heap it describes, far less physical I/O is + needed to access it. In most situations the visibility map remains + cached in memory all the time. + + + + In short, while an index-only scan is possible given the two fundamental + requirements, it will be a win only if a significant fraction of the + table's heap pages have their all-visible map bits set. But tables in + which a large fraction of the rows are unchanging are common enough to + make this type of scan very useful in practice. + + + + + INCLUDE + in index definitions + + To make effective use of the index-only scan feature, you might choose to + create a covering index, which is an index + specifically designed to include the columns needed by a particular + type of query that you run frequently. Since queries typically need to + retrieve more columns than just the ones they search + on, PostgreSQL allows you to create an index + in which some columns are just payload and are not part + of the search key. This is done by adding an INCLUDE + clause listing the extra columns. For example, if you commonly run + queries like + +SELECT y FROM tab WHERE x = 'key'; + + the traditional approach to speeding up such queries would be to create + an index on x only. However, an index defined as + +CREATE INDEX tab_x_y ON tab(x) INCLUDE (y); + + could handle these queries as index-only scans, + because y can be obtained from the index without + visiting the heap. + + + + Because column y is not part of the index's search + key, it does not have to be of a data type that the index can handle; + it's merely stored in the index and is not interpreted by the index + machinery. Also, if the index is a unique index, that is + +CREATE UNIQUE INDEX tab_x_y ON tab(x) INCLUDE (y); + + the uniqueness condition applies to just column x, + not to the combination of x and y. + (An INCLUDE clause can also be written + in UNIQUE and PRIMARY KEY + constraints, providing alternative syntax for setting up an index like + this.) + + + + It's wise to be conservative about adding non-key payload columns to an + index, especially wide columns. If an index tuple exceeds the + maximum size allowed for the index type, data insertion will fail. + In any case, non-key columns duplicate data from the index's table + and bloat the size of the index, thus potentially slowing searches. + And remember that there is little point in including payload columns in an + index unless the table changes slowly enough that an index-only scan is + likely to not need to access the heap. If the heap tuple must be visited + anyway, it costs nothing more to get the column's value from there. + Other restrictions are that expressions are not currently supported as + included columns, and that only B-tree and GiST indexes currently support + included columns. + + + + Before PostgreSQL had + the INCLUDE feature, people sometimes made covering + indexes by writing the payload columns as ordinary index columns, + that is writing + +CREATE INDEX tab_x_y ON tab(x, y); + + even though they had no intention of ever using y as + part of a WHERE clause. This works fine as long as + the extra columns are trailing columns; making them be leading columns is + unwise for the reasons explained in . + However, this method doesn't support the case where you want the index to + enforce uniqueness on the key column(s). + + + + Suffix truncation always removes non-key + columns from upper B-Tree levels. As payload columns, they are + never used to guide index scans. The truncation process also + removes one or more trailing key column(s) when the remaining + prefix of key column(s) happens to be sufficient to describe tuples + on the lowest B-Tree level. In practice, covering indexes without + an INCLUDE clause often avoid storing columns + that are effectively payload in the upper levels. However, + explicitly defining payload columns as non-key columns + reliably keeps the tuples in upper levels + small. + + + + In principle, index-only scans can be used with expression indexes. + For example, given an index on f(x) + where x is a table column, it should be possible to + execute + +SELECT f(x) FROM tab WHERE f(x) < 1; + + as an index-only scan; and this is very attractive + if f() is an expensive-to-compute function. + However, PostgreSQL's planner is currently not + very smart about such cases. It considers a query to be potentially + executable by index-only scan only when all columns + needed by the query are available from the index. In this + example, x is not needed except in the + context f(x), but the planner does not notice that and + concludes that an index-only scan is not possible. If an index-only scan + seems sufficiently worthwhile, this can be worked around by + adding x as an included column, for example + +CREATE INDEX tab_f_x ON tab (f(x)) INCLUDE (x); + + An additional caveat, if the goal is to avoid + recalculating f(x), is that the planner won't + necessarily match uses of f(x) that aren't in + indexable WHERE clauses to the index column. It will + usually get this right in simple queries such as shown above, but not in + queries that involve joins. These deficiencies may be remedied in future + versions of PostgreSQL. + + + + Partial indexes also have interesting interactions with index-only scans. + Consider the partial index shown in : + +CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) + WHERE success; + + In principle, we could do an index-only scan on this index to satisfy a + query like + +SELECT target FROM tests WHERE subject = 'some-subject' AND success; + + But there's a problem: the WHERE clause refers + to success which is not available as a result column + of the index. Nonetheless, an index-only scan is possible because the + plan does not need to recheck that part of the WHERE + clause at run time: all entries found in the index necessarily + have success = true so this need not be explicitly + checked in the plan. PostgreSQL versions 9.6 + and later will recognize such cases and allow index-only scans to be + generated, but older versions will not. + + + + Operator Classes and Operator Families @@ -1138,183 +1405,6 @@ CREATE INDEX test1c_content_y_index ON test1c (content COLLATE "y"); - - Index-Only Scans - - - index - index-only scans - - - index-only scan - - - - All indexes in PostgreSQL are secondary - indexes, meaning that each index is stored separately from the table's - main data area (which is called the table's heap - in PostgreSQL terminology). This means that in an - ordinary index scan, each row retrieval requires fetching data from both - the index and the heap. Furthermore, while the index entries that match a - given indexable WHERE condition are usually close together in - the index, the table rows they reference might be anywhere in the heap. - The heap-access portion of an index scan thus involves a lot of random - access into the heap, which can be slow, particularly on traditional - rotating media. (As described in , - bitmap scans try to alleviate this cost by doing the heap accesses in - sorted order, but that only goes so far.) - - - - To solve this performance problem, PostgreSQL - supports index-only scans, which can answer queries from an - index alone without any heap access. The basic idea is to return values - directly out of each index entry instead of consulting the associated heap - entry. There are two fundamental restrictions on when this method can be - used: - - - - - The index type must support index-only scans. B-tree indexes always - do. GiST and SP-GiST indexes support index-only scans for some - operator classes but not others. Other index types have no support. - The underlying requirement is that the index must physically store, or - else be able to reconstruct, the original data value for each index - entry. As a counterexample, GIN indexes cannot support index-only - scans because each index entry typically holds only part of the - original data value. - - - - - - The query must reference only columns stored in the index. For - example, given an index on columns x and y of a - table that also has a column z, these queries could use - index-only scans: - -SELECT x, y FROM tab WHERE x = 'key'; -SELECT x FROM tab WHERE x = 'key' AND y < 42; - - but these queries could not: - -SELECT x, z FROM tab WHERE x = 'key'; -SELECT x FROM tab WHERE x = 'key' AND z < 42; - - (Expression indexes and partial indexes complicate this rule, - as discussed below.) - - - - - - - If these two fundamental requirements are met, then all the data values - required by the query are available from the index, so an index-only scan - is physically possible. But there is an additional requirement for any - table scan in PostgreSQL: it must verify that each - retrieved row be visible to the query's MVCC snapshot, as - discussed in . Visibility information is not stored - in index entries, only in heap entries; so at first glance it would seem - that every row retrieval would require a heap access anyway. And this is - indeed the case, if the table row has been modified recently. However, - for seldom-changing data there is a way around this - problem. PostgreSQL tracks, for each page in a table's - heap, whether all rows stored in that page are old enough to be visible to - all current and future transactions. This information is stored in a bit - in the table's visibility map. An index-only scan, after - finding a candidate index entry, checks the visibility map bit for the - corresponding heap page. If it's set, the row is known visible and so the - data can be returned with no further work. If it's not set, the heap - entry must be visited to find out whether it's visible, so no performance - advantage is gained over a standard index scan. Even in the successful - case, this approach trades visibility map accesses for heap accesses; but - since the visibility map is four orders of magnitude smaller than the heap - it describes, far less physical I/O is needed to access it. In most - situations the visibility map remains cached in memory all the time. - - - - In short, while an index-only scan is possible given the two fundamental - requirements, it will be a win only if a significant fraction of the - table's heap pages have their all-visible map bits set. But tables in - which a large fraction of the rows are unchanging are common enough to - make this type of scan very useful in practice. - - - - To make effective use of the index-only scan feature, you might choose to - create indexes in which only the leading columns are meant to - match WHERE clauses, while the trailing columns - hold payload data to be returned by a query. For example, if - you commonly run queries like - -SELECT y FROM tab WHERE x = 'key'; - - the traditional approach to speeding up such queries would be to create an - index on x only. However, an index on (x, y) - would offer the possibility of implementing this query as an index-only - scan. As previously discussed, such an index would be larger and hence - more expensive than an index on x alone, so this is attractive - only if the table is known to be mostly static. Note it's important that - the index be declared on (x, y) not (y, x), as for - most index types (particularly B-trees) searches that do not constrain the - leading index columns are not very efficient. - - - - In principle, index-only scans can be used with expression indexes. - For example, given an index on f(x) where x is a - table column, it should be possible to execute - -SELECT f(x) FROM tab WHERE f(x) < 1; - - as an index-only scan; and this is very attractive if f() is - an expensive-to-compute function. However, PostgreSQL's - planner is currently not very smart about such cases. It considers a - query to be potentially executable by index-only scan only when - all columns needed by the query are available from the index. - In this example, x is not needed except in the - context f(x), but the planner does not notice that and - concludes that an index-only scan is not possible. If an index-only scan - seems sufficiently worthwhile, this can be worked around by declaring the - index to be on (f(x), x), where the second column is not - expected to be used in practice but is just there to convince the planner - that an index-only scan is possible. An additional caveat, if the goal is - to avoid recalculating f(x), is that the planner won't - necessarily match uses of f(x) that aren't in - indexable WHERE clauses to the index column. It will usually - get this right in simple queries such as shown above, but not in queries - that involve joins. These deficiencies may be remedied in future versions - of PostgreSQL. - - - - Partial indexes also have interesting interactions with index-only scans. - Consider the partial index shown in : - -CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target) - WHERE success; - - In principle, we could do an index-only scan on this index to satisfy a - query like - -SELECT target FROM tests WHERE subject = 'some-subject' AND success; - - But there's a problem: the WHERE clause refers - to success which is not available as a result column of the - index. Nonetheless, an index-only scan is possible because the plan does - not need to recheck that part of the WHERE clause at run time: - all entries found in the index necessarily have success = true - so this need not be explicitly checked in the - plan. PostgreSQL versions 9.6 and later will recognize - such cases and allow index-only scans to be generated, but older versions - will not. - - - - Examining Index Usage diff --git a/doc/src/sgml/information_schema.sgml b/doc/src/sgml/information_schema.sgml index 09ef2827f2a..906fe7819f5 100644 --- a/doc/src/sgml/information_schema.sgml +++ b/doc/src/sgml/information_schema.sgml @@ -952,6 +952,62 @@ + + <literal>column_column_usage</literal> + + + The view column_column_usage identifies all generated + columns that depend on another base column in the same table. Only tables + owned by a currently enabled role are included. + + + + <literal>column_column_usage</literal> Columns + + + + + Name + Data Type + Description + + + + + + table_catalog + sql_identifier + Name of the database containing the table (always the current database) + + + + table_schema + sql_identifier + Name of the schema containing the table + + + + table_name + sql_identifier + Name of the table + + + + column_name + sql_identifier + Name of the base column that a generated column depends on + + + + dependent_column + sql_identifier + Name of the generated column + + + +
+
+ <literal>column_domain_usage</literal> @@ -1256,7 +1312,7 @@ The view columns contains information about all table columns (or view columns) in the database. System columns - (oid, etc.) are not included. Only those columns are + (ctid, etc.) are not included. Only those columns are shown that the current user has access to (by way of being the owner or having some privilege). @@ -1648,13 +1704,19 @@ is_generated character_data - Applies to a feature not available in PostgreSQL + + If the column is a generated column, then ALWAYS, + else NEVER. + generation_expression character_data - Applies to a feature not available in PostgreSQL + + If the column is a generated column, then the generation expression, + else null. + @@ -2621,8 +2683,9 @@ ORDER BY c.ordinal_position; For permission checking, the set of applicable roles is applied, which can be broader than the set of enabled roles. So generally, it is better to use the view - applicable_roles instead of this one; see also - there. + applicable_roles instead of this one; See + for details on + applicable_roles view. @@ -5793,7 +5856,7 @@ ORDER BY c.ordinal_position; character_data Statement that is executed by the trigger (currently always - EXECUTE PROCEDURE + EXECUTE FUNCTION function(...)) @@ -6674,7 +6737,11 @@ ORDER BY c.ordinal_position; check_option character_data - Applies to a feature not available in PostgreSQL + + CASCADED or LOCAL if the view + has a CHECK OPTION defined on it, + NONE if not + diff --git a/doc/src/sgml/install-windows.sgml b/doc/src/sgml/install-windows.sgml index 99e9c7b78ee..08556b6ebe7 100644 --- a/doc/src/sgml/install-windows.sgml +++ b/doc/src/sgml/install-windows.sgml @@ -19,10 +19,9 @@ There are several different ways of building PostgreSQL on Windows. The simplest way to build with - Microsoft tools is to install Visual Studio Express 2017 - for Windows Desktop and use the included - compiler. It is also possible to build with the full - Microsoft Visual C++ 2005 to 2017. + Microsoft tools is to install Visual Studio 2019 + and use the included compiler. It is also possible to build with the full + Microsoft Visual C++ 2013 to 2019. In some cases that requires the installation of the Windows SDK in addition to the compiler. @@ -69,28 +68,35 @@ Visual Studio Express or some versions of the Microsoft Windows SDK. If you do not already have a Visual Studio environment set up, the easiest - ways are to use the compilers from Visual Studio Express 2017 - for Windows Desktop or those in the Windows SDK - 8.1, which are both free downloads from Microsoft. + ways are to use the compilers from + Visual Studio 2019 or those in the + Windows SDK 10, which are both free downloads + from Microsoft. Both 32-bit and 64-bit builds are possible with the Microsoft Compiler suite. 32-bit PostgreSQL builds are possible with - Visual Studio 2005 to - Visual Studio 2017 (including Express editions), - as well as standalone Windows SDK releases 6.0 to 8.1. + Visual Studio 2013 to + Visual Studio 2019, + as well as standalone Windows SDK releases 8.1a to 10. 64-bit PostgreSQL builds are supported with - Microsoft Windows SDK version 6.0a to 8.1 or - Visual Studio 2008 and above. Compilation - is supported down to Windows XP and - Windows Server 2003 when building with - Visual Studio 2005 to - Visual Studio 2013. Building with - Visual Studio 2015 is supported down to - Windows Vista and Windows Server 2008. - Building with Visual Studio 2017 is supported - down to Windows 7 SP1 and Windows Server 2008 R2 SP1. + Microsoft Windows SDK version 8.1a to 10 or + Visual Studio 2013 and above. Compilation + is supported down to Windows 7 and + Windows Server 2008 R2 SP1 when building with + Visual Studio 2013 to + Visual Studio 2019. + @@ -162,7 +168,7 @@ $ENV{MSBFLAGS}="/m"; If your build environment doesn't ship with a supported version of the Microsoft Windows SDK it is recommended that you upgrade to the latest version (currently - version 7.1), available for download from + version 10), available for download from . @@ -182,7 +188,7 @@ $ENV{MSBFLAGS}="/m"; ActiveState Perl is required to run the build generation scripts. MinGW or Cygwin Perl will not work. It must also be present in the PATH. Binaries can be downloaded from - + (Note: version 5.8.3 or later is required, the free Standard Distribution is sufficient). @@ -293,11 +299,11 @@ $ENV{MSBFLAGS}="/m"; - openssl + OpenSSL Required for SSL support. Binaries can be downloaded from - - or source from . + + or source from . @@ -314,7 +320,7 @@ $ENV{MSBFLAGS}="/m"; Python Required for building PL/Python. Binaries can - be downloaded from . + be downloaded from . @@ -332,7 +338,7 @@ $ENV{MSBFLAGS}="/m"; - Special Considerations for 64-bit Windows + Special Considerations for 64-Bit Windows PostgreSQL will only build for the x64 architecture on 64-bit Windows, there @@ -348,7 +354,7 @@ $ENV{MSBFLAGS}="/m"; To use a server-side third party library such as python or - openssl, this library must also be + OpenSSL, this library must also be 64-bit. There is no support for loading a 32-bit library in a 64-bit server. Several of the third party libraries that PostgreSQL supports may only be available in 32-bit versions, in which case they cannot be used with @@ -473,7 +479,7 @@ $ENV{CONFIG}="Debug"; ActiveState Perl installation, nor in the ActiveState Perl Package Manager (PPM) library. To install, download the IPC-Run-<version>.tar.gz source archive from CPAN, - at , and + at , and uncompress. Edit the buildenv.pl file, and add a PERL5LIB variable to point to the lib subdirectory from the extracted archive. For example: @@ -486,52 +492,5 @@ $ENV{PERL5LIB}=$ENV{PERL5LIB} . ';c:\IPC-Run-0.94\lib'; - - Building the Documentation - - - Building the PostgreSQL documentation in HTML format requires several tools - and files. Create a root directory for all these files, and store them - in the subdirectories in the list below. - - - OpenJade 1.3.1-2 - - Download from - - and uncompress in the subdirectory openjade-1.3.1. - - - - - DocBook DTD 4.2 - - Download from - - and uncompress in the subdirectory docbook. - - - - - ISO character entities - - Download from - and - uncompress in the subdirectory docbook. - - - - Edit the buildenv.pl file, and add a variable for the - location of the root directory, for example: - -$ENV{DOCROOT}='c:\docbook'; - - To build the documentation, run the command - builddoc.bat. Note that this will actually run the - build twice, in order to generate the indexes. The generated HTML files - will be in doc\src\sgml. - - - diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml index 7a7823b7a30..d8494e293bd 100644 --- a/doc/src/sgml/installation.sgml +++ b/doc/src/sgml/installation.sgml @@ -15,12 +15,20 @@ documentation. See standalone-profile.xsl for details. installation + This chapter describes the installation of PostgreSQL using the source code - distribution. (If you are installing a pre-packaged distribution, + distribution. If you are installing a pre-packaged distribution, such as an RPM or Debian package, ignore this chapter - and read the packager's instructions instead.) + and read the packager's instructions instead. + + + + If you are building PostgreSQL for Microsoft + Windows, read this chapter if you intend to build with MinGW or Cygwin; + but if you intend to build with Microsoft's Visual + C++, see instead. @@ -37,7 +45,7 @@ mkdir /usr/local/pgsql/data chown postgres /usr/local/pgsql/data su - postgres /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data -/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data >logfile 2>&1 & +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data -l logfile start /usr/local/pgsql/bin/createdb test /usr/local/pgsql/bin/psql test @@ -54,10 +62,8 @@ su - postgres In general, a modern Unix-compatible platform should be able to run PostgreSQL. The platforms that had received specific testing at the - time of release are listed in - below. In the doc subdirectory of the distribution - there are several platform-specific FAQ documents you - might wish to consult if you are having trouble. + time of release are described in + below. @@ -85,7 +91,7 @@ su - postgres You need an ISO/ANSI C compiler (at least - C89-compliant). Recent + C99-compliant). Recent versions of GCC are recommended, but PostgreSQL is known to build using a wide variety of compilers from different vendors. @@ -245,8 +251,10 @@ su - postgres You need OpenSSL, if you want to support - encrypted client connections. The minimum required version is - 0.9.8. + encrypted client connections. OpenSSL is + also required for random number generation on platforms that do not + have /dev/urandom (except Windows). The minimum + version required is 0.9.8. @@ -316,25 +324,25 @@ su - postgres If you need to get a GNU package, you can find it at your local GNU mirror site (see + url="https://www.gnu.org/prep/ftp"> for a list) or at . Also check that you have sufficient disk space. You will need about - 100 MB for the source tree during compilation and about 20 MB for + 350 MB for the source tree during compilation and about 60 MB for the installation directory. An empty database cluster takes about - 35 MB; databases take about five times the amount of space that a + 40 MB; databases take about five times the amount of space that a flat text file with the same data would take. If you are going to run the regression tests you will temporarily need up to an extra - 150 MB. Use the df command to check free disk + 300 MB. Use the df command to check free disk space. - Getting The Source + Getting the Source The PostgreSQL &version; sources can be obtained from the @@ -347,8 +355,11 @@ su - postgres gunzip postgresql-&version;.tar.gz tar xf postgresql-&version;.tar - (Use bunzip2 instead of gunzip if you - have the .bz2 file.) + (Use bunzip2 instead of gunzip if + you have the .bz2 file. Also, note that most + modern versions of tar can unpack compressed archives + directly, so you don't really need the + separate gunzip or bunzip2 step.) This will create a directory postgresql-&version; under the current directory with the PostgreSQL sources. @@ -385,10 +396,14 @@ su - postgres This script will run a number of tests to determine values for various system dependent variables and detect any quirks of your operating system, and finally will create several files in the - build tree to record what it found. You can also run - configure in a directory outside the source - tree, if you want to keep the build directory separate. This - procedure is also called a + build tree to record what it found. + + + + You can also run configure in a directory outside + the source tree, and then build there, if you want to keep the build + directory separate from the original source files. This procedure is + called a VPATHVPATH build. Here's how: @@ -408,8 +423,231 @@ su - postgres You can customize the build and installation process by supplying one - or more of the following command line options to - configure: + or more command line options to configure. + Typically you would customize the install location, or the set of + optional features that are built. configure + has a large number of options, which are described in + . + + + + Also, configure responds to certain environment + variables, as described in . + These provide additional ways to customize the configuration. + + + + + Build + + + To start the build, type either of: + +make +make all + + (Remember to use GNU make.) + The build will take a few minutes depending on your + hardware. The last line displayed should be: + +All of PostgreSQL successfully made. Ready to install. + + + + + If you want to build everything that can be built, including the + documentation (HTML and man pages), and the additional modules + (contrib), type instead: + +make world + + The last line displayed should be: + +PostgreSQL, contrib, and documentation successfully made. Ready to install. + + + + + If you want to invoke the build from another makefile rather than + manually, you must unset MAKELEVEL or set it to zero, + for instance like this: + +build-postgresql: + $(MAKE) -C postgresql MAKELEVEL=0 all + + Failure to do that can lead to strange error messages, typically about + missing header files. + + + + + Regression Tests + + + regression test + + + + If you want to test the newly built server before you install it, + you can run the regression tests at this point. The regression + tests are a test suite to verify that PostgreSQL + runs on your machine in the way the developers expected it + to. Type: + +make check + + (This won't work as root; do it as an unprivileged user.) + See for + detailed information about interpreting the test results. You can + repeat this test at any later time by issuing the same command. + + + + + Installing the Files + + + + If you are upgrading an existing system be sure to read + , + which has instructions about upgrading a + cluster. + + + + + To install PostgreSQL enter: + +make install + + This will install files into the directories that were specified + in . Make sure that you have appropriate + permissions to write into that area. Normally you need to do this + step as root. Alternatively, you can create the target + directories in advance and arrange for appropriate permissions to + be granted. + + + + To install the documentation (HTML and man pages), enter: + +make install-docs + + + + + If you built the world above, type instead: + +make install-world + + This also installs the documentation. + + + + You can use make install-strip instead of + make install to strip the executable files and + libraries as they are installed. This will save some space. If + you built with debugging support, stripping will effectively + remove the debugging support, so it should only be done if + debugging is no longer needed. install-strip + tries to do a reasonable job saving space, but it does not have + perfect knowledge of how to strip every unneeded byte from an + executable file, so if you want to save all the disk space you + possibly can, you will have to do manual work. + + + + The standard installation provides all the header files needed for client + application development as well as for server-side program + development, such as custom functions or data types written in C. + (Prior to PostgreSQL 8.0, a separate make + install-all-headers command was needed for the latter, but this + step has been folded into the standard install.) + + + + Client-only installation: + + If you want to install only the client applications and + interface libraries, then you can use these commands: + +make -C src/bin install +make -C src/include install +make -C src/interfaces install +make -C doc install + + src/bin has a few binaries for server-only use, + but they are small. + + + + + + + Uninstallation: + + To undo the installation use the command make + uninstall. However, this will not remove any created directories. + + + + + Cleaning: + + + After the installation you can free disk space by removing the built + files from the source tree with the command make + clean. This will preserve the files made by the configure + program, so that you can rebuild everything with make + later on. To reset the source tree to the state in which it was + distributed, use make distclean. If you are going to + build for several platforms within the same source tree you must do + this and re-configure for each platform. (Alternatively, use + a separate build tree for each platform, so that the source tree + remains unmodified.) + + + + + If you perform a build and then discover that your configure + options were wrong, or if you change anything that configure + investigates (for example, software upgrades), then it's a good + idea to do make distclean before reconfiguring and + rebuilding. Without this, your changes in configuration choices + might not propagate everywhere they need to. + + + + <filename>configure</filename> Options + + + configure options + + + + configure's command line options are explained below. + This list is not exhaustive (use ./configure --help + to get one that is). The options not covered here are meant for + advanced use-cases such as cross-compilation, and are documented in + the standard Autoconf documentation. + + + + Installation Locations + + + These options control where make install will put + the files. The option is sufficient for + most cases. If you have special needs, you can customize the + installation subdirectories with the other options described in this + section. Beware however that changing the relative locations of the + different subdirectories may render the installation non-relocatable, + meaning you won't be able to move it after installation. + (The man and doc locations are + not affected by this restriction.) For relocatable installs, you + might want to use the --disable-rpath option + described later. + @@ -422,22 +660,6 @@ su - postgres will ever be installed directly into the PREFIX directory. - - - If you have special needs, you can also customize the - individual subdirectories with the following options. However, - if you leave these with their defaults, the installation will be - relocatable, meaning you can move the directory after - installation. (The man and doc - locations are not affected by this.) - - - - For relocatable installs, you might want to use - configure's --disable-rpath - option. Also, you will need to tell the operating system how - to find the shared libraries. - @@ -597,56 +819,21 @@ su - postgres for dynamically loadable modules. - - - - - - - - Append STRING to the PostgreSQL version number. You - can use this, for example, to mark binaries built from unreleased Git - snapshots or containing custom patches with an extra version string - such as a git describe identifier or a - distribution package release number. - - - + - - - - - DIRECTORIES is a colon-separated list of - directories that will be added to the list the compiler - searches for header files. If you have optional packages - (such as GNU Readline) installed in a non-standard - location, - you have to use this option and probably also the corresponding - option. - - - Example: --with-includes=/opt/gnu/include:/usr/sup/include. - - - + + <productname>PostgreSQL</productname> Features - - - - - DIRECTORIES is a colon-separated list of - directories to search for libraries. You will probably have - to use this option (and the corresponding - option) if you have packages - installed in non-standard locations. - - - Example: --with-libraries=/opt/gnu/lib:/usr/sup/lib. - - - + + The options described in this section enable building of + various PostgreSQL features that are not + built by default. Most of these are non-default only because they + require additional software, as described in + . + + + @@ -666,28 +853,13 @@ su - postgres To use this option, you will need an implementation of the - Gettext API; see above. + Gettext API. - - - - Set NUMBER as the default port number for - server and clients. The default is 5432. The port can always - be changed later on, but if you specify it here then both - server and clients will have the same default compiled in, - which can be very convenient. Usually the only good reason - to select a non-default value is if you intend to run multiple - PostgreSQL servers on the same machine. - - - - - - + Build the PL/Perl server-side language. @@ -722,38 +894,41 @@ su - postgres interfacing to Tcl. This file is normally found automatically at a well-known location, but if you want to use a different version of Tcl you can specify the directory in which to look - for it. + for tclConfig.sh. - + - Build with support for GSSAPI authentication. On many - systems, the GSSAPI (usually a part of the Kerberos installation) - system is not installed in a location - that is searched by default (e.g., /usr/include, - /usr/lib), so you must use the options - and in - addition to this option. configure will check - for the required header files and libraries to make sure that - your GSSAPI installation is sufficient before proceeding. + Build with support for + the ICUICU + library, enabling use of ICU collation + features (see + ). + This requires the ICU4C package + to be installed. The minimum required version + of ICU4C is currently 4.2. - - - - - - The default name of the Kerberos service principal used - by GSSAPI. - postgres is the default. There's usually no - reason to change this unless you have a Windows environment, - in which case it must be set to upper case - POSTGRES. + By default, + pkg-configpkg-config + will be used to find the required compilation options. This is + supported for ICU4C version 4.6 and later. + For older versions, or if pkg-config is + not available, the variables ICU_CFLAGS + and ICU_LIBS can be specified + to configure, like in this example: + +./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' + + (If ICU4C is in the default search path + for the compiler, then you still need to specify nonempty strings in + order to avoid use of pkg-config, for + example, ICU_CFLAGS=' '.) @@ -775,9 +950,10 @@ su - postgres will be used to find the required compilation options. llvm-config, and then llvm-config-$major-$minor for all supported - versions, will be searched on PATH. If that would not - yield the correct binary, use LLVM_CONFIG to specify a - path to the correct llvm-config. For example + versions, will be searched for in your PATH. If + that would not yield the desired program, + use LLVM_CONFIG to specify a path to the + correct llvm-config. For example ./configure ... --with-llvm LLVM_CONFIG='/path/to/llvm/bin/llvm-config' @@ -793,37 +969,6 @@ su - postgres - - - - - Build with support for - the ICUICU - library. This requires the ICU4C package - to be installed. The minimum required version - of ICU4C is currently 4.2. - - - - By default, - pkg-configpkg-config - will be used to find the required compilation options. This is - supported for ICU4C version 4.6 and later. - For older versions, or if pkg-config is - not available, the variables ICU_CFLAGS - and ICU_LIBS can be specified - to configure, like in this example: - -./configure ... --with-icu ICU_CFLAGS='-I/some/where/include' ICU_LIBS='-L/some/where/lib -licui18n -licuuc -licudata' - - (If ICU4C is in the default search path - for the compiler, then you still need to specify a nonempty string in - order to avoid use of pkg-config, for - example, ICU_CFLAGS=' '.) - - - - @@ -844,22 +989,18 @@ su - postgres - - - - Build with PAMPAM - (Pluggable Authentication Modules) support. - - - - - - + - Build with BSD Authentication support. - (The BSD Authentication framework is - currently only available on OpenBSD.) + Build with support for GSSAPI authentication. On many systems, the + GSSAPI system (usually a part of the Kerberos installation) is not + installed in a location + that is searched by default (e.g., /usr/include, + /usr/lib), so you must use the options + and in + addition to this option. configure will check + for the required header files and libraries to make sure that + your GSSAPI installation is sufficient before proceeding. @@ -883,41 +1024,37 @@ su - postgres - + - Build with support - for systemdsystemd - service notifications. This improves integration if the server binary - is started under systemd but has no impact - otherwise; see for more - information. libsystemd and the - associated header files need to be installed to be able to use this - option. + Build with PAMPAM + (Pluggable Authentication Modules) support. - + - Prevents use of the Readline library - (and libedit as well). This option disables - command-line editing and history in - psql, so it is not recommended. + Build with BSD Authentication support. + (The BSD Authentication framework is + currently only available on OpenBSD.) - + - Favors the use of the BSD-licensed libedit library - rather than GPL-licensed Readline. This option - is significant only if you have both libraries installed; the - default in that case is to use Readline. + Build with support + for systemdsystemd + service notifications. This improves integration if the server + is started under systemd but has no impact + otherwise; see for more + information. libsystemd and the + associated header files need to be installed to use this option. @@ -926,8 +1063,9 @@ su - postgres - Build with Bonjour support. This requires Bonjour support - in your operating system. Recommended on macOS. + Build with support for Bonjour automatic service discovery. + This requires Bonjour support in your operating system. + Recommended on macOS. @@ -979,7 +1117,7 @@ su - postgres - Build with libxml (enables SQL/XML support). Libxml version 2.6.23 or + Build with libxml, enabling SQL/XML support. Libxml version 2.6.23 or later is required for this feature. @@ -1002,95 +1140,94 @@ su - postgres - Use libxslt when building the + Build with libxslt, enabling the - module. xml2 relies on this library - to perform XSL transformations of XML. + module to perform XSL transformations of XML. + must be specified as well. + + + + + + Anti-Features + + + The options described in this section allow disabling + certain PostgreSQL features that are built + by default, but which might need to be turned off if the required + software or system features are not available. Using these options is + not recommended unless really necessary. + + + + - + - Disable passing float4 values by value, causing them - to be passed by reference instead. This option costs - performance, but may be needed for compatibility with old - user-defined functions that are written in C and use the - version 0 calling convention. A better long-term - solution is to update any such functions to use the - version 1 calling convention. + Prevents use of the Readline library + (and libedit as well). This option disables + command-line editing and history in + psql. - + - Disable passing float8 values by value, causing them - to be passed by reference instead. This option costs - performance, but may be needed for compatibility with old - user-defined functions that are written in C and use the - version 0 calling convention. A better long-term - solution is to update any such functions to use the - version 1 calling convention. - Note that this option affects not only float8, but also int8 and some - related types such as timestamp. - On 32-bit platforms, is the default - and it is not allowed to select . + Favors the use of the BSD-licensed libedit library + rather than GPL-licensed Readline. This option + is significant only if you have both libraries installed; the + default in that case is to use Readline. - + - Set the segment size, in gigabytes. Large tables are - divided into multiple operating-system files, each of size equal - to the segment size. This avoids problems with file size limits - that exist on many platforms. The default segment size, 1 gigabyte, - is safe on all supported platforms. If your operating system has - largefile support (which most do, nowadays), you can use - a larger segment size. This can be helpful to reduce the number of - file descriptors consumed when working with very large tables. - But be careful not to select a value larger than is supported - by your platform and the file systems you intend to use. Other - tools you might wish to use, such as tar, could - also set limits on the usable file size. - It is recommended, though not absolutely required, that this value - be a power of 2. - Note that changing this value requires an initdb. + + zlib + + Prevents use of the Zlib library. + This disables + support for compressed archives in pg_dump + and pg_restore. - + - Set the block size, in kilobytes. This is the unit - of storage and I/O within tables. The default, 8 kilobytes, - is suitable for most situations; but other values may be useful - in special cases. - The value must be a power of 2 between 1 and 32 (kilobytes). - Note that changing this value requires an initdb. + Disable passing float4 values by value, causing them + to be passed by reference instead. This option costs + performance, but may be needed for compatibility with very old + user-defined functions written in C. - + - Set the WAL block size, in kilobytes. This is the unit - of storage and I/O within the WAL log. The default, 8 kilobytes, - is suitable for most situations; but other values may be useful - in special cases. - The value must be a power of 2 between 1 and 64 (kilobytes). - Note that changing this value requires an initdb. + Disable passing float8 values by value, causing them + to be passed by reference instead. This option costs + performance, but may be needed for compatibility with very old + user-defined functions written in C. + Note that this option affects not only float8, but also int8 and some + related types such as timestamp. + On 32-bit platforms, is the default + and it is not allowed to select . @@ -1101,7 +1238,7 @@ su - postgres Allow the build to succeed even if PostgreSQL has no CPU spinlock support for the platform. The lack of - spinlock support will result in poor performance; therefore, + spinlock support will result in very poor performance; therefore, this option should only be used if the build aborts and informs you that the platform lacks spinlock support. If this option is required to build PostgreSQL on @@ -1112,19 +1249,13 @@ su - postgres - + - Allow the build to succeed even if PostgreSQL - has no support for strong random numbers on the platform. - A source of random numbers is needed for some authentication - protocols, as well as some routines in the - - module. disables functionality that - requires cryptographically strong random numbers, and substitutes - a weak pseudo-random-number-generator for the generation of - authentication salt values and query cancel keys. It may make - authentication less secure. + Disable use of CPU atomic operations. This option does nothing on + platforms that lack such operations. On platforms that do have + them, this will result in poor performance. This option is only + useful for debugging or making performance comparisons. @@ -1136,7 +1267,51 @@ su - postgres Disable the thread-safety of client libraries. This prevents concurrent threads in libpq and ECPG programs from safely controlling - their private connection handles. + their private connection handles. Use this only on platforms + with deficient threading support. + + + + + + + + + + Build Process Details + + + + + + + + DIRECTORIES is a colon-separated list of + directories that will be added to the list the compiler + searches for header files. If you have optional packages + (such as GNU Readline) installed in a non-standard + location, + you have to use this option and probably also the corresponding + option. + + + Example: --with-includes=/opt/gnu/include:/usr/sup/include. + + + + + + + + + DIRECTORIES is a colon-separated list of + directories to search for libraries. You will probably have + to use this option (and the corresponding + option) if you have packages + installed in non-standard locations. + + + Example: --with-libraries=/opt/gnu/lib:/usr/sup/lib. @@ -1182,62 +1357,178 @@ su - postgres - + - - zlib - - Prevents use of the Zlib library. This disables - support for compressed archives in pg_dump - and pg_restore. - This option is only intended for those rare systems where this - library is not available. + Append STRING to the PostgreSQL version number. You + can use this, for example, to mark binaries built from unreleased Git + snapshots or containing custom patches with an extra version string, + such as a git describe identifier or a + distribution package release number. - + - Compiles all programs and libraries with debugging symbols. - This means that you can run the programs in a debugger - to analyze problems. This enlarges the size of the installed - executables considerably, and on non-GCC compilers it usually - also disables compiler optimization, causing slowdowns. However, - having the symbols available is extremely helpful for dealing - with any problems that might arise. Currently, this option is - recommended for production installations only if you use GCC. - But you should always have it on if you are doing development work - or running a beta version. + Do not mark PostgreSQL's executables + to indicate that they should search for shared libraries in the + installation's library directory (see ). + On most platforms, this marking uses an absolute path to the + library directory, so that it will be unhelpful if you relocate + the installation later. However, you will then need to provide + some other way for the executables to find the shared libraries. + Typically this requires configuring the operating system's + dynamic linker to search the library directory; see + for more detail. + + + + + + Miscellaneous + + + It's fairly common, particularly for test builds, to adjust the + default port number with . + The other options in this section are recommended only for advanced + users. + + + + - + - If using GCC, all programs and libraries are compiled with - code coverage testing instrumentation. When run, they - generate files in the build directory with code coverage - metrics. - See - for more information. This option is for use only with GCC - and when doing development work. + Set NUMBER as the default port number for + server and clients. The default is 5432. The port can always + be changed later on, but if you specify it here then both + server and clients will have the same default compiled in, + which can be very convenient. Usually the only good reason + to select a non-default value is if you intend to run multiple + PostgreSQL servers on the same machine. - + - If using GCC, all programs and libraries are compiled so they - can be profiled. On backend exit, a subdirectory will be created - that contains the gmon.out file for use in profiling. - This option is for use only with GCC and when doing development work. + The default name of the Kerberos service principal used + by GSSAPI. + postgres is the default. There's usually no + reason to change this unless you are building for a Windows + environment, in which case it must be set to upper case + POSTGRES. + + + + + + + + + Set the segment size, in gigabytes. Large tables are + divided into multiple operating-system files, each of size equal + to the segment size. This avoids problems with file size limits + that exist on many platforms. The default segment size, 1 gigabyte, + is safe on all supported platforms. If your operating system has + largefile support (which most do, nowadays), you can use + a larger segment size. This can be helpful to reduce the number of + file descriptors consumed when working with very large tables. + But be careful not to select a value larger than is supported + by your platform and the file systems you intend to use. Other + tools you might wish to use, such as tar, could + also set limits on the usable file size. + It is recommended, though not absolutely required, that this value + be a power of 2. + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different segment size. + + + + + + + + + Set the block size, in kilobytes. This is the unit + of storage and I/O within tables. The default, 8 kilobytes, + is suitable for most situations; but other values may be useful + in special cases. + The value must be a power of 2 between 1 and 32 (kilobytes). + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different block size. + + + + + + + + + Set the WAL block size, in kilobytes. This is the unit + of storage and I/O within the WAL log. The default, 8 kilobytes, + is suitable for most situations; but other values may be useful + in special cases. + The value must be a power of 2 between 1 and 64 (kilobytes). + Note that changing this value breaks on-disk database compatibility, + meaning you cannot use pg_upgrade to upgrade to + a build with a different WAL block size. + + + + + + + + + + Developer Options + + + Most of the options in this section are only of interest for + developing or debugging PostgreSQL. + They are not recommended for production builds, except + for , which can be useful to enable + detailed bug reports in the unlucky event that you encounter a bug. + On platforms supporting DTrace, + may also be reasonable to use in production. + + + + When building an installation that will be used to develop code inside + the server, it is recommended to use at least the + options + and . + + + + + + + + + Compiles all programs and libraries with debugging symbols. + This means that you can run the programs in a debugger + to analyze problems. This enlarges the size of the installed + executables considerably, and on non-GCC compilers it usually + also disables compiler optimization, causing slowdowns. However, + having the symbols available is extremely helpful for dealing + with any problems that might arise. Currently, this option is + recommended for production installations only if you use GCC. + But you should always have it on if you are doing development work + or running a beta version. @@ -1261,6 +1552,17 @@ su - postgres + + + + + Enable tests using the Perl TAP tools. This requires a Perl + installation and the Perl module IPC::Run. + See for more information. + + + + @@ -1275,6 +1577,34 @@ su - postgres + + + + + If using GCC, all programs and libraries are compiled with + code coverage testing instrumentation. When run, they + generate files in the build directory with code coverage + metrics. + See + for more information. This option is for use only with GCC + and when doing development work. + + + + + + + + + If using GCC, all programs and libraries are compiled so they + can be profiled. On backend exit, a subdirectory will be created + that contains the gmon.out file containing + profile data. + This option is for use only with GCC and when doing development work. + + + + @@ -1293,7 +1623,7 @@ su - postgres environment variable DTRACE can be set. This will often be necessary because dtrace is typically installed under /usr/sbin, - which might not be in the path. + which might not be in your PATH. @@ -1301,7 +1631,7 @@ su - postgres can be specified in the environment variable DTRACEFLAGS. On Solaris, to include DTrace support in a 64-bit binary, you must specify - DTRACEFLAGS="-64" to configure. For example, + DTRACEFLAGS="-64". For example, using the GCC compiler: ./configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ... @@ -1313,36 +1643,50 @@ su - postgres - - - - - - Enable tests using the Perl TAP tools. This requires a Perl - installation and the Perl module IPC::Run. - See for more information. - - - - - - If you prefer a C compiler different from the one - configure picks, you can set the - environment variable CC to the program of your choice. - By default, configure will pick - gcc if available, else the platform's - default (usually cc). Similarly, you can override the - default compiler flags if needed with the CFLAGS variable. - + + + + + + <filename>configure</filename> Environment Variables + + + configure environment variables + + In addition to the ordinary command-line options described above, + configure responds to a number of environment + variables. You can specify environment variables on the configure command line, for example: ./configure CC=/opt/bin/gcc CFLAGS='-O2 -pipe' + In this usage an environment variable is little different from a + command-line option. + You can also set such variables beforehand: + +export CC=/opt/bin/gcc +export CFLAGS='-O2 -pipe' +./configure + + This usage can be convenient because many programs' configuration + scripts respond to these variables in similar ways. + + + + The most commonly used of these environment variables are + CC and CFLAGS. + If you prefer a C compiler different from the one + configure picks, you can set the + variable CC to the program of your choice. + By default, configure will pick + gcc if available, else the platform's + default (usually cc). Similarly, you can override the + default compiler flags if needed with the CFLAGS variable. @@ -1482,7 +1826,7 @@ su - postgres llvm-config program used to locate the - LLVM installation. + LLVM installation @@ -1500,8 +1844,9 @@ su - postgres PERL - Full path name of the Perl interpreter. This will be used to - determine the dependencies for building PL/Perl. + Perl interpreter program. This will be used to determine the + dependencies for building PL/Perl. The default is + perl. @@ -1510,13 +1855,14 @@ su - postgres PYTHON - Full path name of the Python interpreter. This will be used to + Python interpreter program. This will be used to determine the dependencies for building PL/Python. Also, whether Python 2 or 3 is specified here (or otherwise implicitly chosen) determines which variant of the PL/Python language becomes available. See - for more information. + for more information. If this is not set, the following are probed + in this order: python python3 python2. @@ -1525,9 +1871,11 @@ su - postgres TCLSH - Full path name of the Tcl interpreter. This will be used to - determine the dependencies for building PL/Tcl, and it will - be substituted into Tcl scripts. + Tcl interpreter program. This will be used to + determine the dependencies for building PL/Tcl. + If this is not set, the following are probed in this + order: tclsh tcl tclsh8.6 tclsh86 tclsh8.5 tclsh85 + tclsh8.4 tclsh84. @@ -1537,7 +1885,7 @@ su - postgres xml2-config program used to locate the - libxml installation. + libxml installation @@ -1565,13 +1913,6 @@ su - postgres - - When developing code inside the server, it is recommended to - use the configure options (which - turns on many run-time error checks) and - (which improves the usefulness of debugging tools). - - If using GCC, it is best to build with an optimization level of at least , because using no optimization @@ -1593,180 +1934,13 @@ su - postgres adjustments, while COPT might be kept set all the time. - - - - Build - - - To start the build, type: - -make - - (Remember to use GNU make.) The build - will take a few minutes depending on your - hardware. The last line displayed should be: - -All of PostgreSQL successfully made. Ready to install. - - - - - If you want to build everything that can be built, including the - documentation (HTML and man pages), and the additional modules - (contrib), type instead: - -make world - - The last line displayed should be: - -PostgreSQL, contrib, and documentation successfully made. Ready to install. - - - - - - Regression Tests - - - regression test - - - - If you want to test the newly built server before you install it, - you can run the regression tests at this point. The regression - tests are a test suite to verify that PostgreSQL - runs on your machine in the way the developers expected it - to. Type: - -make check - - (This won't work as root; do it as an unprivileged user.) - See for - detailed information about interpreting the test results. You can - repeat this test at any later time by issuing the same command. - - - - - Installing the Files - - - - If you are upgrading an existing system be sure to read - , - which has instructions about upgrading a - cluster. - - - - - To install PostgreSQL enter: - -make install - - This will install files into the directories that were specified - in . Make sure that you have appropriate - permissions to write into that area. Normally you need to do this - step as root. Alternatively, you can create the target - directories in advance and arrange for appropriate permissions to - be granted. - - - - To install the documentation (HTML and man pages), enter: - -make install-docs - - - - - If you built the world above, type instead: - -make install-world - - This also installs the documentation. - - - - You can use make install-strip instead of - make install to strip the executable files and - libraries as they are installed. This will save some space. If - you built with debugging support, stripping will effectively - remove the debugging support, so it should only be done if - debugging is no longer needed. install-strip - tries to do a reasonable job saving space, but it does not have - perfect knowledge of how to strip every unneeded byte from an - executable file, so if you want to save all the disk space you - possibly can, you will have to do manual work. - - - - The standard installation provides all the header files needed for client - application development as well as for server-side program - development, such as custom functions or data types written in C. - (Prior to PostgreSQL 8.0, a separate make - install-all-headers command was needed for the latter, but this - step has been folded into the standard install.) - - - - Client-only installation: - - If you want to install only the client applications and - interface libraries, then you can use these commands: - -make -C src/bin install -make -C src/include install -make -C src/interfaces install -make -C doc install - - src/bin has a few binaries for server-only use, - but they are small. - - - - - - - Uninstallation: - - To undo the installation use the command make - uninstall. However, this will not remove any created directories. - - - - - Cleaning: - - - After the installation you can free disk space by removing the built - files from the source tree with the command make - clean. This will preserve the files made by the configure - program, so that you can rebuild everything with make - later on. To reset the source tree to the state in which it was - distributed, use make distclean. If you are going to - build for several platforms within the same source tree you must do - this and re-configure for each platform. (Alternatively, use - a separate build tree for each platform, so that the source tree - remains unmodified.) - - - - - If you perform a build and then discover that your configure - options were wrong, or if you change anything that configure - investigates (for example, software upgrades), then it's a good - idea to do make distclean before reconfiguring and - rebuilding. Without this, your changes in configuration choices - might not propagate everywhere they need to. - + Post-Installation Setup - + Shared Libraries @@ -1805,7 +1979,7 @@ setenv LD_LIBRARY_PATH /usr/local/pgsql/lib /etc/profile or ~/.bash_profile. Some good information about the caveats associated with this method can be found at . + url="http://xahlee.info/UnixResource_dir/_/ldpath.html">. @@ -1954,15 +2128,15 @@ export MANPATH If you have installation problems on a platform that is known to be supported according to recent build farm results, please report - it to pgsql-bugs@postgresql.org. If you are interested + it to pgsql-bugs@lists.postgresql.org. If you are interested in porting PostgreSQL to a new platform, - pgsql-hackers@postgresql.org is the appropriate place + pgsql-hackers@lists.postgresql.org is the appropriate place to discuss that. - Platform-specific Notes + Platform-Specific Notes This section documents additional platform-specific issues @@ -1987,175 +2161,11 @@ export MANPATH - PostgreSQL works on AIX, but getting it installed properly can be - challenging. AIX versions from 4.3.3 to 6.1 are considered supported. - You can use GCC or the native IBM compiler xlc. In - general, using recent versions of AIX and PostgreSQL helps. Check - the build farm for up to date information about which versions of - AIX are known to work. - - - - The minimum recommended fix levels for supported AIX versions are: - - - - - AIX 4.3.3 - Maintenance Level 11 + post ML11 bundle - - - - AIX 5.1 - Maintenance Level 9 + post ML9 bundle - - - - AIX 5.2 - Technology Level 10 Service Pack 3 - - - - AIX 5.3 - Technology Level 7 - - - - AIX 6.1 - Base Level - - - - - To check your current fix level, use - oslevel -r in AIX 4.3.3 to AIX 5.2 ML 7, or - oslevel -s in later versions. - - - - Use the following configure flags in addition - to your own if you have installed Readline or libz in - /usr/local: - --with-includes=/usr/local/include - --with-libraries=/usr/local/lib. + PostgreSQL works on AIX, but AIX versions before about 6.1 have + various issues and are not recommended. + You can use GCC or the native IBM compiler xlc. - - GCC Issues - - - On AIX 5.3, there have been some problems getting PostgreSQL to - compile and run using GCC. - - - - You will want to use a version of GCC subsequent to 3.3.2, - particularly if you use a prepackaged version. We had good - success with 4.0.1. Problems with earlier versions seem to have - more to do with the way IBM packaged GCC than with actual issues - with GCC, so that if you compile GCC yourself, you might well - have success with an earlier version of GCC. - - - - - Unix-Domain Sockets Broken - - - AIX 5.3 has a problem - where sockaddr_storage is not defined to - be large enough. In version 5.3, IBM increased the size of - sockaddr_un, the address structure for - Unix-domain sockets, but did not correspondingly increase the - size of sockaddr_storage. The result of - this is that attempts to use Unix-domain sockets with PostgreSQL - lead to libpq overflowing the data structure. TCP/IP connections - work OK, but not Unix-domain sockets, which prevents the - regression tests from working. - - - - The problem was reported to IBM, and is recorded as bug report - PMR29657. If you upgrade to maintenance level 5300-03 or later, - that will include this fix. A quick workaround - is to alter _SS_MAXSIZE to 1025 in - /usr/include/sys/socket.h. In either case, - recompile PostgreSQL once you have the corrected header file. - - - - - Internet Address Issues - - - PostgreSQL relies on the system's getaddrinfo function - to parse IP addresses in listen_addresses, - pg_hba.conf, etc. Older versions of AIX have assorted - bugs in this function. If you have problems related to these settings, - updating to the appropriate AIX fix level shown above - should take care of it. - - - - - - One user reports: - - - - When implementing PostgreSQL version 8.1 on AIX 5.3, we - periodically ran into problems where the statistics collector - would mysteriously not come up successfully. This - appears to be the result of unexpected behavior in the IPv6 - implementation. It looks like PostgreSQL and IPv6 do not play - very well together on AIX 5.3. - - - - Any of the following actions fix the problem. - - - - Delete the IPv6 address for localhost: - -(as root) -# ifconfig lo0 inet6 ::1/0 delete - - - - - - - Remove IPv6 from net services. The - file /etc/netsvc.conf on AIX is roughly - equivalent to /etc/nsswitch.conf on - Solaris/Linux. The default, on AIX, is thus: - -hosts=local,bind - - Replace this with: - -hosts=local4,bind4 - - to deactivate searching for IPv6 addresses. - - - - - - - - This is really a workaround for problems relating - to immaturity of IPv6 support, which improved visibly during the - course of AIX 5.3 releases. It has worked with AIX version 5.3, - but does not represent an elegant solution to the problem. It has - been reported that this workaround is not only unnecessary, but - causes problems on AIX 6.1, where IPv6 support has become more mature. - - - - - Memory Management @@ -2325,9 +2335,9 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address - When building from source, proceed according to the normal + When building from source, proceed according to the Unix-style installation procedure (i.e., ./configure; - make; etc.), noting the following-Cygwin specific + make; etc.), noting the following Cygwin-specific differences: @@ -2379,7 +2389,7 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address Building might fail on some systems where a locale other than C is in use. To fix this, set the locale to C by doing export LANG=C.utf8 before building, and then - setting it back to the previous setting, after you have installed + setting it back to the previous setting after you have installed PostgreSQL. @@ -2396,7 +2406,7 @@ ERROR: could not load library "/opt/dbs/pgsql/lib/plperl.so": Bad address make MAX_CONNECTIONS=5 check (On some systems you can have up to about 10 simultaneous - connections). + connections.) @@ -2412,91 +2422,54 @@ make MAX_CONNECTIONS=5 check - - HP-UX + + macOS - - HP-UX + + macOS installation on - PostgreSQL 7.3+ should work on Series 700/800 PA-RISC machines - running HP-UX 10.X or 11.X, given appropriate system patch levels - and build tools. At least one developer routinely tests on HP-UX - 10.20, and we have reports of successful installations on HP-UX - 11.00 and 11.11. - - - - Aside from the PostgreSQL source distribution, you will need GNU - make (HP's make will not do), and either GCC or HP's full ANSI C - compiler. If you intend to build from Git sources rather than a - distribution tarball, you will also need Flex (GNU lex) and Bison - (GNU yacc). We also recommend making sure you are fairly - up-to-date on HP patches. At a minimum, if you are building 64 - bit binaries on HP-UX 11.11 you may need PHSS_30966 (11.11) or a - successor patch otherwise initdb may hang: - -PHSS_30966 s700_800 ld(1) and linker tools cumulative patch - - - On general principles you should be current on libc and ld/dld - patches, as well as compiler patches if you are using HP's C - compiler. See HP's support sites such - as for free - copies of their latest patches. - - - - If you are building on a PA-RISC 2.0 machine and want to have - 64-bit binaries using GCC, you must use a GCC 64-bit version. - - - - If you are building on a PA-RISC 2.0 machine and want the compiled - binaries to run on PA-RISC 1.1 machines you will need to specify - in CFLAGS. - - - - If you are building on a HP-UX Itanium machine, you will need the - latest HP ANSI C compiler with its dependent patch or successor - patches: - -PHSS_30848 s700_800 HP C Compiler (A.05.57) -PHSS_30849 s700_800 u2comp/be/plugin library Patch - - - - - If you have both HP's C compiler and GCC's, then you might want to - explicitly select the compiler to use when you - run configure: + On recent macOS releases, it's necessary to + embed the sysroot path in the include switches used to + find some system header files. This results in the outputs of + the configure script varying depending on + which SDK version was used during configure. + That shouldn't pose any problem in simple scenarios, but if you are + trying to do something like building an extension on a different machine + than the server code was built on, you may need to force use of a + different sysroot path. To do that, set PG_SYSROOT, + for example -./configure CC=cc +make PG_SYSROOT=/desired/path all - for HP's C compiler, or + To find out the appropriate path on your machine, run -./configure CC=gcc +xcodebuild -version -sdk macosx Path - for GCC. If you omit this setting, then configure will - pick gcc if it has a choice. + Note that building an extension using a different sysroot version than + was used to build the core server is not really recommended; in the + worst case it could result in hard-to-debug ABI inconsistencies. - The default install target location - is /usr/local/pgsql, which you might want to - change to something under /opt. If so, use - the - switch to configure. + You can also select a non-default sysroot path when configuring, by + specifying PG_SYSROOT + to configure: + +./configure ... PG_SYSROOT=/desired/path + - In the regression tests, there might be some low-order-digit - differences in the geometry tests, which vary depending on which - compiler and math library versions you use. Any other error is - cause for suspicion. + macOS's System Integrity + Protection (SIP) feature breaks make check, + because it prevents passing the needed setting + of DYLD_LIBRARY_PATH down to the executables being + tested. You can work around that by doing make + install before make check. + Most PostgreSQL developers just turn off SIP, though. @@ -2512,12 +2485,9 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch PostgreSQL for Windows can be built using MinGW, a Unix-like build environment for Microsoft operating systems, or using Microsoft's Visual C++ compiler suite. - The MinGW build variant uses the normal build system described in + The MinGW build procedure uses the normal build system described in this chapter; the Visual C++ build works completely differently and is described in . - It is a fully native build and uses no additional software like - MinGW. A ready-made installer is available on the main - PostgreSQL web site. @@ -2534,7 +2504,7 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch To build 64 bit binaries using MinGW, install the 64 bit tool set - from , put its bin + from , put its bin directory in the PATH, and run configure with the --host=x86_64-w64-mingw32 option. @@ -2574,8 +2544,7 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch PostgreSQL is well-supported on Solaris. The more up to date your - operating system, the fewer issues you will experience; details - below. + operating system, the fewer issues you will experience. @@ -2584,8 +2553,7 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch You can build with either GCC or Sun's compiler suite. For better code optimization, Sun's compiler is strongly recommended - on the SPARC architecture. We have heard reports of problems - when using GCC 2.95.1; GCC 2.95.3 or later is recommended. If + on the SPARC architecture. If you are using Sun's compiler, be careful not to select /usr/ucb/cc; use /opt/SUNWspro/bin/cc. @@ -2593,14 +2561,14 @@ PHSS_30849 s700_800 u2comp/be/plugin library Patch You can download Sun Studio - from . - Many of GNU tools are integrated into Solaris 10, or they are - present on the Solaris companion CD. If you like packages for - older version of Solaris, you can find these tools + from . + Many GNU tools are integrated into Solaris 10, or they are + present on the Solaris companion CD. If you need packages for + older versions of Solaris, you can find these tools at . If you prefer sources, look - at . + at . @@ -2623,30 +2591,6 @@ configure ... LDFLAGS="-R /usr/sfw/lib:/opt/sfw/lib:/usr/local/lib" - - 64-bit Build Sometimes Crashes - - - On Solaris 7 and older, the 64-bit version of libc has a buggy - vsnprintf routine, which leads to erratic - core dumps in PostgreSQL. The simplest known workaround is to - force PostgreSQL to use its own version of vsnprintf rather than - the library copy. To do this, after you - run configure edit a file produced by - configure: - In src/Makefile.global, change the line - -LIBOBJS = - - to read - -LIBOBJS = snprintf.o - - (There might be other files already listed in this variable. - Order does not matter.) Then build as usual. - - - Compiling for Optimal Performance @@ -2656,18 +2600,15 @@ LIBOBJS = snprintf.o flag to generate significantly faster binaries. Do not use any flags that modify behavior of floating-point operations and errno processing (e.g., - ). These flags could raise some - nonstandard PostgreSQL behavior for example in the date/time - computing. + ). If you do not have a reason to use 64-bit binaries on SPARC, prefer the 32-bit version. The 64-bit operations are slower and - 64-bit binaries are slower than the 32-bit variants. And on + 64-bit binaries are slower than the 32-bit variants. On the other hand, 32-bit code on the AMD64 CPU family is not native, - and that is why 32-bit code is significant slower on this CPU - family. + so 32-bit code is significantly slower on that CPU family. @@ -2692,7 +2633,7 @@ collect2: ld returned 1 exit status make: *** [postgres] Error 1 your DTrace installation is too old to handle probes in static - functions. You need Solaris 10u4 or newer. + functions. You need Solaris 10u4 or newer to use DTrace. diff --git a/doc/src/sgml/intro.sgml b/doc/src/sgml/intro.sgml index 3038826311a..25e98ebe07d 100644 --- a/doc/src/sgml/intro.sgml +++ b/doc/src/sgml/intro.sgml @@ -82,7 +82,7 @@ - What is <productname>PostgreSQL</productname>? + What Is <productname>PostgreSQL</productname>? PostgreSQL is an object-relational diff --git a/doc/src/sgml/isn.sgml b/doc/src/sgml/isn.sgml index 34d37ede018..598dda2e9a8 100644 --- a/doc/src/sgml/isn.sgml +++ b/doc/src/sgml/isn.sgml @@ -355,19 +355,19 @@ SELECT isbn13(id) FROM test; The information to implement this module was collected from several sites, including: - + - - + + The prefixes used for hyphenation were also compiled from: - - + + - - + + Care was taken during the creation of the algorithms and they diff --git a/doc/src/sgml/jit.sgml b/doc/src/sgml/jit.sgml index 2a647e8c6c5..af7e380c58c 100644 --- a/doc/src/sgml/jit.sgml +++ b/doc/src/sgml/jit.sgml @@ -18,25 +18,25 @@ - What is <acronym>JIT</acronym> compilation? + What Is <acronym>JIT</acronym> compilation? - Just-in-time compilation (JIT) is the process of turning + Just-in-Time (JIT) compilation is the process of turning some form of interpreted program evaluation into a native program, and - doing so at runtime. - - For example, instead of using a facility that can evaluate arbitrary SQL - expressions to evaluate an SQL predicate like WHERE a.col = - 3, it is possible to generate a function than can be natively - executed by the CPU that just handles that expression, yielding a speedup. + doing so at run time. + For example, instead of using general-purpose code that can evaluate + arbitrary SQL expressions to evaluate a particular SQL predicate + like WHERE a.col = 3, it is possible to generate a + function that is specific to that expression and can be natively executed + by the CPU, yielding a speedup. PostgreSQL has builtin support to perform JIT compilation using LLVM when - PostgreSQL was built with - --with-llvm (see ). + PostgreSQL is built with + --with-llvm. @@ -58,9 +58,23 @@ Tuple deforming is the process of transforming an on-disk tuple (see ) into its in-memory representation. It can be - accelerated by creating a function specific to the table layout and the - number of columns to be extracted. + linkend="storage-tuple-layout"/>) into its in-memory representation. + It can be accelerated by creating a function specific to the table layout + and the number of columns to be extracted. + + + + + Inlining + + PostgreSQL is very extensible and allows new + data types, functions, operators and other database objects to be defined; + see . In fact the built-in objects are implemented + using nearly the same mechanisms. This extensibility implies some + overhead, for example due to function calls (see ). + To reduce that overhead, JIT compilation can inline the + bodies of small functions into the expressions using them. That allows a + significant percentage of the overhead to be optimized away. @@ -70,27 +84,12 @@ LLVM has support for optimizing generated code. Some of the optimizations are cheap enough to be performed whenever JIT is used, while others are only beneficial for - longer running queries. - + longer-running queries. See for more details about optimizations. - - Inlining - - PostgreSQL is very extensible and allows new - datatypes, functions, operators and other database objects to be defined; - see . In fact the built-in ones are implemented - using nearly the same mechanisms. This extensibility implies some - overhead, for example due to function calls (see ). - To reduce that overhead JIT compilation can inline the - body for small functions into the expression using them. That allows a - significant percentage of the overhead to be optimized away. - - - @@ -98,50 +97,46 @@ JIT compilation is beneficial primarily for long-running - CPU bound queries. Frequently these will be analytical queries. For short + CPU-bound queries. Frequently these will be analytical queries. For short queries the added overhead of performing JIT compilation will often be higher than the time it can save. - To determine whether JIT compilation is used, the total - cost of a query (see and ) is used. - - - - The cost of the query will be compared with GUC. If the cost is higher, + To determine whether JIT compilation should be used, + the total estimated cost of a query (see + and + ) is used. + The estimated cost of the query will be compared with the setting of . If the cost is higher, JIT compilation will be performed. + Two further decisions are then needed. + Firstly, if the estimated cost is more + than the setting of , short + functions and operators used in the query will be inlined. + Secondly, if the estimated cost is more than the setting of , expensive optimizations are + applied to improve the generated code. + Each of these options increases the JIT compilation + overhead, but can reduce query execution time considerably. - If the planner, based on the above criterion, decided that - JIT compilation is beneficial, two further decisions are - made. Firstly, if the query is more costly than the GUC, expensive optimizations are - used to improve the generated code. Secondly, if the query is more costly - than the GUC, short functions - and operators used in the query will be inlined. Both of these operations - increase the JIT overhead, but can reduce query - execution time considerably. - - - - This cost based decision will be made at plan time, not execution - time. This means that when prepared statements are in use, and the generic - plan is used (see ), the values of the - GUCs set at prepare time take effect, not the settings at execution time. + These cost-based decisions will be made at plan time, not execution + time. This means that when prepared statements are in use, and a generic + plan is used (see ), the values of the + configuration parameters in effect at prepare time control the decisions, + not the settings at execution time. - If is set to off, or no + If is set to off, or if no JIT implementation is available (for example because the server was compiled without --with-llvm), - JIT will not performed, even if considered to be + JIT will not be performed, even if it would be beneficial based on the above criteria. Setting - to off takes effect both at plan and at execution time. + to off has effects at both plan and execution time. @@ -149,48 +144,40 @@ can be used to see whether JIT is used or not. As an example, here is a query that is not using JIT: - + =# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┠-│ QUERY PLAN │ -├─────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -│ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1) │ -│ -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1) │ -│ Planning Time: 0.116 ms │ -│ Execution Time: 0.365 ms │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=0.303..0.303 rows=1 loops=1) + -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.017..0.111 rows=356 loops=1) + Planning Time: 0.116 ms + Execution Time: 0.365 ms (4 rows) - + Given the cost of the plan, it is entirely reasonable that no - JIT was used, the cost of JIT would - have been bigger than the savings. Adjusting the cost limits will lead to - JIT use: - + JIT was used; the cost of JIT would + have been bigger than the potential savings. Adjusting the cost limits + will lead to JIT use: + =# SET jit_above_cost = 10; SET =# EXPLAIN ANALYZE SELECT SUM(relpages) FROM pg_class; -┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────┠-│ QUERY PLAN │ -├─────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ -│ Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1) │ -│ -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1) │ -│ Planning Time: 0.133 ms │ -│ JIT: │ -│ Functions: 3 │ -│ Generation Time: 1.259 ms │ -│ Inlining: false │ -│ Inlining Time: 0.000 ms │ -│ Optimization: false │ -│ Optimization Time: 0.797 ms │ -│ Emission Time: 5.048 ms │ -│ Execution Time: 7.416 ms │ -└─────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ - + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Aggregate (cost=16.27..16.29 rows=1 width=8) (actual time=6.049..6.049 rows=1 loops=1) + -> Seq Scan on pg_class (cost=0.00..15.42 rows=342 width=4) (actual time=0.019..0.052 rows=356 loops=1) + Planning Time: 0.133 ms + JIT: + Functions: 3 + Options: Inlining false, Optimization false, Expressions true, Deforming true + Timing: Generation 1.259 ms, Inlining 0.000 ms, Optimization 0.797 ms, Emission 5.048 ms, Total 7.104 ms + Execution Time: 7.416 ms + As visible here, JIT was used, but inlining and expensive optimization were not. If , were lowered, just like , that would change. + linkend="guc-jit-inline-above-cost"/> or were also lowered, + that would change. @@ -198,58 +185,53 @@ SET Configuration + The configuration variable determines whether JIT compilation is enabled or disabled. - - - - As explained in the configuration variables + If it is enabled, the configuration variables , , decide whether JIT - compilation is performed for a query, and how much effort is spent doing - so. + linkend="guc-jit-inline-above-cost"/>, and determine + whether JIT compilation is performed for a query, + and how much effort is spent doing so. - For development and debugging purposes a few additional GUCs exist. allows the generated bitcode to be - inspected. allows GDB to see - generated functions. emits - information so the perf profiler can interpret - JIT generated functions sensibly. + determines which JIT + implementation is used. It is rarely required to be changed. See . - determines which JIT - implementation is used. It rarely is required to be changed. See . + For development and debugging purposes a few additional configuration + parameters exist, as described in + . - + Extensibility Inlining Support for Extensions PostgreSQL's JIT - implementation can inline the implementation of operators and functions - (of type C and internal). See . To do so for functions in extensions, the - definition of these functions needs to be made available. When using PGXS to build an extension against a server - that has been compiled with LLVM support, the relevant files will be - installed automatically. + implementation can inline the bodies of functions + of types C and internal, as well as + operators based on such functions. To do so for functions in extensions, + the definitions of those functions need to be made available. + When using PGXS to build an extension + against a server that has been compiled with LLVM JIT support, the + relevant files will be built and installed automatically. The relevant files have to be installed into $pkglibdir/bitcode/$extension/ and a summary of them - to $pkglibdir/bitcode/$extension.index.bc, where + into $pkglibdir/bitcode/$extension.index.bc, where $pkglibdir is the directory returned by pg_config --pkglibdir and $extension - the basename of the extension's shared library. + is the base name of the extension's shared library. @@ -262,14 +244,16 @@ SET - Pluggable <acronym>JIT</acronym> Provider + Pluggable <acronym>JIT</acronym> Providers PostgreSQL provides a JIT implementation based on LLVM. The interface to the JIT provider is pluggable and the provider can be - changed without recompiling. The provider is chosen via the GUC. + changed without recompiling (although currently, the build process only + provides inlining support data for LLVM). + The active provider is chosen via the setting + . @@ -279,19 +263,20 @@ SET named shared library. The normal library search path is used to locate the library. To provide the required JIT provider callbacks and to indicate that the library is actually a - JIT provider it needs to provide a function named + JIT provider, it needs to provide a C function named _PG_jit_provider_init. This function is passed a struct that needs to be filled with the callback function pointers for - individual actions. - + individual actions: + struct JitProviderCallbacks { JitProviderResetAfterErrorCB reset_after_error; JitProviderReleaseContextCB release_context; JitProviderCompileExprCB compile_expr; }; + extern void _PG_jit_provider_init(JitProviderCallbacks *cb); - + diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml index e7b68fa0d24..6ff87518705 100644 --- a/doc/src/sgml/json.sgml +++ b/doc/src/sgml/json.sgml @@ -22,8 +22,16 @@ - There are two JSON data types: json and jsonb. - They accept almost identical sets of values as + PostgreSQL offers two types for storing JSON + data: json and jsonb. To implement efficient query + mechanisms for these data types, PostgreSQL + also provides the jsonpath data type described in + . + + + + The json and jsonb data types + accept almost identical sets of values as input. The major practical difference is one of efficiency. The json data type stores an exact copy of the input text, which processing functions must reparse on each execution; while @@ -123,7 +131,7 @@
- JSON primitive types and corresponding <productname>PostgreSQL</productname> types + JSON Primitive Types and Corresponding <productname>PostgreSQL</productname> Types @@ -217,10 +225,15 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb; in this example, even though those are semantically insignificant for purposes such as equality checks. + + + For the list of built-in functions and operators available for + constructing and processing JSON values, see . + - Designing JSON documents effectively + Designing JSON Documents Representing data as JSON can be considerably more flexible than the traditional relational data model, which is compelling in @@ -467,6 +480,22 @@ CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags')); (More information on expression indexes can be found in .) + + Also, GIN index supports @@ and @? + operators, which perform jsonpath matching. + +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @@ '$.tags[*] == "qui"'; + + +SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @@ '$.tags[*] ? (@ == "qui")'; + + GIN index extracts statements of following form out of + jsonpath: accessors_chain = const. + Accessors chain may consist of .key, + [*], and [index] accessors. + jsonb_ops additionally supports .* + and .** accessors. + Another approach to querying is to exploit containment, for example: @@ -485,7 +514,8 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu Although the jsonb_path_ops operator class supports - only queries with the @> operator, it has notable + only queries with the @>, @@ + and @? operators, it has notable performance advantages over the default operator class jsonb_ops. A jsonb_path_ops index is usually much smaller than a jsonb_ops @@ -593,4 +623,273 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu lists, and scalars, as appropriate. + + + jsonpath Type + + + jsonpath + + + + The jsonpath type implements support for the SQL/JSON path language + in PostgreSQL to efficiently query JSON data. + It provides a binary representation of the parsed SQL/JSON path + expression that specifies the items to be retrieved by the path + engine from the JSON data for further processing with the + SQL/JSON query functions. + + + + The semantics of SQL/JSON path predicates and operators generally follow SQL. + At the same time, to provide a most natural way of working with JSON data, + SQL/JSON path syntax uses some of the JavaScript conventions: + + + + + + Dot (.) is used for member access. + + + + + Square brackets ([]) are used for array access. + + + + + SQL/JSON arrays are 0-relative, unlike regular SQL arrays that start from 1. + + + + + + An SQL/JSON path expression is typically written in an SQL query as an + SQL character string literal, so it must be enclosed in single quotes, + and any single quotes desired within the value must be doubled + (see ). + Some forms of path expressions require string literals within them. + These embedded string literals follow JavaScript/ECMAScript conventions: + they must be surrounded by double quotes, and backslash escapes may be + used within them to represent otherwise-hard-to-type characters. + In particular, the way to write a double quote within an embedded string + literal is \", and to write a backslash itself, you + must write \\. Other special backslash sequences + include those recognized in JSON strings: + \b, + \f, + \n, + \r, + \t, + \v + for various ASCII control characters, and + \uNNNN for a Unicode + character identified by its 4-hex-digit code point. The backslash + syntax also includes two cases not allowed by JSON: + \xNN for a character code + written with only two hex digits, and + \u{N...} for a character + code written with 1 to 6 hex digits. + + + + A path expression consists of a sequence of path elements, + which can be the following: + + + + Path literals of JSON primitive types: + Unicode text, numeric, true, false, or null. + + + + + Path variables listed in . + + + + + Accessor operators listed in . + + + + + jsonpath operators and methods listed + in + + + + + Parentheses, which can be used to provide filter expressions + or define the order of path evaluation. + + + + + + + For details on using jsonpath expressions with SQL/JSON + query functions, see . + + +
+ <type>jsonpath</type> Variables + + + + Variable + Description + + + + + $ + A variable representing the JSON text to be queried + (the context item). + + + + $varname + + A named variable. Its value can be set by the parameter + vars of several JSON processing functions. + See and + its notes for details. + + + + + @ + A variable representing the result of path evaluation + in filter expressions. + + + + +
+ + + <type>jsonpath</type> Accessors + + + + Accessor Operator + Description + + + + + + + .key + + + ."$varname" + + + + + Member accessor that returns an object member with + the specified key. If the key name is a named variable + starting with $ or does not meet the + JavaScript rules of an identifier, it must be enclosed in + double quotes as a character string literal. + + + + + + + .* + + + + + Wildcard member accessor that returns the values of all + members located at the top level of the current object. + + + + + + + .** + + + + + Recursive wildcard member accessor that processes all levels + of the JSON hierarchy of the current object and returns all + the member values, regardless of their nesting level. This + is a PostgreSQL extension of + the SQL/JSON standard. + + + + + + + .**{level} + + + .**{start_level to + end_level} + + + + + Same as .**, but with a filter over nesting + levels of JSON hierarchy. Nesting levels are specified as integers. + Zero level corresponds to the current object. To access the lowest + nesting level, you can use the last keyword. + This is a PostgreSQL extension of + the SQL/JSON standard. + + + + + + + [subscript, ...] + + + + + Array element accessor. + subscript can be + given in two forms: index + or start_index to end_index. + The first form returns a single array element by its index. The second + form returns an array slice by the range of indexes, including the + elements that correspond to the provided + start_index and end_index. + + + The specified index can be an integer, as + well as an expression returning a single numeric value, which is + automatically cast to integer. Zero index corresponds to the first + array element. You can also use the last keyword + to denote the last array element, which is useful for handling arrays + of unknown length. + + + + + + + [*] + + + + + Wildcard array element accessor that returns all array elements. + + + + + +
+ +
diff --git a/doc/src/sgml/keywords.sgml b/doc/src/sgml/keywords.sgml index 2dba7adedfe..57dcd6ae5c7 100644 --- a/doc/src/sgml/keywords.sgml +++ b/doc/src/sgml/keywords.sgml @@ -75,5330 +75,6 @@ presence of a key word does not indicate the existence of a feature. - - - - - <acronym>SQL</acronym> Key Words - - - - - Key Word - PostgreSQL - SQL:2011 - SQL:2008 - SQL-92 - - - - - - A - - non-reserved - non-reserved - - - - ABORT - non-reserved - - - - - - ABS - - reserved - reserved - - - - ABSENT - - non-reserved - non-reserved - - - - ABSOLUTE - non-reserved - non-reserved - non-reserved - reserved - - - ACCESS - non-reserved - - - - - - ACCORDING - - non-reserved - non-reserved - - - - ACTION - non-reserved - non-reserved - non-reserved - reserved - - - ADA - - non-reserved - non-reserved - non-reserved - - - ADD - non-reserved - non-reserved - non-reserved - reserved - - - ADMIN - non-reserved - non-reserved - non-reserved - - - - AFTER - non-reserved - non-reserved - non-reserved - - - - AGGREGATE - non-reserved - - - - - - ALL - reserved - reserved - reserved - reserved - - - ALLOCATE - - reserved - reserved - reserved - - - ALSO - non-reserved - - - - - - ALTER - non-reserved - reserved - reserved - reserved - - - ALWAYS - non-reserved - non-reserved - non-reserved - - - - ANALYSE - reserved - - - - - - ANALYZE - reserved - - - - - - AND - reserved - reserved - reserved - reserved - - - ANY - reserved - reserved - reserved - reserved - - - ARE - - reserved - reserved - reserved - - - ARRAY - reserved - reserved - reserved - - - - ARRAY_AGG - - reserved - reserved - - - - ARRAY_MAX_CARDINALITY - - reserved - - - - - AS - reserved - reserved - reserved - reserved - - - ASC - reserved - non-reserved - non-reserved - reserved - - - ASENSITIVE - - reserved - reserved - - - - ASSERTION - non-reserved - non-reserved - non-reserved - reserved - - - ASSIGNMENT - non-reserved - non-reserved - non-reserved - - - - ASYMMETRIC - reserved - reserved - reserved - - - - AT - non-reserved - reserved - reserved - reserved - - - ATOMIC - - reserved - reserved - - - - ATTACH - non-reserved - - - - - - ATTRIBUTE - non-reserved - non-reserved - non-reserved - - - - ATTRIBUTES - - non-reserved - non-reserved - - - - AUTHORIZATION - reserved (can be function or type) - reserved - reserved - reserved - - - AVG - - reserved - reserved - reserved - - - BACKWARD - non-reserved - - - - - - BASE64 - - non-reserved - non-reserved - - - - BEFORE - non-reserved - non-reserved - non-reserved - - - - BEGIN - non-reserved - reserved - reserved - reserved - - - BEGIN_FRAME - - reserved - - - - - BEGIN_PARTITION - - reserved - - - - - BERNOULLI - - non-reserved - non-reserved - - - - BETWEEN - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - BIGINT - non-reserved (cannot be function or type) - reserved - reserved - - - - BINARY - reserved (can be function or type) - reserved - reserved - - - - BIT - non-reserved (cannot be function or type) - - - reserved - - - BIT_LENGTH - - - - reserved - - - BLOB - - reserved - reserved - - - - BLOCKED - - non-reserved - non-reserved - - - - BOM - - non-reserved - non-reserved - - - - BOOLEAN - non-reserved (cannot be function or type) - reserved - reserved - - - - BOTH - reserved - reserved - reserved - reserved - - - BREADTH - - non-reserved - non-reserved - - - - BY - non-reserved - reserved - reserved - reserved - - - C - - non-reserved - non-reserved - non-reserved - - - CACHE - non-reserved - - - - - - CALL - - reserved - reserved - - - - CALLED - non-reserved - reserved - reserved - - - - CARDINALITY - - reserved - reserved - - - - CASCADE - non-reserved - non-reserved - non-reserved - reserved - - - CASCADED - non-reserved - reserved - reserved - reserved - - - CASE - reserved - reserved - reserved - reserved - - - CAST - reserved - reserved - reserved - reserved - - - CATALOG - non-reserved - non-reserved - non-reserved - reserved - - - CATALOG_NAME - - non-reserved - non-reserved - non-reserved - - - CEIL - - reserved - reserved - - - - CEILING - - reserved - reserved - - - - CHAIN - non-reserved - non-reserved - non-reserved - - - - CHAR - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - CHARACTER - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - CHARACTERISTICS - non-reserved - non-reserved - non-reserved - - - - CHARACTERS - - non-reserved - non-reserved - - - - CHARACTER_LENGTH - - reserved - reserved - reserved - - - CHARACTER_SET_CATALOG - - non-reserved - non-reserved - non-reserved - - - CHARACTER_SET_NAME - - non-reserved - non-reserved - non-reserved - - - CHARACTER_SET_SCHEMA - - non-reserved - non-reserved - non-reserved - - - CHAR_LENGTH - - reserved - reserved - reserved - - - CHECK - reserved - reserved - reserved - reserved - - - CHECKPOINT - non-reserved - - - - - - CLASS - non-reserved - - - - - - CLASS_ORIGIN - - non-reserved - non-reserved - non-reserved - - - CLOB - - reserved - reserved - - - - CLOSE - non-reserved - reserved - reserved - reserved - - - CLUSTER - non-reserved - - - - - - COALESCE - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - COBOL - - non-reserved - non-reserved - non-reserved - - - COLLATE - reserved - reserved - reserved - reserved - - - COLLATION - reserved (can be function or type) - non-reserved - non-reserved - reserved - - - COLLATION_CATALOG - - non-reserved - non-reserved - non-reserved - - - COLLATION_NAME - - non-reserved - non-reserved - non-reserved - - - COLLATION_SCHEMA - - non-reserved - non-reserved - non-reserved - - - COLLECT - - reserved - reserved - - - - COLUMN - reserved - reserved - reserved - reserved - - - COLUMNS - non-reserved - non-reserved - non-reserved - - - - COLUMN_NAME - - non-reserved - non-reserved - non-reserved - - - COMMAND_FUNCTION - - non-reserved - non-reserved - non-reserved - - - COMMAND_FUNCTION_CODE - - non-reserved - non-reserved - - - - COMMENT - non-reserved - - - - - - COMMENTS - non-reserved - - - - - - COMMIT - non-reserved - reserved - reserved - reserved - - - COMMITTED - non-reserved - non-reserved - non-reserved - non-reserved - - - CONCURRENTLY - reserved (can be function or type) - - - - - - CONDITION - - reserved - reserved - - - - CONDITION_NUMBER - - non-reserved - non-reserved - non-reserved - - - CONFIGURATION - non-reserved - - - - - - CONFLICT - non-reserved - - - - - - CONNECT - - reserved - reserved - reserved - - - CONNECTION - non-reserved - non-reserved - non-reserved - reserved - - - CONNECTION_NAME - - non-reserved - non-reserved - non-reserved - - - CONSTRAINT - reserved - reserved - reserved - reserved - - - CONSTRAINTS - non-reserved - non-reserved - non-reserved - reserved - - - CONSTRAINT_CATALOG - - non-reserved - non-reserved - non-reserved - - - CONSTRAINT_NAME - - non-reserved - non-reserved - non-reserved - - - CONSTRAINT_SCHEMA - - non-reserved - non-reserved - non-reserved - - - CONSTRUCTOR - - non-reserved - non-reserved - - - - CONTAINS - - reserved - non-reserved - - - - CONTENT - non-reserved - non-reserved - non-reserved - - - - CONTINUE - non-reserved - non-reserved - non-reserved - reserved - - - CONTROL - - non-reserved - non-reserved - - - - CONVERSION - non-reserved - - - - - - CONVERT - - reserved - reserved - reserved - - - COPY - non-reserved - - - - - - CORR - - reserved - reserved - - - - CORRESPONDING - - reserved - reserved - reserved - - - COST - non-reserved - - - - - - COUNT - - reserved - reserved - reserved - - - COVAR_POP - - reserved - reserved - - - - COVAR_SAMP - - reserved - reserved - - - - CREATE - reserved - reserved - reserved - reserved - - - CROSS - reserved (can be function or type) - reserved - reserved - reserved - - - CSV - non-reserved - - - - - - CUBE - non-reserved - reserved - reserved - - - - CUME_DIST - - reserved - reserved - - - - CURRENT - non-reserved - reserved - reserved - reserved - - - CURRENT_CATALOG - reserved - reserved - reserved - - - - CURRENT_DATE - reserved - reserved - reserved - reserved - - - CURRENT_DEFAULT_TRANSFORM_GROUP - - reserved - reserved - - - - CURRENT_PATH - - reserved - reserved - - - - CURRENT_ROLE - reserved - reserved - reserved - - - - CURRENT_ROW - - reserved - - - - - CURRENT_SCHEMA - reserved (can be function or type) - reserved - reserved - - - - CURRENT_TIME - reserved - reserved - reserved - reserved - - - CURRENT_TIMESTAMP - reserved - reserved - reserved - reserved - - - CURRENT_TRANSFORM_GROUP_FOR_TYPE - - reserved - reserved - - - - CURRENT_USER - reserved - reserved - reserved - reserved - - - CURSOR - non-reserved - reserved - reserved - reserved - - - CURSOR_NAME - - non-reserved - non-reserved - non-reserved - - - CYCLE - non-reserved - reserved - reserved - - - - DATA - non-reserved - non-reserved - non-reserved - non-reserved - - - DATABASE - non-reserved - - - - - - DATALINK - - reserved - reserved - - - - DATE - - reserved - reserved - reserved - - - DATETIME_INTERVAL_CODE - - non-reserved - non-reserved - non-reserved - - - DATETIME_INTERVAL_PRECISION - - non-reserved - non-reserved - non-reserved - - - DAY - non-reserved - reserved - reserved - reserved - - - DB - - non-reserved - non-reserved - - - - DEALLOCATE - non-reserved - reserved - reserved - reserved - - - DEC - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - DECIMAL - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - DECLARE - non-reserved - reserved - reserved - reserved - - - DEFAULT - reserved - reserved - reserved - reserved - - - DEFAULTS - non-reserved - non-reserved - non-reserved - - - - DEFERRABLE - reserved - non-reserved - non-reserved - reserved - - - DEFERRED - non-reserved - non-reserved - non-reserved - reserved - - - DEFINED - - non-reserved - non-reserved - - - - DEFINER - non-reserved - non-reserved - non-reserved - - - - DEGREE - - non-reserved - non-reserved - - - - DELETE - non-reserved - reserved - reserved - reserved - - - DELIMITER - non-reserved - - - - - - DELIMITERS - non-reserved - - - - - - DENSE_RANK - - reserved - reserved - - - - DEPENDS - non-reserved - - - - - - DEPTH - - non-reserved - non-reserved - - - - DEREF - - reserved - reserved - - - - DERIVED - - non-reserved - non-reserved - - - - DESC - reserved - non-reserved - non-reserved - reserved - - - DESCRIBE - - reserved - reserved - reserved - - - DESCRIPTOR - - non-reserved - non-reserved - reserved - - - DETACH - non-reserved - - - - - - DETERMINISTIC - - reserved - reserved - - - - DIAGNOSTICS - - non-reserved - non-reserved - reserved - - - DICTIONARY - non-reserved - - - - - - DISABLE - non-reserved - - - - - - DISCARD - non-reserved - - - - - - DISCONNECT - - reserved - reserved - reserved - - - DISPATCH - - non-reserved - non-reserved - - - - DISTINCT - reserved - reserved - reserved - reserved - - - DLNEWCOPY - - reserved - reserved - - - - DLPREVIOUSCOPY - - reserved - reserved - - - - DLURLCOMPLETE - - reserved - reserved - - - - DLURLCOMPLETEONLY - - reserved - reserved - - - - DLURLCOMPLETEWRITE - - reserved - reserved - - - - DLURLPATH - - reserved - reserved - - - - DLURLPATHONLY - - reserved - reserved - - - - DLURLPATHWRITE - - reserved - reserved - - - - DLURLSCHEME - - reserved - reserved - - - - DLURLSERVER - - reserved - reserved - - - - DLVALUE - - reserved - reserved - - - - DO - reserved - - - - - - DOCUMENT - non-reserved - non-reserved - non-reserved - - - - DOMAIN - non-reserved - non-reserved - non-reserved - reserved - - - DOUBLE - non-reserved - reserved - reserved - reserved - - - DROP - non-reserved - reserved - reserved - reserved - - - DYNAMIC - - reserved - reserved - - - - DYNAMIC_FUNCTION - - non-reserved - non-reserved - non-reserved - - - DYNAMIC_FUNCTION_CODE - - non-reserved - non-reserved - - - - EACH - non-reserved - reserved - reserved - - - - ELEMENT - - reserved - reserved - - - - ELSE - reserved - reserved - reserved - reserved - - - EMPTY - - non-reserved - non-reserved - - - - ENABLE - non-reserved - - - - - - ENCODING - non-reserved - non-reserved - non-reserved - - - - ENCRYPTED - non-reserved - - - - - - END - reserved - reserved - reserved - reserved - - - END-EXEC - - reserved - reserved - reserved - - - END_FRAME - - reserved - - - - - END_PARTITION - - reserved - - - - - ENFORCED - - non-reserved - - - - - ENUM - non-reserved - - - - - - EQUALS - - reserved - non-reserved - - - - ESCAPE - non-reserved - reserved - reserved - reserved - - - EVENT - non-reserved - - - - - - EVERY - - reserved - reserved - - - - EXCEPT - reserved - reserved - reserved - reserved - - - EXCEPTION - - - - reserved - - - EXCLUDE - non-reserved - non-reserved - non-reserved - - - - EXCLUDING - non-reserved - non-reserved - non-reserved - - - - EXCLUSIVE - non-reserved - - - - - - EXEC - - reserved - reserved - reserved - - - EXECUTE - non-reserved - reserved - reserved - reserved - - - EXISTS - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - EXP - - reserved - reserved - - - - EXPLAIN - non-reserved - - - - - - EXPRESSION - - non-reserved - - - - - EXTENSION - non-reserved - - - - - - EXTERNAL - non-reserved - reserved - reserved - reserved - - - EXTRACT - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - FALSE - reserved - reserved - reserved - reserved - - - FAMILY - non-reserved - - - - - - FETCH - reserved - reserved - reserved - reserved - - - FILE - - non-reserved - non-reserved - - - - FILTER - non-reserved - reserved - reserved - - - - FINAL - - non-reserved - non-reserved - - - - FIRST - non-reserved - non-reserved - non-reserved - reserved - - - FIRST_VALUE - - reserved - reserved - - - - FLAG - - non-reserved - non-reserved - - - - FLOAT - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - FLOOR - - reserved - reserved - - - - FOLLOWING - non-reserved - non-reserved - non-reserved - - - - FOR - reserved - reserved - reserved - reserved - - - FORCE - non-reserved - - - - - - FOREIGN - reserved - reserved - reserved - reserved - - - FORTRAN - - non-reserved - non-reserved - non-reserved - - - FORWARD - non-reserved - - - - - - FOUND - - non-reserved - non-reserved - reserved - - - FRAME_ROW - - reserved - - - - - FREE - - reserved - reserved - - - - FREEZE - reserved (can be function or type) - - - - - - FROM - reserved - reserved - reserved - reserved - - - FS - - non-reserved - non-reserved - - - - FULL - reserved (can be function or type) - reserved - reserved - reserved - - - FUNCTION - non-reserved - reserved - reserved - - - - FUNCTIONS - non-reserved - - - - - - FUSION - - reserved - reserved - - - - G - - non-reserved - non-reserved - - - - GENERAL - - non-reserved - non-reserved - - - - GENERATED - non-reserved - non-reserved - non-reserved - - - - GET - - reserved - reserved - reserved - - - GLOBAL - non-reserved - reserved - reserved - reserved - - - GO - - non-reserved - non-reserved - reserved - - - GOTO - - non-reserved - non-reserved - reserved - - - GRANT - reserved - reserved - reserved - reserved - - - GRANTED - non-reserved - non-reserved - non-reserved - - - - GREATEST - non-reserved (cannot be function or type) - - - - - - GROUP - reserved - reserved - reserved - reserved - - - GROUPING - non-reserved (cannot be function or type) - reserved - reserved - - - - GROUPS - - reserved - - - - - HANDLER - non-reserved - - - - - - HAVING - reserved - reserved - reserved - reserved - - - HEADER - non-reserved - - - - - - HEX - - non-reserved - non-reserved - - - - HIERARCHY - - non-reserved - non-reserved - - - - HOLD - non-reserved - reserved - reserved - - - - HOUR - non-reserved - reserved - reserved - reserved - - - ID - - non-reserved - non-reserved - - - - IDENTITY - non-reserved - reserved - reserved - reserved - - - IF - non-reserved - - - - - - IGNORE - - non-reserved - non-reserved - - - - ILIKE - reserved (can be function or type) - - - - - - IMMEDIATE - non-reserved - non-reserved - non-reserved - reserved - - - IMMEDIATELY - - non-reserved - - - - - IMMUTABLE - non-reserved - - - - - - IMPLEMENTATION - - non-reserved - non-reserved - - - - IMPLICIT - non-reserved - - - - - - IMPORT - non-reserved - reserved - reserved - - - - IN - reserved - reserved - reserved - reserved - - - INCLUDING - non-reserved - non-reserved - non-reserved - - - - INCREMENT - non-reserved - non-reserved - non-reserved - - - - INDENT - - non-reserved - non-reserved - - - - INDEX - non-reserved - - - - - - INDEXES - non-reserved - - - - - - INDICATOR - - reserved - reserved - reserved - - - INHERIT - non-reserved - - - - - - INHERITS - non-reserved - - - - - - INITIALLY - reserved - non-reserved - non-reserved - reserved - - - INLINE - non-reserved - - - - - - INNER - reserved (can be function or type) - reserved - reserved - reserved - - - INOUT - non-reserved (cannot be function or type) - reserved - reserved - - - - INPUT - non-reserved - non-reserved - non-reserved - reserved - - - INSENSITIVE - non-reserved - reserved - reserved - reserved - - - INSERT - non-reserved - reserved - reserved - reserved - - - INSTANCE - - non-reserved - non-reserved - - - - INSTANTIABLE - - non-reserved - non-reserved - - - - INSTEAD - non-reserved - non-reserved - non-reserved - - - - INT - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - INTEGER - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - INTEGRITY - - non-reserved - non-reserved - - - - INTERSECT - reserved - reserved - reserved - reserved - - - INTERSECTION - - reserved - reserved - - - - INTERVAL - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - INTO - reserved - reserved - reserved - reserved - - - INVOKER - non-reserved - non-reserved - non-reserved - - - - IS - reserved (can be function or type) - reserved - reserved - reserved - - - ISNULL - reserved (can be function or type) - - - - - - ISOLATION - non-reserved - non-reserved - non-reserved - reserved - - - JOIN - reserved (can be function or type) - reserved - reserved - reserved - - - K - - non-reserved - non-reserved - - - - KEY - non-reserved - non-reserved - non-reserved - reserved - - - KEY_MEMBER - - non-reserved - non-reserved - - - - KEY_TYPE - - non-reserved - non-reserved - - - - LABEL - non-reserved - - - - - - LAG - - reserved - reserved - - - - LANGUAGE - non-reserved - reserved - reserved - reserved - - - LARGE - non-reserved - reserved - reserved - - - - LAST - non-reserved - non-reserved - non-reserved - reserved - - - LAST_VALUE - - reserved - reserved - - - - LATERAL - reserved - reserved - reserved - - - - LEAD - - reserved - reserved - - - - LEADING - reserved - reserved - reserved - reserved - - - LEAKPROOF - non-reserved - - - - - - LEAST - non-reserved (cannot be function or type) - - - - - - LEFT - reserved (can be function or type) - reserved - reserved - reserved - - - LENGTH - - non-reserved - non-reserved - non-reserved - - - LEVEL - non-reserved - non-reserved - non-reserved - reserved - - - LIBRARY - - non-reserved - non-reserved - - - - LIKE - reserved (can be function or type) - reserved - reserved - reserved - - - LIKE_REGEX - - reserved - reserved - - - - LIMIT - reserved - non-reserved - non-reserved - - - - LINK - - non-reserved - non-reserved - - - - LISTEN - non-reserved - - - - - - LN - - reserved - reserved - - - - LOAD - non-reserved - - - - - - LOCAL - non-reserved - reserved - reserved - reserved - - - LOCALTIME - reserved - reserved - reserved - - - - LOCALTIMESTAMP - reserved - reserved - reserved - - - - LOCATION - non-reserved - non-reserved - non-reserved - - - - LOCATOR - - non-reserved - non-reserved - - - - LOCK - non-reserved - - - - - - LOCKED - non-reserved - - - - - - LOGGED - non-reserved - - - - - - LOWER - - reserved - reserved - reserved - - - M - - non-reserved - non-reserved - - - - MAP - - non-reserved - non-reserved - - - - MAPPING - non-reserved - non-reserved - non-reserved - - - - MATCH - non-reserved - reserved - reserved - reserved - - - MATCHED - - non-reserved - non-reserved - - - - MATERIALIZED - non-reserved - - - - - - MAX - - reserved - reserved - reserved - - - MAXVALUE - non-reserved - non-reserved - non-reserved - - - - MAX_CARDINALITY - - - reserved - - - - MEMBER - - reserved - reserved - - - - MERGE - - reserved - reserved - - - - MESSAGE_LENGTH - - non-reserved - non-reserved - non-reserved - - - MESSAGE_OCTET_LENGTH - - non-reserved - non-reserved - non-reserved - - - MESSAGE_TEXT - - non-reserved - non-reserved - non-reserved - - - METHOD - non-reserved - reserved - reserved - - - - MIN - - reserved - reserved - reserved - - - MINUTE - non-reserved - reserved - reserved - reserved - - - MINVALUE - non-reserved - non-reserved - non-reserved - - - - MOD - - reserved - reserved - - - - MODE - non-reserved - - - - - - MODIFIES - - reserved - reserved - - - - MODULE - - reserved - reserved - reserved - - - MONTH - non-reserved - reserved - reserved - reserved - - - MORE - - non-reserved - non-reserved - non-reserved - - - MOVE - non-reserved - - - - - - MULTISET - - reserved - reserved - - - - MUMPS - - non-reserved - non-reserved - non-reserved - - - NAME - non-reserved - non-reserved - non-reserved - non-reserved - - - NAMES - non-reserved - non-reserved - non-reserved - reserved - - - NAMESPACE - - non-reserved - non-reserved - - - - NATIONAL - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - NATURAL - reserved (can be function or type) - reserved - reserved - reserved - - - NCHAR - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - NCLOB - - reserved - reserved - - - - NESTING - - non-reserved - non-reserved - - - - NEW - non-reserved - reserved - reserved - - - - NEXT - non-reserved - non-reserved - non-reserved - reserved - - - NFC - - non-reserved - non-reserved - - - - NFD - - non-reserved - non-reserved - - - - NFKC - - non-reserved - non-reserved - - - - NFKD - - non-reserved - non-reserved - - - - NIL - - non-reserved - non-reserved - - - - NO - non-reserved - reserved - reserved - reserved - - - NONE - non-reserved (cannot be function or type) - reserved - reserved - - - - NORMALIZE - - reserved - reserved - - - - NORMALIZED - - non-reserved - non-reserved - - - - NOT - reserved - reserved - reserved - reserved - - - NOTHING - non-reserved - - - - - - NOTIFY - non-reserved - - - - - - NOTNULL - reserved (can be function or type) - - - - - - NOWAIT - non-reserved - - - - - - NTH_VALUE - - reserved - reserved - - - - NTILE - - reserved - reserved - - - - NULL - reserved - reserved - reserved - reserved - - - NULLABLE - - non-reserved - non-reserved - non-reserved - - - NULLIF - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - NULLS - non-reserved - non-reserved - non-reserved - - - - NUMBER - - non-reserved - non-reserved - non-reserved - - - NUMERIC - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - OBJECT - non-reserved - non-reserved - non-reserved - - - - OCCURRENCES_REGEX - - reserved - reserved - - - - OCTETS - - non-reserved - non-reserved - - - - OCTET_LENGTH - - reserved - reserved - reserved - - - OF - non-reserved - reserved - reserved - reserved - - - OFF - non-reserved - non-reserved - non-reserved - - - - OFFSET - reserved - reserved - reserved - - - - OIDS - non-reserved - - - - - - OLD - non-reserved - reserved - reserved - - - - ON - reserved - reserved - reserved - reserved - - - ONLY - reserved - reserved - reserved - reserved - - - OPEN - - reserved - reserved - reserved - - - OPERATOR - non-reserved - - - - - - OPTION - non-reserved - non-reserved - non-reserved - reserved - - - OPTIONS - non-reserved - non-reserved - non-reserved - - - - OR - reserved - reserved - reserved - reserved - - - ORDER - reserved - reserved - reserved - reserved - - - ORDERING - - non-reserved - non-reserved - - - - ORDINALITY - non-reserved - non-reserved - non-reserved - - - - OTHERS - - non-reserved - non-reserved - - - - OUT - non-reserved (cannot be function or type) - reserved - reserved - - - - OUTER - reserved (can be function or type) - reserved - reserved - reserved - - - OUTPUT - - non-reserved - non-reserved - reserved - - - OVER - non-reserved - reserved - reserved - - - - OVERLAPS - reserved (can be function or type) - reserved - reserved - reserved - - - OVERLAY - non-reserved (cannot be function or type) - reserved - reserved - - - - OVERRIDING - non-reserved - non-reserved - non-reserved - - - - OWNED - non-reserved - - - - - - OWNER - non-reserved - - - - - - P - - non-reserved - non-reserved - - - - PAD - - non-reserved - non-reserved - reserved - - - PARALLEL - non-reserved - - - - - - PARAMETER - - reserved - reserved - - - - PARAMETER_MODE - - non-reserved - non-reserved - - - - PARAMETER_NAME - - non-reserved - non-reserved - - - - PARAMETER_ORDINAL_POSITION - - non-reserved - non-reserved - - - - PARAMETER_SPECIFIC_CATALOG - - non-reserved - non-reserved - - - - PARAMETER_SPECIFIC_NAME - - non-reserved - non-reserved - - - - PARAMETER_SPECIFIC_SCHEMA - - non-reserved - non-reserved - - - - PARSER - non-reserved - - - - - - PARTIAL - non-reserved - non-reserved - non-reserved - reserved - - - PARTITION - non-reserved - reserved - reserved - - - - PASCAL - - non-reserved - non-reserved - non-reserved - - - PASSING - non-reserved - non-reserved - non-reserved - - - - PASSTHROUGH - - non-reserved - non-reserved - - - - PASSWORD - non-reserved - - - - - - PATH - - non-reserved - non-reserved - - - - PERCENT - - reserved - - - - - PERCENTILE_CONT - - reserved - reserved - - - - PERCENTILE_DISC - - reserved - reserved - - - - PERCENT_RANK - - reserved - reserved - - - - PERIOD - - reserved - - - - - PERMISSION - - non-reserved - non-reserved - - - - PLACING - reserved - non-reserved - non-reserved - - - - PLANS - non-reserved - - - - - - PLI - - non-reserved - non-reserved - non-reserved - - - POLICY - non-reserved - - - - - - PORTION - - reserved - - - - - POSITION - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - POSITION_REGEX - - reserved - reserved - - - - POWER - - reserved - reserved - - - - PRECEDES - - reserved - - - - - PRECEDING - non-reserved - non-reserved - non-reserved - - - - PRECISION - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - PREPARE - non-reserved - reserved - reserved - reserved - - - PREPARED - non-reserved - - - - - - PRESERVE - non-reserved - non-reserved - non-reserved - reserved - - - PRIMARY - reserved - reserved - reserved - reserved - - - PRIOR - non-reserved - non-reserved - non-reserved - reserved - - - PRIVILEGES - non-reserved - non-reserved - non-reserved - reserved - - - PROCEDURAL - non-reserved - - - - - - PROCEDURE - non-reserved - reserved - reserved - reserved - - - PROGRAM - non-reserved - - - - - - PUBLIC - - non-reserved - non-reserved - reserved - - - PUBLICATION - non-reserved - - - - - - QUOTE - non-reserved - - - - - - RANGE - non-reserved - reserved - reserved - - - - RANK - - reserved - reserved - - - - READ - non-reserved - non-reserved - non-reserved - reserved - - - READS - - reserved - reserved - - - - REAL - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - REASSIGN - non-reserved - - - - - - RECHECK - non-reserved - - - - - - RECOVERY - - non-reserved - non-reserved - - - - RECURSIVE - non-reserved - reserved - reserved - - - - REF - non-reserved - reserved - reserved - - - - REFERENCES - reserved - reserved - reserved - reserved - - - REFERENCING - non-reserved - reserved - reserved - - - - REFRESH - non-reserved - - - - - - REGR_AVGX - - reserved - reserved - - - - REGR_AVGY - - reserved - reserved - - - - REGR_COUNT - - reserved - reserved - - - - REGR_INTERCEPT - - reserved - reserved - - - - REGR_R2 - - reserved - reserved - - - - REGR_SLOPE - - reserved - reserved - - - - REGR_SXX - - reserved - reserved - - - - REGR_SXY - - reserved - reserved - - - - REGR_SYY - - reserved - reserved - - - - REINDEX - non-reserved - - - - - - RELATIVE - non-reserved - non-reserved - non-reserved - reserved - - - RELEASE - non-reserved - reserved - reserved - - - - RENAME - non-reserved - - - - - - REPEATABLE - non-reserved - non-reserved - non-reserved - non-reserved - - - REPLACE - non-reserved - - - - - - REPLICA - non-reserved - - - - - - REQUIRING - - non-reserved - non-reserved - - - - RESET - non-reserved - - - - - - RESPECT - - non-reserved - non-reserved - - - - RESTART - non-reserved - non-reserved - non-reserved - - - - RESTORE - - non-reserved - non-reserved - - - - RESTRICT - non-reserved - non-reserved - non-reserved - reserved - - - RESULT - - reserved - reserved - - - - RETURN - - reserved - reserved - - - - RETURNED_CARDINALITY - - non-reserved - non-reserved - - - - RETURNED_LENGTH - - non-reserved - non-reserved - non-reserved - - - RETURNED_OCTET_LENGTH - - non-reserved - non-reserved - non-reserved - - - RETURNED_SQLSTATE - - non-reserved - non-reserved - non-reserved - - - RETURNING - reserved - non-reserved - non-reserved - - - - RETURNS - non-reserved - reserved - reserved - - - - REVOKE - non-reserved - reserved - reserved - reserved - - - RIGHT - reserved (can be function or type) - reserved - reserved - reserved - - - ROLE - non-reserved - non-reserved - non-reserved - - - - ROLLBACK - non-reserved - reserved - reserved - reserved - - - ROLLUP - non-reserved - reserved - reserved - - - - ROUTINE - - non-reserved - non-reserved - - - - ROUTINE_CATALOG - - non-reserved - non-reserved - - - - ROUTINE_NAME - - non-reserved - non-reserved - - - - ROUTINE_SCHEMA - - non-reserved - non-reserved - - - - ROW - non-reserved (cannot be function or type) - reserved - reserved - - - - ROWS - non-reserved - reserved - reserved - reserved - - - ROW_COUNT - - non-reserved - non-reserved - non-reserved - - - ROW_NUMBER - - reserved - reserved - - - - RULE - non-reserved - - - - - - SAVEPOINT - non-reserved - reserved - reserved - - - - SCALE - - non-reserved - non-reserved - non-reserved - - - SCHEMA - non-reserved - non-reserved - non-reserved - reserved - - - SCHEMAS - non-reserved - - - - - - SCHEMA_NAME - - non-reserved - non-reserved - non-reserved - - - SCOPE - - reserved - reserved - - - - SCOPE_CATALOG - - non-reserved - non-reserved - - - - SCOPE_NAME - - non-reserved - non-reserved - - - - SCOPE_SCHEMA - - non-reserved - non-reserved - - - - SCROLL - non-reserved - reserved - reserved - reserved - - - SEARCH - non-reserved - reserved - reserved - - - - SECOND - non-reserved - reserved - reserved - reserved - - - SECTION - - non-reserved - non-reserved - reserved - - - SECURITY - non-reserved - non-reserved - non-reserved - - - - SELECT - reserved - reserved - reserved - reserved - - - SELECTIVE - - non-reserved - non-reserved - - - - SELF - - non-reserved - non-reserved - - - - SENSITIVE - - reserved - reserved - - - - SEQUENCE - non-reserved - non-reserved - non-reserved - - - - SEQUENCES - non-reserved - - - - - - SERIALIZABLE - non-reserved - non-reserved - non-reserved - non-reserved - - - SERVER - non-reserved - non-reserved - non-reserved - - - - SERVER_NAME - - non-reserved - non-reserved - non-reserved - - - SESSION - non-reserved - non-reserved - non-reserved - reserved - - - SESSION_USER - reserved - reserved - reserved - reserved - - - SET - non-reserved - reserved - reserved - reserved - - - SETOF - non-reserved (cannot be function or type) - - - - - - SETS - non-reserved - non-reserved - non-reserved - - - - SHARE - non-reserved - - - - - - SHOW - non-reserved - - - - - - SIMILAR - reserved (can be function or type) - reserved - reserved - - - - SIMPLE - non-reserved - non-reserved - non-reserved - - - - SIZE - - non-reserved - non-reserved - reserved - - - SKIP - non-reserved - - - - - - SMALLINT - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - SNAPSHOT - non-reserved - - - - - - SOME - reserved - reserved - reserved - reserved - - - SOURCE - - non-reserved - non-reserved - - - - SPACE - - non-reserved - non-reserved - reserved - - - SPECIFIC - - reserved - reserved - - - - SPECIFICTYPE - - reserved - reserved - - - - SPECIFIC_NAME - - non-reserved - non-reserved - - - - SQL - non-reserved - reserved - reserved - reserved - - - SQLCODE - - - - reserved - - - SQLERROR - - - - reserved - - - SQLEXCEPTION - - reserved - reserved - - - - SQLSTATE - - reserved - reserved - reserved - - - SQLWARNING - - reserved - reserved - - - - SQRT - - reserved - reserved - - - - STABLE - non-reserved - - - - - - STANDALONE - non-reserved - non-reserved - non-reserved - - - - START - non-reserved - reserved - reserved - - - - STATE - - non-reserved - non-reserved - - - - STATEMENT - non-reserved - non-reserved - non-reserved - - - - STATIC - - reserved - reserved - - - - STATISTICS - non-reserved - - - - - - STDDEV_POP - - reserved - reserved - - - - STDDEV_SAMP - - reserved - reserved - - - - STDIN - non-reserved - - - - - - STDOUT - non-reserved - - - - - - STORAGE - non-reserved - - - - - - STRICT - non-reserved - - - - - - STRIP - non-reserved - non-reserved - non-reserved - - - - STRUCTURE - - non-reserved - non-reserved - - - - STYLE - - non-reserved - non-reserved - - - - SUBCLASS_ORIGIN - - non-reserved - non-reserved - non-reserved - - - SUBMULTISET - - reserved - reserved - - - - SUBSCRIPTION - non-reserved - - - - - - SUBSTRING - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - SUBSTRING_REGEX - - reserved - reserved - - - - SUCCEEDS - - reserved - - - - - SUM - - reserved - reserved - reserved - - - SYMMETRIC - reserved - reserved - reserved - - - - SYSID - non-reserved - - - - - - SYSTEM - non-reserved - reserved - reserved - - - - SYSTEM_TIME - - reserved - - - - - SYSTEM_USER - - reserved - reserved - reserved - - - T - - non-reserved - non-reserved - - - - TABLE - reserved - reserved - reserved - reserved - - - TABLES - non-reserved - - - - - - TABLESAMPLE - reserved (can be function or type) - reserved - reserved - - - - TABLESPACE - non-reserved - - - - - - TABLE_NAME - - non-reserved - non-reserved - non-reserved - - - TEMP - non-reserved - - - - - - TEMPLATE - non-reserved - - - - - - TEMPORARY - non-reserved - non-reserved - non-reserved - reserved - - - TEXT - non-reserved - - - - - - THEN - reserved - reserved - reserved - reserved - - - TIES - - non-reserved - non-reserved - - - - TIME - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - TIMESTAMP - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - TIMEZONE_HOUR - - reserved - reserved - reserved - - - TIMEZONE_MINUTE - - reserved - reserved - reserved - - - TO - reserved - reserved - reserved - reserved - - - TOKEN - - non-reserved - non-reserved - - - - TOP_LEVEL_COUNT - - non-reserved - non-reserved - - - - TRAILING - reserved - reserved - reserved - reserved - - - TRANSACTION - non-reserved - non-reserved - non-reserved - reserved - - - TRANSACTIONS_COMMITTED - - non-reserved - non-reserved - - - - TRANSACTIONS_ROLLED_BACK - - non-reserved - non-reserved - - - - TRANSACTION_ACTIVE - - non-reserved - non-reserved - - - - TRANSFORM - non-reserved - non-reserved - non-reserved - - - - TRANSFORMS - - non-reserved - non-reserved - - - - TRANSLATE - - reserved - reserved - reserved - - - TRANSLATE_REGEX - - reserved - reserved - - - - TRANSLATION - - reserved - reserved - reserved - - - TREAT - non-reserved (cannot be function or type) - reserved - reserved - - - - TRIGGER - non-reserved - reserved - reserved - - - - TRIGGER_CATALOG - - non-reserved - non-reserved - - - - TRIGGER_NAME - - non-reserved - non-reserved - - - - TRIGGER_SCHEMA - - non-reserved - non-reserved - - - - TRIM - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - TRIM_ARRAY - - reserved - reserved - - - - TRUE - reserved - reserved - reserved - reserved - - - TRUNCATE - non-reserved - reserved - reserved - - - - TRUSTED - non-reserved - - - - - - TYPE - non-reserved - non-reserved - non-reserved - non-reserved - - - TYPES - non-reserved - - - - - - UESCAPE - - reserved - reserved - - - - UNBOUNDED - non-reserved - non-reserved - non-reserved - - - - UNCOMMITTED - non-reserved - non-reserved - non-reserved - non-reserved - - - UNDER - - non-reserved - non-reserved - - - - UNENCRYPTED - non-reserved - - - - - - UNION - reserved - reserved - reserved - reserved - - - UNIQUE - reserved - reserved - reserved - reserved - - - UNKNOWN - non-reserved - reserved - reserved - reserved - - - UNLINK - - non-reserved - non-reserved - - - - UNLISTEN - non-reserved - - - - - - UNLOGGED - non-reserved - - - - - - UNNAMED - - non-reserved - non-reserved - non-reserved - - - UNNEST - - reserved - reserved - - - - UNTIL - non-reserved - - - - - - UNTYPED - - non-reserved - non-reserved - - - - UPDATE - non-reserved - reserved - reserved - reserved - - - UPPER - - reserved - reserved - reserved - - - URI - - non-reserved - non-reserved - - - - USAGE - - non-reserved - non-reserved - reserved - - - USER - reserved - reserved - reserved - reserved - - - USER_DEFINED_TYPE_CATALOG - - non-reserved - non-reserved - - - - USER_DEFINED_TYPE_CODE - - non-reserved - non-reserved - - - - USER_DEFINED_TYPE_NAME - - non-reserved - non-reserved - - - - USER_DEFINED_TYPE_SCHEMA - - non-reserved - non-reserved - - - - USING - reserved - reserved - reserved - reserved - - - VACUUM - non-reserved - - - - - - VALID - non-reserved - non-reserved - non-reserved - - - - VALIDATE - non-reserved - - - - - - VALIDATOR - non-reserved - - - - - - VALUE - non-reserved - reserved - reserved - reserved - - - VALUES - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - VALUE_OF - - reserved - - - - - VARBINARY - - reserved - reserved - - - - VARCHAR - non-reserved (cannot be function or type) - reserved - reserved - reserved - - - VARIADIC - reserved - - - - - - VARYING - non-reserved - reserved - reserved - reserved - - - VAR_POP - - reserved - reserved - - - - VAR_SAMP - - reserved - reserved - - - - VERBOSE - reserved (can be function or type) - - - - - - VERSION - non-reserved - non-reserved - non-reserved - - - - VERSIONING - - reserved - - - - - VIEW - non-reserved - non-reserved - non-reserved - reserved - - - VIEWS - non-reserved - - - - - - VOLATILE - non-reserved - - - - - - WHEN - reserved - reserved - reserved - reserved - - - WHENEVER - - reserved - reserved - reserved - - - WHERE - reserved - reserved - reserved - reserved - - - WHITESPACE - non-reserved - non-reserved - non-reserved - - - - WIDTH_BUCKET - - reserved - reserved - - - - WINDOW - reserved - reserved - reserved - - - - WITH - reserved - reserved - reserved - reserved - - - WITHIN - non-reserved - reserved - reserved - - - - WITHOUT - non-reserved - reserved - reserved - - - - WORK - non-reserved - non-reserved - non-reserved - reserved - - - WRAPPER - non-reserved - non-reserved - non-reserved - - - - WRITE - non-reserved - non-reserved - non-reserved - reserved - - - XML - non-reserved - reserved - reserved - - - - XMLAGG - - reserved - reserved - - - - XMLATTRIBUTES - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLBINARY - - reserved - reserved - - - - XMLCAST - - reserved - reserved - - - - XMLCOMMENT - - reserved - reserved - - - - XMLCONCAT - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLDECLARATION - - non-reserved - non-reserved - - - - XMLDOCUMENT - - reserved - reserved - - - - XMLELEMENT - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLEXISTS - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLFOREST - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLITERATE - - reserved - reserved - - - - XMLNAMESPACES - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLPARSE - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLPI - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLQUERY - - reserved - reserved - - - - XMLROOT - non-reserved (cannot be function or type) - - - - - - XMLSCHEMA - - non-reserved - non-reserved - - - - XMLSERIALIZE - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLTABLE - non-reserved (cannot be function or type) - reserved - reserved - - - - XMLTEXT - - reserved - reserved - - - - XMLVALIDATE - - reserved - reserved - - - - YEAR - non-reserved - reserved - reserved - reserved - - - YES - non-reserved - non-reserved - non-reserved - - - - ZONE - non-reserved - non-reserved - non-reserved - reserved - - - -
- + &keywords-table; diff --git a/doc/src/sgml/keywords/sql1992-nonreserved.txt b/doc/src/sgml/keywords/sql1992-nonreserved.txt new file mode 100644 index 00000000000..00abedaac79 --- /dev/null +++ b/doc/src/sgml/keywords/sql1992-nonreserved.txt @@ -0,0 +1,50 @@ +ADA +C +CATALOG_NAME +CHARACTER_SET_CATALOG +CHARACTER_SET_NAME +CHARACTER_SET_SCHEMA +CLASS_ORIGIN +COBOL +COLLATION_CATALOG +COLLATION_NAME +COLLATION_SCHEMA +COLUMN_NAME +COMMAND_FUNCTION +COMMITTED +CONDITION_NUMBER +CONNECTION_NAME +CONSTRAINT_CATALOG +CONSTRAINT_NAME +CONSTRAINT_SCHEMA +CURSOR_NAME +DATA +DATETIME_INTERVAL_CODE +DATETIME_INTERVAL_PRECISION +DYNAMIC_FUNCTION +FORTRAN +LENGTH +MESSAGE_LENGTH +MESSAGE_OCTET_LENGTH +MESSAGE_TEXT +MORE +MUMPS +NAME +NULLABLE +NUMBER +PASCAL +PLI +REPEATABLE +RETURNED_LENGTH +RETURNED_OCTET_LENGTH +RETURNED_SQLSTATE +ROW_COUNT +SCALE +SCHEMA_NAME +SERIALIZABLE +SERVER_NAME +SUBCLASS_ORIGIN +TABLE_NAME +TYPE +UNCOMMITTED +UNNAMED diff --git a/doc/src/sgml/keywords/sql1992-reserved.txt b/doc/src/sgml/keywords/sql1992-reserved.txt new file mode 100644 index 00000000000..5bda21315f8 --- /dev/null +++ b/doc/src/sgml/keywords/sql1992-reserved.txt @@ -0,0 +1,227 @@ +ABSOLUTE +ACTION +ADD +ALL +ALLOCATE +ALTER +AND +ANY +ARE +AS +ASC +ASSERTION +AT +AUTHORIZATION +AVG +BEGIN +BETWEEN +BIT +BIT_LENGTH +BOTH +BY +CASCADE +CASCADED +CASE +CAST +CATALOG +CHAR +CHARACTER +CHAR_LENGTH +CHARACTER_LENGTH +CHECK +CLOSE +COALESCE +COLLATE +COLLATION +COLUMN +COMMIT +CONNECT +CONNECTION +CONSTRAINT +CONSTRAINTS +CONTINUE +CONVERT +CORRESPONDING +COUNT +CREATE +CROSS +CURRENT +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DATE +DAY +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DEFERRABLE +DEFERRED +DELETE +DESC +DESCRIBE +DESCRIPTOR +DIAGNOSTICS +DISCONNECT +DISTINCT +DOMAIN +DOUBLE +DROP +ELSE +END +END-EXEC +ESCAPE +EXCEPT +EXCEPTION +EXEC +EXECUTE +EXISTS +EXTERNAL +EXTRACT +FALSE +FETCH +FIRST +FLOAT +FOR +FOREIGN +FOUND +FROM +FULL +GET +GLOBAL +GO +GOTO +GRANT +GROUP +HAVING +HOUR +IDENTITY +IMMEDIATE +IN +INDICATOR +INITIALLY +INNER +INPUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTERVAL +INTO +IS +ISOLATION +JOIN +KEY +LANGUAGE +LAST +LEADING +LEFT +LEVEL +LIKE +LOCAL +LOWER +MATCH +MAX +MIN +MINUTE +MODULE +MONTH +NAMES +NATIONAL +NATURAL +NCHAR +NEXT +NO +NOT +NULL +NULLIF +NUMERIC +OCTET_LENGTH +OF +ON +ONLY +OPEN +OPTION +OR +ORDER +OUTER +OUTPUT +OVERLAPS +PAD +PARTIAL +POSITION +PRECISION +PREPARE +PRESERVE +PRIMARY +PRIOR +PRIVILEGES +PROCEDURE +PUBLIC +READ +REAL +REFERENCES +RELATIVE +RESTRICT +REVOKE +RIGHT +ROLLBACK +ROWS +SCHEMA +SCROLL +SECOND +SECTION +SELECT +SESSION +SESSION_USER +SET +SIZE +SMALLINT +SOME +SPACE +SQL +SQLCODE +SQLERROR +SQLSTATE +SUBSTRING +SUM +SYSTEM_USER +TABLE +TEMPORARY +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSACTION +TRANSLATE +TRANSLATION +TRIM +TRUE +UNION +UNIQUE +UNKNOWN +UPDATE +UPPER +USAGE +USER +USING +VALUE +VALUES +VARCHAR +VARYING +VIEW +WHEN +WHENEVER +WHERE +WITH +WORK +WRITE +YEAR +ZONE diff --git a/doc/src/sgml/keywords/sql2011-02-nonreserved.txt b/doc/src/sgml/keywords/sql2011-02-nonreserved.txt new file mode 100644 index 00000000000..b28a180f0bd --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-02-nonreserved.txt @@ -0,0 +1,219 @@ +A +ABSOLUTE +ACTION +ADA +ADD +ADMIN +AFTER +ALWAYS +ASC +ASSERTION +ASSIGNMENT +ATTRIBUTE +ATTRIBUTES +BEFORE +BERNOULLI +BREADTH +C +CASCADE +CATALOG +CATALOG_NAME +CHAIN +CHARACTER_SET_CATALOG +CHARACTER_SET_NAME +CHARACTER_SET_SCHEMA +CHARACTERISTICS +CHARACTERS +CLASS_ORIGIN +COBOL +COLLATION +COLLATION_CATALOG +COLLATION_NAME +COLLATION_SCHEMA +COLUMN_NAME +COMMAND_FUNCTION +COMMAND_FUNCTION_CODE +COMMITTED +CONDITION_NUMBER +CONNECTION +CONNECTION_NAME +CONSTRAINT_CATALOG +CONSTRAINT_NAME +CONSTRAINT_SCHEMA +CONSTRAINTS +CONSTRUCTOR +CONTINUE +CURSOR_NAME +DATA +DATETIME_INTERVAL_CODE +DATETIME_INTERVAL_PRECISION +DEFAULTS +DEFERRABLE +DEFERRED +DEFINED +DEFINER +DEGREE +DEPTH +DERIVED +DESC +DESCRIPTOR +DIAGNOSTICS +DISPATCH +DOMAIN +DYNAMIC_FUNCTION +DYNAMIC_FUNCTION_CODE +ENFORCED +EXCLUDE +EXCLUDING +EXPRESSION +FINAL +FIRST +FLAG +FOLLOWING +FORTRAN +FOUND +G +GENERAL +GENERATED +GO +GOTO +GRANTED +HIERARCHY +IGNORE +IMMEDIATE +IMMEDIATELY +IMPLEMENTATION +INCLUDING +INCREMENT +INITIALLY +INPUT +INSTANCE +INSTANTIABLE +INSTEAD +INVOKER +ISOLATION +K +KEY +KEY_MEMBER +KEY_TYPE +LAST +LENGTH +LEVEL +LOCATOR +M +MAP +MATCHED +MAXVALUE +MESSAGE_LENGTH +MESSAGE_OCTET_LENGTH +MESSAGE_TEXT +MINVALUE +MORE +MUMPS +NAME +NAMES +NESTING +NEXT +NFC +NFD +NFKC +NFKD +NORMALIZED +NULLABLE +NULLS +NUMBER +OBJECT +OCTETS +OPTION +OPTIONS +ORDERING +ORDINALITY +OTHERS +OUTPUT +OVERRIDING +P +PAD +PARAMETER_MODE +PARAMETER_NAME +PARAMETER_ORDINAL_POSITION +PARAMETER_SPECIFIC_CATALOG +PARAMETER_SPECIFIC_NAME +PARAMETER_SPECIFIC_SCHEMA +PARTIAL +PASCAL +PATH +PLACING +PLI +PRECEDING +PRESERVE +PRIOR +PRIVILEGES +PUBLIC +READ +RELATIVE +REPEATABLE +RESPECT +RESTART +RESTRICT +RETURNED_CARDINALITY +RETURNED_LENGTH +RETURNED_OCTET_LENGTH +RETURNED_SQLSTATE +ROLE +ROUTINE +ROUTINE_CATALOG +ROUTINE_NAME +ROUTINE_SCHEMA +ROW_COUNT +SCALE +SCHEMA +SCHEMA_NAME +SCOPE_CATALOG +SCOPE_NAME +SCOPE_SCHEMA +SECTION +SECURITY +SELF +SEQUENCE +SERIALIZABLE +SERVER_NAME +SESSION +SETS +SIMPLE +SIZE +SOURCE +SPACE +SPECIFIC_NAME +STATE +STATEMENT +STRUCTURE +STYLE +SUBCLASS_ORIGIN +T +TABLE_NAME +TEMPORARY +TIES +TOP_LEVEL_COUNT +TRANSACTION +TRANSACTION_ACTIVE +TRANSACTIONS_COMMITTED +TRANSACTIONS_ROLLED_BACK +TRANSFORM +TRANSFORMS +TRIGGER_CATALOG +TRIGGER_NAME +TRIGGER_SCHEMA +TYPE +UNBOUNDED +UNCOMMITTED +UNDER +UNNAMED +USAGE +USER_DEFINED_TYPE_CATALOG +USER_DEFINED_TYPE_CODE +USER_DEFINED_TYPE_NAME +USER_DEFINED_TYPE_SCHEMA +VIEW +WORK +WRITE +ZONE diff --git a/doc/src/sgml/keywords/sql2011-02-reserved.txt b/doc/src/sgml/keywords/sql2011-02-reserved.txt new file mode 100644 index 00000000000..95f99e7df20 --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-02-reserved.txt @@ -0,0 +1,324 @@ +ABS +ALL +ALLOCATE +ALTER +AND +ANY +ARE +ARRAY +ARRAY_AGG +ARRAY_MAX_CARDINALITY +AS +ASENSITIVE +ASYMMETRIC +AT +ATOMIC +AUTHORIZATION +AVG +BEGIN +BEGIN_FRAME +BEGIN_PARTITION +BETWEEN +BIGINT +BINARY +BLOB +BOOLEAN +BOTH +BY +CALL +CALLED +CARDINALITY +CASCADED +CASE +CAST +CEIL +CEILING +CHAR +CHAR_LENGTH +CHARACTER +CHARACTER_LENGTH +CHECK +CLOB +CLOSE +COALESCE +COLLATE +COLLECT +COLUMN +COMMIT +CONDITION +CONNECT +CONSTRAINT +CONTAINS +CONVERT +CORR +CORRESPONDING +COUNT +COVAR_POP +COVAR_SAMP +CREATE +CROSS +CUBE +CUME_DIST +CURRENT +CURRENT_CATALOG +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_PATH +CURRENT_ROLE +CURRENT_ROW +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURSOR +CYCLE +DATE +DAY +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DELETE +DENSE_RANK +DEREF +DESCRIBE +DETERMINISTIC +DISCONNECT +DISTINCT +DOUBLE +DROP +DYNAMIC +EACH +ELEMENT +ELSE +END +END_FRAME +END_PARTITION +END-EXEC +EQUALS +ESCAPE +EVERY +EXCEPT +EXEC +EXECUTE +EXISTS +EXP +EXTERNAL +EXTRACT +FALSE +FETCH +FILTER +FIRST_VALUE +FLOAT +FLOOR +FOR +FOREIGN +FRAME_ROW +FREE +FROM +FULL +FUNCTION +FUSION +GET +GLOBAL +GRANT +GROUP +GROUPING +GROUPS +HAVING +HOLD +HOUR +IDENTITY +IN +INDICATOR +INNER +INOUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +JOIN +LAG +LANGUAGE +LARGE +LAST_VALUE +LATERAL +LEAD +LEADING +LEFT +LIKE +LIKE_REGEX +LN +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOWER +MATCH +MAX +MEMBER +MERGE +METHOD +MIN +MINUTE +MOD +MODIFIES +MODULE +MONTH +MULTISET +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NO +NONE +NORMALIZE +NOT +NTH_VALUE +NTILE +NULL +NULLIF +NUMERIC +OCTET_LENGTH +OCCURRENCES_REGEX +OF +OFFSET +OLD +ON +ONLY +OPEN +OR +ORDER +OUT +OUTER +OVER +OVERLAPS +OVERLAY +PARAMETER +PARTITION +PERCENT +PERCENT_RANK +PERCENTILE_CONT +PERCENTILE_DISC +PERIOD +PORTION +POSITION +POSITION_REGEX +POWER +PRECEDES +PRECISION +PREPARE +PRIMARY +PROCEDURE +RANGE +RANK +READS +REAL +RECURSIVE +REF +REFERENCES +REFERENCING +REGR_AVGX +REGR_AVGY +REGR_COUNT +REGR_INTERCEPT +REGR_R2 +REGR_SLOPE +REGR_SXX +REGR_SXY +REGR_SYY +RELEASE +RESULT +RETURN +RETURNS +REVOKE +RIGHT +ROLLBACK +ROLLUP +ROW +ROW_NUMBER +ROWS +SAVEPOINT +SCOPE +SCROLL +SEARCH +SECOND +SELECT +SENSITIVE +SESSION_USER +SET +SIMILAR +SMALLINT +SOME +SPECIFIC +SPECIFICTYPE +SQL +SQLEXCEPTION +SQLSTATE +SQLWARNING +SQRT +START +STATIC +STDDEV_POP +STDDEV_SAMP +SUBMULTISET +SUBSTRING +SUBSTRING_REGEX +SUCCEEDS +SUM +SYMMETRIC +SYSTEM +SYSTEM_TIME +SYSTEM_USER +TABLE +TABLESAMPLE +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSLATE +TRANSLATE_REGEX +TRANSLATION +TREAT +TRIGGER +TRUNCATE +TRIM +TRIM_ARRAY +TRUE +UESCAPE +UNION +UNIQUE +UNKNOWN +UNNEST +UPDATE +UPPER +USER +USING +VALUE +VALUES +VALUE_OF +VAR_POP +VAR_SAMP +VARBINARY +VARCHAR +VARYING +VERSIONING +WHEN +WHENEVER +WHERE +WIDTH_BUCKET +WINDOW +WITH +WITHIN +WITHOUT +YEAR diff --git a/doc/src/sgml/keywords/sql2011-09-nonreserved.txt b/doc/src/sgml/keywords/sql2011-09-nonreserved.txt new file mode 100644 index 00000000000..b360f0ce861 --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-09-nonreserved.txt @@ -0,0 +1,23 @@ +BLOCKED +CONTROL +DB +FILE +FS +INTEGRITY +LIBRARY +LIMIT +LINK +MAPPING +OFF +PASSTHROUGH +PERMISSION +RECOVERY +REQUIRING +RESTORE +SELECTIVE +SERVER +TOKEN +UNLINK +VERSION +WRAPPER +YES diff --git a/doc/src/sgml/keywords/sql2011-09-reserved.txt b/doc/src/sgml/keywords/sql2011-09-reserved.txt new file mode 100644 index 00000000000..02054857667 --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-09-reserved.txt @@ -0,0 +1,13 @@ +DATALINK +DLNEWCOPY +DLPREVIOUSCOPY +DLURLCOMPLETE +DLURLCOMPLETEWRITE +DLURLCOMPLETEONLY +DLURLPATH +DLURLPATHWRITE +DLURLPATHONLY +DLURLSCHEME +DLURLSERVER +DLVALUE +IMPORT diff --git a/doc/src/sgml/keywords/sql2011-14-nonreserved.txt b/doc/src/sgml/keywords/sql2011-14-nonreserved.txt new file mode 100644 index 00000000000..317f651f0ee --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-14-nonreserved.txt @@ -0,0 +1,29 @@ +ABSENT +ACCORDING +BASE64 +BOM +COLUMNS +CONTENT +DOCUMENT +EMPTY +ENCODING +HEX +ID +INDENT +LOCATION +NAMESPACE +NIL +PASSING +PATH +PRESERVE +RETURNING +SEQUENCE +STANDALONE +STRIP +UNTYPED +URI +VALID +VERSION +WHITESPACE +XMLSCHEMA +XMLDECLARATION diff --git a/doc/src/sgml/keywords/sql2011-14-reserved.txt b/doc/src/sgml/keywords/sql2011-14-reserved.txt new file mode 100644 index 00000000000..cf8052946f9 --- /dev/null +++ b/doc/src/sgml/keywords/sql2011-14-reserved.txt @@ -0,0 +1,20 @@ +XML +XMLAGG +XMLATTRIBUTES +XMLBINARY +XMLCAST +XMLCOMMENT +XMLCONCAT +XMLDOCUMENT +XMLELEMENT +XMLEXISTS +XMLFOREST +XMLITERATE +XMLNAMESPACES +XMLPARSE +XMLPI +XMLQUERY +XMLSERIALIZE +XMLTABLE +XMLTEXT +XMLVALIDATE diff --git a/doc/src/sgml/keywords/sql2016-02-nonreserved.txt b/doc/src/sgml/keywords/sql2016-02-nonreserved.txt new file mode 100644 index 00000000000..f39e52e475d --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-02-nonreserved.txt @@ -0,0 +1,248 @@ +A +ABSOLUTE +ACTION +ADA +ADD +ADMIN +AFTER +ALWAYS +ASC +ASSERTION +ASSIGNMENT +ATTRIBUTE +ATTRIBUTES +BEFORE +BERNOULLI +BREADTH +C +CASCADE +CATALOG +CATALOG_NAME +CHAIN +CHAINING +CHARACTER_SET_CATALOG +CHARACTER_SET_NAME +CHARACTER_SET_SCHEMA +CHARACTERISTICS +CHARACTERS +CLASS_ORIGIN +COBOL +COLLATION +COLLATION_CATALOG +COLLATION_NAME +COLLATION_SCHEMA +COLUMNS +COLUMN_NAME +COMMAND_FUNCTION +COMMAND_FUNCTION_CODE +COMMITTED +CONDITIONAL +CONDITION_NUMBER +CONNECTION +CONNECTION_NAME +CONSTRAINT_CATALOG +CONSTRAINT_NAME +CONSTRAINT_SCHEMA +CONSTRAINTS +CONSTRUCTOR +CONTINUE +CURSOR_NAME +DATA +DATETIME_INTERVAL_CODE +DATETIME_INTERVAL_PRECISION +DEFAULTS +DEFERRABLE +DEFERRED +DEFINED +DEFINER +DEGREE +DEPTH +DERIVED +DESC +DESCRIPTOR +DIAGNOSTICS +DISPATCH +DOMAIN +DYNAMIC_FUNCTION +DYNAMIC_FUNCTION_CODE +ENCODING +ENFORCED +ERROR +EXCLUDE +EXCLUDING +EXPRESSION +FINAL +FINISH +FIRST +FLAG +FOLLOWING +FORMAT +FORTRAN +FOUND +FULFILL +G +GENERAL +GENERATED +GO +GOTO +GRANTED +HIERARCHY +IGNORE +IMMEDIATE +IMMEDIATELY +IMPLEMENTATION +INCLUDING +INCREMENT +INITIALLY +INPUT +INSTANCE +INSTANTIABLE +INSTEAD +INVOKER +ISOLATION +JSON +K +KEEP +KEY +KEYS +KEY_MEMBER +KEY_TYPE +LAST +LENGTH +LEVEL +LOCATOR +M +MAP +MATCHED +MAXVALUE +MESSAGE_LENGTH +MESSAGE_OCTET_LENGTH +MESSAGE_TEXT +MINVALUE +MORE +MUMPS +NAME +NAMES +NESTED +NESTING +NEXT +NFC +NFD +NFKC +NFKD +NORMALIZED +NULLABLE +NULLS +NUMBER +OBJECT +OCTETS +OPTION +OPTIONS +ORDERING +ORDINALITY +OTHERS +OUTPUT +OVERFLOW +OVERRIDING +P +PAD +PARAMETER_MODE +PARAMETER_NAME +PARAMETER_ORDINAL_POSITION +PARAMETER_SPECIFIC_CATALOG +PARAMETER_SPECIFIC_NAME +PARAMETER_SPECIFIC_SCHEMA +PARTIAL +PASCAL +PASS +PASSING +PAST +PATH +PLACING +PLAN +PLI +PRECEDING +PRESERVE +PRIOR +PRIVATE +PRIVILEGES +PRUNE +PUBLIC +QUOTES +READ +RELATIVE +REPEATABLE +RESPECT +RESTART +RESTRICT +RETURNED_CARDINALITY +RETURNED_LENGTH +RETURNED_OCTET_LENGTH +RETURNED_SQLSTATE +RETURNING +ROLE +ROUTINE +ROUTINE_CATALOG +ROUTINE_NAME +ROUTINE_SCHEMA +ROW_COUNT +SCALAR +SCALE +SCHEMA +SCHEMA_NAME +SCOPE_CATALOG +SCOPE_NAME +SCOPE_SCHEMA +SECTION +SECURITY +SELF +SEQUENCE +SERIALIZABLE +SERVER_NAME +SESSION +SETS +SIMPLE +SIZE +SOURCE +SPACE +SPECIFIC_NAME +STATE +STATEMENT +STRING +STRUCTURE +STYLE +SUBCLASS_ORIGIN +T +TABLE_NAME +TEMPORARY +THROUGH +TIES +TOP_LEVEL_COUNT +TRANSACTION +TRANSACTION_ACTIVE +TRANSACTIONS_COMMITTED +TRANSACTIONS_ROLLED_BACK +TRANSFORM +TRANSFORMS +TRIGGER_CATALOG +TRIGGER_NAME +TRIGGER_SCHEMA +TYPE +UNBOUNDED +UNCOMMITTED +UNCONDITIONAL +UNDER +UNNAMED +USAGE +USER_DEFINED_TYPE_CATALOG +USER_DEFINED_TYPE_CODE +USER_DEFINED_TYPE_NAME +USER_DEFINED_TYPE_SCHEMA +UTF16 +UTF32 +UTF8 +VIEW +WORK +WRAPPER +WRITE +ZONE diff --git a/doc/src/sgml/keywords/sql2016-02-reserved.txt b/doc/src/sgml/keywords/sql2016-02-reserved.txt new file mode 100644 index 00000000000..ae110123881 --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-02-reserved.txt @@ -0,0 +1,367 @@ +ABS +ACOS +ALL +ALLOCATE +ALTER +AND +ANY +ARE +ARRAY +ARRAY_AGG +ARRAY_MAX_CARDINALITY +AS +ASENSITIVE +ASIN +ASYMMETRIC +AT +ATAN +ATOMIC +AUTHORIZATION +AVG +BEGIN +BEGIN_FRAME +BEGIN_PARTITION +BETWEEN +BIGINT +BINARY +BLOB +BOOLEAN +BOTH +BY +CALL +CALLED +CARDINALITY +CASCADED +CASE +CAST +CEIL +CEILING +CHAR +CHAR_LENGTH +CHARACTER +CHARACTER_LENGTH +CHECK +CLASSIFIER +CLOB +CLOSE +COALESCE +COLLATE +COLLECT +COLUMN +COMMIT +CONDITION +CONNECT +CONSTRAINT +CONTAINS +CONVERT +COPY +CORR +CORRESPONDING +COS +COSH +COUNT +COVAR_POP +COVAR_SAMP +CREATE +CROSS +CUBE +CUME_DIST +CURRENT +CURRENT_CATALOG +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_PATH +CURRENT_ROLE +CURRENT_ROW +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURSOR +CYCLE +DATE +DAY +DEALLOCATE +DEC +DECIMAL +DECFLOAT +DECLARE +DEFAULT +DEFINE +DELETE +DENSE_RANK +DEREF +DESCRIBE +DETERMINISTIC +DISCONNECT +DISTINCT +DOUBLE +DROP +DYNAMIC +EACH +ELEMENT +ELSE +EMPTY +END +END_FRAME +END_PARTITION +END-EXEC +EQUALS +ESCAPE +EVERY +EXCEPT +EXEC +EXECUTE +EXISTS +EXP +EXTERNAL +EXTRACT +FALSE +FETCH +FILTER +FIRST_VALUE +FLOAT +FLOOR +FOR +FOREIGN +FRAME_ROW +FREE +FROM +FULL +FUNCTION +FUSION +GET +GLOBAL +GRANT +GROUP +GROUPING +GROUPS +HAVING +HOLD +HOUR +IDENTITY +IN +INDICATOR +INITIAL +INNER +INOUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +JOIN +JSON_ARRAY +JSON_ARRAYAGG +JSON_EXISTS +JSON_OBJECT +JSON_OBJECTAGG +JSON_QUERY +JSON_TABLE +JSON_TABLE_PRIMITIVE +JSON_VALUE +LAG +LANGUAGE +LARGE +LAST_VALUE +LATERAL +LEAD +LEADING +LEFT +LIKE +LIKE_REGEX +LISTAGG +LN +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOG +LOG10 +LOWER +MATCH +MATCH_NUMBER +MATCH_RECOGNIZE +MATCHES +MAX +MEASURES +MEMBER +MERGE +METHOD +MIN +MINUTE +MOD +MODIFIES +MODULE +MONTH +MULTISET +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NO +NONE +NORMALIZE +NOT +NTH_VALUE +NTILE +NULL +NULLIF +NUMERIC +OCTET_LENGTH +OCCURRENCES_REGEX +OF +OFFSET +OLD +OMIT +ON +ONE +ONLY +OPEN +OR +ORDER +OUT +OUTER +OVER +OVERLAPS +OVERLAY +PARAMETER +PARTITION +PATTERN +PER +PERCENT +PERCENT_RANK +PERCENTILE_CONT +PERCENTILE_DISC +PERIOD +PERMUTE +PORTION +POSITION +POSITION_REGEX +POWER +PRECEDES +PRECISION +PREPARE +PRIMARY +PROCEDURE +PTF +RANGE +RANK +READS +REAL +RECURSIVE +REF +REFERENCES +REFERENCING +REGR_AVGX +REGR_AVGY +REGR_COUNT +REGR_INTERCEPT +REGR_R2 +REGR_SLOPE +REGR_SXX +REGR_SXY +REGR_SYY +RELEASE +RESULT +RETURN +RETURNS +REVOKE +RIGHT +ROLLBACK +ROLLUP +ROW +ROW_NUMBER +ROWS +RUNNING +SAVEPOINT +SCOPE +SCROLL +SEARCH +SECOND +SEEK +SELECT +SENSITIVE +SESSION_USER +SET +SHOW +SIMILAR +SIN +SINH +SKIP +SMALLINT +SOME +SPECIFIC +SPECIFICTYPE +SQL +SQLEXCEPTION +SQLSTATE +SQLWARNING +SQRT +START +STATIC +STDDEV_POP +STDDEV_SAMP +SUBMULTISET +SUBSET +SUBSTRING +SUBSTRING_REGEX +SUCCEEDS +SUM +SYMMETRIC +SYSTEM +SYSTEM_TIME +SYSTEM_USER +TABLE +TABLESAMPLE +TAN +TANH +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSLATE +TRANSLATE_REGEX +TRANSLATION +TREAT +TRIGGER +TRIM +TRIM_ARRAY +TRUE +TRUNCATE +UESCAPE +UNION +UNIQUE +UNKNOWN +UNMATCHED +UNNEST +UPDATE +UPPER +USER +USING +VALUE +VALUES +VALUE_OF +VAR_POP +VAR_SAMP +VARBINARY +VARCHAR +VARYING +VERSIONING +WHEN +WHENEVER +WHERE +WIDTH_BUCKET +WINDOW +WITH +WITHIN +WITHOUT +YEAR diff --git a/doc/src/sgml/keywords/sql2016-09-nonreserved.txt b/doc/src/sgml/keywords/sql2016-09-nonreserved.txt new file mode 100644 index 00000000000..b360f0ce861 --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-09-nonreserved.txt @@ -0,0 +1,23 @@ +BLOCKED +CONTROL +DB +FILE +FS +INTEGRITY +LIBRARY +LIMIT +LINK +MAPPING +OFF +PASSTHROUGH +PERMISSION +RECOVERY +REQUIRING +RESTORE +SELECTIVE +SERVER +TOKEN +UNLINK +VERSION +WRAPPER +YES diff --git a/doc/src/sgml/keywords/sql2016-09-reserved.txt b/doc/src/sgml/keywords/sql2016-09-reserved.txt new file mode 100644 index 00000000000..02054857667 --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-09-reserved.txt @@ -0,0 +1,13 @@ +DATALINK +DLNEWCOPY +DLPREVIOUSCOPY +DLURLCOMPLETE +DLURLCOMPLETEWRITE +DLURLCOMPLETEONLY +DLURLPATH +DLURLPATHWRITE +DLURLPATHONLY +DLURLSCHEME +DLURLSERVER +DLVALUE +IMPORT diff --git a/doc/src/sgml/keywords/sql2016-14-nonreserved.txt b/doc/src/sgml/keywords/sql2016-14-nonreserved.txt new file mode 100644 index 00000000000..00c88ffc57d --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-14-nonreserved.txt @@ -0,0 +1,27 @@ +ABSENT +ACCORDING +BASE64 +BOM +COLUMNS +CONTENT +DOCUMENT +ENCODING +HEX +ID +INDENT +LOCATION +NAMESPACE +NIL +PATH +PRESERVE +RETURNING +SEQUENCE +STANDALONE +STRIP +UNTYPED +URI +VALID +VERSION +WHITESPACE +XMLSCHEMA +XMLDECLARATION diff --git a/doc/src/sgml/keywords/sql2016-14-reserved.txt b/doc/src/sgml/keywords/sql2016-14-reserved.txt new file mode 100644 index 00000000000..cf8052946f9 --- /dev/null +++ b/doc/src/sgml/keywords/sql2016-14-reserved.txt @@ -0,0 +1,20 @@ +XML +XMLAGG +XMLATTRIBUTES +XMLBINARY +XMLCAST +XMLCOMMENT +XMLCONCAT +XMLDOCUMENT +XMLELEMENT +XMLEXISTS +XMLFOREST +XMLITERATE +XMLNAMESPACES +XMLPARSE +XMLPI +XMLQUERY +XMLSERIALIZE +XMLTABLE +XMLTEXT +XMLVALIDATE diff --git a/doc/src/sgml/legal.sgml b/doc/src/sgml/legal.sgml index fd5cda30b74..9bb1d7983be 100644 --- a/doc/src/sgml/legal.sgml +++ b/doc/src/sgml/legal.sgml @@ -1,9 +1,9 @@ -2018 +2019 - 1996-2018 + 1996-2019 The PostgreSQL Global Development Group @@ -11,7 +11,7 @@ Legal Notice - PostgreSQL is Copyright © 1996-2018 + PostgreSQL is Copyright © 1996-2019 by the PostgreSQL Global Development Group. diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 1626999a701..c58527b0c3b 100644 --- a/doc/src/sgml/libpq.sgml +++ b/doc/src/sgml/libpq.sgml @@ -56,12 +56,12 @@ one time. (One reason to do that is to access more than one database.) Each connection is represented by a PGconnPGconn object, which - is obtained from the function PQconnectdb, - PQconnectdbParams, or - PQsetdbLogin. Note that these functions will always + is obtained from the function , + , or + . Note that these functions will always return a non-null object pointer, unless perhaps there is too little memory even to allocate the PGconn object. - The PQstatus function should be called to check + The function should be called to check the return value for a successful connection before queries are sent via the connection object. @@ -107,7 +107,7 @@ - + PQconnectdbParamsPQconnectdbParams @@ -125,9 +125,9 @@ PGconn *PQconnectdbParams(const char * const *keywords, from two NULL-terminated arrays. The first, keywords, is defined as an array of strings, each one being a key word. The second, values, gives the value - for each key word. Unlike PQsetdbLogin below, the parameter + for each key word. Unlike below, the parameter set can be extended without changing the function signature, so use of - this function (or its nonblocking analogs PQconnectStartParams + this function (or its nonblocking analogs and PQconnectPoll) is preferred for new application programming. @@ -172,7 +172,7 @@ PGconn *PQconnectdbParams(const char * const *keywords, - + PQconnectdbPQconnectdb @@ -199,7 +199,7 @@ PGconn *PQconnectdb(const char *conninfo); - + PQsetdbLoginPQsetdbLogin @@ -216,7 +216,7 @@ PGconn *PQsetdbLogin(const char *pghost, - This is the predecessor of PQconnectdb with a fixed + This is the predecessor of with a fixed set of parameters. It has the same functionality except that the missing parameters will always take on default values. Write NULL or an empty string for any one of the fixed parameters that is to be defaulted. @@ -226,13 +226,13 @@ PGconn *PQsetdbLogin(const char *pghost, If the dbName contains an = sign or has a valid connection URI prefix, it is taken as a conninfo string in exactly the same way as - if it had been passed to PQconnectdb, and the remaining - parameters are then applied as specified for PQconnectdbParams. + if it had been passed to , and the remaining + parameters are then applied as specified for . - + PQsetdbPQsetdb @@ -247,14 +247,14 @@ PGconn *PQsetdb(char *pghost, - This is a macro that calls PQsetdbLogin with null pointers + This is a macro that calls with null pointers for the login and pwd parameters. It is provided for backward compatibility with very old programs. - + PQconnectStartParamsPQconnectStartParams PQconnectStartPQconnectStart PQconnectPollPQconnectPoll @@ -279,46 +279,46 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); that your application's thread of execution is not blocked on remote I/O whilst doing so. The point of this approach is that the waits for I/O to complete can occur in the application's main loop, rather than down inside - PQconnectdbParams or PQconnectdb, and so the + or , and so the application can manage this operation in parallel with other activities. - With PQconnectStartParams, the database connection is made + With , the database connection is made using the parameters taken from the keywords and values arrays, and controlled by expand_dbname, - as described above for PQconnectdbParams. + as described above for . With PQconnectStart, the database connection is made using the parameters taken from the string conninfo as - described above for PQconnectdb. + described above for . - Neither PQconnectStartParams nor PQconnectStart + Neither nor PQconnectStart nor PQconnectPoll will block, so long as a number of restrictions are met: - The hostaddr and host parameters are used appropriately to ensure that - name and reverse name queries are not made. See the documentation of - these parameters in for details. + The hostaddr parameter must be used appropriately + to prevent DNS queries from being made. See the documentation of + this parameter in for details. - If you call PQtrace, ensure that the stream object + If you call , ensure that the stream object into which you trace will not block. - You ensure that the socket is in the appropriate state + You must ensure that the socket is in the appropriate state before calling PQconnectPoll, as described below. @@ -326,24 +326,27 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); - Note: use of PQconnectStartParams is analogous to - PQconnectStart shown below. + To begin a nonblocking connection request, + call PQconnectStart + or . If the result is null, + then libpq has been unable to allocate a + new PGconn structure. Otherwise, a + valid PGconn pointer is returned (though not + yet representing a valid connection to the database). Next + call PQstatus(conn). If the result + is CONNECTION_BAD, the connection attempt has already + failed, typically because of invalid connection parameters. - To begin a nonblocking connection request, call conn = PQconnectStart("connection_info_string"). - If conn is null, then libpq has been unable to allocate a new PGconn - structure. Otherwise, a valid PGconn pointer is returned (though not yet - representing a valid connection to the database). On return from - PQconnectStart, call status = PQstatus(conn). If status equals - CONNECTION_BAD, PQconnectStart has failed. - - - - If PQconnectStart succeeds, the next stage is to poll - libpq so that it can proceed with the connection sequence. + If PQconnectStart + or succeeds, the next stage + is to poll libpq so that it can proceed with + the connection sequence. Use PQsocket(conn) to obtain the descriptor of the socket underlying the database connection. + (Caution: do not assume that the socket remains the same + across PQconnectPoll calls.) Loop thus: If PQconnectPoll(conn) last returned PGRES_POLLING_READING, wait until the socket is ready to read (as indicated by select(), poll(), or @@ -352,9 +355,8 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); Conversely, if PQconnectPoll(conn) last returned PGRES_POLLING_WRITING, wait until the socket is ready to write, then call PQconnectPoll(conn) again. - If you have yet to call - PQconnectPoll, i.e., just after the call to - PQconnectStart, behave as if it last returned + On the first iteration, i.e. if you have yet to call + PQconnectPoll, behave as if it last returned PGRES_POLLING_WRITING. Continue this loop until PQconnectPoll(conn) returns PGRES_POLLING_FAILED, indicating the connection procedure @@ -364,7 +366,7 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn); At any time during connection, the status of the connection can be - checked by calling PQstatus. If this call returns CONNECTION_BAD, then the + checked by calling . If this call returns CONNECTION_BAD, then the connection procedure has failed; if the call returns CONNECTION_OK, then the connection is ready. Both of these states are equally detectable from the return value of PQconnectPoll, described above. Other states might also occur @@ -475,19 +477,21 @@ switch(PQstatus(conn)) responsibility to decide whether an excessive amount of time has elapsed. Otherwise, PQconnectStart followed by a PQconnectPoll loop is equivalent to - PQconnectdb. + . - Note that if PQconnectStart returns a non-null pointer, you must call - PQfinish when you are finished with it, in order to dispose of - the structure and any associated memory blocks. This must be done even if - the connection attempt fails or is abandoned. + Note that when PQconnectStart + or returns a non-null + pointer, you must call when you are + finished with it, in order to dispose of the structure and any + associated memory blocks. This must be done even if the connection + attempt fails or is abandoned. - + PQconndefaultsPQconndefaults @@ -514,7 +518,7 @@ typedef struct Returns a connection options array. This can be used to determine - all possible PQconnectdb options and their + all possible options and their current default values. The return value points to an array of PQconninfoOption structures, which ends with an entry having a null keyword pointer. The @@ -527,14 +531,14 @@ typedef struct After processing the options array, free it by passing it to - PQconninfoFree. If this is not done, a small amount of memory - is leaked for each call to PQconndefaults. + . If this is not done, a small amount of memory + is leaked for each call to . - + PQconninfoPQconninfo @@ -546,19 +550,19 @@ PQconninfoOption *PQconninfo(PGconn *conn); Returns a connection options array. This can be used to determine - all possible PQconnectdb options and the + all possible options and the values that were used to connect to the server. The return value points to an array of PQconninfoOption structures, which ends with an entry having a null keyword - pointer. All notes above for PQconndefaults also - apply to the result of PQconninfo. + pointer. All notes above for also + apply to the result of . - + PQconninfoParsePQconninfoParse @@ -573,7 +577,7 @@ PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); Parses a connection string and returns the resulting options as an array; or returns NULL if there is a problem with the connection string. This function can be used to extract - the PQconnectdb options in the provided + the options in the provided connection string. The return value points to an array of PQconninfoOption structures, which ends with an entry having a null keyword pointer. @@ -596,16 +600,16 @@ PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); After processing the options array, free it by passing it to - PQconninfoFree. If this is not done, some memory - is leaked for each call to PQconninfoParse. + . If this is not done, some memory + is leaked for each call to . Conversely, if an error occurs and errmsg is not NULL, - be sure to free the error string using PQfreemem. + be sure to free the error string using . - + PQfinishPQfinish @@ -618,15 +622,15 @@ void PQfinish(PGconn *conn); Note that even if the server connection attempt fails (as - indicated by PQstatus), the application should call PQfinish + indicated by ), the application should call to free the memory used by the PGconn object. The PGconn pointer must not be used again after - PQfinish has been called. + has been called. - + PQresetPQreset @@ -646,7 +650,7 @@ void PQreset(PGconn *conn); - + PQresetStartPQresetStart PQresetPollPQresetPoll @@ -664,15 +668,15 @@ PostgresPollingStatusType PQresetPoll(PGconn *conn); These functions will close the connection to the server and attempt to reestablish a new connection to the same server, using all the same parameters previously used. This can be useful for error recovery if a - working connection is lost. They differ from PQreset (above) in that they + working connection is lost. They differ from (above) in that they act in a nonblocking manner. These functions suffer from the same - restrictions as PQconnectStartParams, PQconnectStart + restrictions as , PQconnectStart and PQconnectPoll. To initiate a connection reset, call - PQresetStart. If it returns 0, the reset has + . If it returns 0, the reset has failed. If it returns 1, poll the reset using PQresetPoll in exactly the same way as you would create the connection using PQconnectPoll. @@ -680,13 +684,13 @@ PostgresPollingStatusType PQresetPoll(PGconn *conn); - + PQpingParamsPQpingParams - PQpingParams reports the status of the + reports the status of the server. It accepts connection parameters identical to those of - PQconnectdbParams, described above. It is not + , described above. It is not necessary to supply correct user name, password, or database name values to obtain the server status; however, if incorrect values are provided, the server will log a failed connection attempt. @@ -700,7 +704,7 @@ PGPing PQpingParams(const char * const *keywords, The function returns one of the following values: - + PQPING_OK @@ -709,7 +713,7 @@ PGPing PQpingParams(const char * const *keywords, - + PQPING_REJECT @@ -719,7 +723,7 @@ PGPing PQpingParams(const char * const *keywords, - + PQPING_NO_RESPONSE @@ -732,7 +736,7 @@ PGPing PQpingParams(const char * const *keywords, - + PQPING_NO_ATTEMPT @@ -749,13 +753,13 @@ PGPing PQpingParams(const char * const *keywords, - + PQpingPQping - PQping reports the status of the + reports the status of the server. It accepts connection parameters identical to those of - PQconnectdb, described above. It is not + , described above. It is not necessary to supply correct user name, password, or database name values to obtain the server status; however, if incorrect values are provided, the server will log a failed connection attempt. @@ -766,7 +770,7 @@ PGPing PQping(const char *conninfo); - The return values are the same as for PQpingParams. + The return values are the same as for . @@ -913,7 +917,8 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname It is possible to specify multiple hosts to connect to, so that they are tried in the given order. In the Keyword/Value format, the host, hostaddr, and port options accept a comma-separated - list of values. The same number of elements must be given in each option, such + list of values. The same number of elements must be given in each + option that is specified, such that e.g. the first hostaddr corresponds to the first host name, the second hostaddr corresponds to the second host name, and so forth. As an exception, if only one port is specified, it @@ -922,13 +927,17 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname In the connection URI format, you can list multiple host:port pairs - separated by commas, in the host component of the URI. In either - format, a single hostname can also translate to multiple network addresses. A - common example of this is a host that has both an IPv4 and an IPv6 address. + separated by commas, in the host component of the URI. + + + + In either format, a single host name can translate to multiple network + addresses. A common example of this is a host that has both an IPv4 and + an IPv6 address. - When multiple hosts are specified, or when a single hostname is + When multiple hosts are specified, or when a single host name is translated to multiple addresses, all the hosts and addresses will be tried in order, until one succeeds. If none of the hosts can be reached, the connection fails. If a connection is established successfully, but @@ -938,8 +947,8 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname If a password file is used, you can have different passwords for different hosts. All the other connection options are the same for every - host, it is not possible to e.g. specify a different username for - different hosts. + host in the list; it is not possible to e.g. specify different + usernames for different hosts. @@ -958,10 +967,9 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname Name of host to connect to.host name If a host name begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the - name of the directory in which the socket file is stored. If - multiple host names are specified, each will be tried in turn in - the order given. The default behavior when host is - not specified is to connect to a Unix-domain + name of the directory in which the socket file is stored. + The default behavior when host is + not specified, or is empty, is to connect to a Unix-domain socketUnix domain socket in /tmp (or whatever socket directory was specified when PostgreSQL was built). On machines without @@ -969,7 +977,8 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname A comma-separated list of host names is also accepted, in which case - each host name in the list is tried in order. See + each host name in the list is tried in order; an empty item in the + list selects the default behavior as explained above. See for details. @@ -984,10 +993,14 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname your machine supports IPv6, you can also use those addresses. TCP/IP communication is always used when a nonempty string is specified for this parameter. + If this parameter is not specified, the value of host + will be looked up to find the corresponding IP address — or, if + host specifies an IP address, that value will be + used directly. - Using hostaddr instead of host allows the + Using hostaddr allows the application to avoid a host name look-up, which might be important in applications with time constraints. However, a host name is required for GSSAPI or SSPI authentication @@ -996,8 +1009,12 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - If host is specified without hostaddr, - a host name lookup occurs. + If host is specified + without hostaddr, a host name lookup occurs. + (When using PQconnectPoll, the lookup occurs + when PQconnectPoll first considers this host + name, and it may cause PQconnectPoll to block + for a significant amount of time.) @@ -1020,14 +1037,17 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname Note that authentication is likely to fail if host is not the name of the server at network address hostaddr. - Also, note that host rather than hostaddr + Also, when both host and hostaddr + are specified, host is used to identify the connection in a password file (see ). A comma-separated list of hostaddr values is also - accepted, in which case each host in the list is tried in order. See + accepted, in which case each host in the list is tried in order. + An empty item in the list causes the corresponding host name to be + used, or the default host name if that is empty as well. See for details. @@ -1047,9 +1067,12 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname name extension for Unix-domain connections.port If multiple hosts were given in the host or - hostaddr parameters, this parameter may specify a list - of ports of equal length, or it may specify a single port number to - be used for all hosts. + hostaddr parameters, this parameter may specify a + comma-separated list of ports of the same length as the host list, or + it may specify a single port number to be used for all hosts. + An empty string, or an empty item in a comma-separated list, + specifies the default port number established + when PostgreSQL was built. @@ -1099,14 +1122,37 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname + + channel_binding + + + This option controls the client's use of channel binding. A setting + of require means that the connection must employ + channel binding, prefer means that the client will + choose channel binding if available, and disable + prevents the use of channel binding. The default + is prefer if + PostgreSQL is compiled with SSL support; + otherwise the default is disable. + + + Channel binding is a method for the server to authenticate itself to + the client. It is only supported over SSL connections + with PostgreSQL 11 or later servers using + the SCRAM authentication method. + + + + connect_timeout - Maximum wait for connection, in seconds (write as a decimal integer - string). Zero or not specified means wait indefinitely. It is not - recommended to use a timeout of less than 2 seconds. - This timeout applies separately to each connection attempt. + Maximum wait for connection, in seconds (write as a decimal integer, + e.g. 10). Zero, negative, or not specified means + wait indefinitely. The minimum allowed timeout is 2 seconds, therefore + a value of 1 is interpreted as 2. + This timeout applies separately to each host name or IP address. For example, if you specify two hosts and connect_timeout is 5, each host will time out if no connection is made within 5 seconds, so the total time spent waiting for a connection might be @@ -1229,6 +1275,20 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname + + tcp_user_timeout + + + Controls the number of milliseconds that transmitted data may + remain unacknowledged before a connection is forcibly closed. + A value of zero uses the system default. This parameter is + ignored for connections made via a Unix-domain socket. + It is only supported on systems where TCP_USER_TIMEOUT + is available; on other systems, it has no effect. + + + + tty @@ -1238,30 +1298,6 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname - - scram_channel_binding - - - Specifies the channel binding type to use with SCRAM authentication. - The list of channel binding types supported by server are listed in - . An empty value specifies that - the client will not use channel binding. The default value is - tls-unique. - - - - Channel binding is only supported on SSL connections. If the - connection is not using SSL, then this setting is ignored. - - - - This parameter is mainly intended for protocol testing. In normal - use, there should not be a need to choose a channel binding type other - than the default one. - - - - replication @@ -1320,6 +1356,63 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname + + gssencmode + + + This option determines whether or with what priority a secure + GSS TCP/IP connection will be negotiated with the + server. There are three modes: + + + + disable + + + only try a non-GSSAPI-encrypted connection + + + + + + prefer (default) + + + if there are GSSAPI credentials present (i.e., + in a credentials cache), first try + a GSSAPI-encrypted connection; if that fails or + there are no credentials, try a + non-GSSAPI-encrypted connection. This is the + default when PostgreSQL has been + compiled with GSSAPI support. + + + + + + require + + + only try a GSSAPI-encrypted connection + + + + + + + + gssencmode is ignored for Unix domain socket + communication. If PostgreSQL is compiled + without GSSAPI support, using the require option + will cause an error, while prefer will be accepted + but libpq will not actually attempt + a GSSAPI-encrypted + connection.GSSAPIwith + libpq + + + + sslmode @@ -1622,19 +1715,14 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname The following functions return parameter values established at connection. These values are fixed for the life of the connection. If a multi-host - connection string is used, the values of PQhost, - PQport, and PQpass can change if a new connection + connection string is used, the values of , + , and can change if a new connection is established using the same PGconn object. Other values are fixed for the lifetime of the PGconn object. - - - PQdb - - PQdb - - + + PQdbPQdb @@ -1646,13 +1734,8 @@ char *PQdb(const PGconn *conn); - - - PQuser - - PQuser - - + + PQuserPQuser @@ -1664,13 +1747,8 @@ char *PQuser(const PGconn *conn); - - - PQpass - - PQpass - - + + PQpassPQpass @@ -1679,16 +1757,22 @@ char *PQuser(const PGconn *conn); char *PQpass(const PGconn *conn); + + + will return either the password specified + in the connection parameters, or if there was none and the password + was obtained from the password + file, it will return that. In the latter case, + if multiple hosts were specified in the connection parameters, it is + not possible to rely on the result of until + the connection is established. The status of the connection can be + checked using the function . + - - - PQhost - - PQhost - - + + PQhostPQhost @@ -1704,15 +1788,15 @@ char *PQhost(const PGconn *conn); If the connection parameters specified both host and - hostaddr, then PQhost will + hostaddr, then will return the host information. If only hostaddr was specified, then that is returned. If multiple hosts were specified in the connection parameters, - PQhost returns the host actually connected to. + returns the host actually connected to. - PQhost returns NULL if the + returns NULL if the conn argument is NULL. Otherwise, if there is an error producing the host information (perhaps if the connection has not been fully established or there was an @@ -1721,20 +1805,40 @@ char *PQhost(const PGconn *conn); If multiple hosts were specified in the connection parameters, it is - not possible to rely on the result of PQhost until + not possible to rely on the result of until the connection is established. The status of the connection can be - checked using the function PQstatus. + checked using the function . - - - PQport - - PQport - - + + + PQhostaddrPQhostaddr + + + + Returns the server IP address of the active connection. + This can be the address that a host name resolved to, + or an IP address provided through the hostaddr + parameter. + +char *PQhostaddr(const PGconn *conn); + + + + + returns NULL if the + conn argument is NULL. + Otherwise, if there is an error producing the host information + (perhaps if the connection has not been fully established or + there was an error), it returns an empty string. + + + + + + PQportPQport @@ -1747,11 +1851,11 @@ char *PQport(const PGconn *conn); If multiple ports were specified in the connection parameters, - PQport returns the port actually connected to. + returns the port actually connected to. - PQport returns NULL if the + returns NULL if the conn argument is NULL. Otherwise, if there is an error producing the port information (perhaps if the connection has not been fully established or there was an @@ -1760,20 +1864,15 @@ char *PQport(const PGconn *conn); If multiple ports were specified in the connection parameters, it is - not possible to rely on the result of PQport until + not possible to rely on the result of until the connection is established. The status of the connection can be - checked using the function PQstatus. + checked using the function . - - - PQtty - - PQtty - - + + PQttyPQtty @@ -1789,13 +1888,8 @@ char *PQtty(const PGconn *conn); - - - PQoptions - - PQoptions - - + + PQoptionsPQoptions @@ -1814,13 +1908,8 @@ char *PQoptions(const PGconn *conn); are executed on the PGconn object. - - - PQstatus - - PQstatus - - + + PQstatusPQstatus @@ -1838,28 +1927,23 @@ ConnStatusType PQstatus(const PGconn *conn); has the status CONNECTION_OK. A failed connection attempt is signaled by status CONNECTION_BAD. Ordinarily, an OK status will - remain so until PQfinish, but a communications + remain so until , but a communications failure might result in the status changing to CONNECTION_BAD prematurely. In that case the application could try to recover by calling - PQreset. + . - See the entry for PQconnectStartParams, PQconnectStart + See the entry for , PQconnectStart and PQconnectPoll with regards to other status codes that might be returned. - - - PQtransactionStatus - - PQtransactionStatus - - + + PQtransactionStatusPQtransactionStatus @@ -1880,13 +1964,8 @@ PGTransactionStatusType PQtransactionStatus(const PGconn *conn); - - - PQparameterStatus - - PQparameterStatus - - + + PQparameterStatusPQparameterStatus @@ -1898,7 +1977,7 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); Certain parameter values are reported by the server automatically at connection startup or whenever their values change. - PQparameterStatus can be used to interrogate these settings. + can be used to interrogate these settings. It returns the current value of a parameter if known, or NULL if the parameter is not known. @@ -1933,13 +2012,13 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); Pre-3.0-protocol servers do not report parameter settings, but libpq includes logic to obtain values for server_version and client_encoding anyway. - Applications are encouraged to use PQparameterStatus + Applications are encouraged to use rather than ad hoc code to determine these values. (Beware however that on a pre-3.0 connection, changing client_encoding via SET after connection - startup will not be reflected by PQparameterStatus.) + startup will not be reflected by .) For server_version, see also - PQserverVersion, which returns the information in a + , which returns the information in a numeric form that is much easier to compare against. @@ -1959,13 +2038,8 @@ const char *PQparameterStatus(const PGconn *conn, const char *paramName); - - - PQprotocolVersion - - PQprotocolVersion - - + + PQprotocolVersionPQprotocolVersion @@ -1987,13 +2061,8 @@ int PQprotocolVersion(const PGconn *conn); - - - PQserverVersion - - PQserverVersion - - + + PQserverVersionPQserverVersion @@ -2016,14 +2085,14 @@ int PQserverVersion(const PGconn *conn); Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version. For those - versions, PQserverVersion uses two digits for each + versions, uses two digits for each part; for example version 9.1.5 will be returned as 90105, and version 9.2.0 will be returned as 90200. Therefore, for purposes of determining feature compatibility, - applications should divide the result of PQserverVersion + applications should divide the result of by 100 not 10000 to determine a logical major version number. In all release series, only the last two digits differ between minor releases (bug-fix releases). @@ -2031,13 +2100,8 @@ int PQserverVersion(const PGconn *conn); - - - PQerrorMessage - - PQerrorMessage - - + + PQerrorMessagePQerrorMessage @@ -2052,20 +2116,20 @@ char *PQerrorMessage(const PGconn *conn); Nearly all libpq functions will set a message for - PQerrorMessage if they fail. Note that by + if they fail. Note that by libpq convention, a nonempty - PQerrorMessage result can consist of multiple lines, + result can consist of multiple lines, and will include a trailing newline. The caller should not free the result directly. It will be freed when the associated PGconn handle is passed to - PQfinish. The result string should not be + . The result string should not be expected to remain the same across operations on the PGconn structure. - + PQsocketPQsocket @@ -2083,7 +2147,7 @@ int PQsocket(const PGconn *conn); - + PQbackendPIDPQbackendPID @@ -2110,7 +2174,7 @@ int PQbackendPID(const PGconn *conn); - + PQconnectionNeedsPasswordPQconnectionNeedsPassword @@ -2130,7 +2194,7 @@ int PQconnectionNeedsPassword(const PGconn *conn); - + PQconnectionUsedPasswordPQconnectionUsedPassword @@ -2156,7 +2220,7 @@ int PQconnectionUsedPassword(const PGconn *conn); usually doesn't change after a connection is established. - + PQsslInUsePQsslInUse @@ -2170,7 +2234,7 @@ int PQsslInUse(const PGconn *conn); - + PQsslAttributePQsslAttribute @@ -2243,7 +2307,7 @@ const char *PQsslAttribute(const PGconn *conn, const char *attribute_name); - + PQsslAttributeNamesPQsslAttributeNames @@ -2255,7 +2319,7 @@ const char * const * PQsslAttributeNames(const PGconn *conn); - + PQsslStructPQsslStruct @@ -2296,7 +2360,7 @@ void *PQsslStruct(const PGconn *conn, const char *struct_name); - + PQgetsslPQgetssl @@ -2314,8 +2378,8 @@ void *PQgetssl(const PGconn *conn); not be used in new applications, because the returned struct is specific to OpenSSL and will not be available if another SSL implementation is used. To check if a connection uses SSL, call - PQsslInUse instead, and for more details about the - connection, use PQsslAttribute. + instead, and for more details about the + connection, use . @@ -2339,13 +2403,8 @@ void *PQgetssl(const PGconn *conn); - - - PQexec - - PQexec - - + + PQexecPQexec @@ -2360,11 +2419,11 @@ PGresult *PQexec(PGconn *conn, const char *command); Returns a PGresult pointer or possibly a null pointer. A non-null pointer will generally be returned except in out-of-memory conditions or serious errors such as inability to send - the command to the server. The PQresultStatus function + the command to the server. The function should be called to check the return value for any errors (including the value of a null pointer, in which case it will return PGRES_FATAL_ERROR). Use - PQerrorMessage to get more information about such + to get more information about such errors. @@ -2373,7 +2432,7 @@ PGresult *PQexec(PGconn *conn, const char *command); The command string can include multiple SQL commands (separated by semicolons). Multiple queries sent in a single - PQexec call are processed in a single transaction, unless + call are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands included in the query string to divide it into multiple transactions. (See @@ -2387,13 +2446,8 @@ PGresult *PQexec(PGconn *conn, const char *command); - - - PQexecParams - - PQexecParams - - + + PQexecParamsPQexecParams @@ -2414,10 +2468,10 @@ PGresult *PQexecParams(PGconn *conn, - PQexecParams is like PQexec, but offers additional + is like , but offers additional functionality: parameter values can be specified separately from the command string proper, and query results can be requested in either text or binary - format. PQexecParams is supported only in protocol 3.0 and later + format. is supported only in protocol 3.0 and later connections; it will fail when using protocol 2.0. @@ -2538,14 +2592,14 @@ PGresult *PQexecParams(PGconn *conn, - The primary advantage of PQexecParams over - PQexec is that parameter values can be separated from the + The primary advantage of over + is that parameter values can be separated from the command string, thus avoiding the need for tedious and error-prone quoting and escaping. - Unlike PQexec, PQexecParams allows at most + Unlike , allows at most one SQL command in the given string. (There can be semicolons in it, but not more than one nonempty command.) This is a limitation of the underlying protocol, but has some usefulness as an extra defense against @@ -2574,12 +2628,8 @@ SELECT * FROM mytable WHERE x = $1::bigint; - - PQprepare - - PQprepare - - + + PQpreparePQprepare @@ -2595,11 +2645,11 @@ PGresult *PQprepare(PGconn *conn, - PQprepare creates a prepared statement for later - execution with PQexecPrepared. This feature allows + creates a prepared statement for later + execution with . This feature allows commands to be executed repeatedly without being parsed and planned each time; see for details. - PQprepare is supported only in protocol 3.0 and later + is supported only in protocol 3.0 and later connections; it will fail when using protocol 2.0. @@ -2623,23 +2673,23 @@ PGresult *PQprepare(PGconn *conn, for an untyped literal string. Also, the query can use parameter symbols with numbers higher than nParams; data types will be inferred for these symbols as well. (See - PQdescribePrepared for a means to find out + for a means to find out what data types were inferred.) - As with PQexec, the result is normally a + As with , the result is normally a PGresult object whose contents indicate server-side success or failure. A null result indicates out-of-memory or inability to send the command at all. Use - PQerrorMessage to get more information about + to get more information about such errors. - Prepared statements for use with PQexecPrepared can also + Prepared statements for use with can also be created by executing SQL statements. Also, although there is no libpq function for deleting a prepared statement, the SQL - - - PQexecPrepared - - PQexecPrepared - - + + PQexecPreparedPQexecPrepared @@ -2673,19 +2718,19 @@ PGresult *PQexecPrepared(PGconn *conn, - PQexecPrepared is like PQexecParams, + is like , but the command to be executed is specified by naming a previously-prepared statement, instead of giving a query string. This feature allows commands that will be used repeatedly to be parsed and planned just once, rather than each time they are executed. The statement must have been prepared previously in - the current session. PQexecPrepared is supported + the current session. is supported only in protocol 3.0 and later connections; it will fail when using protocol 2.0. - The parameters are identical to PQexecParams, except that the + The parameters are identical to , except that the name of a prepared statement is given instead of a query string, and the paramTypes[] parameter is not present (it is not needed since the prepared statement's parameter types were determined when it was created). @@ -2693,13 +2738,8 @@ PGresult *PQexecPrepared(PGconn *conn, - - - PQdescribePrepared - - PQdescribePrepared - - + + PQdescribePreparedPQdescribePrepared @@ -2711,9 +2751,9 @@ PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName); - PQdescribePrepared allows an application to obtain + allows an application to obtain information about a previously prepared statement. - PQdescribePrepared is supported only in protocol 3.0 + is supported only in protocol 3.0 and later connections; it will fail when using protocol 2.0. @@ -2722,24 +2762,19 @@ PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName); the unnamed statement, otherwise it must be the name of an existing prepared statement. On success, a PGresult with status PGRES_COMMAND_OK is returned. The - functions PQnparams and - PQparamtype can be applied to this + functions and + can be applied to this PGresult to obtain information about the parameters of the prepared statement, and the functions - PQnfields, PQfname, - PQftype, etc provide information about the + , , + , etc provide information about the result columns (if any) of the statement. - - - PQdescribePortal - - PQdescribePortal - - + + PQdescribePortalPQdescribePortal @@ -2751,12 +2786,12 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); - PQdescribePortal allows an application to obtain + allows an application to obtain information about a previously created portal. (libpq does not provide any direct access to portals, but you can use this function to inspect the properties of a cursor created with a DECLARE CURSOR SQL command.) - PQdescribePortal is supported only in protocol 3.0 + is supported only in protocol 3.0 and later connections; it will fail when using protocol 2.0. @@ -2765,8 +2800,8 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); the unnamed portal, otherwise it must be the name of an existing portal. On success, a PGresult with status PGRES_COMMAND_OK is returned. The functions - PQnfields, PQfname, - PQftype, etc can be applied to the + , , + , etc can be applied to the PGresult to obtain information about the result columns (if any) of the portal. @@ -2786,13 +2821,8 @@ PGresult *PQdescribePortal(PGconn *conn, const char *portalName); are subject to change in the future. - - - PQresultStatus - - PQresultStatus - - + + PQresultStatusPQresultStatus @@ -2803,7 +2833,7 @@ ExecStatusType PQresultStatus(const PGresult *res); - PQresultStatus can return one of the following values: + can return one of the following values: @@ -2918,7 +2948,7 @@ ExecStatusType PQresultStatus(const PGresult *res); A result of status PGRES_NONFATAL_ERROR will - never be returned directly by PQexec or other + never be returned directly by or other query execution functions; results of this kind are instead passed to the notice processor (see ). @@ -2926,18 +2956,13 @@ ExecStatusType PQresultStatus(const PGresult *res); - - - PQresStatus - - PQresStatus - - + + PQresStatusPQresStatus Converts the enumerated type returned by - PQresultStatus into a string constant describing the + into a string constant describing the status code. The caller should not free the result. @@ -2947,13 +2972,8 @@ char *PQresStatus(ExecStatusType status); - - - PQresultErrorMessage - - PQresultErrorMessage - - + + PQresultErrorMessagePQresultErrorMessage @@ -2965,33 +2985,28 @@ char *PQresultErrorMessage(const PGresult *res); If there was an error, the returned string will include a trailing newline. The caller should not free the result directly. It will be freed when the associated PGresult handle is - passed to PQclear. + passed to . - Immediately following a PQexec or - PQgetResult call, - PQerrorMessage (on the connection) will return - the same string as PQresultErrorMessage (on + Immediately following a or + call, + (on the connection) will return + the same string as (on the result). However, a PGresult will retain its error message until destroyed, whereas the connection's error message will change when subsequent operations are done. - Use PQresultErrorMessage when you want to + Use when you want to know the status associated with a particular PGresult; use - PQerrorMessage when you want to know the + when you want to know the status from the latest operation on the connection. - - - PQresultVerboseErrorMessage - - PQresultVerboseErrorMessage - - + + PQresultVerboseErrorMessagePQresultVerboseErrorMessage @@ -3004,9 +3019,9 @@ char *PQresultVerboseErrorMessage(const PGresult *res, In some situations a client might wish to obtain a more detailed version of a previously-reported error. - PQresultVerboseErrorMessage addresses this need + addresses this need by computing the message that would have been produced - by PQresultErrorMessage if the specified + by if the specified verbosity settings had been in effect for the connection when the given PGresult was generated. If the PGresult is not an error result, @@ -3027,7 +3042,7 @@ char *PQresultVerboseErrorMessage(const PGresult *res, - + PQresultErrorFieldPQresultErrorField @@ -3042,7 +3057,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); not include a trailing newline. The caller should not free the result directly. It will be freed when the associated PGresult handle is passed to - PQclear. + . @@ -3061,7 +3076,7 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); - + PG_DIAG_SEVERITY_NONLOCALIZED @@ -3078,13 +3093,8 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); - - PG_DIAG_SQLSTATE - - error codes - libpq - - + PG_DIAG_SQLSTATEerror codeslibpq The SQLSTATE code for the error. The SQLSTATE code identifies @@ -3301,13 +3311,13 @@ char *PQresultErrorField(const PGresult *res, int fieldcode); - + PQclearPQclear Frees the storage associated with a PGresult. Every command result should be - freed via PQclear when it is no longer + freed via when it is no longer needed. @@ -3319,7 +3329,7 @@ void PQclear(PGresult *res); You can keep a PGresult object around for as long as you need it; it does not go away when you issue a new command, nor even if you close the connection. To get rid of it, - you must call PQclear. Failure to do this + you must call . Failure to do this will result in memory leaks in your application. @@ -3344,13 +3354,8 @@ void PQclear(PGresult *res); - - - PQntuples - - PQntuples - - + + PQntuplesPQntuples @@ -3367,13 +3372,8 @@ int PQntuples(const PGresult *res); - - - PQnfields - - PQnfields - - + + PQnfieldsPQnfields @@ -3387,13 +3387,8 @@ int PQnfields(const PGresult *res); - - - PQfname - - PQfname - - + + PQfnamePQfname @@ -3401,7 +3396,7 @@ int PQnfields(const PGresult *res); Column numbers start at 0. The caller should not free the result directly. It will be freed when the associated PGresult handle is passed to - PQclear. + . char *PQfname(const PGresult *res, int column_number); @@ -3414,13 +3409,8 @@ char *PQfname(const PGresult *res, - - - PQfnumber - - PQfnumber - - + + PQfnumberPQfnumber @@ -3455,13 +3445,8 @@ PQfnumber(res, "\"BAR\"") 1 - - - PQftable - - PQftable - - + + PQftablePQftable @@ -3490,13 +3475,8 @@ Oid PQftable(const PGresult *res, - - - PQftablecol - - PQftablecol - - + + PQftablecolPQftablecol @@ -3517,13 +3497,8 @@ int PQftablecol(const PGresult *res, - - - PQfformat - - PQfformat - - + + PQfformatPQfformat @@ -3543,13 +3518,8 @@ int PQfformat(const PGresult *res, - - - PQftype - - PQftype - - + + PQftypePQftype @@ -3572,13 +3542,8 @@ Oid PQftype(const PGresult *res, - - - PQfmod - - PQfmod - - + + PQfmodPQfmod @@ -3600,13 +3565,8 @@ int PQfmod(const PGresult *res, - - - PQfsize - - PQfsize - - + + PQfsizePQfsize @@ -3619,7 +3579,7 @@ int PQfsize(const PGresult *res, - PQfsize returns the space allocated for this column + returns the space allocated for this column in a database row, in other words the size of the server's internal representation of the data type. (Accordingly, it is not really very useful to clients.) A negative value indicates @@ -3628,13 +3588,8 @@ int PQfsize(const PGresult *res, - - - PQbinaryTuples - - PQbinaryTuples - - + + PQbinaryTuplesPQbinaryTuples @@ -3649,20 +3604,15 @@ int PQbinaryTuples(const PGresult *res); This function is deprecated (except for its use in connection with COPY), because it is possible for a single PGresult to contain text data in some columns and - binary data in others. PQfformat is preferred. - PQbinaryTuples returns 1 only if all columns of the + binary data in others. is preferred. + returns 1 only if all columns of the result are binary (format 1). - - - PQgetvalue - - PQgetvalue - - + + PQgetvaluePQgetvalue @@ -3670,7 +3620,7 @@ int PQbinaryTuples(const PGresult *res); PGresult. Row and column numbers start at 0. The caller should not free the result directly. It will be freed when the associated PGresult handle is - passed to PQclear. + passed to . char *PQgetvalue(const PGresult *res, int row_number, @@ -3680,7 +3630,7 @@ char *PQgetvalue(const PGresult *res, For data in text format, the value returned by - PQgetvalue is a null-terminated character + is a null-terminated character string representation of the field value. For data in binary format, the value is in the binary representation determined by the data type's typsend and typreceive @@ -3691,12 +3641,12 @@ char *PQgetvalue(const PGresult *res, An empty string is returned if the field value is null. See - PQgetisnull to distinguish null values from + to distinguish null values from empty-string values. - The pointer returned by PQgetvalue points + The pointer returned by points to storage that is part of the PGresult structure. One should not modify the data it points to, and one must explicitly copy the data into other storage if it is to be @@ -3706,17 +3656,10 @@ char *PQgetvalue(const PGresult *res, - - - PQgetisnull - - PQgetisnull - - - null value - in libpq - - + + PQgetisnullPQgetisnullnull valuein libpq @@ -3732,18 +3675,14 @@ int PQgetisnull(const PGresult *res, This function returns 1 if the field is null and 0 if it contains a non-null value. (Note that - PQgetvalue will return an empty string, + will return an empty string, not a null pointer, for a null field.) - - - PQgetlength - - PQgetlength - + + PQgetlengthPQgetlength @@ -3759,22 +3698,17 @@ int PQgetlength(const PGresult *res, This is the actual data length for the particular data value, that is, the size of the object pointed to by - PQgetvalue. For text data format this is + . For text data format this is the same as strlen(). For binary format this is essential information. Note that one should not - rely on PQfsize to obtain the actual data + rely on to obtain the actual data length. - - - PQnparams - - PQnparams - - + + PQnparamsPQnparams @@ -3786,19 +3720,14 @@ int PQnparams(const PGresult *res); This function is only useful when inspecting the result of - PQdescribePrepared. For other types of queries it + . For other types of queries it will return zero. - - - PQparamtype - - PQparamtype - - + + PQparamtypePQparamtype @@ -3811,19 +3740,14 @@ Oid PQparamtype(const PGresult *res, int param_number); This function is only useful when inspecting the result of - PQdescribePrepared. For other types of queries it + . For other types of queries it will return zero. - - - PQprint - - PQprint - - + + PQprintPQprint @@ -3868,13 +3792,8 @@ typedef struct - - - PQcmdStatus - - PQcmdStatus - - + + PQcmdStatusPQcmdStatus @@ -3890,18 +3809,13 @@ char *PQcmdStatus(PGresult *res); additional data such as the number of rows processed. The caller should not free the result directly. It will be freed when the associated PGresult handle is passed to - PQclear. + . - - - PQcmdTuples - - PQcmdTuples - - + + PQcmdTuplesPQcmdTuples @@ -3917,27 +3831,20 @@ char *PQcmdTuples(PGresult *res); PGresult. This function can only be used following the execution of a SELECT, CREATE TABLE AS, INSERT, UPDATE, DELETE, - MERGE, MOVE, FETCH, - or COPY statement, or an EXECUTE of a - prepared query that contains an INSERT, - UPDATE, DELETE - or MERGE statement. + MOVE, FETCH, or COPY statement, + or an EXECUTE of a prepared query that contains an + INSERT, UPDATE, or DELETE statement. If the command that generated the PGresult was anything - else, PQcmdTuples returns an empty string. The caller + else, returns an empty string. The caller should not free the return value directly. It will be freed when the associated PGresult handle is passed to - PQclear. + . - - - PQoidValue - - PQoidValue - - + + PQoidValuePQoidValue @@ -3956,20 +3863,15 @@ Oid PQoidValue(const PGresult *res); - - - PQoidStatus - - PQoidStatus - - + + PQoidStatusPQoidStatus This function is deprecated in favor of - PQoidValue and is not thread-safe. + and is not thread-safe. It returns a string with the OID of the inserted row, while - PQoidValue returns the OID value. + returns the OID value. char *PQoidStatus(const PGresult *res); @@ -3990,13 +3892,8 @@ char *PQoidStatus(const PGresult *res); - - - PQescapeLiteral - - PQescapeLiteral - - + + PQescapeLiteralPQescapeLiteral @@ -4006,23 +3903,23 @@ char *PQescapeLiteral(PGconn *conn, const char *str, size_t length); - PQescapeLiteral escapes a string for + escapes a string for use within an SQL command. This is useful when inserting data values as literal constants in SQL commands. Certain characters (such as quotes and backslashes) must be escaped to prevent them from being interpreted specially by the SQL parser. - PQescapeLiteral performs this operation. + performs this operation. - PQescapeLiteral returns an escaped version of the + returns an escaped version of the str parameter in memory allocated with malloc(). This memory should be freed using PQfreemem() when the result is no longer needed. A terminating zero byte is not required, and should not be counted in length. (If a terminating zero byte is found before length bytes are processed, - PQescapeLiteral stops at the zero; the behavior is + stops at the zero; the behavior is thus rather like strncpy.) The return string has all special characters replaced so that they can be properly processed by the PostgreSQL @@ -4032,7 +3929,7 @@ char *PQescapeLiteral(PGconn *conn, const char *str, size_t length); - On error, PQescapeLiteral returns NULL and a suitable + On error, returns NULL and a suitable message is stored in the conn object. @@ -4047,20 +3944,15 @@ char *PQescapeLiteral(PGconn *conn, const char *str, size_t length); - Note that it is not necessary nor correct to do escaping when a data - value is passed as a separate parameter in PQexecParams or + Note that it is neither necessary nor correct to do escaping when a data + value is passed as a separate parameter in or its sibling routines. - - - PQescapeIdentifier - - PQescapeIdentifier - - + + PQescapeIdentifierPQescapeIdentifier @@ -4070,7 +3962,7 @@ char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); - PQescapeIdentifier escapes a string for + escapes a string for use as an SQL identifier, such as a table, column, or function name. This is useful when a user-supplied identifier might contain special characters that would otherwise not be interpreted as part @@ -4079,14 +3971,14 @@ char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); - PQescapeIdentifier returns a version of the + returns a version of the str parameter escaped as an SQL identifier in memory allocated with malloc(). This memory must be freed using PQfreemem() when the result is no longer needed. A terminating zero byte is not required, and should not be counted in length. (If a terminating zero byte is found before length bytes are processed, - PQescapeIdentifier stops at the zero; the behavior is + stops at the zero; the behavior is thus rather like strncpy.) The return string has all special characters replaced so that it will be properly processed as an SQL identifier. A terminating zero byte @@ -4095,7 +3987,7 @@ char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); - On error, PQescapeIdentifier returns NULL and a suitable + On error, returns NULL and a suitable message is stored in the conn object. @@ -4109,13 +4001,8 @@ char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); - - - PQescapeStringConn - - PQescapeStringConn - - + + PQescapeStringConnPQescapeStringConn @@ -4127,10 +4014,10 @@ size_t PQescapeStringConn(PGconn *conn, - PQescapeStringConn escapes string literals, much like - PQescapeLiteral. Unlike PQescapeLiteral, + escapes string literals, much like + . Unlike , the caller is responsible for providing an appropriately sized buffer. - Furthermore, PQescapeStringConn does not generate the + Furthermore, does not generate the single quotes that must surround PostgreSQL string literals; they should be provided in the SQL command that the result is inserted into. The parameter from points to @@ -4139,7 +4026,7 @@ size_t PQescapeStringConn(PGconn *conn, string. A terminating zero byte is not required, and should not be counted in length. (If a terminating zero byte is found before length bytes are processed, - PQescapeStringConn stops at the zero; the behavior is + stops at the zero; the behavior is thus rather like strncpy.) to shall point to a buffer that is able to hold at least one more byte than twice the value of length, otherwise the behavior is undefined. @@ -4158,32 +4045,27 @@ size_t PQescapeStringConn(PGconn *conn, - PQescapeStringConn returns the number of bytes written + returns the number of bytes written to to, not including the terminating zero byte. - - - PQescapeString - - PQescapeString - - + + PQescapeStringPQescapeString - PQescapeString is an older, deprecated version of - PQescapeStringConn. + is an older, deprecated version of + . size_t PQescapeString (char *to, const char *from, size_t length); - The only difference from PQescapeStringConn is that - PQescapeString does not take PGconn + The only difference from is that + does not take PGconn or error parameters. Because of this, it cannot adjust its behavior depending on the connection properties (such as character encoding) and therefore @@ -4192,28 +4074,23 @@ size_t PQescapeString (char *to, const char *from, size_t length); - PQescapeString can be used safely in + can be used safely in client programs that work with only one PostgreSQL connection at a time (in this case it can find out what it needs to know behind the scenes). In other contexts it is a security hazard and should be avoided in favor of - PQescapeStringConn. + . - - - PQescapeByteaConn - - PQescapeByteaConn - - + + PQescapeByteaConnPQescapeByteaConn Escapes binary data for use within an SQL command with the type - bytea. As with PQescapeStringConn, + bytea. As with , this is only used when inserting data directly into an SQL command string. unsigned char *PQescapeByteaConn(PGconn *conn, @@ -4226,7 +4103,7 @@ unsigned char *PQescapeByteaConn(PGconn *conn, Certain byte values must be escaped when used as part of a bytea literal in an SQL statement. - PQescapeByteaConn escapes bytes using + escapes bytes using either hex encoding or backslash escaping. See for more information. @@ -4243,7 +4120,7 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - PQescapeByteaConn returns an escaped version of the + returns an escaped version of the from parameter binary string in memory allocated with malloc(). This memory should be freed using PQfreemem() when the result is no longer needed. The @@ -4263,18 +4140,13 @@ unsigned char *PQescapeByteaConn(PGconn *conn, - - - PQescapeBytea - - PQescapeBytea - - + + PQescapeByteaPQescapeBytea - PQescapeBytea is an older, deprecated version of - PQescapeByteaConn. + is an older, deprecated version of + . unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, @@ -4283,31 +4155,26 @@ unsigned char *PQescapeBytea(const unsigned char *from, - The only difference from PQescapeByteaConn is that - PQescapeBytea does not take a PGconn - parameter. Because of this, PQescapeBytea can + The only difference from is that + does not take a PGconn + parameter. Because of this, can only be used safely in client programs that use a single PostgreSQL connection at a time (in this case it can find out what it needs to know behind the scenes). It might give the wrong results if used in programs that use multiple database connections (use - PQescapeByteaConn in such cases). + in such cases). - - - PQunescapeBytea - - PQunescapeBytea - - + + PQunescapeByteaPQunescapeBytea Converts a string representation of binary data into binary data - — the reverse of PQescapeBytea. This + — the reverse of . This is needed when retrieving bytea data in text format, but not when retrieving it in binary format. @@ -4318,19 +4185,19 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); The from parameter points to a string - such as might be returned by PQgetvalue when applied - to a bytea column. PQunescapeBytea + such as might be returned by when applied + to a bytea column. converts this string representation into its binary representation. It returns a pointer to a buffer allocated with malloc(), or NULL on error, and puts the size of the buffer in to_length. The result must be - freed using PQfreemem when it is no longer needed. + freed using when it is no longer needed. This conversion is not exactly the inverse of - PQescapeBytea, because the string is not expected - to be escaped when received from PQgetvalue. + , because the string is not expected + to be escaped when received from . In particular this means there is no need for string quoting considerations, and so no need for a PGconn parameter. @@ -4350,14 +4217,14 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - The PQexec function is adequate for submitting + The function is adequate for submitting commands in normal, synchronous applications. It has a few deficiencies, however, that can be of importance to some users: - PQexec waits for the command to be completed. + waits for the command to be completed. The application might have other work to do (such as maintaining a user interface), in which case it won't want to block waiting for the response. @@ -4375,17 +4242,17 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); - PQexec can return only one + can return only one PGresult structure. If the submitted command string contains multiple SQL commands, all but the last PGresult are discarded by - PQexec. + . - PQexec always collects the command's entire result, + always collects the command's entire result, buffering it in a single PGresult. While this simplifies error-handling logic for the application, it can be impractical for results containing many rows. @@ -4396,58 +4263,48 @@ unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); Applications that do not like these limitations can instead use the - underlying functions that PQexec is built from: - PQsendQuery and PQgetResult. + underlying functions that is built from: + and . There are also - PQsendQueryParams, - PQsendPrepare, - PQsendQueryPrepared, - PQsendDescribePrepared, and - PQsendDescribePortal, - which can be used with PQgetResult to duplicate + , + , + , + , and + , + which can be used with to duplicate the functionality of - PQexecParams, - PQprepare, - PQexecPrepared, - PQdescribePrepared, and - PQdescribePortal + , + , + , + , and + respectively. - - - PQsendQuery - - PQsendQuery - - + + PQsendQueryPQsendQuery Submits a command to the server without waiting for the result(s). 1 is returned if the command was successfully dispatched and 0 if - not (in which case, use PQerrorMessage to get more + not (in which case, use to get more information about the failure). int PQsendQuery(PGconn *conn, const char *command); - After successfully calling PQsendQuery, call - PQgetResult one or more times to obtain the - results. PQsendQuery cannot be called again - (on the same connection) until PQgetResult + After successfully calling , call + one or more times to obtain the + results. cannot be called again + (on the same connection) until has returned a null pointer, indicating that the command is done. - - - PQsendQueryParams - - PQsendQueryParams - - + + PQsendQueryParamsPQsendQueryParams @@ -4464,23 +4321,18 @@ int PQsendQueryParams(PGconn *conn, int resultFormat); - This is equivalent to PQsendQuery except that + This is equivalent to except that query parameters can be specified separately from the query string. The function's parameters are handled identically to - PQexecParams. Like - PQexecParams, it will not work on 2.0-protocol + . Like + , it will not work on 2.0-protocol connections, and it allows only one command in the query string. - - - PQsendPrepare - - PQsendPrepare - - + + PQsendPreparePQsendPrepare @@ -4494,25 +4346,20 @@ int PQsendPrepare(PGconn *conn, const Oid *paramTypes); - This is an asynchronous version of PQprepare: it + This is an asynchronous version of : it returns 1 if it was able to dispatch the request, and 0 if not. - After a successful call, call PQgetResult to + After a successful call, call to determine whether the server successfully created the prepared statement. The function's parameters are handled identically to - PQprepare. Like - PQprepare, it will not work on 2.0-protocol + . Like + , it will not work on 2.0-protocol connections. - - - PQsendQueryPrepared - - PQsendQueryPrepared - - + + PQsendQueryPreparedPQsendQueryPrepared @@ -4528,24 +4375,19 @@ int PQsendQueryPrepared(PGconn *conn, int resultFormat); - This is similar to PQsendQueryParams, but + This is similar to , but the command to be executed is specified by naming a previously-prepared statement, instead of giving a query string. The function's parameters are handled identically to - PQexecPrepared. Like - PQexecPrepared, it will not work on + . Like + , it will not work on 2.0-protocol connections. - - - PQsendDescribePrepared - - PQsendDescribePrepared - - + + PQsendDescribePreparedPQsendDescribePrepared @@ -4555,24 +4397,19 @@ int PQsendQueryPrepared(PGconn *conn, int PQsendDescribePrepared(PGconn *conn, const char *stmtName); - This is an asynchronous version of PQdescribePrepared: + This is an asynchronous version of : it returns 1 if it was able to dispatch the request, and 0 if not. - After a successful call, call PQgetResult to + After a successful call, call to obtain the results. The function's parameters are handled - identically to PQdescribePrepared. Like - PQdescribePrepared, it will not work on + identically to . Like + , it will not work on 2.0-protocol connections. - - - PQsendDescribePortal - - PQsendDescribePortal - - + + PQsendDescribePortalPQsendDescribePortal @@ -4582,34 +4419,29 @@ int PQsendDescribePrepared(PGconn *conn, const char *stmtName); int PQsendDescribePortal(PGconn *conn, const char *portalName); - This is an asynchronous version of PQdescribePortal: + This is an asynchronous version of : it returns 1 if it was able to dispatch the request, and 0 if not. - After a successful call, call PQgetResult to + After a successful call, call to obtain the results. The function's parameters are handled - identically to PQdescribePortal. Like - PQdescribePortal, it will not work on + identically to . Like + , it will not work on 2.0-protocol connections. - - - PQgetResult - - PQgetResult - - + + PQgetResultPQgetResult Waits for the next result from a prior - PQsendQuery, - PQsendQueryParams, - PQsendPrepare, - PQsendQueryPrepared, - PQsendDescribePrepared, or - PQsendDescribePortal + , + , + , + , + , or + call, and returns it. A null pointer is returned when the command is complete and there will be no more results. @@ -4619,24 +4451,24 @@ PGresult *PQgetResult(PGconn *conn); - PQgetResult must be called repeatedly until + must be called repeatedly until it returns a null pointer, indicating that the command is done. (If called when no command is active, - PQgetResult will just return a null pointer + will just return a null pointer at once.) Each non-null result from - PQgetResult should be processed using the + should be processed using the same PGresult accessor functions previously described. Don't forget to free each result object with - PQclear when done with it. Note that - PQgetResult will block only if a command is + when done with it. Note that + will block only if a command is active and the necessary response data has not yet been read by - PQconsumeInput. + . - Even when PQresultStatus indicates a fatal - error, PQgetResult should be called until it + Even when indicates a fatal + error, should be called until it returns a null pointer, to allow libpq to process the error information completely. @@ -4647,9 +4479,9 @@ PGresult *PQgetResult(PGconn *conn); - Using PQsendQuery and - PQgetResult solves one of - PQexec's problems: If a command string contains + Using and + solves one of + 's problems: If a command string contains multiple SQL commands, the results of those commands can be obtained individually. (This allows a simple form of overlapped processing, by the way: the client can be handling the results of one @@ -4659,24 +4491,20 @@ PGresult *PQgetResult(PGconn *conn); Another frequently-desired feature that can be obtained with - PQsendQuery and PQgetResult + and is retrieving large query results a row at a time. This is discussed in . - By itself, calling PQgetResult + By itself, calling will still cause the client to block until the server completes the next SQL command. This can be avoided by proper use of two more functions: - - - PQconsumeInput - - PQconsumeInput - + + PQconsumeInputPQconsumeInput @@ -4688,42 +4516,37 @@ int PQconsumeInput(PGconn *conn); - PQconsumeInput normally returns 1 indicating + normally returns 1 indicating no error, but returns 0 if there was some kind of - trouble (in which case PQerrorMessage can be + trouble (in which case can be consulted). Note that the result does not say whether any input data was actually collected. After calling - PQconsumeInput, the application can check - PQisBusy and/or + , the application can check + and/or PQnotifies to see if their state has changed. - PQconsumeInput can be called even if the + can be called even if the application is not prepared to deal with a result or notification just yet. The function will read available data and save it in a buffer, thereby causing a select() read-ready indication to go away. The application can thus use - PQconsumeInput to clear the + to clear the select() condition immediately, and then examine the results at leisure. - - - PQisBusy - - PQisBusy - - + + PQisBusyPQisBusy Returns 1 if a command is busy, that is, - PQgetResult would block waiting for input. - A 0 return indicates that PQgetResult can be + would block waiting for input. + A 0 return indicates that can be called with assurance of not blocking. int PQisBusy(PGconn *conn); @@ -4731,8 +4554,8 @@ int PQisBusy(PGconn *conn); - PQisBusy will not itself attempt to read data - from the server; therefore PQconsumeInput + will not itself attempt to read data + from the server; therefore must be invoked first, or the busy state will never end. @@ -4746,11 +4569,11 @@ int PQisBusy(PGconn *conn); all the conditions that it must respond to. One of the conditions will be input available from the server, which in terms of select() means readable data on the file - descriptor identified by PQsocket. When the main + descriptor identified by . When the main loop detects input ready, it should call - PQconsumeInput to read the input. It can then - call PQisBusy, followed by - PQgetResult if PQisBusy + to read the input. It can then + call , followed by + if returns false (0). It can also call PQnotifies to detect NOTIFY messages (see ). @@ -4758,12 +4581,12 @@ int PQisBusy(PGconn *conn); A client that uses - PQsendQuery/PQgetResult + / can also attempt to cancel a command that is still being processed by the server; see . But regardless of - the return value of PQcancel, the application + the return value of , the application must continue with the normal result-reading sequence using - PQgetResult. A successful cancellation will + . A successful cancellation will simply cause the command to terminate sooner than it would have otherwise. @@ -4780,13 +4603,8 @@ int PQisBusy(PGconn *conn); can be used. - - - PQsetnonblocking - - PQsetnonblocking - - + + PQsetnonblockingPQsetnonblocking @@ -4804,26 +4622,21 @@ int PQsetnonblocking(PGconn *conn, int arg); In the nonblocking state, calls to - PQsendQuery, PQputline, - PQputnbytes, PQputCopyData, - and PQendcopy will not block but instead return + , , + , , + and will not block but instead return an error if they need to be called again. - Note that PQexec does not honor nonblocking + Note that does not honor nonblocking mode; if it is called, it will act in blocking fashion anyway. - - - PQisnonblocking - - PQisnonblocking - - + + PQisnonblockingPQisnonblocking @@ -4840,13 +4653,8 @@ int PQisnonblocking(const PGconn *conn); - - - PQflush - - PQflush - - + + PQflushPQflush @@ -4866,23 +4674,23 @@ int PQflush(PGconn *conn); After sending any command or data on a nonblocking connection, call - PQflush. If it returns 1, wait for the socket + . If it returns 1, wait for the socket to become read- or write-ready. If it becomes write-ready, call - PQflush again. If it becomes read-ready, call - PQconsumeInput, then call - PQflush again. Repeat until - PQflush returns 0. (It is necessary to check for - read-ready and drain the input with PQconsumeInput, + again. If it becomes read-ready, call + , then call + again. Repeat until + returns 0. (It is necessary to check for + read-ready and drain the input with , because the server can block trying to send us data, e.g. NOTICE messages, and won't read our data until we read its.) Once - PQflush returns 0, wait for the socket to be + returns 0, wait for the socket to be read-ready and then read the response as described above. - Retrieving Query Results Row-By-Row + Retrieving Query Results Row-by-Row libpq @@ -4894,17 +4702,17 @@ int PQflush(PGconn *conn); entire result and returns it to the application as a single PGresult. This can be unworkable for commands that return a large number of rows. For such cases, applications can use - PQsendQuery and PQgetResult in + and in single-row mode. In this mode, the result row(s) are returned to the application one at a time, as they are received from the server. - To enter single-row mode, call PQsetSingleRowMode - immediately after a successful call of PQsendQuery + To enter single-row mode, call + immediately after a successful call of (or a sibling function). This mode selection is effective only for the - currently executing query. Then call PQgetResult + currently executing query. Then call repeatedly, until it returns null, as documented in . If the query returns any rows, they are returned as individual PGresult objects, which look like @@ -4914,22 +4722,17 @@ int PQflush(PGconn *conn); the query returns zero rows, a zero-row object with status PGRES_TUPLES_OK is returned; this is the signal that no more rows will arrive. (But note that it is still necessary to continue - calling PQgetResult until it returns null.) All of + calling until it returns null.) All of these PGresult objects will contain the same row description data (column names, types, etc) that an ordinary PGresult object for the query would have. - Each object should be freed with PQclear as usual. + Each object should be freed with as usual. - - - PQsetSingleRowMode - - PQsetSingleRowMode - - + + PQsetSingleRowModePQsetSingleRowMode @@ -4942,10 +4745,10 @@ int PQsetSingleRowMode(PGconn *conn); This function can only be called immediately after - PQsendQuery or one of its sibling functions, + or one of its sibling functions, before any other operation on the connection such as - PQconsumeInput or - PQgetResult. If called at the correct time, + or + . If called at the correct time, the function activates single-row mode for the current query and returns 1. Otherwise the mode stays unchanged and the function returns 0. In any case, the mode reverts to normal after @@ -4987,13 +4790,8 @@ int PQsetSingleRowMode(PGconn *conn); this section. - - - PQgetCancel - - PQgetCancel - - + + PQgetCancelPQgetCancel @@ -5005,48 +4803,38 @@ PGcancel *PQgetCancel(PGconn *conn); - PQgetCancel creates a + creates a PGcancelPGcancel object given a PGconn connection object. It will return NULL if the given conn is NULL or an invalid connection. The PGcancel object is an opaque structure that is not meant to be accessed directly by the - application; it can only be passed to PQcancel - or PQfreeCancel. + application; it can only be passed to + or . - - - PQfreeCancel - - PQfreeCancel - - + + PQfreeCancelPQfreeCancel - Frees a data structure created by PQgetCancel. + Frees a data structure created by . void PQfreeCancel(PGcancel *cancel); - PQfreeCancel frees a data object previously created - by PQgetCancel. + frees a data object previously created + by . - - - PQcancel - - PQcancel - - + + PQcancelPQcancel @@ -5074,10 +4862,10 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - PQcancel can safely be invoked from a signal + can safely be invoked from a signal handler, if the errbuf is a local variable in the signal handler. The PGcancel object is read-only - as far as PQcancel is concerned, so it can + as far as is concerned, so it can also be invoked from a thread that is separate from the one manipulating the PGconn object. @@ -5086,18 +4874,13 @@ int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - - - PQrequestCancel - - PQrequestCancel - - + + PQrequestCancelPQrequestCancel - PQrequestCancel is a deprecated variant of - PQcancel. + is a deprecated variant of + . int PQrequestCancel(PGconn *conn); @@ -5108,7 +4891,7 @@ int PQrequestCancel(PGconn *conn); command. It operates directly on the PGconn object, and in case of failure stores the error message in the PGconn object (whence it can - be retrieved by PQerrorMessage). Although + be retrieved by ). Although the functionality is the same, this approach creates hazards for multiple-thread programs and signal handlers, since it is possible that overwriting the PGconn's error message will @@ -5144,7 +4927,7 @@ int PQrequestCancel(PGconn *conn); - The function PQfnPQfn + The function PQfnPQfn requests execution of a server function via the fast-path interface: PGresult *PQfn(PGconn *conn, @@ -5204,7 +4987,7 @@ typedef struct PGresult pointer. The result status should be checked before the result is used. The caller is responsible for freeing the PGresult with - PQclear when it is no longer needed. + when it is no longer needed. @@ -5240,7 +5023,7 @@ typedef struct and NOTIFY commands as ordinary SQL commands. The arrival of NOTIFY messages can subsequently be detected by calling - PQnotifies.PQnotifies + PQnotifies.PQnotifies @@ -5263,7 +5046,7 @@ typedef struct pgNotify After processing a PGnotify object returned by PQnotifies, be sure to free it with - PQfreemem. It is sufficient to free the + . It is sufficient to free the PGnotify pointer; the relname and extra fields do not represent separate allocations. (The names of these fields @@ -5279,28 +5062,28 @@ typedef struct pgNotify PQnotifies does not actually read data from the server; it just returns messages previously absorbed by another - libpq function. In prior releases of + libpq function. In ancient releases of libpq, the only way to ensure timely receipt of NOTIFY messages was to constantly submit commands, even empty ones, and then check PQnotifies after each - PQexec. While this still works, it is deprecated + . While this still works, it is deprecated as a waste of processing power. A better way to check for NOTIFY messages when you have no useful commands to execute is to call - PQconsumeInput, then check + , then check PQnotifies. You can use select() to wait for data to arrive from the server, thereby using no CPU power unless there is - something to do. (See PQsocket to obtain the file + something to do. (See to obtain the file descriptor number to use with select().) Note that this will work OK whether you submit commands with - PQsendQuery/PQgetResult or - simply use PQexec. You should, however, remember + / or + simply use . You should, however, remember to check PQnotifies after each - PQgetResult or PQexec, to + or , to see if any notifications came in during the processing of the command. @@ -5324,7 +5107,7 @@ typedef struct pgNotify The overall process is that the application first issues the SQL - COPY command via PQexec or one + COPY command via or one of the equivalent functions. The response to this (if there is no error in the command) will be a PGresult object bearing a status code of PGRES_COPY_OUT or @@ -5336,26 +5119,26 @@ typedef struct pgNotify PGRES_COMMAND_OK for success or PGRES_FATAL_ERROR if some problem was encountered. At this point further SQL commands can be issued via - PQexec. (It is not possible to execute other SQL + . (It is not possible to execute other SQL commands using the same connection while the COPY operation is in progress.) If a COPY command is issued via - PQexec in a string that could contain additional + in a string that could contain additional commands, the application must continue fetching results via - PQgetResult after completing the COPY - sequence. Only when PQgetResult returns - NULL is it certain that the PQexec + after completing the COPY + sequence. Only when returns + NULL is it certain that the command string is done and it is safe to issue more commands. The functions of this section should be executed only after obtaining a result status of PGRES_COPY_OUT or - PGRES_COPY_IN from PQexec or - PQgetResult. + PGRES_COPY_IN from or + . @@ -5365,14 +5148,9 @@ typedef struct pgNotify that are also used in connection with query results: - - - PQnfields - - PQnfields - with COPY - - + + PQnfieldsPQnfieldswith COPY @@ -5381,14 +5159,9 @@ typedef struct pgNotify - - - PQbinaryTuples - - PQbinaryTuples - with COPY - - + + PQbinaryTuplesPQbinaryTupleswith COPY @@ -5400,14 +5173,9 @@ typedef struct pgNotify - - - PQfformat - - PQfformat - with COPY - - + + PQfformatPQfformatwith COPY @@ -5441,13 +5209,8 @@ typedef struct pgNotify - - - PQputCopyData - - PQputCopyData - - + + PQputCopyDataPQputCopyData @@ -5465,7 +5228,7 @@ int PQputCopyData(PGconn *conn, The result is 1 if the data was queued, zero if it was not queued because of full buffers (this will only happen in nonblocking mode), or -1 if an error occurred. - (Use PQerrorMessage to retrieve details if + (Use to retrieve details if the return value is -1. If the value is zero, wait for write-ready and try again.) @@ -5480,13 +5243,8 @@ int PQputCopyData(PGconn *conn, - - - PQputCopyEnd - - PQputCopyEnd - - + + PQputCopyEndPQputCopyEnd @@ -5515,18 +5273,18 @@ int PQputCopyEnd(PGconn *conn, nonblocking mode, this may only indicate that the termination message was successfully queued. (In nonblocking mode, to be certain that the data has been sent, you should next wait for - write-ready and call PQflush, repeating until it + write-ready and call , repeating until it returns zero.) Zero indicates that the function could not queue the termination message because of full buffers; this will only happen in nonblocking mode. (In this case, wait for - write-ready and try the PQputCopyEnd call + write-ready and try the call again.) If a hard error occurs, -1 is returned; you can use - PQerrorMessage to retrieve details. + to retrieve details. - After successfully calling PQputCopyEnd, call - PQgetResult to obtain the final result status of the + After successfully calling , call + to obtain the final result status of the COPY command. One can wait for this result to be available in the usual way. Then return to normal operation. @@ -5546,13 +5304,8 @@ int PQputCopyEnd(PGconn *conn, - - - PQgetCopyData - - PQgetCopyData - - + + PQgetCopyDataPQgetCopyData @@ -5573,7 +5326,7 @@ int PQgetCopyData(PGconn *conn, be non-NULL. *buffer is set to point to the allocated memory, or to NULL in cases where no buffer is returned. A non-NULL result - buffer should be freed using PQfreemem when no longer + buffer should be freed using when no longer needed. @@ -5586,23 +5339,23 @@ int PQgetCopyData(PGconn *conn, progress, but no row is yet available (this is only possible when async is true). A result of -1 indicates that the COPY is done. A result of -2 indicates that an - error occurred (consult PQerrorMessage for the reason). + error occurred (consult for the reason). When async is true (not zero), - PQgetCopyData will not block waiting for input; it + will not block waiting for input; it will return zero if the COPY is still in progress but no complete row is available. (In this case wait for read-ready - and then call PQconsumeInput before calling - PQgetCopyData again.) When async is - false (zero), PQgetCopyData will block until data is + and then call before calling + again.) When async is + false (zero), will block until data is available or the operation completes. - After PQgetCopyData returns -1, call - PQgetResult to obtain the final result status of the + After returns -1, call + to obtain the final result status of the COPY command. One can wait for this result to be available in the usual way. Then return to normal operation. @@ -5623,13 +5376,8 @@ int PQgetCopyData(PGconn *conn, - - - PQgetline - - PQgetline - - + + PQgetlinePQgetline @@ -5645,7 +5393,7 @@ int PQgetline(PGconn *conn, This function copies up to length-1 characters into the buffer and converts the terminating newline into a zero byte. - PQgetline returns EOF at the + returns EOF at the end of input, 0 if the entire line has been read, and 1 if the buffer is full but the terminating newline has not yet been read. @@ -5662,13 +5410,8 @@ int PQgetline(PGconn *conn, - - - PQgetlineAsync - - PQgetlineAsync - - + + PQgetlineAsyncPQgetlineAsync @@ -5682,28 +5425,28 @@ int PQgetlineAsync(PGconn *conn, - This function is similar to PQgetline, but it can be used + This function is similar to , but it can be used by applications that must read COPY data asynchronously, that is, without blocking. Having issued the COPY command and gotten a PGRES_COPY_OUT response, the - application should call PQconsumeInput and - PQgetlineAsync until the + application should call and + until the end-of-data signal is detected. - Unlike PQgetline, this function takes + Unlike , this function takes responsibility for detecting end-of-data. - On each call, PQgetlineAsync will return data if a + On each call, will return data if a complete data row is available in libpq's input buffer. Otherwise, no data is returned until the rest of the row arrives. The function returns -1 if the end-of-copy-data marker has been recognized, or 0 if no data is available, or a positive number giving the number of bytes of data returned. If -1 is returned, the caller must next call - PQendcopy, and then return to normal processing. + , and then return to normal processing. @@ -5721,13 +5464,8 @@ int PQgetlineAsync(PGconn *conn, - - - PQputline - - PQputline - - + + PQputlinePQputline @@ -5741,10 +5479,10 @@ int PQputline(PGconn *conn, The COPY data stream sent by a series of calls - to PQputline has the same format as that - returned by PQgetlineAsync, except that + to has the same format as that + returned by , except that applications are not obliged to send exactly one data row per - PQputline call; it is okay to send a partial + call; it is okay to send a partial line or multiple lines per call. @@ -5755,20 +5493,15 @@ int PQputline(PGconn *conn, \. as a final line to indicate to the server that it had finished sending COPY data. While this still works, it is deprecated and the special meaning of \. can be expected to be removed in a - future release. It is sufficient to call PQendcopy after + future release. It is sufficient to call after having sent the actual data. - - - PQputnbytes - - PQputnbytes - - + + PQputnbytesPQputnbytes @@ -5782,20 +5515,15 @@ int PQputnbytes(PGconn *conn, - This is exactly like PQputline, except that the data + This is exactly like , except that the data buffer need not be null-terminated since the number of bytes to send is specified directly. Use this procedure when sending binary data. - - - PQendcopy - - PQendcopy - - + + PQendcopyPQendcopy @@ -5805,35 +5533,35 @@ int PQendcopy(PGconn *conn); This function waits until the server has finished the copying. It should either be issued when the last string has been sent - to the server using PQputline or when the + to the server using or when the last string has been received from the server using - PGgetline. It must be issued or the server + PQgetline. It must be issued or the server will get out of sync with the client. Upon return from this function, the server is ready to receive the next SQL command. The return value is 0 on successful completion, - nonzero otherwise. (Use PQerrorMessage to + nonzero otherwise. (Use to retrieve details if the return value is nonzero.) - When using PQgetResult, the application should + When using , the application should respond to a PGRES_COPY_OUT result by executing - PQgetline repeatedly, followed by - PQendcopy after the terminator line is seen. - It should then return to the PQgetResult loop - until PQgetResult returns a null pointer. + repeatedly, followed by + after the terminator line is seen. + It should then return to the loop + until returns a null pointer. Similarly a PGRES_COPY_IN result is processed - by a series of PQputline calls followed by - PQendcopy, then return to the - PQgetResult loop. This arrangement will + by a series of calls followed by + , then return to the + loop. This arrangement will ensure that a COPY command embedded in a series of SQL commands will be executed correctly. Older applications are likely to submit a COPY - via PQexec and assume that the transaction - is done after PQendcopy. This will work + via and assume that the transaction + is done after . This will work correctly only if the COPY is the only SQL command in the command string. @@ -5854,13 +5582,8 @@ int PQendcopy(PGconn *conn); - - - PQclientEncoding - - PQclientEncoding - - + + PQclientEncodingPQclientEncoding @@ -5881,13 +5604,8 @@ char *pg_encoding_to_char(int encoding_id); - - - PQsetClientEncoding - - PQsetClientEncoding - - + + PQsetClientEncodingPQsetClientEncoding @@ -5900,62 +5618,61 @@ int PQsetClientEncoding(PGconn *conn, const char *encoding is the encoding you want to use. If the function successfully sets the encoding, it returns 0, otherwise -1. The current encoding for this connection can be - determined by using PQclientEncoding. + determined by using . - - - PQsetErrorVerbosity - - PQsetErrorVerbosity - - + + PQsetErrorVerbosityPQsetErrorVerbosity Determines the verbosity of messages returned by - PQerrorMessage and PQresultErrorMessage. + and . typedef enum { PQERRORS_TERSE, PQERRORS_DEFAULT, - PQERRORS_VERBOSE + PQERRORS_VERBOSE, + PQERRORS_SQLSTATE } PGVerbosity; PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); - PQsetErrorVerbosity sets the verbosity mode, returning - the connection's previous setting. In TERSE mode, - returned messages include severity, primary text, and position only; - this will normally fit on a single line. The default mode produces - messages that include the above plus any detail, hint, or context - fields (these might span multiple lines). The VERBOSE - mode includes all available fields. Changing the verbosity does not - affect the messages available from already-existing - PGresult objects, only subsequently-created ones. - (But see PQresultVerboseErrorMessage if you + sets the verbosity mode, + returning the connection's previous setting. + In TERSE mode, returned messages include + severity, primary text, and position only; this will normally fit on a + single line. The DEFAULT mode produces messages + that include the above plus any detail, hint, or context fields (these + might span multiple lines). The VERBOSE mode + includes all available fields. The SQLSTATE + mode includes only the error severity and the SQLSTATE + error code, if one is available (if not, the output is like + TERSE mode). + + + + Changing the verbosity setting does not affect the messages available + from already-existing PGresult objects, only + subsequently-created ones. + (But see if you want to print a previous error with a different verbosity.) - - - PQsetErrorContextVisibility - - PQsetErrorContextVisibility - - + + PQsetErrorContextVisibilityPQsetErrorContextVisibility Determines the handling of CONTEXT fields in messages - returned by PQerrorMessage - and PQresultErrorMessage. + returned by + and . typedef enum { @@ -5967,31 +5684,32 @@ typedef enum PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context); - PQsetErrorContextVisibility sets the context display mode, + sets the context display mode, returning the connection's previous setting. This mode controls - whether the CONTEXT field is included in messages - (unless the verbosity setting is TERSE, in which - case CONTEXT is never shown). The NEVER mode + whether the CONTEXT field is included in messages. + The NEVER mode never includes CONTEXT, while ALWAYS always includes it if available. In ERRORS mode (the - default), CONTEXT fields are included only for error - messages, not for notices and warnings. Changing this mode does not + default), CONTEXT fields are included only in error + messages, not in notices and warnings. + (However, if the verbosity setting is TERSE + or SQLSTATE, CONTEXT fields + are omitted regardless of the context display mode.) + + + + Changing this mode does not affect the messages available from already-existing PGresult objects, only subsequently-created ones. - (But see PQresultVerboseErrorMessage if you + (But see if you want to print a previous error with a different display mode.) - - - PQtrace - - PQtrace - - + + PQtracePQtrace @@ -6015,17 +5733,12 @@ void PQtrace(PGconn *conn, FILE *stream); - - - PQuntrace - - PQuntrace - - + + PQuntracePQuntrace - Disables tracing started by PQtrace. + Disables tracing started by . void PQuntrace(PGconn *conn); @@ -6044,13 +5757,8 @@ void PQuntrace(PGconn *conn); - - - PQfreemem - - PQfreemem - - + + PQfreememPQfreemem @@ -6062,9 +5770,9 @@ void PQfreemem(void *ptr); Frees memory allocated by libpq, particularly - PQescapeByteaConn, - PQescapeBytea, - PQunescapeBytea, + , + , + , and PQnotifies. It is particularly important that this function, rather than free(), be used on Microsoft Windows. This is because @@ -6077,37 +5785,27 @@ void PQfreemem(void *ptr); - - - PQconninfoFree - - PQconninfoFree - - + + PQconninfoFreePQconninfoFree Frees the data structures allocated by - PQconndefaults or PQconninfoParse. + or . void PQconninfoFree(PQconninfoOption *connOptions); - A simple PQfreemem will not do for this, since + A simple will not do for this, since the array contains references to subsidiary strings. - - - PQencryptPasswordConn - - PQencryptPasswordConn - - + + PQencryptPasswordConnPQencryptPasswordConn @@ -6140,14 +5838,14 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, is busy executing another query. If you wish to use the default algorithm for the server but want to avoid blocking, query password_encryption yourself before calling - PQencryptPasswordConn, and pass that value as the + , and pass that value as the algorithm. The return value is a string allocated by malloc. The caller can assume the string doesn't contain any special characters - that would require escaping. Use PQfreemem to free the + that would require escaping. Use to free the result when done with it. On error, returns NULL, and a suitable message is stored in the connection object. @@ -6155,13 +5853,8 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, - - - PQencryptPassword - - PQencryptPassword - - + + PQencryptPasswordPQencryptPassword @@ -6169,22 +5862,17 @@ char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, char *PQencryptPassword(const char *passwd, const char *user); - PQencryptPassword is an older, deprecated version of - PQencryptPasswodConn. The difference is that - PQencryptPassword does not + is an older, deprecated version of + . The difference is that + does not require a connection object, and md5 is always used as the encryption algorithm. - - - PQmakeEmptyPGresult - - PQmakeEmptyPGresult - - + + PQmakeEmptyPGresultPQmakeEmptyPGresult @@ -6207,21 +5895,16 @@ PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); registered in the connection are copied into the PGresult. (They do not get PGEVT_RESULTCREATE calls, but see - PQfireResultCreateEvents.) - Note that PQclear should eventually be called + .) + Note that should eventually be called on the object, just as with a PGresult returned by libpq itself. - - - PQfireResultCreateEvents - - PQfireResultCreateEvents - - + + PQfireResultCreateEventsPQfireResultCreateEvents Fires a PGEVT_RESULTCREATE event (see The main reason that this function is separate from - PQmakeEmptyPGresult is that it is often appropriate + is that it is often appropriate to create a PGresult and fill it with data before invoking the event procedures. - - - PQcopyResult - - PQcopyResult - - + + PQcopyResultPQcopyResult Makes a copy of a PGresult object. The copy is not linked to the source result in any way and - PQclear must be called when the copy is no longer + must be called when the copy is no longer needed. If the function fails, NULL is returned. @@ -6294,13 +5972,8 @@ PGresult *PQcopyResult(const PGresult *src, int flags); - - - PQsetResultAttrs - - PQsetResultAttrs - - + + PQsetResultAttrsPQsetResultAttrs @@ -6322,13 +5995,8 @@ int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); - - - PQsetvalue - - PQsetvalue - - + + PQsetvaluePQsetvalue @@ -6341,7 +6009,7 @@ int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); The function will automatically grow the result's internal tuples array as needed. However, the tup_num argument must be - less than or equal to PQntuples, meaning this + less than or equal to , meaning this function can only grow the tuples array one tuple at a time. But any field of any existing tuple can be modified in any order. If a value at field_num already exists, it will be overwritten. @@ -6356,13 +6024,8 @@ int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); - - - PQresultAlloc - - PQresultAlloc - - + + PQresultAllocPQresultAlloc @@ -6382,14 +6045,30 @@ void *PQresultAlloc(PGresult *res, size_t nBytes); - - - PQlibVersion - - PQlibVersion - PQserverVersion - - + + PQresultMemorySizePQresultMemorySize + + + + Retrieves the number of bytes allocated for + a PGresult object. + +size_t PQresultMemorySize(const PGresult *res); + + + + + This value is the sum of all malloc requests + associated with the PGresult object, that is, + all the space that will be freed by . + This information can be useful for managing memory consumption. + + + + + + PQlibVersionPQlibVersionPQserverVersion @@ -6404,7 +6083,7 @@ int PQlibVersion(void); run time, whether specific functionality is available in the currently loaded version of libpq. The function can be used, for example, to determine which connection options are available in - PQconnectdb. + . @@ -6418,14 +6097,14 @@ int PQlibVersion(void); Prior to major version 10, PostgreSQL used three-part version numbers in which the first two parts together represented the major version. For those - versions, PQlibVersion uses two digits for each + versions, uses two digits for each part; for example version 9.1.5 will be returned as 90105, and version 9.2.0 will be returned as 90200. Therefore, for purposes of determining feature compatibility, - applications should divide the result of PQlibVersion + applications should divide the result of by 100 not 10000 to determine a logical major version number. In all release series, only the last two digits differ between minor releases (bug-fix releases). @@ -6474,11 +6153,11 @@ int PQlibVersion(void); - The function PQsetNoticeReceiver + The function PQsetNoticeReceiver notice receiver PQsetNoticeReceiver sets or examines the current notice receiver for a connection object. - Similarly, PQsetNoticeProcessor + Similarly, PQsetNoticeProcessor notice processor PQsetNoticeProcessor sets or examines the current notice processor. @@ -6511,9 +6190,9 @@ PQsetNoticeProcessor(PGconn *conn, receiver function is called. It is passed the message in the form of a PGRES_NONFATAL_ERROR PGresult. (This allows the receiver to extract - individual fields using PQresultErrorField, or obtain a - complete preformatted message using PQresultErrorMessage - or PQresultVerboseErrorMessage.) The same + individual fields using , or obtain a + complete preformatted message using + or .) The same void pointer passed to PQsetNoticeReceiver is also passed. (This pointer can be used to access application-specific state if needed.) @@ -6521,7 +6200,7 @@ PQsetNoticeProcessor(PGconn *conn, The default notice receiver simply extracts the message (using - PQresultErrorMessage) and passes it to the notice + ) and passes it to the notice processor. @@ -6551,7 +6230,7 @@ defaultNoticeProcessor(void *arg, const char *message) from it exist. At creation of a PGresult, the PGconn's current notice handling pointers are copied into the PGresult for possible use by functions like - PQgetvalue. + . @@ -6581,9 +6260,9 @@ defaultNoticeProcessor(void *arg, const char *message) In addition there is an instance data pointer, which starts out NULL in every PGconn and PGresult. This pointer can be manipulated using the - PQinstanceData, - PQsetInstanceData, - PQresultInstanceData and + , + , + and PQsetResultInstanceData functions. Note that unlike the passthrough pointer, instance data of a PGconn is not automatically inherited by PGresults created from @@ -6608,7 +6287,7 @@ defaultNoticeProcessor(void *arg, const char *message) PGEVT_REGISTER - The register event occurs when PQregisterEventProc + The register event occurs when is called. It is the ideal time to initialize any instanceData an event procedure may need. Only one register event will be fired per event handler per connection. If the @@ -6626,7 +6305,7 @@ typedef struct PGEventRegister *. This structure contains a PGconn that should be in the CONNECTION_OK status; guaranteed if one calls - PQregisterEventProc right after obtaining a good + right after obtaining a good PGconn. When returning a failure code, all cleanup must be performed as no PGEVT_CONNDESTROY event will be sent. @@ -6639,7 +6318,7 @@ typedef struct The connection reset event is fired on completion of - PQreset or PQresetPoll. In + or PQresetPoll. In both cases, the event is only fired if the reset was successful. If the event procedure fails, the entire connection reset will fail; the PGconn is put into @@ -6672,7 +6351,7 @@ typedef struct The connection destroy event is fired in response to - PQfinish. It is the event procedure's + . It is the event procedure's responsibility to properly clean up its event data as libpq has no ability to manage this memory. Failure to clean up will lead to memory leaks. @@ -6687,9 +6366,9 @@ typedef struct When a PGEVT_CONNDESTROY event is received, the evtInfo pointer should be cast to a PGEventConnDestroy *. This event is fired - prior to PQfinish performing any other cleanup. + prior to performing any other cleanup. The return value of the event procedure is ignored since there is no - way of indicating a failure from PQfinish. Also, + way of indicating a failure from . Also, an event procedure failure should not abort the process of cleaning up unwanted memory. @@ -6702,7 +6381,7 @@ typedef struct The result creation event is fired in response to any query execution function that generates a result, including - PQgetResult. This event will only be fired after + . This event will only be fired after the result has been created successfully. @@ -6721,7 +6400,7 @@ typedef struct instanceData that needs to be associated with the result. If the event procedure fails, the result will be cleared and the failure will be propagated. The event procedure must not try to - PQclear the result object for itself. When returning a + the result object for itself. When returning a failure code, all cleanup must be performed as no PGEVT_RESULTDESTROY event will be sent. @@ -6733,7 +6412,7 @@ typedef struct The result copy event is fired in response to - PQcopyResult. This event will only be fired after + . This event will only be fired after the copy is complete. Only event procedures that have successfully handled the PGEVT_RESULTCREATE or PGEVT_RESULTCOPY event for the source result @@ -6768,7 +6447,7 @@ typedef struct The result destroy event is fired in response to a - PQclear. It is the event procedure's + . It is the event procedure's responsibility to properly clean up its event data as libpq has no ability to manage this memory. Failure to clean up will lead to memory leaks. @@ -6783,9 +6462,9 @@ typedef struct When a PGEVT_RESULTDESTROY event is received, the evtInfo pointer should be cast to a PGEventResultDestroy *. This event is fired - prior to PQclear performing any other cleanup. + prior to performing any other cleanup. The return value of the event procedure is ignored since there is no - way of indicating a failure from PQclear. Also, + way of indicating a failure from . Also, an event procedure failure should not abort the process of cleaning up unwanted memory. @@ -6798,13 +6477,8 @@ typedef struct Event Callback Procedure - - - PGEventProc - - PGEventProc - - + + PGEventProcPGEventProc @@ -6821,7 +6495,7 @@ int eventproc(PGEventId evtId, void *evtInfo, void *passThrough) evtInfo pointer must be cast to the appropriate structure type to obtain further information about the event. The passThrough parameter is the pointer - provided to PQregisterEventProc when the event + provided to when the event procedure was registered. The function should return a non-zero value if it succeeds and zero if it fails. @@ -6853,13 +6527,8 @@ int eventproc(PGEventId evtId, void *evtInfo, void *passThrough) Event Support Functions - - - PQregisterEventProc - - PQregisterEventProc - - + + PQregisterEventProcPQregisterEventProc @@ -6893,13 +6562,8 @@ int PQregisterEventProc(PGconn *conn, PGEventProc proc, - - - PQsetInstanceData - - PQsetInstanceData - - + + PQsetInstanceDataPQsetInstanceData Sets the connection conn's instanceData @@ -6915,13 +6579,8 @@ int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); - - - PQinstanceData - - PQinstanceData - - + + PQinstanceDataPQinstanceData Returns the @@ -6936,13 +6595,8 @@ void *PQinstanceData(const PGconn *conn, PGEventProc proc); - - - PQresultSetInstanceData - - PQresultSetInstanceData - - + + PQresultSetInstanceDataPQresultSetInstanceData Sets the result's instanceData @@ -6955,16 +6609,19 @@ void *PQinstanceData(const PGconn *conn, PGEventProc proc); int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data); + + + Beware that any storage represented by data + will not be accounted for by , + unless it is allocated using . + (Doing so is recommendable because it eliminates the need to free + such storage explicitly when the result is destroyed.) + - - - PQresultInstanceData - - PQresultInstanceData - - + + PQresultInstanceDataPQresultInstanceData Returns the result's instanceData associated with proc, or NULL @@ -7146,8 +6803,8 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) The following environment variables can be used to select default connection parameter values, which will be used by - PQconnectdb, PQsetdbLogin and - PQsetdb if no value is directly specified by the calling + , and + if no value is directly specified by the calling code. These are useful to avoid hard-coding database connection information into simple client applications, for example. @@ -7229,6 +6886,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGCHANNELBINDING + + PGCHANNELBINDING behaves the same as the connection parameter. + + + @@ -7354,6 +7021,16 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) + + + + PGGSSENCMODE + + PGGSSENCMODE behaves the same as the connection parameter. + + + @@ -7519,13 +7196,18 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough) used. (Therefore, put more-specific entries first when you are using wildcards.) If an entry needs to contain : or \, escape this character with \. - A host name of localhost matches both TCP (host name - localhost) and Unix domain socket (pghost empty - or the default socket directory) connections coming from the local - machine. In a standby server, a database name of replication + The host name field is matched to the host connection + parameter if that is specified, otherwise to + the hostaddr parameter if that is specified; if neither + are given then the host name localhost is searched for. + The host name localhost is also searched for when + the connection is a Unix-domain socket connection and + the host parameter + matches libpq's default socket directory path. + In a standby server, a database field of replication matches streaming replication connections made to the master server. - The database field is of limited usefulness because - users have the same password for all databases in the same cluster. + The database field is of limited usefulness otherwise, because users have + the same password for all databases in the same cluster. @@ -7874,7 +7556,7 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) - For a connection to be known secure, SSL usage must be configured + For a connection to be known SSL-secured, SSL usage must be configured on both the client and the server before the connection is made. If it is only configured on the server, the client may end up sending sensitive information (e.g. passwords) before @@ -8051,25 +7733,19 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*) If your application initializes libssl and/or libcrypto libraries and libpq is built with SSL support, you should call - PQinitOpenSSL to tell libpq + to tell libpq that the libssl and/or libcrypto libraries have been initialized by your application, so that libpq will not also initialize those libraries. - See + url="http://h41379.www4.hpe.com/doc/83final/ba554_90007/ch04.html"> for details on the SSL API. - - - PQinitOpenSSL - - PQinitOpenSSL - - + + PQinitOpenSSLPQinitOpenSSL @@ -8084,7 +7760,7 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); will initialize the OpenSSL library before first opening a database connection. When do_crypto is non-zero, the libcrypto library will be initialized. By - default (if PQinitOpenSSL is not called), both libraries + default (if is not called), both libraries are initialized. When SSL support is not compiled in, this function is present but does nothing. @@ -8099,15 +7775,8 @@ void PQinitOpenSSL(int do_ssl, int do_crypto); - - - PQinitSSL - - PQinitSSL - - - - + + PQinitSSLPQinitSSL Allows applications to select which security libraries to initialize. @@ -8123,9 +7792,9 @@ void PQinitSSL(int do_ssl); - PQinitSSL has been present since - PostgreSQL 8.0, while PQinitOpenSSL - was added in PostgreSQL 8.4, so PQinitSSL + has been present since + PostgreSQL 8.0, while + was added in PostgreSQL 8.4, so might be preferable for applications that need to work with older versions of libpq. @@ -8158,13 +7827,8 @@ void PQinitSSL(int do_ssl); - - - PQisthreadsafe - - PQisthreadsafe - - + + PQisthreadsafePQisthreadsafe @@ -8201,12 +7865,12 @@ int PQisthreadsafe(); - The deprecated functions PQrequestCancel and - PQoidStatus are not thread-safe and should not be - used in multithread programs. PQrequestCancel - can be replaced by PQcancel. - PQoidStatus can be replaced by - PQoidValue. + The deprecated functions and + are not thread-safe and should not be + used in multithread programs. + can be replaced by . + can be replaced by + . @@ -8435,10 +8099,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); @@ -8605,10 +8269,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); @@ -8668,6 +8332,7 @@ main(int argc, char **argv) notify->relname, notify->be_pid); PQfreemem(notify); nnotifies++; + PQconsumeInput(conn); } } @@ -8699,9 +8364,10 @@ main(int argc, char **argv) * * CREATE SCHEMA testlibpq3; * SET search_path = testlibpq3; + * SET standard_conforming_strings = ON; * CREATE TABLE test1 (i int4, t text, b bytea); - * INSERT INTO test1 values (1, 'joe''s place', '\\000\\001\\002\\003\\004'); - * INSERT INTO test1 values (2, 'ho there', '\\004\\003\\002\\001\\000'); + * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); + * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); * * The expected output is: * @@ -8831,7 +8497,7 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SET search_path = testlibpq3"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { diff --git a/doc/src/sgml/limits.sgml b/doc/src/sgml/limits.sgml new file mode 100644 index 00000000000..7713ff71773 --- /dev/null +++ b/doc/src/sgml/limits.sgml @@ -0,0 +1,120 @@ + + + + <productname>PostgreSQL</productname> Limits + + + describes various hard limits of + PostgreSQL. However, practical limits, such as + performance limitations or available disk space may apply before absolute + hard limits are reached. + + + + <productname>PostgreSQL</productname> Limitations + + + + Item + Upper Limit + Comment + + + + + + database size + unlimited + + + + + number of databases + + 4,294,950,911 + + + + + relations per database + + 1,431,650,303 + + + + + relation size + 32 TB + with the default BLCKSZ of 8192 bytes + + + + rows per table + limited by the number of tuples that can fit onto 4,294,967,295 pages + + + + + columns per table + 1600 + further limited by tuple size fitting on a single page; see note + below + + + + field size + 1 GB + + + + + identifier length + 63 bytes + can be increased by recompiling PostgreSQL + + + + indexes per table + unlimited + constrained by maximum relations per database + + + + columns per index + 32 + can be increased by recompiling PostgreSQL + + + + partition keys + 32 + can be increased by recompiling PostgreSQL + + + +
+ + + The maximum number of columns for a table is further reduced as the tuple + being stored must fit in a single 8192-byte heap page. For example, + excluding the tuple header, a tuple made up of 1600 int columns + would consume 6400 bytes and could be stored in a heap page, but a tuple of + 1600 bigint columns would consume 12800 bytes and would + therefore not fit inside a heap page. + Variable-length fields of + types such as text, varchar, and char + can have their values stored out of line in the table's TOAST table when the + values are large enough to require it. Only an 18-byte pointer must remain + inside the tuple in the table's heap. For shorter length variable-length + fields, either a 4-byte or 1-byte field header is used and the value is + stored inside the heap tuple. + + + + Columns that have been dropped from the table also contribute to the maximum + column limit. Moreover, although the dropped column values for newly + created tuples are internally marked as null in the tuple's null bitmap, the + null bitmap also occupies space. + +
diff --git a/doc/src/sgml/lo.sgml b/doc/src/sgml/lo.sgml index ab8d192bc15..cce37932ec6 100644 --- a/doc/src/sgml/lo.sgml +++ b/doc/src/sgml/lo.sgml @@ -70,7 +70,7 @@ CREATE TABLE image (title text, raster lo); CREATE TRIGGER t_raster BEFORE UPDATE OR DELETE ON image - FOR EACH ROW EXECUTE PROCEDURE lo_manage(raster); + FOR EACH ROW EXECUTE FUNCTION lo_manage(raster); diff --git a/doc/src/sgml/lobj.sgml b/doc/src/sgml/lobj.sgml index 771795ae668..d5ac362125c 100644 --- a/doc/src/sgml/lobj.sgml +++ b/doc/src/sgml/lobj.sgml @@ -121,7 +121,7 @@ If an error occurs while executing any one of these functions, the function will return an otherwise-impossible value, typically 0 or -1. A message describing the error is stored in the connection object and - can be retrieved with PQerrorMessage. + can be retrieved with . @@ -535,7 +535,7 @@ int lo_unlink(PGconn *conn, Oid lobjId); -Server-side Functions +Server-Side Functions Server-side functions tailored for manipulating large objects from SQL are @@ -543,7 +543,7 @@ int lo_unlink(PGconn *conn, Oid lobjId); - SQL-oriented Large Object Functions + SQL-Oriented Large Object Functions @@ -568,7 +568,7 @@ int lo_unlink(PGconn *conn, Oid lobjId); Create a large object and store data there, returning its OID. Pass 0 to have the system choose an OID. - lo_from_bytea(0, E'\\xffffff00') + lo_from_bytea(0, '\xffffff00') 24528 @@ -583,7 +583,7 @@ int lo_unlink(PGconn *conn, Oid lobjId); Write data at the given offset. - lo_put(24528, 1, E'\\xaa') + lo_put(24528, 1, '\xaa') @@ -704,7 +704,7 @@ SELECT lo_export(image.raster, '/tmp/motd') FROM image * testlo.c * test using large objects with libpq * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -933,10 +933,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml index 151e773fc2c..f657d1d06e0 100644 --- a/doc/src/sgml/logical-replication.sgml +++ b/doc/src/sgml/logical-replication.sgml @@ -64,6 +64,13 @@ + + + Replicating between PostgreSQL instances on different platforms (for + example Linux to Windows) + + + Giving access to replicated data to different groups of users. @@ -225,10 +232,15 @@ - Columns of a table are also matched by name. A different order of columns - in the target table is allowed, but the column types have to match. The - target table can have additional columns not provided by the published - table. Those will be filled with their default values. + Columns of a table are also matched by name. The order of columns in the + subscriber table does not need to match that of the publisher. The data + types of the columns do not need to match, as long as the text + representation of the data can be converted to the target type. For + example, you can replicate from a column of type integer to a + column of type bigint. The target table can also have + additional columns not provided by the published table. Any such columns + will be filled with the default value as specified in the definition of the + target table. @@ -364,6 +376,22 @@ + + + Replication of TRUNCATE commands is supported, but + some care must be taken when truncating groups of tables connected by + foreign keys. When replicating a truncate action, the subscriber will + truncate the same group of tables that was truncated on the publisher, + either explicitly specified or implicitly collected via + CASCADE, minus tables that are not part of the + subscription. This will work correctly if all affected tables are part + of the same subscription. But if some tables to be truncated on the + subscriber have foreign-key links to tables that are not part of the same + (or any) subscription, then the application of the truncate action on the + subscriber will fail. + + + Large objects (see ) are not replicated. @@ -477,7 +505,14 @@ The role used for the replication connection must have the REPLICATION attribute (or be a superuser). Access for the role must be - configured in pg_hba.conf. + configured in pg_hba.conf and it must have the + LOGIN attribute. + + + + In order to be able to copy the initial table data, the role used for the + replication connection must have the SELECT privilege on + a published table (or be a superuser). diff --git a/doc/src/sgml/logicaldecoding.sgml b/doc/src/sgml/logicaldecoding.sgml index b29cfe6fb40..8db968641ee 100644 --- a/doc/src/sgml/logicaldecoding.sgml +++ b/doc/src/sgml/logicaldecoding.sgml @@ -154,8 +154,8 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot'); an additional connection. -$ pg_recvlogical -d postgres --slot test --create-slot -$ pg_recvlogical -d postgres --slot test --start -f - +$ pg_recvlogical -d postgres --slot=test --create-slot +$ pg_recvlogical -d postgres --slot=test --start -f - ControlZ $ psql -d postgres -c "INSERT INTO data(data) VALUES('4');" $ fg @@ -163,7 +163,7 @@ BEGIN 693 table public.data: INSERT: id[integer]:4 data[text]:'4' COMMIT 693 ControlC -$ pg_recvlogical -d postgres --slot test --drop-slot +$ pg_recvlogical -d postgres --slot=test --drop-slot diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml index 98e0ca5c623..3ddd335b8c9 100644 --- a/doc/src/sgml/ltree.sgml +++ b/doc/src/sgml/ltree.sgml @@ -457,17 +457,17 @@ Europe & Russia*@ & !Transportation lca(ltree, ltree, ...)lca ltree - lowest common ancestor, i.e., longest common prefix of paths + longest common ancestor of paths (up to 8 arguments supported) - lca('1.2.2.3','1.2.3.4.5.6') + lca('1.2.3','1.2.3.4.5.6') 1.2 lca(ltree[]) ltree - lowest common ancestor, i.e., longest common prefix of paths - lca(array['1.2.2.3'::ltree,'1.2.3']) + longest common ancestor of paths in array + lca(array['1.2.3'::ltree,'1.2.3.4']) 1.2 diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 4a68ec3b404..ec8bdcd7a49 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -347,7 +347,7 @@ - Updating The Visibility Map + Updating the Visibility Map Vacuum maintains a visibility map for each @@ -825,6 +825,26 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu autovacuum_vacuum_cost_limit storage parameters have been set are not considered in the balancing algorithm. + + + Autovacuum workers generally don't block other commands. If a process + attempts to acquire a lock that conflicts with the + SHARE UPDATE EXCLUSIVE lock held by autovacuum, lock + acquisition will interrupt the autovacuum. For conflicting lock modes, + see . However, if the autovacuum + is running to prevent transaction ID wraparound (i.e., the autovacuum query + name in the pg_stat_activity view ends with + (to prevent wraparound)), the autovacuum is not + automatically interrupted. + + + + + Regularly running commands that acquire locks conflicting with a + SHARE UPDATE EXCLUSIVE lock (e.g., ANALYZE) can + effectively prevent autovacuums from ever completing. + + @@ -869,19 +889,10 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu can be used safely and easily in all cases. - But since the command requires an exclusive table lock, it is - often preferable to execute an index rebuild with a sequence of - creation and replacement steps. Index types that support - with the CONCURRENTLY - option can instead be recreated that way. If that is successful and the - resulting index is valid, the original index can then be replaced by - the newly built one using a combination of - and . When an index is used to enforce - uniqueness or other constraints, might - be necessary to swap the existing constraint with one enforced by - the new index. Review this alternate multistep rebuild approach - carefully before using it as there are limitations on which - indexes can be reindexed this way, and errors must be handled. + This command requires an ACCESS EXCLUSIVE lock by + default, hence it is often preferable to execute it with its + CONCURRENTLY option, which requires only a + SHARE UPDATE EXCLUSIVE lock. @@ -932,8 +943,8 @@ analyze threshold = analyze base threshold + analyze scale factor * number of tu program if you have one that you are already using with other server software. For example, the rotatelogs tool included in the Apache distribution - can be used with PostgreSQL. To do this, - just pipe the server's + can be used with PostgreSQL. One way to + do this is to pipe the server's stderr output to the desired program. If you start the server with pg_ctl, then stderr @@ -945,6 +956,36 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 + + You can combine these approaches by setting up logrotate + to collect log files produced by PostgreSQL built-in + logging collector. In this case, the logging collector defines the names and + location of the log files, while logrotate + periodically archives these files. When initiating log rotation, + logrotate must ensure that the application + sends further output to the new file. This is commonly done with a + postrotate script that sends a SIGHUP + signal to the application, which then reopens the log file. + In PostgreSQL, you can run pg_ctl + with the logrotate option instead. When the server receives + this command, the server either switches to a new log file or reopens the + existing file, depending on the logging configuration + (see ). + + + + + When using static log file names, the server might fail to reopen the log + file if the max open file limit is reached or a file table overflow occurs. + In this case, log messages are sent to the old log file until a + successful log rotation. If logrotate is + configured to compress the log file and delete it, the server may lose + the messages logged in this timeframe. To avoid this issue, you can + configure the logging collector to dynamically assign log file names + and use a prerotate script to ignore open log files. + + + Another production-grade approach to managing log output is to send it to syslog and let @@ -978,7 +1019,7 @@ pg_ctl start | rotatelogs /var/log/pgsql_log 86400 - pgBadger + pgBadger is an external project that does sophisticated log file analysis. check_postgres diff --git a/doc/src/sgml/mk_feature_tables.pl b/doc/src/sgml/mk_feature_tables.pl index 9b111b8b409..476e50e66d0 100644 --- a/doc/src/sgml/mk_feature_tables.pl +++ b/doc/src/sgml/mk_feature_tables.pl @@ -38,8 +38,8 @@ $is_supported eq $yesno || next; - $feature_name =~ s//>/g; + $feature_name =~ s//>/g; $subfeature_name =~ s//>/g; diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index c278076e68d..828e9084dd7 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -268,6 +268,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser stated above; instead they update continuously throughout the transaction. + + Some of the information in the dynamic statistics views shown in is security restricted. + Ordinary users can only see all the information about their own sessions + (sessions belonging to a role that they are a member of). In rows about + other sessions, many columns will be null. Note, however, that the + existence of a session and its general properties such as its sessions user + and database are visible to all users. Superusers and members of the + built-in role pg_read_all_stats (see also ) can see all the information about all sessions. + +
Dynamic Statistics Views @@ -324,6 +336,22 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + + pg_stat_gssapipg_stat_gssapi + One row per connection (regular and replication), showing information about + GSSAPI authentication and encryption used on this connection. + See for details. + + + + + pg_stat_progress_create_indexpg_stat_progress_create_index + One row for each backend running CREATE INDEX or REINDEX, showing + current progress. + See . + + + pg_stat_progress_vacuumpg_stat_progress_vacuum One row for each backend (including autovacuum worker processes) running @@ -332,6 +360,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser + + pg_stat_progress_clusterpg_stat_progress_cluster + One row for each backend running + CLUSTER or VACUUM FULL, showing current progress. + See . + + +
@@ -804,10 +840,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser text Type of current backend. Possible types are autovacuum launcher, autovacuum worker, - background worker, background writer, + logical replication launcher, + logical replication worker, + parallel worker, background writer, client backend, checkpointer, startup, walreceiver, walsender and walwriter. + In addition, background workers registered by extensions may have + additional types. @@ -1030,17 +1070,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser OldSnapshotTimeMapLock Waiting to read or update old snapshot control information. - - BackendRandomLock - Waiting to generate a random number. - LogicalRepWorkerLock Waiting for action on logical replication worker to finish. CLogTruncationLock - Waiting to truncate the write-ahead log or waiting for write-ahead log truncation to finish. + Waiting to execute txid_status or update + the oldest transaction id available to it. clog @@ -1108,6 +1145,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser predicate_lock_manager Waiting to add or examine predicate lock information. + + serializable_xact + Waiting to perform an operation on a serializable transaction + in a parallel query. + parallel_query_dsa Waiting for parallel query dynamic shared memory allocation lock. @@ -1193,14 +1235,14 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser CheckpointerMain Waiting in main loop of checkpointer process. - - LogicalLauncherMain - Waiting in main loop of logical launcher process. - LogicalApplyMain Waiting in main loop of logical apply process. + + LogicalLauncherMain + Waiting in main loop of logical launcher process. + PgStatMain Waiting in main loop of the statistics collector process. @@ -1236,7 +1278,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ClientWrite - Waiting to write data from the client. + Waiting to write data to the client. LibPQWalReceiverConnect @@ -1268,7 +1310,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Waiting in an extension. - IPC + IPC BgWorkerShutdown Waiting for background worker to shut down. @@ -1280,6 +1322,18 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser BtreePage Waiting for the page number needed to continue a parallel B-tree scan to become available. + + CheckpointDone + Waiting for a checkpoint to complete. + + + CheckpointStart + Waiting for a checkpoint to start. + + + ClogGroupUpdate + Waiting for group leader to update transaction status at transaction end. + ExecuteGather Waiting for activity from child process when executing Gather node. @@ -1368,10 +1422,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser MessageQueueSend Waiting to send bytes to a shared message queue. - - ParallelFinish - Waiting for parallel workers to finish computing. - ParallelBitmapScan Waiting for parallel bitmap scan to become initialized. @@ -1380,13 +1430,17 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser ParallelCreateIndexScan Waiting for parallel CREATE INDEX workers to finish heap scan. + + ParallelFinish + Waiting for parallel workers to finish computing. + ProcArrayGroupUpdate Waiting for group leader to clear transaction id at transaction end. - ClogGroupUpdate - Waiting for group leader to update transaction status at transaction end. + Promote + Waiting for standby promotion. ReplicationOriginDrop @@ -1418,7 +1472,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Waiting to apply WAL at recovery because it is delayed. - IO + IO BufFileRead Waiting for a read from a buffered file. @@ -1674,6 +1728,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser WALSenderTimelineHistoryRead Waiting for a read from a timeline history file during walsender timeline command. + + WALSync + Waiting for a WAL file to reach stable storage. + WALSyncMethodAssign Waiting for data to reach stable storage while assigning WAL sync method. @@ -1856,7 +1914,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i notification that this standby server has written and flushed it (but not yet applied it). This can be used to gauge the delay that synchronous_commit level - remote_flush incurred while committing if this + on incurred while committing if this server was configured as a synchronous standby. @@ -1908,6 +1966,11 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i + + reply_time + timestamp with time zone + Send time of last reply message received from standby server + @@ -2188,15 +2251,31 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i or NULL if SSL is not in use on this connection - clientdn + client_dn text Distinguished Name (DN) field from the client certificate used, or NULL if no client certificate was supplied or if SSL is not in use on this connection. This field is truncated if the DN field is longer than NAMEDATALEN (64 characters - in a standard build) + in a standard build). + + client_serial + numeric + Serial number of the client certificate, or NULL if no client + certificate was supplied or if SSL is not in use on this connection. The + combination of certificate serial number and certificate issuer uniquely + identifies a certificate (unless the issuer erroneously reuses serial + numbers). + + + issuer_dn + text + DN of the issuer of the client certificate, or NULL if no client + certificate was supplied or if SSL is not in use on this connection. + This field is truncated like client_dn. + @@ -2210,6 +2289,55 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i connection.
+ + <structname>pg_stat_gssapi</structname> View + + + + Column + Type + Description + + + + + + pid + integer + Process ID of a backend + + + gss_authenticated + boolean + True if GSSAPI authentication was used for this connection + + + principal + text + Principal used to authenticate this connection, or NULL + if GSSAPI was not used to authenticate this connection. This + field is truncated if the principal is longer than + NAMEDATALEN (64 characters in a standard build). + + + + encrypted + boolean + True if GSSAPI encryption is in use on this connection + + + +
+ + + The pg_stat_gssapi view will contain one row per + backend, showing information about GSSAPI usage on this connection. It can + be joined to pg_stat_activity or + pg_stat_replication on the + pid column to get more details about the + connection. + + <structname>pg_stat_archiver</structname> View @@ -2370,20 +2498,22 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i datid oid - OID of a database + OID of this database, or 0 for objects belonging to a shared + relation datname name - Name of this database + Name of this database, or NULL for the shared + objects. numbackends integer - Number of backends currently connected to this database. - This is the only column in this view that returns a value reflecting - current state; all other columns return the accumulated values since - the last reset. + Number of backends currently connected to this database, or + NULL for the shared objects. This is the only column + in this view that returns a value reflecting current state; all other + columns return the accumulated values since the last reset. xact_commit @@ -2466,6 +2596,20 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i bigint Number of deadlocks detected in this database + + checksum_failures + bigint + Number of data page checksum failures detected in this + database (or on a shared object), or NULL if data checksums are not + enabled. + + + checksum_last_failure + timestamp with time zone + Time at which the last data page checksum failure was detected in + this database (or on a shared object), or NULL if data checksums are not + enabled. + blk_read_time double precision @@ -2489,7 +2633,8 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i The pg_stat_database view will contain one row - for each database in the cluster, showing database-wide statistics. + for each database in the cluster, plus one for the shared objects, showing + database-wide statistics.
@@ -3334,11 +3479,262 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, PostgreSQL has the ability to report the progress of - certain commands during command execution. Currently, the only command - which supports progress reporting is VACUUM. This may be - expanded in the future. + certain commands during command execution. Currently, the only commands + which support progress reporting are CREATE INDEX, + VACUUM and + CLUSTER. This may be expanded in the future. + + + + CREATE INDEX Progress Reporting + + + Whenever CREATE INDEX or REINDEX is running, the + pg_stat_progress_create_index view will contain + one row for each backend that is currently creating indexes. The tables + below describe the information that will be reported and provide information + about how to interpret it. +
+ <structname>pg_stat_progress_create_index</structname> View + + + + Column + Type + Description + + + + + + pid + integer + Process ID of backend. + + + datid + oid + OID of the database to which this backend is connected. + + + datname + name + Name of the database to which this backend is connected. + + + relid + oid + OID of the table on which the index is being created. + + + index_relid + oid + OID of the index being created or reindexed. During a + non-concurrent CREATE INDEX, this is 0. + + + command + text + + The command that is running: CREATE INDEX, + CREATE INDEX CONCURRENTLY, + REINDEX, or REINDEX CONCURRENTLY. + + + + phase + text + + Current processing phase of index creation. See . + + + + lockers_total + bigint + + Total number of lockers to wait for, when applicable. + + + + lockers_done + bigint + + Number of lockers already waited for. + + + + current_locker_pid + bigint + + Process ID of the locker currently being waited for. + + + + blocks_total + bigint + + Total number of blocks to be processed in the current phase. + + + + blocks_done + bigint + + Number of blocks already processed in the current phase. + + + + tuples_total + bigint + + Total number of tuples to be processed in the current phase. + + + + tuples_done + bigint + + Number of tuples already processed in the current phase. + + + + partitions_total + bigint + + When creating an index on a partitioned table, this column is set to + the total number of partitions on which the index is to be created. + + + + partitions_done + bigint + + When creating an index on a partitioned table, this column is set to + the number of partitions on which the index has been completed. + + + + +
+ + + CREATE INDEX Phases + + + + Phase + Description + + + + + initializing + + CREATE INDEX or REINDEX is preparing to create the index. This + phase is expected to be very brief. + + + + waiting for writers before build + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + with write locks that can potentially see the table to finish. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + building index + + The index is being built by the access method-specific code. In this phase, + access methods that support progress reporting fill in their own progress data, + and the subphase is indicated in this column. Typically, + blocks_total and blocks_done + will contain progress data, as well as potentially + tuples_total and tuples_done. + + + + waiting for writers before validation + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + with write locks that can potentially write into the table to finish. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + index validation: scanning index + + CREATE INDEX CONCURRENTLY is scanning the index searching + for tuples that need to be validated. + This phase is skipped when not in concurrent mode. + Columns blocks_total (set to the total size of the index) + and blocks_done contain the progress information for this phase. + + + + index validation: sorting tuples + + CREATE INDEX CONCURRENTLY is sorting the output of the + index scanning phase. + + + + index validation: scanning table + + CREATE INDEX CONCURRENTLY is scanning the table + to validate the index tuples collected in the previous two phases. + This phase is skipped when not in concurrent mode. + Columns blocks_total (set to the total size of the table) + and blocks_done contain the progress information for this phase. + + + + waiting for old snapshots + + CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY is waiting for transactions + that can potentially see the table to release their snapshots. This + phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + waiting for readers before marking dead + + REINDEX CONCURRENTLY is waiting for transactions + with read locks on the table to finish, before marking the old index dead. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + waiting for readers before dropping + + REINDEX CONCURRENTLY is waiting for transactions + with read locks on the table to finish, before dropping the old index. + This phase is skipped when not in concurrent mode. + Columns lockers_total, lockers_done + and current_locker_pid contain the progress + information for this phase. + + + + +
+ + + VACUUM Progress Reporting @@ -3348,9 +3744,11 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid, one row for each backend (including autovacuum worker processes) that is currently vacuuming. The tables below describe the information that will be reported and provide information about how to interpret it. - Progress reporting is not currently supported for VACUUM FULL - and backends running VACUUM FULL will not be listed in this - view. + Progress for VACUUM FULL commands is reported via + pg_stat_progress_cluster + because both VACUUM FULL and CLUSTER + rewrite the table, while regular VACUUM only modifies it + in place. See .
@@ -3451,7 +3849,7 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
- VACUUM phases + VACUUM Phases @@ -3527,6 +3925,183 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
+ + + + CLUSTER Progress Reporting + + + Whenever CLUSTER or VACUUM FULL is + running, the pg_stat_progress_cluster view will + contain a row for each backend that is currently running either command. + The tables below describe the information that will be reported and + provide information about how to interpret it. + + + + <structname>pg_stat_progress_cluster</structname> View + + + + Column + Type + Description + + + + + + pid + integer + Process ID of backend. + + + datid + oid + OID of the database to which this backend is connected. + + + datname + name + Name of the database to which this backend is connected. + + + relid + oid + OID of the table being clustered. + + + command + text + + The command that is running. Either CLUSTER or VACUUM FULL. + + + + phase + text + + Current processing phase. See . + + + + cluster_index_relid + oid + + If the table is being scanned using an index, this is the OID of the + index being used; otherwise, it is zero. + + + + heap_tuples_scanned + bigint + + Number of heap tuples scanned. + This counter only advances when the phase is + seq scanning heap, + index scanning heap + or writing new heap. + + + + heap_tuples_written + bigint + + Number of heap tuples written. + This counter only advances when the phase is + seq scanning heap, + index scanning heap + or writing new heap. + + + + heap_blks_total + bigint + + Total number of heap blocks in the table. This number is reported + as of the beginning of seq scanning heap. + + + + heap_blks_scanned + bigint + + Number of heap blocks scanned. This counter only advances when the + phase is seq scanning heap. + + + + index_rebuild_count + bigint + + Number of indexes rebuilt. This counter only advances when the phase + is rebuilding index. + + + + +
+ + + CLUSTER and VACUUM FULL Phases + + + + Phase + Description + + + + + + initializing + + The command is preparing to begin scanning the heap. This phase is + expected to be very brief. + + + + seq scanning heap + + The command is currently scanning the table using a sequential scan. + + + + index scanning heap + + CLUSTER is currently scanning the table using an index scan. + + + + sorting tuples + + CLUSTER is currently sorting tuples. + + + + swapping relation files + + The command is currently swapping newly-built files into place. + + + + rebuilding index + + The command is currently rebuilding an index. + + + + performing final cleanup + + The command is performing final cleanup. When this phase is + completed, CLUSTER + or VACUUM FULL will end. + + + + +
+
diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 0e3e89af560..f8c96551119 100644 --- a/doc/src/sgml/mvcc.sgml +++ b/doc/src/sgml/mvcc.sgml @@ -422,31 +422,6 @@ COMMIT; 11, which no longer matches the criteria.
- - The MERGE allows the user to specify various combinations - of INSERT, UPDATE or - DELETE subcommands. A MERGE command - with both INSERT and UPDATE - subcommands looks similar to INSERT with an - ON CONFLICT DO UPDATE clause but does not guarantee - that either INSERT and UPDATE will occur. - - If MERGE attempts an UPDATE or DELETE and the row is concurrently updated - but the join condition still passes for the current target and the current - source tuple, then MERGE will behave the same as the UPDATE or DELETE commands - and perform its action on the latest version of the row, using standard - EvalPlanQual. MERGE actions can be conditional, so conditions must be - re-evaluated on the latest row, starting from the first action. - - On the other hand, if the row is concurrently updated or deleted so that - the join condition fails, then MERGE will execute a NOT MATCHED action, if it - exists and the AND WHEN qual evaluates to true. - - If MERGE attempts an INSERT and a unique index is present and a duplicate - row is concurrently inserted then a uniqueness violation is raised. MERGE - does not attempt to avoid the ERROR by attempting an UPDATE. - - Because Read Committed mode starts each command with a new snapshot that includes all transactions committed up to that instant, @@ -840,7 +815,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - Table-level Locks + Table-Level Locks LOCK @@ -872,7 +847,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
- Table-level Lock Modes + Table-Level Lock Modes ACCESS SHARE @@ -925,8 +900,7 @@ ERROR: could not serialize access due to read/write dependencies among transact The commands UPDATE, - DELETE, INSERT and - MERGE + DELETE, and INSERT acquire this lock mode on the target table (in addition to ACCESS SHARE locks on any other referenced tables). In general, this lock mode will be acquired by any @@ -952,10 +926,11 @@ ERROR: could not serialize access due to read/write dependencies among transact Acquired by VACUUM (without ), ANALYZE, CREATE INDEX CONCURRENTLY, - CREATE STATISTICS and - ALTER TABLE VALIDATE and other - ALTER TABLE variants (for full details see - ). + REINDEX CONCURRENTLY, + CREATE STATISTICS, and certain ALTER + INDEX and ALTER TABLE variants (for full + details see and ).
@@ -996,8 +971,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
- Acquired by CREATE COLLATION, - CREATE TRIGGER, and many forms of + Acquired by CREATE TRIGGER and some forms of ALTER TABLE (see ).
@@ -1047,7 +1021,7 @@ ERROR: could not serialize access due to read/write dependencies among transact CLUSTER, VACUUM FULL, and REFRESH MATERIALIZED VIEW (without ) - commands. Many forms of ALTER TABLE also acquire + commands. Many forms of ALTER INDEX and ALTER TABLE also acquire a lock at this level. This is also the default lock mode for LOCK TABLE statements that do not specify a mode explicitly. @@ -1193,7 +1167,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - Row-level Locks + Row-Level Locks In addition to table-level locks, there are row-level locks, which @@ -1208,7 +1182,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - Row-level Lock Modes + Row-Level Lock Modes FOR UPDATE @@ -1310,7 +1284,7 @@ ERROR: could not serialize access due to read/write dependencies among transact
- Conflicting Row-level Locks + Conflicting Row-Level Locks @@ -1362,7 +1336,7 @@ ERROR: could not serialize access due to read/write dependencies among transact - Page-level Locks + Page-Level Locks In addition to table and row locks, page-level share/exclusive locks are @@ -1600,7 +1574,7 @@ SELECT pg_advisory_lock(q.id) FROM - Enforcing Consistency With Serializable Transactions + Enforcing Consistency with Serializable Transactions If the Serializable transaction isolation level is used for all writes @@ -1638,7 +1612,7 @@ SELECT pg_advisory_lock(q.id) FROM - Enforcing Consistency With Explicit Blocking Locks + Enforcing Consistency with Explicit Blocking Locks When non-serializable writes are possible, diff --git a/doc/src/sgml/nls.sgml b/doc/src/sgml/nls.sgml index 16e25abd31e..f2c1792955b 100644 --- a/doc/src/sgml/nls.sgml +++ b/doc/src/sgml/nls.sgml @@ -153,7 +153,7 @@ msgstr "another translated" can also be named language_region.po where region is the - + ISO 3166-1 two-letter country code (in upper case), e.g., pt_BR.po for Portuguese in Brazil. If you @@ -433,7 +433,7 @@ fprintf(stderr, gettext("panic level %d\n"), lvl); - Message-writing Guidelines + Message-Writing Guidelines Here are some guidelines for writing messages that are easily diff --git a/doc/src/sgml/oid2name.sgml b/doc/src/sgml/oid2name.sgml index dd875281c81..c7ebd61c6bf 100644 --- a/doc/src/sgml/oid2name.sgml +++ b/doc/src/sgml/oid2name.sgml @@ -60,41 +60,48 @@ - filenode - show info for table with filenode filenode + + + show info for table with filenode filenode. - include indexes and sequences in the listing + + include indexes and sequences in the listing. - oid - show info for table with OID oid + + + show info for table with OID oid. - omit headers (useful for scripting) + + omit headers (useful for scripting). - show tablespace OIDs + + show tablespace OIDs. + include system objects (those in , - and schemas) + and schemas). - tablename_pattern - show info for table(s) matching tablename_pattern + + + show info for table(s) matching tablename_pattern. @@ -109,8 +116,9 @@ + display more information about each object shown: tablespace name, - schema name, and OID + schema name, and OID. @@ -133,29 +141,34 @@ - database - database to connect to + + + database to connect to. - host - database server's host + + + database server's host. - port - database server's port + + database server's host. Use of this parameter is + deprecated as of + PostgreSQL 12. - username - user name to connect as + + + database server's port. - password - password (deprecated — putting this on the command line - is a security hazard) + + + user name to connect as. @@ -188,6 +201,30 @@ + + Environment + + + + PGHOST + PGPORT + PGUSER + + + + Default connection parameters. + + + + + + + This utility, like most other PostgreSQL + utilities, also uses the environment variables supported by + libpq (see ). + + + Notes diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml index 4d5da186bb4..7e2e1487d79 100644 --- a/doc/src/sgml/pageinspect.sgml +++ b/doc/src/sgml/pageinspect.sgml @@ -125,6 +125,39 @@ test=# SELECT page_checksum(get_raw_page('pg_class', 0), 0); + + + fsm_page_contents(page bytea) returns text + + fsm_page_contents + + + + + + fsm_page_contents shows the internal node structure + of a FSM page. For example: + +test=# SELECT fsm_page_contents(get_raw_page('pg_class', 'fsm', 0)); + + The output is a multiline string, with one line per node in the binary + tree within the page. Only those nodes that are not zero are printed. + The so-called "next" pointer, which points to the next slot to be + returned from the page, is also printed. + + + See src/backend/storage/freespace/README for more + information on the structure of an FSM page. + + + + + + + + Heap Functions + + heap_page_items(page bytea) returns setof record @@ -151,12 +184,17 @@ test=# SELECT * FROM heap_page_items(get_raw_page('pg_class', 0)); src/include/access/htup_details.h for explanations of the fields returned. + + The heap_tuple_infomask_flags function can be + used to unpack the flag bits of t_infomask + and t_infomask2 for heap tuples. + - tuple_data_split(rel_oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[] + tuple_data_split(rel_oid oid, t_data bytea, t_infomask integer, t_infomask2 integer, t_bits text [, do_detoast bool]) returns bytea[] tuple_data_split @@ -181,7 +219,7 @@ test=# SELECT tuple_data_split('pg_class'::regclass, t_data, t_infomask, t_infom - heap_page_item_attrs(rel_oid, t_data bytea, [, do_detoast bool]) returns bytea[] + heap_page_item_attrs(page bytea, rel_oid regclass [, do_detoast bool]) returns setof record heap_page_item_attrs @@ -206,23 +244,36 @@ test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class - fsm_page_contents(page bytea) returns text + heap_tuple_infomask_flags(t_infomask integer, t_infomask2 integer) returns record - fsm_page_contents + heap_tuple_infomask_flags - - fsm_page_contents shows the internal node structure - of a FSM page. The output is a multiline string, with one line per - node in the binary tree within the page. Only those nodes that are not - zero are printed. The so-called "next" pointer, which points to the - next slot to be returned from the page, is also printed. + heap_tuple_infomask_flags decodes the + t_infomask and + t_infomask2 returned by + heap_page_items into a human-readable + set of arrays made of flag names, with one column for all + the flags and one column for combined flags. For example: + +test=# SELECT t_ctid, raw_flags, combined_flags + FROM heap_page_items(get_raw_page('pg_class', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2) + WHERE t_infomask IS NOT NULL OR t_infomask2 IS NOT NULL; + + This function should be called with the same arguments as the return + attributes of heap_page_items. - See src/backend/storage/freespace/README for more - information on the structure of an FSM page. + Combined flags are displayed for source-level macros that take into + account the value of more than one raw bit, such as + HEAP_XMIN_FROZEN. + + + See src/include/access/htup_details.h for + explanations of the flag names returned. @@ -230,7 +281,7 @@ test=# SELECT * FROM heap_page_item_attrs(get_raw_page('pg_class', 0), 'pg_class - B-tree Functions + B-Tree Functions @@ -695,9 +746,8 @@ test-# regexp_replace(spares::text, '(,0)*}', '}') as spares, test-# regexp_replace(mapp::text, '(,0)*}', '}') as mapp test-# FROM hash_metapage_info(get_raw_page('con_hash_index', 0)); -[ RECORD 1 ]------------------------------------------------------------------------------- -spares | {0,0,0,0,0,0,1,1,1,1,1,1,1,1,3,4,4,4,45,55,58,59,508,567,628,704,1193,1202,1204} magic | 105121344 -version | 3 +version | 4 ntuples | 500500 ffactor | 40 bsize | 8152 diff --git a/doc/src/sgml/parallel.sgml b/doc/src/sgml/parallel.sgml index d8f001d4b61..af5d48a5c79 100644 --- a/doc/src/sgml/parallel.sgml +++ b/doc/src/sgml/parallel.sgml @@ -102,7 +102,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; order-preserving merge. In contrast, Gather reads tuples from the workers in whatever order is convenient, destroying any sort order that may have existed. - + @@ -124,14 +124,6 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; configured via max_parallel_workers_per_gather. - - - - must be set to a - value other than none. Parallel query requires dynamic - shared memory in order to pass data between cooperating processes. - - @@ -152,7 +144,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; The query writes any data or locks any database rows. If a query contains a data-modifying operation either at the top level or within a CTE, no parallel plans for that query will be generated. As an - exception, the commands CREATE TABLE, SELECT + exception, the commands CREATE TABLE ... AS, SELECT INTO, and CREATE MATERIALIZED VIEW which create a new table and populate it can use a parallel plan. @@ -192,13 +184,6 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; using a very large number of processes. - - - - The transaction isolation level is serializable. This is - a limitation of the current implementation. - - @@ -241,16 +226,6 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; that may be suboptimal when run serially. - - - - The transaction isolation level is serializable. This situation - does not normally arise, because parallel query plans are not - generated when the transaction isolation level is serializable. - However, it can happen if the transaction isolation level is changed to - serializable after the plan is generated and before it is executed. - - @@ -372,7 +347,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; workers in order to produce the final result. This is reflected in the plan as a Finalize Aggregate node. - + Because the Finalize Aggregate node runs on the leader process, queries which produce a relatively large number of groups in @@ -401,6 +376,54 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; + + Parallel Append + + + Whenever PostgreSQL needs to combine rows + from multiple sources into a single result set, it uses an + Append or MergeAppend plan node. + This commonly happens when implementing UNION ALL or + when scanning a partitioned table. Such nodes can be used in parallel + plans just as they can in any other plan. However, in a parallel plan, + the planner may instead use a Parallel Append node. + + + + When an Append node is used in a parallel plan, each + process will execute the child plans in the order in which they appear, + so that all participating processes cooperate to execute the first child + plan until it is complete and then move to the second plan at around the + same time. When a Parallel Append is used instead, the + executor will instead spread out the participating processes as evenly as + possible across its child plans, so that multiple child plans are executed + simultaneously. This avoids contention, and also avoids paying the startup + cost of a child plan in those processes that never execute it. + + + + Also, unlike a regular Append node, which can only have + partial children when used within a parallel plan, a Parallel + Append node can have both partial and non-partial child plans. + Non-partial children will be scanned by only a single process, since + scanning them more than once would produce duplicate results. Plans that + involve appending multiple results sets can therefore achieve + coarse-grained parallelism even when efficient partial plans are not + available. For example, consider a query against a partitioned table + which can be only be implemented efficiently by using an index that does + not support parallel scans. The planner might choose a Parallel + Append of regular Index Scan plans; each + individual index scan would have to be executed to completion by a single + process, but different scans could be performed at the same time by + different processes. + + + + can be used to disable + this feature. + + + Parallel Plan Tips @@ -473,7 +496,13 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; - Access to an InitPlan or correlated SubPlan. + Plan nodes to which an InitPlan is attached. + + + + + + Plan nodes which reference a correlated SubPlan. @@ -487,7 +516,7 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%'; unsafe, because this would require predicting every operation which the function could possibly perform. In general, this is equivalent to the Halting Problem and therefore impossible. Even for simple functions - where it conceivably be done, we do not try, since this would be expensive + where it could conceivably be done, we do not try, since this would be expensive and error-prone. Instead, all user-defined functions are assumed to be parallel unsafe unless otherwise marked. When using or diff --git a/doc/src/sgml/passwordcheck.sgml b/doc/src/sgml/passwordcheck.sgml index 3db169b4c18..4128b6cc4f6 100644 --- a/doc/src/sgml/passwordcheck.sgml +++ b/doc/src/sgml/passwordcheck.sgml @@ -25,7 +25,7 @@ You can adapt this module to your needs by changing the source code. For example, you can use - CrackLib + CrackLib to check passwords — this only requires uncommenting two lines in the Makefile and rebuilding the module. (We cannot include CrackLib diff --git a/doc/src/sgml/perform.sgml b/doc/src/sgml/perform.sgml index b50357c3b4e..715aff63c80 100644 --- a/doc/src/sgml/perform.sgml +++ b/doc/src/sgml/perform.sgml @@ -899,12 +899,12 @@ EXPLAIN ANALYZE SELECT * FROM tenk1 WHERE unique1 < 100 AND unique2 > 9000 Generally, the EXPLAIN output will display details for every plan node which was generated by the query planner. However, there are cases where the executor is able to determine that certain nodes are - not required; currently, the only node type to support this is the - Append node. This node type has the ability to discard - subnodes which it is able to determine won't contain any records required - by the query. It is possible to determine that nodes have been removed in - this way by the presence of a "Subplans Removed" property in the - EXPLAIN output. + not required; currently, the only node types to support this are the + Append and MergeAppend nodes. These + node types have the ability to discard subnodes which they are able to + determine won't contain any records required by the query. It is possible + to determine that nodes have been removed in this way by the presence of a + "Subplans Removed" property in the EXPLAIN output. @@ -1076,6 +1076,10 @@ WHERE tablename = 'road'; pg_statistic_ext + + pg_statistic_ext_data + + It is common to see slow queries running bad execution plans because multiple columns used in the query clauses are correlated. @@ -1098,13 +1102,13 @@ WHERE tablename = 'road'; - Statistics objects are created using - , which see for more details. + Statistics objects are created using the + command. Creation of such an object merely creates a catalog entry expressing interest in the statistics. Actual data collection is performed by ANALYZE (either a manual command, or background auto-analyze). The collected values can be examined in the - pg_statistic_ext + pg_statistic_ext_data catalog. @@ -1168,14 +1172,14 @@ WHERE tablename = 'road'; Here is an example of collecting functional-dependency statistics: -CREATE STATISTICS stts (dependencies) ON zip, city FROM zipcodes; +CREATE STATISTICS stts (dependencies) ON city, zip FROM zipcodes; ANALYZE zipcodes; -SELECT stxname, stxkeys, stxdependencies - FROM pg_statistic_ext +SELECT stxname, stxkeys, stxddependencies + FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid) WHERE stxname = 'stts'; - stxname | stxkeys | stxdependencies + stxname | stxkeys | stxddependencies ---------+---------+------------------------------------------ stts | 1 5 | {"1 => 5": 1.000000, "5 => 1": 0.423130} (1 row) @@ -1258,12 +1262,12 @@ SELECT * FROM zipcodes WHERE city = 'San Francisco' AND zip = '90210'; Continuing the previous example, the n-distinct counts in a table of ZIP codes might look like the following: -CREATE STATISTICS stts2 (ndistinct) ON zip, state, city FROM zipcodes; +CREATE STATISTICS stts2 (ndistinct) ON city, state, zip FROM zipcodes; ANALYZE zipcodes; -SELECT stxkeys AS k, stxndistinct AS nd - FROM pg_statistic_ext +SELECT stxkeys AS k, stxdndistinct AS nd + FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid) WHERE stxname = 'stts2'; -[ RECORD 1 ]-------------------------------------------------------- k | 1 2 5 @@ -1285,6 +1289,72 @@ nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178} plans. Otherwise, the ANALYZE cycles are just wasted. + + + Multivariate MCV Lists + + + Another type of statistics stored for each column are most-common value + lists. This allows very accurate estimates for individual columns, but + may result in significant misestimates for queries with conditions on + multiple columns. + + + + To improve such estimates, ANALYZE can collect MCV + lists on combinations of columns. Similarly to functional dependencies + and n-distinct coefficients, it's impractical to do this for every + possible column grouping. Even more so in this case, as the MCV list + (unlike functional dependencies and n-distinct coefficients) does store + the common column values. So data is collected only for those groups + of columns appearing together in a statistics object defined with the + mcv option. + + + + Continuing the previous example, the MCV list for a table of ZIP codes + might look like the following (unlike for simpler types of statistics, + a function is required for inspection of MCV contents): + + +CREATE STATISTICS stts3 (mcv) ON city, state FROM zipcodes; + +ANALYZE zipcodes; + +SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts3'; + + index | values | nulls | frequency | base_frequency +-------+------------------------+-------+-----------+---------------- + 0 | {Washington, DC} | {f,f} | 0.003467 | 2.7e-05 + 1 | {Apo, AE} | {f,f} | 0.003067 | 1.9e-05 + 2 | {Houston, TX} | {f,f} | 0.002167 | 0.000133 + 3 | {El Paso, TX} | {f,f} | 0.002 | 0.000113 + 4 | {New York, NY} | {f,f} | 0.001967 | 0.000114 + 5 | {Atlanta, GA} | {f,f} | 0.001633 | 3.3e-05 + 6 | {Sacramento, CA} | {f,f} | 0.001433 | 7.8e-05 + 7 | {Miami, FL} | {f,f} | 0.0014 | 6e-05 + 8 | {Dallas, TX} | {f,f} | 0.001367 | 8.8e-05 + 9 | {Chicago, IL} | {f,f} | 0.001333 | 5.1e-05 + ... +(99 rows) + + This indicates that the most common combination of city and state is + Washington in DC, with actual frequency (in the sample) about 0.35%. + The base frequency of the combination (as computed from the simple + per-column frequencies) is only 0.0027%, resulting in two orders of + magnitude under-estimates. + + + + It's advisable to create MCV statistics objects only + on combinations of columns that are actually used in conditions together, + and for which misestimation of the number of groups is resulting in bad + plans. Otherwise, the ANALYZE and planning cycles + are just wasted. + + + @@ -1535,8 +1605,8 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; needs to be written, because in case of an error, the files containing the newly loaded data will be removed anyway. However, this consideration only applies when - is minimal as all commands - must write WAL otherwise. + is minimal for + non-partitioned tables as all commands must write WAL otherwise. @@ -1695,7 +1765,7 @@ SELECT * FROM x, y, a, b, c WHERE something AND somethingelse; - Some Notes About <application>pg_dump</application> + Some Notes about <application>pg_dump</application> Dump scripts generated by pg_dump automatically apply diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml index efa193d22e3..0acd11ed555 100644 --- a/doc/src/sgml/pgcrypto.sgml +++ b/doc/src/sgml/pgcrypto.sgml @@ -63,7 +63,7 @@ $$ LANGUAGE SQL STRICT IMMUTABLE; hmac(data text, key text, type text) returns bytea -hmac(data bytea, key text, type text) returns bytea +hmac(data bytea, key bytea, type text) returns bytea @@ -956,9 +956,9 @@ gpg -a --export-secret-keys KEYID > secret.key For more details see man gpg, - The GNU + The GNU Privacy Handbook and other documentation on - . + . @@ -1132,7 +1132,8 @@ gen_random_bytes(count integer) returns bytea gen_random_uuid() returns uuid - Returns a version 4 (random) UUID. + Returns a version 4 (random) UUID. (Obsolete, this function is now also + included in core PostgreSQL.) @@ -1274,7 +1275,7 @@ gen_random_uuid() returns uuid The implementation does not resist - side-channel + side-channel attacks. For example, the time required for a pgcrypto decryption function to complete varies among ciphertexts of a given size. @@ -1286,7 +1287,7 @@ gen_random_uuid() returns uuid - + The GNU Privacy Handbook. @@ -1295,7 +1296,7 @@ gen_random_uuid() returns uuid - + How to choose a good password. @@ -1330,13 +1331,13 @@ gen_random_uuid() returns uuid - + Comparison of crypt-des, crypt-md5 and bcrypt algorithms. - + Description of Fortuna CSPRNG. @@ -1344,10 +1345,6 @@ gen_random_uuid() returns uuid Jean-Luc Cooke Fortuna-based /dev/random driver for Linux. - - - Collection of cryptology pointers. - diff --git a/doc/src/sgml/pgrowlocks.sgml b/doc/src/sgml/pgrowlocks.sgml index 39de41a03cf..60e13393ea6 100644 --- a/doc/src/sgml/pgrowlocks.sgml +++ b/doc/src/sgml/pgrowlocks.sgml @@ -70,7 +70,7 @@ pgrowlocks(text) returns setof record Transaction IDs of lockers (more than one if multitransaction) - lock_type + modes text[] Lock mode of lockers (more than one if multitransaction), an array of Key Share, Share, @@ -127,14 +127,14 @@ SELECT * FROM accounts AS a, pgrowlocks('accounts') AS p Sample Output - -test=# SELECT * FROM pgrowlocks('t1'); - locked_row | lock_type | locker | multi | xids | pids -------------+-----------+--------+-------+-----------+--------------- - (0,1) | Shared | 19 | t | {804,805} | {29066,29068} - (0,2) | Shared | 19 | t | {804,805} | {29066,29068} - (0,3) | Exclusive | 804 | f | {804} | {29066} - (0,4) | Exclusive | 804 | f | {804} | {29066} + +=# SELECT * FROM pgrowlocks('t1'); + locked_row | locker | multi | xids | modes | pids +------------+--------+-------+-------+----------------+-------- + (0,1) | 609 | f | {609} | {"For Share"} | {3161} + (0,2) | 609 | f | {609} | {"For Share"} | {3161} + (0,3) | 607 | f | {607} | {"For Update"} | {3107} + (0,4) | 607 | f | {607} | {"For Update"} | {3107} (4 rows) diff --git a/doc/src/sgml/pgstandby.sgml b/doc/src/sgml/pgstandby.sgml index 2cc58fe3567..d8aded43840 100644 --- a/doc/src/sgml/pgstandby.sgml +++ b/doc/src/sgml/pgstandby.sgml @@ -47,7 +47,7 @@ To configure a standby server to use pg_standby, put this into its - recovery.conf configuration file: + postgresql.conf configuration file: restore_command = 'pg_standby archiveDir %f %p %r' diff --git a/doc/src/sgml/pgstatstatements.sgml b/doc/src/sgml/pgstatstatements.sgml index c0217ed485f..26bb82da4a8 100644 --- a/doc/src/sgml/pgstatstatements.sgml +++ b/doc/src/sgml/pgstatstatements.sgml @@ -336,7 +336,7 @@ - pg_stat_statements_reset() returns void + pg_stat_statements_reset(userid Oid, dbid Oid, queryid bigint) returns void pg_stat_statements_reset @@ -344,9 +344,16 @@ - pg_stat_statements_reset discards all statistics - gathered so far by pg_stat_statements. - By default, this function can only be executed by superusers. + pg_stat_statements_reset discards statistics + gathered so far by pg_stat_statements corresponding + to the specified userid, dbid + and queryid. If any of the parameters are not + specified, the default value 0(invalid) is used for + each of them and the statistics that match with other parameters will be + reset. If no parameter is specified or all the specified parameters are + 0(invalid), it will discard all statistics. By + default, this function can only be executed by superusers. Access may be + granted to others using GRANT. @@ -494,36 +501,87 @@ bench=# \x bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5; --[ RECORD 1 ]--------------------------------------------------------------------- -query | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2; +-[ RECORD 1 ]-------------------------------------------------------------------- +query | UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2 calls | 3000 -total_time | 9609.00100000002 -rows | 2836 -hit_percent | 99.9778970000200936 --[ RECORD 2 ]--------------------------------------------------------------------- -query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2; +total_time | 25565.855387 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 2 ]-------------------------------------------------------------------- +query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 calls | 3000 -total_time | 8015.156 -rows | 2990 -hit_percent | 99.9731126579631345 --[ RECORD 3 ]--------------------------------------------------------------------- +total_time | 20756.669379 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 3 ]-------------------------------------------------------------------- query | copy pgbench_accounts from stdin calls | 1 -total_time | 310.624 +total_time | 291.865911 rows | 100000 -hit_percent | 0.30395136778115501520 --[ RECORD 4 ]--------------------------------------------------------------------- -query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2; +hit_percent | 100.0000000000000000 +-[ RECORD 4 ]-------------------------------------------------------------------- +query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 calls | 3000 -total_time | 271.741999999997 +total_time | 271.232977 rows | 3000 -hit_percent | 93.7968855088209426 --[ RECORD 5 ]--------------------------------------------------------------------- +hit_percent | 98.5723926698852723 +-[ RECORD 5 ]-------------------------------------------------------------------- query | alter table pgbench_accounts add primary key (aid) calls | 1 -total_time | 81.42 +total_time | 160.588563 rows | 0 -hit_percent | 34.4947735191637631 +hit_percent | 100.0000000000000000 + + +bench=# SELECT pg_stat_statements_reset(0,0,s.queryid) FROM pg_stat_statements AS s + WHERE s.query = 'UPDATE pgbench_branches SET bbalance = bbalance + $1 WHERE bid = $2'; + +bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / + nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent + FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5; +-[ RECORD 1 ]-------------------------------------------------------------------- +query | UPDATE pgbench_tellers SET tbalance = tbalance + $1 WHERE tid = $2 +calls | 3000 +total_time | 20756.669379 +rows | 3000 +hit_percent | 100.0000000000000000 +-[ RECORD 2 ]-------------------------------------------------------------------- +query | copy pgbench_accounts from stdin +calls | 1 +total_time | 291.865911 +rows | 100000 +hit_percent | 100.0000000000000000 +-[ RECORD 3 ]-------------------------------------------------------------------- +query | UPDATE pgbench_accounts SET abalance = abalance + $1 WHERE aid = $2 +calls | 3000 +total_time | 271.232977 +rows | 3000 +hit_percent | 98.5723926698852723 +-[ RECORD 4 ]-------------------------------------------------------------------- +query | alter table pgbench_accounts add primary key (aid) +calls | 1 +total_time | 160.588563 +rows | 0 +hit_percent | 100.0000000000000000 +-[ RECORD 5 ]-------------------------------------------------------------------- +query | vacuum analyze pgbench_accounts +calls | 1 +total_time | 136.448116 +rows | 0 +hit_percent | 99.9201915403032721 + +bench=# SELECT pg_stat_statements_reset(0,0,0); + +bench=# SELECT query, calls, total_time, rows, 100.0 * shared_blks_hit / + nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent + FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5; +-[ RECORD 1 ]--------------------------------------- +query | SELECT pg_stat_statements_reset(0,0,0) +calls | 1 +total_time | 0.189497 +rows | 1 +hit_percent | + diff --git a/doc/src/sgml/pgtrgm.sgml b/doc/src/sgml/pgtrgm.sgml index 8f395296d8f..3e6fd7395fb 100644 --- a/doc/src/sgml/pgtrgm.sgml +++ b/doc/src/sgml/pgtrgm.sgml @@ -113,7 +113,10 @@ real Same as word_similarity(text, text), but forces - extent boundaries to match word boundaries. + extent boundaries to match word boundaries. Since we don't have + cross-word trigrams, this function actually returns greatest similarity + between first string and any continuous extent of words of the second + string. @@ -152,9 +155,9 @@ In the first string, the set of trigrams is - {" w"," wo","ord","wor","rd "}. + {" w"," wo","wor","ord","rd "}. In the second string, the ordered set of trigrams is - {" t"," tw",two,"wo "," w"," wo","wor","ord","rds", ds "}. + {" t"," tw","two","wo "," w"," wo","wor","ord","rds","ds "}. The most similar extent of an ordered set of trigrams in the second string is {" w"," wo","wor","ord"}, and the similarity is 0.8. @@ -164,16 +167,16 @@ This function returns a value that can be approximately understood as the greatest similarity between the first string and any substring of the second string. However, this function does not add padding to the boundaries of - the extent. Thus, a whole word match gets a higher score than a match with - a part of the word. + the extent. Thus, the number of additional characters present in the + second string is not considered, except for the mismatched word boundaries. At the same time, strict_word_similarity(text, text) - has to select an extent that matches word boundaries. In the example above, + selects an extent of words in the second string. In the example above, strict_word_similarity(text, text) would select the - extent {" w"," wo","wor","ord","rds", ds "}, which - corresponds to the whole word 'words'. + extent of a single word 'words', whose set of trigrams is + {" w"," wo","wor","ord","rds","ds "}. # SELECT strict_word_similarity('word', 'two words'), similarity('word', 'words'); @@ -186,9 +189,9 @@ Thus, the strict_word_similarity(text, text) function - is useful for finding similar subsets of whole words, while + is useful for finding the similarity to whole words, while word_similarity(text, text) is more suitable for - searching similar parts of words. + finding the similarity for parts of words.
@@ -317,23 +320,40 @@ - - - pg_trgm.word_similarity_threshold (real) - - - pg_trgm.word_similarity_threshold configuration parameter - - - - - - Sets the current word similarity threshold that is used by - <% and %> operators. The threshold - must be between 0 and 1 (default is 0.6). - - - + + + pg_trgm.word_similarity_threshold (real) + + + pg_trgm.word_similarity_threshold configuration parameter + + + + + + Sets the current word similarity threshold that is used by the + <% and %> operators. The threshold + must be between 0 and 1 (default is 0.6). + + + + + + pg_trgm.strict_word_similarity_threshold (real) + + + pg_trgm.strict_word_similarity_threshold configuration parameter + + + + + + Sets the current strict word similarity threshold that is used by the + <<% and %>> operators. The threshold + must be between 0 and 1 (default is 0.5). + + + diff --git a/doc/src/sgml/planstats.sgml b/doc/src/sgml/planstats.sgml index ef643ad0646..94b6b22947b 100644 --- a/doc/src/sgml/planstats.sgml +++ b/doc/src/sgml/planstats.sgml @@ -455,7 +455,7 @@ rows = (outer_cardinality * inner_cardinality) * selectivity multivariate - + Functional Dependencies @@ -540,7 +540,7 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1; - + Multivariate N-Distinct Counts @@ -585,6 +585,118 @@ EXPLAIN (ANALYZE, TIMING OFF) SELECT COUNT(*) FROM t GROUP BY a, b; + + + MCV Lists + + + As explained in , functional + dependencies are very cheap and efficient type of statistics, but their + main limitation is their global nature (only tracking dependencies at + the column level, not between individual column values). + + + + This section introduces multivariate variant of MCV + (most-common values) lists, a straightforward extension of the per-column + statistics described in . These + statistics address the limitation by storing individual values, but it is + naturally more expensive, both in terms of building the statistics in + ANALYZE, storage and planning time. + + + + Let's look at the query from + again, but this time with a MCV list created on the + same set of columns (be sure to drop the functional dependencies, to + make sure the planner uses the newly created statistics). + + +DROP STATISTICS stts; +CREATE STATISTICS stts2 (mcv) ON a, b FROM t; +ANALYZE t; +EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 1; + QUERY PLAN +------------------------------------------------------------------------------- + Seq Scan on t (cost=0.00..195.00 rows=100 width=8) (actual rows=100 loops=1) + Filter: ((a = 1) AND (b = 1)) + Rows Removed by Filter: 9900 + + + The estimate is as accurate as with the functional dependencies, mostly + thanks to the table being fairly small and having a simple distribution + with a low number of distinct values. Before looking at the second query, + which was not handled by functional dependencies particularly well, + let's inspect the MCV list a bit. + + + + Inspecting the MCV list is possible using + pg_mcv_list_items set-returning function. + + +SELECT m.* FROM pg_statistic_ext join pg_statistic_ext_data on (oid = stxoid), + pg_mcv_list_items(stxdmcv) m WHERE stxname = 'stts2'; + index | values | nulls | frequency | base_frequency +-------+----------+-------+-----------+---------------- + 0 | {0, 0} | {f,f} | 0.01 | 0.0001 + 1 | {1, 1} | {f,f} | 0.01 | 0.0001 + ... + 49 | {49, 49} | {f,f} | 0.01 | 0.0001 + 50 | {50, 50} | {f,f} | 0.01 | 0.0001 + ... + 97 | {97, 97} | {f,f} | 0.01 | 0.0001 + 98 | {98, 98} | {f,f} | 0.01 | 0.0001 + 99 | {99, 99} | {f,f} | 0.01 | 0.0001 +(100 rows) + + + This confirms there are 100 distinct combinations in the two columns, and + all of them are about equally likely (1% frequency for each one). The + base frequency is the frequency computed from per-column statistics, as if + there were no multi-column statistics. Had there been any null values in + either of the columns, this would be identified in the + nulls column. + + + + When estimating the selectivity, the planner applies all the conditions + on items in the MCV list, and then sums the frequencies + of the matching ones. See mcv_clauselist_selectivity + in src/backend/statistics/mcv.c for details. + + + + Compared to functional dependencies, MCV lists have two + major advantages. Firstly, the list stores actual values, making it possible + to decide which combinations are compatible. + + +EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a = 1 AND b = 10; + QUERY PLAN +--------------------------------------------------------------------------- + Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1) + Filter: ((a = 1) AND (b = 10)) + Rows Removed by Filter: 10000 + + + Secondly, MCV lists handle a wider range of clause types, + not just equality clauses like functional dependencies. For example, + consider the following range query for the same table: + + +EXPLAIN (ANALYZE, TIMING OFF) SELECT * FROM t WHERE a <= 49 AND b > 49; + QUERY PLAN +--------------------------------------------------------------------------- + Seq Scan on t (cost=0.00..195.00 rows=1 width=8) (actual rows=0 loops=1) + Filter: ((a <= 49) AND (b > 49)) + Rows Removed by Filter: 10000 + + + + + + diff --git a/doc/src/sgml/plhandler.sgml b/doc/src/sgml/plhandler.sgml index 363f84b9f34..e1b0af7a60d 100644 --- a/doc/src/sgml/plhandler.sgml +++ b/doc/src/sgml/plhandler.sgml @@ -1,7 +1,7 @@ - Writing A Procedural Language Handler + Writing a Procedural Language Handler procedural language @@ -11,9 +11,8 @@ All calls to functions that are written in a language other than the current version 1 interface for compiled - languages (this includes functions in user-defined procedural languages, - functions written in SQL, and functions using the version 0 compiled - language interface) go through a call handler + languages (this includes functions in user-defined procedural languages + and functions written in SQL) go through a call handler function for the specific language. It is the responsibility of the call handler to execute the function in a meaningful way, such as by interpreting the supplied source text. This chapter outlines @@ -35,15 +34,15 @@ The call handler is called in the same way as any other function: It receives a pointer to a - FunctionCallInfoData struct containing + FunctionCallInfoBaseData struct containing argument values and information about the called function, and it is expected to return a Datum result (and possibly set the isnull field of the - FunctionCallInfoData structure, if it wishes + FunctionCallInfoBaseData structure, if it wishes to return an SQL null result). The difference between a call handler and an ordinary callee function is that the flinfo->fn_oid field of the - FunctionCallInfoData structure will contain + FunctionCallInfoBaseData structure will contain the OID of the actual function to be called, not of the call handler itself. The call handler must use this field to determine which function to execute. Also, the passed argument list has @@ -88,7 +87,7 @@ When a procedural-language function is invoked as a trigger, no arguments are passed in the usual way, but the - FunctionCallInfoData's + FunctionCallInfoBaseData's context field points at a TriggerData structure, rather than being NULL as it is in a plain function call. A language handler should @@ -120,7 +119,7 @@ plsample_call_handler(PG_FUNCTION_ARGS) if (CALLED_AS_TRIGGER(fcinfo)) { /* - * Called as a trigger procedure + * Called as a trigger function */ TriggerData *trigdata = (TriggerData *) fcinfo->context; diff --git a/doc/src/sgml/plperl.sgml b/doc/src/sgml/plperl.sgml index 82f56cb8abc..967efba3b55 100644 --- a/doc/src/sgml/plperl.sgml +++ b/doc/src/sgml/plperl.sgml @@ -1300,7 +1300,7 @@ $$ LANGUAGE plperl; CREATE TRIGGER test_valid_id_trig BEFORE INSERT OR UPDATE ON test - FOR EACH ROW EXECUTE PROCEDURE valid_id(); + FOR EACH ROW EXECUTE FUNCTION valid_id(); @@ -1337,7 +1337,7 @@ CREATE TRIGGER test_valid_id_trig - The return value of the trigger procedure is ignored. + The return value of the trigger function is ignored. @@ -1350,7 +1350,7 @@ $$ LANGUAGE plperl; CREATE EVENT TRIGGER perl_a_snitch ON ddl_command_start - EXECUTE PROCEDURE perlsnitch(); + EXECUTE FUNCTION perlsnitch(); diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 59f6112b07c..70bcce700ba 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -19,7 +19,7 @@ - can be used to create functions and trigger procedures, + can be used to create functions and triggers, @@ -305,10 +305,9 @@ $$ LANGUAGE plpgsql; for transaction control. PL/pgSQL's BEGIN/END are only for grouping; they do not start or end a transaction. - Functions and trigger procedures are always executed within a transaction - established by an outer query — they cannot start or commit that - transaction, since there would be no context for them to execute in. - However, a block containing an EXCEPTION clause effectively + See for information on managing + transactions in PL/pgSQL. + Also, a block containing an EXCEPTION clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction. For more about that see . @@ -579,7 +578,7 @@ $$ LANGUAGE plpgsql; function parameters. The main practical use for this is to assign a different name for variables with predetermined names, such as NEW or OLD within - a trigger procedure. + a trigger function. @@ -914,7 +913,7 @@ my_record.user_id := 20; - Executing a Command With No Result + Executing a Command with No Result For any SQL command that does not return rows, for example @@ -985,7 +984,7 @@ PERFORM create_mv('cs_session_page_requests_mv', my_query); - Executing a Query with a Single-row Result + Executing a Query with a Single-Row Result SELECT INTO @@ -1246,7 +1245,7 @@ EXECUTE format('SELECT count(*) FROM %I ' Another restriction on parameter symbols is that they only work in SELECT, INSERT, UPDATE, and - DELETE and MERGE commands. In other statement + DELETE commands. In other statement types (generically called utility statements), you must insert values textually even if they are just data values. @@ -1287,7 +1286,7 @@ EXECUTE format('SELECT count(*) FROM %I ' - Quoting Values In Dynamic Queries + Quoting Values in Dynamic Queries quote_ident @@ -1415,7 +1414,7 @@ EXECUTE 'UPDATE tbl SET ' Dynamic SQL statements can also be safely constructed using the format function (see ). For example: + linkend="functions-string-format"/>). For example: EXECUTE format('UPDATE tbl SET %I = %L ' 'WHERE key = %L', colname, newvalue, keyvalue); @@ -1486,14 +1485,6 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; the number of rows processed by the most recent SQL command - - RESULT_OID - oid - the OID of the last row inserted by the most - recent SQL command (only useful after - an INSERT command into a table having - OIDs) - PG_CONTEXT text @@ -1529,7 +1520,6 @@ GET DIAGNOSTICS integer_var = ROW_COUNT; UPDATE, INSERT, and DELETE - and MERGE statements set FOUND true if at least one row is affected, false if no row is affected. @@ -1862,19 +1852,33 @@ SELECT * FROM get_available_flightid(CURRENT_DATE); - Returning From a Procedure + Returning from a Procedure A procedure does not have a return value. A procedure can therefore end - without a RETURN statement. If - a RETURN statement is desired to exit the code early, - then NULL must be returned. Returning any other value - will result in an error. + without a RETURN statement. If you wish to use + a RETURN statement to exit the code early, write + just RETURN with no expression. - If a procedure has output parameters, then the output values can be - assigned to the parameters as if they were variables. For example: + If the procedure has output parameters, the final values of the output + parameter variables will be returned to the caller. + + + + + Calling a Procedure + + + A PL/pgSQL function, procedure, + or DO block can call a procedure + using CALL. Output parameters are handled + differently from the way that CALL works in plain + SQL. Each INOUT parameter of the procedure must + correspond to a variable in the CALL statement, and + whatever the procedure returns is assigned back to that variable after + it returns. For example: CREATE PROCEDURE triple(INOUT x int) LANGUAGE plpgsql @@ -1884,7 +1888,13 @@ BEGIN END; $$; -CALL triple(5); +DO $$ +DECLARE myvar int := 5; +BEGIN + CALL triple(myvar); + RAISE NOTICE 'myvar = %', myvar; -- prints 15 +END +$$; @@ -2409,7 +2419,7 @@ END LOOP; - Looping Through Query Results + Looping through Query Results Using a different type of FOR loop, you can iterate through @@ -2427,19 +2437,29 @@ END LOOP label ; resulting from the query and the loop body is executed for each row. Here is an example: -CREATE FUNCTION cs_refresh_mviews() RETURNS integer AS $$ +CREATE FUNCTION refresh_mviews() RETURNS integer AS $$ DECLARE mviews RECORD; BEGIN - RAISE NOTICE 'Refreshing materialized views...'; - - FOR mviews IN SELECT * FROM cs_materialized_views ORDER BY sort_key LOOP + RAISE NOTICE 'Refreshing all materialized views...'; + + FOR mviews IN + SELECT n.nspname AS mv_schema, + c.relname AS mv_name, + pg_catalog.pg_get_userbyid(c.relowner) AS owner + FROM pg_catalog.pg_class c + LEFT JOIN pg_catalog.pg_namespace n ON (n.oid = c.relnamespace) + WHERE c.relkind = 'm' + ORDER BY 1 + LOOP - -- Now "mviews" has one record from cs_materialized_views + -- Now "mviews" has one record with information about the materialized view - RAISE NOTICE 'Refreshing materialized view %s ...', quote_ident(mviews.mv_name); - EXECUTE format('TRUNCATE TABLE %I', mviews.mv_name); - EXECUTE format('INSERT INTO %I %s', mviews.mv_name, mviews.mv_query); + RAISE NOTICE 'Refreshing materialized view %.% (owner: %)...', + quote_ident(mviews.mv_schema), + quote_ident(mviews.mv_name), + quote_ident(mviews.owner); + EXECUTE format('REFRESH MATERIALIZED VIEW %I.%I', mviews.mv_schema, mviews.mv_name); END LOOP; RAISE NOTICE 'Done refreshing materialized views.'; @@ -2494,7 +2514,7 @@ END LOOP label ; - Looping Through Arrays + Looping through Arrays The FOREACH loop is much like a FOR loop, @@ -2741,7 +2761,7 @@ SELECT merge_db(1, 'dennis'); - Obtaining Information About an Error + Obtaining Information about an Error Exception handlers frequently need to identify the specific error that @@ -3197,6 +3217,10 @@ FETCH direction { FROM | IN } BACKWARD. Omitting direction is the same as specifying NEXT. + In the forms using a count, + the count can be any integer-valued + expression (unlike the SQL FETCH command, + which only allows an integer constant). direction values that require moving backward are likely to fail unless the cursor was declared or opened with the SCROLL option. @@ -3234,26 +3258,6 @@ MOVE direction { FROM | IN } < be checked to see whether there was a next row to move to. - - The direction clause can be any of the - variants allowed in the SQL - command, namely - NEXT, - PRIOR, - FIRST, - LAST, - ABSOLUTE count, - RELATIVE count, - ALL, - FORWARD count | ALL , or - BACKWARD count | ALL . - Omitting direction is the same - as specifying NEXT. - direction values that require moving - backward are likely to fail unless the cursor was declared or opened - with the SCROLL option. - - Examples: @@ -3426,7 +3430,7 @@ COMMIT; - Looping Through a Cursor's Result + Looping through a Cursor's Result There is a variant of the FOR statement that allows @@ -3496,6 +3500,20 @@ CALL transaction_test1(); + + chained transactions + in PL/pgSQL + + + + A new transaction starts out with default transaction characteristics such + as transaction isolation level. In cases where transactions are committed + in a loop, it might be desirable to start new transactions automatically + with the same characteristics as the previous one. The commands + COMMIT AND CHAIN and ROLLBACK AND + CHAIN accomplish this. + + Transaction control is only possible in CALL or DO invocations from the top level or nested @@ -3732,9 +3750,9 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id; If no condition name nor SQLSTATE is specified in a RAISE EXCEPTION command, the default is to use - RAISE_EXCEPTION (P0001). If no message - text is specified, the default is to use the condition name or - SQLSTATE as message text. + ERRCODE_RAISE_EXCEPTION (P0001). + If no message text is specified, the default is to use the condition + name or SQLSTATE as message text. @@ -3813,7 +3831,7 @@ ASSERT condition , - Trigger Procedures + Trigger Functions trigger @@ -3822,8 +3840,8 @@ ASSERT condition , PL/pgSQL can be used to define trigger - procedures on data changes or database events. - A trigger procedure is created with the CREATE FUNCTION + functions on data changes or database events. + A trigger function is created with the CREATE FUNCTION command, declaring it as a function with no arguments and a return type of trigger (for data change triggers) or event_trigger (for database event triggers). @@ -3855,7 +3873,7 @@ ASSERT condition , Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level - triggers. This variable is unassigned in statement-level triggers + triggers. This variable is null in statement-level triggers and for DELETE operations. @@ -3867,7 +3885,7 @@ ASSERT condition , Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level - triggers. This variable is unassigned in statement-level triggers + triggers. This variable is null in statement-level triggers and for INSERT operations. @@ -3963,7 +3981,7 @@ ASSERT condition , Data type integer; the number of arguments given to the trigger - procedure in the CREATE TRIGGER statement. + function in the CREATE TRIGGER statement. @@ -4042,11 +4060,11 @@ ASSERT condition , shows an example of a - trigger procedure in PL/pgSQL. + trigger function in PL/pgSQL. - A <application>PL/pgSQL</application> Trigger Procedure + A <application>PL/pgSQL</application> Trigger Function This example trigger ensures that any time a row is inserted or updated @@ -4086,7 +4104,7 @@ CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ $emp_stamp$ LANGUAGE plpgsql; CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp - FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); + FOR EACH ROW EXECUTE FUNCTION emp_stamp(); @@ -4095,11 +4113,11 @@ CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp holds a row for each insert, update, or delete that occurs. This approach can be thought of as auditing changes to a table. shows an example of an - audit trigger procedure in PL/pgSQL. + audit trigger function in PL/pgSQL. - A <application>PL/pgSQL</application> Trigger Procedure For Auditing + A <application>PL/pgSQL</application> Trigger Function for Auditing This example trigger ensures that any insert, update or delete of a row @@ -4141,7 +4159,7 @@ $emp_audit$ LANGUAGE plpgsql; CREATE TRIGGER emp_audit AFTER INSERT OR UPDATE OR DELETE ON emp - FOR EACH ROW EXECUTE PROCEDURE process_emp_audit(); + FOR EACH ROW EXECUTE FUNCTION process_emp_audit(); @@ -4156,7 +4174,7 @@ AFTER INSERT OR UPDATE OR DELETE ON emp - A <application>PL/pgSQL</application> View Trigger Procedure For Auditing + A <application>PL/pgSQL</application> View Trigger Function for Auditing This example uses a trigger on the view to make it updatable, and @@ -4220,7 +4238,7 @@ $$ LANGUAGE plpgsql; CREATE TRIGGER emp_audit INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view - FOR EACH ROW EXECUTE PROCEDURE update_emp_view(); + FOR EACH ROW EXECUTE FUNCTION update_emp_view(); @@ -4232,13 +4250,13 @@ INSTEAD OF INSERT OR UPDATE OR DELETE ON emp_view This technique is commonly used in Data Warehousing, where the tables of measured or observed data (called fact tables) might be extremely large. shows an example of a - trigger procedure in PL/pgSQL that maintains + trigger function in PL/pgSQL that maintains a summary table for a fact table in a data warehouse. - A <application>PL/pgSQL</application> Trigger Procedure For Maintaining A Summary Table + A <application>PL/pgSQL</application> Trigger Function for Maintaining a Summary Table The schema detailed here is partly based on the Grocery Store @@ -4365,7 +4383,7 @@ $maint_sales_summary_bytime$ LANGUAGE plpgsql; CREATE TRIGGER maint_sales_summary_bytime AFTER INSERT OR UPDATE OR DELETE ON sales_fact - FOR EACH ROW EXECUTE PROCEDURE maint_sales_summary_bytime(); + FOR EACH ROW EXECUTE FUNCTION maint_sales_summary_bytime(); INSERT INTO sales_fact VALUES(1,1,1,10,3,15); INSERT INTO sales_fact VALUES(1,2,1,20,5,35); @@ -4442,15 +4460,15 @@ $emp_audit$ LANGUAGE plpgsql; CREATE TRIGGER emp_audit_ins AFTER INSERT ON emp REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit(); + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); CREATE TRIGGER emp_audit_upd AFTER UPDATE ON emp REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit(); + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); CREATE TRIGGER emp_audit_del AFTER DELETE ON emp REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT EXECUTE PROCEDURE process_emp_audit(); + FOR EACH STATEMENT EXECUTE FUNCTION process_emp_audit(); @@ -4462,7 +4480,7 @@ CREATE TRIGGER emp_audit_del PL/pgSQL can be used to define event triggers. - PostgreSQL requires that a procedure that + PostgreSQL requires that a function that is to be called as an event trigger must be declared as a function with no arguments and a return type of event_trigger. @@ -4497,11 +4515,11 @@ CREATE TRIGGER emp_audit_del shows an example of an - event trigger procedure in PL/pgSQL. + event trigger function in PL/pgSQL. - A <application>PL/pgSQL</application> Event Trigger Procedure + A <application>PL/pgSQL</application> Event Trigger Function This example trigger simply raises a NOTICE message @@ -4515,7 +4533,7 @@ BEGIN END; $$ LANGUAGE plpgsql; -CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE PROCEDURE snitch(); +CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE FUNCTION snitch(); @@ -4523,7 +4541,7 @@ CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE PROCEDURE snitch(); - <application>PL/pgSQL</application> Under the Hood + <application>PL/pgSQL</application> under the Hood This section discusses some implementation details that are @@ -5051,7 +5069,7 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ - Additional Compile-time Checks + Additional Compile-Time and Run-Time Checks To aid the user in finding instances of simple but common problems before @@ -5063,26 +5081,64 @@ a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$ so you are advised to test in a separate development environment. - - These additional checks are enabled through the configuration variables - plpgsql.extra_warnings for warnings and - plpgsql.extra_errors for errors. Both can be set either to - a comma-separated list of checks, "none" or "all". - The default is "none". Currently the list of available checks - includes only one: - - - shadowed_variables - - - Checks if a declaration shadows a previously defined variable. - - - - + + Setting plpgsql.extra_warnings, or + plpgsql.extra_errors, as appropriate, to "all" + is encouraged in development and/or testing environments. + + + + These additional checks are enabled through the configuration variables + plpgsql.extra_warnings for warnings and + plpgsql.extra_errors for errors. Both can be set either to + a comma-separated list of checks, "none" or + "all". The default is "none". Currently + the list of available checks includes: + + + shadowed_variables + + + Checks if a declaration shadows a previously defined variable. + + + + + + strict_multi_assignment + + + Some PL/PgSQL commands allow assigning + values to more than one variable at a time, such as + SELECT INTO. Typically, the number of target + variables and the number of source variables should match, though + PL/PgSQL will use NULL + for missing values and extra variables are ignored. Enabling this + check will cause PL/PgSQL to throw a + WARNING or ERROR whenever the + number of target variables and the number of source variables are + different. + + + + + + too_many_rows + + + Enabling this check will cause PL/PgSQL to + check if a given query returns more than one row when an + INTO clause is used. As an INTO + statement will only ever use one row, having a query return multiple + rows is generally either inefficient and/or nondeterministic and + therefore is likely an error. + + + + - The following example shows the effect of plpgsql.extra_warnings - set to shadowed_variables: + The following example shows the effect of plpgsql.extra_warnings + set to shadowed_variables: SET plpgsql.extra_warnings TO 'shadowed_variables'; @@ -5098,8 +5154,41 @@ LINE 3: f1 int; ^ CREATE FUNCTION - - + The below example shows the effects of setting + plpgsql.extra_warnings to + strict_multi_assignment: + +SET plpgsql.extra_warnings TO 'strict_multi_assignment'; + +CREATE OR REPLACE FUNCTION public.foo() + RETURNS void + LANGUAGE plpgsql +AS $$ +DECLARE + x int; + y int; +BEGIN + SELECT 1 INTO x, y; + SELECT 1, 2 INTO x, y; + SELECT 1, 2, 3 INTO x, y; +END; +$$; + +SELECT foo(); +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. + + foo +----- + +(1 row) + + + @@ -5128,7 +5217,7 @@ CREATE FUNCTION PL/pgSQL is similar to PL/SQL in many aspects. It is a block-structured, imperative language, and all - variables have to be declared. Assignments, loops, conditionals + variables have to be declared. Assignments, loops, and conditionals are similar. The main differences you should keep in mind when porting from PL/SQL to PL/pgSQL are: @@ -5547,7 +5636,7 @@ BEGIN INSERT INTO cs_active_job(job_id) VALUES (v_job_id); BEGIN - INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, sysdate); + INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now()); EXCEPTION WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists END; diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml index de383272427..31458e71a89 100644 --- a/doc/src/sgml/plpython.sgml +++ b/doc/src/sgml/plpython.sgml @@ -9,7 +9,7 @@ The PL/Python procedural language allows PostgreSQL functions to be written in the - Python language. + Python language. @@ -89,7 +89,7 @@ This scheme is analogous to the recommendations in PEP 394 regarding the + url="https://www.python.org/dev/peps/pep-0394/">PEP 394 regarding the naming and transitioning of the python command. @@ -165,7 +165,7 @@ See also the - document What's + document What's New In Python 3.0 for more information about porting to Python 3. @@ -665,7 +665,7 @@ CALL python_triple(5, 10); - Set-returning Functions + Set-Returning Functions A PL/Python function can also return sets of scalar or composite types. There are several ways to achieve this because @@ -768,9 +768,9 @@ SELECT * FROM multiout_simple_setof(3); Sharing Data The global dictionary SD is available to store - data between function calls. This variable is private static data. + private data between repeated calls to the same function. The global dictionary GD is public data, - available to all Python functions within a session. Use with + that is available to all Python functions within a session; use with care.global data in PL/Python @@ -1116,7 +1116,7 @@ $$ LANGUAGE plpythonu; batch of rows, never larger than the parameter value. Once all rows are exhausted, fetch starts returning an empty result object. Cursor objects also provide an - iterator + iterator interface, yielding one row at a time until all rows are exhausted. Data fetched that way is not returned as result objects, but rather as dictionaries, each dictionary corresponding to a single result @@ -1167,7 +1167,7 @@ $$ LANGUAGE plpythonu; Do not confuse objects created by plpy.cursor with DB-API cursors as defined by - the Python + the Python Database API specification. They don't have anything in common except for the name. @@ -1297,7 +1297,7 @@ $$ LANGUAGE plpythonu; helper object to manage explicit subtransactions that gets created with the plpy.subtransaction() function. Objects created by this function implement the - + context manager interface. Using explicit subtransactions we can rewrite our function as: @@ -1373,7 +1373,7 @@ $$ LANGUAGE plpythonu; Although context managers were implemented in Python 2.5, to use the with syntax in that version you need to use a future + url="https://docs.python.org/release/2.5/ref/future.html">future statement. Because of implementation details, however, you cannot use future statements in PL/Python functions. diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml index 01f6207d363..7ff828de700 100644 --- a/doc/src/sgml/pltcl.sgml +++ b/doc/src/sgml/pltcl.sgml @@ -15,8 +15,8 @@ PL/Tcl is a loadable procedural language for the PostgreSQL database system that enables the - Tcl language to be used to write functions and - trigger procedures. + Tcl language to be used to write + PostgreSQL functions. @@ -470,24 +470,6 @@ $$ LANGUAGE pltcl; - - - spi_lastoid - - spi_lastoid - in PL/Tcl - - - - - Returns the OID of the row inserted by the last - spi_exec or spi_execp, if the - command was a single-row INSERT and the modified - table contained OIDs. (If not, you get zero.) - - - - subtransaction command @@ -587,7 +569,7 @@ SELECT 'doesn''t' AS ret - Trigger Procedures in PL/Tcl + Trigger Functions in PL/Tcl trigger @@ -595,13 +577,13 @@ SELECT 'doesn''t' AS ret - Trigger procedures can be written in PL/Tcl. - PostgreSQL requires that a procedure that is to be called + Trigger functions can be written in PL/Tcl. + PostgreSQL requires that a function that is to be called as a trigger must be declared as a function with no arguments and a return type of trigger. - The information from the trigger manager is passed to the procedure body + The information from the trigger manager is passed to the function body in the following variables: @@ -619,7 +601,7 @@ SELECT 'doesn''t' AS ret $TG_relid - The object ID of the table that caused the trigger procedure + The object ID of the table that caused the trigger function to be invoked. @@ -629,7 +611,7 @@ SELECT 'doesn''t' AS ret $TG_table_name - The name of the table that caused the trigger procedure + The name of the table that caused the trigger function to be invoked. @@ -639,7 +621,7 @@ SELECT 'doesn''t' AS ret $TG_table_schema - The schema of the table that caused the trigger procedure + The schema of the table that caused the trigger function to be invoked. @@ -722,9 +704,9 @@ SELECT 'doesn''t' AS ret $args - A Tcl list of the arguments to the procedure as given in the + A Tcl list of the arguments to the function as given in the CREATE TRIGGER statement. These arguments are also accessible as - $1 ... $n in the procedure body. + $1 ... $n in the function body. @@ -733,7 +715,7 @@ SELECT 'doesn''t' AS ret - The return value from a trigger procedure can be one of the strings + The return value from a trigger function can be one of the strings OK or SKIP, or a list of column name/value pairs. If the return value is OK, the operation (INSERT/UPDATE/DELETE) @@ -764,7 +746,7 @@ SELECT 'doesn''t' AS ret - Here's a little example trigger procedure that forces an integer value + Here's a little example trigger function that forces an integer value in a table to keep track of the number of updates that are performed on the row. For new rows inserted, the value is initialized to 0 and then incremented on every update operation. @@ -789,17 +771,17 @@ $$ LANGUAGE pltcl; CREATE TABLE mytab (num integer, description text, modcnt integer); CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - FOR EACH ROW EXECUTE PROCEDURE trigfunc_modcount('modcnt'); + FOR EACH ROW EXECUTE FUNCTION trigfunc_modcount('modcnt'); - Notice that the trigger procedure itself does not know the column + Notice that the trigger function itself does not know the column name; that's supplied from the trigger arguments. This lets the - trigger procedure be reused with different tables. + trigger function be reused with different tables. - Event Trigger Procedures in PL/Tcl + Event Trigger Functions in PL/Tcl event trigger @@ -807,13 +789,13 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - Event trigger procedures can be written in PL/Tcl. - PostgreSQL requires that a procedure that is + Event trigger functions can be written in PL/Tcl. + PostgreSQL requires that a function that is to be called as an event trigger must be declared as a function with no arguments and a return type of event_trigger. - The information from the trigger manager is passed to the procedure body + The information from the trigger manager is passed to the function body in the following variables: @@ -839,11 +821,11 @@ CREATE TRIGGER trig_mytab_modcount BEFORE INSERT OR UPDATE ON mytab - The return value of the trigger procedure is ignored. + The return value of the trigger function is ignored. - Here's a little example event trigger procedure that simply raises + Here's a little example event trigger function that simply raises a NOTICE message each time a supported command is executed: @@ -852,7 +834,7 @@ CREATE OR REPLACE FUNCTION tclsnitch() RETURNS event_trigger AS $$ elog NOTICE "tclsnitch: $TG_event $TG_tag" $$ LANGUAGE pltcl; -CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE PROCEDURE tclsnitch(); +CREATE EVENT TRIGGER tcl_a_snitch ON ddl_command_start EXECUTE FUNCTION tclsnitch(); diff --git a/doc/src/sgml/postgres-fdw.sgml b/doc/src/sgml/postgres-fdw.sgml index 54b5e98a0e3..634a7141ef1 100644 --- a/doc/src/sgml/postgres-fdw.sgml +++ b/doc/src/sgml/postgres-fdw.sgml @@ -74,6 +74,11 @@ UPDATE clause. However, the ON CONFLICT DO NOTHING clause is supported, provided a unique index inference specification is omitted. + Note also that postgres_fdw supports row movement + invoked by UPDATE statements executed on partitioned + tables, but it currently does not handle the case where a remote partition + chosen to insert a moved row into is also an UPDATE + target partition that will be updated later. @@ -499,9 +504,9 @@ sending the whole query to the remote server if there are no query WHERE clauses that cannot be sent to the remote server, no local joins for the query, no row-level local BEFORE or - AFTER triggers on the target table, and no - CHECK OPTION constraints from parent views. - In UPDATE, + AFTER triggers or stored generated columns on the target + table, and no CHECK OPTION constraints from parent + views. In UPDATE, expressions to assign to target columns must use only built-in data types, IMMUTABLE operators, or IMMUTABLE functions, to reduce the risk of misexecution of the query. @@ -544,7 +549,7 @@ postgres_fdw likewise establishes remote session settings - for various parameters: + for various parameters: diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml index 0070603fc36..e59cba79975 100644 --- a/doc/src/sgml/postgres.sgml +++ b/doc/src/sgml/postgres.sgml @@ -1,7 +1,7 @@ - @@ -158,7 +158,6 @@ &maintenance; &backup; &high-availability; - &recovery-config; &monitoring; &diskusage; &wal; @@ -251,6 +250,7 @@ &tablesample-method; &custom-scan; &geqo; + &tableam; &indexam; &generic-wal; &btree; @@ -276,6 +276,7 @@ &external-projects; &sourcerepo; &docguide; + &limits; &acronyms; diff --git a/doc/src/sgml/problems.sgml b/doc/src/sgml/problems.sgml index 7d14789e51a..cf432628721 100644 --- a/doc/src/sgml/problems.sgml +++ b/doc/src/sgml/problems.sgml @@ -252,7 +252,7 @@ C library, processor, memory information, and so on. In most cases it is sufficient to report the vendor and version, but do not assume everyone knows what exactly Debian - contains or that everyone runs on i386s. If you have + contains or that everyone runs on x86_64. If you have installation problems then information about the toolchain on your machine (compiler, make, and so on) is also necessary. @@ -264,7 +264,7 @@ It is better to report everything the first time than us having to squeeze the facts out of you. On the other hand, if your input files are huge, it is fair to ask first whether somebody is interested in looking into it. Here is - an article + an article that outlines some more tips on reporting bugs. @@ -296,7 +296,7 @@ In general, send bug reports to the bug report mailing list at - pgsql-bugs@postgresql.org. + pgsql-bugs@lists.postgresql.org. You are requested to use a descriptive subject for your email message, perhaps parts of the error message. @@ -306,7 +306,7 @@ at the project's web site. Entering a bug report this way causes it to be mailed to the - pgsql-bugs@postgresql.org mailing list. + pgsql-bugs@lists.postgresql.org mailing list. @@ -318,8 +318,8 @@ Do not send bug reports to any of the user mailing lists, such as - pgsql-sql@postgresql.org or - pgsql-general@postgresql.org. + pgsql-sql@lists.postgresql.org or + pgsql-general@lists.postgresql.org. These mailing lists are for answering user questions, and their subscribers normally do not wish to receive bug reports. More importantly, they are unlikely to fix them. @@ -327,7 +327,7 @@ Also, please do not send reports to - the developers' mailing list pgsql-hackers@postgresql.org. + the developers' mailing list pgsql-hackers@lists.postgresql.org. This list is for discussing the development of PostgreSQL, and it would be nice if we could keep the bug reports separate. We might choose to take up a @@ -337,14 +337,14 @@ If you have a problem with the documentation, the best place to report it - is the documentation mailing list pgsql-docs@postgresql.org. + is the documentation mailing list pgsql-docs@lists.postgresql.org. Please be specific about what part of the documentation you are unhappy with. If your bug is a portability problem on a non-supported platform, - send mail to pgsql-hackers@postgresql.org, + send mail to pgsql-hackers@lists.postgresql.org, so we (and you) can work on porting PostgreSQL to your platform. @@ -352,14 +352,10 @@ Due to the unfortunate amount of spam going around, all of the above - email addresses are closed mailing lists. That is, you need to be - subscribed to a list to be allowed to post on it. (You need not be - subscribed to use the bug-report web form, however.) - If you would like to send mail but do not want to receive list traffic, - you can subscribe and set your subscription option to nomail. - For more information send mail to - majordomo@postgresql.org - with the single word help in the body of the message. + lists will be moderated unless you are subscribed. That means there + will be some delay before the email is delivered. If you wish to subscribe + to the lists, please visit + for instructions. diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml index 004b36084f1..80275215e04 100644 --- a/doc/src/sgml/protocol.sgml +++ b/doc/src/sgml/protocol.sgml @@ -811,7 +811,7 @@ BEGIN; INSERT INTO mytable VALUES(1); COMMIT; INSERT INTO mytable VALUES(2); -SELCT 1/0; +SELECT 1/0; then none of the statements would get run, resulting in the visible difference that the first INSERT is not committed. @@ -1479,6 +1479,75 @@ SELCT 1/0; of authentication checking. + + + <acronym>GSSAPI</acronym> Session Encryption + + + If PostgreSQL was built with + GSSAPI support, frontend/backend communications + can be encrypted using GSSAPI. This provides + communication security in environments where attackers might be + able to capture the session traffic. For more information on + encrypting PostgreSQL sessions with + GSSAPI, see . + + + + To initiate a GSSAPI-encrypted connection, the + frontend initially sends a GSSENCRequest message rather than a + StartupMessage. The server then responds with a single byte + containing G or N, indicating that it + is willing or unwilling to perform GSSAPI encryption, + respectively. The frontend might close the connection at this point + if it is dissatisfied with the response. To continue after + G, using the GSSAPI C bindings as discussed in RFC2744 + or equivalent, perform a GSSAPI initialization by + calling gss_init_sec_context() in a loop and sending + the result to the server, starting with an empty input and then with each + result from the server, until it returns no output. When sending the + results of gss_init_sec_context() to the server, + prepend the length of the message as a four byte integer in network byte + order. If this is successful, then use gss_wrap() to + encrypt the usual StartupMessage and all subsequent data, prepending the + length of the result from gss_wrap() as a four byte + integer in network byte order to the actual encrypted payload. Note that + the server will only accept encrypted packets from the client which are less + than 16kB; gss_wrap_size_limit() should be used by the + client to determine the size of the unencrypted message which will fit + within this limit and larger messages should be broken up into multiple + gss_wrap() calls. Typical segments are 8kB of + unencrypted data, resulting in encrypted packets of slightly larger than 8kB + but well within the 16kB maximum. The server can be expected to not send + encrypted packets of larger than 16kB to the client. To continue after + N, send the usual StartupMessage and proceed without + encryption. + + + + The frontend should also be prepared to handle an ErrorMessage + response to GSSENCRequest from the server. This would only occur if + the server predates the addition of GSSAPI encryption + support to PostgreSQL. In this case the + connection must be closed, but the frontend might choose to open a fresh + connection and proceed without requesting GSSAPI + encryption. Given the length limits specified above, the ErrorMessage can + not be confused with a proper response from the server with an appropriate + length. + + + + An initial GSSENCRequest can also be used in a connection that is being + opened to send a CancelRequest message. + + + + While the protocol itself does not provide a way for the server to + force GSSAPI encryption, the administrator can + configure the server to reject unencrypted sessions as a byproduct + of authentication checking. + + @@ -1541,7 +1610,7 @@ ErrorMessage. - SCRAM-SHA-256 authentication + SCRAM-SHA-256 Authentication The implemented SASL mechanisms at the moment @@ -1576,12 +1645,27 @@ the password is in. Channel binding is supported in PostgreSQL builds with SSL support. The SASL mechanism name for SCRAM with channel binding is -SCRAM-SHA-256-PLUS. Two channel binding types are -supported: tls-unique and -tls-server-end-point, both defined in RFC 5929. Clients -should use tls-unique if they can support it. -tls-server-end-point is intended for third-party clients -that cannot support tls-unique for some reason. +SCRAM-SHA-256-PLUS. The channel binding type used by +PostgreSQL is tls-server-end-point. + + + + In SCRAM without channel binding, the server chooses + a random number that is transmitted to the client to be mixed with the + user-supplied password in the transmitted password hash. While this + prevents the password hash from being successfully retransmitted in + a later session, it does not prevent a fake server between the real + server and client from passing through the server's random value + and successfully authenticating. + + + + SCRAM with channel binding prevents such + man-in-the-middle attacks by mixing the signature of the server's + certificate into the transmitted password hash. While a fake server can + retransmit the real server's certificate, it doesn't have access to the + private key matching that certificate, and therefore cannot prove it is + the owner, causing SSL connection failure. @@ -1610,7 +1694,7 @@ that cannot support tls-unique for some reason. Server sends an AuthenticationSASLContinue message, with a SCRAM - server-first message as the content. + server-first-message as the content. @@ -2531,8 +2615,8 @@ The commands accepted in replication mode are: size (int8) - The approximate size of the tablespace, if progress report has - been requested; otherwise it's null. + The approximate size of the tablespace, in kilobytes (1024 bytes), + if progress report has been requested; otherwise it's null. @@ -3822,10 +3906,11 @@ CommandComplete (B) INSERT oid rows, where rows is the number of rows - inserted. oid is the object ID - of the inserted row if rows is 1 - and the target table has OIDs; - otherwise oid is 0. + inserted. oid used to be the object ID + of the inserted row if rows was 1 + and the target table had OIDs, but OIDs system columns are + not supported anymore; therefore oid + is always 0. @@ -5698,6 +5783,43 @@ SSLRequest (F) + + +GSSENCRequest (F) + + + + + + + + Int32(8) + + + + Length of message contents in bytes, including self. + + + + + + Int32(80877104) + + + + The GSSAPI Encryption request code. The value is chosen to contain + 1234 in the most significant 16 bits, and 5680 in the + least significant 16 bits. (To avoid confusion, this code + must not be the same as any protocol version number.) + + + + + + + + + @@ -6434,7 +6556,7 @@ Relation - Next, the following message part appears for each column: + Next, the following message part appears for each column (except generated columns): @@ -6746,7 +6868,7 @@ Delete Identifies the following TupleData message as a old tuple. - This field is is present if the table in which the delete has + This field is present if the table in which the delete has happened has REPLICA IDENTITY set to FULL. @@ -6859,7 +6981,7 @@ TupleData - Next, one of the following submessages appears for each column: + Next, one of the following submessages appears for each column (except generated columns): diff --git a/doc/src/sgml/queries.sgml b/doc/src/sgml/queries.sgml index b72be9bf716..22252556be2 100644 --- a/doc/src/sgml/queries.sgml +++ b/doc/src/sgml/queries.sgml @@ -1981,6 +1981,10 @@ GROUP BY region, product; + + RECURSIVE + in common table expressions + The optional RECURSIVE modifier changes WITH from a mere syntactic convenience into a feature that accomplishes things not otherwise possible in standard SQL. Using @@ -2195,22 +2199,94 @@ SELECT n FROM t LIMIT 100; - A useful property of WITH queries is that they are evaluated - only once per execution of the parent query, even if they are referred to - more than once by the parent query or sibling WITH queries. + A useful property of WITH queries is that they are + normally evaluated only once per execution of the parent query, even if + they are referred to more than once by the parent query or + sibling WITH queries. Thus, expensive calculations that are needed in multiple places can be placed within a WITH query to avoid redundant work. Another possible application is to prevent unwanted multiple evaluations of functions with side-effects. - However, the other side of this coin is that the optimizer is less able to - push restrictions from the parent query down into a WITH query - than an ordinary subquery. The WITH query will generally be + However, the other side of this coin is that the optimizer is not able to + push restrictions from the parent query down into a multiply-referenced + WITH query, since that might affect all uses of the + WITH query's output when it should affect only one. + The multiply-referenced WITH query will be evaluated as written, without suppression of rows that the parent query might discard afterwards. (But, as mentioned above, evaluation might stop early if the reference(s) to the query demand only a limited number of rows.) + + However, if a WITH query is non-recursive and + side-effect-free (that is, it is a SELECT containing + no volatile functions) then it can be folded into the parent query, + allowing joint optimization of the two query levels. By default, this + happens if the parent query references the WITH query + just once, but not if it references the WITH query + more than once. You can override that decision by + specifying MATERIALIZED to force separate calculation + of the WITH query, or by specifying NOT + MATERIALIZED to force it to be merged into the parent query. + The latter choice risks duplicate computation of + the WITH query, but it can still give a net savings if + each usage of the WITH query needs only a small part + of the WITH query's full output. + + + + A simple example of these rules is + +WITH w AS ( + SELECT * FROM big_table +) +SELECT * FROM w WHERE key = 123; + + This WITH query will be folded, producing the same + execution plan as + +SELECT * FROM big_table WHERE key = 123; + + In particular, if there's an index on key, + it will probably be used to fetch just the rows having key = + 123. On the other hand, in + +WITH w AS ( + SELECT * FROM big_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref +WHERE w2.key = 123; + + the WITH query will be materialized, producing a + temporary copy of big_table that is then + joined with itself — without benefit of any index. This query + will be executed much more efficiently if written as + +WITH w AS NOT MATERIALIZED ( + SELECT * FROM big_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.key = w2.ref +WHERE w2.key = 123; + + so that the parent query's restrictions can be applied directly + to scans of big_table. + + + + An example where NOT MATERIALIZED could be + undesirable is + +WITH w AS ( + SELECT key, very_expensive_function(val) as f FROM some_table +) +SELECT * FROM w AS w1 JOIN w AS w2 ON w1.f = w2.f; + + Here, materialization of the WITH query ensures + that very_expensive_function is evaluated only + once per table row, not twice. + + The examples above only show WITH being used with SELECT, but it can be attached in the same way to diff --git a/doc/src/sgml/recovery-config.sgml b/doc/src/sgml/recovery-config.sgml deleted file mode 100644 index 92825fdf192..00000000000 --- a/doc/src/sgml/recovery-config.sgml +++ /dev/null @@ -1,509 +0,0 @@ - - - - Recovery Configuration - - - configuration - of recovery - of a standby server - - - - This chapter describes the settings available in the - recovery.confrecovery.conf - file. They apply only for the duration of the - recovery. They must be reset for any subsequent recovery you wish to - perform. They cannot be changed once recovery has begun. - - - - Settings in recovery.conf are specified in the format - name = 'value'. One parameter is specified per line. - Hash marks (#) designate the rest of the - line as a comment. To embed a single quote in a parameter - value, write two quotes (''). - - - - A sample file, share/recovery.conf.sample, - is provided in the installation's share/ directory. - - - - - Archive Recovery Settings - - - - restore_command (string) - - restore_command recovery parameter - - - - - The local shell command to execute to retrieve an archived segment of - the WAL file series. This parameter is required for archive recovery, - but optional for streaming replication. - Any %f in the string is - replaced by the name of the file to retrieve from the archive, - and any %p is replaced by the copy destination path name - on the server. - (The path name is relative to the current working directory, - i.e., the cluster's data directory.) - Any %r is replaced by the name of the file containing the - last valid restart point. That is the earliest file that must be kept - to allow a restore to be restartable, so this information can be used - to truncate the archive to just the minimum required to support - restarting from the current restore. %r is typically only - used by warm-standby configurations - (see ). - Write %% to embed an actual % character. - - - - It is important for the command to return a zero exit status - only if it succeeds. The command will be asked for file - names that are not present in the archive; it must return nonzero - when so asked. Examples: - -restore_command = 'cp /mnt/server/archivedir/%f "%p"' -restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows - - An exception is that if the command was terminated by a signal (other - than SIGTERM, which is used as part of a - database server shutdown) or an error by the shell (such as command - not found), then recovery will abort and the server will not start up. - - - - - - archive_cleanup_command (string) - - archive_cleanup_command recovery parameter - - - - - This optional parameter specifies a shell command that will be executed - at every restartpoint. The purpose of - archive_cleanup_command is to provide a mechanism for - cleaning up old archived WAL files that are no longer needed by the - standby server. - Any %r is replaced by the name of the file containing the - last valid restart point. - That is the earliest file that must be kept to allow a - restore to be restartable, and so all files earlier than %r - may be safely removed. - This information can be used to truncate the archive to just the - minimum required to support restart from the current restore. - The module - is often used in archive_cleanup_command for - single-standby configurations, for example: -archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' - Note however that if multiple standby servers are restoring from the - same archive directory, you will need to ensure that you do not delete - WAL files until they are no longer needed by any of the servers. - archive_cleanup_command would typically be used in a - warm-standby configuration (see ). - Write %% to embed an actual % character in the - command. - - - If the command returns a nonzero exit status then a warning log - message will be written. An exception is that if the command was - terminated by a signal or an error by the shell (such as command not - found), a fatal error will be raised. - - - - - - recovery_end_command (string) - - recovery_end_command recovery parameter - - - - - This parameter specifies a shell command that will be executed once only - at the end of recovery. This parameter is optional. The purpose of the - recovery_end_command is to provide a mechanism for cleanup - following replication or recovery. - Any %r is replaced by the name of the file containing the - last valid restart point, like in . - - - If the command returns a nonzero exit status then a warning log - message will be written and the database will proceed to start up - anyway. An exception is that if the command was terminated by a - signal or an error by the shell (such as command not found), the - database will not proceed with startup. - - - - - - - - - - - Recovery Target Settings - - - By default, recovery will recover to the end of the WAL log. The - following parameters can be used to specify an earlier stopping point. - At most one of recovery_target, - recovery_target_lsn, recovery_target_name, - recovery_target_time, or recovery_target_xid - can be used; if more than one of these is specified in the configuration - file, the last entry will be used. - - - - - recovery_target = 'immediate' - - recovery_target recovery parameter - - - - - This parameter specifies that recovery should end as soon as a - consistent state is reached, i.e. as early as possible. When restoring - from an online backup, this means the point where taking the backup - ended. - - - Technically, this is a string parameter, but 'immediate' - is currently the only allowed value. - - - - - - recovery_target_name (string) - - recovery_target_name recovery parameter - - - - - This parameter specifies the named restore point (created with - pg_create_restore_point()) to which recovery will proceed. - - - - - - recovery_target_time (timestamp) - - recovery_target_time recovery parameter - - - - - This parameter specifies the time stamp up to which recovery - will proceed. - The precise stopping point is also influenced by - . - - - - - - recovery_target_xid (string) - - recovery_target_xid recovery parameter - - - - - This parameter specifies the transaction ID up to which recovery - will proceed. Keep in mind - that while transaction IDs are assigned sequentially at transaction - start, transactions can complete in a different numeric order. - The transactions that will be recovered are those that committed - before (and optionally including) the specified one. - The precise stopping point is also influenced by - . - - - - - - recovery_target_lsn (pg_lsn) - - recovery_target_lsn recovery parameter - - - - - This parameter specifies the LSN of the write-ahead log location up - to which recovery will proceed. The precise stopping point is also - influenced by . This - parameter is parsed using the system data type - pg_lsn. - - - - - - - The following options further specify the recovery target, and affect - what happens when the target is reached: - - - - - recovery_target_inclusive (boolean) - - recovery_target_inclusive recovery parameter - - - - - Specifies whether to stop just after the specified recovery target - (true), or just before the recovery target - (false). - Applies when , - , or - is specified. - This setting controls whether transactions - having exactly the target WAL location (LSN), commit time, or transaction ID, respectively, will - be included in the recovery. Default is true. - - - - - - recovery_target_timeline (string) - - recovery_target_timeline recovery parameter - - - - - Specifies recovering into a particular timeline. The default is - to recover along the same timeline that was current when the - base backup was taken. Setting this to latest recovers - to the latest timeline found in the archive, which is useful in - a standby server. Other than that you only need to set this parameter - in complex re-recovery situations, where you need to return to - a state that itself was reached after a point-in-time recovery. - See for discussion. - - - - - - recovery_target_action (enum) - - recovery_target_action recovery parameter - - - - - Specifies what action the server should take once the recovery target is - reached. The default is pause, which means recovery will - be paused. promote means the recovery process will finish - and the server will start to accept connections. - Finally shutdown will stop the server after reaching the - recovery target. - - - The intended use of the pause setting is to allow queries - to be executed against the database to check if this recovery target - is the most desirable point for recovery. - The paused state can be resumed by - using pg_wal_replay_resume() (see - ), which then - causes recovery to end. If this recovery target is not the - desired stopping point, then shut down the server, change the - recovery target settings to a later target and restart to - continue recovery. - - - The shutdown setting is useful to have the instance ready - at the exact replay point desired. The instance will still be able to - replay more WAL records (and in fact will have to replay WAL records - since the last checkpoint next time it is started). - - - Note that because recovery.conf will not be renamed when - recovery_target_action is set to shutdown, - any subsequent start will end with immediate shutdown unless the - configuration is changed or the recovery.conf file is - removed manually. - - - This setting has no effect if no recovery target is set. - If is not enabled, a setting of - pause will act the same as shutdown. - - - - - - - - - - Standby Server Settings - - - - standby_mode (boolean) - - standby_mode recovery parameter - - - - - Specifies whether to start the PostgreSQL server as - a standby. If this parameter is on, the server will - not stop recovery when the end of archived WAL is reached, but - will keep trying to continue recovery by fetching new WAL segments - using restore_command - and/or by connecting to the primary server as specified by the - primary_conninfo setting. - - - - - primary_conninfo (string) - - primary_conninfo recovery parameter - - - - - Specifies a connection string to be used for the standby server - to connect with the primary. This string is in the format - described in . If any option is - unspecified in this string, then the corresponding environment - variable (see ) is checked. If the - environment variable is not set either, then - defaults are used. - - - The connection string should specify the host name (or address) - of the primary server, as well as the port number if it is not - the same as the standby server's default. - Also specify a user name corresponding to a suitably-privileged role - on the primary (see - ). - A password needs to be provided too, if the primary demands password - authentication. It can be provided in the - primary_conninfo string, or in a separate - ~/.pgpass file on the standby server (use - replication as the database name). - Do not specify a database name in the - primary_conninfo string. - - - This setting has no effect if standby_mode is off. - - - - - primary_slot_name (string) - - primary_slot_name recovery parameter - - - - - Optionally specifies an existing replication slot to be used when - connecting to the primary via streaming replication to control - resource removal on the upstream node - (see ). - This setting has no effect if primary_conninfo is not - set. - - - - - trigger_file (string) - - trigger_file recovery parameter - - - - - Specifies a trigger file whose presence ends recovery in the - standby. Even if this value is not set, you can still promote - the standby using pg_ctl promote. - This setting has no effect if standby_mode is off. - - - - - - recovery_min_apply_delay (integer) - - recovery_min_apply_delay recovery parameter - - - - - By default, a standby server restores WAL records from the - primary as soon as possible. It may be useful to have a time-delayed - copy of the data, offering opportunities to correct data loss errors. - This parameter allows you to delay recovery by a fixed period of time, - measured in milliseconds if no unit is specified. For example, if - you set this parameter to 5min, the standby will - replay each transaction commit only when the system time on the standby - is at least five minutes past the commit time reported by the master. - - - It is possible that the replication delay between servers exceeds the - value of this parameter, in which case no delay is added. - Note that the delay is calculated between the WAL time stamp as written - on master and the current time on the standby. Delays in transfer - because of network lag or cascading replication configurations - may reduce the actual wait time significantly. If the system - clocks on master and standby are not synchronized, this may lead to - recovery applying records earlier than expected; but that is not a - major issue because useful settings of this parameter are much larger - than typical time deviations between servers. - - - The delay occurs only on WAL records for transaction commits. - Other records are replayed as quickly as possible, which - is not a problem because MVCC visibility rules ensure their effects - are not visible until the corresponding commit record is applied. - - - The delay occurs once the database in recovery has reached a consistent - state, until the standby is promoted or triggered. After that the standby - will end recovery without further waiting. - - - This parameter is intended for use with streaming replication deployments; - however, if the parameter is specified it will be honored in all cases. - - hot_standby_feedback will be delayed by use of this feature - which could lead to bloat on the master; use both together with care. - - - - Synchronous replication is affected by this setting when synchronous_commit - is set to remote_apply; every COMMIT - will need to wait to be applied. - - - - - - - - - - diff --git a/doc/src/sgml/ref/abort.sgml b/doc/src/sgml/ref/abort.sgml index 21799d2a83f..03729133651 100644 --- a/doc/src/sgml/ref/abort.sgml +++ b/doc/src/sgml/ref/abort.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -ABORT [ WORK | TRANSACTION ] +ABORT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] @@ -51,6 +51,18 @@ ABORT [ WORK | TRANSACTION ] + + + AND CHAIN + + + If AND CHAIN is specified, a new transaction is + immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, + no new transaction is started. + + + diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml index 7cd6ee85dc9..8d91f3529e6 100644 --- a/doc/src/sgml/ref/allfiles.sgml +++ b/doc/src/sgml/ref/allfiles.sgml @@ -159,7 +159,6 @@ Complete list of usable sgml source files in this directory. - @@ -200,6 +199,7 @@ Complete list of usable sgml source files in this directory. + @@ -211,7 +211,6 @@ Complete list of usable sgml source files in this directory. - diff --git a/doc/src/sgml/ref/alter_default_privileges.sgml b/doc/src/sgml/ref/alter_default_privileges.sgml index 0c09f1db5cd..583f65fad6c 100644 --- a/doc/src/sgml/ref/alter_default_privileges.sgml +++ b/doc/src/sgml/ref/alter_default_privileges.sgml @@ -112,7 +112,7 @@ REVOKE [ GRANT OPTION FOR ] - As explained under , + As explained in , the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to PUBLIC as well. However, this behavior can be changed by @@ -173,9 +173,8 @@ REVOKE [ GRANT OPTION FOR ] Use 's \ddp command to obtain information about existing assignments of default privileges. - The meaning of the privilege values is the same as explained for - \dp under - . + The meaning of the privilege display is the same as explained for + \dp in . diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 85253e209b0..8201cbb65fc 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -118,8 +118,8 @@ ALTER DOMAIN name This form validates a constraint previously added as - NOT VALID, that is, verify that all data in columns using the - domain satisfy the specified constraint. + NOT VALID, that is, it verifies that all values in + table columns of the domain type satisfy the specified constraint. @@ -202,7 +202,7 @@ ALTER DOMAIN name NOT VALID - Do not verify existing column data for constraint validity. + Do not verify existing stored data for constraint validity. @@ -272,6 +272,21 @@ ALTER DOMAIN name Notes + + Although ALTER DOMAIN ADD CONSTRAINT attempts to verify + that existing stored data satisfies the new constraint, this check is not + bulletproof, because the command cannot see table rows that + are newly inserted or updated and not yet committed. If there is a hazard + that concurrent operations might insert bad data, the way to proceed is to + add the constraint using the NOT VALID option, commit + that command, wait until all transactions started before that commit have + finished, and then issue ALTER DOMAIN VALIDATE + CONSTRAINT to search for data violating the constraint. This + method is reliable because once the constraint is committed, all new + transactions are guaranteed to enforce it against new values of the domain + type. + + Currently, ALTER DOMAIN ADD CONSTRAINT, ALTER DOMAIN VALIDATE CONSTRAINT, and ALTER DOMAIN SET NOT diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml index f266be0c37b..0f11897c997 100644 --- a/doc/src/sgml/ref/alter_foreign_table.sgml +++ b/doc/src/sgml/ref/alter_foreign_table.sgml @@ -50,7 +50,6 @@ ALTER FOREIGN TABLE [ IF EXISTS ] nametrigger_name | ALL | USER ] ENABLE REPLICA TRIGGER trigger_name ENABLE ALWAYS TRIGGER trigger_name - SET WITH OIDS SET WITHOUT OIDS INHERIT parent_table NO INHERIT parent_table @@ -223,34 +222,13 @@ ALTER FOREIGN TABLE [ IF EXISTS ] name - - SET WITH OIDS - - - This form adds an oid system column to the - table (see ). - It does nothing if the table already has OIDs. - Unless the table's foreign-data wrapper supports OIDs, this column - will simply read as zeroes. - - - - Note that this is not equivalent to ADD COLUMN oid oid; - that would add a normal column that happened to be named - oid, not a system column. - - - - SET WITHOUT OIDS - This form removes the oid system column from the - table. This is exactly equivalent to - DROP COLUMN oid RESTRICT, - except that it will not complain if there is already no - oid column. + Backward compatibility syntax for removing the oid + system column. As oid system columns cannot be added + anymore, this never has an effect. diff --git a/doc/src/sgml/ref/alter_function.sgml b/doc/src/sgml/ref/alter_function.sgml index d8747e07482..03ffa5945a2 100644 --- a/doc/src/sgml/ref/alter_function.sgml +++ b/doc/src/sgml/ref/alter_function.sgml @@ -40,6 +40,7 @@ ALTER FUNCTION name [ ( [ [ execution_cost ROWS result_rows + SUPPORT support_function SET configuration_parameter { TO | = } { value | DEFAULT } SET configuration_parameter FROM CURRENT RESET configuration_parameter @@ -248,6 +249,24 @@ ALTER FUNCTION name [ ( [ [ support_function + + + + Set or change the planner support function to use for this function. + See for details. You must be + superuser to use this option. + + + + This option cannot be used to remove the support function altogether, + since it must name a new support function. Use CREATE OR + REPLACE FUNCTION if you need to do that. + + + + configuration_parameter value diff --git a/doc/src/sgml/ref/alter_index.sgml b/doc/src/sgml/ref/alter_index.sgml index c0606689f06..6d34dbb74e5 100644 --- a/doc/src/sgml/ref/alter_index.sgml +++ b/doc/src/sgml/ref/alter_index.sgml @@ -39,7 +39,10 @@ ALTER INDEX ALL IN TABLESPACE name ALTER INDEX changes the definition of an existing index. - There are several subforms: + There are several subforms described below. Note that the lock level required + may differ for each subform. An ACCESS EXCLUSIVE lock is held + unless explicitly noted. When multiple subcommands are listed, the lock + held will be the strictest one required from any subcommand. @@ -48,8 +51,15 @@ ALTER INDEX ALL IN TABLESPACE name The RENAME form changes the name of the index. + If the index is associated with a table constraint (either + UNIQUE, PRIMARY KEY, + or EXCLUDE), the constraint is renamed as well. There is no effect on the stored data. + + Renaming an index acquires a SHARE UPDATE EXCLUSIVE + lock. + @@ -134,7 +144,7 @@ ALTER INDEX ALL IN TABLESPACE name subsequent operations, though can be used only on index columns that are defined as an expression. Since expressions lack a unique name, we refer to them using the - ordinal number of the index column. + ordinal number of the index column. The target can be set in the range 0 to 10000; alternatively, set it to -1 to revert to using the system default statistics target (). @@ -285,8 +295,7 @@ REINDEX INDEX distributors; CREATE INDEX coord_idx ON measured (x, y, (z + t)); ALTER INDEX coord_idx ALTER COLUMN 3 SET STATISTICS 1000; - - + diff --git a/doc/src/sgml/ref/alter_large_object.sgml b/doc/src/sgml/ref/alter_large_object.sgml index f4a9c9e2a52..356f8a8eabf 100644 --- a/doc/src/sgml/ref/alter_large_object.sgml +++ b/doc/src/sgml/ref/alter_large_object.sgml @@ -30,9 +30,15 @@ ALTER LARGE OBJECT large_object_oid ALTER LARGE OBJECT changes the definition of a - large object. The only functionality is to assign a new owner. - You must be superuser or owner of the large object to use - ALTER LARGE OBJECT. + large object. + + + + You must own the large object to use ALTER LARGE OBJECT. + To alter the owner, you must also be a direct or indirect member of the new + owning role. (However, a superuser can alter any large object anyway.) + Currently, the only functionality is to assign a new owner, so both + restrictions always apply. diff --git a/doc/src/sgml/ref/alter_opfamily.sgml b/doc/src/sgml/ref/alter_opfamily.sgml index 3c0922c6452..848156c9d7d 100644 --- a/doc/src/sgml/ref/alter_opfamily.sgml +++ b/doc/src/sgml/ref/alter_opfamily.sgml @@ -185,7 +185,7 @@ ALTER OPERATOR FAMILY name USING support_number - The index method's support procedure number for a + The index method's support function number for a function associated with the operator family. @@ -196,7 +196,7 @@ ALTER OPERATOR FAMILY name USING role_specification [ WIT | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit - | [ ENCRYPTED ] PASSWORD 'password' + | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' ALTER ROLE name RENAME TO new_name @@ -168,7 +168,8 @@ ALTER ROLE { role_specification | A BYPASSRLS NOBYPASSRLS CONNECTION LIMIT connlimit - [ ENCRYPTED ] PASSWORD password + [ ENCRYPTED ] PASSWORD 'password' + PASSWORD NULL VALID UNTIL 'timestamp' diff --git a/doc/src/sgml/ref/alter_statistics.sgml b/doc/src/sgml/ref/alter_statistics.sgml index 58c7ed020dd..be4c3f1f057 100644 --- a/doc/src/sgml/ref/alter_statistics.sgml +++ b/doc/src/sgml/ref/alter_statistics.sgml @@ -26,6 +26,7 @@ PostgreSQL documentation ALTER STATISTICS name OWNER TO { new_owner | CURRENT_USER | SESSION_USER } ALTER STATISTICS name RENAME TO new_name ALTER STATISTICS name SET SCHEMA new_schema +ALTER STATISTICS name SET STATISTICS new_target @@ -93,6 +94,22 @@ ALTER STATISTICS name SET SCHEMA + + new_target + + + The statistic-gathering target for this statistics object for subsequent + operations. + The target can be set in the range 0 to 10000; alternatively, set it + to -1 to revert to using the system default statistics + target (). + For more information on the use of statistics by the + PostgreSQL query planner, refer to + . + + + + diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml index bd2262761e8..cb9b60415de 100644 --- a/doc/src/sgml/ref/alter_table.sgml +++ b/doc/src/sgml/ref/alter_table.sgml @@ -72,7 +72,6 @@ ALTER TABLE [ IF EXISTS ] name NO FORCE ROW LEVEL SECURITY CLUSTER ON index_name SET WITHOUT CLUSTER - SET WITH OIDS SET WITHOUT OIDS SET TABLESPACE new_tablespace SET { LOGGED | UNLOGGED } @@ -87,9 +86,9 @@ ALTER TABLE [ IF EXISTS ] name and partition_bound_spec is: -IN ( { numeric_literal | string_literal | NULL } [, ...] ) | -FROM ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) - TO ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) | +IN ( partition_bound_expr [, ...] ) | +FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) + TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) and column_constraint is: @@ -99,11 +98,12 @@ WITH ( MODULUS numeric_literal, REM NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] - [ ON DELETE action ] [ ON UPDATE action ] } + [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and table_constraint is: @@ -114,7 +114,7 @@ WITH ( MODULUS numeric_literal, REM PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and table_constraint_using_index is: @@ -125,13 +125,13 @@ WITH ( MODULUS numeric_literal, REM index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +[ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] exclude_element in an EXCLUDE constraint is: { column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] - @@ -215,8 +215,17 @@ WITH ( MODULUS numeric_literal, REM These forms change whether a column is marked to allow null - values or to reject null values. You can only use SET - NOT NULL when the column contains no null values. + values or to reject null values. + + + + SET NOT NULL may only be applied to a column + providing none of the records in the table contain a + NULL value for the column. Ordinarily this is + checked during the ALTER TABLE by scanning the + entire table; however, if a valid CHECK constraint is + found which proves no NULL can exist, then the + table scan is skipped. @@ -359,22 +368,36 @@ WITH ( MODULUS numeric_literal, REM , plus the option NOT VALID, which is currently only allowed for foreign key and CHECK constraints. - If the constraint is marked NOT VALID, the - potentially-lengthy initial check to verify that all rows in the table - satisfy the constraint is skipped. The constraint will still be + + + + Normally, this form will cause a scan of the table to verify that all + existing rows in the table satisfy the new constraint. But if + the NOT VALID option is used, this + potentially-lengthy scan is skipped. The constraint will still be enforced against subsequent inserts or updates (that is, they'll fail unless there is a matching row in the referenced table, in the case - of foreign keys; and they'll fail unless the new row matches the - specified check constraints). But the + of foreign keys, or they'll fail unless the new row matches the + specified check condition). But the database will not assume that the constraint holds for all rows in the table, until it is validated by using the VALIDATE - CONSTRAINT option. Foreign key constraints on partitioned - tables may not be declared NOT VALID at present. + CONSTRAINT option. + See below for more information + about using the NOT VALID option. + + + + Addition of a foreign key constraint requires a + SHARE ROW EXCLUSIVE lock on the referenced table, + in addition to the lock on the table receiving the constraint. Additional restrictions apply when unique or primary key constraints - are added to partitioned tables; see . + are added to partitioned tables; see . + Also, foreign key constraints on partitioned + tables may not be declared NOT VALID at present. @@ -449,23 +472,13 @@ WITH ( MODULUS numeric_literal, REM VALIDATE CONSTRAINT - This form validates a foreign key or check constraint that was previously created - as NOT VALID, by scanning the table to ensure there - are no rows for which the constraint is not satisfied. - Nothing happens if the constraint is already marked valid. - - - Validation can be a long process on larger tables. The value of separating - validation from initial creation is that you can defer validation to less - busy times, or can be used to give additional time to correct pre-existing - errors while preventing new errors. Note also that validation on its own - does not prevent normal write commands against the table while it runs. - - - Validation acquires only a SHARE UPDATE EXCLUSIVE lock - on the table being altered. If the constraint is a foreign key then - a ROW SHARE lock is also required on - the table referenced by the constraint. + This form validates a foreign key or check constraint that was + previously created as NOT VALID, by scanning the + table to ensure there are no rows for which the constraint is not + satisfied. Nothing happens if the constraint is already marked valid. + (See below for an explanation of the + usefulness of this command.) @@ -474,7 +487,8 @@ WITH ( MODULUS numeric_literal, REM DROP CONSTRAINT [ IF EXISTS ] - This form drops the specified constraint on a table. + This form drops the specified constraint on a table, along with + any index underlying the constraint. If IF EXISTS is specified and the constraint does not exist, no error is thrown. In this case a notice is issued instead. @@ -607,32 +621,13 @@ WITH ( MODULUS numeric_literal, REM - - SET WITH OIDS - - - This form adds an oid system column to the - table (see ). - It does nothing if the table already has OIDs. - - - - Note that this is not equivalent to ADD COLUMN oid oid; - that would add a normal column that happened to be named - oid, not a system column. - - - - SET WITHOUT OIDS - This form removes the oid system column from the - table. This is exactly equivalent to - DROP COLUMN oid RESTRICT, - except that it will not complain if there is already no - oid column. + Backward-compatible syntax for removing the oid + system column. As oid system columns cannot be + added anymore, this never has an effect. @@ -645,6 +640,13 @@ WITH ( MODULUS numeric_literal, REM moves the data file(s) associated with the table to the new tablespace. Indexes on the table, if any, are not moved; but they can be moved separately with additional SET TABLESPACE commands. + When applied to a partitioned table, nothing is moved, but any + partitions created afterwards with + CREATE TABLE PARTITION OF will use that tablespace, + unless the TABLESPACE clause is used to override it. + + + All tables in the current database in a tablespace can be moved by using the ALL IN TABLESPACE form, which will lock all tables to be moved first and then move each one. This form also supports @@ -652,7 +654,7 @@ WITH ( MODULUS numeric_literal, REM roles specified. If the NOWAIT option is specified then the command will fail if it is unable to acquire all of the locks required immediately. Note that system catalogs are not moved by this - command, use ALTER DATABASE or explicit + command; use ALTER DATABASE or explicit ALTER TABLE invocations instead if desired. The information_schema relations are not considered part of the system catalogs and will be moved. @@ -698,17 +700,6 @@ WITH ( MODULUS numeric_literal, REM effective_io_concurrency, parallel_workers, seq_page_cost, random_page_cost, n_distinct and n_distinct_inherited. - - - - While CREATE TABLE allows OIDS to be specified - in the WITH (storage_parameter) syntax, - ALTER TABLE does not treat OIDS as a - storage parameter. Instead use the SET WITH OIDS - and SET WITHOUT OIDS forms to change OID status. - - @@ -769,8 +760,7 @@ WITH ( MODULUS numeric_literal, REM This form links the table to a composite type as though CREATE TABLE OF had formed it. The table's list of column names and types - must precisely match that of the composite type; the presence of - an oid system column is permitted to differ. The table must + must precisely match that of the composite type. The table must not inherit from any other table. These restrictions ensure that CREATE TABLE OF would permit an equivalent table definition. @@ -822,8 +812,10 @@ WITH ( MODULUS numeric_literal, REM The RENAME forms change the name of a table - (or an index, sequence, view, materialized view, or foreign table), the name - of an individual column in a table, or the name of a constraint of the table. + (or an index, sequence, view, materialized view, or foreign table), the + name of an individual column in a table, or the name of a constraint of + the table. When renaming a constraint that has an underlying index, + the index is renamed as well. There is no effect on the stored data. @@ -839,7 +831,7 @@ WITH ( MODULUS numeric_literal, REM - + ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT } @@ -851,6 +843,10 @@ WITH ( MODULUS numeric_literal, REM one will be created in the attached table; or, if an equivalent index already exists, will be attached to the target table's index, as if ALTER INDEX ATTACH PARTITION had been executed. + Note that if the existing table is a foreign table, it is currently not + allowed to attach the table as a partition of the target table if there + are UNIQUE indexes on the target table. (See also + .) @@ -1177,8 +1173,8 @@ WITH ( MODULUS numeric_literal, REM - - Notes + + Notes The key word COLUMN is noise and can be omitted. @@ -1201,8 +1197,7 @@ WITH ( MODULUS numeric_literal, REM the column contents and the old type is either binary coercible to the new type or an unconstrained domain over the new type, a table rewrite is not needed; but any indexes on the affected columns must still be rebuilt. - Adding or removing a system oid column also requires - rewriting the entire table. Table and/or index rebuilds may take a + Table and/or index rebuilds may take a significant amount of time for a large table; and will temporarily require as much as double the disk space. @@ -1224,6 +1219,32 @@ WITH ( MODULUS numeric_literal, REM rewrites can thereby be combined into a single pass over the table. + + Scanning a large table to verify a new foreign key or check constraint + can take a long time, and other updates to the table are locked out + until the ALTER TABLE ADD CONSTRAINT command is + committed. The main purpose of the NOT VALID + constraint option is to reduce the impact of adding a constraint on + concurrent updates. With NOT VALID, + the ADD CONSTRAINT command does not scan the table + and can be committed immediately. After that, a VALIDATE + CONSTRAINT command can be issued to verify that existing rows + satisfy the constraint. The validation step does not need to lock out + concurrent updates, since it knows that other transactions will be + enforcing the constraint for rows that they insert or update; only + pre-existing rows need to be checked. Hence, validation acquires only + a SHARE UPDATE EXCLUSIVE lock on the table being + altered. (If the constraint is a foreign key then a ROW + SHARE lock is also required on the table referenced by the + constraint.) In addition to improving concurrency, it can be useful to + use NOT VALID and VALIDATE + CONSTRAINT in cases where the table is known to contain + pre-existing violations. Once the constraint is in place, no new + violations can be inserted, and the existing problems can be corrected + at leisure until VALIDATE CONSTRAINT finally + succeeds. + + The DROP COLUMN form does not physically remove the column, but simply makes it invisible to SQL operations. Subsequent @@ -1231,9 +1252,7 @@ WITH ( MODULUS numeric_literal, REM column. Thus, dropping a column is quick but it will not immediately reduce the on-disk size of your table, as the space occupied by the dropped column is not reclaimed. The space will be - reclaimed over time as existing rows are updated. (These statements do - not apply when dropping the system oid column; that is done - with an immediate rewrite.) + reclaimed over time as existing rows are updated. @@ -1270,10 +1289,12 @@ WITH ( MODULUS numeric_literal, REM If a table has any descendant tables, it is not permitted to add, rename, or change the type of a column in the parent table without doing - same to the descendants. This ensures that the descendants always have - columns matching the parent. Similarly, a constraint cannot be renamed - in the parent without also renaming it in all descendants, so that - constraints also match between the parent and its descendants. + the same to the descendants. This ensures that the descendants always + have columns matching the parent. Similarly, a CHECK + constraint cannot be renamed in the parent without also renaming it in + all descendants, so that CHECK constraints also match + between the parent and its descendants. (That restriction does not apply + to index-based constraints, however.) Also, because selecting from the parent also selects from its descendants, a constraint on the parent cannot be marked valid unless it is also marked valid for those descendants. In all of these cases, ALTER TABLE @@ -1481,35 +1502,35 @@ ALTER TABLE distributors DROP CONSTRAINT distributors_pkey, - Attach a partition to range partitioned table: + To attach a partition to a range-partitioned table: ALTER TABLE measurement ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); - Attach a partition to list partitioned table: + To attach a partition to a list-partitioned table: ALTER TABLE cities ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b'); - Attach a default partition to a partitioned table: + To attach a partition to a hash-partitioned table: -ALTER TABLE cities - ATTACH PARTITION cities_partdef DEFAULT; +ALTER TABLE orders + ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3); - Attach a partition to hash partitioned table: + To attach a default partition to a partitioned table: -ALTER TABLE orders - ATTACH PARTITION orders_p4 FOR VALUES WITH (MODULUS 4, REMAINDER 3); +ALTER TABLE cities + ATTACH PARTITION cities_partdef DEFAULT; - Detach a partition from partitioned table: + To detach a partition from a partitioned table: ALTER TABLE measurement DETACH PARTITION measurement_y2015m12; diff --git a/doc/src/sgml/ref/alter_type.sgml b/doc/src/sgml/ref/alter_type.sgml index 9127dfd88de..67be1dd5683 100644 --- a/doc/src/sgml/ref/alter_type.sgml +++ b/doc/src/sgml/ref/alter_type.sgml @@ -290,8 +290,9 @@ ALTER TYPE name RENAME VALUE Notes - ALTER TYPE ... ADD VALUE (the form that adds a new value to an - enum type) cannot be executed inside a transaction block. + If ALTER TYPE ... ADD VALUE (the form that adds a new + value to an enum type) is executed inside a transaction block, the new + value cannot be used until after the transaction has been committed. diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml index 8f50f43089a..6769c8ecc4b 100644 --- a/doc/src/sgml/ref/alter_user.sgml +++ b/doc/src/sgml/ref/alter_user.sgml @@ -33,7 +33,7 @@ ALTER USER role_specification [ WIT | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit - | [ ENCRYPTED ] PASSWORD 'password' + | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' ALTER USER name RENAME TO new_name diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index 10b3a9a6733..5ac3ba83219 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -26,7 +26,8 @@ ANALYZE [ VERBOSE ] [ table_and_columnswhere option can be one of: - VERBOSE + VERBOSE [ boolean ] + SKIP_LOCKED [ boolean ] and table_and_columns is: @@ -76,6 +77,38 @@ ANALYZE [ VERBOSE ] [ table_and_columns + + SKIP_LOCKED + + + Specifies that ANALYZE should not wait for any + conflicting locks to be released when beginning work on a relation: + if a relation cannot be locked immediately without waiting, the relation + is skipped. Note that even with this option, ANALYZE + may still block when opening the relation's indexes or when acquiring + sample rows from partitions, table inheritance children, and some + types of foreign tables. Also, while ANALYZE + ordinarily processes all partitions of specified partitioned tables, + this option will cause ANALYZE to skip all + partitions if there is a conflicting lock on the partitioned table. + + + + + + boolean + + + Specifies whether the selected option should be turned on or off. + You can write TRUE, ON, or + 1 to enable the option, and FALSE, + OFF, or 0 to disable it. The + boolean value can also + be omitted, in which case TRUE is assumed. + + + + table_name @@ -114,6 +147,16 @@ ANALYZE [ VERBOSE ] [ table_and_columns Notes + + To analyze a table, one must ordinarily be the table's owner or a + superuser. However, database owners are allowed to + analyze all tables in their databases, except shared catalogs. + (The restriction for shared catalogs means that a true database-wide + ANALYZE can only be performed by a superuser.) + ANALYZE will skip over any tables that the calling user + does not have permission to analyze. + + Foreign tables are analyzed only when explicitly selected. Not all foreign data wrappers support ANALYZE. If the table's diff --git a/doc/src/sgml/ref/call.sgml b/doc/src/sgml/ref/call.sgml index 7418e19eeba..abaa81c78b9 100644 --- a/doc/src/sgml/ref/call.sgml +++ b/doc/src/sgml/ref/call.sgml @@ -33,7 +33,8 @@ CALL name ( [ name ( [ argument - An argument for the procedure call. + An input argument for the procedure call. See for the full details on function and procedure call syntax, including use of named parameters. @@ -81,6 +82,12 @@ CALL name ( [ . + diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml index ed343dd7dae..b25845ffc67 100644 --- a/doc/src/sgml/ref/clusterdb.sgml +++ b/doc/src/sgml/ref/clusterdb.sgml @@ -274,6 +274,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/commit.sgml b/doc/src/sgml/ref/commit.sgml index b2e8d5d1807..5f244cdd3c1 100644 --- a/doc/src/sgml/ref/commit.sgml +++ b/doc/src/sgml/ref/commit.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -COMMIT [ WORK | TRANSACTION ] +COMMIT [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] @@ -38,6 +38,10 @@ COMMIT [ WORK | TRANSACTION ] Parameters + + chained transactions + + WORK @@ -48,6 +52,18 @@ COMMIT [ WORK | TRANSACTION ] + + + AND CHAIN + + + If AND CHAIN is specified, a new transaction is + immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, + no new transaction is started. + + + @@ -61,7 +77,8 @@ COMMIT [ WORK | TRANSACTION ] Issuing COMMIT when not inside a transaction does - no harm, but it will provoke a warning message. + no harm, but it will provoke a warning message. COMMIT AND + CHAIN when not inside a transaction is an error. @@ -79,9 +96,8 @@ COMMIT; Compatibility - The SQL standard only specifies the two forms - COMMIT and COMMIT - WORK. Otherwise, this command is fully conforming. + The command COMMIT conforms to the SQL standard. The + form COMMIT TRANSACTION is a PostgreSQL extension. diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml index 13a8b68d951..5e2992ddacc 100644 --- a/doc/src/sgml/ref/copy.sgml +++ b/doc/src/sgml/ref/copy.sgml @@ -25,6 +25,7 @@ PostgreSQL documentation COPY table_name [ ( column_name [, ...] ) ] FROM { 'filename' | PROGRAM 'command' | STDIN } [ [ WITH ] ( option [, ...] ) ] + [ WHERE condition ] COPY { table_name [ ( column_name [, ...] ) ] | ( query ) } TO { 'filename' | PROGRAM 'command' | STDOUT } @@ -33,7 +34,6 @@ COPY { table_name [ ( where option can be one of: FORMAT format_name - OIDS [ boolean ] FREEZE [ boolean ] DELIMITER 'delimiter_character' NULL 'null_string' @@ -103,7 +103,8 @@ COPY { table_name [ ( An optional list of columns to be copied. If no column list is - specified, all columns of the table will be copied. + specified, all columns of the table except generated columns will be + copied. @@ -203,18 +204,6 @@ COPY { table_name [ ( - - OIDS - - - Specifies copying the OID for each row. (An error is raised if - OIDS is specified for a table that does not - have OIDs, or in the case of copying a query.) - - - - FREEZE @@ -224,7 +213,9 @@ COPY { table_name [ ( COPY FREEZE on + a partitioned table. Note that all other sessions will immediately be able to see the data @@ -364,6 +355,32 @@ COPY { table_name [ ( + + WHERE + + + The optional WHERE clause has the general form + +WHERE condition + + where condition is + any expression that evaluates to a result of type + boolean. Any row that does not satisfy this + condition will not be inserted to the table. A row satisfies the + condition if it returns true when the actual row values are + substituted for any variable references. + + + + Currently, subqueries are not allowed in WHERE + expressions, and the evaluation does not see any changes made by the + COPY itself (this matters when the expression + contains calls to VOLATILE functions). + + + + + @@ -547,8 +564,6 @@ COPY count place of columns that are null. COPY FROM will raise an error if any line of the input file contains more or fewer columns than are expected. - If OIDS is specified, the OID is read or written as the first column, - preceding the user data columns. @@ -822,7 +837,9 @@ only one flag bit is defined, and the rest must be zero: Bit 16 - if 1, OIDs are included in the data; if 0, not + If 1, OIDs are included in the data; if 0, not. Oid system columns + are not supported in PostgreSQL + anymore, but the format still contains the indicator. @@ -893,10 +910,9 @@ distribution). If OIDs are included in the file, the OID field immediately follows the -field-count word. It is a normal field except that it's not included -in the field-count. In particular it has a length word — this will allow -handling of 4-byte vs. 8-byte OIDs without too much pain, and will allow -OIDs to be shown as null if that ever proves desirable. +field-count word. It is a normal field except that it's not included in the +field-count. Note that oid system columns are not supported in current +versions of PostgreSQL. @@ -999,7 +1015,6 @@ COPY table_name [ ( filename' | STDIN } [ [ WITH ] [ BINARY ] - [ OIDS ] [ DELIMITER [ AS ] 'delimiter' ] [ NULL [ AS ] 'null string' ] [ CSV [ HEADER ] @@ -1011,7 +1026,6 @@ COPY { table_name [ ( filename' | STDOUT } [ [ WITH ] [ BINARY ] - [ OIDS ] [ DELIMITER [ AS ] 'delimiter' ] [ NULL [ AS ] 'null string' ] [ CSV [ HEADER ] @@ -1030,12 +1044,12 @@ COPY { table_name [ ( -COPY [ BINARY ] table_name [ WITH OIDS ] +COPY [ BINARY ] table_name FROM { 'filename' | STDIN } [ [USING] DELIMITERS 'delimiter' ] [ WITH NULL AS 'null string' ] -COPY [ BINARY ] table_name [ WITH OIDS ] +COPY [ BINARY ] table_name TO { 'filename' | STDOUT } [ [USING] DELIMITERS 'delimiter' ] [ WITH NULL AS 'null string' ] diff --git a/doc/src/sgml/ref/create_access_method.sgml b/doc/src/sgml/ref/create_access_method.sgml index 851c5e63beb..dae43dbaed5 100644 --- a/doc/src/sgml/ref/create_access_method.sgml +++ b/doc/src/sgml/ref/create_access_method.sgml @@ -61,7 +61,8 @@ CREATE ACCESS METHOD name This clause specifies the type of access method to define. - Only INDEX is supported at present. + Only TABLE and INDEX + are supported at present. @@ -75,10 +76,13 @@ CREATE ACCESS METHOD name that represents the access method. The handler function must be declared to take a single argument of type internal, and its return type depends on the type of access method; - for INDEX access methods, it must - be index_am_handler. The C-level API that the handler - function must implement varies depending on the type of access method. - The index access method API is described in . + for TABLE access methods, it must + be table_am_handler and for INDEX + access methods, it must be index_am_handler. + The C-level API that the handler function must implement varies + depending on the type of access method. The table access method API + is described in and the index access method + API is described in . diff --git a/doc/src/sgml/ref/create_aggregate.sgml b/doc/src/sgml/ref/create_aggregate.sgml index a4aaae876ec..644657dd5ef 100644 --- a/doc/src/sgml/ref/create_aggregate.sgml +++ b/doc/src/sgml/ref/create_aggregate.sgml @@ -21,13 +21,13 @@ PostgreSQL documentation -CREATE AGGREGATE name ( [ argmode ] [ argname ] arg_data_type [ , ... ] ) ( +CREATE [ OR REPLACE ] AGGREGATE name ( [ argmode ] [ argname ] arg_data_type [ , ... ] ) ( SFUNC = sfunc, STYPE = state_data_type [ , SSPACE = state_data_size ] [ , FINALFUNC = ffunc ] [ , FINALFUNC_EXTRA ] - [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ] + [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] [ , COMBINEFUNC = combinefunc ] [ , SERIALFUNC = serialfunc ] [ , DESERIALFUNC = deserialfunc ] @@ -38,20 +38,20 @@ CREATE AGGREGATE name ( [ mstate_data_size ] [ , MFINALFUNC = mffunc ] [ , MFINALFUNC_EXTRA ] - [ , MFINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ] + [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] [ , MINITCOND = minitial_condition ] [ , SORTOP = sort_operator ] [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] ) -CREATE AGGREGATE name ( [ [ argmode ] [ argname ] arg_data_type [ , ... ] ] +CREATE [ OR REPLACE ] AGGREGATE name ( [ [ argmode ] [ argname ] arg_data_type [ , ... ] ] ORDER BY [ argmode ] [ argname ] arg_data_type [ , ... ] ) ( SFUNC = sfunc, STYPE = state_data_type [ , SSPACE = state_data_size ] [ , FINALFUNC = ffunc ] [ , FINALFUNC_EXTRA ] - [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ] + [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] [ , INITCOND = initial_condition ] [ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ] [ , HYPOTHETICAL ] @@ -59,14 +59,14 @@ CREATE AGGREGATE name ( [ [ or the old syntax -CREATE AGGREGATE name ( +CREATE [ OR REPLACE ] AGGREGATE name ( BASETYPE = base_type, SFUNC = sfunc, STYPE = state_data_type [ , SSPACE = state_data_size ] [ , FINALFUNC = ffunc ] [ , FINALFUNC_EXTRA ] - [ , FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ] + [ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] [ , COMBINEFUNC = combinefunc ] [ , SERIALFUNC = serialfunc ] [ , DESERIALFUNC = deserialfunc ] @@ -77,7 +77,7 @@ CREATE AGGREGATE name ( [ , MSSPACE = mstate_data_size ] [ , MFINALFUNC = mffunc ] [ , MFINALFUNC_EXTRA ] - [ , MFINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } ] + [ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ] [ , MINITCOND = minitial_condition ] [ , SORTOP = sort_operator ] ) @@ -88,12 +88,21 @@ CREATE AGGREGATE name ( Description - CREATE AGGREGATE defines a new aggregate - function. Some basic and commonly-used aggregate functions are - included with the distribution; they are documented in . If one defines new types or needs - an aggregate function not already provided, then CREATE - AGGREGATE can be used to provide the desired features. + CREATE AGGREGATE defines a new aggregate function. + CREATE OR REPLACE AGGREGATE will either define a new + aggregate function or replace an existing definition. Some basic and + commonly-used aggregate functions are included with the distribution; they + are documented in . If one defines new + types or needs an aggregate function not already provided, then + CREATE AGGREGATE can be used to provide the desired + features. + + + + When replacing an existing definition, the argument types, result type, + and number of direct arguments may not be changed. Also, the new definition + must be of the same kind (ordinary aggregate, ordered-set aggregate, or + hypothetical-set aggregate) as the old one. @@ -202,7 +211,7 @@ CREATE AGGREGATE name ( as described in . This requires specifying the MSFUNC, MINVFUNC, and MSTYPE parameters, and optionally - the MSPACE, MFINALFUNC, + the MSSPACE, MFINALFUNC, MFINALFUNC_EXTRA, MFINALFUNC_MODIFY, and MINITCOND parameters. Except for MINVFUNC, these parameters work like the corresponding simple-aggregate parameters @@ -419,7 +428,7 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; - FINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } + FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } This option specifies whether the final function is a pure function @@ -585,7 +594,7 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; - MFINALFUNC_MODIFY = { READ_ONLY | SHARABLE | READ_WRITE } + MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } This option is like FINALFUNC_MODIFY, but it describes @@ -678,12 +687,13 @@ SELECT col FROM tab ORDER BY col USING sortop LIMIT 1; Likewise, while an aggregate final function is normally expected not to modify its input values, sometimes it is impractical to avoid modifying the transition-state argument. Such behavior must be declared using - the FINALFUNC_MODIFY parameter. The READ_WRITE + the FINALFUNC_MODIFY parameter. + The READ_WRITE value indicates that the final function modifies the transition state in unspecified ways. This value prevents use of the aggregate as a window function, and it also prevents merging of transition states for aggregate calls that share the same input values and transition functions. - The SHARABLE value indicates that the transition function + The SHAREABLE value indicates that the transition function cannot be applied after the final function, but multiple final-function calls can be performed on the ending transition state value. This value prevents use of the aggregate as a window function, but it allows merging diff --git a/doc/src/sgml/ref/create_collation.sgml b/doc/src/sgml/ref/create_collation.sgml index 5bc9af5499e..def4dda6e88 100644 --- a/doc/src/sgml/ref/create_collation.sgml +++ b/doc/src/sgml/ref/create_collation.sgml @@ -23,6 +23,7 @@ CREATE COLLATION [ IF NOT EXISTS ] name ( [ LC_COLLATE = lc_collate, ] [ LC_CTYPE = lc_ctype, ] [ PROVIDER = provider, ] + [ DETERMINISTIC = boolean, ] [ VERSION = version ] ) CREATE COLLATION [ IF NOT EXISTS ] name FROM existing_collation @@ -124,6 +125,27 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM + + DETERMINISTIC + + + + Specifies whether the collation should use deterministic comparisons. + The default is true. A deterministic comparison considers strings that + are not byte-wise equal to be unequal even if they are considered + logically equal by the comparison. PostgreSQL breaks ties using a + byte-wise comparison. Comparison that is not deterministic can make the + collation be, say, case- or accent-insensitive. For that, you need to + choose an appropriate LC_COLLATE setting + and set the collation to not deterministic here. + + + + Nondeterministic collations are only supported with the ICU provider. + + + + version @@ -162,6 +184,13 @@ CREATE COLLATION [ IF NOT EXISTS ] name FROM Notes + + CREATE COLLATION takes a SHARE ROW + EXCLUSIVE lock, which is self-conflicting, on the + pg_collation system catalog, so only one + CREATE COLLATION command can run at a time. + + Use DROP COLLATION to remove user-defined collations. diff --git a/doc/src/sgml/ref/create_conversion.sgml b/doc/src/sgml/ref/create_conversion.sgml index 4ddbcfacef2..67b4bd26bed 100644 --- a/doc/src/sgml/ref/create_conversion.sgml +++ b/doc/src/sgml/ref/create_conversion.sgml @@ -28,12 +28,15 @@ CREATE [ DEFAULT ] CONVERSION name CREATE CONVERSION defines a new conversion between - character set encodings. Also, conversions that - are marked DEFAULT can be used for automatic encoding - conversion between - client and server. For this purpose, two conversions, from encoding A to - B and from encoding B to A, must be defined. - + two character set encodings. + + + + Conversions that are marked DEFAULT can be used for + automatic encoding conversion between client and server. To support that + usage, two conversions, from encoding A to B and + from encoding B to A, must be defined. + To be able to create a conversion, you must have EXECUTE privilege @@ -122,6 +125,13 @@ conv_proc( Notes + + Neither the source nor the destination encoding can + be SQL_ASCII, as the server's behavior for cases + involving the SQL_ASCII encoding is + hard-wired. + + Use DROP CONVERSION to remove user-defined conversions. diff --git a/doc/src/sgml/ref/create_database.sgml b/doc/src/sgml/ref/create_database.sgml index b2c9e241c2f..4014f6703bb 100644 --- a/doc/src/sgml/ref/create_database.sgml +++ b/doc/src/sgml/ref/create_database.sgml @@ -25,6 +25,7 @@ CREATE DATABASE name [ [ WITH ] [ OWNER [=] user_name ] [ TEMPLATE [=] template ] [ ENCODING [=] encoding ] + [ LOCALE [=] locale ] [ LC_COLLATE [=] lc_collate ] [ LC_CTYPE [=] lc_ctype ] [ TABLESPACE [=] tablespace_name ] @@ -111,6 +112,26 @@ CREATE DATABASE name + + locale + + + This is a shortcut for setting LC_COLLATE + and LC_CTYPE at once. If you specify this, + you cannot specify either of those parameters. + + + + The other locale settings , , , and + are not fixed per database and are not + set by this command. If you want to make them the default for a + specific database, you can use ALTER DATABASE + ... SET. + + + + lc_collate @@ -287,7 +308,7 @@ CREATE DATABASE sales OWNER salesapp TABLESPACE salesspace; To create a database music with a different locale: CREATE DATABASE music - LC_COLLATE 'sv_SE.utf8' LC_CTYPE 'sv_SE.utf8' + LOCALE 'sv_SE.utf8' TEMPLATE template0; In this example, the TEMPLATE template0 clause is required if @@ -300,7 +321,7 @@ CREATE DATABASE music different character set encoding: CREATE DATABASE music2 - LC_COLLATE 'sv_SE.iso885915' LC_CTYPE 'sv_SE.iso885915' + LOCALE 'sv_SE.iso885915' ENCODING LATIN9 TEMPLATE template0; diff --git a/doc/src/sgml/ref/create_domain.sgml b/doc/src/sgml/ref/create_domain.sgml index 49d53043304..81a89249260 100644 --- a/doc/src/sgml/ref/create_domain.sgml +++ b/doc/src/sgml/ref/create_domain.sgml @@ -214,6 +214,30 @@ INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false)); and then to apply column NOT NULL constraints to columns of the domain type as needed, rather than directly to the domain type. + + + PostgreSQL assumes that + CHECK constraints' conditions are immutable, that is, + they will always give the same result for the same input value. This + assumption is what justifies examining CHECK + constraints only when a value is first converted to be of a domain type, + and not at other times. (This is essentially the same as the treatment + of table CHECK constraints, as described in + .) + + + + An example of a common way to break this assumption is to reference a + user-defined function in a CHECK expression, and then + change the behavior of that + function. PostgreSQL does not disallow that, + but it will not notice if there are stored values of the domain type that + now violate the CHECK constraint. That would cause a + subsequent database dump and reload to fail. The recommended way to + handle such a change is to drop the constraint (using ALTER + DOMAIN), adjust the function definition, and re-add the + constraint, thereby rechecking it against stored data. + diff --git a/doc/src/sgml/ref/create_event_trigger.sgml b/doc/src/sgml/ref/create_event_trigger.sgml index 396d82118ee..52ba746166b 100644 --- a/doc/src/sgml/ref/create_event_trigger.sgml +++ b/doc/src/sgml/ref/create_event_trigger.sgml @@ -24,7 +24,7 @@ PostgreSQL documentation CREATE EVENT TRIGGER name ON event [ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ] - EXECUTE PROCEDURE function_name() + EXECUTE { FUNCTION | PROCEDURE } function_name() @@ -98,6 +98,14 @@ CREATE EVENT TRIGGER name A user-supplied function that is declared as taking no argument and returning type event_trigger. + + + In the syntax of CREATE EVENT TRIGGER, the keywords + FUNCTION and PROCEDURE are + equivalent, but the referenced function must in any case be a function, + not a procedure. The use of the keyword PROCEDURE + here is historical and deprecated. + @@ -136,7 +144,7 @@ END; $$; CREATE EVENT TRIGGER abort_ddl ON ddl_command_start - EXECUTE PROCEDURE abort_any_command(); + EXECUTE FUNCTION abort_any_command(); diff --git a/doc/src/sgml/ref/create_foreign_table.sgml b/doc/src/sgml/ref/create_foreign_table.sgml index 37a45b26dbc..9d266f272a7 100644 --- a/doc/src/sgml/ref/create_foreign_table.sgml +++ b/doc/src/sgml/ref/create_foreign_table.sgml @@ -42,7 +42,8 @@ CREATE FOREIGN TABLE [ IF NOT EXISTS ] table_name { NOT NULL | NULL | CHECK ( expression ) [ NO INHERIT ] | - DEFAULT default_expr } + DEFAULT default_expr | + GENERATED ALWAYS AS ( generation_expr ) STORED } and table_constraint is: @@ -160,6 +161,22 @@ CHECK ( expression ) [ NO INHERIT ] + + PARTITION OF parent_table FOR VALUES partition_bound_spec + + + This form can be used to create the foreign table as partition of + the given parent table with specified partition bound values. + See the similar form of + for more details. + Note that it is currently not allowed to create the foreign table as a + partition of the parent table if there are UNIQUE + indexes on the parent table. (See also + ALTER TABLE ATTACH PARTITION.) + + + + CONSTRAINT constraint_name @@ -246,6 +263,30 @@ CHECK ( expression ) [ NO INHERIT ] + + GENERATED ALWAYS AS ( generation_expr ) STOREDgenerated column + + + This clause creates the column as a generated + column. The column cannot be written to, and when read the + result of the specified expression will be returned. + + + + The keyword STORED is required to signify that the + column will be computed on write. (The computed value will be presented + to the foreign-data wrapper for storage and must be returned on + reading.) + + + + The generation expression can refer to other columns in the table, but + not other generated columns. Any functions and operators used must be + immutable. References to other tables are not allowed. + + + + server_name @@ -308,6 +349,22 @@ CHECK ( expression ) [ NO INHERIT ] responsibility to ensure that the constraint definition matches reality. + + + Similar considerations apply to generated columns. Stored generated + columns are computed on insert or update on the local + PostgreSQL server and handed to the + foreign-data wrapper for writing out to the foreign data store, but it is + not enforced that a query of the foreign table returns values for stored + generated columns that are consistent with the generation expression. + Again, this might result in incorrect query results. + + + + While rows can be moved from local partitions to a foreign-table partition + (provided the foreign data wrapper supports tuple routing), they cannot be + moved from a foreign-table partition to another partition. + diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index c0adb8cf1e6..dd6a2f73049 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -33,6 +33,7 @@ CREATE [ OR REPLACE ] FUNCTION | PARALLEL { UNSAFE | RESTRICTED | SAFE } | COST execution_cost | ROWS result_rows + | SUPPORT support_function | SET configuration_parameter { TO value | = value | FROM CURRENT } | AS 'definition' | AS 'obj_file', 'link_symbol' @@ -477,6 +478,19 @@ CREATE [ OR REPLACE ] FUNCTION + + SUPPORT support_function + + + + The name (optionally schema-qualified) of a planner support + function to use for this function. See + for details. + You must be superuser to use this option. + + + + configuration_parameter value @@ -545,8 +559,11 @@ CREATE [ OR REPLACE ] FUNCTION as for the command. The string link_symbol is the function's link symbol, that is, the name of the function in the C - language source code. If the link symbol is omitted, it is assumed - to be the same as the name of the SQL function being defined. + language source code. If the link symbol is omitted, it is assumed to + be the same as the name of the SQL function being defined. The C names + of all functions must be different, so you must give overloaded C + functions different C names (for example, use the argument types as + part of the C names). @@ -575,10 +592,9 @@ CREATE [ OR REPLACE ] FUNCTION PostgreSQL allows function overloading; that is, the same name can be used for several different functions so long as they have distinct - input argument types. However, the C names of all functions must be - different, so you must give overloaded C functions different C - names (for example, use the argument types as part of the C - names). + input argument types. Whether or not you use it, this capability entails + security precautions when calling functions in databases where some users + mistrust other users; see . @@ -759,7 +775,7 @@ $$ LANGUAGE plpgsql Another point to keep in mind is that by default, execute privilege is granted to PUBLIC for newly created functions - (see for more + (see for more information). Frequently you will wish to restrict use of a security definer function to only some users. To do that, you must revoke the default PUBLIC privileges and then grant execute diff --git a/doc/src/sgml/ref/create_index.sgml b/doc/src/sgml/ref/create_index.sgml index 91692325a50..629a31ef795 100644 --- a/doc/src/sgml/ref/create_index.sgml +++ b/doc/src/sgml/ref/create_index.sgml @@ -149,25 +149,28 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] The optional INCLUDE clause specifies a - list of columns which will be included as a non-key part in the index. - Columns listed in this clause cannot also be present as index key columns. - The INCLUDE columns exist solely to - allow more queries to benefit from index-only scans - by including the values of the specified columns in the index. These values - would otherwise have to be obtained by reading the table's heap. + list of columns which will be included in the index + as non-key columns. A non-key column cannot + be used in an index scan search qualification, and it is disregarded + for purposes of any uniqueness or exclusion constraint enforced by + the index. However, an index-only scan can return the contents of + non-key columns without having to visit the index's table, since + they are available directly from the index entry. Thus, addition of + non-key columns allows index-only scans to be used for queries that + otherwise could not use them. - In UNIQUE indexes, uniqueness is only enforced - for key columns. Columns listed in the INCLUDE - clause have no effect on uniqueness enforcement. Other constraints - (PRIMARY KEY and EXCLUDE) work - the same way. + It's wise to be conservative about adding non-key columns to an + index, especially wide columns. If an index tuple exceeds the + maximum size allowed for the index type, data insertion will fail. + In any case, non-key columns duplicate data from the index's table + and bloat the size of the index, thus potentially slowing searches. Columns listed in the INCLUDE clause don't need - appropriate operator classes; the clause can contain non-key index + appropriate operator classes; the clause can include columns whose data types don't have operator classes defined for a given access method. @@ -178,18 +181,11 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - Currently, only the B-tree index access method supports this feature. - In B-tree indexes, the values of columns listed in the - INCLUDE clause are included in leaf tuples which - are linked to the heap tuples, but are not included into pivot tuples - used for tree navigation. Therefore, moving columns from the list of - key columns to the INCLUDE clause can slightly - reduce index size and improve the tree branching factor. - - - - Indexes with columns listed in the INCLUDE clause - are also called covering indexes. + Currently, the B-tree and the GiST index access methods support this + feature. In B-tree and the GiST indexes, the values of columns listed + in the INCLUDE clause are included in leaf tuples + which correspond to heap tuples, but are not included in upper-level + index entries used for tree navigation. @@ -360,46 +356,17 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] The optional WITH clause specifies storage parameters for the index. Each index method has its own set of allowed - storage parameters. All indexes accept the following parameter: + storage parameters. The B-tree, hash, GiST and SP-GiST index methods all + accept this parameter: - - recheck_on_update - - - Specifies whether to recheck a functional index value to see whether - we can use a HOT update or not. The default value is on for functional - indexes with an total expression cost less than 1000, otherwise off. - You might decide to turn this off if you knew that a function used in - an index is unlikely to return the same value when one of the input - columns is updated and so the recheck is not worth the additional cost - of executing the function. - - - - Functional indexes are used frequently for the case where the function - returns a subset of the argument. Examples of this would be accessing - part of a string with SUBSTR() or accessing a single - field in a JSON document using an expression such as - (bookinfo->>'isbn'). In this example, the JSON - document might be updated frequently, yet it is uncommon for the ISBN - field for a book to change so we would keep the parameter set to on - for that index. A more frequently changing field might have an index - with this parameter turned off, while very frequently changing fields - might be better to avoid indexing at all under high load. - - - - - - - The B-tree, hash, GiST and SP-GiST index methods all accept this parameter: - - - - - fillfactor + + fillfactor + + fillfactor storage parameter + + The fillfactor for an index is a percentage that determines how full @@ -425,8 +392,13 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - vacuum_cleanup_index_scale_factor + + vacuum_cleanup_index_scale_factor + + vacuum_cleanup_index_scale_factor + storage parameter + + Per-index value for . @@ -440,8 +412,12 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - buffering + + buffering + + buffering storage parameter + + Determines whether the buffering build technique described in @@ -459,8 +435,12 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - fastupdate + + fastupdate + + fastupdate storage parameter + + This setting controls usage of the fast update technique described in @@ -483,9 +463,15 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] + - - gin_pending_list_limit + + gin_pending_list_limit + + gin_pending_list_limit + storage parameter + + Custom parameter. @@ -500,8 +486,12 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - pages_per_range + + pages_per_range + + pages_per_range storage parameter + + Defines the number of table blocks that make up one block range for @@ -511,8 +501,12 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] - - autosummarize + + autosummarize + + autosummarize storage parameter + + Defines whether a summarization run is invoked for the previous page @@ -592,10 +586,8 @@ Indexes: The recommended recovery method in such cases is to drop the index and try again to perform - CREATE INDEX CONCURRENTLY. (Another possibility is to rebuild - the index with REINDEX. However, since REINDEX - does not support concurrent builds, this option is unlikely to seem - attractive.) + CREATE INDEX CONCURRENTLY. (Another possibility is + to rebuild the index with REINDEX INDEX CONCURRENTLY). @@ -616,12 +608,23 @@ Indexes: Regular index builds permit other regular index builds on the - same table to occur in parallel, but only one concurrent index build - can occur on a table at a time. In both cases, no other types of schema - modification on the table are allowed meanwhile. Another difference - is that a regular CREATE INDEX command can be performed within - a transaction block, but CREATE INDEX CONCURRENTLY cannot. + same table to occur simultaneously, but only one concurrent index build + can occur on a table at a time. In either case, schema modification of the + table is not allowed while the index is being built. Another difference is + that a regular CREATE INDEX command can be performed + within a transaction block, but CREATE INDEX CONCURRENTLY + cannot. + + + Concurrent builds for indexes on partitioned tables are currently not + supported. However, you may concurrently build the index on each + partition individually and then finally create the partitioned index + non-concurrently in order to reduce the time where writes to the + partitioned table will be locked out. In this case, building the + partitioned index is a metadata only operation. + + @@ -654,7 +657,7 @@ Indexes: ordering. For example, we might want to sort a complex-number data type either by absolute value or by real part. We could do this by defining two operator classes for the data type and then selecting - the proper class when making an index. More information about + the proper class when creating an index. More information about operator classes is in and in . @@ -672,12 +675,13 @@ Indexes: will be determined as if no index name had been specified in the command. If the ONLY option is specified, no recursion - is done, and the index is marked invalid - (ALTER INDEX ... ATTACH PARTITION turns the index - valid, once all partitions acquire the index.) Note, however, that - any partition that is created in the future using + is done, and the index is marked invalid. + (ALTER INDEX ... ATTACH PARTITION marks the index + valid, once all partitions acquire matching indexes.) Note, however, + that any partition that is created in the future using CREATE TABLE ... PARTITION OF will automatically - contain the index regardless of whether this option was specified. + have a matching index, regardless of whether ONLY is + specified. @@ -789,8 +793,8 @@ CREATE UNIQUE INDEX title_idx ON films (title); To create a unique B-tree index on the column title - and included columns director and rating - in the table films: + with included columns director + and rating in the table films: CREATE UNIQUE INDEX title_idx ON films (title) INCLUDE (director, rating); @@ -879,6 +883,7 @@ CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity); + diff --git a/doc/src/sgml/ref/create_language.sgml b/doc/src/sgml/ref/create_language.sgml index 6bb69cf0ef6..13b28b1cccb 100644 --- a/doc/src/sgml/ref/create_language.sgml +++ b/doc/src/sgml/ref/create_language.sgml @@ -33,7 +33,7 @@ CREATE [ OR REPLACE ] [ TRUSTED ] [ PROCEDURAL ] LANGUAGE method ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ TABLESPACE tablespace_name ] AS query @@ -45,8 +46,7 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name CREATE TABLE AS, except that it also remembers the query used to initialize the view, so that it can be refreshed later upon demand. A materialized view has many of the same properties as a table, but there - is no support for temporary materialized views or automatic generation of - OIDs. + is no support for temporary materialized views. @@ -86,6 +86,21 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name + + USING method + + + This optional clause specifies the table access method to use to store + the contents for the new materialized view; the method needs be an + access method of type TABLE. See for more information. If this option is not + specified, the default table access method is chosen for the new + materialized view. See + for more information. + + + + WITH ( storage_parameter [= value] [, ... ] ) @@ -95,7 +110,7 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name endterm="sql-createtable-storage-parameters-title"/> for more information. All parameters supported for CREATE TABLE are also supported for CREATE MATERIALIZED - VIEW with the exception of OIDS. + VIEW. See for more information. diff --git a/doc/src/sgml/ref/create_opclass.sgml b/doc/src/sgml/ref/create_opclass.sgml index 0714aeca7ca..dd5252fd976 100644 --- a/doc/src/sgml/ref/create_opclass.sgml +++ b/doc/src/sgml/ref/create_opclass.sgml @@ -38,7 +38,7 @@ CREATE OPERATOR CLASS name [ DEFAUL An operator class defines how a particular data type can be used with an index. The operator class specifies that certain operators will fill particular roles or strategies for this data type and this - index method. The operator class also specifies the support procedures to + index method. The operator class also specifies the support functions to be used by the index method when the operator class is selected for an index column. All the operators and functions used by an operator @@ -201,7 +201,7 @@ CREATE OPERATOR CLASS name [ DEFAUL support_number - The index method's support procedure number for a + The index method's support function number for a function associated with the operator class. @@ -212,7 +212,7 @@ CREATE OPERATOR CLASS name [ DEFAUL The name (optionally schema-qualified) of a function that is an - index method support procedure for the operator class. + index method support function for the operator class. diff --git a/doc/src/sgml/ref/create_operator.sgml b/doc/src/sgml/ref/create_operator.sgml index 35f2f46985b..d5c385c087f 100644 --- a/doc/src/sgml/ref/create_operator.sgml +++ b/doc/src/sgml/ref/create_operator.sgml @@ -22,7 +22,7 @@ PostgreSQL documentation CREATE OPERATOR name ( - PROCEDURE = function_name + {FUNCTION|PROCEDURE} = function_name [, LEFTARG = left_type ] [, RIGHTARG = right_type ] [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ] [, RESTRICT = res_proc ] [, JOIN = join_proc ] @@ -94,11 +94,19 @@ CREATE OPERATOR name ( The function_name - procedure must have been previously defined using CREATE + function must have been previously defined using CREATE FUNCTION and must be defined to accept the correct number of arguments (either one or two) of the indicated types. + + In the syntax of CREATE OPERATOR, the keywords + FUNCTION and PROCEDURE are + equivalent, but the referenced function must in any case be a function, not + a procedure. The use of the keyword PROCEDURE here is + historical and deprecated. + + The other clauses specify optional operator optimization clauses. Their meaning is detailed in . @@ -264,11 +272,11 @@ COMMUTATOR = OPERATOR(myschema.===) , CREATE OPERATOR === ( LEFTARG = box, RIGHTARG = box, - PROCEDURE = area_equal_procedure, + FUNCTION = area_equal_function, COMMUTATOR = ===, NEGATOR = !==, - RESTRICT = area_restriction_procedure, - JOIN = area_join_procedure, + RESTRICT = area_restriction_function, + JOIN = area_join_function, HASHES, MERGES ); diff --git a/doc/src/sgml/ref/create_policy.sgml b/doc/src/sgml/ref/create_policy.sgml index 32f39a48ba9..2e1229c4f94 100644 --- a/doc/src/sgml/ref/create_policy.sgml +++ b/doc/src/sgml/ref/create_policy.sgml @@ -94,13 +94,6 @@ CREATE POLICY name ON default deny policy is assumed, so that no rows will be visible or updatable. - - - No separate policy exists for MERGE. Instead policies - defined for SELECT, INSERT, - UPDATE and DELETE are applied - while executing MERGE, depending on the actions that are activated. - @@ -564,8 +557,7 @@ AND OR ... ) - - + diff --git a/doc/src/sgml/ref/create_procedure.sgml b/doc/src/sgml/ref/create_procedure.sgml index f3c3bb006cf..6c1de34b012 100644 --- a/doc/src/sgml/ref/create_procedure.sgml +++ b/doc/src/sgml/ref/create_procedure.sgml @@ -203,6 +203,12 @@ CREATE [ OR REPLACE ] PROCEDURE conformance, but it is optional since, unlike in SQL, this feature applies to all procedures not only external ones. + + + A SECURITY DEFINER procedure cannot execute + transaction control statements (for example, COMMIT + and ROLLBACK, depending on the language). + diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml index 9c3b6978af4..db842732a8d 100644 --- a/doc/src/sgml/ref/create_role.sgml +++ b/doc/src/sgml/ref/create_role.sgml @@ -33,7 +33,7 @@ CREATE ROLE name [ [ WITH ] connlimit - | [ ENCRYPTED ] PASSWORD 'password' + | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] @@ -210,7 +210,8 @@ CREATE ROLE name [ [ WITH ] - [ ENCRYPTED ] PASSWORD password + [ ENCRYPTED ] PASSWORD 'password' + PASSWORD NULL Sets the role's password. (A password is only of use for diff --git a/doc/src/sgml/ref/create_statistics.sgml b/doc/src/sgml/ref/create_statistics.sgml index 382a1eb64bf..5b583aacb43 100644 --- a/doc/src/sgml/ref/create_statistics.sgml +++ b/doc/src/sgml/ref/create_statistics.sgml @@ -81,9 +81,10 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na A statistics kind to be computed in this statistics object. Currently supported kinds are - ndistinct, which enables n-distinct statistics, and + ndistinct, which enables n-distinct statistics, dependencies, which enables functional - dependency statistics. + dependency statistics, and mcv which enables + most-common values lists. If this clause is omitted, all supported statistics kinds are included in the statistics object. For more information, see @@ -97,7 +98,8 @@ CREATE STATISTICS [ IF NOT EXISTS ] statistics_na The name of a table column to be covered by the computed statistics. - At least two column names must be given. + At least two column names must be given; the order of the column names + is insignificant. @@ -161,7 +163,37 @@ EXPLAIN ANALYZE SELECT * FROM t1 WHERE (a = 1) AND (b = 0); multiply their selectivities together to arrive at a much-too-small row count estimate. With such statistics, the planner recognizes that the WHERE - conditions are redundant and does not underestimate the rowcount. + conditions are redundant and does not underestimate the row count. + + + + Create table t2 with two perfectly correlated columns + (containing identical data), and a MCV list on those columns: + + +CREATE TABLE t2 ( + a int, + b int +); + +INSERT INTO t2 SELECT mod(i,100), mod(i,100) + FROM generate_series(1,1000000) s(i); + +CREATE STATISTICS s2 (mcv) ON a, b FROM t2; + +ANALYZE t2; + +-- valid combination (found in MCV) +EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 1); + +-- invalid combination (not found in MCV) +EXPLAIN ANALYZE SELECT * FROM t2 WHERE (a = 1) AND (b = 2); + + + The MCV list gives the planner more detailed information about the + specific values that commonly appear in the table, as well as an upper + bound on the selectivities of combinations of values that do not appear + in the table, allowing it to generate better estimates in both cases. diff --git a/doc/src/sgml/ref/create_subscription.sgml b/doc/src/sgml/ref/create_subscription.sgml index 49e4841188b..1a90c244fbf 100644 --- a/doc/src/sgml/ref/create_subscription.sgml +++ b/doc/src/sgml/ref/create_subscription.sgml @@ -49,8 +49,8 @@ CREATE SUBSCRIPTION subscription_name - Additional info about subscriptions and logical replication as a whole - can is available at and + Additional information about subscriptions and logical replication as a + whole is available at and . diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index cb3867dbd52..a7d351308f3 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -29,7 +29,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI ] ) [ INHERITS ( parent_table [, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] -[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] +[ USING method ] +[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] @@ -40,7 +41,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [, ... ] ) ] [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] -[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] +[ USING method ] +[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] @@ -51,7 +53,8 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI [, ... ] ) ] { FOR VALUES partition_bound_spec | DEFAULT } [ PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ] -[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] +[ USING method ] +[ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] @@ -62,37 +65,40 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI NULL | CHECK ( expression ) [ NO INHERIT ] | DEFAULT default_expr | + GENERATED ALWAYS AS ( generation_expr ) STORED | GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] | UNIQUE index_parameters | PRIMARY KEY index_parameters | REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] - [ ON DELETE action ] [ ON UPDATE action ] } + [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and table_constraint is: [ CONSTRAINT constraint_name ] { CHECK ( expression ) [ NO INHERIT ] | - UNIQUE ( column_name [, ... ] ) index_parameters INCLUDE (column_name [, ...]) | - PRIMARY KEY ( column_name [, ... ] ) index_parameters INCLUDE (column_name [, ...]) | + UNIQUE ( column_name [, ... ] ) index_parameters | + PRIMARY KEY ( column_name [, ... ] ) index_parameters | EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] | FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] - [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] } + [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] } [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ] and like_option is: -{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } +{ INCLUDING | EXCLUDING } { COMMENTS | CONSTRAINTS | DEFAULTS | GENERATED | IDENTITY | INDEXES | STATISTICS | STORAGE | ALL } and partition_bound_spec is: -IN ( { numeric_literal | string_literal | NULL } [, ...] ) | -FROM ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) - TO ( { numeric_literal | string_literal | MINVALUE | MAXVALUE } [, ...] ) | +IN ( partition_bound_expr [, ...] ) | +FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) + TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) | WITH ( MODULUS numeric_literal, REMAINDER numeric_literal ) index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are: +[ INCLUDE ( column_name [, ... ] ) ] [ WITH ( storage_parameter [= value] [, ... ] ) ] [ USING INDEX TABLESPACE tablespace_name ] @@ -250,6 +256,142 @@ WITH ( MODULUS numeric_literal, REM + + column_name + + + The name of a column to be created in the new table. + + + + + + data_type + + + The data type of the column. This can include array + specifiers. For more information on the data types supported by + PostgreSQL, refer to . + + + + + + COLLATE collation + + + The COLLATE clause assigns a collation to + the column (which must be of a collatable data type). + If not specified, the column data type's default collation is used. + + + + + + INHERITS ( parent_table [, ... ] ) + + + The optional INHERITS clause specifies a list of + tables from which the new table automatically inherits all + columns. Parent tables can be plain tables or foreign tables. + + + + Use of INHERITS creates a persistent relationship + between the new child table and its parent table(s). Schema + modifications to the parent(s) normally propagate to children + as well, and by default the data of the child table is included in + scans of the parent(s). + + + + If the same column name exists in more than one parent + table, an error is reported unless the data types of the columns + match in each of the parent tables. If there is no conflict, + then the duplicate columns are merged to form a single column in + the new table. If the column name list of the new table + contains a column name that is also inherited, the data type must + likewise match the inherited column(s), and the column + definitions are merged into one. If the + new table explicitly specifies a default value for the column, + this default overrides any defaults from inherited declarations + of the column. Otherwise, any parents that specify default + values for the column must all specify the same default, or an + error will be reported. + + + + CHECK constraints are merged in essentially the same way as + columns: if multiple parent tables and/or the new table definition + contain identically-named CHECK constraints, these + constraints must all have the same check expression, or an error will be + reported. Constraints having the same name and expression will + be merged into one copy. A constraint marked NO INHERIT in a + parent will not be considered. Notice that an unnamed CHECK + constraint in the new table will never be merged, since a unique name + will always be chosen for it. + + + + Column STORAGE settings are also copied from parent tables. + + + + If a column in the parent table is an identity column, that property is + not inherited. A column in the child table can be declared identity + column if desired. + + + + + + PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) + + + The optional PARTITION BY clause specifies a strategy + of partitioning the table. The table thus created is called a + partitioned table. The parenthesized list of + columns or expressions forms the partition key + for the table. When using range or hash partitioning, the partition key + can include multiple columns or expressions (up to 32, but this limit can + be altered when building PostgreSQL), but for + list partitioning, the partition key must consist of a single column or + expression. + + + + Range and list partitioning require a btree operator class, while hash + partitioning requires a hash operator class. If no operator class is + specified explicitly, the default operator class of the appropriate + type will be used; if no default operator class exists, an error will + be raised. When hash partitioning is used, the operator class used + must implement support function 2 (see + for details). + + + + A partitioned table is divided into sub-tables (called partitions), + which are created using separate CREATE TABLE commands. + The partitioned table is itself empty. A data row inserted into the + table is routed to a partition based on the value of columns or + expressions in the partition key. If no existing partition matches + the values in the new row, an error will be reported. + + + + Partitioned tables do not support EXCLUDE constraints; + however, you can define these constraints on individual partitions. + + + + See for more discussion on table + partitioning. + + + + + PARTITION OF parent_table { FOR VALUES partition_bound_spec | DEFAULT } @@ -257,8 +399,7 @@ WITH ( MODULUS numeric_literal, REM Creates the table as a partition of the specified parent table. The table can be created either as a partition for specific values using FOR VALUES or as a default partition - using DEFAULT. This option is not available for - hash-partitioned tables. + using DEFAULT. @@ -272,12 +413,13 @@ WITH ( MODULUS numeric_literal, REM - Each of the values specified in - the partition_bound_spec is - a literal, NULL, MINVALUE, or - MAXVALUE. Each literal value must be either a - numeric constant that is coercible to the corresponding partition key - column's type, or a string literal that is valid input for that type. + partition_bound_expr is + any variable-free expression (subqueries, window functions, aggregate + functions, and set-returning functions are not allowed). Its data type + must match the data type of the corresponding partition key column. + The expression is evaluated once at table creation time, so it can + even contain volatile expressions such as + CURRENT_TIMESTAMP. @@ -348,16 +490,15 @@ WITH ( MODULUS numeric_literal, REM If DEFAULT is specified, the table will be - created as a default partition of the parent table. The parent can - either be a list or range partitioned table. A partition key value + created as the default partition of the parent table. This option + is not available for hash-partitioned tables. A partition key value not fitting into any other partition of the given parent will be - routed to the default partition. There can be only one default - partition for a given parent table. + routed to the default partition. When a table has an existing DEFAULT partition and - a new partition is added to it, the existing default partition must + a new partition is added to it, the default partition must be scanned to verify that it does not contain any rows which properly belong in the new partition. If the default partition contains a large number of rows, this may be slow. The scan will be skipped if @@ -391,25 +532,19 @@ WITH ( MODULUS numeric_literal, REM A partition must have the same column names and types as the partitioned - table to which it belongs. If the parent is specified WITH - OIDS then all partitions must have OIDs; the parent's OID - column will be inherited by all partitions just like any other column. - Modifications to the column names or types of a partitioned table, or - the addition or removal of an OID column, will automatically propagate - to all partitions. CHECK constraints will be inherited - automatically by every partition, but an individual partition may specify - additional CHECK constraints; additional constraints with - the same name and condition as in the parent will be merged with the - parent constraint. Defaults may be specified separately for each - partition. + table to which it belongs. Modifications to the column names or types of + a partitioned table will automatically propagate to all partitions. + CHECK constraints will be inherited automatically by + every partition, but an individual partition may specify additional + CHECK constraints; additional constraints with the + same name and condition as in the parent will be merged with the parent + constraint. Defaults may be specified separately for each partition. Rows inserted into a partitioned table will be automatically routed to the correct partition. If no suitable partition exists, an error will - occur. Also, if updating a row in a given partition would require it - to move to another partition due to new partition key values, an error - will occur. + occur. @@ -422,140 +557,6 @@ WITH ( MODULUS numeric_literal, REM - - column_name - - - The name of a column to be created in the new table. - - - - - - data_type - - - The data type of the column. This can include array - specifiers. For more information on the data types supported by - PostgreSQL, refer to . - - - - - - COLLATE collation - - - The COLLATE clause assigns a collation to - the column (which must be of a collatable data type). - If not specified, the column data type's default collation is used. - - - - - - INHERITS ( parent_table [, ... ] ) - - - The optional INHERITS clause specifies a list of - tables from which the new table automatically inherits all - columns. Parent tables can be plain tables or foreign tables. - - - - Use of INHERITS creates a persistent relationship - between the new child table and its parent table(s). Schema - modifications to the parent(s) normally propagate to children - as well, and by default the data of the child table is included in - scans of the parent(s). - - - - If the same column name exists in more than one parent - table, an error is reported unless the data types of the columns - match in each of the parent tables. If there is no conflict, - then the duplicate columns are merged to form a single column in - the new table. If the column name list of the new table - contains a column name that is also inherited, the data type must - likewise match the inherited column(s), and the column - definitions are merged into one. If the - new table explicitly specifies a default value for the column, - this default overrides any defaults from inherited declarations - of the column. Otherwise, any parents that specify default - values for the column must all specify the same default, or an - error will be reported. - - - - CHECK constraints are merged in essentially the same way as - columns: if multiple parent tables and/or the new table definition - contain identically-named CHECK constraints, these - constraints must all have the same check expression, or an error will be - reported. Constraints having the same name and expression will - be merged into one copy. A constraint marked NO INHERIT in a - parent will not be considered. Notice that an unnamed CHECK - constraint in the new table will never be merged, since a unique name - will always be chosen for it. - - - - Column STORAGE settings are also copied from parent tables. - - - - If a column in the parent table is an identity column, that property is - not inherited. A column in the child table can be declared identity - column if desired. - - - - - - PARTITION BY { RANGE | LIST | HASH } ( { column_name | ( expression ) } [ opclass ] [, ...] ) - - - The optional PARTITION BY clause specifies a strategy - of partitioning the table. The table thus created is called a - partitioned table. The parenthesized list of - columns or expressions forms the partition key - for the table. When using range or hash partitioning, the partition key - can include multiple columns or expressions (up to 32, but this limit can - be altered when building PostgreSQL), but for - list partitioning, the partition key must consist of a single column or - expression. - - - - Range and list partitioning require a btree operator class, while hash - partitioning requires a hash operator class. If no operator class is - specified explicitly, the default operator class of the appropriate - type will be used; if no default operator class exists, an error will - be raised. When hash partitioning is used, the operator class used - must implement support function 2 (see - for details). - - - - A partitioned table is divided into sub-tables (called partitions), - which are created using separate CREATE TABLE commands. - The partitioned table is itself empty. A data row inserted into the - table is routed to a partition based on the value of columns or - expressions in the partition key. If no existing partition matches - the values in the new row, an error will be reported. - - - - Partitioned tables do not support EXCLUDE constraints; - however, you can define these constraints on individual partitions. - Also, while it's possible to define PRIMARY KEY - constraints on partitioned tables, creating foreign keys that - reference a partitioned table is not yet supported. - - - - - LIKE source_table [ like_option ... ] @@ -571,66 +572,134 @@ WITH ( MODULUS numeric_literal, REM possible to include data of the new table in scans of the original table. - - Default expressions for the copied column definitions will be copied - only if INCLUDING DEFAULTS is specified. The - default behavior is to exclude default expressions, resulting in the - copied columns in the new table having null defaults. - Note that copying defaults that call database-modification functions, - such as nextval, may create a functional linkage between - the original and new tables. - - - Any identity specifications of copied column definitions will only be - copied if INCLUDING IDENTITY is specified. A new - sequence is created for each identity column of the new table, separate - from the sequences associated with the old table. - - - Not-null constraints are always copied to the new table. - CHECK constraints will be copied only if - INCLUDING CONSTRAINTS is specified. - No distinction is made between column constraints and table - constraints. - - - Extended statistics are copied to the new table if - INCLUDING STATISTICS is specified. - - - Indexes, PRIMARY KEY, UNIQUE, - and EXCLUDE constraints on the original table will be - created on the new table only if INCLUDING INDEXES - is specified. Names for the new indexes and constraints are - chosen according to the default rules, regardless of how the originals - were named. (This behavior avoids possible duplicate-name failures for - the new indexes.) - - - STORAGE settings for the copied column definitions will be - copied only if INCLUDING STORAGE is specified. The - default behavior is to exclude STORAGE settings, resulting - in the copied columns in the new table having type-specific default - settings. For more on STORAGE settings, see - . - - - Comments for the copied columns, constraints, and indexes - will be copied only if INCLUDING COMMENTS - is specified. The default behavior is to exclude comments, resulting in - the copied columns and constraints in the new table having no comments. - - - INCLUDING ALL is an abbreviated form of - INCLUDING COMMENTS INCLUDING CONSTRAINTS INCLUDING DEFAULTS INCLUDING IDENTITY INCLUDING INDEXES INCLUDING STATISTICS INCLUDING STORAGE. - - - Note that unlike INHERITS, columns and + + Also unlike INHERITS, columns and constraints copied by LIKE are not merged with similarly named columns and constraints. If the same name is specified explicitly or in another LIKE clause, an error is signaled. + + The optional like_option clauses specify + which additional properties of the original table to copy. Specifying + INCLUDING copies the property, specifying + EXCLUDING omits the property. + EXCLUDING is the default. If multiple specifications + are made for the same kind of object, the last one is used. The + available options are: + + + + INCLUDING COMMENTS + + + Comments for the copied columns, constraints, and indexes will be + copied. The default behavior is to exclude comments, resulting in + the copied columns and constraints in the new table having no + comments. + + + + + + INCLUDING CONSTRAINTS + + + CHECK constraints will be copied. No distinction + is made between column constraints and table constraints. Not-null + constraints are always copied to the new table. + + + + + + INCLUDING DEFAULTS + + + Default expressions for the copied column definitions will be + copied. Otherwise, default expressions are not copied, resulting in + the copied columns in the new table having null defaults. Note that + copying defaults that call database-modification functions, such as + nextval, may create a functional linkage + between the original and new tables. + + + + + + INCLUDING GENERATED + + + Any generation expressions of copied column definitions will be + copied. By default, new columns will be regular base columns. + + + + + + INCLUDING IDENTITY + + + Any identity specifications of copied column definitions will be + copied. A new sequence is created for each identity column of the + new table, separate from the sequences associated with the old + table. + + + + + + INCLUDING INDEXES + + + Indexes, PRIMARY KEY, UNIQUE, + and EXCLUDE constraints on the original table + will be created on the new table. Names for the new indexes and + constraints are chosen according to the default rules, regardless of + how the originals were named. (This behavior avoids possible + duplicate-name failures for the new indexes.) + + + + + + INCLUDING STATISTICS + + + Extended statistics are copied to the new table. + + + + + + INCLUDING STORAGE + + + STORAGE settings for the copied column + definitions will be copied. The default behavior is to exclude + STORAGE settings, resulting in the copied columns + in the new table having type-specific default settings. For more on + STORAGE settings, see . + + + + + + INCLUDING ALL + + + INCLUDING ALL is an abbreviated form selecting + all the available individual options. (It could be useful to write + individual EXCLUDING clauses after + INCLUDING ALL to select all but some specific + options.) + + + + + + The LIKE clause can also be used to copy column definitions from views, foreign tables, or composite types. @@ -696,7 +765,8 @@ WITH ( MODULUS numeric_literal, REM Currently, CHECK expressions cannot contain subqueries nor refer to variables other than columns of the - current row. The system column tableoid + current row (see ). + The system column tableoid may be referenced, but not any other system column. @@ -722,10 +792,10 @@ WITH ( MODULUS numeric_literal, REM The DEFAULT clause assigns a default data value for the column whose column definition it appears within. The value - is any variable-free expression (subqueries and cross-references - to other columns in the current table are not allowed). The - data type of the default expression must match the data type of the - column. + is any variable-free expression (in particular, cross-references + to other columns in the current table are not allowed). Subqueries + are not allowed either. The data type of the default expression must + match the data type of the column. @@ -736,6 +806,28 @@ WITH ( MODULUS numeric_literal, REM + + GENERATED ALWAYS AS ( generation_expr ) STOREDgenerated column + + + This clause creates the column as a generated + column. The column cannot be written to, and when read the + result of the specified expression will be returned. + + + + The keyword STORED is required to signify that the + column will be computed on write and will be stored on disk. + + + + The generation expression can refer to other columns in the table, but + not other generated columns. Any functions and operators used must be + immutable. References to other tables are not allowed. + + + + GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] @@ -807,9 +899,8 @@ WITH ( MODULUS numeric_literal, REM one or more columns on which the uniqueness is not enforced. Note that although the constraint is not enforced on the included columns, it still depends on them. Consequently, some operations on these columns - (e.g. DROP COLUMN) can cause cascade constraint and - index deletion. See paragraph about INCLUDE in - for more information. + (e.g. DROP COLUMN) can cause cascaded constraint and + index deletion. @@ -854,9 +945,8 @@ WITH ( MODULUS numeric_literal, REM of columns to be specified which will be included in the non-key portion of the index. Although uniqueness is not enforced on the included columns, the constraint still depends on them. Consequently, some operations on the - included columns (e.g. DROP COLUMN) can cause cascade - constraint and index deletion. See paragraph about INCLUDE - in for more information. + included columns (e.g. DROP COLUMN) can cause cascaded + constraint and index deletion. @@ -912,13 +1002,13 @@ WITH ( MODULUS numeric_literal, REM - REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE action ] [ ON UPDATE action ] (column constraint) + REFERENCES reftable [ ( refcolumn ) ] [ MATCH matchtype ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] (column constraint) FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ] [ MATCH matchtype ] - [ ON DELETE action ] - [ ON UPDATE action ] + [ ON DELETE referential_action ] + [ ON UPDATE referential_action ] (table constraint) @@ -932,11 +1022,11 @@ WITH ( MODULUS numeric_literal, REM is used. The referenced columns must be the columns of a non-deferrable unique or primary key constraint in the referenced table. The user must have REFERENCES permission on the referenced table - (either the whole table, or the specific referenced columns). + (either the whole table, or the specific referenced columns). The + addition of a foreign key constraint requires a + SHARE ROW EXCLUSIVE lock on the referenced table. Note that foreign key constraints cannot be defined between temporary - tables and permanent tables. Also note that while it is possible to - define a foreign key on a partitioned table, it is not possible to - declare a foreign key that references a partitioned table. + tables and permanent tables. @@ -1076,6 +1166,20 @@ WITH ( MODULUS numeric_literal, REM + + USING method + + + This optional clause specifies the table access method to use to store + the contents for the new table; the method needs be an access method of + type TABLE. See for more + information. If this option is not specified, the default table access + method is chosen for the new table. See for more information. + + + + WITH ( storage_parameter [= value] [, ... ] ) @@ -1083,46 +1187,21 @@ WITH ( MODULUS numeric_literal, REM This clause specifies optional storage parameters for a table or index; see for more - information. The WITH clause for a - table can also include OIDS=TRUE (or just OIDS) - to specify that rows of the new table - should have OIDs (object identifiers) assigned to them, or - OIDS=FALSE to specify that the rows should not have OIDs. - If OIDS is not specified, the default setting depends upon - the configuration parameter. - (If the new table inherits from any tables that have OIDs, then - OIDS=TRUE is forced even if the command says - OIDS=FALSE.) - - - - If OIDS=FALSE is specified or implied, the new - table does not store OIDs and no OID will be assigned for a row inserted - into it. This is generally considered worthwhile, since it - will reduce OID consumption and thereby postpone the wraparound - of the 32-bit OID counter. Once the counter wraps around, OIDs - can no longer be assumed to be unique, which makes them - considerably less useful. In addition, excluding OIDs from a - table reduces the space required to store the table on disk by - 4 bytes per row (on most machines), slightly improving performance. - - - - To remove OIDs from a table after it has been created, use . + information. For backward-compatibility the WITH + clause for a table can also include OIDS=FALSE to + specify that rows of the new table should not contain OIDs (object + identifiers), OIDS=TRUE is not supported anymore. - WITH OIDS WITHOUT OIDS - These are obsolescent syntaxes equivalent to WITH (OIDS) - and WITH (OIDS=FALSE), respectively. If you wish to give - both an OIDS setting and storage parameters, you must use - the WITH ( ... ) syntax; see above. + This is backward-compatible syntax for declaring a table + WITHOUT OIDS, creating a table WITH + OIDS is not supported anymore. @@ -1153,7 +1232,8 @@ WITH ( MODULUS numeric_literal, REM All rows in the temporary table will be deleted at the end of each transaction block. Essentially, an automatic is done - at each commit. + at each commit. When used on a partitioned table, this + is not cascaded to its partitions. @@ -1163,7 +1243,9 @@ WITH ( MODULUS numeric_literal, REM The temporary table will be dropped at the end of the current - transaction block. + transaction block. When used on a partitioned table, this action + drops its partitions and when used on tables with inheritance + children, it drops the dependent children. @@ -1171,7 +1253,7 @@ WITH ( MODULUS numeric_literal, REM - + TABLESPACE tablespace_name @@ -1179,7 +1261,11 @@ WITH ( MODULUS numeric_literal, REM of the tablespace in which the new table is to be created. If not specified, is consulted, or - if the table is temporary. + if the table is temporary. For + partitioned tables, since no storage is required for the table itself, + the tablespace specified overrides default_tablespace + as the default tablespace to use for any newly created partitions when no + other tablespace is explicitly specified. @@ -1228,8 +1314,12 @@ WITH ( MODULUS numeric_literal, REM - - fillfactor (integer) + + fillfactor (integer) + + fillfactor storage parameter + + The fillfactor for a table is a percentage between 10 and 100. @@ -1246,8 +1336,12 @@ WITH ( MODULUS numeric_literal, REM - - toast_tuple_target (integer) + + toast_tuple_target (integer) + + toast_tuple_target storage parameter + + The toast_tuple_target specifies the minimum tuple length required before @@ -1267,8 +1361,12 @@ WITH ( MODULUS numeric_literal, REM - - parallel_workers (integer) + + parallel_workers (integer) + + parallel_workers storage parameter + + This sets the number of workers that should be used to assist a parallel @@ -1280,8 +1378,12 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_enabled, toast.autovacuum_enabled (boolean) + + autovacuum_enabled, toast.autovacuum_enabled (boolean) + + autovacuum_enabled storage parameter + + Enables or disables the autovacuum daemon for a particular table. @@ -1301,8 +1403,53 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) + + vacuum_index_cleanup, toast.vacuum_index_cleanup (boolean) + + vacuum_index_cleanup storage parameter + + + + + Enables or disables index cleanup when VACUUM is + run on this table. The default value is true. + Disabling index cleanup can speed up VACUUM very + significantly, but may also lead to severely bloated indexes if table + modifications are frequent. The INDEX_CLEANUP + parameter of , if specified, overrides + the value of this option. + + + + + + vacuum_truncate, toast.vacuum_truncate (boolean) + + vacuum_truncate storage parameter + + + + + Enables or disables vacuum to try to truncate off any empty pages + at the end of this table. The default value is true. + If true, VACUUM and + autovacuum do the truncation and the disk space for + the truncated pages is returned to the operating system. + Note that the truncation requires ACCESS EXCLUSIVE + lock on the table. The TRUNCATE parameter + of , if specified, overrides the value + of this option. + + + + + + autovacuum_vacuum_threshold, toast.autovacuum_vacuum_threshold (integer) + + autovacuum_vacuum_threshold + storage parameter + + Per-table value for @@ -1311,8 +1458,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (float4) + + autovacuum_vacuum_scale_factor, toast.autovacuum_vacuum_scale_factor (float4) + + autovacuum_vacuum_scale_factor + storage parameter + + Per-table value for @@ -1321,8 +1473,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_analyze_threshold (integer) + + autovacuum_analyze_threshold (integer) + + autovacuum_analyze_threshold + storage parameter + + Per-table value for @@ -1331,8 +1488,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_analyze_scale_factor (float4) + + autovacuum_analyze_scale_factor (float4) + + autovacuum_analyze_scale_factor + storage parameter + + Per-table value for @@ -1341,8 +1503,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (integer) + + autovacuum_vacuum_cost_delay, toast.autovacuum_vacuum_cost_delay (floating point) + + autovacuum_vacuum_cost_delay + storage parameter + + Per-table value for @@ -1351,8 +1518,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) + + autovacuum_vacuum_cost_limit, toast.autovacuum_vacuum_cost_limit (integer) + + autovacuum_vacuum_cost_limit + storage parameter + + Per-table value for @@ -1361,8 +1533,12 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) + + autovacuum_freeze_min_age, toast.autovacuum_freeze_min_age (integer) + + autovacuum_freeze_min_age storage parameter + + Per-table value for @@ -1374,8 +1550,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) + + autovacuum_freeze_max_age, toast.autovacuum_freeze_max_age (integer) + + autovacuum_freeze_max_age + storage parameter + + Per-table value for @@ -1386,8 +1567,12 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) + + autovacuum_freeze_table_age, toast.autovacuum_freeze_table_age (integer) + + autovacuum_freeze_table_age storage parameter + + Per-table value for @@ -1396,8 +1581,12 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) + + autovacuum_multixact_freeze_min_age, toast.autovacuum_multixact_freeze_min_age (integer) + + autovacuum_multixact_freeze_min_age storage parameter + + Per-table value for @@ -1410,8 +1599,13 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) + + autovacuum_multixact_freeze_max_age, toast.autovacuum_multixact_freeze_max_age (integer) + + autovacuum_multixact_freeze_max_age + storage parameter + + Per-table value @@ -1424,8 +1618,12 @@ WITH ( MODULUS numeric_literal, REM - - autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) + + autovacuum_multixact_freeze_table_age, toast.autovacuum_multixact_freeze_table_age (integer) + + autovacuum_multixact_freeze_table_age storage parameter + + Per-table value @@ -1434,8 +1632,13 @@ WITH ( MODULUS numeric_literal, REM - - log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) + + log_autovacuum_min_duration, toast.log_autovacuum_min_duration (integer) + + log_autovacuum_min_duration + storage parameter + + Per-table value for @@ -1444,8 +1647,12 @@ WITH ( MODULUS numeric_literal, REM - - user_catalog_table (boolean) + + user_catalog_table (boolean) + + user_catalog_table storage parameter + + Declare the table as an additional catalog table for purposes of @@ -1463,29 +1670,6 @@ WITH ( MODULUS numeric_literal, REM Notes - - - Using OIDs in new applications is not recommended: where - possible, using an identity column or other sequence - generator as the table's primary key is preferred. However, if - your application does make use of OIDs to identify specific - rows of a table, it is recommended to create a unique constraint - on the oid column of that table, to ensure that - OIDs in the table will indeed uniquely identify rows even after - counter wraparound. Avoid assuming that OIDs are unique across - tables; if you need a database-wide unique identifier, use the - combination of tableoid and row OID for the - purpose. - - - - - The use of OIDS=FALSE is not recommended - for tables with no primary key, since without either an OID or a - unique data key, it is difficult to identify specific rows. - - - PostgreSQL automatically creates an index for each unique constraint and primary key constraint to @@ -1894,7 +2078,7 @@ CREATE TABLE cities_partdef - Non-deferred Uniqueness Constraints + Non-Deferred Uniqueness Constraints When a UNIQUE or PRIMARY KEY constraint is @@ -1944,6 +2128,30 @@ CREATE TABLE cities_partdef + + Constraint Naming + + + The SQL standard says that table and domain constraints must have names + that are unique across the schema containing the table or domain. + PostgreSQL is laxer: it only requires + constraint names to be unique across the constraints attached to a + particular table or domain. However, this extra freedom does not exist + for index-based constraints (UNIQUE, + PRIMARY KEY, and EXCLUDE + constraints), because the associated index is named the same as the + constraint, and index names must be unique across all relations within + the same schema. + + + + Currently, PostgreSQL does not record names + for NOT NULL constraints at all, so they are not + subject to the uniqueness restriction. This might change in a future + release. + + + Inheritance @@ -1958,7 +2166,7 @@ CREATE TABLE cities_partdef - Zero-column Tables + Zero-Column Tables PostgreSQL allows a table of no columns @@ -1984,6 +2192,16 @@ CREATE TABLE cities_partdef + + Generated Columns + + + The option STORED is not standard but is also used by + other SQL implementations. The SQL standard does not specify the storage + of generated columns. + + + <literal>LIKE</literal> Clause @@ -2000,7 +2218,7 @@ CREATE TABLE cities_partdef The WITH clause is a PostgreSQL - extension; neither storage parameters nor OIDs are in the standard. + extension; storage parameters are not in the standard. @@ -2021,9 +2239,9 @@ CREATE TABLE cities_partdef Typed tables implement a subset of the SQL standard. According to the standard, a typed table has columns corresponding to the underlying composite type as well as one other column that is - the self-referencing column. PostgreSQL does not - support these self-referencing columns explicitly, but the same - effect can be had using the OID feature. + the self-referencing column. + PostgreSQL does not support self-referencing + columns explicitly. diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml index 527138e7872..56d06838f16 100644 --- a/doc/src/sgml/ref/create_table_as.sgml +++ b/doc/src/sgml/ref/create_table_as.sgml @@ -23,7 +23,8 @@ PostgreSQL documentation CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] table_name [ (column_name [, ...] ) ] - [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ] + [ USING method ] + [ WITH ( storage_parameter [= value] [, ... ] ) | WITHOUT OIDS ] [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ] [ TABLESPACE tablespace_name ] AS query @@ -120,6 +121,20 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI + + USING method + + + This optional clause specifies the table access method to use to store + the contents for the new table; the method needs be an access method of + type TABLE. See for more + information. If this option is not specified, the default table access + method is chosen for the new table. See for more information. + + + + WITH ( storage_parameter [= value] [, ... ] ) @@ -127,25 +142,21 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI This clause specifies optional storage parameters for the new table; see for more - information. The WITH clause - can also include OIDS=TRUE (or just OIDS) - to specify that rows of the new table - should have OIDs (object identifiers) assigned to them, or - OIDS=FALSE to specify that the rows should not have OIDs. - See for more information. + information. For backward-compatibility the WITH + clause for a table can also include OIDS=FALSE to + specify that rows of the new table should contain no OIDs (object + identifiers), OIDS=TRUE is not supported anymore. - WITH OIDS WITHOUT OIDS - These are obsolescent syntaxes equivalent to WITH (OIDS) - and WITH (OIDS=FALSE), respectively. If you wish to give - both an OIDS setting and storage parameters, you must use - the WITH ( ... ) syntax; see above. + This is backward-compatible syntax for declaring a table + WITHOUT OIDS, creating a table WITH + OIDS is not supported anymore. @@ -245,14 +256,6 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI TABLE AS offers a superset of the functionality offered by SELECT INTO. - - - The CREATE TABLE AS command allows the user to - explicitly specify whether OIDs should be included. If the - presence of OIDs is not explicitly specified, - the configuration variable is - used. - @@ -281,12 +284,12 @@ CREATE TABLE films2 AS Create a new temporary table films_recent, consisting of only recent entries from the table films, using a - prepared statement. The new table has OIDs and will be dropped at commit: + prepared statement. The new table will be dropped at commit: PREPARE recentfilms(date) AS SELECT * FROM films WHERE date_prod > $1; -CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS +CREATE TEMP TABLE films_recent ON COMMIT DROP AS EXECUTE recentfilms('2002-01-01'); @@ -325,7 +328,7 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS The WITH clause is a PostgreSQL - extension; neither storage parameters nor OIDs are in the standard. + extension; storage parameters are not in the standard. diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml index 18fa5f0ebf0..c621ec2c6bf 100644 --- a/doc/src/sgml/ref/create_tablespace.sgml +++ b/doc/src/sgml/ref/create_tablespace.sgml @@ -92,7 +92,8 @@ CREATE TABLESPACE tablespace_name The directory that will be used for the tablespace. The directory - should be empty and must be owned by the + must exist (CREATE TABLESPACE will not create it), + should be empty, and must be owned by the PostgreSQL system user. The directory must be specified by an absolute path name. @@ -137,15 +138,23 @@ CREATE TABLESPACE tablespace_name Examples - Create a tablespace dbspace at /data/dbs: + To create a tablespace dbspace at file system location + /data/dbs, first create the directory using operating + system facilities and set the correct ownership: + +mkdir /data/dbs +chown postgres:postgres /data/dbs + + Then issue the tablespace creation command inside + PostgreSQL: CREATE TABLESPACE dbspace LOCATION '/data/dbs'; - Create a tablespace indexspace at /data/indexes - owned by user genevieve: + To create a tablespace owned by a different database user, use a command + like this: CREATE TABLESPACE indexspace OWNER genevieve LOCATION '/data/indexes'; diff --git a/doc/src/sgml/ref/create_transform.sgml b/doc/src/sgml/ref/create_transform.sgml index 17cb1932cfe..4bce36b41a7 100644 --- a/doc/src/sgml/ref/create_transform.sgml +++ b/doc/src/sgml/ref/create_transform.sgml @@ -157,7 +157,7 @@ CREATE [ OR REPLACE ] TRANSFORM FOR type_name LANGUAG CREATE TYPE hstore ...; -CREATE LANGUAGE plpythonu ...; +CREATE EXTENSION plpythonu; Then create the necessary functions: @@ -176,7 +176,7 @@ CREATE TRANSFORM FOR hstore LANGUAGE plpythonu ( TO SQL WITH FUNCTION plpython_to_hstore(internal) ); - In practice, these commands would be wrapped up in extensions. + In practice, these commands would be wrapped up in an extension. diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml index 7b971ee6b43..3339a4b4e16 100644 --- a/doc/src/sgml/ref/create_trigger.sgml +++ b/doc/src/sgml/ref/create_trigger.sgml @@ -33,7 +33,7 @@ CREATE [ CONSTRAINT ] TRIGGER name [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ] [ FOR [ EACH ] { ROW | STATEMENT } ] [ WHEN ( condition ) ] - EXECUTE PROCEDURE function_name ( arguments ) + EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments ) where event can be one of: @@ -261,7 +261,9 @@ CREATE [ CONSTRAINT ] TRIGGER name UPDATE OF column_name1 [, column_name2 ... ] The trigger will only fire if at least one of the listed columns - is mentioned as a target of the UPDATE command. + is mentioned as a target of the UPDATE command + or if one of the listed columns is a generated column that depends on a + column that is the target of the UPDATE. @@ -348,7 +350,7 @@ UPDATE OF column_name1 [, column_name2 - This specifies whether the trigger procedure should be fired + This specifies whether the trigger function should be fired once for every row affected by the trigger event, or just once per SQL statement. If neither is specified, FOR EACH STATEMENT is the default. Constraint triggers can only @@ -401,6 +403,14 @@ UPDATE OF column_name1 [, column_name2trigger, which is executed when the trigger fires. + + + In the syntax of CREATE TRIGGER, the keywords + FUNCTION and PROCEDURE are + equivalent, but the referenced function must in any case be a function, + not a procedure. The use of the keyword PROCEDURE + here is historical and deprecated. + @@ -455,7 +465,7 @@ UPDATE OF column_name1 [, column_name2NEW row seen by the condition is the current value, as possibly modified by earlier triggers. Also, a BEFORE trigger's WHEN condition is not allowed to examine the - system columns of the NEW row (such as oid), + system columns of the NEW row (such as ctid), because those won't have been set yet. @@ -555,7 +565,7 @@ UPDATE OF column_name1 [, column_name2 The same, but only execute the function if column balance @@ -565,7 +575,7 @@ CREATE TRIGGER check_update CREATE TRIGGER check_update BEFORE UPDATE OF balance ON accounts FOR EACH ROW - EXECUTE PROCEDURE check_account_update(); + EXECUTE FUNCTION check_account_update(); This form only executes the function if column balance @@ -576,7 +586,7 @@ CREATE TRIGGER check_update BEFORE UPDATE ON accounts FOR EACH ROW WHEN (OLD.balance IS DISTINCT FROM NEW.balance) - EXECUTE PROCEDURE check_account_update(); + EXECUTE FUNCTION check_account_update(); Call a function to log updates of accounts, but only if @@ -587,7 +597,7 @@ CREATE TRIGGER log_update AFTER UPDATE ON accounts FOR EACH ROW WHEN (OLD.* IS DISTINCT FROM NEW.*) - EXECUTE PROCEDURE log_account_update(); + EXECUTE FUNCTION log_account_update(); Execute the function view_insert_row for each row to insert @@ -597,7 +607,7 @@ CREATE TRIGGER log_update CREATE TRIGGER view_insert INSTEAD OF INSERT ON my_view FOR EACH ROW - EXECUTE PROCEDURE view_insert_row(); + EXECUTE FUNCTION view_insert_row(); Execute the function check_transfer_balances_to_zero for each @@ -609,7 +619,7 @@ CREATE TRIGGER transfer_insert AFTER INSERT ON transfer REFERENCING NEW TABLE AS inserted FOR EACH STATEMENT - EXECUTE PROCEDURE check_transfer_balances_to_zero(); + EXECUTE FUNCTION check_transfer_balances_to_zero(); Execute the function check_matching_pairs for each row to @@ -621,7 +631,7 @@ CREATE TRIGGER paired_items_update AFTER UPDATE ON paired_items REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab FOR EACH ROW - EXECUTE PROCEDURE check_matching_pairs(); + EXECUTE FUNCTION check_matching_pairs(); diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml index fa9b520b241..175315f3d7e 100644 --- a/doc/src/sgml/ref/create_type.sgml +++ b/doc/src/sgml/ref/create_type.sgml @@ -117,9 +117,12 @@ CREATE TYPE name The second form of CREATE TYPE creates an enumerated (enum) type, as described in . - Enum types take a list of one or more quoted labels, each of which + Enum types take a list of quoted labels, each of which must be less than NAMEDATALEN bytes long (64 bytes in a - standard PostgreSQL build). + standard PostgreSQL build). (It is possible to + create an enumerated type with zero labels, but such a type cannot be used + to hold values before at least one label is added using .) diff --git a/doc/src/sgml/ref/create_user.sgml b/doc/src/sgml/ref/create_user.sgml index a51dc50c978..198e06e7230 100644 --- a/doc/src/sgml/ref/create_user.sgml +++ b/doc/src/sgml/ref/create_user.sgml @@ -33,7 +33,7 @@ CREATE USER name [ [ WITH ] connlimit - | [ ENCRYPTED ] PASSWORD 'password' + | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] diff --git a/doc/src/sgml/ref/create_view.sgml b/doc/src/sgml/ref/create_view.sgml index b325c1be50f..e7a7e9fae27 100644 --- a/doc/src/sgml/ref/create_view.sgml +++ b/doc/src/sgml/ref/create_view.sgml @@ -82,7 +82,12 @@ CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] [ RECURSIVE ] VIEW - RECURSIVE + RECURSIVE + + RECURSIVE + in views + + Creates a recursive view. The syntax diff --git a/doc/src/sgml/ref/createdb.sgml b/doc/src/sgml/ref/createdb.sgml index 2658efeb1a1..8fc8128bf9c 100644 --- a/doc/src/sgml/ref/createdb.sgml +++ b/doc/src/sgml/ref/createdb.sgml @@ -322,6 +322,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml index 22ee99f2cc4..abe25f17d01 100644 --- a/doc/src/sgml/ref/createuser.sgml +++ b/doc/src/sgml/ref/createuser.sgml @@ -400,6 +400,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/declare.sgml b/doc/src/sgml/ref/declare.sgml index 648c2950f41..34ca9df2437 100644 --- a/doc/src/sgml/ref/declare.sgml +++ b/doc/src/sgml/ref/declare.sgml @@ -271,7 +271,8 @@ DECLARE name [ BINARY ] [ INSENSITI and not use grouping or ORDER BY). Cursors that are not simply updatable might work, or might not, depending on plan choice details; so in the worst case, an application might work in testing - and then fail in production. + and then fail in production. If FOR UPDATE is + specified, the cursor is guaranteed to be updatable. diff --git a/doc/src/sgml/ref/discard.sgml b/doc/src/sgml/ref/discard.sgml index 6b909b7232a..bf44c523cac 100644 --- a/doc/src/sgml/ref/discard.sgml +++ b/doc/src/sgml/ref/discard.sgml @@ -84,15 +84,15 @@ DISCARD { ALL | PLANS | SEQUENCES | TEMPORARY | TEMP } Currently, this has the same effect as executing the following sequence of statements: +CLOSE ALL; SET SESSION AUTHORIZATION DEFAULT; RESET ALL; DEALLOCATE ALL; -CLOSE ALL; UNLISTEN *; SELECT pg_advisory_unlock_all(); DISCARD PLANS; -DISCARD SEQUENCES; DISCARD TEMP; +DISCARD SEQUENCES; diff --git a/doc/src/sgml/ref/do.sgml b/doc/src/sgml/ref/do.sgml index b9a6f9a6fd6..a3a4877e80f 100644 --- a/doc/src/sgml/ref/do.sgml +++ b/doc/src/sgml/ref/do.sgml @@ -81,7 +81,7 @@ DO [ LANGUAGE lang_name ] The procedural language to be used must already have been installed - into the current database by means of CREATE LANGUAGE. + into the current database by means of CREATE EXTENSION. plpgsql is installed by default, but other languages are not. diff --git a/doc/src/sgml/ref/drop_owned.sgml b/doc/src/sgml/ref/drop_owned.sgml index 4c66da2b340..09107bef647 100644 --- a/doc/src/sgml/ref/drop_owned.sgml +++ b/doc/src/sgml/ref/drop_owned.sgml @@ -32,7 +32,7 @@ DROP OWNED BY { name | CURRENT_USER DROP OWNED drops all the objects within the current database that are owned by one of the specified roles. Any privileges granted to the given roles on objects in the current - database and on shared objects (databases, tablespaces) will also be + database or on shared objects (databases, tablespaces) will also be revoked. diff --git a/doc/src/sgml/ref/dropdb.sgml b/doc/src/sgml/ref/dropdb.sgml index 38f38f01ce6..3fbdb337164 100644 --- a/doc/src/sgml/ref/dropdb.sgml +++ b/doc/src/sgml/ref/dropdb.sgml @@ -228,6 +228,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/dropuser.sgml b/doc/src/sgml/ref/dropuser.sgml index 3d4e4b37b35..72bb7e8535c 100644 --- a/doc/src/sgml/ref/dropuser.sgml +++ b/doc/src/sgml/ref/dropuser.sgml @@ -220,6 +220,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/ecpg-ref.sgml b/doc/src/sgml/ref/ecpg-ref.sgml index 7bfee805a7d..df3c1054f0f 100644 --- a/doc/src/sgml/ref/ecpg-ref.sgml +++ b/doc/src/sgml/ref/ecpg-ref.sgml @@ -79,8 +79,8 @@ PostgreSQL documentation Set a compatibility mode. mode can - be INFORMIX or - INFORMIX_SE. + be INFORMIX, + INFORMIX_SE, or ORACLE. diff --git a/doc/src/sgml/ref/end.sgml b/doc/src/sgml/ref/end.sgml index 7523315f344..8b8f4f0dbb9 100644 --- a/doc/src/sgml/ref/end.sgml +++ b/doc/src/sgml/ref/end.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -END [ WORK | TRANSACTION ] +END [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] @@ -50,6 +50,18 @@ END [ WORK | TRANSACTION ] + + + AND CHAIN + + + If AND CHAIN is specified, a new transaction is + immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, + no new transaction is started. + + + diff --git a/doc/src/sgml/ref/explain.sgml b/doc/src/sgml/ref/explain.sgml index 8dc0d7038ac..385d10411fa 100644 --- a/doc/src/sgml/ref/explain.sgml +++ b/doc/src/sgml/ref/explain.sgml @@ -39,6 +39,7 @@ EXPLAIN [ ANALYZE ] [ VERBOSE ] statementboolean ] VERBOSE [ boolean ] COSTS [ boolean ] + SETTINGS [ boolean ] BUFFERS [ boolean ] TIMING [ boolean ] SUMMARY [ boolean ] @@ -152,6 +153,17 @@ ROLLBACK; + + SETTINGS + + + Include information on configuration parameters. Specifically, include + options affecting query planning with value different from the built-in + default value. This parameter defaults to FALSE. + + + + BUFFERS diff --git a/doc/src/sgml/ref/fetch.sgml b/doc/src/sgml/ref/fetch.sgml index 5ef63f00583..e802be61c8c 100644 --- a/doc/src/sgml/ref/fetch.sgml +++ b/doc/src/sgml/ref/fetch.sgml @@ -99,7 +99,7 @@ FETCH [ direction [ FROM | IN ] ] < This page describes usage of cursors at the SQL command level. If you are trying to use cursors inside a PL/pgSQL function, the rules are different — - see . + see . diff --git a/doc/src/sgml/ref/grant.sgml b/doc/src/sgml/ref/grant.sgml index ff64c7a3bae..e98fe860528 100644 --- a/doc/src/sgml/ref/grant.sgml +++ b/doc/src/sgml/ref/grant.sgml @@ -112,16 +112,6 @@ GRANT role_name [, ...] TO - - There is also an option to grant privileges on all objects of the same - type within one or more schemas. This functionality is currently supported - only for tables, sequences, functions, and procedures. ALL - TABLES also affects views and foreign tables, just like the - specific-object GRANT command. ALL - FUNCTIONS also affects aggregate functions, but not procedures, - again just like the specific-object GRANT command. - - The key word PUBLIC indicates that the privileges are to be granted to all roles, including those that might @@ -156,231 +146,35 @@ GRANT role_name [, ...] TO - - PostgreSQL grants default privileges on some types of objects to - PUBLIC. No privileges are granted to - PUBLIC by default on - tables, - table columns, - sequences, - foreign data wrappers, - foreign servers, - large objects, - schemas, - or tablespaces. - For other types of objects, the default privileges - granted to PUBLIC are as follows: - CONNECT and TEMPORARY (create - temporary tables) privileges for databases; - EXECUTE privilege for functions and procedures; and - USAGE privilege for languages and data types - (including domains). - The object owner can, of course, REVOKE - both default and expressly granted privileges. (For maximum - security, issue the REVOKE in the same transaction that - creates the object; then there is no window in which another user - can use the object.) - Also, these initial default privilege settings can be changed using the - - command. - - The possible privileges are: SELECT - - - Allows from - any column, or the specific columns listed, of the specified table, - view, or sequence. - Also allows the use of - TO. - This privilege is also needed to reference existing column values in - or - . - For sequences, this privilege also allows the use of the - currval function. - For large objects, this privilege allows the object to be read. - - - - - INSERT - - - Allows of a new - row into the specified table. If specific columns are listed, - only those columns may be assigned to in the INSERT - command (other columns will therefore receive default values). - Also allows FROM. - - - - - UPDATE - - - Allows of any - column, or the specific columns listed, of the specified table. - (In practice, any nontrivial UPDATE command will require - SELECT privilege as well, since it must reference table - columns to determine which rows to update, and/or to compute new - values for columns.) - SELECT ... FOR UPDATE - and SELECT ... FOR SHARE - also require this privilege on at least one column, in addition to the - SELECT privilege. For sequences, this - privilege allows the use of the nextval and - setval functions. - For large objects, this privilege allows writing or truncating the - object. - - - - - DELETE - - - Allows of a row - from the specified table. - (In practice, any nontrivial DELETE command will require - SELECT privilege as well, since it must reference table - columns to determine which rows to delete.) - - - - - TRUNCATE - - - Allows on - the specified table. - - - - - REFERENCES - - - Allows creation of a foreign key constraint referencing the specified - table, or specified column(s) of the table. (See the - statement.) - - - - - TRIGGER - - - Allows the creation of a trigger on the specified table. (See the - statement.) - - - - - CREATE - - - For databases, allows new schemas and publications to be created within the database. - - - For schemas, allows new objects to be created within the schema. - To rename an existing object, you must own the object and - have this privilege for the containing schema. - - - For tablespaces, allows tables, indexes, and temporary files to be - created within the tablespace, and allows databases to be created that - have the tablespace as their default tablespace. (Note that revoking - this privilege will not alter the placement of existing objects.) - - - - - CONNECT - - - Allows the user to connect to the specified database. This - privilege is checked at connection startup (in addition to checking - any restrictions imposed by pg_hba.conf). - - - - - TEMPORARY - TEMP - - - Allows temporary tables to be created while using the specified database. - - - - - EXECUTE + USAGE - Allows the use of the specified function or procedure and the use of - any operators that are implemented on top of the function. This is the - only type of privilege that is applicable to functions and procedures. - The FUNCTION syntax also works for aggregate - functions. Alternatively, use ROUTINE to refer to a function, - aggregate function, or procedure regardless of what it is. + Specific types of privileges, as defined in . - USAGE + TEMP - For procedural languages, allows the use of the specified language for - the creation of functions in that language. This is the only type - of privilege that is applicable to procedural languages. - - - For schemas, allows access to objects contained in the specified - schema (assuming that the objects' own privilege requirements are - also met). Essentially this allows the grantee to look up - objects within the schema. Without this permission, it is still - possible to see the object names, e.g. by querying the system tables. - Also, after revoking this permission, existing backends might have - statements that have previously performed this lookup, so this is not - a completely secure way to prevent object access. - - - For sequences, this privilege allows the use of the - currval and nextval functions. - - - For types and domains, this privilege allows the use of the type or - domain in the creation of tables, functions, and other schema objects. - (Note that it does not control general usage of the type, - such as values of the type appearing in queries. It only prevents - objects from being created that depend on the type. The main purpose of - the privilege is controlling which users create dependencies on a type, - which could prevent the owner from changing the type later.) - - - For foreign-data wrappers, this privilege allows creation of - new servers using the foreign-data wrapper. - - - For servers, this privilege allows creation of foreign tables using - the server. Grantees may also create, alter, or drop their own - user mappings associated with that server. + Alternative spelling for TEMPORARY. @@ -389,7 +183,7 @@ GRANT role_name [, ...] TO ALL PRIVILEGES - Grant all of the available privileges at once. + Grant all of the privileges available for the object's type. The PRIVILEGES key word is optional in PostgreSQL, though it is required by strict SQL. @@ -397,9 +191,26 @@ GRANT role_name [, ...] TO + - The privileges required by other commands are listed on the - reference page of the respective command. + + The FUNCTION syntax works for plain functions, + aggregate functions, and window functions, but not for procedures; + use PROCEDURE for those. + Alternatively, use ROUTINE to refer to a function, + aggregate function, window function, or procedure regardless of its + precise type. + + + + There is also an option to grant privileges on all objects of the same + type within one or more schemas. This functionality is currently supported + only for tables, sequences, functions, and procedures. ALL + TABLES also affects views and foreign tables, just like the + specific-object GRANT command. ALL + FUNCTIONS also affects aggregate and window functions, but not + procedures, again just like the specific-object GRANT + command. Use ALL ROUTINES to include procedures. @@ -520,79 +331,8 @@ GRANT role_name [, ...] TO - Use 's \dp command - to obtain information about existing privileges for tables and - columns. For example: - -=> \dp mytable - Access privileges - Schema | Name | Type | Access privileges | Column access privileges ---------+---------+-------+-----------------------+-------------------------- - public | mytable | table | miriam=arwdDxt/miriam | col1: - : =r/miriam : miriam_rw=rw/miriam - : admin=arw/miriam -(1 row) - - The entries shown by \dp are interpreted thus: - -rolename=xxxx -- privileges granted to a role - =xxxx -- privileges granted to PUBLIC - - r -- SELECT ("read") - w -- UPDATE ("write") - a -- INSERT ("append") - d -- DELETE - D -- TRUNCATE - x -- REFERENCES - t -- TRIGGER - X -- EXECUTE - U -- USAGE - C -- CREATE - c -- CONNECT - T -- TEMPORARY - arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects) - * -- grant option for preceding privilege - - /yyyy -- role that granted this privilege - - - The above example display would be seen by user miriam after - creating table mytable and doing: - - -GRANT SELECT ON mytable TO PUBLIC; -GRANT SELECT, UPDATE, INSERT ON mytable TO admin; -GRANT SELECT (col1), UPDATE (col1) ON mytable TO miriam_rw; - - - - - For non-table objects there are other \d commands - that can display their privileges. - - - - If the Access privileges column is empty for a given object, - it means the object has default privileges (that is, its privileges column - is null). Default privileges always include all privileges for the owner, - and can include some privileges for PUBLIC depending on the - object type, as explained above. The first GRANT or - REVOKE on an object - will instantiate the default privileges (producing, for example, - {miriam=arwdDxt/miriam}) and then modify them per the - specified request. Similarly, entries are shown in Column access - privileges only for columns with nondefault privileges. - (Note: for this purpose, default privileges always means the - built-in default privileges for the object's type. An object whose - privileges have been affected by an ALTER DEFAULT PRIVILEGES - command will always be shown with an explicit privilege entry that - includes the effects of the ALTER.) - - - - Notice that the owner's implicit grant options are not marked in the - access privileges display. A * will appear only when - grant options have been explicitly granted to someone. + See for more information about specific + privilege types, as well as how to inspect objects' privileges. diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml index feefd9a41e0..da5c8f53075 100644 --- a/doc/src/sgml/ref/initdb.sgml +++ b/doc/src/sgml/ref/initdb.sgml @@ -202,7 +202,9 @@ PostgreSQL documentation Allows users in the same group as the cluster owner to read all cluster - files created by initdb. + files created by initdb. This option is ignored + on Windows as it does not support + POSIX-style group permissions. @@ -214,9 +216,10 @@ PostgreSQL documentation Use checksums on data pages to help detect corruption by the I/O system that would otherwise be silent. Enabling checksums - may incur a noticeable performance penalty. This option can only - be set during initialization, and cannot be changed later. If - set, checksums are calculated for all objects, in all databases. + may incur a noticeable performance penalty. If set, checksums + are calculated for all objects, in all databases. All checksum + failures will be reported in the + view. @@ -334,27 +337,6 @@ PostgreSQL documentation - - - - - Set the WAL segment size, in megabytes. This - is the size of each individual file in the WAL log. The default size - is 16 megabytes. The value must be a power of 2 between 1 and 1024 - (megabytes). This option can only be set during initialization, and - cannot be changed later. - - - - It may be useful to adjust this size to control the granularity of - WAL log shipping or archiving. Also, in databases with a high volume - of WAL, the sheer number of WAL files per directory can become a - performance and management problem. Increasing the WAL file size - will reduce the number of WAL files. - - - - @@ -366,6 +348,26 @@ PostgreSQL documentation + + + + + Set the WAL segment size, in megabytes. This + is the size of each individual file in the WAL log. The default size + is 16 megabytes. The value must be a power of 2 between 1 and 1024 + (megabytes). This option can only be set during initialization, and + cannot be changed later. + + + + It may be useful to adjust this size to control the granularity of + WAL log shipping or archiving. Also, in databases with a high volume + of WAL, the sheer number of WAL files per directory can become a + performance and management problem. Increasing the WAL file size + will reduce the number of WAL files. + + + @@ -460,6 +462,17 @@ PostgreSQL documentation + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + + TZ diff --git a/doc/src/sgml/ref/insert.sgml b/doc/src/sgml/ref/insert.sgml index da294aaa46a..f995a7637f1 100644 --- a/doc/src/sgml/ref/insert.sgml +++ b/doc/src/sgml/ref/insert.sgml @@ -551,14 +551,12 @@ INSERT INTO table_name [ AS INSERT oid count - The count is the - number of rows inserted or updated. If count is exactly one, and the - target table has OIDs, then oid is the OID - assigned to the inserted row. The single row must have been - inserted rather than updated. Otherwise oid is zero. + The count is the number of + rows inserted or updated. oid is always 0 (it + used to be the OID assigned to the inserted row if + count was exactly one and the target table was + declared WITH OIDS and 0 otherwise, but creating a table + WITH OIDS is not supported anymore). @@ -579,13 +577,6 @@ INSERT oid count - - - You may also wish to consider using MERGE, since that - allows mixed INSERT, UPDATE and - DELETE within a single statement. - See . - @@ -756,9 +747,7 @@ INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International') Also, the case in which a column name list is omitted, but not all the columns are filled from the VALUES clause or query, - is disallowed by the standard. If you prefer a more SQL Standard - conforming statement than ON CONFLICT, see - . + is disallowed by the standard. diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index 96d477c2038..a225cea63b2 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -46,8 +46,8 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] - When a view is specified to be locked, all relations appearing in the view - definition query are also locked recursively with the same lock mode. + When a view is locked, all relations appearing in the view definition + query are also locked recursively with the same lock mode. @@ -173,6 +173,13 @@ LOCK [ TABLE ] [ ONLY ] name [ * ] or TRUNCATE privileges. + + The user performing the lock on the view must have the corresponding privilege + on the view. In addition the view's owner must have the relevant privileges on + the underlying base relations, but the user performing the lock does + not need any permissions on the underlying base relations. + + LOCK TABLE is useless outside a transaction block: the lock would remain held only to the completion of the statement. Therefore diff --git a/doc/src/sgml/ref/merge.sgml b/doc/src/sgml/ref/merge.sgml deleted file mode 100644 index b2a9f67cfa9..00000000000 --- a/doc/src/sgml/ref/merge.sgml +++ /dev/null @@ -1,617 +0,0 @@ - - - - - - MERGE - 7 - SQL - Language Statements - - - - MERGE - insert, update, or delete rows of a table based upon source data - - - - -[ WITH with_query [, ...] ] -MERGE INTO target_table_name [ [ AS ] target_alias ] -USING data_source -ON join_condition -when_clause [...] - -where data_source is - -{ source_table_name | - ( source_query ) -} -[ [ AS ] source_alias ] - -and when_clause is - -{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete } | - WHEN NOT MATCHED [ AND condition ] THEN { merge_insert | DO NOTHING } -} - -and merge_insert is - -INSERT [( column_name [, ...] )] -[ OVERRIDING { SYSTEM | USER } VALUE ] -{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES } - -and merge_update is - -UPDATE SET { column_name = { expression | DEFAULT } | - ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) - } [, ...] - -and merge_delete is - -DELETE - - - - - Description - - - MERGE performs actions that modify rows in the - target_table_name, - using the data_source. - MERGE provides a single SQL - statement that can conditionally INSERT, - UPDATE or DELETE rows, a task - that would otherwise require multiple procedural language statements. - - - - First, the MERGE command performs a join - from data_source to - target_table_name - producing zero or more candidate change rows. For each candidate change - row the status of MATCHED or NOT MATCHED is set - just once, after which WHEN clauses are evaluated - in the order specified. If one of them is activated, the specified - action occurs. No more than one WHEN clause can be - activated for any candidate change row. - - - - MERGE actions have the same effect as - regular UPDATE, INSERT, or - DELETE commands of the same names. The syntax of - those commands is different, notably that there is no WHERE - clause and no tablename is specified. All actions refer to the - target_table_name, - though modifications to other tables may be made using triggers. - - - - When DO NOTHING action is specified, the source row is - skipped. Since actions are evaluated in the given order, DO - NOTHING can be handy to skip non-interesting source rows before - more fine-grained handling. - - - - There is no MERGE privilege. - You must have the UPDATE privilege on the column(s) - of the target_table_name - referred to in the SET clause - if you specify an update action, the INSERT privilege - on the target_table_name - if you specify an insert action and/or the DELETE - privilege on the target_table_name - if you specify a delete action on the - target_table_name. - Privileges are tested once at statement start and are checked - whether or not particular WHEN clauses are activated - during the subsequent execution. - You will require the SELECT privilege on the - data_source and any column(s) - of the target_table_name - referred to in a condition. - - - - MERGE is not supported if the target_table_name has - RULES defined on it. - See for more information about RULES. - - - - - Parameters - - - - target_table_name - - - The name (optionally schema-qualified) of the target table to merge into. - - - - - - target_alias - - - A substitute name for the target table. When an alias is - provided, it completely hides the actual name of the table. For - example, given MERGE foo AS f, the remainder of the - MERGE statement must refer to this table as - f not foo. - - - - - - source_table_name - - - The name (optionally schema-qualified) of the source table, view or - transition table. - - - - - - source_query - - - A query (SELECT statement or VALUES - statement) that supplies the rows to be merged into the - target_table_name. - Refer to the - statement or - statement for a description of the syntax. - - - - - - source_alias - - - A substitute name for the data source. When an alias is - provided, it completely hides whether table or query was specified. - - - - - - join_condition - - - join_condition is - an expression resulting in a value of type - boolean (similar to a WHERE - clause) that specifies which rows in the - data_source - match rows in the - target_table_name. - - - - Only columns from target_table_name - that attempt to match data_source - rows should appear in join_condition. - join_condition subexpressions that - only reference target_table_name - columns can only affect which action is taken, often in surprising ways. - - - - - - - when_clause - - - At least one WHEN clause is required. - - - If the WHEN clause specifies WHEN MATCHED - and the candidate change row matches a row in the - target_table_name - the WHEN clause is activated if the - condition is - absent or is present and evaluates to true. - If the WHEN clause specifies WHEN NOT MATCHED - and the candidate change row does not match a row in the - target_table_name - the WHEN clause is activated if the - condition is - absent or is present and evaluates to true. - - - - - - condition - - - An expression that returns a value of type boolean. - If this expression returns true then the WHEN - clause will be activated and the corresponding action will occur for - that row. The expression may not contain functions that possibly performs - writes to the database. - - - A condition on a WHEN MATCHED clause can refer to columns - in both the source and the target relation. A condition on a - WHEN NOT MATCHED clause can only refer to columns from - the source relation, since by definition there is no matching target row. - Only the system attributes from the target table are accessible. - - - - - - merge_insert - - - The specification of an INSERT action that inserts - one row into the target table. - The target column names can be listed in any order. If no list of - column names is given at all, the default is all the columns of the - table in their declared order. - - - Each column not present in the explicit or implicit column list will be - filled with a default value, either its declared default value - or null if there is none. - - - If the expression for any column is not of the correct data type, - automatic type conversion will be attempted. - - - If target_table_name - is a partitioned table, each row is routed to the appropriate partition - and inserted into it. - If target_table_name - is a partition, an error will occur if one of the input rows violates - the partition constraint. - - - Column names may not be specified more than once. - INSERT actions cannot contain sub-selects. - - - Only one VALUES clause can be specified. - The VALUES clause can only refer to columns from - the source relation, since by definition there is no matching target row. - - - - - - merge_update - - - The specification of an UPDATE action that updates - the current row of the target_table_name. - Column names may not be specified more than once. - - - Do not include the table name, as you would normally do with an - command. - For example, UPDATE tab SET col = 1 is invalid. Also, - do not include a WHERE clause, since only the current - row can be updated. For example, - UPDATE SET col = 1 WHERE key = 57 is invalid. - - - - - - merge_delete - - - Specifies a DELETE action that deletes the current row - of the target_table_name. - Do not include the tablename or any other clauses, as you would normally - do with an command. - - - - - - column_name - - - The name of a column in the target_table_name. The column name - can be qualified with a subfield name or array subscript, if - needed. (Inserting into only some fields of a composite - column leaves the other fields null.) When referencing a - column, do not include the table's name in the specification - of a target column. - - - - - - OVERRIDING SYSTEM VALUE - - - Without this clause, it is an error to specify an explicit value - (other than DEFAULT) for an identity column defined - as GENERATED ALWAYS. This clause overrides that - restriction. - - - - - - OVERRIDING USER VALUE - - - If this clause is specified, then any values supplied for identity - columns defined as GENERATED BY DEFAULT are ignored - and the default sequence-generated values are applied. - - - - - - DEFAULT VALUES - - - All columns will be filled with their default values. - (An OVERRIDING clause is not permitted in this - form.) - - - - - - expression - - - An expression to assign to the column. The expression can use the - old values of this and other columns in the table. - - - - - - DEFAULT - - - Set the column to its default value (which will be NULL if no - specific default expression has been assigned to it). - - - - - - with_query - - - The WITH clause allows you to specify one or more - subqueries that can be referenced by name in the MERGE - query. See and - for details. - - - - - - - - - Outputs - - - On successful completion, a MERGE command returns a command - tag of the form - -MERGE total-count - - The total-count is the total - number of rows changed (whether inserted, updated, or deleted). - If total-count is 0, no rows - were changed in any way. - - - - - - Execution - - - The following steps take place during the execution of - MERGE. - - - - Perform any BEFORE STATEMENT triggers for all actions specified, whether or - not their WHEN clauses are activated during execution. - - - - - Perform a join from source to target table. - The resulting query will be optimized normally and will produce - a set of candidate change row. For each candidate change row - - - - Evaluate whether each row is MATCHED or NOT MATCHED. - - - - - Test each WHEN condition in the order specified until one activates. - - - - - When activated, perform the following actions - - - - Perform any BEFORE ROW triggers that fire for the action's event type. - - - - - Apply the action specified, invoking any check constraints on the - target table. - However, it will not invoke rules. - - - - - Perform any AFTER ROW triggers that fire for the action's event type. - - - - - - - - - - - Perform any AFTER STATEMENT triggers for actions specified, whether or - not they actually occur. This is similar to the behavior of an - UPDATE statement that modifies no rows. - - - - In summary, statement triggers for an event type (say, INSERT) will - be fired whenever we specify an action of that kind. Row-level - triggers will fire only for the one event type activated. - So a MERGE might fire statement triggers for both - UPDATE and INSERT, even though only - UPDATE row triggers were fired. - - - - You should ensure that the join produces at most one candidate change row - for each target row. In other words, a target row shouldn't join to more - than one data source row. If it does, then only one of the candidate change - rows will be used to modify the target row, later attempts to modify will - cause an error. This can also occur if row triggers make changes to the - target table which are then subsequently modified by MERGE. - If the repeated action is an INSERT this will - cause a uniqueness violation while a repeated UPDATE or - DELETE will cause a cardinality violation; the latter behavior - is required by the SQL Standard. This differs from - historical PostgreSQL behavior of joins in - UPDATE and DELETE statements where second and - subsequent attempts to modify are simply ignored. - - - - If a WHEN clause omits an AND clause it becomes - the final reachable clause of that kind (MATCHED or - NOT MATCHED). If a later WHEN clause of that kind - is specified it would be provably unreachable and an error is raised. - If a final reachable clause is omitted it is possible that no action - will be taken for a candidate change row. - - - - - Notes - - - The order in which rows are generated from the data source is indeterminate - by default. A source_query - can be used to specify a consistent ordering, if required, which might be - needed to avoid deadlocks between concurrent transactions. - - - - There is no RETURNING clause with MERGE. - Actions of INSERT, UPDATE and DELETE - cannot contain RETURNING or WITH clauses. - - - - - You may also wish to consider using INSERT ... ON CONFLICT as an - alternative statement which offers the ability to run an UPDATE - if a concurrent INSERT occurs. There are a variety of - differences and restrictions between the two statement types and they are not - interchangeable. - - - - - - Examples - - - Perform maintenance on CustomerAccounts based upon new Transactions. - - -MERGE CustomerAccount CA -USING RecentTransactions T -ON T.CustomerId = CA.CustomerId -WHEN MATCHED THEN - UPDATE SET Balance = Balance + TransactionValue -WHEN NOT MATCHED THEN - INSERT (CustomerId, Balance) - VALUES (T.CustomerId, T.TransactionValue); - - - notice that this would be exactly equivalent to the following - statement because the MATCHED result does not change - during execution - - -MERGE CustomerAccount CA -USING (Select CustomerId, TransactionValue From RecentTransactions) AS T -ON CA.CustomerId = T.CustomerId -WHEN NOT MATCHED THEN - INSERT (CustomerId, Balance) - VALUES (T.CustomerId, T.TransactionValue) -WHEN MATCHED THEN - UPDATE SET Balance = Balance + TransactionValue; - - - - - Attempt to insert a new stock item along with the quantity of stock. If - the item already exists, instead update the stock count of the existing - item. Don't allow entries that have zero stock. - -MERGE INTO wines w -USING wine_stock_changes s -ON s.winename = w.winename -WHEN NOT MATCHED AND s.stock_delta > 0 THEN - INSERT VALUES(s.winename, s.stock_delta) -WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN - UPDATE SET stock = w.stock + s.stock_delta; -WHEN MATCHED THEN - DELETE; - - - The wine_stock_changes table might be, for example, a temporary table - recently loaded into the database. - - - - - - Compatibility - - This command conforms to the SQL standard. - - - The WITH clause and DO NOTHING action are extensions to the SQL standard. - - - diff --git a/doc/src/sgml/ref/notify.sgml b/doc/src/sgml/ref/notify.sgml index e0e125a2a2d..d7dcbea02d4 100644 --- a/doc/src/sgml/ref/notify.sgml +++ b/doc/src/sgml/ref/notify.sgml @@ -94,9 +94,9 @@ NOTIFY channel [ , - If the same channel name is signaled multiple times from the same - transaction with identical payload strings, the - database server can decide to deliver a single notification only. + If the same channel name is signaled multiple times with identical + payload strings within the same transaction, only one instance of the + notification event is delivered to listeners. On the other hand, notifications with distinct payload strings will always be delivered as distinct notifications. Similarly, notifications from different transactions will never get folded into one notification. diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml index fc1edf48645..fc9e222f8d0 100644 --- a/doc/src/sgml/ref/pg_basebackup.sgml +++ b/doc/src/sgml/ref/pg_basebackup.sgml @@ -214,10 +214,11 @@ PostgreSQL documentation - Write a minimal recovery.conf in the output + Create standby.signal and append connection settings + to postgresql.auto.conf in the output directory (or into the base archive file when using tar format) to ease setting up a standby server. - The recovery.conf file will record the connection + The postgresql.auto.conf file will record the connection settings and, if specified, the replication slot that pg_basebackup is using, so that the streaming replication will use the same settings later on. @@ -305,8 +306,8 @@ PostgreSQL documentation backup will fail and be unusable. - The write-ahead log files will be written to - the base.tar file. + When tar format mode is used, the write-ahead log files will be + written to the base.tar file. @@ -325,9 +326,10 @@ PostgreSQL documentation requires no extra write-ahead logs to be saved on the master. - The write-ahead log files are written to a separate file - named pg_wal.tar (if the server is a version - earlier than 10, the file will be named pg_xlog.tar). + When tar format mode is used, the write-ahead log files will be + written to a separate file named pg_wal.tar + (if the server is a version earlier than 10, the file will be named + pg_xlog.tar). This value is the default. @@ -387,9 +389,9 @@ PostgreSQL documentation - This option causes the replication slot specified by the - option --slot to be created before starting the - backup. In this case, an error is raised if the slot already exists. + This option causes creation of a replication slot named by the + --slot option before starting the backup. + An error is raised if the slot already exists. @@ -470,7 +472,7 @@ PostgreSQL documentation replication slot. If the base backup is intended to be used as a streaming replication standby using replication slots, it should then use the same replication slot name - in recovery.conf. That way, it is ensured that + in . That way, it is ensured that the server does not remove any necessary WAL data in the time between the end of the base backup and the start of streaming replication. @@ -486,6 +488,18 @@ PostgreSQL documentation + + + + + + Enables verbose mode. Will output some extra steps during startup and + shutdown, as well as show the exact file name that is currently being + processed if progress reporting is also enabled. + + + + @@ -507,33 +521,21 @@ PostgreSQL documentation - Disables verification of checksums, if they are enabled on the server - the base backup is taken from. + the base backup is taken from. - By default, checksums are verified and checksum failures will result in - a non-zero exit status. However, the base backup will not be removed in - this case, as if the --no-clean option was used. + By default, checksums are verified and checksum failures will result + in a non-zero exit status. However, the base backup will not be + removed in such a case, as if the option + had been used. Checksum verifications failures will also be reported + in the view. - - - - - - - Enables verbose mode. Will output some extra steps during startup and - shutdown, as well as show the exact file name that is currently being - processed if progress reporting is also enabled. - - - - @@ -686,6 +688,12 @@ PostgreSQL documentation (see ). + + The environment variable PG_COLOR specifies whether to use + color in diagnostics messages. Possible values are + always, auto, + never. + diff --git a/doc/src/sgml/ref/pg_checksums.sgml b/doc/src/sgml/ref/pg_checksums.sgml new file mode 100644 index 00000000000..162bafdb331 --- /dev/null +++ b/doc/src/sgml/ref/pg_checksums.sgml @@ -0,0 +1,228 @@ + + + + + pg_checksums + + + + pg_checksums + 1 + Application + + + + pg_checksums + enable, disable or check data checksums in a PostgreSQL database cluster + + + + + pg_checksums + option + + + + + + datadir + + + + + + Description + + pg_checksums checks, enables or disables data + checksums in a PostgreSQL cluster. The server + must be shut down cleanly before running + pg_checksums. When verifying checksums, the exit + status is zero if there are no checksum errors, and nonzero if at least one + checksum failure is detected. When enabling or disabling checksums, the + exit status is nonzero if the operation failed. + + + + When verifying checksums, every file in the cluster is scanned. When + enabling checksums, every file in the cluster is rewritten. Disabling + checksums only updates the file pg_control. + + + + + Options + + + The following command-line options are available: + + + + + + + + Specifies the directory where the database cluster is stored. + + + + + + + + + + Checks checksums. This is the default mode if nothing else is + specified. + + + + + + + + + + Disables checksums. + + + + + + + + + + Enables checksums. + + + + + + + + + + Only validate checksums in the relation with filenode + filenode. + + + + + + + + + + By default, pg_checksums will wait for all files + to be written safely to disk. This option causes + pg_checksums to return without waiting, which is + faster, but means that a subsequent operating system crash can leave + the updated data directory corrupt. Generally, this option is useful + for testing but should not be used on a production installation. + This option has no effect when using --check. + + + + + + + + + + Enable progress reporting. Turning this on will deliver a progress + report while checking or enabling checksums. + + + + + + + + + + Enable verbose output. Lists all checked files. + + + + + + + + + + Print the pg_checksums version and exit. + + + + + + + + + + Show help about pg_checksums command line + arguments, and exit. + + + + + + + + + Environment + + + + PGDATA + + + + Specifies the directory where the database cluster is + stored; can be overridden using the option. + + + + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + + + + + + Notes + + Enabling checksums in a large cluster can potentially take a long time. + During this operation, the cluster or other programs that write to the + data directory must not be started or else data loss may occur. + + + When using a replication setup with tools which perform direct copies + of relation file blocks (for example ), + enabling or disabling checksums can lead to page corruptions in the + shape of incorrect checksums if the operation is not done consistently + across all nodes. When enabling or disabling checksums in a replication + setup, it is thus recommended to stop all the clusters before switching + them all consistently. Destroying all standbys, performing the operation + on the primary and finally recreating the standbys from scratch is also + safe. + + + If pg_checksums is aborted or killed while + enabling or disabling checksums, the cluster's data checksum configuration + remains unchanged, and pg_checksums can be + re-run to perform the same operation. + + + diff --git a/doc/src/sgml/ref/pg_controldata.sgml b/doc/src/sgml/ref/pg_controldata.sgml index 32081e9b91c..abac59aa500 100644 --- a/doc/src/sgml/ref/pg_controldata.sgml +++ b/doc/src/sgml/ref/pg_controldata.sgml @@ -68,6 +68,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml index 0816bc1686c..e31275a04e2 100644 --- a/doc/src/sgml/ref/pg_ctl-ref.sgml +++ b/doc/src/sgml/ref/pg_ctl-ref.sgml @@ -97,6 +97,13 @@ PostgreSQL documentation + + pg_ctl + + datadir + + + pg_ctl @@ -226,6 +233,12 @@ PostgreSQL documentation and begin read-write operations. + + mode rotates the server log file. + For details on how to use this mode with external log rotation tools, see + . + + mode sends a signal to a specified process. This is primarily valuable on Microsoft Windows @@ -334,7 +347,7 @@ PostgreSQL documentation options being passed through. - The options should usually be surrounded by single or + The initdb-options should usually be surrounded by single or double quotes to ensure that they are passed through as a group. @@ -681,8 +694,7 @@ PostgreSQL documentation pg_ctl: server is running (PID: 13718) /usr/local/pgsql/bin/postgres "-D" "/usr/local/pgsql/data" "-p" "5433" "-B" "128" - - + The second line is the command that would be invoked in restart mode. diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 50809b48443..4bcd4bdaefe 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -82,7 +82,7 @@ PostgreSQL documentation can be used to examine the archive and/or select which parts of the database are to be restored. The most flexible output file formats are the custom format () and the - directory format(). They allow + directory format (). They allow for selection and reordering of all archived items, support parallel restoration, and are compressed by default. The directory format is the only format that supports parallel dumps. @@ -375,17 +375,17 @@ PostgreSQL documentation - - + + Dump only schemas matching schema; this selects both the + class="parameter">pattern; this selects both the schema itself, and all its contained objects. When this option is not specified, all non-system schemas in the target database will be dumped. Multiple schemas can be - selected by writing multiple switches. Also, the - schema parameter is + selected by writing multiple switches. The + pattern parameter is interpreted as a pattern according to the same rules used by psql's \d commands (see ), @@ -417,12 +417,12 @@ PostgreSQL documentation - - + + - Do not dump any schemas matching the schema pattern. The pattern is + Do not dump any schemas matching pattern. The pattern is interpreted according to the same rules as for . can be given more than once to exclude schemas matching any of several patterns. @@ -438,20 +438,6 @@ PostgreSQL documentation - - - - - - Dump object identifiers (OIDs) as part of the - data for every table. Use this option if your application references - the OID - columns in some way (e.g., in a foreign key constraint). - Otherwise, this option should not be used. - - - - @@ -527,16 +513,16 @@ PostgreSQL documentation - - + + Dump only tables with names matching - table. + pattern. For this purpose, table includes views, materialized views, sequences, and foreign tables. Multiple tables - can be selected by writing multiple switches. Also, the - table parameter is + can be selected by writing multiple switches. The + pattern parameter is interpreted as a pattern according to the same rules used by psql's \d commands (see ), @@ -579,12 +565,12 @@ PostgreSQL documentation - - + + - Do not dump any tables matching the table pattern. The pattern is + Do not dump any tables matching pattern. The pattern is interpreted according to the same rules as for . can be given more than once to exclude tables matching any of several patterns. @@ -675,9 +661,9 @@ PostgreSQL documentation ...). This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non-PostgreSQL databases. - However, since this option generates a separate command for each row, - an error in reloading a row causes only that row to be lost rather - than the entire table contents. + Any error during reloading will cause only rows that are part of the + problematic INSERT to be lost, rather than the + entire table contents. @@ -742,11 +728,11 @@ PostgreSQL documentation - + - Do not dump data for any tables matching the table pattern. The pattern is + Do not dump data for any tables matching pattern. The pattern is interpreted according to the same rules as for . can be given more than once to exclude tables matching any of several patterns. This option is @@ -759,6 +745,17 @@ PostgreSQL documentation + + + + + Use the specified value of when dumping + floating-point data, instead of the maximum available precision. + Routine dumps made for backup purposes should not use this option. + + + + @@ -778,13 +775,40 @@ PostgreSQL documentation than COPY). This will make restoration very slow; it is mainly useful for making dumps that can be loaded into non-PostgreSQL databases. - However, since this option generates a separate command for each row, - an error in reloading a row causes only that row to be lost rather - than the entire table contents. - Note that - the restore might fail altogether if you have rearranged column order. - The option is safe against column - order changes, though even slower. + Any error during reloading will cause only rows that are part of the + problematic INSERT to be lost, rather than the + entire table contents. Note that the restore might fail altogether if + you have rearranged column order. The + option is safe against column order + changes, though even slower. + + + + + + + + + When dumping data for a table partition, make + the COPY or INSERT statements + target the root of the partitioning hierarchy that contains it, rather + than the partition itself. This causes the appropriate partition to + be re-determined for each row when the data is loaded. This may be + useful when reloading data on a server where rows do not always fall + into the same partitions as they did on the original server. That + could happen, for example, if the partitioning column is of type text + and the two systems have different definitions of the collation used + to sort the partitioning column. + + + + It is best not to use parallelism when restoring from an archive made + with this option, because pg_restore will + not know exactly which partition(s) a given archive data item will + load data into. This could result in inefficiency due to lock + conflicts between parallel jobs, or perhaps even reload failures due + to foreign key constraints being set up before all the relevant data + is loaded. @@ -894,6 +918,19 @@ PostgreSQL documentation + + + + + Add ON CONFLICT DO NOTHING to + INSERT commands. + This option is not valid unless , + or + is also specified. + + + + @@ -913,16 +950,15 @@ PostgreSQL documentation - + - When dumping a COPY or INSERT statement for a partitioned table, - target the root of the partitioning hierarchy which contains it rather - than the partition itself. This may be useful when reloading data on - a server where rows do not always fall into the same partitions as - they did on the original server. This could happen, for example, if - the partitioning column is of type text and the two system have - different definitions of the collation used to partition the data. + Dump data as INSERT commands (rather than + COPY). Controls the maximum number of rows per + INSERT command. The value specified must be a + number greater than zero. Any error during reloading will cause only + rows that are part of the problematic INSERT to be + lost, rather than the entire table contents. @@ -1188,6 +1224,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + @@ -1279,7 +1326,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; When dumping logical replication subscriptions, pg_dump will generate CREATE - SUBSCRIPTION commands that use the NOCONNECT + SUBSCRIPTION commands that use the connect = false option, so that restoring the subscription does not make remote connections for creating a replication slot or for initial table copy. That way, the dump can be restored without requiring network access to the remote diff --git a/doc/src/sgml/ref/pg_dumpall.sgml b/doc/src/sgml/ref/pg_dumpall.sgml index 5d6fe9b87d5..7268be9f3ef 100644 --- a/doc/src/sgml/ref/pg_dumpall.sgml +++ b/doc/src/sgml/ref/pg_dumpall.sgml @@ -52,7 +52,8 @@ PostgreSQL documentation The SQL script will be written to the standard output. Use the - [-f|file] option or shell operators to redirect it into a file. + / option or shell operators to + redirect it into a file. @@ -130,20 +131,6 @@ PostgreSQL documentation - - - - - - Dump object identifiers (OIDs) as part of the - data for every table. Use this option if your application references - the OID - columns in some way (e.g., in a foreign key constraint). - Otherwise, this option should not be used. - - - - @@ -300,6 +287,38 @@ PostgreSQL documentation + + + + + Use the specified value of extra_float_digits when dumping + floating-point data, instead of the maximum available precision. + Routine dumps made for backup purposes should not use this option. + + + + + + + + + + Do not dump databases whose name matches + pattern. + Multiple patterns can be excluded by writing multiple + switches. The + pattern parameter is + interpreted as a pattern according to the same rules used by + psql's \d + commands (see ), + so multiple databases can also be excluded by writing wildcard + characters in the pattern. When using wildcards, be careful to + quote the pattern if needed to prevent shell wildcard expansion. + + + + @@ -326,6 +345,28 @@ PostgreSQL documentation + + + + + When dumping data for a table partition, make + the COPY or INSERT statements + target the root of the partitioning hierarchy that contains it, rather + than the partition itself. This causes the appropriate partition to + be re-determined for each row when the data is loaded. This may be + useful when reloading data on a server where rows do not always fall + into the same partitions as they did on the original server. That + could happen, for example, if the partitioning column is of type text + and the two systems have different definitions of the collation used + to sort the partitioning column. + + + + + + @@ -431,6 +472,18 @@ PostgreSQL documentation + + + + + Add ON CONFLICT DO NOTHING to + INSERT commands. + This option is not valid unless or + is also specified. + + + + @@ -450,16 +503,15 @@ PostgreSQL documentation - + - When dumping a COPY or INSERT statement for a partitioned table, - target the root of the partitioning hierarchy which contains it rather - than the partition itself. This may be useful when reloading data on - a server where rows do not always fall into the same partitions as - they did on the original server. This could happen, for example, if - the partitioning column is of type text and the two system have - different definitions of the collation used to partition the data. + Dump data as INSERT commands (rather than + COPY). Controls the maximum number of rows per + INSERT command. The value specified must be a + number greater than zero. Any error during reloading will cause only + rows that are part of the problematic INSERT to be + lost, rather than the entire table contents. @@ -644,6 +696,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/pg_isready.sgml b/doc/src/sgml/ref/pg_isready.sgml index 9567b57ebe2..68447b5093d 100644 --- a/doc/src/sgml/ref/pg_isready.sgml +++ b/doc/src/sgml/ref/pg_isready.sgml @@ -164,6 +164,13 @@ PostgreSQL documentation also uses the environment variables supported by libpq (see ). + + + The environment variable PG_COLOR specifies whether to use + color in diagnostics messages. Possible values are + always, auto, + never. + diff --git a/doc/src/sgml/ref/pg_receivewal.sgml b/doc/src/sgml/ref/pg_receivewal.sgml index a18ddd4bff1..177e9211c08 100644 --- a/doc/src/sgml/ref/pg_receivewal.sgml +++ b/doc/src/sgml/ref/pg_receivewal.sgml @@ -52,7 +52,17 @@ PostgreSQL documentation Unlike the WAL receiver of a PostgreSQL standby server, pg_receivewal by default flushes WAL data only when a WAL file is closed. The option must be specified to flush WAL data - in real time. + in real time. Since pg_receivewal does not + apply WAL, you should not allow it to become a synchronous standby when + equals + remote_apply. If it does, it will appear to be a + standby that never catches up, and will cause transaction commits to + block. To avoid this, you should either configure an appropriate value + for , or specify + application_name for + pg_receivewal that does not match it, or + change the value of synchronous_commit to + something other than remote_apply. @@ -408,6 +418,12 @@ PostgreSQL documentation (see ). + + The environment variable PG_COLOR specifies whether to use + color in diagnostics messages. Possible values are + always, auto, + never. + diff --git a/doc/src/sgml/ref/pg_recvlogical.sgml b/doc/src/sgml/ref/pg_recvlogical.sgml index 141c5cddce1..4c79f90414d 100644 --- a/doc/src/sgml/ref/pg_recvlogical.sgml +++ b/doc/src/sgml/ref/pg_recvlogical.sgml @@ -397,6 +397,13 @@ PostgreSQL documentation uses the environment variables supported by libpq (see ). + + + The environment variable PG_COLOR specifies whether to use + color in diagnostics messages. Possible values are + always, auto, + never. + diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 3f885bdd620..8a9e22d050f 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -320,6 +320,23 @@ PostgreSQL documentation + + Environment + + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + + + + Notes diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index 345324bd27d..c6013546a0e 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -176,8 +176,8 @@ Specify output file for generated script, or for the listing - when used with . Default is the standard - output. + when used with . Use - + for stdout. @@ -579,7 +579,8 @@ - Do not dump comments. + Do not output commands to restore comments, even if the archive + contains them. @@ -821,6 +822,17 @@ + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index 520d843f0ec..fbf454803b5 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -69,7 +69,8 @@ PostgreSQL documentation target cluster ran for a long time after the divergence, the old WAL files might no longer be present. In that case, they can be manually copied from the WAL archive to the pg_wal directory, or - fetched on startup by configuring recovery.conf. The use of + fetched on startup by configuring or + . The use of pg_rewind is not limited to failover, e.g. a standby server can be promoted, run some write transactions, and then rewinded to become a standby again. @@ -83,8 +84,9 @@ PostgreSQL documentation pg_rewind was run, and therefore could not be copied by the pg_rewind session, it must be made available when the target server is started. This can be done by creating a - recovery.conf file in the target data directory with a - suitable restore_command. + recovery.signal file in the target data directory + and configuring suitable + in postgresql.conf. @@ -95,6 +97,26 @@ PostgreSQL documentation are currently on by default. must also be set to on, but is enabled by default. + + + + If pg_rewind fails while processing, then + the data folder of the target is likely not in a state that can be + recovered. In such a case, taking a new fresh backup is recommended. + + + + pg_rewind will fail immediately if it finds + files it cannot write directly to. This can happen for example when + the source and the target server use the same file mapping for read-only + SSL keys and certificates. If such files are present on the target server + it is recommended to remove them before running + pg_rewind. After doing the rewind, some of + those files may have been copied from the source, in which case it may + be necessary to remove the data copied and restore back the set of links + used before the rewind. + + @@ -133,10 +155,40 @@ PostgreSQL documentation Specifies a libpq connection string to connect to the source - PostgreSQL server to synchronize the target with. - The connection must be a normal (non-replication) connection - with superuser access. This option requires the source - server to be running and not in recovery mode. + PostgreSQL server to synchronize the target + with. The connection must be a normal (non-replication) connection + with a role having sufficient permissions to execute the functions + used by pg_rewind on the source server + (see Notes section for details) or a superuser role. This option + requires the source server to be running and not in recovery mode. + + + + + + + + + pg_rewind verifies that the target server + is cleanly shutdown before rewinding; by default, if it isn't, it + starts the server in single-user mode to complete crash recovery. + By passing this option, pg_rewind skips + this and errors out immediately if the server is not cleanly shut + down. Users are expected to handle the situation themselves in that + case. + + + + + + + + + + Create standby.signal and append connection + settings to postgresql.auto.conf in the output + directory. --source-server is mandatory with + this option. @@ -151,6 +203,22 @@ PostgreSQL documentation + + + + + + By default, pg_rewind will wait for all files + to be written safely to disk. This option causes + pg_rewind to return without waiting, which is + faster, but means that a subsequent operating system crash can leave + the synchronized data directory corrupt. Generally, this option is + useful for testing but should not be used when creating a production + installation. + + + + @@ -196,13 +264,44 @@ PostgreSQL documentation pg_rewind also uses the environment variables supported by libpq (see ). + + + The environment variable PG_COLOR specifies whether to use + color in diagnostics messages. Possible values are + always, auto, + never. + Notes + + When executing pg_rewind using an online + cluster as source, a role having sufficient permissions to execute the + functions used by pg_rewind on the source + cluster can be used instead of a superuser. Here is how to create such + a role, named rewind_user here: + +CREATE USER rewind_user LOGIN; +GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user; +GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user; +GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user; +GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user; + + + + + When executing pg_rewind using an online + cluster as source which has been recently promoted, it is necessary + to execute a CHECKPOINT after promotion so as its + control file reflects up-to-date timeline information, which is used by + pg_rewind to check if the target cluster + can be rewound using the designated source cluster. + + - How it works + How It Works The basic idea is to copy all file system-level changes from the source diff --git a/doc/src/sgml/ref/pg_verify_checksums.sgml b/doc/src/sgml/ref/pg_verify_checksums.sgml deleted file mode 100644 index 463ecd5e1b3..00000000000 --- a/doc/src/sgml/ref/pg_verify_checksums.sgml +++ /dev/null @@ -1,112 +0,0 @@ - - - - - pg_verify_checksums - - - - pg_verify_checksums - 1 - Application - - - - pg_verify_checksums - verify data checksums in an offline PostgreSQL database cluster - - - - - pg_verify_checksums - option - datadir - - - - - Description - - pg_verify_checksums verifies data checksums in a PostgreSQL - cluster. It must be run against a cluster that's offline. - - - - - Options - - - The following command-line options are available: - - - - - - - - Only validate checksums in the relation with specified relfilenode. - - - - - - - - - Force check even if checksums are disabled on cluster. - - - - - - - - - Enable debug output. Lists all checked blocks and their checksum. - - - - - - - - - - Print the pg_verify_checksums version and exit. - - - - - - - - - - Show help about pg_verify_checksums command line - arguments, and exit. - - - - - - - - - Notes - - Can only be run when the server is offline. - - - - - See Also - - - - - - - diff --git a/doc/src/sgml/ref/pg_waldump.sgml b/doc/src/sgml/ref/pg_waldump.sgml index 35f974f8c1b..329c10e4303 100644 --- a/doc/src/sgml/ref/pg_waldump.sgml +++ b/doc/src/sgml/ref/pg_waldump.sgml @@ -23,9 +23,7 @@ PostgreSQL documentation pg_waldump - - - + @@ -208,6 +206,32 @@ PostgreSQL documentation + + Environment + + + + PGDATA + + + Data directory; see also the option. + + + + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + + + + Notes diff --git a/doc/src/sgml/ref/pgarchivecleanup.sgml b/doc/src/sgml/ref/pgarchivecleanup.sgml index 4117a4392c1..a3d3538b28a 100644 --- a/doc/src/sgml/ref/pgarchivecleanup.sgml +++ b/doc/src/sgml/ref/pgarchivecleanup.sgml @@ -39,7 +39,7 @@ To configure a standby server to use pg_archivecleanup, put this into its - recovery.conf configuration file: + postgresql.conf configuration file: archive_cleanup_command = 'pg_archivecleanup archivelocation %r' @@ -47,7 +47,7 @@ archive_cleanup_command = 'pg_archivecleanup archivelocation - When used within , all WAL files + When used within , all WAL files logically preceding the value of the %r argument will be removed from archivelocation. This minimizes the number of files that need to be retained, while preserving crash-restart capability. Use of diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml index 41d90300981..e3a0abb4c70 100644 --- a/doc/src/sgml/ref/pgbench.sgml +++ b/doc/src/sgml/ref/pgbench.sgml @@ -306,6 +306,31 @@ pgbench options d + + + + + Create a partitioned pgbench_accounts table with + NUM partitions of nearly equal size for + the scaled number of accounts. + Default is 0, meaning no partitioning. + + + + + + + + + Create a partitioned pgbench_accounts table with + NAME method. + Expected values are range or hash. + This option requires that is set to non-zero. + If unspecified, default is range. + + + + @@ -355,7 +380,6 @@ pgbench options d - clients clients @@ -443,7 +467,7 @@ pgbench options d limit - Transaction which last more than limit milliseconds + Transactions that last more than limit milliseconds are counted and reported separately, as late. @@ -473,6 +497,13 @@ pgbench options d prepared: use extended query protocol with prepared statements. + + In the prepared mode, pgbench + reuses the parse analysis result starting from the second query + iteration, so pgbench runs faster + than in other modes. + + The default is simple query protocol. (See for more information.) @@ -511,7 +542,7 @@ pgbench options d Show progress report every sec seconds. The report - includes the time since the beginning of the run, the tps since the + includes the time since the beginning of the run, the TPS since the last report, and the transaction latency average and standard deviation since the last report. Under throttling (), the latency is computed with respect to the transaction scheduled @@ -610,6 +641,16 @@ pgbench options d + + scriptname + + + Show the actual code of builtin script scriptname + on stderr, and exit immediately. + + + + transactions transactions @@ -727,9 +768,9 @@ pgbench options d Remember to take the sampling rate into account when processing the - log file. For example, when computing tps values, you need to multiply + log file. For example, when computing TPS values, you need to multiply the numbers accordingly (e.g. with 0.01 sample rate, you'll only get - 1/100 of the actual tps). + 1/100 of the actual TPS). @@ -804,11 +845,23 @@ pgbench options d + + Exit Status + + + A successful run will exit with status 0. Exit status 1 indicates static + problems such as invalid command-line options. Errors during the run such + as database errors or problems in the script will result in exit status 2. + In the latter case, pgbench will print partial + results. + + + Notes - What is the <quote>Transaction</quote> Actually Performed in <application>pgbench</application>? + What Is the <quote>Transaction</quote> Actually Performed in <application>pgbench</application>? pgbench executes test scripts chosen randomly @@ -824,7 +877,7 @@ pgbench options d The default built-in transaction script (also invoked with ) issues seven commands per transaction over randomly chosen aid, - tid, bid and balance. + tid, bid and delta. The scenario is inspired by the TPC-B benchmark, but is not actually TPC-B, hence the name. @@ -897,6 +950,8 @@ pgbench options d value can be inserted into a SQL command by writing :variablename. When running more than one client session, each session has its own set of variables. + pgbench supports up to 255 variable uses in one + statement.
@@ -942,13 +997,49 @@ pgbench options d + + + \gset [prefix] + + + + + This command may be used to end SQL queries, taking the place of the + terminating semicolon (;). + + + + When this command is used, the preceding SQL query is expected to + return one row, the columns of which are stored into variables named after + column names, and prefixed with prefix if provided. + + + + The following example puts the final account balance from the first query + into variable abalance, and fills variables + p_two and p_three + with integers from the third query. + The result of the second query is discarded. + +UPDATE pgbench_accounts + SET abalance = abalance + :delta + WHERE aid = :aid + RETURNING abalance \gset +-- compound of two queries +SELECT 1 \; +SELECT 2 AS two, 3 AS three \gset p_ + + + + + \if expression \elif expression \else \endif - + This group of commands implements nestable conditional blocks, similarly to psql's . Conditional expressions are identical to those with \set, @@ -967,7 +1058,7 @@ pgbench options d Sets variable varname to a value calculated from expression. The expression may contain the NULL constant, - boolean constants TRUE and FALSE, + Boolean constants TRUE and FALSE, integer constants such as 5432, double constants such as 3.14159, references to variables :variablename, @@ -989,6 +1080,13 @@ pgbench options d are FALSE. + + Too large or small integer and double constants, as well as + integer arithmetic operators (+, + -, * and /) + raise errors on overflows. + + When no final ELSE clause is provided to a CASE, the default value is NULL. @@ -1078,7 +1176,7 @@ pgbench options d - Built-In Operators + Built-in Operators The arithmetic, bitwise, comparison and logical operators listed in @@ -1088,7 +1186,7 @@ pgbench options d
- pgbench Operators by increasing precedence + pgbench Operators by Increasing Precedence @@ -1215,7 +1313,7 @@ pgbench options d - - substraction + subtraction 3 - 2.0 1.0 @@ -1350,7 +1448,7 @@ pgbench options d 1.0 - mod(i, bj) + mod(i, j) integer modulo mod(54, 32) @@ -1415,7 +1513,7 @@ pgbench options d The random function generates values using a uniform distribution, that is all the values are drawn within the specified - range with equal probability. The random_exponential, + range with equal probability. The random_exponential, random_gaussian and random_zipfian functions require an additional double parameter which determines the precise shape of the distribution. @@ -1479,29 +1577,33 @@ f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) / middle quarter (1.0 / 4.0) of the interval (i.e. from 3.0 / 8.0 to 5.0 / 8.0) and 95% from the middle half (2.0 / 4.0) of the interval (second and third - quartiles). The minimum parameter is 2.0 for performance - of the Box-Muller transform. + quartiles). The minimum allowed parameter + value is 2.0. - random_zipfian generates an approximated bounded zipfian - distribution. For parameter in (0, 1), an - approximated algorithm is taken from - "Quickly Generating Billion-Record Synthetic Databases", - Jim Gray et al, SIGMOD 1994. For parameter - in (1, 1000), a rejection method is used, based on - "Non-Uniform Random Variate Generation", Luc Devroye, p. 550-551, - Springer 1986. The distribution is not defined when the parameter's - value is 1.0. The drawing performance is poor for parameter values - close and above 1.0 and on a small range. + random_zipfian generates a bounded Zipfian + distribution. + parameter defines how skewed the distribution + is. The larger the parameter, the more + frequently values closer to the beginning of the interval are drawn. + The distribution is such that, assuming the range starts from 1, + the ratio of the probability of drawing k + versus drawing k+1 is + ((k+1)/k)**parameter. + For example, random_zipfian(1, ..., 2.5) produces + the value 1 about (2/1)**2.5 = + 5.66 times more frequently than 2, which + itself is produced (3/2)**2.5 = 2.76 times more + frequently than 3, and so on. - parameter - defines how skewed the distribution is. The larger the parameter, the more - frequently values to the beginning of the interval are drawn. - The closer to 0 parameter is, - the flatter (more uniform) the access distribution. + pgbench's implementation is based on + "Non-Uniform Random Variate Generation", Luc Devroye, p. 550-551, + Springer 1986. Due to limitations of that algorithm, + the parameter value is restricted to + the range [1.001, 1000]. @@ -1526,8 +1628,8 @@ f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) / with each other and this is when implicit seed parameter comes in handy: -\set k1 abs(hash(:r), :default_seed + 123) % 1000000 -\set k2 abs(hash(:r), :default_seed + 321) % 1000000 +\set k1 abs(hash(:r, :default_seed + 123)) % 1000000 +\set k2 abs(hash(:r, :default_seed + 321)) % 1000000 diff --git a/doc/src/sgml/ref/pgtesttiming.sgml b/doc/src/sgml/ref/pgtesttiming.sgml index 545a934cf82..798aed36092 100644 --- a/doc/src/sgml/ref/pgtesttiming.sgml +++ b/doc/src/sgml/ref/pgtesttiming.sgml @@ -86,7 +86,7 @@ Usage - Interpreting results + Interpreting Results Good results will show most (>90%) individual timing calls take less than @@ -116,7 +116,7 @@ Histogram of timing durations: - Measuring executor timing overhead + Measuring Executor Timing Overhead When the query executor is running a statement using @@ -145,7 +145,7 @@ EXPLAIN ANALYZE SELECT COUNT(*) FROM t; - Changing time sources + Changing Time Sources On some newer Linux systems, it's possible to change the clock source used to collect timing data at any time. A second example shows the slowdown @@ -223,7 +223,7 @@ Histogram of timing durations: - Clock hardware and timing accuracy + Clock Hardware and Timing Accuracy Collecting accurate timing information is normally done on computers using diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 6dafb404a11..d4da566d762 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -89,6 +89,7 @@ bindir bindir the new PostgreSQL executable directory; + default is the directory where pg_upgrade resides; environment variable PGBINNEW @@ -163,6 +164,14 @@ + + dir + dir + directory to use for postmaster sockets during upgrade; + default is current working directory; environment + variable PGSOCKETDIR + + username username @@ -182,6 +191,27 @@ display version information, then exit + + + + + Use efficient file cloning (also known as reflinks on + some systems) instead of copying files to the new cluster. This can + result in near-instantaneous copying of the data files, giving the + speed advantages of / while + leaving the old cluster untouched. + + + + File cloning is only supported on some operating systems and file + systems. If it is selected but not supported, the + pg_upgrade run will error. At present, it + is supported on Linux (kernel 4.5 or later) with Btrfs and XFS (on + file systems created with reflink support), and on macOS with APFS. + + + + @@ -326,7 +356,8 @@ NET STOP postgresql-&majorversion; against the old primary and standby clusters. Verify that the Latest checkpoint location values match in all clusters. (There will be a mismatch if old standby servers were shut down - before the old primary.) Also, change wal_level to + before the old primary or if the old standby servers are still running.) + Also, change wal_level to replica in the postgresql.conf file on the new primary cluster. @@ -339,7 +370,7 @@ NET STOP postgresql-&majorversion; Always run the pg_upgrade binary of the new server, not the old one. pg_upgrade requires the specification of the old and new cluster's data and executable (bin) directories. You can also specify - user and port values, and whether you want the data files linked + user and port values, and whether you want the data files linked or cloned instead of the default copy behavior. @@ -350,8 +381,12 @@ NET STOP postgresql-&majorversion; once you start the new cluster after the upgrade. Link mode also requires that the old and new cluster data directories be in the same file system. (Tablespaces and pg_wal can be on - different file systems.) See pg_upgrade --help for a full - list of options. + different file systems.) + Clone mode provides the same speed and disk space advantages but + does not cause the old cluster to be unusable once the new cluster + is started. Clone mode also requires that the old and new data + directories be in the same file system. This mode is only available + on certain operating systems and file systems. @@ -387,8 +422,9 @@ pg_upgrade.exe to perform only the checks, even if the old server is still running. pg_upgrade --check will also outline any manual adjustments you will need to make after the upgrade. If you - are going to be using link mode, you should use the - option with to enable link-mode-specific checks. + are going to be using link or clone mode, you should use the option + or with + to enable mode-specific checks. pg_upgrade requires write permission in the current directory. @@ -414,7 +450,7 @@ pg_upgrade.exe - Upgrade Streaming Replication and Log-Shipping standby servers + Upgrade streaming replication and log-shipping standby servers If you used link mode and have Streaming Replication (see Save any configuration files from the old standbys' configuration directories you need to keep, e.g. postgresql.conf, - recovery.conf, because these will be overwritten or + pg_hba.conf, because these will be overwritten or removed in the next step. @@ -581,7 +617,7 @@ rsync --archive --delete --hard-links --size-only --no-inc-recursive /vol1/pg_tb - Post-Upgrade processing + Post-upgrade processing If any post-upgrade processing is required, pg_upgrade will issue @@ -642,32 +678,52 @@ psql --username=postgres --file=script.sql postgres - If you ran pg_upgrade - with , no modifications were made to the old - cluster and you can re-use it anytime. + If the option was used, the old cluster + was unmodified; it can be restarted. - If you ran pg_upgrade - with , the data files are shared between the - old and new cluster. If you started the new cluster, the new - server has written to those shared files and it is unsafe to - use the old cluster. + If the option was not + used, the old cluster was unmodified; it can be restarted. - If you ran pg_upgrade without - or did not start the new server, the - old cluster was not modified except that, if linking - started, a .old suffix was appended to - $PGDATA/global/pg_control. To reuse the old - cluster, possibly remove the .old suffix from - $PGDATA/global/pg_control; you can then restart the - old cluster. + If the option was used, the data + files might be shared between the old and new cluster: + + + + + If pg_upgrade aborted before linking started, + the old cluster was unmodified; it can be restarted. + + + + + + If you did not start the new cluster, the old + cluster was unmodified except that, when linking started, a + .old suffix was appended to + $PGDATA/global/pg_control. To reuse the old + cluster, remove the .old suffix from + $PGDATA/global/pg_control; you can then restart + the old cluster. + + + + + + If you did start the new cluster, it has written to shared files + and it is unsafe to use the old cluster. The old cluster will + need to be restored from backup in this case. + + + + @@ -681,11 +737,21 @@ psql --username=postgres --file=script.sql postgres Notes - pg_upgrade does not support upgrading of databases - containing table columns using these reg* OID-referencing system data types: - regproc, regprocedure, regoper, - regoperator, regconfig, and - regdictionary. (regtype can be upgraded.) + pg_upgrade creates various working files, such + as schema dumps, in the current working directory. For security, be sure + that that directory is not readable or writable by any other users. + + + + pg_upgrade launches short-lived postmasters in + the old and new data directories. Temporary Unix socket files for + communication with these postmasters are, by default, made in the current + working directory. In some situations the path name for the current + directory might be too long to be a valid socket name. In that case you + can use the option to put the socket files in some + directory with a shorter path name. For security, be sure that that + directory is not readable or writable by any other users. + (This is not relevant on Windows.) @@ -704,6 +770,14 @@ psql --username=postgres --file=script.sql postgres insert dummy data, and upgrade that. + + pg_upgrade does not support upgrading of databases + containing table columns using these reg* OID-referencing system data types: + regproc, regprocedure, regoper, + regoperator, regconfig, and + regdictionary. (regtype can be upgraded.) + + If you are upgrading a pre-PostgreSQL 9.2 cluster that uses a configuration-file-only directory, you must pass the @@ -721,7 +795,8 @@ psql --username=postgres --file=script.sql postgres If you want to use link mode and you do not want your old cluster - to be modified when the new cluster is started, make a copy of the + to be modified when the new cluster is started, consider using the clone mode. + If that is not available, make a copy of the old cluster and upgrade that in link mode. To make a valid copy of the old cluster, use rsync to create a dirty copy of the old cluster while the server is running, then shut down diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml index 53dc05a78f0..1a4b7c7825d 100644 --- a/doc/src/sgml/ref/postgres-ref.sgml +++ b/doc/src/sgml/ref/postgres-ref.sgml @@ -391,7 +391,7 @@ PostgreSQL documentation - Semi-internal Options + Semi-Internal Options The options described here are used diff --git a/doc/src/sgml/ref/prepare.sgml b/doc/src/sgml/ref/prepare.sgml index 704fb5e4ab3..9f786cd3adc 100644 --- a/doc/src/sgml/ref/prepare.sgml +++ b/doc/src/sgml/ref/prepare.sgml @@ -52,7 +52,7 @@ PREPARE name [ ( unknown, the type is inferred from the context - in which the parameter is used (if possible). When executing the + in which the parameter is first referenced (if possible). When executing the statement, specify the actual values for these parameters in the EXECUTE statement. Refer to for more @@ -104,7 +104,7 @@ PREPARE name [ ( unknown, it will be inferred - from the context in which the parameter is used. To refer to the + from the context in which the parameter is first referenced. To refer to the parameters in the prepared statement itself, use $1, $2, etc. @@ -127,40 +127,49 @@ PREPARE name [ ( Notes - Prepared statements can use generic plans rather than re-planning with - each set of supplied EXECUTE values. This occurs - immediately for prepared statements with no parameters; otherwise - it occurs only after five or more executions produce plans whose - estimated cost average (including planning overhead) is more expensive - than the generic plan cost estimate. Once a generic plan is chosen, - it is used for the remaining lifetime of the prepared statement. - Using EXECUTE values which are rare in columns with - many duplicates can generate custom plans that are so much cheaper - than the generic plan, even after adding planning overhead, that the - generic plan might never be used. + A prepared statement can be executed with either a generic + plan or a custom plan. A generic + plan is the same across all executions, while a custom plan is generated + for a specific execution using the parameter values given in that call. + Use of a generic plan avoids planning overhead, but in some situations + a custom plan will be much more efficient to execute because the planner + can make use of knowledge of the parameter values. (Of course, if the + prepared statement has no parameters, then this is moot and a generic + plan is always used.) - A generic plan assumes that each value supplied to - EXECUTE is one of the column's distinct values - and that column values are uniformly distributed. For example, - if statistics record three distinct column values, a generic plan - assumes a column equality comparison will match 33% of processed rows. - Column statistics also allow generic plans to accurately compute the - selectivity of unique columns. Comparisons on non-uniformly-distributed - columns and specification of non-existent values affects the average - plan cost, and hence if and when a generic plan is chosen. + By default (that is, when is set + to auto), the server will automatically choose + whether to use a generic or custom plan for a prepared statement that + has parameters. The current rule for this is that the first five + executions are done with custom plans and the average estimated cost of + those plans is calculated. Then a generic plan is created and its + estimated cost is compared to the average custom-plan cost. Subsequent + executions use the generic plan if its cost is not so much higher than + the average custom-plan cost as to make repeated replanning seem + preferable. + + + + This heuristic can be overridden, forcing the server to use either + generic or custom plans, by setting plan_cache_mode + to force_generic_plan + or force_custom_plan respectively. + This setting is primarily useful if the generic plan's cost estimate + is badly off for some reason, allowing it to be chosen even though + its actual cost is much more than that of a custom plan. To examine the query plan PostgreSQL is using - for a prepared statement, use , e.g. - EXPLAIN EXECUTE. + for a prepared statement, use , for example + +EXPLAIN EXECUTE stmt_name(parameter_values); + If a generic plan is in use, it will contain parameter symbols - $n, while a custom plan will have the - supplied parameter values substituted into it. - The row estimates in the generic plan reflect the selectivity - computed for the parameters. + $n, while a custom plan + will have the supplied parameter values substituted into it. @@ -221,7 +230,7 @@ PREPARE usrrptplan (int) AS EXECUTE usrrptplan(1, current_date); - Note that the data type of the second parameter is not specified, + In this example, the data type of the second parameter is not specified, so it is inferred from the context in which $2 is used. diff --git a/doc/src/sgml/ref/prepare_transaction.sgml b/doc/src/sgml/ref/prepare_transaction.sgml index d958f7a06f5..5016ca287e3 100644 --- a/doc/src/sgml/ref/prepare_transaction.sgml +++ b/doc/src/sgml/ref/prepare_transaction.sgml @@ -98,9 +98,9 @@ PREPARE TRANSACTION transaction_id It is not currently allowed to PREPARE a transaction that - has executed any operations involving temporary tables, - created any cursors WITH HOLD, or executed - LISTEN, UNLISTEN, or + has executed any operations involving temporary tables or the session's + temporary namespace, created any cursors WITH HOLD, or + executed LISTEN, UNLISTEN, or NOTIFY. Those features are too tightly tied to the current session to be useful in a transaction to be prepared. diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 10b97950ec1..7789fc61776 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -68,8 +68,8 @@ PostgreSQL documentation Switches to unaligned output mode. (The default output mode is - otherwise aligned.) This is equivalent to \pset format - unaligned. + aligned.) This is equivalent to + \pset format unaligned. @@ -151,6 +151,16 @@ EOF + + + + + Switches to CSV (Comma-Separated Values) output + mode. This is equivalent to \pset format csv. + + + + @@ -270,8 +280,8 @@ EOF - Turn on HTML tabular output. This is - equivalent to \pset format html or the + Switches to HTML output mode. This is + equivalent to \pset format html or the \H command. @@ -558,7 +568,7 @@ EOF Set the field separator for unaligned output to a zero byte. This is - equvalent to \pset fieldsep_zero. + equivalent to \pset fieldsep_zero. @@ -901,6 +911,9 @@ testdb=> host or port as - is equivalent to omitting that parameter. + If hostaddr was specified in the original + connection's conninfo, that address is reused + for the new connection (disregarding any other host specification). @@ -1027,10 +1040,24 @@ testdb=> - This operation is not as efficient as the SQL - COPY command because all data must pass - through the client/server connection. For large - amounts of data the SQL command might be preferable. + Another way to obtain the same result as \copy + ... to is to use the SQL COPY + ... TO STDOUT command and terminate it + with \g filename + or \g |program. + Unlike \copy, this method allows the command to + span multiple lines; also, variable interpolation and backquote + expansion can be used. + + + + + + These operations are not as efficient as the SQL + COPY command with a file or program data source or + destination, because all data must pass through the client/server + connection. For large amounts of data the SQL + command might be preferable. @@ -1314,8 +1341,8 @@ testdb=> The command is used to set default access privileges. The meaning of the - privilege display is explained under - . + privilege display is explained in + . @@ -1334,14 +1361,16 @@ testdb=> In this group of commands, the letters E, i, m, s, t, and v - stand for foreign table, index, materialized view, sequence, table, and view, + stand for foreign table, index, materialized view, + sequence, table, and view, respectively. You can specify any or all of these letters, in any order, to obtain a listing of objects - of these types. For example, \dit lists indexes - and tables. If + is + of these types. For example, \dti lists + tables and indexes. If + is appended to the command name, each object is listed with its - physical size on disk and its associated description, if any. + persistence status (permanent, temporary, or unlogged), + physical size on disk, and associated description if any. If pattern is specified, only objects whose names match the pattern are listed. By default, only user-created objects are shown; supply a @@ -1362,7 +1391,7 @@ testdb=> specified, only those servers whose name matches the pattern are listed. If the form \des+ is used, a full description of each server is shown, including the - server's ACL, type, version, options, and description. + server's access privileges, type, version, options, and description. @@ -1415,24 +1444,24 @@ testdb=> If pattern is specified, only those foreign-data wrappers whose name matches the pattern are listed. If the form \dew+ - is used, the ACL, options, and description of the foreign-data - wrapper are also shown. + is used, the access privileges, options, and description of the + foreign-data wrapper are also shown. - \df[antwS+] [ pattern ] + \df[anptwS+] [ pattern ] Lists functions, together with their result data types, argument data types, and function types, which are classified as agg - (aggregate), normal, trigger, or window. + (aggregate), normal, procedure, trigger, or window. To display only functions of specific type(s), add the corresponding letters a, - n, t, or w to the command. + n, p, t, or w to the command. If pattern is specified, only functions whose names match the pattern are shown. @@ -1629,8 +1658,41 @@ testdb=> The and commands are used to set access privileges. The meaning of the - privilege display is explained under - . + privilege display is explained in + . + + + + + + + \dP[itn+] [ pattern ] + + + Lists partitioned relations. + If pattern + is specified, only entries whose name matches the pattern are listed. + The modifiers t (tables) and i + (indexes) can be appended to the command, filtering the kind of + relations to list. By default, partitioned tables and indexes are + listed. + + + + If the modifier n (nested) is used, + or a pattern is specified, then non-root partitioned relations are + included, and a column is shown displaying the parent of each + partitioned relation. + + + + If + is appended to the command name, the sum of the + sizes of each relation's partitions is also displayed, along with the + relation's description. + If n is combined with +, two + sizes are shown: one including the total size of directly-attached + leaf partitions, and another showing the total size of all partitions, + including indirectly attached sub-partitions. @@ -1801,22 +1863,22 @@ testdb=> \echo text [ ... ] - Prints the arguments to the standard output, separated by one - space and followed by a newline. This can be useful to + Prints the evaluated arguments to standard output, separated by + spaces and followed by a newline. This can be useful to intersperse information in the output of scripts. For example: => \echo `date` Tue Oct 26 21:40:57 CEST 1999 If the first argument is an unquoted -n the trailing - newline is not written. + newline is not written (nor is the first argument). If you use the \o command to redirect your query output you might wish to use \qecho - instead of this command. + instead of this command. See also \warn. @@ -2520,6 +2582,19 @@ lo_import 152801 + + csv_fieldsep + + + Specifies the field separator to be used in + CSV output format. If the separator character + appears in a field's value, that field is output within double + quotes, following standard CSV rules. + The default is a comma. + + + + expanded (or x) @@ -2547,8 +2622,8 @@ lo_import 152801 Specifies the field separator to be used in unaligned output - format. That way one can create, for example, tab- or - comma-separated output, which other programs might prefer. To + format. That way one can create, for example, tab-separated + output, which other programs might prefer. To set a tab as field separator, type \pset fieldsep '\t'. The default field separator is '|' (a vertical bar). @@ -2584,25 +2659,49 @@ lo_import 152801 format - Sets the output format to one of unaligned, - aligned, wrapped, - html, asciidoc, - latex (uses tabular), - latex-longtable, or - troff-ms. - Unique abbreviations are allowed. (That would mean one letter - is enough.) + Sets the output format to one of aligned, + asciidoc, + csv, + html, + latex, + latex-longtable, troff-ms, + unaligned, or wrapped. + Unique abbreviations are allowed. + + + aligned format is the standard, + human-readable, nicely formatted text output; this is the default. unaligned format writes all columns of a row on one line, separated by the currently active field separator. This is useful for creating output that might be intended to be read - in by other programs (for example, tab-separated or comma-separated - format). + in by other programs, for example, tab-separated or comma-separated + format. However, the field separator character is not treated + specially if it appears in a column's value; + so CSV format may be better suited for such + purposes. - aligned format is the standard, human-readable, - nicely formatted text output; this is the default. + csv format + + CSV (Comma-Separated Values) format + in psql + + writes column values separated by commas, applying the quoting + rules described in + RFC 4180. + This output is compatible with the CSV format of the server's + COPY command. + A header line with column names is generated unless + the tuples_only parameter is + on. Titles and footers are not printed. + Each row is terminated by the system-dependent end-of-line character, + which is typically a single newline (\n) for + Unix-like systems or a carriage return and newline sequence + (\r\n) for Microsoft Windows. + Field separator characters other than comma can be selected with + \pset csv_fieldsep. wrapped format is like aligned but wraps @@ -2615,15 +2714,19 @@ lo_import 152801 - The html, asciidoc, latex, - latex-longtable, and troff-ms - formats put out tables that are intended to - be included in documents using the respective mark-up + The asciidoc, html, + latex, latex-longtable, and + troff-ms formats put out tables that are intended + to be included in documents using the respective mark-up language. They are not complete documents! This might not be necessary in HTML, but in LaTeX you must have a complete - document wrapper. latex-longtable - also requires the LaTeX + document wrapper. + The latex format + uses LaTeX's tabular + environment. + The latex-longtable format + requires the LaTeX longtable and booktabs packages. @@ -3123,6 +3226,18 @@ testdb=> \setenv LESS -imx4F + + \warn text [ ... ] + + + This command is identical to \echo except + that the output will be written to psql's + standard error channel, rather than standard output. + + + + + \watch [ seconds ] @@ -3581,6 +3696,17 @@ bar + + HIDE_TABLEAM + + + If this variable is set to true, a table's access + method details are not displayed. This is mainly useful for + regression tests. + + + + HISTCONTROL @@ -3685,6 +3811,9 @@ bar command. This variable is only guaranteed to be valid until after the result of the next SQL command has been displayed. + PostgreSQL servers since version 12 do not + support OID system columns anymore, thus LASTOID will always be 0 + following INSERT when targeting such servers. @@ -3816,7 +3945,8 @@ bar messages from the server. The default is errors (meaning that context will be shown in error messages, but not in notice or warning messages). This setting has no effect - when VERBOSITY is set to terse. + when VERBOSITY is set to terse + or sqlstate. (See also \errverbose, for use when you want a verbose version of the error you just got.) @@ -3870,8 +4000,9 @@ bar This variable can be set to the values default, - verbose, or terse to control the verbosity - of error reports. + verbose, terse, + or sqlstate to control the verbosity of error + reports. (See also \errverbose, for use when you want a verbose version of the error you just got.) @@ -4257,6 +4388,17 @@ $endif + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + + PSQL_EDITOR EDITOR @@ -4590,17 +4732,24 @@ first second peter@localhost testdb=> \pset border 1 Border style is 1. -peter@localhost testdb=> \pset format unaligned -Output format is unaligned. -peter@localhost testdb=> \pset fieldsep "," -Field separator is ",". +peter@localhost testdb=> \pset format csv +Output format is csv. peter@localhost testdb=> \pset tuples_only -Showing only tuples. +Tuples only is on. peter@localhost testdb=> SELECT second, first FROM my_table; one,1 two,2 three,3 four,4 +peter@localhost testdb=> \pset format unaligned +Output format is unaligned. +peter@localhost testdb=> \pset fieldsep '\t' +Field separator is " ". +peter@localhost testdb=> SELECT second, first FROM my_table; +one 1 +two 2 +three 3 +four 4 Alternatively, use the short commands: diff --git a/doc/src/sgml/ref/reassign_owned.sgml b/doc/src/sgml/ref/reassign_owned.sgml index 0fffd6088a9..42f72a726fd 100644 --- a/doc/src/sgml/ref/reassign_owned.sgml +++ b/doc/src/sgml/ref/reassign_owned.sgml @@ -88,9 +88,11 @@ REASSIGN OWNED BY { old_role | CURR The REASSIGN OWNED command does not affect any - privileges granted to the old_roles for - objects that are not owned by them. Use DROP OWNED to - revoke such privileges. + privileges granted to + the old_roles on objects + that are not owned by them. Likewise, it does not affect default + privileges created with ALTER DEFAULT PRIVILEGES. + Use DROP OWNED to revoke such privileges. diff --git a/doc/src/sgml/ref/refresh_materialized_view.sgml b/doc/src/sgml/ref/refresh_materialized_view.sgml index 9cf01a25a5d..fd06f1fda14 100644 --- a/doc/src/sgml/ref/refresh_materialized_view.sgml +++ b/doc/src/sgml/ref/refresh_materialized_view.sgml @@ -31,7 +31,8 @@ REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name REFRESH MATERIALIZED VIEW completely replaces the - contents of a materialized view. The old contents are discarded. If + contents of a materialized view. To execute this command you must be the + owner of the materialized view. The old contents are discarded. If WITH DATA is specified (or defaults) the backing query is executed to provide the new data, and the materialized view is left in a scannable state. If WITH NO DATA is specified no new diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 1c21fafb80e..10881ab03a8 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } name +REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name @@ -65,12 +65,11 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } - An index build with the CONCURRENTLY option failed, leaving - an invalid index. Such indexes are useless but it can be - convenient to use REINDEX to rebuild them. Note that - REINDEX will not perform a concurrent build. To build the - index without interfering with production you should drop the index and - reissue the CREATE INDEX CONCURRENTLY command. + If an index build fails with the CONCURRENTLY option, + this index is left as invalid. Such indexes are useless + but it can be convenient to use REINDEX to rebuild + them. Note that only REINDEX INDEX is able + to perform a concurrent build on an invalid index. @@ -151,6 +150,21 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } + + CONCURRENTLY + + + When this option is used, PostgreSQL will rebuild the + index without taking any locks that prevent concurrent inserts, + updates, or deletes on the table; whereas a standard index rebuild + locks out writes (but not reads) on the table until it's done. + There are several caveats to be aware of when using this option + — see . + + + + VERBOSE @@ -225,10 +239,15 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } Reindexing a single index or table requires being the owner of that - index or table. Reindexing a database requires being the owner of - the database (note that the owner can therefore rebuild indexes of - tables owned by other users). Of course, superusers can always - reindex anything. + index or table. Reindexing a schema or database requires being the + owner of that schema or database. Note that is therefore sometimes + possible for non-superusers to rebuild indexes of tables owned by + other users. However, as a special exception, when + REINDEX DATABASE, REINDEX SCHEMA + or REINDEX SYSTEM is issued by a non-superuser, + indexes on shared catalogs will be skipped unless the user owns the + catalog (which typically won't be the case). Of course, superusers + can always reindex anything. @@ -236,6 +255,159 @@ REINDEX [ ( VERBOSE ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } + + Rebuilding Indexes Concurrently + + + index + rebuilding concurrently + + + + Rebuilding an index can interfere with regular operation of a database. + Normally PostgreSQL locks the table whose index is rebuilt + against writes and performs the entire index build with a single scan of the + table. Other transactions can still read the table, but if they try to + insert, update, or delete rows in the table they will block until the + index rebuild is finished. This could have a severe effect if the system is + a live production database. Very large tables can take many hours to be + indexed, and even for smaller tables, an index rebuild can lock out writers + for periods that are unacceptably long for a production system. + + + + PostgreSQL supports rebuilding indexes with minimum locking + of writes. This method is invoked by specifying the + CONCURRENTLY option of REINDEX. When this option + is used, PostgreSQL must perform two scans of the table + for each index that needs to be rebuilt and wait for termination of + all existing transactions that could potentially use the index. + This method requires more total work than a standard index + rebuild and takes significantly longer to complete as it needs to wait + for unfinished transactions that might modify the index. However, since + it allows normal operations to continue while the index is being rebuilt, this + method is useful for rebuilding indexes in a production environment. Of + course, the extra CPU, memory and I/O load imposed by the index rebuild + may slow down other operations. + + + + The following steps occur in a concurrent reindex. Each step is run in a + separate transaction. If there are multiple indexes to be rebuilt, then + each step loops through all the indexes before moving to the next step. + + + + + A new temporary index definition is added to the catalog + pg_index. This definition will be used to replace + the old index. A SHARE UPDATE EXCLUSIVE lock at + session level is taken on the indexes being reindexed as well as their + associated tables to prevent any schema modification while processing. + + + + + + A first pass to build the index is done for each new index. Once the + index is built, its flag pg_index.indisready is + switched to true to make it ready for inserts, making it + visible to other sessions once the transaction that performed the build + is finished. This step is done in a separate transaction for each + index. + + + + + + Then a second pass is performed to add tuples that were added while the + first pass was running. This step is also done in a separate + transaction for each index. + + + + + + All the constraints that refer to the index are changed to refer to the + new index definition, and the names of the indexes are changed. At + this point, pg_index.indisvalid is switched to + true for the new index and to false for + the old, and a cache invalidation is done causing all sessions that + referenced the old index to be invalidated. + + + + + + The old indexes have pg_index.indisready switched to + false to prevent any new tuple insertions, after waiting + for running queries that might reference the old index to complete. + + + + + + The old indexes are dropped. The SHARE UPDATE + EXCLUSIVE session locks for the indexes and the table are + released. + + + + + + + If a problem arises while rebuilding the indexes, such as a + uniqueness violation in a unique index, the REINDEX + command will fail but leave behind an invalid new index in addition to + the pre-existing one. This index will be ignored for querying purposes + because it might be incomplete; however it will still consume update + overhead. The psql \d command will report + such an index as INVALID: + + +postgres=# \d tab + Table "public.tab" + Column | Type | Modifiers +--------+---------+----------- + col | integer | +Indexes: + "idx" btree (col) + "idx_ccnew" btree (col) INVALID + + + The recommended recovery method in such cases is to drop the invalid index + and try again to perform REINDEX CONCURRENTLY. The + concurrent index created during the processing has a name ending in the + suffix ccnew, or ccold if it is an + old index definition which we failed to drop. Invalid indexes can be + dropped using DROP INDEX, including invalid toast + indexes. + + + + Regular index builds permit other regular index builds on the same table + to occur simultaneously, but only one concurrent index build can occur on a + table at a time. In both cases, no other types of schema modification on + the table are allowed meanwhile. Another difference is that a regular + REINDEX TABLE or REINDEX INDEX + command can be performed within a transaction block, but REINDEX + CONCURRENTLY cannot. + + + + REINDEX SYSTEM does not support + CONCURRENTLY since system catalogs cannot be reindexed + concurrently. + + + + Furthermore, indexes for exclusion constraints cannot be reindexed + concurrently. If such an index is named directly in this command, an + error is raised. If a table or database with exclusion constraint indexes + is reindexed concurrently, those indexes will be skipped. (It is possible + to reindex such indexes without the CONCURRENTLY option.) + + @@ -267,6 +439,14 @@ $ psql broken_db ... broken_db=> REINDEX DATABASE broken_db; broken_db=> \q + + + + Rebuild indexes for a table, without blocking read and write operations + on involved relations while reindexing is in progress: + + +REINDEX TABLE CONCURRENTLY my_broken_table; @@ -277,4 +457,14 @@ broken_db=> \q There is no REINDEX command in the SQL standard. + + + See Also + + + + + + + diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml index 1273dad8072..5e21fbcc4e6 100644 --- a/doc/src/sgml/ref/reindexdb.sgml +++ b/doc/src/sgml/ref/reindexdb.sgml @@ -118,6 +118,16 @@ PostgreSQL documentation + + + + + Use the CONCURRENTLY option. See for further information. + + + + @@ -156,6 +166,29 @@ PostgreSQL documentation + + + + + + Execute the reindex commands in parallel by running + njobs + commands simultaneously. This option reduces the time of the + processing but it also increases the load on the database server. + + + reindexdb will open + njobs connections to the + database, so make sure your + setting is high enough to accommodate all connections. + + + Note that this option is incompatible with the + and options. + + + + @@ -342,6 +375,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/ref/revoke.sgml b/doc/src/sgml/ref/revoke.sgml index 7018202f144..e96d45e7e31 100644 --- a/doc/src/sgml/ref/revoke.sgml +++ b/doc/src/sgml/ref/revoke.sgml @@ -177,18 +177,10 @@ REVOKE [ ADMIN OPTION FOR ] Notes - - Use 's \dp command to - display the privileges granted on existing tables and columns. See for information about the - format. For non-table objects there are other \d commands - that can display their privileges. - - A user can only revoke privileges that were granted directly by that user. If, for example, user A has granted a privilege with - grant option to user B, and user B has in turned granted it to user + grant option to user B, and user B has in turn granted it to user C, then user A cannot revoke the privilege directly from C. Instead, user A could revoke the grant option from user B and use the CASCADE option so that the privilege is @@ -244,6 +236,11 @@ REVOKE [ ADMIN OPTION FOR ] lead to revoking privileges other than the ones you intended, or not revoking anything at all. + + + See for more information about specific + privilege types, as well as how to inspect objects' privileges. + @@ -293,9 +290,10 @@ REVOKE admins FROM joe; See Also - - - + + + + diff --git a/doc/src/sgml/ref/rollback.sgml b/doc/src/sgml/ref/rollback.sgml index 3cafb848a9a..1357eaa8323 100644 --- a/doc/src/sgml/ref/rollback.sgml +++ b/doc/src/sgml/ref/rollback.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation -ROLLBACK [ WORK | TRANSACTION ] +ROLLBACK [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ] @@ -37,6 +37,10 @@ ROLLBACK [ WORK | TRANSACTION ] Parameters + + chained transactions + + WORK @@ -47,6 +51,18 @@ ROLLBACK [ WORK | TRANSACTION ] + + + AND CHAIN + + + If AND CHAIN is specified, a new transaction is + immediately started with the same transaction characteristics (see ) as the just finished one. Otherwise, + no new transaction is started. + + + @@ -60,7 +76,8 @@ ROLLBACK [ WORK | TRANSACTION ] Issuing ROLLBACK outside of a transaction - block emits a warning and otherwise has no effect. + block emits a warning and otherwise has no effect. ROLLBACK AND + CHAIN outside of a transaction block is an error. @@ -78,9 +95,8 @@ ROLLBACK; Compatibility - The SQL standard only specifies the two forms - ROLLBACK and ROLLBACK - WORK. Otherwise, this command is fully conforming. + The command ROLLBACK conforms to the SQL standard. The + form ROLLBACK TRANSACTION is a PostgreSQL extension. diff --git a/doc/src/sgml/ref/select.sgml b/doc/src/sgml/ref/select.sgml index b5d3d3a071e..06d611b64c2 100644 --- a/doc/src/sgml/ref/select.sgml +++ b/doc/src/sgml/ref/select.sgml @@ -72,7 +72,7 @@ SELECT [ ALL | DISTINCT [ ON ( expressionand with_query is: - with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete ) + with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( select | values | insert | update | delete ) TABLE [ ONLY ] table_name [ * ] @@ -93,7 +93,8 @@ TABLE [ ONLY ] table_name [ * ] These effectively serve as temporary tables that can be referenced in the FROM list. A WITH query that is referenced more than once in FROM is - computed only once. + computed only once, + unless specified otherwise with NOT MATERIALIZED. (See below.) @@ -272,9 +273,18 @@ TABLE [ ONLY ] table_name [ * ] that are earlier in the WITH list. + + The primary query and the WITH queries are all + (notionally) executed at the same time. This implies that the effects of + a data-modifying statement in WITH cannot be seen from + other parts of the query, other than by reading its RETURNING + output. If two such data-modifying statements attempt to modify the same + row, the results are unspecified. + + A key property of WITH queries is that they - are evaluated only once per execution of the primary query, + are normally evaluated only once per execution of the primary query, even if the primary query refers to them more than once. In particular, data-modifying statements are guaranteed to be executed once and only once, regardless of whether the primary query @@ -282,12 +292,35 @@ TABLE [ ONLY ] table_name [ * ] - The primary query and the WITH queries are all - (notionally) executed at the same time. This implies that the effects of - a data-modifying statement in WITH cannot be seen from - other parts of the query, other than by reading its RETURNING - output. If two such data-modifying statements attempt to modify the same - row, the results are unspecified. + However, a WITH query can be marked + NOT MATERIALIZED to remove this guarantee. In that + case, the WITH query can be folded into the primary + query much as though it were a simple sub-SELECT in + the primary query's FROM clause. This results in + duplicate computations if the primary query refers to + that WITH query more than once; but if each such use + requires only a few rows of the WITH query's total + output, NOT MATERIALIZED can provide a net savings by + allowing the queries to be optimized jointly. + NOT MATERIALIZED is ignored if it is attached to + a WITH query that is recursive or is not + side-effect-free (i.e., is not a plain SELECT + containing no volatile functions). + + + + By default, a side-effect-free WITH query is folded + into the primary query if it is used exactly once in the primary + query's FROM clause. This allows joint optimization + of the two query levels in situations where that should be semantically + invisible. However, such folding can be prevented by marking the + WITH query as MATERIALIZED. + That might be useful, for example, if the WITH query + is being used as an optimization fence to prevent the planner from + choosing a bad plan. + PostgreSQL versions before v12 never did + such folding, so queries written for older versions might rely on + WITH to act as an optimization fence. @@ -901,8 +934,8 @@ EXCLUDE NO OTHERS CURRENT ROW; it sets the frame to be all rows from the partition start up through the current row's last peer (a row that the window's ORDER BY clause considers - equivalent to the current row), or all rows if there - is no ORDER BY. + equivalent to the current row; all rows are peers if there + is no ORDER BY). In general, UNBOUNDED PRECEDING means that the frame starts with the first row of the partition, and similarly UNBOUNDED FOLLOWING means that the frame ends with the last @@ -924,7 +957,7 @@ EXCLUDE NO OTHERS is an integer indicating that the frame starts or ends that many peer groups before or after the current row's peer group, where a peer group is a group of rows that are - equivalent according to ORDER BY. + equivalent according to the window's ORDER BY clause. In RANGE mode, use of an offset option requires that there be exactly one ORDER BY column in the window definition. @@ -1399,10 +1432,12 @@ OFFSET start OFFSET start { ROW | ROWS } FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY - In this syntax, to write anything except a simple integer constant for - start or count, you must write parentheses - around it. + In this syntax, the start + or count value is required by + the standard to be a literal constant, a parameter, or a variable name; + as a PostgreSQL extension, other expressions + are allowed, but will generally need to be enclosed in parentheses to avoid + ambiguity. If count is omitted in a FETCH clause, it defaults to 1. ROW @@ -2085,6 +2120,12 @@ SELECT distributors.* WHERE distributors.name = 'Westward'; ROWS FROM( ... ) is an extension of the SQL standard. + + + The MATERIALIZED and NOT + MATERIALIZED options of WITH are extensions + of the SQL standard. + diff --git a/doc/src/sgml/ref/select_into.sgml b/doc/src/sgml/ref/select_into.sgml index 6c1a25f5ed5..b1af52a4da1 100644 --- a/doc/src/sgml/ref/select_into.sgml +++ b/doc/src/sgml/ref/select_into.sgml @@ -106,10 +106,13 @@ SELECT [ ALL | DISTINCT [ ON ( expression - To add OIDs to the table created by SELECT INTO, - enable the configuration - variable. Alternatively, CREATE TABLE AS can be - used with the WITH OIDS clause. + In contrast to CREATE TABLE AS, SELECT + INTO does not allow to specify properties like a table's access + method with or the table's + tablespace with . Use if necessary. Therefore, the default table + access method is chosen for the new table. See for more information. diff --git a/doc/src/sgml/ref/set_role.sgml b/doc/src/sgml/ref/set_role.sgml index 0ef6eb9a9c1..9ab0d6af04c 100644 --- a/doc/src/sgml/ref/set_role.sgml +++ b/doc/src/sgml/ref/set_role.sgml @@ -70,7 +70,7 @@ RESET ROLE effectively drops all the privileges assigned directly to the session user and to the other roles it is a member of, leaving only the privileges available to the named role. On the other hand, if the session user role - has the NOINHERITS attribute, SET ROLE drops the + has the NOINHERIT attribute, SET ROLE drops the privileges assigned directly to the session user and instead acquires the privileges available to the named role. diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml index 77430a586cb..f58dcd8877b 100644 --- a/doc/src/sgml/ref/update.sgml +++ b/doc/src/sgml/ref/update.sgml @@ -287,13 +287,30 @@ UPDATE count row satisfies its partition constraint, then the row is moved to that partition. If there is no such partition, an error will occur. Behind the scenes, the row movement is actually a DELETE and - INSERT operation. However, there is a possibility that a - concurrent UPDATE or DELETE on the - same row may miss this row. For details see the section - . - Currently, rows cannot be moved from a partition that is a - foreign table to some other partition, but they can be moved into a foreign - table if the foreign data wrapper supports it. + INSERT operation. + + + + There is a possibility that a concurrent UPDATE or + DELETE on the row being moved will get a serialization + failure error. Suppose session 1 is performing an UPDATE + on a partition key, and meanwhile a concurrent session 2 for which this + row is visible performs an UPDATE or + DELETE operation on this row. In such case, + session 2's UPDATE or DELETE will + detect the row movement and raise a serialization failure error (which + always returns with an SQLSTATE code '40001'). Applications may wish to + retry the transaction if this occurs. In the usual case where the table + is not partitioned, or where there is no row movement, session 2 would + have identified the newly updated row and carried out the + UPDATE/DELETE on this new row + version. + + + + Note that while rows can be moved from local partitions to a foreign-table + partition (provided the foreign data wrapper supports tuple routing), they + cannot be moved from a foreign-table partition to another partition. diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index b760e8ede18..f9b0fb87945 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -26,11 +26,14 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ option can be one of: - FULL - FREEZE - VERBOSE - ANALYZE - DISABLE_PAGE_SKIPPING + FULL [ boolean ] + FREEZE [ boolean ] + VERBOSE [ boolean ] + ANALYZE [ boolean ] + DISABLE_PAGE_SKIPPING [ boolean ] + SKIP_LOCKED [ boolean ] + INDEX_CLEANUP [ boolean ] + TRUNCATE [ boolean ] and table_and_columns is: @@ -160,6 +163,80 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ ). However, if index + cleanup is not performed regularly, performance may suffer, because + as the table is modified, indexes will accumulate dead tuples + and the table itself will accumulate dead line pointers that cannot be + removed until index cleanup is completed. This option has no effect + for tables that do not have an index and is ignored if the + FULL option is used. + + + + + + TRUNCATE + + + Specifies that VACUUM should attempt to + truncate off any empty pages at the end of the table and allow + the disk space for the truncated pages to be returned to + the operating system. This is normally the desired behavior + and is the default unless the vacuum_truncate + option has been set to false for the table to be vacuumed. + Setting this option to false may be useful to avoid + ACCESS EXCLUSIVE lock on the table that + the truncation requires. This option is ignored if the + FULL option is used. + + + + + + boolean + + + Specifies whether the selected option should be turned on or off. + You can write TRUE, ON, or + 1 to enable the option, and FALSE, + OFF, or 0 to disable it. The + boolean value can also + be omitted, in which case TRUE is assumed. + + + + table_name diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml index 955a17a849b..47d93456f86 100644 --- a/doc/src/sgml/ref/vacuumdb.sgml +++ b/doc/src/sgml/ref/vacuumdb.sgml @@ -102,6 +102,21 @@ PostgreSQL documentation + + + + + Disable skipping pages based on the contents of the visibility map. + + + + This option is only available for servers running + PostgreSQL 9.6 and later. + + + + + @@ -157,6 +172,60 @@ PostgreSQL documentation + + + + + Only execute the vacuum or analyze commands on tables with a multixact + ID age of at least mxid_age. + This setting is useful for prioritizing tables to process to prevent + multixact ID wraparound (see + ). + + + For the purposes of this option, the multixact ID age of a relation is + the greatest of the ages of the main relation and its associated + TOAST table, if one exists. Since the commands + issued by vacuumdb will also process the + TOAST table for the relation if necessary, it does + not need to be considered separately. + + + + This option is only available for servers running + PostgreSQL 9.6 and later. + + + + + + + + + + Only execute the vacuum or analyze commands on tables with a + transaction ID age of at least + xid_age. This setting + is useful for prioritizing tables to process to prevent transaction + ID wraparound (see ). + + + For the purposes of this option, the transaction ID age of a relation + is the greatest of the ages of the main relation and its associated + TOAST table, if one exists. Since the commands + issued by vacuumdb will also process the + TOAST table for the relation if necessary, it does + not need to be considered separately. + + + + This option is only available for servers running + PostgreSQL 9.6 and later. + + + + + @@ -167,6 +236,21 @@ PostgreSQL documentation + + + + + Skip relations that cannot be immediately locked for processing. + + + + This option is only available for servers running + PostgreSQL 12 and later. + + + + + @@ -367,6 +451,17 @@ PostgreSQL documentation + + + PG_COLOR + + + Specifies whether to use color in diagnostics messages. Possible values + are always, auto, + never. + + + diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml index ef2270c4673..cef09dd38b3 100644 --- a/doc/src/sgml/reference.sgml +++ b/doc/src/sgml/reference.sgml @@ -186,7 +186,6 @@ &listen; &load; &lock; - &merge; &move; ¬ify; &prepare; @@ -277,6 +276,7 @@ &initdb; &pgarchivecleanup; + &pgChecksums; &pgControldata; &pgCtl; &pgResetwal; diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index 673a8c21642..d98187c970e 100644 --- a/doc/src/sgml/regress.sgml +++ b/doc/src/sgml/regress.sgml @@ -47,7 +47,7 @@ make check ======================= - All 115 tests passed. + All 193 tests passed. ======================= @@ -98,7 +98,7 @@ make MAX_CONNECTIONS=10 check To run the tests after installation (see ), - initialize a data area and start the + initialize a data directory and start the server as explained in , then type: make installcheck @@ -116,10 +116,10 @@ make installcheck-parallel The tests will also transiently create some cluster-wide objects, such as - roles and tablespaces. These objects will have names beginning with - regress_. Beware of using installcheck - mode in installations that have any actual users or tablespaces named - that way. + roles, tablespaces, and subscriptions. These objects will have names + beginning with regress_. Beware of + using installcheck mode with an installation that has + any actual global objects named that way. @@ -130,7 +130,7 @@ make installcheck-parallel The make check and make installcheck commands run only the core regression tests, which test built-in functionality of the PostgreSQL server. The source - distribution also contains additional test suites, most of them having + distribution contains many additional test suites, most of them having to do with add-on functionality such as optional procedural languages. @@ -146,9 +146,24 @@ make installcheck-world already-installed server, respectively, just as previously explained for make check and make installcheck. Other considerations are the same as previously explained for each method. - Note that make check-world builds a separate temporary - installation tree for each tested module, so it requires a great deal - more time and disk space than make installcheck-world. + Note that make check-world builds a separate instance + (temporary data directory) for each tested module, so it requires more + time and disk space than make installcheck-world. + + + + On a modern machine with multiple CPU cores and no tight operating-system + limits, you can make things go substantially faster with parallelism. + The recipe that most PostgreSQL developers actually use for running all + tests is something like + +make check-world -j8 >/dev/null + + with a limit near to or a bit more than the number + of available cores. Discarding stdout + eliminates chatter that's not interesting when you just want to verify + success. (In case of failure, the stderr + messages are usually enough to determine where to look closer.) @@ -166,8 +181,7 @@ make installcheck-world - Regression tests for optional procedural languages (other than - PL/pgSQL, which is tested by the core tests). + Regression tests for optional procedural languages. These are located under src/pl. @@ -184,6 +198,13 @@ make installcheck-world located in src/interfaces/ecpg/test. + + + Tests for core-supported authentication methods, + located in src/test/authentication. + (See below for additional authentication-related tests.) + + Tests stressing behavior of concurrent sessions, @@ -192,21 +213,36 @@ make installcheck-world - Tests of client programs under src/bin. See - also . + Tests for crash recovery and physical replication, + located in src/test/recovery. + + + + + Tests for logical replication, + located in src/test/subscription. + + + + + Tests of client programs, located under src/bin. - When using installcheck mode, these tests will destroy any - existing databases named pl_regression, - contrib_regression, isolation_regression, - ecpg1_regression, or ecpg2_regression, as well as - regression. + When using installcheck mode, these tests will create + and destroy test databases whose names + include regression, for + example pl_regression + or contrib_regression. Beware of + using installcheck mode with an installation that has + any non-test databases named that way. + Some of these auxiliary test suites use the TAP infrastructure explained + in . The TAP-based tests are run only when PostgreSQL was configured with the option . This is recommended for development, but can be omitted if there is no suitable Perl installation. @@ -259,6 +295,17 @@ make check-world PG_TEST_EXTRA='kerberos ldap ssl' configuration are not run even if they are mentioned in PG_TEST_EXTRA. + + + In addition, there are tests in src/test/modules + which will be run by make check-world but not + by make installcheck-world. This is because they + install non-production extensions or have other side-effects that are + considered undesirable for a production installation. You can + use make install and make + installcheck in one of those subdirectories if you wish, + but it's not recommended to do so with a non-test server. + @@ -316,14 +363,6 @@ make check LANG=C ENCODING=EUC_JP make check EXTRA_TESTS=numeric_big - To run the collation tests: - -make check EXTRA_TESTS='collate.icu.utf8 collate.linux.utf8' LANG=en_US.utf8 - - The collate.linux.utf8 test works only on Linux/glibc - platforms. The collate.icu.utf8 test only works when - support for ICU was built. Both tests will only succeed when run in a - database that uses UTF-8 encoding. @@ -410,7 +449,7 @@ make standbycheck If you don't like the diff options that are used by default, set the environment variable PG_REGRESS_DIFF_OPTS, for - instance PG_REGRESS_DIFF_OPTS='-u'. (Or you + instance PG_REGRESS_DIFF_OPTS='-c'. (Or you can run diff yourself, if you prefer.) @@ -653,22 +692,21 @@ testname:output:platformpattern=comparisonfilename - For example: some systems interpret very small floating-point values - as zero, rather than reporting an underflow error. This causes a - few differences in the float8 regression test. + For example: some systems lack a working strtof function, + for which our workaround causes rounding errors in the + float4 regression test. Therefore, we provide a variant comparison file, - float8-small-is-zero.out, which includes + float4-misrounded-input.out, which includes the results to be expected on these systems. To silence the bogus - failure message on OpenBSD + failure message on HP-UX 10 platforms, resultmap includes: -float8:out:i.86-.*-openbsd=float8-small-is-zero.out +float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out which will trigger on any machine where the output of - config.guess matches i.86-.*-openbsd. - Other lines - in resultmap select the variant comparison file for other - platforms where it's appropriate. + config.guess matches hppa.*-hp-hpux10.*. + Other lines in resultmap select the variant comparison + file for other platforms where it's appropriate. @@ -738,6 +776,26 @@ make check PROVE_TESTS='t/001_test1.pl t/003_test3.pl' The TAP tests require the Perl module IPC::Run. This module is available from CPAN or an operating system package. + + + Generically speaking, the TAP tests will test the executables in a + previously-installed installation tree if you say make + installcheck, or will build a new local installation tree from + current sources if you say make check. In either + case they will initialize a local instance (data directory) and + transiently run a server in it. Some of these tests run more than one + server. Thus, these tests can be fairly resource-intensive. + + + + It's important to realize that the TAP tests will start test server(s) + even when you say make installcheck; this is unlike + the traditional non-TAP testing infrastructure, which expects to use an + already-running test server in that case. Some PostgreSQL + subdirectories contain both traditional-style and TAP-style tests, + meaning that make installcheck will produce a mix of + results from temporary servers and the already-running test server. + diff --git a/doc/src/sgml/release-10.sgml b/doc/src/sgml/release-10.sgml deleted file mode 100644 index 8553803aae8..00000000000 --- a/doc/src/sgml/release-10.sgml +++ /dev/null @@ -1,5787 +0,0 @@ - - - - - Release 10.3 - - - Release date: - 2018-03-01 - - - - This release contains a variety of fixes from 10.2. - For information about new features in major release 10, see - . - - - - Migration to Version 10.3 - - - A dump/restore is not required for those running 10.X. - - - - However, if you run an installation in which not all users are mutually - trusting, or if you maintain an application or extension that is - intended for use in arbitrary situations, it is strongly recommended - that you read the documentation changes described in the first changelog - entry below, and take suitable steps to ensure that your installation or - code is secure. - - - - Also, the changes described in the second changelog entry below may - cause functions used in index expressions or materialized views to fail - during auto-analyze, or when reloading from a dump. After upgrading, - monitor the server logs for such problems, and fix affected functions. - - - - Also, if you are upgrading from a version earlier than 10.2, - see . - - - - - Changes - - - - - - - Document how to configure installations and applications to guard - against search-path-dependent trojan-horse attacks from other users - (Noah Misch) - - - - Using a search_path setting that includes any - schemas writable by a hostile user enables that user to capture - control of queries and then run arbitrary SQL code with the - permissions of the attacked user. While it is possible to write - queries that are proof against such hijacking, it is notationally - tedious, and it's very easy to overlook holes. Therefore, we now - recommend configurations in which no untrusted schemas appear in - one's search path. Relevant documentation appears in - (for database administrators and users), - (for application authors), - (for extension authors), and - (for authors - of SECURITY DEFINER functions). - (CVE-2018-1058) - - - - - - - Avoid use of insecure search_path settings - in pg_dump and other client programs - (Noah Misch, Tom Lane) - - - - pg_dump, - pg_upgrade, - vacuumdb and - other PostgreSQL-provided applications were - themselves vulnerable to the type of hijacking described in the previous - changelog entry; since these applications are commonly run by - superusers, they present particularly attractive targets. To make them - secure whether or not the installation as a whole has been secured, - modify them to include only the pg_catalog - schema in their search_path settings. - Autovacuum worker processes now do the same, as well. - - - - In cases where user-provided functions are indirectly executed by - these programs — for example, user-provided functions in index - expressions — the tighter search_path may - result in errors, which will need to be corrected by adjusting those - user-provided functions to not assume anything about what search path - they are invoked under. That has always been good practice, but now - it will be necessary for correct behavior. - (CVE-2018-1058) - - - - - - - Prevent logical replication from trying to ship changes for - unpublishable relations (Peter Eisentraut) - - - - A publication marked FOR ALL TABLES would - incorrectly ship changes in materialized views - and information_schema tables, which are - supposed to be omitted from the change stream. - - - - - - - Fix misbehavior of concurrent-update rechecks with CTE references - appearing in subplans (Tom Lane) - - - - If a CTE (WITH clause reference) is used in an - InitPlan or SubPlan, and the query requires a recheck due to trying - to update or lock a concurrently-updated row, incorrect results could - be obtained. - - - - - - - Fix planner failures with overlapping mergejoin clauses in an outer - join (Tom Lane) - - - - These mistakes led to left and right pathkeys do not match in - mergejoin or outer pathkeys do not match - mergeclauses planner errors in corner cases. - - - - - - - Repair pg_upgrade's failure to - preserve relfrozenxid for materialized - views (Tom Lane, Andres Freund) - - - - This oversight could lead to data corruption in materialized views - after an upgrade, manifesting as could not access status of - transaction or found xmin from before - relfrozenxid errors. The problem would be more likely to - occur in seldom-refreshed materialized views, or ones that were - maintained only with REFRESH MATERIALIZED VIEW - CONCURRENTLY. - - - - If such corruption is observed, it can be repaired by refreshing the - materialized view (without CONCURRENTLY). - - - - - - - Fix incorrect pg_dump output for some - non-default sequence limit values (Alexey Bashtanov) - - - - - - - Fix pg_dump's mishandling - of STATISTICS objects (Tom Lane) - - - - An extended statistics object's schema was mislabeled in the dump's - table of contents, possibly leading to the wrong results in a - schema-selective restore. Its ownership was not correctly restored, - either. Also, change the logic so that statistics objects are - dumped/restored, or not, as independent objects rather than tying - them to the dump/restore decision for the table they are on. The - original definition could not scale to the planned future extension to - cross-table statistics. - - - - - - - Fix incorrect reporting of PL/Python function names in - error CONTEXT stacks (Tom Lane) - - - - An error occurring within a nested PL/Python function call (that is, - one reached via a SPI query from another PL/Python function) would - result in a stack trace showing the inner function's name twice, - rather than the expected results. Also, an error in a nested - PL/Python DO block could result in a null pointer - dereference crash on some platforms. - - - - - - - Allow contrib/auto_explain's - log_min_duration setting to range up - to INT_MAX, or about 24 days instead of 35 minutes - (Tom Lane) - - - - - - - Mark assorted GUC variables as PGDLLIMPORT, to - ease porting extension modules to Windows (Metin Doslu) - - - - - - - - - - Release 10.2 - - - Release date: - 2018-02-08 - - - - This release contains a variety of fixes from 10.1. - For information about new features in major release 10, see - . - - - - Migration to Version 10.2 - - - A dump/restore is not required for those running 10.X. - - - - However, - if you use contrib/cube's ~> - operator, see the entry below about that. - - - - Also, if you are upgrading from a version earlier than 10.1, - see . - - - - - Changes - - - - - - - Fix processing of partition keys containing multiple expressions - (Álvaro Herrera, David Rowley) - - - - This error led to crashes or, with carefully crafted input, disclosure - of arbitrary backend memory. - (CVE-2018-1052) - - - - - - - Ensure that all temporary files made - by pg_upgrade are non-world-readable - (Tom Lane, Noah Misch) - - - - pg_upgrade normally restricts its - temporary files to be readable and writable only by the calling user. - But the temporary file containing pg_dumpall -g - output would be group- or world-readable, or even writable, if the - user's umask setting allows. In typical usage on - multi-user machines, the umask and/or the working - directory's permissions would be tight enough to prevent problems; - but there may be people using pg_upgrade - in scenarios where this oversight would permit disclosure of database - passwords to unfriendly eyes. - (CVE-2018-1053) - - - - - - - Fix vacuuming of tuples that were updated while key-share locked - (Andres Freund, Álvaro Herrera) - - - - In some cases VACUUM would fail to remove such - tuples even though they are now dead, leading to assorted data - corruption scenarios. - - - - - - - Fix failure to mark a hash index's metapage dirty after - adding a new overflow page, potentially leading to index corruption - (Lixian Zou, Amit Kapila) - - - - - - - Ensure that vacuum will always clean up the pending-insertions list of - a GIN index (Masahiko Sawada) - - - - This is necessary to ensure that dead index entries get removed. - The old code got it backwards, allowing vacuum to skip the cleanup if - some other process were running cleanup concurrently, thus risking - invalid entries being left behind in the index. - - - - - - - Fix inadequate buffer locking in some LSN fetches (Jacob Champion, - Asim Praveen, Ashwin Agrawal) - - - - These errors could result in misbehavior under concurrent load. - The potential consequences have not been characterized fully. - - - - - - - Fix incorrect query results from cases involving flattening of - subqueries whose outputs are used in GROUPING SETS - (Heikki Linnakangas) - - - - - - - Fix handling of list partitioning constraints for partition keys of - boolean or array types (Amit Langote) - - - - - - - Avoid unnecessary failure in a query on an inheritance tree that - occurs concurrently with some child table being removed from the tree - by ALTER TABLE NO INHERIT (Tom Lane) - - - - - - - Fix spurious deadlock failures when multiple sessions are - running CREATE INDEX CONCURRENTLY (Jeff Janes) - - - - - - - During VACUUM FULL, update the table's size fields - in pg_class sooner (Amit Kapila) - - - - This prevents poor behavior when rebuilding hash indexes on the - table, since those use the pg_class - statistics to govern the initial hash size. - - - - - - - Fix - UNION/INTERSECT/EXCEPT - over zero columns (Tom Lane) - - - - - - - Disallow identity columns on typed tables and partitions - (Michael Paquier) - - - - These cases will be treated as unsupported features for now. - - - - - - - Fix assorted failures to apply the correct default value when - inserting into an identity column (Michael Paquier, Peter Eisentraut) - - - - In several contexts, notably COPY - and ALTER TABLE ADD COLUMN, the expected default - value was not applied and instead a null value was inserted. - - - - - - - Fix failures when an inheritance tree contains foreign child tables - (Etsuro Fujita) - - - - A mix of regular and foreign tables in an inheritance tree resulted in - creation of incorrect plans for UPDATE - and DELETE queries. This led to visible failures in - some cases, notably when there are row-level triggers on a foreign - child table. - - - - - - - Repair failure with correlated sub-SELECT - inside VALUES inside a LATERAL - subquery (Tom Lane) - - - - - - - Fix could not devise a query plan for the given query - planner failure for some cases involving nested UNION - ALL inside a lateral subquery (Tom Lane) - - - - - - - Allow functional dependency statistics to be used for boolean columns - (Tom Lane) - - - - Previously, although extended statistics could be declared and - collected on boolean columns, the planner failed to apply them. - - - - - - - Avoid underestimating the number of groups emitted by subqueries - containing set-returning functions in their grouping columns (Tom Lane) - - - - Cases similar to SELECT DISTINCT unnest(foo) got a - lower output rowcount estimate in 10.0 than they did in earlier - releases, possibly resulting in unfavorable plan choices. Restore the - prior estimation behavior. - - - - - - - Fix use of triggers in logical replication workers (Petr Jelinek) - - - - - - - Fix logical decoding to correctly clean up disk files for crashed - transactions (Atsushi Torikoshi) - - - - Logical decoding may spill WAL records to disk for transactions - generating many WAL records. Normally these files are cleaned up - after the transaction's commit or abort record arrives; but if - no such record is ever seen, the removal code misbehaved. - - - - - - - Fix walsender timeout failure and failure to respond to interrupts - when processing a large transaction (Petr Jelinek) - - - - - - - Fix race condition during replication origin drop that could allow the - dropping process to wait indefinitely (Tom Lane) - - - - - - - Allow members of the pg_read_all_stats role to see - walsender statistics in the pg_stat_replication - view (Feike Steenbergen) - - - - - - - Show walsenders that are sending base backups as active in - the pg_stat_activity view (Magnus Hagander) - - - - - - - Fix reporting of scram-sha-256 authentication - method in the pg_hba_file_rules view - (Michael Paquier) - - - - Previously this was printed as scram-sha256, - possibly confusing users as to the correct spelling. - - - - - - - Fix has_sequence_privilege() to - support WITH GRANT OPTION tests, - as other privilege-testing functions do (Joe Conway) - - - - - - - In databases using UTF8 encoding, ignore any XML declaration that - asserts a different encoding (Pavel Stehule, Noah Misch) - - - - We always store XML strings in the database encoding, so allowing - libxml to act on a declaration of another encoding gave wrong results. - In encodings other than UTF8, we don't promise to support non-ASCII - XML data anyway, so retain the previous behavior for bug compatibility. - This change affects only xpath() and related - functions; other XML code paths already acted this way. - - - - - - - Provide for forward compatibility with future minor protocol versions - (Robert Haas, Badrul Chowdhury) - - - - Up to now, PostgreSQL servers simply - rejected requests to use protocol versions newer than 3.0, so that - there was no functional difference between the major and minor parts - of the protocol version number. Allow clients to request versions 3.x - without failing, sending back a message showing that the server only - understands 3.0. This makes no difference at the moment, but - back-patching this change should allow speedier introduction of future - minor protocol upgrades. - - - - - - - Allow a client that supports SCRAM channel binding (such as v11 or - later libpq) to connect to a v10 server - (Michael Paquier) - - - - v10 does not have this feature, and the connection-time negotiation - about whether to use it was done incorrectly. - - - - - - - Avoid live-lock in ConditionVariableBroadcast() - (Tom Lane, Thomas Munro) - - - - Given repeatedly-unlucky timing, a process attempting to awaken all - waiters for a condition variable could loop indefinitely. Due to the - limited usage of condition variables in v10, this affects only - parallel index scans and some operations on replication slots. - - - - - - - Clean up waits for condition variables correctly during subtransaction - abort (Robert Haas) - - - - - - - Ensure that child processes that are waiting for a condition variable - will exit promptly if the postmaster process dies (Tom Lane) - - - - - - - Fix crashes in parallel queries using more than one Gather node - (Thomas Munro) - - - - - - - Fix hang in parallel index scan when processing a deleted or half-dead - index page (Amit Kapila) - - - - - - - Avoid crash if parallel bitmap heap scan is unable to allocate a - shared memory segment (Robert Haas) - - - - - - - Cope with failure to start a parallel worker process - (Amit Kapila, Robert Haas) - - - - Parallel query previously tended to hang indefinitely if a worker - could not be started, as the result of fork() - failure or other low-probability problems. - - - - - - - Avoid unnecessary failure when no parallel workers can be obtained - during parallel query startup (Robert Haas) - - - - - - - Fix collection of EXPLAIN statistics from parallel - workers (Amit Kapila, Thomas Munro) - - - - - - - Ensure that query strings passed to parallel workers are correctly - null-terminated (Thomas Munro) - - - - This prevents emitting garbage in postmaster log output from such - workers. - - - - - - - Avoid unsafe alignment assumptions when working - with __int128 (Tom Lane) - - - - Typically, compilers assume that __int128 variables are - aligned on 16-byte boundaries, but our memory allocation - infrastructure isn't prepared to guarantee that, and increasing the - setting of MAXALIGN seems infeasible for multiple reasons. Adjust the - code to allow use of __int128 only when we can tell the - compiler to assume lesser alignment. The only known symptom of this - problem so far is crashes in some parallel aggregation queries. - - - - - - - Prevent stack-overflow crashes when planning extremely deeply - nested set operations - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - - Avoid crash during an EvalPlanQual recheck of an indexscan that is the - inner child of a merge join (Tom Lane) - - - - This could only happen during an update or SELECT FOR - UPDATE of a join, when there is a concurrent update of some - selected row. - - - - - - - Fix crash in autovacuum when extended statistics are defined - for a table but can't be computed (Álvaro Herrera) - - - - - - - Fix null-pointer crashes for some types of LDAP URLs appearing - in pg_hba.conf (Thomas Munro) - - - - - - - Prevent out-of-memory failures due to excessive growth of simple hash - tables (Tomas Vondra, Andres Freund) - - - - - - - Fix sample INSTR() functions in the PL/pgSQL - documentation (Yugo Nagata, Tom Lane) - - - - These functions are stated to - be Oracle compatible, but - they weren't exactly. In particular, there was a discrepancy in the - interpretation of a negative third parameter: Oracle thinks that a - negative value indicates the last place where the target substring can - begin, whereas our functions took it as the last place where the - target can end. Also, Oracle throws an error for a zero or negative - fourth parameter, whereas our functions returned zero. - - - - The sample code has been adjusted to match Oracle's behavior more - precisely. Users who have copied this code into their applications - may wish to update their copies. - - - - - - - Fix pg_dump to make ACL (permissions), - comment, and security label entries reliably identifiable in archive - output formats (Tom Lane) - - - - The tag portion of an ACL archive entry was usually - just the name of the associated object. Make it start with the object - type instead, bringing ACLs into line with the convention already used - for comment and security label archive entries. Also, fix the - comment and security label entries for the whole database, if present, - to make their tags start with DATABASE so that they - also follow this convention. This prevents false matches in code that - tries to identify large-object-related entries by seeing if the tag - starts with LARGE OBJECT. That could have resulted - in misclassifying entries as data rather than schema, with undesirable - results in a schema-only or data-only dump. - - - - Note that this change has user-visible results in the output - of pg_restore --list. - - - - - - - Rename pg_rewind's - copy_file_range function to avoid conflict - with new Linux system call of that name (Andres Freund) - - - - This change prevents build failures with newer glibc versions. - - - - - - - In ecpg, detect indicator arrays that do - not have the correct length and report an error (David Rader) - - - - - - - Change the behavior of contrib/cube's - cube ~> int - operator to make it compatible with KNN search (Alexander Korotkov) - - - - The meaning of the second argument (the dimension selector) has been - changed to make it predictable which value is selected even when - dealing with cubes of varying dimensionalities. - - - - This is an incompatible change, but since the point of the operator - was to be used in KNN searches, it seems rather useless as-is. - After installing this update, any expression indexes or materialized - views using this operator will need to be reindexed/refreshed. - - - - - - - Avoid triggering a libc assertion - in contrib/hstore, due to use - of memcpy() with equal source and destination - pointers (Tomas Vondra) - - - - - - - Fix incorrect display of tuples' null bitmaps - in contrib/pageinspect (Maksim Milyutin) - - - - - - - Fix incorrect output from contrib/pageinspect's - hash_page_items() function (Masahiko Sawada) - - - - - - - In contrib/postgres_fdw, avoid - outer pathkeys do not match mergeclauses - planner error when constructing a plan involving a remote join - (Robert Haas) - - - - - - - In contrib/postgres_fdw, avoid planner failure - when there are duplicate GROUP BY entries - (Jeevan Chalke) - - - - - - - Provide modern examples of how to auto-start Postgres on macOS - (Tom Lane) - - - - The scripts in contrib/start-scripts/osx use - infrastructure that's been deprecated for over a decade, and which no - longer works at all in macOS releases of the last couple of years. - Add a new subdirectory contrib/start-scripts/macos - containing scripts that use the newer launchd - infrastructure. - - - - - - - Fix incorrect selection of configuration-specific libraries for - OpenSSL on Windows (Andrew Dunstan) - - - - - - - Support linking to MinGW-built versions of libperl (Noah Misch) - - - - This allows building PL/Perl with some common Perl distributions for - Windows. - - - - - - - Fix MSVC build to test whether 32-bit libperl - needs -D_USE_32BIT_TIME_T (Noah Misch) - - - - Available Perl distributions are inconsistent about what they expect, - and lack any reliable means of reporting it, so resort to a build-time - test on what the library being used actually does. - - - - - - - On Windows, install the crash dump handler earlier in postmaster - startup (Takayuki Tsunakawa) - - - - This may allow collection of a core dump for some early-startup - failures that did not produce a dump before. - - - - - - - On Windows, avoid encoding-conversion-related crashes when emitting - messages very early in postmaster startup (Takayuki Tsunakawa) - - - - - - - Use our existing Motorola 68K spinlock code on OpenBSD as - well as NetBSD (David Carlier) - - - - - - - Add support for spinlocks on Motorola 88K (David Carlier) - - - - - - - Update time zone data files to tzdata - release 2018c for DST law changes in Brazil, Sao Tome and Principe, - plus historical corrections for Bolivia, Japan, and South Sudan. - The US/Pacific-New zone has been removed (it was - only an alias for America/Los_Angeles anyway). - - - - - - - - - - Release 10.1 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 10.0. - For information about new features in major release 10, see - . - - - - Migration to Version 10.1 - - - A dump/restore is not required for those running 10.X. - - - - However, if you use BRIN indexes, see the fourth changelog entry below. - - - - - Changes - - - - - - - Ensure that INSERT ... ON CONFLICT DO UPDATE checks - table permissions and RLS policies in all cases (Dean Rasheed) - - - - The update path of INSERT ... ON CONFLICT DO UPDATE - requires SELECT permission on the columns of the - arbiter index, but it failed to check for that in the case of an - arbiter specified by constraint name. - In addition, for a table with row level security enabled, it failed to - check updated rows against the table's SELECT - policies (regardless of how the arbiter index was specified). - (CVE-2017-15099) - - - - - - - Fix crash due to rowtype mismatch - in json{b}_populate_recordset() - (Michael Paquier, Tom Lane) - - - - These functions used the result rowtype specified in the FROM - ... AS clause without checking that it matched the actual - rowtype of the supplied tuple value. If it didn't, that would usually - result in a crash, though disclosure of server memory contents seems - possible as well. - (CVE-2017-15098) - - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - - Fix BRIN index summarization to handle concurrent table extension - correctly (Álvaro Herrera) - - - - Previously, a race condition allowed some table rows to be omitted from - the index. It may be necessary to reindex existing BRIN indexes to - recover from past occurrences of this problem. - - - - - - - Fix possible failures during concurrent updates of a BRIN index - (Tom Lane) - - - - These race conditions could result in errors like invalid index - offnum or inconsistent range map. - - - - - - - Prevent logical replication from setting non-replicated columns to - nulls when replicating an UPDATE (Petr Jelinek) - - - - - - - Fix logical replication to fire BEFORE ROW DELETE - triggers when expected (Masahiko Sawada) - - - - Previously, that failed to happen unless the table also had - a BEFORE ROW UPDATE trigger. - - - - - - - Fix crash when logical decoding is invoked from a SPI-using function, - in particular any function written in a PL language - (Tom Lane) - - - - - - - Ignore CTEs when looking up the target table for - INSERT/UPDATE/DELETE, - and prevent matching schema-qualified target table names to trigger - transition table names (Thomas Munro) - - - - This restores the pre-v10 behavior for CTEs attached to DML commands. - - - - - - - Avoid evaluating an aggregate function's argument expression(s) at rows - where its FILTER test fails (Tom Lane) - - - - This restores the pre-v10 (and SQL-standard) behavior. - - - - - - - Fix incorrect query results when multiple GROUPING - SETS columns contain the same simple variable (Tom Lane) - - - - - - - Fix query-lifespan memory leakage while evaluating a set-returning - function in a SELECT's target list (Tom Lane) - - - - - - - Allow parallel execution of prepared statements with generic plans - (Amit Kapila, Kuntal Ghosh) - - - - - - - Fix incorrect parallelization decisions for nested queries - (Amit Kapila, Kuntal Ghosh) - - - - - - - Fix parallel query handling to not fail when a recently-used role is - dropped (Amit Kapila) - - - - - - - Fix crash in parallel execution of a bitmap scan having a BitmapAnd - plan node below a BitmapOr node (Dilip Kumar) - - - - - - - Fix json_build_array(), - json_build_object(), and their jsonb - equivalents to handle explicit VARIADIC arguments - correctly (Michael Paquier) - - - - - - - Fix autovacuum's work item logic to prevent possible - crashes and silent loss of work items (Álvaro Herrera) - - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - - Correctly ignore RelabelType expression nodes - when examining functional-dependency statistics (David Rowley) - - - - This allows, e.g., extended statistics on varchar columns - to be used properly. - - - - - - - Prevent sharing transition states between ordered-set aggregates - (David Rowley) - - - - This causes a crash with the built-in ordered-set aggregates, and - probably with user-written ones as well. v11 and later will include - provisions for dealing with such cases safely, but in released - branches, just disable the optimization. - - - - - - - Prevent idle_in_transaction_session_timeout from - being ignored when a statement_timeout occurred - earlier (Lukas Fittl) - - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - - Reduce the frequency of data flush requests during bulk file copies to - avoid performance problems on macOS, particularly with its new APFS - file system (Tom Lane) - - - - - - - Allow COPY's FREEZE option to - work when the transaction isolation level is REPEATABLE - READ or higher (Noah Misch) - - - - This case was unintentionally broken by a previous bug fix. - - - - - - - Fix AggGetAggref() to return the - correct Aggref nodes to aggregate final - functions whose transition calculations have been merged (Tom Lane) - - - - - - - Fix insufficient schema-qualification in some new queries - in pg_dump - and psql - (Vitaly Burovoy, Tom Lane, Noah Misch) - - - - - - - Avoid use of @> operator - in psql's queries for \d - (Tom Lane) - - - - This prevents problems when the parray_gin - extension is installed, since that defines a conflicting operator. - - - - - - - Fix pg_basebackup's matching of tablespace - paths to canonicalize both paths before comparing (Michael Paquier) - - - - This is particularly helpful on Windows. - - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - - In ecpglib, correctly handle backslashes in string literals depending - on whether standard_conforming_strings is set - (Tsunakawa Takayuki) - - - - - - - Make ecpglib's Informix-compatibility mode ignore fractional digits in - integer input strings, as expected (Gao Zengqi, Michael Meskes) - - - - - - - Fix missing temp-install prerequisites - for check-like Make targets (Noah Misch) - - - - Some non-default test procedures that are meant to work - like make check failed to ensure that the temporary - installation was up to date. - - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - In the documentation, restore HTML anchors to being upper-case strings - (Peter Eisentraut) - - - - Due to a toolchain change, the 10.0 user manual had lower-case strings - for intrapage anchors, thus breaking some external links into our - website documentation. Return to our previous convention of using - upper-case strings. - - - - - - - - - - Release 10 - - - Release date: - 2017-10-05 - - - - Overview - - - Major enhancements in PostgreSQL 10 include: - - - - - - - Logical replication using publish/subscribe - Declarative table partitioning - Improved query parallelism - Significant general performance improvements - Stronger password authentication based on SCRAM-SHA-256 - Improved monitoring and control - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 10 - - - A dump/restore using , or use of , is required for those wishing to migrate data - from any previous release. - - - - Version 10 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - - - - - Hash indexes must be rebuilt after pg_upgrade-ing - from any previous major PostgreSQL version (Mithun - Cy, Robert Haas, Amit Kapila) - - - - Major hash index improvements necessitated this requirement. - pg_upgrade will create a script to assist with this. - - - - - - - Rename write-ahead log directory pg_xlog - to pg_wal, and rename transaction - status directory pg_clog to pg_xact - (Michael Paquier) - - - - Users have occasionally thought that these directories contained only - inessential log files, and proceeded to remove write-ahead log files - or transaction status files manually, causing irrecoverable data - loss. These name changes are intended to discourage such errors in - future. - - - - - - - Rename SQL functions, tools, and options that reference - xlog to wal (Robert Haas) - - - - For example, pg_switch_xlog() becomes - pg_switch_wal(), pg_receivexlog - becomes pg_receivewal, and - becomes . This is for consistency with the - change of the pg_xlog directory name; in general, - the xlog terminology is no longer used in any user-facing - places. - - - - - - - Rename WAL-related functions and views to use lsn - instead of location (David Rowley) - - - - There was previously an inconsistent mixture of the two terminologies. - - - - - - - Change the implementation of set-returning functions appearing in - a query's SELECT list (Andres Freund) - - - - Set-returning functions are now evaluated before evaluation of scalar - expressions in the SELECT list, much as though they had - been placed in a LATERAL FROM-clause item. This allows - saner semantics for cases where multiple set-returning functions are - present. If they return different numbers of rows, the shorter results - are extended to match the longest result by adding nulls. Previously - the results were cycled until they all terminated at the same time, - producing a number of rows equal to the least common multiple of the - functions' periods. In addition, set-returning functions are now - disallowed within CASE and COALESCE constructs. - For more information - see . - - - - - - - Use standard row constructor syntax in UPDATE ... SET - (column_list) = row_constructor - (Tom Lane) - - - - The row_constructor can now begin with the - keyword ROW; previously that had to be omitted. - If just one column name appears in - the column_list, then - the row_constructor now must use - the ROW keyword, since otherwise it is not a valid - row constructor but just a parenthesized expression. - Also, an occurrence - of table_name.* within - the row_constructor is now expanded into - multiple columns, as occurs in other uses - of row_constructors. - - - - - - - When ALTER TABLE ... ADD PRIMARY KEY marks - columns NOT NULL, that change now propagates to - inheritance child tables as well (Michael Paquier) - - - - - - - Prevent statement-level triggers from firing more than once per - statement (Tom Lane) - - - - Cases involving writable CTEs updating the same table updated by the - containing statement, or by another writable CTE, fired BEFORE - STATEMENT or AFTER STATEMENT triggers more than once. - Also, if there were statement-level triggers on a table affected by a - foreign key enforcement action (such as ON DELETE CASCADE), - they could fire more than once per outer SQL statement. This is - contrary to the SQL standard, so change it. - - - - - - - Move sequences' metadata fields into a new pg_sequence - system catalog (Peter Eisentraut) - - - - A sequence relation now stores only the fields that can be modified - by nextval(), that - is last_value, log_cnt, - and is_called. Other sequence properties, such as - the starting value and increment, are kept in a corresponding row of - the pg_sequence catalog. - ALTER SEQUENCE updates are now fully transactional, - implying that the sequence is locked until commit. - The nextval() and setval() functions - remain nontransactional. - - - - The main incompatibility introduced by this change is that selecting - from a sequence relation now returns only the three fields named - above. To obtain the sequence's other properties, applications must - look into pg_sequence. The new system - view pg_sequences - can also be used for this purpose; it provides column names that are - more compatible with existing code. - - - - The output of psql's \d command for a - sequence has been redesigned, too. - - - - - - - Make stream the - WAL needed to restore the backup by default (Magnus - Hagander) - - - - This changes pg_basebackup's - / default to stream. - An option value none has been added to reproduce the old - behavior. The pg_basebackup option - has been removed (instead, use -X fetch). - - - - - - - Change how logical replication - uses pg_hba.conf - (Peter Eisentraut) - - - - In previous releases, a logical replication connection required - the replication keyword in the database column. As - of this release, logical replication matches a normal entry with a - database name or keywords such as all. Physical - replication continues to use the replication keyword. - Since built-in logical replication is new in this release, this - change only affects users of third-party logical replication plugins. - - - - - - - Make all actions wait - for completion by default (Peter Eisentraut) - - - - Previously some pg_ctl actions didn't wait for - completion, and required the use of to do so. - - - - - - - Change the default value of the - server parameter from pg_log to log - (Andreas Karlsson) - - - - - - - Add configuration option to - specify file name for custom OpenSSL DH parameters (Heikki Linnakangas) - - - - This replaces the hardcoded, undocumented file - name dh1024.pem. Note that dh1024.pem is - no longer examined by default; you must set this option if you want - to use custom DH parameters. - - - - - - - Increase the size of the default DH parameters used for OpenSSL - ephemeral DH ciphers to 2048 bits (Heikki Linnakangas) - - - - The size of the compiled-in DH parameters has been increased from - 1024 to 2048 bits, making DH key exchange more resistant to - brute-force attacks. However, some old SSL implementations, notably - some revisions of Java Runtime Environment version 6, will not accept - DH parameters longer than 1024 bits, and hence will not be able to - connect over SSL. If it's necessary to support such old clients, you - can use custom 1024-bit DH parameters instead of the compiled-in - defaults. See . - - - - - - - Remove the ability to store unencrypted passwords on the server - (Heikki Linnakangas) - - - - The server parameter - no longer supports off or plain. - The UNENCRYPTED option is no longer supported in - CREATE/ALTER USER ... PASSWORD. Similarly, the - option has been removed - from createuser. Unencrypted passwords migrated from - older versions will be stored encrypted in this release. The default - setting for password_encryption is still - md5. - - - - - - - Add - and server - parameters to control parallel queries (Amit Kapila, Robert Haas) - - - - These replace min_parallel_relation_size, which was - found to be too generic. - - - - - - - Don't downcase unquoted text - within and related - server parameters (QL Zhuo) - - - - These settings are really lists of file names, but they were - previously treated as lists of SQL identifiers, which have different - parsing rules. - - - - - - - Remove sql_inheritance server parameter (Robert Haas) - - - - Changing this setting from the default value caused queries referencing - parent tables to not include child tables. The SQL - standard requires them to be included, however, and this has been the - default since PostgreSQL 7.1. - - - - - - - Allow multi-dimensional arrays to be passed into PL/Python functions, - and returned as nested Python lists (Alexey Grishchenko, Dave Cramer, - Heikki Linnakangas) - - - - This feature requires a backwards-incompatible change to the handling - of arrays of composite types in PL/Python. Previously, you could - return an array of composite values by writing, e.g., [[col1, - col2], [col1, col2]]; but now that is interpreted as a - two-dimensional array. Composite types in arrays must now be written - as Python tuples, not lists, to resolve the ambiguity; that is, - write [(col1, col2), (col1, col2)] instead. - - - - - - - Remove PL/Tcl's module auto-loading facility (Tom Lane) - - - - This functionality has been replaced by new server - parameters - and , which are easier to use - and more similar to features available in other PLs. - - - - - - - Remove pg_dump/pg_dumpall support - for dumping from pre-8.0 servers (Tom Lane) - - - - Users needing to dump from pre-8.0 servers will need to use dump - programs from PostgreSQL 9.6 or earlier. The - resulting output should still load successfully into newer servers. - - - - - - - Remove support for floating-point timestamps and intervals (Tom Lane) - - - - This removes configure's - option. Floating-point timestamps have few advantages and have not - been the default since PostgreSQL 8.3. - - - - - - - Remove server support for client/server protocol version 1.0 (Tom Lane) - - - - This protocol hasn't had client support - since PostgreSQL 6.3. - - - - - - - Remove contrib/tsearch2 module (Robert Haas) - - - - This module provided compatibility with the version of full text - search that shipped in pre-8.3 PostgreSQL releases. - - - - - - - Remove createlang and droplang - command-line applications (Peter Eisentraut) - - - - These had been deprecated since PostgreSQL 9.1. - Instead, use CREATE EXTENSION and DROP - EXTENSION directly. - - - - - - - Remove support for version-0 function calling conventions (Andres - Freund) - - - - Extensions providing C-coded functions must now conform to version 1 - calling conventions. Version 0 has been deprecated since 2001. - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 10 and the previous major - release. - - - - Server - - - Parallel Queries - - - - - - - Support parallel B-tree index scans (Rahila Syed, Amit Kapila, - Robert Haas, Rafia Sabih) - - - - This change allows B-tree index pages to be searched by separate - parallel workers. - - - - - - - Support parallel bitmap heap scans (Dilip Kumar) - - - - This allows a single index scan to dispatch parallel workers to - process different areas of the heap. - - - - - - - Allow merge joins to be performed in parallel (Dilip Kumar) - - - - - - - Allow non-correlated subqueries to be run in parallel (Amit Kapila) - - - - - - - Improve ability of parallel workers to return pre-sorted data - (Rushabh Lathia) - - - - - - - Increase parallel query usage in procedural language functions - (Robert Haas, Rafia Sabih) - - - - - - - Add server parameter - to limit the number of worker processes that can be used for - query parallelism (Julien Rouhaud) - - - - This parameter can be set lower than to reserve worker processes - for purposes other than parallel queries. - - - - - - - - - Indexes - - - - - - - Add write-ahead logging support to hash indexes (Amit Kapila) - - - - This makes hash indexes crash-safe and replicatable. - The former warning message about their use is removed. - - - - - - - Improve hash index performance (Amit Kapila, Mithun Cy, Ashutosh - Sharma) - - - - - - - Add SP-GiST index support for INET and - CIDR data types (Emre Hasegeli) - - - - - - - Add option to allow BRIN index summarization to happen - more aggressively (Álvaro Herrera) - - - - A new CREATE - INDEX option enables auto-summarization of the - previous BRIN page range when a new page - range is created. - - - - - - - Add functions to remove and re-add BRIN - summarization for BRIN index ranges (Álvaro - Herrera) - - - - The new SQL function brin_summarize_range() - updates BRIN index summarization for a specified - range and brin_desummarize_range() removes it. - This is helpful to update summarization of a range that is now - smaller due to UPDATEs and DELETEs. - - - - - - - Improve accuracy in determining if a BRIN index scan - is beneficial (David Rowley, Emre Hasegeli) - - - - - - - Allow faster GiST inserts and updates by reusing - index space more efficiently (Andrey Borodin) - - - - - - - Reduce page locking during vacuuming of GIN indexes - (Andrey Borodin) - - - - - - - - - - Locking - - - - - - - Reduce locking required to change table parameters (Simon Riggs, - Fabrízio Mello) - - - - For example, changing a table's setting can now be done - with a more lightweight lock. - - - - - - - Allow tuning of predicate lock promotion thresholds (Dagfinn - Ilmari Mannsåker) - - - - Lock promotion can now be controlled through two new server - parameters, and - . - - - - - - - - - Optimizer - - - - - - - Add multi-column optimizer statistics to compute the correlation - ratio and number of distinct values (Tomas Vondra, David Rowley, - Álvaro Herrera) - - - - New commands are CREATE STATISTICS, - ALTER STATISTICS, and - DROP STATISTICS. - This feature is helpful in estimating query memory usage and when - combining the statistics from individual columns. - - - - - - - Improve performance of queries affected by row-level security - restrictions (Tom Lane) - - - - The optimizer now has more knowledge about where it can place RLS - filter conditions, allowing better plans to be generated while still - enforcing the RLS conditions safely. - - - - - - - - - General Performance - - - - - - - Speed up aggregate functions that calculate a running sum - using numeric-type arithmetic, including some variants - of SUM(), AVG(), - and STDDEV() (Heikki Linnakangas) - - - - - - - Improve performance of character encoding conversions by - using radix trees (Kyotaro Horiguchi, Heikki Linnakangas) - - - - - - - Reduce expression evaluation overhead during query execution, - as well as plan node calling overhead (Andres Freund) - - - - This is particularly helpful for queries that process many rows. - - - - - - - Allow hashed aggregation to be used with grouping sets (Andrew - Gierth) - - - - - - - Use uniqueness guarantees to optimize certain join types (David - Rowley) - - - - - - - Improve sort performance of the macaddr data type (Brandur Leach) - - - - - - - Reduce statistics tracking overhead in sessions that reference - many thousands of relations (Aleksander Alekseev) - - - - - - - - - Monitoring - - - - - - - Allow explicit control - over EXPLAIN's display - of planning and execution time (Ashutosh Bapat) - - - - By default planning and execution time are displayed by - EXPLAIN ANALYZE and are not displayed in other cases. - The new EXPLAIN option SUMMARY allows - explicit control of this. - - - - - - - Add default monitoring roles (Dave Page) - - - - New roles pg_monitor, pg_read_all_settings, - pg_read_all_stats, and pg_stat_scan_tables - allow simplified permission configuration. - - - - - - - Properly update the statistics collector during REFRESH MATERIALIZED - VIEW (Jim Mlodgenski) - - - - - - - Logging - - - - - - - Change the default value of - to include current timestamp (with milliseconds) and the process ID - in each line of postmaster log output (Christoph Berg) - - - - The previous default was an empty prefix. - - - - - - - Add functions to return the log and WAL directory - contents (Dave Page) - - - - The new functions - are pg_ls_logdir() - and pg_ls_waldir() - and can be executed by non-superusers with the proper - permissions. - - - - - - - Add function pg_current_logfile() - to read logging collector's current stderr and csvlog output file names - (Gilles Darold) - - - - - - - Report the address and port number of each listening socket - in the server log during postmaster startup (Tom Lane) - - - - Also, when logging failure to bind a listening socket, include - the specific address we attempted to bind to. - - - - - - - Reduce log chatter about the starting and stopping of launcher - subprocesses (Tom Lane) - - - - These are now DEBUG1-level messages. - - - - - - - Reduce message verbosity of lower-numbered debug levels - controlled by - (Robert Haas) - - - - This also changes the verbosity of debug levels. - - - - - - - - - <link linkend="pg-stat-activity-view"><structname>pg_stat_activity</structname></link> - - - - - - - Add pg_stat_activity reporting of low-level wait - states (Michael Paquier, Robert Haas, Rushabh Lathia) - - - - This change enables reporting of numerous low-level wait conditions, - including latch waits, file reads/writes/fsyncs, client reads/writes, - and synchronous replication. - - - - - - - Show auxiliary processes, background workers, and walsender - processes in pg_stat_activity (Kuntal Ghosh, - Michael Paquier) - - - - This simplifies monitoring. A new - column backend_type identifies the process type. - - - - - - - Allow pg_stat_activity to show the SQL query - being executed by parallel workers (Rafia Sabih) - - - - - - - Rename - pg_stat_activity.wait_event_type - values LWLockTranche and - LWLockNamed to LWLock (Robert Haas) - - - - This makes the output more consistent. - - - - - - - - - - <acronym>Authentication</acronym> - - - - - - - Add SCRAM-SHA-256 - support for password negotiation and storage (Michael Paquier, - Heikki Linnakangas) - - - - This provides better security than the existing md5 - negotiation and storage method. - - - - - - - Change the server parameter - from boolean to enum (Michael Paquier) - - - - This was necessary to support additional password hashing options. - - - - - - - Add view pg_hba_file_rules - to display the contents of pg_hba.conf (Haribabu - Kommi) - - - - This shows the file contents, not the currently active settings. - - - - - - - Support multiple RADIUS servers (Magnus Hagander) - - - - All the RADIUS related parameters are now plural and - support a comma-separated list of servers. - - - - - - - - - Server Configuration - - - - - - - Allow SSL configuration to be updated during - configuration reload (Andreas Karlsson, Tom Lane) - - - - This allows SSL to be reconfigured without a server - restart, by using pg_ctl reload, SELECT - pg_reload_conf(), or sending a SIGHUP signal. - However, reloading the SSL configuration does not work - if the server's SSL key requires a passphrase, as there - is no way to re-prompt for the passphrase. The original - configuration will apply for the life of the postmaster in that - case. - - - - - - - Make the maximum value of effectively unlimited - (Jim Nasby) - - - - - - - - - Reliability - - - - - - - After creating or unlinking files, perform an fsync on their parent - directory (Michael Paquier) - - - - This reduces the risk of data loss after a power failure. - - - - - - - <link linkend="wal">Write-Ahead Log</link> (<acronym>WAL</acronym>) - - - - - - - Prevent unnecessary checkpoints and WAL archiving on - otherwise-idle systems (Michael Paquier) - - - - - - - Add server parameter - to add details to WAL that can be sanity-checked on - the standby (Kuntal Ghosh, Robert Haas) - - - - Any sanity-check failure generates a fatal error on the standby. - - - - - - - Increase the maximum configurable WAL segment size - to one gigabyte (Beena Emerson) - - - - A larger WAL segment size allows for fewer - invocations and fewer - WAL files to manage. - - - - - - - - - - - - - Replication and Recovery - - - - - - - Add the ability to logically - replicate tables to standby servers (Petr Jelinek) - - - - Logical replication allows more flexibility than physical - replication does, including replication between different major - versions of PostgreSQL and selective - replication. - - - - - - - Allow waiting for commit acknowledgement from standby - servers irrespective of the order they appear in (Masahiko Sawada) - - - - Previously the server always waited for the active standbys that - appeared first in synchronous_standby_names. The new - synchronous_standby_names keyword ANY allows - waiting for any number of standbys irrespective of their ordering. - This is known as quorum commit. - - - - - - - Reduce configuration changes necessary to perform streaming backup - and replication (Magnus Hagander, Dang Minh Huong) - - - - Specifically, the defaults were changed for , , - , and to make them suitable for these usages - out-of-the-box. - - - - - - - Enable replication from localhost connections by default in - pg_hba.conf - (Michael Paquier) - - - - Previously pg_hba.conf's replication connection - lines were commented out by default. This is particularly useful for - . - - - - - - - Add columns to pg_stat_replication - to report replication delay times (Thomas Munro) - - - - The new columns are write_lag, - flush_lag, and replay_lag. - - - - - - - Allow specification of the recovery stopping point by Log Sequence - Number (LSN) in - recovery.conf - (Michael Paquier) - - - - Previously the stopping point could only be selected by timestamp or - XID. - - - - - - - Allow users to disable pg_stop_backup()'s - waiting for all WAL to be archived (David Steele) - - - - An optional second argument to pg_stop_backup() - controls that behavior. - - - - - - - Allow creation of temporary replication slots - (Petr Jelinek) - - - - Temporary slots are automatically removed on session exit or error. - - - - - - - Improve performance of hot standby replay with better tracking of - Access Exclusive locks (Simon Riggs, David Rowley) - - - - - - - Speed up two-phase commit recovery performance (Stas Kelvich, - Nikhil Sontakke, Michael Paquier) - - - - - - - - - Queries - - - - - - - Add XMLTABLE - function that converts XML-formatted data into a row set - (Pavel Stehule, Álvaro Herrera) - - - - - - - Fix regular expressions' character class handling for large character - codes, particularly Unicode characters above U+7FF - (Tom Lane) - - - - Previously, such characters were never recognized as belonging to - locale-dependent character classes such as [[:alpha:]]. - - - - - - - - - Utility Commands - - - - - - - Add table partitioning - syntax that automatically creates partition constraints and - handles routing of tuple insertions and updates (Amit Langote) - - - - The syntax supports range and list partitioning. - - - - - - - Add AFTER trigger - transition tables to record changed rows (Kevin Grittner, Thomas - Munro) - - - - Transition tables are accessible from triggers written in - server-side languages. - - - - - - - Allow restrictive row-level - security policies (Stephen Frost) - - - - Previously all security policies were permissive, meaning that any - matching policy allowed access. A restrictive policy must - match for access to be granted. These policy types can be combined. - - - - - - - When creating a foreign-key constraint, check - for REFERENCES permission on only the referenced table - (Tom Lane) - - - - Previously REFERENCES permission on the referencing - table was also required. This appears to have stemmed from a - misreading of the SQL standard. Since creating a foreign key (or - any other type of) constraint requires ownership privilege on the - constrained table, additionally requiring REFERENCES - permission seems rather pointless. - - - - - - - Allow default - permissions on schemas (Matheus Oliveira) - - - - This is done using the ALTER DEFAULT PRIVILEGES command. - - - - - - - Add CREATE SEQUENCE - AS command to create a sequence matching an integer data type - (Peter Eisentraut) - - - - This simplifies the creation of sequences matching the range of - base columns. - - - - - - - Allow COPY view - FROM source on views with INSTEAD - INSERT triggers (Haribabu Kommi) - - - - The triggers are fed the data rows read by COPY. - - - - - - - Allow the specification of a function name without arguments in - DDL commands, if it is unique (Peter Eisentraut) - - - - For example, allow DROP - FUNCTION on a function name without arguments if there - is only one function with that name. This behavior is required by the - SQL standard. - - - - - - - Allow multiple functions, operators, and aggregates to be dropped - with a single DROP command (Peter Eisentraut) - - - - - - - Support IF NOT EXISTS - in CREATE SERVER, - CREATE USER MAPPING, - and CREATE COLLATION - (Anastasia Lubennikova, Peter Eisentraut) - - - - - - - Make VACUUM VERBOSE report - the number of skipped frozen pages and oldest xmin (Masahiko - Sawada, Simon Riggs) - - - - This information is also included in output. - - - - - - - Improve speed of VACUUM's removal of trailing empty - heap pages (Claudio Freire, Álvaro Herrera) - - - - - - - - - Data Types - - - - - - - Add full text search support for JSON and JSONB - (Dmitry Dolgov) - - - - The functions ts_headline() and - to_tsvector() can now be used on these data types. - - - - - - - Add support for EUI-64 MAC addresses, as a - new data type macaddr8 - (Haribabu Kommi) - - - - This complements the existing support - for EUI-48 MAC addresses - (type macaddr). - - - - - - - Add identity columns for - assigning a numeric value to columns on insert (Peter Eisentraut) - - - - These are similar to SERIAL columns, but are - SQL standard compliant. - - - - - - - Allow ENUM values to be - renamed (Dagfinn Ilmari Mannsåker) - - - - This uses the syntax ALTER - TYPE ... RENAME VALUE. - - - - - - - Properly treat array pseudotypes - (anyarray) as arrays in to_json() - and to_jsonb() (Andrew Dunstan) - - - - Previously columns declared as anyarray (particularly those - in the pg_stats view) were converted to JSON - strings rather than arrays. - - - - - - - Add operators for multiplication and division - of money values - with int8 values (Peter Eisentraut) - - - - Previously such cases would result in converting the int8 - values to float8 and then using - the money-and-float8 operators. The new behavior - avoids possible precision loss. But note that division - of money by int8 now truncates the quotient, like - other integer-division cases, while the previous behavior would have - rounded. - - - - - - - Check for overflow in the money type's input function - (Peter Eisentraut) - - - - - - - - - Functions - - - - - - - Add simplified regexp_match() - function (Emre Hasegeli) - - - - This is similar to regexp_matches(), but it only - returns results from the first match so it does not need to return a - set, making it easier to use for simple cases. - - - - - - - Add a version of jsonb's delete operator that takes - an array of keys to delete (Magnus Hagander) - - - - - - - Make json_populate_record() - and related functions process JSON arrays and objects recursively - (Nikita Glukhov) - - - - With this change, array-type fields in the destination SQL type are - properly converted from JSON arrays, and composite-type fields are - properly converted from JSON objects. Previously, such cases would - fail because the text representation of the JSON value would be fed - to array_in() or record_in(), and its - syntax would not match what those input functions expect. - - - - - - - Add function txid_current_if_assigned() - to return the current transaction ID or NULL if no - transaction ID has been assigned (Craig Ringer) - - - - This is different from txid_current(), - which always returns a transaction ID, assigning one if necessary. - Unlike that function, this function can be run on standby servers. - - - - - - - Add function txid_status() - to check if a transaction was committed (Craig Ringer) - - - - This is useful for checking after an abrupt disconnection whether - your previous transaction committed and you just didn't receive - the acknowledgement. - - - - - - - Allow make_date() - to interpret negative years as BC years (Álvaro - Herrera) - - - - - - - Make to_timestamp() - and to_date() reject - out-of-range input fields (Artur Zakirov) - - - - For example, - previously to_date('2009-06-40','YYYY-MM-DD') was - accepted and returned 2009-07-10. It will now generate - an error. - - - - - - - - - Server-Side Languages - - - - - - - Allow PL/Python's cursor() and execute() - functions to be called as methods of their plan-object arguments - (Peter Eisentraut) - - - - This allows a more object-oriented programming style. - - - - - - - Allow PL/pgSQL's GET DIAGNOSTICS statement to retrieve - values into array elements (Tom Lane) - - - - Previously, a syntactic restriction prevented the target variable - from being an array element. - - - - - - - <link linkend="pltcl">PL/Tcl</link> - - - - - - - Allow PL/Tcl functions to return composite types and sets - (Karl Lehenbauer) - - - - - - - Add a subtransaction command to PL/Tcl (Victor Wagner) - - - - This allows PL/Tcl queries to fail without aborting the entire - function. - - - - - - - Add server parameters - and , to allow initialization - functions to be called on PL/Tcl startup (Tom Lane) - - - - - - - - - - Client Interfaces - - - - - - - Allow specification of multiple - host names or addresses in libpq connection strings and URIs - (Robert Haas, Heikki Linnakangas) - - - - libpq will connect to the first responsive server in the list. - - - - - - - Allow libpq connection strings and URIs to request a read/write host, - that is a master server rather than a standby server - (Victor Wagner, Mithun Cy) - - - - This is useful when multiple host names are - specified. It is controlled by libpq connection parameter - . - - - - - - - Allow the password file name - to be specified as a libpq connection parameter (Julian Markwort) - - - - Previously this could only be specified via an environment variable. - - - - - - - Add function PQencryptPasswordConn() - to allow creation of more types of encrypted passwords on the - client side (Michael Paquier, Heikki Linnakangas) - - - - Previously only MD5-encrypted passwords could be created - using PQencryptPassword(). - This new function can also create SCRAM-SHA-256-encrypted - passwords. - - - - - - - Change ecpg preprocessor version from 4.12 to 10 - (Tom Lane) - - - - Henceforth the ecpg version will match - the PostgreSQL distribution version number. - - - - - - - - - Client Applications - - - <xref linkend="app-psql"/> - - - - - - - Add conditional branch support to psql (Corey - Huinker) - - - - This feature adds psql - meta-commands \if, \elif, \else, - and \endif. This is primarily helpful for scripting. - - - - - - - Add psql \gx meta-command to execute - (\g) a query in expanded mode (\x) - (Christoph Berg) - - - - - - - Expand psql variable references in - backtick-executed strings (Tom Lane) - - - - This is particularly useful in the new psql - conditional branch commands. - - - - - - - Prevent psql's special variables from being set to - invalid values (Daniel Vérité, Tom Lane) - - - - Previously, setting one of psql's special variables - to an invalid value silently resulted in the default behavior. - \set on a special variable now fails if the proposed - new value is invalid. As a special exception, \set - with an empty or omitted new value, on a boolean-valued special - variable, still has the effect of setting the variable - to on; but now it actually acquires that value rather - than an empty string. \unset on a special variable now - explicitly sets the variable to its default value, which is also - the value it acquires at startup. In sum, a control variable now - always has a displayable value that reflects - what psql is actually doing. - - - - - - - Add variables showing server version and psql version - (Fabien Coelho) - - - - - - - Improve psql's \d (display relation) - and \dD (display domain) commands to show collation, - nullable, and default properties in separate columns (Peter - Eisentraut) - - - - Previously they were shown in a single Modifiers column. - - - - - - - Make the various \d commands handle no-matching-object - cases more consistently (Daniel Gustafsson) - - - - They now all print the message about that to stderr, not stdout, - and the message wording is more consistent. - - - - - - - Improve psql's tab completion (Jeff Janes, - Ian Barwick, Andreas Karlsson, Sehrope Sarkuni, Thomas Munro, - Kevin Grittner, Dagfinn Ilmari Mannsåker) - - - - - - - - - <xref linkend="pgbench"/> - - - - - - - Add pgbench option to - control the log file prefix (Masahiko Sawada) - - - - - - - Allow pgbench's meta-commands to span multiple - lines (Fabien Coelho) - - - - A meta-command can now be continued onto the next line by writing - backslash-return. - - - - - - - Remove restriction on placement of option relative to - other command line options (Tom Lane) - - - - - - - - - - - Server Applications - - - - - - - Add pg_receivewal - option / to specify compression - (Michael Paquier) - - - - - - - Add pg_recvlogical option - to specify the ending position (Craig Ringer) - - - - This complements the existing option. - - - - - - - Rename initdb - options and to be spelled - and (Vik Fearing, - Peter Eisentraut) - - - - The old spellings are still supported. - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link>, - <link linkend="app-pg-dumpall"><application>pg_dumpall</application></link>, - <link linkend="app-pgrestore"><application>pg_restore</application></link> - - - - - - - Allow pg_restore to exclude schemas (Michael Banck) - - - - This adds a new / option. - - - - - - - Add option to - pg_dump (Guillaume Lelarge) - - - - This suppresses dumping of large objects. - - - - - - - Add pg_dumpall option - to omit role passwords - (Robins Tharakan, Simon Riggs) - - - - This allows use of pg_dumpall by non-superusers; - without this option, it fails due to inability to read passwords. - - - - - - - Support using synchronized snapshots when dumping from a standby - server (Petr Jelinek) - - - - - - - Issue fsync() on the output files generated by - pg_dump and - pg_dumpall (Michael Paquier) - - - - This provides more security that the output is safely stored on - disk before the program exits. This can be disabled with - the new option. - - - - - - - - - - <xref linkend="app-pgbasebackup"/> - - - - - - - Allow pg_basebackup to stream write-ahead log in - tar mode (Magnus Hagander) - - - - The WAL will be stored in a separate tar file from - the base backup. - - - - - - - Make pg_basebackup use temporary replication slots - (Magnus Hagander) - - - - Temporary replication slots will be used by default when - pg_basebackup uses WAL streaming with default - options. - - - - - - - Be more careful about fsync'ing in all required places - in pg_basebackup and - pg_receivewal (Michael Paquier) - - - - - - - Add pg_basebackup option to - disable fsync (Michael Paquier) - - - - - - - Improve pg_basebackup's handling of which - directories to skip (David Steele) - - - - - - - - - <application><xref linkend="app-pg-ctl"/></application> - - - - - - - Add wait option for 's - promote operation (Peter Eisentraut) - - - - - - - Add long options for pg_ctl wait () - and no-wait () (Vik Fearing) - - - - - - - Add long option for pg_ctl server options - () (Peter Eisentraut) - - - - - - - Make pg_ctl start --wait detect server-ready by - watching postmaster.pid, not by attempting connections - (Tom Lane) - - - - The postmaster has been changed to report its ready-for-connections - status in postmaster.pid, and pg_ctl - now examines that file to detect whether startup is complete. - This is more efficient and reliable than the old method, and it - eliminates postmaster log entries about rejected connection - attempts during startup. - - - - - - - Reduce pg_ctl's reaction time when waiting for - postmaster start/stop (Tom Lane) - - - - pg_ctl now probes ten times per second when waiting - for a postmaster state change, rather than once per second. - - - - - - - Ensure that pg_ctl exits with nonzero status if an - operation being waited for does not complete within the timeout - (Peter Eisentraut) - - - - The start and promote operations now return - exit status 1, not 0, in such cases. The stop operation - has always done that. - - - - - - - - - - Source Code - - - - - - - Change to two-part release version numbering (Peter Eisentraut, Tom - Lane) - - - - Release numbers will now have two parts (e.g., 10.1) - rather than three (e.g., 9.6.3). - Major versions will now increase just the first number, and minor - releases will increase just the second number. - Release branches will be referred to by single numbers - (e.g., 10 rather than 9.6). - This change is intended to reduce user confusion about what is a - major or minor release of PostgreSQL. - - - - - - - Improve behavior of pgindent - (Piotr Stefaniak, Tom Lane) - - - - We have switched to a new version of pg_bsd_indent - based on recent improvements made by the FreeBSD project. This - fixes numerous small bugs that led to odd C code formatting - decisions. Most notably, lines within parentheses (such as in a - multi-line function call) are now uniformly indented to match the - opening paren, even if that would result in code extending past the - right margin. - - - - - - - Allow the ICU library to - optionally be used for collation support (Peter Eisentraut) - - - - The ICU library has versioning that allows detection - of collation changes between versions. It is enabled via configure - option . The default still uses the operating - system's native collation library. - - - - - - - Automatically mark all PG_FUNCTION_INFO_V1 functions - as DLLEXPORT-ed on - Windows (Laurenz Albe) - - - - If third-party code is using extern function - declarations, they should also add DLLEXPORT markers - to those declarations. - - - - - - - Remove SPI functions SPI_push(), - SPI_pop(), SPI_push_conditional(), - SPI_pop_conditional(), - and SPI_restore_connection() as unnecessary (Tom Lane) - - - - Their functionality now happens automatically. There are now no-op - macros by these names so that external modules don't need to be - updated immediately, but eventually such calls should be removed. - - - - A side effect of this change is that SPI_palloc() and - allied functions now require an active SPI connection; they do not - degenerate to simple palloc() if there is none. That - previous behavior was not very useful and posed risks of unexpected - memory leaks. - - - - - - - Allow shared memory to be dynamically allocated (Thomas Munro, - Robert Haas) - - - - - - - Add slab-like memory allocator for efficient fixed-size allocations - (Tomas Vondra) - - - - - - - Use POSIX semaphores rather than SysV semaphores - on Linux and FreeBSD (Tom Lane) - - - - This avoids platform-specific limits on SysV semaphore usage. - - - - - - - Improve support for 64-bit atomics (Andres Freund) - - - - - - - Enable 64-bit atomic operations on ARM64 (Roman - Shaposhnik) - - - - - - - Switch to using clock_gettime(), if available, for - duration measurements (Tom Lane) - - - - gettimeofday() is still used - if clock_gettime() is not available. - - - - - - - Add more robust random number generators to be used for - cryptographically secure uses (Magnus Hagander, Michael Paquier, - Heikki Linnakangas) - - - - If no strong random number generator can be - found, configure will fail unless - the option is used. However, with - this option, pgcrypto - functions requiring a strong random number generator will be disabled. - - - - - - - Allow WaitLatchOrSocket() to wait for socket - connection on Windows (Andres Freund) - - - - - - - tupconvert.c functions no longer convert tuples just to - embed a different composite-type OID in them (Ashutosh Bapat, Tom Lane) - - - - The majority of callers don't care about the composite-type OID; - but if the result tuple is to be used as a composite Datum, steps - should be taken to make sure the correct OID is inserted in it. - - - - - - - Remove SCO and Unixware ports (Tom Lane) - - - - - - - Overhaul documentation build - process (Alexander Lakhin) - - - - - - - Use XSLT to build the PostgreSQL - documentation (Peter Eisentraut) - - - - Previously Jade, DSSSL, and - JadeTex were used. - - - - - - - Build HTML documentation using XSLT - stylesheets by default (Peter Eisentraut) - - - - - - - - - Additional Modules - - - - - - - Allow file_fdw to read - from program output as well as files (Corey Huinker, Adam Gomaa) - - - - - - - In postgres_fdw, - push aggregate functions to the remote server, when possible - (Jeevan Chalke, Ashutosh Bapat) - - - - This reduces the amount of data that must be passed from the remote - server, and offloads aggregate computation from the requesting server. - - - - - - - In postgres_fdw, push joins to the remote server in - more cases (David Rowley, Ashutosh Bapat, Etsuro Fujita) - - - - - - - Properly support OID columns in - postgres_fdw tables (Etsuro Fujita) - - - - Previously OID columns always returned zeros. - - - - - - - Allow btree_gist - and btree_gin to - index enum types (Andrew Dunstan) - - - - This allows enums to be used in exclusion constraints. - - - - - - - Add indexing support to btree_gist for the - UUID data type (Paul Jungwirth) - - - - - - - Add amcheck which can - check the validity of B-tree indexes (Peter Geoghegan) - - - - - - - Show ignored constants as $N rather than ? - in - pg_stat_statements - (Lukas Fittl) - - - - - - - Improve cube's handling - of zero-dimensional cubes (Tom Lane) - - - - This also improves handling of infinite and - NaN values. - - - - - - - Allow pg_buffercache to run - with fewer locks (Ivan Kartyshov) - - - - This makes it less disruptive when run on production systems. - - - - - - - Add pgstattuple - function pgstathashindex() to view hash index - statistics (Ashutosh Sharma) - - - - - - - Use GRANT permissions to - control pgstattuple function usage (Stephen Frost) - - - - This allows DBAs to allow non-superusers to run these functions. - - - - - - - Reduce locking when pgstattuple examines hash - indexes (Amit Kapila) - - - - - - - Add pageinspect - function page_checksum() to show a page's checksum - (Tomas Vondra) - - - - - - - Add pageinspect - function bt_page_items() to print page items from a - page image (Tomas Vondra) - - - - - - - Add hash index support to pageinspect (Jesper - Pedersen, Ashutosh Sharma) - - - - - - - - - - - Acknowledgments - - - The following individuals (in alphabetical order) have contributed to this - release as patch authors, committers, reviewers, testers, or reporters of - issues. - - - - Adam Brightwell - Adam Brusselback - Adam Gomaa - Adam Sah - Adrian Klaver - Aidan Van Dyk - Aleksander Alekseev - Alexander Korotkov - Alexander Lakhin - Alexander Sosna - Alexey Bashtanov - Alexey Grishchenko - Alexey Isayko - Álvaro Hernández Tortosa - Álvaro Herrera - Amit Kapila - Amit Khandekar - Amit Langote - Amul Sul - Anastasia Lubennikova - Andreas Joseph Krogh - Andreas Karlsson - Andreas Scherbaum - Andreas Seltenreich - Andres Freund - Andrew Dunstan - Andrew Gierth - Andrew Wheelwright - Andrey Borodin - Andrey Lizenko - Andy Abelisto - Antonin Houska - Ants Aasma - Arjen Nienhuis - Arseny Sher - Artur Zakirov - Ashutosh Bapat - Ashutosh Sharma - Ashwin Agrawal - Atsushi Torikoshi - Ayumi Ishii - Basil Bourque - Beena Emerson - Ben de Graaff - Benedikt Grundmann - Bernd Helmle - Brad DeJong - Brandur Leach - Breen Hagan - Bruce Momjian - Bruno Wolff III - Catalin Iacob - Chapman Flack - Chen Huajun - Choi Doo-Won - Chris Bandy - Chris Richards - Chris Ruprecht - Christian Ullrich - Christoph Berg - Chuanting Wang - Claudio Freire - Clinton Adams - Const Zhang - Constantin Pan - Corey Huinker - Craig Ringer - Cynthia Shang - Dagfinn Ilmari Mannsåker - Daisuke Higuchi - Damian Quiroga - Dan Wood - Dang Minh Huong - Daniel Gustafsson - Daniel Vérité - Daniel Westermann - Daniele Varrazzo - Danylo Hlynskyi - Darko Prelec - Dave Cramer - Dave Page - David Christensen - David Fetter - David Johnston - David Rader - David Rowley - David Steele - Dean Rasheed - Denis Smirnov - Denish Patel - Dennis Björklund - Devrim Gündüz - Dilip Kumar - Dilyan Palauzov - Dima Pavlov - Dimitry Ivanov - Dmitriy Sarafannikov - Dmitry Dolgov - Dmitry Fedin - Don Morrison - Egor Rogov - Eiji Seki - Emil Iggland - Emre Hasegeli - Enrique Meneses - Erik Nordström - Erik Rijkers - Erwin Brandstetter - Etsuro Fujita - Eugen Konkov - Eugene Kazakov - Euler Taveira - Fabien Coelho - Fabrízio de Royes Mello - Feike Steenbergen - Felix Gerzaguet - Filip Jirsák - Fujii Masao - Gabriele Bartolini - Gabrielle Roth - Gao Zengqi - Gerdan Santos - Gianni Ciolli - Gilles Darold - Giuseppe Broccolo - Graham Dutton - Greg Atkins - Greg Burek - Grigory Smolkin - Guillaume Lelarge - Hans Buschmann - Haribabu Kommi - Heikki Linnakangas - Henry Boehlert - Huan Ruan - Ian Barwick - Igor Korot - Ildus Kurbangaliev - Ivan Kartyshov - Jaime Casanova - Jakob Egger - James Parks - Jarred Ward - Jason Li - Jason O'Donnell - Jason Petersen - Jeevan Chalke - Jeevan Ladhe - Jeff Dafoe - Jeff Davis - Jeff Janes - Jelte Fennema - Jeremy Finzel - Jeremy Schneider - Jeroen van der Ham - Jesper Pedersen - Jim Mlodgenski - Jim Nasby - Jinyu Zhang - Joe Conway - Joel Jacobson - John Harvey - Jon Nelson - Jordan Gigov - Josh Berkus - Josh Soref - Julian Markwort - Julien Rouhaud - Junseok Yang - Justin Muise - Justin Pryzby - Kacper Zuk - KaiGai Kohei - Karen Huddleston - Karl Lehenbauer - Karl O. Pinc - Keith Fiske - Kevin Grittner - Kim Rose Carlsen - Konstantin Evteev - Konstantin Knizhnik - Kuntal Ghosh - Kurt Kartaltepe - Kyle Conroy - Kyotaro Horiguchi - Laurenz Albe - Leonardo Cecchi - Ludovic Vaugeois-Pepin - Lukas Fittl - Magnus Hagander - Maksim Milyutin - Maksym Sobolyev - Marc Rassbach - Marc-Olaf Jaschke - Marcos Castedo - Marek Cvoren - Mark Dilger - Mark Kirkwood - Mark Pether - Marko Tiikkaja - Markus Winand - Marllius Ribeiro - Marti Raudsepp - Martín Marqués - Masahiko Sawada - Matheus Oliveira - Mathieu Fenniak - Merlin Moncure - Michael Banck - Michael Day - Michael Meskes - Michael Overmeyer - Michael Paquier - Mike Palmiotto - Milos Urbanek - Mithun Cy - Moshe Jacobson - Murtuza Zabuawala - Naoki Okano - Nathan Bossart - Nathan Wagner - Neha Khatri - Neha Sharma - Neil Anderson - Nicolas Baccelli - Nicolas Guini - Nicolas Thauvin - Nikhil Sontakke - Nikita Glukhov - Nikolaus Thiel - Nikolay Nikitin - Nikolay Shaplov - Noah Misch - Noriyoshi Shinoda - Olaf Gawenda - Oleg Bartunov - Oskari Saarenmaa - Otar Shavadze - Paresh More - Paul Jungwirth - Paul Ramsey - Pavan Deolasee - Pavel Golub - Pavel Hanák - Pavel Raiskup - Pavel Stehule - Peng Sun - Peter Eisentraut - Peter Geoghegan - Petr Jelínek - Philippe Beaudoin - Pierre-Emmanuel André - Piotr Stefaniak - Prabhat Sahu - QL Zhuo - Radek Slupik - Rafa de la Torre - Rafia Sabih - Ragnar Ouchterlony - Rahila Syed - Rajkumar Raghuwanshi - Regina Obe - Richard Pistole - Robert Haas - Robins Tharakan - Rod Taylor - Roman Shaposhnik - Rushabh Lathia - Ryan Murphy - Sandeep Thakkar - Scott Milliken - Sean Farrell - Sebastian Luque - Sehrope Sarkuni - Sergey Burladyan - Sergey Koposov - Shay Rojansky - Shinichi Matsuda - Sho Kato - Simon Riggs - Simone Gotti - Spencer Thomason - Stas Kelvich - Stepan Pesternikov - Stephen Frost - Steve Randall - Steve Singer - Steven Fackler - Steven Winfield - Suraj Kharage - Sveinn Sveinsson - Sven R. Kunze - Tahir Fakhroutdinov - Taiki Kondo - Takayuki Tsunakawa - Takeshi Ideriha - Tatsuo Ishii - Tatsuro Yamada - Teodor Sigaev - Thom Brown - Thomas Kellerer - Thomas Munro - Tim Goodaire - Tobias Bussmann - Tom Dunstan - Tom Lane - Tom van Tilburg - Tomas Vondra - Tomonari Katsumata - Tushar Ahuja - Vaishnavi Prabakaran - Venkata Balaji Nagothi - Vicky Vergara - Victor Wagner - Vik Fearing - Vinayak Pokale - Viren Negi - Vitaly Burovoy - Vladimir Kunshchikov - Vladimir Rusinov - Yi Wen Wong - Yugo Nagata - Zhen Ming Yang - Zhou Digoal - - - - diff --git a/doc/src/sgml/release-13.sgml b/doc/src/sgml/release-13.sgml new file mode 100644 index 00000000000..d5530f4130d --- /dev/null +++ b/doc/src/sgml/release-13.sgml @@ -0,0 +1,16 @@ + + + + + Release 13 + + + Release date: + 2020-??-?? + + + + This is just a placeholder for now. + + + diff --git a/doc/src/sgml/release-7.4.sgml b/doc/src/sgml/release-7.4.sgml deleted file mode 100644 index a67945a42b5..00000000000 --- a/doc/src/sgml/release-7.4.sgml +++ /dev/null @@ -1,4622 +0,0 @@ - - - - - Release 7.4.30 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 7.4.29. - For information about new features in the 7.4 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 7.4.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 7.4.30 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.26, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - - - - - Release 7.4.29 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 7.4.28. - For information about new features in the 7.4 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 7.4.X release series in July 2010. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 7.4.29 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.26, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - - - - - Release 7.4.28 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 7.4.27. - For information about new features in the 7.4 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 7.4.X release series in July 2010. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 7.4.28 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.26, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - - - - - Release 7.4.27 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 7.4.26. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.27 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.26, - see . - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - - - - - Release 7.4.26 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 7.4.25. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.26 - - - A dump/restore is not required for those running 7.4.X. - However, if you have any hash indexes on interval columns, - you must REINDEX them after updating to 7.4.26. - Also, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Fix handling of sub-SELECTs appearing in the arguments of - an outer-level aggregate function (Tom) - - - - - - Fix hash calculation for data type interval (Tom) - - - - This corrects wrong results for hash joins on interval values. - It also changes the contents of hash indexes on interval columns. - If you have any such indexes, you must REINDEX them - after updating. - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Fix calculation of distance between a point and a line segment (Tom) - - - - This led to incorrect results from a number of geometric operators. - - - - - - Fix money data type to work in locales where currency - amounts have no fractional digits, e.g. Japan (Itagaki Takahiro) - - - - - - Properly round datetime input like - 00:12:57.9999999999999999999999999999 (Tom) - - - - - - Fix poor choice of page split point in GiST R-tree operator classes - (Teodor) - - - - - - Fix portability issues in plperl initialization (Andrew Dunstan) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - - - - - Release 7.4.25 - - - Release date: - 2009-03-16 - - - - This release contains a variety of fixes from 7.4.24. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.25 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Prevent error recursion crashes when encoding conversion fails (Tom) - - - - This change extends fixes made in the last two minor releases for - related failure scenarios. The previous fixes were narrowly tailored - for the original problem reports, but we have now recognized that - any error thrown by an encoding conversion function could - potentially lead to infinite recursion while trying to report the - error. The solution therefore is to disable translation and encoding - conversion and report the plain-ASCII form of any error message, - if we find we have gotten into a recursive error reporting situation. - (CVE-2009-0922) - - - - - - Disallow CREATE CONVERSION with the wrong encodings - for the specified conversion function (Heikki) - - - - This prevents one possible scenario for encoding conversion failure. - The previous change is a backstop to guard against other kinds of - failures in the same area. - - - - - - Fix core dump when to_char() is given format codes that - are inappropriate for the type of the data argument (Tom) - - - - - - Add MUST (Mauritius Island Summer Time) to the default list - of known timezone abbreviations (Xavier Bugaud) - - - - - - - - - - Release 7.4.24 - - - Release date: - 2009-02-02 - - - - This release contains a variety of fixes from 7.4.23. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.24 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Improve handling of URLs in headline() function (Teodor) - - - - - - Improve handling of overlength headlines in headline() - function (Teodor) - - - - - - Prevent possible Assert failure or misconversion if an encoding - conversion is created with the wrong conversion function for the - specified pair of encodings (Tom, Heikki) - - - - - - Avoid unnecessary locking of small tables in VACUUM - (Heikki) - - - - - - Fix uninitialized variables in contrib/tsearch2's - get_covers() function (Teodor) - - - - - - Fix bug in to_char()'s handling of TH - format codes (Andreas Scherbaum) - - - - - - Make all documentation reference pgsql-bugs and/or - pgsql-hackers as appropriate, instead of the - now-decommissioned pgsql-ports and pgsql-patches - mailing lists (Tom) - - - - - - - - - - Release 7.4.23 - - - Release date: - 2008-11-03 - - - - This release contains a variety of fixes from 7.4.22. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.23 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Fix backend crash when the client encoding cannot represent a localized - error message (Tom) - - - - We have addressed similar issues before, but it would still fail if - the character has no equivalent message itself couldn't - be converted. The fix is to disable localization and send the plain - ASCII error message when we detect such a situation. - - - - - - Fix incorrect tsearch2 headline generation when single query - item matches first word of text (Sushant Sinha) - - - - - - Fix improper display of fractional seconds in interval values when - using a non-ISO datestyle in an - build (Ron Mayer) - - - - - - Ensure SPI_getvalue and SPI_getbinval - behave correctly when the passed tuple and tuple descriptor have - different numbers of columns (Tom) - - - - This situation is normal when a table has had columns added or removed, - but these two functions didn't handle it properly. - The only likely consequence is an incorrect error indication. - - - - - - Fix ecpg's parsing of CREATE USER (Michael) - - - - - - - - - - Release 7.4.22 - - - Release date: - 2008-09-22 - - - - This release contains a variety of fixes from 7.4.21. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.22 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Fix datetime input functions to correctly detect integer overflow when - running on a 64-bit platform (Tom) - - - - - - Improve performance of writing very long log messages to syslog (Tom) - - - - - - Fix bug in backwards scanning of a cursor on a SELECT DISTINCT - ON query (Tom) - - - - - - Fix planner to estimate that GROUP BY expressions yielding - boolean results always result in two groups, regardless of the - expressions' contents (Tom) - - - - This is very substantially more accurate than the regular GROUP - BY estimate for certain boolean tests like col - IS NULL. - - - - - - Improve pg_dump and pg_restore's - error reporting after failure to send a SQL command (Tom) - - - - - - - - - - Release 7.4.21 - - - Release date: - 2008-06-12 - - - - This release contains one serious bug fix over 7.4.20. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.21 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Make pg_get_ruledef() parenthesize negative constants (Tom) - - - - Before this fix, a negative constant in a view or rule might be dumped - as, say, -42::integer, which is subtly incorrect: it should - be (-42)::integer due to operator precedence rules. - Usually this would make little difference, but it could interact with - another recent patch to cause - PostgreSQL to reject what had been a valid - SELECT DISTINCT view query. Since this could result in - pg_dump output failing to reload, it is being treated - as a high-priority fix. The only released versions in which dump - output is actually incorrect are 8.3.1 and 8.2.7. - - - - - - - - - - Release 7.4.20 - - - Release date: - never released - - - - This release contains a variety of fixes from 7.4.19. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.20 - - - A dump/restore is not required for those running 7.4.X. - However, if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Fix conversions between ISO-8859-5 and other encodings to handle - Cyrillic Yo characters (e and E with - two dots) (Sergey Burladyan) - - - - - - Fix a few datatype input functions - that were allowing unused bytes in their results to contain - uninitialized, unpredictable values (Tom) - - - - This could lead to failures in which two apparently identical literal - values were not seen as equal, resulting in the parser complaining - about unmatched ORDER BY and DISTINCT - expressions. - - - - - - Fix a corner case in regular-expression substring matching - (substring(string from - pattern)) (Tom) - - - - The problem occurs when there is a match to the pattern overall but - the user has specified a parenthesized subexpression and that - subexpression hasn't got a match. An example is - substring('foo' from 'foo(bar)?'). - This should return NULL, since (bar) isn't matched, but - it was mistakenly returning the whole-pattern match instead (ie, - foo). - - - - - - Fix incorrect result from ecpg's - PGTYPEStimestamp_sub() function (Michael) - - - - - - Fix DatumGetBool macro to not fail with gcc - 4.3 (Tom) - - - - This problem affects old style (V0) C functions that - return boolean. The fix is already in 8.3, but the need to - back-patch it was not realized at the time. - - - - - - Fix longstanding LISTEN/NOTIFY - race condition (Tom) - - - - In rare cases a session that had just executed a - LISTEN might not get a notification, even though - one would be expected because the concurrent transaction executing - NOTIFY was observed to commit later. - - - - A side effect of the fix is that a transaction that has executed - a not-yet-committed LISTEN command will not see any - row in pg_listener for the LISTEN, - should it choose to look; formerly it would have. This behavior - was never documented one way or the other, but it is possible that - some applications depend on the old behavior. - - - - - - Fix display of constant expressions in ORDER BY - and GROUP BY (Tom) - - - - An explicitly casted constant would be shown incorrectly. This could - for example lead to corruption of a view definition during - dump and reload. - - - - - - Fix libpq to handle NOTICE messages correctly - during COPY OUT (Tom) - - - - This failure has only been observed to occur when a user-defined - datatype's output routine issues a NOTICE, but there is no - guarantee it couldn't happen due to other causes. - - - - - - - - - - Release 7.4.19 - - - Release date: - 2008-01-07 - - - - This release contains a variety of fixes from 7.4.18, - including fixes for significant security issues. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.19 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Prevent functions in indexes from executing with the privileges of - the user running VACUUM, ANALYZE, etc (Tom) - - - - Functions used in index expressions and partial-index - predicates are evaluated whenever a new table entry is made. It has - long been understood that this poses a risk of trojan-horse code - execution if one modifies a table owned by an untrustworthy user. - (Note that triggers, defaults, check constraints, etc. pose the - same type of risk.) But functions in indexes pose extra danger - because they will be executed by routine maintenance operations - such as VACUUM FULL, which are commonly performed - automatically under a superuser account. For example, a nefarious user - can execute code with superuser privileges by setting up a - trojan-horse index definition and waiting for the next routine vacuum. - The fix arranges for standard maintenance operations - (including VACUUM, ANALYZE, REINDEX, - and CLUSTER) to execute as the table owner rather than - the calling user, using the same privilege-switching mechanism already - used for SECURITY DEFINER functions. To prevent bypassing - this security measure, execution of SET SESSION - AUTHORIZATION and SET ROLE is now forbidden within a - SECURITY DEFINER context. (CVE-2007-6600) - - - - - - Repair assorted bugs in the regular-expression package (Tom, Will Drewry) - - - - Suitably crafted regular-expression patterns could cause crashes, - infinite or near-infinite looping, and/or massive memory consumption, - all of which pose denial-of-service hazards for applications that - accept regex search patterns from untrustworthy sources. - (CVE-2007-4769, CVE-2007-4772, CVE-2007-6067) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - The fix that appeared for this in 7.4.18 was incomplete, as it plugged - the hole for only some dblink functions. (CVE-2007-6601, - CVE-2007-3278) - - - - - - Fix planner failure in some cases of WHERE false AND var IN - (SELECT ...) (Tom) - - - - - - Fix potential crash in translate() when using a multibyte - database encoding (Tom) - - - - - - Fix PL/Python to not crash on long exception messages (Alvaro) - - - - - - ecpg parser fixes (Michael) - - - - - - Make contrib/tablefunc's crosstab() handle - NULL rowid as a category in its own right, rather than crashing (Joe) - - - - - - Fix tsvector and tsquery output routines to - escape backslashes correctly (Teodor, Bruce) - - - - - - Fix crash of to_tsvector() on huge input strings (Teodor) - - - - - - Require a specific version of Autoconf to be used - when re-generating the configure script (Peter) - - - - This affects developers and packagers only. The change was made - to prevent accidental use of untested combinations of - Autoconf and PostgreSQL versions. - You can remove the version check if you really want to use a - different Autoconf version, but it's - your responsibility whether the result works or not. - - - - - - - - - - Release 7.4.18 - - - Release date: - 2007-09-17 - - - - This release contains fixes from 7.4.17. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.18 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Prevent index corruption when a transaction inserts rows and - then aborts close to the end of a concurrent VACUUM - on the same table (Tom) - - - - - - Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom) - - - - - - Fix excessive logging of SSL error messages (Tom) - - - - - - Fix crash when log_min_error_statement logging runs out - of memory (Tom) - - - - - - Prevent CLUSTER from failing - due to attempting to process temporary tables of other sessions (Alvaro) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - - - - - - - Release 7.4.17 - - - Release date: - 2007-04-23 - - - - This release contains fixes from 7.4.16, - including a security fix. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.17 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Support explicit placement of the temporary-table schema within - search_path, and disable searching it for functions - and operators (Tom) - - - This is needed to allow a security-definer function to set a - truly secure value of search_path. Without it, - an unprivileged SQL user can use temporary objects to execute code - with the privileges of the security-definer function (CVE-2007-2138). - See CREATE FUNCTION for more information. - - - - - - /contrib/tsearch2 crash fixes (Teodor) - - - - - - Fix potential-data-corruption bug in how VACUUM FULL handles - UPDATE chains (Tom, Pavan Deolasee) - - - - - - Fix PANIC during enlargement of a hash index (bug introduced in 7.4.15) - (Tom) - - - - - - - - - - Release 7.4.16 - - - Release date: - 2007-02-05 - - - - This release contains a variety of fixes from 7.4.15, including - a security fix. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.16 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Remove security vulnerability that allowed connected users - to read backend memory (Tom) - - - The vulnerability involves suppressing the normal check that a SQL - function returns the data type it's declared to, or changing the - data type of a table column used in a SQL function (CVE-2007-0555). - This error can easily be exploited to cause a backend crash, and in - principle might be used to read database content that the user - should not be able to access. - - - - - - Fix rare bug wherein btree index page splits could fail - due to choosing an infeasible split point (Heikki Linnakangas) - - - - - - Fix for rare Assert() crash triggered by UNION (Tom) - - - - - - Tighten security of multi-byte character processing for UTF8 sequences - over three bytes long (Tom) - - - - - - - - - - Release 7.4.15 - - - Release date: - 2007-01-08 - - - - This release contains a variety of fixes from 7.4.14. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.15 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - - - - - Improve handling of getaddrinfo() on AIX (Tom) - - - - This fixes a problem with starting the statistics collector, - among other things. - - - - - - Fix failed to re-find parent key errors in - VACUUM (Tom) - - - - - - Fix bugs affecting multi-gigabyte hash indexes (Tom) - - - - - - Fix error when constructing an ARRAY[] made up of multiple - empty elements (Tom) - - - - - - to_number() and to_char(numeric) - are now STABLE, not IMMUTABLE, for - new initdb installs (Tom) - - - - This is because lc_numeric can potentially - change the output of these functions. - - - - - - Improve index usage of regular expressions that use parentheses (Tom) - - - - This improves psql \d performance also. - - - - - - - - - - Release 7.4.14 - - - Release date: - 2006-10-16 - - - - This release contains a variety of fixes from 7.4.13. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.14 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - - Changes - - -Fix core dump when an untyped literal is taken as -ANYARRAY -Fix string_to_array() to handle overlapping - matches for the separator string -For example, string_to_array('123xx456xxx789', 'xx'). - -Fix corner cases in pattern matching for - psql's \d commands -Fix index-corrupting bugs in /contrib/ltree - (Teodor) -Fix backslash escaping in /contrib/dbmirror -Adjust regression tests for recent changes in US DST laws - - - - - - - - Release 7.4.13 - - - Release date: - 2006-05-23 - - - - This release contains a variety of fixes from 7.4.12, - including patches for extremely serious security issues. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.13 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - Full security against the SQL-injection attacks described in - CVE-2006-2313 and CVE-2006-2314 might require changes in application - code. If you have applications that embed untrustworthy strings - into SQL commands, you should examine them as soon as possible to - ensure that they are using recommended escaping techniques. In - most cases, applications should be using subroutines provided by - libraries or drivers (such as libpq's - PQescapeStringConn()) to perform string escaping, - rather than relying on ad hoc code to do it. - - - - - Changes - - -Change the server to reject invalidly-encoded multibyte -characters in all cases (Tatsuo, Tom) -While PostgreSQL has been moving in this direction for -some time, the checks are now applied uniformly to all encodings and all -textual input, and are now always errors not merely warnings. This change -defends against SQL-injection attacks of the type described in CVE-2006-2313. - - -Reject unsafe uses of \' in string literals -As a server-side defense against SQL-injection attacks of the type -described in CVE-2006-2314, the server now only accepts '' and not -\' as a representation of ASCII single quote in SQL string -literals. By default, \' is rejected only when -client_encoding is set to a client-only encoding (SJIS, BIG5, GBK, -GB18030, or UHC), which is the scenario in which SQL injection is possible. -A new configuration parameter backslash_quote is available to -adjust this behavior when needed. Note that full security against -CVE-2006-2314 might require client-side changes; the purpose of -backslash_quote is in part to make it obvious that insecure -clients are insecure. - - -Modify libpq's string-escaping routines to be -aware of encoding considerations and -standard_conforming_strings -This fixes libpq-using applications for the security -issues described in CVE-2006-2313 and CVE-2006-2314, and also future-proofs -them against the planned changeover to SQL-standard string literal syntax. -Applications that use multiple PostgreSQL connections -concurrently should migrate to PQescapeStringConn() and -PQescapeByteaConn() to ensure that escaping is done correctly -for the settings in use in each database connection. Applications that -do string escaping by hand should be modified to rely on library -routines instead. - - -Fix some incorrect encoding conversion functions -win1251_to_iso, alt_to_iso, -euc_tw_to_big5, euc_tw_to_mic, -mic_to_euc_tw were all broken to varying -extents. - - -Clean up stray remaining uses of \' in strings -(Bruce, Jan) - -Fix bug that sometimes caused OR'd index scans to -miss rows they should have returned - -Fix WAL replay for case where a btree index has been -truncated - -Fix SIMILAR TO for patterns involving -| (Tom) - -Fix server to use custom DH SSL parameters correctly (Michael -Fuhr) - -Fix for Bonjour on Intel Macs (Ashley Clark) - -Fix various minor memory leaks - - - - - - - Release 7.4.12 - - - Release date: - 2006-02-14 - - - - This release contains a variety of fixes from 7.4.11. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.12 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.11, - see . - - - - - Changes - - - -Fix potential crash in SET -SESSION AUTHORIZATION (CVE-2006-0553) -An unprivileged user could crash the server process, resulting in -momentary denial of service to other users, if the server has been compiled -with Asserts enabled (which is not the default). -Thanks to Akio Ishida for reporting this problem. - - -Fix bug with row visibility logic in self-inserted -rows (Tom) -Under rare circumstances a row inserted by the current command -could be seen as already valid, when it should not be. Repairs bug -created in 7.4.9 and 7.3.11 releases. - - -Fix race condition that could lead to file already -exists errors during pg_clog file creation -(Tom) - -Properly check DOMAIN constraints for -UNKNOWN parameters in prepared statements -(Neil) - -Fix to allow restoring dumps that have cross-schema -references to custom operators (Tom) - -Portability fix for testing presence of finite -and isinf during configure (Tom) - - - - - - - - Release 7.4.11 - - - Release date: - 2006-01-09 - - - - This release contains a variety of fixes from 7.4.10. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.11 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.8, - see . - Also, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the locale or - plperl issues described below. - - - - - Changes - - - -Fix for protocol-level Describe messages issued -outside a transaction or in a failed transaction (Tom) - -Fix character string comparison for locales that consider -different character combinations as equal, such as Hungarian (Tom) -This might require REINDEX to fix existing indexes on -textual columns. - -Set locale environment variables during postmaster startup -to ensure that plperl won't change the locale later -This fixes a problem that occurred if the postmaster was -started with environment variables specifying a different locale than what -initdb had been told. Under these conditions, any use of -plperl was likely to lead to corrupt indexes. You might need -REINDEX to fix existing indexes on -textual columns if this has happened to you. - -Fix longstanding bug in strpos() and regular expression -handling in certain rarely used Asian multi-byte character sets (Tatsuo) - - -Fix bug in /contrib/pgcrypto gen_salt, -which caused it not to use all available salt space for MD5 and -XDES algorithms (Marko Kreen, Solar Designer) -Salts for Blowfish and standard DES are unaffected. - -Fix /contrib/dblink to throw an error, -rather than crashing, when the number of columns specified is different from -what's actually returned by the query (Joe) - - - - - - - - Release 7.4.10 - - - Release date: - 2005-12-12 - - - - This release contains a variety of fixes from 7.4.9. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.10 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.8, - see . - - - - - Changes - - - -Fix race condition in transaction log management -There was a narrow window in which an I/O operation could be initiated -for the wrong page, leading to an Assert failure or data -corruption. - - -Prevent failure if client sends Bind protocol message -when current transaction is already aborted - -/contrib/ltree fixes (Teodor) - -AIX and HPUX compile fixes (Tom) - -Fix longstanding planning error for outer joins -This bug sometimes caused a bogus error RIGHT JOIN is -only supported with merge-joinable join conditions. - -Prevent core dump in pg_autovacuum when a -table has been dropped - - - - - - - Release 7.4.9 - - - Release date: - 2005-10-04 - - - - This release contains a variety of fixes from 7.4.8. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.9 - - - A dump/restore is not required for those running 7.4.X. However, - if you are upgrading from a version earlier than 7.4.8, - see . - - - - - Changes - - -Fix error that allowed VACUUM to remove -ctid chains too soon, and add more checking in code that follows -ctid links -This fixes a long-standing problem that could cause crashes in very rare -circumstances. -Fix CHAR() to properly pad spaces to the specified -length when using a multiple-byte character set (Yoshiyuki Asaba) -In prior releases, the padding of CHAR() was incorrect -because it only padded to the specified number of bytes without -considering how many characters were stored. -Fix the sense of the test for read-only transaction -in COPY -The code formerly prohibited COPY TO, where it should -prohibit COPY FROM. - -Fix planning problem with outer-join ON clauses that reference -only the inner-side relation -Further fixes for x FULL JOIN y ON true corner -cases -Make array_in and array_recv more -paranoid about validating their OID parameter -Fix missing rows in queries like UPDATE a=... WHERE -a... with GiST index on column a -Improve robustness of datetime parsing -Improve checking for partially-written WAL -pages -Improve robustness of signal handling when SSL is -enabled -Don't try to open more than max_files_per_process -files during postmaster startup -Various memory leakage fixes -Various portability improvements -Fix PL/pgSQL to handle var := var correctly when -the variable is of pass-by-reference type -Update contrib/tsearch2 to use current Snowball -code - - - - - - - Release 7.4.8 - - - Release date: - 2005-05-09 - - - - This release contains a variety of fixes from 7.4.7, including several - security-related issues. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.8 - - - A dump/restore is not required for those running 7.4.X. However, - it is one possible way of handling two significant security problems - that have been found in the initial contents of 7.4.X system - catalogs. A dump/initdb/reload sequence using 7.4.8's initdb will - automatically correct these problems. - - - - The larger security problem is that the built-in character set encoding - conversion functions can be invoked from SQL commands by unprivileged - users, but the functions were not designed for such use and are not - secure against malicious choices of arguments. The fix involves changing - the declared parameter list of these functions so that they can no longer - be invoked from SQL commands. (This does not affect their normal use - by the encoding conversion machinery.) - - - - The lesser problem is that the contrib/tsearch2 module - creates several functions that are misdeclared to return - internal when they do not accept internal arguments. - This breaks type safety for all functions using internal - arguments. - - - - It is strongly recommended that all installations repair these errors, - either by initdb or by following the manual repair procedures given - below. The errors at least allow unprivileged database users to crash - their server process, and might allow unprivileged users to gain the - privileges of a database superuser. - - - - If you wish not to do an initdb, perform the following procedures instead. - As the database superuser, do: - - -BEGIN; -UPDATE pg_proc SET proargtypes[3] = 'internal'::regtype -WHERE pronamespace = 11 AND pronargs = 5 - AND proargtypes[2] = 'cstring'::regtype; --- The command should report having updated 90 rows; --- if not, rollback and investigate instead of committing! -COMMIT; - - - Next, if you have installed contrib/tsearch2, do: - - -BEGIN; -UPDATE pg_proc SET proargtypes[0] = 'internal'::regtype -WHERE oid IN ( - 'dex_init(text)'::regprocedure, - 'snb_en_init(text)'::regprocedure, - 'snb_ru_init(text)'::regprocedure, - 'spell_init(text)'::regprocedure, - 'syn_init(text)'::regprocedure -); --- The command should report having updated 5 rows; --- if not, rollback and investigate instead of committing! -COMMIT; - - - If this command fails with a message like function - "dex_init(text)" does not exist, then either tsearch2 - is not installed in this database, or you already did the update. - - - - The above procedures must be carried out in each database - of an installation, including template1, and ideally - including template0 as well. If you do not fix the - template databases then any subsequently created databases will contain - the same errors. template1 can be fixed in the same way - as any other database, but fixing template0 requires - additional steps. First, from any database issue: - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; - - Next connect to template0 and perform the above repair - procedures. Finally, do: - --- re-freeze template0: -VACUUM FREEZE; --- and protect it against future alterations: -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - Changes - - -Change encoding function signature to prevent -misuse -Change contrib/tsearch2 to avoid unsafe use of -INTERNAL function results -Repair ancient race condition that allowed a transaction to be -seen as committed for some purposes (eg SELECT FOR UPDATE) slightly sooner -than for other purposes -This is an extremely serious bug since it could lead to apparent -data inconsistencies being briefly visible to applications. -Repair race condition between relation extension and -VACUUM -This could theoretically have caused loss of a page's worth of -freshly-inserted data, although the scenario seems of very low probability. -There are no known cases of it having caused more than an Assert failure. - -Fix comparisons of TIME WITH TIME ZONE values - -The comparison code was wrong in the case where the ---enable-integer-datetimes configuration switch had been used. -NOTE: if you have an index on a TIME WITH TIME ZONE column, -it will need to be REINDEXed after installing this update, because -the fix corrects the sort order of column values. - -Fix EXTRACT(EPOCH) for -TIME WITH TIME ZONE values -Fix mis-display of negative fractional seconds in -INTERVAL values - -This error only occurred when the ---enable-integer-datetimes configuration switch had been used. - -Ensure operations done during backend shutdown are counted by -statistics collector - -This is expected to resolve reports of pg_autovacuum -not vacuuming the system catalogs often enough — it was not being -told about catalog deletions caused by temporary table removal during -backend exit. - -Additional buffer overrun checks in plpgsql -(Neil) -Fix pg_dump to dump trigger names containing % -correctly (Neil) -Fix contrib/pgcrypto for newer OpenSSL builds -(Marko Kreen) -Still more 64-bit fixes for -contrib/intagg -Prevent incorrect optimization of functions returning -RECORD -Prevent to_char(interval) from dumping core for -month-related formats -Prevent crash on COALESCE(NULL,NULL) -Fix array_map to call PL functions correctly -Fix permission checking in ALTER DATABASE RENAME -Fix ALTER LANGUAGE RENAME -Make RemoveFromWaitQueue clean up after itself - -This fixes a lock management error that would only be visible if a transaction -was kicked out of a wait for a lock (typically by query cancel) and then the -holder of the lock released it within a very narrow window. - -Fix problem with untyped parameter appearing in -INSERT ... SELECT -Fix CLUSTER failure after -ALTER TABLE SET WITHOUT OIDS - - - - - - - Release 7.4.7 - - - Release date: - 2005-01-31 - - - - This release contains a variety of fixes from 7.4.6, including several - security-related issues. - For information about new features in the 7.4 major release, see - . - - - - Migration to Version 7.4.7 - - - A dump/restore is not required for those running 7.4.X. - - - - - Changes - - -Disallow LOAD to non-superusers - -On platforms that will automatically execute initialization functions of a -shared library (this includes at least Windows and ELF-based Unixen), -LOAD can be used to make the server execute arbitrary code. -Thanks to NGS Software for reporting this. -Check that creator of an aggregate function has the right to -execute the specified transition functions - -This oversight made it possible to bypass denial of EXECUTE -permission on a function. -Fix security and 64-bit issues in -contrib/intagg -Add needed STRICT marking to some contrib functions (Kris -Jurka) -Avoid buffer overrun when plpgsql cursor declaration has too -many parameters (Neil) -Fix planning error for FULL and RIGHT outer joins - -The result of the join was mistakenly supposed to be sorted the same as the -left input. This could not only deliver mis-sorted output to the user, but -in case of nested merge joins could give outright wrong answers. - -Fix plperl for quote marks in tuple fields -Fix display of negative intervals in SQL and GERMAN -datestyles -Make age(timestamptz) do calculation in local timezone not -GMT - - - - - - - Release 7.4.6 - - - Release date: - 2004-10-22 - - - - This release contains a variety of fixes from 7.4.5. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.6 - - - A dump/restore is not required for those running 7.4.X. - - - - - Changes - - -Repair possible failure to update hint bits on disk - -Under rare circumstances this oversight could lead to -could not access transaction status failures, which qualifies -it as a potential-data-loss bug. - -Ensure that hashed outer join does not miss tuples - -Very large left joins using a hash join plan could fail to output unmatched -left-side rows given just the right data distribution. - -Disallow running pg_ctl as root - -This is to guard against any possible security issues. - -Avoid using temp files in /tmp in make_oidjoins_check - -This has been reported as a security issue, though it's hardly worthy of -concern since there is no reason for non-developers to use this script anyway. - -Prevent forced backend shutdown from re-emitting prior command -result - -In rare cases, a client might think that its last command had succeeded when -it really had been aborted by forced database shutdown. - -Repair bug in pg_stat_get_backend_idset - -This could lead to misbehavior in some of the system-statistics views. - -Fix small memory leak in postmaster -Fix expected both swapped tables to have TOAST -tables bug - -This could arise in cases such as CLUSTER after ALTER TABLE DROP COLUMN. - -Prevent pg_ctl restart from adding -D multiple times -Fix problem with NULL values in GiST indexes -:: is no longer interpreted as a variable in an -ECPG prepare statement - - - - - - - Release 7.4.5 - - - Release date: - 2004-08-18 - - - - This release contains one serious bug fix over 7.4.4. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.5 - - - A dump/restore is not required for those running 7.4.X. - - - - - Changes - - -Repair possible crash during concurrent B-tree index insertions - -This patch fixes a rare case in which concurrent insertions into a B-tree index -could result in a server panic. No permanent damage would result, but it's -still worth a re-release. The bug does not exist in pre-7.4 releases. - - - - - - - - Release 7.4.4 - - - Release date: - 2004-08-16 - - - - This release contains a variety of fixes from 7.4.3. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.4 - - - A dump/restore is not required for those running 7.4.X. - - - - - Changes - - -Prevent possible loss of committed transactions during crash - -Due to insufficient interlocking between transaction commit and checkpointing, -it was possible for transactions committed just before the most recent -checkpoint to be lost, in whole or in part, following a database crash and -restart. This is a serious bug that has existed -since PostgreSQL 7.1. - -Check HAVING restriction before evaluating result list of an -aggregate plan -Avoid crash when session's current user ID is deleted -Fix hashed crosstab for zero-rows case (Joe) -Force cache update after renaming a column in a foreign key -Pretty-print UNION queries correctly -Make psql handle \r\n newlines properly in COPY IN -pg_dump handled ACLs with grant options incorrectly -Fix thread support for macOS and Solaris -Updated JDBC driver (build 215) with various fixes -ECPG fixes -Translation updates (various contributors) - - - - - - - Release 7.4.3 - - - Release date: - 2004-06-14 - - - - This release contains a variety of fixes from 7.4.2. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.3 - - - A dump/restore is not required for those running 7.4.X. - - - - - Changes - - -Fix temporary memory leak when using non-hashed aggregates (Tom) -ECPG fixes, including some for Informix compatibility (Michael) -Fixes for compiling with thread-safety, particularly Solaris (Bruce) -Fix error in COPY IN termination when using the old network protocol (ljb) -Several important fixes in pg_autovacuum, including fixes for -large tables, unsigned oids, stability, temp tables, and debug mode -(Matthew T. O'Connor) -Fix problem with reading tar-format dumps on NetBSD and BSD/OS (Bruce) -Several JDBC fixes -Fix ALTER SEQUENCE RESTART where last_value equals the restart value (Tom) -Repair failure to recalculate nested sub-selects (Tom) -Fix problems with non-constant expressions in LIMIT/OFFSET -Support FULL JOIN with no join clause, such as X FULL JOIN Y ON TRUE (Tom) -Fix another zero-column table bug (Tom) -Improve handling of non-qualified identifiers in GROUP BY clauses in sub-selects (Tom) - -Select-list aliases within the sub-select will now take precedence over -names from outer query levels. - -Do not generate NATURAL CROSS JOIN when decompiling rules (Tom) -Add checks for invalid field length in binary COPY (Tom) - - This fixes a difficult-to-exploit security hole. - -Avoid locking conflict between ANALYZE and LISTEN/NOTIFY -Numerous translation updates (various contributors) - - - - - - - Release 7.4.2 - - - Release date: - 2004-03-08 - - - - This release contains a variety of fixes from 7.4.1. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.2 - - - A dump/restore is not required for those running 7.4.X. However, - it might be advisable as the easiest method of incorporating fixes for - two errors that have been found in the initial contents of 7.4.X system - catalogs. A dump/initdb/reload sequence using 7.4.2's initdb will - automatically correct these problems. - - - - The more severe of the two errors is that data type anyarray - has the wrong alignment label; this is a problem because the - pg_statistic system catalog uses anyarray - columns. The mislabeling can cause planner misestimations and even - crashes when planning queries that involve WHERE clauses on - double-aligned columns (such as float8 and timestamp). - It is strongly recommended that all installations repair this error, - either by initdb or by following the manual repair procedure given - below. - - - - The lesser error is that the system view pg_settings - ought to be marked as having public update access, to allow - UPDATE pg_settings to be used as a substitute for - SET. This can also be fixed either by initdb or manually, - but it is not necessary to fix unless you want to use UPDATE - pg_settings. - - - - If you wish not to do an initdb, the following procedure will work - for fixing pg_statistic. As the database superuser, - do: - - --- clear out old data in pg_statistic: -DELETE FROM pg_statistic; -VACUUM pg_statistic; --- this should update 1 row: -UPDATE pg_type SET typalign = 'd' WHERE oid = 2277; --- this should update 6 rows: -UPDATE pg_attribute SET attalign = 'd' WHERE atttypid = 2277; --- --- At this point you MUST start a fresh backend to avoid a crash! --- --- repopulate pg_statistic: -ANALYZE; - - - This can be done in a live database, but beware that all backends - running in the altered database must be restarted before it is safe to - repopulate pg_statistic. - - - - To repair the pg_settings error, simply do: - -GRANT SELECT, UPDATE ON pg_settings TO PUBLIC; - - - - - The above procedures must be carried out in each database - of an installation, including template1, and ideally - including template0 as well. If you do not fix the - template databases then any subsequently created databases will contain - the same errors. template1 can be fixed in the same way - as any other database, but fixing template0 requires - additional steps. First, from any database issue: - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; - - Next connect to template0 and perform the above repair - procedures. Finally, do: - --- re-freeze template0: -VACUUM FREEZE; --- and protect it against future alterations: -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - Changes - - - Release 7.4.2 incorporates all the fixes included in release 7.3.6, - plus the following fixes: - - - -Fix pg_statistic alignment bug that could crash optimizer -See above for details about this problem. -Allow non-super users to update pg_settings -Fix several optimizer bugs, most of which led to -variable not found in subplan target lists errors -Avoid out-of-memory failure during startup of large multiple -index scan -Fix multibyte problem that could lead to out of -memory error during COPY IN -Fix problems with SELECT INTO / CREATE -TABLE AS from tables without OIDs -Fix problems with alter_table regression test -during parallel testing -Fix problems with hitting open file limit, especially on macOS (Tom) -Partial fix for Turkish-locale issues -initdb will succeed now in Turkish locale, but there are still some -inconveniences associated with the i/I problem. -Make pg_dump set client encoding on restore -Other minor pg_dump fixes -Allow ecpg to again use C keywords as column names (Michael) -Added ecpg WHENEVER NOT_FOUND to -SELECT/INSERT/UPDATE/DELETE (Michael) -Fix ecpg crash for queries calling set-returning functions (Michael) -Various other ecpg fixes (Michael) -Fixes for Borland compiler -Thread build improvements (Bruce) -Various other build fixes -Various JDBC fixes - - - - - - - Release 7.4.1 - - - Release date: - 2003-12-22 - - - - This release contains a variety of fixes from 7.4. - For information about new features in the 7.4 major release, see - . - - - - - Migration to Version 7.4.1 - - - A dump/restore is not required for those - running 7.4. - - - - If you want to install the fixes in the information schema - you need to reload it into the database. - This is either accomplished by initializing a new cluster - by running initdb, or by running the following - sequence of SQL commands in each database (ideally including - template1) as a superuser in - psql, after installing the new release: - -DROP SCHEMA information_schema CASCADE; -\i /usr/local/pgsql/share/information_schema.sql - - Substitute your installation path in the second command. - - - - - - Changes - - -Fixed bug in CREATE SCHEMA parsing in ECPG (Michael) -Fix compile error when and are used together (Peter) -Fix for subqueries that used hash joins (Tom) - - Certain subqueries that used hash joins would crash because of - improperly shared structures. - -Fix free space map compaction bug (Tom) - - This fixes a bug where compaction of the free space map could lead - to a database server shutdown. - - -Fix for Borland compiler build of libpq (Bruce) -Fix netmask() and hostmask() to return the maximum-length masklen (Tom) - - Fix these functions to return values consistent with pre-7.4 - releases. - - -Several contrib/pg_autovacuum fixes - - Fixes include improper variable initialization, missing vacuum after - TRUNCATE, and duration computation overflow for long vacuums. - - -Allow compile of contrib/cube under Cygwin (Jason Tishler) -Fix Solaris use of password file when no passwords are defined (Tom) - - Fix crash on Solaris caused by use of any type of password - authentication when no passwords were defined. - - -JDBC fix for thread problems, other fixes -Fix for bytea index lookups (Joe) -Fix information schema for bit data types (Peter) -Force zero_damaged_pages to be on during recovery from WAL -Prevent some obscure cases of variable not in subplan target lists -Make PQescapeBytea and byteaout consistent with each other (Joe) -Escape bytea output for bytes > 0x7e(Joe) - - If different client encodings are used for bytea output and input, it - is possible for bytea values to be corrupted by the differing - encodings. This fix escapes all bytes that might be affected. - - -Added missing SPI_finish() calls to dblink's get_tuple_of_interest() (Joe) -New Czech FAQ -Fix information schema view constraint_column_usage for foreign keys (Peter) -ECPG fixes (Michael) -Fix bug with multiple IN subqueries and joins in the subqueries (Tom) -Allow COUNT('x') to work (Tom) -Install ECPG include files for Informix compatibility into separate directory (Peter) - - Some names of ECPG include files for Informix compatibility conflicted with operating system include files. - By installing them in their own directory, name conflicts have been reduced. - - -Fix SSL memory leak (Neil) - - This release fixes a bug in 7.4 where SSL didn't free all memory it allocated. - - -Prevent pg_service.conf from using service name as default dbname (Bruce) -Fix local ident authentication on FreeBSD (Tom) - - - - - - - Release 7.4 - - - Release date: - 2003-11-17 - - - - Overview - - - Major changes in this release: - - - - - - IN / NOT IN subqueries are - now much more efficient - - - - - In previous releases, IN/NOT - IN subqueries were joined to the upper query by - sequentially scanning the subquery looking for a match. The - 7.4 code uses the same sophisticated techniques used by - ordinary joins and so is much faster. An - IN will now usually be as fast as or faster - than an equivalent EXISTS subquery; this - reverses the conventional wisdom that applied to previous - releases. - - - - - - - Improved GROUP BY processing by using hash buckets - - - - - In previous releases, rows to be grouped had to be sorted - first. The 7.4 code can do GROUP BY - without sorting, by accumulating results into a hash table - with one entry per group. It will still use the sort - technique, however, if the hash table is estimated to be too - large to fit in sort_mem. - - - - - - - New multikey hash join capability - - - - - In previous releases, hash joins could only occur on single - keys. This release allows multicolumn hash joins. - - - - - - - Queries using the explicit JOIN syntax are - now better optimized - - - - - Prior releases evaluated queries using the explicit - JOIN syntax only in the order implied by - the syntax. 7.4 allows full optimization of these queries, - meaning the optimizer considers all possible join orderings - and chooses the most efficient. Outer joins, however, must - still follow the declared ordering. - - - - - - - Faster and more powerful regular expression code - - - - - The entire regular expression module has been replaced with a - new version by Henry Spencer, originally written for Tcl. The - code greatly improves performance and supports several flavors - of regular expressions. - - - - - - - Function-inlining for simple SQL functions - - - - - Simple SQL functions can now be inlined by including their SQL - in the main query. This improves performance by eliminating - per-call overhead. That means simple SQL functions now - behave like macros. - - - - - - - Full support for IPv6 connections and IPv6 address data types - - - - - Previous releases allowed only IPv4 connections, and the IP - data types only supported IPv4 addresses. This release adds - full IPv6 support in both of these areas. - - - - - - - Major improvements in SSL performance and reliability - - - - - Several people very familiar with the SSL API have overhauled - our SSL code to improve SSL key negotiation and error - recovery. - - - - - - - Make free space map efficiently reuse empty index pages, - and other free space management improvements - - - - - In previous releases, B-tree index pages that were left empty - because of deleted rows could only be reused by rows with - index values similar to the rows originally indexed on that - page. In 7.4, VACUUM records empty index - pages and allows them to be reused for any future index rows. - - - - - - - SQL-standard information schema - - - - - The information schema provides a standardized and stable way - to access information about the schema objects defined in a - database. - - - - - - - Cursors conform more closely to the SQL standard - - - - - The commands FETCH and - MOVE have been overhauled to conform more - closely to the SQL standard. - - - - - - - Cursors can exist outside transactions - - - - - These cursors are also called holdable cursors. - - - - - - - New client-to-server protocol - - - - - The new protocol adds error codes, more status information, - faster startup, better support for binary data transmission, - parameter values separated from SQL commands, prepared - statements available at the protocol level, and cleaner - recovery from COPY failures. The older - protocol is still supported by both server and clients. - - - - - - - libpq and - ECPG applications are now fully - thread-safe - - - - - While previous libpq releases - already supported threads, this release improves thread safety - by fixing some non-thread-safe code that was used during - database connection startup. The configure - option must be used to - enable this feature. - - - - - - - New version of full-text indexing - - - - - A new full-text indexing suite is available in - contrib/tsearch2. - - - - - - - New autovacuum tool - - - - - The new autovacuum tool in - contrib/autovacuum monitors the database - statistics tables for - INSERT/UPDATE/DELETE - activity and automatically vacuums tables when needed. - - - - - - - Array handling has been improved and moved into the server core - - - - - Many array limitations have been removed, and arrays behave - more like fully-supported data types. - - - - - - - - - Migration to Version 7.4 - - - A dump/restore using pg_dump is - required for those wishing to migrate data from any previous - release. - - - - Observe the following incompatibilities: - - - - - - The server-side autocommit setting was removed and - reimplemented in client applications and languages. - Server-side autocommit was causing too many problems with - languages and applications that wanted to control their own - autocommit behavior, so autocommit was removed from the server - and added to individual client APIs as appropriate. - - - - - - Error message wording has changed substantially in this - release. Significant effort was invested to make the messages - more consistent and user-oriented. If your applications try to - detect different error conditions by parsing the error message, - you are strongly encouraged to use the new error code facility instead. - - - - - - Inner joins using the explicit JOIN syntax - might behave differently because they are now better - optimized. - - - - - - A number of server configuration parameters have been renamed - for clarity, primarily those related to - logging. - - - - - - FETCH 0 or MOVE 0 now - does nothing. In prior releases, FETCH 0 - would fetch all remaining rows, and MOVE 0 - would move to the end of the cursor. - - - - - - FETCH and MOVE now return - the actual number of rows fetched/moved, or zero if at the - beginning/end of the cursor. Prior releases would return the - row count passed to the command, not the number of rows - actually fetched or moved. - - - - - - COPY now can process files that use - carriage-return or carriage-return/line-feed end-of-line - sequences. Literal carriage-returns and line-feeds are no - longer accepted in data values; use \r and - \n instead. - - - - - - Trailing spaces are now trimmed when converting from type - char(n) to - varchar(n) or text. - This is what most people always expected to happen anyway. - - - - - - The data type float(p) now - measures p in binary digits, not decimal - digits. The new behavior follows the SQL standard. - - - - - - Ambiguous date values now must match the ordering specified by - the datestyle setting. In prior releases, a - date specification of 10/20/03 was interpreted as a - date in October even if datestyle specified that - the day should be first. 7.4 will throw an error if a date - specification is invalid for the current setting of - datestyle. - - - - - - The functions oidrand, - oidsrand, and - userfntest have been removed. These - functions were determined to be no longer useful. - - - - - - String literals specifying time-varying date/time values, such - as 'now' or 'today' will - no longer work as expected in column default expressions; they - now cause the time of the table creation to be the default, not - the time of the insertion. Functions such as - now(), current_timestamp, or - current_date should be used instead. - - - - In previous releases, there was special code so that strings - such as 'now' were interpreted at - INSERT time and not at table creation time, but - this work around didn't cover all cases. Release 7.4 now - requires that defaults be defined properly using functions such - as now() or current_timestamp. These - will work in all situations. - - - - - - The dollar sign ($) is no longer allowed in - operator names. It can instead be a non-first character in - identifiers. This was done to improve compatibility with other - database systems, and to avoid syntax problems when parameter - placeholders ($n) are written - adjacent to operators. - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - release 7.4 and the previous major release. - - - - Server Operation Changes - - - - - Allow IPv6 server connections (Nigel Kukard, Johan Jordaan, - Bruce, Tom, Kurt Roeckx, Andrew Dunstan) - - - - - - Fix SSL to handle errors cleanly (Nathan Mueller) - - - In prior releases, certain SSL API error reports were not - handled correctly. This release fixes those problems. - - - - - - SSL protocol security and performance improvements (Sean Chittenden) - - - SSL key renegotiation was happening too frequently, causing poor - SSL performance. Also, initial key handling was improved. - - - - - - Print lock information when a deadlock is detected (Tom) - - - This allows easier debugging of deadlock situations. - - - - - - Update /tmp socket modification times - regularly to avoid their removal (Tom) - - - This should help prevent /tmp directory - cleaner administration scripts from removing server socket - files. - - - - Enable PAM for macOS (Aaron Hillegass) - - - Make B-tree indexes fully WAL-safe (Tom) - - In prior releases, under certain rare cases, a server crash - could cause B-tree indexes to become corrupt. This release - removes those last few rare cases. - - - - Allow B-tree index compaction and empty page reuse (Tom) - - - - Fix inconsistent index lookups during split of first root page (Tom) - - - In prior releases, when a single-page index split into two - pages, there was a brief period when another database session - could miss seeing an index entry. This release fixes that rare - failure case. - - - - Improve free space map allocation logic (Tom) - - - Preserve free space information between server restarts (Tom) - - In prior releases, the free space map was not saved when the - postmaster was stopped, so newly started servers had no free - space information. This release saves the free space map, and - reloads it when the server is restarted. - - - - Add start time to pg_stat_activity (Neil) - New code to detect corrupt disk pages; erase with zero_damaged_pages (Tom) - New client/server protocol: faster, no username length limit, allow clean exit from COPY (Tom) - Add transaction status, table ID, column ID to client/server protocol (Tom) - Add binary I/O to client/server protocol (Tom) - Remove autocommit server setting; move to client applications (Tom) - New error message wording, error codes, and three levels of error detail (Tom, Joe, Peter) - - - - - Performance Improvements - - - Add hashing for GROUP BY aggregates (Tom) - Make nested-loop joins be smarter about multicolumn indexes (Tom) - Allow multikey hash joins (Tom) - Improve constant folding (Tom) - Add ability to inline simple SQL functions (Tom) - - - Reduce memory usage for queries using complex functions (Tom) - - In prior releases, functions returning allocated memory would - not free it until the query completed. This release allows the - freeing of function-allocated memory when the function call - completes, reducing the total memory used by functions. - - - - - Improve GEQO optimizer performance (Tom) - - This release fixes several inefficiencies in the way the GEQO optimizer - manages potential query paths. - - - - - - Allow IN/NOT IN to be handled via hash - tables (Tom) - - - - - - Improve NOT IN (subquery) - performance (Tom) - - - - - - Allow most IN subqueries to be processed as - joins (Tom) - - - - - - Pattern matching operations can use indexes regardless of - locale (Peter) - - - There is no way for non-ASCII locales to use the standard - indexes for LIKE comparisons. This release - adds a way to create a special index for - LIKE. - - - - - Allow the postmaster to preload libraries using preload_libraries (Joe) - - For shared libraries that require a long time to load, this - option is available so the library can be preloaded in the - postmaster and inherited by all database sessions. - - - - - - Improve optimizer cost computations, particularly for subqueries (Tom) - - - - - - Avoid sort when subquery ORDER BY matches upper query (Tom) - - - - - - Deduce that WHERE a.x = b.y AND b.y = 42 also - means a.x = 42 (Tom) - - - - - - Allow hash/merge joins on complex joins (Tom) - - - - - - Allow hash joins for more data types (Tom) - - - - - - Allow join optimization of explicit inner joins, disable with - join_collapse_limit (Tom) - - - - - - Add parameter from_collapse_limit to control - conversion of subqueries to joins (Tom) - - - - - - Use faster and more powerful regular expression code from Tcl - (Henry Spencer, Tom) - - - - - - Use bit-mapped relation sets in the optimizer (Tom) - - - - - Improve connection startup time (Tom) - - The new client/server protocol requires fewer network packets to - start a database session. - - - - - - Improve trigger/constraint performance (Stephan) - - - - - - Improve speed of col IN (const, const, const, ...) (Tom) - - - - - - Fix hash indexes which were broken in rare cases (Tom) - - - - Improve hash index concurrency and speed (Tom) - - Prior releases suffered from poor hash index performance, - particularly for high concurrency situations. This release fixes - that, and the development group is interested in reports - comparing B-tree and hash index performance. - - - - - Align shared buffers on 32-byte boundary for copy speed improvement (Manfred Spraul) - - Certain CPU's perform faster data copies when addresses are - 32-byte aligned. - - - - - Data type numeric reimplemented for better performance (Tom) - - numeric used to be stored in base 100. The new code - uses base 10000, for significantly better performance. - - - - - - - Server Configuration Changes - - - - Rename server parameter server_min_messages to log_min_messages (Bruce) - - This was done so most parameters that control the server logs - begin with log_. - - - - Rename show_*_stats to log_*_stats (Bruce) - Rename show_source_port to log_source_port (Bruce) - Rename hostname_lookup to log_hostname (Bruce) - - - Add checkpoint_warning to warn of excessive checkpointing (Bruce) - - In prior releases, it was difficult to determine if checkpoint - was happening too frequently. This feature adds a warning to the - server logs when excessive checkpointing happens. - - - - New read-only server parameters for localization (Tom) - - - - Change debug server log messages to output as DEBUG - rather than LOG (Bruce) - - - - - Prevent server log variables from being turned off by non-superusers (Bruce) - - This is a security feature so non-superusers cannot disable - logging that was enabled by the administrator. - - - - - - log_min_messages/client_min_messages now - controls debug_* output (Bruce) - - - This centralizes client debug information so all debug output - can be sent to either the client or server logs. - - - - - Add macOS Rendezvous server support (Chris Campbell) - - This allows macOS hosts to query the network for available - PostgreSQL servers. - - - - - - Add ability to print only slow statements using - log_min_duration_statement - (Christopher) - - - This is an often requested debugging feature that allows - administrators to see only slow queries in their server logs. - - - - - Allow pg_hba.conf to accept netmasks in CIDR format (Andrew Dunstan) - - This allows administrators to merge the host IP address and - netmask fields into a single CIDR field in pg_hba.conf. - - - - New read-only parameter is_superuser (Tom) - - - New parameter log_error_verbosity to control error detail (Tom) - - This works with the new error reporting feature to supply - additional error information like hints, file names and line - numbers. - - - - - postgres --describe-config now dumps server config variables (Aizaz Ahmed, Peter) - - This option is useful for administration tools that need to know - the configuration variable names and their minimums, maximums, - defaults, and descriptions. - - - - - - Add new columns in pg_settings: - context, type, source, - min_val, max_val (Joe) - - - - - - Make default shared_buffers 1000 and - max_connections 100, if possible (Tom) - - - Prior versions defaulted to 64 shared buffers so PostgreSQL - would start on even very old systems. This release tests the - amount of shared memory allowed by the platform and selects more - reasonable default values if possible. Of course, users are - still encouraged to evaluate their resource load and size - shared_buffers accordingly. - - - - - - New pg_hba.conf record type - hostnossl to prevent SSL connections (Jon - Jensen) - - - In prior releases, there was no way to prevent SSL connections - if both the client and server supported SSL. This option allows - that capability. - - - - - - Remove parameter geqo_random_seed - (Tom) - - - - - - Add server parameter regex_flavor to control regular expression processing (Tom) - - - - - - Make pg_ctl better handle nonstandard ports (Greg) - - - - - - - Query Changes - - - New SQL-standard information schema (Peter) - Add read-only transactions (Peter) - Print key name and value in foreign-key violation messages (Dmitry Tkach) - - - Allow users to see their own queries in pg_stat_activity (Kevin Brown) - - In prior releases, only the superuser could see query strings - using pg_stat_activity. Now ordinary users - can see their own query strings. - - - - - Fix aggregates in subqueries to match SQL standard (Tom) - - The SQL standard says that an aggregate function appearing - within a nested subquery belongs to the outer query if its - argument contains only outer-query variables. Prior - PostgreSQL releases did not handle - this fine point correctly. - - - - - Add option to prevent auto-addition of tables referenced in query (Nigel J. Andrews) - - By default, tables mentioned in the query are automatically - added to the FROM clause if they are not already - there. This is compatible with historic - POSTGRES behavior but is contrary to - the SQL standard. This option allows selecting - standard-compatible behavior. - - - - - Allow UPDATE ... SET col = DEFAULT (Rod) - - This allows UPDATE to set a column to its - declared default value. - - - - - Allow expressions to be used in LIMIT/OFFSET (Tom) - - In prior releases, LIMIT/OFFSET could - only use constants, not expressions. - - - - - Implement CREATE TABLE AS EXECUTE (Neil, Peter) - - - - - - Object Manipulation Changes - - - - Make CREATE SEQUENCE grammar more conforming to SQL:2003 (Neil) - - - - Add statement-level triggers (Neil) - - While this allows a trigger to fire at the end of a statement, - it does not allow the trigger to access all rows modified by the - statement. This capability is planned for a future release. - - - - - Add check constraints for domains (Rod) - - This greatly increases the usefulness of domains by allowing - them to use check constraints. - - - - - Add ALTER DOMAIN (Rod) - - This allows manipulation of existing domains. - - - - - Fix several zero-column table bugs (Tom) - - PostgreSQL supports zero-column tables. This fixes various bugs - that occur when using such tables. - - - - - Have ALTER TABLE ... ADD PRIMARY KEY add not-null constraint (Rod) - - In prior releases, ALTER TABLE ... ADD - PRIMARY would add a unique index, but not a not-null - constraint. That is fixed in this release. - - - - Add ALTER TABLE ... WITHOUT OIDS (Rod) - - This allows control over whether new and updated rows will have - an OID column. This is most useful for saving storage space. - - - - - - Add ALTER SEQUENCE to modify minimum, maximum, - increment, cache, cycle values (Rod) - - - - - Add ALTER TABLE ... CLUSTER ON (Alvaro Herrera) - - This command is used by pg_dump to record the - cluster column for each table previously clustered. This - information is used by database-wide cluster to cluster all - previously clustered tables. - - - - Improve automatic type casting for domains (Rod, Tom) - Allow dollar signs in identifiers, except as first character (Tom) - Disallow dollar signs in operator names, so x=$1 works (Tom) - - - - Allow copying table schema using LIKE - subtable, also SQL:2003 - feature INCLUDING DEFAULTS (Rod) - - - - - - Add WITH GRANT OPTION clause to - GRANT (Peter) - - - This enabled GRANT to give other users the - ability to grant privileges on an object. - - - - - - - Utility Command Changes - - - - Add ON COMMIT clause to CREATE TABLE for temporary tables (Gavin) - - This adds the ability for a table to be dropped or all rows - deleted on transaction commit. - - - - - Allow cursors outside transactions using WITH HOLD (Neil) - - In previous releases, cursors were removed at the end of the - transaction that created them. Cursors can now be created with - the WITH HOLD option, which allows them to - continue to be accessed after the creating transaction has - committed. - - - - - FETCH 0 and MOVE 0 now do nothing (Bruce) - - In previous releases, FETCH 0 fetched all - remaining rows, and MOVE 0 moved to the end - of the cursor. - - - - - - Cause FETCH and MOVE to - return the number of rows fetched/moved, or zero if at the - beginning/end of cursor, per SQL standard (Bruce) - - - In prior releases, the row count returned by - FETCH and MOVE did not - accurately reflect the number of rows processed. - - - - - Properly handle SCROLL with cursors, or - report an error (Neil) - - Allowing random access (both forward and backward scrolling) to - some kinds of queries cannot be done without some additional - work. If SCROLL is specified when the cursor - is created, this additional work will be performed. Furthermore, - if the cursor has been created with NO SCROLL, - no random access is allowed. - - - - - - Implement SQL-compatible options FIRST, - LAST, ABSOLUTE n, - RELATIVE n for - FETCH and MOVE (Tom) - - - - - Allow EXPLAIN on DECLARE CURSOR (Tom) - - - - Allow CLUSTER to use index marked as pre-clustered by default (Alvaro Herrera) - - - - Allow CLUSTER to cluster all tables (Alvaro Herrera) - - This allows all previously clustered tables in a database to be - reclustered with a single command. - - - - Prevent CLUSTER on partial indexes (Tom) - - Allow DOS and Mac line-endings in COPY files (Bruce) - - - - Disallow literal carriage return as a data value, - backslash-carriage-return and \r are still allowed - (Bruce) - - - - - COPY changes (binary, \.) (Tom) - - - - Recover from COPY failure cleanly (Tom) - - - - Prevent possible memory leaks in COPY (Tom) - - - - Make TRUNCATE transaction-safe (Rod) - - TRUNCATE can now be used inside a - transaction. If the transaction aborts, the changes made by the - TRUNCATE are automatically rolled back. - - - - - - Allow prepare/bind of utility commands like - FETCH and EXPLAIN (Tom) - - - - - Add EXPLAIN EXECUTE (Neil) - - - - Improve VACUUM performance on indexes by reducing WAL traffic (Tom) - - - - Functional indexes have been generalized into indexes on expressions (Tom) - - In prior releases, functional indexes only supported a simple - function applied to one or more column names. This release - allows any type of scalar expression. - - - - - - Have SHOW TRANSACTION ISOLATION match input - to SET TRANSACTION ISOLATION - (Tom) - - - - - - Have COMMENT ON DATABASE on nonlocal - database generate a warning, rather than an error (Rod) - - - - Database comments are stored in database-local tables so - comments on a database have to be stored in each database. - - - - - - Improve reliability of LISTEN/NOTIFY (Tom) - - - - - Allow REINDEX to reliably reindex nonshared system catalog indexes (Tom) - - This allows system tables to be reindexed without the - requirement of a standalone session, which was necessary in - previous releases. The only tables that now require a standalone - session for reindexing are the global system tables - pg_database, pg_shadow, and - pg_group. - - - - - - - Data Type and Function Changes - - - - - New server parameter extra_float_digits to - control precision display of floating-point numbers (Pedro - Ferreira, Tom) - - - This controls output precision which was causing regression - testing problems. - - - - Allow +1300 as a numeric time-zone specifier, for FJST (Tom) - - - - Remove rarely used functions oidrand, - oidsrand, and userfntest functions - (Neil) - - - - - Add md5() function to main server, already in contrib/pgcrypto (Joe) - - An MD5 function was frequently requested. For more complex - encryption capabilities, use - contrib/pgcrypto. - - - - Increase date range of timestamp (John Cochran) - - - - Change EXTRACT(EPOCH FROM timestamp) so - timestamp without time zone is assumed to be in - local time, not GMT (Tom) - - - - Trap division by zero in case the operating system doesn't prevent it (Tom) - Change the numeric data type internally to base 10000 (Tom) - New hostmask() function (Greg Wickham) - Fixes for to_char() and to_timestamp() (Karel) - - - - Allow functions that can take any argument data type and return - any data type, using anyelement and - anyarray (Joe) - - - This allows the creation of functions that can work with any - data type. - - - - - - Arrays can now be specified as ARRAY[1,2,3], - ARRAY[['a','b'],['c','d']], or - ARRAY[ARRAY[ARRAY[2]]] (Joe) - - - - - - Allow proper comparisons for arrays, including ORDER - BY and DISTINCT support - (Joe) - - - - Allow indexes on array columns (Joe) - Allow array concatenation with || (Joe) - - - - Allow WHERE qualification - expr op ANY/SOME/ALL - (array_expr) (Joe) - - - This allows arrays to behave like a list of values, for purposes - like SELECT * FROM tab WHERE col IN - (array_val). - - - - - - New array functions array_append, - array_cat, array_lower, - array_prepend, array_to_string, - array_upper, string_to_array (Joe) - - - - Allow user defined aggregates to use polymorphic functions (Joe) - Allow assignments to empty arrays (Joe) - - - - Allow 60 in seconds fields of time, - timestamp, and interval input values - (Tom) - - - Sixty-second values are needed for leap seconds. - - - - Allow cidr data type to be cast to text (Tom) - - Disallow invalid time zone names in SET TIMEZONE - - - - Trim trailing spaces when char is cast to - varchar or text (Tom) - - - - - - Make float(p) measure the precision - p in binary digits, not decimal digits - (Tom) - - - - - Add IPv6 support to the inet and cidr data types (Michael Graff) - - - - Add family() function to report whether address is IPv4 or IPv6 (Michael Graff) - - - - - Have SHOW datestyle generate output similar - to that used by SET datestyle (Tom) - - - - - - Make EXTRACT(TIMEZONE) and SET/SHOW - TIME ZONE follow the SQL convention for the sign of - time zone offsets, i.e., positive is east from UTC (Tom) - - - - - Fix date_trunc('quarter', ...) (Böjthe Zoltán) - - Prior releases returned an incorrect value for this function call. - - - - - Make initcap() more compatible with Oracle (Mike Nolan) - - initcap() now uppercases a letter appearing - after any non-alphanumeric character, rather than only after - whitespace. - - - - - Allow only datestyle field order for date values not in ISO-8601 format (Greg) - - - - - Add new datestyle values MDY, - DMY, and YMD to set input field order; - honor US and European for backward - compatibility (Tom) - - - - - - String literals like 'now' or - 'today' will no longer work as a column - default. Use functions such as now(), - current_timestamp instead. (change - required for prepared statements) (Tom) - - - - - Treat NaN as larger than any other value in min()/max() (Tom) - - NaN was already sorted after ordinary numeric values for most - purposes, but min() and max() didn't - get this right. - - - - - Prevent interval from suppressing :00 - seconds display - - - - - New functions pg_get_triggerdef(prettyprint) - and pg_conversion_is_visible() (Christopher) - - - - - Allow time to be specified as 040506 or 0405 (Tom) - - - - - Input date order must now be YYYY-MM-DD (with 4-digit year) or - match datestyle - - - - - - Make pg_get_constraintdef support - unique, primary-key, and check constraints (Christopher) - - - - - - - Server-Side Language Changes - - - - - Prevent PL/pgSQL crash when RETURN NEXT is - used on a zero-row record variable (Tom) - - - - - - Make PL/Python's spi_execute interface - handle null values properly (Andrew Bosma) - - - - - Allow PL/pgSQL to declare variables of composite types without %ROWTYPE (Tom) - - - - Fix PL/Python's _quote() function to handle big integers - - - - Make PL/Python an untrusted language, now called plpythonu (Kevin Jacobs, Tom) - - The Python language no longer supports a restricted execution - environment, so the trusted version of PL/Python was removed. If - this situation changes, a version of PL/Python that can be used - by non-superusers will be readded. - - - - - Allow polymorphic PL/pgSQL functions (Joe, Tom) - - - - Allow polymorphic SQL functions (Joe) - - - - - Improved compiled function caching mechanism in PL/pgSQL with - full support for polymorphism (Joe) - - - - - - Add new parameter $0 in PL/pgSQL representing the - function's actual return type (Joe) - - - - - - Allow PL/Tcl and PL/Python to use the same trigger on multiple tables (Tom) - - - - - - Fixed PL/Tcl's spi_prepare to accept fully - qualified type names in the parameter type list - (Jan) - - - - - - - psql Changes - - - - Add \pset pager always to always use pager (Greg) - - This forces the pager to be used even if the number of rows is - less than the screen height. This is valuable for rows that - wrap across several screen rows. - - - - Improve tab completion (Rod, Ross Reedstrom, Ian Barwick) - Reorder \? help into groupings (Harald Armin Massa, Bruce) - Add backslash commands for listing schemas, casts, and conversions (Christopher) - - - - \encoding now changes based on the server parameter - client_encoding (Tom) - - - In previous versions, \encoding was not aware - of encoding changes made using SET - client_encoding. - - - - - Save editor buffer into readline history (Ross) - - When \e is used to edit a query, the result is saved - in the readline history for retrieval using the up arrow. - - - - Improve \d display (Christopher) - Enhance HTML mode to be more standards-conforming (Greg) - - - New \set AUTOCOMMIT off capability (Tom) - - This takes the place of the removed server parameter autocommit. - - - - - New \set VERBOSITY to control error detail (Tom) - - This controls the new error reporting details. - - - - New prompt escape sequence %x to show transaction status (Tom) - Long options for psql are now available on all platforms - - - - - pg_dump Changes - - - Multiple pg_dump fixes, including tar format and large objects - Allow pg_dump to dump specific schemas (Neil) - - - Make pg_dump preserve column storage characteristics (Christopher) - - This preserves ALTER TABLE ... SET STORAGE information. - - - - Make pg_dump preserve CLUSTER characteristics (Christopher) - - - - Have pg_dumpall use GRANT/REVOKE to dump database-level privileges (Tom) - - - - - - Allow pg_dumpall to support the options , - , of pg_dump (Tom) - - - - Prevent pg_dump from lowercasing identifiers specified on the command line (Tom) - - - - pg_dump options - and now do nothing, all dumps - use SET SESSION AUTHORIZATION - - - pg_dump no longer reconnects to switch users, but instead always - uses SET SESSION AUTHORIZATION. This will - reduce password prompting during restores. - - - - - Long options for pg_dump are now available on all platforms - - PostgreSQL now includes its own - long-option processing routines. - - - - - - - libpq Changes - - - - - Add function PQfreemem for freeing memory on - Windows, suggested for NOTIFY (Bruce) - - - Windows requires that memory allocated in a library be freed by - a function in the same library, hence - free() doesn't work for freeing memory - allocated by libpq. PQfreemem is the proper - way to free libpq memory, especially on Windows, and is - recommended for other platforms as well. - - - - - Document service capability, and add sample file (Bruce) - - This allows clients to look up connection information in a - central file on the client machine. - - - - - - Make PQsetdbLogin have the same defaults as - PQconnectdb (Tom) - - - - Allow libpq to cleanly fail when result sets are too large (Tom) - - - - Improve performance of function PQunescapeBytea (Ben Lamb) - - - - - - Allow thread-safe libpq with configure - option (Lee Kindness, - Philip Yarra) - - - - - - Allow function pqInternalNotice to accept a - format string and arguments instead of just a preformatted - message (Tom, Sean Chittenden) - - - - - - Control SSL negotiation with sslmode values - disable, allow, - prefer, and require (Jon - Jensen) - - - - - Allow new error codes and levels of text (Tom) - - - - Allow access to the underlying table and column of a query result (Tom) - - This is helpful for query-builder applications that want to know - the underlying table and column names associated with a specific - result set. - - - - Allow access to the current transaction status (Tom) - Add ability to pass binary data directly to the server (Tom) - - - - Add function PQexecPrepared and - PQsendQueryPrepared functions which perform - bind/execute of previously prepared statements (Tom) - - - - - - - JDBC Changes - - - Allow setNull on updateable result sets - Allow executeBatch on a prepared statement (Barry) - Support SSL connections (Barry) - Handle schema names in result sets (Paul Sorenson) - Add refcursor support (Nic Ferrier) - - - - - Miscellaneous Interface Changes - - - - Prevent possible memory leak or core dump during libpgtcl shutdown (Tom) - - - Add Informix compatibility to ECPG (Michael) - - This allows ECPG to process embedded C programs that were - written using certain Informix extensions. - - - - - Add type decimal to ECPG that is fixed length, for Informix (Michael) - - - - - Allow thread-safe embedded SQL programs with - configure option - (Lee Kindness, Bruce) - - - This allows multiple threads to access the database at the same - time. - - - - - Moved Python client PyGreSQL to (Marc) - - - - - - Source Code Changes - - - Prevent need for separate platform geometry regression result files (Tom) - Improved PPC locking primitive (Reinhard Max) - New function palloc0 to allocate and clear memory (Bruce) - Fix locking code for s390x CPU (64-bit) (Tom) - Allow OpenBSD to use local ident credentials (William Ahern) - Make query plan trees read-only to executor (Tom) - Add macOS startup scripts (David Wheeler) - Allow libpq to compile with Borland C++ compiler (Lester Godwin, Karl Waclawek) - Use our own version of getopt_long() if needed (Peter) - Convert administration scripts to C (Peter) - Bison >= 1.85 is now required to build the PostgreSQL grammar, if building from CVS - Merge documentation into one book (Peter) - Add Windows compatibility functions (Bruce) - Allow client interfaces to compile under MinGW (Bruce) - New ereport() function for error reporting (Tom) - Support Intel compiler on Linux (Peter) - Improve Linux startup scripts (Slawomir Sudnik, Darko Prenosil) - Add support for AMD Opteron and Itanium (Jeffrey W. Baker, Bruce) - - Remove option from configure - - This was no longer needed now that we have CREATE CONVERSION. - - - - Generate a compile error if spinlock code is not found (Bruce) - - Platforms without spinlock code will now fail to compile, rather - than silently using semaphores. This failure can be disabled - with a new configure option. - - - - - - - Contrib Changes - - - Change dbmirror license to BSD - Improve earthdistance (Bruno Wolff III) - Portability improvements to pgcrypto (Marko Kreen) - Prevent crash in xml (John Gray, Michael Richards) - Update oracle - Update mysql - Update cube (Bruno Wolff III) - Update earthdistance to use cube (Bruno Wolff III) - Update btree_gist (Oleg) - New tsearch2 full-text search module (Oleg, Teodor) - Add hash-based crosstab function to tablefuncs (Joe) - Add serial column to order connectby() siblings in tablefuncs (Nabil Sayegh,Joe) - Add named persistent connections to dblink (Shridhar Daithanka) - New pg_autovacuum allows automatic VACUUM (Matthew T. O'Connor) - Make pgbench honor environment variables PGHOST, PGPORT, PGUSER (Tatsuo) - Improve intarray (Teodor Sigaev) - Improve pgstattuple (Rod) - Fix bug in metaphone() in fuzzystrmatch - Improve adddepend (Rod) - Update spi/timetravel (Böjthe Zoltán) - Fix dbase option and improve non-ASCII handling (Thomas Behr, Márcio Smiderle) - Remove array module because features now included by default (Joe) - - - - diff --git a/doc/src/sgml/release-8.0.sgml b/doc/src/sgml/release-8.0.sgml deleted file mode 100644 index 6171e0d1eee..00000000000 --- a/doc/src/sgml/release-8.0.sgml +++ /dev/null @@ -1,5421 +0,0 @@ - - - - - Release 8.0.26 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 8.0.25. - For information about new features in the 8.0 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 8.0.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 8.0.26 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.22, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Defend against functions returning setof record where not all the - returned rows are actually of the same rowtype (Tom Lane) - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Avoid recursion while assigning XIDs to heavily-nested - subtransactions (Andres Freund, Robert Haas) - - - - The original coding could result in a crash if there was limited - stack space. - - - - - - Fix log_line_prefix's %i escape, - which could produce junk early in backend startup (Tom Lane) - - - - - - Fix possible data corruption in ALTER TABLE ... SET - TABLESPACE when archiving is enabled (Jeff Davis) - - - - - - Allow CREATE DATABASE and ALTER DATABASE ... SET - TABLESPACE to be interrupted by query-cancel (Guillaume Lelarge) - - - - - - In PL/Python, defend against null pointer results from - PyCObject_AsVoidPtr and PyCObject_FromVoidPtr - (Peter Eisentraut) - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Fix contrib/dblink to handle connection names longer than - 62 bytes correctly (Itagaki Takahiro) - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - Update time zone data files to tzdata release 2010l - for DST law changes in Egypt and Palestine; also historical corrections - for Finland. - - - - This change also adds new names for two Micronesian timezones: - Pacific/Chuuk is now preferred over Pacific/Truk (and the preferred - abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over - Pacific/Ponape. - - - - - - - - - - Release 8.0.25 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 8.0.24. - For information about new features in the 8.0 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.0.X release series in July 2010. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.0.25 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.22, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Prevent infinite recursion in psql when expanding - a variable that refers to itself (Tom) - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - Update time zone data files to tzdata release 2010j - for DST law changes in Argentina, Australian Antarctic, Bangladesh, - Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; - also historical corrections for Taiwan. - - - - - - - - - - Release 8.0.24 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 8.0.23. - For information about new features in the 8.0 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.0.X release series in July 2010. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.0.24 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.22, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Fix possible crashes when trying to recover from a failure in - subtransaction start (Tom) - - - - - - Fix server memory leak associated with use of savepoints and a client - encoding different from server's encoding (Tom) - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix integer-to-bit-string conversions to handle the first fractional - byte correctly when the output bit width is wider than the given - integer by something other than a multiple of 8 bits (Tom) - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - Fix the STOP WAL LOCATION entry in backup history files to - report the next WAL segment's name when the end location is exactly at a - segment boundary (Itagaki Takahiro) - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Fix plpgsql failure in one case where a composite column is set to NULL - (Tom) - - - - - - Add volatile markings in PL/Python to avoid possible - compiler-specific misbehavior (Zdenek Kotala) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - Fix assorted crashes in contrib/xml2 caused by sloppy - memory management (Tom) - - - - - - Update time zone data files to tzdata release 2010e - for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa. - - - - - - - - - - Release 8.0.23 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 8.0.22. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.23 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.22, - see . - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Fix premature drop of temporary files used for a cursor that is accessed - within a subtransaction (Heikki) - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Fix rare crash in exception processing in PL/Python (Peter) - - - - - - Ensure psql's flex module is compiled with the correct - system header definitions (Tom) - - - - This fixes build failures on platforms where - --enable-largefile causes incompatible changes in the - generated code. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - Update time zone data files to tzdata release 2009s - for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, - Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical - corrections for Hong Kong. - - - - - - - - - - Release 8.0.22 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 8.0.21. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.22 - - - A dump/restore is not required for those running 8.0.X. - However, if you have any hash indexes on interval columns, - you must REINDEX them after updating to 8.0.22. - Also, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Fix handling of sub-SELECTs appearing in the arguments of - an outer-level aggregate function (Tom) - - - - - - Fix hash calculation for data type interval (Tom) - - - - This corrects wrong results for hash joins on interval values. - It also changes the contents of hash indexes on interval columns. - If you have any such indexes, you must REINDEX them - after updating. - - - - - - Treat to_char(..., 'TH') as an uppercase ordinal - suffix with 'HH'/'HH12' (Heikki) - - - - It was previously handled as 'th' (lowercase). - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Fix calculation of distance between a point and a line segment (Tom) - - - - This led to incorrect results from a number of geometric operators. - - - - - - Fix money data type to work in locales where currency - amounts have no fractional digits, e.g. Japan (Itagaki Takahiro) - - - - - - Properly round datetime input like - 00:12:57.9999999999999999999999999999 (Tom) - - - - - - Fix poor choice of page split point in GiST R-tree operator classes - (Teodor) - - - - - - Fix portability issues in plperl initialization (Andrew Dunstan) - - - - - - Fix pg_ctl to not go into an infinite loop if - postgresql.conf is empty (Jeff Davis) - - - - - - Fix contrib/xml2's xslt_process() to - properly handle the maximum number of parameters (twenty) (Tom) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - Update time zone data files to tzdata release 2009l - for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, - Argentina/San_Luis, Cuba, Jordan (historical correction only), - Mauritius, Morocco, Palestine, Syria, Tunisia. - - - - - - - - - - Release 8.0.21 - - - Release date: - 2009-03-16 - - - - This release contains a variety of fixes from 8.0.20. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.21 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Prevent error recursion crashes when encoding conversion fails (Tom) - - - - This change extends fixes made in the last two minor releases for - related failure scenarios. The previous fixes were narrowly tailored - for the original problem reports, but we have now recognized that - any error thrown by an encoding conversion function could - potentially lead to infinite recursion while trying to report the - error. The solution therefore is to disable translation and encoding - conversion and report the plain-ASCII form of any error message, - if we find we have gotten into a recursive error reporting situation. - (CVE-2009-0922) - - - - - - Disallow CREATE CONVERSION with the wrong encodings - for the specified conversion function (Heikki) - - - - This prevents one possible scenario for encoding conversion failure. - The previous change is a backstop to guard against other kinds of - failures in the same area. - - - - - - Fix core dump when to_char() is given format codes that - are inappropriate for the type of the data argument (Tom) - - - - - - Add MUST (Mauritius Island Summer Time) to the default list - of known timezone abbreviations (Xavier Bugaud) - - - - - - - - - - Release 8.0.20 - - - Release date: - 2009-02-02 - - - - This release contains a variety of fixes from 8.0.19. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.20 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Improve handling of URLs in headline() function (Teodor) - - - - - - Improve handling of overlength headlines in headline() - function (Teodor) - - - - - - Prevent possible Assert failure or misconversion if an encoding - conversion is created with the wrong conversion function for the - specified pair of encodings (Tom, Heikki) - - - - - - Avoid unnecessary locking of small tables in VACUUM - (Heikki) - - - - - - Fix uninitialized variables in contrib/tsearch2's - get_covers() function (Teodor) - - - - - - Make all documentation reference pgsql-bugs and/or - pgsql-hackers as appropriate, instead of the - now-decommissioned pgsql-ports and pgsql-patches - mailing lists (Tom) - - - - - - Update time zone data files to tzdata release 2009a (for - Kathmandu and historical DST corrections in Switzerland, Cuba) - - - - - - - - - - Release 8.0.19 - - - Release date: - 2008-11-03 - - - - This release contains a variety of fixes from 8.0.18. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.19 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Fix backend crash when the client encoding cannot represent a localized - error message (Tom) - - - - We have addressed similar issues before, but it would still fail if - the character has no equivalent message itself couldn't - be converted. The fix is to disable localization and send the plain - ASCII error message when we detect such a situation. - - - - - - Fix possible crash when deeply nested functions are invoked from - a trigger (Tom) - - - - - - Ensure an error is reported when a newly-defined PL/pgSQL trigger - function is invoked as a normal function (Tom) - - - - - - Fix incorrect tsearch2 headline generation when single query - item matches first word of text (Sushant Sinha) - - - - - - Fix improper display of fractional seconds in interval values when - using a non-ISO datestyle in an - build (Ron Mayer) - - - - - - Ensure SPI_getvalue and SPI_getbinval - behave correctly when the passed tuple and tuple descriptor have - different numbers of columns (Tom) - - - - This situation is normal when a table has had columns added or removed, - but these two functions didn't handle it properly. - The only likely consequence is an incorrect error indication. - - - - - - Fix ecpg's parsing of CREATE USER (Michael) - - - - - - Fix recent breakage of pg_ctl restart (Tom) - - - - - - Update time zone data files to tzdata release 2008i (for - DST law changes in Argentina, Brazil, Mauritius, Syria) - - - - - - - - - - Release 8.0.18 - - - Release date: - 2008-09-22 - - - - This release contains a variety of fixes from 8.0.17. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.18 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Widen local lock counters from 32 to 64 bits (Tom) - - - - This responds to reports that the counters could overflow in - sufficiently long transactions, leading to unexpected lock is - already held errors. - - - - - - Add checks in executor startup to ensure that the tuples produced by an - INSERT or UPDATE will match the target table's - current rowtype (Tom) - - - - ALTER COLUMN TYPE, followed by re-use of a previously - cached plan, could produce this type of situation. The check protects - against data corruption and/or crashes that could ensue. - - - - - - Fix datetime input functions to correctly detect integer overflow when - running on a 64-bit platform (Tom) - - - - - - Improve performance of writing very long log messages to syslog (Tom) - - - - - - Fix bug in backwards scanning of a cursor on a SELECT DISTINCT - ON query (Tom) - - - - - - Fix planner to estimate that GROUP BY expressions yielding - boolean results always result in two groups, regardless of the - expressions' contents (Tom) - - - - This is very substantially more accurate than the regular GROUP - BY estimate for certain boolean tests like col - IS NULL. - - - - - - Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful - about the encoding of data sent to or from Tcl (Tom) - - - - - - Fix PL/Python to work with Python 2.5 - - - - This is a back-port of fixes made during the 8.2 development cycle. - - - - - - Improve pg_dump and pg_restore's - error reporting after failure to send a SQL command (Tom) - - - - - - Fix pg_ctl to properly preserve postmaster - command-line arguments across a restart (Bruce) - - - - - - Update time zone data files to tzdata release 2008f (for - DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco, - Pakistan, Palestine, and Paraguay) - - - - - - - - - - Release 8.0.17 - - - Release date: - 2008-06-12 - - - - This release contains one serious bug fix over 8.0.16. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.17 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Make pg_get_ruledef() parenthesize negative constants (Tom) - - - - Before this fix, a negative constant in a view or rule might be dumped - as, say, -42::integer, which is subtly incorrect: it should - be (-42)::integer due to operator precedence rules. - Usually this would make little difference, but it could interact with - another recent patch to cause - PostgreSQL to reject what had been a valid - SELECT DISTINCT view query. Since this could result in - pg_dump output failing to reload, it is being treated - as a high-priority fix. The only released versions in which dump - output is actually incorrect are 8.3.1 and 8.2.7. - - - - - - - - - - Release 8.0.16 - - - Release date: - never released - - - - This release contains a variety of fixes from 8.0.15. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.16 - - - A dump/restore is not required for those running 8.0.X. - However, if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new - column is correctly checked to see if it's been initialized to all - non-nulls (Brendan Jurd) - - - - Previous versions neglected to check this requirement at all. - - - - - - Fix possible CREATE TABLE failure when inheriting the - same constraint from multiple parent relations that - inherited that constraint from a common ancestor (Tom) - - - - - - Fix conversions between ISO-8859-5 and other encodings to handle - Cyrillic Yo characters (e and E with - two dots) (Sergey Burladyan) - - - - - - Fix a few datatype input functions - that were allowing unused bytes in their results to contain - uninitialized, unpredictable values (Tom) - - - - This could lead to failures in which two apparently identical literal - values were not seen as equal, resulting in the parser complaining - about unmatched ORDER BY and DISTINCT - expressions. - - - - - - Fix a corner case in regular-expression substring matching - (substring(string from - pattern)) (Tom) - - - - The problem occurs when there is a match to the pattern overall but - the user has specified a parenthesized subexpression and that - subexpression hasn't got a match. An example is - substring('foo' from 'foo(bar)?'). - This should return NULL, since (bar) isn't matched, but - it was mistakenly returning the whole-pattern match instead (ie, - foo). - - - - - - Update time zone data files to tzdata release 2008c (for - DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba, - Argentina/San_Luis, and Chile) - - - - - - Fix incorrect result from ecpg's - PGTYPEStimestamp_sub() function (Michael) - - - - - - Fix core dump in contrib/xml2's - xpath_table() function when the input query returns a - NULL value (Tom) - - - - - - Fix contrib/xml2's makefile to not override - CFLAGS (Tom) - - - - - - Fix DatumGetBool macro to not fail with gcc - 4.3 (Tom) - - - - This problem affects old style (V0) C functions that - return boolean. The fix is already in 8.3, but the need to - back-patch it was not realized at the time. - - - - - - Fix longstanding LISTEN/NOTIFY - race condition (Tom) - - - - In rare cases a session that had just executed a - LISTEN might not get a notification, even though - one would be expected because the concurrent transaction executing - NOTIFY was observed to commit later. - - - - A side effect of the fix is that a transaction that has executed - a not-yet-committed LISTEN command will not see any - row in pg_listener for the LISTEN, - should it choose to look; formerly it would have. This behavior - was never documented one way or the other, but it is possible that - some applications depend on the old behavior. - - - - - - Fix rare crash when an error occurs during a query using a hash index - (Heikki) - - - - - - Fix input of datetime values for February 29 in years BC (Tom) - - - - The former coding was mistaken about which years were leap years. - - - - - - Fix unrecognized node type error in some variants of - ALTER OWNER (Tom) - - - - - - Fix pg_ctl to correctly extract the postmaster's port - number from command-line options (Itagaki Takahiro, Tom) - - - - Previously, pg_ctl start -w could try to contact the - postmaster on the wrong port, leading to bogus reports of startup - failure. - - - - - - Use to defend against possible misoptimization - in recent gcc versions (Tom) - - - - This is known to be necessary when building PostgreSQL - with gcc 4.3 or later. - - - - - - Fix display of constant expressions in ORDER BY - and GROUP BY (Tom) - - - - An explicitly casted constant would be shown incorrectly. This could - for example lead to corruption of a view definition during - dump and reload. - - - - - - Fix libpq to handle NOTICE messages correctly - during COPY OUT (Tom) - - - - This failure has only been observed to occur when a user-defined - datatype's output routine issues a NOTICE, but there is no - guarantee it couldn't happen due to other causes. - - - - - - - - - - Release 8.0.15 - - - Release date: - 2008-01-07 - - - - This release contains a variety of fixes from 8.0.14, - including fixes for significant security issues. - For information about new features in the 8.0 major release, see - . - - - - This is the last 8.0.X release for which the PostgreSQL - community will produce binary packages for Windows. - Windows users are encouraged to move to 8.2.X or later, - since there are Windows-specific fixes in 8.2.X that - are impractical to back-port. 8.0.X will continue to - be supported on other platforms. - - - - Migration to Version 8.0.15 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Prevent functions in indexes from executing with the privileges of - the user running VACUUM, ANALYZE, etc (Tom) - - - - Functions used in index expressions and partial-index - predicates are evaluated whenever a new table entry is made. It has - long been understood that this poses a risk of trojan-horse code - execution if one modifies a table owned by an untrustworthy user. - (Note that triggers, defaults, check constraints, etc. pose the - same type of risk.) But functions in indexes pose extra danger - because they will be executed by routine maintenance operations - such as VACUUM FULL, which are commonly performed - automatically under a superuser account. For example, a nefarious user - can execute code with superuser privileges by setting up a - trojan-horse index definition and waiting for the next routine vacuum. - The fix arranges for standard maintenance operations - (including VACUUM, ANALYZE, REINDEX, - and CLUSTER) to execute as the table owner rather than - the calling user, using the same privilege-switching mechanism already - used for SECURITY DEFINER functions. To prevent bypassing - this security measure, execution of SET SESSION - AUTHORIZATION and SET ROLE is now forbidden within a - SECURITY DEFINER context. (CVE-2007-6600) - - - - - - Repair assorted bugs in the regular-expression package (Tom, Will Drewry) - - - - Suitably crafted regular-expression patterns could cause crashes, - infinite or near-infinite looping, and/or massive memory consumption, - all of which pose denial-of-service hazards for applications that - accept regex search patterns from untrustworthy sources. - (CVE-2007-4769, CVE-2007-4772, CVE-2007-6067) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - The fix that appeared for this in 8.0.14 was incomplete, as it plugged - the hole for only some dblink functions. (CVE-2007-6601, - CVE-2007-3278) - - - - - - Update time zone data files to tzdata release 2007k - (in particular, recent Argentina changes) (Tom) - - - - - - Fix planner failure in some cases of WHERE false AND var IN - (SELECT ...) (Tom) - - - - - - Preserve the tablespace of indexes that are - rebuilt by ALTER TABLE ... ALTER COLUMN TYPE (Tom) - - - - - - Make archive recovery always start a new WAL timeline, rather than only - when a recovery stop time was used (Simon) - - - - This avoids a corner-case risk of trying to overwrite an existing - archived copy of the last WAL segment, and seems simpler and cleaner - than the original definition. - - - - - - Make VACUUM not use all of maintenance_work_mem - when the table is too small for it to be useful (Alvaro) - - - - - - Fix potential crash in translate() when using a multibyte - database encoding (Tom) - - - - - - Fix PL/Perl to cope when platform's Perl defines type bool - as int rather than char (Tom) - - - - While this could theoretically happen anywhere, no standard build of - Perl did things this way ... until macOS 10.5. - - - - - - Fix PL/Python to not crash on long exception messages (Alvaro) - - - - - - Fix pg_dump to correctly handle inheritance child tables - that have default expressions different from their parent's (Tom) - - - - - - ecpg parser fixes (Michael) - - - - - - Make contrib/tablefunc's crosstab() handle - NULL rowid as a category in its own right, rather than crashing (Joe) - - - - - - Fix tsvector and tsquery output routines to - escape backslashes correctly (Teodor, Bruce) - - - - - - Fix crash of to_tsvector() on huge input strings (Teodor) - - - - - - Require a specific version of Autoconf to be used - when re-generating the configure script (Peter) - - - - This affects developers and packagers only. The change was made - to prevent accidental use of untested combinations of - Autoconf and PostgreSQL versions. - You can remove the version check if you really want to use a - different Autoconf version, but it's - your responsibility whether the result works or not. - - - - - - - - - - Release 8.0.14 - - - Release date: - 2007-09-17 - - - - This release contains a variety of fixes from 8.0.13. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.14 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Prevent index corruption when a transaction inserts rows and - then aborts close to the end of a concurrent VACUUM - on the same table (Tom) - - - - - - Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom) - - - - - - Fix excessive logging of SSL error messages (Tom) - - - - - - Fix logging so that log messages are never interleaved when using - the syslogger process (Andrew) - - - - - - Fix crash when log_min_error_statement logging runs out - of memory (Tom) - - - - - - Fix incorrect handling of some foreign-key corner cases (Tom) - - - - - - Prevent CLUSTER from failing - due to attempting to process temporary tables of other sessions (Alvaro) - - - - - - Update the time zone database rules, particularly New Zealand's upcoming changes (Tom) - - - - - - Windows socket improvements (Magnus) - - - - - - Suppress timezone name (%Z) in log timestamps on Windows - because of possible encoding mismatches (Tom) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - - - - - - - Release 8.0.13 - - - Release date: - 2007-04-23 - - - - This release contains a variety of fixes from 8.0.12, - including a security fix. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.13 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Support explicit placement of the temporary-table schema within - search_path, and disable searching it for functions - and operators (Tom) - - - This is needed to allow a security-definer function to set a - truly secure value of search_path. Without it, - an unprivileged SQL user can use temporary objects to execute code - with the privileges of the security-definer function (CVE-2007-2138). - See CREATE FUNCTION for more information. - - - - - - /contrib/tsearch2 crash fixes (Teodor) - - - - - - Fix potential-data-corruption bug in how VACUUM FULL handles - UPDATE chains (Tom, Pavan Deolasee) - - - - - - Fix PANIC during enlargement of a hash index (bug introduced in 8.0.10) - (Tom) - - - - - - Fix POSIX-style timezone specs to follow new USA DST rules (Tom) - - - - - - - - - - Release 8.0.12 - - - Release date: - 2007-02-07 - - - - This release contains one fix from 8.0.11. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.12 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Remove overly-restrictive check for type length in constraints and - functional indexes(Tom) - - - - - - - - - - Release 8.0.11 - - - Release date: - 2007-02-05 - - - - This release contains a variety of fixes from 8.0.10, including - a security fix. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.11 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Remove security vulnerabilities that allowed connected users - to read backend memory (Tom) - - - The vulnerabilities involve suppressing the normal check that a SQL - function returns the data type it's declared to, and changing the - data type of a table column (CVE-2007-0555, CVE-2007-0556). These - errors can easily be exploited to cause a backend crash, and in - principle might be used to read database content that the user - should not be able to access. - - - - - - Fix rare bug wherein btree index page splits could fail - due to choosing an infeasible split point (Heikki Linnakangas) - - - - - - Fix for rare Assert() crash triggered by UNION (Tom) - - - - - - Tighten security of multi-byte character processing for UTF8 sequences - over three bytes long (Tom) - - - - - - - - - - Release 8.0.10 - - - Release date: - 2007-01-08 - - - - This release contains a variety of fixes from 8.0.9. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.10 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - - - - - Improve handling of getaddrinfo() on AIX (Tom) - - - - This fixes a problem with starting the statistics collector, - among other things. - - - - - - Fix failed to re-find parent key errors in - VACUUM (Tom) - - - - - - Fix race condition for truncation of a large relation across a - gigabyte boundary by VACUUM (Tom) - - - - - - Fix bugs affecting multi-gigabyte hash indexes (Tom) - - - - - - Fix possible deadlock in Windows signal handling (Teodor) - - - - - - Fix error when constructing an ARRAY[] made up of multiple - empty elements (Tom) - - - - - - Fix ecpg memory leak during connection (Michael) - - - - - - to_number() and to_char(numeric) - are now STABLE, not IMMUTABLE, for - new initdb installs (Tom) - - - - This is because lc_numeric can potentially - change the output of these functions. - - - - - - Improve index usage of regular expressions that use parentheses (Tom) - - - - This improves psql \d performance also. - - - - - - Update timezone database - - - - This affects Australian and Canadian daylight-savings rules in - particular. - - - - - - - - - - Release 8.0.9 - - - Release date: - 2006-10-16 - - - - This release contains a variety of fixes from 8.0.8. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.9 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - - Changes - - -Fix crash when referencing NEW row -values in rule WHERE expressions (Tom) -Fix core dump when an untyped literal is taken as -ANYARRAY -Fix mishandling of AFTER triggers when query contains a SQL -function returning multiple rows (Tom) -Fix ALTER TABLE ... TYPE to recheck -NOT NULL for USING clause (Tom) -Fix string_to_array() to handle overlapping - matches for the separator string -For example, string_to_array('123xx456xxx789', 'xx'). - -Fix corner cases in pattern matching for - psql's \d commands -Fix index-corrupting bugs in /contrib/ltree - (Teodor) -Numerous robustness fixes in ecpg (Joachim -Wieland) -Fix backslash escaping in /contrib/dbmirror -Fix instability of statistics collection on Win32 (Tom, Andrew) -Fixes for AIX and -Intel compilers (Tom) - - - - - - - Release 8.0.8 - - - Release date: - 2006-05-23 - - - - This release contains a variety of fixes from 8.0.7, - including patches for extremely serious security issues. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.8 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - Full security against the SQL-injection attacks described in - CVE-2006-2313 and CVE-2006-2314 might require changes in application - code. If you have applications that embed untrustworthy strings - into SQL commands, you should examine them as soon as possible to - ensure that they are using recommended escaping techniques. In - most cases, applications should be using subroutines provided by - libraries or drivers (such as libpq's - PQescapeStringConn()) to perform string escaping, - rather than relying on ad hoc code to do it. - - - - - Changes - - -Change the server to reject invalidly-encoded multibyte -characters in all cases (Tatsuo, Tom) -While PostgreSQL has been moving in this direction for -some time, the checks are now applied uniformly to all encodings and all -textual input, and are now always errors not merely warnings. This change -defends against SQL-injection attacks of the type described in CVE-2006-2313. - - -Reject unsafe uses of \' in string literals -As a server-side defense against SQL-injection attacks of the type -described in CVE-2006-2314, the server now only accepts '' and not -\' as a representation of ASCII single quote in SQL string -literals. By default, \' is rejected only when -client_encoding is set to a client-only encoding (SJIS, BIG5, GBK, -GB18030, or UHC), which is the scenario in which SQL injection is possible. -A new configuration parameter backslash_quote is available to -adjust this behavior when needed. Note that full security against -CVE-2006-2314 might require client-side changes; the purpose of -backslash_quote is in part to make it obvious that insecure -clients are insecure. - - -Modify libpq's string-escaping routines to be -aware of encoding considerations and -standard_conforming_strings -This fixes libpq-using applications for the security -issues described in CVE-2006-2313 and CVE-2006-2314, and also future-proofs -them against the planned changeover to SQL-standard string literal syntax. -Applications that use multiple PostgreSQL connections -concurrently should migrate to PQescapeStringConn() and -PQescapeByteaConn() to ensure that escaping is done correctly -for the settings in use in each database connection. Applications that -do string escaping by hand should be modified to rely on library -routines instead. - - -Fix some incorrect encoding conversion functions -win1251_to_iso, alt_to_iso, -euc_tw_to_big5, euc_tw_to_mic, -mic_to_euc_tw were all broken to varying -extents. - - -Clean up stray remaining uses of \' in strings -(Bruce, Jan) - -Fix bug that sometimes caused OR'd index scans to -miss rows they should have returned - -Fix WAL replay for case where a btree index has been -truncated - -Fix SIMILAR TO for patterns involving -| (Tom) - -Fix SELECT INTO and CREATE TABLE AS to -create tables in the default tablespace, not the base directory (Kris -Jurka) - -Fix server to use custom DH SSL parameters correctly (Michael -Fuhr) - -Fix for Bonjour on Intel Macs (Ashley Clark) - -Fix various minor memory leaks - -Fix problem with password prompting on some Win32 systems -(Robert Kinberg) - - - - - - - Release 8.0.7 - - - Release date: - 2006-02-14 - - - - This release contains a variety of fixes from 8.0.6. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.7 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.6, - see . - - - - - Changes - - - -Fix potential crash in SET -SESSION AUTHORIZATION (CVE-2006-0553) -An unprivileged user could crash the server process, resulting in -momentary denial of service to other users, if the server has been compiled -with Asserts enabled (which is not the default). -Thanks to Akio Ishida for reporting this problem. - - -Fix bug with row visibility logic in self-inserted -rows (Tom) -Under rare circumstances a row inserted by the current command -could be seen as already valid, when it should not be. Repairs bug -created in 8.0.4, 7.4.9, and 7.3.11 releases. - - -Fix race condition that could lead to file already -exists errors during pg_clog and pg_subtrans file creation -(Tom) - -Fix cases that could lead to crashes if a cache-invalidation -message arrives at just the wrong time (Tom) - -Properly check DOMAIN constraints for -UNKNOWN parameters in prepared statements -(Neil) - -Ensure ALTER COLUMN TYPE will process -FOREIGN KEY, UNIQUE, and PRIMARY KEY -constraints in the proper order (Nakano Yoshihisa) - -Fixes to allow restoring dumps that have cross-schema -references to custom operators or operator classes (Tom) - -Allow pg_restore to continue properly after a -COPY failure; formerly it tried to treat the remaining -COPY data as SQL commands (Stephen Frost) - -Fix pg_ctl unregister crash -when the data directory is not specified (Magnus) - -Fix ecpg crash on AMD64 and PPC -(Neil) - -Recover properly if error occurs during argument passing -in PL/Python (Neil) - -Fix PL/Perl's handling of locales on -Win32 to match the backend (Andrew) - -Fix crash when log_min_messages is set to -DEBUG3 or above in postgresql.conf on Win32 -(Bruce) - -Fix pgxs -L library path -specification for Win32, Cygwin, macOS, AIX (Bruce) - -Check that SID is enabled while checking for Win32 admin -privileges (Magnus) - -Properly reject out-of-range date inputs (Kris -Jurka) - -Portability fix for testing presence of finite -and isinf during configure (Tom) - - - - - - - - Release 8.0.6 - - - Release date: - 2006-01-09 - - - - This release contains a variety of fixes from 8.0.5. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.6 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.3, - see . - Also, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the locale or - plperl issues described below. - - - - - Changes - - - -Fix Windows code so that postmaster will continue rather -than exit if there is no more room in ShmemBackendArray (Magnus) -The previous behavior could lead to a denial-of-service situation if too -many connection requests arrive close together. This applies -only to the Windows port. - -Fix bug introduced in 8.0 that could allow ReadBuffer -to return an already-used page as new, potentially causing loss of -recently-committed data (Tom) - -Fix for protocol-level Describe messages issued -outside a transaction or in a failed transaction (Tom) - -Fix character string comparison for locales that consider -different character combinations as equal, such as Hungarian (Tom) -This might require REINDEX to fix existing indexes on -textual columns. - -Set locale environment variables during postmaster startup -to ensure that plperl won't change the locale later -This fixes a problem that occurred if the postmaster was -started with environment variables specifying a different locale than what -initdb had been told. Under these conditions, any use of -plperl was likely to lead to corrupt indexes. You might need -REINDEX to fix existing indexes on -textual columns if this has happened to you. - -Allow more flexible relocation of installation -directories (Tom) -Previous releases supported relocation only if all installation -directory paths were the same except for the last component. - -Fix longstanding bug in strpos() and regular expression -handling in certain rarely used Asian multi-byte character sets (Tatsuo) - - -Various fixes for functions returning RECORDs -(Tom) - -Fix bug in /contrib/pgcrypto gen_salt, -which caused it not to use all available salt space for MD5 and -XDES algorithms (Marko Kreen, Solar Designer) -Salts for Blowfish and standard DES are unaffected. - -Fix /contrib/dblink to throw an error, -rather than crashing, when the number of columns specified is different from -what's actually returned by the query (Joe) - - - - - - - - Release 8.0.5 - - - Release date: - 2005-12-12 - - - - This release contains a variety of fixes from 8.0.4. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.5 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.3, - see . - - - - - Changes - - - -Fix race condition in transaction log management -There was a narrow window in which an I/O operation could be initiated -for the wrong page, leading to an Assert failure or data -corruption. - - -Fix bgwriter problems after recovering from errors -(Tom) - -The background writer was found to leak buffer pins after write errors. -While not fatal in itself, this might lead to mysterious blockages of -later VACUUM commands. - - - -Prevent failure if client sends Bind protocol message -when current transaction is already aborted - -/contrib/ltree fixes (Teodor) - -AIX and HPUX compile fixes (Tom) - -Retry file reads and writes after Windows -NO_SYSTEM_RESOURCES error (Qingqing Zhou) - -Fix intermittent failure when log_line_prefix -includes %i - -Fix psql performance issue with long scripts -on Windows (Merlin Moncure) - -Fix missing updates of pg_group flat -file - -Fix longstanding planning error for outer joins -This bug sometimes caused a bogus error RIGHT JOIN is -only supported with merge-joinable join conditions. - -Postpone timezone initialization until after -postmaster.pid is created -This avoids confusing startup scripts that expect the pid file to appear -quickly. - -Prevent core dump in pg_autovacuum when a -table has been dropped - -Fix problems with whole-row references (foo.*) -to subquery results - - - - - - - Release 8.0.4 - - - Release date: - 2005-10-04 - - - - This release contains a variety of fixes from 8.0.3. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.4 - - - A dump/restore is not required for those running 8.0.X. However, - if you are upgrading from a version earlier than 8.0.3, - see . - - - - - Changes - - -Fix error that allowed VACUUM to remove -ctid chains too soon, and add more checking in code that follows -ctid links -This fixes a long-standing problem that could cause crashes in very rare -circumstances. -Fix CHAR() to properly pad spaces to the specified -length when using a multiple-byte character set (Yoshiyuki Asaba) -In prior releases, the padding of CHAR() was incorrect -because it only padded to the specified number of bytes without -considering how many characters were stored. -Force a checkpoint before committing CREATE -DATABASE -This should fix recent reports of index is not a btree -failures when a crash occurs shortly after CREATE -DATABASE. -Fix the sense of the test for read-only transaction -in COPY -The code formerly prohibited COPY TO, where it should -prohibit COPY FROM. - -Handle consecutive embedded newlines in COPY -CSV-mode input -Fix date_trunc(week) for dates near year -end -Fix planning problem with outer-join ON clauses that reference -only the inner-side relation -Further fixes for x FULL JOIN y ON true corner -cases -Fix overenthusiastic optimization of x IN (SELECT -DISTINCT ...) and related cases -Fix mis-planning of queries with small LIMIT -values due to poorly thought out fuzzy cost -comparison -Make array_in and array_recv more -paranoid about validating their OID parameter -Fix missing rows in queries like UPDATE a=... WHERE -a... with GiST index on column a -Improve robustness of datetime parsing -Improve checking for partially-written WAL -pages -Improve robustness of signal handling when SSL is -enabled -Improve MIPS and M68K spinlock code -Don't try to open more than max_files_per_process -files during postmaster startup -Various memory leakage fixes -Various portability improvements -Update timezone data files -Improve handling of DLL load failures on Windows -Improve random-number generation on Windows -Make psql -f filename return a nonzero exit code -when opening the file fails -Change pg_dump to handle inherited check -constraints more reliably -Fix password prompting in pg_restore on -Windows -Fix PL/pgSQL to handle var := var correctly when -the variable is of pass-by-reference type -Fix PL/Perl %_SHARED so it's actually -shared -Fix contrib/pg_autovacuum to allow sleep -intervals over 2000 sec -Update contrib/tsearch2 to use current Snowball -code - - - - - - - Release 8.0.3 - - - Release date: - 2005-05-09 - - - - This release contains a variety of fixes from 8.0.2, including several - security-related issues. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.3 - - - A dump/restore is not required for those running 8.0.X. However, - it is one possible way of handling two significant security problems - that have been found in the initial contents of 8.0.X system - catalogs. A dump/initdb/reload sequence using 8.0.3's initdb will - automatically correct these problems. - - - - The larger security problem is that the built-in character set encoding - conversion functions can be invoked from SQL commands by unprivileged - users, but the functions were not designed for such use and are not - secure against malicious choices of arguments. The fix involves changing - the declared parameter list of these functions so that they can no longer - be invoked from SQL commands. (This does not affect their normal use - by the encoding conversion machinery.) - - - - The lesser problem is that the contrib/tsearch2 module - creates several functions that are improperly declared to return - internal when they do not accept internal arguments. - This breaks type safety for all functions using internal - arguments. - - - - It is strongly recommended that all installations repair these errors, - either by initdb or by following the manual repair procedure given - below. The errors at least allow unprivileged database users to crash - their server process, and might allow unprivileged users to gain the - privileges of a database superuser. - - - - If you wish not to do an initdb, perform the same manual repair - procedures shown in the 7.4.8 release - notes. - - - - - Changes - - -Change encoding function signature to prevent -misuse -Change contrib/tsearch2 to avoid unsafe use of -INTERNAL function results -Guard against incorrect second parameter to -record_out -Repair ancient race condition that allowed a transaction to be -seen as committed for some purposes (eg SELECT FOR UPDATE) slightly sooner -than for other purposes -This is an extremely serious bug since it could lead to apparent -data inconsistencies being briefly visible to applications. -Repair race condition between relation extension and -VACUUM -This could theoretically have caused loss of a page's worth of -freshly-inserted data, although the scenario seems of very low probability. -There are no known cases of it having caused more than an Assert failure. - -Fix comparisons of TIME WITH TIME ZONE values - -The comparison code was wrong in the case where the ---enable-integer-datetimes configuration switch had been used. -NOTE: if you have an index on a TIME WITH TIME ZONE column, -it will need to be REINDEXed after installing this update, because -the fix corrects the sort order of column values. - -Fix EXTRACT(EPOCH) for -TIME WITH TIME ZONE values -Fix mis-display of negative fractional seconds in -INTERVAL values - -This error only occurred when the ---enable-integer-datetimes configuration switch had been used. - -Fix pg_dump to dump trigger names containing % -correctly (Neil) -Still more 64-bit fixes for -contrib/intagg -Prevent incorrect optimization of functions returning -RECORD -Prevent crash on COALESCE(NULL,NULL) -Fix Borland makefile for libpq -Fix contrib/btree_gist for timetz type -(Teodor) -Make pg_ctl check the PID found in -postmaster.pid to see if it is still a live -process -Fix pg_dump/pg_restore problems caused -by addition of dump timestamps -Fix interaction between materializing holdable cursors and -firing deferred triggers during transaction commit -Fix memory leak in SQL functions returning pass-by-reference -data types - - - - - - - Release 8.0.2 - - - Release date: - 2005-04-07 - - - - This release contains a variety of fixes from 8.0.1. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.2 - - - A dump/restore is not required for those running 8.0.*. - This release updates the major version number of the - PostgreSQL libraries, so it might be - necessary to re-link some user applications if they cannot - find the properly-numbered shared library. - - - - - Changes - - -Increment the major version number of all interface -libraries (Bruce) - -This should have been done in 8.0.0. It is required so 7.4.X versions -of PostgreSQL client applications, like psql, -can be used on the same machine as 8.0.X applications. This might require -re-linking user applications that use these libraries. - -Add Windows-only wal_sync_method setting of - (Magnus, Bruce) - -This setting causes PostgreSQL to write through -any disk-drive write cache when writing to WAL. -This behavior was formerly called , but was -renamed because it acts quite differently from on other -platforms. - - -Enable the wal_sync_method setting of - on Windows, and make it the default for that - platform (Magnus, Bruce) - -Because the default is no longer , -data loss is possible during a power failure if the disk drive has -write caching enabled. To turn off the write cache on Windows, -from the Device Manager, choose the drive properties, -then Policies. - - -New cache management algorithm 2Q replaces -ARC (Tom) - -This was done to avoid a pending US patent on ARC. The -2Q code might be a few percentage points slower than -ARC for some work loads. A better cache management algorithm -will appear in 8.1. - -Planner adjustments to improve behavior on freshly-created -tables (Tom) -Allow plpgsql to assign to an element of an array that is -initially NULL (Tom) - -Formerly the array would remain NULL, but now it becomes a -single-element array. The main SQL engine was changed to handle -UPDATE of a null array value this way in 8.0, but the similar -case in plpgsql was overlooked. - - -Convert \r\n and \r to \n -in plpython function bodies (Michael Fuhr) - - This prevents syntax errors when plpython code is written on a Windows or - Mac client. - - -Allow SPI cursors to handle utility commands that return rows, -such as EXPLAIN (Tom) -Fix CLUSTER failure after ALTER TABLE -SET WITHOUT OIDS (Tom) -Reduce memory usage of ALTER TABLE ADD COLUMN -(Neil) -Fix ALTER LANGUAGE RENAME (Tom) -Document the Windows-only register and -unregister options of pg_ctl (Magnus) -Ensure operations done during backend shutdown are counted by -statistics collector - -This is expected to resolve reports of pg_autovacuum -not vacuuming the system catalogs often enough — it was not being -told about catalog deletions caused by temporary table removal during -backend exit. - -Change the Windows default for configuration parameter -log_destination to (Magnus) - -By default, a server running on Windows will now send log output to the -Windows event logger rather than standard error. - -Make Kerberos authentication work on Windows (Magnus) -Allow ALTER DATABASE RENAME by superusers -who aren't flagged as having CREATEDB privilege (Tom) -Modify WAL log entries for CREATE and -DROP DATABASE to not specify absolute paths (Tom) -This allows point-in-time recovery on a different machine with possibly -different database location. Note that CREATE TABLESPACE still -poses a hazard in such situations. - -Fix crash from a backend exiting with an open transaction -that created a table and opened a cursor on it (Tom) -Fix array_map() so it can call PL functions -(Tom) -Several contrib/tsearch2 and -contrib/btree_gist fixes (Teodor) - -Fix crash of some contrib/pgcrypto -functions on some platforms (Marko Kreen) -Fix contrib/intagg for 64-bit platforms -(Tom) -Fix ecpg bugs in parsing of CREATE statement -(Michael) -Work around gcc bug on powerpc and amd64 causing problems in -ecpg (Christof Petig) -Do not use locale-aware versions of upper(), -lower(), and initcap() when the locale is -C (Bruce) - - This allows these functions to work on platforms that generate errors - for non-7-bit data when the locale is C. - -Fix quote_ident() to quote names that match keywords (Tom) -Fix to_date() to behave reasonably when -CC and YY fields are both used (Karel) -Prevent to_char(interval) from failing -when given a zero-month interval (Tom) -Fix wrong week returned by date_trunc('week') -(Bruce) - -date_trunc('week') -returned the wrong year for the first few days of January in some years. - -Use the correct default mask length for class D -addresses in INET data types (Tom) - - - - - - - Release 8.0.1 - - - Release date: - 2005-01-31 - - - - This release contains a variety of fixes from 8.0.0, including several - security-related issues. - For information about new features in the 8.0 major release, see - . - - - - Migration to Version 8.0.1 - - - A dump/restore is not required for those running 8.0.0. - - - - - Changes - - -Disallow LOAD to non-superusers - -On platforms that will automatically execute initialization functions of a -shared library (this includes at least Windows and ELF-based Unixen), -LOAD can be used to make the server execute arbitrary code. -Thanks to NGS Software for reporting this. -Check that creator of an aggregate function has the right to -execute the specified transition functions - -This oversight made it possible to bypass denial of EXECUTE -permission on a function. -Fix security and 64-bit issues in -contrib/intagg -Add needed STRICT marking to some contrib functions (Kris -Jurka) -Avoid buffer overrun when plpgsql cursor declaration has too -many parameters (Neil) -Make ALTER TABLE ADD COLUMN enforce domain -constraints in all cases -Fix planning error for FULL and RIGHT outer joins - -The result of the join was mistakenly supposed to be sorted the same as the -left input. This could not only deliver mis-sorted output to the user, but -in case of nested merge joins could give outright wrong answers. - -Improve planning of grouped aggregate queries -ROLLBACK TO savepoint -closes cursors created since the savepoint -Fix inadequate backend stack size on Windows -Avoid SHGetSpecialFolderPath() on Windows -(Magnus) -Fix some problems in running pg_autovacuum as a Windows -service (Dave Page) -Multiple minor bug fixes in -pg_dump/pg_restore -Fix ecpg segfault with named structs used in -typedefs (Michael) - - - - - - - Release 8.0 - - - Release date: - 2005-01-19 - - - - Overview - - - Major changes in this release: - - - - - - Microsoft Windows Native Server - - - - - This is the first PostgreSQL release - to run natively on Microsoft Windows as - a server. It can run as a Windows service. This - release supports NT-based Windows releases like - Windows 2000 SP4, Windows XP, and - Windows 2003. Older releases like - Windows 95, Windows 98, and - Windows ME are not supported because these operating - systems do not have the infrastructure to support - PostgreSQL. A separate installer - project has been created to ease installation on - Windows — see . - - - - Although tested throughout our release cycle, the Windows port - does not have the benefit of years of use in production - environments that PostgreSQL has on - Unix platforms. Therefore it should be treated with the same - level of caution as you would a new product. - - - - Previous releases required the Unix emulation toolkit - Cygwin in order to run the server on Windows - operating systems. PostgreSQL has - supported native clients on Windows for many years. - - - - - - - Savepoints - - - - - Savepoints allow specific parts of a transaction to be aborted - without affecting the remainder of the transaction. Prior - releases had no such capability; there was no way to recover - from a statement failure within a transaction except by - aborting the whole transaction. This feature is valuable for - application writers who require error recovery within a - complex transaction. - - - - - - - Point-In-Time Recovery - - - - - In previous releases there was no way to recover from disk - drive failure except to restore from a previous backup or use - a standby replication server. Point-in-time recovery allows - continuous backup of the server. You can recover either to - the point of failure or to some transaction in the past. - - - - - - - Tablespaces - - - - - Tablespaces allow administrators to select different file systems - for storage of individual tables, indexes, and databases. - This improves performance and control over disk space - usage. Prior releases used initlocation and - manual symlink management for such tasks. - - - - - - - Improved Buffer Management, CHECKPOINT, - VACUUM - - - - - This release has a more intelligent buffer replacement strategy, - which will make better use of available shared buffers and - improve performance. The performance impact of vacuum and - checkpoints is also lessened. - - - - - - - Change Column Types - - - - - A column's data type can now be changed with ALTER - TABLE. - - - - - - - New Perl Server-Side Language - - - - - A new version of the plperl server-side language now - supports a persistent shared storage area, triggers, returning records - and arrays of records, and SPI calls to access the database. - - - - - - - Comma-separated-value (CSV) support in COPY - - - - - COPY can now read and write - comma-separated-value files. It has the flexibility to - interpret nonstandard quoting and separation characters too. - - - - - - - - - Migration to Version 8.0 - - - A dump/restore using pg_dump is - required for those wishing to migrate data from any previous - release. - - - - Observe the following incompatibilities: - - - - - - - In serialization mode, volatile functions - now see the results of concurrent transactions committed up to the - beginning of each statement within the function, rather than up to the - beginning of the interactive command that called the function. - - - - - - Functions declared or always - use the snapshot of the calling query, and therefore do not see the - effects of actions taken after the calling query starts, whether in - their own transaction or other transactions. Such a function must be - read-only, too, meaning that it cannot use any SQL commands other than - SELECT. - - - - - - Nondeferred triggers are now fired immediately - after completion of the triggering query, rather than upon - finishing the current interactive command. This makes a - difference when the triggering query occurred within a function: - the trigger is invoked before the function proceeds to its next - operation. - - - - - - Server configuration parameters virtual_host and - tcpip_socket have been replaced with a more general - parameter listen_addresses. Also, the server now listens on - localhost by default, which eliminates the need for the - -i postmaster switch in many scenarios. - - - - - - Server configuration parameters SortMem and - VacuumMem have been renamed to work_mem - and maintenance_work_mem to better reflect their - use. The original names are still supported in - SET and SHOW. - - - - - - Server configuration parameters log_pid, - log_timestamp, and log_source_port have been - replaced with a more general parameter log_line_prefix. - - - - - - Server configuration parameter syslog has been - replaced with a more logical log_destination variable to - control the log output destination. - - - - - - Server configuration parameter log_statement has been - changed so it can selectively log just database modification or - data definition statements. Server configuration parameter - log_duration now prints only when log_statement - prints the query. - - - - - - Server configuration parameter max_expr_depth parameter has - been replaced with max_stack_depth which measures the - physical stack size rather than the expression nesting depth. This - helps prevent session termination due to stack overflow caused by - recursive functions. - - - - - - The length() function no longer counts trailing spaces in - CHAR(n) values. - - - - - - Casting an integer to BIT(N) selects the rightmost N bits of the - integer, not the leftmost N bits as before. - - - - - - Updating an element or slice of a NULL array value now produces - a nonnull array result, namely an array containing - just the assigned-to positions. - - - - - - Syntax checking of array input values has been tightened up - considerably. Junk that was previously allowed in odd places with - odd results now causes an error. Empty-string element values - must now be written as "", rather than writing nothing. - Also changed behavior with respect to whitespace surrounding - array elements: trailing whitespace is now ignored, for symmetry - with leading whitespace (which has always been ignored). - - - - - - Overflow in integer arithmetic operations is now detected and - reported as an error. - - - - - - The arithmetic operators associated with the single-byte - "char" data type have been removed. - - - - - - The extract() function (also called - date_part) now returns the proper year for BC dates. - It previously returned one less than the correct year. The - function now also returns the proper values for millennium and - century. - - - - - - CIDR values now must have their nonmasked bits be zero. - For example, we no longer allow - 204.248.199.1/31 as a CIDR value. Such - values should never have been accepted by - PostgreSQL and will now be rejected. - - - - - - EXECUTE now returns a completion tag that - matches the executed statement. - - - - - - psql's \copy command now reads or - writes to the query's stdin/stdout, rather than - psql's stdin/stdout. The previous - behavior can be accessed via new - / parameters. - - - - - - The JDBC client interface has been removed from the core - distribution, and is now hosted at . - - - - - - The Tcl client interface has also been removed. There are several - Tcl interfaces now hosted at . - - - - - - The server now uses its own time zone database, rather than the - one supplied by the operating system. This will provide consistent - behavior across all platforms. In most cases, there should be - little noticeable difference in time zone behavior, except that - the time zone names used by SET/SHOW - TimeZone might be different from what your platform provides. - - - - - - Configure's threading option no longer requires - users to run tests or edit configuration files; threading options - are now detected automatically. - - - - - - Now that tablespaces have been implemented, - initlocation has been removed. - - - - - - The API for user-defined GiST indexes has been changed. The - Union and PickSplit methods are now passed a pointer to a - special GistEntryVector structure, - rather than a bytea. - - - - - - - - Deprecated Features - - - Some aspects of PostgreSQL's behavior - have been determined to be suboptimal. For the sake of backward - compatibility these have not been removed in 8.0, but they are - considered deprecated and will be removed in the next major - release. - - - - - - The 8.1 release will remove the to_char() function - for intervals. - - - - - - The server now warns of empty strings passed to - oid/float4/float8 data - types, but continues to interpret them as zeroes as before. - In the next major release, empty strings will be considered - invalid input for these data types. - - - - - - By default, tables in PostgreSQL 8.0 - and earlier are created with OIDs. In the next release, - this will not be the case: to create a table - that contains OIDs, the clause must - be specified or the default_with_oids - configuration parameter must be set. Users are encouraged to - explicitly specify if their tables - require OIDs for compatibility with future releases of - PostgreSQL. - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - release 8.0 and the previous major release. - - - - Performance Improvements - - - - - Support cross-data-type index usage (Tom) - - - Before this change, many queries would not use an index if the data - types did not match exactly. This improvement makes index usage more - intuitive and consistent. - - - - - - New buffer replacement strategy that improves caching (Jan) - - - Prior releases used a least-recently-used (LRU) cache to keep - recently referenced pages in memory. The LRU algorithm - did not consider the number of times a specific cache entry was - accessed, so large table scans could force out useful cache pages. - The new cache algorithm uses four separate lists to track most - recently used and most frequently used cache pages and dynamically - optimize their replacement based on the work load. This should - lead to much more efficient use of the shared buffer cache. - Administrators who have tested shared buffer sizes in the past - should retest with this new cache replacement policy. - - - - - - Add subprocess to write dirty buffers periodically to reduce - checkpoint writes (Jan) - - - In previous releases, the checkpoint process, which runs every few - minutes, would write all dirty buffers to the operating system's - buffer cache then flush all dirty operating system buffers to - disk. This resulted in a periodic spike in disk usage that often - hurt performance. The new code uses a background writer to trickle - disk writes at a steady pace so checkpoints have far fewer dirty - pages to write to disk. Also, the new code does not issue a global - sync() call, but instead fsync()s just - the files written since the last checkpoint. This should improve - performance and minimize degradation during checkpoints. - - - - - - Add ability to prolong vacuum to reduce performance impact (Jan) - - - On busy systems, VACUUM performs many I/O - requests which can hurt performance for other users. This - release allows you to slow down VACUUM to - reduce its impact on other users, though this increases the - total duration of VACUUM. - - - - - - Improve B-tree index performance for duplicate keys (Dmitry Tkach, Tom) - - - This improves the way indexes are scanned when many duplicate - values exist in the index. - - - - - - Use dynamically-generated table size estimates while planning (Tom) - - - Formerly the planner estimated table sizes using the values seen - by the last VACUUM or ANALYZE, - both as to physical table size (number of pages) and number of rows. - Now, the current physical table size is obtained from the kernel, - and the number of rows is estimated by multiplying the table size - by the row density (rows per page) seen by the last - VACUUM or ANALYZE. This should - produce more reliable estimates in cases where the table size has - changed significantly since the last housekeeping command. - - - - - - Improved index usage with OR clauses (Tom) - - - This allows the optimizer to use indexes in statements with many OR - clauses that would not have been indexed in the past. It can also use - multi-column indexes where the first column is specified and the second - column is part of an OR clause. - - - - - - Improve matching of partial index clauses (Tom) - - - The server is now smarter about using partial indexes in queries - involving complex clauses. - - - - - - Improve performance of the GEQO optimizer (Tom) - - - The GEQO optimizer is used to plan queries involving many tables (by - default, twelve or more). This release speeds up the way queries are - analyzed to decrease time spent in optimization. - - - - - - Miscellaneous optimizer improvements - - - There is not room here to list all the minor improvements made, but - numerous special cases work better than in prior releases. - - - - - - Improve lookup speed for C functions (Tom) - - - This release uses a hash table to lookup information for dynamically - loaded C functions. This improves their speed so they perform nearly as - quickly as functions that are built into the server executable. - - - - - - Add type-specific ANALYZE statistics - capability (Mark Cave-Ayland) - - - This feature allows more flexibility in generating statistics - for nonstandard data types. - - - - - - ANALYZE now collects statistics for - expression indexes (Tom) - - - Expression indexes (also called functional indexes) allow users to - index not just columns but the results of expressions and function - calls. With this release, the optimizer can gather and use statistics - about the contents of expression indexes. This will greatly improve - the quality of planning for queries in which an expression index is - relevant. - - - - - - New two-stage sampling method for ANALYZE - (Manfred Koizar) - - - This gives better statistics when the density of valid rows is very - different in different regions of a table. - - - - - - Speed up TRUNCATE (Tom) - - - This buys back some of the performance loss observed in 7.4, while still - keeping TRUNCATE transaction-safe. - - - - - - - - - Server Changes - - - - - Add WAL file archiving and point-in-time recovery (Simon Riggs) - - - - - - Add tablespaces so admins can control disk layout (Gavin) - - - - - - Add a built-in log rotation program (Andreas Pflug) - - - It is now possible to log server messages conveniently without - relying on either syslog or an external log - rotation program. - - - - - - Add new read-only server configuration parameters to show server - compile-time settings: block_size, - integer_datetimes, max_function_args, - max_identifier_length, max_index_keys (Joe) - - - - - - Make quoting of sameuser, samegroup, and - all remove special meaning of these terms in - pg_hba.conf (Andrew) - - - - - - Use clearer IPv6 name ::1/128 for - localhost in default pg_hba.conf (Andrew) - - - - - - Use CIDR format in pg_hba.conf examples (Andrew) - - - - - - Rename server configuration parameters SortMem and - VacuumMem to work_mem and - maintenance_work_mem (Old names still supported) (Tom) - - - This change was made to clarify that bulk operations such as index and - foreign key creation use maintenance_work_mem, while - work_mem is for workspaces used during query execution. - - - - - - Allow logging of session disconnections using server configuration - log_disconnections (Andrew) - - - - - - Add new server configuration parameter log_line_prefix to - allow control of information emitted in each log line (Andrew) - - - Available information includes user name, database name, remote IP - address, and session start time. - - - - - - Remove server configuration parameters log_pid, - log_timestamp, log_source_port; functionality - superseded by log_line_prefix (Andrew) - - - - - - Replace the virtual_host and tcpip_socket - parameters with a unified listen_addresses parameter - (Andrew, Tom) - - - virtual_host could only specify a single IP address to - listen on. listen_addresses allows multiple addresses - to be specified. - - - - - - Listen on localhost by default, which eliminates the need for the - postmaster switch in many scenarios (Andrew) - - - Listening on localhost (127.0.0.1) opens no new - security holes but allows configurations like Windows and JDBC, - which do not support local sockets, to work without special - adjustments. - - - - - - Remove syslog server configuration parameter, and add more - logical log_destination variable to control log output - location (Magnus) - - - - - - Change server configuration parameter log_statement to take - values all, mod, ddl, or - none to select which queries are logged (Bruce) - - - This allows administrators to log only data definition changes or - only data modification statements. - - - - - - Some logging-related configuration parameters could formerly be adjusted - by ordinary users, but only in the more verbose direction. - They are now treated more strictly: only superusers can set them. - However, a superuser can use ALTER USER to provide per-user - settings of these values for non-superusers. Also, it is now possible - for superusers to set values of superuser-only configuration parameters - via PGOPTIONS. - - - - - - Allow configuration files to be placed outside the data directory (mlw) - - - By default, configuration files are kept in the cluster's top directory. - With this addition, configuration files can be placed outside the - data directory, easing administration. - - - - - - Plan prepared queries only when first executed so constants can be - used for statistics (Oliver Jowett) - - - Prepared statements plan queries once and execute them many - times. While prepared queries avoid the overhead of re-planning - on each use, the quality of the plan suffers from not knowing the exact - parameters to be used in the query. In this release, planning of - unnamed prepared statements is delayed until the first execution, - and the actual parameter values of that execution are used as - optimization hints. This allows use of out-of-line parameter passing - without incurring a performance penalty. - - - - - - Allow DECLARE CURSOR to take parameters - (Oliver Jowett) - - - It is now useful to issue DECLARE CURSOR in a - Parse message with parameters. The parameter values - sent at Bind time will be substituted into the - execution of the cursor's query. - - - - - - Fix hash joins and aggregates of inet and - cidr data types (Tom) - - - Release 7.4 handled hashing of mixed inet and - cidr values incorrectly. (This bug did not exist - in prior releases because they wouldn't try to hash either - data type.) - - - - - - Make log_duration print only when log_statement - prints the query (Ed L.) - - - - - - - - - Query Changes - - - - - Add savepoints (nested transactions) (Alvaro) - - - - - - Unsupported isolation levels are now accepted and promoted to the - nearest supported level (Peter) - - - The SQL specification states that if a database doesn't support a - specific isolation level, it should use the next more restrictive level. - This change complies with that recommendation. - - - - - - Allow BEGIN WORK to specify transaction - isolation levels like START TRANSACTION does - (Bruce) - - - - - - Fix table permission checking for cases in which rules generate - a query type different from the originally submitted query (Tom) - - - - - - Implement dollar quoting to simplify single-quote usage (Andrew, Tom, - David Fetter) - - - In previous releases, because single quotes had to be used to - quote a function's body, the use of single quotes inside the - function text required use of two single quotes or other error-prone - notations. With this release we add the ability to use "dollar - quoting" to quote a block of text. The ability to use different - quoting delimiters at different nesting levels greatly simplifies - the task of quoting correctly, especially in complex functions. - Dollar quoting can be used anywhere quoted text is needed. - - - - - - Make CASE val WHEN compval1 THEN ... evaluate val only once (Tom) - - - no longer evaluates the tested expression multiple - times. This has benefits when the expression is complex or is - volatile. - - - - - - Test before computing target list of an - aggregate query (Tom) - - - Fixes improper failure of cases such as SELECT SUM(win)/SUM(lose) - ... GROUP BY ... HAVING SUM(lose) > 0. This should work but formerly - could fail with divide-by-zero. - - - - - - Replace max_expr_depth parameter with - max_stack_depth parameter, measured in kilobytes of stack - size (Tom) - - - This gives us a fairly bulletproof defense against crashing due to - runaway recursive functions. Instead of measuring the depth of expression - nesting, we now directly measure the size of the execution stack. - - - - - - Allow arbitrary row expressions (Tom) - - - This release allows SQL expressions to contain arbitrary composite - types, that is, row values. It also allows functions to more easily - take rows as arguments and return row values. - - - - - - Allow / to be used as the operator - in row and subselect comparisons (Fabien Coelho) - - - - - - Avoid locale-specific case conversion of basic ASCII letters in - identifiers and keywords (Tom) - - - This solves the Turkish problem with mangling of words - containing I and i. Folding of characters - outside the 7-bit-ASCII set is still locale-aware. - - - - - - Improve syntax error reporting (Fabien, Tom) - - - Syntax error reports are more useful than before. - - - - - - Change EXECUTE to return a completion tag - matching the executed statement (Kris Jurka) - - - Previous releases return an EXECUTE tag for - any EXECUTE call. In this release, the tag - returned will reflect the command executed. - - - - - - Avoid emitting in rule listings (Tom) - - - Such a clause makes no logical sense, but in some cases the rule - decompiler formerly produced this syntax. - - - - - - - - - Object Manipulation Changes - - - - - Add COMMENT ON for casts, conversions, languages, - operator classes, and large objects (Christopher) - - - - - - Add new server configuration parameter default_with_oids to - control whether tables are created with OIDs by default (Neil) - - - This allows administrators to control whether CREATE - TABLE commands create tables with or without OID - columns by default. (Note: the current factory default setting for - default_with_oids is TRUE, but the default - will become FALSE in future releases.) - - - - - - Add / clause to - CREATE TABLE AS (Neil) - - - - - - Allow ALTER TABLE DROP COLUMN to drop an OID - column (ALTER TABLE SET WITHOUT OIDS still works) - (Tom) - - - - - - Allow composite types as table columns (Tom) - - - - - - Allow ALTER ... ADD COLUMN with defaults and - constraints; works per SQL spec (Rod) - - - It is now possible for to create a column - that is not initially filled with NULLs, but with a specified - default value. - - - - - - Add ALTER COLUMN TYPE to change column's type (Rod) - - - It is now possible to alter a column's data type without dropping - and re-adding the column. - - - - - - Allow multiple ALTER actions in a single ALTER - TABLE command (Rod) - - - This is particularly useful for ALTER commands that - rewrite the table (which include and - with a default). By grouping - ALTER commands together, the table need be rewritten - only once. - - - - - - Allow ALTER TABLE to add SERIAL - columns (Tom) - - - This falls out from the new capability of specifying defaults for new - columns. - - - - - - Allow changing the owners of aggregates, conversions, databases, - functions, operators, operator classes, schemas, types, and tablespaces - (Christopher, Euler Taveira de Oliveira) - - - Previously this required modifying the system tables directly. - - - - - - Allow temporary object creation to be limited to functions (Sean Chittenden) - - - - - - Add (Christopher) - - - Prior to this release, there was no way to clear an auto-cluster - specification except to modify the system tables. - - - - - - Constraint/Index/SERIAL names are now - table_column_type - with numbers appended to guarantee uniqueness within the schema - (Tom) - - - The SQL specification states that such names should be unique - within a schema. - - - - - - Add pg_get_serial_sequence() to return a - SERIAL column's sequence name (Christopher) - - - This allows automated scripts to reliably find the SERIAL - sequence name. - - - - - - Warn when primary/foreign key data type mismatch requires costly lookup - - - - - - New ALTER INDEX command to allow moving of indexes - between tablespaces (Gavin) - - - - - - Make ALTER TABLE OWNER change dependent sequence - ownership too (Alvaro) - - - - - - - - - - Utility Command Changes - - - - - Allow CREATE SCHEMA to create triggers, - indexes, and sequences (Neil) - - - - - - Add keyword to CREATE RULE (Fabien - Coelho) - - - This allows to be added to rule creation to contrast it with - rules. - - - - - - Add option to LOCK (Tatsuo) - - - This allows the LOCK command to fail if it - would have to wait for the requested lock. - - - - - - Allow COPY to read and write - comma-separated-value (CSV) files (Andrew, Bruce) - - - - - - Generate error if the COPY delimiter and NULL - string conflict (Bruce) - - - - - - GRANT/REVOKE behavior - follows the SQL spec more closely - - - - - - Avoid locking conflict between CREATE INDEX - and CHECKPOINT (Tom) - - - In 7.3 and 7.4, a long-running B-tree index build could block concurrent - CHECKPOINTs from completing, thereby causing WAL bloat because the - WAL log could not be recycled. - - - - - - Database-wide ANALYZE does not hold locks - across tables (Tom) - - - This reduces the potential for deadlocks against other backends - that want exclusive locks on tables. To get the benefit of this - change, do not execute database-wide ANALYZE - inside a transaction block (BEGIN block); it - must be able to commit and start a new transaction for each - table. - - - - - - REINDEX does not exclusively lock the index's - parent table anymore - - - The index itself is still exclusively locked, but readers of the - table can continue if they are not using the particular index - being rebuilt. - - - - - - Erase MD5 user passwords when a user is renamed (Bruce) - - - PostgreSQL uses the user name as salt - when encrypting passwords via MD5. When a user's name is changed, - the salt will no longer match the stored MD5 password, so the - stored password becomes useless. In this release a notice is - generated and the password is cleared. A new password must then - be assigned if the user is to be able to log in with a password. - - - - - - New pg_ctl option for Windows (Andrew) - - - Windows does not have a kill command to send signals to - backends so this capability was added to pg_ctl. - - - - - - Information schema improvements - - - - - - Add option to - initdb so the initial password can be - set by GUI tools (Magnus) - - - - - - Detect locale/encoding mismatch in - initdb (Peter) - - - - - - Add command to pg_ctl to - register Windows operating system service (Dave Page) - - - - - - - - - Data Type and Function Changes - - - - - More complete support for composite types (row types) (Tom) - - - Composite values can be used in many places where only scalar values - worked before. - - - - - - Reject nonrectangular array values as erroneous (Joe) - - - Formerly, array_in would silently build a - surprising result. - - - - - - Overflow in integer arithmetic operations is now detected (Tom) - - - - - - The arithmetic operators associated with the single-byte - "char" data type have been removed. - - - Formerly, the parser would select these operators in many situations - where an unable to select an operator error would be more - appropriate, such as null * null. If you actually want - to do arithmetic on a "char" column, you can cast it to - integer explicitly. - - - - - - Syntax checking of array input values considerably tightened up (Joe) - - - Junk that was previously allowed in odd places with odd results - now causes an ERROR, for example, non-whitespace - after the closing right brace. - - - - - - Empty-string array element values must now be written as - "", rather than writing nothing (Joe) - - - Formerly, both ways of writing an empty-string element value were - allowed, but now a quoted empty string is required. The case where - nothing at all appears will probably be considered to be a NULL - element value in some future release. - - - - - - Array element trailing whitespace is now ignored (Joe) - - - Formerly leading whitespace was ignored, but trailing whitespace - between an element value and the delimiter or right brace was - significant. Now trailing whitespace is also ignored. - - - - - - Emit array values with explicit array bounds when lower bound is not one - (Joe) - - - - - - Accept YYYY-monthname-DD as a date string (Tom) - - - - - - Make netmask and hostmask functions - return maximum-length mask length (Tom) - - - - - - Change factorial function to return numeric (Gavin) - - - Returning numeric allows the factorial function to - work for a wider range of input values. - - - - - - to_char/to_date() date conversion - improvements (Kurt Roeckx, Fabien Coelho) - - - - - - Make length() disregard trailing spaces in - CHAR(n) (Gavin) - - - This change was made to improve consistency: trailing spaces are - semantically insignificant in CHAR(n) data, so they - should not be counted by length(). - - - - - - Warn about empty string being passed to - OID/float4/float8 data types (Neil) - - - 8.1 will throw an error instead. - - - - - - Allow leading or trailing whitespace in - int2/int4/int8/float4/float8 - input routines - (Neil) - - - - - - Better support for IEEE Infinity and NaN - values in float4/float8 (Neil) - - - These should now work on all platforms that support IEEE-compliant - floating point arithmetic. - - - - - - Add option to date_trunc() (Robert Creager) - - - - - - Fix to_char for 1 BC - (previously it returned 1 AD) (Bruce) - - - - - - Fix date_part(year) for BC dates (previously it - returned one less than the correct year) (Bruce) - - - - - - Fix date_part() to return the proper millennium and - century (Fabien Coelho) - - - In previous versions, the century and millennium results had a wrong - number and started in the wrong year, as compared to standard - reckoning of such things. - - - - - - Add ceiling() as an alias for ceil(), - and power() as an alias for pow() for - standards compliance (Neil) - - - - - - Change ln(), log(), - power(), and sqrt() to emit the correct - SQLSTATE error codes for certain error conditions, as - specified by SQL:2003 (Neil) - - - - - - Add width_bucket() function as defined by SQL:2003 (Neil) - - - - - - Add generate_series() functions to simplify working - with numeric sets (Joe) - - - - - - Fix upper/lower/initcap() functions to work with - multibyte encodings (Tom) - - - - - - Add boolean and bitwise integer / - aggregates (Fabien Coelho) - - - - - - New session information functions to return network addresses for client - and server (Sean Chittenden) - - - - - - Add function to determine the area of a closed path (Sean Chittenden) - - - - - - Add function to send cancel request to other backends (Magnus) - - - - - - Add interval plus datetime operators (Tom) - - - The reverse ordering, datetime plus interval, - was already supported, but both are required by the SQL standard. - - - - - - Casting an integer to BIT(N) selects the rightmost N bits - of the integer - (Tom) - - - In prior releases, the leftmost N bits were selected, but this was - deemed unhelpful, not to mention inconsistent with casting from bit - to int. - - - - - - Require CIDR values to have all nonmasked bits be zero - (Kevin Brintnall) - - - - - - - - - Server-Side Language Changes - - - - - In READ COMMITTED serialization mode, volatile functions - now see the results of concurrent transactions committed up to the - beginning of each statement within the function, rather than up to the - beginning of the interactive command that called the function. - - - - - - Functions declared STABLE or IMMUTABLE always - use the snapshot of the calling query, and therefore do not see the - effects of actions taken after the calling query starts, whether in - their own transaction or other transactions. Such a function must be - read-only, too, meaning that it cannot use any SQL commands other than - SELECT. There is a considerable performance gain from - declaring a function STABLE or IMMUTABLE - rather than VOLATILE. - - - - - - Nondeferred triggers are now fired immediately - after completion of the triggering query, rather than upon - finishing the current interactive command. This makes a difference - when the triggering query occurred within a function: the trigger - is invoked before the function proceeds to its next operation. For - example, if a function inserts a new row into a table, any - nondeferred foreign key checks occur before proceeding with the - function. - - - - - - Allow function parameters to be declared with names (Dennis Björklund) - - - This allows better documentation of functions. Whether the names - actually do anything depends on the specific function language - being used. - - - - - - Allow PL/pgSQL parameter names to be referenced in the function (Dennis Björklund) - - - This basically creates an automatic alias for each named parameter. - - - - - - Do minimal syntax checking of PL/pgSQL functions at creation time (Tom) - - - This allows us to catch simple syntax errors sooner. - - - - - - More support for composite types (row and record variables) in PL/pgSQL - - - For example, it now works to pass a rowtype variable to another function - as a single variable. - - - - - - Default values for PL/pgSQL variables can now reference previously - declared variables - - - - - - Improve parsing of PL/pgSQL FOR loops (Tom) - - - Parsing is now driven by presence of ".." rather than - data type of variable. This makes no difference for - correct functions, but should result in more understandable error - messages when a mistake is made. - - - - - - Major overhaul of PL/Perl server-side language (Command Prompt, Andrew Dunstan) - - - - - - In PL/Tcl, SPI commands are now run in subtransactions. If an error - occurs, the subtransaction is cleaned up and the error is reported - as an ordinary Tcl error, which can be trapped with catch. - Formerly, it was not possible to catch such errors. - - - - - - Accept ELSEIF in PL/pgSQL (Neil) - - - Previously PL/pgSQL only allowed ELSIF, but many people - are accustomed to spelling this keyword ELSEIF. - - - - - - - - - <application>psql</application> Changes - - - - - Improve psql information display about database - objects (Christopher) - - - - - - Allow psql to display group membership in - \du and \dg (Markus Bertheau) - - - - - - Prevent psql \dn from showing - temporary schemas (Bruce) - - - - - - Allow psql to handle tilde user expansion for file - names (Zach Irmen) - - - - - - Allow psql to display fancy prompts, including - color, via readline (Reece Hart, Chet Ramey) - - - - - - Make psql \copy match COPY command syntax - fully (Tom) - - - - - - Show the location of syntax errors (Fabien Coelho, Tom) - - - - - - Add CLUSTER information to psql - \d display - (Bruce) - - - - - - Change psql \copy stdin/stdout to read - from command input/output (Bruce) - - - - - - Add / to read from - psql's stdin/stdout (Mark - Feit) - - - - - - Add global psql configuration file, psqlrc.sample - (Bruce) - - - This allows a central file where global psql startup commands can - be stored. - - - - - - Have psql \d+ indicate if the table - has an OID column (Neil) - - - - - - On Windows, use binary mode in psql when reading files so control-Z - is not seen as end-of-file - - - - - - Have \dn+ show permissions and description for schemas (Dennis - Björklund) - - - - - - Improve tab completion support (Stefan Kaltenbrunn, Greg Sabino Mullane) - - - - - - Allow boolean settings to be set using upper or lower case (Michael Paesold) - - - - - - - - - <application>pg_dump</application> Changes - - - - - Use dependency information to improve the reliability of - pg_dump (Tom) - - - This should solve the longstanding problems with related objects - sometimes being dumped in the wrong order. - - - - - - Have pg_dump output objects in alphabetical order if possible (Tom) - - - This should make it easier to identify changes between - dump files. - - - - - - Allow pg_restore to ignore some SQL errors (Fabien Coelho) - - - This makes pg_restore's behavior similar to the - results of feeding a pg_dump output script to - psql. In most cases, ignoring errors and plowing - ahead is the most useful thing to do. Also added was a pg_restore - option to give the old behavior of exiting on an error. - - - - - - pg_restore display now includes - objects' schema names - - - - - - New begin/end markers in pg_dump text output (Bruce) - - - - - - Add start/stop times for - pg_dump/pg_dumpall in verbose mode - (Bruce) - - - - - - Allow most pg_dump options in - pg_dumpall (Christopher) - - - - - - Have pg_dump use ALTER OWNER rather - than SET SESSION AUTHORIZATION by default - (Christopher) - - - - - - - - - libpq Changes - - - - - Make libpq's handling thread-safe (Bruce) - - - - - - Add PQmbdsplen() which returns the display length - of a character (Tatsuo) - - - - - - Add thread locking to SSL and - Kerberos connections (Manfred Spraul) - - - - - - Allow PQoidValue(), PQcmdTuples(), and - PQoidStatus() to work on EXECUTE - commands (Neil) - - - - - - Add PQserverVersion() to provide more convenient - access to the server version number (Greg Sabino Mullane) - - - - - - Add PQprepare/PQsendPrepared() functions to support - preparing statements without necessarily specifying the data types - of their parameters (Abhijit Menon-Sen) - - - - - - Many ECPG improvements, including SET DESCRIPTOR (Michael) - - - - - - - - - Source Code Changes - - - - - Allow the database server to run natively on Windows (Claudio, Magnus, Andrew) - - - - - - Shell script commands converted to C versions for Windows support (Andrew) - - - - - - Create an extension makefile framework (Fabien Coelho, Peter) - - - This simplifies the task of building extensions outside the original - source tree. - - - - - - Support relocatable installations (Bruce) - - - Directory paths for installed files (such as the - /share directory) are now computed relative to the - actual location of the executables, so that an installation tree - can be moved to another place without reconfiguring and - rebuilding. - - - - - - Use to choose installation location of documentation; also - allow (Peter) - - - - - - Add to prevent installation of documentation (Peter) - - - - - - Upgrade to DocBook V4.2 SGML (Peter) - - - - - - New PostgreSQL CVS tag (Marc) - - - This was done to make it easier for organizations to manage their - own copies of the PostgreSQL - CVS repository. File version stamps from the master - repository will not get munged by checking into or out of a copied - repository. - - - - - - Clarify locking code (Manfred Koizar) - - - - - - Buffer manager cleanup (Neil) - - - - - - Decouple platform tests from CPU spinlock code (Bruce, Tom) - - - - - - Add inlined test-and-set code on PA-RISC for gcc - (ViSolve, Tom) - - - - - - Improve i386 spinlock code (Manfred Spraul) - - - - - - Clean up spinlock assembly code to avoid warnings from newer - gcc releases (Tom) - - - - - - Remove JDBC from source tree; now a separate project - - - - - - Remove the libpgtcl client interface; now a separate project - - - - - - More accurately estimate memory and file descriptor usage (Tom) - - - - - - Improvements to the macOS startup scripts (Ray A.) - - - - - - New fsync() test program (Bruce) - - - - - - Major documentation improvements (Neil, Peter) - - - - - - Remove pg_encoding; not needed - anymore - - - - - - Remove pg_id; not needed anymore - - - - - - Remove initlocation; not needed - anymore - - - - - - Auto-detect thread flags (no more manual testing) (Bruce) - - - - - - Use Olson's public domain timezone library (Magnus) - - - - - - With threading enabled, use thread flags on Unixware for - backend executables too (Bruce) - - - Unixware cannot mix threaded and nonthreaded object files in the - same executable, so everything must be compiled as threaded. - - - - - - psql now uses a flex-generated - lexical analyzer to process command strings - - - - - - Reimplement the linked list data structure used throughout the - backend (Neil) - - - This improves performance by allowing list append and length - operations to be more efficient. - - - - - - Allow dynamically loaded modules to create their own server configuration - parameters (Thomas Hallgren) - - - - - - New Brazilian version of FAQ (Euler Taveira de Oliveira) - - - - - - Add French FAQ (Guillaume Lelarge) - - - - - - New pgevent for Windows logging - - - - - - Make libpq and ECPG build as proper shared libraries on macOS (Tom) - - - - - - - - - Contrib Changes - - - - - Overhaul of contrib/dblink (Joe) - - - - - - contrib/dbmirror improvements (Steven Singer) - - - - - - New contrib/xml2 (John Gray, Torchbox) - - - - - - Updated contrib/mysql - - - - - - New version of contrib/btree_gist (Teodor) - - - - - - New contrib/trgm, trigram matching for - PostgreSQL (Teodor) - - - - - - Many contrib/tsearch2 improvements (Teodor) - - - - - - Add double metaphone to contrib/fuzzystrmatch (Andrew) - - - - - - Allow contrib/pg_autovacuum to run as a Windows service (Dave Page) - - - - - - Add functions to contrib/dbsize (Andreas Pflug) - - - - - - Removed contrib/pg_logger: obsoleted by integrated logging - subprocess - - - - - - Removed contrib/rserv: obsoleted by various separate projects - - - - - - - - diff --git a/doc/src/sgml/release-8.1.sgml b/doc/src/sgml/release-8.1.sgml deleted file mode 100644 index 44a30892fdb..00000000000 --- a/doc/src/sgml/release-8.1.sgml +++ /dev/null @@ -1,5444 +0,0 @@ - - - - - Release 8.1.23 - - - Release date: - 2010-12-16 - - - - This release contains a variety of fixes from 8.1.22. - For information about new features in the 8.1 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 8.1.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 8.1.23 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.18, - see . - - - - - - Changes - - - - - - Force the default - wal_sync_method - to be fdatasync on Linux (Tom Lane, Marti Raudsepp) - - - - The default on Linux has actually been fdatasync for many - years, but recent kernel changes caused PostgreSQL to - choose open_datasync instead. This choice did not result - in any performance improvement, and caused outright failures on - certain filesystems, notably ext4 with the - data=journal mount option. - - - - - - Fix recovery from base backup when the starting checkpoint WAL record - is not in the same WAL segment as its redo point (Jeff Davis) - - - - - - Add support for detecting register-stack overrun on IA64 - (Tom Lane) - - - - The IA64 architecture has two hardware stacks. Full - prevention of stack-overrun failures requires checking both. - - - - - - Add a check for stack overflow in copyObject() (Tom Lane) - - - - Certain code paths could crash due to stack overflow given a - sufficiently complex query. - - - - - - Fix detection of page splits in temporary GiST indexes (Heikki - Linnakangas) - - - - It is possible to have a concurrent page split in a - temporary index, if for example there is an open cursor scanning the - index when an insertion is done. GiST failed to detect this case and - hence could deliver wrong results when execution of the cursor - continued. - - - - - - Avoid memory leakage while ANALYZE'ing complex index - expressions (Tom Lane) - - - - - - Ensure an index that uses a whole-row Var still depends on its table - (Tom Lane) - - - - An index declared like create index i on t (foo(t.*)) - would not automatically get dropped when its table was dropped. - - - - - - Do not inline a SQL function with multiple OUT - parameters (Tom Lane) - - - - This avoids a possible crash due to loss of information about the - expected result rowtype. - - - - - - Fix constant-folding of COALESCE() expressions (Tom Lane) - - - - The planner would sometimes attempt to evaluate sub-expressions that - in fact could never be reached, possibly leading to unexpected errors. - - - - - - Add print functionality for InhRelation nodes (Tom Lane) - - - - This avoids a failure when debug_print_parse is enabled - and certain types of query are executed. - - - - - - Fix incorrect calculation of distance from a point to a horizontal - line segment (Tom Lane) - - - - This bug affected several different geometric distance-measurement - operators. - - - - - - Fix PL/pgSQL's handling of simple - expressions to not fail in recursion or error-recovery cases (Tom Lane) - - - - - - Fix bug in contrib/cube's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a cube column. - If you have such an index, consider REINDEXing it after - installing this update. - - - - - - Don't emit identifier will be truncated notices in - contrib/dblink except when creating new connections - (Itagaki Takahiro) - - - - - - Fix potential coredump on missing public key in - contrib/pgcrypto (Marti Raudsepp) - - - - - - Fix memory leak in contrib/xml2's XPath query functions - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2010o - for DST law changes in Fiji and Samoa; - also historical corrections for Hong Kong. - - - - - - - - - - Release 8.1.22 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 8.1.21. - For information about new features in the 8.1 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.1.X release series in November 2010. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.1.22 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.18, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Prevent show_session_authorization() from crashing within autovacuum - processes (Tom Lane) - - - - - - Defend against functions returning setof record where not all the - returned rows are actually of the same rowtype (Tom Lane) - - - - - - Fix possible failure when hashing a pass-by-reference function result - (Tao Ma, Tom Lane) - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Avoid recursion while assigning XIDs to heavily-nested - subtransactions (Andres Freund, Robert Haas) - - - - The original coding could result in a crash if there was limited - stack space. - - - - - - Fix log_line_prefix's %i escape, - which could produce junk early in backend startup (Tom Lane) - - - - - - Fix possible data corruption in ALTER TABLE ... SET - TABLESPACE when archiving is enabled (Jeff Davis) - - - - - - Allow CREATE DATABASE and ALTER DATABASE ... SET - TABLESPACE to be interrupted by query-cancel (Guillaume Lelarge) - - - - - - In PL/Python, defend against null pointer results from - PyCObject_AsVoidPtr and PyCObject_FromVoidPtr - (Peter Eisentraut) - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Fix contrib/dblink to handle connection names longer than - 62 bytes correctly (Itagaki Takahiro) - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - Update time zone data files to tzdata release 2010l - for DST law changes in Egypt and Palestine; also historical corrections - for Finland. - - - - This change also adds new names for two Micronesian timezones: - Pacific/Chuuk is now preferred over Pacific/Truk (and the preferred - abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over - Pacific/Ponape. - - - - - - - - - - Release 8.1.21 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 8.1.20. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.21 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.18, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Prevent infinite recursion in psql when expanding - a variable that refers to itself (Tom) - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - Update time zone data files to tzdata release 2010j - for DST law changes in Argentina, Australian Antarctic, Bangladesh, - Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; - also historical corrections for Taiwan. - - - - - - - - - - Release 8.1.20 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 8.1.19. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.20 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.18, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Fix possible crashes when trying to recover from a failure in - subtransaction start (Tom) - - - - - - Fix server memory leak associated with use of savepoints and a client - encoding different from server's encoding (Tom) - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix integer-to-bit-string conversions to handle the first fractional - byte correctly when the output bit width is wider than the given - integer by something other than a multiple of 8 bits (Tom) - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - Fix the STOP WAL LOCATION entry in backup history files to - report the next WAL segment's name when the end location is exactly at a - segment boundary (Itagaki Takahiro) - - - - - - Fix some more cases of temporary-file leakage (Heikki) - - - - This corrects a problem introduced in the previous minor release. - One case that failed is when a plpgsql function returning set is - called within another function's exception handler. - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Fix psql's numericlocale option to not - format strings it shouldn't in latex and troff output formats (Heikki) - - - - - - Fix plpgsql failure in one case where a composite column is set to NULL - (Tom) - - - - - - Add volatile markings in PL/Python to avoid possible - compiler-specific misbehavior (Zdenek Kotala) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - Fix assorted crashes in contrib/xml2 caused by sloppy - memory management (Tom) - - - - - - Update time zone data files to tzdata release 2010e - for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa. - - - - - - - - - - Release 8.1.19 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 8.1.18. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.19 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.18, - see . - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Ensure that shared tuple-level locks held by prepared transactions are - not ignored (Heikki) - - - - - - Fix premature drop of temporary files used for a cursor that is accessed - within a subtransaction (Heikki) - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Fix processing of ownership dependencies during CREATE OR - REPLACE FUNCTION (Tom) - - - - - - Ensure that Perl arrays are properly converted to - PostgreSQL arrays when returned by a set-returning - PL/Perl function (Andrew Dunstan, Abhijit Menon-Sen) - - - - This worked correctly already for non-set-returning functions. - - - - - - Fix rare crash in exception processing in PL/Python (Peter) - - - - - - Ensure psql's flex module is compiled with the correct - system header definitions (Tom) - - - - This fixes build failures on platforms where - --enable-largefile causes incompatible changes in the - generated code. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - Update time zone data files to tzdata release 2009s - for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, - Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical - corrections for Hong Kong. - - - - - - - - - - Release 8.1.18 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 8.1.17. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.18 - - - A dump/restore is not required for those running 8.1.X. - However, if you have any hash indexes on interval columns, - you must REINDEX them after updating to 8.1.18. - Also, if you are upgrading from a version earlier than 8.1.15, - see . - - - - - - Changes - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Fix handling of sub-SELECTs appearing in the arguments of - an outer-level aggregate function (Tom) - - - - - - Fix hash calculation for data type interval (Tom) - - - - This corrects wrong results for hash joins on interval values. - It also changes the contents of hash indexes on interval columns. - If you have any such indexes, you must REINDEX them - after updating. - - - - - - Treat to_char(..., 'TH') as an uppercase ordinal - suffix with 'HH'/'HH12' (Heikki) - - - - It was previously handled as 'th' (lowercase). - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Fix calculation of distance between a point and a line segment (Tom) - - - - This led to incorrect results from a number of geometric operators. - - - - - - Fix money data type to work in locales where currency - amounts have no fractional digits, e.g. Japan (Itagaki Takahiro) - - - - - - Properly round datetime input like - 00:12:57.9999999999999999999999999999 (Tom) - - - - - - Fix poor choice of page split point in GiST R-tree operator classes - (Teodor) - - - - - - Fix portability issues in plperl initialization (Andrew Dunstan) - - - - - - Fix pg_ctl to not go into an infinite loop if - postgresql.conf is empty (Jeff Davis) - - - - - - Fix contrib/xml2's xslt_process() to - properly handle the maximum number of parameters (twenty) (Tom) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - Update time zone data files to tzdata release 2009l - for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, - Argentina/San_Luis, Cuba, Jordan (historical correction only), - Mauritius, Morocco, Palestine, Syria, Tunisia. - - - - - - - - - - Release 8.1.17 - - - Release date: - 2009-03-16 - - - - This release contains a variety of fixes from 8.1.16. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.17 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.15, - see . - - - - - - Changes - - - - - - Prevent error recursion crashes when encoding conversion fails (Tom) - - - - This change extends fixes made in the last two minor releases for - related failure scenarios. The previous fixes were narrowly tailored - for the original problem reports, but we have now recognized that - any error thrown by an encoding conversion function could - potentially lead to infinite recursion while trying to report the - error. The solution therefore is to disable translation and encoding - conversion and report the plain-ASCII form of any error message, - if we find we have gotten into a recursive error reporting situation. - (CVE-2009-0922) - - - - - - Disallow CREATE CONVERSION with the wrong encodings - for the specified conversion function (Heikki) - - - - This prevents one possible scenario for encoding conversion failure. - The previous change is a backstop to guard against other kinds of - failures in the same area. - - - - - - Fix core dump when to_char() is given format codes that - are inappropriate for the type of the data argument (Tom) - - - - - - Fix decompilation of CASE WHEN with an implicit coercion - (Tom) - - - - This mistake could lead to Assert failures in an Assert-enabled build, - or an unexpected CASE WHEN clause error message in other - cases, when trying to examine or dump a view. - - - - - - Fix possible misassignment of the owner of a TOAST table's rowtype (Tom) - - - - If CLUSTER or a rewriting variant of ALTER TABLE - were executed by someone other than the table owner, the - pg_type entry for the table's TOAST table would end up - marked as owned by that someone. This caused no immediate problems, - since the permissions on the TOAST rowtype aren't examined by any - ordinary database operation. However, it could lead to unexpected - failures if one later tried to drop the role that issued the command - (in 8.1 or 8.2), or owner of data type appears to be invalid - warnings from pg_dump after having done so (in 8.3). - - - - - - Clean up PL/pgSQL error status variables fully at block exit - (Ashesh Vashi and Dave Page) - - - - This is not a problem for PL/pgSQL itself, but the omission could cause - the PL/pgSQL Debugger to crash while examining the state of a function. - - - - - - Add MUST (Mauritius Island Summer Time) to the default list - of known timezone abbreviations (Xavier Bugaud) - - - - - - - - - - Release 8.1.16 - - - Release date: - 2009-02-02 - - - - This release contains a variety of fixes from 8.1.15. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.16 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.15, - see . - - - - - - Changes - - - - - - Fix crash in autovacuum (Alvaro) - - - - The crash occurs only after vacuuming a whole database for - anti-transaction-wraparound purposes, which means that it occurs - infrequently and is hard to track down. - - - - - - Improve handling of URLs in headline() function (Teodor) - - - - - - Improve handling of overlength headlines in headline() - function (Teodor) - - - - - - Prevent possible Assert failure or misconversion if an encoding - conversion is created with the wrong conversion function for the - specified pair of encodings (Tom, Heikki) - - - - - - Avoid unnecessary locking of small tables in VACUUM - (Heikki) - - - - - - Ensure that the contents of a holdable cursor don't depend on the - contents of TOAST tables (Tom) - - - - Previously, large field values in a cursor result might be represented - as TOAST pointers, which would fail if the referenced table got dropped - before the cursor is read, or if the large value is deleted and then - vacuumed away. This cannot happen with an ordinary cursor, - but it could with a cursor that is held past its creating transaction. - - - - - - Fix uninitialized variables in contrib/tsearch2's - get_covers() function (Teodor) - - - - - - Fix configure script to properly report failure when - unable to obtain linkage information for PL/Perl (Andrew) - - - - - - Make all documentation reference pgsql-bugs and/or - pgsql-hackers as appropriate, instead of the - now-decommissioned pgsql-ports and pgsql-patches - mailing lists (Tom) - - - - - - Update time zone data files to tzdata release 2009a (for - Kathmandu and historical DST corrections in Switzerland, Cuba) - - - - - - - - - - Release 8.1.15 - - - Release date: - 2008-11-03 - - - - This release contains a variety of fixes from 8.1.14. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.15 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . Also, if you were running a previous - 8.1.X release, it is recommended to REINDEX all GiST - indexes after the upgrade. - - - - - - Changes - - - - - - Fix GiST index corruption due to marking the wrong index entry - dead after a deletion (Teodor) - - - - This would result in index searches failing to find rows they - should have found. Corrupted indexes can be fixed with - REINDEX. - - - - - - Fix backend crash when the client encoding cannot represent a localized - error message (Tom) - - - - We have addressed similar issues before, but it would still fail if - the character has no equivalent message itself couldn't - be converted. The fix is to disable localization and send the plain - ASCII error message when we detect such a situation. - - - - - - Fix possible crash when deeply nested functions are invoked from - a trigger (Tom) - - - - - - Fix mis-expansion of rule queries when a sub-SELECT appears - in a function call in FROM, a multi-row VALUES - list, or a RETURNING list (Tom) - - - - The usual symptom of this problem is an unrecognized node type - error. - - - - - - Ensure an error is reported when a newly-defined PL/pgSQL trigger - function is invoked as a normal function (Tom) - - - - - - Prevent possible collision of relfilenode numbers - when moving a table to another tablespace with ALTER SET - TABLESPACE (Heikki) - - - - The command tried to re-use the existing filename, instead of - picking one that is known unused in the destination directory. - - - - - - Fix incorrect tsearch2 headline generation when single query - item matches first word of text (Sushant Sinha) - - - - - - Fix improper display of fractional seconds in interval values when - using a non-ISO datestyle in an - build (Ron Mayer) - - - - - - Ensure SPI_getvalue and SPI_getbinval - behave correctly when the passed tuple and tuple descriptor have - different numbers of columns (Tom) - - - - This situation is normal when a table has had columns added or removed, - but these two functions didn't handle it properly. - The only likely consequence is an incorrect error indication. - - - - - - Fix ecpg's parsing of CREATE ROLE (Michael) - - - - - - Fix recent breakage of pg_ctl restart (Tom) - - - - - - Update time zone data files to tzdata release 2008i (for - DST law changes in Argentina, Brazil, Mauritius, Syria) - - - - - - - - - - Release 8.1.14 - - - Release date: - 2008-09-22 - - - - This release contains a variety of fixes from 8.1.13. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.14 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Widen local lock counters from 32 to 64 bits (Tom) - - - - This responds to reports that the counters could overflow in - sufficiently long transactions, leading to unexpected lock is - already held errors. - - - - - - Fix possible duplicate output of tuples during a GiST index scan (Teodor) - - - - - - Add checks in executor startup to ensure that the tuples produced by an - INSERT or UPDATE will match the target table's - current rowtype (Tom) - - - - ALTER COLUMN TYPE, followed by re-use of a previously - cached plan, could produce this type of situation. The check protects - against data corruption and/or crashes that could ensue. - - - - - - Fix AT TIME ZONE to first try to interpret its timezone - argument as a timezone abbreviation, and only try it as a full timezone - name if that fails, rather than the other way around as formerly (Tom) - - - - The timestamp input functions have always resolved ambiguous zone names - in this order. Making AT TIME ZONE do so as well improves - consistency, and fixes a compatibility bug introduced in 8.1: - in ambiguous cases we now behave the same as 8.0 and before did, - since in the older versions AT TIME ZONE accepted - only abbreviations. - - - - - - Fix datetime input functions to correctly detect integer overflow when - running on a 64-bit platform (Tom) - - - - - - Improve performance of writing very long log messages to syslog (Tom) - - - - - - Fix bug in backwards scanning of a cursor on a SELECT DISTINCT - ON query (Tom) - - - - - - Fix planner bug with nested sub-select expressions (Tom) - - - - If the outer sub-select has no direct dependency on the parent query, - but the inner one does, the outer value might not get recalculated - for new parent query rows. - - - - - - Fix planner to estimate that GROUP BY expressions yielding - boolean results always result in two groups, regardless of the - expressions' contents (Tom) - - - - This is very substantially more accurate than the regular GROUP - BY estimate for certain boolean tests like col - IS NULL. - - - - - - Fix PL/pgSQL to not fail when a FOR loop's target variable - is a record containing composite-type fields (Tom) - - - - - - Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful - about the encoding of data sent to or from Tcl (Tom) - - - - - - Fix PL/Python to work with Python 2.5 - - - - This is a back-port of fixes made during the 8.2 development cycle. - - - - - - Improve pg_dump and pg_restore's - error reporting after failure to send a SQL command (Tom) - - - - - - Fix pg_ctl to properly preserve postmaster - command-line arguments across a restart (Bruce) - - - - - - Update time zone data files to tzdata release 2008f (for - DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco, - Pakistan, Palestine, and Paraguay) - - - - - - - - - - Release 8.1.13 - - - Release date: - 2008-06-12 - - - - This release contains one serious and one minor bug fix over 8.1.12. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.13 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Make pg_get_ruledef() parenthesize negative constants (Tom) - - - - Before this fix, a negative constant in a view or rule might be dumped - as, say, -42::integer, which is subtly incorrect: it should - be (-42)::integer due to operator precedence rules. - Usually this would make little difference, but it could interact with - another recent patch to cause - PostgreSQL to reject what had been a valid - SELECT DISTINCT view query. Since this could result in - pg_dump output failing to reload, it is being treated - as a high-priority fix. The only released versions in which dump - output is actually incorrect are 8.3.1 and 8.2.7. - - - - - - Make ALTER AGGREGATE ... OWNER TO update - pg_shdepend (Tom) - - - - This oversight could lead to problems if the aggregate was later - involved in a DROP OWNED or REASSIGN OWNED - operation. - - - - - - - - - - Release 8.1.12 - - - Release date: - never released - - - - This release contains a variety of fixes from 8.1.11. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.12 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new - column is correctly checked to see if it's been initialized to all - non-nulls (Brendan Jurd) - - - - Previous versions neglected to check this requirement at all. - - - - - - Fix possible CREATE TABLE failure when inheriting the - same constraint from multiple parent relations that - inherited that constraint from a common ancestor (Tom) - - - - - - Fix conversions between ISO-8859-5 and other encodings to handle - Cyrillic Yo characters (e and E with - two dots) (Sergey Burladyan) - - - - - - Fix a few datatype input functions - that were allowing unused bytes in their results to contain - uninitialized, unpredictable values (Tom) - - - - This could lead to failures in which two apparently identical literal - values were not seen as equal, resulting in the parser complaining - about unmatched ORDER BY and DISTINCT - expressions. - - - - - - Fix a corner case in regular-expression substring matching - (substring(string from - pattern)) (Tom) - - - - The problem occurs when there is a match to the pattern overall but - the user has specified a parenthesized subexpression and that - subexpression hasn't got a match. An example is - substring('foo' from 'foo(bar)?'). - This should return NULL, since (bar) isn't matched, but - it was mistakenly returning the whole-pattern match instead (ie, - foo). - - - - - - Update time zone data files to tzdata release 2008c (for - DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba, - Argentina/San_Luis, and Chile) - - - - - - Fix incorrect result from ecpg's - PGTYPEStimestamp_sub() function (Michael) - - - - - - Fix core dump in contrib/xml2's - xpath_table() function when the input query returns a - NULL value (Tom) - - - - - - Fix contrib/xml2's makefile to not override - CFLAGS (Tom) - - - - - - Fix DatumGetBool macro to not fail with gcc - 4.3 (Tom) - - - - This problem affects old style (V0) C functions that - return boolean. The fix is already in 8.3, but the need to - back-patch it was not realized at the time. - - - - - - Fix longstanding LISTEN/NOTIFY - race condition (Tom) - - - - In rare cases a session that had just executed a - LISTEN might not get a notification, even though - one would be expected because the concurrent transaction executing - NOTIFY was observed to commit later. - - - - A side effect of the fix is that a transaction that has executed - a not-yet-committed LISTEN command will not see any - row in pg_listener for the LISTEN, - should it choose to look; formerly it would have. This behavior - was never documented one way or the other, but it is possible that - some applications depend on the old behavior. - - - - - - Disallow LISTEN and UNLISTEN within a - prepared transaction (Tom) - - - - This was formerly allowed but trying to do it had various unpleasant - consequences, notably that the originating backend could not exit - as long as an UNLISTEN remained uncommitted. - - - - - - Fix rare crash when an error occurs during a query using a hash index - (Heikki) - - - - - - Fix input of datetime values for February 29 in years BC (Tom) - - - - The former coding was mistaken about which years were leap years. - - - - - - Fix unrecognized node type error in some variants of - ALTER OWNER (Tom) - - - - - - Fix pg_ctl to correctly extract the postmaster's port - number from command-line options (Itagaki Takahiro, Tom) - - - - Previously, pg_ctl start -w could try to contact the - postmaster on the wrong port, leading to bogus reports of startup - failure. - - - - - - Use to defend against possible misoptimization - in recent gcc versions (Tom) - - - - This is known to be necessary when building PostgreSQL - with gcc 4.3 or later. - - - - - - Fix display of constant expressions in ORDER BY - and GROUP BY (Tom) - - - - An explicitly casted constant would be shown incorrectly. This could - for example lead to corruption of a view definition during - dump and reload. - - - - - - Fix libpq to handle NOTICE messages correctly - during COPY OUT (Tom) - - - - This failure has only been observed to occur when a user-defined - datatype's output routine issues a NOTICE, but there is no - guarantee it couldn't happen due to other causes. - - - - - - - - - - Release 8.1.11 - - - Release date: - 2008-01-07 - - - - This release contains a variety of fixes from 8.1.10, - including fixes for significant security issues. - For information about new features in the 8.1 major release, see - . - - - - This is the last 8.1.X release for which the PostgreSQL - community will produce binary packages for Windows. - Windows users are encouraged to move to 8.2.X or later, - since there are Windows-specific fixes in 8.2.X that - are impractical to back-port. 8.1.X will continue to - be supported on other platforms. - - - - Migration to Version 8.1.11 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Prevent functions in indexes from executing with the privileges of - the user running VACUUM, ANALYZE, etc (Tom) - - - - Functions used in index expressions and partial-index - predicates are evaluated whenever a new table entry is made. It has - long been understood that this poses a risk of trojan-horse code - execution if one modifies a table owned by an untrustworthy user. - (Note that triggers, defaults, check constraints, etc. pose the - same type of risk.) But functions in indexes pose extra danger - because they will be executed by routine maintenance operations - such as VACUUM FULL, which are commonly performed - automatically under a superuser account. For example, a nefarious user - can execute code with superuser privileges by setting up a - trojan-horse index definition and waiting for the next routine vacuum. - The fix arranges for standard maintenance operations - (including VACUUM, ANALYZE, REINDEX, - and CLUSTER) to execute as the table owner rather than - the calling user, using the same privilege-switching mechanism already - used for SECURITY DEFINER functions. To prevent bypassing - this security measure, execution of SET SESSION - AUTHORIZATION and SET ROLE is now forbidden within a - SECURITY DEFINER context. (CVE-2007-6600) - - - - - - Repair assorted bugs in the regular-expression package (Tom, Will Drewry) - - - - Suitably crafted regular-expression patterns could cause crashes, - infinite or near-infinite looping, and/or massive memory consumption, - all of which pose denial-of-service hazards for applications that - accept regex search patterns from untrustworthy sources. - (CVE-2007-4769, CVE-2007-4772, CVE-2007-6067) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - The fix that appeared for this in 8.1.10 was incomplete, as it plugged - the hole for only some dblink functions. (CVE-2007-6601, - CVE-2007-3278) - - - - - - Update time zone data files to tzdata release 2007k - (in particular, recent Argentina changes) (Tom) - - - - - - Improve planner's handling of LIKE/regex estimation in non-C locales - (Tom) - - - - - - Fix planner failure in some cases of WHERE false AND var IN - (SELECT ...) (Tom) - - - - - - Preserve the tablespace of indexes that are - rebuilt by ALTER TABLE ... ALTER COLUMN TYPE (Tom) - - - - - - Make archive recovery always start a new WAL timeline, rather than only - when a recovery stop time was used (Simon) - - - - This avoids a corner-case risk of trying to overwrite an existing - archived copy of the last WAL segment, and seems simpler and cleaner - than the original definition. - - - - - - Make VACUUM not use all of maintenance_work_mem - when the table is too small for it to be useful (Alvaro) - - - - - - Fix potential crash in translate() when using a multibyte - database encoding (Tom) - - - - - - Fix overflow in extract(epoch from interval) for intervals - exceeding 68 years (Tom) - - - - - - Fix PL/Perl to not fail when a UTF-8 regular expression is used - in a trusted function (Andrew) - - - - - - Fix PL/Perl to cope when platform's Perl defines type bool - as int rather than char (Tom) - - - - While this could theoretically happen anywhere, no standard build of - Perl did things this way ... until macOS 10.5. - - - - - - Fix PL/Python to not crash on long exception messages (Alvaro) - - - - - - Fix pg_dump to correctly handle inheritance child tables - that have default expressions different from their parent's (Tom) - - - - - - Fix libpq crash when PGPASSFILE refers - to a file that is not a plain file (Martin Pitt) - - - - - - ecpg parser fixes (Michael) - - - - - - Make contrib/pgcrypto defend against - OpenSSL libraries that fail on keys longer than 128 - bits; which is the case at least on some Solaris versions (Marko Kreen) - - - - - - Make contrib/tablefunc's crosstab() handle - NULL rowid as a category in its own right, rather than crashing (Joe) - - - - - - Fix tsvector and tsquery output routines to - escape backslashes correctly (Teodor, Bruce) - - - - - - Fix crash of to_tsvector() on huge input strings (Teodor) - - - - - - Require a specific version of Autoconf to be used - when re-generating the configure script (Peter) - - - - This affects developers and packagers only. The change was made - to prevent accidental use of untested combinations of - Autoconf and PostgreSQL versions. - You can remove the version check if you really want to use a - different Autoconf version, but it's - your responsibility whether the result works or not. - - - - - - - - - - Release 8.1.10 - - - Release date: - 2007-09-17 - - - - This release contains a variety of fixes from 8.1.9. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.10 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Prevent index corruption when a transaction inserts rows and - then aborts close to the end of a concurrent VACUUM - on the same table (Tom) - - - - - - Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom) - - - - - - Allow the interval data type to accept input consisting only of - milliseconds or microseconds (Neil) - - - - - - Speed up rtree index insertion (Teodor) - - - - - - Fix excessive logging of SSL error messages (Tom) - - - - - - Fix logging so that log messages are never interleaved when using - the syslogger process (Andrew) - - - - - - Fix crash when log_min_error_statement logging runs out - of memory (Tom) - - - - - - Fix incorrect handling of some foreign-key corner cases (Tom) - - - - - - Prevent REINDEX and CLUSTER from failing - due to attempting to process temporary tables of other sessions (Alvaro) - - - - - - Update the time zone database rules, particularly New Zealand's upcoming changes (Tom) - - - - - - Windows socket improvements (Magnus) - - - - - - Suppress timezone name (%Z) in log timestamps on Windows - because of possible encoding mismatches (Tom) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - - - - - - - Release 8.1.9 - - - Release date: - 2007-04-23 - - - - This release contains a variety of fixes from 8.1.8, - including a security fix. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.9 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Support explicit placement of the temporary-table schema within - search_path, and disable searching it for functions - and operators (Tom) - - - This is needed to allow a security-definer function to set a - truly secure value of search_path. Without it, - an unprivileged SQL user can use temporary objects to execute code - with the privileges of the security-definer function (CVE-2007-2138). - See CREATE FUNCTION for more information. - - - - - - /contrib/tsearch2 crash fixes (Teodor) - - - - - - Require COMMIT PREPARED to be executed in the same - database as the transaction was prepared in (Heikki) - - - - - - Fix potential-data-corruption bug in how VACUUM FULL handles - UPDATE chains (Tom, Pavan Deolasee) - - - - - - Planner fixes, including improving outer join and bitmap scan - selection logic (Tom) - - - - - - Fix PANIC during enlargement of a hash index (bug introduced in 8.1.6) - (Tom) - - - - - - Fix POSIX-style timezone specs to follow new USA DST rules (Tom) - - - - - - - - - - Release 8.1.8 - - - Release date: - 2007-02-07 - - - - This release contains one fix from 8.1.7. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.8 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Remove overly-restrictive check for type length in constraints and - functional indexes(Tom) - - - - - - - - - - Release 8.1.7 - - - Release date: - 2007-02-05 - - - - This release contains a variety of fixes from 8.1.6, including - a security fix. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.7 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Remove security vulnerabilities that allowed connected users - to read backend memory (Tom) - - - The vulnerabilities involve suppressing the normal check that a SQL - function returns the data type it's declared to, and changing the - data type of a table column (CVE-2007-0555, CVE-2007-0556). These - errors can easily be exploited to cause a backend crash, and in - principle might be used to read database content that the user - should not be able to access. - - - - - - Fix rare bug wherein btree index page splits could fail - due to choosing an infeasible split point (Heikki Linnakangas) - - - - - - Improve VACUUM performance for databases with many tables (Tom) - - - - - - Fix autovacuum to avoid leaving non-permanent transaction IDs in - non-connectable databases (Alvaro) - - - - This bug affects the 8.1 branch only. - - - - - - Fix for rare Assert() crash triggered by UNION (Tom) - - - - - - Tighten security of multi-byte character processing for UTF8 sequences - over three bytes long (Tom) - - - - - - Fix bogus permission denied failures occurring on Windows - due to attempts to fsync already-deleted files (Magnus, Tom) - - - - - - Fix possible crashes when an already-in-use PL/pgSQL function is - updated (Tom) - - - - - - - - - - Release 8.1.6 - - - Release date: - 2007-01-08 - - - - This release contains a variety of fixes from 8.1.5. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.6 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - - - - - Improve handling of getaddrinfo() on AIX (Tom) - - - - This fixes a problem with starting the statistics collector, - among other things. - - - - - - Fix pg_restore to handle a tar-format backup - that contains large objects (blobs) with comments (Tom) - - - - - - Fix failed to re-find parent key errors in - VACUUM (Tom) - - - - - - Clean out pg_internal.init cache files during server - restart (Simon) - - - - This avoids a hazard that the cache files might contain stale - data after PITR recovery. - - - - - - Fix race condition for truncation of a large relation across a - gigabyte boundary by VACUUM (Tom) - - - - - - Fix bug causing needless deadlock errors on row-level locks (Tom) - - - - - - Fix bugs affecting multi-gigabyte hash indexes (Tom) - - - - - - Fix possible deadlock in Windows signal handling (Teodor) - - - - - - Fix error when constructing an ARRAY[] made up of multiple - empty elements (Tom) - - - - - - Fix ecpg memory leak during connection (Michael) - - - - - - Fix for macOS (Darwin) compilation (Tom) - - - - - - to_number() and to_char(numeric) - are now STABLE, not IMMUTABLE, for - new initdb installs (Tom) - - - - This is because lc_numeric can potentially - change the output of these functions. - - - - - - Improve index usage of regular expressions that use parentheses (Tom) - - - - This improves psql \d performance also. - - - - - - Update timezone database - - - - This affects Australian and Canadian daylight-savings rules in - particular. - - - - - - - - - - Release 8.1.5 - - - Release date: - 2006-10-16 - - - - This release contains a variety of fixes from 8.1.4. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.5 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - - Changes - - -Disallow aggregate functions in UPDATE -commands, except within sub-SELECTs (Tom) -The behavior of such an aggregate was unpredictable, and in 8.1.X -could cause a crash, so it has been disabled. The SQL standard does not allow -this either. -Fix core dump when an untyped literal is taken as -ANYARRAY -Fix core dump in duration logging for extended query protocol -when a COMMIT or ROLLBACK is -executed -Fix mishandling of AFTER triggers when query contains a SQL -function returning multiple rows (Tom) -Fix ALTER TABLE ... TYPE to recheck -NOT NULL for USING clause (Tom) -Fix string_to_array() to handle overlapping - matches for the separator string -For example, string_to_array('123xx456xxx789', 'xx'). - -Fix to_timestamp() for -AM/PM formats (Bruce) -Fix autovacuum's calculation that decides whether - ANALYZE is needed (Alvaro) -Fix corner cases in pattern matching for - psql's \d commands -Fix index-corrupting bugs in /contrib/ltree - (Teodor) -Numerous robustness fixes in ecpg (Joachim -Wieland) -Fix backslash escaping in /contrib/dbmirror -Minor fixes in /contrib/dblink and /contrib/tsearch2 - -Efficiency improvements in hash tables and bitmap index scans -(Tom) -Fix instability of statistics collection on Windows (Tom, Andrew) -Fix statement_timeout to use the proper -units on Win32 (Bruce) -In previous Win32 8.1.X versions, the delay was off by a factor of -100. -Fixes for MSVC and Borland C++ -compilers (Hiroshi Saito) -Fixes for AIX and -Intel compilers (Tom) -Fix rare bug in continuous archiving (Tom) - - - - - - - Release 8.1.4 - - - Release date: - 2006-05-23 - - - - This release contains a variety of fixes from 8.1.3, - including patches for extremely serious security issues. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.4 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - Full security against the SQL-injection attacks described in - CVE-2006-2313 and CVE-2006-2314 might require changes in application - code. If you have applications that embed untrustworthy strings - into SQL commands, you should examine them as soon as possible to - ensure that they are using recommended escaping techniques. In - most cases, applications should be using subroutines provided by - libraries or drivers (such as libpq's - PQescapeStringConn()) to perform string escaping, - rather than relying on ad hoc code to do it. - - - - - Changes - - -Change the server to reject invalidly-encoded multibyte -characters in all cases (Tatsuo, Tom) -While PostgreSQL has been moving in this direction for -some time, the checks are now applied uniformly to all encodings and all -textual input, and are now always errors not merely warnings. This change -defends against SQL-injection attacks of the type described in CVE-2006-2313. - - -Reject unsafe uses of \' in string literals -As a server-side defense against SQL-injection attacks of the type -described in CVE-2006-2314, the server now only accepts '' and not -\' as a representation of ASCII single quote in SQL string -literals. By default, \' is rejected only when -client_encoding is set to a client-only encoding (SJIS, BIG5, GBK, -GB18030, or UHC), which is the scenario in which SQL injection is possible. -A new configuration parameter backslash_quote is available to -adjust this behavior when needed. Note that full security against -CVE-2006-2314 might require client-side changes; the purpose of -backslash_quote is in part to make it obvious that insecure -clients are insecure. - - -Modify libpq's string-escaping routines to be -aware of encoding considerations and -standard_conforming_strings -This fixes libpq-using applications for the security -issues described in CVE-2006-2313 and CVE-2006-2314, and also future-proofs -them against the planned changeover to SQL-standard string literal syntax. -Applications that use multiple PostgreSQL connections -concurrently should migrate to PQescapeStringConn() and -PQescapeByteaConn() to ensure that escaping is done correctly -for the settings in use in each database connection. Applications that -do string escaping by hand should be modified to rely on library -routines instead. - - -Fix weak key selection in pgcrypto (Marko Kreen) -Errors in fortuna PRNG reseeding logic could cause a predictable -session key to be selected by pgp_sym_encrypt() in some cases. -This only affects non-OpenSSL-using builds. - - -Fix some incorrect encoding conversion functions -win1251_to_iso, win866_to_iso, -euc_tw_to_big5, euc_tw_to_mic, -mic_to_euc_tw were all broken to varying -extents. - - -Clean up stray remaining uses of \' in strings -(Bruce, Jan) - -Make autovacuum visible in pg_stat_activity -(Alvaro) - -Disable full_page_writes (Tom) -In certain cases, having full_page_writes off would cause -crash recovery to fail. A proper fix will appear in 8.2; for now it's just -disabled. - - -Various planner fixes, particularly for bitmap index scans and -MIN/MAX optimization (Tom) - -Fix incorrect optimization in merge join (Tom) -Outer joins could sometimes emit multiple copies of unmatched rows. - - -Fix crash from using and modifying a plpgsql function in the -same transaction - -Fix WAL replay for case where a B-Tree index has been -truncated - -Fix SIMILAR TO for patterns involving -| (Tom) - -Fix SELECT INTO and CREATE TABLE AS to -create tables in the default tablespace, not the base directory (Kris -Jurka) - -Fix server to use custom DH SSL parameters correctly (Michael -Fuhr) - -Improve qsort performance (Dann Corbit) -Currently this code is only used on Solaris. - - -Fix for OS/X Bonjour on x86 systems (Ashley Clark) - -Fix various minor memory leaks - -Fix problem with password prompting on some Win32 systems -(Robert Kinberg) - -Improve pg_dump's handling of default values -for domains - -Fix pg_dumpall to handle identically-named -users and groups reasonably (only possible when dumping from a pre-8.1 server) -(Tom) -The user and group will be merged into a single role with -LOGIN permission. Formerly the merged role wouldn't have -LOGIN permission, making it unusable as a user. - - -Fix pg_restore -n to work as -documented (Tom) - - - - - - - Release 8.1.3 - - - Release date: - 2006-02-14 - - - - This release contains a variety of fixes from 8.1.2, - including one very serious security issue. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.3 - - - A dump/restore is not required for those running 8.1.X. - However, if you are upgrading from a version earlier than 8.1.2, - see . - - - - - Changes - - - -Fix bug that allowed any logged-in user to SET -ROLE to any other database user id (CVE-2006-0553) -Due to inadequate validity checking, a user could exploit the special -case that SET ROLE normally uses to restore the previous role -setting after an error. This allowed ordinary users to acquire superuser -status, for example. -The escalation-of-privilege risk exists only in 8.1.0-8.1.2. -However, in all releases back to 7.3 there is a related bug in SET -SESSION AUTHORIZATION that allows unprivileged users to crash the server, -if it has been compiled with Asserts enabled (which is not the default). -Thanks to Akio Ishida for reporting this problem. - - -Fix bug with row visibility logic in self-inserted -rows (Tom) -Under rare circumstances a row inserted by the current command -could be seen as already valid, when it should not be. Repairs bug -created in 8.0.4, 7.4.9, and 7.3.11 releases. - - -Fix race condition that could lead to file already -exists errors during pg_clog and pg_subtrans file creation -(Tom) - -Fix cases that could lead to crashes if a cache-invalidation -message arrives at just the wrong time (Tom) - -Properly check DOMAIN constraints for -UNKNOWN parameters in prepared statements -(Neil) - -Ensure ALTER COLUMN TYPE will process -FOREIGN KEY, UNIQUE, and PRIMARY KEY -constraints in the proper order (Nakano Yoshihisa) - -Fixes to allow restoring dumps that have cross-schema -references to custom operators or operator classes (Tom) - -Allow pg_restore to continue properly after a -COPY failure; formerly it tried to treat the remaining -COPY data as SQL commands (Stephen Frost) - -Fix pg_ctl unregister crash -when the data directory is not specified (Magnus) - -Fix libpq PQprint HTML tags -(Christoph Zwerschke) - -Fix ecpg crash on AMD64 and PPC -(Neil) - -Allow SETOF and %TYPE to be used -together in function result type declarations - -Recover properly if error occurs during argument passing -in PL/Python (Neil) - -Fix memory leak in plperl_return_next -(Neil) - -Fix PL/Perl's handling of locales on -Win32 to match the backend (Andrew) - -Various optimizer fixes (Tom) - -Fix crash when log_min_messages is set to -DEBUG3 or above in postgresql.conf on Win32 -(Bruce) - -Fix pgxs -L library path -specification for Win32, Cygwin, macOS, AIX (Bruce) - -Check that SID is enabled while checking for Win32 admin -privileges (Magnus) - -Properly reject out-of-range date inputs (Kris -Jurka) - -Portability fix for testing presence of finite -and isinf during configure (Tom) - -Improve speed of COPY IN via libpq, by -avoiding a kernel call per data line (Alon Goldshuv) - -Improve speed of /contrib/tsearch2 index -creation (Tom) - - - - - - - - Release 8.1.2 - - - Release date: - 2006-01-09 - - - - This release contains a variety of fixes from 8.1.1. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.2 - - - A dump/restore is not required for those running 8.1.X. - However, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the locale or - plperl issues described below. - - - - - Changes - - - -Fix Windows code so that postmaster will continue rather -than exit if there is no more room in ShmemBackendArray (Magnus) -The previous behavior could lead to a denial-of-service situation if too -many connection requests arrive close together. This applies -only to the Windows port. - -Fix bug introduced in 8.0 that could allow ReadBuffer -to return an already-used page as new, potentially causing loss of -recently-committed data (Tom) - -Fix for protocol-level Describe messages issued -outside a transaction or in a failed transaction (Tom) - -Fix character string comparison for locales that consider -different character combinations as equal, such as Hungarian (Tom) -This might require REINDEX to fix existing indexes on -textual columns. - -Set locale environment variables during postmaster startup -to ensure that plperl won't change the locale later -This fixes a problem that occurred if the postmaster was -started with environment variables specifying a different locale than what -initdb had been told. Under these conditions, any use of -plperl was likely to lead to corrupt indexes. You might need -REINDEX to fix existing indexes on -textual columns if this has happened to you. - -Allow more flexible relocation of installation -directories (Tom) -Previous releases supported relocation only if all installation -directory paths were the same except for the last component. - -Prevent crashes caused by the use of -ISO-8859-5 and ISO-8859-9 encodings -(Tatsuo) - -Fix longstanding bug in strpos() and regular expression -handling in certain rarely used Asian multi-byte character sets (Tatsuo) - - -Fix bug where COPY CSV mode considered any -\. to terminate the copy data The new code -requires \. to appear alone on a line, as per -documentation. - -Make COPY CSV mode quote a literal data value of -\. to ensure it cannot be interpreted as the -end-of-data marker (Bruce) - -Various fixes for functions returning RECORDs -(Tom) - -Fix processing of postgresql.conf so a -final line with no newline is processed properly (Tom) - - -Fix bug in /contrib/pgcrypto gen_salt, -which caused it not to use all available salt space for MD5 and -XDES algorithms (Marko Kreen, Solar Designer) -Salts for Blowfish and standard DES are unaffected. - -Fix autovacuum crash when processing expression indexes - - -Fix /contrib/dblink to throw an error, -rather than crashing, when the number of columns specified is different from -what's actually returned by the query (Joe) - - - - - - - - Release 8.1.1 - - - Release date: - 2005-12-12 - - - - This release contains a variety of fixes from 8.1.0. - For information about new features in the 8.1 major release, see - . - - - - Migration to Version 8.1.1 - - - A dump/restore is not required for those running 8.1.X. - - - - - Changes - - -Fix incorrect optimizations of outer-join conditions -(Tom) - -Fix problems with wrong reported column names in cases -involving sub-selects flattened by the optimizer (Tom) - -Fix update failures in scenarios involving CHECK constraints, -toasted columns, and indexes (Tom) - -Fix bgwriter problems after recovering from errors -(Tom) - -The background writer was found to leak buffer pins after write errors. -While not fatal in itself, this might lead to mysterious blockages of -later VACUUM commands. - - - -Prevent failure if client sends Bind protocol message -when current transaction is already aborted - -/contrib/tsearch2 and /contrib/ltree -fixes (Teodor) - -Fix problems with translated error messages in -languages that require word reordering, such as Turkish; also problems with -unexpected truncation of output strings and wrong display of the smallest -possible bigint value (Andrew, Tom) - -These problems only appeared on platforms that were using our -port/snprintf.c code, which includes BSD variants if ---enable-nls was given, and perhaps others. In addition, -a different form of the translated-error-message problem could appear -on Windows depending on which version of libintl was used. - - -Re-allow AM/PM, HH, -HH12, and D format specifiers for -to_char(time) and to_char(interval). -(to_char(interval) should probably use -HH24.) (Bruce) - -AIX, HPUX, and MSVC compile fixes (Tom, Hiroshi -Saito) - -Optimizer improvements (Tom) - -Retry file reads and writes after Windows -NO_SYSTEM_RESOURCES error (Qingqing Zhou) - -Prevent autovacuum from crashing during -ANALYZE of expression index (Alvaro) - -Fix problems with ON COMMIT DELETE ROWS temp -tables - -Fix problems when a trigger alters the output of a SELECT -DISTINCT query - -Add 8.1.0 release note item on how to migrate invalid -UTF-8 byte sequences (Paul Lindner) - - - - - - - Release 8.1 - - - Release date: - 2005-11-08 - - - - Overview - - - Major changes in this release: - - - - - - - Improve concurrent access to the shared buffer cache (Tom) - - - - - Access to the shared buffer cache was identified as a - significant scalability problem, particularly on multi-CPU - systems. In this release, the way that locking is done in the - buffer manager has been overhauled to reduce lock contention - and improve scalability. The buffer manager has also been - changed to use a clock sweep replacement - policy. - - - - - - - Allow index scans to use an intermediate in-memory bitmap (Tom) - - - - - In previous releases, only a single index could be used to do - lookups on a table. With this feature, if a query has - WHERE tab.col1 = 4 and tab.col2 = 9, and there is - no multicolumn index on col1 and col2, - but there is an index on col1 and another on - col2, it is possible to search both indexes and - combine the results in memory, then do heap fetches for only - the rows matching both the col1 and - col2 restrictions. This is very useful in - environments that have a lot of unstructured queries where it - is impossible to create indexes that match all possible access - conditions. Bitmap scans are useful even with a single index, - as they reduce the amount of random access needed; a bitmap - index scan is efficient for retrieving fairly large fractions - of the complete table, whereas plain index scans are not. - - - - - - - Add two-phase commit (Heikki Linnakangas, Alvaro, Tom) - - - - - Two-phase commit allows transactions to be "prepared" on several - computers, and once all computers have successfully prepared - their transactions (none failed), all transactions can be - committed. Even if a machine crashes after a prepare, the - prepared transaction can be committed after the machine is - restarted. New syntax includes PREPARE TRANSACTION and - COMMIT/ROLLBACK PREPARED. A new system view - pg_prepared_xacts has also been added. - - - - - - - Create a new role system that replaces users and groups - (Stephen Frost) - - - - - Roles are a combination of users and groups. Like users, they - can have login capability, and like groups, a role can have - other roles as members. Roles basically remove the distinction - between users and groups. For example, a role can: - - - - - - - Have login capability (optionally) - - - - - - Own objects - - - - - - Hold access permissions for database objects - - - - - - Inherit permissions from other roles it is a member of - - - - - - Once a user logs into a role, she obtains capabilities of - the login role plus any inherited roles, and can use - SET ROLE to switch to other roles she is a member of. - This feature is a generalization of the SQL standard's concept of - roles. - This change also replaces pg_shadow and - pg_group by new role-capable catalogs - pg_authid and pg_auth_members. The old - tables are redefined as read-only views on the new role tables. - - - - - - - Automatically use indexes for MIN() and - MAX() (Tom) - - - - - In previous releases, the only way to use an index for - MIN() or MAX() was to rewrite the - query as SELECT col FROM tab ORDER BY col LIMIT 1. - Index usage now happens automatically. - - - - - - - Move /contrib/pg_autovacuum into the main server - (Alvaro) - - - - - Integrating autovacuum into the server allows it to be - automatically started and stopped in sync with the database - server, and allows autovacuum to be configured from - postgresql.conf. - - - - - - - Add shared row level locks using SELECT ... FOR SHARE - (Alvaro) - - - - - While PostgreSQL's MVCC locking - allows SELECT to never be blocked by writers and - therefore does not need shared row locks for typical operations, - shared locks are useful for applications that require shared row - locking. In particular this reduces the locking requirements - imposed by referential integrity checks. - - - - - - - Add dependencies on shared objects, specifically roles - (Alvaro) - - - - - This extension of the dependency mechanism prevents roles from - being dropped while there are still database objects they own. - Formerly it was possible to accidentally orphan objects by - deleting their owner. While this could be recovered from, it - was messy and unpleasant. - - - - - - - Improve performance for partitioned tables (Simon) - - - - - The new constraint_exclusion configuration - parameter avoids lookups on child tables where constraints indicate - that no matching rows exist in the child table. - - - This allows for a basic type of table partitioning. If child tables - store separate key ranges and this is enforced using appropriate - CHECK constraints, the optimizer will skip child - table accesses when the constraint guarantees no matching rows - exist in the child table. - - - - - - - - - Migration to Version 8.1 - - - A dump/restore using pg_dump is required - for those wishing to migrate data from any previous release. - - - - The 8.0 release announced that the to_char() function - for intervals would be removed in 8.1. However, since no better API - has been suggested, to_char(interval) has been enhanced in - 8.1 and will remain in the server. - - - - Observe the following incompatibilities: - - - - - - - add_missing_from is now false by default (Neil) - - - By default, we now generate an error if a table is used in a query - without a FROM reference. The old behavior is still - available, but the parameter must be set to 'true' to obtain it. - - - - It might be necessary to set add_missing_from to true - in order to load an existing dump file, if the dump contains any - views or rules created using the implicit-FROM syntax. - This should be a one-time annoyance, because - PostgreSQL 8.1 will convert - such views and rules to standard explicit-FROM syntax. - Subsequent dumps will therefore not have the problem. - - - - - - Cause input of a zero-length string ('') for - float4/float8/oid - to throw an error, rather than treating it as a zero (Neil) - - - This change is consistent with the current handling of - zero-length strings for integers. The schedule for this change - was announced in 8.0. - - - - - - default_with_oids is now false by default (Neil) - - - With this option set to false, user-created tables no longer - have an OID column unless WITH OIDS is specified in - CREATE TABLE. Though OIDs have existed in all - releases of PostgreSQL, their use is limited - because they are only four bytes long and the counter is shared - across all installed databases. The preferred way of uniquely - identifying rows is via sequences and the SERIAL type, - which have been supported since PostgreSQL 6.4. - - - - - - Add E'' syntax so eventually ordinary strings can - treat backslashes literally (Bruce) - - - Currently PostgreSQL processes a - backslash in a string literal as introducing a special escape sequence, - e.g. \n or \010. - While this allows easy entry of special values, it is - nonstandard and makes porting of applications from other - databases more difficult. For this reason, the - PostgreSQL project is planning to - remove the special meaning of backslashes in strings. For - backward compatibility and for users who want special backslash - processing, a new string syntax has been created. This new string - syntax is formed by writing an E immediately preceding the - single quote that starts the string, e.g. E'hi\n'. While - this release does not change the handling of backslashes in strings, it - does add new configuration parameters to help users migrate applications - for future releases: - - - - - - standard_conforming_strings — does this release - treat backslashes literally in ordinary strings? - - - - - - escape_string_warning — warn about backslashes in - ordinary (non-E) strings - - - - - - - The standard_conforming_strings value is read-only. - Applications can retrieve the value to know how backslashes are - processed. (Presence of the parameter can also be taken as an - indication that E'' string syntax is supported.) - In a future release, standard_conforming_strings - will be true, meaning backslashes will be treated literally in - non-E strings. To prepare for this change, use E'' - strings in places that need special backslash processing, and - turn on escape_string_warning to find additional - strings that need to be converted to use E''. - Also, use two single-quotes ('') to embed a literal - single-quote in a string, rather than the - PostgreSQL-supported syntax of - backslash single-quote (\'). The former is - standards-conforming and does not require the use of the - E'' string syntax. You can also use the - $$ string syntax, which does not treat backslashes - specially. - - - - - - Make REINDEX DATABASE reindex all indexes in the - database (Tom) - - - Formerly, REINDEX DATABASE reindexed only - system tables. This new behavior seems more intuitive. A new - command REINDEX SYSTEM provides the old functionality - of reindexing just the system tables. - - - - - - Read-only large object descriptors now obey MVCC snapshot semantics - - - When a large object is opened with INV_READ (and not - INV_WRITE), the data read from the descriptor will now - reflect a snapshot of the large object's state at the - time of the transaction snapshot in use by the query that called - lo_open(). To obtain the old behavior of always - returning the latest committed data, include INV_WRITE - in the mode flags for lo_open(). - - - - - - Add proper dependencies for arguments of sequence functions (Tom) - - - In previous releases, sequence names passed to nextval(), - currval(), and setval() were stored as - simple text strings, meaning that renaming or dropping a - sequence used in a DEFAULT clause made the clause - invalid. This release stores all newly-created sequence function - arguments as internal OIDs, allowing them to track sequence - renaming, and adding dependency information that prevents - improper sequence removal. It also makes such DEFAULT - clauses immune to schema renaming and search path changes. - - - Some applications might rely on the old behavior of - run-time lookup for sequence names. This can still be done by - explicitly casting the argument to text, for example - nextval('myseq'::text). - - - Pre-8.1 database dumps loaded into 8.1 will use the old text-based - representation and therefore will not have the features of - OID-stored arguments. However, it is possible to update a - database containing text-based DEFAULT clauses. - First, save this query into a file, such as fixseq.sql: - -SELECT 'ALTER TABLE ' || - pg_catalog.quote_ident(n.nspname) || '.' || - pg_catalog.quote_ident(c.relname) || - ' ALTER COLUMN ' || pg_catalog.quote_ident(a.attname) || - ' SET DEFAULT ' || - regexp_replace(d.adsrc, - $$val\(\(('[^']*')::text\)::regclass$$, - $$val(\1$$, - 'g') || - ';' -FROM pg_namespace n, pg_class c, pg_attribute a, pg_attrdef d -WHERE n.oid = c.relnamespace AND - c.oid = a.attrelid AND - a.attrelid = d.adrelid AND - a.attnum = d.adnum AND - d.adsrc ~ $$val\(\('[^']*'::text\)::regclass$$; - - Next, run the query against a database to find what - adjustments are required, like this for database db1: - -psql -t -f fixseq.sql db1 - - This will show the ALTER TABLE commands needed to - convert the database to the newer OID-based representation. - If the commands look reasonable, run this to update the database: - -psql -t -f fixseq.sql db1 | psql -e db1 - - This process must be repeated in each database to be updated. - - - - - - In psql, treat unquoted - \{digit}+ sequences as octal (Bruce) - - - In previous releases, \{digit}+ sequences were - treated as decimal, and only \0{digit}+ were treated - as octal. This change was made for consistency. - - - - - - Remove grammar productions for prefix and postfix % - and ^ operators - (Tom) - - - These have never been documented and complicated the use of the - modulus operator (%) with negative numbers. - - - - - - Make &< and &> for polygons - consistent with the box "over" operators (Tom) - - - - - - CREATE LANGUAGE can ignore the provided arguments - in favor of information from pg_pltemplate - (Tom) - - - A new system catalog pg_pltemplate has been defined - to carry information about the preferred definitions of procedural - languages (such as whether they have validator functions). When - an entry exists in this catalog for the language being created, - CREATE LANGUAGE will ignore all its parameters except the - language name and instead use the catalog information. This measure - was taken because of increasing problems with obsolete language - definitions being loaded by old dump files. As of 8.1, - pg_dump will dump procedural language definitions as - just CREATE LANGUAGE name, relying - on a template entry to exist at load time. We expect this will be a - more future-proof representation. - - - - - - Make pg_cancel_backend(int) return a - boolean rather than an integer (Neil) - - - - - - Some users are having problems loading UTF-8 data into 8.1.X. - This is because previous versions allowed invalid UTF-8 byte - sequences to be entered into the database, and this release - properly accepts only valid UTF-8 sequences. One way to correct a - dumpfile is to run the command iconv -c -f UTF-8 -t - UTF-8 -o cleanfile.sql dumpfile.sql. The -c option - removes invalid character sequences. A diff of the two files will - show the sequences that are invalid. iconv reads the - entire input file into memory so it might be necessary to use - split to break up the dump into multiple smaller - files for processing. - - - - - - - - Additional Changes - - - Below you will find a detailed account of the additional changes - between PostgreSQL 8.1 and the - previous major release. - - - - Performance Improvements - - - - - Improve GiST and R-tree index performance (Neil) - - - - - - Improve the optimizer, including auto-resizing of hash joins - (Tom) - - - - - - Overhaul internal API in several areas - - - - - - Change WAL record CRCs from 64-bit to 32-bit (Tom) - - - We determined that the extra cost of computing 64-bit CRCs was - significant, and the gain in reliability too marginal to justify it. - - - - - - Prevent writing large empty gaps in WAL pages (Tom) - - - - - - Improve spinlock behavior on SMP machines, particularly Opterons (Tom) - - - - - - Allow nonconsecutive index columns to be used in a multicolumn - index (Tom) - - - For example, this allows an index on columns a,b,c to be used in - a query with WHERE a = 4 and c = 10. - - - - - - Skip WAL logging for CREATE TABLE AS / - SELECT INTO (Simon) - - - Since a crash during CREATE TABLE AS would cause the - table to be dropped during recovery, there is no reason to WAL - log as the table is loaded. (Logging still happens if WAL - archiving is enabled, however.) - - - - - - Allow concurrent GiST index access (Teodor, Oleg) - - - - - - Add configuration parameter full_page_writes to - control writing full pages to WAL (Bruce) - - - To prevent partial disk writes from corrupting the database, - PostgreSQL writes a complete copy of - each database disk page to WAL the first time it is modified - after a checkpoint. This option turns off that functionality for more - speed. This is safe to use with battery-backed disk caches where - partial page writes cannot happen. - - - - - - Use O_DIRECT if available when using - O_SYNC for wal_sync_method - (Itagaki Takahiro) - - - O_DIRECT causes disk writes to bypass the kernel - cache, and for WAL writes, this improves performance. - - - - - - Improve COPY FROM performance (Alon Goldshuv) - - - This was accomplished by reading COPY input in - larger chunks, rather than character by character. - - - - - - Improve the performance of COUNT(), - SUM, AVG(), - STDDEV(), and - VARIANCE() (Neil, Tom) - - - - - - - Server Changes - - - - - Prevent problems due to transaction ID (XID) wraparound (Tom) - - - The server will now warn when the transaction counter approaches - the wraparound point. If the counter becomes too close to wraparound, - the server will stop accepting queries. This ensures that data is - not lost before needed vacuuming is performed. - - - - - - Fix problems with object IDs (OIDs) conflicting with existing system - objects after the OID counter has wrapped around (Tom) - - - - - - Add warning about the need to increase - max_fsm_relations and max_fsm_pages - during VACUUM (Ron Mayer) - - - - - - Add temp_buffers configuration parameter to allow - users to determine the size of the local buffer area for - temporary table access (Tom) - - - - - - Add session start time and client IP address to - pg_stat_activity (Magnus) - - - - - - Adjust pg_stat views for bitmap scans (Tom) - - - The meanings of some of the fields have changed slightly. - - - - - - Enhance pg_locks view (Tom) - - - - - - Log queries for client-side PREPARE and - EXECUTE (Simon) - - - - - - Allow Kerberos name and user name case sensitivity to be - specified in postgresql.conf (Magnus) - - - - - - Add configuration parameter krb_server_hostname so - that the server host name can be specified as part of service - principal (Todd Kover) - - - If not set, any service principal matching an entry in the - keytab can be used. This is new Kerberos matching behavior in - this release. - - - - - - Add log_line_prefix options for millisecond - timestamps (%m) and remote host (%h) (Ed - L.) - - - - - - Add WAL logging for GiST indexes (Teodor, Oleg) - - - GiST indexes are now safe for crash and point-in-time recovery. - - - - - - Remove old *.backup files when we do - pg_stop_backup() (Bruce) - - - This prevents a large number of *.backup files from - existing in pg_xlog/. - - - - - - Add configuration parameters to control TCP/IP keep-alive - times for idle, interval, and count (Oliver Jowett) - - - - These values can be changed to allow more rapid detection of - lost client connections. - - - - - - Add per-user and per-database connection limits (Petr Jelinek) - - - Using ALTER USER and ALTER DATABASE, - limits can now be enforced on the maximum number of sessions that - can concurrently connect as a specific user or to a specific database. - Setting the limit to zero disables user or database connections. - - - - - - Allow more than two gigabytes of shared memory and per-backend - work memory on 64-bit machines (Koichi Suzuki) - - - - - - New system catalog pg_pltemplate allows overriding - obsolete procedural-language definitions in dump files (Tom) - - - - - - - - - Query Changes - - - - - Add temporary views (Koju Iijima, Neil) - - - - - - Fix HAVING without any aggregate functions or - GROUP BY so that the query returns a single group (Tom) - - - Previously, such a case would treat the HAVING - clause the same as a WHERE clause. This was not per spec. - - - - - - Add USING clause to allow additional tables to be - specified to DELETE (Euler Taveira de Oliveira, Neil) - - - In prior releases, there was no clear method for specifying - additional tables to be used for joins in a DELETE - statement. UPDATE already has a FROM - clause for this purpose. - - - - - - Add support for \x hex escapes in backend and ecpg - strings (Bruce) - - - This is just like the standard C \x escape syntax. - Octal escapes were already supported. - - - - - - Add BETWEEN SYMMETRIC query syntax (Pavel Stehule) - - - This feature allows BETWEEN comparisons without - requiring the first value to be less than the second. For - example, 2 BETWEEN [ASYMMETRIC] 3 AND 1 returns - false, while 2 BETWEEN SYMMETRIC 3 AND 1 returns - true. BETWEEN ASYMMETRIC was already supported. - - - - - - Add NOWAIT option to SELECT ... FOR - UPDATE/SHARE (Hans-Juergen Schoenig) - - - While the statement_timeout configuration - parameter allows a query taking more than a certain amount of - time to be canceled, the NOWAIT option allows a - query to be canceled as soon as a SELECT ... FOR - UPDATE/SHARE command cannot immediately acquire a row lock. - - - - - - - - Object Manipulation Changes - - - - - Track dependencies of shared objects (Alvaro) - - - PostgreSQL allows global tables - (users, databases, tablespaces) to reference information in - multiple databases. This addition adds dependency information - for global tables, so, for example, user ownership can be - tracked across databases, so a user who owns something in any - database can no longer be removed. Dependency tracking already - existed for database-local objects. - - - - - - Allow limited ALTER OWNER commands to be performed - by the object owner (Stephen Frost) - - - Prior releases allowed only superusers to change object owners. - Now, ownership can be transferred if the user executing the command - owns the object and would be able to create it as the new owner - (that is, the user is a member of the new owning role and that role - has the CREATE permission that would be needed to create the object - afresh). - - - - - - Add ALTER object SET SCHEMA capability - for some object types (tables, functions, types) (Bernd Helmle) - - - This allows objects to be moved to different schemas. - - - - - - Add ALTER TABLE ENABLE/DISABLE TRIGGER to - disable triggers (Satoshi Nagayasu) - - - - - - - - - Utility Command Changes - - - - - Allow TRUNCATE to truncate multiple tables in a - single command (Alvaro) - - - Because of referential integrity checks, it is not allowed to - truncate a table that is part of a referential integrity - constraint. Using this new functionality, TRUNCATE - can be used to truncate such tables, if both tables involved in - a referential integrity constraint are truncated in a single - TRUNCATE command. - - - - - - Properly process carriage returns and line feeds in - COPY CSV mode (Andrew) - - - In release 8.0, carriage returns and line feeds in CSV - COPY TO were processed in an inconsistent manner. (This was - documented on the TODO list.) - - - - - - Add COPY WITH CSV HEADER to allow a header line as - the first line in COPY (Andrew) - - - This allows handling of the common CSV usage of - placing the column names on the first line of the data file. For - COPY TO, the first line contains the column names, - and for COPY FROM, the first line is ignored. - - - - - - On Windows, display better sub-second precision in - EXPLAIN ANALYZE (Magnus) - - - - - - Add trigger duration display to EXPLAIN ANALYZE - (Tom) - - - Prior releases included trigger execution time as part of the - total execution time, but did not show it separately. It is now - possible to see how much time is spent in each trigger. - - - - - - Add support for \x hex escapes in COPY - (Sergey Ten) - - - Previous releases only supported octal escapes. - - - - - - Make SHOW ALL include variable descriptions - (Matthias Schmidt) - - - SHOW varname still only displays the variable's - value and does not include the description. - - - - - - Make initdb create a new standard - database called postgres, and convert utilities to - use postgres rather than template1 for - standard lookups (Dave) - - - In prior releases, template1 was used both as a - default connection for utilities like - createuser, and as a template for - new databases. This caused CREATE DATABASE to - sometimes fail, because a new database cannot be created if - anyone else is in the template database. With this change, the - default connection database is now postgres, - meaning it is much less likely someone will be using - template1 during CREATE DATABASE. - - - - - - Create new reindexdb command-line - utility by moving /contrib/reindexdb into the - server (Euler Taveira de Oliveira) - - - - - - - - - Data Type and Function Changes - - - - - Add MAX() and MIN() aggregates for - array types (Koju Iijima) - - - - - - Fix to_date() and to_timestamp() to - behave reasonably when CC and YY fields - are both used (Karel Zak) - - - If the format specification contains CC and a year - specification is YYY or longer, ignore the - CC. If the year specification is YY or - shorter, interpret CC as the previous century. - - - - - - Add md5(bytea) (Abhijit Menon-Sen) - - - md5(text) already existed. - - - - - - Add support for numeric ^ numeric based on - power(numeric, numeric) - - - The function already existed, but there was no operator assigned - to it. - - - - - - Fix NUMERIC modulus by properly truncating the quotient - during computation (Bruce) - - - In previous releases, modulus for large values sometimes - returned negative results due to rounding of the quotient. - - - - - - Add a function lastval() (Dennis Björklund) - - - lastval() is a simplified version of - currval(). It automatically determines the proper - sequence name based on the most recent nextval() or - setval() call performed by the current session. - - - - - - Add to_timestamp(DOUBLE PRECISION) (Michael Glaesemann) - - - Converts Unix seconds since 1970 to a TIMESTAMP WITH - TIMEZONE. - - - - - - Add pg_postmaster_start_time() function (Euler - Taveira de Oliveira, Matthias Schmidt) - - - - - - Allow the full use of time zone names in AT TIME - ZONE, not just the short list previously available (Magnus) - - - Previously, only a predefined list of time zone names were - supported by AT TIME ZONE. Now any supported time - zone name can be used, e.g.: - -SELECT CURRENT_TIMESTAMP AT TIME ZONE 'Europe/London'; - - In the above query, the time zone used is adjusted based on the - daylight saving time rules that were in effect on the supplied - date. - - - - - - Add GREATEST() and LEAST() variadic - functions (Pavel Stehule) - - - These functions take a variable number of arguments and return - the greatest or least value among the arguments. - - - - - - Add pg_column_size() (Mark Kirkwood) - - - This returns storage size of a column, which might be compressed. - - - - - - Add regexp_replace() (Atsushi Ogawa) - - - This allows regular expression replacement, like sed. An optional - flag argument allows selection of global (replace all) and - case-insensitive modes. - - - - - - Fix interval division and multiplication (Bruce) - - - Previous versions sometimes returned unjustified results, like - '4 months'::interval / 5 returning '1 mon - -6 days'. - - - - - - Fix roundoff behavior in timestamp, time, and interval output (Tom) - - - This fixes some cases in which the seconds field would be shown as - 60 instead of incrementing the higher-order fields. - - - - - - Add a separate day field to type interval so a one day - interval can be distinguished from a 24 hour interval (Michael - Glaesemann) - - - Days that contain a daylight saving time adjustment are not 24 - hours long, but typically 23 or 25 hours. This change creates a - conceptual distinction between intervals of so many days - and intervals of so many hours. Adding - 1 day to a timestamp now gives the same local time on - the next day even if a daylight saving time adjustment occurs - between, whereas adding 24 hours will give a different - local time when this happens. For example, under US DST rules: - -'2005-04-03 00:00:00-05' + '1 day' = '2005-04-04 00:00:00-04' -'2005-04-03 00:00:00-05' + '24 hours' = '2005-04-04 01:00:00-04' - - - - - - - Add justify_days() and justify_hours() - (Michael Glaesemann) - - - These functions, respectively, adjust days to an appropriate - number of full months and days, and adjust hours to an - appropriate number of full days and hours. - - - - - - Move /contrib/dbsize into the backend, and rename - some of the functions (Dave Page, Andreas Pflug) - - - - - - - pg_tablespace_size() - - - - - - pg_database_size() - - - - - - pg_relation_size() - - - - - - pg_total_relation_size() - - - - - - pg_size_pretty() - - - - - - - pg_total_relation_size() includes indexes and TOAST - tables. - - - - - - Add functions for read-only file access to the cluster directory - (Dave Page, Andreas Pflug) - - - - - - - pg_stat_file() - - - - - - pg_read_file() - - - - - - pg_ls_dir() - - - - - - - - - - Add pg_reload_conf() to force reloading of the - configuration files (Dave Page, Andreas Pflug) - - - - - - Add pg_rotate_logfile() to force rotation of the - server log file (Dave Page, Andreas Pflug) - - - - - - Change pg_stat_* views to include TOAST tables (Tom) - - - - - - - - - Encoding and Locale Changes - - - - - Rename some encodings to be more consistent and to follow - international standards (Bruce) - - - - - - - UNICODE is now UTF8 - - - - - - ALT is now WIN866 - - - - - - WIN is now WIN1251 - - - - - - TCVN is now WIN1258 - - - - - - - - The original names still work. - - - - - - Add support for WIN1252 encoding (Roland Volkmann) - - - - - - Add support for four-byte UTF8 characters (John - Hansen) - - - Previously only one, two, and three-byte UTF8 characters - were supported. This is particularly important for support for - some Chinese character sets. - - - - - - Allow direct conversion between EUC_JP and - SJIS to improve performance (Atsushi Ogawa) - - - - - - Allow the UTF8 encoding to work on Windows (Magnus) - - - This is done by mapping UTF8 to the Windows-native UTF16 - implementation. - - - - - - - - - General Server-Side Language Changes - - - - - Fix ALTER LANGUAGE RENAME (Sergey Yatskevich) - - - - - - Allow function characteristics, like strictness and volatility, - to be modified via ALTER FUNCTION (Neil) - - - - - - Increase the maximum number of function arguments to 100 (Tom) - - - - - - Allow SQL and PL/pgSQL functions to use OUT and - INOUT parameters (Tom) - - - OUT is an alternate way for a function to return - values. Instead of using RETURN, values can be - returned by assigning to parameters declared as OUT or - INOUT. This is notationally simpler in some cases, - particularly so when multiple values need to be returned. - While returning multiple values from a function - was possible in previous releases, this greatly simplifies the - process. (The feature will be extended to other server-side - languages in future releases.) - - - - - - Move language handler functions into the pg_catalog schema - - - This makes it easier to drop the public schema if desired. - - - - - - Add SPI_getnspname() to SPI (Neil) - - - - - - - - PL/pgSQL Server-Side Language Changes - - - - - Overhaul the memory management of PL/pgSQL functions (Neil) - - - The parsetree of each function is now stored in a separate - memory context. This allows this memory to be easily reclaimed - when it is no longer needed. - - - - - - Check function syntax at CREATE FUNCTION time, - rather than at runtime (Neil) - - - Previously, most syntax errors were reported only when the - function was executed. - - - - - - Allow OPEN to open non-SELECT queries - like EXPLAIN and SHOW (Tom) - - - - - - No longer require functions to issue a RETURN - statement (Tom) - - - This is a byproduct of the newly added OUT and - INOUT functionality. RETURN can - be omitted when it is not needed to provide the function's - return value. - - - - - - Add support for an optional INTO clause to - PL/pgSQL's EXECUTE statement (Pavel Stehule, Neil) - - - - - - Make CREATE TABLE AS set ROW_COUNT (Tom) - - - - - - Define SQLSTATE and SQLERRM to return - the SQLSTATE and error message of the current - exception (Pavel Stehule, Neil) - - - These variables are only defined inside exception blocks. - - - - - - Allow the parameters to the RAISE statement to be - expressions (Pavel Stehule, Neil) - - - - - - Add a loop CONTINUE statement (Pavel Stehule, Neil) - - - - - - Allow block and loop labels (Pavel Stehule) - - - - - - - - - PL/Perl Server-Side Language Changes - - - - - Allow large result sets to be returned efficiently (Abhijit - Menon-Sen) - - - This allows functions to use return_next() to avoid - building the entire result set in memory. - - - - - - Allow one-row-at-a-time retrieval of query results (Abhijit Menon-Sen) - - - This allows functions to use spi_query() and - spi_fetchrow() to avoid accumulating the entire - result set in memory. - - - - - - Force PL/Perl to handle strings as UTF8 if the - server encoding is UTF8 (David Kamholz) - - - - - - Add a validator function for PL/Perl (Andrew) - - - This allows syntax errors to be reported at definition time, - rather than execution time. - - - - - - Allow PL/Perl to return a Perl array when the function returns - an array type (Andrew) - - - This basically maps PostgreSQL arrays - to Perl arrays. - - - - - - Allow Perl nonfatal warnings to generate NOTICE - messages (Andrew) - - - - - - Allow Perl's strict mode to be enabled (Andrew) - - - - - - - - - <application>psql</application> Changes - - - - - Add \set ON_ERROR_ROLLBACK to allow statements in - a transaction to error without affecting the rest of the - transaction (Greg Sabino Mullane) - - - This is basically implemented by wrapping every statement in a - sub-transaction. - - - - - - Add support for \x hex strings in - psql variables (Bruce) - - - Octal escapes were already supported. - - - - - - Add support for troff -ms output format (Roger - Leigh) - - - - - - Allow the history file location to be controlled by - HISTFILE (Andreas Seltenreich) - - - This allows configuration of per-database history storage. - - - - - - Prevent \x (expanded mode) from affecting - the output of \d tablename (Neil) - - - - - - Add option to psql to - log sessions (Lorne Sunley) - - - This option was added because some operating systems do not have - simple command-line activity logging functionality. - - - - - - Make \d show the tablespaces of indexes (Qingqing - Zhou) - - - - - - Allow psql help (\h) to - make a best guess on the proper help information (Greg Sabino - Mullane) - - - This allows the user to just add \h to the front of - the syntax error query and get help on the supported syntax. - Previously any additional query text beyond the command name - had to be removed to use \h. - - - - - - Add \pset numericlocale to allow numbers to be - output in a locale-aware format (Eugen Nedelcu) - - - For example, using C locale 100000 would - be output as 100,000.0 while a European locale might - output this value as 100.000,0. - - - - - - Make startup banner show both server version number and - psql's version number, when they are different (Bruce) - - - Also, a warning will be shown if the server and psql - are from different major releases. - - - - - - - - - <application>pg_dump</application> Changes - - - - - Add / switch to - pg_restore (Richard van den Berg) - - - This allows just the objects in a specified schema to be restored. - - - - - - Allow pg_dump to dump large objects even in - text mode (Tom) - - - With this change, large objects are now always dumped; the former - switch is a no-op. - - - - - - Allow pg_dump to dump a consistent snapshot of - large objects (Tom) - - - - - - Dump comments for large objects (Tom) - - - - - - Add to pg_dump - (Magnus Hagander) - - - This allows a database to be dumped in an encoding that is - different from the server's encoding. This is valuable when - transferring the dump to a machine with a different encoding. - - - - - - Rely on pg_pltemplate for procedural languages (Tom) - - - If the call handler for a procedural language is in the - pg_catalog schema, pg_dump does not - dump the handler. Instead, it dumps the language using just - CREATE LANGUAGE name, - relying on the pg_pltemplate catalog to provide - the language's creation parameters at load time. - - - - - - - - - <application>libpq</application> Changes - - - - - Add a PGPASSFILE environment variable to specify the - password file's filename (Andrew) - - - - - - Add lo_create(), that is similar to - lo_creat() but allows the OID of the large object - to be specified (Tom) - - - - - - Make libpq consistently return an error - to the client application on malloc() - failure (Neil) - - - - - - - - Source Code Changes - - - - - Fix pgxs to support building against a relocated - installation - - - - - - Add spinlock support for the Itanium processor using Intel - compiler (Vikram Kalsi) - - - - - - Add Kerberos 5 support for Windows (Magnus) - - - - - - Add Chinese FAQ (laser@pgsqldb.com) - - - - - - Rename Rendezvous to Bonjour to match OS/X feature renaming - (Bruce) - - - - - - Add support for fsync_writethrough on - macOS (Chris Campbell) - - - - - - Streamline the passing of information within the server, the - optimizer, and the lock system (Tom) - - - - - - Allow pg_config to be compiled using MSVC (Andrew) - - - This is required to build DBD::Pg using MSVC. - - - - - - Remove support for Kerberos V4 (Magnus) - - - Kerberos 4 had security vulnerabilities and is no longer - maintained. - - - - - - Code cleanups (Coverity static analysis performed by - EnterpriseDB) - - - - - - Modify postgresql.conf to use documentation defaults - on/off rather than - true/false (Bruce) - - - - - - Enhance pg_config to be able to report more - build-time values (Tom) - - - - - - Allow libpq to be built thread-safe - on Windows (Dave Page) - - - - - - Allow IPv6 connections to be used on Windows (Andrew) - - - - - - Add Server Administration documentation about I/O subsystem - reliability (Bruce) - - - - - - Move private declarations from gist.h to - gist_private.h (Neil) - - - - In previous releases, gist.h contained both the - public GiST API (intended for use by authors of GiST index - implementations) as well as some private declarations used by - the implementation of GiST itself. The latter have been moved - to a separate file, gist_private.h. Most GiST - index implementations should be unaffected. - - - - - - Overhaul GiST memory management (Neil) - - - - GiST methods are now always invoked in a short-lived memory - context. Therefore, memory allocated via palloc() - will be reclaimed automatically, so GiST index implementations - do not need to manually release allocated memory via - pfree(). - - - - - - - - Contrib Changes - - - - - Add /contrib/pg_buffercache contrib module (Mark - Kirkwood) - - - This displays the contents of the buffer cache, for debugging and - performance tuning purposes. - - - - - - Remove /contrib/array because it is obsolete (Tom) - - - - - - Clean up the /contrib/lo module (Tom) - - - - - - Move /contrib/findoidjoins to - /src/tools (Tom) - - - - - - Remove the <<, >>, - &<, and &> operators from - /contrib/cube - - - These operators were not useful. - - - - - - Improve /contrib/btree_gist (Janko Richter) - - - - - - Improve /contrib/pgbench (Tomoaki Sato, Tatsuo) - - - There is now a facility for testing with SQL command scripts given - by the user, instead of only a hard-wired command sequence. - - - - - - Improve /contrib/pgcrypto (Marko Kreen) - - - - - - - Implementation of OpenPGP symmetric-key and public-key encryption - - - Both RSA and Elgamal public-key algorithms are supported. - - - - - - Stand alone build: include SHA256/384/512 hashes, Fortuna PRNG - - - - - - OpenSSL build: support 3DES, use internal AES with OpenSSL < 0.9.7 - - - - - - Take build parameters (OpenSSL, zlib) from configure result - - - There is no need to edit the Makefile anymore. - - - - - - Remove support for libmhash and libmcrypt - - - - - - - - - - - diff --git a/doc/src/sgml/release-8.2.sgml b/doc/src/sgml/release-8.2.sgml deleted file mode 100644 index 51239f9b9d9..00000000000 --- a/doc/src/sgml/release-8.2.sgml +++ /dev/null @@ -1,7077 +0,0 @@ - - - - - Release 8.2.23 - - - Release date: - 2011-12-05 - - - - This release contains a variety of fixes from 8.2.22. - For information about new features in the 8.2 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 8.2.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 8.2.23 - - - A dump/restore is not required for those running 8.2.X. - - - - However, a longstanding error was discovered in the definition of the - information_schema.referential_constraints view. If you - rely on correct results from that view, you should replace its - definition as explained in the first changelog item below. - - - - Also, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Fix bugs in information_schema.referential_constraints view - (Tom Lane) - - - - This view was being insufficiently careful about matching the - foreign-key constraint to the depended-on primary or unique key - constraint. That could result in failure to show a foreign key - constraint at all, or showing it multiple times, or claiming that it - depends on a different constraint than the one it really does. - - - - Since the view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can (as a superuser) drop the - information_schema schema then re-create it by sourcing - SHAREDIR/information_schema.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) This must be repeated in each database - to be fixed. - - - - - - Fix TOAST-related data corruption during CREATE TABLE dest AS - SELECT * FROM src or INSERT INTO dest SELECT * FROM src - (Tom Lane) - - - - If a table has been modified by ALTER TABLE ADD COLUMN, - attempts to copy its data verbatim to another table could produce - corrupt results in certain corner cases. - The problem can only manifest in this precise form in 8.4 and later, - but we patched earlier versions as well in case there are other code - paths that could trigger the same bug. - - - - - - Fix race condition during toast table access from stale syscache entries - (Tom Lane) - - - - The typical symptom was transient errors like missing chunk - number 0 for toast value NNNNN in pg_toast_2619, where the cited - toast table would always belong to a system catalog. - - - - - - Improve locale support in money type's input and output - (Tom Lane) - - - - Aside from not supporting all standard - lc_monetary - formatting options, the input and output functions were inconsistent, - meaning there were locales in which dumped money values could - not be re-read. - - - - - - Don't let transform_null_equals - affect CASE foo WHEN NULL ... constructs - (Heikki Linnakangas) - - - - transform_null_equals is only supposed to affect - foo = NULL expressions written directly by the user, not - equality checks generated internally by this form of CASE. - - - - - - Change foreign-key trigger creation order to better support - self-referential foreign keys (Tom Lane) - - - - For a cascading foreign key that references its own table, a row update - will fire both the ON UPDATE trigger and the - CHECK trigger as one event. The ON UPDATE - trigger must execute first, else the CHECK will check a - non-final state of the row and possibly throw an inappropriate error. - However, the firing order of these triggers is determined by their - names, which generally sort in creation order since the triggers have - auto-generated names following the convention - RI_ConstraintTrigger_NNNN. A proper fix would require - modifying that convention, which we will do in 9.2, but it seems risky - to change it in existing releases. So this patch just changes the - creation order of the triggers. Users encountering this type of error - should drop and re-create the foreign key constraint to get its - triggers into the right order. - - - - - - Preserve blank lines within commands in psql's command - history (Robert Haas) - - - - The former behavior could cause problems if an empty line was removed - from within a string literal, for example. - - - - - - Use the preferred version of xsubpp to build PL/Perl, - not necessarily the operating system's main copy - (David Wheeler and Alex Hunsaker) - - - - - - Honor query cancel interrupts promptly in pgstatindex() - (Robert Haas) - - - - - - Ensure VPATH builds properly install all server header files - (Peter Eisentraut) - - - - - - Shorten file names reported in verbose error messages (Peter Eisentraut) - - - - Regular builds have always reported just the name of the C file - containing the error message call, but VPATH builds formerly - reported an absolute path name. - - - - - - Fix interpretation of Windows timezone names for Central America - (Tom Lane) - - - - Map Central America Standard Time to CST6, not - CST6CDT, because DST is generally not observed anywhere in - Central America. - - - - - - Update time zone data files to tzdata release 2011n - for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa; - also historical corrections for Alaska and British East Africa. - - - - - - - - - - Release 8.2.22 - - - Release date: - 2011-09-26 - - - - This release contains a variety of fixes from 8.2.21. - For information about new features in the 8.2 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.2.X release series in December 2011. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.2.22 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Fix multiple bugs in GiST index page split processing (Heikki - Linnakangas) - - - - The probability of occurrence was low, but these could lead to index - corruption. - - - - - - Avoid possibly accessing off the end of memory in ANALYZE - (Noah Misch) - - - - This fixes a very-low-probability server crash scenario. - - - - - - Fix race condition in relcache init file invalidation (Tom Lane) - - - - There was a window wherein a new backend process could read a stale init - file but miss the inval messages that would tell it the data is stale. - The result would be bizarre failures in catalog accesses, typically - could not read block 0 in file ... later during startup. - - - - - - Fix memory leak at end of a GiST index scan (Tom Lane) - - - - Commands that perform many separate GiST index scans, such as - verification of a new GiST-based exclusion constraint on a table - already containing many rows, could transiently require large amounts of - memory due to this leak. - - - - - - Fix performance problem when constructing a large, lossy bitmap - (Tom Lane) - - - - - - Fix array- and path-creating functions to ensure padding bytes are - zeroes (Tom Lane) - - - - This avoids some situations where the planner will think that - semantically-equal constants are not equal, resulting in poor - optimization. - - - - - - Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane) - - - - This could lead to loss of committed transactions after a server crash. - - - - - - Fix dump bug for VALUES in a view (Tom Lane) - - - - - - Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane) - - - - This operation doesn't work as expected and can lead to failures. - - - - - - Defend against integer overflow when computing size of a hash table (Tom - Lane) - - - - - - Fix portability bugs in use of credentials control messages for - peer authentication (Tom Lane) - - - - - - Fix typo in pg_srand48 seed initialization (Andres Freund) - - - - This led to failure to use all bits of the provided seed. This function - is not used on most platforms (only those without srandom), - and the potential security exposure from a less-random-than-expected - seed seems minimal in any case. - - - - - - Avoid integer overflow when the sum of LIMIT and - OFFSET values exceeds 2^63 (Heikki Linnakangas) - - - - - - Add overflow checks to int4 and int8 versions of - generate_series() (Robert Haas) - - - - - - Fix trailing-zero removal in to_char() (Marti Raudsepp) - - - - In a format with FM and no digit positions - after the decimal point, zeroes to the left of the decimal point could - be removed incorrectly. - - - - - - Fix pg_size_pretty() to avoid overflow for inputs close to - 2^63 (Tom Lane) - - - - - - Fix psql's counting of script file line numbers during - COPY from a different file (Tom Lane) - - - - - - Fix pg_restore's direct-to-database mode for - standard_conforming_strings (Tom Lane) - - - - pg_restore could emit incorrect commands when restoring - directly to a database server from an archive file that had been made - with standard_conforming_strings set to on. - - - - - - Fix write-past-buffer-end and memory leak in libpq's - LDAP service lookup code (Albe Laurenz) - - - - - - In libpq, avoid failures when using nonblocking I/O - and an SSL connection (Martin Pihlak, Tom Lane) - - - - - - Improve libpq's handling of failures during connection startup - (Tom Lane) - - - - In particular, the response to a server report of fork() - failure during SSL connection startup is now saner. - - - - - - Make ecpglib write double values with 15 digits - precision (Akira Kurosawa) - - - - - - Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) - (Tom Lane) - - - - contrib/pg_crypto's blowfish encryption code could give - wrong results on platforms where char is signed (which is most), - leading to encrypted passwords being weaker than they should be. - - - - - - Fix memory leak in contrib/seg (Heikki Linnakangas) - - - - - - Fix pgstatindex() to give consistent results for empty - indexes (Tom Lane) - - - - - - Allow building with perl 5.14 (Alex Hunsaker) - - - - - - Update configure script's method for probing existence of system - functions (Tom Lane) - - - - The version of autoconf we used in 8.3 and 8.2 could be fooled by - compilers that perform link-time optimization. - - - - - - Fix assorted issues with build and install file paths containing spaces - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2011i - for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan. - - - - - - - - - - Release 8.2.21 - - - Release date: - 2011-04-18 - - - - This release contains a variety of fixes from 8.2.20. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.21 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Avoid potential deadlock during catalog cache initialization - (Nikhil Sontakke) - - - - In some cases the cache loading code would acquire share lock on a - system index before locking the index's catalog. This could deadlock - against processes trying to acquire exclusive locks in the other, - more standard order. - - - - - - Fix dangling-pointer problem in BEFORE ROW UPDATE trigger - handling when there was a concurrent update to the target tuple - (Tom Lane) - - - - This bug has been observed to result in intermittent cannot - extract system attribute from virtual tuple failures while trying to - do UPDATE RETURNING ctid. There is a very small probability - of more serious errors, such as generating incorrect index entries for - the updated tuple. - - - - - - Disallow DROP TABLE when there are pending deferred trigger - events for the table (Tom Lane) - - - - Formerly the DROP would go through, leading to - could not open relation with OID nnn errors when the - triggers were eventually fired. - - - - - - Fix PL/Python memory leak involving array slices (Daniel Popowich) - - - - - - Fix pg_restore to cope with long lines (over 1KB) in - TOC files (Tom Lane) - - - - - - Put in more safeguards against crashing due to division-by-zero - with overly enthusiastic compiler optimization (Aurelien Jarno) - - - - - - Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane) - - - - There was a hard-wired assumption that this system function was not - available on MIPS hardware on these systems. Use a compile-time test - instead, since more recent versions have it. - - - - - - Fix compilation failures on HP-UX (Heikki Linnakangas) - - - - - - Fix path separator used by pg_regress on Cygwin - (Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2011f - for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa, - and Turkey; also historical corrections for South Australia, Alaska, - and Hawaii. - - - - - - - - - - Release 8.2.20 - - - Release date: - 2011-01-31 - - - - This release contains a variety of fixes from 8.2.19. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.20 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Avoid failures when EXPLAIN tries to display a simple-form - CASE expression (Tom Lane) - - - - If the CASE's test expression was a constant, the planner - could simplify the CASE into a form that confused the - expression-display code, resulting in unexpected CASE WHEN - clause errors. - - - - - - Fix assignment to an array slice that is before the existing range - of subscripts (Tom Lane) - - - - If there was a gap between the newly added subscripts and the first - pre-existing subscript, the code miscalculated how many entries needed - to be copied from the old array's null bitmap, potentially leading to - data corruption or crash. - - - - - - Avoid unexpected conversion overflow in planner for very distant date - values (Tom Lane) - - - - The date type supports a wider range of dates than can be - represented by the timestamp types, but the planner assumed it - could always convert a date to timestamp with impunity. - - - - - - Fix pg_restore's text output for large objects (BLOBs) - when standard_conforming_strings is on (Tom Lane) - - - - Although restoring directly to a database worked correctly, string - escaping was incorrect if pg_restore was asked for - SQL text output and standard_conforming_strings had been - enabled in the source database. - - - - - - Fix erroneous parsing of tsquery values containing - ... & !(subexpression) | ... (Tom Lane) - - - - Queries containing this combination of operators were not executed - correctly. The same error existed in contrib/intarray's - query_int type and contrib/ltree's - ltxtquery type. - - - - - - Fix buffer overrun in contrib/intarray's input function - for the query_int type (Apple) - - - - This bug is a security risk since the function's return address could - be overwritten. Thanks to Apple Inc's security team for reporting this - issue and supplying the fix. (CVE-2010-4015) - - - - - - Fix bug in contrib/seg's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a seg column. - If you have such an index, consider REINDEXing it after - installing this update. (This is identical to the bug that was fixed in - contrib/cube in the previous update.) - - - - - - - - - - Release 8.2.19 - - - Release date: - 2010-12-16 - - - - This release contains a variety of fixes from 8.2.18. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.19 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Force the default - wal_sync_method - to be fdatasync on Linux (Tom Lane, Marti Raudsepp) - - - - The default on Linux has actually been fdatasync for many - years, but recent kernel changes caused PostgreSQL to - choose open_datasync instead. This choice did not result - in any performance improvement, and caused outright failures on - certain filesystems, notably ext4 with the - data=journal mount option. - - - - - - Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane) - - - - This could result in bad buffer id: 0 failures or - corruption of index contents during replication. - - - - - - Fix recovery from base backup when the starting checkpoint WAL record - is not in the same WAL segment as its redo point (Jeff Davis) - - - - - - Add support for detecting register-stack overrun on IA64 - (Tom Lane) - - - - The IA64 architecture has two hardware stacks. Full - prevention of stack-overrun failures requires checking both. - - - - - - Add a check for stack overflow in copyObject() (Tom Lane) - - - - Certain code paths could crash due to stack overflow given a - sufficiently complex query. - - - - - - Fix detection of page splits in temporary GiST indexes (Heikki - Linnakangas) - - - - It is possible to have a concurrent page split in a - temporary index, if for example there is an open cursor scanning the - index when an insertion is done. GiST failed to detect this case and - hence could deliver wrong results when execution of the cursor - continued. - - - - - - Avoid memory leakage while ANALYZE'ing complex index - expressions (Tom Lane) - - - - - - Ensure an index that uses a whole-row Var still depends on its table - (Tom Lane) - - - - An index declared like create index i on t (foo(t.*)) - would not automatically get dropped when its table was dropped. - - - - - - Do not inline a SQL function with multiple OUT - parameters (Tom Lane) - - - - This avoids a possible crash due to loss of information about the - expected result rowtype. - - - - - - Behave correctly if ORDER BY, LIMIT, - FOR UPDATE, or WITH is attached to the - VALUES part of INSERT ... VALUES (Tom Lane) - - - - - - Fix constant-folding of COALESCE() expressions (Tom Lane) - - - - The planner would sometimes attempt to evaluate sub-expressions that - in fact could never be reached, possibly leading to unexpected errors. - - - - - - Add print functionality for InhRelation nodes (Tom Lane) - - - - This avoids a failure when debug_print_parse is enabled - and certain types of query are executed. - - - - - - Fix incorrect calculation of distance from a point to a horizontal - line segment (Tom Lane) - - - - This bug affected several different geometric distance-measurement - operators. - - - - - - Fix PL/pgSQL's handling of simple - expressions to not fail in recursion or error-recovery cases (Tom Lane) - - - - - - Fix PL/Python's handling of set-returning functions - (Jan Urbanski) - - - - Attempts to call SPI functions within the iterator generating a set - result would fail. - - - - - - Fix bug in contrib/cube's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a cube column. - If you have such an index, consider REINDEXing it after - installing this update. - - - - - - Don't emit identifier will be truncated notices in - contrib/dblink except when creating new connections - (Itagaki Takahiro) - - - - - - Fix potential coredump on missing public key in - contrib/pgcrypto (Marti Raudsepp) - - - - - - Fix memory leak in contrib/xml2's XPath query functions - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2010o - for DST law changes in Fiji and Samoa; - also historical corrections for Hong Kong. - - - - - - - - - - Release 8.2.18 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 8.2.17. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.18 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Fix Windows shared-memory allocation code - (Tsutomu Yamada, Magnus Hagander) - - - - This bug led to the often-reported could not reattach to shared - memory error message. This is a back-patch of a fix that was - applied to newer branches some time ago. - - - - - - Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on - Windows (Magnus Hagander) - - - - Under high load, Windows processes will sometimes fail at startup with - this error code. Formerly the postmaster treated this as a panic - condition and restarted the whole database, but that seems to be - an overreaction. - - - - - - Fix possible duplicate scans of UNION ALL member relations - (Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Reduce PANIC to ERROR in some occasionally-reported btree failure cases, - and provide additional detail in the resulting error messages - (Tom Lane) - - - - This should improve the system's robustness with corrupted indexes. - - - - - - Prevent show_session_authorization() from crashing within autovacuum - processes (Tom Lane) - - - - - - Defend against functions returning setof record where not all the - returned rows are actually of the same rowtype (Tom Lane) - - - - - - Fix possible failure when hashing a pass-by-reference function result - (Tao Ma, Tom Lane) - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Avoid recursion while assigning XIDs to heavily-nested - subtransactions (Andres Freund, Robert Haas) - - - - The original coding could result in a crash if there was limited - stack space. - - - - - - Fix log_line_prefix's %i escape, - which could produce junk early in backend startup (Tom Lane) - - - - - - Fix possible data corruption in ALTER TABLE ... SET - TABLESPACE when archiving is enabled (Jeff Davis) - - - - - - Allow CREATE DATABASE and ALTER DATABASE ... SET - TABLESPACE to be interrupted by query-cancel (Guillaume Lelarge) - - - - - - In PL/Python, defend against null pointer results from - PyCObject_AsVoidPtr and PyCObject_FromVoidPtr - (Peter Eisentraut) - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Fix contrib/dblink to handle connection names longer than - 62 bytes correctly (Itagaki Takahiro) - - - - - - Add hstore(text, text) - function to contrib/hstore (Robert Haas) - - - - This function is the recommended substitute for the now-deprecated - => operator. It was back-patched so that future-proofed - code can be used with older server versions. Note that the patch will - be effective only after contrib/hstore is installed or - reinstalled in a particular database. Users might prefer to execute - the CREATE FUNCTION command by hand, instead. - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - Update time zone data files to tzdata release 2010l - for DST law changes in Egypt and Palestine; also historical corrections - for Finland. - - - - This change also adds new names for two Micronesian timezones: - Pacific/Chuuk is now preferred over Pacific/Truk (and the preferred - abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over - Pacific/Ponape. - - - - - - Make Windows' N. Central Asia Standard Time timezone map to - Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander) - - - - Microsoft changed the DST behavior of this zone in the timezone update - from KB976098. Asia/Novosibirsk is a better match to its new behavior. - - - - - - - - - - Release 8.2.17 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 8.2.16. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.17 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Fix possible crash if a cache reset message is received during - rebuild of a relcache entry (Heikki) - - - - This error was introduced in 8.2.16 while fixing a related failure. - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Prevent infinite recursion in psql when expanding - a variable that refers to itself (Tom) - - - - - - Fix psql's \copy to not add spaces around - a dot within \copy (select ...) (Tom) - - - - Addition of spaces around the decimal point in a numeric literal would - result in a syntax error. - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - Avoid possible crashes in syslogger process on Windows (Heikki) - - - - - - Deal more robustly with incomplete time zone information in the - Windows registry (Magnus) - - - - - - Update the set of known Windows time zone names (Magnus) - - - - - - Update time zone data files to tzdata release 2010j - for DST law changes in Argentina, Australian Antarctic, Bangladesh, - Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; - also historical corrections for Taiwan. - - - - Also, add PKST (Pakistan Summer Time) to the default set of - timezone abbreviations. - - - - - - - - - - Release 8.2.16 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 8.2.15. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.16 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Fix possible deadlock during backend startup (Tom) - - - - - - Fix possible crashes due to not handling errors during relcache reload - cleanly (Tom) - - - - - - Fix possible crashes when trying to recover from a failure in - subtransaction start (Tom) - - - - - - Fix server memory leak associated with use of savepoints and a client - encoding different from server's encoding (Tom) - - - - - - Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST - index page split (Yoichi Hirai) - - - - This would result in index corruption, or even more likely an error - during WAL replay, if we were unlucky enough to crash during - end-of-recovery cleanup after having completed an incomplete GIST - insertion. - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix integer-to-bit-string conversions to handle the first fractional - byte correctly when the output bit width is wider than the given - integer by something other than a multiple of 8 bits (Tom) - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - Fix the STOP WAL LOCATION entry in backup history files to - report the next WAL segment's name when the end location is exactly at a - segment boundary (Itagaki Takahiro) - - - - - - Fix some more cases of temporary-file leakage (Heikki) - - - - This corrects a problem introduced in the previous minor release. - One case that failed is when a plpgsql function returning set is - called within another function's exception handler. - - - - - - Improve constraint exclusion processing of boolean-variable cases, - in particular make it possible to exclude a partition that has a - bool_column = false constraint (Tom) - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Fix possible infinite loop if SSL_read or - SSL_write fails without setting errno (Tom) - - - - This is reportedly possible with some Windows versions of - openssl. - - - - - - Fix psql's numericlocale option to not - format strings it shouldn't in latex and troff output formats (Heikki) - - - - - - Make psql return the correct exit status (3) when - ON_ERROR_STOP and --single-transaction are - both specified and an error occurs during the implied COMMIT - (Bruce) - - - - - - Fix plpgsql failure in one case where a composite column is set to NULL - (Tom) - - - - - - Fix possible failure when calling PL/Perl functions from PL/PerlU - or vice versa (Tim Bunce) - - - - - - Add volatile markings in PL/Python to avoid possible - compiler-specific misbehavior (Zdenek Kotala) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - Fix assorted crashes in contrib/xml2 caused by sloppy - memory management (Tom) - - - - - - Make building of contrib/xml2 more robust on Windows - (Andrew) - - - - - - Fix race condition in Windows signal handling (Radu Ilie) - - - - One known symptom of this bug is that rows in pg_listener - could be dropped under heavy load. - - - - - - Update time zone data files to tzdata release 2010e - for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa. - - - - - - - - - - Release 8.2.15 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 8.2.14. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.15 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.14, - see . - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Ensure that shared tuple-level locks held by prepared transactions are - not ignored (Heikki) - - - - - - Fix premature drop of temporary files used for a cursor that is accessed - within a subtransaction (Heikki) - - - - - - Fix incorrect logic for GiST index page splits, when the split depends - on a non-first column of the index (Paul Ramsey) - - - - - - Don't error out if recycling or removing an old WAL file fails at the - end of checkpoint (Heikki) - - - - It's better to treat the problem as non-fatal and allow the checkpoint - to complete. Future checkpoints will retry the removal. Such problems - are not expected in normal operation, but have been seen to be - caused by misdesigned Windows anti-virus and backup software. - - - - - - Ensure WAL files aren't repeatedly archived on Windows (Heikki) - - - - This is another symptom that could happen if some other process - interfered with deletion of a no-longer-needed file. - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Fix processing of ownership dependencies during CREATE OR - REPLACE FUNCTION (Tom) - - - - - - Fix bug with calling plperl from plperlu or vice - versa (Tom) - - - - An error exit from the inner function could result in crashes due to - failure to re-select the correct Perl interpreter for the outer function. - - - - - - Fix session-lifespan memory leak when a PL/Perl function is redefined - (Tom) - - - - - - Ensure that Perl arrays are properly converted to - PostgreSQL arrays when returned by a set-returning - PL/Perl function (Andrew Dunstan, Abhijit Menon-Sen) - - - - This worked correctly already for non-set-returning functions. - - - - - - Fix rare crash in exception processing in PL/Python (Peter) - - - - - - Ensure psql's flex module is compiled with the correct - system header definitions (Tom) - - - - This fixes build failures on platforms where - --enable-largefile causes incompatible changes in the - generated code. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - Update the timezone abbreviation files to match current reality (Joachim - Wieland) - - - - This includes adding IDT and SGT to the default - timezone abbreviation set. - - - - - - Update time zone data files to tzdata release 2009s - for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, - Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical - corrections for Hong Kong. - - - - - - - - - - Release 8.2.14 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 8.2.13. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.14 - - - A dump/restore is not required for those running 8.2.X. - However, if you have any hash indexes on interval columns, - you must REINDEX them after updating to 8.2.14. - Also, if you are upgrading from a version earlier than 8.2.11, - see . - - - - - - Changes - - - - - - Force WAL segment switch during pg_start_backup() - (Heikki) - - - - This avoids corner cases that could render a base backup unusable. - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Make LOAD of an already-loaded loadable module - into a no-op (Tom) - - - - Formerly, LOAD would attempt to unload and re-load the - module, but this is unsafe and not all that useful. - - - - - - Disallow empty passwords during LDAP authentication (Magnus) - - - - - - Fix handling of sub-SELECTs appearing in the arguments of - an outer-level aggregate function (Tom) - - - - - - Fix bugs associated with fetching a whole-row value from the - output of a Sort or Materialize plan node (Tom) - - - - - - Revert planner change that disabled partial-index and constraint - exclusion optimizations when there were more than 100 clauses in - an AND or OR list (Tom) - - - - - - Fix hash calculation for data type interval (Tom) - - - - This corrects wrong results for hash joins on interval values. - It also changes the contents of hash indexes on interval columns. - If you have any such indexes, you must REINDEX them - after updating. - - - - - - Treat to_char(..., 'TH') as an uppercase ordinal - suffix with 'HH'/'HH12' (Heikki) - - - - It was previously handled as 'th' (lowercase). - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Fix calculation of distance between a point and a line segment (Tom) - - - - This led to incorrect results from a number of geometric operators. - - - - - - Fix money data type to work in locales where currency - amounts have no fractional digits, e.g. Japan (Itagaki Takahiro) - - - - - - Properly round datetime input like - 00:12:57.9999999999999999999999999999 (Tom) - - - - - - Fix poor choice of page split point in GiST R-tree operator classes - (Teodor) - - - - - - Avoid performance degradation in bulk inserts into GIN indexes - when the input values are (nearly) in sorted order (Tom) - - - - - - Correctly enforce NOT NULL domain constraints in some contexts in - PL/pgSQL (Tom) - - - - - - Fix portability issues in plperl initialization (Andrew Dunstan) - - - - - - Fix pg_ctl to not go into an infinite loop if - postgresql.conf is empty (Jeff Davis) - - - - - - Make contrib/hstore throw an error when a key or - value is too long to fit in its data structure, rather than - silently truncating it (Andrew Gierth) - - - - - - Fix contrib/xml2's xslt_process() to - properly handle the maximum number of parameters (twenty) (Tom) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - Update time zone data files to tzdata release 2009l - for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, - Argentina/San_Luis, Cuba, Jordan (historical correction only), - Mauritius, Morocco, Palestine, Syria, Tunisia. - - - - - - - - - - Release 8.2.13 - - - Release date: - 2009-03-16 - - - - This release contains a variety of fixes from 8.2.12. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.13 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.11, - see . - - - - - - Changes - - - - - - Prevent error recursion crashes when encoding conversion fails (Tom) - - - - This change extends fixes made in the last two minor releases for - related failure scenarios. The previous fixes were narrowly tailored - for the original problem reports, but we have now recognized that - any error thrown by an encoding conversion function could - potentially lead to infinite recursion while trying to report the - error. The solution therefore is to disable translation and encoding - conversion and report the plain-ASCII form of any error message, - if we find we have gotten into a recursive error reporting situation. - (CVE-2009-0922) - - - - - - Disallow CREATE CONVERSION with the wrong encodings - for the specified conversion function (Heikki) - - - - This prevents one possible scenario for encoding conversion failure. - The previous change is a backstop to guard against other kinds of - failures in the same area. - - - - - - Fix core dump when to_char() is given format codes that - are inappropriate for the type of the data argument (Tom) - - - - - - Fix possible failure in contrib/tsearch2 when C locale is - used with a multi-byte encoding (Teodor) - - - - Crashes were possible on platforms where wchar_t is narrower - than int; Windows in particular. - - - - - - Fix extreme inefficiency in contrib/tsearch2 parser's - handling of an email-like string containing multiple @ - characters (Heikki) - - - - - - Fix decompilation of CASE WHEN with an implicit coercion - (Tom) - - - - This mistake could lead to Assert failures in an Assert-enabled build, - or an unexpected CASE WHEN clause error message in other - cases, when trying to examine or dump a view. - - - - - - Fix possible misassignment of the owner of a TOAST table's rowtype (Tom) - - - - If CLUSTER or a rewriting variant of ALTER TABLE - were executed by someone other than the table owner, the - pg_type entry for the table's TOAST table would end up - marked as owned by that someone. This caused no immediate problems, - since the permissions on the TOAST rowtype aren't examined by any - ordinary database operation. However, it could lead to unexpected - failures if one later tried to drop the role that issued the command - (in 8.1 or 8.2), or owner of data type appears to be invalid - warnings from pg_dump after having done so (in 8.3). - - - - - - Fix PL/pgSQL to not treat INTO after INSERT as - an INTO-variables clause anywhere in the string, not only at the start; - in particular, don't fail for INSERT INTO within - CREATE RULE (Tom) - - - - - - Clean up PL/pgSQL error status variables fully at block exit - (Ashesh Vashi and Dave Page) - - - - This is not a problem for PL/pgSQL itself, but the omission could cause - the PL/pgSQL Debugger to crash while examining the state of a function. - - - - - - Retry failed calls to CallNamedPipe() on Windows - (Steve Marshall, Magnus) - - - - It appears that this function can sometimes fail transiently; - we previously treated any failure as a hard error, which could - confuse LISTEN/NOTIFY as well as other - operations. - - - - - - Add MUST (Mauritius Island Summer Time) to the default list - of known timezone abbreviations (Xavier Bugaud) - - - - - - - - - - Release 8.2.12 - - - Release date: - 2009-02-02 - - - - This release contains a variety of fixes from 8.2.11. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.12 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.11, - see . - - - - - - Changes - - - - - - Improve handling of URLs in headline() function (Teodor) - - - - - - Improve handling of overlength headlines in headline() - function (Teodor) - - - - - - Prevent possible Assert failure or misconversion if an encoding - conversion is created with the wrong conversion function for the - specified pair of encodings (Tom, Heikki) - - - - - - Fix possible Assert failure if a statement executed in PL/pgSQL is - rewritten into another kind of statement, for example if an - INSERT is rewritten into an UPDATE (Heikki) - - - - - - Ensure that a snapshot is available to datatype input functions (Tom) - - - - This primarily affects domains that are declared with CHECK - constraints involving user-defined stable or immutable functions. Such - functions typically fail if no snapshot has been set. - - - - - - Make it safer for SPI-using functions to be used within datatype I/O; - in particular, to be used in domain check constraints (Tom) - - - - - - Avoid unnecessary locking of small tables in VACUUM - (Heikki) - - - - - - Fix a problem that made UPDATE RETURNING tableoid - return zero instead of the correct OID (Tom) - - - - - - Fix planner misestimation of selectivity when transitive equality - is applied to an outer-join clause (Tom) - - - - This could result in bad plans for queries like - ... from a left join b on a.a1 = b.b1 where a.a1 = 42 ... - - - - - - Improve optimizer's handling of long IN lists (Tom) - - - - This change avoids wasting large amounts of time on such lists - when constraint exclusion is enabled. - - - - - - Ensure that the contents of a holdable cursor don't depend on the - contents of TOAST tables (Tom) - - - - Previously, large field values in a cursor result might be represented - as TOAST pointers, which would fail if the referenced table got dropped - before the cursor is read, or if the large value is deleted and then - vacuumed away. This cannot happen with an ordinary cursor, - but it could with a cursor that is held past its creating transaction. - - - - - - Fix memory leak when a set-returning function is terminated without - reading its whole result (Tom) - - - - - - Fix contrib/dblink's - dblink_get_result(text,bool) function (Joe) - - - - - - Fix possible garbage output from contrib/sslinfo functions - (Tom) - - - - - - Fix configure script to properly report failure when - unable to obtain linkage information for PL/Perl (Andrew) - - - - - - Make all documentation reference pgsql-bugs and/or - pgsql-hackers as appropriate, instead of the - now-decommissioned pgsql-ports and pgsql-patches - mailing lists (Tom) - - - - - - Update time zone data files to tzdata release 2009a (for - Kathmandu and historical DST corrections in Switzerland, Cuba) - - - - - - - - - - Release 8.2.11 - - - Release date: - 2008-11-03 - - - - This release contains a variety of fixes from 8.2.10. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.11 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.7, - see . Also, if you were running a previous - 8.2.X release, it is recommended to REINDEX all GiST - indexes after the upgrade. - - - - - - Changes - - - - - - Fix GiST index corruption due to marking the wrong index entry - dead after a deletion (Teodor) - - - - This would result in index searches failing to find rows they - should have found. Corrupted indexes can be fixed with - REINDEX. - - - - - - Fix backend crash when the client encoding cannot represent a localized - error message (Tom) - - - - We have addressed similar issues before, but it would still fail if - the character has no equivalent message itself couldn't - be converted. The fix is to disable localization and send the plain - ASCII error message when we detect such a situation. - - - - - - Fix possible crash when deeply nested functions are invoked from - a trigger (Tom) - - - - - - Improve optimization of expression IN - (expression-list) queries (Tom, per an idea from Robert - Haas) - - - - Cases in which there are query variables on the right-hand side had been - handled less efficiently in 8.2.x and 8.3.x than in prior versions. - The fix restores 8.1 behavior for such cases. - - - - - - Fix mis-expansion of rule queries when a sub-SELECT appears - in a function call in FROM, a multi-row VALUES - list, or a RETURNING list (Tom) - - - - The usual symptom of this problem is an unrecognized node type - error. - - - - - - Fix memory leak during rescan of a hashed aggregation plan (Neil) - - - - - - Ensure an error is reported when a newly-defined PL/pgSQL trigger - function is invoked as a normal function (Tom) - - - - - - Prevent possible collision of relfilenode numbers - when moving a table to another tablespace with ALTER SET - TABLESPACE (Heikki) - - - - The command tried to re-use the existing filename, instead of - picking one that is known unused in the destination directory. - - - - - - Fix incorrect tsearch2 headline generation when single query - item matches first word of text (Sushant Sinha) - - - - - - Fix improper display of fractional seconds in interval values when - using a non-ISO datestyle in an - build (Ron Mayer) - - - - - - Ensure SPI_getvalue and SPI_getbinval - behave correctly when the passed tuple and tuple descriptor have - different numbers of columns (Tom) - - - - This situation is normal when a table has had columns added or removed, - but these two functions didn't handle it properly. - The only likely consequence is an incorrect error indication. - - - - - - Fix ecpg's parsing of CREATE ROLE (Michael) - - - - - - Fix recent breakage of pg_ctl restart (Tom) - - - - - - Ensure pg_control is opened in binary mode - (Itagaki Takahiro) - - - - pg_controldata and pg_resetxlog - did this incorrectly, and so could fail on Windows. - - - - - - Update time zone data files to tzdata release 2008i (for - DST law changes in Argentina, Brazil, Mauritius, Syria) - - - - - - - - - - Release 8.2.10 - - - Release date: - 2008-09-22 - - - - This release contains a variety of fixes from 8.2.9. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.10 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.7, - see . - - - - - - Changes - - - - - - Fix bug in btree WAL recovery code (Heikki) - - - - Recovery failed if the WAL ended partway through a page split operation. - - - - - - Fix potential miscalculation of datfrozenxid (Alvaro) - - - - This error may explain some recent reports of failure to remove old - pg_clog data. - - - - - - Widen local lock counters from 32 to 64 bits (Tom) - - - - This responds to reports that the counters could overflow in - sufficiently long transactions, leading to unexpected lock is - already held errors. - - - - - - Fix possible duplicate output of tuples during a GiST index scan (Teodor) - - - - - - Fix missed permissions checks when a view contains a simple - UNION ALL construct (Heikki) - - - - Permissions for the referenced tables were checked properly, but not - permissions for the view itself. - - - - - - Add checks in executor startup to ensure that the tuples produced by an - INSERT or UPDATE will match the target table's - current rowtype (Tom) - - - - ALTER COLUMN TYPE, followed by re-use of a previously - cached plan, could produce this type of situation. The check protects - against data corruption and/or crashes that could ensue. - - - - - - Fix possible repeated drops during DROP OWNED (Tom) - - - - This would typically result in strange errors such as cache - lookup failed for relation NNN. - - - - - - Fix AT TIME ZONE to first try to interpret its timezone - argument as a timezone abbreviation, and only try it as a full timezone - name if that fails, rather than the other way around as formerly (Tom) - - - - The timestamp input functions have always resolved ambiguous zone names - in this order. Making AT TIME ZONE do so as well improves - consistency, and fixes a compatibility bug introduced in 8.1: - in ambiguous cases we now behave the same as 8.0 and before did, - since in the older versions AT TIME ZONE accepted - only abbreviations. - - - - - - Fix datetime input functions to correctly detect integer overflow when - running on a 64-bit platform (Tom) - - - - - - Prevent integer overflows during units conversion when displaying a - configuration parameter that has units (Tom) - - - - - - Improve performance of writing very long log messages to syslog (Tom) - - - - - - Allow spaces in the suffix part of an LDAP URL in - pg_hba.conf (Tom) - - - - - - Fix bug in backwards scanning of a cursor on a SELECT DISTINCT - ON query (Tom) - - - - - - Fix planner bug with nested sub-select expressions (Tom) - - - - If the outer sub-select has no direct dependency on the parent query, - but the inner one does, the outer value might not get recalculated - for new parent query rows. - - - - - - Fix planner to estimate that GROUP BY expressions yielding - boolean results always result in two groups, regardless of the - expressions' contents (Tom) - - - - This is very substantially more accurate than the regular GROUP - BY estimate for certain boolean tests like col - IS NULL. - - - - - - Fix PL/pgSQL to not fail when a FOR loop's target variable - is a record containing composite-type fields (Tom) - - - - - - Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful - about the encoding of data sent to or from Tcl (Tom) - - - - - - On Windows, work around a Microsoft bug by preventing - libpq from trying to send more than 64kB per system call - (Magnus) - - - - - - Improve pg_dump and pg_restore's - error reporting after failure to send a SQL command (Tom) - - - - - - Fix pg_ctl to properly preserve postmaster - command-line arguments across a restart (Bruce) - - - - - - Update time zone data files to tzdata release 2008f (for - DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco, - Pakistan, Palestine, and Paraguay) - - - - - - - - - - Release 8.2.9 - - - Release date: - 2008-06-12 - - - - This release contains one serious and one minor bug fix over 8.2.8. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.9 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.7, - see . - - - - - - Changes - - - - - - Make pg_get_ruledef() parenthesize negative constants (Tom) - - - - Before this fix, a negative constant in a view or rule might be dumped - as, say, -42::integer, which is subtly incorrect: it should - be (-42)::integer due to operator precedence rules. - Usually this would make little difference, but it could interact with - another recent patch to cause - PostgreSQL to reject what had been a valid - SELECT DISTINCT view query. Since this could result in - pg_dump output failing to reload, it is being treated - as a high-priority fix. The only released versions in which dump - output is actually incorrect are 8.3.1 and 8.2.7. - - - - - - Make ALTER AGGREGATE ... OWNER TO update - pg_shdepend (Tom) - - - - This oversight could lead to problems if the aggregate was later - involved in a DROP OWNED or REASSIGN OWNED - operation. - - - - - - - - - - Release 8.2.8 - - - Release date: - never released - - - - This release contains a variety of fixes from 8.2.7. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.8 - - - A dump/restore is not required for those running 8.2.X. - However, if you are upgrading from a version earlier than 8.2.7, - see . - - - - - - Changes - - - - - - Fix ERRORDATA_STACK_SIZE exceeded crash that - occurred on Windows when using UTF-8 database encoding and a different - client encoding (Tom) - - - - - - Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new - column is correctly checked to see if it's been initialized to all - non-nulls (Brendan Jurd) - - - - Previous versions neglected to check this requirement at all. - - - - - - Fix possible CREATE TABLE failure when inheriting the - same constraint from multiple parent relations that - inherited that constraint from a common ancestor (Tom) - - - - - - Fix pg_get_ruledef() to show the alias, if any, attached - to the target table of an UPDATE or DELETE - (Tom) - - - - - - Fix GIN bug that could result in a too many LWLocks - taken failure (Teodor) - - - - - - Avoid possible crash when decompressing corrupted data - (Zdenek Kotala) - - - - - - Repair two places where SIGTERM exit of a backend could leave corrupted - state in shared memory (Tom) - - - - Neither case is very important if SIGTERM is used to shut down the - whole database cluster together, but there was a problem if someone - tried to SIGTERM individual backends. - - - - - - Fix conversions between ISO-8859-5 and other encodings to handle - Cyrillic Yo characters (e and E with - two dots) (Sergey Burladyan) - - - - - - Fix several datatype input functions, notably array_in(), - that were allowing unused bytes in their results to contain - uninitialized, unpredictable values (Tom) - - - - This could lead to failures in which two apparently identical literal - values were not seen as equal, resulting in the parser complaining - about unmatched ORDER BY and DISTINCT - expressions. - - - - - - Fix a corner case in regular-expression substring matching - (substring(string from - pattern)) (Tom) - - - - The problem occurs when there is a match to the pattern overall but - the user has specified a parenthesized subexpression and that - subexpression hasn't got a match. An example is - substring('foo' from 'foo(bar)?'). - This should return NULL, since (bar) isn't matched, but - it was mistakenly returning the whole-pattern match instead (ie, - foo). - - - - - - Update time zone data files to tzdata release 2008c (for - DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba, and - Argentina/San_Luis) - - - - - - Fix incorrect result from ecpg's - PGTYPEStimestamp_sub() function (Michael) - - - - - - Fix broken GiST comparison function for contrib/tsearch2's - tsquery type (Teodor) - - - - - - Fix possible crashes in contrib/cube functions (Tom) - - - - - - Fix core dump in contrib/xml2's - xpath_table() function when the input query returns a - NULL value (Tom) - - - - - - Fix contrib/xml2's makefile to not override - CFLAGS (Tom) - - - - - - Fix DatumGetBool macro to not fail with gcc - 4.3 (Tom) - - - - This problem affects old style (V0) C functions that - return boolean. The fix is already in 8.3, but the need to - back-patch it was not realized at the time. - - - - - - - - - - Release 8.2.7 - - - Release date: - 2008-03-17 - - - - This release contains a variety of fixes from 8.2.6. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.7 - - - A dump/restore is not required for those running 8.2.X. - However, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the Windows locale - issue described below. - - - - - - Changes - - - - - - Fix character string comparison for Windows locales that consider - different character combinations as equal (Tom) - - - - This fix applies only on Windows and only when using UTF-8 - database encoding. The same fix was made for all other cases - over two years ago, but Windows with UTF-8 uses a separate code - path that was not updated. If you are using a locale that - considers some non-identical strings as equal, you may need to - REINDEX to fix existing indexes on textual columns. - - - - - - Repair potential deadlock between concurrent VACUUM FULL - operations on different system catalogs (Tom) - - - - - - Fix longstanding LISTEN/NOTIFY - race condition (Tom) - - - - In rare cases a session that had just executed a - LISTEN might not get a notification, even though - one would be expected because the concurrent transaction executing - NOTIFY was observed to commit later. - - - - A side effect of the fix is that a transaction that has executed - a not-yet-committed LISTEN command will not see any - row in pg_listener for the LISTEN, - should it choose to look; formerly it would have. This behavior - was never documented one way or the other, but it is possible that - some applications depend on the old behavior. - - - - - - Disallow LISTEN and UNLISTEN within a - prepared transaction (Tom) - - - - This was formerly allowed but trying to do it had various unpleasant - consequences, notably that the originating backend could not exit - as long as an UNLISTEN remained uncommitted. - - - - - - Disallow dropping a temporary table within a - prepared transaction (Heikki) - - - - This was correctly disallowed by 8.1, but the check was inadvertently - broken in 8.2. - - - - - - Fix rare crash when an error occurs during a query using a hash index - (Heikki) - - - - - - Fix memory leaks in certain usages of set-returning functions (Neil) - - - - - - Fix input of datetime values for February 29 in years BC (Tom) - - - - The former coding was mistaken about which years were leap years. - - - - - - Fix unrecognized node type error in some variants of - ALTER OWNER (Tom) - - - - - - Ensure pg_stat_activity.waiting flag - is cleared when a lock wait is aborted (Tom) - - - - - - Fix handling of process permissions on Windows Vista (Dave, Magnus) - - - - In particular, this fix allows starting the server as the Administrator - user. - - - - - - Update time zone data files to tzdata release 2008a - (in particular, recent Chile changes); adjust timezone abbreviation - VET (Venezuela) to mean UTC-4:30, not UTC-4:00 (Tom) - - - - - - Fix pg_ctl to correctly extract the postmaster's port - number from command-line options (Itagaki Takahiro, Tom) - - - - Previously, pg_ctl start -w could try to contact the - postmaster on the wrong port, leading to bogus reports of startup - failure. - - - - - - Use to defend against possible misoptimization - in recent gcc versions (Tom) - - - - This is known to be necessary when building PostgreSQL - with gcc 4.3 or later. - - - - - - - Correctly enforce statement_timeout values longer - than INT_MAX microseconds (about 35 minutes) (Tom) - - - - This bug affects only builds with . - - - - - - Fix unexpected PARAM_SUBLINK ID planner error when - constant-folding simplifies a sub-select (Tom) - - - - - - Fix logical errors in constraint-exclusion handling of IS - NULL and NOT expressions (Tom) - - - - The planner would sometimes exclude partitions that should not - have been excluded because of the possibility of NULL results. - - - - - - Fix another cause of failed to build any N-way joins - planner errors (Tom) - - - - This could happen in cases where a clauseless join needed to be - forced before a join clause could be exploited. - - - - - - Fix incorrect constant propagation in outer-join planning (Tom) - - - - The planner could sometimes incorrectly conclude that a variable - could be constrained to be equal to a constant, leading - to wrong query results. - - - - - - Fix display of constant expressions in ORDER BY - and GROUP BY (Tom) - - - - An explicitly casted constant would be shown incorrectly. This could - for example lead to corruption of a view definition during - dump and reload. - - - - - - Fix libpq to handle NOTICE messages correctly - during COPY OUT (Tom) - - - - This failure has only been observed to occur when a user-defined - datatype's output routine issues a NOTICE, but there is no - guarantee it couldn't happen due to other causes. - - - - - - - - - - Release 8.2.6 - - - Release date: - 2008-01-07 - - - - This release contains a variety of fixes from 8.2.5, - including fixes for significant security issues. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.6 - - - A dump/restore is not required for those running 8.2.X. - - - - - - Changes - - - - - - Prevent functions in indexes from executing with the privileges of - the user running VACUUM, ANALYZE, etc (Tom) - - - - Functions used in index expressions and partial-index - predicates are evaluated whenever a new table entry is made. It has - long been understood that this poses a risk of trojan-horse code - execution if one modifies a table owned by an untrustworthy user. - (Note that triggers, defaults, check constraints, etc. pose the - same type of risk.) But functions in indexes pose extra danger - because they will be executed by routine maintenance operations - such as VACUUM FULL, which are commonly performed - automatically under a superuser account. For example, a nefarious user - can execute code with superuser privileges by setting up a - trojan-horse index definition and waiting for the next routine vacuum. - The fix arranges for standard maintenance operations - (including VACUUM, ANALYZE, REINDEX, - and CLUSTER) to execute as the table owner rather than - the calling user, using the same privilege-switching mechanism already - used for SECURITY DEFINER functions. To prevent bypassing - this security measure, execution of SET SESSION - AUTHORIZATION and SET ROLE is now forbidden within a - SECURITY DEFINER context. (CVE-2007-6600) - - - - - - Repair assorted bugs in the regular-expression package (Tom, Will Drewry) - - - - Suitably crafted regular-expression patterns could cause crashes, - infinite or near-infinite looping, and/or massive memory consumption, - all of which pose denial-of-service hazards for applications that - accept regex search patterns from untrustworthy sources. - (CVE-2007-4769, CVE-2007-4772, CVE-2007-6067) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - The fix that appeared for this in 8.2.5 was incomplete, as it plugged - the hole for only some dblink functions. (CVE-2007-6601, - CVE-2007-3278) - - - - - - Fix bugs in WAL replay for GIN indexes (Teodor) - - - - - - Fix GIN index build to work properly when - maintenance_work_mem is 4GB or more (Tom) - - - - - - Update time zone data files to tzdata release 2007k - (in particular, recent Argentina changes) (Tom) - - - - - - Improve planner's handling of LIKE/regex estimation in non-C locales - (Tom) - - - - - - Fix planning-speed problem for deep outer-join nests, as well as - possible poor choice of join order (Tom) - - - - - - Fix planner failure in some cases of WHERE false AND var IN - (SELECT ...) (Tom) - - - - - - Make CREATE TABLE ... SERIAL and - ALTER SEQUENCE ... OWNED BY not change the - currval() state of the sequence (Tom) - - - - - - Preserve the tablespace and storage parameters of indexes that are - rebuilt by ALTER TABLE ... ALTER COLUMN TYPE (Tom) - - - - - - Make archive recovery always start a new WAL timeline, rather than only - when a recovery stop time was used (Simon) - - - - This avoids a corner-case risk of trying to overwrite an existing - archived copy of the last WAL segment, and seems simpler and cleaner - than the original definition. - - - - - - Make VACUUM not use all of maintenance_work_mem - when the table is too small for it to be useful (Alvaro) - - - - - - Fix potential crash in translate() when using a multibyte - database encoding (Tom) - - - - - - Make corr() return the correct result for negative - correlation values (Neil) - - - - - - Fix overflow in extract(epoch from interval) for intervals - exceeding 68 years (Tom) - - - - - - Fix PL/Perl to not fail when a UTF-8 regular expression is used - in a trusted function (Andrew) - - - - - - Fix PL/Perl to cope when platform's Perl defines type bool - as int rather than char (Tom) - - - - While this could theoretically happen anywhere, no standard build of - Perl did things this way ... until macOS 10.5. - - - - - - Fix PL/Python to work correctly with Python 2.5 on 64-bit machines - (Marko Kreen) - - - - - - Fix PL/Python to not crash on long exception messages (Alvaro) - - - - - - Fix pg_dump to correctly handle inheritance child tables - that have default expressions different from their parent's (Tom) - - - - - - Fix libpq crash when PGPASSFILE refers - to a file that is not a plain file (Martin Pitt) - - - - - - ecpg parser fixes (Michael) - - - - - - Make contrib/pgcrypto defend against - OpenSSL libraries that fail on keys longer than 128 - bits; which is the case at least on some Solaris versions (Marko Kreen) - - - - - - Make contrib/tablefunc's crosstab() handle - NULL rowid as a category in its own right, rather than crashing (Joe) - - - - - - Fix tsvector and tsquery output routines to - escape backslashes correctly (Teodor, Bruce) - - - - - - Fix crash of to_tsvector() on huge input strings (Teodor) - - - - - - Require a specific version of Autoconf to be used - when re-generating the configure script (Peter) - - - - This affects developers and packagers only. The change was made - to prevent accidental use of untested combinations of - Autoconf and PostgreSQL versions. - You can remove the version check if you really want to use a - different Autoconf version, but it's - your responsibility whether the result works or not. - - - - - - Update gettimeofday configuration check so that - PostgreSQL can be built on newer versions of - MinGW (Magnus) - - - - - - - - - - Release 8.2.5 - - - Release date: - 2007-09-17 - - - - This release contains a variety of fixes from 8.2.4. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.5 - - - A dump/restore is not required for those running 8.2.X. - - - - - - Changes - - - - - - Prevent index corruption when a transaction inserts rows and - then aborts close to the end of a concurrent VACUUM - on the same table (Tom) - - - - - - Fix ALTER DOMAIN ADD CONSTRAINT for cases involving - domains over domains (Tom) - - - - - - Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom) - - - - - - Fix some planner problems with outer joins, notably poor - size estimation for t1 LEFT JOIN t2 WHERE t2.col IS NULL - (Tom) - - - - - - Allow the interval data type to accept input consisting only of - milliseconds or microseconds (Neil) - - - - - - Allow timezone name to appear before the year in timestamp input (Tom) - - - - - - Fixes for GIN indexes used by /contrib/tsearch2 (Teodor) - - - - - - Speed up rtree index insertion (Teodor) - - - - - - Fix excessive logging of SSL error messages (Tom) - - - - - - Fix logging so that log messages are never interleaved when using - the syslogger process (Andrew) - - - - - - Fix crash when log_min_error_statement logging runs out - of memory (Tom) - - - - - - Fix incorrect handling of some foreign-key corner cases (Tom) - - - - - - Fix stddev_pop(numeric) and var_pop(numeric) (Tom) - - - - - - Prevent REINDEX and CLUSTER from failing - due to attempting to process temporary tables of other sessions (Alvaro) - - - - - - Update the time zone database rules, particularly New Zealand's upcoming changes (Tom) - - - - - - Windows socket and semaphore improvements (Magnus) - - - - - - Make pg_ctl -w work properly in Windows service mode (Dave Page) - - - - - - Fix memory allocation bug when using MIT Kerberos on Windows (Magnus) - - - - - - Suppress timezone name (%Z) in log timestamps on Windows - because of possible encoding mismatches (Tom) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - - - Restrict /contrib/pgstattuple functions to superusers, for security reasons (Tom) - - - - - - Do not let /contrib/intarray try to make its GIN opclass - the default (this caused problems at dump/restore) (Tom) - - - - - - - - - - Release 8.2.4 - - - Release date: - 2007-04-23 - - - - This release contains a variety of fixes from 8.2.3, - including a security fix. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.4 - - - A dump/restore is not required for those running 8.2.X. - - - - - - Changes - - - - - - Support explicit placement of the temporary-table schema within - search_path, and disable searching it for functions - and operators (Tom) - - - - This is needed to allow a security-definer function to set a - truly secure value of search_path. Without it, - an unprivileged SQL user can use temporary objects to execute code - with the privileges of the security-definer function (CVE-2007-2138). - See CREATE FUNCTION for more information. - - - - - - Fix shared_preload_libraries for Windows - by forcing reload in each backend (Korry Douglas) - - - - - - Fix to_char() so it properly upper/lower cases localized day or month - names (Pavel Stehule) - - - - - - /contrib/tsearch2 crash fixes (Teodor) - - - - - - Require COMMIT PREPARED to be executed in the same - database as the transaction was prepared in (Heikki) - - - - - - Allow pg_dump to do binary backups larger than two gigabytes - on Windows (Magnus) - - - - - - New traditional (Taiwan) Chinese FAQ (Zhou Daojing) - - - - - - Prevent the statistics collector from writing to disk too frequently (Tom) - - - - - - Fix potential-data-corruption bug in how VACUUM FULL handles - UPDATE chains (Tom, Pavan Deolasee) - - - - - - Fix bug in domains that use array types (Tom) - - - - - - Fix pg_dump so it can dump a serial column's sequence - using when not also dumping the owning table - (Tom) - - - - - - Planner fixes, including improving outer join and bitmap scan - selection logic (Tom) - - - - - - Fix possible wrong answers or crash when a PL/pgSQL function tries - to RETURN from within an EXCEPTION block - (Tom) - - - - - - Fix PANIC during enlargement of a hash index (Tom) - - - - - - Fix POSIX-style timezone specs to follow new USA DST rules (Tom) - - - - - - - - - - Release 8.2.3 - - - Release date: - 2007-02-07 - - - - This release contains two fixes from 8.2.2. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.3 - - - A dump/restore is not required for those running 8.2.X. - - - - - - Changes - - - - - - Remove overly-restrictive check for type length in constraints and - functional indexes(Tom) - - - - - - Fix optimization so MIN/MAX in subqueries can again use indexes (Tom) - - - - - - - - - - Release 8.2.2 - - - Release date: - 2007-02-05 - - - - This release contains a variety of fixes from 8.2.1, including - a security fix. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.2 - - - A dump/restore is not required for those running 8.2.X. - - - - - - Changes - - - - - - Remove security vulnerabilities that allowed connected users - to read backend memory (Tom) - - - - The vulnerabilities involve suppressing the normal check that a SQL - function returns the data type it's declared to, and changing the - data type of a table column (CVE-2007-0555, CVE-2007-0556). These - errors can easily be exploited to cause a backend crash, and in - principle might be used to read database content that the user - should not be able to access. - - - - - - Fix not-so-rare-anymore bug wherein btree index page splits could fail - due to choosing an infeasible split point (Heikki Linnakangas) - - - - - - Fix Borland C compile scripts (L Bayuk) - - - - - - Properly handle to_char('CC') for years ending in - 00 (Tom) - - - - Year 2000 is in the twentieth century, not the twenty-first. - - - - - - /contrib/tsearch2 localization improvements (Tatsuo, Teodor) - - - - - - Fix incorrect permission check in - information_schema.key_column_usage view (Tom) - - - - The symptom is relation with OID nnnnn does not exist errors. - To get this fix without using initdb, use CREATE OR - REPLACE VIEW to install the corrected definition found in - share/information_schema.sql. Note you will need to do - this in each database. - - - - - - Improve VACUUM performance for databases with many tables (Tom) - - - - - - Fix for rare Assert() crash triggered by UNION (Tom) - - - - - - Fix potentially incorrect results from index searches using - ROW inequality conditions (Tom) - - - - - - Tighten security of multi-byte character processing for UTF8 sequences - over three bytes long (Tom) - - - - - - Fix bogus permission denied failures occurring on Windows - due to attempts to fsync already-deleted files (Magnus, Tom) - - - - - - Fix bug that could cause the statistics collector - to hang on Windows (Magnus) - - - - This would in turn lead to autovacuum not working. - - - - - - Fix possible crashes when an already-in-use PL/pgSQL function is - updated (Tom) - - - - - - Improve PL/pgSQL handling of domain types (Sergiy Vyshnevetskiy, Tom) - - - - - - Fix possible errors in processing PL/pgSQL exception blocks (Tom) - - - - - - - - - - Release 8.2.1 - - - Release date: - 2007-01-08 - - - - This release contains a variety of fixes from 8.2. - For information about new features in the 8.2 major release, see - . - - - - Migration to Version 8.2.1 - - - A dump/restore is not required for those running 8.2. - - - - - - Changes - - - - - - Fix crash with SELECT ... LIMIT ALL (also - LIMIT NULL) (Tom) - - - - - - Several /contrib/tsearch2 fixes (Teodor) - - - - - - On Windows, make log messages coming from the operating system use - ASCII encoding (Hiroshi Saito) - - - - This fixes a conversion problem when there is a mismatch between - the encoding of the operating system and database server. - - - - - - Fix Windows linking of pg_dump using - win32.mak - (Hiroshi Saito) - - - - - - Fix planner mistakes for outer join queries (Tom) - - - - - - Fix several problems in queries involving sub-SELECTs (Tom) - - - - - - Fix potential crash in SPI during subtransaction abort (Tom) - - - - This affects all PL functions since they all use SPI. - - - - - - Improve build speed of PDF documentation (Peter) - - - - - - Re-add JST (Japan) timezone abbreviation (Tom) - - - - - - Improve optimization decisions related to index scans (Tom) - - - - - - Have psql print multi-byte combining characters as - before, rather than output as \u (Tom) - - - - - - Improve index usage of regular expressions that use parentheses (Tom) - - - - This improves psql \d performance also. - - - - - - Make pg_dumpall assume that databases have public - CONNECT privilege, when dumping from a pre-8.2 server (Tom) - - - - This preserves the previous behavior that anyone can connect to a - database if allowed by pg_hba.conf. - - - - - - - - - - Release 8.2 - - - Release date: - 2006-12-05 - - - - Overview - - - This release adds many functionality and performance improvements that - were requested by users, including: - - - - - - Query language enhancements including INSERT/UPDATE/DELETE - RETURNING, multirow VALUES lists, and - optional target-table alias in - UPDATE/DELETE - - - - - - Index creation without blocking concurrent - INSERT/UPDATE/DELETE - operations - - - - - - Many query optimization improvements, including support for - reordering outer joins - - - - - - Improved sorting performance with lower memory usage - - - - - - More efficient locking with better concurrency - - - - - - More efficient vacuuming - - - - - - Easier administration of warm standby servers - - - - - - New FILLFACTOR support for tables and indexes - - - - - - Monitoring, logging, and performance tuning additions - - - - - - More control over creating and dropping objects - - - - - - Table inheritance relationships can be defined - for and removed from pre-existing tables - - - - - - COPY TO can copy the output of an arbitrary - SELECT statement - - - - - - Array improvements, including nulls in arrays - - - - - - Aggregate-function improvements, including multiple-input - aggregates and SQL:2003 statistical functions - - - - - - Many contrib/ improvements - - - - - - - - - - - Migration to Version 8.2 - - - A dump/restore using pg_dump is - required for those wishing to migrate data from any previous - release. - - - - Observe the following incompatibilities: - - - - - - - Set escape_string_warning - to on by default (Bruce) - - - - This issues a warning if backslash escapes are used in - non-escape (non-E'') - strings. - - - - - - Change the row - constructor syntax (ROW(...)) so that - list elements foo.* will be expanded to a list - of their member fields, rather than creating a nested - row type field as formerly (Tom) - - - - The new behavior is substantially more useful since it - allows, for example, triggers to check for data changes - with IF row(new.*) IS DISTINCT FROM row(old.*). - The old behavior is still available by omitting .*. - - - - - - Make row comparisons - follow SQL standard semantics and allow them - to be used in index scans (Tom) - - - - Previously, row = and <> comparisons followed the - standard but < <= > >= did not. A row comparison - can now be used as an index constraint for a multicolumn - index matching the row value. - - - - - - Make row IS NOT NULL - tests follow SQL standard semantics (Tom) - - - - The former behavior conformed to the standard for simple cases - with IS NULL, but IS NOT NULL would return - true if any row field was non-null, whereas the standard says it - should return true only when all fields are non-null. - - - - - - Make SET - CONSTRAINT affect only one constraint (Kris Jurka) - - - - In previous releases, SET CONSTRAINT modified - all constraints with a matching name. In this release, - the schema search path is used to modify only the first - matching constraint. A schema specification is also - supported. This more nearly conforms to the SQL standard. - - - - - - Remove RULE permission for tables, for security reasons - (Tom) - - - - As of this release, only a table's owner can create or modify - rules for the table. For backwards compatibility, - GRANT/REVOKE RULE is still accepted, - but it does nothing. - - - - - - Array comparison improvements (Tom) - - - - Now array dimensions are also compared. - - - - - - Change array concatenation - to match documented behavior (Tom) - - - - This changes the previous behavior where concatenation - would modify the array lower bound. - - - - - - Make command-line options of postmaster - and postgres - identical (Peter) - - - - This allows the postmaster to pass arguments to each backend - without using -o. Note that some options are now - only available as long-form options, because there were conflicting - single-letter options. - - - - - - Deprecate use of postmaster symbolic link (Peter) - - - - postmaster and postgres - commands now act identically, with the behavior determined - by command-line options. The postmaster symbolic link is - kept for compatibility, but is not really needed. - - - - - - Change log_duration - to output even if the query is not output (Tom) - - - - In prior releases, log_duration only printed if - the query appeared earlier in the log. - - - - - - Make to_char(time) - and to_char(interval) - treat HH and HH12 as 12-hour - intervals - - - - Most applications should use HH24 unless they - want a 12-hour display. - - - - - - Zero unmasked bits in conversion from INET to CIDR (Tom) - - - - This ensures that the converted value is actually valid for - CIDR. - - - - - - Remove australian_timezones configuration variable - (Joachim Wieland) - - - - This variable has been superseded by a more general facility - for configuring timezone abbreviations. - - - - - - Improve cost estimation for nested-loop index scans (Tom) - - - - This might eliminate the need to set unrealistically small - values of random_page_cost. - If you have been using a very small random_page_cost, - please recheck your test cases. - - - - - - Change behavior of pg_dump -n and - -t options. (Greg Sabino Mullane) - - - See the pg_dump manual page for details. - - - - - - Change libpq - PQdsplen() to return a useful value (Martijn - van Oosterhout) - - - - - - Declare libpq - PQgetssl() as returning void *, - rather than SSL * (Martijn van Oosterhout) - - - - This allows applications to use the function without including - the OpenSSL headers. - - - - - - C-language loadable modules must now include a - PG_MODULE_MAGIC - macro call for version compatibility checking - (Martijn van Oosterhout) - - - - - - For security's sake, modules used by a PL/PerlU function are no - longer available to PL/Perl functions (Andrew) - - - - This also implies that data can no longer be shared between a PL/Perl - function and a PL/PerlU function. - Some Perl installations have not been compiled with the correct flags - to allow multiple interpreters to exist within a single process. - In this situation PL/Perl and PL/PerlU cannot both be used in a - single backend. The solution is to get a Perl installation which - supports multiple interpreters. - - - - - - - In contrib/xml2/, rename xml_valid() to - xml_is_well_formed() (Tom) - - - - xml_valid() will remain for backward compatibility, - but its behavior will change to do schema checking in a future - release. - - - - - - Remove contrib/ora2pg/, now at - - - - - - Remove contrib modules that have been migrated to PgFoundry: - adddepend, dbase, dbmirror, - fulltextindex, mac, userlock - - - - - - Remove abandoned contrib modules: - mSQL-interface, tips - - - - - - Remove QNX and BEOS ports (Bruce) - - - - These ports no longer had active maintainers. - - - - - - - - Changes - - - Below you will find a detailed account of the - changes between PostgreSQL 8.2 and - the previous major release. - - - - Performance Improvements - - - - - Allow the planner to reorder outer - joins in some circumstances (Tom) - - - - In previous releases, outer joins would always be evaluated in - the order written in the query. This change allows the - query optimizer to consider reordering outer joins, in cases where - it can determine that the join order can be changed without - altering the meaning of the query. This can make a - considerable performance difference for queries involving - multiple outer joins or mixed inner and outer joins. - - - - - - Improve efficiency of IN - (list-of-expressions) clauses (Tom) - - - - - - Improve sorting speed and reduce memory usage (Simon, Tom) - - - - - - Improve subtransaction performance (Alvaro, Itagaki Takahiro, - Tom) - - - - - - Add FILLFACTOR to table and index creation (ITAGAKI - Takahiro) - - - - This leaves extra free space in each table or index page, - allowing improved performance as the database grows. This - is particularly valuable to maintain clustering. - - - - - - Increase default values for shared_buffers - and max_fsm_pages - (Andrew) - - - - - - Improve locking performance by breaking the lock manager tables into - sections - (Tom) - - - - This allows locking to be more fine-grained, reducing - contention. - - - - - - Reduce locking requirements of sequential scans (Qingqing - Zhou) - - - - - - Reduce locking required for database creation and destruction - (Tom) - - - - - - Improve the optimizer's selectivity estimates for LIKE, ILIKE, and - regular expression - operations (Tom) - - - - - - Improve planning of joins to inherited - tables and UNION - ALL views (Tom) - - - - - - Allow constraint - exclusion to be applied to inherited UPDATE and - DELETE queries (Tom) - - - - SELECT already honored constraint exclusion. - - - - - - Improve planning of constant WHERE clauses, such as - a condition that depends only on variables inherited from an - outer query level (Tom) - - - - - - Protocol-level unnamed prepared statements are re-planned - for each set of BIND values (Tom) - - - - This improves performance because the exact parameter values - can be used in the plan. - - - - - - Speed up vacuuming of B-Tree indexes (Heikki Linnakangas, - Tom) - - - - - - Avoid extra scan of tables without indexes during VACUUM (Greg Stark) - - - - - - Improve multicolumn GiST - indexing (Oleg, Teodor) - - - - - - Remove dead index entries before B-Tree page split (Junji - Teramoto) - - - - - - - - - Server Changes - - - - - Allow a forced switch to a new transaction log file (Simon, Tom) - - - - This is valuable for keeping warm standby slave servers - in sync with the master. Transaction log file switching now also happens - automatically during pg_stop_backup(). - This ensures that all - transaction log files needed for recovery can be archived immediately. - - - - - - Add WAL informational functions (Simon) - - - - Add functions for interrogating the current transaction log insertion - point and determining WAL filenames from the - hex WAL locations displayed by pg_stop_backup() - and related functions. - - - - - - Improve recovery from a crash during WAL replay (Simon) - - - - The server now does periodic checkpoints during WAL - recovery, so if there is a crash, future WAL - recovery is shortened. This also eliminates the need for - warm standby servers to replay the entire log since the - base backup if they crash. - - - - - - Improve reliability of long-term WAL replay - (Heikki, Simon, Tom) - - - - Formerly, trying to roll forward through more than 2 billion - transactions would not work due to XID wraparound. This meant - warm standby servers had to be reloaded - from fresh base backups periodically. - - - - - - Add archive_timeout - to force transaction log file switches at a given interval (Simon) - - - - This enforces a maximum replication delay for warm standby servers. - - - - - - Add native LDAP - authentication (Magnus Hagander) - - - - This is particularly useful for platforms that do not - support PAM, such as Windows. - - - - - - Add GRANT - CONNECT ON DATABASE (Gevik Babakhani) - - - - This gives SQL-level control over database access. It works as - an additional filter on top of the existing - pg_hba.conf - controls. - - - - - - Add support for SSL - Certificate Revocation List (CRL) files - (Libor Hohoš) - - - - The server and libpq both recognize CRL - files now. - - - - - - GiST indexes are - now clusterable (Teodor) - - - - - - Remove routine autovacuum server log entries (Bruce) - - - - pg_stat_activity - now shows autovacuum activity. - - - - - - Track maximum XID age within individual tables, instead of whole databases (Alvaro) - - - - This reduces the overhead involved in preventing transaction - ID wraparound, by avoiding unnecessary VACUUMs. - - - - - - Add last vacuum and analyze timestamp columns to the stats - collector (Larry Rosenman) - - - - These values now appear in the pg_stat_*_tables - system views. - - - - - - Improve performance of statistics monitoring, especially - stats_command_string - (Tom, Bruce) - - - - This release enables stats_command_string by - default, now that its overhead is minimal. This means - pg_stat_activity - will now show all active queries by default. - - - - - - Add a waiting column to pg_stat_activity - (Tom) - - - - This allows pg_stat_activity to show all the - information included in the ps display. - - - - - - Add configuration parameter update_process_title - to control whether the ps display is updated - for every command (Bruce) - - - - On platforms where it is expensive to update the ps - display, it might be worthwhile to turn this off and rely solely on - pg_stat_activity for status information. - - - - - - Allow units to be specified in configuration settings - (Peter) - - - - For example, you can now set shared_buffers - to 32MB rather than mentally converting sizes. - - - - - - Add support for include - directives in postgresql.conf (Joachim - Wieland) - - - - - - Improve logging of protocol-level prepare/bind/execute - messages (Bruce, Tom) - - - - Such logging now shows statement names, bind parameter - values, and the text of the query being executed. Also, - the query text is properly included in logged error messages - when enabled by log_min_error_statement. - - - - - - Prevent max_stack_depth - from being set to unsafe values - - - - On platforms where we can determine the actual kernel stack depth - limit (which is most), make sure that the initial default value of - max_stack_depth is safe, and reject attempts to set it - to unsafely large values. - - - - - - Enable highlighting of error location in query in more - cases (Tom) - - - - The server is now able to report a specific error location for - some semantic errors (such as unrecognized column name), rather - than just for basic syntax errors as before. - - - - - - Fix failed to re-find parent key errors in - VACUUM (Tom) - - - - - - Clean out pg_internal.init cache files during server - restart (Simon) - - - - This avoids a hazard that the cache files might contain stale - data after PITR recovery. - - - - - - Fix race condition for truncation of a large relation across a - gigabyte boundary by VACUUM (Tom) - - - - - - Fix bug causing needless deadlock errors on row-level locks (Tom) - - - - - - Fix bugs affecting multi-gigabyte hash indexes (Tom) - - - - - - Each backend process is now its own process group leader (Tom) - - - - This allows query cancel to abort subprocesses invoked from a - backend or archive/recovery process. - - - - - - - - - Query Changes - - - - - Add INSERT/UPDATE/DELETE - RETURNING (Jonah Harris, Tom) - - - - This allows these commands to return values, such as the - computed serial key for a new row. In the UPDATE - case, values from the updated version of the row are returned. - - - - - - Add support for multiple-row VALUES clauses, - per SQL standard (Joe, Tom) - - - - This allows INSERT to insert multiple rows of - constants, or queries to generate result sets using constants. - For example, INSERT ... VALUES (...), (...), - ...., and SELECT * FROM (VALUES (...), (...), - ....) AS alias(f1, ...). - - - - - - Allow UPDATE - and DELETE - to use an alias for the target table (Atsushi Ogawa) - - - - The SQL standard does not permit an alias in these commands, but - many database systems allow one anyway for notational convenience. - - - - - - Allow UPDATE - to set multiple columns with a list of values (Susanne - Ebrecht) - - - - This is basically a short-hand for assigning the columns - and values in pairs. The syntax is UPDATE tab - SET (column, ...) = (val, ...). - - - - - - Make row comparisons work per standard (Tom) - - - - The forms <, <=, >, >= now compare rows lexicographically, - that is, compare the first elements, if equal compare the second - elements, and so on. Formerly they expanded to an AND condition - across all the elements, which was neither standard nor very useful. - - - - - - Add CASCADE - option to TRUNCATE (Joachim Wieland) - - - - This causes TRUNCATE to automatically include all tables - that reference the specified table(s) via foreign keys. While - convenient, this is a dangerous tool — use with caution! - - - - - - Support FOR UPDATE and FOR SHARE - in the same SELECT - command (Tom) - - - - - - Add IS NOT - DISTINCT FROM (Pavel Stehule) - - - - This operator is similar to equality (=), but - evaluates to true when both left and right operands are - NULL, and to false when just one is, rather than - yielding NULL in these cases. - - - - - - Improve the length output used by UNION/INTERSECT/EXCEPT - (Tom) - - - - When all corresponding columns are of the same defined length, that - length is used for the result, rather than a generic length. - - - - - - Allow ILIKE - to work for multi-byte encodings (Tom) - - - - Internally, ILIKE now calls lower() - and then uses LIKE. Locale-specific regular - expression patterns still do not work in these encodings. - - - - - - Enable standard_conforming_strings - to be turned on (Kevin Grittner) - - - - This allows backslash escaping in strings to be disabled, - making PostgreSQL more - standards-compliant. The default is off for backwards - compatibility, but future releases will default this to on. - - - - - - Do not flatten subqueries that contain volatile - functions in their target lists (Jaime Casanova) - - - - This prevents surprising behavior due to multiple evaluation - of a volatile function (such as random() - or nextval()). It might cause performance - degradation in the presence of functions that are unnecessarily - marked as volatile. - - - - - - Add system views pg_prepared_statements - and pg_cursors - to show prepared statements and open cursors (Joachim Wieland, Neil) - - - - These are very useful in pooled connection setups. - - - - - - Support portal parameters in EXPLAIN and EXECUTE (Tom) - - - - This allows, for example, JDBC ? parameters to - work in these commands. - - - - - - If SQL-level PREPARE parameters - are unspecified, infer their types from the content of the - query (Neil) - - - - Protocol-level PREPARE already did this. - - - - - - Allow LIMIT and OFFSET to exceed - two billion (Dhanaraj M) - - - - - - - - - Object Manipulation Changes - - - - - Add TABLESPACE clause to CREATE TABLE AS - (Neil) - - - - This allows a tablespace to be specified for the new table. - - - - - - Add ON COMMIT clause to CREATE TABLE AS - (Neil) - - - - This allows temporary tables to be truncated or dropped on - transaction commit. The default behavior is for the table - to remain until the session ends. - - - - - - Add INCLUDING CONSTRAINTS to CREATE TABLE LIKE - (Greg Stark) - - - - This allows easy copying of CHECK constraints to a new - table. - - - - - - Allow the creation of placeholder (shell) types (Martijn van Oosterhout) - - - - A shell type declaration creates a type name, without specifying - any of the details of the type. Making a shell type is useful - because it allows cleaner declaration of the type's input/output - functions, which must exist before the type can be defined for - real. The syntax is CREATE TYPE typename. - - - - - - Aggregate functions - now support multiple input parameters (Sergey Koposov, Tom) - - - - - - Add new aggregate creation syntax (Tom) - - - - The new syntax is CREATE AGGREGATE - aggname (input_type) - (parameter_list). This more - naturally supports the new multi-parameter aggregate - functionality. The previous syntax is still supported. - - - - - - Add ALTER ROLE PASSWORD NULL - to remove a previously set role password (Peter) - - - - - - Add DROP object IF EXISTS for many - object types (Andrew) - - - - This allows DROP operations on non-existent - objects without generating an error. - - - - - - Add DROP OWNED - to drop all objects owned by a role (Alvaro) - - - - - - Add REASSIGN - OWNED to reassign ownership of all objects owned - by a role (Alvaro) - - - - This, and DROP OWNED above, facilitate dropping - roles. - - - - - - Add GRANT ON SEQUENCE - syntax (Bruce) - - - - This was added for setting sequence-specific permissions. - GRANT ON TABLE for sequences is still supported - for backward compatibility. - - - - - - Add USAGE - permission for sequences that allows only currval() - and nextval(), not setval() - (Bruce) - - - - USAGE permission allows more fine-grained - control over sequence access. Granting USAGE - allows users to increment - a sequence, but prevents them from setting the sequence to - an arbitrary value using setval(). - - - - - - Add ALTER TABLE - [ NO ] INHERIT (Greg Stark) - - - - This allows inheritance to be adjusted dynamically, rather than - just at table creation and destruction. This is very valuable - when using inheritance to implement table partitioning. - - - - - - Allow comments on global - objects to be stored globally (Kris Jurka) - - - - Previously, comments attached to databases were stored in individual - databases, making them ineffective, and there was no provision - at all for comments on roles or tablespaces. This change adds a new - shared catalog pg_shdescription - and stores comments on databases, roles, and tablespaces therein. - - - - - - - - - Utility Command Changes - - - - - Add option to allow indexes to be created without blocking - concurrent writes to the table (Greg Stark, Tom) - - - - The new syntax is CREATE - INDEX CONCURRENTLY. The default behavior is - still to block table modification while an index is being - created. - - - - - - Provide advisory - locking functionality (Abhijit Menon-Sen, Tom) - - - - This is a new locking API designed to replace what used to be - in /contrib/userlock. The userlock code is now on pgfoundry. - - - - - - Allow COPY to - dump a SELECT query (Zoltan Boszormenyi, Karel - Zak) - - - - This allows COPY to dump arbitrary SQL - queries. The syntax is COPY (SELECT ...) TO. - - - - - - Make the COPY - command return a command tag that includes the number of - rows copied (Volkan YAZICI) - - - - - - Allow VACUUM - to expire rows without being affected by other concurrent - VACUUM operations (Hannu Krossing, Alvaro, Tom) - - - - - - Make initdb - detect the operating system locale and set the default - DateStyle accordingly (Peter) - - - - This makes it more likely that the installed - postgresql.conf DateStyle value will - be as desired. - - - - - - Reduce number of progress messages displayed by initdb (Tom) - - - - - - - - - Date/Time Changes - - - - - Allow full timezone names in timestamp input values - (Joachim Wieland) - - - - For example, '2006-05-24 21:11 - America/New_York'::timestamptz. - - - - - - Support configurable timezone abbreviations (Joachim Wieland) - - - - A desired set of timezone abbreviations can be chosen via the - configuration parameter timezone_abbreviations. - - - - - - Add pg_timezone_abbrevs - and pg_timezone_names - views to show supported timezones (Magnus Hagander) - - - - - - Add clock_timestamp(), - statement_timestamp(), - and transaction_timestamp() - (Bruce) - - - - clock_timestamp() is the current wall-clock time, - statement_timestamp() is the time the current - statement arrived at the server, and - transaction_timestamp() is an alias for - now(). - - - - - - Allow to_char() - to print localized month and day names (Euler Taveira de - Oliveira) - - - - - - Allow to_char(time) - and to_char(interval) - to output AM/PM specifications - (Bruce) - - - - Intervals and times are treated as 24-hour periods, e.g. - 25 hours is considered AM. - - - - - - Add new function justify_interval() - to adjust interval units (Mark Dilger) - - - - - - Allow timezone offsets up to 14:59 away from GMT - - - - Kiribati uses GMT+14, so we'd better accept that. - - - - - - Interval computation improvements (Michael Glaesemann, Bruce) - - - - - - - - - Other Data Type and Function Changes - - - - - Allow arrays to contain NULL elements (Tom) - - - - - - Allow assignment to array elements not contiguous with the existing - entries (Tom) - - - - The intervening array positions will be filled with nulls. - This is per SQL standard. - - - - - - New built-in operators - for array-subset comparisons (@>, - <@, &&) (Teodor, Tom) - - - - These operators can be indexed for many data types using - GiST or GIN indexes. - - - - - - Add convenient arithmetic operations on - INET/CIDR values (Stephen R. van den - Berg) - - - - The new operators are & (and), | - (or), ~ (not), inet + int8, - inet - int8, and - inet - inet. - - - - - - Add new aggregate functions - from SQL:2003 (Neil) - - - - The new functions are var_pop(), - var_samp(), stddev_pop(), and - stddev_samp(). var_samp() and - stddev_samp() are merely renamings of the - existing aggregates variance() and - stddev(). The latter names remain available - for backward compatibility. - - - - - - Add SQL:2003 statistical aggregates - (Sergey Koposov) - - - - New functions: regr_intercept(), - regr_slope(), regr_r2(), - corr(), covar_samp(), - covar_pop(), regr_avgx(), - regr_avgy(), regr_sxy(), - regr_sxx(), regr_syy(), - regr_count(). - - - - - - Allow domains to be - based on other domains (Tom) - - - - - - Properly enforce domain CHECK constraints - everywhere (Neil, Tom) - - - - For example, the result of a user-defined function that is - declared to return a domain type is now checked against the - domain's constraints. This closes a significant hole in the domain - implementation. - - - - - - Fix problems with dumping renamed SERIAL columns - (Tom) - - - - The fix is to dump a SERIAL column by explicitly - specifying its DEFAULT and sequence elements, - and reconstructing the SERIAL column on reload - using a new ALTER - SEQUENCE OWNED BY command. This also allows - dropping a SERIAL column specification. - - - - - - Add a server-side sleep function pg_sleep() - (Joachim Wieland) - - - - - - Add all comparison operators for the tid (tuple id) data - type (Mark Kirkwood, Greg Stark, Tom) - - - - - - - - - PL/pgSQL Server-Side Language Changes - - - - - Add TG_table_name and TG_table_schema to - trigger parameters (Andrew) - - - - TG_relname is now deprecated. Comparable - changes have been made in the trigger parameters for the other - PLs as well. - - - - - - Allow FOR statements to return values to scalars - as well as records and row types (Pavel Stehule) - - - - - - Add a BY clause to the FOR loop, - to control the iteration increment (Jaime Casanova) - - - - - - Add STRICT to SELECT - INTO (Matt Miller) - - - - STRICT mode throws an exception if more or less - than one row is returned by the SELECT, for - Oracle PL/SQL compatibility. - - - - - - - - - PL/Perl Server-Side Language Changes - - - - - Add table_name and table_schema to - trigger parameters (Adam Sjøgren) - - - - - - Add prepared queries (Dmitry Karasik) - - - - - - Make $_TD trigger data a global variable (Andrew) - - - - Previously, it was lexical, which caused unexpected sharing - violations. - - - - - - Run PL/Perl and PL/PerlU in separate interpreters, for security - reasons (Andrew) - - - In consequence, they can no longer share data nor loaded modules. - Also, if Perl has not been compiled with the requisite flags to - allow multiple interpreters, only one of these languages can be used - in any given backend process. - - - - - - - - - PL/Python Server-Side Language Changes - - - - - Named parameters are passed as ordinary variables, as well as in the - args[] array (Sven Suursoho) - - - - - - Add table_name and table_schema to - trigger parameters (Andrew) - - - - - - Allow returning of composite types and result sets (Sven Suursoho) - - - - - - Return result-set as list, iterator, - or generator (Sven Suursoho) - - - - - - Allow functions to return void (Neil) - - - - - - Python 2.5 is now supported (Tom) - - - - - - - - - <link linkend="app-psql"><application>psql</application></link> Changes - - - - - Add new command \password for changing role - password with client-side password encryption (Peter) - - - - - - Allow \c to connect to a new host and port - number (David, Volkan YAZICI) - - - - - - Add tablespace display to \l+ (Philip Yarra) - - - - - - Improve \df slash command to include the argument - names and modes (OUT or INOUT) of - the function (David Fetter) - - - - - - Support binary COPY (Andreas Pflug) - - - - - - Add option to run the entire session in a single transaction - (Simon) - - - - Use option -1 or --single-transaction. - - - - - - Support for automatically retrieving SELECT - results in batches using a cursor (Chris Mair) - - - - This is enabled using \set FETCH_COUNT - n. This - feature allows large result sets to be retrieved in - psql without attempting to buffer the entire - result set in memory. - - - - - - Make multi-line values align in the proper column - (Martijn van Oosterhout) - - - - Field values containing newlines are now displayed in a more - readable fashion. - - - - - - Save multi-line statements as a single entry, rather than - one line at a time (Sergey E. Koposov) - - - - This makes up-arrow recall of queries easier. (This is - not available on Windows, because that platform uses the native - command-line editing present in the operating system.) - - - - - - Make the line counter 64-bit so it can handle files with more - than two billion lines (David Fetter) - - - - - - Report both the returned data and the command status tag - for INSERT/UPDATE/DELETE - RETURNING (Tom) - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> Changes - - - - - Allow complex selection of objects to be included or excluded - by pg_dump (Greg Sabino Mullane) - - - - pg_dump now supports multiple -n - (schema) and -t (table) options, and adds - -N and -T options to exclude objects. - Also, the arguments of these switches can now be wild-card expressions - rather than single object names, for example - -t 'foo*', and a schema can be part of - a -t or -T switch, for example - -t schema1.table1. - - - - - - Add pg_restore - --no-data-for-failed-tables option to suppress - loading data if table creation failed (i.e., the table already - exists) (Martin Pitt) - - - - - - Add pg_restore - option to run the entire session in a single transaction - (Simon) - - - - Use option -1 or --single-transaction. - - - - - - - - - <link linkend="libpq"><application>libpq</application></link> Changes - - - - - Add PQencryptPassword() - to encrypt passwords (Tom) - - - - This allows passwords to be sent pre-encrypted for commands - like ALTER ROLE ... - PASSWORD. - - - - - - Add function PQisthreadsafe() - (Bruce) - - - - This allows applications to query the thread-safety status - of the library. - - - - - - Add PQdescribePrepared(), - PQdescribePortal(), - and related functions to return information about previously - prepared statements and open cursors (Volkan YAZICI) - - - - - - Allow LDAP lookups - from pg_service.conf - (Laurenz Albe) - - - - - - Allow a hostname in ~/.pgpass - to match the default socket directory (Bruce) - - - - A blank hostname continues to match any Unix-socket connection, - but this addition allows entries that are specific to one of - several postmasters on the machine. - - - - - - - - - <link linkend="ecpg"><application>ecpg</application></link> Changes - - - - - Allow SHOW to - put its result into a variable (Joachim Wieland) - - - - - - Add COPY TO STDOUT - (Joachim Wieland) - - - - - - Add regression tests (Joachim Wieland, Michael) - - - - - - Major source code cleanups (Joachim Wieland, Michael) - - - - - - - - - <application>Windows</application> Port - - - - - Allow MSVC to compile the PostgreSQL - server (Magnus, Hiroshi Saito) - - - - - - Add MSVC support for utility commands and pg_dump (Hiroshi - Saito) - - - - - - Add support for Windows code pages 1253, - 1254, 1255, and 1257 - (Kris Jurka) - - - - - - Drop privileges on startup, so that the server can be started from - an administrative account (Magnus) - - - - - - Stability fixes (Qingqing Zhou, Magnus) - - - - - - Add native semaphore implementation (Qingqing Zhou) - - - - The previous code mimicked SysV semaphores. - - - - - - - - - Source Code Changes - - - - - Add GIN (Generalized - Inverted iNdex) index access method (Teodor, Oleg) - - - - - - Remove R-tree indexing (Tom) - - - - Rtree has been re-implemented using GiST. Among other - differences, this means that rtree indexes now have support - for crash recovery via write-ahead logging (WAL). - - - - - - Reduce libraries needlessly linked into the backend (Martijn - van Oosterhout, Tom) - - - - - - Add a configure flag to allow libedit to be preferred over - GNU readline (Bruce) - - - - Use configure --with-libedit-preferred. - - - - - - Allow installation into directories containing spaces - (Peter) - - - - - - Improve ability to relocate installation directories (Tom) - - - - - - Add support for Solaris x86_64 using the - Solaris compiler (Pierre Girard, Theo - Schlossnagle, Bruce) - - - - - - Add DTrace support (Robert Lor) - - - - - - Add PG_VERSION_NUM for use by third-party - applications wanting to test the backend version in C using > - and < comparisons (Bruce) - - - - - - Add XLOG_BLCKSZ as independent from BLCKSZ - (Mark Wong) - - - - - - Add LWLOCK_STATS define to report locking - activity (Tom) - - - - - - Emit warnings for unknown configure options - (Martijn van Oosterhout) - - - - - - Add server support for plugin libraries - that can be used for add-on tasks such as debugging and performance - measurement (Korry Douglas) - - - - This consists of two features: a table of rendezvous - variables that allows separately-loaded shared libraries to - communicate, and a new configuration parameter local_preload_libraries - that allows libraries to be loaded into specific sessions without - explicit cooperation from the client application. This allows - external add-ons to implement features such as a PL/pgSQL debugger. - - - - - - Rename existing configuration parameter - preload_libraries to shared_preload_libraries - (Tom) - - - - This was done for clarity in comparison to - local_preload_libraries. - - - - - - Add new configuration parameter server_version_num - (Greg Sabino Mullane) - - - - This is like server_version, but is an - integer, e.g. 80200. This allows applications to - make version checks more easily. - - - - - - Add a configuration parameter seq_page_cost - (Tom) - - - - - - Re-implement the regression test script as a C program - (Magnus, Tom) - - - - - - Allow loadable modules to allocate shared memory and - lightweight locks (Marc Munro) - - - - - - Add automatic initialization and finalization of dynamically - loaded libraries (Ralf Engelschall, Tom) - - - - New functions - _PG_init() and _PG_fini() are - called if the library defines such symbols. Hence we no - longer need to specify an initialization function in - shared_preload_libraries; we can assume that - the library used the _PG_init() convention - instead. - - - - - - Add PG_MODULE_MAGIC - header block to all shared object files (Martijn van - Oosterhout) - - - - The magic block prevents version mismatches between loadable object - files and servers. - - - - - - Add shared library support for AIX (Laurenz Albe) - - - - - - New XML - documentation section (Bruce) - - - - - - - - - Contrib Changes - - - - - Major tsearch2 improvements (Oleg, Teodor) - - - - - - - multibyte encoding support, including UTF8 - - - - - query rewriting support - - - - - improved ranking functions - - - - - thesaurus dictionary support - - - - - Ispell dictionaries now recognize MySpell - format, used by OpenOffice - - - - - GIN support - - - - - - - - - - Add adminpack module containing Pgadmin administration - functions (Dave) - - - - These functions provide additional file system access - routines not present in the default PostgreSQL - server. - - - - - - Add sslinfo module (Victor Wagner) - - - - Reports information about the current connection's SSL - certificate. - - - - - - Add pgrowlocks module (Tatsuo) - - - - This shows row locking information for a specified table. - - - - - - Add hstore module (Oleg, Teodor) - - - - - - Add isn module, replacing isbn_issn (Jeremy Kronuz) - - - - This new implementation supports EAN13, UPC, - ISBN (books), ISMN (music), and - ISSN (serials). - - - - - - Add index information functions to pgstattuple (ITAGAKI Takahiro, - Satoshi Nagayasu) - - - - - - Add pg_freespacemap module to display free space map information - (Mark Kirkwood) - - - - - - pgcrypto now has all planned functionality (Marko Kreen) - - - - - Include iMath library in pgcrypto to have the public-key encryption - functions always available. - - - - - Add SHA224 algorithm that was missing in OpenBSD code. - - - - - Activate builtin code for SHA224/256/384/512 hashes on older - OpenSSL to have those algorithms always available. - - - - - New function gen_random_bytes() that returns cryptographically strong - randomness. Useful for generating encryption keys. - - - - - Remove digest_exists(), hmac_exists() and cipher_exists() functions. - - - - - - - - Improvements to cube module (Joshua Reich) - - - - New functions are cube(float[]), - cube(float[], float[]), and - cube_subset(cube, int4[]). - - - - - - Add async query capability to dblink (Kai Londenberg, - Joe Conway) - - - - - - New operators for array-subset comparisons (@>, - <@, &&) (Tom) - - - - Various contrib packages already had these operators for their - datatypes, but the naming wasn't consistent. We have now added - consistently named array-subset comparison operators to the core code - and all the contrib packages that have such functionality. - (The old names remain available, but are deprecated.) - - - - - - Add uninstall scripts for all contrib packages that have install - scripts (David, Josh Drake) - - - - - - - - - diff --git a/doc/src/sgml/release-8.3.sgml b/doc/src/sgml/release-8.3.sgml deleted file mode 100644 index 2e10bc49827..00000000000 --- a/doc/src/sgml/release-8.3.sgml +++ /dev/null @@ -1,8549 +0,0 @@ - - - - - Release 8.3.23 - - - Release date: - 2013-02-07 - - - - This release contains a variety of fixes from 8.3.22. - For information about new features in the 8.3 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 8.3.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 8.3.23 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Prevent execution of enum_recv from SQL (Tom Lane) - - - - The function was misdeclared, allowing a simple SQL command to crash the - server. In principle an attacker might be able to use it to examine the - contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) - for reporting this issue. (CVE-2013-0255) - - - - - - Fix SQL grammar to allow subscripting or field selection from a - sub-SELECT result (Tom Lane) - - - - - - Protect against race conditions when scanning - pg_tablespace (Stephen Frost, Tom Lane) - - - - CREATE DATABASE and DROP DATABASE could - misbehave if there were concurrent updates of - pg_tablespace entries. - - - - - - Prevent DROP OWNED from trying to drop whole databases or - tablespaces (Álvaro Herrera) - - - - For safety, ownership of these objects must be reassigned, not dropped. - - - - - - Prevent misbehavior when a RowExpr or XmlExpr - is parse-analyzed twice (Andres Freund, Tom Lane) - - - - This mistake could be user-visible in contexts such as - CREATE TABLE LIKE INCLUDING INDEXES. - - - - - - Improve defenses against integer overflow in hashtable sizing - calculations (Jeff Davis) - - - - - - Ensure that non-ASCII prompt strings are translated to the correct - code page on Windows (Alexander Law, Noah Misch) - - - - This bug affected psql and some other client programs. - - - - - - Fix possible crash in psql's \? command - when not connected to a database (Meng Qingzhong) - - - - - - Fix one-byte buffer overrun in libpq's - PQprintTuples (Xi Wang) - - - - This ancient function is not used anywhere by - PostgreSQL itself, but it might still be used by some - client code. - - - - - - Rearrange configure's tests for supplied functions so it is not - fooled by bogus exports from libedit/libreadline (Christoph Berg) - - - - - - Ensure Windows build number increases over time (Magnus Hagander) - - - - - - Make pgxs build executables with the right - .exe suffix when cross-compiling for Windows - (Zoltan Boszormenyi) - - - - - - Add new timezone abbreviation FET (Tom Lane) - - - - This is now used in some eastern-European time zones. - - - - - - - - - - Release 8.3.22 - - - Release date: - 2012-12-06 - - - - This release contains a variety of fixes from 8.3.21. - For information about new features in the 8.3 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.3.X release series in February 2013. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.3.22 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Fix multiple bugs associated with CREATE INDEX - CONCURRENTLY (Andres Freund, Tom Lane) - - - - Fix CREATE INDEX CONCURRENTLY to use - in-place updates when changing the state of an index's - pg_index row. This prevents race conditions that could - cause concurrent sessions to miss updating the target index, thus - resulting in corrupt concurrently-created indexes. - - - - Also, fix various other operations to ensure that they ignore - invalid indexes resulting from a failed CREATE INDEX - CONCURRENTLY command. The most important of these is - VACUUM, because an auto-vacuum could easily be launched - on the table before corrective action can be taken to fix or remove - the invalid index. - - - - - - Avoid corruption of internal hash tables when out of memory - (Hitoshi Harada) - - - - - - Fix planning of non-strict equivalence clauses above outer joins - (Tom Lane) - - - - The planner could derive incorrect constraints from a clause equating - a non-strict construct to something else, for example - WHERE COALESCE(foo, 0) = 0 - when foo is coming from the nullable side of an outer join. - - - - - - Improve planner's ability to prove exclusion constraints from - equivalence classes (Tom Lane) - - - - - - Fix partial-row matching in hashed subplans to handle cross-type cases - correctly (Tom Lane) - - - - This affects multicolumn NOT IN subplans, such as - WHERE (a, b) NOT IN (SELECT x, y FROM ...) - when for instance b and y are int4 - and int8 respectively. This mistake led to wrong answers - or crashes depending on the specific datatypes involved. - - - - - - Acquire buffer lock when re-fetching the old tuple for an - AFTER ROW UPDATE/DELETE trigger (Andres Freund) - - - - In very unusual circumstances, this oversight could result in passing - incorrect data to the precheck logic for a foreign-key enforcement - trigger. That could result in a crash, or in an incorrect decision - about whether to fire the trigger. - - - - - - Fix REASSIGN OWNED to handle grants on tablespaces - (Álvaro Herrera) - - - - - - Ignore incorrect pg_attribute entries for system - columns for views (Tom Lane) - - - - Views do not have any system columns. However, we forgot to - remove such entries when converting a table to a view. That's fixed - properly for 9.3 and later, but in previous branches we need to defend - against existing mis-converted views. - - - - - - Fix rule printing to dump INSERT INTO table - DEFAULT VALUES correctly (Tom Lane) - - - - - - Guard against stack overflow when there are too many - UNION/INTERSECT/EXCEPT clauses - in a query (Tom Lane) - - - - - - Prevent platform-dependent failures when dividing the minimum possible - integer value by -1 (Xi Wang, Tom Lane) - - - - - - Fix possible access past end of string in date parsing - (Hitoshi Harada) - - - - - - Produce an understandable error message if the length of the path name - for a Unix-domain socket exceeds the platform-specific limit - (Tom Lane, Andrew Dunstan) - - - - Formerly, this would result in something quite unhelpful, such as - Non-recoverable failure in name resolution. - - - - - - Fix memory leaks when sending composite column values to the client - (Tom Lane) - - - - - - Make pg_ctl more robust about reading the - postmaster.pid file (Heikki Linnakangas) - - - - Fix race conditions and possible file descriptor leakage. - - - - - - Fix possible crash in psql if incorrectly-encoded data - is presented and the client_encoding setting is a - client-only encoding, such as SJIS (Jiang Guiqing) - - - - - - Fix bugs in the restore.sql script emitted by - pg_dump in tar output format (Tom Lane) - - - - The script would fail outright on tables whose names include - upper-case characters. Also, make the script capable of restoring - data in mode as well as the regular COPY mode. - - - - - - Fix pg_restore to accept POSIX-conformant - tar files (Brian Weaver, Tom Lane) - - - - The original coding of pg_dump's tar - output mode produced files that are not fully conformant with the - POSIX standard. This has been corrected for version 9.3. This - patch updates previous branches so that they will accept both the - incorrect and the corrected formats, in hopes of avoiding - compatibility problems when 9.3 comes out. - - - - - - Fix pg_resetxlog to locate postmaster.pid - correctly when given a relative path to the data directory (Tom Lane) - - - - This mistake could lead to pg_resetxlog not noticing - that there is an active postmaster using the data directory. - - - - - - Fix libpq's lo_import() and - lo_export() functions to report file I/O errors properly - (Tom Lane) - - - - - - Fix ecpg's processing of nested structure pointer - variables (Muhammad Usama) - - - - - - Make contrib/pageinspect's btree page inspection - functions take buffer locks while examining pages (Tom Lane) - - - - - - Fix pgxs support for building loadable modules on AIX - (Tom Lane) - - - - Building modules outside the original source tree didn't work on AIX. - - - - - - Update time zone data files to tzdata release 2012j - for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western - Samoa, and portions of Brazil. - - - - - - - - - - Release 8.3.21 - - - Release date: - 2012-09-24 - - - - This release contains a variety of fixes from 8.3.20. - For information about new features in the 8.3 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.3.X release series in February 2013. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.3.21 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Improve page-splitting decisions in GiST indexes (Alexander Korotkov, - Robert Haas, Tom Lane) - - - - Multi-column GiST indexes might suffer unexpected bloat due to this - error. - - - - - - Fix cascading privilege revoke to stop if privileges are still held - (Tom Lane) - - - - If we revoke a grant option from some role X, but - X still holds that option via a grant from someone - else, we should not recursively revoke the corresponding privilege - from role(s) Y that X had granted it - to. - - - - - - Fix handling of SIGFPE when PL/Perl is in use (Andres Freund) - - - - Perl resets the process's SIGFPE handler to - SIG_IGN, which could result in crashes later on. Restore - the normal Postgres signal handler after initializing PL/Perl. - - - - - - Prevent PL/Perl from crashing if a recursive PL/Perl function is - redefined while being executed (Tom Lane) - - - - - - Work around possible misoptimization in PL/Perl (Tom Lane) - - - - Some Linux distributions contain an incorrect version of - pthread.h that results in incorrect compiled code in - PL/Perl, leading to crashes if a PL/Perl function calls another one - that throws an error. - - - - - - Update time zone data files to tzdata release 2012f - for DST law changes in Fiji - - - - - - - - - - Release 8.3.20 - - - Release date: - 2012-08-17 - - - - This release contains a variety of fixes from 8.3.19. - For information about new features in the 8.3 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.3.X release series in February 2013. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.3.20 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Prevent access to external files/URLs via XML entity references - (Noah Misch, Tom Lane) - - - - xml_parse() would attempt to fetch external files or - URLs as needed to resolve DTD and entity references in an XML value, - thus allowing unprivileged database users to attempt to fetch data - with the privileges of the database server. While the external data - wouldn't get returned directly to the user, portions of it could be - exposed in error messages if the data didn't parse as valid XML; and - in any case the mere ability to check existence of a file might be - useful to an attacker. (CVE-2012-3489) - - - - - - Prevent access to external files/URLs via contrib/xml2's - xslt_process() (Peter Eisentraut) - - - - libxslt offers the ability to read and write both - files and URLs through stylesheet commands, thus allowing - unprivileged database users to both read and write data with the - privileges of the database server. Disable that through proper use - of libxslt's security options. (CVE-2012-3488) - - - - Also, remove xslt_process()'s ability to fetch documents - and stylesheets from external files/URLs. While this was a - documented feature, it was long regarded as a bad idea. - The fix for CVE-2012-3489 broke that capability, and rather than - expend effort on trying to fix it, we're just going to summarily - remove it. - - - - - - Prevent too-early recycling of btree index pages (Noah Misch) - - - - When we allowed read-only transactions to skip assigning XIDs, we - introduced the possibility that a deleted btree page could be - recycled while a read-only transaction was still in flight to it. - This would result in incorrect index search results. The probability - of such an error occurring in the field seems very low because of the - timing requirements, but nonetheless it should be fixed. - - - - - - Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane) - - - - If ALTER SEQUENCE was executed on a freshly created or - reset sequence, and then precisely one nextval() call - was made on it, and then the server crashed, WAL replay would restore - the sequence to a state in which it appeared that no - nextval() had been done, thus allowing the first - sequence value to be returned again by the next - nextval() call. In particular this could manifest for - serial columns, since creation of a serial column's sequence - includes an ALTER SEQUENCE OWNED BY step. - - - - - - Ensure the backup_label file is fsync'd after - pg_start_backup() (Dave Kerr) - - - - - - Back-patch 9.1 improvement to compress the fsync request queue - (Robert Haas) - - - - This improves performance during checkpoints. The 9.1 change - has now seen enough field testing to seem safe to back-patch. - - - - - - Only allow autovacuum to be auto-canceled by a directly blocked - process (Tom Lane) - - - - The original coding could allow inconsistent behavior in some cases; - in particular, an autovacuum could get canceled after less than - deadlock_timeout grace period. - - - - - - Improve logging of autovacuum cancels (Robert Haas) - - - - - - Fix log collector so that log_truncate_on_rotation works - during the very first log rotation after server start (Tom Lane) - - - - - - Ensure that a whole-row reference to a subquery doesn't include any - extra GROUP BY or ORDER BY columns (Tom Lane) - - - - - - Disallow copying whole-row references in CHECK - constraints and index definitions during CREATE TABLE - (Tom Lane) - - - - This situation can arise in CREATE TABLE with - LIKE or INHERITS. The copied whole-row - variable was incorrectly labeled with the row type of the original - table not the new one. Rejecting the case seems reasonable for - LIKE, since the row types might well diverge later. For - INHERITS we should ideally allow it, with an implicit - coercion to the parent table's row type; but that will require more - work than seems safe to back-patch. - - - - - - Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki - Linnakangas, Tom Lane) - - - - - - Fix extraction of common prefixes from regular expressions (Tom Lane) - - - - The code could get confused by quantified parenthesized - subexpressions, such as ^(foo)?bar. This would lead to - incorrect index optimization of searches for such patterns. - - - - - - Report errors properly in contrib/xml2's - xslt_process() (Tom Lane) - - - - - - Update time zone data files to tzdata release 2012e - for DST law changes in Morocco and Tokelau - - - - - - - - - - Release 8.3.19 - - - Release date: - 2012-06-04 - - - - This release contains a variety of fixes from 8.3.18. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.19 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Fix incorrect password transformation in - contrib/pgcrypto's DES crypt() function - (Solar Designer) - - - - If a password string contained the byte value 0x80, the - remainder of the password was ignored, causing the password to be much - weaker than it appeared. With this fix, the rest of the string is - properly included in the DES hash. Any stored password values that are - affected by this bug will thus no longer match, so the stored values may - need to be updated. (CVE-2012-2143) - - - - - - Ignore SECURITY DEFINER and SET attributes for - a procedural language's call handler (Tom Lane) - - - - Applying such attributes to a call handler could crash the server. - (CVE-2012-2655) - - - - - - Allow numeric timezone offsets in timestamp input to be up to - 16 hours away from UTC (Tom Lane) - - - - Some historical time zones have offsets larger than 15 hours, the - previous limit. This could result in dumped data values being rejected - during reload. - - - - - - Fix timestamp conversion to cope when the given time is exactly the - last DST transition time for the current timezone (Tom Lane) - - - - This oversight has been there a long time, but was not noticed - previously because most DST-using zones are presumed to have an - indefinite sequence of future DST transitions. - - - - - - Fix text to name and char to name - casts to perform string truncation correctly in multibyte encodings - (Karl Schnaitter) - - - - - - Fix memory copying bug in to_tsquery() (Heikki Linnakangas) - - - - - - Fix slow session startup when pg_attribute is very large - (Tom Lane) - - - - If pg_attribute exceeds one-fourth of - shared_buffers, cache rebuilding code that is sometimes - needed during session start would trigger the synchronized-scan logic, - causing it to take many times longer than normal. The problem was - particularly acute if many new sessions were starting at once. - - - - - - Ensure sequential scans check for query cancel reasonably often (Merlin - Moncure) - - - - A scan encountering many consecutive pages that contain no live tuples - would not respond to interrupts meanwhile. - - - - - - Ensure the Windows implementation of PGSemaphoreLock() - clears ImmediateInterruptOK before returning (Tom Lane) - - - - This oversight meant that a query-cancel interrupt received later - in the same query could be accepted at an unsafe time, with - unpredictable but not good consequences. - - - - - - Show whole-row variables safely when printing views or rules - (Abbas Butt, Tom Lane) - - - - Corner cases involving ambiguous names (that is, the name could be - either a table or column name of the query) were printed in an - ambiguous way, risking that the view or rule would be interpreted - differently after dump and reload. Avoid the ambiguous case by - attaching a no-op cast. - - - - - - Ensure autovacuum worker processes perform stack depth checking - properly (Heikki Linnakangas) - - - - Previously, infinite recursion in a function invoked by - auto-ANALYZE could crash worker processes. - - - - - - Fix logging collector to not lose log coherency under high load (Andrew - Dunstan) - - - - The collector previously could fail to reassemble large messages if it - got too busy. - - - - - - Fix logging collector to ensure it will restart file rotation - after receiving SIGHUP (Tom Lane) - - - - - - Fix PL/pgSQL's GET DIAGNOSTICS command when the target - is the function's first variable (Tom Lane) - - - - - - Fix several performance problems in pg_dump when - the database contains many objects (Jeff Janes, Tom Lane) - - - - pg_dump could get very slow if the database contained - many schemas, or if many objects are in dependency loops, or if there - are many owned sequences. - - - - - - Fix contrib/dblink's dblink_exec() to not leak - temporary database connections upon error (Tom Lane) - - - - - - Update time zone data files to tzdata release 2012c - for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland - Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; - also historical corrections for Canada. - - - - - - - - - - Release 8.3.18 - - - Release date: - 2012-02-27 - - - - This release contains a variety of fixes from 8.3.17. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.18 - - - A dump/restore is not required for those running 8.3.X. - - - - However, if you are upgrading from a version earlier than 8.3.17, - see . - - - - - - Changes - - - - - - Require execute permission on the trigger function for - CREATE TRIGGER (Robert Haas) - - - - This missing check could allow another user to execute a trigger - function with forged input data, by installing it on a table he owns. - This is only of significance for trigger functions marked - SECURITY DEFINER, since otherwise trigger functions run - as the table owner anyway. (CVE-2012-0866) - - - - - - Convert newlines to spaces in names written in pg_dump - comments (Robert Haas) - - - - pg_dump was incautious about sanitizing object names - that are emitted within SQL comments in its output script. A name - containing a newline would at least render the script syntactically - incorrect. Maliciously crafted object names could present a SQL - injection risk when the script is reloaded. (CVE-2012-0868) - - - - - - Fix btree index corruption from insertions concurrent with vacuuming - (Tom Lane) - - - - An index page split caused by an insertion could sometimes cause a - concurrently-running VACUUM to miss removing index entries - that it should remove. After the corresponding table rows are removed, - the dangling index entries would cause errors (such as could not - read block N in file ...) or worse, silently wrong query results - after unrelated rows are re-inserted at the now-free table locations. - This bug has been present since release 8.2, but occurs so infrequently - that it was not diagnosed until now. If you have reason to suspect - that it has happened in your database, reindexing the affected index - will fix things. - - - - - - Allow non-existent values for some settings in ALTER - USER/DATABASE SET (Heikki Linnakangas) - - - - Allow default_text_search_config, - default_tablespace, and temp_tablespaces to be - set to names that are not known. This is because they might be known - in another database where the setting is intended to be used, or for the - tablespace cases because the tablespace might not be created yet. The - same issue was previously recognized for search_path, and - these settings now act like that one. - - - - - - Track the OID counter correctly during WAL replay, even when it wraps - around (Tom Lane) - - - - Previously the OID counter would remain stuck at a high value until the - system exited replay mode. The practical consequences of that are - usually nil, but there are scenarios wherein a standby server that's - been promoted to master might take a long time to advance the OID - counter to a reasonable value once values are needed. - - - - - - Fix regular expression back-references with * attached - (Tom Lane) - - - - Rather than enforcing an exact string match, the code would effectively - accept any string that satisfies the pattern sub-expression referenced - by the back-reference symbol. - - - - A similar problem still afflicts back-references that are embedded in a - larger quantified expression, rather than being the immediate subject - of the quantifier. This will be addressed in a future - PostgreSQL release. - - - - - - Fix recently-introduced memory leak in processing of - inet/cidr values (Heikki Linnakangas) - - - - A patch in the December 2011 releases of PostgreSQL - caused memory leakage in these operations, which could be significant - in scenarios such as building a btree index on such a column. - - - - - - Avoid double close of file handle in syslogger on Windows (MauMau) - - - - Ordinarily this error was invisible, but it would cause an exception - when running on a debug version of Windows. - - - - - - Fix I/O-conversion-related memory leaks in plpgsql - (Andres Freund, Jan Urbanski, Tom Lane) - - - - Certain operations would leak memory until the end of the current - function. - - - - - - Improve pg_dump's handling of inherited table columns - (Tom Lane) - - - - pg_dump mishandled situations where a child column has - a different default expression than its parent column. If the default - is textually identical to the parent's default, but not actually the - same (for instance, because of schema search path differences) it would - not be recognized as different, so that after dump and restore the - child would be allowed to inherit the parent's default. Child columns - that are NOT NULL where their parent is not could also be - restored subtly incorrectly. - - - - - - Fix pg_restore's direct-to-database mode for - INSERT-style table data (Tom Lane) - - - - Direct-to-database restores from archive files made with - or options fail when - using pg_restore from a release dated September or - December 2011, as a result of an oversight in a fix for another - problem. The archive file itself is not at fault, and text-mode - output is okay. - - - - - - Fix error in contrib/intarray's int[] & - int[] operator (Guillaume Lelarge) - - - - If the smallest integer the two input arrays have in common is 1, - and there are smaller values in either array, then 1 would be - incorrectly omitted from the result. - - - - - - Fix error detection in contrib/pgcrypto's - encrypt_iv() and decrypt_iv() - (Marko Kreen) - - - - These functions failed to report certain types of invalid-input errors, - and would instead return random garbage values for incorrect input. - - - - - - Fix one-byte buffer overrun in contrib/test_parser - (Paul Guyot) - - - - The code would try to read one more byte than it should, which would - crash in corner cases. - Since contrib/test_parser is only example code, this is - not a security issue in itself, but bad example code is still bad. - - - - - - Use __sync_lock_test_and_set() for spinlocks on ARM, if - available (Martin Pitt) - - - - This function replaces our previous use of the SWPB - instruction, which is deprecated and not available on ARMv6 and later. - Reports suggest that the old code doesn't fail in an obvious way on - recent ARM boards, but simply doesn't interlock concurrent accesses, - leading to bizarre failures in multiprocess operation. - - - - - - Use option when building with - gcc versions that accept it (Andrew Dunstan) - - - - This prevents assorted scenarios wherein recent versions of gcc will - produce creative results. - - - - - - Allow use of threaded Python on FreeBSD (Chris Rees) - - - - Our configure script previously believed that this combination wouldn't - work; but FreeBSD fixed the problem, so remove that error check. - - - - - - - - - - Release 8.3.17 - - - Release date: - 2011-12-05 - - - - This release contains a variety of fixes from 8.3.16. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.17 - - - A dump/restore is not required for those running 8.3.X. - - - - However, a longstanding error was discovered in the definition of the - information_schema.referential_constraints view. If you - rely on correct results from that view, you should replace its - definition as explained in the first changelog item below. - - - - Also, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Fix bugs in information_schema.referential_constraints view - (Tom Lane) - - - - This view was being insufficiently careful about matching the - foreign-key constraint to the depended-on primary or unique key - constraint. That could result in failure to show a foreign key - constraint at all, or showing it multiple times, or claiming that it - depends on a different constraint than the one it really does. - - - - Since the view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can (as a superuser) drop the - information_schema schema then re-create it by sourcing - SHAREDIR/information_schema.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) This must be repeated in each database - to be fixed. - - - - - - Fix TOAST-related data corruption during CREATE TABLE dest AS - SELECT * FROM src or INSERT INTO dest SELECT * FROM src - (Tom Lane) - - - - If a table has been modified by ALTER TABLE ADD COLUMN, - attempts to copy its data verbatim to another table could produce - corrupt results in certain corner cases. - The problem can only manifest in this precise form in 8.4 and later, - but we patched earlier versions as well in case there are other code - paths that could trigger the same bug. - - - - - - Fix race condition during toast table access from stale syscache entries - (Tom Lane) - - - - The typical symptom was transient errors like missing chunk - number 0 for toast value NNNNN in pg_toast_2619, where the cited - toast table would always belong to a system catalog. - - - - - - Make DatumGetInetP() unpack inet datums that have a 1-byte - header, and add a new macro, DatumGetInetPP(), that does - not (Heikki Linnakangas) - - - - This change affects no core code, but might prevent crashes in add-on - code that expects DatumGetInetP() to produce an unpacked - datum as per usual convention. - - - - - - Improve locale support in money type's input and output - (Tom Lane) - - - - Aside from not supporting all standard - lc_monetary - formatting options, the input and output functions were inconsistent, - meaning there were locales in which dumped money values could - not be re-read. - - - - - - Don't let transform_null_equals - affect CASE foo WHEN NULL ... constructs - (Heikki Linnakangas) - - - - transform_null_equals is only supposed to affect - foo = NULL expressions written directly by the user, not - equality checks generated internally by this form of CASE. - - - - - - Change foreign-key trigger creation order to better support - self-referential foreign keys (Tom Lane) - - - - For a cascading foreign key that references its own table, a row update - will fire both the ON UPDATE trigger and the - CHECK trigger as one event. The ON UPDATE - trigger must execute first, else the CHECK will check a - non-final state of the row and possibly throw an inappropriate error. - However, the firing order of these triggers is determined by their - names, which generally sort in creation order since the triggers have - auto-generated names following the convention - RI_ConstraintTrigger_NNNN. A proper fix would require - modifying that convention, which we will do in 9.2, but it seems risky - to change it in existing releases. So this patch just changes the - creation order of the triggers. Users encountering this type of error - should drop and re-create the foreign key constraint to get its - triggers into the right order. - - - - - - Avoid floating-point underflow while tracking buffer allocation rate - (Greg Matthews) - - - - While harmless in itself, on certain platforms this would result in - annoying kernel log messages. - - - - - - Preserve blank lines within commands in psql's command - history (Robert Haas) - - - - The former behavior could cause problems if an empty line was removed - from within a string literal, for example. - - - - - - Fix pg_dump to dump user-defined casts between - auto-generated types, such as table rowtypes (Tom Lane) - - - - - - Use the preferred version of xsubpp to build PL/Perl, - not necessarily the operating system's main copy - (David Wheeler and Alex Hunsaker) - - - - - - Fix incorrect coding in contrib/dict_int and - contrib/dict_xsyn (Tom Lane) - - - - Some functions incorrectly assumed that memory returned by - palloc() is guaranteed zeroed. - - - - - - Honor query cancel interrupts promptly in pgstatindex() - (Robert Haas) - - - - - - Ensure VPATH builds properly install all server header files - (Peter Eisentraut) - - - - - - Shorten file names reported in verbose error messages (Peter Eisentraut) - - - - Regular builds have always reported just the name of the C file - containing the error message call, but VPATH builds formerly - reported an absolute path name. - - - - - - Fix interpretation of Windows timezone names for Central America - (Tom Lane) - - - - Map Central America Standard Time to CST6, not - CST6CDT, because DST is generally not observed anywhere in - Central America. - - - - - - Update time zone data files to tzdata release 2011n - for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa; - also historical corrections for Alaska and British East Africa. - - - - - - - - - - Release 8.3.16 - - - Release date: - 2011-09-26 - - - - This release contains a variety of fixes from 8.3.15. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.16 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane) - - - - These bugs could result in index corruption after reindexing a system - catalog. They are not believed to affect user indexes. - - - - - - Fix multiple bugs in GiST index page split processing (Heikki - Linnakangas) - - - - The probability of occurrence was low, but these could lead to index - corruption. - - - - - - Fix possible buffer overrun in tsvector_concat() - (Tom Lane) - - - - The function could underestimate the amount of memory needed for its - result, leading to server crashes. - - - - - - Fix crash in xml_recv when processing a - standalone parameter (Tom Lane) - - - - - - Avoid possibly accessing off the end of memory in ANALYZE - and in SJIS-2004 encoding conversion (Noah Misch) - - - - This fixes some very-low-probability server crash scenarios. - - - - - - Fix race condition in relcache init file invalidation (Tom Lane) - - - - There was a window wherein a new backend process could read a stale init - file but miss the inval messages that would tell it the data is stale. - The result would be bizarre failures in catalog accesses, typically - could not read block 0 in file ... later during startup. - - - - - - Fix memory leak at end of a GiST index scan (Tom Lane) - - - - Commands that perform many separate GiST index scans, such as - verification of a new GiST-based exclusion constraint on a table - already containing many rows, could transiently require large amounts of - memory due to this leak. - - - - - - Fix performance problem when constructing a large, lossy bitmap - (Tom Lane) - - - - - - Fix array- and path-creating functions to ensure padding bytes are - zeroes (Tom Lane) - - - - This avoids some situations where the planner will think that - semantically-equal constants are not equal, resulting in poor - optimization. - - - - - - Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane) - - - - This could lead to loss of committed transactions after a server crash. - - - - - - Fix dump bug for VALUES in a view (Tom Lane) - - - - - - Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane) - - - - This operation doesn't work as expected and can lead to failures. - - - - - - Defend against integer overflow when computing size of a hash table (Tom - Lane) - - - - - - Fix cases where CLUSTER might attempt to access - already-removed TOAST data (Tom Lane) - - - - - - Fix portability bugs in use of credentials control messages for - peer authentication (Tom Lane) - - - - - - Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, - Magnus Hagander) - - - - The typical symptom of this problem was The function requested is - not supported errors during SSPI login. - - - - - - Fix typo in pg_srand48 seed initialization (Andres Freund) - - - - This led to failure to use all bits of the provided seed. This function - is not used on most platforms (only those without srandom), - and the potential security exposure from a less-random-than-expected - seed seems minimal in any case. - - - - - - Avoid integer overflow when the sum of LIMIT and - OFFSET values exceeds 2^63 (Heikki Linnakangas) - - - - - - Add overflow checks to int4 and int8 versions of - generate_series() (Robert Haas) - - - - - - Fix trailing-zero removal in to_char() (Marti Raudsepp) - - - - In a format with FM and no digit positions - after the decimal point, zeroes to the left of the decimal point could - be removed incorrectly. - - - - - - Fix pg_size_pretty() to avoid overflow for inputs close to - 2^63 (Tom Lane) - - - - - - In pg_ctl, support silent mode for service registrations - on Windows (MauMau) - - - - - - Fix psql's counting of script file line numbers during - COPY from a different file (Tom Lane) - - - - - - Fix pg_restore's direct-to-database mode for - standard_conforming_strings (Tom Lane) - - - - pg_restore could emit incorrect commands when restoring - directly to a database server from an archive file that had been made - with standard_conforming_strings set to on. - - - - - - Fix write-past-buffer-end and memory leak in libpq's - LDAP service lookup code (Albe Laurenz) - - - - - - In libpq, avoid failures when using nonblocking I/O - and an SSL connection (Martin Pihlak, Tom Lane) - - - - - - Improve libpq's handling of failures during connection startup - (Tom Lane) - - - - In particular, the response to a server report of fork() - failure during SSL connection startup is now saner. - - - - - - Improve libpq's error reporting for SSL failures (Tom - Lane) - - - - - - Make ecpglib write double values with 15 digits - precision (Akira Kurosawa) - - - - - - In ecpglib, be sure LC_NUMERIC setting is - restored after an error (Michael Meskes) - - - - - - Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) - (Tom Lane) - - - - contrib/pg_crypto's blowfish encryption code could give - wrong results on platforms where char is signed (which is most), - leading to encrypted passwords being weaker than they should be. - - - - - - Fix memory leak in contrib/seg (Heikki Linnakangas) - - - - - - Fix pgstatindex() to give consistent results for empty - indexes (Tom Lane) - - - - - - Allow building with perl 5.14 (Alex Hunsaker) - - - - - - Update configure script's method for probing existence of system - functions (Tom Lane) - - - - The version of autoconf we used in 8.3 and 8.2 could be fooled by - compilers that perform link-time optimization. - - - - - - Fix assorted issues with build and install file paths containing spaces - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2011i - for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan. - - - - - - - - - - Release 8.3.15 - - - Release date: - 2011-04-18 - - - - This release contains a variety of fixes from 8.3.14. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.15 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Disallow including a composite type in itself (Tom Lane) - - - - This prevents scenarios wherein the server could recurse infinitely - while processing the composite type. While there are some possible - uses for such a structure, they don't seem compelling enough to - justify the effort required to make sure it always works safely. - - - - - - Avoid potential deadlock during catalog cache initialization - (Nikhil Sontakke) - - - - In some cases the cache loading code would acquire share lock on a - system index before locking the index's catalog. This could deadlock - against processes trying to acquire exclusive locks in the other, - more standard order. - - - - - - Fix dangling-pointer problem in BEFORE ROW UPDATE trigger - handling when there was a concurrent update to the target tuple - (Tom Lane) - - - - This bug has been observed to result in intermittent cannot - extract system attribute from virtual tuple failures while trying to - do UPDATE RETURNING ctid. There is a very small probability - of more serious errors, such as generating incorrect index entries for - the updated tuple. - - - - - - Disallow DROP TABLE when there are pending deferred trigger - events for the table (Tom Lane) - - - - Formerly the DROP would go through, leading to - could not open relation with OID nnn errors when the - triggers were eventually fired. - - - - - - Fix PL/Python memory leak involving array slices (Daniel Popowich) - - - - - - Fix pg_restore to cope with long lines (over 1KB) in - TOC files (Tom Lane) - - - - - - Put in more safeguards against crashing due to division-by-zero - with overly enthusiastic compiler optimization (Aurelien Jarno) - - - - - - Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane) - - - - There was a hard-wired assumption that this system function was not - available on MIPS hardware on these systems. Use a compile-time test - instead, since more recent versions have it. - - - - - - Fix compilation failures on HP-UX (Heikki Linnakangas) - - - - - - Fix version-incompatibility problem with libintl on - Windows (Hiroshi Inoue) - - - - - - Fix usage of xcopy in Windows build scripts to - work correctly under Windows 7 (Andrew Dunstan) - - - - This affects the build scripts only, not installation or usage. - - - - - - Fix path separator used by pg_regress on Cygwin - (Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2011f - for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa, - and Turkey; also historical corrections for South Australia, Alaska, - and Hawaii. - - - - - - - - - - Release 8.3.14 - - - Release date: - 2011-01-31 - - - - This release contains a variety of fixes from 8.3.13. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.14 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Avoid failures when EXPLAIN tries to display a simple-form - CASE expression (Tom Lane) - - - - If the CASE's test expression was a constant, the planner - could simplify the CASE into a form that confused the - expression-display code, resulting in unexpected CASE WHEN - clause errors. - - - - - - Fix assignment to an array slice that is before the existing range - of subscripts (Tom Lane) - - - - If there was a gap between the newly added subscripts and the first - pre-existing subscript, the code miscalculated how many entries needed - to be copied from the old array's null bitmap, potentially leading to - data corruption or crash. - - - - - - Avoid unexpected conversion overflow in planner for very distant date - values (Tom Lane) - - - - The date type supports a wider range of dates than can be - represented by the timestamp types, but the planner assumed it - could always convert a date to timestamp with impunity. - - - - - - Fix pg_restore's text output for large objects (BLOBs) - when standard_conforming_strings is on (Tom Lane) - - - - Although restoring directly to a database worked correctly, string - escaping was incorrect if pg_restore was asked for - SQL text output and standard_conforming_strings had been - enabled in the source database. - - - - - - Fix erroneous parsing of tsquery values containing - ... & !(subexpression) | ... (Tom Lane) - - - - Queries containing this combination of operators were not executed - correctly. The same error existed in contrib/intarray's - query_int type and contrib/ltree's - ltxtquery type. - - - - - - Fix buffer overrun in contrib/intarray's input function - for the query_int type (Apple) - - - - This bug is a security risk since the function's return address could - be overwritten. Thanks to Apple Inc's security team for reporting this - issue and supplying the fix. (CVE-2010-4015) - - - - - - Fix bug in contrib/seg's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a seg column. - If you have such an index, consider REINDEXing it after - installing this update. (This is identical to the bug that was fixed in - contrib/cube in the previous update.) - - - - - - - - - - Release 8.3.13 - - - Release date: - 2010-12-16 - - - - This release contains a variety of fixes from 8.3.12. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.13 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Force the default - wal_sync_method - to be fdatasync on Linux (Tom Lane, Marti Raudsepp) - - - - The default on Linux has actually been fdatasync for many - years, but recent kernel changes caused PostgreSQL to - choose open_datasync instead. This choice did not result - in any performance improvement, and caused outright failures on - certain filesystems, notably ext4 with the - data=journal mount option. - - - - - - Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane) - - - - This could result in bad buffer id: 0 failures or - corruption of index contents during replication. - - - - - - Fix recovery from base backup when the starting checkpoint WAL record - is not in the same WAL segment as its redo point (Jeff Davis) - - - - - - Fix persistent slowdown of autovacuum workers when multiple workers - remain active for a long time (Tom Lane) - - - - The effective vacuum_cost_limit for an autovacuum worker - could drop to nearly zero if it processed enough tables, causing it - to run extremely slowly. - - - - - - Add support for detecting register-stack overrun on IA64 - (Tom Lane) - - - - The IA64 architecture has two hardware stacks. Full - prevention of stack-overrun failures requires checking both. - - - - - - Add a check for stack overflow in copyObject() (Tom Lane) - - - - Certain code paths could crash due to stack overflow given a - sufficiently complex query. - - - - - - Fix detection of page splits in temporary GiST indexes (Heikki - Linnakangas) - - - - It is possible to have a concurrent page split in a - temporary index, if for example there is an open cursor scanning the - index when an insertion is done. GiST failed to detect this case and - hence could deliver wrong results when execution of the cursor - continued. - - - - - - Avoid memory leakage while ANALYZE'ing complex index - expressions (Tom Lane) - - - - - - Ensure an index that uses a whole-row Var still depends on its table - (Tom Lane) - - - - An index declared like create index i on t (foo(t.*)) - would not automatically get dropped when its table was dropped. - - - - - - Do not inline a SQL function with multiple OUT - parameters (Tom Lane) - - - - This avoids a possible crash due to loss of information about the - expected result rowtype. - - - - - - Behave correctly if ORDER BY, LIMIT, - FOR UPDATE, or WITH is attached to the - VALUES part of INSERT ... VALUES (Tom Lane) - - - - - - Fix constant-folding of COALESCE() expressions (Tom Lane) - - - - The planner would sometimes attempt to evaluate sub-expressions that - in fact could never be reached, possibly leading to unexpected errors. - - - - - - Fix postmaster crash when connection acceptance - (accept() or one of the calls made immediately after it) - fails, and the postmaster was compiled with GSSAPI support (Alexander - Chernikov) - - - - - - Fix missed unlink of temporary files when log_temp_files - is active (Tom Lane) - - - - If an error occurred while attempting to emit the log message, the - unlink was not done, resulting in accumulation of temp files. - - - - - - Add print functionality for InhRelation nodes (Tom Lane) - - - - This avoids a failure when debug_print_parse is enabled - and certain types of query are executed. - - - - - - Fix incorrect calculation of distance from a point to a horizontal - line segment (Tom Lane) - - - - This bug affected several different geometric distance-measurement - operators. - - - - - - Fix PL/pgSQL's handling of simple - expressions to not fail in recursion or error-recovery cases (Tom Lane) - - - - - - Fix PL/Python's handling of set-returning functions - (Jan Urbanski) - - - - Attempts to call SPI functions within the iterator generating a set - result would fail. - - - - - - Fix bug in contrib/cube's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a cube column. - If you have such an index, consider REINDEXing it after - installing this update. - - - - - - Don't emit identifier will be truncated notices in - contrib/dblink except when creating new connections - (Itagaki Takahiro) - - - - - - Fix potential coredump on missing public key in - contrib/pgcrypto (Marti Raudsepp) - - - - - - Fix memory leak in contrib/xml2's XPath query functions - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2010o - for DST law changes in Fiji and Samoa; - also historical corrections for Hong Kong. - - - - - - - - - - Release 8.3.12 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 8.3.11. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.12 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on - Windows (Magnus Hagander) - - - - Under high load, Windows processes will sometimes fail at startup with - this error code. Formerly the postmaster treated this as a panic - condition and restarted the whole database, but that seems to be - an overreaction. - - - - - - Fix incorrect usage of non-strict OR joinclauses in Append indexscans - (Tom Lane) - - - - This is a back-patch of an 8.4 fix that was missed in the 8.3 branch. - This corrects an error introduced in 8.3.8 that could cause incorrect - results for outer joins when the inner relation is an inheritance tree - or UNION ALL subquery. - - - - - - Fix possible duplicate scans of UNION ALL member relations - (Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Fix failure to mark cached plans as transient (Tom Lane) - - - - If a plan is prepared while CREATE INDEX CONCURRENTLY is - in progress for one of the referenced tables, it is supposed to be - re-planned once the index is ready for use. This was not happening - reliably. - - - - - - Reduce PANIC to ERROR in some occasionally-reported btree failure cases, - and provide additional detail in the resulting error messages - (Tom Lane) - - - - This should improve the system's robustness with corrupted indexes. - - - - - - Prevent show_session_authorization() from crashing within autovacuum - processes (Tom Lane) - - - - - - Defend against functions returning setof record where not all the - returned rows are actually of the same rowtype (Tom Lane) - - - - - - Fix possible failure when hashing a pass-by-reference function result - (Tao Ma, Tom Lane) - - - - - - Improve merge join's handling of NULLs in the join columns (Tom Lane) - - - - A merge join can now stop entirely upon reaching the first NULL, - if the sort order is such that NULLs sort high. - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Avoid recursion while assigning XIDs to heavily-nested - subtransactions (Andres Freund, Robert Haas) - - - - The original coding could result in a crash if there was limited - stack space. - - - - - - Avoid holding open old WAL segments in the walwriter process - (Magnus Hagander, Heikki Linnakangas) - - - - The previous coding would prevent removal of no-longer-needed segments. - - - - - - Fix log_line_prefix's %i escape, - which could produce junk early in backend startup (Tom Lane) - - - - - - Fix possible data corruption in ALTER TABLE ... SET - TABLESPACE when archiving is enabled (Jeff Davis) - - - - - - Allow CREATE DATABASE and ALTER DATABASE ... SET - TABLESPACE to be interrupted by query-cancel (Guillaume Lelarge) - - - - - - Fix REASSIGN OWNED to handle operator classes and families - (Asko Tiidumaa) - - - - - - Fix possible core dump when comparing two empty tsquery values - (Tom Lane) - - - - - - Fix LIKE's handling of patterns containing % - followed by _ (Tom Lane) - - - - We've fixed this before, but there were still some incorrectly-handled - cases. - - - - - - In PL/Python, defend against null pointer results from - PyCObject_AsVoidPtr and PyCObject_FromVoidPtr - (Peter Eisentraut) - - - - - - Make psql recognize DISCARD ALL as a command that should - not be encased in a transaction block in autocommit-off mode - (Itagaki Takahiro) - - - - - - Fix ecpg to process data from RETURNING - clauses correctly (Michael Meskes) - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Fix contrib/dblink to handle connection names longer than - 62 bytes correctly (Itagaki Takahiro) - - - - - - Add hstore(text, text) - function to contrib/hstore (Robert Haas) - - - - This function is the recommended substitute for the now-deprecated - => operator. It was back-patched so that future-proofed - code can be used with older server versions. Note that the patch will - be effective only after contrib/hstore is installed or - reinstalled in a particular database. Users might prefer to execute - the CREATE FUNCTION command by hand, instead. - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - Update time zone data files to tzdata release 2010l - for DST law changes in Egypt and Palestine; also historical corrections - for Finland. - - - - This change also adds new names for two Micronesian timezones: - Pacific/Chuuk is now preferred over Pacific/Truk (and the preferred - abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over - Pacific/Ponape. - - - - - - Make Windows' N. Central Asia Standard Time timezone map to - Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander) - - - - Microsoft changed the DST behavior of this zone in the timezone update - from KB976098. Asia/Novosibirsk is a better match to its new behavior. - - - - - - - - - - Release 8.3.11 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 8.3.10. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.11 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Fix possible crash if a cache reset message is received during - rebuild of a relcache entry (Heikki) - - - - This error was introduced in 8.3.10 while fixing a related failure. - - - - - - Apply per-function GUC settings while running the language validator - for the function (Itagaki Takahiro) - - - - This avoids failures if the function's code is invalid without the - setting; an example is that SQL functions may not parse if the - search_path is not correct. - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Ensure the archiver process responds to changes in - archive_command as soon as possible (Tom) - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Prevent infinite recursion in psql when expanding - a variable that refers to itself (Tom) - - - - - - Fix psql's \copy to not add spaces around - a dot within \copy (select ...) (Tom) - - - - Addition of spaces around the decimal point in a numeric literal would - result in a syntax error. - - - - - - Fix unnecessary GIN indexes do not support whole-index scans - errors for unsatisfiable queries using contrib/intarray - operators (Tom) - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - Avoid possible crashes in syslogger process on Windows (Heikki) - - - - - - Deal more robustly with incomplete time zone information in the - Windows registry (Magnus) - - - - - - Update the set of known Windows time zone names (Magnus) - - - - - - Update time zone data files to tzdata release 2010j - for DST law changes in Argentina, Australian Antarctic, Bangladesh, - Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; - also historical corrections for Taiwan. - - - - Also, add PKST (Pakistan Summer Time) to the default set of - timezone abbreviations. - - - - - - - - - - Release 8.3.10 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 8.3.9. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.10 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Fix possible deadlock during backend startup (Tom) - - - - - - Fix possible crashes due to not handling errors during relcache reload - cleanly (Tom) - - - - - - Fix possible crash due to use of dangling pointer to a cached plan - (Tatsuo) - - - - - - Fix possible crashes when trying to recover from a failure in - subtransaction start (Tom) - - - - - - Fix server memory leak associated with use of savepoints and a client - encoding different from server's encoding (Tom) - - - - - - Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST - index page split (Yoichi Hirai) - - - - This would result in index corruption, or even more likely an error - during WAL replay, if we were unlucky enough to crash during - end-of-recovery cleanup after having completed an incomplete GIST - insertion. - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix integer-to-bit-string conversions to handle the first fractional - byte correctly when the output bit width is wider than the given - integer by something other than a multiple of 8 bits (Tom) - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - Fix assorted crashes in xml processing caused by sloppy - memory management (Tom) - - - - This is a back-patch of changes first applied in 8.4. The 8.3 code - was known buggy, but the new code was sufficiently different to not - want to back-patch it until it had gotten some field testing. - - - - - - Fix bug with trying to update a field of an element of a - composite-type array column (Tom) - - - - - - Fix the STOP WAL LOCATION entry in backup history files to - report the next WAL segment's name when the end location is exactly at a - segment boundary (Itagaki Takahiro) - - - - - - Fix some more cases of temporary-file leakage (Heikki) - - - - This corrects a problem introduced in the previous minor release. - One case that failed is when a plpgsql function returning set is - called within another function's exception handler. - - - - - - Improve constraint exclusion processing of boolean-variable cases, - in particular make it possible to exclude a partition that has a - bool_column = false constraint (Tom) - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Fix possible infinite loop if SSL_read or - SSL_write fails without setting errno (Tom) - - - - This is reportedly possible with some Windows versions of - openssl. - - - - - - Disallow GSSAPI authentication on local connections, - since it requires a hostname to function correctly (Magnus) - - - - - - Make ecpg report the proper SQLSTATE if the connection - disappears (Michael) - - - - - - Fix psql's numericlocale option to not - format strings it shouldn't in latex and troff output formats (Heikki) - - - - - - Make psql return the correct exit status (3) when - ON_ERROR_STOP and --single-transaction are - both specified and an error occurs during the implied COMMIT - (Bruce) - - - - - - Fix plpgsql failure in one case where a composite column is set to NULL - (Tom) - - - - - - Fix possible failure when calling PL/Perl functions from PL/PerlU - or vice versa (Tim Bunce) - - - - - - Add volatile markings in PL/Python to avoid possible - compiler-specific misbehavior (Zdenek Kotala) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - Allow zero-dimensional arrays in contrib/ltree operations - (Tom) - - - - This case was formerly rejected as an error, but it's more convenient to - treat it the same as a zero-element array. In particular this avoids - unnecessary failures when an ltree operation is applied to the - result of ARRAY(SELECT ...) and the sub-select returns no - rows. - - - - - - Fix assorted crashes in contrib/xml2 caused by sloppy - memory management (Tom) - - - - - - Make building of contrib/xml2 more robust on Windows - (Andrew) - - - - - - Fix race condition in Windows signal handling (Radu Ilie) - - - - One known symptom of this bug is that rows in pg_listener - could be dropped under heavy load. - - - - - - Update time zone data files to tzdata release 2010e - for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa. - - - - - - - - - - Release 8.3.9 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 8.3.8. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.9 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.8, - see . - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Avoid crash on empty thesaurus dictionary (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Ensure that shared tuple-level locks held by prepared transactions are - not ignored (Heikki) - - - - - - Fix premature drop of temporary files used for a cursor that is accessed - within a subtransaction (Heikki) - - - - - - Fix memory leak in syslogger process when rotating to a new CSV logfile - (Tom) - - - - - - Fix Windows permission-downgrade logic (Jesse Morris) - - - - This fixes some cases where the database failed to start on Windows, - often with misleading error messages such as could not locate - matching postgres executable. - - - - - - Fix incorrect logic for GiST index page splits, when the split depends - on a non-first column of the index (Paul Ramsey) - - - - - - Don't error out if recycling or removing an old WAL file fails at the - end of checkpoint (Heikki) - - - - It's better to treat the problem as non-fatal and allow the checkpoint - to complete. Future checkpoints will retry the removal. Such problems - are not expected in normal operation, but have been seen to be - caused by misdesigned Windows anti-virus and backup software. - - - - - - Ensure WAL files aren't repeatedly archived on Windows (Heikki) - - - - This is another symptom that could happen if some other process - interfered with deletion of a no-longer-needed file. - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Raise the maximum authentication token (Kerberos ticket) size in GSSAPI - and SSPI authentication methods (Ian Turner) - - - - While the old 2000-byte limit was more than enough for Unix Kerberos - implementations, tickets issued by Windows Domain Controllers can be - much larger. - - - - - - Re-enable collection of access statistics for sequences (Akira Kurosawa) - - - - This used to work but was broken in 8.3. - - - - - - Fix processing of ownership dependencies during CREATE OR - REPLACE FUNCTION (Tom) - - - - - - Fix incorrect handling of WHERE - x=x conditions (Tom) - - - - In some cases these could get ignored as redundant, but they aren't - — they're equivalent to x IS NOT NULL. - - - - - - Make text search parser accept underscores in XML attributes (Peter) - - - - - - Fix encoding handling in xml binary input (Heikki) - - - - If the XML header doesn't specify an encoding, we now assume UTF-8 by - default; the previous handling was inconsistent. - - - - - - Fix bug with calling plperl from plperlu or vice - versa (Tom) - - - - An error exit from the inner function could result in crashes due to - failure to re-select the correct Perl interpreter for the outer function. - - - - - - Fix session-lifespan memory leak when a PL/Perl function is redefined - (Tom) - - - - - - Ensure that Perl arrays are properly converted to - PostgreSQL arrays when returned by a set-returning - PL/Perl function (Andrew Dunstan, Abhijit Menon-Sen) - - - - This worked correctly already for non-set-returning functions. - - - - - - Fix rare crash in exception processing in PL/Python (Peter) - - - - - - In contrib/pg_standby, disable triggering failover with a - signal on Windows (Fujii Masao) - - - - This never did anything useful, because Windows doesn't have Unix-style - signals, but recent changes made it actually crash. - - - - - - Ensure psql's flex module is compiled with the correct - system header definitions (Tom) - - - - This fixes build failures on platforms where - --enable-largefile causes incompatible changes in the - generated code. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - Update the timezone abbreviation files to match current reality (Joachim - Wieland) - - - - This includes adding IDT and SGT to the default - timezone abbreviation set. - - - - - - Update time zone data files to tzdata release 2009s - for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, - Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical - corrections for Hong Kong. - - - - - - - - - - Release 8.3.8 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 8.3.7. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.8 - - - A dump/restore is not required for those running 8.3.X. - However, if you have any hash indexes on interval columns, - you must REINDEX them after updating to 8.3.8. - Also, if you are upgrading from a version earlier than 8.3.5, - see . - - - - - - Changes - - - - - - Fix Windows shared-memory allocation code (Tsutomu Yamada, Magnus) - - - - This bug led to the often-reported could not reattach - to shared memory error message. - - - - - - Force WAL segment switch during pg_start_backup() - (Heikki) - - - - This avoids corner cases that could render a base backup unusable. - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Make LOAD of an already-loaded loadable module - into a no-op (Tom) - - - - Formerly, LOAD would attempt to unload and re-load the - module, but this is unsafe and not all that useful. - - - - - - Disallow empty passwords during LDAP authentication (Magnus) - - - - - - Fix handling of sub-SELECTs appearing in the arguments of - an outer-level aggregate function (Tom) - - - - - - Fix bugs associated with fetching a whole-row value from the - output of a Sort or Materialize plan node (Tom) - - - - - - Prevent synchronize_seqscans from changing the results of - scrollable and WITH HOLD cursors (Tom) - - - - - - Revert planner change that disabled partial-index and constraint - exclusion optimizations when there were more than 100 clauses in - an AND or OR list (Tom) - - - - - - Fix hash calculation for data type interval (Tom) - - - - This corrects wrong results for hash joins on interval values. - It also changes the contents of hash indexes on interval columns. - If you have any such indexes, you must REINDEX them - after updating. - - - - - - Treat to_char(..., 'TH') as an uppercase ordinal - suffix with 'HH'/'HH12' (Heikki) - - - - It was previously handled as 'th' (lowercase). - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Fix calculation of distance between a point and a line segment (Tom) - - - - This led to incorrect results from a number of geometric operators. - - - - - - Fix money data type to work in locales where currency - amounts have no fractional digits, e.g. Japan (Itagaki Takahiro) - - - - - - Fix LIKE for case where pattern contains %_ - (Tom) - - - - - - Properly round datetime input like - 00:12:57.9999999999999999999999999999 (Tom) - - - - - - Fix memory leaks in XML operations (Tom) - - - - - - Fix poor choice of page split point in GiST R-tree operator classes - (Teodor) - - - - - - Ensure that a fast shutdown request will forcibly terminate - open sessions, even if a smart shutdown was already in progress - (Fujii Masao) - - - - - - Avoid performance degradation in bulk inserts into GIN indexes - when the input values are (nearly) in sorted order (Tom) - - - - - - Correctly enforce NOT NULL domain constraints in some contexts in - PL/pgSQL (Tom) - - - - - - Fix portability issues in plperl initialization (Andrew Dunstan) - - - - - - Fix pg_ctl to not go into an infinite loop if - postgresql.conf is empty (Jeff Davis) - - - - - - Improve pg_dump's efficiency when there are - many large objects (Tamas Vincze) - - - - - - Use SIGUSR1, not SIGQUIT, as the - failover signal for pg_standby (Heikki) - - - - - - Make pg_standby's maxretries option - behave as documented (Fujii Masao) - - - - - - Make contrib/hstore throw an error when a key or - value is too long to fit in its data structure, rather than - silently truncating it (Andrew Gierth) - - - - - - Fix contrib/xml2's xslt_process() to - properly handle the maximum number of parameters (twenty) (Tom) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - Update time zone data files to tzdata release 2009l - for DST law changes in Bangladesh, Egypt, Jordan, Pakistan, - Argentina/San_Luis, Cuba, Jordan (historical correction only), - Mauritius, Morocco, Palestine, Syria, Tunisia. - - - - - - - - - - Release 8.3.7 - - - Release date: - 2009-03-16 - - - - This release contains a variety of fixes from 8.3.6. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.7 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.5, - see . - - - - - - Changes - - - - - - Prevent error recursion crashes when encoding conversion fails (Tom) - - - - This change extends fixes made in the last two minor releases for - related failure scenarios. The previous fixes were narrowly tailored - for the original problem reports, but we have now recognized that - any error thrown by an encoding conversion function could - potentially lead to infinite recursion while trying to report the - error. The solution therefore is to disable translation and encoding - conversion and report the plain-ASCII form of any error message, - if we find we have gotten into a recursive error reporting situation. - (CVE-2009-0922) - - - - - - Disallow CREATE CONVERSION with the wrong encodings - for the specified conversion function (Heikki) - - - - This prevents one possible scenario for encoding conversion failure. - The previous change is a backstop to guard against other kinds of - failures in the same area. - - - - - - Fix xpath() to not modify the path expression unless - necessary, and to make a saner attempt at it when necessary (Andrew) - - - - The SQL standard suggests that xpath should work on data - that is a document fragment, but libxml doesn't support - that, and indeed it's not clear that this is sensible according to the - XPath standard. xpath attempted to work around this - mismatch by modifying both the data and the path expression, but the - modification was buggy and could cause valid searches to fail. Now, - xpath checks whether the data is in fact a well-formed - document, and if so invokes libxml with no change to the - data or path expression. Otherwise, a different modification method - that is somewhat less likely to fail is used. - - - - - The new modification method is still not 100% satisfactory, and it - seems likely that no real solution is possible. This patch should - therefore be viewed as a band-aid to keep from breaking existing - applications unnecessarily. It is likely that - PostgreSQL 8.4 will simply reject use of - xpath on data that is not a well-formed document. - - - - - - - Fix core dump when to_char() is given format codes that - are inappropriate for the type of the data argument (Tom) - - - - - - Fix possible failure in text search when C locale is used with - a multi-byte encoding (Teodor) - - - - Crashes were possible on platforms where wchar_t is narrower - than int; Windows in particular. - - - - - - Fix extreme inefficiency in text search parser's handling of an - email-like string containing multiple @ characters (Heikki) - - - - - - Fix planner problem with sub-SELECT in the output list - of a larger subquery (Tom) - - - - The known symptom of this bug is a failed to locate grouping - columns error that is dependent on the datatype involved; - but there could be other issues as well. - - - - - - Fix decompilation of CASE WHEN with an implicit coercion - (Tom) - - - - This mistake could lead to Assert failures in an Assert-enabled build, - or an unexpected CASE WHEN clause error message in other - cases, when trying to examine or dump a view. - - - - - - Fix possible misassignment of the owner of a TOAST table's rowtype (Tom) - - - - If CLUSTER or a rewriting variant of ALTER TABLE - were executed by someone other than the table owner, the - pg_type entry for the table's TOAST table would end up - marked as owned by that someone. This caused no immediate problems, - since the permissions on the TOAST rowtype aren't examined by any - ordinary database operation. However, it could lead to unexpected - failures if one later tried to drop the role that issued the command - (in 8.1 or 8.2), or owner of data type appears to be invalid - warnings from pg_dump after having done so (in 8.3). - - - - - - Change UNLISTEN to exit quickly if the current session has - never executed any LISTEN command (Tom) - - - - Most of the time this is not a particularly useful optimization, but - since DISCARD ALL invokes UNLISTEN, the previous - coding caused a substantial performance problem for applications that - made heavy use of DISCARD ALL. - - - - - - Fix PL/pgSQL to not treat INTO after INSERT as - an INTO-variables clause anywhere in the string, not only at the start; - in particular, don't fail for INSERT INTO within - CREATE RULE (Tom) - - - - - - Clean up PL/pgSQL error status variables fully at block exit - (Ashesh Vashi and Dave Page) - - - - This is not a problem for PL/pgSQL itself, but the omission could cause - the PL/pgSQL Debugger to crash while examining the state of a function. - - - - - - Retry failed calls to CallNamedPipe() on Windows - (Steve Marshall, Magnus) - - - - It appears that this function can sometimes fail transiently; - we previously treated any failure as a hard error, which could - confuse LISTEN/NOTIFY as well as other - operations. - - - - - - Add MUST (Mauritius Island Summer Time) to the default list - of known timezone abbreviations (Xavier Bugaud) - - - - - - - - - - Release 8.3.6 - - - Release date: - 2009-02-02 - - - - This release contains a variety of fixes from 8.3.5. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.6 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.5, - see . - - - - - - Changes - - - - - - Make DISCARD ALL release advisory locks, in addition - to everything it already did (Tom) - - - - This was decided to be the most appropriate behavior. This could - affect existing applications, however. - - - - - - Fix whole-index GiST scans to work correctly (Teodor) - - - - This error could cause rows to be lost if a table is clustered - on a GiST index. - - - - - - Fix crash of xmlconcat(NULL) (Peter) - - - - - - Fix possible crash in ispell dictionary if high-bit-set - characters are used as flags (Teodor) - - - - This is known to be done by one widely available Norwegian dictionary, - and the same condition may exist in others. - - - - - - Fix misordering of pg_dump output for composite types - (Tom) - - - - The most likely problem was for user-defined operator classes to - be dumped after indexes or views that needed them. - - - - - - Improve handling of URLs in headline() function (Teodor) - - - - - - Improve handling of overlength headlines in headline() - function (Teodor) - - - - - - Prevent possible Assert failure or misconversion if an encoding - conversion is created with the wrong conversion function for the - specified pair of encodings (Tom, Heikki) - - - - - - Fix possible Assert failure if a statement executed in PL/pgSQL is - rewritten into another kind of statement, for example if an - INSERT is rewritten into an UPDATE (Heikki) - - - - - - Ensure that a snapshot is available to datatype input functions (Tom) - - - - This primarily affects domains that are declared with CHECK - constraints involving user-defined stable or immutable functions. Such - functions typically fail if no snapshot has been set. - - - - - - Make it safer for SPI-using functions to be used within datatype I/O; - in particular, to be used in domain check constraints (Tom) - - - - - - Avoid unnecessary locking of small tables in VACUUM - (Heikki) - - - - - - Fix a problem that sometimes kept ALTER TABLE ENABLE/DISABLE - RULE from being recognized by active sessions (Tom) - - - - - - Fix a problem that made UPDATE RETURNING tableoid - return zero instead of the correct OID (Tom) - - - - - - Allow functions declared as taking ANYARRAY to work on - the pg_statistic columns of that type (Tom) - - - - This used to work, but was unintentionally broken in 8.3. - - - - - - Fix planner misestimation of selectivity when transitive equality - is applied to an outer-join clause (Tom) - - - - This could result in bad plans for queries like - ... from a left join b on a.a1 = b.b1 where a.a1 = 42 ... - - - - - - Improve optimizer's handling of long IN lists (Tom) - - - - This change avoids wasting large amounts of time on such lists - when constraint exclusion is enabled. - - - - - - Prevent synchronous scan during GIN index build (Tom) - - - - Because GIN is optimized for inserting tuples in increasing TID order, - choosing to use a synchronous scan could slow the build by a factor of - three or more. - - - - - - Ensure that the contents of a holdable cursor don't depend on the - contents of TOAST tables (Tom) - - - - Previously, large field values in a cursor result might be represented - as TOAST pointers, which would fail if the referenced table got dropped - before the cursor is read, or if the large value is deleted and then - vacuumed away. This cannot happen with an ordinary cursor, - but it could with a cursor that is held past its creating transaction. - - - - - - Fix memory leak when a set-returning function is terminated without - reading its whole result (Tom) - - - - - - Fix encoding conversion problems in XML functions when the database - encoding isn't UTF-8 (Tom) - - - - - - Fix contrib/dblink's - dblink_get_result(text,bool) function (Joe) - - - - - - Fix possible garbage output from contrib/sslinfo functions - (Tom) - - - - - - Fix incorrect behavior of contrib/tsearch2 compatibility - trigger when it's fired more than once in a command (Teodor) - - - - - - Fix possible mis-signaling in autovacuum (Heikki) - - - - - - Support running as a service on Windows 7 beta (Dave and Magnus) - - - - - - Fix ecpg's handling of varchar structs (Michael) - - - - - - Fix configure script to properly report failure when - unable to obtain linkage information for PL/Perl (Andrew) - - - - - - Make all documentation reference pgsql-bugs and/or - pgsql-hackers as appropriate, instead of the - now-decommissioned pgsql-ports and pgsql-patches - mailing lists (Tom) - - - - - - Update time zone data files to tzdata release 2009a (for - Kathmandu and historical DST corrections in Switzerland, Cuba) - - - - - - - - - - Release 8.3.5 - - - Release date: - 2008-11-03 - - - - This release contains a variety of fixes from 8.3.4. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.5 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.1, - see . Also, if you were running a previous - 8.3.X release, it is recommended to REINDEX all GiST - indexes after the upgrade. - - - - - - Changes - - - - - - Fix GiST index corruption due to marking the wrong index entry - dead after a deletion (Teodor) - - - - This would result in index searches failing to find rows they - should have found. Corrupted indexes can be fixed with - REINDEX. - - - - - - Fix backend crash when the client encoding cannot represent a localized - error message (Tom) - - - - We have addressed similar issues before, but it would still fail if - the character has no equivalent message itself couldn't - be converted. The fix is to disable localization and send the plain - ASCII error message when we detect such a situation. - - - - - - Fix possible crash in bytea-to-XML mapping (Michael McMaster) - - - - - - Fix possible crash when deeply nested functions are invoked from - a trigger (Tom) - - - - - - Improve optimization of expression IN - (expression-list) queries (Tom, per an idea from Robert - Haas) - - - - Cases in which there are query variables on the right-hand side had been - handled less efficiently in 8.2.x and 8.3.x than in prior versions. - The fix restores 8.1 behavior for such cases. - - - - - - Fix mis-expansion of rule queries when a sub-SELECT appears - in a function call in FROM, a multi-row VALUES - list, or a RETURNING list (Tom) - - - - The usual symptom of this problem is an unrecognized node type - error. - - - - - - Fix Assert failure during rescan of an IS NULL - search of a GiST index (Teodor) - - - - - - Fix memory leak during rescan of a hashed aggregation plan (Neil) - - - - - - Ensure an error is reported when a newly-defined PL/pgSQL trigger - function is invoked as a normal function (Tom) - - - - - - Force a checkpoint before CREATE DATABASE starts to copy - files (Heikki) - - - - This prevents a possible failure if files had recently been deleted - in the source database. - - - - - - Prevent possible collision of relfilenode numbers - when moving a table to another tablespace with ALTER SET - TABLESPACE (Heikki) - - - - The command tried to re-use the existing filename, instead of - picking one that is known unused in the destination directory. - - - - - - Fix incorrect text search headline generation when single query - item matches first word of text (Sushant Sinha) - - - - - - Fix improper display of fractional seconds in interval values when - using a non-ISO datestyle in an - build (Ron Mayer) - - - - - - Make ILIKE compare characters case-insensitively - even when they're escaped (Andrew) - - - - - - Ensure DISCARD is handled properly by statement logging (Tom) - - - - - - Fix incorrect logging of last-completed-transaction time during - PITR recovery (Tom) - - - - - - Ensure SPI_getvalue and SPI_getbinval - behave correctly when the passed tuple and tuple descriptor have - different numbers of columns (Tom) - - - - This situation is normal when a table has had columns added or removed, - but these two functions didn't handle it properly. - The only likely consequence is an incorrect error indication. - - - - - - Mark SessionReplicationRole as PGDLLIMPORT - so it can be used by Slony on Windows (Magnus) - - - - - - Fix small memory leak when using libpq's - gsslib parameter (Magnus) - - - - The space used by the parameter string was not freed at connection - close. - - - - - - Ensure libgssapi is linked into libpq - if needed (Markus Schaaf) - - - - - - Fix ecpg's parsing of CREATE ROLE (Michael) - - - - - - Fix recent breakage of pg_ctl restart (Tom) - - - - - - Ensure pg_control is opened in binary mode - (Itagaki Takahiro) - - - - pg_controldata and pg_resetxlog - did this incorrectly, and so could fail on Windows. - - - - - - Update time zone data files to tzdata release 2008i (for - DST law changes in Argentina, Brazil, Mauritius, Syria) - - - - - - - - - - Release 8.3.4 - - - Release date: - 2008-09-22 - - - - This release contains a variety of fixes from 8.3.3. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.4 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.1, - see . - - - - - - Changes - - - - - - Fix bug in btree WAL recovery code (Heikki) - - - - Recovery failed if the WAL ended partway through a page split operation. - - - - - - Fix potential use of wrong cutoff XID for HOT page pruning (Alvaro) - - - - This error created a risk of corruption in system - catalogs that are consulted by VACUUM: dead tuple versions - might be removed too soon. The impact of this on actual database - operations would be minimal, since the system doesn't follow MVCC - rules while examining catalogs, but it might result in transiently - wrong output from pg_dump or other client programs. - - - - - - Fix potential miscalculation of datfrozenxid (Alvaro) - - - - This error may explain some recent reports of failure to remove old - pg_clog data. - - - - - - Fix incorrect HOT updates after pg_class is reindexed - (Tom) - - - - Corruption of pg_class could occur if REINDEX - TABLE pg_class was followed in the same session by an ALTER - TABLE RENAME or ALTER TABLE SET SCHEMA command. - - - - - - Fix missed combo cid case (Karl Schnaitter) - - - - This error made rows incorrectly invisible to a transaction in which they - had been deleted by multiple subtransactions that all aborted. - - - - - - Prevent autovacuum from crashing if the table it's currently - checking is deleted at just the wrong time (Alvaro) - - - - - - Widen local lock counters from 32 to 64 bits (Tom) - - - - This responds to reports that the counters could overflow in - sufficiently long transactions, leading to unexpected lock is - already held errors. - - - - - - Fix possible duplicate output of tuples during a GiST index scan (Teodor) - - - - - - Regenerate foreign key checking queries from scratch when either - table is modified (Tom) - - - - Previously, 8.3 would attempt to replan the query, but would work from - previously generated query text. This led to failures if a - table or column was renamed. - - - - - - Fix missed permissions checks when a view contains a simple - UNION ALL construct (Heikki) - - - - Permissions for the referenced tables were checked properly, but not - permissions for the view itself. - - - - - - Add checks in executor startup to ensure that the tuples produced by an - INSERT or UPDATE will match the target table's - current rowtype (Tom) - - - - This situation is believed to be impossible in 8.3, but it can happen in - prior releases, so a check seems prudent. - - - - - - Fix possible repeated drops during DROP OWNED (Tom) - - - - This would typically result in strange errors such as cache - lookup failed for relation NNN. - - - - - - Fix several memory leaks in XML operations (Kris Jurka, Tom) - - - - - - Fix xmlserialize() to raise error properly for - unacceptable target data type (Tom) - - - - - - Fix a couple of places that mis-handled multibyte characters in text - search configuration file parsing (Tom) - - - - Certain characters occurring in configuration files would always cause - invalid byte sequence for encoding failures. - - - - - - Provide file name and line number location for all errors reported - in text search configuration files (Tom) - - - - - - Fix AT TIME ZONE to first try to interpret its timezone - argument as a timezone abbreviation, and only try it as a full timezone - name if that fails, rather than the other way around as formerly (Tom) - - - - The timestamp input functions have always resolved ambiguous zone names - in this order. Making AT TIME ZONE do so as well improves - consistency, and fixes a compatibility bug introduced in 8.1: - in ambiguous cases we now behave the same as 8.0 and before did, - since in the older versions AT TIME ZONE accepted - only abbreviations. - - - - - - Fix datetime input functions to correctly detect integer overflow when - running on a 64-bit platform (Tom) - - - - - - Prevent integer overflows during units conversion when displaying a - configuration parameter that has units (Tom) - - - - - - Improve performance of writing very long log messages to syslog (Tom) - - - - - - Allow spaces in the suffix part of an LDAP URL in - pg_hba.conf (Tom) - - - - - - Fix bug in backwards scanning of a cursor on a SELECT DISTINCT - ON query (Tom) - - - - - - Fix planner bug that could improperly push down IS NULL - tests below an outer join (Tom) - - - - This was triggered by occurrence of IS NULL tests for - the same relation in all arms of an upper OR clause. - - - - - - Fix planner bug with nested sub-select expressions (Tom) - - - - If the outer sub-select has no direct dependency on the parent query, - but the inner one does, the outer value might not get recalculated - for new parent query rows. - - - - - - Fix planner to estimate that GROUP BY expressions yielding - boolean results always result in two groups, regardless of the - expressions' contents (Tom) - - - - This is very substantially more accurate than the regular GROUP - BY estimate for certain boolean tests like col - IS NULL. - - - - - - Fix PL/pgSQL to not fail when a FOR loop's target variable - is a record containing composite-type fields (Tom) - - - - - - Fix PL/Tcl to behave correctly with Tcl 8.5, and to be more careful - about the encoding of data sent to or from Tcl (Tom) - - - - - - Improve performance of PQescapeBytea() (Rudolf Leitgeb) - - - - - - On Windows, work around a Microsoft bug by preventing - libpq from trying to send more than 64kB per system call - (Magnus) - - - - - - Fix ecpg to handle variables properly in SET - commands (Michael) - - - - - - Improve pg_dump and pg_restore's - error reporting after failure to send a SQL command (Tom) - - - - - - Fix pg_ctl to properly preserve postmaster - command-line arguments across a restart (Bruce) - - - - - - Fix erroneous WAL file cutoff point calculation in - pg_standby (Simon) - - - - - - Update time zone data files to tzdata release 2008f (for - DST law changes in Argentina, Bahamas, Brazil, Mauritius, Morocco, - Pakistan, Palestine, and Paraguay) - - - - - - - - - - Release 8.3.3 - - - Release date: - 2008-06-12 - - - - This release contains one serious and one minor bug fix over 8.3.2. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.3 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.1, - see . - - - - - - Changes - - - - - - Make pg_get_ruledef() parenthesize negative constants (Tom) - - - - Before this fix, a negative constant in a view or rule might be dumped - as, say, -42::integer, which is subtly incorrect: it should - be (-42)::integer due to operator precedence rules. - Usually this would make little difference, but it could interact with - another recent patch to cause - PostgreSQL to reject what had been a valid - SELECT DISTINCT view query. Since this could result in - pg_dump output failing to reload, it is being treated - as a high-priority fix. The only released versions in which dump - output is actually incorrect are 8.3.1 and 8.2.7. - - - - - - Make ALTER AGGREGATE ... OWNER TO update - pg_shdepend (Tom) - - - - This oversight could lead to problems if the aggregate was later - involved in a DROP OWNED or REASSIGN OWNED - operation. - - - - - - - - - - Release 8.3.2 - - - Release date: - never released - - - - This release contains a variety of fixes from 8.3.1. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.2 - - - A dump/restore is not required for those running 8.3.X. - However, if you are upgrading from a version earlier than 8.3.1, - see . - - - - - - Changes - - - - - - Fix ERRORDATA_STACK_SIZE exceeded crash that - occurred on Windows when using UTF-8 database encoding and a different - client encoding (Tom) - - - - - - Fix incorrect archive truncation point calculation for the - %r macro in restore_command parameters - (Simon) - - - - This could lead to data loss if a warm-standby script relied on - %r to decide when to throw away WAL segment files. - - - - - - Fix ALTER TABLE ADD COLUMN ... PRIMARY KEY so that the new - column is correctly checked to see if it's been initialized to all - non-nulls (Brendan Jurd) - - - - Previous versions neglected to check this requirement at all. - - - - - - Fix REASSIGN OWNED so that it works on procedural - languages too (Alvaro) - - - - - - Fix problems with SELECT FOR UPDATE/SHARE occurring as a - subquery in a query with a non-SELECT top-level operation - (Tom) - - - - - - Fix possible CREATE TABLE failure when inheriting the - same constraint from multiple parent relations that - inherited that constraint from a common ancestor (Tom) - - - - - - Fix pg_get_ruledef() to show the alias, if any, attached - to the target table of an UPDATE or DELETE - (Tom) - - - - - - Restore the pre-8.3 behavior that an out-of-range block number in a - TID being used in a TidScan plan results in silently not matching any - rows (Tom) - - - - 8.3.0 and 8.3.1 threw an error instead. - - - - - - Fix GIN bug that could result in a too many LWLocks - taken failure (Teodor) - - - - - - Fix broken GiST comparison function for tsquery (Teodor) - - - - - - Fix tsvector_update_trigger() and ts_stat() - to accept domains over the types they expect to work with (Tom) - - - - - - Fix failure to support enum data types as foreign keys (Tom) - - - - - - Avoid possible crash when decompressing corrupted data - (Zdenek Kotala) - - - - - - Fix race conditions between delayed unlinks and DROP - DATABASE (Heikki) - - - - In the worst case this could result in deleting a newly created table - in a new database that happened to get the same OID as the - recently-dropped one; but of course that is an extremely - low-probability scenario. - - - - - - Repair two places where SIGTERM exit of a backend could leave corrupted - state in shared memory (Tom) - - - - Neither case is very important if SIGTERM is used to shut down the - whole database cluster together, but there was a problem if someone - tried to SIGTERM individual backends. - - - - - - Fix possible crash due to incorrect plan generated for an - x IN (SELECT y - FROM ...) clause when x and y - have different data types; and make sure the behavior is semantically - correct when the conversion from y's type to - x's type is lossy (Tom) - - - - - - Fix oversight that prevented the planner from substituting known Param - values as if they were constants (Tom) - - - - This mistake partially disabled optimization of unnamed - extended-Query statements in 8.3.0 and 8.3.1: in particular the - LIKE-to-indexscan optimization would never be applied if the LIKE - pattern was passed as a parameter, and constraint exclusion - depending on a parameter value didn't work either. - - - - - - Fix planner failure when an indexable MIN or - MAX aggregate is used with DISTINCT or - ORDER BY (Tom) - - - - - - Fix planner to ensure it never uses a physical tlist for a - plan node that is feeding a Sort node (Tom) - - - - This led to the sort having to push around more data than it really - needed to, since unused column values were included in the sorted - data. - - - - - - Avoid unnecessary copying of query strings (Tom) - - - - This fixes a performance problem introduced in 8.3.0 when a very large - number of commands are submitted as a single query string. - - - - - - Make TransactionIdIsCurrentTransactionId() use binary - search instead of linear search when checking child-transaction XIDs - (Heikki) - - - - This fixes some cases in which 8.3.0 was significantly - slower than earlier releases. - - - - - - Fix conversions between ISO-8859-5 and other encodings to handle - Cyrillic Yo characters (e and E with - two dots) (Sergey Burladyan) - - - - - - Fix several datatype input functions, notably array_in(), - that were allowing unused bytes in their results to contain - uninitialized, unpredictable values (Tom) - - - - This could lead to failures in which two apparently identical literal - values were not seen as equal, resulting in the parser complaining - about unmatched ORDER BY and DISTINCT - expressions. - - - - - - Fix a corner case in regular-expression substring matching - (substring(string from - pattern)) (Tom) - - - - The problem occurs when there is a match to the pattern overall but - the user has specified a parenthesized subexpression and that - subexpression hasn't got a match. An example is - substring('foo' from 'foo(bar)?'). - This should return NULL, since (bar) isn't matched, but - it was mistakenly returning the whole-pattern match instead (ie, - foo). - - - - - - Prevent cancellation of an auto-vacuum that was launched to prevent - XID wraparound (Alvaro) - - - - - - Improve ANALYZE's handling of in-doubt tuples (those - inserted or deleted by a not-yet-committed transaction) so that the - counts it reports to the stats collector are more likely to be correct - (Pavan Deolasee) - - - - - - Fix initdb to reject a relative path for its - --xlogdir (-X) option (Tom) - - - - - - Make psql print tab characters as an appropriate - number of spaces, rather than \x09 as was done in - 8.3.0 and 8.3.1 (Bruce) - - - - - - Update time zone data files to tzdata release 2008c (for - DST law changes in Morocco, Iraq, Choibalsan, Pakistan, Syria, Cuba, and - Argentina/San_Luis) - - - - - - Add ECPGget_PGconn() function to - ecpglib (Michael) - - - - - - Fix incorrect result from ecpg's - PGTYPEStimestamp_sub() function (Michael) - - - - - - Fix handling of continuation line markers in ecpg - (Michael) - - - - - - Fix possible crashes in contrib/cube functions (Tom) - - - - - - Fix core dump in contrib/xml2's - xpath_table() function when the input query returns a - NULL value (Tom) - - - - - - Fix contrib/xml2's makefile to not override - CFLAGS, and make it auto-configure properly for - libxslt present or not (Tom) - - - - - - - - - - Release 8.3.1 - - - Release date: - 2008-03-17 - - - - This release contains a variety of fixes from 8.3.0. - For information about new features in the 8.3 major release, see - . - - - - Migration to Version 8.3.1 - - - A dump/restore is not required for those running 8.3.X. - However, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the Windows locale - issue described below. - - - - - - Changes - - - - - - Fix character string comparison for Windows locales that consider - different character combinations as equal (Tom) - - - - This fix applies only on Windows and only when using UTF-8 - database encoding. The same fix was made for all other cases - over two years ago, but Windows with UTF-8 uses a separate code - path that was not updated. If you are using a locale that - considers some non-identical strings as equal, you may need to - REINDEX to fix existing indexes on textual columns. - - - - - - Repair corner-case bugs in VACUUM FULL (Tom) - - - - A potential deadlock between concurrent VACUUM FULL - operations on different system catalogs was introduced in 8.2. - This has now been corrected. 8.3 made this worse because the - deadlock could occur within a critical code section, making it - a PANIC rather than just ERROR condition. - - - - Also, a VACUUM FULL that failed partway through - vacuuming a system catalog could result in cache corruption in - concurrent database sessions. - - - - Another VACUUM FULL bug introduced in 8.3 could - result in a crash or out-of-memory report when dealing with - pages containing no live tuples. - - - - - - Fix misbehavior of foreign key checks involving character - or bit columns (Tom) - - - - If the referencing column were of a different but compatible type - (for instance varchar), the constraint was enforced incorrectly. - - - - - - Avoid needless deadlock failures in no-op foreign-key checks (Stephan - Szabo, Tom) - - - - - - Fix possible core dump when re-planning a prepared query (Tom) - - - - This bug affected only protocol-level prepare operations, not - SQL PREPARE, and so tended to be seen only with - JDBC, DBI, and other client-side drivers that use prepared - statements heavily. - - - - - - Fix possible failure when re-planning a query that calls an SPI-using - function (Tom) - - - - - - Fix failure in row-wise comparisons involving columns of different - datatypes (Tom) - - - - - - Fix longstanding LISTEN/NOTIFY - race condition (Tom) - - - - In rare cases a session that had just executed a - LISTEN might not get a notification, even though - one would be expected because the concurrent transaction executing - NOTIFY was observed to commit later. - - - - A side effect of the fix is that a transaction that has executed - a not-yet-committed LISTEN command will not see any - row in pg_listener for the LISTEN, - should it choose to look; formerly it would have. This behavior - was never documented one way or the other, but it is possible that - some applications depend on the old behavior. - - - - - - Disallow LISTEN and UNLISTEN within a - prepared transaction (Tom) - - - - This was formerly allowed but trying to do it had various unpleasant - consequences, notably that the originating backend could not exit - as long as an UNLISTEN remained uncommitted. - - - - - - Disallow dropping a temporary table within a - prepared transaction (Heikki) - - - - This was correctly disallowed by 8.1, but the check was inadvertently - broken in 8.2 and 8.3. - - - - - - Fix rare crash when an error occurs during a query using a hash index - (Heikki) - - - - - - Fix incorrect comparison of tsquery values (Teodor) - - - - - - Fix incorrect behavior of LIKE with non-ASCII characters - in single-byte encodings (Rolf Jentsch) - - - - - - Disable xmlvalidate (Tom) - - - - This function should have been removed before 8.3 release, but - was inadvertently left in the source code. It poses a small - security risk since unprivileged users could use it to read the - first few characters of any file accessible to the server. - - - - - - Fix memory leaks in certain usages of set-returning functions (Neil) - - - - - - Make encode(bytea, 'escape') convert all - high-bit-set byte values into \nnn octal - escape sequences (Tom) - - - - This is necessary to avoid encoding problems when the database - encoding is multi-byte. This change could pose compatibility issues - for applications that are expecting specific results from - encode. - - - - - - Fix input of datetime values for February 29 in years BC (Tom) - - - - The former coding was mistaken about which years were leap years. - - - - - - Fix unrecognized node type error in some variants of - ALTER OWNER (Tom) - - - - - - Avoid tablespace permissions errors in CREATE TABLE LIKE - INCLUDING INDEXES (Tom) - - - - - - Ensure pg_stat_activity.waiting flag - is cleared when a lock wait is aborted (Tom) - - - - - - Fix handling of process permissions on Windows Vista (Dave, Magnus) - - - - In particular, this fix allows starting the server as the Administrator - user. - - - - - - Update time zone data files to tzdata release 2008a - (in particular, recent Chile changes); adjust timezone abbreviation - VET (Venezuela) to mean UTC-4:30, not UTC-4:00 (Tom) - - - - - - Fix ecpg problems with arrays (Michael) - - - - - - Fix pg_ctl to correctly extract the postmaster's port - number from command-line options (Itagaki Takahiro, Tom) - - - - Previously, pg_ctl start -w could try to contact the - postmaster on the wrong port, leading to bogus reports of startup - failure. - - - - - - Use to defend against possible misoptimization - in recent gcc versions (Tom) - - - - This is known to be necessary when building PostgreSQL - with gcc 4.3 or later. - - - - - - Enable building contrib/uuid-ossp with MSVC (Hiroshi Saito) - - - - - - - - - - Release 8.3 - - - Release date: - 2008-02-04 - - - - Overview - - - With significant new functionality and performance enhancements, - this release represents a major leap forward for - PostgreSQL. This was made possible by a growing - community that has dramatically accelerated the pace of - development. This release adds the following major features: - - - - - - - Full text search is integrated into the core database system - - - - - - Support for the SQL/XML standard, including new operators and an - XML data type - - - - - - Enumerated data types (ENUM) - - - - - - Arrays of composite types - - - - - - Universally Unique Identifier (UUID) data type - - - - - - Add control over whether NULLs sort first or last - - - - - - Updatable cursors - - - - - - Server configuration parameters can now be set on a per-function - basis - - - - - - User-defined types can now have type modifiers - - - - - - Automatically re-plan cached queries when table - definitions change or statistics are updated - - - - - - Numerous improvements in logging and statistics collection - - - - - - Support Security Service Provider Interface (SSPI) for - authentication on Windows - - - - - - Support multiple concurrent autovacuum processes, and other - autovacuum improvements - - - - - - Allow the whole PostgreSQL distribution to be compiled - with Microsoft Visual C++ - - - - - - - Major performance improvements are listed below. Most of - these enhancements are automatic and do not require user changes or - tuning: - - - - - - - Asynchronous commit delays writes to WAL during transaction commit - - - - - - Checkpoint writes can be spread over a longer time period to smooth - the I/O spike during each checkpoint - - - - - - Heap-Only Tuples (HOT) accelerate space reuse for - most UPDATEs and DELETEs - - - - - - Just-in-time background writer strategy improves disk write - efficiency - - - - - - Using non-persistent transaction IDs for read-only transactions - reduces overhead and VACUUM requirements - - - - - - Per-field and per-row storage overhead has been reduced - - - - - - Large sequential scans no longer force out frequently used - cached pages - - - - - - Concurrent large sequential scans can now share disk reads - - - - - - ORDER BY ... LIMIT can be done without sorting - - - - - - - The above items are explained in more detail in the sections below. - - - - - - Migration to Version 8.3 - - - A dump/restore using pg_dump is - required for those wishing to migrate data from any previous - release. - - - - Observe the following incompatibilities: - - - - General - - - - - Non-character data types are no longer automatically cast to - TEXT (Peter, Tom) - - - - Previously, if a non-character value was supplied to an operator or - function that requires text input, it was automatically - cast to text, for most (though not all) built-in data types. - This no longer happens: an explicit cast to text is now - required for all non-character-string types. For example, these - expressions formerly worked: - - -substr(current_date, 1, 4) -23 LIKE '2%' - - - but will now draw function does not exist and operator - does not exist errors respectively. Use an explicit cast instead: - - -substr(current_date::text, 1, 4) -23::text LIKE '2%' - - - (Of course, you can use the more verbose CAST() syntax too.) - The reason for the change is that these automatic casts too often caused - surprising behavior. An example is that in previous releases, this - expression was accepted but did not do what was expected: - - -current_date < 2017-11-17 - - - This is actually comparing a date to an integer, which should be - (and now is) rejected — but in the presence of automatic - casts both sides were cast to text and a textual comparison - was done, because the text < text operator was able - to match the expression when no other < operator could. - - - - Types char(n) and - varchar(n) still cast to text - automatically. Also, automatic casting to text still works for - inputs to the concatenation (||) operator, so long as least - one input is a character-string type. - - - - - - Full text search features from contrib/tsearch2 have - been moved into the core server, with some minor syntax changes - - - - contrib/tsearch2 now contains a compatibility - interface. - - - - - - ARRAY(SELECT ...), where the SELECT - returns no rows, now returns an empty array, rather than NULL - (Tom) - - - - - - The array type name for a base data type is no longer always the base - type's name with an underscore prefix - - - - The old naming convention is still honored when possible, but - application code should no longer depend on it. Instead - use the new pg_type.typarray column to - identify the array data type associated with a given type. - - - - - - ORDER BY ... USING operator must now - use a less-than or greater-than operator that is - defined in a btree operator class - - - - This restriction was added to prevent inconsistent results. - - - - - - SET LOCAL changes now persist until - the end of the outermost transaction, unless rolled back (Tom) - - - - Previously SET LOCAL's effects were lost - after subtransaction commit (RELEASE SAVEPOINT - or exit from a PL/pgSQL exception block). - - - - - - Commands rejected in transaction blocks are now also rejected in - multiple-statement query strings (Tom) - - - - For example, "BEGIN; DROP DATABASE; COMMIT" will now be - rejected even if submitted as a single query message. - - - - - - ROLLBACK outside a transaction block now - issues NOTICE instead of WARNING (Bruce) - - - - - - Prevent NOTIFY/LISTEN/UNLISTEN - from accepting schema-qualified names (Bruce) - - - - Formerly, these commands accepted schema.relation but - ignored the schema part, which was confusing. - - - - - - ALTER SEQUENCE no longer affects the sequence's - currval() state (Tom) - - - - - - Foreign keys now must match indexable conditions for - cross-data-type references (Tom) - - - - This improves semantic consistency and helps avoid - performance problems. - - - - - - Restrict object size functions to users who have reasonable - permissions to view such information (Tom) - - - - For example, pg_database_size() now requires - CONNECT permission, which is granted to everyone by - default. pg_tablespace_size() requires - CREATE permission in the tablespace, or is allowed if - the tablespace is the default tablespace for the database. - - - - - - Remove the undocumented !!= (not in) operator (Tom) - - - - NOT IN (SELECT ...) is the proper way to - perform this operation. - - - - - - Internal hashing functions are now more uniformly-distributed (Tom) - - - - If application code was computing and storing hash values using - internal PostgreSQL hashing functions, the hash - values must be regenerated. - - - - - - C-code conventions for handling variable-length data values - have changed (Greg Stark, Tom) - - - - The new SET_VARSIZE() macro must be used - to set the length of generated varlena values. Also, it - might be necessary to expand (de-TOAST) input values - in more cases. - - - - - - Continuous archiving no longer reports each successful archive - operation to the server logs unless DEBUG level is used - (Simon) - - - - - - - - - Configuration Parameters - - - - - - Numerous changes in administrative server parameters - - - - bgwriter_lru_percent, - bgwriter_all_percent, - bgwriter_all_maxpages, - stats_start_collector, and - stats_reset_on_server_start are removed. - redirect_stderr is renamed to - logging_collector. - stats_command_string is renamed to - track_activities. - stats_block_level and stats_row_level - are merged into track_counts. - A new boolean configuration parameter, archive_mode, - controls archiving. Autovacuum's default settings have changed. - - - - - - Remove stats_start_collector parameter (Tom) - - - - We now always start the collector process, unless UDP - socket creation fails. - - - - - - Remove stats_reset_on_server_start parameter (Tom) - - - - This was removed because pg_stat_reset() - can be used for this purpose. - - - - - - Commenting out a parameter in postgresql.conf now - causes it to revert to its default value (Joachim Wieland) - - - - Previously, commenting out an entry left the parameter's value unchanged - until the next server restart. - - - - - - - - - - Character Encodings - - - - - - Add more checks for invalidly-encoded data (Andrew) - - - - This change plugs some holes that existed in literal backslash - escape string processing and COPY escape - processing. Now the de-escaped string is rechecked to see if the - result created an invalid multi-byte character. - - - - - - Disallow database encodings that are inconsistent with the server's - locale setting (Tom) - - - - On most platforms, C locale is the only locale that - will work with any database encoding. Other locale settings imply - a specific encoding and will misbehave if the database encoding - is something different. (Typical symptoms include bogus textual - sort order and wrong results from upper() or - lower().) The server now rejects attempts to create - databases that have an incompatible encoding. - - - - - - Ensure that chr() cannot create - invalidly-encoded values (Andrew) - - - - In UTF8-encoded databases the argument of chr() is - now treated as a Unicode code point. In other multi-byte encodings - chr()'s argument must designate a 7-bit ASCII - character. Zero is no longer accepted. - ascii() has been adjusted to match. - - - - - - Adjust convert() behavior to ensure encoding - validity (Andrew) - - - - The two argument form of convert() has been - removed. The three argument form now takes a bytea - first argument and returns a bytea. To cover the - loss of functionality, three new functions have been added: - - - - - - convert_from(bytea, name) returns - text — converts the first argument from the named - encoding to the database encoding - - - - - - convert_to(text, name) returns - bytea — converts the first argument from the - database encoding to the named encoding - - - - - - length(bytea, name) returns - integer — gives the length of the first - argument in characters in the named encoding - - - - - - - - Remove convert(argument USING conversion_name) - (Andrew) - - - - Its behavior did not match the SQL standard. - - - - - - Make JOHAB encoding client-only (Tatsuo) - - - - JOHAB is not safe as a server-side encoding. - - - - - - - - - - - Changes - - - Below you will find a detailed account of the - changes between PostgreSQL 8.3 and - the previous major release. - - - - Performance - - - - - Asynchronous commit delays writes to WAL during transaction commit - (Simon) - - - - This feature dramatically increases performance for short data-modifying - transactions. The disadvantage is that because disk writes are delayed, - if the database or operating system crashes before data is written to - the disk, committed data will be lost. This feature is useful for - applications that can accept some data loss. Unlike turning off - fsync, using asynchronous commit does not put - database consistency at risk; the worst case is that after a crash the - last few reportedly-committed transactions might not be committed after - all. - This feature is enabled by turning off synchronous_commit - (which can be done per-session or per-transaction, if some transactions - are critical and others are not). - wal_writer_delay can be adjusted to control the maximum - delay before transactions actually reach disk. - - - - - - Checkpoint writes can be spread over a longer time period to smooth - the I/O spike during each checkpoint (Itagaki Takahiro and Heikki - Linnakangas) - - - - Previously all modified buffers were forced to disk as quickly as - possible during a - checkpoint, causing an I/O spike that decreased server performance. - This new approach spreads out disk writes during checkpoints, - reducing peak I/O usage. (User-requested and shutdown checkpoints - are still written as quickly as possible.) - - - - - - Heap-Only Tuples (HOT) accelerate space reuse for most - UPDATEs and DELETEs (Pavan Deolasee, with - ideas from many others) - - - - UPDATEs and DELETEs leave dead tuples - behind, as do failed INSERTs. Previously only - VACUUM could reclaim space taken by dead tuples. With - HOT dead tuple space can be automatically reclaimed at - the time of INSERT or UPDATE if no changes - are made to indexed columns. This allows for more consistent - performance. Also, HOT avoids adding duplicate index - entries. - - - - - - Just-in-time background writer strategy improves disk write - efficiency (Greg Smith, Itagaki Takahiro) - - - - This greatly reduces the need for manual tuning of the background - writer. - - - - - - Per-field and per-row storage overhead have been reduced - (Greg Stark, Heikki Linnakangas) - - - - Variable-length data types with data values less than 128 bytes long - will see a storage decrease of 3 to 6 bytes. For example, two adjacent - char(1) fields now use 4 bytes instead of 16. Row headers - are also 4 bytes shorter than before. - - - - - - Using non-persistent transaction IDs for read-only transactions - reduces overhead and VACUUM requirements (Florian Pflug) - - - - Non-persistent transaction IDs do not increment the global - transaction counter. Therefore, they reduce the load on - pg_clog and increase the time between forced - vacuums to prevent transaction ID wraparound. - Other performance - improvements were also made that should improve concurrency. - - - - - - Avoid incrementing the command counter after a read-only command (Tom) - - - - There was formerly a hard limit of 232 - (4 billion) commands per transaction. Now only commands that - actually changed the database count, so while this limit still - exists, it should be significantly less annoying. - - - - - - Create a dedicated WAL writer process to off-load - work from backends (Simon) - - - - - - Skip unnecessary WAL writes for CLUSTER and - COPY (Simon) - - - - Unless WAL archiving is enabled, the system now avoids WAL writes - for CLUSTER and just fsync()s the - table at the end of the command. It also does the same for - COPY if the table was created in the same - transaction. - - - - - - Large sequential scans no longer force out frequently used - cached pages (Simon, Heikki, Tom) - - - - - - Concurrent large sequential scans can now share disk reads (Jeff Davis) - - - - This is accomplished by starting the new sequential scan in the - middle of the table (where another sequential scan is already - in-progress) and wrapping around to the beginning to finish. This - can affect the order of returned rows in a query that does not - specify ORDER BY. The synchronize_seqscans - configuration parameter can be used to disable this if necessary. - - - - - - ORDER BY ... LIMIT can be done without sorting - (Greg Stark) - - - - This is done by sequentially scanning the table and tracking just - the top N candidate rows, rather than performing a - full sort of the entire table. This is useful when there is no - matching index and the LIMIT is not large. - - - - - - Put a rate limit on messages sent to the statistics - collector by backends - (Tom) - - - - This reduces overhead for short transactions, but might sometimes - increase the delay before statistics are tallied. - - - - - - Improve hash join performance for cases with many NULLs (Tom) - - - - - - Speed up operator lookup for cases with non-exact datatype matches (Tom) - - - - - - - - - Server - - - - - Autovacuum is now enabled by default (Alvaro) - - - - Several changes were made to eliminate disadvantages of having - autovacuum enabled, thereby justifying the change in default. - Several other autovacuum parameter defaults were also modified. - - - - - - Support multiple concurrent autovacuum processes (Alvaro, Itagaki - Takahiro) - - - - This allows multiple vacuums to run concurrently. This prevents - vacuuming of a large table from delaying vacuuming of smaller tables. - - - - - - Automatically re-plan cached queries when table - definitions change or statistics are updated (Tom) - - - - Previously PL/pgSQL functions that referenced temporary tables - would fail if the temporary table was dropped and recreated - between function invocations, unless EXECUTE was - used. This improvement fixes that problem and many related issues. - - - - - - Add a temp_tablespaces parameter to control - the tablespaces for temporary tables and files (Jaime Casanova, - Albert Cervera, Bernd Helmle) - - - - This parameter defines a list of tablespaces to be used. This - enables spreading the I/O load across multiple tablespaces. A random - tablespace is chosen each time a temporary object is created. - Temporary files are no longer stored in per-database - pgsql_tmp/ directories but in per-tablespace - directories. - - - - - - Place temporary tables' TOAST tables in special schemas named - pg_toast_temp_nnn (Tom) - - - - This allows low-level code to recognize these tables as temporary, - which enables various optimizations such as not WAL-logging changes - and using local rather than shared buffers for access. This also - fixes a bug wherein backends unexpectedly held open file references - to temporary TOAST tables. - - - - - - Fix problem that a constant flow of new connection requests could - indefinitely delay the postmaster from completing a shutdown or - a crash restart (Tom) - - - - - - Guard against a very-low-probability data loss scenario by preventing - re-use of a deleted table's relfilenode until after the next - checkpoint (Heikki) - - - - - - Fix CREATE CONSTRAINT TRIGGER - to convert old-style foreign key trigger definitions into regular - foreign key constraints (Tom) - - - - This will ease porting of foreign key constraints carried forward from - pre-7.3 databases, if they were never converted using - contrib/adddepend. - - - - - - Fix DEFAULT NULL to override inherited defaults (Tom) - - - - DEFAULT NULL was formerly considered a noise phrase, but it - should (and now does) override non-null defaults that would otherwise - be inherited from a parent table or domain. - - - - - - Add new encodings EUC_JIS_2004 and SHIFT_JIS_2004 (Tatsuo) - - - - These new encodings can be converted to and from UTF-8. - - - - - - Change server startup log message from database system is - ready to database system is ready to accept - connections, and adjust its timing - - - - The message now appears only when the postmaster is really ready - to accept connections. - - - - - - - - - Monitoring - - - - - Add log_autovacuum_min_duration parameter to - support configurable logging of autovacuum activity (Simon, Alvaro) - - - - - - Add log_lock_waits parameter to log lock waiting - (Simon) - - - - - - Add log_temp_files parameter to log temporary - file usage (Bill Moran) - - - - - - Add log_checkpoints parameter to improve logging - of checkpoints (Greg Smith, Heikki) - - - - - - log_line_prefix now supports - %s and %c escapes in all - processes (Andrew) - - - - Previously these escapes worked only for user sessions, not for - background database processes. - - - - - - Add log_restartpoints to control logging of - point-in-time recovery restart points (Simon) - - - - - - Last transaction end time is now logged at end of recovery and at - each logged restart point (Simon) - - - - - - Autovacuum now reports its activity start time in - pg_stat_activity (Tom) - - - - - - Allow server log output in comma-separated value (CSV) format (Arul - Shaji, Greg Smith, Andrew Dunstan) - - - - CSV-format log files can easily be loaded into a database table for - subsequent analysis. - - - - - - Use PostgreSQL-supplied timezone support for formatting timestamps - displayed in the server log (Tom) - - - - This avoids Windows-specific problems with localized time zone - names that are in the wrong encoding. There is a new - log_timezone parameter that controls the timezone - used in log messages, independently of the client-visible - timezone parameter. - - - - - - New system view pg_stat_bgwriter displays - statistics about background writer activity (Magnus) - - - - - - Add new columns for database-wide tuple statistics to - pg_stat_database (Magnus) - - - - - - Add an xact_start (transaction start time) column to - pg_stat_activity (Neil) - - - - This makes it easier to identify long-running transactions. - - - - - - Add n_live_tuples and n_dead_tuples columns - to pg_stat_all_tables and related views (Glen - Parker) - - - - - - Merge stats_block_level and stats_row_level - parameters into a single parameter track_counts, which - controls all messages sent to the statistics collector process - (Tom) - - - - - - Rename stats_command_string parameter to - track_activities (Tom) - - - - - - Fix statistical counting of live and dead tuples to recognize that - committed and aborted transactions have different effects (Tom) - - - - - - - - - Authentication - - - - - Support Security Service Provider Interface (SSPI) for - authentication on Windows (Magnus) - - - - - - Support GSSAPI authentication (Henry Hotz, Magnus) - - - - This should be preferred to native Kerberos authentication because - GSSAPI is an industry standard. - - - - - - Support a global SSL configuration file (Victor Wagner) - - - - - - Add ssl_ciphers parameter to control accepted SSL ciphers - (Victor Wagner) - - - - - - Add a Kerberos realm parameter, krb_realm (Magnus) - - - - - - - - - Write-Ahead Log (<acronym>WAL</acronym>) and Continuous Archiving - - - - - Change the timestamps recorded in transaction WAL records from - time_t to TimestampTz representation (Tom) - - - - This provides sub-second resolution in WAL, which can be useful for - point-in-time recovery. - - - - - - Reduce WAL disk space needed by warm standby servers (Simon) - - - - This change allows a warm standby server to pass the name of the earliest - still-needed WAL file to the recovery script, allowing automatic removal - of no-longer-needed WAL files. This is done using %r in - the restore_command parameter of - recovery.conf. - - - - - - New boolean configuration parameter, archive_mode, - controls archiving (Simon) - - - - Previously setting archive_command to an empty string - turned off archiving. Now archive_mode turns archiving - on and off, independently of archive_command. This is - useful for stopping archiving temporarily. - - - - - - - - - Queries - - - - - Full text search is integrated into the core database - system (Teodor, Oleg) - - - - Text search has been improved, moved into the core code, and is now - installed by default. contrib/tsearch2 now contains - a compatibility interface. - - - - - - Add control over whether NULLs sort first or last (Teodor, Tom) - - - - The syntax is ORDER BY ... NULLS FIRST/LAST. - - - - - - Allow per-column ascending/descending (ASC/DESC) - ordering options for indexes (Teodor, Tom) - - - - Previously a query using ORDER BY with mixed - ASC/DESC specifiers could not fully use - an index. Now an index can be fully used in such cases if the - index was created with matching - ASC/DESC specifications. - NULL sort order within an index can be controlled, too. - - - - - - Allow col IS NULL to use an index (Teodor) - - - - - - Updatable cursors (Arul Shaji, Tom) - - - - This eliminates the need to reference a primary key to - UPDATE or DELETE rows returned by a cursor. - The syntax is UPDATE/DELETE WHERE CURRENT OF. - - - - - - Allow FOR UPDATE in cursors (Arul Shaji, Tom) - - - - - - Create a general mechanism that supports casts to and from the - standard string types (TEXT, VARCHAR, - CHAR) for every datatype, by - invoking the datatype's I/O functions (Tom) - - - - Previously, such casts were available only for types that had - specialized function(s) for the purpose. - These new casts are assignment-only in the to-string direction, - explicit-only in the other direction, and therefore should create no - surprising behavior. - - - - - - Allow UNION and related constructs to return a domain - type, when all inputs are of that domain type (Tom) - - - - Formerly, the output would be considered to be of the domain's base - type. - - - - - - Allow limited hashing when using two different data types (Tom) - - - - This allows hash joins, hash indexes, hashed subplans, and hash - aggregation to be used in situations involving cross-data-type - comparisons, if the data types have compatible hash functions. - Currently, cross-data-type hashing support exists for - smallint/integer/bigint, - and for float4/float8. - - - - - - Improve optimizer logic for detecting when variables are equal - in a WHERE clause (Tom) - - - - This allows mergejoins to work with descending sort orders, and - improves recognition of redundant sort columns. - - - - - - Improve performance when planning large inheritance trees in - cases where most tables are excluded by constraints (Tom) - - - - - - - - - Object Manipulation - - - - - - Arrays of composite types (David Fetter, Andrew, Tom) - - - - In addition to arrays of explicitly-declared composite types, - arrays of the rowtypes of regular tables and views are now - supported, except for rowtypes of system catalogs, sequences, and TOAST - tables. - - - - - - - Server configuration parameters can now be set on a per-function - basis (Tom) - - - - For example, functions can now set their own - search_path to prevent unexpected behavior if a - different search_path exists at run-time. Security - definer functions should set search_path to - avoid security loopholes. - - - - - - CREATE/ALTER FUNCTION now supports - COST and ROWS options (Tom) - - - - COST allows specification of the cost of a - function call. ROWS allows specification of - the average number or rows returned by a set-returning function. - These values are used by the optimizer in choosing the best plan. - - - - - - Implement CREATE TABLE LIKE ... INCLUDING - INDEXES (Trevor Hardcastle, Nikhil Sontakke, Neil) - - - - - - Allow CREATE INDEX CONCURRENTLY to ignore - transactions in other databases (Simon) - - - - - - Add ALTER VIEW ... RENAME TO and ALTER - SEQUENCE ... RENAME TO (David Fetter, Neil) - - - - Previously this could only be done via ALTER TABLE ... - RENAME TO. - - - - - - Make CREATE/DROP/RENAME DATABASE wait briefly for - conflicting backends to exit before failing (Tom) - - - - This increases the likelihood that these commands will succeed. - - - - - - Allow triggers and rules to be deactivated in groups using a - configuration parameter, for replication purposes (Jan) - - - - This allows replication systems to disable triggers and rewrite - rules as a group without modifying the system catalogs directly. - The behavior is controlled by ALTER TABLE and a new - parameter session_replication_role. - - - - - - User-defined types can now have type modifiers (Teodor, Tom) - - - - This allows a user-defined type to take a modifier, like - ssnum(7). Previously only built-in - data types could have modifiers. - - - - - - - - - Utility Commands - - - - - Non-superuser database owners now are able to add trusted procedural - languages to their databases by default (Jeremy Drake) - - - - While this is reasonably safe, some administrators might wish to - revoke the privilege. It is controlled by - pg_pltemplate.tmpldbacreate. - - - - - - Allow a session's current parameter setting to be used as the - default for future sessions (Tom) - - - - This is done with SET ... FROM CURRENT in - CREATE/ALTER FUNCTION, ALTER - DATABASE, or ALTER ROLE. - - - - - - Implement new commands DISCARD ALL, - DISCARD PLANS, DISCARD - TEMPORARY, CLOSE ALL, and - DEALLOCATE ALL (Marko Kreen, Neil) - - - - These commands simplify resetting a database session to its initial - state, and are particularly useful for connection-pooling software. - - - - - - Make CLUSTER MVCC-safe (Heikki Linnakangas) - - - - Formerly, CLUSTER would discard all tuples - that were committed dead, even if there were still transactions - that should be able to see them under MVCC visibility rules. - - - - - - Add new CLUSTER syntax: CLUSTER - table USING index - (Holger Schurig) - - - - The old CLUSTER syntax is still supported, but - the new form is considered more logical. - - - - - - Fix EXPLAIN so it can show complex plans - more accurately (Tom) - - - - References to subplan outputs are now always shown correctly, - instead of using ?columnN? - for complicated cases. - - - - - - Limit the amount of information reported when a user is dropped - (Alvaro) - - - - Previously, dropping (or attempting to drop) a user who owned many - objects could result in large NOTICE or - ERROR messages listing all these objects; this - caused problems for some client applications. The length of the - message is now limited, although a full list is still sent to the - server log. - - - - - - - - - Data Types - - - - - Support for the SQL/XML standard, including new operators and an - XML data type (Nikolay Samokhvalov, Pavel Stehule, Peter) - - - - - - Enumerated data types (ENUM) (Tom Dunstan) - - - - This feature provides convenient support for fields that have a - small, fixed set of allowed values. An example of creating an - ENUM type is - CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'). - - - - - - Universally Unique Identifier (UUID) data type (Gevik - Babakhani, Neil) - - - - This closely matches RFC 4122. - - - - - - Widen the MONEY data type to 64 bits (D'Arcy Cain) - - - - This greatly increases the range of supported MONEY - values. - - - - - - Fix float4/float8 to handle - Infinity and NAN (Not A Number) - consistently (Bruce) - - - - The code formerly was not consistent about distinguishing - Infinity from overflow conditions. - - - - - - Allow leading and trailing whitespace during input of - boolean values (Neil) - - - - - - Prevent COPY from using digits and lowercase letters as - delimiters (Tom) - - - - - - - - - Functions - - - - - Add new regular expression functions - regexp_matches(), - regexp_split_to_array(), and - regexp_split_to_table() (Jeremy Drake, Neil) - - - - These functions provide extraction of regular expression - subexpressions and allow splitting a string using a POSIX regular - expression. - - - - - - Add lo_truncate() for large object truncation - (Kris Jurka) - - - - - - Implement width_bucket() for the float8 - data type (Neil) - - - - - - Add pg_stat_clear_snapshot() to discard - statistics snapshots collected during the current transaction - (Tom) - - - - The first request for statistics in a transaction takes a statistics - snapshot that does not change during the transaction. This function - allows the snapshot to be discarded and a new snapshot loaded during - the next statistics query. This is particularly useful for PL/pgSQL - functions, which are confined to a single transaction. - - - - - - Add isodow option to EXTRACT() and - date_part() (Bruce) - - - - This returns the day of the week, with Sunday as seven. - (dow returns Sunday as zero.) - - - - - - Add ID (ISO day of week) and IDDD (ISO - day of year) format codes for to_char(), - to_date(), and to_timestamp() (Brendan - Jurd) - - - - - - Make to_timestamp() and to_date() - assume TM (trim) option for potentially - variable-width fields (Bruce) - - - - This matches Oracle's behavior. - - - - - - Fix off-by-one conversion error in - to_date()/to_timestamp() - D (non-ISO day of week) fields (Bruce) - - - - - - Make setseed() return void, rather than a - useless integer value (Neil) - - - - - - Add a hash function for NUMERIC (Neil) - - - - This allows hash indexes and hash-based plans to be used with - NUMERIC columns. - - - - - - Improve efficiency of - LIKE/ILIKE, especially for - multi-byte character sets like UTF-8 (Andrew, Itagaki Takahiro) - - - - - - Make currtid() functions require - SELECT privileges on the target table (Tom) - - - - - - Add several txid_*() functions to query - active transaction IDs (Jan) - - - - This is useful for various replication solutions. - - - - - - - - - PL/pgSQL Server-Side Language - - - - - Add scrollable cursor support, including directional control in - FETCH (Pavel Stehule) - - - - - - Allow IN as an alternative to - FROM in PL/pgSQL's FETCH - statement, for consistency with the backend's - FETCH command (Pavel Stehule) - - - - - - Add MOVE to PL/pgSQL (Magnus, Pavel Stehule, - Neil) - - - - - - Implement RETURN QUERY (Pavel Stehule, Neil) - - - - This adds convenient syntax for PL/pgSQL set-returning functions - that want to return the result of a query. RETURN QUERY - is easier and more efficient than a loop - around RETURN NEXT. - - - - - - Allow function parameter names to be qualified with the - function's name (Tom) - - - - For example, myfunc.myvar. This is particularly - useful for specifying variables in a query where the variable - name might match a column name. - - - - - - Make qualification of variables with block labels work properly (Tom) - - - - Formerly, outer-level block labels could unexpectedly interfere with - recognition of inner-level record or row references. - - - - - - Tighten requirements for FOR loop - STEP values (Tom) - - - - Prevent non-positive STEP values, and handle - loop overflows. - - - - - - Improve accuracy when reporting syntax error locations (Tom) - - - - - - - - - Other Server-Side Languages - - - - - Allow type-name arguments to PL/Perl - spi_prepare() to be data type aliases in - addition to names found in pg_type (Andrew) - - - - - - Allow type-name arguments to PL/Python - plpy.prepare() to be data type aliases in - addition to names found in pg_type (Andrew) - - - - - - Allow type-name arguments to PL/Tcl spi_prepare to - be data type aliases in addition to names found in - pg_type (Andrew) - - - - - - Enable PL/PythonU to compile on Python 2.5 (Marko Kreen) - - - - - - Support a true PL/Python boolean type in compatible Python versions - (Python 2.3 and later) (Marko Kreen) - - - - - - Fix PL/Tcl problems with thread-enabled libtcl spawning - multiple threads within the backend (Steve Marshall, Paul Bayer, - Doug Knight) - - - - This caused all sorts of unpleasantness. - - - - - - - - - <link linkend="app-psql"><application>psql</application></link> - - - - - List disabled triggers separately in \d output - (Brendan Jurd) - - - - - - In \d patterns, always match $ - literally (Tom) - - - - - - Show aggregate return types in \da output - (Greg Sabino Mullane) - - - - - - Add the function's volatility status to the output of - \df+ (Neil) - - - - - - Add \prompt capability (Chad Wagner) - - - - - - Allow \pset, \t, and - \x to specify on or off, - rather than just toggling (Chad Wagner) - - - - - - Add \sleep capability (Jan) - - - - - - Enable \timing output for \copy (Andrew) - - - - - - Improve \timing resolution on Windows - (Itagaki Takahiro) - - - - - - Flush \o output after each backslash command (Tom) - - - - - - Correctly detect and report errors while reading a -f - input file (Peter) - - - - - - Remove -u option (this option has long been deprecated) - (Tom) - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> - - - - - Add --tablespaces-only and --roles-only - options to pg_dumpall (Dave Page) - - - - - - Add an output file option to - pg_dumpall (Dave Page) - - - - This is primarily useful on Windows, where output redirection of - child pg_dump processes does not work. - - - - - - Allow pg_dumpall to accept an initial-connection - database name rather than the default - template1 (Dave Page) - - - - - - In -n and -t switches, always match - $ literally (Tom) - - - - - - Improve performance when a database has thousands of objects (Tom) - - - - - - Remove -u option (this option has long been deprecated) - (Tom) - - - - - - - - - Other Client Applications - - - - - In initdb, allow the location of the - pg_xlog directory to be specified - (Euler Taveira de Oliveira) - - - - - - Enable server core dump generation in pg_regress - on supported operating systems (Andrew) - - - - - - Add a -t (timeout) parameter to pg_ctl - (Bruce) - - - - This controls how long pg_ctl will wait when waiting - for server startup or shutdown. Formerly the timeout was hard-wired - as 60 seconds. - - - - - - Add a pg_ctl option to control generation - of server core dumps (Andrew) - - - - - - Allow Control-C to cancel clusterdb, - reindexdb, and vacuumdb (Itagaki - Takahiro, Magnus) - - - - - - Suppress command tag output for createdb, - createuser, dropdb, and - dropuser (Peter) - - - - The --quiet option is ignored and will be removed in 8.4. - Progress messages when acting on all databases now go to stdout - instead of stderr because they are not actually errors. - - - - - - - - - <link linkend="libpq"><application>libpq</application></link> - - - - - Interpret the dbName parameter of - PQsetdbLogin() as a conninfo string if - it contains an equals sign (Andrew) - - - - This allows use of conninfo strings in client - programs that still use PQsetdbLogin(). - - - - - - Support a global SSL configuration file (Victor - Wagner) - - - - - - Add environment variable PGSSLKEY to control - SSL hardware keys (Victor Wagner) - - - - - - Add lo_truncate() for large object - truncation (Kris Jurka) - - - - - - Add PQconnectionNeedsPassword() that returns - true if the server required a password but none was supplied - (Joe Conway, Tom) - - - - If this returns true after a failed connection attempt, a client - application should prompt the user for a password. In the past - applications have had to check for a specific error message string to - decide whether a password is needed; that approach is now - deprecated. - - - - - - Add PQconnectionUsedPassword() that returns - true if the supplied password was actually used - (Joe Conway, Tom) - - - - This is useful in some security contexts where it is important - to know whether a user-supplied password is actually valid. - - - - - - - - - <link linkend="ecpg"><application>ecpg</application></link> - - - - - Use V3 frontend/backend protocol (Michael) - - - - This adds support for server-side prepared statements. - - - - - - Use native threads, instead of pthreads, on Windows (Magnus) - - - - - - Improve thread-safety of ecpglib (Itagaki Takahiro) - - - - - - Make the ecpg libraries export only necessary API symbols (Michael) - - - - - - - - - <application>Windows</application> Port - - - - - Allow the whole PostgreSQL distribution to be compiled - with Microsoft Visual C++ (Magnus and others) - - - - This allows Windows-based developers to use familiar development - and debugging tools. - Windows executables made with Visual C++ might also have better - stability and performance than those made with other tool sets. - The client-only Visual C++ build scripts have been removed. - - - - - - Drastically reduce postmaster's memory usage when it has many child - processes (Magnus) - - - - - - Allow regression tests to be started by an administrative - user (Magnus) - - - - - - Add native shared memory implementation (Magnus) - - - - - - - - - Server Programming Interface (<acronym>SPI</acronym>) - - - - - Add cursor-related functionality in SPI (Pavel Stehule) - - - - Allow access to the cursor-related planning options, and add - FETCH/MOVE routines. - - - - - - Allow execution of cursor commands through - SPI_execute (Tom) - - - - The macro SPI_ERROR_CURSOR still exists but will - never be returned. - - - - - - SPI plan pointers are now declared as SPIPlanPtr instead of - void * (Tom) - - - - This does not break application code, but switching is - recommended to help catch simple programming mistakes. - - - - - - - - - Build Options - - - - - Add configure option --enable-profiling - to enable code profiling (works only with gcc) - (Korry Douglas and Nikhil Sontakke) - - - - - - Add configure option --with-system-tzdata - to use the operating system's time zone database (Peter) - - - - - - Fix PGXS so extensions can be built against PostgreSQL - installations whose pg_config program does not - appear first in the PATH (Tom) - - - - - - Support gmake draft when building the - SGML documentation (Bruce) - - - - Unless draft is used, the documentation build will - now be repeated if necessary to ensure the index is up-to-date. - - - - - - - - - Source Code - - - - - Rename macro DLLIMPORT to PGDLLIMPORT to - avoid conflicting with third party includes (like Tcl) that - define DLLIMPORT (Magnus) - - - - - - Create operator families to improve planning of - queries involving cross-data-type comparisons (Tom) - - - - - - Update GIN extractQuery() API to allow signalling - that nothing can satisfy the query (Teodor) - - - - - - Move NAMEDATALEN definition from - postgres_ext.h to pg_config_manual.h - (Peter) - - - - - - Provide strlcpy() and - strlcat() on all platforms, and replace - error-prone uses of strncpy(), - strncat(), etc (Peter) - - - - - - Create hooks to let an external plugin monitor (or even replace) the - planner and create plans for hypothetical situations (Gurjeet - Singh, Tom) - - - - - - Create a function variable join_search_hook to let plugins - override the join search order portion of the planner (Julius - Stroffek) - - - - - - Add tas() support for Renesas' M32R processor - (Kazuhiro Inaoka) - - - - - - quote_identifier() and - pg_dump no longer quote keywords that are - unreserved according to the grammar (Tom) - - - - - - Change the on-disk representation of the NUMERIC - data type so that the sign_dscale word comes - before the weight (Tom) - - - - - - Use SYSV semaphores rather than POSIX on Darwin - >= 6.0, i.e., macOS 10.2 and up (Chris Marcellino) - - - - - - Add acronym and NFS documentation - sections (Bruce) - - - - - - "Postgres" is now documented as an accepted alias for - "PostgreSQL" (Peter) - - - - - - Add documentation about preventing database server spoofing when - the server is down (Bruce) - - - - - - - - - Contrib - - - - - Move contrib README content into the - main PostgreSQL documentation (Albert Cervera i - Areny) - - - - - - Add contrib/pageinspect module for low-level - page inspection (Simon, Heikki) - - - - - - Add contrib/pg_standby module for controlling - warm standby operation (Simon) - - - - - - Add contrib/uuid-ossp module for generating - UUID values using the OSSP UUID library (Peter) - - - - Use configure - --with-ossp-uuid to activate. This takes - advantage of the new UUID builtin type. - - - - - - Add contrib/dict_int, - contrib/dict_xsyn, and - contrib/test_parser modules to provide - sample add-on text search dictionary templates and parsers - (Sergey Karpov) - - - - - - Allow contrib/pgbench to set the fillfactor (Pavan - Deolasee) - - - - - - Add timestamps to contrib/pgbench -l - (Greg Smith) - - - - - - Add usage count statistics to - contrib/pgbuffercache (Greg Smith) - - - - - - Add GIN support for contrib/hstore (Teodor) - - - - - - Add GIN support for contrib/pg_trgm (Guillaume Smet, Teodor) - - - - - - Update OS/X startup scripts in - contrib/start-scripts (Mark Cotner, David - Fetter) - - - - - - Restrict pgrowlocks() and - dblink_get_pkey() to users who have - SELECT privilege on the target table (Tom) - - - - - - Restrict contrib/pgstattuple functions to - superusers (Tom) - - - - - - contrib/xml2 is deprecated and planned for - removal in 8.4 (Peter) - - - - The new XML support in core PostgreSQL supersedes this module. - - - - - - - - diff --git a/doc/src/sgml/release-8.4.sgml b/doc/src/sgml/release-8.4.sgml deleted file mode 100644 index 6e6efa3bd19..00000000000 --- a/doc/src/sgml/release-8.4.sgml +++ /dev/null @@ -1,10080 +0,0 @@ - - - - - Release 8.4.22 - - - Release date: - 2014-07-24 - - - - This release contains a variety of fixes from 8.4.21. - For information about new features in the 8.4 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 8.4.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 8.4.22 - - - A dump/restore is not required for those running 8.4.X. - - - - However, this release corrects an index corruption problem in some GiST - indexes. See the first changelog entry below to find out whether your - installation has been affected and what steps you should take if so. - - - - Also, if you are upgrading from a version earlier than 8.4.19, - see . - - - - - - Changes - - - - - - Correctly initialize padding bytes in contrib/btree_gist - indexes on bit columns (Heikki Linnakangas) - - - - This error could result in incorrect query results due to values that - should compare equal not being seen as equal. - Users with GiST indexes on bit or bit varying - columns should REINDEX those indexes after installing this - update. - - - - - - Protect against torn pages when deleting GIN list pages (Heikki - Linnakangas) - - - - This fix prevents possible index corruption if a system crash occurs - while the page update is being written to disk. - - - - - - Fix possibly-incorrect cache invalidation during nested calls - to ReceiveSharedInvalidMessages (Andres Freund) - - - - - - Don't assume a subquery's output is unique if there's a set-returning - function in its targetlist (David Rowley) - - - - This oversight could lead to misoptimization of constructs - like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP - BY y). - - - - - - Fix failure to detoast fields in composite elements of structured - types (Tom Lane) - - - - This corrects cases where TOAST pointers could be copied into other - tables without being dereferenced. If the original data is later - deleted, it would lead to errors like missing chunk number 0 - for toast value ... when the now-dangling pointer is used. - - - - - - Fix record type has not been registered failures with - whole-row references to the output of Append plan nodes (Tom Lane) - - - - - - Fix possible crash when invoking a user-defined function while - rewinding a cursor (Tom Lane) - - - - - - Fix query-lifespan memory leak while evaluating the arguments for a - function in FROM (Tom Lane) - - - - - - Fix session-lifespan memory leaks in regular-expression processing - (Tom Lane, Arthur O'Dwyer, Greg Stark) - - - - - - Fix data encoding error in hungarian.stop (Tom Lane) - - - - - - Fix liveness checks for rows that were inserted in the current - transaction and then deleted by a now-rolled-back subtransaction - (Andres Freund) - - - - This could cause problems (at least spurious warnings, and at worst an - infinite loop) if CREATE INDEX or CLUSTER were - done later in the same transaction. - - - - - - Clear pg_stat_activity.xact_start - during PREPARE TRANSACTION (Andres Freund) - - - - After the PREPARE, the originating session is no longer in - a transaction, so it should not continue to display a transaction - start time. - - - - - - Fix REASSIGN OWNED to not fail for text search objects - (Álvaro Herrera) - - - - - - Block signals during postmaster startup (Tom Lane) - - - - This ensures that the postmaster will properly clean up after itself - if, for example, it receives SIGINT while still - starting up. - - - - - - Secure Unix-domain sockets of temporary postmasters started during - make check (Noah Misch) - - - - Any local user able to access the socket file could connect as the - server's bootstrap superuser, then proceed to execute arbitrary code as - the operating-system user running the test, as we previously noted in - CVE-2014-0067. This change defends against that risk by placing the - server's socket in a temporary, mode 0700 subdirectory - of /tmp. The hazard remains however on platforms where - Unix sockets are not supported, notably Windows, because then the - temporary postmaster must accept local TCP connections. - - - - A useful side effect of this change is to simplify - make check testing in builds that - override DEFAULT_PGSOCKET_DIR. Popular non-default values - like /var/run/postgresql are often not writable by the - build user, requiring workarounds that will no longer be necessary. - - - - - - On Windows, allow new sessions to absorb values of PGC_BACKEND - parameters (such as ) from the - configuration file (Amit Kapila) - - - - Previously, if such a parameter were changed in the file post-startup, - the change would have no effect. - - - - - - Properly quote executable path names on Windows (Nikhil Deshpande) - - - - This oversight could cause initdb - and pg_upgrade to fail on Windows, if the installation - path contained both spaces and @ signs. - - - - - - Fix linking of libpython on macOS (Tom Lane) - - - - The method we previously used can fail with the Python library - supplied by Xcode 5.0 and later. - - - - - - Avoid buffer bloat in libpq when the server - consistently sends data faster than the client can absorb it - (Shin-ichi Morita, Tom Lane) - - - - libpq could be coerced into enlarging its input buffer - until it runs out of memory (which would be reported misleadingly - as lost synchronization with server). Under ordinary - circumstances it's quite far-fetched that data could be continuously - transmitted more quickly than the recv() loop can - absorb it, but this has been observed when the client is artificially - slowed by scheduler constraints. - - - - - - Ensure that LDAP lookup attempts in libpq time out as - intended (Laurenz Albe) - - - - - - Fix pg_restore's processing of old-style large object - comments (Tom Lane) - - - - A direct-to-database restore from an archive file generated by a - pre-9.0 version of pg_dump would usually fail if the - archive contained more than a few comments for large objects. - - - - - - In contrib/pgcrypto functions, ensure sensitive - information is cleared from stack variables before returning - (Marko Kreen) - - - - - - In contrib/uuid-ossp, cache the state of the OSSP UUID - library across calls (Tom Lane) - - - - This improves the efficiency of UUID generation and reduces the amount - of entropy drawn from /dev/urandom, on platforms that - have that. - - - - - - Update time zone data files to tzdata release 2014e - for DST law changes in Crimea, Egypt, and Morocco. - - - - - - - - - - Release 8.4.21 - - - Release date: - 2014-03-20 - - - - This release contains a variety of fixes from 8.4.20. - For information about new features in the 8.4 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.4.X release series in July 2014. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.4.21 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.19, - see . - - - - - - Changes - - - - - - Restore GIN metapages unconditionally to avoid torn-page risk - (Heikki Linnakangas) - - - - Although this oversight could theoretically result in a corrupted - index, it is unlikely to have caused any problems in practice, since - the active part of a GIN metapage is smaller than a standard 512-byte - disk sector. - - - - - - Allow regular-expression operators to be terminated early by query - cancel requests (Tom Lane) - - - - This prevents scenarios wherein a pathological regular expression - could lock up a server process uninterruptibly for a long time. - - - - - - Remove incorrect code that tried to allow OVERLAPS with - single-element row arguments (Joshua Yanovski) - - - - This code never worked correctly, and since the case is neither - specified by the SQL standard nor documented, it seemed better to - remove it than fix it. - - - - - - Avoid getting more than AccessShareLock when de-parsing a - rule or view (Dean Rasheed) - - - - This oversight resulted in pg_dump unexpectedly - acquiring RowExclusiveLock locks on tables mentioned as - the targets of INSERT/UPDATE/DELETE - commands in rules. While usually harmless, that could interfere with - concurrent transactions that tried to acquire, for example, - ShareLock on those tables. - - - - - - Prevent interrupts while reporting non-ERROR messages - (Tom Lane) - - - - This guards against rare server-process freezeups due to recursive - entry to syslog(), and perhaps other related problems. - - - - - - Update time zone data files to tzdata release 2014a - for DST law changes in Fiji and Turkey, plus historical changes in - Israel and Ukraine. - - - - - - - - - - Release 8.4.20 - - - Release date: - 2014-02-20 - - - - This release contains a variety of fixes from 8.4.19. - For information about new features in the 8.4 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 8.4.X release series in July 2014. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 8.4.20 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.19, - see . - - - - - - Changes - - - - - - Shore up GRANT ... WITH ADMIN OPTION restrictions - (Noah Misch) - - - - Granting a role without ADMIN OPTION is supposed to - prevent the grantee from adding or removing members from the granted - role, but this restriction was easily bypassed by doing SET - ROLE first. The security impact is mostly that a role member can - revoke the access of others, contrary to the wishes of his grantor. - Unapproved role member additions are a lesser concern, since an - uncooperative role member could provide most of his rights to others - anyway by creating views or SECURITY DEFINER functions. - (CVE-2014-0060) - - - - - - Prevent privilege escalation via manual calls to PL validator - functions (Andres Freund) - - - - The primary role of PL validator functions is to be called implicitly - during CREATE FUNCTION, but they are also normal SQL - functions that a user can call explicitly. Calling a validator on - a function actually written in some other language was not checked - for and could be exploited for privilege-escalation purposes. - The fix involves adding a call to a privilege-checking function in - each validator function. Non-core procedural languages will also - need to make this change to their own validator functions, if any. - (CVE-2014-0061) - - - - - - Avoid multiple name lookups during table and index DDL - (Robert Haas, Andres Freund) - - - - If the name lookups come to different conclusions due to concurrent - activity, we might perform some parts of the DDL on a different table - than other parts. At least in the case of CREATE INDEX, - this can be used to cause the permissions checks to be performed - against a different table than the index creation, allowing for a - privilege escalation attack. - (CVE-2014-0062) - - - - - - Prevent buffer overrun with long datetime strings (Noah Misch) - - - - The MAXDATELEN constant was too small for the longest - possible value of type interval, allowing a buffer overrun - in interval_out(). Although the datetime input - functions were more careful about avoiding buffer overrun, the limit - was short enough to cause them to reject some valid inputs, such as - input containing a very long timezone name. The ecpg - library contained these vulnerabilities along with some of its own. - (CVE-2014-0063) - - - - - - Prevent buffer overrun due to integer overflow in size calculations - (Noah Misch, Heikki Linnakangas) - - - - Several functions, mostly type input functions, calculated an - allocation size without checking for overflow. If overflow did - occur, a too-small buffer would be allocated and then written past. - (CVE-2014-0064) - - - - - - Prevent overruns of fixed-size buffers - (Peter Eisentraut, Jozef Mlich) - - - - Use strlcpy() and related functions to provide a clear - guarantee that fixed-size buffers are not overrun. Unlike the - preceding items, it is unclear whether these cases really represent - live issues, since in most cases there appear to be previous - constraints on the size of the input string. Nonetheless it seems - prudent to silence all Coverity warnings of this type. - (CVE-2014-0065) - - - - - - Avoid crashing if crypt() returns NULL (Honza Horak, - Bruce Momjian) - - - - There are relatively few scenarios in which crypt() - could return NULL, but contrib/chkpass would crash - if it did. One practical case in which this could be an issue is - if libc is configured to refuse to execute unapproved - hashing algorithms (e.g., FIPS mode). - (CVE-2014-0066) - - - - - - Document risks of make check in the regression testing - instructions (Noah Misch, Tom Lane) - - - - Since the temporary server started by make check - uses trust authentication, another user on the same machine - could connect to it as database superuser, and then potentially - exploit the privileges of the operating-system user who started the - tests. A future release will probably incorporate changes in the - testing procedure to prevent this risk, but some public discussion is - needed first. So for the moment, just warn people against using - make check when there are untrusted users on the - same machine. - (CVE-2014-0067) - - - - - - Fix possible mis-replay of WAL records when some segments of a - relation aren't full size (Greg Stark, Tom Lane) - - - - The WAL update could be applied to the wrong page, potentially many - pages past where it should have been. Aside from corrupting data, - this error has been observed to result in significant bloat - of standby servers compared to their masters, due to updates being - applied far beyond where the end-of-file should have been. This - failure mode does not appear to be a significant risk during crash - recovery, only when initially synchronizing a standby created from a - base backup taken from a quickly-changing master. - - - - - - Ensure that insertions into non-leaf GIN index pages write a full-page - WAL record when appropriate (Heikki Linnakangas) - - - - The previous coding risked index corruption in the event of a - partial-page write during a system crash. - - - - - - Fix race conditions during server process exit (Robert Haas) - - - - Ensure that signal handlers don't attempt to use the - process's MyProc pointer after it's no longer valid. - - - - - - Fix unsafe references to errno within error reporting - logic (Christian Kruse) - - - - This would typically lead to odd behaviors such as missing or - inappropriate HINT fields. - - - - - - Fix possible crashes from using ereport() too early - during server startup (Tom Lane) - - - - The principal case we've seen in the field is a crash if the server - is started in a directory it doesn't have permission to read. - - - - - - Clear retry flags properly in OpenSSL socket write - function (Alexander Kukushkin) - - - - This omission could result in a server lockup after unexpected loss - of an SSL-encrypted connection. - - - - - - Fix length checking for Unicode identifiers (U&"..." - syntax) containing escapes (Tom Lane) - - - - A spurious truncation warning would be printed for such identifiers - if the escaped form of the identifier was too long, but the - identifier actually didn't need truncation after de-escaping. - - - - - - Fix possible crash due to invalid plan for nested sub-selects, such - as WHERE (... x IN (SELECT ...) ...) IN (SELECT ...) - (Tom Lane) - - - - - - Ensure that ANALYZE creates statistics for a table column - even when all the values in it are too wide (Tom Lane) - - - - ANALYZE intentionally omits very wide values from its - histogram and most-common-values calculations, but it neglected to do - something sane in the case that all the sampled entries are too wide. - - - - - - In ALTER TABLE ... SET TABLESPACE, allow the database's - default tablespace to be used without a permissions check - (Stephen Frost) - - - - CREATE TABLE has always allowed such usage, - but ALTER TABLE didn't get the memo. - - - - - - Fix cannot accept a set error when some arms of - a CASE return a set and others don't (Tom Lane) - - - - - - Fix checks for all-zero client addresses in pgstat functions (Kevin - Grittner) - - - - - - Fix possible misclassification of multibyte characters by the text - search parser (Tom Lane) - - - - Non-ASCII characters could be misclassified when using C locale with - a multibyte encoding. On Cygwin, non-C locales could fail as well. - - - - - - Fix possible misbehavior in plainto_tsquery() - (Heikki Linnakangas) - - - - Use memmove() not memcpy() for copying - overlapping memory regions. There have been no field reports of - this actually causing trouble, but it's certainly risky. - - - - - - Accept SHIFT_JIS as an encoding name for locale checking - purposes (Tatsuo Ishii) - - - - - - Fix misbehavior of PQhost() on Windows (Fujii Masao) - - - - It should return localhost if no host has been specified. - - - - - - Improve error handling in libpq and psql - for failures during COPY TO STDOUT/FROM STDIN (Tom Lane) - - - - In particular this fixes an infinite loop that could occur in 9.2 and - up if the server connection was lost during COPY FROM - STDIN. Variants of that scenario might be possible in older - versions, or with other client applications. - - - - - - Fix misaligned descriptors in ecpg (MauMau) - - - - - - In ecpg, handle lack of a hostname in the connection - parameters properly (Michael Meskes) - - - - - - Fix performance regression in contrib/dblink connection - startup (Joe Conway) - - - - Avoid an unnecessary round trip when client and server encodings match. - - - - - - In contrib/isn, fix incorrect calculation of the check - digit for ISMN values (Fabien Coelho) - - - - - - Ensure client-code-only installation procedure works as documented - (Peter Eisentraut) - - - - - - In Mingw and Cygwin builds, install the libpq DLL - in the bin directory (Andrew Dunstan) - - - - This duplicates what the MSVC build has long done. It should fix - problems with programs like psql failing to start - because they can't find the DLL. - - - - - - Don't generate plain-text HISTORY - and src/test/regress/README files anymore (Tom Lane) - - - - These text files duplicated the main HTML and PDF documentation - formats. The trouble involved in maintaining them greatly outweighs - the likely audience for plain-text format. Distribution tarballs - will still contain files by these names, but they'll just be stubs - directing the reader to consult the main documentation. - The plain-text INSTALL file will still be maintained, as - there is arguably a use-case for that. - - - - - - Update time zone data files to tzdata release 2013i - for DST law changes in Jordan and historical changes in Cuba. - - - - In addition, the zones Asia/Riyadh87, - Asia/Riyadh88, and Asia/Riyadh89 have been - removed, as they are no longer maintained by IANA, and never - represented actual civil timekeeping practice. - - - - - - - - - - Release 8.4.19 - - - Release date: - 2013-12-05 - - - - This release contains a variety of fixes from 8.4.18. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.19 - - - A dump/restore is not required for those running 8.4.X. - - - - However, this release corrects a potential data corruption - issue. See the first changelog entry below to find out whether - your installation has been affected and what steps you can take if so. - - - - Also, if you are upgrading from a version earlier than 8.4.17, - see . - - - - - - Changes - - - - - - Fix VACUUM's tests to see whether it can - update relfrozenxid (Andres Freund) - - - - In some cases VACUUM (either manual or autovacuum) could - incorrectly advance a table's relfrozenxid value, - allowing tuples to escape freezing, causing those rows to become - invisible once 2^31 transactions have elapsed. The probability of - data loss is fairly low since multiple incorrect advancements would - need to happen before actual loss occurs, but it's not zero. Users - upgrading from release 8.4.8 or earlier are not affected, but all later - versions contain the bug. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix any latent corruption but will not be able - to fix all pre-existing data errors. However, an installation can be - presumed safe after performing this vacuuming if it has executed fewer - than 2^31 update transactions in its lifetime (check this with - SELECT txid_current() < 2^31). - - - - - - Fix race condition in GIN index posting tree page deletion (Heikki - Linnakangas) - - - - This could lead to transient wrong answers or query failures. - - - - - - Avoid flattening a subquery whose SELECT list contains a - volatile function wrapped inside a sub-SELECT (Tom Lane) - - - - This avoids unexpected results due to extra evaluations of the - volatile function. - - - - - - Fix planner's processing of non-simple-variable subquery outputs - nested within outer joins (Tom Lane) - - - - This error could lead to incorrect plans for queries involving - multiple levels of subqueries within JOIN syntax. - - - - - - Fix premature deletion of temporary files (Andres Freund) - - - - - - Fix possible read past end of memory in rule printing (Peter Eisentraut) - - - - - - Fix array slicing of int2vector and oidvector values - (Tom Lane) - - - - Expressions of this kind are now implicitly promoted to - regular int2 or oid arrays. - - - - - - Fix incorrect behaviors when using a SQL-standard, simple GMT offset - timezone (Tom Lane) - - - - In some cases, the system would use the simple GMT offset value when - it should have used the regular timezone setting that had prevailed - before the simple offset was selected. This change also causes - the timeofday function to honor the simple GMT offset - zone. - - - - - - Prevent possible misbehavior when logging translations of Windows - error codes (Tom Lane) - - - - - - Properly quote generated command lines in pg_ctl - (Naoya Anzai and Tom Lane) - - - - This fix applies only to Windows. - - - - - - Fix pg_dumpall to work when a source database - sets default_transaction_read_only - via ALTER DATABASE SET (Kevin Grittner) - - - - Previously, the generated script would fail during restore. - - - - - - Fix ecpg's processing of lists of variables - declared varchar (Zoltán Böszörményi) - - - - - - Make contrib/lo defend against incorrect trigger definitions - (Marc Cousin) - - - - - - Update time zone data files to tzdata release 2013h - for DST law changes in Argentina, Brazil, Jordan, Libya, - Liechtenstein, Morocco, and Palestine. Also, new timezone - abbreviations WIB, WIT, WITA for Indonesia. - - - - - - - - - - Release 8.4.18 - - - Release date: - 2013-10-10 - - - - This release contains a variety of fixes from 8.4.17. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.18 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.17, - see . - - - - - - Changes - - - - - - Prevent corruption of multi-byte characters when attempting to - case-fold identifiers (Andrew Dunstan) - - - - PostgreSQL case-folds non-ASCII characters only - when using a single-byte server encoding. - - - - - - Fix memory leak caused by lo_open() failure - (Heikki Linnakangas) - - - - - - Fix memory overcommit bug when work_mem is using more - than 24GB of memory (Stephen Frost) - - - - - - Fix deadlock bug in libpq when using SSL (Stephen Frost) - - - - - - Properly compute row estimates for boolean columns containing many NULL - values (Andrew Gierth) - - - - Previously tests like col IS NOT TRUE and col IS - NOT FALSE did not properly factor in NULL values when estimating - plan costs. - - - - - - Prevent pushing down WHERE clauses into unsafe - UNION/INTERSECT subqueries (Tom Lane) - - - - Subqueries of a UNION or INTERSECT that - contain set-returning functions or volatile functions in their - SELECT lists could be improperly optimized, leading to - run-time errors or incorrect query results. - - - - - - Fix rare case of failed to locate grouping columns - planner failure (Tom Lane) - - - - - - Improve view dumping code's handling of dropped columns in referenced - tables (Tom Lane) - - - - - - Fix possible deadlock during concurrent CREATE INDEX - CONCURRENTLY operations (Tom Lane) - - - - - - Fix regexp_matches() handling of zero-length matches - (Jeevan Chalke) - - - - Previously, zero-length matches like '^' could return too many matches. - - - - - - Fix crash for overly-complex regular expressions (Heikki Linnakangas) - - - - - - Fix regular expression match failures for back references combined with - non-greedy quantifiers (Jeevan Chalke) - - - - - - Prevent CREATE FUNCTION from checking SET - variables unless function body checking is enabled (Tom Lane) - - - - - - Fix pgp_pub_decrypt() so it works for secret keys with - passwords (Marko Kreen) - - - - - - Remove rare inaccurate warning during vacuum of index-less tables - (Heikki Linnakangas) - - - - - - Avoid possible failure when performing transaction control commands (e.g - ROLLBACK) in prepared queries (Tom Lane) - - - - - - Ensure that floating-point data input accepts standard spellings - of infinity on all platforms (Tom Lane) - - - - The C99 standard says that allowable spellings are inf, - +inf, -inf, infinity, - +infinity, and -infinity. Make sure we - recognize these even if the platform's strtod function - doesn't. - - - - - - Expand ability to compare rows to records and arrays (Rafal Rzepecki, - Tom Lane) - - - - - - Update time zone data files to tzdata release 2013d - for DST law changes in Israel, Morocco, Palestine, and Paraguay. - Also, historical zone data corrections for Macquarie Island. - - - - - - - - - - Release 8.4.17 - - - Release date: - 2013-04-04 - - - - This release contains a variety of fixes from 8.4.16. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.17 - - - A dump/restore is not required for those running 8.4.X. - - - - However, this release corrects several errors in management of GiST - indexes. After installing this update, it is advisable to - REINDEX any GiST indexes that meet one or more of the - conditions described below. - - - - Also, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Reset OpenSSL randomness state in each postmaster child process - (Marko Kreen) - - - - This avoids a scenario wherein random numbers generated by - contrib/pgcrypto functions might be relatively easy for - another database user to guess. The risk is only significant when - the postmaster is configured with ssl = on - but most connections don't use SSL encryption. (CVE-2013-1900) - - - - - - Fix GiST indexes to not use fuzzy geometric comparisons when - it's not appropriate to do so (Alexander Korotkov) - - - - The core geometric types perform comparisons using fuzzy - equality, but gist_box_same must do exact comparisons, - else GiST indexes using it might become inconsistent. After installing - this update, users should REINDEX any GiST indexes on - box, polygon, circle, or point - columns, since all of these use gist_box_same. - - - - - - Fix erroneous range-union and penalty logic in GiST indexes that use - contrib/btree_gist for variable-width data types, that is - text, bytea, bit, and numeric - columns (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in useless - index bloat. Users are advised to REINDEX such indexes - after installing this update. - - - - - - Fix bugs in GiST page splitting code for multi-column indexes - (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in indexes - that are unnecessarily inefficient to search. Users are advised to - REINDEX multi-column GiST indexes after installing this - update. - - - - - - Fix infinite-loop risk in regular expression compilation (Tom Lane, - Don Porter) - - - - - - Fix potential null-pointer dereference in regular expression compilation - (Tom Lane) - - - - - - Fix to_char() to use ASCII-only case-folding rules where - appropriate (Tom Lane) - - - - This fixes misbehavior of some template patterns that should be - locale-independent, but mishandled I and - i in Turkish locales. - - - - - - Fix unwanted rejection of timestamp 1999-12-31 24:00:00 - (Tom Lane) - - - - - - Remove useless picksplit doesn't support secondary split log - messages (Josh Hansen, Tom Lane) - - - - This message seems to have been added in expectation of code that was - never written, and probably never will be, since GiST's default - handling of secondary splits is actually pretty good. So stop nagging - end users about it. - - - - - - Fix possible failure to send a session's last few transaction - commit/abort counts to the statistics collector (Tom Lane) - - - - - - Eliminate memory leaks in PL/Perl's spi_prepare() function - (Alex Hunsaker, Tom Lane) - - - - - - Fix pg_dumpall to handle database names containing - = correctly (Heikki Linnakangas) - - - - - - Avoid crash in pg_dump when an incorrect connection - string is given (Heikki Linnakangas) - - - - - - Ignore invalid indexes in pg_dump (Michael Paquier) - - - - Dumping invalid indexes can cause problems at restore time, for example - if the reason the index creation failed was because it tried to enforce - a uniqueness condition not satisfied by the table's data. Also, if the - index creation is in fact still in progress, it seems reasonable to - consider it to be an uncommitted DDL change, which - pg_dump wouldn't be expected to dump anyway. - - - - - - Fix contrib/pg_trgm's similarity() function - to return zero for trigram-less strings (Tom Lane) - - - - Previously it returned NaN due to internal division by zero. - - - - - - Update time zone data files to tzdata release 2013b - for DST law changes in Chile, Haiti, Morocco, Paraguay, and some - Russian areas. Also, historical zone data corrections for numerous - places. - - - - Also, update the time zone abbreviation files for recent changes in - Russia and elsewhere: CHOT, GET, - IRKT, KGT, KRAT, MAGT, - MAWT, MSK, NOVT, OMST, - TKT, VLAT, WST, YAKT, - YEKT now follow their current meanings, and - VOLT (Europe/Volgograd) and MIST - (Antarctica/Macquarie) are added to the default abbreviations list. - - - - - - - - - - Release 8.4.16 - - - Release date: - 2013-02-07 - - - - This release contains a variety of fixes from 8.4.15. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.16 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Prevent execution of enum_recv from SQL (Tom Lane) - - - - The function was misdeclared, allowing a simple SQL command to crash the - server. In principle an attacker might be able to use it to examine the - contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) - for reporting this issue. (CVE-2013-0255) - - - - - - Update minimum recovery point when truncating a relation file (Heikki - Linnakangas) - - - - Once data has been discarded, it's no longer safe to stop recovery at - an earlier point in the timeline. - - - - - - Fix SQL grammar to allow subscripting or field selection from a - sub-SELECT result (Tom Lane) - - - - - - Protect against race conditions when scanning - pg_tablespace (Stephen Frost, Tom Lane) - - - - CREATE DATABASE and DROP DATABASE could - misbehave if there were concurrent updates of - pg_tablespace entries. - - - - - - Prevent DROP OWNED from trying to drop whole databases or - tablespaces (Álvaro Herrera) - - - - For safety, ownership of these objects must be reassigned, not dropped. - - - - - - Fix error in vacuum_freeze_table_age - implementation (Andres Freund) - - - - In installations that have existed for more than vacuum_freeze_min_age - transactions, this mistake prevented autovacuum from using partial-table - scans, so that a full-table scan would always happen instead. - - - - - - Prevent misbehavior when a RowExpr or XmlExpr - is parse-analyzed twice (Andres Freund, Tom Lane) - - - - This mistake could be user-visible in contexts such as - CREATE TABLE LIKE INCLUDING INDEXES. - - - - - - Improve defenses against integer overflow in hashtable sizing - calculations (Jeff Davis) - - - - - - Reject out-of-range dates in to_date() (Hitoshi Harada) - - - - - - Ensure that non-ASCII prompt strings are translated to the correct - code page on Windows (Alexander Law, Noah Misch) - - - - This bug affected psql and some other client programs. - - - - - - Fix possible crash in psql's \? command - when not connected to a database (Meng Qingzhong) - - - - - - Fix one-byte buffer overrun in libpq's - PQprintTuples (Xi Wang) - - - - This ancient function is not used anywhere by - PostgreSQL itself, but it might still be used by some - client code. - - - - - - Make ecpglib use translated messages properly - (Chen Huajun) - - - - - - Properly install ecpg_compat and - pgtypes libraries on MSVC (Jiang Guiqing) - - - - - - Rearrange configure's tests for supplied functions so it is not - fooled by bogus exports from libedit/libreadline (Christoph Berg) - - - - - - Ensure Windows build number increases over time (Magnus Hagander) - - - - - - Make pgxs build executables with the right - .exe suffix when cross-compiling for Windows - (Zoltan Boszormenyi) - - - - - - Add new timezone abbreviation FET (Tom Lane) - - - - This is now used in some eastern-European time zones. - - - - - - - - - - Release 8.4.15 - - - Release date: - 2012-12-06 - - - - This release contains a variety of fixes from 8.4.14. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.15 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Fix multiple bugs associated with CREATE INDEX - CONCURRENTLY (Andres Freund, Tom Lane) - - - - Fix CREATE INDEX CONCURRENTLY to use - in-place updates when changing the state of an index's - pg_index row. This prevents race conditions that could - cause concurrent sessions to miss updating the target index, thus - resulting in corrupt concurrently-created indexes. - - - - Also, fix various other operations to ensure that they ignore - invalid indexes resulting from a failed CREATE INDEX - CONCURRENTLY command. The most important of these is - VACUUM, because an auto-vacuum could easily be launched - on the table before corrective action can be taken to fix or remove - the invalid index. - - - - - - Avoid corruption of internal hash tables when out of memory - (Hitoshi Harada) - - - - - - Fix planning of non-strict equivalence clauses above outer joins - (Tom Lane) - - - - The planner could derive incorrect constraints from a clause equating - a non-strict construct to something else, for example - WHERE COALESCE(foo, 0) = 0 - when foo is coming from the nullable side of an outer join. - - - - - - Improve planner's ability to prove exclusion constraints from - equivalence classes (Tom Lane) - - - - - - Fix partial-row matching in hashed subplans to handle cross-type cases - correctly (Tom Lane) - - - - This affects multicolumn NOT IN subplans, such as - WHERE (a, b) NOT IN (SELECT x, y FROM ...) - when for instance b and y are int4 - and int8 respectively. This mistake led to wrong answers - or crashes depending on the specific datatypes involved. - - - - - - Acquire buffer lock when re-fetching the old tuple for an - AFTER ROW UPDATE/DELETE trigger (Andres Freund) - - - - In very unusual circumstances, this oversight could result in passing - incorrect data to the precheck logic for a foreign-key enforcement - trigger. That could result in a crash, or in an incorrect decision - about whether to fire the trigger. - - - - - - Fix ALTER COLUMN TYPE to handle inherited check - constraints properly (Pavan Deolasee) - - - - This worked correctly in pre-8.4 releases, and now works correctly - in 8.4 and later. - - - - - - Fix REASSIGN OWNED to handle grants on tablespaces - (Álvaro Herrera) - - - - - - Ignore incorrect pg_attribute entries for system - columns for views (Tom Lane) - - - - Views do not have any system columns. However, we forgot to - remove such entries when converting a table to a view. That's fixed - properly for 9.3 and later, but in previous branches we need to defend - against existing mis-converted views. - - - - - - Fix rule printing to dump INSERT INTO table - DEFAULT VALUES correctly (Tom Lane) - - - - - - Guard against stack overflow when there are too many - UNION/INTERSECT/EXCEPT clauses - in a query (Tom Lane) - - - - - - Prevent platform-dependent failures when dividing the minimum possible - integer value by -1 (Xi Wang, Tom Lane) - - - - - - Fix possible access past end of string in date parsing - (Hitoshi Harada) - - - - - - Produce an understandable error message if the length of the path name - for a Unix-domain socket exceeds the platform-specific limit - (Tom Lane, Andrew Dunstan) - - - - Formerly, this would result in something quite unhelpful, such as - Non-recoverable failure in name resolution. - - - - - - Fix memory leaks when sending composite column values to the client - (Tom Lane) - - - - - - Make pg_ctl more robust about reading the - postmaster.pid file (Heikki Linnakangas) - - - - Fix race conditions and possible file descriptor leakage. - - - - - - Fix possible crash in psql if incorrectly-encoded data - is presented and the client_encoding setting is a - client-only encoding, such as SJIS (Jiang Guiqing) - - - - - - Fix bugs in the restore.sql script emitted by - pg_dump in tar output format (Tom Lane) - - - - The script would fail outright on tables whose names include - upper-case characters. Also, make the script capable of restoring - data in mode as well as the regular COPY mode. - - - - - - Fix pg_restore to accept POSIX-conformant - tar files (Brian Weaver, Tom Lane) - - - - The original coding of pg_dump's tar - output mode produced files that are not fully conformant with the - POSIX standard. This has been corrected for version 9.3. This - patch updates previous branches so that they will accept both the - incorrect and the corrected formats, in hopes of avoiding - compatibility problems when 9.3 comes out. - - - - - - Fix pg_resetxlog to locate postmaster.pid - correctly when given a relative path to the data directory (Tom Lane) - - - - This mistake could lead to pg_resetxlog not noticing - that there is an active postmaster using the data directory. - - - - - - Fix libpq's lo_import() and - lo_export() functions to report file I/O errors properly - (Tom Lane) - - - - - - Fix ecpg's processing of nested structure pointer - variables (Muhammad Usama) - - - - - - Make contrib/pageinspect's btree page inspection - functions take buffer locks while examining pages (Tom Lane) - - - - - - Fix pgxs support for building loadable modules on AIX - (Tom Lane) - - - - Building modules outside the original source tree didn't work on AIX. - - - - - - Update time zone data files to tzdata release 2012j - for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western - Samoa, and portions of Brazil. - - - - - - - - - - Release 8.4.14 - - - Release date: - 2012-09-24 - - - - This release contains a variety of fixes from 8.4.13. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.14 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Fix planner's assignment of executor parameters, and fix executor's - rescan logic for CTE plan nodes (Tom Lane) - - - - These errors could result in wrong answers from queries that scan the - same WITH subquery multiple times. - - - - - - Improve page-splitting decisions in GiST indexes (Alexander Korotkov, - Robert Haas, Tom Lane) - - - - Multi-column GiST indexes might suffer unexpected bloat due to this - error. - - - - - - Fix cascading privilege revoke to stop if privileges are still held - (Tom Lane) - - - - If we revoke a grant option from some role X, but - X still holds that option via a grant from someone - else, we should not recursively revoke the corresponding privilege - from role(s) Y that X had granted it - to. - - - - - - Fix handling of SIGFPE when PL/Perl is in use (Andres Freund) - - - - Perl resets the process's SIGFPE handler to - SIG_IGN, which could result in crashes later on. Restore - the normal Postgres signal handler after initializing PL/Perl. - - - - - - Prevent PL/Perl from crashing if a recursive PL/Perl function is - redefined while being executed (Tom Lane) - - - - - - Work around possible misoptimization in PL/Perl (Tom Lane) - - - - Some Linux distributions contain an incorrect version of - pthread.h that results in incorrect compiled code in - PL/Perl, leading to crashes if a PL/Perl function calls another one - that throws an error. - - - - - - Update time zone data files to tzdata release 2012f - for DST law changes in Fiji - - - - - - - - - - Release 8.4.13 - - - Release date: - 2012-08-17 - - - - This release contains a variety of fixes from 8.4.12. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.13 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Prevent access to external files/URLs via XML entity references - (Noah Misch, Tom Lane) - - - - xml_parse() would attempt to fetch external files or - URLs as needed to resolve DTD and entity references in an XML value, - thus allowing unprivileged database users to attempt to fetch data - with the privileges of the database server. While the external data - wouldn't get returned directly to the user, portions of it could be - exposed in error messages if the data didn't parse as valid XML; and - in any case the mere ability to check existence of a file might be - useful to an attacker. (CVE-2012-3489) - - - - - - Prevent access to external files/URLs via contrib/xml2's - xslt_process() (Peter Eisentraut) - - - - libxslt offers the ability to read and write both - files and URLs through stylesheet commands, thus allowing - unprivileged database users to both read and write data with the - privileges of the database server. Disable that through proper use - of libxslt's security options. (CVE-2012-3488) - - - - Also, remove xslt_process()'s ability to fetch documents - and stylesheets from external files/URLs. While this was a - documented feature, it was long regarded as a bad idea. - The fix for CVE-2012-3489 broke that capability, and rather than - expend effort on trying to fix it, we're just going to summarily - remove it. - - - - - - Prevent too-early recycling of btree index pages (Noah Misch) - - - - When we allowed read-only transactions to skip assigning XIDs, we - introduced the possibility that a deleted btree page could be - recycled while a read-only transaction was still in flight to it. - This would result in incorrect index search results. The probability - of such an error occurring in the field seems very low because of the - timing requirements, but nonetheless it should be fixed. - - - - - - Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane) - - - - If ALTER SEQUENCE was executed on a freshly created or - reset sequence, and then precisely one nextval() call - was made on it, and then the server crashed, WAL replay would restore - the sequence to a state in which it appeared that no - nextval() had been done, thus allowing the first - sequence value to be returned again by the next - nextval() call. In particular this could manifest for - serial columns, since creation of a serial column's sequence - includes an ALTER SEQUENCE OWNED BY step. - - - - - - Ensure the backup_label file is fsync'd after - pg_start_backup() (Dave Kerr) - - - - - - Back-patch 9.1 improvement to compress the fsync request queue - (Robert Haas) - - - - This improves performance during checkpoints. The 9.1 change - has now seen enough field testing to seem safe to back-patch. - - - - - - Only allow autovacuum to be auto-canceled by a directly blocked - process (Tom Lane) - - - - The original coding could allow inconsistent behavior in some cases; - in particular, an autovacuum could get canceled after less than - deadlock_timeout grace period. - - - - - - Improve logging of autovacuum cancels (Robert Haas) - - - - - - Fix log collector so that log_truncate_on_rotation works - during the very first log rotation after server start (Tom Lane) - - - - - - Fix WITH attached to a nested set operation - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Ensure that a whole-row reference to a subquery doesn't include any - extra GROUP BY or ORDER BY columns (Tom Lane) - - - - - - Disallow copying whole-row references in CHECK - constraints and index definitions during CREATE TABLE - (Tom Lane) - - - - This situation can arise in CREATE TABLE with - LIKE or INHERITS. The copied whole-row - variable was incorrectly labeled with the row type of the original - table not the new one. Rejecting the case seems reasonable for - LIKE, since the row types might well diverge later. For - INHERITS we should ideally allow it, with an implicit - coercion to the parent table's row type; but that will require more - work than seems safe to back-patch. - - - - - - Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki - Linnakangas, Tom Lane) - - - - - - Fix extraction of common prefixes from regular expressions (Tom Lane) - - - - The code could get confused by quantified parenthesized - subexpressions, such as ^(foo)?bar. This would lead to - incorrect index optimization of searches for such patterns. - - - - - - Fix bugs with parsing signed - hh:mm and - hh:mm:ss - fields in interval constants (Amit Kapila, Tom Lane) - - - - - - Report errors properly in contrib/xml2's - xslt_process() (Tom Lane) - - - - - - Update time zone data files to tzdata release 2012e - for DST law changes in Morocco and Tokelau - - - - - - - - - - Release 8.4.12 - - - Release date: - 2012-06-04 - - - - This release contains a variety of fixes from 8.4.11. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.12 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Fix incorrect password transformation in - contrib/pgcrypto's DES crypt() function - (Solar Designer) - - - - If a password string contained the byte value 0x80, the - remainder of the password was ignored, causing the password to be much - weaker than it appeared. With this fix, the rest of the string is - properly included in the DES hash. Any stored password values that are - affected by this bug will thus no longer match, so the stored values may - need to be updated. (CVE-2012-2143) - - - - - - Ignore SECURITY DEFINER and SET attributes for - a procedural language's call handler (Tom Lane) - - - - Applying such attributes to a call handler could crash the server. - (CVE-2012-2655) - - - - - - Allow numeric timezone offsets in timestamp input to be up to - 16 hours away from UTC (Tom Lane) - - - - Some historical time zones have offsets larger than 15 hours, the - previous limit. This could result in dumped data values being rejected - during reload. - - - - - - Fix timestamp conversion to cope when the given time is exactly the - last DST transition time for the current timezone (Tom Lane) - - - - This oversight has been there a long time, but was not noticed - previously because most DST-using zones are presumed to have an - indefinite sequence of future DST transitions. - - - - - - Fix text to name and char to name - casts to perform string truncation correctly in multibyte encodings - (Karl Schnaitter) - - - - - - Fix memory copying bug in to_tsquery() (Heikki Linnakangas) - - - - - - Fix planner's handling of outer PlaceHolderVars within subqueries (Tom - Lane) - - - - This bug concerns sub-SELECTs that reference variables coming from the - nullable side of an outer join of the surrounding query. - In 9.1, queries affected by this bug would fail with ERROR: - Upper-level PlaceHolderVar found where not expected. But in 9.0 and - 8.4, you'd silently get possibly-wrong answers, since the value - transmitted into the subquery wouldn't go to null when it should. - - - - - - Fix slow session startup when pg_attribute is very large - (Tom Lane) - - - - If pg_attribute exceeds one-fourth of - shared_buffers, cache rebuilding code that is sometimes - needed during session start would trigger the synchronized-scan logic, - causing it to take many times longer than normal. The problem was - particularly acute if many new sessions were starting at once. - - - - - - Ensure sequential scans check for query cancel reasonably often (Merlin - Moncure) - - - - A scan encountering many consecutive pages that contain no live tuples - would not respond to interrupts meanwhile. - - - - - - Ensure the Windows implementation of PGSemaphoreLock() - clears ImmediateInterruptOK before returning (Tom Lane) - - - - This oversight meant that a query-cancel interrupt received later - in the same query could be accepted at an unsafe time, with - unpredictable but not good consequences. - - - - - - Show whole-row variables safely when printing views or rules - (Abbas Butt, Tom Lane) - - - - Corner cases involving ambiguous names (that is, the name could be - either a table or column name of the query) were printed in an - ambiguous way, risking that the view or rule would be interpreted - differently after dump and reload. Avoid the ambiguous case by - attaching a no-op cast. - - - - - - Fix COPY FROM to properly handle null marker strings that - correspond to invalid encoding (Tom Lane) - - - - A null marker string such as E'\\0' should work, and did - work in the past, but the case got broken in 8.4. - - - - - - Ensure autovacuum worker processes perform stack depth checking - properly (Heikki Linnakangas) - - - - Previously, infinite recursion in a function invoked by - auto-ANALYZE could crash worker processes. - - - - - - Fix logging collector to not lose log coherency under high load (Andrew - Dunstan) - - - - The collector previously could fail to reassemble large messages if it - got too busy. - - - - - - Fix logging collector to ensure it will restart file rotation - after receiving SIGHUP (Tom Lane) - - - - - - Fix WAL replay logic for GIN indexes to not fail if the index was - subsequently dropped (Tom Lane) - - - - - - Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe - Conway) - - - - - - Fix PL/pgSQL's GET DIAGNOSTICS command when the target - is the function's first variable (Tom Lane) - - - - - - Fix potential access off the end of memory in psql's - expanded display (\x) mode (Peter Eisentraut) - - - - - - Fix several performance problems in pg_dump when - the database contains many objects (Jeff Janes, Tom Lane) - - - - pg_dump could get very slow if the database contained - many schemas, or if many objects are in dependency loops, or if there - are many owned sequences. - - - - - - Fix contrib/dblink's dblink_exec() to not leak - temporary database connections upon error (Tom Lane) - - - - - - Fix contrib/dblink to report the correct connection name in - error messages (Kyotaro Horiguchi) - - - - - - Update time zone data files to tzdata release 2012c - for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland - Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; - also historical corrections for Canada. - - - - - - - - - - Release 8.4.11 - - - Release date: - 2012-02-27 - - - - This release contains a variety of fixes from 8.4.10. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.11 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.10, - see . - - - - - - Changes - - - - - - Require execute permission on the trigger function for - CREATE TRIGGER (Robert Haas) - - - - This missing check could allow another user to execute a trigger - function with forged input data, by installing it on a table he owns. - This is only of significance for trigger functions marked - SECURITY DEFINER, since otherwise trigger functions run - as the table owner anyway. (CVE-2012-0866) - - - - - - Remove arbitrary limitation on length of common name in SSL - certificates (Heikki Linnakangas) - - - - Both libpq and the server truncated the common name - extracted from an SSL certificate at 32 bytes. Normally this would - cause nothing worse than an unexpected verification failure, but there - are some rather-implausible scenarios in which it might allow one - certificate holder to impersonate another. The victim would have to - have a common name exactly 32 bytes long, and the attacker would have - to persuade a trusted CA to issue a certificate in which the common - name has that string as a prefix. Impersonating a server would also - require some additional exploit to redirect client connections. - (CVE-2012-0867) - - - - - - Convert newlines to spaces in names written in pg_dump - comments (Robert Haas) - - - - pg_dump was incautious about sanitizing object names - that are emitted within SQL comments in its output script. A name - containing a newline would at least render the script syntactically - incorrect. Maliciously crafted object names could present a SQL - injection risk when the script is reloaded. (CVE-2012-0868) - - - - - - Fix btree index corruption from insertions concurrent with vacuuming - (Tom Lane) - - - - An index page split caused by an insertion could sometimes cause a - concurrently-running VACUUM to miss removing index entries - that it should remove. After the corresponding table rows are removed, - the dangling index entries would cause errors (such as could not - read block N in file ...) or worse, silently wrong query results - after unrelated rows are re-inserted at the now-free table locations. - This bug has been present since release 8.2, but occurs so infrequently - that it was not diagnosed until now. If you have reason to suspect - that it has happened in your database, reindexing the affected index - will fix things. - - - - - - Update per-column permissions, not only per-table permissions, when - changing table owner (Tom Lane) - - - - Failure to do this meant that any previously granted column permissions - were still shown as having been granted by the old owner. This meant - that neither the new owner nor a superuser could revoke the - now-untraceable-to-table-owner permissions. - - - - - - Allow non-existent values for some settings in ALTER - USER/DATABASE SET (Heikki Linnakangas) - - - - Allow default_text_search_config, - default_tablespace, and temp_tablespaces to be - set to names that are not known. This is because they might be known - in another database where the setting is intended to be used, or for the - tablespace cases because the tablespace might not be created yet. The - same issue was previously recognized for search_path, and - these settings now act like that one. - - - - - - Avoid crashing when we have problems deleting table files post-commit - (Tom Lane) - - - - Dropping a table should lead to deleting the underlying disk files only - after the transaction commits. In event of failure then (for instance, - because of wrong file permissions) the code is supposed to just emit a - warning message and go on, since it's too late to abort the - transaction. This logic got broken as of release 8.4, causing such - situations to result in a PANIC and an unrestartable database. - - - - - - Track the OID counter correctly during WAL replay, even when it wraps - around (Tom Lane) - - - - Previously the OID counter would remain stuck at a high value until the - system exited replay mode. The practical consequences of that are - usually nil, but there are scenarios wherein a standby server that's - been promoted to master might take a long time to advance the OID - counter to a reasonable value once values are needed. - - - - - - Fix regular expression back-references with * attached - (Tom Lane) - - - - Rather than enforcing an exact string match, the code would effectively - accept any string that satisfies the pattern sub-expression referenced - by the back-reference symbol. - - - - A similar problem still afflicts back-references that are embedded in a - larger quantified expression, rather than being the immediate subject - of the quantifier. This will be addressed in a future - PostgreSQL release. - - - - - - Fix recently-introduced memory leak in processing of - inet/cidr values (Heikki Linnakangas) - - - - A patch in the December 2011 releases of PostgreSQL - caused memory leakage in these operations, which could be significant - in scenarios such as building a btree index on such a column. - - - - - - Fix dangling pointer after CREATE TABLE AS/SELECT - INTO in a SQL-language function (Tom Lane) - - - - In most cases this only led to an assertion failure in assert-enabled - builds, but worse consequences seem possible. - - - - - - Avoid double close of file handle in syslogger on Windows (MauMau) - - - - Ordinarily this error was invisible, but it would cause an exception - when running on a debug version of Windows. - - - - - - Fix I/O-conversion-related memory leaks in plpgsql - (Andres Freund, Jan Urbanski, Tom Lane) - - - - Certain operations would leak memory until the end of the current - function. - - - - - - Improve pg_dump's handling of inherited table columns - (Tom Lane) - - - - pg_dump mishandled situations where a child column has - a different default expression than its parent column. If the default - is textually identical to the parent's default, but not actually the - same (for instance, because of schema search path differences) it would - not be recognized as different, so that after dump and restore the - child would be allowed to inherit the parent's default. Child columns - that are NOT NULL where their parent is not could also be - restored subtly incorrectly. - - - - - - Fix pg_restore's direct-to-database mode for - INSERT-style table data (Tom Lane) - - - - Direct-to-database restores from archive files made with - or options fail when - using pg_restore from a release dated September or - December 2011, as a result of an oversight in a fix for another - problem. The archive file itself is not at fault, and text-mode - output is okay. - - - - - - Allow AT option in ecpg - DEALLOCATE statements (Michael Meskes) - - - - The infrastructure to support this has been there for awhile, but - through an oversight there was still an error check rejecting the case. - - - - - - Fix error in contrib/intarray's int[] & - int[] operator (Guillaume Lelarge) - - - - If the smallest integer the two input arrays have in common is 1, - and there are smaller values in either array, then 1 would be - incorrectly omitted from the result. - - - - - - Fix error detection in contrib/pgcrypto's - encrypt_iv() and decrypt_iv() - (Marko Kreen) - - - - These functions failed to report certain types of invalid-input errors, - and would instead return random garbage values for incorrect input. - - - - - - Fix one-byte buffer overrun in contrib/test_parser - (Paul Guyot) - - - - The code would try to read one more byte than it should, which would - crash in corner cases. - Since contrib/test_parser is only example code, this is - not a security issue in itself, but bad example code is still bad. - - - - - - Use __sync_lock_test_and_set() for spinlocks on ARM, if - available (Martin Pitt) - - - - This function replaces our previous use of the SWPB - instruction, which is deprecated and not available on ARMv6 and later. - Reports suggest that the old code doesn't fail in an obvious way on - recent ARM boards, but simply doesn't interlock concurrent accesses, - leading to bizarre failures in multiprocess operation. - - - - - - Use option when building with - gcc versions that accept it (Andrew Dunstan) - - - - This prevents assorted scenarios wherein recent versions of gcc will - produce creative results. - - - - - - Allow use of threaded Python on FreeBSD (Chris Rees) - - - - Our configure script previously believed that this combination wouldn't - work; but FreeBSD fixed the problem, so remove that error check. - - - - - - - - - - Release 8.4.10 - - - Release date: - 2011-12-05 - - - - This release contains a variety of fixes from 8.4.9. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.10 - - - A dump/restore is not required for those running 8.4.X. - - - - However, a longstanding error was discovered in the definition of the - information_schema.referential_constraints view. If you - rely on correct results from that view, you should replace its - definition as explained in the first changelog item below. - - - - Also, if you are upgrading from a version earlier than 8.4.8, - see . - - - - - - Changes - - - - - - Fix bugs in information_schema.referential_constraints view - (Tom Lane) - - - - This view was being insufficiently careful about matching the - foreign-key constraint to the depended-on primary or unique key - constraint. That could result in failure to show a foreign key - constraint at all, or showing it multiple times, or claiming that it - depends on a different constraint than the one it really does. - - - - Since the view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can (as a superuser) drop the - information_schema schema then re-create it by sourcing - SHAREDIR/information_schema.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) This must be repeated in each database - to be fixed. - - - - - - Fix incorrect replay of WAL records for GIN index updates - (Tom Lane) - - - - This could result in transiently failing to find index entries after - a crash, or on a hot-standby server. The problem would be repaired - by the next VACUUM of the index, however. - - - - - - Fix TOAST-related data corruption during CREATE TABLE dest AS - SELECT * FROM src or INSERT INTO dest SELECT * FROM src - (Tom Lane) - - - - If a table has been modified by ALTER TABLE ADD COLUMN, - attempts to copy its data verbatim to another table could produce - corrupt results in certain corner cases. - The problem can only manifest in this precise form in 8.4 and later, - but we patched earlier versions as well in case there are other code - paths that could trigger the same bug. - - - - - - Fix race condition during toast table access from stale syscache entries - (Tom Lane) - - - - The typical symptom was transient errors like missing chunk - number 0 for toast value NNNNN in pg_toast_2619, where the cited - toast table would always belong to a system catalog. - - - - - - Track dependencies of functions on items used in parameter default - expressions (Tom Lane) - - - - Previously, a referenced object could be dropped without having dropped - or modified the function, leading to misbehavior when the function was - used. Note that merely installing this update will not fix the missing - dependency entries; to do that, you'd need to CREATE OR - REPLACE each such function afterwards. If you have functions whose - defaults depend on non-built-in objects, doing so is recommended. - - - - - - Allow inlining of set-returning SQL functions with multiple OUT - parameters (Tom Lane) - - - - - - Make DatumGetInetP() unpack inet datums that have a 1-byte - header, and add a new macro, DatumGetInetPP(), that does - not (Heikki Linnakangas) - - - - This change affects no core code, but might prevent crashes in add-on - code that expects DatumGetInetP() to produce an unpacked - datum as per usual convention. - - - - - - Improve locale support in money type's input and output - (Tom Lane) - - - - Aside from not supporting all standard - lc_monetary - formatting options, the input and output functions were inconsistent, - meaning there were locales in which dumped money values could - not be re-read. - - - - - - Don't let transform_null_equals - affect CASE foo WHEN NULL ... constructs - (Heikki Linnakangas) - - - - transform_null_equals is only supposed to affect - foo = NULL expressions written directly by the user, not - equality checks generated internally by this form of CASE. - - - - - - Change foreign-key trigger creation order to better support - self-referential foreign keys (Tom Lane) - - - - For a cascading foreign key that references its own table, a row update - will fire both the ON UPDATE trigger and the - CHECK trigger as one event. The ON UPDATE - trigger must execute first, else the CHECK will check a - non-final state of the row and possibly throw an inappropriate error. - However, the firing order of these triggers is determined by their - names, which generally sort in creation order since the triggers have - auto-generated names following the convention - RI_ConstraintTrigger_NNNN. A proper fix would require - modifying that convention, which we will do in 9.2, but it seems risky - to change it in existing releases. So this patch just changes the - creation order of the triggers. Users encountering this type of error - should drop and re-create the foreign key constraint to get its - triggers into the right order. - - - - - - Avoid floating-point underflow while tracking buffer allocation rate - (Greg Matthews) - - - - While harmless in itself, on certain platforms this would result in - annoying kernel log messages. - - - - - - Preserve configuration file name and line number values when starting - child processes under Windows (Tom Lane) - - - - Formerly, these would not be displayed correctly in the - pg_settings view. - - - - - - Preserve blank lines within commands in psql's command - history (Robert Haas) - - - - The former behavior could cause problems if an empty line was removed - from within a string literal, for example. - - - - - - Fix pg_dump to dump user-defined casts between - auto-generated types, such as table rowtypes (Tom Lane) - - - - - - Use the preferred version of xsubpp to build PL/Perl, - not necessarily the operating system's main copy - (David Wheeler and Alex Hunsaker) - - - - - - Fix incorrect coding in contrib/dict_int and - contrib/dict_xsyn (Tom Lane) - - - - Some functions incorrectly assumed that memory returned by - palloc() is guaranteed zeroed. - - - - - - Honor query cancel interrupts promptly in pgstatindex() - (Robert Haas) - - - - - - Ensure VPATH builds properly install all server header files - (Peter Eisentraut) - - - - - - Shorten file names reported in verbose error messages (Peter Eisentraut) - - - - Regular builds have always reported just the name of the C file - containing the error message call, but VPATH builds formerly - reported an absolute path name. - - - - - - Fix interpretation of Windows timezone names for Central America - (Tom Lane) - - - - Map Central America Standard Time to CST6, not - CST6CDT, because DST is generally not observed anywhere in - Central America. - - - - - - Update time zone data files to tzdata release 2011n - for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa; - also historical corrections for Alaska and British East Africa. - - - - - - - - - - Release 8.4.9 - - - Release date: - 2011-09-26 - - - - This release contains a variety of fixes from 8.4.8. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.9 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if you are upgrading from a version earlier than 8.4.8, - see . - - - - - - Changes - - - - - - Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane) - - - - These bugs could result in index corruption after reindexing a system - catalog. They are not believed to affect user indexes. - - - - - - Fix multiple bugs in GiST index page split processing (Heikki - Linnakangas) - - - - The probability of occurrence was low, but these could lead to index - corruption. - - - - - - Fix possible buffer overrun in tsvector_concat() - (Tom Lane) - - - - The function could underestimate the amount of memory needed for its - result, leading to server crashes. - - - - - - Fix crash in xml_recv when processing a - standalone parameter (Tom Lane) - - - - - - Make pg_options_to_table return NULL for an option with no - value (Tom Lane) - - - - Previously such cases would result in a server crash. - - - - - - Avoid possibly accessing off the end of memory in ANALYZE - and in SJIS-2004 encoding conversion (Noah Misch) - - - - This fixes some very-low-probability server crash scenarios. - - - - - - Prevent intermittent hang in interactions of startup process with - bgwriter process (Simon Riggs) - - - - This affected recovery in non-hot-standby cases. - - - - - - Fix race condition in relcache init file invalidation (Tom Lane) - - - - There was a window wherein a new backend process could read a stale init - file but miss the inval messages that would tell it the data is stale. - The result would be bizarre failures in catalog accesses, typically - could not read block 0 in file ... later during startup. - - - - - - Fix memory leak at end of a GiST index scan (Tom Lane) - - - - Commands that perform many separate GiST index scans, such as - verification of a new GiST-based exclusion constraint on a table - already containing many rows, could transiently require large amounts of - memory due to this leak. - - - - - - Fix incorrect memory accounting (leading to possible memory bloat) in - tuplestores supporting holdable cursors and plpgsql's RETURN - NEXT command (Tom Lane) - - - - - - Fix performance problem when constructing a large, lossy bitmap - (Tom Lane) - - - - - - Fix join selectivity estimation for unique columns (Tom Lane) - - - - This fixes an erroneous planner heuristic that could lead to poor - estimates of the result size of a join. - - - - - - Fix nested PlaceHolderVar expressions that appear only in sub-select - target lists (Tom Lane) - - - - This mistake could result in outputs of an outer join incorrectly - appearing as NULL. - - - - - - Allow nested EXISTS queries to be optimized properly (Tom - Lane) - - - - - - Fix array- and path-creating functions to ensure padding bytes are - zeroes (Tom Lane) - - - - This avoids some situations where the planner will think that - semantically-equal constants are not equal, resulting in poor - optimization. - - - - - - Fix EXPLAIN to handle gating Result nodes within - inner-indexscan subplans (Tom Lane) - - - - The usual symptom of this oversight was bogus varno errors. - - - - - - Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane) - - - - This could lead to loss of committed transactions after a server crash. - - - - - - Fix dump bug for VALUES in a view (Tom Lane) - - - - - - Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane) - - - - This operation doesn't work as expected and can lead to failures. - - - - - - Fix VACUUM so that it always updates - pg_class.reltuples/relpages (Tom - Lane) - - - - This fixes some scenarios where autovacuum could make increasingly poor - decisions about when to vacuum tables. - - - - - - Defend against integer overflow when computing size of a hash table (Tom - Lane) - - - - - - Fix cases where CLUSTER might attempt to access - already-removed TOAST data (Tom Lane) - - - - - - Fix portability bugs in use of credentials control messages for - peer authentication (Tom Lane) - - - - - - Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, - Magnus Hagander) - - - - The typical symptom of this problem was The function requested is - not supported errors during SSPI login. - - - - - - Throw an error if pg_hba.conf contains hostssl - but SSL is disabled (Tom Lane) - - - - This was concluded to be more user-friendly than the previous behavior - of silently ignoring such lines. - - - - - - Fix typo in pg_srand48 seed initialization (Andres Freund) - - - - This led to failure to use all bits of the provided seed. This function - is not used on most platforms (only those without srandom), - and the potential security exposure from a less-random-than-expected - seed seems minimal in any case. - - - - - - Avoid integer overflow when the sum of LIMIT and - OFFSET values exceeds 2^63 (Heikki Linnakangas) - - - - - - Add overflow checks to int4 and int8 versions of - generate_series() (Robert Haas) - - - - - - Fix trailing-zero removal in to_char() (Marti Raudsepp) - - - - In a format with FM and no digit positions - after the decimal point, zeroes to the left of the decimal point could - be removed incorrectly. - - - - - - Fix pg_size_pretty() to avoid overflow for inputs close to - 2^63 (Tom Lane) - - - - - - Weaken plpgsql's check for typmod matching in record values (Tom Lane) - - - - An overly enthusiastic check could lead to discarding length modifiers - that should have been kept. - - - - - - Correctly handle quotes in locale names during initdb - (Heikki Linnakangas) - - - - The case can arise with some Windows locales, such as People's - Republic of China. - - - - - - Fix pg_upgrade to preserve toast tables' relfrozenxids - during an upgrade from 8.3 (Bruce Momjian) - - - - Failure to do this could lead to pg_clog files being - removed too soon after the upgrade. - - - - - - In pg_ctl, support silent mode for service registrations - on Windows (MauMau) - - - - - - Fix psql's counting of script file line numbers during - COPY from a different file (Tom Lane) - - - - - - Fix pg_restore's direct-to-database mode for - standard_conforming_strings (Tom Lane) - - - - pg_restore could emit incorrect commands when restoring - directly to a database server from an archive file that had been made - with standard_conforming_strings set to on. - - - - - - Be more user-friendly about unsupported cases for parallel - pg_restore (Tom Lane) - - - - This change ensures that such cases are detected and reported before - any restore actions have been taken. - - - - - - Fix write-past-buffer-end and memory leak in libpq's - LDAP service lookup code (Albe Laurenz) - - - - - - In libpq, avoid failures when using nonblocking I/O - and an SSL connection (Martin Pihlak, Tom Lane) - - - - - - Improve libpq's handling of failures during connection startup - (Tom Lane) - - - - In particular, the response to a server report of fork() - failure during SSL connection startup is now saner. - - - - - - Improve libpq's error reporting for SSL failures (Tom - Lane) - - - - - - Fix PQsetvalue() to avoid possible crash when adding a new - tuple to a PGresult originally obtained from a server - query (Andrew Chernow) - - - - - - Make ecpglib write double values with 15 digits - precision (Akira Kurosawa) - - - - - - In ecpglib, be sure LC_NUMERIC setting is - restored after an error (Michael Meskes) - - - - - - Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) - (Tom Lane) - - - - contrib/pg_crypto's blowfish encryption code could give - wrong results on platforms where char is signed (which is most), - leading to encrypted passwords being weaker than they should be. - - - - - - Fix memory leak in contrib/seg (Heikki Linnakangas) - - - - - - Fix pgstatindex() to give consistent results for empty - indexes (Tom Lane) - - - - - - Allow building with perl 5.14 (Alex Hunsaker) - - - - - - Update configure script's method for probing existence of system - functions (Tom Lane) - - - - The version of autoconf we used in 8.3 and 8.2 could be fooled by - compilers that perform link-time optimization. - - - - - - Fix assorted issues with build and install file paths containing spaces - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2011i - for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan. - - - - - - - - - - Release 8.4.8 - - - Release date: - 2011-04-18 - - - - This release contains a variety of fixes from 8.4.7. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.8 - - - A dump/restore is not required for those running 8.4.X. - - - - However, if your installation was upgraded from a previous major - release by running pg_upgrade, you should take - action to prevent possible data loss due to a now-fixed bug in - pg_upgrade. The recommended solution is to run - VACUUM FREEZE on all TOAST tables. - More information is available at - http://wiki.postgresql.org/wiki/20110408pg_upgrade_fix. - - - - Also, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Fix pg_upgrade's handling of TOAST tables - (Bruce Momjian) - - - - The pg_class.relfrozenxid value for - TOAST tables was not correctly copied into the new installation - during pg_upgrade. This could later result in - pg_clog files being discarded while they were still - needed to validate tuples in the TOAST tables, leading to - could not access status of transaction failures. - - - - This error poses a significant risk of data loss for installations - that have been upgraded with pg_upgrade. This patch - corrects the problem for future uses of pg_upgrade, - but does not in itself cure the issue in installations that have been - processed with a buggy version of pg_upgrade. - - - - - - Suppress incorrect PD_ALL_VISIBLE flag was incorrectly set - warning (Heikki Linnakangas) - - - - VACUUM would sometimes issue this warning in cases that - are actually valid. - - - - - - Disallow including a composite type in itself (Tom Lane) - - - - This prevents scenarios wherein the server could recurse infinitely - while processing the composite type. While there are some possible - uses for such a structure, they don't seem compelling enough to - justify the effort required to make sure it always works safely. - - - - - - Avoid potential deadlock during catalog cache initialization - (Nikhil Sontakke) - - - - In some cases the cache loading code would acquire share lock on a - system index before locking the index's catalog. This could deadlock - against processes trying to acquire exclusive locks in the other, - more standard order. - - - - - - Fix dangling-pointer problem in BEFORE ROW UPDATE trigger - handling when there was a concurrent update to the target tuple - (Tom Lane) - - - - This bug has been observed to result in intermittent cannot - extract system attribute from virtual tuple failures while trying to - do UPDATE RETURNING ctid. There is a very small probability - of more serious errors, such as generating incorrect index entries for - the updated tuple. - - - - - - Disallow DROP TABLE when there are pending deferred trigger - events for the table (Tom Lane) - - - - Formerly the DROP would go through, leading to - could not open relation with OID nnn errors when the - triggers were eventually fired. - - - - - - Prevent crash triggered by constant-false WHERE conditions during - GEQO optimization (Tom Lane) - - - - - - Improve planner's handling of semi-join and anti-join cases - (Tom Lane) - - - - - - Fix selectivity estimation for text search to account for NULLs - (Jesper Krogh) - - - - - - Improve PL/pgSQL's ability to handle row types with dropped columns - (Pavel Stehule) - - - - This is a back-patch of fixes previously made in 9.0. - - - - - - Fix PL/Python memory leak involving array slices (Daniel Popowich) - - - - - - Fix pg_restore to cope with long lines (over 1KB) in - TOC files (Tom Lane) - - - - - - Put in more safeguards against crashing due to division-by-zero - with overly enthusiastic compiler optimization (Aurelien Jarno) - - - - - - Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane) - - - - There was a hard-wired assumption that this system function was not - available on MIPS hardware on these systems. Use a compile-time test - instead, since more recent versions have it. - - - - - - Fix compilation failures on HP-UX (Heikki Linnakangas) - - - - - - Fix version-incompatibility problem with libintl on - Windows (Hiroshi Inoue) - - - - - - Fix usage of xcopy in Windows build scripts to - work correctly under Windows 7 (Andrew Dunstan) - - - - This affects the build scripts only, not installation or usage. - - - - - - Fix path separator used by pg_regress on Cygwin - (Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2011f - for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa, - and Turkey; also historical corrections for South Australia, Alaska, - and Hawaii. - - - - - - - - - - Release 8.4.7 - - - Release date: - 2011-01-31 - - - - This release contains a variety of fixes from 8.4.6. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.7 - - - A dump/restore is not required for those running 8.4.X. - However, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Avoid failures when EXPLAIN tries to display a simple-form - CASE expression (Tom Lane) - - - - If the CASE's test expression was a constant, the planner - could simplify the CASE into a form that confused the - expression-display code, resulting in unexpected CASE WHEN - clause errors. - - - - - - Fix assignment to an array slice that is before the existing range - of subscripts (Tom Lane) - - - - If there was a gap between the newly added subscripts and the first - pre-existing subscript, the code miscalculated how many entries needed - to be copied from the old array's null bitmap, potentially leading to - data corruption or crash. - - - - - - Avoid unexpected conversion overflow in planner for very distant date - values (Tom Lane) - - - - The date type supports a wider range of dates than can be - represented by the timestamp types, but the planner assumed it - could always convert a date to timestamp with impunity. - - - - - - Fix pg_restore's text output for large objects (BLOBs) - when standard_conforming_strings is on (Tom Lane) - - - - Although restoring directly to a database worked correctly, string - escaping was incorrect if pg_restore was asked for - SQL text output and standard_conforming_strings had been - enabled in the source database. - - - - - - Fix erroneous parsing of tsquery values containing - ... & !(subexpression) | ... (Tom Lane) - - - - Queries containing this combination of operators were not executed - correctly. The same error existed in contrib/intarray's - query_int type and contrib/ltree's - ltxtquery type. - - - - - - Fix buffer overrun in contrib/intarray's input function - for the query_int type (Apple) - - - - This bug is a security risk since the function's return address could - be overwritten. Thanks to Apple Inc's security team for reporting this - issue and supplying the fix. (CVE-2010-4015) - - - - - - Fix bug in contrib/seg's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a seg column. - If you have such an index, consider REINDEXing it after - installing this update. (This is identical to the bug that was fixed in - contrib/cube in the previous update.) - - - - - - - - - - Release 8.4.6 - - - Release date: - 2010-12-16 - - - - This release contains a variety of fixes from 8.4.5. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.6 - - - A dump/restore is not required for those running 8.4.X. - However, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Force the default - wal_sync_method - to be fdatasync on Linux (Tom Lane, Marti Raudsepp) - - - - The default on Linux has actually been fdatasync for many - years, but recent kernel changes caused PostgreSQL to - choose open_datasync instead. This choice did not result - in any performance improvement, and caused outright failures on - certain filesystems, notably ext4 with the - data=journal mount option. - - - - - - Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane) - - - - This could result in bad buffer id: 0 failures or - corruption of index contents during replication. - - - - - - Fix recovery from base backup when the starting checkpoint WAL record - is not in the same WAL segment as its redo point (Jeff Davis) - - - - - - Fix persistent slowdown of autovacuum workers when multiple workers - remain active for a long time (Tom Lane) - - - - The effective vacuum_cost_limit for an autovacuum worker - could drop to nearly zero if it processed enough tables, causing it - to run extremely slowly. - - - - - - Add support for detecting register-stack overrun on IA64 - (Tom Lane) - - - - The IA64 architecture has two hardware stacks. Full - prevention of stack-overrun failures requires checking both. - - - - - - Add a check for stack overflow in copyObject() (Tom Lane) - - - - Certain code paths could crash due to stack overflow given a - sufficiently complex query. - - - - - - Fix detection of page splits in temporary GiST indexes (Heikki - Linnakangas) - - - - It is possible to have a concurrent page split in a - temporary index, if for example there is an open cursor scanning the - index when an insertion is done. GiST failed to detect this case and - hence could deliver wrong results when execution of the cursor - continued. - - - - - - Fix error checking during early connection processing (Tom Lane) - - - - The check for too many child processes was skipped in some cases, - possibly leading to postmaster crash when attempting to add the new - child process to fixed-size arrays. - - - - - - Improve efficiency of window functions (Tom Lane) - - - - Certain cases where a large number of tuples needed to be read in - advance, but work_mem was large enough to allow them all - to be held in memory, were unexpectedly slow. - percent_rank(), cume_dist() and - ntile() in particular were subject to this problem. - - - - - - Avoid memory leakage while ANALYZE'ing complex index - expressions (Tom Lane) - - - - - - Ensure an index that uses a whole-row Var still depends on its table - (Tom Lane) - - - - An index declared like create index i on t (foo(t.*)) - would not automatically get dropped when its table was dropped. - - - - - - Do not inline a SQL function with multiple OUT - parameters (Tom Lane) - - - - This avoids a possible crash due to loss of information about the - expected result rowtype. - - - - - - Behave correctly if ORDER BY, LIMIT, - FOR UPDATE, or WITH is attached to the - VALUES part of INSERT ... VALUES (Tom Lane) - - - - - - Fix constant-folding of COALESCE() expressions (Tom Lane) - - - - The planner would sometimes attempt to evaluate sub-expressions that - in fact could never be reached, possibly leading to unexpected errors. - - - - - - Fix postmaster crash when connection acceptance - (accept() or one of the calls made immediately after it) - fails, and the postmaster was compiled with GSSAPI support (Alexander - Chernikov) - - - - - - Fix missed unlink of temporary files when log_temp_files - is active (Tom Lane) - - - - If an error occurred while attempting to emit the log message, the - unlink was not done, resulting in accumulation of temp files. - - - - - - Add print functionality for InhRelation nodes (Tom Lane) - - - - This avoids a failure when debug_print_parse is enabled - and certain types of query are executed. - - - - - - Fix incorrect calculation of distance from a point to a horizontal - line segment (Tom Lane) - - - - This bug affected several different geometric distance-measurement - operators. - - - - - - Fix incorrect calculation of transaction status in - ecpg (Itagaki Takahiro) - - - - - - Fix PL/pgSQL's handling of simple - expressions to not fail in recursion or error-recovery cases (Tom Lane) - - - - - - Fix PL/Python's handling of set-returning functions - (Jan Urbanski) - - - - Attempts to call SPI functions within the iterator generating a set - result would fail. - - - - - - Fix bug in contrib/cube's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a cube column. - If you have such an index, consider REINDEXing it after - installing this update. - - - - - - Don't emit identifier will be truncated notices in - contrib/dblink except when creating new connections - (Itagaki Takahiro) - - - - - - Fix potential coredump on missing public key in - contrib/pgcrypto (Marti Raudsepp) - - - - - - Fix memory leak in contrib/xml2's XPath query functions - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2010o - for DST law changes in Fiji and Samoa; - also historical corrections for Hong Kong. - - - - - - - - - - Release 8.4.5 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 8.4.4. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.5 - - - A dump/restore is not required for those running 8.4.X. - However, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Prevent possible crashes in pg_get_expr() by disallowing - it from being called with an argument that is not one of the system - catalog columns it's intended to be used with - (Heikki Linnakangas, Tom Lane) - - - - - - Treat exit code 128 (ERROR_WAIT_NO_CHILDREN) as non-fatal on - Windows (Magnus Hagander) - - - - Under high load, Windows processes will sometimes fail at startup with - this error code. Formerly the postmaster treated this as a panic - condition and restarted the whole database, but that seems to be - an overreaction. - - - - - - Fix incorrect placement of placeholder evaluation (Tom Lane) - - - - This bug could result in query outputs being non-null when they - should be null, in cases where the inner side of an outer join - is a sub-select with non-strict expressions in its output list. - - - - - - Fix possible duplicate scans of UNION ALL member relations - (Tom Lane) - - - - - - Fix cannot handle unplanned sub-select error (Tom Lane) - - - - This occurred when a sub-select contains a join alias reference that - expands into an expression containing another sub-select. - - - - - - Fix mishandling of whole-row Vars that reference a view or sub-select - and appear within a nested sub-select (Tom Lane) - - - - - - Fix mishandling of cross-type IN comparisons (Tom Lane) - - - - This could result in failures if the planner tried to implement an - IN join with a sort-then-unique-then-plain-join plan. - - - - - - Fix computation of ANALYZE statistics for tsvector - columns (Jan Urbanski) - - - - The original coding could produce incorrect statistics, leading to - poor plan choices later. - - - - - - Improve planner's estimate of memory used by array_agg(), - string_agg(), and similar aggregate functions - (Hitoshi Harada) - - - - The previous drastic underestimate could lead to out-of-memory failures - due to inappropriate choice of a hash-aggregation plan. - - - - - - Fix failure to mark cached plans as transient (Tom Lane) - - - - If a plan is prepared while CREATE INDEX CONCURRENTLY is - in progress for one of the referenced tables, it is supposed to be - re-planned once the index is ready for use. This was not happening - reliably. - - - - - - Reduce PANIC to ERROR in some occasionally-reported btree failure cases, - and provide additional detail in the resulting error messages - (Tom Lane) - - - - This should improve the system's robustness with corrupted indexes. - - - - - - Fix incorrect search logic for partial-match queries with GIN indexes - (Tom Lane) - - - - Cases involving AND/OR combination of several GIN index conditions - didn't always give the right answer, and were sometimes much slower - than necessary. - - - - - - Prevent show_session_authorization() from crashing within autovacuum - processes (Tom Lane) - - - - - - Defend against functions returning setof record where not all the - returned rows are actually of the same rowtype (Tom Lane) - - - - - - Fix possible corruption of pending trigger event lists during - subtransaction rollback (Tom Lane) - - - - This could lead to a crash or incorrect firing of triggers. - - - - - - Fix possible failure when hashing a pass-by-reference function result - (Tao Ma, Tom Lane) - - - - - - Improve merge join's handling of NULLs in the join columns (Tom Lane) - - - - A merge join can now stop entirely upon reaching the first NULL, - if the sort order is such that NULLs sort high. - - - - - - Take care to fsync the contents of lockfiles (both - postmaster.pid and the socket lockfile) while writing them - (Tom Lane) - - - - This omission could result in corrupted lockfile contents if the - machine crashes shortly after postmaster start. That could in turn - prevent subsequent attempts to start the postmaster from succeeding, - until the lockfile is manually removed. - - - - - - Avoid recursion while assigning XIDs to heavily-nested - subtransactions (Andres Freund, Robert Haas) - - - - The original coding could result in a crash if there was limited - stack space. - - - - - - Avoid holding open old WAL segments in the walwriter process - (Magnus Hagander, Heikki Linnakangas) - - - - The previous coding would prevent removal of no-longer-needed segments. - - - - - - Fix log_line_prefix's %i escape, - which could produce junk early in backend startup (Tom Lane) - - - - - - Prevent misinterpretation of partially-specified relation options - for TOAST tables (Itagaki Takahiro) - - - - In particular, fillfactor would be read as zero if any - other reloption had been set for the table, leading to serious bloat. - - - - - - Fix inheritance count tracking in ALTER TABLE ... ADD - CONSTRAINT (Robert Haas) - - - - - - Fix possible data corruption in ALTER TABLE ... SET - TABLESPACE when archiving is enabled (Jeff Davis) - - - - - - Allow CREATE DATABASE and ALTER DATABASE ... SET - TABLESPACE to be interrupted by query-cancel (Guillaume Lelarge) - - - - - - Improve CREATE INDEX's checking of whether proposed index - expressions are immutable (Tom Lane) - - - - - - Fix REASSIGN OWNED to handle operator classes and families - (Asko Tiidumaa) - - - - - - Fix possible core dump when comparing two empty tsquery values - (Tom Lane) - - - - - - Fix LIKE's handling of patterns containing % - followed by _ (Tom Lane) - - - - We've fixed this before, but there were still some incorrectly-handled - cases. - - - - - - Re-allow input of Julian dates prior to 0001-01-01 AD (Tom Lane) - - - - Input such as 'J100000'::date worked before 8.4, - but was unintentionally broken by added error-checking. - - - - - - Fix PL/pgSQL to throw an error, not crash, if a cursor is closed within - a FOR loop that is iterating over that cursor - (Heikki Linnakangas) - - - - - - In PL/Python, defend against null pointer results from - PyCObject_AsVoidPtr and PyCObject_FromVoidPtr - (Peter Eisentraut) - - - - - - In libpq, fix full SSL certificate verification for the - case where both host and hostaddr are specified - (Tom Lane) - - - - - - Make psql recognize DISCARD ALL as a command that should - not be encased in a transaction block in autocommit-off mode - (Itagaki Takahiro) - - - - - - Fix some issues in pg_dump's handling of SQL/MED objects - (Tom Lane) - - - - Notably, pg_dump would always fail if run by a - non-superuser, which was not intended. - - - - - - Improve pg_dump and pg_restore's - handling of non-seekable archive files (Tom Lane, Robert Haas) - - - - This is important for proper functioning of parallel restore. - - - - - - Improve parallel pg_restore's ability to cope with selective restore - (-L option) (Tom Lane) - - - - The original code tended to fail if the -L file commanded - a non-default restore ordering. - - - - - - Fix ecpg to process data from RETURNING - clauses correctly (Michael Meskes) - - - - - - Fix some memory leaks in ecpg (Zoltan Boszormenyi) - - - - - - Improve contrib/dblink's handling of tables containing - dropped columns (Tom Lane) - - - - - - Fix connection leak after duplicate connection name - errors in contrib/dblink (Itagaki Takahiro) - - - - - - Fix contrib/dblink to handle connection names longer than - 62 bytes correctly (Itagaki Takahiro) - - - - - - Add hstore(text, text) - function to contrib/hstore (Robert Haas) - - - - This function is the recommended substitute for the now-deprecated - => operator. It was back-patched so that future-proofed - code can be used with older server versions. Note that the patch will - be effective only after contrib/hstore is installed or - reinstalled in a particular database. Users might prefer to execute - the CREATE FUNCTION command by hand, instead. - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - Update time zone data files to tzdata release 2010l - for DST law changes in Egypt and Palestine; also historical corrections - for Finland. - - - - This change also adds new names for two Micronesian timezones: - Pacific/Chuuk is now preferred over Pacific/Truk (and the preferred - abbreviation is CHUT not TRUT) and Pacific/Pohnpei is preferred over - Pacific/Ponape. - - - - - - Make Windows' N. Central Asia Standard Time timezone map to - Asia/Novosibirsk, not Asia/Almaty (Magnus Hagander) - - - - Microsoft changed the DST behavior of this zone in the timezone update - from KB976098. Asia/Novosibirsk is a better match to its new behavior. - - - - - - - - - - Release 8.4.4 - - - Release date: - 2010-05-17 - - - - This release contains a variety of fixes from 8.4.3. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.4 - - - A dump/restore is not required for those running 8.4.X. - However, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Enforce restrictions in plperl using an opmask applied to - the whole interpreter, instead of using Safe.pm - (Tim Bunce, Andrew Dunstan) - - - - Recent developments have convinced us that Safe.pm is too - insecure to rely on for making plperl trustable. This - change removes use of Safe.pm altogether, in favor of using - a separate interpreter with an opcode mask that is always applied. - Pleasant side effects of the change include that it is now possible to - use Perl's strict pragma in a natural way in - plperl, and that Perl's $a and $b - variables work as expected in sort routines, and that function - compilation is significantly faster. (CVE-2010-1169) - - - - - - Prevent PL/Tcl from executing untrustworthy code from - pltcl_modules (Tom) - - - - PL/Tcl's feature for autoloading Tcl code from a database table - could be exploited for trojan-horse attacks, because there was no - restriction on who could create or insert into that table. This change - disables the feature unless pltcl_modules is owned by a - superuser. (However, the permissions on the table are not checked, so - installations that really need a less-than-secure modules table can - still grant suitable privileges to trusted non-superusers.) Also, - prevent loading code into the unrestricted normal Tcl - interpreter unless we are really going to execute a pltclu - function. (CVE-2010-1170) - - - - - - Fix data corruption during WAL replay of - ALTER ... SET TABLESPACE (Tom) - - - - When archive_mode is on, ALTER ... SET TABLESPACE - generates a WAL record whose replay logic was incorrect. It could write - the data to the wrong place, leading to possibly-unrecoverable data - corruption. Data corruption would be observed on standby slaves, and - could occur on the master as well if a database crash and recovery - occurred after committing the ALTER and before the next - checkpoint. - - - - - - Fix possible crash if a cache reset message is received during - rebuild of a relcache entry (Heikki) - - - - This error was introduced in 8.4.3 while fixing a related failure. - - - - - - Apply per-function GUC settings while running the language validator - for the function (Itagaki Takahiro) - - - - This avoids failures if the function's code is invalid without the - setting; an example is that SQL functions may not parse if the - search_path is not correct. - - - - - - Do constraint exclusion for inherited UPDATE and - DELETE target tables when - constraint_exclusion = partition (Tom) - - - - Due to an oversight, this setting previously only caused constraint - exclusion to be checked in SELECT commands. - - - - - - Do not allow an unprivileged user to reset superuser-only parameter - settings (Alvaro) - - - - Previously, if an unprivileged user ran ALTER USER ... RESET - ALL for himself, or ALTER DATABASE ... RESET ALL for - a database he owns, this would remove all special parameter settings - for the user or database, even ones that are only supposed to be - changeable by a superuser. Now, the ALTER will only - remove the parameters that the user has permission to change. - - - - - - Avoid possible crash during backend shutdown if shutdown occurs - when a CONTEXT addition would be made to log entries (Tom) - - - - In some cases the context-printing function would fail because the - current transaction had already been rolled back when it came time - to print a log message. - - - - - - Fix erroneous handling of %r parameter in - recovery_end_command (Heikki) - - - - The value always came out zero. - - - - - - Ensure the archiver process responds to changes in - archive_command as soon as possible (Tom) - - - - - - Fix PL/pgSQL's CASE statement to not fail when the - case expression is a query that returns no rows (Tom) - - - - - - Update PL/Perl's ppport.h for modern Perl versions - (Andrew) - - - - - - Fix assorted memory leaks in PL/Python (Andreas Freund, Tom) - - - - - - Handle empty-string connect parameters properly in ecpg (Michael) - - - - - - Prevent infinite recursion in psql when expanding - a variable that refers to itself (Tom) - - - - - - Fix psql's \copy to not add spaces around - a dot within \copy (select ...) (Tom) - - - - Addition of spaces around the decimal point in a numeric literal would - result in a syntax error. - - - - - - Avoid formatting failure in psql when running in a - locale context that doesn't match the client_encoding - (Tom) - - - - - - Fix unnecessary GIN indexes do not support whole-index scans - errors for unsatisfiable queries using contrib/intarray - operators (Tom) - - - - - - Ensure that contrib/pgstattuple functions respond to cancel - interrupts promptly (Tatsuhito Kasahara) - - - - - - Make server startup deal properly with the case that - shmget() returns EINVAL for an existing - shared memory segment (Tom) - - - - This behavior has been observed on BSD-derived kernels including macOS. - It resulted in an entirely-misleading startup failure complaining that - the shared memory request size was too large. - - - - - - Avoid possible crashes in syslogger process on Windows (Heikki) - - - - - - Deal more robustly with incomplete time zone information in the - Windows registry (Magnus) - - - - - - Update the set of known Windows time zone names (Magnus) - - - - - - Update time zone data files to tzdata release 2010j - for DST law changes in Argentina, Australian Antarctic, Bangladesh, - Mexico, Morocco, Pakistan, Palestine, Russia, Syria, Tunisia; - also historical corrections for Taiwan. - - - - Also, add PKST (Pakistan Summer Time) to the default set of - timezone abbreviations. - - - - - - - - - - Release 8.4.3 - - - Release date: - 2010-03-15 - - - - This release contains a variety of fixes from 8.4.2. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.3 - - - A dump/restore is not required for those running 8.4.X. - However, if you are upgrading from a version earlier than 8.4.2, - see . - - - - - - Changes - - - - - - Add new configuration parameter ssl_renegotiation_limit to - control how often we do session key renegotiation for an SSL connection - (Magnus) - - - - This can be set to zero to disable renegotiation completely, which may - be required if a broken SSL library is used. In particular, some - vendors are shipping stopgap patches for CVE-2009-3555 that cause - renegotiation attempts to fail. - - - - - - Fix possible deadlock during backend startup (Tom) - - - - - - Fix possible crashes due to not handling errors during relcache reload - cleanly (Tom) - - - - - - Fix possible crash due to use of dangling pointer to a cached plan - (Tatsuo) - - - - - - Fix possible crash due to overenthusiastic invalidation of cached - plan for ROLLBACK (Tom) - - - - - - Fix possible crashes when trying to recover from a failure in - subtransaction start (Tom) - - - - - - Fix server memory leak associated with use of savepoints and a client - encoding different from server's encoding (Tom) - - - - - - Fix incorrect WAL data emitted during end-of-recovery cleanup of a GIST - index page split (Yoichi Hirai) - - - - This would result in index corruption, or even more likely an error - during WAL replay, if we were unlucky enough to crash during - end-of-recovery cleanup after having completed an incomplete GIST - insertion. - - - - - - Fix bug in WAL redo cleanup method for GIN indexes (Heikki) - - - - - - Fix incorrect comparison of scan key in GIN index search (Teodor) - - - - - - Make substring() for bit types treat any negative - length as meaning all the rest of the string (Tom) - - - - The previous coding treated only -1 that way, and would produce an - invalid result value for other negative values, possibly leading to - a crash (CVE-2010-0442). - - - - - - Fix integer-to-bit-string conversions to handle the first fractional - byte correctly when the output bit width is wider than the given - integer by something other than a multiple of 8 bits (Tom) - - - - - - Fix some cases of pathologically slow regular expression matching (Tom) - - - - - - Fix bug occurring when trying to inline a SQL function that returns - a set of a composite type that contains dropped columns (Tom) - - - - - - Fix bug with trying to update a field of an element of a - composite-type array column (Tom) - - - - - - Avoid failure when EXPLAIN has to print a FieldStore or - assignment ArrayRef expression (Tom) - - - - These cases can arise now that EXPLAIN VERBOSE tries to - print plan node target lists. - - - - - - Avoid an unnecessary coercion failure in some cases where an undecorated - literal string appears in a subquery within - UNION/INTERSECT/EXCEPT (Tom) - - - - This fixes a regression for some cases that worked before 8.4. - - - - - - Avoid undesirable rowtype compatibility check failures in some cases - where a whole-row Var has a rowtype that contains dropped columns (Tom) - - - - - - Fix the STOP WAL LOCATION entry in backup history files to - report the next WAL segment's name when the end location is exactly at a - segment boundary (Itagaki Takahiro) - - - - - - Always pass the catalog ID to an option validator function specified in - CREATE FOREIGN DATA WRAPPER (Martin Pihlak) - - - - - - Fix some more cases of temporary-file leakage (Heikki) - - - - This corrects a problem introduced in the previous minor release. - One case that failed is when a plpgsql function returning set is - called within another function's exception handler. - - - - - - Add support for doing FULL JOIN ON FALSE (Tom) - - - - This prevents a regression from pre-8.4 releases for some queries that - can now be simplified to a constant-false join condition. - - - - - - Improve constraint exclusion processing of boolean-variable cases, - in particular make it possible to exclude a partition that has a - bool_column = false constraint (Tom) - - - - - - Prevent treating an INOUT cast as representing binary - compatibility (Heikki) - - - - - - Include column name in the message when warning about inability to - grant or revoke column-level privileges (Stephen Frost) - - - - This is more useful than before and helps to prevent confusion when - a REVOKE generates multiple messages, which formerly - appeared to be duplicates. - - - - - - When reading pg_hba.conf and related files, do not treat - @something as a file inclusion request if the @ - appears inside quote marks; also, never treat @ by itself - as a file inclusion request (Tom) - - - - This prevents erratic behavior if a role or database name starts with - @. If you need to include a file whose path name - contains spaces, you can still do so, but you must write - @"/path to/file" rather than putting the quotes around - the whole construct. - - - - - - Prevent infinite loop on some platforms if a directory is named as - an inclusion target in pg_hba.conf and related files - (Tom) - - - - - - Fix possible infinite loop if SSL_read or - SSL_write fails without setting errno (Tom) - - - - This is reportedly possible with some Windows versions of - openssl. - - - - - - Disallow GSSAPI authentication on local connections, - since it requires a hostname to function correctly (Magnus) - - - - - - Protect ecpg against applications freeing strings - unexpectedly (Michael) - - - - - - Make ecpg report the proper SQLSTATE if the connection - disappears (Michael) - - - - - - Fix translation of cell contents in psql \d - output (Heikki) - - - - - - Fix psql's numericlocale option to not - format strings it shouldn't in latex and troff output formats (Heikki) - - - - - - Fix a small per-query memory leak in psql (Tom) - - - - - - Make psql return the correct exit status (3) when - ON_ERROR_STOP and --single-transaction are - both specified and an error occurs during the implied COMMIT - (Bruce) - - - - - - Fix pg_dump's output of permissions for foreign servers - (Heikki) - - - - - - Fix possible crash in parallel pg_restore due to - out-of-range dependency IDs (Tom) - - - - - - Fix plpgsql failure in one case where a composite column is set to NULL - (Tom) - - - - - - Fix possible failure when calling PL/Perl functions from PL/PerlU - or vice versa (Tim Bunce) - - - - - - Add volatile markings in PL/Python to avoid possible - compiler-specific misbehavior (Zdenek Kotala) - - - - - - Ensure PL/Tcl initializes the Tcl interpreter fully (Tom) - - - - The only known symptom of this oversight is that the Tcl - clock command misbehaves if using Tcl 8.5 or later. - - - - - - Prevent ExecutorEnd from being run on portals created - within a failed transaction or subtransaction (Tom) - - - - This is known to cause issues when using - contrib/auto_explain. - - - - - - Prevent crash in contrib/dblink when too many key - columns are specified to a dblink_build_sql_* function - (Rushabh Lathia, Joe Conway) - - - - - - Allow zero-dimensional arrays in contrib/ltree operations - (Tom) - - - - This case was formerly rejected as an error, but it's more convenient to - treat it the same as a zero-element array. In particular this avoids - unnecessary failures when an ltree operation is applied to the - result of ARRAY(SELECT ...) and the sub-select returns no - rows. - - - - - - Fix assorted crashes in contrib/xml2 caused by sloppy - memory management (Tom) - - - - - - Make building of contrib/xml2 more robust on Windows - (Andrew) - - - - - - Fix race condition in Windows signal handling (Radu Ilie) - - - - One known symptom of this bug is that rows in pg_listener - could be dropped under heavy load. - - - - - - Make the configure script report failure if the C compiler does - not provide a working 64-bit integer datatype (Tom) - - - - This case has been broken for some time, and no longer seems worth - supporting, so just reject it at configure time instead. - - - - - - Update time zone data files to tzdata release 2010e - for DST law changes in Bangladesh, Chile, Fiji, Mexico, Paraguay, Samoa. - - - - - - - - - - Release 8.4.2 - - - Release date: - 2009-12-14 - - - - This release contains a variety of fixes from 8.4.1. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.2 - - - A dump/restore is not required for those running 8.4.X. - However, if you have any hash indexes, - you should REINDEX them after updating to 8.4.2, - to repair possible damage. - - - - - - Changes - - - - - - Protect against indirect security threats caused by index functions - changing session-local state (Gurjeet Singh, Tom) - - - - This change prevents allegedly-immutable index functions from possibly - subverting a superuser's session (CVE-2009-4136). - - - - - - Reject SSL certificates containing an embedded null byte in the common - name (CN) field (Magnus) - - - - This prevents unintended matching of a certificate to a server or client - name during SSL validation (CVE-2009-4034). - - - - - - Fix hash index corruption (Tom) - - - - The 8.4 change that made hash indexes keep entries sorted by hash value - failed to update the bucket splitting and compaction routines to - preserve the ordering. So application of either of those operations - could lead to permanent corruption of an index, in the sense that - searches might fail to find entries that are present. To deal with - this, it is recommended to REINDEX any hash indexes you may - have after installing this update. - - - - - - Fix possible crash during backend-startup-time cache initialization (Tom) - - - - - - Avoid crash on empty thesaurus dictionary (Tom) - - - - - - Prevent signals from interrupting VACUUM at unsafe times - (Alvaro) - - - - This fix prevents a PANIC if a VACUUM FULL is canceled - after it's already committed its tuple movements, as well as transient - errors if a plain VACUUM is interrupted after having - truncated the table. - - - - - - Fix possible crash due to integer overflow in hash table size - calculation (Tom) - - - - This could occur with extremely large planner estimates for the size of - a hashjoin's result. - - - - - - Fix crash if a DROP is attempted on an internally-dependent - object (Tom) - - - - - - Fix very rare crash in inet/cidr comparisons (Chris - Mikkelson) - - - - - - Ensure that shared tuple-level locks held by prepared transactions are - not ignored (Heikki) - - - - - - Fix premature drop of temporary files used for a cursor that is accessed - within a subtransaction (Heikki) - - - - - - Fix memory leak in syslogger process when rotating to a new CSV logfile - (Tom) - - - - - - Fix memory leak in postmaster when re-parsing pg_hba.conf - (Tom) - - - - - - Fix Windows permission-downgrade logic (Jesse Morris) - - - - This fixes some cases where the database failed to start on Windows, - often with misleading error messages such as could not locate - matching postgres executable. - - - - - - Make FOR UPDATE/SHARE in the primary query not propagate - into WITH queries (Tom) - - - - For example, in - -WITH w AS (SELECT * FROM foo) SELECT * FROM w, bar ... FOR UPDATE - - the FOR UPDATE will now affect bar but not - foo. This is more useful and consistent than the original - 8.4 behavior, which tried to propagate FOR UPDATE into the - WITH query but always failed due to assorted implementation - restrictions. It also follows the design rule that WITH - queries are executed as if independent of the main query. - - - - - - Fix bug with a WITH RECURSIVE query immediately inside - another one (Tom) - - - - - - Fix concurrency bug in hash indexes (Tom) - - - - Concurrent insertions could cause index scans to transiently report - wrong results. - - - - - - Fix incorrect logic for GiST index page splits, when the split depends - on a non-first column of the index (Paul Ramsey) - - - - - - Fix wrong search results for a multi-column GIN index with - fastupdate enabled (Teodor) - - - - - - Fix bugs in WAL entry creation for GIN indexes (Tom) - - - - These bugs were masked when full_page_writes was on, but - with it off a WAL replay failure was certain if a crash occurred before - the next checkpoint. - - - - - - Don't error out if recycling or removing an old WAL file fails at the - end of checkpoint (Heikki) - - - - It's better to treat the problem as non-fatal and allow the checkpoint - to complete. Future checkpoints will retry the removal. Such problems - are not expected in normal operation, but have been seen to be - caused by misdesigned Windows anti-virus and backup software. - - - - - - Ensure WAL files aren't repeatedly archived on Windows (Heikki) - - - - This is another symptom that could happen if some other process - interfered with deletion of a no-longer-needed file. - - - - - - Fix PAM password processing to be more robust (Tom) - - - - The previous code is known to fail with the combination of the Linux - pam_krb5 PAM module with Microsoft Active Directory as the - domain controller. It might have problems elsewhere too, since it was - making unjustified assumptions about what arguments the PAM stack would - pass to it. - - - - - - Raise the maximum authentication token (Kerberos ticket) size in GSSAPI - and SSPI authentication methods (Ian Turner) - - - - While the old 2000-byte limit was more than enough for Unix Kerberos - implementations, tickets issued by Windows Domain Controllers can be - much larger. - - - - - - Ensure that domain constraints are enforced in constructs like - ARRAY[...]::domain, where the domain is over an array type - (Heikki) - - - - - - Fix foreign-key logic for some cases involving composite-type columns - as foreign keys (Tom) - - - - - - Ensure that a cursor's snapshot is not modified after it is created - (Alvaro) - - - - This could lead to a cursor delivering wrong results if later operations - in the same transaction modify the data the cursor is supposed to return. - - - - - - Fix CREATE TABLE to properly merge default expressions - coming from different inheritance parent tables (Tom) - - - - This used to work but was broken in 8.4. - - - - - - Re-enable collection of access statistics for sequences (Akira Kurosawa) - - - - This used to work but was broken in 8.3. - - - - - - Fix processing of ownership dependencies during CREATE OR - REPLACE FUNCTION (Tom) - - - - - - Fix incorrect handling of WHERE - x=x conditions (Tom) - - - - In some cases these could get ignored as redundant, but they aren't - — they're equivalent to x IS NOT NULL. - - - - - - Fix incorrect plan construction when using hash aggregation to implement - DISTINCT for textually identical volatile expressions (Tom) - - - - - - Fix Assert failure for a volatile SELECT DISTINCT ON - expression (Tom) - - - - - - Fix ts_stat() to not fail on an empty tsvector - value (Tom) - - - - - - Make text search parser accept underscores in XML attributes (Peter) - - - - - - Fix encoding handling in xml binary input (Heikki) - - - - If the XML header doesn't specify an encoding, we now assume UTF-8 by - default; the previous handling was inconsistent. - - - - - - Fix bug with calling plperl from plperlu or vice - versa (Tom) - - - - An error exit from the inner function could result in crashes due to - failure to re-select the correct Perl interpreter for the outer function. - - - - - - Fix session-lifespan memory leak when a PL/Perl function is redefined - (Tom) - - - - - - Ensure that Perl arrays are properly converted to - PostgreSQL arrays when returned by a set-returning - PL/Perl function (Andrew Dunstan, Abhijit Menon-Sen) - - - - This worked correctly already for non-set-returning functions. - - - - - - Fix rare crash in exception processing in PL/Python (Peter) - - - - - - Fix ecpg problem with comments in DECLARE - CURSOR statements (Michael) - - - - - - Fix ecpg to not treat recently-added keywords as - reserved words (Tom) - - - - This affected the keywords CALLED, CATALOG, - DEFINER, ENUM, FOLLOWING, - INVOKER, OPTIONS, PARTITION, - PRECEDING, RANGE, SECURITY, - SERVER, UNBOUNDED, and WRAPPER. - - - - - - Re-allow regular expression special characters in psql's - \df function name parameter (Tom) - - - - - - In contrib/fuzzystrmatch, correct the calculation of - levenshtein distances with non-default costs (Marcin Mank) - - - - - - In contrib/pg_standby, disable triggering failover with a - signal on Windows (Fujii Masao) - - - - This never did anything useful, because Windows doesn't have Unix-style - signals, but recent changes made it actually crash. - - - - - - Put FREEZE and VERBOSE options in the right - order in the VACUUM command that - contrib/vacuumdb produces (Heikki) - - - - - - Fix possible leak of connections when contrib/dblink - encounters an error (Tatsuhito Kasahara) - - - - - - Ensure psql's flex module is compiled with the correct - system header definitions (Tom) - - - - This fixes build failures on platforms where - --enable-largefile causes incompatible changes in the - generated code. - - - - - - Make the postmaster ignore any application_name parameter in - connection request packets, to improve compatibility with future libpq - versions (Tom) - - - - - - Update the timezone abbreviation files to match current reality (Joachim - Wieland) - - - - This includes adding IDT to the default - timezone abbreviation set. - - - - - - Update time zone data files to tzdata release 2009s - for DST law changes in Antarctica, Argentina, Bangladesh, Fiji, - Novokuznetsk, Pakistan, Palestine, Samoa, Syria; also historical - corrections for Hong Kong. - - - - - - - - - - Release 8.4.1 - - - Release date: - 2009-09-09 - - - - This release contains a variety of fixes from 8.4. - For information about new features in the 8.4 major release, see - . - - - - Migration to Version 8.4.1 - - - A dump/restore is not required for those running 8.4.X. - - - - - - Changes - - - - - - Fix WAL page header initialization at the end of archive recovery - (Heikki) - - - - This could lead to failure to process the WAL in a subsequent - archive recovery. - - - - - - Fix cannot make new WAL entries during recovery error (Tom) - - - - - - Fix problem that could make expired rows visible after a crash (Tom) - - - - This bug involved a page status bit potentially not being set - correctly after a server crash. - - - - - - Disallow RESET ROLE and RESET SESSION - AUTHORIZATION inside security-definer functions (Tom, Heikki) - - - - This covers a case that was missed in the previous patch that - disallowed SET ROLE and SET SESSION - AUTHORIZATION inside security-definer functions. - (See CVE-2007-6600) - - - - - - Make LOAD of an already-loaded loadable module - into a no-op (Tom) - - - - Formerly, LOAD would attempt to unload and re-load the - module, but this is unsafe and not all that useful. - - - - - - Make window function PARTITION BY and ORDER BY - items always be interpreted as simple expressions (Tom) - - - - In 8.4.0 these lists were parsed following the rules used for - top-level GROUP BY and ORDER BY lists. - But this was not correct per the SQL standard, and it led to possible - circularity. - - - - - - Fix several errors in planning of semi-joins (Tom) - - - - These led to wrong query results in some cases where IN - or EXISTS was used together with another join. - - - - - - Fix handling of whole-row references to subqueries that are within - an outer join (Tom) - - - - An example is - SELECT COUNT(ss.*) FROM ... LEFT JOIN (SELECT ...) ss ON .... - Here, ss.* would be treated as ROW(NULL,NULL,...) - for null-extended join rows, which is not the same as a simple NULL. - Now it is treated as a simple NULL. - - - - - - Fix Windows shared-memory allocation code (Tsutomu Yamada, Magnus) - - - - This bug led to the often-reported could not reattach - to shared memory error message. - - - - - - Fix locale handling with plperl (Heikki) - - - - This bug could cause the server's locale setting to change when a - plperl function is called, leading to data corruption. - - - - - - Fix handling of reloptions to ensure setting one option doesn't - force default values for others (Itagaki Takahiro) - - - - - - Ensure that a fast shutdown request will forcibly terminate - open sessions, even if a smart shutdown was already in progress - (Fujii Masao) - - - - - - Avoid memory leak for array_agg() in GROUP BY - queries (Tom) - - - - - - Treat to_char(..., 'TH') as an uppercase ordinal - suffix with 'HH'/'HH12' (Heikki) - - - - It was previously handled as 'th' (lowercase). - - - - - - Include the fractional part in the result of - EXTRACT(second) and - EXTRACT(milliseconds) for - time and time with time zone inputs (Tom) - - - - This has always worked for floating-point datetime configurations, - but was broken in the integer datetime code. - - - - - - Fix overflow for INTERVAL 'x ms' - when x is more than 2 million and integer - datetimes are in use (Alex Hunsaker) - - - - - - Improve performance when processing toasted values in index scans (Tom) - - - - This is particularly useful for PostGIS. - - - - - - Fix a typo that disabled commit_delay (Jeff Janes) - - - - - - Output early-startup messages to postmaster.log if the - server is started in silent mode (Tom) - - - - Previously such error messages were discarded, leading to - difficulty in debugging. - - - - - - Remove translated FAQs (Peter) - - - - They are now on the wiki. The - main FAQ was moved to the wiki some time ago. - - - - - - Fix pg_ctl to not go into an infinite loop if - postgresql.conf is empty (Jeff Davis) - - - - - - Fix several errors in pg_dump's - --binary-upgrade mode (Bruce, Tom) - - - - pg_dump --binary-upgrade is used by pg_migrator. - - - - - - Fix contrib/xml2's xslt_process() to - properly handle the maximum number of parameters (twenty) (Tom) - - - - - - Improve robustness of libpq's code to recover - from errors during COPY FROM STDIN (Tom) - - - - - - Avoid including conflicting readline and editline header files - when both libraries are installed (Zdenek Kotala) - - - - - - Work around gcc bug that causes floating-point exception - instead of division by zero on some platforms (Tom) - - - - - - Update time zone data files to tzdata release 2009l - for DST law changes in Bangladesh, Egypt, Mauritius. - - - - - - - - - - Release 8.4 - - - Release date: - 2009-07-01 - - - - Overview - - - After many years of development, PostgreSQL has - become feature-complete in many areas. This release shows a - targeted approach to adding features (e.g., authentication, - monitoring, space reuse), and adds capabilities defined in the - later SQL standards. The major areas of enhancement are: - - - - - - - - - Windowing Functions - - - - - - Common Table Expressions and Recursive Queries - - - - - - Default and variadic parameters for functions - - - - - - Parallel Restore - - - - - - Column Permissions - - - - - - Per-database locale settings - - - - - - Improved hash indexes - - - - - - Improved join performance for EXISTS and NOT EXISTS queries - - - - - - Easier-to-use Warm Standby - - - - - - Automatic sizing of the Free Space Map - - - - - - Visibility Map (greatly reduces vacuum overhead for slowly-changing tables) - - - - - - Version-aware psql (backslash commands work against older servers) - - - - - - Support SSL certificates for user authentication - - - - - - Per-function runtime statistics - - - - - - Easy editing of functions in psql - - - - - - New contrib modules: pg_stat_statements, auto_explain, citext, btree_gin - - - - - - - The above items are explained in more detail in the sections below. - - - - - - Migration to Version 8.4 - - - A dump/restore using pg_dump is - required for those wishing to migrate data from any previous - release. - - - - Observe the following incompatibilities: - - - - General - - - - - Use 64-bit integer datetimes by default (Neil Conway) - - - - Previously this was selected by configure's - option. To retain - the old behavior, build with . - - - - - - Remove ipcclean utility command (Bruce) - - - - The utility only worked on a few platforms. Users should use - their operating system tools instead. - - - - - - - - - Server Settings - - - - - Change default setting for - log_min_messages to warning (previously - it was notice) to reduce log file volume (Tom) - - - - - - Change default setting for max_prepared_transactions to - zero (previously it was 5) (Tom) - - - - - - Make debug_print_parse, debug_print_rewritten, - and debug_print_plan - output appear at LOG message level, not - DEBUG1 as formerly (Tom) - - - - - - Make debug_pretty_print default to on (Tom) - - - - - - Remove explain_pretty_print parameter (no longer needed) (Tom) - - - - - - Make log_temp_files settable by superusers only, like other - logging options (Simon Riggs) - - - - - - Remove automatic appending of the epoch timestamp when no % - escapes are present in log_filename (Robert Haas) - - - - This change was made because some users wanted a fixed log filename, - for use with an external log rotation tool. - - - - - - Remove log_restartpoints from recovery.conf; - instead use log_checkpoints (Simon) - - - - - - Remove krb_realm and krb_server_hostname; - these are now set in pg_hba.conf instead (Magnus) - - - - - - There are also significant changes in pg_hba.conf, - as described below. - - - - - - - - - Queries - - - - - - Change TRUNCATE and LOCK to - apply to child tables of the specified table(s) (Peter) - - - - These commands now accept an ONLY option that prevents - processing child tables; this option must be used if the old - behavior is needed. - - - - - - SELECT DISTINCT and - UNION/INTERSECT/EXCEPT - no longer always produce sorted output (Tom) - - - - Previously, these types of queries always removed duplicate rows - by means of Sort/Unique processing (i.e., sort then remove adjacent - duplicates). Now they can be implemented by hashing, which will not - produce sorted output. If an application relied on the output being - in sorted order, the recommended fix is to add an ORDER BY - clause. As a short-term workaround, the previous behavior can be - restored by disabling enable_hashagg, but that is a very - performance-expensive fix. SELECT DISTINCT ON never uses - hashing, however, so its behavior is unchanged. - - - - - - Force child tables to inherit CHECK constraints from parents - (Alex Hunsaker, Nikhil Sontakke, Tom) - - - - Formerly it was possible to drop such a constraint from a child - table, allowing rows that violate the constraint to be visible - when scanning the parent table. This was deemed inconsistent, - as well as contrary to SQL standard. - - - - - - Disallow negative LIMIT or OFFSET - values, rather than treating them as zero (Simon) - - - - - - Disallow LOCK TABLE outside a transaction block - (Tom) - - - - Such an operation is useless because the lock would be released - immediately. - - - - - - Sequences now contain an additional start_value column - (Zoltan Boszormenyi) - - - - This supports ALTER SEQUENCE ... RESTART. - - - - - - - - - - Functions and Operators - - - - - - Make numeric zero raised to a fractional power return - 0, rather than throwing an error, and make - numeric zero raised to the zero power return 1, - rather than error (Bruce) - - - - This matches the longstanding float8 behavior. - - - - - - Allow unary minus of floating-point values to produce minus zero (Tom) - - - - The changed behavior is more IEEE-standard - compliant. - - - - - - Throw an error if an escape character is the last character in - a LIKE pattern (i.e., it has nothing to escape) (Tom) - - - - Previously, such an escape character was silently ignored, - thus possibly masking application logic errors. - - - - - - Remove ~=~ and ~<>~ operators - formerly used for LIKE index comparisons (Tom) - - - - Pattern indexes now use the regular equality operator. - - - - - - xpath() now passes its arguments to libxml - without any changes (Andrew) - - - - This means that the XML argument must be a well-formed XML document. - The previous coding attempted to allow XML fragments, but it did not - work well. - - - - - - Make xmlelement() format attribute values just like - content values (Peter) - - - - Previously, attribute values were formatted according to the - normal SQL output behavior, which is sometimes at odds with - XML rules. - - - - - - Rewrite memory management for libxml-using functions - (Tom) - - - - This change should avoid some compatibility problems with use of - libxml in PL/Perl and other add-on code. - - - - - - Adopt a faster algorithm for hash functions (Kenneth Marshall, - based on work of Bob Jenkins) - - - - Many of the built-in hash functions now deliver different results on - little-endian and big-endian platforms. - - - - - - - Temporal Functions and Operators - - - - - - DateStyle no longer controls interval output - formatting; instead there is a new variable IntervalStyle - (Ron Mayer) - - - - - - Improve consistency of handling of fractional seconds in - timestamp and interval output (Ron Mayer) - - - - This may result in displaying a different number of fractional - digits than before, or rounding instead of truncating. - - - - - - Make to_char()'s localized month/day names depend - on LC_TIME, not LC_MESSAGES (Euler - Taveira de Oliveira) - - - - - - Cause to_date() and to_timestamp() - to more consistently report errors for invalid input (Brendan - Jurd) - - - - Previous versions would often ignore or silently misread input - that did not match the format string. Such cases will now - result in an error. - - - - - - Fix to_timestamp() to not require upper/lower case - matching for meridian (AM/PM) and era - (BC/AD) format designations (Brendan - Jurd) - - - - For example, input value ad now matches the format - string AD. - - - - - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 8.4 and the previous major - release. - - - - Performance - - - - - Improve optimizer statistics calculations (Jan Urbanski, Tom) - - - - In particular, estimates for full-text-search operators are - greatly improved. - - - - - - Allow SELECT DISTINCT and - UNION/INTERSECT/EXCEPT to - use hashing (Tom) - - - - This means that these types of queries no longer automatically - produce sorted output. - - - - - - Create explicit concepts of semi-joins and anti-joins (Tom) - - - - This work formalizes our previous ad-hoc treatment of IN - (SELECT ...) clauses, and extends it to EXISTS and - NOT EXISTS clauses. It should result in significantly - better planning of EXISTS and NOT EXISTS - queries. In general, logically equivalent IN and - EXISTS clauses should now have similar performance, - whereas previously IN often won. - - - - - - Improve optimization of sub-selects beneath outer joins (Tom) - - - - Formerly, a sub-select or view could not be optimized very well if it - appeared within the nullable side of an outer join and contained - non-strict expressions (for instance, constants) in its result list. - - - - - - Improve the performance of text_position() and - related functions by using Boyer-Moore-Horspool searching (David - Rowley) - - - - This is particularly helpful for long search patterns. - - - - - - Reduce I/O load of writing the statistics collection file - by writing the file only when requested (Martin Pihlak) - - - - - - Improve performance for bulk inserts (Robert Haas, Simon) - - - - - - Increase the default value of default_statistics_target - from 10 to 100 (Greg Sabino Mullane, - Tom) - - - - The maximum value was also increased from 1000 to - 10000. - - - - - - Perform constraint_exclusion checking by default - in queries involving inheritance or UNION ALL (Tom) - - - - A new constraint_exclusion setting, - partition, was added to specify this behavior. - - - - - - Allow I/O read-ahead for bitmap index scans (Greg Stark) - - - - The amount of read-ahead is controlled by - effective_io_concurrency. This feature is available only - if the kernel has posix_fadvise() support. - - - - - - Inline simple set-returning SQL functions in - FROM clauses (Richard Rowell) - - - - - - Improve performance of multi-batch hash joins by providing a special - case for join key values that are especially common in the outer - relation (Bryce Cutt, Ramon Lawrence) - - - - - - Reduce volume of temporary data in multi-batch hash joins - by suppressing physical tlist optimization (Michael - Henderson, Ramon Lawrence) - - - - - - Avoid waiting for idle-in-transaction sessions during - CREATE INDEX CONCURRENTLY (Simon) - - - - - - Improve performance of shared cache invalidation (Tom) - - - - - - - - - Server - - - Settings - - - - - - Convert many postgresql.conf settings to enumerated - values so that pg_settings can display the valid - values (Magnus) - - - - - - Add cursor_tuple_fraction parameter to control the - fraction of a cursor's rows that the planner assumes will be - fetched (Robert Hell) - - - - - - Allow underscores in the names of custom variable - classes in postgresql.conf (Tom) - - - - - - - - - Authentication and security - - - - - Remove support for the (insecure) crypt authentication method - (Magnus) - - - - This effectively obsoletes pre-PostgreSQL 7.2 client - libraries, as there is no longer any non-plaintext password method that - they can use. - - - - - - Support regular expressions in pg_ident.conf - (Magnus) - - - - - - Allow Kerberos/GSSAPI parameters - to be changed without restarting the postmaster (Magnus) - - - - - - Support SSL certificate chains in server certificate - file (Andrew Gierth) - - - - Including the full certificate chain makes the client able - to verify the certificate without having all intermediate CA - certificates present in the local store, which is often the case for - commercial CAs. - - - - - - Report appropriate error message for combination of MD5 - authentication and db_user_namespace enabled (Bruce) - - - - - - - - <filename>pg_hba.conf</filename> - - - - - Change all authentication options to use name=value - syntax (Magnus) - - - - This makes incompatible changes to the ldap, - pam and ident authentication methods. All - pg_hba.conf entries with these methods need to be - rewritten using the new format. - - - - - - Remove the ident sameuser option, instead making that - behavior the default if no usermap is specified (Magnus) - - - - - - Allow a usermap parameter for all external authentication methods - (Magnus) - - - - Previously a usermap was only supported for ident - authentication. - - - - - - Add clientcert option to control requesting of a - client certificate (Magnus) - - - - Previously this was controlled by the presence of a root - certificate file in the server's data directory. - - - - - - Add cert authentication method to allow - user authentication via SSL certificates - (Magnus) - - - - Previously SSL certificates could only verify that - the client had access to a certificate, not authenticate a - user. - - - - - - Allow krb5, gssapi and sspi - realm and krb5 host settings to be specified in - pg_hba.conf (Magnus) - - - - These override the settings in postgresql.conf. - - - - - - Add include_realm parameter for krb5, - gssapi, and sspi methods (Magnus) - - - - This allows identical usernames from different realms to be - authenticated as different database users using usermaps. - - - - - - Parse pg_hba.conf fully when it is loaded, - so that errors are reported immediately (Magnus) - - - - Previously, most errors in the file wouldn't be detected until clients - tried to connect, so an erroneous file could render the system - unusable. With the new behavior, if an error is detected during - reload then the bad file is rejected and the postmaster continues - to use its old copy. - - - - - - Show all parsing errors in pg_hba.conf instead of - aborting after the first one (Selena Deckelmann) - - - - - - Support ident authentication over Unix-domain sockets - on Solaris (Garick Hamlin) - - - - - - - - - Continuous Archiving - - - - - Provide an option to pg_start_backup() to force its - implied checkpoint to finish as quickly as possible (Tom) - - - - The default behavior avoids excess I/O consumption, but that is - pointless if no concurrent query activity is going on. - - - - - - Make pg_stop_backup() wait for modified WAL - files to be archived (Simon) - - - - This guarantees that the backup is valid at the time - pg_stop_backup() completes. - - - - - - When archiving is enabled, rotate the last WAL segment at shutdown - so that all transactions can be archived immediately - (Guillaume Smet, Heikki) - - - - - - Delay smart shutdown while a continuous archiving base backup - is in progress (Laurenz Albe) - - - - - - Cancel a continuous archiving base backup if fast shutdown - is requested (Laurenz Albe) - - - - - - Allow recovery.conf boolean variables to take the - same range of string values as postgresql.conf - boolean variables - (Bruce) - - - - - - - - - Monitoring - - - - - Add pg_conf_load_time() to report when - the PostgreSQL configuration files were last loaded - (George Gensure) - - - - - - Add pg_terminate_backend() to safely terminate a - backend (the SIGTERM signal works also) (Tom, Bruce) - - - - While it's always been possible to SIGTERM a single - backend, this was previously considered unsupported; and testing - of the case found some bugs that are now fixed. - - - - - - Add ability to track user-defined functions' call counts and - runtimes (Martin Pihlak) - - - - Function statistics appear in a new system view, - pg_stat_user_functions. Tracking is controlled - by the new parameter track_functions. - - - - - - Allow specification of the maximum query string size in - pg_stat_activity via new - track_activity_query_size parameter (Thomas Lee) - - - - - - Increase the maximum line length sent to syslog, in - hopes of improving performance (Tom) - - - - - - Add read-only configuration variables segment_size, - wal_block_size, and wal_segment_size - (Bernd Helmle) - - - - - - When reporting a deadlock, report the text of all queries involved - in the deadlock to the server log (Itagaki Takahiro) - - - - - - Add pg_stat_get_activity(pid) function to return - information about a specific process id (Magnus) - - - - - - Allow the location of the server's statistics file to be specified - via stats_temp_directory (Magnus) - - - - This allows the statistics file to be placed in a - RAM-resident directory to reduce I/O requirements. - On startup/shutdown, the file is copied to its traditional location - ($PGDATA/global/) so it is preserved across restarts. - - - - - - - - - - - Queries - - - - - Add support for WINDOW functions (Hitoshi Harada) - - - - - - Add support for WITH clauses (CTEs), including WITH - RECURSIVE (Yoshiyuki Asaba, Tatsuo Ishii, Tom) - - - - - - Add TABLE command (Peter) - - - - TABLE tablename is a SQL standard short-hand for - SELECT * FROM tablename. - - - - - - Allow AS to be optional when specifying a - SELECT (or RETURNING) column output - label (Hiroshi Saito) - - - - This works so long as the column label is not any - PostgreSQL keyword; otherwise AS is still - needed. - - - - - - Support set-returning functions in SELECT result lists - even for functions that return their result via a tuplestore (Tom) - - - - In particular, this means that functions written in PL/pgSQL - and other PL languages can now be called this way. - - - - - - Support set-returning functions in the output of aggregation - and grouping queries (Tom) - - - - - - Allow SELECT FOR UPDATE/SHARE to work - on inheritance trees (Tom) - - - - - - Add infrastructure for SQL/MED (Martin Pihlak, - Peter) - - - - There are no remote or external SQL/MED capabilities - yet, but this change provides a standardized and future-proof - system for managing connection information for modules like - dblink and plproxy. - - - - - - Invalidate cached plans when referenced schemas, functions, operators, - or operator classes are modified (Martin Pihlak, Tom) - - - - This improves the system's ability to respond to on-the-fly - DDL changes. - - - - - Allow comparison of composite types and allow arrays of - anonymous composite types (Tom) - - - - This allows constructs such as - row(1, 1.1) = any (array[row(7, 7.7), row(1, 1.0)]). - This is particularly useful in recursive queries. - - - - - - Add support for Unicode string literal and identifier specifications - using code points, e.g. U&'d\0061t\+000061' - (Peter) - - - - - - Reject \000 in string literals and COPY data - (Tom) - - - - Previously, this was accepted but had the effect of terminating - the string contents. - - - - - - Improve the parser's ability to report error locations (Tom) - - - - An error location is now reported for many semantic errors, - such as mismatched datatypes, that previously could not be localized. - - - - - - - <command>TRUNCATE</command> - - - - - Support statement-level ON TRUNCATE triggers (Simon) - - - - - - Add RESTART/CONTINUE IDENTITY options - for TRUNCATE TABLE - (Zoltan Boszormenyi) - - - - The start value of a sequence can be changed by ALTER - SEQUENCE START WITH. - - - - - - Allow TRUNCATE tab1, tab1 to succeed (Bruce) - - - - - - Add a separate TRUNCATE permission (Robert Haas) - - - - - - - - - <command>EXPLAIN</command> - - - - - Make EXPLAIN VERBOSE show the output columns of each - plan node (Tom) - - - - Previously EXPLAIN VERBOSE output an internal - representation of the query plan. (That behavior is now - available via debug_print_plan.) - - - - - - Make EXPLAIN identify subplans and initplans with - individual labels (Tom) - - - - - - Make EXPLAIN honor debug_print_plan (Tom) - - - - - - Allow EXPLAIN on CREATE TABLE AS (Peter) - - - - - - - - - <literal>LIMIT</literal>/<literal>OFFSET</literal> - - - - - Allow sub-selects in LIMIT and OFFSET (Tom) - - - - - - Add SQL-standard syntax for - LIMIT/OFFSET capabilities (Peter) - - - - To wit, - OFFSET num {ROW|ROWS} FETCH {FIRST|NEXT} [num] {ROW|ROWS} - ONLY. - - - - - - - - - - - Object Manipulation - - - - - Add support for column-level privileges (Stephen Frost, KaiGai - Kohei) - - - - - - Refactor multi-object DROP operations to reduce the - need for CASCADE (Alex Hunsaker) - - - - For example, if table B has a dependency on table - A, the command DROP TABLE A, B no longer - requires the CASCADE option. - - - - - - Fix various problems with concurrent DROP commands - by ensuring that locks are taken before we begin to drop dependencies - of an object (Tom) - - - - - - Improve reporting of dependencies during DROP - commands (Tom) - - - - - - Add WITH [NO] DATA clause to CREATE TABLE - AS, per the SQL standard (Peter, Tom) - - - - - - Add support for user-defined I/O conversion casts (Heikki) - - - - - - Allow CREATE AGGREGATE to use an internal - transition datatype (Tom) - - - - - - Add LIKE clause to CREATE TYPE (Tom) - - - - This simplifies creation of data types that use the same internal - representation as an existing type. - - - - - - Allow specification of the type category and preferred - status for user-defined base types (Tom) - - - - This allows more control over the coercion behavior of user-defined - types. - - - - - - Allow CREATE OR REPLACE VIEW to add columns to the - end of a view (Robert Haas) - - - - - - - <command>ALTER</command> - - - - - Add ALTER TYPE RENAME (Petr Jelinek) - - - - - - Add ALTER SEQUENCE ... RESTART (with no parameter) to - reset a sequence to its initial value (Zoltan Boszormenyi) - - - - - - Modify the ALTER TABLE syntax to allow all reasonable - combinations for tables, indexes, sequences, and views (Tom) - - - - This change allows the following new syntaxes: - - - - - ALTER SEQUENCE OWNER TO - - - - - ALTER VIEW ALTER COLUMN SET/DROP DEFAULT - - - - - ALTER VIEW OWNER TO - - - - - ALTER VIEW SET SCHEMA - - - - - There is no actual new functionality here, but formerly - you had to say ALTER TABLE to do these things, - which was confusing. - - - - - - Add support for the syntax ALTER TABLE ... ALTER COLUMN - ... SET DATA TYPE (Peter) - - - - This is SQL-standard syntax for functionality that - was already supported. - - - - - - Make ALTER TABLE SET WITHOUT OIDS rewrite the table - to physically remove OID values (Tom) - - - - Also, add ALTER TABLE SET WITH OIDS to rewrite the - table to add OIDs. - - - - - - - - - Database Manipulation - - - - - Improve reporting of - CREATE/DROP/RENAME DATABASE - failure when uncommitted prepared transactions are the cause - (Tom) - - - - - - Make LC_COLLATE and LC_CTYPE into - per-database settings (Radek Strnad, Heikki) - - - - This makes collation similar to encoding, which was always - configurable per database. - - - - - - Improve checks that the database encoding, collation - (LC_COLLATE), and character classes - (LC_CTYPE) match (Heikki, Tom) - - - - Note in particular that a new database's encoding and locale - settings can be changed only when copying from template0. - This prevents possibly copying data that doesn't match the settings. - - - - - - Add ALTER DATABASE SET TABLESPACE to move a database - to a new tablespace (Guillaume Lelarge, Bernd Helmle) - - - - - - - - - - - Utility Operations - - - - - - Add a VERBOSE option to the CLUSTER command and - clusterdb (Jim Cox) - - - - - - Decrease memory requirements for recording pending trigger - events (Tom) - - - - - - - Indexes - - - - - Dramatically improve the speed of building and accessing hash - indexes (Tom Raney, Shreya Bhargava) - - - - This allows hash indexes to be sometimes faster than btree - indexes. However, hash indexes are still not crash-safe. - - - - - - Make hash indexes store only the hash code, not the full value of - the indexed column (Xiao Meng) - - - - This greatly reduces the size of hash indexes for long indexed - values, improving performance. - - - - - - Implement fast update option for GIN indexes (Teodor, Oleg) - - - - This option greatly improves update speed at a small penalty in search - speed. - - - - - - xxx_pattern_ops indexes can now be used for simple - equality comparisons, not only for LIKE (Tom) - - - - - - - - - Full Text Indexes - - - - - Remove the requirement to use @@@ when doing - GIN weighted lookups on full text indexes (Tom, Teodor) - - - - The normal @@ text search operator can be used - instead. - - - - - - Add an optimizer selectivity function for @@ text - search operations (Jan Urbanski) - - - - - - Allow prefix matching in full text searches (Teodor Sigaev, - Oleg Bartunov) - - - - - - Support multi-column GIN indexes (Teodor Sigaev) - - - - - - Improve support for Nepali language and Devanagari alphabet (Teodor) - - - - - - - - - <command>VACUUM</command> - - - - - Track free space in separate per-relation fork files (Heikki) - - - - Free space discovered by VACUUM is now recorded in - *_fsm files, rather than in a fixed-sized shared memory - area. The max_fsm_pages and max_fsm_relations - settings have been removed, greatly simplifying administration of - free space management. - - - - - - Add a visibility map to track pages that do not require - vacuuming (Heikki) - - - - This allows VACUUM to avoid scanning all of - a table when only a portion of the table needs vacuuming. - The visibility map is stored in per-relation fork files. - - - - - - Add vacuum_freeze_table_age parameter to control - when VACUUM should ignore the visibility map and - do a full table scan to freeze tuples (Heikki) - - - - - - Track transaction snapshots more carefully (Alvaro) - - - - This improves VACUUM's ability to reclaim space - in the presence of long-running transactions. - - - - - - Add ability to specify per-relation autovacuum and TOAST - parameters in CREATE TABLE (Alvaro, Euler Taveira de - Oliveira) - - - - Autovacuum options used to be stored in a system table. - - - - - - Add --freeze option to vacuumdb - (Bruce) - - - - - - - - - - - Data Types - - - - - Add a CaseSensitive option for text search synonym - dictionaries (Simon) - - - - - - Improve the precision of NUMERIC division (Tom) - - - - - - Add basic arithmetic operators for int2 with int8 - (Tom) - - - - This eliminates the need for explicit casting in some situations. - - - - - - Allow UUID input to accept an optional hyphen after - every fourth digit (Robert Haas) - - - - - - Allow on/off as input for the boolean data type - (Itagaki Takahiro) - - - - - - Allow spaces around NaN in the input string for - type numeric (Sam Mason) - - - - - - - Temporal Data Types - - - - - Reject year 0 BC and years 000 and - 0000 (Tom) - - - - Previously these were interpreted as 1 BC. - (Note: years 0 and 00 are still assumed to be - the year 2000.) - - - - - - Include SGT (Singapore time) in the default list of - known time zone abbreviations (Tom) - - - - - - Support infinity and -infinity as - values of type date (Tom) - - - - - - Make parsing of interval literals more standard-compliant - (Tom, Ron Mayer) - - - - For example, INTERVAL '1' YEAR now does what it's - supposed to. - - - - - - Allow interval fractional-seconds precision to be specified - after the second keyword, for SQL standard - compliance (Tom) - - - - Formerly the precision had to be specified after the keyword - interval. (For backwards compatibility, this syntax is still - supported, though deprecated.) Data type definitions will now be - output using the standard format. - - - - - - Support the IS0 8601 interval syntax (Ron - Mayer, Kevin Grittner) - - - - For example, INTERVAL 'P1Y2M3DT4H5M6.7S' is now - supported. - - - - - - Add IntervalStyle parameter - which controls how interval values are output (Ron Mayer) - - - - Valid values are: postgres, postgres_verbose, - sql_standard, iso_8601. This setting also - controls the handling of negative interval input when only - some fields have positive/negative designations. - - - - - - Improve consistency of handling of fractional seconds in - timestamp and interval output (Ron Mayer) - - - - - - - - - Arrays - - - - - Improve the handling of casts applied to ARRAY[] - constructs, such as ARRAY[...]::integer[] - (Brendan Jurd) - - - - Formerly PostgreSQL attempted to determine a data type - for the ARRAY[] construct without reference to the ensuing - cast. This could fail unnecessarily in many cases, in particular when - the ARRAY[] construct was empty or contained only - ambiguous entries such as NULL. Now the cast is consulted - to determine the type that the array elements must be. - - - - - - Make SQL-syntax ARRAY dimensions optional - to match the SQL standard (Peter) - - - - - - Add array_ndims() to return the number - of dimensions of an array (Robert Haas) - - - - - - Add array_length() to return the length - of an array for a specified dimension (Jim Nasby, Robert - Haas, Peter Eisentraut) - - - - - - Add aggregate function array_agg(), which - returns all aggregated values as a single array (Robert Haas, - Jeff Davis, Peter) - - - - - - Add unnest(), which converts an array to - individual row values (Tom) - - - - This is the opposite of array_agg(). - - - - - - Add array_fill() to create arrays initialized with - a value (Pavel Stehule) - - - - - - Add generate_subscripts() to simplify generating - the range of an array's subscripts (Pavel Stehule) - - - - - - - - - Wide-Value Storage (<acronym>TOAST</acronym>) - - - - - Consider TOAST compression on values as short as - 32 bytes (previously 256 bytes) (Greg Stark) - - - - - - Require 25% minimum space savings before using TOAST - compression (previously 20% for small values and any-savings-at-all - for large values) (Greg) - - - - - - Improve TOAST heuristics for rows that have a mix of large - and small toastable fields, so that we prefer to push large values out - of line and don't compress small values unnecessarily (Greg, Tom) - - - - - - - - - - - Functions - - - - - Document that setseed() allows values from - -1 to 1 (not just 0 to - 1), and enforce the valid range (Kris Jurka) - - - - - - Add server-side function lo_import(filename, oid) - (Tatsuo) - - - - - - Add quote_nullable(), which behaves like - quote_literal() but returns the string NULL for - a null argument (Brendan Jurd) - - - - - - Improve full text search headline() function to - allow extracting several fragments of text (Sushant Sinha) - - - - - - Add suppress_redundant_updates_trigger() trigger - function to avoid overhead for non-data-changing updates (Andrew) - - - - - - Add div(numeric, numeric) to perform numeric - division without rounding (Tom) - - - - - - Add timestamp and timestamptz versions of - generate_series() (Hitoshi Harada) - - - - - - - Object Information Functions - - - - - Implement current_query() for use by functions - that need to know the currently running query (Tomas Doran) - - - - - - Add pg_get_keywords() to return a list of the - parser keywords (Dave Page) - - - - - - Add pg_get_functiondef() to see a function's - definition (Abhijit Menon-Sen) - - - - - - Allow the second argument of pg_get_expr() to be zero - when deparsing an expression that does not contain variables (Tom) - - - - - - Modify pg_relation_size() to use regclass - (Heikki) - - - - pg_relation_size(data_type_name) no longer works. - - - - - - Add boot_val and reset_val columns to - pg_settings output (Greg Smith) - - - - - - Add source file name and line number columns to - pg_settings output for variables set in a configuration - file (Magnus, Alvaro) - - - - For security reasons, these columns are only visible to superusers. - - - - - - Add support for CURRENT_CATALOG, - CURRENT_SCHEMA, SET CATALOG, SET - SCHEMA (Peter) - - - - These provide SQL-standard syntax for existing features. - - - - - - Add pg_typeof() which returns the data type - of any value (Brendan Jurd) - - - - - - Make version() return information about whether - the server is a 32- or 64-bit binary (Bruce) - - - - - - Fix the behavior of information schema columns - is_insertable_into and is_updatable to - be consistent (Peter) - - - - - - Improve the behavior of information schema - datetime_precision columns (Peter) - - - - These columns now show zero for date columns, and 6 - (the default precision) for time, timestamp, and - interval without a declared precision, rather than showing - null as formerly. - - - - - - Convert remaining builtin set-returning functions to use - OUT parameters (Jaime Casanova) - - - - This makes it possible to call these functions without specifying - a column list: pg_show_all_settings(), - pg_lock_status(), pg_prepared_xact(), - pg_prepared_statement(), pg_cursor() - - - - - - Make pg_*_is_visible() and - has_*_privilege() functions return NULL - for invalid OIDs, rather than reporting an error (Tom) - - - - - - Extend has_*_privilege() functions to allow inquiring - about the OR of multiple privileges in one call (Stephen - Frost, Tom) - - - - - - Add has_column_privilege() and - has_any_column_privilege() functions (Stephen - Frost, Tom) - - - - - - - - - Function Creation - - - - - Support variadic functions (functions with a variable number - of arguments) (Pavel Stehule) - - - - Only trailing arguments can be optional, and they all must be - of the same data type. - - - - - - Support default values for function arguments (Pavel Stehule) - - - - - - Add CREATE FUNCTION ... RETURNS TABLE clause (Pavel - Stehule) - - - - - - Allow SQL-language functions to return the output - of an INSERT/UPDATE/DELETE - RETURNING clause (Tom) - - - - - - - - - PL/pgSQL Server-Side Language - - - - - Support EXECUTE USING for easier insertion of data - values into a dynamic query string (Pavel Stehule) - - - - - - Allow looping over the results of a cursor using a FOR - loop (Pavel Stehule) - - - - - - Support RETURN QUERY EXECUTE (Pavel - Stehule) - - - - - - Improve the RAISE command (Pavel Stehule) - - - - - Support DETAIL and HINT fields - - - - - Support specification of the SQLSTATE error code - - - - - Support an exception name parameter - - - - - Allow RAISE without parameters in an exception - block to re-throw the current error - - - - - - - - - Allow specification of SQLSTATE codes - in EXCEPTION lists (Pavel Stehule) - - - - This is useful for handling custom SQLSTATE codes. - - - - - - Support the CASE statement (Pavel Stehule) - - - - - - Make RETURN QUERY set the special FOUND and - GET DIAGNOSTICS ROW_COUNT variables - (Pavel Stehule) - - - - - - Make FETCH and MOVE set the - GET DIAGNOSTICS ROW_COUNT variable - (Andrew Gierth) - - - - - - Make EXIT without a label always exit the innermost - loop (Tom) - - - - Formerly, if there were a BEGIN block more closely nested - than any loop, it would exit that block instead. The new behavior - matches Oracle(TM) and is also what was previously stated by our own - documentation. - - - - - - Make processing of string literals and nested block comments - match the main SQL parser's processing (Tom) - - - - In particular, the format string in RAISE now works - the same as any other string literal, including being subject - to standard_conforming_strings. This change also - fixes other cases in which valid commands would fail when - standard_conforming_strings is on. - - - - - - Avoid memory leakage when the same function is called at varying - exception-block nesting depths (Tom) - - - - - - - - - - - Client Applications - - - - - - Fix pg_ctl restart to preserve command-line arguments - (Bruce) - - - - - - Add -w/--no-password option that - prevents password prompting in all utilities that have a - -W/--password option (Peter) - - - - - - Remove (quiet) option of createdb, - createuser, dropdb, - dropuser (Peter) - - - - These options have had no effect since PostgreSQL - 8.3. - - - - - - - <application>psql</application> - - - - - Remove verbose startup banner; now just suggest help - (Joshua Drake) - - - - - - Make help show common backslash commands (Greg - Sabino Mullane) - - - - - - Add \pset format wrapped mode to wrap output to the - screen width, or file/pipe output too if \pset columns - is set (Bryce Nesbitt) - - - - - - Allow all supported spellings of boolean values in \pset, - rather than just on and off (Bruce) - - - - Formerly, any string other than off was silently taken - to mean true. psql will now complain - about unrecognized spellings (but still take them as true). - - - - - - Use the pager for wide output (Bruce) - - - - - - Require a space between a one-letter backslash command and its first - argument (Bernd Helmle) - - - - This removes a historical source of ambiguity. - - - - - - Improve tab completion support for schema-qualified and - quoted identifiers (Greg Sabino Mullane) - - - - - - Add optional on/off argument for - \timing (David Fetter) - - - - - - Display access control rights on multiple lines (Brendan - Jurd, Andreas Scherbaum) - - - - - - Make \l show database access privileges (Andrew Gilligan) - - - - - - Make \l+ show database sizes, if permissions - allow (Andrew Gilligan) - - - - - - Add the \ef command to edit function definitions - (Abhijit Menon-Sen) - - - - - - - - - <application>psql</application> \d* commands - - - - - - Make \d* commands that do not have a pattern argument - show system objects only if the S modifier is specified - (Greg Sabino Mullane, Bruce) - - - - The former behavior was inconsistent across different variants - of \d, and in most cases it provided no easy way to see - just user objects. - - - - - - Improve \d* commands to work with older - PostgreSQL server versions (back to 7.4), - not only the current server version - (Guillaume Lelarge) - - - - - - Make \d show foreign-key constraints that reference - the selected table (Kenneth D'Souza) - - - - - - Make \d on a sequence show its column values - (Euler Taveira de Oliveira) - - - - - - Add column storage type and other relation options to the - \d+ display (Gregory Stark, Euler Taveira de - Oliveira) - - - - - - Show relation size in \dt+ output (Dickson S. - Guedes) - - - - - - Show the possible values of enum types in \dT+ - (David Fetter) - - - - - - Allow \dC to accept a wildcard pattern, which matches - either datatype involved in the cast (Tom) - - - - - - Add a function type column to \df's output, and add - options to list only selected types of functions (David Fetter) - - - - - - Make \df not hide functions that take or return - type cstring (Tom) - - - - Previously, such functions were hidden because most of them are - datatype I/O functions, which were deemed uninteresting. The new - policy about hiding system functions by default makes this wart - unnecessary. - - - - - - - - - <application>pg_dump</application> - - - - - Add a --no-tablespaces option to - pg_dump/pg_dumpall/pg_restore - so that dumps can be restored to clusters that have non-matching - tablespace layouts (Gavin Roy) - - - - - - Remove and options from - pg_dump and pg_dumpall (Tom) - - - - These options were too frequently confused with the option to - select a database name in other PostgreSQL - client applications. The functionality is still available, - but you must now spell out the long option name - or . - - - - - - Remove / option from - pg_dump and pg_dumpall (Tom) - - - - Use of this option does not throw an error, but it has no - effect. This option was removed because the version checks - are necessary for safety. - - - - - - Disable statement_timeout during dump and restore - (Joshua Drake) - - - - - - Add pg_dump/pg_dumpall option - (David Gould) - - - - This allows dumps to fail if unable to acquire a shared lock - within the specified amount of time. - - - - - - Reorder pg_dump --data-only output - to dump tables referenced by foreign keys before - the referencing tables (Tom) - - - - This allows data loads when foreign keys are already present. - If circular references make a safe ordering impossible, a - NOTICE is issued. - - - - - - Allow pg_dump, pg_dumpall, and - pg_restore to use a specified role (Benedek - László) - - - - - - Allow pg_restore to use multiple concurrent - connections to do the restore (Andrew) - - - - The number of concurrent connections is controlled by the option - --jobs. This is supported only for custom-format archives. - - - - - - - - - - - Programming Tools - - - <application>libpq</application> - - - - - Allow the OID to be specified when importing a large - object, via new function lo_import_with_oid() (Tatsuo) - - - - - - Add events support (Andrew Chernow, Merlin Moncure) - - - - This adds the ability to register callbacks to manage private - data associated with PGconn and PGresult - objects. - - - - - - Improve error handling to allow the return of multiple - error messages as multi-line error reports (Magnus) - - - - - - Make PQexecParams() and related functions return - PGRES_EMPTY_QUERY for an empty query (Tom) - - - - They previously returned PGRES_COMMAND_OK. - - - - - - Document how to avoid the overhead of WSACleanup() - on Windows (Andrew Chernow) - - - - - - Do not rely on Kerberos tickets to determine the default database - username (Magnus) - - - - Previously, a Kerberos-capable build of libpq would use the - principal name from any available Kerberos ticket as default - database username, even if the connection wasn't using Kerberos - authentication. This was deemed inconsistent and confusing. - The default username is now determined the same way with or - without Kerberos. Note however that the database username must still - match the ticket when Kerberos authentication is used. - - - - - - - - <application>libpq</application> <acronym>SSL</acronym> (Secure Sockets Layer) - support - - - - - Fix certificate validation for SSL connections - (Magnus) - - - - libpq now supports verifying both the certificate - and the name of the server when making SSL - connections. If a root certificate is not available to use for - verification, SSL connections will fail. The - sslmode parameter is used to enable certificate - verification and set the level of checking. - The default is still not to do any verification, allowing connections - to SSL-enabled servers without requiring a root certificate on the - client. - - - - - - Support wildcard server certificates (Magnus) - - - - If a certificate CN starts with *, it will - be treated as a wildcard when matching the hostname, allowing the - use of the same certificate for multiple servers. - - - - - - Allow the file locations for client certificates to be specified - (Mark Woodward, Alvaro, Magnus) - - - - - - Add a PQinitOpenSSL function to allow greater control - over OpenSSL/libcrypto initialization (Andrew Chernow) - - - - - - Make libpq unregister its OpenSSL - callbacks when no database connections remain open - (Bruce, Magnus, Russell Smith) - - - - This is required for applications that unload the libpq library, - otherwise invalid OpenSSL callbacks will remain. - - - - - - - - - <application>ecpg</application> - - - - - Add localization support for messages (Euler Taveira de - Oliveira) - - - - - - ecpg parser is now automatically generated from the server - parser (Michael) - - - - Previously the ecpg parser was hand-maintained. - - - - - - - - - Server Programming Interface (<acronym>SPI</acronym>) - - - - - Add support for single-use plans with out-of-line - parameters (Tom) - - - - - - Add new SPI_OK_REWRITTEN return code for - SPI_execute() (Heikki) - - - - This is used when a command is rewritten to another type of - command. - - - - - - Remove unnecessary inclusions from executor/spi.h (Tom) - - - - SPI-using modules might need to add some #include - lines if they were depending on spi.h to include - things for them. - - - - - - - - - - - Build Options - - - - - Update build system to use Autoconf 2.61 (Peter) - - - - - - Require GNU bison for source code builds (Peter) - - - - This has effectively been required for several years, but now there - is no infrastructure claiming to support other parser tools. - - - - - - Add pg_config --htmldir option - (Peter) - - - - - - Pass float4 by value inside the server (Zoltan - Boszormenyi) - - - - Add configure option - --disable-float4-byval to use the old behavior. - External C functions that use old-style (version 0) call convention - and pass or return float4 values will be broken by this - change, so you may need the configure option if you - have such functions and don't want to update them. - - - - - - Pass float8, int8, and related datatypes - by value inside the server on 64-bit platforms (Zoltan Boszormenyi) - - - - Add configure option - --disable-float8-byval to use the old behavior. - As above, this change might break old-style external C functions. - - - - - - Add configure options --with-segsize, - --with-blocksize, --with-wal-blocksize, - --with-wal-segsize (Zdenek Kotala, Tom) - - - - This simplifies build-time control over several constants that - previously could only be changed by editing - pg_config_manual.h. - - - - - - Allow threaded builds on Solaris 2.5 (Bruce) - - - - - - Use the system's getopt_long() on Solaris - (Zdenek Kotala, Tom) - - - - This makes option processing more consistent with what Solaris users - expect. - - - - - - Add support for the Sun Studio compiler on - Linux (Julius Stroffek) - - - - - - Append the major version number to the backend gettext - domain, and the soname major version number to - libraries' gettext domain (Peter) - - - - This simplifies parallel installations of multiple versions. - - - - - - Add support for code coverage testing with gcov - (Michelle Caisse) - - - - - - Allow out-of-tree builds on Mingw and - Cygwin (Richard Evans) - - - - - - Fix the use of Mingw as a cross-compiling source - platform (Peter) - - - - - - - - - Source Code - - - - - Support 64-bit time zone data files (Heikki) - - - - This adds support for daylight saving time (DST) - calculations beyond the year 2038. - - - - - - Deprecate use of platform's time_t data type (Tom) - - - - Some platforms have migrated to 64-bit time_t, some have - not, and Windows can't make up its mind what it's doing. Define - pg_time_t to have the same meaning as time_t, - but always be 64 bits (unless the platform has no 64-bit integer type), - and use that type in all module APIs and on-disk data formats. - - - - - - Fix bug in handling of the time zone database when cross-compiling - (Richard Evans) - - - - - - Link backend object files in one step, rather than in stages - (Peter) - - - - - - Improve gettext support to allow better translation - of plurals (Peter) - - - - - - Add message translation support to the PL languages (Alvaro, Peter) - - - - - - Add more DTrace probes (Robert Lor) - - - - - - Enable DTrace support on macOS - Leopard and other non-Solaris platforms (Robert Lor) - - - - - - Simplify and standardize conversions between C strings and - text datums, by providing common functions for the purpose - (Brendan Jurd, Tom) - - - - - - Clean up the include/catalog/ header files so that - frontend programs can include them without including - postgres.h - (Zdenek Kotala) - - - - - - Make name char-aligned, and suppress zero-padding of - name entries in indexes (Tom) - - - - - - Recover better if dynamically-loaded code executes exit() - (Tom) - - - - - - Add a hook to let plug-ins monitor the executor (Itagaki - Takahiro) - - - - - - Add a hook to allow the planner's statistics lookup behavior to - be overridden (Simon Riggs) - - - - - - Add shmem_startup_hook() for custom shared memory - requirements (Tom) - - - - - - Replace the index access method amgetmulti entry point - with amgetbitmap, and extend the API for - amgettuple to support run-time determination of - operator lossiness (Heikki, Tom, Teodor) - - - - The API for GIN and GiST opclass consistent functions - has been extended as well. - - - - - - Add support for partial-match searches in GIN indexes - (Teodor Sigaev, Oleg Bartunov) - - - - - - Replace pg_class column reltriggers - with boolean relhastriggers (Simon) - - - - Also remove unused pg_class columns - relukeys, relfkeys, and - relrefs. - - - - - - Add a relistemp column to pg_class - to ease identification of temporary tables (Tom) - - - - - - Move platform FAQs into the main documentation - (Peter) - - - - - - Prevent parser input files from being built with any conflicts - (Peter) - - - - - - Add support for the KOI8U (Ukrainian) encoding - (Peter) - - - - - - Add Japanese message translations (Japan PostgreSQL Users Group) - - - - This used to be maintained as a separate project. - - - - - - Fix problem when setting LC_MESSAGES on - MSVC-built systems (Hiroshi Inoue, Hiroshi - Saito, Magnus) - - - - - - - - - Contrib - - - - - - Add contrib/auto_explain to automatically run - EXPLAIN on queries exceeding a specified duration - (Itagaki Takahiro, Tom) - - - - - - Add contrib/btree_gin to allow GIN indexes to - handle more datatypes (Oleg, Teodor) - - - - - - Add contrib/citext to provide a case-insensitive, - multibyte-aware text data type (David Wheeler) - - - - - - Add contrib/pg_stat_statements for server-wide - tracking of statement execution statistics (Itagaki Takahiro) - - - - - - Add duration and query mode options to contrib/pgbench - (Itagaki Takahiro) - - - - - - Make contrib/pgbench use table names - pgbench_accounts, pgbench_branches, - pgbench_history, and pgbench_tellers, - rather than just accounts, branches, - history, and tellers (Tom) - - - - This is to reduce the risk of accidentally destroying real data - by running pgbench. - - - - - - Fix contrib/pgstattuple to handle tables and - indexes with over 2 billion pages (Tatsuhito Kasahara) - - - - - - In contrib/fuzzystrmatch, add a version of the - Levenshtein string-distance function that allows the user to - specify the costs of insertion, deletion, and substitution - (Volkan Yazici) - - - - - - Make contrib/ltree support multibyte encodings - (laser) - - - - - - Enable contrib/dblink to use connection information - stored in the SQL/MED catalogs (Joe Conway) - - - - - - Improve contrib/dblink's reporting of errors from - the remote server (Joe Conway) - - - - - - Make contrib/dblink set client_encoding - to match the local database's encoding (Joe Conway) - - - - This prevents encoding problems when communicating with a remote - database that uses a different encoding. - - - - - - Make sure contrib/dblink uses a password supplied - by the user, and not accidentally taken from the server's - .pgpass file (Joe Conway) - - - - This is a minor security enhancement. - - - - - - Add fsm_page_contents() - to contrib/pageinspect (Heikki) - - - - - - Modify get_raw_page() to support free space map - (*_fsm) files. Also update - contrib/pg_freespacemap. - - - - - - Add support for multibyte encodings to contrib/pg_trgm - (Teodor) - - - - - - Rewrite contrib/intagg to use new - functions array_agg() and unnest() - (Tom) - - - - - - Make contrib/pg_standby recover all available WAL before - failover (Fujii Masao, Simon, Heikki) - - - - To make this work safely, you now need to set the new - recovery_end_command option in recovery.conf - to clean up the trigger file after failover. pg_standby - will no longer remove the trigger file itself. - - - - - - contrib/pg_standby's option is now a no-op, - because it is unsafe to use a symlink (Simon) - - - - - - - - diff --git a/doc/src/sgml/release-9.0.sgml b/doc/src/sgml/release-9.0.sgml deleted file mode 100644 index 9e90f5a7f32..00000000000 --- a/doc/src/sgml/release-9.0.sgml +++ /dev/null @@ -1,11091 +0,0 @@ - - - - - Release 9.0.23 - - - Release date: - 2015-10-08 - - - - This release contains a variety of fixes from 9.0.22. - For information about new features in the 9.0 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 9.0.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 9.0.23 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.18, - see . - - - - - - Changes - - - - - - Fix contrib/pgcrypto to detect and report - too-short crypt() salts (Josh Kupershmidt) - - - - Certain invalid salt arguments crashed the server or disclosed a few - bytes of server memory. We have not ruled out the viability of - attacks that arrange for presence of confidential information in the - disclosed bytes, but they seem unlikely. (CVE-2015-5288) - - - - - - Fix subtransaction cleanup after a portal (cursor) belonging to an - outer subtransaction fails (Tom Lane, Michael Paquier) - - - - A function executed in an outer-subtransaction cursor could cause an - assertion failure or crash by referencing a relation created within an - inner subtransaction. - - - - - - Fix insertion of relations into the relation cache init file - (Tom Lane) - - - - An oversight in a patch in the most recent minor releases - caused pg_trigger_tgrelid_tgname_index to be omitted - from the init file. Subsequent sessions detected this, then deemed the - init file to be broken and silently ignored it, resulting in a - significant degradation in session startup time. In addition to fixing - the bug, install some guards so that any similar future mistake will be - more obvious. - - - - - - Avoid O(N^2) behavior when inserting many tuples into a SPI query - result (Neil Conway) - - - - - - Improve LISTEN startup time when there are many unread - notifications (Matt Newell) - - - - - - Disable SSL renegotiation by default (Michael Paquier, Andres Freund) - - - - While use of SSL renegotiation is a good idea in theory, we have seen - too many bugs in practice, both in the underlying OpenSSL library and - in our usage of it. Renegotiation will be removed entirely in 9.5 and - later. In the older branches, just change the default value - of ssl_renegotiation_limit to zero (disabled). - - - - - - Lower the minimum values of the *_freeze_max_age parameters - (Andres Freund) - - - - This is mainly to make tests of related behavior less time-consuming, - but it may also be of value for installations with limited disk space. - - - - - - Limit the maximum value of wal_buffers to 2GB to avoid - server crashes (Josh Berkus) - - - - - - Fix rare internal overflow in multiplication of numeric values - (Dean Rasheed) - - - - - - Guard against hard-to-reach stack overflows involving record types, - range types, json, jsonb, tsquery, - ltxtquery and query_int (Noah Misch) - - - - - - Fix handling of DOW and DOY in datetime input - (Greg Stark) - - - - These tokens aren't meant to be used in datetime values, but previously - they resulted in opaque internal error messages rather - than invalid input syntax. - - - - - - Add more query-cancel checks to regular expression matching (Tom Lane) - - - - - - Add recursion depth protections to regular expression, SIMILAR - TO, and LIKE matching (Tom Lane) - - - - Suitable search patterns and a low stack depth limit could lead to - stack-overrun crashes. - - - - - - Fix potential infinite loop in regular expression execution (Tom Lane) - - - - A search pattern that can apparently match a zero-length string, but - actually doesn't match because of a back reference, could lead to an - infinite loop. - - - - - - Fix low-memory failures in regular expression compilation - (Andreas Seltenreich) - - - - - - Fix low-probability memory leak during regular expression execution - (Tom Lane) - - - - - - Fix rare low-memory failure in lock cleanup during transaction abort - (Tom Lane) - - - - - - Fix unexpected out-of-memory situation during sort errors - when using tuplestores with small work_mem settings (Tom - Lane) - - - - - - Fix very-low-probability stack overrun in qsort (Tom Lane) - - - - - - Fix invalid memory alloc request size failure in hash joins - with large work_mem settings (Tomas Vondra, Tom Lane) - - - - - - Fix assorted planner bugs (Tom Lane) - - - - These mistakes could lead to incorrect query plans that would give wrong - answers, or to assertion failures in assert-enabled builds, or to odd - planner errors such as could not devise a query plan for the - given query, could not find pathkey item to - sort, plan should not reference subplan's variable, - or failed to assign all NestLoopParams to plan nodes. - Thanks are due to Andreas Seltenreich and Piotr Stefaniak for fuzz - testing that exposed these problems. - - - - - - Use fuzzy path cost tiebreaking rule in all supported branches (Tom Lane) - - - - This change is meant to avoid platform-specific behavior when - alternative plan choices have effectively-identical estimated costs. - - - - - - During postmaster shutdown, ensure that per-socket lock files are - removed and listen sockets are closed before we remove - the postmaster.pid file (Tom Lane) - - - - This avoids race-condition failures if an external script attempts to - start a new postmaster as soon as pg_ctl stop returns. - - - - - - Fix postmaster's handling of a startup-process crash during crash - recovery (Tom Lane) - - - - If, during a crash recovery cycle, the startup process crashes without - having restored database consistency, we'd try to launch a new startup - process, which typically would just crash again, leading to an infinite - loop. - - - - - - Do not print a WARNING when an autovacuum worker is already - gone when we attempt to signal it, and reduce log verbosity for such - signals (Tom Lane) - - - - - - Prevent autovacuum launcher from sleeping unduly long if the server - clock is moved backwards a large amount (Álvaro Herrera) - - - - - - Ensure that cleanup of a GIN index's pending-insertions list is - interruptable by cancel requests (Jeff Janes) - - - - - - Allow all-zeroes pages in GIN indexes to be reused (Heikki Linnakangas) - - - - Such a page might be left behind after a crash. - - - - - - Fix off-by-one error that led to otherwise-harmless warnings - about apparent wraparound in subtrans/multixact truncation - (Thomas Munro) - - - - - - Fix misreporting of CONTINUE and MOVE statement - types in PL/pgSQL's error context messages - (Pavel Stehule, Tom Lane) - - - - - - Fix some places in PL/Tcl that neglected to check for - failure of malloc() calls (Michael Paquier, Álvaro - Herrera) - - - - - - Improve libpq's handling of out-of-memory conditions - (Michael Paquier, Heikki Linnakangas) - - - - - - Fix memory leaks and missing out-of-memory checks - in ecpg (Michael Paquier) - - - - - - Fix psql's code for locale-aware formatting of numeric - output (Tom Lane) - - - - The formatting code invoked by \pset numericlocale on - did the wrong thing for some uncommon cases such as numbers with an - exponent but no decimal point. It could also mangle already-localized - output from the money data type. - - - - - - Prevent crash in psql's \c command when - there is no current connection (Noah Misch) - - - - - - Ensure that temporary files created during a pg_dump - run with tar-format output are not world-readable (Michael - Paquier) - - - - - - Fix pg_dump and pg_upgrade to support - cases where the postgres or template1 database - is in a non-default tablespace (Marti Raudsepp, Bruce Momjian) - - - - - - Fix pg_dump to handle object privileges sanely when - dumping from a server too old to have a particular privilege type - (Tom Lane) - - - - When dumping functions or procedural languages from pre-7.3 - servers, pg_dump would - produce GRANT/REVOKE commands that revoked the - owner's grantable privileges and instead granted all privileges - to PUBLIC. Since the privileges involved are - just USAGE and EXECUTE, this isn't a security - problem, but it's certainly a surprising representation of the older - systems' behavior. Fix it to leave the default privilege state alone - in these cases. - - - - - - Fix pg_dump to dump shell types (Tom Lane) - - - - Shell types (that is, not-yet-fully-defined types) aren't useful for - much, but nonetheless pg_dump should dump them. - - - - - - Fix spinlock assembly code for PPC hardware to be compatible - with AIX's native assembler (Tom Lane) - - - - Building with gcc didn't work if gcc - had been configured to use the native assembler, which is becoming more - common. - - - - - - On AIX, test the -qlonglong compiler option - rather than just assuming it's safe to use (Noah Misch) - - - - - - On AIX, use -Wl,-brtllib link option to allow - symbols to be resolved at runtime (Noah Misch) - - - - Perl relies on this ability in 5.8.0 and later. - - - - - - Avoid use of inline functions when compiling with - 32-bit xlc, due to compiler bugs (Noah Misch) - - - - - - Use librt for sched_yield() when necessary, - which it is on some Solaris versions (Oskari Saarenmaa) - - - - - - Fix Windows install.bat script to handle target directory - names that contain spaces (Heikki Linnakangas) - - - - - - Make the numeric form of the PostgreSQL version number - (e.g., 90405) readily available to extension Makefiles, - as a variable named VERSION_NUM (Michael Paquier) - - - - - - Update time zone data files to tzdata release 2015g for - DST law changes in Cayman Islands, Fiji, Moldova, Morocco, Norfolk - Island, North Korea, Turkey, and Uruguay. There is a new zone name - America/Fort_Nelson for the Canadian Northern Rockies. - - - - - - - - - - Release 9.0.22 - - - Release date: - 2015-06-12 - - - - This release contains a small number of fixes from 9.0.21. - For information about new features in the 9.0 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.0.X release series in September 2015. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.0.22 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.18, - see . - - - - - - Changes - - - - - - Fix rare failure to invalidate relation cache init file (Tom Lane) - - - - With just the wrong timing of concurrent activity, a VACUUM - FULL on a system catalog might fail to update the init file - that's used to avoid cache-loading work for new sessions. This would - result in later sessions being unable to access that catalog at all. - This is a very ancient bug, but it's so hard to trigger that no - reproducible case had been seen until recently. - - - - - - Avoid deadlock between incoming sessions and CREATE/DROP - DATABASE (Tom Lane) - - - - A new session starting in a database that is the target of - a DROP DATABASE command, or is the template for - a CREATE DATABASE command, could cause the command to wait - for five seconds and then fail, even if the new session would have - exited before that. - - - - - - - - - - Release 9.0.21 - - - Release date: - 2015-06-04 - - - - This release contains a small number of fixes from 9.0.20. - For information about new features in the 9.0 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.0.X release series in September 2015. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.0.21 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.18, - see . - - - - - - Changes - - - - - - Avoid failures while fsync'ing data directory during - crash restart (Abhijit Menon-Sen, Tom Lane) - - - - In the previous minor releases we added a patch to fsync - everything in the data directory after a crash. Unfortunately its - response to any error condition was to fail, thereby preventing the - server from starting up, even when the problem was quite harmless. - An example is that an unwritable file in the data directory would - prevent restart on some platforms; but it is common to make SSL - certificate files unwritable by the server. Revise this behavior so - that permissions failures are ignored altogether, and other types of - failures are logged but do not prevent continuing. - - - - - - Remove configure's check prohibiting linking to a - threaded libpython - on OpenBSD (Tom Lane) - - - - The failure this restriction was meant to prevent seems to not be a - problem anymore on current OpenBSD - versions. - - - - - - Allow libpq to use TLS protocol versions beyond v1 - (Noah Misch) - - - - For a long time, libpq was coded so that the only SSL - protocol it would allow was TLS v1. Now that newer TLS versions are - becoming popular, allow it to negotiate the highest commonly-supported - TLS version with the server. (PostgreSQL servers were - already capable of such negotiation, so no change is needed on the - server side.) This is a back-patch of a change already released in - 9.4.0. - - - - - - - - - - Release 9.0.20 - - - Release date: - 2015-05-22 - - - - This release contains a variety of fixes from 9.0.19. - For information about new features in the 9.0 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.0.X release series in September 2015. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.0.20 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.18, - see . - - - - - - Changes - - - - - - Avoid possible crash when client disconnects just before the - authentication timeout expires (Benkocs Norbert Attila) - - - - If the timeout interrupt fired partway through the session shutdown - sequence, SSL-related state would be freed twice, typically causing a - crash and hence denial of service to other sessions. Experimentation - shows that an unauthenticated remote attacker could trigger the bug - somewhat consistently, hence treat as security issue. - (CVE-2015-3165) - - - - - - Improve detection of system-call failures (Noah Misch) - - - - Our replacement implementation of snprintf() failed to - check for errors reported by the underlying system library calls; - the main case that might be missed is out-of-memory situations. - In the worst case this might lead to information exposure, due to our - code assuming that a buffer had been overwritten when it hadn't been. - Also, there were a few places in which security-relevant calls of other - system library functions did not check for failure. - - - - It remains possible that some calls of the *printf() - family of functions are vulnerable to information disclosure if an - out-of-memory error occurs at just the wrong time. We judge the risk - to not be large, but will continue analysis in this area. - (CVE-2015-3166) - - - - - - In contrib/pgcrypto, uniformly report decryption failures - as Wrong key or corrupt data (Noah Misch) - - - - Previously, some cases of decryption with an incorrect key could report - other error message texts. It has been shown that such variance in - error reports can aid attackers in recovering keys from other systems. - While it's unknown whether pgcrypto's specific behaviors - are likewise exploitable, it seems better to avoid the risk by using a - one-size-fits-all message. - (CVE-2015-3167) - - - - - - Fix incorrect checking of deferred exclusion constraints after a HOT - update (Tom Lane) - - - - If a new row that potentially violates a deferred exclusion constraint - is HOT-updated (that is, no indexed columns change and the row can be - stored back onto the same table page) later in the same transaction, - the exclusion constraint would be reported as violated when the check - finally occurred, even if the row(s) the new row originally conflicted - with had been deleted. - - - - - - Prevent improper reordering of antijoins (NOT EXISTS joins) versus - other outer joins (Tom Lane) - - - - This oversight in the planner has been observed to cause could - not find RelOptInfo for given relids errors, but it seems possible - that sometimes an incorrect query plan might get past that consistency - check and result in silently-wrong query output. - - - - - - Fix incorrect matching of subexpressions in outer-join plan nodes - (Tom Lane) - - - - Previously, if textually identical non-strict subexpressions were used - both above and below an outer join, the planner might try to re-use - the value computed below the join, which would be incorrect because the - executor would force the value to NULL in case of an unmatched outer row. - - - - - - Fix GEQO planner to cope with failure of its join order heuristic - (Tom Lane) - - - - This oversight has been seen to lead to failed to join all - relations together errors in queries involving LATERAL, - and that might happen in other cases as well. - - - - - - Fix possible deadlock at startup - when max_prepared_transactions is too small - (Heikki Linnakangas) - - - - - - Don't archive useless preallocated WAL files after a timeline switch - (Heikki Linnakangas) - - - - - - Avoid cannot GetMultiXactIdMembers() during recovery error - (Álvaro Herrera) - - - - - - Recursively fsync() the data directory after a crash - (Abhijit Menon-Sen, Robert Haas) - - - - This ensures consistency if another crash occurs shortly later. (The - second crash would have to be a system-level crash, not just a database - crash, for there to be a problem.) - - - - - - Fix autovacuum launcher's possible failure to shut down, if an error - occurs after it receives SIGTERM (Álvaro Herrera) - - - - - - Cope with unexpected signals in LockBufferForCleanup() - (Andres Freund) - - - - This oversight could result in spurious errors about multiple - backends attempting to wait for pincount 1. - - - - - - Avoid waiting for WAL flush or synchronous replication during commit of - a transaction that was read-only so far as the user is concerned - (Andres Freund) - - - - Previously, a delay could occur at commit in transactions that had - written WAL due to HOT page pruning, leading to undesirable effects - such as sessions getting stuck at startup if all synchronous replicas - are down. Sessions have also been observed to get stuck in catchup - interrupt processing when using synchronous replication; this will fix - that problem as well. - - - - - - Fix crash when manipulating hash indexes on temporary tables - (Heikki Linnakangas) - - - - - - Fix possible failure during hash index bucket split, if other processes - are modifying the index concurrently (Tom Lane) - - - - - - Check for interrupts while analyzing index expressions (Jeff Janes) - - - - ANALYZE executes index expressions many times; if there are - slow functions in such an expression, it's desirable to be able to - cancel the ANALYZE before that loop finishes. - - - - - - Add the name of the target server to object description strings for - foreign-server user mappings (Álvaro Herrera) - - - - - - Recommend setting include_realm to 1 when using - Kerberos/GSSAPI/SSPI authentication (Stephen Frost) - - - - Without this, identically-named users from different realms cannot be - distinguished. For the moment this is only a documentation change, but - it will become the default setting in PostgreSQL 9.5. - - - - - - Remove code for matching IPv4 pg_hba.conf entries to - IPv4-in-IPv6 addresses (Tom Lane) - - - - This hack was added in 2003 in response to a report that some Linux - kernels of the time would report IPv4 connections as having - IPv4-in-IPv6 addresses. However, the logic was accidentally broken in - 9.0. The lack of any field complaints since then shows that it's not - needed anymore. Now we have reports that the broken code causes - crashes on some systems, so let's just remove it rather than fix it. - (Had we chosen to fix it, that would make for a subtle and potentially - security-sensitive change in the effective meaning of - IPv4 pg_hba.conf entries, which does not seem like a good - thing to do in minor releases.) - - - - - - While shutting down service on Windows, periodically send status - updates to the Service Control Manager to prevent it from killing the - service too soon; and ensure that pg_ctl will wait for - shutdown (Krystian Bigaj) - - - - - - Reduce risk of network deadlock when using libpq's - non-blocking mode (Heikki Linnakangas) - - - - When sending large volumes of data, it's important to drain the input - buffer every so often, in case the server has sent enough response data - to cause it to block on output. (A typical scenario is that the server - is sending a stream of NOTICE messages during COPY FROM - STDIN.) This worked properly in the normal blocking mode, but not - so much in non-blocking mode. We've modified libpq - to opportunistically drain input when it can, but a full defense - against this problem requires application cooperation: the application - should watch for socket read-ready as well as write-ready conditions, - and be sure to call PQconsumeInput() upon read-ready. - - - - - - Fix array handling in ecpg (Michael Meskes) - - - - - - Fix psql to sanely handle URIs and conninfo strings as - the first parameter to \connect - (David Fetter, Andrew Dunstan, Álvaro Herrera) - - - - This syntax has been accepted (but undocumented) for a long time, but - previously some parameters might be taken from the old connection - instead of the given string, which was agreed to be undesirable. - - - - - - Suppress incorrect complaints from psql on some - platforms that it failed to write ~/.psql_history at exit - (Tom Lane) - - - - This misbehavior was caused by a workaround for a bug in very old - (pre-2006) versions of libedit. We fixed it by - removing the workaround, which will cause a similar failure to appear - for anyone still using such versions of libedit. - Recommendation: upgrade that library, or use libreadline. - - - - - - Fix pg_dump's rule for deciding which casts are - system-provided casts that should not be dumped (Tom Lane) - - - - - - Fix dumping of views that are just VALUES(...) but have - column aliases (Tom Lane) - - - - - - In pg_upgrade, force timeline 1 in the new cluster - (Bruce Momjian) - - - - This change prevents upgrade failures caused by bogus complaints about - missing WAL history files. - - - - - - In pg_upgrade, check for improperly non-connectable - databases before proceeding - (Bruce Momjian) - - - - - - In pg_upgrade, quote directory paths - properly in the generated delete_old_cluster script - (Bruce Momjian) - - - - - - In pg_upgrade, preserve database-level freezing info - properly - (Bruce Momjian) - - - - This oversight could cause missing-clog-file errors for tables within - the postgres and template1 databases. - - - - - - Run pg_upgrade and pg_resetxlog with - restricted privileges on Windows, so that they don't fail when run by - an administrator (Muhammad Asif Naeem) - - - - - - Fix slow sorting algorithm in contrib/intarray (Tom Lane) - - - - - - Fix compile failure on Sparc V8 machines (Rob Rowan) - - - - - - Update time zone data files to tzdata release 2015d - for DST law changes in Egypt, Mongolia, and Palestine, plus historical - changes in Canada and Chile. Also adopt revised zone abbreviations for - the America/Adak zone (HST/HDT not HAST/HADT). - - - - - - - - - - Release 9.0.19 - - - Release date: - 2015-02-05 - - - - This release contains a variety of fixes from 9.0.18. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.19 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.18, - see . - - - - - - Changes - - - - - - Fix buffer overruns in to_char() - (Bruce Momjian) - - - - When to_char() processes a numeric formatting template - calling for a large number of digits, PostgreSQL - would read past the end of a buffer. When processing a crafted - timestamp formatting template, PostgreSQL would write - past the end of a buffer. Either case could crash the server. - We have not ruled out the possibility of attacks that lead to - privilege escalation, though they seem unlikely. - (CVE-2015-0241) - - - - - - Fix buffer overrun in replacement *printf() functions - (Tom Lane) - - - - PostgreSQL includes a replacement implementation - of printf and related functions. This code will overrun - a stack buffer when formatting a floating point number (conversion - specifiers e, E, f, F, - g or G) with requested precision greater than - about 500. This will crash the server, and we have not ruled out the - possibility of attacks that lead to privilege escalation. - A database user can trigger such a buffer overrun through - the to_char() SQL function. While that is the only - affected core PostgreSQL functionality, extension - modules that use printf-family functions may be at risk as well. - - - - This issue primarily affects PostgreSQL on Windows. - PostgreSQL uses the system implementation of these - functions where adequate, which it is on other modern platforms. - (CVE-2015-0242) - - - - - - Fix buffer overruns in contrib/pgcrypto - (Marko Tiikkaja, Noah Misch) - - - - Errors in memory size tracking within the pgcrypto - module permitted stack buffer overruns and improper dependence on the - contents of uninitialized memory. The buffer overrun cases can - crash the server, and we have not ruled out the possibility of - attacks that lead to privilege escalation. - (CVE-2015-0243) - - - - - - Fix possible loss of frontend/backend protocol synchronization after - an error - (Heikki Linnakangas) - - - - If any error occurred while the server was in the middle of reading a - protocol message from the client, it could lose synchronization and - incorrectly try to interpret part of the message's data as a new - protocol message. An attacker able to submit crafted binary data - within a command parameter might succeed in injecting his own SQL - commands this way. Statement timeout and query cancellation are the - most likely sources of errors triggering this scenario. Particularly - vulnerable are applications that use a timeout and also submit - arbitrary user-crafted data as binary query parameters. Disabling - statement timeout will reduce, but not eliminate, the risk of - exploit. Our thanks to Emil Lenngren for reporting this issue. - (CVE-2015-0244) - - - - - - Fix information leak via constraint-violation error messages - (Stephen Frost) - - - - Some server error messages show the values of columns that violate - a constraint, such as a unique constraint. If the user does not have - SELECT privilege on all columns of the table, this could - mean exposing values that the user should not be able to see. Adjust - the code so that values are displayed only when they came from the SQL - command or could be selected by the user. - (CVE-2014-8161) - - - - - - Lock down regression testing's temporary installations on Windows - (Noah Misch) - - - - Use SSPI authentication to allow connections only from the OS user - who launched the test suite. This closes on Windows the same - vulnerability previously closed on other platforms, namely that other - users might be able to connect to the test postmaster. - (CVE-2014-0067) - - - - - - Avoid possible data corruption if ALTER DATABASE SET - TABLESPACE is used to move a database to a new tablespace and then - shortly later move it back to its original tablespace (Tom Lane) - - - - - - Avoid corrupting tables when ANALYZE inside a transaction - is rolled back (Andres Freund, Tom Lane, Michael Paquier) - - - - If the failing transaction had earlier removed the last index, rule, or - trigger from the table, the table would be left in a corrupted state - with the relevant pg_class flags not set though they - should be. - - - - - - Fix use-of-already-freed-memory problem in EvalPlanQual processing - (Tom Lane) - - - - In READ COMMITTED mode, queries that lock or update - recently-updated rows could crash as a result of this bug. - - - - - - Fix planning of SELECT FOR UPDATE when using a partial - index on a child table (Kyotaro Horiguchi) - - - - In READ COMMITTED mode, SELECT FOR UPDATE must - also recheck the partial index's WHERE condition when - rechecking a recently-updated row to see if it still satisfies the - query's WHERE condition. This requirement was missed if the - index belonged to an inheritance child table, so that it was possible - to incorrectly return rows that no longer satisfy the query condition. - - - - - - Fix corner case wherein SELECT FOR UPDATE could return a row - twice, and possibly miss returning other rows (Tom Lane) - - - - In READ COMMITTED mode, a SELECT FOR UPDATE - that is scanning an inheritance tree could incorrectly return a row - from a prior child table instead of the one it should return from a - later child table. - - - - - - Reject duplicate column names in the referenced-columns list of - a FOREIGN KEY declaration (David Rowley) - - - - This restriction is per SQL standard. Previously we did not reject - the case explicitly, but later on the code would fail with - bizarre-looking errors. - - - - - - Fix bugs in raising a numeric value to a large integral power - (Tom Lane) - - - - The previous code could get a wrong answer, or consume excessive - amounts of time and memory before realizing that the answer must - overflow. - - - - - - In numeric_recv(), truncate away any fractional digits - that would be hidden according to the value's dscale field - (Tom Lane) - - - - A numeric value's display scale (dscale) should - never be less than the number of nonzero fractional digits; but - apparently there's at least one broken client application that - transmits binary numeric values in which that's true. - This leads to strange behavior since the extra digits are taken into - account by arithmetic operations even though they aren't printed. - The least risky fix seems to be to truncate away such hidden - digits on receipt, so that the value is indeed what it prints as. - - - - - - Reject out-of-range numeric timezone specifications (Tom Lane) - - - - Simple numeric timezone specifications exceeding +/- 168 hours (one - week) would be accepted, but could then cause null-pointer dereference - crashes in certain operations. There's no use-case for such large UTC - offsets, so reject them. - - - - - - Fix bugs in tsquery @> tsquery - operator (Heikki Linnakangas) - - - - Two different terms would be considered to match if they had the same - CRC. Also, if the second operand had more terms than the first, it - would be assumed not to be contained in the first; which is wrong - since it might contain duplicate terms. - - - - - - Improve ispell dictionary's defenses against bad affix files (Tom Lane) - - - - - - Allow more than 64K phrases in a thesaurus dictionary (David Boutin) - - - - The previous coding could crash on an oversize dictionary, so this was - deemed a back-patchable bug fix rather than a feature addition. - - - - - - Fix namespace handling in xpath() (Ali Akbar) - - - - Previously, the xml value resulting from - an xpath() call would not have namespace declarations if - the namespace declarations were attached to an ancestor element in the - input xml value, rather than to the specific element being - returned. Propagate the ancestral declaration so that the result is - correct when considered in isolation. - - - - - - Fix planner problems with nested append relations, such as inherited - tables within UNION ALL subqueries (Tom Lane) - - - - - - Fail cleanly when a GiST index tuple doesn't fit on a page, rather - than going into infinite recursion (Andrew Gierth) - - - - - - Exempt tables that have per-table cost_limit - and/or cost_delay settings from autovacuum's global cost - balancing rules (Álvaro Herrera) - - - - The previous behavior resulted in basically ignoring these per-table - settings, which was unintended. Now, a table having such settings - will be vacuumed using those settings, independently of what is going - on in other autovacuum workers. This may result in heavier total I/O - load than before, so such settings should be re-examined for sanity. - - - - - - Avoid wholesale autovacuuming when autovacuum is nominally off - (Tom Lane) - - - - Even when autovacuum is nominally off, we will still launch autovacuum - worker processes to vacuum tables that are at risk of XID wraparound. - However, such a worker process then proceeded to vacuum all tables in - the target database, if they met the usual thresholds for - autovacuuming. This is at best pretty unexpected; at worst it delays - response to the wraparound threat. Fix it so that if autovacuum is - turned off, workers only do anti-wraparound vacuums and - not any other work. - - - - - - Fix race condition between hot standby queries and replaying a - full-page image (Heikki Linnakangas) - - - - This mistake could result in transient errors in queries being - executed in hot standby. - - - - - - Fix several cases where recovery logic improperly ignored WAL records - for COMMIT/ABORT PREPARED (Heikki Linnakangas) - - - - The most notable oversight was - that recovery_target_xid could not be used to stop at - a two-phase commit. - - - - - - Avoid creating unnecessary .ready marker files for - timeline history files (Fujii Masao) - - - - - - Fix possible null pointer dereference when an empty prepared statement - is used and the log_statement setting is mod - or ddl (Fujii Masao) - - - - - - Change pgstat wait timeout warning message to be LOG level, - and rephrase it to be more understandable (Tom Lane) - - - - This message was originally thought to be essentially a can't-happen - case, but it occurs often enough on our slower buildfarm members to be - a nuisance. Reduce it to LOG level, and expend a bit more effort on - the wording: it now reads using stale statistics instead of - current ones because stats collector is not responding. - - - - - - Fix SPARC spinlock implementation to ensure correctness if the CPU is - being run in a non-TSO coherency mode, as some non-Solaris kernels do - (Andres Freund) - - - - - - Warn if macOS's setlocale() starts an unwanted extra - thread inside the postmaster (Noah Misch) - - - - - - Fix processing of repeated dbname parameters - in PQconnectdbParams() (Alex Shulgin) - - - - Unexpected behavior ensued if the first occurrence - of dbname contained a connection string or URI to be - expanded. - - - - - - Ensure that libpq reports a suitable error message on - unexpected socket EOF (Marko Tiikkaja, Tom Lane) - - - - Depending on kernel behavior, libpq might return an - empty error string rather than something useful when the server - unexpectedly closed the socket. - - - - - - Clear any old error message during PQreset() - (Heikki Linnakangas) - - - - If PQreset() is called repeatedly, and the connection - cannot be re-established, error messages from the failed connection - attempts kept accumulating in the PGconn's error - string. - - - - - - Properly handle out-of-memory conditions while parsing connection - options in libpq (Alex Shulgin, Heikki Linnakangas) - - - - - - Fix array overrun in ecpg's version - of ParseDateTime() (Michael Paquier) - - - - - - In initdb, give a clearer error message if a password - file is specified but is empty (Mats Erik Andersson) - - - - - - Fix psql's \s command to work nicely with - libedit, and add pager support (Stepan Rutz, Tom Lane) - - - - When using libedit rather than readline, \s printed the - command history in a fairly unreadable encoded format, and on recent - libedit versions might fail altogether. Fix that by printing the - history ourselves rather than having the library do it. A pleasant - side-effect is that the pager is used if appropriate. - - - - This patch also fixes a bug that caused newline encoding to be applied - inconsistently when saving the command history with libedit. - Multiline history entries written by older psql - versions will be read cleanly with this patch, but perhaps not - vice versa, depending on the exact libedit versions involved. - - - - - - Improve consistency of parsing of psql's special - variables (Tom Lane) - - - - Allow variant spellings of on and off (such - as 1/0) for ECHO_HIDDEN - and ON_ERROR_ROLLBACK. Report a warning for unrecognized - values for COMP_KEYWORD_CASE, ECHO, - ECHO_HIDDEN, HISTCONTROL, - ON_ERROR_ROLLBACK, and VERBOSITY. Recognize - all values for all these variables case-insensitively; previously - there was a mishmash of case-sensitive and case-insensitive behaviors. - - - - - - Fix psql's expanded-mode display to work - consistently when using border = 3 - and linestyle = ascii or unicode - (Stephen Frost) - - - - - - Fix possible deadlock during parallel restore of a schema-only dump - (Robert Haas, Tom Lane) - - - - - - Fix core dump in pg_dump --binary-upgrade on zero-column - composite type (Rushabh Lathia) - - - - - - Fix block number checking - in contrib/pageinspect's get_raw_page() - (Tom Lane) - - - - The incorrect checking logic could prevent access to some pages in - non-main relation forks. - - - - - - Fix contrib/pgcrypto's pgp_sym_decrypt() - to not fail on messages whose length is 6 less than a power of 2 - (Marko Tiikkaja) - - - - - - Handle unexpected query results, especially NULLs, safely in - contrib/tablefunc's connectby() - (Michael Paquier) - - - - connectby() previously crashed if it encountered a NULL - key value. It now prints that row but doesn't recurse further. - - - - - - Avoid a possible crash in contrib/xml2's - xslt_process() (Mark Simonetti) - - - - libxslt seems to have an undocumented dependency on - the order in which resources are freed; reorder our calls to avoid a - crash. - - - - - - Numerous cleanups of warnings from Coverity static code analyzer - (Andres Freund, Tatsuo Ishii, Marko Kreen, Tom Lane, Michael Paquier) - - - - These changes are mostly cosmetic but in some cases fix corner-case - bugs, for example a crash rather than a proper error report after an - out-of-memory failure. None are believed to represent security - issues. - - - - - - Detect incompatible OpenLDAP versions during build (Noah Misch) - - - - With OpenLDAP versions 2.4.24 through 2.4.31, - inclusive, PostgreSQL backends can crash at exit. - Raise a warning during configure based on the - compile-time OpenLDAP version number, and test the crashing scenario - in the contrib/dblink regression test. - - - - - - In non-MSVC Windows builds, ensure libpq.dll is installed - with execute permissions (Noah Misch) - - - - - - Make pg_regress remove any temporary installation it - created upon successful exit (Tom Lane) - - - - This results in a very substantial reduction in disk space usage - during make check-world, since that sequence involves - creation of numerous temporary installations. - - - - - - Support time zone abbreviations that change UTC offset from time to - time (Tom Lane) - - - - Previously, PostgreSQL assumed that the UTC offset - associated with a time zone abbreviation (such as EST) - never changes in the usage of any particular locale. However this - assumption fails in the real world, so introduce the ability for a - zone abbreviation to represent a UTC offset that sometimes changes. - Update the zone abbreviation definition files to make use of this - feature in timezone locales that have changed the UTC offset of their - abbreviations since 1970 (according to the IANA timezone database). - In such timezones, PostgreSQL will now associate the - correct UTC offset with the abbreviation depending on the given date. - - - - - - Update time zone abbreviations lists (Tom Lane) - - - - Add CST (China Standard Time) to our lists. - Remove references to ADT as Arabia Daylight Time, an - abbreviation that's been out of use since 2007; therefore, claiming - there is a conflict with Atlantic Daylight Time doesn't seem - especially helpful. - Fix entirely incorrect GMT offsets for CKT (Cook Islands), FJT, and FJST - (Fiji); we didn't even have them on the proper side of the date line. - - - - - - Update time zone data files to tzdata release 2015a. - - - - The IANA timezone database has adopted abbreviations of the form - AxST/AxDT - for all Australian time zones, reflecting what they believe to be - current majority practice Down Under. These names do not conflict - with usage elsewhere (other than ACST for Acre Summer Time, which has - been in disuse since 1994). Accordingly, adopt these names into - our Default timezone abbreviation set. - The Australia abbreviation set now contains only CST, EAST, - EST, SAST, SAT, and WST, all of which are thought to be mostly - historical usage. Note that SAST has also been changed to be South - Africa Standard Time in the Default abbreviation set. - - - - Also, add zone abbreviations SRET (Asia/Srednekolymsk) and XJT - (Asia/Urumqi), and use WSST/WSDT for western Samoa. Also, there were - DST law changes in Chile, Mexico, the Turks & Caicos Islands - (America/Grand_Turk), and Fiji. There is a new zone - Pacific/Bougainville for portions of Papua New Guinea. Also, numerous - corrections for historical (pre-1970) time zone data. - - - - - - - - - - Release 9.0.18 - - - Release date: - 2014-07-24 - - - - This release contains a variety of fixes from 9.0.17. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.18 - - - A dump/restore is not required for those running 9.0.X. - - - - However, this release corrects an index corruption problem in some GiST - indexes. See the first changelog entry below to find out whether your - installation has been affected and what steps you should take if so. - - - - Also, if you are upgrading from a version earlier than 9.0.15, - see . - - - - - - Changes - - - - - - Correctly initialize padding bytes in contrib/btree_gist - indexes on bit columns (Heikki Linnakangas) - - - - This error could result in incorrect query results due to values that - should compare equal not being seen as equal. - Users with GiST indexes on bit or bit varying - columns should REINDEX those indexes after installing this - update. - - - - - - Protect against torn pages when deleting GIN list pages (Heikki - Linnakangas) - - - - This fix prevents possible index corruption if a system crash occurs - while the page update is being written to disk. - - - - - - Don't clear the right-link of a GiST index page while replaying - updates from WAL (Heikki Linnakangas) - - - - This error could lead to transiently wrong answers from GiST index - scans performed in Hot Standby. - - - - - - Fix possibly-incorrect cache invalidation during nested calls - to ReceiveSharedInvalidMessages (Andres Freund) - - - - - - Don't assume a subquery's output is unique if there's a set-returning - function in its targetlist (David Rowley) - - - - This oversight could lead to misoptimization of constructs - like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP - BY y). - - - - - - Fix failure to detoast fields in composite elements of structured - types (Tom Lane) - - - - This corrects cases where TOAST pointers could be copied into other - tables without being dereferenced. If the original data is later - deleted, it would lead to errors like missing chunk number 0 - for toast value ... when the now-dangling pointer is used. - - - - - - Fix record type has not been registered failures with - whole-row references to the output of Append plan nodes (Tom Lane) - - - - - - Fix possible crash when invoking a user-defined function while - rewinding a cursor (Tom Lane) - - - - - - Fix query-lifespan memory leak while evaluating the arguments for a - function in FROM (Tom Lane) - - - - - - Fix session-lifespan memory leaks in regular-expression processing - (Tom Lane, Arthur O'Dwyer, Greg Stark) - - - - - - Fix data encoding error in hungarian.stop (Tom Lane) - - - - - - Fix liveness checks for rows that were inserted in the current - transaction and then deleted by a now-rolled-back subtransaction - (Andres Freund) - - - - This could cause problems (at least spurious warnings, and at worst an - infinite loop) if CREATE INDEX or CLUSTER were - done later in the same transaction. - - - - - - Clear pg_stat_activity.xact_start - during PREPARE TRANSACTION (Andres Freund) - - - - After the PREPARE, the originating session is no longer in - a transaction, so it should not continue to display a transaction - start time. - - - - - - Fix REASSIGN OWNED to not fail for text search objects - (Álvaro Herrera) - - - - - - Block signals during postmaster startup (Tom Lane) - - - - This ensures that the postmaster will properly clean up after itself - if, for example, it receives SIGINT while still - starting up. - - - - - - Secure Unix-domain sockets of temporary postmasters started during - make check (Noah Misch) - - - - Any local user able to access the socket file could connect as the - server's bootstrap superuser, then proceed to execute arbitrary code as - the operating-system user running the test, as we previously noted in - CVE-2014-0067. This change defends against that risk by placing the - server's socket in a temporary, mode 0700 subdirectory - of /tmp. The hazard remains however on platforms where - Unix sockets are not supported, notably Windows, because then the - temporary postmaster must accept local TCP connections. - - - - A useful side effect of this change is to simplify - make check testing in builds that - override DEFAULT_PGSOCKET_DIR. Popular non-default values - like /var/run/postgresql are often not writable by the - build user, requiring workarounds that will no longer be necessary. - - - - - - Fix tablespace creation WAL replay to work on Windows (MauMau) - - - - - - Fix detection of socket creation failures on Windows (Bruce Momjian) - - - - - - On Windows, allow new sessions to absorb values of PGC_BACKEND - parameters (such as ) from the - configuration file (Amit Kapila) - - - - Previously, if such a parameter were changed in the file post-startup, - the change would have no effect. - - - - - - Properly quote executable path names on Windows (Nikhil Deshpande) - - - - This oversight could cause initdb - and pg_upgrade to fail on Windows, if the installation - path contained both spaces and @ signs. - - - - - - Fix linking of libpython on macOS (Tom Lane) - - - - The method we previously used can fail with the Python library - supplied by Xcode 5.0 and later. - - - - - - Avoid buffer bloat in libpq when the server - consistently sends data faster than the client can absorb it - (Shin-ichi Morita, Tom Lane) - - - - libpq could be coerced into enlarging its input buffer - until it runs out of memory (which would be reported misleadingly - as lost synchronization with server). Under ordinary - circumstances it's quite far-fetched that data could be continuously - transmitted more quickly than the recv() loop can - absorb it, but this has been observed when the client is artificially - slowed by scheduler constraints. - - - - - - Ensure that LDAP lookup attempts in libpq time out as - intended (Laurenz Albe) - - - - - - Fix ecpg to do the right thing when an array - of char * is the target for a FETCH statement returning more - than one row, as well as some other array-handling fixes - (Ashutosh Bapat) - - - - - - Fix pg_restore's processing of old-style large object - comments (Tom Lane) - - - - A direct-to-database restore from an archive file generated by a - pre-9.0 version of pg_dump would usually fail if the - archive contained more than a few comments for large objects. - - - - - - In contrib/pgcrypto functions, ensure sensitive - information is cleared from stack variables before returning - (Marko Kreen) - - - - - - In contrib/uuid-ossp, cache the state of the OSSP UUID - library across calls (Tom Lane) - - - - This improves the efficiency of UUID generation and reduces the amount - of entropy drawn from /dev/urandom, on platforms that - have that. - - - - - - Update time zone data files to tzdata release 2014e - for DST law changes in Crimea, Egypt, and Morocco. - - - - - - - - - - Release 9.0.17 - - - Release date: - 2014-03-20 - - - - This release contains a variety of fixes from 9.0.16. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.17 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.15, - see . - - - - - - Changes - - - - - - Restore GIN metapages unconditionally to avoid torn-page risk - (Heikki Linnakangas) - - - - Although this oversight could theoretically result in a corrupted - index, it is unlikely to have caused any problems in practice, since - the active part of a GIN metapage is smaller than a standard 512-byte - disk sector. - - - - - - Avoid race condition in checking transaction commit status during - receipt of a NOTIFY message (Marko Tiikkaja) - - - - This prevents a scenario wherein a sufficiently fast client might - respond to a notification before database updates made by the - notifier have become visible to the recipient. - - - - - - Allow regular-expression operators to be terminated early by query - cancel requests (Tom Lane) - - - - This prevents scenarios wherein a pathological regular expression - could lock up a server process uninterruptibly for a long time. - - - - - - Remove incorrect code that tried to allow OVERLAPS with - single-element row arguments (Joshua Yanovski) - - - - This code never worked correctly, and since the case is neither - specified by the SQL standard nor documented, it seemed better to - remove it than fix it. - - - - - - Avoid getting more than AccessShareLock when de-parsing a - rule or view (Dean Rasheed) - - - - This oversight resulted in pg_dump unexpectedly - acquiring RowExclusiveLock locks on tables mentioned as - the targets of INSERT/UPDATE/DELETE - commands in rules. While usually harmless, that could interfere with - concurrent transactions that tried to acquire, for example, - ShareLock on those tables. - - - - - - Improve performance of index endpoint probes during planning (Tom Lane) - - - - This change fixes a significant performance problem that occurred - when there were many not-yet-committed rows at the end of the index, - which is a common situation for indexes on sequentially-assigned - values such as timestamps or sequence-generated identifiers. - - - - - - Fix test to see if hot standby connections can be allowed immediately - after a crash (Heikki Linnakangas) - - - - - - Prevent interrupts while reporting non-ERROR messages - (Tom Lane) - - - - This guards against rare server-process freezeups due to recursive - entry to syslog(), and perhaps other related problems. - - - - - - Prevent intermittent could not reserve shared memory region - failures on recent Windows versions (MauMau) - - - - - - Update time zone data files to tzdata release 2014a - for DST law changes in Fiji and Turkey, plus historical changes in - Israel and Ukraine. - - - - - - - - - - Release 9.0.16 - - - Release date: - 2014-02-20 - - - - This release contains a variety of fixes from 9.0.15. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.16 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.15, - see . - - - - - - Changes - - - - - - Shore up GRANT ... WITH ADMIN OPTION restrictions - (Noah Misch) - - - - Granting a role without ADMIN OPTION is supposed to - prevent the grantee from adding or removing members from the granted - role, but this restriction was easily bypassed by doing SET - ROLE first. The security impact is mostly that a role member can - revoke the access of others, contrary to the wishes of his grantor. - Unapproved role member additions are a lesser concern, since an - uncooperative role member could provide most of his rights to others - anyway by creating views or SECURITY DEFINER functions. - (CVE-2014-0060) - - - - - - Prevent privilege escalation via manual calls to PL validator - functions (Andres Freund) - - - - The primary role of PL validator functions is to be called implicitly - during CREATE FUNCTION, but they are also normal SQL - functions that a user can call explicitly. Calling a validator on - a function actually written in some other language was not checked - for and could be exploited for privilege-escalation purposes. - The fix involves adding a call to a privilege-checking function in - each validator function. Non-core procedural languages will also - need to make this change to their own validator functions, if any. - (CVE-2014-0061) - - - - - - Avoid multiple name lookups during table and index DDL - (Robert Haas, Andres Freund) - - - - If the name lookups come to different conclusions due to concurrent - activity, we might perform some parts of the DDL on a different table - than other parts. At least in the case of CREATE INDEX, - this can be used to cause the permissions checks to be performed - against a different table than the index creation, allowing for a - privilege escalation attack. - (CVE-2014-0062) - - - - - - Prevent buffer overrun with long datetime strings (Noah Misch) - - - - The MAXDATELEN constant was too small for the longest - possible value of type interval, allowing a buffer overrun - in interval_out(). Although the datetime input - functions were more careful about avoiding buffer overrun, the limit - was short enough to cause them to reject some valid inputs, such as - input containing a very long timezone name. The ecpg - library contained these vulnerabilities along with some of its own. - (CVE-2014-0063) - - - - - - Prevent buffer overrun due to integer overflow in size calculations - (Noah Misch, Heikki Linnakangas) - - - - Several functions, mostly type input functions, calculated an - allocation size without checking for overflow. If overflow did - occur, a too-small buffer would be allocated and then written past. - (CVE-2014-0064) - - - - - - Prevent overruns of fixed-size buffers - (Peter Eisentraut, Jozef Mlich) - - - - Use strlcpy() and related functions to provide a clear - guarantee that fixed-size buffers are not overrun. Unlike the - preceding items, it is unclear whether these cases really represent - live issues, since in most cases there appear to be previous - constraints on the size of the input string. Nonetheless it seems - prudent to silence all Coverity warnings of this type. - (CVE-2014-0065) - - - - - - Avoid crashing if crypt() returns NULL (Honza Horak, - Bruce Momjian) - - - - There are relatively few scenarios in which crypt() - could return NULL, but contrib/chkpass would crash - if it did. One practical case in which this could be an issue is - if libc is configured to refuse to execute unapproved - hashing algorithms (e.g., FIPS mode). - (CVE-2014-0066) - - - - - - Document risks of make check in the regression testing - instructions (Noah Misch, Tom Lane) - - - - Since the temporary server started by make check - uses trust authentication, another user on the same machine - could connect to it as database superuser, and then potentially - exploit the privileges of the operating-system user who started the - tests. A future release will probably incorporate changes in the - testing procedure to prevent this risk, but some public discussion is - needed first. So for the moment, just warn people against using - make check when there are untrusted users on the - same machine. - (CVE-2014-0067) - - - - - - Fix possible mis-replay of WAL records when some segments of a - relation aren't full size (Greg Stark, Tom Lane) - - - - The WAL update could be applied to the wrong page, potentially many - pages past where it should have been. Aside from corrupting data, - this error has been observed to result in significant bloat - of standby servers compared to their masters, due to updates being - applied far beyond where the end-of-file should have been. This - failure mode does not appear to be a significant risk during crash - recovery, only when initially synchronizing a standby created from a - base backup taken from a quickly-changing master. - - - - - - Fix bug in determining when recovery has reached consistency - (Tomonari Katsumata, Heikki Linnakangas) - - - - In some cases WAL replay would mistakenly conclude that the database - was already consistent at the start of replay, thus possibly allowing - hot-standby queries before the database was really consistent. Other - symptoms such as PANIC: WAL contains references to invalid - pages were also possible. - - - - - - Fix improper locking of btree index pages while replaying - a VACUUM operation in hot-standby mode (Andres Freund, - Heikki Linnakangas, Tom Lane) - - - - This error could result in PANIC: WAL contains references to - invalid pages failures. - - - - - - Ensure that insertions into non-leaf GIN index pages write a full-page - WAL record when appropriate (Heikki Linnakangas) - - - - The previous coding risked index corruption in the event of a - partial-page write during a system crash. - - - - - - Fix race conditions during server process exit (Robert Haas) - - - - Ensure that signal handlers don't attempt to use the - process's MyProc pointer after it's no longer valid. - - - - - - Fix unsafe references to errno within error reporting - logic (Christian Kruse) - - - - This would typically lead to odd behaviors such as missing or - inappropriate HINT fields. - - - - - - Fix possible crashes from using ereport() too early - during server startup (Tom Lane) - - - - The principal case we've seen in the field is a crash if the server - is started in a directory it doesn't have permission to read. - - - - - - Clear retry flags properly in OpenSSL socket write - function (Alexander Kukushkin) - - - - This omission could result in a server lockup after unexpected loss - of an SSL-encrypted connection. - - - - - - Fix length checking for Unicode identifiers (U&"..." - syntax) containing escapes (Tom Lane) - - - - A spurious truncation warning would be printed for such identifiers - if the escaped form of the identifier was too long, but the - identifier actually didn't need truncation after de-escaping. - - - - - - Allow keywords that are type names to be used in lists of roles - (Stephen Frost) - - - - A previous patch allowed such keywords to be used without quoting - in places such as role identifiers; but it missed cases where a - list of role identifiers was permitted, such as DROP ROLE. - - - - - - Fix possible crash due to invalid plan for nested sub-selects, such - as WHERE (... x IN (SELECT ...) ...) IN (SELECT ...) - (Tom Lane) - - - - - - Ensure that ANALYZE creates statistics for a table column - even when all the values in it are too wide (Tom Lane) - - - - ANALYZE intentionally omits very wide values from its - histogram and most-common-values calculations, but it neglected to do - something sane in the case that all the sampled entries are too wide. - - - - - - In ALTER TABLE ... SET TABLESPACE, allow the database's - default tablespace to be used without a permissions check - (Stephen Frost) - - - - CREATE TABLE has always allowed such usage, - but ALTER TABLE didn't get the memo. - - - - - - Fix cannot accept a set error when some arms of - a CASE return a set and others don't (Tom Lane) - - - - - - Fix checks for all-zero client addresses in pgstat functions (Kevin - Grittner) - - - - - - Fix possible misclassification of multibyte characters by the text - search parser (Tom Lane) - - - - Non-ASCII characters could be misclassified when using C locale with - a multibyte encoding. On Cygwin, non-C locales could fail as well. - - - - - - Fix possible misbehavior in plainto_tsquery() - (Heikki Linnakangas) - - - - Use memmove() not memcpy() for copying - overlapping memory regions. There have been no field reports of - this actually causing trouble, but it's certainly risky. - - - - - - Accept SHIFT_JIS as an encoding name for locale checking - purposes (Tatsuo Ishii) - - - - - - Fix misbehavior of PQhost() on Windows (Fujii Masao) - - - - It should return localhost if no host has been specified. - - - - - - Improve error handling in libpq and psql - for failures during COPY TO STDOUT/FROM STDIN (Tom Lane) - - - - In particular this fixes an infinite loop that could occur in 9.2 and - up if the server connection was lost during COPY FROM - STDIN. Variants of that scenario might be possible in older - versions, or with other client applications. - - - - - - Fix misaligned descriptors in ecpg (MauMau) - - - - - - In ecpg, handle lack of a hostname in the connection - parameters properly (Michael Meskes) - - - - - - Fix performance regression in contrib/dblink connection - startup (Joe Conway) - - - - Avoid an unnecessary round trip when client and server encodings match. - - - - - - In contrib/isn, fix incorrect calculation of the check - digit for ISMN values (Fabien Coelho) - - - - - - Ensure client-code-only installation procedure works as documented - (Peter Eisentraut) - - - - - - In Mingw and Cygwin builds, install the libpq DLL - in the bin directory (Andrew Dunstan) - - - - This duplicates what the MSVC build has long done. It should fix - problems with programs like psql failing to start - because they can't find the DLL. - - - - - - Avoid using the deprecated dllwrap tool in Cygwin builds - (Marco Atzeri) - - - - - - Don't generate plain-text HISTORY - and src/test/regress/README files anymore (Tom Lane) - - - - These text files duplicated the main HTML and PDF documentation - formats. The trouble involved in maintaining them greatly outweighs - the likely audience for plain-text format. Distribution tarballs - will still contain files by these names, but they'll just be stubs - directing the reader to consult the main documentation. - The plain-text INSTALL file will still be maintained, as - there is arguably a use-case for that. - - - - - - Update time zone data files to tzdata release 2013i - for DST law changes in Jordan and historical changes in Cuba. - - - - In addition, the zones Asia/Riyadh87, - Asia/Riyadh88, and Asia/Riyadh89 have been - removed, as they are no longer maintained by IANA, and never - represented actual civil timekeeping practice. - - - - - - - - - - Release 9.0.15 - - - Release date: - 2013-12-05 - - - - This release contains a variety of fixes from 9.0.14. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.15 - - - A dump/restore is not required for those running 9.0.X. - - - - However, this release corrects a number of potential data corruption - issues. See the first two changelog entries below to find out whether - your installation has been affected and what steps you can take if so. - - - - Also, if you are upgrading from a version earlier than 9.0.13, - see . - - - - - - Changes - - - - - - Fix VACUUM's tests to see whether it can - update relfrozenxid (Andres Freund) - - - - In some cases VACUUM (either manual or autovacuum) could - incorrectly advance a table's relfrozenxid value, - allowing tuples to escape freezing, causing those rows to become - invisible once 2^31 transactions have elapsed. The probability of - data loss is fairly low since multiple incorrect advancements would - need to happen before actual loss occurs, but it's not zero. Users - upgrading from releases 9.0.4 or 8.4.8 or earlier are not affected, but - all later versions contain the bug. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix any latent corruption but will not be able - to fix all pre-existing data errors. However, an installation can be - presumed safe after performing this vacuuming if it has executed fewer - than 2^31 update transactions in its lifetime (check this with - SELECT txid_current() < 2^31). - - - - - - Fix initialization of pg_clog and pg_subtrans - during hot standby startup (Andres Freund, Heikki Linnakangas) - - - - This bug can cause data loss on standby servers at the moment they - start to accept hot-standby queries, by marking committed transactions - as uncommitted. The likelihood of such corruption is small unless, at - the time of standby startup, the primary server has executed many - updating transactions since its last checkpoint. Symptoms include - missing rows, rows that should have been deleted being still visible, - and obsolete versions of updated rows being still visible alongside - their newer versions. - - - - This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. - Standby servers that have only been running earlier releases are not - at risk. It's recommended that standby servers that have ever run any - of the buggy releases be re-cloned from the primary (e.g., with a new - base backup) after upgrading. - - - - - - Truncate pg_multixact contents during WAL replay - (Andres Freund) - - - - This avoids ever-increasing disk space consumption in standby servers. - - - - - - Fix race condition in GIN index posting tree page deletion (Heikki - Linnakangas) - - - - This could lead to transient wrong answers or query failures. - - - - - - Avoid flattening a subquery whose SELECT list contains a - volatile function wrapped inside a sub-SELECT (Tom Lane) - - - - This avoids unexpected results due to extra evaluations of the - volatile function. - - - - - - Fix planner's processing of non-simple-variable subquery outputs - nested within outer joins (Tom Lane) - - - - This error could lead to incorrect plans for queries involving - multiple levels of subqueries within JOIN syntax. - - - - - - Fix premature deletion of temporary files (Andres Freund) - - - - - - Fix possible read past end of memory in rule printing (Peter Eisentraut) - - - - - - Fix array slicing of int2vector and oidvector values - (Tom Lane) - - - - Expressions of this kind are now implicitly promoted to - regular int2 or oid arrays. - - - - - - Fix incorrect behaviors when using a SQL-standard, simple GMT offset - timezone (Tom Lane) - - - - In some cases, the system would use the simple GMT offset value when - it should have used the regular timezone setting that had prevailed - before the simple offset was selected. This change also causes - the timeofday function to honor the simple GMT offset - zone. - - - - - - Prevent possible misbehavior when logging translations of Windows - error codes (Tom Lane) - - - - - - Properly quote generated command lines in pg_ctl - (Naoya Anzai and Tom Lane) - - - - This fix applies only to Windows. - - - - - - Fix pg_dumpall to work when a source database - sets default_transaction_read_only - via ALTER DATABASE SET (Kevin Grittner) - - - - Previously, the generated script would fail during restore. - - - - - - Fix ecpg's processing of lists of variables - declared varchar (Zoltán Böszörményi) - - - - - - Make contrib/lo defend against incorrect trigger definitions - (Marc Cousin) - - - - - - Update time zone data files to tzdata release 2013h - for DST law changes in Argentina, Brazil, Jordan, Libya, - Liechtenstein, Morocco, and Palestine. Also, new timezone - abbreviations WIB, WIT, WITA for Indonesia. - - - - - - - - - - Release 9.0.14 - - - Release date: - 2013-10-10 - - - - This release contains a variety of fixes from 9.0.13. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.14 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.13, - see . - - - - - - Changes - - - - - - Prevent corruption of multi-byte characters when attempting to - case-fold identifiers (Andrew Dunstan) - - - - PostgreSQL case-folds non-ASCII characters only - when using a single-byte server encoding. - - - - - - Fix checkpoint memory leak in background writer when wal_level = - hot_standby (Naoya Anzai) - - - - - - Fix memory leak caused by lo_open() failure - (Heikki Linnakangas) - - - - - - Fix memory overcommit bug when work_mem is using more - than 24GB of memory (Stephen Frost) - - - - - - Fix deadlock bug in libpq when using SSL (Stephen Frost) - - - - - - Fix possible SSL state corruption in threaded libpq applications - (Nick Phillips, Stephen Frost) - - - - - - Properly compute row estimates for boolean columns containing many NULL - values (Andrew Gierth) - - - - Previously tests like col IS NOT TRUE and col IS - NOT FALSE did not properly factor in NULL values when estimating - plan costs. - - - - - - Prevent pushing down WHERE clauses into unsafe - UNION/INTERSECT subqueries (Tom Lane) - - - - Subqueries of a UNION or INTERSECT that - contain set-returning functions or volatile functions in their - SELECT lists could be improperly optimized, leading to - run-time errors or incorrect query results. - - - - - - Fix rare case of failed to locate grouping columns - planner failure (Tom Lane) - - - - - - Improve view dumping code's handling of dropped columns in referenced - tables (Tom Lane) - - - - - - Properly record index comments created using UNIQUE - and PRIMARY KEY syntax (Andres Freund) - - - - This fixes a parallel pg_restore failure. - - - - - - Fix REINDEX TABLE and REINDEX DATABASE - to properly revalidate constraints and mark invalidated indexes as - valid (Noah Misch) - - - - REINDEX INDEX has always worked properly. - - - - - - Fix possible deadlock during concurrent CREATE INDEX - CONCURRENTLY operations (Tom Lane) - - - - - - Fix regexp_matches() handling of zero-length matches - (Jeevan Chalke) - - - - Previously, zero-length matches like '^' could return too many matches. - - - - - - Fix crash for overly-complex regular expressions (Heikki Linnakangas) - - - - - - Fix regular expression match failures for back references combined with - non-greedy quantifiers (Jeevan Chalke) - - - - - - Prevent CREATE FUNCTION from checking SET - variables unless function body checking is enabled (Tom Lane) - - - - - - Allow ALTER DEFAULT PRIVILEGES to operate on schemas - without requiring CREATE permission (Tom Lane) - - - - - - Loosen restriction on keywords used in queries (Tom Lane) - - - - Specifically, lessen keyword restrictions for role names, language - names, EXPLAIN and COPY options, and - SET values. This allows COPY ... (FORMAT - BINARY) to work as expected; previously BINARY needed - to be quoted. - - - - - - Fix pgp_pub_decrypt() so it works for secret keys with - passwords (Marko Kreen) - - - - - - Remove rare inaccurate warning during vacuum of index-less tables - (Heikki Linnakangas) - - - - - - Ensure that VACUUM ANALYZE still runs the ANALYZE phase - if its attempt to truncate the file is cancelled due to lock conflicts - (Kevin Grittner) - - - - - - Avoid possible failure when performing transaction control commands (e.g - ROLLBACK) in prepared queries (Tom Lane) - - - - - - Ensure that floating-point data input accepts standard spellings - of infinity on all platforms (Tom Lane) - - - - The C99 standard says that allowable spellings are inf, - +inf, -inf, infinity, - +infinity, and -infinity. Make sure we - recognize these even if the platform's strtod function - doesn't. - - - - - - Expand ability to compare rows to records and arrays (Rafal Rzepecki, - Tom Lane) - - - - - - Update time zone data files to tzdata release 2013d - for DST law changes in Israel, Morocco, Palestine, and Paraguay. - Also, historical zone data corrections for Macquarie Island. - - - - - - - - - - Release 9.0.13 - - - Release date: - 2013-04-04 - - - - This release contains a variety of fixes from 9.0.12. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.13 - - - A dump/restore is not required for those running 9.0.X. - - - - However, this release corrects several errors in management of GiST - indexes. After installing this update, it is advisable to - REINDEX any GiST indexes that meet one or more of the - conditions described below. - - - - Also, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Fix insecure parsing of server command-line switches (Mitsumasa - Kondo, Kyotaro Horiguchi) - - - - A connection request containing a database name that begins with - - could be crafted to damage or destroy - files within the server's data directory, even if the request is - eventually rejected. (CVE-2013-1899) - - - - - - Reset OpenSSL randomness state in each postmaster child process - (Marko Kreen) - - - - This avoids a scenario wherein random numbers generated by - contrib/pgcrypto functions might be relatively easy for - another database user to guess. The risk is only significant when - the postmaster is configured with ssl = on - but most connections don't use SSL encryption. (CVE-2013-1900) - - - - - - Fix GiST indexes to not use fuzzy geometric comparisons when - it's not appropriate to do so (Alexander Korotkov) - - - - The core geometric types perform comparisons using fuzzy - equality, but gist_box_same must do exact comparisons, - else GiST indexes using it might become inconsistent. After installing - this update, users should REINDEX any GiST indexes on - box, polygon, circle, or point - columns, since all of these use gist_box_same. - - - - - - Fix erroneous range-union and penalty logic in GiST indexes that use - contrib/btree_gist for variable-width data types, that is - text, bytea, bit, and numeric - columns (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in useless - index bloat. Users are advised to REINDEX such indexes - after installing this update. - - - - - - Fix bugs in GiST page splitting code for multi-column indexes - (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in indexes - that are unnecessarily inefficient to search. Users are advised to - REINDEX multi-column GiST indexes after installing this - update. - - - - - - Fix gist_point_consistent - to handle fuzziness consistently (Alexander Korotkov) - - - - Index scans on GiST indexes on point columns would sometimes - yield results different from a sequential scan, because - gist_point_consistent disagreed with the underlying - operator code about whether to do comparisons exactly or fuzzily. - - - - - - Fix buffer leak in WAL replay (Heikki Linnakangas) - - - - This bug could result in incorrect local pin count errors - during replay, making recovery impossible. - - - - - - Fix race condition in DELETE RETURNING (Tom Lane) - - - - Under the right circumstances, DELETE RETURNING could - attempt to fetch data from a shared buffer that the current process - no longer has any pin on. If some other process changed the buffer - meanwhile, this would lead to garbage RETURNING output, or - even a crash. - - - - - - Fix infinite-loop risk in regular expression compilation (Tom Lane, - Don Porter) - - - - - - Fix potential null-pointer dereference in regular expression compilation - (Tom Lane) - - - - - - Fix to_char() to use ASCII-only case-folding rules where - appropriate (Tom Lane) - - - - This fixes misbehavior of some template patterns that should be - locale-independent, but mishandled I and - i in Turkish locales. - - - - - - Fix unwanted rejection of timestamp 1999-12-31 24:00:00 - (Tom Lane) - - - - - - Fix logic error when a single transaction does UNLISTEN - then LISTEN (Tom Lane) - - - - The session wound up not listening for notify events at all, though it - surely should listen in this case. - - - - - - Remove useless picksplit doesn't support secondary split log - messages (Josh Hansen, Tom Lane) - - - - This message seems to have been added in expectation of code that was - never written, and probably never will be, since GiST's default - handling of secondary splits is actually pretty good. So stop nagging - end users about it. - - - - - - Fix possible failure to send a session's last few transaction - commit/abort counts to the statistics collector (Tom Lane) - - - - - - Eliminate memory leaks in PL/Perl's spi_prepare() function - (Alex Hunsaker, Tom Lane) - - - - - - Fix pg_dumpall to handle database names containing - = correctly (Heikki Linnakangas) - - - - - - Avoid crash in pg_dump when an incorrect connection - string is given (Heikki Linnakangas) - - - - - - Ignore invalid indexes in pg_dump and - pg_upgrade (Michael Paquier, Bruce Momjian) - - - - Dumping invalid indexes can cause problems at restore time, for example - if the reason the index creation failed was because it tried to enforce - a uniqueness condition not satisfied by the table's data. Also, if the - index creation is in fact still in progress, it seems reasonable to - consider it to be an uncommitted DDL change, which - pg_dump wouldn't be expected to dump anyway. - pg_upgrade now also skips invalid indexes rather than - failing. - - - - - - Fix contrib/pg_trgm's similarity() function - to return zero for trigram-less strings (Tom Lane) - - - - Previously it returned NaN due to internal division by zero. - - - - - - Update time zone data files to tzdata release 2013b - for DST law changes in Chile, Haiti, Morocco, Paraguay, and some - Russian areas. Also, historical zone data corrections for numerous - places. - - - - Also, update the time zone abbreviation files for recent changes in - Russia and elsewhere: CHOT, GET, - IRKT, KGT, KRAT, MAGT, - MAWT, MSK, NOVT, OMST, - TKT, VLAT, WST, YAKT, - YEKT now follow their current meanings, and - VOLT (Europe/Volgograd) and MIST - (Antarctica/Macquarie) are added to the default abbreviations list. - - - - - - - - - - Release 9.0.12 - - - Release date: - 2013-02-07 - - - - This release contains a variety of fixes from 9.0.11. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.12 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Prevent execution of enum_recv from SQL (Tom Lane) - - - - The function was misdeclared, allowing a simple SQL command to crash the - server. In principle an attacker might be able to use it to examine the - contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) - for reporting this issue. (CVE-2013-0255) - - - - - - Fix multiple problems in detection of when a consistent database - state has been reached during WAL replay (Fujii Masao, Heikki - Linnakangas, Simon Riggs, Andres Freund) - - - - - - Update minimum recovery point when truncating a relation file (Heikki - Linnakangas) - - - - Once data has been discarded, it's no longer safe to stop recovery at - an earlier point in the timeline. - - - - - - Fix missing cancellations in hot standby mode (Noah Misch, Simon Riggs) - - - - The need to cancel conflicting hot-standby queries would sometimes be - missed, allowing those queries to see inconsistent data. - - - - - - Fix SQL grammar to allow subscripting or field selection from a - sub-SELECT result (Tom Lane) - - - - - - Fix performance problems with autovacuum truncation in busy workloads - (Jan Wieck) - - - - Truncation of empty pages at the end of a table requires exclusive - lock, but autovacuum was coded to fail (and release the table lock) - when there are conflicting lock requests. Under load, it is easily - possible that truncation would never occur, resulting in table bloat. - Fix by performing a partial truncation, releasing the lock, then - attempting to re-acquire the lock and continue. This fix also greatly - reduces the average time before autovacuum releases the lock after a - conflicting request arrives. - - - - - - Protect against race conditions when scanning - pg_tablespace (Stephen Frost, Tom Lane) - - - - CREATE DATABASE and DROP DATABASE could - misbehave if there were concurrent updates of - pg_tablespace entries. - - - - - - Prevent DROP OWNED from trying to drop whole databases or - tablespaces (Álvaro Herrera) - - - - For safety, ownership of these objects must be reassigned, not dropped. - - - - - - Fix error in vacuum_freeze_table_age - implementation (Andres Freund) - - - - In installations that have existed for more than vacuum_freeze_min_age - transactions, this mistake prevented autovacuum from using partial-table - scans, so that a full-table scan would always happen instead. - - - - - - Prevent misbehavior when a RowExpr or XmlExpr - is parse-analyzed twice (Andres Freund, Tom Lane) - - - - This mistake could be user-visible in contexts such as - CREATE TABLE LIKE INCLUDING INDEXES. - - - - - - Improve defenses against integer overflow in hashtable sizing - calculations (Jeff Davis) - - - - - - Reject out-of-range dates in to_date() (Hitoshi Harada) - - - - - - Ensure that non-ASCII prompt strings are translated to the correct - code page on Windows (Alexander Law, Noah Misch) - - - - This bug affected psql and some other client programs. - - - - - - Fix possible crash in psql's \? command - when not connected to a database (Meng Qingzhong) - - - - - - Fix pg_upgrade to deal with invalid indexes safely - (Bruce Momjian) - - - - - - Fix one-byte buffer overrun in libpq's - PQprintTuples (Xi Wang) - - - - This ancient function is not used anywhere by - PostgreSQL itself, but it might still be used by some - client code. - - - - - - Make ecpglib use translated messages properly - (Chen Huajun) - - - - - - Properly install ecpg_compat and - pgtypes libraries on MSVC (Jiang Guiqing) - - - - - - Include our version of isinf() in - libecpg if it's not provided by the system - (Jiang Guiqing) - - - - - - Rearrange configure's tests for supplied functions so it is not - fooled by bogus exports from libedit/libreadline (Christoph Berg) - - - - - - Ensure Windows build number increases over time (Magnus Hagander) - - - - - - Make pgxs build executables with the right - .exe suffix when cross-compiling for Windows - (Zoltan Boszormenyi) - - - - - - Add new timezone abbreviation FET (Tom Lane) - - - - This is now used in some eastern-European time zones. - - - - - - - - - - Release 9.0.11 - - - Release date: - 2012-12-06 - - - - This release contains a variety of fixes from 9.0.10. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.11 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Fix multiple bugs associated with CREATE INDEX - CONCURRENTLY (Andres Freund, Tom Lane) - - - - Fix CREATE INDEX CONCURRENTLY to use - in-place updates when changing the state of an index's - pg_index row. This prevents race conditions that could - cause concurrent sessions to miss updating the target index, thus - resulting in corrupt concurrently-created indexes. - - - - Also, fix various other operations to ensure that they ignore - invalid indexes resulting from a failed CREATE INDEX - CONCURRENTLY command. The most important of these is - VACUUM, because an auto-vacuum could easily be launched - on the table before corrective action can be taken to fix or remove - the invalid index. - - - - - - Fix buffer locking during WAL replay (Tom Lane) - - - - The WAL replay code was insufficiently careful about locking buffers - when replaying WAL records that affect more than one page. This could - result in hot standby queries transiently seeing inconsistent states, - resulting in wrong answers or unexpected failures. - - - - - - Fix an error in WAL generation logic for GIN indexes (Tom Lane) - - - - This could result in index corruption, if a torn-page failure occurred. - - - - - - Properly remove startup process's virtual XID lock when promoting a - hot standby server to normal running (Simon Riggs) - - - - This oversight could prevent subsequent execution of certain - operations such as CREATE INDEX CONCURRENTLY. - - - - - - Avoid bogus out-of-sequence timeline ID errors in standby - mode (Heikki Linnakangas) - - - - - - Prevent the postmaster from launching new child processes after it's - received a shutdown signal (Tom Lane) - - - - This mistake could result in shutdown taking longer than it should, or - even never completing at all without additional user action. - - - - - - Avoid corruption of internal hash tables when out of memory - (Hitoshi Harada) - - - - - - Fix planning of non-strict equivalence clauses above outer joins - (Tom Lane) - - - - The planner could derive incorrect constraints from a clause equating - a non-strict construct to something else, for example - WHERE COALESCE(foo, 0) = 0 - when foo is coming from the nullable side of an outer join. - - - - - - Improve planner's ability to prove exclusion constraints from - equivalence classes (Tom Lane) - - - - - - Fix partial-row matching in hashed subplans to handle cross-type cases - correctly (Tom Lane) - - - - This affects multicolumn NOT IN subplans, such as - WHERE (a, b) NOT IN (SELECT x, y FROM ...) - when for instance b and y are int4 - and int8 respectively. This mistake led to wrong answers - or crashes depending on the specific datatypes involved. - - - - - - Acquire buffer lock when re-fetching the old tuple for an - AFTER ROW UPDATE/DELETE trigger (Andres Freund) - - - - In very unusual circumstances, this oversight could result in passing - incorrect data to the precheck logic for a foreign-key enforcement - trigger. That could result in a crash, or in an incorrect decision - about whether to fire the trigger. - - - - - - Fix ALTER COLUMN TYPE to handle inherited check - constraints properly (Pavan Deolasee) - - - - This worked correctly in pre-8.4 releases, and now works correctly - in 8.4 and later. - - - - - - Fix REASSIGN OWNED to handle grants on tablespaces - (Álvaro Herrera) - - - - - - Ignore incorrect pg_attribute entries for system - columns for views (Tom Lane) - - - - Views do not have any system columns. However, we forgot to - remove such entries when converting a table to a view. That's fixed - properly for 9.3 and later, but in previous branches we need to defend - against existing mis-converted views. - - - - - - Fix rule printing to dump INSERT INTO table - DEFAULT VALUES correctly (Tom Lane) - - - - - - Guard against stack overflow when there are too many - UNION/INTERSECT/EXCEPT clauses - in a query (Tom Lane) - - - - - - Prevent platform-dependent failures when dividing the minimum possible - integer value by -1 (Xi Wang, Tom Lane) - - - - - - Fix possible access past end of string in date parsing - (Hitoshi Harada) - - - - - - Fix failure to advance XID epoch if XID wraparound happens during a - checkpoint and wal_level is hot_standby - (Tom Lane, Andres Freund) - - - - While this mistake had no particular impact on - PostgreSQL itself, it was bad for - applications that rely on txid_current() and related - functions: the TXID value would appear to go backwards. - - - - - - Produce an understandable error message if the length of the path name - for a Unix-domain socket exceeds the platform-specific limit - (Tom Lane, Andrew Dunstan) - - - - Formerly, this would result in something quite unhelpful, such as - Non-recoverable failure in name resolution. - - - - - - Fix memory leaks when sending composite column values to the client - (Tom Lane) - - - - - - Make pg_ctl more robust about reading the - postmaster.pid file (Heikki Linnakangas) - - - - Fix race conditions and possible file descriptor leakage. - - - - - - Fix possible crash in psql if incorrectly-encoded data - is presented and the client_encoding setting is a - client-only encoding, such as SJIS (Jiang Guiqing) - - - - - - Fix bugs in the restore.sql script emitted by - pg_dump in tar output format (Tom Lane) - - - - The script would fail outright on tables whose names include - upper-case characters. Also, make the script capable of restoring - data in mode as well as the regular COPY mode. - - - - - - Fix pg_restore to accept POSIX-conformant - tar files (Brian Weaver, Tom Lane) - - - - The original coding of pg_dump's tar - output mode produced files that are not fully conformant with the - POSIX standard. This has been corrected for version 9.3. This - patch updates previous branches so that they will accept both the - incorrect and the corrected formats, in hopes of avoiding - compatibility problems when 9.3 comes out. - - - - - - Fix pg_resetxlog to locate postmaster.pid - correctly when given a relative path to the data directory (Tom Lane) - - - - This mistake could lead to pg_resetxlog not noticing - that there is an active postmaster using the data directory. - - - - - - Fix libpq's lo_import() and - lo_export() functions to report file I/O errors properly - (Tom Lane) - - - - - - Fix ecpg's processing of nested structure pointer - variables (Muhammad Usama) - - - - - - Fix ecpg's ecpg_get_data function to - handle arrays properly (Michael Meskes) - - - - - - Make contrib/pageinspect's btree page inspection - functions take buffer locks while examining pages (Tom Lane) - - - - - - Fix pgxs support for building loadable modules on AIX - (Tom Lane) - - - - Building modules outside the original source tree didn't work on AIX. - - - - - - Update time zone data files to tzdata release 2012j - for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western - Samoa, and portions of Brazil. - - - - - - - - - - Release 9.0.10 - - - Release date: - 2012-09-24 - - - - This release contains a variety of fixes from 9.0.9. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.10 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Fix planner's assignment of executor parameters, and fix executor's - rescan logic for CTE plan nodes (Tom Lane) - - - - These errors could result in wrong answers from queries that scan the - same WITH subquery multiple times. - - - - - - Improve page-splitting decisions in GiST indexes (Alexander Korotkov, - Robert Haas, Tom Lane) - - - - Multi-column GiST indexes might suffer unexpected bloat due to this - error. - - - - - - Fix cascading privilege revoke to stop if privileges are still held - (Tom Lane) - - - - If we revoke a grant option from some role X, but - X still holds that option via a grant from someone - else, we should not recursively revoke the corresponding privilege - from role(s) Y that X had granted it - to. - - - - - - Improve error messages for Hot Standby misconfiguration errors - (Gurjeet Singh) - - - - - - Fix handling of SIGFPE when PL/Perl is in use (Andres Freund) - - - - Perl resets the process's SIGFPE handler to - SIG_IGN, which could result in crashes later on. Restore - the normal Postgres signal handler after initializing PL/Perl. - - - - - - Prevent PL/Perl from crashing if a recursive PL/Perl function is - redefined while being executed (Tom Lane) - - - - - - Work around possible misoptimization in PL/Perl (Tom Lane) - - - - Some Linux distributions contain an incorrect version of - pthread.h that results in incorrect compiled code in - PL/Perl, leading to crashes if a PL/Perl function calls another one - that throws an error. - - - - - - Fix pg_upgrade's handling of line endings on Windows - (Andrew Dunstan) - - - - Previously, pg_upgrade might add or remove carriage - returns in places such as function bodies. - - - - - - On Windows, make pg_upgrade use backslash path - separators in the scripts it emits (Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2012f - for DST law changes in Fiji - - - - - - - - - - Release 9.0.9 - - - Release date: - 2012-08-17 - - - - This release contains a variety of fixes from 9.0.8. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.9 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Prevent access to external files/URLs via XML entity references - (Noah Misch, Tom Lane) - - - - xml_parse() would attempt to fetch external files or - URLs as needed to resolve DTD and entity references in an XML value, - thus allowing unprivileged database users to attempt to fetch data - with the privileges of the database server. While the external data - wouldn't get returned directly to the user, portions of it could be - exposed in error messages if the data didn't parse as valid XML; and - in any case the mere ability to check existence of a file might be - useful to an attacker. (CVE-2012-3489) - - - - - - Prevent access to external files/URLs via contrib/xml2's - xslt_process() (Peter Eisentraut) - - - - libxslt offers the ability to read and write both - files and URLs through stylesheet commands, thus allowing - unprivileged database users to both read and write data with the - privileges of the database server. Disable that through proper use - of libxslt's security options. (CVE-2012-3488) - - - - Also, remove xslt_process()'s ability to fetch documents - and stylesheets from external files/URLs. While this was a - documented feature, it was long regarded as a bad idea. - The fix for CVE-2012-3489 broke that capability, and rather than - expend effort on trying to fix it, we're just going to summarily - remove it. - - - - - - Prevent too-early recycling of btree index pages (Noah Misch) - - - - When we allowed read-only transactions to skip assigning XIDs, we - introduced the possibility that a deleted btree page could be - recycled while a read-only transaction was still in flight to it. - This would result in incorrect index search results. The probability - of such an error occurring in the field seems very low because of the - timing requirements, but nonetheless it should be fixed. - - - - - - Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane) - - - - If ALTER SEQUENCE was executed on a freshly created or - reset sequence, and then precisely one nextval() call - was made on it, and then the server crashed, WAL replay would restore - the sequence to a state in which it appeared that no - nextval() had been done, thus allowing the first - sequence value to be returned again by the next - nextval() call. In particular this could manifest for - serial columns, since creation of a serial column's sequence - includes an ALTER SEQUENCE OWNED BY step. - - - - - - Fix txid_current() to report the correct epoch when not - in hot standby (Heikki Linnakangas) - - - - This fixes a regression introduced in the previous minor release. - - - - - - Fix bug in startup of Hot Standby when a master transaction has many - subtransactions (Andres Freund) - - - - This mistake led to failures reported as out-of-order XID - insertion in KnownAssignedXids. - - - - - - Ensure the backup_label file is fsync'd after - pg_start_backup() (Dave Kerr) - - - - - - Fix timeout handling in walsender processes (Tom Lane) - - - - WAL sender background processes neglected to establish a - SIGALRM handler, meaning they would wait forever in - some corner cases where a timeout ought to happen. - - - - - - Back-patch 9.1 improvement to compress the fsync request queue - (Robert Haas) - - - - This improves performance during checkpoints. The 9.1 change - has now seen enough field testing to seem safe to back-patch. - - - - - - Fix LISTEN/NOTIFY to cope better with I/O - problems, such as out of disk space (Tom Lane) - - - - After a write failure, all subsequent attempts to send more - NOTIFY messages would fail with messages like - Could not read from file "pg_notify/nnnn" at - offset nnnnn: Success. - - - - - - Only allow autovacuum to be auto-canceled by a directly blocked - process (Tom Lane) - - - - The original coding could allow inconsistent behavior in some cases; - in particular, an autovacuum could get canceled after less than - deadlock_timeout grace period. - - - - - - Improve logging of autovacuum cancels (Robert Haas) - - - - - - Fix log collector so that log_truncate_on_rotation works - during the very first log rotation after server start (Tom Lane) - - - - - - Fix WITH attached to a nested set operation - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Ensure that a whole-row reference to a subquery doesn't include any - extra GROUP BY or ORDER BY columns (Tom Lane) - - - - - - Disallow copying whole-row references in CHECK - constraints and index definitions during CREATE TABLE - (Tom Lane) - - - - This situation can arise in CREATE TABLE with - LIKE or INHERITS. The copied whole-row - variable was incorrectly labeled with the row type of the original - table not the new one. Rejecting the case seems reasonable for - LIKE, since the row types might well diverge later. For - INHERITS we should ideally allow it, with an implicit - coercion to the parent table's row type; but that will require more - work than seems safe to back-patch. - - - - - - Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki - Linnakangas, Tom Lane) - - - - - - Fix extraction of common prefixes from regular expressions (Tom Lane) - - - - The code could get confused by quantified parenthesized - subexpressions, such as ^(foo)?bar. This would lead to - incorrect index optimization of searches for such patterns. - - - - - - Fix bugs with parsing signed - hh:mm and - hh:mm:ss - fields in interval constants (Amit Kapila, Tom Lane) - - - - - - Use Postgres' encoding conversion functions, not Python's, when - converting a Python Unicode string to the server encoding in - PL/Python (Jan Urbanski) - - - - This avoids some corner-case problems, notably that Python doesn't - support all the encodings Postgres does. A notable functional change - is that if the server encoding is SQL_ASCII, you will get the UTF-8 - representation of the string; formerly, any non-ASCII characters in - the string would result in an error. - - - - - - Fix mapping of PostgreSQL encodings to Python encodings in PL/Python - (Jan Urbanski) - - - - - - Report errors properly in contrib/xml2's - xslt_process() (Tom Lane) - - - - - - Update time zone data files to tzdata release 2012e - for DST law changes in Morocco and Tokelau - - - - - - - - - - Release 9.0.8 - - - Release date: - 2012-06-04 - - - - This release contains a variety of fixes from 9.0.7. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.8 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Fix incorrect password transformation in - contrib/pgcrypto's DES crypt() function - (Solar Designer) - - - - If a password string contained the byte value 0x80, the - remainder of the password was ignored, causing the password to be much - weaker than it appeared. With this fix, the rest of the string is - properly included in the DES hash. Any stored password values that are - affected by this bug will thus no longer match, so the stored values may - need to be updated. (CVE-2012-2143) - - - - - - Ignore SECURITY DEFINER and SET attributes for - a procedural language's call handler (Tom Lane) - - - - Applying such attributes to a call handler could crash the server. - (CVE-2012-2655) - - - - - - Allow numeric timezone offsets in timestamp input to be up to - 16 hours away from UTC (Tom Lane) - - - - Some historical time zones have offsets larger than 15 hours, the - previous limit. This could result in dumped data values being rejected - during reload. - - - - - - Fix timestamp conversion to cope when the given time is exactly the - last DST transition time for the current timezone (Tom Lane) - - - - This oversight has been there a long time, but was not noticed - previously because most DST-using zones are presumed to have an - indefinite sequence of future DST transitions. - - - - - - Fix text to name and char to name - casts to perform string truncation correctly in multibyte encodings - (Karl Schnaitter) - - - - - - Fix memory copying bug in to_tsquery() (Heikki Linnakangas) - - - - - - Ensure txid_current() reports the correct epoch when - executed in hot standby (Simon Riggs) - - - - - - Fix planner's handling of outer PlaceHolderVars within subqueries (Tom - Lane) - - - - This bug concerns sub-SELECTs that reference variables coming from the - nullable side of an outer join of the surrounding query. - In 9.1, queries affected by this bug would fail with ERROR: - Upper-level PlaceHolderVar found where not expected. But in 9.0 and - 8.4, you'd silently get possibly-wrong answers, since the value - transmitted into the subquery wouldn't go to null when it should. - - - - - - Fix slow session startup when pg_attribute is very large - (Tom Lane) - - - - If pg_attribute exceeds one-fourth of - shared_buffers, cache rebuilding code that is sometimes - needed during session start would trigger the synchronized-scan logic, - causing it to take many times longer than normal. The problem was - particularly acute if many new sessions were starting at once. - - - - - - Ensure sequential scans check for query cancel reasonably often (Merlin - Moncure) - - - - A scan encountering many consecutive pages that contain no live tuples - would not respond to interrupts meanwhile. - - - - - - Ensure the Windows implementation of PGSemaphoreLock() - clears ImmediateInterruptOK before returning (Tom Lane) - - - - This oversight meant that a query-cancel interrupt received later - in the same query could be accepted at an unsafe time, with - unpredictable but not good consequences. - - - - - - Show whole-row variables safely when printing views or rules - (Abbas Butt, Tom Lane) - - - - Corner cases involving ambiguous names (that is, the name could be - either a table or column name of the query) were printed in an - ambiguous way, risking that the view or rule would be interpreted - differently after dump and reload. Avoid the ambiguous case by - attaching a no-op cast. - - - - - - Fix COPY FROM to properly handle null marker strings that - correspond to invalid encoding (Tom Lane) - - - - A null marker string such as E'\\0' should work, and did - work in the past, but the case got broken in 8.4. - - - - - - Ensure autovacuum worker processes perform stack depth checking - properly (Heikki Linnakangas) - - - - Previously, infinite recursion in a function invoked by - auto-ANALYZE could crash worker processes. - - - - - - Fix logging collector to not lose log coherency under high load (Andrew - Dunstan) - - - - The collector previously could fail to reassemble large messages if it - got too busy. - - - - - - Fix logging collector to ensure it will restart file rotation - after receiving SIGHUP (Tom Lane) - - - - - - Fix WAL replay logic for GIN indexes to not fail if the index was - subsequently dropped (Tom Lane) - - - - - - Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe - Conway) - - - - - - Fix PL/pgSQL's GET DIAGNOSTICS command when the target - is the function's first variable (Tom Lane) - - - - - - Fix potential access off the end of memory in psql's - expanded display (\x) mode (Peter Eisentraut) - - - - - - Fix several performance problems in pg_dump when - the database contains many objects (Jeff Janes, Tom Lane) - - - - pg_dump could get very slow if the database contained - many schemas, or if many objects are in dependency loops, or if there - are many owned sequences. - - - - - - Fix pg_upgrade for the case that a database stored in a - non-default tablespace contains a table in the cluster's default - tablespace (Bruce Momjian) - - - - - - In ecpg, fix rare memory leaks and possible overwrite - of one byte after the sqlca_t structure (Peter Eisentraut) - - - - - - Fix contrib/dblink's dblink_exec() to not leak - temporary database connections upon error (Tom Lane) - - - - - - Fix contrib/dblink to report the correct connection name in - error messages (Kyotaro Horiguchi) - - - - - - Fix contrib/vacuumlo to use multiple transactions when - dropping many large objects (Tim Lewis, Robert Haas, Tom Lane) - - - - This change avoids exceeding max_locks_per_transaction when - many objects need to be dropped. The behavior can be adjusted with the - new -l (limit) option. - - - - - - Update time zone data files to tzdata release 2012c - for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland - Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; - also historical corrections for Canada. - - - - - - - - - - Release 9.0.7 - - - Release date: - 2012-02-27 - - - - This release contains a variety of fixes from 9.0.6. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.7 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.6, - see . - - - - - - Changes - - - - - - Require execute permission on the trigger function for - CREATE TRIGGER (Robert Haas) - - - - This missing check could allow another user to execute a trigger - function with forged input data, by installing it on a table he owns. - This is only of significance for trigger functions marked - SECURITY DEFINER, since otherwise trigger functions run - as the table owner anyway. (CVE-2012-0866) - - - - - - Remove arbitrary limitation on length of common name in SSL - certificates (Heikki Linnakangas) - - - - Both libpq and the server truncated the common name - extracted from an SSL certificate at 32 bytes. Normally this would - cause nothing worse than an unexpected verification failure, but there - are some rather-implausible scenarios in which it might allow one - certificate holder to impersonate another. The victim would have to - have a common name exactly 32 bytes long, and the attacker would have - to persuade a trusted CA to issue a certificate in which the common - name has that string as a prefix. Impersonating a server would also - require some additional exploit to redirect client connections. - (CVE-2012-0867) - - - - - - Convert newlines to spaces in names written in pg_dump - comments (Robert Haas) - - - - pg_dump was incautious about sanitizing object names - that are emitted within SQL comments in its output script. A name - containing a newline would at least render the script syntactically - incorrect. Maliciously crafted object names could present a SQL - injection risk when the script is reloaded. (CVE-2012-0868) - - - - - - Fix btree index corruption from insertions concurrent with vacuuming - (Tom Lane) - - - - An index page split caused by an insertion could sometimes cause a - concurrently-running VACUUM to miss removing index entries - that it should remove. After the corresponding table rows are removed, - the dangling index entries would cause errors (such as could not - read block N in file ...) or worse, silently wrong query results - after unrelated rows are re-inserted at the now-free table locations. - This bug has been present since release 8.2, but occurs so infrequently - that it was not diagnosed until now. If you have reason to suspect - that it has happened in your database, reindexing the affected index - will fix things. - - - - - - Fix transient zeroing of shared buffers during WAL replay (Tom Lane) - - - - The replay logic would sometimes zero and refill a shared buffer, so - that the contents were transiently invalid. In hot standby mode this - can result in a query that's executing in parallel seeing garbage data. - Various symptoms could result from that, but the most common one seems - to be invalid memory alloc request size. - - - - - - Fix postmaster to attempt restart after a hot-standby crash (Tom Lane) - - - - A logic error caused the postmaster to terminate, rather than attempt - to restart the cluster, if any backend process crashed while operating - in hot standby mode. - - - - - - Fix CLUSTER/VACUUM FULL handling of toast - values owned by recently-updated rows (Tom Lane) - - - - This oversight could lead to duplicate key value violates unique - constraint errors being reported against the toast table's index - during one of these commands. - - - - - - Update per-column permissions, not only per-table permissions, when - changing table owner (Tom Lane) - - - - Failure to do this meant that any previously granted column permissions - were still shown as having been granted by the old owner. This meant - that neither the new owner nor a superuser could revoke the - now-untraceable-to-table-owner permissions. - - - - - - Support foreign data wrappers and foreign servers in - REASSIGN OWNED (Alvaro Herrera) - - - - This command failed with unexpected classid errors if - it needed to change the ownership of any such objects. - - - - - - Allow non-existent values for some settings in ALTER - USER/DATABASE SET (Heikki Linnakangas) - - - - Allow default_text_search_config, - default_tablespace, and temp_tablespaces to be - set to names that are not known. This is because they might be known - in another database where the setting is intended to be used, or for the - tablespace cases because the tablespace might not be created yet. The - same issue was previously recognized for search_path, and - these settings now act like that one. - - - - - - Avoid crashing when we have problems deleting table files post-commit - (Tom Lane) - - - - Dropping a table should lead to deleting the underlying disk files only - after the transaction commits. In event of failure then (for instance, - because of wrong file permissions) the code is supposed to just emit a - warning message and go on, since it's too late to abort the - transaction. This logic got broken as of release 8.4, causing such - situations to result in a PANIC and an unrestartable database. - - - - - - Recover from errors occurring during WAL replay of DROP - TABLESPACE (Tom Lane) - - - - Replay will attempt to remove the tablespace's directories, but there - are various reasons why this might fail (for example, incorrect - ownership or permissions on those directories). Formerly the replay - code would panic, rendering the database unrestartable without manual - intervention. It seems better to log the problem and continue, since - the only consequence of failure to remove the directories is some - wasted disk space. - - - - - - Fix race condition in logging AccessExclusiveLocks for hot standby - (Simon Riggs) - - - - Sometimes a lock would be logged as being held by transaction - zero. This is at least known to produce assertion failures on - slave servers, and might be the cause of more serious problems. - - - - - - Track the OID counter correctly during WAL replay, even when it wraps - around (Tom Lane) - - - - Previously the OID counter would remain stuck at a high value until the - system exited replay mode. The practical consequences of that are - usually nil, but there are scenarios wherein a standby server that's - been promoted to master might take a long time to advance the OID - counter to a reasonable value once values are needed. - - - - - - Prevent emitting misleading consistent recovery state reached - log message at the beginning of crash recovery (Heikki Linnakangas) - - - - - - Fix initial value of - pg_stat_replication.replay_location - (Fujii Masao) - - - - Previously, the value shown would be wrong until at least one WAL - record had been replayed. - - - - - - Fix regular expression back-references with * attached - (Tom Lane) - - - - Rather than enforcing an exact string match, the code would effectively - accept any string that satisfies the pattern sub-expression referenced - by the back-reference symbol. - - - - A similar problem still afflicts back-references that are embedded in a - larger quantified expression, rather than being the immediate subject - of the quantifier. This will be addressed in a future - PostgreSQL release. - - - - - - Fix recently-introduced memory leak in processing of - inet/cidr values (Heikki Linnakangas) - - - - A patch in the December 2011 releases of PostgreSQL - caused memory leakage in these operations, which could be significant - in scenarios such as building a btree index on such a column. - - - - - - Fix dangling pointer after CREATE TABLE AS/SELECT - INTO in a SQL-language function (Tom Lane) - - - - In most cases this only led to an assertion failure in assert-enabled - builds, but worse consequences seem possible. - - - - - - Avoid double close of file handle in syslogger on Windows (MauMau) - - - - Ordinarily this error was invisible, but it would cause an exception - when running on a debug version of Windows. - - - - - - Fix I/O-conversion-related memory leaks in plpgsql - (Andres Freund, Jan Urbanski, Tom Lane) - - - - Certain operations would leak memory until the end of the current - function. - - - - - - Improve pg_dump's handling of inherited table columns - (Tom Lane) - - - - pg_dump mishandled situations where a child column has - a different default expression than its parent column. If the default - is textually identical to the parent's default, but not actually the - same (for instance, because of schema search path differences) it would - not be recognized as different, so that after dump and restore the - child would be allowed to inherit the parent's default. Child columns - that are NOT NULL where their parent is not could also be - restored subtly incorrectly. - - - - - - Fix pg_restore's direct-to-database mode for - INSERT-style table data (Tom Lane) - - - - Direct-to-database restores from archive files made with - or options fail when - using pg_restore from a release dated September or - December 2011, as a result of an oversight in a fix for another - problem. The archive file itself is not at fault, and text-mode - output is okay. - - - - - - Allow pg_upgrade to process tables containing - regclass columns (Bruce Momjian) - - - - Since pg_upgrade now takes care to preserve - pg_class OIDs, there was no longer any reason for this - restriction. - - - - - - Make libpq ignore ENOTDIR errors - when looking for an SSL client certificate file - (Magnus Hagander) - - - - This allows SSL connections to be established, though without a - certificate, even when the user's home directory is set to something - like /dev/null. - - - - - - Fix some more field alignment issues in ecpg's SQLDA area - (Zoltan Boszormenyi) - - - - - - Allow AT option in ecpg - DEALLOCATE statements (Michael Meskes) - - - - The infrastructure to support this has been there for awhile, but - through an oversight there was still an error check rejecting the case. - - - - - - Do not use the variable name when defining a varchar structure in ecpg - (Michael Meskes) - - - - - - Fix contrib/auto_explain's JSON output mode to produce - valid JSON (Andrew Dunstan) - - - - The output used brackets at the top level, when it should have used - braces. - - - - - - Fix error in contrib/intarray's int[] & - int[] operator (Guillaume Lelarge) - - - - If the smallest integer the two input arrays have in common is 1, - and there are smaller values in either array, then 1 would be - incorrectly omitted from the result. - - - - - - Fix error detection in contrib/pgcrypto's - encrypt_iv() and decrypt_iv() - (Marko Kreen) - - - - These functions failed to report certain types of invalid-input errors, - and would instead return random garbage values for incorrect input. - - - - - - Fix one-byte buffer overrun in contrib/test_parser - (Paul Guyot) - - - - The code would try to read one more byte than it should, which would - crash in corner cases. - Since contrib/test_parser is only example code, this is - not a security issue in itself, but bad example code is still bad. - - - - - - Use __sync_lock_test_and_set() for spinlocks on ARM, if - available (Martin Pitt) - - - - This function replaces our previous use of the SWPB - instruction, which is deprecated and not available on ARMv6 and later. - Reports suggest that the old code doesn't fail in an obvious way on - recent ARM boards, but simply doesn't interlock concurrent accesses, - leading to bizarre failures in multiprocess operation. - - - - - - Use option when building with - gcc versions that accept it (Andrew Dunstan) - - - - This prevents assorted scenarios wherein recent versions of gcc will - produce creative results. - - - - - - Allow use of threaded Python on FreeBSD (Chris Rees) - - - - Our configure script previously believed that this combination wouldn't - work; but FreeBSD fixed the problem, so remove that error check. - - - - - - - - - - Release 9.0.6 - - - Release date: - 2011-12-05 - - - - This release contains a variety of fixes from 9.0.5. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.6 - - - A dump/restore is not required for those running 9.0.X. - - - - However, a longstanding error was discovered in the definition of the - information_schema.referential_constraints view. If you - rely on correct results from that view, you should replace its - definition as explained in the first changelog item below. - - - - Also, if you are upgrading from a version earlier than 9.0.4, - see . - - - - - - Changes - - - - - - Fix bugs in information_schema.referential_constraints view - (Tom Lane) - - - - This view was being insufficiently careful about matching the - foreign-key constraint to the depended-on primary or unique key - constraint. That could result in failure to show a foreign key - constraint at all, or showing it multiple times, or claiming that it - depends on a different constraint than the one it really does. - - - - Since the view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can (as a superuser) drop the - information_schema schema then re-create it by sourcing - SHAREDIR/information_schema.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) This must be repeated in each database - to be fixed. - - - - - - Fix possible crash during UPDATE or DELETE that - joins to the output of a scalar-returning function (Tom Lane) - - - - A crash could only occur if the target row had been concurrently - updated, so this problem surfaced only intermittently. - - - - - - Fix incorrect replay of WAL records for GIN index updates - (Tom Lane) - - - - This could result in transiently failing to find index entries after - a crash, or on a hot-standby server. The problem would be repaired - by the next VACUUM of the index, however. - - - - - - Fix TOAST-related data corruption during CREATE TABLE dest AS - SELECT * FROM src or INSERT INTO dest SELECT * FROM src - (Tom Lane) - - - - If a table has been modified by ALTER TABLE ADD COLUMN, - attempts to copy its data verbatim to another table could produce - corrupt results in certain corner cases. - The problem can only manifest in this precise form in 8.4 and later, - but we patched earlier versions as well in case there are other code - paths that could trigger the same bug. - - - - - - Fix possible failures during hot standby startup (Simon Riggs) - - - - - - Start hot standby faster when initial snapshot is incomplete - (Simon Riggs) - - - - - - Fix race condition during toast table access from stale syscache entries - (Tom Lane) - - - - The typical symptom was transient errors like missing chunk - number 0 for toast value NNNNN in pg_toast_2619, where the cited - toast table would always belong to a system catalog. - - - - - - Track dependencies of functions on items used in parameter default - expressions (Tom Lane) - - - - Previously, a referenced object could be dropped without having dropped - or modified the function, leading to misbehavior when the function was - used. Note that merely installing this update will not fix the missing - dependency entries; to do that, you'd need to CREATE OR - REPLACE each such function afterwards. If you have functions whose - defaults depend on non-built-in objects, doing so is recommended. - - - - - - Allow inlining of set-returning SQL functions with multiple OUT - parameters (Tom Lane) - - - - - - Don't trust deferred-unique indexes for join removal (Tom Lane and Marti - Raudsepp) - - - - A deferred uniqueness constraint might not hold intra-transaction, - so assuming that it does could give incorrect query results. - - - - - - Make DatumGetInetP() unpack inet datums that have a 1-byte - header, and add a new macro, DatumGetInetPP(), that does - not (Heikki Linnakangas) - - - - This change affects no core code, but might prevent crashes in add-on - code that expects DatumGetInetP() to produce an unpacked - datum as per usual convention. - - - - - - Improve locale support in money type's input and output - (Tom Lane) - - - - Aside from not supporting all standard - lc_monetary - formatting options, the input and output functions were inconsistent, - meaning there were locales in which dumped money values could - not be re-read. - - - - - - Don't let transform_null_equals - affect CASE foo WHEN NULL ... constructs - (Heikki Linnakangas) - - - - transform_null_equals is only supposed to affect - foo = NULL expressions written directly by the user, not - equality checks generated internally by this form of CASE. - - - - - - Change foreign-key trigger creation order to better support - self-referential foreign keys (Tom Lane) - - - - For a cascading foreign key that references its own table, a row update - will fire both the ON UPDATE trigger and the - CHECK trigger as one event. The ON UPDATE - trigger must execute first, else the CHECK will check a - non-final state of the row and possibly throw an inappropriate error. - However, the firing order of these triggers is determined by their - names, which generally sort in creation order since the triggers have - auto-generated names following the convention - RI_ConstraintTrigger_NNNN. A proper fix would require - modifying that convention, which we will do in 9.2, but it seems risky - to change it in existing releases. So this patch just changes the - creation order of the triggers. Users encountering this type of error - should drop and re-create the foreign key constraint to get its - triggers into the right order. - - - - - - Avoid floating-point underflow while tracking buffer allocation rate - (Greg Matthews) - - - - While harmless in itself, on certain platforms this would result in - annoying kernel log messages. - - - - - - Preserve configuration file name and line number values when starting - child processes under Windows (Tom Lane) - - - - Formerly, these would not be displayed correctly in the - pg_settings view. - - - - - - Fix incorrect field alignment in ecpg's SQLDA area - (Zoltan Boszormenyi) - - - - - - Preserve blank lines within commands in psql's command - history (Robert Haas) - - - - The former behavior could cause problems if an empty line was removed - from within a string literal, for example. - - - - - - Fix pg_dump to dump user-defined casts between - auto-generated types, such as table rowtypes (Tom Lane) - - - - - - Assorted fixes for pg_upgrade (Bruce Momjian) - - - - Handle exclusion constraints correctly, avoid failures on Windows, - don't complain about mismatched toast table names in 8.4 databases. - - - - - - Use the preferred version of xsubpp to build PL/Perl, - not necessarily the operating system's main copy - (David Wheeler and Alex Hunsaker) - - - - - - Fix incorrect coding in contrib/dict_int and - contrib/dict_xsyn (Tom Lane) - - - - Some functions incorrectly assumed that memory returned by - palloc() is guaranteed zeroed. - - - - - - Fix assorted errors in contrib/unaccent's configuration - file parsing (Tom Lane) - - - - - - Honor query cancel interrupts promptly in pgstatindex() - (Robert Haas) - - - - - - Fix incorrect quoting of log file name in macOS start script - (Sidar Lopez) - - - - - - Ensure VPATH builds properly install all server header files - (Peter Eisentraut) - - - - - - Shorten file names reported in verbose error messages (Peter Eisentraut) - - - - Regular builds have always reported just the name of the C file - containing the error message call, but VPATH builds formerly - reported an absolute path name. - - - - - - Fix interpretation of Windows timezone names for Central America - (Tom Lane) - - - - Map Central America Standard Time to CST6, not - CST6CDT, because DST is generally not observed anywhere in - Central America. - - - - - - Update time zone data files to tzdata release 2011n - for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa; - also historical corrections for Alaska and British East Africa. - - - - - - - - - - Release 9.0.5 - - - Release date: - 2011-09-26 - - - - This release contains a variety of fixes from 9.0.4. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.5 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if you are upgrading from a version earlier than 9.0.4, - see . - - - - - - Changes - - - - - - Fix catalog cache invalidation after a VACUUM FULL or - CLUSTER on a system catalog (Tom Lane) - - - - In some cases the relocation of a system catalog row to another place - would not be recognized by concurrent server processes, allowing catalog - corruption to occur if they then tried to update that row. The - worst-case outcome could be as bad as complete loss of a table. - - - - - - Fix incorrect order of operations during sinval reset processing, - and ensure that TOAST OIDs are preserved in system catalogs (Tom - Lane) - - - - These mistakes could lead to transient failures after a VACUUM - FULL or CLUSTER on a system catalog. - - - - - - Fix bugs in indexing of in-doubt HOT-updated tuples (Tom Lane) - - - - These bugs could result in index corruption after reindexing a system - catalog. They are not believed to affect user indexes. - - - - - - Fix multiple bugs in GiST index page split processing (Heikki - Linnakangas) - - - - The probability of occurrence was low, but these could lead to index - corruption. - - - - - - Fix possible buffer overrun in tsvector_concat() - (Tom Lane) - - - - The function could underestimate the amount of memory needed for its - result, leading to server crashes. - - - - - - Fix crash in xml_recv when processing a - standalone parameter (Tom Lane) - - - - - - Make pg_options_to_table return NULL for an option with no - value (Tom Lane) - - - - Previously such cases would result in a server crash. - - - - - - Avoid possibly accessing off the end of memory in ANALYZE - and in SJIS-2004 encoding conversion (Noah Misch) - - - - This fixes some very-low-probability server crash scenarios. - - - - - - Protect pg_stat_reset_shared() against NULL input (Magnus - Hagander) - - - - - - Fix possible failure when a recovery conflict deadlock is detected - within a sub-transaction (Tom Lane) - - - - - - Avoid spurious conflicts while recycling btree index pages during hot - standby (Noah Misch, Simon Riggs) - - - - - - Shut down WAL receiver if it's still running at end of recovery (Heikki - Linnakangas) - - - - The postmaster formerly panicked in this situation, but it's actually a - legitimate case. - - - - - - Fix race condition in relcache init file invalidation (Tom Lane) - - - - There was a window wherein a new backend process could read a stale init - file but miss the inval messages that would tell it the data is stale. - The result would be bizarre failures in catalog accesses, typically - could not read block 0 in file ... later during startup. - - - - - - Fix memory leak at end of a GiST index scan (Tom Lane) - - - - Commands that perform many separate GiST index scans, such as - verification of a new GiST-based exclusion constraint on a table - already containing many rows, could transiently require large amounts of - memory due to this leak. - - - - - - Fix memory leak when encoding conversion has to be done on incoming - command strings and LISTEN is active (Tom Lane) - - - - - - Fix incorrect memory accounting (leading to possible memory bloat) in - tuplestores supporting holdable cursors and plpgsql's RETURN - NEXT command (Tom Lane) - - - - - - Fix trigger WHEN conditions when both BEFORE and - AFTER triggers exist (Tom Lane) - - - - Evaluation of WHEN conditions for AFTER ROW - UPDATE triggers could crash if there had been a BEFORE - ROW trigger fired for the same update. - - - - - - Fix performance problem when constructing a large, lossy bitmap - (Tom Lane) - - - - - - Fix join selectivity estimation for unique columns (Tom Lane) - - - - This fixes an erroneous planner heuristic that could lead to poor - estimates of the result size of a join. - - - - - - Fix nested PlaceHolderVar expressions that appear only in sub-select - target lists (Tom Lane) - - - - This mistake could result in outputs of an outer join incorrectly - appearing as NULL. - - - - - - Allow the planner to assume that empty parent tables really are empty - (Tom Lane) - - - - Normally an empty table is assumed to have a certain minimum size for - planning purposes; but this heuristic seems to do more harm than good - for the parent table of an inheritance hierarchy, which often is - permanently empty. - - - - - - Allow nested EXISTS queries to be optimized properly (Tom - Lane) - - - - - - Fix array- and path-creating functions to ensure padding bytes are - zeroes (Tom Lane) - - - - This avoids some situations where the planner will think that - semantically-equal constants are not equal, resulting in poor - optimization. - - - - - - Fix EXPLAIN to handle gating Result nodes within - inner-indexscan subplans (Tom Lane) - - - - The usual symptom of this oversight was bogus varno errors. - - - - - - Fix btree preprocessing of indexedcol IS - NULL conditions (Dean Rasheed) - - - - Such a condition is unsatisfiable if combined with any other type of - btree-indexable condition on the same index column. The case was - handled incorrectly in 9.0.0 and later, leading to query output where - there should be none. - - - - - - Work around gcc 4.6.0 bug that breaks WAL replay (Tom Lane) - - - - This could lead to loss of committed transactions after a server crash. - - - - - - Fix dump bug for VALUES in a view (Tom Lane) - - - - - - Disallow SELECT FOR UPDATE/SHARE on sequences (Tom Lane) - - - - This operation doesn't work as expected and can lead to failures. - - - - - - Fix VACUUM so that it always updates - pg_class.reltuples/relpages (Tom - Lane) - - - - This fixes some scenarios where autovacuum could make increasingly poor - decisions about when to vacuum tables. - - - - - - Defend against integer overflow when computing size of a hash table (Tom - Lane) - - - - - - Fix cases where CLUSTER might attempt to access - already-removed TOAST data (Tom Lane) - - - - - - Fix premature timeout failures during initial authentication transaction - (Tom Lane) - - - - - - Fix portability bugs in use of credentials control messages for - peer authentication (Tom Lane) - - - - - - Fix SSPI login when multiple roundtrips are required (Ahmed Shinwari, - Magnus Hagander) - - - - The typical symptom of this problem was The function requested is - not supported errors during SSPI login. - - - - - - Fix failure when adding a new variable of a custom variable class to - postgresql.conf (Tom Lane) - - - - - - Throw an error if pg_hba.conf contains hostssl - but SSL is disabled (Tom Lane) - - - - This was concluded to be more user-friendly than the previous behavior - of silently ignoring such lines. - - - - - - Fix failure when DROP OWNED BY attempts to remove default - privileges on sequences (Shigeru Hanada) - - - - - - Fix typo in pg_srand48 seed initialization (Andres Freund) - - - - This led to failure to use all bits of the provided seed. This function - is not used on most platforms (only those without srandom), - and the potential security exposure from a less-random-than-expected - seed seems minimal in any case. - - - - - - Avoid integer overflow when the sum of LIMIT and - OFFSET values exceeds 2^63 (Heikki Linnakangas) - - - - - - Add overflow checks to int4 and int8 versions of - generate_series() (Robert Haas) - - - - - - Fix trailing-zero removal in to_char() (Marti Raudsepp) - - - - In a format with FM and no digit positions - after the decimal point, zeroes to the left of the decimal point could - be removed incorrectly. - - - - - - Fix pg_size_pretty() to avoid overflow for inputs close to - 2^63 (Tom Lane) - - - - - - Weaken plpgsql's check for typmod matching in record values (Tom Lane) - - - - An overly enthusiastic check could lead to discarding length modifiers - that should have been kept. - - - - - - Correctly handle quotes in locale names during initdb - (Heikki Linnakangas) - - - - The case can arise with some Windows locales, such as People's - Republic of China. - - - - - - In pg_upgrade, avoid dumping orphaned temporary tables - (Bruce Momjian) - - - - This prevents situations wherein table OID assignments could get out of - sync between old and new installations. - - - - - - Fix pg_upgrade to preserve toast tables' relfrozenxids - during an upgrade from 8.3 (Bruce Momjian) - - - - Failure to do this could lead to pg_clog files being - removed too soon after the upgrade. - - - - - - In pg_upgrade, fix the -l (log) option to - work on Windows (Bruce Momjian) - - - - - - In pg_ctl, support silent mode for service registrations - on Windows (MauMau) - - - - - - Fix psql's counting of script file line numbers during - COPY from a different file (Tom Lane) - - - - - - Fix pg_restore's direct-to-database mode for - standard_conforming_strings (Tom Lane) - - - - pg_restore could emit incorrect commands when restoring - directly to a database server from an archive file that had been made - with standard_conforming_strings set to on. - - - - - - Be more user-friendly about unsupported cases for parallel - pg_restore (Tom Lane) - - - - This change ensures that such cases are detected and reported before - any restore actions have been taken. - - - - - - Fix write-past-buffer-end and memory leak in libpq's - LDAP service lookup code (Albe Laurenz) - - - - - - In libpq, avoid failures when using nonblocking I/O - and an SSL connection (Martin Pihlak, Tom Lane) - - - - - - Improve libpq's handling of failures during connection startup - (Tom Lane) - - - - In particular, the response to a server report of fork() - failure during SSL connection startup is now saner. - - - - - - Improve libpq's error reporting for SSL failures (Tom - Lane) - - - - - - Fix PQsetvalue() to avoid possible crash when adding a new - tuple to a PGresult originally obtained from a server - query (Andrew Chernow) - - - - - - Make ecpglib write double values with 15 digits - precision (Akira Kurosawa) - - - - - - In ecpglib, be sure LC_NUMERIC setting is - restored after an error (Michael Meskes) - - - - - - Apply upstream fix for blowfish signed-character bug (CVE-2011-2483) - (Tom Lane) - - - - contrib/pg_crypto's blowfish encryption code could give - wrong results on platforms where char is signed (which is most), - leading to encrypted passwords being weaker than they should be. - - - - - - Fix memory leak in contrib/seg (Heikki Linnakangas) - - - - - - Fix pgstatindex() to give consistent results for empty - indexes (Tom Lane) - - - - - - Allow building with perl 5.14 (Alex Hunsaker) - - - - - - Fix assorted issues with build and install file paths containing spaces - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2011i - for DST law changes in Canada, Egypt, Russia, Samoa, and South Sudan. - - - - - - - - - - Release 9.0.4 - - - Release date: - 2011-04-18 - - - - This release contains a variety of fixes from 9.0.3. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.4 - - - A dump/restore is not required for those running 9.0.X. - - - - However, if your installation was upgraded from a previous major - release by running pg_upgrade, you should take - action to prevent possible data loss due to a now-fixed bug in - pg_upgrade. The recommended solution is to run - VACUUM FREEZE on all TOAST tables. - More information is available at - http://wiki.postgresql.org/wiki/20110408pg_upgrade_fix. - - - - - - Changes - - - - - - Fix pg_upgrade's handling of TOAST tables - (Bruce Momjian) - - - - The pg_class.relfrozenxid value for - TOAST tables was not correctly copied into the new installation - during pg_upgrade. This could later result in - pg_clog files being discarded while they were still - needed to validate tuples in the TOAST tables, leading to - could not access status of transaction failures. - - - - This error poses a significant risk of data loss for installations - that have been upgraded with pg_upgrade. This patch - corrects the problem for future uses of pg_upgrade, - but does not in itself cure the issue in installations that have been - processed with a buggy version of pg_upgrade. - - - - - - Suppress incorrect PD_ALL_VISIBLE flag was incorrectly set - warning (Heikki Linnakangas) - - - - VACUUM would sometimes issue this warning in cases that - are actually valid. - - - - - - Use better SQLSTATE error codes for hot standby conflict cases - (Tatsuo Ishii and Simon Riggs) - - - - All retryable conflict errors now have an error code that indicates - that a retry is possible. Also, session closure due to the database - being dropped on the master is now reported as - ERRCODE_DATABASE_DROPPED, rather than - ERRCODE_ADMIN_SHUTDOWN, so that connection poolers can - handle the situation correctly. - - - - - - Prevent intermittent hang in interactions of startup process with - bgwriter process (Simon Riggs) - - - - This affected recovery in non-hot-standby cases. - - - - - - Disallow including a composite type in itself (Tom Lane) - - - - This prevents scenarios wherein the server could recurse infinitely - while processing the composite type. While there are some possible - uses for such a structure, they don't seem compelling enough to - justify the effort required to make sure it always works safely. - - - - - - Avoid potential deadlock during catalog cache initialization - (Nikhil Sontakke) - - - - In some cases the cache loading code would acquire share lock on a - system index before locking the index's catalog. This could deadlock - against processes trying to acquire exclusive locks in the other, - more standard order. - - - - - - Fix dangling-pointer problem in BEFORE ROW UPDATE trigger - handling when there was a concurrent update to the target tuple - (Tom Lane) - - - - This bug has been observed to result in intermittent cannot - extract system attribute from virtual tuple failures while trying to - do UPDATE RETURNING ctid. There is a very small probability - of more serious errors, such as generating incorrect index entries for - the updated tuple. - - - - - - Disallow DROP TABLE when there are pending deferred trigger - events for the table (Tom Lane) - - - - Formerly the DROP would go through, leading to - could not open relation with OID nnn errors when the - triggers were eventually fired. - - - - - - Allow replication as a user name in - pg_hba.conf (Andrew Dunstan) - - - - replication is special in the database name column, but it - was mistakenly also treated as special in the user name column. - - - - - - Prevent crash triggered by constant-false WHERE conditions during - GEQO optimization (Tom Lane) - - - - - - Improve planner's handling of semi-join and anti-join cases - (Tom Lane) - - - - - - Fix handling of SELECT FOR UPDATE in a sub-SELECT - (Tom Lane) - - - - This bug typically led to cannot extract system attribute from - virtual tuple errors. - - - - - - Fix selectivity estimation for text search to account for NULLs - (Jesper Krogh) - - - - - - Fix get_actual_variable_range() to support hypothetical indexes - injected by an index adviser plugin (Gurjeet Singh) - - - - - - Fix PL/Python memory leak involving array slices (Daniel Popowich) - - - - - - Allow libpq's SSL initialization to succeed when - user's home directory is unavailable (Tom Lane) - - - - If the SSL mode is such that a root certificate file is not required, - there is no need to fail. This change restores the behavior to what - it was in pre-9.0 releases. - - - - - - Fix libpq to return a useful error message for errors - detected in conninfo_array_parse (Joseph Adams) - - - - A typo caused the library to return NULL, rather than the - PGconn structure containing the error message, to the - application. - - - - - - Fix ecpg preprocessor's handling of float constants - (Heikki Linnakangas) - - - - - - Fix parallel pg_restore to handle comments on - POST_DATA items correctly (Arnd Hannemann) - - - - - - Fix pg_restore to cope with long lines (over 1KB) in - TOC files (Tom Lane) - - - - - - Put in more safeguards against crashing due to division-by-zero - with overly enthusiastic compiler optimization (Aurelien Jarno) - - - - - - Support use of dlopen() in FreeBSD and OpenBSD on MIPS (Tom Lane) - - - - There was a hard-wired assumption that this system function was not - available on MIPS hardware on these systems. Use a compile-time test - instead, since more recent versions have it. - - - - - - Fix compilation failures on HP-UX (Heikki Linnakangas) - - - - - - Avoid crash when trying to write to the Windows console very early - in process startup (Rushabh Lathia) - - - - - - Support building with MinGW 64 bit compiler for Windows - (Andrew Dunstan) - - - - - - Fix version-incompatibility problem with libintl on - Windows (Hiroshi Inoue) - - - - - - Fix usage of xcopy in Windows build scripts to - work correctly under Windows 7 (Andrew Dunstan) - - - - This affects the build scripts only, not installation or usage. - - - - - - Fix path separator used by pg_regress on Cygwin - (Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2011f - for DST law changes in Chile, Cuba, Falkland Islands, Morocco, Samoa, - and Turkey; also historical corrections for South Australia, Alaska, - and Hawaii. - - - - - - - - - - Release 9.0.3 - - - Release date: - 2011-01-31 - - - - This release contains a variety of fixes from 9.0.2. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.3 - - - A dump/restore is not required for those running 9.0.X. - - - - - - Changes - - - - - - Before exiting walreceiver, ensure all the received WAL - is fsync'd to disk (Heikki Linnakangas) - - - - Otherwise the standby server could replay some un-synced WAL, conceivably - leading to data corruption if the system crashes just at that point. - - - - - - Avoid excess fsync activity in walreceiver - (Heikki Linnakangas) - - - - - - Make ALTER TABLE revalidate uniqueness and exclusion - constraints when needed (Noah Misch) - - - - This was broken in 9.0 by a change that was intended to suppress - revalidation during VACUUM FULL and CLUSTER, - but unintentionally affected ALTER TABLE as well. - - - - - - Fix EvalPlanQual for UPDATE of an inheritance tree in which - the tables are not all alike (Tom Lane) - - - - Any variation in the table row types (including dropped columns present - in only some child tables) would confuse the EvalPlanQual code, leading - to misbehavior or even crashes. Since EvalPlanQual is only executed - during concurrent updates to the same row, the problem was only seen - intermittently. - - - - - - Avoid failures when EXPLAIN tries to display a simple-form - CASE expression (Tom Lane) - - - - If the CASE's test expression was a constant, the planner - could simplify the CASE into a form that confused the - expression-display code, resulting in unexpected CASE WHEN - clause errors. - - - - - - Fix assignment to an array slice that is before the existing range - of subscripts (Tom Lane) - - - - If there was a gap between the newly added subscripts and the first - pre-existing subscript, the code miscalculated how many entries needed - to be copied from the old array's null bitmap, potentially leading to - data corruption or crash. - - - - - - Avoid unexpected conversion overflow in planner for very distant date - values (Tom Lane) - - - - The date type supports a wider range of dates than can be - represented by the timestamp types, but the planner assumed it - could always convert a date to timestamp with impunity. - - - - - - Fix PL/Python crash when an array contains null entries (Alex Hunsaker) - - - - - - Remove ecpg's fixed length limit for constants defining - an array dimension (Michael Meskes) - - - - - - Fix erroneous parsing of tsquery values containing - ... & !(subexpression) | ... (Tom Lane) - - - - Queries containing this combination of operators were not executed - correctly. The same error existed in contrib/intarray's - query_int type and contrib/ltree's - ltxtquery type. - - - - - - Fix buffer overrun in contrib/intarray's input function - for the query_int type (Apple) - - - - This bug is a security risk since the function's return address could - be overwritten. Thanks to Apple Inc's security team for reporting this - issue and supplying the fix. (CVE-2010-4015) - - - - - - Fix bug in contrib/seg's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a seg column. - If you have such an index, consider REINDEXing it after - installing this update. (This is identical to the bug that was fixed in - contrib/cube in the previous update.) - - - - - - - - - - Release 9.0.2 - - - Release date: - 2010-12-16 - - - - This release contains a variety of fixes from 9.0.1. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.2 - - - A dump/restore is not required for those running 9.0.X. - - - - - - Changes - - - - - - Force the default - wal_sync_method - to be fdatasync on Linux (Tom Lane, Marti Raudsepp) - - - - The default on Linux has actually been fdatasync for many - years, but recent kernel changes caused PostgreSQL to - choose open_datasync instead. This choice did not result - in any performance improvement, and caused outright failures on - certain filesystems, notably ext4 with the - data=journal mount option. - - - - - - Fix too many KnownAssignedXids error during Hot Standby - replay (Heikki Linnakangas) - - - - - - Fix race condition in lock acquisition during Hot Standby (Simon Riggs) - - - - - - Avoid unnecessary conflicts during Hot Standby (Simon Riggs) - - - - This fixes some cases where replay was considered to conflict with - standby queries (causing delay of replay or possibly cancellation of - the queries), but there was no real conflict. - - - - - - Fix assorted bugs in WAL replay logic for GIN indexes (Tom Lane) - - - - This could result in bad buffer id: 0 failures or - corruption of index contents during replication. - - - - - - Fix recovery from base backup when the starting checkpoint WAL record - is not in the same WAL segment as its redo point (Jeff Davis) - - - - - - Fix corner-case bug when streaming replication is enabled immediately - after creating the master database cluster (Heikki Linnakangas) - - - - - - Fix persistent slowdown of autovacuum workers when multiple workers - remain active for a long time (Tom Lane) - - - - The effective vacuum_cost_limit for an autovacuum worker - could drop to nearly zero if it processed enough tables, causing it - to run extremely slowly. - - - - - - Fix long-term memory leak in autovacuum launcher (Alvaro Herrera) - - - - - - Avoid failure when trying to report an impending transaction - wraparound condition from outside a transaction (Tom Lane) - - - - This oversight prevented recovery after transaction wraparound got - too close, because database startup processing would fail. - - - - - - Add support for detecting register-stack overrun on IA64 - (Tom Lane) - - - - The IA64 architecture has two hardware stacks. Full - prevention of stack-overrun failures requires checking both. - - - - - - Add a check for stack overflow in copyObject() (Tom Lane) - - - - Certain code paths could crash due to stack overflow given a - sufficiently complex query. - - - - - - Fix detection of page splits in temporary GiST indexes (Heikki - Linnakangas) - - - - It is possible to have a concurrent page split in a - temporary index, if for example there is an open cursor scanning the - index when an insertion is done. GiST failed to detect this case and - hence could deliver wrong results when execution of the cursor - continued. - - - - - - Fix error checking during early connection processing (Tom Lane) - - - - The check for too many child processes was skipped in some cases, - possibly leading to postmaster crash when attempting to add the new - child process to fixed-size arrays. - - - - - - Improve efficiency of window functions (Tom Lane) - - - - Certain cases where a large number of tuples needed to be read in - advance, but work_mem was large enough to allow them all - to be held in memory, were unexpectedly slow. - percent_rank(), cume_dist() and - ntile() in particular were subject to this problem. - - - - - - Avoid memory leakage while ANALYZE'ing complex index - expressions (Tom Lane) - - - - - - Ensure an index that uses a whole-row Var still depends on its table - (Tom Lane) - - - - An index declared like create index i on t (foo(t.*)) - would not automatically get dropped when its table was dropped. - - - - - - Add missing support in DROP OWNED BY for removing foreign - data wrapper/server privileges belonging to a user (Heikki Linnakangas) - - - - - - Do not inline a SQL function with multiple OUT - parameters (Tom Lane) - - - - This avoids a possible crash due to loss of information about the - expected result rowtype. - - - - - - Fix crash when inline-ing a set-returning function whose argument list - contains a reference to an inline-able user function (Tom Lane) - - - - - - Behave correctly if ORDER BY, LIMIT, - FOR UPDATE, or WITH is attached to the - VALUES part of INSERT ... VALUES (Tom Lane) - - - - - - Make the OFF keyword unreserved (Heikki Linnakangas) - - - - This prevents problems with using off as a variable name in - PL/pgSQL. That worked before 9.0, but was now broken - because PL/pgSQL now treats all core reserved words - as reserved. - - - - - - Fix constant-folding of COALESCE() expressions (Tom Lane) - - - - The planner would sometimes attempt to evaluate sub-expressions that - in fact could never be reached, possibly leading to unexpected errors. - - - - - - Fix could not find pathkey item to sort planner failure - with comparison of whole-row Vars (Tom Lane) - - - - - - Fix postmaster crash when connection acceptance - (accept() or one of the calls made immediately after it) - fails, and the postmaster was compiled with GSSAPI support (Alexander - Chernikov) - - - - - - Retry after receiving an invalid response packet from a RADIUS - authentication server (Magnus Hagander) - - - - This fixes a low-risk potential denial of service condition. - - - - - - Fix missed unlink of temporary files when log_temp_files - is active (Tom Lane) - - - - If an error occurred while attempting to emit the log message, the - unlink was not done, resulting in accumulation of temp files. - - - - - - Add print functionality for InhRelation nodes (Tom Lane) - - - - This avoids a failure when debug_print_parse is enabled - and certain types of query are executed. - - - - - - Fix incorrect calculation of distance from a point to a horizontal - line segment (Tom Lane) - - - - This bug affected several different geometric distance-measurement - operators. - - - - - - Fix incorrect calculation of transaction status in - ecpg (Itagaki Takahiro) - - - - - - Fix errors in psql's Unicode-escape support (Tom Lane) - - - - - - Speed up parallel pg_restore when the archive - contains many large objects (blobs) (Tom Lane) - - - - - - Fix PL/pgSQL's handling of simple - expressions to not fail in recursion or error-recovery cases (Tom Lane) - - - - - - Fix PL/pgSQL's error reporting for no-such-column - cases (Tom Lane) - - - - As of 9.0, it would sometimes report missing FROM-clause entry - for table foo when record foo has no field bar would be - more appropriate. - - - - - - Fix PL/Python to honor typmod (i.e., length or - precision restrictions) when assigning to tuple fields (Tom Lane) - - - - This fixes a regression from 8.4. - - - - - - Fix PL/Python's handling of set-returning functions - (Jan Urbanski) - - - - Attempts to call SPI functions within the iterator generating a set - result would fail. - - - - - - Fix bug in contrib/cube's GiST picksplit algorithm - (Alexander Korotkov) - - - - This could result in considerable inefficiency, though not actually - incorrect answers, in a GiST index on a cube column. - If you have such an index, consider REINDEXing it after - installing this update. - - - - - - Don't emit identifier will be truncated notices in - contrib/dblink except when creating new connections - (Itagaki Takahiro) - - - - - - Fix potential coredump on missing public key in - contrib/pgcrypto (Marti Raudsepp) - - - - - - Fix buffer overrun in contrib/pg_upgrade (Hernan Gonzalez) - - - - - - Fix memory leak in contrib/xml2's XPath query functions - (Tom Lane) - - - - - - Update time zone data files to tzdata release 2010o - for DST law changes in Fiji and Samoa; - also historical corrections for Hong Kong. - - - - - - - - - - Release 9.0.1 - - - Release date: - 2010-10-04 - - - - This release contains a variety of fixes from 9.0.0. - For information about new features in the 9.0 major release, see - . - - - - Migration to Version 9.0.1 - - - A dump/restore is not required for those running 9.0.X. - - - - - - Changes - - - - - - Use a separate interpreter for each calling SQL userid in PL/Perl and - PL/Tcl (Tom Lane) - - - - This change prevents security problems that can be caused by subverting - Perl or Tcl code that will be executed later in the same session under - another SQL user identity (for example, within a SECURITY - DEFINER function). Most scripting languages offer numerous ways that - that might be done, such as redefining standard functions or operators - called by the target function. Without this change, any SQL user with - Perl or Tcl language usage rights can do essentially anything with the - SQL privileges of the target function's owner. - - - - The cost of this change is that intentional communication among Perl - and Tcl functions becomes more difficult. To provide an escape hatch, - PL/PerlU and PL/TclU functions continue to use only one interpreter - per session. This is not considered a security issue since all such - functions execute at the trust level of a database superuser already. - - - - It is likely that third-party procedural languages that claim to offer - trusted execution have similar security issues. We advise contacting - the authors of any PL you are depending on for security-critical - purposes. - - - - Our thanks to Tim Bunce for pointing out this issue (CVE-2010-3433). - - - - - - Improve pg_get_expr() security fix so that the function - can still be used on the output of a sub-select (Tom Lane) - - - - - - Fix incorrect placement of placeholder evaluation (Tom Lane) - - - - This bug could result in query outputs being non-null when they - should be null, in cases where the inner side of an outer join - is a sub-select with non-strict expressions in its output list. - - - - - - Fix join removal's handling of placeholder expressions (Tom Lane) - - - - - - Fix possible duplicate scans of UNION ALL member relations - (Tom Lane) - - - - - - Prevent infinite loop in ProcessIncomingNotify() after unlistening - (Jeff Davis) - - - - - - Prevent show_session_authorization() from crashing within autovacuum - processes (Tom Lane) - - - - - - Re-allow input of Julian dates prior to 0001-01-01 AD (Tom Lane) - - - - Input such as 'J100000'::date worked before 8.4, - but was unintentionally broken by added error-checking. - - - - - - Make psql recognize DISCARD ALL as a command that should - not be encased in a transaction block in autocommit-off mode - (Itagaki Takahiro) - - - - - - Update build infrastructure and documentation to reflect the source code - repository's move from CVS to Git (Magnus Hagander and others) - - - - - - - - - - Release 9.0 - - - Release date: - 2010-09-20 - - - - Overview - - - This release of - PostgreSQL adds features that have been requested - for years, such as easy-to-use replication, a mass permission-changing - facility, and anonymous code blocks. While past major releases have - been conservative in their scope, this release shows a - bold new desire to provide facilities that new and existing - users of PostgreSQL will embrace. This has all - been done with few incompatibilities. Major enhancements include: - - - - - - - - - - Built-in replication based on log shipping. This advance consists of - two features: Streaming Replication, allowing continuous archive - (WAL) files to be streamed over a network connection to a - standby server, and Hot Standby, allowing continuous archive standby - servers to execute read-only queries. The net effect is to support a - single master with multiple read-only slave servers. - - - - - - Easier database object permissions management. GRANT/REVOKE IN - SCHEMA supports mass permissions changes on existing objects, - while ALTER DEFAULT - PRIVILEGES allows control of privileges for objects created in - the future. Large objects (BLOBs) now support permissions management as - well. - - - - - - Broadly enhanced stored procedure support. - The DO statement supports - ad-hoc or anonymous code blocks. - Functions can now be called using named parameters. - PL/pgSQL is now installed by default, and - PL/Perl and PL/Python have been enhanced in several ways, - including support for Python3. - - - - - - Full support for 64-bit - Windows. - - - - - - More advanced reporting queries, including additional windowing options - (PRECEDING and FOLLOWING) and the ability to - control the order in which values are fed to aggregate functions. - - - - - - New trigger features, including - SQL-standard-compliant per-column triggers and - conditional trigger execution. - - - - - - Deferrable - unique constraints. Mass updates to unique keys are now possible - without trickery. - - - - - - Exclusion constraints. - These provide a generalized version of unique constraints, allowing - enforcement of complex conditions. - - - - - - New and enhanced security features, including RADIUS authentication, - LDAP authentication improvements, and a new contrib module - passwordcheck - for testing password strength. - - - - - - New high-performance implementation of the - LISTEN/NOTIFY feature. - Pending events are now stored in a memory-based queue rather than - a table. Also, a payload string can be sent with each - event, rather than transmitting just an event name as before. - - - - - - New implementation of - VACUUM FULL. - This command now rewrites the entire table and indexes, rather than - moving individual rows to compact space. It is substantially faster - in most cases, and no longer results in index bloat. - - - - - - New contrib module - pg_upgrade - to support in-place upgrades from 8.3 or 8.4 to 9.0. - - - - - - Multiple performance enhancements for specific types of queries, - including elimination of unnecessary joins. This helps optimize some - automatically-generated queries, such as those produced by - object-relational mappers (ORMs). - - - - - - EXPLAIN enhancements. - The output is now available in JSON, XML, or YAML format, and includes - buffer utilization and other data not previously available. - - - - - - hstore improvements, - including new functions and greater data capacity. - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.0 - - - A dump/restore using pg_dump, - or use of pg_upgrade, is required - for those wishing to migrate data from any previous - release. - - - - Version 9.0 contains a number of changes that selectively break backwards - compatibility in order to support new features and code quality - improvements. In particular, users who make extensive use of PL/pgSQL, - Point-In-Time Recovery (PITR), or Warm Standby should test their - applications because of slight user-visible changes in those areas. - Observe the following incompatibilities: - - - - Server Settings - - - - - - Remove server parameter add_missing_from, which was - defaulted to off for many years (Tom Lane) - - - - - - Remove server parameter regex_flavor, which - was defaulted to advanced - for many years (Tom Lane) - - - - - - archive_mode - now only affects archive_command; - a new setting, wal_level, affects - the contents of the write-ahead log (Heikki Linnakangas) - - - - - - log_temp_files - now uses default file size units of kilobytes (Robert Haas) - - - - - - - - - Queries - - - - - - When querying a parent table, - do not do any separate permission checks on child tables - scanned as part of the query (Peter Eisentraut) - - - - The SQL standard specifies this behavior, and it is also much more - convenient in practice than the former behavior of checking permissions - on each child as well as the parent. - - - - - - - - - Data Types - - - - - - bytea output now - appears in hex format by default (Peter Eisentraut) - - - - The server parameter bytea_output can be - used to select the traditional output format if needed for - compatibility. - - - - - - Array input now considers only plain ASCII whitespace characters - to be potentially ignorable; it will never ignore non-ASCII characters, - even if they are whitespace according to some locales (Tom Lane) - - - - This avoids some corner cases where array values could be interpreted - differently depending on the server's locale settings. - - - - - - Improve standards compliance of SIMILAR TO - patterns and SQL-style substring() patterns (Tom Lane) - - - - This includes treating ? and {...} as - pattern metacharacters, while they were simple literal characters - before; that corresponds to new features added in SQL:2008. - Also, ^ and $ are now treated as simple - literal characters; formerly they were treated as metacharacters, - as if the pattern were following POSIX rather than SQL rules. - Also, in SQL-standard substring(), use of parentheses - for nesting no longer interferes with capturing of a substring. - Also, processing of bracket expressions (character classes) is - now more standards-compliant. - - - - - - Reject negative length values in 3-parameter substring() - for bit strings, per the SQL standard (Tom Lane) - - - - - - Make date_trunc truncate rather than round when reducing - precision of fractional seconds (Tom Lane) - - - - The code always acted this way for integer-based dates/times. - Now float-based dates/times behave similarly. - - - - - - - - - Object Renaming - - - - - - Tighten enforcement of column name consistency during RENAME - when a child table inherits the same column from multiple unrelated - parents (KaiGai Kohei) - - - - - - No longer automatically rename indexes and index columns when the - underlying table columns are renamed (Tom Lane) - - - - Administrators can still rename such indexes and columns manually. - This change will require an update of the JDBC driver, and possibly other - drivers, so that unique indexes are correctly recognized after a rename. - - - - - - CREATE OR REPLACE FUNCTION can no longer change - the declared names of function parameters (Pavel Stehule) - - - - In order to avoid creating ambiguity in named-parameter calls, it is - no longer allowed to change the aliases for input parameters - in the declaration of an existing function (although names can still - be assigned to previously unnamed parameters). You now have to - DROP and recreate the function to do that. - - - - - - - - - PL/pgSQL - - - - - - PL/pgSQL now throws an error if a variable name conflicts with a - column name used in a query (Tom Lane) - - - - The former behavior was to bind ambiguous names to PL/pgSQL variables - in preference to query columns, which often resulted in surprising - misbehavior. Throwing an error allows easy detection of ambiguous - situations. Although it's recommended that functions encountering this - type of error be modified to remove the conflict, the old behavior can - be restored if necessary via the configuration parameter plpgsql.variable_conflict, - or via the per-function option #variable_conflict. - - - - - - PL/pgSQL no longer allows variable names that match certain SQL - reserved words (Tom Lane) - - - - This is a consequence of aligning the PL/pgSQL parser to match the - core SQL parser more closely. If necessary, - variable names can be double-quoted to avoid this restriction. - - - - - - PL/pgSQL now requires columns of composite results to match the - expected type modifier as well as base type (Pavel Stehule, Tom Lane) - - - - For example, if a column of the result type is declared as - NUMERIC(30,2), it is no longer acceptable to return a - NUMERIC of some other precision in that column. Previous - versions neglected to check the type modifier and would thus allow - result rows that didn't actually conform to the declared restrictions. - - - - - - PL/pgSQL now treats selection into composite fields more consistently - (Tom Lane) - - - - Formerly, a statement like - SELECT ... INTO rec.fld FROM ... - was treated as a scalar assignment even if the record field - fld was of composite type. Now it is treated as a - record assignment, the same as when the INTO target is a - regular variable of composite type. So the values to be assigned to the - field's subfields should be written as separate columns of the - SELECT list, not as a ROW(...) construct as in - previous versions. - - - - If you need to do this in a way that will work in both 9.0 and previous - releases, you can write something like - rec.fld := ROW(...) FROM .... - - - - - - Remove PL/pgSQL's RENAME declaration (Tom Lane) - - - - Instead of RENAME, use ALIAS, - which can now create an alias for any variable, not only dollar sign - parameter names (such as $1) as before. - - - - - - - - Other Incompatibilities - - - - - - Deprecate use of => as an operator name (Robert Haas) - - - - Future versions of PostgreSQL will probably reject - this operator name entirely, in order to support the SQL-standard - notation for named function parameters. For the moment, it is - still allowed, but a warning is emitted when such an operator is - defined. - - - - - - Remove support for platforms that don't have a working 64-bit - integer data type (Tom Lane) - - - - It is believed all still-supported platforms have working 64-bit - integer data types. - - - - - - - - - Changes - - Version 9.0 has an unprecedented number of new major features, - and over 200 enhancements, improvements, new commands, - new functions, and other changes. - - - - Server - - - Continuous Archiving and Streaming Replication - - - PostgreSQL's existing standby-server capability has been expanded both to - support read-only queries on standby servers and to greatly reduce - the lag between master and standby servers. For many users, this - will be a useful and low-administration form of replication, either - for high availability or for horizontal scalability. - - - - - - Allow a standby server to accept read-only queries - (Simon Riggs, Heikki Linnakangas) - - - - This feature is called Hot Standby. There are new - postgresql.conf and recovery.conf - settings to control this feature, as well as extensive - documentation. - - - - - - Allow write-ahead log (WAL) data to be streamed to a - standby server (Fujii Masao, Heikki Linnakangas) - - - - This feature is called Streaming Replication. - Previously WAL data could be sent to standby servers only - in units of entire WAL files (normally 16 megabytes each). - Streaming Replication eliminates this inefficiency and allows updates - on the master to be propagated to standby servers with very little - delay. There are new postgresql.conf and - recovery.conf settings to control this feature, as well as - extensive documentation. - - - - - - Add pg_last_xlog_receive_location() - and pg_last_xlog_replay_location(), which - can be used to monitor standby server WAL - activity (Simon Riggs, Fujii Masao, Heikki Linnakangas) - - - - - - - - - Performance - - - - - - Allow per-tablespace values to be set for sequential and random page - cost estimates (seq_page_cost/random_page_cost) - via ALTER TABLESPACE - ... SET/RESET (Robert Haas) - - - - - - Improve performance and reliability of EvalPlanQual rechecks in join - queries (Tom Lane) - - - - UPDATE, DELETE, and SELECT FOR - UPDATE/SHARE queries that involve joins will now behave much better - when encountering freshly-updated rows. - - - - - - Improve performance of TRUNCATE when - the table was created or truncated earlier in the same transaction - (Tom Lane) - - - - - - Improve performance of finding inheritance child tables (Tom Lane) - - - - - - - - - Optimizer - - - - - - Remove unnecessary outer - joins (Robert Haas) - - - - Outer joins where the inner side is unique and not referenced above - the join are unnecessary and are therefore now removed. This will - accelerate many automatically generated queries, such as those created - by object-relational mappers (ORMs). - - - - - - Allow IS NOT NULL restrictions to use indexes (Tom Lane) - - - - This is particularly useful for finding - MAX()/MIN() values in indexes that - contain many null values. - - - - - - Improve the optimizer's choices about when to use materialize nodes, - and when to use sorting versus hashing for DISTINCT - (Tom Lane) - - - - - - Improve the optimizer's equivalence detection for expressions involving - boolean <> operators (Tom Lane) - - - - - - - <link linkend="geqo">GEQO</link> - - - - - - Use the same random seed every time GEQO plans a query (Andres - Freund) - - - - While the Genetic Query Optimizer (GEQO) still selects - random plans, it now always selects the same random plans for identical - queries, thus giving more consistent performance. You can modify geqo_seed to experiment with - alternative plans. - - - - - - Improve GEQO plan selection (Tom Lane) - - - - This avoids the rare error failed to make a valid plan, - and should also improve planning speed. - - - - - - - - - Optimizer Statistics - - - - - - Improve ANALYZE - to support inheritance-tree statistics (Tom Lane) - - - - This is particularly useful for partitioned tables. However, - autovacuum does not yet automatically re-analyze parent tables - when child tables change. - - - - - - Improve autovacuum's - detection of when re-analyze is necessary (Tom Lane) - - - - - - Improve optimizer's estimation for greater/less-than comparisons - (Tom Lane) - - - - When looking up statistics for greater/less-than comparisons, - if the comparison value is in the first or last histogram bucket, - use an index (if available) to fetch the current actual column - minimum or maximum. This greatly improves the accuracy of estimates - for comparison values near the ends of the data range, particularly - if the range is constantly changing due to addition of new data. - - - - - - Allow setting of number-of-distinct-values statistics using ALTER TABLE - (Robert Haas) - - - - This allows users to override the estimated number or percentage of - distinct values for a column. This statistic is normally computed by - ANALYZE, but the estimate can be poor, especially on tables - with very large numbers of rows. - - - - - - - - - Authentication - - - - - - Add support for RADIUS (Remote - Authentication Dial In User Service) authentication - (Magnus Hagander) - - - - - - Allow LDAP - (Lightweight Directory Access Protocol) authentication - to operate in search/bind mode - (Robert Fleming, Magnus Hagander) - - - - This allows the user to be looked up first, then the system uses - the DN (Distinguished Name) returned for that user. - - - - - - Add samehost - and samenet designations to - pg_hba.conf (Stef Walter) - - - - These match the server's IP address and subnet address - respectively. - - - - - - Pass trusted SSL root certificate names to the client so the client - can return an appropriate client certificate (Craig Ringer) - - - - - - - - - Monitoring - - - - - - Add the ability for clients to set an application - name, which is displayed in - pg_stat_activity (Dave Page) - - - - This allows administrators to characterize database traffic - and troubleshoot problems by source application. - - - - - - Add a SQLSTATE option (%e) to log_line_prefix - (Guillaume Smet) - - - - This allows users to compile statistics on errors and messages - by error code number. - - - - - - - Write to the Windows event log in UTF16 encoding - (Itagaki Takahiro) - - - - Now there is true multilingual support for PostgreSQL log messages - on Windows. - - - - - - - - - Statistics Counters - - - - - - Add pg_stat_reset_shared('bgwriter') - to reset the cluster-wide shared statistics for the - background writer (Greg Smith) - - - - - - Add pg_stat_reset_single_table_counters() - and pg_stat_reset_single_function_counters() - to allow resetting the statistics counters for individual - tables and functions (Magnus Hagander) - - - - - - - - - Server Settings - - - - - - Allow setting of configuration parameters based on database/role combinations - (Alvaro Herrera) - - - - Previously only per-database and per-role settings were possible, - not combinations. All role and database settings are now stored - in the new pg_db_role_setting system catalog. A new - psql command \drds shows these settings. - The legacy system views pg_roles, - pg_shadow, and pg_user - do not show combination settings, and therefore no longer - completely represent the configuration for a user or database. - - - - - - Add server parameter bonjour, which - controls whether a Bonjour-enabled server advertises - itself via Bonjour (Tom Lane) - - - - The default is off, meaning it does not advertise. This allows - packagers to distribute Bonjour-enabled builds without worrying - that individual users might not want the feature. - - - - - - Add server parameter enable_material, which - controls the use of materialize nodes in the optimizer - (Robert Haas) - - - - The default is on. When off, the optimizer will not add - materialize nodes purely for performance reasons, though they - will still be used when necessary for correctness. - - - - - - Change server parameter log_temp_files to - use default file size units of kilobytes (Robert Haas) - - - - Previously this setting was interpreted in bytes if no units were - specified. - - - - - - Log changes of parameter values when postgresql.conf is - reloaded (Peter Eisentraut) - - - - This lets administrators and security staff audit changes of database - settings, and is also very convenient for checking the effects of - postgresql.conf edits. - - - - - - Properly enforce superuser permissions for custom server parameters - (Tom Lane) - - - - Non-superusers can no longer issue ALTER - ROLE/DATABASE SET for parameters that are not currently - known to the server. This allows the server to correctly check that - superuser-only parameters are only set by superusers. Previously, - the SET would be allowed and then ignored at session start, - making superuser-only custom parameters much less useful than they - should be. - - - - - - - - - - - Queries - - - - - - Perform SELECT - FOR UPDATE/SHARE processing after - applying LIMIT, so the number of rows returned - is always predictable (Tom Lane) - - - - Previously, changes made by concurrent transactions could cause a - SELECT FOR UPDATE to unexpectedly return fewer rows than - specified by its LIMIT. FOR UPDATE in combination - with ORDER BY can still produce surprising results, but that - can be corrected by placing FOR UPDATE in a subquery. - - - - - - Allow mixing of traditional and SQL-standard LIMIT/OFFSET - syntax (Tom Lane) - - - - - - Extend the supported frame options in window functions (Hitoshi - Harada) - - - - Frames can now start with CURRENT ROW, and the ROWS - n PRECEDING/FOLLOWING options are now - supported. - - - - - - Make SELECT INTO and CREATE TABLE AS return - row counts to the client in their command tags - (Boszormenyi Zoltan) - - - - This can save an entire round-trip to the client, allowing result counts - and pagination to be calculated without an additional - COUNT query. - - - - - - - Unicode Strings - - - - - - Support Unicode surrogate pairs (dual 16-bit representation) in - U& - strings and identifiers (Peter Eisentraut) - - - - - - Support Unicode escapes in E'...' - strings (Marko Kreen) - - - - - - - - - - - Object Manipulation - - - - - - Speed up CREATE - DATABASE by deferring flushes to disk (Andres - Freund, Greg Stark) - - - - - - Allow comments on - columns of tables, views, and composite types only, not other - relation types such as indexes and TOAST tables (Tom Lane) - - - - - - Allow the creation of enumerated types containing - no values (Bruce Momjian) - - - - - - Let values of columns having storage type MAIN remain on - the main heap page unless the row cannot fit on a page (Kevin Grittner) - - - - Previously MAIN values were forced out to TOAST - tables until the row size was less than one-quarter of the page size. - - - - - - - <command>ALTER TABLE</command> - - - - - - Implement IF EXISTS for ALTER TABLE DROP COLUMN - and ALTER TABLE DROP CONSTRAINT (Andres Freund) - - - - - - Allow ALTER TABLE commands that rewrite tables to skip - WAL logging (Itagaki Takahiro) - - - - Such operations either produce a new copy of the table or are rolled - back, so WAL archiving can be skipped, unless running in - continuous archiving mode. This reduces I/O overhead and improves - performance. - - - - - - Fix failure of ALTER TABLE table ADD COLUMN - col serial when done by non-owner of table - (Tom Lane) - - - - - - - - - <link linkend="sql-createtable"><command>CREATE TABLE</command></link> - - - - - - Add support for copying COMMENTS and STORAGE - settings in CREATE TABLE ... LIKE commands - (Itagaki Takahiro) - - - - - - Add a shortcut for copying all properties in CREATE - TABLE ... LIKE commands (Itagaki Takahiro) - - - - - - Add the SQL-standard - CREATE TABLE ... OF type command - (Peter Eisentraut) - - - - This allows creation of a table that matches an existing composite - type. Additional constraints and defaults can be specified in the - command. - - - - - - - - - Constraints - - - - - - Add deferrable - unique constraints (Dean Rasheed) - - - - This allows mass updates, such as - UPDATE tab SET col = col + 1, - to work reliably - on columns that have unique indexes or are marked as primary keys. - If the constraint is specified as DEFERRABLE it will be - checked at the end of the statement, rather than after each row is - updated. The constraint check can also be deferred until the end of the - current transaction, allowing such updates to be spread over multiple - SQL commands. - - - - - - Add - exclusion constraints - (Jeff Davis) - - - - Exclusion constraints generalize uniqueness constraints by allowing - arbitrary comparison operators, not just equality. They are created - with the CREATE - TABLE CONSTRAINT ... EXCLUDE clause. - The most common use of exclusion constraints is to specify that column - entries must not overlap, rather than simply not be equal. This is - useful for time periods and other ranges, as well as arrays. - This feature enhances checking of data integrity for many - calendaring, time-management, and scientific applications. - - - - - - Improve uniqueness-constraint violation error messages to - report the values causing the failure (Itagaki Takahiro) - - - - For example, a uniqueness constraint violation might now report - Key (x)=(2) already exists. - - - - - - - - - Object Permissions - - - - - - Add the ability to make mass permission changes across a whole - schema using the new GRANT/REVOKE - IN SCHEMA clause (Petr Jelinek) - - - - This simplifies management of object permissions - and makes it easier to utilize database roles for application - data security. - - - - - - Add ALTER - DEFAULT PRIVILEGES command to control privileges - of objects created later (Petr Jelinek) - - - - This greatly simplifies the assignment of object privileges in a - complex database application. Default privileges can be set for - tables, views, sequences, and functions. Defaults may be assigned on a - per-schema basis, or database-wide. - - - - - - Add the ability to control large object (BLOB) permissions with - GRANT/REVOKE (KaiGai Kohei) - - - - Formerly, any database user could read or modify any large object. - Read and write permissions can now be granted and revoked per - large object, and the ownership of large objects is tracked. - - - - - - - - - - - Utility Operations - - - - - - Make LISTEN/NOTIFY store pending events - in a memory queue, rather than in a system table (Joachim - Wieland) - - - - This substantially improves performance, while retaining the existing - features of transactional support and guaranteed delivery. - - - - - - Allow NOTIFY - to pass an optional payload string to listeners - (Joachim Wieland) - - - - This greatly improves the usefulness of - LISTEN/NOTIFY as a - general-purpose event queue system. - - - - - - Allow CLUSTER - on all per-database system catalogs (Tom Lane) - - - - Shared catalogs still cannot be clustered. - - - - - - - <link linkend="sql-copy"><command>COPY</command></link> - - - - - - Accept COPY ... CSV FORCE QUOTE * - (Itagaki Takahiro) - - - - Now * can be used as shorthand for all columns - in the FORCE QUOTE clause. - - - - - - Add new COPY syntax that allows options to be - specified inside parentheses (Robert Haas, Emmanuel Cecchet) - - - - This allows greater flexibility for future COPY options. - The old syntax is still supported, but only for pre-existing options. - - - - - - - - - <link linkend="sql-explain"><command>EXPLAIN</command></link> - - - - - - Allow EXPLAIN to output in XML, - JSON, or YAML format (Robert Haas, Greg - Sabino Mullane) - - - - The new output formats are easily machine-readable, supporting the - development of new tools for analysis of EXPLAIN output. - - - - - - Add new BUFFERS option to report query - buffer usage during EXPLAIN ANALYZE (Itagaki Takahiro) - - - - This allows better query profiling for individual queries. - Buffer usage is no longer reported in the output for log_statement_stats - and related settings. - - - - - - Add hash usage information to EXPLAIN output (Robert - Haas) - - - - - - Add new EXPLAIN syntax that allows options to be - specified inside parentheses (Robert Haas) - - - - This allows greater flexibility for future EXPLAIN options. - The old syntax is still supported, but only for pre-existing options. - - - - - - - - - <link linkend="sql-vacuum"><command>VACUUM</command></link> - - - - - - Change VACUUM FULL to rewrite the entire table and - rebuild its indexes, rather than moving individual rows around to - compact space (Itagaki Takahiro, Tom Lane) - - - - The previous method was usually slower and caused index bloat. - Note that the new method will use more disk space transiently - during VACUUM FULL; potentially as much as twice - the space normally occupied by the table and its indexes. - - - - - - - Add new VACUUM syntax that allows options to be - specified inside parentheses (Itagaki Takahiro) - - - - This allows greater flexibility for future VACUUM options. - The old syntax is still supported, but only for pre-existing options. - - - - - - - - - Indexes - - - - - - Allow an index to be named automatically by omitting the index name in - CREATE INDEX - (Tom Lane) - - - - - - By default, multicolumn indexes are now named after all their columns; - and index expression columns are now named based on their expressions - (Tom Lane) - - - - - - Reindexing shared system catalogs is now fully transactional - and crash-safe (Tom Lane) - - - - Formerly, reindexing a shared index was only allowed in standalone - mode, and a crash during the operation could leave the index in - worse condition than it was before. - - - - - - Add point_ops operator class for GiST - (Teodor Sigaev) - - - - This feature permits GiST indexing of point - columns. The index can be used for several types of queries - such as point <@ polygon - (point is in polygon). This should make many - PostGIS queries faster. - - - - - - Use red-black binary trees for GIN index creation - (Teodor Sigaev) - - - - Red-black trees are self-balancing. This avoids slowdowns in - cases where the input is in nonrandom order. - - - - - - - - - - - - Data Types - - - - - - Allow bytea values - to be written in hex notation (Peter Eisentraut) - - - - The server parameter bytea_output controls - whether hex or traditional format is used for bytea - output. Libpq's PQescapeByteaConn() function automatically - uses the hex format when connected to PostgreSQL 9.0 - or newer servers. However, pre-9.0 libpq versions will not - correctly process hex format from newer servers. - - - - The new hex format will be directly compatible with more applications - that use binary data, allowing them to store and retrieve it without - extra conversion. It is also significantly faster to read and write - than the traditional format. - - - - - - Allow server parameter extra_float_digits - to be increased to 3 (Tom Lane) - - - - The previous maximum extra_float_digits setting was - 2. There are cases where 3 digits are needed to dump and - restore float4 values exactly. pg_dump will - now use the setting of 3 when dumping from a server that allows it. - - - - - - Tighten input checking for int2vector values (Caleb - Welton) - - - - - - - <link linkend="textsearch">Full Text Search</link> - - - - - - Add prefix support in synonym dictionaries - (Teodor Sigaev) - - - - - - Add filtering dictionaries (Teodor Sigaev) - - - - Filtering dictionaries allow tokens to be modified then passed to - subsequent dictionaries. - - - - - - Allow underscores in email-address tokens (Teodor Sigaev) - - - - - - Use more standards-compliant rules for parsing URL tokens - (Tom Lane) - - - - - - - - - - - Functions - - - - - - Allow function calls to supply parameter names and match them to named - parameters in the function definition (Pavel Stehule) - - - - For example, if a function is defined to take parameters a - and b, it can be called with func(a := 7, b - := 12) or func(b := 12, a := 7). - - - - - - Support locale-specific regular expression - processing with UTF-8 server encoding (Tom Lane) - - - - Locale-specific regular expression functionality includes - case-insensitive matching and locale-specific character classes. - Previously, these features worked correctly for non-ASCII - characters only if the database used a single-byte server encoding (such - as LATIN1). They will still misbehave in multi-byte encodings other - than UTF-8. - - - - - - Add support for scientific notation in to_char() - (EEEE - specification) - (Pavel Stehule, Brendan Jurd) - - - - - - Make to_char() honor FM - (fill mode) in Y, YY, and - YYY specifications (Bruce Momjian, Tom Lane) - - - - It was already honored by YYYY. - - - - - - Fix to_char() to output localized numeric and monetary - strings in the correct encoding on Windows - (Hiroshi Inoue, Itagaki Takahiro, Bruce Momjian) - - - - - - Correct calculations of overlaps - and contains operations for polygons (Teodor Sigaev) - - - - The polygon && (overlaps) operator formerly just - checked to see if the two polygons' bounding boxes overlapped. It now - does a more correct check. The polygon @> and - <@ (contains/contained by) operators formerly checked - to see if one polygon's vertexes were all contained in the other; - this can wrongly report true for some non-convex polygons. - Now they check that all line segments of one polygon are contained in - the other. - - - - - - - Aggregates - - - - - - Allow aggregate functions to use ORDER BY (Andrew Gierth) - - - - For example, this is now supported: array_agg(a ORDER BY - b). This is useful with aggregates for which the order of input - values is significant, and eliminates the need to use a nonstandard - subquery to determine the ordering. - - - - - - Multi-argument aggregate functions can now use DISTINCT - (Andrew Gierth) - - - - - - Add the string_agg() - aggregate function to combine values into a single - string (Pavel Stehule) - - - - - - Aggregate functions that are called with DISTINCT are - now passed NULL values if the aggregate transition function is - not marked as STRICT (Andrew Gierth) - - - - For example, agg(DISTINCT x) might pass a NULL x - value to agg(). This is more consistent with the behavior - in non-DISTINCT cases. - - - - - - - - - Bit Strings - - - - - - Add get_bit() - and set_bit() functions for bit - strings, mirroring those for bytea (Leonardo - F) - - - - - - Implement OVERLAY() - (replace) for bit strings and bytea - (Leonardo F) - - - - - - - - - Object Information Functions - - - - - - Add pg_table_size() - and pg_indexes_size() to provide a more - user-friendly interface to the pg_relation_size() - function (Bernd Helmle) - - - - - - Add has_sequence_privilege() - for sequence permission checking (Abhijit Menon-Sen) - - - - - - Update the information_schema - views to conform to SQL:2008 - (Peter Eisentraut) - - - - - - Make the information_schema views correctly display maximum - octet lengths for char and varchar columns (Peter - Eisentraut) - - - - - - Speed up information_schema privilege views - (Joachim Wieland) - - - - - - - - - Function and Trigger Creation - - - - - - Support execution of anonymous code blocks using the DO statement - (Petr Jelinek, Joshua Tolley, Hannu Valtonen) - - - - This allows execution of server-side code without the need to create - and delete a temporary function definition. Code can be executed in - any language for which the user has permissions to define a function. - - - - - - Implement SQL-standard-compliant per-column triggers - (Itagaki Takahiro) - - - - Such triggers are fired only when the specified column(s) are affected - by the query, e.g. appear in an UPDATE's SET - list. - - - - - - Add the WHEN clause to CREATE TRIGGER - to allow control over whether a trigger is fired (Itagaki - Takahiro) - - - - While the same type of check can always be performed inside the - trigger, doing it in an external WHEN clause can have - performance benefits. - - - - - - - - - - - Server-Side Languages - - - - - - Add the OR REPLACE clause to CREATE LANGUAGE - (Tom Lane) - - - - This is helpful to optionally install a language if it does not - already exist, and is particularly helpful now that PL/pgSQL is - installed by default. - - - - - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side - Language - - - - - - Install PL/pgSQL by default (Bruce Momjian) - - - - The language can still be removed from a particular database if the - administrator has security or performance concerns about making it - available. - - - - - - Improve handling of cases where PL/pgSQL variable names conflict with - identifiers used in queries within a function - (Tom Lane) - - - - The default behavior is now to throw an error when there is a conflict, - so as to avoid surprising behaviors. This can be modified, via the - configuration parameter plpgsql.variable_conflict - or the per-function option #variable_conflict, to allow - either the variable or the query-supplied column to be used. In any - case PL/pgSQL will no longer attempt to substitute variables in places - where they would not be syntactically valid. - - - - - - Make PL/pgSQL use the main lexer, rather than its own version - (Tom Lane) - - - - This ensures accurate tracking of the main system's behavior for details - such as string escaping. Some user-visible details, such as the set - of keywords considered reserved in PL/pgSQL, have changed in - consequence. - - - - - - Avoid throwing an unnecessary error for an invalid record reference - (Tom Lane) - - - - An error is now thrown only if the reference is actually fetched, - rather than whenever the enclosing expression is reached. For - example, many people have tried to do this in triggers: - -if TG_OP = 'INSERT' and NEW.col1 = ... then - - This will now actually work as expected. - - - - - - Improve PL/pgSQL's ability to handle row types with dropped columns - (Pavel Stehule) - - - - - - Allow input parameters to be assigned values within - PL/pgSQL functions (Steve Prentice) - - - - Formerly, input parameters were treated as being declared - CONST, so the function's code could not change their - values. This restriction has been removed to simplify - porting of functions from other DBMSes that do not impose the - equivalent restriction. An input parameter now acts like a local - variable initialized to the passed-in value. - - - - - - Improve error location reporting in PL/pgSQL (Tom Lane) - - - - - - Add count and ALL options to MOVE - FORWARD/BACKWARD in PL/pgSQL (Pavel Stehule) - - - - - - Allow PL/pgSQL's WHERE CURRENT OF to use a cursor - variable (Tom Lane) - - - - - - Allow PL/pgSQL's OPEN cursor FOR EXECUTE to - use parameters (Pavel Stehule, Itagaki Takahiro) - - - - This is accomplished with a new USING clause. - - - - - - - - - <link linkend="plperl">PL/Perl</link> Server-Side Language - - - - - - Add new PL/Perl functions: quote_literal(), - quote_nullable(), quote_ident(), - encode_bytea(), decode_bytea(), - looks_like_number(), - encode_array_literal(), - encode_array_constructor() (Tim Bunce) - - - - - - Add server parameter plperl.on_init to - specify a PL/Perl initialization function (Tim - Bunce) - - - - plperl.on_plperl_init - and plperl.on_plperlu_init - are also available for initialization that is specific to the trusted - or untrusted language respectively. - - - - - - Support END blocks in PL/Perl (Tim Bunce) - - - - END blocks do not currently allow database access. - - - - - - Allow use strict in PL/Perl (Tim Bunce) - - - - Perl strict checks can also be globally enabled with the - new server parameter plperl.use_strict. - - - - - - Allow require in PL/Perl (Tim Bunce) - - - - This basically tests to see if the module is loaded, and if not, - generates an error. It will not allow loading of modules that - the administrator has not preloaded via the initialization parameters. - - - - - - Allow use feature in PL/Perl if Perl version 5.10 or - later is used (Tim Bunce) - - - - - - Verify that PL/Perl return values are valid in the server encoding - (Andrew Dunstan) - - - - - - - - - <link linkend="plpython">PL/Python</link> Server-Side Language - - - - - - Add Unicode support in PL/Python (Peter Eisentraut) - - - - Strings are automatically converted from/to the server encoding as - necessary. - - - - - - Improve bytea support in PL/Python (Caleb Welton) - - - - Bytea values passed into PL/Python are now represented as - binary, rather than the PostgreSQL bytea text format. - Bytea values containing null bytes are now also output - properly from PL/Python. Passing of boolean, integer, and float - values was also improved. - - - - - - Support arrays as parameters and - return values in PL/Python (Peter Eisentraut) - - - - - - Improve mapping of SQL domains to Python types (Peter Eisentraut) - - - - - - Add Python 3 support to PL/Python (Peter Eisentraut) - - - - The new server-side language is called plpython3u. This - cannot be used in the same session with the - Python 2 server-side language. - - - - - - Improve error location and exception reporting in PL/Python (Peter Eisentraut) - - - - - - - - - - - Client Applications - - - - - - Add an option to vacuumdb, to analyze without - vacuuming (Bruce Momjian) - - - - - - - <link linkend="app-psql"><application>psql</application></link> - - - - - - Add support for quoting/escaping the values of psql - variables as SQL strings or - identifiers (Pavel Stehule, Robert Haas) - - - - For example, :'var' will produce the value of - var quoted and properly escaped as a literal string, while - :"var" will produce its value quoted and escaped as an - identifier. - - - - - - Ignore a leading UTF-8-encoded Unicode byte-order marker in - script files read by psql (Itagaki Takahiro) - - - - This is enabled when the client encoding is UTF-8. - It improves compatibility with certain editors, mostly on Windows, - that insist on inserting such markers. - - - - - - Fix psql --file - to properly honor - (Bruce Momjian) - - - - - - Avoid overwriting of psql's command-line history when - two psql sessions are run concurrently (Tom Lane) - - - - - - Improve psql's tab completion support (Itagaki - Takahiro) - - - - - - Show \timing output when it is enabled, regardless of - quiet mode (Peter Eisentraut) - - - - - - - <application>psql</application> Display - - - - - - Improve display of wrapped columns in psql (Roger - Leigh) - - - - This behavior is now the default. - The previous formatting is available by using \pset linestyle - old-ascii. - - - - - - Allow psql to use fancy Unicode line-drawing - characters via \pset linestyle unicode (Roger Leigh) - - - - - - - - - <application>psql</application> <link - linkend="app-psql-meta-commands"><command>\d</command></link> - Commands - - - - - - Make \d show child tables that inherit from the specified - parent (Damien Clochard) - - - - \d shows only the number of child tables, while - \d+ shows the names of all child tables. - - - - - - Show definitions of index columns in \d index_name - (Khee Chin) - - - - The definition is useful for expression indexes. - - - - - - Show a view's defining query only in - \d+, not in \d (Peter Eisentraut) - - - - Always including the query was deemed overly verbose. - - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> - - - - - - Make pg_dump/pg_restore - - also remove large objects (Itagaki Takahiro) - - - - - - Fix pg_dump to properly dump large objects when - standard_conforming_strings is enabled (Tom Lane) - - - - The previous coding could fail when dumping to an archive file - and then generating script output from pg_restore. - - - - - - pg_restore now emits large-object data in hex format - when generating script output (Tom Lane) - - - - This could cause compatibility problems if the script is then - loaded into a pre-9.0 server. To work around that, restore - directly to the server, instead. - - - - - - Allow pg_dump to dump comments attached to columns - of composite types (Taro Minowa (Higepon)) - - - - - - Make pg_dump - output the pg_dump and server versions - in text output mode (Jim Cox, Tom Lane) - - - - These were already provided in custom output mode. - - - - - - pg_restore now complains if any command-line arguments - remain after the switches and optional file name (Tom Lane) - - - - Previously, it silently ignored any such arguments. - - - - - - - - - <link - linkend="app-pg-ctl"><application>pg_ctl</application></link> - - - - - - Allow pg_ctl to be used safely to start the - postmaster during a system reboot (Tom Lane) - - - - Previously, pg_ctl's parent process could have been - mistakenly identified as a running postmaster based on - a stale postmaster lock file, resulting in a transient - failure to start the database. - - - - - - Give pg_ctl the ability to initialize the database - (by invoking initdb) (Zdenek Kotala) - - - - - - - - - - - <application>Development Tools</application> - - - <link linkend="libpq"><application>libpq</application></link> - - - - - - Add new libpq functions - PQconnectdbParams() - and PQconnectStartParams() (Guillaume - Lelarge) - - - - These functions are similar to PQconnectdb() and - PQconnectStart() except that they accept a null-terminated - array of connection options, rather than requiring all options to - be provided in a single string. - - - - - - Add libpq functions PQescapeLiteral() - and PQescapeIdentifier() (Robert Haas) - - - - These functions return appropriately quoted and escaped SQL string - literals and identifiers. The caller is not required to pre-allocate - the string result, as is required by PQescapeStringConn(). - - - - - - Add support for a per-user service file (.pg_service.conf), - which is checked before the site-wide service file - (Peter Eisentraut) - - - - - - Properly report an error if the specified libpq service - cannot be found (Peter Eisentraut) - - - - - - Add TCP keepalive settings - in libpq (Tollef Fog Heen, Fujii Masao, Robert Haas) - - - - Keepalive settings were already supported on the server end of - TCP connections. - - - - - - Avoid extra system calls to block and unblock SIGPIPE - in libpq, on platforms that offer alternative methods - (Jeremy Kerr) - - - - - - When a .pgpass-supplied - password fails, mention where the password came from in the error - message (Bruce Momjian) - - - - - - Load all SSL certificates given in the client certificate file - (Tom Lane) - - - - This improves support for indirectly-signed SSL certificates. - - - - - - - - - <link linkend="ecpg"><application>ecpg</application></link> - - - - - - Add SQLDA - (SQL Descriptor Area) support to ecpg - (Boszormenyi Zoltan) - - - - - - Add the DESCRIBE - [ OUTPUT ] statement to ecpg - (Boszormenyi Zoltan) - - - - - - Add an ECPGtransactionStatus - function to return the current transaction status (Bernd Helmle) - - - - - - Add the string data type in ecpg - Informix-compatibility mode (Boszormenyi Zoltan) - - - - - - Allow ecpg to use new and old - variable names without restriction (Michael Meskes) - - - - - - Allow ecpg to use variable names in - free() (Michael Meskes) - - - - - - Make ecpg_dynamic_type() return zero for non-SQL3 data - types (Michael Meskes) - - - - Previously it returned the negative of the data type OID. - This could be confused with valid type OIDs, however. - - - - - - Support long long types on platforms that already have 64-bit - long (Michael Meskes) - - - - - - - <application>ecpg</application> Cursors - - - - - - Add out-of-scope cursor support in ecpg's native mode - (Boszormenyi Zoltan) - - - - This allows DECLARE to use variables that are not in - scope when OPEN is called. This facility already existed - in ecpg's Informix-compatibility mode. - - - - - - Allow dynamic cursor names in ecpg (Boszormenyi Zoltan) - - - - - - Allow ecpg to use noise words FROM and - IN in FETCH and MOVE (Boszormenyi - Zoltan) - - - - - - - - - - - - - Build Options - - - - - - Enable client thread safety by default (Bruce Momjian) - - - - The thread-safety option can be disabled with configure - . - - - - - - Add support for controlling the Linux out-of-memory killer - (Alex Hunsaker, Tom Lane) - - - - Now that /proc/self/oom_adj allows disabling - of the Linux out-of-memory (OOM) - killer, it's recommendable to disable OOM kills for the postmaster. - It may then be desirable to re-enable OOM kills for the postmaster's - child processes. The new compile-time option LINUX_OOM_ADJ - allows the killer to be reactivated for child processes. - - - - - - - Makefiles - - - - - - New Makefile targets world, - install-world, and installcheck-world - (Andrew Dunstan) - - - - These are similar to the existing all, install, - and installcheck targets, but they also build the - HTML documentation, build and test contrib, - and test server-side languages and ecpg. - - - - - - Add data and documentation installation location control to - PGXS Makefiles (Mark Cave-Ayland) - - - - - - Add Makefile rules to build the PostgreSQL documentation - as a single HTML file or as a single plain-text file - (Peter Eisentraut, Bruce Momjian) - - - - - - - - - Windows - - - - - - Support compiling on 64-bit - Windows and running in 64-bit - mode (Tsutomu Yamada, Magnus Hagander) - - - - This allows for large shared memory sizes on Windows. - - - - - - Support server builds using Visual Studio - 2008 (Magnus Hagander) - - - - - - - - - - - Source Code - - - - - - Distribute prebuilt documentation in a subdirectory tree, rather than - as tar archive files inside the distribution tarball - (Peter Eisentraut) - - - - For example, the prebuilt HTML documentation is now in - doc/src/sgml/html/; the manual pages are packaged - similarly. - - - - - - Make the server's lexer reentrant (Tom Lane) - - - - This was needed for use of the lexer by PL/pgSQL. - - - - - - Improve speed of memory allocation (Tom Lane, Greg Stark) - - - - - - User-defined constraint triggers now have entries in - pg_constraint as well as pg_trigger - (Tom Lane) - - - - Because of this change, - pg_constraint.pgconstrname is now - redundant and has been removed. - - - - - - Add system catalog columns - pg_constraint.conindid and - pg_trigger.tgconstrindid - to better document the use of indexes for constraint - enforcement (Tom Lane) - - - - - - Allow multiple conditions to be communicated to backends using a single - operating system signal (Fujii Masao) - - - - This allows new features to be added without a platform-specific - constraint on the number of signal conditions. - - - - - - Improve source code test coverage, including contrib, PL/Python, - and PL/Perl (Peter Eisentraut, Andrew Dunstan) - - - - - - Remove the use of flat files for system table bootstrapping - (Tom Lane, Alvaro Herrera) - - - - This improves performance when using many roles or - databases, and eliminates some possible failure conditions. - - - - - - Automatically generate the initial contents of - pg_attribute for bootstrapped catalogs - (John Naylor) - - - - This greatly simplifies changes to these catalogs. - - - - - - Split the processing of - INSERT/UPDATE/DELETE operations out - of execMain.c (Marko Tiikkaja) - - - - Updates are now executed in a separate ModifyTable node. This change is - necessary infrastructure for future improvements. - - - - - - Simplify translation of psql's SQL help text - (Peter Eisentraut) - - - - - - Reduce the lengths of some file names so that all file paths in the - distribution tarball are less than 100 characters (Tom Lane) - - - - Some decompression programs have problems with longer file paths. - - - - - - Add a new ERRCODE_INVALID_PASSWORD - SQLSTATE error code (Bruce Momjian) - - - - - - With authors' permissions, remove the few remaining personal source code - copyright notices (Bruce Momjian) - - - - The personal copyright notices were insignificant but the community - occasionally had to answer questions about them. - - - - - - Add new documentation section - about running PostgreSQL in non-durable mode - to improve performance (Bruce Momjian) - - - - - - Restructure the HTML documentation - Makefile rules to make their dependency checks work - correctly, avoiding unnecessary rebuilds (Peter Eisentraut) - - - - - - Use DocBook XSL stylesheets for man page - building, rather than Docbook2X (Peter Eisentraut) - - - - This changes the set of tools needed to build the man pages. - - - - - - Improve PL/Perl code structure (Tim Bunce) - - - - - - Improve error context reports in PL/Perl (Alexey Klyukin) - - - - - - - New Build Requirements - - - Note that these requirements do not apply when building from a - distribution tarball, since tarballs include the files that these - programs are used to build. - - - - - - Require Autoconf 2.63 to build - configure (Peter Eisentraut) - - - - - - Require Flex 2.5.31 or later to build - from a CVS checkout (Tom Lane) - - - - - - Require Perl version 5.8 or later to build - from a CVS checkout (John Naylor, Andrew Dunstan) - - - - - - - - - Portability - - - - - - Use a more modern API for Bonjour (Tom Lane) - - - - Bonjour support now requires macOS 10.3 or later. - The older API has been deprecated by Apple. - - - - - - Add spinlock support for the SuperH - architecture (Nobuhiro Iwamatsu) - - - - - - Allow non-GCC compilers to use inline functions if - they support them (Kurt Harriman) - - - - - - Remove support for platforms that don't have a working 64-bit - integer data type (Tom Lane) - - - - - - Restructure use of LDFLAGS to be more consistent - across platforms (Tom Lane) - - - - LDFLAGS is now used for linking both executables and shared - libraries, and we add on LDFLAGS_EX when linking - executables, or LDFLAGS_SL when linking shared libraries. - - - - - - - - - Server Programming - - - - - - Make backend header files safe to include in C++ - (Kurt Harriman, Peter Eisentraut) - - - - These changes remove keyword conflicts that previously made - C++ usage difficult in backend code. However, there - are still other complexities when using C++ for backend - functions. extern "C" { } is still necessary in - appropriate places, and memory management and error handling are - still problematic. - - - - - - Add AggCheckCallContext() - for use in detecting if a C function is - being called as an aggregate (Hitoshi Harada) - - - - - - Change calling convention for SearchSysCache() and related - functions to avoid hard-wiring the maximum number of cache keys - (Robert Haas) - - - - Existing calls will still work for the moment, but can be expected to - break in 9.1 or later if not converted to the new style. - - - - - - Require calls of fastgetattr() and - heap_getattr() backend macros to provide a non-NULL fourth - argument (Robert Haas) - - - - - - Custom typanalyze functions should no longer rely on - VacAttrStats.attr to determine the type - of data they will be passed (Tom Lane) - - - - This was changed to allow collection of statistics on index columns - for which the storage type is different from the underlying column - data type. There are new fields that tell the actual datatype being - analyzed. - - - - - - - - - Server Hooks - - - - - - Add parser hooks for processing ColumnRef and ParamRef nodes - (Tom Lane) - - - - - - Add a ProcessUtility hook so loadable modules can control utility - commands (Itagaki Takahiro) - - - - - - - - - Binary Upgrade Support - - - - - - Add contrib/pg_upgrade - to support in-place upgrades (Bruce Momjian) - - - - This avoids the requirement of dumping/reloading the database when - upgrading to a new major release of PostgreSQL, thus reducing downtime - by orders of magnitude. It supports upgrades to 9.0 - from PostgreSQL 8.3 and 8.4. - - - - - - Add support for preserving relation relfilenode values - during binary upgrades (Bruce Momjian) - - - - - - Add support for preserving pg_type - and pg_enum OIDs during binary upgrades - (Bruce Momjian) - - - - - - Move data files within tablespaces into - PostgreSQL-version-specific subdirectories - (Bruce Momjian) - - - - This simplifies binary upgrades. - - - - - - - - - - - Contrib - - - - - - Add multithreading option () to contrib/pgbench - (Itagaki Takahiro) - - - - This allows multiple CPUs to be used by pgbench, - reducing the risk of pgbench itself becoming the test bottleneck. - - - - - - Add \shell and \setshell meta - commands to contrib/pgbench - (Michael Paquier) - - - - - - New features for contrib/dict_xsyn - (Sergey Karpov) - - - - The new options are matchorig, matchsynonyms, - and keepsynonyms. - - - - - - Add full text dictionary contrib/unaccent - (Teodor Sigaev) - - - - This filtering dictionary removes accents from letters, which - makes full-text searches over multiple languages much easier. - - - - - - Add dblink_get_notify() - to contrib/dblink (Marcus Kempe) - - - - This allows asynchronous notifications in dblink. - - - - - - Improve contrib/dblink's handling of dropped columns - (Tom Lane) - - - - This affects dblink_build_sql_insert() - and related functions. These functions now number columns according - to logical not physical column numbers. - - - - - - Greatly increase contrib/hstore's data - length limit, and add B-tree and hash support so GROUP - BY and DISTINCT operations are possible on - hstore columns (Andrew Gierth) - - - - New functions and operators were also added. These improvements - make hstore a full-function key-value store embedded in - PostgreSQL. - - - - - - Add contrib/passwordcheck - to support site-specific password strength policies (Laurenz - Albe) - - - - The source code of this module should be modified to implement - site-specific password policies. - - - - - - Add contrib/pg_archivecleanup - tool (Simon Riggs) - - - - This is designed to be used in the - archive_cleanup_command - server parameter, to remove no-longer-needed archive files. - - - - - - Add query text to contrib/auto_explain - output (Andrew Dunstan) - - - - - - Add buffer access counters to contrib/pg_stat_statements - (Itagaki Takahiro) - - - - - - Update contrib/start-scripts/linux - to use /proc/self/oom_adj to disable the - Linux - out-of-memory (OOM) killer (Alex - Hunsaker, Tom Lane) - - - - - - - - diff --git a/doc/src/sgml/release-9.1.sgml b/doc/src/sgml/release-9.1.sgml deleted file mode 100644 index e6ce80032fd..00000000000 --- a/doc/src/sgml/release-9.1.sgml +++ /dev/null @@ -1,11761 +0,0 @@ - - - - - Release 9.1.24 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.1.23. - For information about new features in the 9.1 major release, see - . - - - - This is expected to be the last PostgreSQL release - in the 9.1.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 9.1.24 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix EvalPlanQual rechecks involving CTE scans (Tom Lane) - - - - The recheck would always see the CTE as returning no rows, typically - leading to failure to update rows that were recently updated. - - - - - - Fix improper repetition of previous results from hashed aggregation in - a subquery (Andrew Gierth) - - - - The test to see if we can reuse a previously-computed hash table of - the aggregate state values neglected the possibility of an outer query - reference appearing in an aggregate argument expression. A change in - the value of such a reference should lead to recalculating the hash - table, but did not. - - - - - - Fix timeout length when VACUUM is waiting for exclusive - table lock so that it can truncate the table (Simon Riggs) - - - - The timeout was meant to be 50 milliseconds, but it was actually only - 50 microseconds, causing VACUUM to give up on truncation - much more easily than intended. Set it to the intended value. - - - - - - Remove artificial restrictions on the values accepted - by numeric_in() and numeric_recv() - (Tom Lane) - - - - We allow numeric values up to the limit of the storage format (more - than 1e100000), so it seems fairly pointless - that numeric_in() rejected scientific-notation exponents - above 1000. Likewise, it was silly for numeric_recv() to - reject more than 1000 digits in an input value. - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - Fix file descriptor leakage when truncating a temporary relation of - more than 1GB (Andres Freund) - - - - - - Disallow starting a standalone backend with standby_mode - turned on (Michael Paquier) - - - - This can't do anything useful, since there will be no WAL receiver - process to fetch more WAL data; and it could result in misbehavior - in code that wasn't designed with this situation in mind. - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - Make ecpg's and - options work consistently with our other executables (Haribabu Kommi) - - - - - - Fix contrib/intarray/bench/bench.pl to print the results - of the EXPLAIN it does when given the option - (Daniel Gustafsson) - - - - - - Prevent failure of obsolete dynamic time zone abbreviations (Tom Lane) - - - - If a dynamic time zone abbreviation does not match any entry in the - referenced time zone, treat it as equivalent to the time zone name. - This avoids unexpected failures when IANA removes abbreviations from - their time zone database, as they did in tzdata - release 2016f and seem likely to do again in the future. The - consequences were not limited to not recognizing the individual - abbreviation; any mismatch caused - the pg_timezone_abbrevs view to fail altogether. - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.1.23 - - - Release date: - 2016-08-11 - - - - This release contains a variety of fixes from 9.1.22. - For information about new features in the 9.1 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.1.X release series in September 2016. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.1.23 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix possible mis-evaluation of - nested CASE-WHEN expressions (Heikki - Linnakangas, Michael Paquier, Tom Lane) - - - - A CASE expression appearing within the test value - subexpression of another CASE could become confused about - whether its own test value was null or not. Also, inlining of a SQL - function implementing the equality operator used by - a CASE expression could result in passing the wrong test - value to functions called within a CASE expression in the - SQL function's body. If the test values were of different data - types, a crash might result; moreover such situations could be abused - to allow disclosure of portions of server memory. (CVE-2016-5423) - - - - - - Fix client programs' handling of special characters in database and - role names (Noah Misch, Nathan Bossart, Michael Paquier) - - - - Numerous places in vacuumdb and other client programs - could become confused by database and role names containing double - quotes or backslashes. Tighten up quoting rules to make that safe. - Also, ensure that when a conninfo string is used as a database name - parameter to these programs, it is correctly treated as such throughout. - - - - Fix handling of paired double quotes - in psql's \connect - and \password commands to match the documentation. - - - - Introduce a new option - in psql's \connect command to allow - explicit control of whether to re-use connection parameters from a - previous connection. (Without this, the choice is based on whether - the database name looks like a conninfo string, as before.) This - allows secure handling of database names containing special - characters in pg_dumpall scripts. - - - - pg_dumpall now refuses to deal with database and role - names containing carriage returns or newlines, as it seems impractical - to quote those characters safely on Windows. In future we may reject - such names on the server side, but that step has not been taken yet. - - - - These are considered security fixes because crafted object names - containing special characters could have been used to execute - commands with superuser privileges the next time a superuser - executes pg_dumpall or other routine maintenance - operations. (CVE-2016-5424) - - - - - - Fix corner-case misbehaviors for IS NULL/IS NOT - NULL applied to nested composite values (Andrew Gierth, Tom Lane) - - - - The SQL standard specifies that IS NULL should return - TRUE for a row of all null values (thus ROW(NULL,NULL) IS - NULL yields TRUE), but this is not meant to apply recursively - (thus ROW(NULL, ROW(NULL,NULL)) IS NULL yields FALSE). - The core executor got this right, but certain planner optimizations - treated the test as recursive (thus producing TRUE in both cases), - and contrib/postgres_fdw could produce remote queries - that misbehaved similarly. - - - - - - Make the inet and cidr data types properly reject - IPv6 addresses with too many colon-separated fields (Tom Lane) - - - - - - Prevent crash in close_ps() - (the point ## lseg operator) - for NaN input coordinates (Tom Lane) - - - - Make it return NULL instead of crashing. - - - - - - Fix several one-byte buffer over-reads in to_number() - (Peter Eisentraut) - - - - In several cases the to_number() function would read one - more character than it should from the input string. There is a - small chance of a crash, if the input happens to be adjacent to the - end of memory. - - - - - - Avoid unsafe intermediate state during expensive paths - through heap_update() (Masahiko Sawada, Andres Freund) - - - - Previously, these cases locked the target tuple (by setting its XMAX) - but did not WAL-log that action, thus risking data integrity problems - if the page were spilled to disk and then a database crash occurred - before the tuple update could be completed. - - - - - - Avoid consuming a transaction ID during VACUUM - (Alexander Korotkov) - - - - Some cases in VACUUM unnecessarily caused an XID to be - assigned to the current transaction. Normally this is negligible, - but if one is up against the XID wraparound limit, consuming more - XIDs during anti-wraparound vacuums is a very bad thing. - - - - - - Avoid canceling hot-standby queries during VACUUM FREEZE - (Simon Riggs, Álvaro Herrera) - - - - VACUUM FREEZE on an otherwise-idle master server could - result in unnecessary cancellations of queries on its standby - servers. - - - - - - When a manual ANALYZE specifies a column list, don't - reset the table's changes_since_analyze counter - (Tom Lane) - - - - If we're only analyzing some columns, we should not prevent routine - auto-analyze from happening for the other columns. - - - - - - Fix ANALYZE's overestimation of n_distinct - for a unique or nearly-unique column with many null entries (Tom - Lane) - - - - The nulls could get counted as though they were themselves distinct - values, leading to serious planner misestimates in some types of - queries. - - - - - - Prevent autovacuum from starting multiple workers for the same shared - catalog (Álvaro Herrera) - - - - Normally this isn't much of a problem because the vacuum doesn't take - long anyway; but in the case of a severely bloated catalog, it could - result in all but one worker uselessly waiting instead of doing - useful work on other tables. - - - - - - Fix contrib/btree_gin to handle the smallest - possible bigint value correctly (Peter Eisentraut) - - - - - - Teach libpq to correctly decode server version from future servers - (Peter Eisentraut) - - - - It's planned to switch to two-part instead of three-part server - version numbers for releases after 9.6. Make sure - that PQserverVersion() returns the correct value for - such cases. - - - - - - Fix ecpg's code for unsigned long long - array elements (Michael Meskes) - - - - - - Make pg_basebackup accept -Z 0 as - specifying no compression (Fujii Masao) - - - - - - - Revert to the old heuristic timeout for pg_ctl start -w - (Tom Lane) - - - - The new method adopted as of release 9.1.20 does not work - when silent_mode is enabled, so go back to the old way. - - - - - - Fix makefiles' rule for building AIX shared libraries to be safe for - parallel make (Noah Misch) - - - - - - Fix TAP tests and MSVC scripts to work when build directory's path - name contains spaces (Michael Paquier, Kyotaro Horiguchi) - - - - - - Make regression tests safe for Danish and Welsh locales (Jeff Janes, - Tom Lane) - - - - Change some test data that triggered the unusual sorting rules of - these locales. - - - - - - Update our copy of the timezone code to match - IANA's tzcode release 2016c (Tom Lane) - - - - This is needed to cope with anticipated future changes in the time - zone data files. It also fixes some corner-case bugs in coping with - unusual time zones. - - - - - - Update time zone data files to tzdata release 2016f - for DST law changes in Kemerovo and Novosibirsk, plus historical - corrections for Azerbaijan, Belarus, and Morocco. - - - - - - - - - - Release 9.1.22 - - - Release date: - 2016-05-12 - - - - This release contains a variety of fixes from 9.1.21. - For information about new features in the 9.1 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.1.X release series in September 2016. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.1.22 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Clear the OpenSSL error queue before OpenSSL calls, rather than - assuming it's clear already; and make sure we leave it clear - afterwards (Peter Geoghegan, Dave Vitek, Peter Eisentraut) - - - - This change prevents problems when there are multiple connections - using OpenSSL within a single process and not all the code involved - follows the same rules for when to clear the error queue. - Failures have been reported specifically when a client application - uses SSL connections in libpq concurrently with - SSL connections using the PHP, Python, or Ruby wrappers for OpenSSL. - It's possible for similar problems to arise within the server as well, - if an extension module establishes an outgoing SSL connection. - - - - - - Fix failed to build any N-way joins - planner error with a full join enclosed in the right-hand side of a - left join (Tom Lane) - - - - - - Fix possible misbehavior of TH, th, - and Y,YYY format codes in to_timestamp() - (Tom Lane) - - - - These could advance off the end of the input string, causing subsequent - format codes to read garbage. - - - - - - Fix dumping of rules and views in which the array - argument of a value operator - ANY (array) construct is a sub-SELECT - (Tom Lane) - - - - - - Make pg_regress use a startup timeout from the - PGCTLTIMEOUT environment variable, if that's set (Tom Lane) - - - - This is for consistency with a behavior recently added - to pg_ctl; it eases automated testing on slow machines. - - - - - - Fix pg_upgrade to correctly restore extension - membership for operator families containing only one operator class - (Tom Lane) - - - - In such a case, the operator family was restored into the new database, - but it was no longer marked as part of the extension. This had no - immediate ill effects, but would cause later pg_dump - runs to emit output that would cause (harmless) errors on restore. - - - - - - Rename internal function strtoi() - to strtoint() to avoid conflict with a NetBSD library - function (Thomas Munro) - - - - - - Fix reporting of errors from bind() - and listen() system calls on Windows (Tom Lane) - - - - - - Reduce verbosity of compiler output when building with Microsoft Visual - Studio (Christian Ullrich) - - - - - - Avoid possibly-unsafe use of Windows' FormatMessage() - function (Christian Ullrich) - - - - Use the FORMAT_MESSAGE_IGNORE_INSERTS flag where - appropriate. No live bug is known to exist here, but it seems like a - good idea to be careful. - - - - - - Update time zone data files to tzdata release 2016d - for DST law changes in Russia and Venezuela. There are new zone - names Europe/Kirov and Asia/Tomsk to reflect - the fact that these regions now have different time zone histories from - adjacent regions. - - - - - - - - - - Release 9.1.21 - - - Release date: - 2016-03-31 - - - - This release contains a variety of fixes from 9.1.20. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.21 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix incorrect handling of NULL index entries in - indexed ROW() comparisons (Tom Lane) - - - - An index search using a row comparison such as ROW(a, b) > - ROW('x', 'y') would stop upon reaching a NULL entry in - the b column, ignoring the fact that there might be - non-NULL b values associated with later values - of a. - - - - - - Avoid unlikely data-loss scenarios due to renaming files without - adequate fsync() calls before and after (Michael Paquier, - Tomas Vondra, Andres Freund) - - - - - - Correctly handle cases where pg_subtrans is close to XID - wraparound during server startup (Jeff Janes) - - - - - - Fix corner-case crash due to trying to free localeconv() - output strings more than once (Tom Lane) - - - - - - Fix parsing of affix files for ispell dictionaries - (Tom Lane) - - - - The code could go wrong if the affix file contained any characters - whose byte length changes during case-folding, for - example I in Turkish UTF8 locales. - - - - - - Avoid use of sscanf() to parse ispell - dictionary files (Artur Zakirov) - - - - This dodges a portability problem on FreeBSD-derived platforms - (including macOS). - - - - - - Avoid a crash on old Windows versions (before 7SP1/2008R2SP1) with an - AVX2-capable CPU and a Postgres build done with Visual Studio 2013 - (Christian Ullrich) - - - - This is a workaround for a bug in Visual Studio 2013's runtime - library, which Microsoft have stated they will not fix in that - version. - - - - - - Fix psql's tab completion logic to handle multibyte - characters properly (Kyotaro Horiguchi, Robert Haas) - - - - - - Fix psql's tab completion for - SECURITY LABEL (Tom Lane) - - - - Pressing TAB after SECURITY LABEL might cause a crash - or offering of inappropriate keywords. - - - - - - Make pg_ctl accept a wait timeout from the - PGCTLTIMEOUT environment variable, if none is specified on - the command line (Noah Misch) - - - - This eases testing of slower buildfarm members by allowing them - to globally specify a longer-than-normal timeout for postmaster - startup and shutdown. - - - - - - Fix incorrect test for Windows service status - in pg_ctl (Manuel Mathar) - - - - The previous set of minor releases attempted to - fix pg_ctl to properly determine whether to send log - messages to Window's Event Log, but got the test backwards. - - - - - - Fix pgbench to correctly handle the combination - of -C and -M prepared options (Tom Lane) - - - - - - In PL/Perl, properly translate empty Postgres arrays into empty Perl - arrays (Alex Hunsaker) - - - - - - Make PL/Python cope with function names that aren't valid Python - identifiers (Jim Nasby) - - - - - - Fix multiple mistakes in the statistics returned - by contrib/pgstattuple's pgstatindex() - function (Tom Lane) - - - - - - Remove dependency on psed in MSVC builds, since it's no - longer provided by core Perl (Michael Paquier, Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2016c - for DST law changes in Azerbaijan, Chile, Haiti, Palestine, and Russia - (Altai, Astrakhan, Kirov, Sakhalin, Ulyanovsk regions), plus - historical corrections for Lithuania, Moldova, and Russia - (Kaliningrad, Samara, Volgograd). - - - - - - - - - - Release 9.1.20 - - - Release date: - 2016-02-11 - - - - This release contains a variety of fixes from 9.1.19. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.20 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix infinite loops and buffer-overrun problems in regular expressions - (Tom Lane) - - - - Very large character ranges in bracket expressions could cause - infinite loops in some cases, and memory overwrites in other cases. - (CVE-2016-0773) - - - - - - Perform an immediate shutdown if the postmaster.pid file - is removed (Tom Lane) - - - - The postmaster now checks every minute or so - that postmaster.pid is still there and still contains its - own PID. If not, it performs an immediate shutdown, as though it had - received SIGQUIT. The main motivation for this change - is to ensure that failed buildfarm runs will get cleaned up without - manual intervention; but it also serves to limit the bad effects if a - DBA forcibly removes postmaster.pid and then starts a new - postmaster. - - - - - - In SERIALIZABLE transaction isolation mode, serialization - anomalies could be missed due to race conditions during insertions - (Kevin Grittner, Thomas Munro) - - - - - - Fix failure to emit appropriate WAL records when doing ALTER - TABLE ... SET TABLESPACE for unlogged relations (Michael Paquier, - Andres Freund) - - - - Even though the relation's data is unlogged, the move must be logged or - the relation will be inaccessible after a standby is promoted to master. - - - - - - Fix possible misinitialization of unlogged relations at the end of - crash recovery (Andres Freund, Michael Paquier) - - - - - - Fix ALTER COLUMN TYPE to reconstruct inherited check - constraints properly (Tom Lane) - - - - - - Fix REASSIGN OWNED to change ownership of composite types - properly (Álvaro Herrera) - - - - - - Fix REASSIGN OWNED and ALTER OWNER to correctly - update granted-permissions lists when changing owners of data types, - foreign data wrappers, or foreign servers (Bruce Momjian, - Álvaro Herrera) - - - - - - Fix REASSIGN OWNED to ignore foreign user mappings, - rather than fail (Álvaro Herrera) - - - - - - Add more defenses against bad planner cost estimates for GIN index - scans when the index's internal statistics are very out-of-date - (Tom Lane) - - - - - - Make planner cope with hypothetical GIN indexes suggested by an index - advisor plug-in (Julien Rouhaud) - - - - - - Fix dumping of whole-row Vars in ROW() - and VALUES() lists (Tom Lane) - - - - - - Fix possible internal overflow in numeric division - (Dean Rasheed) - - - - - - Fix enforcement of restrictions inside parentheses within regular - expression lookahead constraints (Tom Lane) - - - - Lookahead constraints aren't allowed to contain backrefs, and - parentheses within them are always considered non-capturing, according - to the manual. However, the code failed to handle these cases properly - inside a parenthesized subexpression, and would give unexpected - results. - - - - - - Conversion of regular expressions to indexscan bounds could produce - incorrect bounds from regexps containing lookahead constraints - (Tom Lane) - - - - - - Fix regular-expression compiler to handle loops of constraint arcs - (Tom Lane) - - - - The code added for CVE-2007-4772 was both incomplete, in that it didn't - handle loops involving more than one state, and incorrect, in that it - could cause assertion failures (though there seem to be no bad - consequences of that in a non-assert build). Multi-state loops would - cause the compiler to run until the query was canceled or it reached - the too-many-states error condition. - - - - - - Improve memory-usage accounting in regular-expression compiler - (Tom Lane) - - - - This causes the code to emit regular expression is too - complex errors in some cases that previously used unreasonable - amounts of time and memory. - - - - - - Improve performance of regular-expression compiler (Tom Lane) - - - - - - Make %h and %r escapes - in log_line_prefix work for messages emitted due - to log_connections (Tom Lane) - - - - Previously, %h/%r started to work just after a - new session had emitted the connection received log message; - now they work for that message too. - - - - - - On Windows, ensure the shared-memory mapping handle gets closed in - child processes that don't need it (Tom Lane, Amit Kapila) - - - - This oversight resulted in failure to recover from crashes - whenever logging_collector is turned on. - - - - - - Fix possible failure to detect socket EOF in non-blocking mode on - Windows (Tom Lane) - - - - It's not entirely clear whether this problem can happen in pre-9.5 - branches, but if it did, the symptom would be that a walsender process - would wait indefinitely rather than noticing a loss of connection. - - - - - - Avoid leaking a token handle during SSPI authentication - (Christian Ullrich) - - - - - - In psql, ensure that libreadline's idea - of the screen size is updated when the terminal window size changes - (Merlin Moncure) - - - - Previously, libreadline did not notice if the window - was resized during query output, leading to strange behavior during - later input of multiline queries. - - - - - - Fix psql's \det command to interpret its - pattern argument the same way as other \d commands with - potentially schema-qualified patterns do (Reece Hart) - - - - - - Avoid possible crash in psql's \c command - when previous connection was via Unix socket and command specifies a - new hostname and same username (Tom Lane) - - - - - - In pg_ctl start -w, test child process status directly - rather than relying on heuristics (Tom Lane, Michael Paquier) - - - - Previously, pg_ctl relied on an assumption that the new - postmaster would always create postmaster.pid within five - seconds. But that can fail on heavily-loaded systems, - causing pg_ctl to report incorrectly that the - postmaster failed to start. - - - - Except on Windows, this change also means that a pg_ctl start - -w done immediately after another such command will now reliably - fail, whereas previously it would report success if done within two - seconds of the first command. - - - - - - In pg_ctl start -w, don't attempt to use a wildcard listen - address to connect to the postmaster (Kondo Yuta) - - - - On Windows, pg_ctl would fail to detect postmaster - startup if listen_addresses is set to 0.0.0.0 - or ::, because it would try to use that value verbatim as - the address to connect to, which doesn't work. Instead assume - that 127.0.0.1 or ::1, respectively, is the - right thing to use. - - - - - - In pg_ctl on Windows, check service status to decide - where to send output, rather than checking if standard output is a - terminal (Michael Paquier) - - - - - - In pg_dump and pg_basebackup, adopt - the GNU convention for handling tar-archive members exceeding 8GB - (Tom Lane) - - - - The POSIX standard for tar file format does not allow - archive member files to exceed 8GB, but most modern implementations - of tar support an extension that fixes that. Adopt - this extension so that pg_dump with no - longer fails on tables with more than 8GB of data, and so - that pg_basebackup can handle files larger than 8GB. - In addition, fix some portability issues that could cause failures for - members between 4GB and 8GB on some platforms. Potentially these - problems could cause unrecoverable data loss due to unreadable backup - files. - - - - - - Fix assorted corner-case bugs in pg_dump's processing - of extension member objects (Tom Lane) - - - - - - Make pg_dump mark a view's triggers as needing to be - processed after its rule, to prevent possible failure during - parallel pg_restore (Tom Lane) - - - - - - Ensure that relation option values are properly quoted - in pg_dump (Kouhei Sutou, Tom Lane) - - - - A reloption value that isn't a simple identifier or number could lead - to dump/reload failures due to syntax errors in CREATE statements - issued by pg_dump. This is not an issue with any - reloption currently supported by core PostgreSQL, but - extensions could allow reloptions that cause the problem. - - - - - - Fix pg_upgrade's file-copying code to handle errors - properly on Windows (Bruce Momjian) - - - - - - Install guards in pgbench against corner-case overflow - conditions during evaluation of script-specified division or modulo - operators (Fabien Coelho, Michael Paquier) - - - - - - Prevent certain PL/Java parameters from being set by - non-superusers (Noah Misch) - - - - This change mitigates a PL/Java security bug - (CVE-2016-0766), which was fixed in PL/Java by marking - these parameters as superuser-only. To fix the security hazard for - sites that update PostgreSQL more frequently - than PL/Java, make the core code aware of them also. - - - - - - Improve libpq's handling of out-of-memory situations - (Michael Paquier, Amit Kapila, Heikki Linnakangas) - - - - - - Fix order of arguments - in ecpg-generated typedef statements - (Michael Meskes) - - - - - - Use %g not %f format - in ecpg's PGTYPESnumeric_from_double() - (Tom Lane) - - - - - - Fix ecpg-supplied header files to not contain comments - continued from a preprocessor directive line onto the next line - (Michael Meskes) - - - - Such a comment is rejected by ecpg. It's not yet clear - whether ecpg itself should be changed. - - - - - - Ensure that contrib/pgcrypto's crypt() - function can be interrupted by query cancel (Andreas Karlsson) - - - - - - Accept flex versions later than 2.5.x - (Tom Lane, Michael Paquier) - - - - Now that flex 2.6.0 has been released, the version checks in our build - scripts needed to be adjusted. - - - - - - Install our missing script where PGXS builds can find it - (Jim Nasby) - - - - This allows sane behavior in a PGXS build done on a machine where build - tools such as bison are missing. - - - - - - Ensure that dynloader.h is included in the installed - header files in MSVC builds (Bruce Momjian, Michael Paquier) - - - - - - Add variant regression test expected-output file to match behavior of - current libxml2 (Tom Lane) - - - - The fix for libxml2's CVE-2015-7499 causes it not to - output error context reports in some cases where it used to do so. - This seems to be a bug, but we'll probably have to live with it for - some time, so work around it. - - - - - - Update time zone data files to tzdata release 2016a for - DST law changes in Cayman Islands, Metlakatla, and Trans-Baikal - Territory (Zabaykalsky Krai), plus historical corrections for Pakistan. - - - - - - - - - - Release 9.1.19 - - - Release date: - 2015-10-08 - - - - This release contains a variety of fixes from 9.1.18. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.19 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix contrib/pgcrypto to detect and report - too-short crypt() salts (Josh Kupershmidt) - - - - Certain invalid salt arguments crashed the server or disclosed a few - bytes of server memory. We have not ruled out the viability of - attacks that arrange for presence of confidential information in the - disclosed bytes, but they seem unlikely. (CVE-2015-5288) - - - - - - Fix subtransaction cleanup after a portal (cursor) belonging to an - outer subtransaction fails (Tom Lane, Michael Paquier) - - - - A function executed in an outer-subtransaction cursor could cause an - assertion failure or crash by referencing a relation created within an - inner subtransaction. - - - - - - Fix insertion of relations into the relation cache init file - (Tom Lane) - - - - An oversight in a patch in the most recent minor releases - caused pg_trigger_tgrelid_tgname_index to be omitted - from the init file. Subsequent sessions detected this, then deemed the - init file to be broken and silently ignored it, resulting in a - significant degradation in session startup time. In addition to fixing - the bug, install some guards so that any similar future mistake will be - more obvious. - - - - - - Avoid O(N^2) behavior when inserting many tuples into a SPI query - result (Neil Conway) - - - - - - Improve LISTEN startup time when there are many unread - notifications (Matt Newell) - - - - - - Back-patch 9.3-era addition of per-resource-owner lock caches - (Jeff Janes) - - - - This substantially improves performance when pg_dump - tries to dump a large number of tables. - - - - - - Disable SSL renegotiation by default (Michael Paquier, Andres Freund) - - - - While use of SSL renegotiation is a good idea in theory, we have seen - too many bugs in practice, both in the underlying OpenSSL library and - in our usage of it. Renegotiation will be removed entirely in 9.5 and - later. In the older branches, just change the default value - of ssl_renegotiation_limit to zero (disabled). - - - - - - Lower the minimum values of the *_freeze_max_age parameters - (Andres Freund) - - - - This is mainly to make tests of related behavior less time-consuming, - but it may also be of value for installations with limited disk space. - - - - - - Limit the maximum value of wal_buffers to 2GB to avoid - server crashes (Josh Berkus) - - - - - - Fix rare internal overflow in multiplication of numeric values - (Dean Rasheed) - - - - - - Guard against hard-to-reach stack overflows involving record types, - range types, json, jsonb, tsquery, - ltxtquery and query_int (Noah Misch) - - - - - - Fix handling of DOW and DOY in datetime input - (Greg Stark) - - - - These tokens aren't meant to be used in datetime values, but previously - they resulted in opaque internal error messages rather - than invalid input syntax. - - - - - - Add more query-cancel checks to regular expression matching (Tom Lane) - - - - - - Add recursion depth protections to regular expression, SIMILAR - TO, and LIKE matching (Tom Lane) - - - - Suitable search patterns and a low stack depth limit could lead to - stack-overrun crashes. - - - - - - Fix potential infinite loop in regular expression execution (Tom Lane) - - - - A search pattern that can apparently match a zero-length string, but - actually doesn't match because of a back reference, could lead to an - infinite loop. - - - - - - Fix low-memory failures in regular expression compilation - (Andreas Seltenreich) - - - - - - Fix low-probability memory leak during regular expression execution - (Tom Lane) - - - - - - Fix rare low-memory failure in lock cleanup during transaction abort - (Tom Lane) - - - - - - Fix unexpected out-of-memory situation during sort errors - when using tuplestores with small work_mem settings (Tom - Lane) - - - - - - Fix very-low-probability stack overrun in qsort (Tom Lane) - - - - - - Fix invalid memory alloc request size failure in hash joins - with large work_mem settings (Tomas Vondra, Tom Lane) - - - - - - Fix assorted planner bugs (Tom Lane) - - - - These mistakes could lead to incorrect query plans that would give wrong - answers, or to assertion failures in assert-enabled builds, or to odd - planner errors such as could not devise a query plan for the - given query, could not find pathkey item to - sort, plan should not reference subplan's variable, - or failed to assign all NestLoopParams to plan nodes. - Thanks are due to Andreas Seltenreich and Piotr Stefaniak for fuzz - testing that exposed these problems. - - - - - - - - Use fuzzy path cost tiebreaking rule in all supported branches (Tom Lane) - - - - This change is meant to avoid platform-specific behavior when - alternative plan choices have effectively-identical estimated costs. - - - - - - Ensure standby promotion trigger files are removed at postmaster - startup (Michael Paquier, Fujii Masao) - - - - This prevents unwanted promotion from occurring if these files appear - in a database backup that is used to initialize a new standby server. - - - - - - During postmaster shutdown, ensure that per-socket lock files are - removed and listen sockets are closed before we remove - the postmaster.pid file (Tom Lane) - - - - This avoids race-condition failures if an external script attempts to - start a new postmaster as soon as pg_ctl stop returns. - - - - - - Fix postmaster's handling of a startup-process crash during crash - recovery (Tom Lane) - - - - If, during a crash recovery cycle, the startup process crashes without - having restored database consistency, we'd try to launch a new startup - process, which typically would just crash again, leading to an infinite - loop. - - - - - - Do not print a WARNING when an autovacuum worker is already - gone when we attempt to signal it, and reduce log verbosity for such - signals (Tom Lane) - - - - - - Prevent autovacuum launcher from sleeping unduly long if the server - clock is moved backwards a large amount (Álvaro Herrera) - - - - - - Ensure that cleanup of a GIN index's pending-insertions list is - interruptable by cancel requests (Jeff Janes) - - - - - - Allow all-zeroes pages in GIN indexes to be reused (Heikki Linnakangas) - - - - Such a page might be left behind after a crash. - - - - - - Fix off-by-one error that led to otherwise-harmless warnings - about apparent wraparound in subtrans/multixact truncation - (Thomas Munro) - - - - - - Fix misreporting of CONTINUE and MOVE statement - types in PL/pgSQL's error context messages - (Pavel Stehule, Tom Lane) - - - - - - Fix PL/Perl to handle non-ASCII error - message texts correctly (Alex Hunsaker) - - - - - - Fix PL/Python crash when returning the string - representation of a record result (Tom Lane) - - - - - - Fix some places in PL/Tcl that neglected to check for - failure of malloc() calls (Michael Paquier, Álvaro - Herrera) - - - - - - In contrib/isn, fix output of ISBN-13 numbers that begin - with 979 (Fabien Coelho) - - - - EANs beginning with 979 (but not 9790) are considered ISBNs, but they - must be printed in the new 13-digit format, not the 10-digit format. - - - - - - Improve libpq's handling of out-of-memory conditions - (Michael Paquier, Heikki Linnakangas) - - - - - - Fix memory leaks and missing out-of-memory checks - in ecpg (Michael Paquier) - - - - - - Fix psql's code for locale-aware formatting of numeric - output (Tom Lane) - - - - The formatting code invoked by \pset numericlocale on - did the wrong thing for some uncommon cases such as numbers with an - exponent but no decimal point. It could also mangle already-localized - output from the money data type. - - - - - - Prevent crash in psql's \c command when - there is no current connection (Noah Misch) - - - - - - Fix selection of default zlib compression level - in pg_dump's directory output format (Andrew Dunstan) - - - - - - Ensure that temporary files created during a pg_dump - run with tar-format output are not world-readable (Michael - Paquier) - - - - - - Fix pg_dump and pg_upgrade to support - cases where the postgres or template1 database - is in a non-default tablespace (Marti Raudsepp, Bruce Momjian) - - - - - - Fix pg_dump to handle object privileges sanely when - dumping from a server too old to have a particular privilege type - (Tom Lane) - - - - When dumping functions or procedural languages from pre-7.3 - servers, pg_dump would - produce GRANT/REVOKE commands that revoked the - owner's grantable privileges and instead granted all privileges - to PUBLIC. Since the privileges involved are - just USAGE and EXECUTE, this isn't a security - problem, but it's certainly a surprising representation of the older - systems' behavior. Fix it to leave the default privilege state alone - in these cases. - - - - - - Fix pg_dump to dump shell types (Tom Lane) - - - - Shell types (that is, not-yet-fully-defined types) aren't useful for - much, but nonetheless pg_dump should dump them. - - - - - - Fix assorted minor memory leaks in pg_dump and other - client-side programs (Michael Paquier) - - - - - - Fix spinlock assembly code for PPC hardware to be compatible - with AIX's native assembler (Tom Lane) - - - - Building with gcc didn't work if gcc - had been configured to use the native assembler, which is becoming more - common. - - - - - - On AIX, test the -qlonglong compiler option - rather than just assuming it's safe to use (Noah Misch) - - - - - - On AIX, use -Wl,-brtllib link option to allow - symbols to be resolved at runtime (Noah Misch) - - - - Perl relies on this ability in 5.8.0 and later. - - - - - - Avoid use of inline functions when compiling with - 32-bit xlc, due to compiler bugs (Noah Misch) - - - - - - Use librt for sched_yield() when necessary, - which it is on some Solaris versions (Oskari Saarenmaa) - - - - - - Fix Windows install.bat script to handle target directory - names that contain spaces (Heikki Linnakangas) - - - - - - Make the numeric form of the PostgreSQL version number - (e.g., 90405) readily available to extension Makefiles, - as a variable named VERSION_NUM (Michael Paquier) - - - - - - Update time zone data files to tzdata release 2015g for - DST law changes in Cayman Islands, Fiji, Moldova, Morocco, Norfolk - Island, North Korea, Turkey, and Uruguay. There is a new zone name - America/Fort_Nelson for the Canadian Northern Rockies. - - - - - - - - - - Release 9.1.18 - - - Release date: - 2015-06-12 - - - - This release contains a small number of fixes from 9.1.17. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.18 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Fix rare failure to invalidate relation cache init file (Tom Lane) - - - - With just the wrong timing of concurrent activity, a VACUUM - FULL on a system catalog might fail to update the init file - that's used to avoid cache-loading work for new sessions. This would - result in later sessions being unable to access that catalog at all. - This is a very ancient bug, but it's so hard to trigger that no - reproducible case had been seen until recently. - - - - - - Avoid deadlock between incoming sessions and CREATE/DROP - DATABASE (Tom Lane) - - - - A new session starting in a database that is the target of - a DROP DATABASE command, or is the template for - a CREATE DATABASE command, could cause the command to wait - for five seconds and then fail, even if the new session would have - exited before that. - - - - - - - - - - Release 9.1.17 - - - Release date: - 2015-06-04 - - - - This release contains a small number of fixes from 9.1.16. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.17 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.16, - see . - - - - - - Changes - - - - - - Avoid failures while fsync'ing data directory during - crash restart (Abhijit Menon-Sen, Tom Lane) - - - - In the previous minor releases we added a patch to fsync - everything in the data directory after a crash. Unfortunately its - response to any error condition was to fail, thereby preventing the - server from starting up, even when the problem was quite harmless. - An example is that an unwritable file in the data directory would - prevent restart on some platforms; but it is common to make SSL - certificate files unwritable by the server. Revise this behavior so - that permissions failures are ignored altogether, and other types of - failures are logged but do not prevent continuing. - - - - - - Remove configure's check prohibiting linking to a - threaded libpython - on OpenBSD (Tom Lane) - - - - The failure this restriction was meant to prevent seems to not be a - problem anymore on current OpenBSD - versions. - - - - - - Allow libpq to use TLS protocol versions beyond v1 - (Noah Misch) - - - - For a long time, libpq was coded so that the only SSL - protocol it would allow was TLS v1. Now that newer TLS versions are - becoming popular, allow it to negotiate the highest commonly-supported - TLS version with the server. (PostgreSQL servers were - already capable of such negotiation, so no change is needed on the - server side.) This is a back-patch of a change already released in - 9.4.0. - - - - - - - - - - Release 9.1.16 - - - Release date: - 2015-05-22 - - - - This release contains a variety of fixes from 9.1.15. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.16 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you use contrib/citext's - regexp_matches() functions, see the changelog entry below - about that. - - - - Also, if you are upgrading from a version earlier than 9.1.14, - see . - - - - - - Changes - - - - - - Avoid possible crash when client disconnects just before the - authentication timeout expires (Benkocs Norbert Attila) - - - - If the timeout interrupt fired partway through the session shutdown - sequence, SSL-related state would be freed twice, typically causing a - crash and hence denial of service to other sessions. Experimentation - shows that an unauthenticated remote attacker could trigger the bug - somewhat consistently, hence treat as security issue. - (CVE-2015-3165) - - - - - - Improve detection of system-call failures (Noah Misch) - - - - Our replacement implementation of snprintf() failed to - check for errors reported by the underlying system library calls; - the main case that might be missed is out-of-memory situations. - In the worst case this might lead to information exposure, due to our - code assuming that a buffer had been overwritten when it hadn't been. - Also, there were a few places in which security-relevant calls of other - system library functions did not check for failure. - - - - It remains possible that some calls of the *printf() - family of functions are vulnerable to information disclosure if an - out-of-memory error occurs at just the wrong time. We judge the risk - to not be large, but will continue analysis in this area. - (CVE-2015-3166) - - - - - - In contrib/pgcrypto, uniformly report decryption failures - as Wrong key or corrupt data (Noah Misch) - - - - Previously, some cases of decryption with an incorrect key could report - other error message texts. It has been shown that such variance in - error reports can aid attackers in recovering keys from other systems. - While it's unknown whether pgcrypto's specific behaviors - are likewise exploitable, it seems better to avoid the risk by using a - one-size-fits-all message. - (CVE-2015-3167) - - - - - - Fix incorrect declaration of contrib/citext's - regexp_matches() functions (Tom Lane) - - - - These functions should return setof text[], like the core - functions they are wrappers for; but they were incorrectly declared as - returning just text[]. This mistake had two results: first, - if there was no match you got a scalar null result, whereas what you - should get is an empty set (zero rows). Second, the g flag - was effectively ignored, since you would get only one result array even - if there were multiple matches. - - - - While the latter behavior is clearly a bug, there might be applications - depending on the former behavior; therefore the function declarations - will not be changed by default until PostgreSQL 9.5. - In pre-9.5 branches, the old behavior exists in version 1.0 of - the citext extension, while we have provided corrected - declarations in version 1.1 (which is not installed by - default). To adopt the fix in pre-9.5 branches, execute - ALTER EXTENSION citext UPDATE TO '1.1' in each database in - which citext is installed. (You can also update - back to 1.0 if you need to undo that.) Be aware that either update - direction will require dropping and recreating any views or rules that - use citext's regexp_matches() functions. - - - - - - Fix incorrect checking of deferred exclusion constraints after a HOT - update (Tom Lane) - - - - If a new row that potentially violates a deferred exclusion constraint - is HOT-updated (that is, no indexed columns change and the row can be - stored back onto the same table page) later in the same transaction, - the exclusion constraint would be reported as violated when the check - finally occurred, even if the row(s) the new row originally conflicted - with had been deleted. - - - - - - Prevent improper reordering of antijoins (NOT EXISTS joins) versus - other outer joins (Tom Lane) - - - - This oversight in the planner has been observed to cause could - not find RelOptInfo for given relids errors, but it seems possible - that sometimes an incorrect query plan might get past that consistency - check and result in silently-wrong query output. - - - - - - Fix incorrect matching of subexpressions in outer-join plan nodes - (Tom Lane) - - - - Previously, if textually identical non-strict subexpressions were used - both above and below an outer join, the planner might try to re-use - the value computed below the join, which would be incorrect because the - executor would force the value to NULL in case of an unmatched outer row. - - - - - - Fix GEQO planner to cope with failure of its join order heuristic - (Tom Lane) - - - - This oversight has been seen to lead to failed to join all - relations together errors in queries involving LATERAL, - and that might happen in other cases as well. - - - - - - Fix possible deadlock at startup - when max_prepared_transactions is too small - (Heikki Linnakangas) - - - - - - Don't archive useless preallocated WAL files after a timeline switch - (Heikki Linnakangas) - - - - - - Avoid cannot GetMultiXactIdMembers() during recovery error - (Álvaro Herrera) - - - - - - Recursively fsync() the data directory after a crash - (Abhijit Menon-Sen, Robert Haas) - - - - This ensures consistency if another crash occurs shortly later. (The - second crash would have to be a system-level crash, not just a database - crash, for there to be a problem.) - - - - - - Fix autovacuum launcher's possible failure to shut down, if an error - occurs after it receives SIGTERM (Álvaro Herrera) - - - - - - Cope with unexpected signals in LockBufferForCleanup() - (Andres Freund) - - - - This oversight could result in spurious errors about multiple - backends attempting to wait for pincount 1. - - - - - - Avoid waiting for WAL flush or synchronous replication during commit of - a transaction that was read-only so far as the user is concerned - (Andres Freund) - - - - Previously, a delay could occur at commit in transactions that had - written WAL due to HOT page pruning, leading to undesirable effects - such as sessions getting stuck at startup if all synchronous replicas - are down. Sessions have also been observed to get stuck in catchup - interrupt processing when using synchronous replication; this will fix - that problem as well. - - - - - - Fix crash when manipulating hash indexes on temporary tables - (Heikki Linnakangas) - - - - - - Fix possible failure during hash index bucket split, if other processes - are modifying the index concurrently (Tom Lane) - - - - - - Check for interrupts while analyzing index expressions (Jeff Janes) - - - - ANALYZE executes index expressions many times; if there are - slow functions in such an expression, it's desirable to be able to - cancel the ANALYZE before that loop finishes. - - - - - - Ensure tableoid of a foreign table is reported - correctly when a READ COMMITTED recheck occurs after - locking rows in SELECT FOR UPDATE, UPDATE, - or DELETE (Etsuro Fujita) - - - - - - Add the name of the target server to object description strings for - foreign-server user mappings (Álvaro Herrera) - - - - - - Recommend setting include_realm to 1 when using - Kerberos/GSSAPI/SSPI authentication (Stephen Frost) - - - - Without this, identically-named users from different realms cannot be - distinguished. For the moment this is only a documentation change, but - it will become the default setting in PostgreSQL 9.5. - - - - - - Remove code for matching IPv4 pg_hba.conf entries to - IPv4-in-IPv6 addresses (Tom Lane) - - - - This hack was added in 2003 in response to a report that some Linux - kernels of the time would report IPv4 connections as having - IPv4-in-IPv6 addresses. However, the logic was accidentally broken in - 9.0. The lack of any field complaints since then shows that it's not - needed anymore. Now we have reports that the broken code causes - crashes on some systems, so let's just remove it rather than fix it. - (Had we chosen to fix it, that would make for a subtle and potentially - security-sensitive change in the effective meaning of - IPv4 pg_hba.conf entries, which does not seem like a good - thing to do in minor releases.) - - - - - - Report WAL flush, not insert, position in IDENTIFY_SYSTEM - replication command (Heikki Linnakangas) - - - - This avoids a possible startup failure - in pg_receivexlog. - - - - - - While shutting down service on Windows, periodically send status - updates to the Service Control Manager to prevent it from killing the - service too soon; and ensure that pg_ctl will wait for - shutdown (Krystian Bigaj) - - - - - - Reduce risk of network deadlock when using libpq's - non-blocking mode (Heikki Linnakangas) - - - - When sending large volumes of data, it's important to drain the input - buffer every so often, in case the server has sent enough response data - to cause it to block on output. (A typical scenario is that the server - is sending a stream of NOTICE messages during COPY FROM - STDIN.) This worked properly in the normal blocking mode, but not - so much in non-blocking mode. We've modified libpq - to opportunistically drain input when it can, but a full defense - against this problem requires application cooperation: the application - should watch for socket read-ready as well as write-ready conditions, - and be sure to call PQconsumeInput() upon read-ready. - - - - - - Fix array handling in ecpg (Michael Meskes) - - - - - - Fix psql to sanely handle URIs and conninfo strings as - the first parameter to \connect - (David Fetter, Andrew Dunstan, Álvaro Herrera) - - - - This syntax has been accepted (but undocumented) for a long time, but - previously some parameters might be taken from the old connection - instead of the given string, which was agreed to be undesirable. - - - - - - Suppress incorrect complaints from psql on some - platforms that it failed to write ~/.psql_history at exit - (Tom Lane) - - - - This misbehavior was caused by a workaround for a bug in very old - (pre-2006) versions of libedit. We fixed it by - removing the workaround, which will cause a similar failure to appear - for anyone still using such versions of libedit. - Recommendation: upgrade that library, or use libreadline. - - - - - - Fix pg_dump's rule for deciding which casts are - system-provided casts that should not be dumped (Tom Lane) - - - - - - In pg_dump, fix failure to honor -Z - compression level option together with -Fd - (Michael Paquier) - - - - - - Make pg_dump consider foreign key relationships - between extension configuration tables while choosing dump order - (Gilles Darold, Michael Paquier, Stephen Frost) - - - - This oversight could result in producing dumps that fail to reload - because foreign key constraints are transiently violated. - - - - - - Fix dumping of views that are just VALUES(...) but have - column aliases (Tom Lane) - - - - - - In pg_upgrade, force timeline 1 in the new cluster - (Bruce Momjian) - - - - This change prevents upgrade failures caused by bogus complaints about - missing WAL history files. - - - - - - In pg_upgrade, check for improperly non-connectable - databases before proceeding - (Bruce Momjian) - - - - - - In pg_upgrade, quote directory paths - properly in the generated delete_old_cluster script - (Bruce Momjian) - - - - - - In pg_upgrade, preserve database-level freezing info - properly - (Bruce Momjian) - - - - This oversight could cause missing-clog-file errors for tables within - the postgres and template1 databases. - - - - - - Run pg_upgrade and pg_resetxlog with - restricted privileges on Windows, so that they don't fail when run by - an administrator (Muhammad Asif Naeem) - - - - - - Improve handling of readdir() failures when scanning - directories in initdb and pg_basebackup - (Marco Nenciarini) - - - - - - Fix slow sorting algorithm in contrib/intarray (Tom Lane) - - - - - - Fix compile failure on Sparc V8 machines (Rob Rowan) - - - - - - Update time zone data files to tzdata release 2015d - for DST law changes in Egypt, Mongolia, and Palestine, plus historical - changes in Canada and Chile. Also adopt revised zone abbreviations for - the America/Adak zone (HST/HDT not HAST/HADT). - - - - - - - - - - Release 9.1.15 - - - Release date: - 2015-02-05 - - - - This release contains a variety of fixes from 9.1.14. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.15 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.14, - see . - - - - - - Changes - - - - - - Fix buffer overruns in to_char() - (Bruce Momjian) - - - - When to_char() processes a numeric formatting template - calling for a large number of digits, PostgreSQL - would read past the end of a buffer. When processing a crafted - timestamp formatting template, PostgreSQL would write - past the end of a buffer. Either case could crash the server. - We have not ruled out the possibility of attacks that lead to - privilege escalation, though they seem unlikely. - (CVE-2015-0241) - - - - - - Fix buffer overrun in replacement *printf() functions - (Tom Lane) - - - - PostgreSQL includes a replacement implementation - of printf and related functions. This code will overrun - a stack buffer when formatting a floating point number (conversion - specifiers e, E, f, F, - g or G) with requested precision greater than - about 500. This will crash the server, and we have not ruled out the - possibility of attacks that lead to privilege escalation. - A database user can trigger such a buffer overrun through - the to_char() SQL function. While that is the only - affected core PostgreSQL functionality, extension - modules that use printf-family functions may be at risk as well. - - - - This issue primarily affects PostgreSQL on Windows. - PostgreSQL uses the system implementation of these - functions where adequate, which it is on other modern platforms. - (CVE-2015-0242) - - - - - - Fix buffer overruns in contrib/pgcrypto - (Marko Tiikkaja, Noah Misch) - - - - Errors in memory size tracking within the pgcrypto - module permitted stack buffer overruns and improper dependence on the - contents of uninitialized memory. The buffer overrun cases can - crash the server, and we have not ruled out the possibility of - attacks that lead to privilege escalation. - (CVE-2015-0243) - - - - - - Fix possible loss of frontend/backend protocol synchronization after - an error - (Heikki Linnakangas) - - - - If any error occurred while the server was in the middle of reading a - protocol message from the client, it could lose synchronization and - incorrectly try to interpret part of the message's data as a new - protocol message. An attacker able to submit crafted binary data - within a command parameter might succeed in injecting his own SQL - commands this way. Statement timeout and query cancellation are the - most likely sources of errors triggering this scenario. Particularly - vulnerable are applications that use a timeout and also submit - arbitrary user-crafted data as binary query parameters. Disabling - statement timeout will reduce, but not eliminate, the risk of - exploit. Our thanks to Emil Lenngren for reporting this issue. - (CVE-2015-0244) - - - - - - Fix information leak via constraint-violation error messages - (Stephen Frost) - - - - Some server error messages show the values of columns that violate - a constraint, such as a unique constraint. If the user does not have - SELECT privilege on all columns of the table, this could - mean exposing values that the user should not be able to see. Adjust - the code so that values are displayed only when they came from the SQL - command or could be selected by the user. - (CVE-2014-8161) - - - - - - Lock down regression testing's temporary installations on Windows - (Noah Misch) - - - - Use SSPI authentication to allow connections only from the OS user - who launched the test suite. This closes on Windows the same - vulnerability previously closed on other platforms, namely that other - users might be able to connect to the test postmaster. - (CVE-2014-0067) - - - - - - Avoid possible data corruption if ALTER DATABASE SET - TABLESPACE is used to move a database to a new tablespace and then - shortly later move it back to its original tablespace (Tom Lane) - - - - - - Avoid corrupting tables when ANALYZE inside a transaction - is rolled back (Andres Freund, Tom Lane, Michael Paquier) - - - - If the failing transaction had earlier removed the last index, rule, or - trigger from the table, the table would be left in a corrupted state - with the relevant pg_class flags not set though they - should be. - - - - - - Ensure that unlogged tables are copied correctly - during CREATE DATABASE or ALTER DATABASE SET - TABLESPACE (Pavan Deolasee, Andres Freund) - - - - - - Fix DROP's dependency searching to correctly handle the - case where a table column is recursively visited before its table - (Petr Jelinek, Tom Lane) - - - - This case is only known to arise when an extension creates both a - datatype and a table using that datatype. The faulty code might - refuse a DROP EXTENSION unless CASCADE is - specified, which should not be required. - - - - - - Fix use-of-already-freed-memory problem in EvalPlanQual processing - (Tom Lane) - - - - In READ COMMITTED mode, queries that lock or update - recently-updated rows could crash as a result of this bug. - - - - - - Fix planning of SELECT FOR UPDATE when using a partial - index on a child table (Kyotaro Horiguchi) - - - - In READ COMMITTED mode, SELECT FOR UPDATE must - also recheck the partial index's WHERE condition when - rechecking a recently-updated row to see if it still satisfies the - query's WHERE condition. This requirement was missed if the - index belonged to an inheritance child table, so that it was possible - to incorrectly return rows that no longer satisfy the query condition. - - - - - - Fix corner case wherein SELECT FOR UPDATE could return a row - twice, and possibly miss returning other rows (Tom Lane) - - - - In READ COMMITTED mode, a SELECT FOR UPDATE - that is scanning an inheritance tree could incorrectly return a row - from a prior child table instead of the one it should return from a - later child table. - - - - - - Reject duplicate column names in the referenced-columns list of - a FOREIGN KEY declaration (David Rowley) - - - - This restriction is per SQL standard. Previously we did not reject - the case explicitly, but later on the code would fail with - bizarre-looking errors. - - - - - - Fix bugs in raising a numeric value to a large integral power - (Tom Lane) - - - - The previous code could get a wrong answer, or consume excessive - amounts of time and memory before realizing that the answer must - overflow. - - - - - - In numeric_recv(), truncate away any fractional digits - that would be hidden according to the value's dscale field - (Tom Lane) - - - - A numeric value's display scale (dscale) should - never be less than the number of nonzero fractional digits; but - apparently there's at least one broken client application that - transmits binary numeric values in which that's true. - This leads to strange behavior since the extra digits are taken into - account by arithmetic operations even though they aren't printed. - The least risky fix seems to be to truncate away such hidden - digits on receipt, so that the value is indeed what it prints as. - - - - - - Reject out-of-range numeric timezone specifications (Tom Lane) - - - - Simple numeric timezone specifications exceeding +/- 168 hours (one - week) would be accepted, but could then cause null-pointer dereference - crashes in certain operations. There's no use-case for such large UTC - offsets, so reject them. - - - - - - Fix bugs in tsquery @> tsquery - operator (Heikki Linnakangas) - - - - Two different terms would be considered to match if they had the same - CRC. Also, if the second operand had more terms than the first, it - would be assumed not to be contained in the first; which is wrong - since it might contain duplicate terms. - - - - - - Improve ispell dictionary's defenses against bad affix files (Tom Lane) - - - - - - Allow more than 64K phrases in a thesaurus dictionary (David Boutin) - - - - The previous coding could crash on an oversize dictionary, so this was - deemed a back-patchable bug fix rather than a feature addition. - - - - - - Fix namespace handling in xpath() (Ali Akbar) - - - - Previously, the xml value resulting from - an xpath() call would not have namespace declarations if - the namespace declarations were attached to an ancestor element in the - input xml value, rather than to the specific element being - returned. Propagate the ancestral declaration so that the result is - correct when considered in isolation. - - - - - - Fix planner problems with nested append relations, such as inherited - tables within UNION ALL subqueries (Tom Lane) - - - - - - Fail cleanly when a GiST index tuple doesn't fit on a page, rather - than going into infinite recursion (Andrew Gierth) - - - - - - Exempt tables that have per-table cost_limit - and/or cost_delay settings from autovacuum's global cost - balancing rules (Álvaro Herrera) - - - - The previous behavior resulted in basically ignoring these per-table - settings, which was unintended. Now, a table having such settings - will be vacuumed using those settings, independently of what is going - on in other autovacuum workers. This may result in heavier total I/O - load than before, so such settings should be re-examined for sanity. - - - - - - Avoid wholesale autovacuuming when autovacuum is nominally off - (Tom Lane) - - - - Even when autovacuum is nominally off, we will still launch autovacuum - worker processes to vacuum tables that are at risk of XID wraparound. - However, such a worker process then proceeded to vacuum all tables in - the target database, if they met the usual thresholds for - autovacuuming. This is at best pretty unexpected; at worst it delays - response to the wraparound threat. Fix it so that if autovacuum is - turned off, workers only do anti-wraparound vacuums and - not any other work. - - - - - - During crash recovery, ensure that unlogged relations are rewritten as - empty and are synced to disk before recovery is considered complete - (Abhijit Menon-Sen, Andres Freund) - - - - This prevents scenarios in which unlogged relations might contain - garbage data following database crash recovery. - - - - - - Fix race condition between hot standby queries and replaying a - full-page image (Heikki Linnakangas) - - - - This mistake could result in transient errors in queries being - executed in hot standby. - - - - - - Fix several cases where recovery logic improperly ignored WAL records - for COMMIT/ABORT PREPARED (Heikki Linnakangas) - - - - The most notable oversight was - that recovery_target_xid could not be used to stop at - a two-phase commit. - - - - - - Avoid creating unnecessary .ready marker files for - timeline history files (Fujii Masao) - - - - - - Fix possible null pointer dereference when an empty prepared statement - is used and the log_statement setting is mod - or ddl (Fujii Masao) - - - - - - Change pgstat wait timeout warning message to be LOG level, - and rephrase it to be more understandable (Tom Lane) - - - - This message was originally thought to be essentially a can't-happen - case, but it occurs often enough on our slower buildfarm members to be - a nuisance. Reduce it to LOG level, and expend a bit more effort on - the wording: it now reads using stale statistics instead of - current ones because stats collector is not responding. - - - - - - Fix SPARC spinlock implementation to ensure correctness if the CPU is - being run in a non-TSO coherency mode, as some non-Solaris kernels do - (Andres Freund) - - - - - - Warn if macOS's setlocale() starts an unwanted extra - thread inside the postmaster (Noah Misch) - - - - - - Fix processing of repeated dbname parameters - in PQconnectdbParams() (Alex Shulgin) - - - - Unexpected behavior ensued if the first occurrence - of dbname contained a connection string or URI to be - expanded. - - - - - - Ensure that libpq reports a suitable error message on - unexpected socket EOF (Marko Tiikkaja, Tom Lane) - - - - Depending on kernel behavior, libpq might return an - empty error string rather than something useful when the server - unexpectedly closed the socket. - - - - - - Clear any old error message during PQreset() - (Heikki Linnakangas) - - - - If PQreset() is called repeatedly, and the connection - cannot be re-established, error messages from the failed connection - attempts kept accumulating in the PGconn's error - string. - - - - - - Properly handle out-of-memory conditions while parsing connection - options in libpq (Alex Shulgin, Heikki Linnakangas) - - - - - - Fix array overrun in ecpg's version - of ParseDateTime() (Michael Paquier) - - - - - - In initdb, give a clearer error message if a password - file is specified but is empty (Mats Erik Andersson) - - - - - - Fix psql's \s command to work nicely with - libedit, and add pager support (Stepan Rutz, Tom Lane) - - - - When using libedit rather than readline, \s printed the - command history in a fairly unreadable encoded format, and on recent - libedit versions might fail altogether. Fix that by printing the - history ourselves rather than having the library do it. A pleasant - side-effect is that the pager is used if appropriate. - - - - This patch also fixes a bug that caused newline encoding to be applied - inconsistently when saving the command history with libedit. - Multiline history entries written by older psql - versions will be read cleanly with this patch, but perhaps not - vice versa, depending on the exact libedit versions involved. - - - - - - Improve consistency of parsing of psql's special - variables (Tom Lane) - - - - Allow variant spellings of on and off (such - as 1/0) for ECHO_HIDDEN - and ON_ERROR_ROLLBACK. Report a warning for unrecognized - values for COMP_KEYWORD_CASE, ECHO, - ECHO_HIDDEN, HISTCONTROL, - ON_ERROR_ROLLBACK, and VERBOSITY. Recognize - all values for all these variables case-insensitively; previously - there was a mishmash of case-sensitive and case-insensitive behaviors. - - - - - - Fix psql's expanded-mode display to work - consistently when using border = 3 - and linestyle = ascii or unicode - (Stephen Frost) - - - - - - Improve performance of pg_dump when the database - contains many instances of multiple dependency paths between the same - two objects (Tom Lane) - - - - - - Fix possible deadlock during parallel restore of a schema-only dump - (Robert Haas, Tom Lane) - - - - - - Fix core dump in pg_dump --binary-upgrade on zero-column - composite type (Rushabh Lathia) - - - - - - Prevent WAL files created by pg_basebackup -x/-X from - being archived again when the standby is promoted (Andres Freund) - - - - - - Fix upgrade-from-unpackaged script for contrib/citext - (Tom Lane) - - - - - - Fix block number checking - in contrib/pageinspect's get_raw_page() - (Tom Lane) - - - - The incorrect checking logic could prevent access to some pages in - non-main relation forks. - - - - - - Fix contrib/pgcrypto's pgp_sym_decrypt() - to not fail on messages whose length is 6 less than a power of 2 - (Marko Tiikkaja) - - - - - - Fix file descriptor leak in contrib/pg_test_fsync - (Jeff Janes) - - - - This could cause failure to remove temporary files on Windows. - - - - - - Handle unexpected query results, especially NULLs, safely in - contrib/tablefunc's connectby() - (Michael Paquier) - - - - connectby() previously crashed if it encountered a NULL - key value. It now prints that row but doesn't recurse further. - - - - - - Avoid a possible crash in contrib/xml2's - xslt_process() (Mark Simonetti) - - - - libxslt seems to have an undocumented dependency on - the order in which resources are freed; reorder our calls to avoid a - crash. - - - - - - Mark some contrib I/O functions with correct volatility - properties (Tom Lane) - - - - The previous over-conservative marking was immaterial in normal use, - but could cause optimization problems or rejection of valid index - expression definitions. Since the consequences are not large, we've - just adjusted the function definitions in the extension modules' - scripts, without changing version numbers. - - - - - - Numerous cleanups of warnings from Coverity static code analyzer - (Andres Freund, Tatsuo Ishii, Marko Kreen, Tom Lane, Michael Paquier) - - - - These changes are mostly cosmetic but in some cases fix corner-case - bugs, for example a crash rather than a proper error report after an - out-of-memory failure. None are believed to represent security - issues. - - - - - - Detect incompatible OpenLDAP versions during build (Noah Misch) - - - - With OpenLDAP versions 2.4.24 through 2.4.31, - inclusive, PostgreSQL backends can crash at exit. - Raise a warning during configure based on the - compile-time OpenLDAP version number, and test the crashing scenario - in the contrib/dblink regression test. - - - - - - In non-MSVC Windows builds, ensure libpq.dll is installed - with execute permissions (Noah Misch) - - - - - - Make pg_regress remove any temporary installation it - created upon successful exit (Tom Lane) - - - - This results in a very substantial reduction in disk space usage - during make check-world, since that sequence involves - creation of numerous temporary installations. - - - - - - Support time zone abbreviations that change UTC offset from time to - time (Tom Lane) - - - - Previously, PostgreSQL assumed that the UTC offset - associated with a time zone abbreviation (such as EST) - never changes in the usage of any particular locale. However this - assumption fails in the real world, so introduce the ability for a - zone abbreviation to represent a UTC offset that sometimes changes. - Update the zone abbreviation definition files to make use of this - feature in timezone locales that have changed the UTC offset of their - abbreviations since 1970 (according to the IANA timezone database). - In such timezones, PostgreSQL will now associate the - correct UTC offset with the abbreviation depending on the given date. - - - - - - Update time zone abbreviations lists (Tom Lane) - - - - Add CST (China Standard Time) to our lists. - Remove references to ADT as Arabia Daylight Time, an - abbreviation that's been out of use since 2007; therefore, claiming - there is a conflict with Atlantic Daylight Time doesn't seem - especially helpful. - Fix entirely incorrect GMT offsets for CKT (Cook Islands), FJT, and FJST - (Fiji); we didn't even have them on the proper side of the date line. - - - - - - Update time zone data files to tzdata release 2015a. - - - - The IANA timezone database has adopted abbreviations of the form - AxST/AxDT - for all Australian time zones, reflecting what they believe to be - current majority practice Down Under. These names do not conflict - with usage elsewhere (other than ACST for Acre Summer Time, which has - been in disuse since 1994). Accordingly, adopt these names into - our Default timezone abbreviation set. - The Australia abbreviation set now contains only CST, EAST, - EST, SAST, SAT, and WST, all of which are thought to be mostly - historical usage. Note that SAST has also been changed to be South - Africa Standard Time in the Default abbreviation set. - - - - Also, add zone abbreviations SRET (Asia/Srednekolymsk) and XJT - (Asia/Urumqi), and use WSST/WSDT for western Samoa. Also, there were - DST law changes in Chile, Mexico, the Turks & Caicos Islands - (America/Grand_Turk), and Fiji. There is a new zone - Pacific/Bougainville for portions of Papua New Guinea. Also, numerous - corrections for historical (pre-1970) time zone data. - - - - - - - - - - Release 9.1.14 - - - Release date: - 2014-07-24 - - - - This release contains a variety of fixes from 9.1.13. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.14 - - - A dump/restore is not required for those running 9.1.X. - - - - However, this release corrects an index corruption problem in some GiST - indexes. See the first changelog entry below to find out whether your - installation has been affected and what steps you should take if so. - - - - Also, if you are upgrading from a version earlier than 9.1.11, - see . - - - - - - Changes - - - - - - Correctly initialize padding bytes in contrib/btree_gist - indexes on bit columns (Heikki Linnakangas) - - - - This error could result in incorrect query results due to values that - should compare equal not being seen as equal. - Users with GiST indexes on bit or bit varying - columns should REINDEX those indexes after installing this - update. - - - - - - Protect against torn pages when deleting GIN list pages (Heikki - Linnakangas) - - - - This fix prevents possible index corruption if a system crash occurs - while the page update is being written to disk. - - - - - - Don't clear the right-link of a GiST index page while replaying - updates from WAL (Heikki Linnakangas) - - - - This error could lead to transiently wrong answers from GiST index - scans performed in Hot Standby. - - - - - - Fix feedback status when is - turned off on-the-fly (Simon Riggs) - - - - - - Fix possibly-incorrect cache invalidation during nested calls - to ReceiveSharedInvalidMessages (Andres Freund) - - - - - - Fix could not find pathkey item to sort planner failures - with UNION ALL over subqueries reading from tables with - inheritance children (Tom Lane) - - - - - - Don't assume a subquery's output is unique if there's a set-returning - function in its targetlist (David Rowley) - - - - This oversight could lead to misoptimization of constructs - like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP - BY y). - - - - - - Fix failure to detoast fields in composite elements of structured - types (Tom Lane) - - - - This corrects cases where TOAST pointers could be copied into other - tables without being dereferenced. If the original data is later - deleted, it would lead to errors like missing chunk number 0 - for toast value ... when the now-dangling pointer is used. - - - - - - Fix record type has not been registered failures with - whole-row references to the output of Append plan nodes (Tom Lane) - - - - - - Fix possible crash when invoking a user-defined function while - rewinding a cursor (Tom Lane) - - - - - - Fix query-lifespan memory leak while evaluating the arguments for a - function in FROM (Tom Lane) - - - - - - Fix session-lifespan memory leaks in regular-expression processing - (Tom Lane, Arthur O'Dwyer, Greg Stark) - - - - - - Fix data encoding error in hungarian.stop (Tom Lane) - - - - - - Prevent foreign tables from being created with OIDS - when is true - (Etsuro Fujita) - - - - - - Fix liveness checks for rows that were inserted in the current - transaction and then deleted by a now-rolled-back subtransaction - (Andres Freund) - - - - This could cause problems (at least spurious warnings, and at worst an - infinite loop) if CREATE INDEX or CLUSTER were - done later in the same transaction. - - - - - - Clear pg_stat_activity.xact_start - during PREPARE TRANSACTION (Andres Freund) - - - - After the PREPARE, the originating session is no longer in - a transaction, so it should not continue to display a transaction - start time. - - - - - - Fix REASSIGN OWNED to not fail for text search objects - (Álvaro Herrera) - - - - - - Block signals during postmaster startup (Tom Lane) - - - - This ensures that the postmaster will properly clean up after itself - if, for example, it receives SIGINT while still - starting up. - - - - - - Fix client host name lookup when processing pg_hba.conf - entries that specify host names instead of IP addresses (Tom Lane) - - - - Ensure that reverse-DNS lookup failures are reported, instead of just - silently not matching such entries. Also ensure that we make only - one reverse-DNS lookup attempt per connection, not one per host name - entry, which is what previously happened if the lookup attempts failed. - - - - - - Secure Unix-domain sockets of temporary postmasters started during - make check (Noah Misch) - - - - Any local user able to access the socket file could connect as the - server's bootstrap superuser, then proceed to execute arbitrary code as - the operating-system user running the test, as we previously noted in - CVE-2014-0067. This change defends against that risk by placing the - server's socket in a temporary, mode 0700 subdirectory - of /tmp. The hazard remains however on platforms where - Unix sockets are not supported, notably Windows, because then the - temporary postmaster must accept local TCP connections. - - - - A useful side effect of this change is to simplify - make check testing in builds that - override DEFAULT_PGSOCKET_DIR. Popular non-default values - like /var/run/postgresql are often not writable by the - build user, requiring workarounds that will no longer be necessary. - - - - - - Fix tablespace creation WAL replay to work on Windows (MauMau) - - - - - - Fix detection of socket creation failures on Windows (Bruce Momjian) - - - - - - On Windows, allow new sessions to absorb values of PGC_BACKEND - parameters (such as ) from the - configuration file (Amit Kapila) - - - - Previously, if such a parameter were changed in the file post-startup, - the change would have no effect. - - - - - - Properly quote executable path names on Windows (Nikhil Deshpande) - - - - This oversight could cause initdb - and pg_upgrade to fail on Windows, if the installation - path contained both spaces and @ signs. - - - - - - Fix linking of libpython on macOS (Tom Lane) - - - - The method we previously used can fail with the Python library - supplied by Xcode 5.0 and later. - - - - - - Avoid buffer bloat in libpq when the server - consistently sends data faster than the client can absorb it - (Shin-ichi Morita, Tom Lane) - - - - libpq could be coerced into enlarging its input buffer - until it runs out of memory (which would be reported misleadingly - as lost synchronization with server). Under ordinary - circumstances it's quite far-fetched that data could be continuously - transmitted more quickly than the recv() loop can - absorb it, but this has been observed when the client is artificially - slowed by scheduler constraints. - - - - - - Ensure that LDAP lookup attempts in libpq time out as - intended (Laurenz Albe) - - - - - - Fix ecpg to do the right thing when an array - of char * is the target for a FETCH statement returning more - than one row, as well as some other array-handling fixes - (Ashutosh Bapat) - - - - - - Fix pg_restore's processing of old-style large object - comments (Tom Lane) - - - - A direct-to-database restore from an archive file generated by a - pre-9.0 version of pg_dump would usually fail if the - archive contained more than a few comments for large objects. - - - - - - In contrib/pgcrypto functions, ensure sensitive - information is cleared from stack variables before returning - (Marko Kreen) - - - - - - In contrib/uuid-ossp, cache the state of the OSSP UUID - library across calls (Tom Lane) - - - - This improves the efficiency of UUID generation and reduces the amount - of entropy drawn from /dev/urandom, on platforms that - have that. - - - - - - Update time zone data files to tzdata release 2014e - for DST law changes in Crimea, Egypt, and Morocco. - - - - - - - - - - Release 9.1.13 - - - Release date: - 2014-03-20 - - - - This release contains a variety of fixes from 9.1.12. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.13 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.11, - see . - - - - - - Changes - - - - - - Restore GIN metapages unconditionally to avoid torn-page risk - (Heikki Linnakangas) - - - - Although this oversight could theoretically result in a corrupted - index, it is unlikely to have caused any problems in practice, since - the active part of a GIN metapage is smaller than a standard 512-byte - disk sector. - - - - - - Avoid race condition in checking transaction commit status during - receipt of a NOTIFY message (Marko Tiikkaja) - - - - This prevents a scenario wherein a sufficiently fast client might - respond to a notification before database updates made by the - notifier have become visible to the recipient. - - - - - - Allow regular-expression operators to be terminated early by query - cancel requests (Tom Lane) - - - - This prevents scenarios wherein a pathological regular expression - could lock up a server process uninterruptibly for a long time. - - - - - - Remove incorrect code that tried to allow OVERLAPS with - single-element row arguments (Joshua Yanovski) - - - - This code never worked correctly, and since the case is neither - specified by the SQL standard nor documented, it seemed better to - remove it than fix it. - - - - - - Avoid getting more than AccessShareLock when de-parsing a - rule or view (Dean Rasheed) - - - - This oversight resulted in pg_dump unexpectedly - acquiring RowExclusiveLock locks on tables mentioned as - the targets of INSERT/UPDATE/DELETE - commands in rules. While usually harmless, that could interfere with - concurrent transactions that tried to acquire, for example, - ShareLock on those tables. - - - - - - Improve performance of index endpoint probes during planning (Tom Lane) - - - - This change fixes a significant performance problem that occurred - when there were many not-yet-committed rows at the end of the index, - which is a common situation for indexes on sequentially-assigned - values such as timestamps or sequence-generated identifiers. - - - - - - Fix walsender's failure to shut down cleanly when client - is pg_receivexlog (Fujii Masao) - - - - - - Fix test to see if hot standby connections can be allowed immediately - after a crash (Heikki Linnakangas) - - - - - - Prevent interrupts while reporting non-ERROR messages - (Tom Lane) - - - - This guards against rare server-process freezeups due to recursive - entry to syslog(), and perhaps other related problems. - - - - - - Fix memory leak in PL/Perl when returning a composite result, including - multiple-OUT-parameter cases (Alex Hunsaker) - - - - - - Prevent intermittent could not reserve shared memory region - failures on recent Windows versions (MauMau) - - - - - - Update time zone data files to tzdata release 2014a - for DST law changes in Fiji and Turkey, plus historical changes in - Israel and Ukraine. - - - - - - - - - - Release 9.1.12 - - - Release date: - 2014-02-20 - - - - This release contains a variety of fixes from 9.1.11. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.12 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.11, - see . - - - - - - Changes - - - - - - Shore up GRANT ... WITH ADMIN OPTION restrictions - (Noah Misch) - - - - Granting a role without ADMIN OPTION is supposed to - prevent the grantee from adding or removing members from the granted - role, but this restriction was easily bypassed by doing SET - ROLE first. The security impact is mostly that a role member can - revoke the access of others, contrary to the wishes of his grantor. - Unapproved role member additions are a lesser concern, since an - uncooperative role member could provide most of his rights to others - anyway by creating views or SECURITY DEFINER functions. - (CVE-2014-0060) - - - - - - Prevent privilege escalation via manual calls to PL validator - functions (Andres Freund) - - - - The primary role of PL validator functions is to be called implicitly - during CREATE FUNCTION, but they are also normal SQL - functions that a user can call explicitly. Calling a validator on - a function actually written in some other language was not checked - for and could be exploited for privilege-escalation purposes. - The fix involves adding a call to a privilege-checking function in - each validator function. Non-core procedural languages will also - need to make this change to their own validator functions, if any. - (CVE-2014-0061) - - - - - - Avoid multiple name lookups during table and index DDL - (Robert Haas, Andres Freund) - - - - If the name lookups come to different conclusions due to concurrent - activity, we might perform some parts of the DDL on a different table - than other parts. At least in the case of CREATE INDEX, - this can be used to cause the permissions checks to be performed - against a different table than the index creation, allowing for a - privilege escalation attack. - (CVE-2014-0062) - - - - - - Prevent buffer overrun with long datetime strings (Noah Misch) - - - - The MAXDATELEN constant was too small for the longest - possible value of type interval, allowing a buffer overrun - in interval_out(). Although the datetime input - functions were more careful about avoiding buffer overrun, the limit - was short enough to cause them to reject some valid inputs, such as - input containing a very long timezone name. The ecpg - library contained these vulnerabilities along with some of its own. - (CVE-2014-0063) - - - - - - Prevent buffer overrun due to integer overflow in size calculations - (Noah Misch, Heikki Linnakangas) - - - - Several functions, mostly type input functions, calculated an - allocation size without checking for overflow. If overflow did - occur, a too-small buffer would be allocated and then written past. - (CVE-2014-0064) - - - - - - Prevent overruns of fixed-size buffers - (Peter Eisentraut, Jozef Mlich) - - - - Use strlcpy() and related functions to provide a clear - guarantee that fixed-size buffers are not overrun. Unlike the - preceding items, it is unclear whether these cases really represent - live issues, since in most cases there appear to be previous - constraints on the size of the input string. Nonetheless it seems - prudent to silence all Coverity warnings of this type. - (CVE-2014-0065) - - - - - - Avoid crashing if crypt() returns NULL (Honza Horak, - Bruce Momjian) - - - - There are relatively few scenarios in which crypt() - could return NULL, but contrib/chkpass would crash - if it did. One practical case in which this could be an issue is - if libc is configured to refuse to execute unapproved - hashing algorithms (e.g., FIPS mode). - (CVE-2014-0066) - - - - - - Document risks of make check in the regression testing - instructions (Noah Misch, Tom Lane) - - - - Since the temporary server started by make check - uses trust authentication, another user on the same machine - could connect to it as database superuser, and then potentially - exploit the privileges of the operating-system user who started the - tests. A future release will probably incorporate changes in the - testing procedure to prevent this risk, but some public discussion is - needed first. So for the moment, just warn people against using - make check when there are untrusted users on the - same machine. - (CVE-2014-0067) - - - - - - Fix possible mis-replay of WAL records when some segments of a - relation aren't full size (Greg Stark, Tom Lane) - - - - The WAL update could be applied to the wrong page, potentially many - pages past where it should have been. Aside from corrupting data, - this error has been observed to result in significant bloat - of standby servers compared to their masters, due to updates being - applied far beyond where the end-of-file should have been. This - failure mode does not appear to be a significant risk during crash - recovery, only when initially synchronizing a standby created from a - base backup taken from a quickly-changing master. - - - - - - Fix bug in determining when recovery has reached consistency - (Tomonari Katsumata, Heikki Linnakangas) - - - - In some cases WAL replay would mistakenly conclude that the database - was already consistent at the start of replay, thus possibly allowing - hot-standby queries before the database was really consistent. Other - symptoms such as PANIC: WAL contains references to invalid - pages were also possible. - - - - - - Fix improper locking of btree index pages while replaying - a VACUUM operation in hot-standby mode (Andres Freund, - Heikki Linnakangas, Tom Lane) - - - - This error could result in PANIC: WAL contains references to - invalid pages failures. - - - - - - Ensure that insertions into non-leaf GIN index pages write a full-page - WAL record when appropriate (Heikki Linnakangas) - - - - The previous coding risked index corruption in the event of a - partial-page write during a system crash. - - - - - - When pause_at_recovery_target - and recovery_target_inclusive are both set, ensure the - target record is applied before pausing, not after (Heikki - Linnakangas) - - - - - - Fix race conditions during server process exit (Robert Haas) - - - - Ensure that signal handlers don't attempt to use the - process's MyProc pointer after it's no longer valid. - - - - - - Fix race conditions in walsender shutdown logic and walreceiver - SIGHUP signal handler (Tom Lane) - - - - - - Fix unsafe references to errno within error reporting - logic (Christian Kruse) - - - - This would typically lead to odd behaviors such as missing or - inappropriate HINT fields. - - - - - - Fix possible crashes from using ereport() too early - during server startup (Tom Lane) - - - - The principal case we've seen in the field is a crash if the server - is started in a directory it doesn't have permission to read. - - - - - - Clear retry flags properly in OpenSSL socket write - function (Alexander Kukushkin) - - - - This omission could result in a server lockup after unexpected loss - of an SSL-encrypted connection. - - - - - - Fix length checking for Unicode identifiers (U&"..." - syntax) containing escapes (Tom Lane) - - - - A spurious truncation warning would be printed for such identifiers - if the escaped form of the identifier was too long, but the - identifier actually didn't need truncation after de-escaping. - - - - - - Allow keywords that are type names to be used in lists of roles - (Stephen Frost) - - - - A previous patch allowed such keywords to be used without quoting - in places such as role identifiers; but it missed cases where a - list of role identifiers was permitted, such as DROP ROLE. - - - - - - Fix parser crash for EXISTS(SELECT * FROM - zero_column_table) (Tom Lane) - - - - - - Fix possible crash due to invalid plan for nested sub-selects, such - as WHERE (... x IN (SELECT ...) ...) IN (SELECT ...) - (Tom Lane) - - - - - - Ensure that ANALYZE creates statistics for a table column - even when all the values in it are too wide (Tom Lane) - - - - ANALYZE intentionally omits very wide values from its - histogram and most-common-values calculations, but it neglected to do - something sane in the case that all the sampled entries are too wide. - - - - - - In ALTER TABLE ... SET TABLESPACE, allow the database's - default tablespace to be used without a permissions check - (Stephen Frost) - - - - CREATE TABLE has always allowed such usage, - but ALTER TABLE didn't get the memo. - - - - - - Fix cannot accept a set error when some arms of - a CASE return a set and others don't (Tom Lane) - - - - - - Fix checks for all-zero client addresses in pgstat functions (Kevin - Grittner) - - - - - - Fix possible misclassification of multibyte characters by the text - search parser (Tom Lane) - - - - Non-ASCII characters could be misclassified when using C locale with - a multibyte encoding. On Cygwin, non-C locales could fail as well. - - - - - - Fix possible misbehavior in plainto_tsquery() - (Heikki Linnakangas) - - - - Use memmove() not memcpy() for copying - overlapping memory regions. There have been no field reports of - this actually causing trouble, but it's certainly risky. - - - - - - Fix placement of permissions checks in pg_start_backup() - and pg_stop_backup() (Andres Freund, Magnus Hagander) - - - - The previous coding might attempt to do catalog access when it - shouldn't. - - - - - - Accept SHIFT_JIS as an encoding name for locale checking - purposes (Tatsuo Ishii) - - - - - - Fix misbehavior of PQhost() on Windows (Fujii Masao) - - - - It should return localhost if no host has been specified. - - - - - - Improve error handling in libpq and psql - for failures during COPY TO STDOUT/FROM STDIN (Tom Lane) - - - - In particular this fixes an infinite loop that could occur in 9.2 and - up if the server connection was lost during COPY FROM - STDIN. Variants of that scenario might be possible in older - versions, or with other client applications. - - - - - - Fix possible incorrect printing of filenames - in pg_basebackup's verbose mode (Magnus Hagander) - - - - - - Avoid including tablespaces inside PGDATA twice in base backups - (Dimitri Fontaine, Magnus Hagander) - - - - - - Fix misaligned descriptors in ecpg (MauMau) - - - - - - In ecpg, handle lack of a hostname in the connection - parameters properly (Michael Meskes) - - - - - - Fix performance regression in contrib/dblink connection - startup (Joe Conway) - - - - Avoid an unnecessary round trip when client and server encodings match. - - - - - - In contrib/isn, fix incorrect calculation of the check - digit for ISMN values (Fabien Coelho) - - - - - - Ensure client-code-only installation procedure works as documented - (Peter Eisentraut) - - - - - - In Mingw and Cygwin builds, install the libpq DLL - in the bin directory (Andrew Dunstan) - - - - This duplicates what the MSVC build has long done. It should fix - problems with programs like psql failing to start - because they can't find the DLL. - - - - - - Avoid using the deprecated dllwrap tool in Cygwin builds - (Marco Atzeri) - - - - - - Don't generate plain-text HISTORY - and src/test/regress/README files anymore (Tom Lane) - - - - These text files duplicated the main HTML and PDF documentation - formats. The trouble involved in maintaining them greatly outweighs - the likely audience for plain-text format. Distribution tarballs - will still contain files by these names, but they'll just be stubs - directing the reader to consult the main documentation. - The plain-text INSTALL file will still be maintained, as - there is arguably a use-case for that. - - - - - - Update time zone data files to tzdata release 2013i - for DST law changes in Jordan and historical changes in Cuba. - - - - In addition, the zones Asia/Riyadh87, - Asia/Riyadh88, and Asia/Riyadh89 have been - removed, as they are no longer maintained by IANA, and never - represented actual civil timekeeping practice. - - - - - - - - - - Release 9.1.11 - - - Release date: - 2013-12-05 - - - - This release contains a variety of fixes from 9.1.10. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.11 - - - A dump/restore is not required for those running 9.1.X. - - - - However, this release corrects a number of potential data corruption - issues. See the first two changelog entries below to find out whether - your installation has been affected and what steps you can take if so. - - - - Also, if you are upgrading from a version earlier than 9.1.9, - see . - - - - - - Changes - - - - - - Fix VACUUM's tests to see whether it can - update relfrozenxid (Andres Freund) - - - - In some cases VACUUM (either manual or autovacuum) could - incorrectly advance a table's relfrozenxid value, - allowing tuples to escape freezing, causing those rows to become - invisible once 2^31 transactions have elapsed. The probability of - data loss is fairly low since multiple incorrect advancements would - need to happen before actual loss occurs, but it's not zero. Users - upgrading from releases 9.0.4 or 8.4.8 or earlier are not affected, but - all later versions contain the bug. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix any latent corruption but will not be able - to fix all pre-existing data errors. However, an installation can be - presumed safe after performing this vacuuming if it has executed fewer - than 2^31 update transactions in its lifetime (check this with - SELECT txid_current() < 2^31). - - - - - - Fix initialization of pg_clog and pg_subtrans - during hot standby startup (Andres Freund, Heikki Linnakangas) - - - - This bug can cause data loss on standby servers at the moment they - start to accept hot-standby queries, by marking committed transactions - as uncommitted. The likelihood of such corruption is small unless, at - the time of standby startup, the primary server has executed many - updating transactions since its last checkpoint. Symptoms include - missing rows, rows that should have been deleted being still visible, - and obsolete versions of updated rows being still visible alongside - their newer versions. - - - - This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. - Standby servers that have only been running earlier releases are not - at risk. It's recommended that standby servers that have ever run any - of the buggy releases be re-cloned from the primary (e.g., with a new - base backup) after upgrading. - - - - - - Truncate pg_multixact contents during WAL replay - (Andres Freund) - - - - This avoids ever-increasing disk space consumption in standby servers. - - - - - - Fix race condition in GIN index posting tree page deletion (Heikki - Linnakangas) - - - - This could lead to transient wrong answers or query failures. - - - - - - Avoid flattening a subquery whose SELECT list contains a - volatile function wrapped inside a sub-SELECT (Tom Lane) - - - - This avoids unexpected results due to extra evaluations of the - volatile function. - - - - - - Fix planner's processing of non-simple-variable subquery outputs - nested within outer joins (Tom Lane) - - - - This error could lead to incorrect plans for queries involving - multiple levels of subqueries within JOIN syntax. - - - - - - Fix incorrect generation of optimized MIN()/MAX() plans for - inheritance trees (Tom Lane) - - - - The planner could fail in cases where the MIN()/MAX() argument was an - expression rather than a simple variable. - - - - - - Fix premature deletion of temporary files (Andres Freund) - - - - - - Fix possible read past end of memory in rule printing (Peter Eisentraut) - - - - - - Fix array slicing of int2vector and oidvector values - (Tom Lane) - - - - Expressions of this kind are now implicitly promoted to - regular int2 or oid arrays. - - - - - - Fix incorrect behaviors when using a SQL-standard, simple GMT offset - timezone (Tom Lane) - - - - In some cases, the system would use the simple GMT offset value when - it should have used the regular timezone setting that had prevailed - before the simple offset was selected. This change also causes - the timeofday function to honor the simple GMT offset - zone. - - - - - - Prevent possible misbehavior when logging translations of Windows - error codes (Tom Lane) - - - - - - Properly quote generated command lines in pg_ctl - (Naoya Anzai and Tom Lane) - - - - This fix applies only to Windows. - - - - - - Fix pg_dumpall to work when a source database - sets default_transaction_read_only - via ALTER DATABASE SET (Kevin Grittner) - - - - Previously, the generated script would fail during restore. - - - - - - Make ecpg search for quoted cursor names - case-sensitively (Zoltán Böszörményi) - - - - - - Fix ecpg's processing of lists of variables - declared varchar (Zoltán Böszörményi) - - - - - - Make contrib/lo defend against incorrect trigger definitions - (Marc Cousin) - - - - - - Update time zone data files to tzdata release 2013h - for DST law changes in Argentina, Brazil, Jordan, Libya, - Liechtenstein, Morocco, and Palestine. Also, new timezone - abbreviations WIB, WIT, WITA for Indonesia. - - - - - - - - - - Release 9.1.10 - - - Release date: - 2013-10-10 - - - - This release contains a variety of fixes from 9.1.9. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.10 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.9, - see . - - - - - - Changes - - - - - - Prevent corruption of multi-byte characters when attempting to - case-fold identifiers (Andrew Dunstan) - - - - PostgreSQL case-folds non-ASCII characters only - when using a single-byte server encoding. - - - - - - Fix checkpoint memory leak in background writer when wal_level = - hot_standby (Naoya Anzai) - - - - - - Fix memory leak caused by lo_open() failure - (Heikki Linnakangas) - - - - - - Fix memory overcommit bug when work_mem is using more - than 24GB of memory (Stephen Frost) - - - - - - Serializable snapshot fixes (Kevin Grittner, Heikki Linnakangas) - - - - - - Fix deadlock bug in libpq when using SSL (Stephen Frost) - - - - - - Fix possible SSL state corruption in threaded libpq applications - (Nick Phillips, Stephen Frost) - - - - - - Properly compute row estimates for boolean columns containing many NULL - values (Andrew Gierth) - - - - Previously tests like col IS NOT TRUE and col IS - NOT FALSE did not properly factor in NULL values when estimating - plan costs. - - - - - - Prevent pushing down WHERE clauses into unsafe - UNION/INTERSECT subqueries (Tom Lane) - - - - Subqueries of a UNION or INTERSECT that - contain set-returning functions or volatile functions in their - SELECT lists could be improperly optimized, leading to - run-time errors or incorrect query results. - - - - - - Fix rare case of failed to locate grouping columns - planner failure (Tom Lane) - - - - - - Fix pg_dump of foreign tables with dropped columns (Andrew Dunstan) - - - - Previously such cases could cause a pg_upgrade error. - - - - - - Reorder pg_dump processing of extension-related - rules and event triggers (Joe Conway) - - - - - - Force dumping of extension tables if specified by pg_dump - -t or -n (Joe Conway) - - - - - - Improve view dumping code's handling of dropped columns in referenced - tables (Tom Lane) - - - - - - Fix pg_restore -l with the directory archive to display - the correct format name (Fujii Masao) - - - - - - Properly record index comments created using UNIQUE - and PRIMARY KEY syntax (Andres Freund) - - - - This fixes a parallel pg_restore failure. - - - - - - Properly guarantee transmission of WAL files before clean switchover - (Fujii Masao) - - - - Previously, the streaming replication connection might close before all - WAL files had been replayed on the standby. - - - - - - Fix WAL segment timeline handling during recovery (Mitsumasa Kondo, - Heikki Linnakangas) - - - - WAL file recycling during standby recovery could lead to premature - recovery completion, resulting in data loss. - - - - - - Fix REINDEX TABLE and REINDEX DATABASE - to properly revalidate constraints and mark invalidated indexes as - valid (Noah Misch) - - - - REINDEX INDEX has always worked properly. - - - - - - Fix possible deadlock during concurrent CREATE INDEX - CONCURRENTLY operations (Tom Lane) - - - - - - Fix regexp_matches() handling of zero-length matches - (Jeevan Chalke) - - - - Previously, zero-length matches like '^' could return too many matches. - - - - - - Fix crash for overly-complex regular expressions (Heikki Linnakangas) - - - - - - Fix regular expression match failures for back references combined with - non-greedy quantifiers (Jeevan Chalke) - - - - - - Prevent CREATE FUNCTION from checking SET - variables unless function body checking is enabled (Tom Lane) - - - - - - Allow ALTER DEFAULT PRIVILEGES to operate on schemas - without requiring CREATE permission (Tom Lane) - - - - - - Loosen restriction on keywords used in queries (Tom Lane) - - - - Specifically, lessen keyword restrictions for role names, language - names, EXPLAIN and COPY options, and - SET values. This allows COPY ... (FORMAT - BINARY) to work as expected; previously BINARY needed - to be quoted. - - - - - - Fix pgp_pub_decrypt() so it works for secret keys with - passwords (Marko Kreen) - - - - - - Make pg_upgrade use pg_dump - --quote-all-identifiers to avoid problems with keyword changes - between releases (Tom Lane) - - - - - - Remove rare inaccurate warning during vacuum of index-less tables - (Heikki Linnakangas) - - - - - - Ensure that VACUUM ANALYZE still runs the ANALYZE phase - if its attempt to truncate the file is cancelled due to lock conflicts - (Kevin Grittner) - - - - - - Avoid possible failure when performing transaction control commands (e.g - ROLLBACK) in prepared queries (Tom Lane) - - - - - - Ensure that floating-point data input accepts standard spellings - of infinity on all platforms (Tom Lane) - - - - The C99 standard says that allowable spellings are inf, - +inf, -inf, infinity, - +infinity, and -infinity. Make sure we - recognize these even if the platform's strtod function - doesn't. - - - - - - Expand ability to compare rows to records and arrays (Rafal Rzepecki, - Tom Lane) - - - - - - Update time zone data files to tzdata release 2013d - for DST law changes in Israel, Morocco, Palestine, and Paraguay. - Also, historical zone data corrections for Macquarie Island. - - - - - - - - - - Release 9.1.9 - - - Release date: - 2013-04-04 - - - - This release contains a variety of fixes from 9.1.8. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.9 - - - A dump/restore is not required for those running 9.1.X. - - - - However, this release corrects several errors in management of GiST - indexes. After installing this update, it is advisable to - REINDEX any GiST indexes that meet one or more of the - conditions described below. - - - - Also, if you are upgrading from a version earlier than 9.1.6, - see . - - - - - - Changes - - - - - - Fix insecure parsing of server command-line switches (Mitsumasa - Kondo, Kyotaro Horiguchi) - - - - A connection request containing a database name that begins with - - could be crafted to damage or destroy - files within the server's data directory, even if the request is - eventually rejected. (CVE-2013-1899) - - - - - - Reset OpenSSL randomness state in each postmaster child process - (Marko Kreen) - - - - This avoids a scenario wherein random numbers generated by - contrib/pgcrypto functions might be relatively easy for - another database user to guess. The risk is only significant when - the postmaster is configured with ssl = on - but most connections don't use SSL encryption. (CVE-2013-1900) - - - - - - Make REPLICATION privilege checks test current user not authenticated - user (Noah Misch) - - - - An unprivileged database user could exploit this mistake to call - pg_start_backup() or pg_stop_backup(), - thus possibly interfering with creation of routine backups. - (CVE-2013-1901) - - - - - - Fix GiST indexes to not use fuzzy geometric comparisons when - it's not appropriate to do so (Alexander Korotkov) - - - - The core geometric types perform comparisons using fuzzy - equality, but gist_box_same must do exact comparisons, - else GiST indexes using it might become inconsistent. After installing - this update, users should REINDEX any GiST indexes on - box, polygon, circle, or point - columns, since all of these use gist_box_same. - - - - - - Fix erroneous range-union and penalty logic in GiST indexes that use - contrib/btree_gist for variable-width data types, that is - text, bytea, bit, and numeric - columns (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in useless - index bloat. Users are advised to REINDEX such indexes - after installing this update. - - - - - - Fix bugs in GiST page splitting code for multi-column indexes - (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in indexes - that are unnecessarily inefficient to search. Users are advised to - REINDEX multi-column GiST indexes after installing this - update. - - - - - - Fix gist_point_consistent - to handle fuzziness consistently (Alexander Korotkov) - - - - Index scans on GiST indexes on point columns would sometimes - yield results different from a sequential scan, because - gist_point_consistent disagreed with the underlying - operator code about whether to do comparisons exactly or fuzzily. - - - - - - Fix buffer leak in WAL replay (Heikki Linnakangas) - - - - This bug could result in incorrect local pin count errors - during replay, making recovery impossible. - - - - - - Fix race condition in DELETE RETURNING (Tom Lane) - - - - Under the right circumstances, DELETE RETURNING could - attempt to fetch data from a shared buffer that the current process - no longer has any pin on. If some other process changed the buffer - meanwhile, this would lead to garbage RETURNING output, or - even a crash. - - - - - - Fix infinite-loop risk in regular expression compilation (Tom Lane, - Don Porter) - - - - - - Fix potential null-pointer dereference in regular expression compilation - (Tom Lane) - - - - - - Fix to_char() to use ASCII-only case-folding rules where - appropriate (Tom Lane) - - - - This fixes misbehavior of some template patterns that should be - locale-independent, but mishandled I and - i in Turkish locales. - - - - - - Fix unwanted rejection of timestamp 1999-12-31 24:00:00 - (Tom Lane) - - - - - - Fix logic error when a single transaction does UNLISTEN - then LISTEN (Tom Lane) - - - - The session wound up not listening for notify events at all, though it - surely should listen in this case. - - - - - - Fix possible planner crash after columns have been added to a view - that's depended on by another view (Tom Lane) - - - - - - Remove useless picksplit doesn't support secondary split log - messages (Josh Hansen, Tom Lane) - - - - This message seems to have been added in expectation of code that was - never written, and probably never will be, since GiST's default - handling of secondary splits is actually pretty good. So stop nagging - end users about it. - - - - - - Fix possible failure to send a session's last few transaction - commit/abort counts to the statistics collector (Tom Lane) - - - - - - Eliminate memory leaks in PL/Perl's spi_prepare() function - (Alex Hunsaker, Tom Lane) - - - - - - Fix pg_dumpall to handle database names containing - = correctly (Heikki Linnakangas) - - - - - - Avoid crash in pg_dump when an incorrect connection - string is given (Heikki Linnakangas) - - - - - - Ignore invalid indexes in pg_dump and - pg_upgrade (Michael Paquier, Bruce Momjian) - - - - Dumping invalid indexes can cause problems at restore time, for example - if the reason the index creation failed was because it tried to enforce - a uniqueness condition not satisfied by the table's data. Also, if the - index creation is in fact still in progress, it seems reasonable to - consider it to be an uncommitted DDL change, which - pg_dump wouldn't be expected to dump anyway. - pg_upgrade now also skips invalid indexes rather than - failing. - - - - - - In pg_basebackup, include only the current server - version's subdirectory when backing up a tablespace (Heikki - Linnakangas) - - - - - - Add a server version check in pg_basebackup and - pg_receivexlog, so they fail cleanly with version - combinations that won't work (Heikki Linnakangas) - - - - - - Fix contrib/pg_trgm's similarity() function - to return zero for trigram-less strings (Tom Lane) - - - - Previously it returned NaN due to internal division by zero. - - - - - - Update time zone data files to tzdata release 2013b - for DST law changes in Chile, Haiti, Morocco, Paraguay, and some - Russian areas. Also, historical zone data corrections for numerous - places. - - - - Also, update the time zone abbreviation files for recent changes in - Russia and elsewhere: CHOT, GET, - IRKT, KGT, KRAT, MAGT, - MAWT, MSK, NOVT, OMST, - TKT, VLAT, WST, YAKT, - YEKT now follow their current meanings, and - VOLT (Europe/Volgograd) and MIST - (Antarctica/Macquarie) are added to the default abbreviations list. - - - - - - - - - - Release 9.1.8 - - - Release date: - 2013-02-07 - - - - This release contains a variety of fixes from 9.1.7. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.8 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.6, - see . - - - - - - Changes - - - - - - Prevent execution of enum_recv from SQL (Tom Lane) - - - - The function was misdeclared, allowing a simple SQL command to crash the - server. In principle an attacker might be able to use it to examine the - contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) - for reporting this issue. (CVE-2013-0255) - - - - - - Fix multiple problems in detection of when a consistent database - state has been reached during WAL replay (Fujii Masao, Heikki - Linnakangas, Simon Riggs, Andres Freund) - - - - - - Update minimum recovery point when truncating a relation file (Heikki - Linnakangas) - - - - Once data has been discarded, it's no longer safe to stop recovery at - an earlier point in the timeline. - - - - - - Fix recycling of WAL segments after changing recovery target timeline - (Heikki Linnakangas) - - - - - - Fix missing cancellations in hot standby mode (Noah Misch, Simon Riggs) - - - - The need to cancel conflicting hot-standby queries would sometimes be - missed, allowing those queries to see inconsistent data. - - - - - - Prevent recovery pause feature from pausing before users can connect - (Tom Lane) - - - - - - Fix SQL grammar to allow subscripting or field selection from a - sub-SELECT result (Tom Lane) - - - - - - Fix performance problems with autovacuum truncation in busy workloads - (Jan Wieck) - - - - Truncation of empty pages at the end of a table requires exclusive - lock, but autovacuum was coded to fail (and release the table lock) - when there are conflicting lock requests. Under load, it is easily - possible that truncation would never occur, resulting in table bloat. - Fix by performing a partial truncation, releasing the lock, then - attempting to re-acquire the lock and continue. This fix also greatly - reduces the average time before autovacuum releases the lock after a - conflicting request arrives. - - - - - - Protect against race conditions when scanning - pg_tablespace (Stephen Frost, Tom Lane) - - - - CREATE DATABASE and DROP DATABASE could - misbehave if there were concurrent updates of - pg_tablespace entries. - - - - - - Prevent DROP OWNED from trying to drop whole databases or - tablespaces (Álvaro Herrera) - - - - For safety, ownership of these objects must be reassigned, not dropped. - - - - - - Fix error in vacuum_freeze_table_age - implementation (Andres Freund) - - - - In installations that have existed for more than vacuum_freeze_min_age - transactions, this mistake prevented autovacuum from using partial-table - scans, so that a full-table scan would always happen instead. - - - - - - Prevent misbehavior when a RowExpr or XmlExpr - is parse-analyzed twice (Andres Freund, Tom Lane) - - - - This mistake could be user-visible in contexts such as - CREATE TABLE LIKE INCLUDING INDEXES. - - - - - - Improve defenses against integer overflow in hashtable sizing - calculations (Jeff Davis) - - - - - - Fix failure to ignore leftover temporary tables after a server crash - (Tom Lane) - - - - - - Reject out-of-range dates in to_date() (Hitoshi Harada) - - - - - - Fix pg_extension_config_dump() to handle - extension-update cases properly (Tom Lane) - - - - This function will now replace any existing entry for the target - table, making it usable in extension update scripts. - - - - - - Fix PL/Python's handling of functions used as triggers on multiple - tables (Andres Freund) - - - - - - Ensure that non-ASCII prompt strings are translated to the correct - code page on Windows (Alexander Law, Noah Misch) - - - - This bug affected psql and some other client programs. - - - - - - Fix possible crash in psql's \? command - when not connected to a database (Meng Qingzhong) - - - - - - Fix possible error if a relation file is removed while - pg_basebackup is running (Heikki Linnakangas) - - - - - - Make pg_dump exclude data of unlogged tables when - running on a hot-standby server (Magnus Hagander) - - - - This would fail anyway because the data is not available on the standby - server, so it seems most convenient to assume - automatically. - - - - - - Fix pg_upgrade to deal with invalid indexes safely - (Bruce Momjian) - - - - - - Fix one-byte buffer overrun in libpq's - PQprintTuples (Xi Wang) - - - - This ancient function is not used anywhere by - PostgreSQL itself, but it might still be used by some - client code. - - - - - - Make ecpglib use translated messages properly - (Chen Huajun) - - - - - - Properly install ecpg_compat and - pgtypes libraries on MSVC (Jiang Guiqing) - - - - - - Include our version of isinf() in - libecpg if it's not provided by the system - (Jiang Guiqing) - - - - - - Rearrange configure's tests for supplied functions so it is not - fooled by bogus exports from libedit/libreadline (Christoph Berg) - - - - - - Ensure Windows build number increases over time (Magnus Hagander) - - - - - - Make pgxs build executables with the right - .exe suffix when cross-compiling for Windows - (Zoltan Boszormenyi) - - - - - - Add new timezone abbreviation FET (Tom Lane) - - - - This is now used in some eastern-European time zones. - - - - - - - - - - Release 9.1.7 - - - Release date: - 2012-12-06 - - - - This release contains a variety of fixes from 9.1.6. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.7 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.6, - see . - - - - - - Changes - - - - - - Fix multiple bugs associated with CREATE INDEX - CONCURRENTLY (Andres Freund, Tom Lane) - - - - Fix CREATE INDEX CONCURRENTLY to use - in-place updates when changing the state of an index's - pg_index row. This prevents race conditions that could - cause concurrent sessions to miss updating the target index, thus - resulting in corrupt concurrently-created indexes. - - - - Also, fix various other operations to ensure that they ignore - invalid indexes resulting from a failed CREATE INDEX - CONCURRENTLY command. The most important of these is - VACUUM, because an auto-vacuum could easily be launched - on the table before corrective action can be taken to fix or remove - the invalid index. - - - - - - Fix buffer locking during WAL replay (Tom Lane) - - - - The WAL replay code was insufficiently careful about locking buffers - when replaying WAL records that affect more than one page. This could - result in hot standby queries transiently seeing inconsistent states, - resulting in wrong answers or unexpected failures. - - - - - - Fix an error in WAL generation logic for GIN indexes (Tom Lane) - - - - This could result in index corruption, if a torn-page failure occurred. - - - - - - Properly remove startup process's virtual XID lock when promoting a - hot standby server to normal running (Simon Riggs) - - - - This oversight could prevent subsequent execution of certain - operations such as CREATE INDEX CONCURRENTLY. - - - - - - Avoid bogus out-of-sequence timeline ID errors in standby - mode (Heikki Linnakangas) - - - - - - Prevent the postmaster from launching new child processes after it's - received a shutdown signal (Tom Lane) - - - - This mistake could result in shutdown taking longer than it should, or - even never completing at all without additional user action. - - - - - - Avoid corruption of internal hash tables when out of memory - (Hitoshi Harada) - - - - - - Prevent file descriptors for dropped tables from being held open past - transaction end (Tom Lane) - - - - This should reduce problems with long-since-dropped tables continuing - to occupy disk space. - - - - - - Prevent database-wide crash and restart when a new child process is - unable to create a pipe for its latch (Tom Lane) - - - - Although the new process must fail, there is no good reason to force a - database-wide restart, so avoid that. This improves robustness when - the kernel is nearly out of file descriptors. - - - - - - Fix planning of non-strict equivalence clauses above outer joins - (Tom Lane) - - - - The planner could derive incorrect constraints from a clause equating - a non-strict construct to something else, for example - WHERE COALESCE(foo, 0) = 0 - when foo is coming from the nullable side of an outer join. - - - - - - Fix SELECT DISTINCT with index-optimized - MIN/MAX on an inheritance tree (Tom Lane) - - - - The planner would fail with failed to re-find MinMaxAggInfo - record given this combination of factors. - - - - - - Improve planner's ability to prove exclusion constraints from - equivalence classes (Tom Lane) - - - - - - Fix partial-row matching in hashed subplans to handle cross-type cases - correctly (Tom Lane) - - - - This affects multicolumn NOT IN subplans, such as - WHERE (a, b) NOT IN (SELECT x, y FROM ...) - when for instance b and y are int4 - and int8 respectively. This mistake led to wrong answers - or crashes depending on the specific datatypes involved. - - - - - - Acquire buffer lock when re-fetching the old tuple for an - AFTER ROW UPDATE/DELETE trigger (Andres Freund) - - - - In very unusual circumstances, this oversight could result in passing - incorrect data to a trigger WHEN condition, or to the - precheck logic for a foreign-key enforcement trigger. That could - result in a crash, or in an incorrect decision about whether to - fire the trigger. - - - - - - Fix ALTER COLUMN TYPE to handle inherited check - constraints properly (Pavan Deolasee) - - - - This worked correctly in pre-8.4 releases, and now works correctly - in 8.4 and later. - - - - - - Fix ALTER EXTENSION SET SCHEMA's failure to move some - subsidiary objects into the new schema (Álvaro Herrera, Dimitri - Fontaine) - - - - - - Fix REASSIGN OWNED to handle grants on tablespaces - (Álvaro Herrera) - - - - - - Ignore incorrect pg_attribute entries for system - columns for views (Tom Lane) - - - - Views do not have any system columns. However, we forgot to - remove such entries when converting a table to a view. That's fixed - properly for 9.3 and later, but in previous branches we need to defend - against existing mis-converted views. - - - - - - Fix rule printing to dump INSERT INTO table - DEFAULT VALUES correctly (Tom Lane) - - - - - - Guard against stack overflow when there are too many - UNION/INTERSECT/EXCEPT clauses - in a query (Tom Lane) - - - - - - Prevent platform-dependent failures when dividing the minimum possible - integer value by -1 (Xi Wang, Tom Lane) - - - - - - Fix possible access past end of string in date parsing - (Hitoshi Harada) - - - - - - Fix failure to advance XID epoch if XID wraparound happens during a - checkpoint and wal_level is hot_standby - (Tom Lane, Andres Freund) - - - - While this mistake had no particular impact on - PostgreSQL itself, it was bad for - applications that rely on txid_current() and related - functions: the TXID value would appear to go backwards. - - - - - - Fix display of - pg_stat_replication.sync_state at a - page boundary (Kyotaro Horiguchi) - - - - - - Produce an understandable error message if the length of the path name - for a Unix-domain socket exceeds the platform-specific limit - (Tom Lane, Andrew Dunstan) - - - - Formerly, this would result in something quite unhelpful, such as - Non-recoverable failure in name resolution. - - - - - - Fix memory leaks when sending composite column values to the client - (Tom Lane) - - - - - - Make pg_ctl more robust about reading the - postmaster.pid file (Heikki Linnakangas) - - - - Fix race conditions and possible file descriptor leakage. - - - - - - Fix possible crash in psql if incorrectly-encoded data - is presented and the client_encoding setting is a - client-only encoding, such as SJIS (Jiang Guiqing) - - - - - - Make pg_dump dump SEQUENCE SET items in - the data not pre-data section of the archive (Tom Lane) - - - - This change fixes dumping of sequences that are marked as extension - configuration tables. - - - - - - Fix bugs in the restore.sql script emitted by - pg_dump in tar output format (Tom Lane) - - - - The script would fail outright on tables whose names include - upper-case characters. Also, make the script capable of restoring - data in mode as well as the regular COPY mode. - - - - - - Fix pg_restore to accept POSIX-conformant - tar files (Brian Weaver, Tom Lane) - - - - The original coding of pg_dump's tar - output mode produced files that are not fully conformant with the - POSIX standard. This has been corrected for version 9.3. This - patch updates previous branches so that they will accept both the - incorrect and the corrected formats, in hopes of avoiding - compatibility problems when 9.3 comes out. - - - - - - Fix tar files emitted by pg_basebackup to - be POSIX conformant (Brian Weaver, Tom Lane) - - - - - - Fix pg_resetxlog to locate postmaster.pid - correctly when given a relative path to the data directory (Tom Lane) - - - - This mistake could lead to pg_resetxlog not noticing - that there is an active postmaster using the data directory. - - - - - - Fix libpq's lo_import() and - lo_export() functions to report file I/O errors properly - (Tom Lane) - - - - - - Fix ecpg's processing of nested structure pointer - variables (Muhammad Usama) - - - - - - Fix ecpg's ecpg_get_data function to - handle arrays properly (Michael Meskes) - - - - - - Make contrib/pageinspect's btree page inspection - functions take buffer locks while examining pages (Tom Lane) - - - - - - Ensure that make install for an extension creates the - extension installation directory (Cédric Villemain) - - - - Previously, this step was missed if MODULEDIR was set in - the extension's Makefile. - - - - - - Fix pgxs support for building loadable modules on AIX - (Tom Lane) - - - - Building modules outside the original source tree didn't work on AIX. - - - - - - Update time zone data files to tzdata release 2012j - for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western - Samoa, and portions of Brazil. - - - - - - - - - - Release 9.1.6 - - - Release date: - 2012-09-24 - - - - This release contains a variety of fixes from 9.1.5. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.6 - - - A dump/restore is not required for those running 9.1.X. - - - - However, you may need to perform REINDEX operations to - recover from the effects of the data corruption bug described in the - first changelog item below. - - - - Also, if you are upgrading from a version earlier than 9.1.4, - see . - - - - - - Changes - - - - - - Fix persistence marking of shared buffers during WAL replay - (Jeff Davis) - - - - This mistake can result in buffers not being written out during - checkpoints, resulting in data corruption if the server later crashes - without ever having written those buffers. Corruption can occur on - any server following crash recovery, but it is significantly more - likely to occur on standby slave servers since those perform much - more WAL replay. There is a low probability of corruption of btree - and GIN indexes. There is a much higher probability of corruption of - table visibility maps. Fortunately, visibility maps are - non-critical data in 9.1, so the worst consequence of such corruption - in 9.1 installations is transient inefficiency of vacuuming. Table - data proper cannot be corrupted by this bug. - - - - While no index corruption due to this bug is known to have occurred - in the field, as a precautionary measure it is recommended that - production installations REINDEX all btree and GIN - indexes at a convenient time after upgrading to 9.1.6. - - - - Also, if you intend to do an in-place upgrade to 9.2.X, before doing - so it is recommended to perform a VACUUM of all tables - while having vacuum_freeze_table_age - set to zero. This will ensure that any lingering wrong data in the - visibility maps is corrected before 9.2.X can depend on it. vacuum_cost_delay - can be adjusted to reduce the performance impact of vacuuming, while - causing it to take longer to finish. - - - - - - Fix planner's assignment of executor parameters, and fix executor's - rescan logic for CTE plan nodes (Tom Lane) - - - - These errors could result in wrong answers from queries that scan the - same WITH subquery multiple times. - - - - - - Fix misbehavior when default_transaction_isolation - is set to serializable (Kevin Grittner, Tom Lane, Heikki - Linnakangas) - - - - Symptoms include crashes at process start on Windows, and crashes in - hot standby operation. - - - - - - Improve selectivity estimation for text search queries involving - prefixes, i.e. word:* patterns (Tom Lane) - - - - - - Improve page-splitting decisions in GiST indexes (Alexander Korotkov, - Robert Haas, Tom Lane) - - - - Multi-column GiST indexes might suffer unexpected bloat due to this - error. - - - - - - Fix cascading privilege revoke to stop if privileges are still held - (Tom Lane) - - - - If we revoke a grant option from some role X, but - X still holds that option via a grant from someone - else, we should not recursively revoke the corresponding privilege - from role(s) Y that X had granted it - to. - - - - - - Disallow extensions from containing the schema they are assigned to - (Thom Brown) - - - - This situation creates circular dependencies that confuse - pg_dump and probably other things. It's confusing - for humans too, so disallow it. - - - - - - Improve error messages for Hot Standby misconfiguration errors - (Gurjeet Singh) - - - - - - Make configure probe for mbstowcs_l (Tom - Lane) - - - - This fixes build failures on some versions of AIX. - - - - - - Fix handling of SIGFPE when PL/Perl is in use (Andres Freund) - - - - Perl resets the process's SIGFPE handler to - SIG_IGN, which could result in crashes later on. Restore - the normal Postgres signal handler after initializing PL/Perl. - - - - - - Prevent PL/Perl from crashing if a recursive PL/Perl function is - redefined while being executed (Tom Lane) - - - - - - Work around possible misoptimization in PL/Perl (Tom Lane) - - - - Some Linux distributions contain an incorrect version of - pthread.h that results in incorrect compiled code in - PL/Perl, leading to crashes if a PL/Perl function calls another one - that throws an error. - - - - - - Fix bugs in contrib/pg_trgm's LIKE pattern - analysis code (Fujii Masao) - - - - LIKE queries using a trigram index could produce wrong - results if the pattern contained LIKE escape characters. - - - - - - Fix pg_upgrade's handling of line endings on Windows - (Andrew Dunstan) - - - - Previously, pg_upgrade might add or remove carriage - returns in places such as function bodies. - - - - - - On Windows, make pg_upgrade use backslash path - separators in the scripts it emits (Andrew Dunstan) - - - - - - Remove unnecessary dependency on pg_config from - pg_upgrade (Peter Eisentraut) - - - - - - Update time zone data files to tzdata release 2012f - for DST law changes in Fiji - - - - - - - - - - Release 9.1.5 - - - Release date: - 2012-08-17 - - - - This release contains a variety of fixes from 9.1.4. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.5 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.4, - see . - - - - - - Changes - - - - - - Prevent access to external files/URLs via XML entity references - (Noah Misch, Tom Lane) - - - - xml_parse() would attempt to fetch external files or - URLs as needed to resolve DTD and entity references in an XML value, - thus allowing unprivileged database users to attempt to fetch data - with the privileges of the database server. While the external data - wouldn't get returned directly to the user, portions of it could be - exposed in error messages if the data didn't parse as valid XML; and - in any case the mere ability to check existence of a file might be - useful to an attacker. (CVE-2012-3489) - - - - - - Prevent access to external files/URLs via contrib/xml2's - xslt_process() (Peter Eisentraut) - - - - libxslt offers the ability to read and write both - files and URLs through stylesheet commands, thus allowing - unprivileged database users to both read and write data with the - privileges of the database server. Disable that through proper use - of libxslt's security options. (CVE-2012-3488) - - - - Also, remove xslt_process()'s ability to fetch documents - and stylesheets from external files/URLs. While this was a - documented feature, it was long regarded as a bad idea. - The fix for CVE-2012-3489 broke that capability, and rather than - expend effort on trying to fix it, we're just going to summarily - remove it. - - - - - - Prevent too-early recycling of btree index pages (Noah Misch) - - - - When we allowed read-only transactions to skip assigning XIDs, we - introduced the possibility that a deleted btree page could be - recycled while a read-only transaction was still in flight to it. - This would result in incorrect index search results. The probability - of such an error occurring in the field seems very low because of the - timing requirements, but nonetheless it should be fixed. - - - - - - Fix crash-safety bug with newly-created-or-reset sequences (Tom Lane) - - - - If ALTER SEQUENCE was executed on a freshly created or - reset sequence, and then precisely one nextval() call - was made on it, and then the server crashed, WAL replay would restore - the sequence to a state in which it appeared that no - nextval() had been done, thus allowing the first - sequence value to be returned again by the next - nextval() call. In particular this could manifest for - serial columns, since creation of a serial column's sequence - includes an ALTER SEQUENCE OWNED BY step. - - - - - - Fix race condition in enum-type value comparisons (Robert - Haas, Tom Lane) - - - - Comparisons could fail when encountering an enum value added since - the current query started. - - - - - - Fix txid_current() to report the correct epoch when not - in hot standby (Heikki Linnakangas) - - - - This fixes a regression introduced in the previous minor release. - - - - - - Prevent selection of unsuitable replication connections as - the synchronous standby (Fujii Masao) - - - - The master might improperly choose pseudo-servers such as - pg_receivexlog or pg_basebackup - as the synchronous standby, and then wait indefinitely for them. - - - - - - Fix bug in startup of Hot Standby when a master transaction has many - subtransactions (Andres Freund) - - - - This mistake led to failures reported as out-of-order XID - insertion in KnownAssignedXids. - - - - - - Ensure the backup_label file is fsync'd after - pg_start_backup() (Dave Kerr) - - - - - - Fix timeout handling in walsender processes (Tom Lane) - - - - WAL sender background processes neglected to establish a - SIGALRM handler, meaning they would wait forever in - some corner cases where a timeout ought to happen. - - - - - - Wake walsenders after each background flush by walwriter (Andres - Freund, Simon Riggs) - - - - This greatly reduces replication delay when the workload contains - only asynchronously-committed transactions. - - - - - - Fix LISTEN/NOTIFY to cope better with I/O - problems, such as out of disk space (Tom Lane) - - - - After a write failure, all subsequent attempts to send more - NOTIFY messages would fail with messages like - Could not read from file "pg_notify/nnnn" at - offset nnnnn: Success. - - - - - - Only allow autovacuum to be auto-canceled by a directly blocked - process (Tom Lane) - - - - The original coding could allow inconsistent behavior in some cases; - in particular, an autovacuum could get canceled after less than - deadlock_timeout grace period. - - - - - - Improve logging of autovacuum cancels (Robert Haas) - - - - - - Fix log collector so that log_truncate_on_rotation works - during the very first log rotation after server start (Tom Lane) - - - - - - Fix WITH attached to a nested set operation - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Ensure that a whole-row reference to a subquery doesn't include any - extra GROUP BY or ORDER BY columns (Tom Lane) - - - - - - Fix dependencies generated during ALTER TABLE ... ADD - CONSTRAINT USING INDEX (Tom Lane) - - - - This command left behind a redundant pg_depend entry - for the index, which could confuse later operations, notably - ALTER TABLE ... ALTER COLUMN TYPE on one of the indexed - columns. - - - - - - Fix REASSIGN OWNED to work on extensions (Alvaro Herrera) - - - - - - Disallow copying whole-row references in CHECK - constraints and index definitions during CREATE TABLE - (Tom Lane) - - - - This situation can arise in CREATE TABLE with - LIKE or INHERITS. The copied whole-row - variable was incorrectly labeled with the row type of the original - table not the new one. Rejecting the case seems reasonable for - LIKE, since the row types might well diverge later. For - INHERITS we should ideally allow it, with an implicit - coercion to the parent table's row type; but that will require more - work than seems safe to back-patch. - - - - - - Fix memory leak in ARRAY(SELECT ...) subqueries (Heikki - Linnakangas, Tom Lane) - - - - - - Fix planner to pass correct collation to operator selectivity - estimators (Tom Lane) - - - - This was not previously required by any core selectivity estimation - function, but third-party code might need it. - - - - - - Fix extraction of common prefixes from regular expressions (Tom Lane) - - - - The code could get confused by quantified parenthesized - subexpressions, such as ^(foo)?bar. This would lead to - incorrect index optimization of searches for such patterns. - - - - - - Fix bugs with parsing signed - hh:mm and - hh:mm:ss - fields in interval constants (Amit Kapila, Tom Lane) - - - - - - Fix pg_dump to better handle views containing partial - GROUP BY lists (Tom Lane) - - - - A view that lists only a primary key column in GROUP BY, - but uses other table columns as if they were grouped, gets marked as - depending on the primary key. Improper handling of such primary key - dependencies in pg_dump resulted in poorly-ordered - dumps, which at best would be inefficient to restore and at worst - could result in outright failure of a parallel - pg_restore run. - - - - - - In PL/Perl, avoid setting UTF8 flag when in SQL_ASCII encoding - (Alex Hunsaker, Kyotaro Horiguchi, Alvaro Herrera) - - - - - - Use Postgres' encoding conversion functions, not Python's, when - converting a Python Unicode string to the server encoding in - PL/Python (Jan Urbanski) - - - - This avoids some corner-case problems, notably that Python doesn't - support all the encodings Postgres does. A notable functional change - is that if the server encoding is SQL_ASCII, you will get the UTF-8 - representation of the string; formerly, any non-ASCII characters in - the string would result in an error. - - - - - - Fix mapping of PostgreSQL encodings to Python encodings in PL/Python - (Jan Urbanski) - - - - - - Report errors properly in contrib/xml2's - xslt_process() (Tom Lane) - - - - - - Update time zone data files to tzdata release 2012e - for DST law changes in Morocco and Tokelau - - - - - - - - - - Release 9.1.4 - - - Release date: - 2012-06-04 - - - - This release contains a variety of fixes from 9.1.3. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.4 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you use the citext data type, and you upgraded - from a previous major release by running pg_upgrade, - you should run CREATE EXTENSION citext FROM unpackaged - to avoid collation-related failures in citext operations. - The same is necessary if you restore a dump from a pre-9.1 database - that contains an instance of the citext data type. - If you've already run the CREATE EXTENSION command before - upgrading to 9.1.4, you will instead need to do manual catalog updates - as explained in the third changelog item below. - - - - Also, if you are upgrading from a version earlier than 9.1.2, - see . - - - - - - Changes - - - - - - Fix incorrect password transformation in - contrib/pgcrypto's DES crypt() function - (Solar Designer) - - - - If a password string contained the byte value 0x80, the - remainder of the password was ignored, causing the password to be much - weaker than it appeared. With this fix, the rest of the string is - properly included in the DES hash. Any stored password values that are - affected by this bug will thus no longer match, so the stored values may - need to be updated. (CVE-2012-2143) - - - - - - Ignore SECURITY DEFINER and SET attributes for - a procedural language's call handler (Tom Lane) - - - - Applying such attributes to a call handler could crash the server. - (CVE-2012-2655) - - - - - - Make contrib/citext's upgrade script fix collations of - citext arrays and domains over citext - (Tom Lane) - - - - Release 9.1.2 provided a fix for collations of citext columns - and indexes in databases upgraded or reloaded from pre-9.1 - installations, but that fix was incomplete: it neglected to handle arrays - and domains over citext. This release extends the module's - upgrade script to handle these cases. As before, if you have already - run the upgrade script, you'll need to run the collation update - commands by hand instead. See the 9.1.2 release notes for more - information about doing this. - - - - - - Allow numeric timezone offsets in timestamp input to be up to - 16 hours away from UTC (Tom Lane) - - - - Some historical time zones have offsets larger than 15 hours, the - previous limit. This could result in dumped data values being rejected - during reload. - - - - - - Fix timestamp conversion to cope when the given time is exactly the - last DST transition time for the current timezone (Tom Lane) - - - - This oversight has been there a long time, but was not noticed - previously because most DST-using zones are presumed to have an - indefinite sequence of future DST transitions. - - - - - - Fix text to name and char to name - casts to perform string truncation correctly in multibyte encodings - (Karl Schnaitter) - - - - - - Fix memory copying bug in to_tsquery() (Heikki Linnakangas) - - - - - - Ensure txid_current() reports the correct epoch when - executed in hot standby (Simon Riggs) - - - - - - Fix planner's handling of outer PlaceHolderVars within subqueries (Tom - Lane) - - - - This bug concerns sub-SELECTs that reference variables coming from the - nullable side of an outer join of the surrounding query. - In 9.1, queries affected by this bug would fail with ERROR: - Upper-level PlaceHolderVar found where not expected. But in 9.0 and - 8.4, you'd silently get possibly-wrong answers, since the value - transmitted into the subquery wouldn't go to null when it should. - - - - - - Fix planning of UNION ALL subqueries with output columns - that are not simple variables (Tom Lane) - - - - Planning of such cases got noticeably worse in 9.1 as a result of a - misguided fix for MergeAppend child's targetlist doesn't match - MergeAppend errors. Revert that fix and do it another way. - - - - - - Fix slow session startup when pg_attribute is very large - (Tom Lane) - - - - If pg_attribute exceeds one-fourth of - shared_buffers, cache rebuilding code that is sometimes - needed during session start would trigger the synchronized-scan logic, - causing it to take many times longer than normal. The problem was - particularly acute if many new sessions were starting at once. - - - - - - Ensure sequential scans check for query cancel reasonably often (Merlin - Moncure) - - - - A scan encountering many consecutive pages that contain no live tuples - would not respond to interrupts meanwhile. - - - - - - Ensure the Windows implementation of PGSemaphoreLock() - clears ImmediateInterruptOK before returning (Tom Lane) - - - - This oversight meant that a query-cancel interrupt received later - in the same query could be accepted at an unsafe time, with - unpredictable but not good consequences. - - - - - - Show whole-row variables safely when printing views or rules - (Abbas Butt, Tom Lane) - - - - Corner cases involving ambiguous names (that is, the name could be - either a table or column name of the query) were printed in an - ambiguous way, risking that the view or rule would be interpreted - differently after dump and reload. Avoid the ambiguous case by - attaching a no-op cast. - - - - - - Fix COPY FROM to properly handle null marker strings that - correspond to invalid encoding (Tom Lane) - - - - A null marker string such as E'\\0' should work, and did - work in the past, but the case got broken in 8.4. - - - - - - Fix EXPLAIN VERBOSE for writable CTEs containing - RETURNING clauses (Tom Lane) - - - - - - Fix PREPARE TRANSACTION to work correctly in the presence - of advisory locks (Tom Lane) - - - - Historically, PREPARE TRANSACTION has simply ignored any - session-level advisory locks the session holds, but this case was - accidentally broken in 9.1. - - - - - - Fix truncation of unlogged tables (Robert Haas) - - - - - - Ignore missing schemas during non-interactive assignments of - search_path (Tom Lane) - - - - This re-aligns 9.1's behavior with that of older branches. Previously - 9.1 would throw an error for nonexistent schemas mentioned in - search_path settings obtained from places such as - ALTER DATABASE SET. - - - - - - Fix bugs with temporary or transient tables used in extension scripts - (Tom Lane) - - - - This includes cases such as a rewriting ALTER TABLE within - an extension update script, since that uses a transient table behind - the scenes. - - - - - - Ensure autovacuum worker processes perform stack depth checking - properly (Heikki Linnakangas) - - - - Previously, infinite recursion in a function invoked by - auto-ANALYZE could crash worker processes. - - - - - - Fix logging collector to not lose log coherency under high load (Andrew - Dunstan) - - - - The collector previously could fail to reassemble large messages if it - got too busy. - - - - - - Fix logging collector to ensure it will restart file rotation - after receiving SIGHUP (Tom Lane) - - - - - - Fix too many LWLocks taken failure in GiST indexes (Heikki - Linnakangas) - - - - - - Fix WAL replay logic for GIN indexes to not fail if the index was - subsequently dropped (Tom Lane) - - - - - - Correctly detect SSI conflicts of prepared transactions after a crash - (Dan Ports) - - - - - - Avoid synchronous replication delay when committing a transaction that - only modified temporary tables (Heikki Linnakangas) - - - - In such a case the transaction's commit record need not be flushed to - standby servers, but some of the code didn't know that and waited for - it to happen anyway. - - - - - - Fix error handling in pg_basebackup - (Thomas Ogrisegg, Fujii Masao) - - - - - - Fix walsender to not go into a busy loop if connection - is terminated (Fujii Masao) - - - - - - Fix memory leak in PL/pgSQL's RETURN NEXT command (Joe - Conway) - - - - - - Fix PL/pgSQL's GET DIAGNOSTICS command when the target - is the function's first variable (Tom Lane) - - - - - - Ensure that PL/Perl package-qualifies the _TD variable - (Alex Hunsaker) - - - - This bug caused trigger invocations to fail when they are nested - within a function invocation that changes the current package. - - - - - - Fix PL/Python functions returning composite types to accept a string - for their result value (Jan Urbanski) - - - - This case was accidentally broken by the 9.1 additions to allow a - composite result value to be supplied in other formats, such as - dictionaries. - - - - - - Fix potential access off the end of memory in psql's - expanded display (\x) mode (Peter Eisentraut) - - - - - - Fix several performance problems in pg_dump when - the database contains many objects (Jeff Janes, Tom Lane) - - - - pg_dump could get very slow if the database contained - many schemas, or if many objects are in dependency loops, or if there - are many owned sequences. - - - - - - Fix memory and file descriptor leaks in pg_restore - when reading a directory-format archive (Peter Eisentraut) - - - - - - Fix pg_upgrade for the case that a database stored in a - non-default tablespace contains a table in the cluster's default - tablespace (Bruce Momjian) - - - - - - In ecpg, fix rare memory leaks and possible overwrite - of one byte after the sqlca_t structure (Peter Eisentraut) - - - - - - Fix contrib/dblink's dblink_exec() to not leak - temporary database connections upon error (Tom Lane) - - - - - - Fix contrib/dblink to report the correct connection name in - error messages (Kyotaro Horiguchi) - - - - - - Fix contrib/vacuumlo to use multiple transactions when - dropping many large objects (Tim Lewis, Robert Haas, Tom Lane) - - - - This change avoids exceeding max_locks_per_transaction when - many objects need to be dropped. The behavior can be adjusted with the - new -l (limit) option. - - - - - - Update time zone data files to tzdata release 2012c - for DST law changes in Antarctica, Armenia, Chile, Cuba, Falkland - Islands, Gaza, Haiti, Hebron, Morocco, Syria, and Tokelau Islands; - also historical corrections for Canada. - - - - - - - - - - Release 9.1.3 - - - Release date: - 2012-02-27 - - - - This release contains a variety of fixes from 9.1.2. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.3 - - - A dump/restore is not required for those running 9.1.X. - - - - However, if you are upgrading from a version earlier than 9.1.2, - see . - - - - - - Changes - - - - - - Require execute permission on the trigger function for - CREATE TRIGGER (Robert Haas) - - - - This missing check could allow another user to execute a trigger - function with forged input data, by installing it on a table he owns. - This is only of significance for trigger functions marked - SECURITY DEFINER, since otherwise trigger functions run - as the table owner anyway. (CVE-2012-0866) - - - - - - Remove arbitrary limitation on length of common name in SSL - certificates (Heikki Linnakangas) - - - - Both libpq and the server truncated the common name - extracted from an SSL certificate at 32 bytes. Normally this would - cause nothing worse than an unexpected verification failure, but there - are some rather-implausible scenarios in which it might allow one - certificate holder to impersonate another. The victim would have to - have a common name exactly 32 bytes long, and the attacker would have - to persuade a trusted CA to issue a certificate in which the common - name has that string as a prefix. Impersonating a server would also - require some additional exploit to redirect client connections. - (CVE-2012-0867) - - - - - - Convert newlines to spaces in names written in pg_dump - comments (Robert Haas) - - - - pg_dump was incautious about sanitizing object names - that are emitted within SQL comments in its output script. A name - containing a newline would at least render the script syntactically - incorrect. Maliciously crafted object names could present a SQL - injection risk when the script is reloaded. (CVE-2012-0868) - - - - - - Fix btree index corruption from insertions concurrent with vacuuming - (Tom Lane) - - - - An index page split caused by an insertion could sometimes cause a - concurrently-running VACUUM to miss removing index entries - that it should remove. After the corresponding table rows are removed, - the dangling index entries would cause errors (such as could not - read block N in file ...) or worse, silently wrong query results - after unrelated rows are re-inserted at the now-free table locations. - This bug has been present since release 8.2, but occurs so infrequently - that it was not diagnosed until now. If you have reason to suspect - that it has happened in your database, reindexing the affected index - will fix things. - - - - - - Fix transient zeroing of shared buffers during WAL replay (Tom Lane) - - - - The replay logic would sometimes zero and refill a shared buffer, so - that the contents were transiently invalid. In hot standby mode this - can result in a query that's executing in parallel seeing garbage data. - Various symptoms could result from that, but the most common one seems - to be invalid memory alloc request size. - - - - - - Fix handling of data-modifying WITH subplans in - READ COMMITTED rechecking (Tom Lane) - - - - A WITH clause containing - INSERT/UPDATE/DELETE would crash - if the parent UPDATE or DELETE command needed - to be re-evaluated at one or more rows due to concurrent updates - in READ COMMITTED mode. - - - - - - Fix corner case in SSI transaction cleanup - (Dan Ports) - - - - When finishing up a read-write serializable transaction, - a crash could occur if all remaining active serializable transactions - are read-only. - - - - - - Fix postmaster to attempt restart after a hot-standby crash (Tom Lane) - - - - A logic error caused the postmaster to terminate, rather than attempt - to restart the cluster, if any backend process crashed while operating - in hot standby mode. - - - - - - Fix CLUSTER/VACUUM FULL handling of toast - values owned by recently-updated rows (Tom Lane) - - - - This oversight could lead to duplicate key value violates unique - constraint errors being reported against the toast table's index - during one of these commands. - - - - - - Update per-column permissions, not only per-table permissions, when - changing table owner (Tom Lane) - - - - Failure to do this meant that any previously granted column permissions - were still shown as having been granted by the old owner. This meant - that neither the new owner nor a superuser could revoke the - now-untraceable-to-table-owner permissions. - - - - - - Support foreign data wrappers and foreign servers in - REASSIGN OWNED (Alvaro Herrera) - - - - This command failed with unexpected classid errors if - it needed to change the ownership of any such objects. - - - - - - Allow non-existent values for some settings in ALTER - USER/DATABASE SET (Heikki Linnakangas) - - - - Allow default_text_search_config, - default_tablespace, and temp_tablespaces to be - set to names that are not known. This is because they might be known - in another database where the setting is intended to be used, or for the - tablespace cases because the tablespace might not be created yet. The - same issue was previously recognized for search_path, and - these settings now act like that one. - - - - - - Fix unsupported node type error caused by COLLATE - in an INSERT expression (Tom Lane) - - - - - - Avoid crashing when we have problems deleting table files post-commit - (Tom Lane) - - - - Dropping a table should lead to deleting the underlying disk files only - after the transaction commits. In event of failure then (for instance, - because of wrong file permissions) the code is supposed to just emit a - warning message and go on, since it's too late to abort the - transaction. This logic got broken as of release 8.4, causing such - situations to result in a PANIC and an unrestartable database. - - - - - - Recover from errors occurring during WAL replay of DROP - TABLESPACE (Tom Lane) - - - - Replay will attempt to remove the tablespace's directories, but there - are various reasons why this might fail (for example, incorrect - ownership or permissions on those directories). Formerly the replay - code would panic, rendering the database unrestartable without manual - intervention. It seems better to log the problem and continue, since - the only consequence of failure to remove the directories is some - wasted disk space. - - - - - - Fix race condition in logging AccessExclusiveLocks for hot standby - (Simon Riggs) - - - - Sometimes a lock would be logged as being held by transaction - zero. This is at least known to produce assertion failures on - slave servers, and might be the cause of more serious problems. - - - - - - Track the OID counter correctly during WAL replay, even when it wraps - around (Tom Lane) - - - - Previously the OID counter would remain stuck at a high value until the - system exited replay mode. The practical consequences of that are - usually nil, but there are scenarios wherein a standby server that's - been promoted to master might take a long time to advance the OID - counter to a reasonable value once values are needed. - - - - - - Prevent emitting misleading consistent recovery state reached - log message at the beginning of crash recovery (Heikki Linnakangas) - - - - - - Fix initial value of - pg_stat_replication.replay_location - (Fujii Masao) - - - - Previously, the value shown would be wrong until at least one WAL - record had been replayed. - - - - - - Fix regular expression back-references with * attached - (Tom Lane) - - - - Rather than enforcing an exact string match, the code would effectively - accept any string that satisfies the pattern sub-expression referenced - by the back-reference symbol. - - - - A similar problem still afflicts back-references that are embedded in a - larger quantified expression, rather than being the immediate subject - of the quantifier. This will be addressed in a future - PostgreSQL release. - - - - - - Fix recently-introduced memory leak in processing of - inet/cidr values (Heikki Linnakangas) - - - - A patch in the December 2011 releases of PostgreSQL - caused memory leakage in these operations, which could be significant - in scenarios such as building a btree index on such a column. - - - - - - Fix planner's ability to push down index-expression restrictions - through UNION ALL (Tom Lane) - - - - This type of optimization was inadvertently disabled by a fix for - another problem in 9.1.2. - - - - - - Fix planning of WITH clauses referenced in - UPDATE/DELETE on an inherited table - (Tom Lane) - - - - This bug led to could not find plan for CTE failures. - - - - - - Fix GIN cost estimation to handle column IN (...) - index conditions (Marti Raudsepp) - - - - This oversight would usually lead to crashes if such a condition could - be used with a GIN index. - - - - - - Prevent assertion failure when exiting a session with an open, failed - transaction (Tom Lane) - - - - This bug has no impact on normal builds with asserts not enabled. - - - - - - Fix dangling pointer after CREATE TABLE AS/SELECT - INTO in a SQL-language function (Tom Lane) - - - - In most cases this only led to an assertion failure in assert-enabled - builds, but worse consequences seem possible. - - - - - - Avoid double close of file handle in syslogger on Windows (MauMau) - - - - Ordinarily this error was invisible, but it would cause an exception - when running on a debug version of Windows. - - - - - - Fix I/O-conversion-related memory leaks in plpgsql - (Andres Freund, Jan Urbanski, Tom Lane) - - - - Certain operations would leak memory until the end of the current - function. - - - - - - Work around bug in perl's SvPVutf8() function (Andrew Dunstan) - - - - This function crashes when handed a typeglob or certain read-only - objects such as $^V. Make plperl avoid passing those to - it. - - - - - - In pg_dump, don't dump contents of an extension's - configuration tables if the extension itself is not being dumped - (Tom Lane) - - - - - - Improve pg_dump's handling of inherited table columns - (Tom Lane) - - - - pg_dump mishandled situations where a child column has - a different default expression than its parent column. If the default - is textually identical to the parent's default, but not actually the - same (for instance, because of schema search path differences) it would - not be recognized as different, so that after dump and restore the - child would be allowed to inherit the parent's default. Child columns - that are NOT NULL where their parent is not could also be - restored subtly incorrectly. - - - - - - Fix pg_restore's direct-to-database mode for - INSERT-style table data (Tom Lane) - - - - Direct-to-database restores from archive files made with - or options fail when - using pg_restore from a release dated September or - December 2011, as a result of an oversight in a fix for another - problem. The archive file itself is not at fault, and text-mode - output is okay. - - - - - - Teach pg_upgrade to handle renaming of - plpython's shared library (Bruce Momjian) - - - - Upgrading a pre-9.1 database that included plpython would fail because - of this oversight. - - - - - - Allow pg_upgrade to process tables containing - regclass columns (Bruce Momjian) - - - - Since pg_upgrade now takes care to preserve - pg_class OIDs, there was no longer any reason for this - restriction. - - - - - - Make libpq ignore ENOTDIR errors - when looking for an SSL client certificate file - (Magnus Hagander) - - - - This allows SSL connections to be established, though without a - certificate, even when the user's home directory is set to something - like /dev/null. - - - - - - Fix some more field alignment issues in ecpg's SQLDA area - (Zoltan Boszormenyi) - - - - - - Allow AT option in ecpg - DEALLOCATE statements (Michael Meskes) - - - - The infrastructure to support this has been there for awhile, but - through an oversight there was still an error check rejecting the case. - - - - - - Do not use the variable name when defining a varchar structure in ecpg - (Michael Meskes) - - - - - - Fix contrib/auto_explain's JSON output mode to produce - valid JSON (Andrew Dunstan) - - - - The output used brackets at the top level, when it should have used - braces. - - - - - - Fix error in contrib/intarray's int[] & - int[] operator (Guillaume Lelarge) - - - - If the smallest integer the two input arrays have in common is 1, - and there are smaller values in either array, then 1 would be - incorrectly omitted from the result. - - - - - - Fix error detection in contrib/pgcrypto's - encrypt_iv() and decrypt_iv() - (Marko Kreen) - - - - These functions failed to report certain types of invalid-input errors, - and would instead return random garbage values for incorrect input. - - - - - - Fix one-byte buffer overrun in contrib/test_parser - (Paul Guyot) - - - - The code would try to read one more byte than it should, which would - crash in corner cases. - Since contrib/test_parser is only example code, this is - not a security issue in itself, but bad example code is still bad. - - - - - - Use __sync_lock_test_and_set() for spinlocks on ARM, if - available (Martin Pitt) - - - - This function replaces our previous use of the SWPB - instruction, which is deprecated and not available on ARMv6 and later. - Reports suggest that the old code doesn't fail in an obvious way on - recent ARM boards, but simply doesn't interlock concurrent accesses, - leading to bizarre failures in multiprocess operation. - - - - - - Use option when building with - gcc versions that accept it (Andrew Dunstan) - - - - This prevents assorted scenarios wherein recent versions of gcc will - produce creative results. - - - - - - Allow use of threaded Python on FreeBSD (Chris Rees) - - - - Our configure script previously believed that this combination wouldn't - work; but FreeBSD fixed the problem, so remove that error check. - - - - - - Allow MinGW builds to use standardly-named OpenSSL libraries - (Tomasz Ostrowski) - - - - - - - - - - Release 9.1.2 - - - Release date: - 2011-12-05 - - - - This release contains a variety of fixes from 9.1.1. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.2 - - - A dump/restore is not required for those running 9.1.X. - - - - However, a longstanding error was discovered in the definition of the - information_schema.referential_constraints view. If you - rely on correct results from that view, you should replace its - definition as explained in the first changelog item below. - - - - Also, if you use the citext data type, and you upgraded - from a previous major release by running pg_upgrade, - you should run CREATE EXTENSION citext FROM unpackaged - to avoid collation-related failures in citext operations. - The same is necessary if you restore a dump from a pre-9.1 database - that contains an instance of the citext data type. - If you've already run the CREATE EXTENSION command before - upgrading to 9.1.2, you will instead need to do manual catalog updates - as explained in the second changelog item. - - - - - - Changes - - - - - - Fix bugs in information_schema.referential_constraints view - (Tom Lane) - - - - This view was being insufficiently careful about matching the - foreign-key constraint to the depended-on primary or unique key - constraint. That could result in failure to show a foreign key - constraint at all, or showing it multiple times, or claiming that it - depends on a different constraint than the one it really does. - - - - Since the view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can (as a superuser) drop the - information_schema schema then re-create it by sourcing - SHAREDIR/information_schema.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) This must be repeated in each database - to be fixed. - - - - - - Make contrib/citext's upgrade script fix collations of - citext columns and indexes (Tom Lane) - - - - Existing citext columns and indexes aren't correctly marked as - being of a collatable data type during pg_upgrade from - a pre-9.1 server, or when a pre-9.1 dump containing the citext - type is loaded into a 9.1 server. - That leads to operations on these columns failing with errors - such as could not determine which collation to use for string - comparison. This change allows them to be fixed by the same - script that upgrades the citext module into a proper 9.1 - extension during CREATE EXTENSION citext FROM unpackaged. - - - - If you have a previously-upgraded database that is suffering from this - problem, and you already ran the CREATE EXTENSION command, - you can manually run (as superuser) the UPDATE commands - found at the end of - SHAREDIR/extension/citext--unpackaged--1.0.sql. - (Run pg_config --sharedir if you're uncertain where - SHAREDIR is.) - There is no harm in doing this again if unsure. - - - - - - Fix possible crash during UPDATE or DELETE that - joins to the output of a scalar-returning function (Tom Lane) - - - - A crash could only occur if the target row had been concurrently - updated, so this problem surfaced only intermittently. - - - - - - Fix incorrect replay of WAL records for GIN index updates - (Tom Lane) - - - - This could result in transiently failing to find index entries after - a crash, or on a hot-standby server. The problem would be repaired - by the next VACUUM of the index, however. - - - - - - Fix TOAST-related data corruption during CREATE TABLE dest AS - SELECT * FROM src or INSERT INTO dest SELECT * FROM src - (Tom Lane) - - - - If a table has been modified by ALTER TABLE ADD COLUMN, - attempts to copy its data verbatim to another table could produce - corrupt results in certain corner cases. - The problem can only manifest in this precise form in 8.4 and later, - but we patched earlier versions as well in case there are other code - paths that could trigger the same bug. - - - - - - Fix possible failures during hot standby startup (Simon Riggs) - - - - - - Start hot standby faster when initial snapshot is incomplete - (Simon Riggs) - - - - - - Fix race condition during toast table access from stale syscache entries - (Tom Lane) - - - - The typical symptom was transient errors like missing chunk - number 0 for toast value NNNNN in pg_toast_2619, where the cited - toast table would always belong to a system catalog. - - - - - - Track dependencies of functions on items used in parameter default - expressions (Tom Lane) - - - - Previously, a referenced object could be dropped without having dropped - or modified the function, leading to misbehavior when the function was - used. Note that merely installing this update will not fix the missing - dependency entries; to do that, you'd need to CREATE OR - REPLACE each such function afterwards. If you have functions whose - defaults depend on non-built-in objects, doing so is recommended. - - - - - - Fix incorrect management of placeholder variables in nestloop joins - (Tom Lane) - - - - This bug is known to lead to variable not found in subplan target - list planner errors, and could possibly result in wrong query output - when outer joins are involved. - - - - - - Fix window functions that sort by expressions involving aggregates - (Tom Lane) - - - - Previously these could fail with could not find pathkey item to - sort planner errors. - - - - - - Fix MergeAppend child's targetlist doesn't match MergeAppend - planner errors (Tom Lane) - - - - - - Fix index matching for operators with both collatable and noncollatable - inputs (Tom Lane) - - - - In 9.1.0, an indexable operator that has a non-collatable left-hand - input type and a collatable right-hand input type would not be - recognized as matching the left-hand column's index. An example is - the hstore ? text operator. - - - - - - Allow inlining of set-returning SQL functions with multiple OUT - parameters (Tom Lane) - - - - - - Don't trust deferred-unique indexes for join removal (Tom Lane and Marti - Raudsepp) - - - - A deferred uniqueness constraint might not hold intra-transaction, - so assuming that it does could give incorrect query results. - - - - - - Make DatumGetInetP() unpack inet datums that have a 1-byte - header, and add a new macro, DatumGetInetPP(), that does - not (Heikki Linnakangas) - - - - This change affects no core code, but might prevent crashes in add-on - code that expects DatumGetInetP() to produce an unpacked - datum as per usual convention. - - - - - - Improve locale support in money type's input and output - (Tom Lane) - - - - Aside from not supporting all standard - lc_monetary - formatting options, the input and output functions were inconsistent, - meaning there were locales in which dumped money values could - not be re-read. - - - - - - Don't let transform_null_equals - affect CASE foo WHEN NULL ... constructs - (Heikki Linnakangas) - - - - transform_null_equals is only supposed to affect - foo = NULL expressions written directly by the user, not - equality checks generated internally by this form of CASE. - - - - - - Change foreign-key trigger creation order to better support - self-referential foreign keys (Tom Lane) - - - - For a cascading foreign key that references its own table, a row update - will fire both the ON UPDATE trigger and the - CHECK trigger as one event. The ON UPDATE - trigger must execute first, else the CHECK will check a - non-final state of the row and possibly throw an inappropriate error. - However, the firing order of these triggers is determined by their - names, which generally sort in creation order since the triggers have - auto-generated names following the convention - RI_ConstraintTrigger_NNNN. A proper fix would require - modifying that convention, which we will do in 9.2, but it seems risky - to change it in existing releases. So this patch just changes the - creation order of the triggers. Users encountering this type of error - should drop and re-create the foreign key constraint to get its - triggers into the right order. - - - - - - Fix IF EXISTS to work correctly in DROP OPERATOR - FAMILY (Robert Haas) - - - - - - Disallow dropping of an extension from within its own script - (Tom Lane) - - - - This prevents odd behavior in case of incorrect management of extension - dependencies. - - - - - - Don't mark auto-generated types as extension members (Robert Haas) - - - - Relation rowtypes and automatically-generated array types do not need to - have their own extension membership entries in pg_depend, - and creating such entries complicates matters for extension upgrades. - - - - - - Cope with invalid pre-existing search_path settings during - CREATE EXTENSION (Tom Lane) - - - - - - Avoid floating-point underflow while tracking buffer allocation rate - (Greg Matthews) - - - - While harmless in itself, on certain platforms this would result in - annoying kernel log messages. - - - - - - Prevent autovacuum transactions from running in serializable mode - (Tom Lane) - - - - Autovacuum formerly used the cluster-wide default transaction isolation - level, but there is no need for it to use anything higher than READ - COMMITTED, and using SERIALIZABLE could result in unnecessary delays - for other processes. - - - - - - Ensure walsender processes respond promptly to SIGTERM - (Magnus Hagander) - - - - - - Exclude postmaster.opts from base backups - (Magnus Hagander) - - - - - - Preserve configuration file name and line number values when starting - child processes under Windows (Tom Lane) - - - - Formerly, these would not be displayed correctly in the - pg_settings view. - - - - - - Fix incorrect field alignment in ecpg's SQLDA area - (Zoltan Boszormenyi) - - - - - - Preserve blank lines within commands in psql's command - history (Robert Haas) - - - - The former behavior could cause problems if an empty line was removed - from within a string literal, for example. - - - - - - Avoid platform-specific infinite loop in pg_dump - (Steve Singer) - - - - - - Fix compression of plain-text output format in pg_dump - (Adrian Klaver and Tom Lane) - - - - pg_dump has historically understood -Z with - no -F switch to mean that it should emit a gzip-compressed - version of its plain text output. Restore that behavior. - - - - - - Fix pg_dump to dump user-defined casts between - auto-generated types, such as table rowtypes (Tom Lane) - - - - - - Fix missed quoting of foreign server names in pg_dump - (Tom Lane) - - - - - - Assorted fixes for pg_upgrade (Bruce Momjian) - - - - Handle exclusion constraints correctly, avoid failures on Windows, - don't complain about mismatched toast table names in 8.4 databases. - - - - - - In PL/pgSQL, allow foreign tables to define row types - (Alexander Soudakov) - - - - - - Fix up conversions of PL/Perl functions' results - (Alex Hunsaker and Tom Lane) - - - - Restore the pre-9.1 behavior that PL/Perl functions returning - void ignore the result value of their last Perl statement; - 9.1.0 would throw an error if that statement returned a reference. - Also, make sure it works to return a string value for a composite type, - so long as the string meets the type's input format. - In addition, throw errors for attempts to return Perl arrays or hashes - when the function's declared result type is not an array or composite - type, respectively. (Pre-9.1 versions rather uselessly returned - strings like ARRAY(0x221a9a0) or - HASH(0x221aa90) in such cases.) - - - - - - Ensure PL/Perl strings are always correctly UTF8-encoded - (Amit Khandekar and Alex Hunsaker) - - - - - - Use the preferred version of xsubpp to build PL/Perl, - not necessarily the operating system's main copy - (David Wheeler and Alex Hunsaker) - - - - - - Correctly propagate SQLSTATE in PL/Python exceptions - (Mika Eloranta and Jan Urbanski) - - - - - - Do not install PL/Python extension files for Python major versions - other than the one built against (Peter Eisentraut) - - - - - - Change all the contrib extension script files to report - a useful error message if they are fed to psql - (Andrew Dunstan and Tom Lane) - - - - This should help teach people about the new method of using - CREATE EXTENSION to load these files. In most cases, - sourcing the scripts directly would fail anyway, but with - harder-to-interpret messages. - - - - - - Fix incorrect coding in contrib/dict_int and - contrib/dict_xsyn (Tom Lane) - - - - Some functions incorrectly assumed that memory returned by - palloc() is guaranteed zeroed. - - - - - - Remove contrib/sepgsql tests from the regular regression - test mechanism (Tom Lane) - - - - Since these tests require root privileges for setup, they're impractical - to run automatically. Switch over to a manual approach instead, and - provide a testing script to help with that. - - - - - - Fix assorted errors in contrib/unaccent's configuration - file parsing (Tom Lane) - - - - - - Honor query cancel interrupts promptly in pgstatindex() - (Robert Haas) - - - - - - Fix incorrect quoting of log file name in macOS start script - (Sidar Lopez) - - - - - - Revert unintentional enabling of WAL_DEBUG (Robert Haas) - - - - Fortunately, as debugging tools go, this one is pretty cheap; - but it's not intended to be enabled by default, so revert. - - - - - - Ensure VPATH builds properly install all server header files - (Peter Eisentraut) - - - - - - Shorten file names reported in verbose error messages (Peter Eisentraut) - - - - Regular builds have always reported just the name of the C file - containing the error message call, but VPATH builds formerly - reported an absolute path name. - - - - - - Fix interpretation of Windows timezone names for Central America - (Tom Lane) - - - - Map Central America Standard Time to CST6, not - CST6CDT, because DST is generally not observed anywhere in - Central America. - - - - - - Update time zone data files to tzdata release 2011n - for DST law changes in Brazil, Cuba, Fiji, Palestine, Russia, and Samoa; - also historical corrections for Alaska and British East Africa. - - - - - - - - - - Release 9.1.1 - - - Release date: - 2011-09-26 - - - - This release contains a small number of fixes from 9.1.0. - For information about new features in the 9.1 major release, see - . - - - - Migration to Version 9.1.1 - - - A dump/restore is not required for those running 9.1.X. - - - - - - Changes - - - - - - Make pg_options_to_table return NULL for an option with no - value (Tom Lane) - - - - Previously such cases would result in a server crash. - - - - - - Fix memory leak at end of a GiST index scan (Tom Lane) - - - - Commands that perform many separate GiST index scans, such as - verification of a new GiST-based exclusion constraint on a table - already containing many rows, could transiently require large amounts of - memory due to this leak. - - - - - - Fix explicit reference to pg_temp schema in CREATE - TEMPORARY TABLE (Robert Haas) - - - - This used to be allowed, but failed in 9.1.0. - - - - - - - - - - Release 9.1 - - - Release date: - 2011-09-12 - - - - Overview - - - This release shows PostgreSQL moving beyond the - traditional relational-database feature set with new, ground-breaking - functionality that is unique to PostgreSQL. - The streaming replication feature introduced in release 9.0 is - significantly enhanced by adding a synchronous-replication option, - streaming backups, and monitoring improvements. - Major enhancements include: - - - - - - - - - Allow synchronous - replication - - - - - - Add support for foreign - tables - - - - - - Add per-column collation support - - - - - - Add extensions which - simplify packaging of additions to PostgreSQL - - - - - - Add a true serializable isolation level - - - - - - Support unlogged tables using the UNLOGGED - option in CREATE - TABLE - - - - - - Allow data-modification commands - (INSERT/UPDATE/DELETE) in - WITH clauses - - - - - - Add nearest-neighbor (order-by-operator) searching to GiST indexes - - - - - - Add a SECURITY - LABEL command and support for - SELinux permissions control - - - - - - Update the PL/Python server-side - language - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.1 - - - A dump/restore using pg_dump, - or use of pg_upgrade, is required - for those wishing to migrate data from any previous - release. - - - - Version 9.1 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - Strings - - - - - - Change the default value of standard_conforming_strings - to on (Robert Haas) - - - - By default, backslashes are now ordinary characters in string literals, - not escape characters. This change removes a long-standing - incompatibility with the SQL standard. escape_string_warning - has produced warnings about this usage for years. E'' - strings are the proper way to embed backslash escapes in strings and are - unaffected by this change. - - - - - This change can break applications that are not expecting it and - do their own string escaping according to the old rules. The - consequences could be as severe as introducing SQL-injection security - holes. Be sure to test applications that are exposed to untrusted - input, to ensure that they correctly handle single quotes and - backslashes in text strings. - - - - - - - - - - Casting - - - - - - Disallow function-style and attribute-style data type casts for - composite types (Tom Lane) - - - - For example, disallow - composite_value.text and - text(composite_value). - Unintentional uses of this syntax have frequently resulted in bug - reports; although it was not a bug, it seems better to go back to - rejecting such expressions. - The CAST and :: syntaxes are still available - for use when a cast of an entire composite value is actually intended. - - - - - - Tighten casting checks for domains based on arrays (Tom Lane) - - - - When a domain is based on an array type, it is allowed to look - through the domain type to access the array elements, including - subscripting the domain value to fetch or assign an element. - Assignment to an element of such a domain value, for instance via - UPDATE ... SET domaincol[5] = ..., will now result in - rechecking the domain type's constraints, whereas before the checks - were skipped. - - - - - - - - - Arrays - - - - - - Change string_to_array() - to return an empty array for a zero-length string (Pavel - Stehule) - - - - Previously this returned a null value. - - - - - - Change string_to_array() - so a NULL separator splits the string into characters - (Pavel Stehule) - - - - Previously this returned a null value. - - - - - - - - - Object Modification - - - - - - Fix improper checks for before/after triggers (Tom Lane) - - - - Triggers can now be fired in three cases: BEFORE, - AFTER, or INSTEAD OF some action. - Trigger function authors should verify that their logic behaves - sanely in all three cases. - - - - - - Require superuser or CREATEROLE permissions in order to - set comments on roles (Tom Lane) - - - - - - - - - Server Settings - - - - - - Change pg_last_xlog_receive_location() - so it never moves backwards (Fujii Masao) - - - - Previously, the value of pg_last_xlog_receive_location() - could move backward when streaming replication is restarted. - - - - - - Have logging of replication connections honor log_connections - (Magnus Hagander) - - - - Previously, replication connections were always logged. - - - - - - - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - Change PL/pgSQL's RAISE command without parameters - to be catchable by the attached exception block (Piyush Newe) - - - - Previously RAISE in a code block was always scoped to - an attached exception block, so it was uncatchable at the same - scope. - - - - - - Adjust PL/pgSQL's error line numbering code to be consistent - with other PLs (Pavel Stehule) - - - - Previously, PL/pgSQL would ignore (not count) an empty line at the - start of the function body. Since this was inconsistent with all - other languages, the special case was removed. - - - - - - Make PL/pgSQL complain about conflicting IN and OUT parameter names - (Tom Lane) - - - - Formerly, the collision was not detected, and the name would just - silently refer to only the OUT parameter. - - - - - - Type modifiers of PL/pgSQL variables are now visible to the SQL parser - (Tom Lane) - - - - A type modifier (such as a varchar length limit) attached to a PL/pgSQL - variable was formerly enforced during assignments, but was ignored for - all other purposes. Such variables will now behave more like table - columns declared with the same modifier. This is not expected to make - any visible difference in most cases, but it could result in subtle - changes for some SQL commands issued by PL/pgSQL functions. - - - - - - - - - Contrib - - - - - - All contrib modules are now installed with CREATE EXTENSION - rather than by manually invoking their SQL scripts - (Dimitri Fontaine, Tom Lane) - - - - To update an existing database containing the 9.0 version of a contrib - module, use CREATE EXTENSION ... FROM unpackaged - to wrap the existing contrib module's objects into an extension. When - updating from a pre-9.0 version, drop the contrib module's objects - using its old uninstall script, then use CREATE EXTENSION. - - - - - - - - - Other Incompatibilities - - - - - - Make pg_stat_reset() - reset all database-level statistics (Tomas Vondra) - - - - Some pg_stat_database counters were not being reset. - - - - - - Fix some information_schema.triggers - column names to match the new SQL-standard names (Dean Rasheed) - - - - - - Treat ECPG cursor names as case-insensitive - (Zoltan Boszormenyi) - - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.1 and the previous major - release. - - - - Server - - - Performance - - - - - - Support unlogged tables using the UNLOGGED - option in CREATE - TABLE (Robert Haas) - - - - Such tables provide better update performance than regular tables, - but are not crash-safe: their contents are automatically cleared in - case of a server crash. Their contents do not propagate to - replication slaves, either. - - - - - - Allow FULL OUTER JOIN to be implemented as a - hash join, and allow either side of a LEFT OUTER JOIN - or RIGHT OUTER JOIN to be hashed (Tom Lane) - - - - Previously FULL OUTER JOIN could only be - implemented as a merge join, and LEFT OUTER JOIN - and RIGHT OUTER JOIN could hash only the nullable - side of the join. These changes provide additional query optimization - possibilities. - - - - - - Merge duplicate fsync requests (Robert Haas, Greg Smith) - - - - This greatly improves performance under heavy write loads. - - - - - - Improve performance of commit_siblings - (Greg Smith) - - - - This allows the use of commit_siblings with - less overhead. - - - - - - Reduce the memory requirement for large ispell dictionaries - (Pavel Stehule, Tom Lane) - - - - - - Avoid leaving data files open after blind writes - (Alvaro Herrera) - - - - This fixes scenarios in which backends might hold files open long - after they were deleted, preventing the kernel from reclaiming - disk space. - - - - - - - - - Optimizer - - - - - - Allow inheritance table scans to return meaningfully-sorted - results (Greg Stark, Hans-Jurgen Schonig, Robert Haas, Tom Lane) - - - - This allows better optimization of queries that use ORDER - BY, LIMIT, or MIN/MAX with - inherited tables. - - - - - - Improve GIN index scan cost estimation (Teodor Sigaev) - - - - - - Improve cost estimation for aggregates and window functions (Tom Lane) - - - - - - - - - Authentication - - - - - - Support host names and host suffixes - (e.g. .example.com) in pg_hba.conf - (Peter Eisentraut) - - - - Previously only host IP addresses and CIDR - values were supported. - - - - - - Support the key word all in the host column of pg_hba.conf - (Peter Eisentraut) - - - - Previously people used 0.0.0.0/0 or ::/0 - for this. - - - - - - Reject local lines in pg_hba.conf - on platforms that don't support Unix-socket connections - (Magnus Hagander) - - - - Formerly, such lines were silently ignored, which could be surprising. - This makes the behavior more like other unsupported cases. - - - - - - Allow GSSAPI - to be used to authenticate to servers via SSPI (Christian Ullrich) - - - - Specifically this allows Unix-based GSSAPI clients - to do SSPI authentication with Windows servers. - - - - - - ident - authentication over local sockets is now known as - peer - (Magnus Hagander) - - - - The old term is still accepted for backward compatibility, but since - the two methods are fundamentally different, it seemed better to adopt - different names for them. - - - - - - Rewrite peer - authentication to avoid use of credential control messages (Tom Lane) - - - - This change makes the peer authentication code simpler and - better-performing. However, it requires the platform to provide the - getpeereid function or an equivalent socket operation. - So far as is known, the only platform for which peer authentication - worked before and now will not is pre-5.0 NetBSD. - - - - - - - - - Monitoring - - - - - - Add details to the logging of restartpoints and checkpoints, - which is controlled by log_checkpoints - (Fujii Masao, Greg Smith) - - - - New details include WAL file and sync activity. - - - - - - Add log_file_mode - which controls the permissions on log files created by the - logging collector (Martin Pihlak) - - - - - - Reduce the default maximum line length for syslog - logging to 900 bytes plus prefixes (Noah Misch) - - - - This avoids truncation of long log lines on syslog implementations - that have a 1KB length limit, rather than the more common 2KB. - - - - - - - - - Statistical Views - - - - - - Add client_hostname column to pg_stat_activity - (Peter Eisentraut) - - - - Previously only the client address was reported. - - - - - - Add pg_stat_xact_* - statistics functions and views (Joel Jacobson) - - - - These are like the database-wide statistics counter views, but - reflect counts for only the current transaction. - - - - - - Add time of last reset in database-level and background writer - statistics views (Tomas Vondra) - - - - - - Add columns showing the number of vacuum and analyze operations - in pg_stat_*_tables - views (Magnus Hagander) - - - - - - Add buffers_backend_fsync column to pg_stat_bgwriter - (Greg Smith) - - - - This new column counts the number of times a backend fsyncs a - buffer. - - - - - - - - - Server Settings - - - - - - Provide auto-tuning of wal_buffers (Greg - Smith) - - - - By default, the value of wal_buffers is now chosen - automatically based on the value of shared_buffers. - - - - - - Increase the maximum values for - deadlock_timeout, - log_min_duration_statement, and - log_autovacuum_min_duration - (Peter Eisentraut) - - - - The maximum value for each of these parameters was previously - only about 35 minutes. Much larger values are now allowed. - - - - - - - - - - - Replication and Recovery - - - Streaming Replication and Continuous Archiving - - - - - - Allow synchronous - replication (Simon Riggs, Fujii Masao) - - - - This allows the primary server to wait for a standby to write a - transaction's information to disk before acknowledging the commit. - One standby at a time can take the role of the synchronous standby, - as controlled by the - synchronous_standby_names - setting. Synchronous replication can be enabled or disabled on a - per-transaction basis using the - synchronous_commit - setting. - - - - - - Add protocol support for sending file system backups to standby servers - using the streaming replication network connection (Magnus Hagander, - Heikki Linnakangas) - - - - This avoids the requirement of manually transferring a file - system backup when setting up a standby server. - - - - - - Add - replication_timeout - setting (Fujii Masao, Heikki Linnakangas) - - - - Replication connections that are idle for more than the - replication_timeout interval will be terminated - automatically. Formerly, a failed connection was typically not - detected until the TCP timeout elapsed, which is inconveniently - long in many situations. - - - - - - Add command-line tool pg_basebackup - for creating a new standby server or database backup (Magnus - Hagander) - - - - - - Add a replication permission - for roles (Magnus Hagander) - - - - This is a read-only permission used for streaming replication. - It allows a non-superuser role to be used for replication connections. - Previously only superusers could initiate replication - connections; superusers still have this permission by default. - - - - - - - - - Replication Monitoring - - - - - - Add system view pg_stat_replication - which displays activity of WAL sender processes (Itagaki - Takahiro, Simon Riggs) - - - - This reports the status of all connected standby servers. - - - - - - Add monitoring function pg_last_xact_replay_timestamp() - (Fujii Masao) - - - - This returns the time at which the primary generated the most - recent commit or abort record applied on the standby. - - - - - - - - - Hot Standby - - - - - - Add configuration parameter hot_standby_feedback - to enable standbys to postpone cleanup of old row versions on the - primary (Simon Riggs) - - - - This helps avoid canceling long-running queries on the standby. - - - - - - Add the pg_stat_database_conflicts - system view to show queries that have been canceled and the - reason (Magnus Hagander) - - - - Cancellations can occur because of dropped tablespaces, lock - timeouts, old snapshots, pinned buffers, and deadlocks. - - - - - - Add a conflicts count to pg_stat_database - (Magnus Hagander) - - - - This is the number of conflicts that occurred in the database. - - - - - - Increase the maximum values for - max_standby_archive_delay and - max_standby_streaming_delay - - - - The maximum value for each of these parameters was previously - only about 35 minutes. Much larger values are now allowed. - - - - - - Add ERRCODE_T_R_DATABASE_DROPPED - error code to report recovery conflicts due to dropped databases - (Tatsuo Ishii) - - - - This is useful for connection pooling software. - - - - - - - - - Recovery Control - - - - - - Add functions to control streaming replication replay (Simon Riggs) - - - - The new functions are pg_xlog_replay_pause(), - pg_xlog_replay_resume(), - and the status function pg_is_xlog_replay_paused(). - - - - - - Add recovery.conf setting - pause_at_recovery_target - to pause recovery at target (Simon Riggs) - - - - This allows a recovery server to be queried to check whether - the recovery point is the one desired. - - - - - - Add the ability to create named restore points using pg_create_restore_point() - (Jaime Casanova) - - - - These named restore points can be specified as recovery - targets using the new recovery.conf setting - recovery_target_name. - - - - - - Allow standby recovery to switch to a new timeline automatically - (Heikki Linnakangas) - - - - Now standby servers scan the archive directory for new - timelines periodically. - - - - - - Add restart_after_crash - setting which disables automatic server restart after a backend - crash (Robert Haas) - - - - This allows external cluster management software to control - whether the database server restarts or not. - - - - - - Allow recovery.conf - to use the same quoting behavior as postgresql.conf - (Dimitri Fontaine) - - - - Previously all values had to be quoted. - - - - - - - - - - - Queries - - - - - - Add a true serializable isolation level - (Kevin Grittner, Dan Ports) - - - - Previously, asking for serializable isolation guaranteed only that a - single MVCC snapshot would be used for the entire transaction, which - allowed certain documented anomalies. The old snapshot isolation - behavior is still available by requesting the REPEATABLE READ - isolation level. - - - - - - Allow data-modification commands - (INSERT/UPDATE/DELETE) in - WITH clauses - (Marko Tiikkaja, Hitoshi Harada) - - - - These commands can use RETURNING to pass data up to the - containing query. - - - - - - Allow WITH - clauses to be attached to INSERT, UPDATE, - DELETE statements (Marko Tiikkaja, Hitoshi Harada) - - - - - - Allow non-GROUP - BY columns in the query target list when the primary - key is specified in the GROUP BY clause (Peter - Eisentraut) - - - - The SQL standard allows this behavior, and - because of the primary key, the result is unambiguous. - - - - - - Allow use of the key word DISTINCT in UNION/INTERSECT/EXCEPT - clauses (Tom Lane) - - - - DISTINCT is the default behavior so use of this - key word is redundant, but the SQL standard allows it. - - - - - - Fix ordinary queries with rules to use the same snapshot behavior - as EXPLAIN ANALYZE (Marko Tiikkaja) - - - - Previously EXPLAIN ANALYZE used slightly different - snapshot timing for queries involving rules. The - EXPLAIN ANALYZE behavior was judged to be more logical. - - - - - - - Strings - - - - - - Add per-column collation support - (Peter Eisentraut, Tom Lane) - - - - Previously collation (the sort ordering of text strings) could only be - chosen at database creation. - Collation can now be set per column, domain, index, or - expression, via the SQL-standard COLLATE clause. - - - - - - - - - - - Object Manipulation - - - - - - Add extensions which - simplify packaging of additions to PostgreSQL - (Dimitri Fontaine, Tom Lane) - - - - Extensions are controlled by the new CREATE/ALTER/DROP EXTENSION - commands. This replaces ad-hoc methods of grouping objects that - are added to a PostgreSQL installation. - - - - - - Add support for foreign - tables (Shigeru Hanada, Robert Haas, Jan Urbanski, - Heikki Linnakangas) - - - - This allows data stored outside the database to be used like - native PostgreSQL-stored data. Foreign tables - are currently read-only, however. - - - - - - Allow new values to be added to an existing enum type via - ALTER TYPE (Andrew - Dunstan) - - - - - - Add ALTER TYPE ... - ADD/DROP/ALTER/RENAME ATTRIBUTE (Peter Eisentraut) - - - - This allows modification of composite types. - - - - - - - <command>ALTER</command> Object - - - - - - Add RESTRICT/CASCADE to ALTER TYPE operations - on typed tables (Peter Eisentraut) - - - - This controls - ADD/DROP/ALTER/RENAME - ATTRIBUTE cascading behavior. - - - - - - Support ALTER TABLE name {OF | NOT OF} - type - (Noah Misch) - - - - This syntax allows a standalone table to be made into a typed table, - or a typed table to be made standalone. - - - - - - Add support for more object types in ALTER ... SET - SCHEMA commands (Dimitri Fontaine) - - - - This command is now supported for conversions, operators, operator - classes, operator families, text search configurations, text search - dictionaries, text search parsers, and text search templates. - - - - - - - - - <link linkend="sql-createtable"><command>CREATE/ALTER TABLE</command></link> - - - - - - Add ALTER TABLE ... - ADD UNIQUE/PRIMARY KEY USING INDEX - (Gurjeet Singh) - - - - This allows a primary key or unique constraint to be defined using an - existing unique index, including a concurrently created unique index. - - - - - - Allow ALTER TABLE - to add foreign keys without validation (Simon Riggs) - - - - The new option is called NOT VALID. The constraint's - state can later be modified to VALIDATED and validation - checks performed. Together these allow you to add a foreign key - with minimal impact on read and write operations. - - - - - - Allow ALTER TABLE - ... SET DATA TYPE to avoid table rewrites in - appropriate cases (Noah Misch, Robert Haas) - - - - For example, converting a varchar column to - text no longer requires a rewrite of the table. - However, increasing the length constraint on a - varchar column still requires a table rewrite. - - - - - - Add CREATE TABLE IF - NOT EXISTS syntax (Robert Haas) - - - - This allows table creation without causing an error if the - table already exists. - - - - - - Fix possible tuple concurrently updated error - when two backends attempt to add an inheritance - child to the same table at the same time (Robert Haas) - - - - ALTER TABLE - now takes a stronger lock on the parent table, so that the sessions - cannot try to update it simultaneously. - - - - - - - - - Object Permissions - - - - - - Add a SECURITY - LABEL command (KaiGai Kohei) - - - - This allows security labels to be assigned to objects. - - - - - - - - - - - Utility Operations - - - - - - Add transaction-level advisory - locks (Marko Tiikkaja) - - - - These are similar to the existing session-level advisory locks, - but such locks are automatically released at transaction end. - - - - - - Make TRUNCATE ... RESTART - IDENTITY restart sequences transactionally (Steve - Singer) - - - - Previously the counter could have been left out of sync if a - backend crashed between the on-commit truncation activity and - commit completion. - - - - - - - <link linkend="sql-copy"><command>COPY</command></link> - - - - - - Add ENCODING option to COPY TO/FROM (Hitoshi - Harada, Itagaki Takahiro) - - - - This allows the encoding of the COPY file to be - specified separately from client encoding. - - - - - - Add bidirectional COPY - protocol support (Fujii Masao) - - - - This is currently only used by streaming replication. - - - - - - - - - <link linkend="sql-explain"><command>EXPLAIN</command></link> - - - - - - Make EXPLAIN VERBOSE show the function call expression - in a FunctionScan node (Tom Lane) - - - - - - - - - <link linkend="sql-vacuum"><command>VACUUM</command></link> - - - - - - Add additional details to the output of VACUUM FULL VERBOSE - and CLUSTER VERBOSE - (Itagaki Takahiro) - - - - New information includes the live and dead tuple count and - whether CLUSTER is using an index to rebuild. - - - - - - Prevent autovacuum from - waiting if it cannot acquire a table lock (Robert Haas) - - - - It will try to vacuum that table later. - - - - - - - - - <link linkend="sql-cluster"><command>CLUSTER</command></link> - - - - - - Allow CLUSTER to sort the table rather than scanning - the index when it seems likely to be cheaper (Leonardo Francalanci) - - - - - - - - - Indexes - - - - - - Add nearest-neighbor (order-by-operator) searching to GiST indexes (Teodor Sigaev, Tom Lane) - - - - This allows GiST indexes to quickly return the - N closest values in a query with LIMIT. - For example - point '(101,456)' LIMIT 10; -]]> - - finds the ten places closest to a given target point. - - - - - - Allow GIN indexes to index null - and empty values (Tom Lane) - - - - This allows full GIN index scans, and fixes various - corner cases in which GIN scans would fail. - - - - - - Allow GIN indexes to - better recognize duplicate search entries (Tom Lane) - - - - This reduces the cost of index scans, especially in cases where - it avoids unnecessary full index scans. - - - - - - Fix GiST indexes to be fully - crash-safe (Heikki Linnakangas) - - - - Previously there were rare cases where a REINDEX - would be required (you would be informed). - - - - - - - - - - - Data Types - - - - - - Allow numeric to use a more compact, two-byte header - in common cases (Robert Haas) - - - - Previously all numeric values had four-byte headers; - this change saves on disk storage. - - - - - - Add support for dividing money by money - (Andy Balholm) - - - - - - Allow binary I/O on type void (Radoslaw Smogura) - - - - - - Improve hypotenuse calculations for geometric operators (Paul Matthews) - - - - This avoids unnecessary overflows, and may also be more accurate. - - - - - - Support hashing array values (Tom Lane) - - - - This provides additional query optimization possibilities. - - - - - - Don't treat a composite type as sortable unless all its column types - are sortable (Tom Lane) - - - - This avoids possible could not identify a comparison function - failures at runtime, if it is possible to implement the query without - sorting. Also, ANALYZE won't try to use inappropriate - statistics-gathering methods for columns of such composite types. - - - - - - - Casting - - - - - - Add support for casting between money and numeric - (Andy Balholm) - - - - - - Add support for casting from int4 and int8 - to money (Joey Adams) - - - - - - Allow casting a table's row type to the table's supertype if - it's a typed table (Peter Eisentraut) - - - - This is analogous to the existing facility that allows casting a row - type to a supertable's row type. - - - - - - - - - <link linkend="functions-xml"><acronym>XML</acronym></link> - - - - - - Add XML function XMLEXISTS and xpath_exists() - functions (Mike Fowler) - - - - These are used for XPath matching. - - - - - - Add XML functions xml_is_well_formed(), - xml_is_well_formed_document(), - xml_is_well_formed_content() - (Mike Fowler) - - - - These check whether the input is properly-formed XML. - They provide functionality that was previously available only in - the deprecated contrib/xml2 module. - - - - - - - - - - - Functions - - - - - - Add SQL function format(text, ...), which - behaves analogously to C's printf() (Pavel Stehule, - Robert Haas) - - - - It currently supports formats for strings, SQL literals, and - SQL identifiers. - - - - - - Add string functions concat(), - concat_ws(), - left(), - right(), - and reverse() - (Pavel Stehule) - - - - These improve compatibility with other database products. - - - - - - Add function pg_read_binary_file() - to read binary files (Dimitri Fontaine, Itagaki Takahiro) - - - - - - Add a single-parameter version of function pg_read_file() - to read an entire file (Dimitri Fontaine, Itagaki Takahiro) - - - - - - Add three-parameter forms of array_to_string() - and string_to_array() - for null value processing control (Pavel Stehule) - - - - - - - Object Information Functions - - - - - - Add the pg_describe_object() - function (Alvaro Herrera) - - - - This function is used to obtain a human-readable string describing - an object, based on the pg_class - OID, object OID, and sub-object ID. It can be used to help - interpret the contents of pg_depend. - - - - - - Update comments for built-in operators and their underlying - functions (Tom Lane) - - - - Functions that are meant to be used via an associated operator - are now commented as such. - - - - - - Add variable quote_all_identifiers - to force the quoting of all identifiers in EXPLAIN - and in system catalog functions like pg_get_viewdef() - (Robert Haas) - - - - This makes exporting schemas to tools and other databases with - different quoting rules easier. - - - - - - Add columns to the information_schema.sequences - system view (Peter Eisentraut) - - - - Previously, though the view existed, the columns about the - sequence parameters were unimplemented. - - - - - - Allow public as a pseudo-role name in has_table_privilege() - and related functions (Alvaro Herrera) - - - - This allows checking for public permissions. - - - - - - - - - Function and Trigger Creation - - - - - - Support INSTEAD - OF triggers on views (Dean Rasheed) - - - - This feature can be used to implement fully updatable views. - - - - - - - - - - - Server-Side Languages - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - Add FOREACH IN - ARRAY to PL/pgSQL - (Pavel Stehule) - - - - This is more efficient and readable than previous methods of - iterating through the elements of an array value. - - - - - - Allow RAISE without parameters to be caught in - the same places that could catch a RAISE ERROR - from the same location (Piyush Newe) - - - - The previous coding threw the error - from the block containing the active exception handler. - The new behavior is more consistent with other DBMS products. - - - - - - - - - <link linkend="plperl">PL/Perl</link> Server-Side Language - - - - - - Allow generic record arguments to PL/Perl functions (Andrew - Dunstan) - - - - PL/Perl functions can now be declared to accept type record. - The behavior is the same as for any named composite type. - - - - - - Convert PL/Perl array arguments to Perl arrays (Alexey Klyukin, - Alex Hunsaker) - - - - String representations are still available. - - - - - - Convert PL/Perl composite-type arguments to Perl hashes - (Alexey Klyukin, Alex Hunsaker) - - - - String representations are still available. - - - - - - - - - <link linkend="plpython">PL/Python</link> Server-Side Language - - - - - - Add table function support for PL/Python (Jan Urbanski) - - - - PL/Python can now return multiple OUT parameters - and record sets. - - - - - - Add a validator to PL/Python (Jan Urbanski) - - - - This allows PL/Python functions to be syntax-checked at function - creation time. - - - - - - Allow exceptions for SQL queries in PL/Python (Jan Urbanski) - - - - This allows access to SQL-generated exception error codes from - PL/Python exception blocks. - - - - - - Add explicit subtransactions to PL/Python (Jan Urbanski) - - - - - - Add PL/Python functions for quoting strings (Jan Urbanski) - - - - These functions are plpy.quote_ident, - plpy.quote_literal, - and plpy.quote_nullable. - - - - - - Add traceback information to PL/Python errors (Jan Urbanski) - - - - - - Report PL/Python errors from iterators with PLy_elog (Jan - Urbanski) - - - - - - Fix exception handling with Python 3 (Jan Urbanski) - - - - Exception classes were previously not available in - plpy under Python 3. - - - - - - - - - - - Client Applications - - - - - - Mark createlang and droplang - as deprecated now that they just invoke extension commands (Tom - Lane) - - - - - - - <link linkend="app-psql"><application>psql</application></link> - - - - - - Add psql command \conninfo - to show current connection information (David Christensen) - - - - - - Add psql command \sf to - show a function's definition (Pavel Stehule) - - - - - - Add psql command \dL to list - languages (Fernando Ike) - - - - - - Add the (system) option to psql's - \dn (list schemas) command (Tom Lane) - - - - \dn without S now suppresses system - schemas. - - - - - - Allow psql's \e and \ef - commands to accept a line number to be used to position the - cursor in the editor (Pavel Stehule) - - - - This is passed to the editor according to the - PSQL_EDITOR_LINENUMBER_ARG environment variable. - - - - - - Have psql set the client encoding from the - operating system locale by default (Heikki Linnakangas) - - - - This only happens if the PGCLIENTENCODING environment - variable is not set. - - - - - - Make \d distinguish between unique - indexes and unique constraints (Josh Kupershmidt) - - - - - - Make \dt+ report pg_table_size - instead of pg_relation_size when talking to 9.0 or - later servers (Bernd Helmle) - - - - This is a more useful measure of table size, but note that it is - not identical to what was previously reported in the same display. - - - - - - Additional tab completion support (Itagaki Takahiro, Pavel Stehule, - Andrey Popp, Christoph Berg, David Fetter, Josh Kupershmidt) - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> - - - - - - Add pg_dump - and pg_dumpall - option to force quoting - of all identifiers (Robert Haas) - - - - - - Add directory format to pg_dump - (Joachim Wieland, Heikki Linnakangas) - - - - This is internally similar to the tar - pg_dump format. - - - - - - - - - <link linkend="app-pg-ctl"><application>pg_ctl</application></link> - - - - - - Fix pg_ctl - so it no longer incorrectly reports that the server is not - running (Bruce Momjian) - - - - Previously this could happen if the server was running but - pg_ctl could not authenticate. - - - - - - Improve pg_ctl start's wait - () option (Bruce Momjian, Tom Lane) - - - - The wait mode is now significantly more robust. It will not get - confused by non-default postmaster port numbers, non-default - Unix-domain socket locations, permission problems, or stale - postmaster lock files. - - - - - - Add promote option to pg_ctl to - switch a standby server to primary (Fujii Masao) - - - - - - - - - - - <application>Development Tools</application> - - - <link linkend="libpq"><application>libpq</application></link> - - - - - - Add a libpq connection option client_encoding - which behaves like the PGCLIENTENCODING environment - variable (Heikki Linnakangas) - - - - The value auto sets the client encoding based on - the operating system locale. - - - - - - Add PQlibVersion() - function which returns the libpq library version (Magnus - Hagander) - - - - libpq already had PQserverVersion() which returns - the server version. - - - - - - Allow libpq-using clients to - check the user name of the server process - when connecting via Unix-domain sockets, with the new requirepeer - connection option - (Peter Eisentraut) - - - - PostgreSQL already allowed servers to check - the client user name when connecting via Unix-domain sockets. - - - - - - Add PQping() - and PQpingParams() - to libpq (Bruce Momjian, Tom Lane) - - - - These functions allow detection of the server's status without - trying to open a new session. - - - - - - - - - <link linkend="ecpg"><application>ECPG</application></link> - - - - - - Allow ECPG to accept dynamic cursor names even in - WHERE CURRENT OF clauses - (Zoltan Boszormenyi) - - - - - - Make ecpglib write double values with a - precision of 15 digits, not 14 as formerly (Akira Kurosawa) - - - - - - - - - - Build Options - - - - - - Use +Olibmerrno compile flag with HP-UX C compilers - that accept it (Ibrar Ahmed) - - - - This avoids possible misbehavior of math library calls on recent - HP platforms. - - - - - - - Makefiles - - - - - - Improved parallel make support (Peter Eisentraut) - - - - This allows for faster compiles. Also, make -k - now works more consistently. - - - - - - Require GNU make - 3.80 or newer (Peter Eisentraut) - - - - This is necessary because of the parallel-make improvements. - - - - - - Add make maintainer-check target - (Peter Eisentraut) - - - - This target performs various source code checks that are not - appropriate for either the build or the regression tests. Currently: - duplicate_oids, SGML syntax and tabs check, NLS syntax check. - - - - - - Support make check in contrib - (Peter Eisentraut) - - - - Formerly only make installcheck worked, but now - there is support for testing in a temporary installation. - The top-level make check-world target now includes - testing contrib this way. - - - - - - - - - Windows - - - - - - On Windows, allow pg_ctl to register - the service as auto-start or start-on-demand (Quan Zongliang) - - - - - - Add support for collecting crash - dumps on Windows (Craig Ringer, Magnus Hagander) - - - - minidumps can now be generated by non-debug - Windows binaries and analyzed by standard debugging tools. - - - - - - Enable building with the MinGW64 compiler (Andrew Dunstan) - - - - This allows building 64-bit Windows binaries even on non-Windows - platforms via cross-compiling. - - - - - - - - - - - Source Code - - - - - - Revise the API for GUC variable assign hooks (Tom Lane) - - - - The previous functions of assign hooks are now split between check - hooks and assign hooks, where the former can fail but the latter - shouldn't. This change will impact add-on modules that define custom - GUC parameters. - - - - - - Add latches to the source code to support waiting for events (Heikki - Linnakangas) - - - - - - Centralize data modification permissions-checking logic - (KaiGai Kohei) - - - - - - Add missing get_object_oid() functions, for consistency - (Robert Haas) - - - - - - Improve ability to use C++ compilers for compiling add-on modules by removing - conflicting key words (Tom Lane) - - - - - - Add support for DragonFly BSD (Rumko) - - - - - - Expose quote_literal_cstr() for backend use - (Robert Haas) - - - - - - Run regression tests in the - default encoding (Peter Eisentraut) - - - - Regression tests were previously always run with - SQL_ASCII encoding. - - - - - - Add src/tools/git_changelog to replace - cvs2cl and pgcvslog (Robert - Haas, Tom Lane) - - - - - - Add git-external-diff script to - src/tools (Bruce Momjian) - - - - This is used to generate context diffs from git. - - - - - - Improve support for building with - Clang (Peter Eisentraut) - - - - - - - Server Hooks - - - - - - Add source code hooks to check permissions (Robert Haas, - Stephen Frost) - - - - - - Add post-object-creation function hooks for use by security - frameworks (KaiGai Kohei) - - - - - - Add a client authentication hook (KaiGai Kohei) - - - - - - - - - - - Contrib - - - - - - Modify contrib modules and procedural - languages to install via the new extension mechanism (Tom Lane, - Dimitri Fontaine) - - - - - - Add contrib/file_fdw - foreign-data wrapper (Shigeru Hanada) - - - - Foreign tables using this foreign data wrapper can read flat files - in a manner very similar to COPY. - - - - - - Add nearest-neighbor search support to contrib/pg_trgm and contrib/btree_gist - (Teodor Sigaev) - - - - - - Add contrib/btree_gist - support for searching on not-equals (Jeff Davis) - - - - - - Fix contrib/fuzzystrmatch's - levenshtein() function to handle multibyte characters - (Alexander Korotkov) - - - - - - Add ssl_cipher() and ssl_version() - functions to contrib/sslinfo (Robert - Haas) - - - - - - Fix contrib/intarray - and contrib/hstore - to give consistent results with indexed empty arrays (Tom Lane) - - - - Previously an empty-array query that used an index might return - different results from one that used a sequential scan. - - - - - - Allow contrib/intarray - to work properly on multidimensional arrays (Tom Lane) - - - - - - In - contrib/intarray, - avoid errors complaining about the presence of nulls in cases where no - nulls are actually present (Tom Lane) - - - - - - In - contrib/intarray, - fix behavior of containment operators with respect to empty arrays - (Tom Lane) - - - - Empty arrays are now correctly considered to be contained in any other - array. - - - - - - Remove contrib/xml2's - arbitrary limit on the number of - parameter=value pairs that can be - handled by xslt_process() (Pavel Stehule) - - - - The previous limit was 10. - - - - - - In contrib/pageinspect, - fix heap_page_item to return infomasks as 32-bit values (Alvaro Herrera) - - - - This avoids returning negative values, which was confusing. The - underlying value is a 16-bit unsigned integer. - - - - - - - Security - - - - - - Add contrib/sepgsql - to interface permission checks with SELinux (KaiGai Kohei) - - - - This uses the new SECURITY LABEL - facility. - - - - - - Add contrib module auth_delay (KaiGai - Kohei) - - - - This causes the server to pause before returning authentication - failure; it is designed to make brute force password attacks - more difficult. - - - - - - Add dummy_seclabel - contrib module (KaiGai Kohei) - - - - This is used for permission regression testing. - - - - - - - - - Performance - - - - - - Add support for LIKE and ILIKE index - searches to contrib/pg_trgm (Alexander - Korotkov) - - - - - - Add levenshtein_less_equal() function to contrib/fuzzystrmatch, - which is optimized for small distances (Alexander Korotkov) - - - - - - Improve performance of index lookups on contrib/seg columns (Alexander - Korotkov) - - - - - - Improve performance of pg_upgrade for - databases with many relations (Bruce Momjian) - - - - - - Add flag to contrib/pgbench to - report per-statement latencies (Florian Pflug) - - - - - - - - - Fsync Testing - - - - - - Move src/tools/test_fsync to contrib/pg_test_fsync - (Bruce Momjian, Tom Lane) - - - - - - Add O_DIRECT support to contrib/pg_test_fsync - (Bruce Momjian) - - - - This matches the use of O_DIRECT by wal_sync_method. - - - - - - Add new tests to contrib/pg_test_fsync - (Bruce Momjian) - - - - - - - - - - - Documentation - - - - - - Extensive ECPG - documentation improvements (Satoshi Nagayasu) - - - - - - Extensive proofreading and documentation improvements - (Thom Brown, Josh Kupershmidt, Susanne Ebrecht) - - - - - - Add documentation for exit_on_error - (Robert Haas) - - - - This parameter causes sessions to exit on any error. - - - - - - Add documentation for pg_options_to_table() - (Josh Berkus) - - - - This function shows table storage options in a readable form. - - - - - - Document that it is possible to access all composite type - fields using (compositeval).* - syntax (Peter Eisentraut) - - - - - - Document that translate() - removes characters in from that don't have a - corresponding to character (Josh Kupershmidt) - - - - - - Merge documentation for CREATE CONSTRAINT TRIGGER and CREATE TRIGGER - (Alvaro Herrera) - - - - - - Centralize permission and upgrade documentation (Bruce Momjian) - - - - - - Add kernel tuning - documentation for Solaris 10 (Josh Berkus) - - - - Previously only Solaris 9 kernel tuning was documented. - - - - - - Handle non-ASCII characters consistently in HISTORY file - (Peter Eisentraut) - - - - While the HISTORY file is in English, we do have to deal - with non-ASCII letters in contributor names. These are now - transliterated so that they are reasonably legible without assumptions - about character set. - - - - - - - - - diff --git a/doc/src/sgml/release-9.2.sgml b/doc/src/sgml/release-9.2.sgml deleted file mode 100644 index 1f2240f158d..00000000000 --- a/doc/src/sgml/release-9.2.sgml +++ /dev/null @@ -1,12201 +0,0 @@ - - - - - Release 9.2.24 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 9.2.23. - For information about new features in the 9.2 major release, see - . - - - - This is expected to be the last PostgreSQL - release in the 9.2.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 9.2.24 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.22, - see . - - - - - - Changes - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - Properly reject attempts to convert infinite float values to - type numeric (Tom Lane, KaiGai Kohei) - - - - Previously the behavior was platform-dependent. - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - Prevent low-probability crash in processing of nested trigger firings - (Tom Lane) - - - - - - Correctly restore the umask setting when file creation fails - in COPY or lo_export() - (Peter Eisentraut) - - - - - - Give a better error message for duplicate column names - in ANALYZE (Nathan Bossart) - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - Fix libpq to guard against integer - overflow in the row count of a PGresult - (Michael Paquier) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017c - (Tom Lane) - - - - This fixes various issues; the only one likely to be user-visible - is that the default DST rules for a POSIX-style zone name, if - no posixrules file exists in the timezone data - directory, now match current US law rather than what it was a dozen - years ago. - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - - - - Release 9.2.23 - - - Release date: - 2017-08-31 - - - - This release contains a small number of fixes from 9.2.22. - For information about new features in the 9.2 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.2.X release series in September 2017. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.2.23 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.22, - see . - - - - - - Changes - - - - - - Show foreign tables - in information_schema.table_privileges - view (Peter Eisentraut) - - - - All other relevant information_schema views include - foreign tables, but this one ignored them. - - - - Since this view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can, as a superuser, do this - in psql: - -SET search_path TO information_schema; -CREATE OR REPLACE VIEW table_privileges AS - SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, - CAST(grantee.rolname AS sql_identifier) AS grantee, - CAST(current_database() AS sql_identifier) AS table_catalog, - CAST(nc.nspname AS sql_identifier) AS table_schema, - CAST(c.relname AS sql_identifier) AS table_name, - CAST(c.prtype AS character_data) AS privilege_type, - CAST( - CASE WHEN - -- object owner always has grant options - pg_has_role(grantee.oid, c.relowner, 'USAGE') - OR c.grantable - THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, - CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy - - FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class - ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), - pg_namespace nc, - pg_authid u_grantor, - ( - SELECT oid, rolname FROM pg_authid - UNION ALL - SELECT 0::oid, 'PUBLIC' - ) AS grantee (oid, rolname) - - WHERE c.relnamespace = nc.oid - AND c.relkind IN ('r', 'v', 'f') - AND c.grantee = grantee.oid - AND c.grantor = u_grantor.oid - AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') - AND (pg_has_role(u_grantor.oid, 'USAGE') - OR pg_has_role(grantee.oid, 'USAGE') - OR grantee.rolname = 'PUBLIC'); - - This must be repeated in each database to be fixed, - including template0. - - - - - - Clean up handling of a fatal exit (e.g., due to receipt - of SIGTERM) that occurs while trying to execute - a ROLLBACK of a failed transaction (Tom Lane) - - - - This situation could result in an assertion failure. In production - builds, the exit would still occur, but it would log an unexpected - message about cannot drop active portal. - - - - - - Remove assertion that could trigger during a fatal exit (Tom Lane) - - - - - - Correctly identify columns that are of a range type or domain type over - a composite type or domain type being searched for (Tom Lane) - - - - Certain ALTER commands that change the definition of a - composite type or domain type are supposed to fail if there are any - stored values of that type in the database, because they lack the - infrastructure needed to update or check such values. Previously, - these checks could miss relevant values that are wrapped inside range - types or sub-domains, possibly allowing the database to become - inconsistent. - - - - - - Change ecpg's parser to allow RETURNING - clauses without attached C variables (Michael Meskes) - - - - This allows ecpg programs to contain SQL constructs - that use RETURNING internally (for example, inside a CTE) - rather than using it to define values to be returned to the client. - - - - - - Improve selection of compiler flags for PL/Perl on Windows (Tom Lane) - - - - This fix avoids possible crashes of PL/Perl due to inconsistent - assumptions about the width of time_t values. - A side-effect that may be visible to extension developers is - that _USE_32BIT_TIME_T is no longer defined globally - in PostgreSQL Windows builds. This is not expected - to cause problems, because type time_t is not used - in any PostgreSQL API definitions. - - - - - - - - - - Release 9.2.22 - - - Release date: - 2017-08-10 - - - - This release contains a variety of fixes from 9.2.21. - For information about new features in the 9.2 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.2.X release series in September 2017. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.2.22 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.2.20, - see . - - - - - - Changes - - - - - - Further restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Noah Misch) - - - - The fix for CVE-2017-7486 was incorrect: it allowed a user - to see the options in her own user mapping, even if she did not - have USAGE permission on the associated foreign server. - Such options might include a password that had been provided by the - server owner rather than the user herself. - Since information_schema.user_mapping_options does not - show the options in such cases, pg_user_mappings - should not either. - (CVE-2017-7547) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - you will need to do the following: - - - - - - Restart the postmaster after adding allow_system_table_mods - = true to postgresql.conf. (In versions - supporting ALTER SYSTEM, you can use that to make the - configuration change, but you'll still need a restart.) - - - - - - In each database of the cluster, - run the following commands as superuser: - -SET search_path = pg_catalog; -CREATE OR REPLACE VIEW pg_user_mappings AS - SELECT - U.oid AS umid, - S.oid AS srvid, - S.srvname AS srvname, - U.umuser AS umuser, - CASE WHEN U.umuser = 0 THEN - 'public' - ELSE - A.rolname - END AS usename, - CASE WHEN (U.umuser <> 0 AND A.rolname = current_user - AND (pg_has_role(S.srvowner, 'USAGE') - OR has_server_privilege(S.oid, 'USAGE'))) - OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE')) - OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) - THEN U.umoptions - ELSE NULL END AS umoptions - FROM pg_user_mapping U - LEFT JOIN pg_authid A ON (A.oid = U.umuser) JOIN - pg_foreign_server S ON (U.umserver = S.oid); - - - - - - - Do not forget to include the template0 - and template1 databases, or the vulnerability will still - exist in databases you create later. To fix template0, - you'll need to temporarily make it accept connections. - In PostgreSQL 9.5 and later, you can use - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true; - - and then after fixing template0, undo that with - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false; - - In prior versions, instead use - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - - Finally, remove the allow_system_table_mods configuration - setting, and again restart the postmaster. - - - - - - - - Disallow empty passwords in all password-based authentication methods - (Heikki Linnakangas) - - - - libpq ignores empty password specifications, and does - not transmit them to the server. So, if a user's password has been - set to the empty string, it's impossible to log in with that password - via psql or other libpq-based - clients. An administrator might therefore believe that setting the - password to empty is equivalent to disabling password login. - However, with a modified or non-libpq-based client, - logging in could be possible, depending on which authentication - method is configured. In particular the most common - method, md5, accepted empty passwords. - Change the server to reject empty passwords in all cases. - (CVE-2017-7546) - - - - - - On Windows, retry process creation if we fail to reserve the address - range for our shared memory in the new process (Tom Lane, Amit - Kapila) - - - - This is expected to fix infrequent child-process-launch failures that - are probably due to interference from antivirus products. - - - - - - Fix low-probability corruption of shared predicate-lock hash table - in Windows builds (Thomas Munro, Tom Lane) - - - - - - Avoid logging clean closure of an SSL connection as though - it were a connection reset (Michael Paquier) - - - - - - Prevent sending SSL session tickets to clients (Tom Lane) - - - - This fix prevents reconnection failures with ticket-aware client-side - SSL code. - - - - - - Fix code for setting on - Solaris (Tom Lane) - - - - - - Fix statistics collector to honor inquiry messages issued just after - a postmaster shutdown and immediate restart (Tom Lane) - - - - Statistics inquiries issued within half a second of the previous - postmaster shutdown were effectively ignored. - - - - - - Ensure that the statistics collector's receive buffer size is at - least 100KB (Tom Lane) - - - - This reduces the risk of dropped statistics data on older platforms - whose default receive buffer size is less than that. - - - - - - Fix possible creation of an invalid WAL segment when a standby is - promoted just after it processes an XLOG_SWITCH WAL - record (Andres Freund) - - - - - - Fix SIGHUP and SIGUSR1 handling in - walsender processes (Petr Jelinek, Andres Freund) - - - - - - Fix unnecessarily slow restarts of walreceiver - processes due to race condition in postmaster (Tom Lane) - - - - - - Fix cases where an INSERT or UPDATE assigns - to more than one element of a column that is of domain-over-array - type (Tom Lane) - - - - - - Move autogenerated array types out of the way during - ALTER ... RENAME (Vik Fearing) - - - - Previously, we would rename a conflicting autogenerated array type - out of the way during CREATE; this fix extends that - behavior to renaming operations. - - - - - - Ensure that ALTER USER ... SET accepts all the syntax - variants that ALTER ROLE ... SET does (Peter Eisentraut) - - - - - - Properly update dependency info when changing a datatype I/O - function's argument or return type from opaque to the - correct type (Heikki Linnakangas) - - - - CREATE TYPE updates I/O functions declared in this - long-obsolete style, but it forgot to record a dependency on the - type, allowing a subsequent DROP TYPE to leave broken - function definitions behind. - - - - - - Reduce memory usage when ANALYZE processes - a tsvector column (Heikki Linnakangas) - - - - - - Fix unnecessary precision loss and sloppy rounding when multiplying - or dividing money values by integers or floats (Tom Lane) - - - - - - Tighten checks for whitespace in functions that parse identifiers, - such as regprocedurein() (Tom Lane) - - - - Depending on the prevailing locale, these functions could - misinterpret fragments of multibyte characters as whitespace. - - - - - - Use relevant #define symbols from Perl while - compiling PL/Perl (Ashutosh Sharma, Tom Lane) - - - - This avoids portability problems, typically manifesting as - a handshake mismatch during library load, when working with - recent Perl versions. - - - - - - In psql, fix failure when COPY FROM STDIN - is ended with a keyboard EOF signal and then another COPY - FROM STDIN is attempted (Thomas Munro) - - - - This misbehavior was observed on BSD-derived platforms (including - macOS), but not on most others. - - - - - - Fix pg_dump to not emit invalid SQL for an empty - operator class (Daniel Gustafsson) - - - - - - Fix pg_dump output to stdout on Windows (Kuntal Ghosh) - - - - A compressed plain-text dump written to stdout would contain corrupt - data due to failure to put the file descriptor into binary mode. - - - - - - Fix pg_get_ruledef() to print correct output for - the ON SELECT rule of a view whose columns have been - renamed (Tom Lane) - - - - In some corner cases, pg_dump relies - on pg_get_ruledef() to dump views, so that this error - could result in dump/reload failures. - - - - - - Fix dumping of function expressions in the FROM clause in - cases where the expression does not deparse into something that looks - like a function call (Tom Lane) - - - - - - Fix pg_basebackup output to stdout on Windows - (Haribabu Kommi) - - - - A backup written to stdout would contain corrupt data due to failure - to put the file descriptor into binary mode. - - - - - - Fix pg_upgrade to ensure that the ending WAL record - does not have = minimum - (Bruce Momjian) - - - - This condition could prevent upgraded standby servers from - reconnecting. - - - - - - Always use , not , when building - shared libraries with gcc (Tom Lane) - - - - This supports larger extension libraries on platforms where it makes - a difference. - - - - - - Fix unescaped-braces issue in our build scripts for Microsoft MSVC, - to avoid a warning or error from recent Perl versions (Andrew - Dunstan) - - - - - - In MSVC builds, handle the case where the openssl - library is not within a VC subdirectory (Andrew Dunstan) - - - - - - In MSVC builds, add proper include path for libxml2 - header files (Andrew Dunstan) - - - - This fixes a former need to move things around in standard Windows - installations of libxml2. - - - - - - In MSVC builds, recognize a Tcl library that is - named tcl86.lib (Noah Misch) - - - - - - - - - - Release 9.2.21 - - - Release date: - 2017-05-11 - - - - This release contains a variety of fixes from 9.2.20. - For information about new features in the 9.2 major release, see - . - - - - The PostgreSQL community will stop releasing updates - for the 9.2.X release series in September 2017. - Users are encouraged to update to a newer release branch soon. - - - - Migration to Version 9.2.21 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.2.20, - see . - - - - - - Changes - - - - - - Restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Michael Paquier, Feike Steenbergen) - - - - The previous coding allowed the owner of a foreign server object, - or anyone he has granted server USAGE permission to, - to see the options for all user mappings associated with that server. - This might well include passwords for other users. - Adjust the view definition to match the behavior of - information_schema.user_mapping_options, namely that - these options are visible to the user being mapped, or if the mapping - is for PUBLIC and the current user is the server - owner, or if the current user is a superuser. - (CVE-2017-7486) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - follow the corrected procedure shown in the changelog entry for - CVE-2017-7547, in . - - - - - - Prevent exposure of statistical information via leaky operators - (Peter Eisentraut) - - - - Some selectivity estimation functions in the planner will apply - user-defined operators to values obtained - from pg_statistic, such as most common values and - histogram entries. This occurs before table permissions are checked, - so a nefarious user could exploit the behavior to obtain these values - for table columns he does not have permission to read. To fix, - fall back to a default estimate if the operator's implementation - function is not certified leak-proof and the calling user does not have - permission to read the table column whose statistics are needed. - At least one of these criteria is satisfied in most cases in practice. - (CVE-2017-7484) - - - - - - Fix possible corruption of init forks of unlogged indexes - (Robert Haas, Michael Paquier) - - - - This could result in an unlogged index being set to an invalid state - after a crash and restart. Such a problem would persist until the - index was dropped and rebuilt. - - - - - - Fix incorrect reconstruction of pg_subtrans entries - when a standby server replays a prepared but uncommitted two-phase - transaction (Tom Lane) - - - - In most cases this turned out to have no visible ill effects, but in - corner cases it could result in circular references - in pg_subtrans, potentially causing infinite loops - in queries that examine rows modified by the two-phase transaction. - - - - - - Ensure parsing of queries in extension scripts sees the results of - immediately-preceding DDL (Julien Rouhaud, Tom Lane) - - - - Due to lack of a cache flush step between commands in an extension - script file, non-utility queries might not see the effects of an - immediately preceding catalog change, such as ALTER TABLE - ... RENAME. - - - - - - Skip tablespace privilege checks when ALTER TABLE ... ALTER - COLUMN TYPE rebuilds an existing index (Noah Misch) - - - - The command failed if the calling user did not currently have - CREATE privilege for the tablespace containing the index. - That behavior seems unhelpful, so skip the check, allowing the - index to be rebuilt where it is. - - - - - - Fix ALTER TABLE ... VALIDATE CONSTRAINT to not recurse - to child tables when the constraint is marked NO INHERIT - (Amit Langote) - - - - This fix prevents unwanted constraint does not exist failures - when no matching constraint is present in the child tables. - - - - - - Fix VACUUM to account properly for pages that could not - be scanned due to conflicting page pins (Andrew Gierth) - - - - This tended to lead to underestimation of the number of tuples in - the table. In the worst case of a small heavily-contended - table, VACUUM could incorrectly report that the table - contained no tuples, leading to very bad planning choices. - - - - - - Ensure that bulk-tuple-transfer loops within a hash join are - interruptible by query cancel requests (Tom Lane, Thomas Munro) - - - - - - Fix cursor_to_xml() to produce valid output - with tableforest = false - (Thomas Munro, Peter Eisentraut) - - - - Previously it failed to produce a wrapping <table> - element. - - - - - - Improve performance of pg_timezone_names view - (Tom Lane, David Rowley) - - - - - - Fix sloppy handling of corner-case errors from lseek() - and close() (Tom Lane) - - - - Neither of these system calls are likely to fail in typical situations, - but if they did, fd.c could get quite confused. - - - - - - Fix incorrect check for whether postmaster is running as a Windows - service (Michael Paquier) - - - - This could result in attempting to write to the event log when that - isn't accessible, so that no logging happens at all. - - - - - - Fix ecpg to support COMMIT PREPARED - and ROLLBACK PREPARED (Masahiko Sawada) - - - - - - Fix a double-free error when processing dollar-quoted string literals - in ecpg (Michael Meskes) - - - - - - In pg_dump, fix incorrect schema and owner marking for - comments and security labels of some types of database objects - (Giuseppe Broccolo, Tom Lane) - - - - In simple cases this caused no ill effects; but for example, a - schema-selective restore might omit comments it should include, because - they were not marked as belonging to the schema of their associated - object. - - - - - - Avoid emitting an invalid list file in pg_restore -l - when SQL object names contain newlines (Tom Lane) - - - - Replace newlines by spaces, which is sufficient to make the output - valid for pg_restore -L's purposes. - - - - - - Fix pg_upgrade to transfer comments and security labels - attached to large objects (blobs) (Stephen Frost) - - - - Previously, blobs were correctly transferred to the new database, but - any comments or security labels attached to them were lost. - - - - - - Improve error handling - in contrib/adminpack's pg_file_write() - function (Noah Misch) - - - - Notably, it failed to detect errors reported - by fclose(). - - - - - - In contrib/dblink, avoid leaking the previous unnamed - connection when establishing a new unnamed connection (Joe Conway) - - - - - - Support OpenSSL 1.1.0 (Heikki Linnakangas, Andreas Karlsson, Tom Lane) - - - - This is a back-patch of work previously done in newer branches; - it's needed since many platforms are adopting newer OpenSSL versions. - - - - - - Support Tcl 8.6 in MSVC builds (Álvaro Herrera) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017b - (Tom Lane) - - - - This fixes a bug affecting some DST transitions in January 2038. - - - - - - Update time zone data files to tzdata release 2017b - for DST law changes in Chile, Haiti, and Mongolia, plus historical - corrections for Ecuador, Kazakhstan, Liberia, and Spain. - Switch to numeric abbreviations for numerous time zones in South - America, the Pacific and Indian oceans, and some Asian and Middle - Eastern countries. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - - - Use correct daylight-savings rules for POSIX-style time zone names - in MSVC builds (David Rowley) - - - - The Microsoft MSVC build scripts neglected to install - the posixrules file in the timezone directory tree. - This resulted in the timezone code falling back to its built-in - rule about what DST behavior to assume for a POSIX-style time zone - name. For historical reasons that still corresponds to the DST rules - the USA was using before 2007 (i.e., change on first Sunday in April - and last Sunday in October). With this fix, a POSIX-style zone name - will use the current and historical DST transition dates of - the US/Eastern zone. If you don't want that, remove - the posixrules file, or replace it with a copy of some - other zone file (see ). Note that - due to caching, you may need to restart the server to get such changes - to take effect. - - - - - - - - - - Release 9.2.20 - - - Release date: - 2017-02-09 - - - - This release contains a variety of fixes from 9.2.19. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.20 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted indexes. - - - - Also, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix a race condition that could cause indexes built - with CREATE INDEX CONCURRENTLY to be corrupt - (Pavan Deolasee, Tom Lane) - - - - If CREATE INDEX CONCURRENTLY was used to build an index - that depends on a column not previously indexed, then rows - updated by transactions that ran concurrently with - the CREATE INDEX command could have received incorrect - index entries. If you suspect this may have happened, the most - reliable solution is to rebuild affected indexes after installing - this update. - - - - - - Unconditionally WAL-log creation of the init fork for an - unlogged table (Michael Paquier) - - - - Previously, this was skipped when - = minimal, but actually it's necessary even in that case - to ensure that the unlogged table is properly reset to empty after a - crash. - - - - - - - Fix WAL page header validation when re-reading segments (Takayuki - Tsunakawa, Amit Kapila) - - - - In corner cases, a spurious out-of-sequence TLI error - could be reported during recovery. - - - - - - If the stats collector dies during hot standby, restart it (Takayuki - Tsunakawa) - - - - - - Check for interrupts while hot standby is waiting for a conflicting - query (Simon Riggs) - - - - - - Avoid constantly respawning the autovacuum launcher in a corner case - (Amit Khandekar) - - - - This fix avoids problems when autovacuum is nominally off and there - are some tables that require freezing, but all such tables are - already being processed by autovacuum workers. - - - - - - Fix check for when an extension member object can be dropped (Tom Lane) - - - - Extension upgrade scripts should be able to drop member objects, - but this was disallowed for serial-column sequences, and possibly - other cases. - - - - - - Make sure ALTER TABLE preserves index tablespace - assignments when rebuilding indexes (Tom Lane, Michael Paquier) - - - - Previously, non-default settings - of could result in broken - indexes. - - - - - - Prevent dropping a foreign-key constraint if there are pending - trigger events for the referenced relation (Tom Lane) - - - - This avoids could not find trigger NNN - or relation NNN has no triggers errors. - - - - - - Fix processing of OID column when a table with OIDs is associated to - a parent with OIDs via ALTER TABLE ... INHERIT (Amit - Langote) - - - - The OID column should be treated the same as regular user columns in - this case, but it wasn't, leading to odd behavior in later - inheritance changes. - - - - - - Check for serializability conflicts before reporting - constraint-violation failures (Thomas Munro) - - - - When using serializable transaction isolation, it is desirable - that any error due to concurrent transactions should manifest - as a serialization failure, thereby cueing the application that - a retry might succeed. Unfortunately, this does not reliably - happen for duplicate-key failures caused by concurrent insertions. - This change ensures that such an error will be reported as a - serialization error if the application explicitly checked for - the presence of a conflicting key (and did not find it) earlier - in the transaction. - - - - - - Ensure that column typmods are determined accurately for - multi-row VALUES constructs (Tom Lane) - - - - This fixes problems occurring when the first value in a column has a - determinable typmod (e.g., length for a varchar value) but - later values don't share the same limit. - - - - - - Throw error for an unfinished Unicode surrogate pair at the end of a - Unicode string (Tom Lane) - - - - Normally, a Unicode surrogate leading character must be followed by a - Unicode surrogate trailing character, but the check for this was - missed if the leading character was the last character in a Unicode - string literal (U&'...') or Unicode identifier - (U&"..."). - - - - - - Ensure that a purely negative text search query, such - as !foo, matches empty tsvectors (Tom Dunstan) - - - - Such matches were found by GIN index searches, but not by sequential - scans or GiST index searches. - - - - - - Prevent crash when ts_rewrite() replaces a non-top-level - subtree with an empty query (Artur Zakirov) - - - - - - Fix performance problems in ts_rewrite() (Tom Lane) - - - - - - Fix ts_rewrite()'s handling of nested NOT operators - (Tom Lane) - - - - - - Fix array_fill() to handle empty arrays properly (Tom Lane) - - - - - - Fix one-byte buffer overrun in quote_literal_cstr() - (Heikki Linnakangas) - - - - The overrun occurred only if the input consisted entirely of single - quotes and/or backslashes. - - - - - - Prevent multiple calls of pg_start_backup() - and pg_stop_backup() from running concurrently (Michael - Paquier) - - - - This avoids an assertion failure, and possibly worse things, if - someone tries to run these functions in parallel. - - - - - - Avoid discarding interval-to-interval casts - that aren't really no-ops (Tom Lane) - - - - In some cases, a cast that should result in zeroing out - low-order interval fields was mistakenly deemed to be a - no-op and discarded. An example is that casting from INTERVAL - MONTH to INTERVAL YEAR failed to clear the months field. - - - - - - Fix pg_dump to dump user-defined casts and transforms - that use built-in functions (Stephen Frost) - - - - - - Fix possible pg_basebackup failure on standby - server when including WAL files (Amit Kapila, Robert Haas) - - - - - - Ensure that the Python exception objects we create for PL/Python are - properly reference-counted (Rafa de la Torre, Tom Lane) - - - - This avoids failures if the objects are used after a Python garbage - collection cycle has occurred. - - - - - - Fix PL/Tcl to support triggers on tables that have .tupno - as a column name (Tom Lane) - - - - This matches the (previously undocumented) behavior of - PL/Tcl's spi_exec and spi_execp commands, - namely that a magic .tupno column is inserted only if - there isn't a real column named that. - - - - - - Allow DOS-style line endings in ~/.pgpass files, - even on Unix (Vik Fearing) - - - - This change simplifies use of the same password file across Unix and - Windows machines. - - - - - - Fix one-byte buffer overrun if ecpg is given a file - name that ends with a dot (Takayuki Tsunakawa) - - - - - - Fix psql's tab completion for ALTER DEFAULT - PRIVILEGES (Gilles Darold, Stephen Frost) - - - - - - In psql, treat an empty or all-blank setting of - the PAGER environment variable as meaning no - pager (Tom Lane) - - - - Previously, such a setting caused output intended for the pager to - vanish entirely. - - - - - - Improve contrib/dblink's reporting of - low-level libpq errors, such as out-of-memory - (Joe Conway) - - - - - - On Windows, ensure that environment variable changes are propagated - to DLLs built with debug options (Christian Ullrich) - - - - - - Sync our copy of the timezone library with IANA release tzcode2016j - (Tom Lane) - - - - This fixes various issues, most notably that timezone data - installation failed if the target directory didn't support hard - links. - - - - - - Update time zone data files to tzdata release 2016j - for DST law changes in northern Cyprus (adding a new zone - Asia/Famagusta), Russia (adding a new zone Europe/Saratov), Tonga, - and Antarctica/Casey. - Historical corrections for Italy, Kazakhstan, Malta, and Palestine. - Switch to preferring numeric zone abbreviations for Tonga. - - - - - - - - - - Release 9.2.19 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.2.18. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.19 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix EvalPlanQual rechecks involving CTE scans (Tom Lane) - - - - The recheck would always see the CTE as returning no rows, typically - leading to failure to update rows that were recently updated. - - - - - - Fix improper repetition of previous results from hashed aggregation in - a subquery (Andrew Gierth) - - - - The test to see if we can reuse a previously-computed hash table of - the aggregate state values neglected the possibility of an outer query - reference appearing in an aggregate argument expression. A change in - the value of such a reference should lead to recalculating the hash - table, but did not. - - - - - - Fix EXPLAIN to emit valid XML when - is on (Markus Winand) - - - - Previously the XML output-format option produced syntactically invalid - tags such as <I/O-Read-Time>. That is now - rendered as <I-O-Read-Time>. - - - - - - Suppress printing of zeroes for unmeasured times - in EXPLAIN (Maksim Milyutin) - - - - Certain option combinations resulted in printing zero values for times - that actually aren't ever measured in that combination. Our general - policy in EXPLAIN is not to print such fields at all, so - do that consistently in all cases. - - - - - - Fix timeout length when VACUUM is waiting for exclusive - table lock so that it can truncate the table (Simon Riggs) - - - - The timeout was meant to be 50 milliseconds, but it was actually only - 50 microseconds, causing VACUUM to give up on truncation - much more easily than intended. Set it to the intended value. - - - - - - Fix bugs in merging inherited CHECK constraints while - creating or altering a table (Tom Lane, Amit Langote) - - - - Allow identical CHECK constraints to be added to a parent - and child table in either order. Prevent merging of a valid - constraint from the parent table with a NOT VALID - constraint on the child. Likewise, prevent merging of a NO - INHERIT child constraint with an inherited constraint. - - - - - - Remove artificial restrictions on the values accepted - by numeric_in() and numeric_recv() - (Tom Lane) - - - - We allow numeric values up to the limit of the storage format (more - than 1e100000), so it seems fairly pointless - that numeric_in() rejected scientific-notation exponents - above 1000. Likewise, it was silly for numeric_recv() to - reject more than 1000 digits in an input value. - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - Fix file descriptor leakage when truncating a temporary relation of - more than 1GB (Andres Freund) - - - - - - Disallow starting a standalone backend with standby_mode - turned on (Michael Paquier) - - - - This can't do anything useful, since there will be no WAL receiver - process to fetch more WAL data; and it could result in misbehavior - in code that wasn't designed with this situation in mind. - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - Make ecpg's and - options work consistently with our other executables (Haribabu Kommi) - - - - - - In pg_dump, never dump range constructor functions - (Tom Lane) - - - - This oversight led to pg_upgrade failures with - extensions containing range types, due to duplicate creation of the - constructor functions. - - - - - - Fix contrib/intarray/bench/bench.pl to print the results - of the EXPLAIN it does when given the option - (Daniel Gustafsson) - - - - - - Update Windows time zone mapping to recognize some time zone names - added in recent Windows versions (Michael Paquier) - - - - - - Prevent failure of obsolete dynamic time zone abbreviations (Tom Lane) - - - - If a dynamic time zone abbreviation does not match any entry in the - referenced time zone, treat it as equivalent to the time zone name. - This avoids unexpected failures when IANA removes abbreviations from - their time zone database, as they did in tzdata - release 2016f and seem likely to do again in the future. The - consequences were not limited to not recognizing the individual - abbreviation; any mismatch caused - the pg_timezone_abbrevs view to fail altogether. - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.2.18 - - - Release date: - 2016-08-11 - - - - This release contains a variety of fixes from 9.2.17. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.18 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix possible mis-evaluation of - nested CASE-WHEN expressions (Heikki - Linnakangas, Michael Paquier, Tom Lane) - - - - A CASE expression appearing within the test value - subexpression of another CASE could become confused about - whether its own test value was null or not. Also, inlining of a SQL - function implementing the equality operator used by - a CASE expression could result in passing the wrong test - value to functions called within a CASE expression in the - SQL function's body. If the test values were of different data - types, a crash might result; moreover such situations could be abused - to allow disclosure of portions of server memory. (CVE-2016-5423) - - - - - - Fix client programs' handling of special characters in database and - role names (Noah Misch, Nathan Bossart, Michael Paquier) - - - - Numerous places in vacuumdb and other client programs - could become confused by database and role names containing double - quotes or backslashes. Tighten up quoting rules to make that safe. - Also, ensure that when a conninfo string is used as a database name - parameter to these programs, it is correctly treated as such throughout. - - - - Fix handling of paired double quotes - in psql's \connect - and \password commands to match the documentation. - - - - Introduce a new option - in psql's \connect command to allow - explicit control of whether to re-use connection parameters from a - previous connection. (Without this, the choice is based on whether - the database name looks like a conninfo string, as before.) This - allows secure handling of database names containing special - characters in pg_dumpall scripts. - - - - pg_dumpall now refuses to deal with database and role - names containing carriage returns or newlines, as it seems impractical - to quote those characters safely on Windows. In future we may reject - such names on the server side, but that step has not been taken yet. - - - - These are considered security fixes because crafted object names - containing special characters could have been used to execute - commands with superuser privileges the next time a superuser - executes pg_dumpall or other routine maintenance - operations. (CVE-2016-5424) - - - - - - Fix corner-case misbehaviors for IS NULL/IS NOT - NULL applied to nested composite values (Andrew Gierth, Tom Lane) - - - - The SQL standard specifies that IS NULL should return - TRUE for a row of all null values (thus ROW(NULL,NULL) IS - NULL yields TRUE), but this is not meant to apply recursively - (thus ROW(NULL, ROW(NULL,NULL)) IS NULL yields FALSE). - The core executor got this right, but certain planner optimizations - treated the test as recursive (thus producing TRUE in both cases), - and contrib/postgres_fdw could produce remote queries - that misbehaved similarly. - - - - - - Make the inet and cidr data types properly reject - IPv6 addresses with too many colon-separated fields (Tom Lane) - - - - - - Prevent crash in close_ps() - (the point ## lseg operator) - for NaN input coordinates (Tom Lane) - - - - Make it return NULL instead of crashing. - - - - - - Fix several one-byte buffer over-reads in to_number() - (Peter Eisentraut) - - - - In several cases the to_number() function would read one - more character than it should from the input string. There is a - small chance of a crash, if the input happens to be adjacent to the - end of memory. - - - - - - Avoid unsafe intermediate state during expensive paths - through heap_update() (Masahiko Sawada, Andres Freund) - - - - Previously, these cases locked the target tuple (by setting its XMAX) - but did not WAL-log that action, thus risking data integrity problems - if the page were spilled to disk and then a database crash occurred - before the tuple update could be completed. - - - - - - Avoid crash in postgres -C when the specified variable - has a null string value (Michael Paquier) - - - - - - Avoid consuming a transaction ID during VACUUM - (Alexander Korotkov) - - - - Some cases in VACUUM unnecessarily caused an XID to be - assigned to the current transaction. Normally this is negligible, - but if one is up against the XID wraparound limit, consuming more - XIDs during anti-wraparound vacuums is a very bad thing. - - - - - - Avoid canceling hot-standby queries during VACUUM FREEZE - (Simon Riggs, Álvaro Herrera) - - - - VACUUM FREEZE on an otherwise-idle master server could - result in unnecessary cancellations of queries on its standby - servers. - - - - - - When a manual ANALYZE specifies a column list, don't - reset the table's changes_since_analyze counter - (Tom Lane) - - - - If we're only analyzing some columns, we should not prevent routine - auto-analyze from happening for the other columns. - - - - - - Fix ANALYZE's overestimation of n_distinct - for a unique or nearly-unique column with many null entries (Tom - Lane) - - - - The nulls could get counted as though they were themselves distinct - values, leading to serious planner misestimates in some types of - queries. - - - - - - Prevent autovacuum from starting multiple workers for the same shared - catalog (Álvaro Herrera) - - - - Normally this isn't much of a problem because the vacuum doesn't take - long anyway; but in the case of a severely bloated catalog, it could - result in all but one worker uselessly waiting instead of doing - useful work on other tables. - - - - - - Prevent infinite loop in GiST index build for geometric columns - containing NaN component values (Tom Lane) - - - - - - Fix contrib/btree_gin to handle the smallest - possible bigint value correctly (Peter Eisentraut) - - - - - - Teach libpq to correctly decode server version from future servers - (Peter Eisentraut) - - - - It's planned to switch to two-part instead of three-part server - version numbers for releases after 9.6. Make sure - that PQserverVersion() returns the correct value for - such cases. - - - - - - Fix ecpg's code for unsigned long long - array elements (Michael Meskes) - - - - - - In pg_dump with both and - options, avoid emitting an unwanted CREATE SCHEMA public - command (David Johnston, Tom Lane) - - - - - - Make pg_basebackup accept -Z 0 as - specifying no compression (Fujii Masao) - - - - - - Fix makefiles' rule for building AIX shared libraries to be safe for - parallel make (Noah Misch) - - - - - - Fix TAP tests and MSVC scripts to work when build directory's path - name contains spaces (Michael Paquier, Kyotaro Horiguchi) - - - - - - Make regression tests safe for Danish and Welsh locales (Jeff Janes, - Tom Lane) - - - - Change some test data that triggered the unusual sorting rules of - these locales. - - - - - - Update our copy of the timezone code to match - IANA's tzcode release 2016c (Tom Lane) - - - - This is needed to cope with anticipated future changes in the time - zone data files. It also fixes some corner-case bugs in coping with - unusual time zones. - - - - - - Update time zone data files to tzdata release 2016f - for DST law changes in Kemerovo and Novosibirsk, plus historical - corrections for Azerbaijan, Belarus, and Morocco. - - - - - - - - - - Release 9.2.17 - - - Release date: - 2016-05-12 - - - - This release contains a variety of fixes from 9.2.16. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.17 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Clear the OpenSSL error queue before OpenSSL calls, rather than - assuming it's clear already; and make sure we leave it clear - afterwards (Peter Geoghegan, Dave Vitek, Peter Eisentraut) - - - - This change prevents problems when there are multiple connections - using OpenSSL within a single process and not all the code involved - follows the same rules for when to clear the error queue. - Failures have been reported specifically when a client application - uses SSL connections in libpq concurrently with - SSL connections using the PHP, Python, or Ruby wrappers for OpenSSL. - It's possible for similar problems to arise within the server as well, - if an extension module establishes an outgoing SSL connection. - - - - - - Fix failed to build any N-way joins - planner error with a full join enclosed in the right-hand side of a - left join (Tom Lane) - - - - - - Fix incorrect handling of equivalence-class tests in multilevel - nestloop plans (Tom Lane) - - - - Given a three-or-more-way equivalence class of variables, such - as X.X = Y.Y = Z.Z, it was possible for the planner to omit - some of the tests needed to enforce that all the variables are actually - equal, leading to join rows being output that didn't satisfy - the WHERE clauses. For various reasons, erroneous plans - were seldom selected in practice, so that this bug has gone undetected - for a long time. - - - - - - Fix possible misbehavior of TH, th, - and Y,YYY format codes in to_timestamp() - (Tom Lane) - - - - These could advance off the end of the input string, causing subsequent - format codes to read garbage. - - - - - - Fix dumping of rules and views in which the array - argument of a value operator - ANY (array) construct is a sub-SELECT - (Tom Lane) - - - - - - Make pg_regress use a startup timeout from the - PGCTLTIMEOUT environment variable, if that's set (Tom Lane) - - - - This is for consistency with a behavior recently added - to pg_ctl; it eases automated testing on slow machines. - - - - - - Fix pg_upgrade to correctly restore extension - membership for operator families containing only one operator class - (Tom Lane) - - - - In such a case, the operator family was restored into the new database, - but it was no longer marked as part of the extension. This had no - immediate ill effects, but would cause later pg_dump - runs to emit output that would cause (harmless) errors on restore. - - - - - - Back-port 9.4-era memory-barrier code changes into 9.2 and 9.3 (Tom Lane) - - - - These changes were not originally needed in pre-9.4 branches, but we - recently back-patched a fix that expected the barrier code to work - properly. Only IA64 (when using icc), HPPA, and Alpha platforms are - affected. - - - - - - Reduce the number of SysV semaphores used by a build configured with - (Tom Lane) - - - - - - Rename internal function strtoi() - to strtoint() to avoid conflict with a NetBSD library - function (Thomas Munro) - - - - - - Fix reporting of errors from bind() - and listen() system calls on Windows (Tom Lane) - - - - - - Reduce verbosity of compiler output when building with Microsoft Visual - Studio (Christian Ullrich) - - - - - - Avoid possibly-unsafe use of Windows' FormatMessage() - function (Christian Ullrich) - - - - Use the FORMAT_MESSAGE_IGNORE_INSERTS flag where - appropriate. No live bug is known to exist here, but it seems like a - good idea to be careful. - - - - - - Update time zone data files to tzdata release 2016d - for DST law changes in Russia and Venezuela. There are new zone - names Europe/Kirov and Asia/Tomsk to reflect - the fact that these regions now have different time zone histories from - adjacent regions. - - - - - - - - - - Release 9.2.16 - - - Release date: - 2016-03-31 - - - - This release contains a variety of fixes from 9.2.15. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.16 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix incorrect handling of NULL index entries in - indexed ROW() comparisons (Tom Lane) - - - - An index search using a row comparison such as ROW(a, b) > - ROW('x', 'y') would stop upon reaching a NULL entry in - the b column, ignoring the fact that there might be - non-NULL b values associated with later values - of a. - - - - - - Avoid unlikely data-loss scenarios due to renaming files without - adequate fsync() calls before and after (Michael Paquier, - Tomas Vondra, Andres Freund) - - - - - - Correctly handle cases where pg_subtrans is close to XID - wraparound during server startup (Jeff Janes) - - - - - - Fix corner-case crash due to trying to free localeconv() - output strings more than once (Tom Lane) - - - - - - Fix parsing of affix files for ispell dictionaries - (Tom Lane) - - - - The code could go wrong if the affix file contained any characters - whose byte length changes during case-folding, for - example I in Turkish UTF8 locales. - - - - - - Avoid use of sscanf() to parse ispell - dictionary files (Artur Zakirov) - - - - This dodges a portability problem on FreeBSD-derived platforms - (including macOS). - - - - - - Avoid a crash on old Windows versions (before 7SP1/2008R2SP1) with an - AVX2-capable CPU and a Postgres build done with Visual Studio 2013 - (Christian Ullrich) - - - - This is a workaround for a bug in Visual Studio 2013's runtime - library, which Microsoft have stated they will not fix in that - version. - - - - - - Fix psql's tab completion logic to handle multibyte - characters properly (Kyotaro Horiguchi, Robert Haas) - - - - - - Fix psql's tab completion for - SECURITY LABEL (Tom Lane) - - - - Pressing TAB after SECURITY LABEL might cause a crash - or offering of inappropriate keywords. - - - - - - Make pg_ctl accept a wait timeout from the - PGCTLTIMEOUT environment variable, if none is specified on - the command line (Noah Misch) - - - - This eases testing of slower buildfarm members by allowing them - to globally specify a longer-than-normal timeout for postmaster - startup and shutdown. - - - - - - Fix incorrect test for Windows service status - in pg_ctl (Manuel Mathar) - - - - The previous set of minor releases attempted to - fix pg_ctl to properly determine whether to send log - messages to Window's Event Log, but got the test backwards. - - - - - - Fix pgbench to correctly handle the combination - of -C and -M prepared options (Tom Lane) - - - - - - In PL/Perl, properly translate empty Postgres arrays into empty Perl - arrays (Alex Hunsaker) - - - - - - Make PL/Python cope with function names that aren't valid Python - identifiers (Jim Nasby) - - - - - - Fix multiple mistakes in the statistics returned - by contrib/pgstattuple's pgstatindex() - function (Tom Lane) - - - - - - Remove dependency on psed in MSVC builds, since it's no - longer provided by core Perl (Michael Paquier, Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2016c - for DST law changes in Azerbaijan, Chile, Haiti, Palestine, and Russia - (Altai, Astrakhan, Kirov, Sakhalin, Ulyanovsk regions), plus - historical corrections for Lithuania, Moldova, and Russia - (Kaliningrad, Samara, Volgograd). - - - - - - - - - - Release 9.2.15 - - - Release date: - 2016-02-11 - - - - This release contains a variety of fixes from 9.2.14. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.15 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix infinite loops and buffer-overrun problems in regular expressions - (Tom Lane) - - - - Very large character ranges in bracket expressions could cause - infinite loops in some cases, and memory overwrites in other cases. - (CVE-2016-0773) - - - - - - Perform an immediate shutdown if the postmaster.pid file - is removed (Tom Lane) - - - - The postmaster now checks every minute or so - that postmaster.pid is still there and still contains its - own PID. If not, it performs an immediate shutdown, as though it had - received SIGQUIT. The main motivation for this change - is to ensure that failed buildfarm runs will get cleaned up without - manual intervention; but it also serves to limit the bad effects if a - DBA forcibly removes postmaster.pid and then starts a new - postmaster. - - - - - - In SERIALIZABLE transaction isolation mode, serialization - anomalies could be missed due to race conditions during insertions - (Kevin Grittner, Thomas Munro) - - - - - - Fix failure to emit appropriate WAL records when doing ALTER - TABLE ... SET TABLESPACE for unlogged relations (Michael Paquier, - Andres Freund) - - - - Even though the relation's data is unlogged, the move must be logged or - the relation will be inaccessible after a standby is promoted to master. - - - - - - Fix possible misinitialization of unlogged relations at the end of - crash recovery (Andres Freund, Michael Paquier) - - - - - - Fix ALTER COLUMN TYPE to reconstruct inherited check - constraints properly (Tom Lane) - - - - - - Fix REASSIGN OWNED to change ownership of composite types - properly (Álvaro Herrera) - - - - - - Fix REASSIGN OWNED and ALTER OWNER to correctly - update granted-permissions lists when changing owners of data types, - foreign data wrappers, or foreign servers (Bruce Momjian, - Álvaro Herrera) - - - - - - Fix REASSIGN OWNED to ignore foreign user mappings, - rather than fail (Álvaro Herrera) - - - - - - Add more defenses against bad planner cost estimates for GIN index - scans when the index's internal statistics are very out-of-date - (Tom Lane) - - - - - - Make planner cope with hypothetical GIN indexes suggested by an index - advisor plug-in (Julien Rouhaud) - - - - - - Fix dumping of whole-row Vars in ROW() - and VALUES() lists (Tom Lane) - - - - - - Fix possible internal overflow in numeric division - (Dean Rasheed) - - - - - - Fix enforcement of restrictions inside parentheses within regular - expression lookahead constraints (Tom Lane) - - - - Lookahead constraints aren't allowed to contain backrefs, and - parentheses within them are always considered non-capturing, according - to the manual. However, the code failed to handle these cases properly - inside a parenthesized subexpression, and would give unexpected - results. - - - - - - Conversion of regular expressions to indexscan bounds could produce - incorrect bounds from regexps containing lookahead constraints - (Tom Lane) - - - - - - Fix regular-expression compiler to handle loops of constraint arcs - (Tom Lane) - - - - The code added for CVE-2007-4772 was both incomplete, in that it didn't - handle loops involving more than one state, and incorrect, in that it - could cause assertion failures (though there seem to be no bad - consequences of that in a non-assert build). Multi-state loops would - cause the compiler to run until the query was canceled or it reached - the too-many-states error condition. - - - - - - Improve memory-usage accounting in regular-expression compiler - (Tom Lane) - - - - This causes the code to emit regular expression is too - complex errors in some cases that previously used unreasonable - amounts of time and memory. - - - - - - Improve performance of regular-expression compiler (Tom Lane) - - - - - - Make %h and %r escapes - in log_line_prefix work for messages emitted due - to log_connections (Tom Lane) - - - - Previously, %h/%r started to work just after a - new session had emitted the connection received log message; - now they work for that message too. - - - - - - On Windows, ensure the shared-memory mapping handle gets closed in - child processes that don't need it (Tom Lane, Amit Kapila) - - - - This oversight resulted in failure to recover from crashes - whenever logging_collector is turned on. - - - - - - Fix possible failure to detect socket EOF in non-blocking mode on - Windows (Tom Lane) - - - - It's not entirely clear whether this problem can happen in pre-9.5 - branches, but if it did, the symptom would be that a walsender process - would wait indefinitely rather than noticing a loss of connection. - - - - - - Avoid leaking a token handle during SSPI authentication - (Christian Ullrich) - - - - - - In psql, ensure that libreadline's idea - of the screen size is updated when the terminal window size changes - (Merlin Moncure) - - - - Previously, libreadline did not notice if the window - was resized during query output, leading to strange behavior during - later input of multiline queries. - - - - - - Fix psql's \det command to interpret its - pattern argument the same way as other \d commands with - potentially schema-qualified patterns do (Reece Hart) - - - - - - Avoid possible crash in psql's \c command - when previous connection was via Unix socket and command specifies a - new hostname and same username (Tom Lane) - - - - - - In pg_ctl start -w, test child process status directly - rather than relying on heuristics (Tom Lane, Michael Paquier) - - - - Previously, pg_ctl relied on an assumption that the new - postmaster would always create postmaster.pid within five - seconds. But that can fail on heavily-loaded systems, - causing pg_ctl to report incorrectly that the - postmaster failed to start. - - - - Except on Windows, this change also means that a pg_ctl start - -w done immediately after another such command will now reliably - fail, whereas previously it would report success if done within two - seconds of the first command. - - - - - - In pg_ctl start -w, don't attempt to use a wildcard listen - address to connect to the postmaster (Kondo Yuta) - - - - On Windows, pg_ctl would fail to detect postmaster - startup if listen_addresses is set to 0.0.0.0 - or ::, because it would try to use that value verbatim as - the address to connect to, which doesn't work. Instead assume - that 127.0.0.1 or ::1, respectively, is the - right thing to use. - - - - - - In pg_ctl on Windows, check service status to decide - where to send output, rather than checking if standard output is a - terminal (Michael Paquier) - - - - - - In pg_dump and pg_basebackup, adopt - the GNU convention for handling tar-archive members exceeding 8GB - (Tom Lane) - - - - The POSIX standard for tar file format does not allow - archive member files to exceed 8GB, but most modern implementations - of tar support an extension that fixes that. Adopt - this extension so that pg_dump with no - longer fails on tables with more than 8GB of data, and so - that pg_basebackup can handle files larger than 8GB. - In addition, fix some portability issues that could cause failures for - members between 4GB and 8GB on some platforms. Potentially these - problems could cause unrecoverable data loss due to unreadable backup - files. - - - - - - Fix assorted corner-case bugs in pg_dump's processing - of extension member objects (Tom Lane) - - - - - - Make pg_dump mark a view's triggers as needing to be - processed after its rule, to prevent possible failure during - parallel pg_restore (Tom Lane) - - - - - - Ensure that relation option values are properly quoted - in pg_dump (Kouhei Sutou, Tom Lane) - - - - A reloption value that isn't a simple identifier or number could lead - to dump/reload failures due to syntax errors in CREATE statements - issued by pg_dump. This is not an issue with any - reloption currently supported by core PostgreSQL, but - extensions could allow reloptions that cause the problem. - - - - - - Fix pg_upgrade's file-copying code to handle errors - properly on Windows (Bruce Momjian) - - - - - - Install guards in pgbench against corner-case overflow - conditions during evaluation of script-specified division or modulo - operators (Fabien Coelho, Michael Paquier) - - - - - - Fix failure to localize messages emitted - by pg_receivexlog and pg_recvlogical - (Ioseph Kim) - - - - - - Avoid dump/reload problems when using both plpython2 - and plpython3 (Tom Lane) - - - - In principle, both versions of PL/Python can be used in - the same database, though not in the same session (because the two - versions of libpython cannot safely be used concurrently). - However, pg_restore and pg_upgrade both - do things that can fall foul of the same-session restriction. Work - around that by changing the timing of the check. - - - - - - Fix PL/Python regression tests to pass with Python 3.5 - (Peter Eisentraut) - - - - - - Prevent certain PL/Java parameters from being set by - non-superusers (Noah Misch) - - - - This change mitigates a PL/Java security bug - (CVE-2016-0766), which was fixed in PL/Java by marking - these parameters as superuser-only. To fix the security hazard for - sites that update PostgreSQL more frequently - than PL/Java, make the core code aware of them also. - - - - - - Improve libpq's handling of out-of-memory situations - (Michael Paquier, Amit Kapila, Heikki Linnakangas) - - - - - - Fix order of arguments - in ecpg-generated typedef statements - (Michael Meskes) - - - - - - Use %g not %f format - in ecpg's PGTYPESnumeric_from_double() - (Tom Lane) - - - - - - Fix ecpg-supplied header files to not contain comments - continued from a preprocessor directive line onto the next line - (Michael Meskes) - - - - Such a comment is rejected by ecpg. It's not yet clear - whether ecpg itself should be changed. - - - - - - Ensure that contrib/pgcrypto's crypt() - function can be interrupted by query cancel (Andreas Karlsson) - - - - - - Accept flex versions later than 2.5.x - (Tom Lane, Michael Paquier) - - - - Now that flex 2.6.0 has been released, the version checks in our build - scripts needed to be adjusted. - - - - - - Install our missing script where PGXS builds can find it - (Jim Nasby) - - - - This allows sane behavior in a PGXS build done on a machine where build - tools such as bison are missing. - - - - - - Ensure that dynloader.h is included in the installed - header files in MSVC builds (Bruce Momjian, Michael Paquier) - - - - - - Add variant regression test expected-output file to match behavior of - current libxml2 (Tom Lane) - - - - The fix for libxml2's CVE-2015-7499 causes it not to - output error context reports in some cases where it used to do so. - This seems to be a bug, but we'll probably have to live with it for - some time, so work around it. - - - - - - Update time zone data files to tzdata release 2016a for - DST law changes in Cayman Islands, Metlakatla, and Trans-Baikal - Territory (Zabaykalsky Krai), plus historical corrections for Pakistan. - - - - - - - - - - Release 9.2.14 - - - Release date: - 2015-10-08 - - - - This release contains a variety of fixes from 9.2.13. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.14 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix contrib/pgcrypto to detect and report - too-short crypt() salts (Josh Kupershmidt) - - - - Certain invalid salt arguments crashed the server or disclosed a few - bytes of server memory. We have not ruled out the viability of - attacks that arrange for presence of confidential information in the - disclosed bytes, but they seem unlikely. (CVE-2015-5288) - - - - - - Fix subtransaction cleanup after a portal (cursor) belonging to an - outer subtransaction fails (Tom Lane, Michael Paquier) - - - - A function executed in an outer-subtransaction cursor could cause an - assertion failure or crash by referencing a relation created within an - inner subtransaction. - - - - - - Fix insertion of relations into the relation cache init file - (Tom Lane) - - - - An oversight in a patch in the most recent minor releases - caused pg_trigger_tgrelid_tgname_index to be omitted - from the init file. Subsequent sessions detected this, then deemed the - init file to be broken and silently ignored it, resulting in a - significant degradation in session startup time. In addition to fixing - the bug, install some guards so that any similar future mistake will be - more obvious. - - - - - - Avoid O(N^2) behavior when inserting many tuples into a SPI query - result (Neil Conway) - - - - - - Improve LISTEN startup time when there are many unread - notifications (Matt Newell) - - - - - - - - Back-patch 9.3-era addition of per-resource-owner lock caches - (Jeff Janes) - - - - This substantially improves performance when pg_dump - tries to dump a large number of tables. - - - - - - Disable SSL renegotiation by default (Michael Paquier, Andres Freund) - - - - While use of SSL renegotiation is a good idea in theory, we have seen - too many bugs in practice, both in the underlying OpenSSL library and - in our usage of it. Renegotiation will be removed entirely in 9.5 and - later. In the older branches, just change the default value - of ssl_renegotiation_limit to zero (disabled). - - - - - - Lower the minimum values of the *_freeze_max_age parameters - (Andres Freund) - - - - This is mainly to make tests of related behavior less time-consuming, - but it may also be of value for installations with limited disk space. - - - - - - Limit the maximum value of wal_buffers to 2GB to avoid - server crashes (Josh Berkus) - - - - - - Fix rare internal overflow in multiplication of numeric values - (Dean Rasheed) - - - - - - Guard against hard-to-reach stack overflows involving record types, - range types, json, jsonb, tsquery, - ltxtquery and query_int (Noah Misch) - - - - - - Fix handling of DOW and DOY in datetime input - (Greg Stark) - - - - These tokens aren't meant to be used in datetime values, but previously - they resulted in opaque internal error messages rather - than invalid input syntax. - - - - - - Add more query-cancel checks to regular expression matching (Tom Lane) - - - - - - Add recursion depth protections to regular expression, SIMILAR - TO, and LIKE matching (Tom Lane) - - - - Suitable search patterns and a low stack depth limit could lead to - stack-overrun crashes. - - - - - - Fix potential infinite loop in regular expression execution (Tom Lane) - - - - A search pattern that can apparently match a zero-length string, but - actually doesn't match because of a back reference, could lead to an - infinite loop. - - - - - - In regular expression execution, correctly record match data for - capturing parentheses within a quantifier even when the match is - zero-length (Tom Lane) - - - - - - Fix low-memory failures in regular expression compilation - (Andreas Seltenreich) - - - - - - Fix low-probability memory leak during regular expression execution - (Tom Lane) - - - - - - Fix rare low-memory failure in lock cleanup during transaction abort - (Tom Lane) - - - - - - Fix unexpected out-of-memory situation during sort errors - when using tuplestores with small work_mem settings (Tom - Lane) - - - - - - Fix very-low-probability stack overrun in qsort (Tom Lane) - - - - - - Fix invalid memory alloc request size failure in hash joins - with large work_mem settings (Tomas Vondra, Tom Lane) - - - - - - Fix assorted planner bugs (Tom Lane) - - - - These mistakes could lead to incorrect query plans that would give wrong - answers, or to assertion failures in assert-enabled builds, or to odd - planner errors such as could not devise a query plan for the - given query, could not find pathkey item to - sort, plan should not reference subplan's variable, - or failed to assign all NestLoopParams to plan nodes. - Thanks are due to Andreas Seltenreich and Piotr Stefaniak for fuzz - testing that exposed these problems. - - - - - - Improve planner's performance for UPDATE/DELETE - on large inheritance sets (Tom Lane, Dean Rasheed) - - - - - - Ensure standby promotion trigger files are removed at postmaster - startup (Michael Paquier, Fujii Masao) - - - - This prevents unwanted promotion from occurring if these files appear - in a database backup that is used to initialize a new standby server. - - - - - - During postmaster shutdown, ensure that per-socket lock files are - removed and listen sockets are closed before we remove - the postmaster.pid file (Tom Lane) - - - - This avoids race-condition failures if an external script attempts to - start a new postmaster as soon as pg_ctl stop returns. - - - - - - Fix postmaster's handling of a startup-process crash during crash - recovery (Tom Lane) - - - - If, during a crash recovery cycle, the startup process crashes without - having restored database consistency, we'd try to launch a new startup - process, which typically would just crash again, leading to an infinite - loop. - - - - - - Do not print a WARNING when an autovacuum worker is already - gone when we attempt to signal it, and reduce log verbosity for such - signals (Tom Lane) - - - - - - Prevent autovacuum launcher from sleeping unduly long if the server - clock is moved backwards a large amount (Álvaro Herrera) - - - - - - Ensure that cleanup of a GIN index's pending-insertions list is - interruptable by cancel requests (Jeff Janes) - - - - - - Allow all-zeroes pages in GIN indexes to be reused (Heikki Linnakangas) - - - - Such a page might be left behind after a crash. - - - - - - Fix handling of all-zeroes pages in SP-GiST indexes (Heikki - Linnakangas) - - - - VACUUM attempted to recycle such pages, but did so in a - way that wasn't crash-safe. - - - - - - Fix off-by-one error that led to otherwise-harmless warnings - about apparent wraparound in subtrans/multixact truncation - (Thomas Munro) - - - - - - Fix misreporting of CONTINUE and MOVE statement - types in PL/pgSQL's error context messages - (Pavel Stehule, Tom Lane) - - - - - - Fix PL/Perl to handle non-ASCII error - message texts correctly (Alex Hunsaker) - - - - - - Fix PL/Python crash when returning the string - representation of a record result (Tom Lane) - - - - - - Fix some places in PL/Tcl that neglected to check for - failure of malloc() calls (Michael Paquier, Álvaro - Herrera) - - - - - - In contrib/isn, fix output of ISBN-13 numbers that begin - with 979 (Fabien Coelho) - - - - EANs beginning with 979 (but not 9790) are considered ISBNs, but they - must be printed in the new 13-digit format, not the 10-digit format. - - - - - - - - Fix contrib/sepgsql's handling of SELECT INTO - statements (Kohei KaiGai) - - - - - - Improve libpq's handling of out-of-memory conditions - (Michael Paquier, Heikki Linnakangas) - - - - - - Fix memory leaks and missing out-of-memory checks - in ecpg (Michael Paquier) - - - - - - Fix psql's code for locale-aware formatting of numeric - output (Tom Lane) - - - - The formatting code invoked by \pset numericlocale on - did the wrong thing for some uncommon cases such as numbers with an - exponent but no decimal point. It could also mangle already-localized - output from the money data type. - - - - - - Prevent crash in psql's \c command when - there is no current connection (Noah Misch) - - - - - - Make pg_dump handle inherited NOT VALID - check constraints correctly (Tom Lane) - - - - - - Fix selection of default zlib compression level - in pg_dump's directory output format (Andrew Dunstan) - - - - - - Ensure that temporary files created during a pg_dump - run with tar-format output are not world-readable (Michael - Paquier) - - - - - - Fix pg_dump and pg_upgrade to support - cases where the postgres or template1 database - is in a non-default tablespace (Marti Raudsepp, Bruce Momjian) - - - - - - Fix pg_dump to handle object privileges sanely when - dumping from a server too old to have a particular privilege type - (Tom Lane) - - - - When dumping data types from pre-9.2 servers, and when dumping - functions or procedural languages from pre-7.3 - servers, pg_dump would - produce GRANT/REVOKE commands that revoked the - owner's grantable privileges and instead granted all privileges - to PUBLIC. Since the privileges involved are - just USAGE and EXECUTE, this isn't a security - problem, but it's certainly a surprising representation of the older - systems' behavior. Fix it to leave the default privilege state alone - in these cases. - - - - - - Fix pg_dump to dump shell types (Tom Lane) - - - - Shell types (that is, not-yet-fully-defined types) aren't useful for - much, but nonetheless pg_dump should dump them. - - - - - - Fix assorted minor memory leaks in pg_dump and other - client-side programs (Michael Paquier) - - - - - - Fix spinlock assembly code for PPC hardware to be compatible - with AIX's native assembler (Tom Lane) - - - - Building with gcc didn't work if gcc - had been configured to use the native assembler, which is becoming more - common. - - - - - - On AIX, test the -qlonglong compiler option - rather than just assuming it's safe to use (Noah Misch) - - - - - - On AIX, use -Wl,-brtllib link option to allow - symbols to be resolved at runtime (Noah Misch) - - - - Perl relies on this ability in 5.8.0 and later. - - - - - - Avoid use of inline functions when compiling with - 32-bit xlc, due to compiler bugs (Noah Misch) - - - - - - Use librt for sched_yield() when necessary, - which it is on some Solaris versions (Oskari Saarenmaa) - - - - - - Fix Windows install.bat script to handle target directory - names that contain spaces (Heikki Linnakangas) - - - - - - Make the numeric form of the PostgreSQL version number - (e.g., 90405) readily available to extension Makefiles, - as a variable named VERSION_NUM (Michael Paquier) - - - - - - Update time zone data files to tzdata release 2015g for - DST law changes in Cayman Islands, Fiji, Moldova, Morocco, Norfolk - Island, North Korea, Turkey, and Uruguay. There is a new zone name - America/Fort_Nelson for the Canadian Northern Rockies. - - - - - - - - - - Release 9.2.13 - - - Release date: - 2015-06-12 - - - - This release contains a small number of fixes from 9.2.12. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.13 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Fix rare failure to invalidate relation cache init file (Tom Lane) - - - - With just the wrong timing of concurrent activity, a VACUUM - FULL on a system catalog might fail to update the init file - that's used to avoid cache-loading work for new sessions. This would - result in later sessions being unable to access that catalog at all. - This is a very ancient bug, but it's so hard to trigger that no - reproducible case had been seen until recently. - - - - - - Avoid deadlock between incoming sessions and CREATE/DROP - DATABASE (Tom Lane) - - - - A new session starting in a database that is the target of - a DROP DATABASE command, or is the template for - a CREATE DATABASE command, could cause the command to wait - for five seconds and then fail, even if the new session would have - exited before that. - - - - - - - - - - Release 9.2.12 - - - Release date: - 2015-06-04 - - - - This release contains a small number of fixes from 9.2.11. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.12 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.11, - see . - - - - - - Changes - - - - - - Avoid failures while fsync'ing data directory during - crash restart (Abhijit Menon-Sen, Tom Lane) - - - - In the previous minor releases we added a patch to fsync - everything in the data directory after a crash. Unfortunately its - response to any error condition was to fail, thereby preventing the - server from starting up, even when the problem was quite harmless. - An example is that an unwritable file in the data directory would - prevent restart on some platforms; but it is common to make SSL - certificate files unwritable by the server. Revise this behavior so - that permissions failures are ignored altogether, and other types of - failures are logged but do not prevent continuing. - - - - - - Fix pg_get_functiondef() to show - functions' LEAKPROOF property, if set (Jeevan Chalke) - - - - - - Remove configure's check prohibiting linking to a - threaded libpython - on OpenBSD (Tom Lane) - - - - The failure this restriction was meant to prevent seems to not be a - problem anymore on current OpenBSD - versions. - - - - - - Allow libpq to use TLS protocol versions beyond v1 - (Noah Misch) - - - - For a long time, libpq was coded so that the only SSL - protocol it would allow was TLS v1. Now that newer TLS versions are - becoming popular, allow it to negotiate the highest commonly-supported - TLS version with the server. (PostgreSQL servers were - already capable of such negotiation, so no change is needed on the - server side.) This is a back-patch of a change already released in - 9.4.0. - - - - - - - - - - Release 9.2.11 - - - Release date: - 2015-05-22 - - - - This release contains a variety of fixes from 9.2.10. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.11 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you use contrib/citext's - regexp_matches() functions, see the changelog entry below - about that. - - - - Also, if you are upgrading from a version earlier than 9.2.10, - see . - - - - - - Changes - - - - - - Avoid possible crash when client disconnects just before the - authentication timeout expires (Benkocs Norbert Attila) - - - - If the timeout interrupt fired partway through the session shutdown - sequence, SSL-related state would be freed twice, typically causing a - crash and hence denial of service to other sessions. Experimentation - shows that an unauthenticated remote attacker could trigger the bug - somewhat consistently, hence treat as security issue. - (CVE-2015-3165) - - - - - - Improve detection of system-call failures (Noah Misch) - - - - Our replacement implementation of snprintf() failed to - check for errors reported by the underlying system library calls; - the main case that might be missed is out-of-memory situations. - In the worst case this might lead to information exposure, due to our - code assuming that a buffer had been overwritten when it hadn't been. - Also, there were a few places in which security-relevant calls of other - system library functions did not check for failure. - - - - It remains possible that some calls of the *printf() - family of functions are vulnerable to information disclosure if an - out-of-memory error occurs at just the wrong time. We judge the risk - to not be large, but will continue analysis in this area. - (CVE-2015-3166) - - - - - - In contrib/pgcrypto, uniformly report decryption failures - as Wrong key or corrupt data (Noah Misch) - - - - Previously, some cases of decryption with an incorrect key could report - other error message texts. It has been shown that such variance in - error reports can aid attackers in recovering keys from other systems. - While it's unknown whether pgcrypto's specific behaviors - are likewise exploitable, it seems better to avoid the risk by using a - one-size-fits-all message. - (CVE-2015-3167) - - - - - - Fix incorrect declaration of contrib/citext's - regexp_matches() functions (Tom Lane) - - - - These functions should return setof text[], like the core - functions they are wrappers for; but they were incorrectly declared as - returning just text[]. This mistake had two results: first, - if there was no match you got a scalar null result, whereas what you - should get is an empty set (zero rows). Second, the g flag - was effectively ignored, since you would get only one result array even - if there were multiple matches. - - - - While the latter behavior is clearly a bug, there might be applications - depending on the former behavior; therefore the function declarations - will not be changed by default until PostgreSQL 9.5. - In pre-9.5 branches, the old behavior exists in version 1.0 of - the citext extension, while we have provided corrected - declarations in version 1.1 (which is not installed by - default). To adopt the fix in pre-9.5 branches, execute - ALTER EXTENSION citext UPDATE TO '1.1' in each database in - which citext is installed. (You can also update - back to 1.0 if you need to undo that.) Be aware that either update - direction will require dropping and recreating any views or rules that - use citext's regexp_matches() functions. - - - - - - Fix incorrect checking of deferred exclusion constraints after a HOT - update (Tom Lane) - - - - If a new row that potentially violates a deferred exclusion constraint - is HOT-updated (that is, no indexed columns change and the row can be - stored back onto the same table page) later in the same transaction, - the exclusion constraint would be reported as violated when the check - finally occurred, even if the row(s) the new row originally conflicted - with had been deleted. - - - - - - Fix planning of star-schema-style queries (Tom Lane) - - - - Sometimes, efficient scanning of a large table requires that index - parameters be provided from more than one other table (commonly, - dimension tables whose keys are needed to index a large fact table). - The planner should be able to find such plans, but an overly - restrictive search heuristic prevented it. - - - - - - Prevent improper reordering of antijoins (NOT EXISTS joins) versus - other outer joins (Tom Lane) - - - - This oversight in the planner has been observed to cause could - not find RelOptInfo for given relids errors, but it seems possible - that sometimes an incorrect query plan might get past that consistency - check and result in silently-wrong query output. - - - - - - Fix incorrect matching of subexpressions in outer-join plan nodes - (Tom Lane) - - - - Previously, if textually identical non-strict subexpressions were used - both above and below an outer join, the planner might try to re-use - the value computed below the join, which would be incorrect because the - executor would force the value to NULL in case of an unmatched outer row. - - - - - - Fix GEQO planner to cope with failure of its join order heuristic - (Tom Lane) - - - - This oversight has been seen to lead to failed to join all - relations together errors in queries involving LATERAL, - and that might happen in other cases as well. - - - - - - Fix possible deadlock at startup - when max_prepared_transactions is too small - (Heikki Linnakangas) - - - - - - Don't archive useless preallocated WAL files after a timeline switch - (Heikki Linnakangas) - - - - - - - - Avoid cannot GetMultiXactIdMembers() during recovery error - (Álvaro Herrera) - - - - - - Recursively fsync() the data directory after a crash - (Abhijit Menon-Sen, Robert Haas) - - - - This ensures consistency if another crash occurs shortly later. (The - second crash would have to be a system-level crash, not just a database - crash, for there to be a problem.) - - - - - - Fix autovacuum launcher's possible failure to shut down, if an error - occurs after it receives SIGTERM (Álvaro Herrera) - - - - - - Cope with unexpected signals in LockBufferForCleanup() - (Andres Freund) - - - - This oversight could result in spurious errors about multiple - backends attempting to wait for pincount 1. - - - - - - Fix crash when doing COPY IN to a table with check - constraints that contain whole-row references (Tom Lane) - - - - The known failure case only crashes in 9.4 and up, but there is very - similar code in 9.3 and 9.2, so back-patch those branches as well. - - - - - - Avoid waiting for WAL flush or synchronous replication during commit of - a transaction that was read-only so far as the user is concerned - (Andres Freund) - - - - Previously, a delay could occur at commit in transactions that had - written WAL due to HOT page pruning, leading to undesirable effects - such as sessions getting stuck at startup if all synchronous replicas - are down. Sessions have also been observed to get stuck in catchup - interrupt processing when using synchronous replication; this will fix - that problem as well. - - - - - - Fix crash when manipulating hash indexes on temporary tables - (Heikki Linnakangas) - - - - - - Fix possible failure during hash index bucket split, if other processes - are modifying the index concurrently (Tom Lane) - - - - - - Check for interrupts while analyzing index expressions (Jeff Janes) - - - - ANALYZE executes index expressions many times; if there are - slow functions in such an expression, it's desirable to be able to - cancel the ANALYZE before that loop finishes. - - - - - - Ensure tableoid of a foreign table is reported - correctly when a READ COMMITTED recheck occurs after - locking rows in SELECT FOR UPDATE, UPDATE, - or DELETE (Etsuro Fujita) - - - - - - Add the name of the target server to object description strings for - foreign-server user mappings (Álvaro Herrera) - - - - - - Recommend setting include_realm to 1 when using - Kerberos/GSSAPI/SSPI authentication (Stephen Frost) - - - - Without this, identically-named users from different realms cannot be - distinguished. For the moment this is only a documentation change, but - it will become the default setting in PostgreSQL 9.5. - - - - - - Remove code for matching IPv4 pg_hba.conf entries to - IPv4-in-IPv6 addresses (Tom Lane) - - - - This hack was added in 2003 in response to a report that some Linux - kernels of the time would report IPv4 connections as having - IPv4-in-IPv6 addresses. However, the logic was accidentally broken in - 9.0. The lack of any field complaints since then shows that it's not - needed anymore. Now we have reports that the broken code causes - crashes on some systems, so let's just remove it rather than fix it. - (Had we chosen to fix it, that would make for a subtle and potentially - security-sensitive change in the effective meaning of - IPv4 pg_hba.conf entries, which does not seem like a good - thing to do in minor releases.) - - - - - - Report WAL flush, not insert, position in IDENTIFY_SYSTEM - replication command (Heikki Linnakangas) - - - - This avoids a possible startup failure - in pg_receivexlog. - - - - - - While shutting down service on Windows, periodically send status - updates to the Service Control Manager to prevent it from killing the - service too soon; and ensure that pg_ctl will wait for - shutdown (Krystian Bigaj) - - - - - - Reduce risk of network deadlock when using libpq's - non-blocking mode (Heikki Linnakangas) - - - - When sending large volumes of data, it's important to drain the input - buffer every so often, in case the server has sent enough response data - to cause it to block on output. (A typical scenario is that the server - is sending a stream of NOTICE messages during COPY FROM - STDIN.) This worked properly in the normal blocking mode, but not - so much in non-blocking mode. We've modified libpq - to opportunistically drain input when it can, but a full defense - against this problem requires application cooperation: the application - should watch for socket read-ready as well as write-ready conditions, - and be sure to call PQconsumeInput() upon read-ready. - - - - - - In libpq, fix misparsing of empty values in URI - connection strings (Thomas Fanghaenel) - - - - - - Fix array handling in ecpg (Michael Meskes) - - - - - - Fix psql to sanely handle URIs and conninfo strings as - the first parameter to \connect - (David Fetter, Andrew Dunstan, Álvaro Herrera) - - - - This syntax has been accepted (but undocumented) for a long time, but - previously some parameters might be taken from the old connection - instead of the given string, which was agreed to be undesirable. - - - - - - Suppress incorrect complaints from psql on some - platforms that it failed to write ~/.psql_history at exit - (Tom Lane) - - - - This misbehavior was caused by a workaround for a bug in very old - (pre-2006) versions of libedit. We fixed it by - removing the workaround, which will cause a similar failure to appear - for anyone still using such versions of libedit. - Recommendation: upgrade that library, or use libreadline. - - - - - - Fix pg_dump's rule for deciding which casts are - system-provided casts that should not be dumped (Tom Lane) - - - - - - In pg_dump, fix failure to honor -Z - compression level option together with -Fd - (Michael Paquier) - - - - - - Make pg_dump consider foreign key relationships - between extension configuration tables while choosing dump order - (Gilles Darold, Michael Paquier, Stephen Frost) - - - - This oversight could result in producing dumps that fail to reload - because foreign key constraints are transiently violated. - - - - - - Fix dumping of views that are just VALUES(...) but have - column aliases (Tom Lane) - - - - - - In pg_upgrade, force timeline 1 in the new cluster - (Bruce Momjian) - - - - This change prevents upgrade failures caused by bogus complaints about - missing WAL history files. - - - - - - In pg_upgrade, check for improperly non-connectable - databases before proceeding - (Bruce Momjian) - - - - - - In pg_upgrade, quote directory paths - properly in the generated delete_old_cluster script - (Bruce Momjian) - - - - - - In pg_upgrade, preserve database-level freezing info - properly - (Bruce Momjian) - - - - This oversight could cause missing-clog-file errors for tables within - the postgres and template1 databases. - - - - - - Run pg_upgrade and pg_resetxlog with - restricted privileges on Windows, so that they don't fail when run by - an administrator (Muhammad Asif Naeem) - - - - - - Improve handling of readdir() failures when scanning - directories in initdb and pg_basebackup - (Marco Nenciarini) - - - - - - - - Fix failure in pg_receivexlog (Andres Freund) - - - - A patch merge mistake in 9.2.10 led to could not create archive - status file errors. - - - - - - Fix slow sorting algorithm in contrib/intarray (Tom Lane) - - - - - - Fix compile failure on Sparc V8 machines (Rob Rowan) - - - - - - Update time zone data files to tzdata release 2015d - for DST law changes in Egypt, Mongolia, and Palestine, plus historical - changes in Canada and Chile. Also adopt revised zone abbreviations for - the America/Adak zone (HST/HDT not HAST/HADT). - - - - - - - - - - Release 9.2.10 - - - Release date: - 2015-02-05 - - - - This release contains a variety of fixes from 9.2.9. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.10 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are a Windows user and are using the Norwegian - (Bokmål) locale, manual action is needed after the upgrade to - replace any Norwegian (Bokmål)_Norway locale names stored - in PostgreSQL system catalogs with the plain-ASCII - alias Norwegian_Norway. For details see - - - - - Also, if you are upgrading from a version earlier than 9.2.9, - see . - - - - - - Changes - - - - - - Fix buffer overruns in to_char() - (Bruce Momjian) - - - - When to_char() processes a numeric formatting template - calling for a large number of digits, PostgreSQL - would read past the end of a buffer. When processing a crafted - timestamp formatting template, PostgreSQL would write - past the end of a buffer. Either case could crash the server. - We have not ruled out the possibility of attacks that lead to - privilege escalation, though they seem unlikely. - (CVE-2015-0241) - - - - - - Fix buffer overrun in replacement *printf() functions - (Tom Lane) - - - - PostgreSQL includes a replacement implementation - of printf and related functions. This code will overrun - a stack buffer when formatting a floating point number (conversion - specifiers e, E, f, F, - g or G) with requested precision greater than - about 500. This will crash the server, and we have not ruled out the - possibility of attacks that lead to privilege escalation. - A database user can trigger such a buffer overrun through - the to_char() SQL function. While that is the only - affected core PostgreSQL functionality, extension - modules that use printf-family functions may be at risk as well. - - - - This issue primarily affects PostgreSQL on Windows. - PostgreSQL uses the system implementation of these - functions where adequate, which it is on other modern platforms. - (CVE-2015-0242) - - - - - - Fix buffer overruns in contrib/pgcrypto - (Marko Tiikkaja, Noah Misch) - - - - Errors in memory size tracking within the pgcrypto - module permitted stack buffer overruns and improper dependence on the - contents of uninitialized memory. The buffer overrun cases can - crash the server, and we have not ruled out the possibility of - attacks that lead to privilege escalation. - (CVE-2015-0243) - - - - - - Fix possible loss of frontend/backend protocol synchronization after - an error - (Heikki Linnakangas) - - - - If any error occurred while the server was in the middle of reading a - protocol message from the client, it could lose synchronization and - incorrectly try to interpret part of the message's data as a new - protocol message. An attacker able to submit crafted binary data - within a command parameter might succeed in injecting his own SQL - commands this way. Statement timeout and query cancellation are the - most likely sources of errors triggering this scenario. Particularly - vulnerable are applications that use a timeout and also submit - arbitrary user-crafted data as binary query parameters. Disabling - statement timeout will reduce, but not eliminate, the risk of - exploit. Our thanks to Emil Lenngren for reporting this issue. - (CVE-2015-0244) - - - - - - Fix information leak via constraint-violation error messages - (Stephen Frost) - - - - Some server error messages show the values of columns that violate - a constraint, such as a unique constraint. If the user does not have - SELECT privilege on all columns of the table, this could - mean exposing values that the user should not be able to see. Adjust - the code so that values are displayed only when they came from the SQL - command or could be selected by the user. - (CVE-2014-8161) - - - - - - Lock down regression testing's temporary installations on Windows - (Noah Misch) - - - - Use SSPI authentication to allow connections only from the OS user - who launched the test suite. This closes on Windows the same - vulnerability previously closed on other platforms, namely that other - users might be able to connect to the test postmaster. - (CVE-2014-0067) - - - - - - Cope with the Windows locale named Norwegian (Bokmål) - (Heikki Linnakangas) - - - - Non-ASCII locale names are problematic since it's not clear what - encoding they should be represented in. Map the troublesome locale - name to a plain-ASCII alias, Norwegian_Norway. - - - - - - Avoid possible data corruption if ALTER DATABASE SET - TABLESPACE is used to move a database to a new tablespace and then - shortly later move it back to its original tablespace (Tom Lane) - - - - - - Avoid corrupting tables when ANALYZE inside a transaction - is rolled back (Andres Freund, Tom Lane, Michael Paquier) - - - - If the failing transaction had earlier removed the last index, rule, or - trigger from the table, the table would be left in a corrupted state - with the relevant pg_class flags not set though they - should be. - - - - - - Ensure that unlogged tables are copied correctly - during CREATE DATABASE or ALTER DATABASE SET - TABLESPACE (Pavan Deolasee, Andres Freund) - - - - - - Fix DROP's dependency searching to correctly handle the - case where a table column is recursively visited before its table - (Petr Jelinek, Tom Lane) - - - - This case is only known to arise when an extension creates both a - datatype and a table using that datatype. The faulty code might - refuse a DROP EXTENSION unless CASCADE is - specified, which should not be required. - - - - - - Fix use-of-already-freed-memory problem in EvalPlanQual processing - (Tom Lane) - - - - In READ COMMITTED mode, queries that lock or update - recently-updated rows could crash as a result of this bug. - - - - - - Fix planning of SELECT FOR UPDATE when using a partial - index on a child table (Kyotaro Horiguchi) - - - - In READ COMMITTED mode, SELECT FOR UPDATE must - also recheck the partial index's WHERE condition when - rechecking a recently-updated row to see if it still satisfies the - query's WHERE condition. This requirement was missed if the - index belonged to an inheritance child table, so that it was possible - to incorrectly return rows that no longer satisfy the query condition. - - - - - - Fix corner case wherein SELECT FOR UPDATE could return a row - twice, and possibly miss returning other rows (Tom Lane) - - - - In READ COMMITTED mode, a SELECT FOR UPDATE - that is scanning an inheritance tree could incorrectly return a row - from a prior child table instead of the one it should return from a - later child table. - - - - - - Reject duplicate column names in the referenced-columns list of - a FOREIGN KEY declaration (David Rowley) - - - - This restriction is per SQL standard. Previously we did not reject - the case explicitly, but later on the code would fail with - bizarre-looking errors. - - - - - - Restore previous behavior of conversion of domains to JSON - (Tom Lane) - - - - This change causes domains over numeric and boolean to be treated - like their base types for purposes of conversion to JSON. It worked - like that before 9.3.5 and 9.2.9, but was unintentionally changed - while fixing a related problem. - - - - - - Fix bugs in raising a numeric value to a large integral power - (Tom Lane) - - - - The previous code could get a wrong answer, or consume excessive - amounts of time and memory before realizing that the answer must - overflow. - - - - - - In numeric_recv(), truncate away any fractional digits - that would be hidden according to the value's dscale field - (Tom Lane) - - - - A numeric value's display scale (dscale) should - never be less than the number of nonzero fractional digits; but - apparently there's at least one broken client application that - transmits binary numeric values in which that's true. - This leads to strange behavior since the extra digits are taken into - account by arithmetic operations even though they aren't printed. - The least risky fix seems to be to truncate away such hidden - digits on receipt, so that the value is indeed what it prints as. - - - - - - Fix incorrect search for shortest-first regular expression matches - (Tom Lane) - - - - Matching would often fail when the number of allowed iterations is - limited by a ? quantifier or a bound expression. - - - - - - Reject out-of-range numeric timezone specifications (Tom Lane) - - - - Simple numeric timezone specifications exceeding +/- 168 hours (one - week) would be accepted, but could then cause null-pointer dereference - crashes in certain operations. There's no use-case for such large UTC - offsets, so reject them. - - - - - - Fix bugs in tsquery @> tsquery - operator (Heikki Linnakangas) - - - - Two different terms would be considered to match if they had the same - CRC. Also, if the second operand had more terms than the first, it - would be assumed not to be contained in the first; which is wrong - since it might contain duplicate terms. - - - - - - Improve ispell dictionary's defenses against bad affix files (Tom Lane) - - - - - - Allow more than 64K phrases in a thesaurus dictionary (David Boutin) - - - - The previous coding could crash on an oversize dictionary, so this was - deemed a back-patchable bug fix rather than a feature addition. - - - - - - Fix namespace handling in xpath() (Ali Akbar) - - - - Previously, the xml value resulting from - an xpath() call would not have namespace declarations if - the namespace declarations were attached to an ancestor element in the - input xml value, rather than to the specific element being - returned. Propagate the ancestral declaration so that the result is - correct when considered in isolation. - - - - - - Ensure that whole-row variables expose nonempty column names - to functions that pay attention to column names within composite - arguments (Tom Lane) - - - - In some contexts, constructs like row_to_json(tab.*) may - not produce the expected column names. This is fixed properly as of - 9.4; in older branches, just ensure that we produce some nonempty - name. (In some cases this will be the underlying table's column name - rather than the query-assigned alias that should theoretically be - visible.) - - - - - - Fix mishandling of system columns, - particularly tableoid, in FDW queries (Etsuro Fujita) - - - - - - Avoid doing indexed_column = ANY - (array) as an index qualifier if that leads - to an inferior plan (Andrew Gierth) - - - - In some cases, = ANY conditions applied to non-first index - columns would be done as index conditions even though it would be - better to use them as simple filter conditions. - - - - - - Fix planner problems with nested append relations, such as inherited - tables within UNION ALL subqueries (Tom Lane) - - - - - - Fail cleanly when a GiST index tuple doesn't fit on a page, rather - than going into infinite recursion (Andrew Gierth) - - - - - - Exempt tables that have per-table cost_limit - and/or cost_delay settings from autovacuum's global cost - balancing rules (Álvaro Herrera) - - - - The previous behavior resulted in basically ignoring these per-table - settings, which was unintended. Now, a table having such settings - will be vacuumed using those settings, independently of what is going - on in other autovacuum workers. This may result in heavier total I/O - load than before, so such settings should be re-examined for sanity. - - - - - - Avoid wholesale autovacuuming when autovacuum is nominally off - (Tom Lane) - - - - Even when autovacuum is nominally off, we will still launch autovacuum - worker processes to vacuum tables that are at risk of XID wraparound. - However, such a worker process then proceeded to vacuum all tables in - the target database, if they met the usual thresholds for - autovacuuming. This is at best pretty unexpected; at worst it delays - response to the wraparound threat. Fix it so that if autovacuum is - turned off, workers only do anti-wraparound vacuums and - not any other work. - - - - - - During crash recovery, ensure that unlogged relations are rewritten as - empty and are synced to disk before recovery is considered complete - (Abhijit Menon-Sen, Andres Freund) - - - - This prevents scenarios in which unlogged relations might contain - garbage data following database crash recovery. - - - - - - Fix race condition between hot standby queries and replaying a - full-page image (Heikki Linnakangas) - - - - This mistake could result in transient errors in queries being - executed in hot standby. - - - - - - Fix several cases where recovery logic improperly ignored WAL records - for COMMIT/ABORT PREPARED (Heikki Linnakangas) - - - - The most notable oversight was - that recovery_target_xid could not be used to stop at - a two-phase commit. - - - - - - Prevent latest WAL file from being archived a second time at completion - of crash recovery (Fujii Masao) - - - - - - Avoid creating unnecessary .ready marker files for - timeline history files (Fujii Masao) - - - - - - Fix possible null pointer dereference when an empty prepared statement - is used and the log_statement setting is mod - or ddl (Fujii Masao) - - - - - - Change pgstat wait timeout warning message to be LOG level, - and rephrase it to be more understandable (Tom Lane) - - - - This message was originally thought to be essentially a can't-happen - case, but it occurs often enough on our slower buildfarm members to be - a nuisance. Reduce it to LOG level, and expend a bit more effort on - the wording: it now reads using stale statistics instead of - current ones because stats collector is not responding. - - - - - - Fix SPARC spinlock implementation to ensure correctness if the CPU is - being run in a non-TSO coherency mode, as some non-Solaris kernels do - (Andres Freund) - - - - - - Warn if macOS's setlocale() starts an unwanted extra - thread inside the postmaster (Noah Misch) - - - - - - Fix processing of repeated dbname parameters - in PQconnectdbParams() (Alex Shulgin) - - - - Unexpected behavior ensued if the first occurrence - of dbname contained a connection string or URI to be - expanded. - - - - - - Ensure that libpq reports a suitable error message on - unexpected socket EOF (Marko Tiikkaja, Tom Lane) - - - - Depending on kernel behavior, libpq might return an - empty error string rather than something useful when the server - unexpectedly closed the socket. - - - - - - Clear any old error message during PQreset() - (Heikki Linnakangas) - - - - If PQreset() is called repeatedly, and the connection - cannot be re-established, error messages from the failed connection - attempts kept accumulating in the PGconn's error - string. - - - - - - Properly handle out-of-memory conditions while parsing connection - options in libpq (Alex Shulgin, Heikki Linnakangas) - - - - - - Fix array overrun in ecpg's version - of ParseDateTime() (Michael Paquier) - - - - - - In initdb, give a clearer error message if a password - file is specified but is empty (Mats Erik Andersson) - - - - - - Fix psql's \s command to work nicely with - libedit, and add pager support (Stepan Rutz, Tom Lane) - - - - When using libedit rather than readline, \s printed the - command history in a fairly unreadable encoded format, and on recent - libedit versions might fail altogether. Fix that by printing the - history ourselves rather than having the library do it. A pleasant - side-effect is that the pager is used if appropriate. - - - - This patch also fixes a bug that caused newline encoding to be applied - inconsistently when saving the command history with libedit. - Multiline history entries written by older psql - versions will be read cleanly with this patch, but perhaps not - vice versa, depending on the exact libedit versions involved. - - - - - - Improve consistency of parsing of psql's special - variables (Tom Lane) - - - - Allow variant spellings of on and off (such - as 1/0) for ECHO_HIDDEN - and ON_ERROR_ROLLBACK. Report a warning for unrecognized - values for COMP_KEYWORD_CASE, ECHO, - ECHO_HIDDEN, HISTCONTROL, - ON_ERROR_ROLLBACK, and VERBOSITY. Recognize - all values for all these variables case-insensitively; previously - there was a mishmash of case-sensitive and case-insensitive behaviors. - - - - - - Fix psql's expanded-mode display to work - consistently when using border = 3 - and linestyle = ascii or unicode - (Stephen Frost) - - - - - - Improve performance of pg_dump when the database - contains many instances of multiple dependency paths between the same - two objects (Tom Lane) - - - - - - Fix pg_dumpall to restore its ability to dump from - pre-8.1 servers (Gilles Darold) - - - - - - Fix possible deadlock during parallel restore of a schema-only dump - (Robert Haas, Tom Lane) - - - - - - Fix core dump in pg_dump --binary-upgrade on zero-column - composite type (Rushabh Lathia) - - - - - - Prevent WAL files created by pg_basebackup -x/-X from - being archived again when the standby is promoted (Andres Freund) - - - - - - Fix failure of contrib/auto_explain to print per-node - timing information when doing EXPLAIN ANALYZE (Tom Lane) - - - - - - Fix upgrade-from-unpackaged script for contrib/citext - (Tom Lane) - - - - - - Fix block number checking - in contrib/pageinspect's get_raw_page() - (Tom Lane) - - - - The incorrect checking logic could prevent access to some pages in - non-main relation forks. - - - - - - Fix contrib/pgcrypto's pgp_sym_decrypt() - to not fail on messages whose length is 6 less than a power of 2 - (Marko Tiikkaja) - - - - - - Fix file descriptor leak in contrib/pg_test_fsync - (Jeff Janes) - - - - This could cause failure to remove temporary files on Windows. - - - - - - Handle unexpected query results, especially NULLs, safely in - contrib/tablefunc's connectby() - (Michael Paquier) - - - - connectby() previously crashed if it encountered a NULL - key value. It now prints that row but doesn't recurse further. - - - - - - Avoid a possible crash in contrib/xml2's - xslt_process() (Mark Simonetti) - - - - libxslt seems to have an undocumented dependency on - the order in which resources are freed; reorder our calls to avoid a - crash. - - - - - - Mark some contrib I/O functions with correct volatility - properties (Tom Lane) - - - - The previous over-conservative marking was immaterial in normal use, - but could cause optimization problems or rejection of valid index - expression definitions. Since the consequences are not large, we've - just adjusted the function definitions in the extension modules' - scripts, without changing version numbers. - - - - - - Numerous cleanups of warnings from Coverity static code analyzer - (Andres Freund, Tatsuo Ishii, Marko Kreen, Tom Lane, Michael Paquier) - - - - These changes are mostly cosmetic but in some cases fix corner-case - bugs, for example a crash rather than a proper error report after an - out-of-memory failure. None are believed to represent security - issues. - - - - - - Detect incompatible OpenLDAP versions during build (Noah Misch) - - - - With OpenLDAP versions 2.4.24 through 2.4.31, - inclusive, PostgreSQL backends can crash at exit. - Raise a warning during configure based on the - compile-time OpenLDAP version number, and test the crashing scenario - in the contrib/dblink regression test. - - - - - - In non-MSVC Windows builds, ensure libpq.dll is installed - with execute permissions (Noah Misch) - - - - - - Make pg_regress remove any temporary installation it - created upon successful exit (Tom Lane) - - - - This results in a very substantial reduction in disk space usage - during make check-world, since that sequence involves - creation of numerous temporary installations. - - - - - - Support time zone abbreviations that change UTC offset from time to - time (Tom Lane) - - - - Previously, PostgreSQL assumed that the UTC offset - associated with a time zone abbreviation (such as EST) - never changes in the usage of any particular locale. However this - assumption fails in the real world, so introduce the ability for a - zone abbreviation to represent a UTC offset that sometimes changes. - Update the zone abbreviation definition files to make use of this - feature in timezone locales that have changed the UTC offset of their - abbreviations since 1970 (according to the IANA timezone database). - In such timezones, PostgreSQL will now associate the - correct UTC offset with the abbreviation depending on the given date. - - - - - - Update time zone abbreviations lists (Tom Lane) - - - - Add CST (China Standard Time) to our lists. - Remove references to ADT as Arabia Daylight Time, an - abbreviation that's been out of use since 2007; therefore, claiming - there is a conflict with Atlantic Daylight Time doesn't seem - especially helpful. - Fix entirely incorrect GMT offsets for CKT (Cook Islands), FJT, and FJST - (Fiji); we didn't even have them on the proper side of the date line. - - - - - - Update time zone data files to tzdata release 2015a. - - - - The IANA timezone database has adopted abbreviations of the form - AxST/AxDT - for all Australian time zones, reflecting what they believe to be - current majority practice Down Under. These names do not conflict - with usage elsewhere (other than ACST for Acre Summer Time, which has - been in disuse since 1994). Accordingly, adopt these names into - our Default timezone abbreviation set. - The Australia abbreviation set now contains only CST, EAST, - EST, SAST, SAT, and WST, all of which are thought to be mostly - historical usage. Note that SAST has also been changed to be South - Africa Standard Time in the Default abbreviation set. - - - - Also, add zone abbreviations SRET (Asia/Srednekolymsk) and XJT - (Asia/Urumqi), and use WSST/WSDT for western Samoa. Also, there were - DST law changes in Chile, Mexico, the Turks & Caicos Islands - (America/Grand_Turk), and Fiji. There is a new zone - Pacific/Bougainville for portions of Papua New Guinea. Also, numerous - corrections for historical (pre-1970) time zone data. - - - - - - - - - - Release 9.2.9 - - - Release date: - 2014-07-24 - - - - This release contains a variety of fixes from 9.2.8. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.9 - - - A dump/restore is not required for those running 9.2.X. - - - - However, this release corrects an index corruption problem in some GiST - indexes. See the first changelog entry below to find out whether your - installation has been affected and what steps you should take if so. - - - - Also, if you are upgrading from a version earlier than 9.2.6, - see . - - - - - - Changes - - - - - - Correctly initialize padding bytes in contrib/btree_gist - indexes on bit columns (Heikki Linnakangas) - - - - This error could result in incorrect query results due to values that - should compare equal not being seen as equal. - Users with GiST indexes on bit or bit varying - columns should REINDEX those indexes after installing this - update. - - - - - - Protect against torn pages when deleting GIN list pages (Heikki - Linnakangas) - - - - This fix prevents possible index corruption if a system crash occurs - while the page update is being written to disk. - - - - - - Don't clear the right-link of a GiST index page while replaying - updates from WAL (Heikki Linnakangas) - - - - This error could lead to transiently wrong answers from GiST index - scans performed in Hot Standby. - - - - - - Fix corner-case infinite loop during insertion into an SP-GiST text - index (Tom Lane) - - - - - - Fix feedback status when is - turned off on-the-fly (Simon Riggs) - - - - - - Fix possibly-incorrect cache invalidation during nested calls - to ReceiveSharedInvalidMessages (Andres Freund) - - - - - - Fix planner's mishandling of nested PlaceHolderVars generated in - nested-nestloop plans (Tom Lane) - - - - This oversight could result in variable not found in subplan - target lists errors, or in silently wrong query results. - - - - - - Fix could not find pathkey item to sort planner failures - with UNION ALL over subqueries reading from tables with - inheritance children (Tom Lane) - - - - - - Don't assume a subquery's output is unique if there's a set-returning - function in its targetlist (David Rowley) - - - - This oversight could lead to misoptimization of constructs - like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP - BY y). - - - - - - Improve planner to drop constant-NULL inputs - of AND/OR when possible (Tom Lane) - - - - This change fixes some cases where the more aggressive parameter - substitution done by 9.2 and later can lead to a worse plan than - older versions produced. - - - - - - Fix identification of input type category in to_json() - and friends (Tom Lane) - - - - This is known to have led to inadequate quoting of money - fields in the JSON result, and there may have been wrong - results for other data types as well. - - - - - - Fix failure to detoast fields in composite elements of structured - types (Tom Lane) - - - - This corrects cases where TOAST pointers could be copied into other - tables without being dereferenced. If the original data is later - deleted, it would lead to errors like missing chunk number 0 - for toast value ... when the now-dangling pointer is used. - - - - - - Fix record type has not been registered failures with - whole-row references to the output of Append plan nodes (Tom Lane) - - - - - - Fix possible crash when invoking a user-defined function while - rewinding a cursor (Tom Lane) - - - - - - Fix query-lifespan memory leak while evaluating the arguments for a - function in FROM (Tom Lane) - - - - - - Fix session-lifespan memory leaks in regular-expression processing - (Tom Lane, Arthur O'Dwyer, Greg Stark) - - - - - - Fix data encoding error in hungarian.stop (Tom Lane) - - - - - - Prevent foreign tables from being created with OIDS - when is true - (Etsuro Fujita) - - - - - - Fix liveness checks for rows that were inserted in the current - transaction and then deleted by a now-rolled-back subtransaction - (Andres Freund) - - - - This could cause problems (at least spurious warnings, and at worst an - infinite loop) if CREATE INDEX or CLUSTER were - done later in the same transaction. - - - - - - Clear pg_stat_activity.xact_start - during PREPARE TRANSACTION (Andres Freund) - - - - After the PREPARE, the originating session is no longer in - a transaction, so it should not continue to display a transaction - start time. - - - - - - Fix REASSIGN OWNED to not fail for text search objects - (Álvaro Herrera) - - - - - - Block signals during postmaster startup (Tom Lane) - - - - This ensures that the postmaster will properly clean up after itself - if, for example, it receives SIGINT while still - starting up. - - - - - - Fix client host name lookup when processing pg_hba.conf - entries that specify host names instead of IP addresses (Tom Lane) - - - - Ensure that reverse-DNS lookup failures are reported, instead of just - silently not matching such entries. Also ensure that we make only - one reverse-DNS lookup attempt per connection, not one per host name - entry, which is what previously happened if the lookup attempts failed. - - - - - - Allow the root user to use postgres -C variable and - postgres --describe-config (MauMau) - - - - The prohibition on starting the server as root does not need to extend - to these operations, and relaxing it prevents failure - of pg_ctl in some scenarios. - - - - - - Secure Unix-domain sockets of temporary postmasters started during - make check (Noah Misch) - - - - Any local user able to access the socket file could connect as the - server's bootstrap superuser, then proceed to execute arbitrary code as - the operating-system user running the test, as we previously noted in - CVE-2014-0067. This change defends against that risk by placing the - server's socket in a temporary, mode 0700 subdirectory - of /tmp. The hazard remains however on platforms where - Unix sockets are not supported, notably Windows, because then the - temporary postmaster must accept local TCP connections. - - - - A useful side effect of this change is to simplify - make check testing in builds that - override DEFAULT_PGSOCKET_DIR. Popular non-default values - like /var/run/postgresql are often not writable by the - build user, requiring workarounds that will no longer be necessary. - - - - - - Fix tablespace creation WAL replay to work on Windows (MauMau) - - - - - - Fix detection of socket creation failures on Windows (Bruce Momjian) - - - - - - On Windows, allow new sessions to absorb values of PGC_BACKEND - parameters (such as ) from the - configuration file (Amit Kapila) - - - - Previously, if such a parameter were changed in the file post-startup, - the change would have no effect. - - - - - - Properly quote executable path names on Windows (Nikhil Deshpande) - - - - This oversight could cause initdb - and pg_upgrade to fail on Windows, if the installation - path contained both spaces and @ signs. - - - - - - Fix linking of libpython on macOS (Tom Lane) - - - - The method we previously used can fail with the Python library - supplied by Xcode 5.0 and later. - - - - - - Avoid buffer bloat in libpq when the server - consistently sends data faster than the client can absorb it - (Shin-ichi Morita, Tom Lane) - - - - libpq could be coerced into enlarging its input buffer - until it runs out of memory (which would be reported misleadingly - as lost synchronization with server). Under ordinary - circumstances it's quite far-fetched that data could be continuously - transmitted more quickly than the recv() loop can - absorb it, but this has been observed when the client is artificially - slowed by scheduler constraints. - - - - - - Ensure that LDAP lookup attempts in libpq time out as - intended (Laurenz Albe) - - - - - - Fix ecpg to do the right thing when an array - of char * is the target for a FETCH statement returning more - than one row, as well as some other array-handling fixes - (Ashutosh Bapat) - - - - - - Fix pg_restore's processing of old-style large object - comments (Tom Lane) - - - - A direct-to-database restore from an archive file generated by a - pre-9.0 version of pg_dump would usually fail if the - archive contained more than a few comments for large objects. - - - - - - Fix pg_upgrade for cases where the new server creates - a TOAST table but the old version did not (Bruce Momjian) - - - - This rare situation would manifest as relation OID mismatch - errors. - - - - - - Prevent contrib/auto_explain from changing the output of - a user's EXPLAIN (Tom Lane) - - - - If auto_explain is active, it could cause - an EXPLAIN (ANALYZE, TIMING OFF) command to nonetheless - print timing information. - - - - - - Fix query-lifespan memory leak in contrib/dblink - (MauMau, Joe Conway) - - - - - - In contrib/pgcrypto functions, ensure sensitive - information is cleared from stack variables before returning - (Marko Kreen) - - - - - - Prevent use of already-freed memory in - contrib/pgstattuple's pgstat_heap() - (Noah Misch) - - - - - - In contrib/uuid-ossp, cache the state of the OSSP UUID - library across calls (Tom Lane) - - - - This improves the efficiency of UUID generation and reduces the amount - of entropy drawn from /dev/urandom, on platforms that - have that. - - - - - - Update time zone data files to tzdata release 2014e - for DST law changes in Crimea, Egypt, and Morocco. - - - - - - - - - - Release 9.2.8 - - - Release date: - 2014-03-20 - - - - This release contains a variety of fixes from 9.2.7. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.8 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.6, - see . - - - - - - Changes - - - - - - Restore GIN metapages unconditionally to avoid torn-page risk - (Heikki Linnakangas) - - - - Although this oversight could theoretically result in a corrupted - index, it is unlikely to have caused any problems in practice, since - the active part of a GIN metapage is smaller than a standard 512-byte - disk sector. - - - - - - Avoid race condition in checking transaction commit status during - receipt of a NOTIFY message (Marko Tiikkaja) - - - - This prevents a scenario wherein a sufficiently fast client might - respond to a notification before database updates made by the - notifier have become visible to the recipient. - - - - - - Allow regular-expression operators to be terminated early by query - cancel requests (Tom Lane) - - - - This prevents scenarios wherein a pathological regular expression - could lock up a server process uninterruptibly for a long time. - - - - - - Remove incorrect code that tried to allow OVERLAPS with - single-element row arguments (Joshua Yanovski) - - - - This code never worked correctly, and since the case is neither - specified by the SQL standard nor documented, it seemed better to - remove it than fix it. - - - - - - Avoid getting more than AccessShareLock when de-parsing a - rule or view (Dean Rasheed) - - - - This oversight resulted in pg_dump unexpectedly - acquiring RowExclusiveLock locks on tables mentioned as - the targets of INSERT/UPDATE/DELETE - commands in rules. While usually harmless, that could interfere with - concurrent transactions that tried to acquire, for example, - ShareLock on those tables. - - - - - - Improve performance of index endpoint probes during planning (Tom Lane) - - - - This change fixes a significant performance problem that occurred - when there were many not-yet-committed rows at the end of the index, - which is a common situation for indexes on sequentially-assigned - values such as timestamps or sequence-generated identifiers. - - - - - - Fix walsender's failure to shut down cleanly when client - is pg_receivexlog (Fujii Masao) - - - - - - Check WAL level and hot standby parameters correctly when doing crash - recovery that will be followed by archive recovery (Heikki Linnakangas) - - - - - - Fix test to see if hot standby connections can be allowed immediately - after a crash (Heikki Linnakangas) - - - - - - Prevent interrupts while reporting non-ERROR messages - (Tom Lane) - - - - This guards against rare server-process freezeups due to recursive - entry to syslog(), and perhaps other related problems. - - - - - - Fix memory leak in PL/Perl when returning a composite result, including - multiple-OUT-parameter cases (Alex Hunsaker) - - - - - - Fix tracking of psql script line numbers - during \copy from out-of-line data - (Kumar Rajeev Rastogi, Amit Khandekar) - - - - \copy ... from incremented the script file line number - for each data line, even if the data was not coming from the script - file. This mistake resulted in wrong line numbers being reported for - any errors occurring later in the same script file. - - - - - - Prevent intermittent could not reserve shared memory region - failures on recent Windows versions (MauMau) - - - - - - Update time zone data files to tzdata release 2014a - for DST law changes in Fiji and Turkey, plus historical changes in - Israel and Ukraine. - - - - - - - - - - Release 9.2.7 - - - Release date: - 2014-02-20 - - - - This release contains a variety of fixes from 9.2.6. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.7 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.6, - see . - - - - - - Changes - - - - - - Shore up GRANT ... WITH ADMIN OPTION restrictions - (Noah Misch) - - - - Granting a role without ADMIN OPTION is supposed to - prevent the grantee from adding or removing members from the granted - role, but this restriction was easily bypassed by doing SET - ROLE first. The security impact is mostly that a role member can - revoke the access of others, contrary to the wishes of his grantor. - Unapproved role member additions are a lesser concern, since an - uncooperative role member could provide most of his rights to others - anyway by creating views or SECURITY DEFINER functions. - (CVE-2014-0060) - - - - - - Prevent privilege escalation via manual calls to PL validator - functions (Andres Freund) - - - - The primary role of PL validator functions is to be called implicitly - during CREATE FUNCTION, but they are also normal SQL - functions that a user can call explicitly. Calling a validator on - a function actually written in some other language was not checked - for and could be exploited for privilege-escalation purposes. - The fix involves adding a call to a privilege-checking function in - each validator function. Non-core procedural languages will also - need to make this change to their own validator functions, if any. - (CVE-2014-0061) - - - - - - Avoid multiple name lookups during table and index DDL - (Robert Haas, Andres Freund) - - - - If the name lookups come to different conclusions due to concurrent - activity, we might perform some parts of the DDL on a different table - than other parts. At least in the case of CREATE INDEX, - this can be used to cause the permissions checks to be performed - against a different table than the index creation, allowing for a - privilege escalation attack. - (CVE-2014-0062) - - - - - - Prevent buffer overrun with long datetime strings (Noah Misch) - - - - The MAXDATELEN constant was too small for the longest - possible value of type interval, allowing a buffer overrun - in interval_out(). Although the datetime input - functions were more careful about avoiding buffer overrun, the limit - was short enough to cause them to reject some valid inputs, such as - input containing a very long timezone name. The ecpg - library contained these vulnerabilities along with some of its own. - (CVE-2014-0063) - - - - - - Prevent buffer overrun due to integer overflow in size calculations - (Noah Misch, Heikki Linnakangas) - - - - Several functions, mostly type input functions, calculated an - allocation size without checking for overflow. If overflow did - occur, a too-small buffer would be allocated and then written past. - (CVE-2014-0064) - - - - - - Prevent overruns of fixed-size buffers - (Peter Eisentraut, Jozef Mlich) - - - - Use strlcpy() and related functions to provide a clear - guarantee that fixed-size buffers are not overrun. Unlike the - preceding items, it is unclear whether these cases really represent - live issues, since in most cases there appear to be previous - constraints on the size of the input string. Nonetheless it seems - prudent to silence all Coverity warnings of this type. - (CVE-2014-0065) - - - - - - Avoid crashing if crypt() returns NULL (Honza Horak, - Bruce Momjian) - - - - There are relatively few scenarios in which crypt() - could return NULL, but contrib/chkpass would crash - if it did. One practical case in which this could be an issue is - if libc is configured to refuse to execute unapproved - hashing algorithms (e.g., FIPS mode). - (CVE-2014-0066) - - - - - - Document risks of make check in the regression testing - instructions (Noah Misch, Tom Lane) - - - - Since the temporary server started by make check - uses trust authentication, another user on the same machine - could connect to it as database superuser, and then potentially - exploit the privileges of the operating-system user who started the - tests. A future release will probably incorporate changes in the - testing procedure to prevent this risk, but some public discussion is - needed first. So for the moment, just warn people against using - make check when there are untrusted users on the - same machine. - (CVE-2014-0067) - - - - - - Fix possible mis-replay of WAL records when some segments of a - relation aren't full size (Greg Stark, Tom Lane) - - - - The WAL update could be applied to the wrong page, potentially many - pages past where it should have been. Aside from corrupting data, - this error has been observed to result in significant bloat - of standby servers compared to their masters, due to updates being - applied far beyond where the end-of-file should have been. This - failure mode does not appear to be a significant risk during crash - recovery, only when initially synchronizing a standby created from a - base backup taken from a quickly-changing master. - - - - - - Fix bug in determining when recovery has reached consistency - (Tomonari Katsumata, Heikki Linnakangas) - - - - In some cases WAL replay would mistakenly conclude that the database - was already consistent at the start of replay, thus possibly allowing - hot-standby queries before the database was really consistent. Other - symptoms such as PANIC: WAL contains references to invalid - pages were also possible. - - - - - - Fix improper locking of btree index pages while replaying - a VACUUM operation in hot-standby mode (Andres Freund, - Heikki Linnakangas, Tom Lane) - - - - This error could result in PANIC: WAL contains references to - invalid pages failures. - - - - - - Ensure that insertions into non-leaf GIN index pages write a full-page - WAL record when appropriate (Heikki Linnakangas) - - - - The previous coding risked index corruption in the event of a - partial-page write during a system crash. - - - - - - When pause_at_recovery_target - and recovery_target_inclusive are both set, ensure the - target record is applied before pausing, not after (Heikki - Linnakangas) - - - - - - Fix race conditions during server process exit (Robert Haas) - - - - Ensure that signal handlers don't attempt to use the - process's MyProc pointer after it's no longer valid. - - - - - - Fix race conditions in walsender shutdown logic and walreceiver - SIGHUP signal handler (Tom Lane) - - - - - - Fix unsafe references to errno within error reporting - logic (Christian Kruse) - - - - This would typically lead to odd behaviors such as missing or - inappropriate HINT fields. - - - - - - Fix possible crashes from using ereport() too early - during server startup (Tom Lane) - - - - The principal case we've seen in the field is a crash if the server - is started in a directory it doesn't have permission to read. - - - - - - Clear retry flags properly in OpenSSL socket write - function (Alexander Kukushkin) - - - - This omission could result in a server lockup after unexpected loss - of an SSL-encrypted connection. - - - - - - Fix length checking for Unicode identifiers (U&"..." - syntax) containing escapes (Tom Lane) - - - - A spurious truncation warning would be printed for such identifiers - if the escaped form of the identifier was too long, but the - identifier actually didn't need truncation after de-escaping. - - - - - - Allow keywords that are type names to be used in lists of roles - (Stephen Frost) - - - - A previous patch allowed such keywords to be used without quoting - in places such as role identifiers; but it missed cases where a - list of role identifiers was permitted, such as DROP ROLE. - - - - - - Fix parser crash for EXISTS(SELECT * FROM - zero_column_table) (Tom Lane) - - - - - - Fix possible crash due to invalid plan for nested sub-selects, such - as WHERE (... x IN (SELECT ...) ...) IN (SELECT ...) - (Tom Lane) - - - - - - Fix UPDATE/DELETE of an inherited target table - that has UNION ALL subqueries (Tom Lane) - - - - Without this fix, UNION ALL subqueries aren't correctly - inserted into the update plans for inheritance child tables after the - first one, typically resulting in no update happening for those child - table(s). - - - - - - Ensure that ANALYZE creates statistics for a table column - even when all the values in it are too wide (Tom Lane) - - - - ANALYZE intentionally omits very wide values from its - histogram and most-common-values calculations, but it neglected to do - something sane in the case that all the sampled entries are too wide. - - - - - - In ALTER TABLE ... SET TABLESPACE, allow the database's - default tablespace to be used without a permissions check - (Stephen Frost) - - - - CREATE TABLE has always allowed such usage, - but ALTER TABLE didn't get the memo. - - - - - - Fix cannot accept a set error when some arms of - a CASE return a set and others don't (Tom Lane) - - - - - - Properly distinguish numbers from non-numbers when generating JSON - output (Andrew Dunstan) - - - - - - Fix checks for all-zero client addresses in pgstat functions (Kevin - Grittner) - - - - - - Fix possible misclassification of multibyte characters by the text - search parser (Tom Lane) - - - - Non-ASCII characters could be misclassified when using C locale with - a multibyte encoding. On Cygwin, non-C locales could fail as well. - - - - - - Fix possible misbehavior in plainto_tsquery() - (Heikki Linnakangas) - - - - Use memmove() not memcpy() for copying - overlapping memory regions. There have been no field reports of - this actually causing trouble, but it's certainly risky. - - - - - - Fix placement of permissions checks in pg_start_backup() - and pg_stop_backup() (Andres Freund, Magnus Hagander) - - - - The previous coding might attempt to do catalog access when it - shouldn't. - - - - - - Accept SHIFT_JIS as an encoding name for locale checking - purposes (Tatsuo Ishii) - - - - - - Fix *-qualification of named parameters in SQL-language - functions (Tom Lane) - - - - Given a composite-type parameter - named foo, $1.* worked fine, - but foo.* not so much. - - - - - - Fix misbehavior of PQhost() on Windows (Fujii Masao) - - - - It should return localhost if no host has been specified. - - - - - - Improve error handling in libpq and psql - for failures during COPY TO STDOUT/FROM STDIN (Tom Lane) - - - - In particular this fixes an infinite loop that could occur in 9.2 and - up if the server connection was lost during COPY FROM - STDIN. Variants of that scenario might be possible in older - versions, or with other client applications. - - - - - - Fix incorrect translation handling in - some psql \d commands - (Peter Eisentraut, Tom Lane) - - - - - - Ensure pg_basebackup's background process is killed - when exiting its foreground process (Magnus Hagander) - - - - - - Fix possible incorrect printing of filenames - in pg_basebackup's verbose mode (Magnus Hagander) - - - - - - Avoid including tablespaces inside PGDATA twice in base backups - (Dimitri Fontaine, Magnus Hagander) - - - - - - Fix misaligned descriptors in ecpg (MauMau) - - - - - - In ecpg, handle lack of a hostname in the connection - parameters properly (Michael Meskes) - - - - - - Fix performance regression in contrib/dblink connection - startup (Joe Conway) - - - - Avoid an unnecessary round trip when client and server encodings match. - - - - - - In contrib/isn, fix incorrect calculation of the check - digit for ISMN values (Fabien Coelho) - - - - - - Fix contrib/pg_stat_statement's handling - of CURRENT_DATE and related constructs (Kyotaro - Horiguchi) - - - - - - Ensure client-code-only installation procedure works as documented - (Peter Eisentraut) - - - - - - In Mingw and Cygwin builds, install the libpq DLL - in the bin directory (Andrew Dunstan) - - - - This duplicates what the MSVC build has long done. It should fix - problems with programs like psql failing to start - because they can't find the DLL. - - - - - - Avoid using the deprecated dllwrap tool in Cygwin builds - (Marco Atzeri) - - - - - - Don't generate plain-text HISTORY - and src/test/regress/README files anymore (Tom Lane) - - - - These text files duplicated the main HTML and PDF documentation - formats. The trouble involved in maintaining them greatly outweighs - the likely audience for plain-text format. Distribution tarballs - will still contain files by these names, but they'll just be stubs - directing the reader to consult the main documentation. - The plain-text INSTALL file will still be maintained, as - there is arguably a use-case for that. - - - - - - Update time zone data files to tzdata release 2013i - for DST law changes in Jordan and historical changes in Cuba. - - - - In addition, the zones Asia/Riyadh87, - Asia/Riyadh88, and Asia/Riyadh89 have been - removed, as they are no longer maintained by IANA, and never - represented actual civil timekeeping practice. - - - - - - - - - - Release 9.2.6 - - - Release date: - 2013-12-05 - - - - This release contains a variety of fixes from 9.2.5. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.6 - - - A dump/restore is not required for those running 9.2.X. - - - - However, this release corrects a number of potential data corruption - issues. See the first two changelog entries below to find out whether - your installation has been affected and what steps you can take if so. - - - - Also, if you are upgrading from a version earlier than 9.2.4, - see . - - - - - - Changes - - - - - - Fix VACUUM's tests to see whether it can - update relfrozenxid (Andres Freund) - - - - In some cases VACUUM (either manual or autovacuum) could - incorrectly advance a table's relfrozenxid value, - allowing tuples to escape freezing, causing those rows to become - invisible once 2^31 transactions have elapsed. The probability of - data loss is fairly low since multiple incorrect advancements would - need to happen before actual loss occurs, but it's not zero. In 9.2.0 - and later, the probability of loss is higher, and it's also possible - to get could not access status of transaction errors as a - consequence of this bug. Users upgrading from releases 9.0.4 or 8.4.8 - or earlier are not affected, but all later versions contain the bug. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix any latent corruption but will not be able - to fix all pre-existing data errors. However, an installation can be - presumed safe after performing this vacuuming if it has executed fewer - than 2^31 update transactions in its lifetime (check this with - SELECT txid_current() < 2^31). - - - - - - Fix initialization of pg_clog and pg_subtrans - during hot standby startup (Andres Freund, Heikki Linnakangas) - - - - This bug can cause data loss on standby servers at the moment they - start to accept hot-standby queries, by marking committed transactions - as uncommitted. The likelihood of such corruption is small unless, at - the time of standby startup, the primary server has executed many - updating transactions since its last checkpoint. Symptoms include - missing rows, rows that should have been deleted being still visible, - and obsolete versions of updated rows being still visible alongside - their newer versions. - - - - This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. - Standby servers that have only been running earlier releases are not - at risk. It's recommended that standby servers that have ever run any - of the buggy releases be re-cloned from the primary (e.g., with a new - base backup) after upgrading. - - - - - - Fix dangling-pointer problem in fast-path locking (Tom Lane) - - - - This could lead to corruption of the lock data structures in shared - memory, causing lock already held and other odd errors. - - - - - - Truncate pg_multixact contents during WAL replay - (Andres Freund) - - - - This avoids ever-increasing disk space consumption in standby servers. - - - - - - Ensure an anti-wraparound VACUUM counts a page as scanned - when it's only verified that no tuples need freezing (Sergey - Burladyan, Jeff Janes) - - - - This bug could result in failing to - advance relfrozenxid, so that the table would still be - thought to need another anti-wraparound vacuum. In the worst case the - database might even shut down to prevent wraparound. - - - - - - Fix race condition in GIN index posting tree page deletion (Heikki - Linnakangas) - - - - This could lead to transient wrong answers or query failures. - - - - - - Fix unexpected spgdoinsert() failure error during SP-GiST - index creation (Teodor Sigaev) - - - - - - Avoid flattening a subquery whose SELECT list contains a - volatile function wrapped inside a sub-SELECT (Tom Lane) - - - - This avoids unexpected results due to extra evaluations of the - volatile function. - - - - - - Fix planner's processing of non-simple-variable subquery outputs - nested within outer joins (Tom Lane) - - - - This error could lead to incorrect plans for queries involving - multiple levels of subqueries within JOIN syntax. - - - - - - Fix incorrect planning in cases where the same non-strict expression - appears in multiple WHERE and outer JOIN - equality clauses (Tom Lane) - - - - - - Fix planner crash with whole-row reference to a subquery (Tom Lane) - - - - - - Fix incorrect generation of optimized MIN()/MAX() plans for - inheritance trees (Tom Lane) - - - - The planner could fail in cases where the MIN()/MAX() argument was an - expression rather than a simple variable. - - - - - - Fix premature deletion of temporary files (Andres Freund) - - - - - - Prevent intra-transaction memory leak when printing range values - (Tom Lane) - - - - This fix actually cures transient memory leaks in any datatype output - function, but range types are the only ones known to have had a - significant problem. - - - - - - Prevent incorrect display of dropped columns in NOT NULL and CHECK - constraint violation messages (Michael Paquier and Tom Lane) - - - - - - Allow default arguments and named-argument notation for window - functions (Tom Lane) - - - - Previously, these cases were likely to crash. - - - - - - Fix possible read past end of memory in rule printing (Peter Eisentraut) - - - - - - Fix array slicing of int2vector and oidvector values - (Tom Lane) - - - - Expressions of this kind are now implicitly promoted to - regular int2 or oid arrays. - - - - - - Fix incorrect behaviors when using a SQL-standard, simple GMT offset - timezone (Tom Lane) - - - - In some cases, the system would use the simple GMT offset value when - it should have used the regular timezone setting that had prevailed - before the simple offset was selected. This change also causes - the timeofday function to honor the simple GMT offset - zone. - - - - - - Prevent possible misbehavior when logging translations of Windows - error codes (Tom Lane) - - - - - - Properly quote generated command lines in pg_ctl - (Naoya Anzai and Tom Lane) - - - - This fix applies only to Windows. - - - - - - Fix pg_dumpall to work when a source database - sets default_transaction_read_only - via ALTER DATABASE SET (Kevin Grittner) - - - - Previously, the generated script would fail during restore. - - - - - - Make ecpg search for quoted cursor names - case-sensitively (Zoltán Böszörményi) - - - - - - Fix ecpg's processing of lists of variables - declared varchar (Zoltán Böszörményi) - - - - - - Make contrib/lo defend against incorrect trigger definitions - (Marc Cousin) - - - - - - Update time zone data files to tzdata release 2013h - for DST law changes in Argentina, Brazil, Jordan, Libya, - Liechtenstein, Morocco, and Palestine. Also, new timezone - abbreviations WIB, WIT, WITA for Indonesia. - - - - - - - - - - Release 9.2.5 - - - Release date: - 2013-10-10 - - - - This release contains a variety of fixes from 9.2.4. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.5 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.4, - see . - - - - - - Changes - - - - - - Prevent corruption of multi-byte characters when attempting to - case-fold identifiers (Andrew Dunstan) - - - - PostgreSQL case-folds non-ASCII characters only - when using a single-byte server encoding. - - - - - - Fix memory leak when creating B-tree indexes on range columns - (Heikki Linnakangas) - - - - - - Fix checkpoint memory leak in background writer when wal_level = - hot_standby (Naoya Anzai) - - - - - - Fix memory leak caused by lo_open() failure - (Heikki Linnakangas) - - - - - - Fix memory overcommit bug when work_mem is using more - than 24GB of memory (Stephen Frost) - - - - - - Serializable snapshot fixes (Kevin Grittner, Heikki Linnakangas) - - - - - - Fix deadlock bug in libpq when using SSL (Stephen Frost) - - - - - - Fix possible SSL state corruption in threaded libpq applications - (Nick Phillips, Stephen Frost) - - - - - - Improve estimate of planner cost when choosing between generic and - custom plans (Tom Lane) - - - - This change will favor generic plans when planning cost is high. - - - - - - Properly compute row estimates for boolean columns containing many NULL - values (Andrew Gierth) - - - - Previously tests like col IS NOT TRUE and col IS - NOT FALSE did not properly factor in NULL values when estimating - plan costs. - - - - - - Fix accounting for qualifier evaluation costs in UNION ALL - and inheritance queries (Tom Lane) - - - - This fixes cases where suboptimal query plans could be chosen if - some WHERE clauses are expensive to calculate. - - - - - - Prevent pushing down WHERE clauses into unsafe - UNION/INTERSECT subqueries (Tom Lane) - - - - Subqueries of a UNION or INTERSECT that - contain set-returning functions or volatile functions in their - SELECT lists could be improperly optimized, leading to - run-time errors or incorrect query results. - - - - - - Fix rare case of failed to locate grouping columns - planner failure (Tom Lane) - - - - - - Fix pg_dump of foreign tables with dropped columns (Andrew Dunstan) - - - - Previously such cases could cause a pg_upgrade error. - - - - - - Reorder pg_dump processing of extension-related - rules and event triggers (Joe Conway) - - - - - - Force dumping of extension tables if specified by pg_dump - -t or -n (Joe Conway) - - - - - - Improve view dumping code's handling of dropped columns in referenced - tables (Tom Lane) - - - - - - Fix pg_restore -l with the directory archive to display - the correct format name (Fujii Masao) - - - - - - Properly record index comments created using UNIQUE - and PRIMARY KEY syntax (Andres Freund) - - - - This fixes a parallel pg_restore failure. - - - - - - Cause pg_basebackup -x with an empty xlog directory - to throw an error rather than crashing (Magnus Hagander, Haruka - Takatsuka) - - - - - - Properly guarantee transmission of WAL files before clean switchover - (Fujii Masao) - - - - Previously, the streaming replication connection might close before all - WAL files had been replayed on the standby. - - - - - - Fix WAL segment timeline handling during recovery (Mitsumasa Kondo, - Heikki Linnakangas) - - - - WAL file recycling during standby recovery could lead to premature - recovery completion, resulting in data loss. - - - - - - Prevent errors in WAL replay due to references to uninitialized empty - pages (Andres Freund) - - - - - - Fix REINDEX TABLE and REINDEX DATABASE - to properly revalidate constraints and mark invalidated indexes as - valid (Noah Misch) - - - - REINDEX INDEX has always worked properly. - - - - - - Avoid deadlocks during insertion into SP-GiST indexes (Teodor Sigaev) - - - - - - Fix possible deadlock during concurrent CREATE INDEX - CONCURRENTLY operations (Tom Lane) - - - - - - Fix GiST index lookup crash (Tom Lane) - - - - - - Fix regexp_matches() handling of zero-length matches - (Jeevan Chalke) - - - - Previously, zero-length matches like '^' could return too many matches. - - - - - - Fix crash for overly-complex regular expressions (Heikki Linnakangas) - - - - - - Fix regular expression match failures for back references combined with - non-greedy quantifiers (Jeevan Chalke) - - - - - - Prevent CREATE FUNCTION from checking SET - variables unless function body checking is enabled (Tom Lane) - - - - - - Allow ALTER DEFAULT PRIVILEGES to operate on schemas - without requiring CREATE permission (Tom Lane) - - - - - - Loosen restriction on keywords used in queries (Tom Lane) - - - - Specifically, lessen keyword restrictions for role names, language - names, EXPLAIN and COPY options, and - SET values. This allows COPY ... (FORMAT - BINARY) to work as expected; previously BINARY needed - to be quoted. - - - - - - Print proper line number during COPY failure (Heikki - Linnakangas) - - - - - - Fix pgp_pub_decrypt() so it works for secret keys with - passwords (Marko Kreen) - - - - - - Make pg_upgrade use pg_dump - --quote-all-identifiers to avoid problems with keyword changes - between releases (Tom Lane) - - - - - - Remove rare inaccurate warning during vacuum of index-less tables - (Heikki Linnakangas) - - - - - - Ensure that VACUUM ANALYZE still runs the ANALYZE phase - if its attempt to truncate the file is cancelled due to lock conflicts - (Kevin Grittner) - - - - - - Avoid possible failure when performing transaction control commands (e.g - ROLLBACK) in prepared queries (Tom Lane) - - - - - - Ensure that floating-point data input accepts standard spellings - of infinity on all platforms (Tom Lane) - - - - The C99 standard says that allowable spellings are inf, - +inf, -inf, infinity, - +infinity, and -infinity. Make sure we - recognize these even if the platform's strtod function - doesn't. - - - - - - Avoid unnecessary reporting when track_activities is off - (Tom Lane) - - - - - - Expand ability to compare rows to records and arrays (Rafal Rzepecki, - Tom Lane) - - - - - - Prevent crash when psql's PSQLRC variable - contains a tilde (Bruce Momjian) - - - - - - Add spinlock support for ARM64 (Mark Salter) - - - - - - Update time zone data files to tzdata release 2013d - for DST law changes in Israel, Morocco, Palestine, and Paraguay. - Also, historical zone data corrections for Macquarie Island. - - - - - - - - - - Release 9.2.4 - - - Release date: - 2013-04-04 - - - - This release contains a variety of fixes from 9.2.3. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.4 - - - A dump/restore is not required for those running 9.2.X. - - - - However, this release corrects several errors in management of GiST - indexes. After installing this update, it is advisable to - REINDEX any GiST indexes that meet one or more of the - conditions described below. - - - - Also, if you are upgrading from a version earlier than 9.2.2, - see . - - - - - - Changes - - - - - - Fix insecure parsing of server command-line switches (Mitsumasa - Kondo, Kyotaro Horiguchi) - - - - A connection request containing a database name that begins with - - could be crafted to damage or destroy - files within the server's data directory, even if the request is - eventually rejected. (CVE-2013-1899) - - - - - - Reset OpenSSL randomness state in each postmaster child process - (Marko Kreen) - - - - This avoids a scenario wherein random numbers generated by - contrib/pgcrypto functions might be relatively easy for - another database user to guess. The risk is only significant when - the postmaster is configured with ssl = on - but most connections don't use SSL encryption. (CVE-2013-1900) - - - - - - Make REPLICATION privilege checks test current user not authenticated - user (Noah Misch) - - - - An unprivileged database user could exploit this mistake to call - pg_start_backup() or pg_stop_backup(), - thus possibly interfering with creation of routine backups. - (CVE-2013-1901) - - - - - - Fix GiST indexes to not use fuzzy geometric comparisons when - it's not appropriate to do so (Alexander Korotkov) - - - - The core geometric types perform comparisons using fuzzy - equality, but gist_box_same must do exact comparisons, - else GiST indexes using it might become inconsistent. After installing - this update, users should REINDEX any GiST indexes on - box, polygon, circle, or point - columns, since all of these use gist_box_same. - - - - - - Fix erroneous range-union and penalty logic in GiST indexes that use - contrib/btree_gist for variable-width data types, that is - text, bytea, bit, and numeric - columns (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in useless - index bloat. Users are advised to REINDEX such indexes - after installing this update. - - - - - - Fix bugs in GiST page splitting code for multi-column indexes - (Tom Lane) - - - - These errors could result in inconsistent indexes in which some keys - that are present would not be found by searches, and also in indexes - that are unnecessarily inefficient to search. Users are advised to - REINDEX multi-column GiST indexes after installing this - update. - - - - - - Fix gist_point_consistent - to handle fuzziness consistently (Alexander Korotkov) - - - - Index scans on GiST indexes on point columns would sometimes - yield results different from a sequential scan, because - gist_point_consistent disagreed with the underlying - operator code about whether to do comparisons exactly or fuzzily. - - - - - - Fix buffer leak in WAL replay (Heikki Linnakangas) - - - - This bug could result in incorrect local pin count errors - during replay, making recovery impossible. - - - - - - Ensure we do crash recovery before entering archive recovery, if the - database was not stopped cleanly and a recovery.conf file - is present (Heikki Linnakangas, Kyotaro Horiguchi, Mitsumasa Kondo) - - - - This is needed to ensure that the database is consistent in certain - scenarios, such as initializing a standby server with a filesystem - snapshot from a running server. - - - - - - Avoid deleting not-yet-archived WAL files during crash recovery - (Heikki Linnakangas, Fujii Masao) - - - - - - Fix race condition in DELETE RETURNING (Tom Lane) - - - - Under the right circumstances, DELETE RETURNING could - attempt to fetch data from a shared buffer that the current process - no longer has any pin on. If some other process changed the buffer - meanwhile, this would lead to garbage RETURNING output, or - even a crash. - - - - - - Fix infinite-loop risk in regular expression compilation (Tom Lane, - Don Porter) - - - - - - Fix potential null-pointer dereference in regular expression compilation - (Tom Lane) - - - - - - Fix to_char() to use ASCII-only case-folding rules where - appropriate (Tom Lane) - - - - This fixes misbehavior of some template patterns that should be - locale-independent, but mishandled I and - i in Turkish locales. - - - - - - Fix unwanted rejection of timestamp 1999-12-31 24:00:00 - (Tom Lane) - - - - - - Fix SQL-language functions to be safely usable as support - functions for range types (Tom Lane) - - - - - - Fix logic error when a single transaction does UNLISTEN - then LISTEN (Tom Lane) - - - - The session wound up not listening for notify events at all, though it - surely should listen in this case. - - - - - - Fix possible planner crash after columns have been added to a view - that's depended on by another view (Tom Lane) - - - - - - Fix performance issue in EXPLAIN (ANALYZE, TIMING OFF) - (Pavel Stehule) - - - - - - Remove useless picksplit doesn't support secondary split log - messages (Josh Hansen, Tom Lane) - - - - This message seems to have been added in expectation of code that was - never written, and probably never will be, since GiST's default - handling of secondary splits is actually pretty good. So stop nagging - end users about it. - - - - - - Remove vestigial secondary-split support in - gist_box_picksplit() (Tom Lane) - - - - Not only was this implementation of secondary-split not better than the - default implementation, it's actually worse. So remove it and let the - default code path handle the case. - - - - - - Fix possible failure to send a session's last few transaction - commit/abort counts to the statistics collector (Tom Lane) - - - - - - Eliminate memory leaks in PL/Perl's spi_prepare() function - (Alex Hunsaker, Tom Lane) - - - - - - Fix pg_dumpall to handle database names containing - = correctly (Heikki Linnakangas) - - - - - - Avoid crash in pg_dump when an incorrect connection - string is given (Heikki Linnakangas) - - - - - - Ignore invalid indexes in pg_dump and - pg_upgrade (Michael Paquier, Bruce Momjian) - - - - Dumping invalid indexes can cause problems at restore time, for example - if the reason the index creation failed was because it tried to enforce - a uniqueness condition not satisfied by the table's data. Also, if the - index creation is in fact still in progress, it seems reasonable to - consider it to be an uncommitted DDL change, which - pg_dump wouldn't be expected to dump anyway. - pg_upgrade now also skips invalid indexes rather than - failing. - - - - - - In pg_basebackup, include only the current server - version's subdirectory when backing up a tablespace (Heikki - Linnakangas) - - - - - - Add a server version check in pg_basebackup and - pg_receivexlog, so they fail cleanly with version - combinations that won't work (Heikki Linnakangas) - - - - - - Fix contrib/dblink to handle inconsistent settings of - DateStyle or IntervalStyle safely (Daniel - Farina, Tom Lane) - - - - Previously, if the remote server had different settings of these - parameters, ambiguous dates might be read incorrectly. This fix - ensures that datetime and interval columns fetched by a - dblink query will be interpreted correctly. Note however - that inconsistent settings are still risky, since literal values - appearing in SQL commands sent to the remote server might be - interpreted differently than they would be locally. - - - - - - Fix contrib/pg_trgm's similarity() function - to return zero for trigram-less strings (Tom Lane) - - - - Previously it returned NaN due to internal division by zero. - - - - - - Enable building PostgreSQL with Microsoft Visual - Studio 2012 (Brar Piening, Noah Misch) - - - - - - Update time zone data files to tzdata release 2013b - for DST law changes in Chile, Haiti, Morocco, Paraguay, and some - Russian areas. Also, historical zone data corrections for numerous - places. - - - - Also, update the time zone abbreviation files for recent changes in - Russia and elsewhere: CHOT, GET, - IRKT, KGT, KRAT, MAGT, - MAWT, MSK, NOVT, OMST, - TKT, VLAT, WST, YAKT, - YEKT now follow their current meanings, and - VOLT (Europe/Volgograd) and MIST - (Antarctica/Macquarie) are added to the default abbreviations list. - - - - - - - - - - Release 9.2.3 - - - Release date: - 2013-02-07 - - - - This release contains a variety of fixes from 9.2.2. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.3 - - - A dump/restore is not required for those running 9.2.X. - - - - However, if you are upgrading from a version earlier than 9.2.2, - see . - - - - - - Changes - - - - - - Prevent execution of enum_recv from SQL (Tom Lane) - - - - The function was misdeclared, allowing a simple SQL command to crash the - server. In principle an attacker might be able to use it to examine the - contents of server memory. Our thanks to Sumit Soni (via Secunia SVCRP) - for reporting this issue. (CVE-2013-0255) - - - - - - Fix multiple problems in detection of when a consistent database - state has been reached during WAL replay (Fujii Masao, Heikki - Linnakangas, Simon Riggs, Andres Freund) - - - - - - Fix detection of end-of-backup point when no actual redo work is - required (Heikki Linnakangas) - - - - This mistake could result in incorrect WAL ends before end of - online backup errors. - - - - - - Update minimum recovery point when truncating a relation file (Heikki - Linnakangas) - - - - Once data has been discarded, it's no longer safe to stop recovery at - an earlier point in the timeline. - - - - - - Fix recycling of WAL segments after changing recovery target timeline - (Heikki Linnakangas) - - - - - - Properly restore timeline history files from archive on cascading - standby servers (Heikki Linnakangas) - - - - - - Fix lock conflict detection on hot-standby servers (Andres Freund, - Robert Haas) - - - - - - Fix missing cancellations in hot standby mode (Noah Misch, Simon Riggs) - - - - The need to cancel conflicting hot-standby queries would sometimes be - missed, allowing those queries to see inconsistent data. - - - - - - Prevent recovery pause feature from pausing before users can connect - (Tom Lane) - - - - - - Fix SQL grammar to allow subscripting or field selection from a - sub-SELECT result (Tom Lane) - - - - - - Fix performance problems with autovacuum truncation in busy workloads - (Jan Wieck) - - - - Truncation of empty pages at the end of a table requires exclusive - lock, but autovacuum was coded to fail (and release the table lock) - when there are conflicting lock requests. Under load, it is easily - possible that truncation would never occur, resulting in table bloat. - Fix by performing a partial truncation, releasing the lock, then - attempting to re-acquire the lock and continue. This fix also greatly - reduces the average time before autovacuum releases the lock after a - conflicting request arrives. - - - - - - Improve performance of SPI_execute and related - functions, thereby improving PL/pgSQL's EXECUTE - (Heikki Linnakangas, Tom Lane) - - - - Remove some data-copying overhead that was added in 9.2 as a - consequence of revisions in the plan caching mechanism. This - eliminates a performance regression compared to 9.1, and also saves - memory, especially when the query string to be executed contains many - SQL statements. - - - - A side benefit is that multi-statement query strings are now - processed fully serially, that is we complete execution of earlier - statements before running parse analysis and planning on the - following ones. This eliminates a long-standing issue, in that DDL - that should affect the behavior of a later statement will now behave as - expected. - - - - - - Restore pre-9.2 cost estimates for index usage (Tom Lane) - - - - An ill-considered change of a fudge factor led to undesirably high - cost estimates for use of very large indexes. - - - - - - Fix intermittent crash in DROP INDEX CONCURRENTLY (Tom Lane) - - - - - - Fix potential corruption of shared-memory lock table during - CREATE/DROP INDEX CONCURRENTLY (Tom Lane) - - - - - - Fix COPY's multiple-tuple-insertion code for the case of - a tuple larger than page size minus fillfactor (Heikki Linnakangas) - - - - The previous coding could get into an infinite loop. - - - - - - Protect against race conditions when scanning - pg_tablespace (Stephen Frost, Tom Lane) - - - - CREATE DATABASE and DROP DATABASE could - misbehave if there were concurrent updates of - pg_tablespace entries. - - - - - - Prevent DROP OWNED from trying to drop whole databases or - tablespaces (Álvaro Herrera) - - - - For safety, ownership of these objects must be reassigned, not dropped. - - - - - - Fix error in vacuum_freeze_table_age - implementation (Andres Freund) - - - - In installations that have existed for more than vacuum_freeze_min_age - transactions, this mistake prevented autovacuum from using partial-table - scans, so that a full-table scan would always happen instead. - - - - - - Prevent misbehavior when a RowExpr or XmlExpr - is parse-analyzed twice (Andres Freund, Tom Lane) - - - - This mistake could be user-visible in contexts such as - CREATE TABLE LIKE INCLUDING INDEXES. - - - - - - Improve defenses against integer overflow in hashtable sizing - calculations (Jeff Davis) - - - - - - Fix some bugs associated with privileges on datatypes (Tom Lane) - - - - There were some issues with default privileges for types, and - pg_dump failed to dump such privileges at all. - - - - - - Fix failure to ignore leftover temporary tables after a server crash - (Tom Lane) - - - - - - Fix failure to rotate postmaster log files for size reasons on - Windows (Jeff Janes, Heikki Linnakangas) - - - - - - Reject out-of-range dates in to_date() (Hitoshi Harada) - - - - - - Fix pg_extension_config_dump() to handle - extension-update cases properly (Tom Lane) - - - - This function will now replace any existing entry for the target - table, making it usable in extension update scripts. - - - - - - Fix PL/pgSQL's reporting of plan-time errors in possibly-simple - expressions (Tom Lane) - - - - The previous coding resulted in sometimes omitting the first line in - the CONTEXT traceback for the error. - - - - - - Fix PL/Python's handling of functions used as triggers on multiple - tables (Andres Freund) - - - - - - Ensure that non-ASCII prompt strings are translated to the correct - code page on Windows (Alexander Law, Noah Misch) - - - - This bug affected psql and some other client programs. - - - - - - Fix possible crash in psql's \? command - when not connected to a database (Meng Qingzhong) - - - - - - Fix possible error if a relation file is removed while - pg_basebackup is running (Heikki Linnakangas) - - - - - - Tolerate timeline switches while pg_basebackup -X fetch - is backing up a standby server (Heikki Linnakangas) - - - - - - Make pg_dump exclude data of unlogged tables when - running on a hot-standby server (Magnus Hagander) - - - - This would fail anyway because the data is not available on the standby - server, so it seems most convenient to assume - automatically. - - - - - - Fix pg_upgrade to deal with invalid indexes safely - (Bruce Momjian) - - - - - - Fix pg_upgrade's -O/-o options (Marti Raudsepp) - - - - - - Fix one-byte buffer overrun in libpq's - PQprintTuples (Xi Wang) - - - - This ancient function is not used anywhere by - PostgreSQL itself, but it might still be used by some - client code. - - - - - - Make ecpglib use translated messages properly - (Chen Huajun) - - - - - - Properly install ecpg_compat and - pgtypes libraries on MSVC (Jiang Guiqing) - - - - - - Include our version of isinf() in - libecpg if it's not provided by the system - (Jiang Guiqing) - - - - - - Rearrange configure's tests for supplied functions so it is not - fooled by bogus exports from libedit/libreadline (Christoph Berg) - - - - - - Ensure Windows build number increases over time (Magnus Hagander) - - - - - - Make pgxs build executables with the right - .exe suffix when cross-compiling for Windows - (Zoltan Boszormenyi) - - - - - - Add new timezone abbreviation FET (Tom Lane) - - - - This is now used in some eastern-European time zones. - - - - - - - - - - Release 9.2.2 - - - Release date: - 2012-12-06 - - - - This release contains a variety of fixes from 9.2.1. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.2 - - - A dump/restore is not required for those running 9.2.X. - - - - However, you may need to perform REINDEX operations to - correct problems in concurrently-built indexes, as described in the first - changelog item below. - - - - Also, if you are upgrading from version 9.2.0, - see . - - - - - - Changes - - - - - - Fix multiple bugs associated with CREATE/DROP INDEX - CONCURRENTLY (Andres Freund, Tom Lane, Simon Riggs, Pavan Deolasee) - - - - An error introduced while adding DROP INDEX CONCURRENTLY - allowed incorrect indexing decisions to be made during the initial - phase of CREATE INDEX CONCURRENTLY; so that indexes built - by that command could be corrupt. It is recommended that indexes - built in 9.2.X with CREATE INDEX CONCURRENTLY be rebuilt - after applying this update. - - - - In addition, fix CREATE/DROP INDEX CONCURRENTLY to use - in-place updates when changing the state of an index's - pg_index row. This prevents race conditions that could - cause concurrent sessions to miss updating the target index, thus - again resulting in corrupt concurrently-created indexes. - - - - Also, fix various other operations to ensure that they ignore - invalid indexes resulting from a failed CREATE INDEX - CONCURRENTLY command. The most important of these is - VACUUM, because an auto-vacuum could easily be launched - on the table before corrective action can be taken to fix or remove - the invalid index. - - - - Also fix DROP INDEX CONCURRENTLY to not disable - insertions into the target index until all queries using it are done. - - - - Also fix misbehavior if DROP INDEX CONCURRENTLY is - canceled: the previous coding could leave an un-droppable index behind. - - - - - - Correct predicate locking for DROP INDEX CONCURRENTLY - (Kevin Grittner) - - - - Previously, SSI predicate locks were processed at the wrong time, - possibly leading to incorrect behavior of serializable transactions - executing in parallel with the DROP. - - - - - - Fix buffer locking during WAL replay (Tom Lane) - - - - The WAL replay code was insufficiently careful about locking buffers - when replaying WAL records that affect more than one page. This could - result in hot standby queries transiently seeing inconsistent states, - resulting in wrong answers or unexpected failures. - - - - - - Fix an error in WAL generation logic for GIN indexes (Tom Lane) - - - - This could result in index corruption, if a torn-page failure occurred. - - - - - - Fix an error in WAL replay logic for SP-GiST indexes (Tom Lane) - - - - This could result in index corruption after a crash, or on a standby - server. - - - - - - Fix incorrect detection of end-of-base-backup location during WAL - recovery (Heikki Linnakangas) - - - - This mistake allowed hot standby mode to start up before the database - reaches a consistent state. - - - - - - Properly remove startup process's virtual XID lock when promoting a - hot standby server to normal running (Simon Riggs) - - - - This oversight could prevent subsequent execution of certain - operations such as CREATE INDEX CONCURRENTLY. - - - - - - Avoid bogus out-of-sequence timeline ID errors in standby - mode (Heikki Linnakangas) - - - - - - Prevent the postmaster from launching new child processes after it's - received a shutdown signal (Tom Lane) - - - - This mistake could result in shutdown taking longer than it should, or - even never completing at all without additional user action. - - - - - - Fix the syslogger process to not fail when - log_rotation_age exceeds 2^31 milliseconds (about 25 days) - (Tom Lane) - - - - - - Fix WaitLatch() to return promptly when the requested - timeout expires (Jeff Janes, Tom Lane) - - - - With the previous coding, a steady stream of non-wait-terminating - interrupts could delay return from WaitLatch() - indefinitely. This has been shown to be a problem for the autovacuum - launcher process, and might cause trouble elsewhere as well. - - - - - - Avoid corruption of internal hash tables when out of memory - (Hitoshi Harada) - - - - - - Prevent file descriptors for dropped tables from being held open past - transaction end (Tom Lane) - - - - This should reduce problems with long-since-dropped tables continuing - to occupy disk space. - - - - - - Prevent database-wide crash and restart when a new child process is - unable to create a pipe for its latch (Tom Lane) - - - - Although the new process must fail, there is no good reason to force a - database-wide restart, so avoid that. This improves robustness when - the kernel is nearly out of file descriptors. - - - - - - Avoid planner crash with joins to unflattened subqueries (Tom Lane) - - - - - - Fix planning of non-strict equivalence clauses above outer joins - (Tom Lane) - - - - The planner could derive incorrect constraints from a clause equating - a non-strict construct to something else, for example - WHERE COALESCE(foo, 0) = 0 - when foo is coming from the nullable side of an outer join. - 9.2 showed this type of error in more cases than previous releases, - but the basic bug has been there for a long time. - - - - - - Fix SELECT DISTINCT with index-optimized - MIN/MAX on an inheritance tree (Tom Lane) - - - - The planner would fail with failed to re-find MinMaxAggInfo - record given this combination of factors. - - - - - - Make sure the planner sees implicit and explicit casts as equivalent - for all purposes, except in the minority of cases where there's - actually a semantic difference (Tom Lane) - - - - - - Include join clauses when considering whether partial indexes can be - used for a query (Tom Lane) - - - - A strict join clause can be sufficient to establish an - x IS NOT NULL predicate, for example. - This fixes a planner regression in 9.2, since previous versions could - make comparable deductions. - - - - - - Limit growth of planning time when there are many indexable join - clauses for the same index (Tom Lane) - - - - - - Improve planner's ability to prove exclusion constraints from - equivalence classes (Tom Lane) - - - - - - Fix partial-row matching in hashed subplans to handle cross-type cases - correctly (Tom Lane) - - - - This affects multicolumn NOT IN subplans, such as - WHERE (a, b) NOT IN (SELECT x, y FROM ...) - when for instance b and y are int4 - and int8 respectively. This mistake led to wrong answers - or crashes depending on the specific datatypes involved. - - - - - - Fix btree mark/restore functions to handle array keys (Tom Lane) - - - - This oversight could result in wrong answers from merge joins whose - inner side is an index scan using an - indexed_column = - ANY(array) condition. - - - - - - Revert patch for taking fewer snapshots (Tom Lane) - - - - The 9.2 change to reduce the number of snapshots taken during query - execution led to some anomalous behaviors not seen in previous - releases, because execution would proceed with a snapshot acquired - before locking the tables used by the query. Thus, for example, - a query would not be guaranteed to see updates committed by a - preceding transaction even if that transaction had exclusive lock. - We'll probably revisit this in future releases, but meanwhile put it - back the way it was before 9.2. - - - - - - Acquire buffer lock when re-fetching the old tuple for an - AFTER ROW UPDATE/DELETE trigger (Andres Freund) - - - - In very unusual circumstances, this oversight could result in passing - incorrect data to a trigger WHEN condition, or to the - precheck logic for a foreign-key enforcement trigger. That could - result in a crash, or in an incorrect decision about whether to - fire the trigger. - - - - - - Fix ALTER COLUMN TYPE to handle inherited check - constraints properly (Pavan Deolasee) - - - - This worked correctly in pre-8.4 releases, and now works correctly - in 8.4 and later. - - - - - - Fix ALTER EXTENSION SET SCHEMA's failure to move some - subsidiary objects into the new schema (Álvaro Herrera, Dimitri - Fontaine) - - - - - - Handle CREATE TABLE AS EXECUTE correctly in extended query - protocol (Tom Lane) - - - - - - Don't modify the input parse tree in DROP RULE IF NOT - EXISTS and DROP TRIGGER IF NOT EXISTS (Tom Lane) - - - - This mistake would cause errors if a cached statement of one of these - types was re-executed. - - - - - - Fix REASSIGN OWNED to handle grants on tablespaces - (Álvaro Herrera) - - - - - - Ignore incorrect pg_attribute entries for system - columns for views (Tom Lane) - - - - Views do not have any system columns. However, we forgot to - remove such entries when converting a table to a view. That's fixed - properly for 9.3 and later, but in previous branches we need to defend - against existing mis-converted views. - - - - - - Fix rule printing to dump INSERT INTO table - DEFAULT VALUES correctly (Tom Lane) - - - - - - Guard against stack overflow when there are too many - UNION/INTERSECT/EXCEPT clauses - in a query (Tom Lane) - - - - - - Prevent platform-dependent failures when dividing the minimum possible - integer value by -1 (Xi Wang, Tom Lane) - - - - - - Fix possible access past end of string in date parsing - (Hitoshi Harada) - - - - - - Fix failure to advance XID epoch if XID wraparound happens during a - checkpoint and wal_level is hot_standby - (Tom Lane, Andres Freund) - - - - While this mistake had no particular impact on - PostgreSQL itself, it was bad for - applications that rely on txid_current() and related - functions: the TXID value would appear to go backwards. - - - - - - Fix pg_terminate_backend() and - pg_cancel_backend() to not throw error for a non-existent - target process (Josh Kupershmidt) - - - - This case already worked as intended when called by a superuser, - but not so much when called by ordinary users. - - - - - - Fix display of - pg_stat_replication.sync_state at a - page boundary (Kyotaro Horiguchi) - - - - - - Produce an understandable error message if the length of the path name - for a Unix-domain socket exceeds the platform-specific limit - (Tom Lane, Andrew Dunstan) - - - - Formerly, this would result in something quite unhelpful, such as - Non-recoverable failure in name resolution. - - - - - - Fix memory leaks when sending composite column values to the client - (Tom Lane) - - - - - - Save some cycles by not searching for subtransaction locks at commit - (Simon Riggs) - - - - In a transaction holding many exclusive locks, this useless activity - could be quite costly. - - - - - - Make pg_ctl more robust about reading the - postmaster.pid file (Heikki Linnakangas) - - - - This fixes race conditions and possible file descriptor leakage. - - - - - - Fix possible crash in psql if incorrectly-encoded data - is presented and the client_encoding setting is a - client-only encoding, such as SJIS (Jiang Guiqing) - - - - - - Make pg_dump dump SEQUENCE SET items in - the data not pre-data section of the archive (Tom Lane) - - - - This fixes an undesirable inconsistency between the meanings of - and , and also fixes - dumping of sequences that are marked as extension configuration tables. - - - - - - Fix pg_dump's handling of DROP DATABASE - commands in mode (Guillaume Lelarge) - - - - Beginning in 9.2.0, pg_dump --clean would issue a - DROP DATABASE command, which was either useless or - dangerous depending on the usage scenario. It no longer does that. - This change also fixes the combination of and - to work sensibly, i.e., emit DROP - DATABASE then CREATE DATABASE before reconnecting to the - target database. - - - - - - Fix pg_dump for views with circular dependencies and - no relation options (Tom Lane) - - - - The previous fix to dump relation options when a view is - involved in a circular dependency didn't work right for the case - that the view has no options; it emitted ALTER VIEW foo - SET () which is invalid syntax. - - - - - - Fix bugs in the restore.sql script emitted by - pg_dump in tar output format (Tom Lane) - - - - The script would fail outright on tables whose names include - upper-case characters. Also, make the script capable of restoring - data in mode as well as the regular COPY mode. - - - - - - Fix pg_restore to accept POSIX-conformant - tar files (Brian Weaver, Tom Lane) - - - - The original coding of pg_dump's tar - output mode produced files that are not fully conformant with the - POSIX standard. This has been corrected for version 9.3. This - patch updates previous branches so that they will accept both the - incorrect and the corrected formats, in hopes of avoiding - compatibility problems when 9.3 comes out. - - - - - - Fix tar files emitted by pg_basebackup to - be POSIX conformant (Brian Weaver, Tom Lane) - - - - - - Fix pg_resetxlog to locate postmaster.pid - correctly when given a relative path to the data directory (Tom Lane) - - - - This mistake could lead to pg_resetxlog not noticing - that there is an active postmaster using the data directory. - - - - - - Fix libpq's lo_import() and - lo_export() functions to report file I/O errors properly - (Tom Lane) - - - - - - Fix ecpg's processing of nested structure pointer - variables (Muhammad Usama) - - - - - - Fix ecpg's ecpg_get_data function to - handle arrays properly (Michael Meskes) - - - - - - Prevent pg_upgrade from trying to process TOAST tables - for system catalogs (Bruce Momjian) - - - - This fixes an error seen when the information_schema has - been dropped and recreated. Other failures were also possible. - - - - - - Improve pg_upgrade performance by setting - synchronous_commit to off in the new cluster - (Bruce Momjian) - - - - - - Make contrib/pageinspect's btree page inspection - functions take buffer locks while examining pages (Tom Lane) - - - - - - Work around unportable behavior of malloc(0) and - realloc(NULL, 0) (Tom Lane) - - - - On platforms where these calls return NULL, some code - mistakenly thought that meant out-of-memory. - This is known to have broken pg_dump for databases - containing no user-defined aggregates. There might be other cases - as well. - - - - - - Ensure that make install for an extension creates the - extension installation directory (Cédric Villemain) - - - - Previously, this step was missed if MODULEDIR was set in - the extension's Makefile. - - - - - - Fix pgxs support for building loadable modules on AIX - (Tom Lane) - - - - Building modules outside the original source tree didn't work on AIX. - - - - - - Update time zone data files to tzdata release 2012j - for DST law changes in Cuba, Israel, Jordan, Libya, Palestine, Western - Samoa, and portions of Brazil. - - - - - - - - - - Release 9.2.1 - - - Release date: - 2012-09-24 - - - - This release contains a variety of fixes from 9.2.0. - For information about new features in the 9.2 major release, see - . - - - - Migration to Version 9.2.1 - - - A dump/restore is not required for those running 9.2.X. - - - - However, you may need to perform REINDEX and/or - VACUUM operations to recover from the effects of the data - corruption bug described in the first changelog item below. - - - - - - Changes - - - - - - Fix persistence marking of shared buffers during WAL replay - (Jeff Davis) - - - - This mistake can result in buffers not being written out during - checkpoints, resulting in data corruption if the server later crashes - without ever having written those buffers. Corruption can occur on - any server following crash recovery, but it is significantly more - likely to occur on standby slave servers since those perform much - more WAL replay. There is a low probability of corruption of btree - and GIN indexes. There is a much higher probability of corruption - of table visibility maps, which might lead to wrong answers - from index-only scans. Table data proper cannot be corrupted by this - bug. - - - - While no index corruption due to this bug is known to have occurred - in the field, as a precautionary measure it is recommended that - production installations REINDEX all btree and GIN - indexes at a convenient time after upgrading to 9.2.1. - - - - Also, it is recommended to perform a VACUUM of all tables - while having vacuum_freeze_table_age - set to zero. This will fix any incorrect visibility map data. vacuum_cost_delay - can be adjusted to reduce the performance impact of vacuuming, while - causing it to take longer to finish. - - - - - - Fix possible incorrect sorting of output from queries involving - WHERE indexed_column IN - (list_of_values) (Tom Lane) - - - - - - Fix planner failure for queries involving GROUP BY - expressions along with window functions and aggregates (Tom Lane) - - - - - - Fix planner's assignment of executor parameters (Tom Lane) - - - - This error could result in wrong answers from queries that scan the - same WITH subquery multiple times. - - - - - - Improve planner's handling of join conditions in index scans (Tom Lane) - - - - - - Improve selectivity estimation for text search queries involving - prefixes, i.e. word:* patterns (Tom Lane) - - - - - - Fix delayed recognition of permissions changes (Tom Lane) - - - - A command that needed no locks other than ones its transaction already - had might fail to notice a concurrent GRANT or - REVOKE that committed since the start of its transaction. - - - - - - Fix ANALYZE to not fail when a column is a domain over an - array type (Tom Lane) - - - - - - Prevent PL/Perl from crashing if a recursive PL/Perl function is - redefined while being executed (Tom Lane) - - - - - - Work around possible misoptimization in PL/Perl (Tom Lane) - - - - Some Linux distributions contain an incorrect version of - pthread.h that results in incorrect compiled code in - PL/Perl, leading to crashes if a PL/Perl function calls another one - that throws an error. - - - - - - Remove unnecessary dependency on pg_config from - pg_upgrade (Peter Eisentraut) - - - - - - Update time zone data files to tzdata release 2012f - for DST law changes in Fiji - - - - - - - - - - Release 9.2 - - - Release date: - 2012-09-10 - - - - Overview - - - This release has been largely focused on performance improvements, though - new SQL features are not lacking. Work also continues in the area of - replication support. Major enhancements include: - - - - - - - - - Allow queries to retrieve data only from indexes, avoiding heap - access (index-only scans) - - - - - - Allow the planner to generate custom plans for specific parameter - values even when using prepared statements - - - - - - Improve the planner's ability to use nested loops with inner - index scans - - - - - - Allow streaming replication slaves to forward data to other slaves - (cascading - replication) - - - - - - Allow pg_basebackup - to make base backups from standby servers - - - - - - Add a pg_receivexlog - tool to archive WAL file changes as they are written - - - - - - Add the SP-GiST (Space-Partitioned - GiST) index access method - - - - - - Add support for range data types - - - - - - Add a JSON - data type - - - - - - Add a security_barrier - option for views - - - - - - Allow libpq connection strings to have the format of a - URI - - - - - - Add a single-row processing - mode to libpq for better handling of large - result sets - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.2 - - - A dump/restore using pg_dump, or use of - pg_upgrade, is required for those wishing - to migrate data from any previous release. - - - - Version 9.2 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - System Catalogs - - - - - - Remove the spclocation field from pg_tablespace - (Magnus Hagander) - - - - This field was duplicative of the symbolic links that actually define - tablespace locations, and thus risked errors of omission when moving - a tablespace. This change allows tablespace directories to be moved - while the server is down, by manually adjusting the symbolic links. - To replace this field, we have added pg_tablespace_location() - to allow querying of the symbolic links. - - - - - - Move tsvector most-common-element statistics to new - pg_stats columns - (Alexander Korotkov) - - - - Consult most_common_elems - and most_common_elem_freqs for the data formerly - available in most_common_vals - and most_common_freqs for a tsvector column. - - - - - - - - - Functions - - - - - - Remove hstore's => - operator (Robert Haas) - - - - Users should now use hstore(text, text). Since - PostgreSQL 9.0, a warning message has been - emitted when an operator named => is created because - the SQL standard reserves that token for - another use. - - - - - - Ensure that xpath() - escapes special characters in string values (Florian Pflug) - - - - Without this it is possible for the result not to be valid - XML. - - - - - - Make pg_relation_size() - and friends return NULL if the object does not exist (Phil Sorber) - - - - This prevents queries that call these functions from returning - errors immediately after a concurrent DROP. - - - - - - Make EXTRACT(EPOCH FROM - timestamp without time zone) - measure the epoch from local midnight, not UTC - midnight (Tom Lane) - - - - This change reverts an ill-considered change made in release 7.3. - Measuring from UTC midnight was inconsistent - because it made the result dependent on the timezone setting, which - computations for timestamp without time zone should not be. - The previous behavior remains available by casting the input value - to timestamp with time zone. - - - - - - Properly parse time strings with trailing yesterday, - today, and tomorrow (Dean Rasheed) - - - - Previously, SELECT '04:00:00 yesterday'::timestamp - returned yesterday's date at midnight. - - - - - - Fix to_date() and - to_timestamp() to wrap incomplete dates toward 2020 - (Bruce Momjian) - - - - Previously, supplied years and year masks of less than four digits - wrapped inconsistently. - - - - - - - - - Object Modification - - - - - - Prevent ALTER - DOMAIN from working on non-domain types (Peter - Eisentraut) - - - - Owner and schema changes were previously possible on non-domain - types. - - - - - - No longer forcibly lowercase procedural language names in CREATE FUNCTION - (Robert Haas) - - - - While unquoted language identifiers are still lowercased, strings - and quoted identifiers are no longer forcibly down-cased. - Thus for example CREATE FUNCTION ... LANGUAGE 'C' - will no longer work; it must be spelled 'c', or better - omit the quotes. - - - - - - Change system-generated names of foreign key enforcement triggers - (Tom Lane) - - - - This change ensures that the triggers fire in the correct order in - some corner cases involving self-referential foreign key constraints. - - - - - - - - - Command-Line Tools - - - - - - Provide consistent backquote, variable - expansion, and quoted substring behavior in psql meta-command - arguments (Tom Lane) - - - - Previously, such references were treated oddly when not separated by - whitespace from adjacent text. For example 'FOO'BAR was - output as FOO BAR (unexpected insertion of a space) and - FOO'BAR'BAZ was output unchanged (not removing the quotes - as most would expect). - - - - - - No longer treat clusterdb - table names as double-quoted; no longer treat reindexdb table - and index names as double-quoted (Bruce Momjian) - - - - Users must now include double-quotes in the command arguments if - quoting is wanted. - - - - - - createuser - no longer prompts for option settings by default (Peter Eisentraut) - - - - Use to obtain the old behavior. - - - - - - Disable prompting for the user name in dropuser unless - is specified (Peter Eisentraut) - - - - - - - - - Server Settings - - - - - - Add server parameters for specifying the locations of server-side - SSL files (Peter Eisentraut) - - - - This allows changing the names and locations of the files that were - previously hard-coded as server.crt, - server.key, root.crt, and - root.crl in the data directory. - The server will no longer examine root.crt or - root.crl by default; to load these files, the - associated parameters must be set to non-default values. - - - - - - Remove the silent_mode parameter (Heikki Linnakangas) - - - - Similar behavior can be obtained with pg_ctl start - -l postmaster.log. - - - - - - Remove the wal_sender_delay parameter, - as it is no longer needed (Tom Lane) - - - - - - Remove the custom_variable_classes parameter (Tom Lane) - - - - The checking provided by this setting was dubious. Now any - setting can be prefixed by any class name. - - - - - - - - Monitoring - - - - - - Rename pg_stat_activity.procpid - to pid, to match other system tables (Magnus Hagander) - - - - - - Create a separate pg_stat_activity column to - report process state (Scott Mead, Magnus Hagander) - - - - The previous query and query_start - values now remain available for an idle session, allowing enhanced - analysis. - - - - - - Rename pg_stat_activity.current_query to - query because it is not cleared when the query - completes (Magnus Hagander) - - - - - - Change all SQL-level statistics timing values - to be float8 columns measured in milliseconds (Tom Lane) - - - - This change eliminates the designed-in assumption that the values - are accurate to microseconds and no more (since the float8 - values can be fractional). - The columns affected are - pg_stat_user_functions.total_time, - pg_stat_user_functions.self_time, - pg_stat_xact_user_functions.total_time, - and - pg_stat_xact_user_functions.self_time. - The statistics functions underlying these columns now also return - float8 milliseconds, rather than bigint - microseconds. - contrib/pg_stat_statements' - total_time column is now also measured in - milliseconds. - - - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.2 and the previous major - release. - - - - Server - - - Performance - - - - - Allow queries to retrieve data only from indexes, avoiding heap - access (Robert Haas, Ibrar Ahmed, Heikki Linnakangas, Tom Lane) - - - - This feature is often called index-only scans. - Heap access can be skipped for heap pages containing only tuples that - are visible to all sessions, as reported by the visibility map; so - the benefit applies mainly to mostly-static data. The visibility map - was made crash-safe as a necessary part of implementing this feature. - - - - - - Add the SP-GiST (Space-Partitioned - GiST) index access method (Teodor Sigaev, Oleg Bartunov, Tom - Lane) - - - - SP-GiST is comparable to GiST in flexibility, but supports - unbalanced partitioned search structures rather than balanced - trees. For suitable problems, SP-GiST can be faster than GiST in both - index build time and search time. - - - - - - Allow group commit to work effectively under heavy load (Peter - Geoghegan, Simon Riggs, Heikki Linnakangas) - - - - Previously, batching of commits became ineffective as the write - workload increased, because of internal lock contention. - - - - - - Allow uncontended locks to be managed using a new - fast-path lock mechanism (Robert Haas) - - - - - - Reduce overhead of creating virtual transaction ID locks (Robert - Haas) - - - - - - Reduce the overhead of serializable isolation level locks (Dan - Ports) - - - - - - Improve PowerPC and Itanium spinlock performance (Manabu Ori, - Robert Haas, Tom Lane) - - - - - - Reduce overhead for shared invalidation cache messages (Robert - Haas) - - - - - - Move the frequently accessed members of the PGPROC - shared memory array to a separate array (Pavan - Deolasee, Heikki Linnakangas, Robert Haas) - - - - - - Improve COPY performance by adding tuples to - the heap in batches (Heikki Linnakangas) - - - - - - Improve GiST index performance for geometric data types by producing - better trees with less memory allocation overhead (Alexander Korotkov) - - - - - - Improve GiST index build times (Alexander Korotkov, Heikki - Linnakangas) - - - - - - Allow hint bits to be set sooner for temporary and unlogged tables - (Robert Haas) - - - - - - Allow sorting to be performed by inlined, - non-SQL-callable comparison functions (Peter - Geoghegan, Robert Haas, Tom Lane) - - - - - - Make the number of CLOG buffers scale based on shared_buffers - (Robert Haas, Simon Riggs, Tom Lane) - - - - - - Improve performance of buffer pool scans that occur when tables or - databases are dropped (Jeff Janes, Simon Riggs) - - - - - - Improve performance of checkpointer's fsync-request queue - when many tables are being dropped or truncated (Tom Lane) - - - - - - Pass the safe number of file descriptors to child processes on Windows - (Heikki Linnakangas) - - - - This allows Windows sessions to use more open file descriptors than - before. - - - - - - - - - Process Management - - - - - - Create a dedicated background process to perform checkpoints (Simon - Riggs) - - - - Formerly the background writer did both dirty-page writing and - checkpointing. Separating this into two processes allows each goal - to be accomplished more predictably. - - - - - - Improve asynchronous commit behavior by waking the walwriter sooner - (Simon Riggs) - - - - Previously, only wal_writer_delay - triggered WAL flushing to disk; now filling a - WAL buffer also triggers WAL - writes. - - - - - - Allow the bgwriter, walwriter, checkpointer, statistics collector, - log collector, and archiver background processes to sleep more - efficiently during periods of inactivity (Peter Geoghegan, Tom Lane) - - - - This series of changes reduces the frequency of process wake-ups when - there is nothing to do, dramatically reducing power consumption on - idle servers. - - - - - - - - - Optimizer - - - - - - Allow the planner to generate custom plans for specific parameter - values even when using prepared statements - (Tom Lane) - - - - In the past, a prepared statement always had a single - generic plan that was used for all parameter values, which - was frequently much inferior to the plans used for non-prepared - statements containing explicit constant values. Now, the planner - attempts to generate custom plans for specific parameter values. - A generic plan will only be used after custom plans have repeatedly - proven to provide no benefit. This change should eliminate the - performance penalties formerly seen from use of prepared statements - (including non-dynamic statements in PL/pgSQL). - - - - - - Improve the planner's ability to use nested loops with inner - index scans (Tom Lane) - - - - The new parameterized path mechanism allows inner - index scans to use values from relations that are more than one join - level up from the scan. This can greatly improve performance in - situations where semantic restrictions (such as outer joins) limit - the allowed join orderings. - - - - - - Improve the planning API for foreign data wrappers - (Etsuro Fujita, Shigeru Hanada, Tom Lane) - - - - Wrappers can now provide multiple access paths for their - tables, allowing more flexibility in join planning. - - - - - - Recognize self-contradictory restriction clauses for non-table - relations (Tom Lane) - - - - This check is only performed when constraint_exclusion - is on. - - - - - - Allow indexed_col op ANY(ARRAY[...]) conditions to be - used in plain index scans and index-only scans (Tom Lane) - - - - Formerly such conditions could only be used in bitmap index scans. - - - - - - Support MIN/MAX index optimizations on - boolean columns (Marti Raudsepp) - - - - - - Account for set-returning functions in SELECT target - lists when setting row count estimates (Tom Lane) - - - - - - Fix planner to handle indexes with duplicated columns more reliably - (Tom Lane) - - - - - - Collect and use element-frequency statistics for arrays (Alexander - Korotkov, Tom Lane) - - - - This change improves selectivity estimation for the array - <@, &&, and - @> operators (array containment and overlaps). - - - - - - Allow statistics to be collected for foreign tables - (Etsuro Fujita) - - - - - - Improve cost estimates for use of partial indexes (Tom Lane) - - - - - - Improve the planner's ability to use statistics for columns - referenced in subqueries (Tom Lane) - - - - - - Improve statistical estimates for subqueries using - DISTINCT (Tom Lane) - - - - - - - - - Authentication - - - - - - Do not treat role names and samerole specified in pg_hba.conf - as automatically including superusers (Andrew Dunstan) - - - - This makes it easier to use reject lines with group roles. - - - - - - Adjust pg_hba.conf processing to handle token - parsing more consistently (Brendan Jurd, Álvaro Herrera) - - - - - - Disallow empty pg_hba.conf files (Tom Lane) - - - - This was done to more quickly detect misconfiguration. - - - - - - Make superuser privilege imply replication privilege (Noah Misch) - - - - This avoids the need to explicitly assign such privileges. - - - - - - - - - Monitoring - - - - - - Attempt to log the current query string during a backend crash - (Marti Raudsepp) - - - - - - Make logging of autovacuum I/O activity more verbose (Greg - Smith, Noah Misch) - - - - This logging is triggered by log_autovacuum_min_duration. - - - - - - Make WAL replay report failures sooner - (Fujii Masao) - - - - There were some cases where failures were only reported once the - server went into master mode. - - - - - - Add pg_xlog_location_diff() - to simplify WAL location comparisons (Euler Taveira de Oliveira) - - - - This is useful for computing replication lag. - - - - - - Support configurable event log application names on Windows - (MauMau, Magnus Hagander) - - - - This allows different instances to use the event log - with different identifiers, by setting the event_source - server parameter, which is similar to how syslog_ident works. - - - - - - Change unexpected EOF messages to DEBUG1 level, - except when there is an open transaction (Magnus Hagander) - - - - This change reduces log chatter caused by applications that close - database connections ungracefully. - - - - - - - - - Statistical Views - - - - - - Track temporary file sizes and file counts in the pg_stat_database - system view (Tomas Vondra) - - - - - - Add a deadlock counter to the pg_stat_database - system view (Magnus Hagander) - - - - - - Add a server parameter track_io_timing - to track I/O timings (Ants Aasma, Robert Haas) - - - - - - Report checkpoint timing information in pg_stat_bgwriter - (Greg Smith, Peter Geoghegan) - - - - - - - - - Server Settings - - - - - - Silently ignore nonexistent schemas specified in search_path (Tom Lane) - - - - This makes it more convenient to use generic path settings, which - might include some schemas that don't exist in all databases. - - - - - - Allow superusers to set deadlock_timeout - per-session, not just per-cluster (Noah Misch) - - - - This allows deadlock_timeout to be reduced for - transactions that are likely to be involved in a deadlock, thus - detecting the failure more quickly. Alternatively, increasing the - value can be used to reduce the chances of a session being chosen for - cancellation due to a deadlock. - - - - - - Add a server parameter temp_file_limit - to constrain temporary file space usage per session (Mark Kirkwood) - - - - - - Allow a superuser to SET an extension's - superuser-only custom variable before loading the associated - extension (Tom Lane) - - - - The system now remembers whether a SET was - performed by a superuser, so that proper privilege checking can be - done when the extension is loaded. - - - - - - Add postmaster - option to query configuration parameters (Bruce Momjian) - - - - This allows pg_ctl to better handle cases where - PGDATA or points to a configuration-only - directory. - - - - - - Replace an empty locale name with the implied value in - CREATE DATABASE - (Tom Lane) - - - - This prevents cases where - pg_database.datcollate or - datctype could be interpreted differently after a - server restart. - - - - - - - <filename>postgresql.conf</filename> - - - - - - Allow multiple errors in postgresql.conf - to be reported, rather than just the first one (Alexey Klyukin, - Tom Lane) - - - - - - Allow a reload of postgresql.conf to be - processed by all sessions, even if there are some settings that - are invalid for particular sessions (Alexey Klyukin) - - - - Previously, such not-valid-within-session values would cause all - setting changes to be ignored by that session. - - - - - - Add an include_if_exists facility for configuration - files (Greg Smith) - - - - This works the same as include, except that an error - is not thrown if the file is missing. - - - - - - Identify the server time zone during initdb, and set - postgresql.conf entries - timezone and - log_timezone - accordingly (Tom Lane) - - - - This avoids expensive time zone probes during server start. - - - - - - Fix pg_settings to - report postgresql.conf line numbers on Windows - (Tom Lane) - - - - - - - - - - - - - Replication and Recovery - - - - - - Allow streaming replication slaves to forward data to other slaves - (cascading - replication) (Fujii Masao) - - - - Previously, only the master server could supply streaming - replication log files to standby servers. - - - - - - Add new synchronous_commit - mode remote_write (Fujii Masao, Simon Riggs) - - - - This mode waits for the standby server to write transaction data to - its own operating system, but does not wait for the data to be - flushed to the standby's disk. - - - - - - Add a pg_receivexlog - tool to archive WAL file changes as they are written, rather - than waiting for completed WAL files (Magnus Hagander) - - - - - - Allow pg_basebackup - to make base backups from standby servers (Jun Ishizuka, Fujii Masao) - - - - This feature lets the work of making new base backups be off-loaded - from the primary server. - - - - - - Allow streaming of WAL files while pg_basebackup - is performing a backup (Magnus Hagander) - - - - This allows passing of WAL files to the standby before they are - discarded on the primary. - - - - - - - - - Queries - - - - - - Cancel the running query if the client gets disconnected - (Florian Pflug) - - - - If the backend detects loss of client connection during a query, it - will now cancel the query rather than attempting to finish it. - - - - - - Retain column names at run time for row expressions - (Andrew Dunstan, Tom Lane) - - - - This change allows better results when a row value is converted to - hstore or json type: the fields of the resulting - value will now have the expected names. - - - - - - Improve column labels used for sub-SELECT results - (Marti Raudsepp) - - - - Previously, the generic label ?column? was used. - - - - - - Improve heuristics for determining the types of unknown values - (Tom Lane) - - - - The longstanding rule that an unknown constant might have the - same type as the value on the other side of the operator using it - is now applied when considering polymorphic operators, not only - for simple operator matches. - - - - - - Warn about creating casts to or from domain types (Robert Haas) - - - - Such casts have no effect. - - - - - - When a row fails a CHECK or NOT NULL - constraint, show the row's contents as error detail (Jan - Kundrát) - - - - This should make it easier to identify which row is problematic - when an insert or update is processing many rows. - - - - - - - - - Object Manipulation - - - - - - Provide more reliable operation during concurrent - DDL (Robert Haas, Noah Misch) - - - - This change adds locking that should eliminate cache lookup - failed errors in many scenarios. Also, it is no longer possible - to add relations to a schema that is being concurrently dropped, a - scenario that formerly led to inconsistent system catalog contents. - - - - - - Add CONCURRENTLY option to DROP INDEX - (Simon Riggs) - - - - This allows index removal without blocking other sessions. - - - - - - Allow foreign data wrappers to have per-column options (Shigeru Hanada) - - - - - - Improve pretty-printing of view definitions (Andrew Dunstan) - - - - - - - Constraints - - - - - - Allow CHECK - constraints to be declared NOT VALID (Álvaro - Herrera) - - - - Adding a NOT VALID constraint does not cause the table to - be scanned to verify that existing rows meet the constraint. - Subsequently, newly added or updated rows are checked. - Such constraints are ignored by the planner when considering - constraint_exclusion, since it is not certain that all - rows meet the constraint. - - - - The new ALTER TABLE VALIDATE command allows NOT - VALID constraints to be checked for existing rows, after which - they are converted into ordinary constraints. - - - - - - Allow CHECK constraints to be declared NO - INHERIT (Nikhil Sontakke, Alex Hunsaker, Álvaro Herrera) - - - - This makes them enforceable only on the parent table, not on - child tables. - - - - - - Add the ability to rename - constraints (Peter Eisentraut) - - - - - - - - <command>ALTER</command> - - - - - - Reduce need to rebuild tables and indexes for certain ALTER TABLE - ... ALTER COLUMN TYPE operations (Noah Misch) - - - - Increasing the length limit for a varchar or varbit - column, or removing the limit altogether, no longer requires a table - rewrite. Similarly, increasing the allowable precision of a - numeric column, or changing a column from constrained - numeric to unconstrained numeric, no longer - requires a table rewrite. Table rewrites are also avoided in similar - cases involving the interval, timestamp, and - timestamptz types. - - - - - - Avoid having ALTER - TABLE revalidate foreign key constraints in some - cases where it is not necessary (Noah Misch) - - - - - - Add IF EXISTS options to some ALTER - commands (Pavel Stehule) - - - - For example, ALTER FOREIGN TABLE IF EXISTS foo RENAME - TO bar. - - - - - - Add ALTER - FOREIGN DATA WRAPPER ... RENAME - and ALTER - SERVER ... RENAME (Peter Eisentraut) - - - - - - Add ALTER - DOMAIN ... RENAME (Peter Eisentraut) - - - - You could already rename domains using ALTER - TYPE. - - - - - - Throw an error for ALTER DOMAIN ... DROP - CONSTRAINT on a nonexistent constraint (Peter Eisentraut) - - - - An IF EXISTS option has been added to provide the - previous behavior. - - - - - - - - - <link linkend="sql-createtable"><command>CREATE TABLE</command></link> - - - - - - Allow CREATE TABLE (LIKE ...) from foreign - tables, views, and composite types (Peter Eisentraut) - - - - For example, this allows a table to be created whose schema matches a - view. - - - - - - Fix CREATE TABLE (LIKE ...) to avoid index name - conflicts when copying index comments (Tom Lane) - - - - - - Fix CREATE TABLE ... AS EXECUTE - to handle WITH NO DATA and column name specifications - (Tom Lane) - - - - - - - - - Object Permissions - - - - - - Add a security_barrier - option for views (KaiGai Kohei, Robert Haas) - - - - This option prevents optimizations that might allow view-protected - data to be exposed to users, for example pushing a clause involving - an insecure function into the WHERE clause of the view. - Such views can be expected to perform more poorly than ordinary - views. - - - - - - Add a new LEAKPROOF function - attribute to mark functions that can safely be pushed down - into security_barrier views (KaiGai Kohei) - - - - - - Add support for privileges on data types (Peter Eisentraut) - - - - This adds support for the SQL-conforming - USAGE privilege on types and domains. The intent is - to be able to restrict which users can create dependencies on types, - since such dependencies limit the owner's ability to alter the type. - - - - - - Check for INSERT privileges in SELECT - INTO / CREATE TABLE AS (KaiGai Kohei) - - - - Because the object is being created by SELECT INTO - or CREATE TABLE AS, the creator would ordinarily - have insert permissions; but there are corner cases where this is not - true, such as when ALTER DEFAULT PRIVILEGES has removed - such permissions. - - - - - - - - - - - Utility Operations - - - - - - Allow VACUUM to more - easily skip pages that cannot be locked (Simon Riggs, Robert Haas) - - - - This change should greatly reduce the incidence of VACUUM - getting stuck waiting for other sessions. - - - - - - Make EXPLAIN - (BUFFERS) count blocks dirtied and written (Robert Haas) - - - - - - Make EXPLAIN ANALYZE report the number of rows - rejected by filter steps (Marko Tiikkaja) - - - - - - Allow EXPLAIN ANALYZE to avoid timing overhead when - time values are not wanted (Tomas Vondra) - - - - This is accomplished by setting the new TIMING option to - FALSE. - - - - - - - - - Data Types - - - - - - Add support for range data types - (Jeff Davis, Tom Lane, Alexander Korotkov) - - - - A range data type stores a lower and upper bound belonging to its - base data type. It supports operations like contains, overlaps, and - intersection. - - - - - - Add a JSON - data type (Robert Haas) - - - - This type stores JSON (JavaScript Object Notation) - data with proper validation. - - - - - - Add array_to_json() - and row_to_json() (Andrew Dunstan) - - - - - - Add a SMALLSERIAL - data type (Mike Pultz) - - - - This is like SERIAL, except it stores the sequence in - a two-byte integer column (int2). - - - - - - Allow domains to be - declared NOT VALID (Álvaro Herrera) - - - - This option can be set at domain creation time, or via ALTER - DOMAIN ... ADD CONSTRAINT ... NOT - VALID. ALTER DOMAIN ... VALIDATE - CONSTRAINT fully validates the constraint. - - - - - - Support more locale-specific formatting options for the money data type (Tom Lane) - - - - Specifically, honor all the POSIX options for ordering of the value, - sign, and currency symbol in monetary output. Also, make sure that - the thousands separator is only inserted to the left of the decimal - point, as required by POSIX. - - - - - - Add bitwise and, or, and not - operators for the macaddr data type (Brendan Jurd) - - - - - - Allow xpath() to - return a single-element XML array when supplied a - scalar value (Florian Pflug) - - - - Previously, it returned an empty array. This change will also - cause xpath_exists() to return true, not false, - for such expressions. - - - - - - Improve XML error handling to be more robust - (Florian Pflug) - - - - - - - - - Functions - - - - - - Allow non-superusers to use pg_cancel_backend() - and pg_terminate_backend() - on other sessions belonging to the same user - (Magnus Hagander, Josh Kupershmidt, Dan Farina) - - - - Previously only superusers were allowed to use these functions. - - - - - - Allow importing and exporting of transaction snapshots (Joachim - Wieland, Tom Lane) - - - - This allows multiple transactions to share identical views of the - database state. - Snapshots are exported via pg_export_snapshot() - and imported via SET - TRANSACTION SNAPSHOT. Only snapshots from - currently-running transactions can be imported. - - - - - - Support COLLATION - FOR on expressions (Peter Eisentraut) - - - - This returns a string representing the collation of the expression. - - - - - - Add pg_opfamily_is_visible() - (Josh Kupershmidt) - - - - - - Add a numeric variant of pg_size_pretty() - for use with pg_xlog_location_diff() (Fujii Masao) - - - - - - Add a pg_trigger_depth() - function (Kevin Grittner) - - - - This reports the current trigger call depth. - - - - - - Allow string_agg() - to process bytea values (Pavel Stehule) - - - - - - Fix regular expressions in which a back-reference occurs within - a larger quantified subexpression (Tom Lane) - - - - For example, ^(\w+)( \1)+$. Previous releases did not - check that the back-reference actually matched the first occurrence. - - - - - - - - - <link linkend="information-schema">Information Schema</link> - - - - - - Add information schema views - role_udt_grants, udt_privileges, - and user_defined_types (Peter Eisentraut) - - - - - - Add composite-type attributes to the - information schema element_types view - (Peter Eisentraut) - - - - - - Implement interval_type columns in the information - schema (Peter Eisentraut) - - - - Formerly these columns read as nulls. - - - - - - Implement collation-related columns in the information schema - attributes, columns, - domains, and element_types - views (Peter Eisentraut) - - - - - - Implement the with_hierarchy column in the - information schema table_privileges view (Peter - Eisentraut) - - - - - - Add display of sequence USAGE privileges to information - schema (Peter Eisentraut) - - - - - - Make the information schema show default privileges (Peter - Eisentraut) - - - - Previously, non-empty default permissions were not represented in the - views. - - - - - - - - - Server-Side Languages - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - Allow the PL/pgSQL OPEN cursor command to supply - parameters by name (Yeb Havinga) - - - - - - Add a GET STACKED DIAGNOSTICS PL/pgSQL command - to retrieve exception info (Pavel Stehule) - - - - - - Speed up PL/pgSQL array assignment by caching type information - (Pavel Stehule) - - - - - - Improve performance and memory consumption for long chains of - ELSIF clauses (Tom Lane) - - - - - - Output the function signature, not just the name, in PL/pgSQL - error messages (Pavel Stehule) - - - - - - - - - <link linkend="plpython">PL/Python</link> Server-Side Language - - - - - - Add PL/Python SPI cursor support (Jan - Urbanski) - - - - This allows PL/Python to read partial result sets. - - - - - - Add result metadata functions to PL/Python (Peter Eisentraut) - - - - Specifically, this adds result object functions - .colnames, .coltypes, and - .coltypmods. - - - - - - Remove support for Python 2.2 (Peter Eisentraut) - - - - - - - - - <link linkend="xfunc-sql">SQL</link> Server-Side Language - - - - - Allow SQL-language functions to reference - parameters by name (Matthew Draper) - - - - To use this, simply name the function arguments and then reference - the argument names in the SQL function body. - - - - - - - - - - Client Applications - - - - - - Add initdb - options and - (Peter Eisentraut) - - - - This allows separate control of local and - host pg_hba.conf authentication - settings. still controls both. - - - - - - Add / flags to - createuser - to control replication permission (Fujii Masao) - - - - - - Add the option to dropdb and dropuser (Josh - Kupershmidt) - - - - - - Give command-line tools the ability to specify the name of the - database to connect to, and fall back to template1 - if a postgres database connection fails (Robert Haas) - - - - - - - <link linkend="app-psql"><application>psql</application></link> - - - - - - Add a display mode to auto-expand output based on the - display width (Peter Eisentraut) - - - - This adds the auto option to the \x - command, which switches to the expanded mode when the normal - output would be wider than the screen. - - - - - - Allow inclusion of a script file that is named relative to the - directory of the file from which it was invoked (Gurjeet Singh) - - - - This is done with a new command \ir. - - - - - - Add support for non-ASCII characters in - psql variable names (Tom Lane) - - - - - - Add support for major-version-specific .psqlrc files - (Bruce Momjian) - - - - psql already supported minor-version-specific - .psqlrc files. - - - - - - Provide environment variable overrides for psql - history and startup file locations (Andrew Dunstan) - - - - PSQL_HISTORY and PSQLRC now - determine these file names if set. - - - - - - Add a \setenv command to modify - the environment variables passed to child processes (Andrew Dunstan) - - - - - - Name psql's temporary editor files with a - .sql extension (Peter Eisentraut) - - - - This allows extension-sensitive editors to select the right mode. - - - - - - Allow psql to use zero-byte field and record - separators (Peter Eisentraut) - - - - Various shell tools use zero-byte (NUL) separators, - e.g. find. - - - - - - Make the \timing option report times for - failed queries (Magnus Hagander) - - - - Previously times were reported only for successful queries. - - - - - - Unify and tighten psql's treatment of \copy - and SQL COPY (Noah Misch) - - - - This fix makes failure behavior more predictable and honors - \set ON_ERROR_ROLLBACK. - - - - - - - - - Informational Commands - - - - - Make \d on a sequence show the - table/column name owning it (Magnus Hagander) - - - - - - Show statistics target for columns in \d+ (Magnus - Hagander) - - - - - - Show role password expiration dates in \du - (Fabrízio de Royes Mello) - - - - - - Display comments for casts, conversions, domains, and languages - (Josh Kupershmidt) - - - - These are included in the output of \dC+, - \dc+, \dD+, and \dL respectively. - - - - - - Display comments for SQL/MED - objects (Josh Kupershmidt) - - - - These are included in the output of \des+, - \det+, and \dew+ for foreign servers, foreign - tables, and foreign data wrappers respectively. - - - - - - Change \dd to display comments only for object types - without their own backslash command (Josh Kupershmidt) - - - - - - - - - Tab Completion - - - - - - In psql tab completion, complete SQL - keywords in either upper or lower case according to the new COMP_KEYWORD_CASE - setting (Peter Eisentraut) - - - - - - Add tab completion support for - EXECUTE (Andreas Karlsson) - - - - - - Allow tab completion of role references in - GRANT/REVOKE (Peter - Eisentraut) - - - - - - Allow tab completion of file names to supply quotes, when necessary - (Noah Misch) - - - - - - Change tab completion support for - TABLE to also include views (Magnus Hagander) - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> - - - - - - Add an option to - pg_dump (Andrew Dunstan) - - - - This allows dumping of a table's definition but not its data, - on a per-table basis. - - - - - - Add a option to pg_dump - and pg_restore (Andrew Dunstan) - - - - Valid values are pre-data, data, - and post-data. The option can be - given more than once to select two or more sections. - - - - - - Make pg_dumpall dump all - roles first, then all configuration settings on roles (Phil Sorber) - - - - This allows a role's configuration settings to mention other - roles without generating an error. - - - - - - Allow pg_dumpall to avoid errors if the - postgres database is missing in the new cluster - (Robert Haas) - - - - - - Dump foreign server user mappings in user name order (Peter - Eisentraut) - - - - This helps produce deterministic dump files. - - - - - - Dump operators in a predictable order (Peter Eisentraut) - - - - - - Tighten rules for when extension configuration tables are dumped - by pg_dump (Tom Lane) - - - - - - Make pg_dump emit more useful dependency - information (Tom Lane) - - - - The dependency links included in archive-format dumps were formerly - of very limited use, because they frequently referenced objects that - appeared nowhere in the dump. Now they represent actual dependencies - (possibly indirect) among the dumped objects. - - - - - - Improve pg_dump's performance when dumping many - database objects (Tom Lane) - - - - - - - - - - - <link linkend="libpq"><application>libpq</application></link> - - - - - - Allow libpq connection strings to have the format of a - URI - (Alexander Shulgin) - - - - The syntax begins with postgres://. This can allow - applications to avoid implementing their own parser for URIs - representing database connections. - - - - - - Add a connection - option to disable SSL compression - (Laurenz Albe) - - - - This can be used to remove the overhead of SSL - compression on fast networks. - - - - - - Add a single-row processing - mode for better handling of large result sets - (Kyotaro Horiguchi, Marko Kreen) - - - - Previously, libpq always collected the entire query - result in memory before passing it back to the application. - - - - - - Add const qualifiers to the declarations of the functions - PQconnectdbParams, PQconnectStartParams, - and PQpingParams (Lionel Elie Mamane) - - - - - - Allow the .pgpass file to include escaped characters - in the password field (Robert Haas) - - - - - - Make library functions use abort() instead of - exit() when it is necessary to terminate the process - (Peter Eisentraut) - - - - This choice does not interfere with the normal exit codes used by the - program, and generates a signal that can be caught by the caller. - - - - - - - - - Source Code - - - - - - Remove dead ports (Peter Eisentraut) - - - - The following platforms are no longer supported: dgux, - nextstep, sunos4, svr4, ultrix4, univel, bsdi. - - - - - - Add support for building with MS - Visual Studio 2010 (Brar Piening) - - - - - - Enable compiling with the MinGW-w64 32-bit compiler (Lars Kanis) - - - - - - Install plpgsql.h into include/server during installation - (Heikki Linnakangas) - - - - - - Improve the latch facility to include detection of postmaster death - (Peter Geoghegan, Heikki Linnakangas, Tom Lane) - - - - This eliminates one of the main reasons that background processes - formerly had to wake up to poll for events. - - - - - - Use C flexible array members, where supported (Peter Eisentraut) - - - - - - Improve the concurrent transaction regression tests - (isolationtester) (Noah Misch) - - - - - - Modify thread_test to create its test files in - the current directory, rather than /tmp (Bruce Momjian) - - - - - - Improve flex and bison warning and error reporting (Tom Lane) - - - - - - Add memory barrier support (Robert Haas) - - - - This is currently unused. - - - - - - Modify pgindent to use a typedef file (Bruce Momjian) - - - - - - Add a hook for processing messages due to be sent to the server - log (Martin Pihlak) - - - - - - Add object access hooks for DROP commands - (KaiGai Kohei) - - - - - - Centralize DROP handling for some object types - (KaiGai Kohei) - - - - - - Add a pg_upgrade test suite (Peter Eisentraut) - - - - - - Sync regular expression code with TCL 8.5.11 - and improve internal processing (Tom Lane) - - - - - - Move CRC tables to libpgport, and provide them - in a separate include file (Daniel Farina) - - - - - - Add options to git_changelog for use in major - release note creation (Bruce Momjian) - - - - - - Support Linux's /proc/self/oom_score_adj API (Tom Lane) - - - - - - - - - Additional Modules - - - - - - Improve efficiency of dblink by using - libpq's new single-row processing mode (Kyotaro Horiguchi, Marko - Kreen) - - - - This improvement does not apply to - dblink_send_query()/dblink_get_result(). - - - - - - Support force_not_null option in file_fdw (Shigeru Hanada) - - - - - - Implement dry-run mode for pg_archivecleanup - (Gabriele Bartolini) - - - - This only outputs the names of files to be deleted. - - - - - - Add new pgbench switches - , , and - (Robert Haas) - - - - - - Change pg_test_fsync to test - for a fixed amount of time, rather than a fixed number of cycles - (Bruce Momjian) - - - - The /cycles option was removed, and - /seconds added. - - - - - - Add a pg_test_timing - utility to measure clock monotonicity and timing overhead (Ants - Aasma, Greg Smith) - - - - - - Add a tcn (triggered change notification) - module to generate NOTIFY events on table changes - (Kevin Grittner) - - - - - - - <link linkend="pgupgrade"><application>pg_upgrade</application></link> - - - - - - Adjust pg_upgrade environment variables (Bruce - Momjian) - - - - Rename data, bin, and port environment - variables to begin with PG, and support - PGPORTOLD/PGPORTNEW, to replace - PGPORT. - - - - - - Overhaul pg_upgrade logging and failure reporting - (Bruce Momjian) - - - - Create four append-only log files, and delete them on success. - Add / option to unconditionally - retain these files. Also remove pg_upgrade options - // options as unnecessary, - and tighten log file permissions. - - - - - - Make pg_upgrade create a script to incrementally - generate more accurate optimizer statistics (Bruce Momjian) - - - - This reduces the time needed to generate minimal cluster statistics - after an upgrade. - - - - - - Allow pg_upgrade to upgrade an old cluster that - does not have a postgres database (Bruce Momjian) - - - - - - Allow pg_upgrade to handle cases where some - old or new databases are missing, as long as they are empty - (Bruce Momjian) - - - - - - Allow pg_upgrade to handle configuration-only - directory installations (Bruce Momjian) - - - - - - In pg_upgrade, add / - options to pass parameters to the servers (Bruce Momjian) - - - - This is useful for configuration-only directory installs. - - - - - - Change pg_upgrade to use port 50432 by default - (Bruce Momjian) - - - - This helps avoid unintended client connections during the upgrade. - - - - - - Reduce cluster locking in pg_upgrade (Bruce - Momjian) - - - - Specifically, only lock the old cluster if link mode is used, - and do it right after the schema is restored. - - - - - - - - - <link linkend="pgstatstatements"><application>pg_stat_statements</application></link> - - - - - - Allow pg_stat_statements to aggregate similar - queries via SQL text normalization (Peter Geoghegan, Tom Lane) - - - - Users with applications that use non-parameterized SQL will now - be able to monitor query performance without detailed log analysis. - - - - - - Add dirtied and written block counts and read/write times to - pg_stat_statements (Robert Haas, Ants Aasma) - - - - - - Prevent pg_stat_statements from double-counting - PREPARE and EXECUTE commands - (Tom Lane) - - - - - - - - - <link linkend="sepgsql">sepgsql</link> - - - - - Support SECURITY LABEL on global objects (KaiGai - Kohei, Robert Haas) - - - - Specifically, add security labels to databases, - tablespaces, and roles. - - - - - - Allow sepgsql to honor database labels (KaiGai Kohei) - - - - - - Perform sepgsql permission checks during the creation of various - objects (KaiGai Kohei) - - - - - - Add sepgsql_setcon() and related functions to control - the sepgsql security domain (KaiGai Kohei) - - - - - - Add a user space access cache to sepgsql to improve performance - (KaiGai Kohei) - - - - - - - - - - Documentation - - - - - - Add a rule to optionally build HTML documentation using the - stylesheet from the website (Magnus Hagander) - - - - Use gmake STYLE=website draft. - - - - - - Improve EXPLAIN documentation (Tom Lane) - - - - - - Document that user/database names are preserved with double-quoting - by command-line tools like vacuumdb (Bruce - Momjian) - - - - - - Document the actual string returned by the client for MD5 - authentication (Cyan Ogilvie) - - - - - - Deprecate use of GLOBAL and LOCAL in - CREATE TEMP TABLE (Noah Misch) - - - - PostgreSQL has long treated these keyword as no-ops, - and continues to do so; but in future they might mean what the SQL - standard says they mean, so applications should avoid using them. - - - - - - - - - diff --git a/doc/src/sgml/release-9.3.sgml b/doc/src/sgml/release-9.3.sgml deleted file mode 100644 index 015c2211b0f..00000000000 --- a/doc/src/sgml/release-9.3.sgml +++ /dev/null @@ -1,13399 +0,0 @@ - - - - - Release 9.3.22 - - - Release date: - 2018-03-01 - - - - This release contains a variety of fixes from 9.3.21. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.22 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you run an installation in which not all users are mutually - trusting, or if you maintain an application or extension that is - intended for use in arbitrary situations, it is strongly recommended - that you read the documentation changes described in the first changelog - entry below, and take suitable steps to ensure that your installation or - code is secure. - - - - Also, the changes described in the second changelog entry below may - cause functions used in index expressions or materialized views to fail - during auto-analyze, or when reloading from a dump. After upgrading, - monitor the server logs for such problems, and fix affected functions. - - - - Also, if you are upgrading from a version earlier than 9.3.18, - see . - - - - - Changes - - - - - - Document how to configure installations and applications to guard - against search-path-dependent trojan-horse attacks from other users - (Noah Misch) - - - - Using a search_path setting that includes any - schemas writable by a hostile user enables that user to capture - control of queries and then run arbitrary SQL code with the - permissions of the attacked user. While it is possible to write - queries that are proof against such hijacking, it is notationally - tedious, and it's very easy to overlook holes. Therefore, we now - recommend configurations in which no untrusted schemas appear in - one's search path. Relevant documentation appears in - (for database administrators and users), - (for application authors), - (for extension authors), and - (for authors - of SECURITY DEFINER functions). - (CVE-2018-1058) - - - - - - Avoid use of insecure search_path settings - in pg_dump and other client programs - (Noah Misch, Tom Lane) - - - - pg_dump, - pg_upgrade, - vacuumdb and - other PostgreSQL-provided applications were - themselves vulnerable to the type of hijacking described in the previous - changelog entry; since these applications are commonly run by - superusers, they present particularly attractive targets. To make them - secure whether or not the installation as a whole has been secured, - modify them to include only the pg_catalog - schema in their search_path settings. - Autovacuum worker processes now do the same, as well. - - - - In cases where user-provided functions are indirectly executed by - these programs — for example, user-provided functions in index - expressions — the tighter search_path may - result in errors, which will need to be corrected by adjusting those - user-provided functions to not assume anything about what search path - they are invoked under. That has always been good practice, but now - it will be necessary for correct behavior. - (CVE-2018-1058) - - - - - - Fix misbehavior of concurrent-update rechecks with CTE references - appearing in subplans (Tom Lane) - - - - If a CTE (WITH clause reference) is used in an - InitPlan or SubPlan, and the query requires a recheck due to trying - to update or lock a concurrently-updated row, incorrect results could - be obtained. - - - - - - Fix planner failures with overlapping mergejoin clauses in an outer - join (Tom Lane) - - - - These mistakes led to left and right pathkeys do not match in - mergejoin or outer pathkeys do not match - mergeclauses planner errors in corner cases. - - - - - - Repair pg_upgrade's failure to - preserve relfrozenxid for materialized - views (Tom Lane, Andres Freund) - - - - This oversight could lead to data corruption in materialized views - after an upgrade, manifesting as could not access status of - transaction or found xmin from before - relfrozenxid errors. The problem would be more likely to - occur in seldom-refreshed materialized views, or ones that were - maintained only with REFRESH MATERIALIZED VIEW - CONCURRENTLY. - - - - If such corruption is observed, it can be repaired by refreshing the - materialized view (without CONCURRENTLY). - - - - - - Fix incorrect reporting of PL/Python function names in - error CONTEXT stacks (Tom Lane) - - - - An error occurring within a nested PL/Python function call (that is, - one reached via a SPI query from another PL/Python function) would - result in a stack trace showing the inner function's name twice, - rather than the expected results. Also, an error in a nested - PL/Python DO block could result in a null pointer - dereference crash on some platforms. - - - - - - Allow contrib/auto_explain's - log_min_duration setting to range up - to INT_MAX, or about 24 days instead of 35 minutes - (Tom Lane) - - - - - - - - - - Release 9.3.21 - - - Release date: - 2018-02-08 - - - - This release contains a variety of fixes from 9.3.20. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.21 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.18, - see . - - - - - Changes - - - - - - Ensure that all temporary files made - by pg_upgrade are non-world-readable - (Tom Lane, Noah Misch) - - - - pg_upgrade normally restricts its - temporary files to be readable and writable only by the calling user. - But the temporary file containing pg_dumpall -g - output would be group- or world-readable, or even writable, if the - user's umask setting allows. In typical usage on - multi-user machines, the umask and/or the working - directory's permissions would be tight enough to prevent problems; - but there may be people using pg_upgrade - in scenarios where this oversight would permit disclosure of database - passwords to unfriendly eyes. - (CVE-2018-1053) - - - - - - Fix vacuuming of tuples that were updated while key-share locked - (Andres Freund, Álvaro Herrera) - - - - In some cases VACUUM would fail to remove such - tuples even though they are now dead, leading to assorted data - corruption scenarios. - - - - - - Fix inadequate buffer locking in some LSN fetches (Jacob Champion, - Asim Praveen, Ashwin Agrawal) - - - - These errors could result in misbehavior under concurrent load. - The potential consequences have not been characterized fully. - - - - - - Avoid unnecessary failure in a query on an inheritance tree that - occurs concurrently with some child table being removed from the tree - by ALTER TABLE NO INHERIT (Tom Lane) - - - - - - Repair failure with correlated sub-SELECT - inside VALUES inside a LATERAL - subquery (Tom Lane) - - - - - - Fix could not devise a query plan for the given query - planner failure for some cases involving nested UNION - ALL inside a lateral subquery (Tom Lane) - - - - - - Fix has_sequence_privilege() to - support WITH GRANT OPTION tests, - as other privilege-testing functions do (Joe Conway) - - - - - - In databases using UTF8 encoding, ignore any XML declaration that - asserts a different encoding (Pavel Stehule, Noah Misch) - - - - We always store XML strings in the database encoding, so allowing - libxml to act on a declaration of another encoding gave wrong results. - In encodings other than UTF8, we don't promise to support non-ASCII - XML data anyway, so retain the previous behavior for bug compatibility. - This change affects only xpath() and related - functions; other XML code paths already acted this way. - - - - - - Provide for forward compatibility with future minor protocol versions - (Robert Haas, Badrul Chowdhury) - - - - Up to now, PostgreSQL servers simply - rejected requests to use protocol versions newer than 3.0, so that - there was no functional difference between the major and minor parts - of the protocol version number. Allow clients to request versions 3.x - without failing, sending back a message showing that the server only - understands 3.0. This makes no difference at the moment, but - back-patching this change should allow speedier introduction of future - minor protocol upgrades. - - - - - - Prevent stack-overflow crashes when planning extremely deeply - nested set operations - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Fix null-pointer crashes for some types of LDAP URLs appearing - in pg_hba.conf (Thomas Munro) - - - - - - Fix sample INSTR() functions in the PL/pgSQL - documentation (Yugo Nagata, Tom Lane) - - - - These functions are stated to - be Oracle compatible, but - they weren't exactly. In particular, there was a discrepancy in the - interpretation of a negative third parameter: Oracle thinks that a - negative value indicates the last place where the target substring can - begin, whereas our functions took it as the last place where the - target can end. Also, Oracle throws an error for a zero or negative - fourth parameter, whereas our functions returned zero. - - - - The sample code has been adjusted to match Oracle's behavior more - precisely. Users who have copied this code into their applications - may wish to update their copies. - - - - - - Fix pg_dump to make ACL (permissions), - comment, and security label entries reliably identifiable in archive - output formats (Tom Lane) - - - - The tag portion of an ACL archive entry was usually - just the name of the associated object. Make it start with the object - type instead, bringing ACLs into line with the convention already used - for comment and security label archive entries. Also, fix the - comment and security label entries for the whole database, if present, - to make their tags start with DATABASE so that they - also follow this convention. This prevents false matches in code that - tries to identify large-object-related entries by seeing if the tag - starts with LARGE OBJECT. That could have resulted - in misclassifying entries as data rather than schema, with undesirable - results in a schema-only or data-only dump. - - - - Note that this change has user-visible results in the output - of pg_restore --list. - - - - - - In ecpg, detect indicator arrays that do - not have the correct length and report an error (David Rader) - - - - - - Avoid triggering a libc assertion - in contrib/hstore, due to use - of memcpy() with equal source and destination - pointers (Tomas Vondra) - - - - - - Provide modern examples of how to auto-start Postgres on macOS - (Tom Lane) - - - - The scripts in contrib/start-scripts/osx use - infrastructure that's been deprecated for over a decade, and which no - longer works at all in macOS releases of the last couple of years. - Add a new subdirectory contrib/start-scripts/macos - containing scripts that use the newer launchd - infrastructure. - - - - - - Fix incorrect selection of configuration-specific libraries for - OpenSSL on Windows (Andrew Dunstan) - - - - - - Support linking to MinGW-built versions of libperl (Noah Misch) - - - - This allows building PL/Perl with some common Perl distributions for - Windows. - - - - - - Fix MSVC build to test whether 32-bit libperl - needs -D_USE_32BIT_TIME_T (Noah Misch) - - - - Available Perl distributions are inconsistent about what they expect, - and lack any reliable means of reporting it, so resort to a build-time - test on what the library being used actually does. - - - - - - On Windows, install the crash dump handler earlier in postmaster - startup (Takayuki Tsunakawa) - - - - This may allow collection of a core dump for some early-startup - failures that did not produce a dump before. - - - - - - On Windows, avoid encoding-conversion-related crashes when emitting - messages very early in postmaster startup (Takayuki Tsunakawa) - - - - - - Use our existing Motorola 68K spinlock code on OpenBSD as - well as NetBSD (David Carlier) - - - - - - Add support for spinlocks on Motorola 88K (David Carlier) - - - - - - Update time zone data files to tzdata - release 2018c for DST law changes in Brazil, Sao Tome and Principe, - plus historical corrections for Bolivia, Japan, and South Sudan. - The US/Pacific-New zone has been removed (it was - only an alias for America/Los_Angeles anyway). - - - - - - - - - - Release 9.3.20 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 9.3.19. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.20 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.18, - see . - - - - - - Changes - - - - - - Fix crash due to rowtype mismatch - in json{b}_populate_recordset() - (Michael Paquier, Tom Lane) - - - - These functions used the result rowtype specified in the FROM - ... AS clause without checking that it matched the actual - rowtype of the supplied tuple value. If it didn't, that would usually - result in a crash, though disclosure of server memory contents seems - possible as well. - (CVE-2017-15098) - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - Properly reject attempts to convert infinite float values to - type numeric (Tom Lane, KaiGai Kohei) - - - - Previously the behavior was platform-dependent. - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - Prevent low-probability crash in processing of nested trigger firings - (Tom Lane) - - - - - - Correctly restore the umask setting when file creation fails - in COPY or lo_export() - (Peter Eisentraut) - - - - - - Give a better error message for duplicate column names - in ANALYZE (Nathan Bossart) - - - - - - Fix mis-parsing of the last line in a - non-newline-terminated pg_hba.conf file - (Tom Lane) - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - Fix libpq to guard against integer - overflow in the row count of a PGresult - (Michael Paquier) - - - - - - Fix ecpg's handling of out-of-scope cursor - declarations with pointer or array variables (Michael Meskes) - - - - - - Make ecpglib's Informix-compatibility mode ignore fractional digits in - integer input strings, as expected (Gao Zengqi, Michael Meskes) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017c - (Tom Lane) - - - - This fixes various issues; the only one likely to be user-visible - is that the default DST rules for a POSIX-style zone name, if - no posixrules file exists in the timezone data - directory, now match current US law rather than what it was a dozen - years ago. - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - - - - Release 9.3.19 - - - Release date: - 2017-08-31 - - - - This release contains a small number of fixes from 9.3.18. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.19 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.18, - see . - - - - - - Changes - - - - - - Show foreign tables - in information_schema.table_privileges - view (Peter Eisentraut) - - - - All other relevant information_schema views include - foreign tables, but this one ignored them. - - - - Since this view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can, as a superuser, do this - in psql: - -SET search_path TO information_schema; -CREATE OR REPLACE VIEW table_privileges AS - SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, - CAST(grantee.rolname AS sql_identifier) AS grantee, - CAST(current_database() AS sql_identifier) AS table_catalog, - CAST(nc.nspname AS sql_identifier) AS table_schema, - CAST(c.relname AS sql_identifier) AS table_name, - CAST(c.prtype AS character_data) AS privilege_type, - CAST( - CASE WHEN - -- object owner always has grant options - pg_has_role(grantee.oid, c.relowner, 'USAGE') - OR c.grantable - THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, - CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy - - FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class - ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), - pg_namespace nc, - pg_authid u_grantor, - ( - SELECT oid, rolname FROM pg_authid - UNION ALL - SELECT 0::oid, 'PUBLIC' - ) AS grantee (oid, rolname) - - WHERE c.relnamespace = nc.oid - AND c.relkind IN ('r', 'v', 'f') - AND c.grantee = grantee.oid - AND c.grantor = u_grantor.oid - AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') - AND (pg_has_role(u_grantor.oid, 'USAGE') - OR pg_has_role(grantee.oid, 'USAGE') - OR grantee.rolname = 'PUBLIC'); - - This must be repeated in each database to be fixed, - including template0. - - - - - - Clean up handling of a fatal exit (e.g., due to receipt - of SIGTERM) that occurs while trying to execute - a ROLLBACK of a failed transaction (Tom Lane) - - - - This situation could result in an assertion failure. In production - builds, the exit would still occur, but it would log an unexpected - message about cannot drop active portal. - - - - - - Remove assertion that could trigger during a fatal exit (Tom Lane) - - - - - - Correctly identify columns that are of a range type or domain type over - a composite type or domain type being searched for (Tom Lane) - - - - Certain ALTER commands that change the definition of a - composite type or domain type are supposed to fail if there are any - stored values of that type in the database, because they lack the - infrastructure needed to update or check such values. Previously, - these checks could miss relevant values that are wrapped inside range - types or sub-domains, possibly allowing the database to become - inconsistent. - - - - - - Fix crash in pg_restore when using parallel mode and - using a list file to select a subset of items to restore - (Fabrízio de Royes Mello) - - - - - - Change ecpg's parser to allow RETURNING - clauses without attached C variables (Michael Meskes) - - - - This allows ecpg programs to contain SQL constructs - that use RETURNING internally (for example, inside a CTE) - rather than using it to define values to be returned to the client. - - - - - - Improve selection of compiler flags for PL/Perl on Windows (Tom Lane) - - - - This fix avoids possible crashes of PL/Perl due to inconsistent - assumptions about the width of time_t values. - A side-effect that may be visible to extension developers is - that _USE_32BIT_TIME_T is no longer defined globally - in PostgreSQL Windows builds. This is not expected - to cause problems, because type time_t is not used - in any PostgreSQL API definitions. - - - - - - - - - - Release 9.3.18 - - - Release date: - 2017-08-10 - - - - This release contains a variety of fixes from 9.3.17. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.18 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.3.16, - see . - - - - - - Changes - - - - - - Further restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Noah Misch) - - - - The fix for CVE-2017-7486 was incorrect: it allowed a user - to see the options in her own user mapping, even if she did not - have USAGE permission on the associated foreign server. - Such options might include a password that had been provided by the - server owner rather than the user herself. - Since information_schema.user_mapping_options does not - show the options in such cases, pg_user_mappings - should not either. - (CVE-2017-7547) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - you will need to do the following: - - - - - - Restart the postmaster after adding allow_system_table_mods - = true to postgresql.conf. (In versions - supporting ALTER SYSTEM, you can use that to make the - configuration change, but you'll still need a restart.) - - - - - - In each database of the cluster, - run the following commands as superuser: - -SET search_path = pg_catalog; -CREATE OR REPLACE VIEW pg_user_mappings AS - SELECT - U.oid AS umid, - S.oid AS srvid, - S.srvname AS srvname, - U.umuser AS umuser, - CASE WHEN U.umuser = 0 THEN - 'public' - ELSE - A.rolname - END AS usename, - CASE WHEN (U.umuser <> 0 AND A.rolname = current_user - AND (pg_has_role(S.srvowner, 'USAGE') - OR has_server_privilege(S.oid, 'USAGE'))) - OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE')) - OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) - THEN U.umoptions - ELSE NULL END AS umoptions - FROM pg_user_mapping U - LEFT JOIN pg_authid A ON (A.oid = U.umuser) JOIN - pg_foreign_server S ON (U.umserver = S.oid); - - - - - - - Do not forget to include the template0 - and template1 databases, or the vulnerability will still - exist in databases you create later. To fix template0, - you'll need to temporarily make it accept connections. - In PostgreSQL 9.5 and later, you can use - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true; - - and then after fixing template0, undo that with - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false; - - In prior versions, instead use - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - - Finally, remove the allow_system_table_mods configuration - setting, and again restart the postmaster. - - - - - - - - Disallow empty passwords in all password-based authentication methods - (Heikki Linnakangas) - - - - libpq ignores empty password specifications, and does - not transmit them to the server. So, if a user's password has been - set to the empty string, it's impossible to log in with that password - via psql or other libpq-based - clients. An administrator might therefore believe that setting the - password to empty is equivalent to disabling password login. - However, with a modified or non-libpq-based client, - logging in could be possible, depending on which authentication - method is configured. In particular the most common - method, md5, accepted empty passwords. - Change the server to reject empty passwords in all cases. - (CVE-2017-7546) - - - - - - Fix concurrent locking of tuple update chains (Álvaro Herrera) - - - - If several sessions concurrently lock a tuple update chain with - nonconflicting lock modes using an old snapshot, and they all - succeed, it was possible for some of them to nonetheless fail (and - conclude there is no live tuple version) due to a race condition. - This had consequences such as foreign-key checks failing to see a - tuple that definitely exists but is being updated concurrently. - - - - - - Fix potential data corruption when freezing a tuple whose XMAX is a - multixact with exactly one still-interesting member (Teodor Sigaev) - - - - - - On Windows, retry process creation if we fail to reserve the address - range for our shared memory in the new process (Tom Lane, Amit - Kapila) - - - - This is expected to fix infrequent child-process-launch failures that - are probably due to interference from antivirus products. - - - - - - Fix low-probability corruption of shared predicate-lock hash table - in Windows builds (Thomas Munro, Tom Lane) - - - - - - Avoid logging clean closure of an SSL connection as though - it were a connection reset (Michael Paquier) - - - - - - Prevent sending SSL session tickets to clients (Tom Lane) - - - - This fix prevents reconnection failures with ticket-aware client-side - SSL code. - - - - - - Fix code for setting on - Solaris (Tom Lane) - - - - - - Fix statistics collector to honor inquiry messages issued just after - a postmaster shutdown and immediate restart (Tom Lane) - - - - Statistics inquiries issued within half a second of the previous - postmaster shutdown were effectively ignored. - - - - - - Ensure that the statistics collector's receive buffer size is at - least 100KB (Tom Lane) - - - - This reduces the risk of dropped statistics data on older platforms - whose default receive buffer size is less than that. - - - - - - Fix possible creation of an invalid WAL segment when a standby is - promoted just after it processes an XLOG_SWITCH WAL - record (Andres Freund) - - - - - - Fix SIGHUP and SIGUSR1 handling in - walsender processes (Petr Jelinek, Andres Freund) - - - - - - Fix unnecessarily slow restarts of walreceiver - processes due to race condition in postmaster (Tom Lane) - - - - - - Fix cases where an INSERT or UPDATE assigns - to more than one element of a column that is of domain-over-array - type (Tom Lane) - - - - - - Allow window functions to be used in sub-SELECTs that - are within the arguments of an aggregate function (Tom Lane) - - - - - - Move autogenerated array types out of the way during - ALTER ... RENAME (Vik Fearing) - - - - Previously, we would rename a conflicting autogenerated array type - out of the way during CREATE; this fix extends that - behavior to renaming operations. - - - - - - Ensure that ALTER USER ... SET accepts all the syntax - variants that ALTER ROLE ... SET does (Peter Eisentraut) - - - - - - Properly update dependency info when changing a datatype I/O - function's argument or return type from opaque to the - correct type (Heikki Linnakangas) - - - - CREATE TYPE updates I/O functions declared in this - long-obsolete style, but it forgot to record a dependency on the - type, allowing a subsequent DROP TYPE to leave broken - function definitions behind. - - - - - - Reduce memory usage when ANALYZE processes - a tsvector column (Heikki Linnakangas) - - - - - - Fix unnecessary precision loss and sloppy rounding when multiplying - or dividing money values by integers or floats (Tom Lane) - - - - - - Tighten checks for whitespace in functions that parse identifiers, - such as regprocedurein() (Tom Lane) - - - - Depending on the prevailing locale, these functions could - misinterpret fragments of multibyte characters as whitespace. - - - - - - Use relevant #define symbols from Perl while - compiling PL/Perl (Ashutosh Sharma, Tom Lane) - - - - This avoids portability problems, typically manifesting as - a handshake mismatch during library load, when working with - recent Perl versions. - - - - - - In libpq, reset GSS/SASL and SSPI authentication - state properly after a failed connection attempt (Michael Paquier) - - - - Failure to do this meant that when falling back from SSL to non-SSL - connections, a GSS/SASL failure in the SSL attempt would always cause - the non-SSL attempt to fail. SSPI did not fail, but it leaked memory. - - - - - - In psql, fix failure when COPY FROM STDIN - is ended with a keyboard EOF signal and then another COPY - FROM STDIN is attempted (Thomas Munro) - - - - This misbehavior was observed on BSD-derived platforms (including - macOS), but not on most others. - - - - - - Fix pg_dump and pg_restore to - emit REFRESH MATERIALIZED VIEW commands last (Tom Lane) - - - - This prevents errors during dump/restore when a materialized view - refers to tables owned by a different user. - - - - - - Fix pg_dump with the option to - drop event triggers as expected (Tom Lane) - - - - It also now correctly assigns ownership of event triggers; before, - they were restored as being owned by the superuser running the - restore script. - - - - - - Fix pg_dump to not emit invalid SQL for an empty - operator class (Daniel Gustafsson) - - - - - - Fix pg_dump output to stdout on Windows (Kuntal Ghosh) - - - - A compressed plain-text dump written to stdout would contain corrupt - data due to failure to put the file descriptor into binary mode. - - - - - - Fix pg_get_ruledef() to print correct output for - the ON SELECT rule of a view whose columns have been - renamed (Tom Lane) - - - - In some corner cases, pg_dump relies - on pg_get_ruledef() to dump views, so that this error - could result in dump/reload failures. - - - - - - Fix dumping of outer joins with empty constraints, such as the result - of a NATURAL LEFT JOIN with no common columns (Tom Lane) - - - - - - Fix dumping of function expressions in the FROM clause in - cases where the expression does not deparse into something that looks - like a function call (Tom Lane) - - - - - - Fix pg_basebackup output to stdout on Windows - (Haribabu Kommi) - - - - A backup written to stdout would contain corrupt data due to failure - to put the file descriptor into binary mode. - - - - - - Fix pg_upgrade to ensure that the ending WAL record - does not have = minimum - (Bruce Momjian) - - - - This condition could prevent upgraded standby servers from - reconnecting. - - - - - - In postgres_fdw, re-establish connections to remote - servers after ALTER SERVER or ALTER USER - MAPPING commands (Kyotaro Horiguchi) - - - - This ensures that option changes affecting connection parameters will - be applied promptly. - - - - - - In postgres_fdw, allow cancellation of remote - transaction control commands (Robert Haas, Rafia Sabih) - - - - This change allows us to quickly escape a wait for an unresponsive - remote server in many more cases than previously. - - - - - - Always use , not , when building - shared libraries with gcc (Tom Lane) - - - - This supports larger extension libraries on platforms where it makes - a difference. - - - - - - Fix unescaped-braces issue in our build scripts for Microsoft MSVC, - to avoid a warning or error from recent Perl versions (Andrew - Dunstan) - - - - - - In MSVC builds, handle the case where the openssl - library is not within a VC subdirectory (Andrew Dunstan) - - - - - - In MSVC builds, add proper include path for libxml2 - header files (Andrew Dunstan) - - - - This fixes a former need to move things around in standard Windows - installations of libxml2. - - - - - - In MSVC builds, recognize a Tcl library that is - named tcl86.lib (Noah Misch) - - - - - - - - - - Release 9.3.17 - - - Release date: - 2017-05-11 - - - - This release contains a variety of fixes from 9.3.16. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.17 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.3.16, - see . - - - - - - Changes - - - - - - Restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Michael Paquier, Feike Steenbergen) - - - - The previous coding allowed the owner of a foreign server object, - or anyone he has granted server USAGE permission to, - to see the options for all user mappings associated with that server. - This might well include passwords for other users. - Adjust the view definition to match the behavior of - information_schema.user_mapping_options, namely that - these options are visible to the user being mapped, or if the mapping - is for PUBLIC and the current user is the server - owner, or if the current user is a superuser. - (CVE-2017-7486) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - follow the corrected procedure shown in the changelog entry for - CVE-2017-7547, in . - - - - - - Prevent exposure of statistical information via leaky operators - (Peter Eisentraut) - - - - Some selectivity estimation functions in the planner will apply - user-defined operators to values obtained - from pg_statistic, such as most common values and - histogram entries. This occurs before table permissions are checked, - so a nefarious user could exploit the behavior to obtain these values - for table columns he does not have permission to read. To fix, - fall back to a default estimate if the operator's implementation - function is not certified leak-proof and the calling user does not have - permission to read the table column whose statistics are needed. - At least one of these criteria is satisfied in most cases in practice. - (CVE-2017-7484) - - - - - - Restore libpq's recognition of - the PGREQUIRESSL environment variable (Daniel Gustafsson) - - - - Processing of this environment variable was unintentionally dropped - in PostgreSQL 9.3, but its documentation remained. - This creates a security hazard, since users might be relying on the - environment variable to force SSL-encrypted connections, but that - would no longer be guaranteed. Restore handling of the variable, - but give it lower priority than PGSSLMODE, to avoid - breaking configurations that work correctly with post-9.3 code. - (CVE-2017-7485) - - - - - - Fix possible corruption of init forks of unlogged indexes - (Robert Haas, Michael Paquier) - - - - This could result in an unlogged index being set to an invalid state - after a crash and restart. Such a problem would persist until the - index was dropped and rebuilt. - - - - - - Fix incorrect reconstruction of pg_subtrans entries - when a standby server replays a prepared but uncommitted two-phase - transaction (Tom Lane) - - - - In most cases this turned out to have no visible ill effects, but in - corner cases it could result in circular references - in pg_subtrans, potentially causing infinite loops - in queries that examine rows modified by the two-phase transaction. - - - - - - Ensure parsing of queries in extension scripts sees the results of - immediately-preceding DDL (Julien Rouhaud, Tom Lane) - - - - Due to lack of a cache flush step between commands in an extension - script file, non-utility queries might not see the effects of an - immediately preceding catalog change, such as ALTER TABLE - ... RENAME. - - - - - - Skip tablespace privilege checks when ALTER TABLE ... ALTER - COLUMN TYPE rebuilds an existing index (Noah Misch) - - - - The command failed if the calling user did not currently have - CREATE privilege for the tablespace containing the index. - That behavior seems unhelpful, so skip the check, allowing the - index to be rebuilt where it is. - - - - - - Fix ALTER TABLE ... VALIDATE CONSTRAINT to not recurse - to child tables when the constraint is marked NO INHERIT - (Amit Langote) - - - - This fix prevents unwanted constraint does not exist failures - when no matching constraint is present in the child tables. - - - - - - Fix VACUUM to account properly for pages that could not - be scanned due to conflicting page pins (Andrew Gierth) - - - - This tended to lead to underestimation of the number of tuples in - the table. In the worst case of a small heavily-contended - table, VACUUM could incorrectly report that the table - contained no tuples, leading to very bad planning choices. - - - - - - Ensure that bulk-tuple-transfer loops within a hash join are - interruptible by query cancel requests (Tom Lane, Thomas Munro) - - - - - - Fix cursor_to_xml() to produce valid output - with tableforest = false - (Thomas Munro, Peter Eisentraut) - - - - Previously it failed to produce a wrapping <table> - element. - - - - - - Improve performance of pg_timezone_names view - (Tom Lane, David Rowley) - - - - - - Fix sloppy handling of corner-case errors from lseek() - and close() (Tom Lane) - - - - Neither of these system calls are likely to fail in typical situations, - but if they did, fd.c could get quite confused. - - - - - - Fix incorrect check for whether postmaster is running as a Windows - service (Michael Paquier) - - - - This could result in attempting to write to the event log when that - isn't accessible, so that no logging happens at all. - - - - - - Fix ecpg to support COMMIT PREPARED - and ROLLBACK PREPARED (Masahiko Sawada) - - - - - - Fix a double-free error when processing dollar-quoted string literals - in ecpg (Michael Meskes) - - - - - - In pg_dump, fix incorrect schema and owner marking for - comments and security labels of some types of database objects - (Giuseppe Broccolo, Tom Lane) - - - - In simple cases this caused no ill effects; but for example, a - schema-selective restore might omit comments it should include, because - they were not marked as belonging to the schema of their associated - object. - - - - - - Avoid emitting an invalid list file in pg_restore -l - when SQL object names contain newlines (Tom Lane) - - - - Replace newlines by spaces, which is sufficient to make the output - valid for pg_restore -L's purposes. - - - - - - Fix pg_upgrade to transfer comments and security labels - attached to large objects (blobs) (Stephen Frost) - - - - Previously, blobs were correctly transferred to the new database, but - any comments or security labels attached to them were lost. - - - - - - Improve error handling - in contrib/adminpack's pg_file_write() - function (Noah Misch) - - - - Notably, it failed to detect errors reported - by fclose(). - - - - - - In contrib/dblink, avoid leaking the previous unnamed - connection when establishing a new unnamed connection (Joe Conway) - - - - - - Fix contrib/pg_trgm's extraction of trigrams from regular - expressions (Tom Lane) - - - - In some cases it would produce a broken data structure that could never - match anything, leading to GIN or GiST indexscans that use a trigram - index not finding any matches to the regular expression. - - - - - - In contrib/postgres_fdw, - transmit query cancellation requests to the remote server - (Michael Paquier, Etsuro Fujita) - - - - Previously, a local query cancellation request did not cause an - already-sent remote query to terminate early. This is a back-patch - of work originally done for 9.6. - - - - - - Support OpenSSL 1.1.0 (Heikki Linnakangas, Andreas Karlsson, Tom Lane) - - - - This is a back-patch of work previously done in newer branches; - it's needed since many platforms are adopting newer OpenSSL versions. - - - - - - Support Tcl 8.6 in MSVC builds (Álvaro Herrera) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017b - (Tom Lane) - - - - This fixes a bug affecting some DST transitions in January 2038. - - - - - - Update time zone data files to tzdata release 2017b - for DST law changes in Chile, Haiti, and Mongolia, plus historical - corrections for Ecuador, Kazakhstan, Liberia, and Spain. - Switch to numeric abbreviations for numerous time zones in South - America, the Pacific and Indian oceans, and some Asian and Middle - Eastern countries. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - - - Use correct daylight-savings rules for POSIX-style time zone names - in MSVC builds (David Rowley) - - - - The Microsoft MSVC build scripts neglected to install - the posixrules file in the timezone directory tree. - This resulted in the timezone code falling back to its built-in - rule about what DST behavior to assume for a POSIX-style time zone - name. For historical reasons that still corresponds to the DST rules - the USA was using before 2007 (i.e., change on first Sunday in April - and last Sunday in October). With this fix, a POSIX-style zone name - will use the current and historical DST transition dates of - the US/Eastern zone. If you don't want that, remove - the posixrules file, or replace it with a copy of some - other zone file (see ). Note that - due to caching, you may need to restart the server to get such changes - to take effect. - - - - - - - - - - Release 9.3.16 - - - Release date: - 2017-02-09 - - - - This release contains a variety of fixes from 9.3.15. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.16 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted indexes. - - - - Also, if you are upgrading from a version earlier than 9.3.15, - see . - - - - - - Changes - - - - - - Fix a race condition that could cause indexes built - with CREATE INDEX CONCURRENTLY to be corrupt - (Pavan Deolasee, Tom Lane) - - - - If CREATE INDEX CONCURRENTLY was used to build an index - that depends on a column not previously indexed, then rows - updated by transactions that ran concurrently with - the CREATE INDEX command could have received incorrect - index entries. If you suspect this may have happened, the most - reliable solution is to rebuild affected indexes after installing - this update. - - - - - - Unconditionally WAL-log creation of the init fork for an - unlogged table (Michael Paquier) - - - - Previously, this was skipped when - = minimal, but actually it's necessary even in that case - to ensure that the unlogged table is properly reset to empty after a - crash. - - - - - - If the stats collector dies during hot standby, restart it (Takayuki - Tsunakawa) - - - - - - Ensure that hot standby feedback works correctly when it's enabled at - standby server start (Ants Aasma, Craig Ringer) - - - - - - Check for interrupts while hot standby is waiting for a conflicting - query (Simon Riggs) - - - - - - Avoid constantly respawning the autovacuum launcher in a corner case - (Amit Khandekar) - - - - This fix avoids problems when autovacuum is nominally off and there - are some tables that require freezing, but all such tables are - already being processed by autovacuum workers. - - - - - - Fix check for when an extension member object can be dropped (Tom Lane) - - - - Extension upgrade scripts should be able to drop member objects, - but this was disallowed for serial-column sequences, and possibly - other cases. - - - - - - Make sure ALTER TABLE preserves index tablespace - assignments when rebuilding indexes (Tom Lane, Michael Paquier) - - - - Previously, non-default settings - of could result in broken - indexes. - - - - - - Prevent dropping a foreign-key constraint if there are pending - trigger events for the referenced relation (Tom Lane) - - - - This avoids could not find trigger NNN - or relation NNN has no triggers errors. - - - - - - Fix processing of OID column when a table with OIDs is associated to - a parent with OIDs via ALTER TABLE ... INHERIT (Amit - Langote) - - - - The OID column should be treated the same as regular user columns in - this case, but it wasn't, leading to odd behavior in later - inheritance changes. - - - - - - Report correct object identity during ALTER TEXT SEARCH - CONFIGURATION (Artur Zakirov) - - - - The wrong catalog OID was reported to extensions such as logical - decoding. - - - - - - Check for serializability conflicts before reporting - constraint-violation failures (Thomas Munro) - - - - When using serializable transaction isolation, it is desirable - that any error due to concurrent transactions should manifest - as a serialization failure, thereby cueing the application that - a retry might succeed. Unfortunately, this does not reliably - happen for duplicate-key failures caused by concurrent insertions. - This change ensures that such an error will be reported as a - serialization error if the application explicitly checked for - the presence of a conflicting key (and did not find it) earlier - in the transaction. - - - - - - Prevent multicolumn expansion of foo.* in - an UPDATE source expression (Tom Lane) - - - - This led to UPDATE target count mismatch --- internal - error. Now the syntax is understood as a whole-row variable, - as it would be in other contexts. - - - - - - Ensure that column typmods are determined accurately for - multi-row VALUES constructs (Tom Lane) - - - - This fixes problems occurring when the first value in a column has a - determinable typmod (e.g., length for a varchar value) but - later values don't share the same limit. - - - - - - Throw error for an unfinished Unicode surrogate pair at the end of a - Unicode string (Tom Lane) - - - - Normally, a Unicode surrogate leading character must be followed by a - Unicode surrogate trailing character, but the check for this was - missed if the leading character was the last character in a Unicode - string literal (U&'...') or Unicode identifier - (U&"..."). - - - - - - Ensure that a purely negative text search query, such - as !foo, matches empty tsvectors (Tom Dunstan) - - - - Such matches were found by GIN index searches, but not by sequential - scans or GiST index searches. - - - - - - Prevent crash when ts_rewrite() replaces a non-top-level - subtree with an empty query (Artur Zakirov) - - - - - - Fix performance problems in ts_rewrite() (Tom Lane) - - - - - - Fix ts_rewrite()'s handling of nested NOT operators - (Tom Lane) - - - - - - Fix array_fill() to handle empty arrays properly (Tom Lane) - - - - - - Fix one-byte buffer overrun in quote_literal_cstr() - (Heikki Linnakangas) - - - - The overrun occurred only if the input consisted entirely of single - quotes and/or backslashes. - - - - - - Prevent multiple calls of pg_start_backup() - and pg_stop_backup() from running concurrently (Michael - Paquier) - - - - This avoids an assertion failure, and possibly worse things, if - someone tries to run these functions in parallel. - - - - - - Avoid discarding interval-to-interval casts - that aren't really no-ops (Tom Lane) - - - - In some cases, a cast that should result in zeroing out - low-order interval fields was mistakenly deemed to be a - no-op and discarded. An example is that casting from INTERVAL - MONTH to INTERVAL YEAR failed to clear the months field. - - - - - - Ensure that cached plans are invalidated by changes in foreign-table - options (Amit Langote, Etsuro Fujita, Ashutosh Bapat) - - - - - - Fix pg_dump to dump user-defined casts and transforms - that use built-in functions (Stephen Frost) - - - - - - Fix possible pg_basebackup failure on standby - server when including WAL files (Amit Kapila, Robert Haas) - - - - - - Ensure that the Python exception objects we create for PL/Python are - properly reference-counted (Rafa de la Torre, Tom Lane) - - - - This avoids failures if the objects are used after a Python garbage - collection cycle has occurred. - - - - - - Fix PL/Tcl to support triggers on tables that have .tupno - as a column name (Tom Lane) - - - - This matches the (previously undocumented) behavior of - PL/Tcl's spi_exec and spi_execp commands, - namely that a magic .tupno column is inserted only if - there isn't a real column named that. - - - - - - Allow DOS-style line endings in ~/.pgpass files, - even on Unix (Vik Fearing) - - - - This change simplifies use of the same password file across Unix and - Windows machines. - - - - - - Fix one-byte buffer overrun if ecpg is given a file - name that ends with a dot (Takayuki Tsunakawa) - - - - - - Fix psql's tab completion for ALTER DEFAULT - PRIVILEGES (Gilles Darold, Stephen Frost) - - - - - - In psql, treat an empty or all-blank setting of - the PAGER environment variable as meaning no - pager (Tom Lane) - - - - Previously, such a setting caused output intended for the pager to - vanish entirely. - - - - - - Improve contrib/dblink's reporting of - low-level libpq errors, such as out-of-memory - (Joe Conway) - - - - - - Teach contrib/dblink to ignore irrelevant server options - when it uses a contrib/postgres_fdw foreign server as - the source of connection options (Corey Huinker) - - - - Previously, if the foreign server object had options that were not - also libpq connection options, an error occurred. - - - - - - On Windows, ensure that environment variable changes are propagated - to DLLs built with debug options (Christian Ullrich) - - - - - - Sync our copy of the timezone library with IANA release tzcode2016j - (Tom Lane) - - - - This fixes various issues, most notably that timezone data - installation failed if the target directory didn't support hard - links. - - - - - - Update time zone data files to tzdata release 2016j - for DST law changes in northern Cyprus (adding a new zone - Asia/Famagusta), Russia (adding a new zone Europe/Saratov), Tonga, - and Antarctica/Casey. - Historical corrections for Italy, Kazakhstan, Malta, and Palestine. - Switch to preferring numeric zone abbreviations for Tonga. - - - - - - - - - - Release 9.3.15 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.3.14. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.15 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted free space maps. - - - - Also, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Fix WAL-logging of truncation of relation free space maps and - visibility maps (Pavan Deolasee, Heikki Linnakangas) - - - - It was possible for these files to not be correctly restored during - crash recovery, or to be written incorrectly on a standby server. - Bogus entries in a free space map could lead to attempts to access - pages that have been truncated away from the relation itself, typically - producing errors like could not read block XXX: - read only 0 of 8192 bytes. Checksum failures in the - visibility map are also possible, if checksumming is enabled. - - - - Procedures for determining whether there is a problem and repairing it - if so are discussed at - . - - - - - - Fix SELECT FOR UPDATE/SHARE to correctly lock tuples that - have been updated by a subsequently-aborted transaction - (Álvaro Herrera) - - - - In 9.5 and later, the SELECT would sometimes fail to - return such tuples at all. A failure has not been proven to occur in - earlier releases, but might be possible with concurrent updates. - - - - - - Fix EvalPlanQual rechecks involving CTE scans (Tom Lane) - - - - The recheck would always see the CTE as returning no rows, typically - leading to failure to update rows that were recently updated. - - - - - - Fix improper repetition of previous results from hashed aggregation in - a subquery (Andrew Gierth) - - - - The test to see if we can reuse a previously-computed hash table of - the aggregate state values neglected the possibility of an outer query - reference appearing in an aggregate argument expression. A change in - the value of such a reference should lead to recalculating the hash - table, but did not. - - - - - - Fix EXPLAIN to emit valid XML when - is on (Markus Winand) - - - - Previously the XML output-format option produced syntactically invalid - tags such as <I/O-Read-Time>. That is now - rendered as <I-O-Read-Time>. - - - - - - Suppress printing of zeroes for unmeasured times - in EXPLAIN (Maksim Milyutin) - - - - Certain option combinations resulted in printing zero values for times - that actually aren't ever measured in that combination. Our general - policy in EXPLAIN is not to print such fields at all, so - do that consistently in all cases. - - - - - - Fix timeout length when VACUUM is waiting for exclusive - table lock so that it can truncate the table (Simon Riggs) - - - - The timeout was meant to be 50 milliseconds, but it was actually only - 50 microseconds, causing VACUUM to give up on truncation - much more easily than intended. Set it to the intended value. - - - - - - Fix bugs in merging inherited CHECK constraints while - creating or altering a table (Tom Lane, Amit Langote) - - - - Allow identical CHECK constraints to be added to a parent - and child table in either order. Prevent merging of a valid - constraint from the parent table with a NOT VALID - constraint on the child. Likewise, prevent merging of a NO - INHERIT child constraint with an inherited constraint. - - - - - - Remove artificial restrictions on the values accepted - by numeric_in() and numeric_recv() - (Tom Lane) - - - - We allow numeric values up to the limit of the storage format (more - than 1e100000), so it seems fairly pointless - that numeric_in() rejected scientific-notation exponents - above 1000. Likewise, it was silly for numeric_recv() to - reject more than 1000 digits in an input value. - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - Fix file descriptor leakage when truncating a temporary relation of - more than 1GB (Andres Freund) - - - - - - Disallow starting a standalone backend with standby_mode - turned on (Michael Paquier) - - - - This can't do anything useful, since there will be no WAL receiver - process to fetch more WAL data; and it could result in misbehavior - in code that wasn't designed with this situation in mind. - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - Make ecpg's and - options work consistently with our other executables (Haribabu Kommi) - - - - - - In pg_dump, never dump range constructor functions - (Tom Lane) - - - - This oversight led to pg_upgrade failures with - extensions containing range types, due to duplicate creation of the - constructor functions. - - - - - - In pg_xlogdump, retry opening new WAL segments when - using option (Magnus Hagander) - - - - This allows for a possible delay in the server's creation of the next - segment. - - - - - - Fix pg_xlogdump to cope with a WAL file that begins - with a continuation record spanning more than one page (Pavan - Deolasee) - - - - - - Fix contrib/intarray/bench/bench.pl to print the results - of the EXPLAIN it does when given the option - (Daniel Gustafsson) - - - - - - Update Windows time zone mapping to recognize some time zone names - added in recent Windows versions (Michael Paquier) - - - - - - Prevent failure of obsolete dynamic time zone abbreviations (Tom Lane) - - - - If a dynamic time zone abbreviation does not match any entry in the - referenced time zone, treat it as equivalent to the time zone name. - This avoids unexpected failures when IANA removes abbreviations from - their time zone database, as they did in tzdata - release 2016f and seem likely to do again in the future. The - consequences were not limited to not recognizing the individual - abbreviation; any mismatch caused - the pg_timezone_abbrevs view to fail altogether. - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.3.14 - - - Release date: - 2016-08-11 - - - - This release contains a variety of fixes from 9.3.13. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.14 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Fix possible mis-evaluation of - nested CASE-WHEN expressions (Heikki - Linnakangas, Michael Paquier, Tom Lane) - - - - A CASE expression appearing within the test value - subexpression of another CASE could become confused about - whether its own test value was null or not. Also, inlining of a SQL - function implementing the equality operator used by - a CASE expression could result in passing the wrong test - value to functions called within a CASE expression in the - SQL function's body. If the test values were of different data - types, a crash might result; moreover such situations could be abused - to allow disclosure of portions of server memory. (CVE-2016-5423) - - - - - - Fix client programs' handling of special characters in database and - role names (Noah Misch, Nathan Bossart, Michael Paquier) - - - - Numerous places in vacuumdb and other client programs - could become confused by database and role names containing double - quotes or backslashes. Tighten up quoting rules to make that safe. - Also, ensure that when a conninfo string is used as a database name - parameter to these programs, it is correctly treated as such throughout. - - - - Fix handling of paired double quotes - in psql's \connect - and \password commands to match the documentation. - - - - Introduce a new option - in psql's \connect command to allow - explicit control of whether to re-use connection parameters from a - previous connection. (Without this, the choice is based on whether - the database name looks like a conninfo string, as before.) This - allows secure handling of database names containing special - characters in pg_dumpall scripts. - - - - pg_dumpall now refuses to deal with database and role - names containing carriage returns or newlines, as it seems impractical - to quote those characters safely on Windows. In future we may reject - such names on the server side, but that step has not been taken yet. - - - - These are considered security fixes because crafted object names - containing special characters could have been used to execute - commands with superuser privileges the next time a superuser - executes pg_dumpall or other routine maintenance - operations. (CVE-2016-5424) - - - - - - Fix corner-case misbehaviors for IS NULL/IS NOT - NULL applied to nested composite values (Andrew Gierth, Tom Lane) - - - - The SQL standard specifies that IS NULL should return - TRUE for a row of all null values (thus ROW(NULL,NULL) IS - NULL yields TRUE), but this is not meant to apply recursively - (thus ROW(NULL, ROW(NULL,NULL)) IS NULL yields FALSE). - The core executor got this right, but certain planner optimizations - treated the test as recursive (thus producing TRUE in both cases), - and contrib/postgres_fdw could produce remote queries - that misbehaved similarly. - - - - - - Make the inet and cidr data types properly reject - IPv6 addresses with too many colon-separated fields (Tom Lane) - - - - - - Prevent crash in close_ps() - (the point ## lseg operator) - for NaN input coordinates (Tom Lane) - - - - Make it return NULL instead of crashing. - - - - - - Avoid possible crash in pg_get_expr() when inconsistent - values are passed to it (Michael Paquier, Thomas Munro) - - - - - - Fix several one-byte buffer over-reads in to_number() - (Peter Eisentraut) - - - - In several cases the to_number() function would read one - more character than it should from the input string. There is a - small chance of a crash, if the input happens to be adjacent to the - end of memory. - - - - - - Do not run the planner on the query contained in CREATE - MATERIALIZED VIEW or CREATE TABLE AS - when WITH NO DATA is specified (Michael Paquier, - Tom Lane) - - - - This avoids some unnecessary failure conditions, for example if a - stable function invoked by the materialized view depends on a table - that doesn't exist yet. - - - - - - Avoid unsafe intermediate state during expensive paths - through heap_update() (Masahiko Sawada, Andres Freund) - - - - Previously, these cases locked the target tuple (by setting its XMAX) - but did not WAL-log that action, thus risking data integrity problems - if the page were spilled to disk and then a database crash occurred - before the tuple update could be completed. - - - - - - Fix hint bit update during WAL replay of row locking operations - (Andres Freund) - - - - The only known consequence of this problem is that row locks held by - a prepared, but uncommitted, transaction might fail to be enforced - after a crash and restart. - - - - - - Avoid unnecessary could not serialize access errors when - acquiring FOR KEY SHARE row locks in serializable mode - (Álvaro Herrera) - - - - - - Avoid crash in postgres -C when the specified variable - has a null string value (Michael Paquier) - - - - - - Ensure that backends see up-to-date statistics for shared catalogs - (Tom Lane) - - - - The statistics collector failed to update the statistics file for - shared catalogs after a request from a regular backend. This problem - was partially masked because the autovacuum launcher regularly makes - requests that did cause such updates; however, it became obvious with - autovacuum disabled. - - - - - - Avoid redundant writes of the statistics files when multiple - backends request updates close together (Tom Lane, Tomas Vondra) - - - - - - Avoid consuming a transaction ID during VACUUM - (Alexander Korotkov) - - - - Some cases in VACUUM unnecessarily caused an XID to be - assigned to the current transaction. Normally this is negligible, - but if one is up against the XID wraparound limit, consuming more - XIDs during anti-wraparound vacuums is a very bad thing. - - - - - - Avoid canceling hot-standby queries during VACUUM FREEZE - (Simon Riggs, Álvaro Herrera) - - - - VACUUM FREEZE on an otherwise-idle master server could - result in unnecessary cancellations of queries on its standby - servers. - - - - - - Prevent possible failure when vacuuming multixact IDs in an - installation that has been pg_upgrade'd from pre-9.3 (Andrew Gierth, - Álvaro Herrera) - - - - The usual symptom of this bug is errors - like MultiXactId NNN has not been created - yet -- apparent wraparound. - - - - - - When a manual ANALYZE specifies a column list, don't - reset the table's changes_since_analyze counter - (Tom Lane) - - - - If we're only analyzing some columns, we should not prevent routine - auto-analyze from happening for the other columns. - - - - - - Fix ANALYZE's overestimation of n_distinct - for a unique or nearly-unique column with many null entries (Tom - Lane) - - - - The nulls could get counted as though they were themselves distinct - values, leading to serious planner misestimates in some types of - queries. - - - - - - Prevent autovacuum from starting multiple workers for the same shared - catalog (Álvaro Herrera) - - - - Normally this isn't much of a problem because the vacuum doesn't take - long anyway; but in the case of a severely bloated catalog, it could - result in all but one worker uselessly waiting instead of doing - useful work on other tables. - - - - - - Prevent infinite loop in GiST index build for geometric columns - containing NaN component values (Tom Lane) - - - - - - Fix contrib/btree_gin to handle the smallest - possible bigint value correctly (Peter Eisentraut) - - - - - - Teach libpq to correctly decode server version from future servers - (Peter Eisentraut) - - - - It's planned to switch to two-part instead of three-part server - version numbers for releases after 9.6. Make sure - that PQserverVersion() returns the correct value for - such cases. - - - - - - Fix ecpg's code for unsigned long long - array elements (Michael Meskes) - - - - - - In pg_dump with both and - options, avoid emitting an unwanted CREATE SCHEMA public - command (David Johnston, Tom Lane) - - - - - - Improve handling of SIGTERM/control-C in - parallel pg_dump and pg_restore (Tom - Lane) - - - - Make sure that the worker processes will exit promptly, and also arrange - to send query-cancel requests to the connected backends, in case they - are doing something long-running such as a CREATE INDEX. - - - - - - Fix error reporting in parallel pg_dump - and pg_restore (Tom Lane) - - - - Previously, errors reported by pg_dump - or pg_restore worker processes might never make it to - the user's console, because the messages went through the master - process, and there were various deadlock scenarios that would prevent - the master process from passing on the messages. Instead, just print - everything to stderr. In some cases this will result in - duplicate messages (for instance, if all the workers report a server - shutdown), but that seems better than no message. - - - - - - Ensure that parallel pg_dump - or pg_restore on Windows will shut down properly - after an error (Kyotaro Horiguchi) - - - - Previously, it would report the error, but then just sit until - manually stopped by the user. - - - - - - Make pg_dump behave better when built without zlib - support (Kyotaro Horiguchi) - - - - It didn't work right for parallel dumps, and emitted some rather - pointless warnings in other cases. - - - - - - Make pg_basebackup accept -Z 0 as - specifying no compression (Fujii Masao) - - - - - - Fix makefiles' rule for building AIX shared libraries to be safe for - parallel make (Noah Misch) - - - - - - Fix TAP tests and MSVC scripts to work when build directory's path - name contains spaces (Michael Paquier, Kyotaro Horiguchi) - - - - - - Be more predictable about reporting statement timeout - versus lock timeout (Tom Lane) - - - - On heavily loaded machines, the regression tests sometimes failed due - to reporting lock timeout even though the statement timeout - should have occurred first. - - - - - - Make regression tests safe for Danish and Welsh locales (Jeff Janes, - Tom Lane) - - - - Change some test data that triggered the unusual sorting rules of - these locales. - - - - - - Update our copy of the timezone code to match - IANA's tzcode release 2016c (Tom Lane) - - - - This is needed to cope with anticipated future changes in the time - zone data files. It also fixes some corner-case bugs in coping with - unusual time zones. - - - - - - Update time zone data files to tzdata release 2016f - for DST law changes in Kemerovo and Novosibirsk, plus historical - corrections for Azerbaijan, Belarus, and Morocco. - - - - - - - - - - Release 9.3.13 - - - Release date: - 2016-05-12 - - - - This release contains a variety of fixes from 9.3.12. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.13 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Clear the OpenSSL error queue before OpenSSL calls, rather than - assuming it's clear already; and make sure we leave it clear - afterwards (Peter Geoghegan, Dave Vitek, Peter Eisentraut) - - - - This change prevents problems when there are multiple connections - using OpenSSL within a single process and not all the code involved - follows the same rules for when to clear the error queue. - Failures have been reported specifically when a client application - uses SSL connections in libpq concurrently with - SSL connections using the PHP, Python, or Ruby wrappers for OpenSSL. - It's possible for similar problems to arise within the server as well, - if an extension module establishes an outgoing SSL connection. - - - - - - Fix failed to build any N-way joins - planner error with a full join enclosed in the right-hand side of a - left join (Tom Lane) - - - - - - Fix incorrect handling of equivalence-class tests in multilevel - nestloop plans (Tom Lane) - - - - Given a three-or-more-way equivalence class of variables, such - as X.X = Y.Y = Z.Z, it was possible for the planner to omit - some of the tests needed to enforce that all the variables are actually - equal, leading to join rows being output that didn't satisfy - the WHERE clauses. For various reasons, erroneous plans - were seldom selected in practice, so that this bug has gone undetected - for a long time. - - - - - - Fix possible misbehavior of TH, th, - and Y,YYY format codes in to_timestamp() - (Tom Lane) - - - - These could advance off the end of the input string, causing subsequent - format codes to read garbage. - - - - - - Fix dumping of rules and views in which the array - argument of a value operator - ANY (array) construct is a sub-SELECT - (Tom Lane) - - - - - - Make pg_regress use a startup timeout from the - PGCTLTIMEOUT environment variable, if that's set (Tom Lane) - - - - This is for consistency with a behavior recently added - to pg_ctl; it eases automated testing on slow machines. - - - - - - Fix pg_upgrade to correctly restore extension - membership for operator families containing only one operator class - (Tom Lane) - - - - In such a case, the operator family was restored into the new database, - but it was no longer marked as part of the extension. This had no - immediate ill effects, but would cause later pg_dump - runs to emit output that would cause (harmless) errors on restore. - - - - - - Fix pg_upgrade to not fail when new-cluster TOAST rules - differ from old (Tom Lane) - - - - pg_upgrade had special-case code to handle the - situation where the new PostgreSQL version thinks that - a table should have a TOAST table while the old version did not. That - code was broken, so remove it, and instead do nothing in such cases; - there seems no reason to believe that we can't get along fine without - a TOAST table if that was okay according to the old version's rules. - - - - - - - Back-port 9.4-era memory-barrier code changes into 9.2 and 9.3 (Tom Lane) - - - - These changes were not originally needed in pre-9.4 branches, but we - recently back-patched a fix that expected the barrier code to work - properly. Only IA64 (when using icc), HPPA, and Alpha platforms are - affected. - - - - - - Reduce the number of SysV semaphores used by a build configured with - (Tom Lane) - - - - - - Rename internal function strtoi() - to strtoint() to avoid conflict with a NetBSD library - function (Thomas Munro) - - - - - - Fix reporting of errors from bind() - and listen() system calls on Windows (Tom Lane) - - - - - - Reduce verbosity of compiler output when building with Microsoft Visual - Studio (Christian Ullrich) - - - - - - Fix putenv() to work properly with Visual Studio 2013 - (Michael Paquier) - - - - - - Avoid possibly-unsafe use of Windows' FormatMessage() - function (Christian Ullrich) - - - - Use the FORMAT_MESSAGE_IGNORE_INSERTS flag where - appropriate. No live bug is known to exist here, but it seems like a - good idea to be careful. - - - - - - Update time zone data files to tzdata release 2016d - for DST law changes in Russia and Venezuela. There are new zone - names Europe/Kirov and Asia/Tomsk to reflect - the fact that these regions now have different time zone histories from - adjacent regions. - - - - - - - - - - Release 9.3.12 - - - Release date: - 2016-03-31 - - - - This release contains a variety of fixes from 9.3.11. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.12 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Fix incorrect handling of NULL index entries in - indexed ROW() comparisons (Tom Lane) - - - - An index search using a row comparison such as ROW(a, b) > - ROW('x', 'y') would stop upon reaching a NULL entry in - the b column, ignoring the fact that there might be - non-NULL b values associated with later values - of a. - - - - - - Avoid unlikely data-loss scenarios due to renaming files without - adequate fsync() calls before and after (Michael Paquier, - Tomas Vondra, Andres Freund) - - - - - - Correctly handle cases where pg_subtrans is close to XID - wraparound during server startup (Jeff Janes) - - - - - - Fix corner-case crash due to trying to free localeconv() - output strings more than once (Tom Lane) - - - - - - Fix parsing of affix files for ispell dictionaries - (Tom Lane) - - - - The code could go wrong if the affix file contained any characters - whose byte length changes during case-folding, for - example I in Turkish UTF8 locales. - - - - - - Avoid use of sscanf() to parse ispell - dictionary files (Artur Zakirov) - - - - This dodges a portability problem on FreeBSD-derived platforms - (including macOS). - - - - - - Avoid a crash on old Windows versions (before 7SP1/2008R2SP1) with an - AVX2-capable CPU and a Postgres build done with Visual Studio 2013 - (Christian Ullrich) - - - - This is a workaround for a bug in Visual Studio 2013's runtime - library, which Microsoft have stated they will not fix in that - version. - - - - - - Fix psql's tab completion logic to handle multibyte - characters properly (Kyotaro Horiguchi, Robert Haas) - - - - - - Fix psql's tab completion for - SECURITY LABEL (Tom Lane) - - - - Pressing TAB after SECURITY LABEL might cause a crash - or offering of inappropriate keywords. - - - - - - Make pg_ctl accept a wait timeout from the - PGCTLTIMEOUT environment variable, if none is specified on - the command line (Noah Misch) - - - - This eases testing of slower buildfarm members by allowing them - to globally specify a longer-than-normal timeout for postmaster - startup and shutdown. - - - - - - Fix incorrect test for Windows service status - in pg_ctl (Manuel Mathar) - - - - The previous set of minor releases attempted to - fix pg_ctl to properly determine whether to send log - messages to Window's Event Log, but got the test backwards. - - - - - - Fix pgbench to correctly handle the combination - of -C and -M prepared options (Tom Lane) - - - - - - In pg_upgrade, skip creating a deletion script when - the new data directory is inside the old data directory (Bruce - Momjian) - - - - Blind application of the script in such cases would result in loss of - the new data directory. - - - - - - In PL/Perl, properly translate empty Postgres arrays into empty Perl - arrays (Alex Hunsaker) - - - - - - Make PL/Python cope with function names that aren't valid Python - identifiers (Jim Nasby) - - - - - - Fix multiple mistakes in the statistics returned - by contrib/pgstattuple's pgstatindex() - function (Tom Lane) - - - - - - Remove dependency on psed in MSVC builds, since it's no - longer provided by core Perl (Michael Paquier, Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2016c - for DST law changes in Azerbaijan, Chile, Haiti, Palestine, and Russia - (Altai, Astrakhan, Kirov, Sakhalin, Ulyanovsk regions), plus - historical corrections for Lithuania, Moldova, and Russia - (Kaliningrad, Samara, Volgograd). - - - - - - - - - - Release 9.3.11 - - - Release date: - 2016-02-11 - - - - This release contains a variety of fixes from 9.3.10. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.11 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Fix infinite loops and buffer-overrun problems in regular expressions - (Tom Lane) - - - - Very large character ranges in bracket expressions could cause - infinite loops in some cases, and memory overwrites in other cases. - (CVE-2016-0773) - - - - - - Perform an immediate shutdown if the postmaster.pid file - is removed (Tom Lane) - - - - The postmaster now checks every minute or so - that postmaster.pid is still there and still contains its - own PID. If not, it performs an immediate shutdown, as though it had - received SIGQUIT. The main motivation for this change - is to ensure that failed buildfarm runs will get cleaned up without - manual intervention; but it also serves to limit the bad effects if a - DBA forcibly removes postmaster.pid and then starts a new - postmaster. - - - - - - In SERIALIZABLE transaction isolation mode, serialization - anomalies could be missed due to race conditions during insertions - (Kevin Grittner, Thomas Munro) - - - - - - Fix failure to emit appropriate WAL records when doing ALTER - TABLE ... SET TABLESPACE for unlogged relations (Michael Paquier, - Andres Freund) - - - - Even though the relation's data is unlogged, the move must be logged or - the relation will be inaccessible after a standby is promoted to master. - - - - - - Fix possible misinitialization of unlogged relations at the end of - crash recovery (Andres Freund, Michael Paquier) - - - - - - Ensure walsender slots are fully re-initialized when being re-used - (Magnus Hagander) - - - - - - Fix ALTER COLUMN TYPE to reconstruct inherited check - constraints properly (Tom Lane) - - - - - - Fix REASSIGN OWNED to change ownership of composite types - properly (Álvaro Herrera) - - - - - - Fix REASSIGN OWNED and ALTER OWNER to correctly - update granted-permissions lists when changing owners of data types, - foreign data wrappers, or foreign servers (Bruce Momjian, - Álvaro Herrera) - - - - - - Fix REASSIGN OWNED to ignore foreign user mappings, - rather than fail (Álvaro Herrera) - - - - - - Fix possible crash after doing query rewrite for an updatable view - (Stephen Frost) - - - - - - Fix planner's handling of LATERAL references (Tom - Lane) - - - - This fixes some corner cases that led to failed to build any - N-way joins or could not devise a query plan planner - failures. - - - - - - Add more defenses against bad planner cost estimates for GIN index - scans when the index's internal statistics are very out-of-date - (Tom Lane) - - - - - - Make planner cope with hypothetical GIN indexes suggested by an index - advisor plug-in (Julien Rouhaud) - - - - - - Speed up generation of unique table aliases in EXPLAIN and - rule dumping, and ensure that generated aliases do not - exceed NAMEDATALEN (Tom Lane) - - - - - - Fix dumping of whole-row Vars in ROW() - and VALUES() lists (Tom Lane) - - - - - - Fix possible internal overflow in numeric division - (Dean Rasheed) - - - - - - Fix enforcement of restrictions inside parentheses within regular - expression lookahead constraints (Tom Lane) - - - - Lookahead constraints aren't allowed to contain backrefs, and - parentheses within them are always considered non-capturing, according - to the manual. However, the code failed to handle these cases properly - inside a parenthesized subexpression, and would give unexpected - results. - - - - - - Conversion of regular expressions to indexscan bounds could produce - incorrect bounds from regexps containing lookahead constraints - (Tom Lane) - - - - - - Fix regular-expression compiler to handle loops of constraint arcs - (Tom Lane) - - - - The code added for CVE-2007-4772 was both incomplete, in that it didn't - handle loops involving more than one state, and incorrect, in that it - could cause assertion failures (though there seem to be no bad - consequences of that in a non-assert build). Multi-state loops would - cause the compiler to run until the query was canceled or it reached - the too-many-states error condition. - - - - - - Improve memory-usage accounting in regular-expression compiler - (Tom Lane) - - - - This causes the code to emit regular expression is too - complex errors in some cases that previously used unreasonable - amounts of time and memory. - - - - - - Improve performance of regular-expression compiler (Tom Lane) - - - - - - Make %h and %r escapes - in log_line_prefix work for messages emitted due - to log_connections (Tom Lane) - - - - Previously, %h/%r started to work just after a - new session had emitted the connection received log message; - now they work for that message too. - - - - - - On Windows, ensure the shared-memory mapping handle gets closed in - child processes that don't need it (Tom Lane, Amit Kapila) - - - - This oversight resulted in failure to recover from crashes - whenever logging_collector is turned on. - - - - - - Fix possible failure to detect socket EOF in non-blocking mode on - Windows (Tom Lane) - - - - It's not entirely clear whether this problem can happen in pre-9.5 - branches, but if it did, the symptom would be that a walsender process - would wait indefinitely rather than noticing a loss of connection. - - - - - - Avoid leaking a token handle during SSPI authentication - (Christian Ullrich) - - - - - - In psql, ensure that libreadline's idea - of the screen size is updated when the terminal window size changes - (Merlin Moncure) - - - - Previously, libreadline did not notice if the window - was resized during query output, leading to strange behavior during - later input of multiline queries. - - - - - - Fix psql's \det command to interpret its - pattern argument the same way as other \d commands with - potentially schema-qualified patterns do (Reece Hart) - - - - - - Avoid possible crash in psql's \c command - when previous connection was via Unix socket and command specifies a - new hostname and same username (Tom Lane) - - - - - - In pg_ctl start -w, test child process status directly - rather than relying on heuristics (Tom Lane, Michael Paquier) - - - - Previously, pg_ctl relied on an assumption that the new - postmaster would always create postmaster.pid within five - seconds. But that can fail on heavily-loaded systems, - causing pg_ctl to report incorrectly that the - postmaster failed to start. - - - - Except on Windows, this change also means that a pg_ctl start - -w done immediately after another such command will now reliably - fail, whereas previously it would report success if done within two - seconds of the first command. - - - - - - In pg_ctl start -w, don't attempt to use a wildcard listen - address to connect to the postmaster (Kondo Yuta) - - - - On Windows, pg_ctl would fail to detect postmaster - startup if listen_addresses is set to 0.0.0.0 - or ::, because it would try to use that value verbatim as - the address to connect to, which doesn't work. Instead assume - that 127.0.0.1 or ::1, respectively, is the - right thing to use. - - - - - - In pg_ctl on Windows, check service status to decide - where to send output, rather than checking if standard output is a - terminal (Michael Paquier) - - - - - - In pg_dump and pg_basebackup, adopt - the GNU convention for handling tar-archive members exceeding 8GB - (Tom Lane) - - - - The POSIX standard for tar file format does not allow - archive member files to exceed 8GB, but most modern implementations - of tar support an extension that fixes that. Adopt - this extension so that pg_dump with no - longer fails on tables with more than 8GB of data, and so - that pg_basebackup can handle files larger than 8GB. - In addition, fix some portability issues that could cause failures for - members between 4GB and 8GB on some platforms. Potentially these - problems could cause unrecoverable data loss due to unreadable backup - files. - - - - - - Fix assorted corner-case bugs in pg_dump's processing - of extension member objects (Tom Lane) - - - - - - Make pg_dump mark a view's triggers as needing to be - processed after its rule, to prevent possible failure during - parallel pg_restore (Tom Lane) - - - - - - Ensure that relation option values are properly quoted - in pg_dump (Kouhei Sutou, Tom Lane) - - - - A reloption value that isn't a simple identifier or number could lead - to dump/reload failures due to syntax errors in CREATE statements - issued by pg_dump. This is not an issue with any - reloption currently supported by core PostgreSQL, but - extensions could allow reloptions that cause the problem. - - - - - - Avoid repeated password prompts during parallel pg_dump - (Zeus Kronion) - - - - - - Fix pg_upgrade's file-copying code to handle errors - properly on Windows (Bruce Momjian) - - - - - - Install guards in pgbench against corner-case overflow - conditions during evaluation of script-specified division or modulo - operators (Fabien Coelho, Michael Paquier) - - - - - - Fix failure to localize messages emitted - by pg_receivexlog and pg_recvlogical - (Ioseph Kim) - - - - - - Avoid dump/reload problems when using both plpython2 - and plpython3 (Tom Lane) - - - - In principle, both versions of PL/Python can be used in - the same database, though not in the same session (because the two - versions of libpython cannot safely be used concurrently). - However, pg_restore and pg_upgrade both - do things that can fall foul of the same-session restriction. Work - around that by changing the timing of the check. - - - - - - Fix PL/Python regression tests to pass with Python 3.5 - (Peter Eisentraut) - - - - - - Fix premature clearing of libpq's input buffer when - socket EOF is seen (Tom Lane) - - - - This mistake caused libpq to sometimes not report the - backend's final error message before reporting server closed the - connection unexpectedly. - - - - - - Prevent certain PL/Java parameters from being set by - non-superusers (Noah Misch) - - - - This change mitigates a PL/Java security bug - (CVE-2016-0766), which was fixed in PL/Java by marking - these parameters as superuser-only. To fix the security hazard for - sites that update PostgreSQL more frequently - than PL/Java, make the core code aware of them also. - - - - - - Improve libpq's handling of out-of-memory situations - (Michael Paquier, Amit Kapila, Heikki Linnakangas) - - - - - - Fix order of arguments - in ecpg-generated typedef statements - (Michael Meskes) - - - - - - Use %g not %f format - in ecpg's PGTYPESnumeric_from_double() - (Tom Lane) - - - - - - Fix ecpg-supplied header files to not contain comments - continued from a preprocessor directive line onto the next line - (Michael Meskes) - - - - Such a comment is rejected by ecpg. It's not yet clear - whether ecpg itself should be changed. - - - - - - Fix hstore_to_json_loose()'s test for whether - an hstore value can be converted to a JSON number (Tom Lane) - - - - Previously this function could be fooled by non-alphanumeric trailing - characters, leading to emitting syntactically-invalid JSON. - - - - - - Ensure that contrib/pgcrypto's crypt() - function can be interrupted by query cancel (Andreas Karlsson) - - - - - - Accept flex versions later than 2.5.x - (Tom Lane, Michael Paquier) - - - - Now that flex 2.6.0 has been released, the version checks in our build - scripts needed to be adjusted. - - - - - - Improve reproducibility of build output by ensuring filenames are given - to the linker in a fixed order (Christoph Berg) - - - - This avoids possible bitwise differences in the produced executable - files from one build to the next. - - - - - - Install our missing script where PGXS builds can find it - (Jim Nasby) - - - - This allows sane behavior in a PGXS build done on a machine where build - tools such as bison are missing. - - - - - - Ensure that dynloader.h is included in the installed - header files in MSVC builds (Bruce Momjian, Michael Paquier) - - - - - - Add variant regression test expected-output file to match behavior of - current libxml2 (Tom Lane) - - - - The fix for libxml2's CVE-2015-7499 causes it not to - output error context reports in some cases where it used to do so. - This seems to be a bug, but we'll probably have to live with it for - some time, so work around it. - - - - - - Update time zone data files to tzdata release 2016a for - DST law changes in Cayman Islands, Metlakatla, and Trans-Baikal - Territory (Zabaykalsky Krai), plus historical corrections for Pakistan. - - - - - - - - - - Release 9.3.10 - - - Release date: - 2015-10-08 - - - - This release contains a variety of fixes from 9.3.9. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.10 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.9, - see . - - - - - - Changes - - - - - - Guard against stack overflows in json parsing - (Oskari Saarenmaa) - - - - If an application constructs PostgreSQL json - or jsonb values from arbitrary user input, the application's - users can reliably crash the PostgreSQL server, causing momentary - denial of service. (CVE-2015-5289) - - - - - - Fix contrib/pgcrypto to detect and report - too-short crypt() salts (Josh Kupershmidt) - - - - Certain invalid salt arguments crashed the server or disclosed a few - bytes of server memory. We have not ruled out the viability of - attacks that arrange for presence of confidential information in the - disclosed bytes, but they seem unlikely. (CVE-2015-5288) - - - - - - Fix subtransaction cleanup after a portal (cursor) belonging to an - outer subtransaction fails (Tom Lane, Michael Paquier) - - - - A function executed in an outer-subtransaction cursor could cause an - assertion failure or crash by referencing a relation created within an - inner subtransaction. - - - - - - Ensure all relations referred to by an updatable view are properly - locked during an update statement (Dean Rasheed) - - - - - - Fix insertion of relations into the relation cache init file - (Tom Lane) - - - - An oversight in a patch in the most recent minor releases - caused pg_trigger_tgrelid_tgname_index to be omitted - from the init file. Subsequent sessions detected this, then deemed the - init file to be broken and silently ignored it, resulting in a - significant degradation in session startup time. In addition to fixing - the bug, install some guards so that any similar future mistake will be - more obvious. - - - - - - Avoid O(N^2) behavior when inserting many tuples into a SPI query - result (Neil Conway) - - - - - - Improve LISTEN startup time when there are many unread - notifications (Matt Newell) - - - - - - Fix performance problem when a session alters large numbers of foreign - key constraints (Jan Wieck, Tom Lane) - - - - This was seen primarily when restoring pg_dump output - for databases with many thousands of tables. - - - - - - Disable SSL renegotiation by default (Michael Paquier, Andres Freund) - - - - While use of SSL renegotiation is a good idea in theory, we have seen - too many bugs in practice, both in the underlying OpenSSL library and - in our usage of it. Renegotiation will be removed entirely in 9.5 and - later. In the older branches, just change the default value - of ssl_renegotiation_limit to zero (disabled). - - - - - - Lower the minimum values of the *_freeze_max_age parameters - (Andres Freund) - - - - This is mainly to make tests of related behavior less time-consuming, - but it may also be of value for installations with limited disk space. - - - - - - Limit the maximum value of wal_buffers to 2GB to avoid - server crashes (Josh Berkus) - - - - - - Avoid logging complaints when a parameter that can only be set at - server start appears multiple times in postgresql.conf, - and fix counting of line numbers after an include_dir - directive (Tom Lane) - - - - - - Fix rare internal overflow in multiplication of numeric values - (Dean Rasheed) - - - - - - Guard against hard-to-reach stack overflows involving record types, - range types, json, jsonb, tsquery, - ltxtquery and query_int (Noah Misch) - - - - - - Fix handling of DOW and DOY in datetime input - (Greg Stark) - - - - These tokens aren't meant to be used in datetime values, but previously - they resulted in opaque internal error messages rather - than invalid input syntax. - - - - - - Add more query-cancel checks to regular expression matching (Tom Lane) - - - - - - Add recursion depth protections to regular expression, SIMILAR - TO, and LIKE matching (Tom Lane) - - - - Suitable search patterns and a low stack depth limit could lead to - stack-overrun crashes. - - - - - - Fix potential infinite loop in regular expression execution (Tom Lane) - - - - A search pattern that can apparently match a zero-length string, but - actually doesn't match because of a back reference, could lead to an - infinite loop. - - - - - - In regular expression execution, correctly record match data for - capturing parentheses within a quantifier even when the match is - zero-length (Tom Lane) - - - - - - Fix low-memory failures in regular expression compilation - (Andreas Seltenreich) - - - - - - Fix low-probability memory leak during regular expression execution - (Tom Lane) - - - - - - Fix rare low-memory failure in lock cleanup during transaction abort - (Tom Lane) - - - - - - Fix unexpected out-of-memory situation during sort errors - when using tuplestores with small work_mem settings (Tom - Lane) - - - - - - Fix very-low-probability stack overrun in qsort (Tom Lane) - - - - - - Fix invalid memory alloc request size failure in hash joins - with large work_mem settings (Tomas Vondra, Tom Lane) - - - - - - Fix assorted planner bugs (Tom Lane) - - - - These mistakes could lead to incorrect query plans that would give wrong - answers, or to assertion failures in assert-enabled builds, or to odd - planner errors such as could not devise a query plan for the - given query, could not find pathkey item to - sort, plan should not reference subplan's variable, - or failed to assign all NestLoopParams to plan nodes. - Thanks are due to Andreas Seltenreich and Piotr Stefaniak for fuzz - testing that exposed these problems. - - - - - - Improve planner's performance for UPDATE/DELETE - on large inheritance sets (Tom Lane, Dean Rasheed) - - - - - - Ensure standby promotion trigger files are removed at postmaster - startup (Michael Paquier, Fujii Masao) - - - - This prevents unwanted promotion from occurring if these files appear - in a database backup that is used to initialize a new standby server. - - - - - - During postmaster shutdown, ensure that per-socket lock files are - removed and listen sockets are closed before we remove - the postmaster.pid file (Tom Lane) - - - - This avoids race-condition failures if an external script attempts to - start a new postmaster as soon as pg_ctl stop returns. - - - - - - Fix postmaster's handling of a startup-process crash during crash - recovery (Tom Lane) - - - - If, during a crash recovery cycle, the startup process crashes without - having restored database consistency, we'd try to launch a new startup - process, which typically would just crash again, leading to an infinite - loop. - - - - - - Make emergency autovacuuming for multixact wraparound more robust - (Andres Freund) - - - - - - Do not print a WARNING when an autovacuum worker is already - gone when we attempt to signal it, and reduce log verbosity for such - signals (Tom Lane) - - - - - - Prevent autovacuum launcher from sleeping unduly long if the server - clock is moved backwards a large amount (Álvaro Herrera) - - - - - - Ensure that cleanup of a GIN index's pending-insertions list is - interruptable by cancel requests (Jeff Janes) - - - - - - Allow all-zeroes pages in GIN indexes to be reused (Heikki Linnakangas) - - - - Such a page might be left behind after a crash. - - - - - - Fix handling of all-zeroes pages in SP-GiST indexes (Heikki - Linnakangas) - - - - VACUUM attempted to recycle such pages, but did so in a - way that wasn't crash-safe. - - - - - - Fix off-by-one error that led to otherwise-harmless warnings - about apparent wraparound in subtrans/multixact truncation - (Thomas Munro) - - - - - - Fix misreporting of CONTINUE and MOVE statement - types in PL/pgSQL's error context messages - (Pavel Stehule, Tom Lane) - - - - - - Fix PL/Perl to handle non-ASCII error - message texts correctly (Alex Hunsaker) - - - - - - Fix PL/Python crash when returning the string - representation of a record result (Tom Lane) - - - - - - Fix some places in PL/Tcl that neglected to check for - failure of malloc() calls (Michael Paquier, Álvaro - Herrera) - - - - - - In contrib/isn, fix output of ISBN-13 numbers that begin - with 979 (Fabien Coelho) - - - - EANs beginning with 979 (but not 9790) are considered ISBNs, but they - must be printed in the new 13-digit format, not the 10-digit format. - - - - - - Improve contrib/postgres_fdw's handling of - collation-related decisions (Tom Lane) - - - - The main user-visible effect is expected to be that comparisons - involving varchar columns will be sent to the remote server - for execution in more cases than before. - - - - - - Improve libpq's handling of out-of-memory conditions - (Michael Paquier, Heikki Linnakangas) - - - - - - Fix memory leaks and missing out-of-memory checks - in ecpg (Michael Paquier) - - - - - - Fix psql's code for locale-aware formatting of numeric - output (Tom Lane) - - - - The formatting code invoked by \pset numericlocale on - did the wrong thing for some uncommon cases such as numbers with an - exponent but no decimal point. It could also mangle already-localized - output from the money data type. - - - - - - Prevent crash in psql's \c command when - there is no current connection (Noah Misch) - - - - - - Make pg_dump handle inherited NOT VALID - check constraints correctly (Tom Lane) - - - - - - Fix selection of default zlib compression level - in pg_dump's directory output format (Andrew Dunstan) - - - - - - Ensure that temporary files created during a pg_dump - run with tar-format output are not world-readable (Michael - Paquier) - - - - - - Fix pg_dump and pg_upgrade to support - cases where the postgres or template1 database - is in a non-default tablespace (Marti Raudsepp, Bruce Momjian) - - - - - - Fix pg_dump to handle object privileges sanely when - dumping from a server too old to have a particular privilege type - (Tom Lane) - - - - When dumping data types from pre-9.2 servers, and when dumping - functions or procedural languages from pre-7.3 - servers, pg_dump would - produce GRANT/REVOKE commands that revoked the - owner's grantable privileges and instead granted all privileges - to PUBLIC. Since the privileges involved are - just USAGE and EXECUTE, this isn't a security - problem, but it's certainly a surprising representation of the older - systems' behavior. Fix it to leave the default privilege state alone - in these cases. - - - - - - Fix pg_dump to dump shell types (Tom Lane) - - - - Shell types (that is, not-yet-fully-defined types) aren't useful for - much, but nonetheless pg_dump should dump them. - - - - - - Fix assorted minor memory leaks in pg_dump and other - client-side programs (Michael Paquier) - - - - - - Fix spinlock assembly code for PPC hardware to be compatible - with AIX's native assembler (Tom Lane) - - - - Building with gcc didn't work if gcc - had been configured to use the native assembler, which is becoming more - common. - - - - - - On AIX, test the -qlonglong compiler option - rather than just assuming it's safe to use (Noah Misch) - - - - - - On AIX, use -Wl,-brtllib link option to allow - symbols to be resolved at runtime (Noah Misch) - - - - Perl relies on this ability in 5.8.0 and later. - - - - - - Avoid use of inline functions when compiling with - 32-bit xlc, due to compiler bugs (Noah Misch) - - - - - - Use librt for sched_yield() when necessary, - which it is on some Solaris versions (Oskari Saarenmaa) - - - - - - Fix Windows install.bat script to handle target directory - names that contain spaces (Heikki Linnakangas) - - - - - - Make the numeric form of the PostgreSQL version number - (e.g., 90405) readily available to extension Makefiles, - as a variable named VERSION_NUM (Michael Paquier) - - - - - - Update time zone data files to tzdata release 2015g for - DST law changes in Cayman Islands, Fiji, Moldova, Morocco, Norfolk - Island, North Korea, Turkey, and Uruguay. There is a new zone name - America/Fort_Nelson for the Canadian Northern Rockies. - - - - - - - - - - Release 9.3.9 - - - Release date: - 2015-06-12 - - - - This release contains a small number of fixes from 9.3.8. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.9 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading an installation that was previously - upgraded using a pg_upgrade version between 9.3.0 and - 9.3.4 inclusive, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.3.7, - see . - - - - - - Changes - - - - - - Fix possible failure to recover from an inconsistent database state - (Robert Haas) - - - - Recent PostgreSQL releases introduced mechanisms to - protect against multixact wraparound, but some of that code did not - account for the possibility that it would need to run during crash - recovery, when the database may not be in a consistent state. This - could result in failure to restart after a crash, or failure to start - up a secondary server. The lingering effects of a previously-fixed - bug in pg_upgrade could also cause such a failure, in - installations that had used pg_upgrade versions - between 9.3.0 and 9.3.4. - - - - The pg_upgrade bug in question was that it would - set oldestMultiXid to 1 in pg_control even - if the true value should be higher. With the fixes introduced in - this release, such a situation will result in immediate emergency - autovacuuming until a correct oldestMultiXid value can be - determined. If that would pose a hardship, users can avoid it by - doing manual vacuuming before upgrading to this release. - In detail: - - - - - Check whether pg_controldata reports Latest - checkpoint's oldestMultiXid to be 1. If not, there's nothing - to do. - - - - - Look in PGDATA/pg_multixact/offsets to see if there's a - file named 0000. If there is, there's nothing to do. - - - - - Otherwise, for each table that has - pg_class.relminmxid equal to 1, - VACUUM that table with - both - and set to - zero. (You can use the vacuum cost delay parameters described - in to reduce - the performance consequences for concurrent sessions.) You must - use PostgreSQL 9.3.5 or later to perform this step. - - - - - - - - - Fix rare failure to invalidate relation cache init file (Tom Lane) - - - - With just the wrong timing of concurrent activity, a VACUUM - FULL on a system catalog might fail to update the init file - that's used to avoid cache-loading work for new sessions. This would - result in later sessions being unable to access that catalog at all. - This is a very ancient bug, but it's so hard to trigger that no - reproducible case had been seen until recently. - - - - - - Avoid deadlock between incoming sessions and CREATE/DROP - DATABASE (Tom Lane) - - - - A new session starting in a database that is the target of - a DROP DATABASE command, or is the template for - a CREATE DATABASE command, could cause the command to wait - for five seconds and then fail, even if the new session would have - exited before that. - - - - - - Improve planner's cost estimates for semi-joins and anti-joins with - inner indexscans (Tom Lane, Tomas Vondra) - - - - This type of plan is quite cheap when all the join clauses are used - as index scan conditions, even if the inner scan would nominally - fetch many rows, because the executor will stop after obtaining one - row. The planner only partially accounted for that effect, and would - therefore overestimate the cost, leading it to possibly choose some - other much less efficient plan type. - - - - - - - - - - Release 9.3.8 - - - Release date: - 2015-06-04 - - - - This release contains a small number of fixes from 9.3.7. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.8 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are upgrading from a version earlier than 9.3.7, - see . - - - - - - Changes - - - - - - Avoid failures while fsync'ing data directory during - crash restart (Abhijit Menon-Sen, Tom Lane) - - - - In the previous minor releases we added a patch to fsync - everything in the data directory after a crash. Unfortunately its - response to any error condition was to fail, thereby preventing the - server from starting up, even when the problem was quite harmless. - An example is that an unwritable file in the data directory would - prevent restart on some platforms; but it is common to make SSL - certificate files unwritable by the server. Revise this behavior so - that permissions failures are ignored altogether, and other types of - failures are logged but do not prevent continuing. - - - - Also apply the same rules in initdb --sync-only. - This case is less critical but it should act similarly. - - - - - - Fix pg_get_functiondef() to show - functions' LEAKPROOF property, if set (Jeevan Chalke) - - - - - - Remove configure's check prohibiting linking to a - threaded libpython - on OpenBSD (Tom Lane) - - - - The failure this restriction was meant to prevent seems to not be a - problem anymore on current OpenBSD - versions. - - - - - - - - Allow libpq to use TLS protocol versions beyond v1 - (Noah Misch) - - - - For a long time, libpq was coded so that the only SSL - protocol it would allow was TLS v1. Now that newer TLS versions are - becoming popular, allow it to negotiate the highest commonly-supported - TLS version with the server. (PostgreSQL servers were - already capable of such negotiation, so no change is needed on the - server side.) This is a back-patch of a change already released in - 9.4.0. - - - - - - - - - - Release 9.3.7 - - - Release date: - 2015-05-22 - - - - This release contains a variety of fixes from 9.3.6. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.7 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you use contrib/citext's - regexp_matches() functions, see the changelog entry below - about that. - - - - Also, if you are upgrading from a version earlier than 9.3.6, - see . - - - - - - Changes - - - - - - Avoid possible crash when client disconnects just before the - authentication timeout expires (Benkocs Norbert Attila) - - - - If the timeout interrupt fired partway through the session shutdown - sequence, SSL-related state would be freed twice, typically causing a - crash and hence denial of service to other sessions. Experimentation - shows that an unauthenticated remote attacker could trigger the bug - somewhat consistently, hence treat as security issue. - (CVE-2015-3165) - - - - - - Improve detection of system-call failures (Noah Misch) - - - - Our replacement implementation of snprintf() failed to - check for errors reported by the underlying system library calls; - the main case that might be missed is out-of-memory situations. - In the worst case this might lead to information exposure, due to our - code assuming that a buffer had been overwritten when it hadn't been. - Also, there were a few places in which security-relevant calls of other - system library functions did not check for failure. - - - - It remains possible that some calls of the *printf() - family of functions are vulnerable to information disclosure if an - out-of-memory error occurs at just the wrong time. We judge the risk - to not be large, but will continue analysis in this area. - (CVE-2015-3166) - - - - - - In contrib/pgcrypto, uniformly report decryption failures - as Wrong key or corrupt data (Noah Misch) - - - - Previously, some cases of decryption with an incorrect key could report - other error message texts. It has been shown that such variance in - error reports can aid attackers in recovering keys from other systems. - While it's unknown whether pgcrypto's specific behaviors - are likewise exploitable, it seems better to avoid the risk by using a - one-size-fits-all message. - (CVE-2015-3167) - - - - - - Protect against wraparound of multixact member IDs - (Álvaro Herrera, Robert Haas, Thomas Munro) - - - - Under certain usage patterns, the existing defenses against this might - be insufficient, allowing pg_multixact/members files to be - removed too early, resulting in data loss. - The fix for this includes modifying the server to fail transactions - that would result in overwriting old multixact member ID data, and - improving autovacuum to ensure it will act proactively to prevent - multixact member ID wraparound, as it does for transaction ID - wraparound. - - - - - - Fix incorrect declaration of contrib/citext's - regexp_matches() functions (Tom Lane) - - - - These functions should return setof text[], like the core - functions they are wrappers for; but they were incorrectly declared as - returning just text[]. This mistake had two results: first, - if there was no match you got a scalar null result, whereas what you - should get is an empty set (zero rows). Second, the g flag - was effectively ignored, since you would get only one result array even - if there were multiple matches. - - - - While the latter behavior is clearly a bug, there might be applications - depending on the former behavior; therefore the function declarations - will not be changed by default until PostgreSQL 9.5. - In pre-9.5 branches, the old behavior exists in version 1.0 of - the citext extension, while we have provided corrected - declarations in version 1.1 (which is not installed by - default). To adopt the fix in pre-9.5 branches, execute - ALTER EXTENSION citext UPDATE TO '1.1' in each database in - which citext is installed. (You can also update - back to 1.0 if you need to undo that.) Be aware that either update - direction will require dropping and recreating any views or rules that - use citext's regexp_matches() functions. - - - - - - Fix incorrect checking of deferred exclusion constraints after a HOT - update (Tom Lane) - - - - If a new row that potentially violates a deferred exclusion constraint - is HOT-updated (that is, no indexed columns change and the row can be - stored back onto the same table page) later in the same transaction, - the exclusion constraint would be reported as violated when the check - finally occurred, even if the row(s) the new row originally conflicted - with had been deleted. - - - - - - Fix planning of star-schema-style queries (Tom Lane) - - - - Sometimes, efficient scanning of a large table requires that index - parameters be provided from more than one other table (commonly, - dimension tables whose keys are needed to index a large fact table). - The planner should be able to find such plans, but an overly - restrictive search heuristic prevented it. - - - - - - Prevent improper reordering of antijoins (NOT EXISTS joins) versus - other outer joins (Tom Lane) - - - - This oversight in the planner has been observed to cause could - not find RelOptInfo for given relids errors, but it seems possible - that sometimes an incorrect query plan might get past that consistency - check and result in silently-wrong query output. - - - - - - Fix incorrect matching of subexpressions in outer-join plan nodes - (Tom Lane) - - - - Previously, if textually identical non-strict subexpressions were used - both above and below an outer join, the planner might try to re-use - the value computed below the join, which would be incorrect because the - executor would force the value to NULL in case of an unmatched outer row. - - - - - - Fix GEQO planner to cope with failure of its join order heuristic - (Tom Lane) - - - - This oversight has been seen to lead to failed to join all - relations together errors in queries involving LATERAL, - and that might happen in other cases as well. - - - - - - Fix possible deadlock at startup - when max_prepared_transactions is too small - (Heikki Linnakangas) - - - - - - Don't archive useless preallocated WAL files after a timeline switch - (Heikki Linnakangas) - - - - - - Recursively fsync() the data directory after a crash - (Abhijit Menon-Sen, Robert Haas) - - - - This ensures consistency if another crash occurs shortly later. (The - second crash would have to be a system-level crash, not just a database - crash, for there to be a problem.) - - - - - - Fix autovacuum launcher's possible failure to shut down, if an error - occurs after it receives SIGTERM (Álvaro Herrera) - - - - - - Cope with unexpected signals in LockBufferForCleanup() - (Andres Freund) - - - - This oversight could result in spurious errors about multiple - backends attempting to wait for pincount 1. - - - - - - Fix crash when doing COPY IN to a table with check - constraints that contain whole-row references (Tom Lane) - - - - The known failure case only crashes in 9.4 and up, but there is very - similar code in 9.3 and 9.2, so back-patch those branches as well. - - - - - - Avoid waiting for WAL flush or synchronous replication during commit of - a transaction that was read-only so far as the user is concerned - (Andres Freund) - - - - Previously, a delay could occur at commit in transactions that had - written WAL due to HOT page pruning, leading to undesirable effects - such as sessions getting stuck at startup if all synchronous replicas - are down. Sessions have also been observed to get stuck in catchup - interrupt processing when using synchronous replication; this will fix - that problem as well. - - - - - - Fix crash when manipulating hash indexes on temporary tables - (Heikki Linnakangas) - - - - - - Fix possible failure during hash index bucket split, if other processes - are modifying the index concurrently (Tom Lane) - - - - - - Check for interrupts while analyzing index expressions (Jeff Janes) - - - - ANALYZE executes index expressions many times; if there are - slow functions in such an expression, it's desirable to be able to - cancel the ANALYZE before that loop finishes. - - - - - - Ensure tableoid of a foreign table is reported - correctly when a READ COMMITTED recheck occurs after - locking rows in SELECT FOR UPDATE, UPDATE, - or DELETE (Etsuro Fujita) - - - - - - Add the name of the target server to object description strings for - foreign-server user mappings (Álvaro Herrera) - - - - - - Include the schema name in object identity strings for conversions - (Álvaro Herrera) - - - - - - Recommend setting include_realm to 1 when using - Kerberos/GSSAPI/SSPI authentication (Stephen Frost) - - - - Without this, identically-named users from different realms cannot be - distinguished. For the moment this is only a documentation change, but - it will become the default setting in PostgreSQL 9.5. - - - - - - Remove code for matching IPv4 pg_hba.conf entries to - IPv4-in-IPv6 addresses (Tom Lane) - - - - This hack was added in 2003 in response to a report that some Linux - kernels of the time would report IPv4 connections as having - IPv4-in-IPv6 addresses. However, the logic was accidentally broken in - 9.0. The lack of any field complaints since then shows that it's not - needed anymore. Now we have reports that the broken code causes - crashes on some systems, so let's just remove it rather than fix it. - (Had we chosen to fix it, that would make for a subtle and potentially - security-sensitive change in the effective meaning of - IPv4 pg_hba.conf entries, which does not seem like a good - thing to do in minor releases.) - - - - - - Report WAL flush, not insert, position in IDENTIFY_SYSTEM - replication command (Heikki Linnakangas) - - - - This avoids a possible startup failure - in pg_receivexlog. - - - - - - While shutting down service on Windows, periodically send status - updates to the Service Control Manager to prevent it from killing the - service too soon; and ensure that pg_ctl will wait for - shutdown (Krystian Bigaj) - - - - - - Reduce risk of network deadlock when using libpq's - non-blocking mode (Heikki Linnakangas) - - - - When sending large volumes of data, it's important to drain the input - buffer every so often, in case the server has sent enough response data - to cause it to block on output. (A typical scenario is that the server - is sending a stream of NOTICE messages during COPY FROM - STDIN.) This worked properly in the normal blocking mode, but not - so much in non-blocking mode. We've modified libpq - to opportunistically drain input when it can, but a full defense - against this problem requires application cooperation: the application - should watch for socket read-ready as well as write-ready conditions, - and be sure to call PQconsumeInput() upon read-ready. - - - - - - In libpq, fix misparsing of empty values in URI - connection strings (Thomas Fanghaenel) - - - - - - Fix array handling in ecpg (Michael Meskes) - - - - - - Fix psql to sanely handle URIs and conninfo strings as - the first parameter to \connect - (David Fetter, Andrew Dunstan, Álvaro Herrera) - - - - This syntax has been accepted (but undocumented) for a long time, but - previously some parameters might be taken from the old connection - instead of the given string, which was agreed to be undesirable. - - - - - - Suppress incorrect complaints from psql on some - platforms that it failed to write ~/.psql_history at exit - (Tom Lane) - - - - This misbehavior was caused by a workaround for a bug in very old - (pre-2006) versions of libedit. We fixed it by - removing the workaround, which will cause a similar failure to appear - for anyone still using such versions of libedit. - Recommendation: upgrade that library, or use libreadline. - - - - - - Fix pg_dump's rule for deciding which casts are - system-provided casts that should not be dumped (Tom Lane) - - - - - - In pg_dump, fix failure to honor -Z - compression level option together with -Fd - (Michael Paquier) - - - - - - Make pg_dump consider foreign key relationships - between extension configuration tables while choosing dump order - (Gilles Darold, Michael Paquier, Stephen Frost) - - - - This oversight could result in producing dumps that fail to reload - because foreign key constraints are transiently violated. - - - - - - Avoid possible pg_dump failure when concurrent sessions - are creating and dropping temporary functions (Tom Lane) - - - - - - Fix dumping of views that are just VALUES(...) but have - column aliases (Tom Lane) - - - - - - In pg_upgrade, force timeline 1 in the new cluster - (Bruce Momjian) - - - - This change prevents upgrade failures caused by bogus complaints about - missing WAL history files. - - - - - - In pg_upgrade, check for improperly non-connectable - databases before proceeding - (Bruce Momjian) - - - - - - In pg_upgrade, quote directory paths - properly in the generated delete_old_cluster script - (Bruce Momjian) - - - - - - In pg_upgrade, preserve database-level freezing info - properly - (Bruce Momjian) - - - - This oversight could cause missing-clog-file errors for tables within - the postgres and template1 databases. - - - - - - Run pg_upgrade and pg_resetxlog with - restricted privileges on Windows, so that they don't fail when run by - an administrator (Muhammad Asif Naeem) - - - - - - Improve handling of readdir() failures when scanning - directories in initdb and pg_basebackup - (Marco Nenciarini) - - - - - - Fix slow sorting algorithm in contrib/intarray (Tom Lane) - - - - - - Fix compile failure on Sparc V8 machines (Rob Rowan) - - - - - - Silence some build warnings on macOS (Tom Lane) - - - - - - Update time zone data files to tzdata release 2015d - for DST law changes in Egypt, Mongolia, and Palestine, plus historical - changes in Canada and Chile. Also adopt revised zone abbreviations for - the America/Adak zone (HST/HDT not HAST/HADT). - - - - - - - - - - Release 9.3.6 - - - Release date: - 2015-02-05 - - - - This release contains a variety of fixes from 9.3.5. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.6 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you are a Windows user and are using the Norwegian - (Bokmål) locale, manual action is needed after the upgrade to - replace any Norwegian (Bokmål)_Norway locale names stored - in PostgreSQL system catalogs with the plain-ASCII - alias Norwegian_Norway. For details see - - - - - Also, if you are upgrading from a version earlier than 9.3.5, - see . - - - - - - Changes - - - - - - - - Fix buffer overruns in to_char() - (Bruce Momjian) - - - - When to_char() processes a numeric formatting template - calling for a large number of digits, PostgreSQL - would read past the end of a buffer. When processing a crafted - timestamp formatting template, PostgreSQL would write - past the end of a buffer. Either case could crash the server. - We have not ruled out the possibility of attacks that lead to - privilege escalation, though they seem unlikely. - (CVE-2015-0241) - - - - - - - - Fix buffer overrun in replacement *printf() functions - (Tom Lane) - - - - PostgreSQL includes a replacement implementation - of printf and related functions. This code will overrun - a stack buffer when formatting a floating point number (conversion - specifiers e, E, f, F, - g or G) with requested precision greater than - about 500. This will crash the server, and we have not ruled out the - possibility of attacks that lead to privilege escalation. - A database user can trigger such a buffer overrun through - the to_char() SQL function. While that is the only - affected core PostgreSQL functionality, extension - modules that use printf-family functions may be at risk as well. - - - - This issue primarily affects PostgreSQL on Windows. - PostgreSQL uses the system implementation of these - functions where adequate, which it is on other modern platforms. - (CVE-2015-0242) - - - - - - - - Fix buffer overruns in contrib/pgcrypto - (Marko Tiikkaja, Noah Misch) - - - - Errors in memory size tracking within the pgcrypto - module permitted stack buffer overruns and improper dependence on the - contents of uninitialized memory. The buffer overrun cases can - crash the server, and we have not ruled out the possibility of - attacks that lead to privilege escalation. - (CVE-2015-0243) - - - - - - - - Fix possible loss of frontend/backend protocol synchronization after - an error - (Heikki Linnakangas) - - - - If any error occurred while the server was in the middle of reading a - protocol message from the client, it could lose synchronization and - incorrectly try to interpret part of the message's data as a new - protocol message. An attacker able to submit crafted binary data - within a command parameter might succeed in injecting his own SQL - commands this way. Statement timeout and query cancellation are the - most likely sources of errors triggering this scenario. Particularly - vulnerable are applications that use a timeout and also submit - arbitrary user-crafted data as binary query parameters. Disabling - statement timeout will reduce, but not eliminate, the risk of - exploit. Our thanks to Emil Lenngren for reporting this issue. - (CVE-2015-0244) - - - - - - - - Fix information leak via constraint-violation error messages - (Stephen Frost) - - - - Some server error messages show the values of columns that violate - a constraint, such as a unique constraint. If the user does not have - SELECT privilege on all columns of the table, this could - mean exposing values that the user should not be able to see. Adjust - the code so that values are displayed only when they came from the SQL - command or could be selected by the user. - (CVE-2014-8161) - - - - - - - - Lock down regression testing's temporary installations on Windows - (Noah Misch) - - - - Use SSPI authentication to allow connections only from the OS user - who launched the test suite. This closes on Windows the same - vulnerability previously closed on other platforms, namely that other - users might be able to connect to the test postmaster. - (CVE-2014-0067) - - - - - - - - Cope with the Windows locale named Norwegian (Bokmål) - (Heikki Linnakangas) - - - - Non-ASCII locale names are problematic since it's not clear what - encoding they should be represented in. Map the troublesome locale - name to a plain-ASCII alias, Norwegian_Norway. - - - - - - - - Avoid possible data corruption if ALTER DATABASE SET - TABLESPACE is used to move a database to a new tablespace and then - shortly later move it back to its original tablespace (Tom Lane) - - - - - - - - Avoid corrupting tables when ANALYZE inside a transaction - is rolled back (Andres Freund, Tom Lane, Michael Paquier) - - - - If the failing transaction had earlier removed the last index, rule, or - trigger from the table, the table would be left in a corrupted state - with the relevant pg_class flags not set though they - should be. - - - - - - - - Ensure that unlogged tables are copied correctly - during CREATE DATABASE or ALTER DATABASE SET - TABLESPACE (Pavan Deolasee, Andres Freund) - - - - - - - - Fix incorrect processing - of CreateEventTrigStmt.eventname (Petr - Jelinek) - - - - This could result in misbehavior if CREATE EVENT TRIGGER - were executed as a prepared query, or via extended query protocol. - - - - - - - - Fix DROP's dependency searching to correctly handle the - case where a table column is recursively visited before its table - (Petr Jelinek, Tom Lane) - - - - This case is only known to arise when an extension creates both a - datatype and a table using that datatype. The faulty code might - refuse a DROP EXTENSION unless CASCADE is - specified, which should not be required. - - - - - - - - Fix use-of-already-freed-memory problem in EvalPlanQual processing - (Tom Lane) - - - - In READ COMMITTED mode, queries that lock or update - recently-updated rows could crash as a result of this bug. - - - - - - - - Avoid possible deadlock while trying to acquire tuple locks - in EvalPlanQual processing (Álvaro Herrera, Mark Kirkwood) - - - - - - - - Fix failure to wait when a transaction tries to acquire a FOR - NO KEY EXCLUSIVE tuple lock, while multiple other transactions - currently hold FOR SHARE locks (Álvaro Herrera) - - - - - - - - Fix planning of SELECT FOR UPDATE when using a partial - index on a child table (Kyotaro Horiguchi) - - - - In READ COMMITTED mode, SELECT FOR UPDATE must - also recheck the partial index's WHERE condition when - rechecking a recently-updated row to see if it still satisfies the - query's WHERE condition. This requirement was missed if the - index belonged to an inheritance child table, so that it was possible - to incorrectly return rows that no longer satisfy the query condition. - - - - - - - - Fix corner case wherein SELECT FOR UPDATE could return a row - twice, and possibly miss returning other rows (Tom Lane) - - - - In READ COMMITTED mode, a SELECT FOR UPDATE - that is scanning an inheritance tree could incorrectly return a row - from a prior child table instead of the one it should return from a - later child table. - - - - - - - - Improve performance of EXPLAIN with large range tables - (Tom Lane) - - - - - - - - Reject duplicate column names in the referenced-columns list of - a FOREIGN KEY declaration (David Rowley) - - - - This restriction is per SQL standard. Previously we did not reject - the case explicitly, but later on the code would fail with - bizarre-looking errors. - - - - - - - - Re-enable error for SELECT ... OFFSET -1 (Tom Lane) - - - - A negative offset value has been an error since 8.4, but an - optimization added in 9.3 accidentally turned the case into a no-op. - Restore the expected behavior. - - - - - - - - Restore previous behavior of conversion of domains to JSON - (Tom Lane) - - - - This change causes domains over numeric and boolean to be treated - like their base types for purposes of conversion to JSON. It worked - like that before 9.3.5 and 9.2.9, but was unintentionally changed - while fixing a related problem. - - - - - - - - Fix json_agg() to not return extra trailing right - brackets in its result (Tom Lane) - - - - - - - - Fix bugs in raising a numeric value to a large integral power - (Tom Lane) - - - - The previous code could get a wrong answer, or consume excessive - amounts of time and memory before realizing that the answer must - overflow. - - - - - - - - In numeric_recv(), truncate away any fractional digits - that would be hidden according to the value's dscale field - (Tom Lane) - - - - A numeric value's display scale (dscale) should - never be less than the number of nonzero fractional digits; but - apparently there's at least one broken client application that - transmits binary numeric values in which that's true. - This leads to strange behavior since the extra digits are taken into - account by arithmetic operations even though they aren't printed. - The least risky fix seems to be to truncate away such hidden - digits on receipt, so that the value is indeed what it prints as. - - - - - - - - Fix incorrect search for shortest-first regular expression matches - (Tom Lane) - - - - Matching would often fail when the number of allowed iterations is - limited by a ? quantifier or a bound expression. - - - - - - - - Reject out-of-range numeric timezone specifications (Tom Lane) - - - - Simple numeric timezone specifications exceeding +/- 168 hours (one - week) would be accepted, but could then cause null-pointer dereference - crashes in certain operations. There's no use-case for such large UTC - offsets, so reject them. - - - - - - - - Fix bugs in tsquery @> tsquery - operator (Heikki Linnakangas) - - - - Two different terms would be considered to match if they had the same - CRC. Also, if the second operand had more terms than the first, it - would be assumed not to be contained in the first; which is wrong - since it might contain duplicate terms. - - - - - - - - Improve ispell dictionary's defenses against bad affix files (Tom Lane) - - - - - - - - Allow more than 64K phrases in a thesaurus dictionary (David Boutin) - - - - The previous coding could crash on an oversize dictionary, so this was - deemed a back-patchable bug fix rather than a feature addition. - - - - - - - - Fix namespace handling in xpath() (Ali Akbar) - - - - Previously, the xml value resulting from - an xpath() call would not have namespace declarations if - the namespace declarations were attached to an ancestor element in the - input xml value, rather than to the specific element being - returned. Propagate the ancestral declaration so that the result is - correct when considered in isolation. - - - - - - - - Ensure that whole-row variables expose nonempty column names - to functions that pay attention to column names within composite - arguments (Tom Lane) - - - - In some contexts, constructs like row_to_json(tab.*) may - not produce the expected column names. This is fixed properly as of - 9.4; in older branches, just ensure that we produce some nonempty - name. (In some cases this will be the underlying table's column name - rather than the query-assigned alias that should theoretically be - visible.) - - - - - - - - Fix mishandling of system columns, - particularly tableoid, in FDW queries (Etsuro Fujita) - - - - - - - - Fix assorted oversights in range-operator selectivity estimation - (Emre Hasegeli) - - - - This patch fixes corner-case unexpected operator NNNN planner - errors, and improves the selectivity estimates for some other cases. - - - - - - - - Avoid doing indexed_column = ANY - (array) as an index qualifier if that leads - to an inferior plan (Andrew Gierth) - - - - In some cases, = ANY conditions applied to non-first index - columns would be done as index conditions even though it would be - better to use them as simple filter conditions. - - - - - - - - Fix variable not found in subplan target list planner - failure when an inline-able SQL function taking a composite argument - is used in a LATERAL subselect and the composite argument - is a lateral reference (Tom Lane) - - - - - - - - Fix planner problems with nested append relations, such as inherited - tables within UNION ALL subqueries (Tom Lane) - - - - - - - - Fail cleanly when a GiST index tuple doesn't fit on a page, rather - than going into infinite recursion (Andrew Gierth) - - - - - - - - Exempt tables that have per-table cost_limit - and/or cost_delay settings from autovacuum's global cost - balancing rules (Álvaro Herrera) - - - - The previous behavior resulted in basically ignoring these per-table - settings, which was unintended. Now, a table having such settings - will be vacuumed using those settings, independently of what is going - on in other autovacuum workers. This may result in heavier total I/O - load than before, so such settings should be re-examined for sanity. - - - - - - - - Avoid wholesale autovacuuming when autovacuum is nominally off - (Tom Lane) - - - - Even when autovacuum is nominally off, we will still launch autovacuum - worker processes to vacuum tables that are at risk of XID wraparound. - However, such a worker process then proceeded to vacuum all tables in - the target database, if they met the usual thresholds for - autovacuuming. This is at best pretty unexpected; at worst it delays - response to the wraparound threat. Fix it so that if autovacuum is - turned off, workers only do anti-wraparound vacuums and - not any other work. - - - - - - - - During crash recovery, ensure that unlogged relations are rewritten as - empty and are synced to disk before recovery is considered complete - (Abhijit Menon-Sen, Andres Freund) - - - - This prevents scenarios in which unlogged relations might contain - garbage data following database crash recovery. - - - - - - - - Fix race condition between hot standby queries and replaying a - full-page image (Heikki Linnakangas) - - - - This mistake could result in transient errors in queries being - executed in hot standby. - - - - - - - - Fix several cases where recovery logic improperly ignored WAL records - for COMMIT/ABORT PREPARED (Heikki Linnakangas) - - - - The most notable oversight was - that recovery_target_xid could not be used to stop at - a two-phase commit. - - - - - - - - Prevent latest WAL file from being archived a second time at completion - of crash recovery (Fujii Masao) - - - - - - - - Avoid creating unnecessary .ready marker files for - timeline history files (Fujii Masao) - - - - - - - - Fix possible null pointer dereference when an empty prepared statement - is used and the log_statement setting is mod - or ddl (Fujii Masao) - - - - - - - - Change pgstat wait timeout warning message to be LOG level, - and rephrase it to be more understandable (Tom Lane) - - - - This message was originally thought to be essentially a can't-happen - case, but it occurs often enough on our slower buildfarm members to be - a nuisance. Reduce it to LOG level, and expend a bit more effort on - the wording: it now reads using stale statistics instead of - current ones because stats collector is not responding. - - - - - - - - Fix possible corruption of postmaster's list of dynamic background - workers (Andres Freund) - - - - - - - - Fix SPARC spinlock implementation to ensure correctness if the CPU is - being run in a non-TSO coherency mode, as some non-Solaris kernels do - (Andres Freund) - - - - - - - - Warn if macOS's setlocale() starts an unwanted extra - thread inside the postmaster (Noah Misch) - - - - - - - - Fix processing of repeated dbname parameters - in PQconnectdbParams() (Alex Shulgin) - - - - Unexpected behavior ensued if the first occurrence - of dbname contained a connection string or URI to be - expanded. - - - - - - - - Ensure that libpq reports a suitable error message on - unexpected socket EOF (Marko Tiikkaja, Tom Lane) - - - - Depending on kernel behavior, libpq might return an - empty error string rather than something useful when the server - unexpectedly closed the socket. - - - - - - - - Clear any old error message during PQreset() - (Heikki Linnakangas) - - - - If PQreset() is called repeatedly, and the connection - cannot be re-established, error messages from the failed connection - attempts kept accumulating in the PGconn's error - string. - - - - - - - - Properly handle out-of-memory conditions while parsing connection - options in libpq (Alex Shulgin, Heikki Linnakangas) - - - - - - - - Fix array overrun in ecpg's version - of ParseDateTime() (Michael Paquier) - - - - - - - - In initdb, give a clearer error message if a password - file is specified but is empty (Mats Erik Andersson) - - - - - - - - Fix psql's \s command to work nicely with - libedit, and add pager support (Stepan Rutz, Tom Lane) - - - - When using libedit rather than readline, \s printed the - command history in a fairly unreadable encoded format, and on recent - libedit versions might fail altogether. Fix that by printing the - history ourselves rather than having the library do it. A pleasant - side-effect is that the pager is used if appropriate. - - - - This patch also fixes a bug that caused newline encoding to be applied - inconsistently when saving the command history with libedit. - Multiline history entries written by older psql - versions will be read cleanly with this patch, but perhaps not - vice versa, depending on the exact libedit versions involved. - - - - - - - - Improve consistency of parsing of psql's special - variables (Tom Lane) - - - - Allow variant spellings of on and off (such - as 1/0) for ECHO_HIDDEN - and ON_ERROR_ROLLBACK. Report a warning for unrecognized - values for COMP_KEYWORD_CASE, ECHO, - ECHO_HIDDEN, HISTCONTROL, - ON_ERROR_ROLLBACK, and VERBOSITY. Recognize - all values for all these variables case-insensitively; previously - there was a mishmash of case-sensitive and case-insensitive behaviors. - - - - - - - - Make psql's \watch command display - nulls as specified by \pset null (Fujii Masao) - - - - - - - - Fix psql's expanded-mode display to work - consistently when using border = 3 - and linestyle = ascii or unicode - (Stephen Frost) - - - - - - - - Fix pg_dump to handle comments on event triggers - without failing (Tom Lane) - - - - - - - - Allow parallel pg_dump to - use (Kevin Grittner) - - - - - - - - Improve performance of pg_dump when the database - contains many instances of multiple dependency paths between the same - two objects (Tom Lane) - - - - - - - - Fix pg_dumpall to restore its ability to dump from - pre-8.1 servers (Gilles Darold) - - - - - - - - Fix possible deadlock during parallel restore of a schema-only dump - (Robert Haas, Tom Lane) - - - - - - - - Fix core dump in pg_dump --binary-upgrade on zero-column - composite type (Rushabh Lathia) - - - - - - - - Fix failure to fsync tables in nondefault tablespaces - during pg_upgrade (Abhijit Menon-Sen, Andres Freund) - - - - With an operating system crash and some bad luck, this could result in - data loss during an upgrade. - - - - - - - - In pg_upgrade, cope with cases where the new cluster - creates a TOAST table for a table that didn't previously have one - (Bruce Momjian) - - - - Previously this could result in failures due to OID conflicts. - - - - - - - - In pg_upgrade, don't try to - set autovacuum_multixact_freeze_max_age for the old cluster - (Bruce Momjian) - - - - This could result in failure because not all 9.3.X versions have that - parameter. Fortunately, we don't actually need to set it at all. - - - - - - - - In pg_upgrade, preserve the transaction ID epoch - (Bruce Momjian) - - - - This oversight did not bother PostgreSQL proper, - but could confuse some external replication tools. - - - - - - - - Prevent WAL files created by pg_basebackup -x/-X from - being archived again when the standby is promoted (Andres Freund) - - - - - - - - Fix memory leak in pg_receivexlog (Fujii Masao) - - - - - - - - Fix unintended suppression of pg_receivexlog verbose - messages (Fujii Masao) - - - - - - - - Fix failure of contrib/auto_explain to print per-node - timing information when doing EXPLAIN ANALYZE (Tom Lane) - - - - - - - - Fix upgrade-from-unpackaged script for contrib/citext - (Tom Lane) - - - - - - - - Avoid integer overflow and buffer overrun - in contrib/hstore's hstore_to_json() - (Heikki Linnakangas) - - - - - - - - Fix recognition of numbers in hstore_to_json_loose(), - so that JSON numbers and strings are correctly distinguished - (Andrew Dunstan) - - - - - - - - Fix block number checking - in contrib/pageinspect's get_raw_page() - (Tom Lane) - - - - The incorrect checking logic could prevent access to some pages in - non-main relation forks. - - - - - - - - Fix contrib/pgcrypto's pgp_sym_decrypt() - to not fail on messages whose length is 6 less than a power of 2 - (Marko Tiikkaja) - - - - - - - - Fix file descriptor leak in contrib/pg_test_fsync - (Jeff Janes) - - - - This could cause failure to remove temporary files on Windows. - - - - - - - - Handle unexpected query results, especially NULLs, safely in - contrib/tablefunc's connectby() - (Michael Paquier) - - - - connectby() previously crashed if it encountered a NULL - key value. It now prints that row but doesn't recurse further. - - - - - - - - Avoid a possible crash in contrib/xml2's - xslt_process() (Mark Simonetti) - - - - libxslt seems to have an undocumented dependency on - the order in which resources are freed; reorder our calls to avoid a - crash. - - - - - - - - Mark some contrib I/O functions with correct volatility - properties (Tom Lane) - - - - The previous over-conservative marking was immaterial in normal use, - but could cause optimization problems or rejection of valid index - expression definitions. Since the consequences are not large, we've - just adjusted the function definitions in the extension modules' - scripts, without changing version numbers. - - - - - - - - Numerous cleanups of warnings from Coverity static code analyzer - (Andres Freund, Tatsuo Ishii, Marko Kreen, Tom Lane, Michael Paquier) - - - - These changes are mostly cosmetic but in some cases fix corner-case - bugs, for example a crash rather than a proper error report after an - out-of-memory failure. None are believed to represent security - issues. - - - - - - - - Fix setup of background workers in EXEC_BACKEND builds, eg Windows - (Robert Haas) - - - - - - - - Detect incompatible OpenLDAP versions during build (Noah Misch) - - - - With OpenLDAP versions 2.4.24 through 2.4.31, - inclusive, PostgreSQL backends can crash at exit. - Raise a warning during configure based on the - compile-time OpenLDAP version number, and test the crashing scenario - in the contrib/dblink regression test. - - - - - - - - In non-MSVC Windows builds, ensure libpq.dll is installed - with execute permissions (Noah Misch) - - - - - - - - Make pg_regress remove any temporary installation it - created upon successful exit (Tom Lane) - - - - This results in a very substantial reduction in disk space usage - during make check-world, since that sequence involves - creation of numerous temporary installations. - - - - - - - - Support time zone abbreviations that change UTC offset from time to - time (Tom Lane) - - - - Previously, PostgreSQL assumed that the UTC offset - associated with a time zone abbreviation (such as EST) - never changes in the usage of any particular locale. However this - assumption fails in the real world, so introduce the ability for a - zone abbreviation to represent a UTC offset that sometimes changes. - Update the zone abbreviation definition files to make use of this - feature in timezone locales that have changed the UTC offset of their - abbreviations since 1970 (according to the IANA timezone database). - In such timezones, PostgreSQL will now associate the - correct UTC offset with the abbreviation depending on the given date. - - - - - - - - Update time zone abbreviations lists (Tom Lane) - - - - Add CST (China Standard Time) to our lists. - Remove references to ADT as Arabia Daylight Time, an - abbreviation that's been out of use since 2007; therefore, claiming - there is a conflict with Atlantic Daylight Time doesn't seem - especially helpful. - Fix entirely incorrect GMT offsets for CKT (Cook Islands), FJT, and FJST - (Fiji); we didn't even have them on the proper side of the date line. - - - - - - - - Update time zone data files to tzdata release 2015a. - - - - The IANA timezone database has adopted abbreviations of the form - AxST/AxDT - for all Australian time zones, reflecting what they believe to be - current majority practice Down Under. These names do not conflict - with usage elsewhere (other than ACST for Acre Summer Time, which has - been in disuse since 1994). Accordingly, adopt these names into - our Default timezone abbreviation set. - The Australia abbreviation set now contains only CST, EAST, - EST, SAST, SAT, and WST, all of which are thought to be mostly - historical usage. Note that SAST has also been changed to be South - Africa Standard Time in the Default abbreviation set. - - - - Also, add zone abbreviations SRET (Asia/Srednekolymsk) and XJT - (Asia/Urumqi), and use WSST/WSDT for western Samoa. Also, there were - DST law changes in Chile, Mexico, the Turks & Caicos Islands - (America/Grand_Turk), and Fiji. There is a new zone - Pacific/Bougainville for portions of Papua New Guinea. Also, numerous - corrections for historical (pre-1970) time zone data. - - - - - - - - - - Release 9.3.5 - - - Release date: - 2014-07-24 - - - - This release contains a variety of fixes from 9.3.4. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.5 - - - A dump/restore is not required for those running 9.3.X. - - - - However, this release corrects a logic error - in pg_upgrade, as well as an index corruption problem in - some GiST indexes. See the first two changelog entries below to find out - whether your installation has been affected and what steps you should take - if so. - - - - Also, if you are upgrading from a version earlier than 9.3.4, - see . - - - - - - Changes - - - - - - - - In pg_upgrade, remove pg_multixact files - left behind by initdb (Bruce Momjian) - - - - If you used a pre-9.3.5 version of pg_upgrade to - upgrade a database cluster to 9.3, it might have left behind a file - $PGDATA/pg_multixact/offsets/0000 that should not be - there and will eventually cause problems in VACUUM. - However, in common cases this file is actually valid and - must not be removed. - To determine whether your installation has this problem, run this - query as superuser, in any database of the cluster: - -WITH list(file) AS (SELECT * FROM pg_ls_dir('pg_multixact/offsets')) -SELECT EXISTS (SELECT * FROM list WHERE file = '0000') AND - NOT EXISTS (SELECT * FROM list WHERE file = '0001') AND - NOT EXISTS (SELECT * FROM list WHERE file = 'FFFF') AND - EXISTS (SELECT * FROM list WHERE file != '0000') - AS file_0000_removal_required; - - If this query returns t, manually remove the file - $PGDATA/pg_multixact/offsets/0000. - Do nothing if the query returns f. - - - - - - - - Correctly initialize padding bytes in contrib/btree_gist - indexes on bit columns (Heikki Linnakangas) - - - - This error could result in incorrect query results due to values that - should compare equal not being seen as equal. - Users with GiST indexes on bit or bit varying - columns should REINDEX those indexes after installing this - update. - - - - - - - - Protect against torn pages when deleting GIN list pages (Heikki - Linnakangas) - - - - This fix prevents possible index corruption if a system crash occurs - while the page update is being written to disk. - - - - - - - - Don't clear the right-link of a GiST index page while replaying - updates from WAL (Heikki Linnakangas) - - - - This error could lead to transiently wrong answers from GiST index - scans performed in Hot Standby. - - - - - - - - Fix corner-case infinite loop during insertion into an SP-GiST text - index (Tom Lane) - - - - - - - - Fix incorrect answers from SP-GiST index searches - with -|- (range adjacency) operator - (Heikki Linnakangas) - - - - - - - - Fix wraparound handling for pg_multixact/members - (Álvaro Herrera) - - - - - - - - Truncate pg_multixact during checkpoints, not - during VACUUM (Álvaro Herrera) - - - - This change ensures that pg_multixact segments can't be - removed if they'd still be needed during WAL replay after a crash. - - - - - - - - Fix possible inconsistency of all-visible flags after WAL recovery - (Heikki Linnakangas) - - - - - - - - Fix possibly-incorrect cache invalidation during nested calls - to ReceiveSharedInvalidMessages (Andres Freund) - - - - - - - - Fix race condition when updating a tuple concurrently locked by - another process (Andres Freund, Álvaro Herrera) - - - - - - - - Fix could not find pathkey item to sort planner failures - with UNION ALL over subqueries reading from tables with - inheritance children (Tom Lane) - - - - - - - - Don't assume a subquery's output is unique if there's a set-returning - function in its targetlist (David Rowley) - - - - This oversight could lead to misoptimization of constructs - like WHERE x IN (SELECT y, generate_series(1,10) FROM t GROUP - BY y). - - - - - - - - Improve planner to drop constant-NULL inputs - of AND/OR when possible (Tom Lane) - - - - This change fixes some cases where the more aggressive parameter - substitution done by 9.2 and later can lead to a worse plan than - older versions produced. - - - - - - - - Ensure that the planner sees equivalent VARIADIC and - non-VARIADIC function calls as equivalent (Tom Lane) - - - - This bug could for example result in failure to use expression indexes - involving variadic functions. It might be necessary to re-create such - indexes, and/or re-create views including variadic function calls that - should match the indexes, for the fix to be effective for existing 9.3 - installations. - - - - - - - - Fix handling of nested JSON objects - in json_populate_recordset() and friends - (Michael Paquier, Tom Lane) - - - - A nested JSON object could result in previous fields of the - parent object not being shown in the output. - - - - - - - - Fix identification of input type category in to_json() - and friends (Tom Lane) - - - - This is known to have led to inadequate quoting of money - fields in the JSON result, and there may have been wrong - results for other data types as well. - - - - - - - - Fix failure to detoast fields in composite elements of structured - types (Tom Lane) - - - - This corrects cases where TOAST pointers could be copied into other - tables without being dereferenced. If the original data is later - deleted, it would lead to errors like missing chunk number 0 - for toast value ... when the now-dangling pointer is used. - - - - - - - - Fix record type has not been registered failures with - whole-row references to the output of Append plan nodes (Tom Lane) - - - - - - - - Fix possible crash when invoking a user-defined function while - rewinding a cursor (Tom Lane) - - - - - - - - Fix query-lifespan memory leak while evaluating the arguments for a - function in FROM (Tom Lane) - - - - - - - - Fix session-lifespan memory leaks in regular-expression processing - (Tom Lane, Arthur O'Dwyer, Greg Stark) - - - - - - - - Fix data encoding error in hungarian.stop (Tom Lane) - - - - - - - - Prevent foreign tables from being created with OIDS - when is true - (Etsuro Fujita) - - - - - - - - Fix liveness checks for rows that were inserted in the current - transaction and then deleted by a now-rolled-back subtransaction - (Andres Freund) - - - - This could cause problems (at least spurious warnings, and at worst an - infinite loop) if CREATE INDEX or CLUSTER were - done later in the same transaction. - - - - - - - - Clear pg_stat_activity.xact_start - during PREPARE TRANSACTION (Andres Freund) - - - - After the PREPARE, the originating session is no longer in - a transaction, so it should not continue to display a transaction - start time. - - - - - - - - Fix REASSIGN OWNED to not fail for text search objects - (Álvaro Herrera) - - - - - - - - Prevent pg_class.relminmxid values from - going backwards during VACUUM FULL (Álvaro Herrera) - - - - - - - - Reduce indentation in rule/view dumps to improve readability and avoid - excessive whitespace (Greg Stark, Tom Lane) - - - - This change reduces the amount of indentation applied to nested - constructs, including some cases that the user probably doesn't think - of as nested, such as UNION lists. Previously, deeply nested - constructs were printed with an amount of whitespace growing as - O(N^2), which created a performance problem and even risk of - out-of-memory failures. Now the indentation is reduced modulo 40, - which is initially odd to look at but seems to preserve readability - better than simply limiting the indentation would do. - Redundant parenthesization of UNION lists has been reduced as well. - - - - - - - - Fix dumping of rules/views when subsequent addition of a column has - resulted in multiple input columns matching a USING - specification (Tom Lane) - - - - - - - - Repair view printing for some cases involving functions - in FROM that return a composite type containing dropped - columns (Tom Lane) - - - - - - - - Block signals during postmaster startup (Tom Lane) - - - - This ensures that the postmaster will properly clean up after itself - if, for example, it receives SIGINT while still - starting up. - - - - - - - - Fix client host name lookup when processing pg_hba.conf - entries that specify host names instead of IP addresses (Tom Lane) - - - - Ensure that reverse-DNS lookup failures are reported, instead of just - silently not matching such entries. Also ensure that we make only - one reverse-DNS lookup attempt per connection, not one per host name - entry, which is what previously happened if the lookup attempts failed. - - - - - - - - Allow the root user to use postgres -C variable and - postgres --describe-config (MauMau) - - - - The prohibition on starting the server as root does not need to extend - to these operations, and relaxing it prevents failure - of pg_ctl in some scenarios. - - - - - - - - Secure Unix-domain sockets of temporary postmasters started during - make check (Noah Misch) - - - - Any local user able to access the socket file could connect as the - server's bootstrap superuser, then proceed to execute arbitrary code as - the operating-system user running the test, as we previously noted in - CVE-2014-0067. This change defends against that risk by placing the - server's socket in a temporary, mode 0700 subdirectory - of /tmp. The hazard remains however on platforms where - Unix sockets are not supported, notably Windows, because then the - temporary postmaster must accept local TCP connections. - - - - A useful side effect of this change is to simplify - make check testing in builds that - override DEFAULT_PGSOCKET_DIR. Popular non-default values - like /var/run/postgresql are often not writable by the - build user, requiring workarounds that will no longer be necessary. - - - - - - - - Fix tablespace creation WAL replay to work on Windows (MauMau) - - - - - - - - Fix detection of socket creation failures on Windows (Bruce Momjian) - - - - - - - - On Windows, allow new sessions to absorb values of PGC_BACKEND - parameters (such as ) from the - configuration file (Amit Kapila) - - - - Previously, if such a parameter were changed in the file post-startup, - the change would have no effect. - - - - - - - - Properly quote executable path names on Windows (Nikhil Deshpande) - - - - This oversight could cause initdb - and pg_upgrade to fail on Windows, if the installation - path contained both spaces and @ signs. - - - - - - - - Fix linking of libpython on macOS (Tom Lane) - - - - The method we previously used can fail with the Python library - supplied by Xcode 5.0 and later. - - - - - - - - Avoid buffer bloat in libpq when the server - consistently sends data faster than the client can absorb it - (Shin-ichi Morita, Tom Lane) - - - - libpq could be coerced into enlarging its input buffer - until it runs out of memory (which would be reported misleadingly - as lost synchronization with server). Under ordinary - circumstances it's quite far-fetched that data could be continuously - transmitted more quickly than the recv() loop can - absorb it, but this has been observed when the client is artificially - slowed by scheduler constraints. - - - - - - - - Ensure that LDAP lookup attempts in libpq time out as - intended (Laurenz Albe) - - - - - - - - Fix ecpg to do the right thing when an array - of char * is the target for a FETCH statement returning more - than one row, as well as some other array-handling fixes - (Ashutosh Bapat) - - - - - - - - Fix pg_dump to cope with a materialized view that - depends on a table's primary key (Tom Lane) - - - - This occurs if the view's query relies on functional dependency to - abbreviate a GROUP BY list. pg_dump got - sufficiently confused that it dumped the materialized view as a - regular view. - - - - - - - - Fix parsing of pg_dumpall's switch - (Tom Lane) - - - - - - - - Fix pg_restore's processing of old-style large object - comments (Tom Lane) - - - - A direct-to-database restore from an archive file generated by a - pre-9.0 version of pg_dump would usually fail if the - archive contained more than a few comments for large objects. - - - - - - - - Fix pg_upgrade for cases where the new server creates - a TOAST table but the old version did not (Bruce Momjian) - - - - This rare situation would manifest as relation OID mismatch - errors. - - - - - - - - In pg_upgrade, - preserve pg_database.datminmxid - and pg_class.relminmxid values from the - old cluster, or insert reasonable values when upgrading from pre-9.3; - also defend against unreasonable values in the core server - (Bruce Momjian, Álvaro Herrera, Tom Lane) - - - - These changes prevent scenarios in which autovacuum might insist on - scanning the entire cluster's contents immediately upon starting the - new cluster, or in which tracking of unfrozen MXID values might be - disabled completely. - - - - - - - - Prevent contrib/auto_explain from changing the output of - a user's EXPLAIN (Tom Lane) - - - - If auto_explain is active, it could cause - an EXPLAIN (ANALYZE, TIMING OFF) command to nonetheless - print timing information. - - - - - - - - Fix query-lifespan memory leak in contrib/dblink - (MauMau, Joe Conway) - - - - - - - - In contrib/pgcrypto functions, ensure sensitive - information is cleared from stack variables before returning - (Marko Kreen) - - - - - - - - Prevent use of already-freed memory in - contrib/pgstattuple's pgstat_heap() - (Noah Misch) - - - - - - - - In contrib/uuid-ossp, cache the state of the OSSP UUID - library across calls (Tom Lane) - - - - This improves the efficiency of UUID generation and reduces the amount - of entropy drawn from /dev/urandom, on platforms that - have that. - - - - - - - - Update time zone data files to tzdata release 2014e - for DST law changes in Crimea, Egypt, and Morocco. - - - - - - - - - - Release 9.3.4 - - - Release date: - 2014-03-20 - - - - This release contains a variety of fixes from 9.3.3. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.4 - - - A dump/restore is not required for those running 9.3.X. - - - - However, the error fixed in the first changelog entry below could have - resulted in corrupt data on standby servers. It may be prudent to - reinitialize standby servers from fresh base backups after installing - this update. - - - - Also, if you are upgrading from a version earlier than 9.3.3, - see . - - - - - - Changes - - - - - - - - Fix WAL replay of locking an already-updated tuple (Andres Freund, - Álvaro Herrera) - - - - This error caused updated rows to not be found by index scans, resulting - in inconsistent query results depending on whether an index scan was - used. Subsequent processing could result in constraint violations, - since the previously updated row would not be found by later index - searches, thus possibly allowing conflicting rows to be inserted. - Since this error is in WAL replay, it would only manifest during crash - recovery or on standby servers. The improperly-replayed case most - commonly arises when a table row that is referenced by a foreign-key - constraint is updated concurrently with creation of a referencing row. - - - - - - - - Restore GIN metapages unconditionally to avoid torn-page risk - (Heikki Linnakangas) - - - - Although this oversight could theoretically result in a corrupted - index, it is unlikely to have caused any problems in practice, since - the active part of a GIN metapage is smaller than a standard 512-byte - disk sector. - - - - - - - - Avoid race condition in checking transaction commit status during - receipt of a NOTIFY message (Marko Tiikkaja) - - - - This prevents a scenario wherein a sufficiently fast client might - respond to a notification before database updates made by the - notifier have become visible to the recipient. - - - - - - - - Allow materialized views to be referenced in UPDATE - and DELETE commands (Michael Paquier) - - - - Previously such queries failed with a complaint about not being able - to lock rows in the materialized view. - - - - - - - - Allow regular-expression operators to be terminated early by query - cancel requests (Tom Lane) - - - - This prevents scenarios wherein a pathological regular expression - could lock up a server process uninterruptibly for a long time. - - - - - - - - Remove incorrect code that tried to allow OVERLAPS with - single-element row arguments (Joshua Yanovski) - - - - This code never worked correctly, and since the case is neither - specified by the SQL standard nor documented, it seemed better to - remove it than fix it. - - - - - - - - Avoid getting more than AccessShareLock when de-parsing a - rule or view (Dean Rasheed) - - - - This oversight resulted in pg_dump unexpectedly - acquiring RowExclusiveLock locks on tables mentioned as - the targets of INSERT/UPDATE/DELETE - commands in rules. While usually harmless, that could interfere with - concurrent transactions that tried to acquire, for example, - ShareLock on those tables. - - - - - - - - Improve performance of index endpoint probes during planning (Tom Lane) - - - - This change fixes a significant performance problem that occurred - when there were many not-yet-committed rows at the end of the index, - which is a common situation for indexes on sequentially-assigned - values such as timestamps or sequence-generated identifiers. - - - - - - - - Use non-default selectivity estimates for - value IN (list) and - value operator ANY - (array) - expressions when the righthand side is a stable expression (Tom Lane) - - - - - - - - Remove the correct per-database statistics file during DROP - DATABASE (Tomas Vondra) - - - - This fix prevents a permanent leak of statistics file space. - Users who have done many DROP DATABASE commands since - upgrading to PostgreSQL 9.3 may wish to check their - statistics directory and delete statistics files that do not - correspond to any existing database. Please note - that db_0.stat should not be removed. - - - - - - - - Fix walsender ping logic to avoid inappropriate - disconnects under continuous load (Andres Freund, Heikki Linnakangas) - - - - walsender failed to send ping messages to the client - if it was constantly busy sending WAL data; but it expected to see - ping responses despite that, and would therefore disconnect - once elapsed. - - - - - - - - Fix walsender's failure to shut down cleanly when client - is pg_receivexlog (Fujii Masao) - - - - - - - - Check WAL level and hot standby parameters correctly when doing crash - recovery that will be followed by archive recovery (Heikki Linnakangas) - - - - - - - - Fix test to see if hot standby connections can be allowed immediately - after a crash (Heikki Linnakangas) - - - - - - - - Add read-only parameter to - display whether page checksums are enabled (Heikki Linnakangas) - - - - Without this parameter, determining the state of checksum - processing was difficult. - - - - - - - - Prevent interrupts while reporting non-ERROR messages - (Tom Lane) - - - - This guards against rare server-process freezeups due to recursive - entry to syslog(), and perhaps other related problems. - - - - - - - - Fix memory leak in PL/Perl when returning a composite result, including - multiple-OUT-parameter cases (Alex Hunsaker) - - - - - - - - Fix tracking of psql script line numbers - during \copy from out-of-line data - (Kumar Rajeev Rastogi, Amit Khandekar) - - - - \copy ... from incremented the script file line number - for each data line, even if the data was not coming from the script - file. This mistake resulted in wrong line numbers being reported for - any errors occurring later in the same script file. - - - - - - - - Fix contrib/postgres_fdw to handle multiple join - conditions properly (Tom Lane) - - - - This oversight could result in sending WHERE clauses to - the remote server for execution even though the clauses are not known - to have the same semantics on the remote server (for example, clauses - that use non-built-in operators). The query might succeed anyway, - but it could also fail with errors from the remote server, or worse - give silently wrong answers. - - - - - - - - Prevent intermittent could not reserve shared memory region - failures on recent Windows versions (MauMau) - - - - - - - - Update time zone data files to tzdata release 2014a - for DST law changes in Fiji and Turkey, plus historical changes in - Israel and Ukraine. - - - - - - - - - - Release 9.3.3 - - - Release date: - 2014-02-20 - - - - This release contains a variety of fixes from 9.3.2. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.3 - - - A dump/restore is not required for those running 9.3.X. - - - - However, several of the issues corrected in this release could have - resulted in corruption of foreign-key constraints; that is, there - might now be referencing rows for which there is no matching row in - the referenced table. It may be worthwhile to recheck such - constraints after installing this update. The simplest way to do that - is to drop and recreate each suspect constraint; however, that will - require taking an exclusive lock on both tables, so it is unlikely to - be acceptable in production databases. Alternatively, you can do a - manual join query between the two tables to look for unmatched rows. - - - - Note also the requirement for replication standby servers to be - upgraded before their master server is upgraded. - - - - Also, if you are upgrading from a version earlier than 9.3.2, - see . - - - - - - Changes - - - - - - - - Shore up GRANT ... WITH ADMIN OPTION restrictions - (Noah Misch) - - - - Granting a role without ADMIN OPTION is supposed to - prevent the grantee from adding or removing members from the granted - role, but this restriction was easily bypassed by doing SET - ROLE first. The security impact is mostly that a role member can - revoke the access of others, contrary to the wishes of his grantor. - Unapproved role member additions are a lesser concern, since an - uncooperative role member could provide most of his rights to others - anyway by creating views or SECURITY DEFINER functions. - (CVE-2014-0060) - - - - - - - - Prevent privilege escalation via manual calls to PL validator - functions (Andres Freund) - - - - The primary role of PL validator functions is to be called implicitly - during CREATE FUNCTION, but they are also normal SQL - functions that a user can call explicitly. Calling a validator on - a function actually written in some other language was not checked - for and could be exploited for privilege-escalation purposes. - The fix involves adding a call to a privilege-checking function in - each validator function. Non-core procedural languages will also - need to make this change to their own validator functions, if any. - (CVE-2014-0061) - - - - - - - - Avoid multiple name lookups during table and index DDL - (Robert Haas, Andres Freund) - - - - If the name lookups come to different conclusions due to concurrent - activity, we might perform some parts of the DDL on a different table - than other parts. At least in the case of CREATE INDEX, - this can be used to cause the permissions checks to be performed - against a different table than the index creation, allowing for a - privilege escalation attack. - (CVE-2014-0062) - - - - - - - - Prevent buffer overrun with long datetime strings (Noah Misch) - - - - The MAXDATELEN constant was too small for the longest - possible value of type interval, allowing a buffer overrun - in interval_out(). Although the datetime input - functions were more careful about avoiding buffer overrun, the limit - was short enough to cause them to reject some valid inputs, such as - input containing a very long timezone name. The ecpg - library contained these vulnerabilities along with some of its own. - (CVE-2014-0063) - - - - - - - - Prevent buffer overrun due to integer overflow in size calculations - (Noah Misch, Heikki Linnakangas) - - - - Several functions, mostly type input functions, calculated an - allocation size without checking for overflow. If overflow did - occur, a too-small buffer would be allocated and then written past. - (CVE-2014-0064) - - - - - - - - Prevent overruns of fixed-size buffers - (Peter Eisentraut, Jozef Mlich) - - - - Use strlcpy() and related functions to provide a clear - guarantee that fixed-size buffers are not overrun. Unlike the - preceding items, it is unclear whether these cases really represent - live issues, since in most cases there appear to be previous - constraints on the size of the input string. Nonetheless it seems - prudent to silence all Coverity warnings of this type. - (CVE-2014-0065) - - - - - - - - Avoid crashing if crypt() returns NULL (Honza Horak, - Bruce Momjian) - - - - There are relatively few scenarios in which crypt() - could return NULL, but contrib/chkpass would crash - if it did. One practical case in which this could be an issue is - if libc is configured to refuse to execute unapproved - hashing algorithms (e.g., FIPS mode). - (CVE-2014-0066) - - - - - - - - Document risks of make check in the regression testing - instructions (Noah Misch, Tom Lane) - - - - Since the temporary server started by make check - uses trust authentication, another user on the same machine - could connect to it as database superuser, and then potentially - exploit the privileges of the operating-system user who started the - tests. A future release will probably incorporate changes in the - testing procedure to prevent this risk, but some public discussion is - needed first. So for the moment, just warn people against using - make check when there are untrusted users on the - same machine. - (CVE-2014-0067) - - - - - - - - Rework tuple freezing protocol - (Álvaro Herrera, Andres Freund) - - - - The logic for tuple freezing was unable to handle some cases involving - freezing of - multixact - IDs, with the practical effect that shared row-level locks - might be forgotten once old enough. - - - - Fixing this required changing the WAL record format for tuple - freezing. While this is no issue for standalone servers, when using - replication it means that standby servers must be upgraded - to 9.3.3 or later before their masters are. An older standby will - be unable to interpret freeze records generated by a newer master, and - will fail with a PANIC message. (In such a case, upgrading the - standby should be sufficient to let it resume execution.) - - - - - - - - Create separate GUC parameters to control multixact freezing - (Álvaro Herrera) - - - - 9.3 requires multixact tuple labels to be frozen before - they grow too old, in the same fashion as plain transaction ID labels - have been frozen for some time. Previously, the transaction ID - freezing parameters were used for multixact IDs too; but since - the consumption rates of transaction IDs and multixact IDs can be - quite different, this did not work very well. Introduce new settings - , - , and - - to control when to freeze multixacts. - - - - - - - - Account for remote row locks propagated by local updates - (Álvaro Herrera) - - - - If a row was locked by transaction A, and transaction B updated it, - the new version of the row created by B would be locked by A, yet - visible only to B. If transaction B then again updated the row, A's - lock wouldn't get checked, thus possibly allowing B to complete when - it shouldn't. This case is new in 9.3 since prior versions did not - have any types of row locking that would permit another transaction - to update the row at all. - - - - This oversight could allow referential integrity checks to give false - positives (for instance, allow deletes that should have been rejected). - Applications using the new commands SELECT FOR KEY SHARE - and SELECT FOR NO KEY UPDATE might also have suffered - locking failures of this kind. - - - - - - - - Prevent forgetting valid row locks when one of several - holders of a row lock aborts (Álvaro Herrera) - - - - This was yet another mechanism by which a shared row lock could be - lost, thus possibly allowing updates that should have been prevented - by foreign-key constraints. - - - - - - - - Fix incorrect logic during update chain locking - (Álvaro Herrera) - - - - This mistake could result in spurious could not serialize access - due to concurrent update errors in REPEATABLE READ - and SERIALIZABLE transaction isolation modes. - - - - - - - - Handle wraparound correctly during extension or truncation - of pg_multixact/members - (Andres Freund, Álvaro Herrera) - - - - - - - - Fix handling of 5-digit filenames in pg_multixact/members - (Álvaro Herrera) - - - - As of 9.3, these names can be more than 4 digits, but the directory - cleanup code ignored such files. - - - - - - - - Improve performance of multixact cache code - (Álvaro Herrera) - - - - - - - - Optimize updating a row that's already locked by the same transaction - (Andres Freund, Álvaro Herrera) - - - - This fixes a performance regression from pre-9.3 versions when doing - SELECT FOR UPDATE followed by UPDATE/DELETE. - - - - - - - - During archive recovery, prefer highest timeline number when WAL - segments with the same ID are present in both the archive - and pg_xlog/ (Kyotaro Horiguchi) - - - - Previously, not-yet-archived segments could get ignored during - recovery. This reverts an undesirable behavioral change in 9.3.0 - back to the way things worked pre-9.3. - - - - - - - - Fix possible mis-replay of WAL records when some segments of a - relation aren't full size (Greg Stark, Tom Lane) - - - - The WAL update could be applied to the wrong page, potentially many - pages past where it should have been. Aside from corrupting data, - this error has been observed to result in significant bloat - of standby servers compared to their masters, due to updates being - applied far beyond where the end-of-file should have been. This - failure mode does not appear to be a significant risk during crash - recovery, only when initially synchronizing a standby created from a - base backup taken from a quickly-changing master. - - - - - - - - Fix bug in determining when recovery has reached consistency - (Tomonari Katsumata, Heikki Linnakangas) - - - - In some cases WAL replay would mistakenly conclude that the database - was already consistent at the start of replay, thus possibly allowing - hot-standby queries before the database was really consistent. Other - symptoms such as PANIC: WAL contains references to invalid - pages were also possible. - - - - - - - - Fix WAL logging of visibility map changes (Heikki Linnakangas) - - - - - - - - Fix improper locking of btree index pages while replaying - a VACUUM operation in hot-standby mode (Andres Freund, - Heikki Linnakangas, Tom Lane) - - - - This error could result in PANIC: WAL contains references to - invalid pages failures. - - - - - - - - Ensure that insertions into non-leaf GIN index pages write a full-page - WAL record when appropriate (Heikki Linnakangas) - - - - The previous coding risked index corruption in the event of a - partial-page write during a system crash. - - - - - - - - When pause_at_recovery_target - and recovery_target_inclusive are both set, ensure the - target record is applied before pausing, not after (Heikki - Linnakangas) - - - - - - - - Ensure walreceiver sends hot-standby feedback messages on time even - when there is a continuous stream of data (Andres Freund, Amit - Kapila) - - - - - - - - Prevent timeout interrupts from taking control away from mainline - code unless ImmediateInterruptOK is set - (Andres Freund, Tom Lane) - - - - This is a serious issue for any application making use of statement - timeouts, as it could cause all manner of strange failures after a - timeout occurred. We have seen reports of stuck spinlocks, - ERRORs being unexpectedly promoted to PANICs, unkillable backends, - and other misbehaviors. - - - - - - - - Fix race conditions during server process exit (Robert Haas) - - - - Ensure that signal handlers don't attempt to use the - process's MyProc pointer after it's no longer valid. - - - - - - - - Fix race conditions in walsender shutdown logic and walreceiver - SIGHUP signal handler (Tom Lane) - - - - - - - - Fix unsafe references to errno within error reporting - logic (Christian Kruse) - - - - This would typically lead to odd behaviors such as missing or - inappropriate HINT fields. - - - - - - - - Fix possible crashes from using ereport() too early - during server startup (Tom Lane) - - - - The principal case we've seen in the field is a crash if the server - is started in a directory it doesn't have permission to read. - - - - - - - - Clear retry flags properly in OpenSSL socket write - function (Alexander Kukushkin) - - - - This omission could result in a server lockup after unexpected loss - of an SSL-encrypted connection. - - - - - - - - Fix length checking for Unicode identifiers (U&"..." - syntax) containing escapes (Tom Lane) - - - - A spurious truncation warning would be printed for such identifiers - if the escaped form of the identifier was too long, but the - identifier actually didn't need truncation after de-escaping. - - - - - - - - Fix parsing of Unicode literals and identifiers just before the end - of a command string or function body (Tom Lane) - - - - - - - - Allow keywords that are type names to be used in lists of roles - (Stephen Frost) - - - - A previous patch allowed such keywords to be used without quoting - in places such as role identifiers; but it missed cases where a - list of role identifiers was permitted, such as DROP ROLE. - - - - - - - - Fix parser crash for EXISTS(SELECT * FROM - zero_column_table) (Tom Lane) - - - - - - - - Fix possible crash due to invalid plan for nested sub-selects, such - as WHERE (... x IN (SELECT ...) ...) IN (SELECT ...) - (Tom Lane) - - - - - - - - Fix mishandling of WHERE conditions pulled up from - a LATERAL subquery (Tom Lane) - - - - The typical symptom of this bug was a JOIN qualification - cannot refer to other relations error, though subtle logic - errors in created plans seem possible as well. - - - - - - - - Disallow LATERAL references to the target table of - an UPDATE/DELETE (Tom Lane) - - - - While this might be allowed in some future release, it was - unintentional in 9.3, and didn't work quite right anyway. - - - - - - - - Fix UPDATE/DELETE of an inherited target table - that has UNION ALL subqueries (Tom Lane) - - - - Without this fix, UNION ALL subqueries aren't correctly - inserted into the update plans for inheritance child tables after the - first one, typically resulting in no update happening for those child - table(s). - - - - - - - - Fix ANALYZE to not fail on a column that's a domain over - a range type (Tom Lane) - - - - - - - - Ensure that ANALYZE creates statistics for a table column - even when all the values in it are too wide (Tom Lane) - - - - ANALYZE intentionally omits very wide values from its - histogram and most-common-values calculations, but it neglected to do - something sane in the case that all the sampled entries are too wide. - - - - - - - - In ALTER TABLE ... SET TABLESPACE, allow the database's - default tablespace to be used without a permissions check - (Stephen Frost) - - - - CREATE TABLE has always allowed such usage, - but ALTER TABLE didn't get the memo. - - - - - - - - Fix support for extensions containing event triggers (Tom Lane) - - - - - - - - Fix cannot accept a set error when some arms of - a CASE return a set and others don't (Tom Lane) - - - - - - - - Fix memory leakage in JSON functions (Craig Ringer) - - - - - - - - Properly distinguish numbers from non-numbers when generating JSON - output (Andrew Dunstan) - - - - - - - - Fix checks for all-zero client addresses in pgstat functions (Kevin - Grittner) - - - - - - - - Fix possible misclassification of multibyte characters by the text - search parser (Tom Lane) - - - - Non-ASCII characters could be misclassified when using C locale with - a multibyte encoding. On Cygwin, non-C locales could fail as well. - - - - - - - - Fix possible misbehavior in plainto_tsquery() - (Heikki Linnakangas) - - - - Use memmove() not memcpy() for copying - overlapping memory regions. There have been no field reports of - this actually causing trouble, but it's certainly risky. - - - - - - - - Fix placement of permissions checks in pg_start_backup() - and pg_stop_backup() (Andres Freund, Magnus Hagander) - - - - The previous coding might attempt to do catalog access when it - shouldn't. - - - - - - - - Accept SHIFT_JIS as an encoding name for locale checking - purposes (Tatsuo Ishii) - - - - - - - - Fix *-qualification of named parameters in SQL-language - functions (Tom Lane) - - - - Given a composite-type parameter - named foo, $1.* worked fine, - but foo.* not so much. - - - - - - - - Fix misbehavior of PQhost() on Windows (Fujii Masao) - - - - It should return localhost if no host has been specified. - - - - - - - - Improve error handling in libpq and psql - for failures during COPY TO STDOUT/FROM STDIN (Tom Lane) - - - - In particular this fixes an infinite loop that could occur in 9.2 and - up if the server connection was lost during COPY FROM - STDIN. Variants of that scenario might be possible in older - versions, or with other client applications. - - - - - - - - Fix incorrect translation handling in - some psql \d commands - (Peter Eisentraut, Tom Lane) - - - - - - - - Ensure pg_basebackup's background process is killed - when exiting its foreground process (Magnus Hagander) - - - - - - - - Fix possible incorrect printing of filenames - in pg_basebackup's verbose mode (Magnus Hagander) - - - - - - - - Avoid including tablespaces inside PGDATA twice in base backups - (Dimitri Fontaine, Magnus Hagander) - - - - - - - - Fix misaligned descriptors in ecpg (MauMau) - - - - - - - - In ecpg, handle lack of a hostname in the connection - parameters properly (Michael Meskes) - - - - - - - - Fix performance regression in contrib/dblink connection - startup (Joe Conway) - - - - Avoid an unnecessary round trip when client and server encodings match. - - - - - - - - In contrib/isn, fix incorrect calculation of the check - digit for ISMN values (Fabien Coelho) - - - - - - - - Fix contrib/pgbench's progress logging to avoid overflow - when the scale factor is large (Tatsuo Ishii) - - - - - - - - Fix contrib/pg_stat_statement's handling - of CURRENT_DATE and related constructs (Kyotaro - Horiguchi) - - - - - - - - Improve lost-connection error handling - in contrib/postgres_fdw (Tom Lane) - - - - - - - - Ensure client-code-only installation procedure works as documented - (Peter Eisentraut) - - - - - - - - In Mingw and Cygwin builds, install the libpq DLL - in the bin directory (Andrew Dunstan) - - - - This duplicates what the MSVC build has long done. It should fix - problems with programs like psql failing to start - because they can't find the DLL. - - - - - - - - Avoid using the deprecated dllwrap tool in Cygwin builds - (Marco Atzeri) - - - - - - - - Enable building with Visual Studio 2013 (Brar Piening) - - - - - - - - Don't generate plain-text HISTORY - and src/test/regress/README files anymore (Tom Lane) - - - - These text files duplicated the main HTML and PDF documentation - formats. The trouble involved in maintaining them greatly outweighs - the likely audience for plain-text format. Distribution tarballs - will still contain files by these names, but they'll just be stubs - directing the reader to consult the main documentation. - The plain-text INSTALL file will still be maintained, as - there is arguably a use-case for that. - - - - - - - - Update time zone data files to tzdata release 2013i - for DST law changes in Jordan and historical changes in Cuba. - - - - In addition, the zones Asia/Riyadh87, - Asia/Riyadh88, and Asia/Riyadh89 have been - removed, as they are no longer maintained by IANA, and never - represented actual civil timekeeping practice. - - - - - - - - - - Release 9.3.2 - - - Release date: - 2013-12-05 - - - - This release contains a variety of fixes from 9.3.1. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.2 - - - A dump/restore is not required for those running 9.3.X. - - - - However, this release corrects a number of potential data corruption - issues. See the first three changelog entries below to find out whether - your installation has been affected and what steps you can take if so. - - - - Also, if you are upgrading from a version earlier than 9.3.1, - see . - - - - - - Changes - - - - - - Fix VACUUM's tests to see whether it can - update relfrozenxid (Andres Freund) - - - - In some cases VACUUM (either manual or autovacuum) could - incorrectly advance a table's relfrozenxid value, - allowing tuples to escape freezing, causing those rows to become - invisible once 2^31 transactions have elapsed. The probability of - data loss is fairly low since multiple incorrect advancements would - need to happen before actual loss occurs, but it's not zero. In 9.2.0 - and later, the probability of loss is higher, and it's also possible - to get could not access status of transaction errors as a - consequence of this bug. Users upgrading from releases 9.0.4 or 8.4.8 - or earlier are not affected, but all later versions contain the bug. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix any latent corruption but will not be able - to fix all pre-existing data errors. However, an installation can be - presumed safe after performing this vacuuming if it has executed fewer - than 2^31 update transactions in its lifetime (check this with - SELECT txid_current() < 2^31). - - - - - - Fix multiple bugs in MultiXactId freezing (Andres Freund, - Álvaro Herrera) - - - - These bugs could lead to could not access status of - transaction errors, or to duplicate or vanishing rows. - Users upgrading from releases prior to 9.3.0 are not affected. - - - - The issue can be ameliorated by, after upgrading, vacuuming all tables - in all databases while having vacuum_freeze_table_age - set to zero. This will fix latent corruption but will not be able to - fix all pre-existing data errors. - - - - As a separate issue, these bugs can also cause standby servers to get - out of sync with the primary, thus exhibiting data errors that are not - in the primary. Therefore, it's recommended that 9.3.0 and 9.3.1 - standby servers be re-cloned from the primary (e.g., with a new base - backup) after upgrading. - - - - - - Fix initialization of pg_clog and pg_subtrans - during hot standby startup (Andres Freund, Heikki Linnakangas) - - - - This bug can cause data loss on standby servers at the moment they - start to accept hot-standby queries, by marking committed transactions - as uncommitted. The likelihood of such corruption is small unless, at - the time of standby startup, the primary server has executed many - updating transactions since its last checkpoint. Symptoms include - missing rows, rows that should have been deleted being still visible, - and obsolete versions of updated rows being still visible alongside - their newer versions. - - - - This bug was introduced in versions 9.3.0, 9.2.5, 9.1.10, and 9.0.14. - Standby servers that have only been running earlier releases are not - at risk. It's recommended that standby servers that have ever run any - of the buggy releases be re-cloned from the primary (e.g., with a new - base backup) after upgrading. - - - - - - Fix multiple bugs in update chain traversal (Andres Freund, - Álvaro Herrera) - - - - These bugs could result in incorrect behavior, such as locking or even - updating the wrong row, in the presence of concurrent updates. - Spurious unable to fetch updated version of tuple errors - were also possible. - - - - - - Fix dangling-pointer problem in fast-path locking (Tom Lane) - - - - This could lead to corruption of the lock data structures in shared - memory, causing lock already held and other odd errors. - - - - - - Fix assorted race conditions in timeout management (Tom Lane) - - - - These errors could result in a server process becoming unresponsive - because it had blocked SIGALRM and/or SIGINT. - - - - - - Truncate pg_multixact contents during WAL replay - (Andres Freund) - - - - This avoids ever-increasing disk space consumption in standby servers. - - - - - - Ensure an anti-wraparound VACUUM counts a page as scanned - when it's only verified that no tuples need freezing (Sergey - Burladyan, Jeff Janes) - - - - This bug could result in failing to - advance relfrozenxid, so that the table would still be - thought to need another anti-wraparound vacuum. In the worst case the - database might even shut down to prevent wraparound. - - - - - - Fix full-table-vacuum request mechanism for MultiXactIds (Andres Freund) - - - - This bug could result in large amounts of useless autovacuum activity. - - - - - - Fix race condition in GIN index posting tree page deletion (Heikki - Linnakangas) - - - - This could lead to transient wrong answers or query failures. - - - - - - Fix unexpected spgdoinsert() failure error during SP-GiST - index creation (Teodor Sigaev) - - - - - - Fix assorted bugs in materialized views (Kevin Grittner, Andres Freund) - - - - - - Re-allow duplicate table aliases if they're within aliased JOINs - (Tom Lane) - - - - Historically PostgreSQL has accepted queries like - -SELECT ... FROM tab1 x CROSS JOIN (tab2 x CROSS JOIN tab3 y) z - - although a strict reading of the SQL standard would forbid the - duplicate usage of table alias x. A misguided change in - 9.3.0 caused it to reject some such cases that were formerly accepted. - Restore the previous behavior. - - - - - - Avoid flattening a subquery whose SELECT list contains a - volatile function wrapped inside a sub-SELECT (Tom Lane) - - - - This avoids unexpected results due to extra evaluations of the - volatile function. - - - - - - Fix planner's processing of non-simple-variable subquery outputs - nested within outer joins (Tom Lane) - - - - This error could lead to incorrect plans for queries involving - multiple levels of subqueries within JOIN syntax. - - - - - - Fix incorrect planning in cases where the same non-strict expression - appears in multiple WHERE and outer JOIN - equality clauses (Tom Lane) - - - - - - Fix planner crash with whole-row reference to a subquery (Tom Lane) - - - - - - Fix incorrect generation of optimized MIN()/MAX() plans for - inheritance trees (Tom Lane) - - - - The planner could fail in cases where the MIN()/MAX() argument was an - expression rather than a simple variable. - - - - - - Fix premature deletion of temporary files (Andres Freund) - - - - - - Prevent intra-transaction memory leak when printing range values - (Tom Lane) - - - - This fix actually cures transient memory leaks in any datatype output - function, but range types are the only ones known to have had a - significant problem. - - - - - - Fix memory leaks when reloading configuration files (Heikki - Linnakangas, Hari Babu) - - - - - - Prevent incorrect display of dropped columns in NOT NULL and CHECK - constraint violation messages (Michael Paquier and Tom Lane) - - - - - - Allow default arguments and named-argument notation for window - functions (Tom Lane) - - - - Previously, these cases were likely to crash. - - - - - - Suppress trailing whitespace on each line when pretty-printing rules - and views (Tom Lane) - - - - 9.3.0 generated such whitespace in many more cases than previous - versions did. To reduce unexpected behavioral changes, suppress - unnecessary whitespace in all cases. - - - - - - Fix possible read past end of memory in rule printing (Peter Eisentraut) - - - - - - Fix array slicing of int2vector and oidvector values - (Tom Lane) - - - - Expressions of this kind are now implicitly promoted to - regular int2 or oid arrays. - - - - - - Return a valid JSON value when converting an empty hstore value - to json - (Oskari Saarenmaa) - - - - - - Fix incorrect behaviors when using a SQL-standard, simple GMT offset - timezone (Tom Lane) - - - - In some cases, the system would use the simple GMT offset value when - it should have used the regular timezone setting that had prevailed - before the simple offset was selected. This change also causes - the timeofday function to honor the simple GMT offset - zone. - - - - - - Prevent possible misbehavior when logging translations of Windows - error codes (Tom Lane) - - - - - - Properly quote generated command lines in pg_ctl - (Naoya Anzai and Tom Lane) - - - - This fix applies only to Windows. - - - - - - Fix pg_dumpall to work when a source database - sets default_transaction_read_only - via ALTER DATABASE SET (Kevin Grittner) - - - - Previously, the generated script would fail during restore. - - - - - - Fix pg_isready to handle its option - properly (Fabrízio de Royes Mello and Fujii Masao) - - - - - - Fix parsing of WAL file names in pg_receivexlog - (Heikki Linnakangas) - - - - This error made pg_receivexlog unable to restart - streaming after stopping, once at least 4 GB of WAL had been written. - - - - - - Report out-of-disk-space failures properly - in pg_upgrade (Peter Eisentraut) - - - - - - Make ecpg search for quoted cursor names - case-sensitively (Zoltán Böszörményi) - - - - - - Fix ecpg's processing of lists of variables - declared varchar (Zoltán Böszörményi) - - - - - - Make contrib/lo defend against incorrect trigger definitions - (Marc Cousin) - - - - - - Update time zone data files to tzdata release 2013h - for DST law changes in Argentina, Brazil, Jordan, Libya, - Liechtenstein, Morocco, and Palestine. Also, new timezone - abbreviations WIB, WIT, WITA for Indonesia. - - - - - - - - - - Release 9.3.1 - - - Release date: - 2013-10-10 - - - - This release contains a variety of fixes from 9.3.0. - For information about new features in the 9.3 major release, see - . - - - - Migration to Version 9.3.1 - - - A dump/restore is not required for those running 9.3.X. - - - - However, if you use the hstore extension, see the - first changelog entry. - - - - - - Changes - - - - - - Ensure new-in-9.3 JSON functionality is added to the hstore - extension during an update (Andrew Dunstan) - - - - Users who upgraded a pre-9.3 database containing hstore - should execute - -ALTER EXTENSION hstore UPDATE; - - after installing 9.3.1, to add two new JSON functions and a cast. - (If hstore is already up to date, this command does - nothing.) - - - - - - Fix memory leak when creating B-tree indexes on range columns - (Heikki Linnakangas) - - - - - - Fix memory leak caused by lo_open() failure - (Heikki Linnakangas) - - - - - - Serializable snapshot fixes (Kevin Grittner, Heikki Linnakangas) - - - - - - Fix deadlock bug in libpq when using SSL (Stephen Frost) - - - - - - Fix timeline handling bugs in pg_receivexlog - (Heikki Linnakangas, Andrew Gierth) - - - - - - Prevent CREATE FUNCTION from checking SET - variables unless function body checking is enabled (Tom Lane) - - - - - - Remove rare inaccurate warning during vacuum of index-less tables - (Heikki Linnakangas) - - - - - - - - - - Release 9.3 - - - Release date: - 2013-09-09 - - - - Overview - - - Major enhancements in PostgreSQL 9.3 include: - - - - - - - - - Add materialized - views - - - - - - Make simple views auto-updatable - - - - - - Add many features for the JSON data type, - including operators and functions - to extract elements from JSON values - - - - - - Implement SQL-standard LATERAL option for - FROM-clause subqueries and function calls - - - - - - Allow foreign data - wrappers to support writes (inserts/updates/deletes) on foreign - tables - - - - - - Add a Postgres foreign - data wrapper to allow access to - other Postgres servers - - - - - - Add support for event triggers - - - - - - Add optional ability to checksum data pages and - report corruption - - - - - - Prevent non-key-field row updates from blocking foreign key checks - - - - - - Greatly reduce System V shared - memory requirements - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.3 - - - A dump/restore using pg_dumpall, or use - of pg_upgrade, is - required for those wishing to migrate data from any previous release. - - - - Version 9.3 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - Server Settings - - - - - - Rename replication_timeout to wal_sender_timeout - (Amit Kapila) - - - - This setting controls the WAL sender timeout. - - - - - - Require superuser privileges to set commit_delay - because it can now potentially delay other sessions (Simon Riggs) - - - - - - Allow in-memory sorts to use their full memory allocation (Jeff Janes) - - - - Users who have set work_mem based on the - previous behavior may need to revisit that setting. - - - - - - - - - Other - - - - - - Throw an error if a tuple to be updated or deleted has already been - updated or deleted by a BEFORE trigger (Kevin Grittner) - - - - Formerly, the originally-intended update was silently skipped, - resulting in logical inconsistency since the trigger might have - propagated data to other places based on the intended update. - Now an error is thrown to prevent the inconsistent results from being - committed. If this change affects your application, the best solution - is usually to move the data-propagation actions to - an AFTER trigger. - - - - This error will also be thrown if a query invokes a volatile function - that modifies rows that are later modified by the query itself. - Such cases likewise previously resulted in silently skipping updates. - - - - - - Change multicolumn ON UPDATE - SET NULL/SET DEFAULT foreign key actions to affect - all columns of the constraint, not just those changed in the - UPDATE (Tom Lane) - - - - Previously, we would set only those referencing columns that - correspond to referenced columns that were changed by - the UPDATE. This was what was required by SQL-92, - but more recent editions of the SQL standard specify the new behavior. - - - - - - Force cached plans to be replanned if the search_path changes - (Tom Lane) - - - - Previously, cached plans already generated in the current session were - not redone if the query was re-executed with a - new search_path setting, resulting in surprising behavior. - - - - - - Fix to_number() - to properly handle a period used as a thousands separator (Tom Lane) - - - - Previously, a period was considered to be a decimal point even when - the locale says it isn't and the D format code is used to - specify use of the locale-specific decimal point. This resulted in - wrong answers if FM format was also used. - - - - - - Fix STRICT non-set-returning functions that have - set-returning functions in their arguments to properly return null - rows (Tom Lane) - - - - A null value passed to the strict function should result in a null - output, but instead, that output row was suppressed entirely. - - - - - - Store WAL in a continuous - stream, rather than skipping the last 16MB segment every 4GB - (Heikki Linnakangas) - - - - Previously, WAL files with names ending in FF - were not used because of this skipping. If you have WAL - backup or restore scripts that took this behavior into account, they - will need to be adjusted. - - - - - - In pg_constraint.confmatchtype, - store the default foreign key match type (non-FULL, - non-PARTIAL) as s for simple - (Tom Lane) - - - - Previously this case was represented by u - for unspecified. - - - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.3 and the previous major - release. - - - - Server - - - Locking - - - - - - Prevent non-key-field row updates from blocking foreign key checks - (Álvaro Herrera, Noah Misch, Andres Freund, Alexander - Shulgin, Marti Raudsepp, Alexander Shulgin) - - - - This change improves concurrency and reduces the probability of - deadlocks when updating tables involved in a foreign-key constraint. - UPDATEs that do not change any columns referenced in a - foreign key now take the new NO KEY UPDATE lock mode on - the row, while foreign key checks use the new KEY SHARE - lock mode, which does not conflict with NO KEY UPDATE. - So there is no blocking unless a foreign-key column is changed. - - - - - - Add configuration variable lock_timeout to - allow limiting how long a session will wait to acquire any one lock - (Zoltán Böszörményi) - - - - - - - - - Indexes - - - - - - Add SP-GiST - support for range data types (Alexander Korotkov) - - - - - - Allow GiST indexes to be - unlogged (Jeevan Chalke) - - - - - - Improve performance of GiST index insertion by randomizing - the choice of which page to descend to when there are multiple equally - good alternatives (Heikki Linnakangas) - - - - - - Improve concurrency of hash index operations (Robert Haas) - - - - - - - - - Optimizer - - - - - - Collect and use histograms of upper and lower bounds, as well as range - lengths, for range types - (Alexander Korotkov) - - - - - - Improve optimizer's cost estimation for index access (Tom Lane) - - - - - - Improve optimizer's hash table size estimate for - doing DISTINCT via hash aggregation (Tom Lane) - - - - - - Suppress no-op Result and Limit plan nodes - (Kyotaro Horiguchi, Amit Kapila, Tom Lane) - - - - - - Reduce optimizer overhead by not keeping plans on the basis of cheap - startup cost when the optimizer only cares about total cost overall - (Tom Lane) - - - - - - - - - General Performance - - - - - - Add COPY FREEZE - option to avoid the overhead of marking tuples as frozen later - (Simon Riggs, Jeff Davis) - - - - - - Improve performance of NUMERIC calculations - (Kyotaro Horiguchi) - - - - - - Improve synchronization of sessions waiting for commit_delay - (Peter Geoghegan) - - - - This greatly improves the usefulness of commit_delay. - - - - - - Improve performance of the CREATE TEMPORARY TABLE ... ON - COMMIT DELETE ROWS option by not truncating such temporary - tables in transactions that haven't touched any temporary tables - (Heikki Linnakangas) - - - - - - Make vacuum recheck visibility after it has removed expired tuples - (Pavan Deolasee) - - - - This increases the chance of a page being marked as all-visible. - - - - - - Add per-resource-owner lock caches (Jeff Janes) - - - - This speeds up lock bookkeeping at statement completion in - multi-statement transactions that hold many locks; it is particularly - useful for pg_dump. - - - - - - Avoid scanning the entire relation cache at commit of a transaction - that creates a new relation (Jeff Janes) - - - - This speeds up sessions that create many tables in successive - small transactions, such as a pg_restore run. - - - - - - Improve performance of transactions that drop many relations - (Tomas Vondra) - - - - - - - - - Monitoring - - - - - - Add optional ability to checksum data pages and - report corruption (Simon Riggs, Jeff Davis, Greg Smith, Ants Aasma) - - - - The checksum option can be set during initdb. - - - - - - Split the statistics collector's - data file into separate global and per-database files (Tomas Vondra) - - - - This reduces the I/O required for statistics tracking. - - - - - - Fix the statistics collector to operate properly in cases where the - system clock goes backwards (Tom Lane) - - - - Previously, statistics collection would stop until the time again - reached the latest time previously recorded. - - - - - - Emit an informative message to postmaster standard error when we - are about to stop logging there - (Tom Lane) - - - - This should help reduce user confusion about where to look for log - output in common configurations that log to standard error only during - postmaster startup. - - - - - - - - - Authentication - - - - - - When an authentication failure occurs, log the relevant - pg_hba.conf - line, to ease debugging of unintended failures - (Magnus Hagander) - - - - - - Improve LDAP error - reporting and documentation (Peter Eisentraut) - - - - - - Add support for specifying LDAP authentication parameters - in URL format, per RFC 4516 (Peter Eisentraut) - - - - - - Change the ssl_ciphers parameter - to start with DEFAULT, rather than ALL, - then remove insecure ciphers (Magnus Hagander) - - - - This should yield a more appropriate SSL cipher set. - - - - - - Parse and load pg_ident.conf - once, not during each connection (Amit Kapila) - - - - This is similar to how pg_hba.conf is processed. - - - - - - - - - Server Settings - - - - - - Greatly reduce System V shared - memory requirements (Robert Haas) - - - - On Unix-like systems, mmap() is now used for most - of PostgreSQL's shared memory. For most users, this - will eliminate any need to adjust kernel parameters for shared memory. - - - - - - Allow the postmaster to listen on multiple Unix-domain sockets - (Honza Horák) - - - - The configuration parameter - unix_socket_directory is replaced by unix_socket_directories, - which accepts a list of directories. - - - - - - Allow a directory of configuration files to be processed (Magnus - Hagander, Greg Smith, Selena Deckelmann) - - - - Such a directory is specified with include_dir in the server - configuration file. - - - - - - Increase the maximum initdb-configured value for shared_buffers - to 128MB (Robert Haas) - - - - This is the maximum value that initdb will attempt to set in postgresql.conf; - the previous maximum was 32MB. - - - - - - Remove the external - PID file, if any, on postmaster exit - (Peter Eisentraut) - - - - - - - - - - - Replication and Recovery - - - - - - Allow a streaming replication standby to follow a timeline switch - (Heikki Linnakangas) - - - - This allows streaming standby servers to receive WAL data from a slave - newly promoted to master status. Previously, other standbys would - require a resync to begin following the new master. - - - - - - Add SQL functions pg_is_in_backup() - and pg_backup_start_time() - (Gilles Darold) - - - - These functions report the status of base backups. - - - - - - Improve performance of streaming log shipping with synchronous_commit - disabled (Andres Freund) - - - - - - Allow much faster promotion of a streaming standby to primary (Simon - Riggs, Kyotaro Horiguchi) - - - - - - Add the last checkpoint's redo location to pg_controldata's - output (Fujii Masao) - - - - This information is useful for determining which WAL - files are needed for restore. - - - - - - Allow tools like pg_receivexlog - to run on computers with different architectures (Heikki - Linnakangas) - - - - WAL files can still only be replayed on servers with the same - architecture as the primary; but they can now be transmitted to and - stored on machines of any architecture, since the - streaming replication protocol is now machine-independent. - - - - - - Make pg_basebackup - output a - minimal recovery.conf file (Zoltán - Böszörményi, Magnus Hagander) - - - - This simplifies setting up a standby server. - - - - - - Allow pg_receivexlog - and pg_basebackup - to handle streaming timeline switches - (Heikki Linnakangas) - - - - - - Add wal_receiver_timeout - parameter to control the WAL receiver's timeout - (Amit Kapila) - - - - This allows more rapid detection of connection failure. - - - - - - Change the WAL record format to - allow splitting the record header across pages (Heikki Linnakangas) - - - - The new format is slightly more compact, and is more efficient to - write. - - - - - - - - - Queries - - - - - - Implement SQL-standard LATERAL option for - FROM-clause subqueries and function calls (Tom Lane) - - - - This feature allows subqueries and functions in FROM to - reference columns from other tables in the FROM - clause. The LATERAL keyword is optional for functions. - - - - - - Add support for piping COPY and psql \copy - data to/from an external program (Etsuro Fujita) - - - - - - Allow a multirow VALUES clause in a rule - to reference OLD/NEW (Tom Lane) - - - - - - - - - Object Manipulation - - - - - - Add support for event triggers - (Dimitri Fontaine, Robert Haas, Álvaro Herrera) - - - - This allows server-side functions written in event-enabled - languages to be called when DDL commands are run. - - - - - - Allow foreign data - wrappers to support writes (inserts/updates/deletes) on foreign - tables (KaiGai Kohei) - - - - - - Add CREATE SCHEMA ... IF - NOT EXISTS clause (Fabrízio de Royes Mello) - - - - - - Make REASSIGN - OWNED also change ownership of shared objects - (Álvaro Herrera) - - - - - - Make CREATE - AGGREGATE complain if the given initial value string is not - valid input for the transition datatype (Tom Lane) - - - - - - Suppress CREATE - TABLE's messages about implicit index and sequence creation - (Robert Haas) - - - - These messages now appear at DEBUG1 verbosity, so that - they will not be shown by default. - - - - - - Allow DROP TABLE IF - EXISTS to succeed when a non-existent schema is specified - in the table name (Bruce Momjian) - - - - Previously, it threw an error if the schema did not exist. - - - - - - Provide clients with constraint violation details - as separate fields (Pavel Stehule) - - - - This allows clients to retrieve table, column, data type, or - constraint name error details. Previously such information had to be - extracted from error strings. Client library support is required to - access these fields. - - - - - - - <command>ALTER</command> - - - - - - Support IF NOT EXISTS option in ALTER TYPE ... ADD VALUE - (Andrew Dunstan) - - - - This is useful for conditionally adding values to enumerated types. - - - - - - Add ALTER ROLE ALL - SET to establish settings for all users (Peter Eisentraut) - - - - This allows settings to apply to all users in all databases. ALTER DATABASE SET - already allowed addition of settings for all users in a single - database. postgresql.conf has a similar effect. - - - - - - Add support for ALTER RULE - ... RENAME (Ali Dar) - - - - - - - - - <link linkend="rules-views"><command>VIEWs</command></link> - - - - - - Add materialized - views (Kevin Grittner) - - - - Unlike ordinary views, where the base tables are read on every access, - materialized views create physical tables at creation or refresh time. - Access to the materialized view then reads from its physical - table. There is not yet any facility for incrementally refreshing - materialized views or auto-accessing them via base table access. - - - - - - Make simple views auto-updatable - (Dean Rasheed) - - - - Simple views that reference some or all columns from a - single base table are now updatable by default. More - complex views can be made updatable using INSTEAD OF triggers - or INSTEAD rules. - - - - - - Add CREATE RECURSIVE - VIEW syntax (Peter Eisentraut) - - - - Internally this is translated into CREATE VIEW ... WITH - RECURSIVE .... - - - - - - Improve view/rule printing code to handle cases where referenced - tables are renamed, or columns are renamed, added, or dropped - (Tom Lane) - - - - Table and column renamings can produce cases where, if we merely - substitute the new name into the original text of a rule or view, the - result is ambiguous. This change fixes the rule-dumping code to insert - manufactured table and column aliases when needed to preserve the - original semantics. - - - - - - - - - - - Data Types - - - - - - Increase the maximum size of large - objects from 2GB to 4TB (Nozomi Anzai, Yugo Nagata) - - - - This change includes adding 64-bit-capable large object access - functions, both in the server and in libpq. - - - - - - Allow text timezone - designations, e.g. America/Chicago, in the - T field of ISO-format timestamptz - input (Bruce Momjian) - - - - - - - <link linkend="datatype-json"><type>JSON</type></link> - - - - - - Add operators and functions - to extract elements from JSON values (Andrew Dunstan) - - - - - - Allow JSON values to be converted into records - (Andrew Dunstan) - - - - - - Add functions to convert - scalars, records, and hstore values to JSON (Andrew - Dunstan) - - - - - - - - - - - - Functions - - - - - - Add array_remove() - and array_replace() - functions (Marco Nenciarini, Gabriele Bartolini) - - - - - - Allow concat() - and format() - to properly expand VARIADIC-labeled arguments - (Pavel Stehule) - - - - - - Improve format() - to provide field width and left/right alignment options (Pavel Stehule) - - - - - - Make to_char(), - to_date(), - and to_timestamp() - handle negative (BC) century values properly - (Bruce Momjian) - - - - Previously the behavior was either wrong or inconsistent - with positive/AD handling, e.g. with the format mask - IYYY-IW-DY. - - - - - - Make to_date() - and to_timestamp() - return proper results when mixing ISO and Gregorian - week/day designations (Bruce Momjian) - - - - - - Cause pg_get_viewdef() - to start a new line by default after each SELECT target - list entry and FROM entry (Marko Tiikkaja) - - - - This reduces line length in view printing, for instance in pg_dump output. - - - - - - Fix map_sql_value_to_xml_value() to print values of - domain types the same way their base type would be printed - (Pavel Stehule) - - - - There are special formatting rules for certain built-in types such as - boolean; these rules now also apply to domains over these - types. - - - - - - - - - Server-Side Languages - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - Allow PL/pgSQL to use RETURN with a composite-type - expression (Asif Rehman) - - - - Previously, in a function returning a composite type, - RETURN could only reference a variable of that type. - - - - - - Allow PL/pgSQL to access constraint violation - details as separate fields (Pavel Stehule) - - - - - - Allow PL/pgSQL to access the number of rows processed by - COPY (Pavel Stehule) - - - - A COPY executed in a PL/pgSQL function now updates the - value retrieved by GET DIAGNOSTICS - x = ROW_COUNT. - - - - - - Allow unreserved keywords to be used as identifiers everywhere in - PL/pgSQL (Tom Lane) - - - - In certain places in the PL/pgSQL grammar, keywords had to be quoted - to be used as identifiers, even if they were nominally unreserved. - - - - - - - - - <link linkend="plpython">PL/Python</link> Server-Side Language - - - - - - Add PL/Python result object string handler (Peter Eisentraut) - - - - This allows plpy.debug(rv) to output something reasonable. - - - - - - Make PL/Python convert OID values to a proper Python numeric type - (Peter Eisentraut) - - - - - - Handle SPI errors raised - explicitly (with PL/Python's RAISE) the same as - internal SPI errors (Oskari Saarenmaa and Jan Urbanski) - - - - - - - - - - - Server Programming Interface (<link linkend="spi">SPI</link>) - - - - - - Prevent leakage of SPI tuple tables during subtransaction - abort (Tom Lane) - - - - At the end of any failed subtransaction, the core SPI code now - releases any SPI tuple tables that were created during that - subtransaction. This avoids the need for SPI-using code to keep track - of such tuple tables and release them manually in error-recovery code. - Failure to do so caused a number of transaction-lifespan memory leakage - issues in PL/pgSQL and perhaps other SPI clients. SPI_freetuptable() - now protects itself against multiple freeing requests, so any existing - code that did take care to clean up shouldn't be broken by this change. - - - - - - Allow SPI functions to access the number of rows processed - by COPY (Pavel Stehule) - - - - - - - - - Client Applications - - - - - - Add command-line utility pg_isready to - check if the server is ready to accept connections (Phil Sorber) - - - - - - Support multiple arguments for pg_restore, - clusterdb, - reindexdb, - and vacuumdb - (Josh Kupershmidt) - - - - This is similar to the way pg_dump's - option works. - - - - - - Add option to pg_dumpall, pg_basebackup, and - pg_receivexlog - to allow specifying a connection string (Amit Kapila) - - - - - - Add libpq function PQconninfo() - to return connection information (Zoltán - Böszörményi, Magnus Hagander) - - - - - - - <link linkend="app-psql"><application>psql</application></link> - - - - - - Adjust function cost settings so psql tab - completion and pattern searching are more efficient (Tom Lane) - - - - - - Improve psql's tab completion coverage (Jeff Janes, - Dean Rasheed, Peter Eisentraut, Magnus Hagander) - - - - - - Allow the psql - mode to work when reading from standard input (Fabien Coelho, - Robert Haas) - - - - Previously this option only worked when reading from a file. - - - - - - Remove psql warning when connecting to an older - server (Peter Eisentraut) - - - - A warning is still issued when connecting to a server of a newer major - version than psql's. - - - - - - - <link linkend="app-psql-meta-commands">Backslash Commands</link> - - - - - - Add psql command \watch to repeatedly - execute a SQL command (Will Leinweber) - - - - - - Add psql command \gset to store query - results in psql variables (Pavel Stehule) - - - - - - Add SSL information to psql's - \conninfo command (Alastair Turner) - - - - - - Add Security column to psql's - \df+ output (Jon Erdman) - - - - - - Allow psql command \l to accept a database - name pattern (Peter Eisentraut) - - - - - - In psql, do not allow \connect to - use defaults if there is no active connection (Bruce Momjian) - - - - This might be the case if the server had crashed. - - - - - - Properly reset state after failure of a SQL command executed with - psql's \g file - (Tom Lane) - - - - Previously, the output from subsequent SQL commands would unexpectedly - continue to go to the same file. - - - - - - - - - Output - - - - - - Add a latex-longtable output format to - psql (Bruce Momjian) - - - - This format allows tables to span multiple pages. - - - - - - Add a border=3 output mode to the psql - latex format (Bruce Momjian) - - - - - - In psql's tuples-only and expanded output modes, no - longer emit (No rows) for zero rows (Peter Eisentraut) - - - - - - In psql's unaligned, expanded output mode, no longer - print an empty line for zero rows (Peter Eisentraut) - - - - - - - - - - - <link linkend="app-pgdump"><application>pg_dump</application></link> - - - - - - Add pg_dump option to dump tables in - parallel (Joachim Wieland) - - - - - - Make pg_dump output functions in a more predictable - order (Joel Jacobson) - - - - - - Fix tar files emitted by pg_dump - to be POSIX conformant (Brian Weaver, Tom Lane) - - - - - - Add option to pg_dump, for - consistency with other client commands (Heikki Linnakangas) - - - - The database name could already be supplied last without a flag. - - - - - - - - - <link linkend="app-initdb"><application>initdb</application></link> - - - - - - Make initdb fsync the newly created data directory (Jeff Davis) - - - - This insures data integrity in event of a system crash shortly after - initdb. This can be disabled by using . - - - - - - Add initdb option to sync the data directory to durable - storage (Bruce Momjian) - - - - This is used by pg_upgrade. - - - - - - Make initdb issue a warning about placing the data directory at the - top of a file system mount point (Bruce Momjian) - - - - - - - - - - - Source Code - - - - - - Add infrastructure to allow plug-in background worker processes - (Álvaro Herrera) - - - - - - Create a centralized timeout API (Zoltán - Böszörményi) - - - - - - Create libpgcommon and move pg_malloc() and other - functions there (Álvaro Herrera, Andres Freund) - - - - This allows libpgport to be used solely for portability-related code. - - - - - - Add support for list links embedded in larger structs (Andres Freund) - - - - - - Use SA_RESTART for all signals, - including SIGALRM (Tom Lane) - - - - - - Ensure that the correct text domain is used when - translating errcontext() messages - (Heikki Linnakangas) - - - - - - Standardize naming of client-side memory allocation functions (Tom Lane) - - - - - - Provide support for static assertions that will fail at - compile time if some compile-time-constant condition is not met - (Andres Freund, Tom Lane) - - - - - - Support Assert() in client-side code (Andrew Dunstan) - - - - - - Add decoration to inform the C compiler that some ereport() - and elog() calls do not return (Peter Eisentraut, - Andres Freund, Tom Lane, Heikki Linnakangas) - - - - - - Allow options to be passed to the regression - test output comparison utility via PG_REGRESS_DIFF_OPTS - (Peter Eisentraut) - - - - - - Add isolation tests for CREATE INDEX - CONCURRENTLY (Abhijit Menon-Sen) - - - - - - Remove typedefs for int2/int4 as they are better - represented as int16/int32 (Peter Eisentraut) - - - - - - Fix install-strip on Mac OS - X (Peter Eisentraut) - - - - - - Remove configure flag - , as it is no longer supported - (Bruce Momjian) - - - - - - Rewrite pgindent in Perl (Andrew Dunstan) - - - - - - Provide Emacs macro to set Perl formatting to - match PostgreSQL's perltidy settings (Peter Eisentraut) - - - - - - Run tool to check the keyword list whenever the backend grammar is - changed (Tom Lane) - - - - - - Change the way UESCAPE is lexed, to significantly reduce - the size of the lexer tables (Heikki Linnakangas) - - - - - - Centralize flex and bison - make rules (Peter Eisentraut) - - - - This is useful for pgxs authors. - - - - - - Change many internal backend functions to return object OIDs - rather than void (Dimitri Fontaine) - - - - This is useful for event triggers. - - - - - - Invent pre-commit/pre-prepare/pre-subcommit events for transaction - callbacks (Tom Lane) - - - - Loadable modules that use transaction callbacks might need modification - to handle these new event types. - - - - - - Add function pg_identify_object() - to produce a machine-readable description of a database object - (Álvaro Herrera) - - - - - - Add post-ALTER-object server hooks (KaiGai Kohei) - - - - - - Implement a generic binary heap and use it for Merge-Append - operations (Abhijit Menon-Sen) - - - - - - Provide a tool to help detect timezone abbreviation changes when - updating the src/timezone/data files - (Tom Lane) - - - - - - Add pkg-config support for libpq - and ecpg libraries (Peter Eisentraut) - - - - - - Remove src/tools/backend, now that the content is on - the PostgreSQL wiki (Bruce Momjian) - - - - - - Split out WAL reading as - an independent facility (Heikki Linnakangas, Andres Freund) - - - - - - Use a 64-bit integer to represent WAL positions - (XLogRecPtr) instead of two 32-bit integers - (Heikki Linnakangas) - - - - Generally, tools that need to read the WAL format - will need to be adjusted. - - - - - - Allow PL/Python to support - platform-specific include directories (Peter Eisentraut) - - - - - - Allow PL/Python on OS - X to build against custom versions of Python - (Peter Eisentraut) - - - - - - - - - Additional Modules - - - - - - Add a Postgres foreign - data wrapper contrib module to allow access to - other Postgres servers (Shigeru Hanada) - - - - This foreign data wrapper supports writes. - - - - - - Add pg_xlogdump - contrib program (Andres Freund) - - - - - - Add support for indexing of regular-expression searches in - pg_trgm - (Alexander Korotkov) - - - - - - Improve pg_trgm's - handling of multibyte characters (Tom Lane) - - - - On a platform that does not have the wcstombs() or towlower() library - functions, this could result in an incompatible change in the contents - of pg_trgm indexes for non-ASCII data. In such cases, - REINDEX those indexes to ensure correct search results. - - - - - - Add a pgstattuple function to report - the size of the pending-insertions list of a GIN index - (Fujii Masao) - - - - - - Make oid2name, - pgbench, and - vacuumlo set - fallback_application_name (Amit Kapila) - - - - - - Improve output of pg_test_timing - (Bruce Momjian) - - - - - - Improve output of pg_test_fsync - (Peter Geoghegan) - - - - - - Create a dedicated foreign data wrapper, with its own option validator - function, for dblink (Shigeru Hanada) - - - - When using this FDW to define the target of a dblink - connection, instead of using a hard-wired list of connection options, - the underlying libpq library is consulted to see what - connection options it supports. - - - - - - - <link linkend="pgupgrade"><application>pg_upgrade</application></link> - - - - - - Allow pg_upgrade to do dumps and restores in - parallel (Bruce Momjian, Andrew Dunstan) - - - - This allows parallel schema dump/restore of databases, as well as - parallel copy/link of data files per tablespace. Use the - option to specify the level of parallelism. - - - - - - Make pg_upgrade create Unix-domain sockets in - the current directory (Bruce Momjian, Tom Lane) - - - - This reduces the possibility that someone will accidentally connect - during the upgrade. - - - - - - Make pg_upgrade mode properly - detect the location of non-default socket directories (Bruce - Momjian, Tom Lane) - - - - - - Improve performance of pg_upgrade for databases - with many tables (Bruce Momjian) - - - - - - Improve pg_upgrade's logs by showing - executed commands (Álvaro Herrera) - - - - - - Improve pg_upgrade's status display during - copy/link (Bruce Momjian) - - - - - - - - - <link linkend="pgbench"><application>pgbench</application></link> - - - - - - Add option to pgbench - (Jeff Janes) - - - - This adds foreign key constraints to the standard tables created by - pgbench, for use in foreign key performance testing. - - - - - - Allow pgbench to aggregate performance statistics - and produce output every - seconds (Tomas Vondra) - - - - - - Add pgbench option - to control the percentage of transactions logged (Tomas Vondra) - - - - - - Reduce and improve the status message output of - pgbench's initialization mode (Robert Haas, - Peter Eisentraut) - - - - - - Add pgbench mode to print one output - line every five seconds (Tomas Vondra) - - - - - - Output pgbench elapsed and estimated remaining - time during initialization (Tomas Vondra) - - - - - - Allow pgbench to use much larger scale factors, - by changing relevant columns from integer to bigint - when the requested scale factor exceeds 20000 - (Greg Smith) - - - - - - - - - - - Documentation - - - - - - Allow EPUB-format documentation to be created - (Peter Eisentraut) - - - - - - Update FreeBSD kernel configuration documentation - (Brad Davis) - - - - - - Improve WINDOW - function documentation (Bruce Momjian, Florian Pflug) - - - - - - Add instructions for setting - up the documentation tool chain on macOS - (Peter Eisentraut) - - - - - - Improve commit_delay - documentation (Peter Geoghegan) - - - - - - - - - diff --git a/doc/src/sgml/release-9.4.sgml b/doc/src/sgml/release-9.4.sgml deleted file mode 100644 index ed4de33dd03..00000000000 --- a/doc/src/sgml/release-9.4.sgml +++ /dev/null @@ -1,11862 +0,0 @@ - - - - - Release 9.4.17 - - - Release date: - 2018-03-01 - - - - This release contains a variety of fixes from 9.4.16. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.17 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you run an installation in which not all users are mutually - trusting, or if you maintain an application or extension that is - intended for use in arbitrary situations, it is strongly recommended - that you read the documentation changes described in the first changelog - entry below, and take suitable steps to ensure that your installation or - code is secure. - - - - Also, the changes described in the second changelog entry below may - cause functions used in index expressions or materialized views to fail - during auto-analyze, or when reloading from a dump. After upgrading, - monitor the server logs for such problems, and fix affected functions. - - - - Also, if you are upgrading from a version earlier than 9.4.13, - see . - - - - - Changes - - - - - - Document how to configure installations and applications to guard - against search-path-dependent trojan-horse attacks from other users - (Noah Misch) - - - - Using a search_path setting that includes any - schemas writable by a hostile user enables that user to capture - control of queries and then run arbitrary SQL code with the - permissions of the attacked user. While it is possible to write - queries that are proof against such hijacking, it is notationally - tedious, and it's very easy to overlook holes. Therefore, we now - recommend configurations in which no untrusted schemas appear in - one's search path. Relevant documentation appears in - (for database administrators and users), - (for application authors), - (for extension authors), and - (for authors - of SECURITY DEFINER functions). - (CVE-2018-1058) - - - - - - Avoid use of insecure search_path settings - in pg_dump and other client programs - (Noah Misch, Tom Lane) - - - - pg_dump, - pg_upgrade, - vacuumdb and - other PostgreSQL-provided applications were - themselves vulnerable to the type of hijacking described in the previous - changelog entry; since these applications are commonly run by - superusers, they present particularly attractive targets. To make them - secure whether or not the installation as a whole has been secured, - modify them to include only the pg_catalog - schema in their search_path settings. - Autovacuum worker processes now do the same, as well. - - - - In cases where user-provided functions are indirectly executed by - these programs — for example, user-provided functions in index - expressions — the tighter search_path may - result in errors, which will need to be corrected by adjusting those - user-provided functions to not assume anything about what search path - they are invoked under. That has always been good practice, but now - it will be necessary for correct behavior. - (CVE-2018-1058) - - - - - - Fix misbehavior of concurrent-update rechecks with CTE references - appearing in subplans (Tom Lane) - - - - If a CTE (WITH clause reference) is used in an - InitPlan or SubPlan, and the query requires a recheck due to trying - to update or lock a concurrently-updated row, incorrect results could - be obtained. - - - - - - Fix planner failures with overlapping mergejoin clauses in an outer - join (Tom Lane) - - - - These mistakes led to left and right pathkeys do not match in - mergejoin or outer pathkeys do not match - mergeclauses planner errors in corner cases. - - - - - - Repair pg_upgrade's failure to - preserve relfrozenxid for materialized - views (Tom Lane, Andres Freund) - - - - This oversight could lead to data corruption in materialized views - after an upgrade, manifesting as could not access status of - transaction or found xmin from before - relfrozenxid errors. The problem would be more likely to - occur in seldom-refreshed materialized views, or ones that were - maintained only with REFRESH MATERIALIZED VIEW - CONCURRENTLY. - - - - If such corruption is observed, it can be repaired by refreshing the - materialized view (without CONCURRENTLY). - - - - - - Fix incorrect reporting of PL/Python function names in - error CONTEXT stacks (Tom Lane) - - - - An error occurring within a nested PL/Python function call (that is, - one reached via a SPI query from another PL/Python function) would - result in a stack trace showing the inner function's name twice, - rather than the expected results. Also, an error in a nested - PL/Python DO block could result in a null pointer - dereference crash on some platforms. - - - - - - Allow contrib/auto_explain's - log_min_duration setting to range up - to INT_MAX, or about 24 days instead of 35 minutes - (Tom Lane) - - - - - - - - - - Release 9.4.16 - - - Release date: - 2018-02-08 - - - - This release contains a variety of fixes from 9.4.15. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.16 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.13, - see . - - - - - Changes - - - - - - Ensure that all temporary files made - by pg_upgrade are non-world-readable - (Tom Lane, Noah Misch) - - - - pg_upgrade normally restricts its - temporary files to be readable and writable only by the calling user. - But the temporary file containing pg_dumpall -g - output would be group- or world-readable, or even writable, if the - user's umask setting allows. In typical usage on - multi-user machines, the umask and/or the working - directory's permissions would be tight enough to prevent problems; - but there may be people using pg_upgrade - in scenarios where this oversight would permit disclosure of database - passwords to unfriendly eyes. - (CVE-2018-1053) - - - - - - Fix vacuuming of tuples that were updated while key-share locked - (Andres Freund, Álvaro Herrera) - - - - In some cases VACUUM would fail to remove such - tuples even though they are now dead, leading to assorted data - corruption scenarios. - - - - - - Fix inadequate buffer locking in some LSN fetches (Jacob Champion, - Asim Praveen, Ashwin Agrawal) - - - - These errors could result in misbehavior under concurrent load. - The potential consequences have not been characterized fully. - - - - - - Avoid unnecessary failure in a query on an inheritance tree that - occurs concurrently with some child table being removed from the tree - by ALTER TABLE NO INHERIT (Tom Lane) - - - - - - Fix spurious deadlock failures when multiple sessions are - running CREATE INDEX CONCURRENTLY (Jeff Janes) - - - - - - Repair failure with correlated sub-SELECT - inside VALUES inside a LATERAL - subquery (Tom Lane) - - - - - - Fix could not devise a query plan for the given query - planner failure for some cases involving nested UNION - ALL inside a lateral subquery (Tom Lane) - - - - - - Fix logical decoding to correctly clean up disk files for crashed - transactions (Atsushi Torikoshi) - - - - Logical decoding may spill WAL records to disk for transactions - generating many WAL records. Normally these files are cleaned up - after the transaction's commit or abort record arrives; but if - no such record is ever seen, the removal code misbehaved. - - - - - - Fix walsender timeout failure and failure to respond to interrupts - when processing a large transaction (Petr Jelinek) - - - - - - Fix has_sequence_privilege() to - support WITH GRANT OPTION tests, - as other privilege-testing functions do (Joe Conway) - - - - - - In databases using UTF8 encoding, ignore any XML declaration that - asserts a different encoding (Pavel Stehule, Noah Misch) - - - - We always store XML strings in the database encoding, so allowing - libxml to act on a declaration of another encoding gave wrong results. - In encodings other than UTF8, we don't promise to support non-ASCII - XML data anyway, so retain the previous behavior for bug compatibility. - This change affects only xpath() and related - functions; other XML code paths already acted this way. - - - - - - Provide for forward compatibility with future minor protocol versions - (Robert Haas, Badrul Chowdhury) - - - - Up to now, PostgreSQL servers simply - rejected requests to use protocol versions newer than 3.0, so that - there was no functional difference between the major and minor parts - of the protocol version number. Allow clients to request versions 3.x - without failing, sending back a message showing that the server only - understands 3.0. This makes no difference at the moment, but - back-patching this change should allow speedier introduction of future - minor protocol upgrades. - - - - - - Cope with failure to start a parallel worker process - (Amit Kapila, Robert Haas) - - - - Parallel query previously tended to hang indefinitely if a worker - could not be started, as the result of fork() - failure or other low-probability problems. - - - - - - Prevent stack-overflow crashes when planning extremely deeply - nested set operations - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Fix null-pointer crashes for some types of LDAP URLs appearing - in pg_hba.conf (Thomas Munro) - - - - - - Fix sample INSTR() functions in the PL/pgSQL - documentation (Yugo Nagata, Tom Lane) - - - - These functions are stated to - be Oracle compatible, but - they weren't exactly. In particular, there was a discrepancy in the - interpretation of a negative third parameter: Oracle thinks that a - negative value indicates the last place where the target substring can - begin, whereas our functions took it as the last place where the - target can end. Also, Oracle throws an error for a zero or negative - fourth parameter, whereas our functions returned zero. - - - - The sample code has been adjusted to match Oracle's behavior more - precisely. Users who have copied this code into their applications - may wish to update their copies. - - - - - - Fix pg_dump to make ACL (permissions), - comment, and security label entries reliably identifiable in archive - output formats (Tom Lane) - - - - The tag portion of an ACL archive entry was usually - just the name of the associated object. Make it start with the object - type instead, bringing ACLs into line with the convention already used - for comment and security label archive entries. Also, fix the - comment and security label entries for the whole database, if present, - to make their tags start with DATABASE so that they - also follow this convention. This prevents false matches in code that - tries to identify large-object-related entries by seeing if the tag - starts with LARGE OBJECT. That could have resulted - in misclassifying entries as data rather than schema, with undesirable - results in a schema-only or data-only dump. - - - - Note that this change has user-visible results in the output - of pg_restore --list. - - - - - - In ecpg, detect indicator arrays that do - not have the correct length and report an error (David Rader) - - - - - - Avoid triggering a libc assertion - in contrib/hstore, due to use - of memcpy() with equal source and destination - pointers (Tomas Vondra) - - - - - - Provide modern examples of how to auto-start Postgres on macOS - (Tom Lane) - - - - The scripts in contrib/start-scripts/osx use - infrastructure that's been deprecated for over a decade, and which no - longer works at all in macOS releases of the last couple of years. - Add a new subdirectory contrib/start-scripts/macos - containing scripts that use the newer launchd - infrastructure. - - - - - - Fix incorrect selection of configuration-specific libraries for - OpenSSL on Windows (Andrew Dunstan) - - - - - - Support linking to MinGW-built versions of libperl (Noah Misch) - - - - This allows building PL/Perl with some common Perl distributions for - Windows. - - - - - - Fix MSVC build to test whether 32-bit libperl - needs -D_USE_32BIT_TIME_T (Noah Misch) - - - - Available Perl distributions are inconsistent about what they expect, - and lack any reliable means of reporting it, so resort to a build-time - test on what the library being used actually does. - - - - - - On Windows, install the crash dump handler earlier in postmaster - startup (Takayuki Tsunakawa) - - - - This may allow collection of a core dump for some early-startup - failures that did not produce a dump before. - - - - - - On Windows, avoid encoding-conversion-related crashes when emitting - messages very early in postmaster startup (Takayuki Tsunakawa) - - - - - - Use our existing Motorola 68K spinlock code on OpenBSD as - well as NetBSD (David Carlier) - - - - - - Add support for spinlocks on Motorola 88K (David Carlier) - - - - - - Update time zone data files to tzdata - release 2018c for DST law changes in Brazil, Sao Tome and Principe, - plus historical corrections for Bolivia, Japan, and South Sudan. - The US/Pacific-New zone has been removed (it was - only an alias for America/Los_Angeles anyway). - - - - - - - - - - Release 9.4.15 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 9.4.14. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.15 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.13, - see . - - - - - Changes - - - - - - Fix crash due to rowtype mismatch - in json{b}_populate_recordset() - (Michael Paquier, Tom Lane) - - - - These functions used the result rowtype specified in the FROM - ... AS clause without checking that it matched the actual - rowtype of the supplied tuple value. If it didn't, that would usually - result in a crash, though disclosure of server memory contents seems - possible as well. - (CVE-2017-15098) - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - Fix crash when logical decoding is invoked from a SPI-using function, - in particular any function written in a PL language - (Tom Lane) - - - - - - Fix json_build_array(), - json_build_object(), and their jsonb - equivalents to handle explicit VARIADIC arguments - correctly (Michael Paquier) - - - - - - Properly reject attempts to convert infinite float values to - type numeric (Tom Lane, KaiGai Kohei) - - - - Previously the behavior was platform-dependent. - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - Avoid SIGBUS crash on Linux when a DSM memory - request exceeds the space available in tmpfs - (Thomas Munro) - - - - - - Prevent low-probability crash in processing of nested trigger firings - (Tom Lane) - - - - - - Allow COPY's FREEZE option to - work when the transaction isolation level is REPEATABLE - READ or higher (Noah Misch) - - - - This case was unintentionally broken by a previous bug fix. - - - - - - Correctly restore the umask setting when file creation fails - in COPY or lo_export() - (Peter Eisentraut) - - - - - - Give a better error message for duplicate column names - in ANALYZE (Nathan Bossart) - - - - - - Fix mis-parsing of the last line in a - non-newline-terminated pg_hba.conf file - (Tom Lane) - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - Fix libpq to guard against integer - overflow in the row count of a PGresult - (Michael Paquier) - - - - - - Fix ecpg's handling of out-of-scope cursor - declarations with pointer or array variables (Michael Meskes) - - - - - - In ecpglib, correctly handle backslashes in string literals depending - on whether standard_conforming_strings is set - (Tsunakawa Takayuki) - - - - - - Make ecpglib's Informix-compatibility mode ignore fractional digits in - integer input strings, as expected (Gao Zengqi, Michael Meskes) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017c - (Tom Lane) - - - - This fixes various issues; the only one likely to be user-visible - is that the default DST rules for a POSIX-style zone name, if - no posixrules file exists in the timezone data - directory, now match current US law rather than what it was a dozen - years ago. - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - - - - Release 9.4.14 - - - Release date: - 2017-08-31 - - - - This release contains a small number of fixes from 9.4.13. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.14 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.13, - see . - - - - - Changes - - - - - - - Fix failure of walsender processes to respond to shutdown signals - (Marco Nenciarini) - - - - A missed flag update resulted in walsenders continuing to run as long - as they had a standby server connected, preventing primary-server - shutdown unless immediate shutdown mode is used. - - - - - - Show foreign tables - in information_schema.table_privileges - view (Peter Eisentraut) - - - - All other relevant information_schema views include - foreign tables, but this one ignored them. - - - - Since this view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can, as a superuser, do this - in psql: - -SET search_path TO information_schema; -CREATE OR REPLACE VIEW table_privileges AS - SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, - CAST(grantee.rolname AS sql_identifier) AS grantee, - CAST(current_database() AS sql_identifier) AS table_catalog, - CAST(nc.nspname AS sql_identifier) AS table_schema, - CAST(c.relname AS sql_identifier) AS table_name, - CAST(c.prtype AS character_data) AS privilege_type, - CAST( - CASE WHEN - -- object owner always has grant options - pg_has_role(grantee.oid, c.relowner, 'USAGE') - OR c.grantable - THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, - CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy - - FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class - ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), - pg_namespace nc, - pg_authid u_grantor, - ( - SELECT oid, rolname FROM pg_authid - UNION ALL - SELECT 0::oid, 'PUBLIC' - ) AS grantee (oid, rolname) - - WHERE c.relnamespace = nc.oid - AND c.relkind IN ('r', 'v', 'f') - AND c.grantee = grantee.oid - AND c.grantor = u_grantor.oid - AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') - AND (pg_has_role(u_grantor.oid, 'USAGE') - OR pg_has_role(grantee.oid, 'USAGE') - OR grantee.rolname = 'PUBLIC'); - - This must be repeated in each database to be fixed, - including template0. - - - - - - Clean up handling of a fatal exit (e.g., due to receipt - of SIGTERM) that occurs while trying to execute - a ROLLBACK of a failed transaction (Tom Lane) - - - - This situation could result in an assertion failure. In production - builds, the exit would still occur, but it would log an unexpected - message about cannot drop active portal. - - - - - - Remove assertion that could trigger during a fatal exit (Tom Lane) - - - - - - Correctly identify columns that are of a range type or domain type over - a composite type or domain type being searched for (Tom Lane) - - - - Certain ALTER commands that change the definition of a - composite type or domain type are supposed to fail if there are any - stored values of that type in the database, because they lack the - infrastructure needed to update or check such values. Previously, - these checks could miss relevant values that are wrapped inside range - types or sub-domains, possibly allowing the database to become - inconsistent. - - - - - - Fix crash in pg_restore when using parallel mode and - using a list file to select a subset of items to restore - (Fabrízio de Royes Mello) - - - - - - Change ecpg's parser to allow RETURNING - clauses without attached C variables (Michael Meskes) - - - - This allows ecpg programs to contain SQL constructs - that use RETURNING internally (for example, inside a CTE) - rather than using it to define values to be returned to the client. - - - - - - Improve selection of compiler flags for PL/Perl on Windows (Tom Lane) - - - - This fix avoids possible crashes of PL/Perl due to inconsistent - assumptions about the width of time_t values. - A side-effect that may be visible to extension developers is - that _USE_32BIT_TIME_T is no longer defined globally - in PostgreSQL Windows builds. This is not expected - to cause problems, because type time_t is not used - in any PostgreSQL API definitions. - - - - - - - - - - Release 9.4.13 - - - Release date: - 2017-08-10 - - - - This release contains a variety of fixes from 9.4.12. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.13 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.4.12, - see . - - - - - Changes - - - - - - Further restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Noah Misch) - - - - The fix for CVE-2017-7486 was incorrect: it allowed a user - to see the options in her own user mapping, even if she did not - have USAGE permission on the associated foreign server. - Such options might include a password that had been provided by the - server owner rather than the user herself. - Since information_schema.user_mapping_options does not - show the options in such cases, pg_user_mappings - should not either. - (CVE-2017-7547) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - you will need to do the following: - - - - - - Restart the postmaster after adding allow_system_table_mods - = true to postgresql.conf. (In versions - supporting ALTER SYSTEM, you can use that to make the - configuration change, but you'll still need a restart.) - - - - - - In each database of the cluster, - run the following commands as superuser: - -SET search_path = pg_catalog; -CREATE OR REPLACE VIEW pg_user_mappings AS - SELECT - U.oid AS umid, - S.oid AS srvid, - S.srvname AS srvname, - U.umuser AS umuser, - CASE WHEN U.umuser = 0 THEN - 'public' - ELSE - A.rolname - END AS usename, - CASE WHEN (U.umuser <> 0 AND A.rolname = current_user - AND (pg_has_role(S.srvowner, 'USAGE') - OR has_server_privilege(S.oid, 'USAGE'))) - OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE')) - OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) - THEN U.umoptions - ELSE NULL END AS umoptions - FROM pg_user_mapping U - LEFT JOIN pg_authid A ON (A.oid = U.umuser) JOIN - pg_foreign_server S ON (U.umserver = S.oid); - - - - - - - Do not forget to include the template0 - and template1 databases, or the vulnerability will still - exist in databases you create later. To fix template0, - you'll need to temporarily make it accept connections. - In PostgreSQL 9.5 and later, you can use - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true; - - and then after fixing template0, undo that with - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false; - - In prior versions, instead use - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - - Finally, remove the allow_system_table_mods configuration - setting, and again restart the postmaster. - - - - - - - - Disallow empty passwords in all password-based authentication methods - (Heikki Linnakangas) - - - - libpq ignores empty password specifications, and does - not transmit them to the server. So, if a user's password has been - set to the empty string, it's impossible to log in with that password - via psql or other libpq-based - clients. An administrator might therefore believe that setting the - password to empty is equivalent to disabling password login. - However, with a modified or non-libpq-based client, - logging in could be possible, depending on which authentication - method is configured. In particular the most common - method, md5, accepted empty passwords. - Change the server to reject empty passwords in all cases. - (CVE-2017-7546) - - - - - - Make lo_put() check for UPDATE privilege on - the target large object (Tom Lane, Michael Paquier) - - - - lo_put() should surely require the same permissions - as lowrite(), but the check was missing, allowing any - user to change the data in a large object. - (CVE-2017-7548) - - - - - - Fix concurrent locking of tuple update chains (Álvaro Herrera) - - - - If several sessions concurrently lock a tuple update chain with - nonconflicting lock modes using an old snapshot, and they all - succeed, it was possible for some of them to nonetheless fail (and - conclude there is no live tuple version) due to a race condition. - This had consequences such as foreign-key checks failing to see a - tuple that definitely exists but is being updated concurrently. - - - - - - Fix potential data corruption when freezing a tuple whose XMAX is a - multixact with exactly one still-interesting member (Teodor Sigaev) - - - - - - Avoid integer overflow and ensuing crash when sorting more than one - billion tuples in-memory (Sergey Koposov) - - - - - - On Windows, retry process creation if we fail to reserve the address - range for our shared memory in the new process (Tom Lane, Amit - Kapila) - - - - This is expected to fix infrequent child-process-launch failures that - are probably due to interference from antivirus products. - - - - - - Fix low-probability corruption of shared predicate-lock hash table - in Windows builds (Thomas Munro, Tom Lane) - - - - - - Avoid logging clean closure of an SSL connection as though - it were a connection reset (Michael Paquier) - - - - - - Prevent sending SSL session tickets to clients (Tom Lane) - - - - This fix prevents reconnection failures with ticket-aware client-side - SSL code. - - - - - - Fix code for setting on - Solaris (Tom Lane) - - - - - - Fix statistics collector to honor inquiry messages issued just after - a postmaster shutdown and immediate restart (Tom Lane) - - - - Statistics inquiries issued within half a second of the previous - postmaster shutdown were effectively ignored. - - - - - - Ensure that the statistics collector's receive buffer size is at - least 100KB (Tom Lane) - - - - This reduces the risk of dropped statistics data on older platforms - whose default receive buffer size is less than that. - - - - - - Fix possible creation of an invalid WAL segment when a standby is - promoted just after it processes an XLOG_SWITCH WAL - record (Andres Freund) - - - - - - Fix walsender to exit promptly when client requests - shutdown (Tom Lane) - - - - - - Fix SIGHUP and SIGUSR1 handling in - walsender processes (Petr Jelinek, Andres Freund) - - - - - - Prevent walsender-triggered panics during shutdown checkpoints - (Andres Freund, Michael Paquier) - - - - - - Fix unnecessarily slow restarts of walreceiver - processes due to race condition in postmaster (Tom Lane) - - - - - - - Fix logical decoding failure with very wide tuples (Andres Freund) - - - - Logical decoding crashed on tuples that are wider than 64KB (after - compression, but with all data in-line). The case arises only - when REPLICA IDENTITY FULL is enabled for a table - containing such tuples. - - - - - - Fix leakage of small subtransactions spilled to disk during logical - decoding (Andres Freund) - - - - This resulted in temporary files consuming excessive disk space. - - - - - - Reduce the work needed to build snapshots during creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - The previous algorithm was infeasibly expensive on a server with a - lot of open transactions. - - - - - - Fix race condition that could indefinitely delay creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - - - Reduce overhead in processing syscache invalidation events (Tom Lane) - - - - This is particularly helpful for logical decoding, which triggers - frequent cache invalidation. - - - - - - Fix cases where an INSERT or UPDATE assigns - to more than one element of a column that is of domain-over-array - type (Tom Lane) - - - - - - Allow window functions to be used in sub-SELECTs that - are within the arguments of an aggregate function (Tom Lane) - - - - - - Move autogenerated array types out of the way during - ALTER ... RENAME (Vik Fearing) - - - - Previously, we would rename a conflicting autogenerated array type - out of the way during CREATE; this fix extends that - behavior to renaming operations. - - - - - - Ensure that ALTER USER ... SET accepts all the syntax - variants that ALTER ROLE ... SET does (Peter Eisentraut) - - - - - - Properly update dependency info when changing a datatype I/O - function's argument or return type from opaque to the - correct type (Heikki Linnakangas) - - - - CREATE TYPE updates I/O functions declared in this - long-obsolete style, but it forgot to record a dependency on the - type, allowing a subsequent DROP TYPE to leave broken - function definitions behind. - - - - - - Reduce memory usage when ANALYZE processes - a tsvector column (Heikki Linnakangas) - - - - - - Fix unnecessary precision loss and sloppy rounding when multiplying - or dividing money values by integers or floats (Tom Lane) - - - - - - Tighten checks for whitespace in functions that parse identifiers, - such as regprocedurein() (Tom Lane) - - - - Depending on the prevailing locale, these functions could - misinterpret fragments of multibyte characters as whitespace. - - - - - - Use relevant #define symbols from Perl while - compiling PL/Perl (Ashutosh Sharma, Tom Lane) - - - - This avoids portability problems, typically manifesting as - a handshake mismatch during library load, when working with - recent Perl versions. - - - - - - In libpq, reset GSS/SASL and SSPI authentication - state properly after a failed connection attempt (Michael Paquier) - - - - Failure to do this meant that when falling back from SSL to non-SSL - connections, a GSS/SASL failure in the SSL attempt would always cause - the non-SSL attempt to fail. SSPI did not fail, but it leaked memory. - - - - - - In psql, fix failure when COPY FROM STDIN - is ended with a keyboard EOF signal and then another COPY - FROM STDIN is attempted (Thomas Munro) - - - - This misbehavior was observed on BSD-derived platforms (including - macOS), but not on most others. - - - - - - Fix pg_dump and pg_restore to - emit REFRESH MATERIALIZED VIEW commands last (Tom Lane) - - - - This prevents errors during dump/restore when a materialized view - refers to tables owned by a different user. - - - - - - Improve pg_dump/pg_restore's - reporting of error conditions originating in zlib - (Vladimir Kunschikov, Álvaro Herrera) - - - - - - Fix pg_dump with the option to - drop event triggers as expected (Tom Lane) - - - - It also now correctly assigns ownership of event triggers; before, - they were restored as being owned by the superuser running the - restore script. - - - - - - Fix pg_dump to not emit invalid SQL for an empty - operator class (Daniel Gustafsson) - - - - - - Fix pg_dump output to stdout on Windows (Kuntal Ghosh) - - - - A compressed plain-text dump written to stdout would contain corrupt - data due to failure to put the file descriptor into binary mode. - - - - - - Fix pg_get_ruledef() to print correct output for - the ON SELECT rule of a view whose columns have been - renamed (Tom Lane) - - - - In some corner cases, pg_dump relies - on pg_get_ruledef() to dump views, so that this error - could result in dump/reload failures. - - - - - - Fix dumping of outer joins with empty constraints, such as the result - of a NATURAL LEFT JOIN with no common columns (Tom Lane) - - - - - - Fix dumping of function expressions in the FROM clause in - cases where the expression does not deparse into something that looks - like a function call (Tom Lane) - - - - - - Fix pg_basebackup output to stdout on Windows - (Haribabu Kommi) - - - - A backup written to stdout would contain corrupt data due to failure - to put the file descriptor into binary mode. - - - - - - Fix pg_upgrade to ensure that the ending WAL record - does not have = minimum - (Bruce Momjian) - - - - This condition could prevent upgraded standby servers from - reconnecting. - - - - - - In postgres_fdw, re-establish connections to remote - servers after ALTER SERVER or ALTER USER - MAPPING commands (Kyotaro Horiguchi) - - - - This ensures that option changes affecting connection parameters will - be applied promptly. - - - - - - In postgres_fdw, allow cancellation of remote - transaction control commands (Robert Haas, Rafia Sabih) - - - - This change allows us to quickly escape a wait for an unresponsive - remote server in many more cases than previously. - - - - - - Increase MAX_SYSCACHE_CALLBACKS to provide more room for - extensions (Tom Lane) - - - - - - Always use , not , when building - shared libraries with gcc (Tom Lane) - - - - This supports larger extension libraries on platforms where it makes - a difference. - - - - - - Fix unescaped-braces issue in our build scripts for Microsoft MSVC, - to avoid a warning or error from recent Perl versions (Andrew - Dunstan) - - - - - - In MSVC builds, handle the case where the openssl - library is not within a VC subdirectory (Andrew Dunstan) - - - - - - In MSVC builds, add proper include path for libxml2 - header files (Andrew Dunstan) - - - - This fixes a former need to move things around in standard Windows - installations of libxml2. - - - - - - In MSVC builds, recognize a Tcl library that is - named tcl86.lib (Noah Misch) - - - - - - In MSVC builds, honor PROVE_FLAGS settings - on vcregress.pl's command line (Andrew Dunstan) - - - - - - - - - - Release 9.4.12 - - - Release date: - 2017-05-11 - - - - This release contains a variety of fixes from 9.4.11. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.12 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are using third-party replication tools that depend - on logical decoding, see the fourth changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.4.11, - see . - - - - - Changes - - - - - - Restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Michael Paquier, Feike Steenbergen) - - - - The previous coding allowed the owner of a foreign server object, - or anyone he has granted server USAGE permission to, - to see the options for all user mappings associated with that server. - This might well include passwords for other users. - Adjust the view definition to match the behavior of - information_schema.user_mapping_options, namely that - these options are visible to the user being mapped, or if the mapping - is for PUBLIC and the current user is the server - owner, or if the current user is a superuser. - (CVE-2017-7486) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - follow the corrected procedure shown in the changelog entry for - CVE-2017-7547, in . - - - - - - Prevent exposure of statistical information via leaky operators - (Peter Eisentraut) - - - - Some selectivity estimation functions in the planner will apply - user-defined operators to values obtained - from pg_statistic, such as most common values and - histogram entries. This occurs before table permissions are checked, - so a nefarious user could exploit the behavior to obtain these values - for table columns he does not have permission to read. To fix, - fall back to a default estimate if the operator's implementation - function is not certified leak-proof and the calling user does not have - permission to read the table column whose statistics are needed. - At least one of these criteria is satisfied in most cases in practice. - (CVE-2017-7484) - - - - - - Restore libpq's recognition of - the PGREQUIRESSL environment variable (Daniel Gustafsson) - - - - Processing of this environment variable was unintentionally dropped - in PostgreSQL 9.3, but its documentation remained. - This creates a security hazard, since users might be relying on the - environment variable to force SSL-encrypted connections, but that - would no longer be guaranteed. Restore handling of the variable, - but give it lower priority than PGSSLMODE, to avoid - breaking configurations that work correctly with post-9.3 code. - (CVE-2017-7485) - - - - - - Fix possibly-invalid initial snapshot during logical decoding - (Petr Jelinek, Andres Freund) - - - - The initial snapshot created for a logical decoding replication slot - was potentially incorrect. This could cause third-party tools that - use logical decoding to copy incomplete/inconsistent initial data. - This was more likely to happen if the source server was busy at the - time of slot creation, or if another logical slot already existed. - - - - If you are using a replication tool that depends on logical decoding, - and it should have copied a nonempty data set at the start of - replication, it is advisable to recreate the replica after - installing this update, or to verify its contents against the source - server. - - - - - - Fix possible corruption of init forks of unlogged indexes - (Robert Haas, Michael Paquier) - - - - This could result in an unlogged index being set to an invalid state - after a crash and restart. Such a problem would persist until the - index was dropped and rebuilt. - - - - - - Fix incorrect reconstruction of pg_subtrans entries - when a standby server replays a prepared but uncommitted two-phase - transaction (Tom Lane) - - - - In most cases this turned out to have no visible ill effects, but in - corner cases it could result in circular references - in pg_subtrans, potentially causing infinite loops - in queries that examine rows modified by the two-phase transaction. - - - - - - Avoid possible crash in walsender due to failure - to initialize a string buffer (Stas Kelvich, Fujii Masao) - - - - - - Fix postmaster's handling of fork() failure for a - background worker process (Tom Lane) - - - - Previously, the postmaster updated portions of its state as though - the process had been launched successfully, resulting in subsequent - confusion. - - - - - - Ensure parsing of queries in extension scripts sees the results of - immediately-preceding DDL (Julien Rouhaud, Tom Lane) - - - - Due to lack of a cache flush step between commands in an extension - script file, non-utility queries might not see the effects of an - immediately preceding catalog change, such as ALTER TABLE - ... RENAME. - - - - - - Skip tablespace privilege checks when ALTER TABLE ... ALTER - COLUMN TYPE rebuilds an existing index (Noah Misch) - - - - The command failed if the calling user did not currently have - CREATE privilege for the tablespace containing the index. - That behavior seems unhelpful, so skip the check, allowing the - index to be rebuilt where it is. - - - - - - Fix ALTER TABLE ... VALIDATE CONSTRAINT to not recurse - to child tables when the constraint is marked NO INHERIT - (Amit Langote) - - - - This fix prevents unwanted constraint does not exist failures - when no matching constraint is present in the child tables. - - - - - - Fix VACUUM to account properly for pages that could not - be scanned due to conflicting page pins (Andrew Gierth) - - - - This tended to lead to underestimation of the number of tuples in - the table. In the worst case of a small heavily-contended - table, VACUUM could incorrectly report that the table - contained no tuples, leading to very bad planning choices. - - - - - - Ensure that bulk-tuple-transfer loops within a hash join are - interruptible by query cancel requests (Tom Lane, Thomas Munro) - - - - - - Fix integer-overflow problems in interval comparison (Kyotaro - Horiguchi, Tom Lane) - - - - The comparison operators for type interval could yield wrong - answers for intervals larger than about 296000 years. Indexes on - columns containing such large values should be reindexed, since they - may be corrupt. - - - - - - Fix cursor_to_xml() to produce valid output - with tableforest = false - (Thomas Munro, Peter Eisentraut) - - - - Previously it failed to produce a wrapping <table> - element. - - - - - - Fix roundoff problems in float8_timestamptz() - and make_interval() (Tom Lane) - - - - These functions truncated, rather than rounded, when converting a - floating-point value to integer microseconds; that could cause - unexpectedly off-by-one results. - - - - - - Improve performance of pg_timezone_names view - (Tom Lane, David Rowley) - - - - - - Reduce memory management overhead for contexts containing many large - blocks (Tom Lane) - - - - - - Fix sloppy handling of corner-case errors from lseek() - and close() (Tom Lane) - - - - Neither of these system calls are likely to fail in typical situations, - but if they did, fd.c could get quite confused. - - - - - - Fix incorrect check for whether postmaster is running as a Windows - service (Michael Paquier) - - - - This could result in attempting to write to the event log when that - isn't accessible, so that no logging happens at all. - - - - - - Fix ecpg to support COMMIT PREPARED - and ROLLBACK PREPARED (Masahiko Sawada) - - - - - - Fix a double-free error when processing dollar-quoted string literals - in ecpg (Michael Meskes) - - - - - - In pg_dump, fix incorrect schema and owner marking for - comments and security labels of some types of database objects - (Giuseppe Broccolo, Tom Lane) - - - - In simple cases this caused no ill effects; but for example, a - schema-selective restore might omit comments it should include, because - they were not marked as belonging to the schema of their associated - object. - - - - - - Avoid emitting an invalid list file in pg_restore -l - when SQL object names contain newlines (Tom Lane) - - - - Replace newlines by spaces, which is sufficient to make the output - valid for pg_restore -L's purposes. - - - - - - Fix pg_upgrade to transfer comments and security labels - attached to large objects (blobs) (Stephen Frost) - - - - Previously, blobs were correctly transferred to the new database, but - any comments or security labels attached to them were lost. - - - - - - Improve error handling - in contrib/adminpack's pg_file_write() - function (Noah Misch) - - - - Notably, it failed to detect errors reported - by fclose(). - - - - - - In contrib/dblink, avoid leaking the previous unnamed - connection when establishing a new unnamed connection (Joe Conway) - - - - - - Fix contrib/pg_trgm's extraction of trigrams from regular - expressions (Tom Lane) - - - - In some cases it would produce a broken data structure that could never - match anything, leading to GIN or GiST indexscans that use a trigram - index not finding any matches to the regular expression. - - - - - - In contrib/postgres_fdw, - transmit query cancellation requests to the remote server - (Michael Paquier, Etsuro Fujita) - - - - Previously, a local query cancellation request did not cause an - already-sent remote query to terminate early. This is a back-patch - of work originally done for 9.6. - - - - - - - Support OpenSSL 1.1.0 (Heikki Linnakangas, Andreas Karlsson, Tom Lane) - - - - This is a back-patch of work previously done in newer branches; - it's needed since many platforms are adopting newer OpenSSL versions. - - - - - - Support Tcl 8.6 in MSVC builds (Álvaro Herrera) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017b - (Tom Lane) - - - - This fixes a bug affecting some DST transitions in January 2038. - - - - - - Update time zone data files to tzdata release 2017b - for DST law changes in Chile, Haiti, and Mongolia, plus historical - corrections for Ecuador, Kazakhstan, Liberia, and Spain. - Switch to numeric abbreviations for numerous time zones in South - America, the Pacific and Indian oceans, and some Asian and Middle - Eastern countries. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - - - Use correct daylight-savings rules for POSIX-style time zone names - in MSVC builds (David Rowley) - - - - The Microsoft MSVC build scripts neglected to install - the posixrules file in the timezone directory tree. - This resulted in the timezone code falling back to its built-in - rule about what DST behavior to assume for a POSIX-style time zone - name. For historical reasons that still corresponds to the DST rules - the USA was using before 2007 (i.e., change on first Sunday in April - and last Sunday in October). With this fix, a POSIX-style zone name - will use the current and historical DST transition dates of - the US/Eastern zone. If you don't want that, remove - the posixrules file, or replace it with a copy of some - other zone file (see ). Note that - due to caching, you may need to restart the server to get such changes - to take effect. - - - - - - - - - - Release 9.4.11 - - - Release date: - 2017-02-09 - - - - This release contains a variety of fixes from 9.4.10. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.11 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted indexes. - - - - Also, if you are upgrading from a version earlier than 9.4.10, - see . - - - - - Changes - - - - - - Fix a race condition that could cause indexes built - with CREATE INDEX CONCURRENTLY to be corrupt - (Pavan Deolasee, Tom Lane) - - - - If CREATE INDEX CONCURRENTLY was used to build an index - that depends on a column not previously indexed, then rows - updated by transactions that ran concurrently with - the CREATE INDEX command could have received incorrect - index entries. If you suspect this may have happened, the most - reliable solution is to rebuild affected indexes after installing - this update. - - - - - - Ensure that the special snapshot used for catalog scans is not - invalidated by premature data pruning (Tom Lane) - - - - Backends failed to account for this snapshot when advertising their - oldest xmin, potentially allowing concurrent vacuuming operations to - remove data that was still needed. This led to transient failures - along the lines of cache lookup failed for relation 1255. - - - - - - Unconditionally WAL-log creation of the init fork for an - unlogged table (Michael Paquier) - - - - Previously, this was skipped when - = minimal, but actually it's necessary even in that case - to ensure that the unlogged table is properly reset to empty after a - crash. - - - - - - Reduce interlocking on standby servers during the replay of btree - index vacuuming operations (Simon Riggs) - - - - This change avoids substantial replication delays that sometimes - occurred while replaying such operations. - - - - - - If the stats collector dies during hot standby, restart it (Takayuki - Tsunakawa) - - - - - - Ensure that hot standby feedback works correctly when it's enabled at - standby server start (Ants Aasma, Craig Ringer) - - - - - - Check for interrupts while hot standby is waiting for a conflicting - query (Simon Riggs) - - - - - - Avoid constantly respawning the autovacuum launcher in a corner case - (Amit Khandekar) - - - - This fix avoids problems when autovacuum is nominally off and there - are some tables that require freezing, but all such tables are - already being processed by autovacuum workers. - - - - - - Fix check for when an extension member object can be dropped (Tom Lane) - - - - Extension upgrade scripts should be able to drop member objects, - but this was disallowed for serial-column sequences, and possibly - other cases. - - - - - - Make sure ALTER TABLE preserves index tablespace - assignments when rebuilding indexes (Tom Lane, Michael Paquier) - - - - Previously, non-default settings - of could result in broken - indexes. - - - - - - Fix incorrect updating of trigger function properties when changing a - foreign-key constraint's deferrability properties with ALTER - TABLE ... ALTER CONSTRAINT (Tom Lane) - - - - This led to odd failures during subsequent exercise of the foreign - key, as the triggers were fired at the wrong times. - - - - - - Prevent dropping a foreign-key constraint if there are pending - trigger events for the referenced relation (Tom Lane) - - - - This avoids could not find trigger NNN - or relation NNN has no triggers errors. - - - - - - Fix processing of OID column when a table with OIDs is associated to - a parent with OIDs via ALTER TABLE ... INHERIT (Amit - Langote) - - - - The OID column should be treated the same as regular user columns in - this case, but it wasn't, leading to odd behavior in later - inheritance changes. - - - - - - Fix CREATE OR REPLACE VIEW to update the view query - before attempting to apply the new view options (Dean Rasheed) - - - - Previously the command would fail if the new options were - inconsistent with the old view definition. - - - - - - Report correct object identity during ALTER TEXT SEARCH - CONFIGURATION (Artur Zakirov) - - - - The wrong catalog OID was reported to extensions such as logical - decoding. - - - - - - Check for serializability conflicts before reporting - constraint-violation failures (Thomas Munro) - - - - When using serializable transaction isolation, it is desirable - that any error due to concurrent transactions should manifest - as a serialization failure, thereby cueing the application that - a retry might succeed. Unfortunately, this does not reliably - happen for duplicate-key failures caused by concurrent insertions. - This change ensures that such an error will be reported as a - serialization error if the application explicitly checked for - the presence of a conflicting key (and did not find it) earlier - in the transaction. - - - - - - Prevent multicolumn expansion of foo.* in - an UPDATE source expression (Tom Lane) - - - - This led to UPDATE target count mismatch --- internal - error. Now the syntax is understood as a whole-row variable, - as it would be in other contexts. - - - - - - Ensure that column typmods are determined accurately for - multi-row VALUES constructs (Tom Lane) - - - - This fixes problems occurring when the first value in a column has a - determinable typmod (e.g., length for a varchar value) but - later values don't share the same limit. - - - - - - Throw error for an unfinished Unicode surrogate pair at the end of a - Unicode string (Tom Lane) - - - - Normally, a Unicode surrogate leading character must be followed by a - Unicode surrogate trailing character, but the check for this was - missed if the leading character was the last character in a Unicode - string literal (U&'...') or Unicode identifier - (U&"..."). - - - - - - Ensure that a purely negative text search query, such - as !foo, matches empty tsvectors (Tom Dunstan) - - - - Such matches were found by GIN index searches, but not by sequential - scans or GiST index searches. - - - - - - Prevent crash when ts_rewrite() replaces a non-top-level - subtree with an empty query (Artur Zakirov) - - - - - - Fix performance problems in ts_rewrite() (Tom Lane) - - - - - - Fix ts_rewrite()'s handling of nested NOT operators - (Tom Lane) - - - - - - Fix array_fill() to handle empty arrays properly (Tom Lane) - - - - - - Fix one-byte buffer overrun in quote_literal_cstr() - (Heikki Linnakangas) - - - - The overrun occurred only if the input consisted entirely of single - quotes and/or backslashes. - - - - - - Prevent multiple calls of pg_start_backup() - and pg_stop_backup() from running concurrently (Michael - Paquier) - - - - This avoids an assertion failure, and possibly worse things, if - someone tries to run these functions in parallel. - - - - - - Avoid discarding interval-to-interval casts - that aren't really no-ops (Tom Lane) - - - - In some cases, a cast that should result in zeroing out - low-order interval fields was mistakenly deemed to be a - no-op and discarded. An example is that casting from INTERVAL - MONTH to INTERVAL YEAR failed to clear the months field. - - - - - - Ensure that cached plans are invalidated by changes in foreign-table - options (Amit Langote, Etsuro Fujita, Ashutosh Bapat) - - - - - - Fix pg_dump to dump user-defined casts and transforms - that use built-in functions (Stephen Frost) - - - - - - Fix pg_restore with - to behave more sanely if an archive contains - unrecognized DROP commands (Tom Lane) - - - - This doesn't fix any live bug, but it may improve the behavior in - future if pg_restore is used with an archive - generated by a later pg_dump version. - - - - - - Fix pg_basebackup's rate limiting in the presence of - slow I/O (Antonin Houska) - - - - If disk I/O was transiently much slower than the specified rate - limit, the calculation overflowed, effectively disabling the rate - limit for the rest of the run. - - - - - - Fix pg_basebackup's handling of - symlinked pg_stat_tmp and pg_replslot - subdirectories (Magnus Hagander, Michael Paquier) - - - - - - Fix possible pg_basebackup failure on standby - server when including WAL files (Amit Kapila, Robert Haas) - - - - - - Ensure that the Python exception objects we create for PL/Python are - properly reference-counted (Rafa de la Torre, Tom Lane) - - - - This avoids failures if the objects are used after a Python garbage - collection cycle has occurred. - - - - - - Fix PL/Tcl to support triggers on tables that have .tupno - as a column name (Tom Lane) - - - - This matches the (previously undocumented) behavior of - PL/Tcl's spi_exec and spi_execp commands, - namely that a magic .tupno column is inserted only if - there isn't a real column named that. - - - - - - Allow DOS-style line endings in ~/.pgpass files, - even on Unix (Vik Fearing) - - - - This change simplifies use of the same password file across Unix and - Windows machines. - - - - - - Fix one-byte buffer overrun if ecpg is given a file - name that ends with a dot (Takayuki Tsunakawa) - - - - - - Fix psql's tab completion for ALTER DEFAULT - PRIVILEGES (Gilles Darold, Stephen Frost) - - - - - - In psql, treat an empty or all-blank setting of - the PAGER environment variable as meaning no - pager (Tom Lane) - - - - Previously, such a setting caused output intended for the pager to - vanish entirely. - - - - - - Improve contrib/dblink's reporting of - low-level libpq errors, such as out-of-memory - (Joe Conway) - - - - - - Teach contrib/dblink to ignore irrelevant server options - when it uses a contrib/postgres_fdw foreign server as - the source of connection options (Corey Huinker) - - - - Previously, if the foreign server object had options that were not - also libpq connection options, an error occurred. - - - - - - On Windows, ensure that environment variable changes are propagated - to DLLs built with debug options (Christian Ullrich) - - - - - - Sync our copy of the timezone library with IANA release tzcode2016j - (Tom Lane) - - - - This fixes various issues, most notably that timezone data - installation failed if the target directory didn't support hard - links. - - - - - - Update time zone data files to tzdata release 2016j - for DST law changes in northern Cyprus (adding a new zone - Asia/Famagusta), Russia (adding a new zone Europe/Saratov), Tonga, - and Antarctica/Casey. - Historical corrections for Italy, Kazakhstan, Malta, and Palestine. - Switch to preferring numeric zone abbreviations for Tonga. - - - - - - - - - - Release 9.4.10 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.4.9. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.10 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted free space maps. - - - - Also, if you are upgrading from a version earlier than 9.4.6, - see . - - - - - Changes - - - - - - Fix WAL-logging of truncation of relation free space maps and - visibility maps (Pavan Deolasee, Heikki Linnakangas) - - - - It was possible for these files to not be correctly restored during - crash recovery, or to be written incorrectly on a standby server. - Bogus entries in a free space map could lead to attempts to access - pages that have been truncated away from the relation itself, typically - producing errors like could not read block XXX: - read only 0 of 8192 bytes. Checksum failures in the - visibility map are also possible, if checksumming is enabled. - - - - Procedures for determining whether there is a problem and repairing it - if so are discussed at - . - - - - - - Fix incorrect creation of GIN index WAL records on big-endian machines - (Tom Lane) - - - - The typical symptom was unexpected GIN leaf action errors - during WAL replay. - - - - - - Fix SELECT FOR UPDATE/SHARE to correctly lock tuples that - have been updated by a subsequently-aborted transaction - (Álvaro Herrera) - - - - In 9.5 and later, the SELECT would sometimes fail to - return such tuples at all. A failure has not been proven to occur in - earlier releases, but might be possible with concurrent updates. - - - - - - Fix EvalPlanQual rechecks involving CTE scans (Tom Lane) - - - - The recheck would always see the CTE as returning no rows, typically - leading to failure to update rows that were recently updated. - - - - - - Fix improper repetition of previous results from hashed aggregation in - a subquery (Andrew Gierth) - - - - The test to see if we can reuse a previously-computed hash table of - the aggregate state values neglected the possibility of an outer query - reference appearing in an aggregate argument expression. A change in - the value of such a reference should lead to recalculating the hash - table, but did not. - - - - - - Fix query-lifespan memory leak in a bulk UPDATE on a table - with a PRIMARY KEY or REPLICA IDENTITY index - (Tom Lane) - - - - - - Fix EXPLAIN to emit valid XML when - is on (Markus Winand) - - - - Previously the XML output-format option produced syntactically invalid - tags such as <I/O-Read-Time>. That is now - rendered as <I-O-Read-Time>. - - - - - - Suppress printing of zeroes for unmeasured times - in EXPLAIN (Maksim Milyutin) - - - - Certain option combinations resulted in printing zero values for times - that actually aren't ever measured in that combination. Our general - policy in EXPLAIN is not to print such fields at all, so - do that consistently in all cases. - - - - - - Fix timeout length when VACUUM is waiting for exclusive - table lock so that it can truncate the table (Simon Riggs) - - - - The timeout was meant to be 50 milliseconds, but it was actually only - 50 microseconds, causing VACUUM to give up on truncation - much more easily than intended. Set it to the intended value. - - - - - - Fix bugs in merging inherited CHECK constraints while - creating or altering a table (Tom Lane, Amit Langote) - - - - Allow identical CHECK constraints to be added to a parent - and child table in either order. Prevent merging of a valid - constraint from the parent table with a NOT VALID - constraint on the child. Likewise, prevent merging of a NO - INHERIT child constraint with an inherited constraint. - - - - - - Remove artificial restrictions on the values accepted - by numeric_in() and numeric_recv() - (Tom Lane) - - - - We allow numeric values up to the limit of the storage format (more - than 1e100000), so it seems fairly pointless - that numeric_in() rejected scientific-notation exponents - above 1000. Likewise, it was silly for numeric_recv() to - reject more than 1000 digits in an input value. - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - Fix logical WAL decoding to work properly when a subtransaction's WAL - output is large enough to spill to disk (Andres Freund) - - - - - - - Fix buffer overread in logical WAL decoding (Tom Lane) - - - - Logical decoding of a tuple update record read 23 bytes too many, - which was usually harmless but with very bad luck could result in a - crash. - - - - - - Fix file descriptor leakage when truncating a temporary relation of - more than 1GB (Andres Freund) - - - - - - Disallow starting a standalone backend with standby_mode - turned on (Michael Paquier) - - - - This can't do anything useful, since there will be no WAL receiver - process to fetch more WAL data; and it could result in misbehavior - in code that wasn't designed with this situation in mind. - - - - - - Properly initialize replication slot state when recycling a - previously-used slot (Michael Paquier) - - - - This failure to reset all of the fields of the slot could - prevent VACUUM from removing dead tuples. - - - - - - Round shared-memory allocation request to a multiple of the actual - huge page size when attempting to use huge pages on Linux (Tom Lane) - - - - This avoids possible failures during munmap() on systems - with atypical default huge page sizes. Except in crash-recovery - cases, there were no ill effects other than a log message. - - - - - - Use a more random value for the dynamic shared memory control - segment's ID (Robert Haas, Tom Lane) - - - - Previously, the same value would be chosen every time, because it was - derived from random() but srandom() had not - yet been called. While relatively harmless, this was not the intended - behavior. - - - - - - On Windows, retry creation of the dynamic shared memory control - segment after an access-denied error (Kyotaro Horiguchi, Amit Kapila) - - - - Windows sometimes returns ERROR_ACCESS_DENIED rather - than ERROR_ALREADY_EXISTS when there is an existing - segment. This led to postmaster startup failure due to believing that - the former was an unrecoverable error. - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - Make ecpg's and - options work consistently with our other executables (Haribabu Kommi) - - - - - - Fix pgbench's calculation of average latency - (Fabien Coelho) - - - - The calculation was incorrect when there were \sleep - commands in the script, or when the test duration was specified in - number of transactions rather than total time. - - - - - - In pg_dump, never dump range constructor functions - (Tom Lane) - - - - This oversight led to pg_upgrade failures with - extensions containing range types, due to duplicate creation of the - constructor functions. - - - - - - In pg_xlogdump, retry opening new WAL segments when - using option (Magnus Hagander) - - - - This allows for a possible delay in the server's creation of the next - segment. - - - - - - Fix pg_xlogdump to cope with a WAL file that begins - with a continuation record spanning more than one page (Pavan - Deolasee) - - - - - - Fix contrib/pg_buffercache to work - when shared_buffers exceeds 256GB (KaiGai Kohei) - - - - - - Fix contrib/intarray/bench/bench.pl to print the results - of the EXPLAIN it does when given the option - (Daniel Gustafsson) - - - - - - Install TAP test infrastructure so that it's available for extension - testing (Craig Ringer) - - - - When PostgreSQL has been configured - with , make install will now - install the Perl support files for TAP testing where PGXS can find - them. This allows non-core extensions to - use $(prove_check) without extra tests. - - - - - - In MSVC builds, include pg_recvlogical in a - client-only installation (MauMau) - - - - - - Update Windows time zone mapping to recognize some time zone names - added in recent Windows versions (Michael Paquier) - - - - - - Prevent failure of obsolete dynamic time zone abbreviations (Tom Lane) - - - - If a dynamic time zone abbreviation does not match any entry in the - referenced time zone, treat it as equivalent to the time zone name. - This avoids unexpected failures when IANA removes abbreviations from - their time zone database, as they did in tzdata - release 2016f and seem likely to do again in the future. The - consequences were not limited to not recognizing the individual - abbreviation; any mismatch caused - the pg_timezone_abbrevs view to fail altogether. - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.4.9 - - - Release date: - 2016-08-11 - - - - This release contains a variety of fixes from 9.4.8. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.9 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.6, - see . - - - - - Changes - - - - - - Fix possible mis-evaluation of - nested CASE-WHEN expressions (Heikki - Linnakangas, Michael Paquier, Tom Lane) - - - - A CASE expression appearing within the test value - subexpression of another CASE could become confused about - whether its own test value was null or not. Also, inlining of a SQL - function implementing the equality operator used by - a CASE expression could result in passing the wrong test - value to functions called within a CASE expression in the - SQL function's body. If the test values were of different data - types, a crash might result; moreover such situations could be abused - to allow disclosure of portions of server memory. (CVE-2016-5423) - - - - - - Fix client programs' handling of special characters in database and - role names (Noah Misch, Nathan Bossart, Michael Paquier) - - - - Numerous places in vacuumdb and other client programs - could become confused by database and role names containing double - quotes or backslashes. Tighten up quoting rules to make that safe. - Also, ensure that when a conninfo string is used as a database name - parameter to these programs, it is correctly treated as such throughout. - - - - Fix handling of paired double quotes - in psql's \connect - and \password commands to match the documentation. - - - - Introduce a new option - in psql's \connect command to allow - explicit control of whether to re-use connection parameters from a - previous connection. (Without this, the choice is based on whether - the database name looks like a conninfo string, as before.) This - allows secure handling of database names containing special - characters in pg_dumpall scripts. - - - - pg_dumpall now refuses to deal with database and role - names containing carriage returns or newlines, as it seems impractical - to quote those characters safely on Windows. In future we may reject - such names on the server side, but that step has not been taken yet. - - - - These are considered security fixes because crafted object names - containing special characters could have been used to execute - commands with superuser privileges the next time a superuser - executes pg_dumpall or other routine maintenance - operations. (CVE-2016-5424) - - - - - - Fix corner-case misbehaviors for IS NULL/IS NOT - NULL applied to nested composite values (Andrew Gierth, Tom Lane) - - - - The SQL standard specifies that IS NULL should return - TRUE for a row of all null values (thus ROW(NULL,NULL) IS - NULL yields TRUE), but this is not meant to apply recursively - (thus ROW(NULL, ROW(NULL,NULL)) IS NULL yields FALSE). - The core executor got this right, but certain planner optimizations - treated the test as recursive (thus producing TRUE in both cases), - and contrib/postgres_fdw could produce remote queries - that misbehaved similarly. - - - - - - Make the inet and cidr data types properly reject - IPv6 addresses with too many colon-separated fields (Tom Lane) - - - - - - Prevent crash in close_ps() - (the point ## lseg operator) - for NaN input coordinates (Tom Lane) - - - - Make it return NULL instead of crashing. - - - - - - Avoid possible crash in pg_get_expr() when inconsistent - values are passed to it (Michael Paquier, Thomas Munro) - - - - - - Fix several one-byte buffer over-reads in to_number() - (Peter Eisentraut) - - - - In several cases the to_number() function would read one - more character than it should from the input string. There is a - small chance of a crash, if the input happens to be adjacent to the - end of memory. - - - - - - Do not run the planner on the query contained in CREATE - MATERIALIZED VIEW or CREATE TABLE AS - when WITH NO DATA is specified (Michael Paquier, - Tom Lane) - - - - This avoids some unnecessary failure conditions, for example if a - stable function invoked by the materialized view depends on a table - that doesn't exist yet. - - - - - - Avoid unsafe intermediate state during expensive paths - through heap_update() (Masahiko Sawada, Andres Freund) - - - - Previously, these cases locked the target tuple (by setting its XMAX) - but did not WAL-log that action, thus risking data integrity problems - if the page were spilled to disk and then a database crash occurred - before the tuple update could be completed. - - - - - - Fix hint bit update during WAL replay of row locking operations - (Andres Freund) - - - - The only known consequence of this problem is that row locks held by - a prepared, but uncommitted, transaction might fail to be enforced - after a crash and restart. - - - - - - Avoid unnecessary could not serialize access errors when - acquiring FOR KEY SHARE row locks in serializable mode - (Álvaro Herrera) - - - - - - Avoid crash in postgres -C when the specified variable - has a null string value (Michael Paquier) - - - - - - Fix possible loss of large subtransactions in logical decoding - (Petru-Florin Mihancea) - - - - - - Fix failure of logical decoding when a subtransaction contains no - actual changes (Marko Tiikkaja, Andrew Gierth) - - - - - - Ensure that backends see up-to-date statistics for shared catalogs - (Tom Lane) - - - - The statistics collector failed to update the statistics file for - shared catalogs after a request from a regular backend. This problem - was partially masked because the autovacuum launcher regularly makes - requests that did cause such updates; however, it became obvious with - autovacuum disabled. - - - - - - Avoid redundant writes of the statistics files when multiple - backends request updates close together (Tom Lane, Tomas Vondra) - - - - - - Avoid consuming a transaction ID during VACUUM - (Alexander Korotkov) - - - - Some cases in VACUUM unnecessarily caused an XID to be - assigned to the current transaction. Normally this is negligible, - but if one is up against the XID wraparound limit, consuming more - XIDs during anti-wraparound vacuums is a very bad thing. - - - - - - - Avoid canceling hot-standby queries during VACUUM FREEZE - (Simon Riggs, Álvaro Herrera) - - - - VACUUM FREEZE on an otherwise-idle master server could - result in unnecessary cancellations of queries on its standby - servers. - - - - - - Prevent possible failure when vacuuming multixact IDs in an - installation that has been pg_upgrade'd from pre-9.3 (Andrew Gierth, - Álvaro Herrera) - - - - The usual symptom of this bug is errors - like MultiXactId NNN has not been created - yet -- apparent wraparound. - - - - - - When a manual ANALYZE specifies a column list, don't - reset the table's changes_since_analyze counter - (Tom Lane) - - - - If we're only analyzing some columns, we should not prevent routine - auto-analyze from happening for the other columns. - - - - - - Fix ANALYZE's overestimation of n_distinct - for a unique or nearly-unique column with many null entries (Tom - Lane) - - - - The nulls could get counted as though they were themselves distinct - values, leading to serious planner misestimates in some types of - queries. - - - - - - Prevent autovacuum from starting multiple workers for the same shared - catalog (Álvaro Herrera) - - - - Normally this isn't much of a problem because the vacuum doesn't take - long anyway; but in the case of a severely bloated catalog, it could - result in all but one worker uselessly waiting instead of doing - useful work on other tables. - - - - - - Avoid duplicate buffer lock release when abandoning a b-tree index - page deletion attempt (Tom Lane) - - - - This mistake prevented VACUUM from completing in some - cases involving corrupt b-tree indexes. - - - - - - Prevent infinite loop in GiST index build for geometric columns - containing NaN component values (Tom Lane) - - - - - - Fix contrib/btree_gin to handle the smallest - possible bigint value correctly (Peter Eisentraut) - - - - - - Teach libpq to correctly decode server version from future servers - (Peter Eisentraut) - - - - It's planned to switch to two-part instead of three-part server - version numbers for releases after 9.6. Make sure - that PQserverVersion() returns the correct value for - such cases. - - - - - - Fix ecpg's code for unsigned long long - array elements (Michael Meskes) - - - - - - In pg_dump with both and - options, avoid emitting an unwanted CREATE SCHEMA public - command (David Johnston, Tom Lane) - - - - - - Improve handling of SIGTERM/control-C in - parallel pg_dump and pg_restore (Tom - Lane) - - - - Make sure that the worker processes will exit promptly, and also arrange - to send query-cancel requests to the connected backends, in case they - are doing something long-running such as a CREATE INDEX. - - - - - - Fix error reporting in parallel pg_dump - and pg_restore (Tom Lane) - - - - Previously, errors reported by pg_dump - or pg_restore worker processes might never make it to - the user's console, because the messages went through the master - process, and there were various deadlock scenarios that would prevent - the master process from passing on the messages. Instead, just print - everything to stderr. In some cases this will result in - duplicate messages (for instance, if all the workers report a server - shutdown), but that seems better than no message. - - - - - - Ensure that parallel pg_dump - or pg_restore on Windows will shut down properly - after an error (Kyotaro Horiguchi) - - - - Previously, it would report the error, but then just sit until - manually stopped by the user. - - - - - - Make pg_dump behave better when built without zlib - support (Kyotaro Horiguchi) - - - - It didn't work right for parallel dumps, and emitted some rather - pointless warnings in other cases. - - - - - - Make pg_basebackup accept -Z 0 as - specifying no compression (Fujii Masao) - - - - - - Fix makefiles' rule for building AIX shared libraries to be safe for - parallel make (Noah Misch) - - - - - - Fix TAP tests and MSVC scripts to work when build directory's path - name contains spaces (Michael Paquier, Kyotaro Horiguchi) - - - - - - Be more predictable about reporting statement timeout - versus lock timeout (Tom Lane) - - - - On heavily loaded machines, the regression tests sometimes failed due - to reporting lock timeout even though the statement timeout - should have occurred first. - - - - - - Make regression tests safe for Danish and Welsh locales (Jeff Janes, - Tom Lane) - - - - Change some test data that triggered the unusual sorting rules of - these locales. - - - - - - Update our copy of the timezone code to match - IANA's tzcode release 2016c (Tom Lane) - - - - This is needed to cope with anticipated future changes in the time - zone data files. It also fixes some corner-case bugs in coping with - unusual time zones. - - - - - - Update time zone data files to tzdata release 2016f - for DST law changes in Kemerovo and Novosibirsk, plus historical - corrections for Azerbaijan, Belarus, and Morocco. - - - - - - - - - - Release 9.4.8 - - - Release date: - 2016-05-12 - - - - This release contains a variety of fixes from 9.4.7. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.8 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.6, - see . - - - - - Changes - - - - - - Clear the OpenSSL error queue before OpenSSL calls, rather than - assuming it's clear already; and make sure we leave it clear - afterwards (Peter Geoghegan, Dave Vitek, Peter Eisentraut) - - - - This change prevents problems when there are multiple connections - using OpenSSL within a single process and not all the code involved - follows the same rules for when to clear the error queue. - Failures have been reported specifically when a client application - uses SSL connections in libpq concurrently with - SSL connections using the PHP, Python, or Ruby wrappers for OpenSSL. - It's possible for similar problems to arise within the server as well, - if an extension module establishes an outgoing SSL connection. - - - - - - Fix failed to build any N-way joins - planner error with a full join enclosed in the right-hand side of a - left join (Tom Lane) - - - - - - Fix incorrect handling of equivalence-class tests in multilevel - nestloop plans (Tom Lane) - - - - Given a three-or-more-way equivalence class of variables, such - as X.X = Y.Y = Z.Z, it was possible for the planner to omit - some of the tests needed to enforce that all the variables are actually - equal, leading to join rows being output that didn't satisfy - the WHERE clauses. For various reasons, erroneous plans - were seldom selected in practice, so that this bug has gone undetected - for a long time. - - - - - - Fix query-lifespan memory leak in GIN index scans (Julien Rouhaud) - - - - - - Fix query-lifespan memory leak and potential index corruption hazard in - GIN index insertion (Tom Lane) - - - - The memory leak would typically not amount to much in simple queries, - but it could be very substantial during a large GIN index build with - high maintenance_work_mem. - - - - - - Fix possible misbehavior of TH, th, - and Y,YYY format codes in to_timestamp() - (Tom Lane) - - - - These could advance off the end of the input string, causing subsequent - format codes to read garbage. - - - - - - Fix dumping of rules and views in which the array - argument of a value operator - ANY (array) construct is a sub-SELECT - (Tom Lane) - - - - - - Disallow newlines in ALTER SYSTEM parameter values - (Tom Lane) - - - - The configuration-file parser doesn't support embedded newlines in - string literals, so we mustn't allow them in values to be inserted - by ALTER SYSTEM. - - - - - - Fix ALTER TABLE ... REPLICA IDENTITY USING INDEX to - work properly if an index on OID is selected (David Rowley) - - - - - - Fix crash in logical decoding on alignment-picky platforms (Tom Lane, - Andres Freund) - - - - The failure occurred only with a transaction large enough to spill to - disk and a primary-key change within that transaction. - - - - - - Avoid repeated requests for feedback from receiver while shutting down - walsender (Nick Cleaton) - - - - - - Make pg_regress use a startup timeout from the - PGCTLTIMEOUT environment variable, if that's set (Tom Lane) - - - - This is for consistency with a behavior recently added - to pg_ctl; it eases automated testing on slow machines. - - - - - - Fix pg_upgrade to correctly restore extension - membership for operator families containing only one operator class - (Tom Lane) - - - - In such a case, the operator family was restored into the new database, - but it was no longer marked as part of the extension. This had no - immediate ill effects, but would cause later pg_dump - runs to emit output that would cause (harmless) errors on restore. - - - - - - Fix pg_upgrade to not fail when new-cluster TOAST rules - differ from old (Tom Lane) - - - - pg_upgrade had special-case code to handle the - situation where the new PostgreSQL version thinks that - a table should have a TOAST table while the old version did not. That - code was broken, so remove it, and instead do nothing in such cases; - there seems no reason to believe that we can't get along fine without - a TOAST table if that was okay according to the old version's rules. - - - - - - Reduce the number of SysV semaphores used by a build configured with - (Tom Lane) - - - - - - Rename internal function strtoi() - to strtoint() to avoid conflict with a NetBSD library - function (Thomas Munro) - - - - - - Fix reporting of errors from bind() - and listen() system calls on Windows (Tom Lane) - - - - - - Reduce verbosity of compiler output when building with Microsoft Visual - Studio (Christian Ullrich) - - - - - - Fix putenv() to work properly with Visual Studio 2013 - (Michael Paquier) - - - - - - Avoid possibly-unsafe use of Windows' FormatMessage() - function (Christian Ullrich) - - - - Use the FORMAT_MESSAGE_IGNORE_INSERTS flag where - appropriate. No live bug is known to exist here, but it seems like a - good idea to be careful. - - - - - - Update time zone data files to tzdata release 2016d - for DST law changes in Russia and Venezuela. There are new zone - names Europe/Kirov and Asia/Tomsk to reflect - the fact that these regions now have different time zone histories from - adjacent regions. - - - - - - - - - - Release 9.4.7 - - - Release date: - 2016-03-31 - - - - This release contains a variety of fixes from 9.4.6. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.7 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.6, - see . - - - - - Changes - - - - - - Fix incorrect handling of NULL index entries in - indexed ROW() comparisons (Tom Lane) - - - - An index search using a row comparison such as ROW(a, b) > - ROW('x', 'y') would stop upon reaching a NULL entry in - the b column, ignoring the fact that there might be - non-NULL b values associated with later values - of a. - - - - - - Avoid unlikely data-loss scenarios due to renaming files without - adequate fsync() calls before and after (Michael Paquier, - Tomas Vondra, Andres Freund) - - - - - - Fix bug in json_to_record() when a field of its input - object contains a sub-object with a field name matching one of the - requested output column names (Tom Lane) - - - - - - Fix misformatting of negative time zone offsets - by to_char()'s OF format code - (Thomas Munro, Tom Lane) - - - - - - Ignore parameter until - recovery has reached a consistent state (Michael Paquier) - - - - Previously, standby servers would delay application of WAL records in - response to recovery_min_apply_delay even while replaying - the initial portion of WAL needed to make their database state valid. - Since the standby is useless until it's reached a consistent database - state, this was deemed unhelpful. - - - - - - Correctly handle cases where pg_subtrans is close to XID - wraparound during server startup (Jeff Janes) - - - - - - Fix assorted bugs in logical decoding (Andres Freund) - - - - Trouble cases included tuples larger than one page when replica - identity is FULL, UPDATEs that change a - primary key within a transaction large enough to be spooled to disk, - incorrect reports of subxact logged without previous toplevel - record, and incorrect reporting of a transaction's commit time. - - - - - - Fix planner error with nested security barrier views when the outer - view has a WHERE clause containing a correlated subquery - (Dean Rasheed) - - - - - - Fix corner-case crash due to trying to free localeconv() - output strings more than once (Tom Lane) - - - - - - Fix parsing of affix files for ispell dictionaries - (Tom Lane) - - - - The code could go wrong if the affix file contained any characters - whose byte length changes during case-folding, for - example I in Turkish UTF8 locales. - - - - - - Avoid use of sscanf() to parse ispell - dictionary files (Artur Zakirov) - - - - This dodges a portability problem on FreeBSD-derived platforms - (including macOS). - - - - - - Avoid a crash on old Windows versions (before 7SP1/2008R2SP1) with an - AVX2-capable CPU and a Postgres build done with Visual Studio 2013 - (Christian Ullrich) - - - - This is a workaround for a bug in Visual Studio 2013's runtime - library, which Microsoft have stated they will not fix in that - version. - - - - - - Fix psql's tab completion logic to handle multibyte - characters properly (Kyotaro Horiguchi, Robert Haas) - - - - - - Fix psql's tab completion for - SECURITY LABEL (Tom Lane) - - - - Pressing TAB after SECURITY LABEL might cause a crash - or offering of inappropriate keywords. - - - - - - Make pg_ctl accept a wait timeout from the - PGCTLTIMEOUT environment variable, if none is specified on - the command line (Noah Misch) - - - - This eases testing of slower buildfarm members by allowing them - to globally specify a longer-than-normal timeout for postmaster - startup and shutdown. - - - - - - Fix incorrect test for Windows service status - in pg_ctl (Manuel Mathar) - - - - The previous set of minor releases attempted to - fix pg_ctl to properly determine whether to send log - messages to Window's Event Log, but got the test backwards. - - - - - - Fix pgbench to correctly handle the combination - of -C and -M prepared options (Tom Lane) - - - - - - In pg_upgrade, skip creating a deletion script when - the new data directory is inside the old data directory (Bruce - Momjian) - - - - Blind application of the script in such cases would result in loss of - the new data directory. - - - - - - In PL/Perl, properly translate empty Postgres arrays into empty Perl - arrays (Alex Hunsaker) - - - - - - Make PL/Python cope with function names that aren't valid Python - identifiers (Jim Nasby) - - - - - - Fix multiple mistakes in the statistics returned - by contrib/pgstattuple's pgstatindex() - function (Tom Lane) - - - - - - Remove dependency on psed in MSVC builds, since it's no - longer provided by core Perl (Michael Paquier, Andrew Dunstan) - - - - - - Update time zone data files to tzdata release 2016c - for DST law changes in Azerbaijan, Chile, Haiti, Palestine, and Russia - (Altai, Astrakhan, Kirov, Sakhalin, Ulyanovsk regions), plus - historical corrections for Lithuania, Moldova, and Russia - (Kaliningrad, Samara, Volgograd). - - - - - - - - - - Release 9.4.6 - - - Release date: - 2016-02-11 - - - - This release contains a variety of fixes from 9.4.5. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.6 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading an installation that contains any GIN - indexes that use the (non-default) jsonb_path_ops operator - class, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.4.4, - see . - - - - - Changes - - - - - - - - Fix inconsistent hash calculations in jsonb_path_ops GIN - indexes (Tom Lane) - - - - When processing jsonb values that contain both scalars and - sub-objects at the same nesting level, for example an array containing - both scalars and sub-arrays, key hash values could be calculated - differently than they would be for the same key in a different context. - This could result in queries not finding entries that they should find. - Fixing this means that existing indexes may now be inconsistent with the - new hash calculation code. Users - should REINDEX jsonb_path_ops GIN indexes after - installing this update to make sure that all searches work as expected. - - - - - - Fix infinite loops and buffer-overrun problems in regular expressions - (Tom Lane) - - - - Very large character ranges in bracket expressions could cause - infinite loops in some cases, and memory overwrites in other cases. - (CVE-2016-0773) - - - - - - - - Perform an immediate shutdown if the postmaster.pid file - is removed (Tom Lane) - - - - The postmaster now checks every minute or so - that postmaster.pid is still there and still contains its - own PID. If not, it performs an immediate shutdown, as though it had - received SIGQUIT. The main motivation for this change - is to ensure that failed buildfarm runs will get cleaned up without - manual intervention; but it also serves to limit the bad effects if a - DBA forcibly removes postmaster.pid and then starts a new - postmaster. - - - - - - - - In SERIALIZABLE transaction isolation mode, serialization - anomalies could be missed due to race conditions during insertions - (Kevin Grittner, Thomas Munro) - - - - - - - - Fix failure to emit appropriate WAL records when doing ALTER - TABLE ... SET TABLESPACE for unlogged relations (Michael Paquier, - Andres Freund) - - - - Even though the relation's data is unlogged, the move must be logged or - the relation will be inaccessible after a standby is promoted to master. - - - - - - - - Fix possible misinitialization of unlogged relations at the end of - crash recovery (Andres Freund, Michael Paquier) - - - - - - - - Ensure walsender slots are fully re-initialized when being re-used - (Magnus Hagander) - - - - - - - - Fix ALTER COLUMN TYPE to reconstruct inherited check - constraints properly (Tom Lane) - - - - - - - - Fix REASSIGN OWNED to change ownership of composite types - properly (Álvaro Herrera) - - - - - - - - Fix REASSIGN OWNED and ALTER OWNER to correctly - update granted-permissions lists when changing owners of data types, - foreign data wrappers, or foreign servers (Bruce Momjian, - Álvaro Herrera) - - - - - - - - Fix REASSIGN OWNED to ignore foreign user mappings, - rather than fail (Álvaro Herrera) - - - - - - - - Fix possible crash after doing query rewrite for an updatable view - (Stephen Frost) - - - - - - - - Fix planner's handling of LATERAL references (Tom - Lane) - - - - This fixes some corner cases that led to failed to build any - N-way joins or could not devise a query plan planner - failures. - - - - - - - - Add more defenses against bad planner cost estimates for GIN index - scans when the index's internal statistics are very out-of-date - (Tom Lane) - - - - - - - - Make planner cope with hypothetical GIN indexes suggested by an index - advisor plug-in (Julien Rouhaud) - - - - - - - - Speed up generation of unique table aliases in EXPLAIN and - rule dumping, and ensure that generated aliases do not - exceed NAMEDATALEN (Tom Lane) - - - - - - - - Fix dumping of whole-row Vars in ROW() - and VALUES() lists (Tom Lane) - - - - - - - - Translation of minus-infinity dates and timestamps to json - or jsonb incorrectly rendered them as plus-infinity (Tom Lane) - - - - - - - - Fix possible internal overflow in numeric division - (Dean Rasheed) - - - - - - - - Fix enforcement of restrictions inside parentheses within regular - expression lookahead constraints (Tom Lane) - - - - Lookahead constraints aren't allowed to contain backrefs, and - parentheses within them are always considered non-capturing, according - to the manual. However, the code failed to handle these cases properly - inside a parenthesized subexpression, and would give unexpected - results. - - - - - - - - Conversion of regular expressions to indexscan bounds could produce - incorrect bounds from regexps containing lookahead constraints - (Tom Lane) - - - - - - - - Fix regular-expression compiler to handle loops of constraint arcs - (Tom Lane) - - - - The code added for CVE-2007-4772 was both incomplete, in that it didn't - handle loops involving more than one state, and incorrect, in that it - could cause assertion failures (though there seem to be no bad - consequences of that in a non-assert build). Multi-state loops would - cause the compiler to run until the query was canceled or it reached - the too-many-states error condition. - - - - - - - - Improve memory-usage accounting in regular-expression compiler - (Tom Lane) - - - - This causes the code to emit regular expression is too - complex errors in some cases that previously used unreasonable - amounts of time and memory. - - - - - - - - Improve performance of regular-expression compiler (Tom Lane) - - - - - - Make %h and %r escapes - in log_line_prefix work for messages emitted due - to log_connections (Tom Lane) - - - - Previously, %h/%r started to work just after a - new session had emitted the connection received log message; - now they work for that message too. - - - - - - - - On Windows, ensure the shared-memory mapping handle gets closed in - child processes that don't need it (Tom Lane, Amit Kapila) - - - - This oversight resulted in failure to recover from crashes - whenever logging_collector is turned on. - - - - - - - - Fix possible failure to detect socket EOF in non-blocking mode on - Windows (Tom Lane) - - - - It's not entirely clear whether this problem can happen in pre-9.5 - branches, but if it did, the symptom would be that a walsender process - would wait indefinitely rather than noticing a loss of connection. - - - - - - Avoid leaking a token handle during SSPI authentication - (Christian Ullrich) - - - - - - - - In psql, ensure that libreadline's idea - of the screen size is updated when the terminal window size changes - (Merlin Moncure) - - - - Previously, libreadline did not notice if the window - was resized during query output, leading to strange behavior during - later input of multiline queries. - - - - - - Fix psql's \det command to interpret its - pattern argument the same way as other \d commands with - potentially schema-qualified patterns do (Reece Hart) - - - - - - - - Avoid possible crash in psql's \c command - when previous connection was via Unix socket and command specifies a - new hostname and same username (Tom Lane) - - - - - - - - In pg_ctl start -w, test child process status directly - rather than relying on heuristics (Tom Lane, Michael Paquier) - - - - Previously, pg_ctl relied on an assumption that the new - postmaster would always create postmaster.pid within five - seconds. But that can fail on heavily-loaded systems, - causing pg_ctl to report incorrectly that the - postmaster failed to start. - - - - Except on Windows, this change also means that a pg_ctl start - -w done immediately after another such command will now reliably - fail, whereas previously it would report success if done within two - seconds of the first command. - - - - - - - - In pg_ctl start -w, don't attempt to use a wildcard listen - address to connect to the postmaster (Kondo Yuta) - - - - On Windows, pg_ctl would fail to detect postmaster - startup if listen_addresses is set to 0.0.0.0 - or ::, because it would try to use that value verbatim as - the address to connect to, which doesn't work. Instead assume - that 127.0.0.1 or ::1, respectively, is the - right thing to use. - - - - - - In pg_ctl on Windows, check service status to decide - where to send output, rather than checking if standard output is a - terminal (Michael Paquier) - - - - - - - - In pg_dump and pg_basebackup, adopt - the GNU convention for handling tar-archive members exceeding 8GB - (Tom Lane) - - - - The POSIX standard for tar file format does not allow - archive member files to exceed 8GB, but most modern implementations - of tar support an extension that fixes that. Adopt - this extension so that pg_dump with no - longer fails on tables with more than 8GB of data, and so - that pg_basebackup can handle files larger than 8GB. - In addition, fix some portability issues that could cause failures for - members between 4GB and 8GB on some platforms. Potentially these - problems could cause unrecoverable data loss due to unreadable backup - files. - - - - - - Fix assorted corner-case bugs in pg_dump's processing - of extension member objects (Tom Lane) - - - - - - Make pg_dump mark a view's triggers as needing to be - processed after its rule, to prevent possible failure during - parallel pg_restore (Tom Lane) - - - - - - - - Ensure that relation option values are properly quoted - in pg_dump (Kouhei Sutou, Tom Lane) - - - - A reloption value that isn't a simple identifier or number could lead - to dump/reload failures due to syntax errors in CREATE statements - issued by pg_dump. This is not an issue with any - reloption currently supported by core PostgreSQL, but - extensions could allow reloptions that cause the problem. - - - - - - - - Avoid repeated password prompts during parallel pg_dump - (Zeus Kronion) - - - - - - - - Fix pg_upgrade's file-copying code to handle errors - properly on Windows (Bruce Momjian) - - - - - - Install guards in pgbench against corner-case overflow - conditions during evaluation of script-specified division or modulo - operators (Fabien Coelho, Michael Paquier) - - - - - - - - Fix failure to localize messages emitted - by pg_receivexlog and pg_recvlogical - (Ioseph Kim) - - - - - - Avoid dump/reload problems when using both plpython2 - and plpython3 (Tom Lane) - - - - In principle, both versions of PL/Python can be used in - the same database, though not in the same session (because the two - versions of libpython cannot safely be used concurrently). - However, pg_restore and pg_upgrade both - do things that can fall foul of the same-session restriction. Work - around that by changing the timing of the check. - - - - - - Fix PL/Python regression tests to pass with Python 3.5 - (Peter Eisentraut) - - - - - - - - Fix premature clearing of libpq's input buffer when - socket EOF is seen (Tom Lane) - - - - This mistake caused libpq to sometimes not report the - backend's final error message before reporting server closed the - connection unexpectedly. - - - - - - Prevent certain PL/Java parameters from being set by - non-superusers (Noah Misch) - - - - This change mitigates a PL/Java security bug - (CVE-2016-0766), which was fixed in PL/Java by marking - these parameters as superuser-only. To fix the security hazard for - sites that update PostgreSQL more frequently - than PL/Java, make the core code aware of them also. - - - - - - - - Improve libpq's handling of out-of-memory situations - (Michael Paquier, Amit Kapila, Heikki Linnakangas) - - - - - - - - Fix order of arguments - in ecpg-generated typedef statements - (Michael Meskes) - - - - - - - - Use %g not %f format - in ecpg's PGTYPESnumeric_from_double() - (Tom Lane) - - - - - - Fix ecpg-supplied header files to not contain comments - continued from a preprocessor directive line onto the next line - (Michael Meskes) - - - - Such a comment is rejected by ecpg. It's not yet clear - whether ecpg itself should be changed. - - - - - - Fix hstore_to_json_loose()'s test for whether - an hstore value can be converted to a JSON number (Tom Lane) - - - - Previously this function could be fooled by non-alphanumeric trailing - characters, leading to emitting syntactically-invalid JSON. - - - - - - - - Ensure that contrib/pgcrypto's crypt() - function can be interrupted by query cancel (Andreas Karlsson) - - - - - - In contrib/postgres_fdw, fix bugs triggered by use - of tableoid in data-modifying commands (Etsuro Fujita, - Robert Haas) - - - - - - - - Accept flex versions later than 2.5.x - (Tom Lane, Michael Paquier) - - - - Now that flex 2.6.0 has been released, the version checks in our build - scripts needed to be adjusted. - - - - - - Improve reproducibility of build output by ensuring filenames are given - to the linker in a fixed order (Christoph Berg) - - - - This avoids possible bitwise differences in the produced executable - files from one build to the next. - - - - - - - - Install our missing script where PGXS builds can find it - (Jim Nasby) - - - - This allows sane behavior in a PGXS build done on a machine where build - tools such as bison are missing. - - - - - - Ensure that dynloader.h is included in the installed - header files in MSVC builds (Bruce Momjian, Michael Paquier) - - - - - - - - Add variant regression test expected-output file to match behavior of - current libxml2 (Tom Lane) - - - - The fix for libxml2's CVE-2015-7499 causes it not to - output error context reports in some cases where it used to do so. - This seems to be a bug, but we'll probably have to live with it for - some time, so work around it. - - - - - - Update time zone data files to tzdata release 2016a for - DST law changes in Cayman Islands, Metlakatla, and Trans-Baikal - Territory (Zabaykalsky Krai), plus historical corrections for Pakistan. - - - - - - - - - - Release 9.4.5 - - - Release date: - 2015-10-08 - - - - This release contains a variety of fixes from 9.4.4. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.5 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.4, - see . - - - - - Changes - - - - - - - - Guard against stack overflows in json parsing - (Oskari Saarenmaa) - - - - If an application constructs PostgreSQL json - or jsonb values from arbitrary user input, the application's - users can reliably crash the PostgreSQL server, causing momentary - denial of service. (CVE-2015-5289) - - - - - - - - Fix contrib/pgcrypto to detect and report - too-short crypt() salts (Josh Kupershmidt) - - - - Certain invalid salt arguments crashed the server or disclosed a few - bytes of server memory. We have not ruled out the viability of - attacks that arrange for presence of confidential information in the - disclosed bytes, but they seem unlikely. (CVE-2015-5288) - - - - - - - - Fix subtransaction cleanup after a portal (cursor) belonging to an - outer subtransaction fails (Tom Lane, Michael Paquier) - - - - A function executed in an outer-subtransaction cursor could cause an - assertion failure or crash by referencing a relation created within an - inner subtransaction. - - - - - - - - Fix possible deadlock during WAL insertion - when commit_delay is set (Heikki Linnakangas) - - - - - - - - Ensure all relations referred to by an updatable view are properly - locked during an update statement (Dean Rasheed) - - - - - - - - Fix insertion of relations into the relation cache init file - (Tom Lane) - - - - An oversight in a patch in the most recent minor releases - caused pg_trigger_tgrelid_tgname_index to be omitted - from the init file. Subsequent sessions detected this, then deemed the - init file to be broken and silently ignored it, resulting in a - significant degradation in session startup time. In addition to fixing - the bug, install some guards so that any similar future mistake will be - more obvious. - - - - - - - - Avoid O(N^2) behavior when inserting many tuples into a SPI query - result (Neil Conway) - - - - - - - - Improve LISTEN startup time when there are many unread - notifications (Matt Newell) - - - - - - - - Fix performance problem when a session alters large numbers of foreign - key constraints (Jan Wieck, Tom Lane) - - - - This was seen primarily when restoring pg_dump output - for databases with many thousands of tables. - - - - - - - - Disable SSL renegotiation by default (Michael Paquier, Andres Freund) - - - - While use of SSL renegotiation is a good idea in theory, we have seen - too many bugs in practice, both in the underlying OpenSSL library and - in our usage of it. Renegotiation will be removed entirely in 9.5 and - later. In the older branches, just change the default value - of ssl_renegotiation_limit to zero (disabled). - - - - - - - - Lower the minimum values of the *_freeze_max_age parameters - (Andres Freund) - - - - This is mainly to make tests of related behavior less time-consuming, - but it may also be of value for installations with limited disk space. - - - - - - - - Limit the maximum value of wal_buffers to 2GB to avoid - server crashes (Josh Berkus) - - - - - - - - Avoid logging complaints when a parameter that can only be set at - server start appears multiple times in postgresql.conf, - and fix counting of line numbers after an include_dir - directive (Tom Lane) - - - - - - - - Fix rare internal overflow in multiplication of numeric values - (Dean Rasheed) - - - - - - - - Guard against hard-to-reach stack overflows involving record types, - range types, json, jsonb, tsquery, - ltxtquery and query_int (Noah Misch) - - - - - - - - Fix handling of DOW and DOY in datetime input - (Greg Stark) - - - - These tokens aren't meant to be used in datetime values, but previously - they resulted in opaque internal error messages rather - than invalid input syntax. - - - - - - - - Add more query-cancel checks to regular expression matching (Tom Lane) - - - - - - - - Add recursion depth protections to regular expression, SIMILAR - TO, and LIKE matching (Tom Lane) - - - - Suitable search patterns and a low stack depth limit could lead to - stack-overrun crashes. - - - - - - - - Fix potential infinite loop in regular expression execution (Tom Lane) - - - - A search pattern that can apparently match a zero-length string, but - actually doesn't match because of a back reference, could lead to an - infinite loop. - - - - - - - - In regular expression execution, correctly record match data for - capturing parentheses within a quantifier even when the match is - zero-length (Tom Lane) - - - - - - - - Fix low-memory failures in regular expression compilation - (Andreas Seltenreich) - - - - - - - - Fix low-probability memory leak during regular expression execution - (Tom Lane) - - - - - - - - Fix rare low-memory failure in lock cleanup during transaction abort - (Tom Lane) - - - - - - - - Fix unexpected out-of-memory situation during sort errors - when using tuplestores with small work_mem settings (Tom - Lane) - - - - - - - - Fix very-low-probability stack overrun in qsort (Tom Lane) - - - - - - - - Fix invalid memory alloc request size failure in hash joins - with large work_mem settings (Tomas Vondra, Tom Lane) - - - - - - - - Fix assorted planner bugs (Tom Lane) - - - - These mistakes could lead to incorrect query plans that would give wrong - answers, or to assertion failures in assert-enabled builds, or to odd - planner errors such as could not devise a query plan for the - given query, could not find pathkey item to - sort, plan should not reference subplan's variable, - or failed to assign all NestLoopParams to plan nodes. - Thanks are due to Andreas Seltenreich and Piotr Stefaniak for fuzz - testing that exposed these problems. - - - - - - - - Improve planner's performance for UPDATE/DELETE - on large inheritance sets (Tom Lane, Dean Rasheed) - - - - - - - - Ensure standby promotion trigger files are removed at postmaster - startup (Michael Paquier, Fujii Masao) - - - - This prevents unwanted promotion from occurring if these files appear - in a database backup that is used to initialize a new standby server. - - - - - - - - During postmaster shutdown, ensure that per-socket lock files are - removed and listen sockets are closed before we remove - the postmaster.pid file (Tom Lane) - - - - This avoids race-condition failures if an external script attempts to - start a new postmaster as soon as pg_ctl stop returns. - - - - - - - - Ensure that the postmaster does not exit until all its child processes - are gone, even in an immediate shutdown (Tom Lane) - - - - Like the previous item, this avoids possible race conditions against a - subsequently-started postmaster. - - - - - - - - Fix postmaster's handling of a startup-process crash during crash - recovery (Tom Lane) - - - - If, during a crash recovery cycle, the startup process crashes without - having restored database consistency, we'd try to launch a new startup - process, which typically would just crash again, leading to an infinite - loop. - - - - - - - - Make emergency autovacuuming for multixact wraparound more robust - (Andres Freund) - - - - - - - - Do not print a WARNING when an autovacuum worker is already - gone when we attempt to signal it, and reduce log verbosity for such - signals (Tom Lane) - - - - - - - - Prevent autovacuum launcher from sleeping unduly long if the server - clock is moved backwards a large amount (Álvaro Herrera) - - - - - - - - Ensure that cleanup of a GIN index's pending-insertions list is - interruptable by cancel requests (Jeff Janes) - - - - - - - - Allow all-zeroes pages in GIN indexes to be reused (Heikki Linnakangas) - - - - Such a page might be left behind after a crash. - - - - - - - - Fix handling of all-zeroes pages in SP-GiST indexes (Heikki - Linnakangas) - - - - VACUUM attempted to recycle such pages, but did so in a - way that wasn't crash-safe. - - - - - - - - Fix off-by-one error that led to otherwise-harmless warnings - about apparent wraparound in subtrans/multixact truncation - (Thomas Munro) - - - - - - - - Fix misreporting of CONTINUE and MOVE statement - types in PL/pgSQL's error context messages - (Pavel Stehule, Tom Lane) - - - - - - - - Fix PL/Perl to handle non-ASCII error - message texts correctly (Alex Hunsaker) - - - - - - - - Fix PL/Python crash when returning the string - representation of a record result (Tom Lane) - - - - - - - - Fix some places in PL/Tcl that neglected to check for - failure of malloc() calls (Michael Paquier, Álvaro - Herrera) - - - - - - - - In contrib/isn, fix output of ISBN-13 numbers that begin - with 979 (Fabien Coelho) - - - - EANs beginning with 979 (but not 9790) are considered ISBNs, but they - must be printed in the new 13-digit format, not the 10-digit format. - - - - - - - - Improve contrib/pg_stat_statements' handling of - query-text garbage collection (Peter Geoghegan) - - - - The external file containing query texts could bloat to very large - sizes; once it got past 1GB attempts to trim it would fail, soon - leading to situations where the file could not be read at all. - - - - - - - - Improve contrib/postgres_fdw's handling of - collation-related decisions (Tom Lane) - - - - The main user-visible effect is expected to be that comparisons - involving varchar columns will be sent to the remote server - for execution in more cases than before. - - - - - - - - Improve libpq's handling of out-of-memory conditions - (Michael Paquier, Heikki Linnakangas) - - - - - - - - Fix memory leaks and missing out-of-memory checks - in ecpg (Michael Paquier) - - - - - - - - Fix psql's code for locale-aware formatting of numeric - output (Tom Lane) - - - - The formatting code invoked by \pset numericlocale on - did the wrong thing for some uncommon cases such as numbers with an - exponent but no decimal point. It could also mangle already-localized - output from the money data type. - - - - - - - - Prevent crash in psql's \c command when - there is no current connection (Noah Misch) - - - - - - - - Make pg_dump handle inherited NOT VALID - check constraints correctly (Tom Lane) - - - - - - - - Fix selection of default zlib compression level - in pg_dump's directory output format (Andrew Dunstan) - - - - - - - - Ensure that temporary files created during a pg_dump - run with tar-format output are not world-readable (Michael - Paquier) - - - - - - - - Fix pg_dump and pg_upgrade to support - cases where the postgres or template1 database - is in a non-default tablespace (Marti Raudsepp, Bruce Momjian) - - - - - - - - Fix pg_dump to handle object privileges sanely when - dumping from a server too old to have a particular privilege type - (Tom Lane) - - - - When dumping data types from pre-9.2 servers, and when dumping - functions or procedural languages from pre-7.3 - servers, pg_dump would - produce GRANT/REVOKE commands that revoked the - owner's grantable privileges and instead granted all privileges - to PUBLIC. Since the privileges involved are - just USAGE and EXECUTE, this isn't a security - problem, but it's certainly a surprising representation of the older - systems' behavior. Fix it to leave the default privilege state alone - in these cases. - - - - - - - - Fix pg_dump to dump shell types (Tom Lane) - - - - Shell types (that is, not-yet-fully-defined types) aren't useful for - much, but nonetheless pg_dump should dump them. - - - - - - - - Fix assorted minor memory leaks in pg_dump and other - client-side programs (Michael Paquier) - - - - - - - - Fix pgbench's progress-report behavior when a query, - or pgbench itself, gets stuck (Fabien Coelho) - - - - - - - - Fix spinlock assembly code for Alpha hardware (Tom Lane) - - - - - - - - Fix spinlock assembly code for PPC hardware to be compatible - with AIX's native assembler (Tom Lane) - - - - Building with gcc didn't work if gcc - had been configured to use the native assembler, which is becoming more - common. - - - - - - - - On AIX, test the -qlonglong compiler option - rather than just assuming it's safe to use (Noah Misch) - - - - - - - - On AIX, use -Wl,-brtllib link option to allow - symbols to be resolved at runtime (Noah Misch) - - - - Perl relies on this ability in 5.8.0 and later. - - - - - - - - Avoid use of inline functions when compiling with - 32-bit xlc, due to compiler bugs (Noah Misch) - - - - - - - - Use librt for sched_yield() when necessary, - which it is on some Solaris versions (Oskari Saarenmaa) - - - - - - - - Translate encoding UHC as Windows code page 949 - (Noah Misch) - - - - This fixes presentation of non-ASCII log messages from processes that - are not attached to any particular database, such as the postmaster. - - - - - - - - On Windows, avoid failure when doing encoding conversion to UTF16 - outside a transaction, such as for log messages (Noah Misch) - - - - - - - - Fix postmaster startup failure due to not - copying setlocale()'s return value (Noah Misch) - - - - This has been reported on Windows systems with the ANSI code page set - to CP936 (Chinese (Simplified, PRC)), and may occur with - other multibyte code pages. - - - - - - - - Fix Windows install.bat script to handle target directory - names that contain spaces (Heikki Linnakangas) - - - - - - - - Make the numeric form of the PostgreSQL version number - (e.g., 90405) readily available to extension Makefiles, - as a variable named VERSION_NUM (Michael Paquier) - - - - - - - - Update time zone data files to tzdata release 2015g for - DST law changes in Cayman Islands, Fiji, Moldova, Morocco, Norfolk - Island, North Korea, Turkey, and Uruguay. There is a new zone name - America/Fort_Nelson for the Canadian Northern Rockies. - - - - - - - - - - Release 9.4.4 - - - Release date: - 2015-06-12 - - - - This release contains a small number of fixes from 9.4.3. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.4 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading an installation that was previously - upgraded using a pg_upgrade version between 9.3.0 and - 9.3.4 inclusive, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.4.2, - see . - - - - - Changes - - - - - - - - Fix possible failure to recover from an inconsistent database state - (Robert Haas) - - - - Recent PostgreSQL releases introduced mechanisms to - protect against multixact wraparound, but some of that code did not - account for the possibility that it would need to run during crash - recovery, when the database may not be in a consistent state. This - could result in failure to restart after a crash, or failure to start - up a secondary server. The lingering effects of a previously-fixed - bug in pg_upgrade could also cause such a failure, in - installations that had used pg_upgrade versions - between 9.3.0 and 9.3.4. - - - - The pg_upgrade bug in question was that it would - set oldestMultiXid to 1 in pg_control even - if the true value should be higher. With the fixes introduced in - this release, such a situation will result in immediate emergency - autovacuuming until a correct oldestMultiXid value can - be determined. If that would pose a hardship, users can avoid it by - doing manual vacuuming before upgrading to this release. - In detail: - - - - - Check whether pg_controldata reports Latest - checkpoint's oldestMultiXid to be 1. If not, there's nothing - to do. - - - - - Look in PGDATA/pg_multixact/offsets to see if there's a - file named 0000. If there is, there's nothing to do. - - - - - Otherwise, for each table that has - pg_class.relminmxid equal to 1, - VACUUM that table with - both - and set to - zero. (You can use the vacuum cost delay parameters described - in to reduce - the performance consequences for concurrent sessions.) - - - - - - - - - - - Fix rare failure to invalidate relation cache init file (Tom Lane) - - - - With just the wrong timing of concurrent activity, a VACUUM - FULL on a system catalog might fail to update the init file - that's used to avoid cache-loading work for new sessions. This would - result in later sessions being unable to access that catalog at all. - This is a very ancient bug, but it's so hard to trigger that no - reproducible case had been seen until recently. - - - - - - - - Avoid deadlock between incoming sessions and CREATE/DROP - DATABASE (Tom Lane) - - - - A new session starting in a database that is the target of - a DROP DATABASE command, or is the template for - a CREATE DATABASE command, could cause the command to wait - for five seconds and then fail, even if the new session would have - exited before that. - - - - - - - - Improve planner's cost estimates for semi-joins and anti-joins with - inner indexscans (Tom Lane, Tomas Vondra) - - - - This type of plan is quite cheap when all the join clauses are used - as index scan conditions, even if the inner scan would nominally - fetch many rows, because the executor will stop after obtaining one - row. The planner only partially accounted for that effect, and would - therefore overestimate the cost, leading it to possibly choose some - other much less efficient plan type. - - - - - - - - - - Release 9.4.3 - - - Release date: - 2015-06-04 - - - - This release contains a small number of fixes from 9.4.2. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.3 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are upgrading from a version earlier than 9.4.2, - see . - - - - - Changes - - - - - - - - Avoid failures while fsync'ing data directory during - crash restart (Abhijit Menon-Sen, Tom Lane) - - - - In the previous minor releases we added a patch to fsync - everything in the data directory after a crash. Unfortunately its - response to any error condition was to fail, thereby preventing the - server from starting up, even when the problem was quite harmless. - An example is that an unwritable file in the data directory would - prevent restart on some platforms; but it is common to make SSL - certificate files unwritable by the server. Revise this behavior so - that permissions failures are ignored altogether, and other types of - failures are logged but do not prevent continuing. - - - - Also apply the same rules in initdb --sync-only. - This case is less critical but it should act similarly. - - - - - - - - Fix pg_get_functiondef() to show - functions' LEAKPROOF property, if set (Jeevan Chalke) - - - - - - - - Fix pushJsonbValue() to unpack jbvBinary - objects (Andrew Dunstan) - - - - This change does not affect any behavior in the core code as of 9.4, - but it avoids a corner case for possible third-party callers. - - - - - - - - Remove configure's check prohibiting linking to a - threaded libpython - on OpenBSD (Tom Lane) - - - - The failure this restriction was meant to prevent seems to not be a - problem anymore on current OpenBSD - versions. - - - - - - - - - - Release 9.4.2 - - - Release date: - 2015-05-22 - - - - This release contains a variety of fixes from 9.4.1. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.2 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you use contrib/citext's - regexp_matches() functions, see the changelog entry below - about that. - - - - Also, if you are upgrading from a version earlier than 9.4.1, - see . - - - - - Changes - - - - - - - - Avoid possible crash when client disconnects just before the - authentication timeout expires (Benkocs Norbert Attila) - - - - If the timeout interrupt fired partway through the session shutdown - sequence, SSL-related state would be freed twice, typically causing a - crash and hence denial of service to other sessions. Experimentation - shows that an unauthenticated remote attacker could trigger the bug - somewhat consistently, hence treat as security issue. - (CVE-2015-3165) - - - - - - - - Improve detection of system-call failures (Noah Misch) - - - - Our replacement implementation of snprintf() failed to - check for errors reported by the underlying system library calls; - the main case that might be missed is out-of-memory situations. - In the worst case this might lead to information exposure, due to our - code assuming that a buffer had been overwritten when it hadn't been. - Also, there were a few places in which security-relevant calls of other - system library functions did not check for failure. - - - - It remains possible that some calls of the *printf() - family of functions are vulnerable to information disclosure if an - out-of-memory error occurs at just the wrong time. We judge the risk - to not be large, but will continue analysis in this area. - (CVE-2015-3166) - - - - - - - - In contrib/pgcrypto, uniformly report decryption failures - as Wrong key or corrupt data (Noah Misch) - - - - Previously, some cases of decryption with an incorrect key could report - other error message texts. It has been shown that such variance in - error reports can aid attackers in recovering keys from other systems. - While it's unknown whether pgcrypto's specific behaviors - are likewise exploitable, it seems better to avoid the risk by using a - one-size-fits-all message. - (CVE-2015-3167) - - - - - - - - Protect against wraparound of multixact member IDs - (Álvaro Herrera, Robert Haas, Thomas Munro) - - - - Under certain usage patterns, the existing defenses against this might - be insufficient, allowing pg_multixact/members files to be - removed too early, resulting in data loss. - The fix for this includes modifying the server to fail transactions - that would result in overwriting old multixact member ID data, and - improving autovacuum to ensure it will act proactively to prevent - multixact member ID wraparound, as it does for transaction ID - wraparound. - - - - - - - - Fix incorrect declaration of contrib/citext's - regexp_matches() functions (Tom Lane) - - - - These functions should return setof text[], like the core - functions they are wrappers for; but they were incorrectly declared as - returning just text[]. This mistake had two results: first, - if there was no match you got a scalar null result, whereas what you - should get is an empty set (zero rows). Second, the g flag - was effectively ignored, since you would get only one result array even - if there were multiple matches. - - - - While the latter behavior is clearly a bug, there might be applications - depending on the former behavior; therefore the function declarations - will not be changed by default until PostgreSQL 9.5. - In pre-9.5 branches, the old behavior exists in version 1.0 of - the citext extension, while we have provided corrected - declarations in version 1.1 (which is not installed by - default). To adopt the fix in pre-9.5 branches, execute - ALTER EXTENSION citext UPDATE TO '1.1' in each database in - which citext is installed. (You can also update - back to 1.0 if you need to undo that.) Be aware that either update - direction will require dropping and recreating any views or rules that - use citext's regexp_matches() functions. - - - - - - - - Render infinite dates and timestamps as infinity when - converting to json, rather than throwing an error - (Andrew Dunstan) - - - - - - - - Fix json/jsonb's populate_record() - and to_record() functions to handle empty input properly - (Andrew Dunstan) - - - - - - - - Fix incorrect checking of deferred exclusion constraints after a HOT - update (Tom Lane) - - - - If a new row that potentially violates a deferred exclusion constraint - is HOT-updated (that is, no indexed columns change and the row can be - stored back onto the same table page) later in the same transaction, - the exclusion constraint would be reported as violated when the check - finally occurred, even if the row(s) the new row originally conflicted - with had been deleted. - - - - - - - - Fix behavior when changing foreign key constraint deferrability status - with ALTER TABLE ... ALTER CONSTRAINT (Tom Lane) - - - - Operations later in the same session or concurrent sessions might not - honor the status change promptly. - - - - - - - - Fix planning of star-schema-style queries (Tom Lane) - - - - Sometimes, efficient scanning of a large table requires that index - parameters be provided from more than one other table (commonly, - dimension tables whose keys are needed to index a large fact table). - The planner should be able to find such plans, but an overly - restrictive search heuristic prevented it. - - - - - - - - Prevent improper reordering of antijoins (NOT EXISTS joins) versus - other outer joins (Tom Lane) - - - - This oversight in the planner has been observed to cause could - not find RelOptInfo for given relids errors, but it seems possible - that sometimes an incorrect query plan might get past that consistency - check and result in silently-wrong query output. - - - - - - - - Fix incorrect matching of subexpressions in outer-join plan nodes - (Tom Lane) - - - - Previously, if textually identical non-strict subexpressions were used - both above and below an outer join, the planner might try to re-use - the value computed below the join, which would be incorrect because the - executor would force the value to NULL in case of an unmatched outer row. - - - - - - - - Fix GEQO planner to cope with failure of its join order heuristic - (Tom Lane) - - - - This oversight has been seen to lead to failed to join all - relations together errors in queries involving LATERAL, - and that might happen in other cases as well. - - - - - - - - Ensure that row locking occurs properly when the target of - an UPDATE or DELETE is a security-barrier view - (Stephen Frost) - - - - - - - - Use a file opened for read/write when syncing replication slot data - during database startup (Andres Freund) - - - - On some platforms, the previous coding could result in errors like - could not fsync file "pg_replslot/...": Bad file descriptor. - - - - - - - - Fix possible deadlock at startup - when max_prepared_transactions is too small - (Heikki Linnakangas) - - - - - - - - Don't archive useless preallocated WAL files after a timeline switch - (Heikki Linnakangas) - - - - - - - - Recursively fsync() the data directory after a crash - (Abhijit Menon-Sen, Robert Haas) - - - - This ensures consistency if another crash occurs shortly later. (The - second crash would have to be a system-level crash, not just a database - crash, for there to be a problem.) - - - - - - - - Fix autovacuum launcher's possible failure to shut down, if an error - occurs after it receives SIGTERM (Álvaro Herrera) - - - - - - - - Fix failure to handle invalidation messages for system catalogs - early in session startup (Tom Lane) - - - - This oversight could result in failures in sessions that start - concurrently with a VACUUM FULL on a system catalog. - - - - - - - - Fix crash in BackendIdGetTransactionIds() when trying - to get status for a backend process that just exited (Tom Lane) - - - - - - - - Cope with unexpected signals in LockBufferForCleanup() - (Andres Freund) - - - - This oversight could result in spurious errors about multiple - backends attempting to wait for pincount 1. - - - - - - - - Fix crash when doing COPY IN to a table with check - constraints that contain whole-row references (Tom Lane) - - - - The known failure case only crashes in 9.4 and up, but there is very - similar code in 9.3 and 9.2, so back-patch those branches as well. - - - - - - - - Avoid waiting for WAL flush or synchronous replication during commit of - a transaction that was read-only so far as the user is concerned - (Andres Freund) - - - - Previously, a delay could occur at commit in transactions that had - written WAL due to HOT page pruning, leading to undesirable effects - such as sessions getting stuck at startup if all synchronous replicas - are down. Sessions have also been observed to get stuck in catchup - interrupt processing when using synchronous replication; this will fix - that problem as well. - - - - - - - - Avoid busy-waiting with short recovery_min_apply_delay - values (Andres Freund) - - - - - - - - Fix crash when manipulating hash indexes on temporary tables - (Heikki Linnakangas) - - - - - - - - Fix possible failure during hash index bucket split, if other processes - are modifying the index concurrently (Tom Lane) - - - - - - - - Fix memory leaks in GIN index vacuum (Heikki Linnakangas) - - - - - - - - Check for interrupts while analyzing index expressions (Jeff Janes) - - - - ANALYZE executes index expressions many times; if there are - slow functions in such an expression, it's desirable to be able to - cancel the ANALYZE before that loop finishes. - - - - - - - - Ensure tableoid of a foreign table is reported - correctly when a READ COMMITTED recheck occurs after - locking rows in SELECT FOR UPDATE, UPDATE, - or DELETE (Etsuro Fujita) - - - - - - - - Add the name of the target server to object description strings for - foreign-server user mappings (Álvaro Herrera) - - - - - - - - Include the schema name in object identity strings for conversions - (Álvaro Herrera) - - - - - - - - Recommend setting include_realm to 1 when using - Kerberos/GSSAPI/SSPI authentication (Stephen Frost) - - - - Without this, identically-named users from different realms cannot be - distinguished. For the moment this is only a documentation change, but - it will become the default setting in PostgreSQL 9.5. - - - - - - - - Remove code for matching IPv4 pg_hba.conf entries to - IPv4-in-IPv6 addresses (Tom Lane) - - - - This hack was added in 2003 in response to a report that some Linux - kernels of the time would report IPv4 connections as having - IPv4-in-IPv6 addresses. However, the logic was accidentally broken in - 9.0. The lack of any field complaints since then shows that it's not - needed anymore. Now we have reports that the broken code causes - crashes on some systems, so let's just remove it rather than fix it. - (Had we chosen to fix it, that would make for a subtle and potentially - security-sensitive change in the effective meaning of - IPv4 pg_hba.conf entries, which does not seem like a good - thing to do in minor releases.) - - - - - - - - Fix status reporting for terminated background workers that were never - actually started (Robert Haas) - - - - - - - - After a database crash, don't restart background workers that are - marked BGW_NEVER_RESTART (Amit Khandekar) - - - - - - - - Report WAL flush, not insert, position in IDENTIFY_SYSTEM - replication command (Heikki Linnakangas) - - - - This avoids a possible startup failure - in pg_receivexlog. - - - - - - - - While shutting down service on Windows, periodically send status - updates to the Service Control Manager to prevent it from killing the - service too soon; and ensure that pg_ctl will wait for - shutdown (Krystian Bigaj) - - - - - - - - Reduce risk of network deadlock when using libpq's - non-blocking mode (Heikki Linnakangas) - - - - When sending large volumes of data, it's important to drain the input - buffer every so often, in case the server has sent enough response data - to cause it to block on output. (A typical scenario is that the server - is sending a stream of NOTICE messages during COPY FROM - STDIN.) This worked properly in the normal blocking mode, but not - so much in non-blocking mode. We've modified libpq - to opportunistically drain input when it can, but a full defense - against this problem requires application cooperation: the application - should watch for socket read-ready as well as write-ready conditions, - and be sure to call PQconsumeInput() upon read-ready. - - - - - - - - In libpq, fix misparsing of empty values in URI - connection strings (Thomas Fanghaenel) - - - - - - - - Fix array handling in ecpg (Michael Meskes) - - - - - - - - Fix psql to sanely handle URIs and conninfo strings as - the first parameter to \connect - (David Fetter, Andrew Dunstan, Álvaro Herrera) - - - - This syntax has been accepted (but undocumented) for a long time, but - previously some parameters might be taken from the old connection - instead of the given string, which was agreed to be undesirable. - - - - - - - - Suppress incorrect complaints from psql on some - platforms that it failed to write ~/.psql_history at exit - (Tom Lane) - - - - This misbehavior was caused by a workaround for a bug in very old - (pre-2006) versions of libedit. We fixed it by - removing the workaround, which will cause a similar failure to appear - for anyone still using such versions of libedit. - Recommendation: upgrade that library, or use libreadline. - - - - - - - - Fix pg_dump's rule for deciding which casts are - system-provided casts that should not be dumped (Tom Lane) - - - - - - - - In pg_dump, fix failure to honor -Z - compression level option together with -Fd - (Michael Paquier) - - - - - - - - Make pg_dump consider foreign key relationships - between extension configuration tables while choosing dump order - (Gilles Darold, Michael Paquier, Stephen Frost) - - - - This oversight could result in producing dumps that fail to reload - because foreign key constraints are transiently violated. - - - - - - - - Avoid possible pg_dump failure when concurrent sessions - are creating and dropping temporary functions (Tom Lane) - - - - - - - - Fix dumping of views that are just VALUES(...) but have - column aliases (Tom Lane) - - - - - - - - Ensure that a view's replication identity is correctly set - to nothing during dump/restore (Marko Tiikkaja) - - - - Previously, if the view was involved in a circular dependency, - it might wind up with an incorrect replication identity property. - - - - - - - - In pg_upgrade, force timeline 1 in the new cluster - (Bruce Momjian) - - - - This change prevents upgrade failures caused by bogus complaints about - missing WAL history files. - - - - - - - - In pg_upgrade, check for improperly non-connectable - databases before proceeding - (Bruce Momjian) - - - - - - - - In pg_upgrade, quote directory paths - properly in the generated delete_old_cluster script - (Bruce Momjian) - - - - - - - - In pg_upgrade, preserve database-level freezing info - properly - (Bruce Momjian) - - - - This oversight could cause missing-clog-file errors for tables within - the postgres and template1 databases. - - - - - - - - Run pg_upgrade and pg_resetxlog with - restricted privileges on Windows, so that they don't fail when run by - an administrator (Muhammad Asif Naeem) - - - - - - - - Improve handling of readdir() failures when scanning - directories in initdb and pg_basebackup - (Marco Nenciarini) - - - - - - - - Fix slow sorting algorithm in contrib/intarray (Tom Lane) - - - - - - - - Fix compile failure on Sparc V8 machines (Rob Rowan) - - - - - - - - Silence some build warnings on macOS (Tom Lane) - - - - - - - - Update time zone data files to tzdata release 2015d - for DST law changes in Egypt, Mongolia, and Palestine, plus historical - changes in Canada and Chile. Also adopt revised zone abbreviations for - the America/Adak zone (HST/HDT not HAST/HADT). - - - - - - - - - - Release 9.4.1 - - - Release date: - 2015-02-05 - - - - This release contains a variety of fixes from 9.4.0. - For information about new features in the 9.4 major release, see - . - - - - Migration to Version 9.4.1 - - - A dump/restore is not required for those running 9.4.X. - - - - However, if you are a Windows user and are using the Norwegian - (Bokmål) locale, manual action is needed after the upgrade to - replace any Norwegian (Bokmål)_Norway - or norwegian-bokmal locale names stored - in PostgreSQL system catalogs with the plain-ASCII - alias Norwegian_Norway. For details see - - - - - - Changes - - - - - - - - Fix buffer overruns in to_char() - (Bruce Momjian) - - - - When to_char() processes a numeric formatting template - calling for a large number of digits, PostgreSQL - would read past the end of a buffer. When processing a crafted - timestamp formatting template, PostgreSQL would write - past the end of a buffer. Either case could crash the server. - We have not ruled out the possibility of attacks that lead to - privilege escalation, though they seem unlikely. - (CVE-2015-0241) - - - - - - - - Fix buffer overrun in replacement *printf() functions - (Tom Lane) - - - - PostgreSQL includes a replacement implementation - of printf and related functions. This code will overrun - a stack buffer when formatting a floating point number (conversion - specifiers e, E, f, F, - g or G) with requested precision greater than - about 500. This will crash the server, and we have not ruled out the - possibility of attacks that lead to privilege escalation. - A database user can trigger such a buffer overrun through - the to_char() SQL function. While that is the only - affected core PostgreSQL functionality, extension - modules that use printf-family functions may be at risk as well. - - - - This issue primarily affects PostgreSQL on Windows. - PostgreSQL uses the system implementation of these - functions where adequate, which it is on other modern platforms. - (CVE-2015-0242) - - - - - - - - Fix buffer overruns in contrib/pgcrypto - (Marko Tiikkaja, Noah Misch) - - - - Errors in memory size tracking within the pgcrypto - module permitted stack buffer overruns and improper dependence on the - contents of uninitialized memory. The buffer overrun cases can - crash the server, and we have not ruled out the possibility of - attacks that lead to privilege escalation. - (CVE-2015-0243) - - - - - - - - Fix possible loss of frontend/backend protocol synchronization after - an error - (Heikki Linnakangas) - - - - If any error occurred while the server was in the middle of reading a - protocol message from the client, it could lose synchronization and - incorrectly try to interpret part of the message's data as a new - protocol message. An attacker able to submit crafted binary data - within a command parameter might succeed in injecting his own SQL - commands this way. Statement timeout and query cancellation are the - most likely sources of errors triggering this scenario. Particularly - vulnerable are applications that use a timeout and also submit - arbitrary user-crafted data as binary query parameters. Disabling - statement timeout will reduce, but not eliminate, the risk of - exploit. Our thanks to Emil Lenngren for reporting this issue. - (CVE-2015-0244) - - - - - - - - Fix information leak via constraint-violation error messages - (Stephen Frost) - - - - Some server error messages show the values of columns that violate - a constraint, such as a unique constraint. If the user does not have - SELECT privilege on all columns of the table, this could - mean exposing values that the user should not be able to see. Adjust - the code so that values are displayed only when they came from the SQL - command or could be selected by the user. - (CVE-2014-8161) - - - - - - - - Lock down regression testing's temporary installations on Windows - (Noah Misch) - - - - Use SSPI authentication to allow connections only from the OS user - who launched the test suite. This closes on Windows the same - vulnerability previously closed on other platforms, namely that other - users might be able to connect to the test postmaster. - (CVE-2014-0067) - - - - - - - - Cope with the Windows locale named Norwegian (Bokmål) - (Heikki Linnakangas) - - - - Non-ASCII locale names are problematic since it's not clear what - encoding they should be represented in. Map the troublesome locale - name to a plain-ASCII alias, Norwegian_Norway. - - - - 9.4.0 mapped the troublesome name to norwegian-bokmal, - but that turns out not to work on all Windows configurations. - Norwegian_Norway is now recommended instead. - - - - - - - - Fix use-of-already-freed-memory problem in EvalPlanQual processing - (Tom Lane) - - - - In READ COMMITTED mode, queries that lock or update - recently-updated rows could crash as a result of this bug. - - - - - - - - Avoid possible deadlock while trying to acquire tuple locks - in EvalPlanQual processing (Álvaro Herrera, Mark Kirkwood) - - - - - - - - Fix failure to wait when a transaction tries to acquire a FOR - NO KEY EXCLUSIVE tuple lock, while multiple other transactions - currently hold FOR SHARE locks (Álvaro Herrera) - - - - - - - - Improve performance of EXPLAIN with large range tables - (Tom Lane) - - - - - - - - Fix jsonb Unicode escape processing, and in consequence - disallow \u0000 (Tom Lane) - - - - Previously, the JSON Unicode escape \u0000 was accepted - and was stored as those six characters; but that is indistinguishable - from what is stored for the input \\u0000, resulting in - ambiguity. Moreover, in cases where de-escaped textual output is - expected, such as the ->> operator, the sequence was - printed as \u0000, which does not meet the expectation - that JSON escaping would be removed. (Consistent behavior would - require emitting a zero byte, but PostgreSQL does not - support zero bytes embedded in text strings.) 9.4.0 included an - ill-advised attempt to improve this situation by adjusting JSON output - conversion rules; but of course that could not fix the fundamental - ambiguity, and it turned out to break other usages of Unicode escape - sequences. Revert that, and to avoid the core problem, - reject \u0000 in jsonb input. - - - - If a jsonb column contains a \u0000 value stored - with 9.4.0, it will henceforth read out as though it - were \\u0000, which is the other valid interpretation of - the data stored by 9.4.0 for this case. - - - - The json type did not have the storage-ambiguity problem, but - it did have the problem of inconsistent de-escaped textual output. - Therefore \u0000 will now also be rejected - in json values when conversion to de-escaped form is - required. This change does not break the ability to - store \u0000 in json columns so long as no - processing is done on the values. This is exactly parallel to the - cases in which non-ASCII Unicode escapes are allowed when the database - encoding is not UTF8. - - - - - - - - Fix namespace handling in xpath() (Ali Akbar) - - - - Previously, the xml value resulting from - an xpath() call would not have namespace declarations if - the namespace declarations were attached to an ancestor element in the - input xml value, rather than to the specific element being - returned. Propagate the ancestral declaration so that the result is - correct when considered in isolation. - - - - - - - - Fix assorted oversights in range-operator selectivity estimation - (Emre Hasegeli) - - - - This patch fixes corner-case unexpected operator NNNN planner - errors, and improves the selectivity estimates for some other cases. - - - - - - - - Revert unintended reduction in maximum size of a GIN index item - (Heikki Linnakangas) - - - - 9.4.0 could fail with index row size exceeds maximum errors - for data that previous versions would accept. - - - - - - - - Fix query-duration memory leak during repeated GIN index rescans - (Heikki Linnakangas) - - - - - - - - Fix possible crash when using - nonzero gin_fuzzy_search_limit (Heikki Linnakangas) - - - - - - - - Assorted fixes for logical decoding (Andres Freund) - - - - - - - - Fix incorrect replay of WAL parameter change records that report - changes in the wal_log_hints setting (Petr Jelinek) - - - - - - - - Change pgstat wait timeout warning message to be LOG level, - and rephrase it to be more understandable (Tom Lane) - - - - This message was originally thought to be essentially a can't-happen - case, but it occurs often enough on our slower buildfarm members to be - a nuisance. Reduce it to LOG level, and expend a bit more effort on - the wording: it now reads using stale statistics instead of - current ones because stats collector is not responding. - - - - - - - - Warn if macOS's setlocale() starts an unwanted extra - thread inside the postmaster (Noah Misch) - - - - - - - - Fix libpq's behavior when /etc/passwd - isn't readable (Tom Lane) - - - - While doing PQsetdbLogin(), libpq - attempts to ascertain the user's operating system name, which on most - Unix platforms involves reading /etc/passwd. As of 9.4, - failure to do that was treated as a hard error. Restore the previous - behavior, which was to fail only if the application does not provide a - database role name to connect as. This supports operation in chroot - environments that lack an /etc/passwd file. - - - - - - - - Improve consistency of parsing of psql's special - variables (Tom Lane) - - - - Allow variant spellings of on and off (such - as 1/0) for ECHO_HIDDEN - and ON_ERROR_ROLLBACK. Report a warning for unrecognized - values for COMP_KEYWORD_CASE, ECHO, - ECHO_HIDDEN, HISTCONTROL, - ON_ERROR_ROLLBACK, and VERBOSITY. Recognize - all values for all these variables case-insensitively; previously - there was a mishmash of case-sensitive and case-insensitive behaviors. - - - - - - - - Fix pg_dump to handle comments on event triggers - without failing (Tom Lane) - - - - - - - - Allow parallel pg_dump to - use (Kevin Grittner) - - - - - - - - Prevent WAL files created by pg_basebackup -x/-X from - being archived again when the standby is promoted (Andres Freund) - - - - - - - - Handle unexpected query results, especially NULLs, safely in - contrib/tablefunc's connectby() - (Michael Paquier) - - - - connectby() previously crashed if it encountered a NULL - key value. It now prints that row but doesn't recurse further. - - - - - - - - Numerous cleanups of warnings from Coverity static code analyzer - (Andres Freund, Tatsuo Ishii, Marko Kreen, Tom Lane, Michael Paquier) - - - - These changes are mostly cosmetic but in some cases fix corner-case - bugs, for example a crash rather than a proper error report after an - out-of-memory failure. None are believed to represent security - issues. - - - - - - - - Allow CFLAGS from configure's environment - to override automatically-supplied CFLAGS (Tom Lane) - - - - Previously, configure would add any switches that it - chose of its own accord to the end of the - user-specified CFLAGS string. Since most compilers - process switches left-to-right, this meant that configure's choices - would override the user-specified flags in case of conflicts. That - should work the other way around, so adjust the logic to put the - user's string at the end not the beginning. - - - - - - - - Make pg_regress remove any temporary installation it - created upon successful exit (Tom Lane) - - - - This results in a very substantial reduction in disk space usage - during make check-world, since that sequence involves - creation of numerous temporary installations. - - - - - - - - Add CST (China Standard Time) to our lists of timezone abbreviations - (Tom Lane) - - - - - - - - Update time zone data files to tzdata release 2015a - for DST law changes in Chile and Mexico, plus historical changes in - Iceland. - - - - - - - - - - Release 9.4 - - - Release date: - 2014-12-18 - - - - Overview - - - Major enhancements in PostgreSQL 9.4 include: - - - - - - - - - Add jsonb, a more - capable and efficient data type for storing JSON data - - - - - - Add new SQL command - for changing postgresql.conf configuration file entries - - - - - - Reduce lock strength for some - commands - - - - - - Allow materialized views - to be refreshed without blocking concurrent reads - - - - - - Add support for logical decoding - of WAL data, to allow database changes to be streamed out in a - customizable format - - - - - - Allow background worker processes - to be dynamically registered, started and terminated - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.4 - - - A dump/restore using , or use - of , is required for those wishing to migrate - data from any previous release. - - - - Version 9.4 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - - - - Tighten checks for multidimensional array input (Bruce Momjian) - - - - Previously, an input array string that started with a single-element - sub-array could later contain multi-element sub-arrays, - e.g. '{{1}, {2,3}}'::int[] would be accepted. - - - - - - When converting values of type date, timestamp - or timestamptz - to JSON, render the - values in a format compliant with ISO 8601 (Andrew Dunstan) - - - - Previously such values were rendered according to the current - setting; but many JSON processors - require timestamps to be in ISO 8601 format. If necessary, the - previous behavior can be obtained by explicitly casting the datetime - value to text before passing it to the JSON conversion - function. - - - - - - The json - #> text[] path extraction operator now - returns its lefthand input, not NULL, if the array is empty (Tom Lane) - - - - This is consistent with the notion that this represents zero - applications of the simple field/element extraction - operator ->. Similarly, json - #>> text[] with an empty array merely - coerces its lefthand input to text. - - - - - - Corner cases in - the JSON - field/element/path extraction operators now return NULL rather - than raising an error (Tom Lane) - - - - For example, applying field extraction to a JSON array now yields NULL - not an error. This is more consistent (since some comparable cases such - as no-such-field already returned NULL), and it makes it safe to create - expression indexes that use these operators, since they will now not - throw errors for any valid JSON input. - - - - - - Cause consecutive whitespace in to_timestamp() - and to_date() format strings to consume a corresponding - number of characters in the input string (whitespace or not), then - conditionally consume adjacent whitespace, if not in FX - mode (Jeevan Chalke) - - - - Previously, consecutive whitespace characters in a non-FX - format string behaved like a single whitespace character and consumed - all adjacent whitespace in the input string. For example, previously - a format string of three spaces would consume only the first space in - ' 12', but it will now consume all three characters. - - - - - - Fix ts_rank_cd() - to ignore stripped lexemes (Alex Hill) - - - - Previously, stripped lexemes were treated as if they had a default - location, producing a rank of dubious usefulness. - - - - - - For functions declared to - take VARIADIC - "any", an actual parameter marked as VARIADIC - must be of a determinable array type (Pavel Stehule) - - - - Such parameters can no longer be written as an undecorated string - literal or NULL; a cast to an appropriate array data type - will now be required. Note that this does not affect parameters not - marked VARIADIC. - - - - - - Ensure that whole-row variables expose the expected column names - to functions that pay attention to column names within composite - arguments (Tom Lane) - - - - Constructs like row_to_json(tab.*) now always emit column - names that match the column aliases visible for table tab - at the point of the call. In previous releases the emitted column - names would sometimes be the table's actual column names regardless - of any aliases assigned in the query. - - - - - - now also discards sequence-related state - (Fabrízio de Royes Mello, Robert Haas) - - - - - - Rename EXPLAIN - ANALYZE's total runtime output - to execution time (Tom Lane) - - - - Now that planning time is also reported, the previous name was - confusing. - - - - - - SHOW TIME ZONE now - outputs simple numeric UTC offsets in POSIX timezone - format (Tom Lane) - - - - Previously, such timezone settings were displayed as interval values. - The new output is properly interpreted by SET TIME ZONE - when passed as a simple string, whereas the old output required - special treatment to be re-parsed correctly. - - - - - - Foreign data wrappers that support updating foreign tables must - consider the possible presence of AFTER ROW triggers - (Noah Misch) - - - - When an AFTER ROW trigger is present, all columns of the - table must be returned by updating actions, since the trigger might - inspect any or all of them. Previously, foreign tables never had - triggers, so the FDW might optimize away fetching columns not mentioned - in the RETURNING clause (if any). - - - - - - Prevent CHECK - constraints from referencing system columns, except - tableoid (Amit Kapila) - - - - Previously such check constraints were allowed, but they would often - cause errors during restores. - - - - - - Use the last specified recovery - target parameter if multiple target parameters are specified - (Heikki Linnakangas) - - - - Previously, there was an undocumented precedence order among - the recovery_target_xxx parameters. - - - - - - On Windows, automatically preserve quotes in command strings supplied - by the user (Heikki Linnakangas) - - - - User commands that did their own quote preservation might need - adjustment. This is likely to be an issue for commands used in - , , - and COPY TO/FROM PROGRAM. - - - - - - Remove catalog column pg_class.reltoastidxid - (Michael Paquier) - - - - - - Remove catalog column pg_rewrite.ev_attr - (Kevin Grittner) - - - - Per-column rules have not been supported since - PostgreSQL 7.3. - - - - - - Remove native support for Kerberos authentication - (, etc) - (Magnus Hagander) - - - - The supported way to use Kerberos authentication is - with GSSAPI. The native code has been deprecated since - PostgreSQL 8.3. - - - - - - In PL/Python, handle domains over arrays like the - underlying array type (Rodolfo Campero) - - - - Previously such values were treated as strings. - - - - - - Make libpq's PQconnectdbParams() - and PQpingParams() - functions process zero-length strings as defaults (Adrian - Vondendriesch) - - - - Previously, these functions treated zero-length string values as - selecting the default in only some cases. - - - - - - Change empty arrays returned by the module - to be zero-dimensional arrays (Bruce Momjian) - - - - Previously, empty arrays were returned as zero-length one-dimensional - arrays, whose text representation looked the same as zero-dimensional - arrays ({}), but they acted differently in array - operations. intarray's behavior in this area now - matches the built-in array operators. - - - - - - now uses - or to specify the user name (Bruce Momjian) - - - - Previously this option was spelled or , - but that was inconsistent with other tools. - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.4 and the previous major - release. - - - - Server - - - - - - Allow background worker processes - to be dynamically registered, started and terminated (Robert Haas) - - - - The new worker_spi module shows an example of use - of this feature. - - - - - - Allow dynamic allocation of shared memory segments (Robert Haas, - Amit Kapila) - - - - This feature is illustrated in the test_shm_mq - module. - - - - - - During crash recovery or immediate shutdown, send uncatchable - termination signals (SIGKILL) to child processes - that do not shut down promptly (MauMau, Álvaro Herrera) - - - - This reduces the likelihood of leaving orphaned child processes - behind after shutdown, as well - as ensuring that crash recovery can proceed if some child processes - have become stuck. - - - - - - Improve randomness of the database system identifier (Tom Lane) - - - - - - Make properly report dead but - not-yet-removable rows to the statistics collector (Hari Babu) - - - - Previously these were reported as live rows. - - - - - - - Indexes - - - - - - Reduce GIN index size - (Alexander Korotkov, Heikki Linnakangas) - - - - Indexes upgraded via will work fine - but will still be in the old, larger GIN format. - Use to recreate old GIN indexes in the - new format. - - - - - - Improve speed of multi-key GIN lookups (Alexander Korotkov, - Heikki Linnakangas) - - - - - - Add GiST index support - for inet and - cidr data types - (Emre Hasegeli) - - - - Such indexes improve subnet and supernet - lookups and ordering comparisons. - - - - - - Fix rare race condition in B-tree page deletion (Heikki Linnakangas) - - - - - - Make the handling of interrupted B-tree page splits more robust - (Heikki Linnakangas) - - - - - - - - - General Performance - - - - - - Allow multiple backends to insert - into WAL buffers - concurrently (Heikki Linnakangas) - - - - This improves parallel write performance. - - - - - - Conditionally write only the modified portion of updated rows to - WAL (Amit Kapila) - - - - - - Improve performance of aggregate functions used as window functions - (David Rowley, Florian Pflug, Tom Lane) - - - - - - Improve speed of aggregates that - use numeric state - values (Hadi Moshayedi) - - - - - - Attempt to freeze - tuples when tables are rewritten with or VACUUM FULL (Robert Haas, - Andres Freund) - - - - This can avoid the need to freeze the tuples in the future. - - - - - - Improve speed of with default nextval() - columns (Simon Riggs) - - - - - - Improve speed of accessing many different sequences in the same session - (David Rowley) - - - - - - Raise hard limit on the number of tuples held in memory during sorting - and B-tree index builds (Noah Misch) - - - - - - Reduce memory allocated by PL/pgSQL - blocks (Tom Lane) - - - - - - Make the planner more aggressive about extracting restriction clauses - from mixed AND/OR clauses (Tom Lane) - - - - - - Disallow pushing volatile WHERE clauses down - into DISTINCT subqueries (Tom Lane) - - - - Pushing down a WHERE clause can produce a more - efficient plan overall, but at the cost of evaluating the clause - more often than is implied by the text of the query; so don't do it - if the clause contains any volatile functions. - - - - - - Auto-resize the catalog caches (Heikki Linnakangas) - - - - This reduces memory consumption for sessions accessing only a few - tables, and improves performance for sessions accessing many tables. - - - - - - - - - Monitoring - - - - - - Add system view to - report WAL archiver activity - (Gabriele Bartolini) - - - - - - Add n_mod_since_analyze columns to - and related system views - (Mark Kirkwood) - - - - These columns expose the system's estimate of the number of changed - tuples since the table's last . This - estimate drives decisions about when to auto-analyze. - - - - - - Add backend_xid and backend_xmin - columns to the system view , - and a backend_xmin column to - (Christian Kruse) - - - - - - - - - <acronym>SSL</acronym> - - - - - - Add support for SSL ECDH key exchange - (Marko Kreen) - - - - This allows use of Elliptic Curve keys for server authentication. - Such keys are faster and have better security than RSA - keys. The new configuration parameter - - controls which curve is used for ECDH. - - - - - - Improve the default setting - (Marko Kreen) - - - - - - By default, the server not the client now controls the preference - order of SSL ciphers - (Marko Kreen) - - - - Previously, the order specified by - was usually ignored in favor of client-side defaults, which are not - configurable in most PostgreSQL clients. If - desired, the old behavior can be restored via the new configuration - parameter . - - - - - - Make show SSL - encryption information (Andreas Kunert) - - - - - - Improve SSL renegotiation handling (Álvaro - Herrera) - - - - - - - - - Server Settings - - - - - - Add new SQL command - for changing postgresql.conf configuration file entries - (Amit Kapila) - - - - Previously such settings could only be changed by manually - editing postgresql.conf. - - - - - - Add configuration parameter - to control the amount of memory used by autovacuum workers - (Peter Geoghegan) - - - - - - Add parameter to allow using huge - memory pages on Linux (Christian Kruse, Richard Poole, Abhijit - Menon-Sen) - - - - This can improve performance on large-memory systems. - - - - - - Add parameter - to limit the number of background workers (Robert Haas) - - - - This is helpful in configuring a standby server to have the - required number of worker processes (the same as the primary). - - - - - - Add superuser-only - parameter to load libraries at session start (Peter Eisentraut) - - - - In contrast to , this - parameter can load any shared library, not just those in - the $libdir/plugins directory. - - - - - - Add parameter to enable WAL - logging of hint-bit changes (Sawada Masahiko) - - - - Hint bit changes are not normally logged, except when checksums are - enabled. This is useful for external tools - like pg_rewind. - - - - - - Increase the default settings of - and by four times (Bruce - Momjian) - - - - The new defaults are 4MB and 64MB respectively. - - - - - - Increase the default setting of - to 4GB (Bruce Momjian, Tom Lane) - - - - - - Allow printf-style space padding to be - specified in (David Rowley) - - - - - - Allow terabyte units (TB) to be used when specifying - configuration variable values (Simon Riggs) - - - - - - Show PIDs of lock holders and waiters and improve - information about relations in - log messages (Christian Kruse) - - - - - - Reduce server logging level when loading shared libraries (Peter - Geoghegan) - - - - The previous level was LOG, which was too verbose - for libraries loaded per-session. - - - - - - On Windows, make SQL_ASCII-encoded databases and server - processes (e.g., ) emit messages in - the character encoding of the server's Windows user locale - (Alexander Law, Noah Misch) - - - - Previously these messages were output in the Windows - ANSI code page. - - - - - - - - - - - Replication and Recovery - - - - - - Add replication - slots to coordinate activity on streaming standbys with the - node they are streaming from (Andres Freund, Robert Haas) - - - - Replication slots allow preservation of resources like - WAL files on the primary until they are no longer - needed by standby servers. - - - - - - Add recovery parameter - to delay replication (Robert Haas, Fabrízio de Royes Mello, - Simon Riggs) - - - - Delaying replay on standby servers can be useful for recovering - from user errors. - - - - - - Add - option to stop WAL recovery as soon as a - consistent state is reached (MauMau, Heikki Linnakangas) - - - - - - Improve recovery target processing (Heikki Linnakangas) - - - - The timestamp reported - by pg_last_xact_replay_timestamp() - now reflects already-committed records, not transactions about to - be committed. Recovering to a restore point now replays the restore - point, rather than stopping just before the restore point. - - - - - - pg_switch_xlog() - now clears any unused trailing space in the old WAL file - (Heikki Linnakangas) - - - - This improves the compression ratio for WAL files. - - - - - - Report failure return codes from external recovery commands - (Peter Eisentraut) - - - - - - Reduce spinlock contention during WAL replay (Heikki - Linnakangas) - - - - - - Write WAL records of running transactions more - frequently (Andres Freund) - - - - This allows standby servers to start faster and clean up resources - more aggressively. - - - - - - - <link linkend="logicaldecoding">Logical Decoding</link> - - - Logical decoding allows database changes to be streamed in a - configurable format. The data is read from - the WAL and transformed into the - desired target format. To implement this feature, the following changes - were made: - - - - - - - Add support for logical decoding - of WAL data, to allow database changes to be streamed out in a - customizable format - (Andres Freund) - - - - - - Add new setting - to enable logical change-set encoding in WAL (Andres - Freund) - - - - - - Add table-level parameter REPLICA IDENTITY - to control logical replication (Andres Freund) - - - - - - Add relation option - to identify user-created tables involved in logical change-set - encoding (Andres Freund) - - - - - - Add application to receive - logical-decoding data (Andres Freund) - - - - - - Add module to illustrate logical - decoding at the SQL level (Andres Freund) - - - - - - - - - - - Queries - - - - - - Add WITH - ORDINALITY syntax to number the rows returned from a - set-returning function in the FROM clause - (Andrew Gierth, David Fetter) - - - - This is particularly useful for functions like - unnest(). - - - - - - Add ROWS - FROM() syntax to allow horizontal concatenation of - set-returning functions in the FROM clause (Andrew Gierth) - - - - - - Allow to have - an empty target list (Tom Lane) - - - - This was added so that views that select from a table with zero - columns can be dumped and restored correctly. - - - - - - Ensure that SELECT ... FOR UPDATE - NOWAIT does not wait in corner cases involving - already-concurrently-updated tuples (Craig Ringer and Thomas Munro) - - - - - - - - - Utility Commands - - - - - - Add DISCARD - SEQUENCES command to discard cached sequence-related state - (Fabrízio de Royes Mello, Robert Haas) - - - - DISCARD ALL will now also discard such information. - - - - - - Add FORCE NULL option - to COPY FROM, which - causes quoted strings matching the specified null string to be - converted to NULLs in CSV mode (Ian Barwick, Michael - Paquier) - - - - Without this option, only unquoted matching strings will be imported - as null values. - - - - - - Issue warnings for commands used outside of transaction blocks - when they can have no effect (Bruce Momjian) - - - - New warnings are issued for SET - LOCAL, SET CONSTRAINTS, SET TRANSACTION and - ABORT when used outside a transaction block. - - - - - - - <xref linkend="sql-explain"/> - - - - - - Make EXPLAIN ANALYZE show planning time (Andreas - Karlsson) - - - - - - Make EXPLAIN show the grouping columns in Agg and - Group nodes (Tom Lane) - - - - - - Make EXPLAIN ANALYZE show exact and lossy - block counts in bitmap heap scans (Etsuro Fujita) - - - - - - - - - Views - - - - - - Allow a materialized view - to be refreshed without blocking other sessions from reading the view - meanwhile (Kevin Grittner) - - - - This is done with REFRESH MATERIALIZED - VIEW CONCURRENTLY. - - - - - - Allow views to be automatically - updated even if they contain some non-updatable columns - (Dean Rasheed) - - - - Previously the presence of non-updatable output columns such as - expressions, literals, and function calls prevented automatic - updates. Now INSERTs, UPDATEs and - DELETEs are supported, provided that they do not - attempt to assign new values to any of the non-updatable columns. - - - - - - Allow control over whether INSERTs and - UPDATEs can add rows to an auto-updatable view that - would not appear in the view (Dean Rasheed) - - - - This is controlled with the new - clause WITH CHECK OPTION. - - - - - - Allow security barrier views - to be automatically updatable (Dean Rasheed) - - - - - - - - - - - Object Manipulation - - - - - - Support triggers on foreign - tables (Ronan Dunklau) - - - - - - Allow moving groups of objects from one tablespace to another - using the ALL IN TABLESPACE ... SET TABLESPACE form of - , , or - (Stephen Frost) - - - - - - Allow changing foreign key constraint deferrability - via ... ALTER - CONSTRAINT (Simon Riggs) - - - - - - Reduce lock strength for some - commands - (Simon Riggs, Noah Misch, Robert Haas) - - - - Specifically, VALIDATE CONSTRAINT, CLUSTER - ON, SET WITHOUT CLUSTER, ALTER COLUMN - SET STATISTICS, ALTER COLUMN SET - , ALTER COLUMN RESET - no longer require ACCESS - EXCLUSIVE locks. - - - - - - Allow tablespace options to be set - in (Vik Fearing) - - - - Formerly these options could only be set - via . - - - - - - Allow to define the estimated - size of the aggregate's transition state data (Hadi Moshayedi) - - - - Proper use of this feature allows the planner to better estimate - how much memory will be used by aggregates. - - - - - - Fix DROP IF EXISTS to avoid errors for non-existent - objects in more cases (Pavel Stehule, Dean Rasheed) - - - - - - Improve how system relations are identified (Andres Freund, - Robert Haas) - - - - Previously, relations once moved into the pg_catalog - schema could no longer be modified or dropped. - - - - - - - - - Data Types - - - - - - Fully implement the line data type (Peter - Eisentraut) - - - - The line segment data type (lseg) has always been - fully supported. The previous line data type (which was - enabled only via a compile-time option) is not binary or - dump-compatible with the new implementation. - - - - - - Add pg_lsn - data type to represent a WAL log sequence number - (LSN) (Robert Haas, Michael Paquier) - - - - - - Allow single-point polygons to be converted - to circles - (Bruce Momjian) - - - - - - Support time zone abbreviations that change UTC offset from time to - time (Tom Lane) - - - - Previously, PostgreSQL assumed that the UTC offset - associated with a time zone abbreviation (such as EST) - never changes in the usage of any particular locale. However this - assumption fails in the real world, so introduce the ability for a - zone abbreviation to represent a UTC offset that sometimes changes. - Update the zone abbreviation definition files to make use of this - feature in timezone locales that have changed the UTC offset of their - abbreviations since 1970 (according to the IANA timezone database). - In such timezones, PostgreSQL will now associate the - correct UTC offset with the abbreviation depending on the given date. - - - - - - Allow 5+ digit years for non-ISO timestamp and - date strings, where appropriate (Bruce Momjian) - - - - - - Add checks for overflow/underflow of interval values - (Bruce Momjian) - - - - - - - <link linkend="datatype-json"><acronym>JSON</acronym></link> - - - - - - Add jsonb, a more - capable and efficient data type for storing JSON data - (Oleg Bartunov, Teodor Sigaev, Alexander - Korotkov, Peter Geoghegan, Andrew Dunstan) - - - - This new type allows faster access to values within a JSON - document, and faster and more useful indexing of JSON columns. - Scalar values in jsonb documents are stored as appropriate - scalar SQL types, and the JSON document structure is pre-parsed - rather than being stored as text as in the original json - data type. - - - - - - Add new JSON functions to allow for the construction - of arbitrarily complex JSON trees (Andrew Dunstan, Laurence Rowe) - - - - New functions include json_array_elements_text(), - json_build_array(), json_object(), - json_object_agg(), json_to_record(), - and json_to_recordset(). - - - - - - Add json_typeof() - to return the data type of a json value (Andrew Tipton) - - - - - - - - - - - Functions - - - - - - Add pg_sleep_for(interval) - and pg_sleep_until(timestamp) to specify - delays more flexibly (Vik Fearing, Julien Rouhaud) - - - - The existing pg_sleep() function only supports delays - specified in seconds. - - - - - - Add cardinality() - function for arrays (Marko Tiikkaja) - - - - This returns the total number of elements in the array, or zero - for an array with no elements. - - - - - - Add SQL functions to allow large - object reads/writes at arbitrary offsets (Pavel Stehule) - - - - - - Allow unnest() - to take multiple arguments, which are individually unnested then - horizontally concatenated (Andrew Gierth) - - - - - - Add functions to construct times, dates, - timestamps, timestamptzs, and intervals - from individual values, rather than strings (Pavel Stehule) - - - - These functions' names are prefixed with make_, - e.g. make_date(). - - - - - - Make to_char()'s - TZ format specifier return a useful value for simple - numeric time zone offsets (Tom Lane) - - - - Previously, to_char(CURRENT_TIMESTAMP, 'TZ') returned - an empty string if the timezone was set to a constant - like -4. - - - - - - Add timezone offset format specifier OF to to_char() - (Bruce Momjian) - - - - - - Improve the random seed used for random() - (Honza Horak) - - - - - - Tighten validity checking for Unicode code points in chr(int) - (Tom Lane) - - - - This function now only accepts values that are valid UTF8 characters - according to RFC 3629. - - - - - - - System Information Functions - - - - - - Add functions for looking up objects in pg_class, - pg_proc, pg_type, and - pg_operator that do not generate errors for - non-existent objects (Yugo Nagata, Nozomi Anzai, - Robert Haas) - - - - For example, to_regclass() - does a lookup in pg_class similarly to - the regclass input function, but it returns NULL for a - non-existent object instead of failing. - - - - - - Add function pg_filenode_relation() - to allow for more efficient lookup of relation names from filenodes - (Andres Freund) - - - - - - Add parameter_default column to information_schema.parameters - view (Peter Eisentraut) - - - - - - Make information_schema.schemata - show all accessible schemas (Peter Eisentraut) - - - - Previously it only showed schemas owned by the current user. - - - - - - - - - Aggregates - - - - - - Add control over which rows are passed - into aggregate functions via the FILTER clause - (David Fetter) - - - - - - Support ordered-set (WITHIN GROUP) - aggregates (Atri Sharma, Andrew Gierth, Tom Lane) - - - - - - Add standard ordered-set aggregates percentile_cont(), - percentile_disc(), mode(), rank(), - dense_rank(), percent_rank(), and - cume_dist() - (Atri Sharma, Andrew Gierth) - - - - - - Support VARIADIC - aggregate functions (Tom Lane) - - - - - - Allow polymorphic aggregates to have non-polymorphic state data - types (Tom Lane) - - - This allows proper declaration in SQL of aggregates like the built-in - aggregate array_agg(). - - - - - - - - - - - Server-Side Languages - - - - - - Add event trigger support to PL/Perl - and PL/Tcl (Dimitri Fontaine) - - - - - - Convert numeric - values to decimal in PL/Python - (Szymon Guz, Ronan Dunklau) - - - - Previously such values were converted to Python float values, - risking loss of precision. - - - - - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - Add ability to retrieve the current PL/pgSQL call stack - using GET - DIAGNOSTICS - (Pavel Stehule, Stephen Frost) - - - - - - Add option - to display the parameters passed to a query that violated a - STRICT constraint (Marko Tiikkaja) - - - - - - Add variables plpgsql.extra_warnings - and plpgsql.extra_errors to enable additional PL/pgSQL - warnings and errors (Marko Tiikkaja, Petr Jelinek) - - - - Currently only warnings/errors about shadowed variables are available. - - - - - - - - - - - <link linkend="libpq"><application>libpq</application></link> - - - - - Make libpq's PQconndefaults() - function ignore invalid service files (Steve Singer, Bruce Momjian) - - - - Previously it returned NULL if an incorrect service file was - encountered. - - - - - - Accept TLS protocol versions beyond TLSv1 - in libpq (Marko Kreen) - - - - - - - - - Client Applications - - - - - - Add option - to specify role membership (Christopher Browne) - - - - - - Add - option to analyze in stages of - increasing granularity (Peter Eisentraut) - - - - This allows minimal statistics to be created quickly. - - - - - - Make pg_resetxlog - with option output current and potentially changed - values (Rajeev Rastogi) - - - - - - Make throw error for incorrect locale - settings, rather than silently falling back to a default choice - (Tom Lane) - - - - - - Make return exit code 4 for - an inaccessible data directory (Amit Kapila, Bruce Momjian) - - - - This behavior more closely matches the Linux Standard Base - (LSB) Core Specification. - - - - - - On Windows, ensure that a non-absolute path - specification is interpreted relative - to 's current directory - (Kumar Rajeev Rastogi) - - - - Previously it would be interpreted relative to whichever directory - the underlying Windows service was started in. - - - - - - Allow sizeof() in ECPG - C array definitions (Michael Meskes) - - - - - - Make ECPG properly handle nesting - of C-style comments in both C and SQL text - (Michael Meskes) - - - - - - - <xref linkend="app-psql"/> - - - - - - Suppress No rows output in psql - mode when the footer is disabled (Bruce Momjian) - - - - - - Allow Control-C to abort psql when it's hung at - connection startup (Peter Eisentraut) - - - - - - - <link linkend="app-psql-meta-commands">Backslash Commands</link> - - - - - - Make psql's \db+ show tablespace options - (Magnus Hagander) - - - - - - Make \do+ display the functions - that implement the operators (Marko Tiikkaja) - - - - - - Make \d+ output an - OID line only if an oid column - exists in the table (Bruce Momjian) - - - - Previously, the presence or absence of an oid - column was always reported. - - - - - - Make \d show disabled system triggers (Bruce - Momjian) - - - - Previously, if you disabled all triggers, only user triggers - would show as disabled. - - - - - - Fix \copy to no longer require - a space between stdin and a semicolon (Etsuro Fujita) - - - - - - Output the row count at the end of \copy, just - like COPY already did (Kumar Rajeev Rastogi) - - - - - - Fix \conninfo to display the - server's IP address for connections using - hostaddr (Fujii Masao) - - - - Previously \conninfo could not display the server's - IP address in such cases. - - - - - - Show the SSL protocol version in - \conninfo (Marko Kreen) - - - - - - Add tab completion for \pset - (Pavel Stehule) - - - - - - Allow \pset with no arguments - to show all settings (Gilles Darold) - - - - - - Make \s display the name of the history file it wrote - without converting it to an absolute path (Tom Lane) - - - - The code previously attempted to convert a relative file name to - an absolute path for display, but frequently got it wrong. - - - - - - - - - - - <xref linkend="app-pgdump"/> - - - - - - Allow options - , , and - to be specified multiple times (Heikki Linnakangas) - - - - This allows multiple objects to be restored in one operation. - - - - - - Optionally add IF EXISTS clauses to the DROP - commands emitted when removing old objects during a restore (Pavel - Stehule) - - - - This change prevents unnecessary errors when removing old objects. - The new option - for , , - and is only available - when is also specified. - - - - - - - - - <xref linkend="app-pgbasebackup"/> - - - - - - Add pg_basebackup option - to specify the pg_xlog directory location (Haribabu - Kommi) - - - - - - Allow pg_basebackup to relocate tablespaces in - the backup copy (Steeve Lennmark) - - - - This is particularly useful for using pg_basebackup - on the same machine as the primary. - - - - - - Allow network-stream base backups to be throttled (Antonin Houska) - - - - This can be controlled with the pg_basebackup - parameter. - - - - - - - - - - - Source Code - - - - - - Improve the way tuples are frozen to preserve forensic information - (Robert Haas, Andres Freund) - - - - This change removes the main objection to freezing tuples as soon - as possible. Code that inspects tuple flag bits will need to be - modified. - - - - - - No longer require function prototypes for functions marked with the - PG_FUNCTION_INFO_V1 - macro (Peter Eisentraut) - - - - This change eliminates the need to write boilerplate prototypes. - Note that the PG_FUNCTION_INFO_V1 macro must appear - before the corresponding function definition to avoid compiler - warnings. - - - - - - Remove SnapshotNow and - HeapTupleSatisfiesNow() (Robert Haas) - - - - All existing uses have been switched to more appropriate snapshot - types. Catalog scans now use MVCC snapshots. - - - - - - Add an API to allow memory allocations over one gigabyte - (Noah Misch) - - - - - - Add psprintf() to simplify memory allocation during - string composition (Peter Eisentraut, Tom Lane) - - - - - - Support printf() size modifier z to - print size_t values (Andres Freund) - - - - - - Change API of appendStringInfoVA() - to better use vsnprintf() (David Rowley, Tom Lane) - - - - - - Allow new types of external toast datums to be created (Andres - Freund) - - - - - - Add single-reader, single-writer, lightweight shared message queue - (Robert Haas) - - - - - - Improve spinlock speed on x86_64 CPUs (Heikki - Linnakangas) - - - - - - Remove spinlock support for unsupported platforms - SINIX, Sun3, and - NS32K (Robert Haas) - - - - - - Remove IRIX port (Robert Haas) - - - - - - Reduce the number of semaphores required by - builds (Robert Haas) - - - - - - Rewrite duplicate_oids Unix shell script in - Perl (Andrew Dunstan) - - - - - - Add Test Anything Protocol (TAP) tests for client - programs (Peter Eisentraut) - - - - Currently, these tests are run by make check-world - only if the option was given - to configure. - This might become the default behavior in some future release. - - - - - - Add make targets and - , which allow selection of individual - tests to be run (Andrew Dunstan) - - - - - - Remove makefile rule (Peter Eisentraut) - - - - The default build rules now include all the formerly-optional tests. - - - - - - Improve support for VPATH builds of PGXS - modules (Cédric Villemain, Andrew Dunstan, Peter Eisentraut) - - - - - - Upgrade to Autoconf 2.69 (Peter Eisentraut) - - - - - - Add a configure flag that appends custom text to the - PG_VERSION string (Oskari Saarenmaa) - - - - This is useful for packagers building custom binaries. - - - - - - Improve DocBook XML validity (Peter Eisentraut) - - - - - - Fix various minor security and sanity issues reported by the - Coverity scanner (Stephen Frost) - - - - - - Improve detection of invalid memory usage when testing - PostgreSQL with Valgrind - (Noah Misch) - - - - - - Improve sample Emacs configuration file - emacs.samples (Peter Eisentraut) - - - - Also add .dir-locals.el to the top of the source tree. - - - - - - Allow pgindent to accept a command-line list - of typedefs (Bruce Momjian) - - - - - - Make pgindent smarter about blank lines - around preprocessor conditionals (Bruce Momjian) - - - - - - Avoid most uses of dlltool - in Cygwin and - Mingw builds (Marco Atzeri, Hiroshi Inoue) - - - - - - Support client-only installs in MSVC (Windows) builds - (MauMau) - - - - - - - - - Additional Modules - - - - - - Add extension to preload relation data - into the shared buffer cache at server start (Robert Haas) - - - - This allows reaching full operating performance more quickly. - - - - - - Add UUID random number generator - gen_random_uuid() to - (Oskari Saarenmaa) - - - - This allows creation of version 4 UUIDs without - requiring installation of . - - - - - - Allow to work with - the BSD or e2fsprogs UUID libraries, - not only the OSSP UUID library (Matteo Beccati) - - - - This improves the uuid-ossp module's portability - since it no longer has to have the increasingly-obsolete OSSP - library. The module's name is now rather a misnomer, but we won't - change it. - - - - - - Add option to to include trigger - execution time (Horiguchi Kyotaro) - - - - - - Fix to not report rows from - uncommitted transactions as dead (Robert Haas) - - - - - - Make functions - use regclass-type arguments (Satoshi Nagayasu) - - - - While text-type arguments are still supported, they - may be removed in a future major release. - - - - - - Improve consistency of output to honor - snapshot rules more consistently (Robert Haas) - - - - - - Improve 's choice of trigrams for indexed - regular expression searches (Alexander Korotkov) - - - - This change discourages use of trigrams containing whitespace, which - are usually less selective. - - - - - - Allow pg_xlogdump - to report a live log stream with - (Heikki Linnakangas) - - - - - - Store data more compactly (Stas Kelvich) - - - - Existing data must be dumped/restored to use the new format. - The old format can still be read. - - - - - - Reduce client-side memory usage by using - a cursor (Andrew Dunstan) - - - - - - Dramatically reduce memory consumption - in (Bruce Momjian) - - - - - - Pass 's user name () option to - generated analyze scripts (Bruce Momjian) - - - - - - - <xref linkend="pgbench"/> - - - - - - Remove line length limit for pgbench scripts (Sawada - Masahiko) - - - - The previous line limit was BUFSIZ. - - - - - - Add long option names to pgbench (Fabien Coelho) - - - - - - Add pgbench option to control - the transaction rate (Fabien Coelho) - - - - - - Add pgbench option to - print periodic progress reports - (Fabien Coelho) - - - - - - - - - <xref linkend="pgstatstatements"/> - - - - - - Make pg_stat_statements use a file, rather than - shared memory, for query text storage (Peter Geoghegan) - - - - This removes the previous limitation on query text length, and - allows a higher number of unique statements to be tracked by default. - - - - - - Allow reporting of pg_stat_statements's internal - query hash identifier (Daniel Farina, Sameer Thakur, Peter - Geoghegan) - - - - - - Add the ability to retrieve all pg_stat_statements - information except the query text (Peter Geoghegan) - - - - This allows monitoring tools to fetch query text only for - just-created entries, improving performance during repeated querying - of the statistics. - - - - - - Make pg_stat_statements ignore DEALLOCATE - commands (Fabien Coelho) - - - - It already ignored PREPARE, as well as planning time in - general, so this seems more consistent. - - - - - - Save the statistics file into $PGDATA/pg_stat at server - shutdown, rather than $PGDATA/global (Fujii Masao) - - - - - - - - - - - diff --git a/doc/src/sgml/release-9.5.sgml b/doc/src/sgml/release-9.5.sgml deleted file mode 100644 index b62dd732a20..00000000000 --- a/doc/src/sgml/release-9.5.sgml +++ /dev/null @@ -1,9658 +0,0 @@ - - - - - Release 9.5.12 - - - Release date: - 2018-03-01 - - - - This release contains a variety of fixes from 9.5.11. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.12 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you run an installation in which not all users are mutually - trusting, or if you maintain an application or extension that is - intended for use in arbitrary situations, it is strongly recommended - that you read the documentation changes described in the first changelog - entry below, and take suitable steps to ensure that your installation or - code is secure. - - - - Also, the changes described in the second changelog entry below may - cause functions used in index expressions or materialized views to fail - during auto-analyze, or when reloading from a dump. After upgrading, - monitor the server logs for such problems, and fix affected functions. - - - - Also, if you are upgrading from a version earlier than 9.5.10, - see . - - - - - Changes - - - - - - Document how to configure installations and applications to guard - against search-path-dependent trojan-horse attacks from other users - (Noah Misch) - - - - Using a search_path setting that includes any - schemas writable by a hostile user enables that user to capture - control of queries and then run arbitrary SQL code with the - permissions of the attacked user. While it is possible to write - queries that are proof against such hijacking, it is notationally - tedious, and it's very easy to overlook holes. Therefore, we now - recommend configurations in which no untrusted schemas appear in - one's search path. Relevant documentation appears in - (for database administrators and users), - (for application authors), - (for extension authors), and - (for authors - of SECURITY DEFINER functions). - (CVE-2018-1058) - - - - - - Avoid use of insecure search_path settings - in pg_dump and other client programs - (Noah Misch, Tom Lane) - - - - pg_dump, - pg_upgrade, - vacuumdb and - other PostgreSQL-provided applications were - themselves vulnerable to the type of hijacking described in the previous - changelog entry; since these applications are commonly run by - superusers, they present particularly attractive targets. To make them - secure whether or not the installation as a whole has been secured, - modify them to include only the pg_catalog - schema in their search_path settings. - Autovacuum worker processes now do the same, as well. - - - - In cases where user-provided functions are indirectly executed by - these programs — for example, user-provided functions in index - expressions — the tighter search_path may - result in errors, which will need to be corrected by adjusting those - user-provided functions to not assume anything about what search path - they are invoked under. That has always been good practice, but now - it will be necessary for correct behavior. - (CVE-2018-1058) - - - - - - Fix misbehavior of concurrent-update rechecks with CTE references - appearing in subplans (Tom Lane) - - - - If a CTE (WITH clause reference) is used in an - InitPlan or SubPlan, and the query requires a recheck due to trying - to update or lock a concurrently-updated row, incorrect results could - be obtained. - - - - - - Fix planner failures with overlapping mergejoin clauses in an outer - join (Tom Lane) - - - - These mistakes led to left and right pathkeys do not match in - mergejoin or outer pathkeys do not match - mergeclauses planner errors in corner cases. - - - - - - Repair pg_upgrade's failure to - preserve relfrozenxid for materialized - views (Tom Lane, Andres Freund) - - - - This oversight could lead to data corruption in materialized views - after an upgrade, manifesting as could not access status of - transaction or found xmin from before - relfrozenxid errors. The problem would be more likely to - occur in seldom-refreshed materialized views, or ones that were - maintained only with REFRESH MATERIALIZED VIEW - CONCURRENTLY. - - - - If such corruption is observed, it can be repaired by refreshing the - materialized view (without CONCURRENTLY). - - - - - - Fix incorrect reporting of PL/Python function names in - error CONTEXT stacks (Tom Lane) - - - - An error occurring within a nested PL/Python function call (that is, - one reached via a SPI query from another PL/Python function) would - result in a stack trace showing the inner function's name twice, - rather than the expected results. Also, an error in a nested - PL/Python DO block could result in a null pointer - dereference crash on some platforms. - - - - - - Allow contrib/auto_explain's - log_min_duration setting to range up - to INT_MAX, or about 24 days instead of 35 minutes - (Tom Lane) - - - - - - - - - - Release 9.5.11 - - - Release date: - 2018-02-08 - - - - This release contains a variety of fixes from 9.5.10. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.11 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you are upgrading from a version earlier than 9.5.10, - see . - - - - - Changes - - - - - - Ensure that all temporary files made - by pg_upgrade are non-world-readable - (Tom Lane, Noah Misch) - - - - pg_upgrade normally restricts its - temporary files to be readable and writable only by the calling user. - But the temporary file containing pg_dumpall -g - output would be group- or world-readable, or even writable, if the - user's umask setting allows. In typical usage on - multi-user machines, the umask and/or the working - directory's permissions would be tight enough to prevent problems; - but there may be people using pg_upgrade - in scenarios where this oversight would permit disclosure of database - passwords to unfriendly eyes. - (CVE-2018-1053) - - - - - - Fix vacuuming of tuples that were updated while key-share locked - (Andres Freund, Álvaro Herrera) - - - - In some cases VACUUM would fail to remove such - tuples even though they are now dead, leading to assorted data - corruption scenarios. - - - - - - Fix inadequate buffer locking in some LSN fetches (Jacob Champion, - Asim Praveen, Ashwin Agrawal) - - - - These errors could result in misbehavior under concurrent load. - The potential consequences have not been characterized fully. - - - - - - Fix incorrect query results from cases involving flattening of - subqueries whose outputs are used in GROUPING SETS - (Heikki Linnakangas) - - - - - - Avoid unnecessary failure in a query on an inheritance tree that - occurs concurrently with some child table being removed from the tree - by ALTER TABLE NO INHERIT (Tom Lane) - - - - - - Fix spurious deadlock failures when multiple sessions are - running CREATE INDEX CONCURRENTLY (Jeff Janes) - - - - - - Fix failures when an inheritance tree contains foreign child tables - (Etsuro Fujita) - - - - A mix of regular and foreign tables in an inheritance tree resulted in - creation of incorrect plans for UPDATE - and DELETE queries. This led to visible failures in - some cases, notably when there are row-level triggers on a foreign - child table. - - - - - - Repair failure with correlated sub-SELECT - inside VALUES inside a LATERAL - subquery (Tom Lane) - - - - - - Fix could not devise a query plan for the given query - planner failure for some cases involving nested UNION - ALL inside a lateral subquery (Tom Lane) - - - - - - Fix logical decoding to correctly clean up disk files for crashed - transactions (Atsushi Torikoshi) - - - - Logical decoding may spill WAL records to disk for transactions - generating many WAL records. Normally these files are cleaned up - after the transaction's commit or abort record arrives; but if - no such record is ever seen, the removal code misbehaved. - - - - - - Fix walsender timeout failure and failure to respond to interrupts - when processing a large transaction (Petr Jelinek) - - - - - - Fix has_sequence_privilege() to - support WITH GRANT OPTION tests, - as other privilege-testing functions do (Joe Conway) - - - - - - In databases using UTF8 encoding, ignore any XML declaration that - asserts a different encoding (Pavel Stehule, Noah Misch) - - - - We always store XML strings in the database encoding, so allowing - libxml to act on a declaration of another encoding gave wrong results. - In encodings other than UTF8, we don't promise to support non-ASCII - XML data anyway, so retain the previous behavior for bug compatibility. - This change affects only xpath() and related - functions; other XML code paths already acted this way. - - - - - - Provide for forward compatibility with future minor protocol versions - (Robert Haas, Badrul Chowdhury) - - - - Up to now, PostgreSQL servers simply - rejected requests to use protocol versions newer than 3.0, so that - there was no functional difference between the major and minor parts - of the protocol version number. Allow clients to request versions 3.x - without failing, sending back a message showing that the server only - understands 3.0. This makes no difference at the moment, but - back-patching this change should allow speedier introduction of future - minor protocol upgrades. - - - - - - Cope with failure to start a parallel worker process - (Amit Kapila, Robert Haas) - - - - Parallel query previously tended to hang indefinitely if a worker - could not be started, as the result of fork() - failure or other low-probability problems. - - - - - - Avoid unsafe alignment assumptions when working - with __int128 (Tom Lane) - - - - Typically, compilers assume that __int128 variables are - aligned on 16-byte boundaries, but our memory allocation - infrastructure isn't prepared to guarantee that, and increasing the - setting of MAXALIGN seems infeasible for multiple reasons. Adjust the - code to allow use of __int128 only when we can tell the - compiler to assume lesser alignment. The only known symptom of this - problem so far is crashes in some parallel aggregation queries. - - - - - - Prevent stack-overflow crashes when planning extremely deeply - nested set operations - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Fix null-pointer crashes for some types of LDAP URLs appearing - in pg_hba.conf (Thomas Munro) - - - - - - Fix sample INSTR() functions in the PL/pgSQL - documentation (Yugo Nagata, Tom Lane) - - - - These functions are stated to - be Oracle compatible, but - they weren't exactly. In particular, there was a discrepancy in the - interpretation of a negative third parameter: Oracle thinks that a - negative value indicates the last place where the target substring can - begin, whereas our functions took it as the last place where the - target can end. Also, Oracle throws an error for a zero or negative - fourth parameter, whereas our functions returned zero. - - - - The sample code has been adjusted to match Oracle's behavior more - precisely. Users who have copied this code into their applications - may wish to update their copies. - - - - - - Fix pg_dump to make ACL (permissions), - comment, and security label entries reliably identifiable in archive - output formats (Tom Lane) - - - - The tag portion of an ACL archive entry was usually - just the name of the associated object. Make it start with the object - type instead, bringing ACLs into line with the convention already used - for comment and security label archive entries. Also, fix the - comment and security label entries for the whole database, if present, - to make their tags start with DATABASE so that they - also follow this convention. This prevents false matches in code that - tries to identify large-object-related entries by seeing if the tag - starts with LARGE OBJECT. That could have resulted - in misclassifying entries as data rather than schema, with undesirable - results in a schema-only or data-only dump. - - - - Note that this change has user-visible results in the output - of pg_restore --list. - - - - - - Rename pg_rewind's - copy_file_range function to avoid conflict - with new Linux system call of that name (Andres Freund) - - - - This change prevents build failures with newer glibc versions. - - - - - - In ecpg, detect indicator arrays that do - not have the correct length and report an error (David Rader) - - - - - - Avoid triggering a libc assertion - in contrib/hstore, due to use - of memcpy() with equal source and destination - pointers (Tomas Vondra) - - - - - - Provide modern examples of how to auto-start Postgres on macOS - (Tom Lane) - - - - The scripts in contrib/start-scripts/osx use - infrastructure that's been deprecated for over a decade, and which no - longer works at all in macOS releases of the last couple of years. - Add a new subdirectory contrib/start-scripts/macos - containing scripts that use the newer launchd - infrastructure. - - - - - - Fix incorrect selection of configuration-specific libraries for - OpenSSL on Windows (Andrew Dunstan) - - - - - - Support linking to MinGW-built versions of libperl (Noah Misch) - - - - This allows building PL/Perl with some common Perl distributions for - Windows. - - - - - - Fix MSVC build to test whether 32-bit libperl - needs -D_USE_32BIT_TIME_T (Noah Misch) - - - - Available Perl distributions are inconsistent about what they expect, - and lack any reliable means of reporting it, so resort to a build-time - test on what the library being used actually does. - - - - - - On Windows, install the crash dump handler earlier in postmaster - startup (Takayuki Tsunakawa) - - - - This may allow collection of a core dump for some early-startup - failures that did not produce a dump before. - - - - - - On Windows, avoid encoding-conversion-related crashes when emitting - messages very early in postmaster startup (Takayuki Tsunakawa) - - - - - - Use our existing Motorola 68K spinlock code on OpenBSD as - well as NetBSD (David Carlier) - - - - - - Add support for spinlocks on Motorola 88K (David Carlier) - - - - - - Update time zone data files to tzdata - release 2018c for DST law changes in Brazil, Sao Tome and Principe, - plus historical corrections for Bolivia, Japan, and South Sudan. - The US/Pacific-New zone has been removed (it was - only an alias for America/Los_Angeles anyway). - - - - - - - - - - Release 9.5.10 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 9.5.9. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.10 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you use BRIN indexes, see the fourth changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.5.8, - see . - - - - - Changes - - - - - - Ensure that INSERT ... ON CONFLICT DO UPDATE checks - table permissions and RLS policies in all cases (Dean Rasheed) - - - - The update path of INSERT ... ON CONFLICT DO UPDATE - requires SELECT permission on the columns of the - arbiter index, but it failed to check for that in the case of an - arbiter specified by constraint name. - In addition, for a table with row level security enabled, it failed to - check updated rows against the table's SELECT - policies (regardless of how the arbiter index was specified). - (CVE-2017-15099) - - - - - - Fix crash due to rowtype mismatch - in json{b}_populate_recordset() - (Michael Paquier, Tom Lane) - - - - These functions used the result rowtype specified in the FROM - ... AS clause without checking that it matched the actual - rowtype of the supplied tuple value. If it didn't, that would usually - result in a crash, though disclosure of server memory contents seems - possible as well. - (CVE-2017-15098) - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - Fix BRIN index summarization to handle concurrent table extension - correctly (Álvaro Herrera) - - - - Previously, a race condition allowed some table rows to be omitted from - the index. It may be necessary to reindex existing BRIN indexes to - recover from past occurrences of this problem. - - - - - - Fix possible failures during concurrent updates of a BRIN index - (Tom Lane) - - - - These race conditions could result in errors like invalid index - offnum or inconsistent range map. - - - - - - Fix crash when logical decoding is invoked from a SPI-using function, - in particular any function written in a PL language - (Tom Lane) - - - - - - Fix json_build_array(), - json_build_object(), and their jsonb - equivalents to handle explicit VARIADIC arguments - correctly (Michael Paquier) - - - - - - Properly reject attempts to convert infinite float values to - type numeric (Tom Lane, KaiGai Kohei) - - - - Previously the behavior was platform-dependent. - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - Correctly ignore RelabelType expression nodes - when determining relation distinctness (David Rowley) - - - - This allows the intended optimization to occur when a subquery has - a result column of type varchar. - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - Avoid SIGBUS crash on Linux when a DSM memory - request exceeds the space available in tmpfs - (Thomas Munro) - - - - - - Prevent low-probability crash in processing of nested trigger firings - (Tom Lane) - - - - - - Allow COPY's FREEZE option to - work when the transaction isolation level is REPEATABLE - READ or higher (Noah Misch) - - - - This case was unintentionally broken by a previous bug fix. - - - - - - Correctly restore the umask setting when file creation fails - in COPY or lo_export() - (Peter Eisentraut) - - - - - - Give a better error message for duplicate column names - in ANALYZE (Nathan Bossart) - - - - - - Fix mis-parsing of the last line in a - non-newline-terminated pg_hba.conf file - (Tom Lane) - - - - - - Fix pg_basebackup's matching of tablespace - paths to canonicalize both paths before comparing (Michael Paquier) - - - - This is particularly helpful on Windows. - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - Fix libpq to guard against integer - overflow in the row count of a PGresult - (Michael Paquier) - - - - - - Fix ecpg's handling of out-of-scope cursor - declarations with pointer or array variables (Michael Meskes) - - - - - - In ecpglib, correctly handle backslashes in string literals depending - on whether standard_conforming_strings is set - (Tsunakawa Takayuki) - - - - - - Make ecpglib's Informix-compatibility mode ignore fractional digits in - integer input strings, as expected (Gao Zengqi, Michael Meskes) - - - - - - Fix missing temp-install prerequisites - for check-like Make targets (Noah Misch) - - - - Some non-default test procedures that are meant to work - like make check failed to ensure that the temporary - installation was up to date. - - - - - - Sync our copy of the timezone library with IANA release tzcode2017c - (Tom Lane) - - - - This fixes various issues; the only one likely to be user-visible - is that the default DST rules for a POSIX-style zone name, if - no posixrules file exists in the timezone data - directory, now match current US law rather than what it was a dozen - years ago. - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - - - - Release 9.5.9 - - - Release date: - 2017-08-31 - - - - This release contains a small number of fixes from 9.5.8. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.9 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you are upgrading from a version earlier than 9.5.8, - see . - - - - - Changes - - - - - - Show foreign tables - in information_schema.table_privileges - view (Peter Eisentraut) - - - - All other relevant information_schema views include - foreign tables, but this one ignored them. - - - - Since this view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can, as a superuser, do this - in psql: - -SET search_path TO information_schema; -CREATE OR REPLACE VIEW table_privileges AS - SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, - CAST(grantee.rolname AS sql_identifier) AS grantee, - CAST(current_database() AS sql_identifier) AS table_catalog, - CAST(nc.nspname AS sql_identifier) AS table_schema, - CAST(c.relname AS sql_identifier) AS table_name, - CAST(c.prtype AS character_data) AS privilege_type, - CAST( - CASE WHEN - -- object owner always has grant options - pg_has_role(grantee.oid, c.relowner, 'USAGE') - OR c.grantable - THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, - CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy - - FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class - ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), - pg_namespace nc, - pg_authid u_grantor, - ( - SELECT oid, rolname FROM pg_authid - UNION ALL - SELECT 0::oid, 'PUBLIC' - ) AS grantee (oid, rolname) - - WHERE c.relnamespace = nc.oid - AND c.relkind IN ('r', 'v', 'f') - AND c.grantee = grantee.oid - AND c.grantor = u_grantor.oid - AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') - AND (pg_has_role(u_grantor.oid, 'USAGE') - OR pg_has_role(grantee.oid, 'USAGE') - OR grantee.rolname = 'PUBLIC'); - - This must be repeated in each database to be fixed, - including template0. - - - - - - Clean up handling of a fatal exit (e.g., due to receipt - of SIGTERM) that occurs while trying to execute - a ROLLBACK of a failed transaction (Tom Lane) - - - - This situation could result in an assertion failure. In production - builds, the exit would still occur, but it would log an unexpected - message about cannot drop active portal. - - - - - - Remove assertion that could trigger during a fatal exit (Tom Lane) - - - - - - Correctly identify columns that are of a range type or domain type over - a composite type or domain type being searched for (Tom Lane) - - - - Certain ALTER commands that change the definition of a - composite type or domain type are supposed to fail if there are any - stored values of that type in the database, because they lack the - infrastructure needed to update or check such values. Previously, - these checks could miss relevant values that are wrapped inside range - types or sub-domains, possibly allowing the database to become - inconsistent. - - - - - - Fix crash in pg_restore when using parallel mode and - using a list file to select a subset of items to restore - (Fabrízio de Royes Mello) - - - - - - Change ecpg's parser to allow RETURNING - clauses without attached C variables (Michael Meskes) - - - - This allows ecpg programs to contain SQL constructs - that use RETURNING internally (for example, inside a CTE) - rather than using it to define values to be returned to the client. - - - - - - Improve selection of compiler flags for PL/Perl on Windows (Tom Lane) - - - - This fix avoids possible crashes of PL/Perl due to inconsistent - assumptions about the width of time_t values. - A side-effect that may be visible to extension developers is - that _USE_32BIT_TIME_T is no longer defined globally - in PostgreSQL Windows builds. This is not expected - to cause problems, because type time_t is not used - in any PostgreSQL API definitions. - - - - - - Fix make check to behave correctly when invoked via a - non-GNU make program (Thomas Munro) - - - - - - - - - - Release 9.5.8 - - - Release date: - 2017-08-10 - - - - This release contains a variety of fixes from 9.5.7. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.8 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.5.7, - see . - - - - - Changes - - - - - - Further restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Noah Misch) - - - - The fix for CVE-2017-7486 was incorrect: it allowed a user - to see the options in her own user mapping, even if she did not - have USAGE permission on the associated foreign server. - Such options might include a password that had been provided by the - server owner rather than the user herself. - Since information_schema.user_mapping_options does not - show the options in such cases, pg_user_mappings - should not either. - (CVE-2017-7547) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - you will need to do the following: - - - - - - Restart the postmaster after adding allow_system_table_mods - = true to postgresql.conf. (In versions - supporting ALTER SYSTEM, you can use that to make the - configuration change, but you'll still need a restart.) - - - - - - In each database of the cluster, - run the following commands as superuser: - -SET search_path = pg_catalog; -CREATE OR REPLACE VIEW pg_user_mappings AS - SELECT - U.oid AS umid, - S.oid AS srvid, - S.srvname AS srvname, - U.umuser AS umuser, - CASE WHEN U.umuser = 0 THEN - 'public' - ELSE - A.rolname - END AS usename, - CASE WHEN (U.umuser <> 0 AND A.rolname = current_user - AND (pg_has_role(S.srvowner, 'USAGE') - OR has_server_privilege(S.oid, 'USAGE'))) - OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE')) - OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) - THEN U.umoptions - ELSE NULL END AS umoptions - FROM pg_user_mapping U - LEFT JOIN pg_authid A ON (A.oid = U.umuser) JOIN - pg_foreign_server S ON (U.umserver = S.oid); - - - - - - - Do not forget to include the template0 - and template1 databases, or the vulnerability will still - exist in databases you create later. To fix template0, - you'll need to temporarily make it accept connections. - In PostgreSQL 9.5 and later, you can use - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true; - - and then after fixing template0, undo that with - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false; - - In prior versions, instead use - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - - Finally, remove the allow_system_table_mods configuration - setting, and again restart the postmaster. - - - - - - - - Disallow empty passwords in all password-based authentication methods - (Heikki Linnakangas) - - - - libpq ignores empty password specifications, and does - not transmit them to the server. So, if a user's password has been - set to the empty string, it's impossible to log in with that password - via psql or other libpq-based - clients. An administrator might therefore believe that setting the - password to empty is equivalent to disabling password login. - However, with a modified or non-libpq-based client, - logging in could be possible, depending on which authentication - method is configured. In particular the most common - method, md5, accepted empty passwords. - Change the server to reject empty passwords in all cases. - (CVE-2017-7546) - - - - - - Make lo_put() check for UPDATE privilege on - the target large object (Tom Lane, Michael Paquier) - - - - lo_put() should surely require the same permissions - as lowrite(), but the check was missing, allowing any - user to change the data in a large object. - (CVE-2017-7548) - - - - - - Correct the documentation about the process for upgrading standby - servers with pg_upgrade (Bruce Momjian) - - - - The previous documentation instructed users to start/stop the primary - server after running pg_upgrade but before syncing - the standby servers. This sequence is unsafe. - - - - - - Fix concurrent locking of tuple update chains (Álvaro Herrera) - - - - If several sessions concurrently lock a tuple update chain with - nonconflicting lock modes using an old snapshot, and they all - succeed, it was possible for some of them to nonetheless fail (and - conclude there is no live tuple version) due to a race condition. - This had consequences such as foreign-key checks failing to see a - tuple that definitely exists but is being updated concurrently. - - - - - - Fix potential data corruption when freezing a tuple whose XMAX is a - multixact with exactly one still-interesting member (Teodor Sigaev) - - - - - - Avoid integer overflow and ensuing crash when sorting more than one - billion tuples in-memory (Sergey Koposov) - - - - - - On Windows, retry process creation if we fail to reserve the address - range for our shared memory in the new process (Tom Lane, Amit - Kapila) - - - - This is expected to fix infrequent child-process-launch failures that - are probably due to interference from antivirus products. - - - - - - Fix low-probability corruption of shared predicate-lock hash table - in Windows builds (Thomas Munro, Tom Lane) - - - - - - Avoid logging clean closure of an SSL connection as though - it were a connection reset (Michael Paquier) - - - - - - Prevent sending SSL session tickets to clients (Tom Lane) - - - - This fix prevents reconnection failures with ticket-aware client-side - SSL code. - - - - - - Fix code for setting on - Solaris (Tom Lane) - - - - - - Fix statistics collector to honor inquiry messages issued just after - a postmaster shutdown and immediate restart (Tom Lane) - - - - Statistics inquiries issued within half a second of the previous - postmaster shutdown were effectively ignored. - - - - - - Ensure that the statistics collector's receive buffer size is at - least 100KB (Tom Lane) - - - - This reduces the risk of dropped statistics data on older platforms - whose default receive buffer size is less than that. - - - - - - Fix possible creation of an invalid WAL segment when a standby is - promoted just after it processes an XLOG_SWITCH WAL - record (Andres Freund) - - - - - - Fix walsender to exit promptly when client requests - shutdown (Tom Lane) - - - - - - Fix SIGHUP and SIGUSR1 handling in - walsender processes (Petr Jelinek, Andres Freund) - - - - - - Prevent walsender-triggered panics during shutdown checkpoints - (Andres Freund, Michael Paquier) - - - - - - Fix unnecessarily slow restarts of walreceiver - processes due to race condition in postmaster (Tom Lane) - - - - - - Fix leakage of small subtransactions spilled to disk during logical - decoding (Andres Freund) - - - - This resulted in temporary files consuming excessive disk space. - - - - - - Reduce the work needed to build snapshots during creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - The previous algorithm was infeasibly expensive on a server with a - lot of open transactions. - - - - - - Fix race condition that could indefinitely delay creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - - - Reduce overhead in processing syscache invalidation events (Tom Lane) - - - - This is particularly helpful for logical decoding, which triggers - frequent cache invalidation. - - - - - - Fix cases where an INSERT or UPDATE assigns - to more than one element of a column that is of domain-over-array - type (Tom Lane) - - - - - - Allow window functions to be used in sub-SELECTs that - are within the arguments of an aggregate function (Tom Lane) - - - - - - Move autogenerated array types out of the way during - ALTER ... RENAME (Vik Fearing) - - - - Previously, we would rename a conflicting autogenerated array type - out of the way during CREATE; this fix extends that - behavior to renaming operations. - - - - - - Fix dangling pointer in ALTER TABLE when there is a - comment on a constraint belonging to the table (David Rowley) - - - - Re-applying the comment to the reconstructed constraint could fail - with a weird error message, or even crash. - - - - - - Ensure that ALTER USER ... SET accepts all the syntax - variants that ALTER ROLE ... SET does (Peter Eisentraut) - - - - - - Properly update dependency info when changing a datatype I/O - function's argument or return type from opaque to the - correct type (Heikki Linnakangas) - - - - CREATE TYPE updates I/O functions declared in this - long-obsolete style, but it forgot to record a dependency on the - type, allowing a subsequent DROP TYPE to leave broken - function definitions behind. - - - - - - Reduce memory usage when ANALYZE processes - a tsvector column (Heikki Linnakangas) - - - - - - Fix unnecessary precision loss and sloppy rounding when multiplying - or dividing money values by integers or floats (Tom Lane) - - - - - - Tighten checks for whitespace in functions that parse identifiers, - such as regprocedurein() (Tom Lane) - - - - Depending on the prevailing locale, these functions could - misinterpret fragments of multibyte characters as whitespace. - - - - - - Use relevant #define symbols from Perl while - compiling PL/Perl (Ashutosh Sharma, Tom Lane) - - - - This avoids portability problems, typically manifesting as - a handshake mismatch during library load, when working with - recent Perl versions. - - - - - - In libpq, reset GSS/SASL and SSPI authentication - state properly after a failed connection attempt (Michael Paquier) - - - - Failure to do this meant that when falling back from SSL to non-SSL - connections, a GSS/SASL failure in the SSL attempt would always cause - the non-SSL attempt to fail. SSPI did not fail, but it leaked memory. - - - - - - In psql, fix failure when COPY FROM STDIN - is ended with a keyboard EOF signal and then another COPY - FROM STDIN is attempted (Thomas Munro) - - - - This misbehavior was observed on BSD-derived platforms (including - macOS), but not on most others. - - - - - - Fix pg_dump and pg_restore to - emit REFRESH MATERIALIZED VIEW commands last (Tom Lane) - - - - This prevents errors during dump/restore when a materialized view - refers to tables owned by a different user. - - - - - - Improve pg_dump/pg_restore's - reporting of error conditions originating in zlib - (Vladimir Kunschikov, Álvaro Herrera) - - - - - - Fix pg_dump with the option to - drop event triggers as expected (Tom Lane) - - - - It also now correctly assigns ownership of event triggers; before, - they were restored as being owned by the superuser running the - restore script. - - - - - - Fix pg_dump to not emit invalid SQL for an empty - operator class (Daniel Gustafsson) - - - - - - Fix pg_dump output to stdout on Windows (Kuntal Ghosh) - - - - A compressed plain-text dump written to stdout would contain corrupt - data due to failure to put the file descriptor into binary mode. - - - - - - Fix pg_get_ruledef() to print correct output for - the ON SELECT rule of a view whose columns have been - renamed (Tom Lane) - - - - In some corner cases, pg_dump relies - on pg_get_ruledef() to dump views, so that this error - could result in dump/reload failures. - - - - - - Fix dumping of outer joins with empty constraints, such as the result - of a NATURAL LEFT JOIN with no common columns (Tom Lane) - - - - - - Fix dumping of function expressions in the FROM clause in - cases where the expression does not deparse into something that looks - like a function call (Tom Lane) - - - - - - Fix pg_basebackup output to stdout on Windows - (Haribabu Kommi) - - - - A backup written to stdout would contain corrupt data due to failure - to put the file descriptor into binary mode. - - - - - - Fix pg_rewind to correctly handle files exceeding 2GB - (Kuntal Ghosh, Michael Paquier) - - - - Ordinarily such files won't appear in PostgreSQL data - directories, but they could be present in some cases. - - - - - - Fix pg_upgrade to ensure that the ending WAL record - does not have = minimum - (Bruce Momjian) - - - - This condition could prevent upgraded standby servers from - reconnecting. - - - - - - Fix pg_xlogdump's computation of WAL record length - (Andres Freund) - - - - - - In postgres_fdw, re-establish connections to remote - servers after ALTER SERVER or ALTER USER - MAPPING commands (Kyotaro Horiguchi) - - - - This ensures that option changes affecting connection parameters will - be applied promptly. - - - - - - In postgres_fdw, allow cancellation of remote - transaction control commands (Robert Haas, Rafia Sabih) - - - - This change allows us to quickly escape a wait for an unresponsive - remote server in many more cases than previously. - - - - - - Increase MAX_SYSCACHE_CALLBACKS to provide more room for - extensions (Tom Lane) - - - - - - Always use , not , when building - shared libraries with gcc (Tom Lane) - - - - This supports larger extension libraries on platforms where it makes - a difference. - - - - - - - Fix unescaped-braces issue in our build scripts for Microsoft MSVC, - to avoid a warning or error from recent Perl versions (Andrew - Dunstan) - - - - - - In MSVC builds, handle the case where the openssl - library is not within a VC subdirectory (Andrew Dunstan) - - - - - - In MSVC builds, add proper include path for libxml2 - header files (Andrew Dunstan) - - - - This fixes a former need to move things around in standard Windows - installations of libxml2. - - - - - - In MSVC builds, recognize a Tcl library that is - named tcl86.lib (Noah Misch) - - - - - - In MSVC builds, honor PROVE_FLAGS settings - on vcregress.pl's command line (Andrew Dunstan) - - - - - - - - - - Release 9.5.7 - - - Release date: - 2017-05-11 - - - - This release contains a variety of fixes from 9.5.6. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.7 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are using third-party replication tools that depend - on logical decoding, see the fourth changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.5.6, - see . - - - - - Changes - - - - - - Restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Michael Paquier, Feike Steenbergen) - - - - The previous coding allowed the owner of a foreign server object, - or anyone he has granted server USAGE permission to, - to see the options for all user mappings associated with that server. - This might well include passwords for other users. - Adjust the view definition to match the behavior of - information_schema.user_mapping_options, namely that - these options are visible to the user being mapped, or if the mapping - is for PUBLIC and the current user is the server - owner, or if the current user is a superuser. - (CVE-2017-7486) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - follow the corrected procedure shown in the changelog entry for - CVE-2017-7547, in . - - - - - - Prevent exposure of statistical information via leaky operators - (Peter Eisentraut) - - - - Some selectivity estimation functions in the planner will apply - user-defined operators to values obtained - from pg_statistic, such as most common values and - histogram entries. This occurs before table permissions are checked, - so a nefarious user could exploit the behavior to obtain these values - for table columns he does not have permission to read. To fix, - fall back to a default estimate if the operator's implementation - function is not certified leak-proof and the calling user does not have - permission to read the table column whose statistics are needed. - At least one of these criteria is satisfied in most cases in practice. - (CVE-2017-7484) - - - - - - Restore libpq's recognition of - the PGREQUIRESSL environment variable (Daniel Gustafsson) - - - - Processing of this environment variable was unintentionally dropped - in PostgreSQL 9.3, but its documentation remained. - This creates a security hazard, since users might be relying on the - environment variable to force SSL-encrypted connections, but that - would no longer be guaranteed. Restore handling of the variable, - but give it lower priority than PGSSLMODE, to avoid - breaking configurations that work correctly with post-9.3 code. - (CVE-2017-7485) - - - - - - Fix possibly-invalid initial snapshot during logical decoding - (Petr Jelinek, Andres Freund) - - - - The initial snapshot created for a logical decoding replication slot - was potentially incorrect. This could cause third-party tools that - use logical decoding to copy incomplete/inconsistent initial data. - This was more likely to happen if the source server was busy at the - time of slot creation, or if another logical slot already existed. - - - - If you are using a replication tool that depends on logical decoding, - and it should have copied a nonempty data set at the start of - replication, it is advisable to recreate the replica after - installing this update, or to verify its contents against the source - server. - - - - - - Fix possible corruption of init forks of unlogged indexes - (Robert Haas, Michael Paquier) - - - - This could result in an unlogged index being set to an invalid state - after a crash and restart. Such a problem would persist until the - index was dropped and rebuilt. - - - - - - Fix incorrect reconstruction of pg_subtrans entries - when a standby server replays a prepared but uncommitted two-phase - transaction (Tom Lane) - - - - In most cases this turned out to have no visible ill effects, but in - corner cases it could result in circular references - in pg_subtrans, potentially causing infinite loops - in queries that examine rows modified by the two-phase transaction. - - - - - - Avoid possible crash in walsender due to failure - to initialize a string buffer (Stas Kelvich, Fujii Masao) - - - - - - Fix possible crash when rescanning a nearest-neighbor index-only scan - on a GiST index (Tom Lane) - - - - - - Fix postmaster's handling of fork() failure for a - background worker process (Tom Lane) - - - - Previously, the postmaster updated portions of its state as though - the process had been launched successfully, resulting in subsequent - confusion. - - - - - - - Fix crash or wrong answers when a GROUPING SETS column's - data type is hashable but not sortable (Pavan Deolasee) - - - - - - Avoid applying physical targetlist optimization to custom - scans (Dmitry Ivanov, Tom Lane) - - - - This optimization supposed that retrieving all columns of a tuple - is inexpensive, which is true for ordinary Postgres tuples; but it - might not be the case for a custom scan provider. - - - - - - Use the correct sub-expression when applying a FOR ALL - row-level-security policy (Stephen Frost) - - - - In some cases the WITH CHECK restriction would be applied - when the USING restriction is more appropriate. - - - - - - Ensure parsing of queries in extension scripts sees the results of - immediately-preceding DDL (Julien Rouhaud, Tom Lane) - - - - Due to lack of a cache flush step between commands in an extension - script file, non-utility queries might not see the effects of an - immediately preceding catalog change, such as ALTER TABLE - ... RENAME. - - - - - - Skip tablespace privilege checks when ALTER TABLE ... ALTER - COLUMN TYPE rebuilds an existing index (Noah Misch) - - - - The command failed if the calling user did not currently have - CREATE privilege for the tablespace containing the index. - That behavior seems unhelpful, so skip the check, allowing the - index to be rebuilt where it is. - - - - - - Fix ALTER TABLE ... VALIDATE CONSTRAINT to not recurse - to child tables when the constraint is marked NO INHERIT - (Amit Langote) - - - - This fix prevents unwanted constraint does not exist failures - when no matching constraint is present in the child tables. - - - - - - Avoid dangling pointer in COPY ... TO when row-level - security is active for the source table (Tom Lane) - - - - Usually this had no ill effects, but sometimes it would cause - unexpected errors or crashes. - - - - - - Avoid accessing an already-closed relcache entry in CLUSTER - and VACUUM FULL (Tom Lane) - - - - With some bad luck, this could lead to indexes on the target - relation getting rebuilt with the wrong persistence setting. - - - - - - Fix VACUUM to account properly for pages that could not - be scanned due to conflicting page pins (Andrew Gierth) - - - - This tended to lead to underestimation of the number of tuples in - the table. In the worst case of a small heavily-contended - table, VACUUM could incorrectly report that the table - contained no tuples, leading to very bad planning choices. - - - - - - Ensure that bulk-tuple-transfer loops within a hash join are - interruptible by query cancel requests (Tom Lane, Thomas Munro) - - - - - - Fix integer-overflow problems in interval comparison (Kyotaro - Horiguchi, Tom Lane) - - - - The comparison operators for type interval could yield wrong - answers for intervals larger than about 296000 years. Indexes on - columns containing such large values should be reindexed, since they - may be corrupt. - - - - - - Fix cursor_to_xml() to produce valid output - with tableforest = false - (Thomas Munro, Peter Eisentraut) - - - - Previously it failed to produce a wrapping <table> - element. - - - - - - Fix roundoff problems in float8_timestamptz() - and make_interval() (Tom Lane) - - - - These functions truncated, rather than rounded, when converting a - floating-point value to integer microseconds; that could cause - unexpectedly off-by-one results. - - - - - - Fix pg_get_object_address() to handle members of operator - families correctly (Álvaro Herrera) - - - - - - Improve performance of pg_timezone_names view - (Tom Lane, David Rowley) - - - - - - Reduce memory management overhead for contexts containing many large - blocks (Tom Lane) - - - - - - Fix sloppy handling of corner-case errors from lseek() - and close() (Tom Lane) - - - - Neither of these system calls are likely to fail in typical situations, - but if they did, fd.c could get quite confused. - - - - - - Fix incorrect check for whether postmaster is running as a Windows - service (Michael Paquier) - - - - This could result in attempting to write to the event log when that - isn't accessible, so that no logging happens at all. - - - - - - Fix ecpg to support COMMIT PREPARED - and ROLLBACK PREPARED (Masahiko Sawada) - - - - - - Fix a double-free error when processing dollar-quoted string literals - in ecpg (Michael Meskes) - - - - - - In pg_dump, fix incorrect schema and owner marking for - comments and security labels of some types of database objects - (Giuseppe Broccolo, Tom Lane) - - - - In simple cases this caused no ill effects; but for example, a - schema-selective restore might omit comments it should include, because - they were not marked as belonging to the schema of their associated - object. - - - - - - Avoid emitting an invalid list file in pg_restore -l - when SQL object names contain newlines (Tom Lane) - - - - Replace newlines by spaces, which is sufficient to make the output - valid for pg_restore -L's purposes. - - - - - - Fix pg_upgrade to transfer comments and security labels - attached to large objects (blobs) (Stephen Frost) - - - - Previously, blobs were correctly transferred to the new database, but - any comments or security labels attached to them were lost. - - - - - - Improve error handling - in contrib/adminpack's pg_file_write() - function (Noah Misch) - - - - Notably, it failed to detect errors reported - by fclose(). - - - - - - In contrib/dblink, avoid leaking the previous unnamed - connection when establishing a new unnamed connection (Joe Conway) - - - - - - Fix contrib/pg_trgm's extraction of trigrams from regular - expressions (Tom Lane) - - - - In some cases it would produce a broken data structure that could never - match anything, leading to GIN or GiST indexscans that use a trigram - index not finding any matches to the regular expression. - - - - - - - In contrib/postgres_fdw, - transmit query cancellation requests to the remote server - (Michael Paquier, Etsuro Fujita) - - - - Previously, a local query cancellation request did not cause an - already-sent remote query to terminate early. This is a back-patch - of work originally done for 9.6. - - - - - - Support Tcl 8.6 in MSVC builds (Álvaro Herrera) - - - - - - Sync our copy of the timezone library with IANA release tzcode2017b - (Tom Lane) - - - - This fixes a bug affecting some DST transitions in January 2038. - - - - - - Update time zone data files to tzdata release 2017b - for DST law changes in Chile, Haiti, and Mongolia, plus historical - corrections for Ecuador, Kazakhstan, Liberia, and Spain. - Switch to numeric abbreviations for numerous time zones in South - America, the Pacific and Indian oceans, and some Asian and Middle - Eastern countries. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - - - Use correct daylight-savings rules for POSIX-style time zone names - in MSVC builds (David Rowley) - - - - The Microsoft MSVC build scripts neglected to install - the posixrules file in the timezone directory tree. - This resulted in the timezone code falling back to its built-in - rule about what DST behavior to assume for a POSIX-style time zone - name. For historical reasons that still corresponds to the DST rules - the USA was using before 2007 (i.e., change on first Sunday in April - and last Sunday in October). With this fix, a POSIX-style zone name - will use the current and historical DST transition dates of - the US/Eastern zone. If you don't want that, remove - the posixrules file, or replace it with a copy of some - other zone file (see ). Note that - due to caching, you may need to restart the server to get such changes - to take effect. - - - - - - - - - - Release 9.5.6 - - - Release date: - 2017-02-09 - - - - This release contains a variety of fixes from 9.5.5. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.6 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted indexes. - - - - Also, if you are upgrading from a version earlier than 9.5.5, - see . - - - - - Changes - - - - - - Fix a race condition that could cause indexes built - with CREATE INDEX CONCURRENTLY to be corrupt - (Pavan Deolasee, Tom Lane) - - - - If CREATE INDEX CONCURRENTLY was used to build an index - that depends on a column not previously indexed, then rows - updated by transactions that ran concurrently with - the CREATE INDEX command could have received incorrect - index entries. If you suspect this may have happened, the most - reliable solution is to rebuild affected indexes after installing - this update. - - - - - - Ensure that the special snapshot used for catalog scans is not - invalidated by premature data pruning (Tom Lane) - - - - Backends failed to account for this snapshot when advertising their - oldest xmin, potentially allowing concurrent vacuuming operations to - remove data that was still needed. This led to transient failures - along the lines of cache lookup failed for relation 1255. - - - - - - Fix incorrect WAL logging for BRIN indexes (Kuntal Ghosh) - - - - The WAL record emitted for a BRIN revmap page when moving an - index tuple to a different page was incorrect. Replay would make the - related portion of the index useless, forcing it to be recomputed. - - - - - - Unconditionally WAL-log creation of the init fork for an - unlogged table (Michael Paquier) - - - - Previously, this was skipped when - = minimal, but actually it's necessary even in that case - to ensure that the unlogged table is properly reset to empty after a - crash. - - - - - - - Reduce interlocking on standby servers during the replay of btree - index vacuuming operations (Simon Riggs) - - - - This change avoids substantial replication delays that sometimes - occurred while replaying such operations. - - - - - - If the stats collector dies during hot standby, restart it (Takayuki - Tsunakawa) - - - - - - Ensure that hot standby feedback works correctly when it's enabled at - standby server start (Ants Aasma, Craig Ringer) - - - - - - Check for interrupts while hot standby is waiting for a conflicting - query (Simon Riggs) - - - - - - Avoid constantly respawning the autovacuum launcher in a corner case - (Amit Khandekar) - - - - This fix avoids problems when autovacuum is nominally off and there - are some tables that require freezing, but all such tables are - already being processed by autovacuum workers. - - - - - - Fix check for when an extension member object can be dropped (Tom Lane) - - - - Extension upgrade scripts should be able to drop member objects, - but this was disallowed for serial-column sequences, and possibly - other cases. - - - - - - Make sure ALTER TABLE preserves index tablespace - assignments when rebuilding indexes (Tom Lane, Michael Paquier) - - - - Previously, non-default settings - of could result in broken - indexes. - - - - - - Fix incorrect updating of trigger function properties when changing a - foreign-key constraint's deferrability properties with ALTER - TABLE ... ALTER CONSTRAINT (Tom Lane) - - - - This led to odd failures during subsequent exercise of the foreign - key, as the triggers were fired at the wrong times. - - - - - - Prevent dropping a foreign-key constraint if there are pending - trigger events for the referenced relation (Tom Lane) - - - - This avoids could not find trigger NNN - or relation NNN has no triggers errors. - - - - - - Fix ALTER TABLE ... SET DATA TYPE ... USING when child - table has different column ordering than the parent - (Álvaro Herrera) - - - - Failure to adjust the column numbering in the USING - expression led to errors, - typically attribute N has wrong type. - - - - - - Fix processing of OID column when a table with OIDs is associated to - a parent with OIDs via ALTER TABLE ... INHERIT (Amit - Langote) - - - - The OID column should be treated the same as regular user columns in - this case, but it wasn't, leading to odd behavior in later - inheritance changes. - - - - - - Fix CREATE OR REPLACE VIEW to update the view query - before attempting to apply the new view options (Dean Rasheed) - - - - Previously the command would fail if the new options were - inconsistent with the old view definition. - - - - - - Report correct object identity during ALTER TEXT SEARCH - CONFIGURATION (Artur Zakirov) - - - - The wrong catalog OID was reported to extensions such as logical - decoding. - - - - - - Fix commit timestamp mechanism to not fail when queried about - the special XIDs FrozenTransactionId - and BootstrapTransactionId (Craig Ringer) - - - - - - - Check for serializability conflicts before reporting - constraint-violation failures (Thomas Munro) - - - - When using serializable transaction isolation, it is desirable - that any error due to concurrent transactions should manifest - as a serialization failure, thereby cueing the application that - a retry might succeed. Unfortunately, this does not reliably - happen for duplicate-key failures caused by concurrent insertions. - This change ensures that such an error will be reported as a - serialization error if the application explicitly checked for - the presence of a conflicting key (and did not find it) earlier - in the transaction. - - - - - - Fix incorrect use of view reloptions as regular table reloptions (Tom - Lane) - - - - The symptom was spurious ON CONFLICT is not supported on table - ... used as a catalog table errors when the target - of INSERT ... ON CONFLICT is a view with cascade option. - - - - - - Fix incorrect target lists can have at most N - entries complaint when using ON CONFLICT with - wide tables (Tom Lane) - - - - - - Prevent multicolumn expansion of foo.* in - an UPDATE source expression (Tom Lane) - - - - This led to UPDATE target count mismatch --- internal - error. Now the syntax is understood as a whole-row variable, - as it would be in other contexts. - - - - - - Ensure that column typmods are determined accurately for - multi-row VALUES constructs (Tom Lane) - - - - This fixes problems occurring when the first value in a column has a - determinable typmod (e.g., length for a varchar value) but - later values don't share the same limit. - - - - - - Throw error for an unfinished Unicode surrogate pair at the end of a - Unicode string (Tom Lane) - - - - Normally, a Unicode surrogate leading character must be followed by a - Unicode surrogate trailing character, but the check for this was - missed if the leading character was the last character in a Unicode - string literal (U&'...') or Unicode identifier - (U&"..."). - - - - - - Ensure that a purely negative text search query, such - as !foo, matches empty tsvectors (Tom Dunstan) - - - - Such matches were found by GIN index searches, but not by sequential - scans or GiST index searches. - - - - - - Prevent crash when ts_rewrite() replaces a non-top-level - subtree with an empty query (Artur Zakirov) - - - - - - Fix performance problems in ts_rewrite() (Tom Lane) - - - - - - Fix ts_rewrite()'s handling of nested NOT operators - (Tom Lane) - - - - - - Improve speed of user-defined aggregates that - use array_append() as transition function (Tom Lane) - - - - - - Fix array_fill() to handle empty arrays properly (Tom Lane) - - - - - - Fix possible crash in array_position() - or array_positions() when processing arrays of records - (Junseok Yang) - - - - - - Fix one-byte buffer overrun in quote_literal_cstr() - (Heikki Linnakangas) - - - - The overrun occurred only if the input consisted entirely of single - quotes and/or backslashes. - - - - - - Prevent multiple calls of pg_start_backup() - and pg_stop_backup() from running concurrently (Michael - Paquier) - - - - This avoids an assertion failure, and possibly worse things, if - someone tries to run these functions in parallel. - - - - - - Disable transform that attempted to remove no-op AT TIME - ZONE conversions (Tom Lane) - - - - This resulted in wrong answers when the simplified expression was - used in an index condition. - - - - - - Avoid discarding interval-to-interval casts - that aren't really no-ops (Tom Lane) - - - - In some cases, a cast that should result in zeroing out - low-order interval fields was mistakenly deemed to be a - no-op and discarded. An example is that casting from INTERVAL - MONTH to INTERVAL YEAR failed to clear the months field. - - - - - - Fix bugs in transmitting GUC parameter values to parallel workers - (Michael Paquier, Tom Lane) - - - - - - Ensure that cached plans are invalidated by changes in foreign-table - options (Amit Langote, Etsuro Fujita, Ashutosh Bapat) - - - - - - Fix pg_dump to dump user-defined casts and transforms - that use built-in functions (Stephen Frost) - - - - - - Fix pg_restore with - to behave more sanely if an archive contains - unrecognized DROP commands (Tom Lane) - - - - This doesn't fix any live bug, but it may improve the behavior in - future if pg_restore is used with an archive - generated by a later pg_dump version. - - - - - - Fix pg_basebackup's rate limiting in the presence of - slow I/O (Antonin Houska) - - - - If disk I/O was transiently much slower than the specified rate - limit, the calculation overflowed, effectively disabling the rate - limit for the rest of the run. - - - - - - Fix pg_basebackup's handling of - symlinked pg_stat_tmp and pg_replslot - subdirectories (Magnus Hagander, Michael Paquier) - - - - - - Fix possible pg_basebackup failure on standby - server when including WAL files (Amit Kapila, Robert Haas) - - - - - - Fix possible mishandling of expanded arrays in domain check - constraints and CASE execution (Tom Lane) - - - - It was possible for a PL/pgSQL function invoked in these contexts to - modify or even delete an array value that needs to be preserved for - additional operations. - - - - - - Fix nested uses of PL/pgSQL functions in contexts such as domain - check constraints evaluated during assignment to a PL/pgSQL variable - (Tom Lane) - - - - - - Ensure that the Python exception objects we create for PL/Python are - properly reference-counted (Rafa de la Torre, Tom Lane) - - - - This avoids failures if the objects are used after a Python garbage - collection cycle has occurred. - - - - - - Fix PL/Tcl to support triggers on tables that have .tupno - as a column name (Tom Lane) - - - - This matches the (previously undocumented) behavior of - PL/Tcl's spi_exec and spi_execp commands, - namely that a magic .tupno column is inserted only if - there isn't a real column named that. - - - - - - Allow DOS-style line endings in ~/.pgpass files, - even on Unix (Vik Fearing) - - - - This change simplifies use of the same password file across Unix and - Windows machines. - - - - - - Fix one-byte buffer overrun if ecpg is given a file - name that ends with a dot (Takayuki Tsunakawa) - - - - - - Fix psql's tab completion for ALTER DEFAULT - PRIVILEGES (Gilles Darold, Stephen Frost) - - - - - - In psql, treat an empty or all-blank setting of - the PAGER environment variable as meaning no - pager (Tom Lane) - - - - Previously, such a setting caused output intended for the pager to - vanish entirely. - - - - - - Improve contrib/dblink's reporting of - low-level libpq errors, such as out-of-memory - (Joe Conway) - - - - - - Teach contrib/dblink to ignore irrelevant server options - when it uses a contrib/postgres_fdw foreign server as - the source of connection options (Corey Huinker) - - - - Previously, if the foreign server object had options that were not - also libpq connection options, an error occurred. - - - - - - Fix portability problems in contrib/pageinspect's - functions for GIN indexes (Peter Eisentraut, Tom Lane) - - - - - - On Windows, ensure that environment variable changes are propagated - to DLLs built with debug options (Christian Ullrich) - - - - - - Sync our copy of the timezone library with IANA release tzcode2016j - (Tom Lane) - - - - This fixes various issues, most notably that timezone data - installation failed if the target directory didn't support hard - links. - - - - - - Update time zone data files to tzdata release 2016j - for DST law changes in northern Cyprus (adding a new zone - Asia/Famagusta), Russia (adding a new zone Europe/Saratov), Tonga, - and Antarctica/Casey. - Historical corrections for Italy, Kazakhstan, Malta, and Palestine. - Switch to preferring numeric zone abbreviations for Tonga. - - - - - - - - - - Release 9.5.5 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.5.4. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.5 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted free space maps. - - - - Also, if you are upgrading from a version earlier than 9.5.2, - see . - - - - - Changes - - - - - - Fix WAL-logging of truncation of relation free space maps and - visibility maps (Pavan Deolasee, Heikki Linnakangas) - - - - It was possible for these files to not be correctly restored during - crash recovery, or to be written incorrectly on a standby server. - Bogus entries in a free space map could lead to attempts to access - pages that have been truncated away from the relation itself, typically - producing errors like could not read block XXX: - read only 0 of 8192 bytes. Checksum failures in the - visibility map are also possible, if checksumming is enabled. - - - - Procedures for determining whether there is a problem and repairing it - if so are discussed at - . - - - - - - - Fix incorrect creation of GIN index WAL records on big-endian machines - (Tom Lane) - - - - The typical symptom was unexpected GIN leaf action errors - during WAL replay. - - - - - - - Fix SELECT FOR UPDATE/SHARE to correctly lock tuples that - have been updated by a subsequently-aborted transaction - (Álvaro Herrera) - - - - In 9.5 and later, the SELECT would sometimes fail to - return such tuples at all. A failure has not been proven to occur in - earlier releases, but might be possible with concurrent updates. - - - - - - - Fix EvalPlanQual rechecks involving CTE scans (Tom Lane) - - - - The recheck would always see the CTE as returning no rows, typically - leading to failure to update rows that were recently updated. - - - - - - - Fix deletion of speculatively inserted TOAST tuples when backing out - of INSERT ... ON CONFLICT (Oskari Saarenmaa) - - - - In the race condition where two transactions try to insert conflicting - tuples at about the same time, the loser would fail with - an attempted to delete invisible tuple error if its - insertion included any TOAST'ed fields. - - - - - - Don't throw serialization errors for self-conflicting insertions - in INSERT ... ON CONFLICT (Thomas Munro, Peter Geoghegan) - - - - - - - Fix improper repetition of previous results from hashed aggregation in - a subquery (Andrew Gierth) - - - - The test to see if we can reuse a previously-computed hash table of - the aggregate state values neglected the possibility of an outer query - reference appearing in an aggregate argument expression. A change in - the value of such a reference should lead to recalculating the hash - table, but did not. - - - - - - - Fix query-lifespan memory leak in a bulk UPDATE on a table - with a PRIMARY KEY or REPLICA IDENTITY index - (Tom Lane) - - - - - - Fix COPY with a column name list from a table that has - row-level security enabled (Adam Brightwell) - - - - - - Fix EXPLAIN to emit valid XML when - is on (Markus Winand) - - - - Previously the XML output-format option produced syntactically invalid - tags such as <I/O-Read-Time>. That is now - rendered as <I-O-Read-Time>. - - - - - - - Suppress printing of zeroes for unmeasured times - in EXPLAIN (Maksim Milyutin) - - - - Certain option combinations resulted in printing zero values for times - that actually aren't ever measured in that combination. Our general - policy in EXPLAIN is not to print such fields at all, so - do that consistently in all cases. - - - - - - Fix statistics update for TRUNCATE in a prepared - transaction (Stas Kelvich) - - - - - - - Fix timeout length when VACUUM is waiting for exclusive - table lock so that it can truncate the table (Simon Riggs) - - - - The timeout was meant to be 50 milliseconds, but it was actually only - 50 microseconds, causing VACUUM to give up on truncation - much more easily than intended. Set it to the intended value. - - - - - - Fix bugs in merging inherited CHECK constraints while - creating or altering a table (Tom Lane, Amit Langote) - - - - Allow identical CHECK constraints to be added to a parent - and child table in either order. Prevent merging of a valid - constraint from the parent table with a NOT VALID - constraint on the child. Likewise, prevent merging of a NO - INHERIT child constraint with an inherited constraint. - - - - - - Show a sensible value - in pg_settings.unit - for min_wal_size and max_wal_size (Tom Lane) - - - - - - - Remove artificial restrictions on the values accepted - by numeric_in() and numeric_recv() - (Tom Lane) - - - - We allow numeric values up to the limit of the storage format (more - than 1e100000), so it seems fairly pointless - that numeric_in() rejected scientific-notation exponents - above 1000. Likewise, it was silly for numeric_recv() to - reject more than 1000 digits in an input value. - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - Preserve commit timestamps across server restart - (Julien Rouhaud, Craig Ringer) - - - - With turned on, old - commit timestamps became inaccessible after a clean server restart. - - - - - - Fix logical WAL decoding to work properly when a subtransaction's WAL - output is large enough to spill to disk (Andres Freund) - - - - - - - Fix possible sorting error when aborting use of abbreviated keys - (Peter Geoghegan) - - - - In the worst case, this could result in a corrupt btree index, which - would need to be rebuilt using REINDEX. However, the - situation is believed to be rare. - - - - - - - Fix file descriptor leakage when truncating a temporary relation of - more than 1GB (Andres Freund) - - - - - - - Disallow starting a standalone backend with standby_mode - turned on (Michael Paquier) - - - - This can't do anything useful, since there will be no WAL receiver - process to fetch more WAL data; and it could result in misbehavior - in code that wasn't designed with this situation in mind. - - - - - - - Properly initialize replication slot state when recycling a - previously-used slot (Michael Paquier) - - - - This failure to reset all of the fields of the slot could - prevent VACUUM from removing dead tuples. - - - - - - Round shared-memory allocation request to a multiple of the actual - huge page size when attempting to use huge pages on Linux (Tom Lane) - - - - This avoids possible failures during munmap() on systems - with atypical default huge page sizes. Except in crash-recovery - cases, there were no ill effects other than a log message. - - - - - - - Use a more random value for the dynamic shared memory control - segment's ID (Robert Haas, Tom Lane) - - - - Previously, the same value would be chosen every time, because it was - derived from random() but srandom() had not - yet been called. While relatively harmless, this was not the intended - behavior. - - - - - - - On Windows, retry creation of the dynamic shared memory control - segment after an access-denied error (Kyotaro Horiguchi, Amit Kapila) - - - - Windows sometimes returns ERROR_ACCESS_DENIED rather - than ERROR_ALREADY_EXISTS when there is an existing - segment. This led to postmaster startup failure due to believing that - the former was an unrecoverable error. - - - - - - - Fix PL/pgSQL to not misbehave with parameters and - local variables of type int2vector or oidvector - (Tom Lane) - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - - Make ecpg's and - options work consistently with our other executables (Haribabu Kommi) - - - - - - - Fix pgbench's calculation of average latency - (Fabien Coelho) - - - - The calculation was incorrect when there were \sleep - commands in the script, or when the test duration was specified in - number of transactions rather than total time. - - - - - - In pg_upgrade, check library loadability in name order - (Tom Lane) - - - - This is a workaround to deal with cross-extension dependencies from - language transform modules to their base language and data type - modules. - - - - - - - In pg_dump, never dump range constructor functions - (Tom Lane) - - - - This oversight led to pg_upgrade failures with - extensions containing range types, due to duplicate creation of the - constructor functions. - - - - - - - In pg_dump with , - suppress TABLESPACE clause of CREATE DATABASE - if is specified (Tom Lane) - - - - - - - Make pg_receivexlog work correctly - with without slots (Gabriele Bartolini) - - - - - - Disallow specifying both - and options to pg_rewind - (Michael Banck) - - - - - - Make pg_rewind turn off synchronous_commit - in its session on the source server (Michael Banck, Michael Paquier) - - - - This allows pg_rewind to work even when the source - server is using synchronous replication that is not working for some - reason. - - - - - - In pg_xlogdump, retry opening new WAL segments when - using option (Magnus Hagander) - - - - This allows for a possible delay in the server's creation of the next - segment. - - - - - - - Fix pg_xlogdump to cope with a WAL file that begins - with a continuation record spanning more than one page (Pavan - Deolasee) - - - - - - - Fix contrib/pg_buffercache to work - when shared_buffers exceeds 256GB (KaiGai Kohei) - - - - - - - Fix contrib/intarray/bench/bench.pl to print the results - of the EXPLAIN it does when given the option - (Daniel Gustafsson) - - - - - - - Support OpenSSL 1.1.0 (Heikki Linnakangas) - - - - - - - Install TAP test infrastructure so that it's available for extension - testing (Craig Ringer) - - - - When PostgreSQL has been configured - with , make install will now - install the Perl support files for TAP testing where PGXS can find - them. This allows non-core extensions to - use $(prove_check) without extra tests. - - - - - - - In MSVC builds, include pg_recvlogical in a - client-only installation (MauMau) - - - - - - - Update Windows time zone mapping to recognize some time zone names - added in recent Windows versions (Michael Paquier) - - - - - - - Prevent failure of obsolete dynamic time zone abbreviations (Tom Lane) - - - - If a dynamic time zone abbreviation does not match any entry in the - referenced time zone, treat it as equivalent to the time zone name. - This avoids unexpected failures when IANA removes abbreviations from - their time zone database, as they did in tzdata - release 2016f and seem likely to do again in the future. The - consequences were not limited to not recognizing the individual - abbreviation; any mismatch caused - the pg_timezone_abbrevs view to fail altogether. - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.5.4 - - - Release date: - 2016-08-11 - - - - This release contains a variety of fixes from 9.5.3. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.4 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you are upgrading from a version earlier than 9.5.2, - see . - - - - - Changes - - - - - - - Fix possible mis-evaluation of - nested CASE-WHEN expressions (Heikki - Linnakangas, Michael Paquier, Tom Lane) - - - - A CASE expression appearing within the test value - subexpression of another CASE could become confused about - whether its own test value was null or not. Also, inlining of a SQL - function implementing the equality operator used by - a CASE expression could result in passing the wrong test - value to functions called within a CASE expression in the - SQL function's body. If the test values were of different data - types, a crash might result; moreover such situations could be abused - to allow disclosure of portions of server memory. (CVE-2016-5423) - - - - - - - Fix client programs' handling of special characters in database and - role names (Noah Misch, Nathan Bossart, Michael Paquier) - - - - Numerous places in vacuumdb and other client programs - could become confused by database and role names containing double - quotes or backslashes. Tighten up quoting rules to make that safe. - Also, ensure that when a conninfo string is used as a database name - parameter to these programs, it is correctly treated as such throughout. - - - - Fix handling of paired double quotes - in psql's \connect - and \password commands to match the documentation. - - - - Introduce a new option - in psql's \connect command to allow - explicit control of whether to re-use connection parameters from a - previous connection. (Without this, the choice is based on whether - the database name looks like a conninfo string, as before.) This - allows secure handling of database names containing special - characters in pg_dumpall scripts. - - - - pg_dumpall now refuses to deal with database and role - names containing carriage returns or newlines, as it seems impractical - to quote those characters safely on Windows. In future we may reject - such names on the server side, but that step has not been taken yet. - - - - These are considered security fixes because crafted object names - containing special characters could have been used to execute - commands with superuser privileges the next time a superuser - executes pg_dumpall or other routine maintenance - operations. (CVE-2016-5424) - - - - - - - Fix corner-case misbehaviors for IS NULL/IS NOT - NULL applied to nested composite values (Andrew Gierth, Tom Lane) - - - - The SQL standard specifies that IS NULL should return - TRUE for a row of all null values (thus ROW(NULL,NULL) IS - NULL yields TRUE), but this is not meant to apply recursively - (thus ROW(NULL, ROW(NULL,NULL)) IS NULL yields FALSE). - The core executor got this right, but certain planner optimizations - treated the test as recursive (thus producing TRUE in both cases), - and contrib/postgres_fdw could produce remote queries - that misbehaved similarly. - - - - - - - Fix unrecognized node type error for INSERT ... ON - CONFLICT within a recursive CTE (a WITH item) (Peter - Geoghegan) - - - - - - - Fix INSERT ... ON CONFLICT to successfully match index - expressions or index predicates that are simplified during the - planner's expression preprocessing phase (Tom Lane) - - - - - - - Correctly handle violations of exclusion constraints that apply to - the target table of an INSERT ... ON CONFLICT command, - but are not one of the selected arbiter indexes (Tom Lane) - - - - Such a case should raise a normal constraint-violation error, but it - got into an infinite loop instead. - - - - - - - Fix INSERT ... ON CONFLICT to not fail if the target - table has a unique index on OID (Tom Lane) - - - - - - - Make the inet and cidr data types properly reject - IPv6 addresses with too many colon-separated fields (Tom Lane) - - - - - - - Prevent crash in close_ps() - (the point ## lseg operator) - for NaN input coordinates (Tom Lane) - - - - Make it return NULL instead of crashing. - - - - - - - Avoid possible crash in pg_get_expr() when inconsistent - values are passed to it (Michael Paquier, Thomas Munro) - - - - - - - Fix several one-byte buffer over-reads in to_number() - (Peter Eisentraut) - - - - In several cases the to_number() function would read one - more character than it should from the input string. There is a - small chance of a crash, if the input happens to be adjacent to the - end of memory. - - - - - - - Do not run the planner on the query contained in CREATE - MATERIALIZED VIEW or CREATE TABLE AS - when WITH NO DATA is specified (Michael Paquier, - Tom Lane) - - - - This avoids some unnecessary failure conditions, for example if a - stable function invoked by the materialized view depends on a table - that doesn't exist yet. - - - - - - - Avoid unsafe intermediate state during expensive paths - through heap_update() (Masahiko Sawada, Andres Freund) - - - - Previously, these cases locked the target tuple (by setting its XMAX) - but did not WAL-log that action, thus risking data integrity problems - if the page were spilled to disk and then a database crash occurred - before the tuple update could be completed. - - - - - - - Fix hint bit update during WAL replay of row locking operations - (Andres Freund) - - - - The only known consequence of this problem is that row locks held by - a prepared, but uncommitted, transaction might fail to be enforced - after a crash and restart. - - - - - - - Avoid unnecessary could not serialize access errors when - acquiring FOR KEY SHARE row locks in serializable mode - (Álvaro Herrera) - - - - - - - Make sure expanded datums returned by a plan node are - read-only (Tom Lane) - - - - This avoids failures in some cases where the result of a lower plan - node is referenced in multiple places in upper nodes. So far as - core PostgreSQL is concerned, only array values - returned by PL/pgSQL functions are at risk; but extensions might - use expanded datums for other things. - - - - - - - Avoid crash in postgres -C when the specified variable - has a null string value (Michael Paquier) - - - - - - - Prevent unintended waits for the receiver in WAL sender processes - (Kyotaro Horiguchi) - - - - - - - Fix possible loss of large subtransactions in logical decoding - (Petru-Florin Mihancea) - - - - - - - Fix failure of logical decoding when a subtransaction contains no - actual changes (Marko Tiikkaja, Andrew Gierth) - - - - - - - Ensure that backends see up-to-date statistics for shared catalogs - (Tom Lane) - - - - The statistics collector failed to update the statistics file for - shared catalogs after a request from a regular backend. This problem - was partially masked because the autovacuum launcher regularly makes - requests that did cause such updates; however, it became obvious with - autovacuum disabled. - - - - - - - Avoid redundant writes of the statistics files when multiple - backends request updates close together (Tom Lane, Tomas Vondra) - - - - - - - Avoid consuming a transaction ID during VACUUM - (Alexander Korotkov) - - - - Some cases in VACUUM unnecessarily caused an XID to be - assigned to the current transaction. Normally this is negligible, - but if one is up against the XID wraparound limit, consuming more - XIDs during anti-wraparound vacuums is a very bad thing. - - - - - - - Prevent possible failure when vacuuming multixact IDs in an - installation that has been pg_upgrade'd from pre-9.3 (Andrew Gierth, - Álvaro Herrera) - - - - The usual symptom of this bug is errors - like MultiXactId NNN has not been created - yet -- apparent wraparound. - - - - - - - When a manual ANALYZE specifies a column list, don't - reset the table's changes_since_analyze counter - (Tom Lane) - - - - If we're only analyzing some columns, we should not prevent routine - auto-analyze from happening for the other columns. - - - - - - - Fix ANALYZE's overestimation of n_distinct - for a unique or nearly-unique column with many null entries (Tom - Lane) - - - - The nulls could get counted as though they were themselves distinct - values, leading to serious planner misestimates in some types of - queries. - - - - - - - Prevent autovacuum from starting multiple workers for the same shared - catalog (Álvaro Herrera) - - - - Normally this isn't much of a problem because the vacuum doesn't take - long anyway; but in the case of a severely bloated catalog, it could - result in all but one worker uselessly waiting instead of doing - useful work on other tables. - - - - - - - Fix bug in b-tree mark/restore processing (Kevin Grittner) - - - - This error could lead to incorrect join results or assertion failures - in a merge join whose inner source node is a b-tree indexscan. - - - - - - - Avoid duplicate buffer lock release when abandoning a b-tree index - page deletion attempt (Tom Lane) - - - - This mistake prevented VACUUM from completing in some - cases involving corrupt b-tree indexes. - - - - - - - Fix building of large (bigger than shared_buffers) - hash indexes (Tom Lane) - - - - The code path used for large indexes contained a bug causing - incorrect hash values to be inserted into the index, so that - subsequent index searches always failed, except for tuples inserted - into the index after the initial build. - - - - - - - Prevent infinite loop in GiST index build for geometric columns - containing NaN component values (Tom Lane) - - - - - - - Fix possible crash during a nearest-neighbor (ORDER BY - distance) indexscan on a contrib/btree_gist index on - an interval column (Peter Geoghegan) - - - - - - - Fix PANIC: failed to add BRIN tuple error when attempting - to update a BRIN index entry (Álvaro Herrera) - - - - - - - Fix possible crash during background worker shutdown (Dmitry Ivanov) - - - - - - - Fix PL/pgSQL's handling of the INTO clause - within IMPORT FOREIGN SCHEMA commands (Tom Lane) - - - - - - - Fix contrib/btree_gin to handle the smallest - possible bigint value correctly (Peter Eisentraut) - - - - - - - Teach libpq to correctly decode server version from future servers - (Peter Eisentraut) - - - - It's planned to switch to two-part instead of three-part server - version numbers for releases after 9.6. Make sure - that PQserverVersion() returns the correct value for - such cases. - - - - - - - Fix ecpg's code for unsigned long long - array elements (Michael Meskes) - - - - - - - In pg_dump with both and - options, avoid emitting an unwanted CREATE SCHEMA public - command (David Johnston, Tom Lane) - - - - - - - Improve handling of SIGTERM/control-C in - parallel pg_dump and pg_restore (Tom - Lane) - - - - Make sure that the worker processes will exit promptly, and also arrange - to send query-cancel requests to the connected backends, in case they - are doing something long-running such as a CREATE INDEX. - - - - - - - Fix error reporting in parallel pg_dump - and pg_restore (Tom Lane) - - - - Previously, errors reported by pg_dump - or pg_restore worker processes might never make it to - the user's console, because the messages went through the master - process, and there were various deadlock scenarios that would prevent - the master process from passing on the messages. Instead, just print - everything to stderr. In some cases this will result in - duplicate messages (for instance, if all the workers report a server - shutdown), but that seems better than no message. - - - - - - - Ensure that parallel pg_dump - or pg_restore on Windows will shut down properly - after an error (Kyotaro Horiguchi) - - - - Previously, it would report the error, but then just sit until - manually stopped by the user. - - - - - - - Make parallel pg_dump fail cleanly when run against a - standby server (Magnus Hagander) - - - - This usage is not supported - unless is specified, but the - error was not handled very well. - - - - - - - Make pg_dump behave better when built without zlib - support (Kyotaro Horiguchi) - - - - It didn't work right for parallel dumps, and emitted some rather - pointless warnings in other cases. - - - - - - - Make pg_basebackup accept -Z 0 as - specifying no compression (Fujii Masao) - - - - - - - Fix makefiles' rule for building AIX shared libraries to be safe for - parallel make (Noah Misch) - - - - - - - Fix TAP tests and MSVC scripts to work when build directory's path - name contains spaces (Michael Paquier, Kyotaro Horiguchi) - - - - - - - Be more predictable about reporting statement timeout - versus lock timeout (Tom Lane) - - - - On heavily loaded machines, the regression tests sometimes failed due - to reporting lock timeout even though the statement timeout - should have occurred first. - - - - - - - Make regression tests safe for Danish and Welsh locales (Jeff Janes, - Tom Lane) - - - - Change some test data that triggered the unusual sorting rules of - these locales. - - - - - - - Update our copy of the timezone code to match - IANA's tzcode release 2016c (Tom Lane) - - - - This is needed to cope with anticipated future changes in the time - zone data files. It also fixes some corner-case bugs in coping with - unusual time zones. - - - - - - - Update time zone data files to tzdata release 2016f - for DST law changes in Kemerovo and Novosibirsk, plus historical - corrections for Azerbaijan, Belarus, and Morocco. - - - - - - - - - - Release 9.5.3 - - - Release date: - 2016-05-12 - - - - This release contains a variety of fixes from 9.5.2. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.3 - - - A dump/restore is not required for those running 9.5.X. - - - - However, if you are upgrading from a version earlier than 9.5.2, - see . - - - - - Changes - - - - - - - Clear the OpenSSL error queue before OpenSSL calls, rather than - assuming it's clear already; and make sure we leave it clear - afterwards (Peter Geoghegan, Dave Vitek, Peter Eisentraut) - - - - This change prevents problems when there are multiple connections - using OpenSSL within a single process and not all the code involved - follows the same rules for when to clear the error queue. - Failures have been reported specifically when a client application - uses SSL connections in libpq concurrently with - SSL connections using the PHP, Python, or Ruby wrappers for OpenSSL. - It's possible for similar problems to arise within the server as well, - if an extension module establishes an outgoing SSL connection. - - - - - - - Fix failed to build any N-way joins - planner error with a full join enclosed in the right-hand side of a - left join (Tom Lane) - - - - - - - Fix incorrect handling of equivalence-class tests in multilevel - nestloop plans (Tom Lane) - - - - Given a three-or-more-way equivalence class of variables, such - as X.X = Y.Y = Z.Z, it was possible for the planner to omit - some of the tests needed to enforce that all the variables are actually - equal, leading to join rows being output that didn't satisfy - the WHERE clauses. For various reasons, erroneous plans - were seldom selected in practice, so that this bug has gone undetected - for a long time. - - - - - - - Fix corner-case parser failures occurring - when is turned on - (Tom Lane) - - - - An example is that SELECT (ARRAY[])::text[] gave an error, - though it worked without the parentheses. - - - - - - - Fix query-lifespan memory leak in GIN index scans (Julien Rouhaud) - - - - - - - Fix query-lifespan memory leak and potential index corruption hazard in - GIN index insertion (Tom Lane) - - - - The memory leak would typically not amount to much in simple queries, - but it could be very substantial during a large GIN index build with - high maintenance_work_mem. - - - - - - - Fix possible misbehavior of TH, th, - and Y,YYY format codes in to_timestamp() - (Tom Lane) - - - - These could advance off the end of the input string, causing subsequent - format codes to read garbage. - - - - - - - Fix dumping of rules and views in which the array - argument of a value operator - ANY (array) construct is a sub-SELECT - (Tom Lane) - - - - - - - Disallow newlines in ALTER SYSTEM parameter values - (Tom Lane) - - - - The configuration-file parser doesn't support embedded newlines in - string literals, so we mustn't allow them in values to be inserted - by ALTER SYSTEM. - - - - - - - Fix ALTER TABLE ... REPLICA IDENTITY USING INDEX to - work properly if an index on OID is selected (David Rowley) - - - - - - - Avoid possible misbehavior after failing to remove a tablespace symlink - (Tom Lane) - - - - - - - Fix crash in logical decoding on alignment-picky platforms (Tom Lane, - Andres Freund) - - - - The failure occurred only with a transaction large enough to spill to - disk and a primary-key change within that transaction. - - - - - - - Avoid repeated requests for feedback from receiver while shutting down - walsender (Nick Cleaton) - - - - - - - Make pg_regress use a startup timeout from the - PGCTLTIMEOUT environment variable, if that's set (Tom Lane) - - - - This is for consistency with a behavior recently added - to pg_ctl; it eases automated testing on slow machines. - - - - - - - Fix pg_upgrade to correctly restore extension - membership for operator families containing only one operator class - (Tom Lane) - - - - In such a case, the operator family was restored into the new database, - but it was no longer marked as part of the extension. This had no - immediate ill effects, but would cause later pg_dump - runs to emit output that would cause (harmless) errors on restore. - - - - - - - Fix pg_upgrade to not fail when new-cluster TOAST rules - differ from old (Tom Lane) - - - - pg_upgrade had special-case code to handle the - situation where the new PostgreSQL version thinks that - a table should have a TOAST table while the old version did not. That - code was broken, so remove it, and instead do nothing in such cases; - there seems no reason to believe that we can't get along fine without - a TOAST table if that was okay according to the old version's rules. - - - - - - - Fix atomic operations for PPC when using IBM's XLC compiler (Noah Misch) - - - - - - - Reduce the number of SysV semaphores used by a build configured with - (Tom Lane) - - - - - - - Rename internal function strtoi() - to strtoint() to avoid conflict with a NetBSD library - function (Thomas Munro) - - - - - - - Fix reporting of errors from bind() - and listen() system calls on Windows (Tom Lane) - - - - - - - Reduce verbosity of compiler output when building with Microsoft Visual - Studio (Christian Ullrich) - - - - - - - Support building with Visual Studio 2015 - (Michael Paquier, Petr Jelínek) - - - - Note that builds made with VS2015 will not run on Windows versions - before Windows Vista. - - - - - - - Fix putenv() to work properly with Visual Studio 2013 - (Michael Paquier) - - - - - - - Avoid possibly-unsafe use of Windows' FormatMessage() - function (Christian Ullrich) - - - - Use the FORMAT_MESSAGE_IGNORE_INSERTS flag where - appropriate. No live bug is known to exist here, but it seems like a - good idea to be careful. - - - - - - - Update time zone data files to tzdata release 2016d - for DST law changes in Russia and Venezuela. There are new zone - names Europe/Kirov and Asia/Tomsk to reflect - the fact that these regions now have different time zone histories from - adjacent regions. - - - - - - - - - - Release 9.5.2 - - - Release date: - 2016-03-31 - - - - This release contains a variety of fixes from 9.5.1. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.2 - - - A dump/restore is not required for those running 9.5.X. - - - - However, you may need to REINDEX some indexes after applying - the update, as per the first changelog entry below. - - - - - Changes - - - - - - - - Disable abbreviated keys for string sorting in non-C - locales (Robert Haas) - - - - PostgreSQL 9.5 introduced logic for speeding up - comparisons of string data types by using the standard C library - function strxfrm() as a substitute - for strcoll(). It now emerges that most versions of - glibc (Linux's implementation of the C library) have buggy - implementations of strxfrm() that, in some locales, - can produce string comparison results that do not - match strcoll(). Until this problem can be better - characterized, disable the optimization in all non-C - locales. (C locale is safe since it uses - neither strcoll() nor strxfrm().) - - - - Unfortunately, this problem affects not only sorting but also entry - ordering in B-tree indexes, which means that B-tree indexes - on text, varchar, or char columns may now - be corrupt if they sort according to an affected locale and were - built or modified under PostgreSQL 9.5.0 or 9.5.1. - Users should REINDEX indexes that might be affected. - - - - It is not possible at this time to give an exhaustive list of - known-affected locales. C locale is known safe, and - there is no evidence of trouble in English-based locales such - as en_US, but some other popular locales such - as de_DE are affected in most glibc versions. - - - - - - - - Maintain row-security status properly in cached plans (Stephen Frost) - - - - In a session that performs queries as more than one role, the plan - cache might incorrectly re-use a plan that was generated for another - role ID, thus possibly applying the wrong set of policies when - row-level security (RLS) is in use. - (CVE-2016-2193) - - - - - - - - Add must-be-superuser checks to some - new contrib/pageinspect functions (Andreas Seltenreich) - - - - Most functions in the pageinspect extension that - inspect bytea values disallow calls by non-superusers, - but brin_page_type() and brin_metapage_info() - failed to do so. Passing contrived bytea values to them might - crash the server or disclose a few bytes of server memory. Add the - missing permissions checks to prevent misuse. - (CVE-2016-3065) - - - - - - - - Fix incorrect handling of indexed ROW() comparisons - (Simon Riggs) - - - - Flaws in a minor optimization introduced in 9.5 caused incorrect - results if the ROW() comparison matches the index ordering - partially but not exactly (for example, differing column order, or the - index contains both ASC and DESC columns). - Pending a better solution, the optimization has been removed. - - - - - - - - Fix incorrect handling of NULL index entries in - indexed ROW() comparisons (Tom Lane) - - - - An index search using a row comparison such as ROW(a, b) > - ROW('x', 'y') would stop upon reaching a NULL entry in - the b column, ignoring the fact that there might be - non-NULL b values associated with later values - of a. - - - - - - - - Avoid unlikely data-loss scenarios due to renaming files without - adequate fsync() calls before and after (Michael Paquier, - Tomas Vondra, Andres Freund) - - - - - - - - Fix incorrect behavior when rechecking a just-modified row in a query - that does SELECT FOR UPDATE/SHARE and contains some - relations that need not be locked (Tom Lane) - - - - Rows from non-locked relations were incorrectly treated as containing - all NULLs during the recheck, which could result in incorrectly - deciding that the updated row no longer passes the WHERE - condition, or in incorrectly outputting NULLs. - - - - - - - - Fix bug in json_to_record() when a field of its input - object contains a sub-object with a field name matching one of the - requested output column names (Tom Lane) - - - - - - - - Fix nonsense result from two-argument form - of jsonb_object() when called with empty arrays - (Michael Paquier, Andrew Dunstan) - - - - - - - - Fix misbehavior in jsonb_set() when converting a path - array element into an integer for use as an array subscript - (Michael Paquier) - - - - - - - - Fix misformatting of negative time zone offsets - by to_char()'s OF format code - (Thomas Munro, Tom Lane) - - - - - - - - Fix possible incorrect logging of waits done by - INSERT ... ON CONFLICT (Peter Geoghegan) - - - - Log messages would sometimes claim that the wait was due to an - exclusion constraint although no such constraint was responsible. - - - - - - - - Ignore parameter until - recovery has reached a consistent state (Michael Paquier) - - - - Previously, standby servers would delay application of WAL records in - response to recovery_min_apply_delay even while replaying - the initial portion of WAL needed to make their database state valid. - Since the standby is useless until it's reached a consistent database - state, this was deemed unhelpful. - - - - - - - - Correctly handle cases where pg_subtrans is close to XID - wraparound during server startup (Jeff Janes) - - - - - - - - Fix assorted bugs in logical decoding (Andres Freund) - - - - Trouble cases included tuples larger than one page when replica - identity is FULL, UPDATEs that change a - primary key within a transaction large enough to be spooled to disk, - incorrect reports of subxact logged without previous toplevel - record, and incorrect reporting of a transaction's commit time. - - - - - - - - Fix planner error with nested security barrier views when the outer - view has a WHERE clause containing a correlated subquery - (Dean Rasheed) - - - - - - - - Fix memory leak in GIN index searches (Tom Lane) - - - - - - - - Fix corner-case crash due to trying to free localeconv() - output strings more than once (Tom Lane) - - - - - - - - Fix parsing of affix files for ispell dictionaries - (Tom Lane) - - - - The code could go wrong if the affix file contained any characters - whose byte length changes during case-folding, for - example I in Turkish UTF8 locales. - - - - - - - - Avoid use of sscanf() to parse ispell - dictionary files (Artur Zakirov) - - - - This dodges a portability problem on FreeBSD-derived platforms - (including macOS). - - - - - - - - Fix atomic-operations code used on PPC with IBM's xlc compiler - (Noah Misch) - - - - This error led to rare failures of concurrent operations on that - platform. - - - - - - - - Avoid a crash on old Windows versions (before 7SP1/2008R2SP1) with an - AVX2-capable CPU and a Postgres build done with Visual Studio 2013 - (Christian Ullrich) - - - - This is a workaround for a bug in Visual Studio 2013's runtime - library, which Microsoft have stated they will not fix in that - version. - - - - - - - - Fix psql's tab completion logic to handle multibyte - characters properly (Kyotaro Horiguchi, Robert Haas) - - - - - - - - Fix psql's tab completion for - SECURITY LABEL (Tom Lane) - - - - Pressing TAB after SECURITY LABEL might cause a crash - or offering of inappropriate keywords. - - - - - - - - Make pg_ctl accept a wait timeout from the - PGCTLTIMEOUT environment variable, if none is specified on - the command line (Noah Misch) - - - - This eases testing of slower buildfarm members by allowing them - to globally specify a longer-than-normal timeout for postmaster - startup and shutdown. - - - - - - - - Fix incorrect test for Windows service status - in pg_ctl (Manuel Mathar) - - - - The previous set of minor releases attempted to - fix pg_ctl to properly determine whether to send log - messages to Window's Event Log, but got the test backwards. - - - - - - - - Fix pgbench to correctly handle the combination - of -C and -M prepared options (Tom Lane) - - - - - - - - In pg_upgrade, skip creating a deletion script when - the new data directory is inside the old data directory (Bruce - Momjian) - - - - Blind application of the script in such cases would result in loss of - the new data directory. - - - - - - - - In PL/Perl, properly translate empty Postgres arrays into empty Perl - arrays (Alex Hunsaker) - - - - - - - - Make PL/Python cope with function names that aren't valid Python - identifiers (Jim Nasby) - - - - - - - - Fix multiple mistakes in the statistics returned - by contrib/pgstattuple's pgstatindex() - function (Tom Lane) - - - - - - - - Remove dependency on psed in MSVC builds, since it's no - longer provided by core Perl (Michael Paquier, Andrew Dunstan) - - - - - - - - Update time zone data files to tzdata release 2016c - for DST law changes in Azerbaijan, Chile, Haiti, Palestine, and Russia - (Altai, Astrakhan, Kirov, Sakhalin, Ulyanovsk regions), plus - historical corrections for Lithuania, Moldova, and Russia - (Kaliningrad, Samara, Volgograd). - - - - - - - - - - Release 9.5.1 - - - Release date: - 2016-02-11 - - - - This release contains a variety of fixes from 9.5.0. - For information about new features in the 9.5 major release, see - . - - - - Migration to Version 9.5.1 - - - A dump/restore is not required for those running 9.5.X. - - - - - Changes - - - - - - - - Fix infinite loops and buffer-overrun problems in regular expressions - (Tom Lane) - - - - Very large character ranges in bracket expressions could cause - infinite loops in some cases, and memory overwrites in other cases. - (CVE-2016-0773) - - - - - - - - Fix an oversight that caused hash joins to miss joining to some tuples - of the inner relation in rare cases (Tomas Vondra, Tom Lane) - - - - - - - - Avoid pushdown of HAVING clauses when grouping sets are - used (Andrew Gierth) - - - - - - - - Fix deparsing of ON CONFLICT arbiter WHERE - clauses (Peter Geoghegan) - - - - - - - - Make %h and %r escapes - in log_line_prefix work for messages emitted due - to log_connections (Tom Lane) - - - - Previously, %h/%r started to work just after a - new session had emitted the connection received log message; - now they work for that message too. - - - - - - - - Avoid leaking a token handle during SSPI authentication - (Christian Ullrich) - - - - - - - - Fix psql's \det command to interpret its - pattern argument the same way as other \d commands with - potentially schema-qualified patterns do (Reece Hart) - - - - - - - - In pg_ctl on Windows, check service status to decide - where to send output, rather than checking if standard output is a - terminal (Michael Paquier) - - - - - - - - Fix assorted corner-case bugs in pg_dump's processing - of extension member objects (Tom Lane) - - - - - - - - Fix improper quoting of domain constraint names - in pg_dump (Elvis Pranskevichus) - - - - - - - - Make pg_dump mark a view's triggers as needing to be - processed after its rule, to prevent possible failure during - parallel pg_restore (Tom Lane) - - - - - - - - Install guards in pgbench against corner-case overflow - conditions during evaluation of script-specified division or modulo - operators (Fabien Coelho, Michael Paquier) - - - - - - - - Suppress useless warning message when pg_receivexlog - connects to a pre-9.4 server (Marco Nenciarini) - - - - - - - - Avoid dump/reload problems when using both plpython2 - and plpython3 (Tom Lane) - - - - In principle, both versions of PL/Python can be used in - the same database, though not in the same session (because the two - versions of libpython cannot safely be used concurrently). - However, pg_restore and pg_upgrade both - do things that can fall foul of the same-session restriction. Work - around that by changing the timing of the check. - - - - - - - - Fix PL/Python regression tests to pass with Python 3.5 - (Peter Eisentraut) - - - - - - - - Prevent certain PL/Java parameters from being set by - non-superusers (Noah Misch) - - - - This change mitigates a PL/Java security bug - (CVE-2016-0766), which was fixed in PL/Java by marking - these parameters as superuser-only. To fix the security hazard for - sites that update PostgreSQL more frequently - than PL/Java, make the core code aware of them also. - - - - - - - - Fix ecpg-supplied header files to not contain comments - continued from a preprocessor directive line onto the next line - (Michael Meskes) - - - - Such a comment is rejected by ecpg. It's not yet clear - whether ecpg itself should be changed. - - - - - - - - Fix hstore_to_json_loose()'s test for whether - an hstore value can be converted to a JSON number (Tom Lane) - - - - Previously this function could be fooled by non-alphanumeric trailing - characters, leading to emitting syntactically-invalid JSON. - - - - - - - - In contrib/postgres_fdw, fix bugs triggered by use - of tableoid in data-modifying commands (Etsuro Fujita, - Robert Haas) - - - - - - - - Fix ill-advised restriction of NAMEDATALEN to be less - than 256 (Robert Haas, Tom Lane) - - - - - - - - Improve reproducibility of build output by ensuring filenames are given - to the linker in a fixed order (Christoph Berg) - - - - This avoids possible bitwise differences in the produced executable - files from one build to the next. - - - - - - - - Ensure that dynloader.h is included in the installed - header files in MSVC builds (Bruce Momjian, Michael Paquier) - - - - - - - - Update time zone data files to tzdata release 2016a for - DST law changes in Cayman Islands, Metlakatla, and Trans-Baikal - Territory (Zabaykalsky Krai), plus historical corrections for Pakistan. - - - - - - - - - - Release 9.5 - - - Release date: - 2016-01-07 - - - - Overview - - - Major enhancements in PostgreSQL 9.5 include: - - - - - - - - - Allow INSERTs - that would generate constraint conflicts to be turned into - UPDATEs or ignored - - - - - - Add GROUP BY analysis features GROUPING SETS, - CUBE and - ROLLUP - - - - - - Add row-level security control - - - - - - Create mechanisms for tracking - the progress of replication, - including methods for identifying the origin of individual changes - during logical replication - - - - - - Add Block Range Indexes (BRIN) - - - - - - Substantial performance improvements for sorting - - - - - - Substantial performance improvements for multi-CPU machines - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.5 - - - A dump/restore using , or use - of , is required for those wishing to migrate - data from any previous release. - - - - Version 9.5 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - - - - - Adjust operator precedence - to match the SQL standard (Tom Lane) - - - - The precedence of <=, >= - and <> has been reduced to match that of - <, > - and =. The precedence of IS tests - (e.g., x IS NULL) has been reduced to be - just below these six comparison operators. - Also, multi-keyword operators beginning with NOT now have - the precedence of their base operator (for example, NOT - BETWEEN now has the same precedence as BETWEEN) whereas - before they had inconsistent precedence, behaving like NOT - with respect to their left operand but like their base operator with - respect to their right operand. The new configuration - parameter can be - enabled to warn about queries in which these precedence changes result - in different parsing choices. - - - - - - - Change 's default shutdown mode from - smart to fast (Bruce Momjian) - - - - This means the default behavior will be to forcibly cancel existing - database sessions, not simply wait for them to exit. - - - - - - - Use assignment cast behavior for data type conversions - in PL/pgSQL assignments, rather than converting to and - from text (Tom Lane) - - - - This change causes conversions of Booleans to strings to - produce true or false, not t - or f. Other type conversions may succeed in more cases - than before; for example, assigning a numeric value 3.9 to - an integer variable will now assign 4 rather than failing. If no - assignment-grade cast is defined for the particular source and - destination types, PL/pgSQL will fall back to its old - I/O conversion behavior. - - - - - - - Allow characters in server - command-line options to be escaped with a backslash (Andres Freund) - - - - Formerly, spaces in the options string always separated options, so - there was no way to include a space in an option value. Including - a backslash in an option value now requires writing \\. - - - - - - - Change the default value of the GSSAPI include_realm parameter to 1, so - that by default the realm is not removed from a GSS - or SSPI principal name (Stephen Frost) - - - - - - - Replace configuration parameter checkpoint_segments - with - and (Heikki Linnakangas) - - - - If you previously adjusted checkpoint_segments, the - following formula will give you an approximately equivalent setting: - -max_wal_size = (3 * checkpoint_segments) * 16MB - - Note that the default setting for max_wal_size is - much higher than the default checkpoint_segments used - to be, so adjusting it might no longer be necessary. - - - - - - - Control the Linux OOM killer via new environment - variables PG_OOM_ADJUST_FILE - and PG_OOM_ADJUST_VALUE, - instead of compile-time options LINUX_OOM_SCORE_ADJ and - LINUX_OOM_ADJ - (Gurjeet Singh) - - - - - - - Decommission server configuration - parameter ssl_renegotiation_limit, which was deprecated - in earlier releases (Andres Freund) - - - - While SSL renegotiation is a good idea in theory, it has caused enough - bugs to be considered a net negative in practice, and it is due to be - removed from future versions of the relevant standards. We have - therefore removed support for it from PostgreSQL. - The ssl_renegotiation_limit parameter still exists, but - cannot be set to anything but zero (disabled). It's not documented - anymore, either. - - - - - - - Remove server configuration parameter autocommit, which - was already deprecated and non-operational (Tom Lane) - - - - - - - Remove the pg_authid - catalog's rolcatupdate field, as it had no usefulness - (Adam Brightwell) - - - - - - - The pg_stat_replication - system view's sent field is now NULL, not zero, when - it has no valid value (Magnus Hagander) - - - - - - - Allow json and jsonb array extraction operators to - accept negative subscripts, which count from the end of JSON arrays - (Peter Geoghegan, Andrew Dunstan) - - - - Previously, these operators returned NULL for negative - subscripts. - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.5 and the previous major - release. - - - - Server - - - Indexes - - - - - - - Add Block Range Indexes (BRIN) - (Álvaro Herrera) - - - - BRIN indexes store only summary data (such as minimum - and maximum values) for ranges of heap blocks. They are therefore - very compact and cheap to update; but if the data is naturally - clustered, they can still provide substantial speedup of searches. - - - - - - - Allow queries to perform accurate distance filtering of - bounding-box-indexed objects (polygons, circles) using GiST indexes (Alexander Korotkov, Heikki - Linnakangas) - - - - Previously, to exploit such an index a subquery had to be used to - select a large number of rows ordered by bounding-box distance, and - the result then had to be filtered further with a more accurate - distance calculation. - - - - - - - Allow GiST indexes to perform index-only - scans (Anastasia Lubennikova, Heikki Linnakangas, Andreas Karlsson) - - - - - - - Add configuration parameter - to control the size of GIN pending lists (Fujii Masao) - - - - This value can also be set on a per-index basis as an index storage - parameter. Previously the pending-list size was controlled - by , which was awkward because - appropriate values for work_mem are often much too large - for this purpose. - - - - - - - Issue a warning during the creation of hash indexes because they are not - crash-safe (Bruce Momjian) - - - - - - - - - General Performance - - - - - - - Improve the speed of sorting of varchar, text, - and numeric fields via abbreviated keys - (Peter Geoghegan, Andrew Gierth, Robert Haas) - - - - - - - Extend the infrastructure that allows sorting to be performed by - inlined, non-SQL-callable comparison functions to - cover CREATE INDEX, REINDEX, and - CLUSTER (Peter Geoghegan) - - - - - - - Improve performance of hash joins (Tomas Vondra, Robert Haas) - - - - - - - Improve concurrency of shared buffer replacement - (Robert Haas, Amit Kapila, Andres Freund) - - - - - - - Reduce the number of page locks and pins during index scans (Kevin Grittner) - - - - The primary benefit of this is to allow index vacuums to be blocked - less often. - - - - - - - Make per-backend tracking of buffer pins more memory-efficient - (Andres Freund) - - - - - - - Improve lock scalability (Andres Freund) - - - - This particularly addresses scalability problems when running on - systems with multiple CPU sockets. - - - - - - - Allow the optimizer to remove unnecessary references to left-joined - subqueries (David Rowley) - - - - - - - Allow pushdown of query restrictions into subqueries with window functions, where appropriate - (David Rowley) - - - - - - - Allow a non-leakproof function to be pushed down into a security - barrier view if the function does not receive any view output - columns (Dean Rasheed) - - - - - - - Teach the planner to use statistics obtained from an expression - index on a boolean-returning function, when a matching function call - appears in WHERE (Tom Lane) - - - - - - - Make ANALYZE compute basic statistics (null fraction and - average column width) even for columns whose data type lacks an - equality function (Oleksandr Shulgin) - - - - - - - Speed up CRC (cyclic redundancy check) computations - and switch to CRC-32C (Abhijit Menon-Sen, Heikki Linnakangas) - - - - - - - Improve bitmap index scan performance (Teodor Sigaev, Tom Lane) - - - - - - - Speed up CREATE INDEX by avoiding unnecessary memory - copies (Robert Haas) - - - - - - - Increase the number of buffer mapping partitions (Amit Kapila, - Andres Freund, Robert Haas) - - - - This improves performance for highly concurrent workloads. - - - - - - - - - Monitoring - - - - - - - Add per-table autovacuum logging control via new - log_autovacuum_min_duration storage parameter - (Michael Paquier) - - - - - - - Add new configuration parameter - (Thomas Munro) - - - - This string, typically set in postgresql.conf, - allows clients to identify the cluster. This name also appears - in the process title of all server processes, allowing for easier - identification of processes belonging to the same cluster. - - - - - - - Prevent non-superusers from changing on connection startup (Fujii Masao) - - - - - - - - - <acronym>SSL</acronym> - - - - - - - Check Subject Alternative - Names in SSL server certificates, if present - (Alexey Klyukin) - - - - When they are present, this replaces checks against the certificate's - Common Name. - - - - - - - Add system view pg_stat_ssl to report - SSL connection information (Magnus Hagander) - - - - - - - Add libpq functions to return SSL - information in an implementation-independent way (Heikki Linnakangas) - - - - While PQgetssl() can - still be used to call OpenSSL functions, it is now - considered deprecated because future versions - of libpq might support other SSL - implementations. When possible, use the new - functions PQsslAttribute(), PQsslAttributeNames(), - and PQsslInUse() - to obtain SSL information in - an SSL-implementation-independent way. - - - - - - - Make libpq honor any OpenSSL - thread callbacks (Jan Urbanski) - - - - Previously they were overwritten. - - - - - - - - - Server Settings - - - - - - - Replace configuration parameter checkpoint_segments - with - and (Heikki Linnakangas) - - - - This change allows the allocation of a large number of WAL - files without keeping them after they are no longer needed. - Therefore the default for max_wal_size has been set - to 1GB, much larger than the old default - for checkpoint_segments. - Also note that standby servers perform restartpoints to try to limit - their WAL space consumption to max_wal_size; previously - they did not pay any attention to checkpoint_segments. - - - - - - - Control the Linux OOM killer via new environment - variables PG_OOM_ADJUST_FILE - and PG_OOM_ADJUST_VALUE - (Gurjeet Singh) - - - - The previous OOM control infrastructure involved - compile-time options LINUX_OOM_SCORE_ADJ and - LINUX_OOM_ADJ, which are no longer supported. - The new behavior is available in all builds. - - - - - - - Allow recording of transaction - commit time stamps when configuration parameter - is enabled (Álvaro Herrera, Petr Jelínek) - - - - Time stamp information can be accessed using functions pg_xact_commit_timestamp() - and pg_last_committed_xact(). - - - - - - - Allow to be set - by ALTER ROLE SET (Peter Eisentraut, Kyotaro Horiguchi) - - - - - - - Allow autovacuum workers - to respond to configuration parameter changes during a run - (Michael Paquier) - - - - - - - Make configuration parameter - read-only (Andres Freund) - - - - This means that assertions can no longer be turned - off if they were enabled at compile time, allowing for more - efficient code optimization. This change also removes the postgres option. - - - - - - - Allow setting on - systems where it has no effect (Peter Eisentraut) - - - - - - - Add system view pg_file_settings - to show the contents of the server's configuration files - (Sawada Masahiko) - - - - - - - Add pending_restart to the system view pg_settings to - indicate a change has been made but will not take effect until a - database restart (Peter Eisentraut) - - - - - - - Allow ALTER SYSTEM - values to be reset with ALTER SYSTEM RESET (Vik - Fearing) - - - - This command removes the specified setting - from postgresql.auto.conf. - - - - - - - - - - - Replication and Recovery - - - - - - - Create mechanisms for tracking - the progress of replication, - including methods for identifying the origin of individual changes - during logical replication (Andres Freund) - - - - This is helpful when implementing replication solutions. - - - - - - - Rework truncation of the multixact commit log to be properly - WAL-logged (Andres Freund) - - - - This makes things substantially simpler and more robust. - - - - - - - Add recovery.conf - parameter recovery_target_action - to control post-recovery activity (Petr Jelínek) - - - - This replaces the old parameter pause_at_recovery_target. - - - - - - - Add new value - always to allow standbys to always archive received - WAL files (Fujii Masao) - - - - - - - Add configuration - parameter to - control WAL read retry after failure - (Alexey Vasiliev, Michael Paquier) - - - - This is particularly helpful for warm standbys. - - - - - - - Allow compression of full-page images stored in WAL - (Rahila Syed, Michael Paquier) - - - - This feature reduces WAL volume, at the cost of more CPU time spent - on WAL logging and WAL replay. It is controlled by a new - configuration parameter , which - currently is off by default. - - - - - - - Archive WAL files with suffix .partial - during standby promotion (Heikki Linnakangas) - - - - - - - Add configuration parameter - to log replication commands (Fujii Masao) - - - - By default, replication commands, e.g. IDENTIFY_SYSTEM, - are not logged, even when is set - to all. - - - - - - - Report the processes holding replication slots in pg_replication_slots - (Craig Ringer) - - - - The new output column is active_pid. - - - - - - - Allow recovery.conf's primary_conninfo setting to - use connection URIs, e.g. postgres:// - (Alexander Shulgin) - - - - - - - - - Queries - - - - - - - Allow INSERTs - that would generate constraint conflicts to be turned into - UPDATEs or ignored (Peter Geoghegan, Heikki - Linnakangas, Andres Freund) - - - - The syntax is INSERT ... ON CONFLICT DO NOTHING/UPDATE. - This is the Postgres implementation of the popular - UPSERT command. - - - - - - - Add GROUP BY analysis features GROUPING SETS, - CUBE and - ROLLUP - (Andrew Gierth, Atri Sharma) - - - - - - - Allow setting multiple target columns in - an UPDATE from the result of - a single sub-SELECT (Tom Lane) - - - - This is accomplished using the syntax UPDATE tab SET - (col1, col2, ...) = (SELECT ...). - - - - - - - Add SELECT option - SKIP LOCKED to skip locked rows (Thomas Munro) - - - - This does not throw an error for locked rows like - NOWAIT does. - - - - - - - Add SELECT option - TABLESAMPLE to return a subset of a table (Petr - Jelínek) - - - - This feature supports the SQL-standard table sampling methods. - In addition, there are provisions - for user-defined - table sampling methods. - - - - - - - Suggest possible matches for mistyped column names (Peter - Geoghegan, Robert Haas) - - - - - - - - - Utility Commands - - - - - - - Add more details about sort ordering in EXPLAIN output (Marius Timmer, - Lukas Kreft, Arne Scheffer) - - - - Details include COLLATE, DESC, - USING, and NULLS FIRST/LAST. - - - - - - - Make VACUUM log the - number of pages skipped due to pins (Jim Nasby) - - - - - - - Make TRUNCATE properly - update the pg_stat* tuple counters (Alexander Shulgin) - - - - - - - <xref linkend="sql-reindex"/> - - - - - - - Allow REINDEX to reindex an entire schema using the - SCHEMA option (Sawada Masahiko) - - - - - - - Add VERBOSE option to REINDEX (Sawada - Masahiko) - - - - - - - Prevent REINDEX DATABASE and SCHEMA - from outputting object names, unless VERBOSE is used - (Simon Riggs) - - - - - - - Remove obsolete FORCE option from REINDEX - (Fujii Masao) - - - - - - - - - - Object Manipulation - - - - - - - Add row-level security control - (Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean Rasheed, - Stephen Frost) - - - - This feature allows row-by-row control over which users can add, - modify, or even see rows in a table. This is controlled by new - commands CREATE/ALTER/DROP POLICY and ALTER TABLE ... ENABLE/DISABLE - ROW SECURITY. - - - - - - - Allow changing of the WAL - logging status of a table after creation with ALTER TABLE ... SET LOGGED / - UNLOGGED (Fabrízio de Royes Mello) - - - - - - - Add IF NOT EXISTS clause to CREATE TABLE AS, - CREATE INDEX, - CREATE SEQUENCE, - and CREATE - MATERIALIZED VIEW (Fabrízio de Royes Mello) - - - - - - - Add support for IF EXISTS to ALTER TABLE ... RENAME - CONSTRAINT (Bruce Momjian) - - - - - - - Allow some DDL commands to accept CURRENT_USER - or SESSION_USER, meaning the current user or session - user, in place of a specific user name (Kyotaro Horiguchi, - Álvaro Herrera) - - - - This feature is now supported in - , , - , , - and ALTER object OWNER TO commands. - - - - - - - Support comments on domain - constraints (Álvaro Herrera) - - - - - - - Reduce lock levels of some create and alter trigger and foreign - key commands (Simon Riggs, Andreas Karlsson) - - - - - - - Allow LOCK TABLE ... ROW EXCLUSIVE - MODE for those with INSERT privileges on the - target table (Stephen Frost) - - - - Previously this command required UPDATE, DELETE, - or TRUNCATE privileges. - - - - - - - Apply table and domain CHECK constraints in order by name - (Tom Lane) - - - - The previous ordering was indeterminate. - - - - - - - Allow CREATE/ALTER DATABASE - to manipulate datistemplate and - datallowconn (Vik Fearing) - - - - This allows these per-database settings to be - changed without manually modifying the pg_database - system catalog. - - - - - - - <link linkend="ddl-foreign-data">Foreign Tables</link> - - - - - - - Add support for - (Ronan Dunklau, Michael Paquier, Tom Lane) - - - - This command allows automatic creation of local foreign tables - that match the structure of existing tables on a remote server. - - - - - - - Allow CHECK constraints to be placed on foreign tables - (Shigeru Hanada, Etsuro Fujita) - - - - Such constraints are assumed to be enforced on the remote server, - and are not enforced locally. However, they are assumed to hold for - purposes of query optimization, such - as constraint - exclusion. - - - - - - - Allow foreign tables to participate in inheritance (Shigeru Hanada, - Etsuro Fujita) - - - - To let this work naturally, foreign tables are now allowed to have - check constraints marked as not valid, and to set storage - and OID characteristics, even though these operations are - effectively no-ops for a foreign table. - - - - - - - Allow foreign data wrappers and custom scans to implement join - pushdown (KaiGai Kohei) - - - - - - - - - <link linkend="event-triggers">Event Triggers</link> - - - - - - - Whenever a ddl_command_end event trigger is installed, - capture details of DDL activity for it to inspect - (Álvaro Herrera) - - - - This information is available through a set-returning function pg_event_trigger_ddl_commands(), - or by inspection of C data structures if that function doesn't - provide enough detail. - - - - - - - Allow event triggers on table rewrites caused by ALTER TABLE (Dimitri - Fontaine) - - - - - - - Add event trigger support for database-level COMMENT, SECURITY LABEL, - and GRANT/REVOKE (Álvaro Herrera) - - - - - - - Add columns to the output of pg_event_trigger_dropped_objects - (Álvaro Herrera) - - - - This allows simpler processing of delete operations. - - - - - - - - - - - Data Types - - - - - - - Allow the xml data type - to accept empty or all-whitespace content values (Peter Eisentraut) - - - - This is required by the SQL/XML - specification. - - - - - - - Allow macaddr input - using the format xxxx-xxxx-xxxx (Herwin Weststrate) - - - - - - - Disallow non-SQL-standard syntax for interval with - both precision and field specifications (Bruce Momjian) - - - - Per the standard, such type specifications should be written as, - for example, INTERVAL MINUTE TO SECOND(2). - PostgreSQL formerly allowed this to be written as - INTERVAL(2) MINUTE TO SECOND, but it must now be - written in the standard way. - - - - - - - Add selectivity estimators for inet/cidr operators and improve - estimators for text search functions (Emre Hasegeli, Tom Lane) - - - - - - - Add data - types regrole - and regnamespace - to simplify entering and pretty-printing the OID of a role - or namespace (Kyotaro Horiguchi) - - - - - - - <link linkend="datatype-json"><acronym>JSON</acronym></link> - - - - - - - Add jsonb functions jsonb_set() - and jsonb_pretty() - (Dmitry Dolgov, Andrew Dunstan, Petr Jelínek) - - - - - - - Add jsonb generator functions to_jsonb(), - jsonb_object(), - jsonb_build_object(), - jsonb_build_array(), - jsonb_agg(), - and jsonb_object_agg() - (Andrew Dunstan) - - - - Equivalent functions already existed for type json. - - - - - - - Reduce casting requirements to/from json and jsonb (Tom Lane) - - - - - - - Allow text, text array, and integer - values to be subtracted - from jsonb documents (Dmitry Dolgov, Andrew Dunstan) - - - - - - - Add jsonb || operator - (Dmitry Dolgov, Andrew Dunstan) - - - - - - - Add json_strip_nulls() - and jsonb_strip_nulls() - functions to remove JSON null values from documents - (Andrew Dunstan) - - - - - - - - - - - Functions - - - - - - - Add generate_series() - for numeric values (Plato Malugin) - - - - - - - Allow array_agg() and - ARRAY() to take arrays as inputs (Ali Akbar, Tom Lane) - - - - - - - Add functions array_position() - and array_positions() - to return subscripts of array values (Pavel Stehule) - - - - - - - Add a point-to-polygon distance operator - <-> - (Alexander Korotkov) - - - - - - - Allow multibyte characters as escapes in SIMILAR TO - and SUBSTRING - (Jeff Davis) - - - - Previously, only a single-byte character was allowed as an escape. - - - - - - - Add a width_bucket() - variant that supports any sortable data type and non-uniform bucket - widths (Petr Jelínek) - - - - - - - Add an optional missing_ok argument to pg_read_file() - and related functions (Michael Paquier, Heikki Linnakangas) - - - - - - - Allow => - to specify named parameters in function calls (Pavel Stehule) - - - - Previously only := could be used. This requires removing - the possibility for => to be a user-defined operator. - Creation of user-defined => operators has been issuing - warnings since PostgreSQL 9.0. - - - - - - - Add POSIX-compliant rounding for platforms that use - PostgreSQL-supplied rounding functions (Pedro Gimeno Fortea) - - - - - - - System Information Functions and Views - - - - - - - Add function pg_get_object_address() - to return OIDs that uniquely - identify an object, and function pg_identify_object_as_address() - to return object information based on OIDs (Álvaro - Herrera) - - - - - - - Loosen security checks for viewing queries in pg_stat_activity, - executing pg_cancel_backend(), - and executing pg_terminate_backend() - (Stephen Frost) - - - - Previously, only the specific role owning the target session could - perform these operations; now membership in that role is sufficient. - - - - - - - Add pg_stat_get_snapshot_timestamp() - to output the time stamp of the statistics snapshot (Matt Kelly) - - - - This represents the last time the snapshot file was written to - the file system. - - - - - - - Add mxid_age() - to compute multi-xid age (Bruce Momjian) - - - - - - - - Aggregates - - - - - - - Add min()/max() aggregates - for inet/cidr data types (Haribabu - Kommi) - - - - - - - Use 128-bit integers, where supported, as accumulators for some - aggregate functions (Andreas Karlsson) - - - - - - - - - - - Server-Side Languages - - - - - - - Improve support for composite types in PL/Python (Ed Behn, Ronan - Dunklau) - - - - This allows PL/Python functions to return arrays - of composite types. - - - - - - - Reduce lossiness of PL/Python floating-point value - conversions (Marko Kreen) - - - - - - - Allow specification of conversion routines between SQL - data types and data types of procedural languages (Peter Eisentraut) - - - - This change adds new commands CREATE/DROP TRANSFORM. - This also adds optional transformations between the hstore and ltree types to/from PL/Perl and PL/Python. - - - - - - - <link linkend="plpgsql">PL/pgSQL</link> Server-Side Language - - - - - - - Improve PL/pgSQL array - performance (Tom Lane) - - - - - - - Add an ASSERT - statement in PL/pgSQL (Pavel Stehule) - - - - - - - Allow more PL/pgSQL - keywords to be used as identifiers (Tom Lane) - - - - - - - - - - - Client Applications - - - - - - - Move pg_archivecleanup, - pg_test_fsync, - pg_test_timing, - and pg_xlogdump - from contrib to src/bin (Peter Eisentraut) - - - - This should result in these programs being installed by default in - most installations. - - - - - - - Add pg_rewind, - which allows re-synchronizing a master server after failback - (Heikki Linnakangas) - - - - - - - Allow pg_receivexlog - to manage physical replication slots (Michael Paquier) - - - - This is controlled via new and - options. - - - - - - - Allow pg_receivexlog - to synchronously flush WAL to storage using new - option (Furuya Osamu, Fujii Masao) - - - - Without this, WAL files are fsync'ed only on close. - - - - - - - Allow vacuumdb to - vacuum in parallel using new option (Dilip Kumar) - - - - - - - In vacuumdb, do not - prompt for the same password repeatedly when multiple connections - are necessary (Haribabu Kommi, Michael Paquier) - - - - - - - Add option to reindexdb (Sawada - Masahiko) - - - - - - - Make pg_basebackup - use a tablespace mapping file when using tar format, - to support symbolic links and file paths of 100+ characters in length - on MS Windows (Amit Kapila) - - - - - - - Add pg_xlogdump option - to display summary statistics (Abhijit Menon-Sen) - - - - - - - <xref linkend="app-psql"/> - - - - - - - Allow psql to produce AsciiDoc output (Szymon Guz) - - - - - - - Add an errors mode that displays only failed commands - to psql's ECHO variable - (Pavel Stehule) - - - - This behavior can also be selected with psql's - option. - - - - - - - Provide separate column, header, and border linestyle control - in psql's unicode linestyle (Pavel Stehule) - - - - Single or double lines are supported; the default is - single. - - - - - - - Add new option %l in psql's PROMPT variables - to display the current multiline statement line number - (Sawada Masahiko) - - - - - - - Add \pset option pager_min_lines - to control pager invocation (Andrew Dunstan) - - - - - - - Improve psql line counting used when deciding - to invoke the pager (Andrew Dunstan) - - - - - - - psql now fails if the file specified by - an or switch cannot be - written (Tom Lane, Daniel Vérité) - - - - Previously, it effectively ignored the switch in such cases. - - - - - - - Add psql tab completion when setting the - variable (Jeff Janes) - - - - Currently only the first schema can be tab-completed. - - - - - - - Improve psql's tab completion for triggers and rules - (Andreas Karlsson) - - - - - - - <link linkend="app-psql-meta-commands">Backslash Commands</link> - - - - - - - Add psql \? help sections - variables and options (Pavel Stehule) - - - - \? variables shows psql's special - variables and \? options shows the command-line options. - \? commands shows the meta-commands, which is the - traditional output and remains the default. These help displays - can also be obtained with the command-line - option --help=section. - - - - - - - Show tablespace size in psql's \db+ - (Fabrízio de Royes Mello) - - - - - - - Show data type owners in psql's \dT+ - (Magnus Hagander) - - - - - - - Allow psql's \watch to output - \timing information (Fujii Masao) - - - - Also prevent from echoing - \watch queries, since that is generally unwanted. - - - - - - - Make psql's \sf and \ef - commands honor ECHO_HIDDEN (Andrew Dunstan) - - - - - - - Improve psql tab completion for \set, - \unset, and :variable names (Pavel - Stehule) - - - - - - - Allow tab completion of role names - in psql \c commands (Ian Barwick) - - - - - - - - - - - <xref linkend="app-pgdump"/> - - - - - - - Allow pg_dump to share a snapshot taken by another - session using (Simon Riggs, Michael Paquier) - - - - The remote snapshot must have been exported by - pg_export_snapshot() or logical replication slot - creation. This can be used to share a consistent snapshot - across multiple pg_dump processes. - - - - - - - Support table sizes exceeding 8GB in tar archive format (Tom Lane) - - - - The POSIX standard for tar format does not allow elements of a tar - archive to exceed 8GB, but most modern implementations of tar - support an extension that does allow it. Use the extension format - when necessary, rather than failing. - - - - - - - Make pg_dump always print the server and - pg_dump versions (Jing Wang) - - - - Previously, version information was only printed in - mode. - - - - - - - Remove the long-ignored / - option from pg_dump, pg_dumpall, - and pg_restore (Fujii Masao) - - - - - - - - - <xref linkend="app-pg-ctl"/> - - - - - - - Support multiple pg_ctl options, - concatenating their values (Bruce Momjian) - - - - - - - Allow control of pg_ctl's event source logging - on MS Windows (MauMau) - - - - This only controls pg_ctl, not the server, which - has separate settings in postgresql.conf. - - - - - - - If the server's listen address is set to a wildcard value - (0.0.0.0 in IPv4 or :: in IPv6), connect via - the loopback address rather than trying to use the wildcard address - literally (Kondo Yuta) - - - - This fix primarily affects Windows, since on other platforms - pg_ctl will prefer to use a Unix-domain socket. - - - - - - - - - <xref linkend="pgupgrade"/> - - - - - - - Move pg_upgrade from contrib to - src/bin (Peter Eisentraut) - - - - In connection with this change, the functionality previously - provided by the pg_upgrade_support module has been - moved into the core server. - - - - - - - Support multiple pg_upgrade - / options, - concatenating their values (Bruce Momjian) - - - - - - - Improve database collation comparisons in - pg_upgrade (Heikki Linnakangas) - - - - - - - Remove support for upgrading from 8.3 clusters (Bruce Momjian) - - - - - - - - - <xref linkend="pgbench"/> - - - - - - - Move pgbench from contrib to src/bin - (Peter Eisentraut) - - - - - - - Fix calculation of TPS number excluding connections - establishing (Tatsuo Ishii, Fabien Coelho) - - - - The overhead for connection establishment was miscalculated whenever - the number of pgbench threads was less than the number of client - connections. Although this is clearly a bug, we won't back-patch it - into pre-9.5 branches since it makes TPS numbers not comparable to - previous results. - - - - - - - Allow counting of pgbench transactions that take over a specified - amount of time (Fabien Coelho) - - - - This is controlled by a new option. - - - - - - - Allow pgbench to generate Gaussian/exponential distributions - using \setrandom (Kondo Mitsumasa, Fabien Coelho) - - - - - - - Allow pgbench's \set command to handle - arithmetic expressions containing more than one operator, and add - % (modulo) to the set of operators it supports - (Robert Haas, Fabien Coelho) - - - - - - - - - - - Source Code - - - - - - - Simplify WAL record format - (Heikki Linnakangas) - - - - This allows external tools to more easily track what blocks - are modified. - - - - - - - Improve the representation of transaction commit and abort WAL - records (Andres Freund) - - - - - - - Add atomic memory operations API (Andres Freund) - - - - - - - Allow custom path and scan methods (KaiGai Kohei, Tom Lane) - - - - This allows extensions greater control over the optimizer and - executor. - - - - - - - Allow foreign data wrappers to do post-filter locking (Etsuro - Fujita) - - - - - - - Foreign tables can now take part in INSERT ... ON CONFLICT - DO NOTHING queries (Peter Geoghegan, Heikki Linnakangas, - Andres Freund) - - - - Foreign data wrappers must be modified to handle this. - INSERT ... ON CONFLICT DO UPDATE is not supported on - foreign tables. - - - - - - - Improve hash_create()'s API for selecting - simple-binary-key hash functions (Teodor Sigaev, Tom Lane) - - - - - - - Improve parallel execution infrastructure (Robert Haas, Amit - Kapila, Noah Misch, Rushabh Lathia, Jeevan Chalke) - - - - - - - Remove Alpha (CPU) and Tru64 (OS) ports (Andres Freund) - - - - - - - Remove swap-byte-based spinlock implementation for - ARMv5 and earlier CPUs (Robert Haas) - - - - ARMv5's weak memory ordering made this locking - implementation unsafe. Spinlock support is still possible on - newer gcc implementations with atomics support. - - - - - - - Generate an error when excessively long (100+ character) file - paths are written to tar files (Peter Eisentraut) - - - - Tar does not support such overly-long paths. - - - - - - - Change index operator class for columns pg_seclabel.provider - and pg_shseclabel.provider - to be text_pattern_ops (Tom Lane) - - - - This avoids possible problems with these indexes when different - databases of a cluster have different default collations. - - - - - - - Change the spinlock primitives to function as compiler barriers - (Robert Haas) - - - - - - - MS Windows - - - - - - - Allow higher-precision time stamp resolution on Windows 8, Windows - Server 2012, and later Windows systems (Craig Ringer) - - - - - - - Install shared libraries to bin in MS Windows (Peter Eisentraut, Michael Paquier) - - - - - - - Install src/test/modules together with - contrib on MSVC builds (Michael - Paquier) - - - - - - - Allow configure's - option to be honored by the - MSVC build (Michael Paquier) - - - - - - - Pass PGFILEDESC into MSVC contrib builds - (Michael Paquier) - - - - - - - Add icons to all MSVC-built binaries and version - information to all MS Windows - binaries (Noah Misch) - - - - MinGW already had such icons. - - - - - - - Add optional-argument support to the internal - getopt_long() implementation (Michael Paquier, - Andres Freund) - - - - This is used by the MSVC build. - - - - - - - - - - - Additional Modules - - - - - - - Add statistics for minimum, maximum, - mean, and standard deviation times to pg_stat_statements - (Mitsumasa Kondo, Andrew Dunstan) - - - - - - - Add pgcrypto function - pgp_armor_headers() to extract PGP - armor headers (Marko Tiikkaja, Heikki Linnakangas) - - - - - - - Allow empty replacement strings in unaccent (Mohammad Alhashash) - - - - This is useful in languages where diacritic signs are represented - as separate characters. - - - - - - - Allow multicharacter source strings in unaccent (Tom Lane) - - - - This could be useful in languages where diacritic signs are - represented as separate characters. It also allows more complex - unaccent dictionaries. - - - - - - - Add contrib modules tsm_system_rows and - tsm_system_time - to allow additional table sampling methods (Petr Jelínek) - - - - - - - Add GIN - index inspection functions to pageinspect (Heikki - Linnakangas, Peter Geoghegan, Michael Paquier) - - - - - - - Add information about buffer pins to pg_buffercache display - (Andres Freund) - - - - - - - Allow pgstattuple - to report approximate answers with less overhead using - pgstattuple_approx() (Abhijit Menon-Sen) - - - - - - - Move dummy_seclabel, test_shm_mq, - test_parser, and worker_spi - from contrib to src/test/modules - (Álvaro Herrera) - - - - These modules are only meant for server testing, so they do not need - to be built or installed when packaging PostgreSQL. - - - - - - - - - - diff --git a/doc/src/sgml/release-9.6.sgml b/doc/src/sgml/release-9.6.sgml deleted file mode 100644 index f364aebeb5c..00000000000 --- a/doc/src/sgml/release-9.6.sgml +++ /dev/null @@ -1,9648 +0,0 @@ - - - - - Release 9.6.8 - - - Release date: - 2018-03-01 - - - - This release contains a variety of fixes from 9.6.7. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.8 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if you run an installation in which not all users are mutually - trusting, or if you maintain an application or extension that is - intended for use in arbitrary situations, it is strongly recommended - that you read the documentation changes described in the first changelog - entry below, and take suitable steps to ensure that your installation or - code is secure. - - - - Also, the changes described in the second changelog entry below may - cause functions used in index expressions or materialized views to fail - during auto-analyze, or when reloading from a dump. After upgrading, - monitor the server logs for such problems, and fix affected functions. - - - - Also, if you are upgrading from a version earlier than 9.6.7, - see . - - - - - Changes - - - - - - Document how to configure installations and applications to guard - against search-path-dependent trojan-horse attacks from other users - (Noah Misch) - - - - Using a search_path setting that includes any - schemas writable by a hostile user enables that user to capture - control of queries and then run arbitrary SQL code with the - permissions of the attacked user. While it is possible to write - queries that are proof against such hijacking, it is notationally - tedious, and it's very easy to overlook holes. Therefore, we now - recommend configurations in which no untrusted schemas appear in - one's search path. Relevant documentation appears in - (for database administrators and users), - (for application authors), - (for extension authors), and - (for authors - of SECURITY DEFINER functions). - (CVE-2018-1058) - - - - - - Avoid use of insecure search_path settings - in pg_dump and other client programs - (Noah Misch, Tom Lane) - - - - pg_dump, - pg_upgrade, - vacuumdb and - other PostgreSQL-provided applications were - themselves vulnerable to the type of hijacking described in the previous - changelog entry; since these applications are commonly run by - superusers, they present particularly attractive targets. To make them - secure whether or not the installation as a whole has been secured, - modify them to include only the pg_catalog - schema in their search_path settings. - Autovacuum worker processes now do the same, as well. - - - - In cases where user-provided functions are indirectly executed by - these programs — for example, user-provided functions in index - expressions — the tighter search_path may - result in errors, which will need to be corrected by adjusting those - user-provided functions to not assume anything about what search path - they are invoked under. That has always been good practice, but now - it will be necessary for correct behavior. - (CVE-2018-1058) - - - - - - Fix misbehavior of concurrent-update rechecks with CTE references - appearing in subplans (Tom Lane) - - - - If a CTE (WITH clause reference) is used in an - InitPlan or SubPlan, and the query requires a recheck due to trying - to update or lock a concurrently-updated row, incorrect results could - be obtained. - - - - - - Fix planner failures with overlapping mergejoin clauses in an outer - join (Tom Lane) - - - - These mistakes led to left and right pathkeys do not match in - mergejoin or outer pathkeys do not match - mergeclauses planner errors in corner cases. - - - - - - Repair pg_upgrade's failure to - preserve relfrozenxid for materialized - views (Tom Lane, Andres Freund) - - - - This oversight could lead to data corruption in materialized views - after an upgrade, manifesting as could not access status of - transaction or found xmin from before - relfrozenxid errors. The problem would be more likely to - occur in seldom-refreshed materialized views, or ones that were - maintained only with REFRESH MATERIALIZED VIEW - CONCURRENTLY. - - - - If such corruption is observed, it can be repaired by refreshing the - materialized view (without CONCURRENTLY). - - - - - - Fix incorrect reporting of PL/Python function names in - error CONTEXT stacks (Tom Lane) - - - - An error occurring within a nested PL/Python function call (that is, - one reached via a SPI query from another PL/Python function) would - result in a stack trace showing the inner function's name twice, - rather than the expected results. Also, an error in a nested - PL/Python DO block could result in a null pointer - dereference crash on some platforms. - - - - - - Allow contrib/auto_explain's - log_min_duration setting to range up - to INT_MAX, or about 24 days instead of 35 minutes - (Tom Lane) - - - - - - Mark assorted GUC variables as PGDLLIMPORT, to - ease porting extension modules to Windows (Metin Doslu) - - - - - - - - - - Release 9.6.7 - - - Release date: - 2018-02-08 - - - - This release contains a variety of fixes from 9.6.6. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.7 - - - A dump/restore is not required for those running 9.6.X. - - - - However, - if you use contrib/cube's ~> - operator, see the entry below about that. - - - - Also, if you are upgrading from a version earlier than 9.6.6, - see . - - - - - Changes - - - - - - Ensure that all temporary files made - by pg_upgrade are non-world-readable - (Tom Lane, Noah Misch) - - - - pg_upgrade normally restricts its - temporary files to be readable and writable only by the calling user. - But the temporary file containing pg_dumpall -g - output would be group- or world-readable, or even writable, if the - user's umask setting allows. In typical usage on - multi-user machines, the umask and/or the working - directory's permissions would be tight enough to prevent problems; - but there may be people using pg_upgrade - in scenarios where this oversight would permit disclosure of database - passwords to unfriendly eyes. - (CVE-2018-1053) - - - - - - Fix vacuuming of tuples that were updated while key-share locked - (Andres Freund, Álvaro Herrera) - - - - In some cases VACUUM would fail to remove such - tuples even though they are now dead, leading to assorted data - corruption scenarios. - - - - - - Ensure that vacuum will always clean up the pending-insertions list of - a GIN index (Masahiko Sawada) - - - - This is necessary to ensure that dead index entries get removed. - The old code got it backwards, allowing vacuum to skip the cleanup if - some other process were running cleanup concurrently, thus risking - invalid entries being left behind in the index. - - - - - - Fix inadequate buffer locking in some LSN fetches (Jacob Champion, - Asim Praveen, Ashwin Agrawal) - - - - These errors could result in misbehavior under concurrent load. - The potential consequences have not been characterized fully. - - - - - - Fix incorrect query results from cases involving flattening of - subqueries whose outputs are used in GROUPING SETS - (Heikki Linnakangas) - - - - - - Avoid unnecessary failure in a query on an inheritance tree that - occurs concurrently with some child table being removed from the tree - by ALTER TABLE NO INHERIT (Tom Lane) - - - - - - Fix spurious deadlock failures when multiple sessions are - running CREATE INDEX CONCURRENTLY (Jeff Janes) - - - - - - Fix failures when an inheritance tree contains foreign child tables - (Etsuro Fujita) - - - - A mix of regular and foreign tables in an inheritance tree resulted in - creation of incorrect plans for UPDATE - and DELETE queries. This led to visible failures in - some cases, notably when there are row-level triggers on a foreign - child table. - - - - - - Repair failure with correlated sub-SELECT - inside VALUES inside a LATERAL - subquery (Tom Lane) - - - - - - Fix could not devise a query plan for the given query - planner failure for some cases involving nested UNION - ALL inside a lateral subquery (Tom Lane) - - - - - - Fix logical decoding to correctly clean up disk files for crashed - transactions (Atsushi Torikoshi) - - - - Logical decoding may spill WAL records to disk for transactions - generating many WAL records. Normally these files are cleaned up - after the transaction's commit or abort record arrives; but if - no such record is ever seen, the removal code misbehaved. - - - - - - Fix walsender timeout failure and failure to respond to interrupts - when processing a large transaction (Petr Jelinek) - - - - - - Fix has_sequence_privilege() to - support WITH GRANT OPTION tests, - as other privilege-testing functions do (Joe Conway) - - - - - - In databases using UTF8 encoding, ignore any XML declaration that - asserts a different encoding (Pavel Stehule, Noah Misch) - - - - We always store XML strings in the database encoding, so allowing - libxml to act on a declaration of another encoding gave wrong results. - In encodings other than UTF8, we don't promise to support non-ASCII - XML data anyway, so retain the previous behavior for bug compatibility. - This change affects only xpath() and related - functions; other XML code paths already acted this way. - - - - - - Provide for forward compatibility with future minor protocol versions - (Robert Haas, Badrul Chowdhury) - - - - Up to now, PostgreSQL servers simply - rejected requests to use protocol versions newer than 3.0, so that - there was no functional difference between the major and minor parts - of the protocol version number. Allow clients to request versions 3.x - without failing, sending back a message showing that the server only - understands 3.0. This makes no difference at the moment, but - back-patching this change should allow speedier introduction of future - minor protocol upgrades. - - - - - - Cope with failure to start a parallel worker process - (Amit Kapila, Robert Haas) - - - - Parallel query previously tended to hang indefinitely if a worker - could not be started, as the result of fork() - failure or other low-probability problems. - - - - - - Fix collection of EXPLAIN statistics from parallel - workers (Amit Kapila, Thomas Munro) - - - - - - Avoid unsafe alignment assumptions when working - with __int128 (Tom Lane) - - - - Typically, compilers assume that __int128 variables are - aligned on 16-byte boundaries, but our memory allocation - infrastructure isn't prepared to guarantee that, and increasing the - setting of MAXALIGN seems infeasible for multiple reasons. Adjust the - code to allow use of __int128 only when we can tell the - compiler to assume lesser alignment. The only known symptom of this - problem so far is crashes in some parallel aggregation queries. - - - - - - Prevent stack-overflow crashes when planning extremely deeply - nested set operations - (UNION/INTERSECT/EXCEPT) - (Tom Lane) - - - - - - Fix null-pointer crashes for some types of LDAP URLs appearing - in pg_hba.conf (Thomas Munro) - - - - - - Fix sample INSTR() functions in the PL/pgSQL - documentation (Yugo Nagata, Tom Lane) - - - - These functions are stated to - be Oracle compatible, but - they weren't exactly. In particular, there was a discrepancy in the - interpretation of a negative third parameter: Oracle thinks that a - negative value indicates the last place where the target substring can - begin, whereas our functions took it as the last place where the - target can end. Also, Oracle throws an error for a zero or negative - fourth parameter, whereas our functions returned zero. - - - - The sample code has been adjusted to match Oracle's behavior more - precisely. Users who have copied this code into their applications - may wish to update their copies. - - - - - - Fix pg_dump to make ACL (permissions), - comment, and security label entries reliably identifiable in archive - output formats (Tom Lane) - - - - The tag portion of an ACL archive entry was usually - just the name of the associated object. Make it start with the object - type instead, bringing ACLs into line with the convention already used - for comment and security label archive entries. Also, fix the - comment and security label entries for the whole database, if present, - to make their tags start with DATABASE so that they - also follow this convention. This prevents false matches in code that - tries to identify large-object-related entries by seeing if the tag - starts with LARGE OBJECT. That could have resulted - in misclassifying entries as data rather than schema, with undesirable - results in a schema-only or data-only dump. - - - - Note that this change has user-visible results in the output - of pg_restore --list. - - - - - - Rename pg_rewind's - copy_file_range function to avoid conflict - with new Linux system call of that name (Andres Freund) - - - - This change prevents build failures with newer glibc versions. - - - - - - In ecpg, detect indicator arrays that do - not have the correct length and report an error (David Rader) - - - - - - Change the behavior of contrib/cube's - cube ~> int - operator to make it compatible with KNN search (Alexander Korotkov) - - - - The meaning of the second argument (the dimension selector) has been - changed to make it predictable which value is selected even when - dealing with cubes of varying dimensionalities. - - - - This is an incompatible change, but since the point of the operator - was to be used in KNN searches, it seems rather useless as-is. - After installing this update, any expression indexes or materialized - views using this operator will need to be reindexed/refreshed. - - - - - - Avoid triggering a libc assertion - in contrib/hstore, due to use - of memcpy() with equal source and destination - pointers (Tomas Vondra) - - - - - - Fix incorrect display of tuples' null bitmaps - in contrib/pageinspect (Maksim Milyutin) - - - - - - In contrib/postgres_fdw, avoid - outer pathkeys do not match mergeclauses - planner error when constructing a plan involving a remote join - (Robert Haas) - - - - - - Provide modern examples of how to auto-start Postgres on macOS - (Tom Lane) - - - - The scripts in contrib/start-scripts/osx use - infrastructure that's been deprecated for over a decade, and which no - longer works at all in macOS releases of the last couple of years. - Add a new subdirectory contrib/start-scripts/macos - containing scripts that use the newer launchd - infrastructure. - - - - - - Fix incorrect selection of configuration-specific libraries for - OpenSSL on Windows (Andrew Dunstan) - - - - - - Support linking to MinGW-built versions of libperl (Noah Misch) - - - - This allows building PL/Perl with some common Perl distributions for - Windows. - - - - - - Fix MSVC build to test whether 32-bit libperl - needs -D_USE_32BIT_TIME_T (Noah Misch) - - - - Available Perl distributions are inconsistent about what they expect, - and lack any reliable means of reporting it, so resort to a build-time - test on what the library being used actually does. - - - - - - On Windows, install the crash dump handler earlier in postmaster - startup (Takayuki Tsunakawa) - - - - This may allow collection of a core dump for some early-startup - failures that did not produce a dump before. - - - - - - On Windows, avoid encoding-conversion-related crashes when emitting - messages very early in postmaster startup (Takayuki Tsunakawa) - - - - - - Use our existing Motorola 68K spinlock code on OpenBSD as - well as NetBSD (David Carlier) - - - - - - Add support for spinlocks on Motorola 88K (David Carlier) - - - - - - Update time zone data files to tzdata - release 2018c for DST law changes in Brazil, Sao Tome and Principe, - plus historical corrections for Bolivia, Japan, and South Sudan. - The US/Pacific-New zone has been removed (it was - only an alias for America/Los_Angeles anyway). - - - - - - - - - - Release 9.6.6 - - - Release date: - 2017-11-09 - - - - This release contains a variety of fixes from 9.6.5. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.6 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if you use BRIN indexes, see the fourth changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.6.4, - see . - - - - - Changes - - - - - - Ensure that INSERT ... ON CONFLICT DO UPDATE checks - table permissions and RLS policies in all cases (Dean Rasheed) - - - - The update path of INSERT ... ON CONFLICT DO UPDATE - requires SELECT permission on the columns of the - arbiter index, but it failed to check for that in the case of an - arbiter specified by constraint name. - In addition, for a table with row level security enabled, it failed to - check updated rows against the table's SELECT - policies (regardless of how the arbiter index was specified). - (CVE-2017-15099) - - - - - - Fix crash due to rowtype mismatch - in json{b}_populate_recordset() - (Michael Paquier, Tom Lane) - - - - These functions used the result rowtype specified in the FROM - ... AS clause without checking that it matched the actual - rowtype of the supplied tuple value. If it didn't, that would usually - result in a crash, though disclosure of server memory contents seems - possible as well. - (CVE-2017-15098) - - - - - - Fix sample server-start scripts to become $PGUSER - before opening $PGLOG (Noah Misch) - - - - Previously, the postmaster log file was opened while still running as - root. The database owner could therefore mount an attack against - another system user by making $PGLOG be a symbolic - link to some other file, which would then become corrupted by appending - log messages. - - - - By default, these scripts are not installed anywhere. Users who have - made use of them will need to manually recopy them, or apply the same - changes to their modified versions. If the - existing $PGLOG file is root-owned, it will need to - be removed or renamed out of the way before restarting the server with - the corrected script. - (CVE-2017-12172) - - - - - - Fix BRIN index summarization to handle concurrent table extension - correctly (Álvaro Herrera) - - - - Previously, a race condition allowed some table rows to be omitted from - the index. It may be necessary to reindex existing BRIN indexes to - recover from past occurrences of this problem. - - - - - - Fix possible failures during concurrent updates of a BRIN index - (Tom Lane) - - - - These race conditions could result in errors like invalid index - offnum or inconsistent range map. - - - - - - Fix crash when logical decoding is invoked from a SPI-using function, - in particular any function written in a PL language - (Tom Lane) - - - - - - Fix incorrect query results when multiple GROUPING - SETS columns contain the same simple variable (Tom Lane) - - - - - - Fix incorrect parallelization decisions for nested queries - (Amit Kapila, Kuntal Ghosh) - - - - - - Fix parallel query handling to not fail when a recently-used role is - dropped (Amit Kapila) - - - - - - Fix json_build_array(), - json_build_object(), and their jsonb - equivalents to handle explicit VARIADIC arguments - correctly (Michael Paquier) - - - - - - - Properly reject attempts to convert infinite float values to - type numeric (Tom Lane, KaiGai Kohei) - - - - Previously the behavior was platform-dependent. - - - - - - Fix corner-case crashes when columns have been added to the end of a - view (Tom Lane) - - - - - - Record proper dependencies when a view or rule - contains FieldSelect - or FieldStore expression nodes (Tom Lane) - - - - Lack of these dependencies could allow a column or data - type DROP to go through when it ought to fail, - thereby causing later uses of the view or rule to get errors. - This patch does not do anything to protect existing views/rules, - only ones created in the future. - - - - - - Correctly detect hashability of range data types (Tom Lane) - - - - The planner mistakenly assumed that any range type could be hashed - for use in hash joins or hash aggregation, but actually it must check - whether the range's subtype has hash support. This does not affect any - of the built-in range types, since they're all hashable anyway. - - - - - - - Correctly ignore RelabelType expression nodes - when determining relation distinctness (David Rowley) - - - - This allows the intended optimization to occur when a subquery has - a result column of type varchar. - - - - - - Prevent sharing transition states between ordered-set aggregates - (David Rowley) - - - - This causes a crash with the built-in ordered-set aggregates, and - probably with user-written ones as well. v11 and later will include - provisions for dealing with such cases safely, but in released - branches, just disable the optimization. - - - - - - Prevent idle_in_transaction_session_timeout from - being ignored when a statement_timeout occurred - earlier (Lukas Fittl) - - - - - - Fix low-probability loss of NOTIFY messages due to - XID wraparound (Marko Tiikkaja, Tom Lane) - - - - If a session executed no queries, but merely listened for - notifications, for more than 2 billion transactions, it started to miss - some notifications from concurrently-committing transactions. - - - - - - - Avoid SIGBUS crash on Linux when a DSM memory - request exceeds the space available in tmpfs - (Thomas Munro) - - - - - - Reduce the frequency of data flush requests during bulk file copies to - avoid performance problems on macOS, particularly with its new APFS - file system (Tom Lane) - - - - - - - Prevent low-probability crash in processing of nested trigger firings - (Tom Lane) - - - - - - Allow COPY's FREEZE option to - work when the transaction isolation level is REPEATABLE - READ or higher (Noah Misch) - - - - This case was unintentionally broken by a previous bug fix. - - - - - - - Correctly restore the umask setting when file creation fails - in COPY or lo_export() - (Peter Eisentraut) - - - - - - - Give a better error message for duplicate column names - in ANALYZE (Nathan Bossart) - - - - - - - Add missing cases in GetCommandLogLevel(), - preventing errors when certain SQL commands are used while - log_statement is set to ddl - (Michael Paquier) - - - - - - - Fix mis-parsing of the last line in a - non-newline-terminated pg_hba.conf file - (Tom Lane) - - - - - - Fix AggGetAggref() to return the - correct Aggref nodes to aggregate final - functions whose transition calculations have been merged (Tom Lane) - - - - - - - Fix pg_dump to ensure that it - emits GRANT commands in a valid order - (Stephen Frost) - - - - - - Fix pg_basebackup's matching of tablespace - paths to canonicalize both paths before comparing (Michael Paquier) - - - - This is particularly helpful on Windows. - - - - - - Fix libpq to not require user's home - directory to exist (Tom Lane) - - - - In v10, failure to find the home directory while trying to - read ~/.pgpass was treated as a hard error, - but it should just cause that file to not be found. Both v10 and - previous release branches made the same mistake when - reading ~/.pg_service.conf, though this was less - obvious since that file is not sought unless a service name is - specified. - - - - - - - Fix libpq to guard against integer - overflow in the row count of a PGresult - (Michael Paquier) - - - - - - - Fix ecpg's handling of out-of-scope cursor - declarations with pointer or array variables (Michael Meskes) - - - - - - In ecpglib, correctly handle backslashes in string literals depending - on whether standard_conforming_strings is set - (Tsunakawa Takayuki) - - - - - - Make ecpglib's Informix-compatibility mode ignore fractional digits in - integer input strings, as expected (Gao Zengqi, Michael Meskes) - - - - - - - Fix ecpg's regression tests to work reliably - on Windows (Christian Ullrich, Michael Meskes) - - - - - - Fix missing temp-install prerequisites - for check-like Make targets (Noah Misch) - - - - Some non-default test procedures that are meant to work - like make check failed to ensure that the temporary - installation was up to date. - - - - - - - Sync our copy of the timezone library with IANA release tzcode2017c - (Tom Lane) - - - - This fixes various issues; the only one likely to be user-visible - is that the default DST rules for a POSIX-style zone name, if - no posixrules file exists in the timezone data - directory, now match current US law rather than what it was a dozen - years ago. - - - - - - Update time zone data files to tzdata - release 2017c for DST law changes in Fiji, Namibia, Northern Cyprus, - Sudan, Tonga, and Turks & Caicos Islands, plus historical - corrections for Alaska, Apia, Burma, Calcutta, Detroit, Ireland, - Namibia, and Pago Pago. - - - - - - - - - - Release 9.6.5 - - - Release date: - 2017-08-31 - - - - This release contains a small number of fixes from 9.6.4. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.5 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if you are upgrading from a version earlier than 9.6.4, - see . - - - - - Changes - - - - - - - Show foreign tables - in information_schema.table_privileges - view (Peter Eisentraut) - - - - All other relevant information_schema views include - foreign tables, but this one ignored them. - - - - Since this view definition is installed by initdb, - merely upgrading will not fix the problem. If you need to fix this - in an existing installation, you can, as a superuser, do this - in psql: - -SET search_path TO information_schema; -CREATE OR REPLACE VIEW table_privileges AS - SELECT CAST(u_grantor.rolname AS sql_identifier) AS grantor, - CAST(grantee.rolname AS sql_identifier) AS grantee, - CAST(current_database() AS sql_identifier) AS table_catalog, - CAST(nc.nspname AS sql_identifier) AS table_schema, - CAST(c.relname AS sql_identifier) AS table_name, - CAST(c.prtype AS character_data) AS privilege_type, - CAST( - CASE WHEN - -- object owner always has grant options - pg_has_role(grantee.oid, c.relowner, 'USAGE') - OR c.grantable - THEN 'YES' ELSE 'NO' END AS yes_or_no) AS is_grantable, - CAST(CASE WHEN c.prtype = 'SELECT' THEN 'YES' ELSE 'NO' END AS yes_or_no) AS with_hierarchy - - FROM ( - SELECT oid, relname, relnamespace, relkind, relowner, (aclexplode(coalesce(relacl, acldefault('r', relowner)))).* FROM pg_class - ) AS c (oid, relname, relnamespace, relkind, relowner, grantor, grantee, prtype, grantable), - pg_namespace nc, - pg_authid u_grantor, - ( - SELECT oid, rolname FROM pg_authid - UNION ALL - SELECT 0::oid, 'PUBLIC' - ) AS grantee (oid, rolname) - - WHERE c.relnamespace = nc.oid - AND c.relkind IN ('r', 'v', 'f') - AND c.grantee = grantee.oid - AND c.grantor = u_grantor.oid - AND c.prtype IN ('INSERT', 'SELECT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER') - AND (pg_has_role(u_grantor.oid, 'USAGE') - OR pg_has_role(grantee.oid, 'USAGE') - OR grantee.rolname = 'PUBLIC'); - - This must be repeated in each database to be fixed, - including template0. - - - - - - - Clean up handling of a fatal exit (e.g., due to receipt - of SIGTERM) that occurs while trying to execute - a ROLLBACK of a failed transaction (Tom Lane) - - - - This situation could result in an assertion failure. In production - builds, the exit would still occur, but it would log an unexpected - message about cannot drop active portal. - - - - - - - Remove assertion that could trigger during a fatal exit (Tom Lane) - - - - - - - Correctly identify columns that are of a range type or domain type over - a composite type or domain type being searched for (Tom Lane) - - - - Certain ALTER commands that change the definition of a - composite type or domain type are supposed to fail if there are any - stored values of that type in the database, because they lack the - infrastructure needed to update or check such values. Previously, - these checks could miss relevant values that are wrapped inside range - types or sub-domains, possibly allowing the database to become - inconsistent. - - - - - - - Prevent crash when passing fixed-length pass-by-reference data types - to parallel worker processes (Tom Lane) - - - - - - - Fix crash in pg_restore when using parallel mode and - using a list file to select a subset of items to restore - (Fabrízio de Royes Mello) - - - - - - - Change ecpg's parser to allow RETURNING - clauses without attached C variables (Michael Meskes) - - - - This allows ecpg programs to contain SQL constructs - that use RETURNING internally (for example, inside a CTE) - rather than using it to define values to be returned to the client. - - - - - - - Change ecpg's parser to recognize backslash - continuation of C preprocessor command lines (Michael Meskes) - - - - - - - Improve selection of compiler flags for PL/Perl on Windows (Tom Lane) - - - - This fix avoids possible crashes of PL/Perl due to inconsistent - assumptions about the width of time_t values. - A side-effect that may be visible to extension developers is - that _USE_32BIT_TIME_T is no longer defined globally - in PostgreSQL Windows builds. This is not expected - to cause problems, because type time_t is not used - in any PostgreSQL API definitions. - - - - - - - Fix make check to behave correctly when invoked via a - non-GNU make program (Thomas Munro) - - - - - - - - - - Release 9.6.4 - - - Release date: - 2017-08-10 - - - - This release contains a variety of fixes from 9.6.3. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.4 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.6.3, - see . - - - - - Changes - - - - - - - Further restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Noah Misch) - - - - The fix for CVE-2017-7486 was incorrect: it allowed a user - to see the options in her own user mapping, even if she did not - have USAGE permission on the associated foreign server. - Such options might include a password that had been provided by the - server owner rather than the user herself. - Since information_schema.user_mapping_options does not - show the options in such cases, pg_user_mappings - should not either. - (CVE-2017-7547) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - you will need to do the following: - - - - - - Restart the postmaster after adding allow_system_table_mods - = true to postgresql.conf. (In versions - supporting ALTER SYSTEM, you can use that to make the - configuration change, but you'll still need a restart.) - - - - - - In each database of the cluster, - run the following commands as superuser: - -SET search_path = pg_catalog; -CREATE OR REPLACE VIEW pg_user_mappings AS - SELECT - U.oid AS umid, - S.oid AS srvid, - S.srvname AS srvname, - U.umuser AS umuser, - CASE WHEN U.umuser = 0 THEN - 'public' - ELSE - A.rolname - END AS usename, - CASE WHEN (U.umuser <> 0 AND A.rolname = current_user - AND (pg_has_role(S.srvowner, 'USAGE') - OR has_server_privilege(S.oid, 'USAGE'))) - OR (U.umuser = 0 AND pg_has_role(S.srvowner, 'USAGE')) - OR (SELECT rolsuper FROM pg_authid WHERE rolname = current_user) - THEN U.umoptions - ELSE NULL END AS umoptions - FROM pg_user_mapping U - LEFT JOIN pg_authid A ON (A.oid = U.umuser) JOIN - pg_foreign_server S ON (U.umserver = S.oid); - - - - - - - Do not forget to include the template0 - and template1 databases, or the vulnerability will still - exist in databases you create later. To fix template0, - you'll need to temporarily make it accept connections. - In PostgreSQL 9.5 and later, you can use - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS true; - - and then after fixing template0, undo that with - -ALTER DATABASE template0 WITH ALLOW_CONNECTIONS false; - - In prior versions, instead use - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - - Finally, remove the allow_system_table_mods configuration - setting, and again restart the postmaster. - - - - - - - - - Disallow empty passwords in all password-based authentication methods - (Heikki Linnakangas) - - - - libpq ignores empty password specifications, and does - not transmit them to the server. So, if a user's password has been - set to the empty string, it's impossible to log in with that password - via psql or other libpq-based - clients. An administrator might therefore believe that setting the - password to empty is equivalent to disabling password login. - However, with a modified or non-libpq-based client, - logging in could be possible, depending on which authentication - method is configured. In particular the most common - method, md5, accepted empty passwords. - Change the server to reject empty passwords in all cases. - (CVE-2017-7546) - - - - - - - Make lo_put() check for UPDATE privilege on - the target large object (Tom Lane, Michael Paquier) - - - - lo_put() should surely require the same permissions - as lowrite(), but the check was missing, allowing any - user to change the data in a large object. - (CVE-2017-7548) - - - - - - - Correct the documentation about the process for upgrading standby - servers with pg_upgrade (Bruce Momjian) - - - - The previous documentation instructed users to start/stop the primary - server after running pg_upgrade but before syncing - the standby servers. This sequence is unsafe. - - - - - - - Fix concurrent locking of tuple update chains (Álvaro Herrera) - - - - If several sessions concurrently lock a tuple update chain with - nonconflicting lock modes using an old snapshot, and they all - succeed, it was possible for some of them to nonetheless fail (and - conclude there is no live tuple version) due to a race condition. - This had consequences such as foreign-key checks failing to see a - tuple that definitely exists but is being updated concurrently. - - - - - - - Fix potential data corruption when freezing a tuple whose XMAX is a - multixact with exactly one still-interesting member (Teodor Sigaev) - - - - - - - Avoid integer overflow and ensuing crash when sorting more than one - billion tuples in-memory (Sergey Koposov) - - - - - - - On Windows, retry process creation if we fail to reserve the address - range for our shared memory in the new process (Tom Lane, Amit - Kapila) - - - - This is expected to fix infrequent child-process-launch failures that - are probably due to interference from antivirus products. - - - - - - - Fix low-probability corruption of shared predicate-lock hash table - in Windows builds (Thomas Munro, Tom Lane) - - - - - - - Avoid logging clean closure of an SSL connection as though - it were a connection reset (Michael Paquier) - - - - - - - Prevent sending SSL session tickets to clients (Tom Lane) - - - - This fix prevents reconnection failures with ticket-aware client-side - SSL code. - - - - - - - Fix code for setting on - Solaris (Tom Lane) - - - - - - - Fix statistics collector to honor inquiry messages issued just after - a postmaster shutdown and immediate restart (Tom Lane) - - - - Statistics inquiries issued within half a second of the previous - postmaster shutdown were effectively ignored. - - - - - - - Ensure that the statistics collector's receive buffer size is at - least 100KB (Tom Lane) - - - - This reduces the risk of dropped statistics data on older platforms - whose default receive buffer size is less than that. - - - - - - - Fix possible creation of an invalid WAL segment when a standby is - promoted just after it processes an XLOG_SWITCH WAL - record (Andres Freund) - - - - - - - Fix walsender to exit promptly when client requests - shutdown (Tom Lane) - - - - - - - Fix SIGHUP and SIGUSR1 handling in - walsender processes (Petr Jelinek, Andres Freund) - - - - - - - Prevent walsender-triggered panics during shutdown checkpoints - (Andres Freund, Michael Paquier) - - - - - - - Fix unnecessarily slow restarts of walreceiver - processes due to race condition in postmaster (Tom Lane) - - - - - - - Fix leakage of small subtransactions spilled to disk during logical - decoding (Andres Freund) - - - - This resulted in temporary files consuming excessive disk space. - - - - - - - Reduce the work needed to build snapshots during creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - The previous algorithm was infeasibly expensive on a server with a - lot of open transactions. - - - - - - - Fix race condition that could indefinitely delay creation of - logical-decoding slots (Andres Freund, Petr Jelinek) - - - - - - - Reduce overhead in processing syscache invalidation events (Tom Lane) - - - - This is particularly helpful for logical decoding, which triggers - frequent cache invalidation. - - - - - - - Remove incorrect heuristic used in some cases to estimate join - selectivity based on the presence of foreign-key constraints - (David Rowley) - - - - In some cases where a multi-column foreign key constraint existed but - did not exactly match a query's join structure, the planner used an - estimation heuristic that turns out not to work well at all. Revert - such cases to the way they were estimated before 9.6. - - - - - - - Fix cases where an INSERT or UPDATE assigns - to more than one element of a column that is of domain-over-array - type (Tom Lane) - - - - - - - Allow window functions to be used in sub-SELECTs that - are within the arguments of an aggregate function (Tom Lane) - - - - - - - Ensure that a view's CHECK OPTIONS clause is enforced - properly when the underlying table is a foreign table (Etsuro Fujita) - - - - Previously, the update might get pushed entirely to the foreign - server, but the need to verify the view conditions was missed if so. - - - - - - - Move autogenerated array types out of the way during - ALTER ... RENAME (Vik Fearing) - - - - Previously, we would rename a conflicting autogenerated array type - out of the way during CREATE; this fix extends that - behavior to renaming operations. - - - - - - - Fix dangling pointer in ALTER TABLE when there is a - comment on a constraint belonging to the table (David Rowley) - - - - Re-applying the comment to the reconstructed constraint could fail - with a weird error message, or even crash. - - - - - - - Ensure that ALTER USER ... SET accepts all the syntax - variants that ALTER ROLE ... SET does (Peter Eisentraut) - - - - - - - Allow a foreign table's CHECK constraints to be - initially NOT VALID (Amit Langote) - - - - CREATE TABLE silently drops NOT VALID - specifiers for CHECK constraints, reasoning that the - table must be empty so the constraint can be validated immediately. - But this is wrong for CREATE FOREIGN TABLE, where there's - no reason to suppose that the underlying table is empty, and even if - it is it's no business of ours to decide that the constraint can be - treated as valid going forward. Skip this optimization for - foreign tables. - - - - - - - Properly update dependency info when changing a datatype I/O - function's argument or return type from opaque to the - correct type (Heikki Linnakangas) - - - - CREATE TYPE updates I/O functions declared in this - long-obsolete style, but it forgot to record a dependency on the - type, allowing a subsequent DROP TYPE to leave broken - function definitions behind. - - - - - - - Allow parallelism in the query plan when COPY copies from - a query's result (Andres Freund) - - - - - - - Reduce memory usage when ANALYZE processes - a tsvector column (Heikki Linnakangas) - - - - - - - Fix unnecessary precision loss and sloppy rounding when multiplying - or dividing money values by integers or floats (Tom Lane) - - - - - - - Tighten checks for whitespace in functions that parse identifiers, - such as regprocedurein() (Tom Lane) - - - - Depending on the prevailing locale, these functions could - misinterpret fragments of multibyte characters as whitespace. - - - - - - - Use relevant #define symbols from Perl while - compiling PL/Perl (Ashutosh Sharma, Tom Lane) - - - - This avoids portability problems, typically manifesting as - a handshake mismatch during library load, when working with - recent Perl versions. - - - - - - - In libpq, reset GSS/SASL and SSPI authentication - state properly after a failed connection attempt (Michael Paquier) - - - - Failure to do this meant that when falling back from SSL to non-SSL - connections, a GSS/SASL failure in the SSL attempt would always cause - the non-SSL attempt to fail. SSPI did not fail, but it leaked memory. - - - - - - - In psql, fix failure when COPY FROM STDIN - is ended with a keyboard EOF signal and then another COPY - FROM STDIN is attempted (Thomas Munro) - - - - This misbehavior was observed on BSD-derived platforms (including - macOS), but not on most others. - - - - - - - Fix pg_dump and pg_restore to - emit REFRESH MATERIALIZED VIEW commands last (Tom Lane) - - - - This prevents errors during dump/restore when a materialized view - refers to tables owned by a different user. - - - - - - - Improve pg_dump/pg_restore's - reporting of error conditions originating in zlib - (Vladimir Kunschikov, Álvaro Herrera) - - - - - - - Fix pg_dump with the option to - drop event triggers as expected (Tom Lane) - - - - It also now correctly assigns ownership of event triggers; before, - they were restored as being owned by the superuser running the - restore script. - - - - - - - Fix pg_dump with the option to not - fail when the public schema doesn't exist (Stephen Frost) - - - - - - - Fix pg_dump to not emit invalid SQL for an empty - operator class (Daniel Gustafsson) - - - - - - - Fix pg_dump output to stdout on Windows (Kuntal Ghosh) - - - - A compressed plain-text dump written to stdout would contain corrupt - data due to failure to put the file descriptor into binary mode. - - - - - - - Fix pg_get_ruledef() to print correct output for - the ON SELECT rule of a view whose columns have been - renamed (Tom Lane) - - - - In some corner cases, pg_dump relies - on pg_get_ruledef() to dump views, so that this error - could result in dump/reload failures. - - - - - - - Fix dumping of outer joins with empty constraints, such as the result - of a NATURAL LEFT JOIN with no common columns (Tom Lane) - - - - - - - Fix dumping of function expressions in the FROM clause in - cases where the expression does not deparse into something that looks - like a function call (Tom Lane) - - - - - - - Fix pg_basebackup output to stdout on Windows - (Haribabu Kommi) - - - - A backup written to stdout would contain corrupt data due to failure - to put the file descriptor into binary mode. - - - - - - - Fix pg_rewind to correctly handle files exceeding 2GB - (Kuntal Ghosh, Michael Paquier) - - - - Ordinarily such files won't appear in PostgreSQL data - directories, but they could be present in some cases. - - - - - - - Fix pg_upgrade to ensure that the ending WAL record - does not have = minimum - (Bruce Momjian) - - - - This condition could prevent upgraded standby servers from - reconnecting. - - - - - - - Fix pg_xlogdump's computation of WAL record length - (Andres Freund) - - - - - - - In postgres_fdw, re-establish connections to remote - servers after ALTER SERVER or ALTER USER - MAPPING commands (Kyotaro Horiguchi) - - - - This ensures that option changes affecting connection parameters will - be applied promptly. - - - - - - - In postgres_fdw, allow cancellation of remote - transaction control commands (Robert Haas, Rafia Sabih) - - - - This change allows us to quickly escape a wait for an unresponsive - remote server in many more cases than previously. - - - - - - - Increase MAX_SYSCACHE_CALLBACKS to provide more room for - extensions (Tom Lane) - - - - - - - Always use , not , when building - shared libraries with gcc (Tom Lane) - - - - This supports larger extension libraries on platforms where it makes - a difference. - - - - - - - In MSVC builds, handle the case where the openssl - library is not within a VC subdirectory (Andrew Dunstan) - - - - - - - In MSVC builds, add proper include path for libxml2 - header files (Andrew Dunstan) - - - - This fixes a former need to move things around in standard Windows - installations of libxml2. - - - - - - - In MSVC builds, recognize a Tcl library that is - named tcl86.lib (Noah Misch) - - - - - - - In MSVC builds, honor PROVE_FLAGS settings - on vcregress.pl's command line (Andrew Dunstan) - - - - - - - - - - Release 9.6.3 - - - Release date: - 2017-05-11 - - - - This release contains a variety of fixes from 9.6.2. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.3 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if you use foreign data servers that make use of user - passwords for authentication, see the first changelog entry below. - - - - Also, if you are using third-party replication tools that depend - on logical decoding, see the fourth changelog entry below. - - - - Also, if you are upgrading from a version earlier than 9.6.2, - see . - - - - - Changes - - - - - - - Restrict visibility - of pg_user_mappings.umoptions, to - protect passwords stored as user mapping options - (Michael Paquier, Feike Steenbergen) - - - - The previous coding allowed the owner of a foreign server object, - or anyone he has granted server USAGE permission to, - to see the options for all user mappings associated with that server. - This might well include passwords for other users. - Adjust the view definition to match the behavior of - information_schema.user_mapping_options, namely that - these options are visible to the user being mapped, or if the mapping - is for PUBLIC and the current user is the server - owner, or if the current user is a superuser. - (CVE-2017-7486) - - - - By itself, this patch will only fix the behavior in newly initdb'd - databases. If you wish to apply this change in an existing database, - follow the corrected procedure shown in the changelog entry for - CVE-2017-7547, in . - - - - - - - Prevent exposure of statistical information via leaky operators - (Peter Eisentraut) - - - - Some selectivity estimation functions in the planner will apply - user-defined operators to values obtained - from pg_statistic, such as most common values and - histogram entries. This occurs before table permissions are checked, - so a nefarious user could exploit the behavior to obtain these values - for table columns he does not have permission to read. To fix, - fall back to a default estimate if the operator's implementation - function is not certified leak-proof and the calling user does not have - permission to read the table column whose statistics are needed. - At least one of these criteria is satisfied in most cases in practice. - (CVE-2017-7484) - - - - - - - Restore libpq's recognition of - the PGREQUIRESSL environment variable (Daniel Gustafsson) - - - - Processing of this environment variable was unintentionally dropped - in PostgreSQL 9.3, but its documentation remained. - This creates a security hazard, since users might be relying on the - environment variable to force SSL-encrypted connections, but that - would no longer be guaranteed. Restore handling of the variable, - but give it lower priority than PGSSLMODE, to avoid - breaking configurations that work correctly with post-9.3 code. - (CVE-2017-7485) - - - - - - - Fix possibly-invalid initial snapshot during logical decoding - (Petr Jelinek, Andres Freund) - - - - The initial snapshot created for a logical decoding replication slot - was potentially incorrect. This could cause third-party tools that - use logical decoding to copy incomplete/inconsistent initial data. - This was more likely to happen if the source server was busy at the - time of slot creation, or if another logical slot already existed. - - - - If you are using a replication tool that depends on logical decoding, - and it should have copied a nonempty data set at the start of - replication, it is advisable to recreate the replica after - installing this update, or to verify its contents against the source - server. - - - - - - - Fix possible corruption of init forks of unlogged indexes - (Robert Haas, Michael Paquier) - - - - This could result in an unlogged index being set to an invalid state - after a crash and restart. Such a problem would persist until the - index was dropped and rebuilt. - - - - - - - Fix incorrect reconstruction of pg_subtrans entries - when a standby server replays a prepared but uncommitted two-phase - transaction (Tom Lane) - - - - In most cases this turned out to have no visible ill effects, but in - corner cases it could result in circular references - in pg_subtrans, potentially causing infinite loops - in queries that examine rows modified by the two-phase transaction. - - - - - - - Avoid possible crash in walsender due to failure - to initialize a string buffer (Stas Kelvich, Fujii Masao) - - - - - - - Fix possible crash when rescanning a nearest-neighbor index-only scan - on a GiST index (Tom Lane) - - - - - - - Prevent delays in postmaster's launching of multiple parallel worker - processes (Tom Lane) - - - - There could be a significant delay (up to tens of seconds) before - satisfying a query's request for more than one worker process, or when - multiple queries requested workers simultaneously. On most platforms - this required unlucky timing, but on some it was the typical case. - - - - - - - Fix postmaster's handling of fork() failure for a - background worker process (Tom Lane) - - - - Previously, the postmaster updated portions of its state as though - the process had been launched successfully, resulting in subsequent - confusion. - - - - - - - Fix possible no relation entry for relid 0 error when - planning nested set operations (Tom Lane) - - - - - - - Fix assorted minor issues in planning of parallel queries (Robert Haas) - - - - - - - Avoid applying physical targetlist optimization to custom - scans (Dmitry Ivanov, Tom Lane) - - - - This optimization supposed that retrieving all columns of a tuple - is inexpensive, which is true for ordinary Postgres tuples; but it - might not be the case for a custom scan provider. - - - - - - - Use the correct sub-expression when applying a FOR ALL - row-level-security policy (Stephen Frost) - - - - In some cases the WITH CHECK restriction would be applied - when the USING restriction is more appropriate. - - - - - - - Ensure parsing of queries in extension scripts sees the results of - immediately-preceding DDL (Julien Rouhaud, Tom Lane) - - - - Due to lack of a cache flush step between commands in an extension - script file, non-utility queries might not see the effects of an - immediately preceding catalog change, such as ALTER TABLE - ... RENAME. - - - - - - - Skip tablespace privilege checks when ALTER TABLE ... ALTER - COLUMN TYPE rebuilds an existing index (Noah Misch) - - - - The command failed if the calling user did not currently have - CREATE privilege for the tablespace containing the index. - That behavior seems unhelpful, so skip the check, allowing the - index to be rebuilt where it is. - - - - - - - Fix ALTER TABLE ... VALIDATE CONSTRAINT to not recurse - to child tables when the constraint is marked NO INHERIT - (Amit Langote) - - - - This fix prevents unwanted constraint does not exist failures - when no matching constraint is present in the child tables. - - - - - - - Avoid dangling pointer in COPY ... TO when row-level - security is active for the source table (Tom Lane) - - - - Usually this had no ill effects, but sometimes it would cause - unexpected errors or crashes. - - - - - - - Avoid accessing an already-closed relcache entry in CLUSTER - and VACUUM FULL (Tom Lane) - - - - With some bad luck, this could lead to indexes on the target - relation getting rebuilt with the wrong persistence setting. - - - - - - - Fix VACUUM to account properly for pages that could not - be scanned due to conflicting page pins (Andrew Gierth) - - - - This tended to lead to underestimation of the number of tuples in - the table. In the worst case of a small heavily-contended - table, VACUUM could incorrectly report that the table - contained no tuples, leading to very bad planning choices. - - - - - - - Ensure that bulk-tuple-transfer loops within a hash join are - interruptible by query cancel requests (Tom Lane, Thomas Munro) - - - - - - - Fix incorrect support for certain box operators in SP-GiST - (Nikita Glukhov) - - - - SP-GiST index scans using the operators &< - &> &<| and |&> - would yield incorrect answers. - - - - - - - Fix integer-overflow problems in interval comparison (Kyotaro - Horiguchi, Tom Lane) - - - - The comparison operators for type interval could yield wrong - answers for intervals larger than about 296000 years. Indexes on - columns containing such large values should be reindexed, since they - may be corrupt. - - - - - - - Fix cursor_to_xml() to produce valid output - with tableforest = false - (Thomas Munro, Peter Eisentraut) - - - - Previously it failed to produce a wrapping <table> - element. - - - - - - - Fix roundoff problems in float8_timestamptz() - and make_interval() (Tom Lane) - - - - These functions truncated, rather than rounded, when converting a - floating-point value to integer microseconds; that could cause - unexpectedly off-by-one results. - - - - - - - Fix pg_get_object_address() to handle members of operator - families correctly (Álvaro Herrera) - - - - - - - Fix cancelling of pg_stop_backup() when attempting to stop - a non-exclusive backup (Michael Paquier, David Steele) - - - - If pg_stop_backup() was cancelled while waiting for a - non-exclusive backup to end, related state was left inconsistent; - a new exclusive backup could not be started, and there were other minor - problems. - - - - - - - Improve performance of pg_timezone_names view - (Tom Lane, David Rowley) - - - - - - - Reduce memory management overhead for contexts containing many large - blocks (Tom Lane) - - - - - - - Fix sloppy handling of corner-case errors from lseek() - and close() (Tom Lane) - - - - Neither of these system calls are likely to fail in typical situations, - but if they did, fd.c could get quite confused. - - - - - - - Fix incorrect check for whether postmaster is running as a Windows - service (Michael Paquier) - - - - This could result in attempting to write to the event log when that - isn't accessible, so that no logging happens at all. - - - - - - - Fix ecpg to support COMMIT PREPARED - and ROLLBACK PREPARED (Masahiko Sawada) - - - - - - - Fix a double-free error when processing dollar-quoted string literals - in ecpg (Michael Meskes) - - - - - - - Fix pgbench to handle the combination - of and options correctly - (Fabien Coelho) - - - - - - - Fix pgbench to honor the long-form option - spelling , as per its documentation (Tom Lane) - - - - - - - Fix pg_dump/pg_restore to correctly - handle privileges for the public schema when - using option (Stephen Frost) - - - - Other schemas start out with no privileges granted, - but public does not; this requires special-case treatment - when it is dropped and restored due to the option. - - - - - - - In pg_dump, fix incorrect schema and owner marking for - comments and security labels of some types of database objects - (Giuseppe Broccolo, Tom Lane) - - - - In simple cases this caused no ill effects; but for example, a - schema-selective restore might omit comments it should include, because - they were not marked as belonging to the schema of their associated - object. - - - - - - - Fix typo in pg_dump's query for initial privileges - of a procedural language (Peter Eisentraut) - - - - This resulted in pg_dump always believing that the - language had no initial privileges. Since that's true for most - procedural languages, ill effects from this bug are probably rare. - - - - - - - Avoid emitting an invalid list file in pg_restore -l - when SQL object names contain newlines (Tom Lane) - - - - Replace newlines by spaces, which is sufficient to make the output - valid for pg_restore -L's purposes. - - - - - - - Fix pg_upgrade to transfer comments and security labels - attached to large objects (blobs) (Stephen Frost) - - - - Previously, blobs were correctly transferred to the new database, but - any comments or security labels attached to them were lost. - - - - - - - Improve error handling - in contrib/adminpack's pg_file_write() - function (Noah Misch) - - - - Notably, it failed to detect errors reported - by fclose(). - - - - - - - In contrib/dblink, avoid leaking the previous unnamed - connection when establishing a new unnamed connection (Joe Conway) - - - - - - - Fix contrib/pg_trgm's extraction of trigrams from regular - expressions (Tom Lane) - - - - In some cases it would produce a broken data structure that could never - match anything, leading to GIN or GiST indexscans that use a trigram - index not finding any matches to the regular expression. - - - - - - - In contrib/postgres_fdw, allow join conditions that - contain shippable extension-provided functions to be pushed to the - remote server (David Rowley, Ashutosh Bapat) - - - - - - - Support Tcl 8.6 in MSVC builds (Álvaro Herrera) - - - - - - - Sync our copy of the timezone library with IANA release tzcode2017b - (Tom Lane) - - - - This fixes a bug affecting some DST transitions in January 2038. - - - - - - - Update time zone data files to tzdata release 2017b - for DST law changes in Chile, Haiti, and Mongolia, plus historical - corrections for Ecuador, Kazakhstan, Liberia, and Spain. - Switch to numeric abbreviations for numerous time zones in South - America, the Pacific and Indian oceans, and some Asian and Middle - Eastern countries. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - - - - Use correct daylight-savings rules for POSIX-style time zone names - in MSVC builds (David Rowley) - - - - The Microsoft MSVC build scripts neglected to install - the posixrules file in the timezone directory tree. - This resulted in the timezone code falling back to its built-in - rule about what DST behavior to assume for a POSIX-style time zone - name. For historical reasons that still corresponds to the DST rules - the USA was using before 2007 (i.e., change on first Sunday in April - and last Sunday in October). With this fix, a POSIX-style zone name - will use the current and historical DST transition dates of - the US/Eastern zone. If you don't want that, remove - the posixrules file, or replace it with a copy of some - other zone file (see ). Note that - due to caching, you may need to restart the server to get such changes - to take effect. - - - - - - - - - - Release 9.6.2 - - - Release date: - 2017-02-09 - - - - This release contains a variety of fixes from 9.6.1. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.2 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if your installation has been affected by the bug described in - the first changelog entry below, then after updating you may need - to take action to repair corrupted indexes. - - - - Also, if you are upgrading from a version earlier than 9.6.1, - see . - - - - - Changes - - - - - - - Fix a race condition that could cause indexes built - with CREATE INDEX CONCURRENTLY to be corrupt - (Pavan Deolasee, Tom Lane) - - - - If CREATE INDEX CONCURRENTLY was used to build an index - that depends on a column not previously indexed, then rows - updated by transactions that ran concurrently with - the CREATE INDEX command could have received incorrect - index entries. If you suspect this may have happened, the most - reliable solution is to rebuild affected indexes after installing - this update. - - - - - - - Ensure that the special snapshot used for catalog scans is not - invalidated by premature data pruning (Tom Lane) - - - - Backends failed to account for this snapshot when advertising their - oldest xmin, potentially allowing concurrent vacuuming operations to - remove data that was still needed. This led to transient failures - along the lines of cache lookup failed for relation 1255. - - - - - - - Fix incorrect WAL logging for BRIN indexes (Kuntal Ghosh) - - - - The WAL record emitted for a BRIN revmap page when moving an - index tuple to a different page was incorrect. Replay would make the - related portion of the index useless, forcing it to be recomputed. - - - - - - - Unconditionally WAL-log creation of the init fork for an - unlogged table (Michael Paquier) - - - - Previously, this was skipped when - = minimal, but actually it's necessary even in that case - to ensure that the unlogged table is properly reset to empty after a - crash. - - - - - - - If the stats collector dies during hot standby, restart it (Takayuki - Tsunakawa) - - - - - - - Ensure that hot standby feedback works correctly when it's enabled at - standby server start (Ants Aasma, Craig Ringer) - - - - - - - Check for interrupts while hot standby is waiting for a conflicting - query (Simon Riggs) - - - - - - - Avoid constantly respawning the autovacuum launcher in a corner case - (Amit Khandekar) - - - - This fix avoids problems when autovacuum is nominally off and there - are some tables that require freezing, but all such tables are - already being processed by autovacuum workers. - - - - - - - Disallow setting the num_sync field to zero in - (Fujii Masao) - - - - The correct way to disable synchronous standby is to set the whole - value to an empty string. - - - - - - - Don't count background worker processes against a user's connection - limit (David Rowley) - - - - - - - Fix check for when an extension member object can be dropped (Tom Lane) - - - - Extension upgrade scripts should be able to drop member objects, - but this was disallowed for serial-column sequences, and possibly - other cases. - - - - - - - Fix tracking of initial privileges for extension member objects so - that it works correctly with ALTER EXTENSION ... ADD/DROP - (Stephen Frost) - - - - An object's current privileges at the time it is added to the - extension will now be considered its default privileges; only - later changes in its privileges will be dumped by - subsequent pg_dump runs. - - - - - - - Make sure ALTER TABLE preserves index tablespace - assignments when rebuilding indexes (Tom Lane, Michael Paquier) - - - - Previously, non-default settings - of could result in broken - indexes. - - - - - - - Fix incorrect updating of trigger function properties when changing a - foreign-key constraint's deferrability properties with ALTER - TABLE ... ALTER CONSTRAINT (Tom Lane) - - - - This led to odd failures during subsequent exercise of the foreign - key, as the triggers were fired at the wrong times. - - - - - - - Prevent dropping a foreign-key constraint if there are pending - trigger events for the referenced relation (Tom Lane) - - - - This avoids could not find trigger NNN - or relation NNN has no triggers errors. - - - - - - - Fix ALTER TABLE ... SET DATA TYPE ... USING when child - table has different column ordering than the parent - (Álvaro Herrera) - - - - Failure to adjust the column numbering in the USING - expression led to errors, - typically attribute N has wrong type. - - - - - - - Fix processing of OID column when a table with OIDs is associated to - a parent with OIDs via ALTER TABLE ... INHERIT (Amit - Langote) - - - - The OID column should be treated the same as regular user columns in - this case, but it wasn't, leading to odd behavior in later - inheritance changes. - - - - - - - Ensure that CREATE TABLE ... LIKE ... WITH OIDS creates - a table with OIDs, whether or not the LIKE-referenced - table(s) have OIDs (Tom Lane) - - - - - - - Fix CREATE OR REPLACE VIEW to update the view query - before attempting to apply the new view options (Dean Rasheed) - - - - Previously the command would fail if the new options were - inconsistent with the old view definition. - - - - - - - Report correct object identity during ALTER TEXT SEARCH - CONFIGURATION (Artur Zakirov) - - - - The wrong catalog OID was reported to extensions such as logical - decoding. - - - - - - - Fix commit timestamp mechanism to not fail when queried about - the special XIDs FrozenTransactionId - and BootstrapTransactionId (Craig Ringer) - - - - - - - Fix incorrect use of view reloptions as regular table reloptions (Tom - Lane) - - - - The symptom was spurious ON CONFLICT is not supported on table - ... used as a catalog table errors when the target - of INSERT ... ON CONFLICT is a view with cascade option. - - - - - - - Fix incorrect target lists can have at most N - entries complaint when using ON CONFLICT with - wide tables (Tom Lane) - - - - - - - Fix spurious query provides a value for a dropped column - errors during INSERT or UPDATE on a table - with a dropped column (Tom Lane) - - - - - - - Prevent multicolumn expansion of foo.* in - an UPDATE source expression (Tom Lane) - - - - This led to UPDATE target count mismatch --- internal - error. Now the syntax is understood as a whole-row variable, - as it would be in other contexts. - - - - - - - Ensure that column typmods are determined accurately for - multi-row VALUES constructs (Tom Lane) - - - - This fixes problems occurring when the first value in a column has a - determinable typmod (e.g., length for a varchar value) but - later values don't share the same limit. - - - - - - - Throw error for an unfinished Unicode surrogate pair at the end of a - Unicode string (Tom Lane) - - - - Normally, a Unicode surrogate leading character must be followed by a - Unicode surrogate trailing character, but the check for this was - missed if the leading character was the last character in a Unicode - string literal (U&'...') or Unicode identifier - (U&"..."). - - - - - - - Fix execution of DISTINCT and ordered aggregates when - multiple such aggregates are able to share the same transition state - (Heikki Linnakangas) - - - - - - - Fix implementation of phrase search operators in tsquery - (Tom Lane) - - - - Remove incorrect, and inconsistently-applied, rewrite rules that - tried to transform away AND/OR/NOT operators appearing below a PHRASE - operator; instead upgrade the execution engine to handle such cases - correctly. This fixes assorted strange behavior and possible crashes - for text search queries containing such combinations. Also fix - nested PHRASE operators to work sanely in combinations other than - simple left-deep trees, correct the behavior when removing stopwords - from a phrase search clause, and make sure that index searches behave - consistently with simple sequential-scan application of such queries. - - - - - - - Ensure that a purely negative text search query, such - as !foo, matches empty tsvectors (Tom Dunstan) - - - - Such matches were found by GIN index searches, but not by sequential - scans or GiST index searches. - - - - - - - Prevent crash when ts_rewrite() replaces a non-top-level - subtree with an empty query (Artur Zakirov) - - - - - - - Fix performance problems in ts_rewrite() (Tom Lane) - - - - - - - Fix ts_rewrite()'s handling of nested NOT operators - (Tom Lane) - - - - - - - Improve speed of user-defined aggregates that - use array_append() as transition function (Tom Lane) - - - - - - - Fix array_fill() to handle empty arrays properly (Tom Lane) - - - - - - - Fix possible crash in array_position() - or array_positions() when processing arrays of records - (Junseok Yang) - - - - - - - Fix one-byte buffer overrun in quote_literal_cstr() - (Heikki Linnakangas) - - - - The overrun occurred only if the input consisted entirely of single - quotes and/or backslashes. - - - - - - - Prevent multiple calls of pg_start_backup() - and pg_stop_backup() from running concurrently (Michael - Paquier) - - - - This avoids an assertion failure, and possibly worse things, if - someone tries to run these functions in parallel. - - - - - - - Disable transform that attempted to remove no-op AT TIME - ZONE conversions (Tom Lane) - - - - This resulted in wrong answers when the simplified expression was - used in an index condition. - - - - - - - Avoid discarding interval-to-interval casts - that aren't really no-ops (Tom Lane) - - - - In some cases, a cast that should result in zeroing out - low-order interval fields was mistakenly deemed to be a - no-op and discarded. An example is that casting from INTERVAL - MONTH to INTERVAL YEAR failed to clear the months field. - - - - - - - Fix crash if the number of workers available to a parallel query - decreases during a rescan (Andreas Seltenreich) - - - - - - - Fix bugs in transmitting GUC parameter values to parallel workers - (Michael Paquier, Tom Lane) - - - - - - - Allow statements prepared with PREPARE to be given - parallel plans (Amit Kapila, Tobias Bussmann) - - - - - - - Fix incorrect generation of parallel plans for semi-joins (Tom Lane) - - - - - - - Fix planner's cardinality estimates for parallel joins (Robert Haas) - - - - Ensure that these estimates reflect the number of rows predicted to - be seen by each worker, rather than the total. - - - - - - - Fix planner to avoid trying to parallelize plan nodes containing - initplans or subplans (Tom Lane, Amit Kapila) - - - - - - - Ensure that cached plans are invalidated by changes in foreign-table - options (Amit Langote, Etsuro Fujita, Ashutosh Bapat) - - - - - - - Fix the plan generated for sorted partial aggregation with a constant - GROUP BY clause (Tom Lane) - - - - - - - Fix could not find plan for CTE planner error when dealing - with a UNION ALL containing CTE references (Tom Lane) - - - - - - - Fix mishandling of initplans when forcibly adding a Material node to - a subplan (Tom Lane) - - - - The typical consequence of this mistake was a plan should not - reference subplan's variable error. - - - - - - - Fix foreign-key-based join selectivity estimation for semi-joins and - anti-joins, as well as inheritance cases (Tom Lane) - - - - The new code for taking the existence of a foreign key relationship - into account did the wrong thing in these cases, making the estimates - worse not better than the pre-9.6 code. - - - - - - - Fix pg_dump to emit the data of a sequence that is - marked as an extension configuration table (Michael Paquier) - - - - - - - Fix mishandling of ALTER DEFAULT PRIVILEGES ... REVOKE - in pg_dump (Stephen Frost) - - - - pg_dump missed issuing the - required REVOKE commands in cases where ALTER - DEFAULT PRIVILEGES had been used to reduce privileges to less than - they would normally be. - - - - - - - Fix pg_dump to dump user-defined casts and transforms - that use built-in functions (Stephen Frost) - - - - - - - Fix pg_restore with - to behave more sanely if an archive contains - unrecognized DROP commands (Tom Lane) - - - - This doesn't fix any live bug, but it may improve the behavior in - future if pg_restore is used with an archive - generated by a later pg_dump version. - - - - - - - Fix pg_basebackup's rate limiting in the presence of - slow I/O (Antonin Houska) - - - - If disk I/O was transiently much slower than the specified rate - limit, the calculation overflowed, effectively disabling the rate - limit for the rest of the run. - - - - - - - Fix pg_basebackup's handling of - symlinked pg_stat_tmp and pg_replslot - subdirectories (Magnus Hagander, Michael Paquier) - - - - - - - Fix possible pg_basebackup failure on standby - server when including WAL files (Amit Kapila, Robert Haas) - - - - - - - Improve initdb to insert the correct - platform-specific default values for - the xxx_flush_after parameters - into postgresql.conf (Fabien Coelho, Tom Lane) - - - - This is a cleaner way of documenting the default values than was used - previously. - - - - - - - Fix possible mishandling of expanded arrays in domain check - constraints and CASE execution (Tom Lane) - - - - It was possible for a PL/pgSQL function invoked in these contexts to - modify or even delete an array value that needs to be preserved for - additional operations. - - - - - - - Fix nested uses of PL/pgSQL functions in contexts such as domain - check constraints evaluated during assignment to a PL/pgSQL variable - (Tom Lane) - - - - - - - Ensure that the Python exception objects we create for PL/Python are - properly reference-counted (Rafa de la Torre, Tom Lane) - - - - This avoids failures if the objects are used after a Python garbage - collection cycle has occurred. - - - - - - - Fix PL/Tcl to support triggers on tables that have .tupno - as a column name (Tom Lane) - - - - This matches the (previously undocumented) behavior of - PL/Tcl's spi_exec and spi_execp commands, - namely that a magic .tupno column is inserted only if - there isn't a real column named that. - - - - - - - Allow DOS-style line endings in ~/.pgpass files, - even on Unix (Vik Fearing) - - - - This change simplifies use of the same password file across Unix and - Windows machines. - - - - - - - Fix one-byte buffer overrun if ecpg is given a file - name that ends with a dot (Takayuki Tsunakawa) - - - - - - - Fix incorrect error reporting for duplicate data - in psql's \crosstabview (Tom Lane) - - - - psql sometimes quoted the wrong row and/or column - values when complaining about multiple entries for the same crosstab - cell. - - - - - - - Fix psql's tab completion for ALTER DEFAULT - PRIVILEGES (Gilles Darold, Stephen Frost) - - - - - - - Fix psql's tab completion for ALTER TABLE t - ALTER c DROP ... (Kyotaro Horiguchi) - - - - - - - In psql, treat an empty or all-blank setting of - the PAGER environment variable as meaning no - pager (Tom Lane) - - - - Previously, such a setting caused output intended for the pager to - vanish entirely. - - - - - - - Improve contrib/dblink's reporting of - low-level libpq errors, such as out-of-memory - (Joe Conway) - - - - - - - Teach contrib/dblink to ignore irrelevant server options - when it uses a contrib/postgres_fdw foreign server as - the source of connection options (Corey Huinker) - - - - Previously, if the foreign server object had options that were not - also libpq connection options, an error occurred. - - - - - - - Fix portability problems in contrib/pageinspect's - functions for GIN indexes (Peter Eisentraut, Tom Lane) - - - - - - - Fix possible miss of socket read events while waiting on Windows - (Amit Kapila) - - - - This error was harmless for most uses, but it is known to cause hangs - when trying to use the pldebugger extension. - - - - - - - On Windows, ensure that environment variable changes are propagated - to DLLs built with debug options (Christian Ullrich) - - - - - - - Sync our copy of the timezone library with IANA release tzcode2016j - (Tom Lane) - - - - This fixes various issues, most notably that timezone data - installation failed if the target directory didn't support hard - links. - - - - - - - Update time zone data files to tzdata release 2016j - for DST law changes in northern Cyprus (adding a new zone - Asia/Famagusta), Russia (adding a new zone Europe/Saratov), Tonga, - and Antarctica/Casey. - Historical corrections for Italy, Kazakhstan, Malta, and Palestine. - Switch to preferring numeric zone abbreviations for Tonga. - - - - - - - - - - Release 9.6.1 - - - Release date: - 2016-10-27 - - - - This release contains a variety of fixes from 9.6.0. - For information about new features in the 9.6 major release, see - . - - - - Migration to Version 9.6.1 - - - A dump/restore is not required for those running 9.6.X. - - - - However, if your installation has been affected by the bugs described in - the first two changelog entries below, then after updating you may need - to take action to repair corrupted free space maps and/or visibility - maps. - - - - - Changes - - - - - - - Fix WAL-logging of truncation of relation free space maps and - visibility maps (Pavan Deolasee, Heikki Linnakangas) - - - - It was possible for these files to not be correctly restored during - crash recovery, or to be written incorrectly on a standby server. - Bogus entries in a free space map could lead to attempts to access - pages that have been truncated away from the relation itself, typically - producing errors like could not read block XXX: - read only 0 of 8192 bytes. Checksum failures in the - visibility map are also possible, if checksumming is enabled. - - - - Procedures for determining whether there is a problem and repairing it - if so are discussed at - . - - - - - - - Fix possible data corruption when pg_upgrade rewrites - a relation visibility map into 9.6 format (Tom Lane) - - - - On big-endian machines, bytes of the new visibility map were written - in the wrong order, leading to a completely incorrect map. On - Windows, the old map was read using text mode, leading to incorrect - results if the map happened to contain consecutive bytes that matched - a carriage return/line feed sequence. The latter error would almost - always lead to a pg_upgrade failure due to the map - file appearing to be the wrong length. - - - - If you are using a big-endian machine (many non-Intel architectures - are big-endian) and have used pg_upgrade to upgrade - from a pre-9.6 release, you should assume that all visibility maps are - incorrect and need to be regenerated. It is sufficient to truncate - each relation's visibility map - with contrib/pg_visibility's - pg_truncate_visibility_map() function. - For more information see - . - - - - - - - Don't throw serialization errors for self-conflicting insertions - in INSERT ... ON CONFLICT (Thomas Munro, Peter Geoghegan) - - - - - - - Fix use-after-free hazard in execution of aggregate functions - using DISTINCT (Peter Geoghegan) - - - - This could lead to a crash or incorrect query results. - - - - - - - Fix incorrect handling of polymorphic aggregates used as window - functions (Tom Lane) - - - - The aggregate's transition function was told that its first argument - and result were of the aggregate's output type, rather than the - state type. This led to errors or crashes with - polymorphic transition functions. - - - - - - - Fix COPY with a column name list from a table that has - row-level security enabled (Adam Brightwell) - - - - - - - Fix EXPLAIN to emit valid XML when - is on (Markus Winand) - - - - Previously the XML output-format option produced syntactically invalid - tags such as <I/O-Read-Time>. That is now - rendered as <I-O-Read-Time>. - - - - - - - Fix statistics update for TRUNCATE in a prepared - transaction (Stas Kelvich) - - - - - - - Fix bugs in merging inherited CHECK constraints while - creating or altering a table (Tom Lane, Amit Langote) - - - - Allow identical CHECK constraints to be added to a parent - and child table in either order. Prevent merging of a valid - constraint from the parent table with a NOT VALID - constraint on the child. Likewise, prevent merging of a NO - INHERIT child constraint with an inherited constraint. - - - - - - - Show a sensible value - in pg_settings.unit - for min_wal_size and max_wal_size (Tom Lane) - - - - - - - Fix replacement of array elements in jsonb_set() - (Tom Lane) - - - - If the target is an existing JSON array element, it got deleted - instead of being replaced with a new value. - - - - - - - Avoid very-low-probability data corruption due to testing tuple - visibility without holding buffer lock (Thomas Munro, Peter Geoghegan, - Tom Lane) - - - - - - - Preserve commit timestamps across server restart - (Julien Rouhaud, Craig Ringer) - - - - With turned on, old - commit timestamps became inaccessible after a clean server restart. - - - - - - - Fix logical WAL decoding to work properly when a subtransaction's WAL - output is large enough to spill to disk (Andres Freund) - - - - - - - Fix dangling-pointer problem in logical WAL decoding (Stas Kelvich) - - - - - - - Round shared-memory allocation request to a multiple of the actual - huge page size when attempting to use huge pages on Linux (Tom Lane) - - - - This avoids possible failures during munmap() on systems - with atypical default huge page sizes. Except in crash-recovery - cases, there were no ill effects other than a log message. - - - - - - - Don't try to share SSL contexts across multiple connections - in libpq (Heikki Linnakangas) - - - - This led to assorted corner-case bugs, particularly when trying to use - different SSL parameters for different connections. - - - - - - - Avoid corner-case memory leak in libpq (Tom Lane) - - - - The reported problem involved leaking an error report - during PQreset(), but there might be related cases. - - - - - - - In pg_upgrade, check library loadability in name order - (Tom Lane) - - - - This is a workaround to deal with cross-extension dependencies from - language transform modules to their base language and data type - modules. - - - - - - - Fix pg_upgrade to work correctly for extensions - containing index access methods (Tom Lane) - - - - To allow this, the server has been extended to support ALTER - EXTENSION ADD/DROP ACCESS METHOD. That functionality should have - been included in the original patch to support dynamic creation of - access methods, but it was overlooked. - - - - - - - Improve error reporting in pg_upgrade's file - copying/linking/rewriting steps (Tom Lane, Álvaro Herrera) - - - - - - - Fix pg_dump to work against pre-7.4 servers - (Amit Langote, Tom Lane) - - - - - - - Disallow specifying both - and options to pg_rewind - (Michael Banck) - - - - - - - Make pg_rewind turn off synchronous_commit - in its session on the source server (Michael Banck, Michael Paquier) - - - - This allows pg_rewind to work even when the source - server is using synchronous replication that is not working for some - reason. - - - - - - - In pg_xlogdump, retry opening new WAL segments when - using option (Magnus Hagander) - - - - This allows for a possible delay in the server's creation of the next - segment. - - - - - - - Fix contrib/pg_visibility to report the correct TID for - a corrupt tuple that has been the subject of a rolled-back update - (Tom Lane) - - - - - - - Fix makefile dependencies so that parallel make - of PL/Python by itself will succeed reliably - (Pavel Raiskup) - - - - - - - Update time zone data files to tzdata release 2016h - for DST law changes in Palestine and Turkey, plus historical - corrections for Turkey and some regions of Russia. - Switch to numeric abbreviations for some time zones in Antarctica, - the former Soviet Union, and Sri Lanka. - - - - The IANA time zone database previously provided textual abbreviations - for all time zones, sometimes making up abbreviations that have little - or no currency among the local population. They are in process of - reversing that policy in favor of using numeric UTC offsets in zones - where there is no evidence of real-world use of an English - abbreviation. At least for the time being, PostgreSQL - will continue to accept such removed abbreviations for timestamp input. - But they will not be shown in the pg_timezone_names - view nor used for output. - - - - In this update, AMT is no longer shown as being in use to - mean Armenia Time. Therefore, we have changed the Default - abbreviation set to interpret it as Amazon Time, thus UTC-4 not UTC+4. - - - - - - - - - - Release 9.6 - - - Release date: - 2016-09-29 - - - - Overview - - - Major enhancements in PostgreSQL 9.6 include: - - - - - - - - - Parallel execution of sequential scans, joins and aggregates - - - - - - Avoid scanning pages unnecessarily during vacuum freeze operations - - - - - - Synchronous replication now allows multiple standby servers for - increased reliability - - - - - - Full-text search can now search for phrases (multiple adjacent words) - - - - - - postgres_fdw now supports remote joins, sorts, - UPDATEs, and DELETEs - - - - - - Substantial performance improvements, especially in the area of - scalability on multi-CPU-socket servers - - - - - - - The above items are explained in more detail in the sections below. - - - - - - - Migration to Version 9.6 - - - A dump/restore using , or use of , is required for those wishing to migrate data - from any previous release. - - - - Version 9.6 contains a number of changes that may affect compatibility - with previous releases. Observe the following incompatibilities: - - - - - - - - Improve the pg_stat_activity - view's information about what a process is waiting for (Amit - Kapila, Ildus Kurbangaliev) - - - - Historically a process has only been shown as waiting if it was - waiting for a heavyweight lock. Now waits for lightweight locks - and buffer pins are also shown in pg_stat_activity. - Also, the type of lock being waited for is now visible. - These changes replace the waiting column with - wait_event_type and wait_event. - - - - - - - In to_char(), - do not count a minus sign (when needed) as part of the field - width for time-related fields (Bruce Momjian) - - - - For example, to_char('-4 years'::interval, 'YY') - now returns -04, rather than -4. - - - - - - - Make extract() behave - more reasonably with infinite inputs (Vitaly Burovoy) - - - - Historically the extract() function just returned - zero given an infinite timestamp, regardless of the given - field name. Make it return infinity - or -infinity as appropriate when the - requested field is one that is monotonically increasing (e.g, - year, epoch), or NULL when - it is not (e.g., day, hour). Also, - throw the expected error for bad field names. - - - - - - - Remove PL/pgSQL's feature that suppressed the - innermost line of CONTEXT for messages emitted by - RAISE commands (Pavel Stehule) - - - - This ancient backwards-compatibility hack was agreed to have - outlived its usefulness. - - - - - - - Fix the default text search parser to allow leading digits - in email and host tokens (Artur Zakirov) - - - - In most cases this will result in few changes in the parsing of - text. But if you have data where such addresses occur frequently, - it may be worth rebuilding dependent tsvector columns - and indexes so that addresses of this form will be found properly - by text searches. - - - - - - - Extend contrib/unaccent's - standard unaccent.rules file to handle all diacritics - known to Unicode, and to expand ligatures correctly (Thomas Munro, - Léonard Benedetti) - - - - The previous version neglected to convert some less-common letters - with diacritic marks. Also, ligatures are now expanded into - separate letters. Installations that use this rules file may wish - to rebuild tsvector columns and indexes that depend on the - result. - - - - - - - Remove the long-deprecated - CREATEUSER/NOCREATEUSER options from - CREATE ROLE and allied commands (Tom Lane) - - - - CREATEUSER actually meant SUPERUSER, - for ancient backwards-compatibility reasons. This has been a - constant source of confusion for people who (reasonably) expect - it to mean CREATEROLE. It has been deprecated for - ten years now, so fix the problem by removing it. - - - - - - - Treat role names beginning with pg_ as reserved - (Stephen Frost) - - - - User creation of such role names is now disallowed. This prevents - conflicts with built-in roles created by initdb. - - - - - - - Change a column name in the - information_schema.routines - view from result_cast_character_set_name - to result_cast_char_set_name (Clément - Prévost) - - - - The SQL:2011 standard specifies the longer name, but that appears - to be a mistake, because adjacent column names use the shorter - style, as do other information_schema views. - - - - - - - psql's option no longer implies - - (Pavel Stehule, Catalin Iacob) - - - - Write (or its - abbreviation ) explicitly to obtain the old - behavior. Scripts so modified will still work with old - versions of psql. - - - - - - - Improve pg_restore's option to - match all types of relations, not only plain tables (Craig Ringer) - - - - - - - Change the display format used for NextXID in - pg_controldata and related places (Joe Conway, - Bruce Momjian) - - - - Display epoch-and-transaction-ID values in the format - number:number. - The previous format - number/number was - confusingly similar to that used for LSNs. - - - - - - - Update extension functions to be marked parallel-safe where - appropriate (Andreas Karlsson) - - - - Many of the standard extensions have been updated to allow their - functions to be executed within parallel query worker processes. - These changes will not take effect in - databases pg_upgrade'd from prior versions unless - you apply ALTER EXTENSION UPDATE to each such extension - (in each database of a cluster). - - - - - - - - - Changes - - - Below you will find a detailed account of the changes between - PostgreSQL 9.6 and the previous major - release. - - - - Server - - - Parallel Queries - - - - - - - Parallel queries (Robert Haas, Amit Kapila, David Rowley, - many others) - - - - With 9.6, PostgreSQL introduces initial support - for parallel execution of large queries. Only strictly read-only - queries where the driving table is accessed via a sequential scan - can be parallelized. Hash joins and nested loops can be performed - in parallel, as can aggregation (for supported aggregates). - Much remains to be done, but this is already a useful set of - features. - - - - Parallel query execution is not (yet) enabled by default. - To allow it, set the new configuration - parameter to a - value larger than zero. Additional control over use of parallelism - is available through other new configuration parameters - , - , , and - min_parallel_relation_size. - - - - - - - Provide infrastructure for marking the parallel-safety status of - functions (Robert Haas, Amit Kapila) - - - - - - - - - Indexes - - - - - - - Allow GIN index builds to - make effective use of - settings larger than 1 GB (Robert Abraham, Teodor Sigaev) - - - - - - - Add pages deleted from a GIN index's pending list to the free space - map immediately - (Jeff Janes, Teodor Sigaev) - - - - This reduces bloat if the table is not vacuumed often. - - - - - - - Add gin_clean_pending_list() - function to allow manual invocation of pending-list cleanup for a - GIN index (Jeff Janes) - - - - Formerly, such cleanup happened only as a byproduct of vacuuming or - analyzing the parent table. - - - - - - - Improve handling of dead index tuples in GiST indexes (Anastasia Lubennikova) - - - - Dead index tuples are now marked as such when an index scan notices - that the corresponding heap tuple is dead. When inserting tuples, - marked-dead tuples will be removed if needed to make space on - the page. - - - - - - - Add an SP-GiST operator class for - type box (Alexander Lebedev) - - - - - - - - - Sorting - - - - - - - Improve sorting performance by using quicksort, not replacement - selection sort, when performing external sort steps (Peter - Geoghegan) - - - - The new approach makes better use of the CPU cache - for typical cache sizes and data volumes. Where necessary, - the behavior can be adjusted via the new configuration parameter - replacement_sort_tuples. - - - - - - - Speed up text sorts where the same string occurs multiple times - (Peter Geoghegan) - - - - - - - Speed up sorting of uuid, bytea, and - char(n) fields by using abbreviated keys - (Peter Geoghegan) - - - - Support for abbreviated keys has also been - added to the non-default operator classes text_pattern_ops, - varchar_pattern_ops, and - bpchar_pattern_ops. Processing of ordered-set - aggregates can also now exploit abbreviated keys. - - - - - - - Speed up CREATE INDEX CONCURRENTLY by treating - TIDs as 64-bit integers during sorting (Peter - Geoghegan) - - - - - - - - - Locking - - - - - - - Reduce contention for the ProcArrayLock (Amit Kapila, - Robert Haas) - - - - - - - Improve performance by moving buffer content locks into the buffer - descriptors (Andres Freund, Simon Riggs) - - - - - - - Replace shared-buffer header spinlocks with atomic operations to - improve scalability (Alexander Korotkov, Andres Freund) - - - - - - - Use atomic operations, rather than a spinlock, to protect an - LWLock's wait queue (Andres Freund) - - - - - - - Partition the shared hash table freelist to reduce contention on - multi-CPU-socket servers (Aleksander Alekseev) - - - - - - - Reduce interlocking on standby servers during the replay of btree - index vacuuming operations (Simon Riggs) - - - - This change avoids substantial replication delays that sometimes - occurred while replaying such operations. - - - - - - - - - Optimizer Statistics - - - - - - - Improve ANALYZE's estimates for columns with many nulls - (Tomas Vondra, Alex Shulgin) - - - - Previously ANALYZE tended to underestimate the number - of non-NULL distinct values in a column with many - NULLs, and was also inaccurate in computing the - most-common values. - - - - - - - Improve planner's estimate of the number of distinct values in - a query result (Tomas Vondra) - - - - - - - Use foreign key relationships to infer selectivity for join - predicates (Tomas Vondra, David Rowley) - - - - If a table t has a foreign key restriction, say - (a,b) REFERENCES r (x,y), then a WHERE - condition such as t.a = r.x AND t.b = r.y cannot - select more than one r row per t row. - The planner formerly considered these AND conditions - to be independent and would often drastically misestimate - selectivity as a result. Now it compares the WHERE - conditions to applicable foreign key constraints and produces - better estimates. - - - - - - - - - <command>VACUUM</command> - - - - - - - Avoid re-vacuuming pages containing only frozen tuples (Masahiko - Sawada, Robert Haas, Andres Freund) - - - - Formerly, anti-wraparound vacuum had to visit every page of - a table, even pages where there was nothing to do. Now, pages - containing only already-frozen tuples are identified in the table's - visibility map, and can be skipped by vacuum even when doing - transaction wraparound prevention. This should greatly reduce the - cost of maintaining large tables containing mostly-unchanging data. - - - - If necessary, vacuum can be forced to process all-frozen - pages using the new DISABLE_PAGE_SKIPPING option. - Normally this should never be needed, but it might help in - recovering from visibility-map corruption. - - - - - - - Avoid useless heap-truncation attempts during VACUUM - (Jeff Janes, Tom Lane) - - - - This change avoids taking an exclusive table lock in some cases - where no truncation is possible. The main benefit comes from - avoiding unnecessary query cancellations on standby servers. - - - - - - - - - General Performance - - - - - - - Allow old MVCC snapshots to be invalidated after a - configurable timeout (Kevin Grittner) - - - - Normally, deleted tuples cannot be physically removed by - vacuuming until the last transaction that could see - them is gone. A transaction that stays open for a long - time can thus cause considerable table bloat because - space cannot be recycled. This feature allows setting - a time-based limit, via the new configuration parameter - , on how long an - MVCC snapshot is guaranteed to be valid. After that, - dead tuples are candidates for removal. A transaction using an - outdated snapshot will get an error if it attempts to read a page - that potentially could have contained such data. - - - - - - - Ignore GROUP BY columns that are - functionally dependent on other columns (David Rowley) - - - - If a GROUP BY clause includes all columns of a - non-deferred primary key, as well as other columns of the same - table, those other columns are redundant and can be dropped - from the grouping. This saves computation in many common cases. - - - - - - - Allow use of an index-only - scan on a partial index when the index's WHERE - clause references columns that are not indexed (Tomas Vondra, - Kyotaro Horiguchi) - - - - For example, an index defined by CREATE INDEX tidx_partial - ON t(b) WHERE a > 0 can now be used for an index-only scan by - a query that specifies WHERE a > 0 and does not - otherwise use a. Previously this was disallowed - because a is not listed as an index column. - - - - - - - - Perform checkpoint writes in sorted order (Fabien Coelho, - Andres Freund) - - - - Previously, checkpoints wrote out dirty pages in whatever order - they happen to appear in shared buffers, which usually is nearly - random. That performs poorly, especially on rotating media. - This change causes checkpoint-driven writes to be done in order - by file and block number, and to be balanced across tablespaces. - - - - - - - Where feasible, trigger kernel writeback after a configurable - number of writes, to prevent accumulation of dirty data in kernel - disk buffers (Fabien Coelho, Andres Freund) - - - - PostgreSQL writes data to the kernel's disk cache, - from where it will be flushed to physical storage in due time. - Many operating systems are not smart about managing this and allow - large amounts of dirty data to accumulate before deciding to flush - it all at once, causing long delays for new I/O requests until the - flushing finishes. - This change attempts to alleviate this problem by explicitly - requesting data flushes after a configurable interval. - - - - On Linux, sync_file_range() is used for this purpose, - and the feature is on by default on Linux because that function has - few downsides. This flushing capability is also available on other - platforms if they have msync() - or posix_fadvise(), but those interfaces have some - undesirable side-effects so the feature is disabled by default on - non-Linux platforms. - - - - The new configuration parameters , , , and control this behavior. - - - - - - - Improve aggregate-function performance by sharing calculations - across multiple aggregates if they have the same arguments and - transition functions (David Rowley) - - - - For example, SELECT AVG(x), VARIANCE(x) FROM tab can use - a single per-row computation for both aggregates. - - - - - - - Speed up visibility tests for recently-created tuples by checking - the current transaction's snapshot, not pg_clog, to - decide if the source transaction should be considered committed - (Jeff Janes, Tom Lane) - - - - - - - Allow tuple hint bits to be set sooner than before (Andres Freund) - - - - - - - Improve performance of short-lived prepared transactions (Stas - Kelvich, Simon Riggs, Pavan Deolasee) - - - - Two-phase commit information is now written only to WAL - during PREPARE TRANSACTION, and will be read back from - WAL during COMMIT PREPARED if that happens - soon thereafter. A separate state file is created only if the - pending transaction does not get committed or aborted by the time - of the next checkpoint. - - - - - - - Improve performance of memory context destruction (Jan Wieck) - - - - - - - Improve performance of resource owners with many tracked objects - (Aleksander Alekseev) - - - - - - - Improve speed of the output functions for timestamp, - time, and date data types (David Rowley, - Andres Freund) - - - - - - - Avoid some unnecessary cancellations of hot-standby queries - during replay of actions that take AccessExclusive - locks (Jeff Janes) - - - - - - - Extend relations multiple blocks at a time when there is contention - for the relation's extension lock (Dilip Kumar) - - - - This improves scalability by decreasing contention. - - - - - - - Increase the number of clog buffers for better scalability (Amit - Kapila, Andres Freund) - - - - - - - Speed up expression evaluation in PL/pgSQL by - keeping ParamListInfo entries for simple variables - valid at all times (Tom Lane) - - - - - - - Avoid reducing the SO_SNDBUF setting below its default - on recent Windows versions (Chen Huajun) - - - - - - - Disable by default on - Windows (Takayuki Tsunakawa) - - - - The overhead of updating the process title is much larger on Windows - than most other platforms, and it is also less useful to do it since - most Windows users do not have tools that can display process titles. - - - - - - - - - Monitoring - - - - - - - Add pg_stat_progress_vacuum - system view to provide progress reporting for VACUUM - operations (Amit Langote, Robert Haas, Vinayak Pokale, Rahila Syed) - - - - - - - Add pg_control_system(), - pg_control_checkpoint(), - pg_control_recovery(), and - pg_control_init() functions to expose fields of - pg_control to SQL (Joe Conway, Michael - Paquier) - - - - - - - Add pg_config - system view (Joe Conway) - - - - This view exposes the same information available from - the pg_config command-line utility, - namely assorted compile-time configuration information for - PostgreSQL. - - - - - - - Add a confirmed_flush_lsn column to the pg_replication_slots - system view (Marko Tiikkaja) - - - - - - - Add pg_stat_wal_receiver - system view to provide information about the state of a hot-standby - server's WAL receiver process (Michael Paquier) - - - - - - - Add pg_blocking_pids() - function to reliably identify which sessions block which others - (Tom Lane) - - - - This function returns an array of the process IDs of any - sessions that are blocking the session with the given process ID. - Historically users have obtained such information using a self-join - on the pg_locks view. However, it is unreasonably - tedious to do it that way with any modicum of correctness, and - the addition of parallel queries has made the old approach entirely - impractical, since locks might be held or awaited by child worker - processes rather than the session's main process. - - - - - - - Add function pg_current_xlog_flush_location() - to expose the current transaction log flush location (Tomas Vondra) - - - - - - - Add function pg_notification_queue_usage() - to report how full the NOTIFY queue is (Brendan Jurd) - - - - - - - Limit the verbosity of memory context statistics dumps (Tom Lane) - - - - The memory usage dump that is output to the postmaster log during an - out-of-memory failure now summarizes statistics when there are a - large number of memory contexts, rather than possibly generating - a very large report. There is also a grand total - summary line now. - - - - - - - - - <acronym>Authentication</acronym> - - - - - - - Add a BSD authentication - method to allow use of - the BSD Authentication service for - PostgreSQL client authentication (Marisa Emerson) - - - - BSD Authentication is currently only available on OpenBSD. - - - - - - - When using PAM - authentication, provide the client IP address or host name - to PAM modules via the PAM_RHOST item - (Grzegorz Sampolski) - - - - - - - Provide detail in the postmaster log for more types of password - authentication failure (Tom Lane) - - - - All ordinarily-reachable password authentication failure cases - should now provide specific DETAIL fields in the log. - - - - - - - Support RADIUS passwords - up to 128 characters long (Marko Tiikkaja) - - - - - - - Add new SSPI - authentication parameters - compat_realm and upn_username to control - whether NetBIOS or Kerberos - realm names and user names are used during SSPI - authentication (Christian Ullrich) - - - - - - - - - Server Configuration - - - - - - - Allow sessions to be terminated automatically if they are in - idle-in-transaction state for too long (Vik Fearing) - - - - This behavior is controlled by the new configuration parameter - . It can - be useful to prevent forgotten transactions from holding locks - or preventing vacuum cleanup for too long. - - - - - - - Raise the maximum allowed value - of to 24 hours (Simon Riggs) - - - - - - - Allow effective_io_concurrency to be set per-tablespace - to support cases where different tablespaces have different I/O - characteristics (Julien Rouhaud) - - - - - - - Add option %n to - print the current time in Unix epoch form, with milliseconds (Tomas - Vondra, Jeff Davis) - - - - - - - Add and configuration parameters - to provide more control over the message format when logging to - syslog (Peter Eisentraut) - - - - - - - Merge the archive and hot_standby values - of the configuration parameter - into a single new value replica (Peter Eisentraut) - - - - Making a distinction between these settings is no longer useful, - and merging them is a step towards a planned future simplification - of replication setup. The old names are still accepted but are - converted to replica internally. - - - - - - - Add configure option to enable - calling sd_notify() at server start and stop (Peter - Eisentraut) - - - - This allows the use of systemd service units of - type notify, which greatly simplifies the management - of PostgreSQL under systemd. - - - - - - - Allow the server's SSL key file to have group read - access if it is owned by root (Christoph Berg) - - - - Formerly, we insisted the key file be owned by the - user running the PostgreSQL server, but - that is inconvenient on some systems (such as Debian) that are configured to manage - certificates centrally. Therefore, allow the case where the key - file is owned by root and has group read access. - It is up to the operating system administrator to ensure that - the group does not include any untrusted users. - - - - - - - - - Reliability - - - - - - - Force backends to exit if the postmaster dies (Rajeev Rastogi, - Robert Haas) - - - - Under normal circumstances the postmaster should always outlive - its child processes. If for some reason the postmaster dies, - force backend sessions to exit with an error. Formerly, existing - backends would continue to run until their clients disconnect, - but that is unsafe and inefficient. It also prevents a new - postmaster from being started until the last old backend has - exited. Backends will detect postmaster death when waiting for - client I/O, so the exit will not be instantaneous, but it should - happen no later than the end of the current query. - - - - - - - Check for serializability conflicts before reporting - constraint-violation failures (Thomas Munro) - - - - When using serializable transaction isolation, it is desirable - that any error due to concurrent transactions should manifest - as a serialization failure, thereby cueing the application that - a retry might succeed. Unfortunately, this does not reliably - happen for duplicate-key failures caused by concurrent insertions. - This change ensures that such an error will be reported as a - serialization error if the application explicitly checked for - the presence of a conflicting key (and did not find it) earlier - in the transaction. - - - - - - - Ensure that invalidation messages are recorded in WAL - even when issued by a transaction that has no XID - assigned (Andres Freund) - - - - This fixes some corner cases in which transactions on standby - servers failed to notice changes, such as new indexes. - - - - - - - Prevent multiple processes from trying to clean a GIN - index's pending list concurrently (Teodor Sigaev, Jeff Janes) - - - - This had been intentionally allowed, but it causes race conditions - that can result in vacuum missing index entries it needs to delete. - - - - - - - - - - - Replication and Recovery - - - - - - - Allow synchronous replication to support multiple simultaneous - synchronous standby servers, not just one (Masahiko Sawada, - Beena Emerson, Michael Paquier, Fujii Masao, Kyotaro Horiguchi) - - - - The number of standby servers that must acknowledge a commit - before it is considered complete is now configurable as part of - the parameter. - - - - - - - Add new setting remote_apply for configuration - parameter (Thomas Munro) - - - - In this mode, the master waits for the transaction to be - applied on the standby server, not just written - to disk. That means that you can count on a transaction started - on the standby to see all commits previously acknowledged by - the master. - - - - - - - Add a feature to the replication - protocol, and a corresponding option to pg_create_physical_replication_slot(), - to allow reserving WAL immediately when creating a - replication slot (Gurjeet Singh, Michael Paquier) - - - - This allows the creation of a replication slot to guarantee - that all the WAL needed for a base backup will be - available. - - - - - - - Add a option to - pg_basebackup - (Peter Eisentraut) - - - - This lets pg_basebackup use a replication - slot defined for WAL streaming. After the base - backup completes, selecting the same slot for regular streaming - replication allows seamless startup of the new standby server. - - - - - - - Extend pg_start_backup() - and pg_stop_backup() to support non-exclusive backups - (Magnus Hagander) - - - - - - - - - Queries - - - - - - - Allow functions that return sets of tuples to return simple - NULLs (Andrew Gierth, Tom Lane) - - - - In the context of SELECT FROM function(...), a function - that returned a set of composite values was previously not allowed - to return a plain NULL value as part of the set. - Now that is allowed and interpreted as a row of NULLs. - This avoids corner-case errors with, for example, unnesting an - array of composite values. - - - - - - - Fully support array subscripts and field selections in the - target column list of an INSERT with multiple - VALUES rows (Tom Lane) - - - - Previously, such cases failed if the same target column was - mentioned more than once, e.g., INSERT INTO tab (x[1], - x[2]) VALUES (...). - - - - - - - When appropriate, postpone evaluation of SELECT - output expressions until after an ORDER BY sort - (Konstantin Knizhnik) - - - - This change ensures that volatile or expensive functions in the - output list are executed in the order suggested by ORDER - BY, and that they are not evaluated more times than required - when there is a LIMIT clause. Previously, these - properties held if the ordering was performed by an index scan or - pre-merge-join sort, but not if it was performed by a top-level - sort. - - - - - - - Widen counters recording the number of tuples processed to 64 bits - (Andreas Scherbaum) - - - - This change allows command tags, e.g. SELECT, to - correctly report tuple counts larger than 4 billion. This also - applies to PL/pgSQL's GET DIAGNOSTICS ... ROW_COUNT - command. - - - - - - - Avoid doing encoding conversions by converting through the - MULE_INTERNAL encoding (Tom Lane) - - - - Previously, many conversions for Cyrillic and Central - European single-byte encodings were done by converting to a - related MULE_INTERNAL coding scheme and then to the - destination encoding. Aside from being inefficient, this meant - that when the conversion encountered an untranslatable character, - the error message would confusingly complain about failure to - convert to or from MULE_INTERNAL, rather than the - user-visible encoding. - - - - - - - Consider performing joins of foreign tables remotely only when the - tables will be accessed under the same role ID (Shigeru Hanada, - Ashutosh Bapat, Etsuro Fujita) - - - - Previously, the foreign join pushdown infrastructure left the - question of security entirely up to individual foreign data - wrappers, but that made it too easy for an FDW to - inadvertently create subtle security holes. So, make it the core - code's job to determine which role ID will access each table, - and do not attempt join pushdown unless the role is the same for - all relevant relations. - - - - - - - - - Utility Commands - - - - - - - Allow COPY to copy the output of an - INSERT/UPDATE/DELETE - ... RETURNING query (Marko Tiikkaja) - - - - Previously, an intermediate CTE had to be written to - get this result. - - - - - - - Introduce ALTER object DEPENDS ON - EXTENSION (Abhijit Menon-Sen) - - - - This command allows a database object to be marked as depending - on an extension, so that it will be dropped automatically if - the extension is dropped (without needing CASCADE). - However, the object is not part of the extension, and thus will - be dumped separately by pg_dump. - - - - - - - Make ALTER object SET SCHEMA do nothing - when the object is already in the requested schema, rather than - throwing an error as it historically has for most object types - (Marti Raudsepp) - - - - - - - Add options to ALTER OPERATOR to allow changing - the selectivity functions associated with an existing operator - (Yury Zhuravlev) - - - - - - - Add an option to ALTER TABLE - ADD COLUMN (Fabrízio de Royes Mello) - - - - - - - Reduce the lock strength needed by ALTER TABLE - when setting fillfactor and autovacuum-related relation options - (Fabrízio de Royes Mello, Simon Riggs) - - - - - - - Introduce CREATE - ACCESS METHOD to allow extensions to create index access - methods (Alexander Korotkov, Petr Jelínek) - - - - - - - Add a CASCADE option to CREATE - EXTENSION to automatically create any extensions the - requested one depends on (Petr Jelínek) - - - - - - - Make CREATE TABLE ... LIKE include an OID - column if any source table has one (Bruce Momjian) - - - - - - - If a CHECK constraint is declared NOT VALID - in a table creation command, automatically mark it as valid - (Amit Langote, Amul Sul) - - - - This is safe because the table has no existing rows. This matches - the longstanding behavior of FOREIGN KEY constraints. - - - - - - - Fix DROP OPERATOR to clear - pg_operator.oprcom and - pg_operator.oprnegate links to - the dropped operator (Roma Sokolov) - - - - Formerly such links were left as-is, which could pose a problem - in the somewhat unlikely event that the dropped operator's - OID was reused for another operator. - - - - - - - Do not show the same subplan twice in EXPLAIN output - (Tom Lane) - - - - In certain cases, typically involving SubPlan nodes in index - conditions, EXPLAIN would print data for the same - subplan twice. - - - - - - - Disallow creation of indexes on system columns, except for - OID columns (David Rowley) - - - - Such indexes were never considered supported, and would very - possibly misbehave since the system might change the system-column - fields of a tuple without updating indexes. However, previously - there were no error checks to prevent them from being created. - - - - - - - - - Permissions Management - - - - - - - Use the privilege system to manage access to sensitive functions - (Stephen Frost) - - - - Formerly, many security-sensitive functions contained hard-wired - checks that would throw an error if they were called by a - non-superuser. This forced the use of superuser roles for - some relatively pedestrian tasks. The hard-wired error checks - are now gone in favor of making initdb revoke the - default public EXECUTE privilege on these functions. - This allows installations to choose to grant usage of such - functions to trusted roles that do not need all superuser - privileges. - - - - - - - Create some built-in roles - that can be used to grant access to what were previously - superuser-only functions (Stephen Frost) - - - - Currently the only such role is pg_signal_backend, - but more are expected to be added in future. - - - - - - - - - Data Types - - - - - - - Improve full-text search to support - searching for phrases, that is, lexemes appearing adjacent to each - other in a specific order, or with a specified distance between - them (Teodor Sigaev, Oleg Bartunov, Dmitry Ivanov) - - - - A phrase-search query can be specified in tsquery - input using the new operators <-> and - <N>. The former means - that the lexemes before and after it must appear adjacent to - each other in that order. The latter means they must be exactly - N lexemes apart. - - - - - - - Allow omitting one or both boundaries in an array slice specifier, - e.g. array_col[3:] (Yury Zhuravlev) - - - - Omitted boundaries are taken as the upper or lower limit of the - corresponding array subscript. This allows simpler specification - for many common use-cases. - - - - - - - Be more careful about out-of-range dates and timestamps (Vitaly - Burovoy) - - - - This change prevents unexpected out-of-range errors for - timestamp with time zone values very close to the - implementation limits. Previously, the same value might - be accepted or not depending on the timezone setting, - meaning that a dump and reload could fail on a value that had been - accepted when presented. Now the limits are enforced according - to the equivalent UTC time, not local time, so as to - be independent of timezone. - - - - Also, PostgreSQL is now more careful to detect - overflow in operations that compute new date or timestamp values, - such as date + integer. - - - - - - - For geometric data types, make sure infinity and - NaN component values are treated consistently during - input and output (Tom Lane) - - - - Such values will now always print the same as they would in - a simple float8 column, and be accepted the same way - on input. Previously the behavior was platform-dependent. - - - - - - - Upgrade - the ispell - dictionary type to handle modern Hunspell files and - support more languages (Artur Zakirov) - - - - - - - Implement look-behind constraints - in regular expressions - (Tom Lane) - - - - A look-behind constraint is like a lookahead constraint in that it - consumes no text; but it checks for existence (or nonexistence) - of a match ending at the current point in the string, rather - than one starting at the current point. Similar features exist - in many other regular-expression engines. - - - - - - - In regular expressions, if an apparent three-digit octal escape - \nnn would exceed 377 (255 decimal), - assume it is a two-digit octal escape instead (Tom Lane) - - - - This makes the behavior match current Tcl releases. - - - - - - - Add transaction ID operators xid <> - xid and xid <> int4, - for consistency with the corresponding equality operators - (Michael Paquier) - - - - - - - - - Functions - - - - - - - Add jsonb_insert() - function to insert a new element into a jsonb array, - or a not-previously-existing key into a jsonb object - (Dmitry Dolgov) - - - - - - - Improve the accuracy of the ln(), log(), - exp(), and pow() functions for type - numeric (Dean Rasheed) - - - - - - - Add a scale(numeric) - function to extract the display scale of a numeric value - (Marko Tiikkaja) - - - - - - - Add trigonometric functions that work in degrees (Dean Rasheed) - - - - For example, sind() - measures its argument in degrees, whereas sin() - measures in radians. These functions go to some lengths to - deliver exact results for values where an exact result can be - expected, for instance sind(30) = 0.5. - - - - - - - Ensure that trigonometric functions handle infinity - and NaN inputs per the POSIX standard - (Dean Rasheed) - - - - The POSIX standard says that these functions should - return NaN for NaN input, and should throw - an error for out-of-range inputs including infinity. - Previously our behavior varied across platforms. - - - - - - - Make to_timestamp(float8) - convert float infinity to - timestamp infinity (Vitaly Burovoy) - - - - Formerly it just failed on an infinite input. - - - - - - - Add new functions for tsvector data (Stas Kelvich) - - - - The new functions are ts_delete(), - ts_filter(), unnest(), - tsvector_to_array(), array_to_tsvector(), - and a variant of setweight() that sets the weight - only for specified lexeme(s). - - - - - - - Allow ts_stat() - and tsvector_update_trigger() - to operate on values that are of types binary-compatible with the - expected argument type, not just exactly that type; for example - allow citext where text is expected (Teodor - Sigaev) - - - - - - - Add variadic functions num_nulls() - and num_nonnulls() that count the number of their - arguments that are null or non-null (Marko Tiikkaja) - - - - An example usage is CHECK(num_nonnulls(a,b,c) = 1) - which asserts that exactly one of a,b,c is not NULL. - These functions can also be used to count the number of null or - nonnull elements in an array. - - - - - - - Add function parse_ident() - to split a qualified, possibly quoted SQL identifier - into its parts (Pavel Stehule) - - - - - - - In to_number(), - interpret a V format code as dividing by 10 to the - power of the number of digits following V (Bruce - Momjian) - - - - This makes it operate in an inverse fashion to - to_char(). - - - - - - - Make the to_reg*() - functions accept type text not cstring - (Petr Korobeinikov) - - - - This avoids the need to write an explicit cast in most cases - where the argument is not a simple literal constant. - - - - - - - Add pg_size_bytes() - function to convert human-readable size strings to numbers (Pavel - Stehule, Vitaly Burovoy, Dean Rasheed) - - - - This function converts strings like those produced by - pg_size_pretty() into bytes. An example - usage is SELECT oid::regclass FROM pg_class WHERE - pg_total_relation_size(oid) > pg_size_bytes('10 GB'). - - - - - - - In pg_size_pretty(), - format negative numbers similarly to positive ones (Adrian - Vondendriesch) - - - - Previously, negative numbers were never abbreviated, just printed - in bytes. - - - - - - - Add an optional missing_ok argument to the current_setting() - function (David Christensen) - - - - This allows avoiding an error for an unrecognized parameter - name, instead returning a NULL. - - - - - - - Change various catalog-inspection functions to return - NULL for invalid input (Michael Paquier) - - - - pg_get_viewdef() - now returns NULL if given an invalid view OID, - and several similar functions likewise return NULL for - bad input. Previously, such cases usually led to cache - lookup failed errors, which are not meant to occur in - user-facing cases. - - - - - - - Fix pg_replication_origin_xact_reset() - to not have any arguments (Fujii Masao) - - - - The documentation said that it has no arguments, and the C code did - not expect any arguments, but the entry in pg_proc - mistakenly specified two arguments. - - - - - - - - - Server-Side Languages - - - - - - - In PL/pgSQL, detect mismatched - CONTINUE and EXIT statements while - compiling a function, rather than at execution time - (Jim Nasby) - - - - - - - Extend PL/Python's error-reporting and - message-reporting functions to allow specifying additional message - fields besides the primary error message (Pavel Stehule) - - - - - - - Allow PL/Python functions to call themselves recursively - via SPI, and fix the behavior when multiple - set-returning PL/Python functions are called within one query - (Alexey Grishchenko, Tom Lane) - - - - - - - Fix session-lifespan memory leaks in PL/Python (Heikki Linnakangas, - Haribabu Kommi, Tom Lane) - - - - - - - Modernize PL/Tcl to use Tcl's object - APIs instead of simple strings (Jim Nasby, Karl - Lehenbauer) - - - - This can improve performance substantially in some cases. - Note that PL/Tcl now requires Tcl 8.4 or later. - - - - - - - In PL/Tcl, make database-reported errors return - additional information in Tcl's errorCode global - variable (Jim Nasby, Tom Lane) - - - - This feature follows the Tcl convention for returning auxiliary - data about an error. - - - - - - - Fix PL/Tcl to perform encoding conversion between - the database encoding and UTF-8, which is what Tcl - expects (Tom Lane) - - - - Previously, strings were passed through without conversion, - leading to misbehavior with non-ASCII characters when - the database encoding was not UTF-8. - - - - - - - - - Client Interfaces - - - - - - - Add a nonlocalized version of - the severity field in - error and notice messages (Tom Lane) - - - - This change allows client code to determine severity of an error or - notice without having to worry about localized variants of the - severity strings. - - - - - - - Introduce a feature in libpq whereby the - CONTEXT field of messages can be suppressed, either - always or only for non-error messages (Pavel Stehule) - - - - The default behavior of PQerrorMessage() - is now to print CONTEXT - only for errors. The new function PQsetErrorContextVisibility() - can be used to adjust this. - - - - - - - Add support in libpq for regenerating an error - message with a different verbosity level (Alex Shulgin) - - - - This is done with the new function PQresultVerboseErrorMessage(). - This supports psql's new \errverbose - feature, and may be useful for other clients as well. - - - - - - - Improve libpq's PQhost() function to return - useful data for default Unix-socket connections (Tom Lane) - - - - Previously it would return NULL if no explicit host - specification had been given; now it returns the default socket - directory path. - - - - - - - Fix ecpg's lexer to handle line breaks within - comments starting on preprocessor directive lines (Michael Meskes) - - - - - - - - - Client Applications - - - - - - - Add a option - to pg_dump - and pg_restore - (Pavel Stehule) - - - - This option causes the program to complain if there is no match - for a or option, rather - than silently doing nothing. - - - - - - - In pg_dump, dump locally-made changes of privilege - assignments for system objects (Stephen Frost) - - - - While it has always been possible for a superuser to change - the privilege assignments for built-in or extension-created - objects, such changes were formerly lost in a dump and reload. - Now, pg_dump recognizes and dumps such changes. - (This works only when dumping from a 9.6 or later server, however.) - - - - - - - Allow pg_dump to dump non-extension-owned objects - that are within an extension-owned schema - (Martín Marqués) - - - - Previously such objects were ignored because they were mistakenly - assumed to belong to the extension owning their schema. - - - - - - - In pg_dump output, include the table name in object - tags for object types that are only uniquely named per-table - (for example, triggers) (Peter Eisentraut) - - - - - - - <xref linkend="app-psql"/> - - - - - - - Support multiple and - command-line options (Pavel Stehule, Catalin Iacob) - - - - The specified operations are carried out in the order in which the - options are given, and then psql terminates. - - - - - - - Add a \crosstabview command that prints the results of - a query in a cross-tabulated display (Daniel Vérité) - - - - In the crosstab display, data values from one query result column - are placed in a grid whose column and row headers come from other - query result columns. - - - - - - - Add an \errverbose command that shows the last server - error at full verbosity (Alex Shulgin) - - - - This is useful after getting an unexpected error — you - no longer need to adjust the VERBOSITY variable and - recreate the failure in order to see error fields that are not - shown by default. - - - - - - - Add \ev and \sv commands for editing and - showing view definitions (Petr Korobeinikov) - - - - These are parallel to the existing \ef and - \sf commands for functions. - - - - - - - Add a \gexec command that executes a query and - re-submits the result(s) as new queries (Corey Huinker) - - - - - - - Allow \pset C string - to set the table title, for consistency with \C - string (Bruce Momjian) - - - - - - - In \pset expanded auto mode, do not use expanded - format for query results with only one column (Andreas Karlsson, - Robert Haas) - - - - - - - Improve the headers output by the \watch command - (Michael Paquier, Tom Lane) - - - - Include the \pset title string if one has - been set, and shorten the prefabricated part of the - header to be timestamp (every - Ns). Also, the timestamp format now - obeys psql's locale environment. - - - - - - - Improve tab-completion logic to consider the entire input query, - not only the current line (Tom Lane) - - - - Previously, breaking a command into multiple lines defeated any - tab completion rules that needed to see words on earlier lines. - - - - - - - Numerous minor improvements in tab-completion behavior (Peter - Eisentraut, Vik Fearing, Kevin Grittner, Kyotaro Horiguchi, Jeff - Janes, Andreas Karlsson, Fujii Masao, Thomas Munro, Masahiko - Sawada, Pavel Stehule) - - - - - - - Add a PROMPT option %p to insert the - process ID of the connected backend (Julien Rouhaud) - - - - - - - Introduce a feature whereby the CONTEXT field of - messages can be suppressed, either always or only for non-error - messages (Pavel Stehule) - - - - Printing CONTEXT only for errors is now the default - behavior. This can be changed by setting the special variable - SHOW_CONTEXT. - - - - - - - Make \df+ show function access privileges and - parallel-safety attributes (Michael Paquier) - - - - - - - - - <xref linkend="pgbench"/> - - - - - - - SQL commands in pgbench scripts are now ended by - semicolons, not newlines (Kyotaro Horiguchi, Tom Lane) - - - - This change allows SQL commands in scripts to span multiple lines. - Existing custom scripts will need to be modified to add a semicolon - at the end of each line that does not have one already. (Doing so - does not break the script for use with older versions - of pgbench.) - - - - - - - Support floating-point arithmetic, as well as some built-in functions, in - expressions in backslash commands (Fabien Coelho) - - - - - - - Replace \setrandom with built-in functions (Fabien - Coelho) - - - - The new built-in functions include random(), - random_exponential(), and - random_gaussian(), which perform the same work as - \setrandom, but are easier to use since they can be - embedded in larger expressions. Since these additions have made - \setrandom obsolete, remove it. - - - - - - - Allow invocation of multiple copies of the built-in scripts, - not only custom scripts (Fabien Coelho) - - - - This is done with the new switch, which works - similarly to for custom scripts. - - - - - - - Allow changing the selection probabilities (weights) for scripts - (Fabien Coelho) - - - - When multiple scripts are specified, each pgbench - transaction randomly chooses one to execute. Formerly this was - always done with uniform probability, but now different selection - probabilities can be specified for different scripts. - - - - - - - Collect statistics for each script in a multi-script run (Fabien - Coelho) - - - - This feature adds an intermediate level of detail to existing - global and per-command statistics printouts. - - - - - - - Add a option to report progress - with Unix epoch timestamps, instead of time since the run started - (Fabien Coelho) - - - - - - - Allow the number of client connections () to not - be an exact multiple of the number of threads () - (Fabien Coelho) - - - - - - - When the option is used, stop promptly at the end - of the specified time (Fabien Coelho) - - - - Previously, specifying a low transaction rate could cause - pgbench to wait significantly longer than - specified. - - - - - - - - - - - Server Applications - - - - - - - Improve error reporting during initdb's - post-bootstrap phase (Tom Lane) - - - - Previously, an error here led to reporting the entire input - file as the failing query; now just the current - query is reported. To get the desired behavior, queries in - initdb's input files must be separated by blank - lines. - - - - - - - Speed up initdb by using just one - standalone-backend session for all the post-bootstrap steps - (Tom Lane) - - - - - - - Improve pg_rewind - so that it can work when the target timeline changes (Alexander - Korotkov) - - - - This allows, for example, rewinding a promoted standby back to - some state of the old master's timeline. - - - - - - - - - Source Code - - - - - - - Remove obsolete - heap_formtuple/heap_modifytuple/heap_deformtuple - functions (Peter Geoghegan) - - - - - - - Add macros to make AllocSetContextCreate() calls simpler - and safer (Tom Lane) - - - - Writing out the individual sizing parameters for a memory context - is now deprecated in favor of using one of the new - macros ALLOCSET_DEFAULT_SIZES, - ALLOCSET_SMALL_SIZES, - or ALLOCSET_START_SMALL_SIZES. - Existing code continues to work, however. - - - - - - - Unconditionally use static inline functions in header - files (Andres Freund) - - - - This may result in warnings and/or wasted code space with very - old compilers, but the notational improvement seems worth it. - - - - - - - Improve TAP testing infrastructure (Michael - Paquier, Craig Ringer, Álvaro Herrera, Stephen Frost) - - - - Notably, it is now possible to test recovery scenarios using - this infrastructure. - - - - - - - Make trace_lwlocks identify individual locks by name - (Robert Haas) - - - - - - - Improve psql's tab-completion code infrastructure - (Thomas Munro, Michael Paquier) - - - - Tab-completion rules are now considerably easier to write, and - more compact. - - - - - - - Nail the pg_shseclabel system catalog into cache, - so that it is available for access during connection authentication - (Adam Brightwell) - - - - The core code does not use this catalog for authentication, - but extensions might wish to consult it. - - - - - - - Restructure index access - method API to hide most of it at - the C level (Alexander Korotkov, Andrew Gierth) - - - - This change modernizes the index AM API to look more - like the designs we have adopted for foreign data wrappers and - tablesample handlers. This simplifies the C code - and makes it much more practical to define index access methods in - installable extensions. A consequence is that most of the columns - of the pg_am system catalog have disappeared. - New inspection - functions have been added to allow SQL queries to determine - index AM properties that used to be discoverable - from pg_am. - - - - - - - Add pg_init_privs - system catalog to hold original privileges - of initdb-created and extension-created objects - (Stephen Frost) - - - - This infrastructure allows pg_dump to dump changes - that an installation may have made in privileges attached to - system objects. Formerly, such changes would be lost in a dump - and reload, but now they are preserved. - - - - - - - Change the way that extensions allocate custom LWLocks - (Amit Kapila, Robert Haas) - - - - The RequestAddinLWLocks() function is removed, - and replaced by RequestNamedLWLockTranche(). - This allows better identification of custom LWLocks, - and is less error-prone. - - - - - - - Improve the isolation tester to allow multiple sessions to wait - concurrently, allowing testing of deadlock scenarios (Robert Haas) - - - - - - - Introduce extensible node types (KaiGai Kohei) - - - - This change allows FDWs or custom scan providers - to store data in a plan tree in a more convenient format than - was previously possible. - - - - - - - Make the planner deal with post-scan/join query steps by generating - and comparing Paths, replacing a lot of ad-hoc logic - (Tom Lane) - - - - This change provides only marginal user-visible improvements today, - but it enables future work on a lot of upper-planner improvements - that were impractical to tackle using the old code structure. - - - - - - - Support partial aggregation (David Rowley, Simon Riggs) - - - - This change allows the computation of an aggregate function to be - split into separate parts, for example so that parallel worker - processes can cooperate on computing an aggregate. In future - it might allow aggregation across local and remote data to occur - partially on the remote end. - - - - - - - Add a generic command progress reporting facility (Vinayak Pokale, - Rahila Syed, Amit Langote, Robert Haas) - - - - - - - Separate out psql's flex lexer to - make it usable by other client programs (Tom Lane, Kyotaro - Horiguchi) - - - - This eliminates code duplication for programs that need to be able - to parse SQL commands well enough to identify command boundaries. - Doing that in full generality is more painful than one could - wish, and up to now only psql has really gotten - it right among our supported client programs. - - - - A new source-code subdirectory src/fe_utils/ has - been created to hold this and other code that is shared across - our client programs. Formerly such sharing was accomplished by - symbolic linking or copying source files at build time, which - was ugly and required duplicate compilation. - - - - - - - Introduce WaitEventSet API to allow - efficient waiting for event sets that usually do not change from - one wait to the next (Andres Freund, Amit Kapila) - - - - - - - Add a generic interface for writing WAL records - (Alexander Korotkov, Petr Jelínek, Markus Nullmeier) - - - - This change allows extensions to write WAL records for - changes to pages using a standard layout. The problem of needing to - replay WAL without access to the extension is solved by - having generic replay code. This allows extensions to implement, - for example, index access methods and have WAL - support for them. - - - - - - - Support generic WAL messages for logical decoding - (Petr Jelínek, Andres Freund) - - - - This feature allows extensions to insert data into the - WAL stream that can be read by logical-decoding - plugins, but is not connected to physical data restoration. - - - - - - - Allow SP-GiST operator classes to store an arbitrary - traversal value while descending the index (Alexander - Lebedev, Teodor Sigaev) - - - - This is somewhat like the reconstructed value, but it - could be any arbitrary chunk of data, not necessarily of the same - data type as the indexed column. - - - - - - - Introduce a LOG_SERVER_ONLY message level for - ereport() (David Steele) - - - - This level acts like LOG except that the message is - never sent to the client. It is meant for use in auditing and - similar applications. - - - - - - - Provide a Makefile target to build all generated - headers (Michael Paquier, Tom Lane) - - - - submake-generated-headers can now be invoked to ensure - that generated backend header files are up-to-date. This is - useful in subdirectories that might be built standalone. - - - - - - - Support OpenSSL 1.1.0 (Andreas Karlsson, Heikki Linnakangas) - - - - - - - - - Additional Modules - - - - - - - Add configuration parameter auto_explain.sample_rate to - allow contrib/auto_explain - to capture just a configurable fraction of all queries (Craig - Ringer, Julien Rouhaud) - - - - This allows reduction of overhead for heavy query traffic, while - still getting useful information on average. - - - - - - - Add contrib/bloom module that - implements an index access method based on Bloom filtering (Teodor - Sigaev, Alexander Korotkov) - - - - This is primarily a proof-of-concept for non-core index access - methods, but it could be useful in its own right for queries that - search many columns. - - - - - - - In contrib/cube, introduce - distance operators for cubes, and support kNN-style searches in - GiST indexes on cube columns (Stas Kelvich) - - - - - - - Make contrib/hstore's hstore_to_jsonb_loose() - and hstore_to_json_loose() functions agree on what - is a number (Tom Lane) - - - - Previously, hstore_to_jsonb_loose() would convert - numeric-looking strings to JSON numbers, rather than - strings, even if they did not exactly match the JSON - syntax specification for numbers. This was inconsistent with - hstore_to_json_loose(), so tighten the test to match - the JSON syntax. - - - - - - - Add selectivity estimation functions for - contrib/intarray operators - to improve plans for queries using those operators (Yury Zhuravlev, - Alexander Korotkov) - - - - - - - Make contrib/pageinspect's - heap_page_items() function show the raw data in each - tuple, and add new functions tuple_data_split() and - heap_page_item_attrs() for inspection of individual - tuple fields (Nikolay Shaplov) - - - - - - - Add an optional S2K iteration count parameter to - contrib/pgcrypto's - pgp_sym_encrypt() function (Jeff Janes) - - - - - - - Add support for word similarity to - contrib/pg_trgm - (Alexander Korotkov, Artur Zakirov) - - - - These functions and operators measure the similarity between one - string and the most similar single word of another string. - - - - - - - Add configuration parameter - pg_trgm.similarity_threshold for - contrib/pg_trgm's similarity threshold (Artur Zakirov) - - - - This threshold has always been configurable, but formerly it was - controlled by special-purpose functions set_limit() - and show_limit(). Those are now deprecated. - - - - - - - Improve contrib/pg_trgm's GIN operator class to - speed up index searches in which both common and rare keys appear - (Jeff Janes) - - - - - - - Improve performance of similarity searches in - contrib/pg_trgm GIN indexes (Christophe Fornaroli) - - - - - - - Add contrib/pg_visibility module - to allow examining table visibility maps (Robert Haas) - - - - - - - Add ssl_extension_info() - function to contrib/sslinfo, to print information - about SSL extensions present in the X509 - certificate used for the current connection (Dmitry Voronin) - - - - - - - <link linkend="postgres-fdw"><filename>postgres_fdw</filename></link> - - - - - - - Allow extension-provided operators and functions to be sent for - remote execution, if the extension is whitelisted in the foreign - server's options (Paul Ramsey) - - - - Users can enable this feature when the extension is known to exist - in a compatible version in the remote database. It allows more - efficient execution of queries involving extension operators. - - - - - - - Consider performing sorts on the remote server (Ashutosh Bapat) - - - - - - - Consider performing joins on the remote server (Shigeru Hanada, - Ashutosh Bapat) - - - - - - - When feasible, perform UPDATE or DELETE - entirely on the remote server (Etsuro Fujita) - - - - Formerly, remote updates involved sending a SELECT FOR UPDATE - command and then updating or deleting the selected rows one-by-one. - While that is still necessary if the operation requires any local - processing, it can now be done remotely if all elements of the - query are safe to send to the remote server. - - - - - - - Allow the fetch size to be set as a server or table option - (Corey Huinker) - - - - Formerly, postgres_fdw always fetched 100 rows at - a time from remote queries; now that behavior is configurable. - - - - - - - Use a single foreign-server connection for local user IDs that - all map to the same remote user (Ashutosh Bapat) - - - - - - - Transmit query cancellation requests to the remote server - (Michael Paquier, Etsuro Fujita) - - - - Previously, a local query cancellation request did not cause an - already-sent remote query to terminate early. - - - - - - - - - - - - diff --git a/doc/src/sgml/release-old.sgml b/doc/src/sgml/release-old.sgml deleted file mode 100644 index d55209d85b1..00000000000 --- a/doc/src/sgml/release-old.sgml +++ /dev/null @@ -1,6557 +0,0 @@ - - - - - Release 7.3.21 - - - Release date: - 2008-01-07 - - - - This release contains a variety of fixes from 7.3.20, - including fixes for significant security issues. - - - - This is expected to be the last PostgreSQL release - in the 7.3.X series. Users are encouraged to update to a newer - release branch soon. - - - - Migration to Version 7.3.21 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - - - - - Prevent functions in indexes from executing with the privileges of - the user running VACUUM, ANALYZE, etc (Tom) - - - - Functions used in index expressions and partial-index - predicates are evaluated whenever a new table entry is made. It has - long been understood that this poses a risk of trojan-horse code - execution if one modifies a table owned by an untrustworthy user. - (Note that triggers, defaults, check constraints, etc. pose the - same type of risk.) But functions in indexes pose extra danger - because they will be executed by routine maintenance operations - such as VACUUM FULL, which are commonly performed - automatically under a superuser account. For example, a nefarious user - can execute code with superuser privileges by setting up a - trojan-horse index definition and waiting for the next routine vacuum. - The fix arranges for standard maintenance operations - (including VACUUM, ANALYZE, REINDEX, - and CLUSTER) to execute as the table owner rather than - the calling user, using the same privilege-switching mechanism already - used for SECURITY DEFINER functions. To prevent bypassing - this security measure, execution of SET SESSION - AUTHORIZATION and SET ROLE is now forbidden within a - SECURITY DEFINER context. (CVE-2007-6600) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - The fix that appeared for this in 7.3.20 was incomplete, as it plugged - the hole for only some dblink functions. (CVE-2007-6601, - CVE-2007-3278) - - - - - - Fix potential crash in translate() when using a multibyte - database encoding (Tom) - - - - - - Make contrib/tablefunc's crosstab() handle - NULL rowid as a category in its own right, rather than crashing (Joe) - - - - - - Require a specific version of Autoconf to be used - when re-generating the configure script (Peter) - - - - This affects developers and packagers only. The change was made - to prevent accidental use of untested combinations of - Autoconf and PostgreSQL versions. - You can remove the version check if you really want to use a - different Autoconf version, but it's - your responsibility whether the result works or not. - - - - - - - - - - Release 7.3.20 - - - Release date: - 2007-09-17 - - - - This release contains fixes from 7.3.19. - - - - Migration to Version 7.3.20 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - - - - - Prevent index corruption when a transaction inserts rows and - then aborts close to the end of a concurrent VACUUM - on the same table (Tom) - - - - - - Make CREATE DOMAIN ... DEFAULT NULL work properly (Tom) - - - - - - Fix crash when log_min_error_statement logging runs out - of memory (Tom) - - - - - - Require non-superusers who use /contrib/dblink to use only - password authentication, as a security measure (Joe) - - - - - - - - - - Release 7.3.19 - - - Release date: - 2007-04-23 - - - - This release contains fixes from 7.3.18, - including a security fix. - - - - Migration to Version 7.3.19 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - - - - - Support explicit placement of the temporary-table schema within - search_path, and disable searching it for functions - and operators (Tom) - - - This is needed to allow a security-definer function to set a - truly secure value of search_path. Without it, - an unprivileged SQL user can use temporary objects to execute code - with the privileges of the security-definer function (CVE-2007-2138). - See CREATE FUNCTION for more information. - - - - - - Fix potential-data-corruption bug in how VACUUM FULL handles - UPDATE chains (Tom, Pavan Deolasee) - - - - - - - - - - Release 7.3.18 - - - Release date: - 2007-02-05 - - - - This release contains a variety of fixes from 7.3.17, including - a security fix. - - - - Migration to Version 7.3.18 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - - - - - Remove security vulnerability that allowed connected users - to read backend memory (Tom) - - - The vulnerability involves changing the - data type of a table column used in a SQL function (CVE-2007-0555). - This error can easily be exploited to cause a backend crash, and in - principle might be used to read database content that the user - should not be able to access. - - - - - - Fix rare bug wherein btree index page splits could fail - due to choosing an infeasible split point (Heikki Linnakangas) - - - - - - Tighten security of multi-byte character processing for UTF8 sequences - over three bytes long (Tom) - - - - - - - - - - Release 7.3.17 - - - Release date: - 2007-01-08 - - - - This release contains a variety of fixes from 7.3.16. - - - - Migration to Version 7.3.17 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - - - - - to_number() and to_char(numeric) - are now STABLE, not IMMUTABLE, for - new initdb installs (Tom) - - - - This is because lc_numeric can potentially - change the output of these functions. - - - - - - Improve index usage of regular expressions that use parentheses (Tom) - - - - This improves psql \d performance also. - - - - - - - - - - Release 7.3.16 - - - Release date: - 2006-10-16 - - - - This release contains a variety of fixes from 7.3.15. - - - - Migration to Version 7.3.16 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - - Changes - - -Fix corner cases in pattern matching for - psql's \d commands -Fix index-corrupting bugs in /contrib/ltree - (Teodor) -Back-port 7.4 spinlock code to improve performance and support -64-bit architectures better -Fix SSL-related memory leak in libpq -Fix backslash escaping in /contrib/dbmirror -Adjust regression tests for recent changes in US DST laws - - - - - - - - Release 7.3.15 - - - Release date: - 2006-05-23 - - - - This release contains a variety of fixes from 7.3.14, - including patches for extremely serious security issues. - - - - Migration to Version 7.3.15 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - Full security against the SQL-injection attacks described in - CVE-2006-2313 and CVE-2006-2314 might require changes in application - code. If you have applications that embed untrustworthy strings - into SQL commands, you should examine them as soon as possible to - ensure that they are using recommended escaping techniques. In - most cases, applications should be using subroutines provided by - libraries or drivers (such as libpq's - PQescapeStringConn()) to perform string escaping, - rather than relying on ad hoc code to do it. - - - - - Changes - - -Change the server to reject invalidly-encoded multibyte -characters in all cases (Tatsuo, Tom) -While PostgreSQL has been moving in this direction for -some time, the checks are now applied uniformly to all encodings and all -textual input, and are now always errors not merely warnings. This change -defends against SQL-injection attacks of the type described in CVE-2006-2313. - - -Reject unsafe uses of \' in string literals -As a server-side defense against SQL-injection attacks of the type -described in CVE-2006-2314, the server now only accepts '' and not -\' as a representation of ASCII single quote in SQL string -literals. By default, \' is rejected only when -client_encoding is set to a client-only encoding (SJIS, BIG5, GBK, -GB18030, or UHC), which is the scenario in which SQL injection is possible. -A new configuration parameter backslash_quote is available to -adjust this behavior when needed. Note that full security against -CVE-2006-2314 might require client-side changes; the purpose of -backslash_quote is in part to make it obvious that insecure -clients are insecure. - - -Modify libpq's string-escaping routines to be -aware of encoding considerations -This fixes libpq-using applications for the security -issues described in CVE-2006-2313 and CVE-2006-2314. -Applications that use multiple PostgreSQL connections -concurrently should migrate to PQescapeStringConn() and -PQescapeByteaConn() to ensure that escaping is done correctly -for the settings in use in each database connection. Applications that -do string escaping by hand should be modified to rely on library -routines instead. - - -Fix some incorrect encoding conversion functions -win1251_to_iso, alt_to_iso, -euc_tw_to_big5, euc_tw_to_mic, -mic_to_euc_tw were all broken to varying -extents. - - -Clean up stray remaining uses of \' in strings -(Bruce, Jan) - -Fix server to use custom DH SSL parameters correctly (Michael -Fuhr) - -Fix various minor memory leaks - - - - - - - Release 7.3.14 - - - Release date: - 2006-02-14 - - - - This release contains a variety of fixes from 7.3.13. - - - - Migration to Version 7.3.14 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.13, - see . - - - - - Changes - - - -Fix potential crash in SET -SESSION AUTHORIZATION (CVE-2006-0553) -An unprivileged user could crash the server process, resulting in -momentary denial of service to other users, if the server has been compiled -with Asserts enabled (which is not the default). -Thanks to Akio Ishida for reporting this problem. - - -Fix bug with row visibility logic in self-inserted -rows (Tom) -Under rare circumstances a row inserted by the current command -could be seen as already valid, when it should not be. Repairs bug -created in 7.3.11 release. - - -Fix race condition that could lead to file already -exists errors during pg_clog file creation -(Tom) - -Fix to allow restoring dumps that have cross-schema -references to custom operators (Tom) - -Portability fix for testing presence of finite -and isinf during configure (Tom) - - - - - - - - Release 7.3.13 - - - Release date: - 2006-01-09 - - - - This release contains a variety of fixes from 7.3.12. - - - - Migration to Version 7.3.13 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.10, - see . - Also, you might need to REINDEX indexes on textual - columns after updating, if you are affected by the locale or - plperl issues described below. - - - - - Changes - - - -Fix character string comparison for locales that consider -different character combinations as equal, such as Hungarian (Tom) -This might require REINDEX to fix existing indexes on -textual columns. - -Set locale environment variables during postmaster startup -to ensure that plperl won't change the locale later -This fixes a problem that occurred if the postmaster was -started with environment variables specifying a different locale than what -initdb had been told. Under these conditions, any use of -plperl was likely to lead to corrupt indexes. You might need -REINDEX to fix existing indexes on -textual columns if this has happened to you. - -Fix longstanding bug in strpos() and regular expression -handling in certain rarely used Asian multi-byte character sets (Tatsuo) - - -Fix bug in /contrib/pgcrypto gen_salt, -which caused it not to use all available salt space for MD5 and -XDES algorithms (Marko Kreen, Solar Designer) -Salts for Blowfish and standard DES are unaffected. - -Fix /contrib/dblink to throw an error, -rather than crashing, when the number of columns specified is different from -what's actually returned by the query (Joe) - - - - - - - - Release 7.3.12 - - - Release date: - 2005-12-12 - - - - This release contains a variety of fixes from 7.3.11. - - - - Migration to Version 7.3.12 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.10, - see . - - - - - Changes - - - -Fix race condition in transaction log management -There was a narrow window in which an I/O operation could be initiated -for the wrong page, leading to an Assert failure or data -corruption. - - -/contrib/ltree fixes (Teodor) - -Fix longstanding planning error for outer joins -This bug sometimes caused a bogus error RIGHT JOIN is -only supported with merge-joinable join conditions. - -Prevent core dump in pg_autovacuum when a -table has been dropped - - - - - - - - Release 7.3.11 - - - Release date: - 2005-10-04 - - - - This release contains a variety of fixes from 7.3.10. - - - - Migration to Version 7.3.11 - - - A dump/restore is not required for those running 7.3.X. However, - if you are upgrading from a version earlier than 7.3.10, - see . - - - - - Changes - - -Fix error that allowed VACUUM to remove -ctid chains too soon, and add more checking in code that follows -ctid links -This fixes a long-standing problem that could cause crashes in very rare -circumstances. -Fix CHAR() to properly pad spaces to the specified -length when using a multiple-byte character set (Yoshiyuki Asaba) -In prior releases, the padding of CHAR() was incorrect -because it only padded to the specified number of bytes without -considering how many characters were stored. -Fix missing rows in queries like UPDATE a=... WHERE -a... with GiST index on column a -Improve checking for partially-written WAL -pages -Improve robustness of signal handling when SSL is -enabled -Various memory leakage fixes -Various portability improvements -Fix PL/pgSQL to handle var := var correctly when -the variable is of pass-by-reference type - - - - - - - Release 7.3.10 - - - Release date: - 2005-05-09 - - - - This release contains a variety of fixes from 7.3.9, including several - security-related issues. - - - - Migration to Version 7.3.10 - - - A dump/restore is not required for those running 7.3.X. However, - it is one possible way of handling a significant security problem - that has been found in the initial contents of 7.3.X system - catalogs. A dump/initdb/reload sequence using 7.3.10's initdb will - automatically correct this problem. - - - - The security problem is that the built-in character set encoding - conversion functions can be invoked from SQL commands by unprivileged - users, but the functions were not designed for such use and are not - secure against malicious choices of arguments. The fix involves changing - the declared parameter list of these functions so that they can no longer - be invoked from SQL commands. (This does not affect their normal use - by the encoding conversion machinery.) - It is strongly recommended that all installations repair this error, - either by initdb or by following the manual repair procedure given - below. The error at least allows unprivileged database users to crash - their server process, and might allow unprivileged users to gain the - privileges of a database superuser. - - - - If you wish not to do an initdb, perform the following procedure instead. - As the database superuser, do: - - -BEGIN; -UPDATE pg_proc SET proargtypes[3] = 'internal'::regtype -WHERE pronamespace = 11 AND pronargs = 5 - AND proargtypes[2] = 'cstring'::regtype; --- The command should report having updated 90 rows; --- if not, rollback and investigate instead of committing! -COMMIT; - - - - - The above procedure must be carried out in each database - of an installation, including template1, and ideally - including template0 as well. If you do not fix the - template databases then any subsequently created databases will contain - the same error. template1 can be fixed in the same way - as any other database, but fixing template0 requires - additional steps. First, from any database issue: - -UPDATE pg_database SET datallowconn = true WHERE datname = 'template0'; - - Next connect to template0 and perform the above repair - procedure. Finally, do: - --- re-freeze template0: -VACUUM FREEZE; --- and protect it against future alterations: -UPDATE pg_database SET datallowconn = false WHERE datname = 'template0'; - - - - - - Changes - - -Change encoding function signature to prevent -misuse -Repair ancient race condition that allowed a transaction to be -seen as committed for some purposes (eg SELECT FOR UPDATE) slightly sooner -than for other purposes -This is an extremely serious bug since it could lead to apparent -data inconsistencies being briefly visible to applications. -Repair race condition between relation extension and -VACUUM -This could theoretically have caused loss of a page's worth of -freshly-inserted data, although the scenario seems of very low probability. -There are no known cases of it having caused more than an Assert failure. - -Fix comparisons of TIME WITH TIME ZONE values - -The comparison code was wrong in the case where the ---enable-integer-datetimes configuration switch had been used. -NOTE: if you have an index on a TIME WITH TIME ZONE column, -it will need to be REINDEXed after installing this update, because -the fix corrects the sort order of column values. - -Fix EXTRACT(EPOCH) for -TIME WITH TIME ZONE values -Fix mis-display of negative fractional seconds in -INTERVAL values - -This error only occurred when the ---enable-integer-datetimes configuration switch had been used. - -Additional buffer overrun checks in plpgsql -(Neil) -Fix pg_dump to dump trigger names containing % -correctly (Neil) -Prevent to_char(interval) from dumping core for -month-related formats -Fix contrib/pgcrypto for newer OpenSSL builds -(Marko Kreen) -Still more 64-bit fixes for -contrib/intagg -Prevent incorrect optimization of functions returning -RECORD - - - - - - - Release 7.3.9 - - - Release date: - 2005-01-31 - - - - This release contains a variety of fixes from 7.3.8, including several - security-related issues. - - - - Migration to Version 7.3.9 - - - A dump/restore is not required for those running 7.3.X. - - - - - Changes - - -Disallow LOAD to non-superusers - -On platforms that will automatically execute initialization functions of a -shared library (this includes at least Windows and ELF-based Unixen), -LOAD can be used to make the server execute arbitrary code. -Thanks to NGS Software for reporting this. -Check that creator of an aggregate function has the right to -execute the specified transition functions - -This oversight made it possible to bypass denial of EXECUTE -permission on a function. -Fix security and 64-bit issues in -contrib/intagg -Add needed STRICT marking to some contrib functions (Kris -Jurka) -Avoid buffer overrun when plpgsql cursor declaration has too -many parameters (Neil) -Fix planning error for FULL and RIGHT outer joins - -The result of the join was mistakenly supposed to be sorted the same as the -left input. This could not only deliver mis-sorted output to the user, but -in case of nested merge joins could give outright wrong answers. - -Fix plperl for quote marks in tuple fields -Fix display of negative intervals in SQL and GERMAN -datestyles - - - - - - - Release 7.3.8 - - - Release date: - 2004-10-22 - - - - This release contains a variety of fixes from 7.3.7. - - - - - Migration to Version 7.3.8 - - - A dump/restore is not required for those running 7.3.X. - - - - - Changes - - -Repair possible failure to update hint bits on disk - -Under rare circumstances this oversight could lead to -could not access transaction status failures, which qualifies -it as a potential-data-loss bug. - -Ensure that hashed outer join does not miss tuples - -Very large left joins using a hash join plan could fail to output unmatched -left-side rows given just the right data distribution. - -Disallow running pg_ctl as root - -This is to guard against any possible security issues. - -Avoid using temp files in /tmp in make_oidjoins_check - -This has been reported as a security issue, though it's hardly worthy of -concern since there is no reason for non-developers to use this script anyway. - - - - - - - - Release 7.3.7 - - - Release date: - 2004-08-16 - - - - This release contains one critical fix over 7.3.6, and some minor items. - - - - - Migration to Version 7.3.7 - - - A dump/restore is not required for those running 7.3.X. - - - - - Changes - - -Prevent possible loss of committed transactions during crash - -Due to insufficient interlocking between transaction commit and checkpointing, -it was possible for transactions committed just before the most recent -checkpoint to be lost, in whole or in part, following a database crash and -restart. This is a serious bug that has existed -since PostgreSQL 7.1. - -Remove asymmetrical word processing in tsearch (Teodor) -Properly schema-qualify function names when pg_dump'ing a CAST - - - - - - - Release 7.3.6 - - - Release date: - 2004-03-02 - - - - This release contains a variety of fixes from 7.3.5. - - - - - Migration to Version 7.3.6 - - - A dump/restore is not required for those - running 7.3.*. - - - - - - Changes - - -Revert erroneous changes in rule permissions checking -A patch applied in 7.3.3 to fix a corner case in rule permissions checks -turns out to have disabled rule-related permissions checks in many -not-so-corner cases. This would for example allow users to insert into views -they weren't supposed to have permission to insert into. We have therefore -reverted the 7.3.3 patch. The original bug will be fixed in 8.0. - -Repair incorrect order of operations in -GetNewTransactionId() - -This bug could result in failure under out-of-disk-space conditions, including -inability to restart even after disk space is freed. - -Ensure configure selects -fno-strict-aliasing even when -an external value for CFLAGS is supplied - -On some platforms, building with -fstrict-aliasing causes bugs. - -Make pg_restore handle 64-bit off_t correctly - -This bug prevented proper restoration from archive files exceeding 4 GB. - -Make contrib/dblink not assume that local and remote type OIDs -match (Joe) -Quote connectby()'s start_with argument properly (Joe) -Don't crash when a rowtype argument to a plpgsql function is -NULL -Avoid generating invalid character encoding sequences in -corner cases when planning LIKE operations -Ensure text_position() cannot scan past end of source string -in multibyte cases (Korea PostgreSQL Users' Group) -Fix index optimization and selectivity estimates for LIKE -operations on bytea columns (Joe) - - - - - - - Release 7.3.5 - - - Release date: - 2003-12-03 - - - - This has a variety of fixes from 7.3.4. - - - - - Migration to Version 7.3.5 - - - A dump/restore is not required for those - running 7.3.*. - - - - - Changes - - -Force zero_damaged_pages to be on during recovery from WAL -Prevent some obscure cases of variable not in subplan target lists -Force stats processes to detach from shared memory, ensuring cleaner shutdown -Make PQescapeBytea and byteaout consistent with each other (Joe) -Added missing SPI_finish() calls to dblink's get_tuple_of_interest() (Joe) -Fix for possible foreign key violation when rule rewrites INSERT (Jan) -Support qualified type names in PL/Tcl's spi_prepare command (Jan) -Make pg_dump handle a procedural language handler located in pg_catalog -Make pg_dump handle cases where a custom opclass is in another schema -Make pg_dump dump binary-compatible casts correctly (Jan) -Fix insertion of expressions containing subqueries into rule bodies -Fix incorrect argument processing in clusterdb script (Anand Ranganathan) -Fix problems with dropped columns in plpython triggers -Repair problems with to_char() reading past end of its input string (Karel) -Fix GB18030 mapping errors (Tatsuo) -Fix several problems with SSL error handling and asynchronous SSL I/O -Remove ability to bind a list of values to a single parameter in JDBC -(prevents possible SQL-injection attacks) -Fix some errors in HAVE_INT64_TIMESTAMP code paths -Fix corner case for btree search in parallel with first root page split - - - - - - - Release 7.3.4 - - - Release date: - 2003-07-24 - - - - This has a variety of fixes from 7.3.3. - - - - - Migration to Version 7.3.4 - - - A dump/restore is not required for those - running 7.3.*. - - - - - Changes - - -Repair breakage in timestamp-to-date conversion for dates before 2000 -Prevent rare possibility of server startup failure (Tom) -Fix bugs in interval-to-time conversion (Tom) -Add constraint names in a few places in pg_dump (Rod) -Improve performance of functions with many parameters (Tom) -Fix to_ascii() buffer overruns (Tom) -Prevent restore of database comments from throwing an error (Tom) -Work around buggy strxfrm() present in some Solaris releases (Tom) -Properly escape jdbc setObject() strings to improve security (Barry) - - - - - - - Release 7.3.3 - - - Release date: - 2003-05-22 - - - - This release contains a variety of fixes for version 7.3.2. - - - - Migration to Version 7.3.3 - - - A dump/restore is not required for those - running version 7.3.*. - - - - - Changes - - -Repair sometimes-incorrect computation of StartUpID after a crash -Avoid slowness with lots of deferred triggers in one transaction (Stephan) -Don't lock referenced row when UPDATE doesn't change foreign key's value (Jan) -Use -fPIC not -fpic on Sparc (Tom Callaway) -Repair lack of schema-awareness in contrib/reindexdb -Fix contrib/intarray error for zero-element result array (Teodor) -Ensure createuser script will exit on control-C (Oliver) -Fix errors when the type of a dropped column has itself been dropped -CHECKPOINT does not cause database panic on failure in noncritical steps -Accept 60 in seconds fields of timestamp, time, interval input values -Issue notice, not error, if TIMESTAMP, - TIME, or INTERVAL precision too large -Fix abstime-to-time cast function (fix is - not applied unless you initdb) -Fix pg_proc entry for - timestampt_izone (fix is not applied unless you - initdb) -Make EXTRACT(EPOCH FROM timestamp without time zone) treat input as local time -'now'::timestamptz gave wrong answer if timezone changed earlier in transaction -HAVE_INT64_TIMESTAMP code for time with timezone overwrote its input -Accept GLOBAL TEMP/TEMPORARY as a - synonym for TEMPORARY -Avoid improper schema-privilege-check failure in foreign-key triggers -Fix bugs in foreign-key triggers for SET DEFAULT action -Fix incorrect time-qual check in row fetch for - UPDATE and DELETE triggers -Foreign-key clauses were parsed but ignored in - ALTER TABLE ADD COLUMN -Fix createlang script breakage for case where handler function already exists -Fix misbehavior on zero-column tables in pg_dump, COPY, ANALYZE, other places -Fix misbehavior of func_error() on type names containing '%' -Fix misbehavior of replace() on strings containing '%' -Regular-expression patterns containing certain multibyte characters failed -Account correctly for NULLs in more cases in join size estimation -Avoid conflict with system definition of isblank() function or macro -Fix failure to convert large code point values in EUC_TW conversions (Tatsuo) -Fix error recovery for SSL_read/SSL_write calls -Don't do early constant-folding of type coercion expressions -Validate page header fields immediately after reading in any page -Repair incorrect check for ungrouped variables in unnamed joins -Fix buffer overrun in to_ascii (Guido Notari) -contrib/ltree fixes (Teodor) -Fix core dump in deadlock detection on machines where char is unsigned -Avoid running out of buffers in many-way indexscan (bug introduced in 7.3) -Fix planner's selectivity estimation functions to handle domains properly -Fix dbmirror memory-allocation bug (Steven Singer) -Prevent infinite loop in ln(numeric) due to roundoff error -GROUP BY got confused if there were multiple equal GROUP BY items -Fix bad plan when inherited UPDATE/DELETE references another inherited table -Prevent clustering on incomplete (partial or non-NULL-storing) indexes -Service shutdown request at proper time if it arrives while still starting up -Fix left-links in temporary indexes (could make backwards scans miss entries) -Fix incorrect handling of client_encoding setting in postgresql.conf (Tatsuo) -Fix failure to respond to pg_ctl stop -m fast after Async_NotifyHandler runs -Fix SPI for case where rule contains multiple statements of the same type -Fix problem with checking for wrong type of access privilege in rule query -Fix problem with EXCEPT in CREATE RULE -Prevent problem with dropping temp tables having serial columns -Fix replace_vars_with_subplan_refs failure in complex views -Fix regexp slowness in single-byte encodings (Tatsuo) -Allow qualified type names in CREATE CAST - and DROP CAST -Accept SETOF type[], which formerly had to - be written SETOF _type -Fix pg_dump core dump in some cases with procedural languages -Force ISO datestyle in pg_dump output, for portability (Oliver) -pg_dump failed to handle error return - from lo_read (Oleg Drokin) -pg_dumpall failed with groups having no members (Nick Eskelinen) -pg_dumpall failed to recognize --globals-only switch -pg_restore failed to restore blobs if -X disable-triggers is specified -Repair intrafunction memory leak in plpgsql -pltcl's elog command dumped core if given wrong parameters (Ian Harding) -plpython used wrong value of atttypmod (Brad McLean) -Fix improper quoting of boolean values in Python interface (D'Arcy) -Added addDataType() method to PGConnection interface for JDBC -Fixed various problems with updateable ResultSets for JDBC (Shawn Green) -Fixed various problems with DatabaseMetaData for JDBC (Kris Jurka, Peter Royal) -Fixed problem with parsing table ACLs in JDBC -Better error message for character set conversion problems in JDBC - - - - - - - Release 7.3.2 - - - Release date: - 2003-02-04 - - - - This release contains a variety of fixes for version 7.3.1. - - - - - Migration to Version 7.3.2 - - - A dump/restore is not required for those - running version 7.3.*. - - - - - Changes - - -Restore creation of OID column in CREATE TABLE AS / SELECT INTO -Fix pg_dump core dump when dumping views having comments -Dump DEFERRABLE/INITIALLY DEFERRED constraints properly -Fix UPDATE when child table's column numbering differs from parent -Increase default value of max_fsm_relations -Fix problem when fetching backwards in a cursor for a single-row query -Make backward fetch work properly with cursor on SELECT DISTINCT query -Fix problems with loading pg_dump files containing contrib/lo usage -Fix problem with all-numeric user names -Fix possible memory leak and core dump during disconnect in libpgtcl -Make plpython's spi_execute command handle nulls properly (Andrew Bosma) -Adjust plpython error reporting so that its regression test passes again -Work with bison 1.875 -Handle mixed-case names properly in plpgsql's %type (Neil) -Fix core dump in pltcl when executing a query rewritten by a rule -Repair array subscript overruns (per report from Yichen Xie) -Reduce MAX_TIME_PRECISION from 13 to 10 in floating-point case -Correctly case-fold variable names in per-database and per-user settings -Fix coredump in plpgsql's RETURN NEXT when SELECT into record returns no rows -Fix outdated use of pg_type.typprtlen in python client interface -Correctly handle fractional seconds in timestamps in JDBC driver -Improve performance of getImportedKeys() in JDBC -Make shared-library symlinks work standardly on HPUX (Giles) -Repair inconsistent rounding behavior for timestamp, time, interval -SSL negotiation fixes (Nathan Mueller) -Make libpq's ~/.pgpass feature work when connecting with PQconnectDB -Update my2pg, ora2pg -Translation updates -Add casts between types lo and oid in contrib/lo -fastpath code now checks for privilege to call function - - - - - - - Release 7.3.1 - - - Release date: - 2002-12-18 - - - - This release contains a variety of fixes for version 7.3. - - - - - Migration to Version 7.3.1 - - - A dump/restore is not required for those - running version 7.3. However, it should be noted that the main - PostgreSQL interface library, libpq, - has a new major version number for this release, which might require - recompilation of client code in certain cases. - - - - - Changes - - -Fix a core dump of COPY TO when client/server encodings don't match (Tom) -Allow pg_dump to work with pre-7.2 servers (Philip) -contrib/adddepend fixes (Tom) -Fix problem with deletion of per-user/per-database config settings (Tom) -contrib/vacuumlo fix (Tom) -Allow 'password' encryption even when pg_shadow contains MD5 passwords (Bruce) -contrib/dbmirror fix (Steven Singer) -Optimizer fixes (Tom) -contrib/tsearch fixes (Teodor Sigaev, Magnus) -Allow locale names to be mixed case (Nicolai Tufar) -Increment libpq library's major version number (Bruce) -pg_hba.conf error reporting fixes (Bruce, Neil) -Add SCO Openserver 5.0.4 as a supported platform (Bruce) -Prevent EXPLAIN from crashing server (Tom) -SSL fixes (Nathan Mueller) -Prevent composite column creation via ALTER TABLE (Tom) - - - - - - - Release 7.3 - - - Release date: - 2002-11-27 - - - - Overview - - - Major changes in this release: - - - - - Schemas - - - Schemas allow users to create objects in separate namespaces, - so two people or applications can have tables with the same - name. There is also a public schema for shared tables. - Table/index creation can be restricted by removing privileges - on the public schema. - - - - - - Drop Column - - - PostgreSQL now supports the - ALTER TABLE ... DROP COLUMN functionality. - - - - - - Table Functions - - - Functions returning multiple rows and/or multiple columns are - now much easier to use than before. You can call such a - table function in the SELECT - FROM clause, treating its output like a - table. Also, PL/pgSQL functions can - now return sets. - - - - - - Prepared Queries - - - PostgreSQL now supports prepared - queries, for improved performance. - - - - - - Dependency Tracking - - - PostgreSQL now records object - dependencies, which allows improvements in many areas. - DROP statements now take either - CASCADE or RESTRICT to control whether - dependent objects are also dropped. - - - - - - Privileges - - - Functions and procedural languages now have privileges, and - functions can be defined to run with the privileges of their - creator. - - - - - - Internationalization - - - Both multibyte and locale support are now always enabled. - - - - - - Logging - - - A variety of logging options have been enhanced. - - - - - - Interfaces - - - A large number of interfaces have been moved to http://gborg.postgresql.org - where they can be developed and released independently. - - - - - - Functions/Identifiers - - - By default, functions can now take up to 32 parameters, and - identifiers can be up to 63 bytes long. Also, OPAQUE - is now deprecated: there are specific pseudo-datatypes - to represent each of the former meanings of OPAQUE - in function argument and result types. - - - - - - - - - Migration to Version 7.3 - - - A dump/restore using pg_dump is required for those - wishing to migrate data from any previous release. If your - application examines the system catalogs, additional changes will - be required due to the introduction of schemas in 7.3; for more - information, see: . - - - - Observe the following incompatibilities: - - - - - - Pre-6.3 clients are no longer supported. - - - - - - pg_hba.conf now has a column for the user - name and additional features. Existing files need to be - adjusted. - - - - - - Several postgresql.conf logging parameters - have been renamed. - - - - - - LIMIT #,# has been disabled; use - LIMIT # OFFSET #. - - - - - - INSERT statements with column lists must - specify a value for each specified column. For example, - INSERT INTO tab (col1, col2) VALUES ('val1') - is now invalid. It's still allowed to supply fewer columns than - expected if the INSERT does not have a column list. - - - - - - serial columns are no longer automatically - UNIQUE; thus, an index will not automatically be - created. - - - - - - A SET command inside an aborted transaction - is now rolled back. - - - - - - COPY no longer considers missing trailing - columns to be null. All columns need to be specified. - (However, one can achieve a similar effect by specifying a - column list in the COPY command.) - - - - - - The data type timestamp is now equivalent to - timestamp without time zone, instead of - timestamp with time zone. - - - - - - Pre-7.3 databases loaded into 7.3 will not have the new object - dependencies for serial columns, unique - constraints, and foreign keys. See the directory - contrib/adddepend/ for a detailed - description and a script that will add such dependencies. - - - - - - An empty string ('') is no longer allowed as - the input into an integer field. Formerly, it was silently - interpreted as 0. - - - - - - - - Changes - - - Server Operation - -Add pg_locks view to show locks (Neil) -Security fixes for password negotiation memory allocation (Neil) -Remove support for version 0 FE/BE protocol (PostgreSQL 6.2 and earlier) (Tom) -Reserve the last few backend slots for superusers, add parameter superuser_reserved_connections to control this (Nigel J. Andrews) - - - - - Performance - -Improve startup by calling localtime() only once (Tom) -Cache system catalog information in flat files for faster startup (Tom) -Improve caching of index information (Tom) -Optimizer improvements (Tom, Fernando Nasser) -Catalog caches now store failed lookups (Tom) -Hash function improvements (Neil) -Improve performance of query tokenization and network handling (Peter) -Speed improvement for large object restore (Mario Weilguni) -Mark expired index entries on first lookup, saving later heap fetches (Tom) -Avoid excessive NULL bitmap padding (Manfred Koizar) -Add BSD-licensed qsort() for Solaris, for performance (Bruce) -Reduce per-row overhead by four bytes (Manfred Koizar) -Fix GEQO optimizer bug (Neil Conway) -Make WITHOUT OID actually save four bytes per row (Manfred Koizar) -Add default_statistics_target variable to specify ANALYZE buckets (Neil) -Use local buffer cache for temporary tables so no WAL overhead (Tom) -Improve free space map performance on large tables (Stephen Marshall, Tom) -Improved WAL write concurrency (Tom) - - - - - Privileges - -Add privileges on functions and procedural languages (Peter) -Add OWNER to CREATE DATABASE so superusers can create databases on behalf of unprivileged users (Gavin Sherry, Tom) -Add new object privilege bits EXECUTE and USAGE (Tom) -Add SET SESSION AUTHORIZATION DEFAULT and RESET SESSION AUTHORIZATION (Tom) -Allow functions to be executed with the privilege of the function owner (Peter) - - - - - Server Configuration - -Server log messages now tagged with LOG, not DEBUG (Bruce) -Add user column to pg_hba.conf (Bruce) -Have log_connections output two lines in log file (Tom) -Remove debug_level from postgresql.conf, now server_min_messages (Bruce) -New ALTER DATABASE/USER ... SET command for per-user/database initialization (Peter) -New parameters server_min_messages and client_min_messages to control which messages are sent to the server logs or client applications (Bruce) -Allow pg_hba.conf to specify lists of users/databases separated by commas, group names prepended with +, and file names prepended with @ (Bruce) -Remove secondary password file capability and pg_password utility (Bruce) -Add variable db_user_namespace for database-local user names (Bruce) -SSL improvements (Bear Giles) -Make encryption of stored passwords the default (Bruce) -Allow statistics collector to be reset by calling pg_stat_reset() (Christopher) -Add log_duration parameter (Bruce) -Rename debug_print_query to log_statement (Bruce) -Rename show_query_stats to show_statement_stats (Bruce) -Add param log_min_error_statement to print commands to logs on error (Gavin) - - - - - Queries - -Make cursors insensitive, meaning their contents do not change (Tom) -Disable LIMIT #,# syntax; now only LIMIT # OFFSET # supported (Bruce) -Increase identifier length to 63 (Neil, Bruce) -UNION fixes for merging >= 3 columns of different lengths (Tom) -Add DEFAULT key word to INSERT, e.g., INSERT ... (..., DEFAULT, ...) (Rod) -Allow views to have default values using ALTER COLUMN ... SET DEFAULT (Neil) -Fail on INSERTs with column lists that don't supply all column values, e.g., INSERT INTO tab (col1, col2) VALUES ('val1'); (Rod) -Fix for join aliases (Tom) -Fix for FULL OUTER JOINs (Tom) -Improve reporting of invalid identifier and location (Tom, Gavin) -Fix OPEN cursor(args) (Tom) -Allow 'ctid' to be used in a view and currtid(viewname) (Hiroshi) -Fix for CREATE TABLE AS with UNION (Tom) -SQL99 syntax improvements (Thomas) -Add statement_timeout variable to cancel queries (Bruce) -Allow prepared queries with PREPARE/EXECUTE (Neil) -Allow FOR UPDATE to appear after LIMIT/OFFSET (Bruce) -Add variable autocommit (Tom, David Van Wie) - - - - - Object Manipulation - -Make equals signs optional in CREATE DATABASE (Gavin Sherry) -Make ALTER TABLE OWNER change index ownership too (Neil) -New ALTER TABLE tabname ALTER COLUMN colname SET STORAGE controls TOAST storage, compression (John Gray) -Add schema support, CREATE/DROP SCHEMA (Tom) -Create schema for temporary tables (Tom) -Add variable search_path for schema search (Tom) -Add ALTER TABLE SET/DROP NOT NULL (Christopher) -New CREATE FUNCTION volatility levels (Tom) -Make rule names unique only per table (Tom) -Add 'ON tablename' clause to DROP RULE and COMMENT ON RULE (Tom) -Add ALTER TRIGGER RENAME (Joe) -New current_schema() and current_schemas() inquiry functions (Tom) -Allow functions to return multiple rows (table functions) (Joe) -Make WITH optional in CREATE DATABASE, for consistency (Bruce) -Add object dependency tracking (Rod, Tom) -Add RESTRICT/CASCADE to DROP commands (Rod) -Add ALTER TABLE DROP for non-CHECK CONSTRAINT (Rod) -Autodestroy sequence on DROP of table with SERIAL (Rod) -Prevent column dropping if column is used by foreign key (Rod) -Automatically drop constraints/functions when object is dropped (Rod) -Add CREATE/DROP OPERATOR CLASS (Bill Studenmund, Tom) -Add ALTER TABLE DROP COLUMN (Christopher, Tom, Hiroshi) -Prevent inherited columns from being removed or renamed (Alvaro Herrera) -Fix foreign key constraints to not error on intermediate database states (Stephan) -Propagate column or table renaming to foreign key constraints -Add CREATE OR REPLACE VIEW (Gavin, Neil, Tom) -Add CREATE OR REPLACE RULE (Gavin, Neil, Tom) -Have rules execute alphabetically, returning more predictable values (Tom) -Triggers are now fired in alphabetical order (Tom) -Add /contrib/adddepend to handle pre-7.3 object dependencies (Rod) -Allow better casting when inserting/updating values (Tom) - - - - - Utility Commands - -Have COPY TO output embedded carriage returns and newlines as \r and \n (Tom) -Allow DELIMITER in COPY FROM to be 8-bit clean (Tatsuo) -Make pg_dump use ALTER TABLE ADD PRIMARY KEY, for performance (Neil) -Disable brackets in multistatement rules (Bruce) -Disable VACUUM from being called inside a function (Bruce) -Allow dropdb and other scripts to use identifiers with spaces (Bruce) -Restrict database comment changes to the current database -Allow comments on operators, independent of the underlying function (Rod) -Rollback SET commands in aborted transactions (Tom) -EXPLAIN now outputs as a query (Tom) -Display condition expressions and sort keys in EXPLAIN (Tom) -Add 'SET LOCAL var = value' to set configuration variables for a single transaction (Tom) -Allow ANALYZE to run in a transaction (Bruce) -Improve COPY syntax using new WITH clauses, keep backward compatibility (Bruce) -Fix pg_dump to consistently output tags in non-ASCII dumps (Bruce) -Make foreign key constraints clearer in dump file (Rod) -Add COMMENT ON CONSTRAINT (Rod) -Allow COPY TO/FROM to specify column names (Brent Verner) -Dump UNIQUE and PRIMARY KEY constraints as ALTER TABLE (Rod) -Have SHOW output a query result (Joe) -Generate failure on short COPY lines rather than pad NULLs (Neil) -Fix CLUSTER to preserve all table attributes (Alvaro Herrera) -New pg_settings table to view/modify GUC settings (Joe) -Add smart quoting, portability improvements to pg_dump output (Peter) -Dump serial columns out as SERIAL (Tom) -Enable large file support, >2G for pg_dump (Peter, Philip Warner, Bruce) -Disallow TRUNCATE on tables that are involved in referential constraints (Rod) -Have TRUNCATE also auto-truncate the toast table of the relation (Tom) -Add clusterdb utility that will auto-cluster an entire database based on previous CLUSTER operations (Alvaro Herrera) -Overhaul pg_dumpall (Peter) -Allow REINDEX of TOAST tables (Tom) -Implemented START TRANSACTION, per SQL99 (Neil) -Fix rare index corruption when a page split affects bulk delete (Tom) -Fix ALTER TABLE ... ADD COLUMN for inheritance (Alvaro Herrera) - - - - - Data Types and Functions - -Fix factorial(0) to return 1 (Bruce) -Date/time/timezone improvements (Thomas) -Fix for array slice extraction (Tom) -Fix extract/date_part to report proper microseconds for timestamp (Tatsuo) -Allow text_substr() and bytea_substr() to read TOAST values more efficiently (John Gray) -Add domain support (Rod) -Make WITHOUT TIME ZONE the default for TIMESTAMP and TIME data types (Thomas) -Allow alternate storage scheme of 64-bit integers for date/time types using --enable-integer-datetimes in configure (Thomas) -Make timezone(timestamptz) return timestamp rather than a string (Thomas) -Allow fractional seconds in date/time types for dates prior to 1BC (Thomas) -Limit timestamp data types to 6 decimal places of precision (Thomas) -Change timezone conversion functions from timetz() to timezone() (Thomas) -Add configuration variables datestyle and timezone (Tom) -Add OVERLAY(), which allows substitution of a substring in a string (Thomas) -Add SIMILAR TO (Thomas, Tom) -Add regular expression SUBSTRING(string FROM pat FOR escape) (Thomas) -Add LOCALTIME and LOCALTIMESTAMP functions (Thomas) -Add named composite types using CREATE TYPE typename AS (column) (Joe) -Allow composite type definition in the table alias clause (Joe) -Add new API to simplify creation of C language table functions (Joe) -Remove ODBC-compatible empty parentheses from calls to SQL99 functions for which these parentheses do not match the standard (Thomas) -Allow macaddr data type to accept 12 hex digits with no separators (Mike Wyer) -Add CREATE/DROP CAST (Peter) -Add IS DISTINCT FROM operator (Thomas) -Add SQL99 TREAT() function, synonym for CAST() (Thomas) -Add pg_backend_pid() to output backend pid (Bruce) -Add IS OF / IS NOT OF type predicate (Thomas) -Allow bit string constants without fully-specified length (Thomas) -Allow conversion between 8-byte integers and bit strings (Thomas) -Implement hex literal conversion to bit string literal (Thomas) -Allow table functions to appear in the FROM clause (Joe) -Increase maximum number of function parameters to 32 (Bruce) -No longer automatically create index for SERIAL column (Tom) -Add current_database() (Rod) -Fix cash_words() to not overflow buffer (Tom) -Add functions replace(), split_part(), to_hex() (Joe) -Fix LIKE for bytea as a right-hand argument (Joe) -Prevent crashes caused by SELECT cash_out(2) (Tom) -Fix to_char(1,'FM999.99') to return a period (Karel) -Fix trigger/type/language functions returning OPAQUE to return proper type (Tom) - - - - - Internationalization - -Add additional encodings: Korean (JOHAB), Thai (WIN874), Vietnamese (TCVN), Arabic (WIN1256), Simplified Chinese (GBK), Korean (UHC) (Eiji Tokuya) -Enable locale support by default (Peter) -Add locale variables (Peter) -Escape byes >= 0x7f for multibyte in PQescapeBytea/PQunescapeBytea (Tatsuo) -Add locale awareness to regular expression character classes -Enable multibyte support by default (Tatsuo) -Add GB18030 multibyte support (Bill Huang) -Add CREATE/DROP CONVERSION, allowing loadable encodings (Tatsuo, Kaori) -Add pg_conversion table (Tatsuo) -Add SQL99 CONVERT() function (Tatsuo) -pg_dumpall, pg_controldata, and pg_resetxlog now national-language aware (Peter) -New and updated translations - - - - - Server-side Languages - -Allow recursive SQL function (Peter) -Change PL/Tcl build to use configured compiler and Makefile.shlib (Peter) -Overhaul the PL/pgSQL FOUND variable to be more Oracle-compatible (Neil, Tom) -Allow PL/pgSQL to handle quoted identifiers (Tom) -Allow set-returning PL/pgSQL functions (Neil) -Make PL/pgSQL schema-aware (Joe) -Remove some memory leaks (Nigel J. Andrews, Tom) - - - - - psql - -Don't lowercase psql \connect database name for 7.2.0 compatibility (Tom) -Add psql \timing to time user queries (Greg Sabino Mullane) -Have psql \d show index information (Greg Sabino Mullane) -New psql \dD shows domains (Jonathan Eisler) -Allow psql to show rules on views (Paul ?) -Fix for psql variable substitution (Tom) -Allow psql \d to show temporary table structure (Tom) -Allow psql \d to show foreign keys (Rod) -Fix \? to honor \pset pager (Bruce) -Have psql reports its version number on startup (Tom) -Allow \copy to specify column names (Tom) - - - - - libpq - -Add ~/.pgpass to store host/user password combinations (Alvaro Herrera) -Add PQunescapeBytea() function to libpq (Patrick Welche) -Fix for sending large queries over non-blocking connections (Bernhard Herzog) -Fix for libpq using timers on Win9X (David Ford) -Allow libpq notify to handle servers with different-length identifiers (Tom) -Add libpq PQescapeString() and PQescapeBytea() to Windows (Bruce) -Fix for SSL with non-blocking connections (Jack Bates) -Add libpq connection timeout parameter (Denis A Ustimenko) - - - - - JDBC - -Allow JDBC to compile with JDK 1.4 (Dave) -Add JDBC 3 support (Barry) -Allows JDBC to set loglevel by adding ?loglevel=X to the connection URL (Barry) -Add Driver.info() message that prints out the version number (Barry) -Add updateable result sets (Raghu Nidagal, Dave) -Add support for callable statements (Paul Bethe) -Add query cancel capability -Add refresh row (Dave) -Fix MD5 encryption handling for multibyte servers (Jun Kawai) -Add support for prepared statements (Barry) - - - - - Miscellaneous Interfaces - -Fixed ECPG bug concerning octal numbers in single quotes (Michael) -Move src/interfaces/libpgeasy to http://gborg.postgresql.org (Marc, Bruce) -Improve Python interface (Elliot Lee, Andrew Johnson, Greg Copeland) -Add libpgtcl connection close event (Gerhard Hintermayer) -Move src/interfaces/libpq++ to http://gborg.postgresql.org (Marc, Bruce) -Move src/interfaces/odbc to http://gborg.postgresql.org (Marc) -Move src/interfaces/libpgeasy to http://gborg.postgresql.org (Marc, Bruce) -Move src/interfaces/perl5 to http://gborg.postgresql.org (Marc, Bruce) -Remove src/bin/pgaccess from main tree, now at http://www.pgaccess.org (Bruce) -Add pg_on_connection_loss command to libpgtcl (Gerhard Hintermayer, Tom) - - - - - Source Code - -Fix for parallel make (Peter) -AIX fixes for linking Tcl (Andreas Zeugswetter) -Allow PL/Perl to build under Cygwin (Jason Tishler) -Improve MIPS compiles (Peter, Oliver Elphick) -Require Autoconf version 2.53 (Peter) -Require readline and zlib by default in configure (Peter) -Allow Solaris to use Intimate Shared Memory (ISM), for performance (Scott Brunza, P.J. Josh Rovero) -Always enable syslog in compile, remove --enable-syslog option (Tatsuo) -Always enable multibyte in compile, remove --enable-multibyte option (Tatsuo) -Always enable locale in compile, remove --enable-locale option (Peter) -Fix for Win9x DLL creation (Magnus Naeslund) -Fix for link() usage by WAL code on Windows, BeOS (Jason Tishler) -Add sys/types.h to c.h, remove from main files (Peter, Bruce) -Fix AIX hang on SMP machines (Tomoyuki Niijima) -AIX SMP hang fix (Tomoyuki Niijima) -Fix pre-1970 date handling on newer glibc libraries (Tom) -Fix PowerPC SMP locking (Tom) -Prevent gcc -ffast-math from being used (Peter, Tom) -Bison >= 1.50 now required for developer builds -Kerberos 5 support now builds with Heimdal (Peter) -Add appendix in the User's Guide which lists SQL features (Thomas) -Improve loadable module linking to use RTLD_NOW (Tom) -New error levels WARNING, INFO, LOG, DEBUG[1-5] (Bruce) -New src/port directory holds replaced libc functions (Peter, Bruce) -New pg_namespace system catalog for schemas (Tom) -Add pg_class.relnamespace for schemas (Tom) -Add pg_type.typnamespace for schemas (Tom) -Add pg_proc.pronamespace for schemas (Tom) -Restructure aggregates to have pg_proc entries (Tom) -System relations now have their own namespace, pg_* test not required (Fernando Nasser) -Rename TOAST index names to be *_index rather than *_idx (Neil) -Add namespaces for operators, opclasses (Tom) -Add additional checks to server control file (Thomas) -New Polish FAQ (Marcin Mazurek) -Add Posix semaphore support (Tom) -Document need for reindex (Bruce) -Rename some internal identifiers to simplify Windows compile (Jan, Katherine Ward) -Add documentation on computing disk space (Bruce) -Remove KSQO from GUC (Bruce) -Fix memory leak in rtree (Kenneth Been) -Modify a few error messages for consistency (Bruce) -Remove unused system table columns (Peter) -Make system columns NOT NULL where appropriate (Tom) -Clean up use of sprintf in favor of snprintf() (Neil, Jukka Holappa) -Remove OPAQUE and create specific subtypes (Tom) -Cleanups in array internal handling (Joe, Tom) -Disallow pg_atoi('') (Bruce) -Remove parameter wal_files because WAL files are now recycled (Bruce) -Add version numbers to heap pages (Tom) - - - - - Contrib - -Allow inet arrays in /contrib/array (Neil) -GiST fixes (Teodor Sigaev, Neil) -Upgrade /contrib/mysql -Add /contrib/dbsize which shows table sizes without vacuum (Peter) -Add /contrib/intagg, integer aggregator routines (mlw) -Improve /contrib/oid2name (Neil, Bruce) -Improve /contrib/tsearch (Oleg, Teodor Sigaev) -Cleanups of /contrib/rserver (Alexey V. Borzov) -Update /contrib/oracle conversion utility (Gilles Darold) -Update /contrib/dblink (Joe) -Improve options supported by /contrib/vacuumlo (Mario Weilguni) -Improvements to /contrib/intarray (Oleg, Teodor Sigaev, Andrey Oktyabrski) -Add /contrib/reindexdb utility (Shaun Thomas) -Add indexing to /contrib/isbn_issn (Dan Weston) -Add /contrib/dbmirror (Steven Singer) -Improve /contrib/pgbench (Neil) -Add /contrib/tablefunc table function examples (Joe) -Add /contrib/ltree data type for tree structures (Teodor Sigaev, Oleg Bartunov) -Move /contrib/pg_controldata, pg_resetxlog into main tree (Bruce) -Fixes to /contrib/cube (Bruno Wolff) -Improve /contrib/fulltextindex (Christopher) - - - - - - - - Release 7.2.8 - - - Release date: - 2005-05-09 - - - - This release contains a variety of fixes from 7.2.7, including one - security-related issue. - - - - Migration to Version 7.2.8 - - - A dump/restore is not required for those running 7.2.X. - - - - - Changes - - -Repair ancient race condition that allowed a transaction to be -seen as committed for some purposes (eg SELECT FOR UPDATE) slightly sooner -than for other purposes -This is an extremely serious bug since it could lead to apparent -data inconsistencies being briefly visible to applications. -Repair race condition between relation extension and -VACUUM -This could theoretically have caused loss of a page's worth of -freshly-inserted data, although the scenario seems of very low probability. -There are no known cases of it having caused more than an Assert failure. - -Fix EXTRACT(EPOCH) for -TIME WITH TIME ZONE values -Additional buffer overrun checks in plpgsql -(Neil) -Fix pg_dump to dump index names and trigger names containing -% correctly (Neil) -Prevent to_char(interval) from dumping core for -month-related formats -Fix contrib/pgcrypto for newer OpenSSL builds -(Marko Kreen) - - - - - - - Release 7.2.7 - - - Release date: - 2005-01-31 - - - - This release contains a variety of fixes from 7.2.6, including several - security-related issues. - - - - Migration to Version 7.2.7 - - - A dump/restore is not required for those running 7.2.X. - - - - - Changes - - -Disallow LOAD to non-superusers - -On platforms that will automatically execute initialization functions of a -shared library (this includes at least Windows and ELF-based Unixen), -LOAD can be used to make the server execute arbitrary code. -Thanks to NGS Software for reporting this. -Add needed STRICT marking to some contrib functions (Kris -Jurka) -Avoid buffer overrun when plpgsql cursor declaration has too -many parameters (Neil) -Fix planning error for FULL and RIGHT outer joins - -The result of the join was mistakenly supposed to be sorted the same as the -left input. This could not only deliver mis-sorted output to the user, but -in case of nested merge joins could give outright wrong answers. - -Fix display of negative intervals in SQL and GERMAN -datestyles - - - - - - - Release 7.2.6 - - - Release date: - 2004-10-22 - - - - This release contains a variety of fixes from 7.2.5. - - - - - Migration to Version 7.2.6 - - - A dump/restore is not required for those running 7.2.X. - - - - - Changes - - -Repair possible failure to update hint bits on disk - -Under rare circumstances this oversight could lead to -could not access transaction status failures, which qualifies -it as a potential-data-loss bug. - -Ensure that hashed outer join does not miss tuples - -Very large left joins using a hash join plan could fail to output unmatched -left-side rows given just the right data distribution. - -Disallow running pg_ctl as root - -This is to guard against any possible security issues. - -Avoid using temp files in /tmp in make_oidjoins_check - -This has been reported as a security issue, though it's hardly worthy of -concern since there is no reason for non-developers to use this script anyway. - -Update to newer versions of Bison - - - - - - - Release 7.2.5 - - - Release date: - 2004-08-16 - - - - This release contains a variety of fixes from 7.2.4. - - - - - Migration to Version 7.2.5 - - - A dump/restore is not required for those running 7.2.X. - - - - - Changes - - -Prevent possible loss of committed transactions during crash - -Due to insufficient interlocking between transaction commit and checkpointing, -it was possible for transactions committed just before the most recent -checkpoint to be lost, in whole or in part, following a database crash and -restart. This is a serious bug that has existed -since PostgreSQL 7.1. - -Fix corner case for btree search in parallel with first root page split -Fix buffer overrun in to_ascii (Guido Notari) -Fix core dump in deadlock detection on machines where char is unsigned -Fix failure to respond to pg_ctl stop -m fast after Async_NotifyHandler runs -Repair memory leaks in pg_dump -Avoid conflict with system definition of isblank() function or macro - - - - - - Release 7.2.4 - - - Release date: - 2003-01-30 - - - - This release contains a variety of fixes for version 7.2.3, - including fixes to prevent possible data loss. - - - - Migration to Version 7.2.4 - - - A dump/restore is not required for those - running version 7.2.*. - - - - - Changes - - -Fix some additional cases of VACUUM "No one parent tuple was found" error -Prevent VACUUM from being called inside a function (Bruce) -Ensure pg_clog updates are sync'd to disk before marking checkpoint complete -Avoid integer overflow during large hash joins -Make GROUP commands work when pg_group.grolist is large enough to be toasted -Fix errors in datetime tables; some timezone names weren't being recognized -Fix integer overflows in circle_poly(), path_encode(), path_add() (Neil) -Repair long-standing logic errors in lseg_eq(), lseg_ne(), lseg_center() - - - - - - - Release 7.2.3 - - - Release date: - 2002-10-01 - - - - This release contains a variety of fixes for version 7.2.2, - including fixes to prevent possible data loss. - - - - Migration to Version 7.2.3 - - - A dump/restore is not required for those - running version 7.2.*. - - - - - Changes - - -Prevent possible compressed transaction log loss (Tom) -Prevent non-superuser from increasing most recent vacuum info (Tom) -Handle pre-1970 date values in newer versions of glibc (Tom) -Fix possible hang during server shutdown -Prevent spinlock hangs on SMP PPC machines (Tomoyuki Niijima) -Fix pg_dump to properly dump FULL JOIN USING (Tom) - - - - - - - Release 7.2.2 - - - Release date: - 2002-08-23 - - - - This release contains a variety of fixes for version 7.2.1. - - - - Migration to Version 7.2.2 - - - A dump/restore is not required for those - running version 7.2.*. - - - - - Changes - - -Allow EXECUTE of "CREATE TABLE AS ... SELECT" in PL/pgSQL (Tom) -Fix for compressed transaction log id wraparound (Tom) -Fix PQescapeBytea/PQunescapeBytea so that they handle bytes > 0x7f (Tatsuo) -Fix for psql and pg_dump crashing when invoked with non-existent long options (Tatsuo) -Fix crash when invoking geometric operators (Tom) -Allow OPEN cursor(args) (Tom) -Fix for rtree_gist index build (Teodor) -Fix for dumping user-defined aggregates (Tom) -contrib/intarray fixes (Oleg) -Fix for complex UNION/EXCEPT/INTERSECT queries using parens (Tom) -Fix to pg_convert (Tatsuo) -Fix for crash with long DATA strings (Thomas, Neil) -Fix for repeat(), lpad(), rpad() and long strings (Neil) - - - - - - - Release 7.2.1 - - - Release date: - 2002-03-21 - - - - This release contains a variety of fixes for version 7.2. - - - - Migration to Version 7.2.1 - - - A dump/restore is not required for those - running version 7.2. - - - - - Changes - - -Ensure that sequence counters do not go backwards after a crash (Tom) -Fix pgaccess kanji-conversion key binding (Tatsuo) -Optimizer improvements (Tom) -Cash I/O improvements (Tom) -New Russian FAQ -Compile fix for missing AuthBlockSig (Heiko) -Additional time zones and time zone fixes (Thomas) -Allow psql \connect to handle mixed case database and user names (Tom) -Return proper OID on command completion even with ON INSERT rules (Tom) -Allow COPY FROM to use 8-bit DELIMITERS (Tatsuo) -Fix bug in extract/date_part for milliseconds/microseconds (Tatsuo) -Improve handling of multiple UNIONs with different lengths (Tom) -contrib/btree_gist improvements (Teodor Sigaev) -contrib/tsearch dictionary improvements, see README.tsearch for an additional installation step (Thomas T. Thai, Teodor Sigaev) -Fix for array subscripts handling (Tom) -Allow EXECUTE of "CREATE TABLE AS ... SELECT" in PL/pgSQL (Tom) - - - - - - - Release 7.2 - - - Release date: - 2002-02-04 - - - - Overview - - - This release improves PostgreSQL for use in - high-volume applications. - - - - Major changes in this release: - - - - - VACUUM - - - Vacuuming no longer locks tables, thus allowing normal user - access during the vacuum. A new VACUUM FULL - command does old-style vacuum by locking the table and - shrinking the on-disk copy of the table. - - - - - - Transactions - - - There is no longer a problem with installations that exceed - four billion transactions. - - - - - - OIDs - - - OIDs are now optional. Users can now create tables without - OIDs for cases where OID usage is excessive. - - - - - - Optimizer - - - The system now computes histogram column statistics during - ANALYZE, allowing much better optimizer choices. - - - - - - Security - - - A new MD5 encryption option allows more secure storage and - transfer of passwords. A new Unix-domain socket - authentication option is available on Linux and BSD systems. - - - - - - Statistics - - - Administrators can use the new table access statistics module - to get fine-grained information about table and index usage. - - - - - - Internationalization - - - Program and library messages can now be displayed in several - languages. - - - - - - - - - Migration to Version 7.2 - - - A dump/restore using pg_dump is required for - those wishing to migrate data from any previous release. - - - - Observe the following incompatibilities: - - - - - - The semantics of the VACUUM command have - changed in this release. You might wish to update your - maintenance procedures accordingly. - - - - - - In this release, comparisons using = NULL - will always return false (or NULL, more precisely). Previous - releases automatically transformed this syntax to IS - NULL. The old behavior can be re-enabled using a - postgresql.conf parameter. - - - - - - The pg_hba.conf and pg_ident.conf - configuration is now only reloaded after receiving a - SIGHUP signal, not with each connection. - - - - - - The function octet_length() now returns the uncompressed data length. - - - - - - The date/time value 'current' is no longer - available. You will need to rewrite your applications. - - - - - - The timestamp(), time(), - and interval() functions are no longer - available. Instead of timestamp(), use - timestamp 'string' or CAST. - - - - - - - The SELECT ... LIMIT #,# syntax will be removed - in the next release. You should change your queries to use - separate LIMIT and OFFSET clauses, e.g. LIMIT 10 OFFSET - 20. - - - - - Changes - - - Server Operation - -Create temporary files in a separate directory (Bruce) -Delete orphaned temporary files on postmaster startup (Bruce) -Added unique indexes to some system tables (Tom) -System table operator reorganization (Oleg Bartunov, Teodor Sigaev, Tom) -Renamed pg_log to pg_clog (Tom) -Enable SIGTERM, SIGQUIT to kill backends (Jan) -Removed compile-time limit on number of backends (Tom) -Better cleanup for semaphore resource failure (Tatsuo, Tom) -Allow safe transaction ID wraparound (Tom) -Removed OIDs from some system tables (Tom) -Removed "triggered data change violation" error check (Tom) -SPI portal creation of prepared/saved plans (Jan) -Allow SPI column functions to work for system columns (Tom) -Long value compression improvement (Tom) -Statistics collector for table, index access (Jan) -Truncate extra-long sequence names to a reasonable value (Tom) -Measure transaction times in milliseconds (Thomas) -Fix TID sequential scans (Hiroshi) -Superuser ID now fixed at 1 (Peter E) -New pg_ctl "reload" option (Tom) - - - - - Performance - -Optimizer improvements (Tom) -New histogram column statistics for optimizer (Tom) -Reuse write-ahead log files rather than discarding them (Tom) -Cache improvements (Tom) -IS NULL, IS NOT NULL optimizer improvement (Tom) -Improve lock manager to reduce lock contention (Tom) -Keep relcache entries for index access support functions (Tom) -Allow better selectivity with NaN and infinities in NUMERIC (Tom) -R-tree performance improvements (Kenneth Been) -B-tree splits more efficient (Tom) - - - - - Privileges - -Change UPDATE, DELETE privileges to be distinct (Peter E) -New REFERENCES, TRIGGER privileges (Peter E) -Allow GRANT/REVOKE to/from more than one user at a time (Peter E) -New has_table_privilege() function (Joe Conway) -Allow non-superuser to vacuum database (Tom) -New SET SESSION AUTHORIZATION command (Peter E) -Fix bug in privilege modifications on newly created tables (Tom) -Disallow access to pg_statistic for non-superuser, add user-accessible views (Tom) - - - - - Client Authentication - -Fork postmaster before doing authentication to prevent hangs (Peter E) -Add ident authentication over Unix domain sockets on Linux, *BSD (Helge Bahmann, Oliver Elphick, Teodor Sigaev, Bruce) -Add a password authentication method that uses MD5 encryption (Bruce) -Allow encryption of stored passwords using MD5 (Bruce) -PAM authentication (Dominic J. Eidson) -Load pg_hba.conf and pg_ident.conf only on startup and SIGHUP (Bruce) - - - - - Server Configuration - -Interpretation of some time zone abbreviations as Australian rather than North American now settable at run time (Bruce) -New parameter to set default transaction isolation level (Peter E) -New parameter to enable conversion of "expr = NULL" into "expr IS NULL", off by default (Peter E) -New parameter to control memory usage by VACUUM (Tom) -New parameter to set client authentication timeout (Tom) -New parameter to set maximum number of open files (Tom) - - - - - Queries - -Statements added by INSERT rules now execute after the INSERT (Jan) -Prevent unadorned relation names in target list (Bruce) -NULLs now sort after all normal values in ORDER BY (Tom) -New IS UNKNOWN, IS NOT UNKNOWN Boolean tests (Tom) -New SHARE UPDATE EXCLUSIVE lock mode (Tom) -New EXPLAIN ANALYZE command that shows run times and row counts (Martijn van Oosterhout) -Fix problem with LIMIT and subqueries (Tom) -Fix for LIMIT, DISTINCT ON pushed into subqueries (Tom) -Fix nested EXCEPT/INTERSECT (Tom) - - - - - Schema Manipulation - -Fix SERIAL in temporary tables (Bruce) -Allow temporary sequences (Bruce) -Sequences now use int8 internally (Tom) -New SERIAL8 creates int8 columns with sequences, default still SERIAL4 (Tom) -Make OIDs optional using WITHOUT OIDS (Tom) -Add %TYPE syntax to CREATE TYPE (Ian Lance Taylor) -Add ALTER TABLE / DROP CONSTRAINT for CHECK constraints (Christopher Kings-Lynne) -New CREATE OR REPLACE FUNCTION to alter existing function (preserving the function OID) (Gavin Sherry) -Add ALTER TABLE / ADD [ UNIQUE | PRIMARY ] (Christopher Kings-Lynne) -Allow column renaming in views -Make ALTER TABLE / RENAME COLUMN update column names of indexes (Brent Verner) -Fix for ALTER TABLE / ADD CONSTRAINT ... CHECK with inherited tables (Stephan Szabo) -ALTER TABLE RENAME update foreign-key trigger arguments correctly (Brent Verner) -DROP AGGREGATE and COMMENT ON AGGREGATE now accept an aggtype (Tom) -Add automatic return type data casting for SQL functions (Tom) -Allow GiST indexes to handle NULLs and multikey indexes (Oleg Bartunov, Teodor Sigaev, Tom) -Enable partial indexes (Martijn van Oosterhout) - - - - - Utility Commands - -Add RESET ALL, SHOW ALL (Marko Kreen) -CREATE/ALTER USER/GROUP now allow options in any order (Vince) -Add LOCK A, B, C functionality (Neil Padgett) -New ENCRYPTED/UNENCRYPTED option to CREATE/ALTER USER (Bruce) -New light-weight VACUUM does not lock table; old semantics are available as VACUUM FULL (Tom) -Disable COPY TO/FROM on views (Bruce) -COPY DELIMITERS string must be exactly one character (Tom) -VACUUM warning about index tuples fewer than heap now only appears when appropriate (Martijn van Oosterhout) -Fix privilege checks for CREATE INDEX (Tom) -Disallow inappropriate use of CREATE/DROP INDEX/TRIGGER/VIEW (Tom) - - - - - Data Types and Functions - -SUM(), AVG(), COUNT() now uses int8 internally for speed (Tom) -Add convert(), convert2() (Tatsuo) -New function bit_length() (Peter E) -Make the "n" in CHAR(n)/VARCHAR(n) represents letters, not bytes (Tatsuo) -CHAR(), VARCHAR() now reject strings that are too long (Peter E) -BIT VARYING now rejects bit strings that are too long (Peter E) -BIT now rejects bit strings that do not match declared size (Peter E) -INET, CIDR text conversion functions (Alex Pilosov) -INET, CIDR operators << and <<= indexable (Alex Pilosov) -Bytea \### now requires valid three digit octal number -Bytea comparison improvements, now supports =, <>, >, >=, <, and <= -Bytea now supports B-tree indexes -Bytea now supports LIKE, LIKE...ESCAPE, NOT LIKE, NOT LIKE...ESCAPE -Bytea now supports concatenation -New bytea functions: position, substring, trim, btrim, and length -New encode() function mode, "escaped", converts minimally escaped bytea to/from text -Add pg_database_encoding_max_length() (Tatsuo) -Add pg_client_encoding() function (Tatsuo) -now() returns time with millisecond precision (Thomas) -New TIMESTAMP WITHOUT TIMEZONE data type (Thomas) -Add ISO date/time specification with "T", yyyy-mm-ddThh:mm:ss (Thomas) -New xid/int comparison functions (Hiroshi) -Add precision to TIME, TIMESTAMP, and INTERVAL data types (Thomas) -Modify type coercion logic to attempt binary-compatible functions first (Tom) -New encode() function installed by default (Marko Kreen) -Improved to_*() conversion functions (Karel Zak) -Optimize LIKE/ILIKE when using single-byte encodings (Tatsuo) -New functions in contrib/pgcrypto: crypt(), hmac(), encrypt(), gen_salt() (Marko Kreen) -Correct description of translate() function (Bruce) -Add INTERVAL argument for SET TIME ZONE (Thomas) -Add INTERVAL YEAR TO MONTH (etc.) syntax (Thomas) -Optimize length functions when using single-byte encodings (Tatsuo) -Fix path_inter, path_distance, path_length, dist_ppath to handle closed paths (Curtis Barrett, Tom) -octet_length(text) now returns non-compressed length (Tatsuo, Bruce) -Handle "July" full name in date/time literals (Greg Sabino Mullane) -Some datatype() function calls now evaluated differently -Add support for Julian and ISO time specifications (Thomas) - - - - - Internationalization - -National language support in psql, pg_dump, libpq, and server (Peter E) -Message translations in Chinese (simplified, traditional), Czech, French, German, Hungarian, Russian, Swedish (Peter E, Serguei A. Mokhov, Karel Zak, Weiping He, Zhenbang Wei, Kovacs Zoltan) -Make trim, ltrim, rtrim, btrim, lpad, rpad, translate multibyte aware (Tatsuo) -Add LATIN5,6,7,8,9,10 support (Tatsuo) -Add ISO 8859-5,6,7,8 support (Tatsuo) -Correct LATIN5 to mean ISO-8859-9, not ISO-8859-5 (Tatsuo) -Make mic2ascii() non-ASCII aware (Tatsuo) -Reject invalid multibyte character sequences (Tatsuo) - - - - - <application>PL/pgSQL</application> - -Now uses portals for SELECT loops, allowing huge result sets (Jan) -CURSOR and REFCURSOR support (Jan) -Can now return open cursors (Jan) -Add ELSEIF (Klaus Reger) -Improve PL/pgSQL error reporting, including location of error (Tom) -Allow IS or FOR key words in cursor declaration, for compatibility (Bruce) -Fix for SELECT ... FOR UPDATE (Tom) -Fix for PERFORM returning multiple rows (Tom) -Make PL/pgSQL use the server's type coercion code (Tom) -Memory leak fix (Jan, Tom) -Make trailing semicolon optional (Tom) - - - - - PL/Perl - -New untrusted PL/Perl (Alex Pilosov) -PL/Perl is now built on some platforms even if libperl is not shared (Peter E) - - - - - PL/Tcl - -Now reports errorInfo (Vsevolod Lobko) -Add spi_lastoid function (bob@redivi.com) - - - - - PL/Python - -...is new (Andrew Bosma) - - - - - <application>psql</application> - -\d displays indexes in unique, primary groupings (Christopher Kings-Lynne) -Allow trailing semicolons in backslash commands (Greg Sabino Mullane) -Read password from /dev/tty if possible -Force new password prompt when changing user and database (Tatsuo, Tom) -Format the correct number of columns for Unicode (Patrice) - - - - - <application>libpq</application> - -New function PQescapeString() to escape quotes in command strings (Florian Weimer) -New function PQescapeBytea() escapes binary strings for use as SQL string literals - - - - - JDBC - -Return OID of INSERT (Ken K) -Handle more data types (Ken K) -Handle single quotes and newlines in strings (Ken K) -Handle NULL variables (Ken K) -Fix for time zone handling (Barry Lind) -Improved Druid support -Allow eight-bit characters with non-multibyte server (Barry Lind) -Support BIT, BINARY types (Ned Wolpert) -Reduce memory usage (Michael Stephens, Dave Cramer) -Update DatabaseMetaData (Peter E) -Add DatabaseMetaData.getCatalogs() (Peter E) -Encoding fixes (Anders Bengtsson) -Get/setCatalog methods (Jason Davies) -DatabaseMetaData.getColumns() now returns column defaults (Jason Davies) -DatabaseMetaData.getColumns() performance improvement (Jeroen van Vianen) -Some JDBC1 and JDBC2 merging (Anders Bengtsson) -Transaction performance improvements (Barry Lind) -Array fixes (Greg Zoller) -Serialize addition -Fix batch processing (Rene Pijlman) -ExecSQL method reorganization (Anders Bengtsson) -GetColumn() fixes (Jeroen van Vianen) -Fix isWriteable() function (Rene Pijlman) -Improved passage of JDBC2 conformance tests (Rene Pijlman) -Add bytea type capability (Barry Lind) -Add isNullable() (Rene Pijlman) -JDBC date/time test suite fixes (Liam Stewart) -Fix for SELECT 'id' AS xxx FROM table (Dave Cramer) -Fix DatabaseMetaData to show precision properly (Mark Lillywhite) -New getImported/getExported keys (Jason Davies) -MD5 password encryption support (Jeremy Wohl) -Fix to actually use type cache (Ned Wolpert) - - - - - ODBC - -Remove query size limit (Hiroshi) -Remove text field size limit (Hiroshi) -Fix for SQLPrimaryKeys in multibyte mode (Hiroshi) -Allow ODBC procedure calls (Hiroshi) -Improve boolean handing (Aidan Mountford) -Most configuration options now settable via DSN (Hiroshi) -Multibyte, performance fixes (Hiroshi) -Allow driver to be used with iODBC or unixODBC (Peter E) -MD5 password encryption support (Bruce) -Add more compatibility functions to odbc.sql (Peter E) - - - - - <application>ECPG</application> - -EXECUTE ... INTO implemented (Christof Petig) -Multiple row descriptor support (e.g. CARDINALITY) (Christof Petig) -Fix for GRANT parameters (Lee Kindness) -Fix INITIALLY DEFERRED bug -Various bug fixes (Michael, Christof Petig) -Auto allocation for indicator variable arrays (int *ind_p=NULL) -Auto allocation for string arrays (char **foo_pp=NULL) -ECPGfree_auto_mem fixed -All function names with external linkage are now prefixed by ECPG -Fixes for arrays of structures (Michael) - - - - - Misc. Interfaces - -Python fix fetchone() (Gerhard Haring) -Use UTF, Unicode in Tcl where appropriate (Vsevolod Lobko, Reinhard Max) -Add Tcl COPY TO/FROM (ljb) -Prevent output of default index op class in pg_dump (Tom) -Fix libpgeasy memory leak (Bruce) - - - - - Build and Install - -Configure, dynamic loader, and shared library fixes (Peter E) -Fixes in QNX 4 port (Bernd Tegge) -Fixes in Cygwin and Windows ports (Jason Tishler, Gerhard Haring, Dmitry Yurtaev, Darko Prenosil, Mikhail Terekhov) -Fix for Windows socket communication failures (Magnus, Mikhail Terekhov) -Hurd compile fix (Oliver Elphick) -BeOS fixes (Cyril Velter) -Remove configure --enable-unicode-conversion, now enabled by multibyte (Tatsuo) -AIX fixes (Tatsuo, Andreas) -Fix parallel make (Peter E) -Install SQL language manual pages into OS-specific directories (Peter E) -Rename config.h to pg_config.h (Peter E) -Reorganize installation layout of header files (Peter E) - - - - - Source Code - -Remove SEP_CHAR (Bruce) -New GUC hooks (Tom) -Merge GUC and command line handling (Marko Kreen) -Remove EXTEND INDEX (Martijn van Oosterhout, Tom) -New pgjindent utility to indent java code (Bruce) -Remove define of true/false when compiling under C++ (Leandro Fanzone, Tom) -pgindent fixes (Bruce, Tom) -Replace strcasecmp() with strcmp() where appropriate (Peter E) -Dynahash portability improvements (Tom) -Add 'volatile' usage in spinlock structures -Improve signal handling logic (Tom) - - - - - Contrib - -New contrib/rtree_gist (Oleg Bartunov, Teodor Sigaev) -New contrib/tsearch full-text indexing (Oleg, Teodor Sigaev) -Add contrib/dblink for remote database access (Joe Conway) -contrib/ora2pg Oracle conversion utility (Gilles Darold) -contrib/xml XML conversion utility (John Gray) -contrib/fulltextindex fixes (Christopher Kings-Lynne) -New contrib/fuzzystrmatch with levenshtein and metaphone, soundex merged (Joe Conway) -Add contrib/intarray boolean queries, binary search, fixes (Oleg Bartunov) -New pg_upgrade utility (Bruce) -Add new pg_resetxlog options (Bruce, Tom) - - - - - - - - Release 7.1.3 - - - Release date: - 2001-08-15 - - - - Migration to Version 7.1.3 - - - A dump/restore is not required for those running - 7.1.X. - - - - - Changes - - - -Remove unused WAL segments of large transactions (Tom) -Multiaction rule fix (Tom) -PL/pgSQL memory allocation fix (Jan) -VACUUM buffer fix (Tom) -Regression test fixes (Tom) -pg_dump fixes for GRANT/REVOKE/comments on views, user-defined types (Tom) -Fix subselects with DISTINCT ON or LIMIT (Tom) -BeOS fix -Disable COPY TO/FROM a view (Tom) -Cygwin build (Jason Tishler) - - - - - - - - Release 7.1.2 - - - Release date: - 2001-05-11 - - - - This has one fix from 7.1.1. - - - - - Migration to Version 7.1.2 - - - A dump/restore is not required for those running - 7.1.X. - - - - - Changes - - - -Fix PL/pgSQL SELECTs when returning no rows -Fix for psql backslash core dump -Referential integrity privilege fix -Optimizer fixes -pg_dump cleanups - - - - - - - - Release 7.1.1 - - - Release date: - 2001-05-05 - - - - This has a variety of fixes from 7.1. - - - - - Migration to Version 7.1.1 - - - A dump/restore is not required for those running - 7.1. - - - - - Changes - - - -Fix for numeric MODULO operator (Tom) -pg_dump fixes (Philip) -pg_dump can dump 7.0 databases (Philip) -readline 4.2 fixes (Peter E) -JOIN fixes (Tom) -AIX, MSWIN, VAX, N32K fixes (Tom) -Multibytes fixes (Tom) -Unicode fixes (Tatsuo) -Optimizer improvements (Tom) -Fix for whole rows in functions (Tom) -Fix for pg_ctl and option strings with spaces (Peter E) -ODBC fixes (Hiroshi) -EXTRACT can now take string argument (Thomas) -Python fixes (Darcy) - - - - - - - - Release 7.1 - - - Release date: - 2001-04-13 - - - - This release focuses on removing limitations that have existed in the - PostgreSQL code for many years. - - - - Major changes in this release: - - - - - - Write-ahead Log (WAL) - - - -To maintain database consistency in case of an operating system crash, -previous releases of PostgreSQL have forced -all data modifications to disk before each transaction commit. With -WAL, only one log file must be flushed to disk, greatly improving -performance. If you have been using -F in previous releases to -disable disk flushes, you might want to consider discontinuing its use. - - - - - - - TOAST - - - - TOAST - Previous releases had a compiled-in row length limit, -typically 8k - 32k. This limit made storage of long text fields -difficult. With TOAST, long rows of any length can be stored with good -performance. - - - - - - - Outer Joins - - - -We now support outer joins. The UNION/NOT IN -workaround for outer joins is no longer required. We use the SQL92 -outer join syntax. - - - - - - - Function Manager - - - -The previous C function manager did not -handle null values properly, nor did it support 64-bit CPU's (Alpha). The new -function manager does. You can continue using your old custom -functions, but you might want to rewrite them in the future to use the new -function manager call interface. - - - - - - - Complex Queries - - - -A large number of complex queries that were -unsupported in previous releases now work. Many combinations of views, -aggregates, UNION, LIMIT, cursors, subqueries, and inherited tables -now work properly. Inherited tables are now accessed by default. -Subqueries in FROM are now supported. - - - - - - - - Migration to Version 7.1 - - - A dump/restore using pg_dump is required for those wishing to migrate - data from any previous release. - - - - - Changes - - - -Bug Fixes ---------- -Many multibyte/Unicode/locale fixes (Tatsuo and others) -More reliable ALTER TABLE RENAME (Tom) -Kerberos V fixes (David Wragg) -Fix for INSERT INTO...SELECT where targetlist has subqueries (Tom) -Prompt username/password on standard error (Bruce) -Large objects inv_read/inv_write fixes (Tom) -Fixes for to_char(), to_date(), to_ascii(), and to_timestamp() (Karel, - Daniel Baldoni) -Prevent query expressions from leaking memory (Tom) -Allow UPDATE of arrays elements (Tom) -Wake up lock waiters during cancel (Hiroshi) -Fix rare cursor crash when using hash join (Tom) -Fix for DROP TABLE/INDEX in rolled-back transaction (Hiroshi) -Fix psql crash from \l+ if MULTIBYTE enabled (Peter E) -Fix truncation of rule names during CREATE VIEW (Ross Reedstrom) -Fix PL/Perl (Alex Kapranoff) -Disallow LOCK on views (Mark Hollomon) -Disallow INSERT/UPDATE/DELETE on views (Mark Hollomon) -Disallow DROP RULE, CREATE INDEX, TRUNCATE on views (Mark Hollomon) -Allow PL/pgSQL accept non-ASCII identifiers (Tatsuo) -Allow views to proper handle GROUP BY, aggregates, DISTINCT (Tom) -Fix rare failure with TRUNCATE command (Tom) -Allow UNION/INTERSECT/EXCEPT to be used with ALL, subqueries, views, - DISTINCT, ORDER BY, SELECT...INTO (Tom) -Fix parser failures during aborted transactions (Tom) -Allow temporary relations to properly clean up indexes (Bruce) -Fix VACUUM problem with moving rows in same page (Tom) -Modify pg_dump to better handle user-defined items in template1 (Philip) -Allow LIMIT in VIEW (Tom) -Require cursor FETCH to honor LIMIT (Tom) -Allow PRIMARY/FOREIGN Key definitions on inherited columns (Stephan) -Allow ORDER BY, LIMIT in subqueries (Tom) -Allow UNION in CREATE RULE (Tom) -Make ALTER/DROP TABLE rollback-able (Vadim, Tom) -Store initdb collation in pg_control so collation cannot be changed (Tom) -Fix INSERT...SELECT with rules (Tom) -Fix FOR UPDATE inside views and subselects (Tom) -Fix OVERLAPS operators conform to SQL92 spec regarding NULLs (Tom) -Fix lpad() and rpad() to handle length less than input string (Tom) -Fix use of NOTIFY in some rules (Tom) -Overhaul btree code (Tom) -Fix NOT NULL use in PL/pgSQL variables (Tom) -Overhaul GIST code (Oleg) -Fix CLUSTER to preserve constraints and column default (Tom) -Improved deadlock detection handling (Tom) -Allow multiple SERIAL columns in a table (Tom) -Prevent occasional index corruption (Vadim) - -Enhancements ------------- -Add OUTER JOINs (Tom) -Function manager overhaul (Tom) -Allow ALTER TABLE RENAME on indexes (Tom) -Improve CLUSTER (Tom) -Improve ps status display for more platforms (Peter E, Marc) -Improve CREATE FUNCTION failure message (Ross) -JDBC improvements (Peter, Travis Bauer, Christopher Cain, William Webber, - Gunnar) -Grand Unified Configuration scheme/GUC. Many options can now be set in - data/postgresql.conf, postmaster/postgres flags, or SET commands (Peter E) -Improved handling of file descriptor cache (Tom) -New warning code about auto-created table alias entries (Bruce) -Overhaul initdb process (Tom, Peter E) -Overhaul of inherited tables; inherited tables now accessed by default; - new ONLY key word prevents it (Chris Bitmead, Tom) -ODBC cleanups/improvements (Nick Gorham, Stephan Szabo, Zoltan Kovacs, - Michael Fork) -Allow renaming of temp tables (Tom) -Overhaul memory manager contexts (Tom) -pg_dumpall uses CREATE USER or CREATE GROUP rather using COPY (Peter E) -Overhaul pg_dump (Philip Warner) -Allow pg_hba.conf secondary password file to specify only username (Peter E) -Allow TEMPORARY or TEMP key word when creating temporary tables (Bruce) -New memory leak checker (Karel) -New SET SESSION CHARACTERISTICS (Thomas) -Allow nested block comments (Thomas) -Add WITHOUT TIME ZONE type qualifier (Thomas) -New ALTER TABLE ADD CONSTRAINT (Stephan) -Use NUMERIC accumulators for INTEGER aggregates (Tom) -Overhaul aggregate code (Tom) -New VARIANCE and STDDEV() aggregates -Improve dependency ordering of pg_dump (Philip) -New pg_restore command (Philip) -New pg_dump tar output option (Philip) -New pg_dump of large objects (Philip) -New ESCAPE option to LIKE (Thomas) -New case-insensitive LIKE - ILIKE (Thomas) -Allow functional indexes to use binary-compatible type (Tom) -Allow SQL functions to be used in more contexts (Tom) -New pg_config utility (Peter E) -New PL/pgSQL EXECUTE command which allows dynamic SQL and utility statements - (Jan) -New PL/pgSQL GET DIAGNOSTICS statement for SPI value access (Jan) -New quote_identifiers() and quote_literal() functions (Jan) -New ALTER TABLE table OWNER TO user command (Mark Hollomon) -Allow subselects in FROM, i.e. FROM (SELECT ...) [AS] alias (Tom) -Update PyGreSQL to version 3.1 (D'Arcy) -Store tables as files named by OID (Vadim) -New SQL function setval(seq,val,bool) for use in pg_dump (Philip) -Require DROP VIEW to remove views, no DROP TABLE (Mark) -Allow DROP VIEW view1, view2 (Mark) -Allow multiple objects in DROP INDEX, DROP RULE, and DROP TYPE (Tom) -Allow automatic conversion to/from Unicode (Tatsuo, Eiji) -New /contrib/pgcrypto hashing functions (Marko Kreen) -New pg_dumpall --globals-only option (Peter E) -New CHECKPOINT command for WAL which creates new WAL log file (Vadim) -New AT TIME ZONE syntax (Thomas) -Allow location of Unix domain socket to be configurable (David J. MacKenzie) -Allow postmaster to listen on a specific IP address (David J. MacKenzie) -Allow socket path name to be specified in hostname by using leading slash - (David J. MacKenzie) -Allow CREATE DATABASE to specify template database (Tom) -New utility to convert MySQL schema dumps to SQL92 and PostgreSQL (Thomas) -New /contrib/rserv replication toolkit (Vadim) -New file format for COPY BINARY (Tom) -New /contrib/oid2name to map numeric files to table names (B Palmer) -New "idle in transaction" ps status message (Marc) -Update to pgaccess 0.98.7 (Constantin Teodorescu) -pg_ctl now defaults to -w (wait) on shutdown, new -l (log) option -Add rudimentary dependency checking to pg_dump (Philip) - -Types ------ -Fix INET/CIDR type ordering and add new functions (Tom) -Make OID behave as an unsigned type (Tom) -Allow BIGINT as synonym for INT8 (Peter E) -New int2 and int8 comparison operators (Tom) -New BIT and BIT VARYING types (Adriaan Joubert, Tom, Peter E) -CHAR() no longer faster than VARCHAR() because of TOAST (Tom) -New GIST seg/cube examples (Gene Selkov) -Improved round(numeric) handling (Tom) -Fix CIDR output formatting (Tom) -New CIDR abbrev() function (Tom) - -Performance ------------ -Write-Ahead Log (WAL) to provide crash recovery with less performance - overhead (Vadim) -ANALYZE stage of VACUUM no longer exclusively locks table (Bruce) -Reduced file seeks (Denis Perchine) -Improve BTREE code for duplicate keys (Tom) -Store all large objects in a single table (Denis Perchine, Tom) -Improve memory allocation performance (Karel, Tom) - -Source Code ------------ -New function manager call conventions (Tom) -SGI portability fixes (David Kaelbling) -New configure --enable-syslog option (Peter E) -New BSDI README (Bruce) -configure script moved to top level, not /src (Peter E) -Makefile/configuration/compilation overhaul (Peter E) -New configure --with-python option (Peter E) -Solaris cleanups (Peter E) -Overhaul /contrib Makefiles (Karel) -New OpenSSL configuration option (Magnus, Peter E) -AIX fixes (Andreas) -QNX fixes (Maurizio) -New heap_open(), heap_openr() API (Tom) -Remove colon and semi-colon operators (Thomas) -New pg_class.relkind value for views (Mark Hollomon) -Rename ichar() to chr() (Karel) -New documentation for btrim(), ascii(), chr(), repeat() (Karel) -Fixes for NT/Cygwin (Pete Forman) -AIX port fixes (Andreas) -New BeOS port (David Reid, Cyril Velter) -Add proofreader's changes to docs (Addison-Wesley, Bruce) -New Alpha spinlock code (Adriaan Joubert, Compaq) -UnixWare port overhaul (Peter E) -New macOS (Darwin) port (Peter Bierman, Bruce Hartzler) -New FreeBSD Alpha port (Alfred) -Overhaul shared memory segments (Tom) -Add IBM S/390 support (Neale Ferguson) -Moved macmanuf to /contrib (Larry Rosenman) -Syslog improvements (Larry Rosenman) -New template0 database that contains no user additions (Tom) -New /contrib/cube and /contrib/seg GIST sample code (Gene Selkov) -Allow NetBSD's libedit instead of readline (Peter) -Improved assembly language source code format (Bruce) -New contrib/pg_logger -New --template option to createdb -New contrib/pg_control utility (Oliver) -New FreeBSD tools ipc_check, start-scripts/freebsd - - - - - - - - Release 7.0.3 - - - Release date: - 2000-11-11 - - - - This has a variety of fixes from 7.0.2. - - - - - Migration to Version 7.0.3 - - - A dump/restore is not required for those running - 7.0.*. - - - - - Changes - - - -Jdbc fixes (Peter) -Large object fix (Tom) -Fix lean in COPY WITH OIDS leak (Tom) -Fix backwards-index-scan (Tom) -Fix SELECT ... FOR UPDATE so it checks for duplicate keys (Hiroshi) -Add --enable-syslog to configure (Marc) -Fix abort transaction at backend exit in rare cases (Tom) -Fix for psql \l+ when multibyte enabled (Tatsuo) -Allow PL/pgSQL to accept non ascii identifiers (Tatsuo) -Make vacuum always flush buffers (Tom) -Fix to allow cancel while waiting for a lock (Hiroshi) -Fix for memory allocation problem in user authentication code (Tom) -Remove bogus use of int4out() (Tom) -Fixes for multiple subqueries in COALESCE or BETWEEN (Tom) -Fix for failure of triggers on heap open in certain cases (Jeroen van - Vianen) -Fix for erroneous selectivity of not-equals (Tom) -Fix for erroneous use of strcmp() (Tom) -Fix for bug where storage manager accesses items beyond end of file - (Tom) -Fix to include kernel errno message in all smgr elog messages (Tom) -Fix for '.' not in PATH at build time (SL Baur) -Fix for out-of-file-descriptors error (Tom) -Fix to make pg_dump dump 'iscachable' flag for functions (Tom) -Fix for subselect in targetlist of Append node (Tom) -Fix for mergejoin plans (Tom) -Fix TRUNCATE failure on relations with indexes (Tom) -Avoid database-wide restart on write error (Hiroshi) -Fix nodeMaterial to honor chgParam by recomputing its output (Tom) -Fix VACUUM problem with moving chain of update row versions when source - and destination of a row version lie on the same page (Tom) -Fix user.c CommandCounterIncrement (Tom) -Fix for AM/PM boundary problem in to_char() (Karel Zak) -Fix TIME aggregate handling (Tom) -Fix to_char() to avoid coredump on NULL input (Tom) -Buffer fix (Tom) -Fix for inserting/copying longer multibyte strings into char() data - types (Tatsuo) -Fix for crash of backend, on abort (Tom) - - - - - - - - Release 7.0.2 - - - Release date: - 2000-06-05 - - - - This is a repackaging of 7.0.1 with added documentation. - - - - - Migration to Version 7.0.2 - - - A dump/restore is not required for those running - 7.*. - - - - - Changes - - - -Added documentation to tarball. - - - - - - - - Release 7.0.1 - - - Release date: - 2000-06-01 - - - - This is a cleanup release for 7.0. - - - - Migration to Version 7.0.1 - - - A dump/restore is not required for those running - 7.0. - - - - - Changes - - - -Fix many CLUSTER failures (Tom) -Allow ALTER TABLE RENAME works on indexes (Tom) -Fix plpgsql to handle datetime->timestamp and timespan->interval (Bruce) -New configure --with-setproctitle switch to use setproctitle() (Marc, Bruce) -Fix the off by one errors in ResultSet from 6.5.3, and more. -jdbc ResultSet fixes (Joseph Shraibman) -optimizer tunings (Tom) -Fix create user for pgaccess -Fix for UNLISTEN failure -IRIX fixes (David Kaelbling) -QNX fixes (Andreas Kardos) -Reduce COPY IN lock level (Tom) -Change libpqeasy to use PQconnectdb() style parameters (Bruce) -Fix pg_dump to handle OID indexes (Tom) -Fix small memory leak (Tom) -Solaris fix for createdb/dropdb (Tatsuo) -Fix for non-blocking connections (Alfred Perlstein) -Fix improper recovery after RENAME TABLE failures (Tom) -Copy pg_ident.conf.sample into /lib directory in install (Bruce) -Add SJIS UDC (NEC selection IBM kanji) support (Eiji Tokuya) -Fix too long syslog message (Tatsuo) -Fix problem with quoted indexes that are too long (Tom) -JDBC ResultSet.getTimestamp() fix (Gregory Krasnow & Floyd Marinescu) -ecpg changes (Michael) - - - - - - - Release 7.0 - - - Release date: - 2000-05-08 - - - - This release contains improvements in many areas, demonstrating - the continued growth of PostgreSQL. - There are more improvements and fixes in 7.0 than in any previous - release. The developers have confidence that this is the best - release yet; we do our best to put out only solid releases, and - this one is no exception. - - - - Major changes in this release: - - - - - - Foreign Keys - - - - Foreign keys are now implemented, with the exception of PARTIAL MATCH - foreign keys. Many users have been asking for this feature, and we are - pleased to offer it. - - - - - - - Optimizer Overhaul - - - - Continuing on work started a year ago, the optimizer has been - improved, allowing better query plan selection and faster performance - with less memory usage. - - - - - - - Updated psql - - - - psql, our interactive terminal monitor, has been - updated with a variety of new features. See the psql manual page for details. - - - - - - - Join Syntax - - - - SQL92 join syntax is now supported, though only as - INNER JOIN for this release. JOIN, - NATURAL JOIN, JOIN/USING, - and JOIN/ON are available, as are - column correlation names. - - - - - - - - Migration to Version 7.0 - - - A dump/restore using pg_dump - is required for those wishing to migrate data from any - previous release of PostgreSQL. - For those upgrading from 6.5.*, you can instead use - pg_upgrade to upgrade to this - release; however, a full dump/reload installation is always the - most robust method for upgrades. - - - - Interface and compatibility issues to consider for the new - release include: - - - - - - The date/time types datetime and - timespan have been superseded by the - SQL92-defined types timestamp and - interval. Although there has been some effort to - ease the transition by allowing - PostgreSQL to recognize - the deprecated type names and translate them to the new type - names, this mechanism cannot be completely transparent to - your existing application. - - - - - - The optimizer has been substantially improved in the area of - query cost estimation. In some cases, this will result in - decreased query times as the optimizer makes a better choice - for the preferred plan. However, in a small number of cases, - usually involving pathological distributions of data, your - query times might go up. If you are dealing with large amounts - of data, you might want to check your queries to verify - performance. - - - - - - The JDBC and ODBC - interfaces have been upgraded and extended. - - - - - - The string function CHAR_LENGTH is now a - native function. Previous versions translated this into a call - to LENGTH, which could result in - ambiguity with other types implementing - LENGTH such as the geometric types. - - - - - - - Changes - - - -Bug Fixes ---------- -Prevent function calls exceeding maximum number of arguments (Tom) -Improve CASE construct (Tom) -Fix SELECT coalesce(f1,0) FROM int4_tbl GROUP BY f1 (Tom) -Fix SELECT sentence.words[0] FROM sentence GROUP BY sentence.words[0] (Tom) -Fix GROUP BY scan bug (Tom) -Improvements in SQL grammar processing (Tom) -Fix for views involved in INSERT ... SELECT ... (Tom) -Fix for SELECT a/2, a/2 FROM test_missing_target GROUP BY a/2 (Tom) -Fix for subselects in INSERT ... SELECT (Tom) -Prevent INSERT ... SELECT ... ORDER BY (Tom) -Fixes for relations greater than 2GB, including vacuum -Improve propagating system table changes to other backends (Tom) -Improve propagating user table changes to other backends (Tom) -Fix handling of temp tables in complex situations (Bruce, Tom) -Allow table locking at table open, improving concurrent reliability (Tom) -Properly quote sequence names in pg_dump (Ross J. Reedstrom) -Prevent DROP DATABASE while others accessing -Prevent any rows from being returned by GROUP BY if no rows processed (Tom) -Fix SELECT COUNT(1) FROM table WHERE ...' if no rows matching WHERE (Tom) -Fix pg_upgrade so it works for MVCC (Tom) -Fix for SELECT ... WHERE x IN (SELECT ... HAVING SUM(x) > 1) (Tom) -Fix for "f1 datetime DEFAULT 'now'" (Tom) -Fix problems with CURRENT_DATE used in DEFAULT (Tom) -Allow comment-only lines, and ;;; lines too. (Tom) -Improve recovery after failed disk writes, disk full (Hiroshi) -Fix cases where table is mentioned in FROM but not joined (Tom) -Allow HAVING clause without aggregate functions (Tom) -Fix for "--" comment and no trailing newline, as seen in perl interface -Improve pg_dump failure error reports (Bruce) -Allow sorts and hashes to exceed 2GB file sizes (Tom) -Fix for pg_dump dumping of inherited rules (Tom) -Fix for NULL handling comparisons (Tom) -Fix inconsistent state caused by failed CREATE/DROP commands (Hiroshi) -Fix for dbname with dash -Prevent DROP INDEX from interfering with other backends (Tom) -Fix file descriptor leak in verify_password() -Fix for "Unable to identify an operator =$" problem -Fix ODBC so no segfault if CommLog and Debug enabled (Dirk Niggemann) -Fix for recursive exit call (Massimo) -Fix for extra-long timezones (Jeroen van Vianen) -Make pg_dump preserve primary key information (Peter E) -Prevent databases with single quotes (Peter E) -Prevent DROP DATABASE inside transaction (Peter E) -ecpg memory leak fixes (Stephen Birch) -Fix for SELECT null::text, SELECT int4fac(null) and SELECT 2 + (null) (Tom) -Y2K timestamp fix (Massimo) -Fix for VACUUM 'HEAP_MOVED_IN was not expected' errors (Tom) -Fix for views with tables/columns containing spaces (Tom) -Prevent privileges on indexes (Peter E) -Fix for spinlock stuck problem when error is generated (Hiroshi) -Fix ipcclean on Linux -Fix handling of NULL constraint conditions (Tom) -Fix memory leak in odbc driver (Nick Gorham) -Fix for privilege check on UNION tables (Tom) -Fix to allow SELECT 'a' LIKE 'a' (Tom) -Fix for SELECT 1 + NULL (Tom) -Fixes to CHAR -Fix log() on numeric type (Tom) -Deprecate ':' and ';' operators -Allow vacuum of temporary tables -Disallow inherited columns with the same name as new columns -Recover or force failure when disk space is exhausted (Hiroshi) -Fix INSERT INTO ... SELECT with AS columns matching result columns -Fix INSERT ... SELECT ... GROUP BY groups by target columns not source columns (Tom) -Fix CREATE TABLE test (a char(5) DEFAULT text '', b int4) with INSERT (Tom) -Fix UNION with LIMIT -Fix CREATE TABLE x AS SELECT 1 UNION SELECT 2 -Fix CREATE TABLE test(col char(2) DEFAULT user) -Fix mismatched types in CREATE TABLE ... DEFAULT -Fix SELECT * FROM pg_class where oid in (0,-1) -Fix SELECT COUNT('asdf') FROM pg_class WHERE oid=12 -Prevent user who can create databases can modifying pg_database table (Peter E) -Fix btree to give a useful elog when key > 1/2 (page - overhead) (Tom) -Fix INSERT of 0.0 into DECIMAL(4,4) field (Tom) - -Enhancements ------------- -New CLI interface include file sqlcli.h, based on SQL3/SQL98 -Remove all limits on query length, row length limit still exists (Tom) -Update jdbc protocol to 2.0 (Jens Glaser jens@jens.de) -Add TRUNCATE command to quickly truncate relation (Mike Mascari) -Fix to give super user and createdb user proper update catalog rights (Peter E) -Allow ecpg bool variables to have NULL values (Christof) -Issue ecpg error if NULL value for variable with no NULL indicator (Christof) -Allow ^C to cancel COPY command (Massimo) -Add SET FSYNC and SHOW PG_OPTIONS commands(Massimo) -Function name overloading for dynamically-loaded C functions (Frankpitt) -Add CmdTuples() to libpq++(Vince) -New CREATE CONSTRAINT TRIGGER and SET CONSTRAINTS commands(Jan) -Allow CREATE FUNCTION/WITH clause to be used for all language types -configure --enable-debug adds -g (Peter E) -configure --disable-debug removes -g (Peter E) -Allow more complex default expressions (Tom) -First real FOREIGN KEY constraint trigger functionality (Jan) -Add FOREIGN KEY ... MATCH FULL ... ON DELETE CASCADE (Jan) -Add FOREIGN KEY ... MATCH <unspecified> referential actions (Don Baccus) -Allow WHERE restriction on ctid (physical heap location) (Hiroshi) -Move pginterface from contrib to interface directory, rename to pgeasy (Bruce) -Change pgeasy connectdb() parameter ordering (Bruce) -Require SELECT DISTINCT target list to have all ORDER BY columns (Tom) -Add Oracle's COMMENT ON command (Mike Mascari mascarim@yahoo.com) -libpq's PQsetNoticeProcessor function now returns previous hook(Peter E) -Prevent PQsetNoticeProcessor from being set to NULL (Peter E) -Make USING in COPY optional (Bruce) -Allow subselects in the target list (Tom) -Allow subselects on the left side of comparison operators (Tom) -New parallel regression test (Jan) -Change backend-side COPY to write files with permissions 644 not 666 (Tom) -Force permissions on PGDATA directory to be secure, even if it exists (Tom) -Added psql LASTOID variable to return last inserted oid (Peter E) -Allow concurrent vacuum and remove pg_vlock vacuum lock file (Tom) -Add privilege check for vacuum (Peter E) -New libpq functions to allow asynchronous connections: PQconnectStart(), - PQconnectPoll(), PQresetStart(), PQresetPoll(), PQsetenvStart(), - PQsetenvPoll(), PQsetenvAbort (Ewan Mellor) -New libpq PQsetenv() function (Ewan Mellor) -create/alter user extension (Peter E) -New postmaster.pid and postmaster.opts under $PGDATA (Tatsuo) -New scripts for create/drop user/db (Peter E) -Major psql overhaul (Peter E) -Add const to libpq interface (Peter E) -New libpq function PQoidValue (Peter E) -Show specific non-aggregate causing problem with GROUP BY (Tom) -Make changes to pg_shadow recreate pg_pwd file (Peter E) -Add aggregate(DISTINCT ...) (Tom) -Allow flag to control COPY input/output of NULLs (Peter E) -Make postgres user have a password by default (Peter E) -Add CREATE/ALTER/DROP GROUP (Peter E) -All administration scripts now support --long options (Peter E, Karel) -Vacuumdb script now supports --all option (Peter E) -ecpg new portable FETCH syntax -Add ecpg EXEC SQL IFDEF, EXEC SQL IFNDEF, EXEC SQL ELSE, EXEC SQL ELIF - and EXEC SQL ENDIF directives -Add pg_ctl script to control backend start-up (Tatsuo) -Add postmaster.opts.default file to store start-up flags (Tatsuo) -Allow --with-mb=SQL_ASCII -Increase maximum number of index keys to 16 (Bruce) -Increase maximum number of function arguments to 16 (Bruce) -Allow configuration of maximum number of index keys and arguments (Bruce) -Allow unprivileged users to change their passwords (Peter E) -Password authentication enabled; required for new users (Peter E) -Disallow dropping a user who owns a database (Peter E) -Change initdb option --with-mb to --enable-multibyte -Add option for initdb to prompts for superuser password (Peter E) -Allow complex type casts like col::numeric(9,2) and col::int2::float8 (Tom) -Updated user interfaces on initdb, initlocation, pg_dump, ipcclean (Peter E) -New pg_char_to_encoding() and pg_encoding_to_char() functions (Tatsuo) -libpq non-blocking mode (Alfred Perlstein) -Improve conversion of types in casts that don't specify a length -New plperl internal programming language (Mark Hollomon) -Allow COPY IN to read file that do not end with a newline (Tom) -Indicate when long identifiers are truncated (Tom) -Allow aggregates to use type equivalency (Peter E) -Add Oracle's to_char(), to_date(), to_datetime(), to_timestamp(), to_number() - conversion functions (Karel Zak <zakkr@zf.jcu.cz>) -Add SELECT DISTINCT ON (expr [, expr ...]) targetlist ... (Tom) -Check to be sure ORDER BY is compatible with the DISTINCT operation (Tom) -Add NUMERIC and int8 types to ODBC -Improve EXPLAIN results for Append, Group, Agg, Unique (Tom) -Add ALTER TABLE ... ADD FOREIGN KEY (Stephan Szabo) -Allow SELECT .. FOR UPDATE in PL/pgSQL (Hiroshi) -Enable backward sequential scan even after reaching EOF (Hiroshi) -Add btree indexing of boolean values, >= and <= (Don Baccus) -Print current line number when COPY FROM fails (Massimo) -Recognize POSIX time zone e.g. "PST+8" and "GMT-8" (Thomas) -Add DEC as synonym for DECIMAL (Thomas) -Add SESSION_USER as SQL92 key word, same as CURRENT_USER (Thomas) -Implement SQL92 column aliases (aka correlation names) (Thomas) -Implement SQL92 join syntax (Thomas) -Make INTERVAL reserved word allowed as a column identifier (Thomas) -Implement REINDEX command (Hiroshi) -Accept ALL in aggregate function SUM(ALL col) (Tom) -Prevent GROUP BY from using column aliases (Tom) -New psql \encoding option (Tatsuo) -Allow PQrequestCancel() to terminate when in waiting-for-lock state (Hiroshi) -Allow negation of a negative number in all cases -Add ecpg descriptors (Christof, Michael) -Allow CREATE VIEW v AS SELECT f1::char(8) FROM tbl -Allow casts with length, like foo::char(8) -New libpq functions PQsetClientEncoding(), PQclientEncoding() (Tatsuo) -Add support for SJIS user defined characters (Tatsuo) -Larger views/rules supported -Make libpq's PQconndefaults() thread-safe (Tom) -Disable // as comment to be ANSI conforming, should use -- (Tom) -Allow column aliases on views CREATE VIEW name (collist) -Fixes for views with subqueries (Tom) -Allow UPDATE table SET fld = (SELECT ...) (Tom) -SET command options no longer require quotes -Update pgaccess to 0.98.6 -New SET SEED command -New pg_options.sample file -New SET FSYNC command (Massimo) -Allow pg_descriptions when creating tables -Allow pg_descriptions when creating types, columns, and functions -Allow psql \copy to allow delimiters (Peter E) -Allow psql to print nulls as distinct from "" [null] (Peter E) - -Types ------ -Many array fixes (Tom) -Allow bare column names to be subscripted as arrays (Tom) -Improve type casting of int and float constants (Tom) -Cleanups for int8 inputs, range checking, and type conversion (Tom) -Fix for SELECT timespan('21:11:26'::time) (Tom) -netmask('x.x.x.x/0') is 255.255.255.255 instead of 0.0.0.0 (Oleg Sharoiko) -Add btree index on NUMERIC (Jan) -Perl fix for large objects containing NUL characters (Douglas Thomson) -ODBC fix for large objects (free) -Fix indexing of cidr data type -Fix for Ethernet MAC addresses (macaddr type) comparisons -Fix for date/time types when overflows happened in computations (Tom) -Allow array on int8 (Peter E) -Fix for rounding/overflow of NUMERIC type, like NUMERIC(4,4) (Tom) -Allow NUMERIC arrays -Fix bugs in NUMERIC ceil() and floor() functions (Tom) -Make char_length()/octet_length including trailing blanks (Tom) -Made abstime/reltime use int4 instead of time_t (Peter E) -New lztext data type for compressed text fields -Revise code to handle coercion of int and float constants (Tom) -Start at new code to implement a BIT and BIT VARYING type (Adriaan Joubert) -NUMERIC now accepts scientific notation (Tom) -NUMERIC to int4 rounds (Tom) -Convert float4/8 to NUMERIC properly (Tom) -Allow type conversion with NUMERIC (Thomas) -Make ISO date style (2000-02-16 09:33) the default (Thomas) -Add NATIONAL CHAR [ VARYING ] (Thomas) -Allow NUMERIC round and trunc to accept negative scales (Tom) -New TIME WITH TIME ZONE type (Thomas) -Add MAX()/MIN() on time type (Thomas) -Add abs(), mod(), fac() for int8 (Thomas) -Rename functions to round(), sqrt(), cbrt(), pow() for float8 (Thomas) -Add transcendental math functions (e.g. sin(), acos()) for float8 (Thomas) -Add exp() and ln() for NUMERIC type -Rename NUMERIC power() to pow() (Thomas) -Improved TRANSLATE() function (Edwin Ramirez, Tom) -Allow X=-Y operators (Tom) -Allow SELECT float8(COUNT(*))/(SELECT COUNT(*) FROM t) FROM t GROUP BY f1; (Tom) -Allow LOCALE to use indexes in regular expression searches (Tom) -Allow creation of functional indexes to use default types - -Performance ------------ -Prevent exponential space consumption with many AND's and OR's (Tom) -Collect attribute selectivity values for system columns (Tom) -Reduce memory usage of aggregates (Tom) -Fix for LIKE optimization to use indexes with multibyte encodings (Tom) -Fix r-tree index optimizer selectivity (Thomas) -Improve optimizer selectivity computations and functions (Tom) -Optimize btree searching for cases where many equal keys exist (Tom) -Enable fast LIKE index processing only if index present (Tom) -Re-use free space on index pages with duplicates (Tom) -Improve hash join processing (Tom) -Prevent descending sort if result is already sorted(Hiroshi) -Allow commuting of index scan query qualifications (Tom) -Prefer index scans in cases where ORDER BY/GROUP BY is required (Tom) -Allocate large memory requests in fix-sized chunks for performance (Tom) -Fix vacuum's performance by reducing memory allocation requests (Tom) -Implement constant-expression simplification (Bernard Frankpitt, Tom) -Use secondary columns to be used to determine start of index scan (Hiroshi) -Prevent quadruple use of disk space when doing internal sorting (Tom) -Faster sorting by calling fewer functions (Tom) -Create system indexes to match all system caches (Bruce, Hiroshi) -Make system caches use system indexes (Bruce) -Make all system indexes unique (Bruce) -Improve pg_statistic management for VACUUM speed improvement (Tom) -Flush backend cache less frequently (Tom, Hiroshi) -COPY now reuses previous memory allocation, improving performance (Tom) -Improve optimization cost estimation (Tom) -Improve optimizer estimate of range queries x > lowbound AND x < highbound (Tom) -Use DNF instead of CNF where appropriate (Tom, Taral) -Further cleanup for OR-of-AND WHERE-clauses (Tom) -Make use of index in OR clauses (x = 1 AND y = 2) OR (x = 2 AND y = 4) (Tom) -Smarter optimizer computations for random index page access (Tom) -New SET variable to control optimizer costs (Tom) -Optimizer queries based on LIMIT, OFFSET, and EXISTS qualifications (Tom) -Reduce optimizer internal housekeeping of join paths for speedup (Tom) -Major subquery speedup (Tom) -Fewer fsync writes when fsync is not disabled (Tom) -Improved LIKE optimizer estimates (Tom) -Prevent fsync in SELECT-only queries (Vadim) -Make index creation use psort code, because it is now faster (Tom) -Allow creation of sort temp tables > 1 Gig - -Source Tree Changes -------------------- -Fix for linux PPC compile -New generic expression-tree-walker subroutine (Tom) -Change form() to varargform() to prevent portability problems -Improved range checking for large integers on Alphas -Clean up #include in /include directory (Bruce) -Add scripts for checking includes (Bruce) -Remove un-needed #include's from *.c files (Bruce) -Change #include's to use <> and "" as appropriate (Bruce) -Enable Windows compilation of libpq -Alpha spinlock fix from Uncle George gatgul@voicenet.com -Overhaul of optimizer data structures (Tom) -Fix to cygipc library (Yutaka Tanida) -Allow pgsql to work on newer Cygwin snapshots (Dan) -New catalog version number (Tom) -Add Linux ARM -Rename heap_replace to heap_update -Update for QNX (Dr. Andreas Kardos) -New platform-specific regression handling (Tom) -Rename oid8 -> oidvector and int28 -> int2vector (Bruce) -Included all yacc and lex files into the distribution (Peter E.) -Remove lextest, no longer needed (Peter E) -Fix for libpq and psql on Windows (Magnus) -Internally change datetime and timespan into timestamp and interval (Thomas) -Fix for plpgsql on BSD/OS -Add SQL_ASCII test case to the regression test (Tatsuo) -configure --with-mb now deprecated (Tatsuo) -NT fixes -NetBSD fixes (Johnny C. Lam lamj@stat.cmu.edu) -Fixes for Alpha compiles -New multibyte encodings - - - - - - - Release 6.5.3 - - - Release date: - 1999-10-13 - - - - This is basically a cleanup release for 6.5.2. We have added a new - PgAccess that was missing in 6.5.2, and installed an NT-specific fix. - - - - - Migration to Version 6.5.3 - - - A dump/restore is not required for those running - 6.5.*. - - - - Changes - - - -Updated version of pgaccess 0.98 -NT-specific patch -Fix dumping rules on inherited tables - - - - - - - - Release 6.5.2 - - - Release date: - 1999-09-15 - - - - This is basically a cleanup release for 6.5.1. We have fixed a variety of - problems reported by 6.5.1 users. - - - - - Migration to Version 6.5.2 - - - A dump/restore is not required for those running - 6.5.*. - - - - - Changes - - - -subselect+CASE fixes(Tom) -Add SHLIB_LINK setting for solaris_i386 and solaris_sparc ports(Daren Sefcik) -Fixes for CASE in WHERE join clauses(Tom) -Fix BTScan abort(Tom) -Repair the check for redundant UNIQUE and PRIMARY KEY indexes(Thomas) -Improve it so that it checks for multicolumn constraints(Thomas) -Fix for Windows making problem with MB enabled(Hiroki Kataoka) -Allow BSD yacc and bison to compile pl code(Bruce) -Fix SET NAMES working -int8 fixes(Thomas) -Fix vacuum's memory consumption(Hiroshi,Tatsuo) -Reduce the total memory consumption of vacuum(Tom) -Fix for timestamp(datetime) -Rule deparsing bugfixes(Tom) -Fix quoting problems in mkMakefile.tcldefs.sh.in and mkMakefile.tkdefs.sh.in(Tom) -This is to re-use space on index pages freed by vacuum(Vadim) -document -x for pg_dump(Bruce) -Fix for unary operators in rule deparser(Tom) -Comment out FileUnlink of excess segments during mdtruncate()(Tom) -IRIX linking fix from Yu Cao >yucao@falcon.kla-tencor.com< -Repair logic error in LIKE: should not return LIKE_ABORT - when reach end of pattern before end of text(Tom) -Repair incorrect cleanup of heap memory allocation during transaction abort(Tom) -Updated version of pgaccess 0.98 - - - - - - - Release 6.5.1 - - - Release date: - 1999-07-15 - - - - This is basically a cleanup release for 6.5. We have fixed a variety of - problems reported by 6.5 users. - - - - Migration to Version 6.5.1 - - - A dump/restore is not required for those running - 6.5. - - - - - Changes - - - -Add NT README file -Portability fixes for linux_ppc, IRIX, linux_alpha, OpenBSD, alpha -Remove QUERY_LIMIT, use SELECT...LIMIT -Fix for EXPLAIN on inheritance(Tom) -Patch to allow vacuum on multisegment tables(Hiroshi) -R-Tree optimizer selectivity fix(Tom) -ACL file descriptor leak fix(Atsushi Ogawa) -New expression subtree code(Tom) -Avoid disk writes for read-only transactions(Vadim) -Fix for removal of temp tables if last transaction was aborted(Bruce) -Fix to prevent too large row from being created(Bruce) -plpgsql fixes -Allow port numbers 32k - 64k(Bruce) -Add ^ precedence(Bruce) -Rename sort files called pg_temp to pg_sorttemp(Bruce) -Fix for microseconds in time values(Tom) -Tutorial source cleanup -New linux_m68k port -Fix for sorting of NULL's in some cases(Tom) -Shared library dependencies fixed (Tom) -Fixed glitches affecting GROUP BY in subselects(Tom) -Fix some compiler warnings (Tomoaki Nishiyama) -Add Win1250 (Czech) support (Pavel Behal) - - - - - - - Release 6.5 - - - Release date: - 1999-06-09 - - - - This release marks a major step in the development team's mastery of the source - code we inherited from Berkeley. You will see we are now easily adding - major features, thanks to the increasing size and experience of our - world-wide development team. - - - - Here is a brief summary of the more notable changes: - - - - - Multiversion concurrency control(MVCC) - - - - This removes our old table-level locking, and replaces it with - a locking system that is superior to most commercial database - systems. In a traditional system, each row that is modified - is locked until committed, preventing reads by other users. - MVCC uses the natural multiversion nature of - PostgreSQL to allow readers to - continue reading consistent data during writer activity. - Writers continue to use the compact pg_log transaction system. - This is all performed without having to allocate a lock for - every row like traditional database systems. So, basically, - we no longer are restricted by simple table-level locking; we - have something better than row-level locking. - - - - - - - Hot backups from pg_dump - - - - pg_dump takes advantage of the new - MVCC features to give a consistent database dump/backup while - the database stays online and available for queries. - - - - - - - Numeric data type - - - - We now have a true numeric data type, with - user-specified precision. - - - - - - - Temporary tables - - - - Temporary tables are guaranteed to have unique names - within a database session, and are destroyed on session exit. - - - - - - - New SQL features - - - - We now have CASE, INTERSECT, and EXCEPT statement - support. We have new LIMIT/OFFSET, SET TRANSACTION ISOLATION LEVEL, - SELECT ... FOR UPDATE, and an improved LOCK TABLE command. - - - - - - - Speedups - - - - We continue to speed up PostgreSQL, - thanks to the variety of talents within our team. We have - sped up memory allocation, optimization, table joins, and row - transfer routines. - - - - - - - Ports - - - - We continue to expand our port list, this time including - Windows NT/ix86 and NetBSD/arm32. - - - - - - - Interfaces - - - - Most interfaces have new versions, and existing functionality - has been improved. - - - - - - - Documentation - - - - New and updated material is present throughout the - documentation. New FAQs have been - contributed for SGI and AIX platforms. - The Tutorial has introductory information - on SQL from Stefan Simkovics. - For the User's Guide, there are - reference pages covering the postmaster and more utility - programs, and a new appendix - contains details on date/time behavior. - The Administrator's Guide has a new - chapter on troubleshooting from Tom Lane. - And the Programmer's Guide has a - description of query processing, also from Stefan, and details - on obtaining the PostgreSQL source - tree via anonymous CVS and - CVSup. - - - - - - - - Migration to Version 6.5 - - - A dump/restore using pg_dump - is required for those wishing to migrate data from any - previous release of PostgreSQL. - pg_upgrade can not - be used to upgrade to this release because the on-disk structure - of the tables has changed compared to previous releases. - - - - The new Multiversion Concurrency Control (MVCC) features can - give somewhat different behaviors in multiuser - environments. Read and understand the following section - to ensure that your existing applications will give you the - behavior you need. - - - - Multiversion Concurrency Control - - - Because readers in 6.5 don't lock data, regardless of transaction - isolation level, data read by one transaction can be overwritten by - another. In other words, if a row is returned by - SELECT it doesn't mean that this row really exists - at the time it is returned (i.e. sometime after the statement or - transaction began) nor that the row is protected from being deleted or - updated by concurrent transactions before the current transaction does - a commit or rollback. - - - - To ensure the actual existence of a row and protect it against - concurrent updates one must use SELECT FOR UPDATE or - an appropriate LOCK TABLE statement. This should be - taken into account when porting applications from previous releases of - PostgreSQL and other environments. - - - - Keep the above in mind if you are using - contrib/refint.* triggers for - referential integrity. Additional techniques are required now. One way is - to use LOCK parent_table IN SHARE ROW EXCLUSIVE MODE - command if a transaction is going to update/delete a primary key and - use LOCK parent_table IN SHARE MODE command if a - transaction is going to update/insert a foreign key. - - - - Note that if you run a transaction in SERIALIZABLE mode then you must - execute the LOCK commands above before execution of any - DML statement - (SELECT/INSERT/DELETE/UPDATE/FETCH/COPY_TO) in the - transaction. - - - - - - These inconveniences will disappear in the future - when the ability to read dirty - (uncommitted) data (regardless of isolation level) and true referential - integrity will be implemented. - - - - - - Changes - - - -Bug Fixes ---------- -Fix text<->float8 and text<->float4 conversion functions(Thomas) -Fix for creating tables with mixed-case constraints(Billy) -Change exp()/pow() behavior to generate error on underflow/overflow(Jan) -Fix bug in pg_dump -z -Memory overrun cleanups(Tatsuo) -Fix for lo_import crash(Tatsuo) -Adjust handling of data type names to suppress double quotes(Thomas) -Use type coercion for matching columns and DEFAULT(Thomas) -Fix deadlock so it only checks once after one second of sleep(Bruce) -Fixes for aggregates and PL/pgSQL(Hiroshi) -Fix for subquery crash(Vadim) -Fix for libpq function PQfnumber and case-insensitive names(Bahman Rafatjoo) -Fix for large object write-in-middle, no extra block, memory consumption(Tatsuo) -Fix for pg_dump -d or -D and quote special characters in INSERT -Repair serious problems with dynahash(Tom) -Fix INET/CIDR portability problems -Fix problem with selectivity error in ALTER TABLE ADD COLUMN(Bruce) -Fix executor so mergejoin of different column types works(Tom) -Fix for Alpha OR selectivity bug -Fix OR index selectivity problem(Bruce) -Fix so \d shows proper length for char()/varchar()(Ryan) -Fix tutorial code(Clark) -Improve destroyuser checking(Oliver) -Fix for Kerberos(Rodney McDuff) -Fix for dropping database while dirty buffers(Bruce) -Fix so sequence nextval() can be case-sensitive(Bruce) -Fix !!= operator -Drop buffers before destroying database files(Bruce) -Fix case where executor evaluates functions twice(Tatsuo) -Allow sequence nextval actions to be case-sensitive(Bruce) -Fix optimizer indexing not working for negative numbers(Bruce) -Fix for memory leak in executor with fjIsNull -Fix for aggregate memory leaks(Erik Riedel) -Allow user name containing a dash to grant privileges -Cleanup of NULL in inet types -Clean up system table bugs(Tom) -Fix problems of PAGER and \? command(Masaaki Sakaida) -Reduce default multisegment file size limit to 1GB(Peter) -Fix for dumping of CREATE OPERATOR(Tom) -Fix for backward scanning of cursors(Hiroshi Inoue) -Fix for COPY FROM STDIN when using \i(Tom) -Fix for subselect is compared inside an expression(Jan) -Fix handling of error reporting while returning rows(Tom) -Fix problems with reference to array types(Tom,Jan) -Prevent UPDATE SET oid(Jan) -Fix pg_dump so -t option can handle case-sensitive tablenames -Fixes for GROUP BY in special cases(Tom, Jan) -Fix for memory leak in failed queries(Tom) -DEFAULT now supports mixed-case identifiers(Tom) -Fix for multisegment uses of DROP/RENAME table, indexes(Ole Gjerde) -Disable use of pg_dump with both -o and -d options(Bruce) -Allow pg_dump to properly dump group privileges(Bruce) -Fix GROUP BY in INSERT INTO table SELECT * FROM table2(Jan) -Fix for computations in views(Jan) -Fix for aggregates on array indexes(Tom) -Fix for DEFAULT handles single quotes in value requiring too many quotes -Fix security problem with non-super users importing/exporting large objects(Tom) -Rollback of transaction that creates table cleaned up properly(Tom) -Fix to allow long table and column names to generate proper serial names(Tom) - -Enhancements ------------- -Add "vacuumdb" utility -Speed up libpq by allocating memory better(Tom) -EXPLAIN all indexes used(Tom) -Implement CASE, COALESCE, NULLIF expression(Thomas) -New pg_dump table output format(Constantin) -Add string min()/max() functions(Thomas) -Extend new type coercion techniques to aggregates(Thomas) -New moddatetime contrib(Terry) -Update to pgaccess 0.96(Constantin) -Add routines for single-byte "char" type(Thomas) -Improved substr() function(Thomas) -Improved multibyte handling(Tatsuo) -Multiversion concurrency control/MVCC(Vadim) -New Serialized mode(Vadim) -Fix for tables over 2gigs(Peter) -New SET TRANSACTION ISOLATION LEVEL(Vadim) -New LOCK TABLE IN ... MODE(Vadim) -Update ODBC driver(Byron) -New NUMERIC data type(Jan) -New SELECT FOR UPDATE(Vadim) -Handle "NaN" and "Infinity" for input values(Jan) -Improved date/year handling(Thomas) -Improved handling of backend connections(Magnus) -New options ELOG_TIMESTAMPS and USE_SYSLOG options for log files(Massimo) -New TCL_ARRAYS option(Massimo) -New INTERSECT and EXCEPT(Stefan) -New pg_index.indisprimary for primary key tracking(D'Arcy) -New pg_dump option to allow dropping of tables before creation(Brook) -Speedup of row output routines(Tom) -New READ COMMITTED isolation level(Vadim) -New TEMP tables/indexes(Bruce) -Prevent sorting if result is already sorted(Jan) -New memory allocation optimization(Jan) -Allow psql to do \p\g(Bruce) -Allow multiple rule actions(Jan) -Added LIMIT/OFFSET functionality(Jan) -Improve optimizer when joining a large number of tables(Bruce) -New intro to SQL from S. Simkovics' Master's Thesis (Stefan, Thomas) -New intro to backend processing from S. Simkovics' Master's Thesis (Stefan) -Improved int8 support(Ryan Bradetich, Thomas, Tom) -New routines to convert between int8 and text/varchar types(Thomas) -New bushy plans, where meta-tables are joined(Bruce) -Enable right-hand queries by default(Bruce) -Allow reliable maximum number of backends to be set at configure time - (--with-maxbackends and postmaster switch (-N backends))(Tom) -GEQO default now 10 tables because of optimizer speedups(Tom) -Allow NULL=Var for MS-SQL portability(Michael, Bruce) -Modify contrib check_primary_key() so either "automatic" or "dependent"(Anand) -Allow psql \d on a view show query(Ryan) -Speedup for LIKE(Bruce) -Ecpg fixes/features, see src/interfaces/ecpg/ChangeLog file(Michael) -JDBC fixes/features, see src/interfaces/jdbc/CHANGELOG(Peter) -Make % operator have precedence like /(Bruce) -Add new postgres -O option to allow system table structure changes(Bruce) -Update contrib/pginterface/findoidjoins script(Tom) -Major speedup in vacuum of deleted rows with indexes(Vadim) -Allow non-SQL functions to run different versions based on arguments(Tom) -Add -E option that shows actual queries sent by \dt and friends(Masaaki Sakaida) -Add version number in start-up banners for psql(Masaaki Sakaida) -New contrib/vacuumlo removes large objects not referenced(Peter) -New initialization for table sizes so non-vacuumed tables perform better(Tom) -Improve error messages when a connection is rejected(Tom) -Support for arrays of char() and varchar() fields(Massimo) -Overhaul of hash code to increase reliability and performance(Tom) -Update to PyGreSQL 2.4(D'Arcy) -Changed debug options so -d4 and -d5 produce different node displays(Jan) -New pg_options: pretty_plan, pretty_parse, pretty_rewritten(Jan) -Better optimization statistics for system table access(Tom) -Better handling of non-default block sizes(Massimo) -Improve GEQO optimizer memory consumption(Tom) -UNION now supports ORDER BY of columns not in target list(Jan) -Major libpq++ improvements(Vince Vielhaber) -pg_dump now uses -z(ACL's) as default(Bruce) -backend cache, memory speedups(Tom) -have pg_dump do everything in one snapshot transaction(Vadim) -fix for large object memory leakage, fix for pg_dumping(Tom) -INET type now respects netmask for comparisons -Make VACUUM ANALYZE only use a readlock(Vadim) -Allow VIEWs on UNIONS(Jan) -pg_dump now can generate consistent snapshots on active databases(Vadim) - -Source Tree Changes -------------------- -Improve port matching(Tom) -Portability fixes for SunOS -Add Windows NT backend port and enable dynamic loading(Magnus and Daniel Horak) -New port to Cobalt Qube(Mips) running Linux(Tatsuo) -Port to NetBSD/m68k(Mr. Mutsuki Nakajima) -Port to NetBSD/sun3(Mr. Mutsuki Nakajima) -Port to NetBSD/macppc(Toshimi Aoki) -Fix for tcl/tk configuration(Vince) -Removed CURRENT key word for rule queries(Jan) -NT dynamic loading now works(Daniel Horak) -Add ARM32 support(Andrew McMurry) -Better support for HP-UX 11 and UnixWare -Improve file handling to be more uniform, prevent file descriptor leak(Tom) -New install commands for plpgsql(Jan) - - - - - - - -Release 6.4.2 - - - Release date: - 1998-12-20 - - - -The 6.4.1 release was improperly packaged. This also has one additional -bug fix. - - - - -Migration to Version 6.4.2 - - -A dump/restore is not required for those running -6.4.*. - - - -Changes - - - -Fix for datetime constant problem on some platforms(Thomas) - - - - - - - - -Release 6.4.1 - - - Release date: - 1998-12-18 - - - -This is basically a cleanup release for 6.4. We have fixed a variety of -problems reported by 6.4 users. - - - - -Migration to Version 6.4.1 - - -A dump/restore is not required for those running -6.4. - - - -Changes - - - -Add pg_dump -N flag to force double quotes around identifiers. This is - the default(Thomas) -Fix for NOT in where clause causing crash(Bruce) -EXPLAIN VERBOSE coredump fix(Vadim) -Fix shared-library problems on Linux -Fix test for table existence to allow mixed-case and whitespace in - the table name(Thomas) -Fix a couple of pg_dump bugs -Configure matches template/.similar entries better(Tom) -Change builtin function names from SPI_* to spi_* -OR WHERE clause fix(Vadim) -Fixes for mixed-case table names(Billy) -contrib/linux/postgres.init.csh/sh fix(Thomas) -libpq memory overrun fix -SunOS fixes(Tom) -Change exp() behavior to generate error on underflow(Thomas) -pg_dump fixes for memory leak, inheritance constraints, layout change -update pgaccess to 0.93 -Fix prototype for 64-bit platforms -Multibyte fixes(Tatsuo) -New ecpg man page -Fix memory overruns(Tatsuo) -Fix for lo_import() crash(Bruce) -Better search for install program(Tom) -Timezone fixes(Tom) -HP-UX fixes(Tom) -Use implicit type coercion for matching DEFAULT values(Thomas) -Add routines to help with single-byte (internal) character type(Thomas) -Compilation of libpq for Windows fixes(Magnus) -Upgrade to PyGreSQL 2.2(D'Arcy) - - - - - - - - -Release 6.4 - - - Release date: - 1998-10-30 - - - -There are many new features and improvements in this release. -Thanks to our developers and maintainers, nearly every aspect of the system -has received some attention since the previous release. -Here is a brief, incomplete summary: - - - - -Views and rules are now functional thanks to extensive new code in the -rewrite rules system from Jan Wieck. He also wrote a chapter on it -for the Programmer's Guide. - - - - -Jan also contributed a second procedural language, PL/pgSQL, to go with the -original PL/pgTCL procedural language he contributed last release. - - - - - -We have optional multiple-byte character set support from Tatsuo Ishii -to complement our existing locale support. - - - - - -Client/server communications has been cleaned up, with better support for -asynchronous messages and interrupts thanks to Tom Lane. - - - - - -The parser will now perform automatic type coercion to match arguments -to available operators and functions, and to match columns and expressions -with target columns. This uses a generic mechanism which supports -the type extensibility features of PostgreSQL. -There is a new chapter in the User's Guide -which covers this topic. - - - - - -Three new data types have been added. -Two types, inet and cidr, support various forms -of IP network, subnet, and machine addressing. There is now an 8-byte integer -type available on some platforms. See the chapter on data types -in the User's Guide for details. -A fourth type, serial, is now supported by the parser as an -amalgam of the int4 type, a sequence, and a unique index. - - - - - -Several more SQL92-compatible syntax features have been -added, including INSERT DEFAULT VALUES - - - - - -The automatic configuration and installation system has received some -attention, and should be more robust for more platforms than it has ever -been. - - - - - - - -Migration to Version 6.4 - - -A dump/restore using pg_dump -or pg_dumpall -is required for those wishing to migrate data from any -previous release of PostgreSQL. - - - - -Changes - - - -Bug Fixes ---------- -Fix for a tiny memory leak in PQsetdb/PQfinish(Bryan) -Remove char2-16 data types, use char/varchar(Darren) -Pqfn not handles a NOTICE message(Anders) -Reduced busywaiting overhead for spinlocks with many backends (dg) -Stuck spinlock detection (dg) -Fix up "ISO-style" timespan decoding and encoding(Thomas) -Fix problem with table drop after rollback of transaction(Vadim) -Change error message and remove non-functional update message(Vadim) -Fix for COPY array checking -Fix for SELECT 1 UNION SELECT NULL -Fix for buffer leaks in large object calls(Pascal) -Change owner from oid to int4 type(Bruce) -Fix a bug in the oracle compatibility functions btrim() ltrim() and rtrim() -Fix for shared invalidation cache overflow(Massimo) -Prevent file descriptor leaks in failed COPY's(Bruce) -Fix memory leak in libpgtcl's pg_select(Constantin) -Fix problems with username/passwords over 8 characters(Tom) -Fix problems with handling of asynchronous NOTIFY in backend(Tom) -Fix of many bad system table entries(Tom) - -Enhancements ------------- -Upgrade ecpg and ecpglib,see src/interfaces/ecpc/ChangeLog(Michael) -Show the index used in an EXPLAIN(Zeugswetter) -EXPLAIN invokes rule system and shows plan(s) for rewritten queries(Jan) -Multibyte awareness of many data types and functions, via configure(Tatsuo) -New configure --with-mb option(Tatsuo) -New initdb --pgencoding option(Tatsuo) -New createdb -E multibyte option(Tatsuo) -Select version(); now returns PostgreSQL version(Jeroen) -libpq now allows asynchronous clients(Tom) -Allow cancel from client of backend query(Tom) -psql now cancels query with Control-C(Tom) -libpq users need not issue dummy queries to get NOTIFY messages(Tom) -NOTIFY now sends sender's PID, so you can tell whether it was your own(Tom) -PGresult struct now includes associated error message, if any(Tom) -Define "tz_hour" and "tz_minute" arguments to date_part()(Thomas) -Add routines to convert between varchar and bpchar(Thomas) -Add routines to allow sizing of varchar and bpchar into target columns(Thomas) -Add bit flags to support timezonehour and minute in data retrieval(Thomas) -Allow more variations on valid floating point numbers (e.g. ".1", "1e6")(Thomas) -Fixes for unary minus parsing with leading spaces(Thomas) -Implement TIMEZONE_HOUR, TIMEZONE_MINUTE per SQL92 specs(Thomas) -Check for and properly ignore FOREIGN KEY column constraints(Thomas) -Define USER as synonym for CURRENT_USER per SQL92 specs(Thomas) -Enable HAVING clause but no fixes elsewhere yet. -Make "char" type a synonym for "char(1)" (actually implemented as bpchar)(Thomas) -Save string type if specified for DEFAULT clause handling(Thomas) -Coerce operations involving different data types(Thomas) -Allow some index use for columns of different types(Thomas) -Add capabilities for automatic type conversion(Thomas) -Cleanups for large objects, so file is truncated on open(Peter) -Readline cleanups(Tom) -Allow psql \f \ to make spaces as delimiter(Bruce) -Pass pg_attribute.atttypmod to the frontend for column field lengths(Tom,Bruce) -Msql compatibility library in /contrib(Aldrin) -Remove the requirement that ORDER/GROUP BY clause identifiers be -included in the target list(David) -Convert columns to match columns in UNION clauses(Thomas) -Remove fork()/exec() and only do fork()(Bruce) -Jdbc cleanups(Peter) -Show backend status on ps command line(only works on some platforms)(Bruce) -Pg_hba.conf now has a sameuser option in the database field -Make lo_unlink take oid param, not int4 -New DISABLE_COMPLEX_MACRO for compilers that cannot handle our macros(Bruce) -Libpgtcl now handles NOTIFY as a Tcl event, need not send dummy queries(Tom) -libpgtcl cleanups(Tom) -Add -error option to libpgtcl's pg_result command(Tom) -New locale patch, see docs/README/locale(Oleg) -Fix for pg_dump so CONSTRAINT and CHECK syntax is correct(ccb) -New contrib/lo code for large object orphan removal(Peter) -New psql command "SET CLIENT_ENCODING TO 'encoding'" for multibytes -feature, see /doc/README.mb(Tatsuo) -contrib/noupdate code to revoke update permission on a column -libpq can now be compiled on Windows(Magnus) -Add PQsetdbLogin() in libpq -New 8-byte integer type, checked by configure for OS support(Thomas) -Better support for quoted table/column names(Thomas) -Surround table and column names with double-quotes in pg_dump(Thomas) -PQreset() now works with passwords(Tom) -Handle case of GROUP BY target list column number out of range(David) -Allow UNION in subselects -Add auto-size to screen to \d? commands(Bruce) -Use UNION to show all \d? results in one query(Bruce) -Add \d? field search feature(Bruce) -Pg_dump issues fewer \connect requests(Tom) -Make pg_dump -z flag work better, document it in manual page(Tom) -Add HAVING clause with full support for subselects and unions(Stephan) -Full text indexing routines in contrib/fulltextindex(Maarten) -Transaction ids now stored in shared memory(Vadim) -New PGCLIENTENCODING when issuing COPY command(Tatsuo) -Support for SQL92 syntax "SET NAMES"(Tatsuo) -Support for LATIN2-5(Tatsuo) -Add UNICODE regression test case(Tatsuo) -Lock manager cleanup, new locking modes for LLL(Vadim) -Allow index use with OR clauses(Bruce) -Allows "SELECT NULL ORDER BY 1;" -Explain VERBOSE prints the plan, and now pretty-prints the plan to -the postmaster log file(Bruce) -Add indexes display to \d command(Bruce) -Allow GROUP BY on functions(David) -New pg_class.relkind for large objects(Bruce) -New way to send libpq NOTICE messages to a different location(Tom) -New \w write command to psql(Bruce) -New /contrib/findoidjoins scans oid columns to find join relationships(Bruce) -Allow binary-compatible indexes to be considered when checking for valid -Indexes for restriction clauses containing a constant(Thomas) -New ISBN/ISSN code in /contrib/isbn_issn -Allow NOT LIKE, IN, NOT IN, BETWEEN, and NOT BETWEEN constraint(Thomas) -New rewrite system fixes many problems with rules and views(Jan) - * Rules on relations work - * Event qualifications on insert/update/delete work - * New OLD variable to reference CURRENT, CURRENT will be remove in future - * Update rules can reference NEW and OLD in rule qualifications/actions - * Insert/update/delete rules on views work - * Multiple rule actions are now supported, surrounded by parentheses - * Regular users can create views/rules on tables they have RULE permits - * Rules and views inherit the privileges of the creator - * No rules at the column level - * No UPDATE NEW/OLD rules - * New pg_tables, pg_indexes, pg_rules and pg_views system views - * Only a single action on SELECT rules - * Total rewrite overhaul, perhaps for 6.5 - * handle subselects - * handle aggregates on views - * handle insert into select from view works -System indexes are now multikey(Bruce) -Oidint2, oidint4, and oidname types are removed(Bruce) -Use system cache for more system table lookups(Bruce) -New backend programming language PL/pgSQL in backend/pl(Jan) -New SERIAL data type, auto-creates sequence/index(Thomas) -Enable assert checking without a recompile(Massimo) -User lock enhancements(Massimo) -New setval() command to set sequence value(Massimo) -Auto-remove unix socket file on start-up if no postmaster running(Massimo) -Conditional trace package(Massimo) -New UNLISTEN command(Massimo) -psql and libpq now compile under Windows using win32.mak(Magnus) -Lo_read no longer stores trailing NULL(Bruce) -Identifiers are now truncated to 31 characters internally(Bruce) -Createuser options now available on the command line -Code for 64-bit integer supported added, configure tested, int8 type(Thomas) -Prevent file descriptor leaf from failed COPY(Bruce) -New pg_upgrade command(Bruce) -Updated /contrib directories(Massimo) -New CREATE TABLE DEFAULT VALUES statement available(Thomas) -New INSERT INTO TABLE DEFAULT VALUES statement available(Thomas) -New DECLARE and FETCH feature(Thomas) -libpq's internal structures now not exported(Tom) -Allow up to 8 key indexes(Bruce) -Remove ARCHIVE key word, that is no longer used(Thomas) -pg_dump -n flag to suppress quotes around identifiers -disable system columns for views(Jan) -new INET and CIDR types for network addresses(TomH, Paul) -no more double quotes in psql output -pg_dump now dumps views(Terry) -new SET QUERY_LIMIT(Tatsuo,Jan) - -Source Tree Changes -------------------- -/contrib cleanup(Jun) -Inline some small functions called for every row(Bruce) -Alpha/linux fixes -HP-UX cleanups(Tom) -Multibyte regression tests(Soonmyung.) -Remove --disabled options from configure -Define PGDOC to use POSTGRESDIR by default -Make regression optional -Remove extra braces code to pgindent(Bruce) -Add bsdi shared library support(Bruce) -New --without-CXX support configure option(Brook) -New FAQ_CVS -Update backend flowchart in tools/backend(Bruce) -Change atttypmod from int16 to int32(Bruce, Tom) -Getrusage() fix for platforms that do not have it(Tom) -Add PQconnectdb, PGUSER, PGPASSWORD to libpq man page -NS32K platform fixes(Phil Nelson, John Buller) -SCO 7/UnixWare 2.x fixes(Billy,others) -Sparc/Solaris 2.5 fixes(Ryan) -Pgbuiltin.3 is obsolete, move to doc files(Thomas) -Even more documentation(Thomas) -Nextstep support(Jacek) -Aix support(David) -pginterface manual page(Bruce) -shared libraries all have version numbers -merged all OS-specific shared library defines into one file -smarter TCL/TK configuration checking(Billy) -smarter perl configuration(Brook) -configure uses supplied install-sh if no install script found(Tom) -new Makefile.shlib for shared library configuration(Tom) - - - - - - -Release 6.3.2 - - - Release date: - 1998-04-07 - - - -This is a bug-fix release for 6.3.x. -Refer to the release notes for version 6.3 for a more complete summary of new features. - - -Summary: - - - - -Repairs automatic configuration support for some platforms, including Linux, -from breakage inadvertently introduced in version 6.3.1. - - - - - -Correctly handles function calls on the left side of BETWEEN and LIKE clauses. - - - - - - -A dump/restore is NOT required for those running 6.3 or 6.3.1. A -make distclean, make, and make install is all that is required. -This last step should be performed while the postmaster is not running. -You should re-link any custom applications that use PostgreSQL libraries. - - -For upgrades from pre-6.3 installations, -refer to the installation and migration instructions for version 6.3. - - - - Changes - - - -Configure detection improvements for tcl/tk(Brook Milligan, Alvin) -Manual page improvements(Bruce) -BETWEEN and LIKE fix(Thomas) -fix for psql \connect used by pg_dump(Oliver Elphick) -New odbc driver -pgaccess, version 0.86 -qsort removed, now uses libc version, cleanups(Jeroen) -fix for buffer over-runs detected(Maurice Gittens) -fix for buffer overrun in libpgtcl(Randy Kunkee) -fix for UNION with DISTINCT or ORDER BY(Bruce) -gettimeofday configure check(Doug Winterburn) -Fix "indexes not used" bug(Vadim) -docs additions(Thomas) -Fix for backend memory leak(Bruce) -libreadline cleanup(Erwan MAS) -Remove DISTDIR(Bruce) -Makefile dependency cleanup(Jeroen van Vianen) -ASSERT fixes(Bruce) - - - - - - - Release 6.3.1 - - - Release date: - 1998-03-23 - - - - Summary: - - - - -Additional support for multibyte character sets. - - - - - -Repair byte ordering for mixed-endian clients and servers. - - - - - -Minor updates to allowed SQL syntax. - - - - - -Improvements to the configuration autodetection for installation. - - - - - - -A dump/restore is NOT required for those running 6.3. A -make distclean, make, and make install is all that is required. -This last step should be performed while the postmaster is not running. -You should re-link any custom applications that use PostgreSQL libraries. - - -For upgrades from pre-6.3 installations, -refer to the installation and migration instructions for version 6.3. - - - - Changes - - - -ecpg cleanup/fixes, now version 1.1(Michael Meskes) -pg_user cleanup(Bruce) -large object fix for pg_dump and tclsh (alvin) -LIKE fix for multiple adjacent underscores -fix for redefining builtin functions(Thomas) -ultrix4 cleanup -upgrade to pg_access 0.83 -updated CLUSTER manual page -multibyte character set support, see doc/README.mb(Tatsuo) -configure --with-pgport fix -pg_ident fix -big-endian fix for backend communications(Kataoka) -SUBSTR() and substring() fix(Jan) -several jdbc fixes(Peter) -libpgtcl improvements, see libptcl/README(Randy Kunkee) -Fix for "Datasize = 0" error(Vadim) -Prevent \do from wrapping(Bruce) -Remove duplicate Russian character set entries -Sunos4 cleanup -Allow optional TABLE key word in LOCK and SELECT INTO(Thomas) -CREATE SEQUENCE options to allow a negative integer(Thomas) -Add "PASSWORD" as an allowed column identifier(Thomas) -Add checks for UNION target fields(Bruce) -Fix Alpha port(Dwayne Bailey) -Fix for text arrays containing quotes(Doug Gibson) -Solaris compile fix(Albert Chin-A-Young) -Better identify tcl and tk libs and includes(Bruce) - - - - - - - Release 6.3 - - - Release date: - 1998-03-01 - - - - There are many new features and improvements in this release. - Here is a brief, incomplete summary: - - - - - Many new SQL features, including - full SQL92 subselect capability - (everything is here but target-list subselects). - - - - - - Support for client-side environment variables to specify time zone and date style. - - - - - - Socket interface for client/server connection. This is the default now - so you might need to start postmaster with the - flag. - - - - - - Better password authorization mechanisms. Default table privileges have changed. - - - - - - Old-style time travel - has been removed. Performance has been improved. - - - - - - - - Bruce Momjian wrote the following notes to introduce the new release. - - - - - There are some general 6.3 issues that I want to mention. These are - only the big items that cannot be described in one sentence. A review - of the detailed changes list is still needed. - - - First, we now have subselects. Now that we have them, I would like to - mention that without subselects, SQL is a very limited language. - Subselects are a major feature, and you should review your code for - places where subselects provide a better solution for your queries. I - think you will find that there are more uses for subselects than you might - think. Vadim has put us on the big SQL map with subselects, and fully - functional ones too. The only thing you cannot do with subselects is to - use them in the target list. - - - Second, 6.3 uses Unix domain sockets rather than TCP/IP by default. To - enable connections from other machines, you have to use the new - postmaster -i option, and of course edit pg_hba.conf. Also, for this - reason, the format of pg_hba.conf has changed. - - - Third, char() fields will now allow faster access than varchar() or - text. Specifically, the text and varchar() have a penalty for access to - any columns after the first column of this type. char() used to also - have this access penalty, but it no longer does. This might suggest that - you redesign some of your tables, especially if you have short character - columns that you have defined as varchar() or text. This and other - changes make 6.3 even faster than earlier releases. - - - We now have passwords definable independent of any Unix file. There are - new SQL USER commands. - See the Administrator's Guide for more - information. There is a new table, pg_shadow, which is used to store - user information and user passwords, and it by default only SELECT-able - by the postgres super-user. pg_user is now a view of pg_shadow, and is - SELECT-able by PUBLIC. You should keep using pg_user in your - application without changes. - - - User-created tables now no longer have SELECT privilege to PUBLIC by - default. This was done because the ANSI standard requires it. You can - of course GRANT any privileges you want after the table is created. - System tables continue to be SELECT-able by PUBLIC. - - - We also have real deadlock detection code. No more sixty-second - timeouts. And the new locking code implements a FIFO better, so there - should be less resource starvation during heavy use. - - - Many complaints have been made about inadequate documentation in previous - releases. Thomas has put much effort into many new manuals for this - release. Check out the doc/ directory. - - - For performance reasons, time travel is gone, but can be implemented - using triggers (see pgsql/contrib/spi/README). Please check out the new - \d command for types, operators, etc. Also, views have their own - privileges now, not based on the underlying tables, so privileges on - them have to be set separately. Check /pgsql/interfaces for some new - ways to talk to PostgreSQL. - - - This is the first release that really required an explanation for - existing users. In many ways, this was necessary because the new - release removes many limitations, and the work-arounds people were using - are no longer needed. - - - - Migration to Version 6.3 - - - A dump/restore using pg_dump - or pg_dumpall - is required for those wishing to migrate data from any - previous release of PostgreSQL. - - - - - Changes - - - -Bug Fixes ---------- -Fix binary cursors broken by MOVE implementation(Vadim) -Fix for tcl library crash(Jan) -Fix for array handling, from Gerhard Hintermayer -Fix acl error, and remove duplicate pqtrace(Bruce) -Fix psql \e for empty file(Bruce) -Fix for textcat on varchar() fields(Bruce) -Fix for DBT Sendproc (Zeugswetter Andres) -Fix vacuum analyze syntax problem(Bruce) -Fix for international identifiers(Tatsuo) -Fix aggregates on inherited tables(Bruce) -Fix substr() for out-of-bounds data -Fix for select 1=1 or 2=2, select 1=1 and 2=2, and select sum(2+2)(Bruce) -Fix notty output to show status result. -q option still turns it off(Bruce) -Fix for count(*), aggs with views and multiple tables and sum(3)(Bruce) -Fix cluster(Bruce) -Fix for PQtrace start/stop several times(Bruce) -Fix a variety of locking problems like newer lock waiters getting - lock before older waiters, and having readlock people not share - locks if a writer is waiting for a lock, and waiting writers not - getting priority over waiting readers(Bruce) -Fix crashes in psql when executing queries from external files(James) -Fix problem with multiple order by columns, with the first one having - NULL values(Jeroen) -Use correct hash table support functions for float8 and int4(Thomas) -Re-enable JOIN= option in CREATE OPERATOR statement (Thomas) -Change precedence for boolean operators to match expected behavior(Thomas) -Generate elog(ERROR) on over-large integer(Bruce) -Allow multiple-argument functions in constraint clauses(Thomas) -Check boolean input literals for 'true','false','yes','no','1','0' - and throw elog(ERROR) if unrecognized(Thomas) -Major large objects fix -Fix for GROUP BY showing duplicates(Vadim) -Fix for index scans in MergeJoin(Vadim) - -Enhancements ------------- -Subselects with EXISTS, IN, ALL, ANY key words (Vadim, Bruce, Thomas) -New User Manual(Thomas, others) -Speedup by inlining some frequently-called functions -Real deadlock detection, no more timeouts(Bruce) -Add SQL92 "constants" CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, - CURRENT_USER(Thomas) -Modify constraint syntax to be SQL92-compliant(Thomas) -Implement SQL92 PRIMARY KEY and UNIQUE clauses using indexes(Thomas) -Recognize SQL92 syntax for FOREIGN KEY. Throw elog notice(Thomas) -Allow NOT NULL UNIQUE constraint clause (each allowed separately before)(Thomas) -Allow PostgreSQL-style casting ("::") of non-constants(Thomas) -Add support for SQL3 TRUE and FALSE boolean constants(Thomas) -Support SQL92 syntax for IS TRUE/IS FALSE/IS NOT TRUE/IS NOT FALSE(Thomas) -Allow shorter strings for boolean literals (e.g. "t", "tr", "tru")(Thomas) -Allow SQL92 delimited identifiers(Thomas) -Implement SQL92 binary and hexadecimal string decoding (b'10' and x'1F')(Thomas) -Support SQL92 syntax for type coercion of literal strings - (e.g. "DATETIME 'now'")(Thomas) -Add conversions for int2, int4, and OID types to and from text(Thomas) -Use shared lock when building indexes(Vadim) -Free memory allocated for a user query inside transaction block after - this query is done, was turned off in <= 6.2.1(Vadim) -New SQL statement CREATE PROCEDURAL LANGUAGE(Jan) -New PostgreSQL Procedural Language (PL) backend interface(Jan) -Rename pg_dump -H option to -h(Bruce) -Add Java support for passwords, European dates(Peter) -Use indexes for LIKE and ~, !~ operations(Bruce) -Add hash functions for datetime and timespan(Thomas) -Time Travel removed(Vadim, Bruce) -Add paging for \d and \z, and fix \i(Bruce) -Add Unix domain socket support to backend and to frontend library(Goran) -Implement CREATE DATABASE/WITH LOCATION and initlocation utility(Thomas) -Allow more SQL92 and/or PostgreSQL reserved words as column identifiers(Thomas) -Augment support for SQL92 SET TIME ZONE...(Thomas) -SET/SHOW/RESET TIME ZONE uses TZ backend environment variable(Thomas) -Implement SET keyword = DEFAULT and SET TIME ZONE DEFAULT(Thomas) -Enable SET TIME ZONE using TZ environment variable(Thomas) -Add PGDATESTYLE environment variable to frontend and backend initialization(Thomas) -Add PGTZ, PGCOSTHEAP, PGCOSTINDEX, PGRPLANS, PGGEQO - frontend library initialization environment variables(Thomas) -Regression tests time zone automatically set with "setenv PGTZ PST8PDT"(Thomas) -Add pg_description table for info on tables, columns, operators, types, and - aggregates(Bruce) -Increase 16 char limit on system table/index names to 32 characters(Bruce) -Rename system indexes(Bruce) -Add 'GERMAN' option to SET DATESTYLE(Thomas) -Define an "ISO-style" timespan output format with "hh:mm:ss" fields(Thomas) -Allow fractional values for delta times (e.g. '2.5 days')(Thomas) -Validate numeric input more carefully for delta times(Thomas) -Implement day of year as possible input to date_part()(Thomas) -Define timespan_finite() and text_timespan() functions(Thomas) -Remove archive stuff(Bruce) -Allow for a pg_password authentication database that is separate from - the system password file(Todd) -Dump ACLs, GRANT, REVOKE privileges(Matt) -Define text, varchar, and bpchar string length functions(Thomas) -Fix Query handling for inheritance, and cost computations(Bruce) -Implement CREATE TABLE/AS SELECT (alternative to SELECT/INTO)(Thomas) -Allow NOT, IS NULL, IS NOT NULL in constraints(Thomas) -Implement UNIONs for SELECT(Bruce) -Add UNION, GROUP, DISTINCT to INSERT(Bruce) -varchar() stores only necessary bytes on disk(Bruce) -Fix for BLOBs(Peter) -Mega-Patch for JDBC...see README_6.3 for list of changes(Peter) -Remove unused "option" from PQconnectdb() -New LOCK command and lock manual page describing deadlocks(Bruce) -Add new psql \da, \dd, \df, \do, \dS, and \dT commands(Bruce) -Enhance psql \z to show sequences(Bruce) -Show NOT NULL and DEFAULT in psql \d table(Bruce) -New psql .psqlrc file start-up(Andrew) -Modify sample start-up script in contrib/linux to show syslog(Thomas) -New types for IP and MAC addresses in contrib/ip_and_mac(TomH) -Unix system time conversions with date/time types in contrib/unixdate(Thomas) -Update of contrib stuff(Massimo) -Add Unix socket support to DBD::Pg(Goran) -New python interface (PyGreSQL 2.0)(D'Arcy) -New frontend/backend protocol has a version number, network byte order(Phil) -Security features in pg_hba.conf enhanced and documented, many cleanups(Phil) -CHAR() now faster access than VARCHAR() or TEXT -ecpg embedded SQL preprocessor -Reduce system column overhead(Vadmin) -Remove pg_time table(Vadim) -Add pg_type attribute to identify types that need length (bpchar, varchar) -Add report of offending line when COPY command fails -Allow VIEW privileges to be set separately from the underlying tables. - For security, use GRANT/REVOKE on views as appropriate(Jan) -Tables now have no default GRANT SELECT TO PUBLIC. You must - explicitly grant such privileges. -Clean up tutorial examples(Darren) - -Source Tree Changes -------------------- -Add new html development tools, and flow chart in /tools/backend -Fix for SCO compiles -Stratus computer port Robert Gillies -Added support for shlib for BSD44_derived & i386_solaris -Make configure more automated(Brook) -Add script to check regression test results -Break parser functions into smaller files, group together(Bruce) -Rename heap_create to heap_create_and_catalog, rename heap_creatr - to heap_create()(Bruce) -Sparc/Linux patch for locking(TomS) -Remove PORTNAME and reorganize port-specific stuff(Marc) -Add optimizer README file(Bruce) -Remove some recursion in optimizer and clean up some code there(Bruce) -Fix for NetBSD locking(Henry) -Fix for libptcl make(Tatsuo) -AIX patch(Darren) -Change IS TRUE, IS FALSE, ... to expressions using "=" rather than - function calls to istrue() or isfalse() to allow optimization(Thomas) -Various fixes NetBSD/Sparc related(TomH) -Alpha linux locking(Travis,Ryan) -Change elog(WARN) to elog(ERROR)(Bruce) -FAQ for FreeBSD(Marc) -Bring in the PostODBC source tree as part of our standard distribution(Marc) -A minor patch for HP/UX 10 vs 9(Stan) -New pg_attribute.atttypmod for type-specific info like varchar length(Bruce) -UnixWare patches(Billy) -New i386 'lock' for spinlock asm(Billy) -Support for multiplexed backends is removed -Start an OpenBSD port -Start an AUX port -Start a Cygnus port -Add string functions to regression suite(Thomas) -Expand a few function names formerly truncated to 16 characters(Thomas) -Remove un-needed malloc() calls and replace with palloc()(Bruce) - - - - - - -Release 6.2.1 - - - Release date: - 1997-10-17 - - - -6.2.1 is a bug-fix and usability release on 6.2. - - -Summary: - - - - -Allow strings to span lines, per SQL92. - - - - - -Include example trigger function for inserting user names on table updates. - - - - - - -This is a minor bug-fix release on 6.2. -For upgrades from pre-6.2 systems, a full dump/reload is required. -Refer to the 6.2 release notes for instructions. - - - -Migration from version 6.2 to version 6.2.1 - - -This is a minor bug-fix release. A dump/reload is not required from version 6.2, -but is required from any release prior to 6.2. - - -In upgrading from version 6.2, if you choose to dump/reload you will find that -avg(money) is now calculated correctly. All other bug fixes take effect -upon updating the executables. - - -Another way to avoid dump/reload is to use the following SQL command -from psql to update the existing system table: - - -update pg_aggregate set aggfinalfn = 'cash_div_flt8' - where aggname = 'avg' and aggbasetype = 790; - - - -This will need to be done to every existing database, including template1. - - - - - Changes - - - -Allow TIME and TYPE column names(Thomas) -Allow larger range of true/false as boolean values(Thomas) -Support output of "now" and "current"(Thomas) -Handle DEFAULT with INSERT of NULL properly(Vadim) -Fix for relation reference counts problem in buffer manager(Vadim) -Allow strings to span lines, like ANSI(Thomas) -Fix for backward cursor with ORDER BY(Vadim) -Fix avg(cash) computation(Thomas) -Fix for specifying a column twice in ORDER/GROUP BY(Vadim) -Documented new libpq function to return affected rows, PQcmdTuples(Bruce) -Trigger function for inserting user names for INSERT/UPDATE(Brook Milligan) - - - - - - -Release 6.2 - - - Release date: - 1997-10-02 - - - -A dump/restore is required for those wishing to migrate data from -previous releases of PostgreSQL. - - - -Migration from version 6.1 to version 6.2 - - -This migration requires a complete dump of the 6.1 database and a -restore of the database in 6.2. - - -Note that the pg_dump and pg_dumpall utility from 6.2 should be used -to dump the 6.1 database. - - - - -Migration from version 1.<replaceable>x</replaceable> to version 6.2 - - -Those migrating from earlier 1.* releases should first upgrade to 1.09 -because the COPY output format was improved from the 1.02 release. - - - - - Changes - - - -Bug Fixes ---------- -Fix problems with pg_dump for inheritance, sequences, archive tables(Bruce) -Fix compile errors on overflow due to shifts, unsigned, and bad prototypes - from Solaris(Diab Jerius) -Fix bugs in geometric line arithmetic (bad intersection calculations)(Thomas) -Check for geometric intersections at endpoints to avoid rounding ugliness(Thomas) -Catch non-functional delete attempts(Vadim) -Change time function names to be more consistent(Michael Reifenberg) -Check for zero divides(Michael Reifenberg) -Fix very old bug which made rows changed/inserted by a command - visible to the command itself (so we had multiple update of - updated rows, etc.)(Vadim) -Fix for SELECT null, 'fail' FROM pg_am (Patrick) -SELECT NULL as EMPTY_FIELD now allowed(Patrick) -Remove un-needed signal stuff from contrib/pginterface -Fix OR (where x != 1 or x isnull didn't return rows with x NULL) (Vadim) -Fix time_cmp function (Vadim) -Fix handling of functions with non-attribute first argument in - WHERE clauses (Vadim) -Fix GROUP BY when order of entries is different from order - in target list (Vadim) -Fix pg_dump for aggregates without sfunc1 (Vadim) - -Enhancements ------------- -Default genetic optimizer GEQO parameter is now 8(Bruce) -Allow use parameters in target list having aggregates in functions(Vadim) -Added JDBC driver as an interface(Adrian & Peter) -pg_password utility -Return number of rows inserted/affected by INSERT/UPDATE/DELETE etc.(Vadim) -Triggers implemented with CREATE TRIGGER (SQL3)(Vadim) -SPI (Server Programming Interface) allows execution of queries inside - C-functions (Vadim) -NOT NULL implemented (SQL92)(Robson Paniago de Miranda) -Include reserved words for string handling, outer joins, and unions(Thomas) -Implement extended comments ("/* ... */") using exclusive states(Thomas) -Add "//" single-line comments(Bruce) -Remove some restrictions on characters in operator names(Thomas) -DEFAULT and CONSTRAINT for tables implemented (SQL92)(Vadim & Thomas) -Add text concatenation operator and function (SQL92)(Thomas) -Support WITH TIME ZONE syntax (SQL92)(Thomas) -Support INTERVAL unit TO unit syntax (SQL92)(Thomas) -Define types DOUBLE PRECISION, INTERVAL, CHARACTER, - and CHARACTER VARYING (SQL92)(Thomas) -Define type FLOAT(p) and rudimentary DECIMAL(p,s), NUMERIC(p,s) (SQL92)(Thomas) -Define EXTRACT(), POSITION(), SUBSTRING(), and TRIM() (SQL92)(Thomas) -Define CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP (SQL92)(Thomas) -Add syntax and warnings for UNION, HAVING, INNER and OUTER JOIN (SQL92)(Thomas) -Add more reserved words, mostly for SQL92 compliance(Thomas) -Allow hh:mm:ss time entry for timespan/reltime types(Thomas) -Add center() routines for lseg, path, polygon(Thomas) -Add distance() routines for circle-polygon, polygon-polygon(Thomas) -Check explicitly for points and polygons contained within polygons - using an axis-crossing algorithm(Thomas) -Add routine to convert circle-box(Thomas) -Merge conflicting operators for different geometric data types(Thomas) -Replace distance operator "<===>" with "<->"(Thomas) -Replace "above" operator "!^" with ">^" and "below" operator "!|" with "<^"(Thomas) -Add routines for text trimming on both ends, substring, and string position(Thomas) -Added conversion routines circle(box) and poly(circle)(Thomas) -Allow internal sorts to be stored in memory rather than in files(Bruce & Vadim) -Allow functions and operators on internally-identical types to succeed(Bruce) -Speed up backend start-up after profiling analysis(Bruce) -Inline frequently called functions for performance(Bruce) -Reduce open() calls(Bruce) -psql: Add PAGER for \h and \?,\C fix -Fix for psql pager when no tty(Bruce) -New entab utility(Bruce) -General trigger functions for referential integrity (Vadim) -General trigger functions for time travel (Vadim) -General trigger functions for AUTOINCREMENT/IDENTITY feature (Vadim) -MOVE implementation (Vadim) - -Source Tree Changes -------------------- -HP-UX 10 patches (Vladimir Turin) -Added SCO support, (Daniel Harris) -MkLinux patches (Tatsuo Ishii) -Change geometric box terminology from "length" to "width"(Thomas) -Deprecate temporary unstored slope fields in geometric code(Thomas) -Remove restart instructions from INSTALL(Bruce) -Look in /usr/ucb first for install(Bruce) -Fix c++ copy example code(Thomas) -Add -o to psql manual page(Bruce) -Prevent relname unallocated string length from being copied into database(Bruce) -Cleanup for NAMEDATALEN use(Bruce) -Fix pg_proc names over 15 chars in output(Bruce) -Add strNcpy() function(Bruce) -remove some (void) casts that are unnecessary(Bruce) -new interfaces directory(Marc) -Replace fopen() calls with calls to fd.c functions(Bruce) -Make functions static where possible(Bruce) -enclose unused functions in #ifdef NOT_USED(Bruce) -Remove call to difftime() in timestamp support to fix SunOS(Bruce & Thomas) -Changes for Digital Unix -Portability fix for pg_dumpall(Bruce) -Rename pg_attribute.attnvals to attdispersion(Bruce) -"intro/unix" manual page now "pgintro"(Bruce) -"built-in" manual page now "pgbuiltin"(Bruce) -"drop" manual page now "drop_table"(Bruce) -Add "create_trigger", "drop_trigger" manual pages(Thomas) -Add constraints regression test(Vadim & Thomas) -Add comments syntax regression test(Thomas) -Add PGINDENT and support program(Bruce) -Massive commit to run PGINDENT on all *.c and *.h files(Bruce) -Files moved to /src/tools directory(Bruce) -SPI and Trigger programming guides (Vadim & D'Arcy) - - - - - - -Release 6.1.1 - - - Release date: - 1997-07-22 - - - -Migration from version 6.1 to version 6.1.1 - - -This is a minor bug-fix release. A dump/reload is not required from version 6.1, -but is required from any release prior to 6.1. -Refer to the release notes for 6.1 for more details. - - - - - Changes - - - -fix for SET with options (Thomas) -allow pg_dump/pg_dumpall to preserve ownership of all tables/objects(Bruce) -new psql \connect option allows changing usernames without changing databases -fix for initdb --debug option(Yoshihiko Ichikawa)) -lextest cleanup(Bruce) -hash fixes(Vadim) -fix date/time month boundary arithmetic(Thomas) -fix timezone daylight handling for some ports(Thomas, Bruce, Tatsuo) -timestamp overhauled to use standard functions(Thomas) -other code cleanup in date/time routines(Thomas) -psql's \d now case-insensitive(Bruce) -psql's backslash commands can now have trailing semicolon(Bruce) -fix memory leak in psql when using \g(Bruce) -major fix for endian handling of communication to server(Thomas, Tatsuo) -Fix for Solaris assembler and include files(Yoshihiko Ichikawa) -allow underscores in usernames(Bruce) -pg_dumpall now returns proper status, portability fix(Bruce) - - - - - - -Release 6.1 - - - Release date: - 1997-06-08 - - - - The regression tests have been adapted and extensively modified for the - 6.1 release of PostgreSQL. - - - - Three new data types (datetime, timespan, and circle) have been added to - the native set of PostgreSQL types. Points, boxes, paths, and polygons - have had their output formats made consistent across the data types. - The polygon output in misc.out has only been spot-checked for correctness - relative to the original regression output. - - - - PostgreSQL 6.1 introduces a new, alternate -optimizer which uses genetic - algorithms. These algorithms introduce a random behavior in the ordering - of query results when the query contains multiple qualifiers or multiple - tables (giving the optimizer a choice on order of evaluation). Several - regression tests have been modified to explicitly order the results, and - hence are insensitive to optimizer choices. A few regression tests are - for data types which are inherently unordered (e.g. points and time - intervals) and tests involving those types are explicitly bracketed with - set geqo to 'off' and reset geqo. - - - - The interpretation of array specifiers (the curly braces around atomic - values) appears to have changed sometime after the original regression - tests were generated. The current ./expected/*.out files reflect this - new interpretation, which might not be correct! - - - - The float8 regression test fails on at least some platforms. This is due - to differences in implementations of pow() and exp() and the signaling - mechanisms used for overflow and underflow conditions. - - - - The random results in the random test should cause the - random test to be failed, since the - regression tests are evaluated using a simple diff. However, - random does not seem to produce random results on my test - machine (Linux/gcc/i686). - - - -Migration to Version 6.1 - - -This migration requires a complete dump of the 6.0 database and a -restore of the database in 6.1. - - -Those migrating from earlier 1.* releases should first upgrade to 1.09 -because the COPY output format was improved from the 1.02 release. - - - - - Changes - - - -Bug Fixes ---------- -packet length checking in library routines -lock manager priority patch -check for under/over flow of float8(Bruce) -multitable join fix(Vadim) -SIGPIPE crash fix(Darren) -large object fixes(Sven) -allow btree indexes to handle NULLs(Vadim) -timezone fixes(D'Arcy) -select SUM(x) can return NULL on no rows(Thomas) -internal optimizer, executor bug fixes(Vadim) -fix problem where inner loop in < or <= has no rows(Vadim) -prevent re-commuting join index clauses(Vadim) -fix join clauses for multiple tables(Vadim) -fix hash, hashjoin for arrays(Vadim) -fix btree for abstime type(Vadim) -large object fixes(Raymond) -fix buffer leak in hash indexes (Vadim) -fix rtree for use in inner scan (Vadim) -fix gist for use in inner scan, cleanups (Vadim, Andrea) -avoid unnecessary local buffers allocation (Vadim, Massimo) -fix local buffers leak in transaction aborts (Vadim) -fix file manager memory leaks, cleanups (Vadim, Massimo) -fix storage manager memory leaks (Vadim) -fix btree duplicates handling (Vadim) -fix deleted rows reincarnation caused by vacuum (Vadim) -fix SELECT varchar()/char() INTO TABLE made zero-length fields(Bruce) -many psql, pg_dump, and libpq memory leaks fixed using Purify (Igor) - -Enhancements ------------- -attribute optimization statistics(Bruce) -much faster new btree bulk load code(Paul) -BTREE UNIQUE added to bulk load code(Vadim) -new lock debug code(Massimo) -massive changes to libpg++(Leo) -new GEQO optimizer speeds table multitable optimization(Martin) -new WARN message for non-unique insert into unique key(Marc) -update x=-3, no spaces, now valid(Bruce) -remove case-sensitive identifier handling(Bruce,Thomas,Dan) -debug backend now pretty-prints tree(Darren) -new Oracle character functions(Edmund) -new plaintext password functions(Dan) -no such class or insufficient privilege changed to distinct messages(Dan) -new ANSI timestamp function(Dan) -new ANSI Time and Date types (Thomas) -move large chunks of data in backend(Martin) -multicolumn btree indexes(Vadim) -new SET var TO value command(Martin) -update transaction status on reads(Dan) -new locale settings for character types(Oleg) -new SEQUENCE serial number generator(Vadim) -GROUP BY function now possible(Vadim) -re-organize regression test(Thomas,Marc) -new optimizer operation weights(Vadim) -new psql \z grant/permit option(Marc) -new MONEY data type(D'Arcy,Thomas) -tcp socket communication speed improved(Vadim) -new VACUUM option for attribute statistics, and for certain columns (Vadim) -many geometric type improvements(Thomas,Keith) -additional regression tests(Thomas) -new datestyle variable(Thomas,Vadim,Martin) -more comparison operators for sorting types(Thomas) -new conversion functions(Thomas) -new more compact btree format(Vadim) -allow pg_dumpall to preserve database ownership(Bruce) -new SET GEQO=# and R_PLANS variable(Vadim) -old (!GEQO) optimizer can use right-sided plans (Vadim) -typechecking improvement in SQL parser(Bruce) -new SET, SHOW, RESET commands(Thomas,Vadim) -new \connect database USER option -new destroydb -i option (Igor) -new \dt and \di psql commands (Darren) -SELECT "\n" now escapes newline (A. Duursma) -new geometry conversion functions from old format (Thomas) - -Source tree changes -------------------- -new configuration script(Marc) -readline configuration option added(Marc) -OS-specific configuration options removed(Marc) -new OS-specific template files(Marc) -no more need to edit Makefile.global(Marc) -re-arrange include files(Marc) -nextstep patches (Gregor Hoffleit) -removed Windows-specific code(Bruce) -removed postmaster -e option, now only postgres -e option (Bruce) -merge duplicate library code in front/backends(Martin) -now works with eBones, international Kerberos(Jun) -more shared library support -c++ include file cleanup(Bruce) -warn about buggy flex(Bruce) -DG/UX, Ultrix, IRIX, AIX portability fixes - - - - - - -Release 6.0 - - - Release date: - 1997-01-29 - - - -A dump/restore is required for those wishing to migrate data from -previous releases of PostgreSQL. - - - -Migration from version 1.09 to version 6.0 - - -This migration requires a complete dump of the 1.09 database and a -restore of the database in 6.0. - - - - -Migration from pre-1.09 to version 6.0 - - -Those migrating from earlier 1.* releases should first upgrade to 1.09 -because the COPY output format was improved from the 1.02 release. - - - - - Changes - - - -Bug Fixes ---------- -ALTER TABLE bug - running postgres process needs to re-read table definition -Allow vacuum to be run on one table or entire database(Bruce) -Array fixes -Fix array over-runs of memory writes(Kurt) -Fix elusive btree range/non-range bug(Dan) -Fix for hash indexes on some types like time and date -Fix for pg_log size explosion -Fix permissions on lo_export()(Bruce) -Fix uninitialized reads of memory(Kurt) -Fixed ALTER TABLE ... char(3) bug(Bruce) -Fixed a few small memory leaks -Fixed EXPLAIN handling of options and changed full_path option name -Fixed output of group acl privileges -Memory leaks (hunt and destroy with tools like Purify(Kurt) -Minor improvements to rules system -NOTIFY fixes -New asserts for run-checking -Overhauled parser/analyze code to properly report errors and increase speed -Pg_dump -d now handles NULL's properly(Bruce) -Prevent SELECT NULL from crashing server (Bruce) -Properly report errors when INSERT ... SELECT columns did not match -Properly report errors when insert column names were not correct -psql \g filename now works(Bruce) -psql fixed problem with multiple statements on one line with multiple outputs -Removed duplicate system OIDs -SELECT * INTO TABLE . GROUP/ORDER BY gives unlink error if table exists(Bruce) -Several fixes for queries that crashed the backend -Starting quote in insert string errors(Bruce) -Submitting an empty query now returns empty status, not just " " query(Bruce) - -Enhancements ------------- -Add EXPLAIN manual page(Bruce) -Add UNIQUE index capability(Dan) -Add hostname/user level access control rather than just hostname and user -Add synonym of != for <>(Bruce) -Allow "select oid,* from table" -Allow BY,ORDER BY to specify columns by number, or by non-alias table.column(Bruce) -Allow COPY from the frontend(Bryan) -Allow GROUP BY to use alias column name(Bruce) -Allow actual compression, not just reuse on the same page(Vadim) -Allow installation-configuration option to auto-add all local users(Bryan) -Allow libpq to distinguish between text value '' and null(Bruce) -Allow non-postgres users with createdb privs to destroydb's -Allow restriction on who can create C functions(Bryan) -Allow restriction on who can do backend COPY(Bryan) -Can shrink tables, pg_time and pg_log(Vadim & Erich) -Change debug level 2 to print queries only, changed debug heading layout(Bruce) -Change default decimal constant representation from float4 to float8(Bruce) -European date format now set when postmaster is started -Execute lowercase function names if not found with exact case -Fixes for aggregate/GROUP processing, allow 'select sum(func(x),sum(x+y) from z' -Gist now included in the distribution(Marc) -Ident authentication of local users(Bryan) -Implement BETWEEN qualifier(Bruce) -Implement IN qualifier(Bruce) -libpq has PQgetisnull()(Bruce) -libpq++ improvements -New options to initdb(Bryan) -Pg_dump allow dump of OIDs(Bruce) -Pg_dump create indexes after tables are loaded for speed(Bruce) -Pg_dumpall dumps all databases, and the user table -Pginterface additions for NULL values(Bruce) -Prevent postmaster from being run as root -psql \h and \? is now readable(Bruce) -psql allow backslashed, semicolons anywhere on the line(Bruce) -psql changed command prompt for lines in query or in quotes(Bruce) -psql char(3) now displays as (bp)char in \d output(Bruce) -psql return code now more accurate(Bryan?) -psql updated help syntax(Bruce) -Re-visit and fix vacuum(Vadim) -Reduce size of regression diffs, remove timezone name difference(Bruce) -Remove compile-time parameters to enable binary distributions(Bryan) -Reverse meaning of HBA masks(Bryan) -Secure Authentication of local users(Bryan) -Speed up vacuum(Vadim) -Vacuum now had VERBOSE option(Bruce) - -Source tree changes -------------------- -All functions now have prototypes that are compared against the calls -Allow asserts to be disabled easily from Makefile.global(Bruce) -Change oid constants used in code to #define names -Decoupled sparc and solaris defines(Kurt) -Gcc -Wall compiles cleanly with warnings only from unfixable constructs -Major include file reorganization/reduction(Marc) -Make now stops on compile failure(Bryan) -Makefile restructuring(Bryan, Marc) -Merge bsdi_2_1 to bsdi(Bruce) -Monitor program removed -Name change from Postgres95 to PostgreSQL -New config.h file(Marc, Bryan) -PG_VERSION now set to 6.0 and used by postmaster -Portability additions, including Ultrix, DG/UX, AIX, and Solaris -Reduced the number of #define's, centralized #define's -Remove duplicate OIDS in system tables(Dan) -Remove duplicate system catalog info or report mismatches(Dan) -Removed many os-specific #define's -Restructured object file generation/location(Bryan, Marc) -Restructured port-specific file locations(Bryan, Marc) -Unused/uninitialized variables corrected - - - - - - -Release 1.09 - - - Release date: - 1996-11-04 - - - -Sorry, we didn't keep track of changes from 1.02 to 1.09. Some of -the changes listed in 6.0 were actually included in the 1.02.1 to 1.09 -releases. - - - - -Release 1.02 - - - Release date: - 1996-08-01 - - - -Migration from version 1.02 to version 1.02.1 - - -Here is a new migration file for 1.02.1. It includes the 'copy' change -and a script to convert old ASCII files. - - - -The following notes are for the benefit of users who want to migrate -databases from Postgres95 1.01 and 1.02 to Postgres95 1.02.1. - - -If you are starting afresh with Postgres95 1.02.1 and do not need -to migrate old databases, you do not need to read any further. - - - - -In order to upgrade older Postgres95 version 1.01 or 1.02 databases to -version 1.02.1, the following steps are required: - - - - -Start up a new 1.02.1 postmaster - - - - -Add the new built-in functions and operators of 1.02.1 to 1.01 or 1.02 - databases. This is done by running the new 1.02.1 server against - your own 1.01 or 1.02 database and applying the queries attached at - the end of the file. This can be done easily through psql. If your - 1.01 or 1.02 database is named testdb and you have cut the commands - from the end of this file and saved them in addfunc.sql: - -% psql testdb -f addfunc.sql - - -Those upgrading 1.02 databases will get a warning when executing the -last two statements in the file because they are already present in 1.02. This is -not a cause for concern. - - - - - - -Dump/Reload Procedure - - -If you are trying to reload a pg_dump or text-mode, copy tablename to -stdout generated with a previous version, you will need to run the -attached sed script on the ASCII file before loading it into the -database. The old format used '.' as end-of-data, while '\.' is now the -end-of-data marker. Also, empty strings are now loaded in as '' rather -than NULL. See the copy manual page for full details. - - -sed 's/^\.$/\\./g' <in_file >out_file - - - -If you are loading an older binary copy or non-stdout copy, there is no -end-of-data character, and hence no conversion necessary. - - --- following lines added by agc to reflect the case-insensitive --- regexp searching for varchar (in 1.02), and bpchar (in 1.02.1) -create operator ~* (leftarg = bpchar, rightarg = text, procedure = texticregexeq); -create operator !~* (leftarg = bpchar, rightarg = text, procedure = texticregexne); -create operator ~* (leftarg = varchar, rightarg = text, procedure = texticregexeq); -create operator !~* (leftarg = varchar, rightarg = text, procedure = texticregexne); - - - - - -Changes - - - -Source code maintenance and development - * worldwide team of volunteers - * the source tree now in CVS at ftp.ki.net - -Enhancements - * psql (and underlying libpq library) now has many more options for - formatting output, including HTML - * pg_dump now output the schema and/or the data, with many fixes to - enhance completeness. - * psql used in place of monitor in administration shell scripts. - monitor to be deprecated in next release. - * date/time functions enhanced - * NULL insert/update/comparison fixed/enhanced - * TCL/TK lib and shell fixed to work with both tck7.4/tk4.0 and tcl7.5/tk4.1 - -Bug Fixes (almost too numerous to mention) - * indexes - * storage management - * check for NULL pointer before dereferencing - * Makefile fixes - -New Ports - * added SolarisX86 port - * added BSD/OS 2.1 port - * added DG/UX port - - - - - - - -Release 1.01 - - - Release date: - 1996-02-23 - - - - -Migration from version 1.0 to version 1.01 - - -The following notes are for the benefit of users who want to migrate -databases from Postgres95 1.0 to Postgres95 1.01. - - -If you are starting afresh with Postgres95 1.01 and do not need -to migrate old databases, you do not need to read any further. - - -In order to Postgres95 version 1.01 with databases created with -Postgres95 version 1.0, the following steps are required: - - - - -Set the definition of NAMEDATALEN in src/Makefile.global to 16 - and OIDNAMELEN to 20. - - - - -Decide whether you want to use Host based authentication. - - - - -If you do, you must create a file name pg_hba in your top-level data - directory (typically the value of your $PGDATA). src/libpq/pg_hba - shows an example syntax. - - - - -If you do not want host-based authentication, you can comment out - the line: - -HBA = 1 - - in src/Makefile.global - - - Note that host-based authentication is turned on by default, and if - you do not take steps A or B above, the out-of-the-box 1.01 will - not allow you to connect to 1.0 databases. - - - - - - - -Compile and install 1.01, but DO NOT do the initdb step. - - - - -Before doing anything else, terminate your 1.0 postmaster, and - backup your existing $PGDATA directory. - - - - -Set your PGDATA environment variable to your 1.0 databases, but set up - path up so that 1.01 binaries are being used. - - - - -Modify the file $PGDATA/PG_VERSION from 5.0 to 5.1 - - - - -Start up a new 1.01 postmaster - - - - -Add the new built-in functions and operators of 1.01 to 1.0 - databases. This is done by running the new 1.01 server against - your own 1.0 database and applying the queries attached and saving - in the file 1.0_to_1.01.sql. This can be done easily through psql. - If your 1.0 database is name testdb: - - -% psql testdb -f 1.0_to_1.01.sql - - -and then execute the following commands (cut and paste from here): - - --- add builtin functions that are new to 1.01 - -create function int4eqoid (int4, oid) returns bool as 'foo' -language 'internal'; -create function oideqint4 (oid, int4) returns bool as 'foo' -language 'internal'; -create function char2icregexeq (char2, text) returns bool as 'foo' -language 'internal'; -create function char2icregexne (char2, text) returns bool as 'foo' -language 'internal'; -create function char4icregexeq (char4, text) returns bool as 'foo' -language 'internal'; -create function char4icregexne (char4, text) returns bool as 'foo' -language 'internal'; -create function char8icregexeq (char8, text) returns bool as 'foo' -language 'internal'; -create function char8icregexne (char8, text) returns bool as 'foo' -language 'internal'; -create function char16icregexeq (char16, text) returns bool as 'foo' -language 'internal'; -create function char16icregexne (char16, text) returns bool as 'foo' -language 'internal'; -create function texticregexeq (text, text) returns bool as 'foo' -language 'internal'; -create function texticregexne (text, text) returns bool as 'foo' -language 'internal'; - --- add builtin functions that are new to 1.01 - -create operator = (leftarg = int4, rightarg = oid, procedure = int4eqoid); -create operator = (leftarg = oid, rightarg = int4, procedure = oideqint4); -create operator ~* (leftarg = char2, rightarg = text, procedure = char2icregexeq); -create operator !~* (leftarg = char2, rightarg = text, procedure = char2icregexne); -create operator ~* (leftarg = char4, rightarg = text, procedure = char4icregexeq); -create operator !~* (leftarg = char4, rightarg = text, procedure = char4icregexne); -create operator ~* (leftarg = char8, rightarg = text, procedure = char8icregexeq); -create operator !~* (leftarg = char8, rightarg = text, procedure = char8icregexne); -create operator ~* (leftarg = char16, rightarg = text, procedure = char16icregexeq); -create operator !~* (leftarg = char16, rightarg = text, procedure = char16icregexne); -create operator ~* (leftarg = text, rightarg = text, procedure = texticregexeq); -create operator !~* (leftarg = text, rightarg = text, procedure = texticregexne); - - - - - - - -Changes - - - -Incompatibilities: - * 1.01 is backwards compatible with 1.0 database provided the user - follow the steps outlined in the MIGRATION_from_1.0_to_1.01 file. - If those steps are not taken, 1.01 is not compatible with 1.0 database. - -Enhancements: - * added PQdisplayTuples() to libpq and changed monitor and psql to use it - * added NeXT port (requires SysVIPC implementation) - * added CAST .. AS ... syntax - * added ASC and DESC key words - * added 'internal' as a possible language for CREATE FUNCTION - internal functions are C functions which have been statically linked - into the postgres backend. - * a new type "name" has been added for system identifiers (table names, - attribute names, etc.) This replaces the old char16 type. The - of name is set by the NAMEDATALEN #define in src/Makefile.global - * a readable reference manual that describes the query language. - * added host-based access control. A configuration file ($PGDATA/pg_hba) - is used to hold the configuration data. If host-based access control - is not desired, comment out HBA=1 in src/Makefile.global. - * changed regex handling to be uniform use of Henry Spencer's regex code - regardless of platform. The regex code is included in the distribution - * added functions and operators for case-insensitive regular expressions. - The operators are ~* and !~*. - * pg_dump uses COPY instead of SELECT loop for better performance - -Bug fixes: - * fixed an optimizer bug that was causing core dumps when - functions calls were used in comparisons in the WHERE clause - * changed all uses of getuid to geteuid so that effective uids are used - * psql now returns non-zero status on errors when using -c - * applied public patches 1-14 - - - - - - -Release 1.0 - - - Release date: - 1995-09-05 - - - -Changes - - - -Copyright change: - * The copyright of Postgres 1.0 has been loosened to be freely modifiable - and modifiable for any purpose. Please read the COPYRIGHT file. - Thanks to Professor Michael Stonebraker for making this possible. - -Incompatibilities: - * date formats have to be MM-DD-YYYY (or DD-MM-YYYY if you're using - EUROPEAN STYLE). This follows SQL-92 specs. - * "delimiters" is now a key word - -Enhancements: - * sql LIKE syntax has been added - * copy command now takes an optional USING DELIMITER specification. - delimiters can be any single-character string. - * IRIX 5.3 port has been added. - Thanks to Paul Walmsley and others. - * updated pg_dump to work with new libpq - * \d has been added psql - Thanks to Keith Parks - * regexp performance for architectures that use POSIX regex has been - improved due to caching of precompiled patterns. - Thanks to Alistair Crooks - * a new version of libpq++ - Thanks to William Wanders - -Bug fixes: - * arbitrary userids can be specified in the createuser script - * \c to connect to other databases in psql now works. - * bad pg_proc entry for float4inc() is fixed - * users with usecreatedb field set can now create databases without - having to be usesuper - * remove access control entries when the entry no longer has any - privileges - * fixed non-portable datetimes implementation - * added kerberos flags to the src/backend/Makefile - * libpq now works with kerberos - * typographic errors in the user manual have been corrected. - * btrees with multiple index never worked, now we tell you they don't - work when you try to use them - - - - - - -<productname>Postgres95</productname> Release 0.03 - - - Release date: - 1995-07-21 - - - -Changes - - -Incompatible changes: - * BETA-0.3 IS INCOMPATIBLE WITH DATABASES CREATED WITH PREVIOUS VERSIONS - (due to system catalog changes and indexing structure changes). - * double-quote (") is deprecated as a quoting character for string literals; - you need to convert them to single quotes ('). - * name of aggregates (eg. int4sum) are renamed in accordance with the - SQL standard (eg. sum). - * CHANGE ACL syntax is replaced by GRANT/REVOKE syntax. - * float literals (eg. 3.14) are now of type float4 (instead of float8 in - previous releases); you might have to do typecasting if you depend on it - being of type float8. If you neglect to do the typecasting and you assign - a float literal to a field of type float8, you might get incorrect values - stored! - * LIBPQ has been totally revamped so that frontend applications - can connect to multiple backends - * the usesysid field in pg_user has been changed from int2 to int4 to - allow wider range of Unix user ids. - * the netbsd/freebsd/bsd o/s ports have been consolidated into a - single BSD44_derived port. (thanks to Alistair Crooks) - -SQL standard-compliance (the following details changes that makes postgres95 -more compliant to the SQL-92 standard): - * the following SQL types are now built-in: smallint, int(eger), float, real, - char(N), varchar(N), date and time. - - The following are aliases to existing postgres types: - smallint -> int2 - integer, int -> int4 - float, real -> float4 - char(N) and varchar(N) are implemented as truncated text types. In - addition, char(N) does blank-padding. - * single-quote (') is used for quoting string literals; '' (in addition to - \') is supported as means of inserting a single quote in a string - * SQL standard aggregate names (MAX, MIN, AVG, SUM, COUNT) are used - (Also, aggregates can now be overloaded, i.e. you can define your - own MAX aggregate to take in a user-defined type.) - * CHANGE ACL removed. GRANT/REVOKE syntax added. - - Privileges can be given to a group using the "GROUP" key word. - For example: - GRANT SELECT ON foobar TO GROUP my_group; - The key word 'PUBLIC' is also supported to mean all users. - - Privileges can only be granted or revoked to one user or group - at a time. - - "WITH GRANT OPTION" is not supported. Only class owners can change - access control - - The default access control is to grant users readonly access. - You must explicitly grant insert/update access to users. To change - this, modify the line in - src/backend/utils/acl.h - that defines ACL_WORLD_DEFAULT - -Bug fixes: - * the bug where aggregates of empty tables were not run has been fixed. Now, - aggregates run on empty tables will return the initial conditions of the - aggregates. Thus, COUNT of an empty table will now properly return 0. - MAX/MIN of an empty table will return a row of value NULL. - * allow the use of \; inside the monitor - * the LISTEN/NOTIFY asynchronous notification mechanism now work - * NOTIFY in rule action bodies now work - * hash indexes work, and access methods in general should perform better. - creation of large btree indexes should be much faster. (thanks to Paul - Aoki) - -Other changes and enhancements: - * addition of an EXPLAIN statement used for explaining the query execution - plan (eg. "EXPLAIN SELECT * FROM EMP" prints out the execution plan for - the query). - * WARN and NOTICE messages no longer have timestamps on them. To turn on - timestamps of error messages, uncomment the line in - src/backend/utils/elog.h: - /* define ELOG_TIMESTAMPS */ - * On an access control violation, the message - "Either no such class or insufficient privilege" - will be given. This is the same message that is returned when - a class is not found. This dissuades non-privileged users from - guessing the existence of privileged classes. - * some additional system catalog changes have been made that are not - visible to the user. - -libpgtcl changes: - * The -oid option has been added to the "pg_result" tcl command. - pg_result -oid returns oid of the last row inserted. If the - last command was not an INSERT, then pg_result -oid returns "". - * the large object interface is available as pg_lo* tcl commands: - pg_lo_open, pg_lo_close, pg_lo_creat, etc. - -Portability enhancements and New Ports: - * flex/lex problems have been cleared up. Now, you should be able to use - flex instead of lex on any platforms. We no longer make assumptions of - what lexer you use based on the platform you use. - * The Linux-ELF port is now supported. Various configuration have been - tested: The following configuration is known to work: - kernel 1.2.10, gcc 2.6.3, libc 4.7.2, flex 2.5.2, bison 1.24 - with everything in ELF format, - -New utilities: - * ipcclean added to the distribution - ipcclean usually does not need to be run, but if your backend crashes - and leaves shared memory segments hanging around, ipcclean will - clean them up for you. - -New documentation: - * the user manual has been revised and libpq documentation added. - - - - - - -<productname>Postgres95</productname> Release 0.02 - - - Release date: - 1995-05-25 - - - -Changes - - - -Incompatible changes: - * The SQL statement for creating a database is 'CREATE DATABASE' instead - of 'CREATEDB'. Similarly, dropping a database is 'DROP DATABASE' instead - of 'DESTROYDB'. However, the names of the executables 'createdb' and - 'destroydb' remain the same. - -New tools: - * pgperl - a Perl (4.036) interface to Postgres95 - * pg_dump - a utility for dumping out a postgres database into a - script file containing query commands. The script files are in an ASCII - format and can be used to reconstruct the database, even on other - machines and other architectures. (Also good for converting - a Postgres 4.2 database to Postgres95 database.) - -The following ports have been incorporated into postgres95-beta-0.02: - * the NetBSD port by Alistair Crooks - * the AIX port by Mike Tung - * the Windows NT port by Jon Forrest (more stuff but not done yet) - * the Linux ELF port by Brian Gallew - -The following bugs have been fixed in postgres95-beta-0.02: - * new lines not escaped in COPY OUT and problem with COPY OUT when first - attribute is a '.' - * cannot type return to use the default user id in createuser - * SELECT DISTINCT on big tables crashes - * Linux installation problems - * monitor doesn't allow use of 'localhost' as PGHOST - * psql core dumps when doing \c or \l - * the "pgtclsh" target missing from src/bin/pgtclsh/Makefile - * libpgtcl has a hard-wired default port number - * SELECT DISTINCT INTO TABLE hangs - * CREATE TYPE doesn't accept 'variable' as the internallength - * wrong result using more than 1 aggregate in a SELECT - - - - - - -<productname>Postgres95</productname> Release 0.01 - - - Release date: - 1995-05-01 - - - -Initial release. - - diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index a815a48b8d0..706dbf4b12a 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -5,8 +5,7 @@ Typical markup: &<> use & escapes PostgreSQL -postgresql.conf, pg_hba.conf, - recovery.conf +postgresql.conf, pg_hba.conf [A-Z][A-Z_ ]+[A-Z_] , , , [A-Za-z_][A-Za-z0-9_]+() \-\-?[A-Za-z_]+[-A-Za-z_]* @@ -638,9 +671,12 @@ psql: could not connect to server: No such file or directory - Upon starting the server, PostgreSQL normally allocates + By default, PostgreSQL allocates a very small amount of System V shared memory, as well as a much larger - amount of POSIX (mmap) shared memory. + amount of anonymous mmap shared memory. + Alternatively, a single large System V shared memory region can be used + (see ). + In addition a significant number of semaphores, which can be either System V or POSIX style, are created at server startup. Currently, POSIX semaphores are used on Linux and FreeBSD systems while other @@ -717,13 +753,13 @@ psql: could not connect to server: No such file or directory SEMMNI Maximum number of semaphore identifiers (i.e., sets) - at least ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) plus room for other applications + at least ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) plus room for other applications SEMMNS Maximum number of semaphores system-wide - ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) * 17 plus room for other applications + ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16) * 17 plus room for other applications @@ -752,8 +788,10 @@ psql: could not connect to server: No such file or directory PostgreSQL requires a few bytes of System V shared memory (typically 48 bytes, on 64-bit platforms) for each copy of the server. On most modern operating systems, this amount can easily be allocated. - However, if you are running many copies of the server, or if other - applications are also using System V shared memory, it may be necessary to + However, if you are running many copies of the server or you explicitly + configure the server to use large amounts of System V shared memory (see + and ), it may be necessary to increase SHMALL, which is the total amount of System V shared memory system-wide. Note that SHMALL is measured in pages rather than bytes on many systems. @@ -780,13 +818,13 @@ psql: could not connect to server: No such file or directory other applications. The maximum number of semaphores in the system is set by SEMMNS, which consequently must be at least as high as max_connections plus - autovacuum_max_workers plus max_worker_processes, - plus one extra for each 16 + autovacuum_max_workers plus max_wal_senders, + plus max_worker_processes, plus one extra for each 16 allowed connections plus workers (see the formula in ). The parameter SEMMNI determines the limit on the number of semaphore sets that can exist on the system at one time. Hence this parameter must be at - least ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16). + least ceil((max_connections + autovacuum_max_workers + max_wal_senders + max_worker_processes + 5) / 16). Lowering the number of allowed connections is a temporary workaround for failures, which are usually confusingly worded No space @@ -796,7 +834,8 @@ psql: could not connect to server: No such file or directory In some cases it might also be necessary to increase SEMMAP to be at least on the order of - SEMMNS. This parameter defines the size of the semaphore + SEMMNS. If the system has this parameter + (many do not), it defines the size of the semaphore resource map, in which each contiguous block of available semaphores needs an entry. When a semaphore set is freed it is either added to an existing entry that is adjacent to the freed block or it is @@ -853,7 +892,7 @@ psql: could not connect to server: No such file or directory - The default settings can be changed using + The default IPC settings can be changed using the sysctl or loader interfaces. The following parameters can be set using sysctl: @@ -872,17 +911,13 @@ psql: could not connect to server: No such file or directory kern.ipc.semmni=256 kern.ipc.semmns=512 -kern.ipc.semmnu=256 - After modifying these values a reboot is required for the new + After modifying that file, a reboot is required for the new settings to take effect. - (Note: FreeBSD does not use SEMMAP. Older versions - would accept but ignore a setting for kern.ipc.semmap; - newer versions reject it altogether.) - You might also want to configure your kernel to lock shared + You might also want to configure your kernel to lock System V shared memory into RAM and prevent it from being paged out to swap. This can be accomplished using the sysctl setting kern.ipc.shm_use_phys. @@ -902,7 +937,7 @@ kern.ipc.semmnu=256 FreeBSD versions before 4.0 work like - OpenBSD (see below). + old OpenBSD (see below). @@ -917,24 +952,31 @@ kern.ipc.semmnu=256 IPC parameters can be adjusted using sysctl, for example: -$ sysctl -w kern.ipc.shmmax=16777216 +# sysctl -w kern.ipc.semmni=100 - To have these settings persist over reboots, modify + To make these settings persist over reboots, modify /etc/sysctl.conf. - You might also want to configure your kernel to lock shared + You will usually want to increase kern.ipc.semmni + and kern.ipc.semmns, + as NetBSD's default settings + for these are uncomfortably small. + + + + You might also want to configure your kernel to lock System V shared memory into RAM and prevent it from being paged out to swap. This can be accomplished using the sysctl setting kern.ipc.shm_use_phys. - NetBSD versions before 5.0 work like - OpenBSD (see below), except that - parameters should be set with the keyword options not - option. + NetBSD versions before 5.0 + work like old OpenBSD + (see below), except that kernel parameters should be set with the + keyword options not option. @@ -945,11 +987,31 @@ kern.ipc.semmnu=256 - The options SYSVSHM and SYSVSEM need - to be enabled when the kernel is compiled. (They are by - default.) The maximum size of shared memory is determined by - the option SHMMAXPGS (in pages). The following - shows an example of how to set the various parameters: + In OpenBSD 3.3 and later, + IPC parameters can be adjusted using sysctl, + for example: + +# sysctl kern.seminfo.semmni=100 + + To make these settings persist over reboots, modify + /etc/sysctl.conf. + + + + You will usually want to + increase kern.seminfo.semmni + and kern.seminfo.semmns, + as OpenBSD's default settings + for these are uncomfortably small. + + + + In older OpenBSD versions, + you will need to build a custom kernel to change the IPC parameters. + Make sure that the options SYSVSHM + and SYSVSEM are enabled, too. (They are by + default.) The following shows an example of how to set the various + parameters in the kernel configuration file: option SYSVSHM option SHMMAXPGS=4096 @@ -959,16 +1021,9 @@ option SYSVSEM option SEMMNI=256 option SEMMNS=512 option SEMMNU=256 -option SEMMAP=256 - - You might also want to configure your kernel to lock shared - memory into RAM and prevent it from being paged out to swap. - This can be accomplished using the sysctl - setting kern.ipc.shm_use_phys. - @@ -1407,7 +1462,7 @@ Out of Memory: Killed process 12345 (postgres). On Linux 2.6 and later, it is possible to modify the kernel's behavior so that it will not overcommit memory. Although this setting will not prevent the OOM killer from being invoked + url="https://lwn.net/Articles/104179/">OOM killer from being invoked altogether, it will lower the chances significantly and will therefore lead to more robust system behavior. This is done by selecting strict overcommit mode via sysctl: @@ -1630,14 +1685,12 @@ $ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid` - It is best not to use SIGKILL to shut down - the server. Doing so will prevent the server from releasing - shared memory and semaphores, which might then have to be done - manually before a new server can be started. Furthermore, - SIGKILL kills the postgres - process without letting it relay the signal to its subprocesses, - so it will be necessary to kill the individual subprocesses by hand as - well. + It is best not to use SIGKILL to shut down the + server. Doing so will prevent the server from releasing shared memory and + semaphores. Furthermore, SIGKILL kills + the postgres process without letting it relay the + signal to its subprocesses, so it might be necessary to kill the + individual subprocesses by hand as well. @@ -1953,9 +2006,9 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 Upgrading Data via Replication - It is also possible to use certain replication methods, such as - Slony, to create a standby server with the updated version of - PostgreSQL. This is possible because Slony supports + It is also possible to use logical replication methods to create a standby + server with the updated version of PostgreSQL. + This is possible because logical replication supports replication between different major versions of PostgreSQL. The standby can be on the same computer or a different computer. Once it has synced up with the master server @@ -1965,6 +2018,13 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 of downtime for an upgrade. + + This method of upgrading can be performed using the built-in logical + replication facilities as well as using external logical replication + systems such as pglogical, + Slony, Londiste, and + Bucardo. + @@ -2008,9 +2068,13 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 - To prevent spoofing on TCP connections, the best solution is to use - SSL certificates and make sure that clients check the server's certificate. - To do that, the server + To prevent spoofing on TCP connections, either use + SSL certificates and make sure that clients check the server's certificate, + or use GSSAPI encryption (or both, if they're on separate connections). + + + + To prevent spoofing with SSL, the server must be configured to accept only hostssl connections () and have SSL key and certificate files (). The TCP client must connect using @@ -2018,6 +2082,14 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 verify-full and have the appropriate root certificate file installed (). + + + To prevent spoofing with GSSAPI, the server must be configured to accept + only hostgssenc connections + () and use gss + authentication with them. The TCP client must connect + using gssencmode=require. + @@ -2114,8 +2186,24 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 which hosts can use non-encrypted connections (host) and which require SSL-encrypted connections (hostssl). Also, clients can specify that they - connect to servers only via SSL. Stunnel or - SSH can also be used to encrypt transmissions. + connect to servers only via SSL. + + + + GSSAPI-encrypted connections encrypt all data sent across the network, + including queries and data returned. (No password is sent across the + network.) The pg_hba.conf file allows + administrators to specify which hosts can use non-encrypted connections + (host) and which require GSSAPI-encrypted connections + (hostgssenc). Also, clients can specify that they + connect to servers only on GSSAPI-encrypted connections + (gssencmode=require). + + + + Stunnel or + SSH can also be used to encrypt + transmissions. @@ -2287,13 +2375,25 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 (CAs) you trust in a file in the data directory, set the parameter in postgresql.conf to the new file name, and add the - authentication option clientcert=1 to the appropriate + authentication option clientcert=verify-ca or + clientcert=verify-full to the appropriate hostssl line(s) in pg_hba.conf. A certificate will then be requested from the client during SSL connection startup. (See for a description - of how to set up certificates on the client.) The server will - verify that the client's certificate is signed by one of the trusted - certificate authorities. + of how to set up certificates on the client.) + + + + For a hostssl entry with + clientcert=verify-ca, the server will verify + that the client's certificate is signed by one of the trusted + certificate authorities. If clientcert=verify-full + is specified, the server will not only verify the certificate + chain, but it will also check whether the username or its mapping + matches the cn (Common Name) of the provided certificate. + Note that certificate chain validation is always ensured when the + cert authentication method is used + (see ). @@ -2303,9 +2403,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 intermediate certificates were created with v3_ca extensions). Certificate Revocation List (CRL) entries are also checked if the parameter is set. - (See + url="http://h41379.www4.hpe.com/doc/83final/ba554_90007/ch04s02.html"> for diagrams showing SSL certificate usage.) @@ -2313,18 +2412,34 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 The clientcert authentication option is available for all authentication methods, but only in pg_hba.conf lines specified as hostssl. When clientcert is - not specified or is set to 0, the server will still verify any presented - client certificates against its CA file, if one is configured — but - it will not insist that a client certificate be presented. + not specified or is set to no-verify, the server will still + verify any presented client certificates against its CA file, if one is + configured — but it will not insist that a client certificate be presented. - If you are setting up client certificates, you may wish to use - the cert authentication method, so that the certificates - control user authentication as well as providing connection security. - See for details. (It is not necessary to - specify clientcert=1 explicitly when using - the cert authentication method.) + There are two approaches to enforce that users provide a certificate during login. + + + + The first approach makes use of the cert authentication + method for hostssl entries in pg_hba.conf, + such that the certificate itself is used for authentication while also + providing ssl connection security. See for details. + (It is not necessary to specify any clientcert options + explicitly when using the cert authentication method.) + In this case, the cn (Common Name) provided in + the certificate is checked against the user name or an applicable mapping. + + + + The second approach combines any authentication method for hostssl + entries with the verification of client certificates by setting the + clientcert authentication option to verify-ca + or verify-full. The former option only enforces that + the certificate is valid, while the latter also ensures that the + cn (Common Name) in the certificate matches + the user name or an applicable mapping. @@ -2457,7 +2572,7 @@ openssl x509 -req -in server.csr -text -days 365 \ server.crt and server.key should be stored on the server, and root.crt should be stored on the client so the client can verify that the server's leaf - certificate was signed by its trusted root certificate. + certificate was signed by its trusted root certificate. root.key should be stored offline for use in creating future certificates. @@ -2505,6 +2620,45 @@ openssl x509 -req -in server.csr -text -days 365 \ + + Secure TCP/IP Connections with GSSAPI Encryption + + + gssapi + + + + PostgreSQL also has native support for + using GSSAPI to encrypt client/server communications for + increased security. Support requires that a GSSAPI + implementation (such as MIT krb5) is installed on both client and server + systems, and that support in PostgreSQL is + enabled at build time (see ). + + + + Basic Setup + + + The PostgreSQL server will listen for both + normal and GSSAPI-encrypted connections on the same TCP + port, and will negotiate with any connecting client on whether to + use GSSAPI for encryption (and for authentication). By + default, this decision is up to the client (which means it can be + downgraded by an attacker); see about + setting up the server to require the use of GSSAPI for + some or all connections. + + + + Other than configuration of the negotiation + behavior, GSSAPI encryption requires no setup beyond + that which is necessary for GSSAPI authentication. (For more information + on configuring that, see .) + + + + Secure TCP/IP Connections with <application>SSH</application> Tunnels diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml index f8c99e1b002..658599306a5 100644 --- a/doc/src/sgml/sepgsql.sgml +++ b/doc/src/sgml/sepgsql.sgml @@ -175,6 +175,9 @@ $ for DBNAME in template0 template1 postgres; do make with a Makefile supplied by SELinux. You will need to locate the appropriate Makefile on your system; the path shown below is only an example. + (This Makefile is usually supplied by the + selinux-policy-devel or + selinux-policy RPM.) Once built, install this policy package using the semodule command, which loads supplied policy packages into the kernel. If the package is correctly installed, diff --git a/doc/src/sgml/sourcerepo.sgml b/doc/src/sgml/sourcerepo.sgml index aaeacb14c56..0ed7f8a3fea 100644 --- a/doc/src/sgml/sourcerepo.sgml +++ b/doc/src/sgml/sourcerepo.sgml @@ -26,7 +26,7 @@ - Getting The Source via <productname>Git</productname> + Getting the Source via <productname>Git</productname> With Git you will make a copy of the entire code repository diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index 8870ee938aa..25e7763c7c7 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -26,9 +26,9 @@ - Do not use C++ style comments (// comments). Strict ANSI C - compilers do not accept them. For the same reason, do not use C++ - extensions such as declaring new variables mid-block. + To maintain a consistent coding style, do not use C++ style comments + (// comments). pgindent + will replace them with /* ... */. @@ -709,8 +709,8 @@ BETTER: could not open file %s (I/O failure) not helpful information. If the error text doesn't make as much sense without the function name, reword it. -BAD: pg_atoi: error in "z": cannot parse "z" -BETTER: invalid input syntax for integer: "z" +BAD: pg_strtoint32: error in "z": cannot parse "z" +BETTER: invalid input syntax for type integer: "z" @@ -867,19 +867,30 @@ BETTER: unrecognized node type: 42 C Standard Code in PostgreSQL should only rely on language - features available in the C89 standard. That means a conforming - C89 compiler has to be able to compile postgres, at least aside - from a few platform dependent pieces. Features from later - revision of the C standard or compiler specific features can be - used, if a fallback is provided. - - - For example static inline and - _StaticAssert() are currently used, even - though they are from newer revisions of the C standard. If not - available we respectively fall back to defining the functions - without inline, and to using a C89 compatible replacement that - performs the same checks, but emits rather cryptic messages. + features available in the C99 standard. That means a conforming + C99 compiler has to be able to compile postgres, at least aside + from a few platform dependent pieces. + + + A few features included in the C99 standard are, at this time, not + permitted to be used in core PostgreSQL + code. This currently includes variable length arrays, intermingled + declarations and code, // comments, universal + character names. Reasons for that include portability and historical + practices. + + + Features from later revision of the C standard or compiler specific + features can be used, if a fallback is provided. + + + For example _Static_assert() and + __builtin_constant_p are currently used, even though + they are from newer revisions of the C standard and a + GCC extension respectively. If not available + we respectively fall back to using a C99 compatible replacement that + performs the same checks, but emits rather cryptic messages and do not + use __builtin_constant_p. diff --git a/doc/src/sgml/spgist.sgml b/doc/src/sgml/spgist.sgml index 06b75190522..0e04a086793 100644 --- a/doc/src/sgml/spgist.sgml +++ b/doc/src/sgml/spgist.sgml @@ -43,7 +43,7 @@ Some of the information here is derived from Purdue University's SP-GiST Indexing Project - web site. + web site. The SP-GiST implementation in PostgreSQL is primarily maintained by Teodor Sigaev and Oleg Bartunov, and there is more information on their @@ -64,12 +64,13 @@
Built-in <acronym>SP-GiST</acronym> Operator Classes - + Name Indexed Data Type Indexable Operators + Ordering Operators @@ -84,6 +85,9 @@ >^~= + + <-> + quad_point_ops @@ -96,6 +100,9 @@ >^ ~= + + <-> + range_ops @@ -111,6 +118,8 @@ >> @> + + box_ops @@ -129,6 +138,9 @@ |>> |&> + + <-> + poly_ops @@ -147,6 +159,9 @@ |>> |&> + + <-> + text_ops @@ -163,6 +178,8 @@ ~>~ ^@ + + inet_ops @@ -180,6 +197,8 @@ <= = + + @@ -188,9 +207,15 @@ Of the two operator classes for type point, quad_point_ops is the default. kd_point_ops - supports the same operators but uses a different index data structure which + supports the same operators but uses a different index data structure that may offer better performance in some applications. + + The quad_point_ops, kd_point_ops and + poly_ops operator classes support the <-> + ordering operator, which enables the k-nearest neighbor (k-NN) + search over indexed point or polygon data sets. + @@ -268,9 +293,9 @@ leaf_consistent additionally returns a boolean result. The methods must not modify any fields of their input structs. In all cases, the output struct is initialized to zeroes before calling the - user-defined method. Optional sixth method compress - accepts datum to be indexed as the only argument and returns value suitable - for physical storage in leaf tuple. + user-defined method. The optional sixth method compress + accepts datum to be indexed as the only argument and returns a value suitable + for physical storage in a leaf tuple. @@ -423,9 +448,9 @@ typedef struct spgChooseOut type that was to be inserted into the index. leafDatum is a value of spgConfigOut.leafType - type which is initially an result of method + type, which is initially a result of method compress applied to datum - when method compress is provided, or same value as + when method compress is provided, or the same value as datum otherwise. leafDatum can change at lower levels of the tree if the choose or picksplit @@ -630,7 +655,10 @@ CREATE FUNCTION my_inner_consistent(internal, internal) RETURNS void ... typedef struct spgInnerConsistentIn { ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ Datum reconstructedValue; /* value reconstructed at parent */ void *traversalValue; /* opclass-specific traverse value */ @@ -653,6 +681,7 @@ typedef struct spgInnerConsistentOut int *levelAdds; /* increment level by this much for each */ Datum *reconstructedValues; /* associated reconstructed values */ void **traversalValues; /* opclass-specific traverse values */ + double **distances; /* associated distances */ } spgInnerConsistentOut; @@ -667,6 +696,8 @@ typedef struct spgInnerConsistentOut In particular it is not necessary to check sk_flags to see if the comparison value is NULL, because the SP-GiST core code will filter out such conditions. + The array orderbys, of length norderbys, + describes ordering operators (if any) in the same manner. reconstructedValue is the value reconstructed for the parent tuple; it is (Datum) 0 at the root level or if the inner_consistent function did not provide a value at the @@ -709,6 +740,10 @@ typedef struct spgInnerConsistentOut of spgConfigOut.leafType type reconstructed for each child node to be visited; otherwise, leave reconstructedValues as NULL. + If ordered search is performed, set distances + to an array of distance values according to orderbys + array (nodes with lowest distances will be processed first). Leave it + NULL otherwise. If it is desired to pass down additional out-of-band information (traverse values) to lower levels of the tree search, set traversalValues to an array of the appropriate @@ -717,6 +752,7 @@ typedef struct spgInnerConsistentOut Note that the inner_consistent function is responsible for palloc'ing the nodeNumbers, levelAdds, + distances, reconstructedValues, and traversalValues arrays in the current memory context. However, any output traverse values pointed to by @@ -747,7 +783,10 @@ CREATE FUNCTION my_leaf_consistent(internal, internal) RETURNS bool ... typedef struct spgLeafConsistentIn { ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ Datum reconstructedValue; /* value reconstructed at parent */ void *traversalValue; /* opclass-specific traverse value */ @@ -759,8 +798,10 @@ typedef struct spgLeafConsistentIn typedef struct spgLeafConsistentOut { - Datum leafValue; /* reconstructed original data, if any */ - bool recheck; /* set true if operator must be rechecked */ + Datum leafValue; /* reconstructed original data, if any */ + bool recheck; /* set true if operator must be rechecked */ + bool recheckDistances; /* set true if distances must be rechecked */ + double *distances; /* associated distances */ } spgLeafConsistentOut; @@ -775,11 +816,13 @@ typedef struct spgLeafConsistentOut In particular it is not necessary to check sk_flags to see if the comparison value is NULL, because the SP-GiST core code will filter out such conditions. + The array orderbys, of length norderbys, + describes the ordering operators in the same manner. reconstructedValue is the value reconstructed for the parent tuple; it is (Datum) 0 at the root level or if the inner_consistent function did not provide a value at the parent level. reconstructedValue is always of - spgConfigOut.leafType type. + spgConfigOut.leafType type. traversalValue is a pointer to any traverse data passed down from the previous call of inner_consistent on the parent index tuple, or NULL at the root level. @@ -803,6 +846,12 @@ typedef struct spgLeafConsistentOut recheck may be set to true if the match is uncertain and so the operator(s) must be re-applied to the actual heap tuple to verify the match. + If ordered search is performed, set distances + to an array of distance values according to orderbys + array. Leave it NULL otherwise. If at least one of returned distances + is not exact, set recheckDistances to true. + In this case, the executor will calculate the exact distances after + fetching the tuple from the heap, and will reorder the tuples if needed. @@ -817,10 +866,10 @@ typedef struct spgLeafConsistentOut Datum compress(Datum in) - Converts the data item into a format suitable for physical storage in + Converts the data item into a format suitable for physical storage in a leaf tuple of index page. It accepts spgConfigIn.attType - value and return + value and returns spgConfigOut.leafType value. Output value should not be toasted. @@ -920,7 +969,7 @@ typedef struct spgLeafConsistentOut - <quote>All-the-same</quote> Inner Tuples + <quote>All-the-Same</quote> Inner Tuples The SP-GiST core can override the results of the diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 0bac3423224..9e37fc3a14e 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -21,23 +21,16 @@ The available procedural languages provide various means to - execute SQL commands from procedures. Most of these facilities are + execute SQL commands from functions. Most of these facilities are based on SPI, so this documentation might be of use for users of those languages as well. - - To avoid misunderstanding we'll use the term function - when we speak of SPI interface functions and - procedure for a user-defined C-function that is - using SPI. - - Note that if a command invoked via SPI fails, then control will not be - returned to your procedure. Rather, the - transaction or subtransaction in which your procedure executes will be + returned to your C function. Rather, the + transaction or subtransaction in which your C function executes will be rolled back. (This might seem surprising given that the SPI functions mostly have documented error-return conventions. Those conventions only apply for errors detected within the SPI functions themselves, however.) @@ -73,7 +66,7 @@ SPI_connect SPI_connect_ext - connect a procedure to the SPI manager + connect a C function to the SPI manager @@ -91,9 +84,9 @@ int SPI_connect_ext(int options) SPI_connect opens a connection from a - procedure invocation to the SPI manager. You must call this + C function invocation to the SPI manager. You must call this function if you want to execute commands through SPI. Some utility - SPI functions can be called from unconnected procedures. + SPI functions can be called from unconnected C functions. @@ -159,7 +152,7 @@ int SPI_connect_ext(int options) SPI_finish - disconnect a procedure from the SPI manager + disconnect a C function from the SPI manager @@ -174,7 +167,7 @@ int SPI_finish(void) SPI_finish closes an existing connection to the SPI manager. You must call this function after completing the - SPI operations needed during your procedure's current invocation. + SPI operations needed during your C function's current invocation. You do not need to worry about making this happen, however, if you abort the transaction via elog(ERROR). In that case SPI will clean itself up automatically. @@ -198,7 +191,7 @@ int SPI_finish(void) SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -238,7 +231,7 @@ int SPI_execute(const char * command, bool rea - This function can only be called from a connected procedure. + This function can only be called from a connected C function. @@ -325,27 +318,36 @@ SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); The structure SPITupleTable is defined thus: -typedef struct +typedef struct SPITupleTable { + /* Public members */ + TupleDesc tupdesc; /* tuple descriptor */ + HeapTuple *vals; /* array of tuples */ + uint64 numvals; /* number of valid tuples */ + + /* Private members, not intended for external callers */ + uint64 alloced; /* allocated length of vals array */ MemoryContext tuptabcxt; /* memory context of result table */ - uint64 alloced; /* number of alloced vals */ - uint64 free; /* number of free vals */ - TupleDesc tupdesc; /* row descriptor */ - HeapTuple *vals; /* rows */ + slist_node next; /* link for internal bookkeeping */ + SubTransactionId subid; /* subxact in which tuptable was created */ } SPITupleTable; - vals is an array of pointers to rows. (The number - of valid entries is given by SPI_processed.) + tupdesc, + vals, and + numvals + can be used by SPI callers; the remaining fields are internal. + vals is an array of pointers to rows. + The number of rows is given by numvals + (for somewhat historical reasons, this count is also returned + in SPI_processed). tupdesc is a row descriptor which you can pass to - SPI functions dealing with rows. tuptabcxt, - alloced, and free are internal - fields not intended for use by SPI callers. + SPI functions dealing with rows. SPI_finish frees all SPITupleTables allocated during the current - procedure. You can free a particular result table earlier, if you + C function. You can free a particular result table earlier, if you are done with it, by calling SPI_freetuptable. @@ -539,7 +541,7 @@ typedef struct SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -555,7 +557,7 @@ typedef struct SPI_processed and SPI_tuptable (just the pointer, not the contents of the structure). Save these two global variables into local - procedure variables if you need to access the result table of + C function variables if you need to access the result table of SPI_execute or another query-execution function across later calls. @@ -835,7 +837,7 @@ SPIPlanPtr SPI_prepare(const char * command, int The statement returned by SPI_prepare can be used - only in the current invocation of the procedure, since + only in the current invocation of the C function, since SPI_finish frees memory allocated for such a statement. But the statement can be saved for longer using the functions SPI_keepplan or SPI_saveplan. @@ -926,7 +928,7 @@ SPIPlanPtr SPI_prepare(const char * command, int - This function should only be called from a connected procedure. + This function should only be called from a connected C function. @@ -1702,9 +1704,9 @@ Portal SPI_cursor_open(const char * name, SPIPlanPtr @@ -2534,7 +2536,7 @@ int SPI_keepplan(SPIPlanPtr plan) SPI_prepare) so that it will not be freed by SPI_finish nor by the transaction manager. This gives you the ability to reuse prepared statements in the subsequent - invocations of your procedure in the current session. + invocations of your C function in the current session. @@ -2604,7 +2606,7 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) by SPI_finish nor by the transaction manager, and returns a pointer to the copied statement. This gives you the ability to reuse prepared statements in the subsequent invocations of - your procedure in the current session. + your C function in the current session. @@ -2644,7 +2646,7 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -2686,7 +2688,7 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr plan) SPI_register_relation - make a ephemeral named relation available by name in SPI queries + make an ephemeral named relation available by name in SPI queries @@ -2757,7 +2759,7 @@ int SPI_register_relation(EphemeralNamedRelation enr) SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -2862,7 +2864,7 @@ int SPI_unregister_relation(const char * name) SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -2977,7 +2979,7 @@ int SPI_register_trigger_data(TriggerData *tdata) SPI_ERROR_UNCONNECTED - if called from an unconnected procedure + if called from an unconnected C function @@ -3011,7 +3013,7 @@ int SPI_register_trigger_data(TriggerData *tdata) All functions described in this section can be used by both - connected and unconnected procedures. + connected and unconnected C functions. @@ -3112,7 +3114,7 @@ int SPI_fnumber(TupleDesc rowdesc, const char * If colname refers to a system column (e.g., - oid) then the appropriate negative column number will + ctid) then the appropriate negative column number will be returned. The caller should be careful to test the return value for exact equality to SPI_ERROR_NOATTRIBUTE to detect an error; testing the result for less than or equal to 0 is @@ -3655,37 +3657,37 @@ const char * SPI_result_code_string(int code); makes it current. SPI_finish restores the previous current memory context and destroys the context created by SPI_connect. These actions ensure that - transient memory allocations made inside your procedure are - reclaimed at procedure exit, avoiding memory leakage. + transient memory allocations made inside your C function are + reclaimed at C function exit, avoiding memory leakage. - However, if your procedure needs to return an object in allocated + However, if your C function needs to return an object in allocated memory (such as a value of a pass-by-reference data type), you cannot allocate that memory using palloc, at least not while you are connected to SPI. If you try, the object will be deallocated by SPI_finish, and your - procedure will not work reliably. To solve this problem, use + C function will not work reliably. To solve this problem, use SPI_palloc to allocate memory for your return object. SPI_palloc allocates memory in the upper executor context, that is, the memory context that was current when SPI_connect was called, which is precisely the right context for a value returned from your - procedure. Several of the other utility procedures described in + C function. Several of the other utility functions described in this section also return objects created in the upper executor context. When SPI_connect is called, the private - context of the procedure, which is created by + context of the C function, which is created by SPI_connect, is made the current context. All allocations made by palloc, repalloc, or SPI utility functions (except as described in this section) are made in this context. When a - procedure disconnects from the SPI manager (via + C function disconnects from the SPI manager (via SPI_finish) the current context is restored to the upper executor context, and all allocations made in the - procedure memory context are freed and cannot be used any more. + C function memory context are freed and cannot be used any more. @@ -4263,12 +4265,12 @@ void SPI_freetuptable(SPITupleTable * tuptable) - This function is useful if a SPI procedure needs to execute + This function is useful if an SPI-using C function needs to execute multiple commands and does not want to keep the results of earlier commands around until it ends. Note that any unfreed row sets will be freed anyway at SPI_finish. Also, if a subtransaction is started and then aborted within execution - of a SPI procedure, SPI automatically frees any row sets created while + of an SPI-using C function, SPI automatically frees any row sets created while the subtransaction was running. @@ -4373,9 +4375,9 @@ int SPI_freeplan(SPIPlanPtr plan) is part of some SQL command will probably result in obscure internal errors or crashes. The interface functions presented here are primarily intended to be used by procedural language implementations to support transaction - management in procedures that are invoked by the CALL + management in SQL-level procedures that are invoked by the CALL command, taking the context of the CALL invocation into - account. SPI procedures implemented in C can implement the same logic, but + account. SPI-using procedures implemented in C can implement the same logic, but the details of that are beyond the scope of this documentation. @@ -4383,6 +4385,7 @@ int SPI_freeplan(SPIPlanPtr plan) SPI_commit + SPI_commit_and_chain SPI_commit @@ -4391,12 +4394,17 @@ int SPI_freeplan(SPIPlanPtr plan) SPI_commit + SPI_commit_and_chain commit the current transaction void SPI_commit(void) + + + +void SPI_commit_and_chain(void) @@ -4413,7 +4421,14 @@ void SPI_commit(void) - This function can only be executed if the SPI connection has been set as + SPI_commit_and_chain is the same, but a new + transaction is immediately started with the same transaction + characteristics as the just finished one, like with the SQL command + COMMIT AND CHAIN. + + + + These functions can only be executed if the SPI connection has been set as nonatomic in the call to SPI_connect_ext. @@ -4423,6 +4438,7 @@ void SPI_commit(void) SPI_rollback + SPI_rollback_and_chain SPI_rollback @@ -4431,12 +4447,17 @@ void SPI_commit(void) SPI_rollback + SPI_rollback_and_chain abort the current transaction void SPI_rollback(void) + + + +void SPI_rollback_and_chain(void) @@ -4451,9 +4472,15 @@ void SPI_rollback(void) using SPI_start_transaction before further database actions can be executed. + + SPI_rollback_and_chain is the same, but a new + transaction is immediately started with the same transaction + characteristics as the just finished one, like with the SQL command + ROLLBACK AND CHAIN. + - This function can only be executed if the SPI connection has been set as + These functions can only be executed if the SPI connection has been set as nonatomic in the call to SPI_connect_ext. @@ -4487,7 +4514,7 @@ void SPI_start_transaction(void) SPI_start_transaction starts a new transaction. It can only be called after SPI_commit or SPI_rollback, as there is no transaction active at - that point. Normally, when an SPI procedure is called, there is already a + that point. Normally, when an SPI-using procedure is called, there is already a transaction active, so attempting to start another one before closing out the current one will result in an error. @@ -4566,7 +4593,7 @@ INSERT INTO a SELECT * FROM a; This section contains a very simple example of SPI usage. The - procedure execq takes an SQL command as its + C function execq takes an SQL command as its first argument and a row count as its second, executes the command using SPI_exec and returns the number of rows that were processed by the command. You can find more complex @@ -4583,40 +4610,43 @@ INSERT INTO a SELECT * FROM a; PG_MODULE_MAGIC; -int64 execq(text *sql, int cnt); +PG_FUNCTION_INFO_V1(execq); -int64 -execq(text *sql, int cnt) +Datum +execq(PG_FUNCTION_ARGS) { char *command; + int cnt; int ret; uint64 proc; /* Convert given text object to a C string */ - command = text_to_cstring(sql); + command = text_to_cstring(PG_GETARG_TEXT_PP(0)); + cnt = PG_GETARG_INT32(1); SPI_connect(); ret = SPI_exec(command, cnt); proc = SPI_processed; + /* * If some rows were fetched, print them via elog(INFO). */ if (ret > 0 && SPI_tuptable != NULL) { - TupleDesc tupdesc = SPI_tuptable->tupdesc; SPITupleTable *tuptable = SPI_tuptable; + TupleDesc tupdesc = tuptable->tupdesc; char buf[8192]; uint64 j; - for (j = 0; j < proc; j++) + for (j = 0; j < tuptable->numvals; j++) { HeapTuple tuple = tuptable->vals[j]; int i; for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++) - snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s", + snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s", SPI_getvalue(tuple, tupdesc, i), (i == tupdesc->natts) ? " " : " |"); elog(INFO, "EXECQ: %s", buf); @@ -4626,16 +4656,10 @@ execq(text *sql, int cnt) SPI_finish(); pfree(command); - return proc; + PG_RETURN_INT64(proc); } - - (This function uses call convention version 0, to make the example - easier to understand. In real applications you should use the new - version 1 interface.) - - This is how you declare the function after having compiled it into a shared library (details are in .): diff --git a/doc/src/sgml/sslinfo.sgml b/doc/src/sgml/sslinfo.sgml index cda09aaafd2..78ff83d6422 100644 --- a/doc/src/sgml/sslinfo.sgml +++ b/doc/src/sgml/sslinfo.sgml @@ -14,6 +14,11 @@ will return NULL) if the current connection does not use SSL. + + Some of the information available through this module can also be obtained + using the built-in system view . + + This extension won't build at all unless the installation was configured with --with-openssl. @@ -180,7 +185,7 @@ countryName (alias C) localityName (alias L) stateOrProvinceName (alias ST) organizationName (alias O) -organizationUnitName (alias OU) +organizationalUnitName (alias OU) title description initials diff --git a/doc/src/sgml/standalone-install.xml b/doc/src/sgml/standalone-install.xml index 62582effed2..5cb3bb33274 100644 --- a/doc/src/sgml/standalone-install.xml +++ b/doc/src/sgml/standalone-install.xml @@ -1,5 +1,5 @@ - + This document describes the installation of PostgreSQL using this source code distribution. + + If you are building PostgreSQL for Microsoft + Windows, read this document if you intend to build with MinGW or Cygwin; + but if you intend to build with Microsoft's Visual + C++, see the main documentation instead. + + @@ -77,25 +85,21 @@ postgres$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/datainitdb step should have told you how to start up the database server. Do so now. The command should look something like: -/usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data - This will start the server in the foreground. To put the server - in the background use something like: -nohup /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data \ - </dev/null >>server.log 2>&1 </dev/null & +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data start To stop a server running in the background you can type: -kill `cat /usr/local/pgsql/data/postmaster.pid` +/usr/local/pgsql/bin/pg_ctl -D /usr/local/pgsql/data stop Create a database: -createdb testdb +/usr/local/pgsql/bin/createdb testdb Then enter: -psql testdb +/usr/local/pgsql/bin/psql testdb to connect to that database. At the prompt you can enter SQL commands and start experimenting. diff --git a/doc/src/sgml/standalone-profile.xsl b/doc/src/sgml/standalone-profile.xsl index ff464c16545..1817d1579ff 100644 --- a/doc/src/sgml/standalone-profile.xsl +++ b/doc/src/sgml/standalone-profile.xsl @@ -16,8 +16,8 @@ variant without links and references to the main documentation. --> + doctype-public="-//OASIS//DTD DocBook XML V4.5//EN" + doctype-system="http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"/> diff --git a/doc/src/sgml/storage.sgml b/doc/src/sgml/storage.sgml index 70a822e0597..1c19e863d2a 100644 --- a/doc/src/sgml/storage.sgml +++ b/doc/src/sgml/storage.sgml @@ -188,6 +188,14 @@ for the database's files; in particular, its system catalogs are stored there. + + Note that the following sections describe the behavior of the builtin + heap table access method, + and the builtin index access methods. Due + to the extensible nature of PostgreSQL, other + access methods might work differently. + + Each table and index is stored in a separate file. For ordinary relations, these files are named after the table or index's filenode number, @@ -374,7 +382,7 @@ The oldest and most common type is a pointer to out-of-line data stored in a TOAST table that is separate from, but associated with, the table containing the TOAST pointer datum itself. These on-disk pointer datums are created by the -TOAST management code (in access/heap/tuptoaster.c) +TOAST management code (in access/common/toast_internals.c) when a tuple to be stored on disk is too large to be stored as-is. Further details appear in . Alternatively, a TOAST pointer datum can contain a pointer to @@ -392,7 +400,7 @@ of the LZ family of compression techniques. See - Out-of-line, on-disk TOAST storage + Out-of-Line, On-Disk TOAST Storage If any of the columns of a table are TOAST-able, the table will @@ -508,7 +516,7 @@ comparison table, in which all the HTML pages were cut down to 7 kB to fit. - Out-of-line, in-memory TOAST storage + Out-of-Line, In-Memory TOAST Storage TOAST pointers can point to data that is not on disk, but is @@ -694,9 +702,10 @@ erased (they will be recreated automatically as needed). This section provides an overview of the page format used within PostgreSQL tables and indexes. - Actually, index access methods need not use this page format. - All the existing index methods do use this basic format, - but the data kept on index metapages usually doesn't follow + Actually, use of this page format is not required for either table or + index access methods. The heap table access method + always uses this format. All the existing index methods also use the + basic format, but the data kept on index metapages usually doesn't follow the item layout rules. @@ -750,14 +759,14 @@ free space pointers. ItemIdData -Array of (offset,length) pairs pointing to the actual items. -4 bytes per item. +Array of item identifiers pointing to the actual items. Each +entry is an (offset,length) pair. 4 bytes per item. Free space -The unallocated space. New item pointers are allocated from the start -of this area, new items from the end. +The unallocated space. New item identifiers are allocated from +the start of this area, new items from the end. @@ -875,8 +884,7 @@ data. Empty in ordinary tables. src/include/storage/bufpage.h. - - + Following the page header are item identifiers (ItemIdData), each requiring four bytes. An item identifier contains a byte-offset to @@ -909,7 +917,7 @@ data. Empty in ordinary tables. The final section is the special section which can - contain anything the access method wishes to store. For example, + contain anything the access method wishes to store. For example, b-tree indexes store links to the page's left and right siblings, as well as some other data relevant to the index structure. Ordinary tables do not use a special section at all (indicated by setting @@ -917,6 +925,24 @@ data. Empty in ordinary tables. + + illustrates how these parts are + laid out in a page. + + +
+ Page Layout + + + + + +
+ + + + Table Row Layout + All table rows are structured in the same way. There is a fixed-size @@ -931,10 +957,11 @@ data. Empty in ordinary tables. only present if the HEAP_HASNULL bit is set in t_infomask. If it is present it begins just after the fixed header and occupies enough bytes to have one bit per data column - (that is, t_natts bits altogether). In this list of bits, a + (that is, the number of bits that equals the attribute count in + t_infomask2). In this list of bits, a 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not present, all columns are assumed not-null. - The object ID is only present if the HEAP_HASOID bit + The object ID is only present if the HEAP_HASOID_OLD bit is set in t_infomask. If present, it appears just before the t_hoff boundary. Any padding needed to make t_hoff a MAXALIGN multiple will appear between the null @@ -1040,6 +1067,7 @@ data. Empty in ordinary tables. it might be compressed, too (see ). + diff --git a/doc/src/sgml/stylesheet-common.xsl b/doc/src/sgml/stylesheet-common.xsl index 6d26e7e5c91..e148c9057f8 100644 --- a/doc/src/sgml/stylesheet-common.xsl +++ b/doc/src/sgml/stylesheet-common.xsl @@ -86,4 +86,15 @@ ? + + + + + + + + + + + diff --git a/doc/src/sgml/stylesheet-hh.xsl b/doc/src/sgml/stylesheet-hh.xsl index 09a95041d6f..1b1ab4bbe9e 100644 --- a/doc/src/sgml/stylesheet-hh.xsl +++ b/doc/src/sgml/stylesheet-hh.xsl @@ -10,12 +10,14 @@ + + -pgsql-docs@postgresql.org +pgsql-docs@lists.postgresql.org @@ -38,4 +40,10 @@
+ + + + + + diff --git a/doc/src/sgml/stylesheet-html-common.xsl b/doc/src/sgml/stylesheet-html-common.xsl index 17b7230d2c1..9edce52a104 100644 --- a/doc/src/sgml/stylesheet-html-common.xsl +++ b/doc/src/sgml/stylesheet-html-common.xsl @@ -14,7 +14,8 @@ -pgsql-docs@postgresql.org + +pgsql-docs@lists.postgresql.org 2 diff --git a/doc/src/sgml/stylesheet-html-nochunk.xsl b/doc/src/sgml/stylesheet-html-nochunk.xsl index ffd2012e918..78add26a9f4 100644 --- a/doc/src/sgml/stylesheet-html-nochunk.xsl +++ b/doc/src/sgml/stylesheet-html-nochunk.xsl @@ -9,4 +9,15 @@ + + + + + + + + + + + diff --git a/doc/src/sgml/stylesheet.css b/doc/src/sgml/stylesheet.css index c355fbecac7..1a66c789d50 100644 --- a/doc/src/sgml/stylesheet.css +++ b/doc/src/sgml/stylesheet.css @@ -102,3 +102,10 @@ var { font-family: monospace; font-style: italic; } acronym { font-style: inherit; } .option { white-space: nowrap; } + +/* make images not too wide on larger screens */ +@media (min-width: 800px) { + .mediaobject { + width: 75%; + } +} diff --git a/doc/src/sgml/stylesheet.xsl b/doc/src/sgml/stylesheet.xsl index 22dd3b93c62..4ff6e8ed242 100644 --- a/doc/src/sgml/stylesheet.xsl +++ b/doc/src/sgml/stylesheet.xsl @@ -28,6 +28,12 @@ + + + + + + + + + Table Access Method Interface Definition + + + Table Access Method + + + tableam + Table Access Method + + + + This chapter explains the interface between the core + PostgreSQL system and table access + methods, which manage the storage for tables. The core system + knows little about these access methods beyond what is specified here, so + it is possible to develop entirely new access method types by writing + add-on code. + + + + Each table access method is described by a row in the pg_am system + catalog. The pg_am entry specifies a name and a + handler function for the table access method. These + entries can be created and deleted using the and SQL commands. + + + + A table access method handler function must be declared to accept a single + argument of type internal and to return the pseudo-type + table_am_handler. The argument is a dummy value that simply + serves to prevent handler functions from being called directly from SQL commands. + + The result of the function must be a pointer to a struct of type + TableAmRoutine, which contains everything that the + core code needs to know to make use of the table access method. The return + value needs to be of server lifetime, which is typically achieved by + defining it as a static const variable in global + scope. The TableAmRoutine struct, also called the + access method's API struct, defines the behavior of + the access method using callbacks. These callbacks are pointers to plain C + functions and are not visible or callable at the SQL level. All the + callbacks and their behavior is defined in the + TableAmRoutine structure (with comments inside the + struct defining the requirements for callbacks). Most callbacks have + wrapper functions, which are documented from the point of view of a user + (rather than an implementor) of the table access method. For details, + please refer to the + src/include/access/tableam.h file. + + + + To implement an access method, an implementor will typically need to + implement an AM-specific type of tuple table slot (see + + src/include/executor/tuptable.h), which allows + code outside the access method to hold references to tuples of the AM, and + to access the columns of the tuple. + + + + Currently, the way an AM actually stores data is fairly unconstrained. For + example, it's possible, but not required, to use postgres' shared buffer + cache. In case it is used, it likely makes sense to use + PostgreSQL's standard page layout as described in + . + + + + One fairly large constraint of the table access method API is that, + currently, if the AM wants to support modifications and/or indexes, it is + necessary for each tuple to have a tuple identifier (TID) + consisting of a block number and an item number (see also ). It is not strictly necessary that the + sub-parts of TIDs have the same meaning they e.g. have + for heap, but if bitmap scan support is desired (it is + optional), the block number needs to provide locality. + + + + For crash safety, an AM can use postgres' WAL, or a custom implementation. + If WAL is chosen, either Generic WAL Records can be used, + or a new type of WAL records can be implemented. + Generic WAL Records are easy, but imply higher WAL volume. + Implementation of a new type of WAL record + currently requires modifications to core code (specifically, + src/include/access/rmgrlist.h). + + + + To implement transactional support in a manner that allows different table + access methods be accessed within a single transaction, it likely is + necessary to closely integrate with the machinery in + src/backend/access/transam/xlog.c. + + + + Any developer of a new table access method can refer to + the existing heap implementation present in + src/backend/access/heap/heapam_handler.c for details of + its implementation. + + + diff --git a/doc/src/sgml/tablesample-method.sgml b/doc/src/sgml/tablesample-method.sgml index b84b7ba8855..1c9f1bf44bf 100644 --- a/doc/src/sgml/tablesample-method.sgml +++ b/doc/src/sgml/tablesample-method.sgml @@ -1,7 +1,7 @@ - Writing A Table Sampling Method + Writing a Table Sampling Method table sampling method @@ -227,7 +227,7 @@ BeginSampleScan (SampleScanState *node, BlockNumber -NextSampleBlock (SampleScanState *node); +NextSampleBlock (SampleScanState *node, BlockNumber nblocks); Returns the block number of the next page to be scanned, or @@ -262,10 +262,9 @@ NextSampleTuple (SampleScanState *node, numbers in the range 1 .. maxoffset actually contain valid tuples. This is not normally a problem since the core code ignores requests to sample missing or invisible tuples; that should not result in - any bias in the sample. However, if necessary, the function can - examine node->ss.ss_currentScanDesc->rs_vistuples[] - to identify which tuples are valid and visible. (This - requires node->use_pagemode to be true.) + any bias in the sample. However, if necessary, the function can use + node->donetuples to examine how many of the tuples + it returned were valid and visible. diff --git a/doc/src/sgml/tcn.sgml b/doc/src/sgml/tcn.sgml index 8cc55efd291..aa2fe4f00af 100644 --- a/doc/src/sgml/tcn.sgml +++ b/doc/src/sgml/tcn.sgml @@ -47,7 +47,7 @@ test(# ); CREATE TABLE test=# create trigger tcndata_tcn_trigger test-# after insert or update or delete on tcndata -test-# for each row execute procedure triggered_change_notification(); +test-# for each row execute function triggered_change_notification(); CREATE TRIGGER test=# listen tcn; LISTEN diff --git a/doc/src/sgml/test-decoding.sgml b/doc/src/sgml/test-decoding.sgml index 310a2d69745..8356a3d67b3 100644 --- a/doc/src/sgml/test-decoding.sgml +++ b/doc/src/sgml/test-decoding.sgml @@ -10,7 +10,7 @@ test_decoding is an example of a logical decoding output plugin. It doesn't do anything especially useful, but can serve as - a starting point for developing your own decoder. + a starting point for developing your own output plugin. diff --git a/doc/src/sgml/textsearch.sgml b/doc/src/sgml/textsearch.sgml index 19f58511c82..3f00ae3bd95 100644 --- a/doc/src/sgml/textsearch.sgml +++ b/doc/src/sgml/textsearch.sgml @@ -620,15 +620,17 @@ CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' | Another approach is to create a separate tsvector column - to hold the output of to_tsvector. This example is a + to hold the output of to_tsvector. To keep this + column automatically up to date with its source data, use a stored + generated column. This example is a concatenation of title and body, using coalesce to ensure that one field will still be indexed when the other is NULL: -ALTER TABLE pgweb ADD COLUMN textsearchable_index_col tsvector; -UPDATE pgweb SET textsearchable_index_col = - to_tsvector('english', coalesce(title,'') || ' ' || coalesce(body,'')); +ALTER TABLE pgweb + ADD COLUMN textsearchable_index_col tsvector + GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED; Then we create a GIN index to speed up the search: @@ -648,14 +650,6 @@ LIMIT 10; - - When using a separate column to store the tsvector - representation, - it is necessary to create a trigger to keep the tsvector - column current anytime title or body changes. - explains how to do that. - - One advantage of the separate-column approach over an expression index is that it is not necessary to explicitly specify the text search @@ -1010,41 +1004,37 @@ websearch_to_tsquery( config Examples: - - select websearch_to_tsquery('english', 'The fat rats'); + +SELECT websearch_to_tsquery('english', 'The fat rats'); + websearch_to_tsquery +---------------------- + 'fat' & 'rat' +(1 row) + +SELECT websearch_to_tsquery('english', '"supernovae stars" -crab'); websearch_to_tsquery - ----------------- - 'fat' & 'rat' - (1 row) - - - select websearch_to_tsquery('english', '"supernovae stars" -crab'); - websearch_to_tsquery - ---------------------------------- - 'supernova' <-> 'star' & !'crab' - (1 row) - - - select websearch_to_tsquery('english', '"sad cat" or "fat rat"'); - websearch_to_tsquery - ----------------------------------- - 'sad' <-> 'cat' | 'fat' <-> 'rat' - (1 row) - - - select websearch_to_tsquery('english', 'signal -"segmentation fault"'); - websearch_to_tsquery - --------------------------------------- - 'signal' & !( 'segment' <-> 'fault' ) - (1 row) - - - select websearch_to_tsquery('english', '""" )( dummy \\ query <->'); +---------------------------------- + 'supernova' <-> 'star' & !'crab' +(1 row) + +SELECT websearch_to_tsquery('english', '"sad cat" or "fat rat"'); websearch_to_tsquery - ---------------------- - 'dummi' & 'queri' - (1 row) - +----------------------------------- + 'sad' <-> 'cat' | 'fat' <-> 'rat' +(1 row) + +SELECT websearch_to_tsquery('english', 'signal -"segmentation fault"'); + websearch_to_tsquery +--------------------------------------- + 'signal' & !( 'segment' <-> 'fault' ) +(1 row) + +SELECT websearch_to_tsquery('english', '""" )( dummy \\ query <->'); + websearch_to_tsquery +---------------------- + 'dummi' & 'queri' +(1 row) +
@@ -1861,6 +1851,14 @@ SELECT ts_rewrite('a & b'::tsquery, for updating a derived tsvector column + + + The method described in this section has been obsoleted by the use of + stored generated columns, as described in . + + + When using a separate column to store the tsvector representation of your documents, it is necessary to create a trigger to update the @@ -1888,7 +1886,7 @@ CREATE TABLE messages ( ); CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE -ON messages FOR EACH ROW EXECUTE PROCEDURE +ON messages FOR EACH ROW EXECUTE FUNCTION tsvector_update_trigger(tsv, 'pg_catalog.english', title, body); INSERT INTO messages VALUES('title here', 'the body text is here'); @@ -1944,7 +1942,7 @@ end $$ LANGUAGE plpgsql; CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE - ON messages FOR EACH ROW EXECUTE PROCEDURE messages_trigger(); + ON messages FOR EACH ROW EXECUTE FUNCTION messages_trigger(); @@ -2875,12 +2873,12 @@ SELECT plainto_tsquery('supernova star'); The standard PostgreSQL distribution does not include any Ispell configuration files. Dictionaries for a large number of languages are available from Ispell. + url="https://www.cs.hmc.edu/~geoff/ispell.html">Ispell. Also, some more modern dictionary file formats are supported — MySpell (OO < 2.0.1) - and Hunspell + url="https://en.wikipedia.org/wiki/MySpell">MySpell (OO < 2.0.1) + and Hunspell (OO >= 2.0.2). A large list of dictionaries is available on the OpenOffice + url="https://wiki.openoffice.org/wiki/Dictionaries">OpenOffice Wiki. @@ -3678,6 +3676,12 @@ SELECT plainto_tsquery('supernovae stars'); retrieved to see if the match is correct. + + A GiST index can be covering, i.e. use the INCLUDE + clause. Included columns can have data types without any GiST operator + class. Included attributes will be stored uncompressed. + + Lossiness causes performance degradation due to unnecessary fetches of table records that turn out to be false matches. Since random access to table @@ -3796,17 +3800,23 @@ Parser: "pg_catalog.default" List text search dictionaries (add + for more detail). => \dFd - List of text search dictionaries - Schema | Name | Description + List of text search dictionaries + Schema | Name | Description ------------+-----------------+----------------------------------------------------------- + pg_catalog | arabic_stem | snowball stemmer for arabic language pg_catalog | danish_stem | snowball stemmer for danish language pg_catalog | dutch_stem | snowball stemmer for dutch language pg_catalog | english_stem | snowball stemmer for english language pg_catalog | finnish_stem | snowball stemmer for finnish language pg_catalog | french_stem | snowball stemmer for french language pg_catalog | german_stem | snowball stemmer for german language + pg_catalog | greek_stem | snowball stemmer for greek language pg_catalog | hungarian_stem | snowball stemmer for hungarian language + pg_catalog | indonesian_stem | snowball stemmer for indonesian language + pg_catalog | irish_stem | snowball stemmer for irish language pg_catalog | italian_stem | snowball stemmer for italian language + pg_catalog | lithuanian_stem | snowball stemmer for lithuanian language + pg_catalog | nepali_stem | snowball stemmer for nepali language pg_catalog | norwegian_stem | snowball stemmer for norwegian language pg_catalog | portuguese_stem | snowball stemmer for portuguese language pg_catalog | romanian_stem | snowball stemmer for romanian language @@ -3814,6 +3824,7 @@ Parser: "pg_catalog.default" pg_catalog | simple | simple dictionary: just lower case and check for stopword pg_catalog | spanish_stem | snowball stemmer for spanish language pg_catalog | swedish_stem | snowball stemmer for swedish language + pg_catalog | tamil_stem | snowball stemmer for tamil language pg_catalog | turkish_stem | snowball stemmer for turkish language @@ -3904,7 +3915,7 @@ Parser: "pg_catalog.default" text search features are: - The length of each lexeme must be less than 2K bytes + The length of each lexeme must be less than 2 kilobytes The length of a tsvector (lexemes + positions) must be diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml index cce58fbf1d0..67e1861e061 100644 --- a/doc/src/sgml/trigger.sgml +++ b/doc/src/sgml/trigger.sgml @@ -182,26 +182,6 @@ will be fired. - - No separate triggers are defined for MERGE. Instead, - statement-level or row-level UPDATE, - DELETE and INSERT triggers are fired - depending on what actions are specified in the MERGE query - and what actions are activated. - - - - While running a MERGE command, statement-level - BEFORE and AFTER triggers are fired for - events specified in the actions of the MERGE command, - irrespective of whether the action is finally activated or not. This is same as - an UPDATE statement that updates no rows, yet - statement-level triggers are fired. The row-level triggers are fired only - when a row is actually updated, inserted or deleted. So it's perfectly legal - that while statement-level triggers are fired for certain type of action, no - row-level triggers are fired for the same kind of action. - - Trigger functions invoked by per-statement triggers should always return NULL. Trigger functions invoked by per-row @@ -263,6 +243,24 @@ operation, and so they can return NULL. + + Some considerations apply for generated + columns.generated columnin + triggers Stored generated columns are computed after + BEFORE triggers and before AFTER + triggers. Therefore, the generated value can be inspected in + AFTER triggers. In BEFORE triggers, + the OLD row contains the old generated value, as one + would expect, but the NEW row does not yet contain the + new generated value and should not be accessed. In the C language + interface, the content of the column is undefined at this point; a + higher-level programming language should prevent access to a stored + generated column in the NEW row in a + BEFORE trigger. Changes to the value of a generated + column in a BEFORE trigger are ignored and will be + overwritten. + + If more than one trigger is defined for the same event on the same relation, the triggers will be fired in alphabetical order by @@ -891,10 +889,10 @@ CREATE FUNCTION trigf() RETURNS trigger LANGUAGE C; CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest - FOR EACH ROW EXECUTE PROCEDURE trigf(); + FOR EACH ROW EXECUTE FUNCTION trigf(); CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest - FOR EACH ROW EXECUTE PROCEDURE trigf(); + FOR EACH ROW EXECUTE FUNCTION trigf(); diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml index ed4be4fcfcc..81dba7dacfe 100644 --- a/doc/src/sgml/typeconv.sgml +++ b/doc/src/sgml/typeconv.sgml @@ -246,7 +246,19 @@ search path position. Check for an operator accepting exactly the input argument types. If one exists (there can be only one exact match in the set of -operators considered), use it. +operators considered), use it. Lack of an exact match creates a security +hazard when calling, via qualified name + + + + The hazard does not arise with a non-schema-qualified name, because a + search path containing schemas that permit untrusted users to create + objects is not a secure schema usage + pattern. + + +(not typical), any operator found in a schema that permits untrusted users to +create objects. In such situations, cast arguments to force an exact match. @@ -589,6 +601,26 @@ function. In that case the function appearing earlier in the search path is used, or if the two functions are in the same schema, the non-variadic one is preferred. + +This creates a security hazard when calling, via qualified name + + + + The hazard does not arise with a non-schema-qualified name, because a + search path containing schemas that permit untrusted users to create + objects is not a secure schema usage + pattern. + + , +a variadic function found in a schema that permits untrusted users to create +objects. A malicious user can take control and execute arbitrary SQL +functions as though you executed them. Substitute a call bearing +the VARIADIC keyword, which bypasses this hazard. Calls +populating VARIADIC "any" parameters often have no +equivalent formulation containing the VARIADIC keyword. To +issue those calls safely, the function's schema must permit only trusted users +to create objects. + @@ -602,6 +634,15 @@ will not be able to determine which to prefer, and so an ambiguous function call error will result if no better match to the call can be found. + +This creates an availability hazard when calling, via qualified +name, any function found in a +schema that permits untrusted users to create objects. A malicious user can +create a function with the name of an existing function, replicating that +function's parameters and appending novel parameters having default values. +This precludes new calls to the original function. To forestall this hazard, +place functions in schemas that permit only trusted users to create objects. + @@ -610,9 +651,12 @@ found. Check for a function accepting exactly the input argument types. If one exists (there can be only one exact match in the set of -functions considered), use it. -(Cases involving unknown will never find a match at -this step.) +functions considered), use it. Lack of an exact match creates a security +hazard when calling, via qualified +name, a function found in a +schema that permits untrusted users to create objects. In such situations, +cast arguments to force an exact match. (Cases involving unknown +will never find a match at this step.) @@ -750,6 +794,57 @@ SELECT round(4.0, 4); + +Variadic Function Resolution + + + +CREATE FUNCTION public.variadic_example(VARIADIC numeric[]) RETURNS int + LANGUAGE sql AS 'SELECT 1'; +CREATE FUNCTION + + +This function accepts, but does not require, the VARIADIC keyword. It +tolerates both integer and numeric arguments: + + +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 1 | 1 | 1 +(1 row) + + +However, the first and second calls will prefer more-specific functions, if +available: + + +CREATE FUNCTION public.variadic_example(numeric) RETURNS int + LANGUAGE sql AS 'SELECT 2'; +CREATE FUNCTION + +CREATE FUNCTION public.variadic_example(int) RETURNS int + LANGUAGE sql AS 'SELECT 3'; +CREATE FUNCTION + +SELECT public.variadic_example(0), + public.variadic_example(0.0), + public.variadic_example(VARIADIC array[0.0]); + variadic_example | variadic_example | variadic_example +------------------+------------------+------------------ + 3 | 2 | 1 +(1 row) + + +Given the default configuration and only the first function existing, the +first and second calls are insecure. Any user could intercept them by +creating the second or third function. By matching the argument type exactly +and using the VARIADIC keyword, the third call is secure. + + + Substring Function Type Resolution diff --git a/doc/src/sgml/unaccent.sgml b/doc/src/sgml/unaccent.sgml index a7f5f53041b..547ac54a71e 100644 --- a/doc/src/sgml/unaccent.sgml +++ b/doc/src/sgml/unaccent.sgml @@ -174,12 +174,14 @@ mydb=# select ts_headline('fr','Hôtel de la Mer',to_tsquery('fr','Hotels') -unaccent(dictionary, string) returns text +unaccent(dictionary regdictionary, string text) returns text If the dictionary argument is - omitted, unaccent is assumed. + omitted, the text search dictionary named unaccent and + appearing in the same schema as the unaccent() + function itself is used. diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index 81b44a8c417..66f162703dd 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -530,9 +530,16 @@ DROP ROLE doomed_role; Execute monitoring functions that may take ACCESS SHARE locks on tables, potentially for a long time. + + pg_monitor + Read/execute various monitoring views and functions. + This role is a member of pg_read_all_settings, + pg_read_all_stats and + pg_stat_scan_tables. + pg_signal_backend - Send signals to other backends (eg: cancel query, terminate). + Signal another backend to cancel a query or terminate its session. pg_read_server_files @@ -549,27 +556,10 @@ DROP ROLE doomed_role; Allow executing programs on the database server as the user the database runs as with COPY and other functions which allow executing a server-side program. - - pg_monitor - Read/execute various monitoring views and functions. - This role is a member of pg_read_all_settings, - pg_read_all_stats and - pg_stat_scan_tables. -
- - The pg_read_server_files, pg_write_server_files and - pg_execute_server_program roles are intended to allow administrators to have - trusted, but non-superuser, roles which are able to access files and run programs on the - database server as the user the database runs as. As these roles are able to access any file on - the server filesystem, they bypass all database-level permission checks when accessing files - directly and they could be used to gain superuser-level access, therefore care should be taken - when granting these roles to users. - - The pg_monitor, pg_read_all_settings, pg_read_all_stats and pg_stat_scan_tables @@ -579,6 +569,25 @@ DROP ROLE doomed_role; other system information normally restricted to superusers. + + The pg_signal_backend role is intended to allow + administrators to enable trusted, but non-superuser, roles to send signals + to other backends. Currently this role enables sending of signals for + canceling a query on another backend or terminating its session. A user + granted this role cannot however send signals to a backend owned by a + superuser. See . + + + + The pg_read_server_files, pg_write_server_files and + pg_execute_server_program roles are intended to allow administrators to have + trusted, but non-superuser, roles which are able to access files and run programs on the + database server as the user the database runs as. As these roles are able to access any file on + the server file system, they bypass all database-level permission checks when accessing files + directly and they could be used to gain superuser-level access, therefore + great care should be taken when granting these roles to users. + + Care should be taken when granting these roles to ensure they are only used where needed and with the understanding that these roles grant access to privileged @@ -586,8 +595,8 @@ DROP ROLE doomed_role; - Administrators can grant access to these roles to users using the GRANT - command: + Administrators can grant access to these roles to users using the + command, for example: GRANT pg_signal_backend TO admin_user; diff --git a/doc/src/sgml/uuid-ossp.sgml b/doc/src/sgml/uuid-ossp.sgml index b3b816c3725..0fbabbfda24 100644 --- a/doc/src/sgml/uuid-ossp.sgml +++ b/doc/src/sgml/uuid-ossp.sgml @@ -11,6 +11,9 @@ The uuid-ossp module provides functions to generate universally unique identifiers (UUIDs) using one of several standard algorithms. There are also functions to produce certain special UUID constants. + This module is only necessary for special requirements beyond what is + available in core PostgreSQL. See for built-in ways to generate UUIDs. @@ -181,14 +184,6 @@ SELECT uuid_generate_v3(uuid_ns_url(), 'http://www.postgresql.org'); More than one of these libraries might be available on a particular machine, so configure does not automatically choose one.
- - - - If you only need randomly-generated (version 4) UUIDs, - consider using the gen_random_uuid() function - from the module instead. - - diff --git a/doc/src/sgml/vacuumlo.sgml b/doc/src/sgml/vacuumlo.sgml index 0b4dfc2b17a..0b57a77af41 100644 --- a/doc/src/sgml/vacuumlo.sgml +++ b/doc/src/sgml/vacuumlo.sgml @@ -55,7 +55,8 @@ - limit + + Remove no more than limit large objects per @@ -69,6 +70,7 @@ + Don't remove anything, just show what would be done. @@ -76,6 +78,7 @@ + Write a lot of progress messages. @@ -110,21 +113,24 @@ - hostname + + Database server's host. - port + + Database server's port. - username + + User name to connect as. @@ -146,6 +152,7 @@ + Force vacuumlo to prompt for a @@ -167,6 +174,30 @@ + + Environment + + + + PGHOST + PGPORT + PGUSER + + + + Default connection parameters. + + + + + + + This utility, like most other PostgreSQL utilities, + also uses the environment variables supported by libpq + (see ). + + + Notes diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml index f4bc2d4161e..4eb8feb9037 100644 --- a/doc/src/sgml/wal.sgml +++ b/doc/src/sgml/wal.sgml @@ -155,7 +155,7 @@ If you use SSDs, be aware that many of these do not honor cache flush commands by default. You can test for reliable I/O subsystem behavior using diskchecker.pl. + url="https://brad.livejournal.com/2116715.html">diskchecker.pl. @@ -551,8 +551,8 @@ flushed to disk after a configurable number of bytes. Otherwise, these pages may be kept in the OS's page cache, inducing a stall when fsync is issued at the end of a checkpoint. This setting will - often help to reduce transaction latency, but it also can an adverse effect - on performance; particularly for workloads that are bigger than + often help to reduce transaction latency, but it also can have an adverse + effect on performance; particularly for workloads that are bigger than , but smaller than the OS's page cache. diff --git a/doc/src/sgml/xaggr.sgml b/doc/src/sgml/xaggr.sgml index 1514e5c388e..f035866848c 100644 --- a/doc/src/sgml/xaggr.sgml +++ b/doc/src/sgml/xaggr.sgml @@ -1,7 +1,7 @@ - User-defined Aggregates + User-Defined Aggregates aggregate function @@ -491,8 +491,8 @@ SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households; to continue adding input rows by executing the transition function again later. This means the final function is not READ_ONLY; it must be declared in - as READ_WRITE, or as SHARABLE if it's - possible for additional final-function calls to make use of the + as READ_WRITE, or as SHAREABLE if + it's possible for additional final-function calls to make use of the already-sorted state. diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index bbc3766cc21..d9afd3be4d0 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,7 +1,7 @@ - User-defined Functions + User-Defined Functions function @@ -73,7 +73,7 @@ - User-defined Procedures + User-Defined Procedures procedure @@ -764,8 +764,11 @@ SELECT mleast(ARRAY[10, -1, 5, 4.4]); -- doesn't work Sometimes it is useful to be able to pass an already-constructed array to a variadic function; this is particularly handy when one variadic - function wants to pass on its array parameter to another one. You can - do that by specifying VARIADIC in the call: + function wants to pass on its array parameter to another one. Also, + this is the only secure way to call a variadic function found in a schema + that permits untrusted users to create objects; see + . You can do this by + specifying VARIADIC in the call: SELECT mleast(VARIADIC ARRAY[10, -1, 5, 4.4]); @@ -827,7 +830,10 @@ SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]); parameters after a parameter with a default value have to have default values as well. (Although the use of named argument notation could allow this restriction to be relaxed, it's still enforced so that - positional argument notation works sensibly.) + positional argument notation works sensibly.) Whether or not you use it, + this capability creates a need for precautions when calling functions in + databases where some users mistrust other users; see + . @@ -1077,10 +1083,10 @@ SELECT x, g FROM tab, LATERAL generate_series(1,5) AS g; It would be exactly the same, except that in this specific example, the planner could choose to put g on the outside of the - nestloop join, since g has no actual lateral dependency + nested-loop join, since g has no actual lateral dependency on tab. That would result in a different output row order. Set-returning functions in the select list are always evaluated - as though they are on the inside of a nestloop join with the rest of + as though they are on the inside of a nested-loop join with the rest of the FROM clause, so that the function(s) are run to completion before the next row from the FROM clause is considered. @@ -1399,11 +1405,14 @@ $$ LANGUAGE SQL; More than one function can be defined with the same SQL name, so long as the arguments they take are different. In other words, - function names can be overloaded. When a - query is executed, the server will determine which function to - call from the data types and the number of the provided arguments. - Overloading can also be used to simulate functions with a variable - number of arguments, up to a finite maximum number. + function names can be overloaded. Whether or not + you use it, this capability entails security precautions when calling + functions in databases where some users mistrust other users; see + . When a query is executed, the server + will determine which function to call from the data types and the number + of the provided arguments. Overloading can also be used to simulate + functions with a variable number of arguments, up to a finite maximum + number. @@ -2060,16 +2069,6 @@ memcpy(destination->data, buffer, 40); - - abstime - AbsoluteTime - utils/nabstime.h - - - bigint (int8) - int64 - postgres.h - boolean bool @@ -2170,11 +2169,6 @@ memcpy(destination->data, buffer, 40); regproc postgres.h - - reltime - RelativeTime - utils/nabstime.h - text text* @@ -2200,11 +2194,6 @@ memcpy(destination->data, buffer, 40); Timestamp* datatype/timestamp.h - - tinterval - TimeInterval - utils/nabstime.h - varchar VarChar* @@ -2583,7 +2572,7 @@ CREATE FUNCTION concat_text(text, text) RETURNS text &dfunc; - Composite-type Arguments + Composite-Type Arguments Composite types do not have a fixed layout like C structures. @@ -2861,14 +2850,6 @@ typedef struct FuncCallContext */ uint64 max_calls; - /* - * OPTIONAL pointer to result slot - * - * This is obsolete and only present for backward compatibility, viz, - * user-defined SRFs that use the deprecated TupleDescGetSlot(). - */ - TupleTableSlot *slot; - /* * OPTIONAL pointer to miscellaneous user-provided context information * @@ -3260,40 +3241,6 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray - - Transform Functions - - - Some function calls can be simplified during planning based on - properties specific to the function. For example, - int4mul(n, 1) could be simplified to just n. - To define such function-specific optimizations, write a - transform function and place its OID in the - protransform field of the primary function's - pg_proc entry. The transform function must have the SQL - signature protransform(internal) RETURNS internal. The - argument, actually FuncExpr *, is a dummy node representing a - call to the primary function. If the transform function's study of the - expression tree proves that a simplified expression tree can substitute - for all possible concrete calls represented thereby, build and return - that simplified expression. Otherwise, return a NULL - pointer (not a SQL null). - - - - We make no guarantee that PostgreSQL will never call the - primary function in cases that the transform function could simplify. - Ensure rigorous equivalence between the simplified expression and an - actual call to the primary function. - - - - Currently, this facility is not exposed to users at the SQL level - because of security concerns, so it is only practical to use for - optimizing built-in functions. - - - Shared Memory and LWLocks @@ -3407,3 +3354,124 @@ if (!ptr) + + + Function Optimization Information + + + optimization information + for functions + + + + By default, a function is just a black box that the + database system knows very little about the behavior of. However, + that means that queries using the function may be executed much less + efficiently than they could be. It is possible to supply additional + knowledge that helps the planner optimize function calls. + + + + Some basic facts can be supplied by declarative annotations provided in + the command. Most important of + these is the function's volatility + category (IMMUTABLE, STABLE, + or VOLATILE); one should always be careful to + specify this correctly when defining a function. + The parallel safety property (PARALLEL + UNSAFE, PARALLEL RESTRICTED, or + PARALLEL SAFE) must also be specified if you hope + to use the function in parallelized queries. + It can also be useful to specify the function's estimated execution + cost, and/or the number of rows a set-returning function is estimated + to return. However, the declarative way of specifying those two + facts only allows specifying a constant value, which is often + inadequate. + + + + It is also possible to attach a planner support + function to a SQL-callable function (called + its target function), and thereby provide + knowledge about the target function that is too complex to be + represented declaratively. Planner support functions have to be + written in C (although their target functions might not be), so this is + an advanced feature that relatively few people will use. + + + + A planner support function must have the SQL signature + +supportfn(internal) returns internal + + It is attached to its target function by specifying + the SUPPORT clause when creating the target function. + + + + The details of the API for planner support functions can be found in + file src/include/nodes/supportnodes.h in the + PostgreSQL source code. Here we provide + just an overview of what planner support functions can do. + The set of possible requests to a support function is extensible, + so more things might be possible in future versions. + + + + Some function calls can be simplified during planning based on + properties specific to the function. For example, + int4mul(n, 1) could be simplified to + just n. This type of transformation can be + performed by a planner support function, by having it implement + the SupportRequestSimplify request type. + The support function will be called for each instance of its target + function found in a query parse tree. If it finds that the particular + call can be simplified into some other form, it can build and return a + parse tree representing that expression. This will automatically work + for operators based on the function, too — in the example just + given, n * 1 would also be simplified to + n. + (But note that this is just an example; this particular + optimization is not actually performed by + standard PostgreSQL.) + We make no guarantee that PostgreSQL will + never call the target function in cases that the support function could + simplify. Ensure rigorous equivalence between the simplified + expression and an actual execution of the target function. + + + + For target functions that return boolean, it is often useful to estimate + the fraction of rows that will be selected by a WHERE clause using that + function. This can be done by a support function that implements + the SupportRequestSelectivity request type. + + + + If the target function's run time is highly dependent on its inputs, + it may be useful to provide a non-constant cost estimate for it. + This can be done by a support function that implements + the SupportRequestCost request type. + + + + For target functions that return sets, it is often useful to provide + a non-constant estimate for the number of rows that will be returned. + This can be done by a support function that implements + the SupportRequestRows request type. + + + + For target functions that return boolean, it may be possible to + convert a function call appearing in WHERE into an indexable operator + clause or clauses. The converted clauses might be exactly equivalent + to the function's condition, or they could be somewhat weaker (that is, + they might accept some values that the function condition does not). + In the latter case the index condition is said to + be lossy; it can still be used to scan an index, + but the function call will have to be executed for each row returned by + the index to see if it really passes the WHERE condition or not. + To create such conditions, the support function must implement + the SupportRequestIndexCondition request type. + + diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml index 9f5c0c3fb2c..ffb5164aaa0 100644 --- a/doc/src/sgml/xindex.sgml +++ b/doc/src/sgml/xindex.sgml @@ -1,7 +1,7 @@ - Interfacing Extensions To Indexes + Interfacing Extensions to Indexes index @@ -50,7 +50,7 @@ WHERE-clause operators that can be used with an index (i.e., can be converted into an index-scan qualification). An operator class can also specify some support - procedures that are needed by the internal operations of the + function that are needed by the internal operations of the index method, but do not directly correspond to any WHERE-clause operator that can be used with the index. @@ -105,7 +105,7 @@ - B-tree Strategies + B-Tree Strategies @@ -410,7 +410,7 @@
- B-tree Support Functions + B-Tree Support Functions @@ -1242,7 +1242,7 @@ SELECT sum(x) OVER (ORDER BY x RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) Ordering Operators - Some index access methods (currently, only GiST) support the concept of + Some index access methods (currently, only GiST and SP-GiST) support the concept of ordering operators. What we have been discussing so far are search operators. A search operator is one for which the index can be searched to find all rows satisfying diff --git a/doc/src/sgml/xml2.sgml b/doc/src/sgml/xml2.sgml index 0a0f13d02d6..560faa000ec 100644 --- a/doc/src/sgml/xml2.sgml +++ b/doc/src/sgml/xml2.sgml @@ -25,7 +25,7 @@ you are encouraged to try converting your applications. If you find that some of the functionality of this module is not available in an adequate form with the newer API, please explain - your issue to pgsql-hackers@postgresql.org so that the deficiency + your issue to pgsql-hackers@lists.postgresql.org so that the deficiency can be addressed. diff --git a/doc/src/sgml/xoper.sgml b/doc/src/sgml/xoper.sgml index 2aa7cf9b642..132056f869a 100644 --- a/doc/src/sgml/xoper.sgml +++ b/doc/src/sgml/xoper.sgml @@ -1,7 +1,7 @@ - User-defined Operators + User-Defined Operators operator @@ -44,7 +44,7 @@ CREATE FUNCTION complex_add(complex, complex) CREATE OPERATOR + ( leftarg = complex, rightarg = complex, - procedure = complex_add, + function = complex_add, commutator = + ); @@ -66,7 +66,7 @@ SELECT (a + b) AS c FROM test_complex; We've shown how to create a binary operator here. To create unary operators, just omit one of leftarg (for left unary) or - rightarg (for right unary). The procedure + rightarg (for right unary). The function clause and the argument clauses are the only required items in CREATE OPERATOR. The commutator clause shown in the example is an optional hint to the query @@ -78,6 +78,11 @@ SELECT (a + b) AS c FROM test_complex; Operator Optimization Information + + optimization information + for operators + + A PostgreSQL operator definition can include several optional clauses that tell the system useful things about how @@ -97,6 +102,13 @@ SELECT (a + b) AS c FROM test_complex; the ones that release &version; understands. + + It is also possible to attach a planner support function to the function + that underlies an operator, providing another way of telling the system + about the behavior of the operator. + See for more information. + + <literal>COMMUTATOR</literal> diff --git a/doc/src/sgml/xplang.sgml b/doc/src/sgml/xplang.sgml index 4b52210459d..60e04307510 100644 --- a/doc/src/sgml/xplang.sgml +++ b/doc/src/sgml/xplang.sgml @@ -137,7 +137,7 @@ CREATE FUNCTION validator_function_name(oid) Finally, the PL must be declared with the command -CREATE TRUSTED PROCEDURAL LANGUAGE language-name +CREATE TRUSTED LANGUAGE language_name HANDLER handler_function_name INLINE inline_function_name VALIDATOR validator_function_name ; @@ -146,7 +146,7 @@ CREATE TRUSTED PROCEDURAL LANGUAGE TRUSTED flag should only be given for languages that do not allow access to database server @@ -200,13 +200,13 @@ CREATE FUNCTION plperl_validator(oid) RETURNS void AS The command: -CREATE TRUSTED PROCEDURAL LANGUAGE plperl +CREATE TRUSTED LANGUAGE plperl HANDLER plperl_call_handler INLINE plperl_inline_handler VALIDATOR plperl_validator; then defines that the previously declared functions - should be invoked for functions and trigger procedures where the + should be invoked for functions and procedures where the language attribute is plperl. diff --git a/doc/src/sgml/xtypes.sgml b/doc/src/sgml/xtypes.sgml index 29747a0873e..e67e5bdf4c4 100644 --- a/doc/src/sgml/xtypes.sgml +++ b/doc/src/sgml/xtypes.sgml @@ -1,7 +1,7 @@ - User-defined Types + User-Defined Types data type @@ -86,8 +86,8 @@ complex_in(PG_FUNCTION_ARGS) if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for complex: \"%s\"", - str))); + errmsg("invalid input syntax for type %s: \"%s\"", + "complex", str))); result = (Complex *) palloc(sizeof(Complex)); result->x = x; diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 20090b360e3..2d21068183b 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -19,11 +19,11 @@ # # Meta configuration -standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check installcheck init-po update-po +standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check checkprep installcheck init-po update-po # these targets should recurse even into subdirectories not being built: standard_always_targets = distprep clean distclean maintainer-clean -.PHONY: $(standard_targets) install-strip html man installcheck-parallel maintainer-check +.PHONY: $(standard_targets) install-strip html man installcheck-parallel # make `all' the default target all: @@ -203,7 +203,6 @@ enable_dtrace = @enable_dtrace@ enable_coverage = @enable_coverage@ enable_tap_tests = @enable_tap_tests@ enable_thread_safety = @enable_thread_safety@ -enable_strong_random = @enable_strong_random@ python_includespec = @python_includespec@ python_libdir = @python_libdir@ @@ -241,6 +240,7 @@ BITCODE_CXXFLAGS = @BITCODE_CXXFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +PG_SYSROOT = @PG_SYSROOT@ override CPPFLAGS := $(ICU_CFLAGS) $(CPPFLAGS) @@ -261,6 +261,7 @@ CFLAGS = @CFLAGS@ CFLAGS_VECTOR = @CFLAGS_VECTOR@ CFLAGS_SSE42 = @CFLAGS_SSE42@ CFLAGS_ARMV8_CRC32C = @CFLAGS_ARMV8_CRC32C@ +PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@ CXXFLAGS = @CXXFLAGS@ LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ @@ -331,6 +332,7 @@ else endif perl_archlibexp = @perl_archlibexp@ perl_privlibexp = @perl_privlibexp@ +perl_includespec = @perl_includespec@ perl_embed_ccflags = @perl_embed_ccflags@ perl_embed_ldflags = @perl_embed_ldflags@ @@ -355,11 +357,11 @@ BZIP2 = bzip2 # available before building, but we don't want parallel makes all trying # to build the same headers. These rules, together with the recursion rules # below, ensure that we update the generated headers once, if needed, -# at the top level of any "make all" or "make install" request. If a -# particular subdirectory knows this isn't needed in itself or its children, -# it can set NO_GENERATED_HEADERS. +# at the top level of any "make all/install/check/installcheck" request. +# If a particular subdirectory knows this isn't needed in itself or its +# children, it can set NO_GENERATED_HEADERS. -all install: submake-generated-headers +all install check installcheck: submake-generated-headers .PHONY: submake-generated-headers @@ -381,18 +383,24 @@ check: temp-install .PHONY: temp-install -temp-install: +temp-install: | submake-generated-headers ifndef NO_TEMP_INSTALL ifneq ($(abs_top_builddir),) ifeq ($(MAKELEVEL),0) rm -rf '$(abs_top_builddir)'/tmp_install $(MKDIR_P) '$(abs_top_builddir)'/tmp_install/log $(MAKE) -C '$(top_builddir)' DESTDIR='$(abs_top_builddir)'/tmp_install install >'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 + $(MAKE) -j1 $(if $(CHECKPREP_TOP),-C $(CHECKPREP_TOP),) checkprep >>'$(abs_top_builddir)'/tmp_install/log/install.log 2>&1 endif - $(if $(EXTRA_INSTALL),for extra in $(EXTRA_INSTALL); do $(MAKE) -C '$(top_builddir)'/$$extra DESTDIR='$(abs_top_builddir)'/tmp_install install >>'$(abs_top_builddir)'/tmp_install/log/install.log || exit; done) endif endif +# Tasks to run serially at the end of temp-install. Some EXTRA_INSTALL +# entries appear more than once in the tree, and parallel installs of the same +# file can fail with EEXIST. +checkprep: + $(if $(EXTRA_INSTALL),for extra in $(EXTRA_INSTALL); do $(MAKE) -C '$(top_builddir)'/$$extra DESTDIR='$(abs_top_builddir)'/tmp_install install || exit; done) + PROVE = @PROVE@ # There are common routines in src/test/perl, and some test suites have # extra perl modules in their own directory. @@ -406,26 +414,29 @@ $(1)="$(if $($(1)),$(2):$$$(1),$(2))" endef # platform-specific environment variable to set shared library path -define ld_library_path_var -$(if $(filter $(PORTNAME),darwin),DYLD_LIBRARY_PATH,$(if $(filter $(PORTNAME),aix),LIBPATH,$(if $(filter $(PORTNAME),hpux),SHLIB_PATH,LD_LIBRARY_PATH))) -endef +# individual ports can override this later, this is the default name +ld_library_path_var = LD_LIBRARY_PATH -define with_temp_install -PATH="$(abs_top_builddir)/tmp_install$(bindir):$$PATH" $(call add_to_path,$(ld_library_path_var),$(abs_top_builddir)/tmp_install$(libdir)) -endef +# with_temp_install_extra is for individual ports to define if they +# need something more here. If not defined then the expansion does +# nothing. +with_temp_install = \ + PATH="$(abs_top_builddir)/tmp_install$(bindir):$$PATH" \ + $(call add_to_path,$(strip $(ld_library_path_var)),$(abs_top_builddir)/tmp_install$(libdir)) \ + $(with_temp_install_extra) ifeq ($(enable_tap_tests),yes) define prove_installcheck rm -rf '$(CURDIR)'/tmp_check $(MKDIR_P) '$(CURDIR)'/tmp_check -cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) +cd $(srcdir) && TESTDIR='$(CURDIR)' PATH="$(bindir):$$PATH" PGPORT='6$(DEF_PGPORT)' top_builddir='$(CURDIR)/$(top_builddir)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' REGRESS_SHLIB='$(abs_top_builddir)/src/test/regress/regress$(DLSUFFIX)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) endef define prove_check rm -rf '$(CURDIR)'/tmp_check $(MKDIR_P) '$(CURDIR)'/tmp_check -cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) +cd $(srcdir) && TESTDIR='$(CURDIR)' $(with_temp_install) PGPORT='6$(DEF_PGPORT)' PG_REGRESS='$(CURDIR)/$(top_builddir)/src/test/regress/pg_regress' REGRESS_SHLIB='$(abs_top_builddir)/src/test/regress/regress$(DLSUFFIX)' $(PROVE) $(PG_PROVE_FLAGS) $(PROVE_FLAGS) $(if $(PROVE_TESTS),$(PROVE_TESTS),t/*.pl) endef else @@ -470,11 +481,6 @@ GCOV = @GCOV@ LCOV = @LCOV@ GENHTML = @GENHTML@ -ifeq ($(enable_coverage),yes) -# ccache loses .gcno files -export CCACHE_DISABLE = 1 -endif - # Feature settings DEF_PGPORT = @default_port@ @@ -495,13 +501,6 @@ host_tuple = @host@ host_os = @host_os@ host_cpu = @host_cpu@ -# Make HAVE_IPV6 available for initdb script creation -HAVE_IPV6= @HAVE_IPV6@ - -# This is mainly for use on FreeBSD, where we have both a.out and elf -# systems now. May be applicable to other systems to? -ELF_SYSTEM= @ELF_SYS@ - # Backend stack size limit has to be hard-wired on Windows (it's in bytes) WIN32_STACK_RLIMIT=4194304 @@ -519,6 +518,11 @@ ifeq ($(enable_rpath), yes) LDFLAGS += $(rpath) endif +# Show the DLSUFFIX to build scripts (e.g. buildfarm) +.PHONY: show_dl_suffix +show_dl_suffix: + @echo $(DLSUFFIX) + ########################################################################## # @@ -533,21 +537,26 @@ libpq_srcdir = $(top_srcdir)/src/interfaces/libpq libpq_builddir = $(top_builddir)/src/interfaces/libpq endif -# This macro is for use by libraries linking to libpq. (Because libpgport -# isn't created with the same link flags as libpq, it can't be used.) +# How to link to libpq. (This macro may be used as-is by backend extensions. +# Client-side code should go through libpq_pgport or libpq_pgport_shlib, +# instead.) libpq = -L$(libpq_builddir) -lpq -# This macro is for use by client executables (not libraries) that use libpq. +# libpq_pgport is for use by client executables (not libraries) that use libpq. # We force clients to pull symbols from the non-shared libraries libpgport # and libpgcommon rather than pulling some libpgport symbols from libpq just # because libpq uses those functions too. This makes applications less -# dependent on changes in libpq's usage of pgport. To do this we link to +# dependent on changes in libpq's usage of pgport (on platforms where we +# don't have symbol export control for libpq). To do this we link to # pgport before libpq. This does cause duplicate -lpgport's to appear -# on client link lines. +# on client link lines, since that also appears in $(LIBS). +# libpq_pgport_shlib is the same idea, but for use in client shared libraries. ifdef PGXS libpq_pgport = -L$(libdir) -lpgcommon -lpgport $(libpq) +libpq_pgport_shlib = -L$(libdir) -lpgcommon_shlib -lpgport_shlib $(libpq) else libpq_pgport = -L$(top_builddir)/src/common -lpgcommon -L$(top_builddir)/src/port -lpgport $(libpq) +libpq_pgport_shlib = -L$(top_builddir)/src/common -lpgcommon_shlib -L$(top_builddir)/src/port -lpgport_shlib $(libpq) endif # Cygwin seems to need ldap libraries to be mentioned here, too @@ -560,14 +569,14 @@ endif # # Commonly used submake targets -submake-libpq: +submake-libpq: | submake-generated-headers $(MAKE) -C $(libpq_builddir) all -submake-libpgport: +submake-libpgport: | submake-generated-headers $(MAKE) -C $(top_builddir)/src/port all $(MAKE) -C $(top_builddir)/src/common all -submake-libpgfeutils: +submake-libpgfeutils: | submake-generated-headers $(MAKE) -C $(top_builddir)/src/port all $(MAKE) -C $(top_builddir)/src/common all $(MAKE) -C $(top_builddir)/src/fe_utils all @@ -579,16 +588,25 @@ submake-libpgfeutils: # # Testing support -PL_TESTDB = pl_regression -CONTRIB_TESTDB = contrib_regression -ifneq ($(MODULE_big),) - CONTRIB_TESTDB_MODULE = contrib_regression_$(MODULE_big) -else - ifneq ($(MODULES),) - CONTRIB_TESTDB_MODULE = contrib_regression_$(MODULES) +ifneq ($(USE_MODULE_DB),) + PL_TESTDB = pl_regression_$(NAME) + # Replace this with $(or ...) if we ever require GNU make 3.81. + ifneq ($(MODULE_big),) + CONTRIB_TESTDB=contrib_regression_$(MODULE_big) + ISOLATION_TESTDB=isolation_regression_$(MODULE_big) else - CONTRIB_TESTDB_MODULE = contrib_regression + ifneq ($(MODULES),) + CONTRIB_TESTDB=contrib_regression_$(word 1,$(MODULES)) + ISOLATION_TESTDB=isolation_regression_$(word 1,$(MODULES)) + else + CONTRIB_TESTDB=contrib_regression_$(word 1,$(REGRESS)) + ISOLATION_TESTDB=isolation_regression_$(word 1,$(ISOLATION)) + endif endif +else + PL_TESTDB = pl_regression + CONTRIB_TESTDB = contrib_regression + ISOLATION_TESTDB = isolation_regression endif ifdef NO_LOCALE @@ -733,6 +751,13 @@ endif # tracking (see below) is used. %: %.c +# Replace gmake's default rule for linking a single .o file to produce an +# executable. The main point here is to put LDFLAGS after the .o file, +# since we put -l switches into LDFLAGS and those are order-sensitive. +# In addition, include CFLAGS and LDFLAGS_EX per project conventions. +%: %.o + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) + ifndef PGXS # Remake Makefile.global from Makefile.global.in if the latter @@ -806,8 +831,8 @@ $(error GNU make 3.80 or newer is required. You are using version $(MAKE_VERSIO endif # This function is only for internal use below. It should be called -# using $(eval). It will set up a target so that it recurses into -# a given subdirectory. For the tree-wide all/install/check cases, +# using $(eval). It will set up a target so that it recurses into a +# given subdirectory. For the tree-wide all/install/check/installcheck cases, # ensure we do our one-time tasks before recursing (see targets above). # Note that to avoid a nasty bug in make 3.80, # this function has to avoid using any complicated constructs (like @@ -820,7 +845,7 @@ endif define _create_recursive_target .PHONY: $(1)-$(2)-recurse $(1): $(1)-$(2)-recurse -$(1)-$(2)-recurse: $(if $(filter all install, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install) +$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install) $$(MAKE) -C $(2) $(3) endef # Note that the use of $$ on the last line above is important; we want @@ -1017,19 +1042,17 @@ endif # $(1) name of the module (e.g. an extension's name or postgres for core code) # $(2) source objects, with .o suffix # -define install_llvm_module -# Create target directory -$(MKDIR_P) "$(DESTDIR)${bitcodedir}/$(1)" -# Create sub-directories, if files are in subdirectories -$(MKDIR_P) $(sort $(dir $(addprefix $(DESTDIR)${bitcodedir}/$(1)/, $(2)))) -# Then install files -# # The many INSTALL_DATA invocations aren't particularly fast, it'd be # good if we could coalesce them, but I didn't find a good way. -$(foreach obj, ${2}, $(INSTALL_DATA) $(patsubst %.o,%.bc, $(obj)) $(DESTDIR)/${bitcodedir}/$(1)/$(dir $(obj)); +# +# Note: blank line at end of macro is necessary to let it be used in foreach +define install_llvm_module +$(MKDIR_P) '$(DESTDIR)${bitcodedir}/$(1)' +$(MKDIR_P) $(sort $(dir $(addprefix '$(DESTDIR)${bitcodedir}'/$(1)/, $(2)))) +$(foreach obj, ${2}, $(INSTALL_DATA) $(patsubst %.o,%.bc, $(obj)) '$(DESTDIR)${bitcodedir}'/$(1)/$(dir $(obj)) ) -# and generate index -(cd "$(DESTDIR)${bitcodedir}" && $(LLVM_BINPATH)/llvm-lto -thinlto -thinlto-action=thinlink -o $(1).index.bc $(addprefix $(1)/,$(patsubst %.o,%.bc, $(2)))) +cd '$(DESTDIR)${bitcodedir}' && $(LLVM_BINPATH)/llvm-lto -thinlto -thinlto-action=thinlink -o $(1).index.bc $(addprefix $(1)/,$(patsubst %.o,%.bc, $(2))) + endef # Uninstall LLVM bitcode module. @@ -1040,6 +1063,7 @@ endef # This intentionally doesn't use the explicit installed file list, # seems too likely to change regularly. define uninstall_llvm_module -rm -rf "$(DESTDIR)${bitcodedir}/$(1)/" -rm -f "$(DESTDIR)${bitcodedir}/$(1).index.bc" +rm -rf '$(DESTDIR)${bitcodedir}/$(1)/' +rm -f '$(DESTDIR)${bitcodedir}/$(1).index.bc' + endef diff --git a/src/Makefile.shlib b/src/Makefile.shlib index 95b82a6dead..c4893edfc38 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -64,11 +64,6 @@ # # Got that? Look at src/interfaces/libpq/Makefile for an example. # -# While the linker allows creation of most shared libraries, -# -Bsymbolic requires resolution of all symbols, making the -# compiler a better choice for shared library creation on ELF platforms. -# With the linker, -Bsymbolic requires the crt1.o startup object file. -# bjm 2001-02-10 COMPILER = $(CC) $(CFLAGS) @@ -144,42 +139,42 @@ ifeq ($(PORTNAME), darwin) endif ifeq ($(PORTNAME), openbsd) - ifdef ELF_SYSTEM - LINK.shared = $(COMPILER) -shared - ifdef soname - LINK.shared += -Wl,-x,-soname,$(soname) - endif - SHLIB_LINK += -lc - else - LINK.shared = $(LD) -x -Bshareable -Bforcearchive + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) + endif + SHLIB_LINK += -lc endif ifeq ($(PORTNAME), freebsd) - ifdef ELF_SYSTEM - ifdef SO_MAJOR_VERSION - shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) - endif - LINK.shared = $(COMPILER) -shared - ifdef soname - LINK.shared += -Wl,-x,-soname,$(soname) - endif - else - ifdef SO_MAJOR_VERSION - shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION) - endif - LINK.shared = $(LD) -x -Bshareable -Bforcearchive + ifdef SO_MAJOR_VERSION + shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) + endif + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) endif endif ifeq ($(PORTNAME), netbsd) - ifdef ELF_SYSTEM - LINK.shared = $(COMPILER) -shared - ifdef soname - LINK.shared += -Wl,-x,-soname,$(soname) - endif - else - LINK.shared = $(LD) -x -Bshareable -Bforcearchive + LINK.shared = $(COMPILER) -shared + ifdef soname + LINK.shared += -Wl,-x,-soname,$(soname) + endif + BUILD.exports = ( echo '{ global:'; $(AWK) '/^[^\#]/ {printf "%s;\n",$$1}' $<; echo ' local: *; };' ) >$@ + exports_file = $(SHLIB_EXPORTS:%.txt=%.list) + ifneq (,$(exports_file)) + LINK.shared += -Wl,--version-script=$(exports_file) endif endif @@ -188,12 +183,12 @@ ifeq ($(PORTNAME), hpux) shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) endif ifeq ($(with_gnu_ld), yes) - LINK.shared = $(CC) -shared + LINK.shared = $(CC) -shared -Wl,-Bsymbolic ifdef soname LINK.shared += -Wl,-h -Wl,$(soname) endif else - LINK.shared = $(LD) -b + LINK.shared = $(LD) -b -Bsymbolic ifdef soname LINK.shared += +h $(soname) endif @@ -230,9 +225,9 @@ endif ifeq ($(PORTNAME), solaris) ifeq ($(GCC), yes) - LINK.shared = $(COMPILER) -shared + LINK.shared = $(COMPILER) -shared -Wl,-Bsymbolic else - LINK.shared = $(COMPILER) -G + LINK.shared = $(COMPILER) -G -Bsymbolic endif ifdef soname ifeq ($(with_gnu_ld), yes) @@ -277,11 +272,17 @@ all-static-lib: $(stlib) all-shared-lib: $(shlib) +# In this rule, "touch $@" works around a problem on some platforms wherein +# ranlib updates the library file's mod time with a value calculated to +# seconds precision. If the filesystem has sub-second timestamps, this can +# cause the library file to appear older than its input files, triggering +# parallel-make problems. ifndef haslibarule $(stlib): $(OBJS) | $(SHLIB_PREREQS) rm -f $@ $(LINK.static) $@ $^ $(RANLIB) $@ + touch $@ endif #haslibarule @@ -343,12 +344,11 @@ ifeq ($(PORTNAME), cygwin) # Cygwin case $(shlib): $(OBJS) | $(SHLIB_PREREQS) - $(CC) $(CFLAGS) -shared -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE) + $(CC) $(CFLAGS) -shared -o $@ -Wl,--out-implib=$(stlib) $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK) $(LIBS) $(LDAP_LIBS_BE) -$(stlib): $(OBJS) | $(SHLIB_PREREQS) - rm -f $@ - $(LINK.static) $@ $^ - $(RANLIB) $@ +# see notes in src/backend/parser/Makefile about use of this type of rule +$(stlib): $(shlib) + touch $@ else @@ -441,7 +441,7 @@ install-lib-static: $(stlib) installdirs-lib $(INSTALL_STLIB) $< '$(DESTDIR)$(libdir)/$(stlib)' ifeq ($(PORTNAME), darwin) cd '$(DESTDIR)$(libdir)' && \ - ranlib $(stlib) + $(RANLIB) $(stlib) endif install-lib-shared: $(shlib) installdirs-lib diff --git a/src/backend/Makefile b/src/backend/Makefile index 1aaf1ec2f59..b03d5e510f6 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -2,7 +2,7 @@ # # Makefile for the postgres backend # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/Makefile @@ -53,14 +53,14 @@ endif ########################################################################## -all: submake-libpgport submake-catalog-headers postgres $(POSTGRES_IMP) +all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $(POSTGRES_IMP) ifneq ($(PORTNAME), cygwin) ifneq ($(PORTNAME), win32) ifneq ($(PORTNAME), aix) postgres: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o $@ endif endif @@ -69,7 +69,7 @@ endif ifeq ($(PORTNAME), cygwin) postgres: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(call expand_subsys,$^) $(LIBS) -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@ # libpostgres.a is actually built in the preceding rule, but we need this to # ensure it's newer than postgres; see notes in src/backend/parser/Makefile @@ -82,7 +82,7 @@ ifeq ($(PORTNAME), win32) LIBS += -lsecur32 postgres: $(OBJS) $(WIN32RES) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LIBS) -o $@$(X) + $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LDFLAGS) $(LDFLAGS_EX) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@$(X) # libpostgres.a is actually built in the preceding rule, but we need this to # ensure it's newer than postgres; see notes in src/backend/parser/Makefile @@ -94,7 +94,7 @@ endif # win32 ifeq ($(PORTNAME), aix) postgres: $(POSTGRES_IMP) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(call expand_subsys,$(OBJS)) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@ + $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) $(LDFLAGS_EX) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@ $(POSTGRES_IMP): $(OBJS) $(LD) $(LDREL) $(LDOUT) SUBSYS.o $(call expand_subsys,$^) @@ -117,7 +117,7 @@ $(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport # The postgres.o target is needed by the rule in Makefile.global that # creates the exports file when MAKE_EXPORTS = true. postgres.o: $(OBJS) - $(CC) $(LDREL) $(LDFLAGS) $(LDFLAGS_EX) $(call expand_subsys,$^) $(LIBS) -o $@ + $(CC) $(LDREL) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@ # The following targets are specified in make commands that appear in @@ -136,24 +136,15 @@ parser/gram.h: parser/gram.y storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl storage/lmgr/lwlocknames.txt $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c -utils/errcodes.h: utils/generate-errcodes.pl utils/errcodes.txt - $(MAKE) -C utils errcodes.h - -# see notes in src/backend/parser/Makefile -utils/fmgrprotos.h: utils/fmgroids.h - touch $@ - -utils/fmgroids.h: utils/Gen_fmgrtab.pl catalog/Catalog.pm $(top_srcdir)/src/include/catalog/pg_proc.dat $(top_srcdir)/src/include/access/transam.h - $(MAKE) -C utils fmgroids.h fmgrprotos.h - -utils/probes.h: utils/probes.d - $(MAKE) -C utils probes.h - # run this unconditionally to avoid needing to know its dependencies here: submake-catalog-headers: $(MAKE) -C catalog distprep generated-header-symlinks -.PHONY: submake-catalog-headers +# run this unconditionally to avoid needing to know its dependencies here: +submake-utils-headers: + $(MAKE) -C utils distprep generated-header-symlinks + +.PHONY: submake-catalog-headers submake-utils-headers # Make symlinks for these headers in the include directory. That way # we can cut down on the -I options. Also, a symlink is automatically @@ -168,7 +159,7 @@ submake-catalog-headers: .PHONY: generated-headers -generated-headers: $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/storage/lwlocknames.h $(top_builddir)/src/include/utils/errcodes.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/fmgrprotos.h $(top_builddir)/src/include/utils/probes.h submake-catalog-headers +generated-headers: $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/storage/lwlocknames.h submake-catalog-headers submake-utils-headers $(top_builddir)/src/include/parser/gram.h: parser/gram.h prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \ @@ -180,26 +171,6 @@ $(top_builddir)/src/include/storage/lwlocknames.h: storage/lmgr/lwlocknames.h cd '$(dir $@)' && rm -f $(notdir $@) && \ $(LN_S) "$$prereqdir/$(notdir $<)" . -$(top_builddir)/src/include/utils/errcodes.h: utils/errcodes.h - prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \ - cd '$(dir $@)' && rm -f $(notdir $@) && \ - $(LN_S) "$$prereqdir/$(notdir $<)" . - -$(top_builddir)/src/include/utils/fmgroids.h: utils/fmgroids.h - prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \ - cd '$(dir $@)' && rm -f $(notdir $@) && \ - $(LN_S) "$$prereqdir/$(notdir $<)" . - -$(top_builddir)/src/include/utils/fmgrprotos.h: utils/fmgrprotos.h - prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \ - cd '$(dir $@)' && rm -f $(notdir $@) && \ - $(LN_S) "$$prereqdir/$(notdir $<)" . - -$(top_builddir)/src/include/utils/probes.h: utils/probes.h - cd '$(dir $@)' && rm -f $(notdir $@) && \ - $(LN_S) "../../../$(subdir)/utils/probes.h" . - - utils/probes.o: utils/probes.d $(SUBDIROBJS) $(DTRACE) $(DTRACEFLAGS) -C -G -s $(call expand_subsys,$^) -o $@ @@ -213,7 +184,8 @@ distprep: $(MAKE) -C catalog distprep $(MAKE) -C replication repl_gram.c repl_scanner.c syncrep_gram.c syncrep_scanner.c $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c - $(MAKE) -C utils fmgrtab.c fmgroids.h fmgrprotos.h errcodes.h + $(MAKE) -C utils distprep + $(MAKE) -C utils/adt jsonpath_gram.c jsonpath_scan.c $(MAKE) -C utils/misc guc-file.c $(MAKE) -C utils/sort qsort_tuple.c @@ -237,7 +209,6 @@ endif $(INSTALL_DATA) $(srcdir)/libpq/pg_hba.conf.sample '$(DESTDIR)$(datadir)/pg_hba.conf.sample' $(INSTALL_DATA) $(srcdir)/libpq/pg_ident.conf.sample '$(DESTDIR)$(datadir)/pg_ident.conf.sample' $(INSTALL_DATA) $(srcdir)/utils/misc/postgresql.conf.sample '$(DESTDIR)$(datadir)/postgresql.conf.sample' - $(INSTALL_DATA) $(srcdir)/access/transam/recovery.conf.sample '$(DESTDIR)$(datadir)/recovery.conf.sample' ifeq ($(with_llvm), yes) install-bin: install-postgres-bitcode @@ -302,8 +273,7 @@ endif $(MAKE) -C utils uninstall-data rm -f '$(DESTDIR)$(datadir)/pg_hba.conf.sample' \ '$(DESTDIR)$(datadir)/pg_ident.conf.sample' \ - '$(DESTDIR)$(datadir)/postgresql.conf.sample' \ - '$(DESTDIR)$(datadir)/recovery.conf.sample' + '$(DESTDIR)$(datadir)/postgresql.conf.sample' ifeq ($(with_llvm), yes) $(call uninstall_llvm_module,postgres) endif @@ -321,10 +291,11 @@ ifeq ($(PORTNAME), win32) endif distclean: clean - rm -f port/tas.s port/dynloader.c port/pg_sema.c port/pg_shmem.c + rm -f port/tas.s port/pg_sema.c port/pg_shmem.c maintainer-clean: distclean $(MAKE) -C catalog $@ + $(MAKE) -C utils $@ rm -f bootstrap/bootparse.c \ bootstrap/bootscanner.c \ parser/gram.c \ @@ -336,10 +307,8 @@ maintainer-clean: distclean replication/syncrep_scanner.c \ storage/lmgr/lwlocknames.c \ storage/lmgr/lwlocknames.h \ - utils/fmgroids.h \ - utils/fmgrprotos.h \ - utils/fmgrtab.c \ - utils/errcodes.h \ + utils/adt/jsonpath_gram.c \ + utils/adt/jsonpath_scan.c \ utils/misc/guc-file.c \ utils/sort/qsort_tuple.c @@ -352,4 +321,4 @@ maintainer-clean: distclean # are up to date. It saves the time of doing all the submakes. .PHONY: quick quick: $(OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(call expand_subsys,$^) $(LIBS) -o postgres + $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o postgres diff --git a/src/backend/access/Makefile b/src/backend/access/Makefile index bd93a6a8d1e..0880e0a8bbb 100644 --- a/src/backend/access/Makefile +++ b/src/backend/access/Makefile @@ -9,6 +9,6 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global SUBDIRS = brin common gin gist hash heap index nbtree rmgrdesc spgist \ - tablesample transam + table tablesample transam include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c index e716f51503c..ae7b729edd9 100644 --- a/src/backend/access/brin/brin.c +++ b/src/backend/access/brin/brin.c @@ -4,7 +4,7 @@ * * See src/backend/access/brin/README for details. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,8 +19,11 @@ #include "access/brin_page.h" #include "access/brin_pageops.h" #include "access/brin_xlog.h" +#include "access/relation.h" #include "access/reloptions.h" #include "access/relscan.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/xloginsert.h" #include "catalog/index.h" #include "catalog/pg_am.h" @@ -64,13 +67,13 @@ typedef struct BrinOpaque #define BRIN_ALL_BLOCKRANGES InvalidBlockNumber static BrinBuildState *initialize_brin_buildstate(Relation idxRel, - BrinRevmap *revmap, BlockNumber pagesPerRange); + BrinRevmap *revmap, BlockNumber pagesPerRange); static void terminate_brin_buildstate(BrinBuildState *state); static void brinsummarize(Relation index, Relation heapRel, BlockNumber pageRange, - bool include_partial, double *numSummarized, double *numExisting); + bool include_partial, double *numSummarized, double *numExisting); static void form_and_insert_tuple(BrinBuildState *state); static void union_tuples(BrinDesc *bdesc, BrinMemTuple *a, - BrinTuple *b); + BrinTuple *b); static void brin_vacuum_scan(Relation idxrel, BufferAccessStrategy strategy); @@ -109,6 +112,7 @@ brinhandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = brincostestimate; amroutine->amoptions = brinoptions; amroutine->amproperty = NULL; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = brinvalidate; amroutine->ambeginscan = brinbeginscan; amroutine->amrescan = brinrescan; @@ -189,7 +193,7 @@ brininsert(Relation idxRel, Datum *values, bool *nulls, NULL, BUFFER_LOCK_SHARE, NULL); if (!lastPageTuple) { - bool recorded; + bool recorded; recorded = AutoVacuumRequestWork(AVW_BRINSummarizeRange, RelationGetRelid(idxRel), @@ -388,9 +392,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) * iterate on the revmap. */ heapOid = IndexGetRelation(RelationGetRelid(idxRel), false); - heapRel = heap_open(heapOid, AccessShareLock); + heapRel = table_open(heapOid, AccessShareLock); nblocks = RelationGetNumberOfBlocks(heapRel); - heap_close(heapRel, AccessShareLock); + table_close(heapRel, AccessShareLock); /* * Make room for the consistent support procedures of indexed columns. We @@ -585,7 +589,7 @@ brinendscan(IndexScanDesc scan) } /* - * Per-heap-tuple callback for IndexBuildHeapScan. + * Per-heap-tuple callback for table_index_build_scan. * * Note we don't worry about the page range at the end of the table here; it is * present in the build state struct after we're called the last time, but not @@ -716,8 +720,8 @@ brinbuild(Relation heap, Relation index, IndexInfo *indexInfo) * Now scan the relation. No syncscan allowed here because we want the * heap blocks in physical order. */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, false, - brinbuildCallback, (void *) state, NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, false, true, + brinbuildCallback, (void *) state, NULL); /* process the final batch */ form_and_insert_tuple(state); @@ -797,15 +801,15 @@ brinvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) stats->num_pages = RelationGetNumberOfBlocks(info->index); /* rest of stats is initialized by zeroing */ - heapRel = heap_open(IndexGetRelation(RelationGetRelid(info->index), false), - AccessShareLock); + heapRel = table_open(IndexGetRelation(RelationGetRelid(info->index), false), + AccessShareLock); brin_vacuum_scan(info->index, info->strategy); brinsummarize(info->index, heapRel, BRIN_ALL_BLOCKRANGES, false, &stats->num_index_tuples, &stats->num_index_tuples); - heap_close(heapRel, AccessShareLock); + table_close(heapRel, AccessShareLock); return stats; } @@ -871,6 +875,12 @@ brin_summarize_range(PG_FUNCTION_ARGS) Relation heapRel; double numSummarized = 0; + if (RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is in progress"), + errhint("BRIN control functions cannot be executed during recovery."))); + if (heapBlk64 > BRIN_ALL_BLOCKRANGES || heapBlk64 < 0) { char *blk = psprintf(INT64_FORMAT, heapBlk64); @@ -889,7 +899,7 @@ brin_summarize_range(PG_FUNCTION_ARGS) */ heapoid = IndexGetRelation(indexoid, true); if (OidIsValid(heapoid)) - heapRel = heap_open(heapoid, ShareUpdateExclusiveLock); + heapRel = table_open(heapoid, ShareUpdateExclusiveLock); else heapRel = NULL; @@ -942,6 +952,12 @@ brin_desummarize_range(PG_FUNCTION_ARGS) Relation indexRel; bool done; + if (RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is in progress"), + errhint("BRIN control functions cannot be executed during recovery."))); + if (heapBlk64 > MaxBlockNumber || heapBlk64 < 0) { char *blk = psprintf(INT64_FORMAT, heapBlk64); @@ -960,7 +976,7 @@ brin_desummarize_range(PG_FUNCTION_ARGS) */ heapoid = IndexGetRelation(indexoid, true); if (OidIsValid(heapoid)) - heapRel = heap_open(heapoid, ShareUpdateExclusiveLock); + heapRel = table_open(heapoid, ShareUpdateExclusiveLock); else heapRel = NULL; @@ -1216,13 +1232,14 @@ summarize_range(IndexInfo *indexInfo, BrinBuildState *state, Relation heapRel, * short of brinbuildCallback creating the new index entry. * * Note that it is critical we use the "any visible" mode of - * IndexBuildHeapRangeScan here: otherwise, we would miss tuples inserted - * by transactions that are still in progress, among other corner cases. + * table_index_build_range_scan here: otherwise, we would miss tuples + * inserted by transactions that are still in progress, among other corner + * cases. */ state->bs_currRangeStart = heapBlk; - IndexBuildHeapRangeScan(heapRel, state->bs_irel, indexInfo, false, true, - heapBlk, scanNumBlks, - brinbuildCallback, (void *) state, NULL); + table_index_build_range_scan(heapRel, state->bs_irel, indexInfo, false, true, false, + heapBlk, scanNumBlks, + brinbuildCallback, (void *) state, NULL); /* * Now we update the values obtained by the scan with the placeholder diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c index 6ce355c6a97..86788024ef6 100644 --- a/src/backend/access/brin/brin_inclusion.c +++ b/src/backend/access/brin/brin_inclusion.c @@ -16,7 +16,7 @@ * writing is the INET type, where IPv6 values cannot be merged with IPv4 * values. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -82,9 +82,9 @@ typedef struct InclusionOpaque } InclusionOpaque; static FmgrInfo *inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, - uint16 procnum); + uint16 procnum); static FmgrInfo *inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, - Oid subtype, uint16 strategynum); + Oid subtype, uint16 strategynum); /* @@ -432,7 +432,7 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS) * It is straightforward to support the equality strategies with * the contains operator. Generally, inequality strategies do not * make much sense for the types which will be used with the - * inclusion BRIN family of opclasses, but is possible to + * inclusion BRIN family of opclasses, but it is possible to * implement them with logical negation of the left-of and * right-of operators. * diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c index 0f6aa33a45b..ad0d18ed39f 100644 --- a/src/backend/access/brin/brin_minmax.c +++ b/src/backend/access/brin/brin_minmax.c @@ -2,7 +2,7 @@ * brin_minmax.c * Implementation of Min/Max opclass for BRIN * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -30,7 +30,7 @@ typedef struct MinmaxOpaque } MinmaxOpaque; static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno, - Oid subtype, uint16 strategynum); + Oid subtype, uint16 strategynum); Datum diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c index 040cb62e55f..f907b4bc297 100644 --- a/src/backend/access/brin/brin_pageops.c +++ b/src/backend/access/brin/brin_pageops.c @@ -2,7 +2,7 @@ * brin_pageops.c * Page-handling routines for BRIN indexes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -34,7 +34,7 @@ MAXALIGN(sizeof(BrinSpecialSpace)))) static Buffer brin_getinsertbuffer(Relation irel, Buffer oldbuf, Size itemsz, - bool *extended); + bool *extended); static Size br_page_get_freespace(Page page); static void brin_initialize_empty_new_buffer(Relation idxrel, Buffer buffer); @@ -178,7 +178,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, brin_can_do_samepage_update(oldbuf, origsz, newsz)) { START_CRIT_SECTION(); - if (!PageIndexTupleOverwrite(oldpage, oldoff, (Item) newtup, newsz)) + if (!PageIndexTupleOverwrite(oldpage, oldoff, (Item) unconstify(BrinTuple *, newtup), newsz)) elog(ERROR, "failed to replace BRIN tuple"); MarkBufferDirty(oldbuf); @@ -195,7 +195,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, XLogRegisterData((char *) &xlrec, SizeOfBrinSamepageUpdate); XLogRegisterBuffer(0, oldbuf, REGBUF_STANDARD); - XLogRegisterBufData(0, (char *) newtup, newsz); + XLogRegisterBufData(0, (char *) unconstify(BrinTuple *, newtup), newsz); recptr = XLogInsert(RM_BRIN_ID, info); @@ -252,7 +252,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, brin_page_init(newpage, BRIN_PAGETYPE_REGULAR); PageIndexTupleDeleteNoCompact(oldpage, oldoff); - newoff = PageAddItem(newpage, (Item) newtup, newsz, + newoff = PageAddItem(newpage, (Item) unconstify(BrinTuple *, newtup), newsz, InvalidOffsetNumber, false, false); if (newoff == InvalidOffsetNumber) elog(ERROR, "failed to add BRIN tuple to new page"); @@ -287,7 +287,7 @@ brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, XLogRegisterData((char *) &xlrec, SizeOfBrinUpdate); XLogRegisterBuffer(0, newbuf, REGBUF_STANDARD | (extended ? REGBUF_WILL_INIT : 0)); - XLogRegisterBufData(0, (char *) newtup, newsz); + XLogRegisterBufData(0, (char *) unconstify(BrinTuple *, newtup), newsz); /* revmap page */ XLogRegisterBuffer(1, revmapbuf, 0); diff --git a/src/backend/access/brin/brin_revmap.c b/src/backend/access/brin/brin_revmap.c index f0dd72ac67f..647350c1018 100644 --- a/src/backend/access/brin/brin_revmap.c +++ b/src/backend/access/brin/brin_revmap.c @@ -12,7 +12,7 @@ * the metapage. When the revmap needs to be expanded, all tuples on the * regular BRIN page at that block (if any) are moved out of the way. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -57,10 +57,10 @@ struct BrinRevmap static BlockNumber revmap_get_blkno(BrinRevmap *revmap, - BlockNumber heapBlk); + BlockNumber heapBlk); static Buffer revmap_get_buffer(BrinRevmap *revmap, BlockNumber heapBlk); static BlockNumber revmap_extend_and_get_blkno(BrinRevmap *revmap, - BlockNumber heapBlk); + BlockNumber heapBlk); static void revmap_physical_extend(BrinRevmap *revmap); /* @@ -395,9 +395,10 @@ brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk) */ /* - * Because of SUE lock, this function shouldn't run concurrently with - * summarization. Placeholder tuples can only exist as leftovers from - * crashed summarization, so if we detect any, we complain but proceed. + * Because of ShareUpdateExclusive lock, this function shouldn't run + * concurrently with summarization. Placeholder tuples can only exist as + * leftovers from crashed summarization, so if we detect any, we complain + * but proceed. */ if (BrinTupleIsPlaceholder(tup)) ereport(WARNING, diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c index 00316b899c8..2b3861710c3 100644 --- a/src/backend/access/brin/brin_tuple.c +++ b/src/backend/access/brin/brin_tuple.c @@ -1,5 +1,5 @@ /* - * brin_tuples.c + * brin_tuple.c * Method implementations for tuples in BRIN indexes. * * Intended usage is that code outside this file only deals with @@ -23,7 +23,7 @@ * Note the size of the null bitmask may not be the same as that of the * datum array. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -40,8 +40,8 @@ static inline void brin_deconstruct_tuple(BrinDesc *brdesc, - char *tp, bits8 *nullbits, bool nulls, - Datum *values, bool *allnulls, bool *hasnulls); + char *tp, bits8 *nullbits, bool nulls, + Datum *values, bool *allnulls, bool *hasnulls); /* @@ -62,7 +62,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc) /* make sure it's in the bdesc's context */ oldcxt = MemoryContextSwitchTo(brdesc->bd_context); - tupdesc = CreateTemplateTupleDesc(brdesc->bd_totalstored, false); + tupdesc = CreateTemplateTupleDesc(brdesc->bd_totalstored); for (i = 0; i < brdesc->bd_tupdesc->natts; i++) { @@ -207,7 +207,7 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple, /* * Note that we reverse the sense of null bits in this module: we * store a 1 for a null attribute rather than a 0. So we must reverse - * the sense of the att_isnull test in br_deconstruct_tuple as well. + * the sense of the att_isnull test in brin_deconstruct_tuple as well. */ bitP = ((bits8 *) ((char *) rettuple + SizeOfBrinTuple)) - 1; bitmask = HIGHBIT; diff --git a/src/backend/access/brin/brin_validate.c b/src/backend/access/brin/brin_validate.c index 35f6ccacced..012933833bd 100644 --- a/src/backend/access/brin/brin_validate.c +++ b/src/backend/access/brin/brin_validate.c @@ -3,7 +3,7 @@ * brin_validate.c * Opclass validator for BRIN. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/brin/brin_xlog.c b/src/backend/access/brin/brin_xlog.c index b2871e78aa6..db1f47ca218 100644 --- a/src/backend/access/brin/brin_xlog.c +++ b/src/backend/access/brin/brin_xlog.c @@ -2,7 +2,7 @@ * brin_xlog.c * XLog replay routines for BRIN indexes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/common/Makefile b/src/backend/access/common/Makefile index f130b6e3501..9ac19d9f9e5 100644 --- a/src/backend/access/common/Makefile +++ b/src/backend/access/common/Makefile @@ -12,7 +12,8 @@ subdir = src/backend/access/common top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = bufmask.o heaptuple.o indextuple.o printsimple.o printtup.o \ - reloptions.o scankey.o session.o tupconvert.o tupdesc.o +OBJS = bufmask.o detoast.o heaptuple.o indextuple.o printsimple.o \ + printtup.o relation.o reloptions.o scankey.o session.o toast_internals.o \ + tupconvert.o tupdesc.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/common/bufmask.c b/src/backend/access/common/bufmask.c index 57021f6ca1a..bcd9bd007b7 100644 --- a/src/backend/access/common/bufmask.c +++ b/src/backend/access/common/bufmask.c @@ -5,12 +5,12 @@ * in a page which can be different when the WAL is generated * and when the WAL is applied. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * Contains common routines required for masking a page. * * IDENTIFICATION - * src/backend/storage/buffer/bufmask.c + * src/backend/access/common/bufmask.c * *------------------------------------------------------------------------- */ @@ -20,7 +20,7 @@ #include "access/bufmask.h" /* - * mask_page_lsn + * mask_page_lsn_and_checksum * * In consistency checks, the LSN of the two pages compared will likely be * different because of concurrent operations when the WAL is generated and diff --git a/src/backend/access/common/detoast.c b/src/backend/access/common/detoast.c new file mode 100644 index 00000000000..47a03fa98b9 --- /dev/null +++ b/src/backend/access/common/detoast.c @@ -0,0 +1,907 @@ +/*------------------------------------------------------------------------- + * + * detoast.c + * Retrieve compressed or external variable size attributes. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/access/common/detoast.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/detoast.h" +#include "access/genam.h" +#include "access/heaptoast.h" +#include "access/table.h" +#include "access/toast_internals.h" +#include "common/pg_lzcompress.h" +#include "utils/expandeddatum.h" +#include "utils/fmgroids.h" +#include "utils/rel.h" + +static struct varlena *toast_fetch_datum(struct varlena *attr); +static struct varlena *toast_fetch_datum_slice(struct varlena *attr, + int32 sliceoffset, int32 length); +static struct varlena *toast_decompress_datum(struct varlena *attr); +static struct varlena *toast_decompress_datum_slice(struct varlena *attr, int32 slicelength); + +/* ---------- + * heap_tuple_fetch_attr - + * + * Public entry point to get back a toasted value from + * external source (possibly still in compressed format). + * + * This will return a datum that contains all the data internally, ie, not + * relying on external storage or memory, but it can still be compressed or + * have a short header. Note some callers assume that if the input is an + * EXTERNAL datum, the result will be a pfree'able chunk. + * ---------- + */ +struct varlena * +heap_tuple_fetch_attr(struct varlena *attr) +{ + struct varlena *result; + + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + /* + * This is an external stored plain value + */ + result = toast_fetch_datum(attr); + } + else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) + { + /* + * This is an indirect pointer --- dereference it + */ + struct varatt_indirect redirect; + + VARATT_EXTERNAL_GET_POINTER(redirect, attr); + attr = (struct varlena *) redirect.pointer; + + /* nested indirect Datums aren't allowed */ + Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); + + /* recurse if value is still external in some other way */ + if (VARATT_IS_EXTERNAL(attr)) + return heap_tuple_fetch_attr(attr); + + /* + * Copy into the caller's memory context, in case caller tries to + * pfree the result. + */ + result = (struct varlena *) palloc(VARSIZE_ANY(attr)); + memcpy(result, attr, VARSIZE_ANY(attr)); + } + else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) + { + /* + * This is an expanded-object pointer --- get flat format + */ + ExpandedObjectHeader *eoh; + Size resultsize; + + eoh = DatumGetEOHP(PointerGetDatum(attr)); + resultsize = EOH_get_flat_size(eoh); + result = (struct varlena *) palloc(resultsize); + EOH_flatten_into(eoh, (void *) result, resultsize); + } + else + { + /* + * This is a plain value inside of the main tuple - why am I called? + */ + result = attr; + } + + return result; +} + + +/* ---------- + * heap_tuple_untoast_attr - + * + * Public entry point to get back a toasted value from compression + * or external storage. The result is always non-extended varlena form. + * + * Note some callers assume that if the input is an EXTERNAL or COMPRESSED + * datum, the result will be a pfree'able chunk. + * ---------- + */ +struct varlena * +heap_tuple_untoast_attr(struct varlena *attr) +{ + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + /* + * This is an externally stored datum --- fetch it back from there + */ + attr = toast_fetch_datum(attr); + /* If it's compressed, decompress it */ + if (VARATT_IS_COMPRESSED(attr)) + { + struct varlena *tmp = attr; + + attr = toast_decompress_datum(tmp); + pfree(tmp); + } + } + else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) + { + /* + * This is an indirect pointer --- dereference it + */ + struct varatt_indirect redirect; + + VARATT_EXTERNAL_GET_POINTER(redirect, attr); + attr = (struct varlena *) redirect.pointer; + + /* nested indirect Datums aren't allowed */ + Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); + + /* recurse in case value is still extended in some other way */ + attr = heap_tuple_untoast_attr(attr); + + /* if it isn't, we'd better copy it */ + if (attr == (struct varlena *) redirect.pointer) + { + struct varlena *result; + + result = (struct varlena *) palloc(VARSIZE_ANY(attr)); + memcpy(result, attr, VARSIZE_ANY(attr)); + attr = result; + } + } + else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) + { + /* + * This is an expanded-object pointer --- get flat format + */ + attr = heap_tuple_fetch_attr(attr); + /* flatteners are not allowed to produce compressed/short output */ + Assert(!VARATT_IS_EXTENDED(attr)); + } + else if (VARATT_IS_COMPRESSED(attr)) + { + /* + * This is a compressed value inside of the main tuple + */ + attr = toast_decompress_datum(attr); + } + else if (VARATT_IS_SHORT(attr)) + { + /* + * This is a short-header varlena --- convert to 4-byte header format + */ + Size data_size = VARSIZE_SHORT(attr) - VARHDRSZ_SHORT; + Size new_size = data_size + VARHDRSZ; + struct varlena *new_attr; + + new_attr = (struct varlena *) palloc(new_size); + SET_VARSIZE(new_attr, new_size); + memcpy(VARDATA(new_attr), VARDATA_SHORT(attr), data_size); + attr = new_attr; + } + + return attr; +} + + +/* ---------- + * heap_tuple_untoast_attr_slice - + * + * Public entry point to get back part of a toasted value + * from compression or external storage. + * + * Note: When slicelength is negative, return suffix of the value. + * ---------- + */ +struct varlena * +heap_tuple_untoast_attr_slice(struct varlena *attr, + int32 sliceoffset, int32 slicelength) +{ + struct varlena *preslice; + struct varlena *result; + char *attrdata; + int32 attrsize; + + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + struct varatt_external toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* fast path for non-compressed external datums */ + if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) + return toast_fetch_datum_slice(attr, sliceoffset, slicelength); + + /* + * For compressed values, we need to fetch enough slices to decompress + * at least the requested part (when a prefix is requested). Otherwise, + * just fetch all slices. + */ + if (slicelength > 0 && sliceoffset >= 0) + { + int32 max_size; + + /* + * Determine maximum amount of compressed data needed for a prefix + * of a given length (after decompression). + */ + max_size = pglz_maximum_compressed_size(sliceoffset + slicelength, + TOAST_COMPRESS_SIZE(attr)); + + /* + * Fetch enough compressed slices (compressed marker will get set + * automatically). + */ + preslice = toast_fetch_datum_slice(attr, 0, max_size); + } + else + preslice = toast_fetch_datum(attr); + } + else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) + { + struct varatt_indirect redirect; + + VARATT_EXTERNAL_GET_POINTER(redirect, attr); + + /* nested indirect Datums aren't allowed */ + Assert(!VARATT_IS_EXTERNAL_INDIRECT(redirect.pointer)); + + return heap_tuple_untoast_attr_slice(redirect.pointer, + sliceoffset, slicelength); + } + else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) + { + /* pass it off to heap_tuple_fetch_attr to flatten */ + preslice = heap_tuple_fetch_attr(attr); + } + else + preslice = attr; + + Assert(!VARATT_IS_EXTERNAL(preslice)); + + if (VARATT_IS_COMPRESSED(preslice)) + { + struct varlena *tmp = preslice; + + /* Decompress enough to encompass the slice and the offset */ + if (slicelength > 0 && sliceoffset >= 0) + preslice = toast_decompress_datum_slice(tmp, slicelength + sliceoffset); + else + preslice = toast_decompress_datum(tmp); + + if (tmp != attr) + pfree(tmp); + } + + if (VARATT_IS_SHORT(preslice)) + { + attrdata = VARDATA_SHORT(preslice); + attrsize = VARSIZE_SHORT(preslice) - VARHDRSZ_SHORT; + } + else + { + attrdata = VARDATA(preslice); + attrsize = VARSIZE(preslice) - VARHDRSZ; + } + + /* slicing of datum for compressed cases and plain value */ + + if (sliceoffset >= attrsize) + { + sliceoffset = 0; + slicelength = 0; + } + + if (((sliceoffset + slicelength) > attrsize) || slicelength < 0) + slicelength = attrsize - sliceoffset; + + result = (struct varlena *) palloc(slicelength + VARHDRSZ); + SET_VARSIZE(result, slicelength + VARHDRSZ); + + memcpy(VARDATA(result), attrdata + sliceoffset, slicelength); + + if (preslice != attr) + pfree(preslice); + + return result; +} + +/* ---------- + * toast_fetch_datum - + * + * Reconstruct an in memory Datum from the chunks saved + * in the toast relation + * ---------- + */ +static struct varlena * +toast_fetch_datum(struct varlena *attr) +{ + Relation toastrel; + Relation *toastidxs; + ScanKeyData toastkey; + SysScanDesc toastscan; + HeapTuple ttup; + TupleDesc toasttupDesc; + struct varlena *result; + struct varatt_external toast_pointer; + int32 ressize; + int32 residx, + nextidx; + int32 numchunks; + Pointer chunk; + bool isnull; + char *chunkdata; + int32 chunksize; + int num_indexes; + int validIndex; + SnapshotData SnapshotToast; + + if (!VARATT_IS_EXTERNAL_ONDISK(attr)) + elog(ERROR, "toast_fetch_datum shouldn't be called for non-ondisk datums"); + + /* Must copy to access aligned fields */ + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + ressize = toast_pointer.va_extsize; + numchunks = ((ressize - 1) / TOAST_MAX_CHUNK_SIZE) + 1; + + result = (struct varlena *) palloc(ressize + VARHDRSZ); + + if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) + SET_VARSIZE_COMPRESSED(result, ressize + VARHDRSZ); + else + SET_VARSIZE(result, ressize + VARHDRSZ); + + /* + * Open the toast relation and its indexes + */ + toastrel = table_open(toast_pointer.va_toastrelid, AccessShareLock); + toasttupDesc = toastrel->rd_att; + + /* Look for the valid index of the toast relation */ + validIndex = toast_open_indexes(toastrel, + AccessShareLock, + &toastidxs, + &num_indexes); + + /* + * Setup a scan key to fetch from the index by va_valueid + */ + ScanKeyInit(&toastkey, + (AttrNumber) 1, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(toast_pointer.va_valueid)); + + /* + * Read the chunks by index + * + * Note that because the index is actually on (valueid, chunkidx) we will + * see the chunks in chunkidx order, even though we didn't explicitly ask + * for it. + */ + nextidx = 0; + + init_toast_snapshot(&SnapshotToast); + toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], + &SnapshotToast, 1, &toastkey); + while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) + { + /* + * Have a chunk, extract the sequence number and the data + */ + residx = DatumGetInt32(fastgetattr(ttup, 2, toasttupDesc, &isnull)); + Assert(!isnull); + chunk = DatumGetPointer(fastgetattr(ttup, 3, toasttupDesc, &isnull)); + Assert(!isnull); + if (!VARATT_IS_EXTENDED(chunk)) + { + chunksize = VARSIZE(chunk) - VARHDRSZ; + chunkdata = VARDATA(chunk); + } + else if (VARATT_IS_SHORT(chunk)) + { + /* could happen due to heap_form_tuple doing its thing */ + chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT; + chunkdata = VARDATA_SHORT(chunk); + } + else + { + /* should never happen */ + elog(ERROR, "found toasted toast chunk for toast value %u in %s", + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + chunksize = 0; /* keep compiler quiet */ + chunkdata = NULL; + } + + /* + * Some checks on the data we've found + */ + if (residx != nextidx) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk number %d (expected %d) for toast value %u in %s", + residx, nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); + if (residx < numchunks - 1) + { + if (chunksize != TOAST_MAX_CHUNK_SIZE) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s", + chunksize, (int) TOAST_MAX_CHUNK_SIZE, + residx, numchunks, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); + } + else if (residx == numchunks - 1) + { + if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != ressize) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s", + chunksize, + (int) (ressize - residx * TOAST_MAX_CHUNK_SIZE), + residx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", + residx, + 0, numchunks - 1, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); + + /* + * Copy the data into proper place in our result + */ + memcpy(VARDATA(result) + residx * TOAST_MAX_CHUNK_SIZE, + chunkdata, + chunksize); + + nextidx++; + } + + /* + * Final checks that we successfully fetched the datum + */ + if (nextidx != numchunks) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("missing chunk number %d for toast value %u in %s", + nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)))); + + /* + * End scan and close relations + */ + systable_endscan_ordered(toastscan); + toast_close_indexes(toastidxs, num_indexes, AccessShareLock); + table_close(toastrel, AccessShareLock); + + return result; +} + +/* ---------- + * toast_fetch_datum_slice - + * + * Reconstruct a segment of a Datum from the chunks saved + * in the toast relation + * + * Note that this function supports non-compressed external datums + * and compressed external datums (in which case the requrested slice + * has to be a prefix, i.e. sliceoffset has to be 0). + * ---------- + */ +static struct varlena * +toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, int32 length) +{ + Relation toastrel; + Relation *toastidxs; + ScanKeyData toastkey[3]; + int nscankeys; + SysScanDesc toastscan; + HeapTuple ttup; + TupleDesc toasttupDesc; + struct varlena *result; + struct varatt_external toast_pointer; + int32 attrsize; + int32 residx; + int32 nextidx; + int numchunks; + int startchunk; + int endchunk; + int32 startoffset; + int32 endoffset; + int totalchunks; + Pointer chunk; + bool isnull; + char *chunkdata; + int32 chunksize; + int32 chcpystrt; + int32 chcpyend; + int num_indexes; + int validIndex; + SnapshotData SnapshotToast; + + if (!VARATT_IS_EXTERNAL_ONDISK(attr)) + elog(ERROR, "toast_fetch_datum_slice shouldn't be called for non-ondisk datums"); + + /* Must copy to access aligned fields */ + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* + * It's nonsense to fetch slices of a compressed datum unless when it's + * a prefix -- this isn't lo_* we can't return a compressed datum which + * is meaningful to toast later. + */ + Assert(!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) || 0 == sliceoffset); + + attrsize = toast_pointer.va_extsize; + totalchunks = ((attrsize - 1) / TOAST_MAX_CHUNK_SIZE) + 1; + + if (sliceoffset >= attrsize) + { + sliceoffset = 0; + length = 0; + } + + /* + * When fetching a prefix of a compressed external datum, account for the + * rawsize tracking amount of raw data, which is stored at the beginning + * as an int32 value). + */ + if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) && length > 0) + length = length + sizeof(int32); + + if (((sliceoffset + length) > attrsize) || length < 0) + length = attrsize - sliceoffset; + + result = (struct varlena *) palloc(length + VARHDRSZ); + + if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) + SET_VARSIZE_COMPRESSED(result, length + VARHDRSZ); + else + SET_VARSIZE(result, length + VARHDRSZ); + + if (length == 0) + return result; /* Can save a lot of work at this point! */ + + startchunk = sliceoffset / TOAST_MAX_CHUNK_SIZE; + endchunk = (sliceoffset + length - 1) / TOAST_MAX_CHUNK_SIZE; + numchunks = (endchunk - startchunk) + 1; + + startoffset = sliceoffset % TOAST_MAX_CHUNK_SIZE; + endoffset = (sliceoffset + length - 1) % TOAST_MAX_CHUNK_SIZE; + + /* + * Open the toast relation and its indexes + */ + toastrel = table_open(toast_pointer.va_toastrelid, AccessShareLock); + toasttupDesc = toastrel->rd_att; + + /* Look for the valid index of toast relation */ + validIndex = toast_open_indexes(toastrel, + AccessShareLock, + &toastidxs, + &num_indexes); + + /* + * Setup a scan key to fetch from the index. This is either two keys or + * three depending on the number of chunks. + */ + ScanKeyInit(&toastkey[0], + (AttrNumber) 1, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(toast_pointer.va_valueid)); + + /* + * Use equality condition for one chunk, a range condition otherwise: + */ + if (numchunks == 1) + { + ScanKeyInit(&toastkey[1], + (AttrNumber) 2, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(startchunk)); + nscankeys = 2; + } + else + { + ScanKeyInit(&toastkey[1], + (AttrNumber) 2, + BTGreaterEqualStrategyNumber, F_INT4GE, + Int32GetDatum(startchunk)); + ScanKeyInit(&toastkey[2], + (AttrNumber) 2, + BTLessEqualStrategyNumber, F_INT4LE, + Int32GetDatum(endchunk)); + nscankeys = 3; + } + + /* + * Read the chunks by index + * + * The index is on (valueid, chunkidx) so they will come in order + */ + init_toast_snapshot(&SnapshotToast); + nextidx = startchunk; + toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], + &SnapshotToast, nscankeys, toastkey); + while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) + { + /* + * Have a chunk, extract the sequence number and the data + */ + residx = DatumGetInt32(fastgetattr(ttup, 2, toasttupDesc, &isnull)); + Assert(!isnull); + chunk = DatumGetPointer(fastgetattr(ttup, 3, toasttupDesc, &isnull)); + Assert(!isnull); + if (!VARATT_IS_EXTENDED(chunk)) + { + chunksize = VARSIZE(chunk) - VARHDRSZ; + chunkdata = VARDATA(chunk); + } + else if (VARATT_IS_SHORT(chunk)) + { + /* could happen due to heap_form_tuple doing its thing */ + chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT; + chunkdata = VARDATA_SHORT(chunk); + } + else + { + /* should never happen */ + elog(ERROR, "found toasted toast chunk for toast value %u in %s", + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + chunksize = 0; /* keep compiler quiet */ + chunkdata = NULL; + } + + /* + * Some checks on the data we've found + */ + if ((residx != nextidx) || (residx > endchunk) || (residx < startchunk)) + elog(ERROR, "unexpected chunk number %d (expected %d) for toast value %u in %s", + residx, nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + if (residx < totalchunks - 1) + { + if (chunksize != TOAST_MAX_CHUNK_SIZE) + elog(ERROR, "unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s when fetching slice", + chunksize, (int) TOAST_MAX_CHUNK_SIZE, + residx, totalchunks, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + } + else if (residx == totalchunks - 1) + { + if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != attrsize) + elog(ERROR, "unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s when fetching slice", + chunksize, + (int) (attrsize - residx * TOAST_MAX_CHUNK_SIZE), + residx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + } + else + elog(ERROR, "unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", + residx, + 0, totalchunks - 1, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + + /* + * Copy the data into proper place in our result + */ + chcpystrt = 0; + chcpyend = chunksize - 1; + if (residx == startchunk) + chcpystrt = startoffset; + if (residx == endchunk) + chcpyend = endoffset; + + memcpy(VARDATA(result) + + (residx * TOAST_MAX_CHUNK_SIZE - sliceoffset) + chcpystrt, + chunkdata + chcpystrt, + (chcpyend - chcpystrt) + 1); + + nextidx++; + } + + /* + * Final checks that we successfully fetched the datum + */ + if (nextidx != (endchunk + 1)) + elog(ERROR, "missing chunk number %d for toast value %u in %s", + nextidx, + toast_pointer.va_valueid, + RelationGetRelationName(toastrel)); + + /* + * End scan and close relations + */ + systable_endscan_ordered(toastscan); + toast_close_indexes(toastidxs, num_indexes, AccessShareLock); + table_close(toastrel, AccessShareLock); + + return result; +} + +/* ---------- + * toast_decompress_datum - + * + * Decompress a compressed version of a varlena datum + */ +static struct varlena * +toast_decompress_datum(struct varlena *attr) +{ + struct varlena *result; + + Assert(VARATT_IS_COMPRESSED(attr)); + + result = (struct varlena *) + palloc(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); + SET_VARSIZE(result, TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); + + if (pglz_decompress(TOAST_COMPRESS_RAWDATA(attr), + TOAST_COMPRESS_SIZE(attr), + VARDATA(result), + TOAST_COMPRESS_RAWSIZE(attr), true) < 0) + elog(ERROR, "compressed data is corrupted"); + + return result; +} + + +/* ---------- + * toast_decompress_datum_slice - + * + * Decompress the front of a compressed version of a varlena datum. + * offset handling happens in heap_tuple_untoast_attr_slice. + * Here we just decompress a slice from the front. + */ +static struct varlena * +toast_decompress_datum_slice(struct varlena *attr, int32 slicelength) +{ + struct varlena *result; + int32 rawsize; + + Assert(VARATT_IS_COMPRESSED(attr)); + + result = (struct varlena *) palloc(slicelength + VARHDRSZ); + + rawsize = pglz_decompress(TOAST_COMPRESS_RAWDATA(attr), + VARSIZE(attr) - TOAST_COMPRESS_HDRSZ, + VARDATA(result), + slicelength, false); + if (rawsize < 0) + elog(ERROR, "compressed data is corrupted"); + + SET_VARSIZE(result, rawsize + VARHDRSZ); + return result; +} + +/* ---------- + * toast_raw_datum_size - + * + * Return the raw (detoasted) size of a varlena datum + * (including the VARHDRSZ header) + * ---------- + */ +Size +toast_raw_datum_size(Datum value) +{ + struct varlena *attr = (struct varlena *) DatumGetPointer(value); + Size result; + + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + /* va_rawsize is the size of the original datum -- including header */ + struct varatt_external toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + result = toast_pointer.va_rawsize; + } + else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) + { + struct varatt_indirect toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* nested indirect Datums aren't allowed */ + Assert(!VARATT_IS_EXTERNAL_INDIRECT(toast_pointer.pointer)); + + return toast_raw_datum_size(PointerGetDatum(toast_pointer.pointer)); + } + else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) + { + result = EOH_get_flat_size(DatumGetEOHP(value)); + } + else if (VARATT_IS_COMPRESSED(attr)) + { + /* here, va_rawsize is just the payload size */ + result = VARRAWSIZE_4B_C(attr) + VARHDRSZ; + } + else if (VARATT_IS_SHORT(attr)) + { + /* + * we have to normalize the header length to VARHDRSZ or else the + * callers of this function will be confused. + */ + result = VARSIZE_SHORT(attr) - VARHDRSZ_SHORT + VARHDRSZ; + } + else + { + /* plain untoasted datum */ + result = VARSIZE(attr); + } + return result; +} + +/* ---------- + * toast_datum_size + * + * Return the physical storage size (possibly compressed) of a varlena datum + * ---------- + */ +Size +toast_datum_size(Datum value) +{ + struct varlena *attr = (struct varlena *) DatumGetPointer(value); + Size result; + + if (VARATT_IS_EXTERNAL_ONDISK(attr)) + { + /* + * Attribute is stored externally - return the extsize whether + * compressed or not. We do not count the size of the toast pointer + * ... should we? + */ + struct varatt_external toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + result = toast_pointer.va_extsize; + } + else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) + { + struct varatt_indirect toast_pointer; + + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* nested indirect Datums aren't allowed */ + Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); + + return toast_datum_size(PointerGetDatum(toast_pointer.pointer)); + } + else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) + { + result = EOH_get_flat_size(DatumGetEOHP(value)); + } + else if (VARATT_IS_SHORT(attr)) + { + result = VARSIZE_SHORT(attr); + } + else + { + /* + * Attribute is stored inline either compressed or not, just calculate + * the size of the datum in either case. + */ + result = VARSIZE(attr); + } + return result; +} diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c index c64645675e6..cc948958d7e 100644 --- a/src/backend/access/common/heaptuple.c +++ b/src/backend/access/common/heaptuple.c @@ -18,7 +18,7 @@ * (In performance-critical code paths we can use pg_detoast_datum_packed * and the appropriate access macros to avoid that overhead.) Note that this * conversion is performed directly in heap_form_tuple, without invoking - * tuptoaster.c. + * heaptoast.c. * * This change will break any code that assumes it needn't detoast values * that have been put into a tuple but never sent to disk. Hopefully there @@ -45,7 +45,7 @@ * and we'd like to still refer to them via C struct offsets. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -57,9 +57,9 @@ #include "postgres.h" +#include "access/heaptoast.h" #include "access/sysattr.h" #include "access/tupdesc_details.h" -#include "access/tuptoaster.h" #include "executor/tuptable.h" #include "utils/expandeddatum.h" @@ -80,7 +80,7 @@ /* * Return the missing value of an attribute, or NULL if there isn't one. */ -static Datum +Datum getmissingattr(TupleDesc tupleDesc, int attnum, bool *isnull) { @@ -100,10 +100,10 @@ getmissingattr(TupleDesc tupleDesc, attrmiss = tupleDesc->constr->missing + (attnum - 1); - if (attrmiss->ammissingPresent) + if (attrmiss->am_present) { *isnull = false; - return attrmiss->ammissing; + return attrmiss->am_value; } } @@ -111,44 +111,6 @@ getmissingattr(TupleDesc tupleDesc, return PointerGetDatum(NULL); } -/* - * Fill in missing values for a TupleTableSlot. - * - * This is only exposed because it's needed for JIT compiled tuple - * deforming. That exception aside, there should be no callers outside of this - * file. - */ -void -slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum) -{ - AttrMissing *attrmiss = NULL; - int missattnum; - - if (slot->tts_tupleDescriptor->constr) - attrmiss = slot->tts_tupleDescriptor->constr->missing; - - if (!attrmiss) - { - /* no missing values array at all, so just fill everything in as NULL */ - memset(slot->tts_values + startAttNum, 0, - (lastAttNum - startAttNum) * sizeof(Datum)); - memset(slot->tts_isnull + startAttNum, 1, - (lastAttNum - startAttNum) * sizeof(bool)); - } - else - { - /* if there is a missing values array we must process them one by one */ - for (missattnum = startAttNum; - missattnum < lastAttNum; - missattnum++) - { - slot->tts_values[missattnum] = attrmiss[missattnum].ammissing; - slot->tts_isnull[missattnum] = - !attrmiss[missattnum].ammissingPresent; - } - } -} - /* * heap_compute_data_size * Determine size of the data area of a tuple to be constructed @@ -420,7 +382,6 @@ heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc) { case TableOidAttributeNumber: case SelfItemPointerAttributeNumber: - case ObjectIdAttributeNumber: case MinTransactionIdAttributeNumber: case MinCommandIdAttributeNumber: case MaxTransactionIdAttributeNumber: @@ -678,9 +639,6 @@ heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull) /* pass-by-reference datatype */ result = PointerGetDatum(&(tup->t_self)); break; - case ObjectIdAttributeNumber: - result = ObjectIdGetDatum(HeapTupleGetOid(tup)); - break; case MinTransactionIdAttributeNumber: result = TransactionIdGetDatum(HeapTupleHeaderGetRawXmin(tup->t_data)); break; @@ -822,46 +780,37 @@ expand_tuple(HeapTuple *targetHeapTuple, firstmissingnum < natts; firstmissingnum++) { - if (attrmiss[firstmissingnum].ammissingPresent) + if (attrmiss[firstmissingnum].am_present) break; + else + hasNulls = true; } /* - * If there are no more missing values everything else must be NULL + * Now walk the missing attributes. If there is a missing value make + * space for it. Otherwise, it's going to be NULL. */ - if (firstmissingnum >= natts) - { - hasNulls = true; - } - else + for (attnum = firstmissingnum; + attnum < natts; + attnum++) { - - /* - * Now walk the missing attributes. If there is a missing value - * make space for it. Otherwise, it's going to be NULL. - */ - for (attnum = firstmissingnum; - attnum < natts; - attnum++) + if (attrmiss[attnum].am_present) { - if (attrmiss[attnum].ammissingPresent) - { - Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum); + Form_pg_attribute att = TupleDescAttr(tupleDesc, attnum); - targetDataLen = att_align_datum(targetDataLen, - att->attalign, - att->attlen, - attrmiss[attnum].ammissing); + targetDataLen = att_align_datum(targetDataLen, + att->attalign, + att->attlen, + attrmiss[attnum].am_value); - targetDataLen = att_addlength_pointer(targetDataLen, - att->attlen, - attrmiss[attnum].ammissing); - } - else - { - /* no missing value, so it must be null */ - hasNulls = true; - } + targetDataLen = att_addlength_pointer(targetDataLen, + att->attlen, + attrmiss[attnum].am_value); + } + else + { + /* no missing value, so it must be null */ + hasNulls = true; } } } /* end if have missing values */ @@ -884,9 +833,6 @@ expand_tuple(HeapTuple *targetHeapTuple, else targetNullLen = 0; - if (tupleDesc->tdhasoid) - len += sizeof(Oid); - /* * Allocate and zero the space needed. Note that the tuple body and * HeapTupleData management structure are allocated in one chunk. @@ -903,7 +849,7 @@ expand_tuple(HeapTuple *targetHeapTuple, = (HeapTupleHeader) ((char *) *targetHeapTuple + HEAPTUPLESIZE); (*targetHeapTuple)->t_len = len; (*targetHeapTuple)->t_tableOid = sourceTuple->t_tableOid; - ItemPointerSetInvalid(&((*targetHeapTuple)->t_self)); + (*targetHeapTuple)->t_self = sourceTuple->t_self; targetTHeader->t_infomask = sourceTHeader->t_infomask; targetTHeader->t_hoff = hoff; @@ -981,14 +927,14 @@ expand_tuple(HeapTuple *targetHeapTuple, Form_pg_attribute attr = TupleDescAttr(tupleDesc, attnum); - if (attrmiss[attnum].ammissingPresent) + if (attrmiss && attrmiss[attnum].am_present) { fill_val(attr, nullBits ? &nullBits : NULL, &bitMask, &targetData, infoMask, - attrmiss[attnum].ammissing, + attrmiss[attnum].am_value, false); } else @@ -1110,9 +1056,6 @@ heap_form_tuple(TupleDesc tupleDescriptor, if (hasnull) len += BITMAPLEN(numberOfAttributes); - if (tupleDescriptor->tdhasoid) - len += sizeof(Oid); - hoff = len = MAXALIGN(len); /* align user data safely */ data_len = heap_compute_data_size(tupleDescriptor, values, isnull); @@ -1144,9 +1087,6 @@ heap_form_tuple(TupleDesc tupleDescriptor, HeapTupleHeaderSetNatts(td, numberOfAttributes); td->t_hoff = hoff; - if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */ - td->t_infomask = HEAP_HASOID; - heap_fill_tuple(tupleDescriptor, values, isnull, @@ -1216,14 +1156,11 @@ heap_modify_tuple(HeapTuple tuple, pfree(isnull); /* - * copy the identification info of the old tuple: t_ctid, t_self, and OID - * (if any) + * copy the identification info of the old tuple: t_ctid, t_self */ newTuple->t_data->t_ctid = tuple->t_data->t_ctid; newTuple->t_self = tuple->t_self; newTuple->t_tableOid = tuple->t_tableOid; - if (tupleDesc->tdhasoid) - HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple)); return newTuple; } @@ -1282,14 +1219,11 @@ heap_modify_tuple_by_cols(HeapTuple tuple, pfree(isnull); /* - * copy the identification info of the old tuple: t_ctid, t_self, and OID - * (if any) + * copy the identification info of the old tuple: t_ctid, t_self */ newTuple->t_data->t_ctid = tuple->t_data->t_ctid; newTuple->t_self = tuple->t_self; newTuple->t_tableOid = tuple->t_tableOid; - if (tupleDesc->tdhasoid) - HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple)); return newTuple; } @@ -1397,375 +1331,6 @@ heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, values[attnum] = getmissingattr(tupleDesc, attnum + 1, &isnull[attnum]); } -/* - * slot_deform_tuple - * Given a TupleTableSlot, extract data from the slot's physical tuple - * into its Datum/isnull arrays. Data is extracted up through the - * natts'th column (caller must ensure this is a legal column number). - * - * This is essentially an incremental version of heap_deform_tuple: - * on each call we extract attributes up to the one needed, without - * re-computing information about previously extracted attributes. - * slot->tts_nvalid is the number of attributes already extracted. - */ -static void -slot_deform_tuple(TupleTableSlot *slot, int natts) -{ - HeapTuple tuple = slot->tts_tuple; - TupleDesc tupleDesc = slot->tts_tupleDescriptor; - Datum *values = slot->tts_values; - bool *isnull = slot->tts_isnull; - HeapTupleHeader tup = tuple->t_data; - bool hasnulls = HeapTupleHasNulls(tuple); - int attnum; - char *tp; /* ptr to tuple data */ - uint32 off; /* offset in tuple data */ - bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */ - bool slow; /* can we use/set attcacheoff? */ - - /* - * Check whether the first call for this tuple, and initialize or restore - * loop state. - */ - attnum = slot->tts_nvalid; - if (attnum == 0) - { - /* Start from the first attribute */ - off = 0; - slow = false; - } - else - { - /* Restore state from previous execution */ - off = slot->tts_off; - slow = slot->tts_slow; - } - - tp = (char *) tup + tup->t_hoff; - - for (; attnum < natts; attnum++) - { - Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum); - - if (hasnulls && att_isnull(attnum, bp)) - { - values[attnum] = (Datum) 0; - isnull[attnum] = true; - slow = true; /* can't use attcacheoff anymore */ - continue; - } - - isnull[attnum] = false; - - if (!slow && thisatt->attcacheoff >= 0) - off = thisatt->attcacheoff; - else if (thisatt->attlen == -1) - { - /* - * We can only cache the offset for a varlena attribute if the - * offset is already suitably aligned, so that there would be no - * pad bytes in any case: then the offset will be valid for either - * an aligned or unaligned value. - */ - if (!slow && - off == att_align_nominal(off, thisatt->attalign)) - thisatt->attcacheoff = off; - else - { - off = att_align_pointer(off, thisatt->attalign, -1, - tp + off); - slow = true; - } - } - else - { - /* not varlena, so safe to use att_align_nominal */ - off = att_align_nominal(off, thisatt->attalign); - - if (!slow) - thisatt->attcacheoff = off; - } - - values[attnum] = fetchatt(thisatt, tp + off); - - off = att_addlength_pointer(off, thisatt->attlen, tp + off); - - if (thisatt->attlen <= 0) - slow = true; /* can't use attcacheoff anymore */ - } - - /* - * Save state for next execution - */ - slot->tts_nvalid = attnum; - slot->tts_off = off; - slot->tts_slow = slow; -} - -/* - * slot_getattr - * This function fetches an attribute of the slot's current tuple. - * It is functionally equivalent to heap_getattr, but fetches of - * multiple attributes of the same tuple will be optimized better, - * because we avoid O(N^2) behavior from multiple calls of - * nocachegetattr(), even when attcacheoff isn't usable. - * - * A difference from raw heap_getattr is that attnums beyond the - * slot's tupdesc's last attribute will be considered NULL even - * when the physical tuple is longer than the tupdesc. - */ -Datum -slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull) -{ - HeapTuple tuple = slot->tts_tuple; - TupleDesc tupleDesc = slot->tts_tupleDescriptor; - HeapTupleHeader tup; - - /* - * system attributes are handled by heap_getsysattr - */ - if (attnum <= 0) - { - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract system attribute from virtual tuple"); - if (tuple == &(slot->tts_minhdr)) /* internal error */ - elog(ERROR, "cannot extract system attribute from minimal tuple"); - return heap_getsysattr(tuple, attnum, tupleDesc, isnull); - } - - /* - * fast path if desired attribute already cached - */ - if (attnum <= slot->tts_nvalid) - { - *isnull = slot->tts_isnull[attnum - 1]; - return slot->tts_values[attnum - 1]; - } - - /* - * return NULL if attnum is out of range according to the tupdesc - */ - if (attnum > tupleDesc->natts) - { - *isnull = true; - return (Datum) 0; - } - - /* - * otherwise we had better have a physical tuple (tts_nvalid should equal - * natts in all virtual-tuple cases) - */ - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract attribute from empty tuple slot"); - - /* - * return NULL or missing value if attnum is out of range according to the - * tuple - * - * (We have to check this separately because of various inheritance and - * table-alteration scenarios: the tuple could be either longer or shorter - * than the tupdesc.) - */ - tup = tuple->t_data; - if (attnum > HeapTupleHeaderGetNatts(tup)) - return getmissingattr(slot->tts_tupleDescriptor, attnum, isnull); - - /* - * check if target attribute is null: no point in groveling through tuple - */ - if (HeapTupleHasNulls(tuple) && att_isnull(attnum - 1, tup->t_bits)) - { - *isnull = true; - return (Datum) 0; - } - - /* - * If the attribute's column has been dropped, we force a NULL result. - * This case should not happen in normal use, but it could happen if we - * are executing a plan cached before the column was dropped. - */ - if (TupleDescAttr(tupleDesc, attnum - 1)->attisdropped) - { - *isnull = true; - return (Datum) 0; - } - - /* - * Extract the attribute, along with any preceding attributes. - */ - slot_deform_tuple(slot, attnum); - - /* - * The result is acquired from tts_values array. - */ - *isnull = slot->tts_isnull[attnum - 1]; - return slot->tts_values[attnum - 1]; -} - -/* - * slot_getallattrs - * This function forces all the entries of the slot's Datum/isnull - * arrays to be valid. The caller may then extract data directly - * from those arrays instead of using slot_getattr. - */ -void -slot_getallattrs(TupleTableSlot *slot) -{ - int tdesc_natts = slot->tts_tupleDescriptor->natts; - int attnum; - HeapTuple tuple; - - /* Quick out if we have 'em all already */ - if (slot->tts_nvalid == tdesc_natts) - return; - - /* - * otherwise we had better have a physical tuple (tts_nvalid should equal - * natts in all virtual-tuple cases) - */ - tuple = slot->tts_tuple; - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract attribute from empty tuple slot"); - - /* - * load up any slots available from physical tuple - */ - attnum = HeapTupleHeaderGetNatts(tuple->t_data); - attnum = Min(attnum, tdesc_natts); - - slot_deform_tuple(slot, attnum); - - attnum = slot->tts_nvalid; - - /* - * If tuple doesn't have all the atts indicated by tupleDesc, read the - * rest as NULLS or missing values. - */ - if (attnum < tdesc_natts) - slot_getmissingattrs(slot, attnum, tdesc_natts); - - slot->tts_nvalid = tdesc_natts; -} - -/* - * slot_getsomeattrs - * This function forces the entries of the slot's Datum/isnull - * arrays to be valid at least up through the attnum'th entry. - */ -void -slot_getsomeattrs(TupleTableSlot *slot, int attnum) -{ - HeapTuple tuple; - int attno; - - /* Quick out if we have 'em all already */ - if (slot->tts_nvalid >= attnum) - return; - - /* Check for caller error */ - if (attnum <= 0 || attnum > slot->tts_tupleDescriptor->natts) - elog(ERROR, "invalid attribute number %d", attnum); - - /* - * otherwise we had better have a physical tuple (tts_nvalid should equal - * natts in all virtual-tuple cases) - */ - tuple = slot->tts_tuple; - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract attribute from empty tuple slot"); - - /* - * load up any slots available from physical tuple - */ - attno = HeapTupleHeaderGetNatts(tuple->t_data); - attno = Min(attno, attnum); - - slot_deform_tuple(slot, attno); - - attno = slot->tts_nvalid; - - /* - * If tuple doesn't have all the atts indicated by attnum, read the - * rest as NULLs or missing values - */ - if (attno < attnum) - slot_getmissingattrs(slot, attno, attnum); - - slot->tts_nvalid = attnum; -} - -/* - * slot_attisnull - * Detect whether an attribute of the slot is null, without - * actually fetching it. - */ -bool -slot_attisnull(TupleTableSlot *slot, int attnum) -{ - HeapTuple tuple = slot->tts_tuple; - TupleDesc tupleDesc = slot->tts_tupleDescriptor; - - /* - * system attributes are handled by heap_attisnull - */ - if (attnum <= 0) - { - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract system attribute from virtual tuple"); - if (tuple == &(slot->tts_minhdr)) /* internal error */ - elog(ERROR, "cannot extract system attribute from minimal tuple"); - return heap_attisnull(tuple, attnum, tupleDesc); - } - - /* - * fast path if desired attribute already cached - */ - if (attnum <= slot->tts_nvalid) - return slot->tts_isnull[attnum - 1]; - - /* - * return NULL if attnum is out of range according to the tupdesc - */ - if (attnum > tupleDesc->natts) - return true; - - /* - * otherwise we had better have a physical tuple (tts_nvalid should equal - * natts in all virtual-tuple cases) - */ - if (tuple == NULL) /* internal error */ - elog(ERROR, "cannot extract attribute from empty tuple slot"); - - /* and let the tuple tell it */ - return heap_attisnull(tuple, attnum, tupleDesc); -} - -/* - * slot_getsysattr - * This function fetches a system attribute of the slot's current tuple. - * Unlike slot_getattr, if the slot does not contain system attributes, - * this will return false (with a NULL attribute value) instead of - * throwing an error. - */ -bool -slot_getsysattr(TupleTableSlot *slot, int attnum, - Datum *value, bool *isnull) -{ - HeapTuple tuple = slot->tts_tuple; - - Assert(attnum < 0); /* else caller error */ - if (tuple == NULL || - tuple == &(slot->tts_minhdr)) - { - /* No physical tuple, or minimal tuple, so fail */ - *value = (Datum) 0; - *isnull = true; - return false; - } - *value = heap_getsysattr(tuple, attnum, slot->tts_tupleDescriptor, isnull); - return true; -} - /* * heap_freetuple */ @@ -1826,9 +1391,6 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor, if (hasnull) len += BITMAPLEN(numberOfAttributes); - if (tupleDescriptor->tdhasoid) - len += sizeof(Oid); - hoff = len = MAXALIGN(len); /* align user data safely */ data_len = heap_compute_data_size(tupleDescriptor, values, isnull); @@ -1847,9 +1409,6 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor, HeapTupleHeaderSetNatts(tuple, numberOfAttributes); tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET; - if (tupleDescriptor->tdhasoid) /* else leave infomask = 0 */ - tuple->t_infomask = HEAP_HASOID; - heap_fill_tuple(tupleDescriptor, values, isnull, diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c index 9b3e0a2e6ea..07586201b9d 100644 --- a/src/backend/access/common/indextuple.c +++ b/src/backend/access/common/indextuple.c @@ -4,7 +4,7 @@ * This file contains index tuple accessor and mutator routines, * as well as various tuple utilities. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,11 +16,17 @@ #include "postgres.h" -#include "access/heapam.h" +#include "access/detoast.h" +#include "access/heaptoast.h" +#include "access/htup_details.h" #include "access/itup.h" -#include "access/tuptoaster.h" -#include "utils/rel.h" +#include "access/toast_internals.h" +/* + * This enables de-toasting of index entries. Needed until VACUUM is + * smart enough to rebuild indexes from scratch. + */ +#define TOAST_INDEX_HACK /* ---------------------------------------------------------------- * index_ tuple interface routines @@ -32,6 +38,9 @@ * * This shouldn't leak any memory; otherwise, callers such as * tuplesort_putindextuplevalues() will be very unhappy. + * + * This shouldn't perform external table access provided caller + * does not pass values that are stored EXTERNAL. * ---------------- */ IndexTuple @@ -416,19 +425,80 @@ nocache_index_getattr(IndexTuple tup, * * The caller must allocate sufficient storage for the output arrays. * (INDEX_MAX_KEYS entries should be enough.) + * + * This is nearly the same as heap_deform_tuple(), but for IndexTuples. + * One difference is that the tuple should never have any missing columns. */ void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, Datum *values, bool *isnull) { - int i; + int hasnulls = IndexTupleHasNulls(tup); + int natts = tupleDescriptor->natts; /* number of atts to extract */ + int attnum; + char *tp; /* ptr to tuple data */ + int off; /* offset in tuple data */ + bits8 *bp; /* ptr to null bitmap in tuple */ + bool slow = false; /* can we use/set attcacheoff? */ /* Assert to protect callers who allocate fixed-size arrays */ - Assert(tupleDescriptor->natts <= INDEX_MAX_KEYS); + Assert(natts <= INDEX_MAX_KEYS); + + /* XXX "knows" t_bits are just after fixed tuple header! */ + bp = (bits8 *) ((char *) tup + sizeof(IndexTupleData)); - for (i = 0; i < tupleDescriptor->natts; i++) + tp = (char *) tup + IndexInfoFindDataOffset(tup->t_info); + off = 0; + + for (attnum = 0; attnum < natts; attnum++) { - values[i] = index_getattr(tup, i + 1, tupleDescriptor, &isnull[i]); + Form_pg_attribute thisatt = TupleDescAttr(tupleDescriptor, attnum); + + if (hasnulls && att_isnull(attnum, bp)) + { + values[attnum] = (Datum) 0; + isnull[attnum] = true; + slow = true; /* can't use attcacheoff anymore */ + continue; + } + + isnull[attnum] = false; + + if (!slow && thisatt->attcacheoff >= 0) + off = thisatt->attcacheoff; + else if (thisatt->attlen == -1) + { + /* + * We can only cache the offset for a varlena attribute if the + * offset is already suitably aligned, so that there would be no + * pad bytes in any case: then the offset will be valid for either + * an aligned or unaligned value. + */ + if (!slow && + off == att_align_nominal(off, thisatt->attalign)) + thisatt->attcacheoff = off; + else + { + off = att_align_pointer(off, thisatt->attalign, -1, + tp + off); + slow = true; + } + } + else + { + /* not varlena, so safe to use att_align_nominal */ + off = att_align_nominal(off, thisatt->attalign); + + if (!slow) + thisatt->attcacheoff = off; + } + + values[attnum] = fetchatt(thisatt, tp + off); + + off = att_addlength_pointer(off, thisatt->attlen, tp + off); + + if (thisatt->attlen <= 0) + slow = true; /* can't use attcacheoff anymore */ } } @@ -448,30 +518,53 @@ CopyIndexTuple(IndexTuple source) } /* - * Truncate tailing attributes from given index tuple leaving it with - * new_indnatts number of attributes. + * Create a palloc'd copy of an index tuple, leaving only the first + * leavenatts attributes remaining. + * + * Truncation is guaranteed to result in an index tuple that is no + * larger than the original. It is safe to use the IndexTuple with + * the original tuple descriptor, but caller must avoid actually + * accessing truncated attributes from returned tuple! In practice + * this means that index_getattr() must be called with special care, + * and that the truncated tuple should only ever be accessed by code + * under caller's direct control. + * + * It's safe to call this function with a buffer lock held, since it + * never performs external table access. If it ever became possible + * for index tuples to contain EXTERNAL TOAST values, then this would + * have to be revisited. */ IndexTuple -index_truncate_tuple(TupleDesc tupleDescriptor, IndexTuple olditup, - int new_indnatts) +index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source, + int leavenatts) { - TupleDesc itupdesc = CreateTupleDescCopyConstr(tupleDescriptor); + TupleDesc truncdesc; Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; - IndexTuple newitup; + IndexTuple truncated; + + Assert(leavenatts <= sourceDescriptor->natts); - Assert(tupleDescriptor->natts <= INDEX_MAX_KEYS); - Assert(new_indnatts > 0); - Assert(new_indnatts < tupleDescriptor->natts); + /* Easy case: no truncation actually required */ + if (leavenatts == sourceDescriptor->natts) + return CopyIndexTuple(source); - index_deform_tuple(olditup, tupleDescriptor, values, isnull); + /* Create temporary descriptor to scribble on */ + truncdesc = palloc(TupleDescSize(sourceDescriptor)); + TupleDescCopy(truncdesc, sourceDescriptor); + truncdesc->natts = leavenatts; - /* form new tuple that will contain only key attributes */ - itupdesc->natts = new_indnatts; - newitup = index_form_tuple(itupdesc, values, isnull); - newitup->t_tid = olditup->t_tid; + /* Deform, form copy of tuple with fewer attributes */ + index_deform_tuple(source, truncdesc, values, isnull); + truncated = index_form_tuple(truncdesc, values, isnull); + truncated->t_tid = source->t_tid; + Assert(IndexTupleSize(truncated) <= IndexTupleSize(source)); + + /* + * Cannot leak memory here, TupleDescCopy() doesn't allocate any inner + * structure, so, plain pfree() should clean all allocated memory + */ + pfree(truncdesc); - FreeTupleDesc(itupdesc); - Assert(IndexTupleSize(newitup) <= IndexTupleSize(olditup)); - return newitup; + return truncated; } diff --git a/src/backend/access/common/printsimple.c b/src/backend/access/common/printsimple.c index 3c4d2277125..651ade14dd2 100644 --- a/src/backend/access/common/printsimple.c +++ b/src/backend/access/common/printsimple.c @@ -8,7 +8,7 @@ * doesn't handle standalone backends or protocol versions other than * 3.0, because we don't need such handling for current applications. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,7 +20,6 @@ #include "access/printsimple.h" #include "catalog/pg_type.h" -#include "fmgr.h" #include "libpq/pqformat.h" #include "utils/builtins.h" diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c index a1d44157044..e330f496892 100644 --- a/src/backend/access/common/printtup.c +++ b/src/backend/access/common/printtup.c @@ -5,7 +5,7 @@ * clients and standalone backends are supported here). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -25,7 +25,7 @@ static void printtup_startup(DestReceiver *self, int operation, - TupleDesc typeinfo); + TupleDesc typeinfo); static bool printtup(TupleTableSlot *slot, DestReceiver *self); static bool printtup_20(TupleTableSlot *slot, DestReceiver *self); static bool printtup_internal_20(TupleTableSlot *slot, DestReceiver *self); @@ -33,9 +33,9 @@ static void printtup_shutdown(DestReceiver *self); static void printtup_destroy(DestReceiver *self); static void SendRowDescriptionCols_2(StringInfo buf, TupleDesc typeinfo, - List *targetlist, int16 *formats); + List *targetlist, int16 *formats); static void SendRowDescriptionCols_3(StringInfo buf, TupleDesc typeinfo, - List *targetlist, int16 *formats); + List *targetlist, int16 *formats); /* ---------------------------------------------------------------- * printtup / debugtup support @@ -61,12 +61,12 @@ typedef struct typedef struct { DestReceiver pub; /* publicly-known function pointers */ - StringInfoData buf; /* output buffer */ Portal portal; /* the Portal we are printing from */ bool sendDescrip; /* send RowDescription at startup? */ TupleDesc attrinfo; /* The attr info we are set up for */ int nattrs; PrinttupAttrInfo *myinfo; /* Cached info about each attr */ + StringInfoData buf; /* output buffer (*not* in tmpcontext) */ MemoryContext tmpcontext; /* Memory context for per-row workspace */ } DR_printtup; @@ -94,6 +94,7 @@ printtup_create_DR(CommandDest dest) self->attrinfo = NULL; self->nattrs = 0; self->myinfo = NULL; + self->buf.data = NULL; self->tmpcontext = NULL; return (DestReceiver *) self; @@ -132,7 +133,10 @@ printtup_startup(DestReceiver *self, int operation, TupleDesc typeinfo) DR_printtup *myState = (DR_printtup *) self; Portal portal = myState->portal; - /* create buffer to be used for all messages */ + /* + * Create I/O buffer to be used for all messages. This cannot be inside + * tmpcontext, since we want to re-use it across rows. + */ initStringInfo(&myState->buf); /* @@ -258,14 +262,14 @@ SendRowDescriptionCols_3(StringInfo buf, TupleDesc typeinfo, List *targetlist, i /* Do we have a non-resjunk tlist item? */ while (tlist_item && ((TargetEntry *) lfirst(tlist_item))->resjunk) - tlist_item = lnext(tlist_item); + tlist_item = lnext(targetlist, tlist_item); if (tlist_item) { TargetEntry *tle = (TargetEntry *) lfirst(tlist_item); resorigtbl = tle->resorigtbl; resorigcol = tle->resorigcol; - tlist_item = lnext(tlist_item); + tlist_item = lnext(targetlist, tlist_item); } else { @@ -544,6 +548,10 @@ printtup_shutdown(DestReceiver *self) myState->attrinfo = NULL; + if (myState->buf.data) + pfree(myState->buf.data); + myState->buf.data = NULL; + if (myState->tmpcontext) MemoryContextDelete(myState->tmpcontext); myState->tmpcontext = NULL; diff --git a/src/backend/access/common/relation.c b/src/backend/access/common/relation.c new file mode 100644 index 00000000000..41a0051f88e --- /dev/null +++ b/src/backend/access/common/relation.c @@ -0,0 +1,217 @@ +/*------------------------------------------------------------------------- + * + * relation.c + * Generic relation related routines. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/common/relation.c + * + * NOTES + * This file contains relation_ routines that implement access to relations + * (tables, indexes, etc). Support that's specific to subtypes of relations + * should go into their respective files, not here. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/relation.h" +#include "access/xact.h" +#include "catalog/namespace.h" +#include "miscadmin.h" +#include "pgstat.h" +#include "storage/lmgr.h" +#include "utils/inval.h" +#include "utils/syscache.h" + + +/* ---------------- + * relation_open - open any relation by relation OID + * + * If lockmode is not "NoLock", the specified kind of lock is + * obtained on the relation. (Generally, NoLock should only be + * used if the caller knows it has some appropriate lock on the + * relation already.) + * + * An error is raised if the relation does not exist. + * + * NB: a "relation" is anything with a pg_class entry. The caller is + * expected to check whether the relkind is something it can handle. + * ---------------- + */ +Relation +relation_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* Get the lock before trying to open the relcache entry */ + if (lockmode != NoLock) + LockRelationOid(relationId, lockmode); + + /* The relcache does all the real work... */ + r = RelationIdGetRelation(relationId); + + if (!RelationIsValid(r)) + elog(ERROR, "could not open relation with OID %u", relationId); + + /* + * If we didn't get the lock ourselves, assert that caller holds one, + * except in bootstrap mode where no locks are used. + */ + Assert(lockmode != NoLock || + IsBootstrapProcessingMode() || + CheckRelationLockedByMe(r, AccessShareLock, true)); + + /* Make note that we've accessed a temporary relation */ + if (RelationUsesLocalBuffers(r)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + + pgstat_initstats(r); + + return r; +} + +/* ---------------- + * try_relation_open - open any relation by relation OID + * + * Same as relation_open, except return NULL instead of failing + * if the relation does not exist. + * ---------------- + */ +Relation +try_relation_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* Get the lock first */ + if (lockmode != NoLock) + LockRelationOid(relationId, lockmode); + + /* + * Now that we have the lock, probe to see if the relation really exists + * or not. + */ + if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relationId))) + { + /* Release useless lock */ + if (lockmode != NoLock) + UnlockRelationOid(relationId, lockmode); + + return NULL; + } + + /* Should be safe to do a relcache load */ + r = RelationIdGetRelation(relationId); + + if (!RelationIsValid(r)) + elog(ERROR, "could not open relation with OID %u", relationId); + + /* If we didn't get the lock ourselves, assert that caller holds one */ + Assert(lockmode != NoLock || + CheckRelationLockedByMe(r, AccessShareLock, true)); + + /* Make note that we've accessed a temporary relation */ + if (RelationUsesLocalBuffers(r)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + + pgstat_initstats(r); + + return r; +} + +/* ---------------- + * relation_openrv - open any relation specified by a RangeVar + * + * Same as relation_open, but the relation is specified by a RangeVar. + * ---------------- + */ +Relation +relation_openrv(const RangeVar *relation, LOCKMODE lockmode) +{ + Oid relOid; + + /* + * Check for shared-cache-inval messages before trying to open the + * relation. This is needed even if we already hold a lock on the + * relation, because GRANT/REVOKE are executed without taking any lock on + * the target relation, and we want to be sure we see current ACL + * information. We can skip this if asked for NoLock, on the assumption + * that such a call is not the first one in the current command, and so we + * should be reasonably up-to-date already. (XXX this all could stand to + * be redesigned, but for the moment we'll keep doing this like it's been + * done historically.) + */ + if (lockmode != NoLock) + AcceptInvalidationMessages(); + + /* Look up and lock the appropriate relation using namespace search */ + relOid = RangeVarGetRelid(relation, lockmode, false); + + /* Let relation_open do the rest */ + return relation_open(relOid, NoLock); +} + +/* ---------------- + * relation_openrv_extended - open any relation specified by a RangeVar + * + * Same as relation_openrv, but with an additional missing_ok argument + * allowing a NULL return rather than an error if the relation is not + * found. (Note that some other causes, such as permissions problems, + * will still result in an ereport.) + * ---------------- + */ +Relation +relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok) +{ + Oid relOid; + + /* + * Check for shared-cache-inval messages before trying to open the + * relation. See comments in relation_openrv(). + */ + if (lockmode != NoLock) + AcceptInvalidationMessages(); + + /* Look up and lock the appropriate relation using namespace search */ + relOid = RangeVarGetRelid(relation, lockmode, missing_ok); + + /* Return NULL on not-found */ + if (!OidIsValid(relOid)) + return NULL; + + /* Let relation_open do the rest */ + return relation_open(relOid, NoLock); +} + +/* ---------------- + * relation_close - close any relation + * + * If lockmode is not "NoLock", we then release the specified lock. + * + * Note that it is often sensible to hold a lock beyond relation_close; + * in that case, the lock is released automatically at xact end. + * ---------------- + */ +void +relation_close(Relation relation, LOCKMODE lockmode) +{ + LockRelId relid = relation->rd_lockInfo.lockRelId; + + Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); + + /* The relcache does the real work... */ + RelationClose(relation); + + if (lockmode != NoLock) + UnlockRelationId(&relid, lockmode); +} diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 69ab2f101c7..b5072c00fe5 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -3,7 +3,7 @@ * reloptions.c * Core support for relation options (pg_class.reloptions) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,11 +19,11 @@ #include "access/gist_private.h" #include "access/hash.h" +#include "access/heaptoast.h" #include "access/htup_details.h" #include "access/nbtree.h" #include "access/reloptions.h" #include "access/spgist.h" -#include "access/tuptoaster.h" #include "catalog/pg_type.h" #include "commands/defrem.h" #include "commands/tablespace.h" @@ -52,9 +52,6 @@ * (v) make sure the lock level is set correctly for that operation * (vi) don't forget to document the option * - * Note that we don't handle "oids" in relOpts because it is handled by - * interpretOidsOption(). - * * The default choice for any new option should be AccessExclusiveLock. * In some cases the lock level can be reduced from there, but the lock * level chosen should always conflict with itself to ensure that multiple @@ -72,12 +69,12 @@ * currently executing. * * Fillfactor can be set because it applies only to subsequent changes made to - * data blocks, as documented in heapio.c + * data blocks, as documented in hio.c * * n_distinct options can be set at ShareUpdateExclusiveLock because they * are only used during ANALYZE, which uses a ShareUpdateExclusiveLock, * so the ANALYZE will not be affected by in-flight changes. Changing those - * values has no affect until the next ANALYZE, so no need for stronger lock. + * values has no effect until the next ANALYZE, so no need for stronger lock. * * Planner-related parameters can be set with ShareUpdateExclusiveLock because * they only affect planning and not the correctness of the execution. Plans @@ -89,6 +86,11 @@ * Setting parallel_workers is safe, since it acts the same as * max_parallel_workers_per_gather which is a USERSET parameter that doesn't * affect existing plans or queries. + * + * vacuum_truncate can be set at ShareUpdateExclusiveLock because it + * is only used during VACUUM, which uses a ShareUpdateExclusiveLock, + * so the VACUUM will not be affected by in-flight changes. Changing its + * value has no effect until the next VACUUM, so no need for stronger lock. */ static relopt_bool boolRelOpts[] = @@ -129,15 +131,6 @@ static relopt_bool boolRelOpts[] = }, true }, - { - { - "recheck_on_update", - "Recheck functional index expression for changed value after update", - RELOPT_KIND_INDEX, - ShareUpdateExclusiveLock /* since only applies to later UPDATEs */ - }, - true - }, { { "security_barrier", @@ -147,6 +140,24 @@ static relopt_bool boolRelOpts[] = }, false }, + { + { + "vacuum_index_cleanup", + "Enables index vacuuming and index cleanup", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + ShareUpdateExclusiveLock + }, + true + }, + { + { + "vacuum_truncate", + "Enables vacuum to truncate empty pages at the end of this table", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + ShareUpdateExclusiveLock + }, + true + }, /* list terminator */ {{NULL}} }; @@ -221,15 +232,6 @@ static relopt_int intRelOpts[] = }, -1, 0, INT_MAX }, - { - { - "autovacuum_vacuum_cost_delay", - "Vacuum cost delay in milliseconds, for autovacuum", - RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, - ShareUpdateExclusiveLock - }, - -1, 0, 100 - }, { { "autovacuum_vacuum_cost_limit", @@ -355,6 +357,15 @@ static relopt_int intRelOpts[] = static relopt_real realRelOpts[] = { + { + { + "autovacuum_vacuum_cost_delay", + "Vacuum cost delay in milliseconds, for autovacuum", + RELOPT_KIND_HEAP | RELOPT_KIND_TOAST, + ShareUpdateExclusiveLock + }, + -1, 0.0, 100.0 + }, { { "autovacuum_vacuum_scale_factor", @@ -416,13 +427,31 @@ static relopt_real realRelOpts[] = RELOPT_KIND_BTREE, ShareUpdateExclusiveLock }, - -1, 0.0, 100.0 + -1, 0.0, 1e10 }, /* list terminator */ {{NULL}} }; -static relopt_string stringRelOpts[] = +/* values from GistOptBufferingMode */ +relopt_enum_elt_def gistBufferingOptValues[] = +{ + {"auto", GIST_OPTION_BUFFERING_AUTO}, + {"on", GIST_OPTION_BUFFERING_ON}, + {"off", GIST_OPTION_BUFFERING_OFF}, + {(const char *) NULL} /* list terminator */ +}; + +/* values from ViewOptCheckOption */ +relopt_enum_elt_def viewCheckOptValues[] = +{ + /* no value for NOT_SET */ + {"local", VIEW_OPTION_CHECK_OPTION_LOCAL}, + {"cascaded", VIEW_OPTION_CHECK_OPTION_CASCADED}, + {(const char *) NULL} /* list terminator */ +}; + +static relopt_enum enumRelOpts[] = { { { @@ -431,10 +460,9 @@ static relopt_string stringRelOpts[] = RELOPT_KIND_GIST, AccessExclusiveLock }, - 4, - false, - gistValidateBufferingOption, - "auto" + gistBufferingOptValues, + GIST_OPTION_BUFFERING_AUTO, + gettext_noop("Valid values are \"on\", \"off\", and \"auto\".") }, { { @@ -443,15 +471,20 @@ static relopt_string stringRelOpts[] = RELOPT_KIND_VIEW, AccessExclusiveLock }, - 0, - true, - validateWithCheckOption, - NULL + viewCheckOptValues, + VIEW_OPTION_CHECK_OPTION_NOT_SET, + gettext_noop("Valid values are \"local\" and \"cascaded\".") }, /* list terminator */ {{NULL}} }; +static relopt_string stringRelOpts[] = +{ + /* list terminator */ + {{NULL}} +}; + static relopt_gen **relOpts = NULL; static bits32 last_assigned_kind = RELOPT_KIND_LAST_DEFAULT; @@ -461,7 +494,7 @@ static bool need_initialization = true; static void initialize_reloptions(void); static void parse_one_reloption(relopt_value *option, char *text_str, - int text_len, bool validate); + int text_len, bool validate); /* * initialize_reloptions @@ -494,6 +527,12 @@ initialize_reloptions(void) realRelOpts[i].gen.lockmode)); j++; } + for (i = 0; enumRelOpts[i].gen.name; i++) + { + Assert(DoLockModesConflict(enumRelOpts[i].gen.lockmode, + enumRelOpts[i].gen.lockmode)); + j++; + } for (i = 0; stringRelOpts[i].gen.name; i++) { Assert(DoLockModesConflict(stringRelOpts[i].gen.lockmode, @@ -532,6 +571,14 @@ initialize_reloptions(void) j++; } + for (i = 0; enumRelOpts[i].gen.name; i++) + { + relOpts[j] = &enumRelOpts[i].gen; + relOpts[j]->type = RELOPT_TYPE_ENUM; + relOpts[j]->namelen = strlen(relOpts[j]->name); + j++; + } + for (i = 0; stringRelOpts[i].gen.name; i++) { relOpts[j] = &stringRelOpts[i].gen; @@ -610,7 +657,8 @@ add_reloption(relopt_gen *newoption) * (for types other than string) */ static relopt_gen * -allocate_reloption(bits32 kinds, int type, const char *name, const char *desc) +allocate_reloption(bits32 kinds, int type, const char *name, const char *desc, + LOCKMODE lockmode) { MemoryContext oldcxt; size_t size; @@ -629,6 +677,9 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc) case RELOPT_TYPE_REAL: size = sizeof(relopt_real); break; + case RELOPT_TYPE_ENUM: + size = sizeof(relopt_enum); + break; case RELOPT_TYPE_STRING: size = sizeof(relopt_string); break; @@ -647,6 +698,7 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc) newoption->kinds = kinds; newoption->namelen = strlen(name); newoption->type = type; + newoption->lockmode = lockmode; MemoryContextSwitchTo(oldcxt); @@ -658,12 +710,13 @@ allocate_reloption(bits32 kinds, int type, const char *name, const char *desc) * Add a new boolean reloption */ void -add_bool_reloption(bits32 kinds, const char *name, const char *desc, bool default_val) +add_bool_reloption(bits32 kinds, const char *name, const char *desc, + bool default_val, LOCKMODE lockmode) { relopt_bool *newoption; newoption = (relopt_bool *) allocate_reloption(kinds, RELOPT_TYPE_BOOL, - name, desc); + name, desc, lockmode); newoption->default_val = default_val; add_reloption((relopt_gen *) newoption); @@ -675,12 +728,12 @@ add_bool_reloption(bits32 kinds, const char *name, const char *desc, bool defaul */ void add_int_reloption(bits32 kinds, const char *name, const char *desc, int default_val, - int min_val, int max_val) + int min_val, int max_val, LOCKMODE lockmode) { relopt_int *newoption; newoption = (relopt_int *) allocate_reloption(kinds, RELOPT_TYPE_INT, - name, desc); + name, desc, lockmode); newoption->default_val = default_val; newoption->min = min_val; newoption->max = max_val; @@ -694,12 +747,12 @@ add_int_reloption(bits32 kinds, const char *name, const char *desc, int default_ */ void add_real_reloption(bits32 kinds, const char *name, const char *desc, double default_val, - double min_val, double max_val) + double min_val, double max_val, LOCKMODE lockmode) { relopt_real *newoption; newoption = (relopt_real *) allocate_reloption(kinds, RELOPT_TYPE_REAL, - name, desc); + name, desc, lockmode); newoption->default_val = default_val; newoption->min = min_val; newoption->max = max_val; @@ -707,6 +760,34 @@ add_real_reloption(bits32 kinds, const char *name, const char *desc, double defa add_reloption((relopt_gen *) newoption); } +/* + * add_enum_reloption + * Add a new enum reloption + * + * The members array must have a terminating NULL entry. + * + * The detailmsg is shown when unsupported values are passed, and has this + * form: "Valid values are \"foo\", \"bar\", and \"bar\"." + * + * The members array and detailmsg are not copied -- caller must ensure that + * they are valid throughout the life of the process. + */ +void +add_enum_reloption(bits32 kinds, const char *name, const char *desc, + relopt_enum_elt_def *members, int default_val, + const char *detailmsg, LOCKMODE lockmode) +{ + relopt_enum *newoption; + + newoption = (relopt_enum *) allocate_reloption(kinds, RELOPT_TYPE_ENUM, + name, desc, lockmode); + newoption->members = members; + newoption->default_val = default_val; + newoption->detailmsg = detailmsg; + + add_reloption((relopt_gen *) newoption); +} + /* * add_string_reloption * Add a new string reloption @@ -718,7 +799,7 @@ add_real_reloption(bits32 kinds, const char *name, const char *desc, double defa */ void add_string_reloption(bits32 kinds, const char *name, const char *desc, const char *default_val, - validate_string_relopt validator) + validate_string_relopt validator, LOCKMODE lockmode) { relopt_string *newoption; @@ -727,7 +808,7 @@ add_string_reloption(bits32 kinds, const char *name, const char *desc, const cha (validator) (default_val); newoption = (relopt_string *) allocate_reloption(kinds, RELOPT_TYPE_STRING, - name, desc); + name, desc, lockmode); newoption->validate_cb = validator; if (default_val) { @@ -757,8 +838,8 @@ add_string_reloption(bits32 kinds, const char *name, const char *desc, const cha * reloptions value (possibly NULL), and we replace or remove entries * as needed. * - * If ignoreOids is true, then we should ignore any occurrence of "oids" - * in the list (it will be or has been handled by interpretOidsOption()). + * If acceptOidsOff is true, then we allow oids = false, but throw error when + * on. This is solely needed for backwards compatibility. * * Note that this is not responsible for determining whether the options * are valid, but it does check that namespaces for all the options given are @@ -771,7 +852,7 @@ add_string_reloption(bits32 kinds, const char *name, const char *desc, const cha */ Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, - char *validnsps[], bool ignoreOids, bool isReset) + char *validnsps[], bool acceptOidsOff, bool isReset) { Datum result; ArrayBuildState *astate; @@ -882,9 +963,6 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace, def->defnamespace))); } - if (ignoreOids && strcmp(def->defname, "oids") == 0) - continue; - /* ignore if not in the same namespace */ if (namspace == NULL) { @@ -905,6 +983,24 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace, value = defGetString(def); else value = "true"; + + /* + * This is not a great place for this test, but there's no other + * convenient place to filter the option out. As WITH (oids = + * false) will be removed someday, this seems like an acceptable + * amount of ugly. + */ + if (acceptOidsOff && def->defnamespace == NULL && + strcmp(def->defname, "oids") == 0) + { + if (defGetBoolean(def)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("tables declared WITH OIDS are not supported"))); + /* skip over option, reloptions machinery doesn't know it */ + continue; + } + len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value); /* +1 leaves room for sprintf's trailing null */ t = (text *) palloc(len + 1); @@ -1192,7 +1288,7 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, { relopt_real *optreal = (relopt_real *) option->gen; - parsed = parse_real(value, &option->values.real_val); + parsed = parse_real(value, &option->values.real_val, 0, NULL); if (validate && !parsed) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -1208,6 +1304,37 @@ parse_one_reloption(relopt_value *option, char *text_str, int text_len, optreal->min, optreal->max))); } break; + case RELOPT_TYPE_ENUM: + { + relopt_enum *optenum = (relopt_enum *) option->gen; + relopt_enum_elt_def *elt; + + parsed = false; + for (elt = optenum->members; elt->string_val; elt++) + { + if (pg_strcasecmp(value, elt->string_val) == 0) + { + option->values.enum_val = elt->symbol_val; + parsed = true; + break; + } + } + if (validate && !parsed) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid value for enum option \"%s\": %s", + option->gen->name, value), + optenum->detailmsg ? + errdetail_internal("%s", _(optenum->detailmsg)) : 0)); + + /* + * If value is not among the allowed string values, but we are + * not asked to validate, just use the default numeric value. + */ + if (!parsed) + option->values.enum_val = optenum->default_val; + } + break; case RELOPT_TYPE_STRING: { relopt_string *optstring = (relopt_string *) option->gen; @@ -1301,6 +1428,11 @@ fillRelOptions(void *rdopts, Size basesize, options[i].values.real_val : ((relopt_real *) options[i].gen)->default_val; break; + case RELOPT_TYPE_ENUM: + *(int *) itempos = options[i].isset ? + options[i].values.enum_val : + ((relopt_enum *) options[i].gen)->default_val; + break; case RELOPT_TYPE_STRING: optstring = (relopt_string *) options[i].gen; if (options[i].isset) @@ -1328,7 +1460,7 @@ fillRelOptions(void *rdopts, Size basesize, break; } } - if (validate && !found && options[i].gen->kinds != RELOPT_KIND_INDEX) + if (validate && !found) elog(ERROR, "reloption \"%s\" not found in parse table", options[i].gen->name); } @@ -1353,8 +1485,6 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold)}, {"autovacuum_analyze_threshold", RELOPT_TYPE_INT, offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold)}, - {"autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT, - offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)}, {"autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT, offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit)}, {"autovacuum_freeze_min_age", RELOPT_TYPE_INT, @@ -1373,6 +1503,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, log_min_duration)}, {"toast_tuple_target", RELOPT_TYPE_INT, offsetof(StdRdOptions, toast_tuple_target)}, + {"autovacuum_vacuum_cost_delay", RELOPT_TYPE_REAL, + offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay)}, {"autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL, offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)}, {"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL, @@ -1382,7 +1514,11 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) {"parallel_workers", RELOPT_TYPE_INT, offsetof(StdRdOptions, parallel_workers)}, {"vacuum_cleanup_index_scale_factor", RELOPT_TYPE_REAL, - offsetof(StdRdOptions, vacuum_cleanup_index_scale_factor)} + offsetof(StdRdOptions, vacuum_cleanup_index_scale_factor)}, + {"vacuum_index_cleanup", RELOPT_TYPE_BOOL, + offsetof(StdRdOptions, vacuum_index_cleanup)}, + {"vacuum_truncate", RELOPT_TYPE_BOOL, + offsetof(StdRdOptions, vacuum_truncate)} }; options = parseRelOptions(reloptions, validate, kind, &numoptions); @@ -1413,8 +1549,8 @@ view_reloptions(Datum reloptions, bool validate) static const relopt_parse_elt tab[] = { {"security_barrier", RELOPT_TYPE_BOOL, offsetof(ViewOptions, security_barrier)}, - {"check_option", RELOPT_TYPE_STRING, - offsetof(ViewOptions, check_option_offset)} + {"check_option", RELOPT_TYPE_ENUM, + offsetof(ViewOptions, check_option)} }; options = parseRelOptions(reloptions, validate, RELOPT_KIND_VIEW, &numoptions); @@ -1486,40 +1622,6 @@ index_reloptions(amoptions_function amoptions, Datum reloptions, bool validate) return amoptions(reloptions, validate); } -/* - * Parse generic options for all indexes. - * - * reloptions options as text[] datum - * validate error flag - */ -bytea * -index_generic_reloptions(Datum reloptions, bool validate) -{ - int numoptions; - GenericIndexOpts *idxopts; - relopt_value *options; - static const relopt_parse_elt tab[] = { - {"recheck_on_update", RELOPT_TYPE_BOOL, offsetof(GenericIndexOpts, recheck_on_update)} - }; - - options = parseRelOptions(reloptions, validate, - RELOPT_KIND_INDEX, - &numoptions); - - /* if none set, we're done */ - if (numoptions == 0) - return NULL; - - idxopts = allocateReloptStruct(sizeof(GenericIndexOpts), options, numoptions); - - fillRelOptions((void *)idxopts, sizeof(GenericIndexOpts), options, numoptions, - validate, tab, lengthof(tab)); - - pfree(options); - - return (bytea*) idxopts; -} - /* * Option parser for attribute reloptions */ diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c index 781516c56a5..e58ed333c9f 100644 --- a/src/backend/access/common/scankey.c +++ b/src/backend/access/common/scankey.c @@ -3,7 +3,7 @@ * scankey.c * scan key support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -64,9 +64,9 @@ ScanKeyEntryInitialize(ScanKey entry, * It cannot handle NULL arguments, unary operators, or nondefault operators, * but we need none of those features for most hardwired lookups. * - * We set collation to DEFAULT_COLLATION_OID always. This is appropriate - * for textual columns in system catalogs, and it will be ignored for - * non-textual columns, so it's not worth trying to be more finicky. + * We set collation to C_COLLATION_OID always. This is the correct value + * for all collation-aware columns in system catalogs, and it will be ignored + * for other column types, so it's not worth trying to be more finicky. * * Note: CurrentMemoryContext at call should be as long-lived as the ScanKey * itself, because that's what will be used for any subsidiary info attached @@ -83,7 +83,7 @@ ScanKeyInit(ScanKey entry, entry->sk_attno = attributeNumber; entry->sk_strategy = strategy; entry->sk_subtype = InvalidOid; - entry->sk_collation = DEFAULT_COLLATION_OID; + entry->sk_collation = C_COLLATION_OID; entry->sk_argument = argument; fmgr_info(procedure, &entry->sk_func); } diff --git a/src/backend/access/common/session.c b/src/backend/access/common/session.c index ffa7432a3c2..8bcb90b9c6d 100644 --- a/src/backend/access/common/session.c +++ b/src/backend/access/common/session.c @@ -12,7 +12,7 @@ * Currently this infrastructure is used to share: * - typemod registry for ephemeral row-types, i.e. BlessTupleDesc etc. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/backend/access/common/session.c * @@ -133,7 +133,7 @@ GetSessionDsmHandle(void) * If we got this far, we can pin the shared memory so it stays mapped for * the rest of this backend's life. If we don't make it this far, cleanup * callbacks for anything we installed above (ie currently - * SharedRecordTypemodRegistry) will run when the DSM segment is detached + * SharedRecordTypmodRegistry) will run when the DSM segment is detached * by CurrentResourceOwner so we aren't left with a broken CurrentSession. */ dsm_pin_mapping(seg); diff --git a/src/backend/access/common/toast_internals.c b/src/backend/access/common/toast_internals.c new file mode 100644 index 00000000000..a9712424901 --- /dev/null +++ b/src/backend/access/common/toast_internals.c @@ -0,0 +1,632 @@ +/*------------------------------------------------------------------------- + * + * toast_internals.c + * Functions for internal use by the TOAST system. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/access/common/toast_internals.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/detoast.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "access/heaptoast.h" +#include "access/table.h" +#include "access/toast_internals.h" +#include "access/xact.h" +#include "catalog/catalog.h" +#include "common/pg_lzcompress.h" +#include "miscadmin.h" +#include "utils/fmgroids.h" +#include "utils/rel.h" +#include "utils/snapmgr.h" + +static bool toastrel_valueid_exists(Relation toastrel, Oid valueid); +static bool toastid_valueid_exists(Oid toastrelid, Oid valueid); + +/* ---------- + * toast_compress_datum - + * + * Create a compressed version of a varlena datum + * + * If we fail (ie, compressed result is actually bigger than original) + * then return NULL. We must not use compressed data if it'd expand + * the tuple! + * + * We use VAR{SIZE,DATA}_ANY so we can handle short varlenas here without + * copying them. But we can't handle external or compressed datums. + * ---------- + */ +Datum +toast_compress_datum(Datum value) +{ + struct varlena *tmp; + int32 valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); + int32 len; + + Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value))); + Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); + + /* + * No point in wasting a palloc cycle if value size is out of the allowed + * range for compression + */ + if (valsize < PGLZ_strategy_default->min_input_size || + valsize > PGLZ_strategy_default->max_input_size) + return PointerGetDatum(NULL); + + tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) + + TOAST_COMPRESS_HDRSZ); + + /* + * We recheck the actual size even if pglz_compress() reports success, + * because it might be satisfied with having saved as little as one byte + * in the compressed data --- which could turn into a net loss once you + * consider header and alignment padding. Worst case, the compressed + * format might require three padding bytes (plus header, which is + * included in VARSIZE(tmp)), whereas the uncompressed format would take + * only one header byte and no padding if the value is short enough. So + * we insist on a savings of more than 2 bytes to ensure we have a gain. + */ + len = pglz_compress(VARDATA_ANY(DatumGetPointer(value)), + valsize, + TOAST_COMPRESS_RAWDATA(tmp), + PGLZ_strategy_default); + if (len >= 0 && + len + TOAST_COMPRESS_HDRSZ < valsize - 2) + { + TOAST_COMPRESS_SET_RAWSIZE(tmp, valsize); + SET_VARSIZE_COMPRESSED(tmp, len + TOAST_COMPRESS_HDRSZ); + /* successful compression */ + return PointerGetDatum(tmp); + } + else + { + /* incompressible data */ + pfree(tmp); + return PointerGetDatum(NULL); + } +} + +/* ---------- + * toast_save_datum - + * + * Save one single datum into the secondary relation and return + * a Datum reference for it. + * + * rel: the main relation we're working with (not the toast rel!) + * value: datum to be pushed to toast storage + * oldexternal: if not NULL, toast pointer previously representing the datum + * options: options to be passed to heap_insert() for toast rows + * ---------- + */ +Datum +toast_save_datum(Relation rel, Datum value, + struct varlena *oldexternal, int options) +{ + Relation toastrel; + Relation *toastidxs; + HeapTuple toasttup; + TupleDesc toasttupDesc; + Datum t_values[3]; + bool t_isnull[3]; + CommandId mycid = GetCurrentCommandId(true); + struct varlena *result; + struct varatt_external toast_pointer; + union + { + struct varlena hdr; + /* this is to make the union big enough for a chunk: */ + char data[TOAST_MAX_CHUNK_SIZE + VARHDRSZ]; + /* ensure union is aligned well enough: */ + int32 align_it; + } chunk_data; + int32 chunk_size; + int32 chunk_seq = 0; + char *data_p; + int32 data_todo; + Pointer dval = DatumGetPointer(value); + int num_indexes; + int validIndex; + + Assert(!VARATT_IS_EXTERNAL(value)); + + /* + * Open the toast relation and its indexes. We can use the index to check + * uniqueness of the OID we assign to the toasted item, even though it has + * additional columns besides OID. + */ + toastrel = table_open(rel->rd_rel->reltoastrelid, RowExclusiveLock); + toasttupDesc = toastrel->rd_att; + + /* Open all the toast indexes and look for the valid one */ + validIndex = toast_open_indexes(toastrel, + RowExclusiveLock, + &toastidxs, + &num_indexes); + + /* + * Get the data pointer and length, and compute va_rawsize and va_extsize. + * + * va_rawsize is the size of the equivalent fully uncompressed datum, so + * we have to adjust for short headers. + * + * va_extsize is the actual size of the data payload in the toast records. + */ + if (VARATT_IS_SHORT(dval)) + { + data_p = VARDATA_SHORT(dval); + data_todo = VARSIZE_SHORT(dval) - VARHDRSZ_SHORT; + toast_pointer.va_rawsize = data_todo + VARHDRSZ; /* as if not short */ + toast_pointer.va_extsize = data_todo; + } + else if (VARATT_IS_COMPRESSED(dval)) + { + data_p = VARDATA(dval); + data_todo = VARSIZE(dval) - VARHDRSZ; + /* rawsize in a compressed datum is just the size of the payload */ + toast_pointer.va_rawsize = VARRAWSIZE_4B_C(dval) + VARHDRSZ; + toast_pointer.va_extsize = data_todo; + /* Assert that the numbers look like it's compressed */ + Assert(VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); + } + else + { + data_p = VARDATA(dval); + data_todo = VARSIZE(dval) - VARHDRSZ; + toast_pointer.va_rawsize = VARSIZE(dval); + toast_pointer.va_extsize = data_todo; + } + + /* + * Insert the correct table OID into the result TOAST pointer. + * + * Normally this is the actual OID of the target toast table, but during + * table-rewriting operations such as CLUSTER, we have to insert the OID + * of the table's real permanent toast table instead. rd_toastoid is set + * if we have to substitute such an OID. + */ + if (OidIsValid(rel->rd_toastoid)) + toast_pointer.va_toastrelid = rel->rd_toastoid; + else + toast_pointer.va_toastrelid = RelationGetRelid(toastrel); + + /* + * Choose an OID to use as the value ID for this toast value. + * + * Normally we just choose an unused OID within the toast table. But + * during table-rewriting operations where we are preserving an existing + * toast table OID, we want to preserve toast value OIDs too. So, if + * rd_toastoid is set and we had a prior external value from that same + * toast table, re-use its value ID. If we didn't have a prior external + * value (which is a corner case, but possible if the table's attstorage + * options have been changed), we have to pick a value ID that doesn't + * conflict with either new or existing toast value OIDs. + */ + if (!OidIsValid(rel->rd_toastoid)) + { + /* normal case: just choose an unused OID */ + toast_pointer.va_valueid = + GetNewOidWithIndex(toastrel, + RelationGetRelid(toastidxs[validIndex]), + (AttrNumber) 1); + } + else + { + /* rewrite case: check to see if value was in old toast table */ + toast_pointer.va_valueid = InvalidOid; + if (oldexternal != NULL) + { + struct varatt_external old_toast_pointer; + + Assert(VARATT_IS_EXTERNAL_ONDISK(oldexternal)); + /* Must copy to access aligned fields */ + VARATT_EXTERNAL_GET_POINTER(old_toast_pointer, oldexternal); + if (old_toast_pointer.va_toastrelid == rel->rd_toastoid) + { + /* This value came from the old toast table; reuse its OID */ + toast_pointer.va_valueid = old_toast_pointer.va_valueid; + + /* + * There is a corner case here: the table rewrite might have + * to copy both live and recently-dead versions of a row, and + * those versions could easily reference the same toast value. + * When we copy the second or later version of such a row, + * reusing the OID will mean we select an OID that's already + * in the new toast table. Check for that, and if so, just + * fall through without writing the data again. + * + * While annoying and ugly-looking, this is a good thing + * because it ensures that we wind up with only one copy of + * the toast value when there is only one copy in the old + * toast table. Before we detected this case, we'd have made + * multiple copies, wasting space; and what's worse, the + * copies belonging to already-deleted heap tuples would not + * be reclaimed by VACUUM. + */ + if (toastrel_valueid_exists(toastrel, + toast_pointer.va_valueid)) + { + /* Match, so short-circuit the data storage loop below */ + data_todo = 0; + } + } + } + if (toast_pointer.va_valueid == InvalidOid) + { + /* + * new value; must choose an OID that doesn't conflict in either + * old or new toast table + */ + do + { + toast_pointer.va_valueid = + GetNewOidWithIndex(toastrel, + RelationGetRelid(toastidxs[validIndex]), + (AttrNumber) 1); + } while (toastid_valueid_exists(rel->rd_toastoid, + toast_pointer.va_valueid)); + } + } + + /* + * Initialize constant parts of the tuple data + */ + t_values[0] = ObjectIdGetDatum(toast_pointer.va_valueid); + t_values[2] = PointerGetDatum(&chunk_data); + t_isnull[0] = false; + t_isnull[1] = false; + t_isnull[2] = false; + + /* + * Split up the item into chunks + */ + while (data_todo > 0) + { + int i; + + CHECK_FOR_INTERRUPTS(); + + /* + * Calculate the size of this chunk + */ + chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo); + + /* + * Build a tuple and store it + */ + t_values[1] = Int32GetDatum(chunk_seq++); + SET_VARSIZE(&chunk_data, chunk_size + VARHDRSZ); + memcpy(VARDATA(&chunk_data), data_p, chunk_size); + toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull); + + heap_insert(toastrel, toasttup, mycid, options, NULL); + + /* + * Create the index entry. We cheat a little here by not using + * FormIndexDatum: this relies on the knowledge that the index columns + * are the same as the initial columns of the table for all the + * indexes. We also cheat by not providing an IndexInfo: this is okay + * for now because btree doesn't need one, but we might have to be + * more honest someday. + * + * Note also that there had better not be any user-created index on + * the TOAST table, since we don't bother to update anything else. + */ + for (i = 0; i < num_indexes; i++) + { + /* Only index relations marked as ready can be updated */ + if (toastidxs[i]->rd_index->indisready) + index_insert(toastidxs[i], t_values, t_isnull, + &(toasttup->t_self), + toastrel, + toastidxs[i]->rd_index->indisunique ? + UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, + NULL); + } + + /* + * Free memory + */ + heap_freetuple(toasttup); + + /* + * Move on to next chunk + */ + data_todo -= chunk_size; + data_p += chunk_size; + } + + /* + * Done - close toast relation and its indexes + */ + toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); + table_close(toastrel, RowExclusiveLock); + + /* + * Create the TOAST pointer value that we'll return + */ + result = (struct varlena *) palloc(TOAST_POINTER_SIZE); + SET_VARTAG_EXTERNAL(result, VARTAG_ONDISK); + memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer)); + + return PointerGetDatum(result); +} + +/* ---------- + * toast_delete_datum - + * + * Delete a single external stored value. + * ---------- + */ +void +toast_delete_datum(Relation rel, Datum value, bool is_speculative) +{ + struct varlena *attr = (struct varlena *) DatumGetPointer(value); + struct varatt_external toast_pointer; + Relation toastrel; + Relation *toastidxs; + ScanKeyData toastkey; + SysScanDesc toastscan; + HeapTuple toasttup; + int num_indexes; + int validIndex; + SnapshotData SnapshotToast; + + if (!VARATT_IS_EXTERNAL_ONDISK(attr)) + return; + + /* Must copy to access aligned fields */ + VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); + + /* + * Open the toast relation and its indexes + */ + toastrel = table_open(toast_pointer.va_toastrelid, RowExclusiveLock); + + /* Fetch valid relation used for process */ + validIndex = toast_open_indexes(toastrel, + RowExclusiveLock, + &toastidxs, + &num_indexes); + + /* + * Setup a scan key to find chunks with matching va_valueid + */ + ScanKeyInit(&toastkey, + (AttrNumber) 1, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(toast_pointer.va_valueid)); + + /* + * Find all the chunks. (We don't actually care whether we see them in + * sequence or not, but since we've already locked the index we might as + * well use systable_beginscan_ordered.) + */ + init_toast_snapshot(&SnapshotToast); + toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], + &SnapshotToast, 1, &toastkey); + while ((toasttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) + { + /* + * Have a chunk, delete it + */ + if (is_speculative) + heap_abort_speculative(toastrel, &toasttup->t_self); + else + simple_heap_delete(toastrel, &toasttup->t_self); + } + + /* + * End scan and close relations + */ + systable_endscan_ordered(toastscan); + toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); + table_close(toastrel, RowExclusiveLock); +} + +/* ---------- + * toastrel_valueid_exists - + * + * Test whether a toast value with the given ID exists in the toast relation. + * For safety, we consider a value to exist if there are either live or dead + * toast rows with that ID; see notes for GetNewOidWithIndex(). + * ---------- + */ +static bool +toastrel_valueid_exists(Relation toastrel, Oid valueid) +{ + bool result = false; + ScanKeyData toastkey; + SysScanDesc toastscan; + int num_indexes; + int validIndex; + Relation *toastidxs; + + /* Fetch a valid index relation */ + validIndex = toast_open_indexes(toastrel, + RowExclusiveLock, + &toastidxs, + &num_indexes); + + /* + * Setup a scan key to find chunks with matching va_valueid + */ + ScanKeyInit(&toastkey, + (AttrNumber) 1, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(valueid)); + + /* + * Is there any such chunk? + */ + toastscan = systable_beginscan(toastrel, + RelationGetRelid(toastidxs[validIndex]), + true, SnapshotAny, 1, &toastkey); + + if (systable_getnext(toastscan) != NULL) + result = true; + + systable_endscan(toastscan); + + /* Clean up */ + toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); + + return result; +} + +/* ---------- + * toastid_valueid_exists - + * + * As above, but work from toast rel's OID not an open relation + * ---------- + */ +static bool +toastid_valueid_exists(Oid toastrelid, Oid valueid) +{ + bool result; + Relation toastrel; + + toastrel = table_open(toastrelid, AccessShareLock); + + result = toastrel_valueid_exists(toastrel, valueid); + + table_close(toastrel, AccessShareLock); + + return result; +} + +/* ---------- + * toast_get_valid_index + * + * Get OID of valid index associated to given toast relation. A toast + * relation can have only one valid index at the same time. + */ +Oid +toast_get_valid_index(Oid toastoid, LOCKMODE lock) +{ + int num_indexes; + int validIndex; + Oid validIndexOid; + Relation *toastidxs; + Relation toastrel; + + /* Open the toast relation */ + toastrel = table_open(toastoid, lock); + + /* Look for the valid index of the toast relation */ + validIndex = toast_open_indexes(toastrel, + lock, + &toastidxs, + &num_indexes); + validIndexOid = RelationGetRelid(toastidxs[validIndex]); + + /* Close the toast relation and all its indexes */ + toast_close_indexes(toastidxs, num_indexes, lock); + table_close(toastrel, lock); + + return validIndexOid; +} + +/* ---------- + * toast_open_indexes + * + * Get an array of the indexes associated to the given toast relation + * and return as well the position of the valid index used by the toast + * relation in this array. It is the responsibility of the caller of this + * function to close the indexes as well as free them. + */ +int +toast_open_indexes(Relation toastrel, + LOCKMODE lock, + Relation **toastidxs, + int *num_indexes) +{ + int i = 0; + int res = 0; + bool found = false; + List *indexlist; + ListCell *lc; + + /* Get index list of the toast relation */ + indexlist = RelationGetIndexList(toastrel); + Assert(indexlist != NIL); + + *num_indexes = list_length(indexlist); + + /* Open all the index relations */ + *toastidxs = (Relation *) palloc(*num_indexes * sizeof(Relation)); + foreach(lc, indexlist) + (*toastidxs)[i++] = index_open(lfirst_oid(lc), lock); + + /* Fetch the first valid index in list */ + for (i = 0; i < *num_indexes; i++) + { + Relation toastidx = (*toastidxs)[i]; + + if (toastidx->rd_index->indisvalid) + { + res = i; + found = true; + break; + } + } + + /* + * Free index list, not necessary anymore as relations are opened and a + * valid index has been found. + */ + list_free(indexlist); + + /* + * The toast relation should have one valid index, so something is going + * wrong if there is nothing. + */ + if (!found) + elog(ERROR, "no valid index found for toast relation with Oid %u", + RelationGetRelid(toastrel)); + + return res; +} + +/* ---------- + * toast_close_indexes + * + * Close an array of indexes for a toast relation and free it. This should + * be called for a set of indexes opened previously with toast_open_indexes. + */ +void +toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock) +{ + int i; + + /* Close relations and clean up things */ + for (i = 0; i < num_indexes; i++) + index_close(toastidxs[i], lock); + pfree(toastidxs); +} + +/* ---------- + * init_toast_snapshot + * + * Initialize an appropriate TOAST snapshot. We must use an MVCC snapshot + * to initialize the TOAST snapshot; since we don't know which one to use, + * just use the oldest one. This is safe: at worst, we will get a "snapshot + * too old" error that might have been avoided otherwise. + */ +void +init_toast_snapshot(Snapshot toast_snapshot) +{ + Snapshot snapshot = GetOldestSnapshot(); + + if (snapshot == NULL) + elog(ERROR, "no known snapshots"); + + InitToastSnapshot(*toast_snapshot, snapshot->lsn, snapshot->whenTaken); +} diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c index 2d0d2f4b32f..0ec9cd5870d 100644 --- a/src/backend/access/common/tupconvert.c +++ b/src/backend/access/common/tupconvert.c @@ -4,12 +4,10 @@ * Tuple conversion support. * * These functions provide conversion between rowtypes that are logically - * equivalent but might have columns in a different order or different sets - * of dropped columns. There is some overlap of functionality with the - * executor's "junkfilter" routines, but these functions work on bare - * HeapTuples rather than TupleTableSlots. + * equivalent but might have columns in a different order or different sets of + * dropped columns. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,6 +20,7 @@ #include "access/htup_details.h" #include "access/tupconvert.h" +#include "executor/tuptable.h" #include "utils/builtins.h" @@ -31,7 +30,7 @@ * The setup routine checks whether the given source and destination tuple * descriptors are logically compatible. If not, it throws an error. * If so, it returns NULL if they are physically compatible (ie, no conversion - * is needed), else a TupleConversionMap that can be used by do_convert_tuple + * is needed), else a TupleConversionMap that can be used by execute_attr_map_tuple * to perform the conversion. * * The TupleConversionMap, if needed, is palloc'd in the caller's memory @@ -139,13 +138,9 @@ convert_tuples_by_position(TupleDesc indesc, /* * Check to see if the map is one-to-one, in which case we need not do a - * tuple conversion. We must also insist that both tupdescs either - * specify or don't specify an OID column, else we need a conversion to - * add/remove space for that. (For some callers, presence or absence of - * an OID column perhaps would not really matter, but let's be safe.) + * tuple conversion. */ - if (indesc->natts == outdesc->natts && - indesc->tdhasoid == outdesc->tdhasoid) + if (indesc->natts == outdesc->natts) { for (i = 0; i < n; i++) { @@ -208,61 +203,18 @@ convert_tuples_by_position(TupleDesc indesc, */ TupleConversionMap * convert_tuples_by_name(TupleDesc indesc, - TupleDesc outdesc, - const char *msg) + TupleDesc outdesc) { TupleConversionMap *map; AttrNumber *attrMap; int n = outdesc->natts; - int i; - bool same; /* Verify compatibility and prepare attribute-number map */ - attrMap = convert_tuples_by_name_map(indesc, outdesc, msg); + attrMap = convert_tuples_by_name_map_if_req(indesc, outdesc); - /* - * Check to see if the map is one-to-one, in which case we need not do a - * tuple conversion. We must also insist that both tupdescs either - * specify or don't specify an OID column, else we need a conversion to - * add/remove space for that. (For some callers, presence or absence of - * an OID column perhaps would not really matter, but let's be safe.) - */ - if (indesc->natts == outdesc->natts && - indesc->tdhasoid == outdesc->tdhasoid) + if (attrMap == NULL) { - same = true; - for (i = 0; i < n; i++) - { - Form_pg_attribute inatt; - Form_pg_attribute outatt; - - if (attrMap[i] == (i + 1)) - continue; - - /* - * If it's a dropped column and the corresponding input column is - * also dropped, we needn't convert. However, attlen and attalign - * must agree. - */ - inatt = TupleDescAttr(indesc, i); - outatt = TupleDescAttr(outdesc, i); - if (attrMap[i] == 0 && - inatt->attisdropped && - inatt->attlen == outatt->attlen && - inatt->attalign == outatt->attalign) - continue; - - same = false; - break; - } - } - else - same = false; - - if (same) - { - /* Runtime conversion is not needed */ - pfree(attrMap); + /* runtime conversion is not needed */ return NULL; } @@ -291,16 +243,19 @@ convert_tuples_by_name(TupleDesc indesc, */ AttrNumber * convert_tuples_by_name_map(TupleDesc indesc, - TupleDesc outdesc, - const char *msg) + TupleDesc outdesc) { AttrNumber *attrMap; - int n; + int outnatts; + int innatts; int i; + int nextindesc = -1; - n = outdesc->natts; - attrMap = (AttrNumber *) palloc0(n * sizeof(AttrNumber)); - for (i = 0; i < n; i++) + outnatts = outdesc->natts; + innatts = indesc->natts; + + attrMap = (AttrNumber *) palloc0(outnatts * sizeof(AttrNumber)); + for (i = 0; i < outnatts; i++) { Form_pg_attribute outatt = TupleDescAttr(outdesc, i); char *attname; @@ -313,10 +268,27 @@ convert_tuples_by_name_map(TupleDesc indesc, attname = NameStr(outatt->attname); atttypid = outatt->atttypid; atttypmod = outatt->atttypmod; - for (j = 0; j < indesc->natts; j++) + + /* + * Now search for an attribute with the same name in the indesc. It + * seems likely that a partitioned table will have the attributes in + * the same order as the partition, so the search below is optimized + * for that case. It is possible that columns are dropped in one of + * the relations, but not the other, so we use the 'nextindesc' + * counter to track the starting point of the search. If the inner + * loop encounters dropped columns then it will have to skip over + * them, but it should leave 'nextindesc' at the correct position for + * the next outer loop. + */ + for (j = 0; j < innatts; j++) { - Form_pg_attribute inatt = TupleDescAttr(indesc, j); + Form_pg_attribute inatt; + nextindesc++; + if (nextindesc >= innatts) + nextindesc = 0; + + inatt = TupleDescAttr(indesc, nextindesc); if (inatt->attisdropped) continue; if (strcmp(attname, NameStr(inatt->attname)) == 0) @@ -325,33 +297,94 @@ convert_tuples_by_name_map(TupleDesc indesc, if (atttypid != inatt->atttypid || atttypmod != inatt->atttypmod) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg_internal("%s", _(msg)), + errmsg("could not convert row type"), errdetail("Attribute \"%s\" of type %s does not match corresponding attribute of type %s.", attname, format_type_be(outdesc->tdtypeid), format_type_be(indesc->tdtypeid)))); - attrMap[i] = (AttrNumber) (j + 1); + attrMap[i] = inatt->attnum; break; } } if (attrMap[i] == 0) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg_internal("%s", _(msg)), + errmsg("could not convert row type"), errdetail("Attribute \"%s\" of type %s does not exist in type %s.", attname, format_type_be(outdesc->tdtypeid), format_type_be(indesc->tdtypeid)))); } - return attrMap; } +/* + * Returns mapping created by convert_tuples_by_name_map, or NULL if no + * conversion not required. This is a convenience routine for + * convert_tuples_by_name() and other functions. + */ +AttrNumber * +convert_tuples_by_name_map_if_req(TupleDesc indesc, + TupleDesc outdesc) +{ + AttrNumber *attrMap; + int n = outdesc->natts; + int i; + bool same; + + /* Verify compatibility and prepare attribute-number map */ + attrMap = convert_tuples_by_name_map(indesc, outdesc); + + /* + * Check to see if the map is one-to-one, in which case we need not do a + * tuple conversion. + */ + if (indesc->natts == outdesc->natts) + { + same = true; + for (i = 0; i < n; i++) + { + Form_pg_attribute inatt; + Form_pg_attribute outatt; + + if (attrMap[i] == (i + 1)) + continue; + + /* + * If it's a dropped column and the corresponding input column is + * also dropped, we needn't convert. However, attlen and attalign + * must agree. + */ + inatt = TupleDescAttr(indesc, i); + outatt = TupleDescAttr(outdesc, i); + if (attrMap[i] == 0 && + inatt->attisdropped && + inatt->attlen == outatt->attlen && + inatt->attalign == outatt->attalign) + continue; + + same = false; + break; + } + } + else + same = false; + + if (same) + { + /* Runtime conversion is not needed */ + pfree(attrMap); + return NULL; + } + else + return attrMap; +} + /* * Perform conversion of a tuple according to the map. */ HeapTuple -do_convert_tuple(HeapTuple tuple, TupleConversionMap *map) +execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map) { AttrNumber *attrMap = map->attrMap; Datum *invalues = map->invalues; @@ -385,6 +418,62 @@ do_convert_tuple(HeapTuple tuple, TupleConversionMap *map) return heap_form_tuple(map->outdesc, outvalues, outisnull); } +/* + * Perform conversion of a tuple slot according to the map. + */ +TupleTableSlot * +execute_attr_map_slot(AttrNumber *attrMap, + TupleTableSlot *in_slot, + TupleTableSlot *out_slot) +{ + Datum *invalues; + bool *inisnull; + Datum *outvalues; + bool *outisnull; + int outnatts; + int i; + + /* Sanity checks */ + Assert(in_slot->tts_tupleDescriptor != NULL && + out_slot->tts_tupleDescriptor != NULL); + Assert(in_slot->tts_values != NULL && out_slot->tts_values != NULL); + + outnatts = out_slot->tts_tupleDescriptor->natts; + + /* Extract all the values of the in slot. */ + slot_getallattrs(in_slot); + + /* Before doing the mapping, clear any old contents from the out slot */ + ExecClearTuple(out_slot); + + invalues = in_slot->tts_values; + inisnull = in_slot->tts_isnull; + outvalues = out_slot->tts_values; + outisnull = out_slot->tts_isnull; + + /* Transpose into proper fields of the out slot. */ + for (i = 0; i < outnatts; i++) + { + int j = attrMap[i] - 1; + + /* attrMap[i] == 0 means it's a NULL datum. */ + if (j == -1) + { + outvalues[i] = (Datum) 0; + outisnull[i] = true; + } + else + { + outvalues[i] = invalues[j]; + outisnull[i] = inisnull[j]; + } + } + + ExecStoreVirtualTuple(out_slot); + + return out_slot; +} + /* * Free a TupleConversionMap structure. */ diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c index 2658399484b..6bc4e4c0360 100644 --- a/src/backend/access/common/tupdesc.c +++ b/src/backend/access/common/tupdesc.c @@ -3,7 +3,7 @@ * tupdesc.c * POSTGRES tuple descriptor support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,7 +19,6 @@ #include "postgres.h" -#include "access/hash.h" #include "access/htup_details.h" #include "access/tupdesc_details.h" #include "catalog/pg_collation.h" @@ -42,7 +41,7 @@ * caller can overwrite this if needed. */ TupleDesc -CreateTemplateTupleDesc(int natts, bool hasoid) +CreateTemplateTupleDesc(int natts) { TupleDesc desc; @@ -63,7 +62,7 @@ CreateTemplateTupleDesc(int natts, bool hasoid) * could be less due to trailing padding, although with the current * definition of pg_attribute there probably isn't any padding. */ - desc = (TupleDesc) palloc(offsetof(struct tupleDesc, attrs) + + desc = (TupleDesc) palloc(offsetof(struct TupleDescData, attrs) + natts * sizeof(FormData_pg_attribute)); /* @@ -73,7 +72,6 @@ CreateTemplateTupleDesc(int natts, bool hasoid) desc->constr = NULL; desc->tdtypeid = RECORDOID; desc->tdtypmod = -1; - desc->tdhasoid = hasoid; desc->tdrefcount = -1; /* assume not reference-counted */ return desc; @@ -88,12 +86,12 @@ CreateTemplateTupleDesc(int natts, bool hasoid) * caller can overwrite this if needed. */ TupleDesc -CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs) +CreateTupleDesc(int natts, Form_pg_attribute *attrs) { TupleDesc desc; int i; - desc = CreateTemplateTupleDesc(natts, hasoid); + desc = CreateTemplateTupleDesc(natts); for (i = 0; i < natts; ++i) memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE); @@ -114,7 +112,7 @@ CreateTupleDescCopy(TupleDesc tupdesc) TupleDesc desc; int i; - desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid); + desc = CreateTemplateTupleDesc(tupdesc->natts); /* Flat-copy the attribute array */ memcpy(TupleDescAttr(desc, 0), @@ -133,6 +131,7 @@ CreateTupleDescCopy(TupleDesc tupdesc) att->atthasdef = false; att->atthasmissing = false; att->attidentity = '\0'; + att->attgenerated = '\0'; } /* We can copy the tuple type identification, too */ @@ -154,7 +153,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) TupleConstr *constr = tupdesc->constr; int i; - desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid); + desc = CreateTemplateTupleDesc(tupdesc->natts); /* Flat-copy the attribute array */ memcpy(TupleDescAttr(desc, 0), @@ -167,6 +166,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) TupleConstr *cpy = (TupleConstr *) palloc0(sizeof(TupleConstr)); cpy->has_not_null = constr->has_not_null; + cpy->has_generated_stored = constr->has_generated_stored; if ((cpy->num_defval = constr->num_defval) > 0) { @@ -185,13 +185,13 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc) memcpy(cpy->missing, constr->missing, tupdesc->natts * sizeof(AttrMissing)); for (i = tupdesc->natts - 1; i >= 0; i--) { - if (constr->missing[i].ammissingPresent) + if (constr->missing[i].am_present) { Form_pg_attribute attr = TupleDescAttr(tupdesc, i); - cpy->missing[i].ammissing = datumCopy(constr->missing[i].ammissing, - attr->attbyval, - attr->attlen); + cpy->missing[i].am_value = datumCopy(constr->missing[i].am_value, + attr->attbyval, + attr->attlen); } } } @@ -249,6 +249,7 @@ TupleDescCopy(TupleDesc dst, TupleDesc src) att->atthasdef = false; att->atthasmissing = false; att->attidentity = '\0'; + att->attgenerated = '\0'; } dst->constr = NULL; @@ -302,6 +303,7 @@ TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, dstAtt->atthasdef = false; dstAtt->atthasmissing = false; dstAtt->attidentity = '\0'; + dstAtt->attgenerated = '\0'; } /* @@ -337,9 +339,9 @@ FreeTupleDesc(TupleDesc tupdesc) for (i = tupdesc->natts - 1; i >= 0; i--) { - if (attrmiss[i].ammissingPresent + if (attrmiss[i].am_present && !TupleDescAttr(tupdesc, i)->attbyval) - pfree(DatumGetPointer(attrmiss[i].ammissing)); + pfree(DatumGetPointer(attrmiss[i].am_value)); } pfree(attrmiss); } @@ -416,8 +418,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; if (tupdesc1->tdtypeid != tupdesc2->tdtypeid) return false; - if (tupdesc1->tdhasoid != tupdesc2->tdhasoid) - return false; for (i = 0; i < tupdesc1->natts; i++) { @@ -460,6 +460,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; if (attr1->attidentity != attr2->attidentity) return false; + if (attr1->attgenerated != attr2->attgenerated) + return false; if (attr1->attisdropped != attr2->attisdropped) return false; if (attr1->attislocal != attr2->attislocal) @@ -480,6 +482,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) return false; if (constr1->has_not_null != constr2->has_not_null) return false; + if (constr1->has_generated_stored != constr2->has_generated_stored) + return false; n = constr1->num_defval; if (n != (int) constr2->num_defval) return false; @@ -512,13 +516,13 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2) AttrMissing *missval1 = constr1->missing + i; AttrMissing *missval2 = constr2->missing + i; - if (missval1->ammissingPresent != missval2->ammissingPresent) + if (missval1->am_present != missval2->am_present) return false; - if (missval1->ammissingPresent) + if (missval1->am_present) { Form_pg_attribute missatt1 = TupleDescAttr(tupdesc1, i); - if (!datumIsEqual(missval1->ammissing, missval2->ammissing, + if (!datumIsEqual(missval1->am_value, missval2->am_value, missatt1->attbyval, missatt1->attlen)) return false; } @@ -574,7 +578,6 @@ hashTupleDesc(TupleDesc desc) s = hash_combine(0, hash_uint32(desc->natts)); s = hash_combine(s, hash_uint32(desc->tdtypeid)); - s = hash_combine(s, hash_uint32(desc->tdhasoid)); for (i = 0; i < desc->natts; ++i) s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid)); @@ -643,6 +646,7 @@ TupleDescInitEntry(TupleDesc desc, att->atthasdef = false; att->atthasmissing = false; att->attidentity = '\0'; + att->attgenerated = '\0'; att->attisdropped = false; att->attislocal = true; att->attinhcount = 0; @@ -702,6 +706,7 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->atthasdef = false; att->atthasmissing = false; att->attidentity = '\0'; + att->attgenerated = '\0'; att->attisdropped = false; att->attislocal = true; att->attinhcount = 0; @@ -748,6 +753,9 @@ TupleDescInitBuiltinEntry(TupleDesc desc, att->attstorage = 'p'; att->attcollation = InvalidOid; break; + + default: + elog(ERROR, "unsupported type %u", oidtypeid); } } @@ -800,7 +808,7 @@ BuildDescForRelation(List *schema) * allocate a new tuple descriptor */ natts = list_length(schema); - desc = CreateTemplateTupleDesc(natts, false); + desc = CreateTemplateTupleDesc(natts); has_not_null = false; attnum = 0; @@ -855,6 +863,7 @@ BuildDescForRelation(List *schema) TupleConstr *constr = (TupleConstr *) palloc0(sizeof(TupleConstr)); constr->has_not_null = true; + constr->has_generated_stored = false; constr->defval = NULL; constr->missing = NULL; constr->num_defval = 0; @@ -900,26 +909,15 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations) /* * allocate a new tuple descriptor */ - desc = CreateTemplateTupleDesc(natts, false); + desc = CreateTemplateTupleDesc(natts); attnum = 0; - - l2 = list_head(types); - l3 = list_head(typmods); - l4 = list_head(collations); - foreach(l1, names) + forfour(l1, names, l2, types, l3, typmods, l4, collations) { char *attname = strVal(lfirst(l1)); - Oid atttypid; - int32 atttypmod; - Oid attcollation; - - atttypid = lfirst_oid(l2); - l2 = lnext(l2); - atttypmod = lfirst_int(l3); - l3 = lnext(l3); - attcollation = lfirst_oid(l4); - l4 = lnext(l4); + Oid atttypid = lfirst_oid(l2); + int32 atttypmod = lfirst_int(l3); + Oid attcollation = lfirst_oid(l4); attnum++; diff --git a/src/backend/access/gin/README b/src/backend/access/gin/README index 990b5ffa581..76c12ae2f6b 100644 --- a/src/backend/access/gin/README +++ b/src/backend/access/gin/README @@ -163,7 +163,7 @@ algorithms. * The posting list can be accessed with GinGetPosting(itup) -* If GinITupIsCompressed(itup), the posting list is stored in compressed +* If GinItupIsCompressed(itup), the posting list is stored in compressed format. Otherwise it is just an array of ItemPointers. New tuples are always stored in compressed format, uncompressed items can be present if the database was migrated from 9.3 or earlier version. @@ -270,7 +270,7 @@ is stored in the higher bits. That requires 43 bits in total, which conveniently fits in at most 6 bytes. A compressed posting list is passed around and stored on disk in a -PackedPostingList struct. The first item in the list is stored uncompressed +GinPostingList struct. The first item in the list is stored uncompressed as a regular ItemPointerData, followed by the length of the list in bytes, followed by the packed items. @@ -304,33 +304,58 @@ the lock on next page has been acquired. The downlink is more tricky. A search descending the tree must release the lock on the parent page before locking the child, or it could deadlock with a concurrent split of the child page; a page split locks the parent, while -already holding a lock on the child page. However, posting trees are only -fully searched from left to right, starting from the leftmost leaf. (The -tree-structure is only needed by insertions, to quickly find the correct -insert location). So as long as we don't delete the leftmost page on each -level, a search can never follow a downlink to page that's about to be -deleted. +already holding a lock on the child page. So, deleted page cannot be reclaimed +immediately. Instead, we have to wait for every transaction, which might wait +to reference this page, to finish. Corresponding processes must observe that +the page is marked deleted and recover accordingly. The previous paragraph's reasoning only applies to searches, and only to posting trees. To protect from inserters following a downlink to a deleted page, vacuum simply locks out all concurrent insertions to the posting tree, -by holding a super-exclusive lock on the parent page of subtree with deletable -pages. Inserters hold a pin on the root page, but searches do not, so while -new searches cannot begin while root page is locked, any already-in-progress -scans can continue concurrently with vacuum in corresponding subtree of -posting tree. To exclude interference with readers vacuum takes exclusive -locks in a depth-first scan in left-to-right order of page tuples. Leftmost -page is never deleted. Thus before deleting any page we obtain exclusive -lock on any left page, effectively excluding deadlock with any reader, despite -taking parent lock before current and left lock after current. We take left -lock not for a concurrency reasons, but rather in need to mark page dirty. -In the entry tree, we never delete pages. +by holding a super-exclusive lock on the posting tree root. Inserters hold a +pin on the root page, but searches do not, so while new searches cannot begin +while root page is locked, any already-in-progress scans can continue +concurrently with vacuum. In the entry tree, we never delete pages. (This is quite different from the mechanism the btree indexam uses to make page-deletions safe; it stamps the deleted pages with an XID and keeps the deleted pages around with the right-link intact until all concurrent scans have finished.) +Predicate Locking +----------------- + +GIN supports predicate locking, for serializable snapshot isolation. +A predicate locks represent that a scan has scanned a range of values. They +are not concerned with physical pages as such, but the logical key values. +A predicate lock on a page covers the key range that would belong on that +page, whether or not there are any matching tuples there currently. In other +words, a predicate lock on an index page covers the "gaps" between the index +tuples. To minimize false positives, predicate locks are acquired at the +finest level possible. + +* Like in the B-tree index, it is enough to lock only leaf pages, because all + insertions happen at the leaf level. + +* In an equality search (i.e. not a partial match search), if a key entry has + a posting tree, we lock the posting tree root page, to represent a lock on + just that key entry. Otherwise, we lock the entry tree page. We also lock + the entry tree page if no match is found, to lock the "gap" where the entry + would've been, had there been one. + +* In a partial match search, we lock all the entry leaf pages that we scan, + in addition to locks on posting tree roots, to represent the "gaps" between + values. + +* In addition to the locks on entry leaf pages and posting tree roots, all + scans grab a lock the metapage. This is to interlock with insertions to + the fast update pending list. An insertion to the pending list can really + belong anywhere in the tree, and the lock on the metapage represents that. + +The interlock for fastupdate pending lists means that with fastupdate=on, +we effectively always grab a full-index lock, so you could get a lot of false +positives. + Compatibility ------------- diff --git a/src/backend/access/gin/ginarrayproc.c b/src/backend/access/gin/ginarrayproc.c index d0fa4adf87c..fd94f776dda 100644 --- a/src/backend/access/gin/ginarrayproc.c +++ b/src/backend/access/gin/ginarrayproc.c @@ -4,7 +4,7 @@ * support functions for GIN's indexing of any array * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginbtree.c b/src/backend/access/gin/ginbtree.c index 095b1192cb4..4c29261256a 100644 --- a/src/backend/access/gin/ginbtree.c +++ b/src/backend/access/gin/ginbtree.c @@ -4,7 +4,7 @@ * page utilities routines for the postgres inverted index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,10 +24,10 @@ static void ginFindParents(GinBtree btree, GinBtreeStack *stack); static bool ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, - void *insertdata, BlockNumber updateblkno, - Buffer childbuf, GinStatsData *buildStats); + void *insertdata, BlockNumber updateblkno, + Buffer childbuf, GinStatsData *buildStats); static void ginFinishSplit(GinBtree btree, GinBtreeStack *stack, - bool freestack, GinStatsData *buildStats); + bool freestack, GinStatsData *buildStats); /* * Lock buffer by needed method for search. @@ -72,9 +72,13 @@ ginTraverseLock(Buffer buffer, bool searchMode) * If 'searchmode' is false, on return stack->buffer is exclusively locked, * and the stack represents the full path to the root. Otherwise stack->buffer * is share-locked, and stack->parent is NULL. + * + * If 'rootConflictCheck' is true, tree root is checked for serialization + * conflict. */ GinBtreeStack * -ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot) +ginFindLeafPage(GinBtree btree, bool searchMode, + bool rootConflictCheck, Snapshot snapshot) { GinBtreeStack *stack; @@ -84,6 +88,9 @@ ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot) stack->parent = NULL; stack->predictNumber = 1; + if (rootConflictCheck) + CheckForSerializableConflictIn(btree->index, NULL, stack->buffer); + for (;;) { Page page; @@ -208,7 +215,7 @@ freeGinBtreeStack(GinBtreeStack *stack) /* * Try to find parent for current stack position. Returns correct parent and * child's offset in stack->parent. The root page is never released, to - * to prevent conflict with vacuum process. + * prevent conflict with vacuum process. */ static void ginFindParents(GinBtree btree, GinBtreeStack *stack) @@ -389,7 +396,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, /* It will fit, perform the insertion */ START_CRIT_SECTION(); - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { XLogBeginInsert(); XLogRegisterBuffer(0, stack->buffer, REGBUF_STANDARD); @@ -410,7 +417,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, MarkBufferDirty(childbuf); } - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { XLogRecPtr recptr; ginxlogInsert xlrec; @@ -521,12 +528,12 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, { PredicateLockPageSplit(btree->index, - BufferGetBlockNumber(stack->buffer), - BufferGetBlockNumber(lbuffer)); + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(lbuffer)); PredicateLockPageSplit(btree->index, - BufferGetBlockNumber(stack->buffer), - BufferGetBlockNumber(rbuffer)); + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(rbuffer)); } } @@ -543,8 +550,8 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, { PredicateLockPageSplit(btree->index, - BufferGetBlockNumber(stack->buffer), - BufferGetBlockNumber(rbuffer)); + BufferGetBlockNumber(stack->buffer), + BufferGetBlockNumber(rbuffer)); } } @@ -588,7 +595,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, } /* write WAL record */ - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { XLogRecPtr recptr; @@ -643,7 +650,7 @@ ginPlaceToPage(GinBtree btree, GinBtreeStack *stack, } else { - elog(ERROR, "invalid return code from GIN placeToPage method: %d", rc); + elog(ERROR, "invalid return code from GIN beginPlaceToPage method: %d", rc); result = false; /* keep compiler quiet */ } diff --git a/src/backend/access/gin/ginbulk.c b/src/backend/access/gin/ginbulk.c index 989c2a0c028..c8543101649 100644 --- a/src/backend/access/gin/ginbulk.c +++ b/src/backend/access/gin/ginbulk.c @@ -4,7 +4,7 @@ * routines for fast build of inverted index * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -27,7 +27,7 @@ /* Combiner function for rbtree.c */ static void -ginCombineData(RBNode *existing, const RBNode *newdata, void *arg) +ginCombineData(RBTNode *existing, const RBTNode *newdata, void *arg) { GinEntryAccumulator *eo = (GinEntryAccumulator *) existing; const GinEntryAccumulator *en = (const GinEntryAccumulator *) newdata; @@ -69,7 +69,7 @@ ginCombineData(RBNode *existing, const RBNode *newdata, void *arg) /* Comparator function for rbtree.c */ static int -cmpEntryAccumulator(const RBNode *a, const RBNode *b, void *arg) +cmpEntryAccumulator(const RBTNode *a, const RBTNode *b, void *arg) { const GinEntryAccumulator *ea = (const GinEntryAccumulator *) a; const GinEntryAccumulator *eb = (const GinEntryAccumulator *) b; @@ -81,7 +81,7 @@ cmpEntryAccumulator(const RBNode *a, const RBNode *b, void *arg) } /* Allocator function for rbtree.c */ -static RBNode * +static RBTNode * ginAllocEntryAccumulator(void *arg) { BuildAccumulator *accum = (BuildAccumulator *) arg; @@ -89,7 +89,7 @@ ginAllocEntryAccumulator(void *arg) /* * Allocate memory by rather big chunks to decrease overhead. We have no - * need to reclaim RBNodes individually, so this costs nothing. + * need to reclaim RBTNodes individually, so this costs nothing. */ if (accum->entryallocator == NULL || accum->eas_used >= DEF_NENTRY) { @@ -98,11 +98,11 @@ ginAllocEntryAccumulator(void *arg) accum->eas_used = 0; } - /* Allocate new RBNode from current chunk */ + /* Allocate new RBTNode from current chunk */ ea = accum->entryallocator + accum->eas_used; accum->eas_used++; - return (RBNode *) ea; + return (RBTNode *) ea; } void @@ -112,12 +112,12 @@ ginInitBA(BuildAccumulator *accum) accum->allocatedMemory = 0; accum->entryallocator = NULL; accum->eas_used = 0; - accum->tree = rb_create(sizeof(GinEntryAccumulator), - cmpEntryAccumulator, - ginCombineData, - ginAllocEntryAccumulator, - NULL, /* no freefunc needed */ - (void *) accum); + accum->tree = rbt_create(sizeof(GinEntryAccumulator), + cmpEntryAccumulator, + ginCombineData, + ginAllocEntryAccumulator, + NULL, /* no freefunc needed */ + (void *) accum); } /* @@ -163,8 +163,8 @@ ginInsertBAEntry(BuildAccumulator *accum, /* temporarily set up single-entry itempointer list */ eatmp.list = heapptr; - ea = (GinEntryAccumulator *) rb_insert(accum->tree, (RBNode *) &eatmp, - &isNew); + ea = (GinEntryAccumulator *) rbt_insert(accum->tree, (RBTNode *) &eatmp, + &isNew); if (isNew) { @@ -256,7 +256,7 @@ qsortCompareItemPointers(const void *a, const void *b) void ginBeginBAScan(BuildAccumulator *accum) { - rb_begin_iterate(accum->tree, LeftRightWalk, &accum->tree_walk); + rbt_begin_iterate(accum->tree, LeftRightWalk, &accum->tree_walk); } /* @@ -272,7 +272,7 @@ ginGetBAEntry(BuildAccumulator *accum, GinEntryAccumulator *entry; ItemPointerData *list; - entry = (GinEntryAccumulator *) rb_iterate(&accum->tree_walk); + entry = (GinEntryAccumulator *) rbt_iterate(&accum->tree_walk); if (entry == NULL) return NULL; /* no more entries */ diff --git a/src/backend/access/gin/gindatapage.c b/src/backend/access/gin/gindatapage.c index 642ca1a2c73..e8c34d6b1f6 100644 --- a/src/backend/access/gin/gindatapage.c +++ b/src/backend/access/gin/gindatapage.c @@ -4,7 +4,7 @@ * routines for handling GIN posting tree pages. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -92,7 +92,7 @@ typedef struct /* * The following fields represent the items in this segment. If 'items' is - * not NULL, it contains a palloc'd array of the itemsin this segment. If + * not NULL, it contains a palloc'd array of the items in this segment. If * 'seg' is not NULL, it contains the items in an already-compressed * format. It can point to an on-disk page (!modified), or a palloc'd * segment in memory. If both are set, they must represent the same items. @@ -104,20 +104,20 @@ typedef struct static ItemPointer dataLeafPageGetUncompressed(Page page, int *nitems); static void dataSplitPageInternal(GinBtree btree, Buffer origbuf, - GinBtreeStack *stack, - void *insertdata, BlockNumber updateblkno, - Page *newlpage, Page *newrpage); + GinBtreeStack *stack, + void *insertdata, BlockNumber updateblkno, + Page *newlpage, Page *newrpage); static disassembledLeaf *disassembleLeaf(Page page); static bool leafRepackItems(disassembledLeaf *leaf, ItemPointer remaining); static bool addItemsToLeaf(disassembledLeaf *leaf, ItemPointer newItems, - int nNewItems); + int nNewItems); static void computeLeafRecompressWALData(disassembledLeaf *leaf); static void dataPlaceToPageLeafRecompress(Buffer buf, disassembledLeaf *leaf); static void dataPlaceToPageLeafSplit(disassembledLeaf *leaf, - ItemPointerData lbound, ItemPointerData rbound, - Page lpage, Page rpage); + ItemPointerData lbound, ItemPointerData rbound, + Page lpage, Page rpage); /* * Read TIDs from leaf data page to single uncompressed array. The TIDs are @@ -593,7 +593,7 @@ dataBeginPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, * Great, all the items fit on a single page. If needed, prepare data * for a WAL record describing the changes we'll make. */ - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) computeLeafRecompressWALData(leaf); /* @@ -719,7 +719,7 @@ dataExecPlaceToPageLeaf(GinBtree btree, Buffer buf, GinBtreeStack *stack, dataPlaceToPageLeafRecompress(buf, leaf); /* If needed, register WAL data built by computeLeafRecompressWALData */ - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { XLogRegisterBufData(0, leaf->walinfo, leaf->walinfolen); } @@ -1152,7 +1152,7 @@ dataExecPlaceToPageInternal(GinBtree btree, Buffer buf, GinBtreeStack *stack, pitem = (PostingItem *) insertdata; GinDataPageAddPostingItem(page, pitem, off); - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { /* * This must be static, because it has to survive until XLogInsert, @@ -1371,7 +1371,7 @@ disassembleLeaf(Page page) if (GinPageIsCompressed(page)) { /* - * Create a leafSegment entry for each segment. + * Create a leafSegmentInfo entry for each segment. */ seg = GinDataLeafPageGetPostingList(page); segbegin = (Pointer) seg; @@ -1394,7 +1394,8 @@ disassembleLeaf(Page page) { /* * A pre-9.4 format uncompressed page is represented by a single - * segment, with an array of items. + * segment, with an array of items. The corner case is uncompressed + * page containing no items, which is represented as no segments. */ ItemPointer uncompressed; int nuncompressed; @@ -1402,15 +1403,18 @@ disassembleLeaf(Page page) uncompressed = dataLeafPageGetUncompressed(page, &nuncompressed); - seginfo = palloc(sizeof(leafSegmentInfo)); + if (nuncompressed > 0) + { + seginfo = palloc(sizeof(leafSegmentInfo)); - seginfo->action = GIN_SEGMENT_REPLACE; - seginfo->seg = NULL; - seginfo->items = palloc(nuncompressed * sizeof(ItemPointerData)); - memcpy(seginfo->items, uncompressed, nuncompressed * sizeof(ItemPointerData)); - seginfo->nitems = nuncompressed; + seginfo->action = GIN_SEGMENT_REPLACE; + seginfo->seg = NULL; + seginfo->items = palloc(nuncompressed * sizeof(ItemPointerData)); + memcpy(seginfo->items, uncompressed, nuncompressed * sizeof(ItemPointerData)); + seginfo->nitems = nuncompressed; - dlist_push_tail(&leaf->segments, &seginfo->node); + dlist_push_tail(&leaf->segments, &seginfo->node); + } leaf->oldformat = true; } @@ -1769,6 +1773,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, Pointer ptr; int nrootitems; int rootsize; + bool is_build = (buildStats != NULL); /* Construct the new root page in memory first. */ tmppage = (Page) palloc(BLCKSZ); @@ -1812,8 +1817,8 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, blkno = BufferGetBlockNumber(buffer); /* - * Copy a predicate lock from entry tree leaf (containing posting list) - * to posting tree. + * Copy any predicate locks from the entry tree leaf (containing posting + * list) to the posting tree. */ PredicateLockPageSplit(index, BufferGetBlockNumber(entrybuffer), blkno); @@ -1822,7 +1827,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, PageRestoreTempPage(tmppage, page); MarkBufferDirty(buffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !is_build) { XLogRecPtr recptr; ginxlogCreatePostingTree data; @@ -1864,7 +1869,7 @@ createPostingTree(Relation index, ItemPointerData *items, uint32 nitems, return blkno; } -void +static void ginPrepareDataScan(GinBtree btree, Relation index, BlockNumber rootBlkno) { memset(btree, 0, sizeof(GinBtreeData)); @@ -1909,9 +1914,8 @@ ginInsertItemPointers(Relation index, BlockNumber rootBlkno, { /* search for the leaf page where the first item should go to */ btree.itemptr = insertdata.items[insertdata.curitem]; - stack = ginFindLeafPage(&btree, false, NULL); + stack = ginFindLeafPage(&btree, false, true, NULL); - GinCheckForSerializableConflictIn(btree.index, NULL, stack->buffer); ginInsertValue(&btree, stack, &insertdata, buildStats); } } @@ -1929,7 +1933,7 @@ ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, btree->fullScan = true; - stack = ginFindLeafPage(btree, true, snapshot); + stack = ginFindLeafPage(btree, true, false, snapshot); return stack; } diff --git a/src/backend/access/gin/ginentrypage.c b/src/backend/access/gin/ginentrypage.c index 810769718f4..b87ff26f9c4 100644 --- a/src/backend/access/gin/ginentrypage.c +++ b/src/backend/access/gin/ginentrypage.c @@ -4,7 +4,7 @@ * routines for handling GIN entry tree pages. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -21,10 +21,10 @@ #include "utils/rel.h" static void entrySplitPage(GinBtree btree, Buffer origbuf, - GinBtreeStack *stack, - GinBtreeEntryInsertData *insertData, - BlockNumber updateblkno, - Page *newlpage, Page *newrpage); + GinBtreeStack *stack, + GinBtreeEntryInsertData *insertData, + BlockNumber updateblkno, + Page *newlpage, Page *newrpage); /* * Form a tuple for entry tree. @@ -571,7 +571,7 @@ entryExecPlaceToPage(GinBtree btree, Buffer buf, GinBtreeStack *stack, elog(ERROR, "failed to add item to index page in \"%s\"", RelationGetRelationName(btree->index)); - if (RelationNeedsWAL(btree->index)) + if (RelationNeedsWAL(btree->index) && !btree->isBuild) { /* * This must be static, because it has to survive until XLogInsert, @@ -616,7 +616,7 @@ entrySplitPage(GinBtree btree, Buffer origbuf, Page lpage = PageGetTempPageCopy(BufferGetPage(origbuf)); Page rpage = PageGetTempPageCopy(BufferGetPage(origbuf)); Size pageSize = PageGetPageSize(lpage); - char tupstore[2 * BLCKSZ]; + PGAlignedBlock tupstore[2]; /* could need 2 pages' worth of tuples */ entryPreparePage(btree, lpage, off, insertData, updateblkno); @@ -625,7 +625,7 @@ entrySplitPage(GinBtree btree, Buffer origbuf, * one after another in a temporary workspace. */ maxoff = PageGetMaxOffsetNumber(lpage); - ptr = tupstore; + ptr = tupstore[0].data; for (i = FirstOffsetNumber; i <= maxoff; i++) { if (i == off) @@ -658,7 +658,7 @@ entrySplitPage(GinBtree btree, Buffer origbuf, GinInitPage(rpage, GinPageGetOpaque(lpage)->flags, pageSize); GinInitPage(lpage, GinPageGetOpaque(rpage)->flags, pageSize); - ptr = tupstore; + ptr = tupstore[0].data; maxoff++; lsize = 0; diff --git a/src/backend/access/gin/ginfast.c b/src/backend/access/gin/ginfast.c index 615730b8e55..439a91b3e61 100644 --- a/src/backend/access/gin/ginfast.c +++ b/src/backend/access/gin/ginfast.c @@ -7,7 +7,7 @@ * transfer pending entries into the regular index structure. This * wins because bulk insertion is much more efficient than retail. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -31,6 +31,7 @@ #include "postmaster/autovacuum.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" +#include "storage/predicate.h" #include "utils/builtins.h" /* GUC parameter */ @@ -63,18 +64,15 @@ writeListPage(Relation index, Buffer buffer, size = 0; OffsetNumber l, off; - char *workspace; + PGAlignedBlock workspace; char *ptr; - /* workspace could be a local array; we use palloc for alignment */ - workspace = palloc(BLCKSZ); - START_CRIT_SECTION(); GinInitBuffer(buffer, GIN_LIST); off = FirstOffsetNumber; - ptr = workspace; + ptr = workspace.data; for (i = 0; i < ntuples; i++) { @@ -126,7 +124,7 @@ writeListPage(Relation index, Buffer buffer, XLogRegisterData((char *) &data, sizeof(ginxlogInsertListPage)); XLogRegisterBuffer(0, buffer, REGBUF_WILL_INIT); - XLogRegisterBufData(0, workspace, size); + XLogRegisterBufData(0, workspace.data, size); recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_INSERT_LISTPAGE); PageSetLSN(page, recptr); @@ -139,8 +137,6 @@ writeListPage(Relation index, Buffer buffer, END_CRIT_SECTION(); - pfree(workspace); - return freesize; } @@ -245,6 +241,13 @@ ginHeapTupleFastInsert(GinState *ginstate, GinTupleCollector *collector) metabuffer = ReadBuffer(index, GIN_METAPAGE_BLKNO); metapage = BufferGetPage(metabuffer); + /* + * An insertion to the pending list could logically belong anywhere in the + * tree, so it conflicts with all serializable scans. All scans acquire a + * predicate lock on the metabuffer to represent that. + */ + CheckForSerializableConflictIn(index, NULL, metabuffer); + if (collector->sumsize + collector->ntuples * sizeof(ItemIdData) > GinListPageSize) { /* @@ -483,18 +486,41 @@ ginHeapTupleFastCollect(GinState *ginstate, entries = ginExtractEntries(ginstate, attnum, value, isNull, &nentries, &categories); + /* + * Protect against integer overflow in allocation calculations + */ + if (nentries < 0 || + collector->ntuples + nentries > MaxAllocSize / sizeof(IndexTuple)) + elog(ERROR, "too many entries for GIN index"); + /* * Allocate/reallocate memory for storing collected tuples */ if (collector->tuples == NULL) { - collector->lentuples = nentries * ginstate->origTupdesc->natts; + /* + * Determine the number of elements to allocate in the tuples array + * initially. Make it a power of 2 to avoid wasting memory when + * resizing (since palloc likes powers of 2). + */ + collector->lentuples = 16; + while (collector->lentuples < nentries) + collector->lentuples *= 2; + collector->tuples = (IndexTuple *) palloc(sizeof(IndexTuple) * collector->lentuples); } - - while (collector->ntuples + nentries > collector->lentuples) + else if (collector->lentuples < collector->ntuples + nentries) { - collector->lentuples *= 2; + /* + * Advance lentuples to the next suitable power of 2. This won't + * overflow, though we could get to a value that exceeds + * MaxAllocSize/sizeof(IndexTuple), causing an error in repalloc. + */ + do + { + collector->lentuples *= 2; + } while (collector->lentuples < collector->ntuples + nentries); + collector->tuples = (IndexTuple *) repalloc(collector->tuples, sizeof(IndexTuple) * collector->lentuples); } @@ -987,7 +1013,7 @@ ginInsertCleanup(GinState *ginstate, bool full_clean, /* * As pending list pages can have a high churn rate, it is desirable to - * recycle them immediately to the FreeSpace Map when ordinary backends + * recycle them immediately to the FreeSpaceMap when ordinary backends * clean the list. */ if (fsm_vac && fill_fsm) @@ -1005,7 +1031,7 @@ Datum gin_clean_pending_list(PG_FUNCTION_ARGS) { Oid indexoid = PG_GETARG_OID(0); - Relation indexRel = index_open(indexoid, AccessShareLock); + Relation indexRel = index_open(indexoid, RowExclusiveLock); IndexBulkDeleteResult stats; GinState ginstate; @@ -1042,7 +1068,7 @@ gin_clean_pending_list(PG_FUNCTION_ARGS) initGinState(&ginstate, indexRel); ginInsertCleanup(&ginstate, true, true, true, &stats); - index_close(indexRel, AccessShareLock); + index_close(indexRel, RowExclusiveLock); PG_RETURN_INT64((int64) stats.pages_deleted); } diff --git a/src/backend/access/gin/ginget.c b/src/backend/access/gin/ginget.c index 0e984166fa8..b18ae2b3ed2 100644 --- a/src/backend/access/gin/ginget.c +++ b/src/backend/access/gin/ginget.c @@ -4,7 +4,7 @@ * fetch tuples from a GIN scan. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -35,20 +35,6 @@ typedef struct pendingPosition } pendingPosition; -/* - * Place predicate lock on GIN page if needed. - */ -static void -GinPredicateLockPage(Relation index, BlockNumber blkno, Snapshot snapshot) -{ - /* - * When fast update is on then no need in locking pages, because we - * anyway need to lock the whole index. - */ - if (!GinGetUseFastUpdate(index)) - PredicateLockPage(index, blkno, snapshot); -} - /* * Goes to the next page if current offset is outside of bounds */ @@ -68,7 +54,7 @@ moveRightIfItNeeded(GinBtreeData *btree, GinBtreeStack *stack, Snapshot snapshot stack->buffer = ginStepRight(stack->buffer, btree->index, GIN_SHARE); stack->blkno = BufferGetBlockNumber(stack->buffer); stack->off = FirstOffsetNumber; - GinPredicateLockPage(btree->index, stack->blkno, snapshot); + PredicateLockPage(btree->index, stack->blkno, snapshot); } return true; @@ -100,11 +86,6 @@ scanPostingTree(Relation index, GinScanEntry scanEntry, */ for (;;) { - /* - * Predicate lock each leaf page in posting tree - */ - GinPredicateLockPage(index, BufferGetBlockNumber(buffer), snapshot); - page = BufferGetPage(buffer); if ((GinPageGetOpaque(page)->flags & GIN_DELETED) == 0) { @@ -158,7 +139,7 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack, * Predicate lock entry leaf page, following pages will be locked by * moveRightIfItNeeded() */ - GinPredicateLockPage(btree->index, stack->buffer, snapshot); + PredicateLockPage(btree->index, stack->buffer, snapshot); for (;;) { @@ -253,6 +234,13 @@ collectMatchBitmap(GinBtreeData *btree, GinBtreeStack *stack, LockBuffer(stack->buffer, GIN_UNLOCK); + /* + * Acquire predicate lock on the posting tree. We already hold a + * lock on the entry page, but insertions to the posting tree + * don't check for conflicts on that level. + */ + PredicateLockPage(btree->index, rootPostingTree, snapshot); + /* Collect all the TIDs in this entry's posting tree */ scanPostingTree(btree->index, scanEntry, rootPostingTree, snapshot); @@ -350,7 +338,7 @@ startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot) ginPrepareEntryScan(&btreeEntry, entry->attnum, entry->queryKey, entry->queryCategory, ginstate); - stackEntry = ginFindLeafPage(&btreeEntry, true, snapshot); + stackEntry = ginFindLeafPage(&btreeEntry, true, false, snapshot); page = BufferGetPage(stackEntry->buffer); /* ginFindLeafPage() will have already checked snapshot age. */ @@ -400,10 +388,6 @@ startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot) { IndexTuple itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, stackEntry->off)); - /* Predicate lock visited entry leaf page */ - GinPredicateLockPage(ginstate->index, - BufferGetBlockNumber(stackEntry->buffer), snapshot); - if (GinIsPostingTree(itup)) { BlockNumber rootPostingTree = GinGetPostingTree(itup); @@ -411,6 +395,13 @@ startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot) Page page; ItemPointerData minItem; + /* + * This is an equality scan, so lock the root of the posting tree. + * It represents a lock on the exact key value, and covers all the + * items in the posting tree. + */ + PredicateLockPage(ginstate->index, rootPostingTree, snapshot); + /* * We should unlock entry page before touching posting tree to * prevent deadlocks with vacuum processes. Because entry is never @@ -425,12 +416,6 @@ startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot) rootPostingTree, snapshot); entry->buffer = stack->buffer; - /* - * Predicate lock visited posting tree page, following pages - * will be locked by moveRightIfItNeeded or entryLoadMoreItems - */ - GinPredicateLockPage(ginstate->index, BufferGetBlockNumber(entry->buffer), snapshot); - /* * We keep buffer pinned because we need to prevent deletion of * page during scan. See GIN's vacuum implementation. RefCount is @@ -452,15 +437,38 @@ startScanEntry(GinState *ginstate, GinScanEntry entry, Snapshot snapshot) freeGinBtreeStack(stack); entry->isFinished = false; } - else if (GinGetNPosting(itup) > 0) + else { - entry->list = ginReadTuple(ginstate, entry->attnum, itup, - &entry->nlist); - entry->predictNumberResult = entry->nlist; + /* + * Lock the entry leaf page. This is more coarse-grained than + * necessary, because it will conflict with any insertions that + * land on the same leaf page, not only the exact key we searched + * for. But locking an individual tuple would require updating + * that lock whenever it moves because of insertions or vacuums, + * which seems too complicated. + */ + PredicateLockPage(ginstate->index, + BufferGetBlockNumber(stackEntry->buffer), + snapshot); + if (GinGetNPosting(itup) > 0) + { + entry->list = ginReadTuple(ginstate, entry->attnum, itup, + &entry->nlist); + entry->predictNumberResult = entry->nlist; - entry->isFinished = false; + entry->isFinished = false; + } } } + else + { + /* + * No entry found. Predicate lock the leaf page, to lock the place + * where the entry would've been, had there been one. + */ + PredicateLockPage(ginstate->index, + BufferGetBlockNumber(stackEntry->buffer), snapshot); + } if (needUnlock) LockBuffer(stackEntry->buffer, GIN_UNLOCK); @@ -533,7 +541,7 @@ startScanKey(GinState *ginstate, GinScanOpaque so, GinScanKey key) for (i = 0; i < key->nentries - 1; i++) { - /* Pass all entries <= i as false, and the rest as MAYBE */ + /* Pass all entries <= i as FALSE, and the rest as MAYBE */ for (j = 0; j <= i; j++) key->entryRes[entryIndexes[j]] = GIN_FALSE; for (j = i + 1; j < key->nentries; j++) @@ -671,9 +679,7 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, OffsetNumberNext(GinItemPointerGetOffsetNumber(&advancePast))); } entry->btree.fullScan = false; - stack = ginFindLeafPage(&entry->btree, true, snapshot); - - GinPredicateLockPage(ginstate->index, BufferGetBlockNumber(stack->buffer), snapshot); + stack = ginFindLeafPage(&entry->btree, true, false, snapshot); /* we don't need the stack, just the buffer. */ entry->buffer = stack->buffer; @@ -719,10 +725,6 @@ entryLoadMoreItems(GinState *ginstate, GinScanEntry entry, entry->buffer = ginStepRight(entry->buffer, ginstate->index, GIN_SHARE); - - GinPredicateLockPage(ginstate->index, BufferGetBlockNumber(entry->buffer), snapshot); - - page = BufferGetPage(entry->buffer); } stepright = true; @@ -1084,8 +1086,8 @@ keyGetItem(GinState *ginstate, MemoryContext tempCtx, GinScanKey key, * lossy page even when none of the other entries match. * * Our strategy is to call the tri-state consistent function, with the - * lossy-page entries set to MAYBE, and all the other entries false. If it - * returns false, none of the lossy items alone are enough for a match, so + * lossy-page entries set to MAYBE, and all the other entries FALSE. If it + * returns FALSE, none of the lossy items alone are enough for a match, so * we don't need to return a lossy-page pointer. Otherwise, return a * lossy-page pointer to indicate that the whole heap page must be * checked. (On subsequent calls, we'll do nothing until minItem is past @@ -1746,8 +1748,7 @@ collectMatchesForHeapRow(IndexScanDesc scan, pendingPosition *pos) } /* - * Collect all matched rows from pending list into bitmap. Also function - * takes PendingLockRelation if it's needed. + * Collect all matched rows from pending list into bitmap. */ static void scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) @@ -1764,6 +1765,12 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) *ntids = 0; + /* + * Acquire predicate lock on the metapage, to conflict with any fastupdate + * insertions. + */ + PredicateLockPage(scan->indexRelation, GIN_METAPAGE_BLKNO, scan->xs_snapshot); + LockBuffer(metabuffer, GIN_SHARE); page = BufferGetPage(metabuffer); TestForOldSnapshot(scan->xs_snapshot, scan->indexRelation, page); @@ -1777,24 +1784,9 @@ scanPendingInsert(IndexScanDesc scan, TIDBitmap *tbm, int64 *ntids) { /* No pending list, so proceed with normal scan */ UnlockReleaseBuffer(metabuffer); - - /* - * If fast update is enabled, we acquire a predicate lock on the entire - * relation as fast update postpones the insertion of tuples into index - * structure due to which we can't detect rw conflicts. - */ - if (GinGetUseFastUpdate(scan->indexRelation)) - PredicateLockRelation(scan->indexRelation, scan->xs_snapshot); - return; } - /* - * Pending list is not empty, we need to lock the index doesn't despite on - * fastupdate state - */ - PredicateLockRelation(scan->indexRelation, scan->xs_snapshot); - pos.pendingBuffer = ReadBuffer(scan->indexRelation, blkno); LockBuffer(pos.pendingBuffer, GIN_SHARE); pos.firstOffset = FirstOffsetNumber; diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index ec5eebb8484..55eab146173 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -4,7 +4,7 @@ * insert routines for the postgres inverted index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,6 +17,7 @@ #include "access/gin_private.h" #include "access/ginxlog.h" #include "access/xloginsert.h" +#include "access/tableam.h" #include "catalog/index.h" #include "miscadmin.h" #include "storage/bufmgr.h" @@ -194,8 +195,9 @@ ginEntryInsert(GinState *ginstate, buildStats->nEntries++; ginPrepareEntryScan(&btree, attnum, key, category, ginstate); + btree.isBuild = (buildStats != NULL); - stack = ginFindLeafPage(&btree, false, NULL); + stack = ginFindLeafPage(&btree, false, false, NULL); page = BufferGetPage(stack->buffer); if (btree.findItem(&btree, stack)) @@ -219,7 +221,7 @@ ginEntryInsert(GinState *ginstate, return; } - GinCheckForSerializableConflictIn(btree.index, NULL, stack->buffer); + CheckForSerializableConflictIn(ginstate->index, NULL, stack->buffer); /* modify an existing leaf entry */ itup = addItemPointersToLeafTuple(ginstate, itup, items, nitem, buildStats, stack->buffer); @@ -228,7 +230,7 @@ ginEntryInsert(GinState *ginstate, } else { - GinCheckForSerializableConflictIn(btree.index, NULL, stack->buffer); + CheckForSerializableConflictIn(ginstate->index, NULL, stack->buffer); /* no match, so construct a new leaf entry */ itup = buildFreshLeafTuple(ginstate, attnum, key, category, items, nitem, buildStats, stack->buffer); @@ -346,23 +348,6 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) GinInitBuffer(RootBuffer, GIN_LEAF); MarkBufferDirty(RootBuffer); - if (RelationNeedsWAL(index)) - { - XLogRecPtr recptr; - Page page; - - XLogBeginInsert(); - XLogRegisterBuffer(0, MetaBuffer, REGBUF_WILL_INIT | REGBUF_STANDARD); - XLogRegisterBuffer(1, RootBuffer, REGBUF_WILL_INIT); - - recptr = XLogInsert(RM_GIN_ID, XLOG_GIN_CREATE_INDEX); - - page = BufferGetPage(RootBuffer); - PageSetLSN(page, recptr); - - page = BufferGetPage(MetaBuffer); - PageSetLSN(page, recptr); - } UnlockReleaseBuffer(MetaBuffer); UnlockReleaseBuffer(RootBuffer); @@ -394,8 +379,9 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) * Do the heap scan. We disallow sync scan here because dataPlaceToPage * prefers to receive tuples in TID order. */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, false, - ginBuildCallback, (void *) &buildstate, NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, false, true, + ginBuildCallback, (void *) &buildstate, + NULL); /* dump remaining entries to the index */ oldCtx = MemoryContextSwitchTo(buildstate.tmpCtx); @@ -417,7 +403,18 @@ ginbuild(Relation heap, Relation index, IndexInfo *indexInfo) * Update metapage stats */ buildstate.buildStats.nTotalPages = RelationGetNumberOfBlocks(index); - ginUpdateStats(index, &buildstate.buildStats); + ginUpdateStats(index, &buildstate.buildStats, true); + + /* + * We didn't write WAL records as we built the index, so if WAL-logging is + * required, write all pages to the WAL now. + */ + if (RelationNeedsWAL(index)) + { + log_newpage_range(index, MAIN_FORKNUM, + 0, RelationGetNumberOfBlocks(index), + true); + } /* * Return statistics @@ -517,18 +514,6 @@ gininsert(Relation index, Datum *values, bool *isnull, memset(&collector, 0, sizeof(GinTupleCollector)); - /* - * With fastupdate on each scan and each insert begin with access to - * pending list, so it effectively lock entire index. In this case - * we aquire predicate lock and check for conflicts over index relation, - * and hope that it will reduce locking overhead. - * - * Do not use GinCheckForSerializableConflictIn() here, because - * it will do nothing (it does actual work only with fastupdate off). - * Check for conflicts for entire index. - */ - CheckForSerializableConflictIn(index, NULL, InvalidBuffer); - for (i = 0; i < ginstate->origTupdesc->natts; i++) ginHeapTupleFastCollect(ginstate, &collector, (OffsetNumber) (i + 1), @@ -539,16 +524,6 @@ gininsert(Relation index, Datum *values, bool *isnull, } else { - GinStatsData stats; - - /* - * Fastupdate is off but if pending list isn't empty then we need to - * check conflicts with PredicateLockRelation in scanPendingInsert(). - */ - ginGetStats(index, &stats); - if (stats.nPendingPages > 0) - CheckForSerializableConflictIn(index, NULL, InvalidBuffer); - for (i = 0; i < ginstate->origTupdesc->natts; i++) ginHeapTupleInsert(ginstate, (OffsetNumber) (i + 1), values[i], isnull[i], diff --git a/src/backend/access/gin/ginlogic.c b/src/backend/access/gin/ginlogic.c index 2c42d1aa916..8f859789728 100644 --- a/src/backend/access/gin/ginlogic.c +++ b/src/backend/access/gin/ginlogic.c @@ -24,7 +24,7 @@ * is used for.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginpostinglist.c b/src/backend/access/gin/ginpostinglist.c index 54c9caffe3f..44aef77edb7 100644 --- a/src/backend/access/gin/ginpostinglist.c +++ b/src/backend/access/gin/ginpostinglist.c @@ -4,7 +4,7 @@ * routines for dealing with posting lists. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -23,25 +23,32 @@ /* * For encoding purposes, item pointers are represented as 64-bit unsigned * integers. The lowest 11 bits represent the offset number, and the next - * lowest 32 bits are the block number. That leaves 17 bits unused, i.e. + * lowest 32 bits are the block number. That leaves 21 bits unused, i.e. * only 43 low bits are used. * + * 11 bits is enough for the offset number, because MaxHeapTuplesPerPage < + * 2^11 on all supported block sizes. We are frugal with the bits, because + * smaller integers use fewer bytes in the varbyte encoding, saving disk + * space. (If we get a new table AM in the future that wants to use the full + * range of possible offset numbers, we'll need to change this.) + * * These 43-bit integers are encoded using varbyte encoding. In each byte, * the 7 low bits contain data, while the highest bit is a continuation bit. * When the continuation bit is set, the next byte is part of the same - * integer, otherwise this is the last byte of this integer. 43 bits fit - * conveniently in at most 6 bytes when varbyte encoded (the 6th byte does - * not need a continuation bit, because we know the max size to be 43 bits): + * integer, otherwise this is the last byte of this integer. 43 bits need + * at most 7 bytes in this encoding: * * 0XXXXXXX * 1XXXXXXX 0XXXXYYY * 1XXXXXXX 1XXXXYYY 0YYYYYYY * 1XXXXXXX 1XXXXYYY 1YYYYYYY 0YYYYYYY * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 0YYYYYYY - * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY YYYYYYYY + * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 0YYYYYYY + * 1XXXXXXX 1XXXXYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 1YYYYYYY 0uuuuuuY * * X = bits used for offset number * Y = bits used for block number + * u = unused bit * * The bytes are in stored in little-endian order. * @@ -73,6 +80,9 @@ */ #define MaxHeapTuplesPerPageBits 11 +/* Max. number of bytes needed to encode the largest supported integer. */ +#define MaxBytesPerInteger 7 + static inline uint64 itemptr_to_uint64(const ItemPointer iptr) { @@ -126,33 +136,40 @@ decode_varbyte(unsigned char **ptr) unsigned char *p = *ptr; uint64 c; + /* 1st byte */ c = *(p++); val = c & 0x7F; if (c & 0x80) { + /* 2nd byte */ c = *(p++); val |= (c & 0x7F) << 7; if (c & 0x80) { + /* 3rd byte */ c = *(p++); val |= (c & 0x7F) << 14; if (c & 0x80) { + /* 4th byte */ c = *(p++); val |= (c & 0x7F) << 21; if (c & 0x80) { + /* 5th byte */ c = *(p++); val |= (c & 0x7F) << 28; if (c & 0x80) { + /* 6th byte */ c = *(p++); val |= (c & 0x7F) << 35; if (c & 0x80) { - /* last byte, no continuation bit */ + /* 7th byte, should not have continuation bit */ c = *(p++); val |= c << 42; + Assert((c & 0x80) == 0); } } } @@ -208,15 +225,15 @@ ginCompressPostingList(const ItemPointer ipd, int nipd, int maxsize, Assert(val > prev); - if (endptr - ptr >= 6) + if (endptr - ptr >= MaxBytesPerInteger) encode_varbyte(delta, &ptr); else { /* - * There are less than 6 bytes left. Have to check if the next + * There are less than 7 bytes left. Have to check if the next * item fits in that space before writing it out. */ - unsigned char buf[6]; + unsigned char buf[MaxBytesPerInteger]; unsigned char *p = buf; encode_varbyte(delta, &p); diff --git a/src/backend/access/gin/ginscan.c b/src/backend/access/gin/ginscan.c index 8ade4311df4..74d9821ac1a 100644 --- a/src/backend/access/gin/ginscan.c +++ b/src/backend/access/gin/ginscan.c @@ -4,7 +4,7 @@ * routines to manage scans of inverted index relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c index 4367523dd98..cf9699ad18e 100644 --- a/src/backend/access/gin/ginutil.c +++ b/src/backend/access/gin/ginutil.c @@ -4,7 +4,7 @@ * Utility routines for the Postgres inverted index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -64,6 +64,7 @@ ginhandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = gincostestimate; amroutine->amoptions = ginoptions; amroutine->amproperty = NULL; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = ginvalidate; amroutine->ambeginscan = ginbeginscan; amroutine->amrescan = ginrescan; @@ -104,7 +105,7 @@ initGinState(GinState *state, Relation index) state->tupdesc[i] = state->origTupdesc; else { - state->tupdesc[i] = CreateTemplateTupleDesc(2, false); + state->tupdesc[i] = CreateTemplateTupleDesc(2); TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 1, NULL, INT2OID, -1, 0); @@ -309,12 +310,7 @@ GinNewBuffer(Relation index) */ if (ConditionalLockBuffer(buffer)) { - Page page = BufferGetPage(buffer); - - if (PageIsNew(page)) - return buffer; /* OK to use, if never initialized */ - - if (GinPageIsDeleted(page)) + if (GinPageIsRecyclable(BufferGetPage(buffer))) return buffer; /* OK to use */ LockBuffer(buffer, GIN_UNLOCK); @@ -666,7 +662,7 @@ ginGetStats(Relation index, GinStatsData *stats) * Note: nPendingPages and ginVersion are *not* copied over */ void -ginUpdateStats(Relation index, const GinStatsData *stats) +ginUpdateStats(Relation index, const GinStatsData *stats, bool is_build) { Buffer metabuffer; Page metapage; @@ -696,7 +692,7 @@ ginUpdateStats(Relation index, const GinStatsData *stats) MarkBufferDirty(metabuffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !is_build) { XLogRecPtr recptr; ginxlogUpdateMeta data; @@ -718,10 +714,3 @@ ginUpdateStats(Relation index, const GinStatsData *stats) END_CRIT_SECTION(); } - -void -GinCheckForSerializableConflictIn(Relation relation, HeapTuple tuple, Buffer buffer) -{ - if (!GinGetUseFastUpdate(relation)) - CheckForSerializableConflictIn(relation, tuple, buffer); -} diff --git a/src/backend/access/gin/ginvacuum.c b/src/backend/access/gin/ginvacuum.c index dd8e31b8721..dc46f2460e2 100644 --- a/src/backend/access/gin/ginvacuum.c +++ b/src/backend/access/gin/ginvacuum.c @@ -4,7 +4,7 @@ * delete & vacuum routines for the postgres GIN * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -157,6 +157,9 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn page = BufferGetPage(dBuffer); rightlink = GinPageGetOpaque(page)->rightlink; + /* For deleted page remember last xid which could knew its address */ + GinPageSetDeleteXid(page, ReadNewTransactionId()); + /* * Any insert which would have gone on the leaf block will now go to its * right sibling. @@ -166,7 +169,6 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn START_CRIT_SECTION(); /* Unlink the page by changing left sibling's rightlink */ - page = BufferGetPage(lBuffer); GinPageGetOpaque(page)->rightlink = rightlink; @@ -214,6 +216,7 @@ ginDeletePage(GinVacuumState *gvs, BlockNumber deleteBlkno, BlockNumber leftBlkn data.parentOffset = myoff; data.rightLink = GinPageGetOpaque(page)->rightlink; + data.deleteXid = GinPageGetDeleteXid(page); XLogRegisterData((char *) &data, sizeof(ginxlogDeletePage)); @@ -316,124 +319,114 @@ ginScanToDelete(GinVacuumState *gvs, BlockNumber blkno, bool isRoot, /* - * Scan through posting tree, delete empty tuples from leaf pages. - * Also, this function collects empty subtrees (with all empty leafs). - * For parents of these subtrees CleanUp lock is taken, then we call - * ScanToDelete. This is done for every inner page, which points to - * empty subtree. + * Scan through posting tree leafs, delete empty tuples. Returns true if there + * is at least one empty page. */ static bool -ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno, bool isRoot) +ginVacuumPostingTreeLeaves(GinVacuumState *gvs, BlockNumber blkno) { Buffer buffer; Page page; bool hasVoidPage = false; MemoryContext oldCxt; - buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, - RBM_NORMAL, gvs->strategy); - page = BufferGetPage(buffer); + /* Find leftmost leaf page of posting tree and lock it in exclusive mode */ + while (true) + { + PostingItem *pitem; - ginTraverseLock(buffer, false); + buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, + RBM_NORMAL, gvs->strategy); + LockBuffer(buffer, GIN_SHARE); + page = BufferGetPage(buffer); - Assert(GinPageIsData(page)); + Assert(GinPageIsData(page)); - if (GinPageIsLeaf(page)) + if (GinPageIsLeaf(page)) + { + LockBuffer(buffer, GIN_UNLOCK); + LockBuffer(buffer, GIN_EXCLUSIVE); + break; + } + + Assert(PageGetMaxOffsetNumber(page) >= FirstOffsetNumber); + + pitem = GinDataPageGetPostingItem(page, FirstOffsetNumber); + blkno = PostingItemGetBlockNumber(pitem); + Assert(blkno != InvalidBlockNumber); + + UnlockReleaseBuffer(buffer); + } + + /* Iterate all posting tree leaves using rightlinks and vacuum them */ + while (true) { oldCxt = MemoryContextSwitchTo(gvs->tmpCxt); ginVacuumPostingTreeLeaf(gvs->index, buffer, gvs); MemoryContextSwitchTo(oldCxt); MemoryContextReset(gvs->tmpCxt); - /* if root is a leaf page, we don't desire further processing */ if (GinDataLeafPageIsEmpty(page)) hasVoidPage = true; - UnlockReleaseBuffer(buffer); - - return hasVoidPage; - } - else - { - OffsetNumber i; - bool hasEmptyChild = false; - bool hasNonEmptyChild = false; - OffsetNumber maxoff = GinPageGetOpaque(page)->maxoff; - BlockNumber *children = palloc(sizeof(BlockNumber) * (maxoff + 1)); - - /* - * Read all children BlockNumbers. Not sure it is safe if there are - * many concurrent vacuums. - */ - - for (i = FirstOffsetNumber; i <= maxoff; i++) - { - PostingItem *pitem = GinDataPageGetPostingItem(page, i); - - children[i] = PostingItemGetBlockNumber(pitem); - } + blkno = GinPageGetOpaque(page)->rightlink; UnlockReleaseBuffer(buffer); - for (i = FirstOffsetNumber; i <= maxoff; i++) - { - if (ginVacuumPostingTreeLeaves(gvs, children[i], false)) - hasEmptyChild = true; - else - hasNonEmptyChild = true; - } + if (blkno == InvalidBlockNumber) + break; - pfree(children); + buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, + RBM_NORMAL, gvs->strategy); + LockBuffer(buffer, GIN_EXCLUSIVE); + page = BufferGetPage(buffer); + } - vacuum_delay_point(); + return hasVoidPage; +} +static void +ginVacuumPostingTree(GinVacuumState *gvs, BlockNumber rootBlkno) +{ + if (ginVacuumPostingTreeLeaves(gvs, rootBlkno)) + { /* - * All subtree is empty - just return true to indicate that parent - * must do a cleanup, unless we are ROOT and there is way to go upper. + * There is at least one empty page. So we have to rescan the tree + * deleting empty pages. */ + Buffer buffer; + DataPageDeleteStack root, + *ptr, + *tmp; - if (hasEmptyChild && !hasNonEmptyChild && !isRoot) - return true; - - if (hasEmptyChild) - { - DataPageDeleteStack root, - *ptr, - *tmp; - - buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, blkno, - RBM_NORMAL, gvs->strategy); - LockBufferForCleanup(buffer); + buffer = ReadBufferExtended(gvs->index, MAIN_FORKNUM, rootBlkno, + RBM_NORMAL, gvs->strategy); - memset(&root, 0, sizeof(DataPageDeleteStack)); - root.leftBlkno = InvalidBlockNumber; - root.isRoot = true; + /* + * Lock posting tree root for cleanup to ensure there are no + * concurrent inserts. + */ + LockBufferForCleanup(buffer); - ginScanToDelete(gvs, blkno, true, &root, InvalidOffsetNumber); + memset(&root, 0, sizeof(DataPageDeleteStack)); + root.leftBlkno = InvalidBlockNumber; + root.isRoot = true; - ptr = root.child; + ginScanToDelete(gvs, rootBlkno, true, &root, InvalidOffsetNumber); - while (ptr) - { - tmp = ptr->child; - pfree(ptr); - ptr = tmp; - } + ptr = root.child; - UnlockReleaseBuffer(buffer); + while (ptr) + { + tmp = ptr->child; + pfree(ptr); + ptr = tmp; } - /* Here we have deleted all empty subtrees */ - return false; + UnlockReleaseBuffer(buffer); } } -static void -ginVacuumPostingTree(GinVacuumState *gvs, BlockNumber rootBlkno) -{ - ginVacuumPostingTreeLeaves(gvs, rootBlkno, true); -} - /* * returns modified page or NULL if page isn't modified. * Function works with original page until first change is occurred, @@ -743,7 +736,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) LockBuffer(buffer, GIN_SHARE); page = (Page) BufferGetPage(buffer); - if (PageIsNew(page) || GinPageIsDeleted(page)) + if (GinPageIsRecyclable(page)) { Assert(blkno != GIN_ROOT_BLKNO); RecordFreeIndexPage(index, blkno); @@ -766,7 +759,7 @@ ginvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) /* Update the metapage with accurate page and entry counts */ idxStat.nTotalPages = npages; - ginUpdateStats(info->index, &idxStat); + ginUpdateStats(info->index, &idxStat, false); /* Finally, vacuum the FSM */ IndexFreeSpaceMapVacuum(info->index); diff --git a/src/backend/access/gin/ginvalidate.c b/src/backend/access/gin/ginvalidate.c index 1035be44634..63bd7f2adce 100644 --- a/src/backend/access/gin/ginvalidate.c +++ b/src/backend/access/gin/ginvalidate.c @@ -3,7 +3,7 @@ * ginvalidate.c * Opclass validator for GIN. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -90,7 +90,7 @@ ginvalidate(Oid opclassoid) { ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types", + errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types", opfamilyname, "gin", format_procedure(procform->amproc)))); result = false; diff --git a/src/backend/access/gin/ginxlog.c b/src/backend/access/gin/ginxlog.c index a6e321d77e4..c945b282721 100644 --- a/src/backend/access/gin/ginxlog.c +++ b/src/backend/access/gin/ginxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for inverted index. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -40,36 +40,6 @@ ginRedoClearIncompleteSplit(XLogReaderState *record, uint8 block_id) UnlockReleaseBuffer(buffer); } -static void -ginRedoCreateIndex(XLogReaderState *record) -{ - XLogRecPtr lsn = record->EndRecPtr; - Buffer RootBuffer, - MetaBuffer; - Page page; - - MetaBuffer = XLogInitBufferForRedo(record, 0); - Assert(BufferGetBlockNumber(MetaBuffer) == GIN_METAPAGE_BLKNO); - page = (Page) BufferGetPage(MetaBuffer); - - GinInitMetabuffer(MetaBuffer); - - PageSetLSN(page, lsn); - MarkBufferDirty(MetaBuffer); - - RootBuffer = XLogInitBufferForRedo(record, 1); - Assert(BufferGetBlockNumber(RootBuffer) == GIN_ROOT_BLKNO); - page = (Page) BufferGetPage(RootBuffer); - - GinInitBuffer(RootBuffer, GIN_LEAF); - - PageSetLSN(page, lsn); - MarkBufferDirty(RootBuffer); - - UnlockReleaseBuffer(RootBuffer); - UnlockReleaseBuffer(MetaBuffer); -} - static void ginRedoCreatePTree(XLogReaderState *record) { @@ -135,6 +105,14 @@ ginRedoInsertEntry(Buffer buffer, bool isLeaf, BlockNumber rightblkno, void *rda } } +/* + * Redo recompression of posting list. Doing all the changes in-place is not + * always possible, because it might require more space than we've on the page. + * Instead, once modification is required we copy unprocessed tail of the page + * into separately allocated chunk of memory for further reading original + * versions of segments. Thanks to that we don't bother about moving page data + * in-place. + */ static void ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) { @@ -144,6 +122,9 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) Pointer segmentend; char *walbuf; int totalsize; + Pointer tailCopy = NULL; + Pointer writePtr; + Pointer segptr; /* * If the page is in pre-9.4 format, convert to new format first. @@ -153,21 +134,37 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) ItemPointer uncompressed = (ItemPointer) GinDataPageGetData(page); int nuncompressed = GinPageGetOpaque(page)->maxoff; int npacked; - GinPostingList *plist; - plist = ginCompressPostingList(uncompressed, nuncompressed, - BLCKSZ, &npacked); - Assert(npacked == nuncompressed); + /* + * Empty leaf pages are deleted as part of vacuum, but leftmost and + * rightmost pages are never deleted. So, pg_upgrade'd from pre-9.4 + * instances might contain empty leaf pages, and we need to handle + * them correctly. + */ + if (nuncompressed > 0) + { + GinPostingList *plist; + + plist = ginCompressPostingList(uncompressed, nuncompressed, + BLCKSZ, &npacked); + totalsize = SizeOfGinPostingList(plist); + + Assert(npacked == nuncompressed); - totalsize = SizeOfGinPostingList(plist); + memcpy(GinDataLeafPageGetPostingList(page), plist, totalsize); + } + else + { + totalsize = 0; + } - memcpy(GinDataLeafPageGetPostingList(page), plist, totalsize); GinDataPageSetDataSize(page, totalsize); GinPageSetCompressed(page); GinPageGetOpaque(page)->maxoff = InvalidOffsetNumber; } oldseg = GinDataLeafPageGetPostingList(page); + writePtr = (Pointer) oldseg; segmentend = (Pointer) oldseg + GinDataLeafPageGetPostingListSize(page); segno = 0; @@ -185,8 +182,6 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) ItemPointerData *newitems; int nnewitems; int segsize; - Pointer segptr; - int szleft; /* Extract all the information we need from the WAL record */ if (a_action == GIN_SEGMENT_INSERT || @@ -209,6 +204,17 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) Assert(segno <= a_segno); while (segno < a_segno) { + /* + * Once modification is started and page tail is copied, we've to + * copy unmodified segments. + */ + segsize = SizeOfGinPostingList(oldseg); + if (tailCopy) + { + Assert(writePtr + segsize < PageGetSpecialPointer(page)); + memcpy(writePtr, (Pointer) oldseg, segsize); + } + writePtr += segsize; oldseg = GinNextPostingListSegment(oldseg); segno++; } @@ -249,36 +255,42 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) Assert(a_action == GIN_SEGMENT_INSERT); segsize = 0; } - szleft = segmentend - segptr; + + /* + * We're about to start modification of the page. So, copy tail of + * the page if it's not done already. + */ + if (!tailCopy && segptr != segmentend) + { + int tailSize = segmentend - segptr; + + tailCopy = (Pointer) palloc(tailSize); + memcpy(tailCopy, segptr, tailSize); + segptr = tailCopy; + oldseg = (GinPostingList *) segptr; + segmentend = segptr + tailSize; + } switch (a_action) { case GIN_SEGMENT_DELETE: - memmove(segptr, segptr + segsize, szleft - segsize); - segmentend -= segsize; - + segptr += segsize; segno++; break; case GIN_SEGMENT_INSERT: - /* make room for the new segment */ - memmove(segptr + newsegsize, segptr, szleft); /* copy the new segment in place */ - memcpy(segptr, newseg, newsegsize); - segmentend += newsegsize; - segptr += newsegsize; + Assert(writePtr + newsegsize <= PageGetSpecialPointer(page)); + memcpy(writePtr, newseg, newsegsize); + writePtr += newsegsize; break; case GIN_SEGMENT_REPLACE: - /* shift the segments that follow */ - memmove(segptr + newsegsize, - segptr + segsize, - szleft - segsize); - /* copy the replacement segment in place */ - memcpy(segptr, newseg, newsegsize); - segmentend -= segsize; - segmentend += newsegsize; - segptr += newsegsize; + /* copy the new version of segment in place */ + Assert(writePtr + newsegsize <= PageGetSpecialPointer(page)); + memcpy(writePtr, newseg, newsegsize); + writePtr += newsegsize; + segptr += segsize; segno++; break; @@ -288,7 +300,18 @@ ginRedoRecompress(Page page, ginxlogRecompressDataLeaf *data) oldseg = (GinPostingList *) segptr; } - totalsize = segmentend - (Pointer) GinDataLeafPageGetPostingList(page); + /* Copy the rest of unmodified segments if any. */ + segptr = (Pointer) oldseg; + if (segptr != segmentend && tailCopy) + { + int restSize = segmentend - segptr; + + Assert(writePtr + restSize <= PageGetSpecialPointer(page)); + memcpy(writePtr, segptr, restSize); + writePtr += restSize; + } + + totalsize = writePtr - (Pointer) GinDataLeafPageGetPostingList(page); GinDataPageSetDataSize(page, totalsize); } @@ -460,11 +483,25 @@ ginRedoDeletePage(XLogReaderState *record) Buffer lbuffer; Page page; + /* + * Lock left page first in order to prevent possible deadlock with + * ginStepRight(). + */ + if (XLogReadBufferForRedo(record, 2, &lbuffer) == BLK_NEEDS_REDO) + { + page = BufferGetPage(lbuffer); + Assert(GinPageIsData(page)); + GinPageGetOpaque(page)->rightlink = data->rightLink; + PageSetLSN(page, lsn); + MarkBufferDirty(lbuffer); + } + if (XLogReadBufferForRedo(record, 0, &dbuffer) == BLK_NEEDS_REDO) { page = BufferGetPage(dbuffer); Assert(GinPageIsData(page)); GinPageGetOpaque(page)->flags = GIN_DELETED; + GinPageSetDeleteXid(page, data->deleteXid); PageSetLSN(page, lsn); MarkBufferDirty(dbuffer); } @@ -479,15 +516,6 @@ ginRedoDeletePage(XLogReaderState *record) MarkBufferDirty(pbuffer); } - if (XLogReadBufferForRedo(record, 2, &lbuffer) == BLK_NEEDS_REDO) - { - page = BufferGetPage(lbuffer); - Assert(GinPageIsData(page)); - GinPageGetOpaque(page)->rightlink = data->rightLink; - PageSetLSN(page, lsn); - MarkBufferDirty(lbuffer); - } - if (BufferIsValid(lbuffer)) UnlockReleaseBuffer(lbuffer); if (BufferIsValid(pbuffer)) @@ -709,9 +737,6 @@ gin_redo(XLogReaderState *record) oldCtx = MemoryContextSwitchTo(opCtx); switch (info) { - case XLOG_GIN_CREATE_INDEX: - ginRedoCreateIndex(record); - break; case XLOG_GIN_CREATE_PTREE: ginRedoCreatePTree(record); break; diff --git a/src/backend/access/gist/README b/src/backend/access/gist/README index 02228662b81..8cbca692967 100644 --- a/src/backend/access/gist/README +++ b/src/backend/access/gist/README @@ -170,7 +170,7 @@ it splits the page, and constructs the new downlink tuples for the split pages. The caller must then call gistplacetopage() on the parent page to insert the downlink tuples. The parent page that holds the downlink to the child might have migrated as a result of concurrent splits of the -parent, gistfindCorrectParent() is used to find the parent page. +parent, gistFindCorrectParent() is used to find the parent page. Splitting the root page works slightly differently. At root split, gistplacetopage() allocates the new child pages and replaces the old root @@ -413,6 +413,54 @@ emptied yet; tuples never move upwards in the tree. The final emptying loops through buffers at a given level until all buffers at that level have been emptied, and then moves down to the next level. +Bulk delete algorithm (VACUUM) +------------------------------ + +VACUUM works in two stages: + +In the first stage, we scan the whole index in physical order. To make sure +that we don't miss any dead tuples because a concurrent page split moved them, +we check the F_FOLLOW_RIGHT flags and NSN on each page, to detect if the +page has been concurrently split. If a concurrent page split is detected, and +one half of the page was moved to a position that we already scanned, we +"jump backwards" to scan the page again. This is the same mechanism that +B-tree VACUUM uses, but because we already have NSNs on pages, to detect page +splits during searches, we don't need a "vacuum cycle ID" concept for that +like B-tree does. + +While we scan all the pages, we also make note of any completely empty leaf +pages. We will try to unlink them from the tree in the second stage. We also +record the block numbers of all internal pages; they are needed in the second +stage, to locate parents of the empty pages. + +In the second stage, we try to unlink any empty leaf pages from the tree, so +that their space can be reused. In order to delete an empty page, its +downlink must be removed from the parent. We scan all the internal pages, +whose block numbers we memorized in the first stage, and look for downlinks +to pages that we have memorized as being empty. Whenever we find one, we +acquire a lock on the parent and child page, re-check that the child page is +still empty. Then, we remove the downlink and mark the child as deleted, and +release the locks. + +The insertion algorithm would get confused, if an internal page was completely +empty. So we never delete the last child of an internal page, even if it's +empty. Currently, we only support deleting leaf pages. + +This page deletion algorithm works on a best-effort basis. It might fail to +find a downlink, if a concurrent page split moved it after the first stage. +In that case, we won't be able to remove all empty pages. That's OK, it's +not expected to happen very often, and hopefully the next VACUUM will clean +it up. + +When we have deleted a page, it's possible that an in-progress search will +still descend on the page, if it saw the downlink before we removed it. The +search will see that it is deleted, and ignore it, but as long as that can +happen, we cannot reuse the page. To "wait out" any in-progress searches, when +a page is deleted, it's labeled with the current next-transaction counter +value. The page is not recycled, until that XID is no longer visible to +anyone. That's much more conservative than necessary, but let's keep it +simple. + Authors: Teodor Sigaev diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 9007d65ad2a..0cc87911d6b 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -4,7 +4,7 @@ * interface routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -30,20 +30,20 @@ /* non-export function prototypes */ static void gistfixsplit(GISTInsertState *state, GISTSTATE *giststate); static bool gistinserttuple(GISTInsertState *state, GISTInsertStack *stack, - GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum); + GISTSTATE *giststate, IndexTuple tuple, OffsetNumber oldoffnum); static bool gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, - GISTSTATE *giststate, - IndexTuple *tuples, int ntup, OffsetNumber oldoffnum, - Buffer leftchild, Buffer rightchild, - bool unlockbuf, bool unlockleftchild); + GISTSTATE *giststate, + IndexTuple *tuples, int ntup, OffsetNumber oldoffnum, + Buffer leftchild, Buffer rightchild, + bool unlockbuf, bool unlockleftchild); static void gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, - GISTSTATE *giststate, List *splitinfo, bool releasebuf); -static void gistvacuumpage(Relation rel, Page page, Buffer buffer); + GISTSTATE *giststate, List *splitinfo, bool unlockbuf); +static void gistprunepage(Relation rel, Page page, Buffer buffer, + Relation heapRel); #define ROTATEDIST(d) do { \ - SplitedPageLayout *tmp=(SplitedPageLayout*)palloc(sizeof(SplitedPageLayout)); \ - memset(tmp,0,sizeof(SplitedPageLayout)); \ + SplitedPageLayout *tmp=(SplitedPageLayout*)palloc0(sizeof(SplitedPageLayout)); \ tmp->block.blkno = InvalidBlockNumber; \ tmp->buffer = InvalidBuffer; \ tmp->next = (d); \ @@ -74,7 +74,7 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->amclusterable = true; amroutine->ampredlocks = true; amroutine->amcanparallel = false; - amroutine->amcaninclude = false; + amroutine->amcaninclude = true; amroutine->amkeytype = InvalidOid; amroutine->ambuild = gistbuild; @@ -86,6 +86,7 @@ gisthandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = gistcostestimate; amroutine->amoptions = gistoptions; amroutine->amproperty = gistproperty; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = gistvalidate; amroutine->ambeginscan = gistbeginscan; amroutine->amrescan = gistrescan; @@ -172,7 +173,7 @@ gistinsert(Relation r, Datum *values, bool *isnull, values, isnull, true /* size is currently bogus */ ); itup->t_tid = *ht_ctid; - gistdoinsert(r, itup, 0, giststate); + gistdoinsert(r, itup, 0, giststate, heapRel, false); /* cleanup */ MemoryContextSwitchTo(oldCxt); @@ -218,7 +219,9 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, BlockNumber *newblkno, Buffer leftchildbuf, List **splitinfo, - bool markfollowright) + bool markfollowright, + Relation heapRel, + bool is_build) { BlockNumber blkno = BufferGetBlockNumber(buffer); Page page = BufferGetPage(buffer); @@ -259,7 +262,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, */ if (is_split && GistPageIsLeaf(page) && GistPageHasGarbage(page)) { - gistvacuumpage(rel, page, buffer); + gistprunepage(rel, page, buffer, heapRel); is_split = gistnospace(page, itup, ntup, oldoffnum, freespace); } @@ -341,8 +344,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, ptr->page = BufferGetPage(ptr->buffer); ptr->block.blkno = BufferGetBlockNumber(ptr->buffer); PredicateLockPageSplit(rel, - BufferGetBlockNumber(buffer), - BufferGetBlockNumber(ptr->buffer)); + BufferGetBlockNumber(buffer), + BufferGetBlockNumber(ptr->buffer)); } /* @@ -457,7 +460,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, * insertion for that. NB: The number of pages and data segments * specified here must match the calculations in gistXLogSplit()! */ - if (RelationNeedsWAL(rel)) + if (!is_build && RelationNeedsWAL(rel)) XLogEnsureRecordSpace(npage, 1 + npage * 2); START_CRIT_SECTION(); @@ -478,18 +481,30 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, PageRestoreTempPage(dist->page, BufferGetPage(dist->buffer)); dist->page = BufferGetPage(dist->buffer); - /* Write the WAL record */ - if (RelationNeedsWAL(rel)) - recptr = gistXLogSplit(is_leaf, - dist, oldrlink, oldnsn, leftchildbuf, - markfollowright); + /* + * Write the WAL record. + * + * If we're building a new index, however, we don't WAL-log changes + * yet. The LSN-NSN interlock between parent and child requires that + * LSNs never move backwards, so set the LSNs to a value that's + * smaller than any real or fake unlogged LSN that might be generated + * later. (There can't be any concurrent scans during index build, so + * we don't need to be able to detect concurrent splits yet.) + */ + if (is_build) + recptr = GistBuildLSN; else - recptr = gistGetFakeLSN(rel); + { + if (RelationNeedsWAL(rel)) + recptr = gistXLogSplit(is_leaf, + dist, oldrlink, oldnsn, leftchildbuf, + markfollowright); + else + recptr = gistGetFakeLSN(rel); + } for (ptr = dist; ptr; ptr = ptr->next) - { PageSetLSN(ptr->page, recptr); - } /* * Return the new child buffers to the caller. @@ -543,28 +558,29 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, if (BufferIsValid(leftchildbuf)) MarkBufferDirty(leftchildbuf); - if (RelationNeedsWAL(rel)) + if (is_build) + recptr = GistBuildLSN; + else { - OffsetNumber ndeloffs = 0, - deloffs[1]; - - if (OffsetNumberIsValid(oldoffnum)) + if (RelationNeedsWAL(rel)) { - deloffs[0] = oldoffnum; - ndeloffs = 1; - } + OffsetNumber ndeloffs = 0, + deloffs[1]; - recptr = gistXLogUpdate(buffer, - deloffs, ndeloffs, itup, ntup, - leftchildbuf); + if (OffsetNumberIsValid(oldoffnum)) + { + deloffs[0] = oldoffnum; + ndeloffs = 1; + } - PageSetLSN(page, recptr); - } - else - { - recptr = gistGetFakeLSN(rel); - PageSetLSN(page, recptr); + recptr = gistXLogUpdate(buffer, + deloffs, ndeloffs, itup, ntup, + leftchildbuf); + } + else + recptr = gistGetFakeLSN(rel); } + PageSetLSN(page, recptr); if (newblkno) *newblkno = blkno; @@ -604,7 +620,8 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, * so it does not bother releasing palloc'd allocations. */ void -gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) +gistdoinsert(Relation r, IndexTuple itup, Size freespace, + GISTSTATE *giststate, Relation heapRel, bool is_build) { ItemId iid; IndexTuple idxtuple; @@ -616,10 +633,13 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) memset(&state, 0, sizeof(GISTInsertState)); state.freespace = freespace; state.r = r; + state.heapRel = heapRel; + state.is_build = is_build; /* Start from the root */ firststack.blkno = GIST_ROOT_BLKNO; firststack.lsn = 0; + firststack.retry_from_parent = false; firststack.parent = NULL; firststack.downlinkoffnum = InvalidOffsetNumber; state.stack = stack = &firststack; @@ -632,6 +652,21 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) */ for (;;) { + /* + * If we split an internal page while descending the tree, we have to + * retry at the parent. (Normally, the LSN-NSN interlock below would + * also catch this and cause us to retry. But LSNs are not updated + * during index build.) + */ + while (stack->retry_from_parent) + { + if (xlocked) + LockBuffer(stack->buffer, GIST_UNLOCK); + xlocked = false; + ReleaseBuffer(stack->buffer); + state.stack = stack = stack->parent; + } + if (XLogRecPtrIsInvalid(stack->lsn)) stack->buffer = ReadBuffer(state.r, stack->blkno); @@ -674,14 +709,15 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) continue; } - if (stack->blkno != GIST_ROOT_BLKNO && - stack->parent->lsn < GistPageGetNSN(stack->page)) + if ((stack->blkno != GIST_ROOT_BLKNO && + stack->parent->lsn < GistPageGetNSN(stack->page)) || + GistPageIsDeleted(stack->page)) { /* - * Concurrent split detected. There's no guarantee that the - * downlink for this page is consistent with the tuple we're - * inserting anymore, so go back to parent and rechoose the best - * child. + * Concurrent split or page deletion detected. There's no + * guarantee that the downlink for this page is consistent with + * the tuple we're inserting anymore, so go back to parent and + * rechoose the best child. */ UnlockReleaseBuffer(stack->buffer); xlocked = false; @@ -783,7 +819,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) /* * Leaf page. Insert the new key. We've already updated all the * parents on the way down, but we might have to split the page if - * it doesn't fit. gistinserthere() will take care of that. + * it doesn't fit. gistinserttuple() will take care of that. */ /* @@ -820,12 +856,13 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) * leaf/inner is enough to recognize split for root */ } - else if (GistFollowRight(stack->page) || - stack->parent->lsn < GistPageGetNSN(stack->page)) + else if ((GistFollowRight(stack->page) || + stack->parent->lsn < GistPageGetNSN(stack->page)) && + GistPageIsDeleted(stack->page)) { /* - * The page was split while we momentarily unlocked the - * page. Go back to parent. + * The page was split or deleted while we momentarily + * unlocked the page. Go back to parent. */ UnlockReleaseBuffer(stack->buffer); xlocked = false; @@ -897,6 +934,9 @@ gistFindPath(Relation r, BlockNumber child, OffsetNumber *downlinkoffnum) break; } + /* currently, internal pages are never deleted */ + Assert(!GistPageIsDeleted(page)); + top->lsn = BufferGetLSNAtomic(buffer); /* @@ -1007,7 +1047,7 @@ gistFindCorrectParent(Relation r, GISTInsertStack *child) { /* * End of chain and still didn't find parent. It's a very-very - * rare situation when root splited. + * rare situation when root splitted. */ break; } @@ -1220,8 +1260,8 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, bool is_split; /* - * Check for any rw conflicts (in serialisation isolation level) - * just before we intend to modify the page + * Check for any rw conflicts (in serializable isolation level) just + * before we intend to modify the page */ CheckForSerializableConflictIn(state->r, NULL, stack->buffer); @@ -1232,7 +1272,9 @@ gistinserttuples(GISTInsertState *state, GISTInsertStack *stack, oldoffnum, NULL, leftchild, &splitinfo, - true); + true, + state->heapRel, + state->is_build); /* * Before recursing up in case the page was split, release locks on the @@ -1271,8 +1313,6 @@ static void gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, GISTSTATE *giststate, List *splitinfo, bool unlockbuf) { - ListCell *lc; - List *reversed; GISTPageSplitInfo *right; GISTPageSplitInfo *left; IndexTuple tuples[2]; @@ -1287,14 +1327,6 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, * left. Finally insert the downlink for the last new page and update the * downlink for the original page as one operation. */ - - /* for convenience, create a copy of the list in reverse order */ - reversed = NIL; - foreach(lc, splitinfo) - { - reversed = lcons(lfirst(lc), reversed); - } - LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE); gistFindCorrectParent(state->r, stack); @@ -1302,10 +1334,10 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, * insert downlinks for the siblings from right to left, until there are * only two siblings left. */ - while (list_length(reversed) > 2) + for (int pos = list_length(splitinfo) - 1; pos > 1; pos--) { - right = (GISTPageSplitInfo *) linitial(reversed); - left = (GISTPageSplitInfo *) lsecond(reversed); + right = (GISTPageSplitInfo *) list_nth(splitinfo, pos); + left = (GISTPageSplitInfo *) list_nth(splitinfo, pos - 1); if (gistinserttuples(state, stack->parent, giststate, &right->downlink, 1, @@ -1319,11 +1351,10 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, gistFindCorrectParent(state->r, stack); } /* gistinserttuples() released the lock on right->buf. */ - reversed = list_delete_first(reversed); } - right = (GISTPageSplitInfo *) linitial(reversed); - left = (GISTPageSplitInfo *) lsecond(reversed); + right = (GISTPageSplitInfo *) lsecond(splitinfo); + left = (GISTPageSplitInfo *) linitial(splitinfo); /* * Finally insert downlink for the remaining right page and update the @@ -1340,6 +1371,23 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack, unlockbuf /* Unlock stack->buffer if caller wants that */ ); Assert(left->buf == stack->buffer); + + /* + * If we split the page because we had to adjust the downlink on an + * internal page, while descending the tree for inserting a new tuple, + * then this might no longer be the correct page for the new tuple. The + * downlink to this page might not cover the new tuple anymore, it might + * need to go to the newly-created right sibling instead. Tell the caller + * to walk back up the stack, to re-check at the parent which page to + * insert to. + * + * Normally, the LSN-NSN interlock during the tree descend would also + * detect that a concurrent split happened (by ourselves), and cause us to + * retry at the parent. But that mechanism doesn't work during index + * build, because we don't do WAL-logging, and don't update LSNs, during + * index build. + */ + stack->retry_from_parent = true; } /* @@ -1377,8 +1425,10 @@ gistSplit(Relation r, IndexTupleSize(itup[0]), GiSTPageSize, RelationGetRelationName(r)))); - memset(v.spl_lisnull, true, sizeof(bool) * giststate->tupdesc->natts); - memset(v.spl_risnull, true, sizeof(bool) * giststate->tupdesc->natts); + memset(v.spl_lisnull, true, + sizeof(bool) * giststate->nonLeafTupdesc->natts); + memset(v.spl_risnull, true, + sizeof(bool) * giststate->nonLeafTupdesc->natts); gistSplitByKey(r, page, itup, len, giststate, &v, 0); /* form left and right vector */ @@ -1456,9 +1506,23 @@ initGISTstate(Relation index) giststate->scanCxt = scanCxt; giststate->tempCxt = scanCxt; /* caller must change this if needed */ - giststate->tupdesc = index->rd_att; + giststate->leafTupdesc = index->rd_att; + + /* + * The truncated tupdesc for non-leaf index tuples, which doesn't contain + * the INCLUDE attributes. + * + * It is used to form tuples during tuple adjustment and page split. + * B-tree creates shortened tuple descriptor for every truncated tuple, + * because it is doing this less often: it does not have to form truncated + * tuples during page split. Also, B-tree is not adjusting tuples on + * internal pages the way GiST does. + */ + giststate->nonLeafTupdesc = CreateTupleDescCopyConstr(index->rd_att); + giststate->nonLeafTupdesc->natts = + IndexRelationGetNumberOfKeyAttributes(index); - for (i = 0; i < index->rd_att->natts; i++) + for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(index); i++) { fmgr_info_copy(&(giststate->consistentFn[i]), index_getprocinfo(index, i + 1, GIST_CONSISTENT_PROC), @@ -1526,6 +1590,21 @@ initGISTstate(Relation index) giststate->supportCollation[i] = DEFAULT_COLLATION_OID; } + /* No opclass information for INCLUDE attributes */ + for (; i < index->rd_att->natts; i++) + { + giststate->consistentFn[i].fn_oid = InvalidOid; + giststate->unionFn[i].fn_oid = InvalidOid; + giststate->compressFn[i].fn_oid = InvalidOid; + giststate->decompressFn[i].fn_oid = InvalidOid; + giststate->penaltyFn[i].fn_oid = InvalidOid; + giststate->picksplitFn[i].fn_oid = InvalidOid; + giststate->equalFn[i].fn_oid = InvalidOid; + giststate->distanceFn[i].fn_oid = InvalidOid; + giststate->fetchFn[i].fn_oid = InvalidOid; + giststate->supportCollation[i] = InvalidOid; + } + MemoryContextSwitchTo(oldCxt); return giststate; @@ -1539,16 +1618,17 @@ freeGISTstate(GISTSTATE *giststate) } /* - * gistvacuumpage() -- try to remove LP_DEAD items from the given page. + * gistprunepage() -- try to remove LP_DEAD items from the given page. * Function assumes that buffer is exclusively locked. */ static void -gistvacuumpage(Relation rel, Page page, Buffer buffer) +gistprunepage(Relation rel, Page page, Buffer buffer, Relation heapRel) { OffsetNumber deletable[MaxIndexTuplesPerPage]; int ndeletable = 0; OffsetNumber offnum, maxoff; + TransactionId latestRemovedXid = InvalidTransactionId; Assert(GistPageIsLeaf(page)); @@ -1567,6 +1647,11 @@ gistvacuumpage(Relation rel, Page page, Buffer buffer) deletable[ndeletable++] = offnum; } + if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) + latestRemovedXid = + index_compute_xid_horizon_for_tuples(rel, heapRel, buffer, + deletable, ndeletable); + if (ndeletable > 0) { START_CRIT_SECTION(); @@ -1589,9 +1674,9 @@ gistvacuumpage(Relation rel, Page page, Buffer buffer) { XLogRecPtr recptr; - recptr = gistXLogUpdate(buffer, + recptr = gistXLogDelete(buffer, deletable, ndeletable, - NULL, 0, InvalidBuffer); + latestRemovedXid); PageSetLSN(page, recptr); } diff --git a/src/backend/access/gist/gistbuild.c b/src/backend/access/gist/gistbuild.c index 434f15f0148..2f4543dee52 100644 --- a/src/backend/access/gist/gistbuild.c +++ b/src/backend/access/gist/gistbuild.c @@ -4,7 +4,7 @@ * build algorithm for GiST indexes implementation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,10 +19,11 @@ #include "access/genam.h" #include "access/gist_private.h" #include "access/gistxlog.h" +#include "access/tableam.h" #include "access/xloginsert.h" #include "catalog/index.h" #include "miscadmin.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "storage/bufmgr.h" #include "storage/smgr.h" #include "utils/memutils.h" @@ -56,6 +57,7 @@ typedef enum typedef struct { Relation indexrel; + Relation heaprel; GISTSTATE *giststate; int64 indtuples; /* number of tuples indexed */ @@ -78,30 +80,30 @@ typedef struct static void gistInitBuffering(GISTBuildState *buildstate); static int calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep); static void gistBuildCallback(Relation index, - HeapTuple htup, - Datum *values, - bool *isnull, - bool tupleIsAlive, - void *state); + HeapTuple htup, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state); static void gistBufferingBuildInsert(GISTBuildState *buildstate, - IndexTuple itup); + IndexTuple itup); static bool gistProcessItup(GISTBuildState *buildstate, IndexTuple itup, - BlockNumber startblkno, int startlevel); + BlockNumber startblkno, int startlevel); static BlockNumber gistbufferinginserttuples(GISTBuildState *buildstate, - Buffer buffer, int level, - IndexTuple *itup, int ntup, OffsetNumber oldoffnum, - BlockNumber parentblk, OffsetNumber downlinkoffnum); + Buffer buffer, int level, + IndexTuple *itup, int ntup, OffsetNumber oldoffnum, + BlockNumber parentblk, OffsetNumber downlinkoffnum); static Buffer gistBufferingFindCorrectParent(GISTBuildState *buildstate, - BlockNumber childblkno, int level, - BlockNumber *parentblk, - OffsetNumber *downlinkoffnum); + BlockNumber childblkno, int level, + BlockNumber *parentblk, + OffsetNumber *downlinkoffnum); static void gistProcessEmptyingQueue(GISTBuildState *buildstate); static void gistEmptyAllBuffers(GISTBuildState *buildstate); static int gistGetMaxLevel(Relation index); static void gistInitParentMap(GISTBuildState *buildstate); static void gistMemorizeParent(GISTBuildState *buildstate, BlockNumber child, - BlockNumber parent); + BlockNumber parent); static void gistMemorizeAllDownlinks(GISTBuildState *buildstate, Buffer parent); static BlockNumber gistGetParent(GISTBuildState *buildstate, BlockNumber child); @@ -122,15 +124,16 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) int fillfactor; buildstate.indexrel = index; + buildstate.heaprel = heap; + if (index->rd_options) { /* Get buffering mode from the options string */ GiSTOptions *options = (GiSTOptions *) index->rd_options; - char *bufferingMode = (char *) options + options->bufferingModeOffset; - if (strcmp(bufferingMode, "on") == 0) + if (options->buffering_mode == GIST_OPTION_BUFFERING_ON) buildstate.bufferingMode = GIST_BUFFERING_STATS; - else if (strcmp(bufferingMode, "off") == 0) + else if (options->buffering_mode == GIST_OPTION_BUFFERING_OFF) buildstate.bufferingMode = GIST_BUFFERING_DISABLED; else buildstate.bufferingMode = GIST_BUFFERING_AUTO; @@ -177,19 +180,7 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) GISTInitBuffer(buffer, F_LEAF); MarkBufferDirty(buffer); - - if (RelationNeedsWAL(index)) - { - XLogRecPtr recptr; - - XLogBeginInsert(); - XLogRegisterBuffer(0, buffer, REGBUF_WILL_INIT); - - recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_CREATE_INDEX); - PageSetLSN(page, recptr); - } - else - PageSetLSN(page, gistGetFakeLSN(heap)); + PageSetLSN(page, GistBuildLSN); UnlockReleaseBuffer(buffer); @@ -202,8 +193,9 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) /* * Do the heap scan. */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, - gistBuildCallback, (void *) &buildstate, NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + gistBuildCallback, + (void *) &buildstate, NULL); /* * If buffering was used, flush out all the tuples that are still in the @@ -222,6 +214,17 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) freeGISTstate(buildstate.giststate); + /* + * We didn't write WAL records as we built the index, so if WAL-logging is + * required, write all pages to the WAL now. + */ + if (RelationNeedsWAL(index)) + { + log_newpage_range(index, MAIN_FORKNUM, + 0, RelationGetNumberOfBlocks(index), + true); + } + /* * Return statistics */ @@ -233,25 +236,6 @@ gistbuild(Relation heap, Relation index, IndexInfo *indexInfo) return result; } -/* - * Validator for "buffering" reloption on GiST indexes. Allows "on", "off" - * and "auto" values. - */ -void -gistValidateBufferingOption(const char *value) -{ - if (value == NULL || - (strcmp(value, "on") != 0 && - strcmp(value, "off") != 0 && - strcmp(value, "auto") != 0)) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for \"buffering\" option"), - errdetail("Valid values are \"on\", \"off\", and \"auto\"."))); - } -} - /* * Attempt to switch to buffering mode. * @@ -452,7 +436,7 @@ calculatePagesPerBuffer(GISTBuildState *buildstate, int levelStep) } /* - * Per-tuple callback from IndexBuildHeapScan. + * Per-tuple callback for table_index_build_scan. */ static void gistBuildCallback(Relation index, @@ -484,7 +468,7 @@ gistBuildCallback(Relation index, * locked, we call gistdoinsert directly. */ gistdoinsert(index, itup, buildstate->freespace, - buildstate->giststate); + buildstate->giststate, buildstate->heaprel, true); } /* Update tuple count and total size. */ @@ -690,7 +674,8 @@ gistbufferinginserttuples(GISTBuildState *buildstate, Buffer buffer, int level, itup, ntup, oldoffnum, &placed_to_blk, InvalidBuffer, &splitinfo, - false); + false, + buildstate->heaprel, true); /* * If this is a root split, update the root path item kept in memory. This diff --git a/src/backend/access/gist/gistbuildbuffers.c b/src/backend/access/gist/gistbuildbuffers.c index 97033983e35..38f786848de 100644 --- a/src/backend/access/gist/gistbuildbuffers.c +++ b/src/backend/access/gist/gistbuildbuffers.c @@ -4,7 +4,7 @@ * node buffer management functions for GiST buffering build algorithm. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -25,15 +25,15 @@ static GISTNodeBufferPage *gistAllocateNewPageBuffer(GISTBuildBuffers *gfbb); static void gistAddLoadedBuffer(GISTBuildBuffers *gfbb, - GISTNodeBuffer *nodeBuffer); + GISTNodeBuffer *nodeBuffer); static void gistLoadNodeBuffer(GISTBuildBuffers *gfbb, - GISTNodeBuffer *nodeBuffer); + GISTNodeBuffer *nodeBuffer); static void gistUnloadNodeBuffer(GISTBuildBuffers *gfbb, - GISTNodeBuffer *nodeBuffer); + GISTNodeBuffer *nodeBuffer); static void gistPlaceItupToPage(GISTNodeBufferPage *pageBuffer, - IndexTuple item); + IndexTuple item); static void gistGetItupFromPage(GISTNodeBufferPage *pageBuffer, - IndexTuple *item); + IndexTuple *item); static long gistBuffersGetFreeBlock(GISTBuildBuffers *gfbb); static void gistBuffersReleaseBlock(GISTBuildBuffers *gfbb, long blocknum); @@ -138,6 +138,7 @@ gistGetNodeBuffer(GISTBuildBuffers *gfbb, GISTSTATE *giststate, nodeBuffer->pageBlocknum = InvalidBlockNumber; nodeBuffer->pageBuffer = NULL; nodeBuffer->queuedForEmptying = false; + nodeBuffer->isTemp = false; nodeBuffer->level = level; /* @@ -186,8 +187,8 @@ gistAllocateNewPageBuffer(GISTBuildBuffers *gfbb) { GISTNodeBufferPage *pageBuffer; - pageBuffer = (GISTNodeBufferPage *) MemoryContextAlloc(gfbb->context, - BLCKSZ); + pageBuffer = (GISTNodeBufferPage *) MemoryContextAllocZero(gfbb->context, + BLCKSZ); pageBuffer->prev = InvalidBlockNumber; /* Set page free space */ diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c index c4e8a3b9131..22d790d8221 100644 --- a/src/backend/access/gist/gistget.c +++ b/src/backend/access/gist/gistget.c @@ -4,7 +4,7 @@ * fetch tuples from a GiST scan. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,15 +14,15 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/gist_private.h" #include "access/relscan.h" -#include "catalog/pg_type.h" #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" #include "pgstat.h" #include "lib/pairingheap.h" -#include "utils/builtins.h" +#include "utils/float.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -74,7 +74,7 @@ gistkillitems(IndexScanDesc scan) /* * Mark all killedItems as dead. We need no additional recheck, because, - * if page was modified, pageLSN must have changed. + * if page was modified, curPageLSN must have changed. */ for (i = 0; i < so->numKilled; i++) { @@ -134,7 +134,7 @@ gistindex_keytest(IndexScanDesc scan, GISTSTATE *giststate = so->giststate; ScanKey key = scan->keyData; int keySize = scan->numberOfKeys; - double *distance_p; + IndexOrderByDistance *distance_p; Relation r = scan->indexRelation; *recheck_p = false; @@ -152,7 +152,10 @@ gistindex_keytest(IndexScanDesc scan, if (GistPageIsLeaf(page)) /* shouldn't happen */ elog(ERROR, "invalid GiST tuple found on leaf page"); for (i = 0; i < scan->numberOfOrderBys; i++) - so->distances[i] = -get_float8_infinity(); + { + so->distances[i].value = -get_float8_infinity(); + so->distances[i].isnull = false; + } return true; } @@ -164,7 +167,7 @@ gistindex_keytest(IndexScanDesc scan, datum = index_getattr(tuple, key->sk_attno, - giststate->tupdesc, + giststate->leafTupdesc, &isNull); if (key->sk_flags & SK_ISNULL) @@ -244,13 +247,14 @@ gistindex_keytest(IndexScanDesc scan, datum = index_getattr(tuple, key->sk_attno, - giststate->tupdesc, + giststate->leafTupdesc, &isNull); if ((key->sk_flags & SK_ISNULL) || isNull) { - /* Assume distance computes as null and sorts to the end */ - *distance_p = get_float8_infinity(); + /* Assume distance computes as null */ + distance_p->value = 0.0; + distance_p->isnull = true; } else { @@ -287,7 +291,8 @@ gistindex_keytest(IndexScanDesc scan, ObjectIdGetDatum(key->sk_subtype), PointerGetDatum(&recheck)); *recheck_distances_p |= recheck; - *distance_p = DatumGetFloat8(dist); + distance_p->value = DatumGetFloat8(dist); + distance_p->isnull = false; } key++; @@ -321,8 +326,8 @@ gistindex_keytest(IndexScanDesc scan, * sibling will be processed next. */ static void -gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, - TIDBitmap *tbm, int64 *ntids) +gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, + IndexOrderByDistance *myDistances, TIDBitmap *tbm, int64 *ntids) { GISTScanOpaque so = (GISTScanOpaque) scan->opaque; GISTSTATE *giststate = so->giststate; @@ -370,13 +375,27 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, /* Insert it into the queue using same distances as for this page */ memcpy(item->distances, myDistances, - sizeof(double) * scan->numberOfOrderBys); + sizeof(item->distances[0]) * scan->numberOfOrderBys); pairingheap_add(so->queue, &item->phNode); MemoryContextSwitchTo(oldcxt); } + /* + * Check if the page was deleted after we saw the downlink. There's + * nothing of interest on a deleted page. Note that we must do this after + * checking the NSN for concurrent splits! It's possible that the page + * originally contained some tuples that are visible to us, but was split + * so that all the visible tuples were moved to another page, and then + * this page was deleted. + */ + if (GistPageIsDeleted(page)) + { + UnlockReleaseBuffer(buffer); + return; + } + so->nPageData = so->curPageData = 0; scan->xs_hitup = NULL; /* might point into pageDataCxt */ if (so->pageDataCxt) @@ -465,6 +484,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, * search. */ GISTSearchItem *item; + int nOrderBys = scan->numberOfOrderBys; oldcxt = MemoryContextSwitchTo(so->queueCxt); @@ -500,7 +520,7 @@ gistScanPage(IndexScanDesc scan, GISTSearchItem *pageItem, double *myDistances, /* Insert it into the queue using new distance data */ memcpy(item->distances, so->distances, - sizeof(double) * scan->numberOfOrderBys); + sizeof(item->distances[0]) * nOrderBys); pairingheap_add(so->queue, &item->phNode); @@ -543,7 +563,6 @@ getNextNearest(IndexScanDesc scan) { GISTScanOpaque so = (GISTScanOpaque) scan->opaque; bool res = false; - int i; if (scan->xs_hitup) { @@ -562,47 +581,12 @@ getNextNearest(IndexScanDesc scan) if (GISTSearchItemIsHeap(*item)) { /* found a heap item at currently minimal distance */ - scan->xs_ctup.t_self = item->data.heap.heapPtr; + scan->xs_heaptid = item->data.heap.heapPtr; scan->xs_recheck = item->data.heap.recheck; - scan->xs_recheckorderby = item->data.heap.recheckDistances; - for (i = 0; i < scan->numberOfOrderBys; i++) - { - if (so->orderByTypes[i] == FLOAT8OID) - { -#ifndef USE_FLOAT8_BYVAL - /* must free any old value to avoid memory leakage */ - if (!scan->xs_orderbynulls[i]) - pfree(DatumGetPointer(scan->xs_orderbyvals[i])); -#endif - scan->xs_orderbyvals[i] = Float8GetDatum(item->distances[i]); - scan->xs_orderbynulls[i] = false; - } - else if (so->orderByTypes[i] == FLOAT4OID) - { - /* convert distance function's result to ORDER BY type */ -#ifndef USE_FLOAT4_BYVAL - /* must free any old value to avoid memory leakage */ - if (!scan->xs_orderbynulls[i]) - pfree(DatumGetPointer(scan->xs_orderbyvals[i])); -#endif - scan->xs_orderbyvals[i] = Float4GetDatum((float4) item->distances[i]); - scan->xs_orderbynulls[i] = false; - } - else - { - /* - * If the ordering operator's return value is anything - * else, we don't know how to convert the float8 bound - * calculated by the distance function to that. The - * executor won't actually need the order by values we - * return here, if there are no lossy results, so only - * insist on converting if the *recheck flag is set. - */ - if (scan->xs_recheckorderby) - elog(ERROR, "GiST operator family's FOR ORDER BY operator must return float8 or float4 if the distance function is lossy"); - scan->xs_orderbynulls[i] = true; - } - } + + index_store_float8_orderby_distances(scan, so->orderByTypes, + item->distances, + item->data.heap.recheckDistances); /* in an index-only scan, also return the reconstructed tuple. */ if (scan->xs_want_itup) @@ -686,7 +670,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir) so->pageData[so->curPageData - 1].offnum; } /* continuing to return tuples from a leaf page */ - scan->xs_ctup.t_self = so->pageData[so->curPageData].heapPtr; + scan->xs_heaptid = so->pageData[so->curPageData].heapPtr; scan->xs_recheck = so->pageData[so->curPageData].recheck; /* in an index-only scan, also return the reconstructed tuple */ @@ -699,7 +683,7 @@ gistgettuple(IndexScanDesc scan, ScanDirection dir) } /* - * Check the last returned tuple and add it to killitems if + * Check the last returned tuple and add it to killedItems if * necessary */ if (scan->kill_prior_tuple @@ -805,11 +789,13 @@ gistgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) * * Opclasses that implement a fetch function support index-only scans. * Opclasses without compression functions also support index-only scans. + * Included attributes always can be fetched for index-only scans. */ bool gistcanreturn(Relation index, int attno) { - if (OidIsValid(index_getprocid(index, attno, GIST_FETCH_PROC)) || + if (attno > IndexRelationGetNumberOfKeyAttributes(index) || + OidIsValid(index_getprocid(index, attno, GIST_FETCH_PROC)) || !OidIsValid(index_getprocid(index, attno, GIST_COMPRESS_PROC))) return true; else diff --git a/src/backend/access/gist/gistproc.c b/src/backend/access/gist/gistproc.c index 97e6dc99100..118dd9653fa 100644 --- a/src/backend/access/gist/gistproc.c +++ b/src/backend/access/gist/gistproc.c @@ -7,7 +7,7 @@ * This gives R-tree behavior, with Guttman's poly-time split algorithm. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,32 +17,23 @@ */ #include "postgres.h" -#include #include #include "access/gist.h" #include "access/stratnum.h" #include "utils/builtins.h" +#include "utils/float.h" #include "utils/geo_decls.h" static bool gist_box_leaf_consistent(BOX *key, BOX *query, - StrategyNumber strategy); + StrategyNumber strategy); static bool rtree_internal_consistent(BOX *key, BOX *query, - StrategyNumber strategy); + StrategyNumber strategy); /* Minimum accepted ratio of split */ #define LIMIT_RATIO 0.3 -/* Convenience macros for NaN-aware comparisons */ -#define FLOAT8_EQ(a,b) (float8_cmp_internal(a, b) == 0) -#define FLOAT8_LT(a,b) (float8_cmp_internal(a, b) < 0) -#define FLOAT8_LE(a,b) (float8_cmp_internal(a, b) <= 0) -#define FLOAT8_GT(a,b) (float8_cmp_internal(a, b) > 0) -#define FLOAT8_GE(a,b) (float8_cmp_internal(a, b) >= 0) -#define FLOAT8_MAX(a,b) (FLOAT8_GT(a, b) ? (a) : (b)) -#define FLOAT8_MIN(a,b) (FLOAT8_LT(a, b) ? (a) : (b)) - /************************************************** * Box ops @@ -54,17 +45,17 @@ static bool rtree_internal_consistent(BOX *key, BOX *query, static void rt_box_union(BOX *n, const BOX *a, const BOX *b) { - n->high.x = FLOAT8_MAX(a->high.x, b->high.x); - n->high.y = FLOAT8_MAX(a->high.y, b->high.y); - n->low.x = FLOAT8_MIN(a->low.x, b->low.x); - n->low.y = FLOAT8_MIN(a->low.y, b->low.y); + n->high.x = float8_max(a->high.x, b->high.x); + n->high.y = float8_max(a->high.y, b->high.y); + n->low.x = float8_min(a->low.x, b->low.x); + n->low.y = float8_min(a->low.y, b->low.y); } /* * Size of a BOX for penalty-calculation purposes. * The result can be +Infinity, but not NaN. */ -static double +static float8 size_box(const BOX *box) { /* @@ -74,8 +65,8 @@ size_box(const BOX *box) * * The less-than cases should not happen, but if they do, say "zero". */ - if (FLOAT8_LE(box->high.x, box->low.x) || - FLOAT8_LE(box->high.y, box->low.y)) + if (float8_le(box->high.x, box->low.x) || + float8_le(box->high.y, box->low.y)) return 0.0; /* @@ -85,20 +76,21 @@ size_box(const BOX *box) */ if (isnan(box->high.x) || isnan(box->high.y)) return get_float8_infinity(); - return (box->high.x - box->low.x) * (box->high.y - box->low.y); + return float8_mul(float8_mi(box->high.x, box->low.x), + float8_mi(box->high.y, box->low.y)); } /* * Return amount by which the union of the two boxes is larger than * the original BOX's area. The result can be +Infinity, but not NaN. */ -static double +static float8 box_penalty(const BOX *original, const BOX *new) { BOX unionbox; rt_box_union(&unionbox, original, new); - return size_box(&unionbox) - size_box(original); + return float8_mi(size_box(&unionbox), size_box(original)); } /* @@ -144,13 +136,13 @@ gist_box_consistent(PG_FUNCTION_ARGS) static void adjustBox(BOX *b, const BOX *addon) { - if (FLOAT8_LT(b->high.x, addon->high.x)) + if (float8_lt(b->high.x, addon->high.x)) b->high.x = addon->high.x; - if (FLOAT8_GT(b->low.x, addon->low.x)) + if (float8_gt(b->low.x, addon->low.x)) b->low.x = addon->low.x; - if (FLOAT8_LT(b->high.y, addon->high.y)) + if (float8_lt(b->high.y, addon->high.y)) b->high.y = addon->high.y; - if (FLOAT8_GT(b->low.y, addon->low.y)) + if (float8_gt(b->low.y, addon->low.y)) b->low.y = addon->low.y; } @@ -272,7 +264,7 @@ typedef struct /* Index of entry in the initial array */ int index; /* Delta between penalties of entry insertion into different groups */ - double delta; + float8 delta; } CommonEntry; /* @@ -288,13 +280,13 @@ typedef struct bool first; /* true if no split was selected yet */ - double leftUpper; /* upper bound of left interval */ - double rightLower; /* lower bound of right interval */ + float8 leftUpper; /* upper bound of left interval */ + float8 rightLower; /* lower bound of right interval */ float4 ratio; float4 overlap; int dim; /* axis of this split */ - double range; /* width of general MBR projection to the + float8 range; /* width of general MBR projection to the * selected axis */ } ConsiderSplitContext; @@ -303,7 +295,7 @@ typedef struct */ typedef struct { - double lower, + float8 lower, upper; } SplitInterval; @@ -313,7 +305,7 @@ typedef struct static int interval_cmp_lower(const void *i1, const void *i2) { - double lower1 = ((const SplitInterval *) i1)->lower, + float8 lower1 = ((const SplitInterval *) i1)->lower, lower2 = ((const SplitInterval *) i2)->lower; return float8_cmp_internal(lower1, lower2); @@ -325,7 +317,7 @@ interval_cmp_lower(const void *i1, const void *i2) static int interval_cmp_upper(const void *i1, const void *i2) { - double upper1 = ((const SplitInterval *) i1)->upper, + float8 upper1 = ((const SplitInterval *) i1)->upper, upper2 = ((const SplitInterval *) i2)->upper; return float8_cmp_internal(upper1, upper2); @@ -348,14 +340,14 @@ non_negative(float val) */ static inline void g_box_consider_split(ConsiderSplitContext *context, int dimNum, - double rightLower, int minLeftCount, - double leftUpper, int maxLeftCount) + float8 rightLower, int minLeftCount, + float8 leftUpper, int maxLeftCount) { int leftCount, rightCount; float4 ratio, overlap; - double range; + float8 range; /* * Calculate entries distribution ratio assuming most uniform distribution @@ -378,8 +370,7 @@ g_box_consider_split(ConsiderSplitContext *context, int dimNum, * Ratio of split - quotient between size of lesser group and total * entries count. */ - ratio = ((float4) Min(leftCount, rightCount)) / - ((float4) context->entriesCount); + ratio = float4_div(Min(leftCount, rightCount), context->entriesCount); if (ratio > LIMIT_RATIO) { @@ -393,11 +384,13 @@ g_box_consider_split(ConsiderSplitContext *context, int dimNum, * or less range with same overlap. */ if (dimNum == 0) - range = context->boundingBox.high.x - context->boundingBox.low.x; + range = float8_mi(context->boundingBox.high.x, + context->boundingBox.low.x); else - range = context->boundingBox.high.y - context->boundingBox.low.y; + range = float8_mi(context->boundingBox.high.y, + context->boundingBox.low.y); - overlap = (leftUpper - rightLower) / range; + overlap = float8_div(float8_mi(leftUpper, rightLower), range); /* If there is no previous selection, select this */ if (context->first) @@ -453,20 +446,14 @@ g_box_consider_split(ConsiderSplitContext *context, int dimNum, /* * Compare common entries by their deltas. - * (We assume the deltas can't be NaN.) */ static int common_entry_cmp(const void *i1, const void *i2) { - double delta1 = ((const CommonEntry *) i1)->delta, + float8 delta1 = ((const CommonEntry *) i1)->delta, delta2 = ((const CommonEntry *) i2)->delta; - if (delta1 < delta2) - return -1; - else if (delta1 > delta2) - return 1; - else - return 0; + return float8_cmp_internal(delta1, delta2); } /* @@ -540,7 +527,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) context.first = true; /* nothing selected yet */ for (dim = 0; dim < 2; dim++) { - double leftUpper, + float8 leftUpper, rightLower; int i1, i2; @@ -616,9 +603,9 @@ gist_box_picksplit(PG_FUNCTION_ARGS) * Find next lower bound of right group. */ while (i1 < nentries && - FLOAT8_EQ(rightLower, intervalsLower[i1].lower)) + float8_eq(rightLower, intervalsLower[i1].lower)) { - if (FLOAT8_LT(leftUpper, intervalsLower[i1].upper)) + if (float8_lt(leftUpper, intervalsLower[i1].upper)) leftUpper = intervalsLower[i1].upper; i1++; } @@ -631,7 +618,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) * left group. */ while (i2 < nentries && - FLOAT8_LE(intervalsUpper[i2].upper, leftUpper)) + float8_le(intervalsUpper[i2].upper, leftUpper)) i2++; /* @@ -653,9 +640,9 @@ gist_box_picksplit(PG_FUNCTION_ARGS) /* * Find next upper bound of left group. */ - while (i2 >= 0 && FLOAT8_EQ(leftUpper, intervalsUpper[i2].upper)) + while (i2 >= 0 && float8_eq(leftUpper, intervalsUpper[i2].upper)) { - if (FLOAT8_GT(rightLower, intervalsUpper[i2].lower)) + if (float8_gt(rightLower, intervalsUpper[i2].lower)) rightLower = intervalsUpper[i2].lower; i2--; } @@ -667,7 +654,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) * Find count of intervals which anyway should be placed to the * right group. */ - while (i1 >= 0 && FLOAT8_GE(intervalsLower[i1].lower, rightLower)) + while (i1 >= 0 && float8_ge(intervalsLower[i1].lower, rightLower)) i1--; /* @@ -737,7 +724,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) */ for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - double lower, + float8 lower, upper; /* @@ -755,10 +742,10 @@ gist_box_picksplit(PG_FUNCTION_ARGS) upper = box->high.y; } - if (FLOAT8_LE(upper, context.leftUpper)) + if (float8_le(upper, context.leftUpper)) { /* Fits to the left group */ - if (FLOAT8_GE(lower, context.rightLower)) + if (float8_ge(lower, context.rightLower)) { /* Fits also to the right group, so "common entry" */ commonEntries[commonEntriesCount++].index = i; @@ -776,7 +763,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) * entry didn't fit on the left group, it better fit in the right * group. */ - Assert(FLOAT8_GE(lower, context.rightLower)); + Assert(float8_ge(lower, context.rightLower)); /* Doesn't fit to the left group, so join to the right group */ PLACE_RIGHT(box, i); @@ -792,7 +779,7 @@ gist_box_picksplit(PG_FUNCTION_ARGS) * Calculate minimum number of entries that must be placed in both * groups, to reach LIMIT_RATIO. */ - int m = ceil(LIMIT_RATIO * (double) nentries); + int m = ceil(LIMIT_RATIO * nentries); /* * Calculate delta between penalties of join "common entries" to @@ -801,8 +788,8 @@ gist_box_picksplit(PG_FUNCTION_ARGS) for (i = 0; i < commonEntriesCount; i++) { box = DatumGetBoxP(entryvec->vector[commonEntries[i].index].key); - commonEntries[i].delta = Abs(box_penalty(leftBox, box) - - box_penalty(rightBox, box)); + commonEntries[i].delta = Abs(float8_mi(box_penalty(leftBox, box), + box_penalty(rightBox, box))); } /* @@ -860,10 +847,10 @@ gist_box_same(PG_FUNCTION_ARGS) bool *result = (bool *) PG_GETARG_POINTER(2); if (b1 && b2) - *result = (FLOAT8_EQ(b1->low.x, b2->low.x) && - FLOAT8_EQ(b1->low.y, b2->low.y) && - FLOAT8_EQ(b1->high.x, b2->high.x) && - FLOAT8_EQ(b1->high.y, b2->high.y)); + *result = (float8_eq(b1->low.x, b2->low.x) && + float8_eq(b1->low.y, b2->low.y) && + float8_eq(b1->high.x, b2->high.x) && + float8_eq(b1->high.y, b2->high.y)); else *result = (b1 == NULL && b2 == NULL); PG_RETURN_POINTER(result); @@ -1116,10 +1103,10 @@ gist_circle_compress(PG_FUNCTION_ARGS) BOX *r; r = (BOX *) palloc(sizeof(BOX)); - r->high.x = in->center.x + in->radius; - r->low.x = in->center.x - in->radius; - r->high.y = in->center.y + in->radius; - r->low.y = in->center.y - in->radius; + r->high.x = float8_pl(in->center.x, in->radius); + r->low.x = float8_mi(in->center.x, in->radius); + r->high.y = float8_pl(in->center.y, in->radius); + r->low.y = float8_mi(in->center.y, in->radius); retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r), @@ -1157,10 +1144,10 @@ gist_circle_consistent(PG_FUNCTION_ARGS) * rtree_internal_consistent even at leaf nodes. (This works in part * because the index entries are bounding boxes not circles.) */ - bbox.high.x = query->center.x + query->radius; - bbox.low.x = query->center.x - query->radius; - bbox.high.y = query->center.y + query->radius; - bbox.low.y = query->center.y - query->radius; + bbox.high.x = float8_pl(query->center.x, query->radius); + bbox.low.x = float8_mi(query->center.x, query->radius); + bbox.high.y = float8_pl(query->center.y, query->radius); + bbox.low.y = float8_mi(query->center.y, query->radius); result = rtree_internal_consistent(DatumGetBoxP(entry->key), &bbox, strategy); @@ -1225,10 +1212,10 @@ gist_point_fetch(PG_FUNCTION_ARGS) DatumGetFloat8(DirectFunctionCall2(point_distance, \ PointPGetDatum(p1), PointPGetDatum(p2))) -static double +static float8 computeDistance(bool isLeaf, BOX *box, Point *point) { - double result = 0.0; + float8 result = 0.0; if (isLeaf) { @@ -1246,9 +1233,9 @@ computeDistance(bool isLeaf, BOX *box, Point *point) /* point is over or below box */ Assert(box->low.y <= box->high.y); if (point->y > box->high.y) - result = point->y - box->high.y; + result = float8_mi(point->y, box->high.y); else if (point->y < box->low.y) - result = box->low.y - point->y; + result = float8_mi(box->low.y, point->y); else elog(ERROR, "inconsistent point values"); } @@ -1257,9 +1244,9 @@ computeDistance(bool isLeaf, BOX *box, Point *point) /* point is to left or right of box */ Assert(box->low.x <= box->high.x); if (point->x > box->high.x) - result = point->x - box->high.x; + result = float8_mi(point->x, box->high.x); else if (point->x < box->low.x) - result = box->low.x - point->x; + result = float8_mi(box->low.x, point->x); else elog(ERROR, "inconsistent point values"); } @@ -1267,7 +1254,7 @@ computeDistance(bool isLeaf, BOX *box, Point *point) { /* closest point will be a vertex */ Point p; - double subresult; + float8 subresult; result = point_point_distance(point, &box->low); @@ -1458,7 +1445,7 @@ gist_point_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - double distance; + float8 distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; switch (strategyGroup) @@ -1477,26 +1464,12 @@ gist_point_distance(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(distance); } -/* - * The inexact GiST distance method for geometric types that store bounding - * boxes. - * - * Compute lossy distance from point to index entries. The result is inexact - * because index entries are bounding boxes, not the exact shapes of the - * indexed geometric types. We use distance from point to MBR of index entry. - * This is a lower bound estimate of distance from point to indexed geometric - * type. - */ -static double -gist_bbox_distance(GISTENTRY *entry, Datum query, - StrategyNumber strategy, bool *recheck) +static float8 +gist_bbox_distance(GISTENTRY *entry, Datum query, StrategyNumber strategy) { - double distance; + float8 distance; StrategyNumber strategyGroup = strategy / GeoStrategyNumberOffset; - /* Bounding box distance is always inexact. */ - *recheck = true; - switch (strategyGroup) { case PointStrategyNumberGroup: @@ -1512,6 +1485,32 @@ gist_bbox_distance(GISTENTRY *entry, Datum query, return distance; } +Datum +gist_box_distance(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + Datum query = PG_GETARG_DATUM(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + + /* Oid subtype = PG_GETARG_OID(3); */ + /* bool *recheck = (bool *) PG_GETARG_POINTER(4); */ + float8 distance; + + distance = gist_bbox_distance(entry, query, strategy); + + PG_RETURN_FLOAT8(distance); +} + +/* + * The inexact GiST distance methods for geometric types that store bounding + * boxes. + * + * Compute lossy distance from point to index entries. The result is inexact + * because index entries are bounding boxes, not the exact shapes of the + * indexed geometric types. We use distance from point to MBR of index entry. + * This is a lower bound estimate of distance from point to indexed geometric + * type. + */ Datum gist_circle_distance(PG_FUNCTION_ARGS) { @@ -1521,9 +1520,10 @@ gist_circle_distance(PG_FUNCTION_ARGS) /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); - double distance; + float8 distance; - distance = gist_bbox_distance(entry, query, strategy, recheck); + distance = gist_bbox_distance(entry, query, strategy); + *recheck = true; PG_RETURN_FLOAT8(distance); } @@ -1537,9 +1537,10 @@ gist_poly_distance(PG_FUNCTION_ARGS) /* Oid subtype = PG_GETARG_OID(3); */ bool *recheck = (bool *) PG_GETARG_POINTER(4); - double distance; + float8 distance; - distance = gist_bbox_distance(entry, query, strategy, recheck); + distance = gist_bbox_distance(entry, query, strategy); + *recheck = true; PG_RETURN_FLOAT8(distance); } diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c index 4d97ff1d5d2..7d0d3524bb6 100644 --- a/src/backend/access/gist/gistscan.c +++ b/src/backend/access/gist/gistscan.c @@ -4,7 +4,7 @@ * routines to manage scans on GiST index relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,6 +17,7 @@ #include "access/gist_private.h" #include "access/gistscan.h" #include "access/relscan.h" +#include "utils/float.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -36,8 +37,23 @@ pairingheap_GISTSearchItem_cmp(const pairingheap_node *a, const pairingheap_node /* Order according to distance comparison */ for (i = 0; i < scan->numberOfOrderBys; i++) { - if (sa->distances[i] != sb->distances[i]) - return (sa->distances[i] < sb->distances[i]) ? 1 : -1; + if (sa->distances[i].isnull) + { + if (!sb->distances[i].isnull) + return -1; + } + else if (sb->distances[i].isnull) + { + return 1; + } + else + { + int cmp = -float8_cmp_internal(sa->distances[i].value, + sb->distances[i].value); + + if (cmp != 0) + return cmp; + } } /* Heap items go before inner pages, to ensure a depth-first search */ @@ -81,7 +97,7 @@ gistbeginscan(Relation r, int nkeys, int norderbys) so->queueCxt = giststate->scanCxt; /* see gistrescan */ /* workspaces with size dependent on numberOfOrderBys: */ - so->distances = palloc(sizeof(double) * scan->numberOfOrderBys); + so->distances = palloc(sizeof(so->distances[0]) * scan->numberOfOrderBys); so->qual_ok = true; /* in case there are zero keys */ if (scan->numberOfOrderBys > 0) { @@ -158,6 +174,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, if (scan->xs_want_itup && !scan->xs_hitupdesc) { int natts; + int nkeyatts; int attno; /* @@ -167,13 +184,23 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, * types. */ natts = RelationGetNumberOfAttributes(scan->indexRelation); - so->giststate->fetchTupdesc = CreateTemplateTupleDesc(natts, false); - for (attno = 1; attno <= natts; attno++) + nkeyatts = IndexRelationGetNumberOfKeyAttributes(scan->indexRelation); + so->giststate->fetchTupdesc = CreateTemplateTupleDesc(natts); + for (attno = 1; attno <= nkeyatts; attno++) { TupleDescInitEntry(so->giststate->fetchTupdesc, attno, NULL, scan->indexRelation->rd_opcintype[attno - 1], -1, 0); } + + for (; attno <= natts; attno++) + { + /* taking opcintype from giststate->tupdesc */ + TupleDescInitEntry(so->giststate->fetchTupdesc, attno, NULL, + TupleDescAttr(so->giststate->leafTupdesc, + attno - 1)->atttypid, + -1, 0); + } scan->xs_hitupdesc = so->giststate->fetchTupdesc; /* Also create a memory context that will hold the returned tuples */ diff --git a/src/backend/access/gist/gistsplit.c b/src/backend/access/gist/gistsplit.c index a7038cca672..6a9c54d86ce 100644 --- a/src/backend/access/gist/gistsplit.c +++ b/src/backend/access/gist/gistsplit.c @@ -15,7 +15,7 @@ * gistSplitByKey() is the entry point to this file. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -207,7 +207,7 @@ placeOne(Relation r, GISTSTATE *giststate, GistSplitVector *v, gistDeCompressAtt(giststate, r, itup, NULL, (OffsetNumber) 0, identry, isnull); - for (; attno < giststate->tupdesc->natts; attno++) + for (; attno < giststate->nonLeafTupdesc->natts; attno++) { float lpenalty, rpenalty; @@ -485,7 +485,7 @@ gistUserPicksplit(Relation r, GistEntryVector *entryvec, int attno, GistSplitVec */ v->spl_dontcare = NULL; - if (attno + 1 < giststate->tupdesc->natts) + if (attno + 1 < giststate->nonLeafTupdesc->natts) { int NumDontCare; @@ -639,7 +639,7 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, Datum datum; bool IsNull; - datum = index_getattr(itup[i - 1], attno + 1, giststate->tupdesc, + datum = index_getattr(itup[i - 1], attno + 1, giststate->leafTupdesc, &IsNull); gistdentryinit(giststate, attno, &(entryvec->vector[i]), datum, r, page, i, @@ -657,7 +657,7 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, */ v->spl_risnull[attno] = v->spl_lisnull[attno] = true; - if (attno + 1 < giststate->tupdesc->natts) + if (attno + 1 < giststate->nonLeafTupdesc->natts) gistSplitByKey(r, page, itup, len, giststate, v, attno + 1); else gistSplitHalf(&v->splitVector, len); @@ -683,7 +683,7 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, v->splitVector.spl_left[v->splitVector.spl_nleft++] = i; /* Compute union keys, unless outer recursion level will handle it */ - if (attno == 0 && giststate->tupdesc->natts == 1) + if (attno == 0 && giststate->nonLeafTupdesc->natts == 1) { v->spl_dontcare = NULL; gistunionsubkey(giststate, itup, v); @@ -700,7 +700,7 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, * Splitting on attno column is not optimal, so consider * redistributing don't-care tuples according to the next column */ - Assert(attno + 1 < giststate->tupdesc->natts); + Assert(attno + 1 < giststate->nonLeafTupdesc->natts); if (v->spl_dontcare == NULL) { @@ -771,7 +771,7 @@ gistSplitByKey(Relation r, Page page, IndexTuple *itup, int len, * that PickSplit (or the special cases above) produced correct union * datums. */ - if (attno == 0 && giststate->tupdesc->natts > 1) + if (attno == 0 && giststate->nonLeafTupdesc->natts > 1) { v->spl_dontcare = NULL; gistunionsubkey(giststate, itup, v); diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 55cccd247a0..45804d7a91e 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -4,7 +4,7 @@ * utilities routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,7 +13,6 @@ */ #include "postgres.h" -#include #include #include "access/gist_private.h" @@ -22,8 +21,10 @@ #include "catalog/pg_opclass.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" -#include "utils/builtins.h" +#include "utils/float.h" #include "utils/syscache.h" +#include "utils/snapmgr.h" +#include "utils/lsyscache.h" /* @@ -119,7 +120,7 @@ gistjoinvector(IndexTuple *itvec, int *len, IndexTuple *additvec, int addlen) } /* - * make plain IndexTupleVector + * make plain IndexTuple vector */ IndexTupleData * @@ -160,7 +161,7 @@ gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, evec = (GistEntryVector *) palloc((len + 2) * sizeof(GISTENTRY) + GEVHDRSZ); - for (i = 0; i < giststate->tupdesc->natts; i++) + for (i = 0; i < giststate->nonLeafTupdesc->natts; i++) { int j; @@ -171,7 +172,8 @@ gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, Datum datum; bool IsNull; - datum = index_getattr(itvec[j], i + 1, giststate->tupdesc, &IsNull); + datum = index_getattr(itvec[j], i + 1, giststate->leafTupdesc, + &IsNull); if (IsNull) continue; @@ -296,11 +298,11 @@ gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, { int i; - for (i = 0; i < r->rd_att->natts; i++) + for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(r); i++) { Datum datum; - datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]); + datum = index_getattr(tuple, i + 1, giststate->leafTupdesc, &isnull[i]); gistdentryinit(giststate, i, &attdata[i], datum, r, p, o, false, isnull[i]); @@ -329,7 +331,7 @@ gistgetadjusted(Relation r, IndexTuple oldtup, IndexTuple addtup, GISTSTATE *gis gistDeCompressAtt(giststate, r, addtup, NULL, (OffsetNumber) 0, addentries, addisnull); - for (i = 0; i < r->rd_att->natts; i++) + for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(r); i++) { gistMakeUnionKey(giststate, i, oldentries + i, oldisnull[i], @@ -442,14 +444,15 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ zero_penalty = true; /* Loop over index attributes. */ - for (j = 0; j < r->rd_att->natts; j++) + for (j = 0; j < IndexRelationGetNumberOfKeyAttributes(r); j++) { Datum datum; float usize; bool IsNull; /* Compute penalty for this column. */ - datum = index_getattr(itup, j + 1, giststate->tupdesc, &IsNull); + datum = index_getattr(itup, j + 1, giststate->leafTupdesc, + &IsNull); gistdentryinit(giststate, j, &entry, datum, r, p, i, false, IsNull); usize = gistpenalty(giststate, j, &entry, IsNull, @@ -470,7 +473,7 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ result = i; best_penalty[j] = usize; - if (j < r->rd_att->natts - 1) + if (j < IndexRelationGetNumberOfKeyAttributes(r) - 1) best_penalty[j + 1] = -1; /* we have new best, so reset keep-it decision */ @@ -500,7 +503,7 @@ gistchoose(Relation r, Page p, IndexTuple it, /* it has compressed entry */ * If we looped past the last column, and did not update "result", * then this tuple is exactly as good as the prior best tuple. */ - if (j == r->rd_att->natts && result != i) + if (j == IndexRelationGetNumberOfKeyAttributes(r) && result != i) { if (keep_current_best == -1) { @@ -579,7 +582,7 @@ gistFormTuple(GISTSTATE *giststate, Relation r, /* * Call the compress method on each attribute. */ - for (i = 0; i < r->rd_att->natts; i++) + for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(r); i++) { if (isnull[i]) compatt[i] = (Datum) 0; @@ -602,7 +605,23 @@ gistFormTuple(GISTSTATE *giststate, Relation r, } } - res = index_form_tuple(giststate->tupdesc, compatt, isnull); + if (isleaf) + { + /* + * Emplace each included attribute if any. + */ + for (; i < r->rd_att->natts; i++) + { + if (isnull[i]) + compatt[i] = (Datum) 0; + else + compatt[i] = attdata[i]; + } + } + + res = index_form_tuple(isleaf ? giststate->leafTupdesc : + giststate->nonLeafTupdesc, + compatt, isnull); /* * The offset number on tuples on internal pages is unused. For historical @@ -644,11 +663,11 @@ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple) bool isnull[INDEX_MAX_KEYS]; int i; - for (i = 0; i < r->rd_att->natts; i++) + for (i = 0; i < IndexRelationGetNumberOfKeyAttributes(r); i++) { Datum datum; - datum = index_getattr(tuple, i + 1, giststate->tupdesc, &isnull[i]); + datum = index_getattr(tuple, i + 1, giststate->leafTupdesc, &isnull[i]); if (giststate->fetchFn[i].fn_oid != InvalidOid) { @@ -679,6 +698,15 @@ gistFetchTuple(GISTSTATE *giststate, Relation r, IndexTuple tuple) fetchatt[i] = (Datum) 0; } } + + /* + * Get each included attribute. + */ + for (; i < r->rd_att->natts; i++) + { + fetchatt[i] = index_getattr(tuple, i + 1, giststate->leafTupdesc, + &isnull[i]); + } MemoryContextSwitchTo(oldcxt); return heap_form_tuple(giststate->fetchTupdesc, fetchatt, isnull); @@ -802,13 +830,31 @@ gistNewBuffer(Relation r) { Page page = BufferGetPage(buffer); + /* + * If the page was never initialized, it's OK to use. + */ if (PageIsNew(page)) - return buffer; /* OK to use, if never initialized */ + return buffer; gistcheckpage(r, buffer); - if (GistPageIsDeleted(page)) - return buffer; /* OK to use */ + /* + * Otherwise, recycle it if deleted, and too old to have any + * processes interested in it. + */ + if (gistPageRecyclable(page)) + { + /* + * If we are generating WAL for Hot Standby then create a WAL + * record that will allow us to conflict with queries running + * on standby, in case they have snapshots older than the + * page's deleteXid. + */ + if (XLogStandbyInfoActive() && RelationNeedsWAL(r)) + gistXLogPageReuse(r, blkno, GistPageGetDeleteXid(page)); + + return buffer; + } LockBuffer(buffer, GIST_UNLOCK); } @@ -832,6 +878,33 @@ gistNewBuffer(Relation r) return buffer; } +/* Can this page be recycled yet? */ +bool +gistPageRecyclable(Page page) +{ + if (PageIsNew(page)) + return true; + if (GistPageIsDeleted(page)) + { + /* + * The page was deleted, but when? If it was just deleted, a scan + * might have seen the downlink to it, and will read the page later. + * As long as that can happen, we must keep the deleted page around as + * a tombstone. + * + * Compare the deletion XID with RecentGlobalXmin. If deleteXid < + * RecentGlobalXmin, then no scan that's still in progress could have + * seen its downlink, and we can recycle it. + */ + FullTransactionId deletexid_full = GistPageGetDeleteXid(page); + FullTransactionId recentxmin_full = GetFullRecentGlobalXmin(); + + if (FullTransactionIdPrecedes(deletexid_full, recentxmin_full)) + return true; + } + return false; +} + bytea * gistoptions(Datum reloptions, bool validate) { @@ -840,7 +913,7 @@ gistoptions(Datum reloptions, bool validate) int numoptions; static const relopt_parse_elt tab[] = { {"fillfactor", RELOPT_TYPE_INT, offsetof(GiSTOptions, fillfactor)}, - {"buffering", RELOPT_TYPE_STRING, offsetof(GiSTOptions, bufferingModeOffset)} + {"buffering", RELOPT_TYPE_ENUM, offsetof(GiSTOptions, buffering_mode)} }; options = parseRelOptions(reloptions, validate, RELOPT_KIND_GIST, @@ -872,12 +945,6 @@ gistproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull) { - HeapTuple tuple; - Form_pg_index rd_index PG_USED_FOR_ASSERTS_ONLY; - Form_pg_opclass rd_opclass; - Datum datum; - bool disnull; - oidvector *indclass; Oid opclass, opfamily, opcintype; @@ -911,41 +978,19 @@ gistproperty(Oid index_oid, int attno, } /* First we need to know the column's opclass. */ - - tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(index_oid)); - if (!HeapTupleIsValid(tuple)) + opclass = get_index_column_opclass(index_oid, attno); + if (!OidIsValid(opclass)) { *isnull = true; return true; } - rd_index = (Form_pg_index) GETSTRUCT(tuple); - - /* caller is supposed to guarantee this */ - Assert(attno > 0 && attno <= rd_index->indnatts); - - datum = SysCacheGetAttr(INDEXRELID, tuple, - Anum_pg_index_indclass, &disnull); - Assert(!disnull); - - indclass = ((oidvector *) DatumGetPointer(datum)); - opclass = indclass->values[attno - 1]; - - ReleaseSysCache(tuple); /* Now look up the opclass family and input datatype. */ - - tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass)); - if (!HeapTupleIsValid(tuple)) + if (!get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype)) { *isnull = true; return true; } - rd_opclass = (Form_pg_opclass) GETSTRUCT(tuple); - - opfamily = rd_opclass->opcfamily; - opcintype = rd_opclass->opcintype; - - ReleaseSysCache(tuple); /* And now we can check whether the function is provided. */ @@ -968,6 +1013,8 @@ gistproperty(Oid index_oid, int attno, Int16GetDatum(GIST_COMPRESS_PROC)); } + *isnull = false; + return true; } @@ -979,7 +1026,7 @@ gistproperty(Oid index_oid, int attno, XLogRecPtr gistGetFakeLSN(Relation rel) { - static XLogRecPtr counter = 1; + static XLogRecPtr counter = FirstNormalUnloggedLSN; if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) { diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 5948218c779..bf754ea6d0d 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -4,7 +4,7 @@ * vacuuming routines for the postgres GiST index access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,259 +16,659 @@ #include "access/genam.h" #include "access/gist_private.h" +#include "access/transam.h" #include "commands/vacuum.h" +#include "lib/integerset.h" #include "miscadmin.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" +#include "utils/memutils.h" +/* + * State kept across vacuum stages. + */ +typedef struct +{ + IndexBulkDeleteResult stats; /* must be first */ + + /* + * These are used to memorize all internal and empty leaf pages in the 1st + * vacuum stage. They are used in the 2nd stage, to delete all the empty + * pages. + */ + IntegerSet *internal_page_set; + IntegerSet *empty_leaf_set; + MemoryContext page_set_context; +} GistBulkDeleteResult; + +/* Working state needed by gistbulkdelete */ +typedef struct +{ + IndexVacuumInfo *info; + GistBulkDeleteResult *stats; + IndexBulkDeleteCallback callback; + void *callback_state; + GistNSN startNSN; +} GistVacState; + +static void gistvacuumscan(IndexVacuumInfo *info, GistBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state); +static void gistvacuumpage(GistVacState *vstate, BlockNumber blkno, + BlockNumber orig_blkno); +static void gistvacuum_delete_empty_pages(IndexVacuumInfo *info, + GistBulkDeleteResult *stats); +static bool gistdeletepage(IndexVacuumInfo *info, GistBulkDeleteResult *stats, + Buffer buffer, OffsetNumber downlink, + Buffer leafBuffer); + +/* allocate the 'stats' struct that's kept over vacuum stages */ +static GistBulkDeleteResult * +create_GistBulkDeleteResult(void) +{ + GistBulkDeleteResult *gist_stats; + + gist_stats = (GistBulkDeleteResult *) palloc0(sizeof(GistBulkDeleteResult)); + gist_stats->page_set_context = + GenerationContextCreate(CurrentMemoryContext, + "GiST VACUUM page set context", + 16 * 1024); + + return gist_stats; +} + +/* + * VACUUM bulkdelete stage: remove index entries. + */ +IndexBulkDeleteResult * +gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + GistBulkDeleteResult *gist_stats = (GistBulkDeleteResult *) stats; + + /* allocate stats if first time through, else re-use existing struct */ + if (gist_stats == NULL) + gist_stats = create_GistBulkDeleteResult(); + + gistvacuumscan(info, gist_stats, callback, callback_state); + + return (IndexBulkDeleteResult *) gist_stats; +} /* - * VACUUM cleanup: update FSM + * VACUUM cleanup stage: delete empty pages, and update index statistics. */ IndexBulkDeleteResult * gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { - Relation rel = info->index; - BlockNumber npages, - blkno; - BlockNumber totFreePages; - double tuplesCount; - bool needLock; + GistBulkDeleteResult *gist_stats = (GistBulkDeleteResult *) stats; /* No-op in ANALYZE ONLY mode */ if (info->analyze_only) return stats; - /* Set up all-zero stats if gistbulkdelete wasn't called */ - if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); + /* + * If gistbulkdelete was called, we need not do anything, just return the + * stats from the latest gistbulkdelete call. If it wasn't called, we + * still need to do a pass over the index, to obtain index statistics. + */ + if (gist_stats == NULL) + { + gist_stats = create_GistBulkDeleteResult(); + gistvacuumscan(info, gist_stats, NULL, NULL); + } /* - * Need lock unless it's local to this backend. + * If we saw any empty pages, try to unlink them from the tree so that + * they can be reused. */ - needLock = !RELATION_IS_LOCAL(rel); + gistvacuum_delete_empty_pages(info, gist_stats); - /* try to find deleted pages */ - if (needLock) - LockRelationForExtension(rel, ExclusiveLock); - npages = RelationGetNumberOfBlocks(rel); - if (needLock) - UnlockRelationForExtension(rel, ExclusiveLock); + /* we don't need the internal and empty page sets anymore */ + MemoryContextDelete(gist_stats->page_set_context); + gist_stats->page_set_context = NULL; + gist_stats->internal_page_set = NULL; + gist_stats->empty_leaf_set = NULL; - totFreePages = 0; - tuplesCount = 0; - for (blkno = GIST_ROOT_BLKNO + 1; blkno < npages; blkno++) + /* + * It's quite possible for us to be fooled by concurrent page splits into + * double-counting some index tuples, so disbelieve any total that exceeds + * the underlying heap's count ... if we know that accurately. Otherwise + * this might just make matters worse. + */ + if (!info->estimated_count) { - Buffer buffer; - Page page; + if (gist_stats->stats.num_index_tuples > info->num_heap_tuples) + gist_stats->stats.num_index_tuples = info->num_heap_tuples; + } - vacuum_delay_point(); + return (IndexBulkDeleteResult *) gist_stats; +} - buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, - info->strategy); - LockBuffer(buffer, GIST_SHARE); - page = (Page) BufferGetPage(buffer); +/* + * gistvacuumscan --- scan the index for VACUUMing purposes + * + * This scans the index for leaf tuples that are deletable according to the + * vacuum callback, and updates the stats. Both btbulkdelete and + * btvacuumcleanup invoke this (the latter only if no btbulkdelete call + * occurred). + * + * This also makes note of any empty leaf pages, as well as all internal + * pages. The second stage, gistvacuum_delete_empty_pages(), needs that + * information. Any deleted pages are added directly to the free space map. + * (They should've been added there when they were originally deleted, already, + * but it's possible that the FSM was lost at a crash, for example.) + * + * The caller is responsible for initially allocating/zeroing a stats struct. + */ +static void +gistvacuumscan(IndexVacuumInfo *info, GistBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + Relation rel = info->index; + GistVacState vstate; + BlockNumber num_pages; + bool needLock; + BlockNumber blkno; + + /* + * Reset counts that will be incremented during the scan; needed in case + * of multiple scans during a single VACUUM command. + */ + stats->stats.estimated_count = false; + stats->stats.num_index_tuples = 0; + stats->stats.pages_deleted = 0; + stats->stats.pages_free = 0; + MemoryContextReset(stats->page_set_context); + stats->internal_page_set = intset_create(); + stats->empty_leaf_set = intset_create(); + + /* Set up info to pass down to gistvacuumpage */ + vstate.info = info; + vstate.stats = stats; + vstate.callback = callback; + vstate.callback_state = callback_state; + if (RelationNeedsWAL(rel)) + vstate.startNSN = GetInsertRecPtr(); + else + vstate.startNSN = gistGetFakeLSN(rel); + + /* + * The outer loop iterates over all index pages, in physical order (we + * hope the kernel will cooperate in providing read-ahead for speed). It + * is critical that we visit all leaf pages, including ones added after we + * start the scan, else we might fail to delete some deletable tuples. + * Hence, we must repeatedly check the relation length. We must acquire + * the relation-extension lock while doing so to avoid a race condition: + * if someone else is extending the relation, there is a window where + * bufmgr/smgr have created a new all-zero page but it hasn't yet been + * write-locked by gistNewBuffer(). If we manage to scan such a page + * here, we'll improperly assume it can be recycled. Taking the lock + * synchronizes things enough to prevent a problem: either num_pages won't + * include the new page, or gistNewBuffer already has write lock on the + * buffer and it will be fully initialized before we can examine it. (See + * also vacuumlazy.c, which has the same issue.) Also, we need not worry + * if a page is added immediately after we look; the page splitting code + * already has write-lock on the left page before it adds a right page, so + * we must already have processed any tuples due to be moved into such a + * page. + * + * We can skip locking for new or temp relations, however, since no one + * else could be accessing them. + */ + needLock = !RELATION_IS_LOCAL(rel); + + blkno = GIST_ROOT_BLKNO; + for (;;) + { + /* Get the current relation length */ + if (needLock) + LockRelationForExtension(rel, ExclusiveLock); + num_pages = RelationGetNumberOfBlocks(rel); + if (needLock) + UnlockRelationForExtension(rel, ExclusiveLock); + + /* Quit if we've scanned the whole relation */ + if (blkno >= num_pages) + break; + /* Iterate over pages, then loop back to recheck length */ + for (; blkno < num_pages; blkno++) + gistvacuumpage(&vstate, blkno, blkno); + } - if (PageIsNew(page) || GistPageIsDeleted(page)) + /* + * If we found any recyclable pages (and recorded them in the FSM), then + * forcibly update the upper-level FSM pages to ensure that searchers can + * find them. It's possible that the pages were also found during + * previous scans and so this is a waste of time, but it's cheap enough + * relative to scanning the index that it shouldn't matter much, and + * making sure that free pages are available sooner not later seems + * worthwhile. + * + * Note that if no recyclable pages exist, we don't bother vacuuming the + * FSM at all. + */ + if (stats->stats.pages_free > 0) + IndexFreeSpaceMapVacuum(rel); + + /* update statistics */ + stats->stats.num_pages = num_pages; +} + +/* + * gistvacuumpage --- VACUUM one page + * + * This processes a single page for gistbulkdelete(). In some cases we + * must go back and re-examine previously-scanned pages; this routine + * recurses when necessary to handle that case. + * + * blkno is the page to process. orig_blkno is the highest block number + * reached by the outer gistvacuumscan loop (the same as blkno, unless we + * are recursing to re-examine a previous page). + */ +static void +gistvacuumpage(GistVacState *vstate, BlockNumber blkno, BlockNumber orig_blkno) +{ + GistBulkDeleteResult *stats = vstate->stats; + IndexVacuumInfo *info = vstate->info; + IndexBulkDeleteCallback callback = vstate->callback; + void *callback_state = vstate->callback_state; + Relation rel = info->index; + Buffer buffer; + Page page; + BlockNumber recurse_to; + +restart: + recurse_to = InvalidBlockNumber; + + /* call vacuum_delay_point while not holding any buffer lock */ + vacuum_delay_point(); + + buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, + info->strategy); + + /* + * We are not going to stay here for a long time, aggressively grab an + * exclusive lock. + */ + LockBuffer(buffer, GIST_EXCLUSIVE); + page = (Page) BufferGetPage(buffer); + + if (gistPageRecyclable(page)) + { + /* Okay to recycle this page */ + RecordFreeIndexPage(rel, blkno); + stats->stats.pages_free++; + stats->stats.pages_deleted++; + } + else if (GistPageIsDeleted(page)) + { + /* Already deleted, but can't recycle yet */ + stats->stats.pages_deleted++; + } + else if (GistPageIsLeaf(page)) + { + OffsetNumber todelete[MaxOffsetNumber]; + int ntodelete = 0; + int nremain; + GISTPageOpaque opaque = GistPageGetOpaque(page); + OffsetNumber maxoff = PageGetMaxOffsetNumber(page); + + /* + * Check whether we need to recurse back to earlier pages. What we + * are concerned about is a page split that happened since we started + * the vacuum scan. If the split moved some tuples to a lower page + * then we might have missed 'em. If so, set up for tail recursion. + * + * This is similar to the checks we do during searches, when following + * a downlink, but we don't need to jump to higher-numbered pages, + * because we will process them later, anyway. + */ + if ((GistFollowRight(page) || + vstate->startNSN < GistPageGetNSN(page)) && + (opaque->rightlink != InvalidBlockNumber) && + (opaque->rightlink < orig_blkno)) { - totFreePages++; - RecordFreeIndexPage(rel, blkno); + recurse_to = opaque->rightlink; } - else if (GistPageIsLeaf(page)) + + /* + * Scan over all items to see which ones need to be deleted according + * to the callback function. + */ + if (callback) { - /* count tuples in index (considering only leaf tuples) */ - tuplesCount += PageGetMaxOffsetNumber(page); + OffsetNumber off; + + for (off = FirstOffsetNumber; + off <= maxoff; + off = OffsetNumberNext(off)) + { + ItemId iid = PageGetItemId(page, off); + IndexTuple idxtuple = (IndexTuple) PageGetItem(page, iid); + + if (callback(&(idxtuple->t_tid), callback_state)) + todelete[ntodelete++] = off; + } } - UnlockReleaseBuffer(buffer); - } - /* Finally, vacuum the FSM */ - IndexFreeSpaceMapVacuum(info->index); + /* + * Apply any needed deletes. We issue just one WAL record per page, + * so as to minimize WAL traffic. + */ + if (ntodelete > 0) + { + START_CRIT_SECTION(); - /* return statistics */ - stats->pages_free = totFreePages; - if (needLock) - LockRelationForExtension(rel, ExclusiveLock); - stats->num_pages = RelationGetNumberOfBlocks(rel); - if (needLock) - UnlockRelationForExtension(rel, ExclusiveLock); - stats->num_index_tuples = tuplesCount; - stats->estimated_count = false; + MarkBufferDirty(buffer); - return stats; -} + PageIndexMultiDelete(page, todelete, ntodelete); + GistMarkTuplesDeleted(page); -typedef struct GistBDItem -{ - GistNSN parentlsn; - BlockNumber blkno; - struct GistBDItem *next; -} GistBDItem; + if (RelationNeedsWAL(rel)) + { + XLogRecPtr recptr; -static void -pushStackIfSplited(Page page, GistBDItem *stack) -{ - GISTPageOpaque opaque = GistPageGetOpaque(page); + recptr = gistXLogUpdate(buffer, + todelete, ntodelete, + NULL, 0, InvalidBuffer); + PageSetLSN(page, recptr); + } + else + PageSetLSN(page, gistGetFakeLSN(rel)); - if (stack->blkno != GIST_ROOT_BLKNO && !XLogRecPtrIsInvalid(stack->parentlsn) && - (GistFollowRight(page) || stack->parentlsn < GistPageGetNSN(page)) && - opaque->rightlink != InvalidBlockNumber /* sanity check */ ) + END_CRIT_SECTION(); + + stats->stats.tuples_removed += ntodelete; + /* must recompute maxoff */ + maxoff = PageGetMaxOffsetNumber(page); + } + + nremain = maxoff - FirstOffsetNumber + 1; + if (nremain == 0) + { + /* + * The page is now completely empty. Remember its block number, + * so that we will try to delete the page in the second stage. + * + * Skip this when recursing, because IntegerSet requires that the + * values are added in ascending order. The next VACUUM will pick + * it up. + */ + if (blkno == orig_blkno) + intset_add_member(stats->empty_leaf_set, blkno); + } + else + stats->stats.num_index_tuples += nremain; + } + else { - /* split page detected, install right link to the stack */ + /* + * On an internal page, check for "invalid tuples", left behind by an + * incomplete page split on PostgreSQL 9.0 or below. These are not + * created by newer PostgreSQL versions, but unfortunately, there is + * no version number anywhere in a GiST index, so we don't know + * whether this index might still contain invalid tuples or not. + */ + OffsetNumber maxoff = PageGetMaxOffsetNumber(page); + OffsetNumber off; + + for (off = FirstOffsetNumber; + off <= maxoff; + off = OffsetNumberNext(off)) + { + ItemId iid = PageGetItemId(page, off); + IndexTuple idxtuple = (IndexTuple) PageGetItem(page, iid); + + if (GistTupleIsInvalid(idxtuple)) + ereport(LOG, + (errmsg("index \"%s\" contains an inner tuple marked as invalid", + RelationGetRelationName(rel)), + errdetail("This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."), + errhint("Please REINDEX it."))); + } + + /* + * Remember the block number of this page, so that we can revisit it + * later in gistvacuum_delete_empty_pages(), when we search for + * parents of empty leaf pages. + */ + if (blkno == orig_blkno) + intset_add_member(stats->internal_page_set, blkno); + } - GistBDItem *ptr = (GistBDItem *) palloc(sizeof(GistBDItem)); + UnlockReleaseBuffer(buffer); - ptr->blkno = opaque->rightlink; - ptr->parentlsn = stack->parentlsn; - ptr->next = stack->next; - stack->next = ptr; + /* + * This is really tail recursion, but if the compiler is too stupid to + * optimize it as such, we'd eat an uncomfortably large amount of stack + * space per recursion level (due to the deletable[] array). A failure is + * improbable since the number of levels isn't likely to be large ... but + * just in case, let's hand-optimize into a loop. + */ + if (recurse_to != InvalidBlockNumber) + { + blkno = recurse_to; + goto restart; } } - /* - * Bulk deletion of all index entries pointing to a set of heap tuples and - * check invalid tuples left after upgrade. - * The set of target tuples is specified via a callback routine that tells - * whether any given heap tuple (identified by ItemPointer) is being deleted. - * - * Result: a palloc'd struct containing statistical info for VACUUM displays. + * Scan all internal pages, and try to delete their empty child pages. */ -IndexBulkDeleteResult * -gistbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state) +static void +gistvacuum_delete_empty_pages(IndexVacuumInfo *info, GistBulkDeleteResult *stats) { Relation rel = info->index; - GistBDItem *stack, - *ptr; - - /* first time through? */ - if (stats == NULL) - stats = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult)); - /* we'll re-count the tuples each time */ - stats->estimated_count = false; - stats->num_index_tuples = 0; - - stack = (GistBDItem *) palloc0(sizeof(GistBDItem)); - stack->blkno = GIST_ROOT_BLKNO; + BlockNumber empty_pages_remaining; + uint64 blkno; - while (stack) + /* + * Rescan all inner pages to find those that have empty child pages. + */ + empty_pages_remaining = intset_num_entries(stats->empty_leaf_set); + intset_begin_iterate(stats->internal_page_set); + while (empty_pages_remaining > 0 && + intset_iterate_next(stats->internal_page_set, &blkno)) { Buffer buffer; Page page; - OffsetNumber i, + OffsetNumber off, maxoff; - IndexTuple idxtuple; - ItemId iid; + OffsetNumber todelete[MaxOffsetNumber]; + BlockNumber leafs_to_delete[MaxOffsetNumber]; + int ntodelete; + int deleted; - buffer = ReadBufferExtended(rel, MAIN_FORKNUM, stack->blkno, + buffer = ReadBufferExtended(rel, MAIN_FORKNUM, (BlockNumber) blkno, RBM_NORMAL, info->strategy); + LockBuffer(buffer, GIST_SHARE); - gistcheckpage(rel, buffer); page = (Page) BufferGetPage(buffer); - if (GistPageIsLeaf(page)) + if (PageIsNew(page) || GistPageIsDeleted(page) || GistPageIsLeaf(page)) { - OffsetNumber todelete[MaxOffsetNumber]; - int ntodelete = 0; + /* + * This page was an internal page earlier, but now it's something + * else. Shouldn't happen... + */ + Assert(false); + UnlockReleaseBuffer(buffer); + continue; + } - LockBuffer(buffer, GIST_UNLOCK); - LockBuffer(buffer, GIST_EXCLUSIVE); + /* + * Scan all the downlinks, and see if any of them point to empty leaf + * pages. + */ + maxoff = PageGetMaxOffsetNumber(page); + ntodelete = 0; + for (off = FirstOffsetNumber; + off <= maxoff && ntodelete < maxoff - 1; + off = OffsetNumberNext(off)) + { + ItemId iid = PageGetItemId(page, off); + IndexTuple idxtuple = (IndexTuple) PageGetItem(page, iid); + BlockNumber leafblk; - page = (Page) BufferGetPage(buffer); - if (stack->blkno == GIST_ROOT_BLKNO && !GistPageIsLeaf(page)) + leafblk = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); + if (intset_is_member(stats->empty_leaf_set, leafblk)) { - /* only the root can become non-leaf during relock */ - UnlockReleaseBuffer(buffer); - /* one more check */ - continue; + leafs_to_delete[ntodelete] = leafblk; + todelete[ntodelete++] = off; } + } - /* - * check for split proceeded after look at parent, we should check - * it after relock - */ - pushStackIfSplited(page, stack); + /* + * In order to avoid deadlock, child page must be locked before + * parent, so we must release the lock on the parent, lock the child, + * and then re-acquire the lock the parent. (And we wouldn't want to + * do I/O, while holding a lock, anyway.) + * + * At the instant that we're not holding a lock on the parent, the + * downlink might get moved by a concurrent insert, so we must + * re-check that it still points to the same child page after we have + * acquired both locks. Also, another backend might have inserted a + * tuple to the page, so that it is no longer empty. gistdeletepage() + * re-checks all these conditions. + */ + LockBuffer(buffer, GIST_UNLOCK); + + deleted = 0; + for (int i = 0; i < ntodelete; i++) + { + Buffer leafbuf; /* - * Remove deletable tuples from page + * Don't remove the last downlink from the parent. That would + * confuse the insertion code. */ + if (PageGetMaxOffsetNumber(page) == FirstOffsetNumber) + break; - maxoff = PageGetMaxOffsetNumber(page); + leafbuf = ReadBufferExtended(rel, MAIN_FORKNUM, leafs_to_delete[i], + RBM_NORMAL, info->strategy); + LockBuffer(leafbuf, GIST_EXCLUSIVE); + gistcheckpage(rel, leafbuf); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - iid = PageGetItemId(page, i); - idxtuple = (IndexTuple) PageGetItem(page, iid); + LockBuffer(buffer, GIST_EXCLUSIVE); + if (gistdeletepage(info, stats, + buffer, todelete[i] - deleted, + leafbuf)) + deleted++; + LockBuffer(buffer, GIST_UNLOCK); - if (callback(&(idxtuple->t_tid), callback_state)) - todelete[ntodelete++] = i; - else - stats->num_index_tuples += 1; - } + UnlockReleaseBuffer(leafbuf); + } - stats->tuples_removed += ntodelete; + ReleaseBuffer(buffer); - if (ntodelete) - { - START_CRIT_SECTION(); + /* update stats */ + stats->stats.pages_removed += deleted; - MarkBufferDirty(buffer); + /* + * We can stop the scan as soon as we have seen the downlinks, even if + * we were not able to remove them all. + */ + empty_pages_remaining -= ntodelete; + } +} - PageIndexMultiDelete(page, todelete, ntodelete); - GistMarkTuplesDeleted(page); +/* + * gistdeletepage takes a leaf page, and its parent, and tries to delete the + * leaf. Both pages must be locked. + * + * Even if the page was empty when we first saw it, a concurrent inserter might + * have added a tuple to it since. Similarly, the downlink might have moved. + * We re-check all the conditions, to make sure the page is still deletable, + * before modifying anything. + * + * Returns true, if the page was deleted, and false if a concurrent update + * prevented it. + */ +static bool +gistdeletepage(IndexVacuumInfo *info, GistBulkDeleteResult *stats, + Buffer parentBuffer, OffsetNumber downlink, + Buffer leafBuffer) +{ + Page parentPage = BufferGetPage(parentBuffer); + Page leafPage = BufferGetPage(leafBuffer); + ItemId iid; + IndexTuple idxtuple; + XLogRecPtr recptr; + FullTransactionId txid; - if (RelationNeedsWAL(rel)) - { - XLogRecPtr recptr; + /* + * Check that the leaf is still empty and deletable. + */ + if (!GistPageIsLeaf(leafPage)) + { + /* a leaf page should never become a non-leaf page */ + Assert(false); + return false; + } - recptr = gistXLogUpdate(buffer, - todelete, ntodelete, - NULL, 0, InvalidBuffer); - PageSetLSN(page, recptr); - } - else - PageSetLSN(page, gistGetFakeLSN(rel)); + if (GistFollowRight(leafPage)) + return false; /* don't mess with a concurrent page split */ - END_CRIT_SECTION(); - } + if (PageGetMaxOffsetNumber(leafPage) != InvalidOffsetNumber) + return false; /* not empty anymore */ - } - else - { - /* check for split proceeded after look at parent */ - pushStackIfSplited(page, stack); + /* + * Ok, the leaf is deletable. Is the downlink in the parent page still + * valid? It might have been moved by a concurrent insert. We could try + * to re-find it by scanning the page again, possibly moving right if the + * was split. But for now, let's keep it simple and just give up. The + * next VACUUM will pick it up. + */ + if (PageIsNew(parentPage) || GistPageIsDeleted(parentPage) || + GistPageIsLeaf(parentPage)) + { + /* shouldn't happen, internal pages are never deleted */ + Assert(false); + return false; + } - maxoff = PageGetMaxOffsetNumber(page); + if (PageGetMaxOffsetNumber(parentPage) < downlink + || PageGetMaxOffsetNumber(parentPage) <= FirstOffsetNumber) + return false; - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - iid = PageGetItemId(page, i); - idxtuple = (IndexTuple) PageGetItem(page, iid); - - ptr = (GistBDItem *) palloc(sizeof(GistBDItem)); - ptr->blkno = ItemPointerGetBlockNumber(&(idxtuple->t_tid)); - ptr->parentlsn = BufferGetLSNAtomic(buffer); - ptr->next = stack->next; - stack->next = ptr; - - if (GistTupleIsInvalid(idxtuple)) - ereport(LOG, - (errmsg("index \"%s\" contains an inner tuple marked as invalid", - RelationGetRelationName(rel)), - errdetail("This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1."), - errhint("Please REINDEX it."))); - } - } + iid = PageGetItemId(parentPage, downlink); + idxtuple = (IndexTuple) PageGetItem(parentPage, iid); + if (BufferGetBlockNumber(leafBuffer) != + ItemPointerGetBlockNumber(&(idxtuple->t_tid))) + return false; + + /* + * All good, proceed with the deletion. + * + * The page cannot be immediately recycled, because in-progress scans that + * saw the downlink might still visit it. Mark the page with the current + * next-XID counter, so that we know when it can be recycled. Once that + * XID becomes older than GlobalXmin, we know that all scans that are + * currently in progress must have ended. (That's much more conservative + * than needed, but let's keep it safe and simple.) + */ + txid = ReadNextFullTransactionId(); - UnlockReleaseBuffer(buffer); + START_CRIT_SECTION(); - ptr = stack->next; - pfree(stack); - stack = ptr; + /* mark the page as deleted */ + MarkBufferDirty(leafBuffer); + GistPageSetDeleted(leafPage, txid); + stats->stats.pages_deleted++; - vacuum_delay_point(); - } + /* remove the downlink from the parent */ + MarkBufferDirty(parentBuffer); + PageIndexTupleDelete(parentPage, downlink); + + if (RelationNeedsWAL(info->index)) + recptr = gistXLogPageDelete(leafBuffer, txid, parentBuffer, downlink); + else + recptr = gistGetFakeLSN(info->index); + PageSetLSN(parentPage, recptr); + PageSetLSN(leafPage, recptr); + + END_CRIT_SECTION(); - return stats; + return true; } diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c index dd87dad386a..dfc1a87a757 100644 --- a/src/backend/access/gist/gistvalidate.c +++ b/src/backend/access/gist/gistvalidate.c @@ -3,7 +3,7 @@ * gistvalidate.c * Opclass validator for GiST. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -90,7 +90,7 @@ gistvalidate(Oid opclassoid) { ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types", + errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types", opfamilyname, "gist", format_procedure(procform->amproc)))); result = false; diff --git a/src/backend/access/gist/gistxlog.c b/src/backend/access/gist/gistxlog.c index 1e091269785..3b28f546465 100644 --- a/src/backend/access/gist/gistxlog.c +++ b/src/backend/access/gist/gistxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for GiST. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,9 +16,14 @@ #include "access/bufmask.h" #include "access/gist_private.h" #include "access/gistxlog.h" +#include "access/heapam_xlog.h" +#include "access/transam.h" #include "access/xloginsert.h" #include "access/xlogutils.h" +#include "miscadmin.h" +#include "storage/procarray.h" #include "utils/memutils.h" +#include "utils/rel.h" static MemoryContext opCtx; /* working memory for operations */ @@ -160,6 +165,63 @@ gistRedoPageUpdateRecord(XLogReaderState *record) UnlockReleaseBuffer(buffer); } + +/* + * redo delete on gist index page to remove tuples marked as DEAD during index + * tuple insertion + */ +static void +gistRedoDeleteRecord(XLogReaderState *record) +{ + XLogRecPtr lsn = record->EndRecPtr; + gistxlogDelete *xldata = (gistxlogDelete *) XLogRecGetData(record); + Buffer buffer; + Page page; + + /* + * If we have any conflict processing to do, it must happen before we + * update the page. + * + * GiST delete records can conflict with standby queries. You might think + * that vacuum records would conflict as well, but we've handled that + * already. XLOG_HEAP2_CLEANUP_INFO records provide the highest xid + * cleaned by the vacuum of the heap and so we can resolve any conflicts + * just once when that arrives. After that we know that no conflicts + * exist from individual gist vacuum records on that index. + */ + if (InHotStandby) + { + RelFileNode rnode; + + XLogRecGetBlockTag(record, 0, &rnode, NULL, NULL); + + ResolveRecoveryConflictWithSnapshot(xldata->latestRemovedXid, rnode); + } + + if (XLogReadBufferForRedo(record, 0, &buffer) == BLK_NEEDS_REDO) + { + page = (Page) BufferGetPage(buffer); + + if (XLogRecGetDataLen(record) > SizeOfGistxlogDelete) + { + OffsetNumber *todelete; + + todelete = (OffsetNumber *) ((char *) xldata + SizeOfGistxlogDelete); + + PageIndexMultiDelete(page, todelete, xldata->ntodelete); + } + + GistClearPageHasGarbage(page); + GistMarkTuplesDeleted(page); + + PageSetLSN(page, lsn); + MarkBufferDirty(buffer); + } + + if (BufferIsValid(buffer)) + UnlockReleaseBuffer(buffer); +} + /* * Returns an array of index pointers. */ @@ -281,23 +343,80 @@ gistRedoPageSplitRecord(XLogReaderState *record) UnlockReleaseBuffer(firstbuffer); } +/* redo page deletion */ static void -gistRedoCreateIndex(XLogReaderState *record) +gistRedoPageDelete(XLogReaderState *record) { XLogRecPtr lsn = record->EndRecPtr; - Buffer buffer; - Page page; + gistxlogPageDelete *xldata = (gistxlogPageDelete *) XLogRecGetData(record); + Buffer parentBuffer; + Buffer leafBuffer; + + if (XLogReadBufferForRedo(record, 0, &leafBuffer) == BLK_NEEDS_REDO) + { + Page page = (Page) BufferGetPage(leafBuffer); + + GistPageSetDeleted(page, xldata->deleteXid); + + PageSetLSN(page, lsn); + MarkBufferDirty(leafBuffer); + } + + if (XLogReadBufferForRedo(record, 1, &parentBuffer) == BLK_NEEDS_REDO) + { + Page page = (Page) BufferGetPage(parentBuffer); + + PageIndexTupleDelete(page, xldata->downlinkOffset); + + PageSetLSN(page, lsn); + MarkBufferDirty(parentBuffer); + } - buffer = XLogInitBufferForRedo(record, 0); - Assert(BufferGetBlockNumber(buffer) == GIST_ROOT_BLKNO); - page = (Page) BufferGetPage(buffer); + if (BufferIsValid(parentBuffer)) + UnlockReleaseBuffer(parentBuffer); + if (BufferIsValid(leafBuffer)) + UnlockReleaseBuffer(leafBuffer); +} - GISTInitBuffer(buffer, F_LEAF); +static void +gistRedoPageReuse(XLogReaderState *record) +{ + gistxlogPageReuse *xlrec = (gistxlogPageReuse *) XLogRecGetData(record); + + /* + * PAGE_REUSE records exist to provide a conflict point when we reuse + * pages in the index via the FSM. That's all they do though. + * + * latestRemovedXid was the page's deleteXid. The deleteXid < + * RecentGlobalXmin test in gistPageRecyclable() conceptually mirrors the + * pgxact->xmin > limitXmin test in GetConflictingVirtualXIDs(). + * Consequently, one XID value achieves the same exclusion effect on + * master and standby. + */ + if (InHotStandby) + { + FullTransactionId latestRemovedFullXid = xlrec->latestRemovedFullXid; + FullTransactionId nextFullXid = ReadNextFullTransactionId(); + uint64 diff; - PageSetLSN(page, lsn); + /* + * ResolveRecoveryConflictWithSnapshot operates on 32-bit + * TransactionIds, so truncate the logged FullTransactionId. If the + * logged value is very old, so that XID wrap-around already happened + * on it, there can't be any snapshots that still see it. + */ + nextFullXid = ReadNextFullTransactionId(); + diff = U64FromFullTransactionId(nextFullXid) - + U64FromFullTransactionId(latestRemovedFullXid); + if (diff < MaxTransactionId / 2) + { + TransactionId latestRemovedXid; - MarkBufferDirty(buffer); - UnlockReleaseBuffer(buffer); + latestRemovedXid = XidFromFullTransactionId(latestRemovedFullXid); + ResolveRecoveryConflictWithSnapshot(latestRemovedXid, + xlrec->node); + } + } } void @@ -318,11 +437,17 @@ gist_redo(XLogReaderState *record) case XLOG_GIST_PAGE_UPDATE: gistRedoPageUpdateRecord(record); break; + case XLOG_GIST_DELETE: + gistRedoDeleteRecord(record); + break; + case XLOG_GIST_PAGE_REUSE: + gistRedoPageReuse(record); + break; case XLOG_GIST_PAGE_SPLIT: gistRedoPageSplitRecord(record); break; - case XLOG_GIST_CREATE_INDEX: - gistRedoCreateIndex(record); + case XLOG_GIST_PAGE_DELETE: + gistRedoPageDelete(record); break; default: elog(PANIC, "gist_redo: unknown op code %u", info); @@ -442,6 +567,56 @@ gistXLogSplit(bool page_is_leaf, return recptr; } +/* + * Write XLOG record describing a page deletion. This also includes removal of + * downlink from the parent page. + */ +XLogRecPtr +gistXLogPageDelete(Buffer buffer, FullTransactionId xid, + Buffer parentBuffer, OffsetNumber downlinkOffset) +{ + gistxlogPageDelete xlrec; + XLogRecPtr recptr; + + xlrec.deleteXid = xid; + xlrec.downlinkOffset = downlinkOffset; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec, SizeOfGistxlogPageDelete); + + XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + XLogRegisterBuffer(1, parentBuffer, REGBUF_STANDARD); + + recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_PAGE_DELETE); + + return recptr; +} + +/* + * Write XLOG record about reuse of a deleted page. + */ +void +gistXLogPageReuse(Relation rel, BlockNumber blkno, FullTransactionId latestRemovedXid) +{ + gistxlogPageReuse xlrec_reuse; + + /* + * Note that we don't register the buffer with the record, because this + * operation doesn't modify the page. This record only exists to provide a + * conflict point for Hot Standby. + */ + + /* XLOG stuff */ + xlrec_reuse.node = rel->rd_node; + xlrec_reuse.block = blkno; + xlrec_reuse.latestRemovedFullXid = latestRemovedXid; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec_reuse, SizeOfGistxlogPageReuse); + + XLogInsert(RM_GIST_ID, XLOG_GIST_PAGE_REUSE); +} + /* * Write XLOG record describing a page update. The update can include any * number of deletions and/or insertions of tuples on a single index page. @@ -487,3 +662,35 @@ gistXLogUpdate(Buffer buffer, return recptr; } + +/* + * Write XLOG record describing a delete of leaf index tuples marked as DEAD + * during new tuple insertion. One may think that this case is already covered + * by gistXLogUpdate(). But deletion of index tuples might conflict with + * standby queries and needs special handling. + */ +XLogRecPtr +gistXLogDelete(Buffer buffer, OffsetNumber *todelete, int ntodelete, + TransactionId latestRemovedXid) +{ + gistxlogDelete xlrec; + XLogRecPtr recptr; + + xlrec.latestRemovedXid = latestRemovedXid; + xlrec.ntodelete = ntodelete; + + XLogBeginInsert(); + XLogRegisterData((char *) &xlrec, SizeOfGistxlogDelete); + + /* + * We need the target-offsets array whether or not we store the whole + * buffer, to allow us to find the latestRemovedXid on a standby server. + */ + XLogRegisterData((char *) todelete, ntodelete * sizeof(OffsetNumber)); + + XLogRegisterBuffer(0, buffer, REGBUF_STANDARD); + + recptr = XLogInsert(RM_GIST_ID, XLOG_GIST_DELETE); + + return recptr; +} diff --git a/src/backend/access/hash/README b/src/backend/access/hash/README index 21b4a82b0b0..2227ebfe9b2 100644 --- a/src/backend/access/hash/README +++ b/src/backend/access/hash/README @@ -173,7 +173,7 @@ where a given tuple ought to be located. To do this, we need the bucket count, highmask, and lowmask from the metapage; however, it's undesirable for performance reasons to have to have to lock and pin the metapage for every such operation. Instead, we retain a cached copy of the metapage -in each each backend's relcache entry. This will produce the correct +in each backend's relcache entry. This will produce the correct bucket mapping as long as the target bucket hasn't been split since the last cache refresh. diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 0002df30c0d..5cc30dac429 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -3,7 +3,7 @@ * hash.c * Implementation of Margo Seltzer's Hashing package for postgres. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,10 +21,13 @@ #include "access/hash.h" #include "access/hash_xlog.h" #include "access/relscan.h" +#include "access/tableam.h" #include "catalog/index.h" +#include "commands/progress.h" #include "commands/vacuum.h" #include "miscadmin.h" #include "optimizer/plancat.h" +#include "pgstat.h" #include "utils/builtins.h" #include "utils/index_selfuncs.h" #include "utils/rel.h" @@ -40,11 +43,11 @@ typedef struct } HashBuildState; static void hashbuildCallback(Relation index, - HeapTuple htup, - Datum *values, - bool *isnull, - bool tupleIsAlive, - void *state); + HeapTuple htup, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state); /* @@ -82,6 +85,7 @@ hashhandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = hashcostestimate; amroutine->amoptions = hashoptions; amroutine->amproperty = NULL; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = hashvalidate; amroutine->ambeginscan = hashbeginscan; amroutine->amrescan = hashrescan; @@ -159,8 +163,11 @@ hashbuild(Relation heap, Relation index, IndexInfo *indexInfo) buildstate.heapRel = heap; /* do the heap scan */ - reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, - hashbuildCallback, (void *) &buildstate, NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + hashbuildCallback, + (void *) &buildstate, NULL); + pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_TOTAL, + buildstate.indtuples); if (buildstate.spool) { @@ -190,7 +197,7 @@ hashbuildempty(Relation index) } /* - * Per-tuple callback from IndexBuildHeapScan + * Per-tuple callback for table_index_build_scan */ static void hashbuildCallback(Relation index, @@ -333,7 +340,7 @@ hashgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) /* * _hash_first and _hash_next handle eliminate dead index entries - * whenever scan->ignored_killed_tuples is true. Therefore, there's + * whenever scan->ignore_killed_tuples is true. Therefore, there's * nothing to do here except add the results to the TIDBitmap. */ tbm_add_tuples(tbm, &(currItem->heapTid), 1, true); diff --git a/src/backend/access/hash/hash_xlog.c b/src/backend/access/hash/hash_xlog.c index ab5aaff1566..86e7210acb8 100644 --- a/src/backend/access/hash/hash_xlog.c +++ b/src/backend/access/hash/hash_xlog.c @@ -4,7 +4,7 @@ * WAL replay logic for hash index. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,7 +14,6 @@ */ #include "postgres.h" -#include "access/heapam_xlog.h" #include "access/bufmask.h" #include "access/hash.h" #include "access/hash_xlog.h" @@ -707,7 +706,7 @@ hash_xlog_squeeze_page(XLogReaderState *record) /* * if the page on which are adding tuples is a page previous to freed - * overflow page, then update its nextblno. + * overflow page, then update its nextblkno. */ if (xldata->is_prev_bucket_same_wrt) { @@ -969,155 +968,6 @@ hash_xlog_update_meta_page(XLogReaderState *record) UnlockReleaseBuffer(metabuf); } -/* - * Get the latestRemovedXid from the heap pages pointed at by the index - * tuples being deleted. See also btree_xlog_delete_get_latestRemovedXid, - * on which this function is based. - */ -static TransactionId -hash_xlog_vacuum_get_latestRemovedXid(XLogReaderState *record) -{ - xl_hash_vacuum_one_page *xlrec; - OffsetNumber *unused; - Buffer ibuffer, - hbuffer; - Page ipage, - hpage; - RelFileNode rnode; - BlockNumber blkno; - ItemId iitemid, - hitemid; - IndexTuple itup; - HeapTupleHeader htuphdr; - BlockNumber hblkno; - OffsetNumber hoffnum; - TransactionId latestRemovedXid = InvalidTransactionId; - int i; - - xlrec = (xl_hash_vacuum_one_page *) XLogRecGetData(record); - - /* - * If there's nothing running on the standby we don't need to derive a - * full latestRemovedXid value, so use a fast path out of here. This - * returns InvalidTransactionId, and so will conflict with all HS - * transactions; but since we just worked out that that's zero people, - * it's OK. - * - * XXX There is a race condition here, which is that a new backend might - * start just after we look. If so, it cannot need to conflict, but this - * coding will result in throwing a conflict anyway. - */ - if (CountDBBackends(InvalidOid) == 0) - return latestRemovedXid; - - /* - * Check if WAL replay has reached a consistent database state. If not, we - * must PANIC. See the definition of - * btree_xlog_delete_get_latestRemovedXid for more details. - */ - if (!reachedConsistency) - elog(PANIC, "hash_xlog_vacuum_get_latestRemovedXid: cannot operate with inconsistent data"); - - /* - * Get index page. If the DB is consistent, this should not fail, nor - * should any of the heap page fetches below. If one does, we return - * InvalidTransactionId to cancel all HS transactions. That's probably - * overkill, but it's safe, and certainly better than panicking here. - */ - XLogRecGetBlockTag(record, 0, &rnode, NULL, &blkno); - ibuffer = XLogReadBufferExtended(rnode, MAIN_FORKNUM, blkno, RBM_NORMAL); - - if (!BufferIsValid(ibuffer)) - return InvalidTransactionId; - LockBuffer(ibuffer, HASH_READ); - ipage = (Page) BufferGetPage(ibuffer); - - /* - * Loop through the deleted index items to obtain the TransactionId from - * the heap items they point to. - */ - unused = (OffsetNumber *) ((char *) xlrec + SizeOfHashVacuumOnePage); - - for (i = 0; i < xlrec->ntuples; i++) - { - /* - * Identify the index tuple about to be deleted. - */ - iitemid = PageGetItemId(ipage, unused[i]); - itup = (IndexTuple) PageGetItem(ipage, iitemid); - - /* - * Locate the heap page that the index tuple points at - */ - hblkno = ItemPointerGetBlockNumber(&(itup->t_tid)); - hbuffer = XLogReadBufferExtended(xlrec->hnode, MAIN_FORKNUM, - hblkno, RBM_NORMAL); - - if (!BufferIsValid(hbuffer)) - { - UnlockReleaseBuffer(ibuffer); - return InvalidTransactionId; - } - LockBuffer(hbuffer, HASH_READ); - hpage = (Page) BufferGetPage(hbuffer); - - /* - * Look up the heap tuple header that the index tuple points at by - * using the heap node supplied with the xlrec. We can't use - * heap_fetch, since it uses ReadBuffer rather than XLogReadBuffer. - * Note that we are not looking at tuple data here, just headers. - */ - hoffnum = ItemPointerGetOffsetNumber(&(itup->t_tid)); - hitemid = PageGetItemId(hpage, hoffnum); - - /* - * Follow any redirections until we find something useful. - */ - while (ItemIdIsRedirected(hitemid)) - { - hoffnum = ItemIdGetRedirect(hitemid); - hitemid = PageGetItemId(hpage, hoffnum); - CHECK_FOR_INTERRUPTS(); - } - - /* - * If the heap item has storage, then read the header and use that to - * set latestRemovedXid. - * - * Some LP_DEAD items may not be accessible, so we ignore them. - */ - if (ItemIdHasStorage(hitemid)) - { - htuphdr = (HeapTupleHeader) PageGetItem(hpage, hitemid); - HeapTupleHeaderAdvanceLatestRemovedXid(htuphdr, &latestRemovedXid); - } - else if (ItemIdIsDead(hitemid)) - { - /* - * Conjecture: if hitemid is dead then it had xids before the xids - * marked on LP_NORMAL items. So we just ignore this item and move - * onto the next, for the purposes of calculating - * latestRemovedxids. - */ - } - else - Assert(!ItemIdIsUsed(hitemid)); - - UnlockReleaseBuffer(hbuffer); - } - - UnlockReleaseBuffer(ibuffer); - - /* - * If all heap tuples were LP_DEAD then we will be returning - * InvalidTransactionId here, which avoids conflicts. This matches - * existing logic which assumes that LP_DEAD tuples must already be older - * than the latestRemovedXid on the cleanup record that set them as - * LP_DEAD, hence must already have generated a conflict. - */ - return latestRemovedXid; -} - /* * replay delete operation in hash index to remove * tuples marked as DEAD during index tuple insertion. @@ -1149,12 +999,10 @@ hash_xlog_vacuum_one_page(XLogReaderState *record) */ if (InHotStandby) { - TransactionId latestRemovedXid = - hash_xlog_vacuum_get_latestRemovedXid(record); RelFileNode rnode; XLogRecGetBlockTag(record, 0, &rnode, NULL, NULL); - ResolveRecoveryConflictWithSnapshot(latestRemovedXid, rnode); + ResolveRecoveryConflictWithSnapshot(xldata->latestRemovedXid, rnode); } action = XLogReadBufferForRedoExtended(record, 0, RBM_NORMAL, true, &buffer); diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index 1aa0b25d38a..6ec1ec3df3a 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -3,7 +3,7 @@ * hashfunc.c * Support functions for hash access method. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -27,7 +27,10 @@ #include "postgres.h" #include "access/hash.h" +#include "catalog/pg_collation.h" #include "utils/builtins.h" +#include "utils/hashutils.h" +#include "utils/pg_locale.h" /* * Datatype-specific hash functions. @@ -242,15 +245,51 @@ Datum hashtext(PG_FUNCTION_ARGS) { text *key = PG_GETARG_TEXT_PP(0); + Oid collid = PG_GET_COLLATION(); + pg_locale_t mylocale = 0; Datum result; - /* - * Note: this is currently identical in behavior to hashvarlena, but keep - * it as a separate function in case we someday want to do something - * different in non-C locales. (See also hashbpchar, if so.) - */ - result = hash_any((unsigned char *) VARDATA_ANY(key), - VARSIZE_ANY_EXHDR(key)); + if (!collid) + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string hashing"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (!mylocale || mylocale->deterministic) + { + result = hash_any((unsigned char *) VARDATA_ANY(key), + VARSIZE_ANY_EXHDR(key)); + } + else + { +#ifdef USE_ICU + if (mylocale->provider == COLLPROVIDER_ICU) + { + int32_t ulen = -1; + UChar *uchar = NULL; + Size bsize; + uint8_t *buf; + + ulen = icu_to_uchar(&uchar, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); + + bsize = ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, NULL, 0); + buf = palloc(bsize); + ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, buf, bsize); + + result = hash_any(buf, bsize); + + pfree(buf); + } + else +#endif + /* shouldn't happen */ + elog(ERROR, "unsupported collprovider: %c", mylocale->provider); + } /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); @@ -262,12 +301,52 @@ Datum hashtextextended(PG_FUNCTION_ARGS) { text *key = PG_GETARG_TEXT_PP(0); + Oid collid = PG_GET_COLLATION(); + pg_locale_t mylocale = 0; Datum result; - /* Same approach as hashtext */ - result = hash_any_extended((unsigned char *) VARDATA_ANY(key), - VARSIZE_ANY_EXHDR(key), - PG_GETARG_INT64(1)); + if (!collid) + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string hashing"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (!mylocale || mylocale->deterministic) + { + result = hash_any_extended((unsigned char *) VARDATA_ANY(key), + VARSIZE_ANY_EXHDR(key), + PG_GETARG_INT64(1)); + } + else + { +#ifdef USE_ICU + if (mylocale->provider == COLLPROVIDER_ICU) + { + int32_t ulen = -1; + UChar *uchar = NULL; + Size bsize; + uint8_t *buf; + + ulen = icu_to_uchar(&uchar, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); + + bsize = ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, NULL, 0); + buf = palloc(bsize); + ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, buf, bsize); + + result = hash_any_extended(buf, bsize, PG_GETARG_INT64(1)); + + pfree(buf); + } + else +#endif + /* shouldn't happen */ + elog(ERROR, "unsupported collprovider: %c", mylocale->provider); + } PG_FREE_IF_COPY(key, 0); @@ -307,589 +386,3 @@ hashvarlenaextended(PG_FUNCTION_ARGS) return result; } - -/* - * This hash function was written by Bob Jenkins - * (bob_jenkins@burtleburtle.net), and superficially adapted - * for PostgreSQL by Neil Conway. For more information on this - * hash function, see http://burtleburtle.net/bob/hash/doobs.html, - * or Bob's article in Dr. Dobb's Journal, Sept. 1997. - * - * In the current code, we have adopted Bob's 2006 update of his hash - * function to fetch the data a word at a time when it is suitably aligned. - * This makes for a useful speedup, at the cost of having to maintain - * four code paths (aligned vs unaligned, and little-endian vs big-endian). - * It also uses two separate mixing functions mix() and final(), instead - * of a slower multi-purpose function. - */ - -/* Get a bit mask of the bits set in non-uint32 aligned addresses */ -#define UINT32_ALIGN_MASK (sizeof(uint32) - 1) - -/* Rotate a uint32 value left by k bits - note multiple evaluation! */ -#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) - -/*---------- - * mix -- mix 3 32-bit values reversibly. - * - * This is reversible, so any information in (a,b,c) before mix() is - * still in (a,b,c) after mix(). - * - * If four pairs of (a,b,c) inputs are run through mix(), or through - * mix() in reverse, there are at least 32 bits of the output that - * are sometimes the same for one pair and different for another pair. - * This was tested for: - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * This does not achieve avalanche. There are input bits of (a,b,c) - * that fail to affect some output bits of (a,b,c), especially of a. The - * most thoroughly mixed value is c, but it doesn't really even achieve - * avalanche in c. - * - * This allows some parallelism. Read-after-writes are good at doubling - * the number of bits affected, so the goal of mixing pulls in the opposite - * direction from the goal of parallelism. I did what I could. Rotates - * seem to cost as much as shifts on every machine I could lay my hands on, - * and rotates are much kinder to the top and bottom bits, so I used rotates. - *---------- - */ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/*---------- - * final -- final mixing of 3 32-bit values (a,b,c) into c - * - * Pairs of (a,b,c) values differing in only a few bits will usually - * produce values of c that look totally different. This was tested for - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * The use of separate functions for mix() and final() allow for a - * substantial performance increase since final() does not need to - * do well in reverse, but is does need to affect all output bits. - * mix(), on the other hand, does not need to affect all output - * bits (affecting 32 bits is enough). The original hash function had - * a single mixing operation that had to satisfy both sets of requirements - * and was slower as a result. - *---------- - */ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c, 4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* - * hash_any() -- hash a variable-length key into a 32-bit value - * k : the key (the unaligned variable-length array of bytes) - * len : the length of the key, counting by bytes - * - * Returns a uint32 value. Every bit of the key affects every bit of - * the return value. Every 1-bit and 2-bit delta achieves avalanche. - * About 6*len+35 instructions. The best hash table sizes are powers - * of 2. There is no need to do mod a prime (mod is sooo slow!). - * If you need less than 32 bits, use a bitmask. - * - * This procedure must never throw elog(ERROR); the ResourceOwner code - * relies on this not to fail. - * - * Note: we could easily change this function to return a 64-bit hash value - * by using the final values of both b and c. b is perhaps a little less - * well mixed than c, however. - */ -Datum -hash_any(register const unsigned char *k, register int keylen) -{ - register uint32 a, - b, - c, - len; - - /* Set up the internal state */ - len = keylen; - a = b = c = 0x9e3779b9 + len + 3923095; - - /* If the source pointer is word-aligned, we use word-wide fetches */ - if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) - { - /* Code path for aligned source data */ - register const uint32 *ka = (const uint32 *) k; - - /* handle most of the key */ - while (len >= 12) - { - a += ka[0]; - b += ka[1]; - c += ka[2]; - mix(a, b, c); - ka += 3; - len -= 12; - } - - /* handle the last 11 bytes */ - k = (const unsigned char *) ka; -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* the lowest byte of c is reserved for the length */ - /* fall through */ - case 8: - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* the lowest byte of c is reserved for the length */ - /* fall through */ - case 8: - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - else - { - /* Code path for non-aligned source data */ - - /* handle most of the key */ - while (len >= 12) - { -#ifdef WORDS_BIGENDIAN - a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); - b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); - c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); -#else /* !WORDS_BIGENDIAN */ - a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); - b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); - c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); -#endif /* WORDS_BIGENDIAN */ - mix(a, b, c); - k += 12; - len -= 12; - } - - /* handle the last 11 bytes */ -#ifdef WORDS_BIGENDIAN - switch (len) /* all the case statements fall through */ - { - case 11: - c += ((uint32) k[10] << 8); - case 10: - c += ((uint32) k[9] << 16); - case 9: - c += ((uint32) k[8] << 24); - /* the lowest byte of c is reserved for the length */ - case 8: - b += k[7]; - case 7: - b += ((uint32) k[6] << 8); - case 6: - b += ((uint32) k[5] << 16); - case 5: - b += ((uint32) k[4] << 24); - case 4: - a += k[3]; - case 3: - a += ((uint32) k[2] << 8); - case 2: - a += ((uint32) k[1] << 16); - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) /* all the case statements fall through */ - { - case 11: - c += ((uint32) k[10] << 24); - case 10: - c += ((uint32) k[9] << 16); - case 9: - c += ((uint32) k[8] << 8); - /* the lowest byte of c is reserved for the length */ - case 8: - b += ((uint32) k[7] << 24); - case 7: - b += ((uint32) k[6] << 16); - case 6: - b += ((uint32) k[5] << 8); - case 5: - b += k[4]; - case 4: - a += ((uint32) k[3] << 24); - case 3: - a += ((uint32) k[2] << 16); - case 2: - a += ((uint32) k[1] << 8); - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - - final(a, b, c); - - /* report the result */ - return UInt32GetDatum(c); -} - -/* - * hash_any_extended() -- hash into a 64-bit value, using an optional seed - * k : the key (the unaligned variable-length array of bytes) - * len : the length of the key, counting by bytes - * seed : a 64-bit seed (0 means no seed) - * - * Returns a uint64 value. Otherwise similar to hash_any. - */ -Datum -hash_any_extended(register const unsigned char *k, register int keylen, - uint64 seed) -{ - register uint32 a, - b, - c, - len; - - /* Set up the internal state */ - len = keylen; - a = b = c = 0x9e3779b9 + len + 3923095; - - /* If the seed is non-zero, use it to perturb the internal state. */ - if (seed != 0) - { - /* - * In essence, the seed is treated as part of the data being hashed, - * but for simplicity, we pretend that it's padded with four bytes of - * zeroes so that the seed constitutes a 12-byte chunk. - */ - a += (uint32) (seed >> 32); - b += (uint32) seed; - mix(a, b, c); - } - - /* If the source pointer is word-aligned, we use word-wide fetches */ - if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) - { - /* Code path for aligned source data */ - register const uint32 *ka = (const uint32 *) k; - - /* handle most of the key */ - while (len >= 12) - { - a += ka[0]; - b += ka[1]; - c += ka[2]; - mix(a, b, c); - ka += 3; - len -= 12; - } - - /* handle the last 11 bytes */ - k = (const unsigned char *) ka; -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* the lowest byte of c is reserved for the length */ - /* fall through */ - case 8: - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* the lowest byte of c is reserved for the length */ - /* fall through */ - case 8: - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - else - { - /* Code path for non-aligned source data */ - - /* handle most of the key */ - while (len >= 12) - { -#ifdef WORDS_BIGENDIAN - a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); - b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); - c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); -#else /* !WORDS_BIGENDIAN */ - a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); - b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); - c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); -#endif /* WORDS_BIGENDIAN */ - mix(a, b, c); - k += 12; - len -= 12; - } - - /* handle the last 11 bytes */ -#ifdef WORDS_BIGENDIAN - switch (len) /* all the case statements fall through */ - { - case 11: - c += ((uint32) k[10] << 8); - case 10: - c += ((uint32) k[9] << 16); - case 9: - c += ((uint32) k[8] << 24); - /* the lowest byte of c is reserved for the length */ - case 8: - b += k[7]; - case 7: - b += ((uint32) k[6] << 8); - case 6: - b += ((uint32) k[5] << 16); - case 5: - b += ((uint32) k[4] << 24); - case 4: - a += k[3]; - case 3: - a += ((uint32) k[2] << 8); - case 2: - a += ((uint32) k[1] << 16); - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) /* all the case statements fall through */ - { - case 11: - c += ((uint32) k[10] << 24); - case 10: - c += ((uint32) k[9] << 16); - case 9: - c += ((uint32) k[8] << 8); - /* the lowest byte of c is reserved for the length */ - case 8: - b += ((uint32) k[7] << 24); - case 7: - b += ((uint32) k[6] << 16); - case 6: - b += ((uint32) k[5] << 8); - case 5: - b += k[4]; - case 4: - a += ((uint32) k[3] << 24); - case 3: - a += ((uint32) k[2] << 16); - case 2: - a += ((uint32) k[1] << 8); - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - - final(a, b, c); - - /* report the result */ - PG_RETURN_UINT64(((uint64) b << 32) | c); -} - -/* - * hash_uint32() -- hash a 32-bit value to a 32-bit value - * - * This has the same result as - * hash_any(&k, sizeof(uint32)) - * but is faster and doesn't force the caller to store k into memory. - */ -Datum -hash_uint32(uint32 k) -{ - register uint32 a, - b, - c; - - a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; - a += k; - - final(a, b, c); - - /* report the result */ - return UInt32GetDatum(c); -} - -/* - * hash_uint32_extended() -- hash a 32-bit value to a 64-bit value, with a seed - * - * Like hash_uint32, this is a convenience function. - */ -Datum -hash_uint32_extended(uint32 k, uint64 seed) -{ - register uint32 a, - b, - c; - - a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; - - if (seed != 0) - { - a += (uint32) (seed >> 32); - b += (uint32) seed; - mix(a, b, c); - } - - a += k; - - final(a, b, c); - - /* report the result */ - PG_RETURN_UINT64(((uint64) b << 32) | c); -} diff --git a/src/backend/access/hash/hashinsert.c b/src/backend/access/hash/hashinsert.c index 3eb722ce266..89876d2ccd0 100644 --- a/src/backend/access/hash/hashinsert.c +++ b/src/backend/access/hash/hashinsert.c @@ -3,7 +3,7 @@ * hashinsert.c * Item insertion in hash tables for Postgres. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,15 +17,14 @@ #include "access/hash.h" #include "access/hash_xlog.h" -#include "access/heapam.h" #include "miscadmin.h" #include "utils/rel.h" #include "storage/lwlock.h" #include "storage/buf_internals.h" #include "storage/predicate.h" -static void _hash_vacuum_one_page(Relation rel, Buffer metabuf, Buffer buf, - RelFileNode hnode); +static void _hash_vacuum_one_page(Relation rel, Relation hrel, + Buffer metabuf, Buffer buf); /* * _hash_doinsert() -- Handle insertion of a single index tuple. @@ -138,7 +137,7 @@ _hash_doinsert(Relation rel, IndexTuple itup, Relation heapRel) if (IsBufferCleanupOK(buf)) { - _hash_vacuum_one_page(rel, metabuf, buf, heapRel->rd_node); + _hash_vacuum_one_page(rel, heapRel, metabuf, buf); if (PageGetFreeSpace(page) >= itemsz) break; /* OK, now we have enough space */ @@ -258,8 +257,8 @@ _hash_doinsert(Relation rel, IndexTuple itup, Relation heapRel) * _hash_pgaddtup() -- add a tuple to a particular page in the index. * * This routine adds the tuple to the page as requested; it does not write out - * the page. It is an error to call pgaddtup() without pin and write lock on - * the target buffer. + * the page. It is an error to call this function without pin and write lock + * on the target buffer. * * Returns the offset number at which the tuple was inserted. This function * is responsible for preserving the condition that tuples in a hash index @@ -336,8 +335,7 @@ _hash_pgaddmultitup(Relation rel, Buffer buf, IndexTuple *itups, */ static void -_hash_vacuum_one_page(Relation rel, Buffer metabuf, Buffer buf, - RelFileNode hnode) +_hash_vacuum_one_page(Relation rel, Relation hrel, Buffer metabuf, Buffer buf) { OffsetNumber deletable[MaxOffsetNumber]; int ndeletable = 0; @@ -361,6 +359,12 @@ _hash_vacuum_one_page(Relation rel, Buffer metabuf, Buffer buf, if (ndeletable > 0) { + TransactionId latestRemovedXid; + + latestRemovedXid = + index_compute_xid_horizon_for_tuples(rel, hrel, buf, + deletable, ndeletable); + /* * Write-lock the meta page so that we can decrement tuple count. */ @@ -394,7 +398,7 @@ _hash_vacuum_one_page(Relation rel, Buffer metabuf, Buffer buf, xl_hash_vacuum_one_page xlrec; XLogRecPtr recptr; - xlrec.hnode = hnode; + xlrec.latestRemovedXid = latestRemovedXid; xlrec.ntuples = ndeletable; XLogBeginInsert(); diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c index b170b46d86b..487103fb798 100644 --- a/src/backend/access/hash/hashovfl.c +++ b/src/backend/access/hash/hashovfl.c @@ -3,7 +3,7 @@ * hashovfl.c * Overflow page management code for the Postgres hash access method * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -793,7 +793,7 @@ _hash_initbitmapbuffer(Buffer buf, uint16 bmsize, bool initpage) * be confused into returning the same tuple more than once or some tuples * not at all by the rearrangement we are performing here. To prevent * any concurrent scan to cross the squeeze scan we use lock chaining - * similar to hasbucketcleanup. Refer comments atop hashbucketcleanup. + * similar to hashbucketcleanup. Refer comments atop hashbucketcleanup. * * We need to retain a pin on the primary bucket to ensure that no concurrent * split can start. diff --git a/src/backend/access/hash/hashpage.c b/src/backend/access/hash/hashpage.c index 3ec29a53568..838ee68c867 100644 --- a/src/backend/access/hash/hashpage.c +++ b/src/backend/access/hash/hashpage.c @@ -3,7 +3,7 @@ * hashpage.c * Hash table page management code for the Postgres hash access method * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,27 +37,17 @@ static bool _hash_alloc_buckets(Relation rel, BlockNumber firstblock, - uint32 nblocks); + uint32 nblocks); static void _hash_splitbucket(Relation rel, Buffer metabuf, - Bucket obucket, Bucket nbucket, - Buffer obuf, - Buffer nbuf, - HTAB *htab, - uint32 maxbucket, - uint32 highmask, uint32 lowmask); + Bucket obucket, Bucket nbucket, + Buffer obuf, + Buffer nbuf, + HTAB *htab, + uint32 maxbucket, + uint32 highmask, uint32 lowmask); static void log_split_page(Relation rel, Buffer buf); -/* - * We use high-concurrency locking on hash indexes (see README for an overview - * of the locking rules). However, we can skip taking lmgr locks when the - * index is local to the current backend (ie, either temp or new in the - * current transaction). No one else can see it, so there's no reason to - * take locks. We still take buffer-level locks, but not lmgr locks. - */ -#define USELOCKING(rel) (!RELATION_IS_LOCAL(rel)) - - /* * _hash_getbuf() -- Get a buffer by block number for read or write. * @@ -519,7 +509,7 @@ _hash_init_metabuffer(Buffer buf, double num_tuples, RegProcedure procid, * Choose the number of initial bucket pages to match the fill factor * given the estimated number of tuples. We round up the result to the * total number of buckets which has to be allocated before using its - * _hashm_spare element. However always force at least 2 bucket pages. The + * hashm_spares element. However always force at least 2 bucket pages. The * upper limit is determined by considerations explained in * _hash_expandtable(). */ @@ -1000,7 +990,7 @@ static bool _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks) { BlockNumber lastblock; - char zerobuf[BLCKSZ]; + PGAlignedBlock zerobuf; Page page; HashPageOpaque ovflopaque; @@ -1013,7 +1003,7 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks) if (lastblock < firstblock || lastblock == InvalidBlockNumber) return false; - page = (Page) zerobuf; + page = (Page) zerobuf.data; /* * Initialize the page. Just zeroing the page won't work; see @@ -1034,11 +1024,12 @@ _hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks) log_newpage(&rel->rd_node, MAIN_FORKNUM, lastblock, - zerobuf, + zerobuf.data, true); RelationOpenSmgr(rel); - smgrextend(rel->rd_smgr, MAIN_FORKNUM, lastblock, zerobuf, false); + PageSetChecksumInplace(page, lastblock); + smgrextend(rel->rd_smgr, MAIN_FORKNUM, lastblock, zerobuf.data, false); return true; } @@ -1519,7 +1510,7 @@ _hash_getcachedmetap(Relation rel, Buffer *metabuf, bool force_refresh) * It's important that we don't set rd_amcache to an invalid value. * Either MemoryContextAlloc or _hash_getbuf could fail, so don't * install a pointer to the newly-allocated storage in the actual - * relcache entry until both have succeeeded. + * relcache entry until both have succeeded. */ if (rel->rd_amcache == NULL) cache = MemoryContextAlloc(rel->rd_indexcxt, diff --git a/src/backend/access/hash/hashsearch.c b/src/backend/access/hash/hashsearch.c index 650041db0a5..79ae499198d 100644 --- a/src/backend/access/hash/hashsearch.c +++ b/src/backend/access/hash/hashsearch.c @@ -3,7 +3,7 @@ * hashsearch.c * search code for postgres hash tables * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,13 +22,13 @@ #include "storage/predicate.h" static bool _hash_readpage(IndexScanDesc scan, Buffer *bufP, - ScanDirection dir); -static int _hash_load_qualified_items(IndexScanDesc scan, Page page, - OffsetNumber offnum, ScanDirection dir); + ScanDirection dir); +static int _hash_load_qualified_items(IndexScanDesc scan, Page page, + OffsetNumber offnum, ScanDirection dir); static inline void _hash_saveitem(HashScanOpaque so, int itemIndex, - OffsetNumber offnum, IndexTuple itup); + OffsetNumber offnum, IndexTuple itup); static void _hash_readnext(IndexScanDesc scan, Buffer *bufp, - Page *pagep, HashPageOpaque *opaquep); + Page *pagep, HashPageOpaque *opaquep); /* * _hash_next() -- Get the next item in a scan. @@ -119,7 +119,7 @@ _hash_next(IndexScanDesc scan, ScanDirection dir) /* OK, itemIndex says what to return */ currItem = &so->currPos.items[so->currPos.itemIndex]; - scan->xs_ctup.t_self = currItem->heapTid; + scan->xs_heaptid = currItem->heapTid; return true; } @@ -432,7 +432,7 @@ _hash_first(IndexScanDesc scan, ScanDirection dir) /* OK, itemIndex says what to return */ currItem = &so->currPos.items[so->currPos.itemIndex]; - scan->xs_ctup.t_self = currItem->heapTid; + scan->xs_heaptid = currItem->heapTid; /* if we're here, _hash_readpage found a valid tuples */ return true; diff --git a/src/backend/access/hash/hashsort.c b/src/backend/access/hash/hashsort.c index b70964f429f..293f80fe24c 100644 --- a/src/backend/access/hash/hashsort.c +++ b/src/backend/access/hash/hashsort.c @@ -14,7 +14,7 @@ * plenty of locality of access. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,7 +26,9 @@ #include "postgres.h" #include "access/hash.h" +#include "commands/progress.h" #include "miscadmin.h" +#include "pgstat.h" #include "utils/tuplesort.h" @@ -116,6 +118,7 @@ void _h_indexbuild(HSpool *hspool, Relation heapRel) { IndexTuple itup; + int64 tups_done = 0; #ifdef USE_ASSERT_CHECKING uint32 hashkey = 0; #endif @@ -141,5 +144,8 @@ _h_indexbuild(HSpool *hspool, Relation heapRel) #endif _hash_doinsert(hspool->index, itup, heapRel); + + pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, + ++tups_done); } } diff --git a/src/backend/access/hash/hashutil.c b/src/backend/access/hash/hashutil.c index 4e485cc4b34..3fb92eab618 100644 --- a/src/backend/access/hash/hashutil.c +++ b/src/backend/access/hash/hashutil.c @@ -3,7 +3,7 @@ * hashutil.c * Utility code for Postgres hash implementation. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -73,10 +73,10 @@ _hash_checkqual(IndexScanDesc scan, IndexTuple itup) } /* - * _hash_datum2hashkey -- given a Datum, call the index's hash procedure + * _hash_datum2hashkey -- given a Datum, call the index's hash function * * The Datum is assumed to be of the index's column type, so we can use the - * "primary" hash procedure that's tracked for us by the generic index code. + * "primary" hash function that's tracked for us by the generic index code. */ uint32 _hash_datum2hashkey(Relation rel, Datum key) diff --git a/src/backend/access/hash/hashvalidate.c b/src/backend/access/hash/hashvalidate.c index 513a3bbc4c2..93158727512 100644 --- a/src/backend/access/hash/hashvalidate.c +++ b/src/backend/access/hash/hashvalidate.c @@ -3,7 +3,7 @@ * hashvalidate.c * Opclass validator for hash. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -96,7 +96,7 @@ hashvalidate(Oid opclassoid) { ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types", + errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types", opfamilyname, "hash", format_procedure(procform->amproc)))); result = false; @@ -182,7 +182,7 @@ hashvalidate(Oid opclassoid) result = false; } - /* There should be relevant hash procedures for each datatype */ + /* There should be relevant hash functions for each datatype */ if (!list_member_oid(hashabletypes, oprform->amoplefttype) || !list_member_oid(hashabletypes, oprform->amoprighttype)) { @@ -311,7 +311,6 @@ check_hash_func_signature(Oid funcid, int16 amprocnum, Oid argtype) */ if ((funcid == F_HASHINT4 || funcid == F_HASHINT4EXTENDED) && (argtype == DATEOID || - argtype == ABSTIMEOID || argtype == RELTIMEOID || argtype == XIDOID || argtype == CIDOID)) /* okay, allowed use of hashint4() */ ; else if ((funcid == F_TIMESTAMP_HASH || diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile index b83d496bcd7..38497b09c07 100644 --- a/src/backend/access/heap/Makefile +++ b/src/backend/access/heap/Makefile @@ -12,6 +12,7 @@ subdir = src/backend/access/heap top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = heapam.o hio.o pruneheap.o rewriteheap.o syncscan.o tuptoaster.o visibilitymap.o +OBJS = heapam.o heapam_handler.o heapam_visibility.o hio.o pruneheap.o rewriteheap.o \ + syncscan.o heaptoast.o vacuumlazy.o visibilitymap.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/heap/README.HOT b/src/backend/access/heap/README.HOT index 4cf3c3a0d4c..68c6709aa88 100644 --- a/src/backend/access/heap/README.HOT +++ b/src/backend/access/heap/README.HOT @@ -149,8 +149,8 @@ the descendant heap-only tuple. It is conceivable that someone prunes the heap-only tuple before that, and even conceivable that the line pointer is re-used for another purpose. Therefore, when following a HOT chain, it is always necessary to be prepared for the possibility that the -linked-to item pointer is unused, dead, or redirected; and if it is a -normal item pointer, we still have to check that XMIN of the tuple matches +linked-to line pointer is unused, dead, or redirected; and if it is a +normal line pointer, we still have to check that XMIN of the tuple matches the XMAX of the tuple we left. Otherwise we should assume that we have come to the end of the HOT chain. Note that this sort of XMIN/XMAX matching is required when following ordinary update chains anyway. @@ -171,14 +171,14 @@ bit: there can be at most one visible tuple in the chain, so we can stop when we find it. This rule does not work for non-MVCC snapshots, though.) Sequential scans do not need to pay attention to the HOT links because -they scan every item pointer on the page anyway. The same goes for a +they scan every line pointer on the page anyway. The same goes for a bitmap heap scan with a lossy bitmap. Pruning ------- -HOT pruning means updating item pointers so that HOT chains are +HOT pruning means updating line pointers so that HOT chains are reduced in length, by collapsing out line pointers for intermediate dead tuples. Although this makes those line pointers available for re-use, it does not immediately make the space occupied by their tuples available. @@ -271,7 +271,7 @@ physical tuple by eliminating an intermediate heap-only tuple or replacing a physical root tuple by a redirect pointer, a decrement in the table's number of dead tuples is reported to pgstats, which may postpone autovacuuming. Note that we do not count replacing a root tuple -by a DEAD item pointer as decrementing n_dead_tuples; we still want +by a DEAD line pointer as decrementing n_dead_tuples; we still want autovacuum to run to clean up the index entries and DEAD item. This area probably needs further work ... diff --git a/src/backend/access/heap/README.tuplock b/src/backend/access/heap/README.tuplock index 10b8d78ab7e..d03ddf6cdcc 100644 --- a/src/backend/access/heap/README.tuplock +++ b/src/backend/access/heap/README.tuplock @@ -36,6 +36,16 @@ do LockTuple as well, if there is any conflict, to ensure that they don't starve out waiting exclusive-lockers. However, if there is not any active conflict for a tuple, we don't incur any extra overhead. +We make an exception to the above rule for those lockers that already hold +some lock on a tuple and attempt to acquire a stronger one on it. In that +case, we skip the LockTuple() call even when there are conflicts, provided +that the target tuple is being locked, updated or deleted by multiple sessions +concurrently. Failing to skip the lock would risk a deadlock, e.g., between a +session that was first to record its weaker lock in the tuple header and would +be waiting on the LockTuple() call to upgrade to the stronger lock level, and +another session that has already done LockTuple() and is waiting for the first +session transaction to release its tuple header-level lock. + We provide four levels of tuple locking strength: SELECT FOR UPDATE obtains an exclusive lock which prevents any kind of modification of the tuple. This is the lock level that is implicitly taken by DELETE operations, and also by @@ -45,10 +55,10 @@ and modifications which might alter the tuple's key. This is the lock that is implicitly taken by UPDATE operations which leave all key fields unchanged. SELECT FOR SHARE obtains a shared lock which prevents any kind of tuple modification. Finally, SELECT FOR KEY SHARE obtains a shared lock which only -prevents tuple removal and modifications of key fields. This last mode -implements a mode just strong enough to implement RI checks, i.e. it ensures -that tuples do not go away from under a check, without blocking when some -other transaction that want to update the tuple without changing its key. +prevents tuple removal and modifications of key fields. This lock level is +just strong enough to implement RI checks, i.e. it ensures that tuples do not +go away from under a check, without blocking transactions that want to update +the tuple without changing its key. The conflict table is: diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index fa415ab06f9..e9544822bf9 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -3,7 +3,7 @@ * heapam.c * heap access method code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -12,12 +12,6 @@ * * * INTERFACE ROUTINES - * relation_open - open any relation by relation OID - * relation_openrv - open any relation specified by a RangeVar - * relation_close - close any relation - * heap_open - open a heap relation by relation OID - * heap_openrv - open a heap relation specified by a RangeVar - * heap_close - (now just a macro for relation_close) * heap_beginscan - begin relation scan * heap_rescan - restart a relation scan * heap_endscan - end relation scan @@ -39,15 +33,17 @@ #include "postgres.h" #include "access/bufmask.h" +#include "access/genam.h" #include "access/heapam.h" #include "access/heapam_xlog.h" +#include "access/heaptoast.h" #include "access/hio.h" #include "access/multixact.h" #include "access/parallel.h" #include "access/relscan.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/transam.h" -#include "access/tuptoaster.h" #include "access/valid.h" #include "access/visibilitymap.h" #include "access/xact.h" @@ -55,8 +51,6 @@ #include "access/xloginsert.h" #include "access/xlogutils.h" #include "catalog/catalog.h" -#include "catalog/namespace.h" -#include "catalog/index.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" @@ -73,63 +67,43 @@ #include "utils/lsyscache.h" #include "utils/relcache.h" #include "utils/snapmgr.h" -#include "utils/syscache.h" -#include "utils/tqual.h" -#include "utils/memutils.h" -#include "nodes/execnodes.h" -#include "executor/executor.h" - -/* GUC variable */ -bool synchronize_seqscans = true; - - -static HeapScanDesc heap_beginscan_internal(Relation relation, - Snapshot snapshot, - int nkeys, ScanKey key, - ParallelHeapScanDesc parallel_scan, - bool allow_strat, - bool allow_sync, - bool allow_pagemode, - bool is_bitmapscan, - bool is_samplescan, - bool temp_snap); -static void heap_parallelscan_startblock_init(HeapScanDesc scan); -static BlockNumber heap_parallelscan_nextpage(HeapScanDesc scan); +#include "utils/spccache.h" + + static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, - TransactionId xid, CommandId cid, int options); + TransactionId xid, CommandId cid, int options); static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf, - Buffer newbuf, HeapTuple oldtup, - HeapTuple newtup, HeapTuple old_key_tup, - bool all_visible_cleared, bool new_all_visible_cleared); + Buffer newbuf, HeapTuple oldtup, + HeapTuple newtup, HeapTuple old_key_tuple, + bool all_visible_cleared, bool new_all_visible_cleared); static Bitmapset *HeapDetermineModifiedColumns(Relation relation, - Bitmapset *interesting_cols, - HeapTuple oldtup, HeapTuple newtup); + Bitmapset *interesting_cols, + HeapTuple oldtup, HeapTuple newtup); static bool heap_acquire_tuplock(Relation relation, ItemPointer tid, - LockTupleMode mode, LockWaitPolicy wait_policy, - bool *have_tuple_lock); + LockTupleMode mode, LockWaitPolicy wait_policy, + bool *have_tuple_lock); static void compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask, - uint16 old_infomask2, TransactionId add_to_xmax, - LockTupleMode mode, bool is_update, - TransactionId *result_xmax, uint16 *result_infomask, - uint16 *result_infomask2); -static HTSU_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, - ItemPointer ctid, TransactionId xid, - LockTupleMode mode); + uint16 old_infomask2, TransactionId add_to_xmax, + LockTupleMode mode, bool is_update, + TransactionId *result_xmax, uint16 *result_infomask, + uint16 *result_infomask2); +static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, + ItemPointer ctid, TransactionId xid, + LockTupleMode mode); static void GetMultiXactIdHintBits(MultiXactId multi, uint16 *new_infomask, - uint16 *new_infomask2); + uint16 *new_infomask2); static TransactionId MultiXactIdGetUpdateXid(TransactionId xmax, - uint16 t_infomask); + uint16 t_infomask); static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, - LockTupleMode lockmode); + LockTupleMode lockmode, bool *current_is_member); static void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, uint16 infomask, - Relation rel, ItemPointer ctid, XLTW_Oper oper, - int *remaining); + Relation rel, ItemPointer ctid, XLTW_Oper oper, + int *remaining); static bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, - uint16 infomask, Relation rel, int *remaining); + uint16 infomask, Relation rel, int *remaining); static XLogRecPtr log_heap_new_cid(Relation relation, HeapTuple tup); -static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_modified, - bool *copy); -static bool ProjIndexIsUnchanged(Relation relation, HeapTuple oldtup, HeapTuple newtup); +static HeapTuple ExtractReplicaIdentity(Relation rel, HeapTuple tup, bool key_changed, + bool *copy); /* @@ -189,6 +163,20 @@ static const struct #define ConditionalLockTupleTuplock(rel, tup, mode) \ ConditionalLockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock) +#ifdef USE_PREFETCH +/* + * heap_compute_xid_horizon_for_tuples and xid_horizon_prefetch_buffer use + * this structure to coordinate prefetching activity. + */ +typedef struct +{ + BlockNumber cur_hblkno; + int next_item; + int nitems; + ItemPointerData *tids; +} XidHorizonPrefetchState; +#endif + /* * This table maps tuple lock strength values for each particular * MultiXactStatus value. @@ -219,6 +207,7 @@ static const int MultiXactStatusLock[MaxMultiXactStatus + 1] = static void initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) { + ParallelBlockTableScanDesc bpscan = NULL; bool allow_strat; bool allow_sync; @@ -233,10 +222,13 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * results for a non-MVCC snapshot, the caller must hold some higher-level * lock that ensures the interesting tuple(s) won't change.) */ - if (scan->rs_parallel != NULL) - scan->rs_nblocks = scan->rs_parallel->phs_nblocks; + if (scan->rs_base.rs_parallel != NULL) + { + bpscan = (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; + scan->rs_nblocks = bpscan->phs_nblocks; + } else - scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_rd); + scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_base.rs_rd); /* * If the table is large relative to NBuffers, use a bulk-read access @@ -247,14 +239,14 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * behaviors, independently of the size of the table; also there is a GUC * variable that can disable synchronized scanning.) * - * Note that heap_parallelscan_initialize has a very similar test; if you - * change this, consider changing that one, too. + * Note that table_block_parallelscan_initialize has a very similar test; + * if you change this, consider changing that one, too. */ - if (!RelationUsesLocalBuffers(scan->rs_rd) && + if (!RelationUsesLocalBuffers(scan->rs_base.rs_rd) && scan->rs_nblocks > NBuffers / 4) { - allow_strat = scan->rs_allow_strat; - allow_sync = scan->rs_allow_sync; + allow_strat = (scan->rs_base.rs_flags & SO_ALLOW_STRAT) != 0; + allow_sync = (scan->rs_base.rs_flags & SO_ALLOW_SYNC) != 0; } else allow_strat = allow_sync = false; @@ -272,10 +264,13 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) scan->rs_strategy = NULL; } - if (scan->rs_parallel != NULL) + if (scan->rs_base.rs_parallel != NULL) { - /* For parallel scan, believe whatever ParallelHeapScanDesc says. */ - scan->rs_syncscan = scan->rs_parallel->phs_syncscan; + /* For parallel scan, believe whatever ParallelTableScanDesc says. */ + if (scan->rs_base.rs_parallel->phs_syncscan) + scan->rs_base.rs_flags |= SO_ALLOW_SYNC; + else + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; } else if (keep_startblock) { @@ -284,16 +279,19 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * so that rewinding a cursor doesn't generate surprising results. * Reset the active syncscan setting, though. */ - scan->rs_syncscan = (allow_sync && synchronize_seqscans); + if (allow_sync && synchronize_seqscans) + scan->rs_base.rs_flags |= SO_ALLOW_SYNC; + else + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; } else if (allow_sync && synchronize_seqscans) { - scan->rs_syncscan = true; - scan->rs_startblock = ss_get_location(scan->rs_rd, scan->rs_nblocks); + scan->rs_base.rs_flags |= SO_ALLOW_SYNC; + scan->rs_startblock = ss_get_location(scan->rs_base.rs_rd, scan->rs_nblocks); } else { - scan->rs_syncscan = false; + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; scan->rs_startblock = 0; } @@ -310,15 +308,15 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * copy the scan key, if appropriate */ if (key != NULL) - memcpy(scan->rs_key, key, scan->rs_nkeys * sizeof(ScanKeyData)); + memcpy(scan->rs_base.rs_key, key, scan->rs_base.rs_nkeys * sizeof(ScanKeyData)); /* - * Currently, we don't have a stats counter for bitmap heap scans (but the - * underlying bitmap index scans will be counted) or sample scans (we only - * update stats for tuple fetches there) + * Currently, we only have a stats counter for sequential heap scans (but + * e.g for bitmap scans the underlying bitmap index scans will be counted, + * and for sample scans we update stats for tuple fetches). */ - if (!scan->rs_bitmapscan && !scan->rs_samplescan) - pgstat_count_heap_scan(scan->rs_rd); + if (scan->rs_base.rs_flags & SO_TYPE_SEQSCAN) + pgstat_count_heap_scan(scan->rs_base.rs_rd); } /* @@ -328,10 +326,13 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * numBlks is number of pages to scan (InvalidBlockNumber means "all") */ void -heap_setscanlimits(HeapScanDesc scan, BlockNumber startBlk, BlockNumber numBlks) +heap_setscanlimits(TableScanDesc sscan, BlockNumber startBlk, BlockNumber numBlks) { + HeapScanDesc scan = (HeapScanDesc) sscan; + Assert(!scan->rs_inited); /* else too late to change */ - Assert(!scan->rs_syncscan); /* else rs_startblock is significant */ + /* else rs_startblock is significant */ + Assert(!(scan->rs_base.rs_flags & SO_ALLOW_SYNC)); /* Check startBlk is valid (but allow case of zero blocks...) */ Assert(startBlk == 0 || startBlk < scan->rs_nblocks); @@ -348,8 +349,9 @@ heap_setscanlimits(HeapScanDesc scan, BlockNumber startBlk, BlockNumber numBlks) * which tuples on the page are visible. */ void -heapgetpage(HeapScanDesc scan, BlockNumber page) +heapgetpage(TableScanDesc sscan, BlockNumber page) { + HeapScanDesc scan = (HeapScanDesc) sscan; Buffer buffer; Snapshot snapshot; Page dp; @@ -376,20 +378,20 @@ heapgetpage(HeapScanDesc scan, BlockNumber page) CHECK_FOR_INTERRUPTS(); /* read page using selected strategy */ - scan->rs_cbuf = ReadBufferExtended(scan->rs_rd, MAIN_FORKNUM, page, + scan->rs_cbuf = ReadBufferExtended(scan->rs_base.rs_rd, MAIN_FORKNUM, page, RBM_NORMAL, scan->rs_strategy); scan->rs_cblock = page; - if (!scan->rs_pageatatime) + if (!(scan->rs_base.rs_flags & SO_ALLOW_PAGEMODE)) return; buffer = scan->rs_cbuf; - snapshot = scan->rs_snapshot; + snapshot = scan->rs_base.rs_snapshot; /* * Prune and repair fragmentation for the whole page, if possible. */ - heap_page_prune_opt(scan->rs_rd, buffer); + heap_page_prune_opt(scan->rs_base.rs_rd, buffer); /* * We must hold share lock on the buffer content while examining tuple @@ -399,7 +401,7 @@ heapgetpage(HeapScanDesc scan, BlockNumber page) LockBuffer(buffer, BUFFER_LOCK_SHARE); dp = BufferGetPage(buffer); - TestForOldSnapshot(snapshot, scan->rs_rd, dp); + TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lines = PageGetMaxOffsetNumber(dp); ntup = 0; @@ -434,7 +436,7 @@ heapgetpage(HeapScanDesc scan, BlockNumber page) HeapTupleData loctup; bool valid; - loctup.t_tableOid = RelationGetRelid(scan->rs_rd); + loctup.t_tableOid = RelationGetRelid(scan->rs_base.rs_rd); loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lpp); loctup.t_len = ItemIdGetLength(lpp); ItemPointerSet(&(loctup.t_self), page, lineoff); @@ -444,8 +446,8 @@ heapgetpage(HeapScanDesc scan, BlockNumber page) else valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer); - CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup, - buffer, snapshot); + CheckForSerializableConflictOut(valid, scan->rs_base.rs_rd, + &loctup, buffer, snapshot); if (valid) scan->rs_vistuples[ntup++] = lineoff; @@ -488,7 +490,7 @@ heapgettup(HeapScanDesc scan, ScanKey key) { HeapTuple tuple = &(scan->rs_ctup); - Snapshot snapshot = scan->rs_snapshot; + Snapshot snapshot = scan->rs_base.rs_snapshot; bool backward = ScanDirectionIsBackward(dir); BlockNumber page; bool finished; @@ -514,11 +516,16 @@ heapgettup(HeapScanDesc scan, tuple->t_data = NULL; return; } - if (scan->rs_parallel != NULL) + if (scan->rs_base.rs_parallel != NULL) { - heap_parallelscan_startblock_init(scan); + ParallelBlockTableScanDesc pbscan = + (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; + + table_block_parallelscan_startblock_init(scan->rs_base.rs_rd, + pbscan); - page = heap_parallelscan_nextpage(scan); + page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, + pbscan); /* Other processes might have already finished the scan. */ if (page == InvalidBlockNumber) @@ -530,7 +537,7 @@ heapgettup(HeapScanDesc scan, } else page = scan->rs_startblock; /* first page */ - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); lineoff = FirstOffsetNumber; /* first offnum */ scan->rs_inited = true; } @@ -545,7 +552,7 @@ heapgettup(HeapScanDesc scan, LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(snapshot, scan->rs_rd, dp); + TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lines = PageGetMaxOffsetNumber(dp); /* page and lineoff now reference the physically next tid */ @@ -554,7 +561,7 @@ heapgettup(HeapScanDesc scan, else if (backward) { /* backward parallel scan not supported */ - Assert(scan->rs_parallel == NULL); + Assert(scan->rs_base.rs_parallel == NULL); if (!scan->rs_inited) { @@ -574,13 +581,13 @@ heapgettup(HeapScanDesc scan, * time, and much more likely that we'll just bollix things for * forward scanners. */ - scan->rs_syncscan = false; + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; /* start from last page of the scan */ if (scan->rs_startblock > 0) page = scan->rs_startblock - 1; else page = scan->rs_nblocks - 1; - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); } else { @@ -591,7 +598,7 @@ heapgettup(HeapScanDesc scan, LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(snapshot, scan->rs_rd, dp); + TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lines = PageGetMaxOffsetNumber(dp); if (!scan->rs_inited) @@ -622,11 +629,11 @@ heapgettup(HeapScanDesc scan, page = ItemPointerGetBlockNumber(&(tuple->t_self)); if (page != scan->rs_cblock) - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); /* Since the tuple was previously fetched, needn't lock page here */ dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(snapshot, scan->rs_rd, dp); + TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lineoff = ItemPointerGetOffsetNumber(&(tuple->t_self)); lpp = PageGetItemId(dp, lineoff); Assert(ItemIdIsNormal(lpp)); @@ -661,11 +668,12 @@ heapgettup(HeapScanDesc scan, snapshot, scan->rs_cbuf); - CheckForSerializableConflictOut(valid, scan->rs_rd, tuple, - scan->rs_cbuf, snapshot); + CheckForSerializableConflictOut(valid, scan->rs_base.rs_rd, + tuple, scan->rs_cbuf, + snapshot); if (valid && key != NULL) - HeapKeyTest(tuple, RelationGetDescr(scan->rs_rd), + HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd), nkeys, key, valid); if (valid) @@ -708,9 +716,13 @@ heapgettup(HeapScanDesc scan, page = scan->rs_nblocks; page--; } - else if (scan->rs_parallel != NULL) + else if (scan->rs_base.rs_parallel != NULL) { - page = heap_parallelscan_nextpage(scan); + ParallelBlockTableScanDesc pbscan = + (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; + + page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, + pbscan); finished = (page == InvalidBlockNumber); } else @@ -733,8 +745,8 @@ heapgettup(HeapScanDesc scan, * a little bit backwards on every invocation, which is confusing. * We don't guarantee any specific ordering in general, though. */ - if (scan->rs_syncscan) - ss_report_location(scan->rs_rd, page); + if (scan->rs_base.rs_flags & SO_ALLOW_SYNC) + ss_report_location(scan->rs_base.rs_rd, page); } /* @@ -751,12 +763,12 @@ heapgettup(HeapScanDesc scan, return; } - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(snapshot, scan->rs_rd, dp); + TestForOldSnapshot(snapshot, scan->rs_base.rs_rd, dp); lines = PageGetMaxOffsetNumber((Page) dp); linesleft = lines; if (backward) @@ -818,11 +830,16 @@ heapgettup_pagemode(HeapScanDesc scan, tuple->t_data = NULL; return; } - if (scan->rs_parallel != NULL) + if (scan->rs_base.rs_parallel != NULL) { - heap_parallelscan_startblock_init(scan); + ParallelBlockTableScanDesc pbscan = + (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; + + table_block_parallelscan_startblock_init(scan->rs_base.rs_rd, + pbscan); - page = heap_parallelscan_nextpage(scan); + page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, + pbscan); /* Other processes might have already finished the scan. */ if (page == InvalidBlockNumber) @@ -834,7 +851,7 @@ heapgettup_pagemode(HeapScanDesc scan, } else page = scan->rs_startblock; /* first page */ - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); lineindex = 0; scan->rs_inited = true; } @@ -846,7 +863,7 @@ heapgettup_pagemode(HeapScanDesc scan, } dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(scan->rs_snapshot, scan->rs_rd, dp); + TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, dp); lines = scan->rs_ntuples; /* page and lineindex now reference the next visible tid */ @@ -855,7 +872,7 @@ heapgettup_pagemode(HeapScanDesc scan, else if (backward) { /* backward parallel scan not supported */ - Assert(scan->rs_parallel == NULL); + Assert(scan->rs_base.rs_parallel == NULL); if (!scan->rs_inited) { @@ -875,13 +892,13 @@ heapgettup_pagemode(HeapScanDesc scan, * time, and much more likely that we'll just bollix things for * forward scanners. */ - scan->rs_syncscan = false; + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; /* start from last page of the scan */ if (scan->rs_startblock > 0) page = scan->rs_startblock - 1; else page = scan->rs_nblocks - 1; - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); } else { @@ -890,7 +907,7 @@ heapgettup_pagemode(HeapScanDesc scan, } dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(scan->rs_snapshot, scan->rs_rd, dp); + TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, dp); lines = scan->rs_ntuples; if (!scan->rs_inited) @@ -920,11 +937,11 @@ heapgettup_pagemode(HeapScanDesc scan, page = ItemPointerGetBlockNumber(&(tuple->t_self)); if (page != scan->rs_cblock) - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); /* Since the tuple was previously fetched, needn't lock page here */ dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(scan->rs_snapshot, scan->rs_rd, dp); + TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, dp); lineoff = ItemPointerGetOffsetNumber(&(tuple->t_self)); lpp = PageGetItemId(dp, lineoff); Assert(ItemIdIsNormal(lpp)); @@ -962,7 +979,7 @@ heapgettup_pagemode(HeapScanDesc scan, { bool valid; - HeapKeyTest(tuple, RelationGetDescr(scan->rs_rd), + HeapKeyTest(tuple, RelationGetDescr(scan->rs_base.rs_rd), nkeys, key, valid); if (valid) { @@ -998,9 +1015,13 @@ heapgettup_pagemode(HeapScanDesc scan, page = scan->rs_nblocks; page--; } - else if (scan->rs_parallel != NULL) + else if (scan->rs_base.rs_parallel != NULL) { - page = heap_parallelscan_nextpage(scan); + ParallelBlockTableScanDesc pbscan = + (ParallelBlockTableScanDesc) scan->rs_base.rs_parallel; + + page = table_block_parallelscan_nextpage(scan->rs_base.rs_rd, + pbscan); finished = (page == InvalidBlockNumber); } else @@ -1023,8 +1044,8 @@ heapgettup_pagemode(HeapScanDesc scan, * a little bit backwards on every invocation, which is confusing. * We don't guarantee any specific ordering in general, though. */ - if (scan->rs_syncscan) - ss_report_location(scan->rs_rd, page); + if (scan->rs_base.rs_flags & SO_ALLOW_SYNC) + ss_report_location(scan->rs_base.rs_rd, page); } /* @@ -1041,10 +1062,10 @@ heapgettup_pagemode(HeapScanDesc scan, return; } - heapgetpage(scan, page); + heapgetpage((TableScanDesc) scan, page); dp = BufferGetPage(scan->rs_cbuf); - TestForOldSnapshot(scan->rs_snapshot, scan->rs_rd, dp); + TestForOldSnapshot(scan->rs_base.rs_snapshot, scan->rs_base.rs_rd, dp); lines = scan->rs_ntuples; linesleft = lines; if (backward) @@ -1106,356 +1127,12 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, * ---------------------------------------------------------------- */ -/* ---------------- - * relation_open - open any relation by relation OID - * - * If lockmode is not "NoLock", the specified kind of lock is - * obtained on the relation. (Generally, NoLock should only be - * used if the caller knows it has some appropriate lock on the - * relation already.) - * - * An error is raised if the relation does not exist. - * - * NB: a "relation" is anything with a pg_class entry. The caller is - * expected to check whether the relkind is something it can handle. - * ---------------- - */ -Relation -relation_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* Get the lock before trying to open the relcache entry */ - if (lockmode != NoLock) - LockRelationOid(relationId, lockmode); - - /* The relcache does all the real work... */ - r = RelationIdGetRelation(relationId); - - if (!RelationIsValid(r)) - elog(ERROR, "could not open relation with OID %u", relationId); - - /* Make note that we've accessed a temporary relation */ - if (RelationUsesLocalBuffers(r)) - MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; - - pgstat_initstats(r); - - return r; -} - -/* ---------------- - * try_relation_open - open any relation by relation OID - * - * Same as relation_open, except return NULL instead of failing - * if the relation does not exist. - * ---------------- - */ -Relation -try_relation_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* Get the lock first */ - if (lockmode != NoLock) - LockRelationOid(relationId, lockmode); - - /* - * Now that we have the lock, probe to see if the relation really exists - * or not. - */ - if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relationId))) - { - /* Release useless lock */ - if (lockmode != NoLock) - UnlockRelationOid(relationId, lockmode); - - return NULL; - } - - /* Should be safe to do a relcache load */ - r = RelationIdGetRelation(relationId); - - if (!RelationIsValid(r)) - elog(ERROR, "could not open relation with OID %u", relationId); - - /* Make note that we've accessed a temporary relation */ - if (RelationUsesLocalBuffers(r)) - MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPREL; - - pgstat_initstats(r); - - return r; -} - -/* ---------------- - * relation_openrv - open any relation specified by a RangeVar - * - * Same as relation_open, but the relation is specified by a RangeVar. - * ---------------- - */ -Relation -relation_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Oid relOid; - - /* - * Check for shared-cache-inval messages before trying to open the - * relation. This is needed even if we already hold a lock on the - * relation, because GRANT/REVOKE are executed without taking any lock on - * the target relation, and we want to be sure we see current ACL - * information. We can skip this if asked for NoLock, on the assumption - * that such a call is not the first one in the current command, and so we - * should be reasonably up-to-date already. (XXX this all could stand to - * be redesigned, but for the moment we'll keep doing this like it's been - * done historically.) - */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); - - /* Look up and lock the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, lockmode, false); - - /* Let relation_open do the rest */ - return relation_open(relOid, NoLock); -} - -/* ---------------- - * relation_openrv_extended - open any relation specified by a RangeVar - * - * Same as relation_openrv, but with an additional missing_ok argument - * allowing a NULL return rather than an error if the relation is not - * found. (Note that some other causes, such as permissions problems, - * will still result in an ereport.) - * ---------------- - */ -Relation -relation_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, - bool missing_ok) -{ - Oid relOid; - - /* - * Check for shared-cache-inval messages before trying to open the - * relation. See comments in relation_openrv(). - */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); - - /* Look up and lock the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, lockmode, missing_ok); - - /* Return NULL on not-found */ - if (!OidIsValid(relOid)) - return NULL; - - /* Let relation_open do the rest */ - return relation_open(relOid, NoLock); -} - -/* ---------------- - * relation_close - close any relation - * - * If lockmode is not "NoLock", we then release the specified lock. - * - * Note that it is often sensible to hold a lock beyond relation_close; - * in that case, the lock is released automatically at xact end. - * ---------------- - */ -void -relation_close(Relation relation, LOCKMODE lockmode) -{ - LockRelId relid = relation->rd_lockInfo.lockRelId; - Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES); - - /* The relcache does the real work... */ - RelationClose(relation); - - if (lockmode != NoLock) - UnlockRelationId(&relid, lockmode); -} - - -/* ---------------- - * heap_open - open a heap relation by relation OID - * - * This is essentially relation_open plus check that the relation - * is not an index nor a composite type. (The caller should also - * check that it's not a view or foreign table before assuming it has - * storage.) - * ---------------- - */ -Relation -heap_open(Oid relationId, LOCKMODE lockmode) -{ - Relation r; - - r = relation_open(relationId, lockmode); - - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - -/* ---------------- - * heap_openrv - open a heap relation specified - * by a RangeVar node - * - * As above, but relation is specified by a RangeVar. - * ---------------- - */ -Relation -heap_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Relation r; - - r = relation_openrv(relation, lockmode); - - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - -/* ---------------- - * heap_openrv_extended - open a heap relation specified - * by a RangeVar node - * - * As above, but optionally return NULL instead of failing for - * relation-not-found. - * ---------------- - */ -Relation -heap_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, - bool missing_ok) -{ - Relation r; - - r = relation_openrv_extended(relation, lockmode, missing_ok); - - if (r) - { - if (r->rd_rel->relkind == RELKIND_INDEX || - r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - } - - return r; -} - - -/* ---------------- - * heap_beginscan - begin relation scan - * - * heap_beginscan is the "standard" case. - * - * heap_beginscan_catalog differs in setting up its own temporary snapshot. - * - * heap_beginscan_strat offers an extended API that lets the caller control - * whether a nondefault buffer access strategy can be used, and whether - * syncscan can be chosen (possibly resulting in the scan not starting from - * block zero). Both of these default to true with plain heap_beginscan. - * - * heap_beginscan_bm is an alternative entry point for setting up a - * HeapScanDesc for a bitmap heap scan. Although that scan technology is - * really quite unlike a standard seqscan, there is just enough commonality - * to make it worth using the same data structure. - * - * heap_beginscan_sampling is an alternative entry point for setting up a - * HeapScanDesc for a TABLESAMPLE scan. As with bitmap scans, it's worth - * using the same data structure although the behavior is rather different. - * In addition to the options offered by heap_beginscan_strat, this call - * also allows control of whether page-mode visibility checking is used. - * ---------------- - */ -HeapScanDesc +TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key) -{ - return heap_beginscan_internal(relation, snapshot, nkeys, key, NULL, - true, true, true, false, false, false); -} - -HeapScanDesc -heap_beginscan_catalog(Relation relation, int nkeys, ScanKey key) -{ - Oid relid = RelationGetRelid(relation); - Snapshot snapshot = RegisterSnapshot(GetCatalogSnapshot(relid)); - - return heap_beginscan_internal(relation, snapshot, nkeys, key, NULL, - true, true, true, false, false, true); -} - -HeapScanDesc -heap_beginscan_strat(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key, - bool allow_strat, bool allow_sync) -{ - return heap_beginscan_internal(relation, snapshot, nkeys, key, NULL, - allow_strat, allow_sync, true, - false, false, false); -} - -HeapScanDesc -heap_beginscan_bm(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key) -{ - return heap_beginscan_internal(relation, snapshot, nkeys, key, NULL, - false, false, true, true, false, false); -} - -HeapScanDesc -heap_beginscan_sampling(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key, - bool allow_strat, bool allow_sync, bool allow_pagemode) -{ - return heap_beginscan_internal(relation, snapshot, nkeys, key, NULL, - allow_strat, allow_sync, allow_pagemode, - false, true, false); -} - -static HeapScanDesc -heap_beginscan_internal(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key, - ParallelHeapScanDesc parallel_scan, - bool allow_strat, - bool allow_sync, - bool allow_pagemode, - bool is_bitmapscan, - bool is_samplescan, - bool temp_snap) + int nkeys, ScanKey key, + ParallelTableScanDesc parallel_scan, + uint32 flags) { HeapScanDesc scan; @@ -1473,35 +1150,42 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot, */ scan = (HeapScanDesc) palloc(sizeof(HeapScanDescData)); - scan->rs_rd = relation; - scan->rs_snapshot = snapshot; - scan->rs_nkeys = nkeys; - scan->rs_bitmapscan = is_bitmapscan; - scan->rs_samplescan = is_samplescan; + scan->rs_base.rs_rd = relation; + scan->rs_base.rs_snapshot = snapshot; + scan->rs_base.rs_nkeys = nkeys; + scan->rs_base.rs_flags = flags; + scan->rs_base.rs_parallel = parallel_scan; scan->rs_strategy = NULL; /* set in initscan */ - scan->rs_allow_strat = allow_strat; - scan->rs_allow_sync = allow_sync; - scan->rs_temp_snap = temp_snap; - scan->rs_parallel = parallel_scan; /* - * we can use page-at-a-time mode if it's an MVCC-safe snapshot + * Disable page-at-a-time mode if it's not a MVCC-safe snapshot. */ - scan->rs_pageatatime = allow_pagemode && IsMVCCSnapshot(snapshot); + if (!(snapshot && IsMVCCSnapshot(snapshot))) + scan->rs_base.rs_flags &= ~SO_ALLOW_PAGEMODE; /* - * For a seqscan in a serializable transaction, acquire a predicate lock - * on the entire relation. This is required not only to lock all the - * matching tuples, but also to conflict with new insertions into the - * table. In an indexscan, we take page locks on the index pages covering - * the range specified in the scan qual, but in a heap scan there is - * nothing more fine-grained to lock. A bitmap scan is a different story, - * there we have already scanned the index and locked the index pages - * covering the predicate. But in that case we still have to lock any - * matching heap tuples. + * For seqscan and sample scans in a serializable transaction, acquire a + * predicate lock on the entire relation. This is required not only to + * lock all the matching tuples, but also to conflict with new insertions + * into the table. In an indexscan, we take page locks on the index pages + * covering the range specified in the scan qual, but in a heap scan there + * is nothing more fine-grained to lock. A bitmap scan is a different + * story, there we have already scanned the index and locked the index + * pages covering the predicate. But in that case we still have to lock + * any matching heap tuples. For sample scan we could optimize the locking + * to be at least page-level granularity, but we'd need to add per-tuple + * locking for that. */ - if (!is_bitmapscan) + if (scan->rs_base.rs_flags & (SO_TYPE_SEQSCAN | SO_TYPE_SAMPLESCAN)) + { + /* + * Ensure a missing snapshot is noticed reliably, even if the + * isolation mode means predicate locking isn't performed (and + * therefore the snapshot isn't used here). + */ + Assert(snapshot); PredicateLockRelation(relation, snapshot); + } /* we only need to set this up once */ scan->rs_ctup.t_tableOid = RelationGetRelid(relation); @@ -1511,23 +1195,40 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot, * initscan() and we don't want to allocate memory again */ if (nkeys > 0) - scan->rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys); + scan->rs_base.rs_key = (ScanKey) palloc(sizeof(ScanKeyData) * nkeys); else - scan->rs_key = NULL; + scan->rs_base.rs_key = NULL; initscan(scan, key, false); - return scan; + return (TableScanDesc) scan; } -/* ---------------- - * heap_rescan - restart a relation scan - * ---------------- - */ void -heap_rescan(HeapScanDesc scan, - ScanKey key) +heap_rescan(TableScanDesc sscan, ScanKey key, bool set_params, + bool allow_strat, bool allow_sync, bool allow_pagemode) { + HeapScanDesc scan = (HeapScanDesc) sscan; + + if (set_params) + { + if (allow_strat) + scan->rs_base.rs_flags |= SO_ALLOW_STRAT; + else + scan->rs_base.rs_flags &= ~SO_ALLOW_STRAT; + + if (allow_sync) + scan->rs_base.rs_flags |= SO_ALLOW_SYNC; + else + scan->rs_base.rs_flags &= ~SO_ALLOW_SYNC; + + if (allow_pagemode && scan->rs_base.rs_snapshot && + IsMVCCSnapshot(scan->rs_base.rs_snapshot)) + scan->rs_base.rs_flags |= SO_ALLOW_PAGEMODE; + else + scan->rs_base.rs_flags &= ~SO_ALLOW_PAGEMODE; + } + /* * unpin scan buffers */ @@ -1540,37 +1241,11 @@ heap_rescan(HeapScanDesc scan, initscan(scan, key, true); } -/* ---------------- - * heap_rescan_set_params - restart a relation scan after changing params - * - * This call allows changing the buffer strategy, syncscan, and pagemode - * options before starting a fresh scan. Note that although the actual use - * of syncscan might change (effectively, enabling or disabling reporting), - * the previously selected startblock will be kept. - * ---------------- - */ void -heap_rescan_set_params(HeapScanDesc scan, ScanKey key, - bool allow_strat, bool allow_sync, bool allow_pagemode) +heap_endscan(TableScanDesc sscan) { - /* adjust parameters */ - scan->rs_allow_strat = allow_strat; - scan->rs_allow_sync = allow_sync; - scan->rs_pageatatime = allow_pagemode && IsMVCCSnapshot(scan->rs_snapshot); - /* ... and rescan */ - heap_rescan(scan, key); -} + HeapScanDesc scan = (HeapScanDesc) sscan; -/* ---------------- - * heap_endscan - end relation scan - * - * See how to integrate with index scans. - * Check handling if reldesc caching. - * ---------------- - */ -void -heap_endscan(HeapScanDesc scan) -{ /* Note: no locking manipulations needed */ /* @@ -1582,240 +1257,20 @@ heap_endscan(HeapScanDesc scan) /* * decrement relation reference count and free scan descriptor storage */ - RelationDecrementReferenceCount(scan->rs_rd); + RelationDecrementReferenceCount(scan->rs_base.rs_rd); - if (scan->rs_key) - pfree(scan->rs_key); + if (scan->rs_base.rs_key) + pfree(scan->rs_base.rs_key); if (scan->rs_strategy != NULL) FreeAccessStrategy(scan->rs_strategy); - if (scan->rs_temp_snap) - UnregisterSnapshot(scan->rs_snapshot); + if (scan->rs_base.rs_flags & SO_TEMP_SNAPSHOT) + UnregisterSnapshot(scan->rs_base.rs_snapshot); pfree(scan); } -/* ---------------- - * heap_parallelscan_estimate - estimate storage for ParallelHeapScanDesc - * - * Sadly, this doesn't reduce to a constant, because the size required - * to serialize the snapshot can vary. - * ---------------- - */ -Size -heap_parallelscan_estimate(Snapshot snapshot) -{ - return add_size(offsetof(ParallelHeapScanDescData, phs_snapshot_data), - EstimateSnapshotSpace(snapshot)); -} - -/* ---------------- - * heap_parallelscan_initialize - initialize ParallelHeapScanDesc - * - * Must allow as many bytes of shared memory as returned by - * heap_parallelscan_estimate. Call this just once in the leader - * process; then, individual workers attach via heap_beginscan_parallel. - * ---------------- - */ -void -heap_parallelscan_initialize(ParallelHeapScanDesc target, Relation relation, - Snapshot snapshot) -{ - target->phs_relid = RelationGetRelid(relation); - target->phs_nblocks = RelationGetNumberOfBlocks(relation); - /* compare phs_syncscan initialization to similar logic in initscan */ - target->phs_syncscan = synchronize_seqscans && - !RelationUsesLocalBuffers(relation) && - target->phs_nblocks > NBuffers / 4; - SpinLockInit(&target->phs_mutex); - target->phs_startblock = InvalidBlockNumber; - pg_atomic_init_u64(&target->phs_nallocated, 0); - if (IsMVCCSnapshot(snapshot)) - { - SerializeSnapshot(snapshot, target->phs_snapshot_data); - target->phs_snapshot_any = false; - } - else - { - Assert(snapshot == SnapshotAny); - target->phs_snapshot_any = true; - } -} - -/* ---------------- - * heap_parallelscan_reinitialize - reset a parallel scan - * - * Call this in the leader process. Caller is responsible for - * making sure that all workers have finished the scan beforehand. - * ---------------- - */ -void -heap_parallelscan_reinitialize(ParallelHeapScanDesc parallel_scan) -{ - pg_atomic_write_u64(¶llel_scan->phs_nallocated, 0); -} - -/* ---------------- - * heap_beginscan_parallel - join a parallel scan - * - * Caller must hold a suitable lock on the correct relation. - * ---------------- - */ -HeapScanDesc -heap_beginscan_parallel(Relation relation, ParallelHeapScanDesc parallel_scan) -{ - Snapshot snapshot; - - Assert(RelationGetRelid(relation) == parallel_scan->phs_relid); - - if (!parallel_scan->phs_snapshot_any) - { - /* Snapshot was serialized -- restore it */ - snapshot = RestoreSnapshot(parallel_scan->phs_snapshot_data); - RegisterSnapshot(snapshot); - } - else - { - /* SnapshotAny passed by caller (not serialized) */ - snapshot = SnapshotAny; - } - - return heap_beginscan_internal(relation, snapshot, 0, NULL, parallel_scan, - true, true, true, false, false, - !parallel_scan->phs_snapshot_any); -} - -/* ---------------- - * heap_parallelscan_startblock_init - find and set the scan's startblock - * - * Determine where the parallel seq scan should start. This function may - * be called many times, once by each parallel worker. We must be careful - * only to set the startblock once. - * ---------------- - */ -static void -heap_parallelscan_startblock_init(HeapScanDesc scan) -{ - BlockNumber sync_startpage = InvalidBlockNumber; - ParallelHeapScanDesc parallel_scan; - - Assert(scan->rs_parallel); - parallel_scan = scan->rs_parallel; - -retry: - /* Grab the spinlock. */ - SpinLockAcquire(¶llel_scan->phs_mutex); - - /* - * If the scan's startblock has not yet been initialized, we must do so - * now. If this is not a synchronized scan, we just start at block 0, but - * if it is a synchronized scan, we must get the starting position from - * the synchronized scan machinery. We can't hold the spinlock while - * doing that, though, so release the spinlock, get the information we - * need, and retry. If nobody else has initialized the scan in the - * meantime, we'll fill in the value we fetched on the second time - * through. - */ - if (parallel_scan->phs_startblock == InvalidBlockNumber) - { - if (!parallel_scan->phs_syncscan) - parallel_scan->phs_startblock = 0; - else if (sync_startpage != InvalidBlockNumber) - parallel_scan->phs_startblock = sync_startpage; - else - { - SpinLockRelease(¶llel_scan->phs_mutex); - sync_startpage = ss_get_location(scan->rs_rd, scan->rs_nblocks); - goto retry; - } - } - SpinLockRelease(¶llel_scan->phs_mutex); -} - -/* ---------------- - * heap_parallelscan_nextpage - get the next page to scan - * - * Get the next page to scan. Even if there are no pages left to scan, - * another backend could have grabbed a page to scan and not yet finished - * looking at it, so it doesn't follow that the scan is done when the - * first backend gets an InvalidBlockNumber return. - * ---------------- - */ -static BlockNumber -heap_parallelscan_nextpage(HeapScanDesc scan) -{ - BlockNumber page; - ParallelHeapScanDesc parallel_scan; - uint64 nallocated; - - Assert(scan->rs_parallel); - parallel_scan = scan->rs_parallel; - - /* - * phs_nallocated tracks how many pages have been allocated to workers - * already. When phs_nallocated >= rs_nblocks, all blocks have been - * allocated. - * - * Because we use an atomic fetch-and-add to fetch the current value, the - * phs_nallocated counter will exceed rs_nblocks, because workers will - * still increment the value, when they try to allocate the next block but - * all blocks have been allocated already. The counter must be 64 bits - * wide because of that, to avoid wrapping around when rs_nblocks is close - * to 2^32. - * - * The actual page to return is calculated by adding the counter to the - * starting block number, modulo nblocks. - */ - nallocated = pg_atomic_fetch_add_u64(¶llel_scan->phs_nallocated, 1); - if (nallocated >= scan->rs_nblocks) - page = InvalidBlockNumber; /* all blocks have been allocated */ - else - page = (nallocated + parallel_scan->phs_startblock) % scan->rs_nblocks; - - /* - * Report scan location. Normally, we report the current page number. - * When we reach the end of the scan, though, we report the starting page, - * not the ending page, just so the starting positions for later scans - * doesn't slew backwards. We only report the position at the end of the - * scan once, though: subsequent callers will report nothing. - */ - if (scan->rs_syncscan) - { - if (page != InvalidBlockNumber) - ss_report_location(scan->rs_rd, page); - else if (nallocated == scan->rs_nblocks) - ss_report_location(scan->rs_rd, parallel_scan->phs_startblock); - } - - return page; -} - -/* ---------------- - * heap_update_snapshot - * - * Update snapshot info in heap scan descriptor. - * ---------------- - */ -void -heap_update_snapshot(HeapScanDesc scan, Snapshot snapshot) -{ - Assert(IsMVCCSnapshot(snapshot)); - - RegisterSnapshot(snapshot); - scan->rs_snapshot = snapshot; - scan->rs_temp_snap = true; -} - -/* ---------------- - * heap_getnext - retrieve next tuple in scan - * - * Fix to work with index relations. - * We don't return the buffer anymore, but you can get it from the - * returned HeapTuple. - * ---------------- - */ - #ifdef HEAPDEBUGALL #define HEAPDEBUG_1 \ elog(DEBUG2, "heap_getnext([%s,nkeys=%d],dir=%d) called", \ @@ -1832,17 +1287,32 @@ heap_update_snapshot(HeapScanDesc scan, Snapshot snapshot) HeapTuple -heap_getnext(HeapScanDesc scan, ScanDirection direction) +heap_getnext(TableScanDesc sscan, ScanDirection direction) { + HeapScanDesc scan = (HeapScanDesc) sscan; + + /* + * This is still widely used directly, without going through table AM, so + * add a safety check. It's possible we should, at a later point, + * downgrade this to an assert. The reason for checking the AM routine, + * rather than the AM oid, is that this allows to write regression tests + * that create another AM reusing the heap handler. + */ + if (unlikely(sscan->rs_rd->rd_tableam != GetHeapamTableAmRoutine())) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg_internal("only heap AM is supported"))); + /* Note: no locking manipulations needed */ HEAPDEBUG_1; /* heap_getnext( info ) */ - if (scan->rs_pageatatime) + if (scan->rs_base.rs_flags & SO_ALLOW_PAGEMODE) heapgettup_pagemode(scan, direction, - scan->rs_nkeys, scan->rs_key); + scan->rs_base.rs_nkeys, scan->rs_base.rs_key); else - heapgettup(scan, direction, scan->rs_nkeys, scan->rs_key); + heapgettup(scan, direction, + scan->rs_base.rs_nkeys, scan->rs_base.rs_key); if (scan->rs_ctup.t_data == NULL) { @@ -1856,9 +1326,57 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction) */ HEAPDEBUG_3; /* heap_getnext returning tuple */ - pgstat_count_heap_getnext(scan->rs_rd); + pgstat_count_heap_getnext(scan->rs_base.rs_rd); - return &(scan->rs_ctup); + return &scan->rs_ctup; +} + +#ifdef HEAPAMSLOTDEBUGALL +#define HEAPAMSLOTDEBUG_1 \ + elog(DEBUG2, "heapam_getnextslot([%s,nkeys=%d],dir=%d) called", \ + RelationGetRelationName(scan->rs_base.rs_rd), scan->rs_base.rs_nkeys, (int) direction) +#define HEAPAMSLOTDEBUG_2 \ + elog(DEBUG2, "heapam_getnextslot returning EOS") +#define HEAPAMSLOTDEBUG_3 \ + elog(DEBUG2, "heapam_getnextslot returning tuple") +#else +#define HEAPAMSLOTDEBUG_1 +#define HEAPAMSLOTDEBUG_2 +#define HEAPAMSLOTDEBUG_3 +#endif + +bool +heap_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot) +{ + HeapScanDesc scan = (HeapScanDesc) sscan; + + /* Note: no locking manipulations needed */ + + HEAPAMSLOTDEBUG_1; /* heap_getnextslot( info ) */ + + if (sscan->rs_flags & SO_ALLOW_PAGEMODE) + heapgettup_pagemode(scan, direction, sscan->rs_nkeys, sscan->rs_key); + else + heapgettup(scan, direction, sscan->rs_nkeys, sscan->rs_key); + + if (scan->rs_ctup.t_data == NULL) + { + HEAPAMSLOTDEBUG_2; /* heap_getnextslot returning EOS */ + ExecClearTuple(slot); + return false; + } + + /* + * if we get here it means we have a new current scan tuple, so point to + * the proper return buffer and return the tuple. + */ + HEAPAMSLOTDEBUG_3; /* heap_getnextslot returning tuple */ + + pgstat_count_heap_getnext(scan->rs_base.rs_rd); + + ExecStoreBufferHeapTuple(&scan->rs_ctup, slot, + scan->rs_cbuf); + return true; } /* @@ -1878,15 +1396,6 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction) * If the tuple is found but fails the time qual check, then false is returned * but tuple->t_data is left pointing to the tuple. * - * keep_buf determines what is done with the buffer in the false-result cases. - * When the caller specifies keep_buf = true, we retain the pin on the buffer - * and return it in *userbuf (so the caller must eventually unpin it); when - * keep_buf = false, the pin is released and *userbuf is set to InvalidBuffer. - * - * stats_relation is the relation to charge the heap_fetch operation against - * for statistical purposes. (This could be the heap rel itself, an - * associated index, or NULL to not count the fetch at all.) - * * heap_fetch does not follow HOT chains: only the exact TID requested will * be fetched. * @@ -1903,9 +1412,7 @@ bool heap_fetch(Relation relation, Snapshot snapshot, HeapTuple tuple, - Buffer *userbuf, - bool keep_buf, - Relation stats_relation) + Buffer *userbuf) { ItemPointer tid = &(tuple->t_self); ItemId lp; @@ -1934,13 +1441,8 @@ heap_fetch(Relation relation, if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page)) { LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - if (keep_buf) - *userbuf = buffer; - else - { - ReleaseBuffer(buffer); - *userbuf = InvalidBuffer; - } + ReleaseBuffer(buffer); + *userbuf = InvalidBuffer; tuple->t_data = NULL; return false; } @@ -1956,13 +1458,8 @@ heap_fetch(Relation relation, if (!ItemIdIsNormal(lp)) { LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - if (keep_buf) - *userbuf = buffer; - else - { - ReleaseBuffer(buffer); - *userbuf = InvalidBuffer; - } + ReleaseBuffer(buffer); + *userbuf = InvalidBuffer; tuple->t_data = NULL; return false; } @@ -1975,7 +1472,7 @@ heap_fetch(Relation relation, tuple->t_tableOid = RelationGetRelid(relation); /* - * check time qualification of tuple, then release lock + * check tuple visibility, then release lock */ valid = HeapTupleSatisfiesVisibility(tuple, snapshot, buffer); @@ -1994,21 +1491,12 @@ heap_fetch(Relation relation, */ *userbuf = buffer; - /* Count the successful fetch against appropriate rel, if any */ - if (stats_relation != NULL) - pgstat_count_heap_fetch(stats_relation); - return true; } - /* Tuple failed time qual, but maybe caller wants to see it anyway. */ - if (keep_buf) - *userbuf = buffer; - else - { - ReleaseBuffer(buffer); - *userbuf = InvalidBuffer; - } + /* Tuple failed time qual */ + ReleaseBuffer(buffer); + *userbuf = InvalidBuffer; return false; } @@ -2041,6 +1529,7 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, { Page dp = (Page) BufferGetPage(buffer); TransactionId prev_xmax = InvalidTransactionId; + BlockNumber blkno; OffsetNumber offnum; bool at_chain_start; bool valid; @@ -2050,14 +1539,13 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, if (all_dead) *all_dead = first_call; - Assert(TransactionIdIsValid(RecentGlobalXmin)); - - Assert(ItemPointerGetBlockNumber(tid) == BufferGetBlockNumber(buffer)); + blkno = ItemPointerGetBlockNumber(tid); offnum = ItemPointerGetOffsetNumber(tid); at_chain_start = first_call; skip = !first_call; - heapTuple->t_self = *tid; + Assert(TransactionIdIsValid(RecentGlobalXmin)); + Assert(BufferGetBlockNumber(buffer) == blkno); /* Scan through possible multiple members of HOT-chain */ for (;;) @@ -2085,10 +1573,16 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, break; } + /* + * Update heapTuple to point to the element of the HOT chain we're + * currently investigating. Having t_self set correctly is important + * because the SSI checks and the *Satisfies routine for historical + * MVCC snapshots need the correct tid to decide about the visibility. + */ heapTuple->t_data = (HeapTupleHeader) PageGetItem(dp, lp); heapTuple->t_len = ItemIdGetLength(lp); heapTuple->t_tableOid = RelationGetRelid(relation); - ItemPointerSetOffsetNumber(&heapTuple->t_self, offnum); + ItemPointerSet(&heapTuple->t_self, blkno, offnum); /* * Shouldn't see a HEAP_ONLY tuple at chain start. @@ -2114,21 +1608,10 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, */ if (!skip) { - /* - * For the benefit of logical decoding, have t_self point at the - * element of the HOT chain we're currently investigating instead - * of the root tuple of the HOT chain. This is important because - * the *Satisfies routine for historical mvcc snapshots needs the - * correct tid to decide about the visibility in some cases. - */ - ItemPointerSet(&(heapTuple->t_self), BufferGetBlockNumber(buffer), offnum); - /* If it's visible per the snapshot, we must return it */ valid = HeapTupleSatisfiesVisibility(heapTuple, snapshot, buffer); CheckForSerializableConflictOut(valid, relation, heapTuple, buffer, snapshot); - /* reset to original, non-redirected, tid */ - heapTuple->t_self = *tid; if (valid) { @@ -2160,7 +1643,7 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, if (HeapTupleIsHotUpdated(heapTuple)) { Assert(ItemPointerGetBlockNumber(&heapTuple->t_data->t_ctid) == - ItemPointerGetBlockNumber(tid)); + blkno); offnum = ItemPointerGetOffsetNumber(&heapTuple->t_data->t_ctid); at_chain_start = false; prev_xmax = HeapTupleHeaderGetUpdateXid(heapTuple->t_data); @@ -2172,35 +1655,11 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, return false; } -/* - * heap_hot_search - search HOT chain for tuple satisfying snapshot - * - * This has the same API as heap_hot_search_buffer, except that the caller - * does not provide the buffer containing the page, rather we access it - * locally. - */ -bool -heap_hot_search(ItemPointer tid, Relation relation, Snapshot snapshot, - bool *all_dead) -{ - bool result; - Buffer buffer; - HeapTupleData heapTuple; - - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); - LockBuffer(buffer, BUFFER_LOCK_SHARE); - result = heap_hot_search_buffer(tid, relation, buffer, snapshot, - &heapTuple, all_dead, true); - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - ReleaseBuffer(buffer); - return result; -} - /* * heap_get_latest_tid - get the latest tid of a specified tuple * - * Actually, this gets the latest version that is visible according to - * the passed snapshot. You can pass SnapshotDirty to get the very latest, + * Actually, this gets the latest version that is visible according to the + * scan's snapshot. Create a scan using SnapshotDirty to get the very latest, * possibly uncommitted version. * * *tid is both an input and an output parameter: it is updated to @@ -2208,28 +1667,20 @@ heap_hot_search(ItemPointer tid, Relation relation, Snapshot snapshot, * if no version of the row passes the snapshot test. */ void -heap_get_latest_tid(Relation relation, - Snapshot snapshot, +heap_get_latest_tid(TableScanDesc sscan, ItemPointer tid) { - BlockNumber blk; + Relation relation = sscan->rs_rd; + Snapshot snapshot = sscan->rs_snapshot; ItemPointerData ctid; TransactionId priorXmax; - /* this is to avoid Assert failures on bad input */ - if (!ItemPointerIsValid(tid)) - return; - /* - * Since this can be called with user-supplied TID, don't trust the input - * too much. (RelationGetNumberOfBlocks is an expensive check, so we - * don't check t_ctid links again this way. Note that it would not do to - * call it just once and save the result, either.) + * table_get_latest_tid verified that the passed in tid is valid. Assume + * that t_ctid links are valid however - there shouldn't be invalid ones + * in the table. */ - blk = ItemPointerGetBlockNumber(tid); - if (blk >= RelationGetNumberOfBlocks(relation)) - elog(ERROR, "block number %u is out of range for relation \"%s\"", - blk, RelationGetRelationName(relation)); + Assert(ItemPointerIsValid(tid)); /* * Loop to chase down t_ctid links. At top of loop, ctid is the tuple we @@ -2295,8 +1746,8 @@ heap_get_latest_tid(Relation relation, } /* - * Check time qualification of tuple; if visible, set it as the new - * result candidate. + * Check tuple visibility; if visible, set it as the new result + * candidate. */ valid = HeapTupleSatisfiesVisibility(&tp, snapshot, buffer); CheckForSerializableConflictOut(valid, relation, &tp, buffer, snapshot); @@ -2401,43 +1852,19 @@ ReleaseBulkInsertStatePin(BulkInsertState bistate) * The new tuple is stamped with current transaction ID and the specified * command ID. * - * If the HEAP_INSERT_SKIP_WAL option is specified, the new tuple is not - * logged in WAL, even for a non-temp relation. Safe usage of this behavior - * requires that we arrange that all new tuples go into new pages not - * containing any tuples from other transactions, and that the relation gets - * fsync'd before commit. (See also heap_sync() comments) - * - * The HEAP_INSERT_SKIP_FSM option is passed directly to - * RelationGetBufferForTuple, which see for more info. - * - * HEAP_INSERT_FROZEN should only be specified for inserts into - * relfilenodes created during the current subtransaction and when - * there are no prior snapshots or pre-existing portals open. - * This causes rows to be frozen, which is an MVCC violation and - * requires explicit options chosen by user. - * - * HEAP_INSERT_SPECULATIVE is used on so-called "speculative insertions", - * which can be backed out afterwards without aborting the whole transaction. - * Other sessions can wait for the speculative insertion to be confirmed, - * turning it into a regular tuple, or aborted, as if it never existed. - * Speculatively inserted tuples behave as "value locks" of short duration, - * used to implement INSERT .. ON CONFLICT. + * See table_tuple_insert for comments about most of the input flags, except + * that this routine directly takes a tuple rather than a slot. * - * Note that most of these options will be applied when inserting into the - * heap's TOAST table, too, if the tuple requires any out-of-line data. Only - * HEAP_INSERT_SPECULATIVE is explicitly ignored, as the toast data does not - * partake in speculative insertion. + * There's corresponding HEAP_INSERT_ options to all the TABLE_INSERT_ + * options, and there additionally is HEAP_INSERT_SPECULATIVE which is used to + * implement table_tuple_insert_speculative(). * - * The BulkInsertState object (if any; bistate can be NULL for default - * behavior) is also just passed through to RelationGetBufferForTuple. - * - * The return value is the OID assigned to the tuple (either here or by the - * caller), or InvalidOid if no OID. The header fields of *tup are updated - * to match the stored tuple; in particular tup->t_self receives the actual - * TID where the tuple was stored. But note that any toasting of fields - * within the tuple data is NOT reflected into *tup. + * On return the header fields of *tup are updated to match the stored tuple; + * in particular tup->t_self receives the actual TID where the tuple was + * stored. But note that any toasting of fields within the tuple data is NOT + * reflected into *tup. */ -Oid +void heap_insert(Relation relation, HeapTuple tup, CommandId cid, int options, BulkInsertState bistate) { @@ -2448,8 +1875,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, bool all_visible_cleared = false; /* - * Fill in tuple header fields, assign an OID, and toast the tuple if - * necessary. + * Fill in tuple header fields and toast the tuple if necessary. * * Note: below this point, heaptup is the data we actually intend to store * into the relation; tup is the caller's original untoasted data. @@ -2551,7 +1977,8 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, * page write, so make sure it's included even if we take a full-page * image. (XXX We could alternatively store a pointer into the FPW). */ - if (RelationIsLogicallyLogged(relation)) + if (RelationIsLogicallyLogged(relation) && + !(options & HEAP_INSERT_NO_LOGICAL)) { xlrec.flags |= XLH_INSERT_CONTAINS_NEW_TUPLE; bufflags |= REGBUF_KEEP_DATA; @@ -2610,16 +2037,13 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid, tup->t_self = heaptup->t_self; heap_freetuple(heaptup); } - - return HeapTupleGetOid(tup); } /* * Subroutine for heap_insert(). Prepares a tuple for insertion. This sets the - * tuple header fields, assigns an OID, and toasts the tuple if necessary. - * Returns a toasted version of the tuple if it was toasted, or the original - * tuple if not. Note that in any case, the header fields are also set in - * the original tuple. + * tuple header fields and toasts the tuple if necessary. Returns a toasted + * version of the tuple if it was toasted, or the original tuple if not. Note + * that in any case, the header fields are also set in the original tuple. */ static HeapTuple heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, @@ -2638,30 +2062,6 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), errmsg("cannot insert tuples in a parallel worker"))); - if (relation->rd_rel->relhasoids) - { -#ifdef NOT_USED - /* this is redundant with an Assert in HeapTupleSetOid */ - Assert(tup->t_data->t_infomask & HEAP_HASOID); -#endif - - /* - * If the object id of this tuple has already been assigned, trust the - * caller. There are a couple of ways this can happen. At initial db - * creation, the backend program sets oids for tuples. When we define - * an index, we set the oid. Finally, in the future, we may allow - * users to set their own object ids in order to support a persistent - * object store (objects need to contain pointers to one another). - */ - if (!OidIsValid(HeapTupleGetOid(tup))) - HeapTupleSetOid(tup, GetNewOid(relation)); - } - else - { - /* check there is not space for an OID */ - Assert(!(tup->t_data->t_infomask & HEAP_HASOID)); - } - tup->t_data->t_infomask &= ~(HEAP_XACT_MASK); tup->t_data->t_infomask2 &= ~(HEAP2_XACT_MASK); tup->t_data->t_infomask |= HEAP_XMAX_INVALID; @@ -2702,37 +2102,39 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid, * temporary context before calling this, if that's a problem. */ void -heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, +heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples, CommandId cid, int options, BulkInsertState bistate) { TransactionId xid = GetCurrentTransactionId(); HeapTuple *heaptuples; int i; int ndone; - char *scratch = NULL; + PGAlignedBlock scratch; Page page; bool needwal; Size saveFreeSpace; bool need_tuple_data = RelationIsLogicallyLogged(relation); bool need_cids = RelationIsAccessibleInLogicalDecoding(relation); + /* currently not needed (thus unsupported) for heap_multi_insert() */ + AssertArg(!(options & HEAP_INSERT_NO_LOGICAL)); + needwal = !(options & HEAP_INSERT_SKIP_WAL) && RelationNeedsWAL(relation); saveFreeSpace = RelationGetTargetPageFreeSpace(relation, HEAP_DEFAULT_FILLFACTOR); - /* Toast and set header data in all the tuples */ + /* Toast and set header data in all the slots */ heaptuples = palloc(ntuples * sizeof(HeapTuple)); for (i = 0; i < ntuples; i++) - heaptuples[i] = heap_prepare_insert(relation, tuples[i], - xid, cid, options); + { + HeapTuple tuple; - /* - * Allocate some memory to use for constructing the WAL record. Using - * palloc() within a critical section is not safe, so we allocate this - * beforehand. - */ - if (needwal) - scratch = palloc(BLCKSZ); + tuple = ExecFetchSlotHeapTuple(slots[i], true, NULL); + slots[i]->tts_tableOid = RelationGetRelid(relation); + tuple->t_tableOid = slots[i]->tts_tableOid; + heaptuples[i] = heap_prepare_insert(relation, tuple, xid, cid, + options); + } /* * We're about to do the actual inserts -- but check for conflict first, @@ -2826,7 +2228,7 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, uint8 info = XLOG_HEAP2_MULTI_INSERT; char *tupledata; int totaldatalen; - char *scratchptr = scratch; + char *scratchptr = scratch.data; bool init; int bufflags = 0; @@ -2885,7 +2287,7 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, scratchptr += datalen; } totaldatalen = scratchptr - tupledata; - Assert((scratchptr - scratch) < BLCKSZ); + Assert((scratchptr - scratch.data) < BLCKSZ); if (need_tuple_data) xlrec->flags |= XLH_INSERT_CONTAINS_NEW_TUPLE; @@ -2912,7 +2314,7 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, bufflags |= REGBUF_KEEP_DATA; XLogBeginInsert(); - XLogRegisterData((char *) xlrec, tupledata - scratch); + XLogRegisterData((char *) xlrec, tupledata - scratch.data); XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags); XLogRegisterBufData(0, tupledata, totaldatalen); @@ -2962,13 +2364,9 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, CacheInvalidateHeapTuple(relation, heaptuples[i], NULL); } - /* - * Copy t_self fields back to the caller's original tuples. This does - * nothing for untoasted tuples (tuples[i] == heaptuples[i)], but it's - * probably faster to always copy than check. - */ + /* copy t_self fields back to the caller's slots */ for (i = 0; i < ntuples; i++) - tuples[i]->t_self = heaptuples[i]->t_self; + slots[i]->tts_tid = heaptuples[i]->t_self; pgstat_count_heap_insert(relation, ntuples); } @@ -2982,10 +2380,10 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, * This should be used rather than using heap_insert directly in most places * where we are modifying system catalogs. */ -Oid +void simple_heap_insert(Relation relation, HeapTuple tup) { - return heap_insert(relation, tup, GetCurrentCommandId(true), 0, NULL); + heap_insert(relation, tup, GetCurrentCommandId(true), 0, NULL); } /* @@ -3032,36 +2430,20 @@ xmax_infomask_changed(uint16 new_infomask, uint16 old_infomask) /* * heap_delete - delete a tuple * - * NB: do not call this directly unless you are prepared to deal with - * concurrent-update conditions. Use simple_heap_delete instead. - * - * relation - table to be modified (caller must hold suitable lock) - * tid - TID of tuple to be deleted - * cid - delete command ID (used for visibility test, and stored into - * cmax if successful) - * crosscheck - if not InvalidSnapshot, also check tuple against this - * wait - true if should wait for any conflicting update to commit/abort - * hufd - output parameter, filled in failure cases (see below) - * changingPart - true iff the tuple is being moved to another partition - * table due to an update of the partition key. Otherwise, false. + * See table_tuple_delete() for an explanation of the parameters, except that + * this routine directly takes a tuple rather than a slot. * - * Normal, successful return value is HeapTupleMayBeUpdated, which - * actually means we did delete it. Failure return codes are - * HeapTupleSelfUpdated, HeapTupleUpdated, or HeapTupleBeingUpdated - * (the last only possible if wait == false). - * - * In the failure cases, the routine fills *hufd with the tuple's t_ctid, - * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax - * (the last only for HeapTupleSelfUpdated, since we - * cannot obtain cmax from a combocid generated by another transaction). - * See comments for struct HeapUpdateFailureData for additional info. + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax (the last + * only for TM_SelfModified, since we cannot obtain cmax from a combocid + * generated by another transaction). */ -HTSU_Result +TM_Result heap_delete(Relation relation, ItemPointer tid, CommandId cid, Snapshot crosscheck, bool wait, - HeapUpdateFailureData *hufd, bool changingPart) + TM_FailureData *tmfd, bool changingPart) { - HTSU_Result result; + TM_Result result; TransactionId xid = GetCurrentTransactionId(); ItemId lp; HeapTupleData tp; @@ -3129,14 +2511,14 @@ heap_delete(Relation relation, ItemPointer tid, l1: result = HeapTupleSatisfiesUpdate(&tp, cid, buffer); - if (result == HeapTupleInvisible) + if (result == TM_Invisible) { UnlockReleaseBuffer(buffer); ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("attempted to delete invisible tuple"))); } - else if (result == HeapTupleBeingUpdated && wait) + else if (result == TM_BeingModified && wait) { TransactionId xwait; uint16 infomask; @@ -3160,15 +2542,20 @@ heap_delete(Relation relation, ItemPointer tid, */ if (infomask & HEAP_XMAX_IS_MULTI) { - /* wait for multixact */ + bool current_is_member = false; + if (DoesMultiXactIdConflict((MultiXactId) xwait, infomask, - LockTupleExclusive)) + LockTupleExclusive, ¤t_is_member)) { LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - /* acquire tuple lock, if necessary */ - heap_acquire_tuplock(relation, &(tp.t_self), LockTupleExclusive, - LockWaitBlock, &have_tuple_lock); + /* + * Acquire the lock, if necessary (but skip it when we're + * requesting a lock and already have one; avoids deadlock). + */ + if (!current_is_member) + heap_acquire_tuplock(relation, &(tp.t_self), LockTupleExclusive, + LockWaitBlock, &have_tuple_lock); /* wait for multixact */ MultiXactIdWait((MultiXactId) xwait, MultiXactStatusUpdate, infomask, @@ -3230,31 +2617,36 @@ heap_delete(Relation relation, ItemPointer tid, if ((tp.t_data->t_infomask & HEAP_XMAX_INVALID) || HEAP_XMAX_IS_LOCKED_ONLY(tp.t_data->t_infomask) || HeapTupleHeaderIsOnlyLocked(tp.t_data)) - result = HeapTupleMayBeUpdated; + result = TM_Ok; + else if (!ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tp.t_data)) + result = TM_Updated; else - result = HeapTupleUpdated; + result = TM_Deleted; } - if (crosscheck != InvalidSnapshot && result == HeapTupleMayBeUpdated) + if (crosscheck != InvalidSnapshot && result == TM_Ok) { /* Perform additional check for transaction-snapshot mode RI updates */ if (!HeapTupleSatisfiesVisibility(&tp, crosscheck, buffer)) - result = HeapTupleUpdated; + result = TM_Updated; } - if (result != HeapTupleMayBeUpdated) + if (result != TM_Ok) { - Assert(result == HeapTupleSelfUpdated || - result == HeapTupleUpdated || - result == HeapTupleBeingUpdated); + Assert(result == TM_SelfModified || + result == TM_Updated || + result == TM_Deleted || + result == TM_BeingModified); Assert(!(tp.t_data->t_infomask & HEAP_XMAX_INVALID)); - hufd->result = result; - hufd->ctid = tp.t_data->t_ctid; - hufd->xmax = HeapTupleHeaderGetUpdateXid(tp.t_data); - if (result == HeapTupleSelfUpdated) - hufd->cmax = HeapTupleHeaderGetCmax(tp.t_data); + Assert(result != TM_Updated || + !ItemPointerEquals(&tp.t_self, &tp.t_data->t_ctid)); + tmfd->ctid = tp.t_data->t_ctid; + tmfd->xmax = HeapTupleHeaderGetUpdateXid(tp.t_data); + if (result == TM_SelfModified) + tmfd->cmax = HeapTupleHeaderGetCmax(tp.t_data); else - hufd->cmax = InvalidCommandId; + tmfd->cmax = InvalidCommandId; UnlockReleaseBuffer(buffer); if (have_tuple_lock) UnlockTupleTuplock(relation, &(tp.t_self), LockTupleExclusive); @@ -3343,6 +2735,7 @@ heap_delete(Relation relation, ItemPointer tid, if (RelationNeedsWAL(relation)) { xl_heap_delete xlrec; + xl_heap_header xlhdr; XLogRecPtr recptr; /* For logical decode we need combocids to properly decode the catalog */ @@ -3377,8 +2770,6 @@ heap_delete(Relation relation, ItemPointer tid, */ if (old_key_tuple != NULL) { - xl_heap_header xlhdr; - xlhdr.t_infomask2 = old_key_tuple->t_data->t_infomask2; xlhdr.t_infomask = old_key_tuple->t_data->t_infomask; xlhdr.t_hoff = old_key_tuple->t_data->t_hoff; @@ -3441,7 +2832,7 @@ heap_delete(Relation relation, ItemPointer tid, if (old_key_tuple != NULL && old_key_copied) heap_freetuple(old_key_tuple); - return HeapTupleMayBeUpdated; + return TM_Ok; } /* @@ -3455,28 +2846,32 @@ heap_delete(Relation relation, ItemPointer tid, void simple_heap_delete(Relation relation, ItemPointer tid) { - HTSU_Result result; - HeapUpdateFailureData hufd; + TM_Result result; + TM_FailureData tmfd; result = heap_delete(relation, tid, GetCurrentCommandId(true), InvalidSnapshot, true /* wait for commit */ , - &hufd, false /* changingPart */); + &tmfd, false /* changingPart */ ); switch (result) { - case HeapTupleSelfUpdated: + case TM_SelfModified: /* Tuple was already updated in current command? */ elog(ERROR, "tuple already updated by self"); break; - case HeapTupleMayBeUpdated: + case TM_Ok: /* done successfully */ break; - case HeapTupleUpdated: + case TM_Updated: elog(ERROR, "tuple concurrently updated"); break; + case TM_Deleted: + elog(ERROR, "tuple concurrently deleted"); + break; + default: elog(ERROR, "unrecognized heap_delete status: %u", result); break; @@ -3486,45 +2881,22 @@ simple_heap_delete(Relation relation, ItemPointer tid) /* * heap_update - replace a tuple * - * NB: do not call this directly unless you are prepared to deal with - * concurrent-update conditions. Use simple_heap_update instead. - * - * relation - table to be modified (caller must hold suitable lock) - * otid - TID of old tuple to be replaced - * newtup - newly constructed tuple data to store - * cid - update command ID (used for visibility test, and stored into - * cmax/cmin if successful) - * crosscheck - if not InvalidSnapshot, also check old tuple against this - * wait - true if should wait for any conflicting update to commit/abort - * hufd - output parameter, filled in failure cases (see below) - * lockmode - output parameter, filled with lock mode acquired on tuple - * - * Normal, successful return value is HeapTupleMayBeUpdated, which - * actually means we *did* update it. Failure return codes are - * HeapTupleSelfUpdated, HeapTupleUpdated, or HeapTupleBeingUpdated - * (the last only possible if wait == false). + * See table_tuple_update() for an explanation of the parameters, except that + * this routine directly takes a tuple rather than a slot. * - * On success, the header fields of *newtup are updated to match the new - * stored tuple; in particular, newtup->t_self is set to the TID where the - * new tuple was inserted, and its HEAP_ONLY_TUPLE flag is set iff a HOT - * update was done. However, any TOAST changes in the new tuple's - * data are not reflected into *newtup. - * - * In the failure cases, the routine fills *hufd with the tuple's t_ctid, - * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax - * (the last only for HeapTupleSelfUpdated, since we - * cannot obtain cmax from a combocid generated by another transaction). - * See comments for struct HeapUpdateFailureData for additional info. + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax (resolving a possible MultiXact, if necessary), and t_cmax (the last + * only for TM_SelfModified, since we cannot obtain cmax from a combocid + * generated by another transaction). */ -HTSU_Result +TM_Result heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, CommandId cid, Snapshot crosscheck, bool wait, - HeapUpdateFailureData *hufd) + TM_FailureData *tmfd, LockTupleMode *lockmode) { - HTSU_Result result; + TM_Result result; TransactionId xid = GetCurrentTransactionId(); Bitmapset *hot_attrs; - Bitmapset *proj_idx_attrs; Bitmapset *key_attrs; Bitmapset *id_attrs; Bitmapset *interesting_attrs; @@ -3559,10 +2931,8 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, infomask2_old_tuple, infomask_new_tuple, infomask2_new_tuple; - LockTupleMode lockmode; Assert(ItemPointerIsValid(otid)); - Assert(hufd != NULL); /* * Forbid this during a parallel operation, lest it allocate a combocid. @@ -3590,11 +2960,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * Note that we get copies of each bitmap, so we need not worry about * relcache flush happening midway through. */ - hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_HOT); - proj_idx_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_PROJ); + hot_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_ALL); key_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_KEY); id_attrs = RelationGetIndexAttrBitmap(relation, INDEX_ATTR_BITMAP_IDENTITY_KEY); + + block = ItemPointerGetBlockNumber(otid); buffer = ReadBuffer(relation, block); page = BufferGetPage(buffer); @@ -3614,7 +2985,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, if (!PageIsFull(page)) { interesting_attrs = bms_add_members(interesting_attrs, hot_attrs); - interesting_attrs = bms_add_members(interesting_attrs, proj_idx_attrs); hot_attrs_checked = true; } interesting_attrs = bms_add_members(interesting_attrs, key_attrs); @@ -3646,21 +3016,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, /* the new tuple is ready, except for this: */ newtup->t_tableOid = RelationGetRelid(relation); - /* Fill in OID for newtup */ - if (relation->rd_rel->relhasoids) - { -#ifdef NOT_USED - /* this is redundant with an Assert in HeapTupleSetOid */ - Assert(newtup->t_data->t_infomask & HEAP_HASOID); -#endif - HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup)); - } - else - { - /* check there is not space for an OID */ - Assert(!(newtup->t_data->t_infomask & HEAP_HASOID)); - } - /* Determine columns modified by the update. */ modified_attrs = HeapDetermineModifiedColumns(relation, interesting_attrs, &oldtup, newtup); @@ -3674,11 +3029,11 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * the value ends up being the same, this test will fail and we will use * the stronger lock. This is acceptable; the important case to optimize * is updates that don't manipulate key columns, not those that - * serendipitiously arrive at the same key values. + * serendipitously arrive at the same key values. */ if (!bms_overlap(modified_attrs, key_attrs)) { - lockmode = hufd->lockmode = LockTupleNoKeyExclusive; + *lockmode = LockTupleNoKeyExclusive; mxact_status = MultiXactStatusNoKeyUpdate; key_intact = true; @@ -3695,7 +3050,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, } else { - lockmode = hufd->lockmode = LockTupleExclusive; + *lockmode = LockTupleExclusive; mxact_status = MultiXactStatusUpdate; key_intact = false; } @@ -3713,16 +3068,16 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, result = HeapTupleSatisfiesUpdate(&oldtup, cid, buffer); /* see below about the "no wait" case */ - Assert(result != HeapTupleBeingUpdated || wait); + Assert(result != TM_BeingModified || wait); - if (result == HeapTupleInvisible) + if (result == TM_Invisible) { UnlockReleaseBuffer(buffer); ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("attempted to update invisible tuple"))); } - else if (result == HeapTupleBeingUpdated && wait) + else if (result == TM_BeingModified && wait) { TransactionId xwait; uint16 infomask; @@ -3771,15 +3126,20 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, { TransactionId update_xact; int remain; + bool current_is_member = false; if (DoesMultiXactIdConflict((MultiXactId) xwait, infomask, - lockmode)) + *lockmode, ¤t_is_member)) { LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - /* acquire tuple lock, if necessary */ - heap_acquire_tuplock(relation, &(oldtup.t_self), lockmode, - LockWaitBlock, &have_tuple_lock); + /* + * Acquire the lock, if necessary (but skip it when we're + * requesting a lock and already have one; avoids deadlock). + */ + if (!current_is_member) + heap_acquire_tuplock(relation, &(oldtup.t_self), *lockmode, + LockWaitBlock, &have_tuple_lock); /* wait for multixact */ MultiXactIdWait((MultiXactId) xwait, mxact_status, infomask, @@ -3805,15 +3165,16 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * Note that the multixact may not be done by now. It could have * surviving members; our own xact or other subxacts of this * backend, and also any other concurrent transaction that locked - * the tuple with KeyShare if we only got TupleLockUpdate. If - * this is the case, we have to be careful to mark the updated - * tuple with the surviving members in Xmax. + * the tuple with LockTupleKeyShare if we only got + * LockTupleNoKeyExclusive. If this is the case, we have to be + * careful to mark the updated tuple with the surviving members in + * Xmax. * * Note that there could have been another update in the * MultiXact. In that case, we need to check whether it committed * or aborted. If it aborted we are safe to update it again; * otherwise there is an update conflict, and we have to return - * HeapTupleUpdated below. + * TableTuple{Deleted, Updated} below. * * In the LockTupleExclusive case, we still need to preserve the * surviving members: those would include the tuple locks we had @@ -3862,7 +3223,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * lock. */ LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - heap_acquire_tuplock(relation, &(oldtup.t_self), lockmode, + heap_acquire_tuplock(relation, &(oldtup.t_self), *lockmode, LockWaitBlock, &have_tuple_lock); XactLockTableWait(xwait, relation, &oldtup.t_self, XLTW_Update); @@ -3885,36 +3246,46 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, can_continue = true; } - result = can_continue ? HeapTupleMayBeUpdated : HeapTupleUpdated; + if (can_continue) + result = TM_Ok; + else if (!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(oldtup.t_data)) + result = TM_Updated; + else + result = TM_Deleted; } - if (crosscheck != InvalidSnapshot && result == HeapTupleMayBeUpdated) + if (crosscheck != InvalidSnapshot && result == TM_Ok) { /* Perform additional check for transaction-snapshot mode RI updates */ if (!HeapTupleSatisfiesVisibility(&oldtup, crosscheck, buffer)) - result = HeapTupleUpdated; + { + result = TM_Updated; + Assert(!ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid)); + } } - if (result != HeapTupleMayBeUpdated) + if (result != TM_Ok) { - Assert(result == HeapTupleSelfUpdated || - result == HeapTupleUpdated || - result == HeapTupleBeingUpdated); + Assert(result == TM_SelfModified || + result == TM_Updated || + result == TM_Deleted || + result == TM_BeingModified); Assert(!(oldtup.t_data->t_infomask & HEAP_XMAX_INVALID)); - hufd->result = result; - hufd->ctid = oldtup.t_data->t_ctid; - hufd->xmax = HeapTupleHeaderGetUpdateXid(oldtup.t_data); - if (result == HeapTupleSelfUpdated) - hufd->cmax = HeapTupleHeaderGetCmax(oldtup.t_data); + Assert(result != TM_Updated || + !ItemPointerEquals(&oldtup.t_self, &oldtup.t_data->t_ctid)); + tmfd->ctid = oldtup.t_data->t_ctid; + tmfd->xmax = HeapTupleHeaderGetUpdateXid(oldtup.t_data); + if (result == TM_SelfModified) + tmfd->cmax = HeapTupleHeaderGetCmax(oldtup.t_data); else - hufd->cmax = InvalidCommandId; + tmfd->cmax = InvalidCommandId; UnlockReleaseBuffer(buffer); if (have_tuple_lock) - UnlockTupleTuplock(relation, &(oldtup.t_self), lockmode); + UnlockTupleTuplock(relation, &(oldtup.t_self), *lockmode); if (vmbuffer != InvalidBuffer) ReleaseBuffer(vmbuffer); bms_free(hot_attrs); - bms_free(proj_idx_attrs); bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); @@ -3948,7 +3319,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, compute_new_xmax_infomask(HeapTupleHeaderGetRawXmax(oldtup.t_data), oldtup.t_data->t_infomask, oldtup.t_data->t_infomask2, - xid, lockmode, true, + xid, *lockmode, true, &xmax_old_tuple, &infomask_old_tuple, &infomask2_old_tuple); @@ -4065,7 +3436,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, compute_new_xmax_infomask(HeapTupleHeaderGetRawXmax(oldtup.t_data), oldtup.t_data->t_infomask, oldtup.t_data->t_infomask2, - xid, lockmode, false, + xid, *lockmode, false, &xmax_lock_old_tuple, &infomask_lock_old_tuple, &infomask2_lock_old_tuple); @@ -4222,18 +3593,11 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, /* * Since the new tuple is going into the same page, we might be able * to do a HOT update. Check if any of the index columns have been - * changed, or if we have projection functional indexes, check whether - * the old and the new values are the same. If the page was already - * full, we may have skipped checking for index columns. If so, HOT - * update is possible. + * changed. If the page was already full, we may have skipped checking + * for index columns, and also can't do a HOT update. */ - if (hot_attrs_checked - && !bms_overlap(modified_attrs, hot_attrs) - && (!bms_overlap(modified_attrs, proj_idx_attrs) - || ProjIndexIsUnchanged(relation, &oldtup, newtup))) - { + if (hot_attrs_checked && !bms_overlap(modified_attrs, hot_attrs)) use_hot_update = true; - } } else { @@ -4377,7 +3741,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, * Release the lmgr tuple lock, if we had it. */ if (have_tuple_lock) - UnlockTupleTuplock(relation, &(oldtup.t_self), lockmode); + UnlockTupleTuplock(relation, &(oldtup.t_self), *lockmode); pgstat_count_heap_update(relation, use_hot_update); @@ -4395,13 +3759,12 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, heap_freetuple(old_key_tuple); bms_free(hot_attrs); - bms_free(proj_idx_attrs); bms_free(key_attrs); bms_free(id_attrs); bms_free(modified_attrs); bms_free(interesting_attrs); - return HeapTupleMayBeUpdated; + return TM_Ok; } /* @@ -4428,13 +3791,12 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum, /* * Likewise, automatically say "not equal" for any system attribute other - * than OID and tableOID; we cannot expect these to be consistent in a HOT - * chain, or even to be set correctly yet in the new tuple. + * than tableOID; we cannot expect these to be consistent in a HOT chain, + * or even to be set correctly yet in the new tuple. */ if (attrnum < 0) { - if (attrnum != ObjectIdAttributeNumber && - attrnum != TableOidAttributeNumber) + if (attrnum != TableOidAttributeNumber) return false; } @@ -4482,83 +3844,6 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum, } } -/* - * Check whether the value is unchanged after update of a projection - * functional index. Compare the new and old values of the indexed - * expression to see if we are able to use a HOT update or not. - */ -static bool ProjIndexIsUnchanged(Relation relation, HeapTuple oldtup, HeapTuple newtup) -{ - ListCell *l; - List *indexoidlist = RelationGetIndexList(relation); - EState *estate = CreateExecutorState(); - ExprContext *econtext = GetPerTupleExprContext(estate); - TupleTableSlot *slot = MakeSingleTupleTableSlot(RelationGetDescr(relation)); - bool equals = true; - Datum old_values[INDEX_MAX_KEYS]; - bool old_isnull[INDEX_MAX_KEYS]; - Datum new_values[INDEX_MAX_KEYS]; - bool new_isnull[INDEX_MAX_KEYS]; - int indexno = 0; - econtext->ecxt_scantuple = slot; - - foreach(l, indexoidlist) - { - if (bms_is_member(indexno, relation->rd_projidx)) - { - Oid indexOid = lfirst_oid(l); - Relation indexDesc = index_open(indexOid, AccessShareLock); - IndexInfo *indexInfo = BuildIndexInfo(indexDesc); - int i; - - ResetExprContext(econtext); - ExecStoreTuple(oldtup, slot, InvalidBuffer, false); - FormIndexDatum(indexInfo, - slot, - estate, - old_values, - old_isnull); - - ExecStoreTuple(newtup, slot, InvalidBuffer, false); - FormIndexDatum(indexInfo, - slot, - estate, - new_values, - new_isnull); - - for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) - { - if (old_isnull[i] != new_isnull[i]) - { - equals = false; - break; - } - else if (!old_isnull[i]) - { - Form_pg_attribute att = TupleDescAttr(RelationGetDescr(indexDesc), i); - if (!datumIsEqual(old_values[i], new_values[i], att->attbyval, att->attlen)) - { - equals = false; - break; - } - } - } - index_close(indexDesc, AccessShareLock); - - if (!equals) - { - break; - } - } - indexno += 1; - } - ExecDropSingleTupleTableSlot(slot); - FreeExecutorState(estate); - - return equals; -} - - /* * Check which columns are being updated. * @@ -4599,28 +3884,33 @@ HeapDetermineModifiedColumns(Relation relation, Bitmapset *interesting_cols, void simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup) { - HTSU_Result result; - HeapUpdateFailureData hufd; + TM_Result result; + TM_FailureData tmfd; + LockTupleMode lockmode; result = heap_update(relation, otid, tup, GetCurrentCommandId(true), InvalidSnapshot, true /* wait for commit */ , - &hufd); + &tmfd, &lockmode); switch (result) { - case HeapTupleSelfUpdated: + case TM_SelfModified: /* Tuple was already updated in current command? */ elog(ERROR, "tuple already updated by self"); break; - case HeapTupleMayBeUpdated: + case TM_Ok: /* done successfully */ break; - case HeapTupleUpdated: + case TM_Updated: elog(ERROR, "tuple concurrently updated"); break; + case TM_Deleted: + elog(ERROR, "tuple concurrently deleted"); + break; + default: elog(ERROR, "unrecognized heap_update status: %u", result); break; @@ -4655,7 +3945,7 @@ get_mxact_status_for_lock(LockTupleMode mode, bool is_update) * * Input parameters: * relation: relation containing tuple (caller must hold suitable lock) - * tuple->t_self: TID of tuple to lock (rest of struct need not be valid) + * tid: TID of tuple to lock * cid: current command ID (used for visibility test, and stored into * tuple's cmax if lock is successful) * mode: indicates if shared or exclusive tuple lock is desired @@ -4666,31 +3956,26 @@ get_mxact_status_for_lock(LockTupleMode mode, bool is_update) * Output parameters: * *tuple: all fields filled in * *buffer: set to buffer holding tuple (pinned but not locked at exit) - * *hufd: filled in failure cases (see below) + * *tmfd: filled in failure cases (see below) * - * Function result may be: - * HeapTupleMayBeUpdated: lock was successfully acquired - * HeapTupleInvisible: lock failed because tuple was never visible to us - * HeapTupleSelfUpdated: lock failed because tuple updated by self - * HeapTupleUpdated: lock failed because tuple updated by other xact - * HeapTupleWouldBlock: lock couldn't be acquired and wait_policy is skip + * Function results are the same as the ones for table_tuple_lock(). * - * In the failure cases other than HeapTupleInvisible, the routine fills - * *hufd with the tuple's t_ctid, t_xmax (resolving a possible MultiXact, - * if necessary), and t_cmax (the last only for HeapTupleSelfUpdated, + * In the failure cases other than TM_Invisible, the routine fills + * *tmfd with the tuple's t_ctid, t_xmax (resolving a possible MultiXact, + * if necessary), and t_cmax (the last only for TM_SelfModified, * since we cannot obtain cmax from a combocid generated by another * transaction). - * See comments for struct HeapUpdateFailureData for additional info. + * See comments for struct TM_FailureData for additional info. * * See README.tuplock for a thorough explanation of this mechanism. */ -HTSU_Result +TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, bool follow_updates, - Buffer *buffer, HeapUpdateFailureData *hufd) + Buffer *buffer, TM_FailureData *tmfd) { - HTSU_Result result; + TM_Result result; ItemPointer tid = &(tuple->t_self); ItemId lp; Page page; @@ -4702,6 +3987,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, new_infomask, new_infomask2; bool first_time = true; + bool skip_tuple_lock = false; bool have_tuple_lock = false; bool cleared_all_frozen = false; @@ -4730,7 +4016,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, l3: result = HeapTupleSatisfiesUpdate(tuple, cid, *buffer); - if (result == HeapTupleInvisible) + if (result == TM_Invisible) { /* * This is possible, but only when locking a tuple for ON CONFLICT @@ -4738,10 +4024,12 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, * order to give that case the opportunity to throw a more specific * error. */ - result = HeapTupleInvisible; + result = TM_Invisible; goto out_locked; } - else if (result == HeapTupleBeingUpdated || result == HeapTupleUpdated) + else if (result == TM_BeingModified || + result == TM_Updated || + result == TM_Deleted) { TransactionId xwait; uint16 infomask; @@ -4797,9 +4085,24 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, if (TUPLOCK_from_mxstatus(members[i].status) >= mode) { pfree(members); - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; } + else + { + /* + * Disable acquisition of the heavyweight tuple lock. + * Otherwise, when promoting a weaker lock, we might + * deadlock with another locker that has acquired the + * heavyweight tuple lock and is waiting for our + * transaction to finish. + * + * Note that in this case we still need to wait for + * the multixact if required, to avoid acquiring + * conflicting locks. + */ + skip_tuple_lock = true; + } } if (members) @@ -4813,20 +4116,20 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, Assert(HEAP_XMAX_IS_KEYSHR_LOCKED(infomask) || HEAP_XMAX_IS_SHR_LOCKED(infomask) || HEAP_XMAX_IS_EXCL_LOCKED(infomask)); - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; case LockTupleShare: if (HEAP_XMAX_IS_SHR_LOCKED(infomask) || HEAP_XMAX_IS_EXCL_LOCKED(infomask)) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; } break; case LockTupleNoKeyExclusive: if (HEAP_XMAX_IS_EXCL_LOCKED(infomask)) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; } break; @@ -4834,7 +4137,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, if (HEAP_XMAX_IS_EXCL_LOCKED(infomask) && infomask2 & HEAP_KEYS_UPDATED) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; } break; @@ -4883,12 +4186,12 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, */ if (follow_updates && updated) { - HTSU_Result res; + TM_Result res; res = heap_lock_updated_tuple(relation, tuple, &t_ctid, GetCurrentTransactionId(), mode); - if (res != HeapTupleMayBeUpdated) + if (res != TM_Ok) { result = res; /* recovery code expects to have buffer lock held */ @@ -4954,7 +4257,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, if (infomask & HEAP_XMAX_IS_MULTI) { if (!DoesMultiXactIdConflict((MultiXactId) xwait, infomask, - mode)) + mode, NULL)) { /* * No conflict, but if the xmax changed under us in the @@ -5013,15 +4316,15 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, /* * Time to sleep on the other transaction/multixact, if necessary. * - * If the other transaction is an update that's already committed, - * then sleeping cannot possibly do any good: if we're required to - * sleep, get out to raise an error instead. + * If the other transaction is an update/delete that's already + * committed, then sleeping cannot possibly do any good: if we're + * required to sleep, get out to raise an error instead. * * By here, we either have already acquired the buffer exclusive lock, * or we must wait for the locking transaction or multixact; so below * we ensure that we grab buffer lock after the sleep. */ - if (require_sleep && result == HeapTupleUpdated) + if (require_sleep && (result == TM_Updated || result == TM_Deleted)) { LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); goto failed; @@ -5031,20 +4334,22 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, /* * Acquire tuple lock to establish our priority for the tuple, or * die trying. LockTuple will release us when we are next-in-line - * for the tuple. We must do this even if we are share-locking. + * for the tuple. We must do this even if we are share-locking, + * but not if we already have a weaker lock on the tuple. * * If we are forced to "start over" below, we keep the tuple lock; * this arranges that we stay at the head of the line while * rechecking tuple state. */ - if (!heap_acquire_tuplock(relation, tid, mode, wait_policy, + if (!skip_tuple_lock && + !heap_acquire_tuplock(relation, tid, mode, wait_policy, &have_tuple_lock)) { /* * This can only happen if wait_policy is Skip and the lock * couldn't be obtained. */ - result = HeapTupleWouldBlock; + result = TM_WouldBlock; /* recovery code expects to have buffer lock held */ LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); goto failed; @@ -5070,7 +4375,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, status, infomask, relation, NULL)) { - result = HeapTupleWouldBlock; + result = TM_WouldBlock; /* recovery code expects to have buffer lock held */ LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); goto failed; @@ -5110,7 +4415,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, case LockWaitSkip: if (!ConditionalXactLockTableWait(xwait)) { - result = HeapTupleWouldBlock; + result = TM_WouldBlock; /* recovery code expects to have buffer lock held */ LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE); goto failed; @@ -5129,12 +4434,12 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, /* if there are updates, follow the update chain */ if (follow_updates && !HEAP_XMAX_IS_LOCKED_ONLY(infomask)) { - HTSU_Result res; + TM_Result res; res = heap_lock_updated_tuple(relation, tuple, &t_ctid, GetCurrentTransactionId(), mode); - if (res != HeapTupleMayBeUpdated) + if (res != TM_Ok) { result = res; /* recovery code expects to have buffer lock held */ @@ -5180,24 +4485,28 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, (tuple->t_data->t_infomask & HEAP_XMAX_INVALID) || HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_data->t_infomask) || HeapTupleHeaderIsOnlyLocked(tuple->t_data)) - result = HeapTupleMayBeUpdated; + result = TM_Ok; + else if (!ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tuple->t_data)) + result = TM_Updated; else - result = HeapTupleUpdated; + result = TM_Deleted; } failed: - if (result != HeapTupleMayBeUpdated) + if (result != TM_Ok) { - Assert(result == HeapTupleSelfUpdated || result == HeapTupleUpdated || - result == HeapTupleWouldBlock); + Assert(result == TM_SelfModified || result == TM_Updated || + result == TM_Deleted || result == TM_WouldBlock); Assert(!(tuple->t_data->t_infomask & HEAP_XMAX_INVALID)); - hufd->result = result; - hufd->ctid = tuple->t_data->t_ctid; - hufd->xmax = HeapTupleHeaderGetUpdateXid(tuple->t_data); - if (result == HeapTupleSelfUpdated) - hufd->cmax = HeapTupleHeaderGetCmax(tuple->t_data); + Assert(result != TM_Updated || + !ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid)); + tmfd->ctid = tuple->t_data->t_ctid; + tmfd->xmax = HeapTupleHeaderGetUpdateXid(tuple->t_data); + if (result == TM_SelfModified) + tmfd->cmax = HeapTupleHeaderGetCmax(tuple->t_data); else - hufd->cmax = InvalidCommandId; + tmfd->cmax = InvalidCommandId; goto out_locked; } @@ -5315,7 +4624,7 @@ heap_lock_tuple(Relation relation, HeapTuple tuple, END_CRIT_SECTION(); - result = HeapTupleMayBeUpdated; + result = TM_Ok; out_locked: LockBuffer(*buffer, BUFFER_LOCK_UNLOCK); @@ -5672,19 +4981,19 @@ compute_new_xmax_infomask(TransactionId xmax, uint16 old_infomask, * Given a hypothetical multixact status held by the transaction identified * with the given xid, does the current transaction need to wait, fail, or can * it continue if it wanted to acquire a lock of the given mode? "needwait" - * is set to true if waiting is necessary; if it can continue, then - * HeapTupleMayBeUpdated is returned. If the lock is already held by the - * current transaction, return HeapTupleSelfUpdated. In case of a conflict - * with another transaction, a different HeapTupleSatisfiesUpdate return code - * is returned. + * is set to true if waiting is necessary; if it can continue, then TM_Ok is + * returned. If the lock is already held by the current transaction, return + * TM_SelfModified. In case of a conflict with another transaction, a + * different HeapTupleSatisfiesUpdate return code is returned. * * The held status is said to be hypothetical because it might correspond to a * lock held by a single Xid, i.e. not a real MultiXactId; we express it this * way for simplicity of API. */ -static HTSU_Result +static TM_Result test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, - LockTupleMode mode, bool *needwait) + LockTupleMode mode, HeapTuple tup, + bool *needwait) { MultiXactStatus wantedstatus; @@ -5693,8 +5002,8 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, /* * Note: we *must* check TransactionIdIsInProgress before - * TransactionIdDidAbort/Commit; see comment at top of tqual.c for an - * explanation. + * TransactionIdDidAbort/Commit; see comment at top of heapam_visibility.c + * for an explanation. */ if (TransactionIdIsCurrentTransactionId(xid)) { @@ -5703,7 +5012,7 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, * very rare but can happen if multiple transactions are trying to * lock an ancient version of the same tuple. */ - return HeapTupleSelfUpdated; + return TM_SelfModified; } else if (TransactionIdIsInProgress(xid)) { @@ -5723,10 +5032,10 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, * If we set needwait above, then this value doesn't matter; * otherwise, this value signals to caller that it's okay to proceed. */ - return HeapTupleMayBeUpdated; + return TM_Ok; } else if (TransactionIdDidAbort(xid)) - return HeapTupleMayBeUpdated; + return TM_Ok; else if (TransactionIdDidCommit(xid)) { /* @@ -5745,18 +5054,24 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, * always be checked. */ if (!ISUPDATE_from_mxstatus(status)) - return HeapTupleMayBeUpdated; + return TM_Ok; if (DoLockModesConflict(LOCKMODE_from_mxstatus(status), LOCKMODE_from_mxstatus(wantedstatus))) + { /* bummer */ - return HeapTupleUpdated; + if (!ItemPointerEquals(&tup->t_self, &tup->t_data->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tup->t_data)) + return TM_Updated; + else + return TM_Deleted; + } - return HeapTupleMayBeUpdated; + return TM_Ok; } /* Not in progress, not aborted, not committed -- must have crashed */ - return HeapTupleMayBeUpdated; + return TM_Ok; } @@ -5767,11 +5082,11 @@ test_lockmode_for_conflict(MultiXactStatus status, TransactionId xid, * xid with the given mode; if this tuple is updated, recurse to lock the new * version as well. */ -static HTSU_Result +static TM_Result heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, LockTupleMode mode) { - HTSU_Result result; + TM_Result result; ItemPointerData tupid; HeapTupleData mytup; Buffer buf; @@ -5796,7 +5111,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, block = ItemPointerGetBlockNumber(&tupid); ItemPointerCopy(&tupid, &(mytup.t_self)); - if (!heap_fetch(rel, SnapshotAny, &mytup, &buf, false, NULL)) + if (!heap_fetch(rel, SnapshotAny, &mytup, &buf)) { /* * if we fail to find the updated version of the tuple, it's @@ -5805,7 +5120,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, * chain, and there's no further tuple to lock: return success to * caller. */ - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_unlocked; } @@ -5854,7 +5169,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, !TransactionIdEquals(HeapTupleHeaderGetXmin(mytup.t_data), priorXmax)) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_locked; } @@ -5865,7 +5180,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, */ if (TransactionIdDidAbort(HeapTupleHeaderGetXmin(mytup.t_data))) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_locked; } @@ -5908,7 +5223,9 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, { result = test_lockmode_for_conflict(members[i].status, members[i].xid, - mode, &needwait); + mode, + &mytup, + &needwait); /* * If the tuple was already locked by ourselves in a @@ -5920,7 +5237,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, * this tuple and continue locking the next version in the * update chain. */ - if (result == HeapTupleSelfUpdated) + if (result == TM_SelfModified) { pfree(members); goto next; @@ -5935,7 +5252,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, pfree(members); goto l4; } - if (result != HeapTupleMayBeUpdated) + if (result != TM_Ok) { pfree(members); goto out_locked; @@ -5985,7 +5302,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, } result = test_lockmode_for_conflict(status, rawxmax, mode, - &needwait); + &mytup, &needwait); /* * If the tuple was already locked by ourselves in a previous @@ -5996,7 +5313,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, * either. We just need to skip this tuple and continue * locking the next version in the update chain. */ - if (result == HeapTupleSelfUpdated) + if (result == TM_SelfModified) goto next; if (needwait) @@ -6006,7 +5323,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, XLTW_LockUpdated); goto l4; } - if (result != HeapTupleMayBeUpdated) + if (result != TM_Ok) { goto out_locked; } @@ -6066,7 +5383,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, ItemPointerEquals(&mytup.t_self, &mytup.t_data->t_ctid) || HeapTupleHeaderIsOnlyLocked(mytup.t_data)) { - result = HeapTupleMayBeUpdated; + result = TM_Ok; goto out_locked; } @@ -6076,7 +5393,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, UnlockReleaseBuffer(buf); } - result = HeapTupleMayBeUpdated; + result = TM_Ok; out_locked: UnlockReleaseBuffer(buf); @@ -6110,7 +5427,7 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid, * transaction cannot be using repeatable read or serializable isolation * levels, because that would lead to a serializability failure. */ -static HTSU_Result +static TM_Result heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid, TransactionId xid, LockTupleMode mode) { @@ -6136,7 +5453,7 @@ heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid, } /* nothing to lock */ - return HeapTupleMayBeUpdated; + return TM_Ok; } /* @@ -6156,7 +5473,7 @@ heap_lock_updated_tuple(Relation rel, HeapTuple tuple, ItemPointer ctid, * An explicit confirmation WAL record also makes logical decoding simpler. */ void -heap_finish_speculative(Relation relation, HeapTuple tuple) +heap_finish_speculative(Relation relation, ItemPointer tid) { Buffer buffer; Page page; @@ -6164,11 +5481,11 @@ heap_finish_speculative(Relation relation, HeapTuple tuple) ItemId lp = NULL; HeapTupleHeader htup; - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&(tuple->t_self))); + buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); page = (Page) BufferGetPage(buffer); - offnum = ItemPointerGetOffsetNumber(&(tuple->t_self)); + offnum = ItemPointerGetOffsetNumber(tid); if (PageGetMaxOffsetNumber(page) >= offnum) lp = PageGetItemId(page, offnum); @@ -6184,7 +5501,7 @@ heap_finish_speculative(Relation relation, HeapTuple tuple) /* NO EREPORT(ERROR) from here till changes are logged */ START_CRIT_SECTION(); - Assert(HeapTupleHeaderIsSpeculative(tuple->t_data)); + Assert(HeapTupleHeaderIsSpeculative(htup)); MarkBufferDirty(buffer); @@ -6192,7 +5509,7 @@ heap_finish_speculative(Relation relation, HeapTuple tuple) * Replace the speculative insertion token with a real t_ctid, pointing to * itself like it does on regular tuples. */ - htup->t_ctid = tuple->t_self; + htup->t_ctid = *tid; /* XLOG stuff */ if (RelationNeedsWAL(relation)) @@ -6200,7 +5517,7 @@ heap_finish_speculative(Relation relation, HeapTuple tuple) xl_heap_confirm xlrec; XLogRecPtr recptr; - xlrec.offnum = ItemPointerGetOffsetNumber(&tuple->t_self); + xlrec.offnum = ItemPointerGetOffsetNumber(tid); XLogBeginInsert(); @@ -6247,10 +5564,9 @@ heap_finish_speculative(Relation relation, HeapTuple tuple) * confirmation records. */ void -heap_abort_speculative(Relation relation, HeapTuple tuple) +heap_abort_speculative(Relation relation, ItemPointer tid) { TransactionId xid = GetCurrentTransactionId(); - ItemPointer tid = &(tuple->t_self); ItemId lp; HeapTupleData tp; Page page; @@ -6537,8 +5853,8 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, /* * This old multi cannot possibly have members still running, but * verify just in case. If it was a locker only, it can be removed - * without any further consideration; but if it contained an update, we - * might need to preserve it. + * without any further consideration; but if it contained an update, + * we might need to preserve it. */ if (MultiXactIdIsRunning(multi, HEAP_XMAX_IS_LOCKED_ONLY(t_infomask))) @@ -6663,7 +5979,8 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, * * As with all tuple visibility routines, it's critical to test * TransactionIdIsInProgress before TransactionIdDidCommit, - * because of race conditions explained in detail in tqual.c. + * because of race conditions explained in detail in + * heapam_visibility.c. */ if (TransactionIdIsCurrentTransactionId(xid) || TransactionIdIsInProgress(xid)) @@ -6685,8 +6002,8 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask, else { /* - * Not in progress, not committed -- must be aborted or crashed; - * we can ignore it. + * Not in progress, not committed -- must be aborted or + * crashed; we can ignore it. */ } @@ -6804,18 +6121,28 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, xl_heap_freeze_tuple *frz, bool *totally_frozen_p) { bool changed = false; - bool freeze_xmax = false; + bool xmax_already_frozen = false; + bool xmin_frozen; + bool freeze_xmax; TransactionId xid; - bool totally_frozen = true; frz->frzflags = 0; frz->t_infomask2 = tuple->t_infomask2; frz->t_infomask = tuple->t_infomask; frz->xmax = HeapTupleHeaderGetRawXmax(tuple); - /* Process xmin */ + /* + * Process xmin. xmin_frozen has two slightly different meanings: in the + * !XidIsNormal case, it means "the xmin doesn't need any freezing" (it's + * already a permanent value), while in the block below it is set true to + * mean "xmin won't need freezing after what we do to it here" (false + * otherwise). In both cases we're allowed to set totally_frozen, as far + * as xmin is concerned. + */ xid = HeapTupleHeaderGetXmin(tuple); - if (TransactionIdIsNormal(xid)) + if (!TransactionIdIsNormal(xid)) + xmin_frozen = true; + else { if (TransactionIdPrecedes(xid, relfrozenxid)) ereport(ERROR, @@ -6823,7 +6150,8 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, errmsg_internal("found xmin %u from before relfrozenxid %u", xid, relfrozenxid))); - if (TransactionIdPrecedes(xid, cutoff_xid)) + xmin_frozen = TransactionIdPrecedes(xid, cutoff_xid); + if (xmin_frozen) { if (!TransactionIdDidCommit(xid)) ereport(ERROR, @@ -6834,8 +6162,6 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, frz->t_infomask |= HEAP_XMIN_FROZEN; changed = true; } - else - totally_frozen = false; } /* @@ -6858,9 +6184,9 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, relfrozenxid, relminmxid, cutoff_xid, cutoff_multi, &flags); - if (flags & FRM_INVALIDATE_XMAX) - freeze_xmax = true; - else if (flags & FRM_RETURN_IS_XID) + freeze_xmax = (flags & FRM_INVALIDATE_XMAX); + + if (flags & FRM_RETURN_IS_XID) { /* * NB -- some of these transformations are only valid because we @@ -6874,7 +6200,6 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, if (flags & FRM_MARK_COMMITTED) frz->t_infomask |= HEAP_XMAX_COMMITTED; changed = true; - totally_frozen = false; } else if (flags & FRM_RETURN_IS_MULTI) { @@ -6896,11 +6221,6 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, frz->xmax = newxmax; changed = true; - totally_frozen = false; - } - else - { - Assert(flags & FRM_NOOP); } } else if (TransactionIdIsNormal(xid)) @@ -6928,11 +6248,24 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, freeze_xmax = true; } else - totally_frozen = false; + freeze_xmax = false; } + else if ((tuple->t_infomask & HEAP_XMAX_INVALID) || + !TransactionIdIsValid(HeapTupleHeaderGetRawXmax(tuple))) + { + freeze_xmax = false; + xmax_already_frozen = true; + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("found xmax %u (infomask 0x%04x) not frozen, not multi, not normal", + xid, tuple->t_infomask))); if (freeze_xmax) { + Assert(!xmax_already_frozen); + frz->xmax = InvalidTransactionId; /* @@ -6985,7 +6318,8 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, } } - *totally_frozen_p = totally_frozen; + *totally_frozen_p = (xmin_frozen && + (freeze_xmax || xmax_already_frozen)); return changed; } @@ -7206,10 +6540,13 @@ HeapTupleGetUpdateXid(HeapTupleHeader tuple) * tuple lock of the given strength? * * The passed infomask pairs up with the given multixact in the tuple header. + * + * If current_is_member is not NULL, it is set to 'true' if the current + * transaction is a member of the given multixact. */ static bool DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, - LockTupleMode lockmode) + LockTupleMode lockmode, bool *current_is_member) { int nmembers; MultiXactMember *members; @@ -7230,15 +6567,24 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, TransactionId memxid; LOCKMODE memlockmode; - memlockmode = LOCKMODE_from_mxstatus(members[i].status); + if (result && (current_is_member == NULL || *current_is_member)) + break; - /* ignore members that don't conflict with the lock we want */ - if (!DoLockModesConflict(memlockmode, wanted)) - continue; + memlockmode = LOCKMODE_from_mxstatus(members[i].status); - /* ignore members from current xact */ + /* ignore members from current xact (but track their presence) */ memxid = members[i].xid; if (TransactionIdIsCurrentTransactionId(memxid)) + { + if (current_is_member != NULL) + *current_is_member = true; + continue; + } + else if (result) + continue; + + /* ignore members that don't conflict with the lock we want */ + if (!DoLockModesConflict(memlockmode, wanted)) continue; if (ISUPDATE_from_mxstatus(members[i].status)) @@ -7257,10 +6603,11 @@ DoesMultiXactIdConflict(MultiXactId multi, uint16 infomask, /* * Whatever remains are either live lockers that conflict with our * wanted lock, and updaters that are not aborted. Those conflict - * with what we want, so return true. + * with what we want. Set up to return true, but keep going to + * look for the current transaction among the multixact members, + * if needed. */ result = true; - break; } pfree(members); } @@ -7577,6 +6924,220 @@ HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple, /* *latestRemovedXid may still be invalid at end */ } +#ifdef USE_PREFETCH +/* + * Helper function for heap_compute_xid_horizon_for_tuples. Issue prefetch + * requests for the number of buffers indicated by prefetch_count. The + * prefetch_state keeps track of all the buffers that we can prefetch and + * which ones have already been prefetched; each call to this function picks + * up where the previous call left off. + */ +static void +xid_horizon_prefetch_buffer(Relation rel, + XidHorizonPrefetchState *prefetch_state, + int prefetch_count) +{ + BlockNumber cur_hblkno = prefetch_state->cur_hblkno; + int count = 0; + int i; + int nitems = prefetch_state->nitems; + ItemPointerData *tids = prefetch_state->tids; + + for (i = prefetch_state->next_item; + i < nitems && count < prefetch_count; + i++) + { + ItemPointer htid = &tids[i]; + + if (cur_hblkno == InvalidBlockNumber || + ItemPointerGetBlockNumber(htid) != cur_hblkno) + { + cur_hblkno = ItemPointerGetBlockNumber(htid); + PrefetchBuffer(rel, MAIN_FORKNUM, cur_hblkno); + count++; + } + } + + /* + * Save the prefetch position so that next time we can continue from that + * position. + */ + prefetch_state->next_item = i; + prefetch_state->cur_hblkno = cur_hblkno; +} +#endif + +/* + * Get the latestRemovedXid from the heap pages pointed at by the index + * tuples being deleted. + * + * We used to do this during recovery rather than on the primary, but that + * approach now appears inferior. It meant that the master could generate + * a lot of work for the standby without any back-pressure to slow down the + * master, and it required the standby to have reached consistency, whereas + * we want to have correct information available even before that point. + * + * It's possible for this to generate a fair amount of I/O, since we may be + * deleting hundreds of tuples from a single index block. To amortize that + * cost to some degree, this uses prefetching and combines repeat accesses to + * the same block. + */ +TransactionId +heap_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *tids, + int nitems) +{ + TransactionId latestRemovedXid = InvalidTransactionId; + BlockNumber hblkno; + Buffer buf = InvalidBuffer; + Page hpage; +#ifdef USE_PREFETCH + XidHorizonPrefetchState prefetch_state; + int io_concurrency; + int prefetch_distance; +#endif + + /* + * Sort to avoid repeated lookups for the same page, and to make it more + * likely to access items in an efficient order. In particular, this + * ensures that if there are multiple pointers to the same page, they all + * get processed looking up and locking the page just once. + */ + qsort((void *) tids, nitems, sizeof(ItemPointerData), + (int (*) (const void *, const void *)) ItemPointerCompare); + +#ifdef USE_PREFETCH + /* Initialize prefetch state. */ + prefetch_state.cur_hblkno = InvalidBlockNumber; + prefetch_state.next_item = 0; + prefetch_state.nitems = nitems; + prefetch_state.tids = tids; + + /* + * Compute the prefetch distance that we will attempt to maintain. + * + * We don't use the regular formula to determine how much to prefetch + * here, but instead just add a constant to effective_io_concurrency. + * That's because it seems best to do some prefetching here even when + * effective_io_concurrency is set to 0, but if the DBA thinks it's OK to + * do more prefetching for other operations, then it's probably OK to do + * more prefetching in this case, too. It may be that this formula is too + * simplistic, but at the moment there is no evidence of that or any idea + * about what would work better. + * + * Since the caller holds a buffer lock somewhere in rel, we'd better make + * sure that isn't a catalog relation before we call code that does + * syscache lookups, to avoid risk of deadlock. + */ + if (IsCatalogRelation(rel)) + io_concurrency = effective_io_concurrency; + else + io_concurrency = get_tablespace_io_concurrency(rel->rd_rel->reltablespace); + prefetch_distance = Min((io_concurrency) + 10, MAX_IO_CONCURRENCY); + + /* Start prefetching. */ + xid_horizon_prefetch_buffer(rel, &prefetch_state, prefetch_distance); +#endif + + /* Iterate over all tids, and check their horizon */ + hblkno = InvalidBlockNumber; + hpage = NULL; + for (int i = 0; i < nitems; i++) + { + ItemPointer htid = &tids[i]; + ItemId hitemid; + OffsetNumber hoffnum; + + /* + * Read heap buffer, but avoid refetching if it's the same block as + * required for the last tid. + */ + if (hblkno == InvalidBlockNumber || + ItemPointerGetBlockNumber(htid) != hblkno) + { + /* release old buffer */ + if (BufferIsValid(buf)) + { + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + ReleaseBuffer(buf); + } + + hblkno = ItemPointerGetBlockNumber(htid); + + buf = ReadBuffer(rel, hblkno); + +#ifdef USE_PREFETCH + + /* + * To maintain the prefetch distance, prefetch one more page for + * each page we read. + */ + xid_horizon_prefetch_buffer(rel, &prefetch_state, 1); +#endif + + hpage = BufferGetPage(buf); + + LockBuffer(buf, BUFFER_LOCK_SHARE); + } + + hoffnum = ItemPointerGetOffsetNumber(htid); + hitemid = PageGetItemId(hpage, hoffnum); + + /* + * Follow any redirections until we find something useful. + */ + while (ItemIdIsRedirected(hitemid)) + { + hoffnum = ItemIdGetRedirect(hitemid); + hitemid = PageGetItemId(hpage, hoffnum); + CHECK_FOR_INTERRUPTS(); + } + + /* + * If the heap item has storage, then read the header and use that to + * set latestRemovedXid. + * + * Some LP_DEAD items may not be accessible, so we ignore them. + */ + if (ItemIdHasStorage(hitemid)) + { + HeapTupleHeader htuphdr; + + htuphdr = (HeapTupleHeader) PageGetItem(hpage, hitemid); + + HeapTupleHeaderAdvanceLatestRemovedXid(htuphdr, &latestRemovedXid); + } + else if (ItemIdIsDead(hitemid)) + { + /* + * Conjecture: if hitemid is dead then it had xids before the xids + * marked on LP_NORMAL items. So we just ignore this item and move + * onto the next, for the purposes of calculating + * latestRemovedXid. + */ + } + else + Assert(!ItemIdIsUsed(hitemid)); + + } + + if (BufferIsValid(buf)) + { + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + ReleaseBuffer(buf); + } + + /* + * If all heap tuples were LP_DEAD then we will be returning + * InvalidTransactionId here, which avoids conflicts. This matches + * existing logic which assumes that LP_DEAD tuples must already be older + * than the latestRemovedXid on the cleanup record that set them as + * LP_DEAD, hence must already have generated a conflict. + */ + + return latestRemovedXid; +} + /* * Perform XLogInsert to register a heap cleanup info message. These * messages are sent once per VACUUM and are required because @@ -7640,7 +7201,7 @@ log_heap_clean(Relation reln, Buffer buffer, * arrays need not be stored too. Note that even if all three arrays are * empty, we want to expose the buffer as a candidate for whole-page * storage, since this record type implies a defragmentation operation - * even if no item pointers changed state. + * even if no line pointers changed state. */ if (nredirected > 0) XLogRegisterBufData(0, (char *) redirected, @@ -8032,19 +7593,24 @@ log_heap_new_cid(Relation relation, HeapTuple tup) * the old tuple in a UPDATE or DELETE. * * Returns NULL if there's no need to log an identity or if there's no suitable - * key in the Relation relation. + * key defined. + * + * key_changed should be false if caller knows that no replica identity + * columns changed value. It's always true in the DELETE case. + * + * *copy is set to true if the returned tuple is a modified copy rather than + * the same tuple that was passed in. */ static HeapTuple -ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool *copy) +ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, + bool *copy) { TupleDesc desc = RelationGetDescr(relation); - Oid replidindex; - Relation idx_rel; char replident = relation->rd_rel->relreplident; - HeapTuple key_tuple = NULL; + Bitmapset *idattrs; + HeapTuple key_tuple; bool nulls[MaxHeapAttributeNumber]; Datum values[MaxHeapAttributeNumber]; - int natt; *copy = false; @@ -8063,7 +7629,7 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool * if (HeapTupleHasExternal(tp)) { *copy = true; - tp = toast_flatten_tuple(tp, RelationGetDescr(relation)); + tp = toast_flatten_tuple(tp, desc); } return tp; } @@ -8072,56 +7638,39 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool * if (!key_changed) return NULL; - /* find the replica identity index */ - replidindex = RelationGetReplicaIndex(relation); - if (!OidIsValid(replidindex)) - { - elog(DEBUG4, "could not find configured replica identity for table \"%s\"", - RelationGetRelationName(relation)); - return NULL; - } - - idx_rel = RelationIdGetRelation(replidindex); - - /* deform tuple, so we have fast access to columns */ - heap_deform_tuple(tp, desc, values, nulls); + /* find out the replica identity columns */ + idattrs = RelationGetIndexAttrBitmap(relation, + INDEX_ATTR_BITMAP_IDENTITY_KEY); - /* set all columns to NULL, regardless of whether they actually are */ - memset(nulls, 1, sizeof(nulls)); + /* + * If there's no defined replica identity columns, treat as !key_changed. + * (This case should not be reachable from heap_update, since that should + * calculate key_changed accurately. But heap_delete just passes constant + * true for key_changed, so we can hit this case in deletes.) + */ + if (bms_is_empty(idattrs)) + return NULL; /* - * Now set all columns contained in the index to NOT NULL, they cannot - * currently be NULL. + * Construct a new tuple containing only the replica identity columns, + * with nulls elsewhere. While we're at it, assert that the replica + * identity columns aren't null. */ - for (natt = 0; natt < IndexRelationGetNumberOfKeyAttributes(idx_rel); natt++) - { - int attno = idx_rel->rd_index->indkey.values[natt]; + heap_deform_tuple(tp, desc, values, nulls); - if (attno < 0) - { - /* - * The OID column can appear in an index definition, but that's - * OK, because we always copy the OID if present (see below). - * Other system columns may not. - */ - if (attno == ObjectIdAttributeNumber) - continue; - elog(ERROR, "system column in index"); - } - nulls[attno - 1] = false; + for (int i = 0; i < desc->natts; i++) + { + if (bms_is_member(i + 1 - FirstLowInvalidHeapAttributeNumber, + idattrs)) + Assert(!nulls[i]); + else + nulls[i] = true; } key_tuple = heap_form_tuple(desc, values, nulls); *copy = true; - RelationClose(idx_rel); - /* - * Always copy oids if the table has them, even if not included in the - * index. The space in the logged tuple is used anyway, so there's little - * point in not including the information. - */ - if (relation->rd_rel->relhasoids) - HeapTupleSetOid(key_tuple, HeapTupleGetOid(tp)); + bms_free(idattrs); /* * If the tuple, which by here only contains indexed columns, still has @@ -8134,7 +7683,7 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool * { HeapTuple oldtup = key_tuple; - key_tuple = toast_flatten_tuple(oldtup, RelationGetDescr(relation)); + key_tuple = toast_flatten_tuple(oldtup, desc); heap_freetuple(oldtup); } @@ -8163,7 +7712,7 @@ heap_xlog_cleanup_info(XLogReaderState *record) } /* - * Handles HEAP2_CLEAN record type + * Handles XLOG_HEAP2_CLEAN record type */ static void heap_xlog_clean(XLogReaderState *record) @@ -8171,7 +7720,6 @@ heap_xlog_clean(XLogReaderState *record) XLogRecPtr lsn = record->EndRecPtr; xl_heap_clean *xlrec = (xl_heap_clean *) XLogRecGetData(record); Buffer buffer; - Size freespace = 0; RelFileNode rnode; BlockNumber blkno; XLogRedoAction action; @@ -8217,14 +7765,12 @@ heap_xlog_clean(XLogReaderState *record) nunused = (end - nowunused); Assert(nunused >= 0); - /* Update all item pointers per the record, and repair fragmentation */ + /* Update all line pointers per the record, and repair fragmentation */ heap_page_prune_execute(buffer, redirected, nredirected, nowdead, ndead, nowunused, nunused); - freespace = PageGetHeapFreeSpace(page); /* needed to update FSM below */ - /* * Note: we don't worry about updating the page's prunability hints. * At worst this will cause an extra prune cycle to occur soon. @@ -8233,18 +7779,24 @@ heap_xlog_clean(XLogReaderState *record) PageSetLSN(page, lsn); MarkBufferDirty(buffer); } + if (BufferIsValid(buffer)) + { + Size freespace = PageGetHeapFreeSpace(BufferGetPage(buffer)); + UnlockReleaseBuffer(buffer); - /* - * Update the FSM as well. - * - * XXX: Don't do this if the page was restored from full page image. We - * don't bother to update the FSM in that case, it doesn't need to be - * totally accurate anyway. - */ - if (action == BLK_NEEDS_REDO) + /* + * After cleaning records from a page, it's useful to update the FSM + * about it, as it may cause the page become target for insertions + * later even if vacuum decides not to visit it (which is possible if + * gets marked all-visible.) + * + * Do this regardless of a full-page image being applied, since the + * FSM data is not in the page anyway. + */ XLogRecordPageWithFreeSpace(rnode, blkno, freespace); + } } /* @@ -8317,9 +7869,34 @@ heap_xlog_visible(XLogReaderState *record) * wal_log_hints enabled.) */ } + if (BufferIsValid(buffer)) + { + Size space = PageGetFreeSpace(BufferGetPage(buffer)); + UnlockReleaseBuffer(buffer); + /* + * Since FSM is not WAL-logged and only updated heuristically, it + * easily becomes stale in standbys. If the standby is later promoted + * and runs VACUUM, it will skip updating individual free space + * figures for pages that became all-visible (or all-frozen, depending + * on the vacuum mode,) which is troublesome when FreeSpaceMapVacuum + * propagates too optimistic free space values to upper FSM layers; + * later inserters try to use such pages only to find out that they + * are unusable. This can cause long stalls when there are many such + * pages. + * + * Forestall those problems by updating FSM's idea about a page that + * is becoming all-visible or all-frozen. + * + * Do this regardless of a full-page image being applied, since the + * FSM data is not in the page anyway. + */ + if (xlrec->flags & VISIBILITYMAP_VALID_BITS) + XLogRecordPageWithFreeSpace(rnode, blkno, space); + } + /* * Even if we skipped the heap page update due to the LSN interlock, it's * still safe to update the visibility map. Any WAL record that clears @@ -9279,6 +8856,7 @@ heap_redo(XLogReaderState *record) heap_xlog_update(record, false); break; case XLOG_HEAP_TRUNCATE: + /* * TRUNCATE is a no-op because the actions are already logged as * SMGR WAL records. TRUNCATE WAL record only exists for logical @@ -9375,10 +8953,10 @@ heap_sync(Relation rel) { Relation toastrel; - toastrel = heap_open(rel->rd_rel->reltoastrelid, AccessShareLock); + toastrel = table_open(rel->rd_rel->reltoastrelid, AccessShareLock); FlushRelationBuffers(toastrel); smgrimmedsync(toastrel->rd_smgr, MAIN_FORKNUM); - heap_close(toastrel, AccessShareLock); + table_close(toastrel, AccessShareLock); } } diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c new file mode 100644 index 00000000000..2dd8821facd --- /dev/null +++ b/src/backend/access/heap/heapam_handler.c @@ -0,0 +1,2562 @@ +/*------------------------------------------------------------------------- + * + * heapam_handler.c + * heap table access method code + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/heap/heapam_handler.c + * + * + * NOTES + * This files wires up the lower level heapam.c et al routines with the + * tableam abstraction. + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "miscadmin.h" + +#include "access/genam.h" +#include "access/heapam.h" +#include "access/heaptoast.h" +#include "access/multixact.h" +#include "access/rewriteheap.h" +#include "access/tableam.h" +#include "access/tsmapi.h" +#include "access/xact.h" +#include "catalog/catalog.h" +#include "catalog/index.h" +#include "catalog/storage.h" +#include "catalog/storage_xlog.h" +#include "commands/progress.h" +#include "executor/executor.h" +#include "pgstat.h" +#include "storage/bufmgr.h" +#include "storage/bufpage.h" +#include "storage/bufmgr.h" +#include "storage/lmgr.h" +#include "storage/predicate.h" +#include "storage/procarray.h" +#include "storage/smgr.h" +#include "utils/builtins.h" +#include "utils/rel.h" + + +static void reform_and_rewrite_tuple(HeapTuple tuple, + Relation OldHeap, Relation NewHeap, + Datum *values, bool *isnull, RewriteState rwstate); + +static bool SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer, + HeapTuple tuple, + OffsetNumber tupoffset); + +static BlockNumber heapam_scan_get_blocks_done(HeapScanDesc hscan); + +static const TableAmRoutine heapam_methods; + + +/* ------------------------------------------------------------------------ + * Slot related callbacks for heap AM + * ------------------------------------------------------------------------ + */ + +static const TupleTableSlotOps * +heapam_slot_callbacks(Relation relation) +{ + return &TTSOpsBufferHeapTuple; +} + + +/* ------------------------------------------------------------------------ + * Index Scan Callbacks for heap AM + * ------------------------------------------------------------------------ + */ + +static IndexFetchTableData * +heapam_index_fetch_begin(Relation rel) +{ + IndexFetchHeapData *hscan = palloc0(sizeof(IndexFetchHeapData)); + + hscan->xs_base.rel = rel; + hscan->xs_cbuf = InvalidBuffer; + + return &hscan->xs_base; +} + +static void +heapam_index_fetch_reset(IndexFetchTableData *scan) +{ + IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan; + + if (BufferIsValid(hscan->xs_cbuf)) + { + ReleaseBuffer(hscan->xs_cbuf); + hscan->xs_cbuf = InvalidBuffer; + } +} + +static void +heapam_index_fetch_end(IndexFetchTableData *scan) +{ + IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan; + + heapam_index_fetch_reset(scan); + + pfree(hscan); +} + +static bool +heapam_index_fetch_tuple(struct IndexFetchTableData *scan, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + bool *call_again, bool *all_dead) +{ + IndexFetchHeapData *hscan = (IndexFetchHeapData *) scan; + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + bool got_heap_tuple; + + Assert(TTS_IS_BUFFERTUPLE(slot)); + + /* We can skip the buffer-switching logic if we're in mid-HOT chain. */ + if (!*call_again) + { + /* Switch to correct buffer if we don't have it already */ + Buffer prev_buf = hscan->xs_cbuf; + + hscan->xs_cbuf = ReleaseAndReadBuffer(hscan->xs_cbuf, + hscan->xs_base.rel, + ItemPointerGetBlockNumber(tid)); + + /* + * Prune page, but only if we weren't already on this page + */ + if (prev_buf != hscan->xs_cbuf) + heap_page_prune_opt(hscan->xs_base.rel, hscan->xs_cbuf); + } + + /* Obtain share-lock on the buffer so we can examine visibility */ + LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_SHARE); + got_heap_tuple = heap_hot_search_buffer(tid, + hscan->xs_base.rel, + hscan->xs_cbuf, + snapshot, + &bslot->base.tupdata, + all_dead, + !*call_again); + bslot->base.tupdata.t_self = *tid; + LockBuffer(hscan->xs_cbuf, BUFFER_LOCK_UNLOCK); + + if (got_heap_tuple) + { + /* + * Only in a non-MVCC snapshot can more than one member of the HOT + * chain be visible. + */ + *call_again = !IsMVCCSnapshot(snapshot); + + slot->tts_tableOid = RelationGetRelid(scan->rel); + ExecStoreBufferHeapTuple(&bslot->base.tupdata, slot, hscan->xs_cbuf); + } + else + { + /* We've reached the end of the HOT chain. */ + *call_again = false; + } + + return got_heap_tuple; +} + + +/* ------------------------------------------------------------------------ + * Callbacks for non-modifying operations on individual tuples for heap AM + * ------------------------------------------------------------------------ + */ + +static bool +heapam_fetch_row_version(Relation relation, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + Buffer buffer; + + Assert(TTS_IS_BUFFERTUPLE(slot)); + + bslot->base.tupdata.t_self = *tid; + if (heap_fetch(relation, snapshot, &bslot->base.tupdata, &buffer)) + { + /* store in slot, transferring existing pin */ + ExecStorePinnedBufferHeapTuple(&bslot->base.tupdata, slot, buffer); + slot->tts_tableOid = RelationGetRelid(relation); + + return true; + } + + return false; +} + +static bool +heapam_tuple_tid_valid(TableScanDesc scan, ItemPointer tid) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + + return ItemPointerIsValid(tid) && + ItemPointerGetBlockNumber(tid) < hscan->rs_nblocks; +} + +static bool +heapam_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, + Snapshot snapshot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + bool res; + + Assert(TTS_IS_BUFFERTUPLE(slot)); + Assert(BufferIsValid(bslot->buffer)); + + /* + * We need buffer pin and lock to call HeapTupleSatisfiesVisibility. + * Caller should be holding pin, but not lock. + */ + LockBuffer(bslot->buffer, BUFFER_LOCK_SHARE); + res = HeapTupleSatisfiesVisibility(bslot->base.tuple, snapshot, + bslot->buffer); + LockBuffer(bslot->buffer, BUFFER_LOCK_UNLOCK); + + return res; +} + + +/* ---------------------------------------------------------------------------- + * Functions for manipulations of physical tuples for heap AM. + * ---------------------------------------------------------------------------- + */ + +static void +heapam_tuple_insert(Relation relation, TupleTableSlot *slot, CommandId cid, + int options, BulkInsertState bistate) +{ + bool shouldFree = true; + HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); + + /* Update the tuple with table oid */ + slot->tts_tableOid = RelationGetRelid(relation); + tuple->t_tableOid = slot->tts_tableOid; + + /* Perform the insertion, and copy the resulting ItemPointer */ + heap_insert(relation, tuple, cid, options, bistate); + ItemPointerCopy(&tuple->t_self, &slot->tts_tid); + + if (shouldFree) + pfree(tuple); +} + +static void +heapam_tuple_insert_speculative(Relation relation, TupleTableSlot *slot, + CommandId cid, int options, + BulkInsertState bistate, uint32 specToken) +{ + bool shouldFree = true; + HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); + + /* Update the tuple with table oid */ + slot->tts_tableOid = RelationGetRelid(relation); + tuple->t_tableOid = slot->tts_tableOid; + + HeapTupleHeaderSetSpeculativeToken(tuple->t_data, specToken); + options |= HEAP_INSERT_SPECULATIVE; + + /* Perform the insertion, and copy the resulting ItemPointer */ + heap_insert(relation, tuple, cid, options, bistate); + ItemPointerCopy(&tuple->t_self, &slot->tts_tid); + + if (shouldFree) + pfree(tuple); +} + +static void +heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, + uint32 specToken, bool succeeded) +{ + bool shouldFree = true; + HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); + + /* adjust the tuple's state accordingly */ + if (succeeded) + heap_finish_speculative(relation, &slot->tts_tid); + else + heap_abort_speculative(relation, &slot->tts_tid); + + if (shouldFree) + pfree(tuple); +} + +static TM_Result +heapam_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, + Snapshot snapshot, Snapshot crosscheck, bool wait, + TM_FailureData *tmfd, bool changingPart) +{ + /* + * Currently Deleting of index tuples are handled at vacuum, in case if + * the storage itself is cleaning the dead tuples by itself, it is the + * time to call the index tuple deletion also. + */ + return heap_delete(relation, tid, cid, crosscheck, wait, tmfd, changingPart); +} + + +static TM_Result +heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, + CommandId cid, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd, + LockTupleMode *lockmode, bool *update_indexes) +{ + bool shouldFree = true; + HeapTuple tuple = ExecFetchSlotHeapTuple(slot, true, &shouldFree); + TM_Result result; + + /* Update the tuple with table oid */ + slot->tts_tableOid = RelationGetRelid(relation); + tuple->t_tableOid = slot->tts_tableOid; + + result = heap_update(relation, otid, tuple, cid, crosscheck, wait, + tmfd, lockmode); + ItemPointerCopy(&tuple->t_self, &slot->tts_tid); + + /* + * Decide whether new index entries are needed for the tuple + * + * Note: heap_update returns the tid (location) of the new tuple in the + * t_self field. + * + * If it's a HOT update, we mustn't insert new index entries. + */ + *update_indexes = result == TM_Ok && !HeapTupleIsHeapOnly(tuple); + + if (shouldFree) + pfree(tuple); + + return result; +} + +static TM_Result +heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot, + TupleTableSlot *slot, CommandId cid, LockTupleMode mode, + LockWaitPolicy wait_policy, uint8 flags, + TM_FailureData *tmfd) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + TM_Result result; + Buffer buffer; + HeapTuple tuple = &bslot->base.tupdata; + bool follow_updates; + + follow_updates = (flags & TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS) != 0; + tmfd->traversed = false; + + Assert(TTS_IS_BUFFERTUPLE(slot)); + +tuple_lock_retry: + tuple->t_self = *tid; + result = heap_lock_tuple(relation, tuple, cid, mode, wait_policy, + follow_updates, &buffer, tmfd); + + if (result == TM_Updated && + (flags & TUPLE_LOCK_FLAG_FIND_LAST_VERSION)) + { + ReleaseBuffer(buffer); + /* Should not encounter speculative tuple on recheck */ + Assert(!HeapTupleHeaderIsSpeculative(tuple->t_data)); + + if (!ItemPointerEquals(&tmfd->ctid, &tuple->t_self)) + { + SnapshotData SnapshotDirty; + TransactionId priorXmax; + + /* it was updated, so look at the updated version */ + *tid = tmfd->ctid; + /* updated row should have xmin matching this xmax */ + priorXmax = tmfd->xmax; + + /* signal that a tuple later in the chain is getting locked */ + tmfd->traversed = true; + + /* + * fetch target tuple + * + * Loop here to deal with updated or busy tuples + */ + InitDirtySnapshot(SnapshotDirty); + for (;;) + { + if (ItemPointerIndicatesMovedPartitions(tid)) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("tuple to be locked was already moved to another partition due to concurrent update"))); + + tuple->t_self = *tid; + if (heap_fetch(relation, &SnapshotDirty, tuple, &buffer)) + { + /* + * If xmin isn't what we're expecting, the slot must have + * been recycled and reused for an unrelated tuple. This + * implies that the latest version of the row was deleted, + * so we need do nothing. (Should be safe to examine xmin + * without getting buffer's content lock. We assume + * reading a TransactionId to be atomic, and Xmin never + * changes in an existing tuple, except to invalid or + * frozen, and neither of those can match priorXmax.) + */ + if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple->t_data), + priorXmax)) + { + ReleaseBuffer(buffer); + return TM_Deleted; + } + + /* otherwise xmin should not be dirty... */ + if (TransactionIdIsValid(SnapshotDirty.xmin)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("t_xmin is uncommitted in tuple to be updated"))); + + /* + * If tuple is being updated by other transaction then we + * have to wait for its commit/abort, or die trying. + */ + if (TransactionIdIsValid(SnapshotDirty.xmax)) + { + ReleaseBuffer(buffer); + switch (wait_policy) + { + case LockWaitBlock: + XactLockTableWait(SnapshotDirty.xmax, + relation, &tuple->t_self, + XLTW_FetchUpdated); + break; + case LockWaitSkip: + if (!ConditionalXactLockTableWait(SnapshotDirty.xmax)) + /* skip instead of waiting */ + return TM_WouldBlock; + break; + case LockWaitError: + if (!ConditionalXactLockTableWait(SnapshotDirty.xmax)) + ereport(ERROR, + (errcode(ERRCODE_LOCK_NOT_AVAILABLE), + errmsg("could not obtain lock on row in relation \"%s\"", + RelationGetRelationName(relation)))); + break; + } + continue; /* loop back to repeat heap_fetch */ + } + + /* + * If tuple was inserted by our own transaction, we have + * to check cmin against cid: cmin >= current CID means + * our command cannot see the tuple, so we should ignore + * it. Otherwise heap_lock_tuple() will throw an error, + * and so would any later attempt to update or delete the + * tuple. (We need not check cmax because + * HeapTupleSatisfiesDirty will consider a tuple deleted + * by our transaction dead, regardless of cmax.) We just + * checked that priorXmax == xmin, so we can test that + * variable instead of doing HeapTupleHeaderGetXmin again. + */ + if (TransactionIdIsCurrentTransactionId(priorXmax) && + HeapTupleHeaderGetCmin(tuple->t_data) >= cid) + { + tmfd->xmax = priorXmax; + + /* + * Cmin is the problematic value, so store that. See + * above. + */ + tmfd->cmax = HeapTupleHeaderGetCmin(tuple->t_data); + ReleaseBuffer(buffer); + return TM_SelfModified; + } + + /* + * This is a live tuple, so try to lock it again. + */ + ReleaseBuffer(buffer); + goto tuple_lock_retry; + } + + /* + * If the referenced slot was actually empty, the latest + * version of the row must have been deleted, so we need do + * nothing. + */ + if (tuple->t_data == NULL) + { + return TM_Deleted; + } + + /* + * As above, if xmin isn't what we're expecting, do nothing. + */ + if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple->t_data), + priorXmax)) + { + if (BufferIsValid(buffer)) + ReleaseBuffer(buffer); + return TM_Deleted; + } + + /* + * If we get here, the tuple was found but failed + * SnapshotDirty. Assuming the xmin is either a committed xact + * or our own xact (as it certainly should be if we're trying + * to modify the tuple), this must mean that the row was + * updated or deleted by either a committed xact or our own + * xact. If it was deleted, we can ignore it; if it was + * updated then chain up to the next version and repeat the + * whole process. + * + * As above, it should be safe to examine xmax and t_ctid + * without the buffer content lock, because they can't be + * changing. + */ + if (ItemPointerEquals(&tuple->t_self, &tuple->t_data->t_ctid)) + { + /* deleted, so forget about it */ + if (BufferIsValid(buffer)) + ReleaseBuffer(buffer); + return TM_Deleted; + } + + /* updated, so look at the updated row */ + *tid = tuple->t_data->t_ctid; + /* updated row should have xmin matching this xmax */ + priorXmax = HeapTupleHeaderGetUpdateXid(tuple->t_data); + if (BufferIsValid(buffer)) + ReleaseBuffer(buffer); + /* loop back to fetch next in chain */ + } + } + else + { + /* tuple was deleted, so give up */ + return TM_Deleted; + } + } + + slot->tts_tableOid = RelationGetRelid(relation); + tuple->t_tableOid = slot->tts_tableOid; + + /* store in slot, transferring existing pin */ + ExecStorePinnedBufferHeapTuple(tuple, slot, buffer); + + return result; +} + +static void +heapam_finish_bulk_insert(Relation relation, int options) +{ + /* + * If we skipped writing WAL, then we need to sync the heap (but not + * indexes since those use WAL anyway / don't go through tableam) + */ + if (options & HEAP_INSERT_SKIP_WAL) + heap_sync(relation); +} + + +/* ------------------------------------------------------------------------ + * DDL related callbacks for heap AM. + * ------------------------------------------------------------------------ + */ + +static void +heapam_relation_set_new_filenode(Relation rel, + const RelFileNode *newrnode, + char persistence, + TransactionId *freezeXid, + MultiXactId *minmulti) +{ + SMgrRelation srel; + + /* + * Initialize to the minimum XID that could put tuples in the table. We + * know that no xacts older than RecentXmin are still running, so that + * will do. + */ + *freezeXid = RecentXmin; + + /* + * Similarly, initialize the minimum Multixact to the first value that + * could possibly be stored in tuples in the table. Running transactions + * could reuse values from their local cache, so we are careful to + * consider all currently running multis. + * + * XXX this could be refined further, but is it worth the hassle? + */ + *minmulti = GetOldestMultiXactId(); + + srel = RelationCreateStorage(*newrnode, persistence); + + /* + * If required, set up an init fork for an unlogged table so that it can + * be correctly reinitialized on restart. An immediate sync is required + * even if the page has been logged, because the write did not go through + * shared_buffers and therefore a concurrent checkpoint may have moved the + * redo pointer past our xlog record. Recovery may as well remove it + * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE + * record. Therefore, logging is necessary even if wal_level=minimal. + */ + if (persistence == RELPERSISTENCE_UNLOGGED) + { + Assert(rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_MATVIEW || + rel->rd_rel->relkind == RELKIND_TOASTVALUE); + smgrcreate(srel, INIT_FORKNUM, false); + log_smgrcreate(newrnode, INIT_FORKNUM); + smgrimmedsync(srel, INIT_FORKNUM); + } + + smgrclose(srel); +} + +static void +heapam_relation_nontransactional_truncate(Relation rel) +{ + RelationTruncate(rel, 0); +} + +static void +heapam_relation_copy_data(Relation rel, const RelFileNode *newrnode) +{ + SMgrRelation dstrel; + + dstrel = smgropen(*newrnode, rel->rd_backend); + RelationOpenSmgr(rel); + + /* + * Since we copy the file directly without looking at the shared buffers, + * we'd better first flush out any pages of the source relation that are + * in shared buffers. We assume no new changes will be made while we are + * holding exclusive lock on the rel. + */ + FlushRelationBuffers(rel); + + /* + * Create and copy all forks of the relation, and schedule unlinking of + * old physical files. + * + * NOTE: any conflict in relfilenode value will be caught in + * RelationCreateStorage(). + */ + RelationCreateStorage(*newrnode, rel->rd_rel->relpersistence); + + /* copy main fork */ + RelationCopyStorage(rel->rd_smgr, dstrel, MAIN_FORKNUM, + rel->rd_rel->relpersistence); + + /* copy those extra forks that exist */ + for (ForkNumber forkNum = MAIN_FORKNUM + 1; + forkNum <= MAX_FORKNUM; forkNum++) + { + if (smgrexists(rel->rd_smgr, forkNum)) + { + smgrcreate(dstrel, forkNum, false); + + /* + * WAL log creation if the relation is persistent, or this is the + * init fork of an unlogged relation. + */ + if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || + (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && + forkNum == INIT_FORKNUM)) + log_smgrcreate(newrnode, forkNum); + RelationCopyStorage(rel->rd_smgr, dstrel, forkNum, + rel->rd_rel->relpersistence); + } + } + + + /* drop old relation, and close new one */ + RelationDropStorage(rel); + smgrclose(dstrel); +} + +static void +heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, + Relation OldIndex, bool use_sort, + TransactionId OldestXmin, + TransactionId *xid_cutoff, + MultiXactId *multi_cutoff, + double *num_tuples, + double *tups_vacuumed, + double *tups_recently_dead) +{ + RewriteState rwstate; + IndexScanDesc indexScan; + TableScanDesc tableScan; + HeapScanDesc heapScan; + bool use_wal; + bool is_system_catalog; + Tuplesortstate *tuplesort; + TupleDesc oldTupDesc = RelationGetDescr(OldHeap); + TupleDesc newTupDesc = RelationGetDescr(NewHeap); + TupleTableSlot *slot; + int natts; + Datum *values; + bool *isnull; + BufferHeapTupleTableSlot *hslot; + + /* Remember if it's a system catalog */ + is_system_catalog = IsSystemRelation(OldHeap); + + /* + * We need to log the copied data in WAL iff WAL archiving/streaming is + * enabled AND it's a WAL-logged rel. + */ + use_wal = XLogIsNeeded() && RelationNeedsWAL(NewHeap); + + /* use_wal off requires smgr_targblock be initially invalid */ + Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber); + + /* Preallocate values/isnull arrays */ + natts = newTupDesc->natts; + values = (Datum *) palloc(natts * sizeof(Datum)); + isnull = (bool *) palloc(natts * sizeof(bool)); + + /* Initialize the rewrite operation */ + rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin, *xid_cutoff, + *multi_cutoff, use_wal); + + + /* Set up sorting if wanted */ + if (use_sort) + tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex, + maintenance_work_mem, + NULL, false); + else + tuplesort = NULL; + + /* + * Prepare to scan the OldHeap. To ensure we see recently-dead tuples + * that still need to be copied, we scan with SnapshotAny and use + * HeapTupleSatisfiesVacuum for the visibility test. + */ + if (OldIndex != NULL && !use_sort) + { + const int ci_index[] = { + PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_INDEX_RELID + }; + int64 ci_val[2]; + + /* Set phase and OIDOldIndex to columns */ + ci_val[0] = PROGRESS_CLUSTER_PHASE_INDEX_SCAN_HEAP; + ci_val[1] = RelationGetRelid(OldIndex); + pgstat_progress_update_multi_param(2, ci_index, ci_val); + + tableScan = NULL; + heapScan = NULL; + indexScan = index_beginscan(OldHeap, OldIndex, SnapshotAny, 0, 0); + index_rescan(indexScan, NULL, 0, NULL, 0); + } + else + { + /* In scan-and-sort mode and also VACUUM FULL, set phase */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_SEQ_SCAN_HEAP); + + tableScan = table_beginscan(OldHeap, SnapshotAny, 0, (ScanKey) NULL); + heapScan = (HeapScanDesc) tableScan; + indexScan = NULL; + + /* Set total heap blocks */ + pgstat_progress_update_param(PROGRESS_CLUSTER_TOTAL_HEAP_BLKS, + heapScan->rs_nblocks); + } + + slot = table_slot_create(OldHeap, NULL); + hslot = (BufferHeapTupleTableSlot *) slot; + + /* + * Scan through the OldHeap, either in OldIndex order or sequentially; + * copy each tuple into the NewHeap, or transiently to the tuplesort + * module. Note that we don't bother sorting dead tuples (they won't get + * to the new table anyway). + */ + for (;;) + { + HeapTuple tuple; + Buffer buf; + bool isdead; + + CHECK_FOR_INTERRUPTS(); + + if (indexScan != NULL) + { + if (!index_getnext_slot(indexScan, ForwardScanDirection, slot)) + break; + + /* Since we used no scan keys, should never need to recheck */ + if (indexScan->xs_recheck) + elog(ERROR, "CLUSTER does not support lossy index conditions"); + } + else + { + if (!table_scan_getnextslot(tableScan, ForwardScanDirection, slot)) + break; + + /* + * In scan-and-sort mode and also VACUUM FULL, set heap blocks + * scanned + */ + pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED, + heapScan->rs_cblock + 1); + } + + tuple = ExecFetchSlotHeapTuple(slot, false, NULL); + buf = hslot->buffer; + + LockBuffer(buf, BUFFER_LOCK_SHARE); + + switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf)) + { + case HEAPTUPLE_DEAD: + /* Definitely dead */ + isdead = true; + break; + case HEAPTUPLE_RECENTLY_DEAD: + *tups_recently_dead += 1; + /* fall through */ + case HEAPTUPLE_LIVE: + /* Live or recently dead, must copy it */ + isdead = false; + break; + case HEAPTUPLE_INSERT_IN_PROGRESS: + + /* + * Since we hold exclusive lock on the relation, normally the + * only way to see this is if it was inserted earlier in our + * own transaction. However, it can happen in system + * catalogs, since we tend to release write lock before commit + * there. Give a warning if neither case applies; but in any + * case we had better copy it. + */ + if (!is_system_catalog && + !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple->t_data))) + elog(WARNING, "concurrent insert in progress within table \"%s\"", + RelationGetRelationName(OldHeap)); + /* treat as live */ + isdead = false; + break; + case HEAPTUPLE_DELETE_IN_PROGRESS: + + /* + * Similar situation to INSERT_IN_PROGRESS case. + */ + if (!is_system_catalog && + !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple->t_data))) + elog(WARNING, "concurrent delete in progress within table \"%s\"", + RelationGetRelationName(OldHeap)); + /* treat as recently dead */ + *tups_recently_dead += 1; + isdead = false; + break; + default: + elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); + isdead = false; /* keep compiler quiet */ + break; + } + + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + + if (isdead) + { + *tups_vacuumed += 1; + /* heap rewrite module still needs to see it... */ + if (rewrite_heap_dead_tuple(rwstate, tuple)) + { + /* A previous recently-dead tuple is now known dead */ + *tups_vacuumed += 1; + *tups_recently_dead -= 1; + } + continue; + } + + *num_tuples += 1; + if (tuplesort != NULL) + { + tuplesort_putheaptuple(tuplesort, tuple); + + /* + * In scan-and-sort mode, report increase in number of tuples + * scanned + */ + pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_TUPLES_SCANNED, + *num_tuples); + } + else + { + const int ct_index[] = { + PROGRESS_CLUSTER_HEAP_TUPLES_SCANNED, + PROGRESS_CLUSTER_HEAP_TUPLES_WRITTEN + }; + int64 ct_val[2]; + + reform_and_rewrite_tuple(tuple, OldHeap, NewHeap, + values, isnull, rwstate); + + /* + * In indexscan mode and also VACUUM FULL, report increase in + * number of tuples scanned and written + */ + ct_val[0] = *num_tuples; + ct_val[1] = *num_tuples; + pgstat_progress_update_multi_param(2, ct_index, ct_val); + } + } + + if (indexScan != NULL) + index_endscan(indexScan); + if (tableScan != NULL) + table_endscan(tableScan); + if (slot) + ExecDropSingleTupleTableSlot(slot); + + /* + * In scan-and-sort mode, complete the sort, then read out all live tuples + * from the tuplestore and write them to the new relation. + */ + if (tuplesort != NULL) + { + double n_tuples = 0; + + /* Report that we are now sorting tuples */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_SORT_TUPLES); + + tuplesort_performsort(tuplesort); + + /* Report that we are now writing new heap */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_WRITE_NEW_HEAP); + + for (;;) + { + HeapTuple tuple; + + CHECK_FOR_INTERRUPTS(); + + tuple = tuplesort_getheaptuple(tuplesort, true); + if (tuple == NULL) + break; + + n_tuples += 1; + reform_and_rewrite_tuple(tuple, + OldHeap, NewHeap, + values, isnull, + rwstate); + /* Report n_tuples */ + pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_TUPLES_WRITTEN, + n_tuples); + } + + tuplesort_end(tuplesort); + } + + /* Write out any remaining tuples, and fsync if needed */ + end_heap_rewrite(rwstate); + + /* Clean up */ + pfree(values); + pfree(isnull); +} + +static bool +heapam_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno, + BufferAccessStrategy bstrategy) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + + /* + * We must maintain a pin on the target page's buffer to ensure that + * concurrent activity - e.g. HOT pruning - doesn't delete tuples out from + * under us. Hence, pin the page until we are done looking at it. We + * also choose to hold sharelock on the buffer throughout --- we could + * release and re-acquire sharelock for each tuple, but since we aren't + * doing much work per tuple, the extra lock traffic is probably better + * avoided. + */ + hscan->rs_cblock = blockno; + hscan->rs_cindex = FirstOffsetNumber; + hscan->rs_cbuf = ReadBufferExtended(scan->rs_rd, MAIN_FORKNUM, + blockno, RBM_NORMAL, bstrategy); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); + + /* in heap all blocks can contain tuples, so always return true */ + return true; +} + +static bool +heapam_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin, + double *liverows, double *deadrows, + TupleTableSlot *slot) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + Page targpage; + OffsetNumber maxoffset; + BufferHeapTupleTableSlot *hslot; + + Assert(TTS_IS_BUFFERTUPLE(slot)); + + hslot = (BufferHeapTupleTableSlot *) slot; + targpage = BufferGetPage(hscan->rs_cbuf); + maxoffset = PageGetMaxOffsetNumber(targpage); + + /* Inner loop over all tuples on the selected page */ + for (; hscan->rs_cindex <= maxoffset; hscan->rs_cindex++) + { + ItemId itemid; + HeapTuple targtuple = &hslot->base.tupdata; + bool sample_it = false; + + itemid = PageGetItemId(targpage, hscan->rs_cindex); + + /* + * We ignore unused and redirect line pointers. DEAD line pointers + * should be counted as dead, because we need vacuum to run to get rid + * of them. Note that this rule agrees with the way that + * heap_page_prune() counts things. + */ + if (!ItemIdIsNormal(itemid)) + { + if (ItemIdIsDead(itemid)) + *deadrows += 1; + continue; + } + + ItemPointerSet(&targtuple->t_self, hscan->rs_cblock, hscan->rs_cindex); + + targtuple->t_tableOid = RelationGetRelid(scan->rs_rd); + targtuple->t_data = (HeapTupleHeader) PageGetItem(targpage, itemid); + targtuple->t_len = ItemIdGetLength(itemid); + + switch (HeapTupleSatisfiesVacuum(targtuple, OldestXmin, + hscan->rs_cbuf)) + { + case HEAPTUPLE_LIVE: + sample_it = true; + *liverows += 1; + break; + + case HEAPTUPLE_DEAD: + case HEAPTUPLE_RECENTLY_DEAD: + /* Count dead and recently-dead rows */ + *deadrows += 1; + break; + + case HEAPTUPLE_INSERT_IN_PROGRESS: + + /* + * Insert-in-progress rows are not counted. We assume that + * when the inserting transaction commits or aborts, it will + * send a stats message to increment the proper count. This + * works right only if that transaction ends after we finish + * analyzing the table; if things happen in the other order, + * its stats update will be overwritten by ours. However, the + * error will be large only if the other transaction runs long + * enough to insert many tuples, so assuming it will finish + * after us is the safer option. + * + * A special case is that the inserting transaction might be + * our own. In this case we should count and sample the row, + * to accommodate users who load a table and analyze it in one + * transaction. (pgstat_report_analyze has to adjust the + * numbers we send to the stats collector to make this come + * out right.) + */ + if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(targtuple->t_data))) + { + sample_it = true; + *liverows += 1; + } + break; + + case HEAPTUPLE_DELETE_IN_PROGRESS: + + /* + * We count and sample delete-in-progress rows the same as + * live ones, so that the stats counters come out right if the + * deleting transaction commits after us, per the same + * reasoning given above. + * + * If the delete was done by our own transaction, however, we + * must count the row as dead to make pgstat_report_analyze's + * stats adjustments come out right. (Note: this works out + * properly when the row was both inserted and deleted in our + * xact.) + * + * The net effect of these choices is that we act as though an + * IN_PROGRESS transaction hasn't happened yet, except if it + * is our own transaction, which we assume has happened. + * + * This approach ensures that we behave sanely if we see both + * the pre-image and post-image rows for a row being updated + * by a concurrent transaction: we will sample the pre-image + * but not the post-image. We also get sane results if the + * concurrent transaction never commits. + */ + if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple->t_data))) + *deadrows += 1; + else + { + sample_it = true; + *liverows += 1; + } + break; + + default: + elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); + break; + } + + if (sample_it) + { + ExecStoreBufferHeapTuple(targtuple, slot, hscan->rs_cbuf); + hscan->rs_cindex++; + + /* note that we leave the buffer locked here! */ + return true; + } + } + + /* Now release the lock and pin on the page */ + UnlockReleaseBuffer(hscan->rs_cbuf); + hscan->rs_cbuf = InvalidBuffer; + + /* also prevent old slot contents from having pin on page */ + ExecClearTuple(slot); + + return false; +} + +static double +heapam_index_build_range_scan(Relation heapRelation, + Relation indexRelation, + IndexInfo *indexInfo, + bool allow_sync, + bool anyvisible, + bool progress, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + HeapScanDesc hscan; + bool is_system_catalog; + bool checking_uniqueness; + HeapTuple heapTuple; + Datum values[INDEX_MAX_KEYS]; + bool isnull[INDEX_MAX_KEYS]; + double reltuples; + ExprState *predicate; + TupleTableSlot *slot; + EState *estate; + ExprContext *econtext; + Snapshot snapshot; + bool need_unregister_snapshot = false; + TransactionId OldestXmin; + BlockNumber previous_blkno = InvalidBlockNumber; + BlockNumber root_blkno = InvalidBlockNumber; + OffsetNumber root_offsets[MaxHeapTuplesPerPage]; + + /* + * sanity checks + */ + Assert(OidIsValid(indexRelation->rd_rel->relam)); + + /* Remember if it's a system catalog */ + is_system_catalog = IsSystemRelation(heapRelation); + + /* See whether we're verifying uniqueness/exclusion properties */ + checking_uniqueness = (indexInfo->ii_Unique || + indexInfo->ii_ExclusionOps != NULL); + + /* + * "Any visible" mode is not compatible with uniqueness checks; make sure + * only one of those is requested. + */ + Assert(!(anyvisible && checking_uniqueness)); + + /* + * Need an EState for evaluation of index expressions and partial-index + * predicates. Also a slot to hold the current tuple. + */ + estate = CreateExecutorState(); + econtext = GetPerTupleExprContext(estate); + slot = table_slot_create(heapRelation, NULL); + + /* Arrange for econtext's scan tuple to be the tuple under test */ + econtext->ecxt_scantuple = slot; + + /* Set up execution state for predicate, if any. */ + predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate); + + /* + * Prepare for scan of the base relation. In a normal index build, we use + * SnapshotAny because we must retrieve all tuples and do our own time + * qual checks (because we have to index RECENTLY_DEAD tuples). In a + * concurrent build, or during bootstrap, we take a regular MVCC snapshot + * and index whatever's live according to that. + */ + OldestXmin = InvalidTransactionId; + + /* okay to ignore lazy VACUUMs here */ + if (!IsBootstrapProcessingMode() && !indexInfo->ii_Concurrent) + OldestXmin = GetOldestXmin(heapRelation, PROCARRAY_FLAGS_VACUUM); + + if (!scan) + { + /* + * Serial index build. + * + * Must begin our own heap scan in this case. We may also need to + * register a snapshot whose lifetime is under our direct control. + */ + if (!TransactionIdIsValid(OldestXmin)) + { + snapshot = RegisterSnapshot(GetTransactionSnapshot()); + need_unregister_snapshot = true; + } + else + snapshot = SnapshotAny; + + scan = table_beginscan_strat(heapRelation, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + true, /* buffer access strategy OK */ + allow_sync); /* syncscan OK? */ + } + else + { + /* + * Parallel index build. + * + * Parallel case never registers/unregisters own snapshot. Snapshot + * is taken from parallel heap scan, and is SnapshotAny or an MVCC + * snapshot, based on same criteria as serial case. + */ + Assert(!IsBootstrapProcessingMode()); + Assert(allow_sync); + snapshot = scan->rs_snapshot; + } + + hscan = (HeapScanDesc) scan; + + /* Publish number of blocks to scan */ + if (progress) + { + BlockNumber nblocks; + + if (hscan->rs_base.rs_parallel != NULL) + { + ParallelBlockTableScanDesc pbscan; + + pbscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel; + nblocks = pbscan->phs_nblocks; + } + else + nblocks = hscan->rs_nblocks; + + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL, + nblocks); + } + + /* + * Must call GetOldestXmin() with SnapshotAny. Should never call + * GetOldestXmin() with MVCC snapshot. (It's especially worth checking + * this for parallel builds, since ambuild routines that support parallel + * builds must work these details out for themselves.) + */ + Assert(snapshot == SnapshotAny || IsMVCCSnapshot(snapshot)); + Assert(snapshot == SnapshotAny ? TransactionIdIsValid(OldestXmin) : + !TransactionIdIsValid(OldestXmin)); + Assert(snapshot == SnapshotAny || !anyvisible); + + /* set our scan endpoints */ + if (!allow_sync) + heap_setscanlimits(scan, start_blockno, numblocks); + else + { + /* syncscan can only be requested on whole relation */ + Assert(start_blockno == 0); + Assert(numblocks == InvalidBlockNumber); + } + + reltuples = 0; + + /* + * Scan all tuples in the base relation. + */ + while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + bool tupleIsAlive; + + CHECK_FOR_INTERRUPTS(); + + /* Report scan progress, if asked to. */ + if (progress) + { + BlockNumber blocks_done = heapam_scan_get_blocks_done(hscan); + + if (blocks_done != previous_blkno) + { + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, + blocks_done); + previous_blkno = blocks_done; + } + } + + /* + * When dealing with a HOT-chain of updated tuples, we want to index + * the values of the live tuple (if any), but index it under the TID + * of the chain's root tuple. This approach is necessary to preserve + * the HOT-chain structure in the heap. So we need to be able to find + * the root item offset for every tuple that's in a HOT-chain. When + * first reaching a new page of the relation, call + * heap_get_root_tuples() to build a map of root item offsets on the + * page. + * + * It might look unsafe to use this information across buffer + * lock/unlock. However, we hold ShareLock on the table so no + * ordinary insert/update/delete should occur; and we hold pin on the + * buffer continuously while visiting the page, so no pruning + * operation can occur either. + * + * Also, although our opinions about tuple liveness could change while + * we scan the page (due to concurrent transaction commits/aborts), + * the chain root locations won't, so this info doesn't need to be + * rebuilt after waiting for another transaction. + * + * Note the implied assumption that there is no more than one live + * tuple per HOT-chain --- else we could create more than one index + * entry pointing to the same root tuple. + */ + if (hscan->rs_cblock != root_blkno) + { + Page page = BufferGetPage(hscan->rs_cbuf); + + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); + heap_get_root_tuples(page, root_offsets); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + + root_blkno = hscan->rs_cblock; + } + + if (snapshot == SnapshotAny) + { + /* do our own time qual check */ + bool indexIt; + TransactionId xwait; + + recheck: + + /* + * We could possibly get away with not locking the buffer here, + * since caller should hold ShareLock on the relation, but let's + * be conservative about it. (This remark is still correct even + * with HOT-pruning: our pin on the buffer prevents pruning.) + */ + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); + + /* + * The criteria for counting a tuple as live in this block need to + * match what analyze.c's heapam_scan_analyze_next_tuple() does, + * otherwise CREATE INDEX and ANALYZE may produce wildly different + * reltuples values, e.g. when there are many recently-dead + * tuples. + */ + switch (HeapTupleSatisfiesVacuum(heapTuple, OldestXmin, + hscan->rs_cbuf)) + { + case HEAPTUPLE_DEAD: + /* Definitely dead, we can ignore it */ + indexIt = false; + tupleIsAlive = false; + break; + case HEAPTUPLE_LIVE: + /* Normal case, index and unique-check it */ + indexIt = true; + tupleIsAlive = true; + /* Count it as live, too */ + reltuples += 1; + break; + case HEAPTUPLE_RECENTLY_DEAD: + + /* + * If tuple is recently deleted then we must index it + * anyway to preserve MVCC semantics. (Pre-existing + * transactions could try to use the index after we finish + * building it, and may need to see such tuples.) + * + * However, if it was HOT-updated then we must only index + * the live tuple at the end of the HOT-chain. Since this + * breaks semantics for pre-existing snapshots, mark the + * index as unusable for them. + * + * We don't count recently-dead tuples in reltuples, even + * if we index them; see heapam_scan_analyze_next_tuple(). + */ + if (HeapTupleIsHotUpdated(heapTuple)) + { + indexIt = false; + /* mark the index as unsafe for old snapshots */ + indexInfo->ii_BrokenHotChain = true; + } + else + indexIt = true; + /* In any case, exclude the tuple from unique-checking */ + tupleIsAlive = false; + break; + case HEAPTUPLE_INSERT_IN_PROGRESS: + + /* + * In "anyvisible" mode, this tuple is visible and we + * don't need any further checks. + */ + if (anyvisible) + { + indexIt = true; + tupleIsAlive = true; + reltuples += 1; + break; + } + + /* + * Since caller should hold ShareLock or better, normally + * the only way to see this is if it was inserted earlier + * in our own transaction. However, it can happen in + * system catalogs, since we tend to release write lock + * before commit there. Give a warning if neither case + * applies. + */ + xwait = HeapTupleHeaderGetXmin(heapTuple->t_data); + if (!TransactionIdIsCurrentTransactionId(xwait)) + { + if (!is_system_catalog) + elog(WARNING, "concurrent insert in progress within table \"%s\"", + RelationGetRelationName(heapRelation)); + + /* + * If we are performing uniqueness checks, indexing + * such a tuple could lead to a bogus uniqueness + * failure. In that case we wait for the inserting + * transaction to finish and check again. + */ + if (checking_uniqueness) + { + /* + * Must drop the lock on the buffer before we wait + */ + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + XactLockTableWait(xwait, heapRelation, + &heapTuple->t_self, + XLTW_InsertIndexUnique); + CHECK_FOR_INTERRUPTS(); + goto recheck; + } + } + else + { + /* + * For consistency with + * heapam_scan_analyze_next_tuple(), count + * HEAPTUPLE_INSERT_IN_PROGRESS tuples as live only + * when inserted by our own transaction. + */ + reltuples += 1; + } + + /* + * We must index such tuples, since if the index build + * commits then they're good. + */ + indexIt = true; + tupleIsAlive = true; + break; + case HEAPTUPLE_DELETE_IN_PROGRESS: + + /* + * As with INSERT_IN_PROGRESS case, this is unexpected + * unless it's our own deletion or a system catalog; but + * in anyvisible mode, this tuple is visible. + */ + if (anyvisible) + { + indexIt = true; + tupleIsAlive = false; + reltuples += 1; + break; + } + + xwait = HeapTupleHeaderGetUpdateXid(heapTuple->t_data); + if (!TransactionIdIsCurrentTransactionId(xwait)) + { + if (!is_system_catalog) + elog(WARNING, "concurrent delete in progress within table \"%s\"", + RelationGetRelationName(heapRelation)); + + /* + * If we are performing uniqueness checks, assuming + * the tuple is dead could lead to missing a + * uniqueness violation. In that case we wait for the + * deleting transaction to finish and check again. + * + * Also, if it's a HOT-updated tuple, we should not + * index it but rather the live tuple at the end of + * the HOT-chain. However, the deleting transaction + * could abort, possibly leaving this tuple as live + * after all, in which case it has to be indexed. The + * only way to know what to do is to wait for the + * deleting transaction to finish and check again. + */ + if (checking_uniqueness || + HeapTupleIsHotUpdated(heapTuple)) + { + /* + * Must drop the lock on the buffer before we wait + */ + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + XactLockTableWait(xwait, heapRelation, + &heapTuple->t_self, + XLTW_InsertIndexUnique); + CHECK_FOR_INTERRUPTS(); + goto recheck; + } + + /* + * Otherwise index it but don't check for uniqueness, + * the same as a RECENTLY_DEAD tuple. + */ + indexIt = true; + + /* + * Count HEAPTUPLE_DELETE_IN_PROGRESS tuples as live, + * if they were not deleted by the current + * transaction. That's what + * heapam_scan_analyze_next_tuple() does, and we want + * the behavior to be consistent. + */ + reltuples += 1; + } + else if (HeapTupleIsHotUpdated(heapTuple)) + { + /* + * It's a HOT-updated tuple deleted by our own xact. + * We can assume the deletion will commit (else the + * index contents don't matter), so treat the same as + * RECENTLY_DEAD HOT-updated tuples. + */ + indexIt = false; + /* mark the index as unsafe for old snapshots */ + indexInfo->ii_BrokenHotChain = true; + } + else + { + /* + * It's a regular tuple deleted by our own xact. Index + * it, but don't check for uniqueness nor count in + * reltuples, the same as a RECENTLY_DEAD tuple. + */ + indexIt = true; + } + /* In any case, exclude the tuple from unique-checking */ + tupleIsAlive = false; + break; + default: + elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); + indexIt = tupleIsAlive = false; /* keep compiler quiet */ + break; + } + + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + + if (!indexIt) + continue; + } + else + { + /* heap_getnext did the time qual check */ + tupleIsAlive = true; + reltuples += 1; + } + + MemoryContextReset(econtext->ecxt_per_tuple_memory); + + /* Set up for predicate or expression evaluation */ + ExecStoreBufferHeapTuple(heapTuple, slot, hscan->rs_cbuf); + + /* + * In a partial index, discard tuples that don't satisfy the + * predicate. + */ + if (predicate != NULL) + { + if (!ExecQual(predicate, econtext)) + continue; + } + + /* + * For the current heap tuple, extract all the attributes we use in + * this index, and note which are null. This also performs evaluation + * of any expressions needed. + */ + FormIndexDatum(indexInfo, + slot, + estate, + values, + isnull); + + /* + * You'd think we should go ahead and build the index tuple here, but + * some index AMs want to do further processing on the data first. So + * pass the values[] and isnull[] arrays, instead. + */ + + if (HeapTupleIsHeapOnly(heapTuple)) + { + /* + * For a heap-only tuple, pretend its TID is that of the root. See + * src/backend/access/heap/README.HOT for discussion. + */ + HeapTupleData rootTuple; + OffsetNumber offnum; + + rootTuple = *heapTuple; + offnum = ItemPointerGetOffsetNumber(&heapTuple->t_self); + + if (!OffsetNumberIsValid(root_offsets[offnum - 1])) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"", + ItemPointerGetBlockNumber(&heapTuple->t_self), + offnum, + RelationGetRelationName(heapRelation)))); + + ItemPointerSetOffsetNumber(&rootTuple.t_self, + root_offsets[offnum - 1]); + + /* Call the AM's callback routine to process the tuple */ + callback(indexRelation, &rootTuple, values, isnull, tupleIsAlive, + callback_state); + } + else + { + /* Call the AM's callback routine to process the tuple */ + callback(indexRelation, heapTuple, values, isnull, tupleIsAlive, + callback_state); + } + } + + /* Report scan progress one last time. */ + if (progress) + { + BlockNumber blks_done; + + if (hscan->rs_base.rs_parallel != NULL) + { + ParallelBlockTableScanDesc pbscan; + + pbscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel; + blks_done = pbscan->phs_nblocks; + } + else + blks_done = hscan->rs_nblocks; + + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, + blks_done); + } + + table_endscan(scan); + + /* we can now forget our snapshot, if set and registered by us */ + if (need_unregister_snapshot) + UnregisterSnapshot(snapshot); + + ExecDropSingleTupleTableSlot(slot); + + FreeExecutorState(estate); + + /* These may have been pointing to the now-gone estate */ + indexInfo->ii_ExpressionsState = NIL; + indexInfo->ii_PredicateState = NULL; + + return reltuples; +} + +static void +heapam_index_validate_scan(Relation heapRelation, + Relation indexRelation, + IndexInfo *indexInfo, + Snapshot snapshot, + ValidateIndexState *state) +{ + TableScanDesc scan; + HeapScanDesc hscan; + HeapTuple heapTuple; + Datum values[INDEX_MAX_KEYS]; + bool isnull[INDEX_MAX_KEYS]; + ExprState *predicate; + TupleTableSlot *slot; + EState *estate; + ExprContext *econtext; + BlockNumber root_blkno = InvalidBlockNumber; + OffsetNumber root_offsets[MaxHeapTuplesPerPage]; + bool in_index[MaxHeapTuplesPerPage]; + BlockNumber previous_blkno = InvalidBlockNumber; + + /* state variables for the merge */ + ItemPointer indexcursor = NULL; + ItemPointerData decoded; + bool tuplesort_empty = false; + + /* + * sanity checks + */ + Assert(OidIsValid(indexRelation->rd_rel->relam)); + + /* + * Need an EState for evaluation of index expressions and partial-index + * predicates. Also a slot to hold the current tuple. + */ + estate = CreateExecutorState(); + econtext = GetPerTupleExprContext(estate); + slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation), + &TTSOpsHeapTuple); + + /* Arrange for econtext's scan tuple to be the tuple under test */ + econtext->ecxt_scantuple = slot; + + /* Set up execution state for predicate, if any. */ + predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate); + + /* + * Prepare for scan of the base relation. We need just those tuples + * satisfying the passed-in reference snapshot. We must disable syncscan + * here, because it's critical that we read from block zero forward to + * match the sorted TIDs. + */ + scan = table_beginscan_strat(heapRelation, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + true, /* buffer access strategy OK */ + false); /* syncscan not OK */ + hscan = (HeapScanDesc) scan; + + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL, + hscan->rs_nblocks); + + /* + * Scan all tuples matching the snapshot. + */ + while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + ItemPointer heapcursor = &heapTuple->t_self; + ItemPointerData rootTuple; + OffsetNumber root_offnum; + + CHECK_FOR_INTERRUPTS(); + + state->htups += 1; + + if ((previous_blkno == InvalidBlockNumber) || + (hscan->rs_cblock != previous_blkno)) + { + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, + hscan->rs_cblock); + previous_blkno = hscan->rs_cblock; + } + + /* + * As commented in table_index_build_scan, we should index heap-only + * tuples under the TIDs of their root tuples; so when we advance onto + * a new heap page, build a map of root item offsets on the page. + * + * This complicates merging against the tuplesort output: we will + * visit the live tuples in order by their offsets, but the root + * offsets that we need to compare against the index contents might be + * ordered differently. So we might have to "look back" within the + * tuplesort output, but only within the current page. We handle that + * by keeping a bool array in_index[] showing all the + * already-passed-over tuplesort output TIDs of the current page. We + * clear that array here, when advancing onto a new heap page. + */ + if (hscan->rs_cblock != root_blkno) + { + Page page = BufferGetPage(hscan->rs_cbuf); + + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); + heap_get_root_tuples(page, root_offsets); + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + + memset(in_index, 0, sizeof(in_index)); + + root_blkno = hscan->rs_cblock; + } + + /* Convert actual tuple TID to root TID */ + rootTuple = *heapcursor; + root_offnum = ItemPointerGetOffsetNumber(heapcursor); + + if (HeapTupleIsHeapOnly(heapTuple)) + { + root_offnum = root_offsets[root_offnum - 1]; + if (!OffsetNumberIsValid(root_offnum)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_internal("failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"", + ItemPointerGetBlockNumber(heapcursor), + ItemPointerGetOffsetNumber(heapcursor), + RelationGetRelationName(heapRelation)))); + ItemPointerSetOffsetNumber(&rootTuple, root_offnum); + } + + /* + * "merge" by skipping through the index tuples until we find or pass + * the current root tuple. + */ + while (!tuplesort_empty && + (!indexcursor || + ItemPointerCompare(indexcursor, &rootTuple) < 0)) + { + Datum ts_val; + bool ts_isnull; + + if (indexcursor) + { + /* + * Remember index items seen earlier on the current heap page + */ + if (ItemPointerGetBlockNumber(indexcursor) == root_blkno) + in_index[ItemPointerGetOffsetNumber(indexcursor) - 1] = true; + } + + tuplesort_empty = !tuplesort_getdatum(state->tuplesort, true, + &ts_val, &ts_isnull, NULL); + Assert(tuplesort_empty || !ts_isnull); + if (!tuplesort_empty) + { + itemptr_decode(&decoded, DatumGetInt64(ts_val)); + indexcursor = &decoded; + + /* If int8 is pass-by-ref, free (encoded) TID Datum memory */ +#ifndef USE_FLOAT8_BYVAL + pfree(DatumGetPointer(ts_val)); +#endif + } + else + { + /* Be tidy */ + indexcursor = NULL; + } + } + + /* + * If the tuplesort has overshot *and* we didn't see a match earlier, + * then this tuple is missing from the index, so insert it. + */ + if ((tuplesort_empty || + ItemPointerCompare(indexcursor, &rootTuple) > 0) && + !in_index[root_offnum - 1]) + { + MemoryContextReset(econtext->ecxt_per_tuple_memory); + + /* Set up for predicate or expression evaluation */ + ExecStoreHeapTuple(heapTuple, slot, false); + + /* + * In a partial index, discard tuples that don't satisfy the + * predicate. + */ + if (predicate != NULL) + { + if (!ExecQual(predicate, econtext)) + continue; + } + + /* + * For the current heap tuple, extract all the attributes we use + * in this index, and note which are null. This also performs + * evaluation of any expressions needed. + */ + FormIndexDatum(indexInfo, + slot, + estate, + values, + isnull); + + /* + * You'd think we should go ahead and build the index tuple here, + * but some index AMs want to do further processing on the data + * first. So pass the values[] and isnull[] arrays, instead. + */ + + /* + * If the tuple is already committed dead, you might think we + * could suppress uniqueness checking, but this is no longer true + * in the presence of HOT, because the insert is actually a proxy + * for a uniqueness check on the whole HOT-chain. That is, the + * tuple we have here could be dead because it was already + * HOT-updated, and if so the updating transaction will not have + * thought it should insert index entries. The index AM will + * check the whole HOT-chain and correctly detect a conflict if + * there is one. + */ + + index_insert(indexRelation, + values, + isnull, + &rootTuple, + heapRelation, + indexInfo->ii_Unique ? + UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, + indexInfo); + + state->tups_inserted += 1; + } + } + + table_endscan(scan); + + ExecDropSingleTupleTableSlot(slot); + + FreeExecutorState(estate); + + /* These may have been pointing to the now-gone estate */ + indexInfo->ii_ExpressionsState = NIL; + indexInfo->ii_PredicateState = NULL; +} + +/* + * Return the number of blocks that have been read by this scan since + * starting. This is meant for progress reporting rather than be fully + * accurate: in a parallel scan, workers can be concurrently reading blocks + * further ahead than what we report. + */ +static BlockNumber +heapam_scan_get_blocks_done(HeapScanDesc hscan) +{ + ParallelBlockTableScanDesc bpscan = NULL; + BlockNumber startblock; + BlockNumber blocks_done; + + if (hscan->rs_base.rs_parallel != NULL) + { + bpscan = (ParallelBlockTableScanDesc) hscan->rs_base.rs_parallel; + startblock = bpscan->phs_startblock; + } + else + startblock = hscan->rs_startblock; + + /* + * Might have wrapped around the end of the relation, if startblock was + * not zero. + */ + if (hscan->rs_cblock > startblock) + blocks_done = hscan->rs_cblock - startblock; + else + { + BlockNumber nblocks; + + nblocks = bpscan != NULL ? bpscan->phs_nblocks : hscan->rs_nblocks; + blocks_done = nblocks - startblock + + hscan->rs_cblock; + } + + return blocks_done; +} + + +/* ------------------------------------------------------------------------ + * Miscellaneous callbacks for the heap AM + * ------------------------------------------------------------------------ + */ + +/* + * Check to see whether the table needs a TOAST table. It does only if + * (1) there are any toastable attributes, and (2) the maximum length + * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to + * create a toast table for something like "f1 varchar(20)".) + */ +static bool +heapam_relation_needs_toast_table(Relation rel) +{ + int32 data_length = 0; + bool maxlength_unknown = false; + bool has_toastable_attrs = false; + TupleDesc tupdesc = rel->rd_att; + int32 tuple_length; + int i; + + for (i = 0; i < tupdesc->natts; i++) + { + Form_pg_attribute att = TupleDescAttr(tupdesc, i); + + if (att->attisdropped) + continue; + data_length = att_align_nominal(data_length, att->attalign); + if (att->attlen > 0) + { + /* Fixed-length types are never toastable */ + data_length += att->attlen; + } + else + { + int32 maxlen = type_maximum_size(att->atttypid, + att->atttypmod); + + if (maxlen < 0) + maxlength_unknown = true; + else + data_length += maxlen; + if (att->attstorage != 'p') + has_toastable_attrs = true; + } + } + if (!has_toastable_attrs) + return false; /* nothing to toast? */ + if (maxlength_unknown) + return true; /* any unlimited-length attrs? */ + tuple_length = MAXALIGN(SizeofHeapTupleHeader + + BITMAPLEN(tupdesc->natts)) + + MAXALIGN(data_length); + return (tuple_length > TOAST_TUPLE_THRESHOLD); +} + + +/* ------------------------------------------------------------------------ + * Planner related callbacks for the heap AM + * ------------------------------------------------------------------------ + */ + +#define HEAP_OVERHEAD_BYTES_PER_TUPLE \ + (MAXALIGN(SizeofHeapTupleHeader) + sizeof(ItemIdData)) +#define HEAP_USABLE_BYTES_PER_PAGE \ + (BLCKSZ - SizeOfPageHeaderData) + +static void +heapam_estimate_rel_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac) +{ + table_block_relation_estimate_size(rel, attr_widths, pages, + tuples, allvisfrac, + HEAP_OVERHEAD_BYTES_PER_TUPLE, + HEAP_USABLE_BYTES_PER_PAGE); +} + + +/* ------------------------------------------------------------------------ + * Executor related callbacks for the heap AM + * ------------------------------------------------------------------------ + */ + +static bool +heapam_scan_bitmap_next_block(TableScanDesc scan, + TBMIterateResult *tbmres) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + BlockNumber page = tbmres->blockno; + Buffer buffer; + Snapshot snapshot; + int ntup; + + hscan->rs_cindex = 0; + hscan->rs_ntuples = 0; + + /* + * Ignore any claimed entries past what we think is the end of the + * relation. It may have been extended after the start of our scan (we + * only hold an AccessShareLock, and it could be inserts from this + * backend). + */ + if (page >= hscan->rs_nblocks) + return false; + + /* + * Acquire pin on the target heap page, trading in any pin we held before. + */ + hscan->rs_cbuf = ReleaseAndReadBuffer(hscan->rs_cbuf, + scan->rs_rd, + page); + hscan->rs_cblock = page; + buffer = hscan->rs_cbuf; + snapshot = scan->rs_snapshot; + + ntup = 0; + + /* + * Prune and repair fragmentation for the whole page, if possible. + */ + heap_page_prune_opt(scan->rs_rd, buffer); + + /* + * We must hold share lock on the buffer content while examining tuple + * visibility. Afterwards, however, the tuples we have found to be + * visible are guaranteed good as long as we hold the buffer pin. + */ + LockBuffer(buffer, BUFFER_LOCK_SHARE); + + /* + * We need two separate strategies for lossy and non-lossy cases. + */ + if (tbmres->ntuples >= 0) + { + /* + * Bitmap is non-lossy, so we just look through the offsets listed in + * tbmres; but we have to follow any HOT chain starting at each such + * offset. + */ + int curslot; + + for (curslot = 0; curslot < tbmres->ntuples; curslot++) + { + OffsetNumber offnum = tbmres->offsets[curslot]; + ItemPointerData tid; + HeapTupleData heapTuple; + + ItemPointerSet(&tid, page, offnum); + if (heap_hot_search_buffer(&tid, scan->rs_rd, buffer, snapshot, + &heapTuple, NULL, true)) + hscan->rs_vistuples[ntup++] = ItemPointerGetOffsetNumber(&tid); + } + } + else + { + /* + * Bitmap is lossy, so we must examine each line pointer on the page. + * But we can ignore HOT chains, since we'll check each tuple anyway. + */ + Page dp = (Page) BufferGetPage(buffer); + OffsetNumber maxoff = PageGetMaxOffsetNumber(dp); + OffsetNumber offnum; + + for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) + { + ItemId lp; + HeapTupleData loctup; + bool valid; + + lp = PageGetItemId(dp, offnum); + if (!ItemIdIsNormal(lp)) + continue; + loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); + loctup.t_len = ItemIdGetLength(lp); + loctup.t_tableOid = scan->rs_rd->rd_id; + ItemPointerSet(&loctup.t_self, page, offnum); + valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer); + if (valid) + { + hscan->rs_vistuples[ntup++] = offnum; + PredicateLockTuple(scan->rs_rd, &loctup, snapshot); + } + CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup, + buffer, snapshot); + } + } + + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + + Assert(ntup <= MaxHeapTuplesPerPage); + hscan->rs_ntuples = ntup; + + return ntup > 0; +} + +static bool +heapam_scan_bitmap_next_tuple(TableScanDesc scan, + TBMIterateResult *tbmres, + TupleTableSlot *slot) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + OffsetNumber targoffset; + Page dp; + ItemId lp; + + /* + * Out of range? If so, nothing more to look at on this page + */ + if (hscan->rs_cindex < 0 || hscan->rs_cindex >= hscan->rs_ntuples) + return false; + + targoffset = hscan->rs_vistuples[hscan->rs_cindex]; + dp = (Page) BufferGetPage(hscan->rs_cbuf); + lp = PageGetItemId(dp, targoffset); + Assert(ItemIdIsNormal(lp)); + + hscan->rs_ctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); + hscan->rs_ctup.t_len = ItemIdGetLength(lp); + hscan->rs_ctup.t_tableOid = scan->rs_rd->rd_id; + ItemPointerSet(&hscan->rs_ctup.t_self, hscan->rs_cblock, targoffset); + + pgstat_count_heap_fetch(scan->rs_rd); + + /* + * Set up the result slot to point to this tuple. Note that the slot + * acquires a pin on the buffer. + */ + ExecStoreBufferHeapTuple(&hscan->rs_ctup, + slot, + hscan->rs_cbuf); + + hscan->rs_cindex++; + + return true; +} + +static bool +heapam_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + TsmRoutine *tsm = scanstate->tsmroutine; + BlockNumber blockno; + + /* return false immediately if relation is empty */ + if (hscan->rs_nblocks == 0) + return false; + + if (tsm->NextSampleBlock) + { + blockno = tsm->NextSampleBlock(scanstate, hscan->rs_nblocks); + hscan->rs_cblock = blockno; + } + else + { + /* scanning table sequentially */ + + if (hscan->rs_cblock == InvalidBlockNumber) + { + Assert(!hscan->rs_inited); + blockno = hscan->rs_startblock; + } + else + { + Assert(hscan->rs_inited); + + blockno = hscan->rs_cblock + 1; + + if (blockno >= hscan->rs_nblocks) + { + /* wrap to beginning of rel, might not have started at 0 */ + blockno = 0; + } + + /* + * Report our new scan position for synchronization purposes. + * + * Note: we do this before checking for end of scan so that the + * final state of the position hint is back at the start of the + * rel. That's not strictly necessary, but otherwise when you run + * the same query multiple times the starting position would shift + * a little bit backwards on every invocation, which is confusing. + * We don't guarantee any specific ordering in general, though. + */ + if (scan->rs_flags & SO_ALLOW_SYNC) + ss_report_location(scan->rs_rd, blockno); + + if (blockno == hscan->rs_startblock) + { + blockno = InvalidBlockNumber; + } + } + } + + if (!BlockNumberIsValid(blockno)) + { + if (BufferIsValid(hscan->rs_cbuf)) + ReleaseBuffer(hscan->rs_cbuf); + hscan->rs_cbuf = InvalidBuffer; + hscan->rs_cblock = InvalidBlockNumber; + hscan->rs_inited = false; + + return false; + } + + heapgetpage(scan, blockno); + hscan->rs_inited = true; + + return true; +} + +static bool +heapam_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate, + TupleTableSlot *slot) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + TsmRoutine *tsm = scanstate->tsmroutine; + BlockNumber blockno = hscan->rs_cblock; + bool pagemode = (scan->rs_flags & SO_ALLOW_PAGEMODE) != 0; + + Page page; + bool all_visible; + OffsetNumber maxoffset; + + /* + * When not using pagemode, we must lock the buffer during tuple + * visibility checks. + */ + if (!pagemode) + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE); + + page = (Page) BufferGetPage(hscan->rs_cbuf); + all_visible = PageIsAllVisible(page) && + !scan->rs_snapshot->takenDuringRecovery; + maxoffset = PageGetMaxOffsetNumber(page); + + for (;;) + { + OffsetNumber tupoffset; + + CHECK_FOR_INTERRUPTS(); + + /* Ask the tablesample method which tuples to check on this page. */ + tupoffset = tsm->NextSampleTuple(scanstate, + blockno, + maxoffset); + + if (OffsetNumberIsValid(tupoffset)) + { + ItemId itemid; + bool visible; + HeapTuple tuple = &(hscan->rs_ctup); + + /* Skip invalid tuple pointers. */ + itemid = PageGetItemId(page, tupoffset); + if (!ItemIdIsNormal(itemid)) + continue; + + tuple->t_data = (HeapTupleHeader) PageGetItem(page, itemid); + tuple->t_len = ItemIdGetLength(itemid); + ItemPointerSet(&(tuple->t_self), blockno, tupoffset); + + + if (all_visible) + visible = true; + else + visible = SampleHeapTupleVisible(scan, hscan->rs_cbuf, + tuple, tupoffset); + + /* in pagemode, heapgetpage did this for us */ + if (!pagemode) + CheckForSerializableConflictOut(visible, scan->rs_rd, tuple, + hscan->rs_cbuf, scan->rs_snapshot); + + /* Try next tuple from same page. */ + if (!visible) + continue; + + /* Found visible tuple, return it. */ + if (!pagemode) + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + + ExecStoreBufferHeapTuple(tuple, slot, hscan->rs_cbuf); + + /* Count successfully-fetched tuples as heap fetches */ + pgstat_count_heap_getnext(scan->rs_rd); + + return true; + } + else + { + /* + * If we get here, it means we've exhausted the items on this page + * and it's time to move to the next. + */ + if (!pagemode) + LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK); + + ExecClearTuple(slot); + return false; + } + } + + Assert(0); +} + + +/* ---------------------------------------------------------------------------- + * Helper functions for the above. + * ---------------------------------------------------------------------------- + */ + +/* + * Reconstruct and rewrite the given tuple + * + * We cannot simply copy the tuple as-is, for several reasons: + * + * 1. We'd like to squeeze out the values of any dropped columns, both + * to save space and to ensure we have no corner-case failures. (It's + * possible for example that the new table hasn't got a TOAST table + * and so is unable to store any large values of dropped cols.) + * + * 2. The tuple might not even be legal for the new table; this is + * currently only known to happen as an after-effect of ALTER TABLE + * SET WITHOUT OIDS. + * + * So, we must reconstruct the tuple from component Datums. + */ +static void +reform_and_rewrite_tuple(HeapTuple tuple, + Relation OldHeap, Relation NewHeap, + Datum *values, bool *isnull, RewriteState rwstate) +{ + TupleDesc oldTupDesc = RelationGetDescr(OldHeap); + TupleDesc newTupDesc = RelationGetDescr(NewHeap); + HeapTuple copiedTuple; + int i; + + heap_deform_tuple(tuple, oldTupDesc, values, isnull); + + /* Be sure to null out any dropped columns */ + for (i = 0; i < newTupDesc->natts; i++) + { + if (TupleDescAttr(newTupDesc, i)->attisdropped) + isnull[i] = true; + } + + copiedTuple = heap_form_tuple(newTupDesc, values, isnull); + + /* The heap rewrite module does the rest */ + rewrite_heap_tuple(rwstate, tuple, copiedTuple); + + heap_freetuple(copiedTuple); +} + +/* + * Check visibility of the tuple. + */ +static bool +SampleHeapTupleVisible(TableScanDesc scan, Buffer buffer, + HeapTuple tuple, + OffsetNumber tupoffset) +{ + HeapScanDesc hscan = (HeapScanDesc) scan; + + if (scan->rs_flags & SO_ALLOW_PAGEMODE) + { + /* + * In pageatatime mode, heapgetpage() already did visibility checks, + * so just look at the info it left in rs_vistuples[]. + * + * We use a binary search over the known-sorted array. Note: we could + * save some effort if we insisted that NextSampleTuple select tuples + * in increasing order, but it's not clear that there would be enough + * gain to justify the restriction. + */ + int start = 0, + end = hscan->rs_ntuples - 1; + + while (start <= end) + { + int mid = (start + end) / 2; + OffsetNumber curoffset = hscan->rs_vistuples[mid]; + + if (tupoffset == curoffset) + return true; + else if (tupoffset < curoffset) + end = mid - 1; + else + start = mid + 1; + } + + return false; + } + else + { + /* Otherwise, we have to check the tuple individually. */ + return HeapTupleSatisfiesVisibility(tuple, scan->rs_snapshot, + buffer); + } +} + + +/* ------------------------------------------------------------------------ + * Definition of the heap table access method. + * ------------------------------------------------------------------------ + */ + +static const TableAmRoutine heapam_methods = { + .type = T_TableAmRoutine, + + .slot_callbacks = heapam_slot_callbacks, + + .scan_begin = heap_beginscan, + .scan_end = heap_endscan, + .scan_rescan = heap_rescan, + .scan_getnextslot = heap_getnextslot, + + .parallelscan_estimate = table_block_parallelscan_estimate, + .parallelscan_initialize = table_block_parallelscan_initialize, + .parallelscan_reinitialize = table_block_parallelscan_reinitialize, + + .index_fetch_begin = heapam_index_fetch_begin, + .index_fetch_reset = heapam_index_fetch_reset, + .index_fetch_end = heapam_index_fetch_end, + .index_fetch_tuple = heapam_index_fetch_tuple, + + .tuple_insert = heapam_tuple_insert, + .tuple_insert_speculative = heapam_tuple_insert_speculative, + .tuple_complete_speculative = heapam_tuple_complete_speculative, + .multi_insert = heap_multi_insert, + .tuple_delete = heapam_tuple_delete, + .tuple_update = heapam_tuple_update, + .tuple_lock = heapam_tuple_lock, + .finish_bulk_insert = heapam_finish_bulk_insert, + + .tuple_fetch_row_version = heapam_fetch_row_version, + .tuple_get_latest_tid = heap_get_latest_tid, + .tuple_tid_valid = heapam_tuple_tid_valid, + .tuple_satisfies_snapshot = heapam_tuple_satisfies_snapshot, + .compute_xid_horizon_for_tuples = heap_compute_xid_horizon_for_tuples, + + .relation_set_new_filenode = heapam_relation_set_new_filenode, + .relation_nontransactional_truncate = heapam_relation_nontransactional_truncate, + .relation_copy_data = heapam_relation_copy_data, + .relation_copy_for_cluster = heapam_relation_copy_for_cluster, + .relation_vacuum = heap_vacuum_rel, + .scan_analyze_next_block = heapam_scan_analyze_next_block, + .scan_analyze_next_tuple = heapam_scan_analyze_next_tuple, + .index_build_range_scan = heapam_index_build_range_scan, + .index_validate_scan = heapam_index_validate_scan, + + .relation_size = table_block_relation_size, + .relation_needs_toast_table = heapam_relation_needs_toast_table, + + .relation_estimate_size = heapam_estimate_rel_size, + + .scan_bitmap_next_block = heapam_scan_bitmap_next_block, + .scan_bitmap_next_tuple = heapam_scan_bitmap_next_tuple, + .scan_sample_next_block = heapam_scan_sample_next_block, + .scan_sample_next_tuple = heapam_scan_sample_next_tuple +}; + + +const TableAmRoutine * +GetHeapamTableAmRoutine(void) +{ + return &heapam_methods; +} + +Datum +heap_tableam_handler(PG_FUNCTION_ARGS) +{ + PG_RETURN_POINTER(&heapam_methods); +} diff --git a/src/backend/utils/time/tqual.c b/src/backend/access/heap/heapam_visibility.c similarity index 86% rename from src/backend/utils/time/tqual.c rename to src/backend/access/heap/heapam_visibility.c index f7c4c9188ce..537e681b236 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/access/heap/heapam_visibility.c @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * - * tqual.c - * POSTGRES "time qualification" code, ie, tuple visibility rules. + * heapam_visibility.c + * Tuple visibility rules for tuples stored in heap. * * NOTE: all the HeapTupleSatisfies routines will update the tuple's * "hint" status bits if we see that the inserting or deleting transaction @@ -52,20 +52,22 @@ * HeapTupleSatisfiesAny() * all tuples are visible * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * src/backend/utils/time/tqual.c + * src/backend/access/heap/heapam_visibility.c * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" #include "access/subtrans.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" @@ -74,12 +76,6 @@ #include "utils/builtins.h" #include "utils/combocid.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" - - -/* Static variables representing various special snapshot semantics */ -SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf}; -SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny}; /* @@ -152,10 +148,7 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, * HeapTupleSatisfiesSelf * True iff heap tuple is valid "for itself". * - * Here, we consider the effects of: - * all committed transactions (as of the current instant) - * previous commands of this transaction - * changes made by the current command + * See SNAPSHOT_MVCC's definition for the intended behaviour. * * Note: * Assumes heap tuple is valid. @@ -172,7 +165,7 @@ HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, * (Xmax != my-transaction && the row was deleted by another transaction * Xmax is not committed))) that has not been committed */ -bool +static bool HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer) { HeapTupleHeader tuple = htup->t_data; @@ -342,7 +335,7 @@ HeapTupleSatisfiesSelf(HeapTuple htup, Snapshot snapshot, Buffer buffer) * HeapTupleSatisfiesAny * Dummy "satisfies" routine: any tuple satisfies SnapshotAny. */ -bool +static bool HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer) { return true; @@ -352,6 +345,8 @@ HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer) * HeapTupleSatisfiesToast * True iff heap tuple is valid as a TOAST row. * + * See SNAPSHOT_TOAST's definition for the intended behaviour. + * * This is a simplified version that only checks for VACUUM moving conditions. * It's appropriate for TOAST usage because TOAST really doesn't want to do * its own time qual checks; if you can see the main table row that contains @@ -362,7 +357,7 @@ HeapTupleSatisfiesAny(HeapTuple htup, Snapshot snapshot, Buffer buffer) * Among other things, this means you can't do UPDATEs of rows in a TOAST * table. */ -bool +static bool HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, Buffer buffer) { @@ -439,24 +434,26 @@ HeapTupleSatisfiesToast(HeapTuple htup, Snapshot snapshot, * * The possible return codes are: * - * HeapTupleInvisible: the tuple didn't exist at all when the scan started, - * e.g. it was created by a later CommandId. + * TM_Invisible: the tuple didn't exist at all when the scan started, e.g. it + * was created by a later CommandId. + * + * TM_Ok: The tuple is valid and visible, so it may be updated. * - * HeapTupleMayBeUpdated: The tuple is valid and visible, so it may be - * updated. + * TM_SelfModified: The tuple was updated by the current transaction, after + * the current scan started. * - * HeapTupleSelfUpdated: The tuple was updated by the current transaction, - * after the current scan started. + * TM_Updated: The tuple was updated by a committed transaction (including + * the case where the tuple was moved into a different partition). * - * HeapTupleUpdated: The tuple was updated by a committed transaction. + * TM_Deleted: The tuple was deleted by a committed transaction. * - * HeapTupleBeingUpdated: The tuple is being updated by an in-progress - * transaction other than the current transaction. (Note: this includes - * the case where the tuple is share-locked by a MultiXact, even if the - * MultiXact includes the current transaction. Callers that want to - * distinguish that case must test for it themselves.) + * TM_BeingModified: The tuple is being updated by an in-progress transaction + * other than the current transaction. (Note: this includes the case where + * the tuple is share-locked by a MultiXact, even if the MultiXact includes + * the current transaction. Callers that want to distinguish that case must + * test for it themselves.) */ -HTSU_Result +TM_Result HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, Buffer buffer) { @@ -468,7 +465,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, if (!HeapTupleHeaderXminCommitted(tuple)) { if (HeapTupleHeaderXminInvalid(tuple)) - return HeapTupleInvisible; + return TM_Invisible; /* Used by pre-9.0 binary upgrades */ if (tuple->t_infomask & HEAP_MOVED_OFF) @@ -476,14 +473,14 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, TransactionId xvac = HeapTupleHeaderGetXvac(tuple); if (TransactionIdIsCurrentTransactionId(xvac)) - return HeapTupleInvisible; + return TM_Invisible; if (!TransactionIdIsInProgress(xvac)) { if (TransactionIdDidCommit(xvac)) { SetHintBits(tuple, buffer, HEAP_XMIN_INVALID, InvalidTransactionId); - return HeapTupleInvisible; + return TM_Invisible; } SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, InvalidTransactionId); @@ -497,7 +494,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, if (!TransactionIdIsCurrentTransactionId(xvac)) { if (TransactionIdIsInProgress(xvac)) - return HeapTupleInvisible; + return TM_Invisible; if (TransactionIdDidCommit(xvac)) SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, InvalidTransactionId); @@ -505,17 +502,17 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, { SetHintBits(tuple, buffer, HEAP_XMIN_INVALID, InvalidTransactionId); - return HeapTupleInvisible; + return TM_Invisible; } } } else if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple))) { if (HeapTupleHeaderGetCmin(tuple) >= curcid) - return HeapTupleInvisible; /* inserted after scan started */ + return TM_Invisible; /* inserted after scan started */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid */ - return HeapTupleMayBeUpdated; + return TM_Ok; if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) { @@ -533,9 +530,9 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, if (tuple->t_infomask & HEAP_XMAX_IS_MULTI) { if (MultiXactIdIsRunning(xmax, true)) - return HeapTupleBeingUpdated; + return TM_BeingModified; else - return HeapTupleMayBeUpdated; + return TM_Ok; } /* @@ -544,8 +541,8 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, * locked/updated. */ if (!TransactionIdIsInProgress(xmax)) - return HeapTupleMayBeUpdated; - return HeapTupleBeingUpdated; + return TM_Ok; + return TM_BeingModified; } if (tuple->t_infomask & HEAP_XMAX_IS_MULTI) @@ -562,17 +559,15 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, { if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false)) - return HeapTupleBeingUpdated; - return HeapTupleMayBeUpdated; + return TM_BeingModified; + return TM_Ok; } else { if (HeapTupleHeaderGetCmax(tuple) >= curcid) - return HeapTupleSelfUpdated; /* updated after scan - * started */ + return TM_SelfModified; /* updated after scan started */ else - return HeapTupleInvisible; /* updated before scan - * started */ + return TM_Invisible; /* updated before scan started */ } } @@ -581,16 +576,16 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, /* deleting subtransaction must have aborted */ SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - return HeapTupleMayBeUpdated; + return TM_Ok; } if (HeapTupleHeaderGetCmax(tuple) >= curcid) - return HeapTupleSelfUpdated; /* updated after scan started */ + return TM_SelfModified; /* updated after scan started */ else - return HeapTupleInvisible; /* updated before scan started */ + return TM_Invisible; /* updated before scan started */ } else if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple))) - return HeapTupleInvisible; + return TM_Invisible; else if (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple))) SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED, HeapTupleHeaderGetRawXmin(tuple)); @@ -599,20 +594,24 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, /* it must have aborted or crashed */ SetHintBits(tuple, buffer, HEAP_XMIN_INVALID, InvalidTransactionId); - return HeapTupleInvisible; + return TM_Invisible; } } /* by here, the inserting transaction has committed */ if (tuple->t_infomask & HEAP_XMAX_INVALID) /* xid invalid or aborted */ - return HeapTupleMayBeUpdated; + return TM_Ok; if (tuple->t_infomask & HEAP_XMAX_COMMITTED) { if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) - return HeapTupleMayBeUpdated; - return HeapTupleUpdated; /* updated by other */ + return TM_Ok; + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tuple)) + return TM_Updated; /* updated by other */ + else + return TM_Deleted; /* deleted by other */ } if (tuple->t_infomask & HEAP_XMAX_IS_MULTI) @@ -620,22 +619,22 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, TransactionId xmax; if (HEAP_LOCKED_UPGRADED(tuple->t_infomask)) - return HeapTupleMayBeUpdated; + return TM_Ok; if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) { if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), true)) - return HeapTupleBeingUpdated; + return TM_BeingModified; SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - return HeapTupleMayBeUpdated; + return TM_Ok; } xmax = HeapTupleGetUpdateXid(tuple); if (!TransactionIdIsValid(xmax)) { if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false)) - return HeapTupleBeingUpdated; + return TM_BeingModified; } /* not LOCKED_ONLY, so it has to have an xmax */ @@ -644,16 +643,22 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, if (TransactionIdIsCurrentTransactionId(xmax)) { if (HeapTupleHeaderGetCmax(tuple) >= curcid) - return HeapTupleSelfUpdated; /* updated after scan started */ + return TM_SelfModified; /* updated after scan started */ else - return HeapTupleInvisible; /* updated before scan started */ + return TM_Invisible; /* updated before scan started */ } if (MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple), false)) - return HeapTupleBeingUpdated; + return TM_BeingModified; if (TransactionIdDidCommit(xmax)) - return HeapTupleUpdated; + { + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tuple)) + return TM_Updated; + else + return TM_Deleted; + } /* * By here, the update in the Xmax is either aborted or crashed, but @@ -668,34 +673,34 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, */ SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - return HeapTupleMayBeUpdated; + return TM_Ok; } else { /* There are lockers running */ - return HeapTupleBeingUpdated; + return TM_BeingModified; } } if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple))) { if (HEAP_XMAX_IS_LOCKED_ONLY(tuple->t_infomask)) - return HeapTupleBeingUpdated; + return TM_BeingModified; if (HeapTupleHeaderGetCmax(tuple) >= curcid) - return HeapTupleSelfUpdated; /* updated after scan started */ + return TM_SelfModified; /* updated after scan started */ else - return HeapTupleInvisible; /* updated before scan started */ + return TM_Invisible; /* updated before scan started */ } if (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmax(tuple))) - return HeapTupleBeingUpdated; + return TM_BeingModified; if (!TransactionIdDidCommit(HeapTupleHeaderGetRawXmax(tuple))) { /* it must have aborted or crashed */ SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - return HeapTupleMayBeUpdated; + return TM_Ok; } /* xmax transaction committed */ @@ -704,22 +709,23 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, { SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - return HeapTupleMayBeUpdated; + return TM_Ok; } SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED, HeapTupleHeaderGetRawXmax(tuple)); - return HeapTupleUpdated; /* updated by other */ + if (!ItemPointerEquals(&htup->t_self, &tuple->t_ctid) || + HeapTupleHeaderIndicatesMovedPartitions(tuple)) + return TM_Updated; /* updated by other */ + else + return TM_Deleted; /* deleted by other */ } /* * HeapTupleSatisfiesDirty * True iff heap tuple is valid including effects of open transactions. * - * Here, we consider the effects of: - * all committed and in-progress transactions (as of the current instant) - * previous commands of this transaction - * changes made by the current command + * See SNAPSHOT_DIRTY's definition for the intended behaviour. * * This is essentially like HeapTupleSatisfiesSelf as far as effects of * the current transaction and committed/aborted xacts are concerned. @@ -735,7 +741,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid, * on the insertion without aborting the whole transaction, the associated * token is also returned in snapshot->speculativeToken. */ -bool +static bool HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot, Buffer buffer) { @@ -934,14 +940,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot, * HeapTupleSatisfiesMVCC * True iff heap tuple is valid for the given MVCC snapshot. * - * Here, we consider the effects of: - * all transactions committed as of the time of the given snapshot - * previous commands of this transaction - * - * Does _not_ include: - * transactions shown as in-progress by the snapshot - * transactions started after the snapshot was taken - * changes made by the current command + * See SNAPSHOT_MVCC's definition for the intended behaviour. * * Notice that here, we will not update the tuple status hint bits if the * inserting/deleting transaction is still running according to our snapshot, @@ -959,7 +958,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot, * inserting/deleting transaction was still running --- which was more cycles * and more contention on the PGXACT array. */ -bool +static bool HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer) { @@ -1390,11 +1389,13 @@ HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin, * True if tuple might be visible to some transaction; false if it's * surely dead to everyone, ie, vacuumable. * - * This is an interface to HeapTupleSatisfiesVacuum that meets the - * SnapshotSatisfiesFunc API, so it can be used through a Snapshot. + * See SNAPSHOT_TOAST's definition for the intended behaviour. + * + * This is an interface to HeapTupleSatisfiesVacuum that's callable via + * HeapTupleSatisfiesSnapshot, so it can be used through a Snapshot. * snapshot->xmin must have been set up with the xmin horizon to use. */ -bool +static bool HeapTupleSatisfiesNonVacuumable(HeapTuple htup, Snapshot snapshot, Buffer buffer) { @@ -1461,136 +1462,14 @@ HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin) return TransactionIdPrecedes(HeapTupleHeaderGetRawXmax(tuple), OldestXmin); } -/* - * XidInMVCCSnapshot - * Is the given XID still-in-progress according to the snapshot? - * - * Note: GetSnapshotData never stores either top xid or subxids of our own - * backend into a snapshot, so these xids will not be reported as "running" - * by this function. This is OK for current uses, because we always check - * TransactionIdIsCurrentTransactionId first, except when it's known the - * XID could not be ours anyway. - */ -bool -XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) -{ - uint32 i; - - /* - * Make a quick range check to eliminate most XIDs without looking at the - * xip arrays. Note that this is OK even if we convert a subxact XID to - * its parent below, because a subxact with XID < xmin has surely also got - * a parent with XID < xmin, while one with XID >= xmax must belong to a - * parent that was not yet committed at the time of this snapshot. - */ - - /* Any xid < xmin is not in-progress */ - if (TransactionIdPrecedes(xid, snapshot->xmin)) - return false; - /* Any xid >= xmax is in-progress */ - if (TransactionIdFollowsOrEquals(xid, snapshot->xmax)) - return true; - - /* - * Snapshot information is stored slightly differently in snapshots taken - * during recovery. - */ - if (!snapshot->takenDuringRecovery) - { - /* - * If the snapshot contains full subxact data, the fastest way to - * check things is just to compare the given XID against both subxact - * XIDs and top-level XIDs. If the snapshot overflowed, we have to - * use pg_subtrans to convert a subxact XID to its parent XID, but - * then we need only look at top-level XIDs not subxacts. - */ - if (!snapshot->suboverflowed) - { - /* we have full data, so search subxip */ - int32 j; - - for (j = 0; j < snapshot->subxcnt; j++) - { - if (TransactionIdEquals(xid, snapshot->subxip[j])) - return true; - } - - /* not there, fall through to search xip[] */ - } - else - { - /* - * Snapshot overflowed, so convert xid to top-level. This is safe - * because we eliminated too-old XIDs above. - */ - xid = SubTransGetTopmostTransaction(xid); - - /* - * If xid was indeed a subxact, we might now have an xid < xmin, - * so recheck to avoid an array scan. No point in rechecking - * xmax. - */ - if (TransactionIdPrecedes(xid, snapshot->xmin)) - return false; - } - - for (i = 0; i < snapshot->xcnt; i++) - { - if (TransactionIdEquals(xid, snapshot->xip[i])) - return true; - } - } - else - { - int32 j; - - /* - * In recovery we store all xids in the subxact array because it is by - * far the bigger array, and we mostly don't know which xids are - * top-level and which are subxacts. The xip array is empty. - * - * We start by searching subtrans, if we overflowed. - */ - if (snapshot->suboverflowed) - { - /* - * Snapshot overflowed, so convert xid to top-level. This is safe - * because we eliminated too-old XIDs above. - */ - xid = SubTransGetTopmostTransaction(xid); - - /* - * If xid was indeed a subxact, we might now have an xid < xmin, - * so recheck to avoid an array scan. No point in rechecking - * xmax. - */ - if (TransactionIdPrecedes(xid, snapshot->xmin)) - return false; - } - - /* - * We now have either a top-level xid higher than xmin or an - * indeterminate xid. We don't know whether it's top level or subxact - * but it doesn't matter. If it's present, the xid is visible. - */ - for (j = 0; j < snapshot->subxcnt; j++) - { - if (TransactionIdEquals(xid, snapshot->subxip[j])) - return true; - } - } - - return false; -} - /* * Is the tuple really only locked? That is, is it not updated? * * It's easy to check just infomask bits if the locker is not a multi; but * otherwise we need to verify that the updating transaction has not aborted. * - * This function is here because it follows the same time qualification rules - * laid out at the top of this file. + * This function is here because it follows the same visibility rules laid out + * at the top of this file. */ bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple) @@ -1659,7 +1538,7 @@ TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) * dangerous to do so as the semantics of doing so during timetravel are more * complicated than when dealing "only" with the present. */ -bool +static bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot, Buffer buffer) { @@ -1796,3 +1675,44 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot, else return true; } + +/* + * HeapTupleSatisfiesVisibility + * True iff heap tuple satisfies a time qual. + * + * Notes: + * Assumes heap tuple is valid, and buffer at least share locked. + * + * Hint bits in the HeapTuple's t_infomask may be updated as a side effect; + * if so, the indicated buffer is marked dirty. + */ +bool +HeapTupleSatisfiesVisibility(HeapTuple tup, Snapshot snapshot, Buffer buffer) +{ + switch (snapshot->snapshot_type) + { + case SNAPSHOT_MVCC: + return HeapTupleSatisfiesMVCC(tup, snapshot, buffer); + break; + case SNAPSHOT_SELF: + return HeapTupleSatisfiesSelf(tup, snapshot, buffer); + break; + case SNAPSHOT_ANY: + return HeapTupleSatisfiesAny(tup, snapshot, buffer); + break; + case SNAPSHOT_TOAST: + return HeapTupleSatisfiesToast(tup, snapshot, buffer); + break; + case SNAPSHOT_DIRTY: + return HeapTupleSatisfiesDirty(tup, snapshot, buffer); + break; + case SNAPSHOT_HISTORIC_MVCC: + return HeapTupleSatisfiesHistoricMVCC(tup, snapshot, buffer); + break; + case SNAPSHOT_NON_VACUUMABLE: + return HeapTupleSatisfiesNonVacuumable(tup, snapshot, buffer); + break; + } + + return false; /* keep compiler quiet */ +} diff --git a/src/backend/access/heap/heaptoast.c b/src/backend/access/heap/heaptoast.c new file mode 100644 index 00000000000..fbf9294598a --- /dev/null +++ b/src/backend/access/heap/heaptoast.c @@ -0,0 +1,605 @@ +/*------------------------------------------------------------------------- + * + * heaptoast.c + * Heap-specific definitions for external and compressed storage + * of variable size attributes. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/access/heap/heaptoast.c + * + * + * INTERFACE ROUTINES + * toast_insert_or_update - + * Try to make a given tuple fit into one page by compressing + * or moving off attributes + * + * toast_delete - + * Reclaim toast storage when a tuple is deleted + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/detoast.h" +#include "access/heapam.h" +#include "access/heaptoast.h" +#include "access/toast_helper.h" +#include "access/toast_internals.h" + + +/* ---------- + * toast_delete - + * + * Cascaded delete toast-entries on DELETE + * ---------- + */ +void +toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative) +{ + TupleDesc tupleDesc; + Datum toast_values[MaxHeapAttributeNumber]; + bool toast_isnull[MaxHeapAttributeNumber]; + + /* + * We should only ever be called for tuples of plain relations or + * materialized views --- recursing on a toast rel is bad news. + */ + Assert(rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_MATVIEW); + + /* + * Get the tuple descriptor and break down the tuple into fields. + * + * NOTE: it's debatable whether to use heap_deform_tuple() here or just + * heap_getattr() only the varlena columns. The latter could win if there + * are few varlena columns and many non-varlena ones. However, + * heap_deform_tuple costs only O(N) while the heap_getattr way would cost + * O(N^2) if there are many varlena columns, so it seems better to err on + * the side of linear cost. (We won't even be here unless there's at + * least one varlena column, by the way.) + */ + tupleDesc = rel->rd_att; + + Assert(tupleDesc->natts <= MaxHeapAttributeNumber); + heap_deform_tuple(oldtup, tupleDesc, toast_values, toast_isnull); + + /* Do the real work. */ + toast_delete_external(rel, toast_values, toast_isnull, is_speculative); +} + + +/* ---------- + * toast_insert_or_update - + * + * Delete no-longer-used toast-entries and create new ones to + * make the new tuple fit on INSERT or UPDATE + * + * Inputs: + * newtup: the candidate new tuple to be inserted + * oldtup: the old row version for UPDATE, or NULL for INSERT + * options: options to be passed to heap_insert() for toast rows + * Result: + * either newtup if no toasting is needed, or a palloc'd modified tuple + * that is what should actually get stored + * + * NOTE: neither newtup nor oldtup will be modified. This is a change + * from the pre-8.1 API of this routine. + * ---------- + */ +HeapTuple +toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup, + int options) +{ + HeapTuple result_tuple; + TupleDesc tupleDesc; + int numAttrs; + + Size maxDataLen; + Size hoff; + + bool toast_isnull[MaxHeapAttributeNumber]; + bool toast_oldisnull[MaxHeapAttributeNumber]; + Datum toast_values[MaxHeapAttributeNumber]; + Datum toast_oldvalues[MaxHeapAttributeNumber]; + ToastAttrInfo toast_attr[MaxHeapAttributeNumber]; + ToastTupleContext ttc; + + /* + * Ignore the INSERT_SPECULATIVE option. Speculative insertions/super + * deletions just normally insert/delete the toast values. It seems + * easiest to deal with that here, instead on, potentially, multiple + * callers. + */ + options &= ~HEAP_INSERT_SPECULATIVE; + + /* + * We should only ever be called for tuples of plain relations or + * materialized views --- recursing on a toast rel is bad news. + */ + Assert(rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_MATVIEW); + + /* + * Get the tuple descriptor and break down the tuple(s) into fields. + */ + tupleDesc = rel->rd_att; + numAttrs = tupleDesc->natts; + + Assert(numAttrs <= MaxHeapAttributeNumber); + heap_deform_tuple(newtup, tupleDesc, toast_values, toast_isnull); + if (oldtup != NULL) + heap_deform_tuple(oldtup, tupleDesc, toast_oldvalues, toast_oldisnull); + + /* ---------- + * Prepare for toasting + * ---------- + */ + ttc.ttc_rel = rel; + ttc.ttc_values = toast_values; + ttc.ttc_isnull = toast_isnull; + if (oldtup == NULL) + { + ttc.ttc_oldvalues = NULL; + ttc.ttc_oldisnull = NULL; + } + else + { + ttc.ttc_oldvalues = toast_oldvalues; + ttc.ttc_oldisnull = toast_oldisnull; + } + ttc.ttc_attr = toast_attr; + toast_tuple_init(&ttc); + + /* ---------- + * Compress and/or save external until data fits into target length + * + * 1: Inline compress attributes with attstorage 'x', and store very + * large attributes with attstorage 'x' or 'e' external immediately + * 2: Store attributes with attstorage 'x' or 'e' external + * 3: Inline compress attributes with attstorage 'm' + * 4: Store attributes with attstorage 'm' external + * ---------- + */ + + /* compute header overhead --- this should match heap_form_tuple() */ + hoff = SizeofHeapTupleHeader; + if ((ttc.ttc_flags & TOAST_HAS_NULLS) != 0) + hoff += BITMAPLEN(numAttrs); + hoff = MAXALIGN(hoff); + /* now convert to a limit on the tuple data size */ + maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff; + + /* + * Look for attributes with attstorage 'x' to compress. Also find large + * attributes with attstorage 'x' or 'e', and store them external. + */ + while (heap_compute_data_size(tupleDesc, + toast_values, toast_isnull) > maxDataLen) + { + int biggest_attno; + + biggest_attno = toast_tuple_find_biggest_attribute(&ttc, true, false); + if (biggest_attno < 0) + break; + + /* + * Attempt to compress it inline, if it has attstorage 'x' + */ + if (TupleDescAttr(tupleDesc, biggest_attno)->attstorage == 'x') + toast_tuple_try_compression(&ttc, biggest_attno); + else + { + /* has attstorage 'e', ignore on subsequent compression passes */ + toast_attr[biggest_attno].tai_colflags |= TOASTCOL_INCOMPRESSIBLE; + } + + /* + * If this value is by itself more than maxDataLen (after compression + * if any), push it out to the toast table immediately, if possible. + * This avoids uselessly compressing other fields in the common case + * where we have one long field and several short ones. + * + * XXX maybe the threshold should be less than maxDataLen? + */ + if (toast_attr[biggest_attno].tai_size > maxDataLen && + rel->rd_rel->reltoastrelid != InvalidOid) + toast_tuple_externalize(&ttc, biggest_attno, options); + } + + /* + * Second we look for attributes of attstorage 'x' or 'e' that are still + * inline, and make them external. But skip this if there's no toast + * table to push them to. + */ + while (heap_compute_data_size(tupleDesc, + toast_values, toast_isnull) > maxDataLen && + rel->rd_rel->reltoastrelid != InvalidOid) + { + int biggest_attno; + + biggest_attno = toast_tuple_find_biggest_attribute(&ttc, false, false); + if (biggest_attno < 0) + break; + toast_tuple_externalize(&ttc, biggest_attno, options); + } + + /* + * Round 3 - this time we take attributes with storage 'm' into + * compression + */ + while (heap_compute_data_size(tupleDesc, + toast_values, toast_isnull) > maxDataLen) + { + int biggest_attno; + + biggest_attno = toast_tuple_find_biggest_attribute(&ttc, true, true); + if (biggest_attno < 0) + break; + + toast_tuple_try_compression(&ttc, biggest_attno); + } + + /* + * Finally we store attributes of type 'm' externally. At this point we + * increase the target tuple size, so that 'm' attributes aren't stored + * externally unless really necessary. + */ + maxDataLen = TOAST_TUPLE_TARGET_MAIN - hoff; + + while (heap_compute_data_size(tupleDesc, + toast_values, toast_isnull) > maxDataLen && + rel->rd_rel->reltoastrelid != InvalidOid) + { + int biggest_attno; + + biggest_attno = toast_tuple_find_biggest_attribute(&ttc, false, true); + if (biggest_attno < 0) + break; + + toast_tuple_externalize(&ttc, biggest_attno, options); + } + + /* + * In the case we toasted any values, we need to build a new heap tuple + * with the changed values. + */ + if ((ttc.ttc_flags & TOAST_NEEDS_CHANGE) != 0) + { + HeapTupleHeader olddata = newtup->t_data; + HeapTupleHeader new_data; + int32 new_header_len; + int32 new_data_len; + int32 new_tuple_len; + + /* + * Calculate the new size of the tuple. + * + * Note: we used to assume here that the old tuple's t_hoff must equal + * the new_header_len value, but that was incorrect. The old tuple + * might have a smaller-than-current natts, if there's been an ALTER + * TABLE ADD COLUMN since it was stored; and that would lead to a + * different conclusion about the size of the null bitmap, or even + * whether there needs to be one at all. + */ + new_header_len = SizeofHeapTupleHeader; + if ((ttc.ttc_flags & TOAST_HAS_NULLS) != 0) + new_header_len += BITMAPLEN(numAttrs); + new_header_len = MAXALIGN(new_header_len); + new_data_len = heap_compute_data_size(tupleDesc, + toast_values, toast_isnull); + new_tuple_len = new_header_len + new_data_len; + + /* + * Allocate and zero the space needed, and fill HeapTupleData fields. + */ + result_tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + new_tuple_len); + result_tuple->t_len = new_tuple_len; + result_tuple->t_self = newtup->t_self; + result_tuple->t_tableOid = newtup->t_tableOid; + new_data = (HeapTupleHeader) ((char *) result_tuple + HEAPTUPLESIZE); + result_tuple->t_data = new_data; + + /* + * Copy the existing tuple header, but adjust natts and t_hoff. + */ + memcpy(new_data, olddata, SizeofHeapTupleHeader); + HeapTupleHeaderSetNatts(new_data, numAttrs); + new_data->t_hoff = new_header_len; + + /* Copy over the data, and fill the null bitmap if needed */ + heap_fill_tuple(tupleDesc, + toast_values, + toast_isnull, + (char *) new_data + new_header_len, + new_data_len, + &(new_data->t_infomask), + ((ttc.ttc_flags & TOAST_HAS_NULLS) != 0) ? + new_data->t_bits : NULL); + } + else + result_tuple = newtup; + + toast_tuple_cleanup(&ttc); + + return result_tuple; +} + + +/* ---------- + * toast_flatten_tuple - + * + * "Flatten" a tuple to contain no out-of-line toasted fields. + * (This does not eliminate compressed or short-header datums.) + * + * Note: we expect the caller already checked HeapTupleHasExternal(tup), + * so there is no need for a short-circuit path. + * ---------- + */ +HeapTuple +toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc) +{ + HeapTuple new_tuple; + int numAttrs = tupleDesc->natts; + int i; + Datum toast_values[MaxTupleAttributeNumber]; + bool toast_isnull[MaxTupleAttributeNumber]; + bool toast_free[MaxTupleAttributeNumber]; + + /* + * Break down the tuple into fields. + */ + Assert(numAttrs <= MaxTupleAttributeNumber); + heap_deform_tuple(tup, tupleDesc, toast_values, toast_isnull); + + memset(toast_free, 0, numAttrs * sizeof(bool)); + + for (i = 0; i < numAttrs; i++) + { + /* + * Look at non-null varlena attributes + */ + if (!toast_isnull[i] && TupleDescAttr(tupleDesc, i)->attlen == -1) + { + struct varlena *new_value; + + new_value = (struct varlena *) DatumGetPointer(toast_values[i]); + if (VARATT_IS_EXTERNAL(new_value)) + { + new_value = heap_tuple_fetch_attr(new_value); + toast_values[i] = PointerGetDatum(new_value); + toast_free[i] = true; + } + } + } + + /* + * Form the reconfigured tuple. + */ + new_tuple = heap_form_tuple(tupleDesc, toast_values, toast_isnull); + + /* + * Be sure to copy the tuple's identity fields. We also make a point of + * copying visibility info, just in case anybody looks at those fields in + * a syscache entry. + */ + new_tuple->t_self = tup->t_self; + new_tuple->t_tableOid = tup->t_tableOid; + + new_tuple->t_data->t_choice = tup->t_data->t_choice; + new_tuple->t_data->t_ctid = tup->t_data->t_ctid; + new_tuple->t_data->t_infomask &= ~HEAP_XACT_MASK; + new_tuple->t_data->t_infomask |= + tup->t_data->t_infomask & HEAP_XACT_MASK; + new_tuple->t_data->t_infomask2 &= ~HEAP2_XACT_MASK; + new_tuple->t_data->t_infomask2 |= + tup->t_data->t_infomask2 & HEAP2_XACT_MASK; + + /* + * Free allocated temp values + */ + for (i = 0; i < numAttrs; i++) + if (toast_free[i]) + pfree(DatumGetPointer(toast_values[i])); + + return new_tuple; +} + + +/* ---------- + * toast_flatten_tuple_to_datum - + * + * "Flatten" a tuple containing out-of-line toasted fields into a Datum. + * The result is always palloc'd in the current memory context. + * + * We have a general rule that Datums of container types (rows, arrays, + * ranges, etc) must not contain any external TOAST pointers. Without + * this rule, we'd have to look inside each Datum when preparing a tuple + * for storage, which would be expensive and would fail to extend cleanly + * to new sorts of container types. + * + * However, we don't want to say that tuples represented as HeapTuples + * can't contain toasted fields, so instead this routine should be called + * when such a HeapTuple is being converted into a Datum. + * + * While we're at it, we decompress any compressed fields too. This is not + * necessary for correctness, but reflects an expectation that compression + * will be more effective if applied to the whole tuple not individual + * fields. We are not so concerned about that that we want to deconstruct + * and reconstruct tuples just to get rid of compressed fields, however. + * So callers typically won't call this unless they see that the tuple has + * at least one external field. + * + * On the other hand, in-line short-header varlena fields are left alone. + * If we "untoasted" them here, they'd just get changed back to short-header + * format anyway within heap_fill_tuple. + * ---------- + */ +Datum +toast_flatten_tuple_to_datum(HeapTupleHeader tup, + uint32 tup_len, + TupleDesc tupleDesc) +{ + HeapTupleHeader new_data; + int32 new_header_len; + int32 new_data_len; + int32 new_tuple_len; + HeapTupleData tmptup; + int numAttrs = tupleDesc->natts; + int i; + bool has_nulls = false; + Datum toast_values[MaxTupleAttributeNumber]; + bool toast_isnull[MaxTupleAttributeNumber]; + bool toast_free[MaxTupleAttributeNumber]; + + /* Build a temporary HeapTuple control structure */ + tmptup.t_len = tup_len; + ItemPointerSetInvalid(&(tmptup.t_self)); + tmptup.t_tableOid = InvalidOid; + tmptup.t_data = tup; + + /* + * Break down the tuple into fields. + */ + Assert(numAttrs <= MaxTupleAttributeNumber); + heap_deform_tuple(&tmptup, tupleDesc, toast_values, toast_isnull); + + memset(toast_free, 0, numAttrs * sizeof(bool)); + + for (i = 0; i < numAttrs; i++) + { + /* + * Look at non-null varlena attributes + */ + if (toast_isnull[i]) + has_nulls = true; + else if (TupleDescAttr(tupleDesc, i)->attlen == -1) + { + struct varlena *new_value; + + new_value = (struct varlena *) DatumGetPointer(toast_values[i]); + if (VARATT_IS_EXTERNAL(new_value) || + VARATT_IS_COMPRESSED(new_value)) + { + new_value = heap_tuple_untoast_attr(new_value); + toast_values[i] = PointerGetDatum(new_value); + toast_free[i] = true; + } + } + } + + /* + * Calculate the new size of the tuple. + * + * This should match the reconstruction code in toast_insert_or_update. + */ + new_header_len = SizeofHeapTupleHeader; + if (has_nulls) + new_header_len += BITMAPLEN(numAttrs); + new_header_len = MAXALIGN(new_header_len); + new_data_len = heap_compute_data_size(tupleDesc, + toast_values, toast_isnull); + new_tuple_len = new_header_len + new_data_len; + + new_data = (HeapTupleHeader) palloc0(new_tuple_len); + + /* + * Copy the existing tuple header, but adjust natts and t_hoff. + */ + memcpy(new_data, tup, SizeofHeapTupleHeader); + HeapTupleHeaderSetNatts(new_data, numAttrs); + new_data->t_hoff = new_header_len; + + /* Set the composite-Datum header fields correctly */ + HeapTupleHeaderSetDatumLength(new_data, new_tuple_len); + HeapTupleHeaderSetTypeId(new_data, tupleDesc->tdtypeid); + HeapTupleHeaderSetTypMod(new_data, tupleDesc->tdtypmod); + + /* Copy over the data, and fill the null bitmap if needed */ + heap_fill_tuple(tupleDesc, + toast_values, + toast_isnull, + (char *) new_data + new_header_len, + new_data_len, + &(new_data->t_infomask), + has_nulls ? new_data->t_bits : NULL); + + /* + * Free allocated temp values + */ + for (i = 0; i < numAttrs; i++) + if (toast_free[i]) + pfree(DatumGetPointer(toast_values[i])); + + return PointerGetDatum(new_data); +} + + +/* ---------- + * toast_build_flattened_tuple - + * + * Build a tuple containing no out-of-line toasted fields. + * (This does not eliminate compressed or short-header datums.) + * + * This is essentially just like heap_form_tuple, except that it will + * expand any external-data pointers beforehand. + * + * It's not very clear whether it would be preferable to decompress + * in-line compressed datums while at it. For now, we don't. + * ---------- + */ +HeapTuple +toast_build_flattened_tuple(TupleDesc tupleDesc, + Datum *values, + bool *isnull) +{ + HeapTuple new_tuple; + int numAttrs = tupleDesc->natts; + int num_to_free; + int i; + Datum new_values[MaxTupleAttributeNumber]; + Pointer freeable_values[MaxTupleAttributeNumber]; + + /* + * We can pass the caller's isnull array directly to heap_form_tuple, but + * we potentially need to modify the values array. + */ + Assert(numAttrs <= MaxTupleAttributeNumber); + memcpy(new_values, values, numAttrs * sizeof(Datum)); + + num_to_free = 0; + for (i = 0; i < numAttrs; i++) + { + /* + * Look at non-null varlena attributes + */ + if (!isnull[i] && TupleDescAttr(tupleDesc, i)->attlen == -1) + { + struct varlena *new_value; + + new_value = (struct varlena *) DatumGetPointer(new_values[i]); + if (VARATT_IS_EXTERNAL(new_value)) + { + new_value = heap_tuple_fetch_attr(new_value); + new_values[i] = PointerGetDatum(new_value); + freeable_values[num_to_free++] = (Pointer) new_value; + } + } + } + + /* + * Form the reconfigured tuple. + */ + new_tuple = heap_form_tuple(tupleDesc, new_values, isnull); + + /* + * Free allocated temp values + */ + for (i = 0; i < num_to_free; i++) + pfree(freeable_values[i]); + + return new_tuple; +} diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index b8b5871559b..d41d318eef9 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -3,7 +3,7 @@ * hio.c * POSTGRES heap access method input/output code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -74,23 +74,31 @@ RelationPutHeapTuple(Relation relation, } /* - * Read in a buffer, using bulk-insert strategy if bistate isn't NULL. + * Read in a buffer in mode, using bulk-insert strategy if bistate isn't NULL. */ static Buffer ReadBufferBI(Relation relation, BlockNumber targetBlock, - BulkInsertState bistate) + ReadBufferMode mode, BulkInsertState bistate) { Buffer buffer; /* If not bulk-insert, exactly like ReadBuffer */ if (!bistate) - return ReadBuffer(relation, targetBlock); + return ReadBufferExtended(relation, MAIN_FORKNUM, targetBlock, + mode, NULL); /* If we have the desired block already pinned, re-pin and return it */ if (bistate->current_buf != InvalidBuffer) { if (BufferGetBlockNumber(bistate->current_buf) == targetBlock) { + /* + * Currently the LOCK variants are only used for extending + * relation, which should never reach this branch. + */ + Assert(mode != RBM_ZERO_AND_LOCK && + mode != RBM_ZERO_AND_CLEANUP_LOCK); + IncrBufferRefCount(bistate->current_buf); return bistate->current_buf; } @@ -101,7 +109,7 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock, /* Perform a read using the buffer strategy */ buffer = ReadBufferExtended(relation, MAIN_FORKNUM, targetBlock, - RBM_NORMAL, bistate->strategy); + mode, bistate->strategy); /* Save the selected block as target for future inserts */ IncrBufferRefCount(buffer); @@ -115,8 +123,8 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock, * visibility map page, if we haven't already got one. * * buffer2 may be InvalidBuffer, if only one buffer is involved. buffer1 - * must not be InvalidBuffer. If both buffers are specified, buffer1 must - * be less than buffer2. + * must not be InvalidBuffer. If both buffers are specified, block1 must + * be less than block2. */ static void GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2, @@ -127,7 +135,7 @@ GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2, bool need_to_pin_buffer2; Assert(BufferIsValid(buffer1)); - Assert(buffer2 == InvalidBuffer || buffer1 <= buffer2); + Assert(buffer2 == InvalidBuffer || block1 <= block2); while (1) { @@ -204,11 +212,10 @@ RelationAddExtraBlocks(Relation relation, BulkInsertState bistate) /* * Extend by one page. This should generally match the main-line * extension code in RelationGetBufferForTuple, except that we hold - * the relation extension lock throughout. + * the relation extension lock throughout, and we don't immediately + * initialize the page (see below). */ - buffer = ReadBufferBI(relation, P_NEW, bistate); - - LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); + buffer = ReadBufferBI(relation, P_NEW, RBM_ZERO_AND_LOCK, bistate); page = BufferGetPage(buffer); if (!PageIsNew(page)) @@ -216,18 +223,18 @@ RelationAddExtraBlocks(Relation relation, BulkInsertState bistate) BufferGetBlockNumber(buffer), RelationGetRelationName(relation)); - PageInit(page, BufferGetPageSize(buffer), 0); - /* - * We mark all the new buffers dirty, but do nothing to write them - * out; they'll probably get used soon, and even if they are not, a - * crash will leave an okay all-zeroes page on disk. + * Add the page to the FSM without initializing. If we were to + * initialize here, the page would potentially get flushed out to disk + * before we add any useful content. There's no guarantee that that'd + * happen before a potential crash, so we need to deal with + * uninitialized pages anyway, thus avoid the potential for + * unnecessary writes. */ - MarkBufferDirty(buffer); /* we'll need this info below */ blockNum = BufferGetBlockNumber(buffer); - freespace = PageGetHeapFreeSpace(page); + freespace = BufferGetPageSize(buffer) - SizeOfPageHeaderData; UnlockReleaseBuffer(buffer); @@ -412,7 +419,7 @@ RelationGetBufferForTuple(Relation relation, Size len, if (otherBuffer == InvalidBuffer) { /* easy case */ - buffer = ReadBufferBI(relation, targetBlock, bistate); + buffer = ReadBufferBI(relation, targetBlock, RBM_NORMAL, bistate); if (PageIsAllVisible(BufferGetPage(buffer))) visibilitymap_pin(relation, targetBlock, vmbuffer); LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); @@ -465,7 +472,7 @@ RelationGetBufferForTuple(Relation relation, Size len, * done a bit of extra work for no gain, but there's no real harm * done. */ - if (otherBuffer == InvalidBuffer || buffer <= otherBuffer) + if (otherBuffer == InvalidBuffer || targetBlock <= otherBlock) GetVisibilityMapPins(relation, buffer, otherBuffer, targetBlock, otherBlock, vmbuffer, vmbuffer_other); @@ -479,6 +486,19 @@ RelationGetBufferForTuple(Relation relation, Size len, * we're done. */ page = BufferGetPage(buffer); + + /* + * If necessary initialize page, it'll be used soon. We could avoid + * dirtying the buffer here, and rely on the caller to do so whenever + * it puts a tuple onto the page, but there seems not much benefit in + * doing so. + */ + if (PageIsNew(page)) + { + PageInit(page, BufferGetPageSize(buffer), 0); + MarkBufferDirty(buffer); + } + pageFreeSpace = PageGetHeapFreeSpace(page); if (len + saveFreeSpace <= pageFreeSpace) { @@ -571,42 +591,67 @@ RelationGetBufferForTuple(Relation relation, Size len, * it worth keeping an accurate file length in shared memory someplace, * rather than relying on the kernel to do it for us? */ - buffer = ReadBufferBI(relation, P_NEW, bistate); + buffer = ReadBufferBI(relation, P_NEW, RBM_ZERO_AND_LOCK, bistate); /* - * We can be certain that locking the otherBuffer first is OK, since it - * must have a lower page number. + * We need to initialize the empty new page. Double-check that it really + * is empty (this should never happen, but if it does we don't want to + * risk wiping out valid data). */ - if (otherBuffer != InvalidBuffer) - LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE); + page = BufferGetPage(buffer); - /* - * Now acquire lock on the new page. - */ - LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); + if (!PageIsNew(page)) + elog(ERROR, "page %u of relation \"%s\" should be empty but is not", + BufferGetBlockNumber(buffer), + RelationGetRelationName(relation)); + + PageInit(page, BufferGetPageSize(buffer), 0); + MarkBufferDirty(buffer); /* * Release the file-extension lock; it's now OK for someone else to extend - * the relation some more. Note that we cannot release this lock before - * we have buffer lock on the new page, or we risk a race condition - * against vacuumlazy.c --- see comments therein. + * the relation some more. */ if (needLock) UnlockRelationForExtension(relation, ExclusiveLock); /* - * We need to initialize the empty new page. Double-check that it really - * is empty (this should never happen, but if it does we don't want to - * risk wiping out valid data). + * Lock the other buffer. It's guaranteed to be of a lower page number + * than the new page. To conform with the deadlock prevent rules, we ought + * to lock otherBuffer first, but that would give other backends a chance + * to put tuples on our page. To reduce the likelihood of that, attempt to + * lock the other buffer conditionally, that's very likely to work. + * Otherwise we need to lock buffers in the correct order, and retry if + * the space has been used in the mean time. + * + * Alternatively, we could acquire the lock on otherBuffer before + * extending the relation, but that'd require holding the lock while + * performing IO, which seems worse than an unlikely retry. */ - page = BufferGetPage(buffer); + if (otherBuffer != InvalidBuffer) + { + Assert(otherBuffer != buffer); - if (!PageIsNew(page)) - elog(ERROR, "page %u of relation \"%s\" should be empty but is not", - BufferGetBlockNumber(buffer), - RelationGetRelationName(relation)); + if (unlikely(!ConditionalLockBuffer(otherBuffer))) + { + LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE); + LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE); - PageInit(page, BufferGetPageSize(buffer), 0); + /* + * Because the buffer was unlocked for a while, it's possible, + * although unlikely, that the page was filled. If so, just retry + * from start. + */ + if (len > PageGetHeapFreeSpace(page)) + { + LockBuffer(otherBuffer, BUFFER_LOCK_UNLOCK); + UnlockReleaseBuffer(buffer); + + goto loop; + } + } + } if (len > PageGetHeapFreeSpace(page)) { diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index c2f5343dac8..a0d22173cef 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -3,7 +3,7 @@ * pruneheap.c * heap page pruning and HOT-chain management code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,7 +25,6 @@ #include "storage/bufmgr.h" #include "utils/snapmgr.h" #include "utils/rel.h" -#include "utils/tqual.h" /* Working data for heap_page_prune and subroutines */ typedef struct @@ -44,13 +43,13 @@ typedef struct } PruneState; /* Local functions */ -static int heap_prune_chain(Relation relation, Buffer buffer, - OffsetNumber rootoffnum, - TransactionId OldestXmin, - PruneState *prstate); +static int heap_prune_chain(Relation relation, Buffer buffer, + OffsetNumber rootoffnum, + TransactionId OldestXmin, + PruneState *prstate); static void heap_prune_record_prunable(PruneState *prstate, TransactionId xid); static void heap_prune_record_redirect(PruneState *prstate, - OffsetNumber offnum, OffsetNumber rdoffnum); + OffsetNumber offnum, OffsetNumber rdoffnum); static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum); static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum); @@ -257,7 +256,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, MarkBufferDirty(buffer); /* - * Emit a WAL HEAP_CLEAN record showing what we did + * Emit a WAL XLOG_HEAP2_CLEAN record showing what we did */ if (RelationNeedsWAL(relation)) { @@ -325,7 +324,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, /* - * Prune specified item pointer or a HOT chain originating at that item. + * Prune specified line pointer or a HOT chain originating at line pointer. * * If the item is an index-referenced tuple (i.e. not a heap-only tuple), * the HOT chain is pruned by removing all DEAD tuples at the start of the HOT @@ -455,7 +454,7 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum, } /* - * Likewise, a dead item pointer can't be part of the chain. (We + * Likewise, a dead line pointer can't be part of the chain. (We * already eliminated the case of dead root tuple outside this * function.) */ @@ -631,7 +630,7 @@ heap_prune_record_prunable(PruneState *prstate, TransactionId xid) prstate->new_prune_xid = xid; } -/* Record item pointer to be redirected */ +/* Record line pointer to be redirected */ static void heap_prune_record_redirect(PruneState *prstate, OffsetNumber offnum, OffsetNumber rdoffnum) @@ -646,7 +645,7 @@ heap_prune_record_redirect(PruneState *prstate, prstate->marked[rdoffnum] = true; } -/* Record item pointer to be marked dead */ +/* Record line pointer to be marked dead */ static void heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum) { @@ -657,7 +656,7 @@ heap_prune_record_dead(PruneState *prstate, OffsetNumber offnum) prstate->marked[offnum] = true; } -/* Record item pointer to be marked unused */ +/* Record line pointer to be marked unused */ static void heap_prune_record_unused(PruneState *prstate, OffsetNumber offnum) { diff --git a/src/backend/access/heap/rewriteheap.c b/src/backend/access/heap/rewriteheap.c index 8d3c861a330..0172a139576 100644 --- a/src/backend/access/heap/rewriteheap.c +++ b/src/backend/access/heap/rewriteheap.c @@ -92,7 +92,7 @@ * heap's TOAST table will go through the normal bufmgr. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION @@ -109,9 +109,9 @@ #include "access/heapam.h" #include "access/heapam_xlog.h" +#include "access/heaptoast.h" #include "access/rewriteheap.h" #include "access/transam.h" -#include "access/tuptoaster.h" #include "access/xact.h" #include "access/xloginsert.h" @@ -130,7 +130,6 @@ #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" #include "storage/procarray.h" @@ -238,7 +237,7 @@ static void logical_end_heap_rewrite(RewriteState state); * new_heap new, locked heap relation to insert tuples to * oldest_xmin xid used by the caller to determine which tuples are dead * freeze_xid xid before which tuples will be frozen - * min_multi multixact before which multis will be removed + * cutoff_multi multixact before which multis will be removed * use_wal should the inserts to the new heap be WAL-logged? * * Returns an opaque RewriteState, allocated in current memory context, @@ -351,7 +350,7 @@ end_heap_rewrite(RewriteState state) * * It's obvious that we must do this when not WAL-logging. It's less * obvious that we have to do it even if we did WAL-log the pages. The - * reason is the same as in tablecmds.c's copy_relation_data(): we're + * reason is the same as in storage.c's RelationCopyStorage(): we're * writing data that's not in shared buffers, and so a CHECKPOINT * occurring during the rewriteheap operation won't have fsync'd data we * wrote before the checkpoint. @@ -652,10 +651,22 @@ raw_heap_insert(RewriteState state, HeapTuple tup) heaptup = tup; } else if (HeapTupleHasExternal(tup) || tup->t_len > TOAST_TUPLE_THRESHOLD) + { + int options = HEAP_INSERT_SKIP_FSM; + + if (!state->rs_use_wal) + options |= HEAP_INSERT_SKIP_WAL; + + /* + * While rewriting the heap for VACUUM FULL / CLUSTER, make sure data + * for the TOAST table are not logically decoded. The main heap is + * WAL-logged as XLOG FPI records, which are not logically decoded. + */ + options |= HEAP_INSERT_NO_LOGICAL; + heaptup = toast_insert_or_update(state->rs_new_rel, tup, NULL, - HEAP_INSERT_SKIP_FSM | - (state->rs_use_wal ? - 0 : HEAP_INSERT_SKIP_WAL)); + options); + } else heaptup = tup; @@ -776,7 +787,7 @@ raw_heap_insert(RewriteState state, HeapTuple tup) * Instead we simply write the mapping files out to disk, *before* the * XLogInsert() is performed. That guarantees that either the XLogInsert() is * inserted after the checkpoint's redo pointer or that the checkpoint (via - * LogicalRewriteHeapCheckpoint()) has flushed the (partial) mapping file to + * CheckPointLogicalRewriteHeap()) has flushed the (partial) mapping file to * disk. That leaves the tail end that has not yet been flushed open to * corruption, which is solved by including the current offset in the * xl_heap_rewrite_mapping records and truncating the mapping file to it @@ -922,7 +933,7 @@ logical_heap_rewrite_flush_mappings(RewriteState state) * Note that we deviate from the usual WAL coding practices here, * check the above "Logical rewrite support" comment for reasoning. */ - written = FileWrite(src->vfd, waldata_start, len, + written = FileWrite(src->vfd, waldata_start, len, src->off, WAIT_EVENT_LOGICAL_REWRITE_WRITE); if (written != len) ereport(ERROR, @@ -965,7 +976,7 @@ logical_end_heap_rewrite(RewriteState state) while ((src = (RewriteMappingFile *) hash_seq_search(&seq_status)) != NULL) { if (FileSync(src->vfd, WAIT_EVENT_LOGICAL_REWRITE_SYNC) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", src->path))); FileClose(src->vfd); @@ -1166,11 +1177,17 @@ heap_xlog_logical_rewrite(XLogReaderState *r) len = xlrec->num_mappings * sizeof(LogicalRewriteMappingData); /* write out tail end of mapping file (again) */ + errno = 0; pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_WRITE); if (write(fd, data, len) != len) + { + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", path))); + } pgstat_report_wait_end(); /* @@ -1180,12 +1197,15 @@ heap_xlog_logical_rewrite(XLogReaderState *r) */ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_MAPPING_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", path))); pgstat_report_wait_end(); - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); } /* --- @@ -1279,11 +1299,15 @@ CheckPointLogicalRewriteHeap(void) */ pgstat_report_wait_start(WAIT_EVENT_LOGICAL_REWRITE_CHECKPOINT_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", path))); pgstat_report_wait_end(); - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); } } FreeDir(mappings_dir); diff --git a/src/backend/access/heap/syncscan.c b/src/backend/access/heap/syncscan.c index 054eb066e91..b615940ed3e 100644 --- a/src/backend/access/heap/syncscan.c +++ b/src/backend/access/heap/syncscan.c @@ -36,7 +36,7 @@ * ss_report_location - update current scan location * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -116,7 +116,7 @@ static ss_scan_locations_t *scan_locations; /* prototypes for internal functions */ static BlockNumber ss_search(RelFileNode relfilenode, - BlockNumber location, bool set); + BlockNumber location, bool set); /* diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c deleted file mode 100644 index 546f80f05ca..00000000000 --- a/src/backend/access/heap/tuptoaster.c +++ /dev/null @@ -1,2392 +0,0 @@ -/*------------------------------------------------------------------------- - * - * tuptoaster.c - * Support routines for external and compressed storage of - * variable size attributes. - * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/backend/access/heap/tuptoaster.c - * - * - * INTERFACE ROUTINES - * toast_insert_or_update - - * Try to make a given tuple fit into one page by compressing - * or moving off attributes - * - * toast_delete - - * Reclaim toast storage when a tuple is deleted - * - * heap_tuple_untoast_attr - - * Fetch back a given value from the "secondary" relation - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include -#include - -#include "access/genam.h" -#include "access/heapam.h" -#include "access/tuptoaster.h" -#include "access/xact.h" -#include "catalog/catalog.h" -#include "common/pg_lzcompress.h" -#include "miscadmin.h" -#include "utils/expandeddatum.h" -#include "utils/fmgroids.h" -#include "utils/rel.h" -#include "utils/snapmgr.h" -#include "utils/typcache.h" -#include "utils/tqual.h" - - -#undef TOAST_DEBUG - -/* - * The information at the start of the compressed toast data. - */ -typedef struct toast_compress_header -{ - int32 vl_len_; /* varlena header (do not touch directly!) */ - int32 rawsize; -} toast_compress_header; - -/* - * Utilities for manipulation of header information for compressed - * toast entries. - */ -#define TOAST_COMPRESS_HDRSZ ((int32) sizeof(toast_compress_header)) -#define TOAST_COMPRESS_RAWSIZE(ptr) (((toast_compress_header *) (ptr))->rawsize) -#define TOAST_COMPRESS_RAWDATA(ptr) \ - (((char *) (ptr)) + TOAST_COMPRESS_HDRSZ) -#define TOAST_COMPRESS_SET_RAWSIZE(ptr, len) \ - (((toast_compress_header *) (ptr))->rawsize = (len)) - -static void toast_delete_datum(Relation rel, Datum value, bool is_speculative); -static Datum toast_save_datum(Relation rel, Datum value, - struct varlena *oldexternal, int options); -static bool toastrel_valueid_exists(Relation toastrel, Oid valueid); -static bool toastid_valueid_exists(Oid toastrelid, Oid valueid); -static struct varlena *toast_fetch_datum(struct varlena *attr); -static struct varlena *toast_fetch_datum_slice(struct varlena *attr, - int32 sliceoffset, int32 length); -static struct varlena *toast_decompress_datum(struct varlena *attr); -static int toast_open_indexes(Relation toastrel, - LOCKMODE lock, - Relation **toastidxs, - int *num_indexes); -static void toast_close_indexes(Relation *toastidxs, int num_indexes, - LOCKMODE lock); -static void init_toast_snapshot(Snapshot toast_snapshot); - - -/* ---------- - * heap_tuple_fetch_attr - - * - * Public entry point to get back a toasted value from - * external source (possibly still in compressed format). - * - * This will return a datum that contains all the data internally, ie, not - * relying on external storage or memory, but it can still be compressed or - * have a short header. Note some callers assume that if the input is an - * EXTERNAL datum, the result will be a pfree'able chunk. - * ---------- - */ -struct varlena * -heap_tuple_fetch_attr(struct varlena *attr) -{ - struct varlena *result; - - if (VARATT_IS_EXTERNAL_ONDISK(attr)) - { - /* - * This is an external stored plain value - */ - result = toast_fetch_datum(attr); - } - else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) - { - /* - * This is an indirect pointer --- dereference it - */ - struct varatt_indirect redirect; - - VARATT_EXTERNAL_GET_POINTER(redirect, attr); - attr = (struct varlena *) redirect.pointer; - - /* nested indirect Datums aren't allowed */ - Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); - - /* recurse if value is still external in some other way */ - if (VARATT_IS_EXTERNAL(attr)) - return heap_tuple_fetch_attr(attr); - - /* - * Copy into the caller's memory context, in case caller tries to - * pfree the result. - */ - result = (struct varlena *) palloc(VARSIZE_ANY(attr)); - memcpy(result, attr, VARSIZE_ANY(attr)); - } - else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) - { - /* - * This is an expanded-object pointer --- get flat format - */ - ExpandedObjectHeader *eoh; - Size resultsize; - - eoh = DatumGetEOHP(PointerGetDatum(attr)); - resultsize = EOH_get_flat_size(eoh); - result = (struct varlena *) palloc(resultsize); - EOH_flatten_into(eoh, (void *) result, resultsize); - } - else - { - /* - * This is a plain value inside of the main tuple - why am I called? - */ - result = attr; - } - - return result; -} - - -/* ---------- - * heap_tuple_untoast_attr - - * - * Public entry point to get back a toasted value from compression - * or external storage. The result is always non-extended varlena form. - * - * Note some callers assume that if the input is an EXTERNAL or COMPRESSED - * datum, the result will be a pfree'able chunk. - * ---------- - */ -struct varlena * -heap_tuple_untoast_attr(struct varlena *attr) -{ - if (VARATT_IS_EXTERNAL_ONDISK(attr)) - { - /* - * This is an externally stored datum --- fetch it back from there - */ - attr = toast_fetch_datum(attr); - /* If it's compressed, decompress it */ - if (VARATT_IS_COMPRESSED(attr)) - { - struct varlena *tmp = attr; - - attr = toast_decompress_datum(tmp); - pfree(tmp); - } - } - else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) - { - /* - * This is an indirect pointer --- dereference it - */ - struct varatt_indirect redirect; - - VARATT_EXTERNAL_GET_POINTER(redirect, attr); - attr = (struct varlena *) redirect.pointer; - - /* nested indirect Datums aren't allowed */ - Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); - - /* recurse in case value is still extended in some other way */ - attr = heap_tuple_untoast_attr(attr); - - /* if it isn't, we'd better copy it */ - if (attr == (struct varlena *) redirect.pointer) - { - struct varlena *result; - - result = (struct varlena *) palloc(VARSIZE_ANY(attr)); - memcpy(result, attr, VARSIZE_ANY(attr)); - attr = result; - } - } - else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) - { - /* - * This is an expanded-object pointer --- get flat format - */ - attr = heap_tuple_fetch_attr(attr); - /* flatteners are not allowed to produce compressed/short output */ - Assert(!VARATT_IS_EXTENDED(attr)); - } - else if (VARATT_IS_COMPRESSED(attr)) - { - /* - * This is a compressed value inside of the main tuple - */ - attr = toast_decompress_datum(attr); - } - else if (VARATT_IS_SHORT(attr)) - { - /* - * This is a short-header varlena --- convert to 4-byte header format - */ - Size data_size = VARSIZE_SHORT(attr) - VARHDRSZ_SHORT; - Size new_size = data_size + VARHDRSZ; - struct varlena *new_attr; - - new_attr = (struct varlena *) palloc(new_size); - SET_VARSIZE(new_attr, new_size); - memcpy(VARDATA(new_attr), VARDATA_SHORT(attr), data_size); - attr = new_attr; - } - - return attr; -} - - -/* ---------- - * heap_tuple_untoast_attr_slice - - * - * Public entry point to get back part of a toasted value - * from compression or external storage. - * ---------- - */ -struct varlena * -heap_tuple_untoast_attr_slice(struct varlena *attr, - int32 sliceoffset, int32 slicelength) -{ - struct varlena *preslice; - struct varlena *result; - char *attrdata; - int32 attrsize; - - if (VARATT_IS_EXTERNAL_ONDISK(attr)) - { - struct varatt_external toast_pointer; - - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - /* fast path for non-compressed external datums */ - if (!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) - return toast_fetch_datum_slice(attr, sliceoffset, slicelength); - - /* fetch it back (compressed marker will get set automatically) */ - preslice = toast_fetch_datum(attr); - } - else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) - { - struct varatt_indirect redirect; - - VARATT_EXTERNAL_GET_POINTER(redirect, attr); - - /* nested indirect Datums aren't allowed */ - Assert(!VARATT_IS_EXTERNAL_INDIRECT(redirect.pointer)); - - return heap_tuple_untoast_attr_slice(redirect.pointer, - sliceoffset, slicelength); - } - else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) - { - /* pass it off to heap_tuple_fetch_attr to flatten */ - preslice = heap_tuple_fetch_attr(attr); - } - else - preslice = attr; - - Assert(!VARATT_IS_EXTERNAL(preslice)); - - if (VARATT_IS_COMPRESSED(preslice)) - { - struct varlena *tmp = preslice; - - preslice = toast_decompress_datum(tmp); - - if (tmp != attr) - pfree(tmp); - } - - if (VARATT_IS_SHORT(preslice)) - { - attrdata = VARDATA_SHORT(preslice); - attrsize = VARSIZE_SHORT(preslice) - VARHDRSZ_SHORT; - } - else - { - attrdata = VARDATA(preslice); - attrsize = VARSIZE(preslice) - VARHDRSZ; - } - - /* slicing of datum for compressed cases and plain value */ - - if (sliceoffset >= attrsize) - { - sliceoffset = 0; - slicelength = 0; - } - - if (((sliceoffset + slicelength) > attrsize) || slicelength < 0) - slicelength = attrsize - sliceoffset; - - result = (struct varlena *) palloc(slicelength + VARHDRSZ); - SET_VARSIZE(result, slicelength + VARHDRSZ); - - memcpy(VARDATA(result), attrdata + sliceoffset, slicelength); - - if (preslice != attr) - pfree(preslice); - - return result; -} - - -/* ---------- - * toast_raw_datum_size - - * - * Return the raw (detoasted) size of a varlena datum - * (including the VARHDRSZ header) - * ---------- - */ -Size -toast_raw_datum_size(Datum value) -{ - struct varlena *attr = (struct varlena *) DatumGetPointer(value); - Size result; - - if (VARATT_IS_EXTERNAL_ONDISK(attr)) - { - /* va_rawsize is the size of the original datum -- including header */ - struct varatt_external toast_pointer; - - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - result = toast_pointer.va_rawsize; - } - else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) - { - struct varatt_indirect toast_pointer; - - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - /* nested indirect Datums aren't allowed */ - Assert(!VARATT_IS_EXTERNAL_INDIRECT(toast_pointer.pointer)); - - return toast_raw_datum_size(PointerGetDatum(toast_pointer.pointer)); - } - else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) - { - result = EOH_get_flat_size(DatumGetEOHP(value)); - } - else if (VARATT_IS_COMPRESSED(attr)) - { - /* here, va_rawsize is just the payload size */ - result = VARRAWSIZE_4B_C(attr) + VARHDRSZ; - } - else if (VARATT_IS_SHORT(attr)) - { - /* - * we have to normalize the header length to VARHDRSZ or else the - * callers of this function will be confused. - */ - result = VARSIZE_SHORT(attr) - VARHDRSZ_SHORT + VARHDRSZ; - } - else - { - /* plain untoasted datum */ - result = VARSIZE(attr); - } - return result; -} - -/* ---------- - * toast_datum_size - * - * Return the physical storage size (possibly compressed) of a varlena datum - * ---------- - */ -Size -toast_datum_size(Datum value) -{ - struct varlena *attr = (struct varlena *) DatumGetPointer(value); - Size result; - - if (VARATT_IS_EXTERNAL_ONDISK(attr)) - { - /* - * Attribute is stored externally - return the extsize whether - * compressed or not. We do not count the size of the toast pointer - * ... should we? - */ - struct varatt_external toast_pointer; - - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - result = toast_pointer.va_extsize; - } - else if (VARATT_IS_EXTERNAL_INDIRECT(attr)) - { - struct varatt_indirect toast_pointer; - - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - /* nested indirect Datums aren't allowed */ - Assert(!VARATT_IS_EXTERNAL_INDIRECT(attr)); - - return toast_datum_size(PointerGetDatum(toast_pointer.pointer)); - } - else if (VARATT_IS_EXTERNAL_EXPANDED(attr)) - { - result = EOH_get_flat_size(DatumGetEOHP(value)); - } - else if (VARATT_IS_SHORT(attr)) - { - result = VARSIZE_SHORT(attr); - } - else - { - /* - * Attribute is stored inline either compressed or not, just calculate - * the size of the datum in either case. - */ - result = VARSIZE(attr); - } - return result; -} - - -/* ---------- - * toast_delete - - * - * Cascaded delete toast-entries on DELETE - * ---------- - */ -void -toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative) -{ - TupleDesc tupleDesc; - int numAttrs; - int i; - Datum toast_values[MaxHeapAttributeNumber]; - bool toast_isnull[MaxHeapAttributeNumber]; - - /* - * We should only ever be called for tuples of plain relations or - * materialized views --- recursing on a toast rel is bad news. - */ - Assert(rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_MATVIEW); - - /* - * Get the tuple descriptor and break down the tuple into fields. - * - * NOTE: it's debatable whether to use heap_deform_tuple() here or just - * heap_getattr() only the varlena columns. The latter could win if there - * are few varlena columns and many non-varlena ones. However, - * heap_deform_tuple costs only O(N) while the heap_getattr way would cost - * O(N^2) if there are many varlena columns, so it seems better to err on - * the side of linear cost. (We won't even be here unless there's at - * least one varlena column, by the way.) - */ - tupleDesc = rel->rd_att; - numAttrs = tupleDesc->natts; - - Assert(numAttrs <= MaxHeapAttributeNumber); - heap_deform_tuple(oldtup, tupleDesc, toast_values, toast_isnull); - - /* - * Check for external stored attributes and delete them from the secondary - * relation. - */ - for (i = 0; i < numAttrs; i++) - { - if (TupleDescAttr(tupleDesc, i)->attlen == -1) - { - Datum value = toast_values[i]; - - if (toast_isnull[i]) - continue; - else if (VARATT_IS_EXTERNAL_ONDISK(PointerGetDatum(value))) - toast_delete_datum(rel, value, is_speculative); - } - } -} - - -/* ---------- - * toast_insert_or_update - - * - * Delete no-longer-used toast-entries and create new ones to - * make the new tuple fit on INSERT or UPDATE - * - * Inputs: - * newtup: the candidate new tuple to be inserted - * oldtup: the old row version for UPDATE, or NULL for INSERT - * options: options to be passed to heap_insert() for toast rows - * Result: - * either newtup if no toasting is needed, or a palloc'd modified tuple - * that is what should actually get stored - * - * NOTE: neither newtup nor oldtup will be modified. This is a change - * from the pre-8.1 API of this routine. - * ---------- - */ -HeapTuple -toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup, - int options) -{ - HeapTuple result_tuple; - TupleDesc tupleDesc; - int numAttrs; - int i; - - bool need_change = false; - bool need_free = false; - bool need_delold = false; - bool has_nulls = false; - - Size maxDataLen; - Size hoff; - - char toast_action[MaxHeapAttributeNumber]; - bool toast_isnull[MaxHeapAttributeNumber]; - bool toast_oldisnull[MaxHeapAttributeNumber]; - Datum toast_values[MaxHeapAttributeNumber]; - Datum toast_oldvalues[MaxHeapAttributeNumber]; - struct varlena *toast_oldexternal[MaxHeapAttributeNumber]; - int32 toast_sizes[MaxHeapAttributeNumber]; - bool toast_free[MaxHeapAttributeNumber]; - bool toast_delold[MaxHeapAttributeNumber]; - - /* - * Ignore the INSERT_SPECULATIVE option. Speculative insertions/super - * deletions just normally insert/delete the toast values. It seems - * easiest to deal with that here, instead on, potentially, multiple - * callers. - */ - options &= ~HEAP_INSERT_SPECULATIVE; - - /* - * We should only ever be called for tuples of plain relations or - * materialized views --- recursing on a toast rel is bad news. - */ - Assert(rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_MATVIEW); - - /* - * Get the tuple descriptor and break down the tuple(s) into fields. - */ - tupleDesc = rel->rd_att; - numAttrs = tupleDesc->natts; - - Assert(numAttrs <= MaxHeapAttributeNumber); - heap_deform_tuple(newtup, tupleDesc, toast_values, toast_isnull); - if (oldtup != NULL) - heap_deform_tuple(oldtup, tupleDesc, toast_oldvalues, toast_oldisnull); - - /* ---------- - * Then collect information about the values given - * - * NOTE: toast_action[i] can have these values: - * ' ' default handling - * 'p' already processed --- don't touch it - * 'x' incompressible, but OK to move off - * - * NOTE: toast_sizes[i] is only made valid for varlena attributes with - * toast_action[i] different from 'p'. - * ---------- - */ - memset(toast_action, ' ', numAttrs * sizeof(char)); - memset(toast_oldexternal, 0, numAttrs * sizeof(struct varlena *)); - memset(toast_free, 0, numAttrs * sizeof(bool)); - memset(toast_delold, 0, numAttrs * sizeof(bool)); - - for (i = 0; i < numAttrs; i++) - { - Form_pg_attribute att = TupleDescAttr(tupleDesc, i); - struct varlena *old_value; - struct varlena *new_value; - - if (oldtup != NULL) - { - /* - * For UPDATE get the old and new values of this attribute - */ - old_value = (struct varlena *) DatumGetPointer(toast_oldvalues[i]); - new_value = (struct varlena *) DatumGetPointer(toast_values[i]); - - /* - * If the old value is stored on disk, check if it has changed so - * we have to delete it later. - */ - if (att->attlen == -1 && !toast_oldisnull[i] && - VARATT_IS_EXTERNAL_ONDISK(old_value)) - { - if (toast_isnull[i] || !VARATT_IS_EXTERNAL_ONDISK(new_value) || - memcmp((char *) old_value, (char *) new_value, - VARSIZE_EXTERNAL(old_value)) != 0) - { - /* - * The old external stored value isn't needed any more - * after the update - */ - toast_delold[i] = true; - need_delold = true; - } - else - { - /* - * This attribute isn't changed by this update so we reuse - * the original reference to the old value in the new - * tuple. - */ - toast_action[i] = 'p'; - continue; - } - } - } - else - { - /* - * For INSERT simply get the new value - */ - new_value = (struct varlena *) DatumGetPointer(toast_values[i]); - } - - /* - * Handle NULL attributes - */ - if (toast_isnull[i]) - { - toast_action[i] = 'p'; - has_nulls = true; - continue; - } - - /* - * Now look at varlena attributes - */ - if (att->attlen == -1) - { - /* - * If the table's attribute says PLAIN always, force it so. - */ - if (att->attstorage == 'p') - toast_action[i] = 'p'; - - /* - * We took care of UPDATE above, so any external value we find - * still in the tuple must be someone else's that we cannot reuse - * (this includes the case of an out-of-line in-memory datum). - * Fetch it back (without decompression, unless we are forcing - * PLAIN storage). If necessary, we'll push it out as a new - * external value below. - */ - if (VARATT_IS_EXTERNAL(new_value)) - { - toast_oldexternal[i] = new_value; - if (att->attstorage == 'p') - new_value = heap_tuple_untoast_attr(new_value); - else - new_value = heap_tuple_fetch_attr(new_value); - toast_values[i] = PointerGetDatum(new_value); - toast_free[i] = true; - need_change = true; - need_free = true; - } - - /* - * Remember the size of this attribute - */ - toast_sizes[i] = VARSIZE_ANY(new_value); - } - else - { - /* - * Not a varlena attribute, plain storage always - */ - toast_action[i] = 'p'; - } - } - - /* ---------- - * Compress and/or save external until data fits into target length - * - * 1: Inline compress attributes with attstorage 'x', and store very - * large attributes with attstorage 'x' or 'e' external immediately - * 2: Store attributes with attstorage 'x' or 'e' external - * 3: Inline compress attributes with attstorage 'm' - * 4: Store attributes with attstorage 'm' external - * ---------- - */ - - /* compute header overhead --- this should match heap_form_tuple() */ - hoff = SizeofHeapTupleHeader; - if (has_nulls) - hoff += BITMAPLEN(numAttrs); - if (newtup->t_data->t_infomask & HEAP_HASOID) - hoff += sizeof(Oid); - hoff = MAXALIGN(hoff); - /* now convert to a limit on the tuple data size */ - maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff; - - /* - * Look for attributes with attstorage 'x' to compress. Also find large - * attributes with attstorage 'x' or 'e', and store them external. - */ - while (heap_compute_data_size(tupleDesc, - toast_values, toast_isnull) > maxDataLen) - { - int biggest_attno = -1; - int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE); - Datum old_value; - Datum new_value; - - /* - * Search for the biggest yet unprocessed internal attribute - */ - for (i = 0; i < numAttrs; i++) - { - Form_pg_attribute att = TupleDescAttr(tupleDesc, i); - - if (toast_action[i] != ' ') - continue; - if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i]))) - continue; /* can't happen, toast_action would be 'p' */ - if (VARATT_IS_COMPRESSED(DatumGetPointer(toast_values[i]))) - continue; - if (att->attstorage != 'x' && att->attstorage != 'e') - continue; - if (toast_sizes[i] > biggest_size) - { - biggest_attno = i; - biggest_size = toast_sizes[i]; - } - } - - if (biggest_attno < 0) - break; - - /* - * Attempt to compress it inline, if it has attstorage 'x' - */ - i = biggest_attno; - if (TupleDescAttr(tupleDesc, i)->attstorage == 'x') - { - old_value = toast_values[i]; - new_value = toast_compress_datum(old_value); - - if (DatumGetPointer(new_value) != NULL) - { - /* successful compression */ - if (toast_free[i]) - pfree(DatumGetPointer(old_value)); - toast_values[i] = new_value; - toast_free[i] = true; - toast_sizes[i] = VARSIZE(DatumGetPointer(toast_values[i])); - need_change = true; - need_free = true; - } - else - { - /* incompressible, ignore on subsequent compression passes */ - toast_action[i] = 'x'; - } - } - else - { - /* has attstorage 'e', ignore on subsequent compression passes */ - toast_action[i] = 'x'; - } - - /* - * If this value is by itself more than maxDataLen (after compression - * if any), push it out to the toast table immediately, if possible. - * This avoids uselessly compressing other fields in the common case - * where we have one long field and several short ones. - * - * XXX maybe the threshold should be less than maxDataLen? - */ - if (toast_sizes[i] > maxDataLen && - rel->rd_rel->reltoastrelid != InvalidOid) - { - old_value = toast_values[i]; - toast_action[i] = 'p'; - toast_values[i] = toast_save_datum(rel, toast_values[i], - toast_oldexternal[i], options); - if (toast_free[i]) - pfree(DatumGetPointer(old_value)); - toast_free[i] = true; - need_change = true; - need_free = true; - } - } - - /* - * Second we look for attributes of attstorage 'x' or 'e' that are still - * inline. But skip this if there's no toast table to push them to. - */ - while (heap_compute_data_size(tupleDesc, - toast_values, toast_isnull) > maxDataLen && - rel->rd_rel->reltoastrelid != InvalidOid) - { - int biggest_attno = -1; - int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE); - Datum old_value; - - /*------ - * Search for the biggest yet inlined attribute with - * attstorage equals 'x' or 'e' - *------ - */ - for (i = 0; i < numAttrs; i++) - { - Form_pg_attribute att = TupleDescAttr(tupleDesc, i); - - if (toast_action[i] == 'p') - continue; - if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i]))) - continue; /* can't happen, toast_action would be 'p' */ - if (att->attstorage != 'x' && att->attstorage != 'e') - continue; - if (toast_sizes[i] > biggest_size) - { - biggest_attno = i; - biggest_size = toast_sizes[i]; - } - } - - if (biggest_attno < 0) - break; - - /* - * Store this external - */ - i = biggest_attno; - old_value = toast_values[i]; - toast_action[i] = 'p'; - toast_values[i] = toast_save_datum(rel, toast_values[i], - toast_oldexternal[i], options); - if (toast_free[i]) - pfree(DatumGetPointer(old_value)); - toast_free[i] = true; - - need_change = true; - need_free = true; - } - - /* - * Round 3 - this time we take attributes with storage 'm' into - * compression - */ - while (heap_compute_data_size(tupleDesc, - toast_values, toast_isnull) > maxDataLen) - { - int biggest_attno = -1; - int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE); - Datum old_value; - Datum new_value; - - /* - * Search for the biggest yet uncompressed internal attribute - */ - for (i = 0; i < numAttrs; i++) - { - if (toast_action[i] != ' ') - continue; - if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i]))) - continue; /* can't happen, toast_action would be 'p' */ - if (VARATT_IS_COMPRESSED(DatumGetPointer(toast_values[i]))) - continue; - if (TupleDescAttr(tupleDesc, i)->attstorage != 'm') - continue; - if (toast_sizes[i] > biggest_size) - { - biggest_attno = i; - biggest_size = toast_sizes[i]; - } - } - - if (biggest_attno < 0) - break; - - /* - * Attempt to compress it inline - */ - i = biggest_attno; - old_value = toast_values[i]; - new_value = toast_compress_datum(old_value); - - if (DatumGetPointer(new_value) != NULL) - { - /* successful compression */ - if (toast_free[i]) - pfree(DatumGetPointer(old_value)); - toast_values[i] = new_value; - toast_free[i] = true; - toast_sizes[i] = VARSIZE(DatumGetPointer(toast_values[i])); - need_change = true; - need_free = true; - } - else - { - /* incompressible, ignore on subsequent compression passes */ - toast_action[i] = 'x'; - } - } - - /* - * Finally we store attributes of type 'm' externally. At this point we - * increase the target tuple size, so that 'm' attributes aren't stored - * externally unless really necessary. - */ - maxDataLen = TOAST_TUPLE_TARGET_MAIN - hoff; - - while (heap_compute_data_size(tupleDesc, - toast_values, toast_isnull) > maxDataLen && - rel->rd_rel->reltoastrelid != InvalidOid) - { - int biggest_attno = -1; - int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE); - Datum old_value; - - /*-------- - * Search for the biggest yet inlined attribute with - * attstorage = 'm' - *-------- - */ - for (i = 0; i < numAttrs; i++) - { - if (toast_action[i] == 'p') - continue; - if (VARATT_IS_EXTERNAL(DatumGetPointer(toast_values[i]))) - continue; /* can't happen, toast_action would be 'p' */ - if (TupleDescAttr(tupleDesc, i)->attstorage != 'm') - continue; - if (toast_sizes[i] > biggest_size) - { - biggest_attno = i; - biggest_size = toast_sizes[i]; - } - } - - if (biggest_attno < 0) - break; - - /* - * Store this external - */ - i = biggest_attno; - old_value = toast_values[i]; - toast_action[i] = 'p'; - toast_values[i] = toast_save_datum(rel, toast_values[i], - toast_oldexternal[i], options); - if (toast_free[i]) - pfree(DatumGetPointer(old_value)); - toast_free[i] = true; - - need_change = true; - need_free = true; - } - - /* - * In the case we toasted any values, we need to build a new heap tuple - * with the changed values. - */ - if (need_change) - { - HeapTupleHeader olddata = newtup->t_data; - HeapTupleHeader new_data; - int32 new_header_len; - int32 new_data_len; - int32 new_tuple_len; - - /* - * Calculate the new size of the tuple. - * - * Note: we used to assume here that the old tuple's t_hoff must equal - * the new_header_len value, but that was incorrect. The old tuple - * might have a smaller-than-current natts, if there's been an ALTER - * TABLE ADD COLUMN since it was stored; and that would lead to a - * different conclusion about the size of the null bitmap, or even - * whether there needs to be one at all. - */ - new_header_len = SizeofHeapTupleHeader; - if (has_nulls) - new_header_len += BITMAPLEN(numAttrs); - if (olddata->t_infomask & HEAP_HASOID) - new_header_len += sizeof(Oid); - new_header_len = MAXALIGN(new_header_len); - new_data_len = heap_compute_data_size(tupleDesc, - toast_values, toast_isnull); - new_tuple_len = new_header_len + new_data_len; - - /* - * Allocate and zero the space needed, and fill HeapTupleData fields. - */ - result_tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + new_tuple_len); - result_tuple->t_len = new_tuple_len; - result_tuple->t_self = newtup->t_self; - result_tuple->t_tableOid = newtup->t_tableOid; - new_data = (HeapTupleHeader) ((char *) result_tuple + HEAPTUPLESIZE); - result_tuple->t_data = new_data; - - /* - * Copy the existing tuple header, but adjust natts and t_hoff. - */ - memcpy(new_data, olddata, SizeofHeapTupleHeader); - HeapTupleHeaderSetNatts(new_data, numAttrs); - new_data->t_hoff = new_header_len; - if (olddata->t_infomask & HEAP_HASOID) - HeapTupleHeaderSetOid(new_data, HeapTupleHeaderGetOid(olddata)); - - /* Copy over the data, and fill the null bitmap if needed */ - heap_fill_tuple(tupleDesc, - toast_values, - toast_isnull, - (char *) new_data + new_header_len, - new_data_len, - &(new_data->t_infomask), - has_nulls ? new_data->t_bits : NULL); - } - else - result_tuple = newtup; - - /* - * Free allocated temp values - */ - if (need_free) - for (i = 0; i < numAttrs; i++) - if (toast_free[i]) - pfree(DatumGetPointer(toast_values[i])); - - /* - * Delete external values from the old tuple - */ - if (need_delold) - for (i = 0; i < numAttrs; i++) - if (toast_delold[i]) - toast_delete_datum(rel, toast_oldvalues[i], false); - - return result_tuple; -} - - -/* ---------- - * toast_flatten_tuple - - * - * "Flatten" a tuple to contain no out-of-line toasted fields. - * (This does not eliminate compressed or short-header datums.) - * - * Note: we expect the caller already checked HeapTupleHasExternal(tup), - * so there is no need for a short-circuit path. - * ---------- - */ -HeapTuple -toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc) -{ - HeapTuple new_tuple; - int numAttrs = tupleDesc->natts; - int i; - Datum toast_values[MaxTupleAttributeNumber]; - bool toast_isnull[MaxTupleAttributeNumber]; - bool toast_free[MaxTupleAttributeNumber]; - - /* - * Break down the tuple into fields. - */ - Assert(numAttrs <= MaxTupleAttributeNumber); - heap_deform_tuple(tup, tupleDesc, toast_values, toast_isnull); - - memset(toast_free, 0, numAttrs * sizeof(bool)); - - for (i = 0; i < numAttrs; i++) - { - /* - * Look at non-null varlena attributes - */ - if (!toast_isnull[i] && TupleDescAttr(tupleDesc, i)->attlen == -1) - { - struct varlena *new_value; - - new_value = (struct varlena *) DatumGetPointer(toast_values[i]); - if (VARATT_IS_EXTERNAL(new_value)) - { - new_value = heap_tuple_fetch_attr(new_value); - toast_values[i] = PointerGetDatum(new_value); - toast_free[i] = true; - } - } - } - - /* - * Form the reconfigured tuple. - */ - new_tuple = heap_form_tuple(tupleDesc, toast_values, toast_isnull); - - /* - * Be sure to copy the tuple's OID and identity fields. We also make a - * point of copying visibility info, just in case anybody looks at those - * fields in a syscache entry. - */ - if (tupleDesc->tdhasoid) - HeapTupleSetOid(new_tuple, HeapTupleGetOid(tup)); - - new_tuple->t_self = tup->t_self; - new_tuple->t_tableOid = tup->t_tableOid; - - new_tuple->t_data->t_choice = tup->t_data->t_choice; - new_tuple->t_data->t_ctid = tup->t_data->t_ctid; - new_tuple->t_data->t_infomask &= ~HEAP_XACT_MASK; - new_tuple->t_data->t_infomask |= - tup->t_data->t_infomask & HEAP_XACT_MASK; - new_tuple->t_data->t_infomask2 &= ~HEAP2_XACT_MASK; - new_tuple->t_data->t_infomask2 |= - tup->t_data->t_infomask2 & HEAP2_XACT_MASK; - - /* - * Free allocated temp values - */ - for (i = 0; i < numAttrs; i++) - if (toast_free[i]) - pfree(DatumGetPointer(toast_values[i])); - - return new_tuple; -} - - -/* ---------- - * toast_flatten_tuple_to_datum - - * - * "Flatten" a tuple containing out-of-line toasted fields into a Datum. - * The result is always palloc'd in the current memory context. - * - * We have a general rule that Datums of container types (rows, arrays, - * ranges, etc) must not contain any external TOAST pointers. Without - * this rule, we'd have to look inside each Datum when preparing a tuple - * for storage, which would be expensive and would fail to extend cleanly - * to new sorts of container types. - * - * However, we don't want to say that tuples represented as HeapTuples - * can't contain toasted fields, so instead this routine should be called - * when such a HeapTuple is being converted into a Datum. - * - * While we're at it, we decompress any compressed fields too. This is not - * necessary for correctness, but reflects an expectation that compression - * will be more effective if applied to the whole tuple not individual - * fields. We are not so concerned about that that we want to deconstruct - * and reconstruct tuples just to get rid of compressed fields, however. - * So callers typically won't call this unless they see that the tuple has - * at least one external field. - * - * On the other hand, in-line short-header varlena fields are left alone. - * If we "untoasted" them here, they'd just get changed back to short-header - * format anyway within heap_fill_tuple. - * ---------- - */ -Datum -toast_flatten_tuple_to_datum(HeapTupleHeader tup, - uint32 tup_len, - TupleDesc tupleDesc) -{ - HeapTupleHeader new_data; - int32 new_header_len; - int32 new_data_len; - int32 new_tuple_len; - HeapTupleData tmptup; - int numAttrs = tupleDesc->natts; - int i; - bool has_nulls = false; - Datum toast_values[MaxTupleAttributeNumber]; - bool toast_isnull[MaxTupleAttributeNumber]; - bool toast_free[MaxTupleAttributeNumber]; - - /* Build a temporary HeapTuple control structure */ - tmptup.t_len = tup_len; - ItemPointerSetInvalid(&(tmptup.t_self)); - tmptup.t_tableOid = InvalidOid; - tmptup.t_data = tup; - - /* - * Break down the tuple into fields. - */ - Assert(numAttrs <= MaxTupleAttributeNumber); - heap_deform_tuple(&tmptup, tupleDesc, toast_values, toast_isnull); - - memset(toast_free, 0, numAttrs * sizeof(bool)); - - for (i = 0; i < numAttrs; i++) - { - /* - * Look at non-null varlena attributes - */ - if (toast_isnull[i]) - has_nulls = true; - else if (TupleDescAttr(tupleDesc, i)->attlen == -1) - { - struct varlena *new_value; - - new_value = (struct varlena *) DatumGetPointer(toast_values[i]); - if (VARATT_IS_EXTERNAL(new_value) || - VARATT_IS_COMPRESSED(new_value)) - { - new_value = heap_tuple_untoast_attr(new_value); - toast_values[i] = PointerGetDatum(new_value); - toast_free[i] = true; - } - } - } - - /* - * Calculate the new size of the tuple. - * - * This should match the reconstruction code in toast_insert_or_update. - */ - new_header_len = SizeofHeapTupleHeader; - if (has_nulls) - new_header_len += BITMAPLEN(numAttrs); - if (tup->t_infomask & HEAP_HASOID) - new_header_len += sizeof(Oid); - new_header_len = MAXALIGN(new_header_len); - new_data_len = heap_compute_data_size(tupleDesc, - toast_values, toast_isnull); - new_tuple_len = new_header_len + new_data_len; - - new_data = (HeapTupleHeader) palloc0(new_tuple_len); - - /* - * Copy the existing tuple header, but adjust natts and t_hoff. - */ - memcpy(new_data, tup, SizeofHeapTupleHeader); - HeapTupleHeaderSetNatts(new_data, numAttrs); - new_data->t_hoff = new_header_len; - if (tup->t_infomask & HEAP_HASOID) - HeapTupleHeaderSetOid(new_data, HeapTupleHeaderGetOid(tup)); - - /* Set the composite-Datum header fields correctly */ - HeapTupleHeaderSetDatumLength(new_data, new_tuple_len); - HeapTupleHeaderSetTypeId(new_data, tupleDesc->tdtypeid); - HeapTupleHeaderSetTypMod(new_data, tupleDesc->tdtypmod); - - /* Copy over the data, and fill the null bitmap if needed */ - heap_fill_tuple(tupleDesc, - toast_values, - toast_isnull, - (char *) new_data + new_header_len, - new_data_len, - &(new_data->t_infomask), - has_nulls ? new_data->t_bits : NULL); - - /* - * Free allocated temp values - */ - for (i = 0; i < numAttrs; i++) - if (toast_free[i]) - pfree(DatumGetPointer(toast_values[i])); - - return PointerGetDatum(new_data); -} - - -/* ---------- - * toast_build_flattened_tuple - - * - * Build a tuple containing no out-of-line toasted fields. - * (This does not eliminate compressed or short-header datums.) - * - * This is essentially just like heap_form_tuple, except that it will - * expand any external-data pointers beforehand. - * - * It's not very clear whether it would be preferable to decompress - * in-line compressed datums while at it. For now, we don't. - * ---------- - */ -HeapTuple -toast_build_flattened_tuple(TupleDesc tupleDesc, - Datum *values, - bool *isnull) -{ - HeapTuple new_tuple; - int numAttrs = tupleDesc->natts; - int num_to_free; - int i; - Datum new_values[MaxTupleAttributeNumber]; - Pointer freeable_values[MaxTupleAttributeNumber]; - - /* - * We can pass the caller's isnull array directly to heap_form_tuple, but - * we potentially need to modify the values array. - */ - Assert(numAttrs <= MaxTupleAttributeNumber); - memcpy(new_values, values, numAttrs * sizeof(Datum)); - - num_to_free = 0; - for (i = 0; i < numAttrs; i++) - { - /* - * Look at non-null varlena attributes - */ - if (!isnull[i] && TupleDescAttr(tupleDesc, i)->attlen == -1) - { - struct varlena *new_value; - - new_value = (struct varlena *) DatumGetPointer(new_values[i]); - if (VARATT_IS_EXTERNAL(new_value)) - { - new_value = heap_tuple_fetch_attr(new_value); - new_values[i] = PointerGetDatum(new_value); - freeable_values[num_to_free++] = (Pointer) new_value; - } - } - } - - /* - * Form the reconfigured tuple. - */ - new_tuple = heap_form_tuple(tupleDesc, new_values, isnull); - - /* - * Free allocated temp values - */ - for (i = 0; i < num_to_free; i++) - pfree(freeable_values[i]); - - return new_tuple; -} - - -/* ---------- - * toast_compress_datum - - * - * Create a compressed version of a varlena datum - * - * If we fail (ie, compressed result is actually bigger than original) - * then return NULL. We must not use compressed data if it'd expand - * the tuple! - * - * We use VAR{SIZE,DATA}_ANY so we can handle short varlenas here without - * copying them. But we can't handle external or compressed datums. - * ---------- - */ -Datum -toast_compress_datum(Datum value) -{ - struct varlena *tmp; - int32 valsize = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); - int32 len; - - Assert(!VARATT_IS_EXTERNAL(DatumGetPointer(value))); - Assert(!VARATT_IS_COMPRESSED(DatumGetPointer(value))); - - /* - * No point in wasting a palloc cycle if value size is out of the allowed - * range for compression - */ - if (valsize < PGLZ_strategy_default->min_input_size || - valsize > PGLZ_strategy_default->max_input_size) - return PointerGetDatum(NULL); - - tmp = (struct varlena *) palloc(PGLZ_MAX_OUTPUT(valsize) + - TOAST_COMPRESS_HDRSZ); - - /* - * We recheck the actual size even if pglz_compress() reports success, - * because it might be satisfied with having saved as little as one byte - * in the compressed data --- which could turn into a net loss once you - * consider header and alignment padding. Worst case, the compressed - * format might require three padding bytes (plus header, which is - * included in VARSIZE(tmp)), whereas the uncompressed format would take - * only one header byte and no padding if the value is short enough. So - * we insist on a savings of more than 2 bytes to ensure we have a gain. - */ - len = pglz_compress(VARDATA_ANY(DatumGetPointer(value)), - valsize, - TOAST_COMPRESS_RAWDATA(tmp), - PGLZ_strategy_default); - if (len >= 0 && - len + TOAST_COMPRESS_HDRSZ < valsize - 2) - { - TOAST_COMPRESS_SET_RAWSIZE(tmp, valsize); - SET_VARSIZE_COMPRESSED(tmp, len + TOAST_COMPRESS_HDRSZ); - /* successful compression */ - return PointerGetDatum(tmp); - } - else - { - /* incompressible data */ - pfree(tmp); - return PointerGetDatum(NULL); - } -} - - -/* ---------- - * toast_get_valid_index - * - * Get OID of valid index associated to given toast relation. A toast - * relation can have only one valid index at the same time. - */ -Oid -toast_get_valid_index(Oid toastoid, LOCKMODE lock) -{ - int num_indexes; - int validIndex; - Oid validIndexOid; - Relation *toastidxs; - Relation toastrel; - - /* Open the toast relation */ - toastrel = heap_open(toastoid, lock); - - /* Look for the valid index of the toast relation */ - validIndex = toast_open_indexes(toastrel, - lock, - &toastidxs, - &num_indexes); - validIndexOid = RelationGetRelid(toastidxs[validIndex]); - - /* Close the toast relation and all its indexes */ - toast_close_indexes(toastidxs, num_indexes, lock); - heap_close(toastrel, lock); - - return validIndexOid; -} - - -/* ---------- - * toast_save_datum - - * - * Save one single datum into the secondary relation and return - * a Datum reference for it. - * - * rel: the main relation we're working with (not the toast rel!) - * value: datum to be pushed to toast storage - * oldexternal: if not NULL, toast pointer previously representing the datum - * options: options to be passed to heap_insert() for toast rows - * ---------- - */ -static Datum -toast_save_datum(Relation rel, Datum value, - struct varlena *oldexternal, int options) -{ - Relation toastrel; - Relation *toastidxs; - HeapTuple toasttup; - TupleDesc toasttupDesc; - Datum t_values[3]; - bool t_isnull[3]; - CommandId mycid = GetCurrentCommandId(true); - struct varlena *result; - struct varatt_external toast_pointer; - union - { - struct varlena hdr; - /* this is to make the union big enough for a chunk: */ - char data[TOAST_MAX_CHUNK_SIZE + VARHDRSZ]; - /* ensure union is aligned well enough: */ - int32 align_it; - } chunk_data; - int32 chunk_size; - int32 chunk_seq = 0; - char *data_p; - int32 data_todo; - Pointer dval = DatumGetPointer(value); - int num_indexes; - int validIndex; - - Assert(!VARATT_IS_EXTERNAL(value)); - - /* - * Open the toast relation and its indexes. We can use the index to check - * uniqueness of the OID we assign to the toasted item, even though it has - * additional columns besides OID. - */ - toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock); - toasttupDesc = toastrel->rd_att; - - /* Open all the toast indexes and look for the valid one */ - validIndex = toast_open_indexes(toastrel, - RowExclusiveLock, - &toastidxs, - &num_indexes); - - /* - * Get the data pointer and length, and compute va_rawsize and va_extsize. - * - * va_rawsize is the size of the equivalent fully uncompressed datum, so - * we have to adjust for short headers. - * - * va_extsize is the actual size of the data payload in the toast records. - */ - if (VARATT_IS_SHORT(dval)) - { - data_p = VARDATA_SHORT(dval); - data_todo = VARSIZE_SHORT(dval) - VARHDRSZ_SHORT; - toast_pointer.va_rawsize = data_todo + VARHDRSZ; /* as if not short */ - toast_pointer.va_extsize = data_todo; - } - else if (VARATT_IS_COMPRESSED(dval)) - { - data_p = VARDATA(dval); - data_todo = VARSIZE(dval) - VARHDRSZ; - /* rawsize in a compressed datum is just the size of the payload */ - toast_pointer.va_rawsize = VARRAWSIZE_4B_C(dval) + VARHDRSZ; - toast_pointer.va_extsize = data_todo; - /* Assert that the numbers look like it's compressed */ - Assert(VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); - } - else - { - data_p = VARDATA(dval); - data_todo = VARSIZE(dval) - VARHDRSZ; - toast_pointer.va_rawsize = VARSIZE(dval); - toast_pointer.va_extsize = data_todo; - } - - /* - * Insert the correct table OID into the result TOAST pointer. - * - * Normally this is the actual OID of the target toast table, but during - * table-rewriting operations such as CLUSTER, we have to insert the OID - * of the table's real permanent toast table instead. rd_toastoid is set - * if we have to substitute such an OID. - */ - if (OidIsValid(rel->rd_toastoid)) - toast_pointer.va_toastrelid = rel->rd_toastoid; - else - toast_pointer.va_toastrelid = RelationGetRelid(toastrel); - - /* - * Choose an OID to use as the value ID for this toast value. - * - * Normally we just choose an unused OID within the toast table. But - * during table-rewriting operations where we are preserving an existing - * toast table OID, we want to preserve toast value OIDs too. So, if - * rd_toastoid is set and we had a prior external value from that same - * toast table, re-use its value ID. If we didn't have a prior external - * value (which is a corner case, but possible if the table's attstorage - * options have been changed), we have to pick a value ID that doesn't - * conflict with either new or existing toast value OIDs. - */ - if (!OidIsValid(rel->rd_toastoid)) - { - /* normal case: just choose an unused OID */ - toast_pointer.va_valueid = - GetNewOidWithIndex(toastrel, - RelationGetRelid(toastidxs[validIndex]), - (AttrNumber) 1); - } - else - { - /* rewrite case: check to see if value was in old toast table */ - toast_pointer.va_valueid = InvalidOid; - if (oldexternal != NULL) - { - struct varatt_external old_toast_pointer; - - Assert(VARATT_IS_EXTERNAL_ONDISK(oldexternal)); - /* Must copy to access aligned fields */ - VARATT_EXTERNAL_GET_POINTER(old_toast_pointer, oldexternal); - if (old_toast_pointer.va_toastrelid == rel->rd_toastoid) - { - /* This value came from the old toast table; reuse its OID */ - toast_pointer.va_valueid = old_toast_pointer.va_valueid; - - /* - * There is a corner case here: the table rewrite might have - * to copy both live and recently-dead versions of a row, and - * those versions could easily reference the same toast value. - * When we copy the second or later version of such a row, - * reusing the OID will mean we select an OID that's already - * in the new toast table. Check for that, and if so, just - * fall through without writing the data again. - * - * While annoying and ugly-looking, this is a good thing - * because it ensures that we wind up with only one copy of - * the toast value when there is only one copy in the old - * toast table. Before we detected this case, we'd have made - * multiple copies, wasting space; and what's worse, the - * copies belonging to already-deleted heap tuples would not - * be reclaimed by VACUUM. - */ - if (toastrel_valueid_exists(toastrel, - toast_pointer.va_valueid)) - { - /* Match, so short-circuit the data storage loop below */ - data_todo = 0; - } - } - } - if (toast_pointer.va_valueid == InvalidOid) - { - /* - * new value; must choose an OID that doesn't conflict in either - * old or new toast table - */ - do - { - toast_pointer.va_valueid = - GetNewOidWithIndex(toastrel, - RelationGetRelid(toastidxs[validIndex]), - (AttrNumber) 1); - } while (toastid_valueid_exists(rel->rd_toastoid, - toast_pointer.va_valueid)); - } - } - - /* - * Initialize constant parts of the tuple data - */ - t_values[0] = ObjectIdGetDatum(toast_pointer.va_valueid); - t_values[2] = PointerGetDatum(&chunk_data); - t_isnull[0] = false; - t_isnull[1] = false; - t_isnull[2] = false; - - /* - * Split up the item into chunks - */ - while (data_todo > 0) - { - int i; - - CHECK_FOR_INTERRUPTS(); - - /* - * Calculate the size of this chunk - */ - chunk_size = Min(TOAST_MAX_CHUNK_SIZE, data_todo); - - /* - * Build a tuple and store it - */ - t_values[1] = Int32GetDatum(chunk_seq++); - SET_VARSIZE(&chunk_data, chunk_size + VARHDRSZ); - memcpy(VARDATA(&chunk_data), data_p, chunk_size); - toasttup = heap_form_tuple(toasttupDesc, t_values, t_isnull); - - heap_insert(toastrel, toasttup, mycid, options, NULL); - - /* - * Create the index entry. We cheat a little here by not using - * FormIndexDatum: this relies on the knowledge that the index columns - * are the same as the initial columns of the table for all the - * indexes. We also cheat by not providing an IndexInfo: this is okay - * for now because btree doesn't need one, but we might have to be - * more honest someday. - * - * Note also that there had better not be any user-created index on - * the TOAST table, since we don't bother to update anything else. - */ - for (i = 0; i < num_indexes; i++) - { - /* Only index relations marked as ready can be updated */ - if (IndexIsReady(toastidxs[i]->rd_index)) - index_insert(toastidxs[i], t_values, t_isnull, - &(toasttup->t_self), - toastrel, - toastidxs[i]->rd_index->indisunique ? - UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, - NULL); - } - - /* - * Free memory - */ - heap_freetuple(toasttup); - - /* - * Move on to next chunk - */ - data_todo -= chunk_size; - data_p += chunk_size; - } - - /* - * Done - close toast relation and its indexes - */ - toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); - heap_close(toastrel, RowExclusiveLock); - - /* - * Create the TOAST pointer value that we'll return - */ - result = (struct varlena *) palloc(TOAST_POINTER_SIZE); - SET_VARTAG_EXTERNAL(result, VARTAG_ONDISK); - memcpy(VARDATA_EXTERNAL(result), &toast_pointer, sizeof(toast_pointer)); - - return PointerGetDatum(result); -} - - -/* ---------- - * toast_delete_datum - - * - * Delete a single external stored value. - * ---------- - */ -static void -toast_delete_datum(Relation rel, Datum value, bool is_speculative) -{ - struct varlena *attr = (struct varlena *) DatumGetPointer(value); - struct varatt_external toast_pointer; - Relation toastrel; - Relation *toastidxs; - ScanKeyData toastkey; - SysScanDesc toastscan; - HeapTuple toasttup; - int num_indexes; - int validIndex; - SnapshotData SnapshotToast; - - if (!VARATT_IS_EXTERNAL_ONDISK(attr)) - return; - - /* Must copy to access aligned fields */ - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - /* - * Open the toast relation and its indexes - */ - toastrel = heap_open(toast_pointer.va_toastrelid, RowExclusiveLock); - - /* Fetch valid relation used for process */ - validIndex = toast_open_indexes(toastrel, - RowExclusiveLock, - &toastidxs, - &num_indexes); - - /* - * Setup a scan key to find chunks with matching va_valueid - */ - ScanKeyInit(&toastkey, - (AttrNumber) 1, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(toast_pointer.va_valueid)); - - /* - * Find all the chunks. (We don't actually care whether we see them in - * sequence or not, but since we've already locked the index we might as - * well use systable_beginscan_ordered.) - */ - init_toast_snapshot(&SnapshotToast); - toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], - &SnapshotToast, 1, &toastkey); - while ((toasttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) - { - /* - * Have a chunk, delete it - */ - if (is_speculative) - heap_abort_speculative(toastrel, toasttup); - else - simple_heap_delete(toastrel, &toasttup->t_self); - } - - /* - * End scan and close relations - */ - systable_endscan_ordered(toastscan); - toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); - heap_close(toastrel, RowExclusiveLock); -} - - -/* ---------- - * toastrel_valueid_exists - - * - * Test whether a toast value with the given ID exists in the toast relation - * ---------- - */ -static bool -toastrel_valueid_exists(Relation toastrel, Oid valueid) -{ - bool result = false; - ScanKeyData toastkey; - SysScanDesc toastscan; - int num_indexes; - int validIndex; - Relation *toastidxs; - SnapshotData SnapshotToast; - - /* Fetch a valid index relation */ - validIndex = toast_open_indexes(toastrel, - RowExclusiveLock, - &toastidxs, - &num_indexes); - - /* - * Setup a scan key to find chunks with matching va_valueid - */ - ScanKeyInit(&toastkey, - (AttrNumber) 1, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(valueid)); - - /* - * Is there any such chunk? - */ - init_toast_snapshot(&SnapshotToast); - toastscan = systable_beginscan(toastrel, - RelationGetRelid(toastidxs[validIndex]), - true, &SnapshotToast, 1, &toastkey); - - if (systable_getnext(toastscan) != NULL) - result = true; - - systable_endscan(toastscan); - - /* Clean up */ - toast_close_indexes(toastidxs, num_indexes, RowExclusiveLock); - - return result; -} - -/* ---------- - * toastid_valueid_exists - - * - * As above, but work from toast rel's OID not an open relation - * ---------- - */ -static bool -toastid_valueid_exists(Oid toastrelid, Oid valueid) -{ - bool result; - Relation toastrel; - - toastrel = heap_open(toastrelid, AccessShareLock); - - result = toastrel_valueid_exists(toastrel, valueid); - - heap_close(toastrel, AccessShareLock); - - return result; -} - - -/* ---------- - * toast_fetch_datum - - * - * Reconstruct an in memory Datum from the chunks saved - * in the toast relation - * ---------- - */ -static struct varlena * -toast_fetch_datum(struct varlena *attr) -{ - Relation toastrel; - Relation *toastidxs; - ScanKeyData toastkey; - SysScanDesc toastscan; - HeapTuple ttup; - TupleDesc toasttupDesc; - struct varlena *result; - struct varatt_external toast_pointer; - int32 ressize; - int32 residx, - nextidx; - int32 numchunks; - Pointer chunk; - bool isnull; - char *chunkdata; - int32 chunksize; - int num_indexes; - int validIndex; - SnapshotData SnapshotToast; - - if (!VARATT_IS_EXTERNAL_ONDISK(attr)) - elog(ERROR, "toast_fetch_datum shouldn't be called for non-ondisk datums"); - - /* Must copy to access aligned fields */ - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - ressize = toast_pointer.va_extsize; - numchunks = ((ressize - 1) / TOAST_MAX_CHUNK_SIZE) + 1; - - result = (struct varlena *) palloc(ressize + VARHDRSZ); - - if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) - SET_VARSIZE_COMPRESSED(result, ressize + VARHDRSZ); - else - SET_VARSIZE(result, ressize + VARHDRSZ); - - /* - * Open the toast relation and its indexes - */ - toastrel = heap_open(toast_pointer.va_toastrelid, AccessShareLock); - toasttupDesc = toastrel->rd_att; - - /* Look for the valid index of the toast relation */ - validIndex = toast_open_indexes(toastrel, - AccessShareLock, - &toastidxs, - &num_indexes); - - /* - * Setup a scan key to fetch from the index by va_valueid - */ - ScanKeyInit(&toastkey, - (AttrNumber) 1, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(toast_pointer.va_valueid)); - - /* - * Read the chunks by index - * - * Note that because the index is actually on (valueid, chunkidx) we will - * see the chunks in chunkidx order, even though we didn't explicitly ask - * for it. - */ - nextidx = 0; - - init_toast_snapshot(&SnapshotToast); - toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], - &SnapshotToast, 1, &toastkey); - while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) - { - /* - * Have a chunk, extract the sequence number and the data - */ - residx = DatumGetInt32(fastgetattr(ttup, 2, toasttupDesc, &isnull)); - Assert(!isnull); - chunk = DatumGetPointer(fastgetattr(ttup, 3, toasttupDesc, &isnull)); - Assert(!isnull); - if (!VARATT_IS_EXTENDED(chunk)) - { - chunksize = VARSIZE(chunk) - VARHDRSZ; - chunkdata = VARDATA(chunk); - } - else if (VARATT_IS_SHORT(chunk)) - { - /* could happen due to heap_form_tuple doing its thing */ - chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT; - chunkdata = VARDATA_SHORT(chunk); - } - else - { - /* should never happen */ - elog(ERROR, "found toasted toast chunk for toast value %u in %s", - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - chunksize = 0; /* keep compiler quiet */ - chunkdata = NULL; - } - - /* - * Some checks on the data we've found - */ - if (residx != nextidx) - elog(ERROR, "unexpected chunk number %d (expected %d) for toast value %u in %s", - residx, nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - if (residx < numchunks - 1) - { - if (chunksize != TOAST_MAX_CHUNK_SIZE) - elog(ERROR, "unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s", - chunksize, (int) TOAST_MAX_CHUNK_SIZE, - residx, numchunks, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - } - else if (residx == numchunks - 1) - { - if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != ressize) - elog(ERROR, "unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s", - chunksize, - (int) (ressize - residx * TOAST_MAX_CHUNK_SIZE), - residx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - } - else - elog(ERROR, "unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", - residx, - 0, numchunks - 1, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - - /* - * Copy the data into proper place in our result - */ - memcpy(VARDATA(result) + residx * TOAST_MAX_CHUNK_SIZE, - chunkdata, - chunksize); - - nextidx++; - } - - /* - * Final checks that we successfully fetched the datum - */ - if (nextidx != numchunks) - elog(ERROR, "missing chunk number %d for toast value %u in %s", - nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - - /* - * End scan and close relations - */ - systable_endscan_ordered(toastscan); - toast_close_indexes(toastidxs, num_indexes, AccessShareLock); - heap_close(toastrel, AccessShareLock); - - return result; -} - -/* ---------- - * toast_fetch_datum_slice - - * - * Reconstruct a segment of a Datum from the chunks saved - * in the toast relation - * ---------- - */ -static struct varlena * -toast_fetch_datum_slice(struct varlena *attr, int32 sliceoffset, int32 length) -{ - Relation toastrel; - Relation *toastidxs; - ScanKeyData toastkey[3]; - int nscankeys; - SysScanDesc toastscan; - HeapTuple ttup; - TupleDesc toasttupDesc; - struct varlena *result; - struct varatt_external toast_pointer; - int32 attrsize; - int32 residx; - int32 nextidx; - int numchunks; - int startchunk; - int endchunk; - int32 startoffset; - int32 endoffset; - int totalchunks; - Pointer chunk; - bool isnull; - char *chunkdata; - int32 chunksize; - int32 chcpystrt; - int32 chcpyend; - int num_indexes; - int validIndex; - SnapshotData SnapshotToast; - - if (!VARATT_IS_EXTERNAL_ONDISK(attr)) - elog(ERROR, "toast_fetch_datum_slice shouldn't be called for non-ondisk datums"); - - /* Must copy to access aligned fields */ - VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr); - - /* - * It's nonsense to fetch slices of a compressed datum -- this isn't lo_* - * we can't return a compressed datum which is meaningful to toast later - */ - Assert(!VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)); - - attrsize = toast_pointer.va_extsize; - totalchunks = ((attrsize - 1) / TOAST_MAX_CHUNK_SIZE) + 1; - - if (sliceoffset >= attrsize) - { - sliceoffset = 0; - length = 0; - } - - if (((sliceoffset + length) > attrsize) || length < 0) - length = attrsize - sliceoffset; - - result = (struct varlena *) palloc(length + VARHDRSZ); - - if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer)) - SET_VARSIZE_COMPRESSED(result, length + VARHDRSZ); - else - SET_VARSIZE(result, length + VARHDRSZ); - - if (length == 0) - return result; /* Can save a lot of work at this point! */ - - startchunk = sliceoffset / TOAST_MAX_CHUNK_SIZE; - endchunk = (sliceoffset + length - 1) / TOAST_MAX_CHUNK_SIZE; - numchunks = (endchunk - startchunk) + 1; - - startoffset = sliceoffset % TOAST_MAX_CHUNK_SIZE; - endoffset = (sliceoffset + length - 1) % TOAST_MAX_CHUNK_SIZE; - - /* - * Open the toast relation and its indexes - */ - toastrel = heap_open(toast_pointer.va_toastrelid, AccessShareLock); - toasttupDesc = toastrel->rd_att; - - /* Look for the valid index of toast relation */ - validIndex = toast_open_indexes(toastrel, - AccessShareLock, - &toastidxs, - &num_indexes); - - /* - * Setup a scan key to fetch from the index. This is either two keys or - * three depending on the number of chunks. - */ - ScanKeyInit(&toastkey[0], - (AttrNumber) 1, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(toast_pointer.va_valueid)); - - /* - * Use equality condition for one chunk, a range condition otherwise: - */ - if (numchunks == 1) - { - ScanKeyInit(&toastkey[1], - (AttrNumber) 2, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(startchunk)); - nscankeys = 2; - } - else - { - ScanKeyInit(&toastkey[1], - (AttrNumber) 2, - BTGreaterEqualStrategyNumber, F_INT4GE, - Int32GetDatum(startchunk)); - ScanKeyInit(&toastkey[2], - (AttrNumber) 2, - BTLessEqualStrategyNumber, F_INT4LE, - Int32GetDatum(endchunk)); - nscankeys = 3; - } - - /* - * Read the chunks by index - * - * The index is on (valueid, chunkidx) so they will come in order - */ - init_toast_snapshot(&SnapshotToast); - nextidx = startchunk; - toastscan = systable_beginscan_ordered(toastrel, toastidxs[validIndex], - &SnapshotToast, nscankeys, toastkey); - while ((ttup = systable_getnext_ordered(toastscan, ForwardScanDirection)) != NULL) - { - /* - * Have a chunk, extract the sequence number and the data - */ - residx = DatumGetInt32(fastgetattr(ttup, 2, toasttupDesc, &isnull)); - Assert(!isnull); - chunk = DatumGetPointer(fastgetattr(ttup, 3, toasttupDesc, &isnull)); - Assert(!isnull); - if (!VARATT_IS_EXTENDED(chunk)) - { - chunksize = VARSIZE(chunk) - VARHDRSZ; - chunkdata = VARDATA(chunk); - } - else if (VARATT_IS_SHORT(chunk)) - { - /* could happen due to heap_form_tuple doing its thing */ - chunksize = VARSIZE_SHORT(chunk) - VARHDRSZ_SHORT; - chunkdata = VARDATA_SHORT(chunk); - } - else - { - /* should never happen */ - elog(ERROR, "found toasted toast chunk for toast value %u in %s", - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - chunksize = 0; /* keep compiler quiet */ - chunkdata = NULL; - } - - /* - * Some checks on the data we've found - */ - if ((residx != nextidx) || (residx > endchunk) || (residx < startchunk)) - elog(ERROR, "unexpected chunk number %d (expected %d) for toast value %u in %s", - residx, nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - if (residx < totalchunks - 1) - { - if (chunksize != TOAST_MAX_CHUNK_SIZE) - elog(ERROR, "unexpected chunk size %d (expected %d) in chunk %d of %d for toast value %u in %s when fetching slice", - chunksize, (int) TOAST_MAX_CHUNK_SIZE, - residx, totalchunks, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - } - else if (residx == totalchunks - 1) - { - if ((residx * TOAST_MAX_CHUNK_SIZE + chunksize) != attrsize) - elog(ERROR, "unexpected chunk size %d (expected %d) in final chunk %d for toast value %u in %s when fetching slice", - chunksize, - (int) (attrsize - residx * TOAST_MAX_CHUNK_SIZE), - residx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - } - else - elog(ERROR, "unexpected chunk number %d (out of range %d..%d) for toast value %u in %s", - residx, - 0, totalchunks - 1, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - - /* - * Copy the data into proper place in our result - */ - chcpystrt = 0; - chcpyend = chunksize - 1; - if (residx == startchunk) - chcpystrt = startoffset; - if (residx == endchunk) - chcpyend = endoffset; - - memcpy(VARDATA(result) + - (residx * TOAST_MAX_CHUNK_SIZE - sliceoffset) + chcpystrt, - chunkdata + chcpystrt, - (chcpyend - chcpystrt) + 1); - - nextidx++; - } - - /* - * Final checks that we successfully fetched the datum - */ - if (nextidx != (endchunk + 1)) - elog(ERROR, "missing chunk number %d for toast value %u in %s", - nextidx, - toast_pointer.va_valueid, - RelationGetRelationName(toastrel)); - - /* - * End scan and close relations - */ - systable_endscan_ordered(toastscan); - toast_close_indexes(toastidxs, num_indexes, AccessShareLock); - heap_close(toastrel, AccessShareLock); - - return result; -} - -/* ---------- - * toast_decompress_datum - - * - * Decompress a compressed version of a varlena datum - */ -static struct varlena * -toast_decompress_datum(struct varlena *attr) -{ - struct varlena *result; - - Assert(VARATT_IS_COMPRESSED(attr)); - - result = (struct varlena *) - palloc(TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); - SET_VARSIZE(result, TOAST_COMPRESS_RAWSIZE(attr) + VARHDRSZ); - - if (pglz_decompress(TOAST_COMPRESS_RAWDATA(attr), - VARSIZE(attr) - TOAST_COMPRESS_HDRSZ, - VARDATA(result), - TOAST_COMPRESS_RAWSIZE(attr)) < 0) - elog(ERROR, "compressed data is corrupted"); - - return result; -} - - -/* ---------- - * toast_open_indexes - * - * Get an array of the indexes associated to the given toast relation - * and return as well the position of the valid index used by the toast - * relation in this array. It is the responsibility of the caller of this - * function to close the indexes as well as free them. - */ -static int -toast_open_indexes(Relation toastrel, - LOCKMODE lock, - Relation **toastidxs, - int *num_indexes) -{ - int i = 0; - int res = 0; - bool found = false; - List *indexlist; - ListCell *lc; - - /* Get index list of the toast relation */ - indexlist = RelationGetIndexList(toastrel); - Assert(indexlist != NIL); - - *num_indexes = list_length(indexlist); - - /* Open all the index relations */ - *toastidxs = (Relation *) palloc(*num_indexes * sizeof(Relation)); - foreach(lc, indexlist) - (*toastidxs)[i++] = index_open(lfirst_oid(lc), lock); - - /* Fetch the first valid index in list */ - for (i = 0; i < *num_indexes; i++) - { - Relation toastidx = (*toastidxs)[i]; - - if (toastidx->rd_index->indisvalid) - { - res = i; - found = true; - break; - } - } - - /* - * Free index list, not necessary anymore as relations are opened and a - * valid index has been found. - */ - list_free(indexlist); - - /* - * The toast relation should have one valid index, so something is going - * wrong if there is nothing. - */ - if (!found) - elog(ERROR, "no valid index found for toast relation with Oid %u", - RelationGetRelid(toastrel)); - - return res; -} - -/* ---------- - * toast_close_indexes - * - * Close an array of indexes for a toast relation and free it. This should - * be called for a set of indexes opened previously with toast_open_indexes. - */ -static void -toast_close_indexes(Relation *toastidxs, int num_indexes, LOCKMODE lock) -{ - int i; - - /* Close relations and clean up things */ - for (i = 0; i < num_indexes; i++) - index_close(toastidxs[i], lock); - pfree(toastidxs); -} - -/* ---------- - * init_toast_snapshot - * - * Initialize an appropriate TOAST snapshot. We must use an MVCC snapshot - * to initialize the TOAST snapshot; since we don't know which one to use, - * just use the oldest one. This is safe: at worst, we will get a "snapshot - * too old" error that might have been avoided otherwise. - */ -static void -init_toast_snapshot(Snapshot toast_snapshot) -{ - Snapshot snapshot = GetOldestSnapshot(); - - if (snapshot == NULL) - elog(ERROR, "no known snapshots"); - - InitToastSnapshot(*toast_snapshot, snapshot->lsn, snapshot->whenTaken); -} diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c similarity index 91% rename from src/backend/commands/vacuumlazy.c rename to src/backend/access/heap/vacuumlazy.c index 5649a70800d..a3c4a1df3b4 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -23,12 +23,12 @@ * the TID array, just enough to hold as many heap tuples as fit on one page. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * src/backend/commands/vacuumlazy.c + * src/backend/access/heap/vacuumlazy.c * *------------------------------------------------------------------------- */ @@ -59,7 +59,6 @@ #include "utils/memutils.h" #include "utils/pg_rusage.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* @@ -113,8 +112,8 @@ typedef struct LVRelStats { - /* hasindex = true means two-pass strategy; false means one-pass */ - bool hasindex; + /* useindex = true means two-pass strategy; false means one-pass */ + bool useindex; /* Overall statistics about rel */ BlockNumber old_rel_pages; /* previous value of pg_class.relpages */ BlockNumber rel_pages; /* total number of pages */ @@ -151,34 +150,35 @@ static BufferAccessStrategy vac_strategy; /* non-export function prototypes */ -static void lazy_scan_heap(Relation onerel, int options, - LVRelStats *vacrelstats, Relation *Irel, int nindexes, - bool aggressive); +static void lazy_scan_heap(Relation onerel, VacuumParams *params, + LVRelStats *vacrelstats, Relation *Irel, int nindexes, + bool aggressive); static void lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats); static bool lazy_check_needs_freeze(Buffer buf, bool *hastup); static void lazy_vacuum_index(Relation indrel, - IndexBulkDeleteResult **stats, - LVRelStats *vacrelstats); + IndexBulkDeleteResult **stats, + LVRelStats *vacrelstats); static void lazy_cleanup_index(Relation indrel, - IndexBulkDeleteResult *stats, - LVRelStats *vacrelstats); -static int lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, - int tupindex, LVRelStats *vacrelstats, Buffer *vmbuffer); -static bool should_attempt_truncation(LVRelStats *vacrelstats); + IndexBulkDeleteResult *stats, + LVRelStats *vacrelstats); +static int lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, + int tupindex, LVRelStats *vacrelstats, Buffer *vmbuffer); +static bool should_attempt_truncation(VacuumParams *params, + LVRelStats *vacrelstats); static void lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats); static BlockNumber count_nondeletable_pages(Relation onerel, - LVRelStats *vacrelstats); + LVRelStats *vacrelstats); static void lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks); static void lazy_record_dead_tuple(LVRelStats *vacrelstats, - ItemPointer itemptr); + ItemPointer itemptr); static bool lazy_tid_reaped(ItemPointer itemptr, void *state); static int vac_cmp_itemptr(const void *left, const void *right); static bool heap_page_is_all_visible(Relation rel, Buffer buf, - TransactionId *visibility_cutoff_xid, bool *all_frozen); + TransactionId *visibility_cutoff_xid, bool *all_frozen); /* - * lazy_vacuum_rel() -- perform LAZY VACUUM for one heap relation + * heap_vacuum_rel() -- perform VACUUM for one heap relation * * This routine vacuums a single heap, cleans out its indexes, and * updates its relpages and reltuples statistics. @@ -187,7 +187,7 @@ static bool heap_page_is_all_visible(Relation rel, Buffer buf, * and locked the relation. */ void -lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, +heap_vacuum_rel(Relation onerel, VacuumParams *params, BufferAccessStrategy bstrategy) { LVRelStats *vacrelstats; @@ -210,6 +210,12 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, MultiXactId new_min_multi; Assert(params != NULL); + Assert(params->index_cleanup != VACOPT_TERNARY_DEFAULT); + Assert(params->truncate != VACOPT_TERNARY_DEFAULT); + + /* not every AM requires these to be valid, but heap does */ + Assert(TransactionIdIsNormal(onerel->rd_rel->relfrozenxid)); + Assert(MultiXactIdIsValid(onerel->rd_rel->relminmxid)); /* measure elapsed time iff autovacuum logging requires it */ if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) @@ -218,7 +224,7 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, starttime = GetCurrentTimestamp(); } - if (options & VACOPT_VERBOSE) + if (params->options & VACOPT_VERBOSE) elevel = INFO; else elevel = DEBUG2; @@ -246,9 +252,26 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, xidFullScanLimit); aggressive |= MultiXactIdPrecedesOrEquals(onerel->rd_rel->relminmxid, mxactFullScanLimit); - if (options & VACOPT_DISABLE_PAGE_SKIPPING) + if (params->options & VACOPT_DISABLE_PAGE_SKIPPING) aggressive = true; + /* + * Normally the relfrozenxid for an anti-wraparound vacuum will be old + * enough to force an aggressive vacuum. However, a concurrent vacuum + * might have already done this work that the relfrozenxid in relcache has + * been updated. If that happens this vacuum is redundant, so skip it. + */ + if (params->is_wraparound && !aggressive) + { + ereport(DEBUG1, + (errmsg("skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"", + get_database_name(MyDatabaseId), + get_namespace_name(RelationGetNamespace(onerel)), + RelationGetRelationName(onerel)))); + pgstat_progress_end_command(); + return; + } + vacrelstats = (LVRelStats *) palloc0(sizeof(LVRelStats)); vacrelstats->old_rel_pages = onerel->rd_rel->relpages; @@ -259,10 +282,11 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, /* Open all indexes of the relation */ vac_open_indexes(onerel, RowExclusiveLock, &nindexes, &Irel); - vacrelstats->hasindex = (nindexes > 0); + vacrelstats->useindex = (nindexes > 0 && + params->index_cleanup == VACOPT_TERNARY_ENABLED); /* Do the vacuuming */ - lazy_scan_heap(onerel, options, vacrelstats, Irel, nindexes, aggressive); + lazy_scan_heap(onerel, params, vacrelstats, Irel, nindexes, aggressive); /* Done with indexes */ vac_close_indexes(nindexes, Irel, NoLock); @@ -286,7 +310,7 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, /* * Optionally truncate the relation. */ - if (should_attempt_truncation(vacrelstats)) + if (should_attempt_truncation(params, vacrelstats)) lazy_truncate_heap(onerel, vacrelstats); /* Report that we are now doing final cleanup */ @@ -333,7 +357,7 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, new_rel_pages, new_live_tuples, new_rel_allvisible, - vacrelstats->hasindex, + nindexes > 0, new_frozen_xid, new_min_multi, false); @@ -374,10 +398,19 @@ lazy_vacuum_rel(Relation onerel, int options, VacuumParams *params, * emitting individual parts of the message when not applicable. */ initStringInfo(&buf); - if (aggressive) - msgfmt = _("automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n"); + if (params->is_wraparound) + { + /* an anti-wraparound vacuum has to be aggressive */ + Assert(aggressive); + msgfmt = _("automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n"); + } else - msgfmt = _("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"); + { + if (aggressive) + msgfmt = _("automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n"); + else + msgfmt = _("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"); + } appendStringInfo(&buf, msgfmt, get_database_name(MyDatabaseId), get_namespace_name(RelationGetNamespace(onerel)), @@ -460,7 +493,7 @@ vacuum_log_cleanup_info(Relation rel, LVRelStats *vacrelstats) * reference them have been killed. */ static void -lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, +lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, Relation *Irel, int nindexes, bool aggressive) { BlockNumber nblocks, @@ -476,7 +509,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, live_tuples, /* live tuples (reltuples estimate) */ tups_vacuumed, /* tuples cleaned up by vacuum */ nkeep, /* dead-but-not-removable tuples */ - nunused; /* unused item pointers */ + nunused; /* unused line pointers */ IndexBulkDeleteResult **indstats; int i; PGRUsage ru0; @@ -574,7 +607,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, * be replayed on any hot standby, where it can be disruptive. */ next_unskippable_block = 0; - if ((options & VACOPT_DISABLE_PAGE_SKIPPING) == 0) + if ((params->options & VACOPT_DISABLE_PAGE_SKIPPING) == 0) { while (next_unskippable_block < nblocks) { @@ -621,7 +654,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, /* see note above about forcing scanning of last page */ #define FORCE_CHECK_PAGE() \ - (blkno == nblocks - 1 && should_attempt_truncation(vacrelstats)) + (blkno == nblocks - 1 && should_attempt_truncation(params, vacrelstats)) pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno); @@ -629,7 +662,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, { /* Time to advance next_unskippable_block */ next_unskippable_block++; - if ((options & VACOPT_DISABLE_PAGE_SKIPPING) == 0) + if ((params->options & VACOPT_DISABLE_PAGE_SKIPPING) == 0) { while (next_unskippable_block < nblocks) { @@ -851,43 +884,46 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, if (PageIsNew(page)) { + bool still_new; + /* - * An all-zeroes page could be left over if a backend extends the - * relation but crashes before initializing the page. Reclaim such - * pages for use. + * All-zeroes pages can be left over if either a backend extends + * the relation by a single page, but crashes before the newly + * initialized page has been written out, or when bulk-extending + * the relation (which creates a number of empty pages at the tail + * end of the relation, but enters them into the FSM). * - * We have to be careful here because we could be looking at a - * page that someone has just added to the relation and not yet - * been able to initialize (see RelationGetBufferForTuple). To - * protect against that, release the buffer lock, grab the - * relation extension lock momentarily, and re-lock the buffer. If - * the page is still uninitialized by then, it must be left over - * from a crashed backend, and we can initialize it. + * Make sure these pages are in the FSM, to ensure they can be + * reused. Do that by testing if there's any space recorded for + * the page. If not, enter it. * - * We don't really need the relation lock when this is a new or - * temp relation, but it's probably not worth the code space to - * check that, since this surely isn't a critical path. - * - * Note: the comparable code in vacuum.c need not worry because - * it's got exclusive lock on the whole relation. + * Note we do not enter the page into the visibilitymap. That has + * the downside that we repeatedly visit this page in subsequent + * vacuums, but otherwise we'll never not discover the space on a + * promoted standby. The harm of repeated checking ought to + * normally not be too bad - the space usually should be used at + * some point, otherwise there wouldn't be any regular vacuums. */ - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - LockRelationForExtension(onerel, ExclusiveLock); - UnlockRelationForExtension(onerel, ExclusiveLock); - LockBufferForCleanup(buf); - if (PageIsNew(page)) + + /* + * Perform checking of FSM after releasing lock, the fsm is + * approximate, after all. + */ + still_new = PageIsNew(page); + UnlockReleaseBuffer(buf); + + if (still_new) { - ereport(WARNING, - (errmsg("relation \"%s\" page %u is uninitialized --- fixing", - relname, blkno))); - PageInit(page, BufferGetPageSize(buf), 0); empty_pages++; - } - freespace = PageGetHeapFreeSpace(page); - MarkBufferDirty(buf); - UnlockReleaseBuffer(buf); - RecordPageWithFreeSpace(onerel, blkno, freespace); + if (GetRecordedFreeSpace(onerel, blkno) == 0) + { + Size freespace; + + freespace = BufferGetPageSize(buf) - SizeOfPageHeaderData; + RecordPageWithFreeSpace(onerel, blkno, freespace); + } + } continue; } @@ -896,7 +932,10 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, empty_pages++; freespace = PageGetHeapFreeSpace(page); - /* empty pages are always all-visible and all-frozen */ + /* + * Empty pages are always all-visible and all-frozen (note that + * the same is currently not true for new pages, see above). + */ if (!PageIsAllVisible(page)) { START_CRIT_SECTION(); @@ -978,7 +1017,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, ItemPointerSet(&(tuple.t_self), blkno, offnum); /* - * DEAD item pointers are to be vacuumed normally; but we don't + * DEAD line pointers are to be vacuumed normally; but we don't * count them in tups_vacuumed, else we'd be double-counting (at * least in the common case where heap_page_prune() just freed up * a non-HOT tuple). @@ -1026,7 +1065,11 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, * it were RECENTLY_DEAD. Also, if it's a heap-only * tuple, we choose to keep it, because it'll be a lot * cheaper to get rid of it in the next pruning pass than - * to treat it like an indexed tuple. + * to treat it like an indexed tuple. Finally, if index + * cleanup is disabled, the second heap pass will not + * execute, and the tuple will not get removed, so we must + * treat it like any other dead tuple that we choose to + * keep. * * If this were to happen for a tuple that actually needed * to be deleted, we'd be in trouble, because it'd @@ -1036,18 +1079,14 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, * preventing corruption. */ if (HeapTupleIsHotUpdated(&tuple) || - HeapTupleIsHeapOnly(&tuple)) + HeapTupleIsHeapOnly(&tuple) || + params->index_cleanup == VACOPT_TERNARY_DISABLED) nkeep += 1; else tupgone = true; /* we can delete the tuple */ all_visible = false; break; case HEAPTUPLE_LIVE: - /* Tuple is good --- but let's do some validity checks */ - if (onerel->rd_rel->relhasoids && - !OidIsValid(HeapTupleGetOid(&tuple))) - elog(WARNING, "relation \"%s\" TID %u/%u: OID is invalid", - relname, blkno, offnum); /* * Count it as live. Not only is this natural, but it's @@ -1197,15 +1236,33 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, } /* - * If there are no indexes then we can vacuum the page right now - * instead of doing a second scan. + * If there are no indexes we can vacuum the page right now instead of + * doing a second scan. Also we don't do that but forget dead tuples + * when index cleanup is disabled. */ - if (nindexes == 0 && - vacrelstats->num_dead_tuples > 0) + if (!vacrelstats->useindex && vacrelstats->num_dead_tuples > 0) { - /* Remove tuples from heap */ - lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats, &vmbuffer); - has_dead_tuples = false; + if (nindexes == 0) + { + /* Remove tuples from heap if the table has no index */ + lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats, &vmbuffer); + vacuumed_pages++; + has_dead_tuples = false; + } + else + { + /* + * Here, we have indexes but index cleanup is disabled. + * Instead of vacuuming the dead tuples on the heap, we just + * forget them. + * + * Note that vacrelstats->dead_tuples could have tuples which + * became dead after HOT-pruning but are not marked dead yet. + * We do not process them because it's a very rare condition, + * and the next vacuum will process them anyway. + */ + Assert(params->index_cleanup == VACOPT_TERNARY_DISABLED); + } /* * Forget the now-vacuumed tuples, and press on, but be careful @@ -1213,7 +1270,6 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, * valid. */ vacrelstats->num_dead_tuples = 0; - vacuumed_pages++; /* * Periodically do incremental FSM vacuuming to make newly-freed @@ -1408,8 +1464,11 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, PROGRESS_VACUUM_PHASE_INDEX_CLEANUP); /* Do post-vacuum cleanup and statistics update for each index */ - for (i = 0; i < nindexes; i++) - lazy_cleanup_index(Irel[i], indstats[i], vacrelstats); + if (vacrelstats->useindex) + { + for (i = 0; i < nindexes; i++) + lazy_cleanup_index(Irel[i], indstats[i], vacrelstats); + } /* If no indexes, make log report that lazy_vacuum_heap would've made */ if (vacuumed_pages) @@ -1426,7 +1485,7 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats, appendStringInfo(&buf, _("%.0f dead row versions cannot be removed yet, oldest xmin: %u\n"), nkeep, OldestXmin); - appendStringInfo(&buf, _("There were %.0f unused item pointers.\n"), + appendStringInfo(&buf, _("There were %.0f unused item identifiers.\n"), nunused); appendStringInfo(&buf, ngettext("Skipped %u page due to buffer pins, ", "Skipped %u pages due to buffer pins, ", @@ -1636,12 +1695,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup) *hastup = false; - /* If we hit an uninitialized page, we want to force vacuuming it. */ - if (PageIsNew(page)) - return true; - - /* Quick out for ordinary empty page. */ - if (PageIsEmpty(page)) + /* + * New and empty pages, obviously, don't contain tuples. We could make + * sure that the page is registered in the FSM, but it doesn't seem worth + * waiting for a cleanup lock just for that, especially because it's + * likely that the pin holder will do so. + */ + if (PageIsNew(page) || PageIsEmpty(page)) return false; maxoff = PageGetMaxOffsetNumber(page); @@ -1690,6 +1750,7 @@ lazy_vacuum_index(Relation indrel, ivinfo.index = indrel; ivinfo.analyze_only = false; + ivinfo.report_progress = false; ivinfo.estimated_count = true; ivinfo.message_level = elevel; /* We can only provide an approximate value of num_heap_tuples here */ @@ -1722,6 +1783,7 @@ lazy_cleanup_index(Relation indrel, ivinfo.index = indrel; ivinfo.analyze_only = false; + ivinfo.report_progress = false; ivinfo.estimated_count = (vacrelstats->tupcount_pages < vacrelstats->rel_pages); ivinfo.message_level = elevel; @@ -1787,10 +1849,13 @@ lazy_cleanup_index(Relation indrel, * careful to depend only on fields that lazy_scan_heap updates on-the-fly. */ static bool -should_attempt_truncation(LVRelStats *vacrelstats) +should_attempt_truncation(VacuumParams *params, LVRelStats *vacrelstats) { BlockNumber possibly_freeable; + if (params->truncate == VACOPT_TERNARY_DISABLED) + return false; + possibly_freeable = vacrelstats->rel_pages - vacrelstats->nonempty_pages; if (possibly_freeable > 0 && (possibly_freeable >= REL_TRUNCATE_MINIMUM || @@ -2026,7 +2091,6 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats) if (PageIsNew(page) || PageIsEmpty(page)) { - /* PageIsNew probably shouldn't happen... */ UnlockReleaseBuffer(buf); continue; } @@ -2082,7 +2146,7 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks) autovacuum_work_mem != -1 ? autovacuum_work_mem : maintenance_work_mem; - if (vacrelstats->hasindex) + if (vacrelstats->useindex) { maxtuples = (vac_work_mem * 1024L) / sizeof(ItemPointerData); maxtuples = Min(maxtuples, INT_MAX); diff --git a/src/backend/access/heap/visibilitymap.c b/src/backend/access/heap/visibilitymap.c index b251e697034..32bf2e4bf4c 100644 --- a/src/backend/access/heap/visibilitymap.c +++ b/src/backend/access/heap/visibilitymap.c @@ -3,7 +3,7 @@ * visibilitymap.c * bitmap for tracking visibility of heap tuples * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,7 +17,8 @@ * visibilitymap_set - set a bit in a previously pinned page * visibilitymap_get_status - get status of bits * visibilitymap_count - count number of bits set in visibility map - * visibilitymap_truncate - truncate the visibility map + * visibilitymap_prepare_truncate - + * prepare for truncation of the visibility map * * NOTES * @@ -89,6 +90,7 @@ #include "access/visibilitymap.h" #include "access/xlog.h" #include "miscadmin.h" +#include "port/pg_bitutils.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/smgr.h" @@ -115,47 +117,15 @@ #define HEAPBLK_TO_MAPBYTE(x) (((x) % HEAPBLOCKS_PER_PAGE) / HEAPBLOCKS_PER_BYTE) #define HEAPBLK_TO_OFFSET(x) (((x) % HEAPBLOCKS_PER_BYTE) * BITS_PER_HEAPBLOCK) -/* tables for fast counting of set bits for visible and frozen */ -static const uint8 number_of_ones_for_visible[256] = { - 0, 1, 0, 1, 1, 2, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 0, 1, 0, 1, 1, 2, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 4, 3, 4, 2, 3, 2, 3, 3, 4, 3, 4, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 4, 3, 4, 2, 3, 2, 3, 3, 4, 3, 4, - 0, 1, 0, 1, 1, 2, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 0, 1, 0, 1, 1, 2, 1, 2, 0, 1, 0, 1, 1, 2, 1, 2, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 4, 3, 4, 2, 3, 2, 3, 3, 4, 3, 4, - 1, 2, 1, 2, 2, 3, 2, 3, 1, 2, 1, 2, 2, 3, 2, 3, - 2, 3, 2, 3, 3, 4, 3, 4, 2, 3, 2, 3, 3, 4, 3, 4 -}; -static const uint8 number_of_ones_for_frozen[256] = { - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, - 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 4, 4, - 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 4, 4, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, - 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 4, 4, - 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 4, 4, 3, 3, 4, 4 -}; +/* Masks for counting subsets of bits in the visibility map. */ +#define VISIBLE_MASK64 UINT64CONST(0x5555555555555555) /* The lower bit of each + * bit pair */ +#define FROZEN_MASK64 UINT64CONST(0xaaaaaaaaaaaaaaaa) /* The upper bit of each + * bit pair */ /* prototypes for internal routines */ static Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend); -static void vm_extend(Relation rel, BlockNumber nvmblocks); +static void vm_extend(Relation rel, BlockNumber vm_nblocks); /* @@ -408,18 +378,16 @@ void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen) { BlockNumber mapBlock; + BlockNumber nvisible = 0; + BlockNumber nfrozen = 0; /* all_visible must be specified */ Assert(all_visible); - *all_visible = 0; - if (all_frozen) - *all_frozen = 0; - for (mapBlock = 0;; mapBlock++) { Buffer mapBuffer; - unsigned char *map; + uint64 *map; int i; /* @@ -436,30 +404,45 @@ visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_fro * immediately stale anyway if anyone is concurrently setting or * clearing bits, and we only really need an approximate value. */ - map = (unsigned char *) PageGetContents(BufferGetPage(mapBuffer)); + map = (uint64 *) PageGetContents(BufferGetPage(mapBuffer)); - for (i = 0; i < MAPSIZE; i++) + StaticAssertStmt(MAPSIZE % sizeof(uint64) == 0, + "unsupported MAPSIZE"); + if (all_frozen == NULL) + { + for (i = 0; i < MAPSIZE / sizeof(uint64); i++) + nvisible += pg_popcount64(map[i] & VISIBLE_MASK64); + } + else { - *all_visible += number_of_ones_for_visible[map[i]]; - if (all_frozen) - *all_frozen += number_of_ones_for_frozen[map[i]]; + for (i = 0; i < MAPSIZE / sizeof(uint64); i++) + { + nvisible += pg_popcount64(map[i] & VISIBLE_MASK64); + nfrozen += pg_popcount64(map[i] & FROZEN_MASK64); + } } ReleaseBuffer(mapBuffer); } + + *all_visible = nvisible; + if (all_frozen) + *all_frozen = nfrozen; } /* - * visibilitymap_truncate - truncate the visibility map - * - * The caller must hold AccessExclusiveLock on the relation, to ensure that - * other backends receive the smgr invalidation event that this function sends - * before they access the VM again. + * visibilitymap_prepare_truncate - + * prepare for truncation of the visibility map * * nheapblocks is the new size of the heap. + * + * Return the number of blocks of new visibility map. + * If it's InvalidBlockNumber, there is nothing to truncate; + * otherwise the caller is responsible for calling smgrtruncate() + * to truncate the visibility map pages. */ -void -visibilitymap_truncate(Relation rel, BlockNumber nheapblocks) +BlockNumber +visibilitymap_prepare_truncate(Relation rel, BlockNumber nheapblocks) { BlockNumber newnblocks; @@ -479,7 +462,7 @@ visibilitymap_truncate(Relation rel, BlockNumber nheapblocks) * nothing to truncate. */ if (!smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) - return; + return InvalidBlockNumber; /* * Unless the new size is exactly at a visibility map page boundary, the @@ -500,7 +483,7 @@ visibilitymap_truncate(Relation rel, BlockNumber nheapblocks) if (!BufferIsValid(mapBuffer)) { /* nothing to do, the file was already smaller */ - return; + return InvalidBlockNumber; } page = BufferGetPage(mapBuffer); @@ -548,20 +531,10 @@ visibilitymap_truncate(Relation rel, BlockNumber nheapblocks) if (smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM) <= newnblocks) { /* nothing to do, the file was already smaller than requested size */ - return; + return InvalidBlockNumber; } - /* Truncate the unused VM pages, and send smgr inval message */ - smgrtruncate(rel->rd_smgr, VISIBILITYMAP_FORKNUM, newnblocks); - - /* - * We might as well update the local smgr_vm_nblocks setting. smgrtruncate - * sent an smgr cache inval message, which will cause other backends to - * invalidate their copy of smgr_vm_nblocks, and this one too at the next - * command boundary. But this ensures it isn't outright wrong until then. - */ - if (rel->rd_smgr) - rel->rd_smgr->smgr_vm_nblocks = newnblocks; + return newnblocks; } /* @@ -610,11 +583,30 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend) * Use ZERO_ON_ERROR mode, and initialize the page if necessary. It's * always safe to clear bits, so it's better to clear corrupt pages than * error out. + * + * The initialize-the-page part is trickier than it looks, because of the + * possibility of multiple backends doing this concurrently, and our + * desire to not uselessly take the buffer lock in the normal path where + * the page is OK. We must take the lock to initialize the page, so + * recheck page newness after we have the lock, in case someone else + * already did it. Also, because we initially check PageIsNew with no + * lock, it's possible to fall through and return the buffer while someone + * else is still initializing the page (i.e., we might see pd_upper as set + * but other page header fields are still zeroes). This is harmless for + * callers that will take a buffer lock themselves, but some callers + * inspect the page without any lock at all. The latter is OK only so + * long as it doesn't depend on the page header having correct contents. + * Current usage is safe because PageGetContents() does not require that. */ buf = ReadBufferExtended(rel, VISIBILITYMAP_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); if (PageIsNew(BufferGetPage(buf))) - PageInit(BufferGetPage(buf), BLCKSZ, 0); + { + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (PageIsNew(BufferGetPage(buf))) + PageInit(BufferGetPage(buf), BLCKSZ, 0); + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + } return buf; } @@ -626,10 +618,9 @@ static void vm_extend(Relation rel, BlockNumber vm_nblocks) { BlockNumber vm_nblocks_now; - Page pg; + PGAlignedBlock pg; - pg = (Page) palloc(BLCKSZ); - PageInit(pg, BLCKSZ, 0); + PageInit((Page) pg.data, BLCKSZ, 0); /* * We use the relation extension lock to lock out other backends trying to @@ -660,10 +651,10 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) /* Now extend the file */ while (vm_nblocks_now < vm_nblocks) { - PageSetChecksumInplace(pg, vm_nblocks_now); + PageSetChecksumInplace((Page) pg.data, vm_nblocks_now); smgrextend(rel->rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now, - (char *) pg, false); + pg.data, false); vm_nblocks_now++; } @@ -680,6 +671,4 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) rel->rd_smgr->smgr_vm_nblocks = vm_nblocks_now; UnlockRelationForExtension(rel, ExclusiveLock); - - pfree(pg); } diff --git a/src/backend/access/index/amapi.c b/src/backend/access/index/amapi.c index f395cb1ab4f..450a7dce1fc 100644 --- a/src/backend/access/index/amapi.c +++ b/src/backend/access/index/amapi.c @@ -3,7 +3,7 @@ * amapi.c * Support routines for API for Postgres index access methods. * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/index/amvalidate.c b/src/backend/access/index/amvalidate.c index 24f9927f820..5a2728502ce 100644 --- a/src/backend/access/index/amvalidate.c +++ b/src/backend/access/index/amvalidate.c @@ -3,7 +3,7 @@ * amvalidate.c * Support routines for index access methods' amvalidate functions. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 58b44117961..2599b5d3425 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -3,7 +3,7 @@ * genam.c * general index access method routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,7 +19,10 @@ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/transam.h" #include "catalog/index.h" #include "lib/stringinfo.h" @@ -33,7 +36,6 @@ #include "utils/ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* ---------------------------------------------------------------- @@ -82,6 +84,7 @@ RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys) scan = (IndexScanDesc) palloc(sizeof(IndexScanDescData)); scan->heapRelation = NULL; /* may be set later */ + scan->xs_heapfetch = NULL; scan->indexRelation = indexRelation; scan->xs_snapshot = InvalidSnapshot; /* caller must initialize this */ scan->numberOfKeys = nkeys; @@ -122,11 +125,6 @@ RelationGetIndexScan(Relation indexRelation, int nkeys, int norderbys) scan->xs_hitup = NULL; scan->xs_hitupdesc = NULL; - ItemPointerSetInvalid(&scan->xs_ctup.t_self); - scan->xs_ctup.t_data = NULL; - scan->xs_cbuf = InvalidBuffer; - scan->xs_continue_hot = false; - return scan; } @@ -180,7 +178,6 @@ BuildIndexValueDescription(Relation indexRelation, { StringInfoData buf; Form_pg_index idxrec; - HeapTuple ht_idx; int indnkeyatts; int i; int keyno; @@ -200,24 +197,13 @@ BuildIndexValueDescription(Relation indexRelation, * Next we need to check table-level SELECT access and then, if there is * no access there, check column-level permissions. */ - - /* - * Fetch the pg_index tuple by the Oid of the index - */ - ht_idx = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexrelid)); - if (!HeapTupleIsValid(ht_idx)) - elog(ERROR, "cache lookup failed for index %u", indexrelid); - idxrec = (Form_pg_index) GETSTRUCT(ht_idx); - + idxrec = indexRelation->rd_index; indrelid = idxrec->indrelid; Assert(indexrelid == idxrec->indexrelid); /* RLS check- if RLS is enabled then we don't return anything. */ if (check_enable_rls(indrelid, InvalidOid, true) == RLS_ENABLED) - { - ReleaseSysCache(ht_idx); return NULL; - } /* Table-level SELECT is enough, if the user has it */ aclresult = pg_class_aclcheck(indrelid, GetUserId(), ACL_SELECT); @@ -227,7 +213,7 @@ BuildIndexValueDescription(Relation indexRelation, * No table-level access, so step through the columns in the index and * make sure the user has SELECT rights on all of them. */ - for (keyno = 0; keyno < idxrec->indnkeyatts; keyno++) + for (keyno = 0; keyno < indnkeyatts; keyno++) { AttrNumber attnum = idxrec->indkey.values[keyno]; @@ -242,12 +228,10 @@ BuildIndexValueDescription(Relation indexRelation, ACL_SELECT) != ACLCHECK_OK) { /* No access, so clean up and return */ - ReleaseSysCache(ht_idx); return NULL; } } } - ReleaseSysCache(ht_idx); initStringInfo(&buf); appendStringInfo(&buf, "(%s)=(", @@ -289,6 +273,43 @@ BuildIndexValueDescription(Relation indexRelation, return buf.data; } +/* + * Get the latestRemovedXid from the table entries pointed at by the index + * tuples being deleted. + */ +TransactionId +index_compute_xid_horizon_for_tuples(Relation irel, + Relation hrel, + Buffer ibuf, + OffsetNumber *itemnos, + int nitems) +{ + ItemPointerData *ttids = + (ItemPointerData *) palloc(sizeof(ItemPointerData) * nitems); + TransactionId latestRemovedXid = InvalidTransactionId; + Page ipage = BufferGetPage(ibuf); + IndexTuple itup; + + /* identify what the index tuples about to be deleted point to */ + for (int i = 0; i < nitems; i++) + { + ItemId iitemid; + + iitemid = PageGetItemId(ipage, itemnos[i]); + itup = (IndexTuple) PageGetItem(ipage, iitemid); + + ItemPointerCopy(&itup->t_tid, &ttids[i]); + } + + /* determine the actual xid horizon */ + latestRemovedXid = + table_compute_xid_horizon_for_tuples(hrel, ttids, nitems); + + pfree(ttids); + + return latestRemovedXid; +} + /* ---------------------------------------------------------------- * heap-or-index-scan access to system catalogs @@ -348,6 +369,7 @@ systable_beginscan(Relation heapRelation, sysscan->heap_rel = heapRelation; sysscan->irel = irel; + sysscan->slot = table_slot_create(heapRelation, NULL); if (snapshot == NULL) { @@ -397,9 +419,9 @@ systable_beginscan(Relation heapRelation, * disadvantage; and there are no compensating advantages, because * it's unlikely that such scans will occur in parallel. */ - sysscan->scan = heap_beginscan_strat(heapRelation, snapshot, - nkeys, key, - true, false); + sysscan->scan = table_beginscan_strat(heapRelation, snapshot, + nkeys, key, + true, false); sysscan->iscan = NULL; } @@ -414,28 +436,46 @@ systable_beginscan(Relation heapRelation, * Note that returned tuple is a reference to data in a disk buffer; * it must not be modified, and should be presumed inaccessible after * next getnext() or endscan() call. + * + * XXX: It'd probably make sense to offer a slot based interface, at least + * optionally. */ HeapTuple systable_getnext(SysScanDesc sysscan) { - HeapTuple htup; + HeapTuple htup = NULL; if (sysscan->irel) { - htup = index_getnext(sysscan->iscan, ForwardScanDirection); + if (index_getnext_slot(sysscan->iscan, ForwardScanDirection, sysscan->slot)) + { + bool shouldFree; - /* - * We currently don't need to support lossy index operators for any - * system catalog scan. It could be done here, using the scan keys to - * drive the operator calls, if we arranged to save the heap attnums - * during systable_beginscan(); this is practical because we still - * wouldn't need to support indexes on expressions. - */ - if (htup && sysscan->iscan->xs_recheck) - elog(ERROR, "system catalog scans with lossy index conditions are not implemented"); + htup = ExecFetchSlotHeapTuple(sysscan->slot, false, &shouldFree); + Assert(!shouldFree); + + /* + * We currently don't need to support lossy index operators for + * any system catalog scan. It could be done here, using the scan + * keys to drive the operator calls, if we arranged to save the + * heap attnums during systable_beginscan(); this is practical + * because we still wouldn't need to support indexes on + * expressions. + */ + if (sysscan->iscan->xs_recheck) + elog(ERROR, "system catalog scans with lossy index conditions are not implemented"); + } } else - htup = heap_getnext(sysscan->scan, ForwardScanDirection); + { + if (table_scan_getnextslot(sysscan->scan, ForwardScanDirection, sysscan->slot)) + { + bool shouldFree; + + htup = ExecFetchSlotHeapTuple(sysscan->slot, false, &shouldFree); + Assert(!shouldFree); + } + } return htup; } @@ -459,37 +499,20 @@ systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup) Snapshot freshsnap; bool result; + Assert(tup == ExecFetchSlotHeapTuple(sysscan->slot, false, NULL)); + /* - * Trust that LockBuffer() and HeapTupleSatisfiesMVCC() do not themselves + * Trust that table_tuple_satisfies_snapshot() and its subsidiaries + * (commonly LockBuffer() and HeapTupleSatisfiesMVCC()) do not themselves * acquire snapshots, so we need not register the snapshot. Those * facilities are too low-level to have any business scanning tables. */ freshsnap = GetCatalogSnapshot(RelationGetRelid(sysscan->heap_rel)); - if (sysscan->irel) - { - IndexScanDesc scan = sysscan->iscan; - - Assert(IsMVCCSnapshot(scan->xs_snapshot)); - Assert(tup == &scan->xs_ctup); - Assert(BufferIsValid(scan->xs_cbuf)); - /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ - LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE); - result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->xs_cbuf); - LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK); - } - else - { - HeapScanDesc scan = sysscan->scan; - - Assert(IsMVCCSnapshot(scan->rs_snapshot)); - Assert(tup == &scan->rs_ctup); - Assert(BufferIsValid(scan->rs_cbuf)); - /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->rs_cbuf); - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - } + result = table_tuple_satisfies_snapshot(sysscan->heap_rel, + sysscan->slot, + freshsnap); + return result; } @@ -501,13 +524,19 @@ systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup) void systable_endscan(SysScanDesc sysscan) { + if (sysscan->slot) + { + ExecDropSingleTupleTableSlot(sysscan->slot); + sysscan->slot = NULL; + } + if (sysscan->irel) { index_endscan(sysscan->iscan); index_close(sysscan->irel, AccessShareLock); } else - heap_endscan(sysscan->scan); + table_endscan(sysscan->scan); if (sysscan->snapshot) UnregisterSnapshot(sysscan->snapshot); @@ -528,8 +557,8 @@ systable_endscan(SysScanDesc sysscan) * we could do a heapscan and sort, but the uses are in places that * probably don't need to still work with corrupted catalog indexes.) * For the moment, therefore, these functions are merely the thinnest of - * wrappers around index_beginscan/index_getnext. The main reason for their - * existence is to centralize possible future support of lossy operators + * wrappers around index_beginscan/index_getnext_slot. The main reason for + * their existence is to centralize possible future support of lossy operators * in catalog scans. */ SysScanDesc @@ -554,6 +583,7 @@ systable_beginscan_ordered(Relation heapRelation, sysscan->heap_rel = heapRelation; sysscan->irel = indexRelation; + sysscan->slot = table_slot_create(heapRelation, NULL); if (snapshot == NULL) { @@ -599,10 +629,12 @@ systable_beginscan_ordered(Relation heapRelation, HeapTuple systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction) { - HeapTuple htup; + HeapTuple htup = NULL; Assert(sysscan->irel); - htup = index_getnext(sysscan->iscan, direction); + if (index_getnext_slot(sysscan->iscan, direction, sysscan->slot)) + htup = ExecFetchSlotHeapTuple(sysscan->slot, false, NULL); + /* See notes in systable_getnext */ if (htup && sysscan->iscan->xs_recheck) elog(ERROR, "system catalog scans with lossy index conditions are not implemented"); @@ -616,6 +648,12 @@ systable_getnext_ordered(SysScanDesc sysscan, ScanDirection direction) void systable_endscan_ordered(SysScanDesc sysscan) { + if (sysscan->slot) + { + ExecDropSingleTupleTableSlot(sysscan->slot); + sysscan->slot = NULL; + } + Assert(sysscan->irel); index_endscan(sysscan->iscan); if (sysscan->snapshot) diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c index 22b5cc921f8..9dfa0ddfbb6 100644 --- a/src/backend/access/index/indexam.c +++ b/src/backend/access/index/indexam.c @@ -3,7 +3,7 @@ * indexam.c * general index access method routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,7 +26,7 @@ * index_beginscan_parallel - join parallel index scan * index_getnext_tid - get the next TID from a scan * index_fetch_heap - get the scan's next heap tuple - * index_getnext - get the next heap tuple from a scan + * index_getnext_slot - get the next tuple from a scan * index_getbitmap - get all tuples from a scan * index_bulk_delete - bulk deletion of index tuples * index_vacuum_cleanup - post-deletion cleanup of an index @@ -38,48 +38,24 @@ * This file contains the index_ routines which used * to be a scattered collection of stuff in access/genam. * - * - * old comments - * Scans are implemented as follows: - * - * `0' represents an invalid item pointer. - * `-' represents an unknown item pointer. - * `X' represents a known item pointers. - * `+' represents known or invalid item pointers. - * `*' represents any item pointers. - * - * State is represented by a triple of these symbols in the order of - * previous, current, next. Note that the case of reverse scans works - * identically. - * - * State Result - * (1) + + - + 0 0 (if the next item pointer is invalid) - * (2) + X - (otherwise) - * (3) * 0 0 * 0 0 (no change) - * (4) + X 0 X 0 0 (shift) - * (5) * + X + X - (shift, add unknown) - * - * All other states cannot occur. - * - * Note: It would be possible to cache the status of the previous and - * next item pointer using the flags. - * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/amapi.h" +#include "access/heapam.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xlog.h" #include "catalog/index.h" +#include "catalog/pg_type.h" #include "pgstat.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/predicate.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" /* ---------------------------------------------------------------- @@ -97,7 +73,7 @@ #define RELATION_CHECKS \ ( \ AssertMacro(RelationIsValid(indexRelation)), \ - AssertMacro(PointerIsValid(indexRelation->rd_amroutine)), \ + AssertMacro(PointerIsValid(indexRelation->rd_indam)), \ AssertMacro(!ReindexIsProcessingIndex(RelationGetRelid(indexRelation))) \ ) @@ -105,26 +81,26 @@ ( \ AssertMacro(IndexScanIsValid(scan)), \ AssertMacro(RelationIsValid(scan->indexRelation)), \ - AssertMacro(PointerIsValid(scan->indexRelation->rd_amroutine)) \ + AssertMacro(PointerIsValid(scan->indexRelation->rd_indam)) \ ) #define CHECK_REL_PROCEDURE(pname) \ do { \ - if (indexRelation->rd_amroutine->pname == NULL) \ + if (indexRelation->rd_indam->pname == NULL) \ elog(ERROR, "function %s is not defined for index %s", \ CppAsString(pname), RelationGetRelationName(indexRelation)); \ } while(0) #define CHECK_SCAN_PROCEDURE(pname) \ do { \ - if (scan->indexRelation->rd_amroutine->pname == NULL) \ + if (scan->indexRelation->rd_indam->pname == NULL) \ elog(ERROR, "function %s is not defined for index %s", \ CppAsString(pname), RelationGetRelationName(scan->indexRelation)); \ } while(0) static IndexScanDesc index_beginscan_internal(Relation indexRelation, - int nkeys, int norderbys, Snapshot snapshot, - ParallelIndexScanDesc pscan, bool temp_snap); + int nkeys, int norderbys, Snapshot snapshot, + ParallelIndexScanDesc pscan, bool temp_snap); /* ---------------------------------------------------------------- @@ -202,14 +178,14 @@ index_insert(Relation indexRelation, RELATION_CHECKS; CHECK_REL_PROCEDURE(aminsert); - if (!(indexRelation->rd_amroutine->ampredlocks)) + if (!(indexRelation->rd_indam->ampredlocks)) CheckForSerializableConflictIn(indexRelation, (HeapTuple) NULL, InvalidBuffer); - return indexRelation->rd_amroutine->aminsert(indexRelation, values, isnull, - heap_t_ctid, heapRelation, - checkUnique, indexInfo); + return indexRelation->rd_indam->aminsert(indexRelation, values, isnull, + heap_t_ctid, heapRelation, + checkUnique, indexInfo); } /* @@ -234,6 +210,9 @@ index_beginscan(Relation heapRelation, scan->heapRelation = heapRelation; scan->xs_snapshot = snapshot; + /* prepare to fetch index matches from table */ + scan->xs_heapfetch = table_index_fetch_begin(heapRelation); + return scan; } @@ -274,7 +253,7 @@ index_beginscan_internal(Relation indexRelation, RELATION_CHECKS; CHECK_REL_PROCEDURE(ambeginscan); - if (!(indexRelation->rd_amroutine->ampredlocks)) + if (!(indexRelation->rd_indam->ampredlocks)) PredicateLockRelation(indexRelation, snapshot); /* @@ -285,8 +264,8 @@ index_beginscan_internal(Relation indexRelation, /* * Tell the AM to open a scan. */ - scan = indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys, - norderbys); + scan = indexRelation->rd_indam->ambeginscan(indexRelation, nkeys, + norderbys); /* Initialize information for parallel scan. */ scan->parallel_scan = pscan; scan->xs_temp_snap = temp_snap; @@ -317,19 +296,15 @@ index_rescan(IndexScanDesc scan, Assert(nkeys == scan->numberOfKeys); Assert(norderbys == scan->numberOfOrderBys); - /* Release any held pin on a heap page */ - if (BufferIsValid(scan->xs_cbuf)) - { - ReleaseBuffer(scan->xs_cbuf); - scan->xs_cbuf = InvalidBuffer; - } - - scan->xs_continue_hot = false; + /* Release resources (like buffer pins) from table accesses */ + if (scan->xs_heapfetch) + table_index_fetch_reset(scan->xs_heapfetch); scan->kill_prior_tuple = false; /* for safety */ + scan->xs_heap_continue = false; - scan->indexRelation->rd_amroutine->amrescan(scan, keys, nkeys, - orderbys, norderbys); + scan->indexRelation->rd_indam->amrescan(scan, keys, nkeys, + orderbys, norderbys); } /* ---------------- @@ -342,15 +317,15 @@ index_endscan(IndexScanDesc scan) SCAN_CHECKS; CHECK_SCAN_PROCEDURE(amendscan); - /* Release any held pin on a heap page */ - if (BufferIsValid(scan->xs_cbuf)) + /* Release resources (like buffer pins) from table accesses */ + if (scan->xs_heapfetch) { - ReleaseBuffer(scan->xs_cbuf); - scan->xs_cbuf = InvalidBuffer; + table_index_fetch_end(scan->xs_heapfetch); + scan->xs_heapfetch = NULL; } /* End the AM's scan */ - scan->indexRelation->rd_amroutine->amendscan(scan); + scan->indexRelation->rd_indam->amendscan(scan); /* Release index refcount acquired by index_beginscan */ RelationDecrementReferenceCount(scan->indexRelation); @@ -372,23 +347,22 @@ index_markpos(IndexScanDesc scan) SCAN_CHECKS; CHECK_SCAN_PROCEDURE(ammarkpos); - scan->indexRelation->rd_amroutine->ammarkpos(scan); + scan->indexRelation->rd_indam->ammarkpos(scan); } /* ---------------- * index_restrpos - restore a scan position * - * NOTE: this only restores the internal scan state of the index AM. - * The current result tuple (scan->xs_ctup) doesn't change. See comments - * for ExecRestrPos(). - * - * NOTE: in the presence of HOT chains, mark/restore only works correctly - * if the scan's snapshot is MVCC-safe; that ensures that there's at most one - * returnable tuple in each HOT chain, and so restoring the prior state at the - * granularity of the index AM is sufficient. Since the only current user - * of mark/restore functionality is nodeMergejoin.c, this effectively means - * that merge-join plans only work for MVCC snapshots. This could be fixed - * if necessary, but for now it seems unimportant. + * NOTE: this only restores the internal scan state of the index AM. See + * comments for ExecRestrPos(). + * + * NOTE: For heap, in the presence of HOT chains, mark/restore only works + * correctly if the scan's snapshot is MVCC-safe; that ensures that there's at + * most one returnable tuple in each HOT chain, and so restoring the prior + * state at the granularity of the index AM is sufficient. Since the only + * current user of mark/restore functionality is nodeMergejoin.c, this + * effectively means that merge-join plans only work for MVCC snapshots. This + * could be fixed if necessary, but for now it seems unimportant. * ---------------- */ void @@ -399,11 +373,14 @@ index_restrpos(IndexScanDesc scan) SCAN_CHECKS; CHECK_SCAN_PROCEDURE(amrestrpos); - scan->xs_continue_hot = false; + /* release resources (like buffer pins) from table accesses */ + if (scan->xs_heapfetch) + table_index_fetch_reset(scan->xs_heapfetch); scan->kill_prior_tuple = false; /* for safety */ + scan->xs_heap_continue = false; - scan->indexRelation->rd_amroutine->amrestrpos(scan); + scan->indexRelation->rd_indam->amrestrpos(scan); } /* @@ -429,9 +406,9 @@ index_parallelscan_estimate(Relation indexRelation, Snapshot snapshot) * AM-specific data needed. (It's hard to believe that could work, but * it's easy enough to cater to it here.) */ - if (indexRelation->rd_amroutine->amestimateparallelscan != NULL) + if (indexRelation->rd_indam->amestimateparallelscan != NULL) nbytes = add_size(nbytes, - indexRelation->rd_amroutine->amestimateparallelscan()); + indexRelation->rd_indam->amestimateparallelscan()); return nbytes; } @@ -464,12 +441,12 @@ index_parallelscan_initialize(Relation heapRelation, Relation indexRelation, SerializeSnapshot(snapshot, target->ps_snapshot_data); /* aminitparallelscan is optional; assume no-op if not provided by AM */ - if (indexRelation->rd_amroutine->aminitparallelscan != NULL) + if (indexRelation->rd_indam->aminitparallelscan != NULL) { void *amtarget; amtarget = OffsetToPointer(target, offset); - indexRelation->rd_amroutine->aminitparallelscan(amtarget); + indexRelation->rd_indam->aminitparallelscan(amtarget); } } @@ -482,9 +459,12 @@ index_parallelrescan(IndexScanDesc scan) { SCAN_CHECKS; + if (scan->xs_heapfetch) + table_index_fetch_reset(scan->xs_heapfetch); + /* amparallelrescan is optional; assume no-op if not provided by AM */ - if (scan->indexRelation->rd_amroutine->amparallelrescan != NULL) - scan->indexRelation->rd_amroutine->amparallelrescan(scan); + if (scan->indexRelation->rd_indam->amparallelrescan != NULL) + scan->indexRelation->rd_indam->amparallelrescan(scan); } /* @@ -512,6 +492,9 @@ index_beginscan_parallel(Relation heaprel, Relation indexrel, int nkeys, scan->heapRelation = heaprel; scan->xs_snapshot = snapshot; + /* prepare to fetch index matches from table */ + scan->xs_heapfetch = table_index_fetch_begin(heaprel); + return scan; } @@ -534,31 +517,31 @@ index_getnext_tid(IndexScanDesc scan, ScanDirection direction) /* * The AM's amgettuple proc finds the next index entry matching the scan - * keys, and puts the TID into scan->xs_ctup.t_self. It should also set + * keys, and puts the TID into scan->xs_heaptid. It should also set * scan->xs_recheck and possibly scan->xs_itup/scan->xs_hitup, though we * pay no attention to those fields here. */ - found = scan->indexRelation->rd_amroutine->amgettuple(scan, direction); + found = scan->indexRelation->rd_indam->amgettuple(scan, direction); /* Reset kill flag immediately for safety */ scan->kill_prior_tuple = false; + scan->xs_heap_continue = false; /* If we're out of index entries, we're done */ if (!found) { - /* ... but first, release any held pin on a heap page */ - if (BufferIsValid(scan->xs_cbuf)) - { - ReleaseBuffer(scan->xs_cbuf); - scan->xs_cbuf = InvalidBuffer; - } + /* release resources (like buffer pins) from table accesses */ + if (scan->xs_heapfetch) + table_index_fetch_reset(scan->xs_heapfetch); + return NULL; } + Assert(ItemPointerIsValid(&scan->xs_heaptid)); pgstat_count_index_tuples(scan->indexRelation, 1); /* Return the TID of the tuple we found. */ - return &scan->xs_ctup.t_self; + return &scan->xs_heaptid; } /* ---------------- @@ -579,53 +562,18 @@ index_getnext_tid(IndexScanDesc scan, ScanDirection direction) * enough information to do it efficiently in the general case. * ---------------- */ -HeapTuple -index_fetch_heap(IndexScanDesc scan) +bool +index_fetch_heap(IndexScanDesc scan, TupleTableSlot *slot) { - ItemPointer tid = &scan->xs_ctup.t_self; bool all_dead = false; - bool got_heap_tuple; - - /* We can skip the buffer-switching logic if we're in mid-HOT chain. */ - if (!scan->xs_continue_hot) - { - /* Switch to correct buffer if we don't have it already */ - Buffer prev_buf = scan->xs_cbuf; - - scan->xs_cbuf = ReleaseAndReadBuffer(scan->xs_cbuf, - scan->heapRelation, - ItemPointerGetBlockNumber(tid)); + bool found; - /* - * Prune page, but only if we weren't already on this page - */ - if (prev_buf != scan->xs_cbuf) - heap_page_prune_opt(scan->heapRelation, scan->xs_cbuf); - } + found = table_index_fetch_tuple(scan->xs_heapfetch, &scan->xs_heaptid, + scan->xs_snapshot, slot, + &scan->xs_heap_continue, &all_dead); - /* Obtain share-lock on the buffer so we can examine visibility */ - LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE); - got_heap_tuple = heap_hot_search_buffer(tid, scan->heapRelation, - scan->xs_cbuf, - scan->xs_snapshot, - &scan->xs_ctup, - &all_dead, - !scan->xs_continue_hot); - LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK); - - if (got_heap_tuple) - { - /* - * Only in a non-MVCC snapshot can more than one member of the HOT - * chain be visible. - */ - scan->xs_continue_hot = !IsMVCCSnapshot(scan->xs_snapshot); + if (found) pgstat_count_heap_fetch(scan->indexRelation); - return &scan->xs_ctup; - } - - /* We've reached the end of the HOT chain. */ - scan->xs_continue_hot = false; /* * If we scanned a whole HOT chain and found only dead tuples, tell index @@ -637,17 +585,17 @@ index_fetch_heap(IndexScanDesc scan) if (!scan->xactStartedInRecovery) scan->kill_prior_tuple = all_dead; - return NULL; + return found; } /* ---------------- - * index_getnext - get the next heap tuple from a scan + * index_getnext_slot - get the next tuple from a scan * - * The result is the next heap tuple satisfying the scan keys and the - * snapshot, or NULL if no more matching tuples exist. + * The result is true if a tuple satisfying the scan keys and the snapshot was + * found, false otherwise. The tuple is stored in the specified slot. * - * On success, the buffer containing the heap tup is pinned (the pin will be - * dropped in a future index_getnext_tid, index_fetch_heap or index_endscan + * On success, resources (like buffer pins) are likely to be held, and will be + * dropped by a future index_getnext_tid, index_fetch_heap or index_endscan * call). * * Note: caller must check scan->xs_recheck, and perform rechecking of the @@ -655,32 +603,23 @@ index_fetch_heap(IndexScanDesc scan) * enough information to do it efficiently in the general case. * ---------------- */ -HeapTuple -index_getnext(IndexScanDesc scan, ScanDirection direction) +bool +index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot) { - HeapTuple heapTuple; - ItemPointer tid; - for (;;) { - if (scan->xs_continue_hot) - { - /* - * We are resuming scan of a HOT chain after having returned an - * earlier member. Must still hold pin on current heap page. - */ - Assert(BufferIsValid(scan->xs_cbuf)); - Assert(ItemPointerGetBlockNumber(&scan->xs_ctup.t_self) == - BufferGetBlockNumber(scan->xs_cbuf)); - } - else + if (!scan->xs_heap_continue) { + ItemPointer tid; + /* Time to fetch the next TID from the index */ tid = index_getnext_tid(scan, direction); /* If we're out of index entries, we're done */ if (tid == NULL) break; + + Assert(ItemPointerEquals(tid, &scan->xs_heaptid)); } /* @@ -688,12 +627,12 @@ index_getnext(IndexScanDesc scan, ScanDirection direction) * If we don't find anything, loop around and grab the next TID from * the index. */ - heapTuple = index_fetch_heap(scan); - if (heapTuple != NULL) - return heapTuple; + Assert(ItemPointerIsValid(&scan->xs_heaptid)); + if (index_fetch_heap(scan, slot)) + return true; } - return NULL; /* failure exit */ + return false; } /* ---------------- @@ -723,7 +662,7 @@ index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap) /* * have the am's getbitmap proc do all the work. */ - ntids = scan->indexRelation->rd_amroutine->amgetbitmap(scan, bitmap); + ntids = scan->indexRelation->rd_indam->amgetbitmap(scan, bitmap); pgstat_count_index_tuples(scan->indexRelation, ntids); @@ -750,8 +689,8 @@ index_bulk_delete(IndexVacuumInfo *info, RELATION_CHECKS; CHECK_REL_PROCEDURE(ambulkdelete); - return indexRelation->rd_amroutine->ambulkdelete(info, stats, - callback, callback_state); + return indexRelation->rd_indam->ambulkdelete(info, stats, + callback, callback_state); } /* ---------------- @@ -769,7 +708,7 @@ index_vacuum_cleanup(IndexVacuumInfo *info, RELATION_CHECKS; CHECK_REL_PROCEDURE(amvacuumcleanup); - return indexRelation->rd_amroutine->amvacuumcleanup(info, stats); + return indexRelation->rd_indam->amvacuumcleanup(info, stats); } /* ---------------- @@ -785,10 +724,10 @@ index_can_return(Relation indexRelation, int attno) RELATION_CHECKS; /* amcanreturn is optional; assume false if not provided by AM */ - if (indexRelation->rd_amroutine->amcanreturn == NULL) + if (indexRelation->rd_indam->amcanreturn == NULL) return false; - return indexRelation->rd_amroutine->amcanreturn(indexRelation, attno); + return indexRelation->rd_indam->amcanreturn(indexRelation, attno); } /* ---------------- @@ -826,7 +765,7 @@ index_getprocid(Relation irel, int nproc; int procindex; - nproc = irel->rd_amroutine->amsupport; + nproc = irel->rd_indam->amsupport; Assert(procnum > 0 && procnum <= (uint16) nproc); @@ -860,7 +799,7 @@ index_getprocinfo(Relation irel, int nproc; int procindex; - nproc = irel->rd_amroutine->amsupport; + nproc = irel->rd_indam->amsupport; Assert(procnum > 0 && procnum <= (uint16) nproc); @@ -897,3 +836,78 @@ index_getprocinfo(Relation irel, return locinfo; } + +/* ---------------- + * index_store_float8_orderby_distances + * + * Convert AM distance function's results (that can be inexact) + * to ORDER BY types and save them into xs_orderbyvals/xs_orderbynulls + * for a possible recheck. + * ---------------- + */ +void +index_store_float8_orderby_distances(IndexScanDesc scan, Oid *orderByTypes, + IndexOrderByDistance *distances, + bool recheckOrderBy) +{ + int i; + + Assert(distances || !recheckOrderBy); + + scan->xs_recheckorderby = recheckOrderBy; + + for (i = 0; i < scan->numberOfOrderBys; i++) + { + if (orderByTypes[i] == FLOAT8OID) + { +#ifndef USE_FLOAT8_BYVAL + /* must free any old value to avoid memory leakage */ + if (!scan->xs_orderbynulls[i]) + pfree(DatumGetPointer(scan->xs_orderbyvals[i])); +#endif + if (distances && !distances[i].isnull) + { + scan->xs_orderbyvals[i] = Float8GetDatum(distances[i].value); + scan->xs_orderbynulls[i] = false; + } + else + { + scan->xs_orderbyvals[i] = (Datum) 0; + scan->xs_orderbynulls[i] = true; + } + } + else if (orderByTypes[i] == FLOAT4OID) + { + /* convert distance function's result to ORDER BY type */ +#ifndef USE_FLOAT4_BYVAL + /* must free any old value to avoid memory leakage */ + if (!scan->xs_orderbynulls[i]) + pfree(DatumGetPointer(scan->xs_orderbyvals[i])); +#endif + if (distances && !distances[i].isnull) + { + scan->xs_orderbyvals[i] = Float4GetDatum((float4) distances[i].value); + scan->xs_orderbynulls[i] = false; + } + else + { + scan->xs_orderbyvals[i] = (Datum) 0; + scan->xs_orderbynulls[i] = true; + } + } + else + { + /* + * If the ordering operator's return value is anything else, we + * don't know how to convert the float8 bound calculated by the + * distance function to that. The executor won't actually need + * the order by values we return here, if there are no lossy + * results, so only insist on converting if the *recheck flag is + * set. + */ + if (scan->xs_recheckorderby) + elog(ERROR, "ORDER BY operator must return float8 or float4 if the distance function is lossy"); + scan->xs_orderbynulls[i] = true; + } + } +} diff --git a/src/backend/access/nbtree/Makefile b/src/backend/access/nbtree/Makefile index bbb21d235c0..9aab9cf64ac 100644 --- a/src/backend/access/nbtree/Makefile +++ b/src/backend/access/nbtree/Makefile @@ -13,6 +13,6 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \ - nbtutils.o nbtsort.o nbtvalidate.o nbtxlog.o + nbtsplitloc.o nbtutils.o nbtsort.o nbtvalidate.o nbtxlog.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/nbtree/README b/src/backend/access/nbtree/README index aef455c122a..6db203e75cf 100644 --- a/src/backend/access/nbtree/README +++ b/src/backend/access/nbtree/README @@ -28,46 +28,44 @@ right-link to find the new page containing the key range you're looking for. This might need to be repeated, if the page has been split more than once. +Lehman and Yao talk about alternating "separator" keys and downlinks in +internal pages rather than tuples or records. We use the term "pivot" +tuple to refer to tuples which don't point to heap tuples, that are used +only for tree navigation. All tuples on non-leaf pages and high keys on +leaf pages are pivot tuples. Since pivot tuples are only used to represent +which part of the key space belongs on each page, they can have attribute +values copied from non-pivot tuples that were deleted and killed by VACUUM +some time ago. A pivot tuple may contain a "separator" key and downlink, +just a separator key (i.e. the downlink value is implicitly undefined), or +just a downlink (i.e. all attributes are truncated away). + +The requirement that all btree keys be unique is satisfied by treating heap +TID as a tiebreaker attribute. Logical duplicates are sorted in heap TID +order. This is necessary because Lehman and Yao also require that the key +range for a subtree S is described by Ki < v <= Ki+1 where Ki and Ki+1 are +the adjacent keys in the parent page (Ki must be _strictly_ less than v, +which is assured by having reliably unique keys). Keys are always unique +on their level, with the exception of a leaf page's high key, which can be +fully equal to the last item on the page. + +The Postgres implementation of suffix truncation must make sure that the +Lehman and Yao invariants hold, and represents that absent/truncated +attributes in pivot tuples have the sentinel value "minus infinity". The +later section on suffix truncation will be helpful if it's unclear how the +Lehman & Yao invariants work with a real world example. + Differences to the Lehman & Yao algorithm ----------------------------------------- We have made the following changes in order to incorporate the L&Y algorithm into Postgres: -The requirement that all btree keys be unique is too onerous, -but the algorithm won't work correctly without it. Fortunately, it is -only necessary that keys be unique on a single tree level, because L&Y -only use the assumption of key uniqueness when re-finding a key in a -parent page (to determine where to insert the key for a split page). -Therefore, we can use the link field to disambiguate multiple -occurrences of the same user key: only one entry in the parent level -will be pointing at the page we had split. (Indeed we need not look at -the real "key" at all, just at the link field.) We can distinguish -items at the leaf level in the same way, by examining their links to -heap tuples; we'd never have two items for the same heap tuple. - -Lehman and Yao assume that the key range for a subtree S is described -by Ki < v <= Ki+1 where Ki and Ki+1 are the adjacent keys in the parent -page. This does not work for nonunique keys (for example, if we have -enough equal keys to spread across several leaf pages, there *must* be -some equal bounding keys in the first level up). Therefore we assume -Ki <= v <= Ki+1 instead. A search that finds exact equality to a -bounding key in an upper tree level must descend to the left of that -key to ensure it finds any equal keys in the preceding page. An -insertion that sees the high key of its target page is equal to the key -to be inserted has a choice whether or not to move right, since the new -key could go on either page. (Currently, we try to find a page where -there is room for the new key without a split.) - Lehman and Yao don't require read locks, but assume that in-memory copies of tree pages are unshared. Postgres shares in-memory buffers among backends. As a result, we do page-level read locking on btree pages in order to guarantee that no record is modified while we are examining it. This reduces concurrency but guarantees correct -behavior. An advantage is that when trading in a read lock for a -write lock, we need not re-read the page after getting the write lock. -Since we're also holding a pin on the shared buffer containing the -page, we know that buffer still contains the page and is up-to-date. +behavior. We support the notion of an ordered "scan" of an index as well as insertions, deletions, and simple lookups. A scan in the forward @@ -138,13 +136,32 @@ since we saw the root. We can identify the correct tree level by means of the level numbers stored in each page. The situation is rare enough that we do not need a more efficient solution.) +Lehman and Yao must couple/chain locks as part of moving right when +relocating a child page's downlink during an ascent of the tree. This is +the only point where Lehman and Yao have to simultaneously hold three +locks (a lock on the child, the original parent, and the original parent's +right sibling). We don't need to couple internal page locks for pages on +the same level, though. We match a child's block number to a downlink +from a pivot tuple one level up, whereas Lehman and Yao match on the +separator key associated with the downlink that was followed during the +initial descent. We can release the lock on the original parent page +before acquiring a lock on its right sibling, since there is never any +need to deal with the case where the separator key that we must relocate +becomes the original parent's high key. Lanin and Shasha don't couple +locks here either, though they also don't couple locks between levels +during ascents. They are willing to "wait and try again" to avoid races. +Their algorithm is optimistic, which means that "an insertion holds no +more than one write lock at a time during its ascent". We more or less +stick with Lehman and Yao's approach of conservatively coupling parent and +child locks when ascending the tree, since it's far simpler. + Lehman and Yao assume fixed-size keys, but we must deal with variable-size keys. Therefore there is not a fixed maximum number of keys per page; we just stuff in as many as will fit. When we split a page, we try to equalize the number of bytes, not items, assigned to -each of the resulting pages. Note we must include the incoming item in -this calculation, otherwise it is possible to find that the incoming -item doesn't fit on the split page where it needs to go! +pages (though suffix truncation is also considered). Note we must include +the incoming item in this calculation, otherwise it is possible to find +that the incoming item doesn't fit on the split page where it needs to go! The Deletion Algorithm ---------------------- @@ -194,9 +211,7 @@ be prepared for the possibility that the item it wants is to the left of the recorded position (but it can't have moved left out of the recorded page). Since we hold a lock on the lower page (per L&Y) until we have re-found the parent item that links to it, we can be assured that the -parent item does still exist and can't have been deleted. Also, because -we are matching downlink page numbers and not data keys, we don't have any -problem with possibly misidentifying the parent item. +parent item does still exist and can't have been deleted. Page Deletion ------------- @@ -228,7 +243,7 @@ it, but it's still linked to its siblings. (Note: Lanin and Shasha prefer to make the key space move left, but their argument for doing so hinges on not having left-links, which we have -anyway. So we simplify the algorithm by moving key space right.) +anyway. So we simplify the algorithm by moving the key space right.) To preserve consistency on the parent level, we cannot merge the key space of a page into its right sibling unless the right sibling is a child of @@ -263,11 +278,15 @@ long as we're keeping the leaf locked. The internal pages in the chain cannot acquire new children afterwards either, because the leaf page is marked as half-dead and won't be split. -Removing the downlink to the top of the to-be-deleted chain effectively -transfers the key space to the right sibling for all the intermediate levels -too, in one atomic operation. A concurrent search might still visit the -intermediate pages, but it will move right when it reaches the half-dead page -at the leaf level. +Removing the downlink to the top of the to-be-deleted subtree/chain +effectively transfers the key space to the right sibling for all the +intermediate levels too, in one atomic operation. A concurrent search might +still visit the intermediate pages, but it will move right when it reaches +the half-dead page at the leaf level. In particular, the search will move to +the subtree to the right of the half-dead leaf page/to-be-deleted subtree, +since the half-dead leaf page's right sibling must be a "cousin" page, not a +"true" sibling page (or a second cousin page when the to-be-deleted chain +starts at leaf page's grandparent page, and so on). In the second stage, the topmost page in the chain is unlinked from its siblings, and the half-dead leaf page is updated to point to the next page @@ -375,6 +394,25 @@ positives, so long as it never gives a false negative. This makes it possible to implement the test with a small counter value stored on each index page. +Fastpath For Index Insertion +---------------------------- + +We optimize for a common case of insertion of increasing index key +values by caching the last page to which this backend inserted the last +value, if this page was the rightmost leaf page. For the next insert, we +can then quickly check if the cached page is still the rightmost leaf +page and also the correct place to hold the current value. We can avoid +the cost of walking down the tree in such common cases. + +The optimization works on the assumption that there can only be one +non-ignorable leaf rightmost page, and so even a RecentGlobalXmin style +interlock isn't required. We cannot fail to detect that our hint was +invalidated, because there can only be one such page in the B-Tree at +any time. It's possible that the page will be deleted and recycled +without a backend's cached page also being detected as invalidated, but +only when we happen to recycle a block that once again gets recycled as the +rightmost leaf page. + On-the-Fly Deletion Of Index Tuples ----------------------------------- @@ -435,7 +473,7 @@ right sibling's left-link --- followed by a second WAL entry for the insertion on the parent level (which might itself be a page split, requiring an additional insertion above that, etc). -For a root split, the followon WAL entry is a "new root" entry rather than +For a root split, the follow-on WAL entry is a "new root" entry rather than an "insertion" entry, but details are otherwise much the same. Because splitting involves multiple atomic actions, it's possible that the @@ -457,7 +495,10 @@ inserting a downlink might require splitting a page, it might fail if you run out of disk space. That would be bad during VACUUM - the reason for running VACUUM in the first place might be that you run out of disk space, and now VACUUM won't finish because you're out of disk space. In contrast, -an insertion can require enlarging the physical file anyway. +an insertion can require enlarging the physical file anyway. There is one +minor exception: VACUUM finishes interrupted splits of internal pages when +deleting their children. This allows the code for re-finding parent items +to be used by both page splits and page deletion. To identify missing downlinks, when a page is split, the left page is flagged to indicate that the split is not yet complete (INCOMPLETE_SPLIT). @@ -576,36 +617,98 @@ scankey point to comparison functions that return boolean, such as int4lt. There might be more than one scankey entry for a given index column, or none at all. (We require the keys to appear in index column order, but the order of multiple keys for a given column is unspecified.) An -insertion scankey uses the same array-of-ScanKey data structure, but the -sk_func pointers point to btree comparison support functions (ie, 3-way -comparators that return int4 values interpreted as <0, =0, >0). In an -insertion scankey there is exactly one entry per index column. Insertion -scankeys are built within the btree code (eg, by _bt_mkscankey()) and are -used to locate the starting point of a scan, as well as for locating the -place to insert a new index tuple. (Note: in the case of an insertion -scankey built from a search scankey, there might be fewer keys than -index columns, indicating that we have no constraints for the remaining -index columns.) After we have located the starting point of a scan, the -original search scankey is consulted as each index entry is sequentially -scanned to decide whether to return the entry and whether the scan can -stop (see _bt_checkkeys()). - -We use term "pivot" index tuples to distinguish tuples which don't point -to heap tuples, but rather used for tree navigation. Pivot tuples includes -all tuples on non-leaf pages and high keys on leaf pages. Note that pivot -index tuples are only used to represent which part of the key space belongs -on each page, and can have attribute values copied from non-pivot tuples -that were deleted and killed by VACUUM some time ago. In principle, we could -truncate away attributes that are not needed for a page high key during a leaf -page split, provided that the remaining attributes distinguish the last index -tuple on the post-split left page as belonging on the left page, and the first -index tuple on the post-split right page as belonging on the right page. This -optimization is sometimes called suffix truncation, and may appear in a future -release. Since the high key is subsequently reused as the downlink in the -parent page for the new right page, suffix truncation can increase index -fan-out considerably by keeping pivot tuples short. INCLUDE indexes similarly -truncate away non-key attributes at the time of a leaf page split, -increasing fan-out. +insertion scankey ("BTScanInsert" data structure) uses a similar +array-of-ScanKey data structure, but the sk_func pointers point to btree +comparison support functions (ie, 3-way comparators that return int4 values +interpreted as <0, =0, >0). In an insertion scankey there is at most one +entry per index column. There is also other data about the rules used to +locate where to begin the scan, such as whether or not the scan is a +"nextkey" scan. Insertion scankeys are built within the btree code (eg, by +_bt_mkscankey()) and are used to locate the starting point of a scan, as +well as for locating the place to insert a new index tuple. (Note: in the +case of an insertion scankey built from a search scankey or built from a +truncated pivot tuple, there might be fewer keys than index columns, +indicating that we have no constraints for the remaining index columns.) +After we have located the starting point of a scan, the original search +scankey is consulted as each index entry is sequentially scanned to decide +whether to return the entry and whether the scan can stop (see +_bt_checkkeys()). + +Notes about suffix truncation +----------------------------- + +We truncate away suffix key attributes that are not needed for a page high +key during a leaf page split. The remaining attributes must distinguish +the last index tuple on the post-split left page as belonging on the left +page, and the first index tuple on the post-split right page as belonging +on the right page. Tuples logically retain truncated key attributes, +though they implicitly have "negative infinity" as their value, and have no +storage overhead. Since the high key is subsequently reused as the +downlink in the parent page for the new right page, suffix truncation makes +pivot tuples short. INCLUDE indexes are guaranteed to have non-key +attributes truncated at the time of a leaf page split, but may also have +some key attributes truncated away, based on the usual criteria for key +attributes. They are not a special case, since non-key attributes are +merely payload to B-Tree searches. + +The goal of suffix truncation of key attributes is to improve index +fan-out. The technique was first described by Bayer and Unterauer (R.Bayer +and K.Unterauer, Prefix B-Trees, ACM Transactions on Database Systems, Vol +2, No. 1, March 1977, pp 11-26). The Postgres implementation is loosely +based on their paper. Note that Postgres only implements what the paper +refers to as simple prefix B-Trees. Note also that the paper assumes that +the tree has keys that consist of single strings that maintain the "prefix +property", much like strings that are stored in a suffix tree (comparisons +of earlier bytes must always be more significant than comparisons of later +bytes, and, in general, the strings must compare in a way that doesn't +break transitive consistency as they're split into pieces). Suffix +truncation in Postgres currently only works at the whole-attribute +granularity, but it would be straightforward to invent opclass +infrastructure that manufactures a smaller attribute value in the case of +variable-length types, such as text. An opclass support function could +manufacture the shortest possible key value that still correctly separates +each half of a leaf page split. + +There is sophisticated criteria for choosing a leaf page split point. The +general idea is to make suffix truncation effective without unduly +influencing the balance of space for each half of the page split. The +choice of leaf split point can be thought of as a choice among points +*between* items on the page to be split, at least if you pretend that the +incoming tuple was placed on the page already (you have to pretend because +there won't actually be enough space for it on the page). Choosing the +split point between two index tuples where the first non-equal attribute +appears as early as possible results in truncating away as many suffix +attributes as possible. Evenly balancing space among each half of the +split is usually the first concern, but even small adjustments in the +precise split point can allow truncation to be far more effective. + +Suffix truncation is primarily valuable because it makes pivot tuples +smaller, which delays splits of internal pages, but that isn't the only +reason why it's effective. Even truncation that doesn't make pivot tuples +smaller due to alignment still prevents pivot tuples from being more +restrictive than truly necessary in how they describe which values belong +on which pages. + +While it's not possible to correctly perform suffix truncation during +internal page splits, it's still useful to be discriminating when splitting +an internal page. The split point that implies a downlink be inserted in +the parent that's the smallest one available within an acceptable range of +the fillfactor-wise optimal split point is chosen. This idea also comes +from the Prefix B-Tree paper. This process has much in common with what +happens at the leaf level to make suffix truncation effective. The overall +effect is that suffix truncation tends to produce smaller, more +discriminating pivot tuples, especially early in the lifetime of the index, +while biasing internal page splits makes the earlier, smaller pivot tuples +end up in the root page, delaying root page splits. + +Logical duplicates are given special consideration. The logic for +selecting a split point goes to great lengths to avoid having duplicates +span more than one page, and almost always manages to pick a split point +between two user-key-distinct tuples, accepting a completely lopsided split +if it must. When a page that's already full of duplicates must be split, +the fallback strategy assumes that duplicates are mostly inserted in +ascending heap TID order. The page is split in a way that leaves the left +half of the page mostly full, and the right half of the page mostly empty. Notes About Data Representation ------------------------------- @@ -618,20 +721,26 @@ don't need to renumber any existing pages when splitting the root.) The Postgres disk block data format (an array of items) doesn't fit Lehman and Yao's alternating-keys-and-pointers notion of a disk page, -so we have to play some games. +so we have to play some games. (The alternating-keys-and-pointers +notion is important for internal page splits, which conceptually split +at the middle of an existing pivot tuple -- the tuple's "separator" key +goes on the left side of the split as the left side's new high key, +while the tuple's pointer/downlink goes on the right side as the +first/minus infinity downlink.) On a page that is not rightmost in its tree level, the "high key" is kept in the page's first item, and real data items start at item 2. The link portion of the "high key" item goes unused. A page that is -rightmost has no "high key", so data items start with the first item. -Putting the high key at the left, rather than the right, may seem odd, -but it avoids moving the high key as we add data items. +rightmost has no "high key" (it's implicitly positive infinity), so +data items start with the first item. Putting the high key at the +left, rather than the right, may seem odd, but it avoids moving the +high key as we add data items. On a leaf page, the data items are simply links to (TIDs of) tuples in the relation being indexed, with the associated key values. On a non-leaf page, the data items are down-links to child pages with -bounding keys. The key in each data item is the *lower* bound for +bounding keys. The key in each data item is a strict lower bound for keys on that child page, so logically the key is to the left of that downlink. The high key (if present) is the upper bound for the last downlink. The first data item on each such page has no lower bound @@ -639,4 +748,5 @@ downlink. The first data item on each such page has no lower bound routines must treat it accordingly. The actual key stored in the item is irrelevant, and need not be stored at all. This arrangement corresponds to the fact that an L&Y non-leaf page has one more pointer -than key. +than key. Suffix truncation's negative infinity attributes behave in +the same way. diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c index b1855e8aa80..cdd7d48c5c2 100644 --- a/src/backend/access/nbtree/nbtcompare.c +++ b/src/backend/access/nbtree/nbtcompare.c @@ -3,7 +3,7 @@ * nbtcompare.c * Comparison functions for btree access method. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,11 +22,10 @@ * * The result is always an int32 regardless of the input datatype. * - * Although any negative int32 (except INT_MIN) is acceptable for reporting - * "<", and any positive int32 is acceptable for reporting ">", routines + * Although any negative int32 is acceptable for reporting "<", + * and any positive int32 is acceptable for reporting ">", routines * that work on 32-bit or wider datatypes can't just return "a - b". - * That could overflow and give the wrong answer. Also, one must not - * return INT_MIN to report "<", since some callers will negate the result. + * That could overflow and give the wrong answer. * * NOTE: it is critical that the comparison function impose a total order * on all non-NULL values of the data type, and that the datatype's @@ -44,13 +43,31 @@ * during an index access won't be recovered till end of query. This * primarily affects comparison routines for toastable datatypes; * they have to be careful to free any detoasted copy of an input datum. + * + * NOTE: we used to forbid comparison functions from returning INT_MIN, + * but that proves to be too error-prone because some platforms' versions + * of memcmp() etc can return INT_MIN. As a means of stress-testing + * callers, this file can be compiled with STRESS_SORT_INT_MIN defined + * to cause many of these functions to return INT_MIN or INT_MAX instead of + * their customary -1/+1. For production, though, that's not a good idea + * since users or third-party code might expect the traditional results. *------------------------------------------------------------------------- */ #include "postgres.h" +#include + #include "utils/builtins.h" #include "utils/sortsupport.h" +#ifdef STRESS_SORT_INT_MIN +#define A_LESS_THAN_B INT_MIN +#define A_GREATER_THAN_B INT_MAX +#else +#define A_LESS_THAN_B (-1) +#define A_GREATER_THAN_B 1 +#endif + Datum btboolcmp(PG_FUNCTION_ARGS) @@ -95,11 +112,11 @@ btint4cmp(PG_FUNCTION_ARGS) int32 b = PG_GETARG_INT32(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } static int @@ -109,11 +126,11 @@ btint4fastcmp(Datum x, Datum y, SortSupport ssup) int32 b = DatumGetInt32(y); if (a > b) - return 1; + return A_GREATER_THAN_B; else if (a == b) return 0; else - return -1; + return A_LESS_THAN_B; } Datum @@ -132,11 +149,11 @@ btint8cmp(PG_FUNCTION_ARGS) int64 b = PG_GETARG_INT64(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } static int @@ -146,11 +163,11 @@ btint8fastcmp(Datum x, Datum y, SortSupport ssup) int64 b = DatumGetInt64(y); if (a > b) - return 1; + return A_GREATER_THAN_B; else if (a == b) return 0; else - return -1; + return A_LESS_THAN_B; } Datum @@ -169,11 +186,11 @@ btint48cmp(PG_FUNCTION_ARGS) int64 b = PG_GETARG_INT64(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -183,11 +200,11 @@ btint84cmp(PG_FUNCTION_ARGS) int32 b = PG_GETARG_INT32(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -197,11 +214,11 @@ btint24cmp(PG_FUNCTION_ARGS) int32 b = PG_GETARG_INT32(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -211,11 +228,11 @@ btint42cmp(PG_FUNCTION_ARGS) int16 b = PG_GETARG_INT16(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -225,11 +242,11 @@ btint28cmp(PG_FUNCTION_ARGS) int64 b = PG_GETARG_INT64(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -239,11 +256,11 @@ btint82cmp(PG_FUNCTION_ARGS) int16 b = PG_GETARG_INT16(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } Datum @@ -253,11 +270,11 @@ btoidcmp(PG_FUNCTION_ARGS) Oid b = PG_GETARG_OID(1); if (a > b) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else if (a == b) PG_RETURN_INT32(0); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } static int @@ -267,11 +284,11 @@ btoidfastcmp(Datum x, Datum y, SortSupport ssup) Oid b = DatumGetObjectId(y); if (a > b) - return 1; + return A_GREATER_THAN_B; else if (a == b) return 0; else - return -1; + return A_LESS_THAN_B; } Datum @@ -299,9 +316,9 @@ btoidvectorcmp(PG_FUNCTION_ARGS) if (a->values[i] != b->values[i]) { if (a->values[i] > b->values[i]) - PG_RETURN_INT32(1); + PG_RETURN_INT32(A_GREATER_THAN_B); else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(A_LESS_THAN_B); } } PG_RETURN_INT32(0); @@ -316,30 +333,3 @@ btcharcmp(PG_FUNCTION_ARGS) /* Be careful to compare chars as unsigned */ PG_RETURN_INT32((int32) ((uint8) a) - (int32) ((uint8) b)); } - -Datum -btnamecmp(PG_FUNCTION_ARGS) -{ - Name a = PG_GETARG_NAME(0); - Name b = PG_GETARG_NAME(1); - - PG_RETURN_INT32(strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN)); -} - -static int -btnamefastcmp(Datum x, Datum y, SortSupport ssup) -{ - Name a = DatumGetName(x); - Name b = DatumGetName(y); - - return strncmp(NameStr(*a), NameStr(*b), NAMEDATALEN); -} - -Datum -btnamesortsupport(PG_FUNCTION_ARGS) -{ - SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); - - ssup->comparator = btnamefastcmp; - PG_RETURN_VOID(); -} diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 0b93acd0244..b84bf1c3dfa 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -3,7 +3,7 @@ * nbtinsert.c * Item insertion in Lehman and Yao btrees for Postgres. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,75 +15,46 @@ #include "postgres.h" -#include "access/heapam.h" #include "access/nbtree.h" #include "access/nbtxlog.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xloginsert.h" #include "miscadmin.h" #include "storage/lmgr.h" #include "storage/predicate.h" #include "storage/smgr.h" -#include "utils/tqual.h" - -typedef struct -{ - /* context data for _bt_checksplitloc */ - Size newitemsz; /* size of new item to be inserted */ - int fillfactor; /* needed when splitting rightmost page */ - bool is_leaf; /* T if splitting a leaf page */ - bool is_rightmost; /* T if splitting a rightmost page */ - OffsetNumber newitemoff; /* where the new item is to be inserted */ - int leftspace; /* space available for items on left page */ - int rightspace; /* space available for items on right page */ - int olddataitemstotal; /* space taken by old items */ - - bool have_split; /* found a valid split? */ - - /* these fields valid only if have_split is true */ - bool newitemonleft; /* new item on left or right of best split */ - OffsetNumber firstright; /* best split point */ - int best_delta; /* best size delta so far */ -} FindSplitData; +/* Minimum tree height for application of fastpath optimization */ +#define BTREE_FASTPATH_MIN_LEVEL 2 static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf); -static TransactionId _bt_check_unique(Relation rel, IndexTuple itup, - Relation heapRel, Buffer buf, OffsetNumber offset, - ScanKey itup_scankey, - IndexUniqueCheck checkUnique, bool *is_unique, - uint32 *speculativeToken); -static void _bt_findinsertloc(Relation rel, - Buffer *bufptr, - OffsetNumber *offsetptr, - int keysz, - ScanKey scankey, - IndexTuple newtup, - BTStack stack, - Relation heapRel); -static void _bt_insertonpg(Relation rel, Buffer buf, Buffer cbuf, - BTStack stack, - IndexTuple itup, - OffsetNumber newitemoff, - bool split_only_page); -static Buffer _bt_split(Relation rel, Buffer buf, Buffer cbuf, - OffsetNumber firstright, OffsetNumber newitemoff, Size newitemsz, - IndexTuple newitem, bool newitemonleft); +static TransactionId _bt_check_unique(Relation rel, BTInsertState insertstate, + Relation heapRel, + IndexUniqueCheck checkUnique, bool *is_unique, + uint32 *speculativeToken); +static OffsetNumber _bt_findinsertloc(Relation rel, + BTInsertState insertstate, + bool checkingunique, + BTStack stack, + Relation heapRel); +static void _bt_stepright(Relation rel, BTInsertState insertstate, BTStack stack); +static void _bt_insertonpg(Relation rel, BTScanInsert itup_key, + Buffer buf, + Buffer cbuf, + BTStack stack, + IndexTuple itup, + OffsetNumber newitemoff, + bool split_only_page); +static Buffer _bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, + Buffer cbuf, OffsetNumber newitemoff, Size newitemsz, + IndexTuple newitem); static void _bt_insert_parent(Relation rel, Buffer buf, Buffer rbuf, - BTStack stack, bool is_root, bool is_only); -static OffsetNumber _bt_findsplitloc(Relation rel, Page page, - OffsetNumber newitemoff, - Size newitemsz, - bool *newitemonleft); -static void _bt_checksplitloc(FindSplitData *state, - OffsetNumber firstoldonright, bool newitemonleft, - int dataitemstoleft, Size firstoldonrightsz); + BTStack stack, bool is_root, bool is_only); static bool _bt_pgaddtup(Page page, Size itemsize, IndexTuple itup, - OffsetNumber itup_off); -static bool _bt_isequal(Relation idxrel, Page page, OffsetNumber offnum, - int keysz, ScanKey scankey); + OffsetNumber itup_off); static void _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel); /* @@ -109,52 +80,83 @@ _bt_doinsert(Relation rel, IndexTuple itup, IndexUniqueCheck checkUnique, Relation heapRel) { bool is_unique = false; - int indnkeyatts; - ScanKey itup_scankey; + BTInsertStateData insertstate; + BTScanInsert itup_key; BTStack stack = NULL; Buffer buf; - OffsetNumber offset; bool fastpath; - - indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); - Assert(indnkeyatts != 0); + bool checkingunique = (checkUnique != UNIQUE_CHECK_NO); /* we need an insertion scan key to do our search, so build one */ - itup_scankey = _bt_mkscankey(rel, itup); + itup_key = _bt_mkscankey(rel, itup); + + if (checkingunique) + { + if (!itup_key->anynullkeys) + { + /* No (heapkeyspace) scantid until uniqueness established */ + itup_key->scantid = NULL; + } + else + { + /* + * Scan key for new tuple contains NULL key values. Bypass + * checkingunique steps. They are unnecessary because core code + * considers NULL unequal to every value, including NULL. + * + * This optimization avoids O(N^2) behavior within the + * _bt_findinsertloc() heapkeyspace path when a unique index has a + * large number of "duplicates" with NULL key values. + */ + checkingunique = false; + /* Tuple is unique in the sense that core code cares about */ + Assert(checkUnique != UNIQUE_CHECK_EXISTING); + is_unique = true; + } + } + + /* + * Fill in the BTInsertState working area, to track the current page and + * position within the page to insert on + */ + insertstate.itup = itup; + /* PageAddItem will MAXALIGN(), but be consistent */ + insertstate.itemsz = MAXALIGN(IndexTupleSize(itup)); + insertstate.itup_key = itup_key; + insertstate.bounds_valid = false; + insertstate.buf = InvalidBuffer; /* * It's very common to have an index on an auto-incremented or * monotonically increasing value. In such cases, every insertion happens - * towards the end of the index. We try to optimise that case by caching + * towards the end of the index. We try to optimize that case by caching * the right-most leaf of the index. If our cached block is still the * rightmost leaf, has enough free space to accommodate a new entry and * the insertion key is strictly greater than the first key in this page, * then we can safely conclude that the new key will be inserted in the - * cached block. So we simply search within the cached block and insert the - * key at the appropriate location. We call it a fastpath. + * cached block. So we simply search within the cached block and insert + * the key at the appropriate location. We call it a fastpath. * * Testing has revealed, though, that the fastpath can result in increased * contention on the exclusive-lock on the rightmost leaf page. So we - * conditionally check if the lock is available. If it's not available then - * we simply abandon the fastpath and take the regular path. This makes - * sense because unavailability of the lock also signals that some other - * backend might be concurrently inserting into the page, thus reducing our - * chances to finding an insertion place in this page. + * conditionally check if the lock is available. If it's not available + * then we simply abandon the fastpath and take the regular path. This + * makes sense because unavailability of the lock also signals that some + * other backend might be concurrently inserting into the page, thus + * reducing our chances to finding an insertion place in this page. */ top: fastpath = false; - offset = InvalidOffsetNumber; if (RelationGetTargetBlock(rel) != InvalidBlockNumber) { - Size itemsz; - Page page; - BTPageOpaque lpageop; + Page page; + BTPageOpaque lpageop; /* * Conditionally acquire exclusive lock on the buffer before doing any * checks. If we don't get the lock, we simply follow slowpath. If we - * do get the lock, this ensures that the index state cannot change, as - * far as the rightmost part of the index is concerned. + * do get the lock, this ensures that the index state cannot change, + * as far as the rightmost part of the index is concerned. */ buf = ReadBuffer(rel, RelationGetTargetBlock(rel)); @@ -165,24 +167,23 @@ _bt_doinsert(Relation rel, IndexTuple itup, page = BufferGetPage(buf); lpageop = (BTPageOpaque) PageGetSpecialPointer(page); - itemsz = IndexTupleSize(itup); - itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do this - * but we need to be consistent */ /* * Check if the page is still the rightmost leaf page, has enough - * free space to accommodate the new tuple, no split is in - * progress, and the insertion scan key is strictly greater than - * the first key on the page. + * free space to accommodate the new tuple, and the insertion scan + * key is strictly greater than the first key on the page. */ if (P_ISLEAF(lpageop) && P_RIGHTMOST(lpageop) && - !P_INCOMPLETE_SPLIT(lpageop) && !P_IGNORE(lpageop) && - (PageGetFreeSpace(page) > itemsz) && + (PageGetFreeSpace(page) > insertstate.itemsz) && PageGetMaxOffsetNumber(page) >= P_FIRSTDATAKEY(lpageop) && - _bt_compare(rel, indnkeyatts, itup_scankey, page, - P_FIRSTDATAKEY(lpageop)) > 0) + _bt_compare(rel, itup_key, page, P_FIRSTDATAKEY(lpageop)) > 0) { + /* + * The right-most block should never have an incomplete split. + * But be paranoid and check for it anyway. + */ + Assert(!P_INCOMPLETE_SPLIT(lpageop)); fastpath = true; } else @@ -202,8 +203,8 @@ _bt_doinsert(Relation rel, IndexTuple itup, ReleaseBuffer(buf); /* - * If someone's holding a lock, it's likely to change anyway, - * so don't try again until we get an updated rightmost leaf. + * If someone's holding a lock, it's likely to change anyway, so + * don't try again until we get an updated rightmost leaf. */ RelationSetTargetBlock(rel, InvalidBlockNumber); } @@ -211,25 +212,16 @@ _bt_doinsert(Relation rel, IndexTuple itup, if (!fastpath) { - /* find the first page containing this key */ - stack = _bt_search(rel, indnkeyatts, itup_scankey, false, &buf, BT_WRITE, - NULL); - - /* trade in our read lock for a write lock */ - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - LockBuffer(buf, BT_WRITE); - /* - * If the page was split between the time that we surrendered our read - * lock and acquired our write lock, then this page may no longer be - * the right place for the key we want to insert. In this case, we - * need to move right in the tree. See Lehman and Yao for an - * excruciatingly precise description. + * Find the first page containing this key. Buffer returned by + * _bt_search() is locked in exclusive mode. */ - buf = _bt_moveright(rel, buf, indnkeyatts, itup_scankey, false, - true, stack, BT_WRITE, NULL); + stack = _bt_search(rel, itup_key, &buf, BT_WRITE, NULL); } + insertstate.buf = buf; + buf = InvalidBuffer; /* insertstate.buf now owns the buffer */ + /* * If we're not allowing duplicates, make sure the key isn't already in * the index. @@ -237,12 +229,13 @@ _bt_doinsert(Relation rel, IndexTuple itup, * NOTE: obviously, _bt_check_unique can only detect keys that are already * in the index; so it cannot defend against concurrent insertions of the * same key. We protect against that by means of holding a write lock on - * the target page. Any other would-be inserter of the same key must - * acquire a write lock on the same target page, so only one would-be - * inserter can be making the check at one time. Furthermore, once we are - * past the check we hold write locks continuously until we have performed - * our insertion, so no later inserter can fail to see our insertion. - * (This requires some care in _bt_insertonpg.) + * the first page the value could be on, with omitted/-inf value for the + * implicit heap TID tiebreaker attribute. Any other would-be inserter of + * the same key must acquire a write lock on the same page, so only one + * would-be inserter can be making the check at one time. Furthermore, + * once we are past the check we hold write locks continuously until we + * have performed our insertion, so no later inserter can fail to see our + * insertion. (This requires some care in _bt_findinsertloc.) * * If we must wait for another xact, we release the lock while waiting, * and then must start over completely. @@ -251,19 +244,19 @@ _bt_doinsert(Relation rel, IndexTuple itup, * let the tuple in and return false for possibly non-unique, or true for * definitely unique. */ - if (checkUnique != UNIQUE_CHECK_NO) + if (checkingunique) { TransactionId xwait; uint32 speculativeToken; - offset = _bt_binsrch(rel, buf, indnkeyatts, itup_scankey, false); - xwait = _bt_check_unique(rel, itup, heapRel, buf, offset, itup_scankey, - checkUnique, &is_unique, &speculativeToken); + xwait = _bt_check_unique(rel, &insertstate, heapRel, checkUnique, + &is_unique, &speculativeToken); if (TransactionIdIsValid(xwait)) { /* Have to wait for the other guy ... */ - _bt_relbuf(rel, buf); + _bt_relbuf(rel, insertstate.buf); + insertstate.buf = InvalidBuffer; /* * If it's a speculative insertion, wait for it to finish (ie. to @@ -280,35 +273,45 @@ _bt_doinsert(Relation rel, IndexTuple itup, _bt_freestack(stack); goto top; } + + /* Uniqueness is established -- restore heap tid as scantid */ + if (itup_key->heapkeyspace) + itup_key->scantid = &itup->t_tid; } if (checkUnique != UNIQUE_CHECK_EXISTING) { + OffsetNumber newitemoff; + /* * The only conflict predicate locking cares about for indexes is when - * an index tuple insert conflicts with an existing lock. Since the - * actual location of the insert is hard to predict because of the - * random search used to prevent O(N^2) performance when there are - * many duplicate entries, we can just use the "first valid" page. - * This reasoning also applies to INCLUDE indexes, whose extra - * attributes are not considered part of the key space. + * an index tuple insert conflicts with an existing lock. We don't + * know the actual page we're going to insert on for sure just yet in + * checkingunique and !heapkeyspace cases, but it's okay to use the + * first page the value could be on (with scantid omitted) instead. + */ + CheckForSerializableConflictIn(rel, NULL, insertstate.buf); + + /* + * Do the insertion. Note that insertstate contains cached binary + * search bounds established within _bt_check_unique when insertion is + * checkingunique. */ - CheckForSerializableConflictIn(rel, NULL, buf); - /* do the insertion */ - _bt_findinsertloc(rel, &buf, &offset, indnkeyatts, itup_scankey, itup, - stack, heapRel); - _bt_insertonpg(rel, buf, InvalidBuffer, stack, itup, offset, false); + newitemoff = _bt_findinsertloc(rel, &insertstate, checkingunique, + stack, heapRel); + _bt_insertonpg(rel, itup_key, insertstate.buf, InvalidBuffer, stack, + itup, newitemoff, false); } else { /* just release the buffer */ - _bt_relbuf(rel, buf); + _bt_relbuf(rel, insertstate.buf); } /* be tidy */ if (stack) _bt_freestack(stack); - _bt_freeskey(itup_scankey); + pfree(itup_key); return is_unique; } @@ -316,10 +319,6 @@ _bt_doinsert(Relation rel, IndexTuple itup, /* * _bt_check_unique() -- Check for violation of unique index constraint * - * offset points to the first possible item that could conflict. It can - * also point to end-of-page, which means that the first tuple to check - * is the first tuple on the next page. - * * Returns InvalidTransactionId if there is no conflict, else an xact ID * we must wait for to see if it commits a conflicting tuple. If an actual * conflict is detected, no return --- just ereport(). If an xact ID is @@ -331,15 +330,24 @@ _bt_doinsert(Relation rel, IndexTuple itup, * InvalidTransactionId because we don't want to wait. In this case we * set *is_unique to false if there is a potential conflict, and the * core code must redo the uniqueness check later. + * + * As a side-effect, sets state in insertstate that can later be used by + * _bt_findinsertloc() to reuse most of the binary search work we do + * here. + * + * Do not call here when there are NULL values in scan key. NULL should be + * considered unequal to NULL when checking for duplicates, but we are not + * prepared to handle that correctly. */ static TransactionId -_bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, - Buffer buf, OffsetNumber offset, ScanKey itup_scankey, +_bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel, IndexUniqueCheck checkUnique, bool *is_unique, uint32 *speculativeToken) { - int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); + IndexTuple itup = insertstate->itup; + BTScanInsert itup_key = insertstate->itup_key; SnapshotData SnapshotDirty; + OffsetNumber offset; OffsetNumber maxoff; Page page; BTPageOpaque opaque; @@ -351,13 +359,25 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, InitDirtySnapshot(SnapshotDirty); - page = BufferGetPage(buf); + page = BufferGetPage(insertstate->buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); maxoff = PageGetMaxOffsetNumber(page); + /* + * Find the first tuple with the same key. + * + * This also saves the binary search bounds in insertstate. We use them + * in the fastpath below, but also in the _bt_findinsertloc() call later. + */ + Assert(!insertstate->bounds_valid); + offset = _bt_binsrch_insert(rel, insertstate); + /* * Scan over all equal tuples, looking for live conflicts. */ + Assert(!insertstate->bounds_valid || insertstate->low == offset); + Assert(!itup_key->anynullkeys); + Assert(itup_key->scantid == NULL); for (;;) { ItemId curitemid; @@ -370,34 +390,47 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, */ if (offset <= maxoff) { + /* + * Fastpath: In most cases, we can use cached search bounds to + * limit our consideration to items that are definitely + * duplicates. This fastpath doesn't apply when the original page + * is empty, or when initial offset is past the end of the + * original page, which may indicate that we need to examine a + * second or subsequent page. + * + * Note that this optimization allows us to avoid calling + * _bt_compare() directly when there are no duplicates, as long as + * the offset where the key will go is not at the end of the page. + */ + if (nbuf == InvalidBuffer && offset == insertstate->stricthigh) + { + Assert(insertstate->bounds_valid); + Assert(insertstate->low >= P_FIRSTDATAKEY(opaque)); + Assert(insertstate->low <= insertstate->stricthigh); + Assert(_bt_compare(rel, itup_key, page, offset) < 0); + break; + } + curitemid = PageGetItemId(page, offset); /* * We can skip items that are marked killed. * - * Formerly, we applied _bt_isequal() before checking the kill - * flag, so as to fall out of the item loop as soon as possible. - * However, in the presence of heavy update activity an index may - * contain many killed items with the same key; running - * _bt_isequal() on each killed item gets expensive. Furthermore - * it is likely that the non-killed version of each key appears - * first, so that we didn't actually get to exit any sooner - * anyway. So now we just advance over killed items as quickly as - * we can. We only apply _bt_isequal() when we get to a non-killed - * item or the end of the page. + * In the presence of heavy update activity an index may contain + * many killed items with the same key; running _bt_compare() on + * each killed item gets expensive. Just advance over killed + * items as quickly as we can. We only apply _bt_compare() when + * we get to a non-killed item. Even those comparisons could be + * avoided (in the common case where there is only one page to + * visit) by reusing bounds, but just skipping dead items is fast + * enough. */ if (!ItemIdIsDead(curitemid)) { ItemPointerData htid; bool all_dead; - /* - * _bt_compare returns 0 for (1,NULL) and (1,NULL) - this's - * how we handling NULLs - and so we must not use _bt_compare - * in real comparison, but only for ordering/finding items on - * pages. - vadim 03/24/97 - */ - if (!_bt_isequal(rel, page, offset, indnkeyatts, itup_scankey)) + if (_bt_compare(rel, itup_key, page, offset) != 0) break; /* we're past all the equal tuples */ /* okay, we gotta fetch the heap tuple ... */ @@ -416,12 +449,14 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, } /* - * We check the whole HOT-chain to see if there is any tuple - * that satisfies SnapshotDirty. This is necessary because we - * have just a single index entry for the entire chain. + * Check if there's any table tuples for this index entry + * satisfying SnapshotDirty. This is necessary because for AMs + * with optimizations like heap's HOT, we have just a single + * index entry for the entire chain. */ - else if (heap_hot_search(&htid, heapRel, &SnapshotDirty, - &all_dead)) + else if (table_index_fetch_tuple_check(heapRel, &htid, + &SnapshotDirty, + &all_dead)) { TransactionId xwait; @@ -430,7 +465,8 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * check, then don't bother checking if the tuple is being * updated in another transaction. Just return the fact * that it is a potential conflict and leave the full - * check till later. + * check till later. Don't invalidate binary search + * bounds. */ if (checkUnique == UNIQUE_CHECK_PARTIAL) { @@ -453,6 +489,8 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, _bt_relbuf(rel, nbuf); /* Tell _bt_doinsert to wait... */ *speculativeToken = SnapshotDirty.speculativeToken; + /* Caller releases lock on buf immediately */ + insertstate->bounds_valid = false; return xwait; } @@ -474,7 +512,8 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * entry. */ htid = itup->t_tid; - if (heap_hot_search(&htid, heapRel, SnapshotSelf, NULL)) + if (table_index_fetch_tuple_check(heapRel, &htid, + SnapshotSelf, NULL)) { /* Normal case --- it's still live */ } @@ -494,7 +533,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * otherwise be masked by this unique constraint * violation. */ - CheckForSerializableConflictIn(rel, NULL, buf); + CheckForSerializableConflictIn(rel, NULL, insertstate->buf); /* * This is a definite conflict. Break the tuple down into @@ -506,7 +545,9 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, */ if (nbuf != InvalidBuffer) _bt_relbuf(rel, nbuf); - _bt_relbuf(rel, buf); + _bt_relbuf(rel, insertstate->buf); + insertstate->buf = InvalidBuffer; + insertstate->bounds_valid = false; { Datum values[INDEX_MAX_KEYS]; @@ -546,7 +587,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, if (nbuf != InvalidBuffer) MarkBufferDirtyHint(nbuf, true); else - MarkBufferDirtyHint(buf, true); + MarkBufferDirtyHint(insertstate->buf, true); } } } @@ -558,11 +599,14 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, offset = OffsetNumberNext(offset); else { + int highkeycmp; + /* If scankey == hikey we gotta check the next page too */ if (P_RIGHTMOST(opaque)) break; - if (!_bt_isequal(rel, page, P_HIKEY, - indnkeyatts, itup_scankey)) + highkeycmp = _bt_compare(rel, itup_key, page, P_HIKEY); + Assert(highkeycmp <= 0); + if (highkeycmp != 0) break; /* Advance to next non-dead page --- there must be one */ for (;;) @@ -579,6 +623,7 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, } maxoff = PageGetMaxOffsetNumber(page); offset = P_FIRSTDATAKEY(opaque); + /* Don't invalidate binary search bounds */ } } @@ -606,190 +651,253 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, /* * _bt_findinsertloc() -- Finds an insert location for a tuple * - * If the new key is equal to one or more existing keys, we can - * legitimately place it anywhere in the series of equal keys --- in fact, - * if the new key is equal to the page's "high key" we can place it on - * the next page. If it is equal to the high key, and there's not room - * to insert the new tuple on the current page without splitting, then - * we can move right hoping to find more free space and avoid a split. - * (We should not move right indefinitely, however, since that leads to - * O(N^2) insertion behavior in the presence of many equal keys.) - * Once we have chosen the page to put the key on, we'll insert it before - * any existing equal keys because of the way _bt_binsrch() works. + * On entry, insertstate buffer contains the page the new tuple belongs + * on. It is exclusive-locked and pinned by the caller. * - * If there's not enough room in the space, we try to make room by - * removing any LP_DEAD tuples. + * If 'checkingunique' is true, the buffer on entry is the first page + * that contains duplicates of the new key. If there are duplicates on + * multiple pages, the correct insertion position might be some page to + * the right, rather than the first page. In that case, this function + * moves right to the correct target page. * - * On entry, *bufptr and *offsetptr point to the first legal position - * where the new tuple could be inserted. The caller should hold an - * exclusive lock on *bufptr. *offsetptr can also be set to - * InvalidOffsetNumber, in which case the function will search for the - * right location within the page if needed. On exit, they point to the - * chosen insert location. If _bt_findinsertloc decides to move right, - * the lock and pin on the original page will be released and the new - * page returned to the caller is exclusively locked instead. + * (In a !heapkeyspace index, there can be multiple pages with the same + * high key, where the new tuple could legitimately be placed on. In + * that case, the caller passes the first page containing duplicates, + * just like when checkingunique=true. If that page doesn't have enough + * room for the new tuple, this function moves right, trying to find a + * legal page that does.) * - * newtup is the new tuple we're inserting, and scankey is an insertion - * type scan key for it. + * On exit, insertstate buffer contains the chosen insertion page, and + * the offset within that page is returned. If _bt_findinsertloc needed + * to move right, the lock and pin on the original page are released, and + * the new buffer is exclusively locked and pinned instead. + * + * If insertstate contains cached binary search bounds, we will take + * advantage of them. This avoids repeating comparisons that we made in + * _bt_check_unique() already. + * + * If there is not enough room on the page for the new tuple, we try to + * make room by removing any LP_DEAD tuples. */ -static void +static OffsetNumber _bt_findinsertloc(Relation rel, - Buffer *bufptr, - OffsetNumber *offsetptr, - int keysz, - ScanKey scankey, - IndexTuple newtup, + BTInsertState insertstate, + bool checkingunique, BTStack stack, Relation heapRel) { - Buffer buf = *bufptr; - Page page = BufferGetPage(buf); - Size itemsz; + BTScanInsert itup_key = insertstate->itup_key; + Page page = BufferGetPage(insertstate->buf); BTPageOpaque lpageop; - bool movedright, - vacuumed; - OffsetNumber newitemoff; - OffsetNumber firstlegaloff = *offsetptr; lpageop = (BTPageOpaque) PageGetSpecialPointer(page); - itemsz = IndexTupleSize(newtup); - itemsz = MAXALIGN(itemsz); /* be safe, PageAddItem will do this but we - * need to be consistent */ + /* Check 1/3 of a page restriction */ + if (unlikely(insertstate->itemsz > BTMaxItemSize(page))) + _bt_check_third_page(rel, heapRel, itup_key->heapkeyspace, page, + insertstate->itup); - /* - * Check whether the item can fit on a btree page at all. (Eventually, we - * ought to try to apply TOAST methods if not.) We actually need to be - * able to fit three items on every page, so restrict any one item to 1/3 - * the per-page available space. Note that at this point, itemsz doesn't - * include the ItemId. - * - * NOTE: if you change this, see also the similar code in _bt_buildadd(). - */ - if (itemsz > BTMaxItemSize(page)) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("index row size %zu exceeds maximum %zu for index \"%s\"", - itemsz, BTMaxItemSize(page), - RelationGetRelationName(rel)), - errhint("Values larger than 1/3 of a buffer page cannot be indexed.\n" - "Consider a function index of an MD5 hash of the value, " - "or use full text indexing."), - errtableconstraint(heapRel, - RelationGetRelationName(rel)))); + Assert(P_ISLEAF(lpageop) && !P_INCOMPLETE_SPLIT(lpageop)); + Assert(!insertstate->bounds_valid || checkingunique); + Assert(!itup_key->heapkeyspace || itup_key->scantid != NULL); + Assert(itup_key->heapkeyspace || itup_key->scantid == NULL); - /*---------- - * If we will need to split the page to put the item on this page, - * check whether we can put the tuple somewhere to the right, - * instead. Keep scanning right until we - * (a) find a page with enough free space, - * (b) reach the last page where the tuple can legally go, or - * (c) get tired of searching. - * (c) is not flippant; it is important because if there are many - * pages' worth of equal keys, it's better to split one of the early - * pages than to scan all the way to the end of the run of equal keys - * on every insert. We implement "get tired" as a random choice, - * since stopping after scanning a fixed number of pages wouldn't work - * well (we'd never reach the right-hand side of previously split - * pages). Currently the probability of moving right is set at 0.99, - * which may seem too high to change the behavior much, but it does an - * excellent job of preventing O(N^2) behavior with many equal keys. - *---------- - */ - movedright = false; - vacuumed = false; - while (PageGetFreeSpace(page) < itemsz) + if (itup_key->heapkeyspace) { - Buffer rbuf; - BlockNumber rblkno; - /* - * before considering moving right, see if we can obtain enough space - * by erasing LP_DEAD items + * If we're inserting into a unique index, we may have to walk right + * through leaf pages to find the one leaf page that we must insert on + * to. + * + * This is needed for checkingunique callers because a scantid was not + * used when we called _bt_search(). scantid can only be set after + * _bt_check_unique() has checked for duplicates. The buffer + * initially stored in insertstate->buf has the page where the first + * duplicate key might be found, which isn't always the page that new + * tuple belongs on. The heap TID attribute for new tuple (scantid) + * could force us to insert on a sibling page, though that should be + * very rare in practice. */ - if (P_ISLEAF(lpageop) && P_HAS_GARBAGE(lpageop)) + if (checkingunique) { - _bt_vacuum_one_page(rel, buf, heapRel); + for (;;) + { + /* + * Does the new tuple belong on this page? + * + * The earlier _bt_check_unique() call may well have + * established a strict upper bound on the offset for the new + * item. If it's not the last item of the page (i.e. if there + * is at least one tuple on the page that goes after the tuple + * we're inserting) then we know that the tuple belongs on + * this page. We can skip the high key check. + */ + if (insertstate->bounds_valid && + insertstate->low <= insertstate->stricthigh && + insertstate->stricthigh <= PageGetMaxOffsetNumber(page)) + break; - /* - * remember that we vacuumed this page, because that makes the - * hint supplied by the caller invalid - */ - vacuumed = true; + /* Test '<=', not '!=', since scantid is set now */ + if (P_RIGHTMOST(lpageop) || + _bt_compare(rel, itup_key, page, P_HIKEY) <= 0) + break; - if (PageGetFreeSpace(page) >= itemsz) - break; /* OK, now we have enough space */ + _bt_stepright(rel, insertstate, stack); + /* Update local state after stepping right */ + page = BufferGetPage(insertstate->buf); + lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + } } /* - * nope, so check conditions (b) and (c) enumerated above + * If the target page is full, see if we can obtain enough space by + * erasing LP_DEAD items */ - if (P_RIGHTMOST(lpageop) || - _bt_compare(rel, keysz, scankey, page, P_HIKEY) != 0 || - random() <= (MAX_RANDOM_VALUE / 100)) - break; - - /* - * step right to next non-dead page + if (PageGetFreeSpace(page) < insertstate->itemsz && + P_HAS_GARBAGE(lpageop)) + { + _bt_vacuum_one_page(rel, insertstate->buf, heapRel); + insertstate->bounds_valid = false; + } + } + else + { + /*---------- + * This is a !heapkeyspace (version 2 or 3) index. The current page + * is the first page that we could insert the new tuple to, but there + * may be other pages to the right that we could opt to use instead. + * + * If the new key is equal to one or more existing keys, we can + * legitimately place it anywhere in the series of equal keys. In + * fact, if the new key is equal to the page's "high key" we can place + * it on the next page. If it is equal to the high key, and there's + * not room to insert the new tuple on the current page without + * splitting, then we move right hoping to find more free space and + * avoid a split. * - * must write-lock that page before releasing write lock on current - * page; else someone else's _bt_check_unique scan could fail to see - * our insertion. write locks on intermediate dead pages won't do - * because we don't know when they will get de-linked from the tree. + * Keep scanning right until we + * (a) find a page with enough free space, + * (b) reach the last page where the tuple can legally go, or + * (c) get tired of searching. + * (c) is not flippant; it is important because if there are many + * pages' worth of equal keys, it's better to split one of the early + * pages than to scan all the way to the end of the run of equal keys + * on every insert. We implement "get tired" as a random choice, + * since stopping after scanning a fixed number of pages wouldn't work + * well (we'd never reach the right-hand side of previously split + * pages). The probability of moving right is set at 0.99, which may + * seem too high to change the behavior much, but it does an excellent + * job of preventing O(N^2) behavior with many equal keys. + *---------- */ - rbuf = InvalidBuffer; - - rblkno = lpageop->btpo_next; - for (;;) + while (PageGetFreeSpace(page) < insertstate->itemsz) { - rbuf = _bt_relandgetbuf(rel, rbuf, rblkno, BT_WRITE); - page = BufferGetPage(rbuf); - lpageop = (BTPageOpaque) PageGetSpecialPointer(page); - /* - * If this page was incompletely split, finish the split now. We - * do this while holding a lock on the left sibling, which is not - * good because finishing the split could be a fairly lengthy - * operation. But this should happen very seldom. + * Before considering moving right, see if we can obtain enough + * space by erasing LP_DEAD items */ - if (P_INCOMPLETE_SPLIT(lpageop)) + if (P_HAS_GARBAGE(lpageop)) { - _bt_finish_split(rel, rbuf, stack); - rbuf = InvalidBuffer; - continue; + _bt_vacuum_one_page(rel, insertstate->buf, heapRel); + insertstate->bounds_valid = false; + + if (PageGetFreeSpace(page) >= insertstate->itemsz) + break; /* OK, now we have enough space */ } - if (!P_IGNORE(lpageop)) + /* + * Nope, so check conditions (b) and (c) enumerated above + * + * The earlier _bt_check_unique() call may well have established a + * strict upper bound on the offset for the new item. If it's not + * the last item of the page (i.e. if there is at least one tuple + * on the page that's greater than the tuple we're inserting to) + * then we know that the tuple belongs on this page. We can skip + * the high key check. + */ + if (insertstate->bounds_valid && + insertstate->low <= insertstate->stricthigh && + insertstate->stricthigh <= PageGetMaxOffsetNumber(page)) + break; + + if (P_RIGHTMOST(lpageop) || + _bt_compare(rel, itup_key, page, P_HIKEY) != 0 || + random() <= (MAX_RANDOM_VALUE / 100)) break; - if (P_RIGHTMOST(lpageop)) - elog(ERROR, "fell off the end of index \"%s\"", - RelationGetRelationName(rel)); - rblkno = lpageop->btpo_next; + _bt_stepright(rel, insertstate, stack); + /* Update local state after stepping right */ + page = BufferGetPage(insertstate->buf); + lpageop = (BTPageOpaque) PageGetSpecialPointer(page); } - _bt_relbuf(rel, buf); - buf = rbuf; - movedright = true; - vacuumed = false; } /* - * Now we are on the right page, so find the insert position. If we moved - * right at all, we know we should insert at the start of the page. If we - * didn't move right, we can use the firstlegaloff hint if the caller - * supplied one, unless we vacuumed the page which might have moved tuples - * around making the hint invalid. If we didn't move right or can't use - * the hint, find the position by searching. + * We should now be on the correct page. Find the offset within the page + * for the new tuple. (Possibly reusing earlier search bounds.) */ - if (movedright) - newitemoff = P_FIRSTDATAKEY(lpageop); - else if (firstlegaloff != InvalidOffsetNumber && !vacuumed) - newitemoff = firstlegaloff; - else - newitemoff = _bt_binsrch(rel, buf, keysz, scankey, false); + Assert(P_RIGHTMOST(lpageop) || + _bt_compare(rel, itup_key, page, P_HIKEY) <= 0); - *bufptr = buf; - *offsetptr = newitemoff; + return _bt_binsrch_insert(rel, insertstate); +} + +/* + * Step right to next non-dead page, during insertion. + * + * This is a bit more complicated than moving right in a search. We must + * write-lock the target page before releasing write lock on current page; + * else someone else's _bt_check_unique scan could fail to see our insertion. + * Write locks on intermediate dead pages won't do because we don't know when + * they will get de-linked from the tree. + * + * This is more aggressive than it needs to be for non-unique !heapkeyspace + * indexes. + */ +static void +_bt_stepright(Relation rel, BTInsertState insertstate, BTStack stack) +{ + Page page; + BTPageOpaque lpageop; + Buffer rbuf; + BlockNumber rblkno; + + page = BufferGetPage(insertstate->buf); + lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + + rbuf = InvalidBuffer; + rblkno = lpageop->btpo_next; + for (;;) + { + rbuf = _bt_relandgetbuf(rel, rbuf, rblkno, BT_WRITE); + page = BufferGetPage(rbuf); + lpageop = (BTPageOpaque) PageGetSpecialPointer(page); + + /* + * If this page was incompletely split, finish the split now. We do + * this while holding a lock on the left sibling, which is not good + * because finishing the split could be a fairly lengthy operation. + * But this should happen very seldom. + */ + if (P_INCOMPLETE_SPLIT(lpageop)) + { + _bt_finish_split(rel, rbuf, stack); + rbuf = InvalidBuffer; + continue; + } + + if (!P_IGNORE(lpageop)) + break; + if (P_RIGHTMOST(lpageop)) + elog(ERROR, "fell off the end of index \"%s\"", + RelationGetRelationName(rel)); + + rblkno = lpageop->btpo_next; + } + /* rbuf locked; unlock buf, update state for caller */ + _bt_relbuf(rel, insertstate->buf); + insertstate->buf = rbuf; + insertstate->bounds_valid = false; } /*---------- @@ -797,8 +905,9 @@ _bt_findinsertloc(Relation rel, * * This recursive procedure does the following things: * - * + if necessary, splits the target page (making sure that the - * split is equitable as far as post-insert free space goes). + * + if necessary, splits the target page, using 'itup_key' for + * suffix truncation on leaf pages (caller passes NULL for + * non-leaf pages). * + inserts the tuple. * + if the page was split, pops the parent stack, and finds the * right place to insert the new child pointer (by walking @@ -811,22 +920,17 @@ _bt_findinsertloc(Relation rel, * insertion, and the buffer must be pinned and write-locked. On return, * we will have dropped both the pin and the lock on the buffer. * - * When inserting to a non-leaf page, 'cbuf' is the left-sibling of the - * page we're inserting the downlink for. This function will clear the + * This routine only performs retail tuple insertions. 'itup' should + * always be either a non-highkey leaf item, or a downlink (new high + * key items are created indirectly, when a page is split). When + * inserting to a non-leaf page, 'cbuf' is the left-sibling of the page + * we're inserting the downlink for. This function will clear the * INCOMPLETE_SPLIT flag on it, and release the buffer. - * - * The locking interactions in this code are critical. You should - * grok Lehman and Yao's paper before making any changes. In addition, - * you need to understand how we disambiguate duplicate keys in this - * implementation, in order to be able to find our location using - * L&Y "move right" operations. Since we may insert duplicate user - * keys, and since these dups may propagate up the tree, we use the - * 'afteritem' parameter to position ourselves correctly for the - * insertion on internal pages. *---------- */ static void _bt_insertonpg(Relation rel, + BTScanInsert itup_key, Buffer buf, Buffer cbuf, BTStack stack, @@ -836,7 +940,6 @@ _bt_insertonpg(Relation rel, { Page page; BTPageOpaque lpageop; - OffsetNumber firstright = InvalidOffsetNumber; Size itemsz; page = BufferGetPage(buf); @@ -844,6 +947,13 @@ _bt_insertonpg(Relation rel, /* child buffer must be given iff inserting on an internal page */ Assert(P_ISLEAF(lpageop) == !BufferIsValid(cbuf)); + /* tuple must have appropriate number of attributes */ + Assert(!P_ISLEAF(lpageop) || + BTreeTupleGetNAtts(itup, rel) == + IndexRelationGetNumberOfAttributes(rel)); + Assert(P_ISLEAF(lpageop) || + BTreeTupleGetNAtts(itup, rel) <= + IndexRelationGetNumberOfKeyAttributes(rel)); /* The caller should've finished any incomplete splits already. */ if (P_INCOMPLETE_SPLIT(lpageop)) @@ -865,17 +975,28 @@ _bt_insertonpg(Relation rel, { bool is_root = P_ISROOT(lpageop); bool is_only = P_LEFTMOST(lpageop) && P_RIGHTMOST(lpageop); - bool newitemonleft; Buffer rbuf; - /* Choose the split point */ - firstright = _bt_findsplitloc(rel, page, - newitemoff, itemsz, - &newitemonleft); + /* + * If we're here then a pagesplit is needed. We should never reach + * here if we're using the fastpath since we should have checked for + * all the required conditions, including the fact that this page has + * enough freespace. Note that this routine can in theory deal with + * the situation where a NULL stack pointer is passed (that's what + * would happen if the fastpath is taken). But that path is much + * slower, defeating the very purpose of the optimization. The + * following assertion should protect us from any future code changes + * that invalidate those assumptions. + * + * Note that whenever we fail to take the fastpath, we clear the + * cached block. Checking for a valid cached block at this point is + * enough to decide whether we're in a fastpath or not. + */ + Assert(!(P_ISLEAF(lpageop) && + BlockNumberIsValid(RelationGetTargetBlock(rel)))); /* split the buffer into left and right halves */ - rbuf = _bt_split(rel, buf, cbuf, firstright, - newitemoff, itemsz, itup, newitemonleft); + rbuf = _bt_split(rel, itup_key, buf, cbuf, newitemoff, itemsz, itup); PredicateLockPageSplit(rel, BufferGetBlockNumber(buf), BufferGetBlockNumber(rbuf)); @@ -892,8 +1013,10 @@ _bt_insertonpg(Relation rel, * * We're ready to do the parent insertion. We need to hold onto the * locks for the child pages until we locate the parent, but we can - * release them before doing the actual insertion (see Lehman and Yao - * for the reasoning). + * at least release the lock on the right child before doing the + * actual insertion. The lock on the left child will be released + * last of all by parent insertion, where it is the 'cbuf' of parent + * page. *---------- */ _bt_insert_parent(rel, buf, rbuf, stack, is_root, is_only); @@ -905,6 +1028,7 @@ _bt_insertonpg(Relation rel, BTMetaPageData *metad = NULL; OffsetNumber itup_off; BlockNumber itup_blkno; + BlockNumber cachedBlock = InvalidBlockNumber; itup_off = newitemoff; itup_blkno = BufferGetBlockNumber(buf); @@ -932,6 +1056,18 @@ _bt_insertonpg(Relation rel, } } + /* + * Every internal page should have exactly one negative infinity item + * at all times. Only _bt_split() and _bt_newroot() should add items + * that become negative infinity items through truncation, since + * they're the only routines that allocate new internal pages. Do not + * allow a retail insertion of a new item at the negative infinity + * offset. + */ + if (!P_ISLEAF(lpageop) && newitemoff == P_FIRSTDATAKEY(lpageop)) + elog(ERROR, "cannot insert second negative infinity item in block %u of index \"%s\"", + itup_blkno, RelationGetRelationName(rel)); + /* Do the update. No ereport(ERROR) until changes are logged */ START_CRIT_SECTION(); @@ -944,7 +1080,7 @@ _bt_insertonpg(Relation rel, if (BufferIsValid(metabuf)) { /* upgrade meta-page if needed */ - if (metad->btm_version < BTREE_VERSION) + if (metad->btm_version < BTREE_NOVAC_VERSION) _bt_upgrademetapage(metapg); metad->btm_fastroot = itup_blkno; metad->btm_fastlevel = lpageop->btpo.level; @@ -962,6 +1098,15 @@ _bt_insertonpg(Relation rel, MarkBufferDirty(cbuf); } + /* + * Cache the block information if we just inserted into the rightmost + * leaf page of the index and it's not the root page. For very small + * index where root is also the leaf, there is no point trying for any + * optimization. + */ + if (P_RIGHTMOST(lpageop) && P_ISLEAF(lpageop) && !P_ISROOT(lpageop)) + cachedBlock = BufferGetBlockNumber(buf); + /* XLOG stuff */ if (RelationNeedsWAL(rel)) { @@ -969,7 +1114,6 @@ _bt_insertonpg(Relation rel, xl_btree_metadata xlmeta; uint8 xlinfo; XLogRecPtr recptr; - IndexTupleData trunctuple; xlrec.offnum = itup_off; @@ -977,16 +1121,7 @@ _bt_insertonpg(Relation rel, XLogRegisterData((char *) &xlrec, SizeOfBtreeInsert); if (P_ISLEAF(lpageop)) - { xlinfo = XLOG_BTREE_INSERT_LEAF; - - /* - * Cache the block information if we just inserted into the - * rightmost leaf page of the index. - */ - if (P_RIGHTMOST(lpageop)) - RelationSetTargetBlock(rel, BufferGetBlockNumber(buf)); - } else { /* @@ -1000,6 +1135,8 @@ _bt_insertonpg(Relation rel, if (BufferIsValid(metabuf)) { + Assert(metad->btm_version >= BTREE_NOVAC_VERSION); + xlmeta.version = metad->btm_version; xlmeta.root = metad->btm_root; xlmeta.level = metad->btm_level; xlmeta.fastroot = metad->btm_fastroot; @@ -1014,17 +1151,8 @@ _bt_insertonpg(Relation rel, xlinfo = XLOG_BTREE_INSERT_META; } - /* Read comments in _bt_pgaddtup */ XLogRegisterBuffer(0, buf, REGBUF_STANDARD); - if (!P_ISLEAF(lpageop) && newitemoff == P_FIRSTDATAKEY(lpageop)) - { - trunctuple = *itup; - trunctuple.t_info = sizeof(IndexTupleData); - XLogRegisterBufData(0, (char *) &trunctuple, - sizeof(IndexTupleData)); - } - else - XLogRegisterBufData(0, (char *) itup, IndexTupleSize(itup)); + XLogRegisterBufData(0, (char *) itup, IndexTupleSize(itup)); recptr = XLogInsert(RM_BTREE_ID, xlinfo); @@ -1048,6 +1176,23 @@ _bt_insertonpg(Relation rel, if (BufferIsValid(cbuf)) _bt_relbuf(rel, cbuf); _bt_relbuf(rel, buf); + + /* + * If we decided to cache the insertion target block, then set it now. + * But before that, check for the height of the tree and don't go for + * the optimization for small indexes. We defer that check to this + * point to ensure that we don't call _bt_getrootheight while holding + * lock on any other block. + * + * We do this after dropping locks on all buffers. So the information + * about whether the insertion block is still the rightmost block or + * not may have changed in between. But we will deal with that during + * next insert operation. No special care is required while setting + * it. + */ + if (BlockNumberIsValid(cachedBlock) && + _bt_getrootheight(rel) >= BTREE_FASTPATH_MIN_LEVEL) + RelationSetTargetBlock(rel, cachedBlock); } } @@ -1055,21 +1200,21 @@ _bt_insertonpg(Relation rel, * _bt_split() -- split a page in the btree. * * On entry, buf is the page to split, and is pinned and write-locked. - * firstright is the item index of the first item to be moved to the - * new right page. newitemoff etc. tell us about the new item that - * must be inserted along with the data from the old page. + * newitemoff etc. tell us about the new item that must be inserted + * along with the data from the original page. * - * When splitting a non-leaf page, 'cbuf' is the left-sibling of the - * page we're inserting the downlink for. This function will clear the - * INCOMPLETE_SPLIT flag on it, and release the buffer. + * itup_key is used for suffix truncation on leaf pages (internal + * page callers pass NULL). When splitting a non-leaf page, 'cbuf' + * is the left-sibling of the page we're inserting the downlink for. + * This function will clear the INCOMPLETE_SPLIT flag on it, and + * release the buffer. * * Returns the new right sibling of buf, pinned and write-locked. * The pin and lock on buf are maintained. */ static Buffer -_bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, - OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem, - bool newitemonleft) +_bt_split(Relation rel, BTScanInsert itup_key, Buffer buf, Buffer cbuf, + OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem) { Buffer rbuf; Page origpage; @@ -1088,98 +1233,101 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, IndexTuple item; OffsetNumber leftoff, rightoff; + OffsetNumber firstright; OffsetNumber maxoff; OffsetNumber i; - bool isleaf; + bool newitemonleft, + isleaf; IndexTuple lefthikey; int indnatts = IndexRelationGetNumberOfAttributes(rel); int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); - /* Acquire a new page to split into */ - rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE); - /* * origpage is the original page to be split. leftpage is a temporary * buffer that receives the left-sibling data, which will be copied back - * into origpage on success. rightpage is the new page that receives the - * right-sibling data. If we fail before reaching the critical section, - * origpage hasn't been modified and leftpage is only workspace. In - * principle we shouldn't need to worry about rightpage either, because it - * hasn't been linked into the btree page structure; but to avoid leaving - * possibly-confusing junk behind, we are careful to rewrite rightpage as - * zeroes before throwing any error. + * into origpage on success. rightpage is the new page that will receive + * the right-sibling data. + * + * leftpage is allocated after choosing a split point. rightpage's new + * buffer isn't acquired until after leftpage is initialized and has new + * high key, the last point where splitting the page may fail (barring + * corruption). Failing before acquiring new buffer won't have lasting + * consequences, since origpage won't have been modified and leftpage is + * only workspace. */ origpage = BufferGetPage(buf); - leftpage = PageGetTempPage(origpage); - rightpage = BufferGetPage(rbuf); - + oopaque = (BTPageOpaque) PageGetSpecialPointer(origpage); origpagenumber = BufferGetBlockNumber(buf); - rightpagenumber = BufferGetBlockNumber(rbuf); - - _bt_pageinit(leftpage, BufferGetPageSize(buf)); - /* rightpage was already initialized by _bt_getbuf */ /* - * Copy the original page's LSN into leftpage, which will become the - * updated version of the page. We need this because XLogInsert will - * examine the LSN and possibly dump it in a page image. + * Choose a point to split origpage at. + * + * A split point can be thought of as a point _between_ two existing + * tuples on origpage (lastleft and firstright tuples), provided you + * pretend that the new item that didn't fit is already on origpage. + * + * Since origpage does not actually contain newitem, the representation of + * split points needs to work with two boundary cases: splits where + * newitem is lastleft, and splits where newitem is firstright. + * newitemonleft resolves the ambiguity that would otherwise exist when + * newitemoff == firstright. In all other cases it's clear which side of + * the split every tuple goes on from context. newitemonleft is usually + * (but not always) redundant information. */ - PageSetLSN(leftpage, PageGetLSN(origpage)); + firstright = _bt_findsplitloc(rel, origpage, newitemoff, newitemsz, + newitem, &newitemonleft); - /* init btree private data */ - oopaque = (BTPageOpaque) PageGetSpecialPointer(origpage); + /* Allocate temp buffer for leftpage */ + leftpage = PageGetTempPage(origpage); + _bt_pageinit(leftpage, BufferGetPageSize(buf)); lopaque = (BTPageOpaque) PageGetSpecialPointer(leftpage); - ropaque = (BTPageOpaque) PageGetSpecialPointer(rightpage); - isleaf = P_ISLEAF(oopaque); - - /* if we're splitting this page, it won't be the root when we're done */ - /* also, clear the SPLIT_END and HAS_GARBAGE flags in both pages */ + /* + * leftpage won't be the root when we're done. Also, clear the SPLIT_END + * and HAS_GARBAGE flags. + */ lopaque->btpo_flags = oopaque->btpo_flags; lopaque->btpo_flags &= ~(BTP_ROOT | BTP_SPLIT_END | BTP_HAS_GARBAGE); - ropaque->btpo_flags = lopaque->btpo_flags; - /* set flag in left page indicating that the right page has no downlink */ + /* set flag in leftpage indicating that rightpage has no downlink yet */ lopaque->btpo_flags |= BTP_INCOMPLETE_SPLIT; lopaque->btpo_prev = oopaque->btpo_prev; - lopaque->btpo_next = rightpagenumber; - ropaque->btpo_prev = origpagenumber; - ropaque->btpo_next = oopaque->btpo_next; - lopaque->btpo.level = ropaque->btpo.level = oopaque->btpo.level; - /* Since we already have write-lock on both pages, ok to read cycleid */ - lopaque->btpo_cycleid = _bt_vacuum_cycleid(rel); - ropaque->btpo_cycleid = lopaque->btpo_cycleid; + /* handle btpo_next after rightpage buffer acquired */ + lopaque->btpo.level = oopaque->btpo.level; + /* handle btpo_cycleid after rightpage buffer acquired */ /* - * If the page we're splitting is not the rightmost page at its level in - * the tree, then the first entry on the page is the high key for the - * page. We need to copy that to the right half. Otherwise (meaning the - * rightmost page case), all the items on the right half will be user - * data. + * Copy the original page's LSN into leftpage, which will become the + * updated version of the page. We need this because XLogInsert will + * examine the LSN and possibly dump it in a page image. */ - rightoff = P_HIKEY; - - if (!P_RIGHTMOST(oopaque)) - { - itemid = PageGetItemId(origpage, P_HIKEY); - itemsz = ItemIdGetLength(itemid); - item = (IndexTuple) PageGetItem(origpage, itemid); - if (PageAddItem(rightpage, (Item) item, itemsz, rightoff, - false, false) == InvalidOffsetNumber) - { - memset(rightpage, 0, BufferGetPageSize(rbuf)); - elog(ERROR, "failed to add hikey to the right sibling" - " while splitting block %u of index \"%s\"", - origpagenumber, RelationGetRelationName(rel)); - } - rightoff = OffsetNumberNext(rightoff); - } + PageSetLSN(leftpage, PageGetLSN(origpage)); + isleaf = P_ISLEAF(oopaque); /* * The "high key" for the new left page will be the first key that's going - * to go into the new right page. This might be either the existing data - * item at position firstright, or the incoming tuple. + * to go into the new right page, or a truncated version if this is a leaf + * page split. + * + * The high key for the left page is formed using the first item on the + * right page, which may seem to be contrary to Lehman & Yao's approach of + * using the left page's last item as its new high key when splitting on + * the leaf level. It isn't, though: suffix truncation will leave the + * left page's high key fully equal to the last item on the left page when + * two tuples with equal key values (excluding heap TID) enclose the split + * point. It isn't actually necessary for a new leaf high key to be equal + * to the last item on the left for the L&Y "subtree" invariant to hold. + * It's sufficient to make sure that the new leaf high key is strictly + * less than the first item on the right leaf page, and greater than or + * equal to (not necessarily equal to) the last item on the left leaf + * page. + * + * In other words, when suffix truncation isn't possible, L&Y's exact + * approach to leaf splits is taken. (Actually, even that is slightly + * inaccurate. A tuple with all the keys from firstright but the heap TID + * from lastleft will be used as the new high key, since the last left + * tuple could be physically larger despite being opclass-equal in respect + * of all attributes prior to the heap TID attribute.) */ - leftoff = P_HIKEY; if (!newitemonleft && newitemoff == firstright) { /* incoming tuple will become first on right page */ @@ -1195,32 +1343,131 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, } /* - * We must truncate included attributes of the "high key" item, before - * insert it onto the leaf page. It's the only point in insertion - * process, where we perform truncation. All other functions work with - * this high key and do not change it. + * Truncate unneeded key and non-key attributes of the high key item + * before inserting it on the left page. This can only happen at the leaf + * level, since in general all pivot tuple values originate from leaf + * level high keys. A pivot tuple in a grandparent page must guide a + * search not only to the correct parent page, but also to the correct + * leaf page. */ - if (indnatts != indnkeyatts && isleaf) + if (isleaf && (itup_key->heapkeyspace || indnatts != indnkeyatts)) { - lefthikey = _bt_truncate_tuple(rel, item); + IndexTuple lastleft; + + /* + * Determine which tuple will become the last on the left page. This + * is needed to decide how many attributes from the first item on the + * right page must remain in new high key for left page. + */ + if (newitemonleft && newitemoff == firstright) + { + /* incoming tuple will become last on left page */ + lastleft = newitem; + } + else + { + OffsetNumber lastleftoff; + + /* item just before firstright will become last on left page */ + lastleftoff = OffsetNumberPrev(firstright); + Assert(lastleftoff >= P_FIRSTDATAKEY(oopaque)); + itemid = PageGetItemId(origpage, lastleftoff); + lastleft = (IndexTuple) PageGetItem(origpage, itemid); + } + + Assert(lastleft != item); + lefthikey = _bt_truncate(rel, lastleft, item, itup_key); itemsz = IndexTupleSize(lefthikey); itemsz = MAXALIGN(itemsz); } else lefthikey = item; + /* + * Add new high key to leftpage + */ + leftoff = P_HIKEY; + + Assert(BTreeTupleGetNAtts(lefthikey, rel) > 0); + Assert(BTreeTupleGetNAtts(lefthikey, rel) <= indnkeyatts); if (PageAddItem(leftpage, (Item) lefthikey, itemsz, leftoff, false, false) == InvalidOffsetNumber) - { - memset(rightpage, 0, BufferGetPageSize(rbuf)); elog(ERROR, "failed to add hikey to the left sibling" " while splitting block %u of index \"%s\"", origpagenumber, RelationGetRelationName(rel)); - } leftoff = OffsetNumberNext(leftoff); + /* be tidy */ + if (lefthikey != item) + pfree(lefthikey); + + /* + * Acquire a new right page to split into, now that left page has a new + * high key. From here on, it's not okay to throw an error without + * zeroing rightpage first. This coding rule ensures that we won't + * confuse future VACUUM operations, which might otherwise try to re-find + * a downlink to a leftover junk page as the page undergoes deletion. + * + * It would be reasonable to start the critical section just after the new + * rightpage buffer is acquired instead; that would allow us to avoid + * leftover junk pages without bothering to zero rightpage. We do it this + * way because it avoids an unnecessary PANIC when either origpage or its + * existing sibling page are corrupt. + */ + rbuf = _bt_getbuf(rel, P_NEW, BT_WRITE); + rightpage = BufferGetPage(rbuf); + rightpagenumber = BufferGetBlockNumber(rbuf); + /* rightpage was initialized by _bt_getbuf */ + ropaque = (BTPageOpaque) PageGetSpecialPointer(rightpage); + + /* + * Finish off remaining leftpage special area fields. They cannot be set + * before both origpage (leftpage) and rightpage buffers are acquired and + * locked. + */ + lopaque->btpo_next = rightpagenumber; + lopaque->btpo_cycleid = _bt_vacuum_cycleid(rel); + + /* + * rightpage won't be the root when we're done. Also, clear the SPLIT_END + * and HAS_GARBAGE flags. + */ + ropaque->btpo_flags = oopaque->btpo_flags; + ropaque->btpo_flags &= ~(BTP_ROOT | BTP_SPLIT_END | BTP_HAS_GARBAGE); + ropaque->btpo_prev = origpagenumber; + ropaque->btpo_next = oopaque->btpo_next; + ropaque->btpo.level = oopaque->btpo.level; + ropaque->btpo_cycleid = lopaque->btpo_cycleid; + + /* + * Add new high key to rightpage where necessary. + * + * If the page we're splitting is not the rightmost page at its level in + * the tree, then the first entry on the page is the high key from + * origpage. + */ + rightoff = P_HIKEY; + + if (!P_RIGHTMOST(oopaque)) + { + itemid = PageGetItemId(origpage, P_HIKEY); + itemsz = ItemIdGetLength(itemid); + item = (IndexTuple) PageGetItem(origpage, itemid); + Assert(BTreeTupleGetNAtts(item, rel) > 0); + Assert(BTreeTupleGetNAtts(item, rel) <= indnkeyatts); + if (PageAddItem(rightpage, (Item) item, itemsz, rightoff, + false, false) == InvalidOffsetNumber) + { + memset(rightpage, 0, BufferGetPageSize(rbuf)); + elog(ERROR, "failed to add hikey to the right sibling" + " while splitting block %u of index \"%s\"", + origpagenumber, RelationGetRelationName(rel)); + } + rightoff = OffsetNumberNext(rightoff); + } /* - * Now transfer all the data items to the appropriate page. + * Now transfer all the data items (non-pivot tuples in isleaf case, or + * additional pivot tuples in !isleaf case) to the appropriate page. * * Note: we *must* insert at least the right page's items in item-number * order, for the benefit of _bt_restore_page(). @@ -1238,6 +1485,7 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, { if (newitemonleft) { + Assert(newitemoff <= firstright); if (!_bt_pgaddtup(leftpage, newitemsz, newitem, leftoff)) { memset(rightpage, 0, BufferGetPageSize(rbuf)); @@ -1249,6 +1497,7 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, } else { + Assert(newitemoff >= firstright); if (!_bt_pgaddtup(rightpage, newitemsz, newitem, rightoff)) { memset(rightpage, 0, BufferGetPageSize(rbuf)); @@ -1311,7 +1560,6 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, * all readers release locks on a page before trying to fetch its * neighbors. */ - if (!P_RIGHTMOST(oopaque)) { sbuf = _bt_getbuf(rel, oopaque->btpo_next, BT_WRITE); @@ -1320,10 +1568,12 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, if (sopaque->btpo_prev != origpagenumber) { memset(rightpage, 0, BufferGetPageSize(rbuf)); - elog(ERROR, "right sibling's left-link doesn't match: " - "block %u links to %u instead of expected %u in index \"%s\"", - oopaque->btpo_next, sopaque->btpo_prev, origpagenumber, - RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling's left-link doesn't match: " + "block %u links to %u instead of expected %u in index \"%s\"", + oopaque->btpo_next, sopaque->btpo_prev, origpagenumber, + RelationGetRelationName(rel)))); } /* @@ -1398,7 +1648,6 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, xl_btree_split xlrec; uint8 xlinfo; XLogRecPtr recptr; - bool loglhikey = false; xlrec.level = ropaque->btpo.level; xlrec.firstright = firstright; @@ -1427,42 +1676,26 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, if (newitemonleft) XLogRegisterBufData(0, (char *) newitem, MAXALIGN(newitemsz)); - /* Log left page */ - if (!isleaf || indnatts != indnkeyatts) - { - /* - * We must also log the left page's high key. There are two - * reasons for that: right page's leftmost key is suppressed on - * non-leaf levels and in covering indexes included columns are - * truncated from high keys. Show it as belonging to the left - * page buffer, so that it is not stored if XLogInsert decides it - * needs a full-page image of the left page. - */ - itemid = PageGetItemId(origpage, P_HIKEY); - item = (IndexTuple) PageGetItem(origpage, itemid); - XLogRegisterBufData(0, (char *) item, MAXALIGN(IndexTupleSize(item))); - loglhikey = true; - } + /* Log the left page's new high key */ + itemid = PageGetItemId(origpage, P_HIKEY); + item = (IndexTuple) PageGetItem(origpage, itemid); + XLogRegisterBufData(0, (char *) item, MAXALIGN(IndexTupleSize(item))); /* * Log the contents of the right page in the format understood by - * _bt_restore_page(). We set lastrdata->buffer to InvalidBuffer, - * because we're going to recreate the whole page anyway, so it should - * never be stored by XLogInsert. + * _bt_restore_page(). The whole right page will be recreated. * * Direct access to page is not good but faster - we should implement * some new func in page API. Note we only store the tuples * themselves, knowing that they were inserted in item-number order - * and so the item pointers can be reconstructed. See comments for + * and so the line pointers can be reconstructed. See comments for * _bt_restore_page(). */ XLogRegisterBufData(1, (char *) rightpage + ((PageHeader) rightpage)->pd_upper, ((PageHeader) rightpage)->pd_special - ((PageHeader) rightpage)->pd_upper); - xlinfo = newitemonleft ? - (loglhikey ? XLOG_BTREE_SPLIT_L_HIGHKEY : XLOG_BTREE_SPLIT_L) : - (loglhikey ? XLOG_BTREE_SPLIT_R_HIGHKEY : XLOG_BTREE_SPLIT_R); + xlinfo = newitemonleft ? XLOG_BTREE_SPLIT_L : XLOG_BTREE_SPLIT_R; recptr = XLogInsert(RM_BTREE_ID, xlinfo); PageSetLSN(origpage, recptr); @@ -1492,274 +1725,18 @@ _bt_split(Relation rel, Buffer buf, Buffer cbuf, OffsetNumber firstright, } /* - * _bt_findsplitloc() -- find an appropriate place to split a page. - * - * The idea here is to equalize the free space that will be on each split - * page, *after accounting for the inserted tuple*. (If we fail to account - * for it, we might find ourselves with too little room on the page that - * it needs to go into!) - * - * If the page is the rightmost page on its level, we instead try to arrange - * to leave the left split page fillfactor% full. In this way, when we are - * inserting successively increasing keys (consider sequences, timestamps, - * etc) we will end up with a tree whose pages are about fillfactor% full, - * instead of the 50% full result that we'd get without this special case. - * This is the same as nbtsort.c produces for a newly-created tree. Note - * that leaf and nonleaf pages use different fillfactors. - * - * We are passed the intended insert position of the new tuple, expressed as - * the offsetnumber of the tuple it must go in front of. (This could be - * maxoff+1 if the tuple is to go at the end.) - * - * We return the index of the first existing tuple that should go on the - * righthand page, plus a boolean indicating whether the new tuple goes on - * the left or right page. The bool is necessary to disambiguate the case - * where firstright == newitemoff. - */ -static OffsetNumber -_bt_findsplitloc(Relation rel, - Page page, - OffsetNumber newitemoff, - Size newitemsz, - bool *newitemonleft) -{ - BTPageOpaque opaque; - OffsetNumber offnum; - OffsetNumber maxoff; - ItemId itemid; - FindSplitData state; - int leftspace, - rightspace, - goodenough, - olddataitemstotal, - olddataitemstoleft; - bool goodenoughfound; - - opaque = (BTPageOpaque) PageGetSpecialPointer(page); - - /* Passed-in newitemsz is MAXALIGNED but does not include line pointer */ - newitemsz += sizeof(ItemIdData); - - /* Total free space available on a btree page, after fixed overhead */ - leftspace = rightspace = - PageGetPageSize(page) - SizeOfPageHeaderData - - MAXALIGN(sizeof(BTPageOpaqueData)); - - /* The right page will have the same high key as the old page */ - if (!P_RIGHTMOST(opaque)) - { - itemid = PageGetItemId(page, P_HIKEY); - rightspace -= (int) (MAXALIGN(ItemIdGetLength(itemid)) + - sizeof(ItemIdData)); - } - - /* Count up total space in data items without actually scanning 'em */ - olddataitemstotal = rightspace - (int) PageGetExactFreeSpace(page); - - state.newitemsz = newitemsz; - state.is_leaf = P_ISLEAF(opaque); - state.is_rightmost = P_RIGHTMOST(opaque); - state.have_split = false; - if (state.is_leaf) - state.fillfactor = RelationGetFillFactor(rel, - BTREE_DEFAULT_FILLFACTOR); - else - state.fillfactor = BTREE_NONLEAF_FILLFACTOR; - state.newitemonleft = false; /* these just to keep compiler quiet */ - state.firstright = 0; - state.best_delta = 0; - state.leftspace = leftspace; - state.rightspace = rightspace; - state.olddataitemstotal = olddataitemstotal; - state.newitemoff = newitemoff; - - /* - * Finding the best possible split would require checking all the possible - * split points, because of the high-key and left-key special cases. - * That's probably more work than it's worth; instead, stop as soon as we - * find a "good-enough" split, where good-enough is defined as an - * imbalance in free space of no more than pagesize/16 (arbitrary...) This - * should let us stop near the middle on most pages, instead of plowing to - * the end. - */ - goodenough = leftspace / 16; - - /* - * Scan through the data items and calculate space usage for a split at - * each possible position. - */ - olddataitemstoleft = 0; - goodenoughfound = false; - maxoff = PageGetMaxOffsetNumber(page); - - for (offnum = P_FIRSTDATAKEY(opaque); - offnum <= maxoff; - offnum = OffsetNumberNext(offnum)) - { - Size itemsz; - - itemid = PageGetItemId(page, offnum); - itemsz = MAXALIGN(ItemIdGetLength(itemid)) + sizeof(ItemIdData); - - /* - * Will the new item go to left or right of split? - */ - if (offnum > newitemoff) - _bt_checksplitloc(&state, offnum, true, - olddataitemstoleft, itemsz); - - else if (offnum < newitemoff) - _bt_checksplitloc(&state, offnum, false, - olddataitemstoleft, itemsz); - else - { - /* need to try it both ways! */ - _bt_checksplitloc(&state, offnum, true, - olddataitemstoleft, itemsz); - - _bt_checksplitloc(&state, offnum, false, - olddataitemstoleft, itemsz); - } - - /* Abort scan once we find a good-enough choice */ - if (state.have_split && state.best_delta <= goodenough) - { - goodenoughfound = true; - break; - } - - olddataitemstoleft += itemsz; - } - - /* - * If the new item goes as the last item, check for splitting so that all - * the old items go to the left page and the new item goes to the right - * page. - */ - if (newitemoff > maxoff && !goodenoughfound) - _bt_checksplitloc(&state, newitemoff, false, olddataitemstotal, 0); - - /* - * I believe it is not possible to fail to find a feasible split, but just - * in case ... - */ - if (!state.have_split) - elog(ERROR, "could not find a feasible split point for index \"%s\"", - RelationGetRelationName(rel)); - - *newitemonleft = state.newitemonleft; - return state.firstright; -} - -/* - * Subroutine to analyze a particular possible split choice (ie, firstright - * and newitemonleft settings), and record the best split so far in *state. - * - * firstoldonright is the offset of the first item on the original page - * that goes to the right page, and firstoldonrightsz is the size of that - * tuple. firstoldonright can be > max offset, which means that all the old - * items go to the left page and only the new item goes to the right page. - * In that case, firstoldonrightsz is not used. - * - * olddataitemstoleft is the total size of all old items to the left of - * firstoldonright. - */ -static void -_bt_checksplitloc(FindSplitData *state, - OffsetNumber firstoldonright, - bool newitemonleft, - int olddataitemstoleft, - Size firstoldonrightsz) -{ - int leftfree, - rightfree; - Size firstrightitemsz; - bool newitemisfirstonright; - - /* Is the new item going to be the first item on the right page? */ - newitemisfirstonright = (firstoldonright == state->newitemoff - && !newitemonleft); - - if (newitemisfirstonright) - firstrightitemsz = state->newitemsz; - else - firstrightitemsz = firstoldonrightsz; - - /* Account for all the old tuples */ - leftfree = state->leftspace - olddataitemstoleft; - rightfree = state->rightspace - - (state->olddataitemstotal - olddataitemstoleft); - - /* - * The first item on the right page becomes the high key of the left page; - * therefore it counts against left space as well as right space. When - * index has included attribues, then those attributes of left page high - * key will be truncate leaving that page with slightly more free space. - * However, that shouldn't affect our ability to find valid split - * location, because anyway split location should exists even without high - * key truncation. - */ - leftfree -= firstrightitemsz; - - /* account for the new item */ - if (newitemonleft) - leftfree -= (int) state->newitemsz; - else - rightfree -= (int) state->newitemsz; - - /* - * If we are not on the leaf level, we will be able to discard the key - * data from the first item that winds up on the right page. - */ - if (!state->is_leaf) - rightfree += (int) firstrightitemsz - - (int) (MAXALIGN(sizeof(IndexTupleData)) + sizeof(ItemIdData)); - - /* - * If feasible split point, remember best delta. - */ - if (leftfree >= 0 && rightfree >= 0) - { - int delta; - - if (state->is_rightmost) - { - /* - * If splitting a rightmost page, try to put (100-fillfactor)% of - * free space on left page. See comments for _bt_findsplitloc. - */ - delta = (state->fillfactor * leftfree) - - ((100 - state->fillfactor) * rightfree); - } - else - { - /* Otherwise, aim for equal free space on both sides */ - delta = leftfree - rightfree; - } - - if (delta < 0) - delta = -delta; - if (!state->have_split || delta < state->best_delta) - { - state->have_split = true; - state->newitemonleft = newitemonleft; - state->firstright = firstoldonright; - state->best_delta = delta; - } - } -} - -/* - * _bt_insert_parent() -- Insert downlink into parent after a page split. + * _bt_insert_parent() -- Insert downlink into parent, completing split. * * On entry, buf and rbuf are the left and right split pages, which we - * still hold write locks on per the L&Y algorithm. We release the - * write locks once we have write lock on the parent page. (Any sooner, - * and it'd be possible for some other process to try to split or delete - * one of these pages, and get confused because it cannot find the downlink.) + * still hold write locks on. Both locks will be released here. We + * release the rbuf lock once we have a write lock on the page that we + * intend to insert a downlink to rbuf on (i.e. buf's current parent page). + * The lock on buf is released at the same point as the lock on the parent + * page, since buf's INCOMPLETE_SPLIT flag must be cleared by the same + * atomic operation that completes the split by inserting a new downlink. * - * stack - stack showing how we got here. May be NULL in cases that don't - * have to be efficient (concurrent ROOT split, WAL recovery) + * stack - stack showing how we got here. Will be NULL when splitting true + * root, or during concurrent root split, where we can be inefficient * is_root - we split the true root * is_only - we split a page alone on its level (might have been fast root) */ @@ -1820,12 +1797,11 @@ _bt_insert_parent(Relation rel, stack = &fakestack; stack->bts_blkno = BufferGetBlockNumber(pbuf); stack->bts_offset = InvalidOffsetNumber; - stack->bts_btentry = InvalidBlockNumber; stack->bts_parent = NULL; _bt_relbuf(rel, pbuf); } - /* get high key from left page == lower bound for new right page */ + /* get high key from left, a strict lower bound for new right page */ ritem = (IndexTuple) PageGetItem(page, PageGetItemId(page, P_HIKEY)); @@ -1834,14 +1810,15 @@ _bt_insert_parent(Relation rel, BTreeInnerTupleSetDownLink(new_item, rbknum); /* - * Find the parent buffer and get the parent page. + * Re-find and write lock the parent of buf. * - * Oops - if we were moved right then we need to change stack item! We - * want to find parent pointing to where we are, right ? - vadim - * 05/27/97 + * It's possible that the location of buf's downlink has changed since + * our initial _bt_search() descent. _bt_getstackbuf() will detect + * and recover from this, updating the stack, which ensures that the + * new downlink will be inserted at the correct offset. Even buf's + * parent may have changed. */ - stack->bts_btentry = bknum; - pbuf = _bt_getstackbuf(rel, stack, BT_WRITE); + pbuf = _bt_getstackbuf(rel, stack, bknum); /* * Now we can unlock the right child. The left child will be unlocked @@ -1849,13 +1826,14 @@ _bt_insert_parent(Relation rel, */ _bt_relbuf(rel, rbuf); - /* Check for error only after writing children */ if (pbuf == InvalidBuffer) - elog(ERROR, "failed to re-find parent key in index \"%s\" for split pages %u/%u", - RelationGetRelationName(rel), bknum, rbknum); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("failed to re-find parent key in index \"%s\" for split pages %u/%u", + RelationGetRelationName(rel), bknum, rbknum))); - /* Recursively update the parent */ - _bt_insertonpg(rel, pbuf, buf, stack->bts_parent, + /* Recursively insert into the parent */ + _bt_insertonpg(rel, NULL, pbuf, buf, stack->bts_parent, new_item, stack->bts_offset + 1, is_only); @@ -1921,20 +1899,37 @@ _bt_finish_split(Relation rel, Buffer lbuf, BTStack stack) } /* - * _bt_getstackbuf() -- Walk back up the tree one step, and find the item - * we last looked at in the parent. + * _bt_getstackbuf() -- Walk back up the tree one step, and find the pivot + * tuple whose downlink points to child page. * - * This is possible because we save the downlink from the parent item, - * which is enough to uniquely identify it. Insertions into the parent - * level could cause the item to move right; deletions could cause it - * to move left, but not left of the page we previously found it in. + * Caller passes child's block number, which is used to identify + * associated pivot tuple in parent page using a linear search that + * matches on pivot's downlink/block number. The expected location of + * the pivot tuple is taken from the stack one level above the child + * page. This is used as a starting point. Insertions into the + * parent level could cause the pivot tuple to move right; deletions + * could cause it to move left, but not left of the page we previously + * found it on. * - * Adjusts bts_blkno & bts_offset if changed. + * Caller can use its stack to relocate the pivot tuple/downlink for + * any same-level page to the right of the page found by its initial + * descent. This is necessary because of the possibility that caller + * moved right to recover from a concurrent page split. It's also + * convenient for certain callers to be able to step right when there + * wasn't a concurrent page split, while still using their original + * stack. For example, the checkingunique _bt_doinsert() case may + * have to step right when there are many physical duplicates, and its + * scantid forces an insertion to the right of the "first page the + * value could be on". * - * Returns InvalidBuffer if item not found (should not happen). + * Returns write-locked parent page buffer, or InvalidBuffer if pivot + * tuple not found (should not happen). Adjusts bts_blkno & + * bts_offset if changed. Page split caller should insert its new + * pivot tuple for its new right sibling page on parent page, at the + * offset number bts_offset + 1. */ Buffer -_bt_getstackbuf(Relation rel, BTStack stack, int access) +_bt_getstackbuf(Relation rel, BTStack stack, BlockNumber child) { BlockNumber blkno; OffsetNumber start; @@ -1948,11 +1943,11 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access) Page page; BTPageOpaque opaque; - buf = _bt_getbuf(rel, blkno, access); + buf = _bt_getbuf(rel, blkno, BT_WRITE); page = BufferGetPage(buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); - if (access == BT_WRITE && P_INCOMPLETE_SPLIT(opaque)) + if (P_INCOMPLETE_SPLIT(opaque)) { _bt_finish_split(rel, buf, stack->bts_parent); continue; @@ -1996,7 +1991,7 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access) itemid = PageGetItemId(page, offnum); item = (IndexTuple) PageGetItem(page, itemid); - if (BTreeInnerTupleGetDownLink(item) == stack->bts_btentry) + if (BTreeInnerTupleGetDownLink(item) == child) { /* Return accurate pointer to where link is now */ stack->bts_blkno = blkno; @@ -2012,7 +2007,7 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access) itemid = PageGetItemId(page, offnum); item = (IndexTuple) PageGetItem(page, itemid); - if (BTreeInnerTupleGetDownLink(item) == stack->bts_btentry) + if (BTreeInnerTupleGetDownLink(item) == child) { /* Return accurate pointer to where link is now */ stack->bts_blkno = blkno; @@ -2024,6 +2019,9 @@ _bt_getstackbuf(Relation rel, BTStack stack, int access) /* * The item we're looking for moved right at least one page. + * + * Lehman and Yao couple/chain locks when moving right here, which we + * can avoid. See nbtree/README. */ if (P_RIGHTMOST(opaque)) { @@ -2090,10 +2088,6 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); - /* upgrade metapage if needed */ - if (metad->btm_version < BTREE_VERSION) - _bt_upgrademetapage(metapg); - /* * Create downlink item for left page (old root). Since this will be the * first item in a non-leaf page, it implicitly has minus-infinity key @@ -2103,7 +2097,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) left_item = (IndexTuple) palloc(left_item_sz); left_item->t_info = left_item_sz; BTreeInnerTupleSetDownLink(left_item, lbkno); - BTreeTupSetNAtts(left_item, 0); + BTreeTupleSetNAtts(left_item, 0); /* * Create downlink item for right page. The key for it is obtained from @@ -2118,6 +2112,10 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) /* NO EREPORT(ERROR) from here till newroot op is logged */ START_CRIT_SECTION(); + /* upgrade metapage if needed */ + if (metad->btm_version < BTREE_NOVAC_VERSION) + _bt_upgrademetapage(metapg); + /* set btree special data */ rootopaque = (BTPageOpaque) PageGetSpecialPointer(rootpage); rootopaque->btpo_prev = rootopaque->btpo_next = P_NONE; @@ -2140,6 +2138,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) * Note: we *must* insert the two items in item-number order, for the * benefit of _bt_restore_page(). */ + Assert(BTreeTupleGetNAtts(left_item, rel) == 0); if (PageAddItem(rootpage, (Item) left_item, left_item_sz, P_HIKEY, false, false) == InvalidOffsetNumber) elog(PANIC, "failed to add leftkey to new root page" @@ -2149,6 +2148,9 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) /* * insert the right page pointer into the new root page. */ + Assert(BTreeTupleGetNAtts(right_item, rel) > 0); + Assert(BTreeTupleGetNAtts(right_item, rel) <= + IndexRelationGetNumberOfKeyAttributes(rel)); if (PageAddItem(rootpage, (Item) right_item, right_item_sz, P_FIRSTKEY, false, false) == InvalidOffsetNumber) elog(PANIC, "failed to add rightkey to new root page" @@ -2180,6 +2182,8 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf) XLogRegisterBuffer(1, lbuf, REGBUF_STANDARD); XLogRegisterBuffer(2, metabuf, REGBUF_WILL_INIT | REGBUF_STANDARD); + Assert(metad->btm_version >= BTREE_NOVAC_VERSION); + md.version = metad->btm_version; md.root = rootblknum; md.level = metad->btm_level; md.fastroot = rootblknum; @@ -2244,7 +2248,8 @@ _bt_pgaddtup(Page page, { trunctuple = *itup; trunctuple.t_info = sizeof(IndexTupleData); - BTreeTupSetNAtts(&trunctuple, 0); + /* Deliberately zero INDEX_ALT_TID_MASK bits */ + BTreeTupleSetNAtts(&trunctuple, 0); itup = &trunctuple; itemsize = sizeof(IndexTupleData); } @@ -2256,66 +2261,6 @@ _bt_pgaddtup(Page page, return true; } -/* - * _bt_isequal - used in _bt_doinsert in check for duplicates. - * - * This is very similar to _bt_compare, except for NULL handling. - * Rule is simple: NOT_NULL not equal NULL, NULL not equal NULL too. - */ -static bool -_bt_isequal(Relation idxrel, Page page, OffsetNumber offnum, - int keysz, ScanKey scankey) -{ - TupleDesc itupdesc = RelationGetDescr(idxrel); - IndexTuple itup; - int i; - - /* Better be comparing to a leaf item */ - Assert(P_ISLEAF((BTPageOpaque) PageGetSpecialPointer(page))); - - itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); - - /* - * Index tuple shouldn't be truncated. Despite we technically could - * compare truncated tuple as well, this function should be only called - * for regular non-truncated leaf tuples and P_HIKEY tuple on - * rightmost leaf page. - */ - Assert((P_RIGHTMOST((BTPageOpaque) PageGetSpecialPointer(page)) || - offnum != P_HIKEY) - ? BTreeTupGetNAtts(itup, idxrel) == itupdesc->natts - : true); - - for (i = 1; i <= keysz; i++) - { - AttrNumber attno; - Datum datum; - bool isNull; - int32 result; - - attno = scankey->sk_attno; - Assert(attno == i); - datum = index_getattr(itup, attno, itupdesc, &isNull); - - /* NULLs are never equal to anything */ - if (isNull || (scankey->sk_flags & SK_ISNULL)) - return false; - - result = DatumGetInt32(FunctionCall2Coll(&scankey->sk_func, - scankey->sk_collation, - datum, - scankey->sk_argument)); - - if (result != 0) - return false; - - scankey++; - } - - /* if we get here, the keys are equal */ - return true; -} - /* * _bt_vacuum_one_page - vacuum just one index page. * @@ -2334,6 +2279,8 @@ _bt_vacuum_one_page(Relation rel, Buffer buffer, Relation heapRel) Page page = BufferGetPage(buffer); BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); + Assert(P_ISLEAF(opaque)); + /* * Scan over all items to see which ones need to be deleted according to * LP_DEAD flags. diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index ba689259127..268f869a36c 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -4,7 +4,7 @@ * BTree-specific page management code for the Postgres btree access * method. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -33,15 +33,15 @@ #include "storage/predicate.h" #include "utils/snapmgr.h" -static void _bt_cachemetadata(Relation rel, BTMetaPageData *metad); +static BTMetaPageData *_bt_getmeta(Relation rel, Buffer metabuf); static bool _bt_mark_page_halfdead(Relation rel, Buffer buf, BTStack stack); static bool _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, - bool *rightsib_empty); + bool *rightsib_empty); static bool _bt_lock_branch_parent(Relation rel, BlockNumber child, - BTStack stack, Buffer *topparent, OffsetNumber *topoff, - BlockNumber *target, BlockNumber *rightsib); + BTStack stack, Buffer *topparent, OffsetNumber *topoff, + BlockNumber *target, BlockNumber *rightsib); static void _bt_log_reuse_page(Relation rel, BlockNumber blkno, - TransactionId latestRemovedXid); + TransactionId latestRemovedXid); /* * _bt_initmetapage() -- Fill a page buffer with a correct metapage image @@ -77,7 +77,9 @@ _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level) } /* - * _bt_upgrademetapage() -- Upgrade a meta-page from an old format to the new. + * _bt_upgrademetapage() -- Upgrade a meta-page from an old format to version + * 3, the last version that can be updated without broadly affecting + * on-disk compatibility. (A REINDEX is required to upgrade to v4.) * * This routine does purely in-memory image upgrade. Caller is * responsible for locking, WAL-logging etc. @@ -93,11 +95,11 @@ _bt_upgrademetapage(Page page) /* It must be really a meta page of upgradable version */ Assert(metaopaque->btpo_flags & BTP_META); - Assert(metad->btm_version < BTREE_VERSION); + Assert(metad->btm_version < BTREE_NOVAC_VERSION); Assert(metad->btm_version >= BTREE_MIN_VERSION); /* Set version number and fill extra fields added into version 3 */ - metad->btm_version = BTREE_VERSION; + metad->btm_version = BTREE_NOVAC_VERSION; metad->btm_oldest_btpo_xact = InvalidTransactionId; metad->btm_last_cleanup_num_heap_tuples = -1.0; @@ -107,41 +109,42 @@ _bt_upgrademetapage(Page page) } /* - * Cache metadata from meta page to rel->rd_amcache. + * Get metadata from share-locked buffer containing metapage, while performing + * standard sanity checks. + * + * Callers that cache data returned here in local cache should note that an + * on-the-fly upgrade using _bt_upgrademetapage() can change the version field + * and BTREE_NOVAC_VERSION specific fields without invalidating local cache. */ -static void -_bt_cachemetadata(Relation rel, BTMetaPageData *metad) +static BTMetaPageData * +_bt_getmeta(Relation rel, Buffer metabuf) { - /* We assume rel->rd_amcache was already freed by caller */ - Assert(rel->rd_amcache == NULL); - rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt, - sizeof(BTMetaPageData)); + Page metapg; + BTPageOpaque metaopaque; + BTMetaPageData *metad; - /* - * Meta page should be of supported version (should be already checked by - * caller). - */ - Assert(metad->btm_version >= BTREE_MIN_VERSION && - metad->btm_version <= BTREE_VERSION); + metapg = BufferGetPage(metabuf); + metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg); + metad = BTPageGetMeta(metapg); - if (metad->btm_version == BTREE_VERSION) - { - /* Last version of meta-data, no need to upgrade */ - memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData)); - } - else - { - BTMetaPageData *cached_metad = (BTMetaPageData *) rel->rd_amcache; + /* sanity-check the metapage */ + if (!P_ISMETA(metaopaque) || + metad->btm_magic != BTREE_MAGIC) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("index \"%s\" is not a btree", + RelationGetRelationName(rel)))); - /* - * Upgrade meta-data: copy available information from meta-page and - * fill new fields with default values. - */ - memcpy(rel->rd_amcache, metad, offsetof(BTMetaPageData, btm_oldest_btpo_xact)); - cached_metad->btm_version = BTREE_VERSION; - cached_metad->btm_oldest_btpo_xact = InvalidTransactionId; - cached_metad->btm_last_cleanup_num_heap_tuples = -1.0; - } + if (metad->btm_version < BTREE_MIN_VERSION || + metad->btm_version > BTREE_VERSION) + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("version mismatch in index \"%s\": file version %d, " + "current version %d, minimal supported version %d", + RelationGetRelationName(rel), + metad->btm_version, BTREE_VERSION, BTREE_MIN_VERSION))); + + return metad; } /* @@ -155,11 +158,11 @@ void _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, float8 numHeapTuples) { - Buffer metabuf; - Page metapg; + Buffer metabuf; + Page metapg; BTMetaPageData *metad; - bool needsRewrite = false; - XLogRecPtr recptr; + bool needsRewrite = false; + XLogRecPtr recptr; /* read the metapage and check if it needs rewrite */ metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); @@ -167,7 +170,7 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, metad = BTPageGetMeta(metapg); /* outdated version of metapage always needs rewrite */ - if (metad->btm_version < BTREE_VERSION) + if (metad->btm_version < BTREE_NOVAC_VERSION) needsRewrite = true; else if (metad->btm_oldest_btpo_xact != oldestBtpoXact || metad->btm_last_cleanup_num_heap_tuples != numHeapTuples) @@ -186,10 +189,10 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, START_CRIT_SECTION(); /* upgrade meta-page if needed */ - if (metad->btm_version < BTREE_VERSION) + if (metad->btm_version < BTREE_NOVAC_VERSION) _bt_upgrademetapage(metapg); - /* update cleanup-related infromation */ + /* update cleanup-related information */ metad->btm_oldest_btpo_xact = oldestBtpoXact; metad->btm_last_cleanup_num_heap_tuples = numHeapTuples; MarkBufferDirty(metabuf); @@ -202,6 +205,8 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, XLogBeginInsert(); XLogRegisterBuffer(0, metabuf, REGBUF_WILL_INIT | REGBUF_STANDARD); + Assert(metad->btm_version >= BTREE_NOVAC_VERSION); + md.version = metad->btm_version; md.root = metad->btm_root; md.level = metad->btm_level; md.fastroot = metad->btm_fastroot; @@ -225,9 +230,7 @@ _bt_update_meta_cleanup_info(Relation rel, TransactionId oldestBtpoXact, * * Since the root page can move around the btree file, we have to read * its location from the metadata page, and then read the root page - * itself. If no root page exists yet, we have to create one. The - * standard class of race conditions exists here; I think I covered - * them all in the Hopi Indian rain dance of lock requests below. + * itself. If no root page exists yet, we have to create one. * * The access type parameter (BT_READ or BT_WRITE) controls whether * a new root page will be created or not. If access = BT_READ, @@ -252,8 +255,6 @@ Buffer _bt_getroot(Relation rel, int access) { Buffer metabuf; - Page metapg; - BTPageOpaque metaopaque; Buffer rootbuf; Page rootpage; BTPageOpaque rootopaque; @@ -306,30 +307,13 @@ _bt_getroot(Relation rel, int access) } metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); - metapg = BufferGetPage(metabuf); - metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg); - metad = BTPageGetMeta(metapg); - - /* sanity-check the metapage */ - if (!P_ISMETA(metaopaque) || - metad->btm_magic != BTREE_MAGIC) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("index \"%s\" is not a btree", - RelationGetRelationName(rel)))); - - if (metad->btm_version < BTREE_MIN_VERSION || - metad->btm_version > BTREE_VERSION) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("version mismatch in index \"%s\": file version %d, " - "current version %d, minimal supported version %d", - RelationGetRelationName(rel), - metad->btm_version, BTREE_VERSION, BTREE_MIN_VERSION))); + metad = _bt_getmeta(rel, metabuf); /* if no root page initialized yet, do it */ if (metad->btm_root == P_NONE) { + Page metapg; + /* If access = BT_READ, caller doesn't want us to create root yet */ if (access == BT_READ) { @@ -341,10 +325,6 @@ _bt_getroot(Relation rel, int access) LockBuffer(metabuf, BUFFER_LOCK_UNLOCK); LockBuffer(metabuf, BT_WRITE); - /* upgrade metapage if needed */ - if (metad->btm_version < BTREE_VERSION) - _bt_upgrademetapage(metapg); - /* * Race condition: if someone else initialized the metadata between * the time we released the read lock and acquired the write lock, we @@ -375,10 +355,16 @@ _bt_getroot(Relation rel, int access) rootopaque->btpo_flags = (BTP_LEAF | BTP_ROOT); rootopaque->btpo.level = 0; rootopaque->btpo_cycleid = 0; + /* Get raw page pointer for metapage */ + metapg = BufferGetPage(metabuf); /* NO ELOG(ERROR) till meta is updated */ START_CRIT_SECTION(); + /* upgrade metapage if needed */ + if (metad->btm_version < BTREE_NOVAC_VERSION) + _bt_upgrademetapage(metapg); + metad->btm_root = rootblkno; metad->btm_level = 0; metad->btm_fastroot = rootblkno; @@ -400,6 +386,8 @@ _bt_getroot(Relation rel, int access) XLogRegisterBuffer(0, rootbuf, REGBUF_WILL_INIT); XLogRegisterBuffer(2, metabuf, REGBUF_WILL_INIT | REGBUF_STANDARD); + Assert(metad->btm_version >= BTREE_NOVAC_VERSION); + md.version = metad->btm_version; md.root = rootblkno; md.level = 0; md.fastroot = rootblkno; @@ -430,7 +418,7 @@ _bt_getroot(Relation rel, int access) LockBuffer(rootbuf, BUFFER_LOCK_UNLOCK); LockBuffer(rootbuf, BT_READ); - /* okay, metadata is correct, release lock on it */ + /* okay, metadata is correct, release lock on it without caching */ _bt_relbuf(rel, metabuf); } else @@ -442,7 +430,9 @@ _bt_getroot(Relation rel, int access) /* * Cache the metapage data for next time */ - _bt_cachemetadata(rel, metad); + rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt, + sizeof(BTMetaPageData)); + memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData)); /* * We are done with the metapage; arrange to release it via first @@ -595,37 +585,12 @@ _bt_getrootheight(Relation rel) { BTMetaPageData *metad; - /* - * We can get what we need from the cached metapage data. If it's not - * cached yet, load it. Sanity checks here must match _bt_getroot(). - */ if (rel->rd_amcache == NULL) { Buffer metabuf; - Page metapg; - BTPageOpaque metaopaque; metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); - metapg = BufferGetPage(metabuf); - metaopaque = (BTPageOpaque) PageGetSpecialPointer(metapg); - metad = BTPageGetMeta(metapg); - - /* sanity-check the metapage */ - if (!P_ISMETA(metaopaque) || - metad->btm_magic != BTREE_MAGIC) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("index \"%s\" is not a btree", - RelationGetRelationName(rel)))); - - if (metad->btm_version < BTREE_MIN_VERSION || - metad->btm_version > BTREE_VERSION) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg("version mismatch in index \"%s\": file version %d, " - "current version %d, minimal supported version %d", - RelationGetRelationName(rel), - metad->btm_version, BTREE_VERSION, BTREE_MIN_VERSION))); + metad = _bt_getmeta(rel, metabuf); /* * If there's no root page yet, _bt_getroot() doesn't expect a cache @@ -641,20 +606,83 @@ _bt_getrootheight(Relation rel) /* * Cache the metapage data for next time */ - _bt_cachemetadata(rel, metad); - + rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt, + sizeof(BTMetaPageData)); + memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData)); _bt_relbuf(rel, metabuf); } + /* Get cached page */ metad = (BTMetaPageData *) rel->rd_amcache; /* We shouldn't have cached it if any of these fail */ Assert(metad->btm_magic == BTREE_MAGIC); - Assert(metad->btm_version == BTREE_VERSION); + Assert(metad->btm_version >= BTREE_MIN_VERSION); + Assert(metad->btm_version <= BTREE_VERSION); Assert(metad->btm_fastroot != P_NONE); return metad->btm_fastlevel; } +/* + * _bt_heapkeyspace() -- is heap TID being treated as a key? + * + * This is used to determine the rules that must be used to descend a + * btree. Version 4 indexes treat heap TID as a tiebreaker attribute. + * pg_upgrade'd version 3 indexes need extra steps to preserve reasonable + * performance when inserting a new BTScanInsert-wise duplicate tuple + * among many leaf pages already full of such duplicates. + */ +bool +_bt_heapkeyspace(Relation rel) +{ + BTMetaPageData *metad; + + if (rel->rd_amcache == NULL) + { + Buffer metabuf; + + metabuf = _bt_getbuf(rel, BTREE_METAPAGE, BT_READ); + metad = _bt_getmeta(rel, metabuf); + + /* + * If there's no root page yet, _bt_getroot() doesn't expect a cache + * to be made, so just stop here. (XXX perhaps _bt_getroot() should + * be changed to allow this case.) + */ + if (metad->btm_root == P_NONE) + { + uint32 btm_version = metad->btm_version; + + _bt_relbuf(rel, metabuf); + return btm_version > BTREE_NOVAC_VERSION; + } + + /* + * Cache the metapage data for next time + * + * An on-the-fly version upgrade performed by _bt_upgrademetapage() + * can change the nbtree version for an index without invalidating any + * local cache. This is okay because it can only happen when moving + * from version 2 to version 3, both of which are !heapkeyspace + * versions. + */ + rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt, + sizeof(BTMetaPageData)); + memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData)); + _bt_relbuf(rel, metabuf); + } + + /* Get cached page */ + metad = (BTMetaPageData *) rel->rd_amcache; + /* We shouldn't have cached it if any of these fail */ + Assert(metad->btm_magic == BTREE_MAGIC); + Assert(metad->btm_version >= BTREE_MIN_VERSION); + Assert(metad->btm_version <= BTREE_VERSION); + Assert(metad->btm_fastroot != P_NONE); + + return metad->btm_version > BTREE_NOVAC_VERSION; +} + /* * _bt_checkpage() -- Verify that a freshly-read page looks sane. */ @@ -782,9 +810,14 @@ _bt_getbuf(Relation rel, BlockNumber blkno, int access) /* * If we are generating WAL for Hot Standby then create a * WAL record that will allow us to conflict with queries - * running on standby. + * running on standby, in case they have snapshots older + * than btpo.xact. This can only apply if the page does + * have a valid btpo.xact value, ie not if it's new. (We + * must check that because an all-zero page has no special + * space.) */ - if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) + if (XLogStandbyInfoActive() && RelationNeedsWAL(rel) && + !PageIsNew(page)) { BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); @@ -897,7 +930,10 @@ _bt_pageinit(Page page, Size size) * _bt_page_recyclable() -- Is an existing page recyclable? * * This exists to make sure _bt_getbuf and btvacuumscan have the same - * policy about whether a page is safe to re-use. + * policy about whether a page is safe to re-use. But note that _bt_getbuf + * knows enough to distinguish the PageIsNew condition from the other one. + * At some point it might be appropriate to redesign this to have a three-way + * result value. */ bool _bt_page_recyclable(Page page) @@ -1024,10 +1060,16 @@ _bt_delitems_delete(Relation rel, Buffer buf, { Page page = BufferGetPage(buf); BTPageOpaque opaque; + TransactionId latestRemovedXid = InvalidTransactionId; /* Shouldn't be called unless there's something to do */ Assert(nitems > 0); + if (XLogStandbyInfoActive() && RelationNeedsWAL(rel)) + latestRemovedXid = + index_compute_xid_horizon_for_tuples(rel, heapRel, buf, + itemnos, nitems); + /* No ereport(ERROR) until changes are logged */ START_CRIT_SECTION(); @@ -1057,7 +1099,7 @@ _bt_delitems_delete(Relation rel, Buffer buf, XLogRecPtr recptr; xl_btree_delete xlrec_delete; - xlrec_delete.hnode = heapRel->rd_node; + xlrec_delete.latestRemovedXid = latestRemovedXid; xlrec_delete.nitems = nitems; XLogBeginInsert(); @@ -1115,9 +1157,11 @@ _bt_is_page_halfdead(Relation rel, BlockNumber blk) * right sibling. * * "child" is the leaf page we wish to delete, and "stack" is a search stack - * leading to it (approximately). Note that we will update the stack - * entry(s) to reflect current downlink positions --- this is harmless and - * indeed saves later search effort in _bt_pagedel. The caller should + * leading to it (it actually leads to the leftmost leaf page with a high key + * matching that of the page to be deleted in !heapkeyspace indexes). Note + * that we will update the stack entry(s) to reflect current downlink + * positions --- this is essentially the same as the corresponding step of + * splitting, and is not expected to affect caller. The caller should * initialize *target and *rightsib to the leaf page and its right sibling. * * Note: it's OK to release page locks on any internal pages between the leaf @@ -1140,14 +1184,17 @@ _bt_lock_branch_parent(Relation rel, BlockNumber child, BTStack stack, BlockNumber leftsib; /* - * Locate the downlink of "child" in the parent (updating the stack entry - * if needed) + * Locate the downlink of "child" in the parent, updating the stack entry + * if needed. This is how !heapkeyspace indexes deal with having + * non-unique high keys in leaf level pages. Even heapkeyspace indexes + * can have a stale stack due to insertions into the parent. */ - stack->bts_btentry = child; - pbuf = _bt_getstackbuf(rel, stack, BT_WRITE); + pbuf = _bt_getstackbuf(rel, stack, child); if (pbuf == InvalidBuffer) - elog(ERROR, "failed to re-find parent key in index \"%s\" for deletion target page %u", - RelationGetRelationName(rel), child); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("failed to re-find parent key in index \"%s\" for deletion target page %u", + RelationGetRelationName(rel), child))); parent = stack->bts_blkno; poffset = stack->bts_offset; @@ -1214,17 +1261,6 @@ _bt_lock_branch_parent(Relation rel, BlockNumber child, BTStack stack, _bt_relbuf(rel, lbuf); } - /* - * Perform the same check on this internal level that - * _bt_mark_page_halfdead performed on the leaf level. - */ - if (_bt_is_page_halfdead(rel, *rightsib)) - { - elog(DEBUG1, "could not delete page %u because its right sibling %u is half-dead", - parent, *rightsib); - return false; - } - return _bt_lock_branch_parent(rel, parent, stack->bts_parent, topparent, topoff, target, rightsib); } @@ -1353,16 +1389,17 @@ _bt_pagedel(Relation rel, Buffer buf) { /* * We need an approximate pointer to the page's parent page. We - * use the standard search mechanism to search for the page's high - * key; this will give us a link to either the current parent or - * someplace to its left (if there are multiple equal high keys). + * use a variant of the standard search mechanism to search for + * the page's high key; this will give us a link to either the + * current parent or someplace to its left (if there are multiple + * equal high keys, which is possible with !heapkeyspace indexes). * * Also check if this is the right-half of an incomplete split * (see comment above). */ if (!stack) { - ScanKey itup_scankey; + BTScanInsert itup_key; ItemId itemid; IndexTuple targetkey; Buffer lbuf; @@ -1412,12 +1449,11 @@ _bt_pagedel(Relation rel, Buffer buf) } /* we need an insertion scan key for the search, so build one */ - itup_scankey = _bt_mkscankey(rel, targetkey); - /* find the leftmost leaf page containing this key */ - stack = _bt_search(rel, - IndexRelationGetNumberOfKeyAttributes(rel), - itup_scankey, false, &lbuf, BT_READ, NULL); - /* don't need a pin on the page */ + itup_key = _bt_mkscankey(rel, targetkey); + /* find the leftmost leaf page with matching pivot/high key */ + itup_key->pivotsearch = true; + stack = _bt_search(rel, itup_key, &lbuf, BT_READ, NULL); + /* don't need a lock or second pin on the page */ _bt_relbuf(rel, lbuf); /* @@ -1443,6 +1479,7 @@ _bt_pagedel(Relation rel, Buffer buf) rightsib_empty = false; while (P_ISHALFDEAD(opaque)) { + /* will check for interrupts, once lock is released */ if (!_bt_unlink_halfdead_page(rel, buf, &rightsib_empty)) { /* _bt_unlink_halfdead_page already released buffer */ @@ -1455,6 +1492,12 @@ _bt_pagedel(Relation rel, Buffer buf) _bt_relbuf(rel, buf); + /* + * Check here, as calling loops will have locks held, preventing + * interrupts from being processed. + */ + CHECK_FOR_INTERRUPTS(); + /* * The page has now been deleted. If its right sibling is completely * empty, it's possible that the reason we haven't deleted it earlier @@ -1527,7 +1570,17 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) * parent, unless it is the only child --- in which case the parent has to * be deleted too, and the same condition applies recursively to it. We * have to check this condition all the way up before trying to delete, - * and lock the final parent of the to-be-deleted branch. + * and lock the final parent of the to-be-deleted subtree. + * + * However, we won't need to repeat the above _bt_is_page_halfdead() check + * for parent/ancestor pages because of the rightmost restriction. The + * leaf check will apply to a right "cousin" leaf page rather than a + * simple right sibling leaf page in cases where we actually go on to + * perform internal page deletion. The right cousin leaf page is + * representative of the left edge of the subtree to the right of the + * to-be-deleted subtree as a whole. (Besides, internal pages are never + * marked half-dead, so it isn't even possible to directly assess if an + * internal page is part of some other to-be-deleted subtree.) */ rightsib = leafrightsib; target = leafblkno; @@ -1559,9 +1612,11 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) itemid = PageGetItemId(page, nextoffset); itup = (IndexTuple) PageGetItem(page, itemid); if (BTreeInnerTupleGetDownLink(itup) != rightsib) - elog(ERROR, "right sibling %u of block %u is not next child %u of block %u in index \"%s\"", - rightsib, target, BTreeInnerTupleGetDownLink(itup), - BufferGetBlockNumber(topparent), RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling %u of block %u is not next child %u of block %u in index \"%s\"", + rightsib, target, BTreeInnerTupleGetDownLink(itup), + BufferGetBlockNumber(topparent), RelationGetRelationName(rel)))); /* * Any insert which would have gone on the leaf block will now go to its @@ -1597,17 +1652,17 @@ _bt_mark_page_halfdead(Relation rel, Buffer leafbuf, BTStack stack) opaque = (BTPageOpaque) PageGetSpecialPointer(page); opaque->btpo_flags |= BTP_HALF_DEAD; - PageIndexTupleDelete(page, P_HIKEY); - Assert(PageGetMaxOffsetNumber(page) == 0); + Assert(PageGetMaxOffsetNumber(page) == P_HIKEY); MemSet(&trunctuple, 0, sizeof(IndexTupleData)); trunctuple.t_info = sizeof(IndexTupleData); if (target != leafblkno) - ItemPointerSetBlockNumber(&trunctuple.t_tid, target); + BTreeTupleSetTopParent(&trunctuple, target); else - ItemPointerSetInvalid(&trunctuple.t_tid); - if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY, - false, false) == InvalidOffsetNumber) - elog(ERROR, "could not add dummy high key to half-dead page"); + BTreeTupleSetTopParent(&trunctuple, InvalidBlockNumber); + + if (!PageIndexTupleOverwrite(page, P_HIKEY, (Item) &trunctuple, + IndexTupleSize(&trunctuple))) + elog(ERROR, "could not overwrite high key in half-dead page"); /* Must mark buffers dirty before XLogInsert */ MarkBufferDirty(topparent); @@ -1688,7 +1743,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) BTPageOpaque opaque; bool rightsib_is_rightmost; int targetlevel; - ItemPointer leafhikey; + IndexTuple leafhikey; BlockNumber nextchild; page = BufferGetPage(leafbuf); @@ -1700,21 +1755,28 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) * Remember some information about the leaf page. */ itemid = PageGetItemId(page, P_HIKEY); - leafhikey = &((IndexTuple) PageGetItem(page, itemid))->t_tid; + leafhikey = (IndexTuple) PageGetItem(page, itemid); leafleftsib = opaque->btpo_prev; leafrightsib = opaque->btpo_next; LockBuffer(leafbuf, BUFFER_LOCK_UNLOCK); + /* + * Check here, as calling loops will have locks held, preventing + * interrupts from being processed. + */ + CHECK_FOR_INTERRUPTS(); + /* * If the leaf page still has a parent pointing to it (or a chain of * parents), we don't unlink the leaf page yet, but the topmost remaining * parent in the branch. Set 'target' and 'buf' to reference the page * actually being unlinked. */ - if (ItemPointerIsValid(leafhikey)) + target = BTreeTupleGetTopParent(leafhikey); + + if (target != InvalidBlockNumber) { - target = ItemPointerGetBlockNumberNoCheck(leafhikey); Assert(target != leafblkno); /* fetch the block number of the topmost parent's left sibling */ @@ -1764,6 +1826,14 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) /* step right one page */ leftsib = opaque->btpo_next; _bt_relbuf(rel, lbuf); + + /* + * It'd be good to check for interrupts here, but it's not easy to + * do so because a lock is always held. This block isn't + * frequently reached, so hopefully the consequences of not + * checking interrupts aren't too bad. + */ + if (leftsib == P_NONE) { elog(LOG, "no left sibling (concurrent deletion?) of block %u in \"%s\"", @@ -1810,8 +1880,10 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) target, RelationGetRelationName(rel)); } if (opaque->btpo_prev != leftsib) - elog(ERROR, "left link changed unexpectedly in block %u of index \"%s\"", - target, RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("left link changed unexpectedly in block %u of index \"%s\"", + target, RelationGetRelationName(rel)))); if (target == leafblkno) { @@ -1843,10 +1915,12 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) page = BufferGetPage(rbuf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); if (opaque->btpo_prev != target) - elog(ERROR, "right sibling's left-link doesn't match: " - "block %u links to %u instead of expected %u in index \"%s\"", - rightsib, opaque->btpo_prev, target, - RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("right sibling's left-link doesn't match: " + "block %u links to %u instead of expected %u in index \"%s\"", + rightsib, opaque->btpo_prev, target, + RelationGetRelationName(rel)))); rightsib_is_rightmost = P_RIGHTMOST(opaque); *rightsib_empty = (P_FIRSTDATAKEY(opaque) > PageGetMaxOffsetNumber(page)); @@ -1856,9 +1930,6 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) * might be possible to push the fast root even further down, but the odds * of doing so are slim, and the locking considerations daunting.) * - * We don't support handling this in the case where the parent is becoming - * half-dead, even though it theoretically could occur. - * * We can safely acquire a lock on the metapage here --- see comments for * _bt_newroot(). */ @@ -1917,12 +1988,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) * branch. */ if (target != leafblkno) - { - if (nextchild == InvalidBlockNumber) - ItemPointerSetInvalid(leafhikey); - else - ItemPointerSetBlockNumber(leafhikey, nextchild); - } + BTreeTupleSetTopParent(leafhikey, nextchild); /* * Mark the page itself deleted. It can be recycled when all current @@ -1944,7 +2010,7 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) if (BufferIsValid(metabuf)) { /* upgrade metapage if needed */ - if (metad->btm_version < BTREE_VERSION) + if (metad->btm_version < BTREE_NOVAC_VERSION) _bt_upgrademetapage(metapg); metad->btm_fastroot = rightsib; metad->btm_fastlevel = targetlevel; @@ -1992,6 +2058,8 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) { XLogRegisterBuffer(4, metabuf, REGBUF_WILL_INIT | REGBUF_STANDARD); + Assert(metad->btm_version >= BTREE_NOVAC_VERSION); + xlmeta.version = metad->btm_version; xlmeta.root = metad->btm_root; xlmeta.level = metad->btm_level; xlmeta.fastroot = metad->btm_fastroot; diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index d97f5249deb..4cfd5289ad7 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -8,7 +8,7 @@ * This file contains only the public interface routines. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,6 +22,7 @@ #include "access/nbtxlog.h" #include "access/relscan.h" #include "access/xlog.h" +#include "commands/progress.h" #include "commands/vacuum.h" #include "miscadmin.h" #include "nodes/execnodes.h" @@ -92,10 +93,10 @@ typedef struct BTParallelScanDescData *BTParallelScanDesc; static void btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, void *callback_state, - BTCycleId cycleid, TransactionId *oldestBtpoXact); + IndexBulkDeleteCallback callback, void *callback_state, + BTCycleId cycleid, TransactionId *oldestBtpoXact); static void btvacuumpage(BTVacState *vstate, BlockNumber blkno, - BlockNumber orig_blkno); + BlockNumber orig_blkno); /* @@ -133,6 +134,7 @@ bthandler(PG_FUNCTION_ARGS) amroutine->amcostestimate = btcostestimate; amroutine->amoptions = btoptions; amroutine->amproperty = btproperty; + amroutine->ambuildphasename = btbuildphasename; amroutine->amvalidate = btvalidate; amroutine->ambeginscan = btbeginscan; amroutine->amrescan = btrescan; @@ -310,7 +312,7 @@ btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm) if (_bt_first(scan, ForwardScanDirection)) { /* Save tuple ID, and continue scanning */ - heapTid = &scan->xs_ctup.t_self; + heapTid = &scan->xs_heaptid; tbm_add_tuples(tbm, heapTid, 1, false); ntids++; @@ -619,8 +621,8 @@ btparallelrescan(IndexScanDesc scan) /* * _bt_parallel_seize() -- Begin the process of advancing the scan to a new - * page. Other scans must wait until we call bt_parallel_release() or - * bt_parallel_done(). + * page. Other scans must wait until we call _bt_parallel_release() + * or _bt_parallel_done(). * * The return value is true if we successfully seized the scan and false * if we did not. The latter case occurs if no pages remain for the current @@ -785,16 +787,16 @@ _bt_parallel_advance_array_keys(IndexScanDesc scan) static bool _bt_vacuum_needs_cleanup(IndexVacuumInfo *info) { - Buffer metabuf; - Page metapg; + Buffer metabuf; + Page metapg; BTMetaPageData *metad; - bool result = false; + bool result = false; metabuf = _bt_getbuf(info->index, BTREE_METAPAGE, BT_READ); metapg = BufferGetPage(metabuf); metad = BTPageGetMeta(metapg); - if (metad->btm_version < BTREE_VERSION) + if (metad->btm_version < BTREE_NOVAC_VERSION) { /* * Do cleanup if metapage needs upgrade, because we don't have @@ -814,25 +816,28 @@ _bt_vacuum_needs_cleanup(IndexVacuumInfo *info) } else { - StdRdOptions *relopts; - float8 cleanup_scale_factor; + StdRdOptions *relopts; + float8 cleanup_scale_factor; + float8 prev_num_heap_tuples; /* - * If table receives large enough amount of insertions and no cleanup - * was performed, then index might appear to have stalled statistics. - * In order to evade that, we perform cleanup when table receives - * vacuum_cleanup_index_scale_factor fractions of insertions. + * If table receives enough insertions and no cleanup was performed, + * then index would appear have stale statistics. If scale factor is + * set, we avoid that by performing cleanup if the number of inserted + * tuples exceeds vacuum_cleanup_index_scale_factor fraction of + * original tuples count. */ relopts = (StdRdOptions *) info->index->rd_options; cleanup_scale_factor = (relopts && - relopts->vacuum_cleanup_index_scale_factor >= 0) - ? relopts->vacuum_cleanup_index_scale_factor - : vacuum_cleanup_index_scale_factor; - - if (cleanup_scale_factor < 0 || - metad->btm_last_cleanup_num_heap_tuples < 0 || - info->num_heap_tuples > (1.0 + cleanup_scale_factor) * - metad->btm_last_cleanup_num_heap_tuples) + relopts->vacuum_cleanup_index_scale_factor >= 0) + ? relopts->vacuum_cleanup_index_scale_factor + : vacuum_cleanup_index_scale_factor; + prev_num_heap_tuples = metad->btm_last_cleanup_num_heap_tuples; + + if (cleanup_scale_factor <= 0 || + prev_num_heap_tuples <= 0 || + (info->num_heap_tuples - prev_num_heap_tuples) / + prev_num_heap_tuples >= cleanup_scale_factor) result = true; } @@ -862,7 +867,7 @@ btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, /* The ENSURE stuff ensures we clean up shared memory on failure */ PG_ENSURE_ERROR_CLEANUP(_bt_end_vacuum_callback, PointerGetDatum(rel)); { - TransactionId oldestBtpoXact; + TransactionId oldestBtpoXact; cycleid = _bt_start_vacuum(rel); @@ -870,8 +875,8 @@ btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, &oldestBtpoXact); /* - * Update cleanup-related information in metapage. These information - * is used only for cleanup but keeping up them to date can avoid + * Update cleanup-related information in metapage. This information is + * used only for cleanup but keeping them up to date can avoid * unnecessary cleanup even after bulkdelete. */ _bt_update_meta_cleanup_info(info->index, oldestBtpoXact, @@ -899,15 +904,15 @@ btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) * If btbulkdelete was called, we need not do anything, just return the * stats from the latest btbulkdelete call. If it wasn't called, we might * still need to do a pass over the index, to recycle any newly-recyclable - * pages and to obtain index statistics. _bt_vacuum_needs_cleanup checks - * is there are newly-recyclable or stalled index statistics. + * pages or to obtain index statistics. _bt_vacuum_needs_cleanup + * determines if either are needed. * * Since we aren't going to actually delete any leaf items, there's no * need to go through all the vacuum-cycle-ID pushups. */ if (stats == NULL) { - TransactionId oldestBtpoXact; + TransactionId oldestBtpoXact; /* Check if we need a cleanup */ if (!_bt_vacuum_needs_cleanup(info)) @@ -1018,6 +1023,10 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, if (needLock) UnlockRelationForExtension(rel, ExclusiveLock); + if (info->report_progress) + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_TOTAL, + num_pages); + /* Quit if we've scanned the whole relation */ if (blkno >= num_pages) break; @@ -1025,6 +1034,9 @@ btvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, for (; blkno < num_pages; blkno++) { btvacuumpage(&vstate, blkno, blkno); + if (info->report_progress) + pgstat_progress_update_param(PROGRESS_SCAN_BLOCKS_DONE, + blkno); } } diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c index 4c6fdcdd8aa..8e512461a0e 100644 --- a/src/backend/access/nbtree/nbtsearch.c +++ b/src/backend/access/nbtree/nbtsearch.c @@ -4,7 +4,7 @@ * Search code for postgres btrees. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,20 +22,20 @@ #include "storage/predicate.h" #include "utils/lsyscache.h" #include "utils/rel.h" -#include "utils/tqual.h" +static void _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp); +static OffsetNumber _bt_binsrch(Relation rel, BTScanInsert key, Buffer buf); static bool _bt_readpage(IndexScanDesc scan, ScanDirection dir, - OffsetNumber offnum); + OffsetNumber offnum); static void _bt_saveitem(BTScanOpaque so, int itemIndex, - OffsetNumber offnum, IndexTuple itup); + OffsetNumber offnum, IndexTuple itup); static bool _bt_steppage(IndexScanDesc scan, ScanDirection dir); static bool _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir); static bool _bt_parallel_readpage(IndexScanDesc scan, BlockNumber blkno, - ScanDirection dir); + ScanDirection dir); static Buffer _bt_walk_left(Relation rel, Buffer buf, Snapshot snapshot); static bool _bt_endpoint(IndexScanDesc scan, ScanDirection dir); -static void _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp); static inline void _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir); @@ -67,18 +67,13 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp) } } - /* * _bt_search() -- Search the tree for a particular scankey, * or more precisely for the first leaf page it could be on. * - * The passed scankey must be an insertion-type scankey (see nbtree/README), + * The passed scankey is an insertion-type scankey (see nbtree/README), * but it can omit the rightmost column(s) of the index. * - * When nextkey is false (the usual case), we are looking for the first - * item >= scankey. When nextkey is true, we are looking for the first - * item strictly greater than scankey. - * * Return value is a stack of parent-page pointers. *bufP is set to the * address of the leaf-page buffer, which is read-locked and pinned. * No locks are held on the parent pages, however! @@ -87,17 +82,18 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp) * place during the descent through the tree. This is not needed when * positioning for an insert or delete, so NULL is used for those cases. * - * NOTE that the returned buffer is read-locked regardless of the access - * parameter. However, access = BT_WRITE will allow an empty root page - * to be created and returned. When access = BT_READ, an empty index - * will result in *bufP being set to InvalidBuffer. Also, in BT_WRITE mode, - * any incomplete splits encountered during the search will be finished. + * The returned buffer is locked according to access parameter. Additionally, + * access = BT_WRITE will allow an empty root page to be created and returned. + * When access = BT_READ, an empty index will result in *bufP being set to + * InvalidBuffer. Also, in BT_WRITE mode, any incomplete splits encountered + * during the search will be finished. */ BTStack -_bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, - Buffer *bufP, int access, Snapshot snapshot) +_bt_search(Relation rel, BTScanInsert key, Buffer *bufP, int access, + Snapshot snapshot) { BTStack stack_in = NULL; + int page_access = BT_READ; /* Get the root page to start with */ *bufP = _bt_getroot(rel, access); @@ -130,9 +126,8 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, * if the leaf page is split and we insert to the parent page). But * this is a good opportunity to finish splits of internal pages too. */ - *bufP = _bt_moveright(rel, *bufP, keysz, scankey, nextkey, - (access == BT_WRITE), stack_in, - BT_READ, snapshot); + *bufP = _bt_moveright(rel, key, *bufP, (access == BT_WRITE), stack_in, + page_access, snapshot); /* if this is a leaf page, we're done */ page = BufferGetPage(*bufP); @@ -144,35 +139,62 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, * Find the appropriate item on the internal page, and get the child * page that it points to. */ - offnum = _bt_binsrch(rel, *bufP, keysz, scankey, nextkey); + offnum = _bt_binsrch(rel, key, *bufP); itemid = PageGetItemId(page, offnum); itup = (IndexTuple) PageGetItem(page, itemid); blkno = BTreeInnerTupleGetDownLink(itup); par_blkno = BufferGetBlockNumber(*bufP); /* - * We need to save the location of the index entry we chose in the - * parent page on a stack. In case we split the tree, we'll use the - * stack to work back up to the parent page. We also save the actual - * downlink (TID) to uniquely identify the index entry, in case it - * moves right while we're working lower in the tree. See the paper - * by Lehman and Yao for how this is detected and handled. (We use the - * child link to disambiguate duplicate keys in the index -- Lehman - * and Yao disallow duplicate keys.) + * We need to save the location of the pivot tuple we chose in the + * parent page on a stack. If we need to split a page, we'll use + * the stack to work back up to its parent page. If caller ends up + * splitting a page one level down, it usually ends up inserting a + * new pivot tuple/downlink immediately after the location recorded + * here. */ new_stack = (BTStack) palloc(sizeof(BTStackData)); new_stack->bts_blkno = par_blkno; new_stack->bts_offset = offnum; - new_stack->bts_btentry = blkno; new_stack->bts_parent = stack_in; + /* + * Page level 1 is lowest non-leaf page level prior to leaves. So, if + * we're on the level 1 and asked to lock leaf page in write mode, + * then lock next page in write mode, because it must be a leaf. + */ + if (opaque->btpo.level == 1 && access == BT_WRITE) + page_access = BT_WRITE; + /* drop the read lock on the parent page, acquire one on the child */ - *bufP = _bt_relandgetbuf(rel, *bufP, blkno, BT_READ); + *bufP = _bt_relandgetbuf(rel, *bufP, blkno, page_access); /* okay, all set to move down a level */ stack_in = new_stack; } + /* + * If we're asked to lock leaf in write mode, but didn't manage to, then + * relock. This should only happen when the root page is a leaf page (and + * the only page in the index other than the metapage). + */ + if (access == BT_WRITE && page_access == BT_READ) + { + /* trade in our read lock for a write lock */ + LockBuffer(*bufP, BUFFER_LOCK_UNLOCK); + LockBuffer(*bufP, BT_WRITE); + + /* + * If the page was split between the time that we surrendered our read + * lock and acquired our write lock, then this page may no longer be + * the right place for the key we want to insert. In this case, we + * need to move right in the tree. See Lehman and Yao for an + * excruciatingly precise description. + */ + *bufP = _bt_moveright(rel, key, *bufP, true, stack_in, BT_WRITE, + snapshot); + } + return stack_in; } @@ -186,16 +208,17 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, * or strictly to the right of it. * * This routine decides whether or not we need to move right in the - * tree by examining the high key entry on the page. If that entry - * is strictly less than the scankey, or <= the scankey in the nextkey=true - * case, then we followed the wrong link and we need to move right. + * tree by examining the high key entry on the page. If that entry is + * strictly less than the scankey, or <= the scankey in the + * key.nextkey=true case, then we followed the wrong link and we need + * to move right. * - * The passed scankey must be an insertion-type scankey (see nbtree/README), - * but it can omit the rightmost column(s) of the index. + * The passed insertion-type scankey can omit the rightmost column(s) of the + * index. (see nbtree/README) * - * When nextkey is false (the usual case), we are looking for the first - * item >= scankey. When nextkey is true, we are looking for the first - * item strictly greater than scankey. + * When key.nextkey is false (the usual case), we are looking for the first + * item >= key. When key.nextkey is true, we are looking for the first item + * strictly greater than key. * * If forupdate is true, we will attempt to finish any incomplete splits * that we encounter. This is required when locking a target page for an @@ -212,10 +235,8 @@ _bt_search(Relation rel, int keysz, ScanKey scankey, bool nextkey, */ Buffer _bt_moveright(Relation rel, + BTScanInsert key, Buffer buf, - int keysz, - ScanKey scankey, - bool nextkey, bool forupdate, BTStack stack, int access, @@ -228,11 +249,13 @@ _bt_moveright(Relation rel, /* * When nextkey = false (normal case): if the scan key that brought us to * this page is > the high key stored on the page, then the page has split - * and we need to move right. (If the scan key is equal to the high key, - * we might or might not need to move right; have to scan the page first - * anyway.) + * and we need to move right. (pg_upgrade'd !heapkeyspace indexes could + * have some duplicates to the right as well as the left, but that's + * something that's only ever dealt with on the leaf level, after + * _bt_search has found an initial leaf page.) * * When nextkey = true: move right if the scan key is >= page's high key. + * (Note that key.scantid cannot be set in this case.) * * The page could even have split more than once, so scan as far as * needed. @@ -240,7 +263,7 @@ _bt_moveright(Relation rel, * We also have to move right if we followed a link that brought us to a * dead page. */ - cmpval = nextkey ? 0 : 1; + cmpval = key->nextkey ? 0 : 1; for (;;) { @@ -275,7 +298,7 @@ _bt_moveright(Relation rel, continue; } - if (P_IGNORE(opaque) || _bt_compare(rel, keysz, scankey, page, P_HIKEY) >= cmpval) + if (P_IGNORE(opaque) || _bt_compare(rel, key, page, P_HIKEY) >= cmpval) { /* step right one page */ buf = _bt_relandgetbuf(rel, buf, opaque->btpo_next, access); @@ -295,13 +318,6 @@ _bt_moveright(Relation rel, /* * _bt_binsrch() -- Do a binary search for a key on a particular page. * - * The passed scankey must be an insertion-type scankey (see nbtree/README), - * but it can omit the rightmost column(s) of the index. - * - * When nextkey is false (the usual case), we are looking for the first - * item >= scankey. When nextkey is true, we are looking for the first - * item strictly greater than scankey. - * * On a leaf page, _bt_binsrch() returns the OffsetNumber of the first * key >= given scankey, or > scankey if nextkey is true. (NOTE: in * particular, this means it is possible to return a value 1 greater than the @@ -319,12 +335,10 @@ _bt_moveright(Relation rel, * the given page. _bt_binsrch() has no lock or refcount side effects * on the buffer. */ -OffsetNumber +static OffsetNumber _bt_binsrch(Relation rel, - Buffer buf, - int keysz, - ScanKey scankey, - bool nextkey) + BTScanInsert key, + Buffer buf) { Page page; BTPageOpaque opaque; @@ -336,6 +350,11 @@ _bt_binsrch(Relation rel, page = BufferGetPage(buf); opaque = (BTPageOpaque) PageGetSpecialPointer(page); + /* Requesting nextkey semantics while using scantid seems nonsensical */ + Assert(!key->nextkey || key->scantid == NULL); + /* scantid-set callers must use _bt_binsrch_insert() on leaf pages */ + Assert(!P_ISLEAF(opaque) || key->scantid == NULL); + low = P_FIRSTDATAKEY(opaque); high = PageGetMaxOffsetNumber(page); @@ -346,7 +365,7 @@ _bt_binsrch(Relation rel, * This can never happen on an internal page, however, since they are * never empty (an internal page must have children). */ - if (high < low) + if (unlikely(high < low)) return low; /* @@ -363,7 +382,7 @@ _bt_binsrch(Relation rel, */ high++; /* establish the loop invariant for high */ - cmpval = nextkey ? 0 : 1; /* select comparison value */ + cmpval = key->nextkey ? 0 : 1; /* select comparison value */ while (high > low) { @@ -371,7 +390,7 @@ _bt_binsrch(Relation rel, /* We have low <= mid < high, so mid points at a real slot */ - result = _bt_compare(rel, keysz, scankey, page, mid); + result = _bt_compare(rel, key, page, mid); if (result >= cmpval) low = mid + 1; @@ -398,14 +417,120 @@ _bt_binsrch(Relation rel, return OffsetNumberPrev(low); } -/*---------- - * _bt_compare() -- Compare scankey to a particular tuple on the page. +/* * - * The passed scankey must be an insertion-type scankey (see nbtree/README), - * but it can omit the rightmost column(s) of the index. + * _bt_binsrch_insert() -- Cacheable, incremental leaf page binary search. + * + * Like _bt_binsrch(), but with support for caching the binary search + * bounds. Only used during insertion, and only on the leaf page that it + * looks like caller will insert tuple on. Exclusive-locked and pinned + * leaf page is contained within insertstate. + * + * Caches the bounds fields in insertstate so that a subsequent call can + * reuse the low and strict high bounds of original binary search. Callers + * that use these fields directly must be prepared for the case where low + * and/or stricthigh are not on the same page (one or both exceed maxoff + * for the page). The case where there are no items on the page (high < + * low) makes bounds invalid. + * + * Caller is responsible for invalidating bounds when it modifies the page + * before calling here a second time. + */ +OffsetNumber +_bt_binsrch_insert(Relation rel, BTInsertState insertstate) +{ + BTScanInsert key = insertstate->itup_key; + Page page; + BTPageOpaque opaque; + OffsetNumber low, + high, + stricthigh; + int32 result, + cmpval; + + page = BufferGetPage(insertstate->buf); + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + + Assert(P_ISLEAF(opaque)); + Assert(!key->nextkey); + + if (!insertstate->bounds_valid) + { + /* Start new binary search */ + low = P_FIRSTDATAKEY(opaque); + high = PageGetMaxOffsetNumber(page); + } + else + { + /* Restore result of previous binary search against same page */ + low = insertstate->low; + high = insertstate->stricthigh; + } + + /* If there are no keys on the page, return the first available slot */ + if (unlikely(high < low)) + { + /* Caller can't reuse bounds */ + insertstate->low = InvalidOffsetNumber; + insertstate->stricthigh = InvalidOffsetNumber; + insertstate->bounds_valid = false; + return low; + } + + /* + * Binary search to find the first key on the page >= scan key. (nextkey + * is always false when inserting). + * + * The loop invariant is: all slots before 'low' are < scan key, all slots + * at or after 'high' are >= scan key. 'stricthigh' is > scan key, and is + * maintained to save additional search effort for caller. + * + * We can fall out when high == low. + */ + if (!insertstate->bounds_valid) + high++; /* establish the loop invariant for high */ + stricthigh = high; /* high initially strictly higher */ + + cmpval = 1; /* !nextkey comparison value */ + + while (high > low) + { + OffsetNumber mid = low + ((high - low) / 2); + + /* We have low <= mid < high, so mid points at a real slot */ + + result = _bt_compare(rel, key, page, mid); + + if (result >= cmpval) + low = mid + 1; + else + { + high = mid; + if (result != 0) + stricthigh = high; + } + } + + /* + * On a leaf page, a binary search always returns the first key >= scan + * key (at least in !nextkey case), which could be the last slot + 1. This + * is also the lower bound of cached search. + * + * stricthigh may also be the last slot + 1, which prevents caller from + * using bounds directly, but is still useful to us if we're called a + * second time with cached bounds (cached low will be < stricthigh when + * that happens). + */ + insertstate->low = low; + insertstate->stricthigh = stricthigh; + insertstate->bounds_valid = true; + + return low; +} + +/*---------- + * _bt_compare() -- Compare insertion-type scankey to tuple on a page. * - * keysz: number of key conditions to be checked (might be less than the - * number of index columns!) * page/offnum: location of btree item to be compared to. * * This routine returns: @@ -418,32 +543,30 @@ _bt_binsrch(Relation rel, * * CRUCIAL NOTE: on a non-leaf page, the first data key is assumed to be * "minus infinity": this routine will always claim it is less than the - * scankey. The actual key value stored (if any, which there probably isn't) - * does not matter. This convention allows us to implement the Lehman and - * Yao convention that the first down-link pointer is before the first key. - * See backend/access/nbtree/README for details. + * scankey. The actual key value stored is explicitly truncated to 0 + * attributes (explicitly minus infinity) with version 3+ indexes, but + * that isn't relied upon. This allows us to implement the Lehman and + * Yao convention that the first down-link pointer is before the first + * key. See backend/access/nbtree/README for details. *---------- */ int32 _bt_compare(Relation rel, - int keysz, - ScanKey scankey, + BTScanInsert key, Page page, OffsetNumber offnum) { TupleDesc itupdesc = RelationGetDescr(rel); BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); IndexTuple itup; - int i; + ItemPointer heapTid; + ScanKey scankey; + int ncmpkey; + int ntupatts; - /* - * Check tuple has correct number of attributes. - */ - if (unlikely(!_bt_check_natts(rel, page, offnum))) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("tuple has wrong number of attributes in index \"%s\"", - RelationGetRelationName(rel)))); + Assert(_bt_check_natts(rel, key->heapkeyspace, page, offnum)); + Assert(key->keysz <= IndexRelationGetNumberOfKeyAttributes(rel)); + Assert(key->heapkeyspace || key->scantid == NULL); /* * Force result ">" if target item is first data item on an internal page @@ -453,6 +576,7 @@ _bt_compare(Relation rel, return 1; itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); + ntupatts = BTreeTupleGetNAtts(itup, rel); /* * The scan key is set up with the attribute number associated with each @@ -466,7 +590,10 @@ _bt_compare(Relation rel, * _bt_first). */ - for (i = 1; i <= keysz; i++) + ncmpkey = Min(ntupatts, key->keysz); + Assert(key->heapkeyspace || ncmpkey == key->keysz); + scankey = key->scankeys; + for (int i = 1; i <= ncmpkey; i++) { Datum datum; bool isNull; @@ -507,7 +634,7 @@ _bt_compare(Relation rel, scankey->sk_argument)); if (!(scankey->sk_flags & SK_BT_DESC)) - result = -result; + INVERT_COMPARE_RESULT(result); } /* if the keys are unequal, return the difference */ @@ -517,8 +644,77 @@ _bt_compare(Relation rel, scankey++; } - /* if we get here, the keys are equal */ - return 0; + /* + * All non-truncated attributes (other than heap TID) were found to be + * equal. Treat truncated attributes as minus infinity when scankey has a + * key attribute value that would otherwise be compared directly. + * + * Note: it doesn't matter if ntupatts includes non-key attributes; + * scankey won't, so explicitly excluding non-key attributes isn't + * necessary. + */ + if (key->keysz > ntupatts) + return 1; + + /* + * Use the heap TID attribute and scantid to try to break the tie. The + * rules are the same as any other key attribute -- only the + * representation differs. + */ + heapTid = BTreeTupleGetHeapTID(itup); + if (key->scantid == NULL) + { + /* + * Most searches have a scankey that is considered greater than a + * truncated pivot tuple if and when the scankey has equal values for + * attributes up to and including the least significant untruncated + * attribute in tuple. + * + * For example, if an index has the minimum two attributes (single + * user key attribute, plus heap TID attribute), and a page's high key + * is ('foo', -inf), and scankey is ('foo', ), the search + * will not descend to the page to the left. The search will descend + * right instead. The truncated attribute in pivot tuple means that + * all non-pivot tuples on the page to the left are strictly < 'foo', + * so it isn't necessary to descend left. In other words, search + * doesn't have to descend left because it isn't interested in a match + * that has a heap TID value of -inf. + * + * However, some searches (pivotsearch searches) actually require that + * we descend left when this happens. -inf is treated as a possible + * match for omitted scankey attribute(s). This is needed by page + * deletion, which must re-find leaf pages that are targets for + * deletion using their high keys. + * + * Note: the heap TID part of the test ensures that scankey is being + * compared to a pivot tuple with one or more truncated key + * attributes. + * + * Note: pg_upgrade'd !heapkeyspace indexes must always descend to the + * left here, since they have no heap TID attribute (and cannot have + * any -inf key values in any case, since truncation can only remove + * non-key attributes). !heapkeyspace searches must always be + * prepared to deal with matches on both sides of the pivot once the + * leaf level is reached. + */ + if (key->heapkeyspace && !key->pivotsearch && + key->keysz == ntupatts && heapTid == NULL) + return 1; + + /* All provided scankey arguments found to be equal */ + return 0; + } + + /* + * Treat truncated heap TID as minus infinity, since scankey has a key + * attribute value (scantid) that would otherwise be compared directly + */ + Assert(key->keysz == IndexRelationGetNumberOfKeyAttributes(rel)); + if (heapTid == NULL) + return 1; + + Assert(ntupatts >= IndexRelationGetNumberOfKeyAttributes(rel)); + return ItemPointerCompare(key->scantid, heapTid); } /* @@ -552,8 +748,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) StrategyNumber strat; bool nextkey; bool goback; + BTScanInsertData inskey; ScanKey startKeys[INDEX_MAX_KEYS]; - ScanKeyData scankeys[INDEX_MAX_KEYS]; ScanKeyData notnullkeys[INDEX_MAX_KEYS]; int keysCount = 0; int i; @@ -799,8 +995,9 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) /* * We want to start the scan somewhere within the index. Set up an * insertion scankey we can use to search for the boundary point we - * identified above. The insertion scankey is built in the local - * scankeys[] array, using the keys identified by startKeys[]. + * identified above. The insertion scankey is built using the keys + * identified by startKeys[]. (Remaining insertion scankey fields are + * initialized after initial-positioning strategy is finalized.) */ Assert(keysCount <= INDEX_MAX_KEYS); for (i = 0; i < keysCount; i++) @@ -828,7 +1025,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) _bt_parallel_done(scan); return false; } - memcpy(scankeys + i, subkey, sizeof(ScanKeyData)); + memcpy(inskey.scankeys + i, subkey, sizeof(ScanKeyData)); /* * If the row comparison is the last positioning key we accepted, @@ -860,7 +1057,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) if (subkey->sk_flags & SK_ISNULL) break; /* can't use null keys */ Assert(keysCount < INDEX_MAX_KEYS); - memcpy(scankeys + keysCount, subkey, sizeof(ScanKeyData)); + memcpy(inskey.scankeys + keysCount, subkey, + sizeof(ScanKeyData)); keysCount++; if (subkey->sk_flags & SK_ROW_END) { @@ -906,7 +1104,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) FmgrInfo *procinfo; procinfo = index_getprocinfo(rel, cur->sk_attno, BTORDER_PROC); - ScanKeyEntryInitializeWithInfo(scankeys + i, + ScanKeyEntryInitializeWithInfo(inskey.scankeys + i, cur->sk_flags, cur->sk_attno, InvalidStrategy, @@ -927,7 +1125,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) elog(ERROR, "missing support function %d(%u,%u) for attribute %d of index \"%s\"", BTORDER_PROC, rel->rd_opcintype[i], cur->sk_subtype, cur->sk_attno, RelationGetRelationName(rel)); - ScanKeyEntryInitialize(scankeys + i, + ScanKeyEntryInitialize(inskey.scankeys + i, cur->sk_flags, cur->sk_attno, InvalidStrategy, @@ -1030,12 +1228,19 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) return false; } + /* Initialize remaining insertion scan key fields */ + inskey.heapkeyspace = _bt_heapkeyspace(rel); + inskey.anynullkeys = false; /* unused */ + inskey.nextkey = nextkey; + inskey.pivotsearch = false; + inskey.scantid = NULL; + inskey.keysz = keysCount; + /* * Use the manufactured insertion scan key to descend the tree and * position ourselves on the target leaf page. */ - stack = _bt_search(rel, keysCount, scankeys, nextkey, &buf, BT_READ, - scan->xs_snapshot); + stack = _bt_search(rel, &inskey, &buf, BT_READ, scan->xs_snapshot); /* don't need to keep the stack around... */ _bt_freestack(stack); @@ -1064,7 +1269,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) _bt_initialize_more_data(so, dir); /* position to the precise item on the page */ - offnum = _bt_binsrch(rel, buf, keysCount, scankeys, nextkey); + offnum = _bt_binsrch(rel, &inskey, buf); /* * If nextkey = false, we are positioned at the first item >= scan key, or @@ -1113,7 +1318,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir) readcomplete: /* OK, itemIndex says what to return */ currItem = &so->currPos.items[so->currPos.itemIndex]; - scan->xs_ctup.t_self = currItem->heapTid; + scan->xs_heaptid = currItem->heapTid; if (scan->xs_want_itup) scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset); @@ -1163,7 +1368,7 @@ _bt_next(IndexScanDesc scan, ScanDirection dir) /* OK, itemIndex says what to return */ currItem = &so->currPos.items[so->currPos.itemIndex]; - scan->xs_ctup.t_self = currItem->heapTid; + scan->xs_heaptid = currItem->heapTid; if (scan->xs_want_itup) scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset); @@ -1198,8 +1403,8 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum) OffsetNumber minoff; OffsetNumber maxoff; int itemIndex; - IndexTuple itup; bool continuescan; + int indnatts; /* * We must have the buffer pinned and locked, but the usual macro can't be @@ -1219,6 +1424,8 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum) _bt_parallel_release(scan, BufferGetBlockNumber(so->currPos.buf)); } + continuescan = true; /* default assumption */ + indnatts = IndexRelationGetNumberOfAttributes(scan->indexRelation); minoff = P_FIRSTDATAKEY(opaque); maxoff = PageGetMaxOffsetNumber(page); @@ -1260,23 +1467,58 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum) while (offnum <= maxoff) { - itup = _bt_checkkeys(scan, page, offnum, dir, &continuescan); - if (itup != NULL) + ItemId iid = PageGetItemId(page, offnum); + IndexTuple itup; + + /* + * If the scan specifies not to return killed tuples, then we + * treat a killed tuple as not passing the qual + */ + if (scan->ignore_killed_tuples && ItemIdIsDead(iid)) + { + offnum = OffsetNumberNext(offnum); + continue; + } + + itup = (IndexTuple) PageGetItem(page, iid); + + if (_bt_checkkeys(scan, itup, indnatts, dir, &continuescan)) { /* tuple passes all scan key conditions, so remember it */ _bt_saveitem(so, itemIndex, offnum, itup); itemIndex++; } + /* When !continuescan, there can't be any more matches, so stop */ if (!continuescan) - { - /* there can't be any more matches, so stop */ - so->currPos.moreRight = false; break; - } offnum = OffsetNumberNext(offnum); } + /* + * We don't need to visit page to the right when the high key + * indicates that no more matches will be found there. + * + * Checking the high key like this works out more often than you might + * think. Leaf page splits pick a split point between the two most + * dissimilar tuples (this is weighed against the need to evenly share + * free space). Leaf pages with high key attribute values that can + * only appear on non-pivot tuples on the right sibling page are + * common. + */ + if (continuescan && !P_RIGHTMOST(opaque)) + { + ItemId iid = PageGetItemId(page, P_HIKEY); + IndexTuple itup = (IndexTuple) PageGetItem(page, iid); + int truncatt; + + truncatt = BTreeTupleGetNAtts(itup, scan->indexRelation); + _bt_checkkeys(scan, itup, truncatt, dir, &continuescan); + } + + if (!continuescan) + so->currPos.moreRight = false; + Assert(itemIndex <= MaxIndexTuplesPerPage); so->currPos.firstItem = 0; so->currPos.lastItem = itemIndex - 1; @@ -1291,8 +1533,40 @@ _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum) while (offnum >= minoff) { - itup = _bt_checkkeys(scan, page, offnum, dir, &continuescan); - if (itup != NULL) + ItemId iid = PageGetItemId(page, offnum); + IndexTuple itup; + bool tuple_alive; + bool passes_quals; + + /* + * If the scan specifies not to return killed tuples, then we + * treat a killed tuple as not passing the qual. Most of the + * time, it's a win to not bother examining the tuple's index + * keys, but just skip to the next tuple (previous, actually, + * since we're scanning backwards). However, if this is the first + * tuple on the page, we do check the index keys, to prevent + * uselessly advancing to the page to the left. This is similar + * to the high key optimization used by forward scans. + */ + if (scan->ignore_killed_tuples && ItemIdIsDead(iid)) + { + Assert(offnum >= P_FIRSTDATAKEY(opaque)); + if (offnum > P_FIRSTDATAKEY(opaque)) + { + offnum = OffsetNumberPrev(offnum); + continue; + } + + tuple_alive = false; + } + else + tuple_alive = true; + + itup = (IndexTuple) PageGetItem(page, iid); + + passes_quals = _bt_checkkeys(scan, itup, indnatts, dir, + &continuescan); + if (passes_quals && tuple_alive) { /* tuple passes all scan key conditions, so remember it */ itemIndex--; @@ -1504,17 +1778,19 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir) /* nope, keep going */ if (scan->parallel_scan != NULL) { + _bt_relbuf(rel, so->currPos.buf); status = _bt_parallel_seize(scan, &blkno); if (!status) { - _bt_relbuf(rel, so->currPos.buf); BTScanPosInvalidate(so->currPos); return false; } } else + { blkno = opaque->btpo_next; - _bt_relbuf(rel, so->currPos.buf); + _bt_relbuf(rel, so->currPos.buf); + } } } else @@ -1832,8 +2108,10 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost, if (opaque->btpo.level == level) break; if (opaque->btpo.level < level) - elog(ERROR, "btree level %u not found in index \"%s\"", - level, RelationGetRelationName(rel)); + ereport(ERROR, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg_internal("btree level %u not found in index \"%s\"", + level, RelationGetRelationName(rel)))); /* Descend to leftmost or rightmost child page */ if (rightmost) @@ -1940,7 +2218,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir) /* OK, itemIndex says what to return */ currItem = &so->currPos.items[so->currPos.itemIndex]; - scan->xs_ctup.t_self = currItem->heapTid; + scan->xs_heaptid = currItem->heapTid; if (scan->xs_want_itup) scan->xs_itup = (IndexTuple) (so->currTuples + currItem->tupleOffset); @@ -1968,51 +2246,3 @@ _bt_initialize_more_data(BTScanOpaque so, ScanDirection dir) so->numKilled = 0; /* just paranoia */ so->markItemIndex = -1; /* ditto */ } - -/* - * Check if index tuple have appropriate number of attributes. - */ -bool -_bt_check_natts(Relation index, Page page, OffsetNumber offnum) -{ - int16 natts = IndexRelationGetNumberOfAttributes(index); - int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(index); - ItemId itemid; - IndexTuple itup; - BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); - - /* - * Assert that mask allocated for number of keys in index tuple can fit - * maximum number of index keys. - */ - StaticAssertStmt(BT_N_KEYS_OFFSET_MASK >= INDEX_MAX_KEYS, - "BT_N_KEYS_OFFSET_MASK can't fit INDEX_MAX_KEYS"); - - itemid = PageGetItemId(page, offnum); - itup = (IndexTuple) PageGetItem(page, itemid); - - if (P_ISLEAF(opaque) && offnum >= P_FIRSTDATAKEY(opaque)) - { - /* - * Regular leaf tuples have as every index attributes - */ - return (BTreeTupGetNAtts(itup, index) == natts); - } - else if (!P_ISLEAF(opaque) && offnum == P_FIRSTDATAKEY(opaque)) - { - /* - * Leftmost tuples on non-leaf pages have no attributes, or haven't - * INDEX_ALT_TID_MASK set in pg_upgraded indexes. - */ - return (BTreeTupGetNAtts(itup, index) == 0 || - ((itup->t_info & INDEX_ALT_TID_MASK) == 0)); - } - else - { - /* - * Pivot tuples stored in non-leaf pages and hikeys of leaf pages - * contain only key attributes - */ - return (BTreeTupGetNAtts(itup, index) == nkeyatts); - } -} diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index feba5e1c8fb..ab196920064 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -14,15 +14,6 @@ * its parent level. When we have only one page on a level, it must be * the root -- it can be attached to the btree metapage and we are done. * - * This code is moderately slow (~10% slower) compared to the regular - * btree (insertion) build code on sorted or well-clustered data. On - * random data, however, the insertion build code is unusable -- the - * difference on a 60MB heap is a factor of 15 because the random - * probes into the btree thrash the buffer pool. (NOTE: the above - * "10%" estimate is probably obsolete, since it refers to an old and - * not very good external sort implementation that used to exist in - * this module. tuplesort.c is almost certainly faster.) - * * It is not wise to pack the pages entirely full, since then *any* * insertion would cause a split (and not only of the leaf page; the need * for a split would cascade right up the tree). The steady-state load @@ -55,7 +46,7 @@ * This code isn't concerned about the FSM at all. The caller is responsible * for initializing that. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -69,10 +60,13 @@ #include "access/nbtree.h" #include "access/parallel.h" #include "access/relscan.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "access/xloginsert.h" #include "catalog/index.h" +#include "commands/progress.h" #include "miscadmin.h" #include "pgstat.h" #include "storage/smgr.h" @@ -164,13 +158,21 @@ typedef struct BTShared bool brokenhotchain; /* - * This variable-sized field must come last. - * - * See _bt_parallel_estimate_shared(). + * ParallelTableScanDescData data follows. Can't directly embed here, as + * implementations of the parallel table scan desc interface might need + * stronger alignment. */ - ParallelHeapScanDescData heapdesc; } BTShared; +/* + * Return pointer to a BTShared's parallel table scan. + * + * c.f. shm_toc_allocate as to why BUFFERALIGN is used, rather than just + * MAXALIGN. + */ +#define ParallelTableScanFromBTShared(shared) \ + (ParallelTableScanDesc) ((char *) (shared) + BUFFERALIGN(sizeof(BTShared))) + /* * Status for leader in parallel index build. */ @@ -262,6 +264,7 @@ typedef struct BTWriteState { Relation heap; Relation index; + BTScanInsert inskey; /* generic insertion scankey */ bool btws_use_wal; /* dump pages to WAL? */ BlockNumber btws_pages_alloced; /* # pages allocated */ BlockNumber btws_pages_written; /* # pages written out */ @@ -270,33 +273,34 @@ typedef struct BTWriteState static double _bt_spools_heapscan(Relation heap, Relation index, - BTBuildState *buildstate, IndexInfo *indexInfo); + BTBuildState *buildstate, IndexInfo *indexInfo); static void _bt_spooldestroy(BTSpool *btspool); static void _bt_spool(BTSpool *btspool, ItemPointer self, - Datum *values, bool *isnull); + Datum *values, bool *isnull); static void _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2); static void _bt_build_callback(Relation index, HeapTuple htup, Datum *values, - bool *isnull, bool tupleIsAlive, void *state); + bool *isnull, bool tupleIsAlive, void *state); static Page _bt_blnewpage(uint32 level); static BTPageState *_bt_pagestate(BTWriteState *wstate, uint32 level); static void _bt_slideleft(Page page); static void _bt_sortaddtup(Page page, Size itemsize, - IndexTuple itup, OffsetNumber itup_off); + IndexTuple itup, OffsetNumber itup_off); static void _bt_buildadd(BTWriteState *wstate, BTPageState *state, - IndexTuple itup); + IndexTuple itup); static void _bt_uppershutdown(BTWriteState *wstate, BTPageState *state); static void _bt_load(BTWriteState *wstate, - BTSpool *btspool, BTSpool *btspool2); + BTSpool *btspool, BTSpool *btspool2); static void _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, - int request); + int request); static void _bt_end_parallel(BTLeader *btleader); -static Size _bt_parallel_estimate_shared(Snapshot snapshot); +static Size _bt_parallel_estimate_shared(Relation heap, Snapshot snapshot); static double _bt_parallel_heapscan(BTBuildState *buildstate, - bool *brokenhotchain); + bool *brokenhotchain); static void _bt_leader_participate_as_worker(BTBuildState *buildstate); static void _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, - BTShared *btshared, Sharedsort *sharedsort, - Sharedsort *sharedsort2, int sortmem); + BTShared *btshared, Sharedsort *sharedsort, + Sharedsort *sharedsort2, int sortmem, + bool progress); /* @@ -392,6 +396,10 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate, /* Save as primary spool */ buildstate->spool = btspool; + /* Report table scan phase started */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN); + /* Attempt to launch parallel worker scan when required */ if (indexInfo->ii_ParallelWorkers > 0) _bt_begin_parallel(buildstate, indexInfo->ii_Concurrent, @@ -478,13 +486,31 @@ _bt_spools_heapscan(Relation heap, Relation index, BTBuildState *buildstate, /* Fill spool using either serial or parallel heap scan */ if (!buildstate->btleader) - reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, - _bt_build_callback, (void *) buildstate, - NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + _bt_build_callback, (void *) buildstate, + NULL); else reltuples = _bt_parallel_heapscan(buildstate, &indexInfo->ii_BrokenHotChain); + /* + * Set the progress target for the next phase. Reset the block number + * values set by table_index_build_scan + */ + { + const int index[] = { + PROGRESS_CREATEIDX_TUPLES_TOTAL, + PROGRESS_SCAN_BLOCKS_TOTAL, + PROGRESS_SCAN_BLOCKS_DONE + }; + const int64 val[] = { + buildstate->indtuples, + 0, 0 + }; + + pgstat_progress_update_multi_param(3, index, val); + } + /* okay, all heap tuples are spooled */ if (buildstate->spool2 && !buildstate->havedead) { @@ -533,12 +559,19 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) } #endif /* BTREE_BUILD_STATS */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_PERFORMSORT_1); tuplesort_performsort(btspool->sortstate); if (btspool2) + { + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_PERFORMSORT_2); tuplesort_performsort(btspool2->sortstate); + } wstate.heap = btspool->heap; wstate.index = btspool->index; + wstate.inskey = _bt_mkscankey(wstate.index, NULL); /* * We need to log index creation in WAL iff WAL archiving/streaming is @@ -551,11 +584,13 @@ _bt_leafbuild(BTSpool *btspool, BTSpool *btspool2) wstate.btws_pages_written = 0; wstate.btws_zeropage = NULL; /* until needed */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_BTREE_PHASE_LEAF_LOAD); _bt_load(&wstate, btspool, btspool2); } /* - * Per-tuple callback from IndexBuildHeapScan + * Per-tuple callback for table_index_build_scan */ static void _bt_build_callback(Relation index, @@ -622,7 +657,7 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) /* XLOG stuff */ if (wstate->btws_use_wal) { - /* We use the heap NEWPAGE record type for this */ + /* We use the XLOG_FPI record type for this */ log_newpage(&wstate->index->rd_node, MAIN_FORKNUM, blkno, page, true); } @@ -752,7 +787,8 @@ _bt_sortaddtup(Page page, { trunctuple = *itup; trunctuple.t_info = sizeof(IndexTupleData); - BTreeTupSetNAtts(&trunctuple, 0); + /* Deliberately zero INDEX_ALT_TID_MASK bits */ + BTreeTupleSetNAtts(&trunctuple, 0); itup = &trunctuple; itemsize = sizeof(IndexTupleData); } @@ -790,7 +826,9 @@ _bt_sortaddtup(Page page, * placeholder for the pointer to the "high key" item; when we have * filled up the page, we will set linp0 to point to itemN and clear * linpN. On the other hand, if we find this is the last (rightmost) - * page, we leave the items alone and slide the linp array over. + * page, we leave the items alone and slide the linp array over. If + * the high key is to be truncated, offset 1 is deleted, and we insert + * the truncated high key at offset 1. * * 'last' pointer indicates the last offset added to the page. *---------- @@ -803,9 +841,7 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) OffsetNumber last_off; Size pgspc; Size itupsz; - BTPageOpaque pageop; - int indnatts = IndexRelationGetNumberOfAttributes(wstate->index); - int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(wstate->index); + bool isleaf; /* * This is a handy place to check for cancel interrupts during the btree @@ -820,37 +856,47 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) pgspc = PageGetFreeSpace(npage); itupsz = IndexTupleSize(itup); itupsz = MAXALIGN(itupsz); + /* Leaf case has slightly different rules due to suffix truncation */ + isleaf = (state->btps_level == 0); /* - * Check whether the item can fit on a btree page at all. (Eventually, we - * ought to try to apply TOAST methods if not.) We actually need to be - * able to fit three items on every page, so restrict any one item to 1/3 - * the per-page available space. Note that at this point, itupsz doesn't - * include the ItemId. + * Check whether the new item can fit on a btree page on current level at + * all. * - * NOTE: similar code appears in _bt_insertonpg() to defend against - * oversize items being inserted into an already-existing index. But - * during creation of an index, we don't go through there. + * Every newly built index will treat heap TID as part of the keyspace, + * which imposes the requirement that new high keys must occasionally have + * a heap TID appended within _bt_truncate(). That may leave a new pivot + * tuple one or two MAXALIGN() quantums larger than the original first + * right tuple it's derived from. v4 deals with the problem by decreasing + * the limit on the size of tuples inserted on the leaf level by the same + * small amount. Enforce the new v4+ limit on the leaf level, and the old + * limit on internal levels, since pivot tuples may need to make use of + * the reserved space. This should never fail on internal pages. */ - if (itupsz > BTMaxItemSize(npage)) - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("index row size %zu exceeds maximum %zu for index \"%s\"", - itupsz, BTMaxItemSize(npage), - RelationGetRelationName(wstate->index)), - errhint("Values larger than 1/3 of a buffer page cannot be indexed.\n" - "Consider a function index of an MD5 hash of the value, " - "or use full text indexing."), - errtableconstraint(wstate->heap, - RelationGetRelationName(wstate->index)))); + if (unlikely(itupsz > BTMaxItemSize(npage))) + _bt_check_third_page(wstate->index, wstate->heap, isleaf, npage, + itup); /* - * Check to see if page is "full". It's definitely full if the item won't - * fit. Otherwise, compare to the target freespace derived from the - * fillfactor. However, we must put at least two items on each page, so - * disregard fillfactor if we don't have that many. + * Check to see if current page will fit new item, with space left over to + * append a heap TID during suffix truncation when page is a leaf page. + * + * It is guaranteed that we can fit at least 2 non-pivot tuples plus a + * high key with heap TID when finishing off a leaf page, since we rely on + * _bt_check_third_page() rejecting oversized non-pivot tuples. On + * internal pages we can always fit 3 pivot tuples with larger internal + * page tuple limit (includes page high key). + * + * Most of the time, a page is only "full" in the sense that the soft + * fillfactor-wise limit has been exceeded. However, we must always leave + * at least two items plus a high key on each page before starting a new + * page. Disregard fillfactor and insert on "full" current page if we + * don't have the minimum number of items yet. (Note that we deliberately + * assume that suffix truncation neither enlarges nor shrinks new high key + * when applying soft limit.) */ - if (pgspc < itupsz || (pgspc < state->btps_full && last_off > P_FIRSTKEY)) + if (pgspc < itupsz + (isleaf ? MAXALIGN(sizeof(ItemPointerData)) : 0) || + (pgspc < state->btps_full && last_off > P_FIRSTKEY)) { /* * Finish off the page and write it out. @@ -860,8 +906,6 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) ItemId ii; ItemId hii; IndexTuple oitup; - IndexTuple keytup; - BTPageOpaque opageop = (BTPageOpaque) PageGetSpecialPointer(opage); /* Create new page of same level */ npage = _bt_blnewpage(state->btps_level); @@ -882,34 +926,57 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) _bt_sortaddtup(npage, ItemIdGetLength(ii), oitup, P_FIRSTKEY); /* - * Move 'last' into the high key position on opage + * Move 'last' into the high key position on opage. _bt_blnewpage() + * allocated empty space for a line pointer when opage was first + * created, so this is a matter of rearranging already-allocated space + * on page, and initializing high key line pointer. (Actually, leaf + * pages must also swap oitup with a truncated version of oitup, which + * is sometimes larger than oitup, though never by more than the space + * needed to append a heap TID.) */ hii = PageGetItemId(opage, P_HIKEY); *hii = *ii; ItemIdSetUnused(ii); /* redundant */ ((PageHeader) opage)->pd_lower -= sizeof(ItemIdData); - if (indnkeyatts != indnatts && P_ISLEAF(opageop)) + if (isleaf) { + IndexTuple lastleft; + IndexTuple truncated; + /* - * We truncate included attributes of high key here. Subsequent - * insertions assume that hikey is already truncated, and so they - * need not worry about it, when copying the high key into the - * parent page as a downlink. + * Truncate away any unneeded attributes from high key on leaf + * level. This is only done at the leaf level because downlinks + * in internal pages are either negative infinity items, or get + * their contents from copying from one level down. See also: + * _bt_split(). * - * The code above have just rearranged item pointers, but it - * didn't save any space. In order to save the space on page we - * have to truly shift index tuples on the page. But that's not - * so bad for performance, because we operating pd_upper and don't - * have to shift much of tuples memory. Shift of ItemId's is - * rather cheap, because they are small. + * We don't try to bias our choice of split point to make it more + * likely that _bt_truncate() can truncate away more attributes, + * whereas the split point used within _bt_split() is chosen much + * more delicately. Suffix truncation is mostly useful because it + * improves space utilization for workloads with random + * insertions. It doesn't seem worthwhile to add logic for + * choosing a split point here for a benefit that is bound to be + * much smaller. + * + * Overwrite the old item with new truncated high key directly. + * oitup is already located at the physical beginning of tuple + * space, so this should directly reuse the existing tuple space. */ - keytup = _bt_truncate_tuple(wstate->index, oitup); - - /* delete "wrong" high key, insert keytup as P_HIKEY. */ - PageIndexTupleDelete(opage, P_HIKEY); - - _bt_sortaddtup(opage, IndexTupleSize(keytup), keytup, P_HIKEY); + ii = PageGetItemId(opage, OffsetNumberPrev(last_off)); + lastleft = (IndexTuple) PageGetItem(opage, ii); + + truncated = _bt_truncate(wstate->index, lastleft, oitup, + wstate->inskey); + if (!PageIndexTupleOverwrite(opage, P_HIKEY, (Item) truncated, + IndexTupleSize(truncated))) + elog(ERROR, "failed to add high key to the index page"); + pfree(truncated); + + /* oitup should continue to point to the page's high key */ + hii = PageGetItemId(opage, P_HIKEY); + oitup = (IndexTuple) PageGetItem(opage, hii); } /* @@ -920,19 +987,20 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) if (state->btps_next == NULL) state->btps_next = _bt_pagestate(wstate, state->btps_level + 1); - Assert(state->btps_minkey != NULL); + Assert((BTreeTupleGetNAtts(state->btps_minkey, wstate->index) <= + IndexRelationGetNumberOfKeyAttributes(wstate->index) && + BTreeTupleGetNAtts(state->btps_minkey, wstate->index) > 0) || + P_LEFTMOST((BTPageOpaque) PageGetSpecialPointer(opage))); + Assert(BTreeTupleGetNAtts(state->btps_minkey, wstate->index) == 0 || + !P_LEFTMOST((BTPageOpaque) PageGetSpecialPointer(opage))); BTreeInnerTupleSetDownLink(state->btps_minkey, oblkno); _bt_buildadd(wstate, state->btps_next, state->btps_minkey); pfree(state->btps_minkey); /* - * Save a copy of the minimum key for the new page. We have to copy - * it off the old page, not the new one, in case we are not at leaf - * level. Despite oitup is already initialized, it's important to get - * high key from the page, since we could have replaced it with - * truncated copy. See comment above. + * Save a copy of the high key from the old page. It is also used as + * the minimum key for the new page. */ - oitup = (IndexTuple) PageGetItem(opage, PageGetItemId(opage, P_HIKEY)); state->btps_minkey = CopyIndexTuple(oitup); /* @@ -959,26 +1027,23 @@ _bt_buildadd(BTWriteState *wstate, BTPageState *state, IndexTuple itup) last_off = P_FIRSTKEY; } - pageop = (BTPageOpaque) PageGetSpecialPointer(npage); - /* + * By here, either original page is still the current page, or a new page + * was created that became the current page. Either way, the current page + * definitely has space for new item. + * * If the new item is the first for its page, stash a copy for later. Note * this will only happen for the first item on a level; on later pages, * the first item for a page is copied from the prior page in the code - * above. + * above. The minimum key for an entire level is nothing more than a + * minus infinity (downlink only) pivot tuple placeholder. */ if (last_off == P_HIKEY) { Assert(state->btps_minkey == NULL); - - /* - * Truncate included attributes of the tuple that we're going to - * insert into the parent page as a downlink - */ - if (indnkeyatts != indnatts && P_ISLEAF(pageop)) - state->btps_minkey = _bt_truncate_tuple(wstate->index, itup); - else - state->btps_minkey = CopyIndexTuple(itup); + state->btps_minkey = CopyIndexTuple(itup); + /* _bt_sortaddtup() will perform full truncation later */ + BTreeTupleSetNAtts(state->btps_minkey, 0); } /* @@ -1030,7 +1095,12 @@ _bt_uppershutdown(BTWriteState *wstate, BTPageState *state) } else { - Assert(s->btps_minkey != NULL); + Assert((BTreeTupleGetNAtts(s->btps_minkey, wstate->index) <= + IndexRelationGetNumberOfKeyAttributes(wstate->index) && + BTreeTupleGetNAtts(s->btps_minkey, wstate->index) > 0) || + P_LEFTMOST(opaque)); + Assert(BTreeTupleGetNAtts(s->btps_minkey, wstate->index) == 0 || + !P_LEFTMOST(opaque)); BTreeInnerTupleSetDownLink(s->btps_minkey, blkno); _bt_buildadd(wstate, s->btps_next, s->btps_minkey); pfree(s->btps_minkey); @@ -1072,8 +1142,8 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) TupleDesc tupdes = RelationGetDescr(wstate->index); int i, keysz = IndexRelationGetNumberOfKeyAttributes(wstate->index); - ScanKey indexScanKey = NULL; SortSupport sortKeys; + int64 tuples_done = 0; if (merge) { @@ -1085,7 +1155,6 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) /* the preparation of merge */ itup = tuplesort_getindextuple(btspool->sortstate, true); itup2 = tuplesort_getindextuple(btspool2->sortstate, true); - indexScanKey = _bt_mkscankey_nodata(wstate->index); /* Prepare SortSupport data for each column */ sortKeys = (SortSupport) palloc0(keysz * sizeof(SortSupportData)); @@ -1093,7 +1162,7 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) for (i = 0; i < keysz; i++) { SortSupport sortKey = sortKeys + i; - ScanKey scanKey = indexScanKey + i; + ScanKey scanKey = wstate->inskey->scankeys + i; int16 strategy; sortKey->ssup_cxt = CurrentMemoryContext; @@ -1112,8 +1181,6 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) PrepareSortSupportFromIndexRel(wstate->index, strategy, sortKey); } - _bt_freeskey(indexScanKey); - for (;;) { load1 = true; /* load BTSpool next ? */ @@ -1124,6 +1191,8 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) } else if (itup != NULL) { + int32 compare = 0; + for (i = 1; i <= keysz; i++) { SortSupport entry; @@ -1131,7 +1200,6 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) attrDatum2; bool isNull1, isNull2; - int32 compare; entry = sortKeys + i - 1; attrDatum1 = index_getattr(itup, i, tupdes, &isNull1); @@ -1148,6 +1216,20 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) else if (compare < 0) break; } + + /* + * If key values are equal, we sort on ItemPointer. This is + * required for btree indexes, since heap TID is treated as an + * implicit last key attribute in order to ensure that all + * keys in the index are physically unique. + */ + if (compare == 0) + { + compare = ItemPointerCompare(&itup->t_tid, &itup2->t_tid); + Assert(compare != 0); + if (compare > 0) + load1 = false; + } } else load1 = false; @@ -1166,6 +1248,10 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) _bt_buildadd(wstate, state, itup2); itup2 = tuplesort_getindextuple(btspool2->sortstate, true); } + + /* Report progress */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, + ++tuples_done); } pfree(sortKeys); } @@ -1180,6 +1266,10 @@ _bt_load(BTWriteState *wstate, BTSpool *btspool, BTSpool *btspool2) state = _bt_pagestate(wstate, 0); _bt_buildadd(wstate, state, itup); + + /* Report progress */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_TUPLES_DONE, + ++tuples_done); } } @@ -1252,7 +1342,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) EnterParallelMode(); Assert(request > 0); pcxt = CreateParallelContext("postgres", "_bt_parallel_build_main", - request, true); + request); scantuplesortstates = leaderparticipates ? request + 1 : request; /* @@ -1271,7 +1361,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) * Estimate size for our own PARALLEL_KEY_BTREE_SHARED workspace, and * PARALLEL_KEY_TUPLESORT tuplesort workspace */ - estbtshared = _bt_parallel_estimate_shared(snapshot); + estbtshared = _bt_parallel_estimate_shared(btspool->heap, snapshot); shm_toc_estimate_chunk(&pcxt->estimator, estbtshared); estsort = tuplesort_estimate_shared(scantuplesortstates); shm_toc_estimate_chunk(&pcxt->estimator, estsort); @@ -1312,7 +1402,9 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) btshared->havedead = false; btshared->indtuples = 0.0; btshared->brokenhotchain = false; - heap_parallelscan_initialize(&btshared->heapdesc, btspool->heap, snapshot); + table_parallelscan_initialize(btspool->heap, + ParallelTableScanFromBTShared(btshared), + snapshot); /* * Store shared tuplesort-private state, for which we reserved space. @@ -1399,17 +1491,11 @@ _bt_end_parallel(BTLeader *btleader) * btree index build based on the snapshot its parallel scan will use. */ static Size -_bt_parallel_estimate_shared(Snapshot snapshot) +_bt_parallel_estimate_shared(Relation heap, Snapshot snapshot) { - if (!IsMVCCSnapshot(snapshot)) - { - Assert(snapshot == SnapshotAny); - return sizeof(BTShared); - } - - return add_size(offsetof(BTShared, heapdesc) + - offsetof(ParallelHeapScanDescData, phs_snapshot_data), - EstimateSnapshotSpace(snapshot)); + /* c.f. shm_toc_allocate as to why BUFFERALIGN is used */ + return add_size(BUFFERALIGN(sizeof(BTShared)), + table_parallelscan_estimate(heap, snapshot)); } /* @@ -1496,7 +1582,7 @@ _bt_leader_participate_as_worker(BTBuildState *buildstate) /* Perform work common to all participants */ _bt_parallel_scan_and_sort(leaderworker, leaderworker2, btleader->btshared, btleader->sharedsort, btleader->sharedsort2, - sortmem); + sortmem, true); #ifdef BTREE_BUILD_STATS if (log_btree_build_stats) @@ -1553,7 +1639,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) } /* Open relations within worker */ - heapRel = heap_open(btshared->heaprelid, heapLockmode); + heapRel = table_open(btshared->heaprelid, heapLockmode); indexRel = index_open(btshared->indexrelid, indexLockmode); /* Initialize worker's own spool */ @@ -1587,7 +1673,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) /* Perform sorting of spool, and possibly a spool2 */ sortmem = maintenance_work_mem / btshared->scantuplesortstates; _bt_parallel_scan_and_sort(btspool, btspool2, btshared, sharedsort, - sharedsort2, sortmem); + sharedsort2, sortmem, false); #ifdef BTREE_BUILD_STATS if (log_btree_build_stats) @@ -1598,7 +1684,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) #endif /* BTREE_BUILD_STATS */ index_close(indexRel, indexLockmode); - heap_close(heapRel, heapLockmode); + table_close(heapRel, heapLockmode); } /* @@ -1616,11 +1702,11 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) static void _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, BTShared *btshared, Sharedsort *sharedsort, - Sharedsort *sharedsort2, int sortmem) + Sharedsort *sharedsort2, int sortmem, bool progress) { SortCoordinate coordinate; BTBuildState buildstate; - HeapScanDesc scan; + TableScanDesc scan; double reltuples; IndexInfo *indexInfo; @@ -1673,10 +1759,11 @@ _bt_parallel_scan_and_sort(BTSpool *btspool, BTSpool *btspool2, /* Join parallel scan */ indexInfo = BuildIndexInfo(btspool->index); indexInfo->ii_Concurrent = btshared->isconcurrent; - scan = heap_beginscan_parallel(btspool->heap, &btshared->heapdesc); - reltuples = IndexBuildHeapScan(btspool->heap, btspool->index, indexInfo, - true, _bt_build_callback, - (void *) &buildstate, scan); + scan = table_beginscan_parallel(btspool->heap, + ParallelTableScanFromBTShared(btshared)); + reltuples = table_index_build_scan(btspool->heap, btspool->index, indexInfo, + true, progress, _bt_build_callback, + (void *) &buildstate, scan); /* * Execute this worker's part of the sort. diff --git a/src/backend/access/nbtree/nbtsplitloc.c b/src/backend/access/nbtree/nbtsplitloc.c new file mode 100644 index 00000000000..1c1029b6c4d --- /dev/null +++ b/src/backend/access/nbtree/nbtsplitloc.c @@ -0,0 +1,1091 @@ +/*------------------------------------------------------------------------- + * + * nbtsplitloc.c + * Choose split point code for Postgres btree implementation. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/nbtree/nbtsplitloc.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/nbtree.h" +#include "storage/lmgr.h" + +/* limits on split interval (default strategy only) */ +#define MAX_LEAF_INTERVAL 9 +#define MAX_INTERNAL_INTERVAL 18 + +typedef enum +{ + /* strategy for searching through materialized list of split points */ + SPLIT_DEFAULT, /* give some weight to truncation */ + SPLIT_MANY_DUPLICATES, /* find minimally distinguishing point */ + SPLIT_SINGLE_VALUE /* leave left page almost full */ +} FindSplitStrat; + +typedef struct +{ + /* details of free space left by split */ + int16 curdelta; /* current leftfree/rightfree delta */ + int16 leftfree; /* space left on left page post-split */ + int16 rightfree; /* space left on right page post-split */ + + /* split point identifying fields (returned by _bt_findsplitloc) */ + OffsetNumber firstoldonright; /* first item on new right page */ + bool newitemonleft; /* new item goes on left, or right? */ + +} SplitPoint; + +typedef struct +{ + /* context data for _bt_recsplitloc */ + Relation rel; /* index relation */ + Page page; /* page undergoing split */ + IndexTuple newitem; /* new item (cause of page split) */ + Size newitemsz; /* size of newitem (includes line pointer) */ + bool is_leaf; /* T if splitting a leaf page */ + bool is_rightmost; /* T if splitting rightmost page on level */ + OffsetNumber newitemoff; /* where the new item is to be inserted */ + int leftspace; /* space available for items on left page */ + int rightspace; /* space available for items on right page */ + int olddataitemstotal; /* space taken by old items */ + Size minfirstrightsz; /* smallest firstoldonright tuple size */ + + /* candidate split point data */ + int maxsplits; /* maximum number of splits */ + int nsplits; /* current number of splits */ + SplitPoint *splits; /* all candidate split points for page */ + int interval; /* current range of acceptable split points */ +} FindSplitData; + +static void _bt_recsplitloc(FindSplitData *state, + OffsetNumber firstoldonright, bool newitemonleft, + int olddataitemstoleft, Size firstoldonrightsz); +static void _bt_deltasortsplits(FindSplitData *state, double fillfactormult, + bool usemult); +static int _bt_splitcmp(const void *arg1, const void *arg2); +static bool _bt_afternewitemoff(FindSplitData *state, OffsetNumber maxoff, + int leaffillfactor, bool *usemult); +static bool _bt_adjacenthtid(ItemPointer lowhtid, ItemPointer highhtid); +static OffsetNumber _bt_bestsplitloc(FindSplitData *state, int perfectpenalty, + bool *newitemonleft, FindSplitStrat strategy); +static int _bt_strategy(FindSplitData *state, SplitPoint *leftpage, + SplitPoint *rightpage, FindSplitStrat *strategy); +static void _bt_interval_edges(FindSplitData *state, + SplitPoint **leftinterval, SplitPoint **rightinterval); +static inline int _bt_split_penalty(FindSplitData *state, SplitPoint *split); +static inline IndexTuple _bt_split_lastleft(FindSplitData *state, + SplitPoint *split); +static inline IndexTuple _bt_split_firstright(FindSplitData *state, + SplitPoint *split); + + +/* + * _bt_findsplitloc() -- find an appropriate place to split a page. + * + * The main goal here is to equalize the free space that will be on each + * split page, *after accounting for the inserted tuple*. (If we fail to + * account for it, we might find ourselves with too little room on the page + * that it needs to go into!) + * + * If the page is the rightmost page on its level, we instead try to arrange + * to leave the left split page fillfactor% full. In this way, when we are + * inserting successively increasing keys (consider sequences, timestamps, + * etc) we will end up with a tree whose pages are about fillfactor% full, + * instead of the 50% full result that we'd get without this special case. + * This is the same as nbtsort.c produces for a newly-created tree. Note + * that leaf and nonleaf pages use different fillfactors. Note also that + * there are a number of further special cases where fillfactor is not + * applied in the standard way. + * + * We are passed the intended insert position of the new tuple, expressed as + * the offsetnumber of the tuple it must go in front of (this could be + * maxoff+1 if the tuple is to go at the end). The new tuple itself is also + * passed, since it's needed to give some weight to how effective suffix + * truncation will be. The implementation picks the split point that + * maximizes the effectiveness of suffix truncation from a small list of + * alternative candidate split points that leave each side of the split with + * about the same share of free space. Suffix truncation is secondary to + * equalizing free space, except in cases with large numbers of duplicates. + * Note that it is always assumed that caller goes on to perform truncation, + * even with pg_upgrade'd indexes where that isn't actually the case + * (!heapkeyspace indexes). See nbtree/README for more information about + * suffix truncation. + * + * We return the index of the first existing tuple that should go on the + * righthand page, plus a boolean indicating whether the new tuple goes on + * the left or right page. The bool is necessary to disambiguate the case + * where firstright == newitemoff. + */ +OffsetNumber +_bt_findsplitloc(Relation rel, + Page page, + OffsetNumber newitemoff, + Size newitemsz, + IndexTuple newitem, + bool *newitemonleft) +{ + BTPageOpaque opaque; + int leftspace, + rightspace, + olddataitemstotal, + olddataitemstoleft, + perfectpenalty, + leaffillfactor; + FindSplitData state; + FindSplitStrat strategy; + ItemId itemid; + OffsetNumber offnum, + maxoff, + foundfirstright; + double fillfactormult; + bool usemult; + SplitPoint leftpage, + rightpage; + + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + maxoff = PageGetMaxOffsetNumber(page); + + /* Total free space available on a btree page, after fixed overhead */ + leftspace = rightspace = + PageGetPageSize(page) - SizeOfPageHeaderData - + MAXALIGN(sizeof(BTPageOpaqueData)); + + /* The right page will have the same high key as the old page */ + if (!P_RIGHTMOST(opaque)) + { + itemid = PageGetItemId(page, P_HIKEY); + rightspace -= (int) (MAXALIGN(ItemIdGetLength(itemid)) + + sizeof(ItemIdData)); + } + + /* Count up total space in data items before actually scanning 'em */ + olddataitemstotal = rightspace - (int) PageGetExactFreeSpace(page); + leaffillfactor = RelationGetFillFactor(rel, BTREE_DEFAULT_FILLFACTOR); + + /* Passed-in newitemsz is MAXALIGNED but does not include line pointer */ + newitemsz += sizeof(ItemIdData); + state.rel = rel; + state.page = page; + state.newitem = newitem; + state.newitemsz = newitemsz; + state.is_leaf = P_ISLEAF(opaque); + state.is_rightmost = P_RIGHTMOST(opaque); + state.leftspace = leftspace; + state.rightspace = rightspace; + state.olddataitemstotal = olddataitemstotal; + state.minfirstrightsz = SIZE_MAX; + state.newitemoff = newitemoff; + + /* + * maxsplits should never exceed maxoff because there will be at most as + * many candidate split points as there are points _between_ tuples, once + * you imagine that the new item is already on the original page (the + * final number of splits may be slightly lower because not all points + * between tuples will be legal). + */ + state.maxsplits = maxoff; + state.splits = palloc(sizeof(SplitPoint) * state.maxsplits); + state.nsplits = 0; + + /* + * Scan through the data items and calculate space usage for a split at + * each possible position + */ + olddataitemstoleft = 0; + + for (offnum = P_FIRSTDATAKEY(opaque); + offnum <= maxoff; + offnum = OffsetNumberNext(offnum)) + { + Size itemsz; + + itemid = PageGetItemId(page, offnum); + itemsz = MAXALIGN(ItemIdGetLength(itemid)) + sizeof(ItemIdData); + + /* + * When item offset number is not newitemoff, neither side of the + * split can be newitem. Record a split after the previous data item + * from original page, but before the current data item from original + * page. (_bt_recsplitloc() will reject the split when there are no + * previous items, which we rely on.) + */ + if (offnum < newitemoff) + _bt_recsplitloc(&state, offnum, false, olddataitemstoleft, itemsz); + else if (offnum > newitemoff) + _bt_recsplitloc(&state, offnum, true, olddataitemstoleft, itemsz); + else + { + /* + * Record a split after all "offnum < newitemoff" original page + * data items, but before newitem + */ + _bt_recsplitloc(&state, offnum, false, olddataitemstoleft, itemsz); + + /* + * Record a split after newitem, but before data item from + * original page at offset newitemoff/current offset + */ + _bt_recsplitloc(&state, offnum, true, olddataitemstoleft, itemsz); + } + + olddataitemstoleft += itemsz; + } + + /* + * Record a split after all original page data items, but before newitem. + * (Though only when it's possible that newitem will end up alone on new + * right page.) + */ + Assert(olddataitemstoleft == olddataitemstotal); + if (newitemoff > maxoff) + _bt_recsplitloc(&state, newitemoff, false, olddataitemstotal, 0); + + /* + * I believe it is not possible to fail to find a feasible split, but just + * in case ... + */ + if (state.nsplits == 0) + elog(ERROR, "could not find a feasible split point for index \"%s\"", + RelationGetRelationName(rel)); + + /* + * Start search for a split point among list of legal split points. Give + * primary consideration to equalizing available free space in each half + * of the split initially (start with default strategy), while applying + * rightmost and split-after-new-item optimizations where appropriate. + * Either of the two other fallback strategies may be required for cases + * with a large number of duplicates around the original/space-optimal + * split point. + * + * Default strategy gives some weight to suffix truncation in deciding a + * split point on leaf pages. It attempts to select a split point where a + * distinguishing attribute appears earlier in the new high key for the + * left side of the split, in order to maximize the number of trailing + * attributes that can be truncated away. Only candidate split points + * that imply an acceptable balance of free space on each side are + * considered. + */ + if (!state.is_leaf) + { + /* fillfactormult only used on rightmost page */ + usemult = state.is_rightmost; + fillfactormult = BTREE_NONLEAF_FILLFACTOR / 100.0; + } + else if (state.is_rightmost) + { + /* Rightmost leaf page -- fillfactormult always used */ + usemult = true; + fillfactormult = leaffillfactor / 100.0; + } + else if (_bt_afternewitemoff(&state, maxoff, leaffillfactor, &usemult)) + { + /* + * New item inserted at rightmost point among a localized grouping on + * a leaf page -- apply "split after new item" optimization, either by + * applying leaf fillfactor multiplier, or by choosing the exact split + * point that leaves the new item as last on the left. (usemult is set + * for us.) + */ + if (usemult) + { + /* fillfactormult should be set based on leaf fillfactor */ + fillfactormult = leaffillfactor / 100.0; + } + else + { + /* find precise split point after newitemoff */ + for (int i = 0; i < state.nsplits; i++) + { + SplitPoint *split = state.splits + i; + + if (split->newitemonleft && + newitemoff == split->firstoldonright) + { + pfree(state.splits); + *newitemonleft = true; + return newitemoff; + } + } + + /* + * Cannot legally split after newitemoff; proceed with split + * without using fillfactor multiplier. This is defensive, and + * should never be needed in practice. + */ + fillfactormult = 0.50; + } + } + else + { + /* Other leaf page. 50:50 page split. */ + usemult = false; + /* fillfactormult not used, but be tidy */ + fillfactormult = 0.50; + } + + /* + * Set an initial limit on the split interval/number of candidate split + * points as appropriate. The "Prefix B-Trees" paper refers to this as + * sigma l for leaf splits and sigma b for internal ("branch") splits. + * It's hard to provide a theoretical justification for the initial size + * of the split interval, though it's clear that a small split interval + * makes suffix truncation much more effective without noticeably + * affecting space utilization over time. + */ + state.interval = Min(Max(1, state.nsplits * 0.05), + state.is_leaf ? MAX_LEAF_INTERVAL : + MAX_INTERNAL_INTERVAL); + + /* + * Save leftmost and rightmost splits for page before original ordinal + * sort order is lost by delta/fillfactormult sort + */ + leftpage = state.splits[0]; + rightpage = state.splits[state.nsplits - 1]; + + /* Give split points a fillfactormult-wise delta, and sort on deltas */ + _bt_deltasortsplits(&state, fillfactormult, usemult); + + /* + * Determine if default strategy/split interval will produce a + * sufficiently distinguishing split, or if we should change strategies. + * Alternative strategies change the range of split points that are + * considered acceptable (split interval), and possibly change + * fillfactormult, in order to deal with pages with a large number of + * duplicates gracefully. + * + * Pass low and high splits for the entire page (actually, they're for an + * imaginary version of the page that includes newitem). These are used + * when the initial split interval encloses split points that are full of + * duplicates, and we need to consider if it's even possible to avoid + * appending a heap TID. + */ + perfectpenalty = _bt_strategy(&state, &leftpage, &rightpage, &strategy); + + if (strategy == SPLIT_DEFAULT) + { + /* + * Default strategy worked out (always works out with internal page). + * Original split interval still stands. + */ + } + + /* + * Many duplicates strategy is used when a heap TID would otherwise be + * appended, but the page isn't completely full of logical duplicates. + * + * The split interval is widened to include all legal candidate split + * points. There might be a few as two distinct values in the whole-page + * split interval, though it's also possible that most of the values on + * the page are unique. The final split point will either be to the + * immediate left or to the immediate right of the group of duplicate + * tuples that enclose the first/delta-optimal split point (perfect + * penalty was set so that the lowest delta split point that avoids + * appending a heap TID will be chosen). Maximizing the number of + * attributes that can be truncated away is not a goal of the many + * duplicates strategy. + * + * Single value strategy is used when it is impossible to avoid appending + * a heap TID. It arranges to leave the left page very full. This + * maximizes space utilization in cases where tuples with the same + * attribute values span many pages. Newly inserted duplicates will tend + * to have higher heap TID values, so we'll end up splitting to the right + * consistently. (Single value strategy is harmless though not + * particularly useful with !heapkeyspace indexes.) + */ + else if (strategy == SPLIT_MANY_DUPLICATES) + { + Assert(state.is_leaf); + /* Shouldn't try to truncate away extra user attributes */ + Assert(perfectpenalty == + IndexRelationGetNumberOfKeyAttributes(state.rel)); + /* No need to resort splits -- no change in fillfactormult/deltas */ + state.interval = state.nsplits; + } + else if (strategy == SPLIT_SINGLE_VALUE) + { + Assert(state.is_leaf); + /* Split near the end of the page */ + usemult = true; + fillfactormult = BTREE_SINGLEVAL_FILLFACTOR / 100.0; + /* Resort split points with new delta */ + _bt_deltasortsplits(&state, fillfactormult, usemult); + /* Appending a heap TID is unavoidable, so interval of 1 is fine */ + state.interval = 1; + } + + /* + * Search among acceptable split points (using final split interval) for + * the entry that has the lowest penalty, and is therefore expected to + * maximize fan-out. Sets *newitemonleft for us. + */ + foundfirstright = _bt_bestsplitloc(&state, perfectpenalty, newitemonleft, + strategy); + pfree(state.splits); + + return foundfirstright; +} + +/* + * Subroutine to record a particular point between two tuples (possibly the + * new item) on page (ie, combination of firstright and newitemonleft + * settings) in *state for later analysis. This is also a convenient point + * to check if the split is legal (if it isn't, it won't be recorded). + * + * firstoldonright is the offset of the first item on the original page that + * goes to the right page, and firstoldonrightsz is the size of that tuple. + * firstoldonright can be > max offset, which means that all the old items go + * to the left page and only the new item goes to the right page. In that + * case, firstoldonrightsz is not used. + * + * olddataitemstoleft is the total size of all old items to the left of the + * split point that is recorded here when legal. Should not include + * newitemsz, since that is handled here. + */ +static void +_bt_recsplitloc(FindSplitData *state, + OffsetNumber firstoldonright, + bool newitemonleft, + int olddataitemstoleft, + Size firstoldonrightsz) +{ + int16 leftfree, + rightfree; + Size firstrightitemsz; + bool newitemisfirstonright; + + /* Is the new item going to be the first item on the right page? */ + newitemisfirstonright = (firstoldonright == state->newitemoff + && !newitemonleft); + + if (newitemisfirstonright) + firstrightitemsz = state->newitemsz; + else + firstrightitemsz = firstoldonrightsz; + + /* Account for all the old tuples */ + leftfree = state->leftspace - olddataitemstoleft; + rightfree = state->rightspace - + (state->olddataitemstotal - olddataitemstoleft); + + /* + * The first item on the right page becomes the high key of the left page; + * therefore it counts against left space as well as right space (we + * cannot assume that suffix truncation will make it any smaller). When + * index has included attributes, then those attributes of left page high + * key will be truncated leaving that page with slightly more free space. + * However, that shouldn't affect our ability to find valid split + * location, since we err in the direction of being pessimistic about free + * space on the left half. Besides, even when suffix truncation of + * non-TID attributes occurs, the new high key often won't even be a + * single MAXALIGN() quantum smaller than the firstright tuple it's based + * on. + * + * If we are on the leaf level, assume that suffix truncation cannot avoid + * adding a heap TID to the left half's new high key when splitting at the + * leaf level. In practice the new high key will often be smaller and + * will rarely be larger, but conservatively assume the worst case. + */ + if (state->is_leaf) + leftfree -= (int16) (firstrightitemsz + + MAXALIGN(sizeof(ItemPointerData))); + else + leftfree -= (int16) firstrightitemsz; + + /* account for the new item */ + if (newitemonleft) + leftfree -= (int16) state->newitemsz; + else + rightfree -= (int16) state->newitemsz; + + /* + * If we are not on the leaf level, we will be able to discard the key + * data from the first item that winds up on the right page. + */ + if (!state->is_leaf) + rightfree += (int16) firstrightitemsz - + (int16) (MAXALIGN(sizeof(IndexTupleData)) + sizeof(ItemIdData)); + + /* Record split if legal */ + if (leftfree >= 0 && rightfree >= 0) + { + Assert(state->nsplits < state->maxsplits); + + /* Determine smallest firstright item size on page */ + state->minfirstrightsz = Min(state->minfirstrightsz, firstrightitemsz); + + state->splits[state->nsplits].curdelta = 0; + state->splits[state->nsplits].leftfree = leftfree; + state->splits[state->nsplits].rightfree = rightfree; + state->splits[state->nsplits].firstoldonright = firstoldonright; + state->splits[state->nsplits].newitemonleft = newitemonleft; + state->nsplits++; + } +} + +/* + * Subroutine to assign space deltas to materialized array of candidate split + * points based on current fillfactor, and to sort array using that fillfactor + */ +static void +_bt_deltasortsplits(FindSplitData *state, double fillfactormult, + bool usemult) +{ + for (int i = 0; i < state->nsplits; i++) + { + SplitPoint *split = state->splits + i; + int16 delta; + + if (usemult) + delta = fillfactormult * split->leftfree - + (1.0 - fillfactormult) * split->rightfree; + else + delta = split->leftfree - split->rightfree; + + if (delta < 0) + delta = -delta; + + /* Save delta */ + split->curdelta = delta; + } + + qsort(state->splits, state->nsplits, sizeof(SplitPoint), _bt_splitcmp); +} + +/* + * qsort-style comparator used by _bt_deltasortsplits() + */ +static int +_bt_splitcmp(const void *arg1, const void *arg2) +{ + SplitPoint *split1 = (SplitPoint *) arg1; + SplitPoint *split2 = (SplitPoint *) arg2; + + if (split1->curdelta > split2->curdelta) + return 1; + if (split1->curdelta < split2->curdelta) + return -1; + + return 0; +} + +/* + * Subroutine to determine whether or not a non-rightmost leaf page should be + * split immediately after the would-be original page offset for the + * new/incoming tuple (or should have leaf fillfactor applied when new item is + * to the right on original page). This is appropriate when there is a + * pattern of localized monotonically increasing insertions into a composite + * index, where leading attribute values form local groupings, and we + * anticipate further insertions of the same/current grouping (new item's + * grouping) in the near future. This can be thought of as a variation on + * applying leaf fillfactor during rightmost leaf page splits, since cases + * that benefit will converge on packing leaf pages leaffillfactor% full over + * time. + * + * We may leave extra free space remaining on the rightmost page of a "most + * significant column" grouping of tuples if that grouping never ends up + * having future insertions that use the free space. That effect is + * self-limiting; a future grouping that becomes the "nearest on the right" + * grouping of the affected grouping usually puts the extra free space to good + * use. + * + * Caller uses optimization when routine returns true, though the exact action + * taken by caller varies. Caller uses original leaf page fillfactor in + * standard way rather than using the new item offset directly when *usemult + * was also set to true here. Otherwise, caller applies optimization by + * locating the legal split point that makes the new tuple the very last tuple + * on the left side of the split. + */ +static bool +_bt_afternewitemoff(FindSplitData *state, OffsetNumber maxoff, + int leaffillfactor, bool *usemult) +{ + int16 nkeyatts; + ItemId itemid; + IndexTuple tup; + int keepnatts; + + Assert(state->is_leaf && !state->is_rightmost); + + nkeyatts = IndexRelationGetNumberOfKeyAttributes(state->rel); + + /* Single key indexes not considered here */ + if (nkeyatts == 1) + return false; + + /* Ascending insertion pattern never inferred when new item is first */ + if (state->newitemoff == P_FIRSTKEY) + return false; + + /* + * Only apply optimization on pages with equisized tuples, since ordinal + * keys are likely to be fixed-width. Testing if the new tuple is + * variable width directly might also work, but that fails to apply the + * optimization to indexes with a numeric_ops attribute. + * + * Conclude that page has equisized tuples when the new item is the same + * width as the smallest item observed during pass over page, and other + * non-pivot tuples must be the same width as well. (Note that the + * possibly-truncated existing high key isn't counted in + * olddataitemstotal, and must be subtracted from maxoff.) + */ + if (state->newitemsz != state->minfirstrightsz) + return false; + if (state->newitemsz * (maxoff - 1) != state->olddataitemstotal) + return false; + + /* + * Avoid applying optimization when tuples are wider than a tuple + * consisting of two non-NULL int8/int64 attributes (or four non-NULL + * int4/int32 attributes) + */ + if (state->newitemsz > + MAXALIGN(sizeof(IndexTupleData) + sizeof(int64) * 2) + + sizeof(ItemIdData)) + return false; + + /* + * At least the first attribute's value must be equal to the corresponding + * value in previous tuple to apply optimization. New item cannot be a + * duplicate, either. + * + * Handle case where new item is to the right of all items on the existing + * page. This is suggestive of monotonically increasing insertions in + * itself, so the "heap TID adjacency" test is not applied here. + */ + if (state->newitemoff > maxoff) + { + itemid = PageGetItemId(state->page, maxoff); + tup = (IndexTuple) PageGetItem(state->page, itemid); + keepnatts = _bt_keep_natts_fast(state->rel, tup, state->newitem); + + if (keepnatts > 1 && keepnatts <= nkeyatts) + { + *usemult = true; + return true; + } + + return false; + } + + /* + * "Low cardinality leading column, high cardinality suffix column" + * indexes with a random insertion pattern (e.g., an index with a boolean + * column, such as an index on '(book_is_in_print, book_isbn)') present us + * with a risk of consistently misapplying the optimization. We're + * willing to accept very occasional misapplication of the optimization, + * provided the cases where we get it wrong are rare and self-limiting. + * + * Heap TID adjacency strongly suggests that the item just to the left was + * inserted very recently, which limits overapplication of the + * optimization. Besides, all inappropriate cases triggered here will + * still split in the middle of the page on average. + */ + itemid = PageGetItemId(state->page, OffsetNumberPrev(state->newitemoff)); + tup = (IndexTuple) PageGetItem(state->page, itemid); + /* Do cheaper test first */ + if (!_bt_adjacenthtid(&tup->t_tid, &state->newitem->t_tid)) + return false; + /* Check same conditions as rightmost item case, too */ + keepnatts = _bt_keep_natts_fast(state->rel, tup, state->newitem); + + if (keepnatts > 1 && keepnatts <= nkeyatts) + { + double interp = (double) state->newitemoff / ((double) maxoff + 1); + double leaffillfactormult = (double) leaffillfactor / 100.0; + + /* + * Don't allow caller to split after a new item when it will result in + * a split point to the right of the point that a leaf fillfactor + * split would use -- have caller apply leaf fillfactor instead + */ + *usemult = interp > leaffillfactormult; + + return true; + } + + return false; +} + +/* + * Subroutine for determining if two heap TIDS are "adjacent". + * + * Adjacent means that the high TID is very likely to have been inserted into + * heap relation immediately after the low TID, probably during the current + * transaction. + */ +static bool +_bt_adjacenthtid(ItemPointer lowhtid, ItemPointer highhtid) +{ + BlockNumber lowblk, + highblk; + + lowblk = ItemPointerGetBlockNumber(lowhtid); + highblk = ItemPointerGetBlockNumber(highhtid); + + /* Make optimistic assumption of adjacency when heap blocks match */ + if (lowblk == highblk) + return true; + + /* When heap block one up, second offset should be FirstOffsetNumber */ + if (lowblk + 1 == highblk && + ItemPointerGetOffsetNumber(highhtid) == FirstOffsetNumber) + return true; + + return false; +} + +/* + * Subroutine to find the "best" split point among candidate split points. + * The best split point is the split point with the lowest penalty among split + * points that fall within current/final split interval. Penalty is an + * abstract score, with a definition that varies depending on whether we're + * splitting a leaf page or an internal page. See _bt_split_penalty() for + * details. + * + * "perfectpenalty" is assumed to be the lowest possible penalty among + * candidate split points. This allows us to return early without wasting + * cycles on calculating the first differing attribute for all candidate + * splits when that clearly cannot improve our choice (or when we only want a + * minimally distinguishing split point, and don't want to make the split any + * more unbalanced than is necessary). + * + * We return the index of the first existing tuple that should go on the right + * page, plus a boolean indicating if new item is on left of split point. + */ +static OffsetNumber +_bt_bestsplitloc(FindSplitData *state, int perfectpenalty, + bool *newitemonleft, FindSplitStrat strategy) +{ + int bestpenalty, + lowsplit; + int highsplit = Min(state->interval, state->nsplits); + SplitPoint *final; + + bestpenalty = INT_MAX; + lowsplit = 0; + for (int i = lowsplit; i < highsplit; i++) + { + int penalty; + + penalty = _bt_split_penalty(state, state->splits + i); + + if (penalty <= perfectpenalty) + { + bestpenalty = penalty; + lowsplit = i; + break; + } + + if (penalty < bestpenalty) + { + bestpenalty = penalty; + lowsplit = i; + } + } + + final = &state->splits[lowsplit]; + + /* + * There is a risk that the "many duplicates" strategy will repeatedly do + * the wrong thing when there are monotonically decreasing insertions to + * the right of a large group of duplicates. Repeated splits could leave + * a succession of right half pages with free space that can never be + * used. This must be avoided. + * + * Consider the example of the leftmost page in a single integer attribute + * NULLS FIRST index which is almost filled with NULLs. Monotonically + * decreasing integer insertions might cause the same leftmost page to + * split repeatedly at the same point. Each split derives its new high + * key from the lowest current value to the immediate right of the large + * group of NULLs, which will always be higher than all future integer + * insertions, directing all future integer insertions to the same + * leftmost page. + */ + if (strategy == SPLIT_MANY_DUPLICATES && !state->is_rightmost && + !final->newitemonleft && final->firstoldonright >= state->newitemoff && + final->firstoldonright < state->newitemoff + MAX_LEAF_INTERVAL) + { + /* + * Avoid the problem by peforming a 50:50 split when the new item is + * just to the right of the would-be "many duplicates" split point. + */ + final = &state->splits[0]; + } + + *newitemonleft = final->newitemonleft; + return final->firstoldonright; +} + +/* + * Subroutine to decide whether split should use default strategy/initial + * split interval, or whether it should finish splitting the page using + * alternative strategies (this is only possible with leaf pages). + * + * Caller uses alternative strategy (or sticks with default strategy) based + * on how *strategy is set here. Return value is "perfect penalty", which is + * passed to _bt_bestsplitloc() as a final constraint on how far caller is + * willing to go to avoid appending a heap TID when using the many duplicates + * strategy (it also saves _bt_bestsplitloc() useless cycles). + */ +static int +_bt_strategy(FindSplitData *state, SplitPoint *leftpage, + SplitPoint *rightpage, FindSplitStrat *strategy) +{ + IndexTuple leftmost, + rightmost; + SplitPoint *leftinterval, + *rightinterval; + int perfectpenalty; + int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(state->rel); + + /* Assume that alternative strategy won't be used for now */ + *strategy = SPLIT_DEFAULT; + + /* + * Use smallest observed first right item size for entire page as perfect + * penalty on internal pages. This can save cycles in the common case + * where most or all splits (not just splits within interval) have first + * right tuples that are the same size. + */ + if (!state->is_leaf) + return state->minfirstrightsz; + + /* + * Use leftmost and rightmost tuples from leftmost and rightmost splits in + * current split interval + */ + _bt_interval_edges(state, &leftinterval, &rightinterval); + leftmost = _bt_split_lastleft(state, leftinterval); + rightmost = _bt_split_firstright(state, rightinterval); + + /* + * If initial split interval can produce a split point that will at least + * avoid appending a heap TID in new high key, we're done. Finish split + * with default strategy and initial split interval. + */ + perfectpenalty = _bt_keep_natts_fast(state->rel, leftmost, rightmost); + if (perfectpenalty <= indnkeyatts) + return perfectpenalty; + + /* + * Work out how caller should finish split when even their "perfect" + * penalty for initial/default split interval indicates that the interval + * does not contain even a single split that avoids appending a heap TID. + * + * Use the leftmost split's lastleft tuple and the rightmost split's + * firstright tuple to assess every possible split. + */ + leftmost = _bt_split_lastleft(state, leftpage); + rightmost = _bt_split_firstright(state, rightpage); + + /* + * If page (including new item) has many duplicates but is not entirely + * full of duplicates, a many duplicates strategy split will be performed. + * If page is entirely full of duplicates, a single value strategy split + * will be performed. + */ + perfectpenalty = _bt_keep_natts_fast(state->rel, leftmost, rightmost); + if (perfectpenalty <= indnkeyatts) + { + *strategy = SPLIT_MANY_DUPLICATES; + + /* + * Many duplicates strategy should split at either side the group of + * duplicates that enclose the delta-optimal split point. Return + * indnkeyatts rather than the true perfect penalty to make that + * happen. (If perfectpenalty was returned here then low cardinality + * composite indexes could have continual unbalanced splits.) + * + * Note that caller won't go through with a many duplicates split in + * rare cases where it looks like there are ever-decreasing insertions + * to the immediate right of the split point. This must happen just + * before a final decision is made, within _bt_bestsplitloc(). + */ + return indnkeyatts; + } + + /* + * Single value strategy is only appropriate with ever-increasing heap + * TIDs; otherwise, original default strategy split should proceed to + * avoid pathological performance. Use page high key to infer if this is + * the rightmost page among pages that store the same duplicate value. + * This should not prevent insertions of heap TIDs that are slightly out + * of order from using single value strategy, since that's expected with + * concurrent inserters of the same duplicate value. + */ + else if (state->is_rightmost) + *strategy = SPLIT_SINGLE_VALUE; + else + { + ItemId itemid; + IndexTuple hikey; + + itemid = PageGetItemId(state->page, P_HIKEY); + hikey = (IndexTuple) PageGetItem(state->page, itemid); + perfectpenalty = _bt_keep_natts_fast(state->rel, hikey, + state->newitem); + if (perfectpenalty <= indnkeyatts) + *strategy = SPLIT_SINGLE_VALUE; + else + { + /* + * Have caller finish split using default strategy, since page + * does not appear to be the rightmost page for duplicates of the + * value the page is filled with + */ + } + } + + return perfectpenalty; +} + +/* + * Subroutine to locate leftmost and rightmost splits for current/default + * split interval. Note that it will be the same split iff there is only one + * split in interval. + */ +static void +_bt_interval_edges(FindSplitData *state, SplitPoint **leftinterval, + SplitPoint **rightinterval) +{ + int highsplit = Min(state->interval, state->nsplits); + SplitPoint *deltaoptimal; + + deltaoptimal = state->splits; + *leftinterval = NULL; + *rightinterval = NULL; + + /* + * Delta is an absolute distance to optimal split point, so both the + * leftmost and rightmost split point will usually be at the end of the + * array + */ + for (int i = highsplit - 1; i >= 0; i--) + { + SplitPoint *distant = state->splits + i; + + if (distant->firstoldonright < deltaoptimal->firstoldonright) + { + if (*leftinterval == NULL) + *leftinterval = distant; + } + else if (distant->firstoldonright > deltaoptimal->firstoldonright) + { + if (*rightinterval == NULL) + *rightinterval = distant; + } + else if (!distant->newitemonleft && deltaoptimal->newitemonleft) + { + /* + * "incoming tuple will become first on right page" (distant) is + * to the left of "incoming tuple will become last on left page" + * (delta-optimal) + */ + Assert(distant->firstoldonright == state->newitemoff); + if (*leftinterval == NULL) + *leftinterval = distant; + } + else if (distant->newitemonleft && !deltaoptimal->newitemonleft) + { + /* + * "incoming tuple will become last on left page" (distant) is to + * the right of "incoming tuple will become first on right page" + * (delta-optimal) + */ + Assert(distant->firstoldonright == state->newitemoff); + if (*rightinterval == NULL) + *rightinterval = distant; + } + else + { + /* There was only one or two splits in initial split interval */ + Assert(distant == deltaoptimal); + if (*leftinterval == NULL) + *leftinterval = distant; + if (*rightinterval == NULL) + *rightinterval = distant; + } + + if (*leftinterval && *rightinterval) + return; + } + + Assert(false); +} + +/* + * Subroutine to find penalty for caller's candidate split point. + * + * On leaf pages, penalty is the attribute number that distinguishes each side + * of a split. It's the last attribute that needs to be included in new high + * key for left page. It can be greater than the number of key attributes in + * cases where a heap TID will need to be appended during truncation. + * + * On internal pages, penalty is simply the size of the first item on the + * right half of the split (including line pointer overhead). This tuple will + * become the new high key for the left page. + */ +static inline int +_bt_split_penalty(FindSplitData *state, SplitPoint *split) +{ + IndexTuple lastleftuple; + IndexTuple firstrighttuple; + + if (!state->is_leaf) + { + ItemId itemid; + + if (!split->newitemonleft && + split->firstoldonright == state->newitemoff) + return state->newitemsz; + + itemid = PageGetItemId(state->page, split->firstoldonright); + + return MAXALIGN(ItemIdGetLength(itemid)) + sizeof(ItemIdData); + } + + lastleftuple = _bt_split_lastleft(state, split); + firstrighttuple = _bt_split_firstright(state, split); + + Assert(lastleftuple != firstrighttuple); + return _bt_keep_natts_fast(state->rel, lastleftuple, firstrighttuple); +} + +/* + * Subroutine to get a lastleft IndexTuple for a split point from page + */ +static inline IndexTuple +_bt_split_lastleft(FindSplitData *state, SplitPoint *split) +{ + ItemId itemid; + + if (split->newitemonleft && split->firstoldonright == state->newitemoff) + return state->newitem; + + itemid = PageGetItemId(state->page, + OffsetNumberPrev(split->firstoldonright)); + return (IndexTuple) PageGetItem(state->page, itemid); +} + +/* + * Subroutine to get a firstright IndexTuple for a split point from page + */ +static inline IndexTuple +_bt_split_firstright(FindSplitData *state, SplitPoint *split) +{ + ItemId itemid; + + if (!split->newitemonleft && split->firstoldonright == state->newitemoff) + return state->newitem; + + itemid = PageGetItemId(state->page, split->firstoldonright); + return (IndexTuple) PageGetItem(state->page, itemid); +} diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 12b636253e7..bc855dd25dc 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -3,7 +3,7 @@ * nbtutils.c * Utility code for Postgres btree implementation. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,8 +20,10 @@ #include "access/nbtree.h" #include "access/reloptions.h" #include "access/relscan.h" +#include "commands/progress.h" #include "miscadmin.h" #include "utils/array.h" +#include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -35,20 +37,22 @@ typedef struct BTSortArrayContext } BTSortArrayContext; static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, - StrategyNumber strat, - Datum *elems, int nelems); -static int _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey, - bool reverse, - Datum *elems, int nelems); + StrategyNumber strat, + Datum *elems, int nelems); +static int _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey, + bool reverse, + Datum *elems, int nelems); static int _bt_compare_array_elements(const void *a, const void *b, void *arg); static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, - ScanKey leftarg, ScanKey rightarg, - bool *result); + ScanKey leftarg, ScanKey rightarg, + bool *result); static bool _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption); static void _bt_mark_scankey_required(ScanKey skey); static bool _bt_check_rowcompare(ScanKey skey, - IndexTuple tuple, TupleDesc tupdesc, - ScanDirection dir, bool *continuescan); + IndexTuple tuple, int tupnatts, TupleDesc tupdesc, + ScanDirection dir, bool *continuescan); +static int _bt_keep_natts(Relation rel, IndexTuple lastleft, + IndexTuple firstright, BTScanInsert itup_key); /* @@ -56,34 +60,60 @@ static bool _bt_check_rowcompare(ScanKey skey, * Build an insertion scan key that contains comparison data from itup * as well as comparator routines appropriate to the key datatypes. * - * The result is intended for use with _bt_compare(). + * When itup is a non-pivot tuple, the returned insertion scan key is + * suitable for finding a place for it to go on the leaf level. Pivot + * tuples can be used to re-find leaf page with matching high key, but + * then caller needs to set scan key's pivotsearch field to true. This + * allows caller to search for a leaf page with a matching high key, + * which is usually to the left of the first leaf page a non-pivot match + * might appear on. + * + * The result is intended for use with _bt_compare() and _bt_truncate(). + * Callers that don't need to fill out the insertion scankey arguments + * (e.g. they use an ad-hoc comparison routine, or only need a scankey + * for _bt_truncate()) can pass a NULL index tuple. The scankey will + * be initialized as if an "all truncated" pivot tuple was passed + * instead. + * + * Note that we may occasionally have to share lock the metapage to + * determine whether or not the keys in the index are expected to be + * unique (i.e. if this is a "heapkeyspace" index). We assume a + * heapkeyspace index when caller passes a NULL tuple, allowing index + * build callers to avoid accessing the non-existent metapage. */ -ScanKey +BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup) { + BTScanInsert key; ScanKey skey; TupleDesc itupdesc; - int indnatts PG_USED_FOR_ASSERTS_ONLY; int indnkeyatts; int16 *indoption; + int tupnatts; int i; itupdesc = RelationGetDescr(rel); - indnatts = IndexRelationGetNumberOfAttributes(rel); indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); indoption = rel->rd_indoption; + tupnatts = itup ? BTreeTupleGetNAtts(itup, rel) : 0; - Assert(indnkeyatts != 0); - Assert(indnkeyatts <= indnatts); - Assert(BTreeTupGetNAtts(itup, rel) == indnatts || - BTreeTupGetNAtts(itup, rel) == indnkeyatts); + Assert(tupnatts <= IndexRelationGetNumberOfAttributes(rel)); /* - * We'll execute search using ScanKey constructed on key columns. Non key - * (included) columns must be omitted. + * We'll execute search using scan key constructed on key columns. + * Truncated attributes and non-key attributes are omitted from the final + * scan key. */ - skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData)); - + key = palloc(offsetof(BTScanInsertData, scankeys) + + sizeof(ScanKeyData) * indnkeyatts); + key->heapkeyspace = itup == NULL || _bt_heapkeyspace(rel); + key->anynullkeys = false; /* initial assumption */ + key->nextkey = false; + key->pivotsearch = false; + key->keysz = Min(indnkeyatts, tupnatts); + key->scantid = key->heapkeyspace && itup ? + BTreeTupleGetHeapTID(itup) : NULL; + skey = key->scankeys; for (i = 0; i < indnkeyatts; i++) { FmgrInfo *procinfo; @@ -96,56 +126,20 @@ _bt_mkscankey(Relation rel, IndexTuple itup) * comparison can be needed. */ procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); - arg = index_getattr(itup, i + 1, itupdesc, &null); - flags = (null ? SK_ISNULL : 0) | (indoption[i] << SK_BT_INDOPTION_SHIFT); - ScanKeyEntryInitializeWithInfo(&skey[i], - flags, - (AttrNumber) (i + 1), - InvalidStrategy, - InvalidOid, - rel->rd_indcollation[i], - procinfo, - arg); - } - - return skey; -} - -/* - * _bt_mkscankey_nodata - * Build an insertion scan key that contains 3-way comparator routines - * appropriate to the key datatypes, but no comparison data. The - * comparison data ultimately used must match the key datatypes. - * - * The result cannot be used with _bt_compare(), unless comparison - * data is first stored into the key entries. Currently this - * routine is only called by nbtsort.c and tuplesort.c, which have - * their own comparison routines. - */ -ScanKey -_bt_mkscankey_nodata(Relation rel) -{ - ScanKey skey; - int indnkeyatts; - int16 *indoption; - int i; - - indnkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); - indoption = rel->rd_indoption; - - skey = (ScanKey) palloc(indnkeyatts * sizeof(ScanKeyData)); - - for (i = 0; i < indnkeyatts; i++) - { - FmgrInfo *procinfo; - int flags; /* - * We can use the cached (default) support procs since no cross-type - * comparison can be needed. + * Key arguments built from truncated attributes (or when caller + * provides no tuple) are defensively represented as NULL values. They + * should never be used. */ - procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC); - flags = SK_ISNULL | (indoption[i] << SK_BT_INDOPTION_SHIFT); + if (i < tupnatts) + arg = index_getattr(itup, i + 1, itupdesc, &null); + else + { + arg = (Datum) 0; + null = true; + } + flags = (null ? SK_ISNULL : 0) | (indoption[i] << SK_BT_INDOPTION_SHIFT); ScanKeyEntryInitializeWithInfo(&skey[i], flags, (AttrNumber) (i + 1), @@ -153,19 +147,13 @@ _bt_mkscankey_nodata(Relation rel) InvalidOid, rel->rd_indcollation[i], procinfo, - (Datum) 0); + arg); + /* Record if any key attribute is NULL (or truncated) */ + if (null) + key->anynullkeys = true; } - return skey; -} - -/* - * free a scan key made by either _bt_mkscankey or _bt_mkscankey_nodata. - */ -void -_bt_freeskey(ScanKey skey) -{ - pfree(skey); + return key; } /* @@ -518,7 +506,7 @@ _bt_compare_array_elements(const void *a, const void *b, void *arg) cxt->collation, da, db)); if (cxt->reverse) - compare = -compare; + INVERT_COMPARE_RESULT(compare); return compare; } @@ -676,7 +664,7 @@ _bt_restore_array_keys(IndexScanDesc scan) * scan->numberOfKeys is the number of input keys, so->numberOfKeys gets * the number of output keys (possibly less, never greater). * - * The output keys are marked with additional sk_flag bits beyond the + * The output keys are marked with additional sk_flags bits beyond the * system-standard bits supplied by the caller. The DESC and NULLS_FIRST * indoption bits for the relevant index attribute are copied into the flags. * Also, for a DESC column, we commute (flip) all the sk_strategy numbers @@ -1350,72 +1338,34 @@ _bt_mark_scankey_required(ScanKey skey) /* * Test whether an indextuple satisfies all the scankey conditions. * - * If so, return the address of the index tuple on the index page. - * If not, return NULL. + * Return true if so, false if not. If the tuple fails to pass the qual, + * we also determine whether there's any need to continue the scan beyond + * this tuple, and set *continuescan accordingly. See comments for + * _bt_preprocess_keys(), above, about how this is done. * - * If the tuple fails to pass the qual, we also determine whether there's - * any need to continue the scan beyond this tuple, and set *continuescan - * accordingly. See comments for _bt_preprocess_keys(), above, about how - * this is done. + * Forward scan callers can pass a high key tuple in the hopes of having + * us set *continuescan to false, and avoiding an unnecessary visit to + * the page to the right. * * scan: index scan descriptor (containing a search-type scankey) - * page: buffer page containing index tuple - * offnum: offset number of index tuple (must be a valid item!) + * tuple: index tuple to test + * tupnatts: number of attributes in tupnatts (high key may be truncated) * dir: direction we are scanning in * continuescan: output parameter (will be set correctly in all cases) - * - * Caller must hold pin and lock on the index page. */ -IndexTuple -_bt_checkkeys(IndexScanDesc scan, - Page page, OffsetNumber offnum, +bool +_bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, ScanDirection dir, bool *continuescan) { - ItemId iid = PageGetItemId(page, offnum); - bool tuple_alive; - IndexTuple tuple; TupleDesc tupdesc; BTScanOpaque so; int keysz; int ikey; ScanKey key; - *continuescan = true; /* default assumption */ - - /* - * If the scan specifies not to return killed tuples, then we treat a - * killed tuple as not passing the qual. Most of the time, it's a win to - * not bother examining the tuple's index keys, but just return - * immediately with continuescan = true to proceed to the next tuple. - * However, if this is the last tuple on the page, we should check the - * index keys to prevent uselessly advancing to the next page. - */ - if (scan->ignore_killed_tuples && ItemIdIsDead(iid)) - { - /* return immediately if there are more tuples on the page */ - if (ScanDirectionIsForward(dir)) - { - if (offnum < PageGetMaxOffsetNumber(page)) - return NULL; - } - else - { - BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); - - if (offnum > P_FIRSTDATAKEY(opaque)) - return NULL; - } + Assert(BTreeTupleGetNAtts(tuple, scan->indexRelation) == tupnatts); - /* - * OK, we want to check the keys so we can set continuescan correctly, - * but we'll return NULL even if the tuple passes the key tests. - */ - tuple_alive = false; - } - else - tuple_alive = true; - - tuple = (IndexTuple) PageGetItem(page, iid); + *continuescan = true; /* default assumption */ tupdesc = RelationGetDescr(scan->indexRelation); so = (BTScanOpaque) scan->opaque; @@ -1427,12 +1377,25 @@ _bt_checkkeys(IndexScanDesc scan, bool isNull; Datum test; + if (key->sk_attno > tupnatts) + { + /* + * This attribute is truncated (must be high key). The value for + * this attribute in the first non-pivot tuple on the page to the + * right could be any possible value. Assume that truncated + * attribute passes the qual. + */ + Assert(ScanDirectionIsForward(dir)); + continue; + } + /* row-comparison keys need special processing */ if (key->sk_flags & SK_ROW_HEADER) { - if (_bt_check_rowcompare(key, tuple, tupdesc, dir, continuescan)) + if (_bt_check_rowcompare(key, tuple, tupnatts, tupdesc, dir, + continuescan)) continue; - return NULL; + return false; } datum = index_getattr(tuple, @@ -1470,7 +1433,7 @@ _bt_checkkeys(IndexScanDesc scan, /* * In any case, this indextuple doesn't match the qual. */ - return NULL; + return false; } if (isNull) @@ -1511,7 +1474,7 @@ _bt_checkkeys(IndexScanDesc scan, /* * In any case, this indextuple doesn't match the qual. */ - return NULL; + return false; } test = FunctionCall2Coll(&key->sk_func, key->sk_collation, @@ -1539,16 +1502,12 @@ _bt_checkkeys(IndexScanDesc scan, /* * In any case, this indextuple doesn't match the qual. */ - return NULL; + return false; } } - /* Check for failure due to it being a killed tuple. */ - if (!tuple_alive) - return NULL; - /* If we get here, the tuple passes all index quals. */ - return tuple; + return true; } /* @@ -1561,8 +1520,8 @@ _bt_checkkeys(IndexScanDesc scan, * This is a subroutine for _bt_checkkeys, which see for more info. */ static bool -_bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc, - ScanDirection dir, bool *continuescan) +_bt_check_rowcompare(ScanKey skey, IndexTuple tuple, int tupnatts, + TupleDesc tupdesc, ScanDirection dir, bool *continuescan) { ScanKey subkey = (ScanKey) DatumGetPointer(skey->sk_argument); int32 cmpresult = 0; @@ -1579,6 +1538,22 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc, Assert(subkey->sk_flags & SK_ROW_MEMBER); + if (subkey->sk_attno > tupnatts) + { + /* + * This attribute is truncated (must be high key). The value for + * this attribute in the first non-pivot tuple on the page to the + * right could be any possible value. Assume that truncated + * attribute passes the qual. + */ + Assert(ScanDirectionIsForward(dir)); + cmpresult = 0; + if (subkey->sk_flags & SK_ROW_END) + break; + subkey++; + continue; + } + datum = index_getattr(tuple, subkey->sk_attno, tupdesc, @@ -1651,7 +1626,7 @@ _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, TupleDesc tupdesc, subkey->sk_argument)); if (subkey->sk_flags & SK_BT_DESC) - cmpresult = -cmpresult; + INVERT_COMPARE_RESULT(cmpresult); /* Done comparing if unequal, else advance to next column */ if (cmpresult != 0) @@ -2082,28 +2057,516 @@ btproperty(Oid index_oid, int attno, } /* - * _bt_truncate_tuple() -- remove non-key (INCLUDE) attributes from index - * tuple. + * btbuildphasename() -- Return name of index build phase. + */ +char * +btbuildphasename(int64 phasenum) +{ + switch (phasenum) + { + case PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE: + return "initializing"; + case PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN: + return "scanning table"; + case PROGRESS_BTREE_PHASE_PERFORMSORT_1: + return "sorting live tuples"; + case PROGRESS_BTREE_PHASE_PERFORMSORT_2: + return "sorting dead tuples"; + case PROGRESS_BTREE_PHASE_LEAF_LOAD: + return "loading tuples in tree"; + default: + return NULL; + } +} + +/* + * _bt_truncate() -- create tuple without unneeded suffix attributes. + * + * Returns truncated pivot index tuple allocated in caller's memory context, + * with key attributes copied from caller's firstright argument. If rel is + * an INCLUDE index, non-key attributes will definitely be truncated away, + * since they're not part of the key space. More aggressive suffix + * truncation can take place when it's clear that the returned tuple does not + * need one or more suffix key attributes. We only need to keep firstright + * attributes up to and including the first non-lastleft-equal attribute. + * Caller's insertion scankey is used to compare the tuples; the scankey's + * argument values are not considered here. + * + * Note that returned tuple's t_tid offset will hold the number of attributes + * present, so the original item pointer offset is not represented. Caller + * should only change truncated tuple's downlink. Note also that truncated + * key attributes are treated as containing "minus infinity" values by + * _bt_compare(). * - * Transforms an ordinal B-tree leaf index tuple into pivot tuple to be used - * as hikey or non-leaf page tuple with downlink. Note that t_tid offset - * will be overritten in order to represent number of present tuple attributes. + * In the worst case (when a heap TID must be appended to distinguish lastleft + * from firstright), the size of the returned tuple is the size of firstright + * plus the size of an additional MAXALIGN()'d item pointer. This guarantee + * is important, since callers need to stay under the 1/3 of a page + * restriction on tuple size. If this routine is ever taught to truncate + * within an attribute/datum, it will need to avoid returning an enlarged + * tuple to caller when truncation + TOAST compression ends up enlarging the + * final datum. */ IndexTuple -_bt_truncate_tuple(Relation idxrel, IndexTuple olditup) +_bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, + BTScanInsert itup_key) +{ + TupleDesc itupdesc = RelationGetDescr(rel); + int16 natts = IndexRelationGetNumberOfAttributes(rel); + int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); + int keepnatts; + IndexTuple pivot; + ItemPointer pivotheaptid; + Size newsize; + + /* + * We should only ever truncate leaf index tuples. It's never okay to + * truncate a second time. + */ + Assert(BTreeTupleGetNAtts(lastleft, rel) == natts); + Assert(BTreeTupleGetNAtts(firstright, rel) == natts); + + /* Determine how many attributes must be kept in truncated tuple */ + keepnatts = _bt_keep_natts(rel, lastleft, firstright, itup_key); + +#ifdef DEBUG_NO_TRUNCATE + /* Force truncation to be ineffective for testing purposes */ + keepnatts = nkeyatts + 1; +#endif + + if (keepnatts <= natts) + { + IndexTuple tidpivot; + + pivot = index_truncate_tuple(itupdesc, firstright, keepnatts); + + /* + * If there is a distinguishing key attribute within new pivot tuple, + * there is no need to add an explicit heap TID attribute + */ + if (keepnatts <= nkeyatts) + { + BTreeTupleSetNAtts(pivot, keepnatts); + return pivot; + } + + /* + * Only truncation of non-key attributes was possible, since key + * attributes are all equal. It's necessary to add a heap TID + * attribute to the new pivot tuple. + */ + Assert(natts != nkeyatts); + newsize = IndexTupleSize(pivot) + MAXALIGN(sizeof(ItemPointerData)); + tidpivot = palloc0(newsize); + memcpy(tidpivot, pivot, IndexTupleSize(pivot)); + /* cannot leak memory here */ + pfree(pivot); + pivot = tidpivot; + } + else + { + /* + * No truncation was possible, since key attributes are all equal. + * It's necessary to add a heap TID attribute to the new pivot tuple. + */ + Assert(natts == nkeyatts); + newsize = IndexTupleSize(firstright) + MAXALIGN(sizeof(ItemPointerData)); + pivot = palloc0(newsize); + memcpy(pivot, firstright, IndexTupleSize(firstright)); + } + + /* + * We have to use heap TID as a unique-ifier in the new pivot tuple, since + * no non-TID key attribute in the right item readily distinguishes the + * right side of the split from the left side. Use enlarged space that + * holds a copy of first right tuple; place a heap TID value within the + * extra space that remains at the end. + * + * nbtree conceptualizes this case as an inability to truncate away any + * key attribute. We must use an alternative representation of heap TID + * within pivots because heap TID is only treated as an attribute within + * nbtree (e.g., there is no pg_attribute entry). + */ + Assert(itup_key->heapkeyspace); + pivot->t_info &= ~INDEX_SIZE_MASK; + pivot->t_info |= newsize; + + /* + * Lehman & Yao use lastleft as the leaf high key in all cases, but don't + * consider suffix truncation. It seems like a good idea to follow that + * example in cases where no truncation takes place -- use lastleft's heap + * TID. (This is also the closest value to negative infinity that's + * legally usable.) + */ + pivotheaptid = (ItemPointer) ((char *) pivot + newsize - + sizeof(ItemPointerData)); + ItemPointerCopy(&lastleft->t_tid, pivotheaptid); + + /* + * Lehman and Yao require that the downlink to the right page, which is to + * be inserted into the parent page in the second phase of a page split be + * a strict lower bound on items on the right page, and a non-strict upper + * bound for items on the left page. Assert that heap TIDs follow these + * invariants, since a heap TID value is apparently needed as a + * tiebreaker. + */ +#ifndef DEBUG_NO_TRUNCATE + Assert(ItemPointerCompare(&lastleft->t_tid, &firstright->t_tid) < 0); + Assert(ItemPointerCompare(pivotheaptid, &lastleft->t_tid) >= 0); + Assert(ItemPointerCompare(pivotheaptid, &firstright->t_tid) < 0); +#else + + /* + * Those invariants aren't guaranteed to hold for lastleft + firstright + * heap TID attribute values when they're considered here only because + * DEBUG_NO_TRUNCATE is defined (a heap TID is probably not actually + * needed as a tiebreaker). DEBUG_NO_TRUNCATE must therefore use a heap + * TID value that always works as a strict lower bound for items to the + * right. In particular, it must avoid using firstright's leading key + * attribute values along with lastleft's heap TID value when lastleft's + * TID happens to be greater than firstright's TID. + */ + ItemPointerCopy(&firstright->t_tid, pivotheaptid); + + /* + * Pivot heap TID should never be fully equal to firstright. Note that + * the pivot heap TID will still end up equal to lastleft's heap TID when + * that's the only usable value. + */ + ItemPointerSetOffsetNumber(pivotheaptid, + OffsetNumberPrev(ItemPointerGetOffsetNumber(pivotheaptid))); + Assert(ItemPointerCompare(pivotheaptid, &firstright->t_tid) < 0); +#endif + + BTreeTupleSetNAtts(pivot, nkeyatts); + BTreeTupleSetAltHeapTID(pivot); + + return pivot; +} + +/* + * _bt_keep_natts - how many key attributes to keep when truncating. + * + * Caller provides two tuples that enclose a split point. Caller's insertion + * scankey is used to compare the tuples; the scankey's argument values are + * not considered here. + * + * This can return a number of attributes that is one greater than the + * number of key attributes for the index relation. This indicates that the + * caller must use a heap TID as a unique-ifier in new pivot tuple. + */ +static int +_bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright, + BTScanInsert itup_key) { - IndexTuple newitup; - int nkeyattrs = IndexRelationGetNumberOfKeyAttributes(idxrel); + int nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); + TupleDesc itupdesc = RelationGetDescr(rel); + int keepnatts; + ScanKey scankey; /* - * We're assuming to truncate only regular leaf index tuples which have - * both key and non-key attributes. + * Be consistent about the representation of BTREE_VERSION 2/3 tuples + * across Postgres versions; don't allow new pivot tuples to have + * truncated key attributes there. _bt_compare() treats truncated key + * attributes as having the value minus infinity, which would break + * searches within !heapkeyspace indexes. */ - Assert(BTreeTupGetNAtts(olditup, idxrel) == IndexRelationGetNumberOfAttributes(idxrel)); + if (!itup_key->heapkeyspace) + { + Assert(nkeyatts != IndexRelationGetNumberOfAttributes(rel)); + return nkeyatts; + } - newitup = index_truncate_tuple(RelationGetDescr(idxrel), - olditup, nkeyattrs); - BTreeTupSetNAtts(newitup, nkeyattrs); + scankey = itup_key->scankeys; + keepnatts = 1; + for (int attnum = 1; attnum <= nkeyatts; attnum++, scankey++) + { + Datum datum1, + datum2; + bool isNull1, + isNull2; + + datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1); + datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2); + + if (isNull1 != isNull2) + break; - return newitup; + if (!isNull1 && + DatumGetInt32(FunctionCall2Coll(&scankey->sk_func, + scankey->sk_collation, + datum1, + datum2)) != 0) + break; + + keepnatts++; + } + + return keepnatts; +} + +/* + * _bt_keep_natts_fast - fast bitwise variant of _bt_keep_natts. + * + * This is exported so that a candidate split point can have its effect on + * suffix truncation inexpensively evaluated ahead of time when finding a + * split location. A naive bitwise approach to datum comparisons is used to + * save cycles. + * + * The approach taken here usually provides the same answer as _bt_keep_natts + * will (for the same pair of tuples from a heapkeyspace index), since the + * majority of btree opclasses can never indicate that two datums are equal + * unless they're bitwise equal (once detoasted). Similarly, result may + * differ from the _bt_keep_natts result when either tuple has TOASTed datums, + * though this is barely possible in practice. + * + * These issues must be acceptable to callers, typically because they're only + * concerned about making suffix truncation as effective as possible without + * leaving excessive amounts of free space on either side of page split. + * Callers can rely on the fact that attributes considered equal here are + * definitely also equal according to _bt_keep_natts. + */ +int +_bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright) +{ + TupleDesc itupdesc = RelationGetDescr(rel); + int keysz = IndexRelationGetNumberOfKeyAttributes(rel); + int keepnatts; + + keepnatts = 1; + for (int attnum = 1; attnum <= keysz; attnum++) + { + Datum datum1, + datum2; + bool isNull1, + isNull2; + Form_pg_attribute att; + + datum1 = index_getattr(lastleft, attnum, itupdesc, &isNull1); + datum2 = index_getattr(firstright, attnum, itupdesc, &isNull2); + att = TupleDescAttr(itupdesc, attnum - 1); + + if (isNull1 != isNull2) + break; + + if (!isNull1 && + !datumIsEqual(datum1, datum2, att->attbyval, att->attlen)) + break; + + keepnatts++; + } + + return keepnatts; +} + +/* + * _bt_check_natts() -- Verify tuple has expected number of attributes. + * + * Returns value indicating if the expected number of attributes were found + * for a particular offset on page. This can be used as a general purpose + * sanity check. + * + * Testing a tuple directly with BTreeTupleGetNAtts() should generally be + * preferred to calling here. That's usually more convenient, and is always + * more explicit. Call here instead when offnum's tuple may be a negative + * infinity tuple that uses the pre-v11 on-disk representation, or when a low + * context check is appropriate. This routine is as strict as possible about + * what is expected on each version of btree. + */ +bool +_bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum) +{ + int16 natts = IndexRelationGetNumberOfAttributes(rel); + int16 nkeyatts = IndexRelationGetNumberOfKeyAttributes(rel); + BTPageOpaque opaque = (BTPageOpaque) PageGetSpecialPointer(page); + IndexTuple itup; + int tupnatts; + + /* + * We cannot reliably test a deleted or half-dead page, since they have + * dummy high keys + */ + if (P_IGNORE(opaque)) + return true; + + Assert(offnum >= FirstOffsetNumber && + offnum <= PageGetMaxOffsetNumber(page)); + + /* + * Mask allocated for number of keys in index tuple must be able to fit + * maximum possible number of index attributes + */ + StaticAssertStmt(BT_N_KEYS_OFFSET_MASK >= INDEX_MAX_KEYS, + "BT_N_KEYS_OFFSET_MASK can't fit INDEX_MAX_KEYS"); + + itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum)); + tupnatts = BTreeTupleGetNAtts(itup, rel); + + if (P_ISLEAF(opaque)) + { + if (offnum >= P_FIRSTDATAKEY(opaque)) + { + /* + * Non-pivot tuples currently never use alternative heap TID + * representation -- even those within heapkeyspace indexes + */ + if ((itup->t_info & INDEX_ALT_TID_MASK) != 0) + return false; + + /* + * Leaf tuples that are not the page high key (non-pivot tuples) + * should never be truncated. (Note that tupnatts must have been + * inferred, rather than coming from an explicit on-disk + * representation.) + */ + return tupnatts == natts; + } + else + { + /* + * Rightmost page doesn't contain a page high key, so tuple was + * checked above as ordinary leaf tuple + */ + Assert(!P_RIGHTMOST(opaque)); + + /* + * !heapkeyspace high key tuple contains only key attributes. Note + * that tupnatts will only have been explicitly represented in + * !heapkeyspace indexes that happen to have non-key attributes. + */ + if (!heapkeyspace) + return tupnatts == nkeyatts; + + /* Use generic heapkeyspace pivot tuple handling */ + } + } + else /* !P_ISLEAF(opaque) */ + { + if (offnum == P_FIRSTDATAKEY(opaque)) + { + /* + * The first tuple on any internal page (possibly the first after + * its high key) is its negative infinity tuple. Negative + * infinity tuples are always truncated to zero attributes. They + * are a particular kind of pivot tuple. + */ + if (heapkeyspace) + return tupnatts == 0; + + /* + * The number of attributes won't be explicitly represented if the + * negative infinity tuple was generated during a page split that + * occurred with a version of Postgres before v11. There must be + * a problem when there is an explicit representation that is + * non-zero, or when there is no explicit representation and the + * tuple is evidently not a pre-pg_upgrade tuple. + * + * Prior to v11, downlinks always had P_HIKEY as their offset. Use + * that to decide if the tuple is a pre-v11 tuple. + */ + return tupnatts == 0 || + ((itup->t_info & INDEX_ALT_TID_MASK) == 0 && + ItemPointerGetOffsetNumber(&(itup->t_tid)) == P_HIKEY); + } + else + { + /* + * !heapkeyspace downlink tuple with separator key contains only + * key attributes. Note that tupnatts will only have been + * explicitly represented in !heapkeyspace indexes that happen to + * have non-key attributes. + */ + if (!heapkeyspace) + return tupnatts == nkeyatts; + + /* Use generic heapkeyspace pivot tuple handling */ + } + + } + + /* Handle heapkeyspace pivot tuples (excluding minus infinity items) */ + Assert(heapkeyspace); + + /* + * Explicit representation of the number of attributes is mandatory with + * heapkeyspace index pivot tuples, regardless of whether or not there are + * non-key attributes. + */ + if ((itup->t_info & INDEX_ALT_TID_MASK) == 0) + return false; + + /* + * Heap TID is a tiebreaker key attribute, so it cannot be untruncated + * when any other key attribute is truncated + */ + if (BTreeTupleGetHeapTID(itup) != NULL && tupnatts != nkeyatts) + return false; + + /* + * Pivot tuple must have at least one untruncated key attribute (minus + * infinity pivot tuples are the only exception). Pivot tuples can never + * represent that there is a value present for a key attribute that + * exceeds pg_index.indnkeyatts for the index. + */ + return tupnatts > 0 && tupnatts <= nkeyatts; +} + +/* + * + * _bt_check_third_page() -- check whether tuple fits on a btree page at all. + * + * We actually need to be able to fit three items on every page, so restrict + * any one item to 1/3 the per-page available space. Note that itemsz should + * not include the ItemId overhead. + * + * It might be useful to apply TOAST methods rather than throw an error here. + * Using out of line storage would break assumptions made by suffix truncation + * and by contrib/amcheck, though. + */ +void +_bt_check_third_page(Relation rel, Relation heap, bool needheaptidspace, + Page page, IndexTuple newtup) +{ + Size itemsz; + BTPageOpaque opaque; + + itemsz = MAXALIGN(IndexTupleSize(newtup)); + + /* Double check item size against limit */ + if (itemsz <= BTMaxItemSize(page)) + return; + + /* + * Tuple is probably too large to fit on page, but it's possible that the + * index uses version 2 or version 3, or that page is an internal page, in + * which case a slightly higher limit applies. + */ + if (!needheaptidspace && itemsz <= BTMaxItemSizeNoHeapTid(page)) + return; + + /* + * Internal page insertions cannot fail here, because that would mean that + * an earlier leaf level insertion that should have failed didn't + */ + opaque = (BTPageOpaque) PageGetSpecialPointer(page); + if (!P_ISLEAF(opaque)) + elog(ERROR, "cannot insert oversized tuple of size %zu on internal page of index \"%s\"", + itemsz, RelationGetRelationName(rel)); + + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("index row size %zu exceeds btree version %u maximum %zu for index \"%s\"", + itemsz, + needheaptidspace ? BTREE_VERSION : BTREE_NOVAC_VERSION, + needheaptidspace ? BTMaxItemSize(page) : + BTMaxItemSizeNoHeapTid(page), + RelationGetRelationName(rel)), + errdetail("Index row references tuple (%u,%u) in relation \"%s\".", + ItemPointerGetBlockNumber(&newtup->t_tid), + ItemPointerGetOffsetNumber(&newtup->t_tid), + RelationGetRelationName(heap)), + errhint("Values larger than 1/3 of a buffer page cannot be indexed.\n" + "Consider a function index of an MD5 hash of the value, " + "or use full text indexing."), + errtableconstraint(heap, RelationGetRelationName(rel)))); } diff --git a/src/backend/access/nbtree/nbtvalidate.c b/src/backend/access/nbtree/nbtvalidate.c index f24091c0ada..0148ea78929 100644 --- a/src/backend/access/nbtree/nbtvalidate.c +++ b/src/backend/access/nbtree/nbtvalidate.c @@ -3,7 +3,7 @@ * nbtvalidate.c * Opclass validator for btree. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/access/nbtree/nbtxlog.c b/src/backend/access/nbtree/nbtxlog.c index 0986ef07cf3..dd5315c1aad 100644 --- a/src/backend/access/nbtree/nbtxlog.c +++ b/src/backend/access/nbtree/nbtxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for btrees. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,7 +15,6 @@ #include "postgres.h" #include "access/bufmask.h" -#include "access/heapam_xlog.h" #include "access/nbtree.h" #include "access/nbtxlog.h" #include "access/transam.h" @@ -103,11 +102,13 @@ _bt_restore_meta(XLogReaderState *record, uint8 block_id) md = BTPageGetMeta(metapg); md->btm_magic = BTREE_MAGIC; - md->btm_version = BTREE_VERSION; + md->btm_version = xlrec->version; md->btm_root = xlrec->root; md->btm_level = xlrec->level; md->btm_fastroot = xlrec->fastroot; md->btm_fastlevel = xlrec->fastlevel; + /* Cannot log BTREE_MIN_VERSION index metapage without upgrade */ + Assert(md->btm_version >= BTREE_NOVAC_VERSION); md->btm_oldest_btpo_xact = xlrec->oldest_btpo_xact; md->btm_last_cleanup_num_heap_tuples = xlrec->last_cleanup_num_heap_tuples; @@ -182,7 +183,7 @@ btree_xlog_insert(bool isleaf, bool ismeta, XLogReaderState *record) if (PageAddItem(page, (Item) datapos, datalen, xlrec->offnum, false, false) == InvalidOffsetNumber) - elog(PANIC, "btree_insert_redo: failed to add item"); + elog(PANIC, "btree_xlog_insert: failed to add item"); PageSetLSN(page, lsn); MarkBufferDirty(buffer); @@ -202,7 +203,7 @@ btree_xlog_insert(bool isleaf, bool ismeta, XLogReaderState *record) } static void -btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) +btree_xlog_split(bool onleft, XLogReaderState *record) { XLogRecPtr lsn = record->EndRecPtr; xl_btree_split *xlrec = (xl_btree_split *) XLogRecGetData(record); @@ -213,8 +214,6 @@ btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) BTPageOpaque ropaque; char *datapos; Size datalen; - IndexTuple left_hikey = NULL; - Size left_hikeysz = 0; BlockNumber leftsib; BlockNumber rightsib; BlockNumber rnext; @@ -248,26 +247,9 @@ btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) _bt_restore_page(rpage, datapos, datalen); - /* Non-leaf page should always have its high key logged. */ - Assert(isleaf || lhighkey); - - /* - * When the high key isn't present is the wal record, then we assume it to - * be equal to the first key on the right page. - */ - if (!lhighkey) - { - ItemId hiItemId = PageGetItemId(rpage, P_FIRSTDATAKEY(ropaque)); - - left_hikey = (IndexTuple) PageGetItem(rpage, hiItemId); - left_hikeysz = ItemIdGetLength(hiItemId); - } - PageSetLSN(rpage, lsn); MarkBufferDirty(rbuf); - /* don't release the buffer yet; we touch right page's first item below */ - /* Now reconstruct left (original) sibling page */ if (XLogReadBufferForRedo(record, 0, &lbuf) == BLK_NEEDS_REDO) { @@ -275,16 +257,17 @@ btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) * To retain the same physical order of the tuples that they had, we * initialize a temporary empty page for the left page and add all the * items to that in item number order. This mirrors how _bt_split() - * works. It's not strictly required to retain the same physical - * order, as long as the items are in the correct item number order, - * but it helps debugging. See also _bt_restore_page(), which does - * the same for the right page. + * works. Retaining the same physical order makes WAL consistency + * checking possible. See also _bt_restore_page(), which does the + * same for the right page. */ Page lpage = (Page) BufferGetPage(lbuf); BTPageOpaque lopaque = (BTPageOpaque) PageGetSpecialPointer(lpage); OffsetNumber off; - IndexTuple newitem = NULL; - Size newitemsz = 0; + IndexTuple newitem = NULL, + left_hikey = NULL; + Size newitemsz = 0, + left_hikeysz = 0; Page newlpage; OffsetNumber leftoff; @@ -299,13 +282,10 @@ btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) } /* Extract left hikey and its size (assuming 16-bit alignment) */ - if (lhighkey) - { - left_hikey = (IndexTuple) datapos; - left_hikeysz = MAXALIGN(IndexTupleSize(left_hikey)); - datapos += left_hikeysz; - datalen -= left_hikeysz; - } + left_hikey = (IndexTuple) datapos; + left_hikeysz = MAXALIGN(IndexTupleSize(left_hikey)); + datapos += left_hikeysz; + datalen -= left_hikeysz; Assert(datalen == 0); @@ -364,7 +344,10 @@ btree_xlog_split(bool onleft, bool lhighkey, XLogReaderState *record) MarkBufferDirty(lbuf); } - /* We no longer need the buffers */ + /* + * We no longer need the buffers. They must be released together, so that + * readers cannot observe two inconsistent halves. + */ if (BufferIsValid(lbuf)) UnlockReleaseBuffer(lbuf); UnlockReleaseBuffer(rbuf); @@ -519,159 +502,6 @@ btree_xlog_vacuum(XLogReaderState *record) UnlockReleaseBuffer(buffer); } -/* - * Get the latestRemovedXid from the heap pages pointed at by the index - * tuples being deleted. This puts the work for calculating latestRemovedXid - * into the recovery path rather than the primary path. - * - * It's possible that this generates a fair amount of I/O, since an index - * block may have hundreds of tuples being deleted. Repeat accesses to the - * same heap blocks are common, though are not yet optimised. - * - * XXX optimise later with something like XLogPrefetchBuffer() - */ -static TransactionId -btree_xlog_delete_get_latestRemovedXid(XLogReaderState *record) -{ - xl_btree_delete *xlrec = (xl_btree_delete *) XLogRecGetData(record); - OffsetNumber *unused; - Buffer ibuffer, - hbuffer; - Page ipage, - hpage; - RelFileNode rnode; - BlockNumber blkno; - ItemId iitemid, - hitemid; - IndexTuple itup; - HeapTupleHeader htuphdr; - BlockNumber hblkno; - OffsetNumber hoffnum; - TransactionId latestRemovedXid = InvalidTransactionId; - int i; - - /* - * If there's nothing running on the standby we don't need to derive a - * full latestRemovedXid value, so use a fast path out of here. This - * returns InvalidTransactionId, and so will conflict with all HS - * transactions; but since we just worked out that that's zero people, - * it's OK. - * - * XXX There is a race condition here, which is that a new backend might - * start just after we look. If so, it cannot need to conflict, but this - * coding will result in throwing a conflict anyway. - */ - if (CountDBBackends(InvalidOid) == 0) - return latestRemovedXid; - - /* - * In what follows, we have to examine the previous state of the index - * page, as well as the heap page(s) it points to. This is only valid if - * WAL replay has reached a consistent database state; which means that - * the preceding check is not just an optimization, but is *necessary*. We - * won't have let in any user sessions before we reach consistency. - */ - if (!reachedConsistency) - elog(PANIC, "btree_xlog_delete_get_latestRemovedXid: cannot operate with inconsistent data"); - - /* - * Get index page. If the DB is consistent, this should not fail, nor - * should any of the heap page fetches below. If one does, we return - * InvalidTransactionId to cancel all HS transactions. That's probably - * overkill, but it's safe, and certainly better than panicking here. - */ - XLogRecGetBlockTag(record, 0, &rnode, NULL, &blkno); - ibuffer = XLogReadBufferExtended(rnode, MAIN_FORKNUM, blkno, RBM_NORMAL); - if (!BufferIsValid(ibuffer)) - return InvalidTransactionId; - LockBuffer(ibuffer, BT_READ); - ipage = (Page) BufferGetPage(ibuffer); - - /* - * Loop through the deleted index items to obtain the TransactionId from - * the heap items they point to. - */ - unused = (OffsetNumber *) ((char *) xlrec + SizeOfBtreeDelete); - - for (i = 0; i < xlrec->nitems; i++) - { - /* - * Identify the index tuple about to be deleted - */ - iitemid = PageGetItemId(ipage, unused[i]); - itup = (IndexTuple) PageGetItem(ipage, iitemid); - - /* - * Locate the heap page that the index tuple points at - */ - hblkno = ItemPointerGetBlockNumber(&(itup->t_tid)); - hbuffer = XLogReadBufferExtended(xlrec->hnode, MAIN_FORKNUM, hblkno, RBM_NORMAL); - if (!BufferIsValid(hbuffer)) - { - UnlockReleaseBuffer(ibuffer); - return InvalidTransactionId; - } - LockBuffer(hbuffer, BT_READ); - hpage = (Page) BufferGetPage(hbuffer); - - /* - * Look up the heap tuple header that the index tuple points at by - * using the heap node supplied with the xlrec. We can't use - * heap_fetch, since it uses ReadBuffer rather than XLogReadBuffer. - * Note that we are not looking at tuple data here, just headers. - */ - hoffnum = ItemPointerGetOffsetNumberNoCheck(&(itup->t_tid)); - hitemid = PageGetItemId(hpage, hoffnum); - - /* - * Follow any redirections until we find something useful. - */ - while (ItemIdIsRedirected(hitemid)) - { - hoffnum = ItemIdGetRedirect(hitemid); - hitemid = PageGetItemId(hpage, hoffnum); - CHECK_FOR_INTERRUPTS(); - } - - /* - * If the heap item has storage, then read the header and use that to - * set latestRemovedXid. - * - * Some LP_DEAD items may not be accessible, so we ignore them. - */ - if (ItemIdHasStorage(hitemid)) - { - htuphdr = (HeapTupleHeader) PageGetItem(hpage, hitemid); - - HeapTupleHeaderAdvanceLatestRemovedXid(htuphdr, &latestRemovedXid); - } - else if (ItemIdIsDead(hitemid)) - { - /* - * Conjecture: if hitemid is dead then it had xids before the xids - * marked on LP_NORMAL items. So we just ignore this item and move - * onto the next, for the purposes of calculating - * latestRemovedxids. - */ - } - else - Assert(!ItemIdIsUsed(hitemid)); - - UnlockReleaseBuffer(hbuffer); - } - - UnlockReleaseBuffer(ibuffer); - - /* - * If all heap tuples were LP_DEAD then we will be returning - * InvalidTransactionId here, which avoids conflicts. This matches - * existing logic which assumes that LP_DEAD tuples must already be older - * than the latestRemovedXid on the cleanup record that set them as - * LP_DEAD, hence must already have generated a conflict. - */ - return latestRemovedXid; -} - static void btree_xlog_delete(XLogReaderState *record) { @@ -694,12 +524,11 @@ btree_xlog_delete(XLogReaderState *record) */ if (InHotStandby) { - TransactionId latestRemovedXid = btree_xlog_delete_get_latestRemovedXid(record); RelFileNode rnode; XLogRecGetBlockTag(record, 0, &rnode, NULL, NULL); - ResolveRecoveryConflictWithSnapshot(latestRemovedXid, rnode); + ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid, rnode); } /* @@ -801,10 +630,8 @@ btree_xlog_mark_page_halfdead(uint8 info, XLogReaderState *record) */ MemSet(&trunctuple, 0, sizeof(IndexTupleData)); trunctuple.t_info = sizeof(IndexTupleData); - if (xlrec->topparent != InvalidBlockNumber) - ItemPointerSetBlockNumber(&trunctuple.t_tid, xlrec->topparent); - else - ItemPointerSetInvalid(&trunctuple.t_tid); + BTreeTupleSetTopParent(&trunctuple, xlrec->topparent); + if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY, false, false) == InvalidOffsetNumber) elog(ERROR, "could not add dummy high key to half-dead page"); @@ -911,10 +738,8 @@ btree_xlog_unlink_page(uint8 info, XLogReaderState *record) /* Add a dummy hikey item */ MemSet(&trunctuple, 0, sizeof(IndexTupleData)); trunctuple.t_info = sizeof(IndexTupleData); - if (xlrec->topparent != InvalidBlockNumber) - ItemPointerSetBlockNumber(&trunctuple.t_tid, xlrec->topparent); - else - ItemPointerSetInvalid(&trunctuple.t_tid); + BTreeTupleSetTopParent(&trunctuple, xlrec->topparent); + if (PageAddItem(page, (Item) &trunctuple, sizeof(IndexTupleData), P_HIKEY, false, false) == InvalidOffsetNumber) elog(ERROR, "could not add dummy high key to half-dead page"); @@ -1008,16 +833,10 @@ btree_redo(XLogReaderState *record) btree_xlog_insert(false, true, record); break; case XLOG_BTREE_SPLIT_L: - btree_xlog_split(true, false, record); - break; - case XLOG_BTREE_SPLIT_L_HIGHKEY: - btree_xlog_split(true, true, record); + btree_xlog_split(true, record); break; case XLOG_BTREE_SPLIT_R: - btree_xlog_split(false, false, record); - break; - case XLOG_BTREE_SPLIT_R_HIGHKEY: - btree_xlog_split(false, true, record); + btree_xlog_split(false, record); break; case XLOG_BTREE_VACUUM: btree_xlog_vacuum(record); diff --git a/src/backend/access/rmgrdesc/brindesc.c b/src/backend/access/rmgrdesc/brindesc.c index d4642342545..457c9c7c5ce 100644 --- a/src/backend/access/rmgrdesc/brindesc.c +++ b/src/backend/access/rmgrdesc/brindesc.c @@ -3,7 +3,7 @@ * brindesc.c * rmgr descriptor routines for BRIN indexes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/clogdesc.c b/src/backend/access/rmgrdesc/clogdesc.c index 4c00d4d1f8b..a908fe75077 100644 --- a/src/backend/access/rmgrdesc/clogdesc.c +++ b/src/backend/access/rmgrdesc/clogdesc.c @@ -3,7 +3,7 @@ * clogdesc.c * rmgr descriptor routines for access/transam/clog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/committsdesc.c b/src/backend/access/rmgrdesc/committsdesc.c index b6e210398de..6f23adaff8c 100644 --- a/src/backend/access/rmgrdesc/committsdesc.c +++ b/src/backend/access/rmgrdesc/committsdesc.c @@ -3,7 +3,7 @@ * committsdesc.c * rmgr descriptor routines for access/transam/commit_ts.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/dbasedesc.c b/src/backend/access/rmgrdesc/dbasedesc.c index 39e26d7ed44..c7d60ce10d6 100644 --- a/src/backend/access/rmgrdesc/dbasedesc.c +++ b/src/backend/access/rmgrdesc/dbasedesc.c @@ -3,7 +3,7 @@ * dbasedesc.c * rmgr descriptor routines for commands/dbcommands.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,15 +29,15 @@ dbase_desc(StringInfo buf, XLogReaderState *record) xl_dbase_create_rec *xlrec = (xl_dbase_create_rec *) rec; appendStringInfo(buf, "copy dir %u/%u to %u/%u", - xlrec->src_db_id, xlrec->src_tablespace_id, - xlrec->db_id, xlrec->tablespace_id); + xlrec->src_tablespace_id, xlrec->src_db_id, + xlrec->tablespace_id, xlrec->db_id); } else if (info == XLOG_DBASE_DROP) { xl_dbase_drop_rec *xlrec = (xl_dbase_drop_rec *) rec; appendStringInfo(buf, "dir %u/%u", - xlrec->db_id, xlrec->tablespace_id); + xlrec->tablespace_id, xlrec->db_id); } } diff --git a/src/backend/access/rmgrdesc/genericdesc.c b/src/backend/access/rmgrdesc/genericdesc.c index 4e9bba804de..0fe02dc85a7 100644 --- a/src/backend/access/rmgrdesc/genericdesc.c +++ b/src/backend/access/rmgrdesc/genericdesc.c @@ -4,7 +4,7 @@ * rmgr descriptor routines for access/transam/generic_xlog.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/rmgrdesc/genericdesc.c diff --git a/src/backend/access/rmgrdesc/gindesc.c b/src/backend/access/rmgrdesc/gindesc.c index 3456187e3d2..f3f4e1b2149 100644 --- a/src/backend/access/rmgrdesc/gindesc.c +++ b/src/backend/access/rmgrdesc/gindesc.c @@ -3,7 +3,7 @@ * gindesc.c * rmgr descriptor routines for access/transam/gin/ginxlog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -78,9 +78,6 @@ gin_desc(StringInfo buf, XLogReaderState *record) switch (info) { - case XLOG_GIN_CREATE_INDEX: - /* no further information */ - break; case XLOG_GIN_CREATE_PTREE: /* no further information */ break; @@ -188,9 +185,6 @@ gin_identify(uint8 info) switch (info & ~XLR_INFO_MASK) { - case XLOG_GIN_CREATE_INDEX: - id = "CREATE_INDEX"; - break; case XLOG_GIN_CREATE_PTREE: id = "CREATE_PTREE"; break; diff --git a/src/backend/access/rmgrdesc/gistdesc.c b/src/backend/access/rmgrdesc/gistdesc.c index e5e925e0c5a..eccb6fd9428 100644 --- a/src/backend/access/rmgrdesc/gistdesc.c +++ b/src/backend/access/rmgrdesc/gistdesc.c @@ -3,7 +3,7 @@ * gistdesc.c * rmgr descriptor routines for access/gist/gistxlog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,6 +23,24 @@ out_gistxlogPageUpdate(StringInfo buf, gistxlogPageUpdate *xlrec) { } +static void +out_gistxlogPageReuse(StringInfo buf, gistxlogPageReuse *xlrec) +{ + appendStringInfo(buf, "rel %u/%u/%u; blk %u; latestRemovedXid %u:%u", + xlrec->node.spcNode, xlrec->node.dbNode, + xlrec->node.relNode, xlrec->block, + EpochFromFullTransactionId(xlrec->latestRemovedFullXid), + XidFromFullTransactionId(xlrec->latestRemovedFullXid)); +} + +static void +out_gistxlogDelete(StringInfo buf, gistxlogDelete *xlrec) +{ + appendStringInfo(buf, "delete: latestRemovedXid %u, nitems: %u", + xlrec->latestRemovedXid, xlrec->ntodelete); + +} + static void out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec) { @@ -30,6 +48,15 @@ out_gistxlogPageSplit(StringInfo buf, gistxlogPageSplit *xlrec) xlrec->npage); } +static void +out_gistxlogPageDelete(StringInfo buf, gistxlogPageDelete *xlrec) +{ + appendStringInfo(buf, "deleteXid %u:%u; downlink %u", + EpochFromFullTransactionId(xlrec->deleteXid), + XidFromFullTransactionId(xlrec->deleteXid), + xlrec->downlinkOffset); +} + void gist_desc(StringInfo buf, XLogReaderState *record) { @@ -41,10 +68,17 @@ gist_desc(StringInfo buf, XLogReaderState *record) case XLOG_GIST_PAGE_UPDATE: out_gistxlogPageUpdate(buf, (gistxlogPageUpdate *) rec); break; + case XLOG_GIST_PAGE_REUSE: + out_gistxlogPageReuse(buf, (gistxlogPageReuse *) rec); + break; + case XLOG_GIST_DELETE: + out_gistxlogDelete(buf, (gistxlogDelete *) rec); + break; case XLOG_GIST_PAGE_SPLIT: out_gistxlogPageSplit(buf, (gistxlogPageSplit *) rec); break; - case XLOG_GIST_CREATE_INDEX: + case XLOG_GIST_PAGE_DELETE: + out_gistxlogPageDelete(buf, (gistxlogPageDelete *) rec); break; } } @@ -59,11 +93,17 @@ gist_identify(uint8 info) case XLOG_GIST_PAGE_UPDATE: id = "PAGE_UPDATE"; break; + case XLOG_GIST_DELETE: + id = "DELETE"; + break; + case XLOG_GIST_PAGE_REUSE: + id = "PAGE_REUSE"; + break; case XLOG_GIST_PAGE_SPLIT: id = "PAGE_SPLIT"; break; - case XLOG_GIST_CREATE_INDEX: - id = "CREATE_INDEX"; + case XLOG_GIST_PAGE_DELETE: + id = "PAGE_DELETE"; break; } diff --git a/src/backend/access/rmgrdesc/hashdesc.c b/src/backend/access/rmgrdesc/hashdesc.c index 3c53c84f1a9..a29aa96e9ca 100644 --- a/src/backend/access/rmgrdesc/hashdesc.c +++ b/src/backend/access/rmgrdesc/hashdesc.c @@ -3,7 +3,7 @@ * hashdesc.c * rmgr descriptor routines for access/hash/hash.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -113,8 +113,9 @@ hash_desc(StringInfo buf, XLogReaderState *record) { xl_hash_vacuum_one_page *xlrec = (xl_hash_vacuum_one_page *) rec; - appendStringInfo(buf, "ntuples %d", - xlrec->ntuples); + appendStringInfo(buf, "ntuples %d, latest removed xid %u", + xlrec->ntuples, + xlrec->latestRemovedXid); break; } } diff --git a/src/backend/access/rmgrdesc/heapdesc.c b/src/backend/access/rmgrdesc/heapdesc.c index 318a281d7f2..f25ebcda999 100644 --- a/src/backend/access/rmgrdesc/heapdesc.c +++ b/src/backend/access/rmgrdesc/heapdesc.c @@ -3,7 +3,7 @@ * heapdesc.c * rmgr descriptor routines for access/heap/heapam.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -42,22 +42,26 @@ heap_desc(StringInfo buf, XLogReaderState *record) { xl_heap_insert *xlrec = (xl_heap_insert *) rec; - appendStringInfo(buf, "off %u", xlrec->offnum); + appendStringInfo(buf, "off %u flags 0x%02X", xlrec->offnum, + xlrec->flags); } else if (info == XLOG_HEAP_DELETE) { xl_heap_delete *xlrec = (xl_heap_delete *) rec; - appendStringInfo(buf, "off %u ", xlrec->offnum); + appendStringInfo(buf, "off %u flags 0x%02X ", + xlrec->offnum, + xlrec->flags); out_infobits(buf, xlrec->infobits_set); } else if (info == XLOG_HEAP_UPDATE) { xl_heap_update *xlrec = (xl_heap_update *) rec; - appendStringInfo(buf, "off %u xmax %u ", + appendStringInfo(buf, "off %u xmax %u flags 0x%02X ", xlrec->old_offnum, - xlrec->old_xmax); + xlrec->old_xmax, + xlrec->flags); out_infobits(buf, xlrec->old_infobits_set); appendStringInfo(buf, "; new off %u xmax %u", xlrec->new_offnum, @@ -67,9 +71,10 @@ heap_desc(StringInfo buf, XLogReaderState *record) { xl_heap_update *xlrec = (xl_heap_update *) rec; - appendStringInfo(buf, "off %u xmax %u ", + appendStringInfo(buf, "off %u xmax %u flags 0x%02X ", xlrec->old_offnum, - xlrec->old_xmax); + xlrec->old_xmax, + xlrec->flags); out_infobits(buf, xlrec->old_infobits_set); appendStringInfo(buf, "; new off %u xmax %u", xlrec->new_offnum, @@ -81,9 +86,9 @@ heap_desc(StringInfo buf, XLogReaderState *record) int i; if (xlrec->flags & XLH_TRUNCATE_CASCADE) - appendStringInfo(buf, "cascade "); + appendStringInfoString(buf, "cascade "); if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS) - appendStringInfo(buf, "restart_seqs "); + appendStringInfoString(buf, "restart_seqs "); appendStringInfo(buf, "nrelids %u relids", xlrec->nrelids); for (i = 0; i < xlrec->nrelids; i++) appendStringInfo(buf, " %u", xlrec->relids[i]); @@ -98,7 +103,7 @@ heap_desc(StringInfo buf, XLogReaderState *record) { xl_heap_lock *xlrec = (xl_heap_lock *) rec; - appendStringInfo(buf, "off %u: xid %u: flags %u ", + appendStringInfo(buf, "off %u: xid %u: flags 0x%02X ", xlrec->offnum, xlrec->locking_xid, xlrec->flags); out_infobits(buf, xlrec->infobits_set); } @@ -139,20 +144,21 @@ heap2_desc(StringInfo buf, XLogReaderState *record) { xl_heap_visible *xlrec = (xl_heap_visible *) rec; - appendStringInfo(buf, "cutoff xid %u flags %d", + appendStringInfo(buf, "cutoff xid %u flags 0x%02X", xlrec->cutoff_xid, xlrec->flags); } else if (info == XLOG_HEAP2_MULTI_INSERT) { xl_heap_multi_insert *xlrec = (xl_heap_multi_insert *) rec; - appendStringInfo(buf, "%d tuples", xlrec->ntuples); + appendStringInfo(buf, "%d tuples flags 0x%02X", xlrec->ntuples, + xlrec->flags); } else if (info == XLOG_HEAP2_LOCK_UPDATED) { xl_heap_lock_updated *xlrec = (xl_heap_lock_updated *) rec; - appendStringInfo(buf, "off %u: xmax %u: flags %u ", + appendStringInfo(buf, "off %u: xmax %u: flags 0x%02X ", xlrec->offnum, xlrec->xmax, xlrec->flags); out_infobits(buf, xlrec->infobits_set); } diff --git a/src/backend/access/rmgrdesc/logicalmsgdesc.c b/src/backend/access/rmgrdesc/logicalmsgdesc.c index 5b26da1b863..6a720b6d769 100644 --- a/src/backend/access/rmgrdesc/logicalmsgdesc.c +++ b/src/backend/access/rmgrdesc/logicalmsgdesc.c @@ -3,7 +3,7 @@ * logicalmsgdesc.c * rmgr descriptor routines for replication/logical/message.c * - * Portions Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2015-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/rmgrdesc/mxactdesc.c b/src/backend/access/rmgrdesc/mxactdesc.c index bd13837bd45..c125d2a4c12 100644 --- a/src/backend/access/rmgrdesc/mxactdesc.c +++ b/src/backend/access/rmgrdesc/mxactdesc.c @@ -3,7 +3,7 @@ * mxactdesc.c * rmgr descriptor routines for access/transam/multixact.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/nbtdesc.c b/src/backend/access/rmgrdesc/nbtdesc.c index 0b996ea13a8..4ee6d04a68e 100644 --- a/src/backend/access/rmgrdesc/nbtdesc.c +++ b/src/backend/access/rmgrdesc/nbtdesc.c @@ -3,7 +3,7 @@ * nbtdesc.c * rmgr descriptor routines for access/nbtree/nbtxlog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,13 +35,11 @@ btree_desc(StringInfo buf, XLogReaderState *record) } case XLOG_BTREE_SPLIT_L: case XLOG_BTREE_SPLIT_R: - case XLOG_BTREE_SPLIT_L_HIGHKEY: - case XLOG_BTREE_SPLIT_R_HIGHKEY: { xl_btree_split *xlrec = (xl_btree_split *) rec; - appendStringInfo(buf, "level %u, firstright %d", - xlrec->level, xlrec->firstright); + appendStringInfo(buf, "level %u, firstright %d, newitemoff %d", + xlrec->level, xlrec->firstright, xlrec->newitemoff); break; } case XLOG_BTREE_VACUUM: @@ -56,7 +54,8 @@ btree_desc(StringInfo buf, XLogReaderState *record) { xl_btree_delete *xlrec = (xl_btree_delete *) rec; - appendStringInfo(buf, "%d items", xlrec->nitems); + appendStringInfo(buf, "%d items, latest removed xid %u", + xlrec->nitems, xlrec->latestRemovedXid); break; } case XLOG_BTREE_MARK_PAGE_HALFDEAD: @@ -96,6 +95,17 @@ btree_desc(StringInfo buf, XLogReaderState *record) xlrec->node.relNode, xlrec->latestRemovedXid); break; } + case XLOG_BTREE_META_CLEANUP: + { + xl_btree_metadata *xlrec; + + xlrec = (xl_btree_metadata *) XLogRecGetBlockData(record, 0, + NULL); + appendStringInfo(buf, "oldest_btpo_xact %u; last_cleanup_num_heap_tuples: %f", + xlrec->oldest_btpo_xact, + xlrec->last_cleanup_num_heap_tuples); + break; + } } } @@ -121,12 +131,6 @@ btree_identify(uint8 info) case XLOG_BTREE_SPLIT_R: id = "SPLIT_R"; break; - case XLOG_BTREE_SPLIT_L_HIGHKEY: - id = "SPLIT_L_HIGHKEY"; - break; - case XLOG_BTREE_SPLIT_R_HIGHKEY: - id = "SPLIT_R_HIGHKEY"; - break; case XLOG_BTREE_VACUUM: id = "VACUUM"; break; @@ -148,6 +152,9 @@ btree_identify(uint8 info) case XLOG_BTREE_REUSE_PAGE: id = "REUSE_PAGE"; break; + case XLOG_BTREE_META_CLEANUP: + id = "META_CLEANUP"; + break; } return id; diff --git a/src/backend/access/rmgrdesc/relmapdesc.c b/src/backend/access/rmgrdesc/relmapdesc.c index 5dbec9d94cb..d9e6c41a012 100644 --- a/src/backend/access/rmgrdesc/relmapdesc.c +++ b/src/backend/access/rmgrdesc/relmapdesc.c @@ -3,7 +3,7 @@ * relmapdesc.c * rmgr descriptor routines for utils/cache/relmapper.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/replorigindesc.c b/src/backend/access/rmgrdesc/replorigindesc.c index 2719bf4a280..95c8d9f642e 100644 --- a/src/backend/access/rmgrdesc/replorigindesc.c +++ b/src/backend/access/rmgrdesc/replorigindesc.c @@ -3,7 +3,7 @@ * replorigindesc.c * rmgr descriptor routines for replication/logical/origin.c * - * Portions Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2015-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/access/rmgrdesc/seqdesc.c b/src/backend/access/rmgrdesc/seqdesc.c index 5c11eb00f0c..8bb4020a783 100644 --- a/src/backend/access/rmgrdesc/seqdesc.c +++ b/src/backend/access/rmgrdesc/seqdesc.c @@ -3,7 +3,7 @@ * seqdesc.c * rmgr descriptor routines for commands/sequence.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/smgrdesc.c b/src/backend/access/rmgrdesc/smgrdesc.c index df1ad38b5a1..bcda162dfc7 100644 --- a/src/backend/access/rmgrdesc/smgrdesc.c +++ b/src/backend/access/rmgrdesc/smgrdesc.c @@ -3,7 +3,7 @@ * smgrdesc.c * rmgr descriptor routines for catalog/storage.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/spgdesc.c b/src/backend/access/rmgrdesc/spgdesc.c index 92b1392974e..40c1c8b3f98 100644 --- a/src/backend/access/rmgrdesc/spgdesc.c +++ b/src/backend/access/rmgrdesc/spgdesc.c @@ -3,7 +3,7 @@ * spgdesc.c * rmgr descriptor routines for access/spgist/spgxlog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,8 +24,6 @@ spg_desc(StringInfo buf, XLogReaderState *record) switch (info) { - case XLOG_SPGIST_CREATE_INDEX: - break; case XLOG_SPGIST_ADD_LEAF: { spgxlogAddLeaf *xlrec = (spgxlogAddLeaf *) rec; @@ -88,9 +86,6 @@ spg_identify(uint8 info) switch (info & ~XLR_INFO_MASK) { - case XLOG_SPGIST_CREATE_INDEX: - id = "CREATE_INDEX"; - break; case XLOG_SPGIST_ADD_LEAF: id = "ADD_LEAF"; break; diff --git a/src/backend/access/rmgrdesc/standbydesc.c b/src/backend/access/rmgrdesc/standbydesc.c index 76825a8d9c1..c295358f364 100644 --- a/src/backend/access/rmgrdesc/standbydesc.c +++ b/src/backend/access/rmgrdesc/standbydesc.c @@ -3,7 +3,7 @@ * standbydesc.c * rmgr descriptor routines for storage/ipc/standby.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/tblspcdesc.c b/src/backend/access/rmgrdesc/tblspcdesc.c index d97762687bf..ccedd013b73 100644 --- a/src/backend/access/rmgrdesc/tblspcdesc.c +++ b/src/backend/access/rmgrdesc/tblspcdesc.c @@ -3,7 +3,7 @@ * tblspcdesc.c * rmgr descriptor routines for commands/tablespace.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/rmgrdesc/xactdesc.c b/src/backend/access/rmgrdesc/xactdesc.c index 9b40f447ff1..a61f38dd19b 100644 --- a/src/backend/access/rmgrdesc/xactdesc.c +++ b/src/backend/access/rmgrdesc/xactdesc.c @@ -3,7 +3,7 @@ * xactdesc.c * rmgr descriptor routines for access/transam/xact.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -104,18 +104,18 @@ ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *pars if (parsed->xinfo & XACT_XINFO_HAS_GID) { - int gidlen; strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid)); - gidlen = strlen(data) + 1; - data += MAXALIGN(gidlen); + data += strlen(data) + 1; } } + /* Note: no alignment is guaranteed after this point */ + if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) { xl_xact_origin xl_origin; - /* we're only guaranteed 4 byte alignment, so copy onto stack */ + /* no alignment is guaranteed, so copy onto stack */ memcpy(&xl_origin, data, sizeof(xl_origin)); parsed->origin_lsn = xl_origin.origin_lsn; @@ -188,18 +188,18 @@ ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed) if (parsed->xinfo & XACT_XINFO_HAS_GID) { - int gidlen; strlcpy(parsed->twophase_gid, data, sizeof(parsed->twophase_gid)); - gidlen = strlen(data) + 1; - data += MAXALIGN(gidlen); + data += strlen(data) + 1; } } + /* Note: no alignment is guaranteed after this point */ + if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) { xl_xact_origin xl_origin; - /* we're only guaranteed 4 byte alignment, so copy onto stack */ + /* no alignment is guaranteed, so copy onto stack */ memcpy(&xl_origin, data, sizeof(xl_origin)); parsed->origin_lsn = xl_origin.origin_lsn; diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c index 00741c7b09e..33060f30429 100644 --- a/src/backend/access/rmgrdesc/xlogdesc.c +++ b/src/backend/access/rmgrdesc/xlogdesc.c @@ -3,7 +3,7 @@ * xlogdesc.c * rmgr descriptor routines for access/transam/xlog.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,6 +14,7 @@ */ #include "postgres.h" +#include "access/transam.h" #include "access/xlog.h" #include "access/xlog_internal.h" #include "catalog/pg_control.h" @@ -52,7 +53,8 @@ xlog_desc(StringInfo buf, XLogReaderState *record) checkpoint->ThisTimeLineID, checkpoint->PrevTimeLineID, checkpoint->fullPageWrites ? "true" : "false", - checkpoint->nextXidEpoch, checkpoint->nextXid, + EpochFromFullTransactionId(checkpoint->nextFullXid), + XidFromFullTransactionId(checkpoint->nextFullXid), checkpoint->nextOid, checkpoint->nextMulti, checkpoint->nextMultiOffset, @@ -110,11 +112,12 @@ xlog_desc(StringInfo buf, XLogReaderState *record) } appendStringInfo(buf, "max_connections=%d max_worker_processes=%d " - "max_prepared_xacts=%d max_locks_per_xact=%d " - "wal_level=%s wal_log_hints=%s " - "track_commit_timestamp=%s", + "max_wal_senders=%d max_prepared_xacts=%d " + "max_locks_per_xact=%d wal_level=%s " + "wal_log_hints=%s track_commit_timestamp=%s", xlrec.MaxConnections, xlrec.max_worker_processes, + xlrec.max_wal_senders, xlrec.max_prepared_xacts, xlrec.max_locks_per_xact, wal_level_str, diff --git a/src/backend/access/spgist/Makefile b/src/backend/access/spgist/Makefile index 14948a531ee..5be3df59926 100644 --- a/src/backend/access/spgist/Makefile +++ b/src/backend/access/spgist/Makefile @@ -14,6 +14,7 @@ include $(top_builddir)/src/Makefile.global OBJS = spgutils.o spginsert.o spgscan.o spgvacuum.o spgvalidate.o \ spgdoinsert.o spgxlog.o \ - spgtextproc.o spgquadtreeproc.o spgkdtreeproc.o + spgtextproc.o spgquadtreeproc.o spgkdtreeproc.o \ + spgproc.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/spgist/README b/src/backend/access/spgist/README index 09ab21af264..b55b0738320 100644 --- a/src/backend/access/spgist/README +++ b/src/backend/access/spgist/README @@ -41,7 +41,11 @@ contain exactly one inner tuple. When the search traversal algorithm reaches an inner tuple, it chooses a set of nodes to continue tree traverse in depth. If it reaches a leaf page it -scans a list of leaf tuples to find the ones that match the query. +scans a list of leaf tuples to find the ones that match the query. SP-GiST +also supports ordered (nearest-neighbor) searches - that is during scan pending +nodes are put into priority queue, so traversal is performed by the +closest-first model. + The insertion algorithm descends the tree similarly, except it must choose just one node to descend to from each inner tuple. Insertion might also have diff --git a/src/backend/access/spgist/spgdoinsert.c b/src/backend/access/spgist/spgdoinsert.c index 7bf26f8baeb..c34c44cd8b5 100644 --- a/src/backend/access/spgist/spgdoinsert.c +++ b/src/backend/access/spgist/spgdoinsert.c @@ -4,7 +4,7 @@ * implementation of insert algorithm * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -289,7 +289,7 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple, MarkBufferDirty(current->buffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; int flags; @@ -516,7 +516,7 @@ moveLeafs(Relation index, SpGistState *state, MarkBufferDirty(current->buffer); MarkBufferDirty(nbuf); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; @@ -1334,7 +1334,7 @@ doPickSplit(Relation index, SpGistState *state, saveCurrent.buffer = InvalidBuffer; } - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; int flags; @@ -1531,7 +1531,7 @@ spgAddNodeAction(Relation index, SpGistState *state, MarkBufferDirty(current->buffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; @@ -1644,7 +1644,7 @@ spgAddNodeAction(Relation index, SpGistState *state, MarkBufferDirty(saveCurrent.buffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; int flags; @@ -1840,7 +1840,7 @@ spgSplitNodeAction(Relation index, SpGistState *state, MarkBufferDirty(current->buffer); - if (RelationNeedsWAL(index)) + if (RelationNeedsWAL(index) && !state->isBuild) { XLogRecPtr recptr; @@ -1908,11 +1908,12 @@ spgdoinsert(Relation index, SpGistState *state, /* * Prepare the leaf datum to insert. * - * If an optional "compress" method is provided, then call it to form - * the leaf datum from the input datum. Otherwise store the input datum as - * is. Since we don't use index_form_tuple in this AM, we have to make sure - * value to be inserted is not toasted; FormIndexDatum doesn't guarantee - * that. But we assume the "compress" method to return an untoasted value. + * If an optional "compress" method is provided, then call it to form the + * leaf datum from the input datum. Otherwise store the input datum as + * is. Since we don't use index_form_tuple in this AM, we have to make + * sure value to be inserted is not toasted; FormIndexDatum doesn't + * guarantee that. But we assume the "compress" method to return an + * untoasted value. */ if (!isnull) { diff --git a/src/backend/access/spgist/spginsert.c b/src/backend/access/spgist/spginsert.c index 7dd0d61fbbc..b40bd440cf0 100644 --- a/src/backend/access/spgist/spginsert.c +++ b/src/backend/access/spgist/spginsert.c @@ -5,7 +5,7 @@ * * All the actual insertion logic is in spgdoinsert.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,6 +19,7 @@ #include "access/genam.h" #include "access/spgist_private.h" #include "access/spgxlog.h" +#include "access/tableam.h" #include "access/xlog.h" #include "access/xloginsert.h" #include "catalog/index.h" @@ -37,7 +38,7 @@ typedef struct } SpGistBuildState; -/* Callback to process one heap tuple during IndexBuildHeapScan */ +/* Callback to process one heap tuple during table_index_build_scan */ static void spgistBuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state) @@ -104,26 +105,6 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo) SpGistInitBuffer(nullbuffer, SPGIST_LEAF | SPGIST_NULLS); MarkBufferDirty(nullbuffer); - if (RelationNeedsWAL(index)) - { - XLogRecPtr recptr; - - XLogBeginInsert(); - - /* - * Replay will re-initialize the pages, so don't take full pages - * images. No other data to log. - */ - XLogRegisterBuffer(0, metabuffer, REGBUF_WILL_INIT | REGBUF_STANDARD); - XLogRegisterBuffer(1, rootbuffer, REGBUF_WILL_INIT | REGBUF_STANDARD); - XLogRegisterBuffer(2, nullbuffer, REGBUF_WILL_INIT | REGBUF_STANDARD); - - recptr = XLogInsert(RM_SPGIST_ID, XLOG_SPGIST_CREATE_INDEX); - - PageSetLSN(BufferGetPage(metabuffer), recptr); - PageSetLSN(BufferGetPage(rootbuffer), recptr); - PageSetLSN(BufferGetPage(nullbuffer), recptr); - } END_CRIT_SECTION(); @@ -142,14 +123,25 @@ spgbuild(Relation heap, Relation index, IndexInfo *indexInfo) "SP-GiST build temporary context", ALLOCSET_DEFAULT_SIZES); - reltuples = IndexBuildHeapScan(heap, index, indexInfo, true, - spgistBuildCallback, (void *) &buildstate, - NULL); + reltuples = table_index_build_scan(heap, index, indexInfo, true, true, + spgistBuildCallback, (void *) &buildstate, + NULL); MemoryContextDelete(buildstate.tmpCtx); SpGistUpdateMetaPage(index); + /* + * We didn't write WAL records as we built the index, so if WAL-logging is + * required, write all pages to the WAL now. + */ + if (RelationNeedsWAL(index)) + { + log_newpage_range(index, MAIN_FORKNUM, + 0, RelationGetNumberOfBlocks(index), + true); + } + result = (IndexBuildResult *) palloc0(sizeof(IndexBuildResult)); result->heap_tuples = reltuples; result->index_tuples = buildstate.indtuples; diff --git a/src/backend/access/spgist/spgkdtreeproc.c b/src/backend/access/spgist/spgkdtreeproc.c index 556f3a4e076..9d479fec4d6 100644 --- a/src/backend/access/spgist/spgkdtreeproc.c +++ b/src/backend/access/spgist/spgkdtreeproc.c @@ -4,7 +4,7 @@ * implementation of k-d tree over points for SP-GiST * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,9 +16,11 @@ #include "postgres.h" #include "access/spgist.h" +#include "access/spgist_private.h" #include "access/stratnum.h" #include "catalog/pg_type.h" #include "utils/builtins.h" +#include "utils/float.h" #include "utils/geo_decls.h" @@ -162,6 +164,7 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS) double coord; int which; int i; + BOX bboxes[2]; Assert(in->hasPrefix); coord = DatumGetFloat8(in->prefixDatum); @@ -248,12 +251,85 @@ spg_kd_inner_consistent(PG_FUNCTION_ARGS) } /* We must descend into the children identified by which */ - out->nodeNumbers = (int *) palloc(sizeof(int) * 2); out->nNodes = 0; + + /* Fast-path for no matching children */ + if (!which) + PG_RETURN_VOID(); + + out->nodeNumbers = (int *) palloc(sizeof(int) * 2); + + /* + * When ordering scan keys are specified, we've to calculate distance for + * them. In order to do that, we need calculate bounding boxes for both + * children nodes. Calculation of those bounding boxes on non-zero level + * require knowledge of bounding box of upper node. So, we save bounding + * boxes to traversalValues. + */ + if (in->norderbys > 0) + { + BOX infArea; + BOX *area; + + out->distances = (double **) palloc(sizeof(double *) * in->nNodes); + out->traversalValues = (void **) palloc(sizeof(void *) * in->nNodes); + + if (in->level == 0) + { + float8 inf = get_float8_infinity(); + + infArea.high.x = inf; + infArea.high.y = inf; + infArea.low.x = -inf; + infArea.low.y = -inf; + area = &infArea; + } + else + { + area = (BOX *) in->traversalValue; + Assert(area); + } + + bboxes[0].low = area->low; + bboxes[1].high = area->high; + + if (in->level % 2) + { + /* split box by x */ + bboxes[0].high.x = bboxes[1].low.x = coord; + bboxes[0].high.y = area->high.y; + bboxes[1].low.y = area->low.y; + } + else + { + /* split box by y */ + bboxes[0].high.y = bboxes[1].low.y = coord; + bboxes[0].high.x = area->high.x; + bboxes[1].low.x = area->low.x; + } + } + for (i = 1; i <= 2; i++) { if (which & (1 << i)) - out->nodeNumbers[out->nNodes++] = i - 1; + { + out->nodeNumbers[out->nNodes] = i - 1; + + if (in->norderbys > 0) + { + MemoryContext oldCtx = MemoryContextSwitchTo(in->traversalMemoryContext); + BOX *box = box_copy(&bboxes[i - 1]); + + MemoryContextSwitchTo(oldCtx); + + out->traversalValues[out->nNodes] = box; + + out->distances[out->nNodes] = spg_key_orderbys_distances(BoxPGetDatum(box), false, + in->orderbys, in->norderbys); + } + + out->nNodes++; + } } /* Set up level increments, too */ diff --git a/src/backend/access/spgist/spgproc.c b/src/backend/access/spgist/spgproc.c new file mode 100644 index 00000000000..688638a7e33 --- /dev/null +++ b/src/backend/access/spgist/spgproc.c @@ -0,0 +1,88 @@ +/*------------------------------------------------------------------------- + * + * spgproc.c + * Common supporting procedures for SP-GiST opclasses. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/access/spgist/spgproc.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include + +#include "access/spgist_private.h" +#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/geo_decls.h" + +#define point_point_distance(p1,p2) \ + DatumGetFloat8(DirectFunctionCall2(point_distance, \ + PointPGetDatum(p1), PointPGetDatum(p2))) + +/* Point-box distance in the assumption that box is aligned by axis */ +static double +point_box_distance(Point *point, BOX *box) +{ + double dx, + dy; + + if (isnan(point->x) || isnan(box->low.x) || + isnan(point->y) || isnan(box->low.y)) + return get_float8_nan(); + + if (point->x < box->low.x) + dx = box->low.x - point->x; + else if (point->x > box->high.x) + dx = point->x - box->high.x; + else + dx = 0.0; + + if (point->y < box->low.y) + dy = box->low.y - point->y; + else if (point->y > box->high.y) + dy = point->y - box->high.y; + else + dy = 0.0; + + return HYPOT(dx, dy); +} + +/* + * Returns distances from given key to array of ordering scan keys. Leaf key + * is expected to be point, non-leaf key is expected to be box. Scan key + * arguments are expected to be points. + */ +double * +spg_key_orderbys_distances(Datum key, bool isLeaf, + ScanKey orderbys, int norderbys) +{ + int sk_num; + double *distances = (double *) palloc(norderbys * sizeof(double)), + *distance = distances; + + for (sk_num = 0; sk_num < norderbys; ++sk_num, ++orderbys, ++distance) + { + Point *point = DatumGetPointP(orderbys->sk_argument); + + *distance = isLeaf ? point_point_distance(point, DatumGetPointP(key)) + : point_box_distance(point, DatumGetBoxP(key)); + } + + return distances; +} + +BOX * +box_copy(BOX *orig) +{ + BOX *result = palloc(sizeof(BOX)); + + *result = *orig; + return result; +} diff --git a/src/backend/access/spgist/spgquadtreeproc.c b/src/backend/access/spgist/spgquadtreeproc.c index 8700ff35731..e50108e1cae 100644 --- a/src/backend/access/spgist/spgquadtreeproc.c +++ b/src/backend/access/spgist/spgquadtreeproc.c @@ -4,7 +4,7 @@ * implementation of quad tree over points for SP-GiST * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,8 +17,10 @@ #include "access/spgist.h" #include "access/stratnum.h" +#include "access/spgist_private.h" #include "catalog/pg_type.h" #include "utils/builtins.h" +#include "utils/float.h" #include "utils/geo_decls.h" @@ -77,6 +79,38 @@ getQuadrant(Point *centroid, Point *tst) return 0; } +/* Returns bounding box of a given quadrant inside given bounding box */ +static BOX * +getQuadrantArea(BOX *bbox, Point *centroid, int quadrant) +{ + BOX *result = (BOX *) palloc(sizeof(BOX)); + + switch (quadrant) + { + case 1: + result->high = bbox->high; + result->low = *centroid; + break; + case 2: + result->high.x = bbox->high.x; + result->high.y = centroid->y; + result->low.x = centroid->x; + result->low.y = bbox->low.y; + break; + case 3: + result->high = *centroid; + result->low = bbox->low; + break; + case 4: + result->high.x = centroid->x; + result->high.y = bbox->high.y; + result->low.x = bbox->low.x; + result->low.y = centroid->y; + break; + } + + return result; +} Datum spg_quad_choose(PG_FUNCTION_ARGS) @@ -196,19 +230,66 @@ spg_quad_inner_consistent(PG_FUNCTION_ARGS) spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0); spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1); Point *centroid; + BOX infbbox; + BOX *bbox = NULL; int which; int i; Assert(in->hasPrefix); centroid = DatumGetPointP(in->prefixDatum); + /* + * When ordering scan keys are specified, we've to calculate distance for + * them. In order to do that, we need calculate bounding boxes for all + * children nodes. Calculation of those bounding boxes on non-zero level + * require knowledge of bounding box of upper node. So, we save bounding + * boxes to traversalValues. + */ + if (in->norderbys > 0) + { + out->distances = (double **) palloc(sizeof(double *) * in->nNodes); + out->traversalValues = (void **) palloc(sizeof(void *) * in->nNodes); + + if (in->level == 0) + { + double inf = get_float8_infinity(); + + infbbox.high.x = inf; + infbbox.high.y = inf; + infbbox.low.x = -inf; + infbbox.low.y = -inf; + bbox = &infbbox; + } + else + { + bbox = in->traversalValue; + Assert(bbox); + } + } + if (in->allTheSame) { /* Report that all nodes should be visited */ out->nNodes = in->nNodes; out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); for (i = 0; i < in->nNodes; i++) + { out->nodeNumbers[i] = i; + + if (in->norderbys > 0) + { + MemoryContext oldCtx = MemoryContextSwitchTo(in->traversalMemoryContext); + + /* Use parent quadrant box as traversalValue */ + BOX *quadrant = box_copy(bbox); + + MemoryContextSwitchTo(oldCtx); + + out->traversalValues[i] = quadrant; + out->distances[i] = spg_key_orderbys_distances(BoxPGetDatum(quadrant), false, + in->orderbys, in->norderbys); + } + } PG_RETURN_VOID(); } @@ -286,13 +367,35 @@ spg_quad_inner_consistent(PG_FUNCTION_ARGS) break; /* no need to consider remaining conditions */ } + out->levelAdds = palloc(sizeof(int) * 4); + for (i = 0; i < 4; ++i) + out->levelAdds[i] = 1; + /* We must descend into the quadrant(s) identified by which */ out->nodeNumbers = (int *) palloc(sizeof(int) * 4); out->nNodes = 0; + for (i = 1; i <= 4; i++) { if (which & (1 << i)) - out->nodeNumbers[out->nNodes++] = i - 1; + { + out->nodeNumbers[out->nNodes] = i - 1; + + if (in->norderbys > 0) + { + MemoryContext oldCtx = MemoryContextSwitchTo(in->traversalMemoryContext); + BOX *quadrant = getQuadrantArea(bbox, centroid, i); + + MemoryContextSwitchTo(oldCtx); + + out->traversalValues[out->nNodes] = quadrant; + + out->distances[out->nNodes] = spg_key_orderbys_distances(BoxPGetDatum(quadrant), false, + in->orderbys, in->norderbys); + } + + out->nNodes++; + } } PG_RETURN_VOID(); @@ -356,5 +459,10 @@ spg_quad_leaf_consistent(PG_FUNCTION_ARGS) break; } + if (res && in->norderbys > 0) + /* ok, it passes -> let's compute the distances */ + out->distances = spg_key_orderbys_distances(in->leafDatum, true, + in->orderbys, in->norderbys); + PG_RETURN_BOOL(res); } diff --git a/src/backend/access/spgist/spgscan.c b/src/backend/access/spgist/spgscan.c index c7280808122..6e940fd3def 100644 --- a/src/backend/access/spgist/spgscan.c +++ b/src/backend/access/spgist/spgscan.c @@ -4,7 +4,7 @@ * routines for scanning SP-GiST indexes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,79 +15,162 @@ #include "postgres.h" +#include "access/genam.h" #include "access/relscan.h" #include "access/spgist_private.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "utils/datum.h" +#include "utils/float.h" +#include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" - typedef void (*storeRes_func) (SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isnull, bool recheck); + Datum leafValue, bool isNull, bool recheck, + bool recheckDistances, double *distances); -typedef struct ScanStackEntry +/* + * Pairing heap comparison function for the SpGistSearchItem queue. + * KNN-searches currently only support NULLS LAST. So, preserve this logic + * here. + */ +static int +pairingheap_SpGistSearchItem_cmp(const pairingheap_node *a, + const pairingheap_node *b, void *arg) { - Datum reconstructedValue; /* value reconstructed from parent */ - void *traversalValue; /* opclass-specific traverse value */ - int level; /* level of items on this page */ - ItemPointerData ptr; /* block and offset to scan from */ -} ScanStackEntry; + const SpGistSearchItem *sa = (const SpGistSearchItem *) a; + const SpGistSearchItem *sb = (const SpGistSearchItem *) b; + SpGistScanOpaque so = (SpGistScanOpaque) arg; + int i; + + if (sa->isNull) + { + if (!sb->isNull) + return -1; + } + else if (sb->isNull) + { + return 1; + } + else + { + /* Order according to distance comparison */ + for (i = 0; i < so->numberOfNonNullOrderBys; i++) + { + if (isnan(sa->distances[i]) && isnan(sb->distances[i])) + continue; /* NaN == NaN */ + if (isnan(sa->distances[i])) + return -1; /* NaN > number */ + if (isnan(sb->distances[i])) + return 1; /* number < NaN */ + if (sa->distances[i] != sb->distances[i]) + return (sa->distances[i] < sb->distances[i]) ? 1 : -1; + } + } + + /* Leaf items go before inner pages, to ensure a depth-first search */ + if (sa->isLeaf && !sb->isLeaf) + return 1; + if (!sa->isLeaf && sb->isLeaf) + return -1; + return 0; +} -/* Free a ScanStackEntry */ static void -freeScanStackEntry(SpGistScanOpaque so, ScanStackEntry *stackEntry) +spgFreeSearchItem(SpGistScanOpaque so, SpGistSearchItem *item) { if (!so->state.attLeafType.attbyval && - DatumGetPointer(stackEntry->reconstructedValue) != NULL) - pfree(DatumGetPointer(stackEntry->reconstructedValue)); - if (stackEntry->traversalValue) - pfree(stackEntry->traversalValue); + DatumGetPointer(item->value) != NULL) + pfree(DatumGetPointer(item->value)); + + if (item->traversalValue) + pfree(item->traversalValue); - pfree(stackEntry); + pfree(item); } -/* Free the entire stack */ +/* + * Add SpGistSearchItem to queue + * + * Called in queue context + */ static void -freeScanStack(SpGistScanOpaque so) +spgAddSearchItemToQueue(SpGistScanOpaque so, SpGistSearchItem *item) { - ListCell *lc; + pairingheap_add(so->scanQueue, &item->phNode); +} - foreach(lc, so->scanStack) - { - freeScanStackEntry(so, (ScanStackEntry *) lfirst(lc)); - } - list_free(so->scanStack); - so->scanStack = NIL; +static SpGistSearchItem * +spgAllocSearchItem(SpGistScanOpaque so, bool isnull, double *distances) +{ + /* allocate distance array only for non-NULL items */ + SpGistSearchItem *item = + palloc(SizeOfSpGistSearchItem(isnull ? 0 : so->numberOfNonNullOrderBys)); + + item->isNull = isnull; + + if (!isnull && so->numberOfNonNullOrderBys > 0) + memcpy(item->distances, distances, + sizeof(item->distances[0]) * so->numberOfNonNullOrderBys); + + return item; +} + +static void +spgAddStartItem(SpGistScanOpaque so, bool isnull) +{ + SpGistSearchItem *startEntry = + spgAllocSearchItem(so, isnull, so->zeroDistances); + + ItemPointerSet(&startEntry->heapPtr, + isnull ? SPGIST_NULL_BLKNO : SPGIST_ROOT_BLKNO, + FirstOffsetNumber); + startEntry->isLeaf = false; + startEntry->level = 0; + startEntry->value = (Datum) 0; + startEntry->traversalValue = NULL; + startEntry->recheck = false; + startEntry->recheckDistances = false; + + spgAddSearchItemToQueue(so, startEntry); } /* - * Initialize scanStack to search the root page, resetting + * Initialize queue to search the root page, resetting * any previously active scan */ static void resetSpGistScanOpaque(SpGistScanOpaque so) { - ScanStackEntry *startEntry; + MemoryContext oldCtx; + + MemoryContextReset(so->traversalCxt); - freeScanStack(so); + oldCtx = MemoryContextSwitchTo(so->traversalCxt); + + /* initialize queue only for distance-ordered scans */ + so->scanQueue = pairingheap_allocate(pairingheap_SpGistSearchItem_cmp, so); if (so->searchNulls) - { - /* Stack a work item to scan the null index entries */ - startEntry = (ScanStackEntry *) palloc0(sizeof(ScanStackEntry)); - ItemPointerSet(&startEntry->ptr, SPGIST_NULL_BLKNO, FirstOffsetNumber); - so->scanStack = lappend(so->scanStack, startEntry); - } + /* Add a work item to scan the null index entries */ + spgAddStartItem(so, true); if (so->searchNonNulls) + /* Add a work item to scan the non-null index entries */ + spgAddStartItem(so, false); + + MemoryContextSwitchTo(oldCtx); + + if (so->numberOfOrderBys > 0) { - /* Stack a work item to scan the non-null index entries */ - startEntry = (ScanStackEntry *) palloc0(sizeof(ScanStackEntry)); - ItemPointerSet(&startEntry->ptr, SPGIST_ROOT_BLKNO, FirstOffsetNumber); - so->scanStack = lappend(so->scanStack, startEntry); + /* Must pfree distances to avoid memory leak */ + int i; + + for (i = 0; i < so->nPtrs; i++) + if (so->distances[i]) + pfree(so->distances[i]); } if (so->want_itup) @@ -122,6 +205,37 @@ spgPrepareScanKeys(IndexScanDesc scan) int nkeys; int i; + so->numberOfOrderBys = scan->numberOfOrderBys; + so->orderByData = scan->orderByData; + + if (so->numberOfOrderBys <= 0) + so->numberOfNonNullOrderBys = 0; + else + { + int j = 0; + + /* + * Remove all NULL keys, but remember their offsets in the original + * array. + */ + for (i = 0; i < scan->numberOfOrderBys; i++) + { + ScanKey skey = &so->orderByData[i]; + + if (skey->sk_flags & SK_ISNULL) + so->nonNullOrderByOffsets[i] = -1; + else + { + if (i != j) + so->orderByData[j] = *skey; + + so->nonNullOrderByOffsets[i] = j++; + } + } + + so->numberOfNonNullOrderBys = j; + } + if (scan->numberOfKeys <= 0) { /* If no quals, whole-index scan is required */ @@ -182,8 +296,9 @@ spgbeginscan(Relation rel, int keysz, int orderbysz) { IndexScanDesc scan; SpGistScanOpaque so; + int i; - scan = RelationGetIndexScan(rel, keysz, 0); + scan = RelationGetIndexScan(rel, keysz, orderbysz); so = (SpGistScanOpaque) palloc0(sizeof(SpGistScanOpaqueData)); if (keysz > 0) @@ -191,6 +306,7 @@ spgbeginscan(Relation rel, int keysz, int orderbysz) else so->keyData = NULL; initSpGistState(&so->state, scan->indexRelation); + so->tempCxt = AllocSetContextCreate(CurrentMemoryContext, "SP-GiST search temporary context", ALLOCSET_DEFAULT_SIZES); @@ -201,6 +317,45 @@ spgbeginscan(Relation rel, int keysz, int orderbysz) /* Set up indexTupDesc and xs_hitupdesc in case it's an index-only scan */ so->indexTupDesc = scan->xs_hitupdesc = RelationGetDescr(rel); + /* Allocate various arrays needed for order-by scans */ + if (scan->numberOfOrderBys > 0) + { + /* This will be filled in spgrescan, but allocate the space here */ + so->orderByTypes = (Oid *) + palloc(sizeof(Oid) * scan->numberOfOrderBys); + so->nonNullOrderByOffsets = (int *) + palloc(sizeof(int) * scan->numberOfOrderBys); + + /* These arrays have constant contents, so we can fill them now */ + so->zeroDistances = (double *) + palloc(sizeof(double) * scan->numberOfOrderBys); + so->infDistances = (double *) + palloc(sizeof(double) * scan->numberOfOrderBys); + + for (i = 0; i < scan->numberOfOrderBys; i++) + { + so->zeroDistances[i] = 0.0; + so->infDistances[i] = get_float8_infinity(); + } + + scan->xs_orderbyvals = (Datum *) + palloc0(sizeof(Datum) * scan->numberOfOrderBys); + scan->xs_orderbynulls = (bool *) + palloc(sizeof(bool) * scan->numberOfOrderBys); + memset(scan->xs_orderbynulls, true, + sizeof(bool) * scan->numberOfOrderBys); + } + + fmgr_info_copy(&so->innerConsistentFn, + index_getprocinfo(rel, 1, SPGIST_INNER_CONSISTENT_PROC), + CurrentMemoryContext); + + fmgr_info_copy(&so->leafConsistentFn, + index_getprocinfo(rel, 1, SPGIST_LEAF_CONSISTENT_PROC), + CurrentMemoryContext); + + so->indexCollation = rel->rd_indcollation[0]; + scan->opaque = so; return scan; @@ -212,20 +367,43 @@ spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, { SpGistScanOpaque so = (SpGistScanOpaque) scan->opaque; - /* clear traversal context before proceeding to the next scan */ - MemoryContextReset(so->traversalCxt); - /* copy scankeys into local storage */ if (scankey && scan->numberOfKeys > 0) - { memmove(scan->keyData, scankey, scan->numberOfKeys * sizeof(ScanKeyData)); + + /* initialize order-by data if needed */ + if (orderbys && scan->numberOfOrderBys > 0) + { + int i; + + memmove(scan->orderByData, orderbys, + scan->numberOfOrderBys * sizeof(ScanKeyData)); + + for (i = 0; i < scan->numberOfOrderBys; i++) + { + ScanKey skey = &scan->orderByData[i]; + + /* + * Look up the datatype returned by the original ordering + * operator. SP-GiST always uses a float8 for the distance + * function, but the ordering operator could be anything else. + * + * XXX: The distance function is only allowed to be lossy if the + * ordering operator's result type is float4 or float8. Otherwise + * we don't know how to return the distance to the executor. But + * we cannot check that here, as we won't know if the distance + * function is lossy until it returns *recheck = true for the + * first time. + */ + so->orderByTypes[i] = get_func_rettype(skey->sk_func.fn_oid); + } } /* preprocess scankeys, set up the representation in *so */ spgPrepareScanKeys(scan); - /* set up starting stack entries */ + /* set up starting queue entries */ resetSpGistScanOpaque(so); } @@ -236,65 +414,344 @@ spgendscan(IndexScanDesc scan) MemoryContextDelete(so->tempCxt); MemoryContextDelete(so->traversalCxt); + + if (so->keyData) + pfree(so->keyData); + + if (so->state.deadTupleStorage) + pfree(so->state.deadTupleStorage); + + if (scan->numberOfOrderBys > 0) + { + pfree(so->orderByTypes); + pfree(so->nonNullOrderByOffsets); + pfree(so->zeroDistances); + pfree(so->infDistances); + pfree(scan->xs_orderbyvals); + pfree(scan->xs_orderbynulls); + } + + pfree(so); +} + +/* + * Leaf SpGistSearchItem constructor, called in queue context + */ +static SpGistSearchItem * +spgNewHeapItem(SpGistScanOpaque so, int level, ItemPointer heapPtr, + Datum leafValue, bool recheck, bool recheckDistances, + bool isnull, double *distances) +{ + SpGistSearchItem *item = spgAllocSearchItem(so, isnull, distances); + + item->level = level; + item->heapPtr = *heapPtr; + /* copy value to queue cxt out of tmp cxt */ + item->value = isnull ? (Datum) 0 : + datumCopy(leafValue, so->state.attLeafType.attbyval, + so->state.attLeafType.attlen); + item->traversalValue = NULL; + item->isLeaf = true; + item->recheck = recheck; + item->recheckDistances = recheckDistances; + + return item; } /* * Test whether a leaf tuple satisfies all the scan keys * - * *leafValue is set to the reconstructed datum, if provided - * *recheck is set true if any of the operators are lossy + * *reportedSome is set to true if: + * the scan is not ordered AND the item satisfies the scankeys */ static bool -spgLeafTest(Relation index, SpGistScanOpaque so, +spgLeafTest(SpGistScanOpaque so, SpGistSearchItem *item, SpGistLeafTuple leafTuple, bool isnull, - int level, Datum reconstructedValue, - void *traversalValue, - Datum *leafValue, bool *recheck) + bool *reportedSome, storeRes_func storeRes) { + Datum leafValue; + double *distances; bool result; - Datum leafDatum; - spgLeafConsistentIn in; - spgLeafConsistentOut out; - FmgrInfo *procinfo; - MemoryContext oldCtx; + bool recheck; + bool recheckDistances; if (isnull) { /* Should not have arrived on a nulls page unless nulls are wanted */ Assert(so->searchNulls); - *leafValue = (Datum) 0; - *recheck = false; - return true; + leafValue = (Datum) 0; + distances = NULL; + recheck = false; + recheckDistances = false; + result = true; + } + else + { + spgLeafConsistentIn in; + spgLeafConsistentOut out; + + /* use temp context for calling leaf_consistent */ + MemoryContext oldCxt = MemoryContextSwitchTo(so->tempCxt); + + in.scankeys = so->keyData; + in.nkeys = so->numberOfKeys; + in.orderbys = so->orderByData; + in.norderbys = so->numberOfNonNullOrderBys; + in.reconstructedValue = item->value; + in.traversalValue = item->traversalValue; + in.level = item->level; + in.returnData = so->want_itup; + in.leafDatum = SGLTDATUM(leafTuple, &so->state); + + out.leafValue = (Datum) 0; + out.recheck = false; + out.distances = NULL; + out.recheckDistances = false; + + result = DatumGetBool(FunctionCall2Coll(&so->leafConsistentFn, + so->indexCollation, + PointerGetDatum(&in), + PointerGetDatum(&out))); + recheck = out.recheck; + recheckDistances = out.recheckDistances; + leafValue = out.leafValue; + distances = out.distances; + + MemoryContextSwitchTo(oldCxt); } - leafDatum = SGLTDATUM(leafTuple, &so->state); + if (result) + { + /* item passes the scankeys */ + if (so->numberOfNonNullOrderBys > 0) + { + /* the scan is ordered -> add the item to the queue */ + MemoryContext oldCxt = MemoryContextSwitchTo(so->traversalCxt); + SpGistSearchItem *heapItem = spgNewHeapItem(so, item->level, + &leafTuple->heapPtr, + leafValue, + recheck, + recheckDistances, + isnull, + distances); + + spgAddSearchItemToQueue(so, heapItem); + + MemoryContextSwitchTo(oldCxt); + } + else + { + /* non-ordered scan, so report the item right away */ + Assert(!recheckDistances); + storeRes(so, &leafTuple->heapPtr, leafValue, isnull, + recheck, false, NULL); + *reportedSome = true; + } + } - /* use temp context for calling leaf_consistent */ - oldCtx = MemoryContextSwitchTo(so->tempCxt); + return result; +} - in.scankeys = so->keyData; - in.nkeys = so->numberOfKeys; - in.reconstructedValue = reconstructedValue; - in.traversalValue = traversalValue; - in.level = level; - in.returnData = so->want_itup; - in.leafDatum = leafDatum; +/* A bundle initializer for inner_consistent methods */ +static void +spgInitInnerConsistentIn(spgInnerConsistentIn *in, + SpGistScanOpaque so, + SpGistSearchItem *item, + SpGistInnerTuple innerTuple) +{ + in->scankeys = so->keyData; + in->orderbys = so->orderByData; + in->nkeys = so->numberOfKeys; + in->norderbys = so->numberOfNonNullOrderBys; + in->reconstructedValue = item->value; + in->traversalMemoryContext = so->traversalCxt; + in->traversalValue = item->traversalValue; + in->level = item->level; + in->returnData = so->want_itup; + in->allTheSame = innerTuple->allTheSame; + in->hasPrefix = (innerTuple->prefixSize > 0); + in->prefixDatum = SGITDATUM(innerTuple, &so->state); + in->nNodes = innerTuple->nNodes; + in->nodeLabels = spgExtractNodeLabels(&so->state, innerTuple); +} + +static SpGistSearchItem * +spgMakeInnerItem(SpGistScanOpaque so, + SpGistSearchItem *parentItem, + SpGistNodeTuple tuple, + spgInnerConsistentOut *out, int i, bool isnull, + double *distances) +{ + SpGistSearchItem *item = spgAllocSearchItem(so, isnull, distances); + + item->heapPtr = tuple->t_tid; + item->level = out->levelAdds ? parentItem->level + out->levelAdds[i] + : parentItem->level; + + /* Must copy value out of temp context */ + item->value = out->reconstructedValues + ? datumCopy(out->reconstructedValues[i], + so->state.attLeafType.attbyval, + so->state.attLeafType.attlen) + : (Datum) 0; + + /* + * Elements of out.traversalValues should be allocated in + * in.traversalMemoryContext, which is actually a long lived context of + * index scan. + */ + item->traversalValue = + out->traversalValues ? out->traversalValues[i] : NULL; + + item->isLeaf = false; + item->recheck = false; + item->recheckDistances = false; + + return item; +} - out.leafValue = (Datum) 0; - out.recheck = false; +static void +spgInnerTest(SpGistScanOpaque so, SpGistSearchItem *item, + SpGistInnerTuple innerTuple, bool isnull) +{ + MemoryContext oldCxt = MemoryContextSwitchTo(so->tempCxt); + spgInnerConsistentOut out; + int nNodes = innerTuple->nNodes; + int i; - procinfo = index_getprocinfo(index, 1, SPGIST_LEAF_CONSISTENT_PROC); - result = DatumGetBool(FunctionCall2Coll(procinfo, - index->rd_indcollation[0], - PointerGetDatum(&in), - PointerGetDatum(&out))); + memset(&out, 0, sizeof(out)); - *leafValue = out.leafValue; - *recheck = out.recheck; + if (!isnull) + { + spgInnerConsistentIn in; - MemoryContextSwitchTo(oldCtx); + spgInitInnerConsistentIn(&in, so, item, innerTuple); - return result; + /* use user-defined inner consistent method */ + FunctionCall2Coll(&so->innerConsistentFn, + so->indexCollation, + PointerGetDatum(&in), + PointerGetDatum(&out)); + } + else + { + /* force all children to be visited */ + out.nNodes = nNodes; + out.nodeNumbers = (int *) palloc(sizeof(int) * nNodes); + for (i = 0; i < nNodes; i++) + out.nodeNumbers[i] = i; + } + + /* If allTheSame, they should all or none of them match */ + if (innerTuple->allTheSame && out.nNodes != 0 && out.nNodes != nNodes) + elog(ERROR, "inconsistent inner_consistent results for allTheSame inner tuple"); + + if (out.nNodes) + { + /* collect node pointers */ + SpGistNodeTuple node; + SpGistNodeTuple *nodes = (SpGistNodeTuple *) palloc( + sizeof(SpGistNodeTuple) * nNodes); + + SGITITERATE(innerTuple, i, node) + { + nodes[i] = node; + } + + MemoryContextSwitchTo(so->traversalCxt); + + for (i = 0; i < out.nNodes; i++) + { + int nodeN = out.nodeNumbers[i]; + SpGistSearchItem *innerItem; + double *distances; + + Assert(nodeN >= 0 && nodeN < nNodes); + + node = nodes[nodeN]; + + if (!ItemPointerIsValid(&node->t_tid)) + continue; + + /* + * Use infinity distances if innerConsistentFn() failed to return + * them or if is a NULL item (their distances are really unused). + */ + distances = out.distances ? out.distances[i] : so->infDistances; + + innerItem = spgMakeInnerItem(so, item, node, &out, i, isnull, + distances); + + spgAddSearchItemToQueue(so, innerItem); + } + } + + MemoryContextSwitchTo(oldCxt); +} + +/* Returns a next item in an (ordered) scan or null if the index is exhausted */ +static SpGistSearchItem * +spgGetNextQueueItem(SpGistScanOpaque so) +{ + if (pairingheap_is_empty(so->scanQueue)) + return NULL; /* Done when both heaps are empty */ + + /* Return item; caller is responsible to pfree it */ + return (SpGistSearchItem *) pairingheap_remove_first(so->scanQueue); +} + +enum SpGistSpecialOffsetNumbers +{ + SpGistBreakOffsetNumber = InvalidOffsetNumber, + SpGistRedirectOffsetNumber = MaxOffsetNumber + 1, + SpGistErrorOffsetNumber = MaxOffsetNumber + 2 +}; + +static OffsetNumber +spgTestLeafTuple(SpGistScanOpaque so, + SpGistSearchItem *item, + Page page, OffsetNumber offset, + bool isnull, bool isroot, + bool *reportedSome, + storeRes_func storeRes) +{ + SpGistLeafTuple leafTuple = (SpGistLeafTuple) + PageGetItem(page, PageGetItemId(page, offset)); + + if (leafTuple->tupstate != SPGIST_LIVE) + { + if (!isroot) /* all tuples on root should be live */ + { + if (leafTuple->tupstate == SPGIST_REDIRECT) + { + /* redirection tuple should be first in chain */ + Assert(offset == ItemPointerGetOffsetNumber(&item->heapPtr)); + /* transfer attention to redirect point */ + item->heapPtr = ((SpGistDeadTuple) leafTuple)->pointer; + Assert(ItemPointerGetBlockNumber(&item->heapPtr) != SPGIST_METAPAGE_BLKNO); + return SpGistRedirectOffsetNumber; + } + + if (leafTuple->tupstate == SPGIST_DEAD) + { + /* dead tuple should be first in chain */ + Assert(offset == ItemPointerGetOffsetNumber(&item->heapPtr)); + /* No live entries on this page */ + Assert(leafTuple->nextOffset == InvalidOffsetNumber); + return SpGistBreakOffsetNumber; + } + } + + /* We should not arrive at a placeholder */ + elog(ERROR, "unexpected SPGiST tuple state: %d", leafTuple->tupstate); + return SpGistErrorOffsetNumber; + } + + Assert(ItemPointerIsValid(&leafTuple->heapPtr)); + + spgLeafTest(so, item, leafTuple, isnull, reportedSome, storeRes); + + return leafTuple->nextOffset; } /* @@ -313,247 +770,101 @@ spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, while (scanWholeIndex || !reportedSome) { - ScanStackEntry *stackEntry; - BlockNumber blkno; - OffsetNumber offset; - Page page; - bool isnull; - - /* Pull next to-do item from the list */ - if (so->scanStack == NIL) - break; /* there are no more pages to scan */ + SpGistSearchItem *item = spgGetNextQueueItem(so); - stackEntry = (ScanStackEntry *) linitial(so->scanStack); - so->scanStack = list_delete_first(so->scanStack); + if (item == NULL) + break; /* No more items in queue -> done */ redirect: /* Check for interrupts, just in case of infinite loop */ CHECK_FOR_INTERRUPTS(); - blkno = ItemPointerGetBlockNumber(&stackEntry->ptr); - offset = ItemPointerGetOffsetNumber(&stackEntry->ptr); - - if (buffer == InvalidBuffer) + if (item->isLeaf) { - buffer = ReadBuffer(index, blkno); - LockBuffer(buffer, BUFFER_LOCK_SHARE); + /* We store heap items in the queue only in case of ordered search */ + Assert(so->numberOfNonNullOrderBys > 0); + storeRes(so, &item->heapPtr, item->value, item->isNull, + item->recheck, item->recheckDistances, item->distances); + reportedSome = true; } - else if (blkno != BufferGetBlockNumber(buffer)) + else { - UnlockReleaseBuffer(buffer); - buffer = ReadBuffer(index, blkno); - LockBuffer(buffer, BUFFER_LOCK_SHARE); - } - /* else new pointer points to the same page, no work needed */ + BlockNumber blkno = ItemPointerGetBlockNumber(&item->heapPtr); + OffsetNumber offset = ItemPointerGetOffsetNumber(&item->heapPtr); + Page page; + bool isnull; + + if (buffer == InvalidBuffer) + { + buffer = ReadBuffer(index, blkno); + LockBuffer(buffer, BUFFER_LOCK_SHARE); + } + else if (blkno != BufferGetBlockNumber(buffer)) + { + UnlockReleaseBuffer(buffer); + buffer = ReadBuffer(index, blkno); + LockBuffer(buffer, BUFFER_LOCK_SHARE); + } - page = BufferGetPage(buffer); - TestForOldSnapshot(snapshot, index, page); + /* else new pointer points to the same page, no work needed */ - isnull = SpGistPageStoresNulls(page) ? true : false; + page = BufferGetPage(buffer); + TestForOldSnapshot(snapshot, index, page); - if (SpGistPageIsLeaf(page)) - { - SpGistLeafTuple leafTuple; - OffsetNumber max = PageGetMaxOffsetNumber(page); - Datum leafValue = (Datum) 0; - bool recheck = false; + isnull = SpGistPageStoresNulls(page) ? true : false; - if (SpGistBlockIsRoot(blkno)) + if (SpGistPageIsLeaf(page)) { - /* When root is a leaf, examine all its tuples */ - for (offset = FirstOffsetNumber; offset <= max; offset++) - { - leafTuple = (SpGistLeafTuple) - PageGetItem(page, PageGetItemId(page, offset)); - if (leafTuple->tupstate != SPGIST_LIVE) - { - /* all tuples on root should be live */ - elog(ERROR, "unexpected SPGiST tuple state: %d", - leafTuple->tupstate); - } + /* Page is a leaf - that is, all it's tuples are heap items */ + OffsetNumber max = PageGetMaxOffsetNumber(page); - Assert(ItemPointerIsValid(&leafTuple->heapPtr)); - if (spgLeafTest(index, so, - leafTuple, isnull, - stackEntry->level, - stackEntry->reconstructedValue, - stackEntry->traversalValue, - &leafValue, - &recheck)) - { - storeRes(so, &leafTuple->heapPtr, - leafValue, isnull, recheck); - reportedSome = true; - } + if (SpGistBlockIsRoot(blkno)) + { + /* When root is a leaf, examine all its tuples */ + for (offset = FirstOffsetNumber; offset <= max; offset++) + (void) spgTestLeafTuple(so, item, page, offset, + isnull, true, + &reportedSome, storeRes); } - } - else - { - /* Normal case: just examine the chain we arrived at */ - while (offset != InvalidOffsetNumber) + else { - Assert(offset >= FirstOffsetNumber && offset <= max); - leafTuple = (SpGistLeafTuple) - PageGetItem(page, PageGetItemId(page, offset)); - if (leafTuple->tupstate != SPGIST_LIVE) + /* Normal case: just examine the chain we arrived at */ + while (offset != InvalidOffsetNumber) { - if (leafTuple->tupstate == SPGIST_REDIRECT) - { - /* redirection tuple should be first in chain */ - Assert(offset == ItemPointerGetOffsetNumber(&stackEntry->ptr)); - /* transfer attention to redirect point */ - stackEntry->ptr = ((SpGistDeadTuple) leafTuple)->pointer; - Assert(ItemPointerGetBlockNumber(&stackEntry->ptr) != SPGIST_METAPAGE_BLKNO); + Assert(offset >= FirstOffsetNumber && offset <= max); + offset = spgTestLeafTuple(so, item, page, offset, + isnull, false, + &reportedSome, storeRes); + if (offset == SpGistRedirectOffsetNumber) goto redirect; - } - if (leafTuple->tupstate == SPGIST_DEAD) - { - /* dead tuple should be first in chain */ - Assert(offset == ItemPointerGetOffsetNumber(&stackEntry->ptr)); - /* No live entries on this page */ - Assert(leafTuple->nextOffset == InvalidOffsetNumber); - break; - } - /* We should not arrive at a placeholder */ - elog(ERROR, "unexpected SPGiST tuple state: %d", - leafTuple->tupstate); } - - Assert(ItemPointerIsValid(&leafTuple->heapPtr)); - if (spgLeafTest(index, so, - leafTuple, isnull, - stackEntry->level, - stackEntry->reconstructedValue, - stackEntry->traversalValue, - &leafValue, - &recheck)) - { - storeRes(so, &leafTuple->heapPtr, - leafValue, isnull, recheck); - reportedSome = true; - } - - offset = leafTuple->nextOffset; } } - } - else /* page is inner */ - { - SpGistInnerTuple innerTuple; - spgInnerConsistentIn in; - spgInnerConsistentOut out; - FmgrInfo *procinfo; - SpGistNodeTuple *nodes; - SpGistNodeTuple node; - int i; - MemoryContext oldCtx; - - innerTuple = (SpGistInnerTuple) PageGetItem(page, - PageGetItemId(page, offset)); - - if (innerTuple->tupstate != SPGIST_LIVE) - { - if (innerTuple->tupstate == SPGIST_REDIRECT) - { - /* transfer attention to redirect point */ - stackEntry->ptr = ((SpGistDeadTuple) innerTuple)->pointer; - Assert(ItemPointerGetBlockNumber(&stackEntry->ptr) != SPGIST_METAPAGE_BLKNO); - goto redirect; - } - elog(ERROR, "unexpected SPGiST tuple state: %d", - innerTuple->tupstate); - } - - /* use temp context for calling inner_consistent */ - oldCtx = MemoryContextSwitchTo(so->tempCxt); - - in.scankeys = so->keyData; - in.nkeys = so->numberOfKeys; - in.reconstructedValue = stackEntry->reconstructedValue; - in.traversalMemoryContext = so->traversalCxt; - in.traversalValue = stackEntry->traversalValue; - in.level = stackEntry->level; - in.returnData = so->want_itup; - in.allTheSame = innerTuple->allTheSame; - in.hasPrefix = (innerTuple->prefixSize > 0); - in.prefixDatum = SGITDATUM(innerTuple, &so->state); - in.nNodes = innerTuple->nNodes; - in.nodeLabels = spgExtractNodeLabels(&so->state, innerTuple); - - /* collect node pointers */ - nodes = (SpGistNodeTuple *) palloc(sizeof(SpGistNodeTuple) * in.nNodes); - SGITITERATE(innerTuple, i, node) - { - nodes[i] = node; - } - - memset(&out, 0, sizeof(out)); - - if (!isnull) - { - /* use user-defined inner consistent method */ - procinfo = index_getprocinfo(index, 1, SPGIST_INNER_CONSISTENT_PROC); - FunctionCall2Coll(procinfo, - index->rd_indcollation[0], - PointerGetDatum(&in), - PointerGetDatum(&out)); - } - else - { - /* force all children to be visited */ - out.nNodes = in.nNodes; - out.nodeNumbers = (int *) palloc(sizeof(int) * in.nNodes); - for (i = 0; i < in.nNodes; i++) - out.nodeNumbers[i] = i; - } - - MemoryContextSwitchTo(oldCtx); - - /* If allTheSame, they should all or none of 'em match */ - if (innerTuple->allTheSame) - if (out.nNodes != 0 && out.nNodes != in.nNodes) - elog(ERROR, "inconsistent inner_consistent results for allTheSame inner tuple"); - - for (i = 0; i < out.nNodes; i++) + else /* page is inner */ { - int nodeN = out.nodeNumbers[i]; + SpGistInnerTuple innerTuple = (SpGistInnerTuple) + PageGetItem(page, PageGetItemId(page, offset)); - Assert(nodeN >= 0 && nodeN < in.nNodes); - if (ItemPointerIsValid(&nodes[nodeN]->t_tid)) + if (innerTuple->tupstate != SPGIST_LIVE) { - ScanStackEntry *newEntry; - - /* Create new work item for this node */ - newEntry = palloc(sizeof(ScanStackEntry)); - newEntry->ptr = nodes[nodeN]->t_tid; - if (out.levelAdds) - newEntry->level = stackEntry->level + out.levelAdds[i]; - else - newEntry->level = stackEntry->level; - /* Must copy value out of temp context */ - if (out.reconstructedValues) - newEntry->reconstructedValue = - datumCopy(out.reconstructedValues[i], - so->state.attLeafType.attbyval, - so->state.attLeafType.attlen); - else - newEntry->reconstructedValue = (Datum) 0; - - /* - * Elements of out.traversalValues should be allocated in - * in.traversalMemoryContext, which is actually a long - * lived context of index scan. - */ - newEntry->traversalValue = (out.traversalValues) ? - out.traversalValues[i] : NULL; - - so->scanStack = lcons(newEntry, so->scanStack); + if (innerTuple->tupstate == SPGIST_REDIRECT) + { + /* transfer attention to redirect point */ + item->heapPtr = ((SpGistDeadTuple) innerTuple)->pointer; + Assert(ItemPointerGetBlockNumber(&item->heapPtr) != + SPGIST_METAPAGE_BLKNO); + goto redirect; + } + elog(ERROR, "unexpected SPGiST tuple state: %d", + innerTuple->tupstate); } + + spgInnerTest(so, item, innerTuple, isnull); } } - /* done with this scan stack entry */ - freeScanStackEntry(so, stackEntry); + /* done with this scan item */ + spgFreeSearchItem(so, item); /* clear temp context before proceeding to the next one */ MemoryContextReset(so->tempCxt); } @@ -562,11 +873,14 @@ spgWalk(Relation index, SpGistScanOpaque so, bool scanWholeIndex, UnlockReleaseBuffer(buffer); } + /* storeRes subroutine for getbitmap case */ static void storeBitmap(SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isnull, bool recheck) + Datum leafValue, bool isnull, bool recheck, bool recheckDistances, + double *distances) { + Assert(!recheckDistances && !distances); tbm_add_tuples(so->tbm, heapPtr, 1, recheck); so->ntids++; } @@ -590,11 +904,46 @@ spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm) /* storeRes subroutine for gettuple case */ static void storeGettuple(SpGistScanOpaque so, ItemPointer heapPtr, - Datum leafValue, bool isnull, bool recheck) + Datum leafValue, bool isnull, bool recheck, bool recheckDistances, + double *nonNullDistances) { Assert(so->nPtrs < MaxIndexTuplesPerPage); so->heapPtrs[so->nPtrs] = *heapPtr; so->recheck[so->nPtrs] = recheck; + so->recheckDistances[so->nPtrs] = recheckDistances; + + if (so->numberOfOrderBys > 0) + { + if (isnull || so->numberOfNonNullOrderBys <= 0) + so->distances[so->nPtrs] = NULL; + else + { + IndexOrderByDistance *distances = + palloc(sizeof(distances[0]) * so->numberOfOrderBys); + int i; + + for (i = 0; i < so->numberOfOrderBys; i++) + { + int offset = so->nonNullOrderByOffsets[i]; + + if (offset >= 0) + { + /* Copy non-NULL distance value */ + distances[i].value = nonNullDistances[offset]; + distances[i].isnull = false; + } + else + { + /* Set distance's NULL flag. */ + distances[i].value = 0.0; + distances[i].isnull = true; + } + } + + so->distances[so->nPtrs] = distances; + } + } + if (so->want_itup) { /* @@ -623,14 +972,29 @@ spggettuple(IndexScanDesc scan, ScanDirection dir) { if (so->iPtr < so->nPtrs) { - /* continuing to return tuples from a leaf page */ - scan->xs_ctup.t_self = so->heapPtrs[so->iPtr]; + /* continuing to return reported tuples */ + scan->xs_heaptid = so->heapPtrs[so->iPtr]; scan->xs_recheck = so->recheck[so->iPtr]; scan->xs_hitup = so->reconTups[so->iPtr]; + + if (so->numberOfOrderBys > 0) + index_store_float8_orderby_distances(scan, so->orderByTypes, + so->distances[so->iPtr], + so->recheckDistances[so->iPtr]); so->iPtr++; return true; } + if (so->numberOfOrderBys > 0) + { + /* Must pfree distances to avoid memory leak */ + int i; + + for (i = 0; i < so->nPtrs; i++) + if (so->distances[i]) + pfree(so->distances[i]); + } + if (so->want_itup) { /* Must pfree reconstructed tuples to avoid memory leak */ diff --git a/src/backend/access/spgist/spgtextproc.c b/src/backend/access/spgist/spgtextproc.c index 76c0305695b..a7c1a09e05f 100644 --- a/src/backend/access/spgist/spgtextproc.c +++ b/src/backend/access/spgist/spgtextproc.c @@ -29,7 +29,7 @@ * No new entries ever get pushed into a -2-labeled child, either. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -626,15 +626,16 @@ spg_text_leaf_consistent(PG_FUNCTION_ARGS) if (strategy == RTPrefixStrategyNumber) { /* - * if level >= length of query then reconstrValue is began with - * query (prefix) string and we don't need to check it again. + * if level >= length of query then reconstrValue must begin with + * query (prefix) string, so we don't need to check it again. */ - res = (level >= queryLen) || - DatumGetBool(DirectFunctionCall2(text_starts_with, - out->leafValue, PointerGetDatum(query))); + DatumGetBool(DirectFunctionCall2Coll(text_starts_with, + PG_GET_COLLATION(), + out->leafValue, + PointerGetDatum(query))); - if (!res) /* no need to consider remaining conditions */ + if (!res) /* no need to consider remaining conditions */ break; continue; @@ -648,22 +649,22 @@ spg_text_leaf_consistent(PG_FUNCTION_ARGS) /* If asserts enabled, verify encoding of reconstructed string */ Assert(pg_verifymbstr(fullValue, fullLen, false)); - r = varstr_cmp(fullValue, Min(queryLen, fullLen), - VARDATA_ANY(query), Min(queryLen, fullLen), + r = varstr_cmp(fullValue, fullLen, + VARDATA_ANY(query), queryLen, PG_GET_COLLATION()); } else { /* Non-collation-aware comparison */ r = memcmp(fullValue, VARDATA_ANY(query), Min(queryLen, fullLen)); - } - if (r == 0) - { - if (queryLen > fullLen) - r = -1; - else if (queryLen < fullLen) - r = 1; + if (r == 0) + { + if (queryLen > fullLen) + r = -1; + else if (queryLen < fullLen) + r = 1; + } } switch (strategy) diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c index 4a9b5da268d..45472db147b 100644 --- a/src/backend/access/spgist/spgutils.c +++ b/src/backend/access/spgist/spgutils.c @@ -4,7 +4,7 @@ * various support functions for SP-GiST * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,16 +15,21 @@ #include "postgres.h" +#include "access/amvalidate.h" +#include "access/htup_details.h" #include "access/reloptions.h" #include "access/spgist_private.h" #include "access/transam.h" #include "access/xact.h" +#include "catalog/pg_amop.h" #include "storage/bufmgr.h" #include "storage/indexfsm.h" #include "storage/lmgr.h" #include "utils/builtins.h" +#include "utils/catcache.h" #include "utils/index_selfuncs.h" #include "utils/lsyscache.h" +#include "utils/syscache.h" /* @@ -39,7 +44,7 @@ spghandler(PG_FUNCTION_ARGS) amroutine->amstrategies = 0; amroutine->amsupport = SPGISTNProc; amroutine->amcanorder = false; - amroutine->amcanorderbyop = false; + amroutine->amcanorderbyop = true; amroutine->amcanbackward = false; amroutine->amcanunique = false; amroutine->amcanmulticol = false; @@ -61,7 +66,8 @@ spghandler(PG_FUNCTION_ARGS) amroutine->amcanreturn = spgcanreturn; amroutine->amcostestimate = spgcostestimate; amroutine->amoptions = spgoptions; - amroutine->amproperty = NULL; + amroutine->amproperty = spgproperty; + amroutine->ambuildphasename = NULL; amroutine->amvalidate = spgvalidate; amroutine->ambeginscan = spgbeginscan; amroutine->amrescan = spgrescan; @@ -133,7 +139,7 @@ spgGetCache(Relation index) if (!OidIsValid(index_getprocid(index, 1, SPGIST_COMPRESS_PROC))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("compress method must not defined when leaf type is different from input type"))); + errmsg("compress method must be defined when leaf type is different from input type"))); fillTypeDesc(&cache->attLeafType, cache->config.leafType); } @@ -949,3 +955,82 @@ SpGistPageAddNewItem(SpGistState *state, Page page, Item item, Size size, return offnum; } + +/* + * spgproperty() -- Check boolean properties of indexes. + * + * This is optional for most AMs, but is required for SP-GiST because the core + * property code doesn't support AMPROP_DISTANCE_ORDERABLE. + */ +bool +spgproperty(Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull) +{ + Oid opclass, + opfamily, + opcintype; + CatCList *catlist; + int i; + + /* Only answer column-level inquiries */ + if (attno == 0) + return false; + + switch (prop) + { + case AMPROP_DISTANCE_ORDERABLE: + break; + default: + return false; + } + + /* + * Currently, SP-GiST distance-ordered scans require that there be a + * distance operator in the opclass with the default types. So we assume + * that if such a operator exists, then there's a reason for it. + */ + + /* First we need to know the column's opclass. */ + opclass = get_index_column_opclass(index_oid, attno); + if (!OidIsValid(opclass)) + { + *isnull = true; + return true; + } + + /* Now look up the opclass family and input datatype. */ + if (!get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype)) + { + *isnull = true; + return true; + } + + /* And now we can check whether the operator is provided. */ + catlist = SearchSysCacheList1(AMOPSTRATEGY, + ObjectIdGetDatum(opfamily)); + + *res = false; + + for (i = 0; i < catlist->n_members; i++) + { + HeapTuple amoptup = &catlist->members[i]->tuple; + Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(amoptup); + + if (amopform->amoppurpose == AMOP_ORDER && + (amopform->amoplefttype == opcintype || + amopform->amoprighttype == opcintype) && + opfamily_can_sort_type(amopform->amopsortfamily, + get_op_rettype(amopform->amopopr))) + { + *res = true; + break; + } + } + + ReleaseSysCacheList(catlist); + + *isnull = false; + + return true; +} diff --git a/src/backend/access/spgist/spgvacuum.c b/src/backend/access/spgist/spgvacuum.c index a83a4b581ed..478d4c0d612 100644 --- a/src/backend/access/spgist/spgvacuum.c +++ b/src/backend/access/spgist/spgvacuum.c @@ -4,7 +4,7 @@ * vacuum for SP-GiST * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -192,9 +192,9 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, * happened since VACUUM started. * * Note: we could make a tighter test by seeing if the xid is - * "running" according to the active snapshot; but tqual.c doesn't - * currently export a suitable API, and it's not entirely clear - * that a tighter test is worth the cycles anyway. + * "running" according to the active snapshot; but snapmgr.c + * doesn't currently export a suitable API, and it's not entirely + * clear that a tighter test is worth the cycles anyway. */ if (TransactionIdFollowsOrEquals(dt->xid, bds->myXmin)) spgAddPendingTID(bds, &dt->pointer); @@ -337,7 +337,7 @@ vacuumLeafPage(spgBulkDeleteState *bds, Relation index, Buffer buffer, InvalidBlockNumber, InvalidOffsetNumber); /* - * We implement the move step by swapping the item pointers of the source + * We implement the move step by swapping the line pointers of the source * and target tuples, then replacing the newly-source tuples with * placeholders. This is perhaps unduly friendly with the page data * representation, but it's fast and doesn't risk page overflow when a @@ -842,7 +842,7 @@ spgvacuumscan(spgBulkDeleteState *bds) } } - /* Propagate local lastUsedPage cache to metablock */ + /* Propagate local lastUsedPages cache to metablock */ SpGistUpdateMetaPage(index); /* diff --git a/src/backend/access/spgist/spgvalidate.c b/src/backend/access/spgist/spgvalidate.c index 8bbed7ff32b..4b9fdbd5d78 100644 --- a/src/backend/access/spgist/spgvalidate.c +++ b/src/backend/access/spgist/spgvalidate.c @@ -3,7 +3,7 @@ * spgvalidate.c * Opclass validator for SP-GiST. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -53,7 +53,7 @@ spgvalidate(Oid opclassoid) OpFamilyOpFuncGroup *opclassgroup; int i; ListCell *lc; - spgConfigIn configIn; + spgConfigIn configIn; spgConfigOut configOut; Oid configOutLefttype = InvalidOid; Oid configOutRighttype = InvalidOid; @@ -96,7 +96,7 @@ spgvalidate(Oid opclassoid) { ereport(INFO, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains support procedure %s with different left and right input types", + errmsg("operator family \"%s\" of access method %s contains support function %s with different left and right input types", opfamilyname, "spgist", format_procedure(procform->amproc)))); result = false; @@ -119,9 +119,9 @@ spgvalidate(Oid opclassoid) configOutRighttype = procform->amprocrighttype; /* - * When leaf and attribute types are the same, compress function - * is not required and we set corresponding bit in functionset - * for later group consistency check. + * When leaf and attribute types are the same, compress + * function is not required and we set corresponding bit in + * functionset for later group consistency check. */ if (!OidIsValid(configOut.leafType) || configOut.leafType == configIn.attType) @@ -187,6 +187,7 @@ spgvalidate(Oid opclassoid) { HeapTuple oprtup = &oprlist->members[i]->tuple; Form_pg_amop oprform = (Form_pg_amop) GETSTRUCT(oprtup); + Oid op_rettype; /* TODO: Check that only allowed strategy numbers exist */ if (oprform->amopstrategy < 1 || oprform->amopstrategy > 63) @@ -200,20 +201,26 @@ spgvalidate(Oid opclassoid) result = false; } - /* spgist doesn't support ORDER BY operators */ - if (oprform->amoppurpose != AMOP_SEARCH || - OidIsValid(oprform->amopsortfamily)) + /* spgist supports ORDER BY operators */ + if (oprform->amoppurpose != AMOP_SEARCH) { - ereport(INFO, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s", - opfamilyname, "spgist", - format_operator(oprform->amopopr)))); - result = false; + /* ... and operator result must match the claimed btree opfamily */ + op_rettype = get_op_rettype(oprform->amopopr); + if (!opfamily_can_sort_type(oprform->amopsortfamily, op_rettype)) + { + ereport(INFO, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s", + opfamilyname, "spgist", + format_operator(oprform->amopopr)))); + result = false; + } } + else + op_rettype = BOOLOID; /* Check operator signature --- same for all spgist strategies */ - if (!check_amop_signature(oprform->amopopr, BOOLOID, + if (!check_amop_signature(oprform->amopopr, op_rettype, oprform->amoplefttype, oprform->amoprighttype)) { diff --git a/src/backend/access/spgist/spgxlog.c b/src/backend/access/spgist/spgxlog.c index 9e2bd3f8119..ebe6ae8715b 100644 --- a/src/backend/access/spgist/spgxlog.c +++ b/src/backend/access/spgist/spgxlog.c @@ -4,7 +4,7 @@ * WAL replay logic for SP-GiST * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -72,38 +72,6 @@ addOrReplaceTuple(Page page, Item tuple, int size, OffsetNumber offset) size); } -static void -spgRedoCreateIndex(XLogReaderState *record) -{ - XLogRecPtr lsn = record->EndRecPtr; - Buffer buffer; - Page page; - - buffer = XLogInitBufferForRedo(record, 0); - Assert(BufferGetBlockNumber(buffer) == SPGIST_METAPAGE_BLKNO); - page = (Page) BufferGetPage(buffer); - SpGistInitMetapage(page); - PageSetLSN(page, lsn); - MarkBufferDirty(buffer); - UnlockReleaseBuffer(buffer); - - buffer = XLogInitBufferForRedo(record, 1); - Assert(BufferGetBlockNumber(buffer) == SPGIST_ROOT_BLKNO); - SpGistInitBuffer(buffer, SPGIST_LEAF); - page = (Page) BufferGetPage(buffer); - PageSetLSN(page, lsn); - MarkBufferDirty(buffer); - UnlockReleaseBuffer(buffer); - - buffer = XLogInitBufferForRedo(record, 2); - Assert(BufferGetBlockNumber(buffer) == SPGIST_NULL_BLKNO); - SpGistInitBuffer(buffer, SPGIST_LEAF | SPGIST_NULLS); - page = (Page) BufferGetPage(buffer); - PageSetLSN(page, lsn); - MarkBufferDirty(buffer); - UnlockReleaseBuffer(buffer); -} - static void spgRedoAddLeaf(XLogReaderState *record) { @@ -976,9 +944,6 @@ spg_redo(XLogReaderState *record) oldCxt = MemoryContextSwitchTo(opCtx); switch (info) { - case XLOG_SPGIST_CREATE_INDEX: - spgRedoCreateIndex(record); - break; case XLOG_SPGIST_ADD_LEAF: spgRedoAddLeaf(record); break; diff --git a/src/backend/access/table/Makefile b/src/backend/access/table/Makefile new file mode 100644 index 00000000000..b29df3f3335 --- /dev/null +++ b/src/backend/access/table/Makefile @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for access/table +# +# IDENTIFICATION +# src/backend/access/table/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/access/table +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = table.o tableam.o tableamapi.o toast_helper.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/table/table.c b/src/backend/access/table/table.c new file mode 100644 index 00000000000..a51c06ce2e9 --- /dev/null +++ b/src/backend/access/table/table.c @@ -0,0 +1,136 @@ +/*------------------------------------------------------------------------- + * + * table.c + * Generic routines for table related code. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/table/table.c + * + * + * NOTES + * This file contains table_ routines that implement access to tables (in + * contrast to other relation types like indexes) that are independent of + * individual table access methods. + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/relation.h" +#include "access/table.h" +#include "storage/lmgr.h" + + +/* ---------------- + * table_open - open a table relation by relation OID + * + * This is essentially relation_open plus check that the relation + * is not an index nor a composite type. (The caller should also + * check that it's not a view or foreign table before assuming it has + * storage.) + * ---------------- + */ +Relation +table_open(Oid relationId, LOCKMODE lockmode) +{ + Relation r; + + r = relation_open(relationId, lockmode); + + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + + return r; +} + +/* ---------------- + * table_openrv - open a table relation specified + * by a RangeVar node + * + * As above, but relation is specified by a RangeVar. + * ---------------- + */ +Relation +table_openrv(const RangeVar *relation, LOCKMODE lockmode) +{ + Relation r; + + r = relation_openrv(relation, lockmode); + + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + + return r; +} + +/* ---------------- + * table_openrv_extended - open a table relation specified + * by a RangeVar node + * + * As above, but optionally return NULL instead of failing for + * relation-not-found. + * ---------------- + */ +Relation +table_openrv_extended(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok) +{ + Relation r; + + r = relation_openrv_extended(relation, lockmode, missing_ok); + + if (r) + { + if (r->rd_rel->relkind == RELKIND_INDEX || + r->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is an index", + RelationGetRelationName(r)))); + else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("\"%s\" is a composite type", + RelationGetRelationName(r)))); + } + + return r; +} + +/* ---------------- + * table_close - close a table + * + * If lockmode is not "NoLock", we then release the specified lock. + * + * Note that it is often sensible to hold a lock beyond relation_close; + * in that case, the lock is released automatically at xact end. + * ---------------- + */ +void +table_close(Relation relation, LOCKMODE lockmode) +{ + relation_close(relation, lockmode); +} diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c new file mode 100644 index 00000000000..5d3f5c3f541 --- /dev/null +++ b/src/backend/access/table/tableam.c @@ -0,0 +1,649 @@ +/*---------------------------------------------------------------------- + * + * tableam.c + * Table access method routines too big to be inline functions. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/access/table/tableam.c + * + * NOTES + * Note that most function in here are documented in tableam.h, rather than + * here. That's because there's a lot of inline functions in tableam.h and + * it'd be harder to understand if one constantly had to switch between files. + * + *---------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "access/heapam.h" /* for ss_* */ +#include "access/tableam.h" +#include "access/xact.h" +#include "optimizer/plancat.h" +#include "storage/bufmgr.h" +#include "storage/shmem.h" +#include "storage/smgr.h" + + +/* GUC variables */ +char *default_table_access_method = DEFAULT_TABLE_ACCESS_METHOD; +bool synchronize_seqscans = true; + + +/* ---------------------------------------------------------------------------- + * Slot functions. + * ---------------------------------------------------------------------------- + */ + +const TupleTableSlotOps * +table_slot_callbacks(Relation relation) +{ + const TupleTableSlotOps *tts_cb; + + if (relation->rd_tableam) + tts_cb = relation->rd_tableam->slot_callbacks(relation); + else if (relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + /* + * Historically FDWs expect to store heap tuples in slots. Continue + * handing them one, to make it less painful to adapt FDWs to new + * versions. The cost of a heap slot over a virtual slot is pretty + * small. + */ + tts_cb = &TTSOpsHeapTuple; + } + else + { + /* + * These need to be supported, as some parts of the code (like COPY) + * need to create slots for such relations too. It seems better to + * centralize the knowledge that a heap slot is the right thing in + * that case here. + */ + Assert(relation->rd_rel->relkind == RELKIND_VIEW || + relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + tts_cb = &TTSOpsVirtual; + } + + return tts_cb; +} + +TupleTableSlot * +table_slot_create(Relation relation, List **reglist) +{ + const TupleTableSlotOps *tts_cb; + TupleTableSlot *slot; + + tts_cb = table_slot_callbacks(relation); + slot = MakeSingleTupleTableSlot(RelationGetDescr(relation), tts_cb); + + if (reglist) + *reglist = lappend(*reglist, slot); + + return slot; +} + + +/* ---------------------------------------------------------------------------- + * Table scan functions. + * ---------------------------------------------------------------------------- + */ + +TableScanDesc +table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_TYPE_SEQSCAN | + SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE | SO_TEMP_SNAPSHOT; + Oid relid = RelationGetRelid(relation); + Snapshot snapshot = RegisterSnapshot(GetCatalogSnapshot(relid)); + + return relation->rd_tableam->scan_begin(relation, snapshot, nkeys, key, + NULL, flags); +} + +void +table_scan_update_snapshot(TableScanDesc scan, Snapshot snapshot) +{ + Assert(IsMVCCSnapshot(snapshot)); + + RegisterSnapshot(snapshot); + scan->rs_snapshot = snapshot; + scan->rs_flags |= SO_TEMP_SNAPSHOT; +} + + +/* ---------------------------------------------------------------------------- + * Parallel table scan related functions. + * ---------------------------------------------------------------------------- + */ + +Size +table_parallelscan_estimate(Relation rel, Snapshot snapshot) +{ + Size sz = 0; + + if (IsMVCCSnapshot(snapshot)) + sz = add_size(sz, EstimateSnapshotSpace(snapshot)); + else + Assert(snapshot == SnapshotAny); + + sz = add_size(sz, rel->rd_tableam->parallelscan_estimate(rel)); + + return sz; +} + +void +table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan, + Snapshot snapshot) +{ + Size snapshot_off = rel->rd_tableam->parallelscan_initialize(rel, pscan); + + pscan->phs_snapshot_off = snapshot_off; + + if (IsMVCCSnapshot(snapshot)) + { + SerializeSnapshot(snapshot, (char *) pscan + pscan->phs_snapshot_off); + pscan->phs_snapshot_any = false; + } + else + { + Assert(snapshot == SnapshotAny); + pscan->phs_snapshot_any = true; + } +} + +TableScanDesc +table_beginscan_parallel(Relation relation, ParallelTableScanDesc parallel_scan) +{ + Snapshot snapshot; + uint32 flags = SO_TYPE_SEQSCAN | + SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE; + + Assert(RelationGetRelid(relation) == parallel_scan->phs_relid); + + if (!parallel_scan->phs_snapshot_any) + { + /* Snapshot was serialized -- restore it */ + snapshot = RestoreSnapshot((char *) parallel_scan + + parallel_scan->phs_snapshot_off); + RegisterSnapshot(snapshot); + flags |= SO_TEMP_SNAPSHOT; + } + else + { + /* SnapshotAny passed by caller (not serialized) */ + snapshot = SnapshotAny; + } + + return relation->rd_tableam->scan_begin(relation, snapshot, 0, NULL, + parallel_scan, flags); +} + + +/* ---------------------------------------------------------------------------- + * Index scan related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * To perform that check simply start an index scan, create the necessary + * slot, do the heap lookup, and shut everything down again. This could be + * optimized, but is unlikely to matter from a performance POV. If there + * frequently are live index pointers also matching a unique index key, the + * CPU overhead of this routine is unlikely to matter. + */ +bool +table_index_fetch_tuple_check(Relation rel, + ItemPointer tid, + Snapshot snapshot, + bool *all_dead) +{ + IndexFetchTableData *scan; + TupleTableSlot *slot; + bool call_again = false; + bool found; + + slot = table_slot_create(rel, NULL); + scan = table_index_fetch_begin(rel); + found = table_index_fetch_tuple(scan, tid, snapshot, slot, &call_again, + all_dead); + table_index_fetch_end(scan); + ExecDropSingleTupleTableSlot(slot); + + return found; +} + + +/* ------------------------------------------------------------------------ + * Functions for non-modifying operations on individual tuples + * ------------------------------------------------------------------------ + */ + +void +table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid) +{ + Relation rel = scan->rs_rd; + const TableAmRoutine *tableam = rel->rd_tableam; + + /* + * Since this can be called with user-supplied TID, don't trust the input + * too much. + */ + if (!tableam->tuple_tid_valid(scan, tid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("tid (%u, %u) is not valid for relation \"%s\"", + ItemPointerGetBlockNumberNoCheck(tid), + ItemPointerGetOffsetNumberNoCheck(tid), + RelationGetRelationName(rel)))); + + tableam->tuple_get_latest_tid(scan, tid); +} + + +/* ---------------------------------------------------------------------------- + * Functions to make modifications a bit simpler. + * ---------------------------------------------------------------------------- + */ + +/* + * simple_table_tuple_insert - insert a tuple + * + * Currently, this routine differs from table_tuple_insert only in supplying a + * default command ID and not allowing access to the speedup options. + */ +void +simple_table_tuple_insert(Relation rel, TupleTableSlot *slot) +{ + table_tuple_insert(rel, slot, GetCurrentCommandId(true), 0, NULL); +} + +/* + * simple_table_tuple_delete - delete a tuple + * + * This routine may be used to delete a tuple when concurrent updates of + * the target tuple are not expected (for example, because we have a lock + * on the relation associated with the tuple). Any failure is reported + * via ereport(). + */ +void +simple_table_tuple_delete(Relation rel, ItemPointer tid, Snapshot snapshot) +{ + TM_Result result; + TM_FailureData tmfd; + + result = table_tuple_delete(rel, tid, + GetCurrentCommandId(true), + snapshot, InvalidSnapshot, + true /* wait for commit */ , + &tmfd, false /* changingPart */ ); + + switch (result) + { + case TM_SelfModified: + /* Tuple was already updated in current command? */ + elog(ERROR, "tuple already updated by self"); + break; + + case TM_Ok: + /* done successfully */ + break; + + case TM_Updated: + elog(ERROR, "tuple concurrently updated"); + break; + + case TM_Deleted: + elog(ERROR, "tuple concurrently deleted"); + break; + + default: + elog(ERROR, "unrecognized table_tuple_delete status: %u", result); + break; + } +} + +/* + * simple_table_tuple_update - replace a tuple + * + * This routine may be used to update a tuple when concurrent updates of + * the target tuple are not expected (for example, because we have a lock + * on the relation associated with the tuple). Any failure is reported + * via ereport(). + */ +void +simple_table_tuple_update(Relation rel, ItemPointer otid, + TupleTableSlot *slot, + Snapshot snapshot, + bool *update_indexes) +{ + TM_Result result; + TM_FailureData tmfd; + LockTupleMode lockmode; + + result = table_tuple_update(rel, otid, slot, + GetCurrentCommandId(true), + snapshot, InvalidSnapshot, + true /* wait for commit */ , + &tmfd, &lockmode, update_indexes); + + switch (result) + { + case TM_SelfModified: + /* Tuple was already updated in current command? */ + elog(ERROR, "tuple already updated by self"); + break; + + case TM_Ok: + /* done successfully */ + break; + + case TM_Updated: + elog(ERROR, "tuple concurrently updated"); + break; + + case TM_Deleted: + elog(ERROR, "tuple concurrently deleted"); + break; + + default: + elog(ERROR, "unrecognized table_tuple_update status: %u", result); + break; + } + +} + + +/* ---------------------------------------------------------------------------- + * Helper functions to implement parallel scans for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +Size +table_block_parallelscan_estimate(Relation rel) +{ + return sizeof(ParallelBlockTableScanDescData); +} + +Size +table_block_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan) +{ + ParallelBlockTableScanDesc bpscan = (ParallelBlockTableScanDesc) pscan; + + bpscan->base.phs_relid = RelationGetRelid(rel); + bpscan->phs_nblocks = RelationGetNumberOfBlocks(rel); + /* compare phs_syncscan initialization to similar logic in initscan */ + bpscan->base.phs_syncscan = synchronize_seqscans && + !RelationUsesLocalBuffers(rel) && + bpscan->phs_nblocks > NBuffers / 4; + SpinLockInit(&bpscan->phs_mutex); + bpscan->phs_startblock = InvalidBlockNumber; + pg_atomic_init_u64(&bpscan->phs_nallocated, 0); + + return sizeof(ParallelBlockTableScanDescData); +} + +void +table_block_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan) +{ + ParallelBlockTableScanDesc bpscan = (ParallelBlockTableScanDesc) pscan; + + pg_atomic_write_u64(&bpscan->phs_nallocated, 0); +} + +/* + * find and set the scan's startblock + * + * Determine where the parallel seq scan should start. This function may be + * called many times, once by each parallel worker. We must be careful only + * to set the startblock once. + */ +void +table_block_parallelscan_startblock_init(Relation rel, ParallelBlockTableScanDesc pbscan) +{ + BlockNumber sync_startpage = InvalidBlockNumber; + +retry: + /* Grab the spinlock. */ + SpinLockAcquire(&pbscan->phs_mutex); + + /* + * If the scan's startblock has not yet been initialized, we must do so + * now. If this is not a synchronized scan, we just start at block 0, but + * if it is a synchronized scan, we must get the starting position from + * the synchronized scan machinery. We can't hold the spinlock while + * doing that, though, so release the spinlock, get the information we + * need, and retry. If nobody else has initialized the scan in the + * meantime, we'll fill in the value we fetched on the second time + * through. + */ + if (pbscan->phs_startblock == InvalidBlockNumber) + { + if (!pbscan->base.phs_syncscan) + pbscan->phs_startblock = 0; + else if (sync_startpage != InvalidBlockNumber) + pbscan->phs_startblock = sync_startpage; + else + { + SpinLockRelease(&pbscan->phs_mutex); + sync_startpage = ss_get_location(rel, pbscan->phs_nblocks); + goto retry; + } + } + SpinLockRelease(&pbscan->phs_mutex); +} + +/* + * get the next page to scan + * + * Get the next page to scan. Even if there are no pages left to scan, + * another backend could have grabbed a page to scan and not yet finished + * looking at it, so it doesn't follow that the scan is done when the first + * backend gets an InvalidBlockNumber return. + */ +BlockNumber +table_block_parallelscan_nextpage(Relation rel, ParallelBlockTableScanDesc pbscan) +{ + BlockNumber page; + uint64 nallocated; + + /* + * phs_nallocated tracks how many pages have been allocated to workers + * already. When phs_nallocated >= rs_nblocks, all blocks have been + * allocated. + * + * Because we use an atomic fetch-and-add to fetch the current value, the + * phs_nallocated counter will exceed rs_nblocks, because workers will + * still increment the value, when they try to allocate the next block but + * all blocks have been allocated already. The counter must be 64 bits + * wide because of that, to avoid wrapping around when rs_nblocks is close + * to 2^32. + * + * The actual page to return is calculated by adding the counter to the + * starting block number, modulo nblocks. + */ + nallocated = pg_atomic_fetch_add_u64(&pbscan->phs_nallocated, 1); + if (nallocated >= pbscan->phs_nblocks) + page = InvalidBlockNumber; /* all blocks have been allocated */ + else + page = (nallocated + pbscan->phs_startblock) % pbscan->phs_nblocks; + + /* + * Report scan location. Normally, we report the current page number. + * When we reach the end of the scan, though, we report the starting page, + * not the ending page, just so the starting positions for later scans + * doesn't slew backwards. We only report the position at the end of the + * scan once, though: subsequent callers will report nothing. + */ + if (pbscan->base.phs_syncscan) + { + if (page != InvalidBlockNumber) + ss_report_location(rel, page); + else if (nallocated == pbscan->phs_nblocks) + ss_report_location(rel, pbscan->phs_startblock); + } + + return page; +} + +/* ---------------------------------------------------------------------------- + * Helper functions to implement relation sizing for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +/* + * table_block_relation_size + * + * If a table AM uses the various relation forks as the sole place where data + * is stored, and if it uses them in the expected manner (e.g. the actual data + * is in the main fork rather than some other), it can use this implementation + * of the relation_size callback rather than implementing its own. + */ +uint64 +table_block_relation_size(Relation rel, ForkNumber forkNumber) +{ + uint64 nblocks = 0; + + /* Open it at the smgr level if not already done */ + RelationOpenSmgr(rel); + + /* InvalidForkNumber indicates returning the size for all forks */ + if (forkNumber == InvalidForkNumber) + { + for (int i = 0; i < MAX_FORKNUM; i++) + nblocks += smgrnblocks(rel->rd_smgr, i); + } + else + nblocks = smgrnblocks(rel->rd_smgr, forkNumber); + + return nblocks * BLCKSZ; +} + +/* + * table_block_relation_estimate_size + * + * This function can't be directly used as the implementation of the + * relation_estimate_size callback, because it has a few additional parameters. + * Instead, it is intended to be used as a helper function; the caller can + * pass through the arguments to its relation_estimate_size function plus the + * additional values required here. + * + * overhead_bytes_per_tuple should contain the approximate number of bytes + * of storage required to store a tuple above and beyond what is required for + * the tuple data proper. Typically, this would include things like the + * size of the tuple header and item pointer. This is only used for query + * planning, so a table AM where the value is not constant could choose to + * pass a "best guess". + * + * usable_bytes_per_page should contain the approximate number of bytes per + * page usable for tuple data, excluding the page header and any anticipated + * special space. + */ +void +table_block_relation_estimate_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac, + Size overhead_bytes_per_tuple, + Size usable_bytes_per_page) +{ + BlockNumber curpages; + BlockNumber relpages; + double reltuples; + BlockNumber relallvisible; + double density; + + /* it should have storage, so we can call the smgr */ + curpages = RelationGetNumberOfBlocks(rel); + + /* coerce values in pg_class to more desirable types */ + relpages = (BlockNumber) rel->rd_rel->relpages; + reltuples = (double) rel->rd_rel->reltuples; + relallvisible = (BlockNumber) rel->rd_rel->relallvisible; + + /* + * HACK: if the relation has never yet been vacuumed, use a minimum size + * estimate of 10 pages. The idea here is to avoid assuming a + * newly-created table is really small, even if it currently is, because + * that may not be true once some data gets loaded into it. Once a vacuum + * or analyze cycle has been done on it, it's more reasonable to believe + * the size is somewhat stable. + * + * (Note that this is only an issue if the plan gets cached and used again + * after the table has been filled. What we're trying to avoid is using a + * nestloop-type plan on a table that has grown substantially since the + * plan was made. Normally, autovacuum/autoanalyze will occur once enough + * inserts have happened and cause cached-plan invalidation; but that + * doesn't happen instantaneously, and it won't happen at all for cases + * such as temporary tables.) + * + * We approximate "never vacuumed" by "has relpages = 0", which means this + * will also fire on genuinely empty relations. Not great, but + * fortunately that's a seldom-seen case in the real world, and it + * shouldn't degrade the quality of the plan too much anyway to err in + * this direction. + * + * If the table has inheritance children, we don't apply this heuristic. + * Totally empty parent tables are quite common, so we should be willing + * to believe that they are empty. + */ + if (curpages < 10 && + relpages == 0 && + !rel->rd_rel->relhassubclass) + curpages = 10; + + /* report estimated # pages */ + *pages = curpages; + /* quick exit if rel is clearly empty */ + if (curpages == 0) + { + *tuples = 0; + *allvisfrac = 0; + return; + } + + /* estimate number of tuples from previous tuple density */ + if (relpages > 0) + density = reltuples / (double) relpages; + else + { + /* + * When we have no data because the relation was truncated, estimate + * tuple width from attribute datatypes. We assume here that the + * pages are completely full, which is OK for tables (since they've + * presumably not been VACUUMed yet) but is probably an overestimate + * for indexes. Fortunately get_relation_info() can clamp the + * overestimate to the parent table's size. + * + * Note: this code intentionally disregards alignment considerations, + * because (a) that would be gilding the lily considering how crude + * the estimate is, (b) it creates platform dependencies in the + * default plans which are kind of a headache for regression testing, + * and (c) different table AMs might use different padding schemes. + */ + int32 tuple_width; + + tuple_width = get_rel_data_width(rel, attr_widths); + tuple_width += overhead_bytes_per_tuple; + /* note: integer division is intentional here */ + density = usable_bytes_per_page / tuple_width; + } + *tuples = rint(density * (double) curpages); + + /* + * We use relallvisible as-is, rather than scaling it up like we do for + * the pages and tuples counts, on the theory that any pages added since + * the last VACUUM are most likely not marked all-visible. But costsize.c + * wants it converted to a fraction. + */ + if (relallvisible == 0 || curpages <= 0) + *allvisfrac = 0; + else if ((double) relallvisible >= curpages) + *allvisfrac = 1; + else + *allvisfrac = (double) relallvisible / curpages; +} diff --git a/src/backend/access/table/tableamapi.c b/src/backend/access/table/tableamapi.c new file mode 100644 index 00000000000..eff1085a6df --- /dev/null +++ b/src/backend/access/table/tableamapi.c @@ -0,0 +1,158 @@ +/*---------------------------------------------------------------------- + * + * tableamapi.c + * Support routines for API for Postgres table access methods + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/backend/access/table/tableamapi.c + *---------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/heapam.h" +#include "access/htup_details.h" +#include "access/tableam.h" +#include "access/xact.h" +#include "catalog/pg_am.h" +#include "catalog/pg_proc.h" +#include "commands/defrem.h" +#include "miscadmin.h" +#include "utils/fmgroids.h" +#include "utils/memutils.h" +#include "utils/syscache.h" + + +/* + * GetTableAmRoutine + * Call the specified access method handler routine to get its + * TableAmRoutine struct, which will be palloc'd in the caller's + * memory context. + */ +const TableAmRoutine * +GetTableAmRoutine(Oid amhandler) +{ + Datum datum; + const TableAmRoutine *routine; + + datum = OidFunctionCall0(amhandler); + routine = (TableAmRoutine *) DatumGetPointer(datum); + + if (routine == NULL || !IsA(routine, TableAmRoutine)) + elog(ERROR, "table access method handler %u did not return a TableAmRoutine struct", + amhandler); + + /* + * Assert that all required callbacks are present. That makes it a bit + * easier to keep AMs up to date, e.g. when forward porting them to a new + * major version. + */ + Assert(routine->scan_begin != NULL); + Assert(routine->scan_end != NULL); + Assert(routine->scan_rescan != NULL); + Assert(routine->scan_getnextslot != NULL); + + Assert(routine->parallelscan_estimate != NULL); + Assert(routine->parallelscan_initialize != NULL); + Assert(routine->parallelscan_reinitialize != NULL); + + Assert(routine->index_fetch_begin != NULL); + Assert(routine->index_fetch_reset != NULL); + Assert(routine->index_fetch_end != NULL); + Assert(routine->index_fetch_tuple != NULL); + + Assert(routine->tuple_fetch_row_version != NULL); + Assert(routine->tuple_tid_valid != NULL); + Assert(routine->tuple_get_latest_tid != NULL); + Assert(routine->tuple_satisfies_snapshot != NULL); + Assert(routine->compute_xid_horizon_for_tuples != NULL); + + Assert(routine->tuple_insert != NULL); + + /* + * Could be made optional, but would require throwing error during + * parse-analysis. + */ + Assert(routine->tuple_insert_speculative != NULL); + Assert(routine->tuple_complete_speculative != NULL); + + Assert(routine->multi_insert != NULL); + Assert(routine->tuple_delete != NULL); + Assert(routine->tuple_update != NULL); + Assert(routine->tuple_lock != NULL); + + Assert(routine->relation_set_new_filenode != NULL); + Assert(routine->relation_nontransactional_truncate != NULL); + Assert(routine->relation_copy_data != NULL); + Assert(routine->relation_copy_for_cluster != NULL); + Assert(routine->relation_vacuum != NULL); + Assert(routine->scan_analyze_next_block != NULL); + Assert(routine->scan_analyze_next_tuple != NULL); + Assert(routine->index_build_range_scan != NULL); + Assert(routine->index_validate_scan != NULL); + + Assert(routine->relation_size != NULL); + Assert(routine->relation_needs_toast_table != NULL); + + Assert(routine->relation_estimate_size != NULL); + + /* optional, but one callback implies presence of the other */ + Assert((routine->scan_bitmap_next_block == NULL) == + (routine->scan_bitmap_next_tuple == NULL)); + Assert(routine->scan_sample_next_block != NULL); + Assert(routine->scan_sample_next_tuple != NULL); + + return routine; +} + +/* check_hook: validate new default_table_access_method */ +bool +check_default_table_access_method(char **newval, void **extra, GucSource source) +{ + if (**newval == '\0') + { + GUC_check_errdetail("%s cannot be empty.", + "default_table_access_method"); + return false; + } + + if (strlen(*newval) >= NAMEDATALEN) + { + GUC_check_errdetail("%s is too long (maximum %d characters).", + "default_table_access_method", NAMEDATALEN - 1); + return false; + } + + /* + * If we aren't inside a transaction, or not connected to a database, we + * cannot do the catalog access necessary to verify the method. Must + * accept the value on faith. + */ + if (IsTransactionState() && MyDatabaseId != InvalidOid) + { + if (!OidIsValid(get_table_am_oid(*newval, true))) + { + /* + * When source == PGC_S_TEST, don't throw a hard error for a + * nonexistent table access method, only a NOTICE. See comments in + * guc.h. + */ + if (source == PGC_S_TEST) + { + ereport(NOTICE, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("table access method \"%s\" does not exist", + *newval))); + } + else + { + GUC_check_errdetail("Table access method \"%s\" does not exist.", + *newval); + return false; + } + } + } + + return true; +} diff --git a/src/backend/access/table/toast_helper.c b/src/backend/access/table/toast_helper.c new file mode 100644 index 00000000000..7532b4f8659 --- /dev/null +++ b/src/backend/access/table/toast_helper.c @@ -0,0 +1,331 @@ +/*------------------------------------------------------------------------- + * + * toast_helper.c + * Helper functions for table AMs implementing compressed or + * out-of-line storage of varlena attributes. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/access/common/toast_helper.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/detoast.h" +#include "access/table.h" +#include "access/toast_helper.h" +#include "access/toast_internals.h" + +/* + * Prepare to TOAST a tuple. + * + * tupleDesc, toast_values, and toast_isnull are required parameters; they + * provide the necessary details about the tuple to be toasted. + * + * toast_oldvalues and toast_oldisnull should be NULL for a newly-inserted + * tuple; for an update, they should describe the existing tuple. + * + * All of these arrays should have a length equal to tupleDesc->natts. + * + * On return, toast_flags and toast_attr will have been initialized. + * toast_flags is just a single uint8, but toast_attr is an caller-provided + * array with a length equal to tupleDesc->natts. The caller need not + * perform any initialization of the array before calling this function. + */ +void +toast_tuple_init(ToastTupleContext *ttc) +{ + TupleDesc tupleDesc = ttc->ttc_rel->rd_att; + int numAttrs = tupleDesc->natts; + int i; + + ttc->ttc_flags = 0; + + for (i = 0; i < numAttrs; i++) + { + Form_pg_attribute att = TupleDescAttr(tupleDesc, i); + struct varlena *old_value; + struct varlena *new_value; + + ttc->ttc_attr[i].tai_colflags = 0; + ttc->ttc_attr[i].tai_oldexternal = NULL; + + if (ttc->ttc_oldvalues != NULL) + { + /* + * For UPDATE get the old and new values of this attribute + */ + old_value = + (struct varlena *) DatumGetPointer(ttc->ttc_oldvalues[i]); + new_value = + (struct varlena *) DatumGetPointer(ttc->ttc_values[i]); + + /* + * If the old value is stored on disk, check if it has changed so + * we have to delete it later. + */ + if (att->attlen == -1 && !ttc->ttc_oldisnull[i] && + VARATT_IS_EXTERNAL_ONDISK(old_value)) + { + if (ttc->ttc_isnull[i] || + !VARATT_IS_EXTERNAL_ONDISK(new_value) || + memcmp((char *) old_value, (char *) new_value, + VARSIZE_EXTERNAL(old_value)) != 0) + { + /* + * The old external stored value isn't needed any more + * after the update + */ + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_DELETE_OLD; + ttc->ttc_flags |= TOAST_NEEDS_DELETE_OLD; + } + else + { + /* + * This attribute isn't changed by this update so we reuse + * the original reference to the old value in the new + * tuple. + */ + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE; + continue; + } + } + } + else + { + /* + * For INSERT simply get the new value + */ + new_value = (struct varlena *) DatumGetPointer(ttc->ttc_values[i]); + } + + /* + * Handle NULL attributes + */ + if (ttc->ttc_isnull[i]) + { + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE; + ttc->ttc_flags |= TOAST_HAS_NULLS; + continue; + } + + /* + * Now look at varlena attributes + */ + if (att->attlen == -1) + { + /* + * If the table's attribute says PLAIN always, force it so. + */ + if (att->attstorage == 'p') + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE; + + /* + * We took care of UPDATE above, so any external value we find + * still in the tuple must be someone else's that we cannot reuse + * (this includes the case of an out-of-line in-memory datum). + * Fetch it back (without decompression, unless we are forcing + * PLAIN storage). If necessary, we'll push it out as a new + * external value below. + */ + if (VARATT_IS_EXTERNAL(new_value)) + { + ttc->ttc_attr[i].tai_oldexternal = new_value; + if (att->attstorage == 'p') + new_value = heap_tuple_untoast_attr(new_value); + else + new_value = heap_tuple_fetch_attr(new_value); + ttc->ttc_values[i] = PointerGetDatum(new_value); + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_NEEDS_FREE; + ttc->ttc_flags |= (TOAST_NEEDS_CHANGE | TOAST_NEEDS_FREE); + } + + /* + * Remember the size of this attribute + */ + ttc->ttc_attr[i].tai_size = VARSIZE_ANY(new_value); + } + else + { + /* + * Not a varlena attribute, plain storage always + */ + ttc->ttc_attr[i].tai_colflags |= TOASTCOL_IGNORE; + } + } +} + +/* + * Find the largest varlena attribute that satisfies certain criteria. + * + * The relevant column must not be marked TOASTCOL_IGNORE, and if the + * for_compression flag is passed as true, it must also not be marked + * TOASTCOL_INCOMPRESSIBLE. + * + * The column must have attstorage 'e' or 'x' if check_main is false, and + * must have attstorage 'm' if check_main is true. + * + * The column must have a minimum size of MAXALIGN(TOAST_POINTER_SIZE); + * if not, no benefit is to be expected by compressing it. + * + * The return value is the index of the biggest suitable column, or + * -1 if there is none. + */ +int +toast_tuple_find_biggest_attribute(ToastTupleContext *ttc, + bool for_compression, bool check_main) +{ + TupleDesc tupleDesc = ttc->ttc_rel->rd_att; + int numAttrs = tupleDesc->natts; + int biggest_attno = -1; + int32 biggest_size = MAXALIGN(TOAST_POINTER_SIZE); + int32 skip_colflags = TOASTCOL_IGNORE; + int i; + + if (for_compression) + skip_colflags |= TOASTCOL_INCOMPRESSIBLE; + + for (i = 0; i < numAttrs; i++) + { + Form_pg_attribute att = TupleDescAttr(tupleDesc, i); + + if ((ttc->ttc_attr[i].tai_colflags & skip_colflags) != 0) + continue; + if (VARATT_IS_EXTERNAL(DatumGetPointer(ttc->ttc_values[i]))) + continue; /* can't happen, toast_action would be 'p' */ + if (for_compression && + VARATT_IS_COMPRESSED(DatumGetPointer(ttc->ttc_values[i]))) + continue; + if (check_main && att->attstorage != 'm') + continue; + if (!check_main && att->attstorage != 'x' && att->attstorage != 'e') + continue; + + if (ttc->ttc_attr[i].tai_size > biggest_size) + { + biggest_attno = i; + biggest_size = ttc->ttc_attr[i].tai_size; + } + } + + return biggest_attno; +} + +/* + * Try compression for an attribute. + * + * If we find that the attribute is not compressible, mark it so. + */ +void +toast_tuple_try_compression(ToastTupleContext *ttc, int attribute) +{ + Datum *value = &ttc->ttc_values[attribute]; + Datum new_value = toast_compress_datum(*value); + ToastAttrInfo *attr = &ttc->ttc_attr[attribute]; + + if (DatumGetPointer(new_value) != NULL) + { + /* successful compression */ + if ((attr->tai_colflags & TOASTCOL_NEEDS_FREE) != 0) + pfree(DatumGetPointer(*value)); + *value = new_value; + attr->tai_colflags |= TOASTCOL_NEEDS_FREE; + attr->tai_size = VARSIZE(DatumGetPointer(*value)); + ttc->ttc_flags |= (TOAST_NEEDS_CHANGE | TOAST_NEEDS_FREE); + } + else + { + /* incompressible, ignore on subsequent compression passes */ + attr->tai_colflags |= TOASTCOL_INCOMPRESSIBLE; + } +} + +/* + * Move an attribute to external storage. + */ +void +toast_tuple_externalize(ToastTupleContext *ttc, int attribute, int options) +{ + Datum *value = &ttc->ttc_values[attribute]; + Datum old_value = *value; + ToastAttrInfo *attr = &ttc->ttc_attr[attribute]; + + attr->tai_colflags |= TOASTCOL_IGNORE; + *value = toast_save_datum(ttc->ttc_rel, old_value, attr->tai_oldexternal, + options); + if ((attr->tai_colflags & TOASTCOL_NEEDS_FREE) != 0) + pfree(DatumGetPointer(old_value)); + attr->tai_colflags |= TOASTCOL_NEEDS_FREE; + ttc->ttc_flags |= (TOAST_NEEDS_CHANGE | TOAST_NEEDS_FREE); +} + +/* + * Perform appropriate cleanup after one tuple has been subjected to TOAST. + */ +void +toast_tuple_cleanup(ToastTupleContext *ttc) +{ + TupleDesc tupleDesc = ttc->ttc_rel->rd_att; + int numAttrs = tupleDesc->natts; + + /* + * Free allocated temp values + */ + if ((ttc->ttc_flags & TOAST_NEEDS_FREE) != 0) + { + int i; + + for (i = 0; i < numAttrs; i++) + { + ToastAttrInfo *attr = &ttc->ttc_attr[i]; + + if ((attr->tai_colflags & TOASTCOL_NEEDS_FREE) != 0) + pfree(DatumGetPointer(ttc->ttc_values[i])); + } + } + + /* + * Delete external values from the old tuple + */ + if ((ttc->ttc_flags & TOAST_NEEDS_DELETE_OLD) != 0) + { + int i; + + for (i = 0; i < numAttrs; i++) + { + ToastAttrInfo *attr = &ttc->ttc_attr[i]; + + if ((attr->tai_colflags & TOASTCOL_NEEDS_DELETE_OLD) != 0) + toast_delete_datum(ttc->ttc_rel, ttc->ttc_oldvalues[i], false); + } + } +} + +/* + * Check for external stored attributes and delete them from the secondary + * relation. + */ +void +toast_delete_external(Relation rel, Datum *values, bool *isnull, + bool is_speculative) +{ + TupleDesc tupleDesc = rel->rd_att; + int numAttrs = tupleDesc->natts; + int i; + + for (i = 0; i < numAttrs; i++) + { + if (TupleDescAttr(tupleDesc, i)->attlen == -1) + { + Datum value = values[i]; + + if (isnull[i]) + continue; + else if (VARATT_IS_EXTERNAL_ONDISK(PointerGetDatum(value))) + toast_delete_datum(rel, value, is_speculative); + } + } +} diff --git a/src/backend/access/tablesample/bernoulli.c b/src/backend/access/tablesample/bernoulli.c index 1f2a9339351..5ff5bdbd533 100644 --- a/src/backend/access/tablesample/bernoulli.c +++ b/src/backend/access/tablesample/bernoulli.c @@ -13,7 +13,7 @@ * cutoff value computed from the selection probability by BeginSampleScan. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,17 +24,13 @@ #include "postgres.h" -#ifdef _MSC_VER -#include /* for _isnan */ -#endif #include -#include "access/hash.h" #include "access/tsmapi.h" #include "catalog/pg_type.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "utils/builtins.h" +#include "utils/hashutils.h" /* Private state */ @@ -47,19 +43,19 @@ typedef struct static void bernoulli_samplescangetsamplesize(PlannerInfo *root, - RelOptInfo *baserel, - List *paramexprs, - BlockNumber *pages, - double *tuples); + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); static void bernoulli_initsamplescan(SampleScanState *node, - int eflags); + int eflags); static void bernoulli_beginsamplescan(SampleScanState *node, - Datum *params, - int nparams, - uint32 seed); + Datum *params, + int nparams, + uint32 seed); static OffsetNumber bernoulli_nextsampletuple(SampleScanState *node, - BlockNumber blockno, - OffsetNumber maxoffset); + BlockNumber blockno, + OffsetNumber maxoffset); /* diff --git a/src/backend/access/tablesample/system.c b/src/backend/access/tablesample/system.c index f888e04f40c..4693c667b5d 100644 --- a/src/backend/access/tablesample/system.c +++ b/src/backend/access/tablesample/system.c @@ -13,7 +13,7 @@ * cutoff value computed from the selection probability by BeginSampleScan. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,18 +24,14 @@ #include "postgres.h" -#ifdef _MSC_VER -#include /* for _isnan */ -#endif #include -#include "access/hash.h" #include "access/relscan.h" #include "access/tsmapi.h" #include "catalog/pg_type.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "utils/builtins.h" +#include "utils/hashutils.h" /* Private state */ @@ -49,20 +45,20 @@ typedef struct static void system_samplescangetsamplesize(PlannerInfo *root, - RelOptInfo *baserel, - List *paramexprs, - BlockNumber *pages, - double *tuples); + RelOptInfo *baserel, + List *paramexprs, + BlockNumber *pages, + double *tuples); static void system_initsamplescan(SampleScanState *node, - int eflags); + int eflags); static void system_beginsamplescan(SampleScanState *node, - Datum *params, - int nparams, - uint32 seed); -static BlockNumber system_nextsampleblock(SampleScanState *node); + Datum *params, + int nparams, + uint32 seed); +static BlockNumber system_nextsampleblock(SampleScanState *node, BlockNumber nblocks); static OffsetNumber system_nextsampletuple(SampleScanState *node, - BlockNumber blockno, - OffsetNumber maxoffset); + BlockNumber blockno, + OffsetNumber maxoffset); /* @@ -180,10 +176,9 @@ system_beginsamplescan(SampleScanState *node, * Select next block to sample. */ static BlockNumber -system_nextsampleblock(SampleScanState *node) +system_nextsampleblock(SampleScanState *node, BlockNumber nblocks) { SystemSamplerData *sampler = (SystemSamplerData *) node->tsm_state; - HeapScanDesc scan = node->ss.ss_currentScanDesc; BlockNumber nextblock = sampler->nextblock; uint32 hashinput[2]; @@ -202,7 +197,7 @@ system_nextsampleblock(SampleScanState *node) * Loop over block numbers until finding suitable block or reaching end of * relation. */ - for (; nextblock < scan->rs_nblocks; nextblock++) + for (; nextblock < nblocks; nextblock++) { uint32 hash; @@ -214,7 +209,7 @@ system_nextsampleblock(SampleScanState *node) break; } - if (nextblock < scan->rs_nblocks) + if (nextblock < nblocks) { /* Found a suitable block; remember where we should start next time */ sampler->nextblock = nextblock + 1; diff --git a/src/backend/access/tablesample/tablesample.c b/src/backend/access/tablesample/tablesample.c index 6f62581e87b..e5330203b31 100644 --- a/src/backend/access/tablesample/tablesample.c +++ b/src/backend/access/tablesample/tablesample.c @@ -3,7 +3,7 @@ * tablesample.c * Support functions for TABLESAMPLE feature * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/transam/README b/src/backend/access/transam/README index ad4083eb6b5..b5a2cb2de83 100644 --- a/src/backend/access/transam/README +++ b/src/backend/access/transam/README @@ -530,7 +530,7 @@ void XLogResetInsertion(void) construction workspace. This is only needed if you have already called XLogBeginInsert(), but decide to not insert the record after all. -void XLogEnsureRecordSpace(int max_block_id, int nrdatas) +void XLogEnsureRecordSpace(int max_block_id, int ndatas) Normally, the WAL record construction buffers have the following limits: diff --git a/src/backend/access/transam/README.parallel b/src/backend/access/transam/README.parallel index f09a5806345..85e5840feba 100644 --- a/src/backend/access/transam/README.parallel +++ b/src/backend/access/transam/README.parallel @@ -125,6 +125,10 @@ worker. This includes: - State related to pending REINDEX operations, which prevents access to an index that is currently being rebuilt. + - Active relmapper.c mapping state. This is needed to allow consistent + answers when fetching the current relfilenode for relation oids of + mapped relations. + To prevent unprincipled deadlocks when running in parallel mode, this code also arranges for the leader and all workers to participate in group locking. See src/backend/storage/lmgr/README for more details. diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c index 8b7ff5b0c24..595c860aaaf 100644 --- a/src/backend/access/transam/clog.c +++ b/src/backend/access/transam/clog.c @@ -23,7 +23,7 @@ * for aborts (whether sync or async), since the post-crash assumption would * be that such transactions failed anyway. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/clog.c @@ -92,20 +92,20 @@ static int ZeroCLOGPage(int pageno, bool writeXlog); static bool CLOGPagePrecedes(int page1, int page2); static void WriteZeroPageXlogRec(int pageno); static void WriteTruncateXlogRec(int pageno, TransactionId oldestXact, - Oid oldestXidDb); + Oid oldestXactDb); static void TransactionIdSetPageStatus(TransactionId xid, int nsubxids, - TransactionId *subxids, XidStatus status, - XLogRecPtr lsn, int pageno, - bool all_xact_same_page); + TransactionId *subxids, XidStatus status, + XLogRecPtr lsn, int pageno, + bool all_xact_same_page); static void TransactionIdSetStatusBit(TransactionId xid, XidStatus status, - XLogRecPtr lsn, int slotno); + XLogRecPtr lsn, int slotno); static void set_status_by_pages(int nsubxids, TransactionId *subxids, - XidStatus status, XLogRecPtr lsn); + XidStatus status, XLogRecPtr lsn); static bool TransactionGroupUpdateXidStatus(TransactionId xid, - XidStatus status, XLogRecPtr lsn, int pageno); + XidStatus status, XLogRecPtr lsn, int pageno); static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids, - TransactionId *subxids, XidStatus status, - XLogRecPtr lsn, int pageno); + TransactionId *subxids, XidStatus status, + XLogRecPtr lsn, int pageno); /* @@ -155,7 +155,7 @@ static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids, * NB: this is a low-level routine and is NOT the preferred entry point * for most uses; functions in transam.c are the intended callers. * - * XXX Think about issuing FADVISE_WILLNEED on pages that we will need, + * XXX Think about issuing POSIX_FADV_WILLNEED on pages that we will need, * but aren't yet in cache, as well as hinting pages not to fall out of * cache yet. */ @@ -749,12 +749,12 @@ ZeroCLOGPage(int pageno, bool writeXlog) /* * This must be called ONCE during postmaster or standalone-backend startup, - * after StartupXLOG has initialized ShmemVariableCache->nextXid. + * after StartupXLOG has initialized ShmemVariableCache->nextFullXid. */ void StartupCLOG(void) { - TransactionId xid = ShmemVariableCache->nextXid; + TransactionId xid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); int pageno = TransactionIdToPage(xid); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); @@ -773,7 +773,7 @@ StartupCLOG(void) void TrimCLOG(void) { - TransactionId xid = ShmemVariableCache->nextXid; + TransactionId xid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); int pageno = TransactionIdToPage(xid); LWLockAcquire(CLogControlLock, LW_EXCLUSIVE); @@ -792,7 +792,7 @@ TrimCLOG(void) * but makes no WAL entry). Let's just be safe. (We need not worry about * pages beyond the current one, since those will be zeroed when first * used. For the same reason, there is no need to do anything when - * nextXid is exactly at a page boundary; and it's likely that the + * nextFullXid is exactly at a page boundary; and it's likely that the * "current" page doesn't exist yet in that case.) */ if (TransactionIdToPgIndex(xid) != 0) @@ -891,7 +891,7 @@ ExtendCLOG(TransactionId newestXact) * Remove all CLOG segments before the one holding the passed transaction ID * * Before removing any CLOG data, we must flush XLOG to disk, to ensure - * that any recently-emitted HEAP_FREEZE records have reached disk; otherwise + * that any recently-emitted FREEZE_PAGE records have reached disk; otherwise * a crash and restart might leave us with some unfrozen tuples referencing * removed CLOG data. We choose to emit a special TRUNCATE XLOG record too. * Replaying the deletion from XLOG is not critical, since the files could diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c index 04a15e4e29b..3316734e14f 100644 --- a/src/backend/access/transam/commit_ts.c +++ b/src/backend/access/transam/commit_ts.c @@ -15,7 +15,7 @@ * re-perform the status update on redo; so we need make no additional XLOG * entry here. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/commit_ts.c @@ -103,10 +103,10 @@ CommitTimestampShared *commitTsShared; bool track_commit_timestamp; static void SetXidCommitTsInPage(TransactionId xid, int nsubxids, - TransactionId *subxids, TimestampTz ts, - RepOriginId nodeid, int pageno); + TransactionId *subxids, TimestampTz ts, + RepOriginId nodeid, int pageno); static void TransactionIdSetCommitTs(TransactionId xid, TimestampTz ts, - RepOriginId nodeid, int slotno); + RepOriginId nodeid, int slotno); static void error_commit_ts_disabled(void); static int ZeroCommitTsPage(int pageno, bool writeXlog); static bool CommitTsPagePrecedes(int page1, int page2); @@ -115,8 +115,8 @@ static void DeactivateCommitTs(void); static void WriteZeroPageXlogRec(int pageno); static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid); static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids, - TransactionId *subxids, TimestampTz timestamp, - RepOriginId nodeid); + TransactionId *subxids, TimestampTz timestamp, + RepOriginId nodeid); /* * TransactionTreeSetCommitTsData @@ -434,7 +434,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp", @@ -553,7 +553,7 @@ ZeroCommitTsPage(int pageno, bool writeXlog) /* * This must be called ONCE during postmaster or standalone-backend startup, - * after StartupXLOG has initialized ShmemVariableCache->nextXid. + * after StartupXLOG has initialized ShmemVariableCache->nextFullXid. */ void StartupCommitTs(void) @@ -573,10 +573,9 @@ CompleteCommitTsInitialization(void) * any leftover data. * * Conversely, we activate the module if the feature is enabled. This is - * not necessary in a master system because we already did it earlier, but - * if we're in a standby server that got promoted which had the feature - * enabled and was following a master that had the feature disabled, this - * is where we turn it on locally. + * necessary for primary and standby as the activation depends on the + * control file contents at the beginning of recovery or when a + * XLOG_PARAMETER_CHANGE is replayed. */ if (!track_commit_timestamp) DeactivateCommitTs(); @@ -586,7 +585,7 @@ CompleteCommitTsInitialization(void) /* * Activate or deactivate CommitTs' upon reception of a XLOG_PARAMETER_CHANGE - * XLog record in a standby. + * XLog record during recovery. */ void CommitTsParameterChange(bool newvalue, bool oldvalue) @@ -644,7 +643,7 @@ ActivateCommitTs(void) } LWLockRelease(CommitTsLock); - xid = ShmemVariableCache->nextXid; + xid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); pageno = TransactionIdToCTsPage(xid); /* @@ -884,7 +883,8 @@ AdvanceOldestCommitTsXid(TransactionId oldestXact) /* - * Decide which of two CLOG page numbers is "older" for truncation purposes. + * Decide which of two commitTS page numbers is "older" for truncation + * purposes. * * We need to use comparison of TransactionIds here in order to do the right * thing with wraparound XID arithmetic. However, if we are asked about diff --git a/src/backend/access/transam/generic_xlog.c b/src/backend/access/transam/generic_xlog.c index ce023548ae8..d2591601030 100644 --- a/src/backend/access/transam/generic_xlog.c +++ b/src/backend/access/transam/generic_xlog.c @@ -4,7 +4,7 @@ * Implementation of generic xlog records. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/generic_xlog.c @@ -61,22 +61,19 @@ typedef struct /* State of generic xlog record construction */ struct GenericXLogState { - /* - * page's images. Should be first in this struct to have MAXALIGN'ed - * images addresses, because some code working with pages directly aligns - * addresses, not offsets from beginning of page - */ - char images[MAX_GENERIC_XLOG_PAGES * BLCKSZ]; + /* Info about each page, see above */ PageData pages[MAX_GENERIC_XLOG_PAGES]; bool isLogged; + /* Page images (properly aligned) */ + PGAlignedBlock images[MAX_GENERIC_XLOG_PAGES]; }; static void writeFragment(PageData *pageData, OffsetNumber offset, - OffsetNumber len, const char *data); + OffsetNumber len, const char *data); static void computeRegionDelta(PageData *pageData, - const char *curpage, const char *targetpage, - int targetStart, int targetEnd, - int validStart, int validEnd); + const char *curpage, const char *targetpage, + int targetStart, int targetEnd, + int validStart, int validEnd); static void computeDelta(PageData *pageData, Page curpage, Page targetpage); static void applyPageRedo(Page page, const char *delta, Size deltaSize); @@ -251,12 +248,12 @@ computeDelta(PageData *pageData, Page curpage, Page targetpage) #ifdef WAL_DEBUG if (XLOG_DEBUG) { - char tmp[BLCKSZ]; + PGAlignedBlock tmp; - memcpy(tmp, curpage, BLCKSZ); - applyPageRedo(tmp, pageData->delta, pageData->deltaLen); - if (memcmp(tmp, targetpage, targetLower) != 0 || - memcmp(tmp + targetUpper, targetpage + targetUpper, + memcpy(tmp.data, curpage, BLCKSZ); + applyPageRedo(tmp.data, pageData->delta, pageData->deltaLen); + if (memcmp(tmp.data, targetpage, targetLower) != 0 || + memcmp(tmp.data + targetUpper, targetpage + targetUpper, BLCKSZ - targetUpper) != 0) elog(ERROR, "result of generic xlog apply does not match"); } @@ -277,7 +274,7 @@ GenericXLogStart(Relation relation) for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++) { - state->pages[i].image = state->images + BLCKSZ * i; + state->pages[i].image = state->images[i].data; state->pages[i].buffer = InvalidBuffer; } diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index a9a51055e96..7b2448e05ba 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -59,7 +59,7 @@ * counter does not fall within the wraparound horizon considering the global * minimum value. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/multixact.c @@ -282,7 +282,7 @@ typedef struct MultiXactStateData } MultiXactStateData; /* - * Last element of OldestMemberMXactID and OldestVisibleMXactId arrays. + * Last element of OldestMemberMXactId and OldestVisibleMXactId arrays. * Valid elements are (1..MaxOldestSlot); element 0 is never used. */ #define MaxOldestSlot (MaxBackends + max_prepared_xacts) @@ -340,7 +340,7 @@ static MemoryContext MXactContext = NULL; /* internal MultiXactId management */ static void MultiXactIdSetOldestVisible(void); static void RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, - int nmembers, MultiXactMember *members); + int nmembers, MultiXactMember *members); static MultiXactId GetNewMultiXactId(int nmembers, MultiXactOffset *offset); /* MultiXact cache management */ @@ -348,7 +348,7 @@ static int mxactMemberComparator(const void *arg1, const void *arg2); static MultiXactId mXactCacheGetBySet(int nmembers, MultiXactMember *members); static int mXactCacheGetById(MultiXactId multi, MultiXactMember **members); static void mXactCachePut(MultiXactId multi, int nmembers, - MultiXactMember *members); + MultiXactMember *members); static char *mxstatus_to_string(MultiXactStatus status); @@ -358,17 +358,19 @@ static int ZeroMultiXactMemberPage(int pageno, bool writeXlog); static bool MultiXactOffsetPagePrecedes(int page1, int page2); static bool MultiXactMemberPagePrecedes(int page1, int page2); static bool MultiXactOffsetPrecedes(MultiXactOffset offset1, - MultiXactOffset offset2); + MultiXactOffset offset2); static void ExtendMultiXactOffset(MultiXactId multi); static void ExtendMultiXactMember(MultiXactOffset offset, int nmembers); static bool MultiXactOffsetWouldWrap(MultiXactOffset boundary, - MultiXactOffset start, uint32 distance); + MultiXactOffset start, uint32 distance); static bool SetOffsetVacuumLimit(bool is_startup); static bool find_multixact_start(MultiXactId multi, MultiXactOffset *result); static void WriteMZeroPageXlogRec(int pageno, uint8 info); static void WriteMTruncateXlogRec(Oid oldestMultiDB, - MultiXactId startOff, MultiXactId endOff, - MultiXactOffset startMemb, MultiXactOffset endMemb); + MultiXactId startTruncOff, + MultiXactId endTruncOff, + MultiXactOffset startTruncMemb, + MultiXactOffset endTruncMemb); /* @@ -1713,7 +1715,7 @@ PostPrepare_MultiXact(TransactionId xid) myOldestMember = OldestMemberMXactId[MyBackendId]; if (MultiXactIdIsValid(myOldestMember)) { - BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid); + BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, false); /* * Even though storing MultiXactId is atomic, acquire lock to make @@ -1755,7 +1757,7 @@ void multixact_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len) { - BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid); + BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, false); MultiXactId oldestMember; /* @@ -1776,7 +1778,7 @@ void multixact_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len) { - BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid); + BackendId dummyBackendId = TwoPhaseGetDummyBackendId(xid, true); Assert(len == sizeof(MultiXactId)); @@ -2208,7 +2210,7 @@ SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, * space, but that's not really true, because multixacts wrap differently * from transaction IDs. Note that, separately from any concern about * multixact IDs wrapping, we must ensure that multixact members do not - * wrap. Limits for that are set in DetermineSafeOldestOffset, not here. + * wrap. Limits for that are set in SetOffsetVacuumLimit, not here. */ multiWrapLimit = oldest_datminmxid + (MaxMultiXactId >> 1); if (multiWrapLimit < FirstMultiXactId) @@ -2555,7 +2557,7 @@ SetOffsetVacuumLimit(bool is_startup) /* * NB: Have to prevent concurrent truncation, we might otherwise try to - * lookup a oldestMulti that's concurrently getting truncated away. + * lookup an oldestMulti that's concurrently getting truncated away. */ LWLockAcquire(MultiXactTruncationLock, LW_SHARED); @@ -2732,7 +2734,7 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result) /* * Flush out dirty data, so PhysicalPageExists can work correctly. * SimpleLruFlush() is a pretty big hammer for that. Alternatively we - * could add a in-memory version of page exists, but find_multixact_start + * could add an in-memory version of page exists, but find_multixact_start * is called infrequently, and it doesn't seem bad to flush buffers to * disk before truncation. */ @@ -2784,7 +2786,7 @@ ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members) /* * Multixact members can be removed once the multixacts that refer to them - * are older than every datminxmid. autovacuum_multixact_freeze_max_age and + * are older than every datminmxid. autovacuum_multixact_freeze_max_age and * vacuum_multixact_freeze_table_age work together to make sure we never have * too many multixacts; we hope that, at least under normal circumstances, * this will also be sufficient to keep us from using too many offsets. @@ -3267,9 +3269,9 @@ multixact_redo(XLogReaderState *record) xlrec->moff + xlrec->nmembers); /* - * Make sure nextXid is beyond any XID mentioned in the record. This - * should be unnecessary, since any XID found here ought to have other - * evidence in the XLOG, but let's be safe. + * Make sure nextFullXid is beyond any XID mentioned in the record. + * This should be unnecessary, since any XID found here ought to have + * other evidence in the XLOG, but let's be safe. */ max_xid = XLogRecGetXid(record); for (i = 0; i < xlrec->nmembers; i++) @@ -3278,19 +3280,7 @@ multixact_redo(XLogReaderState *record) max_xid = xlrec->members[i].xid; } - /* - * We don't expect anyone else to modify nextXid, hence startup - * process doesn't need to hold a lock while checking this. We still - * acquire the lock to modify it, though. - */ - if (TransactionIdFollowsOrEquals(max_xid, - ShmemVariableCache->nextXid)) - { - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = max_xid; - TransactionIdAdvance(ShmemVariableCache->nextXid); - LWLockRelease(XidGenLock); - } + AdvanceNextFullTransactionIdPastXid(max_xid); } else if (info == XLOG_MULTIXACT_TRUNCATE_ID) { @@ -3368,7 +3358,7 @@ pg_get_multixact_members(PG_FUNCTION_ARGS) false); multi->iter = 0; - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "mode", diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index 1d631b72755..55d129a64f7 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -3,7 +3,7 @@ * parallel.c * Infrastructure for launching parallel workers * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,6 +19,7 @@ #include "access/session.h" #include "access/xact.h" #include "access/xlog.h" +#include "catalog/pg_enum.h" #include "catalog/index.h" #include "catalog/namespace.h" #include "commands/async.h" @@ -27,9 +28,10 @@ #include "libpq/pqformat.h" #include "libpq/pqmq.h" #include "miscadmin.h" -#include "optimizer/planmain.h" +#include "optimizer/optimizer.h" #include "pgstat.h" #include "storage/ipc.h" +#include "storage/predicate.h" #include "storage/sinval.h" #include "storage/spin.h" #include "tcop/tcopprot.h" @@ -37,7 +39,7 @@ #include "utils/guc.h" #include "utils/inval.h" #include "utils/memutils.h" -#include "utils/resowner.h" +#include "utils/relmapper.h" #include "utils/snapmgr.h" #include "utils/typcache.h" @@ -70,6 +72,8 @@ #define PARALLEL_KEY_ENTRYPOINT UINT64CONST(0xFFFFFFFFFFFF0009) #define PARALLEL_KEY_SESSION_DSM UINT64CONST(0xFFFFFFFFFFFF000A) #define PARALLEL_KEY_REINDEX_STATE UINT64CONST(0xFFFFFFFFFFFF000B) +#define PARALLEL_KEY_RELMAPPER_STATE UINT64CONST(0xFFFFFFFFFFFF000C) +#define PARALLEL_KEY_ENUMBLACKLIST UINT64CONST(0xFFFFFFFFFFFF000D) /* Fixed-size parallel state. */ typedef struct FixedParallelState @@ -86,6 +90,9 @@ typedef struct FixedParallelState PGPROC *parallel_master_pgproc; pid_t parallel_master_pid; BackendId parallel_master_backend_id; + TimestampTz xact_ts; + TimestampTz stmt_ts; + SerializableXactHandle serializable_xact_handle; /* Mutex protects remaining fields. */ slock_t mutex; @@ -150,7 +157,7 @@ static void ParallelWorkerShutdown(int code, Datum arg); */ ParallelContext * CreateParallelContext(const char *library_name, const char *function_name, - int nworkers, bool serializable_okay) + int nworkers) { MemoryContext oldcontext; ParallelContext *pcxt; @@ -161,23 +168,6 @@ CreateParallelContext(const char *library_name, const char *function_name, /* Number of workers should be non-negative. */ Assert(nworkers >= 0); - /* - * If dynamic shared memory is not available, we won't be able to use - * background workers. - */ - if (dynamic_shared_memory_type == DSM_IMPL_NONE) - nworkers = 0; - - /* - * If we are running under serializable isolation, we can't use parallel - * workers, at least not until somebody enhances that mechanism to be - * parallel-aware. Utility statement callers may ask us to ignore this - * restriction because they're always able to safely ignore the fact that - * SIREAD locks do not work with parallelism. - */ - if (IsolationIsSerializable() && !serializable_okay) - nworkers = 0; - /* We might be running in a short-lived memory context. */ oldcontext = MemoryContextSwitchTo(TopTransactionContext); @@ -213,6 +203,8 @@ InitializeParallelDSM(ParallelContext *pcxt) Size asnaplen = 0; Size tstatelen = 0; Size reindexlen = 0; + Size relmapperlen = 0; + Size enumblacklistlen = 0; Size segsize = 0; int i; FixedParallelState *fps; @@ -264,8 +256,12 @@ InitializeParallelDSM(ParallelContext *pcxt) shm_toc_estimate_chunk(&pcxt->estimator, sizeof(dsm_handle)); reindexlen = EstimateReindexStateSpace(); shm_toc_estimate_chunk(&pcxt->estimator, reindexlen); + relmapperlen = EstimateRelationMapSpace(); + shm_toc_estimate_chunk(&pcxt->estimator, relmapperlen); + enumblacklistlen = EstimateEnumBlacklistSpace(); + shm_toc_estimate_chunk(&pcxt->estimator, enumblacklistlen); /* If you add more chunks here, you probably need to add keys. */ - shm_toc_estimate_keys(&pcxt->estimator, 8); + shm_toc_estimate_keys(&pcxt->estimator, 10); /* Estimate space need for error queues. */ StaticAssertStmt(BUFFERALIGN(PARALLEL_ERROR_QUEUE_SIZE) == @@ -321,6 +317,9 @@ InitializeParallelDSM(ParallelContext *pcxt) fps->parallel_master_pgproc = MyProc; fps->parallel_master_pid = MyProcPid; fps->parallel_master_backend_id = MyBackendId; + fps->xact_ts = GetCurrentTransactionStartTimestamp(); + fps->stmt_ts = GetCurrentStatementStartTimestamp(); + fps->serializable_xact_handle = ShareSerializableXact(); SpinLockInit(&fps->mutex); fps->last_xlog_end = 0; shm_toc_insert(pcxt->toc, PARALLEL_KEY_FIXED, fps); @@ -335,9 +334,11 @@ InitializeParallelDSM(ParallelContext *pcxt) char *asnapspace; char *tstatespace; char *reindexspace; + char *relmapperspace; char *error_queue_space; char *session_dsm_handle_space; char *entrypointstate; + char *enumblacklistspace; Size lnamelen; /* Serialize shared libraries we have loaded. */ @@ -381,6 +382,18 @@ InitializeParallelDSM(ParallelContext *pcxt) SerializeReindexState(reindexlen, reindexspace); shm_toc_insert(pcxt->toc, PARALLEL_KEY_REINDEX_STATE, reindexspace); + /* Serialize relmapper state. */ + relmapperspace = shm_toc_allocate(pcxt->toc, relmapperlen); + SerializeRelationMap(relmapperlen, relmapperspace); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_RELMAPPER_STATE, + relmapperspace); + + /* Serialize enum blacklist state. */ + enumblacklistspace = shm_toc_allocate(pcxt->toc, enumblacklistlen); + SerializeEnumBlacklist(enumblacklistspace, enumblacklistlen); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_ENUMBLACKLIST, + enumblacklistspace); + /* Allocate space for worker information. */ pcxt->worker = palloc0(sizeof(ParallelWorkerInfo) * pcxt->nworkers); @@ -672,13 +685,9 @@ WaitForParallelWorkersToAttach(ParallelContext *pcxt) * just end up waiting for the same worker again. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, -1, WAIT_EVENT_BGWORKER_STARTUP); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) ResetLatch(MyLatch); } @@ -795,8 +804,8 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt) } } - WaitLatch(MyLatch, WL_LATCH_SET, -1, - WAIT_EVENT_PARALLEL_FINISH); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, -1, + WAIT_EVENT_PARALLEL_FINISH); ResetLatch(MyLatch); } @@ -1213,6 +1222,8 @@ ParallelWorkerMain(Datum main_arg) char *asnapspace; char *tstatespace; char *reindexspace; + char *relmapperspace; + char *enumblacklistspace; StringInfoData msgbuf; char *session_dsm_handle_space; @@ -1227,16 +1238,19 @@ ParallelWorkerMain(Datum main_arg) Assert(ParallelWorkerNumber == -1); memcpy(&ParallelWorkerNumber, MyBgworkerEntry->bgw_extra, sizeof(int)); - /* Set up a memory context and resource owner. */ - Assert(CurrentResourceOwner == NULL); - CurrentResourceOwner = ResourceOwnerCreate(NULL, "parallel toplevel"); + /* Set up a memory context to work in, just for cleanliness. */ CurrentMemoryContext = AllocSetContextCreate(TopMemoryContext, "Parallel worker", ALLOCSET_DEFAULT_SIZES); /* - * Now that we have a resource owner, we can attach to the dynamic shared - * memory segment and read the table of contents. + * Attach to the dynamic shared memory segment for the parallel query, and + * find its table of contents. + * + * Note: at this point, we have not created any ResourceOwner in this + * process. This will result in our DSM mapping surviving until process + * exit, which is fine. If there were a ResourceOwner, it would acquire + * ownership of the mapping, but we have no need for that. */ seg = dsm_attach(DatumGetUInt32(main_arg)); if (seg == NULL) @@ -1304,12 +1318,11 @@ ParallelWorkerMain(Datum main_arg) return; /* - * Load libraries that were loaded by original backend. We want to do - * this before restoring GUCs, because the libraries might define custom - * variables. + * Restore transaction and statement start-time timestamps. This must + * happen before anything that would start a transaction, else asserts in + * xact.c will fire. */ - libraryspace = shm_toc_lookup(toc, PARALLEL_KEY_LIBRARY, false); - RestoreLibraryState(libraryspace); + SetParallelStartTimestamps(fps->xact_ts, fps->stmt_ts); /* * Identify the entry point to be called. In theory this could result in @@ -1333,9 +1346,17 @@ ParallelWorkerMain(Datum main_arg) */ SetClientEncoding(GetDatabaseEncoding()); + /* + * Load libraries that were loaded by original backend. We want to do + * this before restoring GUCs, because the libraries might define custom + * variables. + */ + libraryspace = shm_toc_lookup(toc, PARALLEL_KEY_LIBRARY, false); + StartTransactionCommand(); + RestoreLibraryState(libraryspace); + /* Restore GUC values from launching backend. */ gucspace = shm_toc_lookup(toc, PARALLEL_KEY_GUC, false); - StartTransactionCommand(); RestoreGUCState(gucspace); CommitTransactionCommand(); @@ -1385,6 +1406,18 @@ ParallelWorkerMain(Datum main_arg) reindexspace = shm_toc_lookup(toc, PARALLEL_KEY_REINDEX_STATE, false); RestoreReindexState(reindexspace); + /* Restore relmapper state. */ + relmapperspace = shm_toc_lookup(toc, PARALLEL_KEY_RELMAPPER_STATE, false); + RestoreRelationMap(relmapperspace); + + /* Restore enum blacklist. */ + enumblacklistspace = shm_toc_lookup(toc, PARALLEL_KEY_ENUMBLACKLIST, + false); + RestoreEnumBlacklist(enumblacklistspace); + + /* Attach to the leader's serializable transaction, if SERIALIZABLE. */ + AttachSerializableXact(fps->serializable_xact_handle); + /* * We've initialized all of our state now; nothing should change * hereafter. @@ -1400,7 +1433,7 @@ ParallelWorkerMain(Datum main_arg) /* Must exit parallel mode to pop active snapshot. */ ExitParallelMode(); - /* Must pop active snapshot so resowner.c doesn't complain. */ + /* Must pop active snapshot so snapmgr.c doesn't complain. */ PopActiveSnapshot(); /* Shut down the parallel-worker transaction. */ diff --git a/src/backend/access/transam/recovery.conf.sample b/src/backend/access/transam/recovery.conf.sample deleted file mode 100644 index 8e466126428..00000000000 --- a/src/backend/access/transam/recovery.conf.sample +++ /dev/null @@ -1,158 +0,0 @@ -# ------------------------------- -# PostgreSQL recovery config file -# ------------------------------- -# -# Edit this file to provide the parameters that PostgreSQL needs to -# perform an archive recovery of a database, or to act as a replication -# standby. -# -# If "recovery.conf" is present in the PostgreSQL data directory, it is -# read on postmaster startup. After successful recovery, it is renamed -# to "recovery.done" to ensure that we do not accidentally re-enter -# archive recovery or standby mode. -# -# This file consists of lines of the form: -# -# name = value -# -# Comments are introduced with '#'. -# -# The complete list of option names and allowed values can be found -# in the PostgreSQL documentation. -# -#--------------------------------------------------------------------------- -# ARCHIVE RECOVERY PARAMETERS -#--------------------------------------------------------------------------- -# -# restore_command -# -# specifies the shell command that is executed to copy log files -# back from archival storage. The command string may contain %f, -# which is replaced by the name of the desired log file, and %p, -# which is replaced by the absolute path to copy the log file to. -# -# This parameter is *required* for an archive recovery, but optional -# for streaming replication. -# -# It is important that the command return nonzero exit status on failure. -# The command *will* be asked for log files that are not present in the -# archive; it must return nonzero when so asked. -# -# NOTE that the basename of %p will be different from %f; do not -# expect them to be interchangeable. -# -#restore_command = '' # e.g. 'cp /mnt/server/archivedir/%f %p' -# -# -# archive_cleanup_command -# -# specifies an optional shell command to execute at every restartpoint. -# This can be useful for cleaning up the archive of a standby server. -# -#archive_cleanup_command = '' -# -# recovery_end_command -# -# specifies an optional shell command to execute at completion of recovery. -# This can be useful for cleaning up after the restore_command. -# -#recovery_end_command = '' -# -#--------------------------------------------------------------------------- -# RECOVERY TARGET PARAMETERS -#--------------------------------------------------------------------------- -# -# By default, recovery will rollforward to the end of the WAL log. -# If you want to stop rollforward at a specific point, you -# must set a recovery target. -# -# You may set a recovery target either by transactionId, by name, by -# timestamp or by WAL location (LSN). Recovery may either include or -# exclude the transaction(s) with the recovery target value (i.e., -# stop either just after or just before the given target, -# respectively). -# -# -#recovery_target_name = '' # e.g. 'daily backup 2011-01-26' -# -#recovery_target_time = '' # e.g. '2004-07-14 22:39:00 EST' -# -#recovery_target_xid = '' -# -#recovery_target_lsn = '' # e.g. '0/70006B8' -# -#recovery_target_inclusive = true -# -# -# Alternatively, you can request stopping as soon as a consistent state -# is reached, by uncommenting this option. -# -#recovery_target = 'immediate' -# -# -# If you want to recover into a timeline other than the "main line" shown in -# pg_control, specify the timeline number here, or write 'latest' to get -# the latest branch for which there's a history file. -# -#recovery_target_timeline = 'latest' -# -# -# If recovery_target_action = 'pause', recovery will pause when the -# recovery target is reached. The pause state will continue until -# pg_wal_replay_resume() is called. This setting has no effect if -# no recovery target is set. If hot_standby is not enabled then the -# server will shutdown instead, though you may request this in -# any case by specifying 'shutdown'. -# -#recovery_target_action = 'pause' -# -#--------------------------------------------------------------------------- -# STANDBY SERVER PARAMETERS -#--------------------------------------------------------------------------- -# -# standby_mode -# -# When standby_mode is enabled, the PostgreSQL server will work as a -# standby. It will continuously wait for the additional XLOG records, using -# restore_command and/or primary_conninfo. -# -#standby_mode = off -# -# primary_conninfo -# -# If set, the PostgreSQL server will try to connect to the primary using this -# connection string and receive XLOG records continuously. -# -#primary_conninfo = '' # e.g. 'host=localhost port=5432' -# -# If set, the PostgreSQL server will use the specified replication slot when -# connecting to the primary via streaming replication to control resource -# removal on the upstream node. This setting has no effect if primary_conninfo -# is not set. -# -#primary_slot_name = '' -# -# By default, a standby server keeps restoring XLOG records from the -# primary indefinitely. If you want to stop the standby mode, finish recovery -# and open the system in read/write mode, specify a path to a trigger file. -# The server will poll the trigger file path periodically and start as a -# primary server when it's found. -# -#trigger_file = '' -# -# By default, a standby server restores XLOG records from the primary as -# soon as possible. If you want to explicitly delay the replay of committed -# transactions from the master, specify a minimum apply delay. For example, -# if you set this parameter to 5min, the standby will replay each transaction -# commit only when the system time on the standby is at least five minutes -# past the commit time reported by the master. -# -#recovery_min_apply_delay = 0 -# -#--------------------------------------------------------------------------- -# HOT STANDBY PARAMETERS -#--------------------------------------------------------------------------- -# -# Hot Standby related parameters are listed in postgresql.conf -# -#--------------------------------------------------------------------------- diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c index 87942b4ccab..e38f9199ddb 100644 --- a/src/backend/access/transam/slru.c +++ b/src/backend/access/transam/slru.c @@ -38,7 +38,7 @@ * by re-setting the page's page_dirty flag. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/slru.c @@ -129,12 +129,12 @@ static void SimpleLruWaitIO(SlruCtl ctl, int slotno); static void SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata); static bool SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno); static bool SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, - SlruFlush fdata); + SlruFlush fdata); static void SlruReportIOError(SlruCtl ctl, int pageno, TransactionId xid); static int SlruSelectLRUPage(SlruCtl ctl, int pageno); static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, - int segpage, void *data); + int segpage, void *data); static void SlruInternalDeleteSegment(SlruCtl ctl, char *filename); /* @@ -599,7 +599,7 @@ SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno) SlruFileName(ctl, path, segno); - fd = OpenTransientFile(path, O_RDWR | PG_BINARY); + fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); if (fd < 0) { /* expected: file doesn't exist */ @@ -614,14 +614,20 @@ SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno) if ((endpos = lseek(fd, 0, SEEK_END)) < 0) { - slru_errcause = SLRU_OPEN_FAILED; + slru_errcause = SLRU_SEEK_FAILED; slru_errno = errno; SlruReportIOError(ctl, pageno, 0); } result = endpos >= (off_t) (offset + BLCKSZ); - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + { + slru_errcause = SLRU_CLOSE_FAILED; + slru_errno = errno; + return false; + } + return result; } @@ -654,7 +660,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno) * SlruPhysicalWritePage). Hence, if we are InRecovery, allow the case * where the file doesn't exist, and return zeroes instead. */ - fd = OpenTransientFile(path, O_RDWR | PG_BINARY); + fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); if (fd < 0) { if (errno != ENOENT || !InRecovery) @@ -691,7 +697,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int pageno, int slotno) } pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) { slru_errcause = SLRU_CLOSE_FAILED; slru_errno = errno; @@ -863,7 +869,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) if (!fdata) { pgstat_report_wait_start(WAIT_EVENT_SLRU_SYNC); - if (ctl->do_fsync && pg_fsync(fd)) + if (ctl->do_fsync && pg_fsync(fd) != 0) { pgstat_report_wait_end(); slru_errcause = SLRU_FSYNC_FAILED; @@ -873,7 +879,7 @@ SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno, SlruFlush fdata) } pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) { slru_errcause = SLRU_CLOSE_FAILED; slru_errno = errno; @@ -914,21 +920,32 @@ SlruReportIOError(SlruCtl ctl, int pageno, TransactionId xid) path, offset))); break; case SLRU_READ_FAILED: - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not access status of transaction %u", xid), - errdetail("Could not read from file \"%s\" at offset %u: %m.", - path, offset))); + if (errno) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not access status of transaction %u", xid), + errdetail("Could not read from file \"%s\" at offset %u: %m.", + path, offset))); + else + ereport(ERROR, + (errmsg("could not access status of transaction %u", xid), + errdetail("Could not read from file \"%s\" at offset %u: read too few bytes.", path, offset))); break; case SLRU_WRITE_FAILED: - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not access status of transaction %u", xid), - errdetail("Could not write to file \"%s\" at offset %u: %m.", - path, offset))); + if (errno) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not access status of transaction %u", xid), + errdetail("Could not write to file \"%s\" at offset %u: %m.", + path, offset))); + else + ereport(ERROR, + (errmsg("could not access status of transaction %u", xid), + errdetail("Could not write to file \"%s\" at offset %u: wrote too few bytes.", + path, offset))); break; case SLRU_FSYNC_FAILED: - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not access status of transaction %u", xid), errdetail("Could not fsync file \"%s\": %m.", @@ -1140,7 +1157,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied) for (i = 0; i < fdata.num_files; i++) { pgstat_report_wait_start(WAIT_EVENT_SLRU_FLUSH_SYNC); - if (ctl->do_fsync && pg_fsync(fdata.fd[i])) + if (ctl->do_fsync && pg_fsync(fdata.fd[i]) != 0) { slru_errcause = SLRU_FSYNC_FAILED; slru_errno = errno; @@ -1149,7 +1166,7 @@ SimpleLruFlush(SlruCtl ctl, bool allow_redirtied) } pgstat_report_wait_end(); - if (CloseTransientFile(fdata.fd[i])) + if (CloseTransientFile(fdata.fd[i]) != 0) { slru_errcause = SLRU_CLOSE_FAILED; slru_errno = errno; @@ -1358,7 +1375,7 @@ SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data) } /* - * Scan the SimpleLRU directory and apply a callback to each file found in it. + * Scan the SimpleLru directory and apply a callback to each file found in it. * * If the callback returns true, the scan is stopped. The last return value * from the callback is returned. diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c index 4faa21f5aef..e667fd02385 100644 --- a/src/backend/access/transam/subtrans.c +++ b/src/backend/access/transam/subtrans.c @@ -19,7 +19,7 @@ * data across crashes. During database startup, we simply force the * currently-active page of SUBTRANS to zeroes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/subtrans.c @@ -241,14 +241,15 @@ ZeroSUBTRANSPage(int pageno) /* * This must be called ONCE during postmaster or standalone-backend startup, - * after StartupXLOG has initialized ShmemVariableCache->nextXid. + * after StartupXLOG has initialized ShmemVariableCache->nextFullXid. * - * oldestActiveXID is the oldest XID of any prepared transaction, or nextXid + * oldestActiveXID is the oldest XID of any prepared transaction, or nextFullXid * if there are none. */ void StartupSUBTRANS(TransactionId oldestActiveXID) { + FullTransactionId nextFullXid; int startPage; int endPage; @@ -261,7 +262,8 @@ StartupSUBTRANS(TransactionId oldestActiveXID) LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE); startPage = TransactionIdToPage(oldestActiveXID); - endPage = TransactionIdToPage(ShmemVariableCache->nextXid); + nextFullXid = ShmemVariableCache->nextFullXid; + endPage = TransactionIdToPage(XidFromFullTransactionId(nextFullXid)); while (startPage != endPage) { diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c index 61d36050c34..c2ba480c703 100644 --- a/src/backend/access/transam/timeline.c +++ b/src/backend/access/transam/timeline.c @@ -21,7 +21,7 @@ * The fields are separated by tabs. Lines beginning with # are comments, and * are ignored. Empty lines are also ignored. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/timeline.c @@ -370,7 +370,11 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, } pgstat_report_wait_end(); } - CloseTransientFile(srcfd); + + if (CloseTransientFile(srcfd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); } /* @@ -406,17 +410,16 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", tmppath))); pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", tmppath))); - /* * Now move the completed history file into place with its final name. */ @@ -485,17 +488,16 @@ writeTimeLineHistoryFile(TimeLineID tli, char *content, int size) pgstat_report_wait_start(WAIT_EVENT_TIMELINE_HISTORY_FILE_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", tmppath))); pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", tmppath))); - /* * Now move the completed history file into place with its final name. */ diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index 52a624c90bb..365ddfb428f 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -3,7 +3,7 @@ * transam.c * postgres transaction (commit) log interface routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -228,8 +228,8 @@ TransactionIdDidAbort(TransactionId transactionId) * (and so it's not named TransactionIdDidComplete, which would be the * appropriate name for a function that worked that way). The intended * use is just to short-circuit TransactionIdIsInProgress calls when doing - * repeated tqual.c checks for the same XID. If this isn't extremely fast - * then it will be counterproductive. + * repeated heapam_visibility.c checks for the same XID. If this isn't + * extremely fast then it will be counterproductive. * * Note: * Assumes transaction identifier is valid. diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index d6e4b7980f3..546bd43ce8b 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -3,7 +3,7 @@ * twophase.c * Two-phase commit support functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -98,6 +98,7 @@ #include "replication/walsender.h" #include "storage/fd.h" #include "storage/ipc.h" +#include "storage/md.h" #include "storage/predicate.h" #include "storage/proc.h" #include "storage/procarray.h" @@ -201,31 +202,31 @@ static GlobalTransaction MyLockedGxact = NULL; static bool twophaseExitRegistered = false; static void RecordTransactionCommitPrepared(TransactionId xid, - int nchildren, - TransactionId *children, - int nrels, - RelFileNode *rels, - int ninvalmsgs, - SharedInvalidationMessage *invalmsgs, - bool initfileinval, - const char *gid); + int nchildren, + TransactionId *children, + int nrels, + RelFileNode *rels, + int ninvalmsgs, + SharedInvalidationMessage *invalmsgs, + bool initfileinval, + const char *gid); static void RecordTransactionAbortPrepared(TransactionId xid, - int nchildren, - TransactionId *children, - int nrels, - RelFileNode *rels, - const char *gid); + int nchildren, + TransactionId *children, + int nrels, + RelFileNode *rels, + const char *gid); static void ProcessRecords(char *bufptr, TransactionId xid, - const TwoPhaseCallback callbacks[]); + const TwoPhaseCallback callbacks[]); static void RemoveGXact(GlobalTransaction gxact); static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len); static char *ProcessTwoPhaseBuffer(TransactionId xid, - XLogRecPtr prepare_start_lsn, - bool fromdisk, bool setParent, bool setNextXid); + XLogRecPtr prepare_start_lsn, + bool fromdisk, bool setParent, bool setNextXid); static void MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, - const char *gid, TimestampTz prepared_at, Oid owner, - Oid databaseid); + const char *gid, TimestampTz prepared_at, Oid owner, + Oid databaseid); static void RemoveTwoPhaseFile(TransactionId xid, bool giveWarning); static void RecreateTwoPhaseFile(TransactionId xid, void *content, int len); @@ -471,6 +472,7 @@ MarkAsPreparingGuts(GlobalTransaction gxact, TransactionId xid, const char *gid, proc->backendId = InvalidBackendId; proc->databaseId = databaseid; proc->roleId = owner; + proc->tempNamespaceId = InvalidOid; proc->isBackgroundWorker = false; proc->lwWaiting = false; proc->lwWaitMode = 0; @@ -733,7 +735,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS) /* build tupdesc for result tuples */ /* this had better match pg_prepared_xacts view in system_views.sql */ - tupdesc = CreateTemplateTupleDesc(5, false); + tupdesc = CreateTemplateTupleDesc(5); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "transaction", XIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "gid", @@ -800,9 +802,12 @@ pg_prepared_xact(PG_FUNCTION_ARGS) * TwoPhaseGetGXact * Get the GlobalTransaction struct for a prepared transaction * specified by XID + * + * If lock_held is set to true, TwoPhaseStateLock will not be taken, so the + * caller had better hold it. */ static GlobalTransaction -TwoPhaseGetGXact(TransactionId xid) +TwoPhaseGetGXact(TransactionId xid, bool lock_held) { GlobalTransaction result = NULL; int i; @@ -810,6 +815,8 @@ TwoPhaseGetGXact(TransactionId xid) static TransactionId cached_xid = InvalidTransactionId; static GlobalTransaction cached_gxact = NULL; + Assert(!lock_held || LWLockHeldByMe(TwoPhaseStateLock)); + /* * During a recovery, COMMIT PREPARED, or ABORT PREPARED, we'll be called * repeatedly for the same XID. We can save work with a simple cache. @@ -817,7 +824,8 @@ TwoPhaseGetGXact(TransactionId xid) if (xid == cached_xid) return cached_gxact; - LWLockAcquire(TwoPhaseStateLock, LW_SHARED); + if (!lock_held) + LWLockAcquire(TwoPhaseStateLock, LW_SHARED); for (i = 0; i < TwoPhaseState->numPrepXacts; i++) { @@ -831,7 +839,8 @@ TwoPhaseGetGXact(TransactionId xid) } } - LWLockRelease(TwoPhaseStateLock); + if (!lock_held) + LWLockRelease(TwoPhaseStateLock); if (result == NULL) /* should not happen */ elog(ERROR, "failed to find GlobalTransaction for xid %u", xid); @@ -843,17 +852,18 @@ TwoPhaseGetGXact(TransactionId xid) } /* - * TwoPhaseGetDummyProc + * TwoPhaseGetDummyBackendId * Get the dummy backend ID for prepared transaction specified by XID * * Dummy backend IDs are similar to real backend IDs of real backends. * They start at MaxBackends + 1, and are unique across all currently active - * real backends and prepared transactions. + * real backends and prepared transactions. If lock_held is set to true, + * TwoPhaseStateLock will not be taken, so the caller had better hold it. */ BackendId -TwoPhaseGetDummyBackendId(TransactionId xid) +TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held) { - GlobalTransaction gxact = TwoPhaseGetGXact(xid); + GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held); return gxact->dummyBackendId; } @@ -861,11 +871,14 @@ TwoPhaseGetDummyBackendId(TransactionId xid) /* * TwoPhaseGetDummyProc * Get the PGPROC that represents a prepared transaction specified by XID + * + * If lock_held is set to true, TwoPhaseStateLock will not be taken, so the + * caller had better hold it. */ PGPROC * -TwoPhaseGetDummyProc(TransactionId xid) +TwoPhaseGetDummyProc(TransactionId xid, bool lock_held) { - GlobalTransaction gxact = TwoPhaseGetGXact(xid); + GlobalTransaction gxact = TwoPhaseGetGXact(xid, lock_held); return &ProcGlobal->allProcs[gxact->pgprocno]; } @@ -913,7 +926,7 @@ typedef struct TwoPhaseFileHeader bool initfileinval; /* does relcache init file need invalidation? */ uint16 gidlen; /* length of the GID - GID follows the header */ XLogRecPtr origin_lsn; /* lsn of this record at origin node */ - TimestampTz origin_timestamp; /* time of prepare at origin node */ + TimestampTz origin_timestamp; /* time of prepare at origin node */ } TwoPhaseFileHeader; /* @@ -1065,7 +1078,7 @@ EndPrepare(GlobalTransaction gxact) { TwoPhaseFileHeader *hdr; StateFileChunk *record; - bool replorigin; + bool replorigin; /* Add the end sentinel to the list of 2PC records */ RegisterTwoPhaseRecord(TWOPHASE_RM_END_ID, 0, @@ -1129,9 +1142,11 @@ EndPrepare(GlobalTransaction gxact) gxact->prepare_end_lsn = XLogInsert(RM_XACT_ID, XLOG_XACT_PREPARE); if (replorigin) + { /* Move LSNs forward for this replication origin */ replorigin_session_advance(replorigin_session_origin_lsn, gxact->prepare_end_lsn); + } XLogFlush(gxact->prepare_end_lsn); @@ -1204,10 +1219,12 @@ RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, * Read and validate the state file for xid. * * If it looks OK (has a valid magic number and CRC), return the palloc'd - * contents of the file. Otherwise return NULL. + * contents of the file, issuing an error when finding corrupted data. If + * missing_ok is true, which indicates that missing files can be safely + * ignored, then return NULL. This state can be reached when doing recovery. */ static char * -ReadTwoPhaseFile(TransactionId xid, bool give_warnings) +ReadTwoPhaseFile(TransactionId xid, bool missing_ok) { char path[MAXPGPATH]; char *buf; @@ -1217,18 +1234,19 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings) uint32 crc_offset; pg_crc32c calc_crc, file_crc; + int r; TwoPhaseFilePath(path, xid); fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); if (fd < 0) { - if (give_warnings) - ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not open two-phase state file \"%s\": %m", - path))); - return NULL; + if (missing_ok && errno == ENOENT) + return NULL; + + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", path))); } /* @@ -1238,31 +1256,27 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings) * even on a valid file. */ if (fstat(fd, &stat)) - { - CloseTransientFile(fd); - if (give_warnings) - ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not stat two-phase state file \"%s\": %m", - path))); - return NULL; - } + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", path))); if (stat.st_size < (MAXALIGN(sizeof(TwoPhaseFileHeader)) + MAXALIGN(sizeof(TwoPhaseRecordOnDisk)) + sizeof(pg_crc32c)) || stat.st_size > MaxAllocSize) - { - CloseTransientFile(fd); - return NULL; - } + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg_plural("incorrect size of file \"%s\": %zu byte", + "incorrect size of file \"%s\": %zu bytes", + (Size) stat.st_size, path, + (Size) stat.st_size))); crc_offset = stat.st_size - sizeof(pg_crc32c); if (crc_offset != MAXALIGN(crc_offset)) - { - CloseTransientFile(fd); - return NULL; - } + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("incorrect alignment of CRC offset for file \"%s\"", + path))); /* * OK, slurp in the file. @@ -1270,28 +1284,38 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings) buf = (char *) palloc(stat.st_size); pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_READ); - if (read(fd, buf, stat.st_size) != stat.st_size) + r = read(fd, buf, stat.st_size); + if (r != stat.st_size) { - pgstat_report_wait_end(); - CloseTransientFile(fd); - if (give_warnings) - ereport(WARNING, + if (r < 0) + ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read two-phase state file \"%s\": %m", - path))); - pfree(buf); - return NULL; + errmsg("could not read file \"%s\": %m", path))); + else + ereport(ERROR, + (errmsg("could not read file \"%s\": read %d of %zu", + path, r, (Size) stat.st_size))); } pgstat_report_wait_end(); - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); hdr = (TwoPhaseFileHeader *) buf; - if (hdr->magic != TWOPHASE_MAGIC || hdr->total_len != stat.st_size) - { - pfree(buf); - return NULL; - } + if (hdr->magic != TWOPHASE_MAGIC) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("invalid magic number stored in file \"%s\"", + path))); + + if (hdr->total_len != stat.st_size) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("invalid size stored in file \"%s\"", + path))); INIT_CRC32C(calc_crc); COMP_CRC32C(calc_crc, buf, crc_offset); @@ -1300,10 +1324,10 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings) file_crc = *((pg_crc32c *) (buf + crc_offset)); if (!EQ_CRC32C(calc_crc, file_crc)) - { - pfree(buf); - return NULL; - } + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("calculated CRC checksum does not match value stored in file \"%s\"", + path))); return buf; } @@ -1315,7 +1339,7 @@ void ParsePrepareRecord(uint8 info, char *xlrec, xl_xact_parsed_prepare *parsed) { TwoPhaseFileHeader *hdr; - char *bufptr; + char *bufptr; hdr = (TwoPhaseFileHeader *) xlrec; bufptr = xlrec + MAXALIGN(sizeof(TwoPhaseFileHeader)); @@ -1353,7 +1377,6 @@ ParsePrepareRecord(uint8 info, char *xlrec, xl_xact_parsed_prepare *parsed) * * Note clearly that this function can access WAL during normal operation, * similarly to the way WALSender or Logical Decoding would do. - * */ static void XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len) @@ -1362,8 +1385,8 @@ XlogReadTwoPhaseData(XLogRecPtr lsn, char **buf, int *len) XLogReaderState *xlogreader; char *errormsg; - xlogreader = XLogReaderAllocate(wal_segment_size, &read_local_xlog_page, - NULL); + xlogreader = XLogReaderAllocate(wal_segment_size, NULL, + &read_local_xlog_page, NULL); if (!xlogreader) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), @@ -1412,7 +1435,7 @@ StandbyTransactionIdIsPrepared(TransactionId xid) return false; /* nothing to do */ /* Read and validate file */ - buf = ReadTwoPhaseFile(xid, false); + buf = ReadTwoPhaseFile(xid, true); if (buf == NULL) return false; @@ -1444,7 +1467,6 @@ FinishPreparedTransaction(const char *gid, bool isCommit) RelFileNode *delrels; int ndelrels; SharedInvalidationMessage *invalmsgs; - int i; /* * Validate the GID, and lock the GXACT to ensure that two backends do not @@ -1461,7 +1483,7 @@ FinishPreparedTransaction(const char *gid, bool isCommit) * to disk if for some reason they have lived for a long time. */ if (gxact->ondisk) - buf = ReadTwoPhaseFile(xid, true); + buf = ReadTwoPhaseFile(xid, false); else XlogReadTwoPhaseData(gxact->prepare_start_lsn, &buf, NULL); @@ -1485,6 +1507,9 @@ FinishPreparedTransaction(const char *gid, bool isCommit) /* compute latestXid among all children */ latestXid = TransactionIdLatest(xid, hdr->nsubxacts, children); + /* Prevent cancel/die interrupt while cleaning up */ + HOLD_INTERRUPTS(); + /* * The order of operations here is critical: make the XLOG entry for * commit or abort, then mark the transaction committed or aborted in @@ -1534,13 +1559,9 @@ FinishPreparedTransaction(const char *gid, bool isCommit) delrels = abortrels; ndelrels = hdr->nabortrels; } - for (i = 0; i < ndelrels; i++) - { - SMgrRelation srel = smgropen(delrels[i], InvalidBackendId); - smgrdounlink(srel, false); - smgrclose(srel); - } + /* Make sure files supposed to be dropped are dropped */ + DropRelationFiles(delrels, ndelrels, false); /* * Handle cache invalidation messages. @@ -1554,6 +1575,14 @@ FinishPreparedTransaction(const char *gid, bool isCommit) if (hdr->initfileinval) RelationCacheInitFilePostInvalidate(); + /* + * Acquire the two-phase lock. We want to work on the two-phase callbacks + * while holding it to avoid potential conflicts with other transactions + * attempting to use the same GID, so the lock is released once the shared + * memory state is cleared. + */ + LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE); + /* And now do the callbacks */ if (isCommit) ProcessRecords(bufptr, xid, twophase_postcommit_callbacks); @@ -1562,8 +1591,17 @@ FinishPreparedTransaction(const char *gid, bool isCommit) PredicateLockTwoPhaseFinish(xid, isCommit); + /* Clear shared memory state */ + RemoveGXact(gxact); + + /* + * Release the lock as all callbacks are called and shared memory cleanup + * is done. + */ + LWLockRelease(TwoPhaseStateLock); + /* Count the prepared xact as committed or aborted */ - AtEOXact_PgStat(isCommit); + AtEOXact_PgStat(isCommit, false); /* * And now we can clean up any files we may have left. @@ -1571,11 +1609,10 @@ FinishPreparedTransaction(const char *gid, bool isCommit) if (gxact->ondisk) RemoveTwoPhaseFile(xid, true); - LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE); - RemoveGXact(gxact); - LWLockRelease(TwoPhaseStateLock); MyLockedGxact = NULL; + RESUME_INTERRUPTS(); + pfree(buf); } @@ -1620,8 +1657,7 @@ RemoveTwoPhaseFile(TransactionId xid, bool giveWarning) if (errno != ENOENT || giveWarning) ereport(WARNING, (errcode_for_file_access(), - errmsg("could not remove two-phase state file \"%s\": %m", - path))); + errmsg("could not remove file \"%s\": %m", path))); } /* @@ -1649,26 +1685,28 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len) if (fd < 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not recreate two-phase state file \"%s\": %m", - path))); + errmsg("could not recreate file \"%s\": %m", path))); /* Write content and CRC */ + errno = 0; pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_WRITE); if (write(fd, content, len) != len) { - pgstat_report_wait_end(); - CloseTransientFile(fd); + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write two-phase state file: %m"))); + errmsg("could not write file \"%s\": %m", path))); } if (write(fd, &statefile_crc, sizeof(pg_crc32c)) != sizeof(pg_crc32c)) { - pgstat_report_wait_end(); - CloseTransientFile(fd); + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write two-phase state file: %m"))); + errmsg("could not write file \"%s\": %m", path))); } pgstat_report_wait_end(); @@ -1678,18 +1716,15 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len) */ pgstat_report_wait_start(WAIT_EVENT_TWOPHASE_FILE_SYNC); if (pg_fsync(fd) != 0) - { - CloseTransientFile(fd); ereport(ERROR, (errcode_for_file_access(), - errmsg("could not fsync two-phase state file: %m"))); - } + errmsg("could not fsync file \"%s\": %m", path))); pgstat_report_wait_end(); if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not close two-phase state file: %m"))); + errmsg("could not close file \"%s\": %m", path))); } /* @@ -1706,7 +1741,7 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len) * possible that GXACTs that were valid at checkpoint start will no longer * exist if we wait a little bit. With typical checkpoint settings this * will be about 3 minutes for an online checkpoint, so as a result we - * we expect that there will be no GXACTs that need to be copied to disk. + * expect that there will be no GXACTs that need to be copied to disk. * * If a GXACT remains valid across multiple checkpoints, it will already * be on disk so we don't bother to repeat that write. @@ -1829,22 +1864,26 @@ restoreTwoPhaseData(void) * * Scan the shared memory entries of TwoPhaseState and determine the range * of valid XIDs present. This is run during database startup, after we - * have completed reading WAL. ShmemVariableCache->nextXid has been set to + * have completed reading WAL. ShmemVariableCache->nextFullXid has been set to * one more than the highest XID for which evidence exists in WAL. * - * We throw away any prepared xacts with main XID beyond nextXid --- if any + * We throw away any prepared xacts with main XID beyond nextFullXid --- if any * are present, it suggests that the DBA has done a PITR recovery to an * earlier point in time without cleaning out pg_twophase. We dare not * try to recover such prepared xacts since they likely depend on database * state that doesn't exist now. * - * However, we will advance nextXid beyond any subxact XIDs belonging to + * However, we will advance nextFullXid beyond any subxact XIDs belonging to * valid prepared xacts. We need to do this since subxact commit doesn't * write a WAL entry, and so there might be no evidence in WAL of those * subxact XIDs. * + * On corrupted two-phase files, fail immediately. Keeping around broken + * entries and let replay continue causes harm on the system, and a new + * backup should be rolled in. + * * Our other responsibility is to determine and return the oldest valid XID - * among the prepared xacts (if none, return ShmemVariableCache->nextXid). + * among the prepared xacts (if none, return ShmemVariableCache->nextFullXid). * This is needed to synchronize pg_subtrans startup properly. * * If xids_p and nxids_p are not NULL, pointer to a palloc'd array of all @@ -1854,7 +1893,8 @@ restoreTwoPhaseData(void) TransactionId PrescanPreparedTransactions(TransactionId **xids_p, int *nxids_p) { - TransactionId origNextXid = ShmemVariableCache->nextXid; + FullTransactionId nextFullXid = ShmemVariableCache->nextFullXid; + TransactionId origNextXid = XidFromFullTransactionId(nextFullXid); TransactionId result = origNextXid; TransactionId *xids = NULL; int nxids = 0; @@ -2070,7 +2110,7 @@ RecoverPreparedTransactions(void) * * If setParent is true, set up subtransaction parent linkages. * - * If setNextXid is true, set ShmemVariableCache->nextXid to the newest + * If setNextXid is true, set ShmemVariableCache->nextFullXid to the newest * value scanned. */ static char * @@ -2079,7 +2119,8 @@ ProcessTwoPhaseBuffer(TransactionId xid, bool fromdisk, bool setParent, bool setNextXid) { - TransactionId origNextXid = ShmemVariableCache->nextXid; + FullTransactionId nextFullXid = ShmemVariableCache->nextFullXid; + TransactionId origNextXid = XidFromFullTransactionId(nextFullXid); TransactionId *subxids; char *buf; TwoPhaseFileHeader *hdr; @@ -2133,15 +2174,7 @@ ProcessTwoPhaseBuffer(TransactionId xid, if (fromdisk) { /* Read and validate file */ - buf = ReadTwoPhaseFile(xid, true); - if (buf == NULL) - { - ereport(WARNING, - (errmsg("removing corrupt two-phase state file for transaction %u", - xid))); - RemoveTwoPhaseFile(xid, true); - return NULL; - } + buf = ReadTwoPhaseFile(xid, false); } else { @@ -2154,26 +2187,20 @@ ProcessTwoPhaseBuffer(TransactionId xid, if (!TransactionIdEquals(hdr->xid, xid)) { if (fromdisk) - { - ereport(WARNING, - (errmsg("removing corrupt two-phase state file for transaction %u", + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted two-phase state file for transaction %u", xid))); - RemoveTwoPhaseFile(xid, true); - } else - { - ereport(WARNING, - (errmsg("removing corrupt two-phase state from memory for transaction %u", + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted two-phase state in memory for transaction %u", xid))); - PrepareRedoRemove(xid, true); - } - pfree(buf); - return NULL; } /* * Examine subtransaction XIDs ... they should all follow main XID, and - * they may force us to advance nextXid. + * they may force us to advance nextFullXid. */ subxids = (TransactionId *) (buf + MAXALIGN(sizeof(TwoPhaseFileHeader)) + @@ -2184,25 +2211,9 @@ ProcessTwoPhaseBuffer(TransactionId xid, Assert(TransactionIdFollows(subxid, xid)); - /* update nextXid if needed */ - if (setNextXid && - TransactionIdFollowsOrEquals(subxid, - ShmemVariableCache->nextXid)) - { - /* - * We don't expect anyone else to modify nextXid, hence we don't - * need to hold a lock while examining it. We still acquire the - * lock to modify it, though, so we recheck. - */ - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - if (TransactionIdFollowsOrEquals(subxid, - ShmemVariableCache->nextXid)) - { - ShmemVariableCache->nextXid = subxid; - TransactionIdAdvance(ShmemVariableCache->nextXid); - } - LWLockRelease(XidGenLock); - } + /* update nextFullXid if needed */ + if (setNextXid) + AdvanceNextFullTransactionIdPastXid(subxid); if (setParent) SubTransSetParent(subxid, xid); diff --git a/src/backend/access/transam/twophase_rmgr.c b/src/backend/access/transam/twophase_rmgr.c index 6d327e36bcf..2b899e6598b 100644 --- a/src/backend/access/transam/twophase_rmgr.c +++ b/src/backend/access/transam/twophase_rmgr.c @@ -3,7 +3,7 @@ * twophase_rmgr.c * Two-phase-commit resource managers tables * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c index 394843f7e91..b18eee42d48 100644 --- a/src/backend/access/transam/varsup.c +++ b/src/backend/access/transam/varsup.c @@ -3,7 +3,7 @@ * varsup.c * postgres OID & XID variables support routines * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/transam/varsup.c @@ -35,7 +35,8 @@ VariableCache ShmemVariableCache = NULL; /* - * Allocate the next XID for a new transaction or subtransaction. + * Allocate the next FullTransactionId for a new transaction or + * subtransaction. * * The new XID is also stored into MyPgXact before returning. * @@ -44,9 +45,10 @@ VariableCache ShmemVariableCache = NULL; * does something. So it is safe to do a database lookup if we want to * issue a warning about XID wrap. */ -TransactionId +FullTransactionId GetNewTransactionId(bool isSubXact) { + FullTransactionId full_xid; TransactionId xid; /* @@ -64,7 +66,7 @@ GetNewTransactionId(bool isSubXact) { Assert(!isSubXact); MyPgXact->xid = BootstrapTransactionId; - return BootstrapTransactionId; + return FullTransactionIdFromEpochAndXid(0, BootstrapTransactionId); } /* safety check, we should never get this far in a HS standby */ @@ -73,7 +75,8 @@ GetNewTransactionId(bool isSubXact) LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - xid = ShmemVariableCache->nextXid; + full_xid = ShmemVariableCache->nextFullXid; + xid = XidFromFullTransactionId(full_xid); /*---------- * Check to see if it's safe to assign another XID. This protects against @@ -156,7 +159,8 @@ GetNewTransactionId(bool isSubXact) /* Re-acquire lock and start over */ LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - xid = ShmemVariableCache->nextXid; + full_xid = ShmemVariableCache->nextFullXid; + xid = XidFromFullTransactionId(full_xid); } /* @@ -173,12 +177,12 @@ GetNewTransactionId(bool isSubXact) ExtendSUBTRANS(xid); /* - * Now advance the nextXid counter. This must not happen until after we - * have successfully completed ExtendCLOG() --- if that routine fails, we - * want the next incoming transaction to try it again. We cannot assign - * more XIDs until there is CLOG space for them. + * Now advance the nextFullXid counter. This must not happen until after + * we have successfully completed ExtendCLOG() --- if that routine fails, + * we want the next incoming transaction to try it again. We cannot + * assign more XIDs until there is CLOG space for them. */ - TransactionIdAdvance(ShmemVariableCache->nextXid); + FullTransactionIdAdvance(&ShmemVariableCache->nextFullXid); /* * We must store the new XID into the shared ProcArray before releasing @@ -186,20 +190,23 @@ GetNewTransactionId(bool isSubXact) * latestCompletedXid is present in the ProcArray, which is essential for * correct OldestXmin tracking; see src/backend/access/transam/README. * - * XXX by storing xid into MyPgXact without acquiring ProcArrayLock, we - * are relying on fetch/store of an xid to be atomic, else other backends - * might see a partially-set xid here. But holding both locks at once - * would be a nasty concurrency hit. So for now, assume atomicity. - * * Note that readers of PGXACT xid fields should be careful to fetch the * value only once, rather than assume they can read a value multiple - * times and get the same answer each time. + * times and get the same answer each time. Note we are assuming that + * TransactionId and int fetch/store are atomic. * * The same comments apply to the subxact xid count and overflow fields. * - * A solution to the atomic-store problem would be to give each PGXACT its - * own spinlock used only for fetching/storing that PGXACT's xid and - * related fields. + * Use of a write barrier prevents dangerous code rearrangement in this + * function; other backends could otherwise e.g. be examining my subxids + * info concurrently, and we don't want them to see an invalid + * intermediate state, such as an incremented nxids before the array entry + * is filled. + * + * Other processes that read nxids should do so before reading xids + * elements with a pg_read_barrier() in between, so that they can be sure + * not to read an uninitialized array element; see + * src/backend/storage/lmgr/README.barrier. * * If there's no room to fit a subtransaction XID into PGPROC, set the * cache-overflowed flag instead. This forces readers to look in @@ -211,51 +218,86 @@ GetNewTransactionId(bool isSubXact) * window *will* include the parent XID, so they will deliver the correct * answer later on when someone does have a reason to inquire.) */ + if (!isSubXact) + MyPgXact->xid = xid; /* LWLockRelease acts as barrier */ + else { - /* - * Use volatile pointer to prevent code rearrangement; other backends - * could be examining my subxids info concurrently, and we don't want - * them to see an invalid intermediate state, such as incrementing - * nxids before filling the array entry. Note we are assuming that - * TransactionId and int fetch/store are atomic. - */ - volatile PGPROC *myproc = MyProc; - volatile PGXACT *mypgxact = MyPgXact; + int nxids = MyPgXact->nxids; - if (!isSubXact) - mypgxact->xid = xid; - else + if (nxids < PGPROC_MAX_CACHED_SUBXIDS) { - int nxids = mypgxact->nxids; - - if (nxids < PGPROC_MAX_CACHED_SUBXIDS) - { - myproc->subxids.xids[nxids] = xid; - mypgxact->nxids = nxids + 1; - } - else - mypgxact->overflowed = true; + MyProc->subxids.xids[nxids] = xid; + pg_write_barrier(); + MyPgXact->nxids = nxids + 1; } + else + MyPgXact->overflowed = true; } LWLockRelease(XidGenLock); - return xid; + return full_xid; } /* - * Read nextXid but don't allocate it. + * Read nextFullXid but don't allocate it. */ -TransactionId -ReadNewTransactionId(void) +FullTransactionId +ReadNextFullTransactionId(void) { - TransactionId xid; + FullTransactionId fullXid; LWLockAcquire(XidGenLock, LW_SHARED); - xid = ShmemVariableCache->nextXid; + fullXid = ShmemVariableCache->nextFullXid; LWLockRelease(XidGenLock); - return xid; + return fullXid; +} + +/* + * Advance nextFullXid to the value after a given xid. The epoch is inferred. + * This must only be called during recovery or from two-phase start-up code. + */ +void +AdvanceNextFullTransactionIdPastXid(TransactionId xid) +{ + FullTransactionId newNextFullXid; + TransactionId next_xid; + uint32 epoch; + + /* + * It is safe to read nextFullXid without a lock, because this is only + * called from the startup process or single-process mode, meaning that no + * other process can modify it. + */ + Assert(AmStartupProcess() || !IsUnderPostmaster); + + /* Fast return if this isn't an xid high enough to move the needle. */ + next_xid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); + if (!TransactionIdFollowsOrEquals(xid, next_xid)) + return; + + /* + * Compute the FullTransactionId that comes after the given xid. To do + * this, we preserve the existing epoch, but detect when we've wrapped + * into a new epoch. This is necessary because WAL records and 2PC state + * currently contain 32 bit xids. The wrap logic is safe in those cases + * because the span of active xids cannot exceed one epoch at any given + * point in the WAL stream. + */ + TransactionIdAdvance(xid); + epoch = EpochFromFullTransactionId(ShmemVariableCache->nextFullXid); + if (unlikely(xid < next_xid)) + ++epoch; + newNextFullXid = FullTransactionIdFromEpochAndXid(epoch, xid); + + /* + * We still need to take a lock to modify the value when there are + * concurrent readers. + */ + LWLockAcquire(XidGenLock, LW_EXCLUSIVE); + ShmemVariableCache->nextFullXid = newNextFullXid; + LWLockRelease(XidGenLock); } /* @@ -359,7 +401,7 @@ SetTransactionIdLimit(TransactionId oldest_datfrozenxid, Oid oldest_datoid) ShmemVariableCache->xidStopLimit = xidStopLimit; ShmemVariableCache->xidWrapLimit = xidWrapLimit; ShmemVariableCache->oldestXidDB = oldest_datoid; - curXid = ShmemVariableCache->nextXid; + curXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); LWLockRelease(XidGenLock); /* Log the info */ @@ -435,7 +477,7 @@ ForceTransactionIdLimitUpdate(void) /* Locking is probably not really necessary, but let's be careful */ LWLockAcquire(XidGenLock, LW_SHARED); - nextXid = ShmemVariableCache->nextXid; + nextXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); xidVacLimit = ShmemVariableCache->xidVacLimit; oldestXid = ShmemVariableCache->oldestXid; oldestXidDB = ShmemVariableCache->oldestXidDB; @@ -446,7 +488,7 @@ ForceTransactionIdLimitUpdate(void) if (!TransactionIdIsValid(xidVacLimit)) return true; /* this shouldn't happen anymore either */ if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit)) - return true; /* past VacLimit, don't delay updating */ + return true; /* past xidVacLimit, don't delay updating */ if (!SearchSysCacheExists1(DATABASEOID, ObjectIdGetDatum(oldestXidDB))) return true; /* could happen, per comments above */ return false; @@ -459,8 +501,8 @@ ForceTransactionIdLimitUpdate(void) * OIDs are generated by a cluster-wide counter. Since they are only 32 bits * wide, counter wraparound will occur eventually, and therefore it is unwise * to assume they are unique unless precautions are taken to make them so. - * Hence, this routine should generally not be used directly. The only - * direct callers should be GetNewOid() and GetNewRelFileNode() in + * Hence, this routine should generally not be used directly. The only direct + * callers should be GetNewOidWithIndex() and GetNewRelFileNode() in * catalog/catalog.c. */ Oid @@ -476,11 +518,9 @@ GetNewObjectId(void) /* * Check for wraparound of the OID counter. We *must* not return 0 - * (InvalidOid); and as long as we have to check that, it seems a good - * idea to skip over everything below FirstNormalObjectId too. (This - * basically just avoids lots of collisions with bootstrap-assigned OIDs - * right after a wrap occurs, so as to avoid a possibly large number of - * iterations in GetNewOid.) Note we are relying on unsigned comparison. + * (InvalidOid), and in normal operation we mustn't return anything below + * FirstNormalObjectId since that range is reserved for initdb (see + * IsCatalogRelationOid()). Note we are relying on unsigned comparison. * * During initdb, we start the OID generator at FirstBootstrapObjectId, so * we only wrap if before that point when in bootstrap or standalone mode. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 948733c1e3d..9162286c98a 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -5,7 +5,7 @@ * * See src/backend/access/transam/README for more information. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -31,6 +31,7 @@ #include "access/xloginsert.h" #include "access/xlogutils.h" #include "catalog/namespace.h" +#include "catalog/pg_enum.h" #include "catalog/storage.h" #include "commands/async.h" #include "commands/tablecmds.h" @@ -48,6 +49,7 @@ #include "storage/condition_variable.h" #include "storage/fd.h" #include "storage/lmgr.h" +#include "storage/md.h" #include "storage/predicate.h" #include "storage/proc.h" #include "storage/procarray.h" @@ -89,9 +91,9 @@ int synchronous_commit = SYNCHRONOUS_COMMIT_ON; * need to return the same answers in the parallel worker as they would have * in the user backend, so we need some additional bookkeeping. * - * XactTopTransactionId stores the XID of our toplevel transaction, which - * will be the same as TopTransactionState.transactionId in an ordinary - * backend; but in a parallel backend, which does not have the entire + * XactTopFullTransactionId stores the XID of our toplevel transaction, which + * will be the same as TopTransactionStateData.fullTransactionId in an + * ordinary backend; but in a parallel backend, which does not have the entire * transaction state, it will instead be copied from the backend that started * the parallel operation. * @@ -103,7 +105,7 @@ int synchronous_commit = SYNCHRONOUS_COMMIT_ON; * The XIDs are stored sorted in numerical order (not logical order) to make * lookups as fast as possible. */ -TransactionId XactTopTransactionId = InvalidTransactionId; +FullTransactionId XactTopFullTransactionId = {InvalidTransactionId}; int nParallelCurrentXids = 0; TransactionId *ParallelCurrentXids; @@ -169,7 +171,7 @@ typedef enum TBlockState */ typedef struct TransactionStateData { - TransactionId transactionId; /* my XID, or Invalid if none */ + FullTransactionId fullTransactionId; /* my FullTransactionId */ SubTransactionId subTransactionId; /* my subxact ID */ char *name; /* savepoint name, if any */ int savepointLevel; /* savepoint level */ @@ -188,38 +190,39 @@ typedef struct TransactionStateData bool startedInRecovery; /* did we start in recovery? */ bool didLogXid; /* has xid been included in WAL record? */ int parallelModeLevel; /* Enter/ExitParallelMode counter */ + bool chain; /* start a new block after this one */ struct TransactionStateData *parent; /* back link to parent */ } TransactionStateData; typedef TransactionStateData *TransactionState; +/* + * Serialized representation used to transmit transaction state to parallel + * workers through shared memory. + */ +typedef struct SerializedTransactionState +{ + int xactIsoLevel; + bool xactDeferrable; + FullTransactionId topFullTransactionId; + FullTransactionId currentFullTransactionId; + CommandId currentCommandId; + int nParallelCurrentXids; + TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]; +} SerializedTransactionState; + +/* The size of SerializedTransactionState, not including the final array. */ +#define SerializedTransactionStateHeaderSize \ + offsetof(SerializedTransactionState, parallelCurrentXids) + /* * CurrentTransactionState always points to the current transaction state * block. It will point to TopTransactionStateData when not in a * transaction at all, or when in a top-level transaction. */ static TransactionStateData TopTransactionStateData = { - 0, /* transaction id */ - 0, /* subtransaction id */ - NULL, /* savepoint name */ - 0, /* savepoint level */ - TRANS_DEFAULT, /* transaction state */ - TBLOCK_DEFAULT, /* transaction block state from the client - * perspective */ - 0, /* transaction nesting depth */ - 0, /* GUC context nesting depth */ - NULL, /* cur transaction context */ - NULL, /* cur transaction resource owner */ - NULL, /* subcommitted child Xids */ - 0, /* # of subcommitted child Xids */ - 0, /* allocated size of childXids[] */ - InvalidOid, /* previous CurrentUserId setting */ - 0, /* previous SecurityRestrictionContext */ - false, /* entry-time xact r/o state */ - false, /* startedInRecovery */ - false, /* didLogXid */ - 0, /* parallelModeLevel */ - NULL /* link to parent state block */ + .state = TRANS_DEFAULT, + .blockState = TBLOCK_DEFAULT, }; /* @@ -261,6 +264,9 @@ static char *prepareGID; */ static bool forceSyncCommit = false; +/* Flag for logging statements in a transaction. */ +bool xact_is_sampled = false; + /* * Private context for transaction-abort work --- we reserve space for this * at startup to ensure that AbortTransaction and AbortSubTransaction can work @@ -306,11 +312,11 @@ static void AtStart_Memory(void); static void AtStart_ResourceOwner(void); static void CallXactCallbacks(XactEvent event); static void CallSubXactCallbacks(SubXactEvent event, - SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId mySubid, + SubTransactionId parentSubid); static void CleanupTransaction(void); static void CheckTransactionBlock(bool isTopLevel, bool throwError, - const char *stmtType); + const char *stmtType); static void CommitTransaction(void); static TransactionId RecordTransactionAbort(bool isSubXact); static void StartTransaction(void); @@ -388,9 +394,9 @@ IsAbortedTransactionBlockState(void) TransactionId GetTopTransactionId(void) { - if (!TransactionIdIsValid(XactTopTransactionId)) + if (!FullTransactionIdIsValid(XactTopFullTransactionId)) AssignTransactionId(&TopTransactionStateData); - return XactTopTransactionId; + return XidFromFullTransactionId(XactTopFullTransactionId); } /* @@ -403,7 +409,7 @@ GetTopTransactionId(void) TransactionId GetTopTransactionIdIfAny(void) { - return XactTopTransactionId; + return XidFromFullTransactionId(XactTopFullTransactionId); } /* @@ -418,9 +424,9 @@ GetCurrentTransactionId(void) { TransactionState s = CurrentTransactionState; - if (!TransactionIdIsValid(s->transactionId)) + if (!FullTransactionIdIsValid(s->fullTransactionId)) AssignTransactionId(s); - return s->transactionId; + return XidFromFullTransactionId(s->fullTransactionId); } /* @@ -433,7 +439,66 @@ GetCurrentTransactionId(void) TransactionId GetCurrentTransactionIdIfAny(void) { - return CurrentTransactionState->transactionId; + return XidFromFullTransactionId(CurrentTransactionState->fullTransactionId); +} + +/* + * GetTopFullTransactionId + * + * This will return the FullTransactionId of the main transaction, assigning + * one if it's not yet set. Be careful to call this only inside a valid xact. + */ +FullTransactionId +GetTopFullTransactionId(void) +{ + if (!FullTransactionIdIsValid(XactTopFullTransactionId)) + AssignTransactionId(&TopTransactionStateData); + return XactTopFullTransactionId; +} + +/* + * GetTopFullTransactionIdIfAny + * + * This will return the FullTransactionId of the main transaction, if one is + * assigned. It will return InvalidFullTransactionId if we are not currently + * inside a transaction, or inside a transaction that hasn't yet been assigned + * one. + */ +FullTransactionId +GetTopFullTransactionIdIfAny(void) +{ + return XactTopFullTransactionId; +} + +/* + * GetCurrentFullTransactionId + * + * This will return the FullTransactionId of the current transaction (main or + * sub transaction), assigning one if it's not yet set. Be careful to call + * this only inside a valid xact. + */ +FullTransactionId +GetCurrentFullTransactionId(void) +{ + TransactionState s = CurrentTransactionState; + + if (!FullTransactionIdIsValid(s->fullTransactionId)) + AssignTransactionId(s); + return s->fullTransactionId; +} + +/* + * GetCurrentFullTransactionIdIfAny + * + * This will return the FullTransactionId of the current sub xact, if one is + * assigned. It will return InvalidFullTransactionId if we are not currently + * inside a transaction, or inside a transaction that hasn't been assigned one + * yet. + */ +FullTransactionId +GetCurrentFullTransactionIdIfAny(void) +{ + return CurrentTransactionState->fullTransactionId; } /* @@ -444,7 +509,7 @@ GetCurrentTransactionIdIfAny(void) void MarkCurrentTransactionIdLoggedIfAny(void) { - if (TransactionIdIsValid(CurrentTransactionState->transactionId)) + if (FullTransactionIdIsValid(CurrentTransactionState->fullTransactionId)) CurrentTransactionState->didLogXid = true; } @@ -479,7 +544,7 @@ GetStableLatestTransactionId(void) /* * AssignTransactionId * - * Assigns a new permanent XID to the given TransactionState. + * Assigns a new permanent FullTransactionId to the given TransactionState. * We do not assign XIDs to transactions until/unless this is called. * Also, any parent TransactionStates that don't yet have XIDs are assigned * one; this maintains the invariant that a child transaction has an XID @@ -493,7 +558,7 @@ AssignTransactionId(TransactionState s) bool log_unknown_top = false; /* Assert that caller didn't screw up */ - Assert(!TransactionIdIsValid(s->transactionId)); + Assert(!FullTransactionIdIsValid(s->fullTransactionId)); Assert(s->state == TRANS_INPROGRESS); /* @@ -505,18 +570,18 @@ AssignTransactionId(TransactionState s) /* * Ensure parent(s) have XIDs, so that a child always has an XID later - * than its parent. Musn't recurse here, or we might get a stack overflow - * if we're at the bottom of a huge stack of subtransactions none of which - * have XIDs yet. + * than its parent. Mustn't recurse here, or we might get a stack + * overflow if we're at the bottom of a huge stack of subtransactions none + * of which have XIDs yet. */ - if (isSubXact && !TransactionIdIsValid(s->parent->transactionId)) + if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId)) { TransactionState p = s->parent; TransactionState *parents; size_t parentOffset = 0; parents = palloc(sizeof(TransactionState) * s->nestingLevel); - while (p != NULL && !TransactionIdIsValid(p->transactionId)) + while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId)) { parents[parentOffset++] = p; p = p->parent; @@ -547,26 +612,28 @@ AssignTransactionId(TransactionState s) log_unknown_top = true; /* - * Generate a new Xid and record it in PG_PROC and pg_subtrans. + * Generate a new FullTransactionId and record its xid in PG_PROC and + * pg_subtrans. * * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in * shared storage other than PG_PROC; because if there's no room for it in * PG_PROC, the subtrans entry is needed to ensure that other backends see * the Xid as "running". See GetNewTransactionId. */ - s->transactionId = GetNewTransactionId(isSubXact); + s->fullTransactionId = GetNewTransactionId(isSubXact); if (!isSubXact) - XactTopTransactionId = s->transactionId; + XactTopFullTransactionId = s->fullTransactionId; if (isSubXact) - SubTransSetParent(s->transactionId, s->parent->transactionId); + SubTransSetParent(XidFromFullTransactionId(s->fullTransactionId), + XidFromFullTransactionId(s->parent->fullTransactionId)); /* * If it's a top-level transaction, the predicate locking system needs to * be told about it too. */ if (!isSubXact) - RegisterPredicateLockingXid(s->transactionId); + RegisterPredicateLockingXid(XidFromFullTransactionId(s->fullTransactionId)); /* * Acquire lock on the transaction XID. (We assume this cannot block.) We @@ -576,7 +643,7 @@ AssignTransactionId(TransactionState s) currentOwner = CurrentResourceOwner; CurrentResourceOwner = s->curTransactionOwner; - XactLockTableInsert(s->transactionId); + XactLockTableInsert(XidFromFullTransactionId(s->fullTransactionId)); CurrentResourceOwner = currentOwner; @@ -600,7 +667,7 @@ AssignTransactionId(TransactionState s) */ if (isSubXact && XLogStandbyInfoActive()) { - unreportedXids[nUnreportedXids] = s->transactionId; + unreportedXids[nUnreportedXids] = XidFromFullTransactionId(s->fullTransactionId); nUnreportedXids++; /* @@ -693,6 +760,22 @@ GetCurrentCommandId(bool used) return currentCommandId; } +/* + * SetParallelStartTimestamps + * + * In a parallel worker, we should inherit the parent transaction's + * timestamps rather than setting our own. The parallel worker + * infrastructure must call this to provide those values before + * calling StartTransaction() or SetCurrentStatementStartTimestamp(). + */ +void +SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts) +{ + Assert(IsParallelWorker()); + xactStartTimestamp = xact_ts; + stmtStartTimestamp = stmt_ts; +} + /* * GetCurrentTransactionStartTimestamp */ @@ -727,11 +810,17 @@ GetCurrentTransactionStopTimestamp(void) /* * SetCurrentStatementStartTimestamp + * + * In a parallel worker, this should already have been provided by a call + * to SetParallelStartTimestamps(). */ void SetCurrentStatementStartTimestamp(void) { - stmtStartTimestamp = GetCurrentTimestamp(); + if (!IsParallelWorker()) + stmtStartTimestamp = GetCurrentTimestamp(); + else + Assert(stmtStartTimestamp != 0); } /* @@ -770,10 +859,10 @@ TransactionIdIsCurrentTransactionId(TransactionId xid) * We always say that BootstrapTransactionId is "not my transaction ID" * even when it is (ie, during bootstrap). Along with the fact that * transam.c always treats BootstrapTransactionId as already committed, - * this causes the tqual.c routines to see all tuples as committed, which - * is what we need during bootstrap. (Bootstrap mode only inserts tuples, - * it never updates or deletes them, so all tuples can be presumed good - * immediately.) + * this causes the heapam_visibility.c routines to see all tuples as + * committed, which is what we need during bootstrap. (Bootstrap mode + * only inserts tuples, it never updates or deletes them, so all tuples + * can be presumed good immediately.) * * Likewise, InvalidTransactionId and FrozenTransactionId are certainly * not my transaction ID, so we can just return "false" immediately for @@ -826,9 +915,9 @@ TransactionIdIsCurrentTransactionId(TransactionId xid) if (s->state == TRANS_ABORT) continue; - if (!TransactionIdIsValid(s->transactionId)) + if (!FullTransactionIdIsValid(s->fullTransactionId)) continue; /* it can't have any child XIDs either */ - if (TransactionIdEquals(xid, s->transactionId)) + if (TransactionIdEquals(xid, XidFromFullTransactionId(s->fullTransactionId))) return true; /* As the childXids array is ordered, we can use binary search */ low = 0; @@ -996,11 +1085,11 @@ AtStart_Memory(void) */ if (TransactionAbortContext == NULL) TransactionAbortContext = - AllocSetContextCreateExtended(TopMemoryContext, - "TransactionAbortContext", - 32 * 1024, - 32 * 1024, - 32 * 1024); + AllocSetContextCreate(TopMemoryContext, + "TransactionAbortContext", + 32 * 1024, + 32 * 1024, + 32 * 1024); /* * We shouldn't have a transaction context already. @@ -1143,7 +1232,7 @@ RecordTransactionCommit(void) if (!markXidCommitted) { /* - * We expect that every smgrscheduleunlink is followed by a catalog + * We expect that every RelationDropStorage is followed by a catalog * update, and hence XID assignment, so we shouldn't get here with any * pending deletes. Use a real test not just an Assert to check this, * since it's a bit fragile. @@ -1489,7 +1578,7 @@ AtSubCommit_childXids(void) * all XIDs already in the array belong to subtransactions started and * subcommitted before us, so their XIDs must precede ours. */ - s->parent->childXids[s->parent->nChildXids] = s->transactionId; + s->parent->childXids[s->parent->nChildXids] = XidFromFullTransactionId(s->fullTransactionId); if (s->nChildXids > 0) memcpy(&s->parent->childXids[s->parent->nChildXids + 1], @@ -1803,21 +1892,44 @@ StartTransaction(void) s = &TopTransactionStateData; CurrentTransactionState = s; - Assert(XactTopTransactionId == InvalidTransactionId); + Assert(!FullTransactionIdIsValid(XactTopFullTransactionId)); + + /* check the current transaction state */ + Assert(s->state == TRANS_DEFAULT); /* - * check the current transaction state + * Set the current transaction state information appropriately during + * start processing. Note that once the transaction status is switched + * this process cannot fail until the user ID and the security context + * flags are fetched below. */ - if (s->state != TRANS_DEFAULT) - elog(WARNING, "StartTransaction while in %s state", - TransStateAsString(s->state)); + s->state = TRANS_START; + s->fullTransactionId = InvalidFullTransactionId; /* until assigned */ + + /* Determine if statements are logged in this transaction */ + xact_is_sampled = log_xact_sample_rate != 0 && + (log_xact_sample_rate == 1 || + random() <= log_xact_sample_rate * MAX_RANDOM_VALUE); /* - * set the current transaction state information appropriately during - * start processing + * initialize current transaction state fields + * + * note: prevXactReadOnly is not used at the outermost level */ - s->state = TRANS_START; - s->transactionId = InvalidTransactionId; /* until assigned */ + s->nestingLevel = 1; + s->gucNestLevel = 1; + s->childXids = NULL; + s->nChildXids = 0; + s->maxChildXids = 0; + + /* + * Once the current user ID and the security context flags are fetched, + * both will be properly reset even if transaction startup fails. + */ + GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext); + + /* SecurityRestrictionContext should never be set outside a transaction */ + Assert(s->prevSecContext == 0); /* * Make sure we've reset xact state variables @@ -1876,7 +1988,7 @@ StartTransaction(void) /* * Advertise it in the proc array. We assume assignment of - * LocalTransactionID is atomic, and the backendId should be set already. + * localTransactionId is atomic, and the backendId should be set already. */ Assert(MyProc->backendId == vxid.backendId); MyProc->lxid = vxid.localTransactionId; @@ -1884,28 +1996,26 @@ StartTransaction(void) TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId); /* - * set transaction_timestamp() (a/k/a now()). We want this to be the same - * as the first command's statement_timestamp(), so don't do a fresh - * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark - * xactStopTimestamp as unset. + * set transaction_timestamp() (a/k/a now()). Normally, we want this to + * be the same as the first command's statement_timestamp(), so don't do a + * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But + * for transactions started inside procedures (i.e., nonatomic SPI + * contexts), we do need to advance the timestamp. Also, in a parallel + * worker, the timestamp should already have been provided by a call to + * SetParallelStartTimestamps(). */ - xactStartTimestamp = stmtStartTimestamp; - xactStopTimestamp = 0; + if (!IsParallelWorker()) + { + if (!SPI_inside_nonatomic_context()) + xactStartTimestamp = stmtStartTimestamp; + else + xactStartTimestamp = GetCurrentTimestamp(); + } + else + Assert(xactStartTimestamp != 0); pgstat_report_xact_timestamp(xactStartTimestamp); - - /* - * initialize current transaction state fields - * - * note: prevXactReadOnly is not used at the outermost level - */ - s->nestingLevel = 1; - s->gucNestLevel = 1; - s->childXids = NULL; - s->nChildXids = 0; - s->maxChildXids = 0; - GetUserIdAndSecContext(&s->prevUser, &s->prevSecContext); - /* SecurityRestrictionContext should never be set outside a transaction */ - Assert(s->prevSecContext == 0); + /* Mark xactStopTimestamp as unset. */ + xactStopTimestamp = 0; /* * initialize other subsystems for new transaction @@ -2003,9 +2113,12 @@ CommitTransaction(void) /* * Mark serializable transaction as complete for predicate locking * purposes. This should be done as late as we can put it and still allow - * errors to be raised for failure patterns found at commit. + * errors to be raised for failure patterns found at commit. This is not + * appropriate in a parallel worker however, because we aren't committing + * the leader's transaction and its serializable state will live on. */ - PreCommit_CheckForSerializationFailure(); + if (!is_parallel_worker) + PreCommit_CheckForSerializationFailure(); /* * Insert notifications sent by NOTIFY commands into the queue. This @@ -2018,7 +2131,7 @@ CommitTransaction(void) HOLD_INTERRUPTS(); /* Commit updates to the relation map --- do this as late as possible */ - AtEOXact_RelationMap(true); + AtEOXact_RelationMap(true, is_parallel_worker); /* * set the current transaction state information appropriately during @@ -2120,13 +2233,14 @@ CommitTransaction(void) AtCommit_Notify(); AtEOXact_GUC(true, 1); AtEOXact_SPI(true); + AtEOXact_Enum(); AtEOXact_on_commit_actions(true); AtEOXact_Namespace(true, is_parallel_worker); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(true); AtEOXact_ComboCid(); AtEOXact_HashTables(true); - AtEOXact_PgStat(true); + AtEOXact_PgStat(true, is_parallel_worker); AtEOXact_Snapshot(true, false); AtEOXact_ApplyLauncher(true); pgstat_report_xact_timestamp(0); @@ -2139,7 +2253,7 @@ CommitTransaction(void) AtCommit_Memory(); - s->transactionId = InvalidTransactionId; + s->fullTransactionId = InvalidFullTransactionId; s->subTransactionId = InvalidSubTransactionId; s->nestingLevel = 0; s->gucNestLevel = 0; @@ -2147,7 +2261,7 @@ CommitTransaction(void) s->nChildXids = 0; s->maxChildXids = 0; - XactTopTransactionId = InvalidTransactionId; + XactTopFullTransactionId = InvalidFullTransactionId; nParallelCurrentXids = 0; /* @@ -2245,6 +2359,11 @@ PrepareTransaction(void) * clean up the source backend's local buffers and ON COMMIT state if the * prepared xact includes a DROP of a temp table. * + * Other objects types, like functions, operators or extensions, share the + * same restriction as they should not be created, locked or dropped as + * this can mess up with this session or even a follow-up session trying + * to use the same temporary namespace. + * * We must check this after executing any ON COMMIT actions, because they * might still access a temp relation. * @@ -2252,10 +2371,10 @@ PrepareTransaction(void) * cases, such as a temp table created and dropped all within the * transaction. That seems to require much more bookkeeping though. */ - if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPREL)) + if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot PREPARE a transaction that has operated on temporary tables"))); + errmsg("cannot PREPARE a transaction that has operated on temporary objects"))); /* * Likewise, don't allow PREPARE after pg_export_snapshot. This could be @@ -2398,10 +2517,11 @@ PrepareTransaction(void) /* PREPARE acts the same as COMMIT as far as GUC is concerned */ AtEOXact_GUC(true, 1); AtEOXact_SPI(true); + AtEOXact_Enum(); AtEOXact_on_commit_actions(true); AtEOXact_Namespace(true, false); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(true); AtEOXact_ComboCid(); AtEOXact_HashTables(true); /* don't call AtEOXact_PgStat here; we fixed pgstat state above */ @@ -2416,7 +2536,7 @@ PrepareTransaction(void) AtCommit_Memory(); - s->transactionId = InvalidTransactionId; + s->fullTransactionId = InvalidFullTransactionId; s->subTransactionId = InvalidSubTransactionId; s->nestingLevel = 0; s->gucNestLevel = 0; @@ -2424,7 +2544,7 @@ PrepareTransaction(void) s->nChildXids = 0; s->maxChildXids = 0; - XactTopTransactionId = InvalidTransactionId; + XactTopFullTransactionId = InvalidFullTransactionId; nParallelCurrentXids = 0; /* @@ -2539,7 +2659,7 @@ AbortTransaction(void) AtAbort_Portals(); AtEOXact_LargeObject(false); AtAbort_Notify(); - AtEOXact_RelationMap(false); + AtEOXact_RelationMap(false, is_parallel_worker); AtAbort_Twophase(); /* @@ -2600,13 +2720,14 @@ AbortTransaction(void) AtEOXact_GUC(false, 1); AtEOXact_SPI(false); + AtEOXact_Enum(); AtEOXact_on_commit_actions(false); AtEOXact_Namespace(false, is_parallel_worker); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(false); AtEOXact_ComboCid(); AtEOXact_HashTables(false); - AtEOXact_PgStat(false); + AtEOXact_PgStat(false, is_parallel_worker); AtEOXact_ApplyLauncher(false); pgstat_report_xact_timestamp(0); } @@ -2647,7 +2768,7 @@ CleanupTransaction(void) AtCleanup_Memory(); /* and transaction memory */ - s->transactionId = InvalidTransactionId; + s->fullTransactionId = InvalidFullTransactionId; s->subTransactionId = InvalidSubTransactionId; s->nestingLevel = 0; s->gucNestLevel = 0; @@ -2656,7 +2777,7 @@ CleanupTransaction(void) s->maxChildXids = 0; s->parallelModeLevel = 0; - XactTopTransactionId = InvalidTransactionId; + XactTopFullTransactionId = InvalidFullTransactionId; nParallelCurrentXids = 0; /* @@ -2737,6 +2858,36 @@ StartTransactionCommand(void) MemoryContextSwitchTo(CurTransactionContext); } + +/* + * Simple system for saving and restoring transaction characteristics + * (isolation level, read only, deferrable). We need this for transaction + * chaining, so that we can set the characteristics of the new transaction to + * be the same as the previous one. (We need something like this because the + * GUC system resets the characteristics at transaction end, so for example + * just skipping the reset in StartTransaction() won't work.) + */ +static int save_XactIsoLevel; +static bool save_XactReadOnly; +static bool save_XactDeferrable; + +void +SaveTransactionCharacteristics(void) +{ + save_XactIsoLevel = XactIsoLevel; + save_XactReadOnly = XactReadOnly; + save_XactDeferrable = XactDeferrable; +} + +void +RestoreTransactionCharacteristics(void) +{ + XactIsoLevel = save_XactIsoLevel; + XactReadOnly = save_XactReadOnly; + XactDeferrable = save_XactDeferrable; +} + + /* * CommitTransactionCommand */ @@ -2745,6 +2896,9 @@ CommitTransactionCommand(void) { TransactionState s = CurrentTransactionState; + if (s->chain) + SaveTransactionCharacteristics(); + switch (s->blockState) { /* @@ -2796,6 +2950,13 @@ CommitTransactionCommand(void) case TBLOCK_END: CommitTransaction(); s->blockState = TBLOCK_DEFAULT; + if (s->chain) + { + StartTransaction(); + s->blockState = TBLOCK_INPROGRESS; + s->chain = false; + RestoreTransactionCharacteristics(); + } break; /* @@ -2815,6 +2976,13 @@ CommitTransactionCommand(void) case TBLOCK_ABORT_END: CleanupTransaction(); s->blockState = TBLOCK_DEFAULT; + if (s->chain) + { + StartTransaction(); + s->blockState = TBLOCK_INPROGRESS; + s->chain = false; + RestoreTransactionCharacteristics(); + } break; /* @@ -2826,6 +2994,13 @@ CommitTransactionCommand(void) AbortTransaction(); CleanupTransaction(); s->blockState = TBLOCK_DEFAULT; + if (s->chain) + { + StartTransaction(); + s->blockState = TBLOCK_INPROGRESS; + s->chain = false; + RestoreTransactionCharacteristics(); + } break; /* @@ -3189,7 +3364,7 @@ PreventInTransactionBlock(bool isTopLevel, const char *stmtType) } /* - * WarnNoTranactionBlock + * WarnNoTransactionBlock * RequireTransactionBlock * * These two functions allow for warnings or errors if a command is executed @@ -3267,8 +3442,8 @@ bool IsInTransactionBlock(bool isTopLevel) { /* - * Return true on same conditions that would make PreventInTransactionBlock - * error out + * Return true on same conditions that would make + * PreventInTransactionBlock error out */ if (IsTransactionBlock()) return true; @@ -3483,7 +3658,7 @@ PrepareTransactionBlock(const char *gid) bool result; /* Set up to commit the current transaction */ - result = EndTransactionBlock(); + result = EndTransactionBlock(false); /* If successful, change outer tblock state to PREPARE */ if (result) @@ -3529,7 +3704,7 @@ PrepareTransactionBlock(const char *gid) * resource owner, etc while executing inside a Portal. */ bool -EndTransactionBlock(void) +EndTransactionBlock(bool chain) { TransactionState s = CurrentTransactionState; bool result = false; @@ -3546,13 +3721,21 @@ EndTransactionBlock(void) break; /* - * In an implicit transaction block, commit, but issue a warning + * We are in an implicit transaction block. If AND CHAIN was + * specified, error. Otherwise commit, but issue a warning * because there was no explicit BEGIN before this. */ case TBLOCK_IMPLICIT_INPROGRESS: - ereport(WARNING, - (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), - errmsg("there is no transaction in progress"))); + if (chain) + ereport(ERROR, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + /* translator: %s represents an SQL statement name */ + errmsg("%s can only be used in transaction blocks", + "COMMIT AND CHAIN"))); + else + ereport(WARNING, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + errmsg("there is no transaction in progress"))); s->blockState = TBLOCK_END; result = true; break; @@ -3614,15 +3797,24 @@ EndTransactionBlock(void) break; /* - * The user issued COMMIT when not inside a transaction. Issue a - * WARNING, staying in TBLOCK_STARTED state. The upcoming call to + * The user issued COMMIT when not inside a transaction. For + * COMMIT without CHAIN, issue a WARNING, staying in + * TBLOCK_STARTED state. The upcoming call to * CommitTransactionCommand() will then close the transaction and - * put us back into the default state. + * put us back into the default state. For COMMIT AND CHAIN, + * error. */ case TBLOCK_STARTED: - ereport(WARNING, - (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), - errmsg("there is no transaction in progress"))); + if (chain) + ereport(ERROR, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + /* translator: %s represents an SQL statement name */ + errmsg("%s can only be used in transaction blocks", + "COMMIT AND CHAIN"))); + else + ereport(WARNING, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + errmsg("there is no transaction in progress"))); result = true; break; @@ -3655,6 +3847,13 @@ EndTransactionBlock(void) break; } + Assert(s->blockState == TBLOCK_STARTED || + s->blockState == TBLOCK_END || + s->blockState == TBLOCK_ABORT_END || + s->blockState == TBLOCK_ABORT_PENDING); + + s->chain = chain; + return result; } @@ -3665,7 +3864,7 @@ EndTransactionBlock(void) * As above, we don't actually do anything here except change blockState. */ void -UserAbortTransactionBlock(void) +UserAbortTransactionBlock(bool chain) { TransactionState s = CurrentTransactionState; @@ -3717,10 +3916,10 @@ UserAbortTransactionBlock(void) break; /* - * The user issued ABORT when not inside a transaction. Issue a - * WARNING and go to abort state. The upcoming call to - * CommitTransactionCommand() will then put us back into the - * default state. + * The user issued ABORT when not inside a transaction. For + * ROLLBACK without CHAIN, issue a WARNING and go to abort state. + * The upcoming call to CommitTransactionCommand() will then put + * us back into the default state. For ROLLBACK AND CHAIN, error. * * We do the same thing with ABORT inside an implicit transaction, * although in this case we might be rolling back actual database @@ -3729,9 +3928,16 @@ UserAbortTransactionBlock(void) */ case TBLOCK_STARTED: case TBLOCK_IMPLICIT_INPROGRESS: - ereport(WARNING, - (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), - errmsg("there is no transaction in progress"))); + if (chain) + ereport(ERROR, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + /* translator: %s represents an SQL statement name */ + errmsg("%s can only be used in transaction blocks", + "ROLLBACK AND CHAIN"))); + else + ereport(WARNING, + (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION), + errmsg("there is no transaction in progress"))); s->blockState = TBLOCK_ABORT_PENDING; break; @@ -3763,6 +3969,11 @@ UserAbortTransactionBlock(void) BlockStateAsString(s->blockState)); break; } + + Assert(s->blockState == TBLOCK_ABORT_END || + s->blockState == TBLOCK_ABORT_PENDING); + + s->chain = chain; } /* @@ -4588,7 +4799,7 @@ CommitSubTransaction(void) */ /* Post-commit cleanup */ - if (TransactionIdIsValid(s->transactionId)) + if (FullTransactionIdIsValid(s->fullTransactionId)) AtSubCommit_childXids(); AfterTriggerEndSubXact(true); AtSubCommit_Portals(s->subTransactionId, @@ -4613,8 +4824,8 @@ CommitSubTransaction(void) * The only lock we actually release here is the subtransaction XID lock. */ CurrentResourceOwner = s->curTransactionOwner; - if (TransactionIdIsValid(s->transactionId)) - XactLockTableDelete(s->transactionId); + if (FullTransactionIdIsValid(s->fullTransactionId)) + XactLockTableDelete(XidFromFullTransactionId(s->fullTransactionId)); /* * Other locks should get transferred to their parent resource owner. @@ -4637,6 +4848,7 @@ CommitSubTransaction(void) AtEOSubXact_HashTables(true, s->nestingLevel); AtEOSubXact_PgStat(true, s->nestingLevel); AtSubCommit_Snapshot(s->nestingLevel); + AtEOSubXact_ApplyLauncher(true, s->nestingLevel); /* * We need to restore the upper transaction's read-only state, in case the @@ -4759,7 +4971,7 @@ AbortSubTransaction(void) (void) RecordTransactionAbort(true); /* Post-abort cleanup */ - if (TransactionIdIsValid(s->transactionId)) + if (FullTransactionIdIsValid(s->fullTransactionId)) AtSubAbort_childXids(); CallSubXactCallbacks(SUBXACT_EVENT_ABORT_SUB, s->subTransactionId, @@ -4790,6 +5002,7 @@ AbortSubTransaction(void) AtEOSubXact_HashTables(false, s->nestingLevel); AtEOSubXact_PgStat(false, s->nestingLevel); AtSubAbort_Snapshot(s->nestingLevel); + AtEOSubXact_ApplyLauncher(false, s->nestingLevel); } /* @@ -4871,7 +5084,7 @@ PushTransaction(void) * We can now stack a minimally valid subtransaction without fear of * failure. */ - s->transactionId = InvalidTransactionId; /* until assigned */ + s->fullTransactionId = InvalidFullTransactionId; /* until assigned */ s->subTransactionId = currentSubTransactionId; s->parent = p; s->nestingLevel = p->nestingLevel + 1; @@ -4938,18 +5151,17 @@ Size EstimateTransactionStateSpace(void) { TransactionState s; - Size nxids = 6; /* iso level, deferrable, top & current XID, - * command counter, XID count */ + Size nxids = 0; + Size size = SerializedTransactionStateHeaderSize; for (s = CurrentTransactionState; s != NULL; s = s->parent) { - if (TransactionIdIsValid(s->transactionId)) + if (FullTransactionIdIsValid(s->fullTransactionId)) nxids = add_size(nxids, 1); nxids = add_size(nxids, s->nChildXids); } - nxids = add_size(nxids, nParallelCurrentXids); - return mul_size(nxids, sizeof(TransactionId)); + return add_size(size, mul_size(sizeof(TransactionId), nxids)); } /* @@ -4958,14 +5170,10 @@ EstimateTransactionStateSpace(void) * needed by a parallel worker. * * We need to save and restore XactDeferrable, XactIsoLevel, and the XIDs - * associated with this transaction. The first eight bytes of the result - * contain XactDeferrable and XactIsoLevel; the next twelve bytes contain the - * XID of the top-level transaction, the XID of the current transaction - * (or, in each case, InvalidTransactionId if none), and the current command - * counter. After that, the next 4 bytes contain a count of how many - * additional XIDs follow; this is followed by all of those XIDs one after - * another. We emit the XIDs in sorted order for the convenience of the - * receiving process. + * associated with this transaction. These are serialized into a + * caller-supplied buffer big enough to hold the number of bytes reported by + * EstimateTransactionStateSpace(). We emit the XIDs in sorted order for the + * convenience of the receiving process. */ void SerializeTransactionState(Size maxsize, char *start_address) @@ -4973,16 +5181,17 @@ SerializeTransactionState(Size maxsize, char *start_address) TransactionState s; Size nxids = 0; Size i = 0; - Size c = 0; TransactionId *workspace; - TransactionId *result = (TransactionId *) start_address; + SerializedTransactionState *result; + + result = (SerializedTransactionState *) start_address; - result[c++] = (TransactionId) XactIsoLevel; - result[c++] = (TransactionId) XactDeferrable; - result[c++] = XactTopTransactionId; - result[c++] = CurrentTransactionState->transactionId; - result[c++] = (TransactionId) currentCommandId; - Assert(maxsize >= c * sizeof(TransactionId)); + result->xactIsoLevel = XactIsoLevel; + result->xactDeferrable = XactDeferrable; + result->topFullTransactionId = XactTopFullTransactionId; + result->currentFullTransactionId = + CurrentTransactionState->fullTransactionId; + result->currentCommandId = currentCommandId; /* * If we're running in a parallel worker and launching a parallel worker @@ -4991,9 +5200,8 @@ SerializeTransactionState(Size maxsize, char *start_address) */ if (nParallelCurrentXids > 0) { - result[c++] = nParallelCurrentXids; - Assert(maxsize >= (nParallelCurrentXids + c) * sizeof(TransactionId)); - memcpy(&result[c], ParallelCurrentXids, + result->nParallelCurrentXids = nParallelCurrentXids; + memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids, nParallelCurrentXids * sizeof(TransactionId)); return; } @@ -5004,18 +5212,19 @@ SerializeTransactionState(Size maxsize, char *start_address) */ for (s = CurrentTransactionState; s != NULL; s = s->parent) { - if (TransactionIdIsValid(s->transactionId)) + if (FullTransactionIdIsValid(s->fullTransactionId)) nxids = add_size(nxids, 1); nxids = add_size(nxids, s->nChildXids); } - Assert((c + 1 + nxids) * sizeof(TransactionId) <= maxsize); + Assert(SerializedTransactionStateHeaderSize + nxids * sizeof(TransactionId) + <= maxsize); /* Copy them to our scratch space. */ workspace = palloc(nxids * sizeof(TransactionId)); for (s = CurrentTransactionState; s != NULL; s = s->parent) { - if (TransactionIdIsValid(s->transactionId)) - workspace[i++] = s->transactionId; + if (FullTransactionIdIsValid(s->fullTransactionId)) + workspace[i++] = XidFromFullTransactionId(s->fullTransactionId); memcpy(&workspace[i], s->childXids, s->nChildXids * sizeof(TransactionId)); i += s->nChildXids; @@ -5026,8 +5235,9 @@ SerializeTransactionState(Size maxsize, char *start_address) qsort(workspace, nxids, sizeof(TransactionId), xidComparator); /* Copy data into output area. */ - result[c++] = (TransactionId) nxids; - memcpy(&result[c], workspace, nxids * sizeof(TransactionId)); + result->nParallelCurrentXids = nxids; + memcpy(&result->parallelCurrentXids[0], workspace, + nxids * sizeof(TransactionId)); } /* @@ -5038,18 +5248,20 @@ SerializeTransactionState(Size maxsize, char *start_address) void StartParallelWorkerTransaction(char *tstatespace) { - TransactionId *tstate = (TransactionId *) tstatespace; + SerializedTransactionState *tstate; Assert(CurrentTransactionState->blockState == TBLOCK_DEFAULT); StartTransaction(); - XactIsoLevel = (int) tstate[0]; - XactDeferrable = (bool) tstate[1]; - XactTopTransactionId = tstate[2]; - CurrentTransactionState->transactionId = tstate[3]; - currentCommandId = tstate[4]; - nParallelCurrentXids = (int) tstate[5]; - ParallelCurrentXids = &tstate[6]; + tstate = (SerializedTransactionState *) tstatespace; + XactIsoLevel = tstate->xactIsoLevel; + XactDeferrable = tstate->xactDeferrable; + XactTopFullTransactionId = tstate->topFullTransactionId; + CurrentTransactionState->fullTransactionId = + tstate->currentFullTransactionId; + currentCommandId = tstate->currentCommandId; + nParallelCurrentXids = tstate->nParallelCurrentXids; + ParallelCurrentXids = &tstate->parallelCurrentXids[0]; CurrentTransactionState->blockState = TBLOCK_PARALLEL_INPROGRESS; } @@ -5108,7 +5320,7 @@ ShowTransactionStateRec(const char *str, TransactionState s) PointerIsValid(s->name) ? s->name : "unnamed", BlockStateAsString(s->blockState), TransStateAsString(s->state), - (unsigned int) s->transactionId, + (unsigned int) XidFromFullTransactionId(s->fullTransactionId), (unsigned int) s->subTransactionId, (unsigned int) currentCommandId, currentCommandIdUsed ? " (used)" : "", @@ -5245,9 +5457,7 @@ XactLogCommitRecord(TimestampTz commit_time, xl_xact_invals xl_invals; xl_xact_twophase xl_twophase; xl_xact_origin xl_origin; - uint8 info; - int gidlen = 0; Assert(CritSectionCount > 0); @@ -5313,10 +5523,7 @@ XactLogCommitRecord(TimestampTz commit_time, Assert(twophase_gid != NULL); if (XLogLogicalInfoActive()) - { xl_xinfo.xinfo |= XACT_XINFO_HAS_GID; - gidlen = strlen(twophase_gid) + 1; /* include '\0' */ - } } /* dump transaction origin information */ @@ -5370,12 +5577,7 @@ XactLogCommitRecord(TimestampTz commit_time, { XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase)); if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID) - { - static const char zeroes[MAXIMUM_ALIGNOF] = { 0 }; - XLogRegisterData((char*) twophase_gid, gidlen); - if (MAXALIGN(gidlen) != gidlen) - XLogRegisterData((char*) zeroes, MAXALIGN(gidlen) - gidlen); - } + XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1); } if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN) @@ -5409,7 +5611,6 @@ XactLogAbortRecord(TimestampTz abort_time, xl_xact_origin xl_origin; uint8 info; - int gidlen = 0; Assert(CritSectionCount > 0); @@ -5448,10 +5649,7 @@ XactLogAbortRecord(TimestampTz abort_time, Assert(twophase_gid != NULL); if (XLogLogicalInfoActive()) - { xl_xinfo.xinfo |= XACT_XINFO_HAS_GID; - gidlen = strlen(twophase_gid) + 1; /* include '\0' */ - } } if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive()) @@ -5462,9 +5660,9 @@ XactLogAbortRecord(TimestampTz abort_time, } /* dump transaction origin information only for abort prepared */ - if ( (replorigin_session_origin != InvalidRepOriginId) && - TransactionIdIsValid(twophase_xid) && - XLogLogicalInfoActive()) + if ((replorigin_session_origin != InvalidRepOriginId) && + TransactionIdIsValid(twophase_xid) && + XLogLogicalInfoActive()) { xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN; @@ -5487,7 +5685,6 @@ XactLogAbortRecord(TimestampTz abort_time, if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO) XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo)); - if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS) { XLogRegisterData((char *) (&xl_subxacts), @@ -5508,12 +5705,7 @@ XactLogAbortRecord(TimestampTz abort_time, { XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase)); if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID) - { - static const char zeroes[MAXIMUM_ALIGNOF] = { 0 }; - XLogRegisterData((char*) twophase_gid, gidlen); - if (MAXALIGN(gidlen) != gidlen) - XLogRegisterData((char*) zeroes, MAXALIGN(gidlen) - gidlen); - } + XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1); } if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN) @@ -5536,28 +5728,14 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, RepOriginId origin_id) { TransactionId max_xid; - int i; TimestampTz commit_time; Assert(TransactionIdIsValid(xid)); max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts); - /* - * Make sure nextXid is beyond any XID mentioned in the record. - * - * We don't expect anyone else to modify nextXid, hence we don't need to - * hold a lock while checking this. We still acquire the lock to modify - * it, though. - */ - if (TransactionIdFollowsOrEquals(max_xid, - ShmemVariableCache->nextXid)) - { - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = max_xid; - TransactionIdAdvance(ShmemVariableCache->nextXid); - LWLockRelease(XidGenLock); - } + /* Make sure nextFullXid is beyond any XID mentioned in the record. */ + AdvanceNextFullTransactionIdPastXid(max_xid); Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) == (origin_id == InvalidRepOriginId)); @@ -5622,12 +5800,10 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, /* * Release locks, if any. We do this for both two phase and normal one * phase transactions. In effect we are ignoring the prepare phase and - * just going straight to lock release. At commit we release all locks - * via their top-level xid only, so no need to provide subxact list, - * which will save time when replaying commits. + * just going straight to lock release. */ if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS) - StandbyReleaseLockTree(xid, 0, NULL); + StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts); } if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) @@ -5657,16 +5833,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, */ XLogFlush(lsn); - for (i = 0; i < parsed->nrels; i++) - { - SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - XLogDropRelation(parsed->xnodes[i], fork); - smgrdounlink(srel, true); - smgrclose(srel); - } + /* Make sure files supposed to be dropped are dropped */ + DropRelationFiles(parsed->xnodes, parsed->nrels, true); } /* @@ -5705,30 +5873,15 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) { - int i; TransactionId max_xid; Assert(TransactionIdIsValid(xid)); - /* - * Make sure nextXid is beyond any XID mentioned in the record. - * - * We don't expect anyone else to modify nextXid, hence we don't need to - * hold a lock while checking this. We still acquire the lock to modify - * it, though. - */ + /* Make sure nextFullXid is beyond any XID mentioned in the record. */ max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts); - - if (TransactionIdFollowsOrEquals(max_xid, - ShmemVariableCache->nextXid)) - { - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = max_xid; - TransactionIdAdvance(ShmemVariableCache->nextXid); - LWLockRelease(XidGenLock); - } + AdvanceNextFullTransactionIdPastXid(max_xid); if (standbyState == STANDBY_DISABLED) { @@ -5758,8 +5911,7 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) xid, parsed->nsubxacts, parsed->subxacts, max_xid); /* - * There are no flat files that need updating, nor invalidation - * messages to send or undo. + * There are no invalidation messages to send or undo. */ /* @@ -5770,16 +5922,7 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) } /* Make sure files supposed to be dropped are dropped */ - for (i = 0; i < parsed->nrels; i++) - { - SMgrRelation srel = smgropen(parsed->xnodes[i], InvalidBackendId); - ForkNumber fork; - - for (fork = 0; fork <= MAX_FORKNUM; fork++) - XLogDropRelation(parsed->xnodes[i], fork); - smgrdounlink(srel, true); - smgrclose(srel); - } + DropRelationFiles(parsed->xnodes, parsed->nrels, true); } void diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a51df6b0b90..543087cd8f0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -4,7 +4,7 @@ * PostgreSQL write-ahead log manager * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlog.c @@ -24,12 +24,12 @@ #include "access/clog.h" #include "access/commit_ts.h" +#include "access/heaptoast.h" #include "access/multixact.h" #include "access/rewriteheap.h" #include "access/subtrans.h" #include "access/timeline.h" #include "access/transam.h" -#include "access/tuptoaster.h" #include "access/twophase.h" #include "access/xact.h" #include "access/xlog_internal.h" @@ -40,11 +40,13 @@ #include "catalog/pg_control.h" #include "catalog/pg_database.h" #include "commands/tablespace.h" +#include "common/controldata_utils.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" #include "postmaster/bgwriter.h" #include "postmaster/walwriter.h" +#include "postmaster/postmaster.h" #include "postmaster/startup.h" #include "replication/basebackup.h" #include "replication/logical.h" @@ -65,11 +67,10 @@ #include "storage/reinit.h" #include "storage/smgr.h" #include "storage/spin.h" -#include "utils/backend_random.h" +#include "storage/sync.h" #include "utils/builtins.h" #include "utils/guc.h" #include "utils/memutils.h" -#include "utils/pg_lsn.h" #include "utils/ps_status.h" #include "utils/relmapper.h" #include "utils/snapmgr.h" @@ -78,12 +79,9 @@ extern uint32 bootstrap_data_checksum_version; -/* File path names (all relative to $PGDATA) */ +/* Unsupported old recovery command file names (relative to $PGDATA) */ #define RECOVERY_COMMAND_FILE "recovery.conf" #define RECOVERY_COMMAND_DONE "recovery.done" -#define PROMOTE_SIGNAL_FILE "promote" -#define FALLBACK_PROMOTE_SIGNAL_FILE "fallback_promote" - /* User-settable parameters */ int max_wal_size_mb = 1024; /* 1 GB */ @@ -99,6 +97,8 @@ bool wal_log_hints = false; bool wal_compression = false; char *wal_consistency_checking_string = NULL; bool *wal_consistency_checking = NULL; +bool wal_init_zero = true; +bool wal_recycle = true; bool log_checkpoints = false; int sync_method = DEFAULT_SYNC_METHOD; int wal_level = WAL_LEVEL_MINIMAL; @@ -167,6 +167,13 @@ const struct config_enum_entry archive_mode_options[] = { {NULL, 0, false} }; +const struct config_enum_entry recovery_target_action_options[] = { + {"pause", RECOVERY_TARGET_ACTION_PAUSE, false}, + {"promote", RECOVERY_TARGET_ACTION_PROMOTE, false}, + {"shutdown", RECOVERY_TARGET_ACTION_SHUTDOWN, false}, + {NULL, 0, false} +}; + /* * Statistics for current checkpoint are collected in this global struct. * Because only the checkpointer or a stand-alone backend can perform @@ -236,7 +243,7 @@ static int LocalXLogInsertAllowed = -1; /* * When ArchiveRecoveryRequested is set, archive recovery was requested, - * ie. recovery.conf file was present. When InArchiveRecovery is set, we are + * ie. signal files were present. When InArchiveRecovery is set, we are * currently recovering using offline XLOG archives. These variables are only * valid in the startup process. * @@ -248,6 +255,9 @@ static int LocalXLogInsertAllowed = -1; bool ArchiveRecoveryRequested = false; bool InArchiveRecovery = false; +static bool standby_signal_file_found = false; +static bool recovery_signal_file_found = false; + /* Was the last xlog file restored from archive, or local? */ static bool restoredFromArchive = false; @@ -255,25 +265,26 @@ static bool restoredFromArchive = false; static char *replay_image_masked = NULL; static char *master_image_masked = NULL; -/* options taken from recovery.conf for archive recovery */ +/* options formerly taken from recovery.conf for archive recovery */ char *recoveryRestoreCommand = NULL; -static char *recoveryEndCommand = NULL; -static char *archiveCleanupCommand = NULL; -static RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET; -static bool recoveryTargetInclusive = true; -static RecoveryTargetAction recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE; -static TransactionId recoveryTargetXid; +char *recoveryEndCommand = NULL; +char *archiveCleanupCommand = NULL; +RecoveryTargetType recoveryTarget = RECOVERY_TARGET_UNSET; +bool recoveryTargetInclusive = true; +int recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE; +TransactionId recoveryTargetXid; +char *recovery_target_time_string; static TimestampTz recoveryTargetTime; -static char *recoveryTargetName; -static XLogRecPtr recoveryTargetLSN; -static int recovery_min_apply_delay = 0; -static TimestampTz recoveryDelayUntilTime; +const char *recoveryTargetName; +XLogRecPtr recoveryTargetLSN; +int recovery_min_apply_delay = 0; +TimestampTz recoveryDelayUntilTime; -/* options taken from recovery.conf for XLOG streaming */ -static bool StandbyModeRequested = false; -static char *PrimaryConnInfo = NULL; -static char *PrimarySlotName = NULL; -static char *TriggerFile = NULL; +/* options formerly taken from recovery.conf for XLOG streaming */ +bool StandbyModeRequested = false; +char *PrimaryConnInfo = NULL; +char *PrimarySlotName = NULL; +char *PromoteTriggerFile = NULL; /* are we currently in standby mode? */ bool StandbyMode = false; @@ -299,9 +310,11 @@ static bool recoveryStopAfter; * the currently-scanned WAL record was generated). We also need these * timeline values: * - * recoveryTargetTLI: the desired timeline that we want to end in. + * recoveryTargetTimeLineGoal: what the user requested, if any + * + * recoveryTargetTLIRequested: numeric value of requested timeline, if constant * - * recoveryTargetIsLatest: was the requested target timeline 'latest'? + * recoveryTargetTLI: the currently understood target timeline; changes * * expectedTLEs: a list of TimeLineHistoryEntries for recoveryTargetTLI and the timelines of * its known parents, newest first (so recoveryTargetTLI is always the @@ -315,8 +328,9 @@ static bool recoveryStopAfter; * file was created.) During a sequential scan we do not allow this value * to decrease. */ -static TimeLineID recoveryTargetTLI; -static bool recoveryTargetIsLatest = false; +RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal = RECOVERY_TARGET_TIMELINE_LATEST; +TimeLineID recoveryTargetTLIRequested = 0; +TimeLineID recoveryTargetTLI = 0; static List *expectedTLEs; static TimeLineID curFileTLI; @@ -579,8 +593,7 @@ typedef struct XLogCtlData /* Protected by info_lck: */ XLogwrtRqst LogwrtRqst; XLogRecPtr RedoRecPtr; /* a recent copy of Insert->RedoRecPtr */ - uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */ - TransactionId ckptXid; + FullTransactionId ckptFullXid; /* nextFullXid of latest checkpoint */ XLogRecPtr asyncXactLSN; /* LSN of newest async commit/abort */ XLogRecPtr replicationSlotMinLSN; /* oldest LSN needed by any slot */ @@ -614,7 +627,7 @@ typedef struct XLogCtlData /* * These values do not change after startup, although the pointed-to pages - * and xlblocks values certainly do. xlblock values are protected by + * and xlblocks values certainly do. xlblocks values are protected by * WALBufMappingLock. */ char *pages; /* buffers for unwritten XLOG pages */ @@ -630,12 +643,6 @@ typedef struct XLogCtlData TimeLineID ThisTimeLineID; TimeLineID PrevTimeLineID; - /* - * archiveCleanupCommand is read from recovery.conf but needs to be in - * shared memory so that the checkpointer process can access it. - */ - char archiveCleanupCommand[MAXPGPATH]; - /* * SharedRecoveryInProgress indicates if we're still in crash or archive * recovery. Protected by info_lck. @@ -737,7 +744,7 @@ static ControlFileData *ControlFile = NULL; */ #define UsableBytesInPage (XLOG_BLCKSZ - SizeOfXLogShortPHD) -/* Convert min_wal_size_mb and max wal_size_mb to equivalent segment count */ +/* Convert min_wal_size_mb and max_wal_size_mb to equivalent segment count */ #define ConvertToXSegs(x, segsize) \ (x / ((segsize) / (1024 * 1024))) @@ -763,17 +770,15 @@ typedef enum } XLogSource; /* human-readable names for XLogSources, for debugging output */ -static const char *xlogSourceNames[] = {"any", "archive", "pg_wal", "stream"}; +static const char *const xlogSourceNames[] = {"any", "archive", "pg_wal", "stream"}; /* * openLogFile is -1 or a kernel FD for an open log file segment. - * When it's open, openLogOff is the current seek offset in the file. - * openLogSegNo identifies the segment. These variables are only - * used to write the XLOG, and so will normally refer to the active segment. + * openLogSegNo identifies the segment. These variables are only used to + * write the XLOG, and so will normally refer to the active segment. */ static int openLogFile = -1; static XLogSegNo openLogSegNo = 0; -static uint32 openLogOff = 0; /* * These variables are used similarly to the ones above, but for reading @@ -821,8 +826,14 @@ static XLogSource XLogReceiptSource = 0; /* XLOG_FROM_* code */ static XLogRecPtr ReadRecPtr; /* start of last record read */ static XLogRecPtr EndRecPtr; /* end+1 of last record read */ -static XLogRecPtr minRecoveryPoint; /* local copy of - * ControlFile->minRecoveryPoint */ +/* + * Local copies of equivalent fields in the control file. When running + * crash recovery, minRecoveryPoint is set to InvalidXLogRecPtr as we + * expect to replay all the WAL available, and updateMinRecoveryPoint is + * switched to false to prevent any updates while replaying records. + * Those values are kept consistent as long as crash recovery runs. + */ +static XLogRecPtr minRecoveryPoint; static TimeLineID minRecoveryPointTLI; static bool updateMinRecoveryPoint = true; @@ -846,7 +857,8 @@ static bool holdingAllLocks = false; static MemoryContext walDebugCxt = NULL; #endif -static void readRecoveryCommandFile(void); +static void readRecoverySignalFile(void); +static void validateRecoveryParameters(void); static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog); static bool recoveryStopsBefore(XLogReaderState *record); static bool recoveryStopsAfter(XLogReaderState *record); @@ -857,7 +869,7 @@ static void SetCurrentChunkStartTime(TimestampTz xtime); static void CheckRequiredParameterValues(void); static void XLogReportParameters(void); static void checkTimeLineSwitch(XLogRecPtr lsn, TimeLineID newTLI, - TimeLineID prevTLI); + TimeLineID prevTLI); static void LocalSetXLogInsertAllowed(void); static void CreateEndOfRecoveryRecord(void); static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); @@ -868,30 +880,30 @@ static void AdvanceXLInsertBuffer(XLogRecPtr upto, bool opportunistic); static bool XLogCheckpointNeeded(XLogSegNo new_segno); static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible); static bool InstallXLogFileSegment(XLogSegNo *segno, char *tmppath, - bool find_free, XLogSegNo max_segno, - bool use_lock); -static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli, - int source, bool notfoundOk); + bool find_free, XLogSegNo max_segno, + bool use_lock); +static int XLogFileRead(XLogSegNo segno, int emode, TimeLineID tli, + int source, bool notfoundOk); static int XLogFileReadAnyTLI(XLogSegNo segno, int emode, int source); -static int XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, char *readBuf, - TimeLineID *readTLI); +static int XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, + int reqLen, XLogRecPtr targetRecPtr, char *readBuf); static bool WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, - bool fetching_ckpt, XLogRecPtr tliRecPtr); + bool fetching_ckpt, XLogRecPtr tliRecPtr); static int emode_for_corrupt_record(int emode, XLogRecPtr RecPtr); static void XLogFileClose(void); static void PreallocXlogFiles(XLogRecPtr endptr); -static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr); -static void RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr); +static void RemoveTempXlogFiles(void); +static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr); +static void RemoveXlogFile(const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr); static void UpdateLastRemovedPtr(char *filename); static void ValidateXLOGDirectoryStructure(void); static void CleanupBackupHistory(void); static void UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force); static XLogRecord *ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, - int emode, bool fetching_ckpt); + int emode, bool fetching_ckpt); static void CheckRecoveryConsistency(void); static XLogRecord *ReadCheckpointRecord(XLogReaderState *xlogreader, - XLogRecPtr RecPtr, int whichChkpti, bool report); + XLogRecPtr RecPtr, int whichChkpt, bool report); static bool rescanLatestTimeLine(void); static void WriteControlFile(void); static void ReadControlFile(void); @@ -905,19 +917,19 @@ static void xlog_outdesc(StringInfo buf, XLogReaderState *record); static void pg_start_backup_callback(int code, Datum arg); static void pg_stop_backup_callback(int code, Datum arg); static bool read_backup_label(XLogRecPtr *checkPointLoc, - bool *backupEndRequired, bool *backupFromStandby); + bool *backupEndRequired, bool *backupFromStandby); static bool read_tablespace_map(List **tablespaces); static void rm_redo_error_callback(void *arg); static int get_sync_bit(int method); static void CopyXLogRecordToWAL(int write_len, bool isLogSwitch, - XLogRecData *rdata, - XLogRecPtr StartPos, XLogRecPtr EndPos); + XLogRecData *rdata, + XLogRecPtr StartPos, XLogRecPtr EndPos); static void ReserveXLogInsertLocation(int size, XLogRecPtr *StartPos, - XLogRecPtr *EndPos, XLogRecPtr *PrevPtr); + XLogRecPtr *EndPos, XLogRecPtr *PrevPtr); static bool ReserveXLogSwitch(XLogRecPtr *StartPos, XLogRecPtr *EndPos, - XLogRecPtr *PrevPtr); + XLogRecPtr *PrevPtr); static XLogRecPtr WaitXLogInsertionsToFinish(XLogRecPtr upto); static char *GetXLogBuffer(XLogRecPtr ptr); static XLogRecPtr XLogBytePosToRecPtr(uint64 bytepos); @@ -937,7 +949,7 @@ static void WALInsertLockUpdateInsertingAt(XLogRecPtr insertingAt); * * If 'fpw_lsn' is valid, it is the oldest LSN among the pages that this * WAL record applies to, that were not included in the record as full page - * images. If fpw_lsn >= RedoRecPtr, the function does not perform the + * images. If fpw_lsn <= RedoRecPtr, the function does not perform the * insertion and returns InvalidXLogRecPtr. The caller can then recalculate * which pages need a full-page image, and retry. If fpw_lsn is invalid, the * record is always inserted. @@ -970,6 +982,7 @@ XLogInsertRecord(XLogRecData *rdata, info == XLOG_SWITCH); XLogRecPtr StartPos; XLogRecPtr EndPos; + bool prevDoPageWrites = doPageWrites; /* we assume that all of the record header is in the first chunk */ Assert(rdata->len >= SizeOfXLogRecord); @@ -1017,10 +1030,14 @@ XLogInsertRecord(XLogRecData *rdata, WALInsertLockAcquire(); /* - * Check to see if my copy of RedoRecPtr or doPageWrites is out of date. - * If so, may have to go back and have the caller recompute everything. - * This can only happen just after a checkpoint, so it's better to be slow - * in this case and fast otherwise. + * Check to see if my copy of RedoRecPtr is out of date. If so, may have + * to go back and have the caller recompute everything. This can only + * happen just after a checkpoint, so it's better to be slow in this case + * and fast otherwise. + * + * Also check to see if fullPageWrites or forcePageWrites was just turned + * on; if we weren't already doing full-page writes then go back and + * recompute. * * If we aren't doing full-page writes then RedoRecPtr doesn't actually * affect the contents of the XLOG record, so we'll update our local copy @@ -1035,7 +1052,9 @@ XLogInsertRecord(XLogRecData *rdata, } doPageWrites = (Insert->fullPageWrites || Insert->forcePageWrites); - if (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr && doPageWrites) + if (doPageWrites && + (!prevDoPageWrites || + (fpw_lsn != InvalidXLogRecPtr && fpw_lsn <= RedoRecPtr))) { /* * Oops, some buffer now needs to be backed up that the caller didn't @@ -1176,7 +1195,8 @@ XLogInsertRecord(XLogRecData *rdata, appendBinaryStringInfo(&recordBuf, rdata->data, rdata->len); if (!debug_reader) - debug_reader = XLogReaderAllocate(wal_segment_size, NULL, NULL); + debug_reader = XLogReaderAllocate(wal_segment_size, NULL, + NULL, NULL); if (!debug_reader) { @@ -1777,11 +1797,11 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto) do { /* - * See if this insertion is in progress. LWLockWait will wait for - * the lock to be released, or for the 'value' to be set by a - * LWLockUpdateVar call. When a lock is initially acquired, its - * value is 0 (InvalidXLogRecPtr), which means that we don't know - * where it's inserting yet. We will have to wait for it. If + * See if this insertion is in progress. LWLockWaitForVar will + * wait for the lock to be released, or for the 'value' to be set + * by a LWLockUpdateVar call. When a lock is initially acquired, + * its value is 0 (InvalidXLogRecPtr), which means that we don't + * know where it's inserting yet. We will have to wait for it. If * it's a small insertion, the record will most likely fit on the * same page and the inserter will release the lock without ever * calling LWLockUpdateVar. But if it has to sleep, it will @@ -1965,7 +1985,7 @@ XLogBytePosToRecPtr(uint64 bytepos) seg_offset += fullpages * XLOG_BLCKSZ + bytesleft + SizeOfXLogShortPHD; } - XLogSegNoOffsetToRecPtr(fullsegs, seg_offset, result, wal_segment_size); + XLogSegNoOffsetToRecPtr(fullsegs, seg_offset, wal_segment_size, result); return result; } @@ -2011,7 +2031,7 @@ XLogBytePosToEndRecPtr(uint64 bytepos) seg_offset += fullpages * XLOG_BLCKSZ + bytesleft + SizeOfXLogShortPHD; } - XLogSegNoOffsetToRecPtr(fullsegs, seg_offset, result, wal_segment_size); + XLogSegNoOffsetToRecPtr(fullsegs, seg_offset, wal_segment_size, result); return result; } @@ -2280,7 +2300,7 @@ assign_checkpoint_completion_target(double newval, void *extra) * XLOG segments? Returns the highest segment that should be preallocated. */ static XLogSegNo -XLOGfileslop(XLogRecPtr PriorRedoPtr) +XLOGfileslop(XLogRecPtr RedoRecPtr) { XLogSegNo minSegNo; XLogSegNo maxSegNo; @@ -2292,9 +2312,9 @@ XLOGfileslop(XLogRecPtr PriorRedoPtr) * correspond to. Always recycle enough segments to meet the minimum, and * remove enough segments to stay below the maximum. */ - minSegNo = PriorRedoPtr / wal_segment_size + + minSegNo = RedoRecPtr / wal_segment_size + ConvertToXSegs(min_wal_size_mb, wal_segment_size) - 1; - maxSegNo = PriorRedoPtr / wal_segment_size + + maxSegNo = RedoRecPtr / wal_segment_size + ConvertToXSegs(max_wal_size_mb, wal_segment_size) - 1; /* @@ -2309,7 +2329,7 @@ XLOGfileslop(XLogRecPtr PriorRedoPtr) /* add 10% for good measure. */ distance *= 1.10; - recycleSegNo = (XLogSegNo) ceil(((double) PriorRedoPtr + distance) / + recycleSegNo = (XLogSegNo) ceil(((double) RedoRecPtr + distance) / wal_segment_size); if (recycleSegNo < minSegNo) @@ -2428,7 +2448,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) /* create/use new log file */ use_existent = true; openLogFile = XLogFileInit(openLogSegNo, &use_existent, true); - openLogOff = 0; } /* Make sure we have the current logfile open */ @@ -2437,7 +2456,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) XLByteToPrevSeg(LogwrtResult.Write, openLogSegNo, wal_segment_size); openLogFile = XLogFileOpen(openLogSegNo); - openLogOff = 0; } /* Add current page to the set of pending pages-to-dump */ @@ -2470,18 +2488,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) Size nleft; int written; - /* Need to seek in the file? */ - if (openLogOff != startoffset) - { - if (lseek(openLogFile, (off_t) startoffset, SEEK_SET) < 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not seek in log file %s to offset %u: %m", - XLogFileNameP(ThisTimeLineID, openLogSegNo), - startoffset))); - openLogOff = startoffset; - } - /* OK to write the page(s) */ from = XLogCtl->pages + startidx * (Size) XLOG_BLCKSZ; nbytes = npages * (Size) XLOG_BLCKSZ; @@ -2490,7 +2496,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) { errno = 0; pgstat_report_wait_start(WAIT_EVENT_WAL_WRITE); - written = write(openLogFile, from, nleft); + written = pg_pwrite(openLogFile, from, nleft, startoffset); pgstat_report_wait_end(); if (written <= 0) { @@ -2501,14 +2507,13 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) errmsg("could not write to log file %s " "at offset %u, length %zu: %m", XLogFileNameP(ThisTimeLineID, openLogSegNo), - openLogOff, nbytes))); + startoffset, nleft))); } nleft -= written; from += written; + startoffset += written; } while (nleft > 0); - /* Update state for write */ - openLogOff += nbytes; npages = 0; /* @@ -2594,7 +2599,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) XLByteToPrevSeg(LogwrtResult.Write, openLogSegNo, wal_segment_size); openLogFile = XLogFileOpen(openLogSegNo); - openLogOff = 0; } issue_xlog_fsync(openLogFile, openLogSegNo); @@ -2711,18 +2715,30 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) if (!updateMinRecoveryPoint || (!force && lsn <= minRecoveryPoint)) return; + /* + * An invalid minRecoveryPoint means that we need to recover all the WAL, + * i.e., we're doing crash recovery. We never modify the control file's + * value in that case, so we can short-circuit future checks here too. The + * local values of minRecoveryPoint and minRecoveryPointTLI should not be + * updated until crash recovery finishes. We only do this for the startup + * process as it should not update its own reference of minRecoveryPoint + * until it has finished crash recovery to make sure that all WAL + * available is replayed in this case. This also saves from extra locks + * taken on the control file from the startup process. + */ + if (XLogRecPtrIsInvalid(minRecoveryPoint) && InRecovery) + { + updateMinRecoveryPoint = false; + return; + } + LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); /* update local copy */ minRecoveryPoint = ControlFile->minRecoveryPoint; minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; - /* - * An invalid minRecoveryPoint means that we need to recover all the WAL, - * i.e., we're doing crash recovery. We never modify the control file's - * value in that case, so we can short-circuit future checks here too. - */ - if (minRecoveryPoint == 0) + if (XLogRecPtrIsInvalid(minRecoveryPoint)) updateMinRecoveryPoint = false; else if (force || minRecoveryPoint < lsn) { @@ -3034,9 +3050,9 @@ XLogBackgroundFlush(void) else if (TimestampDifferenceExceeds(lastflush, now, WalWriterDelay)) { /* - * Flush the writes at least every WalWriteDelay ms. This is important - * to bound the amount of time it takes for an asynchronous commit to - * hit disk. + * Flush the writes at least every WalWriterDelay ms. This is + * important to bound the amount of time it takes for an asynchronous + * commit to hit disk. */ WriteRqst.Flush = WriteRqst.Write; lastflush = now; @@ -3110,7 +3126,18 @@ XLogNeedsFlush(XLogRecPtr record) */ if (RecoveryInProgress()) { - /* Quick exit if already known updated */ + /* + * An invalid minRecoveryPoint means that we need to recover all the + * WAL, i.e., we're doing crash recovery. We never modify the control + * file's value in that case, so we can short-circuit future checks + * here too. This triggers a quick exit path for the startup process, + * which cannot update its local copy of minRecoveryPoint as long as + * it has not replayed all WAL available when doing crash recovery. + */ + if (XLogRecPtrIsInvalid(minRecoveryPoint) && InRecovery) + updateMinRecoveryPoint = false; + + /* Quick exit if already known to be updated or cannot be updated */ if (record <= minRecoveryPoint || !updateMinRecoveryPoint) return false; @@ -3125,12 +3152,11 @@ XLogNeedsFlush(XLogRecPtr record) LWLockRelease(ControlFileLock); /* - * An invalid minRecoveryPoint means that we need to recover all the - * WAL, i.e., we're doing crash recovery. We never modify the control - * file's value in that case, so we can short-circuit future checks - * here too. + * Check minRecoveryPoint for any other process than the startup + * process doing crash recovery, which should not update the control + * file value if crash recovery is still running. */ - if (minRecoveryPoint == 0) + if (XLogRecPtrIsInvalid(minRecoveryPoint)) updateMinRecoveryPoint = false; /* check again */ @@ -3181,12 +3207,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) { char path[MAXPGPATH]; char tmppath[MAXPGPATH]; - char zbuffer_raw[XLOG_BLCKSZ + MAXIMUM_ALIGNOF]; - char *zbuffer; + PGAlignedXLogBlock zbuffer; XLogSegNo installed_segno; XLogSegNo max_segno; int fd; int nbytes; + int save_errno; XLogFilePath(path, ThisTimeLineID, logsegno, wal_segment_size); @@ -3226,56 +3252,77 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", tmppath))); - /* - * Zero-fill the file. We have to do this the hard way to ensure that all - * the file space has really been allocated --- on platforms that allow - * "holes" in files, just seeking to the end doesn't allocate intermediate - * space. This way, we know that we have all the space and (after the - * fsync below) that all the indirect blocks are down on disk. Therefore, - * fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the - * log file. - * - * Note: ensure the buffer is reasonably well-aligned; this may save a few - * cycles transferring data to the kernel. - */ - zbuffer = (char *) MAXALIGN(zbuffer_raw); - memset(zbuffer, 0, XLOG_BLCKSZ); - for (nbytes = 0; nbytes < wal_segment_size; nbytes += XLOG_BLCKSZ) + memset(zbuffer.data, 0, XLOG_BLCKSZ); + + pgstat_report_wait_start(WAIT_EVENT_WAL_INIT_WRITE); + save_errno = 0; + if (wal_init_zero) + { + /* + * Zero-fill the file. With this setting, we do this the hard way to + * ensure that all the file space has really been allocated. On + * platforms that allow "holes" in files, just seeking to the end + * doesn't allocate intermediate space. This way, we know that we + * have all the space and (after the fsync below) that all the + * indirect blocks are down on disk. Therefore, fdatasync(2) or + * O_DSYNC will be sufficient to sync future writes to the log file. + */ + for (nbytes = 0; nbytes < wal_segment_size; nbytes += XLOG_BLCKSZ) + { + errno = 0; + if (write(fd, zbuffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ) + { + /* if write didn't set errno, assume no disk space */ + save_errno = errno ? errno : ENOSPC; + break; + } + } + } + else { + /* + * Otherwise, seeking to the end and writing a solitary byte is + * enough. + */ errno = 0; - pgstat_report_wait_start(WAIT_EVENT_WAL_INIT_WRITE); - if ((int) write(fd, zbuffer, XLOG_BLCKSZ) != (int) XLOG_BLCKSZ) + if (pg_pwrite(fd, zbuffer.data, 1, wal_segment_size - 1) != 1) { - int save_errno = errno; + /* if write didn't set errno, assume no disk space */ + save_errno = errno ? errno : ENOSPC; + } + } + pgstat_report_wait_end(); - /* - * If we fail to make the file, delete it to release disk space - */ - unlink(tmppath); + if (save_errno) + { + /* + * If we fail to make the file, delete it to release disk space + */ + unlink(tmppath); - close(fd); + close(fd); - /* if write didn't set errno, assume problem is no disk space */ - errno = save_errno ? save_errno : ENOSPC; + errno = save_errno; - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not write to file \"%s\": %m", tmppath))); - } - pgstat_report_wait_end(); + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not write to file \"%s\": %m", tmppath))); } pgstat_report_wait_start(WAIT_EVENT_WAL_INIT_SYNC); if (pg_fsync(fd) != 0) { + int save_errno = errno; + close(fd); + errno = save_errno; ereport(ERROR, (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", tmppath))); } pgstat_report_wait_end(); - if (close(fd)) + if (close(fd) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", tmppath))); @@ -3348,7 +3395,7 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, { char path[MAXPGPATH]; char tmppath[MAXPGPATH]; - char buffer[XLOG_BLCKSZ]; + PGAlignedXLogBlock buffer; int srcfd; int fd; int nbytes; @@ -3391,31 +3438,34 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, * zeros. */ if (nread < sizeof(buffer)) - memset(buffer, 0, sizeof(buffer)); + memset(buffer.data, 0, sizeof(buffer)); if (nread > 0) { + int r; + if (nread > sizeof(buffer)) nread = sizeof(buffer); - errno = 0; pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_READ); - if (read(srcfd, buffer, nread) != nread) + r = read(srcfd, buffer.data, nread); + if (r != nread) { - if (errno != 0) + if (r < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", path))); else ereport(ERROR, - (errmsg("not enough data in file \"%s\"", - path))); + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, r, (Size) nread))); } pgstat_report_wait_end(); } errno = 0; pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_WRITE); - if ((int) write(fd, buffer, sizeof(buffer)) != (int) sizeof(buffer)) + if ((int) write(fd, buffer.data, sizeof(buffer)) != (int) sizeof(buffer)) { int save_errno = errno; @@ -3435,17 +3485,20 @@ XLogFileCopy(XLogSegNo destsegno, TimeLineID srcTLI, XLogSegNo srcsegno, pgstat_report_wait_start(WAIT_EVENT_WAL_COPY_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", tmppath))); pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", tmppath))); - CloseTransientFile(srcfd); + if (CloseTransientFile(srcfd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); /* * Now move the segment into place with its final name. @@ -3553,7 +3606,7 @@ XLogFileOpen(XLogSegNo segno) if (fd < 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not open write-ahead log file \"%s\": %m", path))); + errmsg("could not open file \"%s\": %m", path))); return fd; } @@ -3739,10 +3792,10 @@ XLogFileClose(void) (void) posix_fadvise(openLogFile, 0, 0, POSIX_FADV_DONTNEED); #endif - if (close(openLogFile)) + if (close(openLogFile) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not close log file %s: %m", + errmsg("could not close file \"%s\": %m", XLogFileNameP(ThisTimeLineID, openLogSegNo)))); openLogFile = -1; } @@ -3851,15 +3904,44 @@ UpdateLastRemovedPtr(char *filename) SpinLockRelease(&XLogCtl->info_lck); } +/* + * Remove all temporary log files in pg_wal + * + * This is called at the beginning of recovery after a previous crash, + * at a point where no other processes write fresh WAL data. + */ +static void +RemoveTempXlogFiles(void) +{ + DIR *xldir; + struct dirent *xlde; + + elog(DEBUG2, "removing all temporary WAL segments"); + + xldir = AllocateDir(XLOGDIR); + while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL) + { + char path[MAXPGPATH]; + + if (strncmp(xlde->d_name, "xlogtemp.", 9) != 0) + continue; + + snprintf(path, MAXPGPATH, XLOGDIR "/%s", xlde->d_name); + unlink(path); + elog(DEBUG2, "removed temporary WAL segment \"%s\"", path); + } + FreeDir(xldir); +} + /* * Recycle or remove all log files older or equal to passed segno. * - * endptr is current (or recent) end of xlog, and PriorRedoRecPtr is the - * redo pointer of the previous checkpoint. These are used to determine + * endptr is current (or recent) end of xlog, and RedoRecPtr is the + * redo pointer of the last checkpoint. These are used to determine * whether we want to recycle rather than delete no-longer-wanted log files. */ static void -RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) +RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr) { DIR *xldir; struct dirent *xlde; @@ -3902,7 +3984,7 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) /* Update the last removed location in shared memory first */ UpdateLastRemovedPtr(xlde->d_name); - RemoveXlogFile(xlde->d_name, PriorRedoPtr, endptr); + RemoveXlogFile(xlde->d_name, RedoRecPtr, endptr); } } } @@ -3976,14 +4058,14 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI) /* * Recycle or remove a log file that's no longer needed. * - * endptr is current (or recent) end of xlog, and PriorRedoRecPtr is the - * redo pointer of the previous checkpoint. These are used to determine + * endptr is current (or recent) end of xlog, and RedoRecPtr is the + * redo pointer of the last checkpoint. These are used to determine * whether we want to recycle rather than delete no-longer-wanted log files. - * If PriorRedoRecPtr is not known, pass invalid, and the function will - * recycle, somewhat arbitrarily, 10 future segments. + * If RedoRecPtr is not known, pass invalid, and the function will recycle, + * somewhat arbitrarily, 10 future segments. */ static void -RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) +RemoveXlogFile(const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr) { char path[MAXPGPATH]; #ifdef WIN32 @@ -3993,14 +4075,19 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) XLogSegNo endlogSegNo; XLogSegNo recycleSegNo; - /* - * Initialize info about where to try to recycle to. - */ - XLByteToSeg(endptr, endlogSegNo, wal_segment_size); - if (PriorRedoPtr == InvalidXLogRecPtr) - recycleSegNo = endlogSegNo + 10; + if (wal_recycle) + { + /* + * Initialize info about where to try to recycle to. + */ + XLByteToSeg(endptr, endlogSegNo, wal_segment_size); + if (RedoRecPtr == InvalidXLogRecPtr) + recycleSegNo = endlogSegNo + 10; + else + recycleSegNo = XLOGfileslop(RedoRecPtr); + } else - recycleSegNo = XLOGfileslop(PriorRedoPtr); + recycleSegNo = 0; /* keep compiler quiet */ snprintf(path, MAXPGPATH, XLOGDIR "/%s", segname); @@ -4009,7 +4096,8 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) * segment. Only recycle normal files, pg_standby for example can create * symbolic links pointing to a separate archive directory. */ - if (endlogSegNo <= recycleSegNo && + if (wal_recycle && + endlogSegNo <= recycleSegNo && lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) && InstallXLogFileSegment(&endlogSegNo, path, true, recycleSegNo, true)) @@ -4047,7 +4135,7 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr) { ereport(LOG, (errcode_for_file_access(), - errmsg("could not rename old write-ahead log file \"%s\": %m", + errmsg("could not rename file \"%s\": %m", path))); return; } @@ -4154,9 +4242,6 @@ CleanupBackupHistory(void) * If no valid record is available, returns NULL, or fails if emode is PANIC. * (emode must be either PANIC, LOG). In standby mode, retries until a valid * record is available. - * - * The record is copied into readRecordBuf, so that on successful return, - * the returned record pointer always points there. */ static XLogRecord * ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, @@ -4212,7 +4297,7 @@ ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, XLByteToSeg(xlogreader->latestPagePtr, segno, wal_segment_size); offset = XLogSegmentOffset(xlogreader->latestPagePtr, wal_segment_size); - XLogFileName(fname, xlogreader->readPageTLI, segno, + XLogFileName(fname, xlogreader->seg.ws_tli, segno, wal_segment_size); ereport(emode_for_corrupt_record(emode, RecPtr ? RecPtr : EndRecPtr), @@ -4266,6 +4351,12 @@ ReadRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr, int emode, minRecoveryPoint = ControlFile->minRecoveryPoint; minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; + /* + * The startup process can update its local copy of + * minRecoveryPoint from this point. + */ + updateMinRecoveryPoint = true; + UpdateControlFile(); LWLockRelease(ControlFileLock); @@ -4451,7 +4542,7 @@ WriteControlFile(void) if (fd < 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not create control file \"%s\": %m", + errmsg("could not create file \"%s\": %m", XLOG_CONTROL_FILE))); errno = 0; @@ -4463,7 +4554,8 @@ WriteControlFile(void) errno = ENOSPC; ereport(PANIC, (errcode_for_file_access(), - errmsg("could not write to control file: %m"))); + errmsg("could not write to file \"%s\": %m", + XLOG_CONTROL_FILE))); } pgstat_report_wait_end(); @@ -4471,13 +4563,15 @@ WriteControlFile(void) if (pg_fsync(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not fsync control file: %m"))); + errmsg("could not fsync file \"%s\": %m", + XLOG_CONTROL_FILE))); pgstat_report_wait_end(); - if (close(fd)) + if (close(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not close control file: %m"))); + errmsg("could not close file \"%s\": %m", + XLOG_CONTROL_FILE))); } static void @@ -4486,6 +4580,7 @@ ReadControlFile(void) pg_crc32c crc; int fd; static char wal_segsz_str[20]; + int r; /* * Read data... @@ -4495,14 +4590,24 @@ ReadControlFile(void) if (fd < 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not open control file \"%s\": %m", + errmsg("could not open file \"%s\": %m", XLOG_CONTROL_FILE))); pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_READ); - if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not read from control file: %m"))); + r = read(fd, ControlFile, sizeof(ControlFileData)); + if (r != sizeof(ControlFileData)) + { + if (r < 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", + XLOG_CONTROL_FILE))); + else + ereport(PANIC, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + XLOG_CONTROL_FILE, r, sizeof(ControlFileData)))); + } pgstat_report_wait_end(); close(fd); @@ -4652,8 +4757,10 @@ ReadControlFile(void) if (!IsValidWalSegSize(wal_segment_size)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("WAL segment size must be a power of two between 1MB and 1GB, but the control file specifies %d bytes", - wal_segment_size))); + errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte", + "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes", + wal_segment_size, + wal_segment_size))); snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size); SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL, @@ -4662,11 +4769,11 @@ ReadControlFile(void) /* check and update variables dependent on wal_segment_size */ if (ConvertToXSegs(min_wal_size_mb, wal_segment_size) < 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\"."))); + errmsg("\"min_wal_size\" must be at least twice \"wal_segment_size\""))); if (ConvertToXSegs(max_wal_size_mb, wal_segment_size) < 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\"."))); + errmsg("\"max_wal_size\" must be at least twice \"wal_segment_size\""))); UsableBytesInSegment = (wal_segment_size / XLOG_BLCKSZ * UsableBytesInPage) - @@ -4679,49 +4786,14 @@ ReadControlFile(void) PGC_INTERNAL, PGC_S_OVERRIDE); } +/* + * Utility wrapper to update the control file. Note that the control + * file gets flushed. + */ void UpdateControlFile(void) { - int fd; - - INIT_CRC32C(ControlFile->crc); - COMP_CRC32C(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(ControlFile->crc); - - fd = BasicOpenFile(XLOG_CONTROL_FILE, - O_RDWR | PG_BINARY); - if (fd < 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not open control file \"%s\": %m", - XLOG_CONTROL_FILE))); - - errno = 0; - pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE); - if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not write to control file: %m"))); - } - pgstat_report_wait_end(); - - pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE); - if (pg_fsync(fd) != 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not fsync control file: %m"))); - pgstat_report_wait_end(); - - if (close(fd)) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not close control file: %m"))); + update_controlfile(DataDir, ControlFile, true); } /* @@ -5050,7 +5122,7 @@ BootStrapXLOG(void) * a genuine-looking password challenge for the non-existent user, in lieu * of an actual stored password. */ - if (!pg_backend_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN)) + if (!pg_strong_random(mock_auth_nonce, MOCK_AUTH_NONCE_LEN)) ereport(PANIC, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("could not generate secret authorization token"))); @@ -5074,8 +5146,8 @@ BootStrapXLOG(void) checkPoint.ThisTimeLineID = ThisTimeLineID; checkPoint.PrevTimeLineID = ThisTimeLineID; checkPoint.fullPageWrites = fullPageWrites; - checkPoint.nextXidEpoch = 0; - checkPoint.nextXid = FirstNormalTransactionId; + checkPoint.nextFullXid = + FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId); checkPoint.nextOid = FirstBootstrapObjectId; checkPoint.nextMulti = FirstMultiXactId; checkPoint.nextMultiOffset = 0; @@ -5088,7 +5160,7 @@ BootStrapXLOG(void) checkPoint.time = (pg_time_t) time(NULL); checkPoint.oldestActiveXid = InvalidTransactionId; - ShmemVariableCache->nextXid = checkPoint.nextXid; + ShmemVariableCache->nextFullXid = checkPoint.nextFullXid; ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->oidCount = 0; MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); @@ -5154,7 +5226,7 @@ BootStrapXLOG(void) errmsg("could not fsync bootstrap write-ahead log file: %m"))); pgstat_report_wait_end(); - if (close(openLogFile)) + if (close(openLogFile) != 0) ereport(PANIC, (errcode_for_file_access(), errmsg("could not close bootstrap write-ahead log file: %m"))); @@ -5171,11 +5243,12 @@ BootStrapXLOG(void) ControlFile->time = checkPoint.time; ControlFile->checkPoint = checkPoint.redo; ControlFile->checkPointCopy = checkPoint; - ControlFile->unloggedLSN = 1; + ControlFile->unloggedLSN = FirstNormalUnloggedLSN; /* Set important parameter values for use when replaying WAL */ ControlFile->MaxConnections = MaxConnections; ControlFile->max_worker_processes = max_worker_processes; + ControlFile->max_wal_senders = max_wal_senders; ControlFile->max_prepared_xacts = max_prepared_xacts; ControlFile->max_locks_per_xact = max_locks_per_xact; ControlFile->wal_level = wal_level; @@ -5215,306 +5288,140 @@ str_time(pg_time_t tnow) } /* - * See if there is a recovery command file (recovery.conf), and if so - * read in parameters for archive recovery and XLOG streaming. + * See if there are any recovery signal files and if so, set state for + * recovery. * - * The file is parsed using the main configuration parser. + * See if there is a recovery command file (recovery.conf), and if so + * throw an ERROR since as of PG12 we no longer recognize that. */ static void -readRecoveryCommandFile(void) +readRecoverySignalFile(void) { - FILE *fd; - TimeLineID rtli = 0; - bool rtliGiven = false; - ConfigVariable *item, - *head = NULL, - *tail = NULL; - bool recoveryTargetActionSet = false; + struct stat stat_buf; + if (IsBootstrapProcessingMode()) + return; - fd = AllocateFile(RECOVERY_COMMAND_FILE, "r"); - if (fd == NULL) - { - if (errno == ENOENT) - return; /* not there, so no archive recovery */ + /* + * Check for old recovery API file: recovery.conf + */ + if (stat(RECOVERY_COMMAND_FILE, &stat_buf) == 0) ereport(FATAL, (errcode_for_file_access(), - errmsg("could not open recovery command file \"%s\": %m", + errmsg("using recovery command file \"%s\" is not supported", RECOVERY_COMMAND_FILE))); - } /* - * Since we're asking ParseConfigFp() to report errors as FATAL, there's - * no need to check the return value. + * Remove unused .done file, if present. Ignore if absent. */ - (void) ParseConfigFp(fd, RECOVERY_COMMAND_FILE, 0, FATAL, &head, &tail); - - FreeFile(fd); + unlink(RECOVERY_COMMAND_DONE); - for (item = head; item; item = item->next) + /* + * Check for recovery signal files and if found, fsync them since they + * represent server state information. We don't sweat too much about the + * possibility of fsync failure, however. + * + * If present, standby signal file takes precedence. If neither is present + * then we won't enter archive recovery. + */ + if (stat(STANDBY_SIGNAL_FILE, &stat_buf) == 0) { - if (strcmp(item->name, "restore_command") == 0) - { - recoveryRestoreCommand = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("restore_command = '%s'", - recoveryRestoreCommand))); - } - else if (strcmp(item->name, "recovery_end_command") == 0) - { - recoveryEndCommand = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("recovery_end_command = '%s'", - recoveryEndCommand))); - } - else if (strcmp(item->name, "archive_cleanup_command") == 0) - { - archiveCleanupCommand = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("archive_cleanup_command = '%s'", - archiveCleanupCommand))); - } - else if (strcmp(item->name, "recovery_target_action") == 0) - { - if (strcmp(item->value, "pause") == 0) - recoveryTargetAction = RECOVERY_TARGET_ACTION_PAUSE; - else if (strcmp(item->value, "promote") == 0) - recoveryTargetAction = RECOVERY_TARGET_ACTION_PROMOTE; - else if (strcmp(item->value, "shutdown") == 0) - recoveryTargetAction = RECOVERY_TARGET_ACTION_SHUTDOWN; - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for recovery parameter \"%s\": \"%s\"", - "recovery_target_action", - item->value), - errhint("Valid values are \"pause\", \"promote\", and \"shutdown\"."))); - - ereport(DEBUG2, - (errmsg_internal("recovery_target_action = '%s'", - item->value))); - - recoveryTargetActionSet = true; - } - else if (strcmp(item->name, "recovery_target_timeline") == 0) - { - rtliGiven = true; - if (strcmp(item->value, "latest") == 0) - rtli = 0; - else - { - errno = 0; - rtli = (TimeLineID) strtoul(item->value, NULL, 0); - if (errno == EINVAL || errno == ERANGE) - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery_target_timeline is not a valid number: \"%s\"", - item->value))); - } - if (rtli) - ereport(DEBUG2, - (errmsg_internal("recovery_target_timeline = %u", rtli))); - else - ereport(DEBUG2, - (errmsg_internal("recovery_target_timeline = latest"))); - } - else if (strcmp(item->name, "recovery_target_xid") == 0) - { - errno = 0; - recoveryTargetXid = (TransactionId) strtoul(item->value, NULL, 0); - if (errno == EINVAL || errno == ERANGE) - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery_target_xid is not a valid number: \"%s\"", - item->value))); - ereport(DEBUG2, - (errmsg_internal("recovery_target_xid = %u", - recoveryTargetXid))); - recoveryTarget = RECOVERY_TARGET_XID; - } - else if (strcmp(item->name, "recovery_target_time") == 0) - { - recoveryTarget = RECOVERY_TARGET_TIME; - - if (strcmp(item->value, "epoch") == 0 || - strcmp(item->value, "infinity") == 0 || - strcmp(item->value, "-infinity") == 0 || - strcmp(item->value, "now") == 0 || - strcmp(item->value, "today") == 0 || - strcmp(item->value, "tomorrow") == 0 || - strcmp(item->value, "yesterday") == 0) - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery_target_time is not a valid timestamp: \"%s\"", - item->value))); + int fd; - /* - * Convert the time string given by the user to TimestampTz form. - */ - recoveryTargetTime = - DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in, - CStringGetDatum(item->value), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(-1))); - ereport(DEBUG2, - (errmsg_internal("recovery_target_time = '%s'", - timestamptz_to_str(recoveryTargetTime)))); - } - else if (strcmp(item->name, "recovery_target_name") == 0) + fd = BasicOpenFilePerm(STANDBY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method), + S_IRUSR | S_IWUSR); + if (fd >= 0) { - recoveryTarget = RECOVERY_TARGET_NAME; - - recoveryTargetName = pstrdup(item->value); - if (strlen(recoveryTargetName) >= MAXFNAMELEN) - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery_target_name is too long (maximum %d characters)", - MAXFNAMELEN - 1))); - - ereport(DEBUG2, - (errmsg_internal("recovery_target_name = '%s'", - recoveryTargetName))); + (void) pg_fsync(fd); + close(fd); } - else if (strcmp(item->name, "recovery_target_lsn") == 0) - { - recoveryTarget = RECOVERY_TARGET_LSN; + standby_signal_file_found = true; + } + else if (stat(RECOVERY_SIGNAL_FILE, &stat_buf) == 0) + { + int fd; - /* - * Convert the LSN string given by the user to XLogRecPtr form. - */ - recoveryTargetLSN = - DatumGetLSN(DirectFunctionCall3(pg_lsn_in, - CStringGetDatum(item->value), - ObjectIdGetDatum(InvalidOid), - Int32GetDatum(-1))); - ereport(DEBUG2, - (errmsg_internal("recovery_target_lsn = '%X/%X'", - (uint32) (recoveryTargetLSN >> 32), - (uint32) recoveryTargetLSN))); - } - else if (strcmp(item->name, "recovery_target") == 0) - { - if (strcmp(item->value, "immediate") == 0) - recoveryTarget = RECOVERY_TARGET_IMMEDIATE; - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for recovery parameter \"%s\": \"%s\"", - "recovery_target", - item->value), - errhint("The only allowed value is \"immediate\"."))); - ereport(DEBUG2, - (errmsg_internal("recovery_target = '%s'", - item->value))); - } - else if (strcmp(item->name, "recovery_target_inclusive") == 0) - { - /* - * does nothing if a recovery_target is not also set - */ - if (!parse_bool(item->value, &recoveryTargetInclusive)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("parameter \"%s\" requires a Boolean value", - "recovery_target_inclusive"))); - ereport(DEBUG2, - (errmsg_internal("recovery_target_inclusive = %s", - item->value))); - } - else if (strcmp(item->name, "standby_mode") == 0) - { - if (!parse_bool(item->value, &StandbyModeRequested)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("parameter \"%s\" requires a Boolean value", - "standby_mode"))); - ereport(DEBUG2, - (errmsg_internal("standby_mode = '%s'", item->value))); - } - else if (strcmp(item->name, "primary_conninfo") == 0) - { - PrimaryConnInfo = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("primary_conninfo = '%s'", - PrimaryConnInfo))); - } - else if (strcmp(item->name, "primary_slot_name") == 0) - { - ReplicationSlotValidateName(item->value, ERROR); - PrimarySlotName = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("primary_slot_name = '%s'", - PrimarySlotName))); - } - else if (strcmp(item->name, "trigger_file") == 0) + fd = BasicOpenFilePerm(RECOVERY_SIGNAL_FILE, O_RDWR | PG_BINARY | get_sync_bit(sync_method), + S_IRUSR | S_IWUSR); + if (fd >= 0) { - TriggerFile = pstrdup(item->value); - ereport(DEBUG2, - (errmsg_internal("trigger_file = '%s'", - TriggerFile))); + (void) pg_fsync(fd); + close(fd); } - else if (strcmp(item->name, "recovery_min_apply_delay") == 0) - { - const char *hintmsg; + recovery_signal_file_found = true; + } - if (!parse_int(item->value, &recovery_min_apply_delay, GUC_UNIT_MS, - &hintmsg)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("parameter \"%s\" requires a temporal value", - "recovery_min_apply_delay"), - hintmsg ? errhint("%s", _(hintmsg)) : 0)); - ereport(DEBUG2, - (errmsg_internal("recovery_min_apply_delay = '%s'", item->value))); - } - else - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unrecognized recovery parameter \"%s\"", - item->name))); + StandbyModeRequested = false; + ArchiveRecoveryRequested = false; + if (standby_signal_file_found) + { + StandbyModeRequested = true; + ArchiveRecoveryRequested = true; } + else if (recovery_signal_file_found) + { + StandbyModeRequested = false; + ArchiveRecoveryRequested = true; + } + else + return; + + /* + * We don't support standby mode in standalone backends; that requires + * other processes such as the WAL receiver to be alive. + */ + if (StandbyModeRequested && !IsUnderPostmaster) + ereport(FATAL, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("standby mode is not supported by single-user servers"))); +} + +static void +validateRecoveryParameters(void) +{ + if (!ArchiveRecoveryRequested) + return; /* * Check for compulsory parameters */ if (StandbyModeRequested) { - if (PrimaryConnInfo == NULL && recoveryRestoreCommand == NULL) + if ((PrimaryConnInfo == NULL || strcmp(PrimaryConnInfo, "") == 0) && + (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0)) ereport(WARNING, - (errmsg("recovery command file \"%s\" specified neither primary_conninfo nor restore_command", - RECOVERY_COMMAND_FILE), + (errmsg("specified neither primary_conninfo nor restore_command"), errhint("The database server will regularly poll the pg_wal subdirectory to check for files placed there."))); } else { - if (recoveryRestoreCommand == NULL) + if (recoveryRestoreCommand == NULL || + strcmp(recoveryRestoreCommand, "") == 0) ereport(FATAL, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery command file \"%s\" must specify restore_command when standby mode is not enabled", - RECOVERY_COMMAND_FILE))); + errmsg("must specify restore_command when standby mode is not enabled"))); } /* - * Override any inconsistent requests. Not that this is a change of + * Override any inconsistent requests. Note that this is a change of * behaviour in 9.5; prior to this we simply ignored a request to pause if * hot_standby = off, which was surprising behaviour. */ if (recoveryTargetAction == RECOVERY_TARGET_ACTION_PAUSE && - recoveryTargetActionSet && !EnableHotStandby) recoveryTargetAction = RECOVERY_TARGET_ACTION_SHUTDOWN; /* - * We don't support standby_mode in standalone backends; that requires - * other processes such as the WAL receiver to be alive. + * Final parsing of recovery_target_time string; see also + * check_recovery_target_time(). */ - if (StandbyModeRequested && !IsUnderPostmaster) - ereport(FATAL, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("standby mode is not supported by single-user servers"))); - - /* Enable fetching from archive recovery area */ - ArchiveRecoveryRequested = true; + if (recoveryTarget == RECOVERY_TARGET_TIME) + { + recoveryTargetTime = DatumGetTimestampTz(DirectFunctionCall3(timestamptz_in, + CStringGetDatum(recovery_target_time_string), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + } /* * If user specified recovery_target_timeline, validate it or compute the @@ -5522,28 +5429,31 @@ readRecoveryCommandFile(void) * command and set InArchiveRecovery, because we need to fetch timeline * history files from the archive. */ - if (rtliGiven) + if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC) { - if (rtli) - { - /* Timeline 1 does not have a history file, all else should */ - if (rtli != 1 && !existsTimeLineHistory(rtli)) - ereport(FATAL, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("recovery target timeline %u does not exist", - rtli))); - recoveryTargetTLI = rtli; - recoveryTargetIsLatest = false; - } - else - { - /* We start the "latest" search from pg_control's timeline */ - recoveryTargetTLI = findNewestTimeLine(recoveryTargetTLI); - recoveryTargetIsLatest = true; - } - } + TimeLineID rtli = recoveryTargetTLIRequested; - FreeConfigVariables(head); + /* Timeline 1 does not have a history file, all else should */ + if (rtli != 1 && !existsTimeLineHistory(rtli)) + ereport(FATAL, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("recovery target timeline %u does not exist", + rtli))); + recoveryTargetTLI = rtli; + } + else if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_LATEST) + { + /* We start the "latest" search from pg_control's timeline */ + recoveryTargetTLI = findNewestTimeLine(recoveryTargetTLI); + } + else + { + /* + * else we just use the recoveryTargetTLI as already read from + * ControlFile + */ + Assert(recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_CONTROLFILE); + } } /* @@ -5552,7 +5462,6 @@ readRecoveryCommandFile(void) static void exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog) { - char recoveryPath[MAXPGPATH]; char xlogfname[MAXFNAMELEN]; XLogSegNo endLogSegNo; XLogSegNo startLogSegNo; @@ -5618,10 +5527,10 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog) fd = XLogFileInit(startLogSegNo, &use_existent, true); - if (close(fd)) + if (close(fd) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not close log file %s: %m", + errmsg("could not close file \"%s\": %m", XLogFileNameP(ThisTimeLineID, startLogSegNo)))); } @@ -5633,22 +5542,14 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog) XLogArchiveCleanup(xlogfname); /* - * Since there might be a partial WAL segment named RECOVERYXLOG, get rid - * of it. - */ - snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG"); - unlink(recoveryPath); /* ignore any error */ - - /* Get rid of any remaining recovered timeline-history file, too */ - snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY"); - unlink(recoveryPath); /* ignore any error */ - - /* - * Rename the config file out of the way, so that we don't accidentally + * Remove the signal files out of the way, so that we don't accidentally * re-enter archive recovery mode in a subsequent crash. */ - unlink(RECOVERY_COMMAND_DONE); - durable_rename(RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE, FATAL); + if (standby_signal_file_found) + durable_unlink(STANDBY_SIGNAL_FILE, FATAL); + + if (recovery_signal_file_found) + durable_unlink(RECOVERY_SIGNAL_FILE, FATAL); ereport(LOG, (errmsg("archive recovery complete"))); @@ -5706,6 +5607,13 @@ recoveryStopsBefore(XLogReaderState *record) TimestampTz recordXtime = 0; TransactionId recordXid; + /* + * Ignore recovery target settings when not in archive recovery (meaning + * we are in crash recovery). + */ + if (!ArchiveRecoveryRequested) + return false; + /* Check if we should stop as soon as reaching consistency */ if (recoveryTarget == RECOVERY_TARGET_IMMEDIATE && reachedConsistency) { @@ -5847,6 +5755,13 @@ recoveryStopsAfter(XLogReaderState *record) uint8 rmid; TimestampTz recordXtime; + /* + * Ignore recovery target settings when not in archive recovery (meaning + * we are in crash recovery). + */ + if (!ArchiveRecoveryRequested) + return false; + info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; rmid = XLogRecGetRmid(record); @@ -6112,17 +6027,20 @@ recoveryApplyDelay(XLogReaderState *record) TimestampDifference(GetCurrentTimestamp(), recoveryDelayUntilTime, &secs, µsecs); - /* NB: We're ignoring waits below min_apply_delay's resolution. */ + /* + * NB: We're ignoring waits below recovery_min_apply_delay's + * resolution. + */ if (secs <= 0 && microsecs / 1000 <= 0) break; elog(DEBUG2, "recovery apply delay %ld seconds, %d milliseconds", secs, microsecs / 1000); - WaitLatch(&XLogCtl->recoveryWakeupLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - secs * 1000L + microsecs / 1000, - WAIT_EVENT_RECOVERY_APPLY_DELAY); + (void) WaitLatch(&XLogCtl->recoveryWakeupLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + secs * 1000L + microsecs / 1000, + WAIT_EVENT_RECOVERY_APPLY_DELAY); } return true; } @@ -6261,6 +6179,9 @@ CheckRequiredParameterValues(void) RecoveryRequiresIntParameter("max_worker_processes", max_worker_processes, ControlFile->max_worker_processes); + RecoveryRequiresIntParameter("max_wal_senders", + max_wal_senders, + ControlFile->max_wal_senders); RecoveryRequiresIntParameter("max_prepared_transactions", max_prepared_xacts, ControlFile->max_prepared_xacts); @@ -6297,6 +6218,15 @@ StartupXLOG(void) bool fast_promoted = false; struct stat st; + /* + * We should have an aux process resource owner to use, and we should not + * be in a transaction that's installed some other resowner. + */ + Assert(AuxProcessResourceOwner != NULL); + Assert(CurrentResourceOwner == NULL || + CurrentResourceOwner == AuxProcessResourceOwner); + CurrentResourceOwner = AuxProcessResourceOwner; + /* * Verify XLOG status looks valid. */ @@ -6351,17 +6281,25 @@ StartupXLOG(void) */ ValidateXLOGDirectoryStructure(); - /* - * If we previously crashed, there might be data which we had written, - * intending to fsync it, but which we had not actually fsync'd yet. - * Therefore, a power failure in the near future might cause earlier - * unflushed writes to be lost, even though more recent data written to - * disk from here on would be persisted. To avoid that, fsync the entire - * data directory. + /*---------- + * If we previously crashed, perform a couple of actions: + * - The pg_wal directory may still include some temporary WAL segments + * used when creating a new segment, so perform some clean up to not + * bloat this path. This is done first as there is no point to sync this + * temporary data. + * - There might be data which we had written, intending to fsync it, + * but which we had not actually fsync'd yet. Therefore, a power failure + * in the near future might cause earlier unflushed writes to be lost, + * even though more recent data written to disk from here on would be + * persisted. To avoid that, fsync the entire data directory. + *--------- */ if (ControlFile->state != DB_SHUTDOWNED && ControlFile->state != DB_SHUTDOWNED_IN_RECOVERY) + { + RemoveTempXlogFiles(); SyncDataDirectory(); + } /* * Initialize on the assumption we want to recover to the latest timeline @@ -6374,18 +6312,10 @@ StartupXLOG(void) recoveryTargetTLI = ControlFile->checkPointCopy.ThisTimeLineID; /* - * Check for recovery control file, and if so set up state for offline - * recovery + * Check for signal files, and if so set up state for offline recovery */ - readRecoveryCommandFile(); - - /* - * Save archive_cleanup_command in shared memory so that other processes - * can see it. - */ - strlcpy(XLogCtl->archiveCleanupCommand, - archiveCleanupCommand ? archiveCleanupCommand : "", - sizeof(XLogCtl->archiveCleanupCommand)); + readRecoverySignalFile(); + validateRecoveryParameters(); if (ArchiveRecoveryRequested) { @@ -6426,7 +6356,8 @@ StartupXLOG(void) /* Set up XLOG reader facility */ MemSet(&private, 0, sizeof(XLogPageReadPrivate)); - xlogreader = XLogReaderAllocate(wal_segment_size, &XLogPageRead, &private); + xlogreader = XLogReaderAllocate(wal_segment_size, NULL, + &XLogPageRead, &private); if (!xlogreader) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), @@ -6435,8 +6366,11 @@ StartupXLOG(void) xlogreader->system_identifier = ControlFile->system_identifier; /* - * Allocate pages dedicated to WAL consistency checks, those had better be - * aligned. + * Allocate two page buffers dedicated to WAL consistency checks. We do + * it this way, rather than just making static arrays, for two reasons: + * (1) no need to waste the storage in most instantiations of the backend; + * (2) a static char array isn't guaranteed to have any particular + * alignment, whereas palloc() will provide MAXALIGN'd storage. */ replay_image_masked = (char *) palloc(BLCKSZ); master_image_masked = (char *) palloc(BLCKSZ); @@ -6480,14 +6414,20 @@ StartupXLOG(void) if (!ReadRecord(xlogreader, checkPoint.redo, LOG, false)) ereport(FATAL, (errmsg("could not find redo location referenced by checkpoint record"), - errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir))); + errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" + "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" + "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.", + DataDir, DataDir, DataDir))); } } else { ereport(FATAL, (errmsg("could not locate required checkpoint record"), - errhint("If you are not restoring from a backup, try removing the file \"%s/backup_label\".", DataDir))); + errhint("If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" + "If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" + "Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup.", + DataDir, DataDir, DataDir))); wasShutdown = false; /* keep compiler quiet */ } @@ -6562,7 +6502,8 @@ StartupXLOG(void) * This can happen for example if a base backup is taken from a * running server using an atomic filesystem snapshot, without calling * pg_start/stop_backup. Or if you just kill a running master server - * and put it into archive recovery by creating a recovery.conf file. + * and put it into archive recovery by creating a recovery signal + * file. * * Our strategy in that case is to perform crash recovery first, * replaying all the WAL present in pg_wal, and only enter archive @@ -6597,7 +6538,7 @@ StartupXLOG(void) { /* * We used to attempt to go back to a secondary checkpoint record - * here, but only when not in standby_mode. We now just fail if we + * here, but only when not in standby mode. We now just fail if we * can't read the last checkpoint because this allows us to * simplify processing around checkpoints. */ @@ -6671,8 +6612,8 @@ StartupXLOG(void) (uint32) (checkPoint.redo >> 32), (uint32) checkPoint.redo, wasShutdown ? "true" : "false"))); ereport(DEBUG1, - (errmsg_internal("next transaction ID: %u:%u; next OID: %u", - checkPoint.nextXidEpoch, checkPoint.nextXid, + (errmsg_internal("next transaction ID: " UINT64_FORMAT "; next OID: %u", + U64FromFullTransactionId(checkPoint.nextFullXid), checkPoint.nextOid))); ereport(DEBUG1, (errmsg_internal("next MultiXactId: %u; next MultiXactOffset: %u", @@ -6687,12 +6628,12 @@ StartupXLOG(void) (errmsg_internal("commit timestamp Xid oldest/newest: %u/%u", checkPoint.oldestCommitTsXid, checkPoint.newestCommitTsXid))); - if (!TransactionIdIsNormal(checkPoint.nextXid)) + if (!TransactionIdIsNormal(XidFromFullTransactionId(checkPoint.nextFullXid))) ereport(PANIC, (errmsg("invalid next transaction ID"))); /* initialize shared memory variables from the checkpoint record */ - ShmemVariableCache->nextXid = checkPoint.nextXid; + ShmemVariableCache->nextFullXid = checkPoint.nextFullXid; ShmemVariableCache->nextOid = checkPoint.nextOid; ShmemVariableCache->oidCount = 0; MultiXactSetNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); @@ -6701,8 +6642,7 @@ StartupXLOG(void) SetMultiXactIdLimit(checkPoint.oldestMulti, checkPoint.oldestMultiDB, true); SetCommitTsLimit(checkPoint.oldestCommitTsXid, checkPoint.newestCommitTsXid); - XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; - XLogCtl->ckptXid = checkPoint.nextXid; + XLogCtl->ckptFullXid = checkPoint.nextFullXid; /* * Initialize replication slots, before there's a chance to remove @@ -6723,11 +6663,12 @@ StartupXLOG(void) StartupMultiXact(); /* - * Ditto commit timestamps. In a standby, we do it if setting is enabled - * in ControlFile; in a master we base the decision on the GUC itself. + * Ditto for commit timestamps. Activate the facility if the setting is + * enabled in the control file, as there should be no tracking of commit + * timestamps done when the setting was disabled. This facility can be + * started or stopped when replaying a XLOG_PARAMETER_CHANGE record. */ - if (ArchiveRecoveryRequested ? - ControlFile->track_commit_timestamp : track_commit_timestamp) + if (ControlFile->track_commit_timestamp) StartupCommitTs(); /* @@ -6787,7 +6728,7 @@ StartupXLOG(void) /* * Check whether we need to force recovery from WAL. If it appears to - * have been a clean shutdown and we did not have a recovery.conf file, + * have been a clean shutdown and we did not have a recovery signal file, * then assume no recovery needed. */ if (checkPoint.redo < RecPtr) @@ -6801,7 +6742,7 @@ StartupXLOG(void) InRecovery = true; else if (ArchiveRecoveryRequested) { - /* force recovery due to presence of recovery.conf */ + /* force recovery due to presence of recovery signal file */ InRecovery = true; } @@ -6879,9 +6820,26 @@ StartupXLOG(void) /* No need to hold ControlFileLock yet, we aren't up far enough */ UpdateControlFile(); - /* initialize our local copy of minRecoveryPoint */ - minRecoveryPoint = ControlFile->minRecoveryPoint; - minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; + /* + * Initialize our local copy of minRecoveryPoint. When doing crash + * recovery we want to replay up to the end of WAL. Particularly, in + * the case of a promoted standby minRecoveryPoint value in the + * control file is only updated after the first checkpoint. However, + * if the instance crashes before the first post-recovery checkpoint + * is completed then recovery will use a stale location causing the + * startup process to think that there are still invalid page + * references when checking for data consistency. + */ + if (InArchiveRecovery) + { + minRecoveryPoint = ControlFile->minRecoveryPoint; + minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; + } + else + { + minRecoveryPoint = InvalidXLogRecPtr; + minRecoveryPointTLI = 0; + } /* * Reset pgstat data, because it may be invalid after recovery. @@ -6955,7 +6913,7 @@ StartupXLOG(void) Assert(TransactionIdIsValid(oldestActiveXID)); /* Tell procarray about the range of xids it has to deal with */ - ProcArrayInitRecovery(ShmemVariableCache->nextXid); + ProcArrayInitRecovery(XidFromFullTransactionId(ShmemVariableCache->nextFullXid)); /* * Startup commit log and subtrans only. MultiXact and commit @@ -6985,9 +6943,9 @@ StartupXLOG(void) running.xcnt = nxids; running.subxcnt = 0; running.subxid_overflow = false; - running.nextXid = checkPoint.nextXid; + running.nextXid = XidFromFullTransactionId(checkPoint.nextFullXid); running.oldestRunningXid = oldestActiveXID; - latestCompletedXid = checkPoint.nextXid; + latestCompletedXid = XidFromFullTransactionId(checkPoint.nextFullXid); TransactionIdRetreat(latestCompletedXid); Assert(TransactionIdIsNormal(latestCompletedXid)); running.latestCompletedXid = latestCompletedXid; @@ -7042,7 +7000,7 @@ StartupXLOG(void) if (ArchiveRecoveryRequested && IsUnderPostmaster) { PublishStartupProcessInformation(); - SetForwardFsyncRequests(); + EnableSyncRequestForwarding(); SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED); bgwriterLaunched = true; } @@ -7157,20 +7115,10 @@ StartupXLOG(void) error_context_stack = &errcallback; /* - * ShmemVariableCache->nextXid must be beyond record's xid. - * - * We don't expect anyone else to modify nextXid, hence we - * don't need to hold a lock while examining it. We still - * acquire the lock to modify it, though. + * ShmemVariableCache->nextFullXid must be beyond record's + * xid. */ - if (TransactionIdFollowsOrEquals(record->xl_xid, - ShmemVariableCache->nextXid)) - { - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = record->xl_xid; - TransactionIdAdvance(ShmemVariableCache->nextXid); - LWLockRelease(XidGenLock); - } + AdvanceNextFullTransactionIdPastXid(record->xl_xid); /* * Before replaying this record, check if this record causes @@ -7411,7 +7359,7 @@ StartupXLOG(void) * and we were reading the old WAL from a segment belonging to a higher * timeline. */ - EndOfLogTLI = xlogreader->readPageTLI; + EndOfLogTLI = xlogreader->seg.ws_tli; /* * Complain if we did not roll forward far enough to render the backup @@ -7449,6 +7397,13 @@ StartupXLOG(void) } } + /* + * Pre-scan prepared transactions to find out the range of XIDs present. + * This information is not quite needed yet, but it is positioned here so + * as potential problems are detected before any on-disk change is done. + */ + oldestActiveXID = PrescanPreparedTransactions(NULL, NULL); + /* * Consider whether we need to assign a new timeline ID. * @@ -7467,6 +7422,7 @@ StartupXLOG(void) if (ArchiveRecoveryRequested) { char reason[200]; + char recoveryPath[MAXPGPATH]; Assert(InArchiveRecovery); @@ -7503,23 +7459,43 @@ StartupXLOG(void) else snprintf(reason, sizeof(reason), "no recovery target specified"); + /* + * We are now done reading the old WAL. Turn off archive fetching if + * it was active, and make a writable copy of the last WAL segment. + * (Note that we also have a copy of the last block of the old WAL in + * readBuf; we will use that below.) + */ + exitArchiveRecovery(EndOfLogTLI, EndOfLog); + + /* + * Write the timeline history file, and have it archived. After this + * point (or rather, as soon as the file is archived), the timeline + * will appear as "taken" in the WAL archive and to any standby + * servers. If we crash before actually switching to the new + * timeline, standby servers will nevertheless think that we switched + * to the new timeline, and will try to connect to the new timeline. + * To minimize the window for that, try to do as little as possible + * between here and writing the end-of-recovery record. + */ writeTimeLineHistory(ThisTimeLineID, recoveryTargetTLI, EndRecPtr, reason); + + /* + * Since there might be a partial WAL segment named RECOVERYXLOG, get + * rid of it. + */ + snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYXLOG"); + unlink(recoveryPath); /* ignore any error */ + + /* Get rid of any remaining recovered timeline-history file, too */ + snprintf(recoveryPath, MAXPGPATH, XLOGDIR "/RECOVERYHISTORY"); + unlink(recoveryPath); /* ignore any error */ } /* Save the selected TimeLineID in shared memory, too */ XLogCtl->ThisTimeLineID = ThisTimeLineID; XLogCtl->PrevTimeLineID = PrevTimeLineID; - /* - * We are now done reading the old WAL. Turn off archive fetching if it - * was active, and make a writable copy of the last WAL segment. (Note - * that we also have a copy of the last block of the old WAL in readBuf; - * we will use that below.) - */ - if (ArchiveRecoveryRequested) - exitArchiveRecovery(EndOfLogTLI, EndOfLog); - /* * Prepare to write WAL starting at EndOfLog location, and init xlog * buffer cache using the block containing the last record from the @@ -7572,9 +7548,6 @@ StartupXLOG(void) XLogCtl->LogwrtRqst.Write = EndOfLog; XLogCtl->LogwrtRqst.Flush = EndOfLog; - /* Pre-scan prepared transactions to find out the range of XIDs present */ - oldestActiveXID = PrescanPreparedTransactions(NULL, NULL); - /* * Update full_page_writes in shared memory and write an XLOG_FPW_CHANGE * record before resource manager writes cleanup WAL records or checkpoint @@ -7642,7 +7615,7 @@ StartupXLOG(void) /* * And finally, execute the recovery_end_command, if any. */ - if (recoveryEndCommand) + if (recoveryEndCommand && strcmp(recoveryEndCommand, "") != 0) ExecuteRecoveryCommand(recoveryEndCommand, "recovery_end_command", true); @@ -7737,7 +7710,7 @@ StartupXLOG(void) /* also initialize latestCompletedXid, to nextXid - 1 */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); - ShmemVariableCache->latestCompletedXid = ShmemVariableCache->nextXid; + ShmemVariableCache->latestCompletedXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); TransactionIdRetreat(ShmemVariableCache->latestCompletedXid); LWLockRelease(ProcArrayLock); @@ -7848,6 +7821,8 @@ CheckRecoveryConsistency(void) if (XLogRecPtrIsInvalid(minRecoveryPoint)) return; + Assert(InArchiveRecovery); + /* * assume that we are called in the startup process, and hence don't need * a lock to read lastReplayedEndRecPtr @@ -8329,46 +8304,20 @@ GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN) } /* - * GetNextXidAndEpoch - get the current nextXid value and associated epoch - * - * This is exported for use by code that would like to have 64-bit XIDs. - * We don't really support such things, but all XIDs within the system - * can be presumed "close to" the result, and thus the epoch associated - * with them can be determined. + * This must be called ONCE during postmaster or standalone-backend shutdown */ void -GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch) +ShutdownXLOG(int code, Datum arg) { - uint32 ckptXidEpoch; - TransactionId ckptXid; - TransactionId nextXid; - - /* Must read checkpoint info first, else have race condition */ - SpinLockAcquire(&XLogCtl->info_lck); - ckptXidEpoch = XLogCtl->ckptXidEpoch; - ckptXid = XLogCtl->ckptXid; - SpinLockRelease(&XLogCtl->info_lck); - - /* Now fetch current nextXid */ - nextXid = ReadNewTransactionId(); - /* - * nextXid is certainly logically later than ckptXid. So if it's - * numerically less, it must have wrapped into the next epoch. + * We should have an aux process resource owner to use, and we should not + * be in a transaction that's installed some other resowner. */ - if (nextXid < ckptXid) - ckptXidEpoch++; + Assert(AuxProcessResourceOwner != NULL); + Assert(CurrentResourceOwner == NULL || + CurrentResourceOwner == AuxProcessResourceOwner); + CurrentResourceOwner = AuxProcessResourceOwner; - *xid = nextXid; - *epoch = ckptXidEpoch; -} - -/* - * This must be called ONCE during postmaster or standalone-backend shutdown - */ -void -ShutdownXLOG(int code, Datum arg) -{ /* Don't be chatty in standalone mode */ ereport(IsPostmasterEnvironment ? LOG : NOTICE, (errmsg("shutting down"))); @@ -8418,7 +8367,7 @@ LogCheckpointStart(int flags, bool restartpoint) (flags & CHECKPOINT_IMMEDIATE) ? " immediate" : "", (flags & CHECKPOINT_FORCE) ? " force" : "", (flags & CHECKPOINT_WAIT) ? " wait" : "", - (flags & CHECKPOINT_CAUSE_XLOG) ? " xlog" : "", + (flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "", (flags & CHECKPOINT_CAUSE_TIME) ? " time" : "", (flags & CHECKPOINT_FLUSH_ALL) ? " flush-all" : ""); } @@ -8509,7 +8458,7 @@ LogCheckpointEnd(bool restartpoint) * Update the estimate of distance between checkpoints. * * The estimate is used to calculate the number of WAL segments to keep - * preallocated, see XLOGFileSlop(). + * preallocated, see XLOGfileslop(). */ static void UpdateCheckPointDistanceEstimate(uint64 nbytes) @@ -8579,6 +8528,7 @@ CreateCheckPoint(int flags) bool shutdown; CheckPoint checkPoint; XLogRecPtr recptr; + XLogSegNo _logSegNo; XLogCtlInsert *Insert = &XLogCtl->Insert; uint32 freespace; XLogRecPtr PriorRedoPtr; @@ -8647,7 +8597,7 @@ CreateCheckPoint(int flags) * the REDO pointer. Note that smgr must not do anything that'd have to * be undone if we decide no checkpoint is needed. */ - smgrpreckpt(); + SyncPreCheckpoint(); /* Begin filling in the checkpoint WAL record */ MemSet(&checkPoint, 0, sizeof(checkPoint)); @@ -8772,7 +8722,7 @@ CreateCheckPoint(int flags) * there. */ LWLockAcquire(XidGenLock, LW_SHARED); - checkPoint.nextXid = ShmemVariableCache->nextXid; + checkPoint.nextFullXid = ShmemVariableCache->nextFullXid; checkPoint.oldestXid = ShmemVariableCache->oldestXid; checkPoint.oldestXidDB = ShmemVariableCache->oldestXidDB; LWLockRelease(XidGenLock); @@ -8782,11 +8732,6 @@ CreateCheckPoint(int flags) checkPoint.newestCommitTsXid = ShmemVariableCache->newestCommitTsXid; LWLockRelease(CommitTsLock); - /* Increase XID epoch if we've wrapped around since last checkpoint */ - checkPoint.nextXidEpoch = ControlFile->checkPointCopy.nextXidEpoch; - if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid) - checkPoint.nextXidEpoch++; - LWLockAcquire(OidGenLock, LW_SHARED); checkPoint.nextOid = ShmemVariableCache->nextOid; if (!shutdown) @@ -8930,8 +8875,7 @@ CreateCheckPoint(int flags) /* Update shared-memory copy of checkpoint XID/epoch */ SpinLockAcquire(&XLogCtl->info_lck); - XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; - XLogCtl->ckptXid = checkPoint.nextXid; + XLogCtl->ckptFullXid = checkPoint.nextFullXid; SpinLockRelease(&XLogCtl->info_lck); /* @@ -8943,24 +8887,23 @@ CreateCheckPoint(int flags) /* * Let smgr do post-checkpoint cleanup (eg, deleting old files). */ - smgrpostckpt(); + SyncPostCheckpoint(); /* - * Delete old log files and recycle them + * Update the average distance between checkpoints if the prior checkpoint + * exists. */ if (PriorRedoPtr != InvalidXLogRecPtr) - { - XLogSegNo _logSegNo; - - /* Update the average distance between checkpoints. */ UpdateCheckPointDistanceEstimate(RedoRecPtr - PriorRedoPtr); - /* Trim from the last checkpoint, not the last - 1 */ - XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size); - KeepLogSeg(recptr, &_logSegNo); - _logSegNo--; - RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr); - } + /* + * Delete old log files, those no longer needed for last checkpoint to + * prevent the disk holding the xlog from growing full. + */ + XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size); + KeepLogSeg(recptr, &_logSegNo); + _logSegNo--; + RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr); /* * Make more log segments if needed. (Do this after recycling old log @@ -9126,6 +9069,11 @@ CreateRestartPoint(int flags) XLogRecPtr lastCheckPointEndPtr; CheckPoint lastCheckPoint; XLogRecPtr PriorRedoPtr; + XLogRecPtr receivePtr; + XLogRecPtr replayPtr; + TimeLineID replayTLI; + XLogRecPtr endptr; + XLogSegNo _logSegNo; TimestampTz xtime; /* @@ -9229,7 +9177,7 @@ CreateRestartPoint(int flags) /* * Update pg_control, using current time. Check that it still shows - * IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing; + * DB_IN_ARCHIVE_RECOVERY state and an older checkpoint, else do nothing; * this is a quick hack to make sure nothing really bad happens if somehow * we get here after the end-of-recovery checkpoint. */ @@ -9268,68 +9216,60 @@ CreateRestartPoint(int flags) LWLockRelease(ControlFileLock); /* - * Delete old log files (those no longer needed even for previous - * checkpoint/restartpoint) to prevent the disk holding the xlog from - * growing full. + * Update the average distance between checkpoints/restartpoints if the + * prior checkpoint exists. */ if (PriorRedoPtr != InvalidXLogRecPtr) - { - XLogRecPtr receivePtr; - XLogRecPtr replayPtr; - TimeLineID replayTLI; - XLogRecPtr endptr; - XLogSegNo _logSegNo; - - /* Update the average distance between checkpoints/restartpoints. */ UpdateCheckPointDistanceEstimate(RedoRecPtr - PriorRedoPtr); - XLByteToSeg(PriorRedoPtr, _logSegNo, wal_segment_size); - - /* - * Get the current end of xlog replayed or received, whichever is - * later. - */ - receivePtr = GetWalRcvWriteRecPtr(NULL, NULL); - replayPtr = GetXLogReplayRecPtr(&replayTLI); - endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr; + /* + * Delete old log files, those no longer needed for last restartpoint to + * prevent the disk holding the xlog from growing full. + */ + XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size); - KeepLogSeg(endptr, &_logSegNo); - _logSegNo--; + /* + * Retreat _logSegNo using the current end of xlog replayed or received, + * whichever is later. + */ + receivePtr = GetWalRcvWriteRecPtr(NULL, NULL); + replayPtr = GetXLogReplayRecPtr(&replayTLI); + endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr; + KeepLogSeg(endptr, &_logSegNo); + _logSegNo--; - /* - * Try to recycle segments on a useful timeline. If we've been - * promoted since the beginning of this restartpoint, use the new - * timeline chosen at end of recovery (RecoveryInProgress() sets - * ThisTimeLineID in that case). If we're still in recovery, use the - * timeline we're currently replaying. - * - * There is no guarantee that the WAL segments will be useful on the - * current timeline; if recovery proceeds to a new timeline right - * after this, the pre-allocated WAL segments on this timeline will - * not be used, and will go wasted until recycled on the next - * restartpoint. We'll live with that. - */ - if (RecoveryInProgress()) - ThisTimeLineID = replayTLI; + /* + * Try to recycle segments on a useful timeline. If we've been promoted + * since the beginning of this restartpoint, use the new timeline chosen + * at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that + * case). If we're still in recovery, use the timeline we're currently + * replaying. + * + * There is no guarantee that the WAL segments will be useful on the + * current timeline; if recovery proceeds to a new timeline right after + * this, the pre-allocated WAL segments on this timeline will not be used, + * and will go wasted until recycled on the next restartpoint. We'll live + * with that. + */ + if (RecoveryInProgress()) + ThisTimeLineID = replayTLI; - RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr); + RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr); - /* - * Make more log segments if needed. (Do this after recycling old log - * segments, since that may supply some of the needed files.) - */ - PreallocXlogFiles(endptr); + /* + * Make more log segments if needed. (Do this after recycling old log + * segments, since that may supply some of the needed files.) + */ + PreallocXlogFiles(endptr); - /* - * ThisTimeLineID is normally not set when we're still in recovery. - * However, recycling/preallocating segments above needed - * ThisTimeLineID to determine which timeline to install the segments - * on. Reset it now, to restore the normal state of affairs for - * debugging purposes. - */ - if (RecoveryInProgress()) - ThisTimeLineID = 0; - } + /* + * ThisTimeLineID is normally not set when we're still in recovery. + * However, recycling/preallocating segments above needed ThisTimeLineID + * to determine which timeline to install the segments on. Reset it now, + * to restore the normal state of affairs for debugging purposes. + */ + if (RecoveryInProgress()) + ThisTimeLineID = 0; /* * Truncate pg_subtrans if possible. We can throw away all data before @@ -9356,8 +9296,8 @@ CreateRestartPoint(int flags) /* * Finally, execute archive_cleanup_command, if any. */ - if (XLogCtl->archiveCleanupCommand[0]) - ExecuteRecoveryCommand(XLogCtl->archiveCleanupCommand, + if (archiveCleanupCommand && strcmp(archiveCleanupCommand, "") != 0) + ExecuteRecoveryCommand(archiveCleanupCommand, "archive_cleanup_command", false); @@ -9499,6 +9439,7 @@ XLogReportParameters(void) wal_log_hints != ControlFile->wal_log_hints || MaxConnections != ControlFile->MaxConnections || max_worker_processes != ControlFile->max_worker_processes || + max_wal_senders != ControlFile->max_wal_senders || max_prepared_xacts != ControlFile->max_prepared_xacts || max_locks_per_xact != ControlFile->max_locks_per_xact || track_commit_timestamp != ControlFile->track_commit_timestamp) @@ -9517,6 +9458,7 @@ XLogReportParameters(void) xlrec.MaxConnections = MaxConnections; xlrec.max_worker_processes = max_worker_processes; + xlrec.max_wal_senders = max_wal_senders; xlrec.max_prepared_xacts = max_prepared_xacts; xlrec.max_locks_per_xact = max_locks_per_xact; xlrec.wal_level = wal_level; @@ -9532,6 +9474,7 @@ XLogReportParameters(void) ControlFile->MaxConnections = MaxConnections; ControlFile->max_worker_processes = max_worker_processes; + ControlFile->max_wal_senders = max_wal_senders; ControlFile->max_prepared_xacts = max_prepared_xacts; ControlFile->max_locks_per_xact = max_locks_per_xact; ControlFile->wal_level = wal_level; @@ -9552,6 +9495,7 @@ void UpdateFullPageWrites(void) { XLogCtlInsert *Insert = &XLogCtl->Insert; + bool recoveryInProgress; /* * Do nothing if full_page_writes has not been changed. @@ -9563,6 +9507,13 @@ UpdateFullPageWrites(void) if (fullPageWrites == Insert->fullPageWrites) return; + /* + * Perform this outside critical section so that the WAL insert + * initialization done by RecoveryInProgress() doesn't trigger an + * assertion failure. + */ + recoveryInProgress = RecoveryInProgress(); + START_CRIT_SECTION(); /* @@ -9583,7 +9534,7 @@ UpdateFullPageWrites(void) * Write an XLOG_FPW_CHANGE record. This allows us to keep track of * full_page_writes during archive recovery, if required. */ - if (XLogStandbyInfoActive() && !RecoveryInProgress()) + if (XLogStandbyInfoActive() && !recoveryInProgress) { XLogBeginInsert(); XLogRegisterData((char *) (&fullPageWrites), sizeof(bool)); @@ -9686,7 +9637,7 @@ xlog_redo(XLogReaderState *record) memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint)); /* In a SHUTDOWN checkpoint, believe the counters exactly */ LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = checkPoint.nextXid; + ShmemVariableCache->nextFullXid = checkPoint.nextFullXid; LWLockRelease(XidGenLock); LWLockAcquire(OidGenLock, LW_EXCLUSIVE); ShmemVariableCache->nextOid = checkPoint.nextOid; @@ -9740,9 +9691,9 @@ xlog_redo(XLogReaderState *record) running.xcnt = nxids; running.subxcnt = 0; running.subxid_overflow = false; - running.nextXid = checkPoint.nextXid; + running.nextXid = XidFromFullTransactionId(checkPoint.nextFullXid); running.oldestRunningXid = oldestActiveXID; - latestCompletedXid = checkPoint.nextXid; + latestCompletedXid = XidFromFullTransactionId(checkPoint.nextFullXid); TransactionIdRetreat(latestCompletedXid); Assert(TransactionIdIsNormal(latestCompletedXid)); running.latestCompletedXid = latestCompletedXid; @@ -9754,13 +9705,11 @@ xlog_redo(XLogReaderState *record) } /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ - ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; - ControlFile->checkPointCopy.nextXid = checkPoint.nextXid; + ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid; /* Update shared-memory copy of checkpoint XID/epoch */ SpinLockAcquire(&XLogCtl->info_lck); - XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; - XLogCtl->ckptXid = checkPoint.nextXid; + XLogCtl->ckptFullXid = checkPoint.nextFullXid; SpinLockRelease(&XLogCtl->info_lck); /* @@ -9781,15 +9730,24 @@ xlog_redo(XLogReaderState *record) memcpy(&checkPoint, XLogRecGetData(record), sizeof(CheckPoint)); /* In an ONLINE checkpoint, treat the XID counter as a minimum */ LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - if (TransactionIdPrecedes(ShmemVariableCache->nextXid, - checkPoint.nextXid)) - ShmemVariableCache->nextXid = checkPoint.nextXid; + if (FullTransactionIdPrecedes(ShmemVariableCache->nextFullXid, + checkPoint.nextFullXid)) + ShmemVariableCache->nextFullXid = checkPoint.nextFullXid; LWLockRelease(XidGenLock); - /* ... but still treat OID counter as exact */ - LWLockAcquire(OidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextOid = checkPoint.nextOid; - ShmemVariableCache->oidCount = 0; - LWLockRelease(OidGenLock); + + /* + * We ignore the nextOid counter in an ONLINE checkpoint, preferring + * to track OID assignment through XLOG_NEXTOID records. The nextOid + * counter is from the start of the checkpoint and might well be stale + * compared to later XLOG_NEXTOID records. We could try to take the + * maximum of the nextOid counter and our latest value, but since + * there's no particular guarantee about the speed with which the OID + * counter wraps around, that's a risky thing to do. In any case, + * users of the nextOid counter are required to avoid assignment of + * duplicates, so that a somewhat out-of-date value should be safe. + */ + + /* Handle multixact */ MultiXactAdvanceNextMXact(checkPoint.nextMulti, checkPoint.nextMultiOffset); @@ -9804,13 +9762,11 @@ xlog_redo(XLogReaderState *record) SetTransactionIdLimit(checkPoint.oldestXid, checkPoint.oldestXidDB); /* ControlFile->checkPointCopy always tracks the latest ckpt XID */ - ControlFile->checkPointCopy.nextXidEpoch = checkPoint.nextXidEpoch; - ControlFile->checkPointCopy.nextXid = checkPoint.nextXid; + ControlFile->checkPointCopy.nextFullXid = checkPoint.nextFullXid; /* Update shared-memory copy of checkpoint XID/epoch */ SpinLockAcquire(&XLogCtl->info_lck); - XLogCtl->ckptXidEpoch = checkPoint.nextXidEpoch; - XLogCtl->ckptXid = checkPoint.nextXid; + XLogCtl->ckptFullXid = checkPoint.nextFullXid; SpinLockRelease(&XLogCtl->info_lck); /* TLI should not change in an on-line checkpoint */ @@ -9856,12 +9812,11 @@ xlog_redo(XLogReaderState *record) } else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT) { - Buffer buffer; - /* * Full-page image (FPI) records contain nothing else but a backup - * block. The block reference must include a full-page image - - * otherwise there would be no point in this record. + * block (or multiple backup blocks). Every block reference must + * include a full-page image - otherwise there would be no point in + * this record. * * No recovery conflicts are generated by these generic records - if a * resource manager needs to generate conflicts, it has to define a @@ -9873,9 +9828,14 @@ xlog_redo(XLogReaderState *record) * XLOG_FPI and XLOG_FPI_FOR_HINT records, they use a different info * code just to distinguish them for statistics purposes. */ - if (XLogReadBufferForRedo(record, 0, &buffer) != BLK_RESTORED) - elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block"); - UnlockReleaseBuffer(buffer); + for (uint8 block_id = 0; block_id <= record->max_block_id; block_id++) + { + Buffer buffer; + + if (XLogReadBufferForRedo(record, block_id, &buffer) != BLK_RESTORED) + elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block"); + UnlockReleaseBuffer(buffer); + } } else if (info == XLOG_BACKUP_END) { @@ -9918,6 +9878,7 @@ xlog_redo(XLogReaderState *record) LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->MaxConnections = xlrec.MaxConnections; ControlFile->max_worker_processes = xlrec.max_worker_processes; + ControlFile->max_wal_senders = xlrec.max_wal_senders; ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts; ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact; ControlFile->wal_level = xlrec.wal_level; @@ -9927,11 +9888,16 @@ xlog_redo(XLogReaderState *record) * Update minRecoveryPoint to ensure that if recovery is aborted, we * recover back up to this point before allowing hot standby again. * This is important if the max_* settings are decreased, to ensure - * you don't run queries against the WAL preceding the change. + * you don't run queries against the WAL preceding the change. The + * local copies cannot be updated as long as crash recovery is + * happening and we expect all the WAL to be replayed. */ - minRecoveryPoint = ControlFile->minRecoveryPoint; - minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; - if (minRecoveryPoint != 0 && minRecoveryPoint < lsn) + if (InArchiveRecovery) + { + minRecoveryPoint = ControlFile->minRecoveryPoint; + minRecoveryPointTLI = ControlFile->minRecoveryPointTLI; + } + if (minRecoveryPoint != InvalidXLogRecPtr && minRecoveryPoint < lsn) { ControlFile->minRecoveryPoint = lsn; ControlFile->minRecoveryPointTLI = ThisTimeLineID; @@ -9944,7 +9910,7 @@ xlog_redo(XLogReaderState *record) UpdateControlFile(); LWLockRelease(ControlFileLock); - /* Check to see if any changes to max_connections give problems */ + /* Check to see if any parameter change gives a problem on recovery */ CheckRequiredParameterValues(); } else if (info == XLOG_FPW_CHANGE) @@ -10115,7 +10081,7 @@ assign_xlog_sync_method(int new_sync_method, void *extra) if (pg_fsync(openLogFile) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not fsync log segment %s: %m", + errmsg("could not fsync file \"%s\": %m", XLogFileNameP(ThisTimeLineID, openLogSegNo)))); pgstat_report_wait_end(); if (get_sync_bit(sync_method) != get_sync_bit(new_sync_method)) @@ -10129,18 +10095,19 @@ assign_xlog_sync_method(int new_sync_method, void *extra) * Issue appropriate kind of fsync (if any) for an XLOG output file. * * 'fd' is a file descriptor for the XLOG file to be fsync'd. - * 'log' and 'seg' are for error reporting purposes. + * 'segno' is for error reporting purposes. */ void issue_xlog_fsync(int fd, XLogSegNo segno) { + pgstat_report_wait_start(WAIT_EVENT_WAL_SYNC); switch (sync_method) { case SYNC_METHOD_FSYNC: if (pg_fsync_no_writethrough(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not fsync log file %s: %m", + errmsg("could not fsync file \"%s\": %m", XLogFileNameP(ThisTimeLineID, segno)))); break; #ifdef HAVE_FSYNC_WRITETHROUGH @@ -10148,7 +10115,7 @@ issue_xlog_fsync(int fd, XLogSegNo segno) if (pg_fsync_writethrough(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not fsync write-through log file %s: %m", + errmsg("could not fsync write-through file \"%s\": %m", XLogFileNameP(ThisTimeLineID, segno)))); break; #endif @@ -10157,7 +10124,7 @@ issue_xlog_fsync(int fd, XLogSegNo segno) if (pg_fdatasync(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not fdatasync log file %s: %m", + errmsg("could not fdatasync file \"%s\": %m", XLogFileNameP(ThisTimeLineID, segno)))); break; #endif @@ -10169,6 +10136,7 @@ issue_xlog_fsync(int fd, XLogSegNo segno) elog(PANIC, "unrecognized wal_sync_method: %d", sync_method); break; } + pgstat_report_wait_end(); } /* @@ -10184,9 +10152,10 @@ XLogFileNameP(TimeLineID tli, XLogSegNo segno) } /* - * do_pg_start_backup is the workhorse of the user-visible pg_start_backup() - * function. It creates the necessary starting checkpoint and constructs the - * backup label file. + * do_pg_start_backup + * + * Utility function called at the start of an online backup. It creates the + * necessary starting checkpoint and constructs the backup label file. * * There are two kind of backups: exclusive and non-exclusive. An exclusive * backup is started with pg_start_backup(), and there can be only one active @@ -10647,10 +10616,9 @@ do_pg_start_backup(const char *backupidstr, bool fast, TimeLineID *starttli_p, * Mark that start phase has correctly finished for an exclusive backup. * Session-level locks are updated as well to reflect that state. * - * Note that CHECK_FOR_INTERRUPTS() must not occur while updating - * backup counters and session-level lock. Otherwise they can be - * updated inconsistently, and which might cause do_pg_abort_backup() - * to fail. + * Note that CHECK_FOR_INTERRUPTS() must not occur while updating backup + * counters and session-level lock. Otherwise they can be updated + * inconsistently, and which might cause do_pg_abort_backup() to fail. */ if (exclusive) { @@ -10727,8 +10695,10 @@ get_backup_status(void) } /* - * do_pg_stop_backup is the workhorse of the user-visible pg_stop_backup() - * function. + * do_pg_stop_backup + * + * Utility function called at the end of an online backup. It cleans up the + * backup state and can optionally wait for WAL segments to be archived. * * If labelfile is NULL, this stops an exclusive backup. Otherwise this stops * the non-exclusive backup specified by 'labelfile'. @@ -10895,11 +10865,11 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) /* * Clean up session-level lock. * - * You might think that WALInsertLockRelease() can be called - * before cleaning up session-level lock because session-level - * lock doesn't need to be protected with WAL insertion lock. - * But since CHECK_FOR_INTERRUPTS() can occur in it, - * session-level lock must be cleaned up before it. + * You might think that WALInsertLockRelease() can be called before + * cleaning up session-level lock because session-level lock doesn't need + * to be protected with WAL insertion lock. But since + * CHECK_FOR_INTERRUPTS() can occur in it, session-level lock must be + * cleaned up before it. */ sessionBackupState = SESSION_BACKUP_NONE; @@ -11033,6 +11003,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename); fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n", (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename); + /* * Transfer remaining lines including label and start timeline to * history file. @@ -11098,7 +11069,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) if (!reported_waiting && waits > 5) { ereport(NOTICE, - (errmsg("pg_stop_backup cleanup done, waiting for required WAL segments to be archived"))); + (errmsg("base backup done, waiting for required WAL segments to be archived"))); reported_waiting = true; } @@ -11108,16 +11079,16 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p) { seconds_before_warning *= 2; /* This wraps in >10 years... */ ereport(WARNING, - (errmsg("pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)", + (errmsg("still waiting for all required WAL segments to be archived (%d seconds elapsed)", waits), errhint("Check that your archive_command is executing properly. " - "pg_stop_backup can be canceled safely, " + "You can safely cancel this backup, " "but the database backup will not be usable without all the WAL segments."))); } } ereport(NOTICE, - (errmsg("pg_stop_backup complete, all required WAL segments have been archived"))); + (errmsg("all required WAL segments have been archived"))); } else if (waitforarchive) ereport(NOTICE, @@ -11250,7 +11221,8 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, bool *backupFromStandby) { char startxlogfilename[MAXFNAMELEN]; - TimeLineID tli_from_walseg, tli_from_file; + TimeLineID tli_from_walseg, + tli_from_file; FILE *lfp; char ch; char backuptype[20]; @@ -11313,13 +11285,13 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, } /* - * Parse START TIME and LABEL. Those are not mandatory fields for - * recovery but checking for their presence is useful for debugging - * and the next sanity checks. Cope also with the fact that the - * result buffers have a pre-allocated size, hence if the backup_label - * file has been generated with strings longer than the maximum assumed - * here an incorrect parsing happens. That's fine as only minor - * consistency checks are done afterwards. + * Parse START TIME and LABEL. Those are not mandatory fields for recovery + * but checking for their presence is useful for debugging and the next + * sanity checks. Cope also with the fact that the result buffers have a + * pre-allocated size, hence if the backup_label file has been generated + * with strings longer than the maximum assumed here an incorrect parsing + * happens. That's fine as only minor consistency checks are done + * afterwards. */ if (fscanf(lfp, "START TIME: %127[^\n]\n", backuptime) == 1) ereport(DEBUG1, @@ -11332,8 +11304,8 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, backuplabel, BACKUP_LABEL_FILE))); /* - * START TIMELINE is new as of 11. Its parsing is not mandatory, still - * use it as a sanity check if present. + * START TIMELINE is new as of 11. Its parsing is not mandatory, still use + * it as a sanity check if present. */ if (fscanf(lfp, "START TIMELINE: %u\n", &tli_from_file) == 1) { @@ -11341,7 +11313,7 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE), - errdetail("Timeline ID parsed is %u, but expected %u", + errdetail("Timeline ID parsed is %u, but expected %u.", tli_from_file, tli_from_walseg))); ereport(DEBUG1, @@ -11567,13 +11539,14 @@ CancelBackup(void) */ static int XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, - XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *readTLI) + XLogRecPtr targetRecPtr, char *readBuf) { XLogPageReadPrivate *private = (XLogPageReadPrivate *) xlogreader->private_data; int emode = private->emode; uint32 targetPageOff; XLogSegNo targetSegNo PG_USED_FOR_ASSERTS_ONLY; + int r; XLByteToSeg(targetPagePtr, targetSegNo, wal_segment_size); targetPageOff = XLogSegmentOffset(targetPagePtr, wal_segment_size); @@ -11652,29 +11625,29 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, /* Read the requested page */ readOff = targetPageOff; - if (lseek(readFile, (off_t) readOff, SEEK_SET) < 0) - { - char fname[MAXFNAMELEN]; - - XLogFileName(fname, curFileTLI, readSegNo, wal_segment_size); - ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), - (errcode_for_file_access(), - errmsg("could not seek in log segment %s to offset %u: %m", - fname, readOff))); - goto next_record_is_invalid; - } pgstat_report_wait_start(WAIT_EVENT_WAL_READ); - if (read(readFile, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + r = pg_pread(readFile, readBuf, XLOG_BLCKSZ, (off_t) readOff); + if (r != XLOG_BLCKSZ) { char fname[MAXFNAMELEN]; + int save_errno = errno; pgstat_report_wait_end(); XLogFileName(fname, curFileTLI, readSegNo, wal_segment_size); - ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), - (errcode_for_file_access(), - errmsg("could not read from log segment %s, offset %u: %m", - fname, readOff))); + if (r < 0) + { + errno = save_errno; + ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), + (errcode_for_file_access(), + errmsg("could not read from log segment %s, offset %u: %m", + fname, readOff))); + } + else + ereport(emode_for_corrupt_record(emode, targetPagePtr + reqLen), + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read from log segment %s, offset %u: read %d of %zu", + fname, readOff, r, (Size) XLOG_BLCKSZ))); goto next_record_is_invalid; } pgstat_report_wait_end(); @@ -11683,7 +11656,41 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, Assert(targetPageOff == readOff); Assert(reqLen <= readLen); - *readTLI = curFileTLI; + xlogreader->seg.ws_tli = curFileTLI; + + /* + * Check the page header immediately, so that we can retry immediately if + * it's not valid. This may seem unnecessary, because XLogReadRecord() + * validates the page header anyway, and would propagate the failure up to + * ReadRecord(), which would retry. However, there's a corner case with + * continuation records, if a record is split across two pages such that + * we would need to read the two pages from different sources. For + * example, imagine a scenario where a streaming replica is started up, + * and replay reaches a record that's split across two WAL segments. The + * first page is only available locally, in pg_wal, because it's already + * been recycled in the master. The second page, however, is not present + * in pg_wal, and we should stream it from the master. There is a recycled + * WAL segment present in pg_wal, with garbage contents, however. We would + * read the first page from the local WAL segment, but when reading the + * second page, we would read the bogus, recycled, WAL segment. If we + * didn't catch that case here, we would never recover, because + * ReadRecord() would retry reading the whole record from the beginning. + * + * Of course, this only catches errors in the page header, which is what + * happens in the case of a recycled WAL segment. Other kinds of errors or + * corruption still has the same problem. But this at least fixes the + * common case, which can happen as part of normal operation. + * + * Validating the page header is cheap enough that doing it twice + * shouldn't be a big deal from a performance point of view. + */ + if (!XLogReaderValidatePageHeader(xlogreader, targetPagePtr, readBuf)) + { + /* reset any error XLogReaderValidatePageHeader() might have set */ + xlogreader->errormsg_buf[0] = '\0'; + goto next_record_is_invalid; + } + return readLen; next_record_is_invalid: @@ -11806,7 +11813,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, * that when we later jump backwards to start redo at * RedoStartLSN, we will have the logs streamed already. */ - if (PrimaryConnInfo) + if (PrimaryConnInfo && strcmp(PrimaryConnInfo, "") != 0) { XLogRecPtr ptr; TimeLineID tli; @@ -11818,12 +11825,18 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, } else { - ptr = tliRecPtr; + ptr = RecPtr; + + /* + * Use the record begin position to determine the + * TLI, rather than the position we're reading. + */ tli = tliOfPointInHistory(tliRecPtr, expectedTLEs); if (curFileTLI > 0 && tli < curFileTLI) elog(ERROR, "according to history file, WAL location %X/%X belongs to timeline %u, but previous recovered WAL file came from timeline %u", - (uint32) (ptr >> 32), (uint32) ptr, + (uint32) (tliRecPtr >> 32), + (uint32) tliRecPtr, tli, curFileTLI); } curFileTLI = tli; @@ -11869,7 +11882,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, * Before we sleep, re-scan for possible new timelines if * we were requested to recover to the latest timeline. */ - if (recoveryTargetIsLatest) + if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_LATEST) { if (rescanLatestTimeLine()) { @@ -11898,9 +11911,11 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, wait_time = wal_retrieve_retry_interval - (secs * 1000 + usecs / 1000); - WaitLatch(&XLogCtl->recoveryWakeupLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - wait_time, WAIT_EVENT_RECOVERY_WAL_STREAM); + (void) WaitLatch(&XLogCtl->recoveryWakeupLatch, + WL_LATCH_SET | WL_TIMEOUT | + WL_EXIT_ON_PM_DEATH, + wait_time, + WAIT_EVENT_RECOVERY_WAL_STREAM); ResetLatch(&XLogCtl->recoveryWakeupLatch); now = GetCurrentTimestamp(); } @@ -12072,11 +12087,13 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool randAccess, /* * Wait for more WAL to arrive. Time out after 5 seconds - * to react to a trigger file promptly. + * to react to a trigger file promptly and to check if the + * WAL receiver is still active. */ - WaitLatch(&XLogCtl->recoveryWakeupLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - 5000L, WAIT_EVENT_RECOVERY_WAL_ALL); + (void) WaitLatch(&XLogCtl->recoveryWakeupLatch, + WL_LATCH_SET | WL_TIMEOUT | + WL_EXIT_ON_PM_DEATH, + 5000L, WAIT_EVENT_RECOVERY_WAL_ALL); ResetLatch(&XLogCtl->recoveryWakeupLatch); break; } @@ -12169,14 +12186,14 @@ CheckForStandbyTrigger(void) return true; } - if (TriggerFile == NULL) + if (PromoteTriggerFile == NULL || strcmp(PromoteTriggerFile, "") == 0) return false; - if (stat(TriggerFile, &stat_buf) == 0) + if (stat(PromoteTriggerFile, &stat_buf) == 0) { ereport(LOG, - (errmsg("trigger file found: %s", TriggerFile))); - unlink(TriggerFile); + (errmsg("promote trigger file found: %s", PromoteTriggerFile))); + unlink(PromoteTriggerFile); triggered = true; fast_promote = true; return true; @@ -12184,8 +12201,8 @@ CheckForStandbyTrigger(void) else if (errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not stat trigger file \"%s\": %m", - TriggerFile))); + errmsg("could not stat promote trigger file \"%s\": %m", + PromoteTriggerFile))); return false; } diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c index 5c6de4989c9..9a21f006d1d 100644 --- a/src/backend/access/transam/xlogarchive.c +++ b/src/backend/access/transam/xlogarchive.c @@ -4,7 +4,7 @@ * Functions for archiving WAL files and restoring from the archive. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogarchive.c @@ -59,14 +59,13 @@ RestoreArchivedFile(char *path, const char *xlogfname, char *endp; const char *sp; int rc; - bool signaled; struct stat stat_buf; XLogSegNo restartSegNo; XLogRecPtr restartRedoPtr; TimeLineID restartTli; /* In standby mode, restore_command might not be supplied */ - if (recoveryRestoreCommand == NULL) + if (recoveryRestoreCommand == NULL || strcmp(recoveryRestoreCommand, "") == 0) goto not_available; /* @@ -289,17 +288,12 @@ RestoreArchivedFile(char *path, const char *xlogfname, * will perform an immediate shutdown when it sees us exiting * unexpectedly. * - * Per the Single Unix Spec, shells report exit status > 128 when a called - * command died on a signal. Also, 126 and 127 are used to report - * problems such as an unfindable command; treat those as fatal errors - * too. + * We treat hard shell errors such as "command not found" as fatal, too. */ - if (WIFSIGNALED(rc) && WTERMSIG(rc) == SIGTERM) + if (wait_result_is_signal(rc, SIGTERM)) proc_exit(1); - signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125; - - ereport(signaled ? FATAL : DEBUG2, + ereport(wait_result_is_any_signal(rc, true) ? FATAL : DEBUG2, (errmsg("could not restore file \"%s\" from archive: %s", xlogfname, wait_result_to_str(rc)))); @@ -335,7 +329,6 @@ ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOn char *endp; const char *sp; int rc; - bool signaled; XLogSegNo restartSegNo; XLogRecPtr restartRedoPtr; TimeLineID restartTli; @@ -403,14 +396,11 @@ ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOn { /* * If the failure was due to any sort of signal, it's best to punt and - * abort recovery. See also detailed comments on signals in - * RestoreArchivedFile(). + * abort recovery. See comments in RestoreArchivedFile(). */ - signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 125; - - ereport((signaled && failOnSignal) ? FATAL : WARNING, + ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING, /*------ - translator: First %s represents a recovery.conf parameter name like + translator: First %s represents a postgresql.conf parameter name like "recovery_end_command", the 2nd is the value of that parameter, the third an already translated error message. */ (errmsg("%s \"%s\": %s", commandName, @@ -422,7 +412,7 @@ ExecuteRecoveryCommand(const char *command, const char *commandName, bool failOn /* * A file was restored from the archive under a temporary filename (path), * and now we want to keep it. Rename it under the permanent filename in - * in pg_wal (xlogfname), replacing any existing file with the same name. + * pg_wal (xlogfname), replacing any existing file with the same name. */ void KeepFileRestoredFromArchive(const char *path, const char *xlogfname) @@ -620,9 +610,16 @@ XLogArchiveCheckDone(const char *xlog) { char archiveStatusPath[MAXPGPATH]; struct stat stat_buf; + bool inRecovery = RecoveryInProgress(); - /* Always deletable if archiving is off */ - if (!XLogArchivingActive()) + /* + * The file is always deletable if archive_mode is "off". On standbys + * archiving is disabled if archive_mode is "on", and enabled with + * "always". On a primary, archiving is enabled if archive_mode is "on" + * or "always". + */ + if (!((XLogArchivingActive() && !inRecovery) || + (XLogArchivingAlways() && inRecovery))) return true; /* First check for .done --- this means archiver is done with it */ diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index 97317429786..8f179887ab1 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -7,7 +7,7 @@ * This file contains WAL control and information functions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogfuncs.c @@ -16,6 +16,8 @@ */ #include "postgres.h" +#include + #include "access/htup_details.h" #include "access/xlog.h" #include "access/xlog_internal.h" @@ -23,6 +25,7 @@ #include "catalog/pg_type.h" #include "funcapi.h" #include "miscadmin.h" +#include "pgstat.h" #include "replication/walreceiver.h" #include "storage/smgr.h" #include "utils/builtins.h" @@ -264,7 +267,7 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS) values[0] = LSNGetDatum(stoppoint); tuplestore_putvalues(tupstore, tupdesc, values, nulls); - tuplestore_donestoring(typstore); + tuplestore_donestoring(tupstore); return (Datum) 0; } @@ -462,13 +465,14 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"), - errhint("pg_walfile_name_offset() cannot be executed during recovery."))); + errhint("%s cannot be executed during recovery.", + "pg_walfile_name_offset()"))); /* * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - resultTupleDesc = CreateTemplateTupleDesc(2, false); + resultTupleDesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "file_name", TEXTOID, -1, 0); TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset", @@ -518,7 +522,8 @@ pg_walfile_name(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"), - errhint("pg_walfile_name() cannot be executed during recovery."))); + errhint("%s cannot be executed during recovery.", + "pg_walfile_name()"))); XLByteToPrevSeg(locationpoint, xlogsegno, wal_segment_size); XLogFileName(xlogfilename, ThisTimeLineID, xlogsegno, wal_segment_size); @@ -697,3 +702,86 @@ pg_backup_start_time(PG_FUNCTION_ARGS) PG_RETURN_DATUM(xtime); } + +/* + * Promotes a standby server. + * + * A result of "true" means that promotion has been completed if "wait" is + * "true", or initiated if "wait" is false. + */ +Datum +pg_promote(PG_FUNCTION_ARGS) +{ + bool wait = PG_GETARG_BOOL(0); + int wait_seconds = PG_GETARG_INT32(1); + FILE *promote_file; + int i; + + if (!RecoveryInProgress()) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("recovery is not in progress"), + errhint("Recovery control functions can only be executed during recovery."))); + + if (wait_seconds <= 0) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"wait_seconds\" must not be negative or zero"))); + + /* create the promote signal file */ + promote_file = AllocateFile(PROMOTE_SIGNAL_FILE, "w"); + if (!promote_file) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not create file \"%s\": %m", + PROMOTE_SIGNAL_FILE))); + + if (FreeFile(promote_file)) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not write file \"%s\": %m", + PROMOTE_SIGNAL_FILE))); + + /* signal the postmaster */ + if (kill(PostmasterPid, SIGUSR1) != 0) + { + ereport(WARNING, + (errmsg("failed to send signal to postmaster: %m"))); + (void) unlink(PROMOTE_SIGNAL_FILE); + PG_RETURN_BOOL(false); + } + + /* return immediately if waiting was not requested */ + if (!wait) + PG_RETURN_BOOL(true); + + /* wait for the amount of time wanted until promotion */ +#define WAITS_PER_SECOND 10 + for (i = 0; i < WAITS_PER_SECOND * wait_seconds; i++) + { + int rc; + + ResetLatch(MyLatch); + + if (!RecoveryInProgress()) + PG_RETURN_BOOL(true); + + CHECK_FOR_INTERRUPTS(); + + rc = WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + 1000L / WAITS_PER_SECOND, + WAIT_EVENT_PROMOTE); + + /* + * Emergency bailout if postmaster has died. This is to avoid the + * necessity for manual cleanup of all postmaster children. + */ + if (rc & WL_POSTMASTER_DEATH) + PG_RETURN_BOOL(false); + } + + ereport(WARNING, + (errmsg("server did not promote within %d seconds", wait_seconds))); + PG_RETURN_BOOL(false); +} diff --git a/src/backend/access/transam/xloginsert.c b/src/backend/access/transam/xloginsert.c index 5bea073a2b7..3ec67d468b5 100644 --- a/src/backend/access/transam/xloginsert.c +++ b/src/backend/access/transam/xloginsert.c @@ -9,7 +9,7 @@ * of XLogRecData structs by a call to XLogRecordAssemble(). See * access/transam/README for details. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xloginsert.c @@ -107,10 +107,10 @@ static bool begininsert_called = false; static MemoryContext xloginsert_cxt; static XLogRecData *XLogRecordAssemble(RmgrId rmid, uint8 info, - XLogRecPtr RedoRecPtr, bool doPageWrites, - XLogRecPtr *fpw_lsn); + XLogRecPtr RedoRecPtr, bool doPageWrites, + XLogRecPtr *fpw_lsn); static bool XLogCompressBackupBlock(char *page, uint16 hole_offset, - uint16 hole_length, char *dest, uint16 *dlen); + uint16 hole_length, char *dest, uint16 *dlen); /* * Begin constructing a WAL record. This must be called before the @@ -605,7 +605,7 @@ XLogRecordAssemble(RmgrId rmid, uint8 info, } else { - /* No "hole" to compress out */ + /* No "hole" to remove */ bimg.hole_offset = 0; cbimg.hole_length = 0; } @@ -809,12 +809,12 @@ XLogCompressBackupBlock(char *page, uint16 hole_offset, uint16 hole_length, int32 len; int32 extra_bytes = 0; char *source; - char tmp[BLCKSZ]; + PGAlignedBlock tmp; if (hole_length != 0) { /* must skip the hole */ - source = tmp; + source = tmp.data; memcpy(source, page, hole_offset); memcpy(source + hole_offset, page + (hole_offset + hole_length), @@ -917,7 +917,7 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std) if (lsn <= RedoRecPtr) { int flags; - char copied_buffer[BLCKSZ]; + PGAlignedBlock copied_buffer; char *origdata = (char *) BufferGetBlock(buffer); RelFileNode rnode; ForkNumber forkno; @@ -935,11 +935,11 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std) uint16 lower = ((PageHeader) page)->pd_lower; uint16 upper = ((PageHeader) page)->pd_upper; - memcpy(copied_buffer, origdata, lower); - memcpy(copied_buffer + upper, origdata + upper, BLCKSZ - upper); + memcpy(copied_buffer.data, origdata, lower); + memcpy(copied_buffer.data + upper, origdata + upper, BLCKSZ - upper); } else - memcpy(copied_buffer, origdata, BLCKSZ); + memcpy(copied_buffer.data, origdata, BLCKSZ); XLogBeginInsert(); @@ -948,7 +948,7 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std) flags |= REGBUF_STANDARD; BufferGetTag(buffer, &rnode, &forkno, &blkno); - XLogRegisterBlock(0, &rnode, forkno, blkno, copied_buffer, flags); + XLogRegisterBlock(0, &rnode, forkno, blkno, copied_buffer.data, flags); recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI_FOR_HINT); } @@ -1021,6 +1021,88 @@ log_newpage_buffer(Buffer buffer, bool page_std) return log_newpage(&rnode, forkNum, blkno, page, page_std); } +/* + * WAL-log a range of blocks in a relation. + * + * An image of all pages with block numbers 'startblk' <= X < 'endblk' is + * written to the WAL. If the range is large, this is done in multiple WAL + * records. + * + * If all page follows the standard page layout, with a PageHeader and unused + * space between pd_lower and pd_upper, set 'page_std' to true. That allows + * the unused space to be left out from the WAL records, making them smaller. + * + * NOTE: This function acquires exclusive-locks on the pages. Typically, this + * is used on a newly-built relation, and the caller is holding a + * AccessExclusiveLock on it, so no other backend can be accessing it at the + * same time. If that's not the case, you must ensure that this does not + * cause a deadlock through some other means. + */ +void +log_newpage_range(Relation rel, ForkNumber forkNum, + BlockNumber startblk, BlockNumber endblk, + bool page_std) +{ + BlockNumber blkno; + + /* + * Iterate over all the pages in the range. They are collected into + * batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written + * for each batch. + */ + XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID - 1, 0); + + blkno = startblk; + while (blkno < endblk) + { + Buffer bufpack[XLR_MAX_BLOCK_ID]; + XLogRecPtr recptr; + int nbufs; + int i; + + CHECK_FOR_INTERRUPTS(); + + /* Collect a batch of blocks. */ + nbufs = 0; + while (nbufs < XLR_MAX_BLOCK_ID && blkno < endblk) + { + Buffer buf = ReadBuffer(rel, blkno); + + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + + /* + * Completely empty pages are not WAL-logged. Writing a WAL record + * would change the LSN, and we don't want that. We want the page + * to stay empty. + */ + if (!PageIsNew(BufferGetPage(buf))) + bufpack[nbufs++] = buf; + else + UnlockReleaseBuffer(buf); + blkno++; + } + + /* Write WAL record for this batch. */ + XLogBeginInsert(); + + START_CRIT_SECTION(); + for (i = 0; i < nbufs; i++) + { + XLogRegisterBuffer(i, bufpack[i], REGBUF_FORCE_IMAGE | REGBUF_STANDARD); + MarkBufferDirty(bufpack[i]); + } + + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI); + + for (i = 0; i < nbufs; i++) + { + PageSetLSN(BufferGetPage(bufpack[i]), recptr); + UnlockReleaseBuffer(bufpack[i]); + } + END_CRIT_SECTION(); + } +} + /* * Allocate working buffers needed for WAL record construction. */ diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c index 3a86f3497eb..c8b0d2303d3 100644 --- a/src/backend/access/transam/xlogreader.c +++ b/src/backend/access/transam/xlogreader.c @@ -3,7 +3,7 @@ * xlogreader.c * Generic XLog reading facility * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/access/transam/xlogreader.c @@ -25,18 +25,22 @@ #include "common/pg_lzcompress.h" #include "replication/origin.h" -static bool allocate_recordbuf(XLogReaderState *state, uint32 reclength); +#ifndef FRONTEND +#include "miscadmin.h" +#include "utils/memutils.h" +#endif + -static bool ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, - XLogPageHeader hdr); +static void report_invalid_record(XLogReaderState *state, const char *fmt,...) + pg_attribute_printf(2, 3); +static bool allocate_recordbuf(XLogReaderState *state, uint32 reclength); +static int ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, + int reqLen); +static void XLogReaderInvalReadState(XLogReaderState *state); static bool ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, - XLogRecPtr PrevRecPtr, XLogRecord *record, bool randAccess); + XLogRecPtr PrevRecPtr, XLogRecord *record, bool randAccess); static bool ValidXLogRecord(XLogReaderState *state, XLogRecord *record, - XLogRecPtr recptr); -static int ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, - int reqLen); -static void report_invalid_record(XLogReaderState *state, const char *fmt,...) pg_attribute_printf(2, 3); - + XLogRecPtr recptr); static void ResetDecoder(XLogReaderState *state); /* size of the buffer allocated for error message. */ @@ -64,8 +68,8 @@ report_invalid_record(XLogReaderState *state, const char *fmt,...) * Returns NULL if the xlogreader couldn't be allocated. */ XLogReaderState * -XLogReaderAllocate(int wal_segment_size, XLogPageReadCB pagereadfunc, - void *private_data) +XLogReaderAllocate(int wal_segment_size, const char *waldir, + XLogPageReadCB pagereadfunc, void *private_data) { XLogReaderState *state; @@ -92,12 +96,14 @@ XLogReaderAllocate(int wal_segment_size, XLogPageReadCB pagereadfunc, return NULL; } - state->wal_segment_size = wal_segment_size; + /* Initialize segment info. */ + WALOpenSegmentInit(&state->seg, &state->segcxt, wal_segment_size, + waldir); + state->read_page = pagereadfunc; /* system_identifier initialized to zeroes above */ state->private_data = private_data; - /* ReadRecPtr and EndRecPtr initialized to zeroes above */ - /* readSegNo, readOff, readLen, readPageTLI initialized to zeroes above */ + /* ReadRecPtr, EndRecPtr and readLen initialized to zeroes above */ state->errormsg_buf = palloc_extended(MAX_ERRORMSG_LEN + 1, MCXT_ALLOC_NO_OOM); if (!state->errormsg_buf) @@ -162,6 +168,25 @@ allocate_recordbuf(XLogReaderState *state, uint32 reclength) newSize += XLOG_BLCKSZ - (newSize % XLOG_BLCKSZ); newSize = Max(newSize, 5 * Max(BLCKSZ, XLOG_BLCKSZ)); +#ifndef FRONTEND + + /* + * Note that in much unlucky circumstances, the random data read from a + * recycled segment can cause this routine to be called with a size + * causing a hard failure at allocation. For a standby, this would cause + * the instance to stop suddenly with a hard failure, preventing it to + * retry fetching WAL from one of its sources which could allow it to move + * on with replay without a manual restart. If the data comes from a past + * recycled segment and is still valid, then the allocation may succeed + * but record checks are going to fail so this would be short-lived. If + * the allocation fails because of a memory shortage, then this is not a + * hard failure either per the guarantee given by MCXT_ALLOC_NO_OOM. + */ + if (!AllocSizeIsValid(newSize)) + return false; + +#endif + if (state->readRecordBuf) pfree(state->readRecordBuf); state->readRecordBuf = @@ -175,6 +200,23 @@ allocate_recordbuf(XLogReaderState *state, uint32 reclength) return true; } +/* + * Initialize the passed segment structs. + */ +void +WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt, + int segsize, const char *waldir) +{ + seg->ws_file = -1; + seg->ws_segno = 0; + seg->ws_off = 0; + seg->ws_tli = 0; + + segcxt->ws_segsize = segsize; + if (waldir) + snprintf(segcxt->ws_dir, MAXPGPATH, "%s", waldir); +} + /* * Attempt to read an XLOG record. * @@ -332,19 +374,6 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg) gotheader = false; } - /* - * Enlarge readRecordBuf as needed. - */ - if (total_len > state->readRecordBufSize && - !allocate_recordbuf(state, total_len)) - { - /* We treat this as a "bogus data" condition */ - report_invalid_record(state, "record length %u at %X/%X too long", - total_len, - (uint32) (RecPtr >> 32), (uint32) RecPtr); - goto err; - } - len = XLOG_BLCKSZ - RecPtr % XLOG_BLCKSZ; if (total_len > len) { @@ -354,6 +383,19 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg) char *buffer; uint32 gotlen; + /* + * Enlarge readRecordBuf as needed. + */ + if (total_len > state->readRecordBufSize && + !allocate_recordbuf(state, total_len)) + { + /* We treat this as a "bogus data" condition */ + report_invalid_record(state, "record length %u at %X/%X too long", + total_len, + (uint32) (RecPtr >> 32), (uint32) RecPtr); + goto err; + } + /* Copy the first fragment of the record from the first page. */ memcpy(state->readRecordBuf, state->readBuf + RecPtr % XLOG_BLCKSZ, len); @@ -458,7 +500,6 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg) state->EndRecPtr = RecPtr + MAXALIGN(total_len); state->ReadRecPtr = RecPtr; - memcpy(state->readRecordBuf, record, total_len); } /* @@ -468,8 +509,8 @@ XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg) (record->xl_info & ~XLR_INFO_MASK) == XLOG_SWITCH) { /* Pretend it extends to end of segment */ - state->EndRecPtr += state->wal_segment_size - 1; - state->EndRecPtr -= XLogSegmentOffset(state->EndRecPtr, state->wal_segment_size); + state->EndRecPtr += state->segcxt.ws_segsize - 1; + state->EndRecPtr -= XLogSegmentOffset(state->EndRecPtr, state->segcxt.ws_segsize); } if (DecodeXLogRecord(state, record, errormsg)) @@ -511,12 +552,12 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) Assert((pageptr % XLOG_BLCKSZ) == 0); - XLByteToSeg(pageptr, targetSegNo, state->wal_segment_size); - targetPageOff = XLogSegmentOffset(pageptr, state->wal_segment_size); + XLByteToSeg(pageptr, targetSegNo, state->segcxt.ws_segsize); + targetPageOff = XLogSegmentOffset(pageptr, state->segcxt.ws_segsize); /* check whether we have all the requested data already */ - if (targetSegNo == state->readSegNo && targetPageOff == state->readOff && - reqLen < state->readLen) + if (targetSegNo == state->seg.ws_segno && + targetPageOff == state->seg.ws_off && reqLen <= state->readLen) return state->readLen; /* @@ -531,23 +572,21 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) * record is. This is so that we can check the additional identification * info that is present in the first page's "long" header. */ - if (targetSegNo != state->readSegNo && targetPageOff != 0) + if (targetSegNo != state->seg.ws_segno && targetPageOff != 0) { - XLogPageHeader hdr; XLogRecPtr targetSegmentPtr = pageptr - targetPageOff; readLen = state->read_page(state, targetSegmentPtr, XLOG_BLCKSZ, state->currRecPtr, - state->readBuf, &state->readPageTLI); + state->readBuf); if (readLen < 0) goto err; /* we can be sure to have enough WAL available, we scrolled back */ Assert(readLen == XLOG_BLCKSZ); - hdr = (XLogPageHeader) state->readBuf; - - if (!ValidXLogPageHeader(state, targetSegmentPtr, hdr)) + if (!XLogReaderValidatePageHeader(state, targetSegmentPtr, + state->readBuf)) goto err; } @@ -557,7 +596,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) */ readLen = state->read_page(state, pageptr, Max(reqLen, SizeOfXLogShortPHD), state->currRecPtr, - state->readBuf, &state->readPageTLI); + state->readBuf); if (readLen < 0) goto err; @@ -576,7 +615,7 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) { readLen = state->read_page(state, pageptr, XLogPageHeaderSize(hdr), state->currRecPtr, - state->readBuf, &state->readPageTLI); + state->readBuf); if (readLen < 0) goto err; } @@ -584,12 +623,12 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) /* * Now that we know we have the full header, validate it. */ - if (!ValidXLogPageHeader(state, pageptr, hdr)) + if (!XLogReaderValidatePageHeader(state, pageptr, (char *) hdr)) goto err; /* update read state information */ - state->readSegNo = targetSegNo; - state->readOff = targetPageOff; + state->seg.ws_segno = targetSegNo; + state->seg.ws_off = targetPageOff; state->readLen = readLen; return readLen; @@ -602,11 +641,11 @@ ReadPageInternal(XLogReaderState *state, XLogRecPtr pageptr, int reqLen) /* * Invalidate the xlogreader's read state to force a re-read. */ -void +static void XLogReaderInvalReadState(XLogReaderState *state) { - state->readSegNo = 0; - state->readOff = 0; + state->seg.ws_segno = 0; + state->seg.ws_off = 0; state->readLen = 0; } @@ -683,7 +722,7 @@ ValidXLogRecordHeader(XLogReaderState *state, XLogRecPtr RecPtr, * We assume all of the record (that is, xl_tot_len bytes) has been read * into memory at *record. Also, ValidXLogRecordHeader() has accepted the * record's header, which means in particular that xl_tot_len is at least - * SizeOfXlogRecord. + * SizeOfXLogRecord. */ static bool ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) @@ -709,28 +748,32 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr) } /* - * Validate a page header + * Validate a page header. + * + * Check if 'phdr' is valid as the header of the XLog page at position + * 'recptr'. */ -static bool -ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, - XLogPageHeader hdr) +bool +XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr, + char *phdr) { XLogRecPtr recaddr; XLogSegNo segno; int32 offset; + XLogPageHeader hdr = (XLogPageHeader) phdr; Assert((recptr % XLOG_BLCKSZ) == 0); - XLByteToSeg(recptr, segno, state->wal_segment_size); - offset = XLogSegmentOffset(recptr, state->wal_segment_size); + XLByteToSeg(recptr, segno, state->segcxt.ws_segsize); + offset = XLogSegmentOffset(recptr, state->segcxt.ws_segsize); - XLogSegNoOffsetToRecPtr(segno, offset, recaddr, state->wal_segment_size); + XLogSegNoOffsetToRecPtr(segno, offset, state->segcxt.ws_segsize, recaddr); if (hdr->xlp_magic != XLOG_PAGE_MAGIC) { char fname[MAXFNAMELEN]; - XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size); + XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, "invalid magic number %04X in log segment %s, offset %u", @@ -744,7 +787,7 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, { char fname[MAXFNAMELEN]; - XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size); + XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, "invalid info bits %04X in log segment %s, offset %u", @@ -761,23 +804,13 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, if (state->system_identifier && longhdr->xlp_sysid != state->system_identifier) { - char fhdrident_str[32]; - char sysident_str[32]; - - /* - * Format sysids separately to keep platform-dependent format code - * out of the translatable message string. - */ - snprintf(fhdrident_str, sizeof(fhdrident_str), UINT64_FORMAT, - longhdr->xlp_sysid); - snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT, - state->system_identifier); report_invalid_record(state, - "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s", - fhdrident_str, sysident_str); + "WAL file is from different database system: WAL file database system identifier is %llu, pg_control database system identifier is %llu", + (unsigned long long) longhdr->xlp_sysid, + (unsigned long long) state->system_identifier); return false; } - else if (longhdr->xlp_seg_size != state->wal_segment_size) + else if (longhdr->xlp_seg_size != state->segcxt.ws_segsize) { report_invalid_record(state, "WAL file is from different database system: incorrect segment size in page header"); @@ -794,7 +827,7 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, { char fname[MAXFNAMELEN]; - XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size); + XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); /* hmm, first page of file doesn't have a long header? */ report_invalid_record(state, @@ -805,11 +838,16 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, return false; } + /* + * Check that the address on the page agrees with what we expected. This + * check typically fails when an old WAL segment is recycled, and hasn't + * yet been overwritten with new data yet. + */ if (hdr->xlp_pageaddr != recaddr) { char fname[MAXFNAMELEN]; - XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size); + XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, "unexpected pageaddr %X/%X in log segment %s, offset %u", @@ -834,7 +872,7 @@ ValidXLogPageHeader(XLogReaderState *state, XLogRecPtr recptr, { char fname[MAXFNAMELEN]; - XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size); + XLogFileName(fname, state->seg.ws_tli, segno, state->segcxt.ws_segsize); report_invalid_record(state, "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u", @@ -978,7 +1016,6 @@ XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr) #endif /* FRONTEND */ - /* ---------------------------------------- * Functions for decoding the data and block references in a record. * ---------------------------------------- @@ -1384,7 +1421,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) { DecodedBkpBlock *bkpb; char *ptr; - char tmp[BLCKSZ]; + PGAlignedBlock tmp; if (!record->blocks[block_id].in_use) return false; @@ -1397,8 +1434,8 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) if (bkpb->bimg_info & BKPIMAGE_IS_COMPRESSED) { /* If a backup block image is compressed, decompress it */ - if (pglz_decompress(ptr, bkpb->bimg_len, tmp, - BLCKSZ - bkpb->hole_length) < 0) + if (pglz_decompress(ptr, bkpb->bimg_len, tmp.data, + BLCKSZ - bkpb->hole_length, true) < 0) { report_invalid_record(record, "invalid compressed image at %X/%X, block %d", (uint32) (record->ReadRecPtr >> 32), @@ -1406,7 +1443,7 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) block_id); return false; } - ptr = tmp; + ptr = tmp.data; } /* generate page, taking into account hole if necessary */ @@ -1426,3 +1463,37 @@ RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page) return true; } + +#ifndef FRONTEND + +/* + * Extract the FullTransactionId from a WAL record. + */ +FullTransactionId +XLogRecGetFullXid(XLogReaderState *record) +{ + TransactionId xid, + next_xid; + uint32 epoch; + + /* + * This function is only safe during replay, because it depends on the + * replay state. See AdvanceNextFullTransactionIdPastXid() for more. + */ + Assert(AmStartupProcess() || !IsUnderPostmaster); + + xid = XLogRecGetXid(record); + next_xid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); + epoch = EpochFromFullTransactionId(ShmemVariableCache->nextFullXid); + + /* + * If xid is numerically greater than next_xid, it has to be from the + * last epoch. + */ + if (unlikely(xid > next_xid)) + --epoch; + + return FullTransactionIdFromEpochAndXid(epoch, xid); +} + +#endif diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index 52fe55e2afb..5f1e5ba75d5 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -8,7 +8,7 @@ * None of this code is used during normal system operation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/access/transam/xlogutils.c @@ -523,7 +523,7 @@ XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, } /* - * Struct actually returned by XLogFakeRelcacheEntry, though the declared + * Struct actually returned by CreateFakeRelcacheEntry, though the declared * return type is Relation. */ typedef struct @@ -718,9 +718,10 @@ XLogRead(char *buf, int segsize, TimeLineID tli, XLogRecPtr startptr, if (lseek(sendFile, (off_t) startoff, SEEK_SET) < 0) { char path[MAXPGPATH]; + int save_errno = errno; XLogFilePath(path, tli, sendSegNo, segsize); - + errno = save_errno; ereport(ERROR, (errcode_for_file_access(), errmsg("could not seek in log segment %s to offset %u: %m", @@ -741,9 +742,10 @@ XLogRead(char *buf, int segsize, TimeLineID tli, XLogRecPtr startptr, if (readbytes <= 0) { char path[MAXPGPATH]; + int save_errno = errno; XLogFilePath(path, tli, sendSegNo, segsize); - + errno = save_errno; ereport(ERROR, (errcode_for_file_access(), errmsg("could not read from log segment %s, offset %u, length %lu: %m", @@ -800,8 +802,8 @@ XLogRead(char *buf, int segsize, TimeLineID tli, XLogRecPtr startptr, void XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wantLength) { - const XLogRecPtr lastReadPage = state->readSegNo * - state->wal_segment_size + state->readOff; + const XLogRecPtr lastReadPage = state->seg.ws_segno * + state->segcxt.ws_segsize + state->seg.ws_off; Assert(wantPage != InvalidXLogRecPtr && wantPage % XLOG_BLCKSZ == 0); Assert(wantLength <= XLOG_BLCKSZ); @@ -845,8 +847,8 @@ XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wa if (state->currTLIValidUntil != InvalidXLogRecPtr && state->currTLI != ThisTimeLineID && state->currTLI != 0 && - ((wantPage + wantLength) / state->wal_segment_size) < - (state->currTLIValidUntil / state->wal_segment_size)) + ((wantPage + wantLength) / state->segcxt.ws_segsize) < + (state->currTLIValidUntil / state->segcxt.ws_segsize)) return; /* @@ -867,12 +869,12 @@ XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wa * by a promotion or replay from a cascaded replica. */ List *timelineHistory = readTimeLineHistory(ThisTimeLineID); + XLogRecPtr endOfSegment; - XLogRecPtr endOfSegment = (((wantPage / state->wal_segment_size) + 1) - * state->wal_segment_size) - 1; - - Assert(wantPage / state->wal_segment_size == - endOfSegment / state->wal_segment_size); + endOfSegment = ((wantPage / state->segcxt.ws_segsize) + 1) * + state->segcxt.ws_segsize - 1; + Assert(wantPage / state->segcxt.ws_segsize == + endOfSegment / state->segcxt.ws_segsize); /* * Find the timeline of the last LSN on the segment containing @@ -907,8 +909,7 @@ XLogReadDetermineTimeline(XLogReaderState *state, XLogRecPtr wantPage, uint32 wa */ int read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, char *cur_page, - TimeLineID *pageTLI) + int reqLen, XLogRecPtr targetRecPtr, char *cur_page) { XLogRecPtr read_upto, loc; @@ -931,8 +932,7 @@ read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, read_upto = GetFlushRecPtr(); else read_upto = GetXLogReplayRecPtr(&ThisTimeLineID); - - *pageTLI = ThisTimeLineID; + state->seg.ws_tli = ThisTimeLineID; /* * Check which timeline to get the record from. @@ -982,14 +982,14 @@ read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, read_upto = state->currTLIValidUntil; /* - * Setting pageTLI to our wanted record's TLI is slightly wrong; + * Setting ws_tli to our wanted record's TLI is slightly wrong; * the page might begin on an older timeline if it contains a * timeline switch, since its xlog segment will have been copied * from the prior timeline. This is pretty harmless though, as * nothing cares so long as the timeline doesn't go backwards. We * should read the page header instead; FIXME someday. */ - *pageTLI = state->currTLI; + state->seg.ws_tli = state->currTLI; /* No need to wait on a historical timeline */ break; @@ -1020,7 +1020,7 @@ read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, * as 'count', read the whole page anyway. It's guaranteed to be * zero-padded up to the page boundary if it's incomplete. */ - XLogRead(cur_page, state->wal_segment_size, *pageTLI, targetPagePtr, + XLogRead(cur_page, state->segcxt.ws_segsize, state->seg.ws_tli, targetPagePtr, XLOG_BLCKSZ); /* number of valid bytes in the buffer */ diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y index 1ec0e5c8a9c..4f2587d74af 100644 --- a/src/backend/bootstrap/bootparse.y +++ b/src/backend/bootstrap/bootparse.y @@ -4,7 +4,7 @@ * bootparse.y * yacc grammar for the "bootstrap" mode (BKI file format) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -105,6 +105,7 @@ static int num_columns_read = 0; List *list; IndexElem *ielem; char *str; + const char *kw; int ival; Oid oidval; } @@ -112,21 +113,21 @@ static int num_columns_read = 0; %type boot_index_params %type boot_index_param %type boot_ident -%type optbootstrap optsharedrelation optwithoutoids boot_column_nullness -%type oidspec optoideq optrowtypeoid +%type optbootstrap optsharedrelation boot_column_nullness +%type oidspec optrowtypeoid %token ID -%token OPEN XCLOSE XCREATE INSERT_TUPLE -%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST %token COMMA EQUALS LPAREN RPAREN -%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID NULLVAL -%token XFORCE XNOT XNULL +/* NULLVAL is a reserved keyword */ +%token NULLVAL +/* All the rest are unreserved, and should be handled in boot_ident! */ +%token OPEN XCLOSE XCREATE INSERT_TUPLE +%token XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST +%token OBJ_ID XBOOTSTRAP XSHARED_RELATION XROWTYPE_OID +%token XFORCE XNOT XNULL %start TopLevel -%nonassoc low -%nonassoc high - %% TopLevel: @@ -160,22 +161,16 @@ Boot_OpenStmt: ; Boot_CloseStmt: - XCLOSE boot_ident %prec low + XCLOSE boot_ident { do_start(); closerel($2); do_end(); } - | XCLOSE %prec high - { - do_start(); - closerel(NULL); - do_end(); - } ; Boot_CreateStmt: - XCREATE boot_ident oidspec optbootstrap optsharedrelation optwithoutoids optrowtypeoid LPAREN + XCREATE boot_ident oidspec optbootstrap optsharedrelation optrowtypeoid LPAREN { do_start(); numattr = 0; @@ -197,7 +192,7 @@ Boot_CreateStmt: do_start(); - tupdesc = CreateTupleDesc(numattr, !($6), attrtypes); + tupdesc = CreateTupleDesc(numattr, attrtypes); shared_relation = $5; @@ -214,6 +209,9 @@ Boot_CreateStmt: if ($4) { + TransactionId relfrozenxid; + MultiXactId relminmxid; + if (boot_reldesc) { elog(DEBUG4, "create bootstrap: warning, open relation exists, closing first"); @@ -225,12 +223,15 @@ Boot_CreateStmt: shared_relation ? GLOBALTABLESPACE_OID : 0, $3, InvalidOid, + HEAP_TABLE_AM_OID, tupdesc, RELKIND_RELATION, RELPERSISTENCE_PERMANENT, shared_relation, mapped_relation, - true); + true, + &relfrozenxid, + &relminmxid); elog(DEBUG4, "bootstrap relation created"); } else @@ -241,17 +242,16 @@ Boot_CreateStmt: PG_CATALOG_NAMESPACE, shared_relation ? GLOBALTABLESPACE_OID : 0, $3, - $7, + $6, InvalidOid, BOOTSTRAP_SUPERUSERID, + HEAP_TABLE_AM_OID, tupdesc, NIL, RELKIND_RELATION, RELPERSISTENCE_PERMANENT, shared_relation, mapped_relation, - true, - 0, ONCOMMIT_NOOP, (Datum) 0, false, @@ -266,13 +266,10 @@ Boot_CreateStmt: ; Boot_InsertStmt: - INSERT_TUPLE optoideq + INSERT_TUPLE { do_start(); - if ($2) - elog(DEBUG4, "inserting row with oid %u", $2); - else - elog(DEBUG4, "inserting row"); + elog(DEBUG4, "inserting row"); num_columns_read = 0; } LPAREN boot_column_val_list RPAREN @@ -282,7 +279,7 @@ Boot_InsertStmt: numattr, num_columns_read); if (boot_reldesc == NULL) elog(FATAL, "relation not open"); - InsertOneTuple($2); + InsertOneTuple(); do_end(); } ; @@ -317,6 +314,7 @@ Boot_DeclareIndexStmt: stmt->transformed = false; stmt->concurrent = false; stmt->if_not_exists = false; + stmt->reset_default_tblspc = false; /* locks and races need not concern us in bootstrap mode */ relationId = RangeVarGetRelid(stmt->relation, NoLock, @@ -366,6 +364,7 @@ Boot_DeclareUniqueIndexStmt: stmt->transformed = false; stmt->concurrent = false; stmt->if_not_exists = false; + stmt->reset_default_tblspc = false; /* locks and races need not concern us in bootstrap mode */ relationId = RangeVarGetRelid(stmt->relation, NoLock, @@ -437,11 +436,6 @@ optsharedrelation: | { $$ = 0; } ; -optwithoutoids: - XWITHOUT_OIDS { $$ = 1; } - | { $$ = 0; } - ; - optrowtypeoid: XROWTYPE_OID oidspec { $$ = $2; } | { $$ = InvalidOid; } @@ -471,11 +465,6 @@ oidspec: boot_ident { $$ = atooid($1); } ; -optoideq: - OBJ_ID EQUALS oidspec { $$ = $3; } - | { $$ = InvalidOid; } - ; - boot_column_val_list: boot_column_val | boot_column_val_list boot_column_val @@ -489,8 +478,27 @@ boot_column_val: { InsertOneNull(num_columns_read++); } ; -boot_ident : - ID { $$ = yylval.str; } +boot_ident: + ID { $$ = $1; } + | OPEN { $$ = pstrdup($1); } + | XCLOSE { $$ = pstrdup($1); } + | XCREATE { $$ = pstrdup($1); } + | INSERT_TUPLE { $$ = pstrdup($1); } + | XDECLARE { $$ = pstrdup($1); } + | INDEX { $$ = pstrdup($1); } + | ON { $$ = pstrdup($1); } + | USING { $$ = pstrdup($1); } + | XBUILD { $$ = pstrdup($1); } + | INDICES { $$ = pstrdup($1); } + | UNIQUE { $$ = pstrdup($1); } + | XTOAST { $$ = pstrdup($1); } + | OBJ_ID { $$ = pstrdup($1); } + | XBOOTSTRAP { $$ = pstrdup($1); } + | XSHARED_RELATION { $$ = pstrdup($1); } + | XROWTYPE_OID { $$ = pstrdup($1); } + | XFORCE { $$ = pstrdup($1); } + | XNOT { $$ = pstrdup($1); } + | XNULL { $$ = pstrdup($1); } ; %% diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l index 2ce6e524db1..91e74404066 100644 --- a/src/backend/bootstrap/bootscanner.l +++ b/src/backend/bootstrap/bootscanner.l @@ -4,7 +4,7 @@ * bootscanner.l * a lexical scanner for the bootstrap parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -65,28 +65,37 @@ static int yyline = 1; /* line number for error reporting */ %option prefix="boot_yy" -D [0-9] -oct \\{D}{D}{D} -id ([A-Za-z0-9_]|{oct}|\-)+ +id [-A-Za-z0-9_]+ sid \"([^\"])*\" -arrayid [A-Za-z0-9_]+\[{D}*\] + +/* + * Keyword tokens return the keyword text (as a constant string) in yylval.kw, + * just in case that's needed because we want to treat the keyword as an + * unreserved identifier. Note that _null_ is not treated as a keyword + * for this purpose; it's the one "reserved word" in the bootstrap syntax. + * + * Notice that all the keywords are case-sensitive, and for historical + * reasons some must be upper case. + * + * String tokens return a palloc'd string in yylval.str. + */ %% -open { return OPEN; } +open { yylval.kw = "open"; return OPEN; } -close { return XCLOSE; } +close { yylval.kw = "close"; return XCLOSE; } -create { return XCREATE; } +create { yylval.kw = "create"; return XCREATE; } -OID { return OBJ_ID; } -bootstrap { return XBOOTSTRAP; } -"shared_relation" { return XSHARED_RELATION; } -"without_oids" { return XWITHOUT_OIDS; } -"rowtype_oid" { return XROWTYPE_OID; } -_null_ { return NULLVAL; } +OID { yylval.kw = "OID"; return OBJ_ID; } +bootstrap { yylval.kw = "bootstrap"; return XBOOTSTRAP; } +shared_relation { yylval.kw = "shared_relation"; return XSHARED_RELATION; } +rowtype_oid { yylval.kw = "rowtype_oid"; return XROWTYPE_OID; } + +insert { yylval.kw = "insert"; return INSERT_TUPLE; } -insert { return INSERT_TUPLE; } +_null_ { return NULLVAL; } "," { return COMMA; } "=" { return EQUALS; } @@ -94,36 +103,31 @@ insert { return INSERT_TUPLE; } ")" { return RPAREN; } [\n] { yyline++; } -[\t] ; -" " ; - -^\#[^\n]* ; /* drop everything after "#" for comments */ - - -"declare" { return XDECLARE; } -"build" { return XBUILD; } -"indices" { return INDICES; } -"unique" { return UNIQUE; } -"index" { return INDEX; } -"on" { return ON; } -"using" { return USING; } -"toast" { return XTOAST; } -"FORCE" { return XFORCE; } -"NOT" { return XNOT; } -"NULL" { return XNULL; } - -{arrayid} { - yylval.str = MapArrayTypeName(yytext); - return ID; - } +[\r\t ] ; + +^\#[^\n]* ; /* drop everything after "#" for comments */ + +declare { yylval.kw = "declare"; return XDECLARE; } +build { yylval.kw = "build"; return XBUILD; } +indices { yylval.kw = "indices"; return INDICES; } +unique { yylval.kw = "unique"; return UNIQUE; } +index { yylval.kw = "index"; return INDEX; } +on { yylval.kw = "on"; return ON; } +using { yylval.kw = "using"; return USING; } +toast { yylval.kw = "toast"; return XTOAST; } +FORCE { yylval.kw = "FORCE"; return XFORCE; } +NOT { yylval.kw = "NOT"; return XNOT; } +NULL { yylval.kw = "NULL"; return XNULL; } + {id} { yylval.str = scanstr(yytext); return ID; } {sid} { - yytext[strlen(yytext)-1] = '\0'; /* strip off quotes */ + /* leading and trailing quotes are not passed to scanstr */ + yytext[strlen(yytext) - 1] = '\0'; yylval.str = scanstr(yytext+1); - yytext[strlen(yytext)] = '"'; /* restore quotes */ + yytext[strlen(yytext)] = '"'; /* restore yytext */ return ID; } @@ -131,8 +135,6 @@ insert { return INSERT_TUPLE; } elog(ERROR, "syntax error at line %d: unexpected character \"%s\"", yyline, yytext); } - - %% /* LCOV_EXCL_STOP */ diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 59cd4b17f32..9238fbe98d7 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -4,7 +4,7 @@ * routines to support running postgres in 'bootstrap' mode * bootstrap mode is used to create the initial template database * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,13 +17,17 @@ #include #include +#include "access/genam.h" +#include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog_internal.h" #include "bootstrap/bootstrap.h" #include "catalog/index.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" +#include "common/link-canary.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -45,7 +49,6 @@ #include "utils/ps_status.h" #include "utils/rel.h" #include "utils/relmapper.h" -#include "utils/tqual.h" uint32 bootstrap_data_checksum_version = 0; /* No checksum */ @@ -110,7 +113,7 @@ static const struct typinfo TypInfo[] = { F_INT4IN, F_INT4OUT}, {"float4", FLOAT4OID, 0, 4, FLOAT4PASSBYVAL, 'i', 'p', InvalidOid, F_FLOAT4IN, F_FLOAT4OUT}, - {"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'c', 'p', InvalidOid, + {"name", NAMEOID, CHAROID, NAMEDATALEN, false, 'c', 'p', C_COLLATION_OID, F_NAMEIN, F_NAMEOUT}, {"regclass", REGCLASSOID, 0, 4, true, 'i', 'p', InvalidOid, F_REGCLASSIN, F_REGCLASSOUT}, @@ -265,7 +268,7 @@ AuxiliaryProcessMain(int argc, char *argv[]) if (!IsValidWalSegSize(WalSegSz)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("-X requires a power of 2 value between 1MB and 1GB"))); + errmsg("-X requires a power of two value between 1 MB and 1 GB"))); SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL, PGC_S_OVERRIDE); } @@ -403,6 +406,13 @@ AuxiliaryProcessMain(int argc, char *argv[]) /* finish setting up bufmgr.c */ InitBufferPoolBackend(); + /* + * Auxiliary processes don't run transactions, but they may need a + * resource owner anyway to manage buffer pins acquired outside + * transactions (and, perhaps, other things in future). + */ + CreateAuxProcessResourceOwner(); + /* Initialize backend status information */ pgstat_initialize(); pgstat_bestart(); @@ -495,6 +505,13 @@ BootstrapModeMain(void) Assert(!IsUnderPostmaster); Assert(IsBootstrapProcessingMode()); + /* + * To ensure that src/common/link-canary.c is linked into the backend, we + * must call it from somewhere. Here is as good as anywhere. + */ + if (pg_link_canary_is_frontend()) + elog(ERROR, "backend is incorrectly linked to frontend functions"); + /* * Do backend-like initialization for bootstrap mode */ @@ -541,11 +558,15 @@ bootstrap_signals(void) { Assert(!IsUnderPostmaster); - /* Set up appropriately for interactive use */ - pqsignal(SIGHUP, die); - pqsignal(SIGINT, die); - pqsignal(SIGTERM, die); - pqsignal(SIGQUIT, die); + /* + * We don't actually need any non-default signal handling in bootstrap + * mode; "curl up and die" is a sufficient response for all these cases. + * Let's set that handling explicitly, as documentation if nothing else. + */ + pqsignal(SIGHUP, SIG_DFL); + pqsignal(SIGINT, SIG_DFL); + pqsignal(SIGTERM, SIG_DFL); + pqsignal(SIGQUIT, SIG_DFL); } /* @@ -578,7 +599,7 @@ boot_openrel(char *relname) int i; struct typmap **app; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; if (strlen(relname) >= NAMEDATALEN) @@ -587,28 +608,28 @@ boot_openrel(char *relname) if (Typ == NULL) { /* We can now load the pg_type data */ - rel = heap_open(TypeRelationId, NoLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(TypeRelationId, NoLock); + scan = table_beginscan_catalog(rel, 0, NULL); i = 0; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) ++i; - heap_endscan(scan); + table_endscan(scan); app = Typ = ALLOC(struct typmap *, i + 1); while (i-- > 0) *app++ = ALLOC(struct typmap, 1); *app = NULL; - scan = heap_beginscan_catalog(rel, 0, NULL); + scan = table_beginscan_catalog(rel, 0, NULL); app = Typ; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { - (*app)->am_oid = HeapTupleGetOid(tup); + (*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid; memcpy((char *) &(*app)->am_typ, (char *) GETSTRUCT(tup), sizeof((*app)->am_typ)); app++; } - heap_endscan(scan); - heap_close(rel, NoLock); + table_endscan(scan); + table_close(rel, NoLock); } if (boot_reldesc != NULL) @@ -617,7 +638,7 @@ boot_openrel(char *relname) elog(DEBUG4, "open relation %s, attrsize %d", relname, (int) ATTRIBUTE_FIXED_PART_SIZE); - boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock); + boot_reldesc = table_openrv(makeRangeVar(NULL, relname, -1), NoLock); numattr = RelationGetNumberOfAttributes(boot_reldesc); for (i = 0; i < numattr; i++) { @@ -663,7 +684,7 @@ closerel(char *name) { elog(DEBUG4, "close relation %s", RelationGetRelationName(boot_reldesc)); - heap_close(boot_reldesc, NoLock); + table_close(boot_reldesc, NoLock); boot_reldesc = NULL; } } @@ -695,7 +716,7 @@ DefineAttr(char *name, char *type, int attnum, int nullness) namestrcpy(&attrtypes[attnum]->attname, name); elog(DEBUG4, "column %s %s", NameStr(attrtypes[attnum]->attname), type); - attrtypes[attnum]->attnum = attnum + 1; /* fillatt */ + attrtypes[attnum]->attnum = attnum + 1; typeoid = gettype(type); @@ -729,6 +750,15 @@ DefineAttr(char *name, char *type, int attnum, int nullness) attrtypes[attnum]->attndims = 0; } + /* + * If a system catalog column is collation-aware, force it to use C + * collation, so that its behavior is independent of the database's + * collation. This is essential to allow template0 to be cloned with a + * different database collation. + */ + if (OidIsValid(attrtypes[attnum]->attcollation)) + attrtypes[attnum]->attcollation = C_COLLATION_OID; + attrtypes[attnum]->attstattarget = -1; attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; @@ -784,20 +814,16 @@ DefineAttr(char *name, char *type, int attnum, int nullness) * ---------------- */ void -InsertOneTuple(Oid objectid) +InsertOneTuple(void) { HeapTuple tuple; TupleDesc tupDesc; int i; - elog(DEBUG4, "inserting row oid %u, %d columns", objectid, numattr); + elog(DEBUG4, "inserting row with %d columns", numattr); - tupDesc = CreateTupleDesc(numattr, - RelationGetForm(boot_reldesc)->relhasoids, - attrtypes); + tupDesc = CreateTupleDesc(numattr, attrtypes); tuple = heap_form_tuple(tupDesc, values, Nulls); - if (objectid != (Oid) 0) - HeapTupleSetOid(tuple, objectid); pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ simple_heap_insert(boot_reldesc, tuple); @@ -894,7 +920,7 @@ gettype(char *type) { int i; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; struct typmap **app; @@ -917,27 +943,27 @@ gettype(char *type) return i; } elog(DEBUG4, "external type: %s", type); - rel = heap_open(TypeRelationId, NoLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(TypeRelationId, NoLock); + scan = table_beginscan_catalog(rel, 0, NULL); i = 0; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) ++i; - heap_endscan(scan); + table_endscan(scan); app = Typ = ALLOC(struct typmap *, i + 1); while (i-- > 0) *app++ = ALLOC(struct typmap, 1); *app = NULL; - scan = heap_beginscan_catalog(rel, 0, NULL); + scan = table_beginscan_catalog(rel, 0, NULL); app = Typ; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { - (*app)->am_oid = HeapTupleGetOid(tup); + (*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid; memmove((char *) &(*app++)->am_typ, (char *) GETSTRUCT(tup), sizeof((*app)->am_typ)); } - heap_endscan(scan); - heap_close(rel, NoLock); + table_endscan(scan); + table_close(rel, NoLock); return gettype(type); } elog(ERROR, "unrecognized type \"%s\"", type); @@ -1036,36 +1062,6 @@ AllocateAttribute(void) MemoryContextAllocZero(TopMemoryContext, ATTRIBUTE_FIXED_PART_SIZE); } -/* - * MapArrayTypeName - * - * Given a type name, produce the corresponding array type name by prepending - * '_' and truncating as needed to fit in NAMEDATALEN-1 bytes. This is only - * used in bootstrap mode, so we can get away with assuming that the input is - * ASCII and we don't need multibyte-aware truncation. - * - * The given string normally ends with '[]' or '[digits]'; we discard that. - * - * The result is a palloc'd string. - */ -char * -MapArrayTypeName(const char *s) -{ - int i, - j; - char newStr[NAMEDATALEN]; - - newStr[0] = '_'; - j = 1; - for (i = 0; i < NAMEDATALEN - 2 && s[i] != '['; i++, j++) - newStr[j] = s[i]; - - newStr[j] = '\0'; - - return pstrdup(newStr); -} - - /* * index_register() -- record an index that has been set up for building * later. @@ -1136,12 +1132,12 @@ build_indices(void) Relation ind; /* need not bother with locks during bootstrap */ - heap = heap_open(ILHead->il_heap, NoLock); + heap = table_open(ILHead->il_heap, NoLock); ind = index_open(ILHead->il_ind, NoLock); - index_build(heap, ind, ILHead->il_info, false, false, false); + index_build(heap, ind, ILHead->il_info, false, false); index_close(ind, NoLock); - heap_close(heap, NoLock); + table_close(heap, NoLock); } } diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm index 02bd6d43836..368b1dea3e4 100644 --- a/src/backend/catalog/Catalog.pm +++ b/src/backend/catalog/Catalog.pm @@ -4,7 +4,7 @@ # Perl module that extracts info from catalog files into Perl # data structures # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/catalog/Catalog.pm @@ -16,6 +16,9 @@ package Catalog; use strict; use warnings; +use File::Compare; + + # Parses a catalog header file into a data structure describing the schema # of the catalog. sub ParseHeader @@ -33,181 +36,186 @@ sub ParseHeader 'TransactionId' => 'xid', 'XLogRecPtr' => 'pg_lsn'); - my %catalog; - my $declaring_attributes = 0; - my $is_varlen = 0; - my $is_client_code = 0; + my %catalog; + my $declaring_attributes = 0; + my $is_varlen = 0; + my $is_client_code = 0; - $catalog{columns} = []; - $catalog{toasting} = []; - $catalog{indexing} = []; - $catalog{client_code} = []; + $catalog{columns} = []; + $catalog{toasting} = []; + $catalog{indexing} = []; + $catalog{client_code} = []; - open(my $ifh, '<', $input_file) || die "$input_file: $!"; + open(my $ifh, '<', $input_file) || die "$input_file: $!"; - # Scan the input file. - while (<$ifh>) - { + # Scan the input file. + while (<$ifh>) + { - # Set appropriate flag when we're in certain code sections. - if (/^#/) + # Set appropriate flag when we're in certain code sections. + if (/^#/) + { + $is_varlen = 1 if /^#ifdef\s+CATALOG_VARLEN/; + if (/^#ifdef\s+EXPOSE_TO_CLIENT_CODE/) { - $is_varlen = 1 if /^#ifdef\s+CATALOG_VARLEN/; - if (/^#ifdef\s+EXPOSE_TO_CLIENT_CODE/) - { - $is_client_code = 1; - next; - } - next if !$is_client_code; + $is_client_code = 1; + next; } + next if !$is_client_code; + } - if (!$is_client_code) + if (!$is_client_code) + { + # Strip C-style comments. + s;/\*(.|\n)*\*/;;g; + if (m;/\*;) { - # Strip C-style comments. - s;/\*(.|\n)*\*/;;g; - if (m;/\*;) - { - - # handle multi-line comments properly. - my $next_line = <$ifh>; - die "$input_file: ends within C-style comment\n" - if !defined $next_line; - $_ .= $next_line; - redo; - } - # Strip useless whitespace and trailing semicolons. - chomp; - s/^\s+//; - s/;\s*$//; - s/\s+/ /g; + # handle multi-line comments properly. + my $next_line = <$ifh>; + die "$input_file: ends within C-style comment\n" + if !defined $next_line; + $_ .= $next_line; + redo; } - # Push the data into the appropriate data structure. - if (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/) + # Strip useless whitespace and trailing semicolons. + chomp; + s/^\s+//; + s/;\s*$//; + s/\s+/ /g; + } + + # Push the data into the appropriate data structure. + # Caution: when adding new recognized OID-defining macros, + # also update src/include/catalog/renumber_oids.pl. + if (/^DECLARE_TOAST\(\s*(\w+),\s*(\d+),\s*(\d+)\)/) + { + push @{ $catalog{toasting} }, + { parent_table => $1, toast_oid => $2, toast_index_oid => $3 }; + } + elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/) + { + push @{ $catalog{indexing} }, + { + is_unique => $1 ? 1 : 0, + index_name => $2, + index_oid => $3, + index_decl => $4 + }; + } + elsif (/^CATALOG\((\w+),(\d+),(\w+)\)/) + { + $catalog{catname} = $1; + $catalog{relation_oid} = $2; + $catalog{relation_oid_macro} = $3; + + $catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : ''; + $catalog{shared_relation} = + /BKI_SHARED_RELATION/ ? ' shared_relation' : ''; + if (/BKI_ROWTYPE_OID\((\d+),(\w+)\)/) { - my ($toast_name, $toast_oid, $index_oid) = ($1, $2, $3); - push @{ $catalog{toasting} }, - "declare toast $toast_oid $index_oid on $toast_name\n"; + $catalog{rowtype_oid} = $1; + $catalog{rowtype_oid_clause} = " rowtype_oid $1"; + $catalog{rowtype_oid_macro} = $2; } - elsif (/^DECLARE_(UNIQUE_)?INDEX\(\s*(\w+),\s*(\d+),\s*(.+)\)/) + else { - my ($is_unique, $index_name, $index_oid, $using) = - ($1, $2, $3, $4); - push @{ $catalog{indexing} }, - sprintf( - "declare %sindex %s %s %s\n", - $is_unique ? 'unique ' : '', - $index_name, $index_oid, $using); + $catalog{rowtype_oid} = ''; + $catalog{rowtype_oid_clause} = ''; + $catalog{rowtype_oid_macro} = ''; } - elsif (/^BUILD_INDICES/) + $catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 1 : 0; + $declaring_attributes = 1; + } + elsif ($is_client_code) + { + if (/^#endif/) { - push @{ $catalog{indexing} }, "build indices\n"; + $is_client_code = 0; } - elsif (/^CATALOG\((\w+),(\d+),(\w+)\)/) + else { - $catalog{catname} = $1; - $catalog{relation_oid} = $2; - $catalog{relation_oid_macro} = $3; - - $catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : ''; - $catalog{shared_relation} = - /BKI_SHARED_RELATION/ ? ' shared_relation' : ''; - $catalog{without_oids} = - /BKI_WITHOUT_OIDS/ ? ' without_oids' : ''; - if (/BKI_ROWTYPE_OID\((\d+),(\w+)\)/) - { - $catalog{rowtype_oid} = $1; - $catalog{rowtype_oid_clause} = " rowtype_oid $1"; - $catalog{rowtype_oid_macro} = $2; - } - else - { - $catalog{rowtype_oid} = ''; - $catalog{rowtype_oid_clause} = ''; - $catalog{rowtype_oid_macro} = ''; - } - $catalog{schema_macro} = /BKI_SCHEMA_MACRO/ ? 1 : 0; - $declaring_attributes = 1; + push @{ $catalog{client_code} }, $_; + } + } + elsif ($declaring_attributes) + { + next if (/^{|^$/); + if (/^}/) + { + $declaring_attributes = 0; } - elsif ($is_client_code) + else { - if (/^#endif/) + my %column; + my @attopts = split /\s+/, $_; + my $atttype = shift @attopts; + my $attname = shift @attopts; + die "parse error ($input_file)" + unless ($attname and $atttype); + + if (exists $RENAME_ATTTYPE{$atttype}) { - $is_client_code = 0; + $atttype = $RENAME_ATTTYPE{$atttype}; } - else - { - push @{ $catalog{client_code} }, $_; - } - } - elsif ($declaring_attributes) - { - next if (/^{|^$/); - if (/^}/) + + # If the C name ends with '[]' or '[digits]', we have + # an array type, so we discard that from the name and + # prepend '_' to the type. + if ($attname =~ /(\w+)\[\d*\]/) { - $declaring_attributes = 0; + $attname = $1; + $atttype = '_' . $atttype; } - else + + $column{type} = $atttype; + $column{name} = $attname; + $column{is_varlen} = 1 if $is_varlen; + + foreach my $attopt (@attopts) { - my %column; - my @attopts = split /\s+/, $_; - my $atttype = shift @attopts; - my $attname = shift @attopts; - die "parse error ($input_file)" - unless ($attname and $atttype); - - if (exists $RENAME_ATTTYPE{$atttype}) + if ($attopt eq 'BKI_FORCE_NULL') { - $atttype = $RENAME_ATTTYPE{$atttype}; + $column{forcenull} = 1; } - if ($attname =~ /(.*)\[.*\]/) # array attribute + elsif ($attopt eq 'BKI_FORCE_NOT_NULL') { - $attname = $1; - $atttype .= '[]'; + $column{forcenotnull} = 1; } - $column{type} = $atttype; - $column{name} = $attname; - $column{is_varlen} = 1 if $is_varlen; + # We use quotes for values like \0 and \054, to + # make sure all compilers and syntax highlighters + # can recognize them properly. + elsif ($attopt =~ /BKI_DEFAULT\(['"]?([^'"]+)['"]?\)/) + { + $column{default} = $1; + } + elsif ( + $attopt =~ /BKI_ARRAY_DEFAULT\(['"]?([^'"]+)['"]?\)/) + { + $column{array_default} = $1; + } + elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/) + { + $column{lookup} = $1; + } + else + { + die + "unknown or misformatted column option $attopt on column $attname"; + } - foreach my $attopt (@attopts) + if ($column{forcenull} and $column{forcenotnull}) { - if ($attopt eq 'BKI_FORCE_NULL') - { - $column{forcenull} = 1; - } - elsif ($attopt eq 'BKI_FORCE_NOT_NULL') - { - $column{forcenotnull} = 1; - } - # We use quotes for values like \0 and \054, to - # make sure all compilers and syntax highlighters - # can recognize them properly. - elsif ($attopt =~ /BKI_DEFAULT\(['"]?([^'"]+)['"]?\)/) - { - $column{default} = $1; - } - elsif ($attopt =~ /BKI_LOOKUP\((\w+)\)/) - { - $column{lookup} = $1; - } - else - { - die -"unknown column option $attopt on column $attname"; - } - - if ($column{forcenull} and $column{forcenotnull}) - { - die "$attname is forced both null and not null"; - } + die "$attname is forced both null and not null"; } - push @{ $catalog{columns} }, \%column; } + push @{ $catalog{columns} }, \%column; } } - close $ifh; + } + close $ifh; return \%catalog; } @@ -222,9 +230,9 @@ sub ParseData open(my $ifd, '<', $input_file) || die "$input_file: $!"; $input_file =~ /(\w+)\.dat$/ - or die "Input file needs to be a .dat file.\n"; + or die "Input file $input_file needs to be a .dat file.\n"; my $catname = $1; - my $data = []; + my $data = []; # Scan the input file. while (<$ifd>) @@ -241,39 +249,49 @@ sub ParseData # Quick hack to detect when we have a full hash ref to # parse. We can't just use a regex because of values in - # pg_aggregate and pg_proc like '{0,0}'. + # pg_aggregate and pg_proc like '{0,0}'. This will need + # work if we ever need to allow unbalanced braces within + # a field value. my $lcnt = tr/{//; my $rcnt = tr/}//; if ($lcnt == $rcnt) { - eval '$hash_ref = ' . $_; + # We're treating the input line as a piece of Perl, so we + # need to use string eval here. Tell perlcritic we know what + # we're doing. + eval '$hash_ref = ' . $_; ## no critic (ProhibitStringyEval) if (!ref $hash_ref) { - die "Error parsing $_\n$!"; + die "$input_file: error parsing line $.:\n$_\n"; } + # Annotate each hash with the source line number. + $hash_ref->{line_number} = $.; + # Expand tuples to their full representation. AddDefaultValues($hash_ref, $schema, $catname); } else { my $next_line = <$ifd>; - die "$input_file: ends within Perl hash\n" + die "$input_file: file ends within Perl hash\n" if !defined $next_line; $_ .= $next_line; redo; } } - # If we found a hash reference, keep it - # and annotate the line number. - # Only keep non-data strings if we - # are told to preserve formatting. + # If we found a hash reference, keep it, unless it is marked as + # autogenerated; in that case it'd duplicate an entry we'll + # autogenerate below. (This makes it safe for reformat_dat_file.pl + # with --full-tuples to print autogenerated entries, which seems like + # useful behavior for debugging.) + # + # Only keep non-data strings if we are told to preserve formatting. if (defined $hash_ref) { - $hash_ref->{line_number} = $.; - push @$data, $hash_ref; + push @$data, $hash_ref if !$hash_ref->{autogenerated}; } elsif ($preserve_formatting) { @@ -281,6 +299,10 @@ sub ParseData } } close $ifd; + + # If this is pg_type, auto-generate array types too. + GenerateArrayTypes($schema, $data) if $catname eq 'pg_type'; + return $data; } @@ -291,6 +313,21 @@ sub AddDefaultValues my ($row, $schema, $catname) = @_; my @missing_fields; + # Compute special-case column values. + # Note: If you add new cases here, you must also teach + # strip_default_values() in include/catalog/reformat_dat_file.pl + # to delete them. + if ($catname eq 'pg_proc') + { + # pg_proc.pronargs can be derived from proargtypes. + if (defined $row->{proargtypes}) + { + my @proargtypes = split /\s+/, $row->{proargtypes}; + $row->{pronargs} = scalar(@proargtypes); + } + } + + # Now fill in defaults, and note any columns that remain undefined. foreach my $column (@$schema) { my $attname = $column->{name}; @@ -300,16 +337,13 @@ sub AddDefaultValues { ; } - elsif (defined $column->{default}) + elsif ($attname eq 'oid') { - $row->{$attname} = $column->{default}; + ; } - elsif ($catname eq 'pg_proc' && $attname eq 'pronargs' && - defined($row->{proargtypes})) + elsif (defined $column->{default}) { - # pg_proc.pronargs can be derived from proargtypes. - my @proargtypes = split /\s+/, $row->{proargtypes}; - $row->{$attname} = scalar(@proargtypes); + $row->{$attname} = $column->{default}; } else { @@ -318,67 +352,132 @@ sub AddDefaultValues } } + # Failure to provide all columns is a hard error. if (@missing_fields) { - my $msg = "Failed to form full tuple for $catname\n"; - $msg .= "Missing values for: " . join(', ', @missing_fields); - $msg .= "\nOther values for row:\n"; - while (my($key, $value) = each %$row) + die sprintf "missing values for field(s) %s in %s.dat line %s\n", + join(', ', @missing_fields), $catname, $row->{line_number}; + } +} + +# If a pg_type entry has an array_type_oid metadata field, +# auto-generate an entry for its array type. +sub GenerateArrayTypes +{ + my $pgtype_schema = shift; + my $types = shift; + my @array_types; + + foreach my $elem_type (@$types) + { + next if !(ref $elem_type eq 'HASH'); + next if !defined($elem_type->{array_type_oid}); + + my %array_type; + + # Set up metadata fields for array type. + $array_type{oid} = $elem_type->{array_type_oid}; + $array_type{autogenerated} = 1; + $array_type{line_number} = $elem_type->{line_number}; + + # Set up column values derived from the element type. + $array_type{typname} = '_' . $elem_type->{typname}; + $array_type{typelem} = $elem_type->{typname}; + + # Arrays require INT alignment, unless the element type requires + # DOUBLE alignment. + $array_type{typalign} = $elem_type->{typalign} eq 'd' ? 'd' : 'i'; + + # Fill in the rest of the array entry's fields. + foreach my $column (@$pgtype_schema) { - $msg .= "$key => $value, "; + my $attname = $column->{name}; + + # Skip if we already set it above. + next if defined $array_type{$attname}; + + # Apply the BKI_ARRAY_DEFAULT setting if there is one, + # otherwise copy the field from the element type. + if (defined $column->{array_default}) + { + $array_type{$attname} = $column->{array_default}; + } + else + { + $array_type{$attname} = $elem_type->{$attname}; + } } - die $msg; + + # Lastly, cross-link the array to the element type. + $elem_type->{typarray} = $array_type{typname}; + + push @array_types, \%array_type; } + + push @$types, @array_types; + + return; } # Rename temporary files to final names. -# Call this function with the final file name and the .tmp extension +# Call this function with the final file name and the .tmp extension. +# +# If the final file already exists and has identical contents, don't +# overwrite it; this behavior avoids unnecessary recompiles due to +# updating the mod date on unchanged header files. +# # Note: recommended extension is ".tmp$$", so that parallel make steps -# can't use the same temp files +# can't use the same temp files. sub RenameTempFile { my $final_name = shift; my $extension = shift; my $temp_name = $final_name . $extension; - rename($temp_name, $final_name) || die "rename: $temp_name: $!"; + + if (-f $final_name + && compare($temp_name, $final_name) == 0) + { + unlink($temp_name) || die "unlink: $temp_name: $!"; + } + else + { + rename($temp_name, $final_name) || die "rename: $temp_name: $!"; + } + return; } # Find a symbol defined in a particular header file and extract the value. -# -# The include path has to be passed as a reference to an array. +# include_path should be the path to src/include/. sub FindDefinedSymbol { my ($catalog_header, $include_path, $symbol) = @_; + my $value; - for my $path (@$include_path) + # Make sure include path ends in a slash. + if (substr($include_path, -1) ne '/') { - - # Make sure include path ends in a slash. - if (substr($path, -1) ne '/') - { - $path .= '/'; - } - my $file = $path . $catalog_header; - next if !-f $file; - open(my $find_defined_symbol, '<', $file) || die "$file: $!"; - while (<$find_defined_symbol>) + $include_path .= '/'; + } + my $file = $include_path . $catalog_header; + open(my $find_defined_symbol, '<', $file) || die "$file: $!"; + while (<$find_defined_symbol>) + { + if (/^#define\s+\Q$symbol\E\s+(\S+)/) { - if (/^#define\s+\Q$symbol\E\s+(\S+)/) - { - return $1; - } + $value = $1; + last; } - close $find_defined_symbol; - die "$file: no definition found for $symbol\n"; } - die "$catalog_header: not found in any include directory\n"; + close $find_defined_symbol; + return $value if defined $value; + die "$file: no definition found for $symbol\n"; } # Similar to FindDefinedSymbol, but looks in the bootstrap metadata. sub FindDefinedSymbolFromData { my ($data, $symbol) = @_; - foreach my $row (@{ $data }) + foreach my $row (@{$data}) { if ($row->{oid_symbol} eq $symbol) { @@ -388,4 +487,57 @@ sub FindDefinedSymbolFromData die "no definition found for $symbol\n"; } +# Extract an array of all the OIDs assigned in the specified catalog headers +# and their associated data files (if any). +# Caution: genbki.pl contains equivalent logic; change it too if you need to +# touch this. +sub FindAllOidsFromHeaders +{ + my @input_files = @_; + + my @oids = (); + + foreach my $header (@input_files) + { + $header =~ /(.+)\.h$/ + or die "Input files need to be header files.\n"; + my $datfile = "$1.dat"; + + my $catalog = Catalog::ParseHeader($header); + + # We ignore the pg_class OID and rowtype OID of bootstrap catalogs, + # as those are expected to appear in the initial data for pg_class + # and pg_type. For regular catalogs, include these OIDs. + if (!$catalog->{bootstrap}) + { + push @oids, $catalog->{relation_oid} + if ($catalog->{relation_oid}); + push @oids, $catalog->{rowtype_oid} if ($catalog->{rowtype_oid}); + } + + # Not all catalogs have a data file. + if (-e $datfile) + { + my $catdata = + Catalog::ParseData($datfile, $catalog->{columns}, 0); + + foreach my $row (@$catdata) + { + push @oids, $row->{oid} if defined $row->{oid}; + } + } + + foreach my $toast (@{ $catalog->{toasting} }) + { + push @oids, $toast->{toast_oid}, $toast->{toast_index_oid}; + } + foreach my $index (@{ $catalog->{indexing} }) + { + push @oids, $index->{index_oid}; + } + } + + return \@oids; +} + 1; diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index d25d98a40b8..8bece078dd1 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/catalog # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/catalog/Makefile @@ -34,7 +34,7 @@ CATALOG_HEADERS := \ pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \ pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \ pg_language.h pg_largeobject_metadata.h pg_largeobject.h pg_aggregate.h \ - pg_statistic_ext.h \ + pg_statistic_ext.h pg_statistic_ext_data.h \ pg_statistic.h pg_rewrite.h pg_trigger.h pg_event_trigger.h pg_description.h \ pg_cast.h pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \ pg_database.h pg_db_role_setting.h pg_tablespace.h pg_pltemplate.h \ @@ -60,7 +60,7 @@ POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\ # The .dat files we need can just be listed alphabetically. POSTGRES_BKI_DATA = $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_aggregate.dat pg_am.dat pg_amop.dat pg_amproc.dat pg_authid.dat \ - pg_cast.dat pg_class.dat pg_collation.dat \ + pg_cast.dat pg_class.dat pg_collation.dat pg_conversion.dat \ pg_database.dat pg_language.dat \ pg_namespace.dat pg_opclass.dat pg_operator.dat pg_opfamily.dat \ pg_pltemplate.dat pg_proc.dat pg_range.dat pg_tablespace.dat \ @@ -68,9 +68,6 @@ POSTGRES_BKI_DATA = $(addprefix $(top_srcdir)/src/include/catalog/,\ pg_ts_template.dat pg_type.dat \ ) -# location of Catalog.pm -catalogdir = $(top_srcdir)/src/backend/catalog - all: distprep generated-header-symlinks distprep: bki-stamp @@ -79,14 +76,17 @@ distprep: bki-stamp generated-header-symlinks: $(top_builddir)/src/include/catalog/header-stamp +# bki-stamp records the last time we ran genbki.pl. We don't rely on +# the timestamps of the individual output files, because the Perl script +# won't update them if they didn't change (to avoid unnecessary recompiles). # Technically, this should depend on Makefile.global which supplies -# $(MAJORVERSION); but then postgres.bki would need to be rebuilt after every +# $(MAJORVERSION); but then genbki.pl would need to be re-run after every # configure run, even in distribution tarballs. So depending on configure.in # instead is cheating a bit, but it will achieve the goal of updating the # version number when it changes. -bki-stamp: genbki.pl Catalog.pm $(POSTGRES_BKI_SRCS) $(POSTGRES_BKI_DATA) $(top_srcdir)/configure.in $(top_srcdir)/src/include/catalog/duplicate_oids - cd $(top_srcdir)/src/include/catalog && $(PERL) ./duplicate_oids - $(PERL) -I $(catalogdir) $< --set-version=$(MAJORVERSION) $(POSTGRES_BKI_SRCS) +bki-stamp: genbki.pl Catalog.pm $(POSTGRES_BKI_SRCS) $(POSTGRES_BKI_DATA) $(top_srcdir)/configure.in + $(PERL) $< --include-path=$(top_srcdir)/src/include/ \ + --set-version=$(MAJORVERSION) $(POSTGRES_BKI_SRCS) touch $@ # The generated headers must all be symlinked into builddir/src/include/, diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 0ace1968df4..88ce37c08de 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -3,7 +3,7 @@ * aclchk.c * Routines to check access control permissions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,6 +21,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -74,7 +75,6 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -120,26 +120,26 @@ static List *objectNamesToOids(ObjectType objtype, List *objnames); static List *objectsInSchemaToOids(ObjectType objtype, List *nspnames); static List *getRelationsInNamespace(Oid namespaceId, char relkind); static void expand_col_privileges(List *colnames, Oid table_oid, - AclMode this_privileges, - AclMode *col_privileges, - int num_col_privileges); + AclMode this_privileges, + AclMode *col_privileges, + int num_col_privileges); static void expand_all_col_privileges(Oid table_oid, Form_pg_class classForm, - AclMode this_privileges, - AclMode *col_privileges, - int num_col_privileges); + AclMode this_privileges, + AclMode *col_privileges, + int num_col_privileges); static AclMode string_to_privilege(const char *privname); static const char *privilege_to_string(AclMode privilege); static AclMode restrict_and_check_grant(bool is_grant, AclMode avail_goptions, - bool all_privs, AclMode privileges, - Oid objectId, Oid grantorId, - ObjectType objtype, const char *objname, - AttrNumber att_number, const char *colname); + bool all_privs, AclMode privileges, + Oid objectId, Oid grantorId, + ObjectType objtype, const char *objname, + AttrNumber att_number, const char *colname); static AclMode pg_aclmask(ObjectType objtype, Oid table_oid, AttrNumber attnum, - Oid roleid, AclMode mask, AclMaskHow how); + Oid roleid, AclMode mask, AclMaskHow how); static void recordExtensionInitPriv(Oid objoid, Oid classoid, int objsubid, - Acl *new_acl); + Acl *new_acl); static void recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, - Acl *new_acl); + Acl *new_acl); #ifdef ACLDEBUG @@ -446,6 +446,7 @@ ExecuteGrantStmt(GrantStmt *stmt) switch (stmt->objtype) { case OBJECT_TABLE: + /* * Because this might be a sequence, we test both relation and * sequence bits, and later do a more limited test when we know @@ -821,7 +822,7 @@ objectsInSchemaToOids(ObjectType objtype, List *nspnames) ScanKeyData key[2]; int keycount; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; keycount = 0; @@ -842,16 +843,18 @@ objectsInSchemaToOids(ObjectType objtype, List *nspnames) BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(PROKIND_PROCEDURE)); - rel = heap_open(ProcedureRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, keycount, key); + rel = table_open(ProcedureRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, keycount, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - objects = lappend_oid(objects, HeapTupleGetOid(tuple)); + Oid oid = ((Form_pg_proc) GETSTRUCT(tuple))->oid; + + objects = lappend_oid(objects, oid); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); } break; default: @@ -875,7 +878,7 @@ getRelationsInNamespace(Oid namespaceId, char relkind) List *relations = NIL; ScanKeyData key[2]; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; ScanKeyInit(&key[0], @@ -887,16 +890,18 @@ getRelationsInNamespace(Oid namespaceId, char relkind) BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(relkind)); - rel = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 2, key); + rel = table_open(RelationRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 2, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - relations = lappend_oid(relations, HeapTupleGetOid(tuple)); + Oid oid = ((Form_pg_class) GETSTRUCT(tuple))->oid; + + relations = lappend_oid(relations, oid); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); return relations; } @@ -1161,7 +1166,7 @@ SetDefaultACL(InternalDefaultACL *iacls) Oid *oldmembers; Oid *newmembers; - rel = heap_open(DefaultAclRelationId, RowExclusiveLock); + rel = table_open(DefaultAclRelationId, RowExclusiveLock); /* * The default for a global entry is the hard-wired default ACL for the @@ -1298,7 +1303,7 @@ SetDefaultACL(InternalDefaultACL *iacls) * there shouldn't be anything depending on this entry. */ myself.classId = DefaultAclRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid; myself.objectSubId = 0; performDeletion(&myself, DROP_RESTRICT, 0); @@ -1306,6 +1311,8 @@ SetDefaultACL(InternalDefaultACL *iacls) } else { + Oid defAclOid; + /* Prepare to insert or update pg_default_acl entry */ MemSet(values, 0, sizeof(values)); MemSet(nulls, false, sizeof(nulls)); @@ -1314,6 +1321,9 @@ SetDefaultACL(InternalDefaultACL *iacls) if (isNew) { /* insert new entry */ + defAclOid = GetNewOidWithIndex(rel, DefaultAclOidIndexId, + Anum_pg_default_acl_oid); + values[Anum_pg_default_acl_oid - 1] = ObjectIdGetDatum(defAclOid); values[Anum_pg_default_acl_defaclrole - 1] = ObjectIdGetDatum(iacls->roleid); values[Anum_pg_default_acl_defaclnamespace - 1] = ObjectIdGetDatum(iacls->nspid); values[Anum_pg_default_acl_defaclobjtype - 1] = CharGetDatum(objtype); @@ -1324,6 +1334,8 @@ SetDefaultACL(InternalDefaultACL *iacls) } else { + defAclOid = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid; + /* update existing entry */ values[Anum_pg_default_acl_defaclacl - 1] = PointerGetDatum(new_acl); replaces[Anum_pg_default_acl_defaclacl - 1] = true; @@ -1337,8 +1349,7 @@ SetDefaultACL(InternalDefaultACL *iacls) if (isNew) { /* dependency on role */ - recordDependencyOnOwner(DefaultAclRelationId, - HeapTupleGetOid(newtuple), + recordDependencyOnOwner(DefaultAclRelationId, defAclOid, iacls->roleid); /* dependency on namespace */ @@ -1348,7 +1359,7 @@ SetDefaultACL(InternalDefaultACL *iacls) referenced; myself.classId = DefaultAclRelationId; - myself.objectId = HeapTupleGetOid(newtuple); + myself.objectId = defAclOid; myself.objectSubId = 0; referenced.classId = NamespaceRelationId; @@ -1365,23 +1376,21 @@ SetDefaultACL(InternalDefaultACL *iacls) nnewmembers = aclmembers(new_acl, &newmembers); updateAclDependencies(DefaultAclRelationId, - HeapTupleGetOid(newtuple), 0, + defAclOid, 0, iacls->roleid, noldmembers, oldmembers, nnewmembers, newmembers); if (isNew) - InvokeObjectPostCreateHook(DefaultAclRelationId, - HeapTupleGetOid(newtuple), 0); + InvokeObjectPostCreateHook(DefaultAclRelationId, defAclOid, 0); else - InvokeObjectPostAlterHook(DefaultAclRelationId, - HeapTupleGetOid(newtuple), 0); + InvokeObjectPostAlterHook(DefaultAclRelationId, defAclOid, 0); } if (HeapTupleIsValid(tuple)) ReleaseSysCache(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -1403,10 +1412,10 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid) HeapTuple tuple; /* first fetch info needed by SetDefaultACL */ - rel = heap_open(DefaultAclRelationId, AccessShareLock); + rel = table_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_default_acl_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objid)); @@ -1448,7 +1457,7 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid) } systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); iacls.is_grant = false; iacls.all_privs = true; @@ -1526,10 +1535,10 @@ RemoveDefaultACLById(Oid defaclOid) SysScanDesc scan; HeapTuple tuple; - rel = heap_open(DefaultAclRelationId, RowExclusiveLock); + rel = table_open(DefaultAclRelationId, RowExclusiveLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_default_acl_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(defaclOid)); @@ -1544,7 +1553,7 @@ RemoveDefaultACLById(Oid defaclOid) CatalogTupleDelete(rel, &tuple->t_self); systable_endscan(scan); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -1607,10 +1616,6 @@ expand_all_col_privileges(Oid table_oid, Form_pg_class classForm, if (curr_att == InvalidAttrNumber) continue; - /* Skip OID column if it doesn't exist */ - if (curr_att == ObjectIdAttributeNumber && !classForm->relhasoids) - continue; - /* Views don't have any system columns at all */ if (classForm->relkind == RELKIND_VIEW && curr_att < 0) continue; @@ -1636,7 +1641,7 @@ expand_all_col_privileges(Oid table_oid, Form_pg_class classForm, /* * This processes attributes, but expects to be called from - * ExecGrant_Relation, not directly from ExecGrantStmt. + * ExecGrant_Relation, not directly from ExecuteGrantStmt. */ static void ExecGrant_Attribute(InternalGrant *istmt, Oid relOid, const char *relname, @@ -1793,8 +1798,8 @@ ExecGrant_Relation(InternalGrant *istmt) Relation attRelation; ListCell *cell; - relation = heap_open(RelationRelationId, RowExclusiveLock); - attRelation = heap_open(AttributeRelationId, RowExclusiveLock); + relation = table_open(RelationRelationId, RowExclusiveLock); + attRelation = table_open(AttributeRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2114,8 +2119,8 @@ ExecGrant_Relation(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(attRelation, RowExclusiveLock); - heap_close(relation, RowExclusiveLock); + table_close(attRelation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2127,7 +2132,7 @@ ExecGrant_Database(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_DATABASE; - relation = heap_open(DatabaseRelationId, RowExclusiveLock); + relation = table_open(DatabaseRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2222,7 +2227,7 @@ ExecGrant_Database(InternalGrant *istmt) CatalogTupleUpdate(relation, &newtuple->t_self, newtuple); /* Update the shared dependency ACL info */ - updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple), 0, + updateAclDependencies(DatabaseRelationId, pg_database_tuple->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -2235,7 +2240,7 @@ ExecGrant_Database(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2247,7 +2252,7 @@ ExecGrant_Fdw(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_FDW; - relation = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + relation = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2349,7 +2354,7 @@ ExecGrant_Fdw(InternalGrant *istmt) /* Update the shared dependency ACL info */ updateAclDependencies(ForeignDataWrapperRelationId, - HeapTupleGetOid(tuple), 0, + pg_fdw_tuple->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -2362,7 +2367,7 @@ ExecGrant_Fdw(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2374,7 +2379,7 @@ ExecGrant_ForeignServer(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_FOREIGN_SERVER; - relation = heap_open(ForeignServerRelationId, RowExclusiveLock); + relation = table_open(ForeignServerRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2474,7 +2479,7 @@ ExecGrant_ForeignServer(InternalGrant *istmt) /* Update the shared dependency ACL info */ updateAclDependencies(ForeignServerRelationId, - HeapTupleGetOid(tuple), 0, + pg_server_tuple->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -2487,7 +2492,7 @@ ExecGrant_ForeignServer(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2499,7 +2504,7 @@ ExecGrant_Function(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_FUNCTION; - relation = heap_open(ProcedureRelationId, RowExclusiveLock); + relation = table_open(ProcedureRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2610,7 +2615,7 @@ ExecGrant_Function(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2622,7 +2627,7 @@ ExecGrant_Language(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_LANGUAGE; - relation = heap_open(LanguageRelationId, RowExclusiveLock); + relation = table_open(LanguageRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2728,7 +2733,7 @@ ExecGrant_Language(InternalGrant *istmt) recordExtensionInitPriv(langId, LanguageRelationId, 0, new_acl); /* Update the shared dependency ACL info */ - updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple), 0, + updateAclDependencies(LanguageRelationId, pg_language_tuple->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -2741,7 +2746,7 @@ ExecGrant_Language(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2753,8 +2758,8 @@ ExecGrant_Largeobject(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_LARGEOBJECT; - relation = heap_open(LargeObjectMetadataRelationId, - RowExclusiveLock); + relation = table_open(LargeObjectMetadataRelationId, + RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2783,7 +2788,7 @@ ExecGrant_Largeobject(InternalGrant *istmt) /* There's no syscache for pg_largeobject_metadata */ ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); @@ -2868,7 +2873,7 @@ ExecGrant_Largeobject(InternalGrant *istmt) /* Update the shared dependency ACL info */ updateAclDependencies(LargeObjectRelationId, - HeapTupleGetOid(tuple), 0, + form_lo_meta->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -2881,7 +2886,7 @@ ExecGrant_Largeobject(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -2893,7 +2898,7 @@ ExecGrant_Namespace(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_SCHEMA; - relation = heap_open(NamespaceRelationId, RowExclusiveLock); + relation = table_open(NamespaceRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -2992,7 +2997,7 @@ ExecGrant_Namespace(InternalGrant *istmt) recordExtensionInitPriv(nspid, NamespaceRelationId, 0, new_acl); /* Update the shared dependency ACL info */ - updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple), 0, + updateAclDependencies(NamespaceRelationId, pg_namespace_tuple->oid, 0, ownerId, noldmembers, oldmembers, nnewmembers, newmembers); @@ -3005,7 +3010,7 @@ ExecGrant_Namespace(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -3017,7 +3022,7 @@ ExecGrant_Tablespace(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_TABLESPACE; - relation = heap_open(TableSpaceRelationId, RowExclusiveLock); + relation = table_open(TableSpaceRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -3125,7 +3130,7 @@ ExecGrant_Tablespace(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } static void @@ -3137,7 +3142,7 @@ ExecGrant_Type(InternalGrant *istmt) if (istmt->all_privs && istmt->privileges == ACL_NO_RIGHTS) istmt->privileges = ACL_ALL_RIGHTS_TYPE; - relation = heap_open(TypeRelationId, RowExclusiveLock); + relation = table_open(TypeRelationId, RowExclusiveLock); foreach(cell, istmt->objects) { @@ -3262,7 +3267,7 @@ ExecGrant_Type(InternalGrant *istmt) CommandCounterIncrement(); } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } @@ -3458,7 +3463,7 @@ aclcheck_error(AclResult aclerr, ObjectType objtype, case OBJECT_VIEW: msg = gettext_noop("permission denied for view %s"); break; - /* these currently aren't used */ + /* these currently aren't used */ case OBJECT_ACCESS_METHOD: case OBJECT_AMOP: case OBJECT_AMPROC: @@ -3583,11 +3588,13 @@ aclcheck_error(AclResult aclerr, ObjectType objtype, case OBJECT_TSDICTIONARY: msg = gettext_noop("must be owner of text search dictionary %s"); break; - /* - * Special cases: For these, the error message talks about - * "relation", because that's where the ownership is - * attached. See also check_object_ownership(). - */ + + /* + * Special cases: For these, the error message talks + * about "relation", because that's where the + * ownership is attached. See also + * check_object_ownership(). + */ case OBJECT_COLUMN: case OBJECT_POLICY: case OBJECT_RULE: @@ -3595,7 +3602,7 @@ aclcheck_error(AclResult aclerr, ObjectType objtype, case OBJECT_TRIGGER: msg = gettext_noop("must be owner of relation %s"); break; - /* these currently aren't used */ + /* these currently aren't used */ case OBJECT_ACCESS_METHOD: case OBJECT_AMOP: case OBJECT_AMPROC: @@ -4107,13 +4114,13 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, return mask; /* - * Get the largeobject's ACL from pg_language_metadata + * Get the largeobject's ACL from pg_largeobject_metadata */ - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - AccessShareLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid)); @@ -4152,7 +4159,7 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, systable_endscan(scan); - heap_close(pg_lo_meta, AccessShareLock); + table_close(pg_lo_meta, AccessShareLock); return result; } @@ -4891,11 +4898,11 @@ pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid) return true; /* There's no syscache for pg_largeobject_metadata */ - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - AccessShareLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(lobj_oid)); @@ -4912,7 +4919,7 @@ pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid) ownerId = ((Form_pg_largeobject_metadata) GETSTRUCT(tuple))->lomowner; systable_endscan(scan); - heap_close(pg_lo_meta, AccessShareLock); + table_close(pg_lo_meta, AccessShareLock); return has_privs_of_role(roleid, ownerId); } @@ -5254,10 +5261,10 @@ pg_extension_ownercheck(Oid ext_oid, Oid roleid) return true; /* There's no syscache for pg_extension, so do it the hard way */ - pg_extension = heap_open(ExtensionRelationId, AccessShareLock); + pg_extension = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid)); @@ -5274,7 +5281,7 @@ pg_extension_ownercheck(Oid ext_oid, Oid roleid) ownerId = ((Form_pg_extension) GETSTRUCT(tuple))->extowner; systable_endscan(scan); - heap_close(pg_extension, AccessShareLock); + table_close(pg_extension, AccessShareLock); return has_privs_of_role(roleid, ownerId); } @@ -5442,7 +5449,10 @@ get_default_acl_internal(Oid roleId, Oid nsp_oid, char objtype) /* * Get default permissions for newly created object within given schema * - * Returns NULL if built-in system defaults should be used + * Returns NULL if built-in system defaults should be used. + * + * If the result is not NULL, caller must call recordDependencyOnNewAcl + * once the OID of the new object is known. */ Acl * get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid) @@ -5517,6 +5527,30 @@ get_user_default_acl(ObjectType objtype, Oid ownerId, Oid nsp_oid) return result; } +/* + * Record dependencies on roles mentioned in a new object's ACL. + */ +void +recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, + Oid ownerId, Acl *acl) +{ + int nmembers; + Oid *members; + + /* Nothing to do if ACL is defaulted */ + if (acl == NULL) + return; + + /* Extract roles mentioned in ACL */ + nmembers = aclmembers(acl, &members); + + /* Update the shared dependency ACL info */ + updateAclDependencies(classId, objectId, objsubId, + ownerId, + 0, NULL, + nmembers, members); +} + /* * Record initial privileges for the top-level object passed in. * @@ -5692,11 +5726,11 @@ recordExtObjInitPriv(Oid objoid, Oid classoid) SysScanDesc scan; Relation relation; - relation = heap_open(LargeObjectMetadataRelationId, RowExclusiveLock); + relation = table_open(LargeObjectMetadataRelationId, RowExclusiveLock); /* There's no syscache for pg_largeobject_metadata */ ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objoid)); @@ -5934,7 +5968,7 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a HeapTuple tuple; HeapTuple oldtuple; - relation = heap_open(InitPrivsRelationId, RowExclusiveLock); + relation = table_open(InitPrivsRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_init_privs_objoid, @@ -6020,5 +6054,5 @@ recordExtensionInitPrivWorker(Oid objoid, Oid classoid, int objsubid, Acl *new_a /* prevent error when processing objects multiple times */ CommandCounterIncrement(); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 809749add90..1af31c2b9f9 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -5,7 +5,7 @@ * bits of hard-wired knowledge * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,7 +21,9 @@ #include #include "access/genam.h" +#include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "access/transam.h" #include "catalog/catalog.h" #include "catalog/indexing.h" @@ -43,21 +45,26 @@ #include "miscadmin.h" #include "storage/fd.h" #include "utils/fmgroids.h" +#include "utils/fmgrprotos.h" #include "utils/rel.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" +#include "utils/syscache.h" /* * IsSystemRelation - * True iff the relation is either a system catalog or toast table. - * By a system catalog, we mean one that created in the pg_catalog schema - * during initdb. User-created relations in pg_catalog don't count as - * system catalogs. + * True iff the relation is either a system catalog or a toast table. + * See IsCatalogRelation for the exact definition of a system catalog. * - * NB: TOAST relations are considered system relations by this test - * for compatibility with the old IsSystemRelationName function. - * This is appropriate in many places but not all. Where it's not, - * also check IsToastRelation or use IsCatalogRelation(). + * We treat toast tables of user relations as "system relations" for + * protection purposes, e.g. you can't change their schemas without + * special permissions. Therefore, most uses of this function are + * checking whether allow_system_table_mods restrictions apply. + * For other purposes, consider whether you shouldn't be using + * IsCatalogRelation instead. + * + * This function does not perform any catalog accesses. + * Some callers rely on that! */ bool IsSystemRelation(Relation relation) @@ -74,67 +81,74 @@ IsSystemRelation(Relation relation) bool IsSystemClass(Oid relid, Form_pg_class reltuple) { - return IsToastClass(reltuple) || IsCatalogClass(relid, reltuple); + /* IsCatalogRelationOid is a bit faster, so test that first */ + return (IsCatalogRelationOid(relid) || IsToastClass(reltuple)); } /* * IsCatalogRelation - * True iff the relation is a system catalog, or the toast table for - * a system catalog. By a system catalog, we mean one that created - * in the pg_catalog schema during initdb. As with IsSystemRelation(), - * user-created relations in pg_catalog don't count as system catalogs. + * True iff the relation is a system catalog. + * + * By a system catalog, we mean one that is created during the bootstrap + * phase of initdb. That includes not just the catalogs per se, but + * also their indexes, and TOAST tables and indexes if any. * - * Note that IsSystemRelation() returns true for ALL toast relations, - * but this function returns true only for toast relations of system - * catalogs. + * This function does not perform any catalog accesses. + * Some callers rely on that! */ bool IsCatalogRelation(Relation relation) { - return IsCatalogClass(RelationGetRelid(relation), relation->rd_rel); + return IsCatalogRelationOid(RelationGetRelid(relation)); } /* - * IsCatalogClass - * True iff the relation is a system catalog relation. + * IsCatalogRelationOid + * True iff the relation identified by this OID is a system catalog. * - * Check IsCatalogRelation() for details. + * By a system catalog, we mean one that is created during the bootstrap + * phase of initdb. That includes not just the catalogs per se, but + * also their indexes, and TOAST tables and indexes if any. + * + * This function does not perform any catalog accesses. + * Some callers rely on that! */ bool -IsCatalogClass(Oid relid, Form_pg_class reltuple) +IsCatalogRelationOid(Oid relid) { - Oid relnamespace = reltuple->relnamespace; - /* - * Never consider relations outside pg_catalog/pg_toast to be catalog - * relations. - */ - if (!IsSystemNamespace(relnamespace) && !IsToastNamespace(relnamespace)) - return false; - - /* ---- - * Check whether the oid was assigned during initdb, when creating the - * initial template database. Minus the relations in information_schema - * excluded above, these are integral part of the system. - * We could instead check whether the relation is pinned in pg_depend, but - * this is noticeably cheaper and doesn't require catalog access. + * We consider a relation to be a system catalog if it has an OID that was + * manually assigned or assigned by genbki.pl. This includes all the + * defined catalogs, their indexes, and their TOAST tables and indexes. + * + * This rule excludes the relations in information_schema, which are not + * integral to the system and can be treated the same as user relations. + * (Since it's valid to drop and recreate information_schema, any rule + * that did not act this way would be wrong.) * - * This test is safe since even an oid wraparound will preserve this - * property (cf. GetNewObjectId()) and it has the advantage that it works - * correctly even if a user decides to create a relation in the pg_catalog - * namespace. - * ---- + * This test is reliable since an OID wraparound will skip this range of + * OIDs; see GetNewObjectId(). */ - return relid < FirstNormalObjectId; + return (relid < (Oid) FirstBootstrapObjectId); } /* * IsToastRelation * True iff relation is a TOAST support relation (or index). + * + * Does not perform any catalog accesses. */ bool IsToastRelation(Relation relation) { + /* + * What we actually check is whether the relation belongs to a pg_toast + * namespace. This should be equivalent because of restrictions that are + * enforced elsewhere against creating user relations in, or moving + * relations into/out of, a pg_toast namespace. Notice also that this + * will not say "true" for toast tables belonging to other sessions' temp + * tables; we expect that other mechanisms will prevent access to those. + */ return IsToastNamespace(RelationGetNamespace(relation)); } @@ -153,14 +167,16 @@ IsToastClass(Form_pg_class reltuple) } /* - * IsSystemNamespace + * IsCatalogNamespace * True iff namespace is pg_catalog. * + * Does not perform any catalog accesses. + * * NOTE: the reason this isn't a macro is to avoid having to include * catalog/pg_namespace.h in a lot of places. */ bool -IsSystemNamespace(Oid namespaceId) +IsCatalogNamespace(Oid namespaceId) { return namespaceId == PG_CATALOG_NAMESPACE; } @@ -169,9 +185,13 @@ IsSystemNamespace(Oid namespaceId) * IsToastNamespace * True iff namespace is pg_toast or my temporary-toast-table namespace. * + * Does not perform any catalog accesses. + * * Note: this will return false for temporary-toast-table namespaces belonging * to other backends. Those are treated the same as other backends' regular * temp table namespaces, and access is prevented where appropriate. + * If you need to check for those, you may be able to use isAnyTempNamespace, + * but beware that that does involve a catalog access. */ bool IsToastNamespace(Oid namespaceId) @@ -253,82 +273,49 @@ IsSharedRelation(Oid relationId) relationId == SubscriptionNameIndexId) return true; /* These are their toast tables and toast indexes (see toasting.h) */ - if (relationId == PgShdescriptionToastTable || - relationId == PgShdescriptionToastIndex || + if (relationId == PgAuthidToastTable || + relationId == PgAuthidToastIndex || + relationId == PgDatabaseToastTable || + relationId == PgDatabaseToastIndex || relationId == PgDbRoleSettingToastTable || relationId == PgDbRoleSettingToastIndex || + relationId == PgPlTemplateToastTable || + relationId == PgPlTemplateToastIndex || + relationId == PgReplicationOriginToastTable || + relationId == PgReplicationOriginToastIndex || + relationId == PgShdescriptionToastTable || + relationId == PgShdescriptionToastIndex || relationId == PgShseclabelToastTable || - relationId == PgShseclabelToastIndex) + relationId == PgShseclabelToastIndex || + relationId == PgSubscriptionToastTable || + relationId == PgSubscriptionToastIndex || + relationId == PgTablespaceToastTable || + relationId == PgTablespaceToastIndex) return true; return false; } /* - * GetNewOid - * Generate a new OID that is unique within the given relation. - * - * Caller must have a suitable lock on the relation. - * - * Uniqueness is promised only if the relation has a unique index on OID. - * This is true for all system catalogs that have OIDs, but might not be - * true for user tables. Note that we are effectively assuming that the - * table has a relatively small number of entries (much less than 2^32) - * and there aren't very long runs of consecutive existing OIDs. Again, - * this is reasonable for system catalogs but less so for user tables. + * GetNewOidWithIndex + * Generate a new OID that is unique within the system relation. * * Since the OID is not immediately inserted into the table, there is a * race condition here; but a problem could occur only if someone else * managed to cycle through 2^32 OIDs and generate the same OID before we * finish inserting our row. This seems unlikely to be a problem. Note * that if we had to *commit* the row to end the race condition, the risk - * would be rather higher; therefore we use SnapshotDirty in the test, - * so that we will see uncommitted rows. - */ -Oid -GetNewOid(Relation relation) -{ - Oid oidIndex; - - /* If relation doesn't have OIDs at all, caller is confused */ - Assert(relation->rd_rel->relhasoids); - - /* In bootstrap mode, we don't have any indexes to use */ - if (IsBootstrapProcessingMode()) - return GetNewObjectId(); - - /* The relcache will cache the identity of the OID index for us */ - oidIndex = RelationGetOidIndex(relation); - - /* If no OID index, just hand back the next OID counter value */ - if (!OidIsValid(oidIndex)) - { - /* - * System catalogs that have OIDs should *always* have a unique OID - * index; we should only take this path for user tables. Give a - * warning if it looks like somebody forgot an index. - */ - if (IsSystemRelation(relation)) - elog(WARNING, "generating possibly-non-unique OID for \"%s\"", - RelationGetRelationName(relation)); - - return GetNewObjectId(); - } - - /* Otherwise, use the index to find a nonconflicting OID */ - return GetNewOidWithIndex(relation, oidIndex, ObjectIdAttributeNumber); -} - -/* - * GetNewOidWithIndex - * Guts of GetNewOid: use the supplied index + * would be rather higher; therefore we use SnapshotAny in the test, so that + * we will see uncommitted rows. (We used to use SnapshotDirty, but that has + * the disadvantage that it ignores recently-deleted rows, creating a risk + * of transient conflicts for as long as our own MVCC snapshots think a + * recently-deleted row is live. The risk is far higher when selecting TOAST + * OIDs, because SnapshotToast considers dead rows as active indefinitely.) * - * This is exported separately because there are cases where we want to use - * an index that will not be recognized by RelationGetOidIndex: TOAST tables - * have indexes that are usable, but have multiple columns and are on - * ordinary columns rather than a true OID column. This code will work - * anyway, so long as the OID is the index's first column. The caller must - * pass in the actual heap attnum of the OID column, however. + * Note that we are effectively assuming that the table has a relatively small + * number of entries (much less than 2^32) and there aren't very long runs of + * consecutive existing OIDs. This is a mostly reasonable assumption for + * system catalogs. * * Caller must have a suitable lock on the relation. */ @@ -336,11 +323,17 @@ Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) { Oid newOid; - SnapshotData SnapshotDirty; SysScanDesc scan; ScanKeyData key; bool collides; + /* Only system relations are supported */ + Assert(IsSystemRelation(relation)); + + /* In bootstrap mode, we don't have any indexes to use */ + if (IsBootstrapProcessingMode()) + return GetNewObjectId(); + /* * We should never be asked to generate a new pg_type OID during * pg_upgrade; doing so would risk collisions with the OIDs it wants to @@ -349,8 +342,6 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) */ Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId); - InitDirtySnapshot(SnapshotDirty); - /* Generate new OIDs until we find one not in the table */ do { @@ -363,9 +354,9 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(newOid)); - /* see notes above about using SnapshotDirty */ + /* see notes above about using SnapshotAny */ scan = systable_beginscan(relation, indexId, true, - &SnapshotDirty, 1, &key); + SnapshotAny, 1, &key); collides = HeapTupleIsValid(systable_getnext(scan)); @@ -385,8 +376,8 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn) * is also an unused OID within pg_class. If the result is to be used only * as a relfilenode for an existing relation, pass NULL for pg_class. * - * As with GetNewOid, there is some theoretical risk of a race condition, - * but it doesn't seem worth worrying about. + * As with GetNewOidWithIndex(), there is some theoretical risk of a race + * condition, but it doesn't seem worth worrying about. * * Note: we don't support using this in bootstrap mode. All relations * created by bootstrap have preassigned OIDs, so there's no need. @@ -396,7 +387,6 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence) { RelFileNodeBackend rnode; char *rpath; - int fd; bool collides; BackendId backend; @@ -438,18 +428,17 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence) /* Generate the OID */ if (pg_class) - rnode.node.relNode = GetNewOid(pg_class); + rnode.node.relNode = GetNewOidWithIndex(pg_class, ClassOidIndexId, + Anum_pg_class_oid); else rnode.node.relNode = GetNewObjectId(); /* Check for existing file of same name */ rpath = relpath(rnode, MAIN_FORKNUM); - fd = BasicOpenFile(rpath, O_RDONLY | PG_BINARY); - if (fd >= 0) + if (access(rpath, F_OK) == 0) { /* definite collision */ - close(fd); collides = true; } else @@ -457,13 +446,9 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence) /* * Here we have a little bit of a dilemma: if errno is something * other than ENOENT, should we declare a collision and loop? In - * particular one might think this advisable for, say, EPERM. - * However there really shouldn't be any unreadable files in a - * tablespace directory, and if the EPERM is actually complaining - * that we can't read the directory itself, we'd be in an infinite - * loop. In practice it seems best to go ahead regardless of the - * errno. If there is a colliding file we will get an smgr - * failure when we attempt to create the new relation file. + * practice it seems best to go ahead regardless of the errno. If + * there is a colliding file we will get an smgr failure when we + * attempt to create the new relation file. */ collides = false; } @@ -473,3 +458,82 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence) return rnode.node.relNode; } + +/* + * SQL callable interface for GetNewOidWithIndex(). Outside of initdb's + * direct insertions into catalog tables, and recovering from corruption, this + * should rarely be needed. + * + * Function is intentionally not documented in the user facing docs. + */ +Datum +pg_nextoid(PG_FUNCTION_ARGS) +{ + Oid reloid = PG_GETARG_OID(0); + Name attname = PG_GETARG_NAME(1); + Oid idxoid = PG_GETARG_OID(2); + Relation rel; + Relation idx; + HeapTuple atttuple; + Form_pg_attribute attform; + AttrNumber attno; + Oid newoid; + + /* + * As this function is not intended to be used during normal running, and + * only supports system catalogs (which require superuser permissions to + * modify), just checking for superuser ought to not obstruct valid + * usecases. + */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to call pg_nextoid()"))); + + rel = table_open(reloid, RowExclusiveLock); + idx = index_open(idxoid, RowExclusiveLock); + + if (!IsSystemRelation(rel)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("pg_nextoid() can only be used on system catalogs"))); + + if (idx->rd_index->indrelid != RelationGetRelid(rel)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("index \"%s\" does not belong to table \"%s\"", + RelationGetRelationName(idx), + RelationGetRelationName(rel)))); + + atttuple = SearchSysCacheAttName(reloid, NameStr(*attname)); + if (!HeapTupleIsValid(atttuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + NameStr(*attname), RelationGetRelationName(rel)))); + + attform = ((Form_pg_attribute) GETSTRUCT(atttuple)); + attno = attform->attnum; + + if (attform->atttypid != OIDOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("column \"%s\" is not of type oid", + NameStr(*attname)))); + + if (IndexRelationGetNumberOfKeyAttributes(idx) != 1 || + idx->rd_index->indkey.values[0] != attno) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("index \"%s\" is not the index for column \"%s\"", + RelationGetRelationName(idx), + NameStr(*attname)))); + + newoid = GetNewOidWithIndex(rel, idxoid, attno); + + ReleaseSysCache(atttuple); + table_close(rel, RowExclusiveLock); + index_close(idx, RowExclusiveLock); + + return newoid; +} diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index c23cfdaf6be..dd0a7d8dac9 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -4,7 +4,7 @@ * Routines to support inter-object dependencies. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,7 +14,9 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/heap.h" @@ -79,7 +81,6 @@ #include "utils/guc.h" #include "utils/lsyscache.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -98,8 +99,11 @@ typedef struct #define DEPFLAG_NORMAL 0x0002 /* reached via normal dependency */ #define DEPFLAG_AUTO 0x0004 /* reached via auto dependency */ #define DEPFLAG_INTERNAL 0x0008 /* reached via internal dependency */ -#define DEPFLAG_EXTENSION 0x0010 /* reached via extension dependency */ -#define DEPFLAG_REVERSE 0x0020 /* reverse internal/extension link */ +#define DEPFLAG_PARTITION 0x0010 /* reached via partition dependency */ +#define DEPFLAG_EXTENSION 0x0020 /* reached via extension dependency */ +#define DEPFLAG_REVERSE 0x0040 /* reverse internal/extension link */ +#define DEPFLAG_IS_PART 0x0080 /* has a partition dependency */ +#define DEPFLAG_SUBOBJECT 0x0100 /* subobject of another deletable object */ /* expansible list of ObjectAddresses */ @@ -121,6 +125,13 @@ typedef struct ObjectAddressStack struct ObjectAddressStack *next; /* next outer stack level */ } ObjectAddressStack; +/* temporary storage in findDependentObjects */ +typedef struct +{ + ObjectAddress obj; /* object to be deleted --- MUST BE FIRST */ + int subflags; /* flags to pass down when recursing to obj */ +} ObjectAddressAndFlags; + /* for find_expr_references_walker */ typedef struct { @@ -175,36 +186,36 @@ static const Oid object_classes[] = { static void findDependentObjects(const ObjectAddress *object, - int objflags, - int flags, - ObjectAddressStack *stack, - ObjectAddresses *targetObjects, - const ObjectAddresses *pendingObjects, - Relation *depRel); + int objflags, + int flags, + ObjectAddressStack *stack, + ObjectAddresses *targetObjects, + const ObjectAddresses *pendingObjects, + Relation *depRel); static void reportDependentObjects(const ObjectAddresses *targetObjects, - DropBehavior behavior, - int flags, - const ObjectAddress *origObject); + DropBehavior behavior, + int flags, + const ObjectAddress *origObject); static void deleteOneObject(const ObjectAddress *object, - Relation *depRel, int32 flags); + Relation *depRel, int32 flags); static void doDeletion(const ObjectAddress *object, int flags); static void AcquireDeletionLock(const ObjectAddress *object, int flags); static void ReleaseDeletionLock(const ObjectAddress *object); static bool find_expr_references_walker(Node *node, - find_expr_references_context *context); + find_expr_references_context *context); static void eliminate_duplicate_dependencies(ObjectAddresses *addrs); static int object_address_comparator(const void *a, const void *b); static void add_object_address(ObjectClass oclass, Oid objectId, int32 subId, - ObjectAddresses *addrs); -static void add_exact_object_address_extra(const ObjectAddress *object, - const ObjectAddressExtra *extra, ObjectAddresses *addrs); +static void add_exact_object_address_extra(const ObjectAddress *object, + const ObjectAddressExtra *extra, + ObjectAddresses *addrs); static bool object_address_present_add_flags(const ObjectAddress *object, - int flags, - ObjectAddresses *addrs); + int flags, + ObjectAddresses *addrs); static bool stack_address_present_add_flags(const ObjectAddress *object, - int flags, - ObjectAddressStack *stack); + int flags, + ObjectAddressStack *stack); static void DeleteInitPrivs(const ObjectAddress *object); @@ -295,6 +306,10 @@ deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, * PERFORM_DELETION_SKIP_EXTENSIONS: do not delete extensions, even when * deleting objects that are part of an extension. This should generally * be used only when dropping temporary objects. + * + * PERFORM_DELETION_CONCURRENT_LOCK: perform the drop normally but with a lock + * as if it were concurrent. This is used by REINDEX CONCURRENTLY. + * */ void performDeletion(const ObjectAddress *object, @@ -307,7 +322,7 @@ performDeletion(const ObjectAddress *object, * We save some cycles by opening pg_depend just once and passing the * Relation pointer down to all the recursive deletion steps. */ - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); /* * Acquire deletion lock on the target object. (Ideally the caller has @@ -343,7 +358,7 @@ performDeletion(const ObjectAddress *object, /* And clean up */ free_object_addresses(targetObjects); - heap_close(depRel, RowExclusiveLock); + table_close(depRel, RowExclusiveLock); } /* @@ -371,7 +386,7 @@ performMultipleDeletions(const ObjectAddresses *objects, * We save some cycles by opening pg_depend just once and passing the * Relation pointer down to all the recursive deletion steps. */ - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); /* * Construct a list of objects to delete (ie, the given objects plus @@ -419,7 +434,7 @@ performMultipleDeletions(const ObjectAddresses *objects, /* And clean up */ free_object_addresses(targetObjects); - heap_close(depRel, RowExclusiveLock); + table_close(depRel, RowExclusiveLock); } /* @@ -469,6 +484,11 @@ findDependentObjects(const ObjectAddress *object, SysScanDesc scan; HeapTuple tup; ObjectAddress otherObject; + ObjectAddress owningObject; + ObjectAddress partitionObject; + ObjectAddressAndFlags *dependentObjects; + int numDependentObjects; + int maxDependentObjects; ObjectAddressStack mystack; ObjectAddressExtra extra; @@ -523,6 +543,7 @@ findDependentObjects(const ObjectAddress *object, ObjectIdGetDatum(object->objectId)); if (object->objectSubId != 0) { + /* Consider only dependencies of this sub-object */ ScanKeyInit(&key[2], Anum_pg_depend_objsubid, BTEqualStrategyNumber, F_INT4EQ, @@ -530,11 +551,18 @@ findDependentObjects(const ObjectAddress *object, nkeys = 3; } else + { + /* Consider dependencies of this object and any sub-objects it has */ nkeys = 2; + } scan = systable_beginscan(*depRel, DependDependerIndexId, true, NULL, nkeys, key); + /* initialize variables that loop may fill */ + memset(&owningObject, 0, sizeof(owningObject)); + memset(&partitionObject, 0, sizeof(partitionObject)); + while (HeapTupleIsValid(tup = systable_getnext(scan))) { Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup); @@ -543,6 +571,18 @@ findDependentObjects(const ObjectAddress *object, otherObject.objectId = foundDep->refobjid; otherObject.objectSubId = foundDep->refobjsubid; + /* + * When scanning dependencies of a whole object, we may find rows + * linking sub-objects of the object to the object itself. (Normally, + * such a dependency is implicit, but we must make explicit ones in + * some cases involving partitioning.) We must ignore such rows to + * avoid infinite recursion. + */ + if (otherObject.classId == object->classId && + otherObject.objectId == object->objectId && + object->objectSubId == 0) + continue; + switch (foundDep->deptype) { case DEPENDENCY_NORMAL: @@ -579,24 +619,26 @@ findDependentObjects(const ObjectAddress *object, /* FALL THRU */ case DEPENDENCY_INTERNAL: - case DEPENDENCY_INTERNAL_AUTO: /* * This object is part of the internal implementation of * another object, or is part of the extension that is the * other object. We have three cases: * - * 1. At the outermost recursion level, disallow the DROP. (We - * just ereport here, rather than proceeding, since no other - * dependencies are likely to be interesting.) However, if - * the owning object is listed in pendingObjects, just release - * the caller's lock and return; we'll eventually complete the - * DROP when we reach that entry in the pending list. + * 1. At the outermost recursion level, we must disallow the + * DROP. However, if the owning object is listed in + * pendingObjects, just release the caller's lock and return; + * we'll eventually complete the DROP when we reach that entry + * in the pending list. + * + * Note: the above statement is true only if this pg_depend + * entry still exists by then; in principle, therefore, we + * could miss deleting an item the user told us to delete. + * However, no inconsistency can result: since we're at outer + * level, there is no object depending on this one. */ if (stack == NULL) { - char *otherObjDesc; - if (pendingObjects && object_address_present(&otherObject, pendingObjects)) { @@ -605,14 +647,21 @@ findDependentObjects(const ObjectAddress *object, ReleaseDeletionLock(object); return; } - otherObjDesc = getObjectDescription(&otherObject); - ereport(ERROR, - (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), - errmsg("cannot drop %s because %s requires it", - getObjectDescription(object), - otherObjDesc), - errhint("You can drop %s instead.", - otherObjDesc))); + + /* + * We postpone actually issuing the error message until + * after this loop, so that we can make the behavior + * independent of the ordering of pg_depend entries, at + * least if there's not more than one INTERNAL and one + * EXTENSION dependency. (If there's more, we'll complain + * about a random one of them.) Prefer to complain about + * EXTENSION, since that's generally a more important + * dependency. + */ + if (!OidIsValid(owningObject.classId) || + foundDep->deptype == DEPENDENCY_EXTENSION) + owningObject = otherObject; + break; } /* @@ -631,14 +680,6 @@ findDependentObjects(const ObjectAddress *object, * transform this deletion request into a delete of this * owning object. * - * For INTERNAL_AUTO dependencies, we don't enforce this; - * in other words, we don't follow the links back to the - * owning object. - */ - if (foundDep->deptype == DEPENDENCY_INTERNAL_AUTO) - break; - - /* * First, release caller's lock on this object and get * deletion lock on the owning object. (We must release * caller's lock to avoid deadlock against a concurrent @@ -660,6 +701,13 @@ findDependentObjects(const ObjectAddress *object, return; } + /* + * One way or the other, we're done with the scan; might as + * well close it down before recursing, to reduce peak + * resource consumption. + */ + systable_endscan(scan); + /* * Okay, recurse to the owning object instead of proceeding. * @@ -678,10 +726,66 @@ findDependentObjects(const ObjectAddress *object, targetObjects, pendingObjects, depRel); + + /* + * The current target object should have been added to + * targetObjects while processing the owning object; but it + * probably got only the flag bits associated with the + * dependency we're looking at. We need to add the objflags + * that were passed to this recursion level, too, else we may + * get a bogus failure in reportDependentObjects (if, for + * example, we were called due to a partition dependency). + * + * If somehow the current object didn't get scheduled for + * deletion, bleat. (That would imply that somebody deleted + * this dependency record before the recursion got to it.) + * Another idea would be to reacquire lock on the current + * object and resume trying to delete it, but it seems not + * worth dealing with the race conditions inherent in that. + */ + if (!object_address_present_add_flags(object, objflags, + targetObjects)) + elog(ERROR, "deletion of owning object %s failed to delete %s", + getObjectDescription(&otherObject), + getObjectDescription(object)); + /* And we're done here. */ - systable_endscan(scan); return; + case DEPENDENCY_PARTITION_PRI: + + /* + * Remember that this object has a partition-type dependency. + * After the dependency scan, we'll complain if we didn't find + * a reason to delete one of its partition dependencies. + */ + objflags |= DEPFLAG_IS_PART; + + /* + * Also remember the primary partition owner, for error + * messages. If there are multiple primary owners (which + * there should not be), we'll report a random one of them. + */ + partitionObject = otherObject; + break; + + case DEPENDENCY_PARTITION_SEC: + + /* + * Only use secondary partition owners in error messages if we + * find no primary owner (which probably shouldn't happen). + */ + if (!(objflags & DEPFLAG_IS_PART)) + partitionObject = otherObject; + + /* + * Remember that this object has a partition-type dependency. + * After the dependency scan, we'll complain if we didn't find + * a reason to delete one of its partition dependencies. + */ + objflags |= DEPFLAG_IS_PART; + break; + case DEPENDENCY_PIN: /* @@ -701,12 +805,39 @@ findDependentObjects(const ObjectAddress *object, systable_endscan(scan); /* - * Now recurse to any dependent objects. We must visit them first since - * they have to be deleted before the current object. + * If we found an INTERNAL or EXTENSION dependency when we're at outer + * level, complain about it now. If we also found a PARTITION dependency, + * we prefer to report the PARTITION dependency. This is arbitrary but + * seems to be more useful in practice. */ - mystack.object = object; /* set up a new stack level */ - mystack.flags = objflags; - mystack.next = stack; + if (OidIsValid(owningObject.classId)) + { + char *otherObjDesc; + + if (OidIsValid(partitionObject.classId)) + otherObjDesc = getObjectDescription(&partitionObject); + else + otherObjDesc = getObjectDescription(&owningObject); + + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot drop %s because %s requires it", + getObjectDescription(object), otherObjDesc), + errhint("You can drop %s instead.", otherObjDesc))); + } + + /* + * Next, identify all objects that directly depend on the current object. + * To ensure predictable deletion order, we collect them up in + * dependentObjects and sort the list before actually recursing. (The + * deletion order would be valid in any case, but doing this ensures + * consistent output from DROP CASCADE commands, which is helpful for + * regression testing.) + */ + maxDependentObjects = 128; /* arbitrary initial allocation */ + dependentObjects = (ObjectAddressAndFlags *) + palloc(maxDependentObjects * sizeof(ObjectAddressAndFlags)); + numDependentObjects = 0; ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -739,6 +870,16 @@ findDependentObjects(const ObjectAddress *object, otherObject.objectId = foundDep->objid; otherObject.objectSubId = foundDep->objsubid; + /* + * If what we found is a sub-object of the current object, just ignore + * it. (Normally, such a dependency is implicit, but we must make + * explicit ones in some cases involving partitioning.) + */ + if (otherObject.classId == object->classId && + otherObject.objectId == object->objectId && + object->objectSubId == 0) + continue; + /* * Must lock the dependent object before recursing to it. */ @@ -759,7 +900,10 @@ findDependentObjects(const ObjectAddress *object, continue; } - /* Recurse, passing objflags indicating the dependency type */ + /* + * We do need to delete it, so identify objflags to be passed down, + * which depend on the dependency type. + */ switch (foundDep->deptype) { case DEPENDENCY_NORMAL: @@ -769,10 +913,13 @@ findDependentObjects(const ObjectAddress *object, case DEPENDENCY_AUTO_EXTENSION: subflags = DEPFLAG_AUTO; break; - case DEPENDENCY_INTERNAL_AUTO: case DEPENDENCY_INTERNAL: subflags = DEPFLAG_INTERNAL; break; + case DEPENDENCY_PARTITION_PRI: + case DEPENDENCY_PARTITION_SEC: + subflags = DEPFLAG_PARTITION; + break; case DEPENDENCY_EXTENSION: subflags = DEPFLAG_EXTENSION; break; @@ -795,8 +942,47 @@ findDependentObjects(const ObjectAddress *object, break; } - findDependentObjects(&otherObject, - subflags, + /* And add it to the pending-objects list */ + if (numDependentObjects >= maxDependentObjects) + { + /* enlarge array if needed */ + maxDependentObjects *= 2; + dependentObjects = (ObjectAddressAndFlags *) + repalloc(dependentObjects, + maxDependentObjects * sizeof(ObjectAddressAndFlags)); + } + + dependentObjects[numDependentObjects].obj = otherObject; + dependentObjects[numDependentObjects].subflags = subflags; + numDependentObjects++; + } + + systable_endscan(scan); + + /* + * Now we can sort the dependent objects into a stable visitation order. + * It's safe to use object_address_comparator here since the obj field is + * first within ObjectAddressAndFlags. + */ + if (numDependentObjects > 1) + qsort((void *) dependentObjects, numDependentObjects, + sizeof(ObjectAddressAndFlags), + object_address_comparator); + + /* + * Now recurse to the dependent objects. We must visit them first since + * they have to be deleted before the current object. + */ + mystack.object = object; /* set up a new stack level */ + mystack.flags = objflags; + mystack.next = stack; + + for (int i = 0; i < numDependentObjects; i++) + { + ObjectAddressAndFlags *depObj = dependentObjects + i; + + findDependentObjects(&depObj->obj, + depObj->subflags, flags, &mystack, targetObjects, @@ -804,15 +990,20 @@ findDependentObjects(const ObjectAddress *object, depRel); } - systable_endscan(scan); + pfree(dependentObjects); /* * Finally, we can add the target object to targetObjects. Be careful to * include any flags that were passed back down to us from inner recursion - * levels. + * levels. Record the "dependee" as being either the most important + * partition owner if there is one, else the object we recursed from, if + * any. (The logic in reportDependentObjects() is such that it can only + * need one of those objects.) */ extra.flags = mystack.flags; - if (stack) + if (extra.flags & DEPFLAG_IS_PART) + extra.dependee = partitionObject; + else if (stack) extra.dependee = *stack->object; else memset(&extra.dependee, 0, sizeof(extra.dependee)); @@ -846,9 +1037,38 @@ reportDependentObjects(const ObjectAddresses *targetObjects, int numNotReportedClient = 0; int i; + /* + * If we need to delete any partition-dependent objects, make sure that + * we're deleting at least one of their partition dependencies, too. That + * can be detected by checking that we reached them by a PARTITION + * dependency at some point. + * + * We just report the first such object, as in most cases the only way to + * trigger this complaint is to explicitly try to delete one partition of + * a partitioned object. + */ + for (i = 0; i < targetObjects->numrefs; i++) + { + const ObjectAddressExtra *extra = &targetObjects->extras[i]; + + if ((extra->flags & DEPFLAG_IS_PART) && + !(extra->flags & DEPFLAG_PARTITION)) + { + const ObjectAddress *object = &targetObjects->refs[i]; + char *otherObjDesc = getObjectDescription(&extra->dependee); + + ereport(ERROR, + (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), + errmsg("cannot drop %s because %s requires it", + getObjectDescription(object), otherObjDesc), + errhint("You can drop %s instead.", otherObjDesc))); + } + } + /* * If no error is to be thrown, and the msglevel is too low to be shown to - * either client or server log, there's no need to do any of the work. + * either client or server log, there's no need to do any of the rest of + * the work. * * Note: this code doesn't know all there is to be known about elog * levels, but it works for NOTICE and DEBUG2, which are the only values @@ -884,15 +1104,20 @@ reportDependentObjects(const ObjectAddresses *targetObjects, if (extra->flags & DEPFLAG_ORIGINAL) continue; + /* Also ignore sub-objects; we'll report the whole object elsewhere */ + if (extra->flags & DEPFLAG_SUBOBJECT) + continue; + objDesc = getObjectDescription(obj); /* * If, at any stage of the recursive search, we reached the object via - * an AUTO, INTERNAL, or EXTENSION dependency, then it's okay to - * delete it even in RESTRICT mode. + * an AUTO, INTERNAL, PARTITION, or EXTENSION dependency, then it's + * okay to delete it even in RESTRICT mode. */ if (extra->flags & (DEPFLAG_AUTO | DEPFLAG_INTERNAL | + DEPFLAG_PARTITION | DEPFLAG_EXTENSION)) { /* @@ -1022,7 +1247,7 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags) * relation open across doDeletion(). */ if (flags & PERFORM_DELETION_CONCURRENTLY) - heap_close(*depRel, RowExclusiveLock); + table_close(*depRel, RowExclusiveLock); /* * Delete the object itself, in an object-type-dependent way. @@ -1039,7 +1264,7 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags) * Reopen depRel if we closed it above */ if (flags & PERFORM_DELETION_CONCURRENTLY) - *depRel = heap_open(DependRelationId, RowExclusiveLock); + *depRel = table_open(DependRelationId, RowExclusiveLock); /* * Now remove any pg_depend records that link from this object to others. @@ -1121,9 +1346,10 @@ doDeletion(const ObjectAddress *object, int flags) relKind == RELKIND_PARTITIONED_INDEX) { bool concurrent = ((flags & PERFORM_DELETION_CONCURRENTLY) != 0); + bool concurrent_lock_mode = ((flags & PERFORM_DELETION_CONCURRENT_LOCK) != 0); Assert(object->objectSubId == 0); - index_drop(object->objectId, concurrent); + index_drop(object->objectId, concurrent, concurrent_lock_mode); } else { @@ -1388,8 +1614,10 @@ recordDependencyOnExpr(const ObjectAddress *depender, * As above, but only one relation is expected to be referenced (with * varno = 1 and varlevelsup = 0). Pass the relation OID instead of a * range table. An additional frammish is that dependencies on that - * relation (or its component columns) will be marked with 'self_behavior', - * whereas 'behavior' is used for everything else. + * relation's component columns will be marked with 'self_behavior', + * whereas 'behavior' is used for everything else; also, if 'reverse_self' + * is true, those dependencies are reversed so that the columns are made + * to depend on the table not vice versa. * * NOTE: the caller should ensure that a whole-table dependency on the * specified relation is created separately, if one is needed. In particular, @@ -1402,7 +1630,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, - bool ignore_self) + bool reverse_self) { find_expr_references_context context; RangeTblEntry rte; @@ -1415,6 +1643,7 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender, rte.rtekind = RTE_RELATION; rte.relid = relId; rte.relkind = RELKIND_RELATION; /* no need for exactness here */ + rte.rellockmode = AccessShareLock; context.rtables = list_make1(list_make1(&rte)); @@ -1425,7 +1654,8 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender, eliminate_duplicate_dependencies(context.addrs); /* Separate self-dependencies if necessary */ - if (behavior != self_behavior && context.addrs->numrefs > 0) + if ((behavior != self_behavior || reverse_self) && + context.addrs->numrefs > 0) { ObjectAddresses *self_addrs; ObjectAddress *outobj; @@ -1456,11 +1686,23 @@ recordDependencyOnSingleRelExpr(const ObjectAddress *depender, } context.addrs->numrefs = outrefs; - /* Record the self-dependencies */ - if (!ignore_self) + /* Record the self-dependencies with the appropriate direction */ + if (!reverse_self) recordMultipleDependencies(depender, self_addrs->refs, self_addrs->numrefs, self_behavior); + else + { + /* Can't use recordMultipleDependencies, so do it the hard way */ + int selfref; + + for (selfref = 0; selfref < self_addrs->numrefs; selfref++) + { + ObjectAddress *thisobj = self_addrs->refs + selfref; + + recordDependencyOn(thisobj, depender, self_behavior); + } + } free_object_addresses(self_addrs); } @@ -2101,18 +2343,31 @@ object_address_comparator(const void *a, const void *b) const ObjectAddress *obja = (const ObjectAddress *) a; const ObjectAddress *objb = (const ObjectAddress *) b; - if (obja->classId < objb->classId) + /* + * Primary sort key is OID descending. Most of the time, this will result + * in putting newer objects before older ones, which is likely to be the + * right order to delete in. + */ + if (obja->objectId > objb->objectId) return -1; - if (obja->classId > objb->classId) - return 1; if (obja->objectId < objb->objectId) + return 1; + + /* + * Next sort on catalog ID, in case identical OIDs appear in different + * catalogs. Sort direction is pretty arbitrary here. + */ + if (obja->classId < objb->classId) return -1; - if (obja->objectId > objb->objectId) + if (obja->classId > objb->classId) return 1; /* - * We sort the subId as an unsigned int so that 0 will come first. See - * logic in eliminate_duplicate_dependencies. + * Last, sort on object subId. + * + * We sort the subId as an unsigned int so that 0 (the whole object) will + * come first. This is essential for eliminate_duplicate_dependencies, + * and is also the best order for findDependentObjects. */ if ((unsigned int) obja->objectSubId < (unsigned int) objb->objectSubId) return -1; @@ -2317,13 +2572,19 @@ object_address_present_add_flags(const ObjectAddress *object, * DROP COLUMN action even though we know we're gonna delete * the table later. * + * What we can do, though, is mark this as a subobject so that + * we don't report it separately, which is confusing because + * it's unpredictable whether it happens or not. But do so + * only if flags != 0 (flags == 0 is a read-only probe). + * * Because there could be other subobjects of this object in * the array, this case means we always have to loop through * the whole array; we cannot exit early on a match. */ ObjectAddressExtra *thisextra = addrs->extras + i; - thisextra->flags |= flags; + if (flags) + thisextra->flags |= (flags | DEPFLAG_SUBOBJECT); } } } @@ -2371,7 +2632,8 @@ stack_address_present_add_flags(const ObjectAddress *object, * object_address_present_add_flags(), we should propagate * flags for the whole object to each of its subobjects. */ - stackptr->flags |= flags; + if (flags) + stackptr->flags |= (flags | DEPFLAG_SUBOBJECT); } } } @@ -2394,6 +2656,23 @@ record_object_address_dependencies(const ObjectAddress *depender, behavior); } +/* + * Sort the items in an ObjectAddresses array. + * + * The major sort key is OID-descending, so that newer objects will be listed + * first in most cases. This is primarily useful for ensuring stable outputs + * from regression tests; it's not recommended if the order of the objects is + * determined by user input, such as the order of targets in a DROP command. + */ +void +sort_object_addresses(ObjectAddresses *addrs) +{ + if (addrs->numrefs > 1) + qsort((void *) addrs->refs, addrs->numrefs, + sizeof(ObjectAddress), + object_address_comparator); +} + /* * Clean up when done with an ObjectAddresses array. */ @@ -2555,7 +2834,7 @@ DeleteInitPrivs(const ObjectAddress *object) SysScanDesc scan; HeapTuple oldtuple; - relation = heap_open(InitPrivsRelationId, RowExclusiveLock); + relation = table_open(InitPrivsRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_init_privs_objoid, @@ -2578,5 +2857,5 @@ DeleteInitPrivs(const ObjectAddress *object) systable_endscan(scan); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl index cd68fc31088..201d12d358c 100644 --- a/src/backend/catalog/genbki.pl +++ b/src/backend/catalog/genbki.pl @@ -7,79 +7,58 @@ # formatted header files and data files. The BKI files are used to # initialize the postgres template database. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/catalog/genbki.pl # #---------------------------------------------------------------------- -use Catalog; - use strict; use warnings; +use Getopt::Long; + +use File::Basename; +use File::Spec; +BEGIN { use lib File::Spec->rel2abs(dirname(__FILE__)); } + +use Catalog; -my @input_files; my $output_path = ''; my $major_version; +my $include_path; -# Process command line switches. -while (@ARGV) -{ - my $arg = shift @ARGV; - if ($arg !~ /^-/) - { - push @input_files, $arg; - } - elsif ($arg =~ /^-o/) - { - $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; - } - elsif ($arg =~ /^--set-version=(.*)$/) - { - $major_version = $1; - die "Invalid version string.\n" - if !($major_version =~ /^\d+$/); - } - else - { - usage(); - } -} +GetOptions( + 'output:s' => \$output_path, + 'set-version:s' => \$major_version, + 'include-path:s' => \$include_path) || usage(); # Sanity check arguments. -die "No input files.\n" if !@input_files; -die "--set-version must be specified.\n" if !defined $major_version; +die "No input files.\n" unless @ARGV; +die "--set-version must be specified.\n" unless $major_version; +die "Invalid version string: $major_version\n" + unless $major_version =~ /^\d+$/; +die "--include-path must be specified.\n" unless $include_path; -# Make sure output_path ends in a slash. +# Make sure paths end with a slash. if ($output_path ne '' && substr($output_path, -1) ne '/') { $output_path .= '/'; } +if (substr($include_path, -1) ne '/') +{ + $include_path .= '/'; +} -# Open temp files -my $tmpext = ".tmp$$"; -my $bkifile = $output_path . 'postgres.bki'; -open my $bki, '>', $bkifile . $tmpext - or die "can't open $bkifile$tmpext: $!"; -my $schemafile = $output_path . 'schemapg.h'; -open my $schemapg, '>', $schemafile . $tmpext - or die "can't open $schemafile$tmpext: $!"; -my $descrfile = $output_path . 'postgres.description'; -open my $descr, '>', $descrfile . $tmpext - or die "can't open $descrfile$tmpext: $!"; -my $shdescrfile = $output_path . 'postgres.shdescription'; -open my $shdescr, '>', $shdescrfile . $tmpext - or die "can't open $shdescrfile$tmpext: $!"; - -# Read all the files into internal data structures. Not all catalogs -# will have a data file. +# Read all the files into internal data structures. my @catnames; my %catalogs; my %catalog_data; my @toast_decls; my @index_decls; -foreach my $header (@input_files) +my %oidcounts; + +foreach my $header (@ARGV) { $header =~ /(.+)\.h$/ or die "Input files need to be header files.\n"; @@ -95,51 +74,134 @@ $catalogs{$catname} = $catalog; } + # While checking for duplicated OIDs, we ignore the pg_class OID and + # rowtype OID of bootstrap catalogs, as those are expected to appear + # in the initial data for pg_class and pg_type. For regular catalogs, + # include these OIDs. (See also Catalog::FindAllOidsFromHeaders + # if you change this logic.) + if (!$catalog->{bootstrap}) + { + $oidcounts{ $catalog->{relation_oid} }++ + if ($catalog->{relation_oid}); + $oidcounts{ $catalog->{rowtype_oid} }++ + if ($catalog->{rowtype_oid}); + } + + # Not all catalogs have a data file. if (-e $datfile) { - $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0); + my $data = Catalog::ParseData($datfile, $schema, 0); + $catalog_data{$catname} = $data; + + # Check for duplicated OIDs while we're at it. + foreach my $row (@$data) + { + $oidcounts{ $row->{oid} }++ if defined $row->{oid}; + } } - foreach my $toast_decl (@{ $catalog->{toasting} }) + # If the header file contained toast or index info, build BKI + # commands for those, which we'll output later. + foreach my $toast (@{ $catalog->{toasting} }) { - push @toast_decls, $toast_decl; + push @toast_decls, + sprintf "declare toast %s %s on %s\n", + $toast->{toast_oid}, $toast->{toast_index_oid}, + $toast->{parent_table}; + $oidcounts{ $toast->{toast_oid} }++; + $oidcounts{ $toast->{toast_index_oid} }++; } - foreach my $index_decl (@{ $catalog->{indexing} }) + foreach my $index (@{ $catalog->{indexing} }) { - push @index_decls, $index_decl; + push @index_decls, + sprintf "declare %sindex %s %s %s\n", + $index->{is_unique} ? 'unique ' : '', + $index->{index_name}, $index->{index_oid}, + $index->{index_decl}; + $oidcounts{ $index->{index_oid} }++; } } +# Complain and exit if we found any duplicate OIDs. +# While duplicate OIDs would only cause a failure if they appear in +# the same catalog, our project policy is that manually assigned OIDs +# should be globally unique, to avoid confusion. +my $found = 0; +foreach my $oid (keys %oidcounts) +{ + next unless $oidcounts{$oid} > 1; + print STDERR "Duplicate OIDs detected:\n" if !$found; + print STDERR "$oid\n"; + $found++; +} +die "found $found duplicate OID(s) in catalog data\n" if $found; + + +# Oids not specified in the input files are automatically assigned, +# starting at FirstGenbkiObjectId, extending up to FirstBootstrapObjectId. +my $FirstGenbkiObjectId = + Catalog::FindDefinedSymbol('access/transam.h', $include_path, + 'FirstGenbkiObjectId'); +my $FirstBootstrapObjectId = + Catalog::FindDefinedSymbol('access/transam.h', $include_path, + 'FirstBootstrapObjectId'); +my $GenbkiNextOid = $FirstGenbkiObjectId; + + # Fetch some special data that we will substitute into the output file. # CAUTION: be wary about what symbols you substitute into the .bki file here! # It's okay to substitute things that are expected to be really constant # within a given Postgres release, such as fixed OIDs. Do not substitute # anything that could depend on platform or configuration. (The right place # to handle those sorts of things is in initdb.c's bootstrap_template1().) -my $BOOTSTRAP_SUPERUSERID = Catalog::FindDefinedSymbolFromData( - $catalog_data{pg_authid}, 'BOOTSTRAP_SUPERUSERID'); -my $PG_CATALOG_NAMESPACE = Catalog::FindDefinedSymbolFromData( - $catalog_data{pg_namespace}, 'PG_CATALOG_NAMESPACE'); +my $BOOTSTRAP_SUPERUSERID = + Catalog::FindDefinedSymbolFromData($catalog_data{pg_authid}, + 'BOOTSTRAP_SUPERUSERID'); +my $C_COLLATION_OID = + Catalog::FindDefinedSymbolFromData($catalog_data{pg_collation}, + 'C_COLLATION_OID'); +my $PG_CATALOG_NAMESPACE = + Catalog::FindDefinedSymbolFromData($catalog_data{pg_namespace}, + 'PG_CATALOG_NAMESPACE'); -# Build lookup tables for OID macro substitutions and for pg_attribute -# copies of pg_type values. +# Build lookup tables. -# index access method OID lookup +# access method OID lookup my %amoids; foreach my $row (@{ $catalog_data{pg_am} }) { $amoids{ $row->{amname} } = $row->{oid}; } +# class (relation) OID lookup (note this only covers bootstrap catalogs!) +my %classoids; +foreach my $row (@{ $catalog_data{pg_class} }) +{ + $classoids{ $row->{relname} } = $row->{oid}; +} + +# collation OID lookup +my %collationoids; +foreach my $row (@{ $catalog_data{pg_collation} }) +{ + $collationoids{ $row->{collname} } = $row->{oid}; +} + +# language OID lookup +my %langoids; +foreach my $row (@{ $catalog_data{pg_language} }) +{ + $langoids{ $row->{lanname} } = $row->{oid}; +} + # opclass OID lookup my %opcoids; foreach my $row (@{ $catalog_data{pg_opclass} }) { # There is no unique name, so we need to combine access method # and opclass name. - my $key = sprintf "%s/%s", - $row->{opcmethod}, $row->{opcname}; + my $key = sprintf "%s/%s", $row->{opcmethod}, $row->{opcname}; $opcoids{$key} = $row->{oid}; } @@ -160,8 +222,7 @@ { # There is no unique name, so we need to combine access method # and opfamily name. - my $key = sprintf "%s/%s", - $row->{opfmethod}, $row->{opfname}; + my $key = sprintf "%s/%s", $row->{opfmethod}, $row->{opfname}; $opfoids{$key} = $row->{oid}; } @@ -179,6 +240,7 @@ { $procoids{$prokey} = $row->{oid}; } + # Also generate an entry using proname(proargtypes). This is not quite # identical to regprocedure lookup because we don't worry much about # special SQL names for types etc; we just use the names in the source @@ -195,29 +257,119 @@ } } +# tablespace OID lookup +my %tablespaceoids; +foreach my $row (@{ $catalog_data{pg_tablespace} }) +{ + $tablespaceoids{ $row->{spcname} } = $row->{oid}; +} + +# text search configuration OID lookup +my %tsconfigoids; +foreach my $row (@{ $catalog_data{pg_ts_config} }) +{ + $tsconfigoids{ $row->{cfgname} } = $row->{oid}; +} + +# text search dictionary OID lookup +my %tsdictoids; +foreach my $row (@{ $catalog_data{pg_ts_dict} }) +{ + $tsdictoids{ $row->{dictname} } = $row->{oid}; +} + +# text search parser OID lookup +my %tsparseroids; +foreach my $row (@{ $catalog_data{pg_ts_parser} }) +{ + $tsparseroids{ $row->{prsname} } = $row->{oid}; +} + +# text search template OID lookup +my %tstemplateoids; +foreach my $row (@{ $catalog_data{pg_ts_template} }) +{ + $tstemplateoids{ $row->{tmplname} } = $row->{oid}; +} + # type lookups my %typeoids; my %types; foreach my $row (@{ $catalog_data{pg_type} }) { + # for OID macro substitutions $typeoids{ $row->{typname} } = $row->{oid}; + + # for pg_attribute copies of pg_type values $types{ $row->{typname} } = $row; } -# Map catalog name to OID lookup. +# Encoding identifier lookup. This uses the same replacement machinery +# as for OIDs, but we have to dig the values out of pg_wchar.h. +my %encids; + +my $encfile = $include_path . 'mb/pg_wchar.h'; +open(my $ef, '<', $encfile) || die "$encfile: $!"; + +# We're parsing an enum, so start with 0 and increment +# every time we find an enum member. +my $encid = 0; +my $collect_encodings = 0; +while (<$ef>) +{ + if (/typedef\s+enum\s+pg_enc/) + { + $collect_encodings = 1; + next; + } + + last if /_PG_LAST_ENCODING_/; + + if ($collect_encodings and /^\s+(PG_\w+)/) + { + $encids{$1} = $encid; + $encid++; + } +} + +close $ef; + +# Map lookup name to the corresponding hash table. my %lookup_kind = ( - pg_am => \%amoids, - pg_opclass => \%opcoids, - pg_operator => \%operoids, - pg_opfamily => \%opfoids, - pg_proc => \%procoids, - pg_type => \%typeoids -); + pg_am => \%amoids, + pg_class => \%classoids, + pg_collation => \%collationoids, + pg_language => \%langoids, + pg_opclass => \%opcoids, + pg_operator => \%operoids, + pg_opfamily => \%opfoids, + pg_proc => \%procoids, + pg_tablespace => \%tablespaceoids, + pg_ts_config => \%tsconfigoids, + pg_ts_dict => \%tsdictoids, + pg_ts_parser => \%tsparseroids, + pg_ts_template => \%tstemplateoids, + pg_type => \%typeoids, + encoding => \%encids); +# Open temp files +my $tmpext = ".tmp$$"; +my $bkifile = $output_path . 'postgres.bki'; +open my $bki, '>', $bkifile . $tmpext + or die "can't open $bkifile$tmpext: $!"; +my $schemafile = $output_path . 'schemapg.h'; +open my $schemapg, '>', $schemafile . $tmpext + or die "can't open $schemafile$tmpext: $!"; +my $descrfile = $output_path . 'postgres.description'; +open my $descr, '>', $descrfile . $tmpext + or die "can't open $descrfile$tmpext: $!"; +my $shdescrfile = $output_path . 'postgres.shdescription'; +open my $shdescr, '>', $shdescrfile . $tmpext + or die "can't open $shdescrfile$tmpext: $!"; + # Generate postgres.bki, postgres.description, postgres.shdescription, # and pg_*_d.h headers. -print "Generating BKI files and symbol definition headers...\n"; # version marker for .bki file print $bki "# PostgreSQL $major_version\n"; @@ -243,7 +395,7 @@ * %s_d.h * Macro definitions for %s * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -273,13 +425,13 @@ print $bki "create $catname $catalog->{relation_oid}" . $catalog->{shared_relation} . $catalog->{bootstrap} - . $catalog->{without_oids} . $catalog->{rowtype_oid_clause}; my $first = 1; print $bki "\n (\n"; my $schema = $catalog->{columns}; + my %attnames; my $attnum = 0; foreach my $column (@$schema) { @@ -287,6 +439,9 @@ my $attname = $column->{name}; my $atttype = $column->{type}; + # Build hash of column names for use later + $attnames{$attname} = 1; + # Emit column definitions if (!$first) { @@ -306,8 +461,7 @@ } # Emit Anum_* constants - print $def - sprintf("#define Anum_%s_%s %s\n", $catname, $attname, $attnum); + printf $def "#define Anum_%s_%s %s\n", $catname, $attname, $attnum; } print $bki "\n )\n"; @@ -338,12 +492,33 @@ { my %bki_values = %$row; + # Complain about unrecognized keys; they are presumably misspelled + foreach my $key (keys %bki_values) + { + next + if $key eq "oid_symbol" + || $key eq "array_type_oid" + || $key eq "descr" + || $key eq "autogenerated" + || $key eq "line_number"; + die sprintf "unrecognized field name \"%s\" in %s.dat line %s\n", + $key, $catname, $bki_values{line_number} + if (!exists($attnames{$key})); + } + # Perform required substitutions on fields foreach my $column (@$schema) { my $attname = $column->{name}; my $atttype = $column->{type}; + # Assign oid if oid column exists and no explicit assignment in row + if ($attname eq "oid" and not defined $bki_values{$attname}) + { + $bki_values{$attname} = $GenbkiNextOid; + $GenbkiNextOid++; + } + # Substitute constant values we acquired above. # (It's intentional that this can apply to parts of a field). $bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g; @@ -351,7 +526,7 @@ # Replace OID synonyms with OIDs per the appropriate lookup rule. # - # If the column type is oidvector or oid[], we have to replace + # If the column type is oidvector or _oid, we have to replace # each element of the array as per the lookup rule. if ($column->{lookup}) { @@ -365,27 +540,28 @@ if ($atttype eq 'oidvector') { @lookupnames = split /\s+/, $bki_values{$attname}; - @lookupoids = lookup_oids($lookup, $catname, - \%bki_values, @lookupnames); + @lookupoids = lookup_oids($lookup, $catname, \%bki_values, + @lookupnames); $bki_values{$attname} = join(' ', @lookupoids); } - elsif ($atttype eq 'oid[]') + elsif ($atttype eq '_oid') { if ($bki_values{$attname} ne '_null_') { $bki_values{$attname} =~ s/[{}]//g; @lookupnames = split /,/, $bki_values{$attname}; - @lookupoids = lookup_oids($lookup, $catname, - \%bki_values, @lookupnames); - $bki_values{$attname} = - sprintf "{%s}", join(',', @lookupoids); + @lookupoids = + lookup_oids($lookup, $catname, \%bki_values, + @lookupnames); + $bki_values{$attname} = sprintf "{%s}", + join(',', @lookupoids); } } else { $lookupnames[0] = $bki_values{$attname}; - @lookupoids = lookup_oids($lookup, $catname, - \%bki_values, @lookupnames); + @lookupoids = lookup_oids($lookup, $catname, \%bki_values, + @lookupnames); $bki_values{$attname} = $lookupoids[0]; } } @@ -428,7 +604,7 @@ } print $bki "close $catname\n"; - print $def sprintf("\n#endif\t\t\t\t\t\t\t/* %s_D_H */\n", uc $catname); + printf $def "\n#endif\t\t\t\t\t\t\t/* %s_D_H */\n", uc $catname; # Close and rename definition header close $def; @@ -449,6 +625,14 @@ print $bki $declaration; } +# last command in the BKI file: build the indexes declared above +print $bki "build indices\n"; + +# check that we didn't overrun available OIDs +die + "genbki OID counter reached $GenbkiNextOid, overrunning FirstBootstrapObjectId\n" + if $GenbkiNextOid > $FirstBootstrapObjectId; + # Now generate schemapg.h @@ -459,7 +643,7 @@ * schemapg.h * Schema_pg_xxx macros for use by relcache.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES @@ -521,8 +705,8 @@ sub gen_pg_attribute { my $table = $catalogs{$table_name}; - # Currently, all bootstrapped relations also need schemapg.h - # entries, so skip if the relation isn't to be in schemapg.h. + # Currently, all bootstrap catalogs also need schemapg.h + # entries, so skip if it isn't to be in schemapg.h. next if !$table->{schema_macro}; $schemapg_entries{$table_name} = []; @@ -548,7 +732,7 @@ sub gen_pg_attribute morph_row_for_schemapg(\%row, $schema); push @{ $schemapg_entries{$table_name} }, sprintf "{ %s }", - join(', ', grep { defined $_ } @row{@attnames}); + join(', ', grep { defined $_ } @row{@attnames}); } # Generate entries for system attributes. @@ -558,7 +742,6 @@ sub gen_pg_attribute $attnum = 0; my @SYS_ATTRS = ( { name => 'ctid', type => 'tid' }, - { name => 'oid', type => 'oid' }, { name => 'xmin', type => 'xid' }, { name => 'cmin', type => 'cid' }, { name => 'xmax', type => 'xid' }, @@ -572,16 +755,12 @@ sub gen_pg_attribute $row{attrelid} = $table->{relation_oid}; $row{attstattarget} = '0'; - # Omit the oid column if the catalog doesn't have them - next - if $table->{without_oids} - && $attr->{name} eq 'oid'; - morph_row_for_pgattr(\%row, $schema, $attr, 1); print_bki_insert(\%row, $schema); } } } + return; } # Given $pgattr_schema (the pg_attribute schema for a catalog sufficient for @@ -598,10 +777,6 @@ sub morph_row_for_pgattr $row->{attname} = $attname; - # Adjust type name for arrays: foo[] becomes _foo, so we can look it up in - # pg_type - $atttype = '_' . $1 if $atttype =~ /(.+)\[\]$/; - # Copy the type data from pg_type, and add some type-dependent items my $type = $types{$atttype}; @@ -613,7 +788,10 @@ sub morph_row_for_pgattr # set attndims if it's an array type $row->{attndims} = $type->{typcategory} eq 'A' ? '1' : '0'; - $row->{attcollation} = $type->{typcollation}; + + # collation-aware catalog columns must use C collation + $row->{attcollation} = + $type->{typcollation} ne '0' ? $C_COLLATION_OID : 0; if (defined $attr->{forcenotnull}) { @@ -631,11 +809,11 @@ sub morph_row_for_pgattr # compare DefineAttr in bootstrap.c. oidvector and # int2vector are also treated as not-nullable. $row->{attnotnull} = - $type->{typname} eq 'oidvector' ? 't' - : $type->{typname} eq 'int2vector' ? 't' - : $type->{typlen} eq 'NAMEDATALEN' ? 't' - : $type->{typlen} > 0 ? 't' - : 'f'; + $type->{typname} eq 'oidvector' ? 't' + : $type->{typname} eq 'int2vector' ? 't' + : $type->{typlen} eq 'NAMEDATALEN' ? 't' + : $type->{typlen} > 0 ? 't' + : 'f'; } else { @@ -643,18 +821,16 @@ sub morph_row_for_pgattr } Catalog::AddDefaultValues($row, $pgattr_schema, 'pg_attribute'); + return; } -# Write an entry to postgres.bki. Adding quotes here allows us to keep -# most double quotes out of the catalog data files for readability. See -# bootscanner.l for what tokens need quoting. +# Write an entry to postgres.bki. sub print_bki_insert { my $row = shift; my $schema = shift; my @bki_values; - my $oid = $row->{oid} ? "OID = $row->{oid} " : ''; foreach my $column (@$schema) { @@ -666,30 +842,24 @@ sub print_bki_insert # since that represents a NUL char in C code. $bki_value = '' if $bki_value eq '\0'; + # Handle single quotes by doubling them, and double quotes by + # converting them to octal escapes, because that's what the + # bootstrap scanner requires. We do not process backslashes + # specially; this allows escape-string-style backslash escapes + # to be used in catalog data. + $bki_value =~ s/'/''/g; + $bki_value =~ s/"/\\042/g; + + # Quote value if needed. We need not quote values that satisfy + # the "id" pattern in bootscanner.l, currently "[-A-Za-z0-9_]+". $bki_value = sprintf(qq'"%s"', $bki_value) - if $bki_value ne '_null_' - and $bki_value !~ /^"[^"]+"$/ - and ( length($bki_value) == 0 # Empty string - or $bki_value =~ /\s/ # Contains whitespace - - # To preserve historical formatting, operator names are - # always quoted. Likewise for values of multi-element types, - # even if they only contain a single element. - or $attname eq 'oprname' - or $atttype eq 'oidvector' - or $atttype eq 'int2vector' - or $atttype =~ /\[\]$/ - - # Quote strings that have non-word characters. We make - # exceptions for values that are octals or negative numbers, - # for the same historical reason as above. - or ( $bki_value =~ /\W/ - and $bki_value !~ /^\\\d{3}$/ - and $bki_value !~ /^-\d*$/)); + if length($bki_value) == 0 + or $bki_value =~ /[^-A-Za-z0-9_]/; push @bki_values, $bki_value; } - printf $bki "insert %s( %s )\n", $oid, join(' ', @bki_values); + printf $bki "insert ( %s )\n", join(' ', @bki_values); + return; } # Given a row reference, modify it so that it becomes a valid entry for @@ -724,7 +894,7 @@ sub morph_row_for_schemapg # don't change. elsif ($atttype eq 'bool') { - $row->{$attname} = 'true' if $row->{$attname} eq 't'; + $row->{$attname} = 'true' if $row->{$attname} eq 't'; $row->{$attname} = 'false' if $row->{$attname} eq 'f'; } @@ -732,11 +902,15 @@ sub morph_row_for_schemapg # Only the fixed-size portions of the descriptors are ever used. delete $row->{$attname} if $column->{is_varlen}; } + return; } # Perform OID lookups on an array of OID names. # If we don't have a unique value to substitute, warn and # leave the entry unchanged. +# (A warning seems sufficient because the bootstrap backend will reject +# non-numeric values anyway. So we might as well detect multiple problems +# within this genbki.pl run.) sub lookup_oids { my ($lookup, $catname, $bki_values, @lookupnames) = @_; @@ -752,9 +926,10 @@ sub lookup_oids else { push @lookupoids, $lookupname; - warn sprintf "unresolved OID reference \"%s\" in %s.dat line %s", - $lookupname, $catname, $bki_values->{line_number} - if $lookupname ne '-' and $lookupname ne '0'; + warn sprintf + "unresolved OID reference \"%s\" in %s.dat line %s\n", + $lookupname, $catname, $bki_values->{line_number} + if $lookupname ne '-' and $lookupname ne '0'; } } return @lookupoids; @@ -765,13 +940,13 @@ sub form_pg_type_symbol { my $typename = shift; - # Skip for rowtypes of bootstrap tables, since they have their + # Skip for rowtypes of bootstrap catalogs, since they have their # own naming convention defined elsewhere. return - if $typename eq 'pg_type' - or $typename eq 'pg_proc' - or $typename eq 'pg_attribute' - or $typename eq 'pg_class'; + if $typename eq 'pg_type' + or $typename eq 'pg_proc' + or $typename eq 'pg_attribute' + or $typename eq 'pg_class'; # Transform like so: # foo_bar -> FOO_BAROID @@ -785,17 +960,18 @@ sub form_pg_type_symbol sub usage { die <] [--include-path/-i ] header... Options: - -o output path + --output Output directory (default '.') --set-version PostgreSQL version number for initdb cross-check + --include-path Include path in source tree genbki.pl generates BKI files and symbol definition headers from specially formatted header files and .dat files. The BKI files are used to initialize the postgres template database. -Report bugs to . +Report bugs to . EOM } diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 8f329a6299b..b7bcdd9d0f7 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -3,7 +3,7 @@ * heap.c * code to create and destroy POSTGRES heap relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,9 +29,13 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" @@ -42,6 +46,7 @@ #include "catalog/index.h" #include "catalog/objectaccess.h" #include "catalog/partition.h" +#include "catalog/pg_am.h" #include "catalog/pg_attrdef.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -61,13 +66,13 @@ #include "executor/executor.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/var.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" #include "parser/parse_relation.h" +#include "parser/parsetree.h" +#include "partitioning/partdesc.h" #include "storage/lmgr.h" #include "storage/predicate.h" #include "storage/smgr.h" @@ -77,11 +82,11 @@ #include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" #include "utils/rel.h" #include "utils/ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* Potentially set by pg_upgrade_support functions */ @@ -89,36 +94,37 @@ Oid binary_upgrade_next_heap_pg_class_oid = InvalidOid; Oid binary_upgrade_next_toast_pg_class_oid = InvalidOid; static void AddNewRelationTuple(Relation pg_class_desc, - Relation new_rel_desc, - Oid new_rel_oid, - Oid new_type_oid, - Oid reloftype, - Oid relowner, - char relkind, - Datum relacl, - Datum reloptions); + Relation new_rel_desc, + Oid new_rel_oid, + Oid new_type_oid, + Oid reloftype, + Oid relowner, + char relkind, + TransactionId relfrozenxid, + TransactionId relminmxid, + Datum relacl, + Datum reloptions); static ObjectAddress AddNewRelationType(const char *typeName, - Oid typeNamespace, - Oid new_rel_oid, - char new_rel_kind, - Oid ownerid, - Oid new_row_type, - Oid new_array_type); + Oid typeNamespace, + Oid new_rel_oid, + char new_rel_kind, + Oid ownerid, + Oid new_row_type, + Oid new_array_type); static void RelationRemoveInheritance(Oid relid); -static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr, - bool is_validated, bool is_local, int inhcount, - bool is_no_inherit, bool is_internal); +static Oid StoreRelCheck(Relation rel, const char *ccname, Node *expr, + bool is_validated, bool is_local, int inhcount, + bool is_no_inherit, bool is_internal); static void StoreConstraints(Relation rel, List *cooked_constraints, - bool is_internal); + bool is_internal); static bool MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr, - bool allow_merge, bool is_local, - bool is_initially_valid, - bool is_no_inherit); + bool allow_merge, bool is_local, + bool is_initially_valid, + bool is_no_inherit); static void SetRelationNumChecks(Relation rel, int numchecks); static Node *cookConstraint(ParseState *pstate, - Node *raw_constraint, - char *relname); -static List *insert_ordered_unique_oid(List *list, Oid datum); + Node *raw_constraint, + char *relname); /* ---------------------------------------------------------------- @@ -143,40 +149,74 @@ static List *insert_ordered_unique_oid(List *list, Oid datum); * fixed-size portion of the structure anyway. */ -static FormData_pg_attribute a1 = { - 0, {"ctid"}, TIDOID, 0, sizeof(ItemPointerData), - SelfItemPointerAttributeNumber, 0, -1, -1, - false, 'p', 's', true, false, false, '\0', false, true, 0 -}; - -static FormData_pg_attribute a2 = { - 0, {"oid"}, OIDOID, 0, sizeof(Oid), - ObjectIdAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a1 = { + .attname = {"ctid"}, + .atttypid = TIDOID, + .attlen = sizeof(ItemPointerData), + .attnum = SelfItemPointerAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = false, + .attstorage = 'p', + .attalign = 's', + .attnotnull = true, + .attislocal = true, }; -static FormData_pg_attribute a3 = { - 0, {"xmin"}, XIDOID, 0, sizeof(TransactionId), - MinTransactionIdAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a2 = { + .attname = {"xmin"}, + .atttypid = XIDOID, + .attlen = sizeof(TransactionId), + .attnum = MinTransactionIdAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = true, + .attstorage = 'p', + .attalign = 'i', + .attnotnull = true, + .attislocal = true, }; -static FormData_pg_attribute a4 = { - 0, {"cmin"}, CIDOID, 0, sizeof(CommandId), - MinCommandIdAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a3 = { + .attname = {"cmin"}, + .atttypid = CIDOID, + .attlen = sizeof(CommandId), + .attnum = MinCommandIdAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = true, + .attstorage = 'p', + .attalign = 'i', + .attnotnull = true, + .attislocal = true, }; -static FormData_pg_attribute a5 = { - 0, {"xmax"}, XIDOID, 0, sizeof(TransactionId), - MaxTransactionIdAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a4 = { + .attname = {"xmax"}, + .atttypid = XIDOID, + .attlen = sizeof(TransactionId), + .attnum = MaxTransactionIdAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = true, + .attstorage = 'p', + .attalign = 'i', + .attnotnull = true, + .attislocal = true, }; -static FormData_pg_attribute a6 = { - 0, {"cmax"}, CIDOID, 0, sizeof(CommandId), - MaxCommandIdAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a5 = { + .attname = {"cmax"}, + .atttypid = CIDOID, + .attlen = sizeof(CommandId), + .attnum = MaxCommandIdAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = true, + .attstorage = 'p', + .attalign = 'i', + .attnotnull = true, + .attislocal = true, }; /* @@ -185,26 +225,32 @@ static FormData_pg_attribute a6 = { * table of a particular class/type. In any case table is still the word * used in SQL. */ -static FormData_pg_attribute a7 = { - 0, {"tableoid"}, OIDOID, 0, sizeof(Oid), - TableOidAttributeNumber, 0, -1, -1, - true, 'p', 'i', true, false, false, '\0', false, true, 0 +static const FormData_pg_attribute a6 = { + .attname = {"tableoid"}, + .atttypid = OIDOID, + .attlen = sizeof(Oid), + .attnum = TableOidAttributeNumber, + .attcacheoff = -1, + .atttypmod = -1, + .attbyval = true, + .attstorage = 'p', + .attalign = 'i', + .attnotnull = true, + .attislocal = true, }; -static const Form_pg_attribute SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7}; +static const FormData_pg_attribute *SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6}; /* * This function returns a Form_pg_attribute pointer for a system attribute. * Note that we elog if the presented attno is invalid, which would only * happen if there's a problem upstream. */ -Form_pg_attribute -SystemAttributeDefinition(AttrNumber attno, bool relhasoids) +const FormData_pg_attribute * +SystemAttributeDefinition(AttrNumber attno) { if (attno >= 0 || attno < -(int) lengthof(SysAtt)) elog(ERROR, "invalid system attribute number %d", attno); - if (attno == ObjectIdAttributeNumber && !relhasoids) - elog(ERROR, "invalid system attribute number %d", attno); return SysAtt[-attno - 1]; } @@ -212,20 +258,17 @@ SystemAttributeDefinition(AttrNumber attno, bool relhasoids) * If the given name is a system attribute name, return a Form_pg_attribute * pointer for a prototype definition. If not, return NULL. */ -Form_pg_attribute -SystemAttributeByName(const char *attname, bool relhasoids) +const FormData_pg_attribute * +SystemAttributeByName(const char *attname) { int j; for (j = 0; j < (int) lengthof(SysAtt); j++) { - Form_pg_attribute att = SysAtt[j]; + const FormData_pg_attribute *att = SysAtt[j]; - if (relhasoids || att->attnum != ObjectIdAttributeNumber) - { - if (strcmp(NameStr(att->attname), attname) == 0) - return att; - } + if (strcmp(NameStr(att->attname), attname) == 0) + return att; } return NULL; @@ -254,12 +297,15 @@ heap_create(const char *relname, Oid reltablespace, Oid relid, Oid relfilenode, + Oid accessmtd, TupleDesc tupDesc, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, - bool allow_system_table_mods) + bool allow_system_table_mods, + TransactionId *relfrozenxid, + MultiXactId *relminmxid) { bool create_storage; Relation rel; @@ -277,7 +323,7 @@ heap_create(const char *relname, * user defined relation, not a system one. */ if (!allow_system_table_mods && - ((IsSystemNamespace(relnamespace) && relkind != RELKIND_INDEX) || + ((IsCatalogNamespace(relnamespace) && relkind != RELKIND_INDEX) || IsToastNamespace(relnamespace)) && IsNormalProcessingMode()) ereport(ERROR, @@ -286,27 +332,28 @@ heap_create(const char *relname, get_namespace_name(relnamespace), relname), errdetail("System catalog modifications are currently disallowed."))); - /* - * Decide if we need storage or not, and handle a couple other special - * cases for particular relkinds. - */ + *relfrozenxid = InvalidTransactionId; + *relminmxid = InvalidMultiXactId; + + /* Handle reltablespace for specific relkinds. */ switch (relkind) { case RELKIND_VIEW: case RELKIND_COMPOSITE_TYPE: case RELKIND_FOREIGN_TABLE: - case RELKIND_PARTITIONED_TABLE: - case RELKIND_PARTITIONED_INDEX: - create_storage = false; /* * Force reltablespace to zero if the relation has no physical * storage. This is mainly just for cleanliness' sake. + * + * Partitioned tables and indexes don't have physical storage + * either, but we want to keep their tablespace settings so that + * their children can inherit it. */ reltablespace = InvalidOid; break; + case RELKIND_SEQUENCE: - create_storage = true; /* * Force reltablespace to zero for sequences, since we don't @@ -315,19 +362,21 @@ heap_create(const char *relname, reltablespace = InvalidOid; break; default: - create_storage = true; break; } /* - * Unless otherwise requested, the physical ID (relfilenode) is initially - * the same as the logical ID (OID). When the caller did specify a - * relfilenode, it already exists; do not attempt to create it. + * Decide whether to create storage. If caller passed a valid relfilenode, + * storage is already created, so don't do it here. Also don't create it + * for relkinds without physical storage. */ - if (OidIsValid(relfilenode)) + if (!RELKIND_HAS_STORAGE(relkind) || OidIsValid(relfilenode)) create_storage = false; else + { + create_storage = true; relfilenode = relid; + } /* * Never allow a pg_class entry to explicitly specify the database's @@ -348,6 +397,7 @@ heap_create(const char *relname, relnamespace, tupDesc, relid, + accessmtd, relfilenode, reltablespace, shared_relation, @@ -358,13 +408,37 @@ heap_create(const char *relname, /* * Have the storage manager create the relation's disk file, if needed. * - * We only create the main fork here, other forks will be created on - * demand. + * For relations the callback creates both the main and the init fork, for + * indexes only the main fork is created. The other forks will be created + * on demand. */ if (create_storage) { RelationOpenSmgr(rel); - RelationCreateStorage(rel->rd_node, relpersistence); + + switch (rel->rd_rel->relkind) + { + case RELKIND_VIEW: + case RELKIND_COMPOSITE_TYPE: + case RELKIND_FOREIGN_TABLE: + case RELKIND_PARTITIONED_TABLE: + case RELKIND_PARTITIONED_INDEX: + Assert(false); + break; + + case RELKIND_INDEX: + case RELKIND_SEQUENCE: + RelationCreateStorage(rel->rd_node, relpersistence); + break; + + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: + table_relation_set_new_filenode(rel, &rel->rd_node, + relpersistence, + relfrozenxid, relminmxid); + break; + } } return rel; @@ -407,11 +481,14 @@ heap_create(const char *relname, * this is used to make certain the tuple descriptor contains a * valid set of attribute names and datatypes. a problem simply * generates ereport(ERROR) which aborts the current transaction. + * + * relkind is the relkind of the relation to be created. + * flags controls which datatypes are allowed, cf CheckAttributeType. * -------------------------------- */ void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, - bool allow_system_table_mods) + int flags) { int i; int j; @@ -436,8 +513,7 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, { Form_pg_attribute attr = TupleDescAttr(tupdesc, i); - if (SystemAttributeByName(NameStr(attr->attname), - tupdesc->tdhasoid) != NULL) + if (SystemAttributeByName(NameStr(attr->attname)) != NULL) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_COLUMN), errmsg("column name \"%s\" conflicts with a system column name", @@ -470,7 +546,7 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, TupleDescAttr(tupdesc, i)->atttypid, TupleDescAttr(tupdesc, i)->attcollation, NIL, /* assume we're creating a new rowtype */ - allow_system_table_mods); + flags); } } @@ -487,13 +563,22 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, * containing_rowtypes. When checking a to-be-created rowtype, it's * sufficient to pass NIL, because there could not be any recursive reference * to a not-yet-existing rowtype. + * + * flags is a bitmask controlling which datatypes we allow. For the most + * part, pseudo-types are disallowed as attribute types, but there are some + * exceptions: ANYARRAYOID, RECORDOID, and RECORDARRAYOID can be allowed + * in some cases. (This works because values of those type classes are + * self-identifying to some extent. However, RECORDOID and RECORDARRAYOID + * are reliably identifiable only within a session, since the identity info + * may use a typmod that is only locally assigned. The caller is expected + * to know whether these cases are safe.) * -------------------------------- */ void CheckAttributeType(const char *attname, Oid atttypid, Oid attcollation, List *containing_rowtypes, - bool allow_system_table_mods) + int flags) { char att_typtype = get_typtype(atttypid); Oid att_typelem; @@ -501,12 +586,18 @@ CheckAttributeType(const char *attname, if (att_typtype == TYPTYPE_PSEUDO) { /* - * Refuse any attempt to create a pseudo-type column, except for a - * special hack for pg_statistic: allow ANYARRAY when modifying system - * catalogs (this allows creating pg_statistic and cloning it during - * VACUUM FULL) + * We disallow pseudo-type columns, with the exception of ANYARRAY, + * RECORD, and RECORD[] when the caller says that those are OK. + * + * We don't need to worry about recursive containment for RECORD and + * RECORD[] because (a) no named composite type should be allowed to + * contain those, and (b) two "anonymous" record types couldn't be + * considered to be the same type, so infinite recursion isn't + * possible. */ - if (atttypid != ANYARRAYOID || !allow_system_table_mods) + if (!((atttypid == ANYARRAYOID && (flags & CHKATYPE_ANYARRAY)) || + (atttypid == RECORDOID && (flags & CHKATYPE_ANYRECORD)) || + (atttypid == RECORDARRAYOID && (flags & CHKATYPE_ANYRECORD)))) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("column \"%s\" has pseudo-type %s", @@ -519,7 +610,7 @@ CheckAttributeType(const char *attname, */ CheckAttributeType(attname, getBaseType(atttypid), attcollation, containing_rowtypes, - allow_system_table_mods); + flags); } else if (att_typtype == TYPTYPE_COMPOSITE) { @@ -542,7 +633,7 @@ CheckAttributeType(const char *attname, errmsg("composite type %s cannot be made a member of itself", format_type_be(atttypid)))); - containing_rowtypes = lcons_oid(atttypid, containing_rowtypes); + containing_rowtypes = lappend_oid(containing_rowtypes, atttypid); relation = relation_open(get_typ_typrelid(atttypid), AccessShareLock); @@ -557,12 +648,12 @@ CheckAttributeType(const char *attname, CheckAttributeType(NameStr(attr->attname), attr->atttypid, attr->attcollation, containing_rowtypes, - allow_system_table_mods); + flags); } relation_close(relation, AccessShareLock); - containing_rowtypes = list_delete_first(containing_rowtypes); + containing_rowtypes = list_delete_last(containing_rowtypes); } else if (OidIsValid((att_typelem = get_element_type(atttypid)))) { @@ -571,7 +662,7 @@ CheckAttributeType(const char *attname, */ CheckAttributeType(attname, att_typelem, attcollation, containing_rowtypes, - allow_system_table_mods); + flags); } /* @@ -591,8 +682,8 @@ CheckAttributeType(const char *attname, * Construct and insert a new tuple in pg_attribute. * * Caller has already opened and locked pg_attribute. new_attribute is the - * attribute to insert (but we ignore attacl and attoptions, which are always - * initialized to NULL). + * attribute to insert. attcacheoff is always initialized to -1, attacl and + * attoptions are always initialized to NULL. * * indstate is the index state for CatalogTupleInsertWithInfo. It can be * passed as NULL, in which case we'll fetch the necessary info. (Don't do @@ -619,7 +710,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel, values[Anum_pg_attribute_attlen - 1] = Int16GetDatum(new_attribute->attlen); values[Anum_pg_attribute_attnum - 1] = Int16GetDatum(new_attribute->attnum); values[Anum_pg_attribute_attndims - 1] = Int32GetDatum(new_attribute->attndims); - values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(new_attribute->attcacheoff); + values[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1); values[Anum_pg_attribute_atttypmod - 1] = Int32GetDatum(new_attribute->atttypmod); values[Anum_pg_attribute_attbyval - 1] = BoolGetDatum(new_attribute->attbyval); values[Anum_pg_attribute_attstorage - 1] = CharGetDatum(new_attribute->attstorage); @@ -628,6 +719,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel, values[Anum_pg_attribute_atthasdef - 1] = BoolGetDatum(new_attribute->atthasdef); values[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(new_attribute->atthasmissing); values[Anum_pg_attribute_attidentity - 1] = CharGetDatum(new_attribute->attidentity); + values[Anum_pg_attribute_attgenerated - 1] = CharGetDatum(new_attribute->attgenerated); values[Anum_pg_attribute_attisdropped - 1] = BoolGetDatum(new_attribute->attisdropped); values[Anum_pg_attribute_attislocal - 1] = BoolGetDatum(new_attribute->attislocal); values[Anum_pg_attribute_attinhcount - 1] = Int32GetDatum(new_attribute->attinhcount); @@ -660,9 +752,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel, static void AddNewAttributeTuples(Oid new_rel_oid, TupleDesc tupdesc, - char relkind, - bool oidislocal, - int oidinhcount) + char relkind) { Form_pg_attribute attr; int i; @@ -675,7 +765,7 @@ AddNewAttributeTuples(Oid new_rel_oid, /* * open pg_attribute and its indexes. */ - rel = heap_open(AttributeRelationId, RowExclusiveLock); + rel = table_open(AttributeRelationId, RowExclusiveLock); indstate = CatalogOpenIndexes(rel); @@ -688,9 +778,8 @@ AddNewAttributeTuples(Oid new_rel_oid, attr = TupleDescAttr(tupdesc, i); /* Fill in the correct relation OID */ attr->attrelid = new_rel_oid; - /* Make sure these are OK, too */ + /* Make sure this is OK, too */ attr->attstattarget = -1; - attr->attcacheoff = -1; InsertPgAttributeTuple(rel, attr, indstate); @@ -725,23 +814,11 @@ AddNewAttributeTuples(Oid new_rel_oid, { FormData_pg_attribute attStruct; - /* skip OID where appropriate */ - if (!tupdesc->tdhasoid && - SysAtt[i]->attnum == ObjectIdAttributeNumber) - continue; - - memcpy(&attStruct, (char *) SysAtt[i], sizeof(FormData_pg_attribute)); + memcpy(&attStruct, SysAtt[i], sizeof(FormData_pg_attribute)); /* Fill in the correct relation OID in the copied tuple */ attStruct.attrelid = new_rel_oid; - /* Fill in correct inheritance info for the OID column */ - if (attStruct.attnum == ObjectIdAttributeNumber) - { - attStruct.attislocal = oidislocal; - attStruct.attinhcount = oidinhcount; - } - InsertPgAttributeTuple(rel, &attStruct, indstate); } } @@ -751,7 +828,7 @@ AddNewAttributeTuples(Oid new_rel_oid, */ CatalogCloseIndexes(indstate); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* -------------------------------- @@ -783,6 +860,7 @@ InsertPgClassTuple(Relation pg_class_desc, memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid); values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname); values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace); values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype); @@ -801,7 +879,6 @@ InsertPgClassTuple(Relation pg_class_desc, values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind); values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts); values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks); - values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids); values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules); values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers); values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity); @@ -827,12 +904,6 @@ InsertPgClassTuple(Relation pg_class_desc, tup = heap_form_tuple(RelationGetDescr(pg_class_desc), values, nulls); - /* - * The new tuple must have the oid already chosen for the rel. Sure would - * be embarrassing to do this sort of thing in polite company. - */ - HeapTupleSetOid(tup, new_rel_oid); - /* finally insert the new tuple, update the indexes, and clean up */ CatalogTupleInsert(pg_class_desc, tup); @@ -854,6 +925,8 @@ AddNewRelationTuple(Relation pg_class_desc, Oid reloftype, Oid relowner, char relkind, + TransactionId relfrozenxid, + TransactionId relminmxid, Datum relacl, Datum reloptions) { @@ -890,40 +963,8 @@ AddNewRelationTuple(Relation pg_class_desc, break; } - /* Initialize relfrozenxid and relminmxid */ - if (relkind == RELKIND_RELATION || - relkind == RELKIND_MATVIEW || - relkind == RELKIND_TOASTVALUE) - { - /* - * Initialize to the minimum XID that could put tuples in the table. - * We know that no xacts older than RecentXmin are still running, so - * that will do. - */ - new_rel_reltup->relfrozenxid = RecentXmin; - - /* - * Similarly, initialize the minimum Multixact to the first value that - * could possibly be stored in tuples in the table. Running - * transactions could reuse values from their local cache, so we are - * careful to consider all currently running multis. - * - * XXX this could be refined further, but is it worth the hassle? - */ - new_rel_reltup->relminmxid = GetOldestMultiXactId(); - } - else - { - /* - * Other relation types will not contain XIDs, so set relfrozenxid to - * InvalidTransactionId. (Note: a sequence does contain a tuple, but - * we force its xmin to be FrozenTransactionId always; see - * commands/sequence.c.) - */ - new_rel_reltup->relfrozenxid = InvalidTransactionId; - new_rel_reltup->relminmxid = InvalidMultiXactId; - } - + new_rel_reltup->relfrozenxid = relfrozenxid; + new_rel_reltup->relminmxid = relminmxid; new_rel_reltup->relowner = relowner; new_rel_reltup->reltype = new_type_oid; new_rel_reltup->reloftype = reloftype; @@ -1007,8 +1048,6 @@ AddNewRelationType(const char *typeName, * relpersistence: rel's persistence status (permanent, temp, or unlogged) * shared_relation: true if it's to be a shared relation * mapped_relation: true if the relation will use the relfilenode map - * oidislocal: true if oid column (if any) should be marked attislocal - * oidinhcount: attinhcount to assign to oid column (if any) * oncommit: ON COMMIT marking (only relevant if it's a temp table) * reloptions: reloptions in Datum form, or (Datum) 0 if none * use_user_acl: true if should look for user-defined default permissions; @@ -1030,14 +1069,13 @@ heap_create_with_catalog(const char *relname, Oid reltypeid, Oid reloftypeid, Oid ownerid, + Oid accessmtd, TupleDesc tupdesc, List *cooked_constraints, char relkind, char relpersistence, bool shared_relation, bool mapped_relation, - bool oidislocal, - int oidinhcount, OnCommitAction oncommit, Datum reloptions, bool use_user_acl, @@ -1054,15 +1092,23 @@ heap_create_with_catalog(const char *relname, Oid new_type_oid; ObjectAddress new_type_addr; Oid new_array_oid = InvalidOid; + TransactionId relfrozenxid; + MultiXactId relminmxid; - pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); + pg_class_desc = table_open(RelationRelationId, RowExclusiveLock); /* * sanity checks */ Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode()); - CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods); + /* + * Validate proposed tupdesc for the desired relkind. If + * allow_system_table_mods is on, allow ANYARRAY to be used; this is a + * hack to allow creating pg_statistic and cloning it during VACUUM FULL. + */ + CheckAttributeNamesTypes(tupdesc, relkind, + allow_system_table_mods ? CHKATYPE_ANYARRAY : 0); /* * This would fail later on anyway, if the relation already exists. But @@ -1080,7 +1126,7 @@ heap_create_with_catalog(const char *relname, * autogenerated array, we can rename it out of the way; otherwise we can * at least give a good error message. */ - old_type_oid = GetSysCacheOid2(TYPENAMENSP, + old_type_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(relname), ObjectIdGetDatum(relnamespace)); if (OidIsValid(old_type_oid)) @@ -1173,12 +1219,15 @@ heap_create_with_catalog(const char *relname, reltablespace, relid, InvalidOid, + accessmtd, tupdesc, relkind, relpersistence, shared_relation, mapped_relation, - allow_system_table_mods); + allow_system_table_mods, + &relfrozenxid, + &relminmxid); Assert(relid == RelationGetRelid(new_rel_desc)); @@ -1277,14 +1326,15 @@ heap_create_with_catalog(const char *relname, reloftypeid, ownerid, relkind, + relfrozenxid, + relminmxid, PointerGetDatum(relacl), reloptions); /* * now add tuples to pg_attribute for the attributes in our new relation. */ - AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind, - oidislocal, oidinhcount); + AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind); /* * Make a dependency link to force the relation to be deleted if its @@ -1311,6 +1361,7 @@ heap_create_with_catalog(const char *relname, myself.classId = RelationRelationId; myself.objectId = relid; myself.objectSubId = 0; + referenced.classId = NamespaceRelationId; referenced.objectId = relnamespace; referenced.objectSubId = 0; @@ -1318,6 +1369,8 @@ heap_create_with_catalog(const char *relname, recordDependencyOnOwner(RelationRelationId, relid, ownerid); + recordDependencyOnNewAcl(RelationRelationId, relid, 0, ownerid, relacl); + recordDependencyOnCurrentExtension(&myself, false); if (reloftypeid) @@ -1328,16 +1381,20 @@ heap_create_with_catalog(const char *relname, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (relacl != NULL) + /* + * Make a dependency link to force the relation to be deleted if its + * access method is. Do this only for relation and materialized views. + * + * No need to add an explicit dependency for the toast table, as the + * main table depends on it. + */ + if (relkind == RELKIND_RELATION || + relkind == RELKIND_MATVIEW) { - int nnewmembers; - Oid *newmembers; - - nnewmembers = aclmembers(relacl, &newmembers); - updateAclDependencies(RelationRelationId, relid, 0, - ownerid, - 0, NULL, - nnewmembers, newmembers); + referenced.classId = AccessMethodRelationId; + referenced.objectId = accessmtd; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } } @@ -1359,45 +1416,16 @@ heap_create_with_catalog(const char *relname, if (oncommit != ONCOMMIT_NOOP) register_on_commit_action(relid, oncommit); - /* - * Unlogged objects need an init fork, except for partitioned tables which - * have no storage at all. - */ - if (relpersistence == RELPERSISTENCE_UNLOGGED && - relkind != RELKIND_PARTITIONED_TABLE) - heap_create_init_fork(new_rel_desc); - /* * ok, the relation has been cataloged, so close our relations and return * the OID of the newly created relation. */ - heap_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ - heap_close(pg_class_desc, RowExclusiveLock); + table_close(new_rel_desc, NoLock); /* do not unlock till end of xact */ + table_close(pg_class_desc, RowExclusiveLock); return relid; } -/* - * Set up an init fork for an unlogged table so that it can be correctly - * reinitialized on restart. An immediate sync is required even if the - * page has been logged, because the write did not go through - * shared_buffers and therefore a concurrent checkpoint may have moved - * the redo pointer past our xlog record. Recovery may as well remove it - * while replaying, for example, XLOG_DBASE_CREATE or XLOG_TBLSPC_CREATE - * record. Therefore, logging is necessary even if wal_level=minimal. - */ -void -heap_create_init_fork(Relation rel) -{ - Assert(rel->rd_rel->relkind == RELKIND_RELATION || - rel->rd_rel->relkind == RELKIND_MATVIEW || - rel->rd_rel->relkind == RELKIND_TOASTVALUE); - RelationOpenSmgr(rel); - smgrcreate(rel->rd_smgr, INIT_FORKNUM, false); - log_smgrcreate(&rel->rd_smgr->smgr_rnode.node, INIT_FORKNUM); - smgrimmedsync(rel->rd_smgr, INIT_FORKNUM); -} - /* * RelationRemoveInheritance * @@ -1415,7 +1443,7 @@ RelationRemoveInheritance(Oid relid) ScanKeyData key; HeapTuple tuple; - catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock); + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); ScanKeyInit(&key, Anum_pg_inherits_inhrelid, @@ -1429,7 +1457,7 @@ RelationRemoveInheritance(Oid relid) CatalogTupleDelete(catalogRelation, &tuple->t_self); systable_endscan(scan); - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); } /* @@ -1447,7 +1475,7 @@ DeleteRelationTuple(Oid relid) HeapTuple tup; /* Grab an appropriate lock on the pg_class relation */ - pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock); + pg_class_desc = table_open(RelationRelationId, RowExclusiveLock); tup = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tup)) @@ -1458,7 +1486,7 @@ DeleteRelationTuple(Oid relid) ReleaseSysCache(tup); - heap_close(pg_class_desc, RowExclusiveLock); + table_close(pg_class_desc, RowExclusiveLock); } /* @@ -1478,7 +1506,7 @@ DeleteAttributeTuples(Oid relid) HeapTuple atttup; /* Grab an appropriate lock on the pg_attribute relation */ - attrel = heap_open(AttributeRelationId, RowExclusiveLock); + attrel = table_open(AttributeRelationId, RowExclusiveLock); /* Use the index to scan only attributes of the target relation */ ScanKeyInit(&key[0], @@ -1495,7 +1523,7 @@ DeleteAttributeTuples(Oid relid) /* Clean up after the scan */ systable_endscan(scan); - heap_close(attrel, RowExclusiveLock); + table_close(attrel, RowExclusiveLock); } /* @@ -1515,7 +1543,7 @@ DeleteSystemAttributeTuples(Oid relid) HeapTuple atttup; /* Grab an appropriate lock on the pg_attribute relation */ - attrel = heap_open(AttributeRelationId, RowExclusiveLock); + attrel = table_open(AttributeRelationId, RowExclusiveLock); /* Use the index to scan only system attributes of the target relation */ ScanKeyInit(&key[0], @@ -1536,7 +1564,7 @@ DeleteSystemAttributeTuples(Oid relid) /* Clean up after the scan */ systable_endscan(scan); - heap_close(attrel, RowExclusiveLock); + table_close(attrel, RowExclusiveLock); } /* @@ -1559,13 +1587,12 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) /* * Grab an exclusive lock on the target table, which we will NOT release * until end of transaction. (In the simple case where we are directly - * dropping this column, AlterTableDropColumn already did this ... but - * when cascading from a drop of some other object, we may not have any - * lock.) + * dropping this column, ATExecDropColumn already did this ... but when + * cascading from a drop of some other object, we may not have any lock.) */ rel = relation_open(relid, AccessExclusiveLock); - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy2(ATTNUM, ObjectIdGetDatum(relid), @@ -1605,6 +1632,9 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) /* We don't want to keep stats for it anymore */ attStruct->attstattarget = 0; + /* Unset this so no one tries to look up the generation expression */ + attStruct->attgenerated = '\0'; + /* * Change the column name to something that isn't likely to conflict */ @@ -1612,6 +1642,29 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) "........pg.dropped.%d........", attnum); namestrcpy(&(attStruct->attname), newattname); + /* clear the missing value if any */ + if (attStruct->atthasmissing) + { + Datum valuesAtt[Natts_pg_attribute]; + bool nullsAtt[Natts_pg_attribute]; + bool replacesAtt[Natts_pg_attribute]; + + /* update the tuple - set atthasmissing and attmissingval */ + MemSet(valuesAtt, 0, sizeof(valuesAtt)); + MemSet(nullsAtt, false, sizeof(nullsAtt)); + MemSet(replacesAtt, false, sizeof(replacesAtt)); + + valuesAtt[Anum_pg_attribute_atthasmissing - 1] = + BoolGetDatum(false); + replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true; + valuesAtt[Anum_pg_attribute_attmissingval - 1] = (Datum) 0; + nullsAtt[Anum_pg_attribute_attmissingval - 1] = true; + replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; + + tuple = heap_modify_tuple(tuple, RelationGetDescr(attr_rel), + valuesAtt, nullsAtt, replacesAtt); + } + CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); } @@ -1621,7 +1674,7 @@ RemoveAttributeById(Oid relid, AttrNumber attnum) * backends of the change. */ - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); if (attnum > 0) RemoveStatistics(relid, attnum); @@ -1645,7 +1698,7 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, HeapTuple tuple; bool found = false; - attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock); + attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock); ScanKeyInit(&scankeys[0], Anum_pg_attrdef_adrelid, @@ -1663,9 +1716,10 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, while (HeapTupleIsValid(tuple = systable_getnext(scan))) { ObjectAddress object; + Form_pg_attrdef attrtuple = (Form_pg_attrdef) GETSTRUCT(tuple); object.classId = AttrDefaultRelationId; - object.objectId = HeapTupleGetOid(tuple); + object.objectId = attrtuple->oid; object.objectSubId = 0; performDeletion(&object, behavior, @@ -1675,7 +1729,7 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum, } systable_endscan(scan); - heap_close(attrdef_rel, RowExclusiveLock); + table_close(attrdef_rel, RowExclusiveLock); if (complain && !found) elog(ERROR, "could not find attrdef tuple for relation %u attnum %d", @@ -1702,11 +1756,11 @@ RemoveAttrDefaultById(Oid attrdefId) AttrNumber myattnum; /* Grab an appropriate lock on the pg_attrdef relation */ - attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock); + attrdef_rel = table_open(AttrDefaultRelationId, RowExclusiveLock); /* Find the pg_attrdef tuple */ ScanKeyInit(&scankeys[0], - ObjectIdAttributeNumber, + Anum_pg_attrdef_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(attrdefId)); @@ -1727,10 +1781,10 @@ RemoveAttrDefaultById(Oid attrdefId) CatalogTupleDelete(attrdef_rel, &tuple->t_self); systable_endscan(scan); - heap_close(attrdef_rel, RowExclusiveLock); + table_close(attrdef_rel, RowExclusiveLock); /* Fix the pg_attribute row */ - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy2(ATTNUM, ObjectIdGetDatum(myrelid), @@ -1747,7 +1801,7 @@ RemoveAttrDefaultById(Oid attrdefId) * Our update of the pg_attribute row will force a relcache rebuild, so * there's nothing else to do here. */ - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); /* Keep lock on attribute's rel until end of xact */ relation_close(myrel, NoLock); @@ -1827,7 +1881,7 @@ heap_drop_with_catalog(Oid relid) Relation rel; HeapTuple tuple; - rel = heap_open(ForeignTableRelationId, RowExclusiveLock); + rel = table_open(ForeignTableRelationId, RowExclusiveLock); tuple = SearchSysCache1(FOREIGNTABLEREL, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) @@ -1836,7 +1890,7 @@ heap_drop_with_catalog(Oid relid) CatalogTupleDelete(rel, &tuple->t_self); ReleaseSysCache(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -1965,7 +2019,7 @@ RelationClearMissing(Relation rel) /* Get a lock on pg_attribute */ - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); /* process each non-system attribute, including any dropped columns */ for (attnum = 1; attnum <= natts; attnum++) @@ -1997,7 +2051,64 @@ RelationClearMissing(Relation rel) * Our update of the pg_attribute rows will force a relcache rebuild, so * there's nothing else to do here. */ - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); +} + +/* + * SetAttrMissing + * + * Set the missing value of a single attribute. This should only be used by + * binary upgrade. Takes an AccessExclusive lock on the relation owning the + * attribute. + */ +void +SetAttrMissing(Oid relid, char *attname, char *value) +{ + Datum valuesAtt[Natts_pg_attribute]; + bool nullsAtt[Natts_pg_attribute]; + bool replacesAtt[Natts_pg_attribute]; + Datum missingval; + Form_pg_attribute attStruct; + Relation attrrel, + tablerel; + HeapTuple atttup, + newtup; + + /* lock the table the attribute belongs to */ + tablerel = table_open(relid, AccessExclusiveLock); + + /* Lock the attribute row and get the data */ + attrrel = table_open(AttributeRelationId, RowExclusiveLock); + atttup = SearchSysCacheAttName(relid, attname); + if (!HeapTupleIsValid(atttup)) + elog(ERROR, "cache lookup failed for attribute %s of relation %u", + attname, relid); + attStruct = (Form_pg_attribute) GETSTRUCT(atttup); + + /* get an array value from the value string */ + missingval = OidFunctionCall3(F_ARRAY_IN, + CStringGetDatum(value), + ObjectIdGetDatum(attStruct->atttypid), + Int32GetDatum(attStruct->atttypmod)); + + /* update the tuple - set atthasmissing and attmissingval */ + MemSet(valuesAtt, 0, sizeof(valuesAtt)); + MemSet(nullsAtt, false, sizeof(nullsAtt)); + MemSet(replacesAtt, false, sizeof(replacesAtt)); + + valuesAtt[Anum_pg_attribute_atthasmissing - 1] = BoolGetDatum(true); + replacesAtt[Anum_pg_attribute_atthasmissing - 1] = true; + valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval; + replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; + + newtup = heap_modify_tuple(atttup, RelationGetDescr(attrrel), + valuesAtt, nullsAtt, replacesAtt); + CatalogTupleUpdate(attrrel, &newtup->t_self, newtup); + + /* clean up */ + ReleaseSysCache(atttup); + table_close(attrrel, RowExclusiveLock); + table_close(tablerel, AccessExclusiveLock); } /* @@ -2016,7 +2127,6 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, Node *expr, bool is_internal, bool add_column_mode) { char *adbin; - char *adsrc; Relation adrel; HeapTuple tuple; Datum values[4]; @@ -2024,54 +2134,47 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, Relation attrrel; HeapTuple atttup; Form_pg_attribute attStruct; + char attgenerated; Oid attrdefOid; ObjectAddress colobject, defobject; + adrel = table_open(AttrDefaultRelationId, RowExclusiveLock); + /* * Flatten expression to string form for storage. */ adbin = nodeToString(expr); - /* - * Also deparse it to form the mostly-obsolete adsrc field. - */ - adsrc = deparse_expression(expr, - deparse_context_for(RelationGetRelationName(rel), - RelationGetRelid(rel)), - false, false); - /* * Make the pg_attrdef entry. */ + attrdefOid = GetNewOidWithIndex(adrel, AttrDefaultOidIndexId, + Anum_pg_attrdef_oid); + values[Anum_pg_attrdef_oid - 1] = ObjectIdGetDatum(attrdefOid); values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel); values[Anum_pg_attrdef_adnum - 1] = attnum; values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin); - values[Anum_pg_attrdef_adsrc - 1] = CStringGetTextDatum(adsrc); - - adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock); tuple = heap_form_tuple(adrel->rd_att, values, nulls); - attrdefOid = CatalogTupleInsert(adrel, tuple); + CatalogTupleInsert(adrel, tuple); defobject.classId = AttrDefaultRelationId; defobject.objectId = attrdefOid; defobject.objectSubId = 0; - heap_close(adrel, RowExclusiveLock); + table_close(adrel, RowExclusiveLock); /* now can free some of the stuff allocated above */ pfree(DatumGetPointer(values[Anum_pg_attrdef_adbin - 1])); - pfree(DatumGetPointer(values[Anum_pg_attrdef_adsrc - 1])); heap_freetuple(tuple); pfree(adbin); - pfree(adsrc); /* * Update the pg_attribute entry for the column to show that a default * exists. */ - attrrel = heap_open(AttributeRelationId, RowExclusiveLock); + attrrel = table_open(AttributeRelationId, RowExclusiveLock); atttup = SearchSysCacheCopy2(ATTNUM, ObjectIdGetDatum(RelationGetRelid(rel)), Int16GetDatum(attnum)); @@ -2079,6 +2182,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, elog(ERROR, "cache lookup failed for attribute %d of relation %u", attnum, RelationGetRelid(rel)); attStruct = (Form_pg_attribute) GETSTRUCT(atttup); + attgenerated = attStruct->attgenerated; if (!attStruct->atthasdef) { Form_pg_attribute defAttStruct; @@ -2099,7 +2203,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, valuesAtt[Anum_pg_attribute_atthasdef - 1] = true; replacesAtt[Anum_pg_attribute_atthasdef - 1] = true; - if (add_column_mode) + if (add_column_mode && !attgenerated) { expr2 = expression_planner(expr2); estate = CreateExecutorState(); @@ -2145,7 +2249,7 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, pfree(DatumGetPointer(missingval)); } - heap_close(attrrel, RowExclusiveLock); + table_close(attrrel, RowExclusiveLock); heap_freetuple(atttup); /* @@ -2161,7 +2265,26 @@ StoreAttrDefault(Relation rel, AttrNumber attnum, /* * Record dependencies on objects used in the expression, too. */ - recordDependencyOnExpr(&defobject, expr, NIL, DEPENDENCY_NORMAL); + if (attgenerated) + { + /* + * Generated column: Dropping anything that the generation expression + * refers to automatically drops the generated column. + */ + recordDependencyOnSingleRelExpr(&colobject, expr, RelationGetRelid(rel), + DEPENDENCY_AUTO, + DEPENDENCY_AUTO, false); + } + else + { + /* + * Normal default: Dropping anything that the default refers to + * requires CASCADE and drops the default only. + */ + recordDependencyOnSingleRelExpr(&defobject, expr, RelationGetRelid(rel), + DEPENDENCY_NORMAL, + DEPENDENCY_NORMAL, false); + } /* * Post creation hook for attribute defaults. @@ -2191,7 +2314,6 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr, bool is_no_inherit, bool is_internal) { char *ccbin; - char *ccsrc; List *varList; int keycount; int16 *attNos; @@ -2202,14 +2324,6 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr, */ ccbin = nodeToString(expr); - /* - * Also deparse it to form the mostly-obsolete consrc field. - */ - ccsrc = deparse_expression(expr, - deparse_context_for(RelationGetRelationName(rel), - RelationGetRelid(rel)), - false, false); - /* * Find columns of rel that are used in expr * @@ -2282,14 +2396,12 @@ StoreRelCheck(Relation rel, const char *ccname, Node *expr, NULL, /* not an exclusion constraint */ expr, /* Tree form of check constraint */ ccbin, /* Binary form of check constraint */ - ccsrc, /* Source form of check constraint */ is_local, /* conislocal */ inhcount, /* coninhcount */ is_no_inherit, /* connoinherit */ is_internal); /* internally constructed? */ pfree(ccbin); - pfree(ccsrc); return constrOid; } @@ -2380,7 +2492,8 @@ AddRelationNewConstraints(Relation rel, List *newConstraints, bool allow_merge, bool is_local, - bool is_internal) + bool is_internal, + const char *queryString) { List *cookedConstraints = NIL; TupleDesc tupleDesc; @@ -2409,8 +2522,10 @@ AddRelationNewConstraints(Relation rel, * rangetable entry. We need a ParseState for transformExpr. */ pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; rte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, NULL, false, true); @@ -2427,12 +2542,14 @@ AddRelationNewConstraints(Relation rel, expr = cookDefault(pstate, colDef->raw_default, atp->atttypid, atp->atttypmod, - NameStr(atp->attname)); + NameStr(atp->attname), + atp->attgenerated); /* * If the expression is just a NULL constant, we do not bother to make * an explicit pg_attrdef entry, since the default behavior is - * equivalent. + * equivalent. This applies to column defaults, but not for + * generation expressions. * * Note a nonobvious property of this test: if the column is of a * domain type, what we'll get is not a bare null Const but a @@ -2441,7 +2558,9 @@ AddRelationNewConstraints(Relation rel, * override any default that the domain might have. */ if (expr == NULL || - (IsA(expr, Const) &&((Const *) expr)->constisnull)) + (!colDef->generated && + IsA(expr, Const) && + castNode(Const, expr)->constisnull)) continue; /* If the DEFAULT is volatile we cannot use a missing value */ @@ -2626,133 +2745,133 @@ MergeWithExistingConstraint(Relation rel, const char *ccname, Node *expr, bool found; Relation conDesc; SysScanDesc conscan; - ScanKeyData skey[2]; + ScanKeyData skey[3]; HeapTuple tup; /* Search for a pg_constraint entry with same name and relation */ - conDesc = heap_open(ConstraintRelationId, RowExclusiveLock); + conDesc = table_open(ConstraintRelationId, RowExclusiveLock); found = false; ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationGetRelid(rel))); + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], Anum_pg_constraint_conname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(ccname)); - ScanKeyInit(&skey[1], - Anum_pg_constraint_connamespace, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetNamespace(rel))); - - conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, - NULL, 2, skey); + conscan = systable_beginscan(conDesc, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - while (HeapTupleIsValid(tup = systable_getnext(conscan))) + /* There can be at most one matching row */ + if (HeapTupleIsValid(tup = systable_getnext(conscan))) { Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup); - if (con->conrelid == RelationGetRelid(rel)) + /* Found it. Conflicts if not identical check constraint */ + if (con->contype == CONSTRAINT_CHECK) { - /* Found it. Conflicts if not identical check constraint */ - if (con->contype == CONSTRAINT_CHECK) - { - Datum val; - bool isnull; - - val = fastgetattr(tup, - Anum_pg_constraint_conbin, - conDesc->rd_att, &isnull); - if (isnull) - elog(ERROR, "null conbin for rel %s", - RelationGetRelationName(rel)); - if (equal(expr, stringToNode(TextDatumGetCString(val)))) - found = true; - } + Datum val; + bool isnull; + + val = fastgetattr(tup, + Anum_pg_constraint_conbin, + conDesc->rd_att, &isnull); + if (isnull) + elog(ERROR, "null conbin for rel %s", + RelationGetRelationName(rel)); + if (equal(expr, stringToNode(TextDatumGetCString(val)))) + found = true; + } - /* - * If the existing constraint is purely inherited (no local - * definition) then interpret addition of a local constraint as a - * legal merge. This allows ALTER ADD CONSTRAINT on parent and - * child tables to be given in either order with same end state. - * However if the relation is a partition, all inherited - * constraints are always non-local, including those that were - * merged. - */ - if (is_local && !con->conislocal && !rel->rd_rel->relispartition) - allow_merge = true; + /* + * If the existing constraint is purely inherited (no local + * definition) then interpret addition of a local constraint as a + * legal merge. This allows ALTER ADD CONSTRAINT on parent and child + * tables to be given in either order with same end state. However if + * the relation is a partition, all inherited constraints are always + * non-local, including those that were merged. + */ + if (is_local && !con->conislocal && !rel->rd_rel->relispartition) + allow_merge = true; - if (!found || !allow_merge) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("constraint \"%s\" for relation \"%s\" already exists", - ccname, RelationGetRelationName(rel)))); + if (!found || !allow_merge) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("constraint \"%s\" for relation \"%s\" already exists", + ccname, RelationGetRelationName(rel)))); - /* If the child constraint is "no inherit" then cannot merge */ - if (con->connoinherit) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"", - ccname, RelationGetRelationName(rel)))); + /* If the child constraint is "no inherit" then cannot merge */ + if (con->connoinherit) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"", + ccname, RelationGetRelationName(rel)))); - /* - * Must not change an existing inherited constraint to "no - * inherit" status. That's because inherited constraints should - * be able to propagate to lower-level children. - */ - if (con->coninhcount > 0 && is_no_inherit) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"", - ccname, RelationGetRelationName(rel)))); + /* + * Must not change an existing inherited constraint to "no inherit" + * status. That's because inherited constraints should be able to + * propagate to lower-level children. + */ + if (con->coninhcount > 0 && is_no_inherit) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("constraint \"%s\" conflicts with inherited constraint on relation \"%s\"", + ccname, RelationGetRelationName(rel)))); - /* - * If the child constraint is "not valid" then cannot merge with a - * valid parent constraint - */ - if (is_initially_valid && !con->convalidated) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"", - ccname, RelationGetRelationName(rel)))); + /* + * If the child constraint is "not valid" then cannot merge with a + * valid parent constraint. + */ + if (is_initially_valid && !con->convalidated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"", + ccname, RelationGetRelationName(rel)))); - /* OK to update the tuple */ - ereport(NOTICE, - (errmsg("merging constraint \"%s\" with inherited definition", - ccname))); + /* OK to update the tuple */ + ereport(NOTICE, + (errmsg("merging constraint \"%s\" with inherited definition", + ccname))); - tup = heap_copytuple(tup); - con = (Form_pg_constraint) GETSTRUCT(tup); + tup = heap_copytuple(tup); + con = (Form_pg_constraint) GETSTRUCT(tup); - /* - * In case of partitions, an inherited constraint must be - * inherited only once since it cannot have multiple parents and - * it is never considered local. - */ - if (rel->rd_rel->relispartition) - { - con->coninhcount = 1; - con->conislocal = false; - } + /* + * In case of partitions, an inherited constraint must be inherited + * only once since it cannot have multiple parents and it is never + * considered local. + */ + if (rel->rd_rel->relispartition) + { + con->coninhcount = 1; + con->conislocal = false; + } + else + { + if (is_local) + con->conislocal = true; else - { - if (is_local) - con->conislocal = true; - else - con->coninhcount++; - } + con->coninhcount++; + } - if (is_no_inherit) - { - Assert(is_local); - con->connoinherit = true; - } - CatalogTupleUpdate(conDesc, &tup->t_self, tup); - break; + if (is_no_inherit) + { + Assert(is_local); + con->connoinherit = true; } + + CatalogTupleUpdate(conDesc, &tup->t_self, tup); } systable_endscan(conscan); - heap_close(conDesc, RowExclusiveLock); + table_close(conDesc, RowExclusiveLock); return found; } @@ -2774,7 +2893,7 @@ SetRelationNumChecks(Relation rel, int numchecks) HeapTuple reltup; Form_pg_class relStruct; - relrel = heap_open(RelationRelationId, RowExclusiveLock); + relrel = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(rel))); if (!HeapTupleIsValid(reltup)) @@ -2795,7 +2914,47 @@ SetRelationNumChecks(Relation rel, int numchecks) } heap_freetuple(reltup); - heap_close(relrel, RowExclusiveLock); + table_close(relrel, RowExclusiveLock); +} + +/* + * Check for references to generated columns + */ +static bool +check_nested_generated_walker(Node *node, void *context) +{ + ParseState *pstate = context; + + if (node == NULL) + return false; + else if (IsA(node, Var)) + { + Var *var = (Var *) node; + Oid relid; + AttrNumber attnum; + + relid = rt_fetch(var->varno, pstate->p_rtable)->relid; + attnum = var->varattno; + + if (OidIsValid(relid) && AttributeNumberIsValid(attnum) && get_attgenerated(relid, attnum)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cannot use generated column \"%s\" in column generation expression", + get_attname(relid, attnum, false)), + errdetail("A generated column cannot reference another generated column."), + parser_errposition(pstate, var->location))); + + return false; + } + else + return expression_tree_walker(node, check_nested_generated_walker, + (void *) context); +} + +static void +check_nested_generated(ParseState *pstate, Node *node) +{ + check_nested_generated_walker(node, pstate); } /* @@ -2815,7 +2974,8 @@ cookDefault(ParseState *pstate, Node *raw_default, Oid atttypid, int32 atttypmod, - const char *attname) + const char *attname, + char attgenerated) { Node *expr; @@ -2824,22 +2984,25 @@ cookDefault(ParseState *pstate, /* * Transform raw parsetree to executable expression. */ - expr = transformExpr(pstate, raw_default, EXPR_KIND_COLUMN_DEFAULT); + expr = transformExpr(pstate, raw_default, attgenerated ? EXPR_KIND_GENERATED_COLUMN : EXPR_KIND_COLUMN_DEFAULT); - /* - * Make sure default expr does not refer to any vars (we need this check - * since the pstate includes the target table). - */ - if (contain_var_clause(expr)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), - errmsg("cannot use column references in default expression"))); + if (attgenerated) + { + check_nested_generated(pstate, expr); - /* - * transformExpr() should have already rejected subqueries, aggregates, - * window functions, and SRFs, based on the EXPR_KIND_ for a default - * expression. - */ + if (contain_mutable_functions(expr)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("generation expression is not immutable"))); + } + else + { + /* + * For a default expression, transformExpr() should have rejected + * column references. + */ + Assert(!contain_var_clause(expr)); + } /* * Coerce the expression to the correct type and typmod, if given. This @@ -2932,7 +3095,7 @@ RemoveStatistics(Oid relid, AttrNumber attnum) int nkeys; HeapTuple tuple; - pgstatistic = heap_open(StatisticRelationId, RowExclusiveLock); + pgstatistic = table_open(StatisticRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_statistic_starelid, @@ -2959,7 +3122,7 @@ RemoveStatistics(Oid relid, AttrNumber attnum) systable_endscan(scan); - heap_close(pgstatistic, RowExclusiveLock); + table_close(pgstatistic, RowExclusiveLock); } @@ -2995,7 +3158,7 @@ RelationTruncateIndexes(Relation heapRelation) /* Initialize the index and rebuild */ /* Note: we do not need to re-establish pkey setting */ - index_build(heapRelation, currentIndex, indexInfo, false, true, false); + index_build(heapRelation, currentIndex, indexInfo, true, false); /* We're done with this index */ index_close(currentIndex, NoLock); @@ -3023,7 +3186,7 @@ heap_truncate(List *relids) Oid rid = lfirst_oid(cell); Relation rel; - rel = heap_open(rid, AccessExclusiveLock); + rel = table_open(rid, AccessExclusiveLock); relations = lappend(relations, rel); } @@ -3039,7 +3202,7 @@ heap_truncate(List *relids) heap_truncate_one_rel(rel); /* Close the relation, but keep exclusive lock on it until commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -3057,8 +3220,15 @@ heap_truncate_one_rel(Relation rel) { Oid toastrelid; - /* Truncate the actual file (and discard buffers) */ - RelationTruncate(rel, 0); + /* + * Truncate the relation. Partitioned tables have no storage, so there is + * nothing to do for them here. + */ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + return; + + /* Truncate the underlying relation */ + table_relation_nontransactional_truncate(rel); /* If the relation has indexes, truncate the indexes too */ RelationTruncateIndexes(rel); @@ -3067,12 +3237,12 @@ heap_truncate_one_rel(Relation rel) toastrelid = rel->rd_rel->reltoastrelid; if (OidIsValid(toastrelid)) { - Relation toastrel = heap_open(toastrelid, AccessExclusiveLock); + Relation toastrel = table_open(toastrelid, AccessExclusiveLock); - RelationTruncate(toastrel, 0); + table_relation_nontransactional_truncate(toastrel); RelationTruncateIndexes(toastrel); /* keep the lock... */ - heap_close(toastrel, NoLock); + table_close(toastrel, NoLock); } } @@ -3100,13 +3270,16 @@ heap_truncate_check_FKs(List *relations, bool tempTables) * Build a list of OIDs of the interesting relations. * * If a relation has no triggers, then it can neither have FKs nor be - * referenced by a FK from another table, so we can ignore it. + * referenced by a FK from another table, so we can ignore it. For + * partitioned tables, FKs have no triggers, so we must include them + * anyway. */ foreach(cell, relations) { Relation rel = lfirst(cell); - if (rel->rd_rel->relhastriggers) + if (rel->rd_rel->relhastriggers || + rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) oids = lappend_oid(oids, RelationGetRelid(rel)); } @@ -3193,7 +3366,7 @@ heap_truncate_find_FKs(List *relationIds) * Must scan pg_constraint. Right now, it is a seqscan because there is * no available index on confrelid. */ - fkeyRel = heap_open(ConstraintRelationId, AccessShareLock); + fkeyRel = table_open(ConstraintRelationId, AccessShareLock); fkeyScan = systable_beginscan(fkeyRel, InvalidOid, false, NULL, 0, NULL); @@ -3210,55 +3383,19 @@ heap_truncate_find_FKs(List *relationIds) if (!list_member_oid(relationIds, con->confrelid)) continue; - /* Add referencer unless already in input or result list */ + /* Add referencer to result, unless present in input list */ if (!list_member_oid(relationIds, con->conrelid)) - result = insert_ordered_unique_oid(result, con->conrelid); + result = lappend_oid(result, con->conrelid); } systable_endscan(fkeyScan); - heap_close(fkeyRel, AccessShareLock); + table_close(fkeyRel, AccessShareLock); - return result; -} - -/* - * insert_ordered_unique_oid - * Insert a new Oid into a sorted list of Oids, preserving ordering, - * and eliminating duplicates - * - * Building the ordered list this way is O(N^2), but with a pretty small - * constant, so for the number of entries we expect it will probably be - * faster than trying to apply qsort(). It seems unlikely someone would be - * trying to truncate a table with thousands of dependent tables ... - */ -static List * -insert_ordered_unique_oid(List *list, Oid datum) -{ - ListCell *prev; - - /* Does the datum belong at the front? */ - if (list == NIL || datum < linitial_oid(list)) - return lcons_oid(datum, list); - /* Does it match the first entry? */ - if (datum == linitial_oid(list)) - return list; /* duplicate, so don't insert */ - /* No, so find the entry it belongs after */ - prev = list_head(list); - for (;;) - { - ListCell *curr = lnext(prev); + /* Now sort and de-duplicate the result list */ + list_sort(result, list_oid_cmp); + list_deduplicate_oid(result); - if (curr == NULL || datum < lfirst_oid(curr)) - break; /* it belongs after 'prev', before 'curr' */ - - if (datum == lfirst_oid(curr)) - return list; /* duplicate, so don't insert */ - - prev = curr; - } - /* Insert datum into list after 'prev' */ - lappend_cell_oid(list, prev, datum); - return list; + return result; } /* @@ -3305,7 +3442,7 @@ StorePartitionKey(Relation rel, else partexprDatum = (Datum) 0; - pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock); + pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock); MemSet(nulls, false, sizeof(nulls)); @@ -3325,11 +3462,11 @@ StorePartitionKey(Relation rel, tuple = heap_form_tuple(RelationGetDescr(pg_partitioned_table), values, nulls); CatalogTupleInsert(pg_partitioned_table, tuple); - heap_close(pg_partitioned_table, RowExclusiveLock); + table_close(pg_partitioned_table, RowExclusiveLock); /* Mark this relation as dependent on a few things as follows */ myself.classId = RelationRelationId; - myself.objectId = RelationGetRelid(rel);; + myself.objectId = RelationGetRelid(rel); myself.objectSubId = 0; /* Operator class and collation per key column */ @@ -3348,22 +3485,42 @@ StorePartitionKey(Relation rel, referenced.classId = CollationRelationId; referenced.objectId = partcollation[i]; referenced.objectSubId = 0; + + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + } - recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + /* + * The partitioning columns are made internally dependent on the table, + * because we cannot drop any of them without dropping the whole table. + * (ATExecDropColumn independently enforces that, but it's not bulletproof + * so we need the dependencies too.) + */ + for (i = 0; i < partnatts; i++) + { + if (partattrs[i] == 0) + continue; /* ignore expressions here */ + + referenced.classId = RelationRelationId; + referenced.objectId = RelationGetRelid(rel); + referenced.objectSubId = partattrs[i]; + + recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL); } /* - * Anything mentioned in the expressions. We must ignore the column - * references, which will depend on the table itself; there is no separate - * partition key object. + * Also consider anything mentioned in partition expressions. External + * references (e.g. functions) get NORMAL dependencies. Table columns + * mentioned in the expressions are handled the same as plain partitioning + * columns, i.e. they become internally dependent on the whole table. */ if (partexprs) recordDependencyOnSingleRelExpr(&myself, (Node *) partexprs, RelationGetRelid(rel), DEPENDENCY_NORMAL, - DEPENDENCY_AUTO, true); + DEPENDENCY_INTERNAL, + true /* reverse the self-deps */ ); /* * We must invalidate the relcache so that the next @@ -3383,7 +3540,7 @@ RemovePartitionKeyByRelId(Oid relid) Relation rel; HeapTuple tuple; - rel = heap_open(PartitionedRelationId, RowExclusiveLock); + rel = table_open(PartitionedRelationId, RowExclusiveLock); tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) @@ -3393,7 +3550,7 @@ RemovePartitionKeyByRelId(Oid relid) CatalogTupleDelete(rel, &tuple->t_self); ReleaseSysCache(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -3405,7 +3562,7 @@ RemovePartitionKeyByRelId(Oid relid) * pg_partitioned_table. * * Also, invalidate the parent's relcache, so that the next rebuild will load - * the new partition's info into its partition descriptor.  If there is a + * the new partition's info into its partition descriptor. If there is a * default partition, we must invalidate its relcache entry as well. */ void @@ -3420,7 +3577,7 @@ StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound) Oid defaultPartOid; /* Update pg_class tuple */ - classRel = heap_open(RelationRelationId, RowExclusiveLock); + classRel = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(rel))); if (!HeapTupleIsValid(tuple)) @@ -3453,7 +3610,7 @@ StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound) ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true; CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple); heap_freetuple(newtuple); - heap_close(classRel, RowExclusiveLock); + table_close(classRel, RowExclusiveLock); /* * If we're storing bounds for the default partition, update diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 5d73e92901f..098732cc4a8 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -3,7 +3,7 @@ * index.c * code to create and destroy POSTGRES index relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,10 +24,11 @@ #include #include "access/amapi.h" +#include "access/heapam.h" #include "access/multixact.h" #include "access/relscan.h" -#include "access/reloptions.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/visibilitymap.h" #include "access/xact.h" @@ -38,9 +39,11 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/objectaccess.h" +#include "catalog/partition.h" #include "catalog/pg_am.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" +#include "catalog/pg_description.h" #include "catalog/pg_depend.h" #include "catalog/pg_inherits.h" #include "catalog/pg_operator.h" @@ -49,15 +52,17 @@ #include "catalog/pg_trigger.h" #include "catalog/pg_type.h" #include "catalog/storage.h" +#include "commands/event_trigger.h" +#include "commands/progress.h" #include "commands/tablecmds.h" #include "commands/trigger.h" #include "executor/executor.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "parser/parser.h" +#include "pgstat.h" #include "rewrite/rewriteManip.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" @@ -74,22 +79,11 @@ #include "utils/syscache.h" #include "utils/tuplesort.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" /* Potentially set by pg_upgrade_support functions */ Oid binary_upgrade_next_index_pg_class_oid = InvalidOid; -/* state info for validate_index bulkdelete callback */ -typedef struct -{ - Tuplesortstate *tuplesort; /* for sorting the index TIDs */ - /* statistics (for debug purposes only): */ - double htups, - itups, - tups_inserted; -} v_i_state; - /* * Pointer-free representation of variables used when reindexing system * catalogs; we use this to propagate those values to parallel workers. @@ -105,39 +99,32 @@ typedef struct /* non-export function prototypes */ static bool relationHasPrimaryKey(Relation rel); static TupleDesc ConstructTupleDescriptor(Relation heapRelation, - IndexInfo *indexInfo, - List *indexColNames, - Oid accessMethodObjectId, - Oid *collationObjectId, - Oid *classObjectId); + IndexInfo *indexInfo, + List *indexColNames, + Oid accessMethodObjectId, + Oid *collationObjectId, + Oid *classObjectId); static void InitializeAttributeOids(Relation indexRelation, - int numatts, Oid indexoid); + int numatts, Oid indexoid); static void AppendAttributeTuples(Relation indexRelation, int numatts); static void UpdateIndexRelation(Oid indexoid, Oid heapoid, - Oid parentIndexId, - IndexInfo *indexInfo, - Oid *collationOids, - Oid *classOids, - int16 *coloptions, - bool primary, - bool isexclusion, - bool immediate, - bool isvalid, - bool isready); + Oid parentIndexId, + IndexInfo *indexInfo, + Oid *collationOids, + Oid *classOids, + int16 *coloptions, + bool primary, + bool isexclusion, + bool immediate, + bool isvalid, + bool isready); static void index_update_stats(Relation rel, - bool hasindex, - double reltuples); + bool hasindex, + double reltuples); static void IndexCheckExclusion(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo); -static inline int64 itemptr_encode(ItemPointer itemptr); -static inline void itemptr_decode(ItemPointer itemptr, int64 encoded); + Relation indexRelation, + IndexInfo *indexInfo); static bool validate_index_callback(ItemPointer itemptr, void *opaque); -static void validate_index_heapscan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - Snapshot snapshot, - v_i_state *state); static bool ReindexIsCurrentlyProcessingIndex(Oid indexOid); static void SetReindexProcessing(Oid heapOid, Oid indexOid); static void ResetReindexProcessing(void); @@ -152,7 +139,7 @@ static void ResetReindexPending(void); * * Caller must have suitable lock on the relation. * - * Note: we intentionally do not check IndexIsValid here; that's because this + * Note: we intentionally do not check indisvalid here; that's because this * is used to enforce the rule that there can be only one indisprimary index, * and we want that to be true even if said index is invalid. */ @@ -198,13 +185,14 @@ relationHasPrimaryKey(Relation rel) * * We check for a pre-existing primary key, and that all columns of the index * are simple column references (not expressions), and that all those - * columns are marked NOT NULL. If they aren't (which can only happen during - * ALTER TABLE ADD CONSTRAINT, since the parser forces such columns to be - * created NOT NULL during CREATE TABLE), do an ALTER SET NOT NULL to mark - * them so --- or fail if they are not in fact nonnull. + * columns are marked NOT NULL. If not, fail. * - * As of PG v10, the SET NOT NULL is applied to child tables as well, so - * that the behavior is like a manual SET NOT NULL. + * We used to automatically change unmarked columns to NOT NULL here by doing + * our own local ALTER TABLE command. But that doesn't work well if we're + * executing one subcommand of an ALTER TABLE: the operations may not get + * performed in the right order overall. Now we expect that the parser + * inserted any required ALTER TABLE SET NOT NULL operations before trying + * to create a primary-key index. * * Caller had better have at least ShareLock on the table, else the not-null * checking isn't trustworthy. @@ -212,18 +200,18 @@ relationHasPrimaryKey(Relation rel) void index_check_primary_key(Relation heapRel, IndexInfo *indexInfo, - bool is_alter_table) + bool is_alter_table, + IndexStmt *stmt) { - List *cmds; int i; /* - * If ALTER TABLE, check that there isn't already a PRIMARY KEY. In CREATE - * TABLE, we have faith that the parser rejected multiple pkey clauses; - * and CREATE INDEX doesn't have a way to say PRIMARY KEY, so it's no - * problem either. + * If ALTER TABLE or CREATE TABLE .. PARTITION OF, check that there isn't + * already a PRIMARY KEY. In CREATE TABLE for an ordinary relation, we + * have faith that the parser rejected multiple pkey clauses; and CREATE + * INDEX doesn't have a way to say PRIMARY KEY, so it's no problem either. */ - if (is_alter_table && + if ((is_alter_table || heapRel->rd_rel->relispartition) && relationHasPrimaryKey(heapRel)) { ereport(ERROR, @@ -234,12 +222,12 @@ index_check_primary_key(Relation heapRel, /* * Check that all of the attributes in a primary key are marked as not - * null, otherwise attempt to ALTER TABLE .. SET NOT NULL + * null. (We don't really expect to see that; it'd mean the parser messed + * up. But it seems wise to check anyway.) */ - cmds = NIL; for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) { - AttrNumber attnum = indexInfo->ii_KeyAttrNumbers[i]; + AttrNumber attnum = indexInfo->ii_IndexAttrNumbers[i]; HeapTuple atttuple; Form_pg_attribute attform; @@ -261,26 +249,13 @@ index_check_primary_key(Relation heapRel, attform = (Form_pg_attribute) GETSTRUCT(atttuple); if (!attform->attnotnull) - { - /* Add a subcommand to make this one NOT NULL */ - AlterTableCmd *cmd = makeNode(AlterTableCmd); - - cmd->subtype = AT_SetNotNull; - cmd->name = pstrdup(NameStr(attform->attname)); - cmds = lappend(cmds, cmd); - } + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("primary key column \"%s\" is not marked NOT NULL", + NameStr(attform->attname)))); ReleaseSysCache(atttuple); } - - /* - * XXX: possible future improvement: when being called from ALTER TABLE, - * it would be more efficient to merge this with the outer ALTER TABLE, so - * as to avoid two scans. But that seems to complicate DefineIndex's API - * unduly. - */ - if (cmds) - AlterTableInternal(RelationGetRelid(heapRel), cmds, true); } /* @@ -297,6 +272,7 @@ ConstructTupleDescriptor(Relation heapRelation, Oid *classObjectId) { int numatts = indexInfo->ii_NumIndexAttrs; + int numkeyatts = indexInfo->ii_NumIndexKeyAttrs; ListCell *colnames_item = list_head(indexColNames); ListCell *indexpr_item = list_head(indexInfo->ii_Expressions); IndexAmRoutine *amroutine; @@ -315,79 +291,63 @@ ConstructTupleDescriptor(Relation heapRelation, /* * allocate the new tuple descriptor */ - indexTupDesc = CreateTemplateTupleDesc(numatts, false); + indexTupDesc = CreateTemplateTupleDesc(numatts); /* - * For simple index columns, we copy the pg_attribute row from the parent - * relation and modify it as necessary. For expressions we have to cons - * up a pg_attribute row the hard way. + * Fill in the pg_attribute row. */ for (i = 0; i < numatts; i++) { - AttrNumber atnum = indexInfo->ii_KeyAttrNumbers[i]; + AttrNumber atnum = indexInfo->ii_IndexAttrNumbers[i]; Form_pg_attribute to = TupleDescAttr(indexTupDesc, i); HeapTuple tuple; Form_pg_type typeTup; Form_pg_opclass opclassTup; Oid keyType; + MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE); + to->attnum = i + 1; + to->attstattarget = -1; + to->attcacheoff = -1; + to->attislocal = true; + to->attcollation = (i < numkeyatts) ? + collationObjectId[i] : InvalidOid; + + /* + * For simple index columns, we copy some pg_attribute fields from the + * parent relation. For expressions we have to look at the expression + * result. + */ if (atnum != 0) { /* Simple index column */ - Form_pg_attribute from; - - if (atnum < 0) - { - /* - * here we are indexing on a system attribute (-1...-n) - */ - from = SystemAttributeDefinition(atnum, - heapRelation->rd_rel->relhasoids); - } - else - { - /* - * here we are indexing on a normal attribute (1...n) - */ - if (atnum > natts) /* safety check */ - elog(ERROR, "invalid column number %d", atnum); - from = TupleDescAttr(heapTupDesc, - AttrNumberGetAttrOffset(atnum)); - } - - /* - * now that we've determined the "from", let's copy the tuple desc - * data... - */ - memcpy(to, from, ATTRIBUTE_FIXED_PART_SIZE); - - /* - * Fix the stuff that should not be the same as the underlying - * attr - */ - to->attnum = i + 1; - - to->attstattarget = -1; - to->attcacheoff = -1; - to->attnotnull = false; - to->atthasdef = false; - to->atthasmissing = false; - to->attidentity = '\0'; - to->attislocal = true; - to->attinhcount = 0; - to->attcollation = collationObjectId[i]; + const FormData_pg_attribute *from; + + Assert(atnum > 0); /* should've been caught above */ + + if (atnum > natts) /* safety check */ + elog(ERROR, "invalid column number %d", atnum); + from = TupleDescAttr(heapTupDesc, + AttrNumberGetAttrOffset(atnum)); + + namecpy(&to->attname, &from->attname); + to->atttypid = from->atttypid; + to->attlen = from->attlen; + to->attndims = from->attndims; + to->atttypmod = from->atttypmod; + to->attbyval = from->attbyval; + to->attstorage = from->attstorage; + to->attalign = from->attalign; } else { /* Expressional index */ Node *indexkey; - MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE); - if (indexpr_item == NULL) /* shouldn't happen */ elog(ERROR, "too few entries in indexprs list"); indexkey = (Node *) lfirst(indexpr_item); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(indexInfo->ii_Expressions, indexpr_item); /* * Lookup the expression type in pg_type for the type length etc. @@ -399,19 +359,14 @@ ConstructTupleDescriptor(Relation heapRelation, typeTup = (Form_pg_type) GETSTRUCT(tuple); /* - * Assign some of the attributes values. Leave the rest as 0. + * Assign some of the attributes values. Leave the rest. */ - to->attnum = i + 1; to->atttypid = keyType; to->attlen = typeTup->typlen; to->attbyval = typeTup->typbyval; to->attstorage = typeTup->typstorage; to->attalign = typeTup->typalign; - to->attstattarget = -1; - to->attcacheoff = -1; to->atttypmod = exprTypmod(indexkey); - to->attislocal = true; - to->attcollation = collationObjectId[i]; ReleaseSysCache(tuple); @@ -426,7 +381,7 @@ ConstructTupleDescriptor(Relation heapRelation, */ CheckAttributeType(NameStr(to->attname), to->atttypid, to->attcollation, - NIL, false); + NIL, 0); } /* @@ -442,7 +397,7 @@ ConstructTupleDescriptor(Relation heapRelation, if (colnames_item == NULL) /* shouldn't happen */ elog(ERROR, "too few entries in colnames list"); namestrcpy(&to->attname, (const char *) lfirst(colnames_item)); - colnames_item = lnext(colnames_item); + colnames_item = lnext(indexColNames, colnames_item); /* * Check the opclass and index AM to see if either provides a keytype @@ -541,7 +496,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts) /* * open the attribute relation and its indexes */ - pg_attribute = heap_open(AttributeRelationId, RowExclusiveLock); + pg_attribute = table_open(AttributeRelationId, RowExclusiveLock); indstate = CatalogOpenIndexes(pg_attribute); @@ -554,19 +509,14 @@ AppendAttributeTuples(Relation indexRelation, int numatts) { Form_pg_attribute attr = TupleDescAttr(indexTupDesc, i); - /* - * There used to be very grotty code here to set these fields, but I - * think it's unnecessary. They should be set already. - */ Assert(attr->attnum == i + 1); - Assert(attr->attcacheoff == -1); InsertPgAttributeTuple(pg_attribute, attr, indstate); } CatalogCloseIndexes(indstate); - heap_close(pg_attribute, RowExclusiveLock); + table_close(pg_attribute, RowExclusiveLock); } /* ---------------------------------------------------------------- @@ -578,7 +528,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts) static void UpdateIndexRelation(Oid indexoid, Oid heapoid, - Oid parentIndexOid, + Oid parentIndexId, IndexInfo *indexInfo, Oid *collationOids, Oid *classOids, @@ -607,10 +557,10 @@ UpdateIndexRelation(Oid indexoid, */ indkey = buildint2vector(NULL, indexInfo->ii_NumIndexAttrs); for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) - indkey->values[i] = indexInfo->ii_KeyAttrNumbers[i]; - indcollation = buildoidvector(collationOids, indexInfo->ii_NumIndexAttrs); + indkey->values[i] = indexInfo->ii_IndexAttrNumbers[i]; + indcollation = buildoidvector(collationOids, indexInfo->ii_NumIndexKeyAttrs); indclass = buildoidvector(classOids, indexInfo->ii_NumIndexKeyAttrs); - indoption = buildint2vector(coloptions, indexInfo->ii_NumIndexAttrs); + indoption = buildint2vector(coloptions, indexInfo->ii_NumIndexKeyAttrs); /* * Convert the index expressions (if any) to a text datum @@ -644,7 +594,7 @@ UpdateIndexRelation(Oid indexoid, /* * open the system catalog index relation */ - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); /* * Build a pg_index tuple @@ -686,7 +636,7 @@ UpdateIndexRelation(Oid indexoid, /* * close the relation and free the tuple */ - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); heap_freetuple(tuple); } @@ -774,6 +724,8 @@ index_create(Relation heapRelation, bool concurrent = (flags & INDEX_CREATE_CONCURRENT) != 0; bool partitioned = (flags & INDEX_CREATE_PARTITIONED) != 0; char relkind; + TransactionId relfrozenxid; + MultiXactId relminmxid; /* constraint flags can only be set when a constraint is requested */ Assert((constr_flags == 0) || @@ -784,7 +736,7 @@ index_create(Relation heapRelation, relkind = partitioned ? RELKIND_PARTITIONED_INDEX : RELKIND_INDEX; is_exclusion = (indexInfo->ii_ExclusionOps != NULL); - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); /* * The index will be in the same namespace as its parent table, and is @@ -811,23 +763,68 @@ index_create(Relation heapRelation, errmsg("user-defined indexes on system catalog tables are not supported"))); /* - * concurrent index build on a system catalog is unsafe because we tend to - * release locks before committing in catalogs + * Btree text_pattern_ops uses text_eq as the equality operator, which is + * fine as long as the collation is deterministic; text_eq then reduces to + * bitwise equality and so it is semantically compatible with the other + * operators and functions in that opclass. But with a nondeterministic + * collation, text_eq could yield results that are incompatible with the + * actual behavior of the index (which is determined by the opclass's + * comparison function). We prevent such problems by refusing creation of + * an index with that opclass and a nondeterministic collation. + * + * The same applies to varchar_pattern_ops and bpchar_pattern_ops. If we + * find more cases, we might decide to create a real mechanism for marking + * opclasses as incompatible with nondeterminism; but for now, this small + * hack suffices. + * + * Another solution is to use a special operator, not text_eq, as the + * equality opclass member; but that is undesirable because it would + * prevent index usage in many queries that work fine today. + */ + for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) + { + Oid collation = collationObjectId[i]; + Oid opclass = classObjectId[i]; + + if (collation) + { + if ((opclass == TEXT_BTREE_PATTERN_OPS_OID || + opclass == VARCHAR_BTREE_PATTERN_OPS_OID || + opclass == BPCHAR_BTREE_PATTERN_OPS_OID) && + !get_collation_isdeterministic(collation)) + { + HeapTuple classtup; + + classtup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass)); + if (!HeapTupleIsValid(classtup)) + elog(ERROR, "cache lookup failed for operator class %u", opclass); + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for operator class \"%s\"", + NameStr(((Form_pg_opclass) GETSTRUCT(classtup))->opcname)))); + ReleaseSysCache(classtup); + } + } + } + + /* + * Concurrent index build on a system catalog is unsafe because we tend to + * release locks before committing in catalogs. */ if (concurrent && - IsSystemRelation(heapRelation)) + IsCatalogRelation(heapRelation)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("concurrent index creation on system catalog tables is not supported"))); /* - * This case is currently not supported, but there's no way to ask for it - * in the grammar anyway, so it can't happen. + * This case is currently not supported. There's no way to ask for it in + * the grammar with CREATE INDEX, but it can happen with REINDEX. */ if (concurrent && is_exclusion) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg_internal("concurrent index creation for exclusion constraints is not supported"))); + errmsg("concurrent index creation for exclusion constraints is not supported"))); /* * We cannot allow indexing a shared relation after initdb (because @@ -844,6 +841,12 @@ index_create(Relation heapRelation, if (shared_relation && tableSpaceId != GLOBALTABLESPACE_OID) elog(ERROR, "shared relations must be placed in pg_global tablespace"); + /* + * Check for duplicate name (both as to the index, and as to the + * associated constraint if any). Such cases would fail on the relevant + * catalogs' unique indexes anyway, but we prefer to give a friendlier + * error message. + */ if (get_relname_relid(indexRelationName, namespaceId)) { if ((flags & INDEX_CREATE_IF_NOT_EXISTS) != 0) @@ -852,7 +855,7 @@ index_create(Relation heapRelation, (errcode(ERRCODE_DUPLICATE_TABLE), errmsg("relation \"%s\" already exists, skipping", indexRelationName))); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); return InvalidOid; } @@ -862,6 +865,20 @@ index_create(Relation heapRelation, indexRelationName))); } + if ((flags & INDEX_CREATE_ADD_CONSTRAINT) != 0 && + ConstraintNameIsUsed(CONSTRAINT_RELATION, heapRelationId, + indexRelationName)) + { + /* + * INDEX_CREATE_IF_NOT_EXISTS does not apply here, since the + * conflicting constraint is not an index. + */ + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_OBJECT), + errmsg("constraint \"%s\" for relation \"%s\" already exists", + indexRelationName, RelationGetRelationName(heapRelation)))); + } + /* * construct tuple descriptor for index tuples */ @@ -908,13 +925,18 @@ index_create(Relation heapRelation, tableSpaceId, indexRelationId, relFileNode, + accessMethodObjectId, indexTupDesc, relkind, relpersistence, shared_relation, mapped_relation, - allow_system_table_mods); + allow_system_table_mods, + &relfrozenxid, + &relminmxid); + Assert(relfrozenxid == InvalidTransactionId); + Assert(relminmxid == InvalidMultiXactId); Assert(indexRelationId == RelationGetRelid(indexRelation)); /* @@ -932,7 +954,7 @@ index_create(Relation heapRelation, */ indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner; indexRelation->rd_rel->relam = accessMethodObjectId; - indexRelation->rd_rel->relhasoids = false; + indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid); /* * store index's pg_class entry @@ -943,7 +965,7 @@ index_create(Relation heapRelation, reloptions); /* done with pg_class */ - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); /* * now update the object id's of all the attribute tuple forms in the @@ -974,9 +996,18 @@ index_create(Relation heapRelation, !concurrent && !invalid, !concurrent); - /* update pg_inherits, if needed */ + /* + * Register relcache invalidation on the indexes' heap relation, to + * maintain consistency of its index list + */ + CacheInvalidateRelcache(heapRelation); + + /* update pg_inherits and the parent's relhassubclass, if needed */ if (OidIsValid(parentIndexRelid)) + { StoreSingleInheritance(indexRelationId, parentIndexRelid, 1); + SetRelationHasSubclass(parentIndexRelid, true); + } /* * Register constraint and dependencies for the index. @@ -1019,34 +1050,31 @@ index_create(Relation heapRelation, } localaddr = index_constraint_create(heapRelation, - indexRelationId, - parentConstraintId, - indexInfo, - indexRelationName, - constraintType, - constr_flags, - allow_system_table_mods, - is_internal); + indexRelationId, + parentConstraintId, + indexInfo, + indexRelationName, + constraintType, + constr_flags, + allow_system_table_mods, + is_internal); if (constraintId) *constraintId = localaddr.objectId; } else { bool have_simple_col = false; - DependencyType deptype; - - deptype = OidIsValid(parentIndexRelid) ? DEPENDENCY_INTERNAL_AUTO : DEPENDENCY_AUTO; /* Create auto dependencies on simply-referenced columns */ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { - if (indexInfo->ii_KeyAttrNumbers[i] != 0) + if (indexInfo->ii_IndexAttrNumbers[i] != 0) { referenced.classId = RelationRelationId; referenced.objectId = heapRelationId; - referenced.objectSubId = indexInfo->ii_KeyAttrNumbers[i]; + referenced.objectSubId = indexInfo->ii_IndexAttrNumbers[i]; - recordDependencyOn(&myself, &referenced, deptype); + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); have_simple_col = true; } @@ -1064,23 +1092,34 @@ index_create(Relation heapRelation, referenced.objectId = heapRelationId; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, deptype); + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); } } - /* Store dependency on parent index, if any */ + /* + * If this is an index partition, create partition dependencies on + * both the parent index and the table. (Note: these must be *in + * addition to*, not instead of, all other dependencies. Otherwise + * we'll be short some dependencies after DETACH PARTITION.) + */ if (OidIsValid(parentIndexRelid)) { referenced.classId = RelationRelationId; referenced.objectId = parentIndexRelid; referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL_AUTO); + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); + + referenced.classId = RelationRelationId; + referenced.objectId = heapRelationId; + referenced.objectSubId = 0; + + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } /* Store dependency on collations */ /* The default collation is pinned, so don't bother recording it */ - for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) + for (i = 0; i < indexInfo->ii_NumIndexKeyAttrs; i++) { if (OidIsValid(collationObjectId[i]) && collationObjectId[i] != DEFAULT_COLLATION_OID) @@ -1180,8 +1219,7 @@ index_create(Relation heapRelation, } else { - index_build(heapRelation, indexRelation, indexInfo, isprimary, false, - true); + index_build(heapRelation, indexRelation, indexInfo, false, true); } /* @@ -1194,177 +1232,696 @@ index_create(Relation heapRelation, } /* - * index_constraint_create - * - * Set up a constraint associated with an index. Return the new constraint's - * address. + * index_concurrently_create_copy * - * heapRelation: table owning the index (must be suitably locked by caller) - * indexRelationId: OID of the index - * parentConstraintId: if constraint is on a partition, the OID of the - * constraint in the parent. - * indexInfo: same info executor uses to insert into the index - * constraintName: what it say (generally, should match name of index) - * constraintType: one of CONSTRAINT_PRIMARY, CONSTRAINT_UNIQUE, or - * CONSTRAINT_EXCLUSION - * flags: bitmask that can include any combination of these bits: - * INDEX_CONSTR_CREATE_MARK_AS_PRIMARY: index is a PRIMARY KEY - * INDEX_CONSTR_CREATE_DEFERRABLE: constraint is DEFERRABLE - * INDEX_CONSTR_CREATE_INIT_DEFERRED: constraint is INITIALLY DEFERRED - * INDEX_CONSTR_CREATE_UPDATE_INDEX: update the pg_index row - * INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS: remove existing dependencies - * of index on table's columns - * allow_system_table_mods: allow table to be a system catalog - * is_internal: index is constructed due to internal process + * Create concurrently an index based on the definition of the one provided by + * caller. The index is inserted into catalogs and needs to be built later + * on. This is called during concurrent reindex processing. */ -ObjectAddress -index_constraint_create(Relation heapRelation, - Oid indexRelationId, - Oid parentConstraintId, - IndexInfo *indexInfo, - const char *constraintName, - char constraintType, - bits16 constr_flags, - bool allow_system_table_mods, - bool is_internal) +Oid +index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char *newName) { - Oid namespaceId = RelationGetNamespace(heapRelation); - ObjectAddress myself, - referenced; - Oid conOid; - bool deferrable; - bool initdeferred; - bool mark_as_primary; - bool islocal; - bool noinherit; - int inhcount; - - deferrable = (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) != 0; - initdeferred = (constr_flags & INDEX_CONSTR_CREATE_INIT_DEFERRED) != 0; - mark_as_primary = (constr_flags & INDEX_CONSTR_CREATE_MARK_AS_PRIMARY) != 0; - - /* constraint creation support doesn't work while bootstrapping */ - Assert(!IsBootstrapProcessingMode()); + Relation indexRelation; + IndexInfo *oldInfo, + *newInfo; + Oid newIndexId = InvalidOid; + HeapTuple indexTuple, + classTuple; + Datum indclassDatum, + colOptionDatum, + optionDatum; + oidvector *indclass; + int2vector *indcoloptions; + bool isnull; + List *indexColNames = NIL; + List *indexExprs = NIL; + List *indexPreds = NIL; - /* enforce system-table restriction */ - if (!allow_system_table_mods && - IsSystemRelation(heapRelation) && - IsNormalProcessingMode()) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("user-defined indexes on system catalog tables are not supported"))); + indexRelation = index_open(oldIndexId, RowExclusiveLock); - /* primary/unique constraints shouldn't have any expressions */ - if (indexInfo->ii_Expressions && - constraintType != CONSTRAINT_EXCLUSION) - elog(ERROR, "constraints cannot have index expressions"); + /* The new index needs some information from the old index */ + oldInfo = BuildIndexInfo(indexRelation); /* - * If we're manufacturing a constraint for a pre-existing index, we need - * to get rid of the existing auto dependencies for the index (the ones - * that index_create() would have made instead of calling this function). - * - * Note: this code would not necessarily do the right thing if the index - * has any expressions or predicate, but we'd never be turning such an - * index into a UNIQUE or PRIMARY KEY constraint. + * Concurrent build of an index with exclusion constraints is not + * supported. */ - if (constr_flags & INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS) - deleteDependencyRecordsForClass(RelationRelationId, indexRelationId, - RelationRelationId, DEPENDENCY_AUTO); + if (oldInfo->ii_ExclusionOps != NULL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("concurrent index creation for exclusion constraints is not supported"))); - if (OidIsValid(parentConstraintId)) + /* Get the array of class and column options IDs from index info */ + indexTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(oldIndexId)); + if (!HeapTupleIsValid(indexTuple)) + elog(ERROR, "cache lookup failed for index %u", oldIndexId); + indclassDatum = SysCacheGetAttr(INDEXRELID, indexTuple, + Anum_pg_index_indclass, &isnull); + Assert(!isnull); + indclass = (oidvector *) DatumGetPointer(indclassDatum); + + colOptionDatum = SysCacheGetAttr(INDEXRELID, indexTuple, + Anum_pg_index_indoption, &isnull); + Assert(!isnull); + indcoloptions = (int2vector *) DatumGetPointer(colOptionDatum); + + /* Fetch options of index if any */ + classTuple = SearchSysCache1(RELOID, oldIndexId); + if (!HeapTupleIsValid(classTuple)) + elog(ERROR, "cache lookup failed for relation %u", oldIndexId); + optionDatum = SysCacheGetAttr(RELOID, classTuple, + Anum_pg_class_reloptions, &isnull); + + /* + * Fetch the list of expressions and predicates directly from the + * catalogs. This cannot rely on the information from IndexInfo of the + * old index as these have been flattened for the planner. + */ + if (oldInfo->ii_Expressions != NIL) { - islocal = false; - inhcount = 1; - noinherit = false; + Datum exprDatum; + char *exprString; + + exprDatum = SysCacheGetAttr(INDEXRELID, indexTuple, + Anum_pg_index_indexprs, &isnull); + Assert(!isnull); + exprString = TextDatumGetCString(exprDatum); + indexExprs = (List *) stringToNode(exprString); + pfree(exprString); } - else + if (oldInfo->ii_Predicate != NIL) { - islocal = true; - inhcount = 0; - noinherit = true; + Datum predDatum; + char *predString; + + predDatum = SysCacheGetAttr(INDEXRELID, indexTuple, + Anum_pg_index_indpred, &isnull); + Assert(!isnull); + predString = TextDatumGetCString(predDatum); + indexPreds = (List *) stringToNode(predString); + + /* Also convert to implicit-AND format */ + indexPreds = make_ands_implicit((Expr *) indexPreds); + pfree(predString); } /* - * Construct a pg_constraint entry. + * Build the index information for the new index. Note that rebuild of + * indexes with exclusion constraints is not supported, hence there is no + * need to fill all the ii_Exclusion* fields. */ - conOid = CreateConstraintEntry(constraintName, - namespaceId, - constraintType, - deferrable, - initdeferred, - true, - parentConstraintId, - RelationGetRelid(heapRelation), - indexInfo->ii_KeyAttrNumbers, - indexInfo->ii_NumIndexKeyAttrs, - indexInfo->ii_NumIndexAttrs, - InvalidOid, /* no domain */ - indexRelationId, /* index OID */ - InvalidOid, /* no foreign key */ - NULL, - NULL, - NULL, - NULL, - 0, - ' ', - ' ', - ' ', - indexInfo->ii_ExclusionOps, - NULL, /* no check constraint */ - NULL, - NULL, - islocal, - inhcount, - noinherit, - is_internal); + newInfo = makeIndexInfo(oldInfo->ii_NumIndexAttrs, + oldInfo->ii_NumIndexKeyAttrs, + oldInfo->ii_Am, + indexExprs, + indexPreds, + oldInfo->ii_Unique, + false, /* not ready for inserts */ + true); /* - * Register the index as internally dependent on the constraint. + * Extract the list of column names and the column numbers for the new + * index information. All this information will be used for the index + * creation. + */ + for (int i = 0; i < oldInfo->ii_NumIndexAttrs; i++) + { + TupleDesc indexTupDesc = RelationGetDescr(indexRelation); + Form_pg_attribute att = TupleDescAttr(indexTupDesc, i); + + indexColNames = lappend(indexColNames, NameStr(att->attname)); + newInfo->ii_IndexAttrNumbers[i] = oldInfo->ii_IndexAttrNumbers[i]; + } + + /* + * Now create the new index. * - * Note that the constraint has a dependency on the table, so we don't - * need (or want) any direct dependency from the index to the table. + * For a partition index, we adjust the partition dependency later, to + * ensure a consistent state at all times. That is why parentIndexRelid + * is not set here. + */ + newIndexId = index_create(heapRelation, + newName, + InvalidOid, /* indexRelationId */ + InvalidOid, /* parentIndexRelid */ + InvalidOid, /* parentConstraintId */ + InvalidOid, /* relFileNode */ + newInfo, + indexColNames, + indexRelation->rd_rel->relam, + indexRelation->rd_rel->reltablespace, + indexRelation->rd_indcollation, + indclass->values, + indcoloptions->values, + optionDatum, + INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT, + 0, + true, /* allow table to be a system catalog? */ + false, /* is_internal? */ + NULL); + + /* Close the relations used and clean up */ + index_close(indexRelation, NoLock); + ReleaseSysCache(indexTuple); + ReleaseSysCache(classTuple); + + return newIndexId; +} + +/* + * index_concurrently_build + * + * Build index for a concurrent operation. Low-level locks are taken when + * this operation is performed to prevent only schema changes, but they need + * to be kept until the end of the transaction performing this operation. + * 'indexOid' refers to an index relation OID already created as part of + * previous processing, and 'heapOid' refers to its parent heap relation. + */ +void +index_concurrently_build(Oid heapRelationId, + Oid indexRelationId) +{ + Relation heapRel; + Relation indexRelation; + IndexInfo *indexInfo; + + /* This had better make sure that a snapshot is active */ + Assert(ActiveSnapshotSet()); + + /* Open and lock the parent heap relation */ + heapRel = table_open(heapRelationId, ShareUpdateExclusiveLock); + + /* And the target index relation */ + indexRelation = index_open(indexRelationId, RowExclusiveLock); + + /* + * We have to re-build the IndexInfo struct, since it was lost in the + * commit of the transaction where this concurrent index was created at + * the catalog level. */ - myself.classId = RelationRelationId; - myself.objectId = indexRelationId; - myself.objectSubId = 0; + indexInfo = BuildIndexInfo(indexRelation); + Assert(!indexInfo->ii_ReadyForInserts); + indexInfo->ii_Concurrent = true; + indexInfo->ii_BrokenHotChain = false; - referenced.classId = ConstraintRelationId; - referenced.objectId = conOid; - referenced.objectSubId = 0; + /* Now build the index */ + index_build(heapRel, indexRelation, indexInfo, false, true); - recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL); + /* Close both the relations, but keep the locks */ + table_close(heapRel, NoLock); + index_close(indexRelation, NoLock); /* - * Also, if this is a constraint on a partition, mark it as depending - * on the constraint in the parent. + * Update the pg_index row to mark the index as ready for inserts. Once we + * commit this transaction, any new transactions that open the table must + * insert new entries into the index for insertions and non-HOT updates. */ - if (OidIsValid(parentConstraintId)) - { - ObjectAddress parentConstr; + index_set_state_flags(indexRelationId, INDEX_CREATE_SET_READY); +} - ObjectAddressSet(parentConstr, ConstraintRelationId, parentConstraintId); - recordDependencyOn(&referenced, &parentConstr, DEPENDENCY_INTERNAL_AUTO); - } +/* + * index_concurrently_swap + * + * Swap name, dependencies, and constraints of the old index over to the new + * index, while marking the old index as invalid and the new as valid. + */ +void +index_concurrently_swap(Oid newIndexId, Oid oldIndexId, const char *oldName) +{ + Relation pg_class, + pg_index, + pg_constraint, + pg_trigger; + Relation oldClassRel, + newClassRel; + HeapTuple oldClassTuple, + newClassTuple; + Form_pg_class oldClassForm, + newClassForm; + HeapTuple oldIndexTuple, + newIndexTuple; + Form_pg_index oldIndexForm, + newIndexForm; + Oid indexConstraintOid; + List *constraintOids = NIL; + ListCell *lc; /* - * If the constraint is deferrable, create the deferred uniqueness - * checking trigger. (The trigger will be given an internal dependency on - * the constraint by CreateTrigger.) + * Take a necessary lock on the old and new index before swapping them. */ - if (deferrable) - { - CreateTrigStmt *trigger; + oldClassRel = relation_open(oldIndexId, ShareUpdateExclusiveLock); + newClassRel = relation_open(newIndexId, ShareUpdateExclusiveLock); - trigger = makeNode(CreateTrigStmt); - trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ? - "PK_ConstraintTrigger" : - "Unique_ConstraintTrigger"; - trigger->relation = NULL; - trigger->funcname = SystemFuncName("unique_key_recheck"); - trigger->args = NIL; - trigger->row = true; - trigger->timing = TRIGGER_TYPE_AFTER; + /* Now swap names and dependencies of those indexes */ + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + oldClassTuple = SearchSysCacheCopy1(RELOID, + ObjectIdGetDatum(oldIndexId)); + if (!HeapTupleIsValid(oldClassTuple)) + elog(ERROR, "could not find tuple for relation %u", oldIndexId); + newClassTuple = SearchSysCacheCopy1(RELOID, + ObjectIdGetDatum(newIndexId)); + if (!HeapTupleIsValid(newClassTuple)) + elog(ERROR, "could not find tuple for relation %u", newIndexId); + + oldClassForm = (Form_pg_class) GETSTRUCT(oldClassTuple); + newClassForm = (Form_pg_class) GETSTRUCT(newClassTuple); + + /* Swap the names */ + namestrcpy(&newClassForm->relname, NameStr(oldClassForm->relname)); + namestrcpy(&oldClassForm->relname, oldName); + + /* Copy partition flag to track inheritance properly */ + newClassForm->relispartition = oldClassForm->relispartition; + + CatalogTupleUpdate(pg_class, &oldClassTuple->t_self, oldClassTuple); + CatalogTupleUpdate(pg_class, &newClassTuple->t_self, newClassTuple); + + heap_freetuple(oldClassTuple); + heap_freetuple(newClassTuple); + + /* Now swap index info */ + pg_index = table_open(IndexRelationId, RowExclusiveLock); + + oldIndexTuple = SearchSysCacheCopy1(INDEXRELID, + ObjectIdGetDatum(oldIndexId)); + if (!HeapTupleIsValid(oldIndexTuple)) + elog(ERROR, "could not find tuple for relation %u", oldIndexId); + newIndexTuple = SearchSysCacheCopy1(INDEXRELID, + ObjectIdGetDatum(newIndexId)); + if (!HeapTupleIsValid(newIndexTuple)) + elog(ERROR, "could not find tuple for relation %u", newIndexId); + + oldIndexForm = (Form_pg_index) GETSTRUCT(oldIndexTuple); + newIndexForm = (Form_pg_index) GETSTRUCT(newIndexTuple); + + /* + * Copy constraint flags from the old index. This is safe because the old + * index guaranteed uniqueness. + */ + newIndexForm->indisprimary = oldIndexForm->indisprimary; + oldIndexForm->indisprimary = false; + newIndexForm->indisexclusion = oldIndexForm->indisexclusion; + oldIndexForm->indisexclusion = false; + newIndexForm->indimmediate = oldIndexForm->indimmediate; + oldIndexForm->indimmediate = true; + + /* Mark old index as valid and new as invalid as index_set_state_flags */ + newIndexForm->indisvalid = true; + oldIndexForm->indisvalid = false; + oldIndexForm->indisclustered = false; + + CatalogTupleUpdate(pg_index, &oldIndexTuple->t_self, oldIndexTuple); + CatalogTupleUpdate(pg_index, &newIndexTuple->t_self, newIndexTuple); + + heap_freetuple(oldIndexTuple); + heap_freetuple(newIndexTuple); + + /* + * Move constraints and triggers over to the new index + */ + + constraintOids = get_index_ref_constraints(oldIndexId); + + indexConstraintOid = get_index_constraint(oldIndexId); + + if (OidIsValid(indexConstraintOid)) + constraintOids = lappend_oid(constraintOids, indexConstraintOid); + + pg_constraint = table_open(ConstraintRelationId, RowExclusiveLock); + pg_trigger = table_open(TriggerRelationId, RowExclusiveLock); + + foreach(lc, constraintOids) + { + HeapTuple constraintTuple, + triggerTuple; + Form_pg_constraint conForm; + ScanKeyData key[1]; + SysScanDesc scan; + Oid constraintOid = lfirst_oid(lc); + + /* Move the constraint from the old to the new index */ + constraintTuple = SearchSysCacheCopy1(CONSTROID, + ObjectIdGetDatum(constraintOid)); + if (!HeapTupleIsValid(constraintTuple)) + elog(ERROR, "could not find tuple for constraint %u", constraintOid); + + conForm = ((Form_pg_constraint) GETSTRUCT(constraintTuple)); + + if (conForm->conindid == oldIndexId) + { + conForm->conindid = newIndexId; + + CatalogTupleUpdate(pg_constraint, &constraintTuple->t_self, constraintTuple); + } + + heap_freetuple(constraintTuple); + + /* Search for trigger records */ + ScanKeyInit(&key[0], + Anum_pg_trigger_tgconstraint, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(constraintOid)); + + scan = systable_beginscan(pg_trigger, TriggerConstraintIndexId, true, + NULL, 1, key); + + while (HeapTupleIsValid((triggerTuple = systable_getnext(scan)))) + { + Form_pg_trigger tgForm = (Form_pg_trigger) GETSTRUCT(triggerTuple); + + if (tgForm->tgconstrindid != oldIndexId) + continue; + + /* Make a modifiable copy */ + triggerTuple = heap_copytuple(triggerTuple); + tgForm = (Form_pg_trigger) GETSTRUCT(triggerTuple); + + tgForm->tgconstrindid = newIndexId; + + CatalogTupleUpdate(pg_trigger, &triggerTuple->t_self, triggerTuple); + + heap_freetuple(triggerTuple); + } + + systable_endscan(scan); + } + + /* + * Move comment if any + */ + { + Relation description; + ScanKeyData skey[3]; + SysScanDesc sd; + HeapTuple tuple; + Datum values[Natts_pg_description] = {0}; + bool nulls[Natts_pg_description] = {0}; + bool replaces[Natts_pg_description] = {0}; + + values[Anum_pg_description_objoid - 1] = ObjectIdGetDatum(newIndexId); + replaces[Anum_pg_description_objoid - 1] = true; + + ScanKeyInit(&skey[0], + Anum_pg_description_objoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oldIndexId)); + ScanKeyInit(&skey[1], + Anum_pg_description_classoid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationRelationId)); + ScanKeyInit(&skey[2], + Anum_pg_description_objsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(0)); + + description = table_open(DescriptionRelationId, RowExclusiveLock); + + sd = systable_beginscan(description, DescriptionObjIndexId, true, + NULL, 3, skey); + + while ((tuple = systable_getnext(sd)) != NULL) + { + tuple = heap_modify_tuple(tuple, RelationGetDescr(description), + values, nulls, replaces); + CatalogTupleUpdate(description, &tuple->t_self, tuple); + + break; /* Assume there can be only one match */ + } + + systable_endscan(sd); + table_close(description, NoLock); + } + + /* + * Swap inheritance relationship with parent index + */ + if (get_rel_relispartition(oldIndexId)) + { + List *ancestors = get_partition_ancestors(oldIndexId); + Oid parentIndexRelid = linitial_oid(ancestors); + + DeleteInheritsTuple(oldIndexId, parentIndexRelid); + StoreSingleInheritance(newIndexId, parentIndexRelid, 1); + + list_free(ancestors); + } + + /* + * Move all dependencies of and on the old index to the new one + */ + changeDependenciesOf(RelationRelationId, oldIndexId, newIndexId); + changeDependenciesOn(RelationRelationId, oldIndexId, newIndexId); + + /* + * Copy over statistics from old to new index + */ + { + PgStat_StatTabEntry *tabentry; + + tabentry = pgstat_fetch_stat_tabentry(oldIndexId); + if (tabentry) + { + if (newClassRel->pgstat_info) + { + newClassRel->pgstat_info->t_counts.t_numscans = tabentry->numscans; + newClassRel->pgstat_info->t_counts.t_tuples_returned = tabentry->tuples_returned; + newClassRel->pgstat_info->t_counts.t_tuples_fetched = tabentry->tuples_fetched; + newClassRel->pgstat_info->t_counts.t_blocks_fetched = tabentry->blocks_fetched; + newClassRel->pgstat_info->t_counts.t_blocks_hit = tabentry->blocks_hit; + + /* + * The data will be sent by the next pgstat_report_stat() + * call. + */ + } + } + } + + /* Close relations */ + table_close(pg_class, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); + table_close(pg_constraint, RowExclusiveLock); + table_close(pg_trigger, RowExclusiveLock); + + /* The lock taken previously is not released until the end of transaction */ + relation_close(oldClassRel, NoLock); + relation_close(newClassRel, NoLock); +} + +/* + * index_concurrently_set_dead + * + * Perform the last invalidation stage of DROP INDEX CONCURRENTLY or REINDEX + * CONCURRENTLY before actually dropping the index. After calling this + * function, the index is seen by all the backends as dead. Low-level locks + * taken here are kept until the end of the transaction calling this function. + */ +void +index_concurrently_set_dead(Oid heapId, Oid indexId) +{ + Relation userHeapRelation; + Relation userIndexRelation; + + /* + * No more predicate locks will be acquired on this index, and we're about + * to stop doing inserts into the index which could show conflicts with + * existing predicate locks, so now is the time to move them to the heap + * relation. + */ + userHeapRelation = table_open(heapId, ShareUpdateExclusiveLock); + userIndexRelation = index_open(indexId, ShareUpdateExclusiveLock); + TransferPredicateLocksToHeapRelation(userIndexRelation); + + /* + * Now we are sure that nobody uses the index for queries; they just might + * have it open for updating it. So now we can unset indisready and + * indislive, then wait till nobody could be using it at all anymore. + */ + index_set_state_flags(indexId, INDEX_DROP_SET_DEAD); + + /* + * Invalidate the relcache for the table, so that after this commit all + * sessions will refresh the table's index list. Forgetting just the + * index's relcache entry is not enough. + */ + CacheInvalidateRelcache(userHeapRelation); + + /* + * Close the relations again, though still holding session lock. + */ + table_close(userHeapRelation, NoLock); + index_close(userIndexRelation, NoLock); +} + +/* + * index_constraint_create + * + * Set up a constraint associated with an index. Return the new constraint's + * address. + * + * heapRelation: table owning the index (must be suitably locked by caller) + * indexRelationId: OID of the index + * parentConstraintId: if constraint is on a partition, the OID of the + * constraint in the parent. + * indexInfo: same info executor uses to insert into the index + * constraintName: what it say (generally, should match name of index) + * constraintType: one of CONSTRAINT_PRIMARY, CONSTRAINT_UNIQUE, or + * CONSTRAINT_EXCLUSION + * flags: bitmask that can include any combination of these bits: + * INDEX_CONSTR_CREATE_MARK_AS_PRIMARY: index is a PRIMARY KEY + * INDEX_CONSTR_CREATE_DEFERRABLE: constraint is DEFERRABLE + * INDEX_CONSTR_CREATE_INIT_DEFERRED: constraint is INITIALLY DEFERRED + * INDEX_CONSTR_CREATE_UPDATE_INDEX: update the pg_index row + * INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS: remove existing dependencies + * of index on table's columns + * allow_system_table_mods: allow table to be a system catalog + * is_internal: index is constructed due to internal process + */ +ObjectAddress +index_constraint_create(Relation heapRelation, + Oid indexRelationId, + Oid parentConstraintId, + IndexInfo *indexInfo, + const char *constraintName, + char constraintType, + bits16 constr_flags, + bool allow_system_table_mods, + bool is_internal) +{ + Oid namespaceId = RelationGetNamespace(heapRelation); + ObjectAddress myself, + idxaddr; + Oid conOid; + bool deferrable; + bool initdeferred; + bool mark_as_primary; + bool islocal; + bool noinherit; + int inhcount; + + deferrable = (constr_flags & INDEX_CONSTR_CREATE_DEFERRABLE) != 0; + initdeferred = (constr_flags & INDEX_CONSTR_CREATE_INIT_DEFERRED) != 0; + mark_as_primary = (constr_flags & INDEX_CONSTR_CREATE_MARK_AS_PRIMARY) != 0; + + /* constraint creation support doesn't work while bootstrapping */ + Assert(!IsBootstrapProcessingMode()); + + /* enforce system-table restriction */ + if (!allow_system_table_mods && + IsSystemRelation(heapRelation) && + IsNormalProcessingMode()) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("user-defined indexes on system catalog tables are not supported"))); + + /* primary/unique constraints shouldn't have any expressions */ + if (indexInfo->ii_Expressions && + constraintType != CONSTRAINT_EXCLUSION) + elog(ERROR, "constraints cannot have index expressions"); + + /* + * If we're manufacturing a constraint for a pre-existing index, we need + * to get rid of the existing auto dependencies for the index (the ones + * that index_create() would have made instead of calling this function). + * + * Note: this code would not necessarily do the right thing if the index + * has any expressions or predicate, but we'd never be turning such an + * index into a UNIQUE or PRIMARY KEY constraint. + */ + if (constr_flags & INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS) + deleteDependencyRecordsForClass(RelationRelationId, indexRelationId, + RelationRelationId, DEPENDENCY_AUTO); + + if (OidIsValid(parentConstraintId)) + { + islocal = false; + inhcount = 1; + noinherit = false; + } + else + { + islocal = true; + inhcount = 0; + noinherit = true; + } + + /* + * Construct a pg_constraint entry. + */ + conOid = CreateConstraintEntry(constraintName, + namespaceId, + constraintType, + deferrable, + initdeferred, + true, + parentConstraintId, + RelationGetRelid(heapRelation), + indexInfo->ii_IndexAttrNumbers, + indexInfo->ii_NumIndexKeyAttrs, + indexInfo->ii_NumIndexAttrs, + InvalidOid, /* no domain */ + indexRelationId, /* index OID */ + InvalidOid, /* no foreign key */ + NULL, + NULL, + NULL, + NULL, + 0, + ' ', + ' ', + ' ', + indexInfo->ii_ExclusionOps, + NULL, /* no check constraint */ + NULL, + islocal, + inhcount, + noinherit, + is_internal); + + /* + * Register the index as internally dependent on the constraint. + * + * Note that the constraint has a dependency on the table, so we don't + * need (or want) any direct dependency from the index to the table. + */ + ObjectAddressSet(myself, ConstraintRelationId, conOid); + ObjectAddressSet(idxaddr, RelationRelationId, indexRelationId); + recordDependencyOn(&idxaddr, &myself, DEPENDENCY_INTERNAL); + + /* + * Also, if this is a constraint on a partition, give it partition-type + * dependencies on the parent constraint as well as the table. + */ + if (OidIsValid(parentConstraintId)) + { + ObjectAddress referenced; + + ObjectAddressSet(referenced, ConstraintRelationId, parentConstraintId); + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); + ObjectAddressSet(referenced, RelationRelationId, + RelationGetRelid(heapRelation)); + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); + } + + /* + * If the constraint is deferrable, create the deferred uniqueness + * checking trigger. (The trigger will be given an internal dependency on + * the constraint by CreateTrigger.) + */ + if (deferrable) + { + CreateTrigStmt *trigger; + + trigger = makeNode(CreateTrigStmt); + trigger->trigname = (constraintType == CONSTRAINT_PRIMARY) ? + "PK_ConstraintTrigger" : + "Unique_ConstraintTrigger"; + trigger->relation = NULL; + trigger->funcname = SystemFuncName("unique_key_recheck"); + trigger->args = NIL; + trigger->row = true; + trigger->timing = TRIGGER_TYPE_AFTER; trigger->events = TRIGGER_TYPE_INSERT | TRIGGER_TYPE_UPDATE; trigger->columns = NIL; trigger->whenClause = NULL; @@ -1394,7 +1951,7 @@ index_constraint_create(Relation heapRelation, Form_pg_index indexForm; bool dirty = false; - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); indexTuple = SearchSysCacheCopy1(INDEXRELID, ObjectIdGetDatum(indexRelationId)); @@ -1423,10 +1980,10 @@ index_constraint_create(Relation heapRelation, } heap_freetuple(indexTuple); - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); } - return referenced; + return myself; } /* @@ -1434,9 +1991,14 @@ index_constraint_create(Relation heapRelation, * * NOTE: this routine should now only be called through performDeletion(), * else associated dependencies won't be cleaned up. + * + * If concurrent is true, do a DROP INDEX CONCURRENTLY. If concurrent is + * false but concurrent_lock_mode is true, then do a normal DROP INDEX but + * take a lock for CONCURRENTLY processing. That is used as part of REINDEX + * CONCURRENTLY. */ void -index_drop(Oid indexId, bool concurrent) +index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode) { Oid heapId; Relation userHeapRelation; @@ -1468,8 +2030,8 @@ index_drop(Oid indexId, bool concurrent) * using it.) */ heapId = IndexGetRelation(indexId, false); - lockmode = concurrent ? ShareUpdateExclusiveLock : AccessExclusiveLock; - userHeapRelation = heap_open(heapId, lockmode); + lockmode = (concurrent || concurrent_lock_mode) ? ShareUpdateExclusiveLock : AccessExclusiveLock; + userHeapRelation = table_open(heapId, lockmode); userIndexRelation = index_open(indexId, lockmode); /* @@ -1546,7 +2108,7 @@ index_drop(Oid indexId, bool concurrent) SET_LOCKTAG_RELATION(heaplocktag, heaprelid.dbId, heaprelid.relId); indexrelid = userIndexRelation->rd_lockInfo.lockRelId; - heap_close(userHeapRelation, NoLock); + table_close(userHeapRelation, NoLock); index_close(userIndexRelation, NoLock); /* @@ -1581,38 +2143,10 @@ index_drop(Oid indexId, bool concurrent) * to acquire an exclusive lock on our table. The lock code will * detect deadlock and error out properly. */ - WaitForLockers(heaplocktag, AccessExclusiveLock); - - /* - * No more predicate locks will be acquired on this index, and we're - * about to stop doing inserts into the index which could show - * conflicts with existing predicate locks, so now is the time to move - * them to the heap relation. - */ - userHeapRelation = heap_open(heapId, ShareUpdateExclusiveLock); - userIndexRelation = index_open(indexId, ShareUpdateExclusiveLock); - TransferPredicateLocksToHeapRelation(userIndexRelation); - - /* - * Now we are sure that nobody uses the index for queries; they just - * might have it open for updating it. So now we can unset indisready - * and indislive, then wait till nobody could be using it at all - * anymore. - */ - index_set_state_flags(indexId, INDEX_DROP_SET_DEAD); - - /* - * Invalidate the relcache for the table, so that after this commit - * all sessions will refresh the table's index list. Forgetting just - * the index's relcache entry is not enough. - */ - CacheInvalidateRelcache(userHeapRelation); + WaitForLockers(heaplocktag, AccessExclusiveLock, true); - /* - * Close the relations again, though still holding session lock. - */ - heap_close(userHeapRelation, NoLock); - index_close(userIndexRelation, NoLock); + /* Finish invalidation of index and mark it as dead */ + index_concurrently_set_dead(heapId, indexId); /* * Again, commit the transaction to make the pg_index update visible @@ -1625,7 +2159,7 @@ index_drop(Oid indexId, bool concurrent) * Wait till every transaction that saw the old index state has * finished. */ - WaitForLockers(heaplocktag, AccessExclusiveLock); + WaitForLockers(heaplocktag, AccessExclusiveLock, true); /* * Re-open relations to allow us to complete our actions. @@ -1634,7 +2168,7 @@ index_drop(Oid indexId, bool concurrent) * leave nothing to chance and grab AccessExclusiveLock on the index * before the physical deletion. */ - userHeapRelation = heap_open(heapId, ShareUpdateExclusiveLock); + userHeapRelation = table_open(heapId, ShareUpdateExclusiveLock); userIndexRelation = index_open(indexId, AccessExclusiveLock); } else @@ -1661,7 +2195,7 @@ index_drop(Oid indexId, bool concurrent) /* * fix INDEX relation, and check for expressional index */ - indexRelation = heap_open(IndexRelationId, RowExclusiveLock); + indexRelation = table_open(IndexRelationId, RowExclusiveLock); tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId)); if (!HeapTupleIsValid(tuple)) @@ -1673,7 +2207,7 @@ index_drop(Oid indexId, bool concurrent) CatalogTupleDelete(indexRelation, &tuple->t_self); ReleaseSysCache(tuple); - heap_close(indexRelation, RowExclusiveLock); + table_close(indexRelation, RowExclusiveLock); /* * if it has any expression columns, we might have stored statistics about @@ -1710,7 +2244,7 @@ index_drop(Oid indexId, bool concurrent) /* * Close owning rel, but keep lock */ - heap_close(userHeapRelation, NoLock); + table_close(userHeapRelation, NoLock); /* * Release the session locks before we go. @@ -1740,7 +2274,7 @@ index_drop(Oid indexId, bool concurrent) IndexInfo * BuildIndexInfo(Relation index) { - IndexInfo *ii = makeNode(IndexInfo); + IndexInfo *ii; Form_pg_index indexStruct = index->rd_index; int i; int numAtts; @@ -1750,21 +2284,23 @@ BuildIndexInfo(Relation index) if (numAtts < 1 || numAtts > INDEX_MAX_KEYS) elog(ERROR, "invalid indnatts %d for index %u", numAtts, RelationGetRelid(index)); - ii->ii_NumIndexAttrs = numAtts; - ii->ii_NumIndexKeyAttrs = indexStruct->indnkeyatts; - Assert(ii->ii_NumIndexKeyAttrs != 0); - Assert(ii->ii_NumIndexKeyAttrs <= ii->ii_NumIndexAttrs); - - for (i = 0; i < numAtts; i++) - ii->ii_KeyAttrNumbers[i] = indexStruct->indkey.values[i]; - /* fetch any expressions needed for expressional indexes */ - ii->ii_Expressions = RelationGetIndexExpressions(index); - ii->ii_ExpressionsState = NIL; + /* + * Create the node, fetching any expressions needed for expressional + * indexes and index predicate if any. + */ + ii = makeIndexInfo(indexStruct->indnatts, + indexStruct->indnkeyatts, + index->rd_rel->relam, + RelationGetIndexExpressions(index), + RelationGetIndexPredicate(index), + indexStruct->indisunique, + indexStruct->indisready, + false); - /* fetch index predicate if any */ - ii->ii_Predicate = RelationGetIndexPredicate(index); - ii->ii_PredicateState = NULL; + /* fill in attribute numbers */ + for (i = 0; i < numAtts; i++) + ii->ii_IndexAttrNumbers[i] = indexStruct->indkey.values[i]; /* fetch exclusion constraint info if any */ if (indexStruct->indisexclusion) @@ -1774,30 +2310,6 @@ BuildIndexInfo(Relation index) &ii->ii_ExclusionProcs, &ii->ii_ExclusionStrats); } - else - { - ii->ii_ExclusionOps = NULL; - ii->ii_ExclusionProcs = NULL; - ii->ii_ExclusionStrats = NULL; - } - - /* other info */ - ii->ii_Unique = indexStruct->indisunique; - ii->ii_ReadyForInserts = IndexIsReady(indexStruct); - /* assume not doing speculative insertion for now */ - ii->ii_UniqueOps = NULL; - ii->ii_UniqueProcs = NULL; - ii->ii_UniqueStrats = NULL; - - /* initialize index-build state to default */ - ii->ii_Concurrent = false; - ii->ii_BrokenHotChain = false; - ii->ii_ParallelWorkers = 0; - - /* set up for possible use by index AM */ - ii->ii_Am = index->rd_rel->relam; - ii->ii_AmCache = NULL; - ii->ii_Context = CurrentMemoryContext; return ii; } @@ -1818,7 +2330,7 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, Oid *opfamilies1, Oid *opfamilies2, AttrNumber *attmap, int maplen) { - int i; + int i; if (info1->ii_Unique != info2->ii_Unique) return false; @@ -1831,6 +2343,10 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, if (info1->ii_NumIndexAttrs != info2->ii_NumIndexAttrs) return false; + /* and same number of key attributes */ + if (info1->ii_NumIndexKeyAttrs != info2->ii_NumIndexKeyAttrs) + return false; + /* * and columns match through the attribute map (actual attribute numbers * might differ!) Note that this implies that index columns that are @@ -1839,15 +2355,19 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, */ for (i = 0; i < info1->ii_NumIndexAttrs; i++) { - if (maplen < info2->ii_KeyAttrNumbers[i]) + if (maplen < info2->ii_IndexAttrNumbers[i]) elog(ERROR, "incorrect attribute map"); /* ignore expressions at this stage */ - if ((info1->ii_KeyAttrNumbers[i] != InvalidAttrNumber) && - (attmap[info2->ii_KeyAttrNumbers[i] - 1] != - info1->ii_KeyAttrNumbers[i])) + if ((info1->ii_IndexAttrNumbers[i] != InvalidAttrNumber) && + (attmap[info2->ii_IndexAttrNumbers[i] - 1] != + info1->ii_IndexAttrNumbers[i])) return false; + /* collation and opfamily is not valid for including columns */ + if (i >= info1->ii_NumIndexKeyAttrs) + continue; + if (collations1[i] != collations2[i]) return false; if (opfamilies1[i] != opfamilies2[i]) @@ -1862,8 +2382,8 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, return false; if (info1->ii_Expressions != NIL) { - bool found_whole_row; - Node *mapped; + bool found_whole_row; + Node *mapped; mapped = map_variable_attnos((Node *) info2->ii_Expressions, 1, 0, attmap, maplen, @@ -1886,8 +2406,8 @@ CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, return false; if (info1->ii_Predicate != NULL) { - bool found_whole_row; - Node *mapped; + bool found_whole_row; + Node *mapped; mapped = map_variable_attnos((Node *) info2->ii_Predicate, 1, 0, attmap, maplen, @@ -2006,11 +2526,13 @@ FormIndexDatum(IndexInfo *indexInfo, for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { - int keycol = indexInfo->ii_KeyAttrNumbers[i]; + int keycol = indexInfo->ii_IndexAttrNumbers[i]; Datum iDatum; bool isNull; - if (keycol != 0) + if (keycol < 0) + iDatum = slot_getsysattr(slot, keycol, &isNull); + else if (keycol != 0) { /* * Plain index column; get the value we need directly from the @@ -2028,7 +2550,7 @@ FormIndexDatum(IndexInfo *indexInfo, iDatum = ExecEvalExprSwitchContext((ExprState *) lfirst(indexpr_item), GetPerTupleExprContext(estate), &isNull); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(indexInfo->ii_ExpressionsState, indexpr_item); } values[i] = iDatum; isnull[i] = isNull; @@ -2092,14 +2614,14 @@ index_update_stats(Relation rel, * It is safe to use a non-transactional update even though our * transaction could still fail before committing. Setting relhasindex * true is safe even if there are no indexes (VACUUM will eventually fix - * it). And of course the new relpages and - * reltuples counts are correct regardless. However, we don't want to - * change relpages (or relallvisible) if the caller isn't providing an - * updated reltuples count, because that would bollix the - * reltuples/relpages ratio which is what's really important. + * it). And of course the new relpages and reltuples counts are correct + * regardless. However, we don't want to change relpages (or + * relallvisible) if the caller isn't providing an updated reltuples + * count, because that would bollix the reltuples/relpages ratio which is + * what's really important. */ - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); /* * Make a copy of the tuple to update. Normally we use the syscache, but @@ -2110,18 +2632,18 @@ index_update_stats(Relation rel, ReindexIsProcessingHeap(RelationRelationId)) { /* don't assume syscache will work */ - HeapScanDesc pg_class_scan; + TableScanDesc pg_class_scan; ScanKeyData key[1]; ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_class_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); - pg_class_scan = heap_beginscan_catalog(pg_class, 1, key); + pg_class_scan = table_beginscan_catalog(pg_class, 1, key); tuple = heap_getnext(pg_class_scan, ForwardScanDirection); tuple = heap_copytuple(tuple); - heap_endscan(pg_class_scan); + table_endscan(pg_class_scan); } else { @@ -2188,7 +2710,7 @@ index_update_stats(Relation rel, heap_freetuple(tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); } @@ -2201,13 +2723,9 @@ index_update_stats(Relation rel, * entries of the index and heap relation as needed, using statistics * returned by ambuild as well as data passed by the caller. * - * isprimary tells whether to mark the index as a primary-key index. * isreindex indicates we are recreating a previously-existing index. * parallel indicates if parallelism may be useful. * - * Note: when reindexing an existing index, isprimary can be false even if - * the index is a PK; it's already properly marked and need not be re-marked. - * * Note: before Postgres 8.2, the passed-in heap and index Relations * were automatically closed by this routine. This is no longer the case. * The caller opened 'em, and the caller should close 'em. @@ -2216,7 +2734,6 @@ void index_build(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, - bool isprimary, bool isreindex, bool parallel) { @@ -2229,9 +2746,9 @@ index_build(Relation heapRelation, * sanity checks */ Assert(RelationIsValid(indexRelation)); - Assert(PointerIsValid(indexRelation->rd_amroutine)); - Assert(PointerIsValid(indexRelation->rd_amroutine->ambuild)); - Assert(PointerIsValid(indexRelation->rd_amroutine->ambuildempty)); + Assert(PointerIsValid(indexRelation->rd_indam)); + Assert(PointerIsValid(indexRelation->rd_indam->ambuild)); + Assert(PointerIsValid(indexRelation->rd_indam->ambuildempty)); /* * Determine worker process details for parallel CREATE INDEX. Currently, @@ -2269,11 +2786,30 @@ index_build(Relation heapRelation, save_sec_context | SECURITY_RESTRICTED_OPERATION); save_nestlevel = NewGUCNestLevel(); + /* Set up initial progress report status */ + { + const int index[] = { + PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_SUBPHASE, + PROGRESS_CREATEIDX_TUPLES_DONE, + PROGRESS_CREATEIDX_TUPLES_TOTAL, + PROGRESS_SCAN_BLOCKS_DONE, + PROGRESS_SCAN_BLOCKS_TOTAL + }; + const int64 val[] = { + PROGRESS_CREATEIDX_PHASE_BUILD, + PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE, + 0, 0, 0, 0 + }; + + pgstat_progress_update_multi_param(6, index, val); + } + /* * Call the access method's build procedure */ - stats = indexRelation->rd_amroutine->ambuild(heapRelation, indexRelation, - indexInfo); + stats = indexRelation->rd_indam->ambuild(heapRelation, indexRelation, + indexInfo); Assert(PointerIsValid(stats)); /* @@ -2288,642 +2824,95 @@ index_build(Relation heapRelation, { RelationOpenSmgr(indexRelation); smgrcreate(indexRelation->rd_smgr, INIT_FORKNUM, false); - indexRelation->rd_amroutine->ambuildempty(indexRelation); - } - - /* - * If we found any potentially broken HOT chains, mark the index as not - * being usable until the current transaction is below the event horizon. - * See src/backend/access/heap/README.HOT for discussion. Also set this - * if early pruning/vacuuming is enabled for the heap relation. While it - * might become safe to use the index earlier based on actual cleanup - * activity and other active transactions, the test for that would be much - * more complex and would require some form of blocking, so keep it simple - * and fast by just using the current transaction. - * - * However, when reindexing an existing index, we should do nothing here. - * Any HOT chains that are broken with respect to the index must predate - * the index's original creation, so there is no need to change the - * index's usability horizon. Moreover, we *must not* try to change the - * index's pg_index entry while reindexing pg_index itself, and this - * optimization nicely prevents that. The more complex rules needed for a - * reindex are handled separately after this function returns. - * - * We also need not set indcheckxmin during a concurrent index build, - * because we won't set indisvalid true until all transactions that care - * about the broken HOT chains or early pruning/vacuuming are gone. - * - * Therefore, this code path can only be taken during non-concurrent - * CREATE INDEX. Thus the fact that heap_update will set the pg_index - * tuple's xmin doesn't matter, because that tuple was created in the - * current transaction anyway. That also means we don't need to worry - * about any concurrent readers of the tuple; no other transaction can see - * it yet. - */ - if ((indexInfo->ii_BrokenHotChain || EarlyPruningEnabled(heapRelation)) && - !isreindex && - !indexInfo->ii_Concurrent) - { - Oid indexId = RelationGetRelid(indexRelation); - Relation pg_index; - HeapTuple indexTuple; - Form_pg_index indexForm; - - pg_index = heap_open(IndexRelationId, RowExclusiveLock); - - indexTuple = SearchSysCacheCopy1(INDEXRELID, - ObjectIdGetDatum(indexId)); - if (!HeapTupleIsValid(indexTuple)) - elog(ERROR, "cache lookup failed for index %u", indexId); - indexForm = (Form_pg_index) GETSTRUCT(indexTuple); - - /* If it's a new index, indcheckxmin shouldn't be set ... */ - Assert(!indexForm->indcheckxmin); - - indexForm->indcheckxmin = true; - CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple); - - heap_freetuple(indexTuple); - heap_close(pg_index, RowExclusiveLock); - } - - /* - * Update heap and index pg_class rows - */ - index_update_stats(heapRelation, - true, - stats->heap_tuples); - - index_update_stats(indexRelation, - false, - stats->index_tuples); - - /* Make the updated catalog row versions visible */ - CommandCounterIncrement(); - - /* - * If it's for an exclusion constraint, make a second pass over the heap - * to verify that the constraint is satisfied. We must not do this until - * the index is fully valid. (Broken HOT chains shouldn't matter, though; - * see comments for IndexCheckExclusion.) - */ - if (indexInfo->ii_ExclusionOps != NULL) - IndexCheckExclusion(heapRelation, indexRelation, indexInfo); - - /* Roll back any GUC changes executed by index functions */ - AtEOXact_GUC(false, save_nestlevel); - - /* Restore userid and security context */ - SetUserIdAndSecContext(save_userid, save_sec_context); -} - - -/* - * IndexBuildHeapScan - scan the heap relation to find tuples to be indexed - * - * This is called back from an access-method-specific index build procedure - * after the AM has done whatever setup it needs. The parent heap relation - * is scanned to find tuples that should be entered into the index. Each - * such tuple is passed to the AM's callback routine, which does the right - * things to add it to the new index. After we return, the AM's index - * build procedure does whatever cleanup it needs. - * - * The total count of live heap tuples is returned. This is for updating - * pg_class statistics. (It's annoying not to be able to do that here, but we - * want to merge that update with others; see index_update_stats.) Note that - * the index AM itself must keep track of the number of index tuples; we don't - * do so here because the AM might reject some of the tuples for its own - * reasons, such as being unable to store NULLs. - * - * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect - * any potentially broken HOT chains. Currently, we set this if there are - * any RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without - * trying very hard to detect whether they're really incompatible with the - * chain tip. - */ -double -IndexBuildHeapScan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool allow_sync, - IndexBuildCallback callback, - void *callback_state, - HeapScanDesc scan) -{ - return IndexBuildHeapRangeScan(heapRelation, indexRelation, - indexInfo, allow_sync, - false, - 0, InvalidBlockNumber, - callback, callback_state, scan); -} - -/* - * As above, except that instead of scanning the complete heap, only the given - * number of blocks are scanned. Scan to end-of-rel can be signalled by - * passing InvalidBlockNumber as numblocks. Note that restricting the range - * to scan cannot be done when requesting syncscan. - * - * When "anyvisible" mode is requested, all tuples visible to any transaction - * are indexed and counted as live, including those inserted or deleted by - * transactions that are still in progress. - */ -double -IndexBuildHeapRangeScan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool allow_sync, - bool anyvisible, - BlockNumber start_blockno, - BlockNumber numblocks, - IndexBuildCallback callback, - void *callback_state, - HeapScanDesc scan) -{ - bool is_system_catalog; - bool checking_uniqueness; - HeapTuple heapTuple; - Datum values[INDEX_MAX_KEYS]; - bool isnull[INDEX_MAX_KEYS]; - double reltuples; - ExprState *predicate; - TupleTableSlot *slot; - EState *estate; - ExprContext *econtext; - Snapshot snapshot; - bool need_unregister_snapshot = false; - TransactionId OldestXmin; - BlockNumber root_blkno = InvalidBlockNumber; - OffsetNumber root_offsets[MaxHeapTuplesPerPage]; - - /* - * sanity checks - */ - Assert(OidIsValid(indexRelation->rd_rel->relam)); - - /* Remember if it's a system catalog */ - is_system_catalog = IsSystemRelation(heapRelation); - - /* See whether we're verifying uniqueness/exclusion properties */ - checking_uniqueness = (indexInfo->ii_Unique || - indexInfo->ii_ExclusionOps != NULL); - - /* - * "Any visible" mode is not compatible with uniqueness checks; make sure - * only one of those is requested. - */ - Assert(!(anyvisible && checking_uniqueness)); - - /* - * Need an EState for evaluation of index expressions and partial-index - * predicates. Also a slot to hold the current tuple. - */ - estate = CreateExecutorState(); - econtext = GetPerTupleExprContext(estate); - slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); - - /* Arrange for econtext's scan tuple to be the tuple under test */ - econtext->ecxt_scantuple = slot; - - /* Set up execution state for predicate, if any. */ - predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate); - - /* - * Prepare for scan of the base relation. In a normal index build, we use - * SnapshotAny because we must retrieve all tuples and do our own time - * qual checks (because we have to index RECENTLY_DEAD tuples). In a - * concurrent build, or during bootstrap, we take a regular MVCC snapshot - * and index whatever's live according to that. - */ - OldestXmin = InvalidTransactionId; - - /* okay to ignore lazy VACUUMs here */ - if (!IsBootstrapProcessingMode() && !indexInfo->ii_Concurrent) - OldestXmin = GetOldestXmin(heapRelation, PROCARRAY_FLAGS_VACUUM); - - if (!scan) - { - /* - * Serial index build. - * - * Must begin our own heap scan in this case. We may also need to - * register a snapshot whose lifetime is under our direct control. - */ - if (!TransactionIdIsValid(OldestXmin)) - { - snapshot = RegisterSnapshot(GetTransactionSnapshot()); - need_unregister_snapshot = true; - } - else - snapshot = SnapshotAny; - - scan = heap_beginscan_strat(heapRelation, /* relation */ - snapshot, /* snapshot */ - 0, /* number of keys */ - NULL, /* scan key */ - true, /* buffer access strategy OK */ - allow_sync); /* syncscan OK? */ - } - else - { - /* - * Parallel index build. - * - * Parallel case never registers/unregisters own snapshot. Snapshot - * is taken from parallel heap scan, and is SnapshotAny or an MVCC - * snapshot, based on same criteria as serial case. - */ - Assert(!IsBootstrapProcessingMode()); - Assert(allow_sync); - snapshot = scan->rs_snapshot; - } - - /* - * Must call GetOldestXmin() with SnapshotAny. Should never call - * GetOldestXmin() with MVCC snapshot. (It's especially worth checking - * this for parallel builds, since ambuild routines that support parallel - * builds must work these details out for themselves.) - */ - Assert(snapshot == SnapshotAny || IsMVCCSnapshot(snapshot)); - Assert(snapshot == SnapshotAny ? TransactionIdIsValid(OldestXmin) : - !TransactionIdIsValid(OldestXmin)); - Assert(snapshot == SnapshotAny || !anyvisible); - - /* set our scan endpoints */ - if (!allow_sync) - heap_setscanlimits(scan, start_blockno, numblocks); - else - { - /* syncscan can only be requested on whole relation */ - Assert(start_blockno == 0); - Assert(numblocks == InvalidBlockNumber); - } - - reltuples = 0; - - /* - * Scan all tuples in the base relation. - */ - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - bool tupleIsAlive; - - CHECK_FOR_INTERRUPTS(); - - /* - * When dealing with a HOT-chain of updated tuples, we want to index - * the values of the live tuple (if any), but index it under the TID - * of the chain's root tuple. This approach is necessary to preserve - * the HOT-chain structure in the heap. So we need to be able to find - * the root item offset for every tuple that's in a HOT-chain. When - * first reaching a new page of the relation, call - * heap_get_root_tuples() to build a map of root item offsets on the - * page. - * - * It might look unsafe to use this information across buffer - * lock/unlock. However, we hold ShareLock on the table so no - * ordinary insert/update/delete should occur; and we hold pin on the - * buffer continuously while visiting the page, so no pruning - * operation can occur either. - * - * Also, although our opinions about tuple liveness could change while - * we scan the page (due to concurrent transaction commits/aborts), - * the chain root locations won't, so this info doesn't need to be - * rebuilt after waiting for another transaction. - * - * Note the implied assumption that there is no more than one live - * tuple per HOT-chain --- else we could create more than one index - * entry pointing to the same root tuple. - */ - if (scan->rs_cblock != root_blkno) - { - Page page = BufferGetPage(scan->rs_cbuf); - - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - heap_get_root_tuples(page, root_offsets); - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - - root_blkno = scan->rs_cblock; - } - - if (snapshot == SnapshotAny) - { - /* do our own time qual check */ - bool indexIt; - TransactionId xwait; - - recheck: - - /* - * We could possibly get away with not locking the buffer here, - * since caller should hold ShareLock on the relation, but let's - * be conservative about it. (This remark is still correct even - * with HOT-pruning: our pin on the buffer prevents pruning.) - */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - - /* - * The criteria for counting a tuple as live in this block need to - * match what analyze.c's acquire_sample_rows() does, otherwise - * CREATE INDEX and ANALYZE may produce wildly different reltuples - * values, e.g. when there are many recently-dead tuples. - */ - switch (HeapTupleSatisfiesVacuum(heapTuple, OldestXmin, - scan->rs_cbuf)) - { - case HEAPTUPLE_DEAD: - /* Definitely dead, we can ignore it */ - indexIt = false; - tupleIsAlive = false; - break; - case HEAPTUPLE_LIVE: - /* Normal case, index and unique-check it */ - indexIt = true; - tupleIsAlive = true; - /* Count it as live, too */ - reltuples += 1; - break; - case HEAPTUPLE_RECENTLY_DEAD: - - /* - * If tuple is recently deleted then we must index it - * anyway to preserve MVCC semantics. (Pre-existing - * transactions could try to use the index after we finish - * building it, and may need to see such tuples.) - * - * However, if it was HOT-updated then we must only index - * the live tuple at the end of the HOT-chain. Since this - * breaks semantics for pre-existing snapshots, mark the - * index as unusable for them. - * - * We don't count recently-dead tuples in reltuples, even - * if we index them; see acquire_sample_rows(). - */ - if (HeapTupleIsHotUpdated(heapTuple)) - { - indexIt = false; - /* mark the index as unsafe for old snapshots */ - indexInfo->ii_BrokenHotChain = true; - } - else - indexIt = true; - /* In any case, exclude the tuple from unique-checking */ - tupleIsAlive = false; - break; - case HEAPTUPLE_INSERT_IN_PROGRESS: - - /* - * In "anyvisible" mode, this tuple is visible and we - * don't need any further checks. - */ - if (anyvisible) - { - indexIt = true; - tupleIsAlive = true; - reltuples += 1; - break; - } - - /* - * Since caller should hold ShareLock or better, normally - * the only way to see this is if it was inserted earlier - * in our own transaction. However, it can happen in - * system catalogs, since we tend to release write lock - * before commit there. Give a warning if neither case - * applies. - */ - xwait = HeapTupleHeaderGetXmin(heapTuple->t_data); - if (!TransactionIdIsCurrentTransactionId(xwait)) - { - if (!is_system_catalog) - elog(WARNING, "concurrent insert in progress within table \"%s\"", - RelationGetRelationName(heapRelation)); - - /* - * If we are performing uniqueness checks, indexing - * such a tuple could lead to a bogus uniqueness - * failure. In that case we wait for the inserting - * transaction to finish and check again. - */ - if (checking_uniqueness) - { - /* - * Must drop the lock on the buffer before we wait - */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - XactLockTableWait(xwait, heapRelation, - &heapTuple->t_self, - XLTW_InsertIndexUnique); - CHECK_FOR_INTERRUPTS(); - goto recheck; - } - } - else - { - /* - * For consistency with acquire_sample_rows(), count - * HEAPTUPLE_INSERT_IN_PROGRESS tuples as live only - * when inserted by our own transaction. - */ - reltuples += 1; - } - - /* - * We must index such tuples, since if the index build - * commits then they're good. - */ - indexIt = true; - tupleIsAlive = true; - break; - case HEAPTUPLE_DELETE_IN_PROGRESS: - - /* - * As with INSERT_IN_PROGRESS case, this is unexpected - * unless it's our own deletion or a system catalog; but - * in anyvisible mode, this tuple is visible. - */ - if (anyvisible) - { - indexIt = true; - tupleIsAlive = false; - reltuples += 1; - break; - } - - xwait = HeapTupleHeaderGetUpdateXid(heapTuple->t_data); - if (!TransactionIdIsCurrentTransactionId(xwait)) - { - if (!is_system_catalog) - elog(WARNING, "concurrent delete in progress within table \"%s\"", - RelationGetRelationName(heapRelation)); - - /* - * If we are performing uniqueness checks, assuming - * the tuple is dead could lead to missing a - * uniqueness violation. In that case we wait for the - * deleting transaction to finish and check again. - * - * Also, if it's a HOT-updated tuple, we should not - * index it but rather the live tuple at the end of - * the HOT-chain. However, the deleting transaction - * could abort, possibly leaving this tuple as live - * after all, in which case it has to be indexed. The - * only way to know what to do is to wait for the - * deleting transaction to finish and check again. - */ - if (checking_uniqueness || - HeapTupleIsHotUpdated(heapTuple)) - { - /* - * Must drop the lock on the buffer before we wait - */ - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - XactLockTableWait(xwait, heapRelation, - &heapTuple->t_self, - XLTW_InsertIndexUnique); - CHECK_FOR_INTERRUPTS(); - goto recheck; - } - - /* - * Otherwise index it but don't check for uniqueness, - * the same as a RECENTLY_DEAD tuple. - */ - indexIt = true; - - /* - * Count HEAPTUPLE_DELETE_IN_PROGRESS tuples as live, - * if they were not deleted by the current - * transaction. That's what acquire_sample_rows() - * does, and we want the behavior to be consistent. - */ - reltuples += 1; - } - else if (HeapTupleIsHotUpdated(heapTuple)) - { - /* - * It's a HOT-updated tuple deleted by our own xact. - * We can assume the deletion will commit (else the - * index contents don't matter), so treat the same as - * RECENTLY_DEAD HOT-updated tuples. - */ - indexIt = false; - /* mark the index as unsafe for old snapshots */ - indexInfo->ii_BrokenHotChain = true; - } - else - { - /* - * It's a regular tuple deleted by our own xact. Index - * it, but don't check for uniqueness nor count in - * reltuples, the same as a RECENTLY_DEAD tuple. - */ - indexIt = true; - } - /* In any case, exclude the tuple from unique-checking */ - tupleIsAlive = false; - break; - default: - elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); - indexIt = tupleIsAlive = false; /* keep compiler quiet */ - break; - } - - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - - if (!indexIt) - continue; - } - else - { - /* heap_getnext did the time qual check */ - tupleIsAlive = true; - } - - MemoryContextReset(econtext->ecxt_per_tuple_memory); - - /* Set up for predicate or expression evaluation */ - ExecStoreTuple(heapTuple, slot, InvalidBuffer, false); + indexRelation->rd_indam->ambuildempty(indexRelation); + } - /* - * In a partial index, discard tuples that don't satisfy the - * predicate. - */ - if (predicate != NULL) - { - if (!ExecQual(predicate, econtext)) - continue; - } + /* + * If we found any potentially broken HOT chains, mark the index as not + * being usable until the current transaction is below the event horizon. + * See src/backend/access/heap/README.HOT for discussion. Also set this + * if early pruning/vacuuming is enabled for the heap relation. While it + * might become safe to use the index earlier based on actual cleanup + * activity and other active transactions, the test for that would be much + * more complex and would require some form of blocking, so keep it simple + * and fast by just using the current transaction. + * + * However, when reindexing an existing index, we should do nothing here. + * Any HOT chains that are broken with respect to the index must predate + * the index's original creation, so there is no need to change the + * index's usability horizon. Moreover, we *must not* try to change the + * index's pg_index entry while reindexing pg_index itself, and this + * optimization nicely prevents that. The more complex rules needed for a + * reindex are handled separately after this function returns. + * + * We also need not set indcheckxmin during a concurrent index build, + * because we won't set indisvalid true until all transactions that care + * about the broken HOT chains or early pruning/vacuuming are gone. + * + * Therefore, this code path can only be taken during non-concurrent + * CREATE INDEX. Thus the fact that heap_update will set the pg_index + * tuple's xmin doesn't matter, because that tuple was created in the + * current transaction anyway. That also means we don't need to worry + * about any concurrent readers of the tuple; no other transaction can see + * it yet. + */ + if ((indexInfo->ii_BrokenHotChain || EarlyPruningEnabled(heapRelation)) && + !isreindex && + !indexInfo->ii_Concurrent) + { + Oid indexId = RelationGetRelid(indexRelation); + Relation pg_index; + HeapTuple indexTuple; + Form_pg_index indexForm; - /* - * For the current heap tuple, extract all the attributes we use in - * this index, and note which are null. This also performs evaluation - * of any expressions needed. - */ - FormIndexDatum(indexInfo, - slot, - estate, - values, - isnull); + pg_index = table_open(IndexRelationId, RowExclusiveLock); - /* - * You'd think we should go ahead and build the index tuple here, but - * some index AMs want to do further processing on the data first. So - * pass the values[] and isnull[] arrays, instead. - */ + indexTuple = SearchSysCacheCopy1(INDEXRELID, + ObjectIdGetDatum(indexId)); + if (!HeapTupleIsValid(indexTuple)) + elog(ERROR, "cache lookup failed for index %u", indexId); + indexForm = (Form_pg_index) GETSTRUCT(indexTuple); - if (HeapTupleIsHeapOnly(heapTuple)) - { - /* - * For a heap-only tuple, pretend its TID is that of the root. See - * src/backend/access/heap/README.HOT for discussion. - */ - HeapTupleData rootTuple; - OffsetNumber offnum; + /* If it's a new index, indcheckxmin shouldn't be set ... */ + Assert(!indexForm->indcheckxmin); - rootTuple = *heapTuple; - offnum = ItemPointerGetOffsetNumber(&heapTuple->t_self); + indexForm->indcheckxmin = true; + CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple); - if (!OffsetNumberIsValid(root_offsets[offnum - 1])) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg_internal("failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"", - ItemPointerGetBlockNumber(&heapTuple->t_self), - offnum, - RelationGetRelationName(heapRelation)))); - - ItemPointerSetOffsetNumber(&rootTuple.t_self, - root_offsets[offnum - 1]); - - /* Call the AM's callback routine to process the tuple */ - callback(indexRelation, &rootTuple, values, isnull, tupleIsAlive, - callback_state); - } - else - { - /* Call the AM's callback routine to process the tuple */ - callback(indexRelation, heapTuple, values, isnull, tupleIsAlive, - callback_state); - } + heap_freetuple(indexTuple); + table_close(pg_index, RowExclusiveLock); } - heap_endscan(scan); + /* + * Update heap and index pg_class rows + */ + index_update_stats(heapRelation, + true, + stats->heap_tuples); - /* we can now forget our snapshot, if set and registered by us */ - if (need_unregister_snapshot) - UnregisterSnapshot(snapshot); + index_update_stats(indexRelation, + false, + stats->index_tuples); - ExecDropSingleTupleTableSlot(slot); + /* Make the updated catalog row versions visible */ + CommandCounterIncrement(); - FreeExecutorState(estate); + /* + * If it's for an exclusion constraint, make a second pass over the heap + * to verify that the constraint is satisfied. We must not do this until + * the index is fully valid. (Broken HOT chains shouldn't matter, though; + * see comments for IndexCheckExclusion.) + */ + if (indexInfo->ii_ExclusionOps != NULL) + IndexCheckExclusion(heapRelation, indexRelation, indexInfo); - /* These may have been pointing to the now-gone estate */ - indexInfo->ii_ExpressionsState = NIL; - indexInfo->ii_PredicateState = NULL; + /* Roll back any GUC changes executed by index functions */ + AtEOXact_GUC(false, save_nestlevel); - return reltuples; + /* Restore userid and security context */ + SetUserIdAndSecContext(save_userid, save_sec_context); } - /* * IndexCheckExclusion - verify that a new exclusion constraint is satisfied * @@ -2941,8 +2930,7 @@ IndexCheckExclusion(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo) { - HeapScanDesc scan; - HeapTuple heapTuple; + TableScanDesc scan; Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; ExprState *predicate; @@ -2965,7 +2953,7 @@ IndexCheckExclusion(Relation heapRelation, */ estate = CreateExecutorState(); econtext = GetPerTupleExprContext(estate); - slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); + slot = table_slot_create(heapRelation, NULL); /* Arrange for econtext's scan tuple to be the tuple under test */ econtext->ecxt_scantuple = slot; @@ -2977,22 +2965,17 @@ IndexCheckExclusion(Relation heapRelation, * Scan all live tuples in the base relation. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan_strat(heapRelation, /* relation */ - snapshot, /* snapshot */ - 0, /* number of keys */ - NULL, /* scan key */ - true, /* buffer access strategy OK */ - true); /* syncscan OK */ - - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + scan = table_beginscan_strat(heapRelation, /* relation */ + snapshot, /* snapshot */ + 0, /* number of keys */ + NULL, /* scan key */ + true, /* buffer access strategy OK */ + true); /* syncscan OK */ + + while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) { CHECK_FOR_INTERRUPTS(); - MemoryContextReset(econtext->ecxt_per_tuple_memory); - - /* Set up for predicate or expression evaluation */ - ExecStoreTuple(heapTuple, slot, InvalidBuffer, false); - /* * In a partial index, ignore tuples that don't satisfy the predicate. */ @@ -3016,11 +2999,13 @@ IndexCheckExclusion(Relation heapRelation, */ check_exclusion_constraint(heapRelation, indexRelation, indexInfo, - &(heapTuple->t_self), values, isnull, + &(slot->tts_tid), values, isnull, estate, true); + + MemoryContextReset(econtext->ecxt_per_tuple_memory); } - heap_endscan(scan); + table_endscan(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(slot); @@ -3046,7 +3031,7 @@ IndexCheckExclusion(Relation heapRelation, * incompatible HOT update done to it. We now build the index normally via * index_build(), while holding a weak lock that allows concurrent * insert/update/delete. Also, we index only tuples that are valid - * as of the start of the scan (see IndexBuildHeapScan), whereas a normal + * as of the start of the scan (see table_index_build_scan), whereas a normal * build takes care to include recently-dead tuples. This is OK because * we won't mark the index valid until all transactions that might be able * to see those tuples are gone. The reason for doing that is to avoid @@ -3103,13 +3088,29 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) indexRelation; IndexInfo *indexInfo; IndexVacuumInfo ivinfo; - v_i_state state; + ValidateIndexState state; Oid save_userid; int save_sec_context; int save_nestlevel; + { + const int index[] = { + PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_TUPLES_DONE, + PROGRESS_CREATEIDX_TUPLES_TOTAL, + PROGRESS_SCAN_BLOCKS_DONE, + PROGRESS_SCAN_BLOCKS_TOTAL + }; + const int64 val[] = { + PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN, + 0, 0, 0, 0 + }; + + pgstat_progress_update_multi_param(5, index, val); + } + /* Open and lock the parent heap relation */ - heapRelation = heap_open(heapId, ShareUpdateExclusiveLock); + heapRelation = table_open(heapId, ShareUpdateExclusiveLock); /* And the target index relation */ indexRelation = index_open(indexId, RowExclusiveLock); @@ -3138,6 +3139,7 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) */ ivinfo.index = indexRelation; ivinfo.analyze_only = false; + ivinfo.report_progress = true; ivinfo.estimated_count = true; ivinfo.message_level = DEBUG2; ivinfo.num_heap_tuples = heapRelation->rd_rel->reltuples; @@ -3155,20 +3157,36 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) NULL, false); state.htups = state.itups = state.tups_inserted = 0; + /* ambulkdelete updates progress metrics */ (void) index_bulk_delete(&ivinfo, NULL, validate_index_callback, (void *) &state); /* Execute the sort */ + { + const int index[] = { + PROGRESS_CREATEIDX_PHASE, + PROGRESS_SCAN_BLOCKS_DONE, + PROGRESS_SCAN_BLOCKS_TOTAL + }; + const int64 val[] = { + PROGRESS_CREATEIDX_PHASE_VALIDATE_SORT, + 0, 0 + }; + + pgstat_progress_update_multi_param(3, index, val); + } tuplesort_performsort(state.tuplesort); /* * Now scan the heap and "merge" it with the index */ - validate_index_heapscan(heapRelation, - indexRelation, - indexInfo, - snapshot, - &state); + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_VALIDATE_TABLESCAN); + table_index_validate_scan(heapRelation, + indexRelation, + indexInfo, + snapshot, + &state); /* Done with tuplesort object */ tuplesort_end(state.tuplesort); @@ -3185,47 +3203,7 @@ validate_index(Oid heapId, Oid indexId, Snapshot snapshot) /* Close rels, but keep locks */ index_close(indexRelation, NoLock); - heap_close(heapRelation, NoLock); -} - -/* - * itemptr_encode - Encode ItemPointer as int64/int8 - * - * This representation must produce values encoded as int64 that sort in the - * same order as their corresponding original TID values would (using the - * default int8 opclass to produce a result equivalent to the default TID - * opclass). - * - * As noted in validate_index(), this can be significantly faster. - */ -static inline int64 -itemptr_encode(ItemPointer itemptr) -{ - BlockNumber block = ItemPointerGetBlockNumber(itemptr); - OffsetNumber offset = ItemPointerGetOffsetNumber(itemptr); - int64 encoded; - - /* - * Use the 16 least significant bits for the offset. 32 adjacent bits are - * used for the block number. Since remaining bits are unused, there - * cannot be negative encoded values (We assume a two's complement - * representation). - */ - encoded = ((uint64) block << 16) | (uint16) offset; - - return encoded; -} - -/* - * itemptr_decode - Decode int64/int8 representation back to ItemPointer - */ -static inline void -itemptr_decode(ItemPointer itemptr, int64 encoded) -{ - BlockNumber block = (BlockNumber) (encoded >> 16); - OffsetNumber offset = (OffsetNumber) (encoded & 0xFFFF); - - ItemPointerSet(itemptr, block, offset); + table_close(heapRelation, NoLock); } /* @@ -3234,7 +3212,7 @@ itemptr_decode(ItemPointer itemptr, int64 encoded) static bool validate_index_callback(ItemPointer itemptr, void *opaque) { - v_i_state *state = (v_i_state *) opaque; + ValidateIndexState *state = (ValidateIndexState *) opaque; int64 encoded = itemptr_encode(itemptr); tuplesort_putdatum(state->tuplesort, Int64GetDatum(encoded), false); @@ -3242,242 +3220,6 @@ validate_index_callback(ItemPointer itemptr, void *opaque) return false; /* never actually delete anything */ } -/* - * validate_index_heapscan - second table scan for concurrent index build - * - * This has much code in common with IndexBuildHeapScan, but it's enough - * different that it seems cleaner to have two routines not one. - */ -static void -validate_index_heapscan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - Snapshot snapshot, - v_i_state *state) -{ - HeapScanDesc scan; - HeapTuple heapTuple; - Datum values[INDEX_MAX_KEYS]; - bool isnull[INDEX_MAX_KEYS]; - ExprState *predicate; - TupleTableSlot *slot; - EState *estate; - ExprContext *econtext; - BlockNumber root_blkno = InvalidBlockNumber; - OffsetNumber root_offsets[MaxHeapTuplesPerPage]; - bool in_index[MaxHeapTuplesPerPage]; - - /* state variables for the merge */ - ItemPointer indexcursor = NULL; - ItemPointerData decoded; - bool tuplesort_empty = false; - - /* - * sanity checks - */ - Assert(OidIsValid(indexRelation->rd_rel->relam)); - - /* - * Need an EState for evaluation of index expressions and partial-index - * predicates. Also a slot to hold the current tuple. - */ - estate = CreateExecutorState(); - econtext = GetPerTupleExprContext(estate); - slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); - - /* Arrange for econtext's scan tuple to be the tuple under test */ - econtext->ecxt_scantuple = slot; - - /* Set up execution state for predicate, if any. */ - predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate); - - /* - * Prepare for scan of the base relation. We need just those tuples - * satisfying the passed-in reference snapshot. We must disable syncscan - * here, because it's critical that we read from block zero forward to - * match the sorted TIDs. - */ - scan = heap_beginscan_strat(heapRelation, /* relation */ - snapshot, /* snapshot */ - 0, /* number of keys */ - NULL, /* scan key */ - true, /* buffer access strategy OK */ - false); /* syncscan not OK */ - - /* - * Scan all tuples matching the snapshot. - */ - while ((heapTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - ItemPointer heapcursor = &heapTuple->t_self; - ItemPointerData rootTuple; - OffsetNumber root_offnum; - - CHECK_FOR_INTERRUPTS(); - - state->htups += 1; - - /* - * As commented in IndexBuildHeapScan, we should index heap-only - * tuples under the TIDs of their root tuples; so when we advance onto - * a new heap page, build a map of root item offsets on the page. - * - * This complicates merging against the tuplesort output: we will - * visit the live tuples in order by their offsets, but the root - * offsets that we need to compare against the index contents might be - * ordered differently. So we might have to "look back" within the - * tuplesort output, but only within the current page. We handle that - * by keeping a bool array in_index[] showing all the - * already-passed-over tuplesort output TIDs of the current page. We - * clear that array here, when advancing onto a new heap page. - */ - if (scan->rs_cblock != root_blkno) - { - Page page = BufferGetPage(scan->rs_cbuf); - - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - heap_get_root_tuples(page, root_offsets); - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - - memset(in_index, 0, sizeof(in_index)); - - root_blkno = scan->rs_cblock; - } - - /* Convert actual tuple TID to root TID */ - rootTuple = *heapcursor; - root_offnum = ItemPointerGetOffsetNumber(heapcursor); - - if (HeapTupleIsHeapOnly(heapTuple)) - { - root_offnum = root_offsets[root_offnum - 1]; - if (!OffsetNumberIsValid(root_offnum)) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg_internal("failed to find parent tuple for heap-only tuple at (%u,%u) in table \"%s\"", - ItemPointerGetBlockNumber(heapcursor), - ItemPointerGetOffsetNumber(heapcursor), - RelationGetRelationName(heapRelation)))); - ItemPointerSetOffsetNumber(&rootTuple, root_offnum); - } - - /* - * "merge" by skipping through the index tuples until we find or pass - * the current root tuple. - */ - while (!tuplesort_empty && - (!indexcursor || - ItemPointerCompare(indexcursor, &rootTuple) < 0)) - { - Datum ts_val; - bool ts_isnull; - - if (indexcursor) - { - /* - * Remember index items seen earlier on the current heap page - */ - if (ItemPointerGetBlockNumber(indexcursor) == root_blkno) - in_index[ItemPointerGetOffsetNumber(indexcursor) - 1] = true; - } - - tuplesort_empty = !tuplesort_getdatum(state->tuplesort, true, - &ts_val, &ts_isnull, NULL); - Assert(tuplesort_empty || !ts_isnull); - if (!tuplesort_empty) - { - itemptr_decode(&decoded, DatumGetInt64(ts_val)); - indexcursor = &decoded; - - /* If int8 is pass-by-ref, free (encoded) TID Datum memory */ -#ifndef USE_FLOAT8_BYVAL - pfree(DatumGetPointer(ts_val)); -#endif - } - else - { - /* Be tidy */ - indexcursor = NULL; - } - } - - /* - * If the tuplesort has overshot *and* we didn't see a match earlier, - * then this tuple is missing from the index, so insert it. - */ - if ((tuplesort_empty || - ItemPointerCompare(indexcursor, &rootTuple) > 0) && - !in_index[root_offnum - 1]) - { - MemoryContextReset(econtext->ecxt_per_tuple_memory); - - /* Set up for predicate or expression evaluation */ - ExecStoreTuple(heapTuple, slot, InvalidBuffer, false); - - /* - * In a partial index, discard tuples that don't satisfy the - * predicate. - */ - if (predicate != NULL) - { - if (!ExecQual(predicate, econtext)) - continue; - } - - /* - * For the current heap tuple, extract all the attributes we use - * in this index, and note which are null. This also performs - * evaluation of any expressions needed. - */ - FormIndexDatum(indexInfo, - slot, - estate, - values, - isnull); - - /* - * You'd think we should go ahead and build the index tuple here, - * but some index AMs want to do further processing on the data - * first. So pass the values[] and isnull[] arrays, instead. - */ - - /* - * If the tuple is already committed dead, you might think we - * could suppress uniqueness checking, but this is no longer true - * in the presence of HOT, because the insert is actually a proxy - * for a uniqueness check on the whole HOT-chain. That is, the - * tuple we have here could be dead because it was already - * HOT-updated, and if so the updating transaction will not have - * thought it should insert index entries. The index AM will - * check the whole HOT-chain and correctly detect a conflict if - * there is one. - */ - - index_insert(indexRelation, - values, - isnull, - &rootTuple, - heapRelation, - indexInfo->ii_Unique ? - UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, - indexInfo); - - state->tups_inserted += 1; - } - } - - heap_endscan(scan); - - ExecDropSingleTupleTableSlot(slot); - - FreeExecutorState(estate); - - /* These may have been pointing to the now-gone estate */ - indexInfo->ii_ExpressionsState = NIL; - indexInfo->ii_PredicateState = NULL; -} - - /* * index_set_state_flags - adjust pg_index state flags * @@ -3506,7 +3248,7 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action) Assert(GetTopTransactionIdIfAny() == InvalidTransactionId); /* Open pg_index and fetch a writable copy of the index's tuple */ - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); indexTuple = SearchSysCacheCopy1(INDEXRELID, ObjectIdGetDatum(indexId)); @@ -3566,7 +3308,7 @@ index_set_state_flags(Oid indexId, IndexStateFlagsAction action) /* ... and write it back in-place */ heap_inplace_update(pg_index, indexTuple); - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); } @@ -3609,6 +3351,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, IndexInfo *indexInfo; volatile bool skipped_constraint = false; PGRUsage ru0; + bool progress = (options & REINDEXOPT_REPORT_PROGRESS) != 0; pg_rusage_init(&ru0); @@ -3617,7 +3360,17 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, * we only need to be sure no schema or data changes are going on. */ heapId = IndexGetRelation(indexId, false); - heapRelation = heap_open(heapId, ShareLock); + heapRelation = table_open(heapId, ShareLock); + + if (progress) + { + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, + heapId); + pgstat_progress_update_param(PROGRESS_CREATEIDX_COMMAND, + PROGRESS_CREATEIDX_COMMAND_REINDEX); + pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, + indexId); + } /* * Open the target index relation and get an exclusive lock on it, to @@ -3625,6 +3378,10 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, */ iRel = index_open(indexId, AccessExclusiveLock); + if (progress) + pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, + iRel->rd_rel->relam); + /* * The case of reindexing partitioned tables and indexes is handled * differently by upper layers, so this case shouldn't arise. @@ -3654,32 +3411,32 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, */ TransferPredicateLocksToHeapRelation(iRel); + /* Fetch info needed for index_build */ + indexInfo = BuildIndexInfo(iRel); + + /* If requested, skip checking uniqueness/exclusion constraints */ + if (skip_constraint_checks) + { + if (indexInfo->ii_Unique || indexInfo->ii_ExclusionOps != NULL) + skipped_constraint = true; + indexInfo->ii_Unique = false; + indexInfo->ii_ExclusionOps = NULL; + indexInfo->ii_ExclusionProcs = NULL; + indexInfo->ii_ExclusionStrats = NULL; + } + + /* ensure SetReindexProcessing state isn't leaked */ PG_TRY(); { /* Suppress use of the target index while rebuilding it */ SetReindexProcessing(heapId, indexId); - /* Fetch info needed for index_build */ - indexInfo = BuildIndexInfo(iRel); - - /* If requested, skip checking uniqueness/exclusion constraints */ - if (skip_constraint_checks) - { - if (indexInfo->ii_Unique || indexInfo->ii_ExclusionOps != NULL) - skipped_constraint = true; - indexInfo->ii_Unique = false; - indexInfo->ii_ExclusionOps = NULL; - indexInfo->ii_ExclusionProcs = NULL; - indexInfo->ii_ExclusionStrats = NULL; - } - - /* We'll build a new physical relation for the index */ - RelationSetNewRelfilenode(iRel, persistence, InvalidTransactionId, - InvalidMultiXactId); + /* Create a new physical relation for the index */ + RelationSetNewRelfilenode(iRel, persistence); /* Initialize the index and rebuild */ /* Note: we do not need to re-establish pkey setting */ - index_build(heapRelation, iRel, indexInfo, false, true, true); + index_build(heapRelation, iRel, indexInfo, true, true); } PG_CATCH(); { @@ -3731,7 +3488,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, bool index_bad; bool early_pruning_enabled = EarlyPruningEnabled(heapRelation); - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); indexTuple = SearchSysCacheCopy1(INDEXRELID, ObjectIdGetDatum(indexId)); @@ -3765,7 +3522,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, CacheInvalidateRelcache(heapRelation); } - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); } /* Log what we did */ @@ -3776,9 +3533,12 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, errdetail_internal("%s", pg_rusage_show(&ru0)))); + if (progress) + pgstat_progress_end_command(); + /* Close rels, but keep locks */ index_close(iRel, NoLock); - heap_close(heapRelation, NoLock); + table_close(heapRelation, NoLock); } /* @@ -3822,15 +3582,15 @@ reindex_relation(Oid relid, int flags, int options) Relation rel; Oid toast_relid; List *indexIds; - bool is_pg_class; bool result; + int i; /* * Open and lock the relation. ShareLock is sufficient since we only need * to prevent schema and data changes in it. The lock level used here * should match ReindexTable(). */ - rel = heap_open(relid, ShareLock); + rel = table_open(relid, ShareLock); /* * This may be useful when implemented someday; but that day is not today. @@ -3844,7 +3604,7 @@ reindex_relation(Oid relid, int flags, int options) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("REINDEX of partitioned tables is not yet implemented, skipping \"%s\"", RelationGetRelationName(rel)))); - heap_close(rel, ShareLock); + table_close(rel, ShareLock); return false; } @@ -3857,37 +3617,8 @@ reindex_relation(Oid relid, int flags, int options) */ indexIds = RelationGetIndexList(rel); - /* - * reindex_index will attempt to update the pg_class rows for the relation - * and index. If we are processing pg_class itself, we want to make sure - * that the updates do not try to insert index entries into indexes we - * have not processed yet. (When we are trying to recover from corrupted - * indexes, that could easily cause a crash.) We can accomplish this - * because CatalogTupleInsert/CatalogTupleUpdate will use the relcache's - * index list to know which indexes to update. We just force the index - * list to be only the stuff we've processed. - * - * It is okay to not insert entries into the indexes we have not processed - * yet because all of this is transaction-safe. If we fail partway - * through, the updated rows are dead and it doesn't matter whether they - * have index entries. Also, a new pg_class index will be created with a - * correct entry for its own pg_class row because we do - * RelationSetNewRelfilenode() before we do index_build(). - * - * Note that we also clear pg_class's rd_oidindex until the loop is done, - * so that that index can't be accessed either. This means we cannot - * safely generate new relation OIDs while in the loop; shouldn't be a - * problem. - */ - is_pg_class = (RelationGetRelid(rel) == RelationRelationId); - - /* Ensure rd_indexattr is valid; see comments for RelationSetIndexList */ - if (is_pg_class) - (void) RelationGetIndexAttrBitmap(rel, INDEX_ATTR_BITMAP_HOT); - PG_TRY(); { - List *doneIndexes; ListCell *indexId; char persistence; @@ -3915,14 +3646,11 @@ reindex_relation(Oid relid, int flags, int options) persistence = rel->rd_rel->relpersistence; /* Reindex all the indexes. */ - doneIndexes = NIL; + i = 1; foreach(indexId, indexIds) { Oid indexOid = lfirst_oid(indexId); - if (is_pg_class) - RelationSetIndexList(rel, doneIndexes, InvalidOid); - reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS), persistence, options); @@ -3931,8 +3659,10 @@ reindex_relation(Oid relid, int flags, int options) /* Index should no longer be in the pending list */ Assert(!ReindexIsProcessingIndex(indexOid)); - if (is_pg_class) - doneIndexes = lappend_oid(doneIndexes, indexOid); + /* Set index rebuild count */ + pgstat_progress_update_param(PROGRESS_CLUSTER_INDEX_REBUILD_COUNT, + i); + i++; } } PG_CATCH(); @@ -3944,13 +3674,10 @@ reindex_relation(Oid relid, int flags, int options) PG_END_TRY(); ResetReindexPending(); - if (is_pg_class) - RelationSetIndexList(rel, indexIds, ClassOidIndexId); - /* * Close rel, but continue to hold the lock. */ - heap_close(rel, NoLock); + table_close(rel, NoLock); result = (indexIds != NIL); @@ -4123,7 +3850,7 @@ RestoreReindexState(void *reindexstate) { SerializedReindexState *sistate = (SerializedReindexState *) reindexstate; int c = 0; - MemoryContext oldcontext; + MemoryContext oldcontext; currentlyReindexedHeap = sistate->currentlyReindexedHeap; currentlyReindexedIndex = sistate->currentlyReindexedIndex; diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c index 5a361683da4..f237e62bc90 100644 --- a/src/backend/catalog/indexing.c +++ b/src/backend/catalog/indexing.c @@ -4,7 +4,7 @@ * This file contains routines to support indexes defined on system * catalogs. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,6 +15,8 @@ */ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "catalog/index.h" #include "catalog/indexing.h" @@ -42,7 +44,7 @@ CatalogOpenIndexes(Relation heapRel) ResultRelInfo *resultRelInfo; resultRelInfo = makeNode(ResultRelInfo); - resultRelInfo->ri_RangeTableIndex = 1; /* dummy */ + resultRelInfo->ri_RangeTableIndex = 0; /* dummy */ resultRelInfo->ri_RelationDesc = heapRel; resultRelInfo->ri_TrigDesc = NULL; /* we don't fire triggers */ @@ -80,9 +82,15 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; - /* HOT update does not require index inserts */ + /* + * HOT update does not require index inserts. But with asserts enabled we + * want to check that it'd be legal to currently insert into the + * table/index. + */ +#ifndef USE_ASSERT_CHECKING if (HeapTupleIsHeapOnly(heapTuple)) return; +#endif /* * Get information from the state structure. Fall out if nothing to do. @@ -95,8 +103,9 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) heapRelation = indstate->ri_RelationDesc; /* Need a slot to hold the tuple being examined */ - slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); - ExecStoreTuple(heapTuple, slot, InvalidBuffer, false); + slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRelation), + &TTSOpsHeapTuple); + ExecStoreHeapTuple(heapTuple, slot, false); /* * for each index, form and insert the index tuple @@ -104,8 +113,10 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) for (i = 0; i < numIndexes; i++) { IndexInfo *indexInfo; + Relation index; indexInfo = indexInfoArray[i]; + index = relationDescs[i]; /* If the index is marked as read-only, ignore it */ if (!indexInfo->ii_ReadyForInserts) @@ -118,9 +129,18 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) Assert(indexInfo->ii_Expressions == NIL); Assert(indexInfo->ii_Predicate == NIL); Assert(indexInfo->ii_ExclusionOps == NULL); - Assert(relationDescs[i]->rd_index->indimmediate); + Assert(index->rd_index->indimmediate); Assert(indexInfo->ii_NumIndexKeyAttrs != 0); + /* see earlier check above */ +#ifdef USE_ASSERT_CHECKING + if (HeapTupleIsHeapOnly(heapTuple)) + { + Assert(!ReindexIsProcessingIndex(RelationGetRelid(index))); + continue; + } +#endif /* USE_ASSERT_CHECKING */ + /* * FormIndexDatum fills in its values and isnull parameters with the * appropriate values for the column(s) of the index. @@ -134,12 +154,12 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) /* * The index AM does the rest. */ - index_insert(relationDescs[i], /* index relation */ + index_insert(index, /* index relation */ values, /* array of index Datums */ isnull, /* is-null flags */ &(heapTuple->t_self), /* tid of heap tuple */ heapRelation, - relationDescs[i]->rd_index->indisunique ? + index->rd_index->indisunique ? UNIQUE_CHECK_YES : UNIQUE_CHECK_NO, indexInfo); } @@ -159,20 +179,17 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple) * and building the index info structures is moderately expensive. * (Use CatalogTupleInsertWithInfo in such cases.) */ -Oid +void CatalogTupleInsert(Relation heapRel, HeapTuple tup) { CatalogIndexState indstate; - Oid oid; indstate = CatalogOpenIndexes(heapRel); - oid = simple_heap_insert(heapRel, tup); + simple_heap_insert(heapRel, tup); CatalogIndexInsert(indstate, tup); CatalogCloseIndexes(indstate); - - return oid; } /* @@ -183,17 +200,13 @@ CatalogTupleInsert(Relation heapRel, HeapTuple tup) * might cache the CatalogIndexState data somewhere (perhaps in the relcache) * so that callers needn't trouble over this ... but we don't do so today. */ -Oid +void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate) { - Oid oid; - - oid = simple_heap_insert(heapRel, tup); + simple_heap_insert(heapRel, tup); CatalogIndexInsert(indstate, tup); - - return oid; } /* diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql index f4e69f4a264..c42e76ea894 100644 --- a/src/backend/catalog/information_schema.sql +++ b/src/backend/catalog/information_schema.sql @@ -1,8 +1,8 @@ /* * SQL Information Schema - * as defined in ISO/IEC 9075-11:2011 + * as defined in ISO/IEC 9075-11:2016 * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/backend/catalog/information_schema.sql * @@ -48,10 +48,6 @@ CREATE FUNCTION _pg_expandarray(IN anyarray, OUT x anyelement, OUT n int) pg_catalog.array_upper($1,1), 1) as g(s)'; -CREATE FUNCTION _pg_keysequal(smallint[], smallint[]) RETURNS boolean - LANGUAGE sql IMMUTABLE PARALLEL SAFE -- intentionally not STRICT, to allow inlining - AS 'select $1 operator(pg_catalog.<@) $2 and $2 operator(pg_catalog.<@) $1'; - /* Given an index's OID and an underlying-table column number, return the * column's position in the index (NULL if not there) */ CREATE FUNCTION _pg_index_position(oid, smallint) RETURNS int @@ -186,7 +182,7 @@ CREATE FUNCTION _pg_interval_type(typid oid, mod int4) RETURNS text AS $$SELECT CASE WHEN $1 IN (1186) /* interval */ - THEN upper(substring(format_type($1, $2) from 'interval[()0-9]* #"%#"' for '#')) + THEN pg_catalog.upper(substring(pg_catalog.format_type($1, $2) from 'interval[()0-9]* #"%#"' for '#')) ELSE null END$$; @@ -208,7 +204,7 @@ CREATE DOMAIN cardinal_number AS integer * CHARACTER_DATA domain */ -CREATE DOMAIN character_data AS character varying; +CREATE DOMAIN character_data AS character varying COLLATE "C"; /* @@ -216,7 +212,7 @@ CREATE DOMAIN character_data AS character varying; * SQL_IDENTIFIER domain */ -CREATE DOMAIN sql_identifier AS character varying; +CREATE DOMAIN sql_identifier AS name; /* @@ -243,7 +239,7 @@ CREATE DOMAIN time_stamp AS timestamp(2) with time zone * YES_OR_NO domain */ -CREATE DOMAIN yes_or_no AS character varying(3) +CREATE DOMAIN yes_or_no AS character varying(3) COLLATE "C" CONSTRAINT yes_or_no_check CHECK (value IN ('YES', 'NO')); @@ -416,7 +412,7 @@ CREATE VIEW check_constraint_routine_usage AS CAST(c.conname AS sql_identifier) AS constraint_name, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(np.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name FROM pg_namespace nc, pg_constraint c, pg_depend d, pg_proc p, pg_namespace np WHERE nc.oid = c.connamespace AND c.contype = 'c' @@ -509,7 +505,29 @@ GRANT SELECT ON collation_character_set_applicability TO PUBLIC; * COLUMN_COLUMN_USAGE view */ --- feature not supported +CREATE VIEW column_column_usage AS + SELECT CAST(current_database() AS sql_identifier) AS table_catalog, + CAST(n.nspname AS sql_identifier) AS table_schema, + CAST(c.relname AS sql_identifier) AS table_name, + CAST(ac.attname AS sql_identifier) AS column_name, + CAST(ad.attname AS sql_identifier) AS dependent_column + + FROM pg_namespace n, pg_class c, pg_depend d, + pg_attribute ac, pg_attribute ad + + WHERE n.oid = c.relnamespace + AND c.oid = ac.attrelid + AND c.oid = ad.attrelid + AND d.classid = 'pg_catalog.pg_class'::regclass + AND d.refclassid = 'pg_catalog.pg_class'::regclass + AND d.objid = d.refobjid + AND c.oid = d.objid + AND d.objsubid = ad.attnum + AND d.refobjsubid = ac.attnum + AND ad.attgenerated <> '' + AND pg_has_role(c.relowner, 'USAGE'); + +GRANT SELECT ON column_column_usage TO PUBLIC; /* @@ -656,7 +674,7 @@ CREATE VIEW columns AS CAST(c.relname AS sql_identifier) AS table_name, CAST(a.attname AS sql_identifier) AS column_name, CAST(a.attnum AS cardinal_number) AS ordinal_position, - CAST(pg_get_expr(ad.adbin, ad.adrelid) AS character_data) AS column_default, + CAST(CASE WHEN a.attgenerated = '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS column_default, CAST(CASE WHEN a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) THEN 'NO' ELSE 'YES' END AS yes_or_no) AS is_nullable, @@ -745,8 +763,8 @@ CREATE VIEW columns AS CAST(seq.seqmin AS character_data) AS identity_minimum, CAST(CASE WHEN seq.seqcycle THEN 'YES' ELSE 'NO' END AS yes_or_no) AS identity_cycle, - CAST('NEVER' AS character_data) AS is_generated, - CAST(null AS character_data) AS generation_expression, + CAST(CASE WHEN a.attgenerated <> '' THEN 'ALWAYS' ELSE 'NEVER' END AS character_data) AS is_generated, + CAST(CASE WHEN a.attgenerated <> '' THEN pg_get_expr(ad.adbin, ad.adrelid) END AS character_data) AS generation_expression, CAST(CASE WHEN c.relkind IN ('r', 'p') OR (c.relkind IN ('v', 'f') AND @@ -1115,7 +1133,7 @@ GRANT SELECT ON key_column_usage TO PUBLIC; CREATE VIEW parameters AS SELECT CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(n_nspname AS sql_identifier) AS specific_schema, - CAST(proname || '_' || CAST(p_oid AS text) AS sql_identifier) AS specific_name, + CAST(nameconcatoid(proname, p_oid) AS sql_identifier) AS specific_name, CAST((ss.x).n AS cardinal_number) AS ordinal_position, CAST( CASE WHEN proargmodes IS NULL THEN 'IN' @@ -1184,7 +1202,7 @@ GRANT SELECT ON parameters TO PUBLIC; /* * 5.39 - * REFERENCED_TYPES view + * PRIVATE_PARAMETERS view */ -- feature not supported @@ -1192,6 +1210,14 @@ GRANT SELECT ON parameters TO PUBLIC; /* * 5.40 + * REFERENCED_TYPES view + */ + +-- feature not supported + + +/* + * 5.41 * REFERENTIAL_CONSTRAINTS view */ @@ -1253,7 +1279,7 @@ GRANT SELECT ON referential_constraints TO PUBLIC; /* - * 5.41 + * 5.42 * ROLE_COLUMN_GRANTS view */ @@ -1273,14 +1299,14 @@ CREATE VIEW role_column_grants AS GRANT SELECT ON role_column_grants TO PUBLIC; --- 5.42 ROLE_ROUTINE_GRANTS view is based on 5.49 ROUTINE_PRIVILEGES and is defined there instead. +-- 5.43 ROLE_ROUTINE_GRANTS view is based on 5.50 ROUTINE_PRIVILEGES and is defined there instead. --- 5.43 ROLE_TABLE_GRANTS view is based on 5.62 TABLE_PRIVILEGES and is defined there instead. +-- 5.44 ROLE_TABLE_GRANTS view is based on 5.63 TABLE_PRIVILEGES and is defined there instead. /* - * 5.44 + * 5.45 * ROLE_TABLE_METHOD_GRANTS view */ @@ -1288,14 +1314,14 @@ GRANT SELECT ON role_column_grants TO PUBLIC; --- 5.45 ROLE_USAGE_GRANTS view is based on 5.74 USAGE_PRIVILEGES and is defined there instead. +-- 5.46 ROLE_USAGE_GRANTS view is based on 5.75 USAGE_PRIVILEGES and is defined there instead. --- 5.46 ROLE_UDT_GRANTS view is based on 5.73 UDT_PRIVILEGES and is defined there instead. +-- 5.47 ROLE_UDT_GRANTS view is based on 5.74 UDT_PRIVILEGES and is defined there instead. /* - * 5.47 + * 5.48 * ROUTINE_COLUMN_USAGE view */ @@ -1303,7 +1329,7 @@ GRANT SELECT ON role_column_grants TO PUBLIC; /* - * 5.48 + * 5.49 * ROUTINE_PERIOD_USAGE view */ @@ -1311,7 +1337,7 @@ GRANT SELECT ON role_column_grants TO PUBLIC; /* - * 5.49 + * 5.50 * ROUTINE_PRIVILEGES view */ @@ -1320,7 +1346,7 @@ CREATE VIEW routine_privileges AS CAST(grantee.rolname AS sql_identifier) AS grantee, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(n.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, CAST(current_database() AS sql_identifier) AS routine_catalog, CAST(n.nspname AS sql_identifier) AS routine_schema, CAST(p.proname AS sql_identifier) AS routine_name, @@ -1378,7 +1404,7 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; /* - * 5.50 + * 5.51 * ROUTINE_ROUTINE_USAGE view */ @@ -1386,7 +1412,7 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; /* - * 5.51 + * 5.52 * ROUTINE_SEQUENCE_USAGE view */ @@ -1394,7 +1420,7 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; /* - * 5.52 + * 5.53 * ROUTINE_TABLE_USAGE view */ @@ -1402,14 +1428,14 @@ GRANT SELECT ON role_routine_grants TO PUBLIC; /* - * 5.53 + * 5.54 * ROUTINES view */ CREATE VIEW routines AS SELECT CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(n.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, CAST(current_database() AS sql_identifier) AS routine_catalog, CAST(n.nspname AS sql_identifier) AS routine_schema, CAST(p.proname AS sql_identifier) AS routine_name, @@ -1520,7 +1546,7 @@ GRANT SELECT ON routines TO PUBLIC; /* - * 5.54 + * 5.55 * SCHEMATA view */ @@ -1541,7 +1567,7 @@ GRANT SELECT ON schemata TO PUBLIC; /* - * 5.55 + * 5.56 * SEQUENCES view */ @@ -1571,7 +1597,7 @@ GRANT SELECT ON sequences TO PUBLIC; /* - * 5.56 + * 5.57 * SQL_FEATURES table */ @@ -1583,7 +1609,7 @@ CREATE TABLE sql_features ( is_supported yes_or_no, is_verified_by character_data, comments character_data -) WITHOUT OIDS; +); -- Will be filled with external data by initdb. @@ -1591,7 +1617,7 @@ GRANT SELECT ON sql_features TO PUBLIC; /* - * 5.57 + * 5.58 * SQL_IMPLEMENTATION_INFO table */ @@ -1604,7 +1630,7 @@ CREATE TABLE sql_implementation_info ( integer_value cardinal_number, character_value character_data, comments character_data -) WITHOUT OIDS; +); INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL); INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, (SELECT default_collate_name FROM character_sets), NULL); @@ -1635,7 +1661,7 @@ CREATE TABLE sql_languages ( sql_language_implementation character_data, sql_language_binding_style character_data, sql_language_programming_language character_data -) WITHOUT OIDS; +); INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'DIRECT', NULL); INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'EMBEDDED', 'C'); @@ -1656,7 +1682,7 @@ CREATE TABLE sql_packages ( is_supported yes_or_no, is_verified_by character_data, comments character_data -) WITHOUT OIDS; +); INSERT INTO sql_packages VALUES ('PKG000', 'Core', 'NO', NULL, ''); INSERT INTO sql_packages VALUES ('PKG001', 'Enhanced datetime facilities', 'YES', NULL, ''); @@ -1673,7 +1699,7 @@ GRANT SELECT ON sql_packages TO PUBLIC; /* - * 5.58 + * 5.59 * SQL_PARTS table */ @@ -1683,7 +1709,7 @@ CREATE TABLE sql_parts ( is_supported yes_or_no, is_verified_by character_data, comments character_data -) WITHOUT OIDS; +); INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, ''); INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, ''); @@ -1693,11 +1719,11 @@ INSERT INTO sql_parts VALUES ('9', 'Management of External Data (SQL/MED)', 'NO' INSERT INTO sql_parts VALUES ('10', 'Object Language Bindings (SQL/OLB)', 'NO', NULL, ''); INSERT INTO sql_parts VALUES ('11', 'Information and Definition Schema (SQL/Schemata)', 'NO', NULL, ''); INSERT INTO sql_parts VALUES ('13', 'Routines and Types Using the Java Programming Language (SQL/JRT)', 'NO', NULL, ''); -INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', 'YES', NULL, ''); +INSERT INTO sql_parts VALUES ('14', 'XML-Related Specifications (SQL/XML)', 'NO', NULL, ''); /* - * 5.59 + * 5.60 * SQL_SIZING table */ @@ -1708,7 +1734,7 @@ CREATE TABLE sql_sizing ( sizing_name character_data, supported_value cardinal_number, comments character_data -) WITHOUT OIDS; +); INSERT INTO sql_sizing VALUES (34, 'MAXIMUM CATALOG NAME LENGTH', 63, NULL); INSERT INTO sql_sizing VALUES (30, 'MAXIMUM COLUMN NAME LENGTH', 63, NULL); @@ -1757,13 +1783,13 @@ CREATE TABLE sql_sizing_profiles ( profile_id character_data, required_value cardinal_number, comments character_data -) WITHOUT OIDS; +); GRANT SELECT ON sql_sizing_profiles TO PUBLIC; /* - * 5.60 + * 5.61 * TABLE_CONSTRAINTS view */ @@ -1836,7 +1862,7 @@ GRANT SELECT ON table_constraints TO PUBLIC; /* - * 5.61 + * 5.62 * TABLE_METHOD_PRIVILEGES view */ @@ -1844,7 +1870,7 @@ GRANT SELECT ON table_constraints TO PUBLIC; /* - * 5.62 + * 5.63 * TABLE_PRIVILEGES view */ @@ -1954,7 +1980,7 @@ GRANT SELECT ON tables TO PUBLIC; /* - * 5.64 + * 5.65 * TRANSFORMS view */ @@ -1964,7 +1990,7 @@ CREATE VIEW transforms AS CAST(t.typname AS sql_identifier) AS udt_name, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(np.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, CAST(l.lanname AS sql_identifier) AS group_name, CAST('FROM SQL' AS character_data) AS transform_type FROM pg_type t JOIN pg_transform x ON t.oid = x.trftype @@ -1980,7 +2006,7 @@ CREATE VIEW transforms AS CAST(t.typname AS sql_identifier) AS udt_name, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(np.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name, CAST(l.lanname AS sql_identifier) AS group_name, CAST('TO SQL' AS character_data) AS transform_type FROM pg_type t JOIN pg_transform x ON t.oid = x.trftype @@ -1994,7 +2020,7 @@ CREATE VIEW transforms AS /* - * 5.65 + * 5.66 * TRANSLATIONS view */ @@ -2002,7 +2028,7 @@ CREATE VIEW transforms AS /* - * 5.66 + * 5.67 * TRIGGERED_UPDATE_COLUMNS view */ @@ -2034,7 +2060,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.67 + * 5.68 * TRIGGER_COLUMN_USAGE view */ @@ -2042,7 +2068,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.68 + * 5.69 * TRIGGER_PERIOD_USAGE view */ @@ -2050,7 +2076,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.69 + * 5.70 * TRIGGER_ROUTINE_USAGE view */ @@ -2058,7 +2084,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.70 + * 5.71 * TRIGGER_SEQUENCE_USAGE view */ @@ -2066,7 +2092,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.71 + * 5.72 * TRIGGER_TABLE_USAGE view */ @@ -2074,7 +2100,7 @@ GRANT SELECT ON triggered_update_columns TO PUBLIC; /* - * 5.72 + * 5.73 * TRIGGERS view */ @@ -2094,12 +2120,12 @@ CREATE VIEW triggers AS AS cardinal_number) AS action_order, CAST( CASE WHEN pg_has_role(c.relowner, 'USAGE') - THEN (regexp_match(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE PROCEDURE'))[1] + THEN (regexp_match(pg_get_triggerdef(t.oid), E'.{35,} WHEN \\((.+)\\) EXECUTE FUNCTION'))[1] ELSE null END AS character_data) AS action_condition, CAST( substring(pg_get_triggerdef(t.oid) from - position('EXECUTE PROCEDURE' in substring(pg_get_triggerdef(t.oid) from 48)) + 47) + position('EXECUTE FUNCTION' in substring(pg_get_triggerdef(t.oid) from 48)) + 47) AS character_data) AS action_statement, CAST( -- hard-wired reference to TRIGGER_TYPE_ROW @@ -2136,7 +2162,7 @@ GRANT SELECT ON triggers TO PUBLIC; /* - * 5.73 + * 5.74 * UDT_PRIVILEGES view */ @@ -2198,7 +2224,7 @@ GRANT SELECT ON role_udt_grants TO PUBLIC; /* - * 5.74 + * 5.75 * USAGE_PRIVILEGES view */ @@ -2390,7 +2416,7 @@ GRANT SELECT ON role_usage_grants TO PUBLIC; /* - * 5.75 + * 5.76 * USER_DEFINED_TYPES view */ @@ -2437,7 +2463,7 @@ GRANT SELECT ON user_defined_types TO PUBLIC; /* - * 5.76 + * 5.77 * VIEW_COLUMN_USAGE */ @@ -2476,7 +2502,7 @@ GRANT SELECT ON view_column_usage TO PUBLIC; /* - * 5.77 + * 5.78 * VIEW_PERIOD_USAGE */ @@ -2484,7 +2510,7 @@ GRANT SELECT ON view_column_usage TO PUBLIC; /* - * 5.78 + * 5.79 * VIEW_ROUTINE_USAGE */ @@ -2495,7 +2521,7 @@ CREATE VIEW view_routine_usage AS CAST(v.relname AS sql_identifier) AS table_name, CAST(current_database() AS sql_identifier) AS specific_catalog, CAST(np.nspname AS sql_identifier) AS specific_schema, - CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier) AS specific_name + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier) AS specific_name FROM pg_namespace nv, pg_class v, pg_depend dv, pg_depend dp, pg_proc p, pg_namespace np @@ -2517,7 +2543,7 @@ GRANT SELECT ON view_routine_usage TO PUBLIC; /* - * 5.79 + * 5.80 * VIEW_TABLE_USAGE */ @@ -2552,7 +2578,7 @@ GRANT SELECT ON view_table_usage TO PUBLIC; /* - * 5.80 + * 5.81 * VIEWS view */ @@ -2712,7 +2738,8 @@ CREATE VIEW element_types AS UNION ALL /* parameters */ - SELECT pronamespace, CAST(proname || '_' || CAST(oid AS text) AS sql_identifier), + SELECT pronamespace, + CAST(nameconcatoid(proname, oid) AS sql_identifier), 'ROUTINE'::text, (ss.x).n, (ss.x).x, 0 FROM (SELECT p.pronamespace, p.proname, p.oid, _pg_expandarray(coalesce(p.proallargtypes, p.proargtypes::oid[])) AS x @@ -2721,7 +2748,8 @@ CREATE VIEW element_types AS UNION ALL /* result types */ - SELECT p.pronamespace, CAST(p.proname || '_' || CAST(p.oid AS text) AS sql_identifier), + SELECT p.pronamespace, + CAST(nameconcatoid(p.proname, p.oid) AS sql_identifier), 'ROUTINE'::text, 0, p.prorettype, 0 FROM pg_proc p @@ -2743,7 +2771,6 @@ GRANT SELECT ON element_types TO PUBLIC; -- SQL/MED views; these use section numbers from part 9 of the standard. --- (still SQL:2008; there is no SQL:2011 SQL/MED) /* Base view for foreign table columns */ CREATE VIEW _pg_foreign_table_columns AS diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 0f67a122ede..e251f5a9fdc 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -9,7 +9,7 @@ * and implementing search-path-controlled searches. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -47,7 +47,7 @@ #include "parser/parse_func.h" #include "storage/ipc.h" #include "storage/lmgr.h" -#include "storage/sinval.h" +#include "storage/sinvaladt.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/catcache.h" @@ -192,12 +192,13 @@ char *namespace_search_path = NULL; /* Local functions */ static void recomputeNamespacePath(void); +static void AccessTempTableNamespace(bool force); static void InitTempTableNamespace(void); static void RemoveTempRelations(Oid tempNamespaceId); static void RemoveTempRelationsCallback(int code, Datum arg); static void NamespaceCallback(Datum arg, int cacheid, uint32 hashvalue); static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, - int **argnumbers); + int **argnumbers); /* @@ -459,9 +460,8 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) /* check for pg_temp alias */ if (strcmp(newRelation->schemaname, "pg_temp") == 0) { - /* Initialize temp namespace if first time through */ - if (!OidIsValid(myTempNamespace)) - InitTempTableNamespace(); + /* Initialize temp namespace */ + AccessTempTableNamespace(false); return myTempNamespace; } /* use exact schema given */ @@ -470,9 +470,8 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) } else if (newRelation->relpersistence == RELPERSISTENCE_TEMP) { - /* Initialize temp namespace if first time through */ - if (!OidIsValid(myTempNamespace)) - InitTempTableNamespace(); + /* Initialize temp namespace */ + AccessTempTableNamespace(false); return myTempNamespace; } else @@ -482,7 +481,7 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) if (activeTempCreationPending) { /* Need to initialize temp namespace */ - InitTempTableNamespace(); + AccessTempTableNamespace(true); return myTempNamespace; } namespaceId = activeCreationNamespace; @@ -505,9 +504,9 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation) * permission on the target namespace, this function will instead signal * an ERROR. * - * If non-NULL, *existing_oid is set to the OID of any existing relation with - * the same name which already exists in that namespace, or to InvalidOid if - * no such relation exists. + * If non-NULL, *existing_relation_id is set to the OID of any existing relation + * with the same name which already exists in that namespace, or to InvalidOid + * if no such relation exists. * * If lockmode != NoLock, the specified lock mode is acquired on the existing * relation, if any, provided that the current user owns the target relation. @@ -758,13 +757,23 @@ RelationIsVisible(Oid relid) /* * TypenameGetTypid + * Wrapper for binary compatibility. + */ +Oid +TypenameGetTypid(const char *typname) +{ + return TypenameGetTypidExtended(typname, true); +} + +/* + * TypenameGetTypidExtended * Try to resolve an unqualified datatype name. * Returns OID if type found in search path, else InvalidOid. * * This is essentially the same as RelnameGetRelid. */ Oid -TypenameGetTypid(const char *typname) +TypenameGetTypidExtended(const char *typname, bool temp_ok) { Oid typid; ListCell *l; @@ -775,7 +784,10 @@ TypenameGetTypid(const char *typname) { Oid namespaceId = lfirst_oid(l); - typid = GetSysCacheOid2(TYPENAMENSP, + if (!temp_ok && namespaceId == myTempNamespace) + continue; /* do not look in temp namespace */ + + typid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(typid)) @@ -1084,7 +1096,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames, palloc(offsetof(struct _FuncCandidateList, args) + effective_nargs * sizeof(Oid)); newResult->pathpos = pathpos; - newResult->oid = HeapTupleGetOid(proctup); + newResult->oid = procform->oid; newResult->nargs = effective_nargs; newResult->argnumbers = argnumbers; if (argnumbers) @@ -1488,7 +1500,8 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright) ObjectIdGetDatum(namespaceId)); if (HeapTupleIsValid(opertup)) { - Oid result = HeapTupleGetOid(opertup); + Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup); + Oid result = operclass->oid; ReleaseSysCache(opertup); return result; @@ -1533,7 +1546,7 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright) if (operform->oprnamespace == namespaceId) { - Oid result = HeapTupleGetOid(opertup); + Oid result = operform->oid; ReleaseSysCacheList(catlist); return result; @@ -1687,7 +1700,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok) continue; /* keep previous result */ /* replace previous result */ prevResult->pathpos = pathpos; - prevResult->oid = HeapTupleGetOid(opertup); + prevResult->oid = operform->oid; continue; /* args are same, of course */ } } @@ -1700,7 +1713,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok) nextResult += SPACE_PER_OP; newResult->pathpos = pathpos; - newResult->oid = HeapTupleGetOid(opertup); + newResult->oid = operform->oid; newResult->nargs = 2; newResult->nvargs = 0; newResult->ndargs = 0; @@ -1790,7 +1803,7 @@ OpclassnameGetOpcid(Oid amid, const char *opcname) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - opcid = GetSysCacheOid3(CLAAMNAMENSP, + opcid = GetSysCacheOid3(CLAAMNAMENSP, Anum_pg_opclass_oid, ObjectIdGetDatum(amid), PointerGetDatum(opcname), ObjectIdGetDatum(namespaceId)); @@ -1873,7 +1886,7 @@ OpfamilynameGetOpfid(Oid amid, const char *opfname) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, + opfid = GetSysCacheOid3(OPFAMILYAMNAMENSP, Anum_pg_opfamily_oid, ObjectIdGetDatum(amid), PointerGetDatum(opfname), ObjectIdGetDatum(namespaceId)); @@ -1946,7 +1959,7 @@ lookup_collation(const char *collname, Oid collnamespace, int32 encoding) Form_pg_collation collform; /* Check for encoding-specific entry (exact match) */ - collid = GetSysCacheOid3(COLLNAMEENCNSP, + collid = GetSysCacheOid3(COLLNAMEENCNSP, Anum_pg_collation_oid, PointerGetDatum(collname), Int32GetDatum(encoding), ObjectIdGetDatum(collnamespace)); @@ -1969,13 +1982,13 @@ lookup_collation(const char *collname, Oid collnamespace, int32 encoding) if (collform->collprovider == COLLPROVIDER_ICU) { if (is_encoding_supported_by_icu(encoding)) - collid = HeapTupleGetOid(colltup); + collid = collform->oid; else collid = InvalidOid; } else { - collid = HeapTupleGetOid(colltup); + collid = collform->oid; } ReleaseSysCache(colltup); return collid; @@ -2089,7 +2102,7 @@ ConversionGetConid(const char *conname) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - conid = GetSysCacheOid2(CONNAMENSP, + conid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid, PointerGetDatum(conname), ObjectIdGetDatum(namespaceId)); if (OidIsValid(conid)) @@ -2172,7 +2185,7 @@ get_statistics_object_oid(List *names, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) stats_oid = InvalidOid; else - stats_oid = GetSysCacheOid2(STATEXTNAMENSP, + stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid, PointerGetDatum(stats_name), ObjectIdGetDatum(namespaceId)); } @@ -2187,7 +2200,7 @@ get_statistics_object_oid(List *names, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - stats_oid = GetSysCacheOid2(STATEXTNAMENSP, + stats_oid = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid, PointerGetDatum(stats_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(stats_oid)) @@ -2294,7 +2307,7 @@ get_ts_parser_oid(List *names, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) prsoid = InvalidOid; else - prsoid = GetSysCacheOid2(TSPARSERNAMENSP, + prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid, PointerGetDatum(parser_name), ObjectIdGetDatum(namespaceId)); } @@ -2310,7 +2323,7 @@ get_ts_parser_oid(List *names, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - prsoid = GetSysCacheOid2(TSPARSERNAMENSP, + prsoid = GetSysCacheOid2(TSPARSERNAMENSP, Anum_pg_ts_parser_oid, PointerGetDatum(parser_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(prsoid)) @@ -2399,7 +2412,7 @@ TSParserIsVisible(Oid prsId) /* * get_ts_dict_oid - find a TS dictionary by possibly qualified name * - * If not found, returns InvalidOid if failOK, else throws error + * If not found, returns InvalidOid if missing_ok, else throws error */ Oid get_ts_dict_oid(List *names, bool missing_ok) @@ -2420,7 +2433,7 @@ get_ts_dict_oid(List *names, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) dictoid = InvalidOid; else - dictoid = GetSysCacheOid2(TSDICTNAMENSP, + dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid, PointerGetDatum(dict_name), ObjectIdGetDatum(namespaceId)); } @@ -2436,7 +2449,7 @@ get_ts_dict_oid(List *names, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - dictoid = GetSysCacheOid2(TSDICTNAMENSP, + dictoid = GetSysCacheOid2(TSDICTNAMENSP, Anum_pg_ts_dict_oid, PointerGetDatum(dict_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(dictoid)) @@ -2547,7 +2560,7 @@ get_ts_template_oid(List *names, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) tmploid = InvalidOid; else - tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, + tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid, PointerGetDatum(template_name), ObjectIdGetDatum(namespaceId)); } @@ -2563,7 +2576,7 @@ get_ts_template_oid(List *names, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, + tmploid = GetSysCacheOid2(TSTEMPLATENAMENSP, Anum_pg_ts_template_oid, PointerGetDatum(template_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(tmploid)) @@ -2673,7 +2686,7 @@ get_ts_config_oid(List *names, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) cfgoid = InvalidOid; else - cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, + cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid, PointerGetDatum(config_name), ObjectIdGetDatum(namespaceId)); } @@ -2689,7 +2702,7 @@ get_ts_config_oid(List *names, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, + cfgoid = GetSysCacheOid2(TSCONFIGNAMENSP, Anum_pg_ts_config_oid, PointerGetDatum(config_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(cfgoid)) @@ -2920,9 +2933,8 @@ LookupCreationNamespace(const char *nspname) /* check for pg_temp alias */ if (strcmp(nspname, "pg_temp") == 0) { - /* Initialize temp namespace if first time through */ - if (!OidIsValid(myTempNamespace)) - InitTempTableNamespace(); + /* Initialize temp namespace */ + AccessTempTableNamespace(false); return myTempNamespace; } @@ -2985,9 +2997,8 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p) /* check for pg_temp alias */ if (strcmp(schemaname, "pg_temp") == 0) { - /* Initialize temp namespace if first time through */ - if (!OidIsValid(myTempNamespace)) - InitTempTableNamespace(); + /* Initialize temp namespace */ + AccessTempTableNamespace(false); return myTempNamespace; } /* use exact schema given */ @@ -3001,7 +3012,7 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p) if (activeTempCreationPending) { /* Need to initialize temp namespace */ - InitTempTableNamespace(); + AccessTempTableNamespace(true); return myTempNamespace; } namespaceId = activeCreationNamespace; @@ -3025,7 +3036,8 @@ get_namespace_oid(const char *nspname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(NAMESPACENAME, CStringGetDatum(nspname)); + oid = GetSysCacheOid1(NAMESPACENAME, Anum_pg_namespace_oid, + CStringGetDatum(nspname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), @@ -3204,6 +3216,46 @@ isOtherTempNamespace(Oid namespaceId) return isAnyTempNamespace(namespaceId); } +/* + * isTempNamespaceInUse - is the given namespace owned and actively used + * by a backend? + * + * Note: this can be used while scanning relations in pg_class to detect + * orphaned temporary tables or namespaces with a backend connected to a + * given database. The result may be out of date quickly, so the caller + * must be careful how to handle this information. + */ +bool +isTempNamespaceInUse(Oid namespaceId) +{ + PGPROC *proc; + int backendId; + + Assert(OidIsValid(MyDatabaseId)); + + backendId = GetTempNamespaceBackendId(namespaceId); + + if (backendId == InvalidBackendId || + backendId == MyBackendId) + return false; + + /* Is the backend alive? */ + proc = BackendIdGetProc(backendId); + if (proc == NULL) + return false; + + /* Is the backend connected to the same database we are looking at? */ + if (proc->databaseId != MyDatabaseId) + return false; + + /* Does the backend own the temporary namespace? */ + if (proc->tempNamespaceId != namespaceId) + return false; + + /* all good to go */ + return true; +} + /* * GetTempNamespaceBackendId - if the given namespace is a temporary-table * namespace (either my own, or another backend's), return the BackendId @@ -3363,7 +3415,7 @@ OverrideSearchPathMatchesCurrent(OverrideSearchPath *path) if (path->addTemp) { if (lc && lfirst_oid(lc) == myTempNamespace) - lc = lnext(lc); + lc = lnext(activeSearchPath, lc); else return false; } @@ -3371,7 +3423,7 @@ OverrideSearchPathMatchesCurrent(OverrideSearchPath *path) if (path->addCatalog) { if (lc && lfirst_oid(lc) == PG_CATALOG_NAMESPACE) - lc = lnext(lc); + lc = lnext(activeSearchPath, lc); else return false; } @@ -3382,7 +3434,7 @@ OverrideSearchPathMatchesCurrent(OverrideSearchPath *path) foreach(lcp, path->schemas) { if (lc && lfirst_oid(lc) == lfirst_oid(lcp)) - lc = lnext(lc); + lc = lnext(activeSearchPath, lc); else return false; } @@ -3581,7 +3633,7 @@ get_conversion_oid(List *name, bool missing_ok) if (missing_ok && !OidIsValid(namespaceId)) conoid = InvalidOid; else - conoid = GetSysCacheOid2(CONNAMENSP, + conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid, PointerGetDatum(conversion_name), ObjectIdGetDatum(namespaceId)); } @@ -3597,7 +3649,7 @@ get_conversion_oid(List *name, bool missing_ok) if (namespaceId == myTempNamespace) continue; /* do not look in temp namespace */ - conoid = GetSysCacheOid2(CONNAMENSP, + conoid = GetSysCacheOid2(CONNAMENSP, Anum_pg_conversion_oid, PointerGetDatum(conversion_name), ObjectIdGetDatum(namespaceId)); if (OidIsValid(conoid)) @@ -3790,6 +3842,38 @@ recomputeNamespacePath(void) list_free(oidlist); } +/* + * AccessTempTableNamespace + * Provide access to a temporary namespace, potentially creating it + * if not present yet. This routine registers if the namespace gets + * in use in this transaction. 'force' can be set to true to allow + * the caller to enforce the creation of the temporary namespace for + * use in this backend, which happens if its creation is pending. + */ +static void +AccessTempTableNamespace(bool force) +{ + /* + * Make note that this temporary namespace has been accessed in this + * transaction. + */ + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + + /* + * If the caller attempting to access a temporary schema expects the + * creation of the namespace to be pending and should be enforced, then go + * through the creation. + */ + if (!force && OidIsValid(myTempNamespace)) + return; + + /* + * The temporary tablespace does not exist yet and is wanted, so + * initialize it. + */ + InitTempTableNamespace(); +} + /* * InitTempTableNamespace * Initialize temp table namespace on first use in a particular backend @@ -3893,6 +3977,18 @@ InitTempTableNamespace(void) myTempNamespace = namespaceId; myTempToastNamespace = toastspaceId; + /* + * Mark MyProc as owning this namespace which other processes can use to + * decide if a temporary namespace is in use or not. We assume that + * assignment of namespaceId is an atomic operation. Even if it is not, + * the temporary relation which resulted in the creation of this temporary + * namespace is still locked until the current transaction commits, and + * its pg_namespace row is not visible yet. However it does not matter: + * this flag makes the namespace as being in use, so no objects created on + * it would be removed concurrently. + */ + MyProc->tempNamespaceId = namespaceId; + /* It should not be done already. */ AssertState(myTempNamespaceSubID == InvalidSubTransactionId); myTempNamespaceSubID = GetCurrentSubTransactionId(); @@ -3923,6 +4019,17 @@ AtEOXact_Namespace(bool isCommit, bool parallel) myTempNamespace = InvalidOid; myTempToastNamespace = InvalidOid; baseSearchPathValid = false; /* need to rebuild list */ + + /* + * Reset the temporary namespace flag in MyProc. We assume that + * this operation is atomic. + * + * Because this transaction is aborting, the pg_namespace row is + * not visible to anyone else anyway, but that doesn't matter: + * it's not a problem if objects contained in this namespace are + * removed concurrently. + */ + MyProc->tempNamespaceId = InvalidOid; } myTempNamespaceSubID = InvalidSubTransactionId; } @@ -3975,6 +4082,17 @@ AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, myTempNamespace = InvalidOid; myTempToastNamespace = InvalidOid; baseSearchPathValid = false; /* need to rebuild list */ + + /* + * Reset the temporary namespace flag in MyProc. We assume that + * this operation is atomic. + * + * Because this subtransaction is aborting, the pg_namespace row + * is not visible to anyone else anyway, but that doesn't matter: + * it's not a problem if objects contained in this namespace are + * removed concurrently. + */ + MyProc->tempNamespaceId = InvalidOid; } } @@ -4199,7 +4317,7 @@ fetch_search_path(bool includeImplicit) */ if (activeTempCreationPending) { - InitTempTableNamespace(); + AccessTempTableNamespace(true); recomputeNamespacePath(); } diff --git a/src/backend/catalog/objectaccess.c b/src/backend/catalog/objectaccess.c index 65884699c44..b1619b859f2 100644 --- a/src/backend/catalog/objectaccess.c +++ b/src/backend/catalog/objectaccess.c @@ -3,7 +3,7 @@ * objectaccess.c * functions for object_access_hook on various events * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 3cbee108c38..ce8a4e927da 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -3,7 +3,7 @@ * objectaddress.c * functions for working with ObjectAddresses * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,11 @@ #include "postgres.h" +#include "access/genam.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/catalog.h" #include "catalog/indexing.h" #include "catalog/objectaddress.h" @@ -27,6 +30,7 @@ #include "catalog/pg_authid.h" #include "catalog/pg_cast.h" #include "catalog/pg_default_acl.h" +#include "catalog/pg_enum.h" #include "catalog/pg_event_trigger.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -83,7 +87,6 @@ #include "utils/memutils.h" #include "utils/regproc.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* * ObjectProperty @@ -99,6 +102,7 @@ typedef struct int name_catcache_id; /* id of catcache on (name,namespace), or * (name) if the object does not live in a * namespace */ + AttrNumber attnum_oid; /* attribute number of oid column */ AttrNumber attnum_name; /* attnum of name field */ AttrNumber attnum_namespace; /* attnum of namespace field */ AttrNumber attnum_owner; /* attnum of owner field */ @@ -117,6 +121,7 @@ static const ObjectPropertyType ObjectProperty[] = AmOidIndexId, AMOID, AMNAME, + Anum_pg_am_oid, Anum_pg_am_amname, InvalidAttrNumber, InvalidAttrNumber, @@ -129,6 +134,7 @@ static const ObjectPropertyType ObjectProperty[] = CastOidIndexId, -1, -1, + Anum_pg_cast_oid, InvalidAttrNumber, InvalidAttrNumber, InvalidAttrNumber, @@ -141,6 +147,7 @@ static const ObjectPropertyType ObjectProperty[] = CollationOidIndexId, COLLOID, -1, /* COLLNAMEENCNSP also takes encoding */ + Anum_pg_collation_oid, Anum_pg_collation_collname, Anum_pg_collation_collnamespace, Anum_pg_collation_collowner, @@ -153,6 +160,7 @@ static const ObjectPropertyType ObjectProperty[] = ConstraintOidIndexId, CONSTROID, -1, + Anum_pg_constraint_oid, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, InvalidAttrNumber, @@ -165,6 +173,7 @@ static const ObjectPropertyType ObjectProperty[] = ConversionOidIndexId, CONVOID, CONNAMENSP, + Anum_pg_conversion_oid, Anum_pg_conversion_conname, Anum_pg_conversion_connamespace, Anum_pg_conversion_conowner, @@ -177,6 +186,7 @@ static const ObjectPropertyType ObjectProperty[] = DatabaseOidIndexId, DATABASEOID, -1, + Anum_pg_database_oid, Anum_pg_database_datname, InvalidAttrNumber, Anum_pg_database_datdba, @@ -189,6 +199,7 @@ static const ObjectPropertyType ObjectProperty[] = ExtensionOidIndexId, -1, -1, + Anum_pg_extension_oid, Anum_pg_extension_extname, InvalidAttrNumber, /* extension doesn't belong to extnamespace */ Anum_pg_extension_extowner, @@ -201,6 +212,7 @@ static const ObjectPropertyType ObjectProperty[] = ForeignDataWrapperOidIndexId, FOREIGNDATAWRAPPEROID, FOREIGNDATAWRAPPERNAME, + Anum_pg_foreign_data_wrapper_oid, Anum_pg_foreign_data_wrapper_fdwname, InvalidAttrNumber, Anum_pg_foreign_data_wrapper_fdwowner, @@ -213,6 +225,7 @@ static const ObjectPropertyType ObjectProperty[] = ForeignServerOidIndexId, FOREIGNSERVEROID, FOREIGNSERVERNAME, + Anum_pg_foreign_server_oid, Anum_pg_foreign_server_srvname, InvalidAttrNumber, Anum_pg_foreign_server_srvowner, @@ -225,6 +238,7 @@ static const ObjectPropertyType ObjectProperty[] = ProcedureOidIndexId, PROCOID, -1, /* PROCNAMEARGSNSP also takes argument types */ + Anum_pg_proc_oid, Anum_pg_proc_proname, Anum_pg_proc_pronamespace, Anum_pg_proc_proowner, @@ -237,6 +251,7 @@ static const ObjectPropertyType ObjectProperty[] = LanguageOidIndexId, LANGOID, LANGNAME, + Anum_pg_language_oid, Anum_pg_language_lanname, InvalidAttrNumber, Anum_pg_language_lanowner, @@ -249,6 +264,7 @@ static const ObjectPropertyType ObjectProperty[] = LargeObjectMetadataOidIndexId, -1, -1, + Anum_pg_largeobject_metadata_oid, InvalidAttrNumber, InvalidAttrNumber, Anum_pg_largeobject_metadata_lomowner, @@ -261,6 +277,7 @@ static const ObjectPropertyType ObjectProperty[] = OpclassOidIndexId, CLAOID, -1, /* CLAAMNAMENSP also takes opcmethod */ + Anum_pg_opclass_oid, Anum_pg_opclass_opcname, Anum_pg_opclass_opcnamespace, Anum_pg_opclass_opcowner, @@ -273,6 +290,7 @@ static const ObjectPropertyType ObjectProperty[] = OperatorOidIndexId, OPEROID, -1, /* OPERNAMENSP also takes left and right type */ + Anum_pg_operator_oid, Anum_pg_operator_oprname, Anum_pg_operator_oprnamespace, Anum_pg_operator_oprowner, @@ -285,6 +303,7 @@ static const ObjectPropertyType ObjectProperty[] = OpfamilyOidIndexId, OPFAMILYOID, -1, /* OPFAMILYAMNAMENSP also takes opfmethod */ + Anum_pg_opfamily_oid, Anum_pg_opfamily_opfname, Anum_pg_opfamily_opfnamespace, Anum_pg_opfamily_opfowner, @@ -297,6 +316,7 @@ static const ObjectPropertyType ObjectProperty[] = AuthIdOidIndexId, AUTHOID, AUTHNAME, + Anum_pg_authid_oid, Anum_pg_authid_rolname, InvalidAttrNumber, InvalidAttrNumber, @@ -309,6 +329,7 @@ static const ObjectPropertyType ObjectProperty[] = RewriteOidIndexId, -1, -1, + Anum_pg_rewrite_oid, Anum_pg_rewrite_rulename, InvalidAttrNumber, InvalidAttrNumber, @@ -321,6 +342,7 @@ static const ObjectPropertyType ObjectProperty[] = NamespaceOidIndexId, NAMESPACEOID, NAMESPACENAME, + Anum_pg_namespace_oid, Anum_pg_namespace_nspname, InvalidAttrNumber, Anum_pg_namespace_nspowner, @@ -333,6 +355,7 @@ static const ObjectPropertyType ObjectProperty[] = ClassOidIndexId, RELOID, RELNAMENSP, + Anum_pg_class_oid, Anum_pg_class_relname, Anum_pg_class_relnamespace, Anum_pg_class_relowner, @@ -345,6 +368,7 @@ static const ObjectPropertyType ObjectProperty[] = TablespaceOidIndexId, TABLESPACEOID, -1, + Anum_pg_tablespace_oid, Anum_pg_tablespace_spcname, InvalidAttrNumber, Anum_pg_tablespace_spcowner, @@ -356,13 +380,15 @@ static const ObjectPropertyType ObjectProperty[] = TransformRelationId, TransformOidIndexId, TRFOID, - InvalidAttrNumber + InvalidAttrNumber, + Anum_pg_transform_oid }, { TriggerRelationId, TriggerOidIndexId, -1, -1, + Anum_pg_trigger_oid, Anum_pg_trigger_tgname, InvalidAttrNumber, InvalidAttrNumber, @@ -375,6 +401,7 @@ static const ObjectPropertyType ObjectProperty[] = PolicyOidIndexId, -1, -1, + Anum_pg_policy_oid, Anum_pg_policy_polname, InvalidAttrNumber, InvalidAttrNumber, @@ -387,6 +414,7 @@ static const ObjectPropertyType ObjectProperty[] = EventTriggerOidIndexId, EVENTTRIGGEROID, EVENTTRIGGERNAME, + Anum_pg_event_trigger_oid, Anum_pg_event_trigger_evtname, InvalidAttrNumber, Anum_pg_event_trigger_evtowner, @@ -399,6 +427,7 @@ static const ObjectPropertyType ObjectProperty[] = TSConfigOidIndexId, TSCONFIGOID, TSCONFIGNAMENSP, + Anum_pg_ts_config_oid, Anum_pg_ts_config_cfgname, Anum_pg_ts_config_cfgnamespace, Anum_pg_ts_config_cfgowner, @@ -411,6 +440,7 @@ static const ObjectPropertyType ObjectProperty[] = TSDictionaryOidIndexId, TSDICTOID, TSDICTNAMENSP, + Anum_pg_ts_dict_oid, Anum_pg_ts_dict_dictname, Anum_pg_ts_dict_dictnamespace, Anum_pg_ts_dict_dictowner, @@ -423,6 +453,7 @@ static const ObjectPropertyType ObjectProperty[] = TSParserOidIndexId, TSPARSEROID, TSPARSERNAMENSP, + Anum_pg_ts_parser_oid, Anum_pg_ts_parser_prsname, Anum_pg_ts_parser_prsnamespace, InvalidAttrNumber, @@ -435,6 +466,7 @@ static const ObjectPropertyType ObjectProperty[] = TSTemplateOidIndexId, TSTEMPLATEOID, TSTEMPLATENAMENSP, + Anum_pg_ts_template_oid, Anum_pg_ts_template_tmplname, Anum_pg_ts_template_tmplnamespace, InvalidAttrNumber, @@ -447,6 +479,7 @@ static const ObjectPropertyType ObjectProperty[] = TypeOidIndexId, TYPEOID, TYPENAMENSP, + Anum_pg_type_oid, Anum_pg_type_typname, Anum_pg_type_typnamespace, Anum_pg_type_typowner, @@ -459,6 +492,7 @@ static const ObjectPropertyType ObjectProperty[] = PublicationObjectIndexId, PUBLICATIONOID, PUBLICATIONNAME, + Anum_pg_publication_oid, Anum_pg_publication_pubname, InvalidAttrNumber, Anum_pg_publication_pubowner, @@ -471,6 +505,7 @@ static const ObjectPropertyType ObjectProperty[] = SubscriptionObjectIndexId, SUBSCRIPTIONOID, SUBSCRIPTIONNAME, + Anum_pg_subscription_oid, Anum_pg_subscription_subname, InvalidAttrNumber, Anum_pg_subscription_subowner, @@ -483,6 +518,7 @@ static const ObjectPropertyType ObjectProperty[] = StatisticExtOidIndexId, STATEXTOID, STATEXTNAMENSP, + Anum_pg_statistic_ext_oid, Anum_pg_statistic_ext_stxname, Anum_pg_statistic_ext_stxnamespace, Anum_pg_statistic_ext_stxowner, @@ -494,7 +530,7 @@ static const ObjectPropertyType ObjectProperty[] = /* * This struct maps the string object types as returned by - * getObjectTypeDescription into ObjType enum values. Note that some enum + * getObjectTypeDescription into ObjectType enum values. Note that some enum * values can be obtained by different names, and that some string object types * do not have corresponding values in the output enum. The user of this map * must be careful to test for invalid values being returned. @@ -725,38 +761,38 @@ const ObjectAddress InvalidObjectAddress = }; static ObjectAddress get_object_address_unqualified(ObjectType objtype, - Value *strval, bool missing_ok); + Value *strval, bool missing_ok); static ObjectAddress get_relation_by_qualified_name(ObjectType objtype, - List *object, Relation *relp, - LOCKMODE lockmode, bool missing_ok); + List *object, Relation *relp, + LOCKMODE lockmode, bool missing_ok); static ObjectAddress get_object_address_relobject(ObjectType objtype, - List *object, Relation *relp, bool missing_ok); + List *object, Relation *relp, bool missing_ok); static ObjectAddress get_object_address_attribute(ObjectType objtype, - List *object, Relation *relp, - LOCKMODE lockmode, bool missing_ok); + List *object, Relation *relp, + LOCKMODE lockmode, bool missing_ok); static ObjectAddress get_object_address_attrdef(ObjectType objtype, - List *object, Relation *relp, LOCKMODE lockmode, - bool missing_ok); + List *object, Relation *relp, LOCKMODE lockmode, + bool missing_ok); static ObjectAddress get_object_address_type(ObjectType objtype, - TypeName *typename, bool missing_ok); + TypeName *typename, bool missing_ok); static ObjectAddress get_object_address_opcf(ObjectType objtype, List *object, - bool missing_ok); + bool missing_ok); static ObjectAddress get_object_address_opf_member(ObjectType objtype, - List *object, bool missing_ok); + List *object, bool missing_ok); static ObjectAddress get_object_address_usermapping(List *object, - bool missing_ok); + bool missing_ok); static ObjectAddress get_object_address_publication_rel(List *object, - Relation *relp, - bool missing_ok); + Relation *relp, + bool missing_ok); static ObjectAddress get_object_address_defacl(List *object, - bool missing_ok); + bool missing_ok); static const ObjectPropertyType *get_object_property_data(Oid class_id); static void getRelationDescription(StringInfo buffer, Oid relid); static void getOpFamilyDescription(StringInfo buffer, Oid opfid); static void getRelationTypeDescription(StringInfo buffer, Oid relid, - int32 objectSubId); + int32 objectSubId); static void getProcedureTypeDescription(StringInfo buffer, Oid procid); static void getConstraintTypeDescription(StringInfo buffer, Oid constroid); static void getOpFamilyIdentity(StringInfo buffer, Oid opfid, List **object); @@ -1301,9 +1337,9 @@ get_object_address_relobject(ObjectType objtype, List *object, /* Extract relation name and open relation. */ relname = list_truncate(list_copy(object), nnames - 1); - relation = heap_openrv_extended(makeRangeVarFromNameList(relname), - AccessShareLock, - missing_ok); + relation = table_openrv_extended(makeRangeVarFromNameList(relname), + AccessShareLock, + missing_ok); reloid = relation ? RelationGetRelid(relation) : InvalidOid; @@ -1343,7 +1379,7 @@ get_object_address_relobject(ObjectType objtype, List *object, if (!OidIsValid(address.objectId)) { if (relation != NULL) - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); relation = NULL; /* department of accident prevention */ return address; @@ -1459,7 +1495,11 @@ get_object_address_attrdef(ObjectType objtype, List *object, scan = systable_beginscan(attrdef, AttrDefaultIndexId, true, NULL, 2, keys); if (HeapTupleIsValid(tup = systable_getnext(scan))) - defoid = HeapTupleGetOid(tup); + { + Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup); + + defoid = atdform->oid; + } systable_endscan(scan); relation_close(attrdef, AccessShareLock); @@ -1633,7 +1673,7 @@ get_object_address_opf_member(ObjectType objtype, } else { - address.objectId = HeapTupleGetOid(tp); + address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); } } @@ -1664,7 +1704,7 @@ get_object_address_opf_member(ObjectType objtype, } else { - address.objectId = HeapTupleGetOid(tp); + address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); } } @@ -1711,7 +1751,7 @@ get_object_address_usermapping(List *object, bool missing_ok) username, servername))); return address; } - userid = HeapTupleGetOid(tp); + userid = ((Form_pg_authid) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); } @@ -1738,7 +1778,7 @@ get_object_address_usermapping(List *object, bool missing_ok) return address; } - address.objectId = HeapTupleGetOid(tp); + address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); @@ -1781,7 +1821,7 @@ get_object_address_publication_rel(List *object, /* Find the publication relation mapping in syscache. */ address.objectId = - GetSysCacheOid2(PUBLICATIONRELMAP, + GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid, ObjectIdGetDatum(RelationGetRelid(relation)), ObjectIdGetDatum(pub->oid)); if (!OidIsValid(address.objectId)) @@ -1868,7 +1908,7 @@ get_object_address_defacl(List *object, bool missing_ok) CStringGetDatum(username)); if (!HeapTupleIsValid(tp)) goto not_found; - userid = HeapTupleGetOid(tp); + userid = ((Form_pg_authid) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); /* @@ -1892,7 +1932,7 @@ get_object_address_defacl(List *object, bool missing_ok) if (!HeapTupleIsValid(tp)) goto not_found; - address.objectId = HeapTupleGetOid(tp); + address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid; ReleaseSysCache(tp); return address; @@ -2062,8 +2102,8 @@ pg_get_object_address(PG_FUNCTION_ARGS) } /* - * get_object_address is pretty sensitive to the length its input lists; - * check that they're what it wants. + * get_object_address is pretty sensitive to the length of its input + * lists; check that they're what it wants. */ switch (type) { @@ -2092,6 +2132,7 @@ pg_get_object_address(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("name list length must be at least %d", 3))); /* fall through to check args length */ + /* FALLTHROUGH */ case OBJECT_OPERATOR: if (list_length(args) != 2) ereport(ERROR, @@ -2201,7 +2242,7 @@ pg_get_object_address(PG_FUNCTION_ARGS) if (relation) relation_close(relation, AccessShareLock); - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "classid", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "objid", @@ -2254,10 +2295,32 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, case OBJECT_TYPE: case OBJECT_DOMAIN: case OBJECT_ATTRIBUTE: - case OBJECT_DOMCONSTRAINT: if (!pg_type_ownercheck(address.objectId, roleid)) aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId); break; + case OBJECT_DOMCONSTRAINT: + { + HeapTuple tuple; + Oid contypid; + + tuple = SearchSysCache1(CONSTROID, + ObjectIdGetDatum(address.objectId)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "constraint with OID %u does not exist", + address.objectId); + + contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid; + + ReleaseSysCache(tuple); + + /* + * Fallback to type ownership check in this case as this is + * what domain constraints rely on. + */ + if (!pg_type_ownercheck(contypid, roleid)) + aclcheck_error_type(ACLCHECK_NOT_OWNER, contypid); + } + break; case OBJECT_AGGREGATE: case OBJECT_FUNCTION: case OBJECT_PROCEDURE: @@ -2509,6 +2572,14 @@ get_object_catcache_name(Oid class_id) return prop->name_catcache_id; } +AttrNumber +get_object_attnum_oid(Oid class_id) +{ + const ObjectPropertyType *prop = get_object_property_data(class_id); + + return prop->attnum_oid; +} + AttrNumber get_object_attnum_name(Oid class_id) { @@ -2624,7 +2695,7 @@ get_object_property_data(Oid class_id) * We try a syscache first, if available. */ HeapTuple -get_catalog_object_by_oid(Relation catalog, Oid objectId) +get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId) { HeapTuple tuple; Oid classId = RelationGetRelid(catalog); @@ -2645,7 +2716,7 @@ get_catalog_object_by_oid(Relation catalog, Oid objectId) Assert(OidIsValid(oidIndexId)); ScanKeyInit(&skey, - ObjectIdAttributeNumber, + oidcol, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); @@ -2680,12 +2751,23 @@ getObjectDescription(const ObjectAddress *object) switch (getObjectClass(object)) { case OCLASS_CLASS: - getRelationDescription(&buffer, object->objectId); - if (object->objectSubId != 0) - appendStringInfo(&buffer, _(" column %s"), + if (object->objectSubId == 0) + getRelationDescription(&buffer, object->objectId); + else + { + /* column, not whole relation */ + StringInfoData rel; + + initStringInfo(&rel); + getRelationDescription(&rel, object->objectId); + /* translator: second %s is, e.g., "table %s" */ + appendStringInfo(&buffer, _("column %s of %s"), get_attname(object->objectId, object->objectSubId, - false)); + false), + rel.data); + pfree(rel.data); + } break; case OCLASS_PROC: @@ -2706,10 +2788,10 @@ getObjectDescription(const ObjectAddress *object) HeapTuple tup; Form_pg_cast castForm; - castDesc = heap_open(CastRelationId, AccessShareLock); + castDesc = table_open(CastRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_cast_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -2729,7 +2811,7 @@ getObjectDescription(const ObjectAddress *object) format_type_be(castForm->casttarget)); systable_endscan(rcscan); - heap_close(castDesc, AccessShareLock); + table_close(castDesc, AccessShareLock); break; } @@ -2737,6 +2819,7 @@ getObjectDescription(const ObjectAddress *object) { HeapTuple collTup; Form_pg_collation coll; + char *nspname; collTup = SearchSysCache1(COLLOID, ObjectIdGetDatum(object->objectId)); @@ -2744,8 +2827,16 @@ getObjectDescription(const ObjectAddress *object) elog(ERROR, "cache lookup failed for collation %u", object->objectId); coll = (Form_pg_collation) GETSTRUCT(collTup); + + /* Qualify the name if not visible in search path */ + if (CollationIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(coll->collnamespace); + appendStringInfo(&buffer, _("collation %s"), - NameStr(coll->collname)); + quote_qualified_identifier(nspname, + NameStr(coll->collname))); ReleaseSysCache(collTup); break; } @@ -2768,6 +2859,7 @@ getObjectDescription(const ObjectAddress *object) initStringInfo(&rel); getRelationDescription(&rel, con->conrelid); + /* translator: second %s is, e.g., "table %s" */ appendStringInfo(&buffer, _("constraint %s on %s"), NameStr(con->conname), rel.data); pfree(rel.data); @@ -2785,14 +2877,25 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_CONVERSION: { HeapTuple conTup; + Form_pg_conversion conv; + char *nspname; conTup = SearchSysCache1(CONVOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(conTup)) elog(ERROR, "cache lookup failed for conversion %u", object->objectId); + conv = (Form_pg_conversion) GETSTRUCT(conTup); + + /* Qualify the name if not visible in search path */ + if (ConversionIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(conv->connamespace); + appendStringInfo(&buffer, _("conversion %s"), - NameStr(((Form_pg_conversion) GETSTRUCT(conTup))->conname)); + quote_qualified_identifier(nspname, + NameStr(conv->conname))); ReleaseSysCache(conTup); break; } @@ -2806,10 +2909,10 @@ getObjectDescription(const ObjectAddress *object) Form_pg_attrdef attrdef; ObjectAddress colobject; - attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock); + attrdefDesc = table_open(AttrDefaultRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_attrdef_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -2828,11 +2931,12 @@ getObjectDescription(const ObjectAddress *object) colobject.objectId = attrdef->adrelid; colobject.objectSubId = attrdef->adnum; - appendStringInfo(&buffer, _("default for %s"), + /* translator: %s is typically "column %s of table %s" */ + appendStringInfo(&buffer, _("default value for %s"), getObjectDescription(&colobject)); systable_endscan(adscan); - heap_close(attrdefDesc, AccessShareLock); + table_close(attrdefDesc, AccessShareLock); break; } @@ -2917,11 +3021,11 @@ getObjectDescription(const ObjectAddress *object) Form_pg_amop amopForm; StringInfoData opfam; - amopDesc = heap_open(AccessMethodOperatorRelationId, - AccessShareLock); + amopDesc = table_open(AccessMethodOperatorRelationId, + AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amop_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -2954,7 +3058,7 @@ getObjectDescription(const ObjectAddress *object) pfree(opfam.data); systable_endscan(amscan); - heap_close(amopDesc, AccessShareLock); + table_close(amopDesc, AccessShareLock); break; } @@ -2967,11 +3071,11 @@ getObjectDescription(const ObjectAddress *object) Form_pg_amproc amprocForm; StringInfoData opfam; - amprocDesc = heap_open(AccessMethodProcedureRelationId, - AccessShareLock); + amprocDesc = table_open(AccessMethodProcedureRelationId, + AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amproc_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -3004,7 +3108,7 @@ getObjectDescription(const ObjectAddress *object) pfree(opfam.data); systable_endscan(amscan); - heap_close(amprocDesc, AccessShareLock); + table_close(amprocDesc, AccessShareLock); break; } @@ -3015,11 +3119,12 @@ getObjectDescription(const ObjectAddress *object) SysScanDesc rcscan; HeapTuple tup; Form_pg_rewrite rule; + StringInfoData rel; - ruleDesc = heap_open(RewriteRelationId, AccessShareLock); + ruleDesc = table_open(RewriteRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_rewrite_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -3031,15 +3136,17 @@ getObjectDescription(const ObjectAddress *object) if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for rule %u", object->objectId); - rule = (Form_pg_rewrite) GETSTRUCT(tup); - appendStringInfo(&buffer, _("rule %s on "), - NameStr(rule->rulename)); - getRelationDescription(&buffer, rule->ev_class); + initStringInfo(&rel); + getRelationDescription(&rel, rule->ev_class); + /* translator: second %s is, e.g., "table %s" */ + appendStringInfo(&buffer, _("rule %s on %s"), + NameStr(rule->rulename), rel.data); + pfree(rel.data); systable_endscan(rcscan); - heap_close(ruleDesc, AccessShareLock); + table_close(ruleDesc, AccessShareLock); break; } @@ -3050,11 +3157,12 @@ getObjectDescription(const ObjectAddress *object) SysScanDesc tgscan; HeapTuple tup; Form_pg_trigger trig; + StringInfoData rel; - trigDesc = heap_open(TriggerRelationId, AccessShareLock); + trigDesc = table_open(TriggerRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_trigger_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -3066,15 +3174,17 @@ getObjectDescription(const ObjectAddress *object) if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for trigger %u", object->objectId); - trig = (Form_pg_trigger) GETSTRUCT(tup); - appendStringInfo(&buffer, _("trigger %s on "), - NameStr(trig->tgname)); - getRelationDescription(&buffer, trig->tgrelid); + initStringInfo(&rel); + getRelationDescription(&rel, trig->tgrelid); + /* translator: second %s is, e.g., "table %s" */ + appendStringInfo(&buffer, _("trigger %s on %s"), + NameStr(trig->tgname), rel.data); + pfree(rel.data); systable_endscan(tgscan); - heap_close(trigDesc, AccessShareLock); + table_close(trigDesc, AccessShareLock); break; } @@ -3094,17 +3204,24 @@ getObjectDescription(const ObjectAddress *object) { HeapTuple stxTup; Form_pg_statistic_ext stxForm; + char *nspname; stxTup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(stxTup)) elog(ERROR, "could not find tuple for statistics object %u", object->objectId); - stxForm = (Form_pg_statistic_ext) GETSTRUCT(stxTup); + /* Qualify the name if not visible in search path */ + if (StatisticsObjIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(stxForm->stxnamespace); + appendStringInfo(&buffer, _("statistics object %s"), - NameStr(stxForm->stxname)); + quote_qualified_identifier(nspname, + NameStr(stxForm->stxname))); ReleaseSysCache(stxTup); break; @@ -3113,14 +3230,25 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_TSPARSER: { HeapTuple tup; + Form_pg_ts_parser prsForm; + char *nspname; tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search parser %u", object->objectId); + prsForm = (Form_pg_ts_parser) GETSTRUCT(tup); + + /* Qualify the name if not visible in search path */ + if (TSParserIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(prsForm->prsnamespace); + appendStringInfo(&buffer, _("text search parser %s"), - NameStr(((Form_pg_ts_parser) GETSTRUCT(tup))->prsname)); + quote_qualified_identifier(nspname, + NameStr(prsForm->prsname))); ReleaseSysCache(tup); break; } @@ -3128,14 +3256,25 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_TSDICT: { HeapTuple tup; + Form_pg_ts_dict dictForm; + char *nspname; tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search dictionary %u", object->objectId); + dictForm = (Form_pg_ts_dict) GETSTRUCT(tup); + + /* Qualify the name if not visible in search path */ + if (TSDictionaryIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(dictForm->dictnamespace); + appendStringInfo(&buffer, _("text search dictionary %s"), - NameStr(((Form_pg_ts_dict) GETSTRUCT(tup))->dictname)); + quote_qualified_identifier(nspname, + NameStr(dictForm->dictname))); ReleaseSysCache(tup); break; } @@ -3143,14 +3282,25 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_TSTEMPLATE: { HeapTuple tup; + Form_pg_ts_template tmplForm; + char *nspname; tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search template %u", object->objectId); + tmplForm = (Form_pg_ts_template) GETSTRUCT(tup); + + /* Qualify the name if not visible in search path */ + if (TSTemplateIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(tmplForm->tmplnamespace); + appendStringInfo(&buffer, _("text search template %s"), - NameStr(((Form_pg_ts_template) GETSTRUCT(tup))->tmplname)); + quote_qualified_identifier(nspname, + NameStr(tmplForm->tmplname))); ReleaseSysCache(tup); break; } @@ -3158,14 +3308,25 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_TSCONFIG: { HeapTuple tup; + Form_pg_ts_config cfgForm; + char *nspname; tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(object->objectId)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for text search configuration %u", object->objectId); + cfgForm = (Form_pg_ts_config) GETSTRUCT(tup); + + /* Qualify the name if not visible in search path */ + if (TSConfigIsVisible(object->objectId)) + nspname = NULL; + else + nspname = get_namespace_name(cfgForm->cfgnamespace); + appendStringInfo(&buffer, _("text search configuration %s"), - NameStr(((Form_pg_ts_config) GETSTRUCT(tup))->cfgname)); + quote_qualified_identifier(nspname, + NameStr(cfgForm->cfgname))); ReleaseSysCache(tup); break; } @@ -3255,11 +3416,13 @@ getObjectDescription(const ObjectAddress *object) SysScanDesc rcscan; HeapTuple tup; Form_pg_default_acl defacl; + char *rolename; + char *nspname; - defaclrel = heap_open(DefaultAclRelationId, AccessShareLock); + defaclrel = table_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_default_acl_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -3274,50 +3437,76 @@ getObjectDescription(const ObjectAddress *object) defacl = (Form_pg_default_acl) GETSTRUCT(tup); + rolename = GetUserNameFromId(defacl->defaclrole, false); + + if (OidIsValid(defacl->defaclnamespace)) + nspname = get_namespace_name(defacl->defaclnamespace); + else + nspname = NULL; + switch (defacl->defaclobjtype) { case DEFACLOBJ_RELATION: - appendStringInfo(&buffer, - _("default privileges on new relations belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + if (nspname) + appendStringInfo(&buffer, + _("default privileges on new relations belonging to role %s in schema %s"), + rolename, nspname); + else + appendStringInfo(&buffer, + _("default privileges on new relations belonging to role %s"), + rolename); break; case DEFACLOBJ_SEQUENCE: - appendStringInfo(&buffer, - _("default privileges on new sequences belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + if (nspname) + appendStringInfo(&buffer, + _("default privileges on new sequences belonging to role %s in schema %s"), + rolename, nspname); + else + appendStringInfo(&buffer, + _("default privileges on new sequences belonging to role %s"), + rolename); break; case DEFACLOBJ_FUNCTION: - appendStringInfo(&buffer, - _("default privileges on new functions belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + if (nspname) + appendStringInfo(&buffer, + _("default privileges on new functions belonging to role %s in schema %s"), + rolename, nspname); + else + appendStringInfo(&buffer, + _("default privileges on new functions belonging to role %s"), + rolename); break; case DEFACLOBJ_TYPE: - appendStringInfo(&buffer, - _("default privileges on new types belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + if (nspname) + appendStringInfo(&buffer, + _("default privileges on new types belonging to role %s in schema %s"), + rolename, nspname); + else + appendStringInfo(&buffer, + _("default privileges on new types belonging to role %s"), + rolename); break; case DEFACLOBJ_NAMESPACE: + Assert(!nspname); appendStringInfo(&buffer, _("default privileges on new schemas belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + rolename); break; default: /* shouldn't get here */ - appendStringInfo(&buffer, - _("default privileges belonging to role %s"), - GetUserNameFromId(defacl->defaclrole, false)); + if (nspname) + appendStringInfo(&buffer, + _("default privileges belonging to role %s in schema %s"), + rolename, nspname); + else + appendStringInfo(&buffer, + _("default privileges belonging to role %s"), + rolename); break; } - if (OidIsValid(defacl->defaclnamespace)) - { - appendStringInfo(&buffer, - _(" in schema %s"), - get_namespace_name(defacl->defaclnamespace)); - } - systable_endscan(rcscan); - heap_close(defaclrel, AccessShareLock); + table_close(defaclrel, AccessShareLock); break; } @@ -3355,11 +3544,12 @@ getObjectDescription(const ObjectAddress *object) SysScanDesc sscan; HeapTuple tuple; Form_pg_policy form_policy; + StringInfoData rel; - policy_rel = heap_open(PolicyRelationId, AccessShareLock); + policy_rel = table_open(PolicyRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_policy_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -3371,22 +3561,25 @@ getObjectDescription(const ObjectAddress *object) if (!HeapTupleIsValid(tuple)) elog(ERROR, "could not find tuple for policy %u", object->objectId); - form_policy = (Form_pg_policy) GETSTRUCT(tuple); - appendStringInfo(&buffer, _("policy %s on "), - NameStr(form_policy->polname)); - getRelationDescription(&buffer, form_policy->polrelid); + initStringInfo(&rel); + getRelationDescription(&rel, form_policy->polrelid); + /* translator: second %s is, e.g., "table %s" */ + appendStringInfo(&buffer, _("policy %s on %s"), + NameStr(form_policy->polname), rel.data); + pfree(rel.data); systable_endscan(sscan); - heap_close(policy_rel, AccessShareLock); + table_close(policy_rel, AccessShareLock); break; } case OCLASS_PUBLICATION: { appendStringInfo(&buffer, _("publication %s"), - get_publication_name(object->objectId)); + get_publication_name(object->objectId, + false)); break; } @@ -3395,6 +3588,7 @@ getObjectDescription(const ObjectAddress *object) HeapTuple tup; char *pubname; Form_pg_publication_rel prform; + StringInfoData rel; tup = SearchSysCache1(PUBLICATIONREL, ObjectIdGetDatum(object->objectId)); @@ -3403,10 +3597,15 @@ getObjectDescription(const ObjectAddress *object) object->objectId); prform = (Form_pg_publication_rel) GETSTRUCT(tup); - pubname = get_publication_name(prform->prpubid); + pubname = get_publication_name(prform->prpubid, false); + + initStringInfo(&rel); + getRelationDescription(&rel, prform->prrelid); - appendStringInfo(&buffer, _("publication table %s in publication %s"), - get_rel_name(prform->prrelid), pubname); + /* translator: first %s is, e.g., "table %s" */ + appendStringInfo(&buffer, _("publication of %s in publication %s"), + rel.data, pubname); + pfree(rel.data); ReleaseSysCache(tup); break; } @@ -3414,7 +3613,8 @@ getObjectDescription(const ObjectAddress *object) case OCLASS_SUBSCRIPTION: { appendStringInfo(&buffer, _("subscription %s"), - get_subscription_name(object->objectId)); + get_subscription_name(object->objectId, + false)); break; } @@ -3465,6 +3665,8 @@ getObjectDescriptionOids(Oid classid, Oid objid) /* * subroutine for getObjectDescription: describe a relation + * + * The result is appended to "buffer". */ static void getRelationDescription(StringInfo buffer, Oid relid) @@ -3621,7 +3823,7 @@ pg_identify_object(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schema", @@ -3636,9 +3838,11 @@ pg_identify_object(PG_FUNCTION_ARGS) if (is_objectclass_supported(address.classId)) { HeapTuple objtup; - Relation catalog = heap_open(address.classId, AccessShareLock); + Relation catalog = table_open(address.classId, AccessShareLock); - objtup = get_catalog_object_by_oid(catalog, address.objectId); + objtup = get_catalog_object_by_oid(catalog, + get_object_attnum_oid(address.classId), + address.objectId); if (objtup != NULL) { bool isnull; @@ -3676,7 +3880,7 @@ pg_identify_object(PG_FUNCTION_ARGS) } } - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); } /* object type */ @@ -3738,7 +3942,7 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "object_names", @@ -3757,7 +3961,10 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS) pfree(identity); /* object_names */ - values[1] = PointerGetDatum(strlist_to_textarray(names)); + if (names != NIL) + values[1] = PointerGetDatum(strlist_to_textarray(names)); + else + values[1] = PointerGetDatum(construct_empty_array(TEXTOID)); nulls[1] = false; /* object_args */ @@ -4014,8 +4221,9 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid) HeapTuple constrTup; Form_pg_constraint constrForm; - constrRel = heap_open(ConstraintRelationId, AccessShareLock); - constrTup = get_catalog_object_by_oid(constrRel, constroid); + constrRel = table_open(ConstraintRelationId, AccessShareLock); + constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid, + constroid); if (!HeapTupleIsValid(constrTup)) elog(ERROR, "cache lookup failed for constraint %u", constroid); @@ -4026,9 +4234,9 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid) else if (OidIsValid(constrForm->contypid)) appendStringInfoString(buffer, "domain constraint"); else - elog(ERROR, "invalid constraint %u", HeapTupleGetOid(constrTup)); + elog(ERROR, "invalid constraint %u", constrForm->oid); - heap_close(constrRel, AccessShareLock); + table_close(constrRel, AccessShareLock); } /* @@ -4137,9 +4345,10 @@ getObjectIdentityParts(const ObjectAddress *object, HeapTuple tup; Form_pg_cast castForm; - castRel = heap_open(CastRelationId, AccessShareLock); + castRel = table_open(CastRelationId, AccessShareLock); - tup = get_catalog_object_by_oid(castRel, object->objectId); + tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid, + object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for cast %u", @@ -4157,7 +4366,7 @@ getObjectIdentityParts(const ObjectAddress *object, *objargs = list_make1(format_type_be_qualified(castForm->casttarget)); } - heap_close(castRel, AccessShareLock); + table_close(castRel, AccessShareLock); break; } @@ -4258,10 +4467,10 @@ getObjectIdentityParts(const ObjectAddress *object, Form_pg_attrdef attrdef; ObjectAddress colobject; - attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock); + attrdefDesc = table_open(AttrDefaultRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_attrdef_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -4285,7 +4494,7 @@ getObjectIdentityParts(const ObjectAddress *object, objname, objargs)); systable_endscan(adscan); - heap_close(attrdefDesc, AccessShareLock); + table_close(attrdefDesc, AccessShareLock); break; } @@ -4387,11 +4596,11 @@ getObjectIdentityParts(const ObjectAddress *object, char *ltype; char *rtype; - amopDesc = heap_open(AccessMethodOperatorRelationId, - AccessShareLock); + amopDesc = table_open(AccessMethodOperatorRelationId, + AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amop_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -4426,7 +4635,7 @@ getObjectIdentityParts(const ObjectAddress *object, pfree(opfam.data); systable_endscan(amscan); - heap_close(amopDesc, AccessShareLock); + table_close(amopDesc, AccessShareLock); break; } @@ -4441,11 +4650,11 @@ getObjectIdentityParts(const ObjectAddress *object, char *ltype; char *rtype; - amprocDesc = heap_open(AccessMethodProcedureRelationId, - AccessShareLock); + amprocDesc = table_open(AccessMethodProcedureRelationId, + AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amproc_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -4480,7 +4689,7 @@ getObjectIdentityParts(const ObjectAddress *object, pfree(opfam.data); systable_endscan(amscan); - heap_close(amprocDesc, AccessShareLock); + table_close(amprocDesc, AccessShareLock); break; } @@ -4490,9 +4699,10 @@ getObjectIdentityParts(const ObjectAddress *object, HeapTuple tup; Form_pg_rewrite rule; - ruleDesc = heap_open(RewriteRelationId, AccessShareLock); + ruleDesc = table_open(RewriteRelationId, AccessShareLock); - tup = get_catalog_object_by_oid(ruleDesc, object->objectId); + tup = get_catalog_object_by_oid(ruleDesc, Anum_pg_rewrite_oid, + object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for rule %u", @@ -4506,7 +4716,7 @@ getObjectIdentityParts(const ObjectAddress *object, if (objname) *objname = lappend(*objname, pstrdup(NameStr(rule->rulename))); - heap_close(ruleDesc, AccessShareLock); + table_close(ruleDesc, AccessShareLock); break; } @@ -4516,9 +4726,10 @@ getObjectIdentityParts(const ObjectAddress *object, HeapTuple tup; Form_pg_trigger trig; - trigDesc = heap_open(TriggerRelationId, AccessShareLock); + trigDesc = table_open(TriggerRelationId, AccessShareLock); - tup = get_catalog_object_by_oid(trigDesc, object->objectId); + tup = get_catalog_object_by_oid(trigDesc, Anum_pg_trigger_oid, + object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for trigger %u", @@ -4532,7 +4743,7 @@ getObjectIdentityParts(const ObjectAddress *object, if (objname) *objname = lappend(*objname, pstrdup(NameStr(trig->tgname))); - heap_close(trigDesc, AccessShareLock); + table_close(trigDesc, AccessShareLock); break; } @@ -4777,10 +4988,10 @@ getObjectIdentityParts(const ObjectAddress *object, char *schema; char *username; - defaclrel = heap_open(DefaultAclRelationId, AccessShareLock); + defaclrel = table_open(DefaultAclRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_default_acl_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); @@ -4843,7 +5054,7 @@ getObjectIdentityParts(const ObjectAddress *object, } systable_endscan(rcscan); - heap_close(defaclrel, AccessShareLock); + table_close(defaclrel, AccessShareLock); break; } @@ -4888,9 +5099,10 @@ getObjectIdentityParts(const ObjectAddress *object, HeapTuple tup; Form_pg_policy policy; - polDesc = heap_open(PolicyRelationId, AccessShareLock); + polDesc = table_open(PolicyRelationId, AccessShareLock); - tup = get_catalog_object_by_oid(polDesc, object->objectId); + tup = get_catalog_object_by_oid(polDesc, Anum_pg_policy_oid, + object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for policy %u", @@ -4904,7 +5116,7 @@ getObjectIdentityParts(const ObjectAddress *object, if (objname) *objname = lappend(*objname, pstrdup(NameStr(policy->polname))); - heap_close(polDesc, AccessShareLock); + table_close(polDesc, AccessShareLock); break; } @@ -4912,7 +5124,7 @@ getObjectIdentityParts(const ObjectAddress *object, { char *pubname; - pubname = get_publication_name(object->objectId); + pubname = get_publication_name(object->objectId, false); appendStringInfoString(&buffer, quote_identifier(pubname)); if (objname) @@ -4933,16 +5145,13 @@ getObjectIdentityParts(const ObjectAddress *object, object->objectId); prform = (Form_pg_publication_rel) GETSTRUCT(tup); - pubname = get_publication_name(prform->prpubid); + pubname = get_publication_name(prform->prpubid, false); - appendStringInfo(&buffer, _("%s in publication %s"), - get_rel_name(prform->prrelid), pubname); + getRelationIdentity(&buffer, prform->prrelid, objname); + appendStringInfo(&buffer, " in publication %s", pubname); - if (objname) - { - getRelationIdentity(&buffer, prform->prrelid, objname); + if (objargs) *objargs = list_make1(pubname); - } ReleaseSysCache(tup); break; @@ -4952,7 +5161,7 @@ getObjectIdentityParts(const ObjectAddress *object, { char *subname; - subname = get_subscription_name(object->objectId); + subname = get_subscription_name(object->objectId, false); appendStringInfoString(&buffer, quote_identifier(subname)); if (objname) @@ -4968,9 +5177,11 @@ getObjectIdentityParts(const ObjectAddress *object, char *transformLang; char *transformType; - transformDesc = heap_open(TransformRelationId, AccessShareLock); + transformDesc = table_open(TransformRelationId, AccessShareLock); - tup = get_catalog_object_by_oid(transformDesc, object->objectId); + tup = get_catalog_object_by_oid(transformDesc, + Anum_pg_transform_oid, + object->objectId); if (!HeapTupleIsValid(tup)) elog(ERROR, "could not find tuple for transform %u", @@ -4990,7 +5201,7 @@ getObjectIdentityParts(const ObjectAddress *object, *objargs = list_make1(pstrdup(transformLang)); } - heap_close(transformDesc, AccessShareLock); + table_close(transformDesc, AccessShareLock); } break; @@ -5082,10 +5293,12 @@ strlist_to_textarray(List *list) { ArrayType *arr; Datum *datums; + bool *nulls; int j = 0; ListCell *cell; MemoryContext memcxt; MemoryContext oldcxt; + int lb[1]; /* Work in a temp context; easier than individually pfree'ing the Datums */ memcxt = AllocSetContextCreate(CurrentMemoryContext, @@ -5094,18 +5307,26 @@ strlist_to_textarray(List *list) oldcxt = MemoryContextSwitchTo(memcxt); datums = (Datum *) palloc(sizeof(Datum) * list_length(list)); + nulls = palloc(sizeof(bool) * list_length(list)); foreach(cell, list) { char *name = lfirst(cell); - datums[j++] = CStringGetTextDatum(name); + if (name) + { + nulls[j] = false; + datums[j++] = CStringGetTextDatum(name); + } + else + nulls[j] = true; } MemoryContextSwitchTo(oldcxt); - arr = construct_array(datums, list_length(list), - TEXTOID, -1, false, 'i'); + lb[0] = 1; + arr = construct_md_array(datums, nulls, 1, &j, + lb, TEXTOID, -1, false, 'i'); MemoryContextDelete(memcxt); @@ -5121,6 +5342,7 @@ get_relkind_objtype(char relkind) case RELKIND_PARTITIONED_TABLE: return OBJECT_TABLE; case RELKIND_INDEX: + case RELKIND_PARTITIONED_INDEX: return OBJECT_INDEX; case RELKIND_SEQUENCE: return OBJECT_SEQUENCE; @@ -5130,7 +5352,11 @@ get_relkind_objtype(char relkind) return OBJECT_MATVIEW; case RELKIND_FOREIGN_TABLE: return OBJECT_FOREIGN_TABLE; - /* other relkinds are not supported here because they don't map to OBJECT_* values */ + + /* + * other relkinds are not supported here because they don't map to + * OBJECT_* values + */ default: elog(ERROR, "unexpected relkind: %d", relkind); return 0; diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 0f5932feeef..53af14e939e 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -3,7 +3,7 @@ * partition.c * Partitioning related data structures and functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -12,2607 +12,217 @@ * *------------------------------------------------------------------------- */ - #include "postgres.h" -#include "access/hash.h" -#include "access/heapam.h" +#include "access/genam.h" #include "access/htup_details.h" -#include "access/nbtree.h" +#include "access/table.h" +#include "access/tupconvert.h" #include "access/sysattr.h" -#include "catalog/dependency.h" #include "catalog/indexing.h" -#include "catalog/objectaddress.h" #include "catalog/partition.h" -#include "catalog/pg_collation.h" #include "catalog/pg_inherits.h" -#include "catalog/pg_opclass.h" #include "catalog/pg_partitioned_table.h" -#include "catalog/pg_type.h" -#include "commands/tablecmds.h" -#include "executor/executor.h" -#include "miscadmin.h" #include "nodes/makefuncs.h" -#include "nodes/nodeFuncs.h" -#include "nodes/parsenodes.h" -#include "optimizer/clauses.h" -#include "optimizer/planmain.h" -#include "optimizer/prep.h" -#include "optimizer/var.h" -#include "parser/parse_coerce.h" +#include "optimizer/optimizer.h" #include "partitioning/partbounds.h" #include "rewrite/rewriteManip.h" -#include "storage/lmgr.h" -#include "utils/array.h" -#include "utils/builtins.h" -#include "utils/datum.h" #include "utils/fmgroids.h" -#include "utils/hashutils.h" -#include "utils/inval.h" -#include "utils/lsyscache.h" -#include "utils/memutils.h" +#include "utils/partcache.h" #include "utils/rel.h" -#include "utils/ruleutils.h" #include "utils/syscache.h" static Oid get_partition_parent_worker(Relation inhRel, Oid relid); static void get_partition_ancestors_worker(Relation inhRel, Oid relid, - List **ancestors); -static int32 qsort_partition_hbound_cmp(const void *a, const void *b); -static int32 qsort_partition_list_value_cmp(const void *a, const void *b, - void *arg); -static int32 qsort_partition_rbound_cmp(const void *a, const void *b, - void *arg); - -static Oid get_partition_operator(PartitionKey key, int col, - StrategyNumber strategy, bool *need_relabel); -static Expr *make_partition_op_expr(PartitionKey key, int keynum, - uint16 strategy, Expr *arg1, Expr *arg2); -static void get_range_key_properties(PartitionKey key, int keynum, - PartitionRangeDatum *ldatum, - PartitionRangeDatum *udatum, - ListCell **partexprs_item, - Expr **keyCol, - Const **lower_val, Const **upper_val); -static List *get_qual_for_hash(Relation parent, PartitionBoundSpec *spec); -static List *get_qual_for_list(Relation parent, PartitionBoundSpec *spec); -static List *get_qual_for_range(Relation parent, PartitionBoundSpec *spec, - bool for_default); -static List *get_range_nulltest(PartitionKey key); -static List *generate_partition_qual(Relation rel); - -static PartitionRangeBound *make_one_range_bound(PartitionKey key, int index, - List *datums, bool lower); -static int32 partition_hbound_cmp(int modulus1, int remainder1, int modulus2, - int remainder2); -static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, - Oid *partcollation, Datum *datums1, - PartitionRangeDatumKind *kind1, bool lower1, - PartitionRangeBound *b2); - -static int get_partition_bound_num_indexes(PartitionBoundInfo b); - + List **ancestors); /* - * RelationBuildPartitionDesc - * Form rel's partition descriptor + * get_partition_parent + * Obtain direct parent of given relation + * + * Returns inheritance parent of a partition by scanning pg_inherits * - * Not flushed from the cache by RelationClearRelation() unless changed because - * of addition or removal of partition. + * Note: Because this function assumes that the relation whose OID is passed + * as an argument will have precisely one parent, it should only be called + * when it is known that the relation is a partition. */ -void -RelationBuildPartitionDesc(Relation rel) +Oid +get_partition_parent(Oid relid) { - List *inhoids, - *partoids; - Oid *oids = NULL; - List *boundspecs = NIL; - ListCell *cell; - int i, - nparts; - PartitionKey key = RelationGetPartitionKey(rel); - PartitionDesc result; - MemoryContext oldcxt; - - int ndatums = 0; - int default_index = -1; - - /* Hash partitioning specific */ - PartitionHashBound **hbounds = NULL; - - /* List partitioning specific */ - PartitionListValue **all_values = NULL; - int null_index = -1; - - /* Range partitioning specific */ - PartitionRangeBound **rbounds = NULL; - - /* Get partition oids from pg_inherits */ - inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock); - - /* Collect bound spec nodes in a list */ - i = 0; - partoids = NIL; - foreach(cell, inhoids) - { - Oid inhrelid = lfirst_oid(cell); - HeapTuple tuple; - Datum datum; - bool isnull; - Node *boundspec; + Relation catalogRelation; + Oid result; - tuple = SearchSysCache1(RELOID, inhrelid); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", inhrelid); + catalogRelation = table_open(InheritsRelationId, AccessShareLock); - /* - * It is possible that the pg_class tuple of a partition has not been - * updated yet to set its relpartbound field. The only case where - * this happens is when we open the parent relation to check using its - * partition descriptor that a new partition's bound does not overlap - * some existing partition. - */ - if (!((Form_pg_class) GETSTRUCT(tuple))->relispartition) - { - ReleaseSysCache(tuple); - continue; - } + result = get_partition_parent_worker(catalogRelation, relid); - datum = SysCacheGetAttr(RELOID, tuple, - Anum_pg_class_relpartbound, - &isnull); - Assert(!isnull); - boundspec = (Node *) stringToNode(TextDatumGetCString(datum)); + if (!OidIsValid(result)) + elog(ERROR, "could not find tuple for parent of relation %u", relid); - /* - * Sanity check: If the PartitionBoundSpec says this is the default - * partition, its OID should correspond to whatever's stored in - * pg_partitioned_table.partdefid; if not, the catalog is corrupt. - */ - if (castNode(PartitionBoundSpec, boundspec)->is_default) - { - Oid partdefid; + table_close(catalogRelation, AccessShareLock); - partdefid = get_default_partition_oid(RelationGetRelid(rel)); - if (partdefid != inhrelid) - elog(ERROR, "expected partdefid %u, but got %u", - inhrelid, partdefid); - } + return result; +} - boundspecs = lappend(boundspecs, boundspec); - partoids = lappend_oid(partoids, inhrelid); - ReleaseSysCache(tuple); - } +/* + * get_partition_parent_worker + * Scan the pg_inherits relation to return the OID of the parent of the + * given relation + */ +static Oid +get_partition_parent_worker(Relation inhRel, Oid relid) +{ + SysScanDesc scan; + ScanKeyData key[2]; + Oid result = InvalidOid; + HeapTuple tuple; - nparts = list_length(partoids); + ScanKeyInit(&key[0], + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(relid)); + ScanKeyInit(&key[1], + Anum_pg_inherits_inhseqno, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(1)); - if (nparts > 0) + scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true, + NULL, 2, key); + tuple = systable_getnext(scan); + if (HeapTupleIsValid(tuple)) { - oids = (Oid *) palloc(nparts * sizeof(Oid)); - i = 0; - foreach(cell, partoids) - oids[i++] = lfirst_oid(cell); - - /* Convert from node to the internal representation */ - if (key->strategy == PARTITION_STRATEGY_HASH) - { - ndatums = nparts; - hbounds = (PartitionHashBound **) - palloc(nparts * sizeof(PartitionHashBound *)); - - i = 0; - foreach(cell, boundspecs) - { - PartitionBoundSpec *spec = castNode(PartitionBoundSpec, - lfirst(cell)); - - if (spec->strategy != PARTITION_STRATEGY_HASH) - elog(ERROR, "invalid strategy in partition bound spec"); - - hbounds[i] = (PartitionHashBound *) - palloc(sizeof(PartitionHashBound)); - - hbounds[i]->modulus = spec->modulus; - hbounds[i]->remainder = spec->remainder; - hbounds[i]->index = i; - i++; - } - - /* Sort all the bounds in ascending order */ - qsort(hbounds, nparts, sizeof(PartitionHashBound *), - qsort_partition_hbound_cmp); - } - else if (key->strategy == PARTITION_STRATEGY_LIST) - { - List *non_null_values = NIL; - - /* - * Create a unified list of non-null values across all partitions. - */ - i = 0; - null_index = -1; - foreach(cell, boundspecs) - { - PartitionBoundSpec *spec = castNode(PartitionBoundSpec, - lfirst(cell)); - ListCell *c; - - if (spec->strategy != PARTITION_STRATEGY_LIST) - elog(ERROR, "invalid strategy in partition bound spec"); - - /* - * Note the index of the partition bound spec for the default - * partition. There's no datum to add to the list of non-null - * datums for this partition. - */ - if (spec->is_default) - { - default_index = i; - i++; - continue; - } - - foreach(c, spec->listdatums) - { - Const *val = castNode(Const, lfirst(c)); - PartitionListValue *list_value = NULL; - - if (!val->constisnull) - { - list_value = (PartitionListValue *) - palloc0(sizeof(PartitionListValue)); - list_value->index = i; - list_value->value = val->constvalue; - } - else - { - /* - * Never put a null into the values array, flag - * instead for the code further down below where we - * construct the actual relcache struct. - */ - if (null_index != -1) - elog(ERROR, "found null more than once"); - null_index = i; - } - - if (list_value) - non_null_values = lappend(non_null_values, - list_value); - } - - i++; - } - - ndatums = list_length(non_null_values); - - /* - * Collect all list values in one array. Alongside the value, we - * also save the index of partition the value comes from. - */ - all_values = (PartitionListValue **) palloc(ndatums * - sizeof(PartitionListValue *)); - i = 0; - foreach(cell, non_null_values) - { - PartitionListValue *src = lfirst(cell); - - all_values[i] = (PartitionListValue *) - palloc(sizeof(PartitionListValue)); - all_values[i]->value = src->value; - all_values[i]->index = src->index; - i++; - } - - qsort_arg(all_values, ndatums, sizeof(PartitionListValue *), - qsort_partition_list_value_cmp, (void *) key); - } - else if (key->strategy == PARTITION_STRATEGY_RANGE) - { - int k; - PartitionRangeBound **all_bounds, - *prev; - - all_bounds = (PartitionRangeBound **) palloc0(2 * nparts * - sizeof(PartitionRangeBound *)); - - /* - * Create a unified list of range bounds across all the - * partitions. - */ - i = ndatums = 0; - foreach(cell, boundspecs) - { - PartitionBoundSpec *spec = castNode(PartitionBoundSpec, - lfirst(cell)); - PartitionRangeBound *lower, - *upper; - - if (spec->strategy != PARTITION_STRATEGY_RANGE) - elog(ERROR, "invalid strategy in partition bound spec"); - - /* - * Note the index of the partition bound spec for the default - * partition. There's no datum to add to the allbounds array - * for this partition. - */ - if (spec->is_default) - { - default_index = i++; - continue; - } - - lower = make_one_range_bound(key, i, spec->lowerdatums, - true); - upper = make_one_range_bound(key, i, spec->upperdatums, - false); - all_bounds[ndatums++] = lower; - all_bounds[ndatums++] = upper; - i++; - } - - Assert(ndatums == nparts * 2 || - (default_index != -1 && ndatums == (nparts - 1) * 2)); - - /* Sort all the bounds in ascending order */ - qsort_arg(all_bounds, ndatums, - sizeof(PartitionRangeBound *), - qsort_partition_rbound_cmp, - (void *) key); - - /* Save distinct bounds from all_bounds into rbounds. */ - rbounds = (PartitionRangeBound **) - palloc(ndatums * sizeof(PartitionRangeBound *)); - k = 0; - prev = NULL; - for (i = 0; i < ndatums; i++) - { - PartitionRangeBound *cur = all_bounds[i]; - bool is_distinct = false; - int j; - - /* Is the current bound distinct from the previous one? */ - for (j = 0; j < key->partnatts; j++) - { - Datum cmpval; - - if (prev == NULL || cur->kind[j] != prev->kind[j]) - { - is_distinct = true; - break; - } - - /* - * If the bounds are both MINVALUE or MAXVALUE, stop now - * and treat them as equal, since any values after this - * point must be ignored. - */ - if (cur->kind[j] != PARTITION_RANGE_DATUM_VALUE) - break; - - cmpval = FunctionCall2Coll(&key->partsupfunc[j], - key->partcollation[j], - cur->datums[j], - prev->datums[j]); - if (DatumGetInt32(cmpval) != 0) - { - is_distinct = true; - break; - } - } - - /* - * Only if the bound is distinct save it into a temporary - * array i.e. rbounds which is later copied into boundinfo - * datums array. - */ - if (is_distinct) - rbounds[k++] = all_bounds[i]; - - prev = cur; - } + Form_pg_inherits form = (Form_pg_inherits) GETSTRUCT(tuple); - /* Update ndatums to hold the count of distinct datums. */ - ndatums = k; - } - else - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); + result = form->inhparent; } - /* Now build the actual relcache partition descriptor */ - rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext, - "partition descriptor", - ALLOCSET_DEFAULT_SIZES); - MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt, RelationGetRelationName(rel)); - - oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt); - - result = (PartitionDescData *) palloc0(sizeof(PartitionDescData)); - result->nparts = nparts; - if (nparts > 0) - { - PartitionBoundInfo boundinfo; - int *mapping; - int next_index = 0; - - result->oids = (Oid *) palloc0(nparts * sizeof(Oid)); - - boundinfo = (PartitionBoundInfoData *) - palloc0(sizeof(PartitionBoundInfoData)); - boundinfo->strategy = key->strategy; - boundinfo->default_index = -1; - boundinfo->ndatums = ndatums; - boundinfo->null_index = -1; - boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); - - /* Initialize mapping array with invalid values */ - mapping = (int *) palloc(sizeof(int) * nparts); - for (i = 0; i < nparts; i++) - mapping[i] = -1; - - switch (key->strategy) - { - case PARTITION_STRATEGY_HASH: - { - /* Modulus are stored in ascending order */ - int greatest_modulus = hbounds[ndatums - 1]->modulus; - - boundinfo->indexes = (int *) palloc(greatest_modulus * - sizeof(int)); - - for (i = 0; i < greatest_modulus; i++) - boundinfo->indexes[i] = -1; - - for (i = 0; i < nparts; i++) - { - int modulus = hbounds[i]->modulus; - int remainder = hbounds[i]->remainder; - - boundinfo->datums[i] = (Datum *) palloc(2 * - sizeof(Datum)); - boundinfo->datums[i][0] = Int32GetDatum(modulus); - boundinfo->datums[i][1] = Int32GetDatum(remainder); - - while (remainder < greatest_modulus) - { - /* overlap? */ - Assert(boundinfo->indexes[remainder] == -1); - boundinfo->indexes[remainder] = i; - remainder += modulus; - } - - mapping[hbounds[i]->index] = i; - pfree(hbounds[i]); - } - pfree(hbounds); - break; - } - - case PARTITION_STRATEGY_LIST: - { - boundinfo->indexes = (int *) palloc(ndatums * sizeof(int)); - - /* - * Copy values. Indexes of individual values are mapped - * to canonical values so that they match for any two list - * partitioned tables with same number of partitions and - * same lists per partition. One way to canonicalize is - * to assign the index in all_values[] of the smallest - * value of each partition, as the index of all of the - * partition's values. - */ - for (i = 0; i < ndatums; i++) - { - boundinfo->datums[i] = (Datum *) palloc(sizeof(Datum)); - boundinfo->datums[i][0] = datumCopy(all_values[i]->value, - key->parttypbyval[0], - key->parttyplen[0]); - - /* If the old index has no mapping, assign one */ - if (mapping[all_values[i]->index] == -1) - mapping[all_values[i]->index] = next_index++; - - boundinfo->indexes[i] = mapping[all_values[i]->index]; - } - - /* - * If null-accepting partition has no mapped index yet, - * assign one. This could happen if such partition - * accepts only null and hence not covered in the above - * loop which only handled non-null values. - */ - if (null_index != -1) - { - Assert(null_index >= 0); - if (mapping[null_index] == -1) - mapping[null_index] = next_index++; - boundinfo->null_index = mapping[null_index]; - } - - /* Assign mapped index for the default partition. */ - if (default_index != -1) - { - /* - * The default partition accepts any value not - * specified in the lists of other partitions, hence - * it should not get mapped index while assigning - * those for non-null datums. - */ - Assert(default_index >= 0 && - mapping[default_index] == -1); - mapping[default_index] = next_index++; - boundinfo->default_index = mapping[default_index]; - } - - /* All partition must now have a valid mapping */ - Assert(next_index == nparts); - break; - } - - case PARTITION_STRATEGY_RANGE: - { - boundinfo->kind = (PartitionRangeDatumKind **) - palloc(ndatums * - sizeof(PartitionRangeDatumKind *)); - boundinfo->indexes = (int *) palloc((ndatums + 1) * - sizeof(int)); - - for (i = 0; i < ndatums; i++) - { - int j; - - boundinfo->datums[i] = (Datum *) palloc(key->partnatts * - sizeof(Datum)); - boundinfo->kind[i] = (PartitionRangeDatumKind *) - palloc(key->partnatts * - sizeof(PartitionRangeDatumKind)); - for (j = 0; j < key->partnatts; j++) - { - if (rbounds[i]->kind[j] == PARTITION_RANGE_DATUM_VALUE) - boundinfo->datums[i][j] = - datumCopy(rbounds[i]->datums[j], - key->parttypbyval[j], - key->parttyplen[j]); - boundinfo->kind[i][j] = rbounds[i]->kind[j]; - } - - /* - * There is no mapping for invalid indexes. - * - * Any lower bounds in the rbounds array have invalid - * indexes assigned, because the values between the - * previous bound (if there is one) and this (lower) - * bound are not part of the range of any existing - * partition. - */ - if (rbounds[i]->lower) - boundinfo->indexes[i] = -1; - else - { - int orig_index = rbounds[i]->index; - - /* If the old index has no mapping, assign one */ - if (mapping[orig_index] == -1) - mapping[orig_index] = next_index++; - - boundinfo->indexes[i] = mapping[orig_index]; - } - } - - /* Assign mapped index for the default partition. */ - if (default_index != -1) - { - Assert(default_index >= 0 && mapping[default_index] == -1); - mapping[default_index] = next_index++; - boundinfo->default_index = mapping[default_index]; - } - boundinfo->indexes[i] = -1; - break; - } - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); - } - - result->boundinfo = boundinfo; - - /* - * Now assign OIDs from the original array into mapped indexes of the - * result array. Order of OIDs in the former is defined by the - * catalog scan that retrieved them, whereas that in the latter is - * defined by canonicalized representation of the partition bounds. - */ - for (i = 0; i < nparts; i++) - result->oids[mapping[i]] = oids[i]; - pfree(mapping); - } + systable_endscan(scan); - MemoryContextSwitchTo(oldcxt); - rel->rd_partdesc = result; + return result; } /* - * Are two partition bound collections logically equal? + * get_partition_ancestors + * Obtain ancestors of given relation + * + * Returns a list of ancestors of the given relation. * - * Used in the keep logic of relcache.c (ie, in RelationClearRelation()). - * This is also useful when b1 and b2 are bound collections of two separate - * relations, respectively, because PartitionBoundInfo is a canonical - * representation of partition bounds. + * Note: Because this function assumes that the relation whose OID is passed + * as an argument and each ancestor will have precisely one parent, it should + * only be called when it is known that the relation is a partition. */ -bool -partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, - PartitionBoundInfo b1, PartitionBoundInfo b2) +List * +get_partition_ancestors(Oid relid) { - int i; - - if (b1->strategy != b2->strategy) - return false; - - if (b1->ndatums != b2->ndatums) - return false; - - if (b1->null_index != b2->null_index) - return false; - - if (b1->default_index != b2->default_index) - return false; - - if (b1->strategy == PARTITION_STRATEGY_HASH) - { - int greatest_modulus = get_hash_partition_greatest_modulus(b1); - - /* - * If two hash partitioned tables have different greatest moduli, - * their partition schemes don't match. - */ - if (greatest_modulus != get_hash_partition_greatest_modulus(b2)) - return false; - - /* - * We arrange the partitions in the ascending order of their modulus - * and remainders. Also every modulus is factor of next larger - * modulus. Therefore we can safely store index of a given partition - * in indexes array at remainder of that partition. Also entries at - * (remainder + N * modulus) positions in indexes array are all same - * for (modulus, remainder) specification for any partition. Thus - * datums array from both the given bounds are same, if and only if - * their indexes array will be same. So, it suffices to compare - * indexes array. - */ - for (i = 0; i < greatest_modulus; i++) - if (b1->indexes[i] != b2->indexes[i]) - return false; - -#ifdef USE_ASSERT_CHECKING - - /* - * Nonetheless make sure that the bounds are indeed same when the - * indexes match. Hash partition bound stores modulus and remainder - * at b1->datums[i][0] and b1->datums[i][1] position respectively. - */ - for (i = 0; i < b1->ndatums; i++) - Assert((b1->datums[i][0] == b2->datums[i][0] && - b1->datums[i][1] == b2->datums[i][1])); -#endif - } - else - { - for (i = 0; i < b1->ndatums; i++) - { - int j; - - for (j = 0; j < partnatts; j++) - { - /* For range partitions, the bounds might not be finite. */ - if (b1->kind != NULL) - { - /* The different kinds of bound all differ from each other */ - if (b1->kind[i][j] != b2->kind[i][j]) - return false; + List *result = NIL; + Relation inhRel; - /* - * Non-finite bounds are equal without further - * examination. - */ - if (b1->kind[i][j] != PARTITION_RANGE_DATUM_VALUE) - continue; - } + inhRel = table_open(InheritsRelationId, AccessShareLock); - /* - * Compare the actual values. Note that it would be both - * incorrect and unsafe to invoke the comparison operator - * derived from the partitioning specification here. It would - * be incorrect because we want the relcache entry to be - * updated for ANY change to the partition bounds, not just - * those that the partitioning operator thinks are - * significant. It would be unsafe because we might reach - * this code in the context of an aborted transaction, and an - * arbitrary partitioning operator might not be safe in that - * context. datumIsEqual() should be simple enough to be - * safe. - */ - if (!datumIsEqual(b1->datums[i][j], b2->datums[i][j], - parttypbyval[j], parttyplen[j])) - return false; - } + get_partition_ancestors_worker(inhRel, relid, &result); - if (b1->indexes[i] != b2->indexes[i]) - return false; - } + table_close(inhRel, AccessShareLock); - /* There are ndatums+1 indexes in case of range partitions */ - if (b1->strategy == PARTITION_STRATEGY_RANGE && - b1->indexes[i] != b2->indexes[i]) - return false; - } - return true; + return result; } /* - * Return a copy of given PartitionBoundInfo structure. The data types of bounds - * are described by given partition key specification. + * get_partition_ancestors_worker + * recursive worker for get_partition_ancestors */ -PartitionBoundInfo -partition_bounds_copy(PartitionBoundInfo src, - PartitionKey key) +static void +get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors) { - PartitionBoundInfo dest; - int i; - int ndatums; - int partnatts; - int num_indexes; - - dest = (PartitionBoundInfo) palloc(sizeof(PartitionBoundInfoData)); - - dest->strategy = src->strategy; - ndatums = dest->ndatums = src->ndatums; - partnatts = key->partnatts; - - num_indexes = get_partition_bound_num_indexes(src); - - /* List partitioned tables have only a single partition key. */ - Assert(key->strategy != PARTITION_STRATEGY_LIST || partnatts == 1); + Oid parentOid; - dest->datums = (Datum **) palloc(sizeof(Datum *) * ndatums); + /* Recursion ends at the topmost level, ie., when there's no parent */ + parentOid = get_partition_parent_worker(inhRel, relid); + if (parentOid == InvalidOid) + return; - if (src->kind != NULL) - { - dest->kind = (PartitionRangeDatumKind **) palloc(ndatums * - sizeof(PartitionRangeDatumKind *)); - for (i = 0; i < ndatums; i++) - { - dest->kind[i] = (PartitionRangeDatumKind *) palloc(partnatts * - sizeof(PartitionRangeDatumKind)); + *ancestors = lappend_oid(*ancestors, parentOid); + get_partition_ancestors_worker(inhRel, parentOid, ancestors); +} - memcpy(dest->kind[i], src->kind[i], - sizeof(PartitionRangeDatumKind) * key->partnatts); - } - } - else - dest->kind = NULL; +/* + * index_get_partition + * Return the OID of index of the given partition that is a child + * of the given index, or InvalidOid if there isn't one. + */ +Oid +index_get_partition(Relation partition, Oid indexId) +{ + List *idxlist = RelationGetIndexList(partition); + ListCell *l; - for (i = 0; i < ndatums; i++) + foreach(l, idxlist) { - int j; + Oid partIdx = lfirst_oid(l); + HeapTuple tup; + Form_pg_class classForm; + bool ispartition; - /* - * For a corresponding to hash partition, datums array will have two - * elements - modulus and remainder. - */ - bool hash_part = (key->strategy == PARTITION_STRATEGY_HASH); - int natts = hash_part ? 2 : partnatts; - - dest->datums[i] = (Datum *) palloc(sizeof(Datum) * natts); - - for (j = 0; j < natts; j++) + tup = SearchSysCache1(RELOID, ObjectIdGetDatum(partIdx)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for relation %u", partIdx); + classForm = (Form_pg_class) GETSTRUCT(tup); + ispartition = classForm->relispartition; + ReleaseSysCache(tup); + if (!ispartition) + continue; + if (get_partition_parent(lfirst_oid(l)) == indexId) { - bool byval; - int typlen; - - if (hash_part) - { - typlen = sizeof(int32); /* Always int4 */ - byval = true; /* int4 is pass-by-value */ - } - else - { - byval = key->parttypbyval[j]; - typlen = key->parttyplen[j]; - } - - if (dest->kind == NULL || - dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE) - dest->datums[i][j] = datumCopy(src->datums[i][j], - byval, typlen); + list_free(idxlist); + return partIdx; } } - dest->indexes = (int *) palloc(sizeof(int) * num_indexes); - memcpy(dest->indexes, src->indexes, sizeof(int) * num_indexes); - - dest->null_index = src->null_index; - dest->default_index = src->default_index; - - return dest; + return InvalidOid; } /* - * check_new_partition_bound + * map_partition_varattnos - maps varattno of any Vars in expr from the + * attno's of 'from_rel' to the attno's of 'to_rel' partition, each of which + * may be either a leaf partition or a partitioned table, but both of which + * must be from the same partitioning hierarchy. * - * Checks if the new partition's bound overlaps any of the existing partitions - * of parent. Also performs additional checks as necessary per strategy. + * Even though all of the same column names must be present in all relations + * in the hierarchy, and they must also have the same types, the attnos may + * be different. + * + * If found_whole_row is not NULL, *found_whole_row returns whether a + * whole-row variable was found in the input expression. + * + * Note: this will work on any node tree, so really the argument and result + * should be declared "Node *". But a substantial majority of the callers + * are working on Lists, so it's less messy to do the casts internally. */ -void -check_new_partition_bound(char *relname, Relation parent, - PartitionBoundSpec *spec) +List * +map_partition_varattnos(List *expr, int fromrel_varno, + Relation to_rel, Relation from_rel, + bool *found_whole_row) { - PartitionKey key = RelationGetPartitionKey(parent); - PartitionDesc partdesc = RelationGetPartitionDesc(parent); - PartitionBoundInfo boundinfo = partdesc->boundinfo; - ParseState *pstate = make_parsestate(NULL); - int with = -1; - bool overlap = false; - - if (spec->is_default) - { - if (boundinfo == NULL || !partition_bound_has_default(boundinfo)) - return; - - /* Default partition already exists, error out. */ - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("partition \"%s\" conflicts with existing default partition \"%s\"", - relname, get_rel_name(partdesc->oids[boundinfo->default_index])), - parser_errposition(pstate, spec->location))); - } - - switch (key->strategy) - { - case PARTITION_STRATEGY_HASH: - { - Assert(spec->strategy == PARTITION_STRATEGY_HASH); - Assert(spec->remainder >= 0 && spec->remainder < spec->modulus); - - if (partdesc->nparts > 0) - { - PartitionBoundInfo boundinfo = partdesc->boundinfo; - Datum **datums = boundinfo->datums; - int ndatums = boundinfo->ndatums; - int greatest_modulus; - int remainder; - int offset; - bool valid_modulus = true; - int prev_modulus, /* Previous largest modulus */ - next_modulus; /* Next largest modulus */ - - /* - * Check rule that every modulus must be a factor of the - * next larger modulus. For example, if you have a bunch - * of partitions that all have modulus 5, you can add a - * new partition with modulus 10 or a new partition with - * modulus 15, but you cannot add both a partition with - * modulus 10 and a partition with modulus 15, because 10 - * is not a factor of 15. - * - * Get the greatest (modulus, remainder) pair contained in - * boundinfo->datums that is less than or equal to the - * (spec->modulus, spec->remainder) pair. - */ - offset = partition_hash_bsearch(boundinfo, - spec->modulus, - spec->remainder); - if (offset < 0) - { - next_modulus = DatumGetInt32(datums[0][0]); - valid_modulus = (next_modulus % spec->modulus) == 0; - } - else - { - prev_modulus = DatumGetInt32(datums[offset][0]); - valid_modulus = (spec->modulus % prev_modulus) == 0; - - if (valid_modulus && (offset + 1) < ndatums) - { - next_modulus = DatumGetInt32(datums[offset + 1][0]); - valid_modulus = (next_modulus % spec->modulus) == 0; - } - } - - if (!valid_modulus) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("every hash partition modulus must be a factor of the next larger modulus"))); - - greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); - remainder = spec->remainder; - - /* - * Normally, the lowest remainder that could conflict with - * the new partition is equal to the remainder specified - * for the new partition, but when the new partition has a - * modulus higher than any used so far, we need to adjust. - */ - if (remainder >= greatest_modulus) - remainder = remainder % greatest_modulus; - - /* Check every potentially-conflicting remainder. */ - do - { - if (boundinfo->indexes[remainder] != -1) - { - overlap = true; - with = boundinfo->indexes[remainder]; - break; - } - remainder += spec->modulus; - } while (remainder < greatest_modulus); - } - - break; - } - - case PARTITION_STRATEGY_LIST: - { - Assert(spec->strategy == PARTITION_STRATEGY_LIST); - - if (partdesc->nparts > 0) - { - ListCell *cell; - - Assert(boundinfo && - boundinfo->strategy == PARTITION_STRATEGY_LIST && - (boundinfo->ndatums > 0 || - partition_bound_accepts_nulls(boundinfo) || - partition_bound_has_default(boundinfo))); - - foreach(cell, spec->listdatums) - { - Const *val = castNode(Const, lfirst(cell)); - - if (!val->constisnull) - { - int offset; - bool equal; - - offset = partition_list_bsearch(key->partsupfunc, - key->partcollation, - boundinfo, - val->constvalue, - &equal); - if (offset >= 0 && equal) - { - overlap = true; - with = boundinfo->indexes[offset]; - break; - } - } - else if (partition_bound_accepts_nulls(boundinfo)) - { - overlap = true; - with = boundinfo->null_index; - break; - } - } - } - - break; - } - - case PARTITION_STRATEGY_RANGE: - { - PartitionRangeBound *lower, - *upper; - - Assert(spec->strategy == PARTITION_STRATEGY_RANGE); - lower = make_one_range_bound(key, -1, spec->lowerdatums, true); - upper = make_one_range_bound(key, -1, spec->upperdatums, false); - - /* - * First check if the resulting range would be empty with - * specified lower and upper bounds - */ - if (partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, lower->datums, - lower->kind, true, upper) >= 0) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("empty range bound specified for partition \"%s\"", - relname), - errdetail("Specified lower bound %s is greater than or equal to upper bound %s.", - get_range_partbound_string(spec->lowerdatums), - get_range_partbound_string(spec->upperdatums)), - parser_errposition(pstate, spec->location))); - } - - if (partdesc->nparts > 0) - { - PartitionBoundInfo boundinfo = partdesc->boundinfo; - int offset; - bool equal; - - Assert(boundinfo && - boundinfo->strategy == PARTITION_STRATEGY_RANGE && - (boundinfo->ndatums > 0 || - partition_bound_has_default(boundinfo))); - - /* - * Test whether the new lower bound (which is treated - * inclusively as part of the new partition) lies inside - * an existing partition, or in a gap. - * - * If it's inside an existing partition, the bound at - * offset + 1 will be the upper bound of that partition, - * and its index will be >= 0. - * - * If it's in a gap, the bound at offset + 1 will be the - * lower bound of the next partition, and its index will - * be -1. This is also true if there is no next partition, - * since the index array is initialised with an extra -1 - * at the end. - */ - offset = partition_range_bsearch(key->partnatts, - key->partsupfunc, - key->partcollation, - boundinfo, lower, - &equal); - - if (boundinfo->indexes[offset + 1] < 0) - { - /* - * Check that the new partition will fit in the gap. - * For it to fit, the new upper bound must be less - * than or equal to the lower bound of the next - * partition, if there is one. - */ - if (offset + 1 < boundinfo->ndatums) - { - int32 cmpval; - Datum *datums; - PartitionRangeDatumKind *kind; - bool is_lower; - - datums = boundinfo->datums[offset + 1]; - kind = boundinfo->kind[offset + 1]; - is_lower = (boundinfo->indexes[offset + 1] == -1); - - cmpval = partition_rbound_cmp(key->partnatts, - key->partsupfunc, - key->partcollation, - datums, kind, - is_lower, upper); - if (cmpval < 0) - { - /* - * The new partition overlaps with the - * existing partition between offset + 1 and - * offset + 2. - */ - overlap = true; - with = boundinfo->indexes[offset + 2]; - } - } - } - else - { - /* - * The new partition overlaps with the existing - * partition between offset and offset + 1. - */ - overlap = true; - with = boundinfo->indexes[offset + 1]; - } - } - - break; - } - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); - } - - if (overlap) - { - Assert(with >= 0); - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("partition \"%s\" would overlap partition \"%s\"", - relname, get_rel_name(partdesc->oids[with])), - parser_errposition(pstate, spec->location))); - } -} - -/* - * check_default_allows_bound - * - * This function checks if there exists a row in the default partition that - * would properly belong to the new partition being added. If it finds one, - * it throws an error. - */ -void -check_default_allows_bound(Relation parent, Relation default_rel, - PartitionBoundSpec *new_spec) -{ - List *new_part_constraints; - List *def_part_constraints; - List *all_parts; - ListCell *lc; - - new_part_constraints = (new_spec->strategy == PARTITION_STRATEGY_LIST) - ? get_qual_for_list(parent, new_spec) - : get_qual_for_range(parent, new_spec, false); - def_part_constraints = - get_proposed_default_constraint(new_part_constraints); - - /* - * If the existing constraints on the default partition imply that it will - * not contain any row that would belong to the new partition, we can - * avoid scanning the default partition. - */ - if (PartConstraintImpliedByRelConstraint(default_rel, def_part_constraints)) - { - ereport(INFO, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(default_rel)))); - return; - } - - /* - * Scan the default partition and its subpartitions, and check for rows - * that do not satisfy the revised partition constraints. - */ - if (default_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - all_parts = find_all_inheritors(RelationGetRelid(default_rel), - AccessExclusiveLock, NULL); - else - all_parts = list_make1_oid(RelationGetRelid(default_rel)); - - foreach(lc, all_parts) - { - Oid part_relid = lfirst_oid(lc); - Relation part_rel; - Expr *constr; - Expr *partition_constraint; - EState *estate; - HeapTuple tuple; - ExprState *partqualstate = NULL; - Snapshot snapshot; - TupleDesc tupdesc; - ExprContext *econtext; - HeapScanDesc scan; - MemoryContext oldCxt; - TupleTableSlot *tupslot; - - /* Lock already taken above. */ - if (part_relid != RelationGetRelid(default_rel)) - { - part_rel = heap_open(part_relid, NoLock); - - /* - * If the partition constraints on default partition child imply - * that it will not contain any row that would belong to the new - * partition, we can avoid scanning the child table. - */ - if (PartConstraintImpliedByRelConstraint(part_rel, - def_part_constraints)) - { - ereport(INFO, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(part_rel)))); - - heap_close(part_rel, NoLock); - continue; - } - } - else - part_rel = default_rel; - - /* - * Only RELKIND_RELATION relations (i.e. leaf partitions) need to be - * scanned. - */ - if (part_rel->rd_rel->relkind != RELKIND_RELATION) - { - if (part_rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) - ereport(WARNING, - (errcode(ERRCODE_CHECK_VIOLATION), - errmsg("skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"", - RelationGetRelationName(part_rel), - RelationGetRelationName(default_rel)))); - - if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel)) - heap_close(part_rel, NoLock); - - continue; - } - - tupdesc = CreateTupleDescCopy(RelationGetDescr(part_rel)); - constr = linitial(def_part_constraints); - partition_constraint = (Expr *) - map_partition_varattnos((List *) constr, - 1, part_rel, parent, NULL); - estate = CreateExecutorState(); - - /* Build expression execution states for partition check quals */ - partqualstate = ExecPrepareExpr(partition_constraint, estate); - - econtext = GetPerTupleExprContext(estate); - snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(part_rel, snapshot, 0, NULL); - tupslot = MakeSingleTupleTableSlot(tupdesc); - - /* - * Switch to per-tuple memory context and reset it for each tuple - * produced, so we don't leak memory. - */ - oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - ExecStoreTuple(tuple, tupslot, InvalidBuffer, false); - econtext->ecxt_scantuple = tupslot; - - if (!ExecCheck(partqualstate, econtext)) - ereport(ERROR, - (errcode(ERRCODE_CHECK_VIOLATION), - errmsg("updated partition constraint for default partition \"%s\" would be violated by some row", - RelationGetRelationName(default_rel)))); - - ResetExprContext(econtext); - CHECK_FOR_INTERRUPTS(); - } - - MemoryContextSwitchTo(oldCxt); - heap_endscan(scan); - UnregisterSnapshot(snapshot); - ExecDropSingleTupleTableSlot(tupslot); - FreeExecutorState(estate); - - if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel)) - heap_close(part_rel, NoLock); /* keep the lock until commit */ - } -} - -/* - * get_partition_parent - * Obtain direct parent of given relation - * - * Returns inheritance parent of a partition by scanning pg_inherits - * - * Note: Because this function assumes that the relation whose OID is passed - * as an argument will have precisely one parent, it should only be called - * when it is known that the relation is a partition. - */ -Oid -get_partition_parent(Oid relid) -{ - Relation catalogRelation; - Oid result; - - catalogRelation = heap_open(InheritsRelationId, AccessShareLock); - - result = get_partition_parent_worker(catalogRelation, relid); - - if (!OidIsValid(result)) - elog(ERROR, "could not find tuple for parent of relation %u", relid); - - heap_close(catalogRelation, AccessShareLock); - - return result; -} - -/* - * get_partition_parent_worker - * Scan the pg_inherits relation to return the OID of the parent of the - * given relation - */ -static Oid -get_partition_parent_worker(Relation inhRel, Oid relid) -{ - SysScanDesc scan; - ScanKeyData key[2]; - Oid result = InvalidOid; - HeapTuple tuple; - - ScanKeyInit(&key[0], - Anum_pg_inherits_inhrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(relid)); - ScanKeyInit(&key[1], - Anum_pg_inherits_inhseqno, - BTEqualStrategyNumber, F_INT4EQ, - Int32GetDatum(1)); - - scan = systable_beginscan(inhRel, InheritsRelidSeqnoIndexId, true, - NULL, 2, key); - tuple = systable_getnext(scan); - if (HeapTupleIsValid(tuple)) - { - Form_pg_inherits form = (Form_pg_inherits) GETSTRUCT(tuple); - - result = form->inhparent; - } - - systable_endscan(scan); - - return result; -} - -/* - * get_partition_ancestors - * Obtain ancestors of given relation - * - * Returns a list of ancestors of the given relation. - * - * Note: Because this function assumes that the relation whose OID is passed - * as an argument and each ancestor will have precisely one parent, it should - * only be called when it is known that the relation is a partition. - */ -List * -get_partition_ancestors(Oid relid) -{ - List *result = NIL; - Relation inhRel; - - inhRel = heap_open(InheritsRelationId, AccessShareLock); - - get_partition_ancestors_worker(inhRel, relid, &result); - - heap_close(inhRel, AccessShareLock); - - return result; -} - -/* - * get_partition_ancestors_worker - * recursive worker for get_partition_ancestors - */ -static void -get_partition_ancestors_worker(Relation inhRel, Oid relid, List **ancestors) -{ - Oid parentOid; - - /* Recursion ends at the topmost level, ie., when there's no parent */ - parentOid = get_partition_parent_worker(inhRel, relid); - if (parentOid == InvalidOid) - return; - - *ancestors = lappend_oid(*ancestors, parentOid); - get_partition_ancestors_worker(inhRel, parentOid, ancestors); -} - -/* - * get_qual_from_partbound - * Given a parser node for partition bound, return the list of executable - * expressions as partition constraint - */ -List * -get_qual_from_partbound(Relation rel, Relation parent, - PartitionBoundSpec *spec) -{ - PartitionKey key = RelationGetPartitionKey(parent); - List *my_qual = NIL; - - Assert(key != NULL); - - switch (key->strategy) - { - case PARTITION_STRATEGY_HASH: - Assert(spec->strategy == PARTITION_STRATEGY_HASH); - my_qual = get_qual_for_hash(parent, spec); - break; - - case PARTITION_STRATEGY_LIST: - Assert(spec->strategy == PARTITION_STRATEGY_LIST); - my_qual = get_qual_for_list(parent, spec); - break; - - case PARTITION_STRATEGY_RANGE: - Assert(spec->strategy == PARTITION_STRATEGY_RANGE); - my_qual = get_qual_for_range(parent, spec, false); - break; - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); - } - - return my_qual; -} - -/* - * map_partition_varattnos - maps varattno of any Vars in expr from the - * attno's of 'from_rel' to the attno's of 'to_rel' partition, each of which - * may be either a leaf partition or a partitioned table, but both of which - * must be from the same partitioning hierarchy. - * - * Even though all of the same column names must be present in all relations - * in the hierarchy, and they must also have the same types, the attnos may - * be different. - * - * If found_whole_row is not NULL, *found_whole_row returns whether a - * whole-row variable was found in the input expression. - * - * Note: this will work on any node tree, so really the argument and result - * should be declared "Node *". But a substantial majority of the callers - * are working on Lists, so it's less messy to do the casts internally. - */ -List * -map_partition_varattnos(List *expr, int fromrel_varno, - Relation to_rel, Relation from_rel, - bool *found_whole_row) -{ - bool my_found_whole_row = false; + bool my_found_whole_row = false; if (expr != NIL) - { - AttrNumber *part_attnos; - - part_attnos = convert_tuples_by_name_map(RelationGetDescr(to_rel), - RelationGetDescr(from_rel), - gettext_noop("could not convert row type")); - expr = (List *) map_variable_attnos((Node *) expr, - fromrel_varno, 0, - part_attnos, - RelationGetDescr(from_rel)->natts, - RelationGetForm(to_rel)->reltype, - &my_found_whole_row); - } - - if (found_whole_row) - *found_whole_row = my_found_whole_row; - - return expr; -} - -/* - * RelationGetPartitionQual - * - * Returns a list of partition quals - */ -List * -RelationGetPartitionQual(Relation rel) -{ - /* Quick exit */ - if (!rel->rd_rel->relispartition) - return NIL; - - return generate_partition_qual(rel); -} - -/* - * get_partition_qual_relid - * - * Returns an expression tree describing the passed-in relation's partition - * constraint. If there is no partition constraint returns NULL; this can - * happen if the default partition is the only partition. - */ -Expr * -get_partition_qual_relid(Oid relid) -{ - Relation rel = heap_open(relid, AccessShareLock); - Expr *result = NULL; - List *and_args; - - /* Do the work only if this relation is a partition. */ - if (rel->rd_rel->relispartition) - { - and_args = generate_partition_qual(rel); - - if (and_args == NIL) - result = NULL; - else if (list_length(and_args) > 1) - result = makeBoolExpr(AND_EXPR, and_args, -1); - else - result = linitial(and_args); - } - - /* Keep the lock. */ - heap_close(rel, NoLock); - - return result; -} - - -/* - * get_partition_operator - * - * Return oid of the operator of given strategy for a given partition key - * column. - */ -static Oid -get_partition_operator(PartitionKey key, int col, StrategyNumber strategy, - bool *need_relabel) -{ - Oid operoid; - - /* - * First check if there exists an operator of the given strategy, with - * this column's type as both its lefttype and righttype, in the - * partitioning operator family specified for the column. - */ - operoid = get_opfamily_member(key->partopfamily[col], - key->parttypid[col], - key->parttypid[col], - strategy); - - /* - * If one doesn't exist, we must resort to using an operator in the same - * operator family but with the operator class declared input type. It is - * OK to do so, because the column's type is known to be binary-coercible - * with the operator class input type (otherwise, the operator class in - * question would not have been accepted as the partitioning operator - * class). We must however inform the caller to wrap the non-Const - * expression with a RelabelType node to denote the implicit coercion. It - * ensures that the resulting expression structurally matches similarly - * processed expressions within the optimizer. - */ - if (!OidIsValid(operoid)) - { - operoid = get_opfamily_member(key->partopfamily[col], - key->partopcintype[col], - key->partopcintype[col], - strategy); - if (!OidIsValid(operoid)) - elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", - strategy, key->partopcintype[col], key->partopcintype[col], - key->partopfamily[col]); - *need_relabel = true; - } - else - *need_relabel = false; - - return operoid; -} - -/* - * make_partition_op_expr - * Returns an Expr for the given partition key column with arg1 and - * arg2 as its leftop and rightop, respectively - */ -static Expr * -make_partition_op_expr(PartitionKey key, int keynum, - uint16 strategy, Expr *arg1, Expr *arg2) -{ - Oid operoid; - bool need_relabel = false; - Expr *result = NULL; - - /* Get the correct btree operator for this partitioning column */ - operoid = get_partition_operator(key, keynum, strategy, &need_relabel); - - /* - * Chosen operator may be such that the non-Const operand needs to be - * coerced, so apply the same; see the comment in - * get_partition_operator(). - */ - if (!IsA(arg1, Const) && - (need_relabel || - key->partcollation[keynum] != key->parttypcoll[keynum])) - arg1 = (Expr *) makeRelabelType(arg1, - key->partopcintype[keynum], - -1, - key->partcollation[keynum], - COERCE_EXPLICIT_CAST); - - /* Generate the actual expression */ - switch (key->strategy) - { - case PARTITION_STRATEGY_LIST: - { - List *elems = (List *) arg2; - int nelems = list_length(elems); - - Assert(nelems >= 1); - Assert(keynum == 0); - - if (nelems > 1 && - !type_is_array(key->parttypid[keynum])) - { - ArrayExpr *arrexpr; - ScalarArrayOpExpr *saopexpr; - - /* Construct an ArrayExpr for the right-hand inputs */ - arrexpr = makeNode(ArrayExpr); - arrexpr->array_typeid = - get_array_type(key->parttypid[keynum]); - arrexpr->array_collid = key->parttypcoll[keynum]; - arrexpr->element_typeid = key->parttypid[keynum]; - arrexpr->elements = elems; - arrexpr->multidims = false; - arrexpr->location = -1; - - /* Build leftop = ANY (rightop) */ - saopexpr = makeNode(ScalarArrayOpExpr); - saopexpr->opno = operoid; - saopexpr->opfuncid = get_opcode(operoid); - saopexpr->useOr = true; - saopexpr->inputcollid = key->partcollation[keynum]; - saopexpr->args = list_make2(arg1, arrexpr); - saopexpr->location = -1; - - result = (Expr *) saopexpr; - } - else - { - List *elemops = NIL; - ListCell *lc; - - foreach (lc, elems) - { - Expr *elem = lfirst(lc), - *elemop; - - elemop = make_opclause(operoid, - BOOLOID, - false, - arg1, elem, - InvalidOid, - key->partcollation[keynum]); - elemops = lappend(elemops, elemop); - } - - result = nelems > 1 ? makeBoolExpr(OR_EXPR, elemops, -1) : linitial(elemops); - } - break; - } - - case PARTITION_STRATEGY_RANGE: - result = make_opclause(operoid, - BOOLOID, - false, - arg1, arg2, - InvalidOid, - key->partcollation[keynum]); - break; - - default: - elog(ERROR, "invalid partitioning strategy"); - break; - } - - return result; -} - -/* - * get_qual_for_hash - * - * Returns a CHECK constraint expression to use as a hash partition's - * constraint, given the parent relation and partition bound structure. - * - * The partition constraint for a hash partition is always a call to the - * built-in function satisfies_hash_partition(). - */ -static List * -get_qual_for_hash(Relation parent, PartitionBoundSpec *spec) -{ - PartitionKey key = RelationGetPartitionKey(parent); - FuncExpr *fexpr; - Node *relidConst; - Node *modulusConst; - Node *remainderConst; - List *args; - ListCell *partexprs_item; - int i; - - /* Fixed arguments. */ - relidConst = (Node *) makeConst(OIDOID, - -1, - InvalidOid, - sizeof(Oid), - ObjectIdGetDatum(RelationGetRelid(parent)), - false, - true); - - modulusConst = (Node *) makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - Int32GetDatum(spec->modulus), - false, - true); - - remainderConst = (Node *) makeConst(INT4OID, - -1, - InvalidOid, - sizeof(int32), - Int32GetDatum(spec->remainder), - false, - true); - - args = list_make3(relidConst, modulusConst, remainderConst); - partexprs_item = list_head(key->partexprs); - - /* Add an argument for each key column. */ - for (i = 0; i < key->partnatts; i++) - { - Node *keyCol; - - /* Left operand */ - if (key->partattrs[i] != 0) - { - keyCol = (Node *) makeVar(1, - key->partattrs[i], - key->parttypid[i], - key->parttypmod[i], - key->parttypcoll[i], - 0); - } - else - { - keyCol = (Node *) copyObject(lfirst(partexprs_item)); - partexprs_item = lnext(partexprs_item); - } - - args = lappend(args, keyCol); - } - - fexpr = makeFuncExpr(F_SATISFIES_HASH_PARTITION, - BOOLOID, - args, - InvalidOid, - InvalidOid, - COERCE_EXPLICIT_CALL); - - return list_make1(fexpr); -} - -/* - * get_qual_for_list - * - * Returns an implicit-AND list of expressions to use as a list partition's - * constraint, given the parent relation and partition bound structure. - * - * The function returns NIL for a default partition when it's the only - * partition since in that case there is no constraint. - */ -static List * -get_qual_for_list(Relation parent, PartitionBoundSpec *spec) -{ - PartitionKey key = RelationGetPartitionKey(parent); - List *result; - Expr *keyCol; - Expr *opexpr; - NullTest *nulltest; - ListCell *cell; - List *elems = NIL; - bool list_has_null = false; - - /* - * Only single-column list partitioning is supported, so we are worried - * only about the partition key with index 0. - */ - Assert(key->partnatts == 1); - - /* Construct Var or expression representing the partition column */ - if (key->partattrs[0] != 0) - keyCol = (Expr *) makeVar(1, - key->partattrs[0], - key->parttypid[0], - key->parttypmod[0], - key->parttypcoll[0], - 0); - else - keyCol = (Expr *) copyObject(linitial(key->partexprs)); - - /* - * For default list partition, collect datums for all the partitions. The - * default partition constraint should check that the partition key is - * equal to none of those. - */ - if (spec->is_default) - { - int i; - int ndatums = 0; - PartitionDesc pdesc = RelationGetPartitionDesc(parent); - PartitionBoundInfo boundinfo = pdesc->boundinfo; - - if (boundinfo) - { - ndatums = boundinfo->ndatums; - - if (partition_bound_accepts_nulls(boundinfo)) - list_has_null = true; - } - - /* - * If default is the only partition, there need not be any partition - * constraint on it. - */ - if (ndatums == 0 && !list_has_null) - return NIL; - - for (i = 0; i < ndatums; i++) - { - Const *val; - - /* - * Construct Const from known-not-null datum. We must be careful - * to copy the value, because our result has to be able to outlive - * the relcache entry we're copying from. - */ - val = makeConst(key->parttypid[0], - key->parttypmod[0], - key->parttypcoll[0], - key->parttyplen[0], - datumCopy(*boundinfo->datums[i], - key->parttypbyval[0], - key->parttyplen[0]), - false, /* isnull */ - key->parttypbyval[0]); - - elems = lappend(elems, val); - } - } - else - { - /* - * Create list of Consts for the allowed values, excluding any nulls. - */ - foreach(cell, spec->listdatums) - { - Const *val = castNode(Const, lfirst(cell)); - - if (val->constisnull) - list_has_null = true; - else - elems = lappend(elems, copyObject(val)); - } - } - - if (elems) - { - /* - * Generate the operator expression from the non-null partition - * values. - */ - opexpr = make_partition_op_expr(key, 0, BTEqualStrategyNumber, - keyCol, (Expr *) elems); - } - else - { - /* - * If there are no partition values, we don't need an operator - * expression. - */ - opexpr = NULL; - } - - if (!list_has_null) - { - /* - * Gin up a "col IS NOT NULL" test that will be AND'd with the main - * expression. This might seem redundant, but the partition routing - * machinery needs it. - */ - nulltest = makeNode(NullTest); - nulltest->arg = keyCol; - nulltest->nulltesttype = IS_NOT_NULL; - nulltest->argisrow = false; - nulltest->location = -1; - - result = opexpr ? list_make2(nulltest, opexpr) : list_make1(nulltest); - } - else - { - /* - * Gin up a "col IS NULL" test that will be OR'd with the main - * expression. - */ - nulltest = makeNode(NullTest); - nulltest->arg = keyCol; - nulltest->nulltesttype = IS_NULL; - nulltest->argisrow = false; - nulltest->location = -1; - - if (opexpr) - { - Expr *or; - - or = makeBoolExpr(OR_EXPR, list_make2(nulltest, opexpr), -1); - result = list_make1(or); - } - else - result = list_make1(nulltest); - } - - /* - * Note that, in general, applying NOT to a constraint expression doesn't - * necessarily invert the set of rows it accepts, because NOT (NULL) is - * NULL. However, the partition constraints we construct here never - * evaluate to NULL, so applying NOT works as intended. - */ - if (spec->is_default) - { - result = list_make1(make_ands_explicit(result)); - result = list_make1(makeBoolExpr(NOT_EXPR, result, -1)); - } - - return result; -} - -/* - * get_range_key_properties - * Returns range partition key information for a given column - * - * This is a subroutine for get_qual_for_range, and its API is pretty - * specialized to that caller. - * - * Constructs an Expr for the key column (returned in *keyCol) and Consts - * for the lower and upper range limits (returned in *lower_val and - * *upper_val). For MINVALUE/MAXVALUE limits, NULL is returned instead of - * a Const. All of these structures are freshly palloc'd. - * - * *partexprs_item points to the cell containing the next expression in - * the key->partexprs list, or NULL. It may be advanced upon return. - */ -static void -get_range_key_properties(PartitionKey key, int keynum, - PartitionRangeDatum *ldatum, - PartitionRangeDatum *udatum, - ListCell **partexprs_item, - Expr **keyCol, - Const **lower_val, Const **upper_val) -{ - /* Get partition key expression for this column */ - if (key->partattrs[keynum] != 0) - { - *keyCol = (Expr *) makeVar(1, - key->partattrs[keynum], - key->parttypid[keynum], - key->parttypmod[keynum], - key->parttypcoll[keynum], - 0); - } - else - { - if (*partexprs_item == NULL) - elog(ERROR, "wrong number of partition key expressions"); - *keyCol = copyObject(lfirst(*partexprs_item)); - *partexprs_item = lnext(*partexprs_item); - } - - /* Get appropriate Const nodes for the bounds */ - if (ldatum->kind == PARTITION_RANGE_DATUM_VALUE) - *lower_val = castNode(Const, copyObject(ldatum->value)); - else - *lower_val = NULL; - - if (udatum->kind == PARTITION_RANGE_DATUM_VALUE) - *upper_val = castNode(Const, copyObject(udatum->value)); - else - *upper_val = NULL; -} - - /* - * get_range_nulltest - * - * A non-default range partition table does not currently allow partition - * keys to be null, so emit an IS NOT NULL expression for each key column. - */ -static List * -get_range_nulltest(PartitionKey key) -{ - List *result = NIL; - NullTest *nulltest; - ListCell *partexprs_item; - int i; - - partexprs_item = list_head(key->partexprs); - for (i = 0; i < key->partnatts; i++) - { - Expr *keyCol; - - if (key->partattrs[i] != 0) - { - keyCol = (Expr *) makeVar(1, - key->partattrs[i], - key->parttypid[i], - key->parttypmod[i], - key->parttypcoll[i], - 0); - } - else - { - if (partexprs_item == NULL) - elog(ERROR, "wrong number of partition key expressions"); - keyCol = copyObject(lfirst(partexprs_item)); - partexprs_item = lnext(partexprs_item); - } - - nulltest = makeNode(NullTest); - nulltest->arg = keyCol; - nulltest->nulltesttype = IS_NOT_NULL; - nulltest->argisrow = false; - nulltest->location = -1; - result = lappend(result, nulltest); - } - - return result; -} - -/* - * get_qual_for_range - * - * Returns an implicit-AND list of expressions to use as a range partition's - * constraint, given the parent relation and partition bound structure. - * - * For a multi-column range partition key, say (a, b, c), with (al, bl, cl) - * as the lower bound tuple and (au, bu, cu) as the upper bound tuple, we - * generate an expression tree of the following form: - * - * (a IS NOT NULL) and (b IS NOT NULL) and (c IS NOT NULL) - * AND - * (a > al OR (a = al AND b > bl) OR (a = al AND b = bl AND c >= cl)) - * AND - * (a < au OR (a = au AND b < bu) OR (a = au AND b = bu AND c < cu)) - * - * It is often the case that a prefix of lower and upper bound tuples contains - * the same values, for example, (al = au), in which case, we will emit an - * expression tree of the following form: - * - * (a IS NOT NULL) and (b IS NOT NULL) and (c IS NOT NULL) - * AND - * (a = al) - * AND - * (b > bl OR (b = bl AND c >= cl)) - * AND - * (b < bu) OR (b = bu AND c < cu)) - * - * If a bound datum is either MINVALUE or MAXVALUE, these expressions are - * simplified using the fact that any value is greater than MINVALUE and less - * than MAXVALUE. So, for example, if cu = MAXVALUE, c < cu is automatically - * true, and we need not emit any expression for it, and the last line becomes - * - * (b < bu) OR (b = bu), which is simplified to (b <= bu) - * - * In most common cases with only one partition column, say a, the following - * expression tree will be generated: a IS NOT NULL AND a >= al AND a < au - * - * For default partition, it returns the negation of the constraints of all - * the other partitions. - * - * External callers should pass for_default as false; we set it to true only - * when recursing. - */ -static List * -get_qual_for_range(Relation parent, PartitionBoundSpec *spec, - bool for_default) -{ - List *result = NIL; - ListCell *cell1, - *cell2, - *partexprs_item, - *partexprs_item_saved; - int i, - j; - PartitionRangeDatum *ldatum, - *udatum; - PartitionKey key = RelationGetPartitionKey(parent); - Expr *keyCol; - Const *lower_val, - *upper_val; - List *lower_or_arms, - *upper_or_arms; - int num_or_arms, - current_or_arm; - ListCell *lower_or_start_datum, - *upper_or_start_datum; - bool need_next_lower_arm, - need_next_upper_arm; - - if (spec->is_default) - { - List *or_expr_args = NIL; - PartitionDesc pdesc = RelationGetPartitionDesc(parent); - Oid *inhoids = pdesc->oids; - int nparts = pdesc->nparts, - i; - - for (i = 0; i < nparts; i++) - { - Oid inhrelid = inhoids[i]; - HeapTuple tuple; - Datum datum; - bool isnull; - PartitionBoundSpec *bspec; - - tuple = SearchSysCache1(RELOID, inhrelid); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", inhrelid); - - datum = SysCacheGetAttr(RELOID, tuple, - Anum_pg_class_relpartbound, - &isnull); - - Assert(!isnull); - bspec = (PartitionBoundSpec *) - stringToNode(TextDatumGetCString(datum)); - if (!IsA(bspec, PartitionBoundSpec)) - elog(ERROR, "expected PartitionBoundSpec"); - - if (!bspec->is_default) - { - List *part_qual; - - part_qual = get_qual_for_range(parent, bspec, true); - - /* - * AND the constraints of the partition and add to - * or_expr_args - */ - or_expr_args = lappend(or_expr_args, list_length(part_qual) > 1 - ? makeBoolExpr(AND_EXPR, part_qual, -1) - : linitial(part_qual)); - } - ReleaseSysCache(tuple); - } - - if (or_expr_args != NIL) - { - Expr *other_parts_constr; - - /* - * Combine the constraints obtained for non-default partitions - * using OR. As requested, each of the OR's args doesn't include - * the NOT NULL test for partition keys (which is to avoid its - * useless repetition). Add the same now. - */ - other_parts_constr = - makeBoolExpr(AND_EXPR, - lappend(get_range_nulltest(key), - list_length(or_expr_args) > 1 - ? makeBoolExpr(OR_EXPR, or_expr_args, - -1) - : linitial(or_expr_args)), - -1); - - /* - * Finally, the default partition contains everything *NOT* - * contained in the non-default partitions. - */ - result = list_make1(makeBoolExpr(NOT_EXPR, - list_make1(other_parts_constr), -1)); - } - - return result; - } - - lower_or_start_datum = list_head(spec->lowerdatums); - upper_or_start_datum = list_head(spec->upperdatums); - num_or_arms = key->partnatts; - - /* - * If it is the recursive call for default, we skip the get_range_nulltest - * to avoid accumulating the NullTest on the same keys for each partition. - */ - if (!for_default) - result = get_range_nulltest(key); - - /* - * Iterate over the key columns and check if the corresponding lower and - * upper datums are equal using the btree equality operator for the - * column's type. If equal, we emit single keyCol = common_value - * expression. Starting from the first column for which the corresponding - * lower and upper bound datums are not equal, we generate OR expressions - * as shown in the function's header comment. - */ - i = 0; - partexprs_item = list_head(key->partexprs); - partexprs_item_saved = partexprs_item; /* placate compiler */ - forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums) - { - EState *estate; - MemoryContext oldcxt; - Expr *test_expr; - ExprState *test_exprstate; - Datum test_result; - bool isNull; - - ldatum = castNode(PartitionRangeDatum, lfirst(cell1)); - udatum = castNode(PartitionRangeDatum, lfirst(cell2)); - - /* - * Since get_range_key_properties() modifies partexprs_item, and we - * might need to start over from the previous expression in the later - * part of this function, save away the current value. - */ - partexprs_item_saved = partexprs_item; - - get_range_key_properties(key, i, ldatum, udatum, - &partexprs_item, - &keyCol, - &lower_val, &upper_val); - - /* - * If either value is NULL, the corresponding partition bound is - * either MINVALUE or MAXVALUE, and we treat them as unequal, because - * even if they're the same, there is no common value to equate the - * key column with. - */ - if (!lower_val || !upper_val) - break; - - /* Create the test expression */ - estate = CreateExecutorState(); - oldcxt = MemoryContextSwitchTo(estate->es_query_cxt); - test_expr = make_partition_op_expr(key, i, BTEqualStrategyNumber, - (Expr *) lower_val, - (Expr *) upper_val); - fix_opfuncids((Node *) test_expr); - test_exprstate = ExecInitExpr(test_expr, NULL); - test_result = ExecEvalExprSwitchContext(test_exprstate, - GetPerTupleExprContext(estate), - &isNull); - MemoryContextSwitchTo(oldcxt); - FreeExecutorState(estate); - - /* If not equal, go generate the OR expressions */ - if (!DatumGetBool(test_result)) - break; - - /* - * The bounds for the last key column can't be equal, because such a - * range partition would never be allowed to be defined (it would have - * an empty range otherwise). - */ - if (i == key->partnatts - 1) - elog(ERROR, "invalid range bound specification"); - - /* Equal, so generate keyCol = lower_val expression */ - result = lappend(result, - make_partition_op_expr(key, i, BTEqualStrategyNumber, - keyCol, (Expr *) lower_val)); - - i++; - } - - /* First pair of lower_val and upper_val that are not equal. */ - lower_or_start_datum = cell1; - upper_or_start_datum = cell2; - - /* OR will have as many arms as there are key columns left. */ - num_or_arms = key->partnatts - i; - current_or_arm = 0; - lower_or_arms = upper_or_arms = NIL; - need_next_lower_arm = need_next_upper_arm = true; - while (current_or_arm < num_or_arms) - { - List *lower_or_arm_args = NIL, - *upper_or_arm_args = NIL; - - /* Restart scan of columns from the i'th one */ - j = i; - partexprs_item = partexprs_item_saved; - - for_both_cell(cell1, lower_or_start_datum, cell2, upper_or_start_datum) - { - PartitionRangeDatum *ldatum_next = NULL, - *udatum_next = NULL; - - ldatum = castNode(PartitionRangeDatum, lfirst(cell1)); - if (lnext(cell1)) - ldatum_next = castNode(PartitionRangeDatum, - lfirst(lnext(cell1))); - udatum = castNode(PartitionRangeDatum, lfirst(cell2)); - if (lnext(cell2)) - udatum_next = castNode(PartitionRangeDatum, - lfirst(lnext(cell2))); - get_range_key_properties(key, j, ldatum, udatum, - &partexprs_item, - &keyCol, - &lower_val, &upper_val); - - if (need_next_lower_arm && lower_val) - { - uint16 strategy; - - /* - * For the non-last columns of this arm, use the EQ operator. - * For the last column of this arm, use GT, unless this is the - * last column of the whole bound check, or the next bound - * datum is MINVALUE, in which case use GE. - */ - if (j - i < current_or_arm) - strategy = BTEqualStrategyNumber; - else if (j == key->partnatts - 1 || - (ldatum_next && - ldatum_next->kind == PARTITION_RANGE_DATUM_MINVALUE)) - strategy = BTGreaterEqualStrategyNumber; - else - strategy = BTGreaterStrategyNumber; - - lower_or_arm_args = lappend(lower_or_arm_args, - make_partition_op_expr(key, j, - strategy, - keyCol, - (Expr *) lower_val)); - } - - if (need_next_upper_arm && upper_val) - { - uint16 strategy; - - /* - * For the non-last columns of this arm, use the EQ operator. - * For the last column of this arm, use LT, unless the next - * bound datum is MAXVALUE, in which case use LE. - */ - if (j - i < current_or_arm) - strategy = BTEqualStrategyNumber; - else if (udatum_next && - udatum_next->kind == PARTITION_RANGE_DATUM_MAXVALUE) - strategy = BTLessEqualStrategyNumber; - else - strategy = BTLessStrategyNumber; - - upper_or_arm_args = lappend(upper_or_arm_args, - make_partition_op_expr(key, j, - strategy, - keyCol, - (Expr *) upper_val)); - } - - /* - * Did we generate enough of OR's arguments? First arm considers - * the first of the remaining columns, second arm considers first - * two of the remaining columns, and so on. - */ - ++j; - if (j - i > current_or_arm) - { - /* - * We must not emit any more arms if the new column that will - * be considered is unbounded, or this one was. - */ - if (!lower_val || !ldatum_next || - ldatum_next->kind != PARTITION_RANGE_DATUM_VALUE) - need_next_lower_arm = false; - if (!upper_val || !udatum_next || - udatum_next->kind != PARTITION_RANGE_DATUM_VALUE) - need_next_upper_arm = false; - break; - } - } - - if (lower_or_arm_args != NIL) - lower_or_arms = lappend(lower_or_arms, - list_length(lower_or_arm_args) > 1 - ? makeBoolExpr(AND_EXPR, lower_or_arm_args, -1) - : linitial(lower_or_arm_args)); - - if (upper_or_arm_args != NIL) - upper_or_arms = lappend(upper_or_arms, - list_length(upper_or_arm_args) > 1 - ? makeBoolExpr(AND_EXPR, upper_or_arm_args, -1) - : linitial(upper_or_arm_args)); - - /* If no work to do in the next iteration, break away. */ - if (!need_next_lower_arm && !need_next_upper_arm) - break; - - ++current_or_arm; - } - - /* - * Generate the OR expressions for each of lower and upper bounds (if - * required), and append to the list of implicitly ANDed list of - * expressions. - */ - if (lower_or_arms != NIL) - result = lappend(result, - list_length(lower_or_arms) > 1 - ? makeBoolExpr(OR_EXPR, lower_or_arms, -1) - : linitial(lower_or_arms)); - if (upper_or_arms != NIL) - result = lappend(result, - list_length(upper_or_arms) > 1 - ? makeBoolExpr(OR_EXPR, upper_or_arms, -1) - : linitial(upper_or_arms)); - - /* - * As noted above, for non-default, we return list with constant TRUE. If - * the result is NIL during the recursive call for default, it implies - * this is the only other partition which can hold every value of the key - * except NULL. Hence we return the NullTest result skipped earlier. - */ - if (result == NIL) - result = for_default - ? get_range_nulltest(key) - : list_make1(makeBoolConst(true, false)); - - return result; -} - -/* - * generate_partition_qual - * - * Generate partition predicate from rel's partition bound expression. The - * function returns a NIL list if there is no predicate. - * - * Result expression tree is stored CacheMemoryContext to ensure it survives - * as long as the relcache entry. But we should be running in a less long-lived - * working context. To avoid leaking cache memory if this routine fails partway - * through, we build in working memory and then copy the completed structure - * into cache memory. - */ -static List * -generate_partition_qual(Relation rel) -{ - HeapTuple tuple; - MemoryContext oldcxt; - Datum boundDatum; - bool isnull; - PartitionBoundSpec *bound; - List *my_qual = NIL, - *result = NIL; - Relation parent; - bool found_whole_row; - - /* Guard against stack overflow due to overly deep partition tree */ - check_stack_depth(); - - /* Quick copy */ - if (rel->rd_partcheck != NIL) - return copyObject(rel->rd_partcheck); - - /* Grab at least an AccessShareLock on the parent table */ - parent = heap_open(get_partition_parent(RelationGetRelid(rel)), - AccessShareLock); - - /* Get pg_class.relpartbound */ - tuple = SearchSysCache1(RELOID, RelationGetRelid(rel)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", - RelationGetRelid(rel)); - - boundDatum = SysCacheGetAttr(RELOID, tuple, - Anum_pg_class_relpartbound, - &isnull); - if (isnull) /* should not happen */ - elog(ERROR, "relation \"%s\" has relpartbound = null", - RelationGetRelationName(rel)); - bound = castNode(PartitionBoundSpec, - stringToNode(TextDatumGetCString(boundDatum))); - ReleaseSysCache(tuple); - - my_qual = get_qual_from_partbound(rel, parent, bound); - - /* Add the parent's quals to the list (if any) */ - if (parent->rd_rel->relispartition) - result = list_concat(generate_partition_qual(parent), my_qual); - else - result = my_qual; - - /* - * Change Vars to have partition's attnos instead of the parent's. We do - * this after we concatenate the parent's quals, because we want every Var - * in it to bear this relation's attnos. It's safe to assume varno = 1 - * here. - */ - result = map_partition_varattnos(result, 1, rel, parent, - &found_whole_row); - /* There can never be a whole-row reference here */ - if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in partition key"); - - /* Save a copy in the relcache */ - oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - rel->rd_partcheck = copyObject(result); - MemoryContextSwitchTo(oldcxt); - - /* Keep the parent locked until commit */ - heap_close(parent, NoLock); - - return result; -} - -/* - * get_partition_for_tuple - * Finds partition of relation which accepts the partition key specified - * in values and isnull - * - * Return value is index of the partition (>= 0 and < partdesc->nparts) if one - * found or -1 if none found. - */ -int -get_partition_for_tuple(Relation relation, Datum *values, bool *isnull) -{ - int bound_offset; - int part_index = -1; - PartitionKey key = RelationGetPartitionKey(relation); - PartitionDesc partdesc = RelationGetPartitionDesc(relation); - - /* Route as appropriate based on partitioning strategy. */ - switch (key->strategy) - { - case PARTITION_STRATEGY_HASH: - { - PartitionBoundInfo boundinfo = partdesc->boundinfo; - int greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); - uint64 rowHash = compute_hash_value(key->partnatts, - key->partsupfunc, - values, isnull); - - part_index = boundinfo->indexes[rowHash % greatest_modulus]; - } - break; - - case PARTITION_STRATEGY_LIST: - if (isnull[0]) - { - if (partition_bound_accepts_nulls(partdesc->boundinfo)) - part_index = partdesc->boundinfo->null_index; - } - else - { - bool equal = false; - - bound_offset = partition_list_bsearch(key->partsupfunc, - key->partcollation, - partdesc->boundinfo, - values[0], &equal); - if (bound_offset >= 0 && equal) - part_index = partdesc->boundinfo->indexes[bound_offset]; - } - break; - - case PARTITION_STRATEGY_RANGE: - { - bool equal = false, - range_partkey_has_null = false; - int i; - - /* - * No range includes NULL, so this will be accepted by the - * default partition if there is one, and otherwise rejected. - */ - for (i = 0; i < key->partnatts; i++) - { - if (isnull[i]) - { - range_partkey_has_null = true; - break; - } - } - - if (!range_partkey_has_null) - { - bound_offset = partition_range_datum_bsearch(key->partsupfunc, - key->partcollation, - partdesc->boundinfo, - key->partnatts, - values, - &equal); - - /* - * The bound at bound_offset is less than or equal to the - * tuple value, so the bound at offset+1 is the upper - * bound of the partition we're looking for, if there - * actually exists one. - */ - part_index = partdesc->boundinfo->indexes[bound_offset + 1]; - } - } - break; + { + AttrNumber *part_attnos; - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) key->strategy); + part_attnos = convert_tuples_by_name_map(RelationGetDescr(to_rel), + RelationGetDescr(from_rel)); + expr = (List *) map_variable_attnos((Node *) expr, + fromrel_varno, 0, + part_attnos, + RelationGetDescr(from_rel)->natts, + RelationGetForm(to_rel)->reltype, + &my_found_whole_row); } - /* - * part_index < 0 means we failed to find a partition of this parent. Use - * the default partition, if there is one. - */ - if (part_index < 0) - part_index = partdesc->boundinfo->default_index; + if (found_whole_row) + *found_whole_row = my_found_whole_row; - return part_index; + return expr; } /* @@ -2626,8 +236,7 @@ get_partition_for_tuple(Relation relation, Datum *values, bool *isnull) * text. */ bool -has_partition_attrs(Relation rel, Bitmapset *attnums, - bool *used_in_expr) +has_partition_attrs(Relation rel, Bitmapset *attnums, bool *used_in_expr) { PartitionKey key; int partnatts; @@ -2665,7 +274,7 @@ has_partition_attrs(Relation rel, Bitmapset *attnums, /* Find all attributes referenced */ pull_varattnos(expr, 1, &expr_attrs); - partexprs_item = lnext(partexprs_item); + partexprs_item = lnext(partexprs, partexprs_item); if (bms_overlap(attnums, expr_attrs)) { @@ -2679,410 +288,6 @@ has_partition_attrs(Relation rel, Bitmapset *attnums, return false; } -/* - * qsort_partition_hbound_cmp - * - * We sort hash bounds by modulus, then by remainder. - */ -static int32 -qsort_partition_hbound_cmp(const void *a, const void *b) -{ - PartitionHashBound *h1 = (*(PartitionHashBound *const *) a); - PartitionHashBound *h2 = (*(PartitionHashBound *const *) b); - - return partition_hbound_cmp(h1->modulus, h1->remainder, - h2->modulus, h2->remainder); -} - -/* - * partition_hbound_cmp - * - * Compares modulus first, then remainder if modulus are equal. - */ -static int32 -partition_hbound_cmp(int modulus1, int remainder1, int modulus2, int remainder2) -{ - if (modulus1 < modulus2) - return -1; - if (modulus1 > modulus2) - return 1; - if (modulus1 == modulus2 && remainder1 != remainder2) - return (remainder1 > remainder2) ? 1 : -1; - return 0; -} - -/* - * qsort_partition_list_value_cmp - * - * Compare two list partition bound datums - */ -static int32 -qsort_partition_list_value_cmp(const void *a, const void *b, void *arg) -{ - Datum val1 = (*(const PartitionListValue **) a)->value, - val2 = (*(const PartitionListValue **) b)->value; - PartitionKey key = (PartitionKey) arg; - - return DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0], - key->partcollation[0], - val1, val2)); -} - -/* - * make_one_range_bound - * - * Return a PartitionRangeBound given a list of PartitionRangeDatum elements - * and a flag telling whether the bound is lower or not. Made into a function - * because there are multiple sites that want to use this facility. - */ -static PartitionRangeBound * -make_one_range_bound(PartitionKey key, int index, List *datums, bool lower) -{ - PartitionRangeBound *bound; - ListCell *lc; - int i; - - Assert(datums != NIL); - - bound = (PartitionRangeBound *) palloc0(sizeof(PartitionRangeBound)); - bound->index = index; - bound->datums = (Datum *) palloc0(key->partnatts * sizeof(Datum)); - bound->kind = (PartitionRangeDatumKind *) palloc0(key->partnatts * - sizeof(PartitionRangeDatumKind)); - bound->lower = lower; - - i = 0; - foreach(lc, datums) - { - PartitionRangeDatum *datum = castNode(PartitionRangeDatum, lfirst(lc)); - - /* What's contained in this range datum? */ - bound->kind[i] = datum->kind; - - if (datum->kind == PARTITION_RANGE_DATUM_VALUE) - { - Const *val = castNode(Const, datum->value); - - if (val->constisnull) - elog(ERROR, "invalid range bound datum"); - bound->datums[i] = val->constvalue; - } - - i++; - } - - return bound; -} - -/* Used when sorting range bounds across all range partitions */ -static int32 -qsort_partition_rbound_cmp(const void *a, const void *b, void *arg) -{ - PartitionRangeBound *b1 = (*(PartitionRangeBound *const *) a); - PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b); - PartitionKey key = (PartitionKey) arg; - - return partition_rbound_cmp(key->partnatts, key->partsupfunc, - key->partcollation, b1->datums, b1->kind, - b1->lower, b2); -} - -/* - * partition_rbound_cmp - * - * Return for two range bounds whether the 1st one (specified in datums1, - * kind1, and lower1) is <, =, or > the bound specified in *b2. - * - * partnatts, partsupfunc and partcollation give the number of attributes in the - * bounds to be compared, comparison function to be used and the collations of - * attributes, respectively. - * - * Note that if the values of the two range bounds compare equal, then we take - * into account whether they are upper or lower bounds, and an upper bound is - * considered to be smaller than a lower bound. This is important to the way - * that RelationBuildPartitionDesc() builds the PartitionBoundInfoData - * structure, which only stores the upper bound of a common boundary between - * two contiguous partitions. - */ -static int32 -partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, - Datum *datums1, PartitionRangeDatumKind *kind1, - bool lower1, PartitionRangeBound *b2) -{ - int32 cmpval = 0; /* placate compiler */ - int i; - Datum *datums2 = b2->datums; - PartitionRangeDatumKind *kind2 = b2->kind; - bool lower2 = b2->lower; - - for (i = 0; i < partnatts; i++) - { - /* - * First, handle cases where the column is unbounded, which should not - * invoke the comparison procedure, and should not consider any later - * columns. Note that the PartitionRangeDatumKind enum elements - * compare the same way as the values they represent. - */ - if (kind1[i] < kind2[i]) - return -1; - else if (kind1[i] > kind2[i]) - return 1; - else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE) - - /* - * The column bounds are both MINVALUE or both MAXVALUE. No later - * columns should be considered, but we still need to compare - * whether they are upper or lower bounds. - */ - break; - - cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i], - partcollation[i], - datums1[i], - datums2[i])); - if (cmpval != 0) - break; - } - - /* - * If the comparison is anything other than equal, we're done. If they - * compare equal though, we still have to consider whether the boundaries - * are inclusive or exclusive. Exclusive one is considered smaller of the - * two. - */ - if (cmpval == 0 && lower1 != lower2) - cmpval = lower1 ? 1 : -1; - - return cmpval; -} - -/* - * partition_rbound_datum_cmp - * - * Return whether range bound (specified in rb_datums, rb_kind, and rb_lower) - * is <, =, or > partition key of tuple (tuple_datums) - * - * n_tuple_datums, partsupfunc and partcollation give number of attributes in - * the bounds to be compared, comparison function to be used and the collations - * of attributes resp. - * - */ -int32 -partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, - Datum *rb_datums, PartitionRangeDatumKind *rb_kind, - Datum *tuple_datums, int n_tuple_datums) -{ - int i; - int32 cmpval = -1; - - for (i = 0; i < n_tuple_datums; i++) - { - if (rb_kind[i] == PARTITION_RANGE_DATUM_MINVALUE) - return -1; - else if (rb_kind[i] == PARTITION_RANGE_DATUM_MAXVALUE) - return 1; - - cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i], - partcollation[i], - rb_datums[i], - tuple_datums[i])); - if (cmpval != 0) - break; - } - - return cmpval; -} - -/* - * partition_list_bsearch - * Returns the index of the greatest bound datum that is less than equal - * to the given value or -1 if all of the bound datums are greater - * - * *is_equal is set to true if the bound datum at the returned index is equal - * to the input value. - */ -int -partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, - PartitionBoundInfo boundinfo, - Datum value, bool *is_equal) -{ - int lo, - hi, - mid; - - lo = -1; - hi = boundinfo->ndatums - 1; - while (lo < hi) - { - int32 cmpval; - - mid = (lo + hi + 1) / 2; - cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[0], - partcollation[0], - boundinfo->datums[mid][0], - value)); - if (cmpval <= 0) - { - lo = mid; - *is_equal = (cmpval == 0); - if (*is_equal) - break; - } - else - hi = mid - 1; - } - - return lo; -} - -/* - * partition_range_bsearch - * Returns the index of the greatest range bound that is less than or - * equal to the given range bound or -1 if all of the range bounds are - * greater - * - * *is_equal is set to true if the range bound at the returned index is equal - * to the input range bound - */ -int -partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, - Oid *partcollation, - PartitionBoundInfo boundinfo, - PartitionRangeBound *probe, bool *is_equal) -{ - int lo, - hi, - mid; - - lo = -1; - hi = boundinfo->ndatums - 1; - while (lo < hi) - { - int32 cmpval; - - mid = (lo + hi + 1) / 2; - cmpval = partition_rbound_cmp(partnatts, partsupfunc, partcollation, - boundinfo->datums[mid], - boundinfo->kind[mid], - (boundinfo->indexes[mid] == -1), - probe); - if (cmpval <= 0) - { - lo = mid; - *is_equal = (cmpval == 0); - - if (*is_equal) - break; - } - else - hi = mid - 1; - } - - return lo; -} - -/* - * partition_range_bsearch - * Returns the index of the greatest range bound that is less than or - * equal to the given tuple or -1 if all of the range bounds are greater - * - * *is_equal is set to true if the range bound at the returned index is equal - * to the input tuple. - */ -int -partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, - PartitionBoundInfo boundinfo, - int nvalues, Datum *values, bool *is_equal) -{ - int lo, - hi, - mid; - - lo = -1; - hi = boundinfo->ndatums - 1; - while (lo < hi) - { - int32 cmpval; - - mid = (lo + hi + 1) / 2; - cmpval = partition_rbound_datum_cmp(partsupfunc, - partcollation, - boundinfo->datums[mid], - boundinfo->kind[mid], - values, - nvalues); - if (cmpval <= 0) - { - lo = mid; - *is_equal = (cmpval == 0); - - if (*is_equal) - break; - } - else - hi = mid - 1; - } - - return lo; -} - -/* - * partition_hash_bsearch - * Returns the index of the greatest (modulus, remainder) pair that is - * less than or equal to the given (modulus, remainder) pair or -1 if - * all of them are greater - */ -int -partition_hash_bsearch(PartitionBoundInfo boundinfo, - int modulus, int remainder) -{ - int lo, - hi, - mid; - - lo = -1; - hi = boundinfo->ndatums - 1; - while (lo < hi) - { - int32 cmpval, - bound_modulus, - bound_remainder; - - mid = (lo + hi + 1) / 2; - bound_modulus = DatumGetInt32(boundinfo->datums[mid][0]); - bound_remainder = DatumGetInt32(boundinfo->datums[mid][1]); - cmpval = partition_hbound_cmp(bound_modulus, bound_remainder, - modulus, remainder); - if (cmpval <= 0) - { - lo = mid; - - if (cmpval == 0) - break; - } - else - hi = mid - 1; - } - - return lo; -} - -/* - * get_default_oid_from_partdesc - * - * Given a partition descriptor, return the OID of the default partition, if - * one exists; else, return InvalidOid. - */ -Oid -get_default_oid_from_partdesc(PartitionDesc partdesc) -{ - if (partdesc && partdesc->boundinfo && - partition_bound_has_default(partdesc->boundinfo)) - return partdesc->oids[partdesc->boundinfo->default_index]; - - return InvalidOid; -} - /* * get_default_partition_oid * @@ -3113,7 +318,7 @@ get_default_partition_oid(Oid parentId) /* * update_default_partition_oid * - * Update pg_partition_table.partdefid with a new default partition OID. + * Update pg_partitioned_table.partdefid with a new default partition OID. */ void update_default_partition_oid(Oid parentId, Oid defaultPartId) @@ -3122,7 +327,7 @@ update_default_partition_oid(Oid parentId, Oid defaultPartId) Relation pg_partitioned_table; Form_pg_partitioned_table part_table_form; - pg_partitioned_table = heap_open(PartitionedRelationId, RowExclusiveLock); + pg_partitioned_table = table_open(PartitionedRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(PARTRELID, ObjectIdGetDatum(parentId)); @@ -3135,7 +340,7 @@ update_default_partition_oid(Oid parentId, Oid defaultPartId) CatalogTupleUpdate(pg_partitioned_table, &tuple->t_self, tuple); heap_freetuple(tuple); - heap_close(pg_partitioned_table, RowExclusiveLock); + table_close(pg_partitioned_table, RowExclusiveLock); } /* @@ -3169,323 +374,3 @@ get_proposed_default_constraint(List *new_part_constraints) return make_ands_implicit(defPartConstraint); } - -/* - * get_partition_bound_num_indexes - * - * Returns the number of the entries in the partition bound indexes array. - */ -static int -get_partition_bound_num_indexes(PartitionBoundInfo bound) -{ - int num_indexes; - - Assert(bound); - - switch (bound->strategy) - { - case PARTITION_STRATEGY_HASH: - - /* - * The number of the entries in the indexes array is same as the - * greatest modulus. - */ - num_indexes = get_hash_partition_greatest_modulus(bound); - break; - - case PARTITION_STRATEGY_LIST: - num_indexes = bound->ndatums; - break; - - case PARTITION_STRATEGY_RANGE: - /* Range partitioned table has an extra index. */ - num_indexes = bound->ndatums + 1; - break; - - default: - elog(ERROR, "unexpected partition strategy: %d", - (int) bound->strategy); - } - - return num_indexes; -} - -/* - * get_hash_partition_greatest_modulus - * - * Returns the greatest modulus of the hash partition bound. The greatest - * modulus will be at the end of the datums array because hash partitions are - * arranged in the ascending order of their modulus and remainders. - */ -int -get_hash_partition_greatest_modulus(PartitionBoundInfo bound) -{ - Assert(bound && bound->strategy == PARTITION_STRATEGY_HASH); - Assert(bound->datums && bound->ndatums > 0); - Assert(DatumGetInt32(bound->datums[bound->ndatums - 1][0]) > 0); - - return DatumGetInt32(bound->datums[bound->ndatums - 1][0]); -} - -/* - * compute_hash_value - * - * Compute the hash value for given not null partition key values. - */ -uint64 -compute_hash_value(int partnatts, FmgrInfo *partsupfunc, - Datum *values, bool *isnull) -{ - int i; - uint64 rowHash = 0; - Datum seed = UInt64GetDatum(HASH_PARTITION_SEED); - - for (i = 0; i < partnatts; i++) - { - if (!isnull[i]) - { - Datum hash; - - Assert(OidIsValid(partsupfunc[i].fn_oid)); - - /* - * Compute hash for each datum value by calling respective - * datatype-specific hash functions of each partition key - * attribute. - */ - hash = FunctionCall2(&partsupfunc[i], values[i], seed); - - /* Form a single 64-bit hash value */ - rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); - } - } - - return rowHash; -} - -/* - * satisfies_hash_partition - * - * This is an SQL-callable function for use in hash partition constraints. - * The first three arguments are the parent table OID, modulus, and remainder. - * The remaining arguments are the value of the partitioning columns (or - * expressions); these are hashed and the results are combined into a single - * hash value by calling hash_combine64. - * - * Returns true if remainder produced when this computed single hash value is - * divided by the given modulus is equal to given remainder, otherwise false. - * - * See get_qual_for_hash() for usage. - */ -Datum -satisfies_hash_partition(PG_FUNCTION_ARGS) -{ - typedef struct ColumnsHashData - { - Oid relid; - int nkeys; - Oid variadic_type; - int16 variadic_typlen; - bool variadic_typbyval; - char variadic_typalign; - FmgrInfo partsupfunc[PARTITION_MAX_KEYS]; - } ColumnsHashData; - Oid parentId; - int modulus; - int remainder; - Datum seed = UInt64GetDatum(HASH_PARTITION_SEED); - ColumnsHashData *my_extra; - uint64 rowHash = 0; - - /* Return null if the parent OID, modulus, or remainder is NULL. */ - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) - PG_RETURN_NULL(); - parentId = PG_GETARG_OID(0); - modulus = PG_GETARG_INT32(1); - remainder = PG_GETARG_INT32(2); - - /* Sanity check modulus and remainder. */ - if (modulus <= 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("modulus for hash partition must be a positive integer"))); - if (remainder < 0) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("remainder for hash partition must be a non-negative integer"))); - if (remainder >= modulus) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("remainder for hash partition must be less than modulus"))); - - /* - * Cache hash function information. - */ - my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; - if (my_extra == NULL || my_extra->relid != parentId) - { - Relation parent; - PartitionKey key; - int j; - - /* Open parent relation and fetch partition keyinfo */ - parent = try_relation_open(parentId, AccessShareLock); - if (parent == NULL) - PG_RETURN_NULL(); - key = RelationGetPartitionKey(parent); - - /* Reject parent table that is not hash-partitioned. */ - if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE || - key->strategy != PARTITION_STRATEGY_HASH) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("\"%s\" is not a hash partitioned table", - get_rel_name(parentId)))); - - if (!get_fn_expr_variadic(fcinfo->flinfo)) - { - int nargs = PG_NARGS() - 3; - - /* complain if wrong number of column values */ - if (key->partnatts != nargs) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("number of partitioning columns (%d) does not match number of partition keys provided (%d)", - key->partnatts, nargs))); - - /* allocate space for our cache */ - fcinfo->flinfo->fn_extra = - MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, - offsetof(ColumnsHashData, partsupfunc) + - sizeof(FmgrInfo) * nargs); - my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; - my_extra->relid = parentId; - my_extra->nkeys = key->partnatts; - - /* check argument types and save fmgr_infos */ - for (j = 0; j < key->partnatts; ++j) - { - Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, j + 3); - - if (argtype != key->parttypid[j] && !IsBinaryCoercible(argtype, key->parttypid[j])) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"", - j + 1, format_type_be(key->parttypid[j]), format_type_be(argtype)))); - - fmgr_info_copy(&my_extra->partsupfunc[j], - &key->partsupfunc[j], - fcinfo->flinfo->fn_mcxt); - } - - } - else - { - ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); - - /* allocate space for our cache -- just one FmgrInfo in this case */ - fcinfo->flinfo->fn_extra = - MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, - offsetof(ColumnsHashData, partsupfunc) + - sizeof(FmgrInfo)); - my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; - my_extra->relid = parentId; - my_extra->nkeys = key->partnatts; - my_extra->variadic_type = ARR_ELEMTYPE(variadic_array); - get_typlenbyvalalign(my_extra->variadic_type, - &my_extra->variadic_typlen, - &my_extra->variadic_typbyval, - &my_extra->variadic_typalign); - - /* check argument types */ - for (j = 0; j < key->partnatts; ++j) - if (key->parttypid[j] != my_extra->variadic_type) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"", - j + 1, - format_type_be(key->parttypid[j]), - format_type_be(my_extra->variadic_type)))); - - fmgr_info_copy(&my_extra->partsupfunc[0], - &key->partsupfunc[0], - fcinfo->flinfo->fn_mcxt); - } - - /* Hold lock until commit */ - relation_close(parent, NoLock); - } - - if (!OidIsValid(my_extra->variadic_type)) - { - int nkeys = my_extra->nkeys; - int i; - - /* - * For a non-variadic call, neither the number of arguments nor their - * types can change across calls, so avoid the expense of rechecking - * here. - */ - - for (i = 0; i < nkeys; i++) - { - Datum hash; - - /* keys start from fourth argument of function. */ - int argno = i + 3; - - if (PG_ARGISNULL(argno)) - continue; - - Assert(OidIsValid(my_extra->partsupfunc[i].fn_oid)); - - hash = FunctionCall2(&my_extra->partsupfunc[i], - PG_GETARG_DATUM(argno), - seed); - - /* Form a single 64-bit hash value */ - rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); - } - } - else - { - ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); - int i; - int nelems; - Datum *datum; - bool *isnull; - - deconstruct_array(variadic_array, - my_extra->variadic_type, - my_extra->variadic_typlen, - my_extra->variadic_typbyval, - my_extra->variadic_typalign, - &datum, &isnull, &nelems); - - /* complain if wrong number of column values */ - if (nelems != my_extra->nkeys) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("number of partitioning columns (%d) does not match number of partition keys provided (%d)", - my_extra->nkeys, nelems))); - - for (i = 0; i < nelems; i++) - { - Datum hash; - - if (isnull[i]) - continue; - - Assert(OidIsValid(my_extra->partsupfunc[0].fn_oid)); - - hash = FunctionCall2(&my_extra->partsupfunc[0], - datum[i], - seed); - - /* Form a single 64-bit hash value */ - rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); - } - } - - PG_RETURN_BOOL(rowHash % modulus == remainder); -} diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c index 66b4af93bdb..1ac235a0f40 100644 --- a/src/backend/catalog/pg_aggregate.c +++ b/src/backend/catalog/pg_aggregate.c @@ -3,7 +3,7 @@ * pg_aggregate.c * routines to support manipulation of the pg_aggregate relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,8 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_aggregate.h" @@ -34,9 +34,9 @@ #include "utils/syscache.h" -static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types, - Oid variadicArgType, - Oid *rettype); +static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types, + Oid variadicArgType, + Oid *rettype); /* @@ -45,6 +45,7 @@ static Oid lookup_agg_function(List *fnName, int nargs, Oid *input_types, ObjectAddress AggregateCreate(const char *aggName, Oid aggNamespace, + bool replace, char aggKind, int numArgs, int numDirectArgs, @@ -77,8 +78,10 @@ AggregateCreate(const char *aggName, { Relation aggdesc; HeapTuple tup; + HeapTuple oldtup; bool nulls[Natts_pg_aggregate]; Datum values[Natts_pg_aggregate]; + bool replaces[Natts_pg_aggregate]; Form_pg_proc proc; Oid transfn; Oid finalfn = InvalidOid; /* can be omitted */ @@ -113,7 +116,7 @@ AggregateCreate(const char *aggName, elog(ERROR, "aggregate must have a transition function"); if (numDirectArgs < 0 || numDirectArgs > numArgs) - elog(ERROR, "incorrect number of direct args for aggregate"); + elog(ERROR, "incorrect number of direct arguments for aggregate"); /* * Aggregates can have at most FUNC_MAX_ARGS-1 args, else the transfn @@ -410,16 +413,17 @@ AggregateCreate(const char *aggName, Oid combineType; /* - * Combine function must have 2 argument, each of which is the trans - * type + * Combine function must have 2 arguments, each of which is the trans + * type. VARIADIC doesn't affect it. */ fnArgs[0] = aggTransType; fnArgs[1] = aggTransType; - combinefn = lookup_agg_function(aggcombinefnName, 2, fnArgs, - variadicArgType, &combineType); + combinefn = lookup_agg_function(aggcombinefnName, 2, + fnArgs, InvalidOid, + &combineType); - /* Ensure the return type matches the aggregates trans type */ + /* Ensure the return type matches the aggregate's trans type */ if (combineType != aggTransType) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), @@ -429,14 +433,14 @@ AggregateCreate(const char *aggName, /* * A combine function to combine INTERNAL states must accept nulls and - * ensure that the returned state is in the correct memory context. + * ensure that the returned state is in the correct memory context. We + * cannot directly check the latter, but we can check the former. */ if (aggTransType == INTERNALOID && func_strict(combinefn)) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("combine function with transition type %s must not be declared STRICT", format_type_be(aggTransType)))); - } /* @@ -444,10 +448,11 @@ AggregateCreate(const char *aggName, */ if (aggserialfnName) { + /* signature is always serialize(internal) returns bytea */ fnArgs[0] = INTERNALOID; serialfn = lookup_agg_function(aggserialfnName, 1, - fnArgs, variadicArgType, + fnArgs, InvalidOid, &rettype); if (rettype != BYTEAOID) @@ -463,11 +468,12 @@ AggregateCreate(const char *aggName, */ if (aggdeserialfnName) { + /* signature is always deserialize(bytea, internal) returns internal */ fnArgs[0] = BYTEAOID; fnArgs[1] = INTERNALOID; /* dummy argument for type safety */ deserialfn = lookup_agg_function(aggdeserialfnName, 2, - fnArgs, variadicArgType, + fnArgs, InvalidOid, &rettype); if (rettype != INTERNALOID) @@ -606,7 +612,7 @@ AggregateCreate(const char *aggName, myself = ProcedureCreate(aggName, aggNamespace, - false, /* no replacement */ + replace, /* maybe replacement */ false, /* doesn't return a set */ finaltype, /* returnType */ GetUserId(), /* proowner */ @@ -629,6 +635,7 @@ AggregateCreate(const char *aggName, parameterDefaults, /* parameterDefaults */ PointerGetDatum(NULL), /* trftypes */ PointerGetDatum(NULL), /* proconfig */ + InvalidOid, /* no prosupport */ 1, /* procost */ 0); /* prorows */ procOid = myself.objectId; @@ -636,12 +643,15 @@ AggregateCreate(const char *aggName, /* * Okay to create the pg_aggregate entry. */ + aggdesc = table_open(AggregateRelationId, RowExclusiveLock); + tupDesc = aggdesc->rd_att; /* initialize nulls and values */ for (i = 0; i < Natts_pg_aggregate; i++) { nulls[i] = false; values[i] = (Datum) NULL; + replaces[i] = true; } values[Anum_pg_aggregate_aggfnoid - 1] = ObjectIdGetDatum(procOid); values[Anum_pg_aggregate_aggkind - 1] = CharGetDatum(aggKind); @@ -672,19 +682,62 @@ AggregateCreate(const char *aggName, else nulls[Anum_pg_aggregate_aggminitval - 1] = true; - aggdesc = heap_open(AggregateRelationId, RowExclusiveLock); - tupDesc = aggdesc->rd_att; + if (replace) + oldtup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(procOid)); + else + oldtup = NULL; - tup = heap_form_tuple(tupDesc, values, nulls); - CatalogTupleInsert(aggdesc, tup); + if (HeapTupleIsValid(oldtup)) + { + Form_pg_aggregate oldagg = (Form_pg_aggregate) GETSTRUCT(oldtup); - heap_close(aggdesc, RowExclusiveLock); + /* + * If we're replacing an existing entry, we need to validate that + * we're not changing anything that would break callers. Specifically + * we must not change aggkind or aggnumdirectargs, which affect how an + * aggregate call is treated in parse analysis. + */ + if (aggKind != oldagg->aggkind) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot change routine kind"), + (oldagg->aggkind == AGGKIND_NORMAL ? + errdetail("\"%s\" is an ordinary aggregate function.", aggName) : + oldagg->aggkind == AGGKIND_ORDERED_SET ? + errdetail("\"%s\" is an ordered-set aggregate.", aggName) : + oldagg->aggkind == AGGKIND_HYPOTHETICAL ? + errdetail("\"%s\" is a hypothetical-set aggregate.", aggName) : + 0))); + if (numDirectArgs != oldagg->aggnumdirectargs) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("cannot change number of direct arguments of an aggregate function"))); + + replaces[Anum_pg_aggregate_aggfnoid - 1] = false; + replaces[Anum_pg_aggregate_aggkind - 1] = false; + replaces[Anum_pg_aggregate_aggnumdirectargs - 1] = false; + + tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces); + CatalogTupleUpdate(aggdesc, &tup->t_self, tup); + ReleaseSysCache(oldtup); + } + else + { + tup = heap_form_tuple(tupDesc, values, nulls); + CatalogTupleInsert(aggdesc, tup); + } + + table_close(aggdesc, RowExclusiveLock); /* * Create dependencies for the aggregate (above and beyond those already * made by ProcedureCreate). Note: we don't need an explicit dependency * on aggTransType since we depend on it indirectly through transfn. - * Likewise for aggmTransType using the mtransfunc, if it exists. + * Likewise for aggmTransType using the mtransfn, if it exists. + * + * If we're replacing an existing definition, ProcedureCreate deleted all + * our existing dependencies, so we have to do the same things here either + * way. */ /* Depends on transition function */ @@ -770,7 +823,11 @@ AggregateCreate(const char *aggName, /* * lookup_agg_function - * common code for finding transfn, invtransfn, finalfn, and combinefn + * common code for finding aggregate support functions + * + * fnName: possibly-schema-qualified function name + * nargs, input_types: expected function argument types + * variadicArgType: type of variadic argument if any, else InvalidOid * * Returns OID of function, and stores its return type into *rettype * diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c index ce7e5fb5cc1..dd99d53547f 100644 --- a/src/backend/catalog/pg_collation.c +++ b/src/backend/catalog/pg_collation.c @@ -3,7 +3,7 @@ * pg_collation.c * routines to support manipulation of the pg_collation relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,10 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -29,7 +30,6 @@ #include "utils/pg_locale.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -46,6 +46,7 @@ Oid CollationCreate(const char *collname, Oid collnamespace, Oid collowner, char collprovider, + bool collisdeterministic, int32 collencoding, const char *collcollate, const char *collctype, const char *collversion, @@ -106,7 +107,7 @@ CollationCreate(const char *collname, Oid collnamespace, } /* open pg_collation; see below about the lock level */ - rel = heap_open(CollationRelationId, ShareRowExclusiveLock); + rel = table_open(CollationRelationId, ShareRowExclusiveLock); /* * Also forbid a specific-encoding collation shadowing an any-encoding @@ -128,12 +129,12 @@ CollationCreate(const char *collname, Oid collnamespace, { if (quiet) { - heap_close(rel, NoLock); + table_close(rel, NoLock); return InvalidOid; } else if (if_not_exists) { - heap_close(rel, NoLock); + table_close(rel, NoLock); ereport(NOTICE, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("collation \"%s\" already exists, skipping", @@ -153,10 +154,14 @@ CollationCreate(const char *collname, Oid collnamespace, memset(nulls, 0, sizeof(nulls)); namestrcpy(&name_name, collname); + oid = GetNewOidWithIndex(rel, CollationOidIndexId, + Anum_pg_collation_oid); + values[Anum_pg_collation_oid - 1] = ObjectIdGetDatum(oid); values[Anum_pg_collation_collname - 1] = NameGetDatum(&name_name); values[Anum_pg_collation_collnamespace - 1] = ObjectIdGetDatum(collnamespace); values[Anum_pg_collation_collowner - 1] = ObjectIdGetDatum(collowner); values[Anum_pg_collation_collprovider - 1] = CharGetDatum(collprovider); + values[Anum_pg_collation_collisdeterministic - 1] = BoolGetDatum(collisdeterministic); values[Anum_pg_collation_collencoding - 1] = Int32GetDatum(collencoding); namestrcpy(&name_collate, collcollate); values[Anum_pg_collation_collcollate - 1] = NameGetDatum(&name_collate); @@ -170,7 +175,7 @@ CollationCreate(const char *collname, Oid collnamespace, tup = heap_form_tuple(tupDesc, values, nulls); /* insert a new tuple */ - oid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); Assert(OidIsValid(oid)); /* set up dependencies for the new collation */ @@ -185,8 +190,7 @@ CollationCreate(const char *collname, Oid collnamespace, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ - recordDependencyOnOwner(CollationRelationId, HeapTupleGetOid(tup), - collowner); + recordDependencyOnOwner(CollationRelationId, oid, collowner); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); @@ -195,7 +199,7 @@ CollationCreate(const char *collname, Oid collnamespace, InvokeObjectPostCreateHook(CollationRelationId, oid, 0); heap_freetuple(tup); - heap_close(rel, NoLock); + table_close(rel, NoLock); return oid; } @@ -214,10 +218,10 @@ RemoveCollationById(Oid collationOid) SysScanDesc scandesc; HeapTuple tuple; - rel = heap_open(CollationRelationId, RowExclusiveLock); + rel = table_open(CollationRelationId, RowExclusiveLock); ScanKeyInit(&scanKeyData, - ObjectIdAttributeNumber, + Anum_pg_collation_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(collationOid)); @@ -233,5 +237,5 @@ RemoveCollationById(Oid collationOid) systable_endscan(scandesc); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 8ba9890ca68..56568b0105f 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -3,7 +3,7 @@ * pg_constraint.c * routines to support manipulation of the pg_constraint relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,12 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" +#include "access/tupconvert.h" +#include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -32,7 +35,6 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -71,7 +73,6 @@ CreateConstraintEntry(const char *constraintName, const Oid *exclOp, Node *conExpr, const char *conBin, - const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, @@ -83,7 +84,6 @@ CreateConstraintEntry(const char *constraintName, bool nulls[Natts_pg_constraint]; Datum values[Natts_pg_constraint]; ArrayType *conkeyArray; - ArrayType *conincludingArray; ArrayType *confkeyArray; ArrayType *conpfeqopArray; ArrayType *conppeqopArray; @@ -93,7 +93,7 @@ CreateConstraintEntry(const char *constraintName, int i; ObjectAddress conobject; - conDesc = heap_open(ConstraintRelationId, RowExclusiveLock); + conDesc = table_open(ConstraintRelationId, RowExclusiveLock); Assert(constraintName); namestrcpy(&cname, constraintName); @@ -114,21 +114,6 @@ CreateConstraintEntry(const char *constraintName, else conkeyArray = NULL; - if (constraintNTotalKeys > constraintNKeys) - { - Datum *conincluding; - int j = 0; - int constraintNIncludedKeys = constraintNTotalKeys - constraintNKeys; - - conincluding = (Datum *) palloc(constraintNIncludedKeys * sizeof(Datum)); - for (i = constraintNKeys; i < constraintNTotalKeys; i++) - conincluding[j++] = Int16GetDatum(constraintKey[i]); - conincludingArray = construct_array(conincluding, constraintNIncludedKeys, - INT2OID, 2, true, 's'); - } - else - conincludingArray = NULL; - if (foreignNKeys > 0) { Datum *fkdatums; @@ -179,6 +164,9 @@ CreateConstraintEntry(const char *constraintName, values[i] = (Datum) NULL; } + conOid = GetNewOidWithIndex(conDesc, ConstraintOidIndexId, + Anum_pg_constraint_oid); + values[Anum_pg_constraint_oid - 1] = ObjectIdGetDatum(conOid); values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname); values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace); values[Anum_pg_constraint_contype - 1] = CharGetDatum(constraintType); @@ -202,11 +190,6 @@ CreateConstraintEntry(const char *constraintName, else nulls[Anum_pg_constraint_conkey - 1] = true; - if (conincludingArray) - values[Anum_pg_constraint_conincluding - 1] = PointerGetDatum(conincludingArray); - else - nulls[Anum_pg_constraint_conincluding - 1] = true; - if (confkeyArray) values[Anum_pg_constraint_confkey - 1] = PointerGetDatum(confkeyArray); else @@ -232,31 +215,20 @@ CreateConstraintEntry(const char *constraintName, else nulls[Anum_pg_constraint_conexclop - 1] = true; - /* - * initialize the binary form of the check constraint. - */ if (conBin) values[Anum_pg_constraint_conbin - 1] = CStringGetTextDatum(conBin); else nulls[Anum_pg_constraint_conbin - 1] = true; - /* - * initialize the text form of the check constraint - */ - if (conSrc) - values[Anum_pg_constraint_consrc - 1] = CStringGetTextDatum(conSrc); - else - nulls[Anum_pg_constraint_consrc - 1] = true; - tup = heap_form_tuple(RelationGetDescr(conDesc), values, nulls); - conOid = CatalogTupleInsert(conDesc, tup); + CatalogTupleInsert(conDesc, tup); conobject.classId = ConstraintRelationId; conobject.objectId = conOid; conobject.objectSubId = 0; - heap_close(conDesc, RowExclusiveLock); + table_close(conDesc, RowExclusiveLock); if (OidIsValid(relId)) { @@ -400,268 +372,71 @@ CreateConstraintEntry(const char *constraintName, } /* - * CloneForeignKeyConstraints - * Clone foreign keys from a partitioned table to a newly acquired - * partition. + * Test whether given name is currently used as a constraint name + * for the given object (relation or domain). * - * relationId is a partition of parentId, so we can be certain that it has the - * same columns with the same datatypes. The columns may be in different - * order, though. + * This is used to decide whether to accept a user-specified constraint name. + * It is deliberately not the same test as ChooseConstraintName uses to decide + * whether an auto-generated name is OK: here, we will allow it unless there + * is an identical constraint name in use *on the same object*. * - * The *cloned list is appended ClonedConstraint elements describing what was - * created. + * NB: Caller should hold exclusive lock on the given object, else + * this test can be fooled by concurrent additions. */ -void -CloneForeignKeyConstraints(Oid parentId, Oid relationId, List **cloned) +bool +ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, + const char *conname) { - Relation pg_constraint; - Relation parentRel; - Relation rel; - ScanKeyData key; - SysScanDesc scan; - TupleDesc tupdesc; - HeapTuple tuple; - AttrNumber *attmap; - - parentRel = heap_open(parentId, NoLock); /* already got lock */ - /* see ATAddForeignKeyConstraint about lock level */ - rel = heap_open(relationId, AccessExclusiveLock); - - pg_constraint = heap_open(ConstraintRelationId, RowShareLock); - tupdesc = RelationGetDescr(pg_constraint); - - /* - * The constraint key may differ, if the columns in the partition are - * different. This map is used to convert them. - */ - attmap = convert_tuples_by_name_map(RelationGetDescr(rel), - RelationGetDescr(parentRel), - gettext_noop("could not convert row type")); - - ScanKeyInit(&key, - Anum_pg_constraint_conrelid, BTEqualStrategyNumber, - F_OIDEQ, ObjectIdGetDatum(parentId)); - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, - NULL, 1, &key); - - while ((tuple = systable_getnext(scan)) != NULL) - { - Form_pg_constraint constrForm = (Form_pg_constraint) GETSTRUCT(tuple); - AttrNumber conkey[INDEX_MAX_KEYS]; - AttrNumber mapped_conkey[INDEX_MAX_KEYS]; - AttrNumber confkey[INDEX_MAX_KEYS]; - Oid conpfeqop[INDEX_MAX_KEYS]; - Oid conppeqop[INDEX_MAX_KEYS]; - Oid conffeqop[INDEX_MAX_KEYS]; - Constraint *fkconstraint; - ClonedConstraint *newc; - Oid constrOid; - ObjectAddress parentAddr, - childAddr; - int nelem; - int i; - ArrayType *arr; - Datum datum; - bool isnull; - - /* only foreign keys */ - if (constrForm->contype != CONSTRAINT_FOREIGN) - continue; - - ObjectAddressSet(parentAddr, ConstraintRelationId, - HeapTupleGetOid(tuple)); - - datum = fastgetattr(tuple, Anum_pg_constraint_conkey, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null conkey"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "conkey is not a 1-D smallint array"); - memcpy(conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber)); + bool found; + Relation conDesc; + SysScanDesc conscan; + ScanKeyData skey[3]; - for (i = 0; i < nelem; i++) - mapped_conkey[i] = attmap[conkey[i] - 1]; + conDesc = table_open(ConstraintRelationId, AccessShareLock); - datum = fastgetattr(tuple, Anum_pg_constraint_confkey, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null confkey"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "confkey is not a 1-D smallint array"); - memcpy(confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber)); - - datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null conpfeqop"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conpfeqop is not a 1-D OID array"); - memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid)); - - datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null conpfeqop"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conpfeqop is not a 1-D OID array"); - memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid)); - - datum = fastgetattr(tuple, Anum_pg_constraint_conppeqop, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null conppeqop"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conppeqop is not a 1-D OID array"); - memcpy(conppeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid)); - - datum = fastgetattr(tuple, Anum_pg_constraint_conffeqop, - tupdesc, &isnull); - if (isnull) - elog(ERROR, "null conffeqop"); - arr = DatumGetArrayTypeP(datum); - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conffeqop is not a 1-D OID array"); - memcpy(conffeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid)); - - constrOid = - CreateConstraintEntry(NameStr(constrForm->conname), - constrForm->connamespace, - CONSTRAINT_FOREIGN, - constrForm->condeferrable, - constrForm->condeferred, - constrForm->convalidated, - HeapTupleGetOid(tuple), - relationId, - mapped_conkey, - nelem, - nelem, - InvalidOid, /* not a domain constraint */ - constrForm->conindid, /* same index */ - constrForm->confrelid, /* same foreign rel */ - confkey, - conpfeqop, - conppeqop, - conffeqop, - nelem, - constrForm->confupdtype, - constrForm->confdeltype, - constrForm->confmatchtype, - NULL, - NULL, - NULL, - NULL, - false, - 1, false, true); - - ObjectAddressSet(childAddr, ConstraintRelationId, constrOid); - recordDependencyOn(&childAddr, &parentAddr, DEPENDENCY_INTERNAL_AUTO); - - fkconstraint = makeNode(Constraint); - /* for now this is all we need */ - fkconstraint->fk_upd_action = constrForm->confupdtype; - fkconstraint->fk_del_action = constrForm->confdeltype; - fkconstraint->deferrable = constrForm->condeferrable; - fkconstraint->initdeferred = constrForm->condeferred; - - createForeignKeyTriggers(rel, constrForm->confrelid, fkconstraint, - constrOid, constrForm->conindid, false); - - if (cloned) - { - /* - * Feed back caller about the constraints we created, so that they can - * set up constraint verification. - */ - newc = palloc(sizeof(ClonedConstraint)); - newc->relid = relationId; - newc->refrelid = constrForm->confrelid; - newc->conindid = constrForm->conindid; - newc->conid = constrOid; - newc->constraint = fkconstraint; - - *cloned = lappend(*cloned, newc); - } - } - systable_endscan(scan); + ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum((conCat == CONSTRAINT_RELATION) + ? objId : InvalidOid)); + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum((conCat == CONSTRAINT_DOMAIN) + ? objId : InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(conname)); - pfree(attmap); + conscan = systable_beginscan(conDesc, ConstraintRelidTypidNameIndexId, + true, NULL, 3, skey); - if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - { - PartitionDesc partdesc = RelationGetPartitionDesc(rel); - int i; + /* There can be at most one matching row */ + found = (HeapTupleIsValid(systable_getnext(conscan))); - for (i = 0; i < partdesc->nparts; i++) - CloneForeignKeyConstraints(RelationGetRelid(rel), - partdesc->oids[i], - cloned); - } + systable_endscan(conscan); + table_close(conDesc, AccessShareLock); - heap_close(rel, NoLock); /* keep lock till commit */ - heap_close(parentRel, NoLock); - heap_close(pg_constraint, RowShareLock); + return found; } /* - * Test whether given name is currently used as a constraint name - * for the given object (relation or domain). + * Does any constraint of the given name exist in the given namespace? * - * This is used to decide whether to accept a user-specified constraint name. - * It is deliberately not the same test as ChooseConstraintName uses to decide - * whether an auto-generated name is OK: here, we will allow it unless there - * is an identical constraint name in use *on the same object*. - * - * NB: Caller should hold exclusive lock on the given object, else - * this test can be fooled by concurrent additions. + * This is used for code that wants to match ChooseConstraintName's rule + * that we should avoid autogenerating duplicate constraint names within a + * namespace. */ bool -ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, - Oid objNamespace, const char *conname) +ConstraintNameExists(const char *conname, Oid namespaceid) { bool found; Relation conDesc; SysScanDesc conscan; ScanKeyData skey[2]; - HeapTuple tup; - conDesc = heap_open(ConstraintRelationId, AccessShareLock); - - found = false; + conDesc = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_constraint_conname, @@ -671,29 +446,15 @@ ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, ScanKeyInit(&skey[1], Anum_pg_constraint_connamespace, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(objNamespace)); + ObjectIdGetDatum(namespaceid)); conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true, NULL, 2, skey); - while (HeapTupleIsValid(tup = systable_getnext(conscan))) - { - Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup); - - if (conCat == CONSTRAINT_RELATION && con->conrelid == objId) - { - found = true; - break; - } - else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId) - { - found = true; - break; - } - } + found = (HeapTupleIsValid(systable_getnext(conscan))); systable_endscan(conscan); - heap_close(conDesc, AccessShareLock); + table_close(conDesc, AccessShareLock); return found; } @@ -735,7 +496,7 @@ ChooseConstraintName(const char *name1, const char *name2, bool found; ListCell *l; - conDesc = heap_open(ConstraintRelationId, AccessShareLock); + conDesc = table_open(ConstraintRelationId, AccessShareLock); /* try the unmodified label first */ StrNCpy(modlabel, label, sizeof(modlabel)); @@ -783,7 +544,7 @@ ChooseConstraintName(const char *name1, const char *name2, snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass); } - heap_close(conDesc, AccessShareLock); + table_close(conDesc, AccessShareLock); return conname; } @@ -798,7 +559,7 @@ RemoveConstraintById(Oid conId) HeapTuple tup; Form_pg_constraint con; - conDesc = heap_open(ConstraintRelationId, RowExclusiveLock); + conDesc = table_open(ConstraintRelationId, RowExclusiveLock); tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conId)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -816,10 +577,10 @@ RemoveConstraintById(Oid conId) * If the constraint is for a relation, open and exclusive-lock the * relation it's for. */ - rel = heap_open(con->conrelid, AccessExclusiveLock); + rel = table_open(con->conrelid, AccessExclusiveLock); /* - * We need to update the relcheck count if it is a check constraint + * We need to update the relchecks count if it is a check constraint * being dropped. This update will force backends to rebuild relcache * entries when we commit. */ @@ -829,7 +590,7 @@ RemoveConstraintById(Oid conId) HeapTuple relTup; Form_pg_class classForm; - pgrel = heap_open(RelationRelationId, RowExclusiveLock); + pgrel = table_open(RelationRelationId, RowExclusiveLock); relTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(con->conrelid)); if (!HeapTupleIsValid(relTup)) @@ -846,11 +607,11 @@ RemoveConstraintById(Oid conId) heap_freetuple(relTup); - heap_close(pgrel, RowExclusiveLock); + table_close(pgrel, RowExclusiveLock); } /* Keep lock on constraint's rel until end of xact */ - heap_close(rel, NoLock); + table_close(rel, NoLock); } else if (OidIsValid(con->contypid)) { @@ -869,7 +630,7 @@ RemoveConstraintById(Oid conId) /* Clean up */ ReleaseSysCache(tup); - heap_close(conDesc, RowExclusiveLock); + table_close(conDesc, RowExclusiveLock); } /* @@ -889,7 +650,7 @@ RenameConstraintById(Oid conId, const char *newname) HeapTuple tuple; Form_pg_constraint con; - conDesc = heap_open(ConstraintRelationId, RowExclusiveLock); + conDesc = table_open(ConstraintRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(CONSTROID, ObjectIdGetDatum(conId)); if (!HeapTupleIsValid(tuple)) @@ -897,13 +658,11 @@ RenameConstraintById(Oid conId, const char *newname) con = (Form_pg_constraint) GETSTRUCT(tuple); /* - * We need to check whether the name is already in use --- note that there - * currently is not a unique index that would catch this. + * For user-friendliness, check whether the name is already in use. */ if (OidIsValid(con->conrelid) && ConstraintNameIsUsed(CONSTRAINT_RELATION, con->conrelid, - con->connamespace, newname)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), @@ -912,7 +671,6 @@ RenameConstraintById(Oid conId, const char *newname) if (OidIsValid(con->contypid) && ConstraintNameIsUsed(CONSTRAINT_DOMAIN, con->contypid, - con->connamespace, newname)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), @@ -927,7 +685,7 @@ RenameConstraintById(Oid conId, const char *newname) InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0); heap_freetuple(tuple); - heap_close(conDesc, RowExclusiveLock); + table_close(conDesc, RowExclusiveLock); } /* @@ -942,32 +700,23 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved) { Relation conRel; - ScanKeyData key[1]; + ScanKeyData key[2]; SysScanDesc scan; HeapTuple tup; - conRel = heap_open(ConstraintRelationId, RowExclusiveLock); - - if (isType) - { - ScanKeyInit(&key[0], - Anum_pg_constraint_contypid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(ownerId)); + conRel = table_open(ConstraintRelationId, RowExclusiveLock); - scan = systable_beginscan(conRel, ConstraintTypidIndexId, true, - NULL, 1, key); - } - else - { - ScanKeyInit(&key[0], - Anum_pg_constraint_conrelid, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(ownerId)); + ScanKeyInit(&key[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(isType ? InvalidOid : ownerId)); + ScanKeyInit(&key[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(isType ? ownerId : InvalidOid)); - scan = systable_beginscan(conRel, ConstraintRelidIndexId, true, - NULL, 1, key); - } + scan = systable_beginscan(conRel, ConstraintRelidTypidNameIndexId, true, + NULL, 2, key); while (HeapTupleIsValid((tup = systable_getnext(scan)))) { @@ -975,7 +724,7 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, ObjectAddress thisobj; thisobj.classId = ConstraintRelationId; - thisobj.objectId = HeapTupleGetOid(tup); + thisobj.objectId = conform->oid; thisobj.objectSubId = 0; if (object_address_present(&thisobj, objsMoved)) @@ -1005,44 +754,79 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, systable_endscan(scan); - heap_close(conRel, RowExclusiveLock); + table_close(conRel, RowExclusiveLock); } /* * ConstraintSetParentConstraint - * Set a partition's constraint as child of its parent table's + * Set a partition's constraint as child of its parent constraint, + * or remove the linkage if parentConstrId is InvalidOid. * * This updates the constraint's pg_constraint row to show it as inherited, and - * add a dependency to the parent so that it cannot be removed on its own. + * adds PARTITION dependencies to prevent the constraint from being deleted + * on its own. Alternatively, reverse that. */ void -ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId) +ConstraintSetParentConstraint(Oid childConstrId, + Oid parentConstrId, + Oid childTableId) { - Relation constrRel; + Relation constrRel; Form_pg_constraint constrForm; - HeapTuple tuple, - newtup; - ObjectAddress depender; - ObjectAddress referenced; + HeapTuple tuple, + newtup; + ObjectAddress depender; + ObjectAddress referenced; - constrRel = heap_open(ConstraintRelationId, RowExclusiveLock); + constrRel = table_open(ConstraintRelationId, RowExclusiveLock); tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(childConstrId)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for constraint %u", childConstrId); newtup = heap_copytuple(tuple); constrForm = (Form_pg_constraint) GETSTRUCT(newtup); - constrForm->conislocal = false; - constrForm->coninhcount++; - constrForm->conparentid = parentConstrId; - CatalogTupleUpdate(constrRel, &tuple->t_self, newtup); - ReleaseSysCache(tuple); + if (OidIsValid(parentConstrId)) + { + /* don't allow setting parent for a constraint that already has one */ + Assert(constrForm->coninhcount == 0); + if (constrForm->conparentid != InvalidOid) + elog(ERROR, "constraint %u already has a parent constraint", + childConstrId); + + constrForm->conislocal = false; + constrForm->coninhcount++; + constrForm->conparentid = parentConstrId; - ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId); - ObjectAddressSet(depender, ConstraintRelationId, childConstrId); + CatalogTupleUpdate(constrRel, &tuple->t_self, newtup); - recordDependencyOn(&depender, &referenced, DEPENDENCY_INTERNAL_AUTO); + ObjectAddressSet(depender, ConstraintRelationId, childConstrId); - heap_close(constrRel, RowExclusiveLock); + ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId); + recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI); + + ObjectAddressSet(referenced, RelationRelationId, childTableId); + recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC); + } + else + { + constrForm->coninhcount--; + constrForm->conislocal = true; + constrForm->conparentid = InvalidOid; + + /* Make sure there's no further inheritance. */ + Assert(constrForm->coninhcount == 0); + + CatalogTupleUpdate(constrRel, &tuple->t_self, newtup); + + deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId, + ConstraintRelationId, + DEPENDENCY_PARTITION_PRI); + deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId, + RelationRelationId, + DEPENDENCY_PARTITION_SEC); + } + + ReleaseSysCache(tuple); + table_close(constrRel, RowExclusiveLock); } @@ -1057,38 +841,30 @@ get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok) Relation pg_constraint; HeapTuple tuple; SysScanDesc scan; - ScanKeyData skey[1]; + ScanKeyData skey[3]; Oid conOid = InvalidOid; - /* - * Fetch the constraint tuple from pg_constraint. There may be more than - * one match, because constraints are not required to have unique names; - * if so, error out. - */ - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(conname)); - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, - NULL, 1, skey); + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); - - if (strcmp(NameStr(con->conname), conname) == 0) - { - if (OidIsValid(conOid)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("table \"%s\" has multiple constraints named \"%s\"", - get_rel_name(relid), conname))); - conOid = HeapTupleGetOid(tuple); - } - } + /* There can be at most one matching row */ + if (HeapTupleIsValid(tuple = systable_getnext(scan))) + conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid; systable_endscan(scan); @@ -1099,7 +875,7 @@ get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok) errmsg("constraint \"%s\" for table \"%s\" does not exist", conname, get_rel_name(relid)))); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return conOid; } @@ -1124,67 +900,62 @@ get_relation_constraint_attnos(Oid relid, const char *conname, Relation pg_constraint; HeapTuple tuple; SysScanDesc scan; - ScanKeyData skey[1]; + ScanKeyData skey[3]; /* Set *constraintOid, to avoid complaints about uninitialized vars */ *constraintOid = InvalidOid; - /* - * Fetch the constraint tuple from pg_constraint. There may be more than - * one match, because constraints are not required to have unique names; - * if so, error out. - */ - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(conname)); - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, - NULL, 1, skey); + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - while (HeapTupleIsValid(tuple = systable_getnext(scan))) + /* There can be at most one matching row */ + if (HeapTupleIsValid(tuple = systable_getnext(scan))) { - Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); Datum adatum; bool isNull; - ArrayType *arr; - int16 *attnums; - int numcols; - int i; - /* Check the constraint name */ - if (strcmp(NameStr(con->conname), conname) != 0) - continue; - if (OidIsValid(*constraintOid)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("table \"%s\" has multiple constraints named \"%s\"", - get_rel_name(relid), conname))); - - *constraintOid = HeapTupleGetOid(tuple); + *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid; /* Extract the conkey array, ie, attnums of constrained columns */ adatum = heap_getattr(tuple, Anum_pg_constraint_conkey, RelationGetDescr(pg_constraint), &isNull); - if (isNull) - continue; /* no constrained columns */ - - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - numcols = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - numcols < 0 || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "conkey is not a 1-D smallint array"); - attnums = (int16 *) ARR_DATA_PTR(arr); - - /* Construct the result value */ - for (i = 0; i < numcols; i++) + if (!isNull) { - conattnos = bms_add_member(conattnos, - attnums[i] - FirstLowInvalidHeapAttributeNumber); + ArrayType *arr; + int numcols; + int16 *attnums; + int i; + + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + numcols = ARR_DIMS(arr)[0]; + if (ARR_NDIM(arr) != 1 || + numcols < 0 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != INT2OID) + elog(ERROR, "conkey is not a 1-D smallint array"); + attnums = (int16 *) ARR_DATA_PTR(arr); + + /* Construct the result value */ + for (i = 0; i < numcols; i++) + { + conattnos = bms_add_member(conattnos, + attnums[i] - FirstLowInvalidHeapAttributeNumber); + } } } @@ -1197,7 +968,7 @@ get_relation_constraint_attnos(Oid relid, const char *conname, errmsg("constraint \"%s\" for table \"%s\" does not exist", conname, get_rel_name(relid)))); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return conattnos; } @@ -1210,34 +981,34 @@ Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId) { Relation pg_constraint; - SysScanDesc scan; - ScanKeyData key; + SysScanDesc scan; + ScanKeyData key; HeapTuple tuple; Oid constraintId = InvalidOid; - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&key, Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relationId)); - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true, NULL, 1, &key); while ((tuple = systable_getnext(scan)) != NULL) { - Form_pg_constraint constrForm; + Form_pg_constraint constrForm; constrForm = (Form_pg_constraint) GETSTRUCT(tuple); if (constrForm->conindid == indexId) { - constraintId = HeapTupleGetOid(tuple); + constraintId = constrForm->oid; break; } } systable_endscan(scan); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return constraintId; } @@ -1252,38 +1023,30 @@ get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok) Relation pg_constraint; HeapTuple tuple; SysScanDesc scan; - ScanKeyData skey[1]; + ScanKeyData skey[3]; Oid conOid = InvalidOid; - /* - * Fetch the constraint tuple from pg_constraint. There may be more than - * one match, because constraints are not required to have unique names; - * if so, error out. - */ - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[1], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(conname)); - scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true, - NULL, 1, skey); - - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - if (strcmp(NameStr(con->conname), conname) == 0) - { - if (OidIsValid(conOid)) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("domain %s has multiple constraints named \"%s\"", - format_type_be(typid), conname))); - conOid = HeapTupleGetOid(tuple); - } - } + /* There can be at most one matching row */ + if (HeapTupleIsValid(tuple = systable_getnext(scan))) + conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid; systable_endscan(scan); @@ -1294,7 +1057,7 @@ get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok) errmsg("constraint \"%s\" for domain %s does not exist", conname, format_type_be(typid)))); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return conOid; } @@ -1326,14 +1089,14 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid) *constraintOid = InvalidOid; /* Scan pg_constraint for constraints of the target rel */ - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relid)); - scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true, + scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true, NULL, 1, skey); while (HeapTupleIsValid(tuple = systable_getnext(scan))) @@ -1363,7 +1126,7 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid) RelationGetDescr(pg_constraint), &isNull); if (isNull) elog(ERROR, "null conkey for constraint %u", - HeapTupleGetOid(tuple)); + ((Form_pg_constraint) GETSTRUCT(tuple))->oid); arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ numkeys = ARR_DIMS(arr)[0]; if (ARR_NDIM(arr) != 1 || @@ -1379,7 +1142,7 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid) pkattnos = bms_add_member(pkattnos, attnums[i] - FirstLowInvalidHeapAttributeNumber); } - *constraintOid = HeapTupleGetOid(tuple); + *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid; /* No need to search further */ break; @@ -1387,11 +1150,120 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid) systable_endscan(scan); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return pkattnos; } +/* + * Extract data from the pg_constraint tuple of a foreign-key constraint. + * + * All arguments save the first are output arguments; the last three of them + * can be passed as NULL if caller doesn't need them. + */ +void +DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, + AttrNumber *conkey, AttrNumber *confkey, + Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs) +{ + Oid constrId; + Datum adatum; + bool isNull; + ArrayType *arr; + int numkeys; + + constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid; + + /* + * We expect the arrays to be 1-D arrays of the right types; verify that. + * We don't need to use deconstruct_array() since the array data is just + * going to look like a C array of values. + */ + adatum = SysCacheGetAttr(CONSTROID, tuple, + Anum_pg_constraint_conkey, &isNull); + if (isNull) + elog(ERROR, "null conkey for constraint %u", constrId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + if (ARR_NDIM(arr) != 1 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != INT2OID) + elog(ERROR, "conkey is not a 1-D smallint array"); + numkeys = ARR_DIMS(arr)[0]; + if (numkeys <= 0 || numkeys > INDEX_MAX_KEYS) + elog(ERROR, "foreign key constraint cannot have %d columns", numkeys); + memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16)); + if ((Pointer) arr != DatumGetPointer(adatum)) + pfree(arr); /* free de-toasted copy, if any */ + + adatum = SysCacheGetAttr(CONSTROID, tuple, + Anum_pg_constraint_confkey, &isNull); + if (isNull) + elog(ERROR, "null confkey for constraint %u", constrId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + if (ARR_NDIM(arr) != 1 || + ARR_DIMS(arr)[0] != numkeys || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != INT2OID) + elog(ERROR, "confkey is not a 1-D smallint array"); + memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16)); + if ((Pointer) arr != DatumGetPointer(adatum)) + pfree(arr); /* free de-toasted copy, if any */ + + if (pf_eq_oprs) + { + adatum = SysCacheGetAttr(CONSTROID, tuple, + Anum_pg_constraint_conpfeqop, &isNull); + if (isNull) + elog(ERROR, "null conpfeqop for constraint %u", constrId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + /* see TryReuseForeignKey if you change the test below */ + if (ARR_NDIM(arr) != 1 || + ARR_DIMS(arr)[0] != numkeys || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "conpfeqop is not a 1-D Oid array"); + memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); + if ((Pointer) arr != DatumGetPointer(adatum)) + pfree(arr); /* free de-toasted copy, if any */ + } + + if (pp_eq_oprs) + { + adatum = SysCacheGetAttr(CONSTROID, tuple, + Anum_pg_constraint_conppeqop, &isNull); + if (isNull) + elog(ERROR, "null conppeqop for constraint %u", constrId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + if (ARR_NDIM(arr) != 1 || + ARR_DIMS(arr)[0] != numkeys || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "conppeqop is not a 1-D Oid array"); + memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); + if ((Pointer) arr != DatumGetPointer(adatum)) + pfree(arr); /* free de-toasted copy, if any */ + } + + if (ff_eq_oprs) + { + adatum = SysCacheGetAttr(CONSTROID, tuple, + Anum_pg_constraint_conffeqop, &isNull); + if (isNull) + elog(ERROR, "null conffeqop for constraint %u", constrId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + if (ARR_NDIM(arr) != 1 || + ARR_DIMS(arr)[0] != numkeys || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "conffeqop is not a 1-D Oid array"); + memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); + if ((Pointer) arr != DatumGetPointer(adatum)) + pfree(arr); /* free de-toasted copy, if any */ + } + + *numfks = numkeys; +} + /* * Determine whether a relation can be proven functionally dependent on * a set of grouping columns. If so, return true and add the pg_constraint diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c index fd5c18426bf..04c207662ac 100644 --- a/src/backend/catalog/pg_conversion.c +++ b/src/backend/catalog/pg_conversion.c @@ -3,7 +3,7 @@ * pg_conversion.c * routines to support manipulation of the pg_conversion relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,8 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -29,7 +31,6 @@ #include "utils/fmgroids.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* * ConversionCreate @@ -46,6 +47,7 @@ ConversionCreate(const char *conname, Oid connamespace, Relation rel; TupleDesc tupDesc; HeapTuple tup; + Oid oid; bool nulls[Natts_pg_conversion]; Datum values[Natts_pg_conversion]; NameData cname; @@ -81,7 +83,7 @@ ConversionCreate(const char *conname, Oid connamespace, } /* open pg_conversion */ - rel = heap_open(ConversionRelationId, RowExclusiveLock); + rel = table_open(ConversionRelationId, RowExclusiveLock); tupDesc = rel->rd_att; /* initialize nulls and values */ @@ -93,6 +95,9 @@ ConversionCreate(const char *conname, Oid connamespace, /* form a tuple */ namestrcpy(&cname, conname); + oid = GetNewOidWithIndex(rel, ConversionOidIndexId, + Anum_pg_conversion_oid); + values[Anum_pg_conversion_oid - 1] = ObjectIdGetDatum(oid); values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname); values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace); values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner); @@ -107,7 +112,7 @@ ConversionCreate(const char *conname, Oid connamespace, CatalogTupleInsert(rel, tup); myself.classId = ConversionRelationId; - myself.objectId = HeapTupleGetOid(tup); + myself.objectId = oid; myself.objectSubId = 0; /* create dependency on conversion procedure */ @@ -123,17 +128,16 @@ ConversionCreate(const char *conname, Oid connamespace, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); /* create dependency on owner */ - recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup), - conowner); + recordDependencyOnOwner(ConversionRelationId, oid, conowner); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, false); /* Post creation hook for new conversion */ - InvokeObjectPostCreateHook(ConversionRelationId, HeapTupleGetOid(tup), 0); + InvokeObjectPostCreateHook(ConversionRelationId, oid, 0); heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -149,26 +153,26 @@ RemoveConversionById(Oid conversionOid) { Relation rel; HeapTuple tuple; - HeapScanDesc scan; + TableScanDesc scan; ScanKeyData scanKeyData; ScanKeyInit(&scanKeyData, - ObjectIdAttributeNumber, + Anum_pg_conversion_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(conversionOid)); /* open pg_conversion */ - rel = heap_open(ConversionRelationId, RowExclusiveLock); + rel = table_open(ConversionRelationId, RowExclusiveLock); - scan = heap_beginscan_catalog(rel, 1, &scanKeyData); + scan = table_beginscan_catalog(rel, 1, &scanKeyData); /* search for the target tuple */ if (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) CatalogTupleDelete(rel, &tuple->t_self); else elog(ERROR, "could not find tuple for conversion %u", conversionOid); - heap_endscan(scan); - heap_close(rel, RowExclusiveLock); + table_endscan(scan); + table_close(rel, RowExclusiveLock); } /* diff --git a/src/backend/catalog/pg_db_role_setting.c b/src/backend/catalog/pg_db_role_setting.c index e123691923c..20acac2eea9 100644 --- a/src/backend/catalog/pg_db_role_setting.c +++ b/src/backend/catalog/pg_db_role_setting.c @@ -2,7 +2,7 @@ * pg_db_role_setting.c * Routines to support manipulation of the pg_db_role_setting relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,12 +13,12 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" #include "catalog/pg_db_role_setting.h" #include "utils/fmgroids.h" #include "utils/rel.h" -#include "utils/tqual.h" void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt) @@ -33,7 +33,7 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt) /* Get the old tuple, if any. */ - rel = heap_open(DbRoleSettingRelationId, RowExclusiveLock); + rel = table_open(DbRoleSettingRelationId, RowExclusiveLock); ScanKeyInit(&scankey[0], Anum_pg_db_role_setting_setdatabase, BTEqualStrategyNumber, F_OIDEQ, @@ -158,7 +158,7 @@ AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt) systable_endscan(scan); /* Close pg_db_role_setting, but keep lock till commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* @@ -170,12 +170,12 @@ void DropSetting(Oid databaseid, Oid roleid) { Relation relsetting; - HeapScanDesc scan; + TableScanDesc scan; ScanKeyData keys[2]; HeapTuple tup; int numkeys = 0; - relsetting = heap_open(DbRoleSettingRelationId, RowExclusiveLock); + relsetting = table_open(DbRoleSettingRelationId, RowExclusiveLock); if (OidIsValid(databaseid)) { @@ -196,14 +196,14 @@ DropSetting(Oid databaseid, Oid roleid) numkeys++; } - scan = heap_beginscan_catalog(relsetting, numkeys, keys); + scan = table_beginscan_catalog(relsetting, numkeys, keys); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { CatalogTupleDelete(relsetting, &tup->t_self); } - heap_endscan(scan); + table_endscan(scan); - heap_close(relsetting, RowExclusiveLock); + table_close(relsetting, RowExclusiveLock); } /* diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index 2ea05f350b3..a060c25d2ee 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -3,7 +3,7 @@ * pg_depend.c * routines to support manipulation of the pg_depend relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_constraint.h" @@ -27,7 +27,6 @@ #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/rel.h" -#include "utils/tqual.h" static bool isObjectPinned(const ObjectAddress *object, Relation rel); @@ -75,7 +74,7 @@ recordMultipleDependencies(const ObjectAddress *depender, if (IsBootstrapProcessingMode()) return; - dependDesc = heap_open(DependRelationId, RowExclusiveLock); + dependDesc = table_open(DependRelationId, RowExclusiveLock); /* Don't open indexes unless we need to make an update */ indstate = NULL; @@ -120,7 +119,7 @@ recordMultipleDependencies(const ObjectAddress *depender, if (indstate != NULL) CatalogCloseIndexes(indstate); - heap_close(dependDesc, RowExclusiveLock); + table_close(dependDesc, RowExclusiveLock); } /* @@ -197,7 +196,7 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId, SysScanDesc scan; HeapTuple tup; - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -223,7 +222,7 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId, systable_endscan(scan); - heap_close(depRel, RowExclusiveLock); + table_close(depRel, RowExclusiveLock); return count; } @@ -247,7 +246,7 @@ deleteDependencyRecordsForClass(Oid classId, Oid objectId, SysScanDesc scan; HeapTuple tup; - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -274,7 +273,7 @@ deleteDependencyRecordsForClass(Oid classId, Oid objectId, systable_endscan(scan); - heap_close(depRel, RowExclusiveLock); + table_close(depRel, RowExclusiveLock); return count; } @@ -287,9 +286,12 @@ deleteDependencyRecordsForClass(Oid classId, Oid objectId, * newRefObjectId is the new referenced object (must be of class refClassId). * * Note the lack of objsubid parameters. If there are subobject references - * they will all be readjusted. + * they will all be readjusted. Also, there is an expectation that we are + * dealing with NORMAL dependencies: if we have to replace an (implicit) + * dependency on a pinned object with an explicit dependency on an unpinned + * one, the new one will be NORMAL. * - * Returns the number of records updated. + * Returns the number of records updated -- zero indicates a problem. */ long changeDependencyFor(Oid classId, Oid objectId, @@ -302,35 +304,52 @@ changeDependencyFor(Oid classId, Oid objectId, SysScanDesc scan; HeapTuple tup; ObjectAddress objAddr; + ObjectAddress depAddr; + bool oldIsPinned; bool newIsPinned; - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); /* - * If oldRefObjectId is pinned, there won't be any dependency entries on - * it --- we can't cope in that case. (This isn't really worth expending - * code to fix, in current usage; it just means you can't rename stuff out - * of pg_catalog, which would likely be a bad move anyway.) + * Check to see if either oldRefObjectId or newRefObjectId is pinned. + * Pinned objects should not have any dependency entries pointing to them, + * so in these cases we should add or remove a pg_depend entry, or do + * nothing at all, rather than update an entry as in the normal case. */ objAddr.classId = refClassId; objAddr.objectId = oldRefObjectId; objAddr.objectSubId = 0; - if (isObjectPinned(&objAddr, depRel)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot remove dependency on %s because it is a system object", - getObjectDescription(&objAddr)))); + oldIsPinned = isObjectPinned(&objAddr, depRel); - /* - * We can handle adding a dependency on something pinned, though, since - * that just means deleting the dependency entry. - */ objAddr.objectId = newRefObjectId; newIsPinned = isObjectPinned(&objAddr, depRel); - /* Now search for dependency records */ + if (oldIsPinned) + { + table_close(depRel, RowExclusiveLock); + + /* + * If both are pinned, we need do nothing. However, return 1 not 0, + * else callers will think this is an error case. + */ + if (newIsPinned) + return 1; + + /* + * There is no old dependency record, but we should insert a new one. + * Assume a normal dependency is wanted. + */ + depAddr.classId = classId; + depAddr.objectId = objectId; + depAddr.objectSubId = 0; + recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL); + + return 1; + } + + /* There should be existing dependency record(s), so search. */ ScanKeyInit(&key[0], Anum_pg_depend_classid, BTEqualStrategyNumber, F_OIDEQ, @@ -371,7 +390,151 @@ changeDependencyFor(Oid classId, Oid objectId, systable_endscan(scan); - heap_close(depRel, RowExclusiveLock); + table_close(depRel, RowExclusiveLock); + + return count; +} + +/* + * Adjust all dependency records to come from a different object of the same type + * + * classId/oldObjectId specify the old referencing object. + * newObjectId is the new referencing object (must be of class classId). + * + * Returns the number of records updated. + */ +long +changeDependenciesOf(Oid classId, Oid oldObjectId, + Oid newObjectId) +{ + long count = 0; + Relation depRel; + ScanKeyData key[2]; + SysScanDesc scan; + HeapTuple tup; + + depRel = table_open(DependRelationId, RowExclusiveLock); + + ScanKeyInit(&key[0], + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classId)); + ScanKeyInit(&key[1], + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oldObjectId)); + + scan = systable_beginscan(depRel, DependDependerIndexId, true, + NULL, 2, key); + + while (HeapTupleIsValid((tup = systable_getnext(scan)))) + { + Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); + + /* make a modifiable copy */ + tup = heap_copytuple(tup); + depform = (Form_pg_depend) GETSTRUCT(tup); + + depform->objid = newObjectId; + + CatalogTupleUpdate(depRel, &tup->t_self, tup); + + heap_freetuple(tup); + + count++; + } + + systable_endscan(scan); + + table_close(depRel, RowExclusiveLock); + + return count; +} + +/* + * Adjust all dependency records to point to a different object of the same type + * + * refClassId/oldRefObjectId specify the old referenced object. + * newRefObjectId is the new referenced object (must be of class refClassId). + * + * Returns the number of records updated. + */ +long +changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, + Oid newRefObjectId) +{ + long count = 0; + Relation depRel; + ScanKeyData key[2]; + SysScanDesc scan; + HeapTuple tup; + ObjectAddress objAddr; + bool newIsPinned; + + depRel = table_open(DependRelationId, RowExclusiveLock); + + /* + * If oldRefObjectId is pinned, there won't be any dependency entries on + * it --- we can't cope in that case. (This isn't really worth expending + * code to fix, in current usage; it just means you can't rename stuff out + * of pg_catalog, which would likely be a bad move anyway.) + */ + objAddr.classId = refClassId; + objAddr.objectId = oldRefObjectId; + objAddr.objectSubId = 0; + + if (isObjectPinned(&objAddr, depRel)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot remove dependency on %s because it is a system object", + getObjectDescription(&objAddr)))); + + /* + * We can handle adding a dependency on something pinned, though, since + * that just means deleting the dependency entry. + */ + objAddr.objectId = newRefObjectId; + + newIsPinned = isObjectPinned(&objAddr, depRel); + + /* Now search for dependency records */ + ScanKeyInit(&key[0], + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(refClassId)); + ScanKeyInit(&key[1], + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(oldRefObjectId)); + + scan = systable_beginscan(depRel, DependReferenceIndexId, true, + NULL, 2, key); + + while (HeapTupleIsValid((tup = systable_getnext(scan)))) + { + Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); + + if (newIsPinned) + CatalogTupleDelete(depRel, &tup->t_self); + else + { + /* make a modifiable copy */ + tup = heap_copytuple(tup); + depform = (Form_pg_depend) GETSTRUCT(tup); + + depform->refobjid = newRefObjectId; + + CatalogTupleUpdate(depRel, &tup->t_self, tup); + + heap_freetuple(tup); + } + + count++; + } + + systable_endscan(scan); + + table_close(depRel, RowExclusiveLock); return count; } @@ -452,7 +615,7 @@ getExtensionOfObject(Oid classId, Oid objectId) SysScanDesc scan; HeapTuple tup; - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -480,7 +643,7 @@ getExtensionOfObject(Oid classId, Oid objectId) systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); return result; } @@ -505,7 +668,7 @@ sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId) SysScanDesc scan; HeapTuple tup; - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -535,17 +698,18 @@ sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId) systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); return ret; } /* * Collect a list of OIDs of all sequences owned by the specified relation, - * and column if specified. + * and column if specified. If deptype is not zero, then only find sequences + * with the specified dependency type. */ -List * -getOwnedSequences(Oid relid, AttrNumber attnum) +static List * +getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype) { List *result = NIL; Relation depRel; @@ -553,7 +717,7 @@ getOwnedSequences(Oid relid, AttrNumber attnum) SysScanDesc scan; HeapTuple tup; - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -587,37 +751,53 @@ getOwnedSequences(Oid relid, AttrNumber attnum) (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) && get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE) { - result = lappend_oid(result, deprec->objid); + if (!deptype || deprec->deptype == deptype) + result = lappend_oid(result, deprec->objid); } } systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); return result; } /* - * Get owned sequence, error if not exactly one. + * Collect a list of OIDs of all sequences owned (identity or serial) by the + * specified relation. + */ +List * +getOwnedSequences(Oid relid) +{ + return getOwnedSequences_internal(relid, 0, 0); +} + +/* + * Get owned identity sequence, error if not exactly one. */ Oid -getOwnedSequence(Oid relid, AttrNumber attnum) +getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok) { - List *seqlist = getOwnedSequences(relid, attnum); + List *seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL); if (list_length(seqlist) > 1) elog(ERROR, "more than one owned sequence found"); else if (list_length(seqlist) < 1) - elog(ERROR, "no owned sequence found"); + { + if (missing_ok) + return InvalidOid; + else + elog(ERROR, "no owned sequence found"); + } return linitial_oid(seqlist); } /* * get_constraint_index - * Given the OID of a unique or primary-key constraint, return the - * OID of the underlying unique index. + * Given the OID of a unique, primary-key, or exclusion constraint, + * return the OID of the underlying index. * * Return InvalidOid if the index couldn't be found; this suggests the * given OID is bogus, but we leave it to caller to decide what to do. @@ -632,7 +812,7 @@ get_constraint_index(Oid constraintId) HeapTuple tup; /* Search the dependency table for the dependent index */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -664,10 +844,13 @@ get_constraint_index(Oid constraintId) { char relkind = get_rel_relkind(deprec->objid); - /* This is pure paranoia; there shouldn't be any such */ + /* + * This is pure paranoia; there shouldn't be any other relkinds + * dependent on a constraint. + */ if (relkind != RELKIND_INDEX && relkind != RELKIND_PARTITIONED_INDEX) - break; + continue; indexId = deprec->objid; break; @@ -675,15 +858,16 @@ get_constraint_index(Oid constraintId) } systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); return indexId; } /* * get_index_constraint - * Given the OID of an index, return the OID of the owning unique or - * primary-key constraint, or InvalidOid if no such constraint. + * Given the OID of an index, return the OID of the owning unique, + * primary-key, or exclusion constraint, or InvalidOid if there + * is no owning constraint. */ Oid get_index_constraint(Oid indexId) @@ -695,7 +879,7 @@ get_index_constraint(Oid indexId) HeapTuple tup; /* Search the dependency table for the index */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -731,7 +915,62 @@ get_index_constraint(Oid indexId) } systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); return constraintId; } + +/* + * get_index_ref_constraints + * Given the OID of an index, return the OID of all foreign key + * constraints which reference the index. + */ +List * +get_index_ref_constraints(Oid indexId) +{ + List *result = NIL; + Relation depRel; + ScanKeyData key[3]; + SysScanDesc scan; + HeapTuple tup; + + /* Search the dependency table for the index */ + depRel = table_open(DependRelationId, AccessShareLock); + + ScanKeyInit(&key[0], + Anum_pg_depend_refclassid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(RelationRelationId)); + ScanKeyInit(&key[1], + Anum_pg_depend_refobjid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(indexId)); + ScanKeyInit(&key[2], + Anum_pg_depend_refobjsubid, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(0)); + + scan = systable_beginscan(depRel, DependReferenceIndexId, true, + NULL, 3, key); + + while (HeapTupleIsValid(tup = systable_getnext(scan))) + { + Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup); + + /* + * We assume any normal dependency from a constraint must be what we + * are looking for. + */ + if (deprec->classid == ConstraintRelationId && + deprec->objsubid == 0 && + deprec->deptype == DEPENDENCY_NORMAL) + { + result = lappend_oid(result, deprec->objid); + } + } + + systable_endscan(scan); + table_close(depRel, AccessShareLock); + + return result; +} diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c index fde361f3675..d0ff802501f 100644 --- a/src/backend/catalog/pg_enum.c +++ b/src/backend/catalog/pg_enum.c @@ -3,7 +3,7 @@ * pg_enum.c * routines to support manipulation of the pg_enum relation * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -14,8 +14,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -28,13 +28,25 @@ #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/fmgroids.h" +#include "utils/hsearch.h" +#include "utils/memutils.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* Potentially set by pg_upgrade_support functions */ Oid binary_upgrade_next_pg_enum_oid = InvalidOid; +/* + * Hash table of enum value OIDs created during the current transaction by + * AddEnumLabel. We disallow using these values until the transaction is + * committed; otherwise, they might get into indexes where we can't clean + * them up, and then if the transaction rolls back we have a broken index. + * (See comments for check_safe_enum_use() in enum.c.) Values created by + * EnumValuesCreate are *not* blacklisted; we assume those are created during + * CREATE TYPE, so they can't go away unless the enum type itself does. + */ +static HTAB *enum_blacklist = NULL; + static void RenumberEnumType(Relation pg_enum, HeapTuple *existing, int nelems); static int sort_order_cmp(const void *p1, const void *p2); @@ -66,7 +78,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) * probably not worth trying harder. */ - pg_enum = heap_open(EnumRelationId, RowExclusiveLock); + pg_enum = table_open(EnumRelationId, RowExclusiveLock); /* * Allocate OIDs for the enum's members. @@ -89,7 +101,8 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) do { - new_oid = GetNewOid(pg_enum); + new_oid = GetNewOidWithIndex(pg_enum, EnumOidIndexId, + Anum_pg_enum_oid); } while (new_oid & 1); oids[elemno] = new_oid; } @@ -116,13 +129,13 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) errdetail("Labels must be %d characters or less.", NAMEDATALEN - 1))); + values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(oids[elemno]); values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid); values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(elemno + 1); namestrcpy(&enumlabel, lab); values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel); tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls); - HeapTupleSetOid(tup, oids[elemno]); CatalogTupleInsert(pg_enum, tup); heap_freetuple(tup); @@ -132,7 +145,7 @@ EnumValuesCreate(Oid enumTypeOid, List *vals) /* clean up */ pfree(oids); - heap_close(pg_enum, RowExclusiveLock); + table_close(pg_enum, RowExclusiveLock); } @@ -148,7 +161,7 @@ EnumValuesDelete(Oid enumTypeOid) SysScanDesc scan; HeapTuple tup; - pg_enum = heap_open(EnumRelationId, RowExclusiveLock); + pg_enum = table_open(EnumRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_enum_enumtypid, @@ -165,9 +178,26 @@ EnumValuesDelete(Oid enumTypeOid) systable_endscan(scan); - heap_close(pg_enum, RowExclusiveLock); + table_close(pg_enum, RowExclusiveLock); } +/* + * Initialize the enum blacklist for this transaction. + */ +static void +init_enum_blacklist(void) +{ + HASHCTL hash_ctl; + + memset(&hash_ctl, 0, sizeof(hash_ctl)); + hash_ctl.keysize = sizeof(Oid); + hash_ctl.entrysize = sizeof(Oid); + hash_ctl.hcxt = TopTransactionContext; + enum_blacklist = hash_create("Enum value blacklist", + 32, + &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); +} /* * AddEnumLabel @@ -238,7 +268,7 @@ AddEnumLabel(Oid enumTypeOid, newVal))); } - pg_enum = heap_open(EnumRelationId, RowExclusiveLock); + pg_enum = table_open(EnumRelationId, RowExclusiveLock); /* If we have to renumber the existing members, we restart from here */ restart: @@ -376,7 +406,8 @@ AddEnumLabel(Oid enumTypeOid, bool sorts_ok; /* Get a new OID (different from all existing pg_enum tuples) */ - newOid = GetNewOid(pg_enum); + newOid = GetNewOidWithIndex(pg_enum, EnumOidIndexId, + Anum_pg_enum_oid); /* * Detect whether it sorts correctly relative to existing @@ -389,7 +420,7 @@ AddEnumLabel(Oid enumTypeOid, { HeapTuple exists_tup = existing[i]; Form_pg_enum exists_en = (Form_pg_enum) GETSTRUCT(exists_tup); - Oid exists_oid = HeapTupleGetOid(exists_tup); + Oid exists_oid = exists_en->oid; if (exists_oid & 1) continue; /* ignore odd Oids */ @@ -450,16 +481,23 @@ AddEnumLabel(Oid enumTypeOid, /* Create the new pg_enum entry */ memset(nulls, false, sizeof(nulls)); + values[Anum_pg_enum_oid - 1] = ObjectIdGetDatum(newOid); values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid); values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder); namestrcpy(&enumlabel, newVal); values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel); enum_tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls); - HeapTupleSetOid(enum_tup, newOid); CatalogTupleInsert(pg_enum, enum_tup); heap_freetuple(enum_tup); - heap_close(pg_enum, RowExclusiveLock); + table_close(pg_enum, RowExclusiveLock); + + /* Set up the blacklist hash if not already done in this transaction */ + if (enum_blacklist == NULL) + init_enum_blacklist(); + + /* Add the new value to the blacklist */ + (void) hash_search(enum_blacklist, &newOid, HASH_ENTER, NULL); } @@ -498,7 +536,7 @@ RenameEnumLabel(Oid enumTypeOid, */ LockDatabaseObject(TypeRelationId, enumTypeOid, 0, ExclusiveLock); - pg_enum = heap_open(EnumRelationId, RowExclusiveLock); + pg_enum = table_open(EnumRelationId, RowExclusiveLock); /* Get the list of existing members of the enum */ list = SearchSysCacheList1(ENUMTYPOIDNAME, @@ -543,7 +581,40 @@ RenameEnumLabel(Oid enumTypeOid, CatalogTupleUpdate(pg_enum, &enum_tup->t_self, enum_tup); heap_freetuple(enum_tup); - heap_close(pg_enum, RowExclusiveLock); + table_close(pg_enum, RowExclusiveLock); +} + + +/* + * Test if the given enum value is on the blacklist + */ +bool +EnumBlacklisted(Oid enum_id) +{ + bool found; + + /* If we've made no blacklist table, all values are safe */ + if (enum_blacklist == NULL) + return false; + + /* Else, is it in the table? */ + (void) hash_search(enum_blacklist, &enum_id, HASH_FIND, &found); + return found; +} + + +/* + * Clean up enum stuff after end of top-level transaction. + */ +void +AtEOXact_Enum(void) +{ + /* + * Reset the blacklist table, as all our enum values are now committed. + * The memory will go away automatically when TopTransactionContext is + * freed; it's sufficient to clear our pointer. + */ + enum_blacklist = NULL; } @@ -620,3 +691,72 @@ sort_order_cmp(const void *p1, const void *p2) else return 0; } + +Size +EstimateEnumBlacklistSpace(void) +{ + size_t entries; + + if (enum_blacklist) + entries = hash_get_num_entries(enum_blacklist); + else + entries = 0; + + /* Add one for the terminator. */ + return sizeof(Oid) * (entries + 1); +} + +void +SerializeEnumBlacklist(void *space, Size size) +{ + Oid *serialized = (Oid *) space; + + /* + * Make sure the hash table hasn't changed in size since the caller + * reserved the space. + */ + Assert(size == EstimateEnumBlacklistSpace()); + + /* Write out all the values from the hash table, if there is one. */ + if (enum_blacklist) + { + HASH_SEQ_STATUS status; + Oid *value; + + hash_seq_init(&status, enum_blacklist); + while ((value = (Oid *) hash_seq_search(&status))) + *serialized++ = *value; + } + + /* Write out the terminator. */ + *serialized = InvalidOid; + + /* + * Make sure the amount of space we actually used matches what was + * estimated. + */ + Assert((char *) (serialized + 1) == ((char *) space) + size); +} + +void +RestoreEnumBlacklist(void *space) +{ + Oid *serialized = (Oid *) space; + + Assert(!enum_blacklist); + + /* + * As a special case, if the list is empty then don't even bother to + * create the hash table. This is the usual case, since enum alteration + * is expected to be rare. + */ + if (!OidIsValid(*serialized)) + return; + + /* Read all the values into a new hash table. */ + init_enum_blacklist(); + do + { + hash_search(enum_blacklist, serialized++, HASH_ENTER, NULL); + } while (OidIsValid(*serialized)); +} diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c index 6160804ef8e..59af16221ea 100644 --- a/src/backend/catalog/pg_inherits.c +++ b/src/backend/catalog/pg_inherits.c @@ -8,7 +8,7 @@ * Perhaps someday that code should be moved here, but it'd have to be * disentangled from other stuff such as pg_depend updates. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,8 +20,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_inherits.h" #include "parser/parse_type.h" @@ -30,7 +30,6 @@ #include "utils/fmgroids.h" #include "utils/memutils.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* * Entry of a hash table used in find_all_inheritors. See below. @@ -38,7 +37,7 @@ typedef struct SeenRelsEntry { Oid rel_id; /* relation oid */ - ListCell *numparents_cell; /* corresponding list cell */ + int list_index; /* its position in output list(s) */ } SeenRelsEntry; /* @@ -80,7 +79,7 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode) oidarr = (Oid *) palloc(maxoids * sizeof(Oid)); numoids = 0; - relation = heap_open(InheritsRelationId, AccessShareLock); + relation = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_inherits_inhparent, @@ -103,7 +102,7 @@ find_inheritance_children(Oid parentrelId, LOCKMODE lockmode) systable_endscan(scan); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* * If we found more than one child, sort them by OID. This ensures @@ -187,7 +186,9 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents) * indirect children. We can use a single list as both the record of * already-found rels and the agenda of rels yet to be scanned for more * children. This is a bit tricky but works because the foreach() macro - * doesn't fetch the next list element until the bottom of the loop. + * doesn't fetch the next list element until the bottom of the loop. Note + * that we can't keep pointers into the output lists; but an index is + * sufficient. */ rels_list = list_make1_oid(parentrelId); rel_numparents = list_make1_int(0); @@ -218,14 +219,18 @@ find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents) if (found) { /* if the rel is already there, bump number-of-parents counter */ - lfirst_int(hash_entry->numparents_cell)++; + ListCell *numparents_cell; + + numparents_cell = list_nth_cell(rel_numparents, + hash_entry->list_index); + lfirst_int(numparents_cell)++; } else { /* if it's not there, add it. expect 1 parent, initially. */ + hash_entry->list_index = list_length(rels_list); rels_list = lappend_oid(rels_list, child_oid); rel_numparents = lappend_int(rel_numparents, 1); - hash_entry->numparents_cell = rel_numparents->tail; } } } @@ -285,14 +290,14 @@ has_superclass(Oid relationId) ScanKeyData skey; bool result; - catalog = heap_open(InheritsRelationId, AccessShareLock); + catalog = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(relationId)); scan = systable_beginscan(catalog, InheritsRelidSeqnoIndexId, true, NULL, 1, &skey); result = HeapTupleIsValid(systable_getnext(scan)); systable_endscan(scan); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); return result; } @@ -335,7 +340,7 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId) queue = list_make1_oid(subclassRelid); visited = NIL; - inhrel = heap_open(InheritsRelationId, AccessShareLock); + inhrel = table_open(InheritsRelationId, AccessShareLock); /* * Use queue to do a breadth-first traversal of the inheritance graph from @@ -397,7 +402,7 @@ typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId) } /* clean up ... */ - heap_close(inhrel, AccessShareLock); + table_close(inhrel, AccessShareLock); list_free(visited); list_free(queue); @@ -416,7 +421,7 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber) HeapTuple tuple; Relation inhRelation; - inhRelation = heap_open(InheritsRelationId, RowExclusiveLock); + inhRelation = table_open(InheritsRelationId, RowExclusiveLock); /* * Make the pg_inherits entry @@ -433,7 +438,7 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber) heap_freetuple(tuple); - heap_close(inhRelation, RowExclusiveLock); + table_close(inhRelation, RowExclusiveLock); } /* @@ -448,7 +453,7 @@ StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber) bool DeleteInheritsTuple(Oid inhrelid, Oid inhparent) { - bool found = false; + bool found = false; Relation catalogRelation; ScanKeyData key; SysScanDesc scan; @@ -457,7 +462,7 @@ DeleteInheritsTuple(Oid inhrelid, Oid inhparent) /* * Find pg_inherits entries by inhrelid. */ - catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock); + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); ScanKeyInit(&key, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -480,7 +485,7 @@ DeleteInheritsTuple(Oid inhrelid, Oid inhparent) /* Done */ systable_endscan(scan); - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); return found; } diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c index a876473976a..1a687028fe2 100644 --- a/src/backend/catalog/pg_largeobject.c +++ b/src/backend/catalog/pg_largeobject.c @@ -3,7 +3,7 @@ * pg_largeobject.c * routines to support manipulation of the pg_largeobject relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,10 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_largeobject.h" @@ -26,7 +27,6 @@ #include "utils/acl.h" #include "utils/fmgroids.h" #include "utils/rel.h" -#include "utils/tqual.h" /* @@ -45,8 +45,8 @@ LargeObjectCreate(Oid loid) Datum values[Natts_pg_largeobject_metadata]; bool nulls[Natts_pg_largeobject_metadata]; - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - RowExclusiveLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + RowExclusiveLock); /* * Insert metadata of the largeobject @@ -54,21 +54,26 @@ LargeObjectCreate(Oid loid) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + if (OidIsValid(loid)) + loid_new = loid; + else + loid_new = GetNewOidWithIndex(pg_lo_meta, + LargeObjectMetadataOidIndexId, + Anum_pg_largeobject_metadata_oid); + + values[Anum_pg_largeobject_metadata_oid - 1] = ObjectIdGetDatum(loid_new); values[Anum_pg_largeobject_metadata_lomowner - 1] = ObjectIdGetDatum(GetUserId()); nulls[Anum_pg_largeobject_metadata_lomacl - 1] = true; ntup = heap_form_tuple(RelationGetDescr(pg_lo_meta), values, nulls); - if (OidIsValid(loid)) - HeapTupleSetOid(ntup, loid); - loid_new = CatalogTupleInsert(pg_lo_meta, ntup); - Assert(!OidIsValid(loid) || loid == loid_new); + CatalogTupleInsert(pg_lo_meta, ntup); heap_freetuple(ntup); - heap_close(pg_lo_meta, RowExclusiveLock); + table_close(pg_lo_meta, RowExclusiveLock); return loid_new; } @@ -86,17 +91,17 @@ LargeObjectDrop(Oid loid) SysScanDesc scan; HeapTuple tuple; - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - RowExclusiveLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + RowExclusiveLock); - pg_largeobject = heap_open(LargeObjectRelationId, - RowExclusiveLock); + pg_largeobject = table_open(LargeObjectRelationId, + RowExclusiveLock); /* * Delete an entry from pg_largeobject_metadata */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); @@ -132,9 +137,9 @@ LargeObjectDrop(Oid loid) systable_endscan(scan); - heap_close(pg_largeobject, RowExclusiveLock); + table_close(pg_largeobject, RowExclusiveLock); - heap_close(pg_lo_meta, RowExclusiveLock); + table_close(pg_lo_meta, RowExclusiveLock); } /* @@ -159,12 +164,12 @@ LargeObjectExists(Oid loid) bool retval = false; ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - AccessShareLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + AccessShareLock); sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, @@ -176,7 +181,7 @@ LargeObjectExists(Oid loid) systable_endscan(sd); - heap_close(pg_lo_meta, AccessShareLock); + table_close(pg_lo_meta, AccessShareLock); return retval; } diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c index 2cf52be0255..81958813b18 100644 --- a/src/backend/catalog/pg_namespace.c +++ b/src/backend/catalog/pg_namespace.c @@ -3,7 +3,7 @@ * pg_namespace.c * routines to support manipulation of the pg_namespace relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,9 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -68,12 +69,19 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp) else nspacl = NULL; + nspdesc = table_open(NamespaceRelationId, RowExclusiveLock); + tupDesc = nspdesc->rd_att; + /* initialize nulls and values */ for (i = 0; i < Natts_pg_namespace; i++) { nulls[i] = false; values[i] = (Datum) NULL; } + + nspoid = GetNewOidWithIndex(nspdesc, NamespaceOidIndexId, + Anum_pg_namespace_oid); + values[Anum_pg_namespace_oid - 1] = ObjectIdGetDatum(nspoid); namestrcpy(&nname, nspName); values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname); values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId); @@ -82,15 +90,13 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp) else nulls[Anum_pg_namespace_nspacl - 1] = true; - nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock); - tupDesc = nspdesc->rd_att; tup = heap_form_tuple(tupDesc, values, nulls); - nspoid = CatalogTupleInsert(nspdesc, tup); + CatalogTupleInsert(nspdesc, tup); Assert(OidIsValid(nspoid)); - heap_close(nspdesc, RowExclusiveLock); + table_close(nspdesc, RowExclusiveLock); /* Record dependencies */ myself.classId = NamespaceRelationId; @@ -100,6 +106,9 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp) /* dependency on owner */ recordDependencyOnOwner(NamespaceRelationId, nspoid, ownerId); + /* dependences on roles mentioned in default ACL */ + recordDependencyOnNewAcl(NamespaceRelationId, nspoid, 0, ownerId, nspacl); + /* dependency on extension ... but not for magic temp schemas */ if (!isTemp) recordDependencyOnCurrentExtension(&myself, false); diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c index 6dde75ed252..bcaa26c9978 100644 --- a/src/backend/catalog/pg_operator.c +++ b/src/backend/catalog/pg_operator.c @@ -3,7 +3,7 @@ * pg_operator.c * routines to support manipulation of the pg_operator relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,9 +17,10 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -37,27 +38,27 @@ #include "utils/syscache.h" -static Oid OperatorGet(const char *operatorName, - Oid operatorNamespace, - Oid leftObjectId, - Oid rightObjectId, - bool *defined); +static Oid OperatorGet(const char *operatorName, + Oid operatorNamespace, + Oid leftObjectId, + Oid rightObjectId, + bool *defined); -static Oid OperatorLookup(List *operatorName, - Oid leftObjectId, - Oid rightObjectId, - bool *defined); +static Oid OperatorLookup(List *operatorName, + Oid leftObjectId, + Oid rightObjectId, + bool *defined); -static Oid OperatorShellMake(const char *operatorName, - Oid operatorNamespace, - Oid leftTypeId, - Oid rightTypeId); +static Oid OperatorShellMake(const char *operatorName, + Oid operatorNamespace, + Oid leftTypeId, + Oid rightTypeId); -static Oid get_other_operator(List *otherOp, - Oid otherLeftTypeId, Oid otherRightTypeId, - const char *operatorName, Oid operatorNamespace, - Oid leftTypeId, Oid rightTypeId, - bool isCommutator); +static Oid get_other_operator(List *otherOp, + Oid otherLeftTypeId, Oid otherRightTypeId, + const char *operatorName, Oid operatorNamespace, + Oid leftTypeId, Oid rightTypeId, + bool isCommutator); /* @@ -142,10 +143,10 @@ OperatorGet(const char *operatorName, ObjectIdGetDatum(operatorNamespace)); if (HeapTupleIsValid(tup)) { - RegProcedure oprcode = ((Form_pg_operator) GETSTRUCT(tup))->oprcode; + Form_pg_operator oprform = (Form_pg_operator) GETSTRUCT(tup); - operatorObjectId = HeapTupleGetOid(tup); - *defined = RegProcedureIsValid(oprcode); + operatorObjectId = oprform->oid; + *defined = RegProcedureIsValid(oprform->oprcode); ReleaseSysCache(tup); } else @@ -218,6 +219,12 @@ OperatorShellMake(const char *operatorName, errmsg("\"%s\" is not a valid operator name", operatorName))); + /* + * open pg_operator + */ + pg_operator_desc = table_open(OperatorRelationId, RowExclusiveLock); + tupDesc = pg_operator_desc->rd_att; + /* * initialize our *nulls and *values arrays */ @@ -231,6 +238,9 @@ OperatorShellMake(const char *operatorName, * initialize values[] with the operator name and input data types. Note * that oprcode is set to InvalidOid, indicating it's a shell. */ + operatorObjectId = GetNewOidWithIndex(pg_operator_desc, OperatorOidIndexId, + Anum_pg_operator_oid); + values[Anum_pg_operator_oid - 1] = ObjectIdGetDatum(operatorObjectId); namestrcpy(&oname, operatorName); values[Anum_pg_operator_oprname - 1] = NameGetDatum(&oname); values[Anum_pg_operator_oprnamespace - 1] = ObjectIdGetDatum(operatorNamespace); @@ -247,12 +257,6 @@ OperatorShellMake(const char *operatorName, values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid); values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid); - /* - * open pg_operator - */ - pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock); - tupDesc = pg_operator_desc->rd_att; - /* * create a new operator tuple */ @@ -261,7 +265,7 @@ OperatorShellMake(const char *operatorName, /* * insert our "shell" operator tuple */ - operatorObjectId = CatalogTupleInsert(pg_operator_desc, tup); + CatalogTupleInsert(pg_operator_desc, tup); /* Add dependencies for the entry */ makeOperatorDependencies(tup, false); @@ -279,7 +283,7 @@ OperatorShellMake(const char *operatorName, /* * close the operator relation and return the oid. */ - heap_close(pg_operator_desc, RowExclusiveLock); + table_close(pg_operator_desc, RowExclusiveLock); return operatorObjectId; } @@ -502,7 +506,7 @@ OperatorCreate(const char *operatorName, values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(restrictionId); values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(joinId); - pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock); + pg_operator_desc = table_open(OperatorRelationId, RowExclusiveLock); /* * If we are replacing an operator shell, update; else insert @@ -517,6 +521,7 @@ OperatorCreate(const char *operatorName, elog(ERROR, "cache lookup failed for operator %u", operatorObjectId); + replaces[Anum_pg_operator_oid - 1] = false; tup = heap_modify_tuple(tup, RelationGetDescr(pg_operator_desc), values, @@ -529,10 +534,15 @@ OperatorCreate(const char *operatorName, { isUpdate = false; + operatorObjectId = GetNewOidWithIndex(pg_operator_desc, + OperatorOidIndexId, + Anum_pg_operator_oid); + values[Anum_pg_operator_oid - 1] = ObjectIdGetDatum(operatorObjectId); + tup = heap_form_tuple(RelationGetDescr(pg_operator_desc), values, nulls); - operatorObjectId = CatalogTupleInsert(pg_operator_desc, tup); + CatalogTupleInsert(pg_operator_desc, tup); } /* Add dependencies for the entry */ @@ -541,7 +551,7 @@ OperatorCreate(const char *operatorName, /* Post creation hook for new operator */ InvokeObjectPostCreateHook(OperatorRelationId, operatorObjectId, 0); - heap_close(pg_operator_desc, RowExclusiveLock); + table_close(pg_operator_desc, RowExclusiveLock); /* * If a commutator and/or negator link is provided, update the other @@ -656,7 +666,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete) CommandCounterIncrement(); /* Open the relation. */ - pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock); + pg_operator_desc = table_open(OperatorRelationId, RowExclusiveLock); /* Get a writable copy of the commutator's tuple. */ if (OidIsValid(commId)) @@ -748,7 +758,7 @@ OperatorUpd(Oid baseId, Oid commId, Oid negId, bool isDelete) } /* Close relation and release catalog lock. */ - heap_close(pg_operator_desc, RowExclusiveLock); + table_close(pg_operator_desc, RowExclusiveLock); } /* @@ -767,7 +777,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) referenced; myself.classId = OperatorRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = oper->oid; myself.objectSubId = 0; /* @@ -853,7 +863,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate) } /* Dependency on owner */ - recordDependencyOnOwner(OperatorRelationId, HeapTupleGetOid(tuple), + recordDependencyOnOwner(OperatorRelationId, oper->oid, oper->oprowner); /* Dependency on extension */ diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index d7833529119..ef009ad2bc6 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -3,7 +3,7 @@ * pg_proc.c * routines to support manipulation of the pg_proc relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,7 +15,9 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -48,10 +50,10 @@ typedef struct } parse_error_callback_arg; static void sql_function_parse_error_callback(void *arg); -static int match_prosrc_to_query(const char *prosrc, const char *queryText, - int cursorpos); +static int match_prosrc_to_query(const char *prosrc, const char *queryText, + int cursorpos); static bool match_prosrc_to_literal(const char *prosrc, const char *literal, - int cursorpos, int *newcursorpos); + int cursorpos, int *newcursorpos); /* ---------------------------------------------------------------- @@ -86,6 +88,7 @@ ProcedureCreate(const char *procedureName, List *parameterDefaults, Datum trftypes, Datum proconfig, + Oid prosupport, float4 procost, float4 prorows) { @@ -108,7 +111,6 @@ ProcedureCreate(const char *procedureName, bool nulls[Natts_pg_proc]; Datum values[Natts_pg_proc]; bool replaces[Natts_pg_proc]; - Oid relid; NameData procname; TupleDesc tupDesc; bool is_update; @@ -254,20 +256,6 @@ ProcedureCreate(const char *procedureName, errmsg("unsafe use of pseudo-type \"internal\""), errdetail("A function returning \"internal\" must have at least one \"internal\" argument."))); - /* - * don't allow functions of complex types that have the same name as - * existing attributes of the type - */ - if (parameterCount == 1 && - OidIsValid(parameterTypes->values[0]) && - (relid = typeOrDomainTypeRelid(parameterTypes->values[0])) != InvalidOid && - get_attnum(relid, procedureName) != InvalidAttrNumber) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_COLUMN), - errmsg("\"%s\" is already an attribute of type %s", - procedureName, - format_type_be(parameterTypes->values[0])))); - if (paramModes != NULL) { /* @@ -332,7 +320,7 @@ ProcedureCreate(const char *procedureName, values[Anum_pg_proc_procost - 1] = Float4GetDatum(procost); values[Anum_pg_proc_prorows - 1] = Float4GetDatum(prorows); values[Anum_pg_proc_provariadic - 1] = ObjectIdGetDatum(variadicType); - values[Anum_pg_proc_protransform - 1] = ObjectIdGetDatum(InvalidOid); + values[Anum_pg_proc_prosupport - 1] = ObjectIdGetDatum(prosupport); values[Anum_pg_proc_prokind - 1] = CharGetDatum(prokind); values[Anum_pg_proc_prosecdef - 1] = BoolGetDatum(security_definer); values[Anum_pg_proc_proleakproof - 1] = BoolGetDatum(isLeakProof); @@ -375,7 +363,7 @@ ProcedureCreate(const char *procedureName, nulls[Anum_pg_proc_proconfig - 1] = true; /* proacl will be determined later */ - rel = heap_open(ProcedureRelationId, RowExclusiveLock); + rel = table_open(ProcedureRelationId, RowExclusiveLock); tupDesc = RelationGetDescr(rel); /* Check for pre-existing definition */ @@ -390,13 +378,14 @@ ProcedureCreate(const char *procedureName, Form_pg_proc oldproc = (Form_pg_proc) GETSTRUCT(oldtup); Datum proargnames; bool isnull; + const char *dropcmd; if (!replace) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_FUNCTION), errmsg("function \"%s\" already exists with same argument types", procedureName))); - if (!pg_proc_ownercheck(HeapTupleGetOid(oldtup), proowner)) + if (!pg_proc_ownercheck(oldproc->oid, proowner)) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION, procedureName); @@ -415,17 +404,33 @@ ProcedureCreate(const char *procedureName, errdetail("\"%s\" is a window function.", procedureName) : 0))); + dropcmd = (prokind == PROKIND_PROCEDURE ? "DROP PROCEDURE" : + prokind == PROKIND_AGGREGATE ? "DROP AGGREGATE" : + "DROP FUNCTION"); + /* * Not okay to change the return type of the existing proc, since * existing rules, views, etc may depend on the return type. + * + * In case of a procedure, a changing return type means that whether + * the procedure has output parameters was changed. Since there is no + * user visible return type, we produce a more specific error message. */ if (returnType != oldproc->prorettype || returnsSet != oldproc->proretset) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("cannot change return type of existing function"), - errhint("Use DROP FUNCTION %s first.", - format_procedure(HeapTupleGetOid(oldtup))))); + prokind == PROKIND_PROCEDURE + ? errmsg("cannot change whether a procedure has output parameters") + : errmsg("cannot change return type of existing function"), + + /* + * translator: first %s is DROP FUNCTION, DROP PROCEDURE, or DROP + * AGGREGATE + */ + errhint("Use %s %s first.", + dropcmd, + format_procedure(oldproc->oid)))); /* * If it returns RECORD, check for possible change of record type @@ -449,8 +454,10 @@ ProcedureCreate(const char *procedureName, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("cannot change return type of existing function"), errdetail("Row type defined by OUT parameters is different."), - errhint("Use DROP FUNCTION %s first.", - format_procedure(HeapTupleGetOid(oldtup))))); + /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */ + errhint("Use %s %s first.", + dropcmd, + format_procedure(oldproc->oid)))); } /* @@ -492,8 +499,10 @@ ProcedureCreate(const char *procedureName, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("cannot change name of input parameter \"%s\"", old_arg_names[j]), - errhint("Use DROP FUNCTION %s first.", - format_procedure(HeapTupleGetOid(oldtup))))); + /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */ + errhint("Use %s %s first.", + dropcmd, + format_procedure(oldproc->oid)))); } } @@ -516,8 +525,10 @@ ProcedureCreate(const char *procedureName, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("cannot remove parameter defaults from existing function"), - errhint("Use DROP FUNCTION %s first.", - format_procedure(HeapTupleGetOid(oldtup))))); + /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */ + errhint("Use %s %s first.", + dropcmd, + format_procedure(oldproc->oid)))); proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup, Anum_pg_proc_proargdefaults, @@ -527,11 +538,9 @@ ProcedureCreate(const char *procedureName, Assert(list_length(oldDefaults) == oldproc->pronargdefaults); /* new list can have more defaults than old, advance over 'em */ - newlc = list_head(parameterDefaults); - for (i = list_length(parameterDefaults) - oldproc->pronargdefaults; - i > 0; - i--) - newlc = lnext(newlc); + newlc = list_nth_cell(parameterDefaults, + list_length(parameterDefaults) - + oldproc->pronargdefaults); foreach(oldlc, oldDefaults) { @@ -542,16 +551,19 @@ ProcedureCreate(const char *procedureName, ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("cannot change data type of existing parameter default value"), - errhint("Use DROP FUNCTION %s first.", - format_procedure(HeapTupleGetOid(oldtup))))); - newlc = lnext(newlc); + /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */ + errhint("Use %s %s first.", + dropcmd, + format_procedure(oldproc->oid)))); + newlc = lnext(parameterDefaults, newlc); } } /* - * Do not change existing ownership or permissions, either. Note + * Do not change existing oid, ownership or permissions, either. Note * dependency-update code below has to agree with this decision. */ + replaces[Anum_pg_proc_oid - 1] = false; replaces[Anum_pg_proc_proowner - 1] = false; replaces[Anum_pg_proc_proacl - 1] = false; @@ -565,6 +577,7 @@ ProcedureCreate(const char *procedureName, else { /* Creating a new procedure */ + Oid newOid; /* First, get default permissions and set up proacl */ proacl = get_user_default_acl(OBJECT_FUNCTION, proowner, @@ -574,13 +587,16 @@ ProcedureCreate(const char *procedureName, else nulls[Anum_pg_proc_proacl - 1] = true; + newOid = GetNewOidWithIndex(rel, ProcedureOidIndexId, + Anum_pg_proc_oid); + values[Anum_pg_proc_oid - 1] = ObjectIdGetDatum(newOid); tup = heap_form_tuple(tupDesc, values, nulls); CatalogTupleInsert(rel, tup); is_update = false; } - retval = HeapTupleGetOid(tup); + retval = ((Form_pg_proc) GETSTRUCT(tup))->oid; /* * Create dependencies for the new function. If we are updating an @@ -645,22 +661,23 @@ ProcedureCreate(const char *procedureName, recordDependencyOnExpr(&myself, (Node *) parameterDefaults, NIL, DEPENDENCY_NORMAL); + /* dependency on support function, if any */ + if (OidIsValid(prosupport)) + { + referenced.classId = ProcedureRelationId; + referenced.objectId = prosupport; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } + /* dependency on owner */ if (!is_update) recordDependencyOnOwner(ProcedureRelationId, retval, proowner); /* dependency on any roles mentioned in ACL */ - if (!is_update && proacl != NULL) - { - int nnewmembers; - Oid *newmembers; - - nnewmembers = aclmembers(proacl, &newmembers); - updateAclDependencies(ProcedureRelationId, retval, 0, - proowner, - 0, NULL, - nnewmembers, newmembers); - } + if (!is_update) + recordDependencyOnNewAcl(ProcedureRelationId, retval, 0, + proowner, proacl); /* dependency on extension */ recordDependencyOnCurrentExtension(&myself, is_update); @@ -670,7 +687,7 @@ ProcedureCreate(const char *procedureName, /* Post creation hook for new function */ InvokeObjectPostCreateHook(ProcedureRelationId, retval, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); /* Verify function body */ if (OidIsValid(languageValidator)) diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c index ec3bd1d22d2..fd5da7d5f7b 100644 --- a/src/backend/catalog/pg_publication.c +++ b/src/backend/catalog/pg_publication.c @@ -3,7 +3,7 @@ * pg_publication.c * publication C API manipulation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,9 +18,9 @@ #include "miscadmin.h" #include "access/genam.h" -#include "access/hash.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -91,16 +91,23 @@ check_publication_add_relation(Relation targetrel) * Does same checks as the above, but does not need relation to be opened * and also does not throw errors. * - * Note this also excludes all tables with relid < FirstNormalObjectId, + * XXX This also excludes all tables with relid < FirstNormalObjectId, * ie all tables created during initdb. This mainly affects the preinstalled - * information_schema. (IsCatalogClass() only checks for these inside - * pg_catalog and toast schemas.) + * information_schema. IsCatalogRelationOid() only excludes tables with + * relid < FirstBootstrapObjectId, making that test rather redundant, + * but really we should get rid of the FirstNormalObjectId test not + * IsCatalogRelationOid. We can't do so today because we don't want + * information_schema tables to be considered publishable; but this test + * is really inadequate for that, since the information_schema could be + * dropped and reloaded and then it'll be considered publishable. The best + * long-term solution may be to add a "relispublishable" bool to pg_class, + * and depend on that instead of OID checks. */ static bool is_publishable_class(Oid relid, Form_pg_class reltuple) { return reltuple->relkind == RELKIND_RELATION && - !IsCatalogClass(relid, reltuple) && + !IsCatalogRelationOid(relid) && reltuple->relpersistence == RELPERSISTENCE_PERMANENT && relid >= FirstNormalObjectId; } @@ -130,7 +137,7 @@ pg_relation_is_publishable(PG_FUNCTION_ARGS) bool result; tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); - if (!tuple) + if (!HeapTupleIsValid(tuple)) PG_RETURN_NULL(); result = is_publishable_class(relid, (Form_pg_class) GETSTRUCT(tuple)); ReleaseSysCache(tuple); @@ -155,7 +162,7 @@ publication_add_relation(Oid pubid, Relation targetrel, ObjectAddress myself, referenced; - rel = heap_open(PublicationRelRelationId, RowExclusiveLock); + rel = table_open(PublicationRelRelationId, RowExclusiveLock); /* * Check for duplicates. Note that this does not really prevent @@ -165,7 +172,7 @@ publication_add_relation(Oid pubid, Relation targetrel, if (SearchSysCacheExists2(PUBLICATIONRELMAP, ObjectIdGetDatum(relid), ObjectIdGetDatum(pubid))) { - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); if (if_not_exists) return InvalidObjectAddress; @@ -182,6 +189,9 @@ publication_add_relation(Oid pubid, Relation targetrel, memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId, + Anum_pg_publication_rel_oid); + values[Anum_pg_publication_rel_oid - 1] = ObjectIdGetDatum(prrelid); values[Anum_pg_publication_rel_prpubid - 1] = ObjectIdGetDatum(pubid); values[Anum_pg_publication_rel_prrelid - 1] = @@ -190,7 +200,7 @@ publication_add_relation(Oid pubid, Relation targetrel, tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); /* Insert tuple into catalog. */ - prrelid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); ObjectAddressSet(myself, PublicationRelRelationId, prrelid); @@ -204,7 +214,7 @@ publication_add_relation(Oid pubid, Relation targetrel, recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); /* Close the table. */ - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); /* Invalidate relcache so that publication info is rebuilt. */ CacheInvalidateRelcache(targetrel); @@ -255,7 +265,7 @@ GetPublicationRelations(Oid pubid) HeapTuple tup; /* Find all publications associated with the relation. */ - pubrelsrel = heap_open(PublicationRelRelationId, AccessShareLock); + pubrelsrel = table_open(PublicationRelRelationId, AccessShareLock); ScanKeyInit(&scankey, Anum_pg_publication_rel_prpubid, @@ -276,7 +286,7 @@ GetPublicationRelations(Oid pubid) } systable_endscan(scan); - heap_close(pubrelsrel, AccessShareLock); + table_close(pubrelsrel, AccessShareLock); return result; } @@ -294,7 +304,7 @@ GetAllTablesPublications(void) HeapTuple tup; /* Find all publications that are marked as for all tables. */ - rel = heap_open(PublicationRelationId, AccessShareLock); + rel = table_open(PublicationRelationId, AccessShareLock); ScanKeyInit(&scankey, Anum_pg_publication_puballtables, @@ -306,10 +316,14 @@ GetAllTablesPublications(void) result = NIL; while (HeapTupleIsValid(tup = systable_getnext(scan))) - result = lappend_oid(result, HeapTupleGetOid(tup)); + { + Oid oid = ((Form_pg_publication) GETSTRUCT(tup))->oid; + + result = lappend_oid(result, oid); + } systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return result; } @@ -322,30 +336,30 @@ GetAllTablesPublicationRelations(void) { Relation classRel; ScanKeyData key[1]; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; List *result = NIL; - classRel = heap_open(RelationRelationId, AccessShareLock); + classRel = table_open(RelationRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_class_relkind, BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_RELATION)); - scan = heap_beginscan_catalog(classRel, 1, key); + scan = table_beginscan_catalog(classRel, 1, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid relid = HeapTupleGetOid(tuple); Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); + Oid relid = relForm->oid; if (is_publishable_class(relid, relForm)) result = lappend_oid(result, relid); } - heap_endscan(scan); - heap_close(classRel, AccessShareLock); + table_endscan(scan); + table_close(classRel, AccessShareLock); return result; } @@ -392,7 +406,8 @@ GetPublicationByName(const char *pubname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(PUBLICATIONNAME, CStringGetDatum(pubname)); + oid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid, + CStringGetDatum(pubname)); if (!OidIsValid(oid)) { if (missing_ok) @@ -417,7 +432,8 @@ get_publication_oid(const char *pubname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(PUBLICATIONNAME, CStringGetDatum(pubname)); + oid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid, + CStringGetDatum(pubname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -427,9 +443,12 @@ get_publication_oid(const char *pubname, bool missing_ok) /* * get_publication_name - given a publication Oid, look up the name + * + * If missing_ok is false, throw an error if name not found. If true, just + * return NULL. */ char * -get_publication_name(Oid pubid) +get_publication_name(Oid pubid, bool missing_ok) { HeapTuple tup; char *pubname; @@ -438,7 +457,11 @@ get_publication_name(Oid pubid) tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid)); if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for publication %u", pubid); + { + if (!missing_ok) + elog(ERROR, "cache lookup failed for publication %u", pubid); + return NULL; + } pubform = (Form_pg_publication) GETSTRUCT(tup); pubname = pstrdup(NameStr(pubform->pubname)); @@ -458,7 +481,6 @@ pg_get_publication_tables(PG_FUNCTION_ARGS) char *pubname = text_to_cstring(PG_GETARG_TEXT_PP(0)); Publication *publication; List *tables; - ListCell **lcp; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) @@ -476,22 +498,19 @@ pg_get_publication_tables(PG_FUNCTION_ARGS) tables = GetAllTablesPublicationRelations(); else tables = GetPublicationRelations(publication->oid); - lcp = (ListCell **) palloc(sizeof(ListCell *)); - *lcp = list_head(tables); - funcctx->user_fctx = (void *) lcp; + funcctx->user_fctx = (void *) tables; MemoryContextSwitchTo(oldcontext); } /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); - lcp = (ListCell **) funcctx->user_fctx; + tables = (List *) funcctx->user_fctx; - while (*lcp != NULL) + if (funcctx->call_cntr < list_length(tables)) { - Oid relid = lfirst_oid(*lcp); + Oid relid = list_nth_oid(tables, funcctx->call_cntr); - *lcp = lnext(*lcp); SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid)); } diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c index c902f98606b..e6e138babdf 100644 --- a/src/backend/catalog/pg_range.c +++ b/src/backend/catalog/pg_range.c @@ -3,7 +3,7 @@ * pg_range.c * routines to support manipulation of the pg_range relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_collation.h" @@ -26,7 +26,6 @@ #include "catalog/pg_type.h" #include "utils/fmgroids.h" #include "utils/rel.h" -#include "utils/tqual.h" /* @@ -45,7 +44,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ObjectAddress myself; ObjectAddress referenced; - pg_range = heap_open(RangeRelationId, RowExclusiveLock); + pg_range = table_open(RangeRelationId, RowExclusiveLock); memset(nulls, 0, sizeof(nulls)); @@ -101,7 +100,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - heap_close(pg_range, RowExclusiveLock); + table_close(pg_range, RowExclusiveLock); } @@ -117,7 +116,7 @@ RangeDelete(Oid rangeTypeOid) SysScanDesc scan; HeapTuple tup; - pg_range = heap_open(RangeRelationId, RowExclusiveLock); + pg_range = table_open(RangeRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_range_rngtypid, @@ -134,5 +133,5 @@ RangeDelete(Oid rangeTypeOid) systable_endscan(scan); - heap_close(pg_range, RowExclusiveLock); + table_close(pg_range, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index faf42b76405..fb7f8ddefc9 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -3,7 +3,7 @@ * pg_shdepend.c * routines to support manipulation of the pg_shdepend relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" @@ -65,7 +65,6 @@ #include "utils/acl.h" #include "utils/fmgroids.h" #include "utils/syscache.h" -#include "utils/tqual.h" typedef enum @@ -75,26 +74,33 @@ typedef enum REMOTE_OBJECT } SharedDependencyObjectType; +typedef struct +{ + ObjectAddress object; + char deptype; + SharedDependencyObjectType objtype; +} ShDependObjectInfo; + static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2); static Oid classIdGetDbId(Oid classId); static void shdepChangeDep(Relation sdepRel, - Oid classid, Oid objid, int32 objsubid, - Oid refclassid, Oid refobjid, - SharedDependencyType deptype); + Oid classid, Oid objid, int32 objsubid, + Oid refclassid, Oid refobjid, + SharedDependencyType deptype); static void shdepAddDependency(Relation sdepRel, - Oid classId, Oid objectId, int32 objsubId, - Oid refclassId, Oid refobjId, - SharedDependencyType deptype); + Oid classId, Oid objectId, int32 objsubId, + Oid refclassId, Oid refobjId, + SharedDependencyType deptype); static void shdepDropDependency(Relation sdepRel, - Oid classId, Oid objectId, int32 objsubId, - bool drop_subobjects, - Oid refclassId, Oid refobjId, - SharedDependencyType deptype); + Oid classId, Oid objectId, int32 objsubId, + bool drop_subobjects, + Oid refclassId, Oid refobjId, + SharedDependencyType deptype); static void storeObjectDescription(StringInfo descs, - SharedDependencyObjectType type, - ObjectAddress *object, - SharedDependencyType deptype, - int count); + SharedDependencyObjectType type, + ObjectAddress *object, + SharedDependencyType deptype, + int count); static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel); @@ -131,7 +137,7 @@ recordSharedDependencyOn(ObjectAddress *depender, if (IsBootstrapProcessingMode()) return; - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); /* If the referenced object is pinned, do nothing. */ if (!isSharedObjectPinned(referenced->classId, referenced->objectId, @@ -143,7 +149,7 @@ recordSharedDependencyOn(ObjectAddress *depender, deptype); } - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } /* @@ -305,7 +311,7 @@ changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId) { Relation sdepRel; - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); /* Adjust the SHARED_DEPENDENCY_OWNER entry */ shdepChangeDep(sdepRel, @@ -336,7 +342,7 @@ changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId) AuthIdRelationId, newOwnerId, SHARED_DEPENDENCY_ACL); - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } /* @@ -436,7 +442,7 @@ updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, if (noldmembers > 0 || nnewmembers > 0) { - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); /* Add new dependencies that weren't already present */ for (i = 0; i < nnewmembers; i++) @@ -479,7 +485,7 @@ updateAclDependencies(Oid classId, Oid objectId, int32 objsubId, SHARED_DEPENDENCY_ACL); } - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } if (oldmembers) @@ -497,6 +503,56 @@ typedef struct int count; } remoteDep; +/* + * qsort comparator for ShDependObjectInfo items + */ +static int +shared_dependency_comparator(const void *a, const void *b) +{ + const ShDependObjectInfo *obja = (const ShDependObjectInfo *) a; + const ShDependObjectInfo *objb = (const ShDependObjectInfo *) b; + + /* + * Primary sort key is OID ascending. + */ + if (obja->object.objectId < objb->object.objectId) + return -1; + if (obja->object.objectId > objb->object.objectId) + return 1; + + /* + * Next sort on catalog ID, in case identical OIDs appear in different + * catalogs. Sort direction is pretty arbitrary here. + */ + if (obja->object.classId < objb->object.classId) + return -1; + if (obja->object.classId > objb->object.classId) + return 1; + + /* + * Sort on object subId. + * + * We sort the subId as an unsigned int so that 0 (the whole object) will + * come first. + */ + if ((unsigned int) obja->object.objectSubId < (unsigned int) objb->object.objectSubId) + return -1; + if ((unsigned int) obja->object.objectSubId > (unsigned int) objb->object.objectSubId) + return 1; + + /* + * Last, sort on deptype, in case the same object has multiple dependency + * types. (Note that there's no need to consider objtype, as that's + * determined by the catalog OID.) + */ + if (obja->deptype < objb->deptype) + return -1; + if (obja->deptype > objb->deptype) + return 1; + + return 0; +} + /* * checkSharedDependencies * @@ -532,6 +588,9 @@ checkSharedDependencies(Oid classId, Oid objectId, List *remDeps = NIL; ListCell *cell; ObjectAddress object; + ShDependObjectInfo *objects; + int numobjects; + int allocedobjects; StringInfoData descs; StringInfoData alldescs; @@ -539,13 +598,21 @@ checkSharedDependencies(Oid classId, Oid objectId, * We limit the number of dependencies reported to the client to * MAX_REPORTED_DEPS, since client software may not deal well with * enormous error strings. The server log always gets a full report. + * + * For stability of regression test results, we sort local and shared + * objects by OID before reporting them. We don't worry about the order + * in which other databases are reported, though. */ #define MAX_REPORTED_DEPS 100 + allocedobjects = 128; /* arbitrary initial array size */ + objects = (ShDependObjectInfo *) + palloc(allocedobjects * sizeof(ShDependObjectInfo)); + numobjects = 0; initStringInfo(&descs); initStringInfo(&alldescs); - sdepRel = heap_open(SharedDependRelationId, AccessShareLock); + sdepRel = table_open(SharedDependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_shdepend_refclassid, @@ -581,36 +648,26 @@ checkSharedDependencies(Oid classId, Oid objectId, /* * If it's a dependency local to this database or it's a shared - * object, describe it. + * object, add it to the objects array. * * If it's a remote dependency, keep track of it so we can report the * number of them later. */ - if (sdepForm->dbid == MyDatabaseId) + if (sdepForm->dbid == MyDatabaseId || + sdepForm->dbid == InvalidOid) { - if (numReportedDeps < MAX_REPORTED_DEPS) + if (numobjects >= allocedobjects) { - numReportedDeps++; - storeObjectDescription(&descs, LOCAL_OBJECT, &object, - sdepForm->deptype, 0); + allocedobjects *= 2; + objects = (ShDependObjectInfo *) + repalloc(objects, + allocedobjects * sizeof(ShDependObjectInfo)); } - else - numNotReportedDeps++; - storeObjectDescription(&alldescs, LOCAL_OBJECT, &object, - sdepForm->deptype, 0); - } - else if (sdepForm->dbid == InvalidOid) - { - if (numReportedDeps < MAX_REPORTED_DEPS) - { - numReportedDeps++; - storeObjectDescription(&descs, SHARED_OBJECT, &object, - sdepForm->deptype, 0); - } - else - numNotReportedDeps++; - storeObjectDescription(&alldescs, SHARED_OBJECT, &object, - sdepForm->deptype, 0); + objects[numobjects].object = object; + objects[numobjects].deptype = sdepForm->deptype; + objects[numobjects].objtype = (sdepForm->dbid == MyDatabaseId) ? + LOCAL_OBJECT : SHARED_OBJECT; + numobjects++; } else { @@ -646,7 +703,34 @@ checkSharedDependencies(Oid classId, Oid objectId, systable_endscan(scan); - heap_close(sdepRel, AccessShareLock); + table_close(sdepRel, AccessShareLock); + + /* + * Sort and report local and shared objects. + */ + if (numobjects > 1) + qsort((void *) objects, numobjects, + sizeof(ShDependObjectInfo), shared_dependency_comparator); + + for (int i = 0; i < numobjects; i++) + { + if (numReportedDeps < MAX_REPORTED_DEPS) + { + numReportedDeps++; + storeObjectDescription(&descs, + objects[i].objtype, + &objects[i].object, + objects[i].deptype, + 0); + } + else + numNotReportedDeps++; + storeObjectDescription(&alldescs, + objects[i].objtype, + &objects[i].object, + objects[i].deptype, + 0); + } /* * Summarize dependencies in remote databases. @@ -671,6 +755,7 @@ checkSharedDependencies(Oid classId, Oid objectId, SHARED_DEPENDENCY_INVALID, dep->count); } + pfree(objects); list_free_deep(remDeps); if (descs.len == 0) @@ -720,7 +805,7 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) bool nulls[Natts_pg_shdepend]; bool replace[Natts_pg_shdepend]; - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); sdepDesc = RelationGetDescr(sdepRel); indstate = CatalogOpenIndexes(sdepRel); @@ -762,7 +847,7 @@ copyTemplateDependencies(Oid templateDbId, Oid newDbId) systable_endscan(scan); CatalogCloseIndexes(indstate); - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } /* @@ -779,7 +864,7 @@ dropDatabaseDependencies(Oid databaseId) SysScanDesc scan; HeapTuple tup; - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); /* * First, delete all the entries that have the database Oid in the dbid @@ -806,7 +891,7 @@ dropDatabaseDependencies(Oid databaseId) InvalidOid, InvalidOid, SHARED_DEPENDENCY_INVALID); - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } /* @@ -824,14 +909,14 @@ deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId) { Relation sdepRel; - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); shdepDropDependency(sdepRel, classId, objectId, objectSubId, (objectSubId == 0), InvalidOid, InvalidOid, SHARED_DEPENDENCY_INVALID); - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } /* @@ -1173,7 +1258,7 @@ shdepDropOwned(List *roleids, DropBehavior behavior) * acquire RowExclusiveLock. Better get that right now to avoid potential * deadlock failures. */ - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); /* * For each role, find the dependent objects and drop them using the @@ -1267,10 +1352,18 @@ shdepDropOwned(List *roleids, DropBehavior behavior) systable_endscan(scan); } + /* + * For stability of deletion-report ordering, sort the objects into + * approximate reverse creation order before deletion. (This might also + * make the deletion go a bit faster, since there's less chance of having + * to rearrange the objects due to dependencies.) + */ + sort_object_addresses(deleteobjs); + /* the dependency mechanism does the actual work */ performMultipleDeletions(deleteobjs, behavior, 0); - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); free_object_addresses(deleteobjs); } @@ -1292,7 +1385,7 @@ shdepReassignOwned(List *roleids, Oid newrole) * acquire RowExclusiveLock. Better get that right now to avoid potential * deadlock problems. */ - sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock); + sdepRel = table_open(SharedDependRelationId, RowExclusiveLock); foreach(cell, roleids) { @@ -1428,12 +1521,12 @@ shdepReassignOwned(List *roleids, Oid newrole) if (classId == LargeObjectRelationId) classId = LargeObjectMetadataRelationId; - catalog = heap_open(classId, RowExclusiveLock); + catalog = table_open(classId, RowExclusiveLock); AlterObjectOwner_internal(catalog, sdepForm->objid, newrole); - heap_close(catalog, NoLock); + table_close(catalog, NoLock); } break; @@ -1448,5 +1541,5 @@ shdepReassignOwned(List *roleids, Oid newrole) systable_endscan(scan); } - heap_close(sdepRel, RowExclusiveLock); + table_close(sdepRel, RowExclusiveLock); } diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c index 8705d8b1d36..afee2838cc2 100644 --- a/src/backend/catalog/pg_subscription.c +++ b/src/backend/catalog/pg_subscription.c @@ -3,7 +3,7 @@ * pg_subscription.c * replication subscriptions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,6 +19,7 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/indexing.h" @@ -123,7 +124,7 @@ CountDBSubscriptions(Oid dbid) SysScanDesc scan; HeapTuple tup; - rel = heap_open(SubscriptionRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelationId, RowExclusiveLock); ScanKeyInit(&scankey, Anum_pg_subscription_subdbid, @@ -138,7 +139,7 @@ CountDBSubscriptions(Oid dbid) systable_endscan(scan); - heap_close(rel, NoLock); + table_close(rel, NoLock); return nsubs; } @@ -168,8 +169,8 @@ get_subscription_oid(const char *subname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid2(SUBSCRIPTIONNAME, MyDatabaseId, - CStringGetDatum(subname)); + oid = GetSysCacheOid2(SUBSCRIPTIONNAME, Anum_pg_subscription_oid, + MyDatabaseId, CStringGetDatum(subname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -179,9 +180,12 @@ get_subscription_oid(const char *subname, bool missing_ok) /* * get_subscription_name - given a subscription OID, look up the name + * + * If missing_ok is false, throw an error if name not found. If true, just + * return NULL. */ char * -get_subscription_name(Oid subid) +get_subscription_name(Oid subid, bool missing_ok) { HeapTuple tup; char *subname; @@ -190,7 +194,11 @@ get_subscription_name(Oid subid) tup = SearchSysCache1(SUBSCRIPTIONOID, ObjectIdGetDatum(subid)); if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for subscription %u", subid); + { + if (!missing_ok) + elog(ERROR, "cache lookup failed for subscription %u", subid); + return NULL; + } subform = (Form_pg_subscription) GETSTRUCT(tup); subname = pstrdup(NameStr(subform->subname)); @@ -229,19 +237,18 @@ textarray_to_stringlist(ArrayType *textarray) /* * Add new state record for a subscription table. */ -Oid +void AddSubscriptionRelState(Oid subid, Oid relid, char state, XLogRecPtr sublsn) { Relation rel; HeapTuple tup; - Oid subrelid; bool nulls[Natts_pg_subscription_rel]; Datum values[Natts_pg_subscription_rel]; LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock); - rel = heap_open(SubscriptionRelRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelRelationId, RowExclusiveLock); /* Try finding existing mapping. */ tup = SearchSysCacheCopy2(SUBSCRIPTIONRELMAP, @@ -265,33 +272,30 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state, tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); /* Insert tuple into catalog. */ - subrelid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); /* Cleanup. */ - heap_close(rel, NoLock); - - return subrelid; + table_close(rel, NoLock); } /* * Update the state of a subscription table. */ -Oid +void UpdateSubscriptionRelState(Oid subid, Oid relid, char state, XLogRecPtr sublsn) { Relation rel; HeapTuple tup; - Oid subrelid; bool nulls[Natts_pg_subscription_rel]; Datum values[Natts_pg_subscription_rel]; bool replaces[Natts_pg_subscription_rel]; LockSharedObject(SubscriptionRelationId, subid, 0, AccessShareLock); - rel = heap_open(SubscriptionRelRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelRelationId, RowExclusiveLock); /* Try finding existing mapping. */ tup = SearchSysCacheCopy2(SUBSCRIPTIONRELMAP, @@ -321,12 +325,8 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state, /* Update the catalog. */ CatalogTupleUpdate(rel, &tup->t_self, tup); - subrelid = HeapTupleGetOid(tup); - /* Cleanup. */ - heap_close(rel, NoLock); - - return subrelid; + table_close(rel, NoLock); } /* @@ -344,7 +344,7 @@ GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, bool isnull; Datum d; - rel = heap_open(SubscriptionRelRelationId, AccessShareLock); + rel = table_open(SubscriptionRelRelationId, AccessShareLock); /* Try finding the mapping. */ tup = SearchSysCache2(SUBSCRIPTIONRELMAP, @@ -355,7 +355,7 @@ GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, { if (missing_ok) { - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); *sublsn = InvalidXLogRecPtr; return SUBREL_STATE_UNKNOWN; } @@ -378,7 +378,7 @@ GetSubscriptionRelState(Oid subid, Oid relid, XLogRecPtr *sublsn, /* Cleanup */ ReleaseSysCache(tup); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return substate; } @@ -391,12 +391,12 @@ void RemoveSubscriptionRel(Oid subid, Oid relid) { Relation rel; - HeapScanDesc scan; + TableScanDesc scan; ScanKeyData skey[2]; HeapTuple tup; int nkeys = 0; - rel = heap_open(SubscriptionRelRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelRelationId, RowExclusiveLock); if (OidIsValid(subid)) { @@ -417,14 +417,14 @@ RemoveSubscriptionRel(Oid subid, Oid relid) } /* Do the search and delete what we found. */ - scan = heap_beginscan_catalog(rel, nkeys, skey); + scan = table_beginscan_catalog(rel, nkeys, skey); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { CatalogTupleDelete(rel, &tup->t_self); } - heap_endscan(scan); + table_endscan(scan); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -443,7 +443,7 @@ GetSubscriptionRelations(Oid subid) ScanKeyData skey[2]; SysScanDesc scan; - rel = heap_open(SubscriptionRelRelationId, AccessShareLock); + rel = table_open(SubscriptionRelRelationId, AccessShareLock); ScanKeyInit(&skey[nkeys++], Anum_pg_subscription_rel_srsubid, @@ -470,7 +470,7 @@ GetSubscriptionRelations(Oid subid) /* Cleanup */ systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return res; } @@ -490,7 +490,7 @@ GetSubscriptionNotReadyRelations(Oid subid) ScanKeyData skey[2]; SysScanDesc scan; - rel = heap_open(SubscriptionRelRelationId, AccessShareLock); + rel = table_open(SubscriptionRelRelationId, AccessShareLock); ScanKeyInit(&skey[nkeys++], Anum_pg_subscription_rel_srsubid, @@ -522,7 +522,7 @@ GetSubscriptionNotReadyRelations(Oid subid) /* Cleanup */ systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return res; } diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c index 2ddd46d48ed..2a51501d8d9 100644 --- a/src/backend/catalog/pg_type.c +++ b/src/backend/catalog/pg_type.c @@ -3,7 +3,7 @@ * pg_type.c * routines to support manipulation of the pg_type relation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,9 +14,10 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/binary_upgrade.h" #include "catalog/dependency.h" #include "catalog/indexing.h" @@ -69,7 +70,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) /* * open pg_type */ - pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); + pg_type_desc = table_open(TypeRelationId, RowExclusiveLock); tupDesc = pg_type_desc->rd_att; /* @@ -121,11 +122,6 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) nulls[Anum_pg_type_typdefault - 1] = true; nulls[Anum_pg_type_typacl - 1] = true; - /* - * create a new type tuple - */ - tup = heap_form_tuple(tupDesc, values, nulls); - /* Use binary-upgrade override for pg_type.oid? */ if (IsBinaryUpgrade) { @@ -134,36 +130,38 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pg_type OID value not set when in binary upgrade mode"))); - HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid); + typoid = binary_upgrade_next_pg_type_oid; binary_upgrade_next_pg_type_oid = InvalidOid; } + else + { + typoid = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId, + Anum_pg_type_oid); + } + + values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typoid); + + /* + * create a new type tuple + */ + tup = heap_form_tuple(tupDesc, values, nulls); /* * insert the tuple in the relation and get the tuple's oid. */ - typoid = CatalogTupleInsert(pg_type_desc, tup); + CatalogTupleInsert(pg_type_desc, tup); /* * Create dependencies. We can/must skip this in bootstrap mode. */ if (!IsBootstrapProcessingMode()) - GenerateTypeDependencies(typeNamespace, - typoid, - InvalidOid, + GenerateTypeDependencies(typoid, + (Form_pg_type) GETSTRUCT(tup), + NULL, + NULL, 0, - ownerId, - F_SHELL_IN, - F_SHELL_OUT, - InvalidOid, - InvalidOid, - InvalidOid, - InvalidOid, - InvalidOid, - InvalidOid, false, - InvalidOid, - InvalidOid, - NULL, + false, false); /* Post creation hook for new shell type */ @@ -175,7 +173,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId) * clean up and return the type-oid */ heap_freetuple(tup); - heap_close(pg_type_desc, RowExclusiveLock); + table_close(pg_type_desc, RowExclusiveLock); return address; } @@ -225,14 +223,15 @@ TypeCreate(Oid newTypeOid, { Relation pg_type_desc; Oid typeObjectId; + bool isDependentType; bool rebuildDeps = false; + Acl *typacl; HeapTuple tup; bool nulls[Natts_pg_type]; bool replaces[Natts_pg_type]; Datum values[Natts_pg_type]; NameData name; int i; - Acl *typacl = NULL; ObjectAddress address; /* @@ -320,6 +319,17 @@ TypeCreate(Oid newTypeOid, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("fixed-size types must have storage PLAIN"))); + /* + * This is a dependent type if it's an implicitly-created array type, or + * if it's a relation rowtype that's not a composite type. For such types + * we'll leave the ACL empty, and we'll skip creating some dependency + * records because there will be a dependency already through the + * depended-on type or relation. (Caution: this is closely intertwined + * with some behavior in GenerateTypeDependencies.) + */ + isDependentType = isImplicitArray || + (OidIsValid(relationOid) && relationKind != RELKIND_COMPOSITE_TYPE); + /* * initialize arrays needed for heap_form_tuple or heap_modify_tuple */ @@ -379,8 +389,14 @@ TypeCreate(Oid newTypeOid, else nulls[Anum_pg_type_typdefault - 1] = true; - typacl = get_user_default_acl(OBJECT_TYPE, ownerId, - typeNamespace); + /* + * Initialize the type's ACL, too. But dependent types don't get one. + */ + if (isDependentType) + typacl = NULL; + else + typacl = get_user_default_acl(OBJECT_TYPE, ownerId, + typeNamespace); if (typacl != NULL) values[Anum_pg_type_typacl - 1] = PointerGetDatum(typacl); else @@ -392,18 +408,20 @@ TypeCreate(Oid newTypeOid, * NOTE: updating will not work correctly in bootstrap mode; but we don't * expect to be overwriting any shell types in bootstrap mode. */ - pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); + pg_type_desc = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy2(TYPENAMENSP, CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace)); if (HeapTupleIsValid(tup)) { + Form_pg_type typform = (Form_pg_type) GETSTRUCT(tup); + /* * check that the type is not already defined. It may exist as a * shell type, however. */ - if (((Form_pg_type) GETSTRUCT(tup))->typisdefined) + if (typform->typisdefined) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("type \"%s\" already exists", typeName))); @@ -411,13 +429,15 @@ TypeCreate(Oid newTypeOid, /* * shell type must have been created by same owner */ - if (((Form_pg_type) GETSTRUCT(tup))->typowner != ownerId) + if (typform->typowner != ownerId) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TYPE, typeName); /* trouble if caller wanted to force the OID */ if (OidIsValid(newTypeOid)) elog(ERROR, "cannot assign new OID to existing shell type"); + replaces[Anum_pg_type_oid - 1] = false; + /* * Okay to update existing shell type tuple */ @@ -429,19 +449,15 @@ TypeCreate(Oid newTypeOid, CatalogTupleUpdate(pg_type_desc, &tup->t_self, tup); - typeObjectId = HeapTupleGetOid(tup); + typeObjectId = typform->oid; rebuildDeps = true; /* get rid of shell type's dependencies */ } else { - tup = heap_form_tuple(RelationGetDescr(pg_type_desc), - values, - nulls); - /* Force the OID if requested by caller */ if (OidIsValid(newTypeOid)) - HeapTupleSetOid(tup, newTypeOid); + typeObjectId = newTypeOid; /* Use binary-upgrade override for pg_type.oid, if supplied. */ else if (IsBinaryUpgrade) { @@ -450,37 +466,36 @@ TypeCreate(Oid newTypeOid, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pg_type OID value not set when in binary upgrade mode"))); - HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid); + typeObjectId = binary_upgrade_next_pg_type_oid; binary_upgrade_next_pg_type_oid = InvalidOid; } - /* else allow system to assign oid */ + else + { + typeObjectId = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId, + Anum_pg_type_oid); + } + + values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typeObjectId); + + tup = heap_form_tuple(RelationGetDescr(pg_type_desc), + values, nulls); - typeObjectId = CatalogTupleInsert(pg_type_desc, tup); + CatalogTupleInsert(pg_type_desc, tup); } /* * Create dependencies. We can/must skip this in bootstrap mode. */ if (!IsBootstrapProcessingMode()) - GenerateTypeDependencies(typeNamespace, - typeObjectId, - relationOid, - relationKind, - ownerId, - inputProcedure, - outputProcedure, - receiveProcedure, - sendProcedure, - typmodinProcedure, - typmodoutProcedure, - analyzeProcedure, - elementType, - isImplicitArray, - baseType, - typeCollation, + GenerateTypeDependencies(typeObjectId, + (Form_pg_type) GETSTRUCT(tup), (defaultTypeBin ? stringToNode(defaultTypeBin) : NULL), + typacl, + relationKind, + isImplicitArray, + isDependentType, rebuildDeps); /* Post creation hook for new type */ @@ -491,7 +506,7 @@ TypeCreate(Oid newTypeOid, /* * finish up */ - heap_close(pg_type_desc, RowExclusiveLock); + table_close(pg_type_desc, RowExclusiveLock); return address; } @@ -499,6 +514,17 @@ TypeCreate(Oid newTypeOid, /* * GenerateTypeDependencies: build the dependencies needed for a type * + * Most of what this function needs to know about the type is passed as the + * new pg_type row, typeForm. But we can't get at the varlena fields through + * that, so defaultExpr and typacl are passed separately. (typacl is really + * "Acl *", but we declare it "void *" to avoid including acl.h in pg_type.h.) + * + * relationKind and isImplicitArray aren't visible in the pg_type row either, + * so they're also passed separately. + * + * isDependentType is true if this is an implicit array or relation rowtype; + * that means it doesn't need its own dependencies on owner etc. + * * If rebuild is true, we remove existing dependencies and rebuild them * from scratch. This is needed for ALTER TYPE, and also when replacing * a shell type. We don't remove an existing extension dependency, though. @@ -508,23 +534,13 @@ TypeCreate(Oid newTypeOid, * that type will become a member of the extension.) */ void -GenerateTypeDependencies(Oid typeNamespace, - Oid typeObjectId, - Oid relationOid, /* only for relation rowtypes */ - char relationKind, /* ditto */ - Oid owner, - Oid inputProcedure, - Oid outputProcedure, - Oid receiveProcedure, - Oid sendProcedure, - Oid typmodinProcedure, - Oid typmodoutProcedure, - Oid analyzeProcedure, - Oid elementType, - bool isImplicitArray, - Oid baseType, - Oid typeCollation, +GenerateTypeDependencies(Oid typeObjectId, + Form_pg_type typeForm, Node *defaultExpr, + void *typacl, + char relationKind, /* only for relation rowtypes */ + bool isImplicitArray, + bool isDependentType, bool rebuild) { ObjectAddress myself, @@ -542,79 +558,80 @@ GenerateTypeDependencies(Oid typeNamespace, myself.objectSubId = 0; /* - * Make dependencies on namespace, owner, extension. + * Make dependencies on namespace, owner, ACL, extension. * - * For a relation rowtype (that's not a composite type), we should skip - * these because we'll depend on them indirectly through the pg_class - * entry. Likewise, skip for implicit arrays since we'll depend on them - * through the element type. + * Skip these for a dependent type, since it will have such dependencies + * indirectly through its depended-on type or relation. */ - if ((!OidIsValid(relationOid) || relationKind == RELKIND_COMPOSITE_TYPE) && - !isImplicitArray) + if (!isDependentType) { referenced.classId = NamespaceRelationId; - referenced.objectId = typeNamespace; + referenced.objectId = typeForm->typnamespace; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - recordDependencyOnOwner(TypeRelationId, typeObjectId, owner); + recordDependencyOnOwner(TypeRelationId, typeObjectId, + typeForm->typowner); + + recordDependencyOnNewAcl(TypeRelationId, typeObjectId, 0, + typeForm->typowner, typacl); recordDependencyOnCurrentExtension(&myself, rebuild); } /* Normal dependencies on the I/O functions */ - if (OidIsValid(inputProcedure)) + if (OidIsValid(typeForm->typinput)) { referenced.classId = ProcedureRelationId; - referenced.objectId = inputProcedure; + referenced.objectId = typeForm->typinput; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(outputProcedure)) + if (OidIsValid(typeForm->typoutput)) { referenced.classId = ProcedureRelationId; - referenced.objectId = outputProcedure; + referenced.objectId = typeForm->typoutput; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(receiveProcedure)) + if (OidIsValid(typeForm->typreceive)) { referenced.classId = ProcedureRelationId; - referenced.objectId = receiveProcedure; + referenced.objectId = typeForm->typreceive; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(sendProcedure)) + if (OidIsValid(typeForm->typsend)) { referenced.classId = ProcedureRelationId; - referenced.objectId = sendProcedure; + referenced.objectId = typeForm->typsend; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(typmodinProcedure)) + if (OidIsValid(typeForm->typmodin)) { referenced.classId = ProcedureRelationId; - referenced.objectId = typmodinProcedure; + referenced.objectId = typeForm->typmodin; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(typmodoutProcedure)) + if (OidIsValid(typeForm->typmodout)) { referenced.classId = ProcedureRelationId; - referenced.objectId = typmodoutProcedure; + referenced.objectId = typeForm->typmodout; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } - if (OidIsValid(analyzeProcedure)) + if (OidIsValid(typeForm->typanalyze)) { referenced.classId = ProcedureRelationId; - referenced.objectId = analyzeProcedure; + referenced.objectId = typeForm->typanalyze; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -628,10 +645,10 @@ GenerateTypeDependencies(Oid typeNamespace, * relation is, and not otherwise. And in the latter, of course we get the * opposite effect. */ - if (OidIsValid(relationOid)) + if (OidIsValid(typeForm->typrelid)) { referenced.classId = RelationRelationId; - referenced.objectId = relationOid; + referenced.objectId = typeForm->typrelid; referenced.objectSubId = 0; if (relationKind != RELKIND_COMPOSITE_TYPE) @@ -645,30 +662,31 @@ GenerateTypeDependencies(Oid typeNamespace, * dependent on the element type. Otherwise, if it has an element type, * the dependency is a normal one. */ - if (OidIsValid(elementType)) + if (OidIsValid(typeForm->typelem)) { referenced.classId = TypeRelationId; - referenced.objectId = elementType; + referenced.objectId = typeForm->typelem; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, isImplicitArray ? DEPENDENCY_INTERNAL : DEPENDENCY_NORMAL); } /* Normal dependency from a domain to its base type. */ - if (OidIsValid(baseType)) + if (OidIsValid(typeForm->typbasetype)) { referenced.classId = TypeRelationId; - referenced.objectId = baseType; + referenced.objectId = typeForm->typbasetype; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } /* Normal dependency from a domain to its collation. */ /* We know the default collation is pinned, so don't bother recording it */ - if (OidIsValid(typeCollation) && typeCollation != DEFAULT_COLLATION_OID) + if (OidIsValid(typeForm->typcollation) && + typeForm->typcollation != DEFAULT_COLLATION_OID) { referenced.classId = CollationRelationId; - referenced.objectId = typeCollation; + referenced.objectId = typeForm->typcollation; referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } @@ -696,7 +714,7 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) Oid arrayOid; Oid oldTypeOid; - pg_type_desc = heap_open(TypeRelationId, RowExclusiveLock); + pg_type_desc = table_open(TypeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tuple)) @@ -709,7 +727,7 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) arrayOid = typ->typarray; /* Check for a conflicting type name. */ - oldTypeOid = GetSysCacheOid2(TYPENAMENSP, + oldTypeOid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(newTypeName), ObjectIdGetDatum(typeNamespace)); @@ -739,7 +757,7 @@ RenameTypeInternal(Oid typeOid, const char *newTypeName, Oid typeNamespace) InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); heap_freetuple(tuple); - heap_close(pg_type_desc, RowExclusiveLock); + table_close(pg_type_desc, RowExclusiveLock); /* * If the type has an array type, recurse to handle that. But we don't @@ -774,7 +792,7 @@ makeArrayTypeName(const char *typeName, Oid typeNamespace) * The idea is to prepend underscores as needed until we make a name that * doesn't collide with anything... */ - pg_type_desc = heap_open(TypeRelationId, AccessShareLock); + pg_type_desc = table_open(TypeRelationId, AccessShareLock); for (i = 1; i < NAMEDATALEN - 1; i++) { @@ -792,7 +810,7 @@ makeArrayTypeName(const char *typeName, Oid typeNamespace) break; } - heap_close(pg_type_desc, AccessShareLock); + table_close(pg_type_desc, AccessShareLock); if (i >= NAMEDATALEN - 1) ereport(ERROR, diff --git a/src/backend/catalog/sql_features.txt b/src/backend/catalog/sql_features.txt index ca0409b83ea..9c68292a54d 100644 --- a/src/backend/catalog/sql_features.txt +++ b/src/backend/catalog/sql_features.txt @@ -29,6 +29,16 @@ B125 Routine language MUMPS NO B126 Routine language Pascal NO B127 Routine language PL/I NO B128 Routine language SQL NO +B200 Polymorphic table functions NO +B201 More than one PTF generic table parameter NO +B202 PTF Copartitioning NO +B203 More than one copartition specification NO +B204 PRUNE WHEN EMPTY NO +B205 Pass-through columns NO +B206 PTF descriptor parameters NO +B207 Cross products of partitionings NO +B208 PTF component procedure interface NO +B209 PTF extended names NO B211 Module language Ada: VARCHAR and NUMERIC support NO B221 Routine language Ada: VARCHAR and NUMERIC support NO E011 Numeric data types YES @@ -229,9 +239,9 @@ F311 Schema definition statement 02 CREATE TABLE for persistent base tables YES F311 Schema definition statement 03 CREATE VIEW YES F311 Schema definition statement 04 CREATE VIEW: WITH CHECK OPTION YES F311 Schema definition statement 05 GRANT statement YES -F312 MERGE statement YES also consider INSERT ... ON CONFLICT DO UPDATE -F313 Enhanced MERGE statement YES -F314 MERGE statement with DELETE branch YES +F312 MERGE statement NO consider INSERT ... ON CONFLICT DO UPDATE +F313 Enhanced MERGE statement NO +F314 MERGE statement with DELETE branch NO F321 User authorization YES F341 Usage tables NO no ROUTINE_*_USAGE tables F361 Subprogram support YES @@ -254,6 +264,7 @@ F401 Extended joined table 02 FULL OUTER JOIN YES F401 Extended joined table 04 CROSS JOIN YES F402 Named column joins for LOBs, arrays, and multisets YES F403 Partitioned joined tables NO +F404 Range variable for common column names NO F411 Time zone specification YES differences regarding literal interpretation F421 National character YES F431 Read-only scrollable cursors YES @@ -291,6 +302,7 @@ F651 Catalog name qualifiers YES F661 Simple tables YES F671 Subqueries in CHECK NO intentionally omitted F672 Retrospective check constraints YES +F673 Reads SQL-data routine invocations in CHECK constraints NO F690 Collation support YES but no character set support F692 Extended collation support YES F693 SQL-session and client module collations NO @@ -338,6 +350,9 @@ F864 Top-level in views YES F865 in YES F866 FETCH FIRST clause: PERCENT option NO F867 FETCH FIRST clause: WITH TIES option NO +R010 Row pattern recognition: FROM clause NO +R020 Row pattern recognition: WINDOW clause NO +R030 Row pattern recognition: full aggregate support NO S011 Distinct data types NO S011 Distinct data types 01 USER_DEFINED_TYPES view NO S023 Basic structured types NO @@ -404,10 +419,10 @@ T042 Extended LOB data type support NO T043 Multiplier T NO T044 Multiplier P NO T051 Row types NO -T052 MAX and MIN for row types NO T053 Explicit aliases for all-fields reference NO T061 UCS support NO T071 BIGINT data type YES +T076 DECFLOAT data type NO T101 Enhanced nullability determination NO T111 Updatable joins, unions, and columns NO T121 WITH (excluding RECURSIVE) in query expression YES @@ -443,7 +458,7 @@ T213 INSTEAD OF triggers YES T231 Sensitive cursors YES T241 START TRANSACTION statement YES T251 SET TRANSACTION statement: LOCAL option NO -T261 Chained transactions NO +T261 Chained transactions YES T271 Savepoints YES T272 Enhanced savepoint management NO T281 SELECT privilege with column granularity YES @@ -452,9 +467,9 @@ T301 Functional dependencies NO partially supported T312 OVERLAY function YES T321 Basic SQL-invoked routines NO T321 Basic SQL-invoked routines 01 User-defined functions with no overloading YES -T321 Basic SQL-invoked routines 02 User-defined stored procedures with no overloading NO +T321 Basic SQL-invoked routines 02 User-defined stored procedures with no overloading YES T321 Basic SQL-invoked routines 03 Function invocation YES -T321 Basic SQL-invoked routines 04 CALL statement NO +T321 Basic SQL-invoked routines 04 CALL statement YES T321 Basic SQL-invoked routines 05 RETURN statement NO T321 Basic SQL-invoked routines 06 ROUTINES view YES T321 Basic SQL-invoked routines 07 PARAMETERS view YES @@ -480,8 +495,11 @@ T495 Combined data change and retrieval NO different syntax T501 Enhanced EXISTS predicate YES T502 Period predicates NO T511 Transaction counts NO -T521 Named arguments in CALL statement NO +T521 Named arguments in CALL statement YES T522 Default values for IN parameters of SQL-invoked procedures NO supported except DEFAULT key word in invocation +T523 Default values for INOUT parameters of SQL-invoked procedures YES +T524 Named arguments in routine invocations other than a CALL statement YES +T525 Default values for parameters of SQL-invoked functions YES T551 Optional key words for default syntax YES T561 Holdable locators NO T571 Array-returning external SQL-invoked functions NO @@ -490,7 +508,7 @@ T581 Regular expression substring function YES T591 UNIQUE constraints of possibly null columns YES T601 Local cursor references NO T611 Elementary OLAP operations YES -T612 Advanced OLAP operations NO some forms supported +T612 Advanced OLAP operations YES T613 Sampling YES T614 NTILE function YES T615 LEAD and LAG functions YES @@ -500,6 +518,10 @@ T618 NTH_VALUE function NO function exists, but some options missing T619 Nested window functions NO T620 WINDOW clause: GROUPS option YES T621 Enhanced numeric functions YES +T622 Trigonometric functions YES +T623 General logarithm functions YES +T624 Common logarithm functions YES +T625 LISTAGG NO T631 IN predicate with one list element YES T641 Multiple column assignment NO only some syntax variants supported T651 SQL-schema statements in SQL routines YES @@ -507,6 +529,29 @@ T652 SQL-dynamic statements in SQL routines NO T653 SQL-schema statements in external routines NO T654 SQL-dynamic statements in external routines NO T655 Cyclically dependent routines YES +T811 Basic SQL/JSON constructor functions NO +T812 SQL/JSON: JSON_OBJECTAGG NO +T813 SQL/JSON: JSON_ARRAYAGG with ORDER BY NO +T814 Colon in JSON_OBJECT or JSON_OBJECTAGG NO +T821 Basic SQL/JSON query operators NO +T822 SQL/JSON: IS JSON WITH UNIQUE KEYS predicate NO +T823 SQL/JSON: PASSING clause NO +T824 JSON_TABLE: specific PLAN clause NO +T825 SQL/JSON: ON EMPTY and ON ERROR clauses NO +T826 General value expression in ON ERROR or ON EMPTY clauses NO +T827 JSON_TABLE: sibling NESTED COLUMNS clauses NO +T828 JSON_QUERY NO +T829 JSON_QUERY: array wrapper options NO +T830 Enforcing unique keys in SQL/JSON constructor functions NO +T831 SQL/JSON path language: strict mode YES +T832 SQL/JSON path language: item method YES +T833 SQL/JSON path language: multiple subscripts YES +T834 SQL/JSON path language: wildcard member accessor YES +T835 SQL/JSON path language: filter expressions YES +T836 SQL/JSON path language: starts with predicate YES +T837 SQL/JSON path language: regex_like predicate YES +T838 JSON_TABLE: PLAN DEFAULT clause NO +T839 Formatted cast of datetimes to/from character strings NO M001 Datalinks NO M002 Datalinks via SQL/CLI NO M003 Datalinks via Embedded SQL NO @@ -593,7 +638,7 @@ X085 Predefined namespace prefixes NO X086 XML namespace declarations in XMLTable NO X090 XML document predicate YES X091 XML content predicate NO -X096 XMLExists NO XPath only +X096 XMLExists NO XPath 1.0 only X100 Host language support for XML: CONTENT option NO X101 Host language support for XML: DOCUMENT option NO X110 Host language support for XML: VARCHAR mapping NO @@ -635,8 +680,8 @@ X204 XMLQuery: initializing an XQuery variable NO X205 XMLQuery: EMPTY ON EMPTY option NO X206 XMLQuery: NULL ON EMPTY option NO X211 XML 1.1 support NO -X221 XML passing mechanism BY VALUE NO -X222 XML passing mechanism BY REF YES +X221 XML passing mechanism BY VALUE YES +X222 XML passing mechanism BY REF NO parser accepts BY REF but ignores it; passing is always BY VALUE X231 XML(CONTENT(UNTYPED)) type NO X232 XML(CONTENT(ANY)) type NO X241 RETURNING CONTENT in XML publishing NO @@ -661,11 +706,11 @@ X282 XMLValidate with CONTENT option NO X283 XMLValidate with SEQUENCE option NO X284 XMLValidate: NAMESPACE without ELEMENT clause NO X286 XMLValidate: NO NAMESPACE with ELEMENT clause NO -X300 XMLTable NO XPath only +X300 XMLTable NO XPath 1.0 only X301 XMLTable: derived column list option YES X302 XMLTable: ordinality column option YES X303 XMLTable: column default option YES -X304 XMLTable: passing a context item YES +X304 XMLTable: passing a context item YES must be XML DOCUMENT X305 XMLTable: initializing an XQuery variable NO X400 Name and identifier mapping YES X410 Alter column data type: XML type YES diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index 5df4382b7e7..b8c9b6f9c68 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -3,7 +3,7 @@ * storage.c * code to create and destroy physical storage for relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,6 +19,8 @@ #include "postgres.h" +#include "miscadmin.h" + #include "access/visibilitymap.h" #include "access/xact.h" #include "access/xlog.h" @@ -73,7 +75,7 @@ static PendingRelDelete *pendingDeletes = NULL; /* head of linked list */ * This function is transactional. The creation is WAL-logged, and if the * transaction aborts later on, the storage will be destroyed. */ -void +SMgrRelation RelationCreateStorage(RelFileNode rnode, char relpersistence) { PendingRelDelete *pending; @@ -97,7 +99,7 @@ RelationCreateStorage(RelFileNode rnode, char relpersistence) break; default: elog(ERROR, "invalid relpersistence: %c", relpersistence); - return; /* placate compiler */ + return NULL; /* placate compiler */ } srel = smgropen(rnode, backend); @@ -115,13 +117,15 @@ RelationCreateStorage(RelFileNode rnode, char relpersistence) pending->nestLevel = GetCurrentTransactionNestLevel(); pending->next = pendingDeletes; pendingDeletes = pending; + + return srel; } /* * Perform XLogInsert of an XLOG_SMGR_CREATE record to WAL. */ void -log_smgrcreate(RelFileNode *rnode, ForkNumber forkNum) +log_smgrcreate(const RelFileNode *rnode, ForkNumber forkNum) { xl_smgr_create xlrec; @@ -227,6 +231,10 @@ RelationTruncate(Relation rel, BlockNumber nblocks) { bool fsm; bool vm; + bool need_fsm_vacuum = false; + ForkNumber forks[MAX_FORKNUM]; + BlockNumber blocks[MAX_FORKNUM]; + int nforks = 0; /* Open it at the smgr level if not already done */ RelationOpenSmgr(rel); @@ -238,15 +246,35 @@ RelationTruncate(Relation rel, BlockNumber nblocks) rel->rd_smgr->smgr_fsm_nblocks = InvalidBlockNumber; rel->rd_smgr->smgr_vm_nblocks = InvalidBlockNumber; - /* Truncate the FSM first if it exists */ + /* Prepare for truncation of MAIN fork of the relation */ + forks[nforks] = MAIN_FORKNUM; + blocks[nforks] = nblocks; + nforks++; + + /* Prepare for truncation of the FSM if it exists */ fsm = smgrexists(rel->rd_smgr, FSM_FORKNUM); if (fsm) - FreeSpaceMapTruncateRel(rel, nblocks); + { + blocks[nforks] = FreeSpaceMapPrepareTruncateRel(rel, nblocks); + if (BlockNumberIsValid(blocks[nforks])) + { + forks[nforks] = FSM_FORKNUM; + nforks++; + need_fsm_vacuum = true; + } + } - /* Truncate the visibility map too if it exists. */ + /* Prepare for truncation of the visibility map too if it exists */ vm = smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM); if (vm) - visibilitymap_truncate(rel, nblocks); + { + blocks[nforks] = visibilitymap_prepare_truncate(rel, nblocks); + if (BlockNumberIsValid(blocks[nforks])) + { + forks[nforks] = VISIBILITYMAP_FORKNUM; + nforks++; + } + } /* * We WAL-log the truncation before actually truncating, which means @@ -286,8 +314,106 @@ RelationTruncate(Relation rel, BlockNumber nblocks) XLogFlush(lsn); } - /* Do the real work */ - smgrtruncate(rel->rd_smgr, MAIN_FORKNUM, nblocks); + /* Do the real work to truncate relation forks */ + smgrtruncate(rel->rd_smgr, forks, nforks, blocks); + + /* + * Update upper-level FSM pages to account for the truncation. + * This is important because the just-truncated pages were likely + * marked as all-free, and would be preferentially selected. + */ + if (need_fsm_vacuum) + FreeSpaceMapVacuumRange(rel, nblocks, InvalidBlockNumber); +} + +/* + * Copy a fork's data, block by block. + * + * Note that this requires that there is no dirty data in shared buffers. If + * it's possible that there are, callers need to flush those using + * e.g. FlushRelationBuffers(rel). + */ +void +RelationCopyStorage(SMgrRelation src, SMgrRelation dst, + ForkNumber forkNum, char relpersistence) +{ + PGAlignedBlock buf; + Page page; + bool use_wal; + bool copying_initfork; + BlockNumber nblocks; + BlockNumber blkno; + + page = (Page) buf.data; + + /* + * The init fork for an unlogged relation in many respects has to be + * treated the same as normal relation, changes need to be WAL logged and + * it needs to be synced to disk. + */ + copying_initfork = relpersistence == RELPERSISTENCE_UNLOGGED && + forkNum == INIT_FORKNUM; + + /* + * We need to log the copied data in WAL iff WAL archiving/streaming is + * enabled AND it's a permanent relation. + */ + use_wal = XLogIsNeeded() && + (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork); + + nblocks = smgrnblocks(src, forkNum); + + for (blkno = 0; blkno < nblocks; blkno++) + { + /* If we got a cancel signal during the copy of the data, quit */ + CHECK_FOR_INTERRUPTS(); + + smgrread(src, forkNum, blkno, buf.data); + + if (!PageIsVerified(page, blkno)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("invalid page in block %u of relation %s", + blkno, + relpathbackend(src->smgr_rnode.node, + src->smgr_rnode.backend, + forkNum)))); + + /* + * WAL-log the copied page. Unfortunately we don't know what kind of a + * page this is, so we have to log the full page including any unused + * space. + */ + if (use_wal) + log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false); + + PageSetChecksumInplace(page, blkno); + + /* + * Now write the page. We say isTemp = true even if it's not a temp + * rel, because there's no need for smgr to schedule an fsync for this + * write; we'll do it ourselves below. + */ + smgrextend(dst, forkNum, blkno, buf.data, true); + } + + /* + * If the rel is WAL-logged, must fsync before commit. We use heap_sync + * to ensure that the toast table gets fsync'd too. (For a temp or + * unlogged rel we don't care since the data will be gone after a crash + * anyway.) + * + * It's obvious that we must do this when not WAL-logging the copy. It's + * less obvious that we have to do it even if we did WAL-log the copied + * pages. The reason is that since we're copying outside shared buffers, a + * CHECKPOINT occurring during the copy has no way to flush the previously + * written data to disk (indeed it won't know the new rel even exists). A + * crash later on would replay WAL from the checkpoint, therefore it + * wouldn't replay our earlier WAL entries. If we do not fsync those pages + * here, they might still not be on disk when the crash occurs. + */ + if (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork) + smgrimmedsync(dst, forkNum); } /* @@ -494,6 +620,10 @@ smgr_redo(XLogReaderState *record) xl_smgr_truncate *xlrec = (xl_smgr_truncate *) XLogRecGetData(record); SMgrRelation reln; Relation rel; + ForkNumber forks[MAX_FORKNUM]; + BlockNumber blocks[MAX_FORKNUM]; + int nforks = 0; + bool need_fsm_vacuum = false; reln = smgropen(xlrec->rnode, InvalidBackendId); @@ -522,23 +652,54 @@ smgr_redo(XLogReaderState *record) */ XLogFlush(lsn); + /* Prepare for truncation of MAIN fork */ if ((xlrec->flags & SMGR_TRUNCATE_HEAP) != 0) { - smgrtruncate(reln, MAIN_FORKNUM, xlrec->blkno); + forks[nforks] = MAIN_FORKNUM; + blocks[nforks] = xlrec->blkno; + nforks++; /* Also tell xlogutils.c about it */ XLogTruncateRelation(xlrec->rnode, MAIN_FORKNUM, xlrec->blkno); } - /* Truncate FSM and VM too */ + /* Prepare for truncation of FSM and VM too */ rel = CreateFakeRelcacheEntry(xlrec->rnode); if ((xlrec->flags & SMGR_TRUNCATE_FSM) != 0 && smgrexists(reln, FSM_FORKNUM)) - FreeSpaceMapTruncateRel(rel, xlrec->blkno); + { + blocks[nforks] = FreeSpaceMapPrepareTruncateRel(rel, xlrec->blkno); + if (BlockNumberIsValid(blocks[nforks])) + { + forks[nforks] = FSM_FORKNUM; + nforks++; + need_fsm_vacuum = true; + } + } if ((xlrec->flags & SMGR_TRUNCATE_VM) != 0 && smgrexists(reln, VISIBILITYMAP_FORKNUM)) - visibilitymap_truncate(rel, xlrec->blkno); + { + blocks[nforks] = visibilitymap_prepare_truncate(rel, xlrec->blkno); + if (BlockNumberIsValid(blocks[nforks])) + { + forks[nforks] = VISIBILITYMAP_FORKNUM; + nforks++; + } + } + + /* Do the real work to truncate relation forks */ + if (nforks > 0) + smgrtruncate(reln, forks, nforks, blocks); + + /* + * Update upper-level FSM pages to account for the truncation. + * This is important because the just-truncated pages were likely + * marked as all-free, and would be preferentially selected. + */ + if (need_fsm_vacuum) + FreeSpaceMapVacuumRange(rel, xlrec->blkno, + InvalidBlockNumber); FreeFakeRelcacheEntry(rel); } diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 8cd8bf40ac4..9fe4a4794a0 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1,7 +1,7 @@ /* * PostgreSQL System Views * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/backend/catalog/system_views.sql * @@ -41,7 +41,7 @@ CREATE VIEW pg_shadow AS rolreplication AS userepl, rolbypassrls AS usebypassrls, rolpassword AS passwd, - rolvaliduntil::abstime AS valuntil, + rolvaliduntil AS valuntil, setconfig AS useconfig FROM pg_authid LEFT JOIN pg_db_role_setting s ON (pg_authid.oid = setrole AND setdatabase = 0) @@ -162,7 +162,7 @@ CREATE VIEW pg_indexes AS JOIN pg_class I ON (I.oid = X.indexrelid) LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) LEFT JOIN pg_tablespace T ON (T.oid = I.reltablespace) - WHERE C.relkind IN ('r', 'm') AND I.relkind = 'i'; + WHERE C.relkind IN ('r', 'm', 'p') AND I.relkind IN ('i', 'I'); CREATE OR REPLACE VIEW pg_sequences AS SELECT @@ -253,14 +253,55 @@ CREATE VIEW pg_stats WITH (security_barrier) AS REVOKE ALL on pg_statistic FROM public; +CREATE VIEW pg_stats_ext WITH (security_barrier) AS + SELECT cn.nspname AS schemaname, + c.relname AS tablename, + sn.nspname AS statistics_schemaname, + s.stxname AS statistics_name, + pg_get_userbyid(s.stxowner) AS statistics_owner, + ( SELECT array_agg(a.attname ORDER BY a.attnum) + FROM unnest(s.stxkeys) k + JOIN pg_attribute a + ON (a.attrelid = s.stxrelid AND a.attnum = k) + ) AS attnames, + s.stxkind AS kinds, + sd.stxdndistinct AS n_distinct, + sd.stxddependencies AS dependencies, + m.most_common_vals, + m.most_common_val_nulls, + m.most_common_freqs, + m.most_common_base_freqs + FROM pg_statistic_ext s JOIN pg_class c ON (c.oid = s.stxrelid) + JOIN pg_statistic_ext_data sd ON (s.oid = sd.stxoid) + LEFT JOIN pg_namespace cn ON (cn.oid = c.relnamespace) + LEFT JOIN pg_namespace sn ON (sn.oid = s.stxnamespace) + LEFT JOIN LATERAL + ( SELECT array_agg(values) AS most_common_vals, + array_agg(nulls) AS most_common_val_nulls, + array_agg(frequency) AS most_common_freqs, + array_agg(base_frequency) AS most_common_base_freqs + FROM pg_mcv_list_items(sd.stxdmcv) + ) m ON sd.stxdmcv IS NOT NULL + WHERE NOT EXISTS + ( SELECT 1 + FROM unnest(stxkeys) k + JOIN pg_attribute a + ON (a.attrelid = s.stxrelid AND a.attnum = k) + WHERE NOT has_column_privilege(c.oid, a.attnum, 'select') ) + AND (c.relrowsecurity = false OR NOT row_security_active(c.oid)); + +-- unprivileged users may read pg_statistic_ext but not pg_statistic_ext_data +REVOKE ALL on pg_statistic_ext_data FROM public; + CREATE VIEW pg_publication_tables AS SELECT P.pubname AS pubname, N.nspname AS schemaname, C.relname AS tablename - FROM pg_publication P, pg_class C - JOIN pg_namespace N ON (N.oid = C.relnamespace) - WHERE C.oid IN (SELECT relid FROM pg_get_publication_tables(P.pubname)); + FROM pg_publication P, + LATERAL pg_get_publication_tables(P.pubname) GPT, + pg_class C JOIN pg_namespace N ON (N.oid = C.relnamespace) + WHERE C.oid = GPT.relid; CREATE VIEW pg_locks AS SELECT * FROM pg_lock_status() AS L; @@ -293,180 +334,180 @@ CREATE VIEW pg_prepared_statements AS CREATE VIEW pg_seclabels AS SELECT - l.objoid, l.classoid, l.objsubid, - CASE WHEN rel.relkind IN ('r', 'p') THEN 'table'::text - WHEN rel.relkind = 'v' THEN 'view'::text - WHEN rel.relkind = 'm' THEN 'materialized view'::text - WHEN rel.relkind = 'S' THEN 'sequence'::text - WHEN rel.relkind = 'f' THEN 'foreign table'::text END AS objtype, - rel.relnamespace AS objnamespace, - CASE WHEN pg_table_is_visible(rel.oid) - THEN quote_ident(rel.relname) - ELSE quote_ident(nsp.nspname) || '.' || quote_ident(rel.relname) - END AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + CASE WHEN rel.relkind IN ('r', 'p') THEN 'table'::text + WHEN rel.relkind = 'v' THEN 'view'::text + WHEN rel.relkind = 'm' THEN 'materialized view'::text + WHEN rel.relkind = 'S' THEN 'sequence'::text + WHEN rel.relkind = 'f' THEN 'foreign table'::text END AS objtype, + rel.relnamespace AS objnamespace, + CASE WHEN pg_table_is_visible(rel.oid) + THEN quote_ident(rel.relname) + ELSE quote_ident(nsp.nspname) || '.' || quote_ident(rel.relname) + END AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_class rel ON l.classoid = rel.tableoid AND l.objoid = rel.oid - JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + pg_seclabel l + JOIN pg_class rel ON l.classoid = rel.tableoid AND l.objoid = rel.oid + JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'column'::text AS objtype, - rel.relnamespace AS objnamespace, - CASE WHEN pg_table_is_visible(rel.oid) - THEN quote_ident(rel.relname) - ELSE quote_ident(nsp.nspname) || '.' || quote_ident(rel.relname) - END || '.' || att.attname AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'column'::text AS objtype, + rel.relnamespace AS objnamespace, + CASE WHEN pg_table_is_visible(rel.oid) + THEN quote_ident(rel.relname) + ELSE quote_ident(nsp.nspname) || '.' || quote_ident(rel.relname) + END || '.' || att.attname AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_class rel ON l.classoid = rel.tableoid AND l.objoid = rel.oid - JOIN pg_attribute att - ON rel.oid = att.attrelid AND l.objsubid = att.attnum - JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid + pg_seclabel l + JOIN pg_class rel ON l.classoid = rel.tableoid AND l.objoid = rel.oid + JOIN pg_attribute att + ON rel.oid = att.attrelid AND l.objsubid = att.attnum + JOIN pg_namespace nsp ON rel.relnamespace = nsp.oid WHERE - l.objsubid != 0 + l.objsubid != 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - CASE pro.prokind + l.objoid, l.classoid, l.objsubid, + CASE pro.prokind WHEN 'a' THEN 'aggregate'::text WHEN 'f' THEN 'function'::text WHEN 'p' THEN 'procedure'::text WHEN 'w' THEN 'window'::text END AS objtype, - pro.pronamespace AS objnamespace, - CASE WHEN pg_function_is_visible(pro.oid) - THEN quote_ident(pro.proname) - ELSE quote_ident(nsp.nspname) || '.' || quote_ident(pro.proname) - END || '(' || pg_catalog.pg_get_function_arguments(pro.oid) || ')' AS objname, - l.provider, l.label + pro.pronamespace AS objnamespace, + CASE WHEN pg_function_is_visible(pro.oid) + THEN quote_ident(pro.proname) + ELSE quote_ident(nsp.nspname) || '.' || quote_ident(pro.proname) + END || '(' || pg_catalog.pg_get_function_arguments(pro.oid) || ')' AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_proc pro ON l.classoid = pro.tableoid AND l.objoid = pro.oid - JOIN pg_namespace nsp ON pro.pronamespace = nsp.oid + pg_seclabel l + JOIN pg_proc pro ON l.classoid = pro.tableoid AND l.objoid = pro.oid + JOIN pg_namespace nsp ON pro.pronamespace = nsp.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - CASE WHEN typ.typtype = 'd' THEN 'domain'::text - ELSE 'type'::text END AS objtype, - typ.typnamespace AS objnamespace, - CASE WHEN pg_type_is_visible(typ.oid) - THEN quote_ident(typ.typname) - ELSE quote_ident(nsp.nspname) || '.' || quote_ident(typ.typname) - END AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + CASE WHEN typ.typtype = 'd' THEN 'domain'::text + ELSE 'type'::text END AS objtype, + typ.typnamespace AS objnamespace, + CASE WHEN pg_type_is_visible(typ.oid) + THEN quote_ident(typ.typname) + ELSE quote_ident(nsp.nspname) || '.' || quote_ident(typ.typname) + END AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_type typ ON l.classoid = typ.tableoid AND l.objoid = typ.oid - JOIN pg_namespace nsp ON typ.typnamespace = nsp.oid + pg_seclabel l + JOIN pg_type typ ON l.classoid = typ.tableoid AND l.objoid = typ.oid + JOIN pg_namespace nsp ON typ.typnamespace = nsp.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'large object'::text AS objtype, - NULL::oid AS objnamespace, - l.objoid::text AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'large object'::text AS objtype, + NULL::oid AS objnamespace, + l.objoid::text AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_largeobject_metadata lom ON l.objoid = lom.oid + pg_seclabel l + JOIN pg_largeobject_metadata lom ON l.objoid = lom.oid WHERE - l.classoid = 'pg_catalog.pg_largeobject'::regclass AND l.objsubid = 0 + l.classoid = 'pg_catalog.pg_largeobject'::regclass AND l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'language'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(lan.lanname) AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'language'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(lan.lanname) AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_language lan ON l.classoid = lan.tableoid AND l.objoid = lan.oid + pg_seclabel l + JOIN pg_language lan ON l.classoid = lan.tableoid AND l.objoid = lan.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'schema'::text AS objtype, - nsp.oid AS objnamespace, - quote_ident(nsp.nspname) AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'schema'::text AS objtype, + nsp.oid AS objnamespace, + quote_ident(nsp.nspname) AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_namespace nsp ON l.classoid = nsp.tableoid AND l.objoid = nsp.oid + pg_seclabel l + JOIN pg_namespace nsp ON l.classoid = nsp.tableoid AND l.objoid = nsp.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'event trigger'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(evt.evtname) AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'event trigger'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(evt.evtname) AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_event_trigger evt ON l.classoid = evt.tableoid - AND l.objoid = evt.oid + pg_seclabel l + JOIN pg_event_trigger evt ON l.classoid = evt.tableoid + AND l.objoid = evt.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, l.objsubid, - 'publication'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(p.pubname) AS objname, - l.provider, l.label + l.objoid, l.classoid, l.objsubid, + 'publication'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(p.pubname) AS objname, + l.provider, l.label FROM - pg_seclabel l - JOIN pg_publication p ON l.classoid = p.tableoid AND l.objoid = p.oid + pg_seclabel l + JOIN pg_publication p ON l.classoid = p.tableoid AND l.objoid = p.oid WHERE - l.objsubid = 0 + l.objsubid = 0 UNION ALL SELECT - l.objoid, l.classoid, 0::int4 AS objsubid, - 'subscription'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(s.subname) AS objname, - l.provider, l.label + l.objoid, l.classoid, 0::int4 AS objsubid, + 'subscription'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(s.subname) AS objname, + l.provider, l.label FROM - pg_shseclabel l - JOIN pg_subscription s ON l.classoid = s.tableoid AND l.objoid = s.oid + pg_shseclabel l + JOIN pg_subscription s ON l.classoid = s.tableoid AND l.objoid = s.oid UNION ALL SELECT - l.objoid, l.classoid, 0::int4 AS objsubid, - 'database'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(dat.datname) AS objname, - l.provider, l.label + l.objoid, l.classoid, 0::int4 AS objsubid, + 'database'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(dat.datname) AS objname, + l.provider, l.label FROM - pg_shseclabel l - JOIN pg_database dat ON l.classoid = dat.tableoid AND l.objoid = dat.oid + pg_shseclabel l + JOIN pg_database dat ON l.classoid = dat.tableoid AND l.objoid = dat.oid UNION ALL SELECT - l.objoid, l.classoid, 0::int4 AS objsubid, - 'tablespace'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(spc.spcname) AS objname, - l.provider, l.label + l.objoid, l.classoid, 0::int4 AS objsubid, + 'tablespace'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(spc.spcname) AS objname, + l.provider, l.label FROM - pg_shseclabel l - JOIN pg_tablespace spc ON l.classoid = spc.tableoid AND l.objoid = spc.oid + pg_shseclabel l + JOIN pg_tablespace spc ON l.classoid = spc.tableoid AND l.objoid = spc.oid UNION ALL SELECT - l.objoid, l.classoid, 0::int4 AS objsubid, - 'role'::text AS objtype, - NULL::oid AS objnamespace, - quote_ident(rol.rolname) AS objname, - l.provider, l.label + l.objoid, l.classoid, 0::int4 AS objsubid, + 'role'::text AS objtype, + NULL::oid AS objnamespace, + quote_ident(rol.rolname) AS objname, + l.provider, l.label FROM - pg_shseclabel l - JOIN pg_authid rol ON l.classoid = rol.tableoid AND l.objoid = rol.oid; + pg_shseclabel l + JOIN pg_authid rol ON l.classoid = rol.tableoid AND l.objoid = rol.oid; CREATE VIEW pg_settings AS SELECT * FROM pg_show_all_settings() AS A; @@ -734,7 +775,8 @@ CREATE VIEW pg_stat_replication AS W.flush_lag, W.replay_lag, W.sync_priority, - W.sync_state + W.sync_state, + W.reply_time FROM pg_stat_get_activity(NULL) AS S JOIN pg_stat_get_wal_senders() AS W ON (S.pid = W.pid) LEFT JOIN pg_authid AS U ON (S.usesysid = U.oid); @@ -781,7 +823,17 @@ CREATE VIEW pg_stat_ssl AS S.sslcipher AS cipher, S.sslbits AS bits, S.sslcompression AS compression, - S.sslclientdn AS clientdn + S.ssl_client_dn AS client_dn, + S.ssl_client_serial AS client_serial, + S.ssl_issuer_dn AS issuer_dn + FROM pg_stat_get_activity(NULL) AS S; + +CREATE VIEW pg_stat_gssapi AS + SELECT + S.pid, + S.gss_auth AS gss_authenticated, + S.gss_princ AS principal, + S.gss_enc AS encrypted FROM pg_stat_get_activity(NULL) AS S; CREATE VIEW pg_replication_slots AS @@ -805,7 +857,10 @@ CREATE VIEW pg_stat_database AS SELECT D.oid AS datid, D.datname AS datname, - pg_stat_get_db_numbackends(D.oid) AS numbackends, + CASE + WHEN (D.oid = (0)::oid) THEN 0 + ELSE pg_stat_get_db_numbackends(D.oid) + END AS numbackends, pg_stat_get_db_xact_commit(D.oid) AS xact_commit, pg_stat_get_db_xact_rollback(D.oid) AS xact_rollback, pg_stat_get_db_blocks_fetched(D.oid) - @@ -820,10 +875,16 @@ CREATE VIEW pg_stat_database AS pg_stat_get_db_temp_files(D.oid) AS temp_files, pg_stat_get_db_temp_bytes(D.oid) AS temp_bytes, pg_stat_get_db_deadlocks(D.oid) AS deadlocks, + pg_stat_get_db_checksum_failures(D.oid) AS checksum_failures, + pg_stat_get_db_checksum_last_failure(D.oid) AS checksum_last_failure, pg_stat_get_db_blk_read_time(D.oid) AS blk_read_time, pg_stat_get_db_blk_write_time(D.oid) AS blk_write_time, pg_stat_get_db_stat_reset_time(D.oid) AS stats_reset - FROM pg_database D; + FROM ( + SELECT 0 AS oid, NULL::name AS datname + UNION ALL + SELECT oid, datname FROM pg_database + ) D; CREATE VIEW pg_stat_database_conflicts AS SELECT @@ -886,22 +947,84 @@ CREATE VIEW pg_stat_bgwriter AS pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; CREATE VIEW pg_stat_progress_vacuum AS - SELECT - S.pid AS pid, S.datid AS datid, D.datname AS datname, - S.relid AS relid, - CASE S.param1 WHEN 0 THEN 'initializing' - WHEN 1 THEN 'scanning heap' - WHEN 2 THEN 'vacuuming indexes' - WHEN 3 THEN 'vacuuming heap' - WHEN 4 THEN 'cleaning up indexes' - WHEN 5 THEN 'truncating heap' - WHEN 6 THEN 'performing final cleanup' - END AS phase, - S.param2 AS heap_blks_total, S.param3 AS heap_blks_scanned, - S.param4 AS heap_blks_vacuumed, S.param5 AS index_vacuum_count, - S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples + SELECT + S.pid AS pid, S.datid AS datid, D.datname AS datname, + S.relid AS relid, + CASE S.param1 WHEN 0 THEN 'initializing' + WHEN 1 THEN 'scanning heap' + WHEN 2 THEN 'vacuuming indexes' + WHEN 3 THEN 'vacuuming heap' + WHEN 4 THEN 'cleaning up indexes' + WHEN 5 THEN 'truncating heap' + WHEN 6 THEN 'performing final cleanup' + END AS phase, + S.param2 AS heap_blks_total, S.param3 AS heap_blks_scanned, + S.param4 AS heap_blks_vacuumed, S.param5 AS index_vacuum_count, + S.param6 AS max_dead_tuples, S.param7 AS num_dead_tuples FROM pg_stat_get_progress_info('VACUUM') AS S - LEFT JOIN pg_database D ON S.datid = D.oid; + LEFT JOIN pg_database D ON S.datid = D.oid; + +CREATE VIEW pg_stat_progress_cluster AS + SELECT + S.pid AS pid, + S.datid AS datid, + D.datname AS datname, + S.relid AS relid, + CASE S.param1 WHEN 1 THEN 'CLUSTER' + WHEN 2 THEN 'VACUUM FULL' + END AS command, + CASE S.param2 WHEN 0 THEN 'initializing' + WHEN 1 THEN 'seq scanning heap' + WHEN 2 THEN 'index scanning heap' + WHEN 3 THEN 'sorting tuples' + WHEN 4 THEN 'writing new heap' + WHEN 5 THEN 'swapping relation files' + WHEN 6 THEN 'rebuilding index' + WHEN 7 THEN 'performing final cleanup' + END AS phase, + CAST(S.param3 AS oid) AS cluster_index_relid, + S.param4 AS heap_tuples_scanned, + S.param5 AS heap_tuples_written, + S.param6 AS heap_blks_total, + S.param7 AS heap_blks_scanned, + S.param8 AS index_rebuild_count + FROM pg_stat_get_progress_info('CLUSTER') AS S + LEFT JOIN pg_database D ON S.datid = D.oid; + +CREATE VIEW pg_stat_progress_create_index AS + SELECT + S.pid AS pid, S.datid AS datid, D.datname AS datname, + S.relid AS relid, + CAST(S.param7 AS oid) AS index_relid, + CASE S.param1 WHEN 1 THEN 'CREATE INDEX' + WHEN 2 THEN 'CREATE INDEX CONCURRENTLY' + WHEN 3 THEN 'REINDEX' + WHEN 4 THEN 'REINDEX CONCURRENTLY' + END AS command, + CASE S.param10 WHEN 0 THEN 'initializing' + WHEN 1 THEN 'waiting for writers before build' + WHEN 2 THEN 'building index' || + COALESCE((': ' || pg_indexam_progress_phasename(S.param9::oid, S.param11)), + '') + WHEN 3 THEN 'waiting for writers before validation' + WHEN 4 THEN 'index validation: scanning index' + WHEN 5 THEN 'index validation: sorting tuples' + WHEN 6 THEN 'index validation: scanning table' + WHEN 7 THEN 'waiting for old snapshots' + WHEN 8 THEN 'waiting for readers before marking dead' + WHEN 9 THEN 'waiting for readers before dropping' + END as phase, + S.param4 AS lockers_total, + S.param5 AS lockers_done, + S.param6 AS current_locker_pid, + S.param16 AS blocks_total, + S.param17 AS blocks_done, + S.param12 AS tuples_total, + S.param13 AS tuples_done, + S.param14 AS partitions_total, + S.param15 AS partitions_done + FROM pg_stat_get_progress_info('CREATE INDEX') AS S + LEFT JOIN pg_database D ON S.datid = D.oid; CREATE VIEW pg_user_mappings AS SELECT @@ -1027,6 +1150,11 @@ CREATE OR REPLACE FUNCTION pg_stop_backup ( RETURNS SETOF record STRICT VOLATILE LANGUAGE internal as 'pg_stop_backup_v2' PARALLEL RESTRICTED; +CREATE OR REPLACE FUNCTION + pg_promote(wait boolean DEFAULT true, wait_seconds integer DEFAULT 60) + RETURNS boolean STRICT VOLATILE LANGUAGE INTERNAL AS 'pg_promote' + PARALLEL SAFE; + -- legacy definition for compatibility with 9.3 CREATE OR REPLACE FUNCTION json_populate_record(base anyelement, from_json json, use_json_as_text boolean DEFAULT false) @@ -1081,7 +1209,7 @@ AS 'pg_create_physical_replication_slot'; CREATE OR REPLACE FUNCTION pg_create_logical_replication_slot( IN slot_name name, IN plugin name, IN temporary boolean DEFAULT false, - OUT slot_name text, OUT lsn pg_lsn) + OUT slot_name name, OUT lsn pg_lsn) RETURNS RECORD LANGUAGE INTERNAL STRICT VOLATILE @@ -1119,6 +1247,86 @@ LANGUAGE INTERNAL STRICT IMMUTABLE PARALLEL SAFE AS 'jsonb_insert'; +CREATE OR REPLACE FUNCTION + jsonb_path_exists(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_exists'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_match'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_array'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT IMMUTABLE PARALLEL SAFE +AS 'jsonb_path_query_first'; + +CREATE OR REPLACE FUNCTION + jsonb_path_exists_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_exists_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_match_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS boolean +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_match_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS SETOF jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_array_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_array_tz'; + +CREATE OR REPLACE FUNCTION + jsonb_path_query_first_tz(target jsonb, path jsonpath, vars jsonb DEFAULT '{}', + silent boolean DEFAULT false) +RETURNS jsonb +LANGUAGE INTERNAL +STRICT STABLE PARALLEL SAFE +AS 'jsonb_path_query_first_tz'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather @@ -1138,6 +1346,7 @@ REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public; REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public; REVOKE EXECUTE ON FUNCTION pg_current_logfile() FROM public; REVOKE EXECUTE ON FUNCTION pg_current_logfile(text) FROM public; +REVOKE EXECUTE ON FUNCTION pg_promote(boolean, integer) FROM public; REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public; REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public; @@ -1150,6 +1359,9 @@ REVOKE EXECUTE ON FUNCTION lo_export(oid, text) FROM public; REVOKE EXECUTE ON FUNCTION pg_ls_logdir() FROM public; REVOKE EXECUTE ON FUNCTION pg_ls_waldir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_archive_statusdir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir() FROM public; +REVOKE EXECUTE ON FUNCTION pg_ls_tmpdir(oid) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_file(text) FROM public; REVOKE EXECUTE ON FUNCTION pg_read_file(text,bigint,bigint) FROM public; @@ -1170,6 +1382,9 @@ REVOKE EXECUTE ON FUNCTION pg_ls_dir(text,boolean,boolean) FROM public; -- GRANT EXECUTE ON FUNCTION pg_ls_logdir() TO pg_monitor; GRANT EXECUTE ON FUNCTION pg_ls_waldir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_archive_statusdir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir() TO pg_monitor; +GRANT EXECUTE ON FUNCTION pg_ls_tmpdir(oid) TO pg_monitor; GRANT pg_read_all_settings TO pg_monitor; GRANT pg_read_all_stats TO pg_monitor; diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 9fb2e6b06e8..de6282a6675 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -4,7 +4,7 @@ * This file contains routines to support creation of toast tables * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,9 +14,10 @@ */ #include "postgres.h" -#include "access/tuptoaster.h" +#include "access/heapam.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" @@ -37,9 +38,9 @@ Oid binary_upgrade_next_toast_pg_type_oid = InvalidOid; static void CheckAndCreateToastTable(Oid relOid, Datum reloptions, - LOCKMODE lockmode, bool check); + LOCKMODE lockmode, bool check); static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, - Datum reloptions, LOCKMODE lockmode, bool check); + Datum reloptions, LOCKMODE lockmode, bool check); static bool needs_toast_table(Relation rel); @@ -78,12 +79,12 @@ CheckAndCreateToastTable(Oid relOid, Datum reloptions, LOCKMODE lockmode, bool c { Relation rel; - rel = heap_open(relOid, lockmode); + rel = table_open(relOid, lockmode); /* create_toast_table does all the work */ (void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions, lockmode, check); - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* @@ -96,7 +97,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) { Relation rel; - rel = heap_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock); + rel = table_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_MATVIEW) @@ -111,7 +112,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) elog(ERROR, "\"%s\" does not require a toast table", relName); - heap_close(rel, NoLock); + table_close(rel, NoLock); } @@ -145,21 +146,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, ObjectAddress baseobject, toastobject; - /* - * Toast table is shared if and only if its parent is. - * - * We cannot allow toasting a shared relation after initdb (because - * there's no way to mark it toasted in other databases' pg_class). - */ - shared_relation = rel->rd_rel->relisshared; - if (shared_relation && !IsBootstrapProcessingMode()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("shared tables cannot be toasted after initdb"))); - - /* It's mapped if and only if its parent is, too */ - mapped_relation = RelationIsMapped(rel); - /* * Is it already toasted? */ @@ -216,7 +202,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, "pg_toast_%u_index", relOid); /* this is pretty painful... need a tuple descriptor */ - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "chunk_id", OIDOID, @@ -259,6 +245,12 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, binary_upgrade_next_toast_pg_type_oid = InvalidOid; } + /* Toast table is shared if and only if its parent is. */ + shared_relation = rel->rd_rel->relisshared; + + /* It's mapped if and only if its parent is, too */ + mapped_relation = RelationIsMapped(rel); + toast_relid = heap_create_with_catalog(toast_relname, namespaceid, rel->rd_rel->reltablespace, @@ -266,14 +258,13 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, toast_typid, InvalidOid, rel->rd_rel->relowner, + rel->rd_rel->relam, tupdesc, NIL, RELKIND_TOASTVALUE, rel->rd_rel->relpersistence, shared_relation, mapped_relation, - true, - 0, ONCOMMIT_NOOP, reloptions, false, @@ -283,11 +274,11 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, NULL); Assert(toast_relid != InvalidOid); - /* make the toast relation visible, else heap_open will fail */ + /* make the toast relation visible, else table_open will fail */ CommandCounterIncrement(); /* ShareLock is not really needed here, but take it anyway */ - toast_rel = heap_open(toast_relid, ShareLock); + toast_rel = table_open(toast_relid, ShareLock); /* * Create unique index on chunk_id, chunk_seq. @@ -304,8 +295,8 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, indexInfo = makeNode(IndexInfo); indexInfo->ii_NumIndexAttrs = 2; indexInfo->ii_NumIndexKeyAttrs = 2; - indexInfo->ii_KeyAttrNumbers[0] = 1; - indexInfo->ii_KeyAttrNumbers[1] = 2; + indexInfo->ii_IndexAttrNumbers[0] = 1; + indexInfo->ii_IndexAttrNumbers[1] = 2; indexInfo->ii_Expressions = NIL; indexInfo->ii_ExpressionsState = NIL; indexInfo->ii_Predicate = NIL; @@ -340,12 +331,12 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, collationObjectId, classObjectId, coloptions, (Datum) 0, INDEX_CREATE_IS_PRIMARY, 0, true, true, NULL); - heap_close(toast_rel, NoLock); + table_close(toast_rel, NoLock); /* * Store the toast table's OID in the parent relation's pg_class row */ - class_rel = heap_open(RelationRelationId, RowExclusiveLock); + class_rel = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid)); if (!HeapTupleIsValid(reltup)) @@ -366,7 +357,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, heap_freetuple(reltup); - heap_close(class_rel, RowExclusiveLock); + table_close(class_rel, RowExclusiveLock); /* * Register dependency from the toast table to the master, so that the @@ -394,58 +385,33 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, } /* - * Check to see whether the table needs a TOAST table. It does only if - * (1) there are any toastable attributes, and (2) the maximum length - * of a tuple could exceed TOAST_TUPLE_THRESHOLD. (We don't want to - * create a toast table for something like "f1 varchar(20)".) - * No need to create a TOAST table for partitioned tables. + * Check to see whether the table needs a TOAST table. */ static bool needs_toast_table(Relation rel) { - int32 data_length = 0; - bool maxlength_unknown = false; - bool has_toastable_attrs = false; - TupleDesc tupdesc; - int32 tuple_length; - int i; - + /* + * No need to create a TOAST table for partitioned tables. + */ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) return false; - tupdesc = rel->rd_att; + /* + * We cannot allow toasting a shared relation after initdb (because + * there's no way to mark it toasted in other databases' pg_class). + */ + if (rel->rd_rel->relisshared && !IsBootstrapProcessingMode()) + return false; + + /* + * Ignore attempts to create toast tables on catalog tables after initdb. + * Which catalogs get toast tables is explicitly chosen in + * catalog/toasting.h. (We could get here via some ALTER TABLE command if + * the catalog doesn't have a toast table.) + */ + if (IsCatalogRelation(rel) && !IsBootstrapProcessingMode()) + return false; - for (i = 0; i < tupdesc->natts; i++) - { - Form_pg_attribute att = TupleDescAttr(tupdesc, i); - - if (att->attisdropped) - continue; - data_length = att_align_nominal(data_length, att->attalign); - if (att->attlen > 0) - { - /* Fixed-length types are never toastable */ - data_length += att->attlen; - } - else - { - int32 maxlen = type_maximum_size(att->atttypid, - att->atttypmod); - - if (maxlen < 0) - maxlength_unknown = true; - else - data_length += maxlen; - if (att->attstorage != 'p') - has_toastable_attrs = true; - } - } - if (!has_toastable_attrs) - return false; /* nothing to toast? */ - if (maxlength_unknown) - return true; /* any unlimited-length attrs? */ - tuple_length = MAXALIGN(SizeofHeapTupleHeader + - BITMAPLEN(tupdesc->natts)) + - MAXALIGN(data_length); - return (tuple_length > TOAST_TUPLE_THRESHOLD); + /* Otherwise, let the AM decide. */ + return table_relation_needs_toast_table(rel); } diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile index 4a6c99e0908..d64628566d3 100644 --- a/src/backend/commands/Makefile +++ b/src/backend/commands/Makefile @@ -20,6 +20,6 @@ OBJS = amcmds.o aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o \ policy.o portalcmds.o prepare.o proclang.o publicationcmds.o \ schemacmds.o seclabel.o sequence.o statscmds.o subscriptioncmds.o \ tablecmds.o tablespace.o trigger.o tsearchcmds.o typecmds.o user.o \ - vacuum.o vacuumlazy.o variable.o view.o + vacuum.o variable.o view.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index a1fd871d317..d569067dc4d 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -4,7 +4,7 @@ * * Routines for aggregate-manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,7 +54,12 @@ static char extractModify(DefElem *defel); * "parameters" is a list of DefElem representing the agg's definition clauses. */ ObjectAddress -DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List *parameters) +DefineAggregate(ParseState *pstate, + List *name, + List *args, + bool oldstyle, + List *parameters, + bool replace) { char *aggName; Oid aggNamespace; @@ -436,6 +441,7 @@ DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List */ return AggregateCreate(aggName, /* aggregate name */ aggNamespace, /* namespace */ + replace, aggKind, numArgs, numDirectArgs, @@ -477,13 +483,13 @@ extractModify(DefElem *defel) if (strcmp(val, "read_only") == 0) return AGGMODIFY_READ_ONLY; - if (strcmp(val, "sharable") == 0) - return AGGMODIFY_SHARABLE; + if (strcmp(val, "shareable") == 0) + return AGGMODIFY_SHAREABLE; if (strcmp(val, "read_write") == 0) return AGGMODIFY_READ_WRITE; ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("parameter \"%s\" must be READ_ONLY, SHARABLE, or READ_WRITE", + errmsg("parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE", defel->defname))); return 0; /* keep compiler quiet */ } diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 0d63866fb09..70dbcb0756c 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -3,7 +3,7 @@ * alter.c * Drivers for generic alter commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,7 +15,9 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -64,7 +66,6 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid); @@ -273,6 +274,12 @@ AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name) if (SearchSysCacheExists2(SUBSCRIPTIONNAME, MyDatabaseId, CStringGetDatum(new_name))) report_name_conflict(classId, new_name); + + /* Also enforce regression testing naming rules, if enabled */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(new_name, "regress_", 8) != 0) + elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\""); +#endif } else if (nameCacheId >= 0) { @@ -398,11 +405,11 @@ ExecRenameStmt(RenameStmt *stmt) AccessExclusiveLock, false); Assert(relation == NULL); - catalog = heap_open(address.classId, RowExclusiveLock); + catalog = table_open(address.classId, RowExclusiveLock); AlterObjectRename_internal(catalog, address.objectId, stmt->newname); - heap_close(catalog, RowExclusiveLock); + table_close(catalog, RowExclusiveLock); return address; } @@ -437,7 +444,7 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre * don't need the relation here, but we'll retain the lock until commit. */ if (rel) - heap_close(rel, NoLock); + table_close(rel, NoLock); refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname, &rel, AccessExclusiveLock, false); @@ -517,12 +524,12 @@ ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, false); Assert(relation == NULL); classId = address.classId; - catalog = heap_open(classId, RowExclusiveLock); + catalog = table_open(classId, RowExclusiveLock); nspOid = LookupCreationNamespace(stmt->newschema); oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId, nspOid); - heap_close(catalog, RowExclusiveLock); + table_close(catalog, RowExclusiveLock); } break; @@ -597,12 +604,12 @@ AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, { Relation catalog; - catalog = heap_open(classId, RowExclusiveLock); + catalog = table_open(classId, RowExclusiveLock); oldNspOid = AlterObjectNamespace_internal(catalog, objid, nspOid); - heap_close(catalog, RowExclusiveLock); + table_close(catalog, RowExclusiveLock); } break; @@ -874,10 +881,10 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) if (classId == LargeObjectRelationId) classId = LargeObjectMetadataRelationId; - catalog = heap_open(classId, RowExclusiveLock); + catalog = table_open(classId, RowExclusiveLock); AlterObjectOwner_internal(catalog, address.objectId, newowner); - heap_close(catalog, RowExclusiveLock); + table_close(catalog, RowExclusiveLock); return address; } @@ -903,6 +910,7 @@ void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) { Oid classId = RelationGetRelid(rel); + AttrNumber Anum_oid = get_object_attnum_oid(classId); AttrNumber Anum_owner = get_object_attnum_owner(classId); AttrNumber Anum_namespace = get_object_attnum_namespace(classId); AttrNumber Anum_acl = get_object_attnum_acl(classId); @@ -913,7 +921,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) Oid old_ownerId; Oid namespaceId = InvalidOid; - oldtup = get_catalog_object_by_oid(rel, objectId); + oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId); if (oldtup == NULL) elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", objectId, RelationGetRelationName(rel)); @@ -942,7 +950,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) /* Superusers can bypass permission checks */ if (!superuser()) { - ObjectType objtype = get_object_type(classId, objectId); + ObjectType objtype = get_object_type(classId, objectId); /* must be owner */ if (!has_privs_of_role(GetUserId(), old_ownerId)) @@ -959,8 +967,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) } else { - snprintf(namebuf, sizeof(namebuf), "%u", - HeapTupleGetOid(oldtup)); + snprintf(namebuf, sizeof(namebuf), "%u", objectId); objname = namebuf; } aclcheck_error(ACLCHECK_NOT_OWNER, objtype, objname); @@ -1017,7 +1024,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) /* Update owner dependency reference */ if (classId == LargeObjectMetadataRelationId) classId = LargeObjectRelationId; - changeDependencyOnOwner(classId, HeapTupleGetOid(newtup), new_ownerId); + changeDependencyOnOwner(classId, objectId, new_ownerId); /* Release memory */ pfree(values); diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c index f2173450ad3..c0e40980d5f 100644 --- a/src/backend/commands/amcmds.c +++ b/src/backend/commands/amcmds.c @@ -3,7 +3,7 @@ * amcmds.c * Routines for SQL commands that manipulate access methods. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -13,8 +13,9 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/pg_am.h" @@ -29,7 +30,7 @@ #include "utils/syscache.h" -static Oid lookup_index_am_handler_func(List *handler_name, char amtype); +static Oid lookup_am_handler_func(List *handler_name, char amtype); static const char *get_am_type_string(char amtype); @@ -49,7 +50,7 @@ CreateAccessMethod(CreateAmStmt *stmt) Datum values[Natts_pg_am]; HeapTuple tup; - rel = heap_open(AccessMethodRelationId, RowExclusiveLock); + rel = table_open(AccessMethodRelationId, RowExclusiveLock); /* Must be super user */ if (!superuser()) @@ -60,7 +61,8 @@ CreateAccessMethod(CreateAmStmt *stmt) errhint("Must be superuser to create an access method."))); /* Check if name is used */ - amoid = GetSysCacheOid1(AMNAME, CStringGetDatum(stmt->amname)); + amoid = GetSysCacheOid1(AMNAME, Anum_pg_am_oid, + CStringGetDatum(stmt->amname)); if (OidIsValid(amoid)) { ereport(ERROR, @@ -72,7 +74,7 @@ CreateAccessMethod(CreateAmStmt *stmt) /* * Get the handler function oid, verifying the AM type while at it. */ - amhandler = lookup_index_am_handler_func(stmt->handler_name, stmt->amtype); + amhandler = lookup_am_handler_func(stmt->handler_name, stmt->amtype); /* * Insert tuple into pg_am. @@ -80,6 +82,8 @@ CreateAccessMethod(CreateAmStmt *stmt) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid); + values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid); values[Anum_pg_am_amname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->amname)); values[Anum_pg_am_amhandler - 1] = ObjectIdGetDatum(amhandler); @@ -87,7 +91,7 @@ CreateAccessMethod(CreateAmStmt *stmt) tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); - amoid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); myself.classId = AccessMethodRelationId; @@ -103,7 +107,7 @@ CreateAccessMethod(CreateAmStmt *stmt) recordDependencyOnCurrentExtension(&myself, false); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -122,7 +126,7 @@ RemoveAccessMethodById(Oid amOid) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to drop access methods"))); - relation = heap_open(AccessMethodRelationId, RowExclusiveLock); + relation = table_open(AccessMethodRelationId, RowExclusiveLock); tup = SearchSysCache1(AMOID, ObjectIdGetDatum(amOid)); if (!HeapTupleIsValid(tup)) @@ -132,7 +136,7 @@ RemoveAccessMethodById(Oid amOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* @@ -164,7 +168,7 @@ get_am_type_oid(const char *amname, char amtype, bool missing_ok) NameStr(amform->amname), get_am_type_string(amtype)))); - oid = HeapTupleGetOid(tup); + oid = amform->oid; ReleaseSysCache(tup); } @@ -185,6 +189,16 @@ get_index_am_oid(const char *amname, bool missing_ok) return get_am_type_oid(amname, AMTYPE_INDEX, missing_ok); } +/* + * get_table_am_oid - given an access method name, look up its OID + * and verify it corresponds to an table AM. + */ +Oid +get_table_am_oid(const char *amname, bool missing_ok) +{ + return get_am_type_oid(amname, AMTYPE_TABLE, missing_ok); +} + /* * get_am_oid - given an access method name, look up its OID. * The type is not checked. @@ -225,6 +239,8 @@ get_am_type_string(char amtype) { case AMTYPE_INDEX: return "INDEX"; + case AMTYPE_TABLE: + return "TABLE"; default: /* shouldn't happen */ elog(ERROR, "invalid access method type '%c'", amtype); @@ -239,10 +255,11 @@ get_am_type_string(char amtype) * This function either return valid function Oid or throw an error. */ static Oid -lookup_index_am_handler_func(List *handler_name, char amtype) +lookup_am_handler_func(List *handler_name, char amtype) { Oid handlerOid; - static const Oid funcargtypes[1] = {INTERNALOID}; + Oid funcargtypes[1] = {INTERNALOID}; + Oid expectedType = InvalidOid; if (handler_name == NIL) ereport(ERROR, @@ -256,16 +273,21 @@ lookup_index_am_handler_func(List *handler_name, char amtype) switch (amtype) { case AMTYPE_INDEX: - if (get_func_rettype(handlerOid) != INDEX_AM_HANDLEROID) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("function %s must return type %s", - NameListToString(handler_name), - "index_am_handler"))); + expectedType = INDEX_AM_HANDLEROID; + break; + case AMTYPE_TABLE: + expectedType = TABLE_AM_HANDLEROID; break; default: elog(ERROR, "unrecognized access method type \"%c\"", amtype); } + if (get_func_rettype(handlerOid) != expectedType) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("function %s must return type %s", + get_func_name(handlerOid), + format_type_extended(expectedType, -1, 0)))); + return handlerOid; } diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index d471541097d..7accb950eb1 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -3,7 +3,7 @@ * analyze.c * the Postgres statistics generator * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,11 +16,15 @@ #include +#include "access/detoast.h" +#include "access/genam.h" #include "access/multixact.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/tupconvert.h" -#include "access/tuptoaster.h" #include "access/visibilitymap.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -60,7 +64,6 @@ #include "utils/sortsupport.h" #include "utils/syscache.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* Per-index data for ANALYZE */ @@ -81,25 +84,25 @@ static MemoryContext anl_context = NULL; static BufferAccessStrategy vac_strategy; -static void do_analyze_rel(Relation onerel, int options, - VacuumParams *params, List *va_cols, - AcquireSampleRowsFunc acquirefunc, BlockNumber relpages, - bool inh, bool in_outer_xact, int elevel); +static void do_analyze_rel(Relation onerel, + VacuumParams *params, List *va_cols, + AcquireSampleRowsFunc acquirefunc, BlockNumber relpages, + bool inh, bool in_outer_xact, int elevel); static void compute_index_stats(Relation onerel, double totalrows, - AnlIndexData *indexdata, int nindexes, - HeapTuple *rows, int numrows, - MemoryContext col_context); + AnlIndexData *indexdata, int nindexes, + HeapTuple *rows, int numrows, + MemoryContext col_context); static VacAttrStats *examine_attribute(Relation onerel, int attnum, - Node *index_expr); -static int acquire_sample_rows(Relation onerel, int elevel, - HeapTuple *rows, int targrows, - double *totalrows, double *totaldeadrows); + Node *index_expr); +static int acquire_sample_rows(Relation onerel, int elevel, + HeapTuple *rows, int targrows, + double *totalrows, double *totaldeadrows); static int compare_rows(const void *a, const void *b); -static int acquire_inherited_sample_rows(Relation onerel, int elevel, - HeapTuple *rows, int targrows, - double *totalrows, double *totaldeadrows); +static int acquire_inherited_sample_rows(Relation onerel, int elevel, + HeapTuple *rows, int targrows, + double *totalrows, double *totaldeadrows); static void update_attstats(Oid relid, bool inh, - int natts, VacAttrStats **vacattrstats); + int natts, VacAttrStats **vacattrstats); static Datum std_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull); static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull); @@ -112,7 +115,7 @@ static Datum ind_fetch_func(VacAttrStatsP stats, int rownum, bool *isNull); * use it once we've successfully opened the rel, since it might be stale. */ void -analyze_rel(Oid relid, RangeVar *relation, int options, +analyze_rel(Oid relid, RangeVar *relation, VacuumParams *params, List *va_cols, bool in_outer_xact, BufferAccessStrategy bstrategy) { @@ -120,10 +123,9 @@ analyze_rel(Oid relid, RangeVar *relation, int options, int elevel; AcquireSampleRowsFunc acquirefunc = NULL; BlockNumber relpages = 0; - bool rel_lock = true; /* Select logging level */ - if (options & VACOPT_VERBOSE) + if (params->options & VACOPT_VERBOSE) elevel = INFO; else elevel = DEBUG2; @@ -142,81 +144,29 @@ analyze_rel(Oid relid, RangeVar *relation, int options, * concurrent VACUUM, which doesn't matter much at the moment but might * matter if we ever try to accumulate stats on dead tuples.) If the rel * has been dropped since we last saw it, we don't need to process it. + * + * Make sure to generate only logs for ANALYZE in this case. */ - if (!(options & VACOPT_NOWAIT)) - onerel = try_relation_open(relid, ShareUpdateExclusiveLock); - else if (ConditionalLockRelationOid(relid, ShareUpdateExclusiveLock)) - onerel = try_relation_open(relid, NoLock); - else - { - onerel = NULL; - rel_lock = false; - } + onerel = vacuum_open_relation(relid, relation, params->options & ~(VACOPT_VACUUM), + params->log_min_duration >= 0, + ShareUpdateExclusiveLock); - /* - * If we failed to open or lock the relation, emit a log message before - * exiting. - */ + /* leave if relation could not be opened or locked */ if (!onerel) - { - /* - * If the RangeVar is not defined, we do not have enough information - * to provide a meaningful log statement. Chances are that - * analyze_rel's caller has intentionally not provided this - * information so that this logging is skipped, anyway. - */ - if (relation == NULL) - return; - - /* - * Determine the log level. For autovacuum logs, we emit a LOG if - * log_autovacuum_min_duration is not disabled. For manual ANALYZE, - * we emit a WARNING to match the log statements in the permissions - * checks. - */ - if (!IsAutoVacuumWorkerProcess()) - elevel = WARNING; - else if (params->log_min_duration >= 0) - elevel = LOG; - else - return; - - if (!rel_lock) - ereport(elevel, - (errcode(ERRCODE_LOCK_NOT_AVAILABLE), - errmsg("skipping analyze of \"%s\" --- lock not available", - relation->relname))); - else - ereport(elevel, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("skipping analyze of \"%s\" --- relation no longer exists", - relation->relname))); - return; - } /* - * Check permissions --- this should match vacuum's check! + * Check if relation needs to be skipped based on ownership. This check + * happens also when building the relation list to analyze for a manual + * operation, and needs to be done additionally here as ANALYZE could + * happen across multiple transactions where relation ownership could have + * changed in-between. Make sure to generate only logs for ANALYZE in + * this case. */ - if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) || - (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared))) + if (!vacuum_is_relation_owner(RelationGetRelid(onerel), + onerel->rd_rel, + params->options & VACOPT_ANALYZE)) { - /* No need for a WARNING if we already complained during VACUUM */ - if (!(options & VACOPT_VACUUM)) - { - if (onerel->rd_rel->relisshared) - ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser can analyze it", - RelationGetRelationName(onerel)))); - else if (onerel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE) - ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it", - RelationGetRelationName(onerel)))); - else - ereport(WARNING, - (errmsg("skipping \"%s\" --- only table or database owner can analyze it", - RelationGetRelationName(onerel)))); - } relation_close(onerel, ShareUpdateExclusiveLock); return; } @@ -287,7 +237,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options, else { /* No need for a WARNING if we already complained during VACUUM */ - if (!(options & VACOPT_VACUUM)) + if (!(params->options & VACOPT_VACUUM)) ereport(WARNING, (errmsg("skipping \"%s\" --- cannot analyze non-tables or special system tables", RelationGetRelationName(onerel)))); @@ -307,14 +257,14 @@ analyze_rel(Oid relid, RangeVar *relation, int options, * tables, which don't contain any rows. */ if (onerel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) - do_analyze_rel(onerel, options, params, va_cols, acquirefunc, + do_analyze_rel(onerel, params, va_cols, acquirefunc, relpages, false, in_outer_xact, elevel); /* * If there are child tables, do recursive ANALYZE. */ if (onerel->rd_rel->relhassubclass) - do_analyze_rel(onerel, options, params, va_cols, acquirefunc, relpages, + do_analyze_rel(onerel, params, va_cols, acquirefunc, relpages, true, in_outer_xact, elevel); /* @@ -342,7 +292,7 @@ analyze_rel(Oid relid, RangeVar *relation, int options, * appropriate acquirefunc for each child table. */ static void -do_analyze_rel(Relation onerel, int options, VacuumParams *params, +do_analyze_rel(Relation onerel, VacuumParams *params, List *va_cols, AcquireSampleRowsFunc acquirefunc, BlockNumber relpages, bool inh, bool in_outer_xact, int elevel) @@ -357,7 +307,8 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, VacAttrStats **vacattrstats; AnlIndexData *indexdata; int targrows, - numrows; + numrows, + minrows; double totalrows, totaldeadrows; HeapTuple *rows; @@ -495,7 +446,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, tcnt = 0; for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { - int keycol = indexInfo->ii_KeyAttrNumbers[i]; + int keycol = indexInfo->ii_IndexAttrNumbers[i]; if (keycol == 0) { @@ -505,7 +456,8 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, if (indexpr_item == NULL) /* shouldn't happen */ elog(ERROR, "too few entries in indexprs list"); indexkey = (Node *) lfirst(indexpr_item); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(indexInfo->ii_Expressions, + indexpr_item); thisdata->vacattrstats[tcnt] = examine_attribute(Irel[ind], i + 1, indexkey); if (thisdata->vacattrstats[tcnt] != NULL) @@ -540,6 +492,16 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, } } + /* + * Look at extended statistics objects too, as those may define custom + * statistics target. So we may need to sample more rows and then build + * the statistics with enough detail. + */ + minrows = ComputeExtStatisticsRows(onerel, attr_cnt, vacattrstats); + + if (targrows < minrows) + targrows = minrows; + /* * Acquire the sample rows */ @@ -623,9 +585,15 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, thisdata->attr_cnt, thisdata->vacattrstats); } - /* Build extended statistics (if there are any). */ - BuildRelationExtStatistics(onerel, totalrows, numrows, rows, attr_cnt, - vacattrstats); + /* + * Build extended statistics (if there are any). + * + * For now we only build extended statistics on individual relations, + * not for relations representing inheritance trees. + */ + if (!inh) + BuildRelationExtStatistics(onerel, totalrows, numrows, rows, + attr_cnt, vacattrstats); } /* @@ -653,7 +621,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, * VACUUM ANALYZE, don't overwrite the accurate count already inserted by * VACUUM. */ - if (!inh && !(options & VACOPT_VACUUM)) + if (!inh && !(params->options & VACOPT_VACUUM)) { for (ind = 0; ind < nindexes; ind++) { @@ -684,7 +652,7 @@ do_analyze_rel(Relation onerel, int options, VacuumParams *params, (va_cols == NIL)); /* If this isn't part of VACUUM ANALYZE, let index AMs do cleanup */ - if (!(options & VACOPT_VACUUM)) + if (!(params->options & VACOPT_VACUUM)) { for (ind = 0; ind < nindexes; ind++) { @@ -783,7 +751,8 @@ compute_index_stats(Relation onerel, double totalrows, estate = CreateExecutorState(); econtext = GetPerTupleExprContext(estate); /* Need a slot to hold the current heap tuple, too */ - slot = MakeSingleTupleTableSlot(RelationGetDescr(onerel)); + slot = MakeSingleTupleTableSlot(RelationGetDescr(onerel), + &TTSOpsHeapTuple); /* Arrange for econtext's scan tuple to be the tuple under test */ econtext->ecxt_scantuple = slot; @@ -809,7 +778,7 @@ compute_index_stats(Relation onerel, double totalrows, ResetExprContext(econtext); /* Set up for predicate or expression evaluation */ - ExecStoreTuple(heapTuple, slot, InvalidBuffer, false); + ExecStoreHeapTuple(heapTuple, slot, false); /* If index is partial, check predicate */ if (predicate != NULL) @@ -956,11 +925,22 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) { stats->attrtypid = exprType(index_expr); stats->attrtypmod = exprTypmod(index_expr); + + /* + * If a collation has been specified for the index column, use that in + * preference to anything else; but if not, fall back to whatever we + * can get from the expression. + */ + if (OidIsValid(onerel->rd_indcollation[attnum - 1])) + stats->attrcollid = onerel->rd_indcollation[attnum - 1]; + else + stats->attrcollid = exprCollation(index_expr); } else { stats->attrtypid = attr->atttypid; stats->attrtypmod = attr->atttypmod; + stats->attrcollid = attr->attcollation; } typtuple = SearchSysCacheCopy1(TYPEOID, @@ -1052,6 +1032,8 @@ acquire_sample_rows(Relation onerel, int elevel, TransactionId OldestXmin; BlockSamplerData bs; ReservoirStateData rstate; + TupleTableSlot *slot; + TableScanDesc scan; Assert(targrows > 0); @@ -1065,178 +1047,68 @@ acquire_sample_rows(Relation onerel, int elevel, /* Prepare for sampling rows */ reservoir_init_selection_state(&rstate, targrows); + scan = table_beginscan_analyze(onerel); + slot = table_slot_create(onerel, NULL); + /* Outer loop over blocks to sample */ while (BlockSampler_HasMore(&bs)) { BlockNumber targblock = BlockSampler_Next(&bs); - Buffer targbuffer; - Page targpage; - OffsetNumber targoffset, - maxoffset; vacuum_delay_point(); - /* - * We must maintain a pin on the target page's buffer to ensure that - * the maxoffset value stays good (else concurrent VACUUM might delete - * tuples out from under us). Hence, pin the page until we are done - * looking at it. We also choose to hold sharelock on the buffer - * throughout --- we could release and re-acquire sharelock for each - * tuple, but since we aren't doing much work per tuple, the extra - * lock traffic is probably better avoided. - */ - targbuffer = ReadBufferExtended(onerel, MAIN_FORKNUM, targblock, - RBM_NORMAL, vac_strategy); - LockBuffer(targbuffer, BUFFER_LOCK_SHARE); - targpage = BufferGetPage(targbuffer); - maxoffset = PageGetMaxOffsetNumber(targpage); - - /* Inner loop over all tuples on the selected page */ - for (targoffset = FirstOffsetNumber; targoffset <= maxoffset; targoffset++) - { - ItemId itemid; - HeapTupleData targtuple; - bool sample_it = false; - - itemid = PageGetItemId(targpage, targoffset); + if (!table_scan_analyze_next_block(scan, targblock, vac_strategy)) + continue; + while (table_scan_analyze_next_tuple(scan, OldestXmin, &liverows, &deadrows, slot)) + { /* - * We ignore unused and redirect line pointers. DEAD line - * pointers should be counted as dead, because we need vacuum to - * run to get rid of them. Note that this rule agrees with the - * way that heap_page_prune() counts things. + * The first targrows sample rows are simply copied into the + * reservoir. Then we start replacing tuples in the sample until + * we reach the end of the relation. This algorithm is from Jeff + * Vitter's paper (see full citation in utils/misc/sampling.c). It + * works by repeatedly computing the number of tuples to skip + * before selecting a tuple, which replaces a randomly chosen + * element of the reservoir (current set of tuples). At all times + * the reservoir is a true random sample of the tuples we've + * passed over so far, so when we fall off the end of the relation + * we're done. */ - if (!ItemIdIsNormal(itemid)) - { - if (ItemIdIsDead(itemid)) - deadrows += 1; - continue; - } - - ItemPointerSet(&targtuple.t_self, targblock, targoffset); - - targtuple.t_tableOid = RelationGetRelid(onerel); - targtuple.t_data = (HeapTupleHeader) PageGetItem(targpage, itemid); - targtuple.t_len = ItemIdGetLength(itemid); - - switch (HeapTupleSatisfiesVacuum(&targtuple, - OldestXmin, - targbuffer)) - { - case HEAPTUPLE_LIVE: - sample_it = true; - liverows += 1; - break; - - case HEAPTUPLE_DEAD: - case HEAPTUPLE_RECENTLY_DEAD: - /* Count dead and recently-dead rows */ - deadrows += 1; - break; - - case HEAPTUPLE_INSERT_IN_PROGRESS: - - /* - * Insert-in-progress rows are not counted. We assume - * that when the inserting transaction commits or aborts, - * it will send a stats message to increment the proper - * count. This works right only if that transaction ends - * after we finish analyzing the table; if things happen - * in the other order, its stats update will be - * overwritten by ours. However, the error will be large - * only if the other transaction runs long enough to - * insert many tuples, so assuming it will finish after us - * is the safer option. - * - * A special case is that the inserting transaction might - * be our own. In this case we should count and sample - * the row, to accommodate users who load a table and - * analyze it in one transaction. (pgstat_report_analyze - * has to adjust the numbers we send to the stats - * collector to make this come out right.) - */ - if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(targtuple.t_data))) - { - sample_it = true; - liverows += 1; - } - break; - - case HEAPTUPLE_DELETE_IN_PROGRESS: - - /* - * We count delete-in-progress rows as still live, using - * the same reasoning given above; but we don't bother to - * include them in the sample. - * - * If the delete was done by our own transaction, however, - * we must count the row as dead to make - * pgstat_report_analyze's stats adjustments come out - * right. (Note: this works out properly when the row was - * both inserted and deleted in our xact.) - */ - if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(targtuple.t_data))) - deadrows += 1; - else - liverows += 1; - break; - - default: - elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); - break; - } - - if (sample_it) + if (numrows < targrows) + rows[numrows++] = ExecCopySlotHeapTuple(slot); + else { /* - * The first targrows sample rows are simply copied into the - * reservoir. Then we start replacing tuples in the sample - * until we reach the end of the relation. This algorithm is - * from Jeff Vitter's paper (see full citation below). It - * works by repeatedly computing the number of tuples to skip - * before selecting a tuple, which replaces a randomly chosen - * element of the reservoir (current set of tuples). At all - * times the reservoir is a true random sample of the tuples - * we've passed over so far, so when we fall off the end of - * the relation we're done. + * t in Vitter's paper is the number of records already + * processed. If we need to compute a new S value, we must + * use the not-yet-incremented value of samplerows as t. */ - if (numrows < targrows) - rows[numrows++] = heap_copytuple(&targtuple); - else + if (rowstoskip < 0) + rowstoskip = reservoir_get_next_S(&rstate, samplerows, targrows); + + if (rowstoskip <= 0) { /* - * t in Vitter's paper is the number of records already - * processed. If we need to compute a new S value, we - * must use the not-yet-incremented value of samplerows as - * t. + * Found a suitable tuple, so save it, replacing one old + * tuple at random */ - if (rowstoskip < 0) - rowstoskip = reservoir_get_next_S(&rstate, samplerows, targrows); + int k = (int) (targrows * sampler_random_fract(rstate.randstate)); - if (rowstoskip <= 0) - { - /* - * Found a suitable tuple, so save it, replacing one - * old tuple at random - */ - int k = (int) (targrows * sampler_random_fract(rstate.randstate)); - - Assert(k >= 0 && k < targrows); - heap_freetuple(rows[k]); - rows[k] = heap_copytuple(&targtuple); - } - - rowstoskip -= 1; + Assert(k >= 0 && k < targrows); + heap_freetuple(rows[k]); + rows[k] = ExecCopySlotHeapTuple(slot); } - samplerows += 1; + rowstoskip -= 1; } - } - /* Now release the lock and pin on the page */ - UnlockReleaseBuffer(targbuffer); + samplerows += 1; + } } + ExecDropSingleTupleTableSlot(slot); + table_endscan(scan); + /* * If we didn't find as many tuples as we wanted then we're done. No sort * is needed, since they're already in order. @@ -1375,14 +1247,14 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, BlockNumber relpages = 0; /* We already got the needed lock */ - childrel = heap_open(childOID, NoLock); + childrel = table_open(childOID, NoLock); /* Ignore if temp table of another backend */ if (RELATION_IS_OTHER_TEMP(childrel)) { /* ... but release the lock on it */ Assert(childrel != onerel); - heap_close(childrel, AccessShareLock); + table_close(childrel, AccessShareLock); continue; } @@ -1414,7 +1286,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, { /* ignore, but release the lock on it */ Assert(childrel != onerel); - heap_close(childrel, AccessShareLock); + table_close(childrel, AccessShareLock); continue; } } @@ -1426,9 +1298,9 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, */ Assert(childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); if (childrel != onerel) - heap_close(childrel, AccessShareLock); + table_close(childrel, AccessShareLock); else - heap_close(childrel, NoLock); + table_close(childrel, NoLock); continue; } @@ -1495,8 +1367,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, TupleConversionMap *map; map = convert_tuples_by_name(RelationGetDescr(childrel), - RelationGetDescr(onerel), - gettext_noop("could not convert row type")); + RelationGetDescr(onerel)); if (map != NULL) { int j; @@ -1505,7 +1376,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, { HeapTuple newtup; - newtup = do_convert_tuple(rows[numrows + j], map); + newtup = execute_attr_map_tuple(rows[numrows + j], map); heap_freetuple(rows[numrows + j]); rows[numrows + j] = newtup; } @@ -1524,7 +1395,7 @@ acquire_inherited_sample_rows(Relation onerel, int elevel, * Note: we cannot release the child-table locks, since we may have * pointers to their TOAST tables in the sampled rows. */ - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } return numrows; @@ -1562,7 +1433,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats) if (natts <= 0) return; /* nothing to do */ - sd = heap_open(StatisticRelationId, RowExclusiveLock); + sd = table_open(StatisticRelationId, RowExclusiveLock); for (attno = 0; attno < natts; attno++) { @@ -1605,6 +1476,11 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats) { values[i++] = ObjectIdGetDatum(stats->staop[k]); /* staopN */ } + i = Anum_pg_statistic_stacoll1 - 1; + for (k = 0; k < STATISTIC_NUM_SLOTS; k++) + { + values[i++] = ObjectIdGetDatum(stats->stacoll[k]); /* stacollN */ + } i = Anum_pg_statistic_stanumbers1 - 1; for (k = 0; k < STATISTIC_NUM_SLOTS; k++) { @@ -1678,7 +1554,7 @@ update_attstats(Oid relid, bool inh, int natts, VacAttrStats **vacattrstats) heap_freetuple(stup); } - heap_close(sd, RowExclusiveLock); + table_close(sd, RowExclusiveLock); } /* @@ -1756,25 +1632,25 @@ typedef struct static void compute_trivial_stats(VacAttrStatsP stats, - AnalyzeAttrFetchFunc fetchfunc, - int samplerows, - double totalrows); + AnalyzeAttrFetchFunc fetchfunc, + int samplerows, + double totalrows); static void compute_distinct_stats(VacAttrStatsP stats, - AnalyzeAttrFetchFunc fetchfunc, - int samplerows, - double totalrows); + AnalyzeAttrFetchFunc fetchfunc, + int samplerows, + double totalrows); static void compute_scalar_stats(VacAttrStatsP stats, - AnalyzeAttrFetchFunc fetchfunc, - int samplerows, - double totalrows); + AnalyzeAttrFetchFunc fetchfunc, + int samplerows, + double totalrows); static int compare_scalars(const void *a, const void *b, void *arg); static int compare_mcvs(const void *a, const void *b); -static int analyze_mcv_list(int *mcv_counts, - int num_mcv, - double stadistinct, - double stanullfrac, - int samplerows, - double totalrows); +static int analyze_mcv_list(int *mcv_counts, + int num_mcv, + double stadistinct, + double stanullfrac, + int samplerows, + double totalrows); /* @@ -2045,9 +1921,8 @@ compute_distinct_stats(VacAttrStatsP stats, firstcount1 = track_cnt; for (j = 0; j < track_cnt; j++) { - /* We always use the default collation for statistics */ if (DatumGetBool(FunctionCall2Coll(&f_cmpeq, - DEFAULT_COLLATION_OID, + stats->attrcollid, value, track[j].value))) { match = true; @@ -2254,6 +2129,7 @@ compute_distinct_stats(VacAttrStatsP stats, stats->stakind[0] = STATISTIC_KIND_MCV; stats->staop[0] = mystats->eqopr; + stats->stacoll[0] = stats->attrcollid; stats->stanumbers[0] = mcv_freqs; stats->numnumbers[0] = num_mcv; stats->stavalues[0] = mcv_values; @@ -2325,8 +2201,7 @@ compute_scalar_stats(VacAttrStatsP stats, memset(&ssup, 0, sizeof(ssup)); ssup.ssup_cxt = CurrentMemoryContext; - /* We always use the default collation for statistics */ - ssup.ssup_collation = DEFAULT_COLLATION_OID; + ssup.ssup_collation = stats->attrcollid; ssup.ssup_nulls_first = false; /* @@ -2619,6 +2494,7 @@ compute_scalar_stats(VacAttrStatsP stats, stats->stakind[slot_idx] = STATISTIC_KIND_MCV; stats->staop[slot_idx] = mystats->eqopr; + stats->stacoll[slot_idx] = stats->attrcollid; stats->stanumbers[slot_idx] = mcv_freqs; stats->numnumbers[slot_idx] = num_mcv; stats->stavalues[slot_idx] = mcv_values; @@ -2734,6 +2610,7 @@ compute_scalar_stats(VacAttrStatsP stats, stats->stakind[slot_idx] = STATISTIC_KIND_HISTOGRAM; stats->staop[slot_idx] = mystats->ltopr; + stats->stacoll[slot_idx] = stats->attrcollid; stats->stavalues[slot_idx] = hist_values; stats->numvalues[slot_idx] = num_hist; @@ -2777,6 +2654,7 @@ compute_scalar_stats(VacAttrStatsP stats, stats->stakind[slot_idx] = STATISTIC_KIND_CORRELATION; stats->staop[slot_idx] = mystats->ltopr; + stats->stacoll[slot_idx] = stats->attrcollid; stats->stanumbers[slot_idx] = corrs; stats->numnumbers[slot_idx] = 1; slot_idx++; @@ -2898,7 +2776,7 @@ analyze_mcv_list(int *mcv_counts, * significantly more common than the estimated selectivity they would * have if they weren't in the list. All non-MCV values are assumed to be * equally common, after taking into account the frequencies of all the - * the values in the MCV list and the number of nulls (c.f. eqsel()). + * values in the MCV list and the number of nulls (c.f. eqsel()). * * Here sumcount tracks the total count of all but the last (least common) * value in the MCV list, allowing us to determine the effect of excluding diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index ee7c6d41b40..ee01df589f2 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -3,7 +3,7 @@ * async.c * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -75,8 +75,10 @@ * list of listening backends and send a PROCSIG_NOTIFY_INTERRUPT signal * to every listening backend (we don't know which backend is listening on * which channel so we must signal them all). We can exclude backends that - * are already up to date, though. We don't bother with a self-signal - * either, but just process the queue directly. + * are already up to date, though, and we can also exclude backends that + * are in other databases (unless they are way behind and should be kicked + * to make them advance their pointers). We don't bother with a + * self-signal either, but just process the queue directly. * * 5. Upon receipt of a PROCSIG_NOTIFY_INTERRUPT signal, the signal handler * sets the process's latch, which triggers the event to be processed @@ -89,13 +91,14 @@ * Inbound-notify processing consists of reading all of the notifications * that have arrived since scanning last time. We read every notification * until we reach either a notification from an uncommitted transaction or - * the head pointer's position. Then we check if we were the laziest - * backend: if our pointer is set to the same position as the global tail - * pointer is set, then we move the global tail pointer ahead to where the - * second-laziest backend is (in general, we take the MIN of the current - * head position and all active backends' new tail pointers). Whenever we - * move the global tail pointer we also truncate now-unused pages (i.e., - * delete files in pg_notify/ that are no longer used). + * the head pointer's position. + * + * 6. To avoid SLRU wraparound and limit disk space consumption, the tail + * pointer needs to be advanced so that old pages can be truncated. + * This is relatively expensive (notably, it requires an exclusive lock), + * so we don't want to do it often. We make sending backends do this work + * if they advanced the queue head into a new page, but only once every + * QUEUE_CLEANUP_DELAY pages. * * An application that listens on the same channel it notifies will get * NOTIFY messages for its own NOTIFYs. These can be ignored, if not useful, @@ -135,11 +138,11 @@ #include "storage/sinval.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" +#include "utils/hashutils.h" #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/snapmgr.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* @@ -211,6 +214,19 @@ typedef struct QueuePosition (x).page != (y).page ? (x) : \ (x).offset > (y).offset ? (x) : (y)) +/* + * Parameter determining how often we try to advance the tail pointer: + * we do that after every QUEUE_CLEANUP_DELAY pages of NOTIFY data. This is + * also the distance by which a backend in another database needs to be + * behind before we'll decide we need to wake it up to advance its pointer. + * + * Resist the temptation to make this really large. While that would save + * work in some places, it would add cost in others. In particular, this + * should likely be less than NUM_ASYNC_BUFFERS, to ensure that backends + * catch up before the pages they'll need to read fall out of SLRU cache. + */ +#define QUEUE_CLEANUP_DELAY 4 + /* * Struct describing a listening backend's status */ @@ -218,6 +234,7 @@ typedef struct QueueBackendStatus { int32 pid; /* either a PID or InvalidPid */ Oid dboid; /* backend's database OID, or InvalidOid */ + BackendId nextListener; /* id of next listener, or InvalidBackendId */ QueuePosition pos; /* backend has read queue up to here */ } QueueBackendStatus; @@ -241,12 +258,19 @@ typedef struct QueueBackendStatus * Each backend uses the backend[] array entry with index equal to its * BackendId (which can range from 1 to MaxBackends). We rely on this to make * SendProcSignal fast. + * + * The backend[] array entries for actively-listening backends are threaded + * together using firstListener and the nextListener links, so that we can + * scan them without having to iterate over inactive entries. We keep this + * list in order by BackendId so that the scan is cache-friendly when there + * are many active entries. */ typedef struct AsyncQueueControl { QueuePosition head; /* head points to the next free location */ - QueuePosition tail; /* the global tail is equivalent to the pos of - * the "slowest" backend */ + QueuePosition tail; /* tail must be <= the queue position of every + * listening backend */ + BackendId firstListener; /* id of first listener, or InvalidBackendId */ TimestampTz lastQueueFillWarn; /* time of last queue-full msg */ QueueBackendStatus backend[FLEXIBLE_ARRAY_MEMBER]; /* backend[0] is not used; used entries are from [1] to [MaxBackends] */ @@ -256,8 +280,10 @@ static AsyncQueueControl *asyncQueueControl; #define QUEUE_HEAD (asyncQueueControl->head) #define QUEUE_TAIL (asyncQueueControl->tail) +#define QUEUE_FIRST_LISTENER (asyncQueueControl->firstListener) #define QUEUE_BACKEND_PID(i) (asyncQueueControl->backend[i].pid) #define QUEUE_BACKEND_DBOID(i) (asyncQueueControl->backend[i].dboid) +#define QUEUE_NEXT_LISTENER(i) (asyncQueueControl->backend[i].nextListener) #define QUEUE_BACKEND_POS(i) (asyncQueueControl->backend[i].pos) /* @@ -324,14 +350,25 @@ static List *upperPendingActions = NIL; /* list of upper-xact lists */ /* * State for outbound notifies consists of a list of all channels+payloads - * NOTIFYed in the current transaction. We do not actually perform a NOTIFY - * until and unless the transaction commits. pendingNotifies is NIL if no - * NOTIFYs have been done in the current transaction. + * NOTIFYed in the current transaction. We do not actually perform a NOTIFY + * until and unless the transaction commits. pendingNotifies is NULL if no + * NOTIFYs have been done in the current (sub) transaction. + * + * We discard duplicate notify events issued in the same transaction. + * Hence, in addition to the list proper (which we need to track the order + * of the events, since we guarantee to deliver them in order), we build a + * hash table which we can probe to detect duplicates. Since building the + * hash table is somewhat expensive, we do so only once we have at least + * MIN_HASHABLE_NOTIFIES events queued in the current (sub) transaction; + * before that we just scan the events linearly. * * The list is kept in CurTransactionContext. In subtransactions, each * subtransaction has its own list in its own CurTransactionContext, but - * successful subtransactions attach their lists to their parent's list. - * Failed subtransactions simply discard their lists. + * successful subtransactions add their entries to their parent's list. + * Failed subtransactions simply discard their lists. Since these lists + * are independent, there may be notify events in a subtransaction's list + * that duplicate events in some ancestor (sub) transaction; we get rid of + * the dups when merging the subtransaction's list into its parent's. * * Note: the action and notify lists do not interact within a transaction. * In particular, if a transaction does NOTIFY and then LISTEN on the same @@ -340,11 +377,26 @@ static List *upperPendingActions = NIL; /* list of upper-xact lists */ */ typedef struct Notification { - char *channel; /* channel name */ - char *payload; /* payload string (can be empty) */ + uint16 channel_len; /* length of channel-name string */ + uint16 payload_len; /* length of payload string */ + /* null-terminated channel name, then null-terminated payload follow */ + char data[FLEXIBLE_ARRAY_MEMBER]; } Notification; -static List *pendingNotifies = NIL; /* list of Notifications */ +typedef struct NotificationList +{ + List *events; /* list of Notification structs */ + HTAB *hashtab; /* hash of NotificationHash structs, or NULL */ +} NotificationList; + +#define MIN_HASHABLE_NOTIFIES 16 /* threshold to build hashtab */ + +typedef struct NotificationHash +{ + Notification *event; /* => the actual Notification struct */ +} NotificationHash; + +static NotificationList *pendingNotifies = NULL; /* current list, if any */ static List *upperPendingNotifies = NIL; /* list of upper-xact lists */ @@ -366,10 +418,14 @@ static bool amRegisteredListener = false; /* has this backend sent notifications in the current transaction? */ static bool backendHasSentNotifications = false; +/* have we advanced to a page that's a multiple of QUEUE_CLEANUP_DELAY? */ +static bool backendTryAdvanceTail = false; + /* GUC parameter */ bool Trace_notify = false; /* local function prototypes */ +static int asyncQueuePageDiff(int p, int q); static bool asyncQueuePagePrecedes(int p, int q); static void queue_listen(ListenActionKind action, const char *channel); static void Async_UnlistenOnExit(int code, Datum arg); @@ -385,22 +441,26 @@ static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe); static ListCell *asyncQueueAddEntries(ListCell *nextNotify); static double asyncQueueUsage(void); static void asyncQueueFillWarning(void); -static bool SignalBackends(void); +static void SignalBackends(void); static void asyncQueueReadAllNotifications(void); static bool asyncQueueProcessPageEntries(volatile QueuePosition *current, - QueuePosition stop, - char *page_buffer, - Snapshot snapshot); + QueuePosition stop, + char *page_buffer, + Snapshot snapshot); static void asyncQueueAdvanceTail(void); static void ProcessIncomingNotify(void); -static bool AsyncExistsPendingNotify(const char *channel, const char *payload); +static bool AsyncExistsPendingNotify(Notification *n); +static void AddEventToPendingNotifies(Notification *n); +static uint32 notification_hash(const void *key, Size keysize); +static int notification_match(const void *key1, const void *key2, Size keysize); static void ClearPendingActionsAndNotifies(void); /* - * We will work on the page range of 0..QUEUE_MAX_PAGE. + * Compute the difference between two queue page numbers (i.e., p - q), + * accounting for wraparound. */ -static bool -asyncQueuePagePrecedes(int p, int q) +static int +asyncQueuePageDiff(int p, int q) { int diff; @@ -416,7 +476,14 @@ asyncQueuePagePrecedes(int p, int q) diff -= QUEUE_MAX_PAGE + 1; else if (diff < -((QUEUE_MAX_PAGE + 1) / 2)) diff += QUEUE_MAX_PAGE + 1; - return diff < 0; + return diff; +} + +/* Is p < q, accounting for wraparound? */ +static bool +asyncQueuePagePrecedes(int p, int q) +{ + return asyncQueuePageDiff(p, q) < 0; } /* @@ -461,16 +528,16 @@ AsyncShmemInit(void) if (!found) { /* First time through, so initialize it */ - int i; - SET_QUEUE_POS(QUEUE_HEAD, 0, 0); SET_QUEUE_POS(QUEUE_TAIL, 0, 0); + QUEUE_FIRST_LISTENER = InvalidBackendId; asyncQueueControl->lastQueueFillWarn = 0; /* zero'th entry won't be used, but let's initialize it anyway */ - for (i = 0; i <= MaxBackends; i++) + for (int i = 0; i <= MaxBackends; i++) { QUEUE_BACKEND_PID(i) = InvalidPid; QUEUE_BACKEND_DBOID(i) = InvalidOid; + QUEUE_NEXT_LISTENER(i) = InvalidBackendId; SET_QUEUE_POS(QUEUE_BACKEND_POS(i), 0, 0); } } @@ -542,6 +609,8 @@ pg_notify(PG_FUNCTION_ARGS) void Async_Notify(const char *channel, const char *payload) { + size_t channel_len; + size_t payload_len; Notification *n; MemoryContext oldcontext; @@ -551,47 +620,67 @@ Async_Notify(const char *channel, const char *payload) if (Trace_notify) elog(DEBUG1, "Async_Notify(%s)", channel); + channel_len = channel ? strlen(channel) : 0; + payload_len = payload ? strlen(payload) : 0; + /* a channel name must be specified */ - if (!channel || !strlen(channel)) + if (channel_len == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("channel name cannot be empty"))); - if (strlen(channel) >= NAMEDATALEN) + /* enforce length limits */ + if (channel_len >= NAMEDATALEN) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("channel name too long"))); - if (payload) - { - if (strlen(payload) >= NOTIFY_PAYLOAD_MAX_LENGTH) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("payload string too long"))); - } - - /* no point in making duplicate entries in the list ... */ - if (AsyncExistsPendingNotify(channel, payload)) - return; + if (payload_len >= NOTIFY_PAYLOAD_MAX_LENGTH) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("payload string too long"))); /* + * We must construct the Notification entry, even if we end up not using + * it, in order to compare it cheaply to existing list entries. + * * The notification list needs to live until end of transaction, so store * it in the transaction context. */ oldcontext = MemoryContextSwitchTo(CurTransactionContext); - n = (Notification *) palloc(sizeof(Notification)); - n->channel = pstrdup(channel); + n = (Notification *) palloc(offsetof(Notification, data) + + channel_len + payload_len + 2); + n->channel_len = channel_len; + n->payload_len = payload_len; + strcpy(n->data, channel); if (payload) - n->payload = pstrdup(payload); + strcpy(n->data + channel_len + 1, payload); else - n->payload = ""; + n->data[channel_len + 1] = '\0'; - /* - * We want to preserve the order so we need to append every notification. - * See comments at AsyncExistsPendingNotify(). - */ - pendingNotifies = lappend(pendingNotifies, n); + /* Now check for duplicates */ + if (AsyncExistsPendingNotify(n)) + { + /* It's a dup, so forget it */ + pfree(n); + MemoryContextSwitchTo(oldcontext); + return; + } + + if (pendingNotifies == NULL) + { + /* First notify event in current (sub)xact */ + pendingNotifies = (NotificationList *) palloc(sizeof(NotificationList)); + pendingNotifies->events = list_make1(n); + /* We certainly don't need a hashtable yet */ + pendingNotifies->hashtab = NULL; + } + else + { + /* Append more events to existing list */ + AddEventToPendingNotifies(n); + } MemoryContextSwitchTo(oldcontext); } @@ -690,36 +779,22 @@ Datum pg_listening_channels(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; - ListCell **lcp; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { - MemoryContext oldcontext; - /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); - - /* switch to memory context appropriate for multiple function calls */ - oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - - /* allocate memory for user context */ - lcp = (ListCell **) palloc(sizeof(ListCell *)); - *lcp = list_head(listenChannels); - funcctx->user_fctx = (void *) lcp; - - MemoryContextSwitchTo(oldcontext); } /* stuff done on every call of the function */ funcctx = SRF_PERCALL_SETUP(); - lcp = (ListCell **) funcctx->user_fctx; - while (*lcp != NULL) + if (funcctx->call_cntr < list_length(listenChannels)) { - char *channel = (char *) lfirst(*lcp); + char *channel = (char *) list_nth(listenChannels, + funcctx->call_cntr); - *lcp = lnext(*lcp); SRF_RETURN_NEXT(funcctx, CStringGetTextDatum(channel)); } @@ -776,7 +851,7 @@ PreCommit_Notify(void) { ListCell *p; - if (pendingActions == NIL && pendingNotifies == NIL) + if (!pendingActions && !pendingNotifies) return; /* no relevant statements in this xact */ if (Trace_notify) @@ -836,7 +911,7 @@ PreCommit_Notify(void) /* Now push the notifications into the queue */ backendHasSentNotifications = true; - nextNotify = list_head(pendingNotifies); + nextNotify = list_head(pendingNotifies->events); while (nextNotify != NULL) { /* @@ -922,7 +997,7 @@ Exec_ListenPreCommit(void) { QueuePosition head; QueuePosition max; - int i; + BackendId prevListener; /* * Nothing to do if we are already listening to something, nor if we @@ -959,26 +1034,37 @@ Exec_ListenPreCommit(void) * our database; any notifications it's already advanced over are surely * committed and need not be re-examined by us. (We must consider only * backends connected to our DB, because others will not have bothered to - * check committed-ness of notifications in our DB.) But we only bother - * with that if there's more than a page worth of notifications - * outstanding, otherwise scanning all the other backends isn't worth it. + * check committed-ness of notifications in our DB.) * - * We need exclusive lock here so we can look at other backends' entries. + * We need exclusive lock here so we can look at other backends' entries + * and manipulate the list links. */ LWLockAcquire(AsyncQueueLock, LW_EXCLUSIVE); head = QUEUE_HEAD; max = QUEUE_TAIL; - if (QUEUE_POS_PAGE(max) != QUEUE_POS_PAGE(head)) + prevListener = InvalidBackendId; + for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) { - for (i = 1; i <= MaxBackends; i++) - { - if (QUEUE_BACKEND_DBOID(i) == MyDatabaseId) - max = QUEUE_POS_MAX(max, QUEUE_BACKEND_POS(i)); - } + if (QUEUE_BACKEND_DBOID(i) == MyDatabaseId) + max = QUEUE_POS_MAX(max, QUEUE_BACKEND_POS(i)); + /* Also find last listening backend before this one */ + if (i < MyBackendId) + prevListener = i; } QUEUE_BACKEND_POS(MyBackendId) = max; QUEUE_BACKEND_PID(MyBackendId) = MyProcPid; QUEUE_BACKEND_DBOID(MyBackendId) = MyDatabaseId; + /* Insert backend into list of listeners at correct position */ + if (prevListener > 0) + { + QUEUE_NEXT_LISTENER(MyBackendId) = QUEUE_NEXT_LISTENER(prevListener); + QUEUE_NEXT_LISTENER(prevListener) = MyBackendId; + } + else + { + QUEUE_NEXT_LISTENER(MyBackendId) = QUEUE_FIRST_LISTENER; + QUEUE_FIRST_LISTENER = MyBackendId; + } LWLockRelease(AsyncQueueLock); /* Now we are listed in the global array, so remember we're listening */ @@ -993,8 +1079,6 @@ Exec_ListenPreCommit(void) * notification to the frontend. Also, although our transaction might * have executed NOTIFY, those message(s) aren't queued yet so we can't * see them in the queue. - * - * This will also advance the global tail pointer if possible. */ if (!QUEUE_POS_EQUAL(max, head)) asyncQueueReadAllNotifications(); @@ -1036,23 +1120,20 @@ static void Exec_UnlistenCommit(const char *channel) { ListCell *q; - ListCell *prev; if (Trace_notify) elog(DEBUG1, "Exec_UnlistenCommit(%s,%d)", channel, MyProcPid); - prev = NULL; foreach(q, listenChannels) { char *lchan = (char *) lfirst(q); if (strcmp(lchan, channel) == 0) { - listenChannels = list_delete_cell(listenChannels, q, prev); + listenChannels = foreach_delete_current(listenChannels, q); pfree(lchan); break; } - prev = q; } /* @@ -1083,6 +1164,8 @@ Exec_UnlistenAllCommit(void) * of a transaction. If we issued any notifications in the just-completed * transaction, send signals to other backends to process them, and also * process the queue ourselves to send messages to our own frontend. + * Also, if we filled enough queue pages with new notifies, try to advance + * the queue tail pointer. * * The reason that this is not done in AtCommit_Notify is that there is * a nonzero chance of errors here (for example, encoding conversion errors @@ -1101,7 +1184,6 @@ void ProcessCompletedNotifies(void) { MemoryContext caller_context; - bool signalled; /* Nothing to do if we didn't send any notifications */ if (!backendHasSentNotifications) @@ -1130,23 +1212,20 @@ ProcessCompletedNotifies(void) StartTransactionCommand(); /* Send signals to other backends */ - signalled = SignalBackends(); + SignalBackends(); if (listenChannels != NIL) { /* Read the queue ourselves, and send relevant stuff to the frontend */ asyncQueueReadAllNotifications(); } - else if (!signalled) + + /* + * If it's time to try to advance the global tail pointer, do that. + */ + if (backendTryAdvanceTail) { - /* - * If we found no other listening backends, and we aren't listening - * ourselves, then we must execute asyncQueueAdvanceTail to flush the - * queue, because ain't nobody else gonna do it. This prevents queue - * overflow when we're sending useless notifies to nobody. (A new - * listener could have joined since we looked, but if so this is - * harmless.) - */ + backendTryAdvanceTail = false; asyncQueueAdvanceTail(); } @@ -1187,28 +1266,37 @@ IsListeningOn(const char *channel) static void asyncQueueUnregister(void) { - bool advanceTail; - Assert(listenChannels == NIL); /* else caller error */ if (!amRegisteredListener) /* nothing to do */ return; - LWLockAcquire(AsyncQueueLock, LW_SHARED); - /* check if entry is valid and oldest ... */ - advanceTail = (MyProcPid == QUEUE_BACKEND_PID(MyBackendId)) && - QUEUE_POS_EQUAL(QUEUE_BACKEND_POS(MyBackendId), QUEUE_TAIL); - /* ... then mark it invalid */ + /* + * Need exclusive lock here to manipulate list links. + */ + LWLockAcquire(AsyncQueueLock, LW_EXCLUSIVE); + /* Mark our entry as invalid */ QUEUE_BACKEND_PID(MyBackendId) = InvalidPid; QUEUE_BACKEND_DBOID(MyBackendId) = InvalidOid; + /* and remove it from the list */ + if (QUEUE_FIRST_LISTENER == MyBackendId) + QUEUE_FIRST_LISTENER = QUEUE_NEXT_LISTENER(MyBackendId); + else + { + for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) + { + if (QUEUE_NEXT_LISTENER(i) == MyBackendId) + { + QUEUE_NEXT_LISTENER(i) = QUEUE_NEXT_LISTENER(MyBackendId); + break; + } + } + } + QUEUE_NEXT_LISTENER(MyBackendId) = InvalidBackendId; LWLockRelease(AsyncQueueLock); /* mark ourselves as no longer listed in the global array */ amRegisteredListener = false; - - /* If we were the laziest backend, try to advance the tail pointer */ - if (advanceTail) - asyncQueueAdvanceTail(); } /* @@ -1285,8 +1373,8 @@ asyncQueueAdvance(volatile QueuePosition *position, int entryLength) static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe) { - size_t channellen = strlen(n->channel); - size_t payloadlen = strlen(n->payload); + size_t channellen = n->channel_len; + size_t payloadlen = n->payload_len; int entryLength; Assert(channellen < NAMEDATALEN); @@ -1299,8 +1387,7 @@ asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe) qe->dboid = MyDatabaseId; qe->xid = GetCurrentTransactionId(); qe->srcPid = MyProcPid; - memcpy(qe->data, n->channel, channellen + 1); - memcpy(qe->data + channellen + 1, n->payload, payloadlen + 1); + memcpy(qe->data, n->data, channellen + payloadlen + 2); } /* @@ -1312,9 +1399,9 @@ asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe) * database OID in order to fill the page. So every page is always used up to * the last byte which simplifies reading the page later. * - * We are passed the list cell containing the next notification to write - * and return the first still-unwritten cell back. Eventually we will return - * NULL indicating all is done. + * We are passed the list cell (in pendingNotifies->events) containing the next + * notification to write and return the first still-unwritten cell back. + * Eventually we will return NULL indicating all is done. * * We are holding AsyncQueueLock already from the caller and grab AsyncCtlLock * locally in this function. @@ -1363,7 +1450,7 @@ asyncQueueAddEntries(ListCell *nextNotify) if (offset + qe.length <= QUEUE_PAGESIZE) { /* OK, so advance nextNotify past this item */ - nextNotify = lnext(nextNotify); + nextNotify = lnext(pendingNotifies->events, nextNotify); } else { @@ -1395,6 +1482,15 @@ asyncQueueAddEntries(ListCell *nextNotify) * page without overrunning the queue. */ slotno = SimpleLruZeroPage(AsyncCtl, QUEUE_POS_PAGE(queue_head)); + + /* + * If the new page address is a multiple of QUEUE_CLEANUP_DELAY, + * set flag to remember that we should try to advance the tail + * pointer (we don't want to actually do that right here). + */ + if (QUEUE_POS_PAGE(queue_head) % QUEUE_CLEANUP_DELAY == 0) + backendTryAdvanceTail = true; + /* And exit the loop */ break; } @@ -1475,16 +1571,13 @@ asyncQueueFillWarning(void) { QueuePosition min = QUEUE_HEAD; int32 minPid = InvalidPid; - int i; - for (i = 1; i <= MaxBackends; i++) + for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) { - if (QUEUE_BACKEND_PID(i) != InvalidPid) - { - min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); - if (QUEUE_POS_EQUAL(min, QUEUE_BACKEND_POS(i))) - minPid = QUEUE_BACKEND_PID(i); - } + Assert(QUEUE_BACKEND_PID(i) != InvalidPid); + min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); + if (QUEUE_POS_EQUAL(min, QUEUE_BACKEND_POS(i))) + minPid = QUEUE_BACKEND_PID(i); } ereport(WARNING, @@ -1501,32 +1594,30 @@ asyncQueueFillWarning(void) } /* - * Send signals to all listening backends (except our own). + * Send signals to listening backends. * - * Returns true if we sent at least one signal. + * We never signal our own process; that should be handled by our caller. * - * Since we need EXCLUSIVE lock anyway we also check the position of the other - * backends and in case one is already up-to-date we don't signal it. - * This can happen if concurrent notifying transactions have sent a signal and - * the signaled backend has read the other notifications and ours in the same - * step. + * Normally we signal only backends in our own database, since only those + * backends could be interested in notifies we send. However, if there's + * notify traffic in our database but no traffic in another database that + * does have listener(s), those listeners will fall further and further + * behind. Waken them anyway if they're far enough behind, so that they'll + * advance their queue position pointers, allowing the global tail to advance. * * Since we know the BackendId and the Pid the signalling is quite cheap. */ -static bool +static void SignalBackends(void) { - bool signalled = false; int32 *pids; BackendId *ids; int count; - int i; - int32 pid; /* - * Identify all backends that are listening and not already up-to-date. We - * don't want to send signals while holding the AsyncQueueLock, so we just - * build a list of target PIDs. + * Identify backends that we need to signal. We don't want to send + * signals while holding the AsyncQueueLock, so this loop just builds a + * list of target PIDs. * * XXX in principle these pallocs could fail, which would be bad. Maybe * preallocate the arrays? But in practice this is only run in trivial @@ -1537,27 +1628,45 @@ SignalBackends(void) count = 0; LWLockAcquire(AsyncQueueLock, LW_EXCLUSIVE); - for (i = 1; i <= MaxBackends; i++) + for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) { - pid = QUEUE_BACKEND_PID(i); - if (pid != InvalidPid && pid != MyProcPid) + int32 pid = QUEUE_BACKEND_PID(i); + QueuePosition pos; + + Assert(pid != InvalidPid); + if (pid == MyProcPid) + continue; /* never signal self */ + pos = QUEUE_BACKEND_POS(i); + if (QUEUE_BACKEND_DBOID(i) == MyDatabaseId) { - QueuePosition pos = QUEUE_BACKEND_POS(i); - - if (!QUEUE_POS_EQUAL(pos, QUEUE_HEAD)) - { - pids[count] = pid; - ids[count] = i; - count++; - } + /* + * Always signal listeners in our own database, unless they're + * already caught up (unlikely, but possible). + */ + if (QUEUE_POS_EQUAL(pos, QUEUE_HEAD)) + continue; } + else + { + /* + * Listeners in other databases should be signaled only if they + * are far behind. + */ + if (asyncQueuePageDiff(QUEUE_POS_PAGE(QUEUE_HEAD), + QUEUE_POS_PAGE(pos)) < QUEUE_CLEANUP_DELAY) + continue; + } + /* OK, need to signal this one */ + pids[count] = pid; + ids[count] = i; + count++; } LWLockRelease(AsyncQueueLock); /* Now send signals */ - for (i = 0; i < count; i++) + for (int i = 0; i < count; i++) { - pid = pids[i]; + int32 pid = pids[i]; /* * Note: assuming things aren't broken, a signal failure here could @@ -1567,14 +1676,10 @@ SignalBackends(void) */ if (SendProcSignal(pid, PROCSIG_NOTIFY_INTERRUPT, ids[i]) < 0) elog(DEBUG3, "could not signal backend with PID %d: %m", pid); - else - signalled = true; } pfree(pids); pfree(ids); - - return signalled; } /* @@ -1625,7 +1730,7 @@ AtSubStart_Notify(void) Assert(list_length(upperPendingNotifies) == GetCurrentTransactionNestLevel() - 1); - pendingNotifies = NIL; + pendingNotifies = NULL; MemoryContextSwitchTo(old_cxt); } @@ -1639,7 +1744,7 @@ void AtSubCommit_Notify(void) { List *parentPendingActions; - List *parentPendingNotifies; + NotificationList *parentPendingNotifies; parentPendingActions = linitial_node(List, upperPendingActions); upperPendingActions = list_delete_first(upperPendingActions); @@ -1652,16 +1757,41 @@ AtSubCommit_Notify(void) */ pendingActions = list_concat(parentPendingActions, pendingActions); - parentPendingNotifies = linitial_node(List, upperPendingNotifies); + parentPendingNotifies = (NotificationList *) linitial(upperPendingNotifies); upperPendingNotifies = list_delete_first(upperPendingNotifies); Assert(list_length(upperPendingNotifies) == GetCurrentTransactionNestLevel() - 2); - /* - * We could try to eliminate duplicates here, but it seems not worthwhile. - */ - pendingNotifies = list_concat(parentPendingNotifies, pendingNotifies); + if (pendingNotifies == NULL) + { + /* easy, no notify events happened in current subxact */ + pendingNotifies = parentPendingNotifies; + } + else if (parentPendingNotifies == NULL) + { + /* easy, subxact's list becomes parent's */ + } + else + { + /* + * Formerly, we didn't bother to eliminate duplicates here, but now we + * must, else we fall foul of "Assert(!found)", either here or during + * a later attempt to build the parent-level hashtable. + */ + NotificationList *childPendingNotifies = pendingNotifies; + ListCell *l; + + pendingNotifies = parentPendingNotifies; + /* Insert all the subxact's events into parent, except for dups */ + foreach(l, childPendingNotifies->events) + { + Notification *childn = (Notification *) lfirst(l); + + if (!AsyncExistsPendingNotify(childn)) + AddEventToPendingNotifies(childn); + } + } } /* @@ -1690,7 +1820,7 @@ AtSubAbort_Notify(void) while (list_length(upperPendingNotifies) > my_level - 2) { - pendingNotifies = linitial_node(List, upperPendingNotifies); + pendingNotifies = (NotificationList *) linitial(upperPendingNotifies); upperPendingNotifies = list_delete_first(upperPendingNotifies); } } @@ -1750,7 +1880,6 @@ asyncQueueReadAllNotifications(void) QueuePosition oldpos; QueuePosition head; Snapshot snapshot; - bool advanceTail; /* page_buffer must be adequately aligned, so use a union */ union @@ -1872,13 +2001,8 @@ asyncQueueReadAllNotifications(void) /* Update shared state */ LWLockAcquire(AsyncQueueLock, LW_SHARED); QUEUE_BACKEND_POS(MyBackendId) = pos; - advanceTail = QUEUE_POS_EQUAL(oldpos, QUEUE_TAIL); LWLockRelease(AsyncQueueLock); - /* If we were the laziest backend, try to advance the tail pointer */ - if (advanceTail) - asyncQueueAdvanceTail(); - PG_RE_THROW(); } PG_END_TRY(); @@ -1886,13 +2010,8 @@ asyncQueueReadAllNotifications(void) /* Update shared state */ LWLockAcquire(AsyncQueueLock, LW_SHARED); QUEUE_BACKEND_POS(MyBackendId) = pos; - advanceTail = QUEUE_POS_EQUAL(oldpos, QUEUE_TAIL); LWLockRelease(AsyncQueueLock); - /* If we were the laziest backend, try to advance the tail pointer */ - if (advanceTail) - asyncQueueAdvanceTail(); - /* Done with snapshot */ UnregisterSnapshot(snapshot); } @@ -1956,7 +2075,7 @@ asyncQueueProcessPageEntries(volatile QueuePosition *current, * Note that we must test XidInMVCCSnapshot before we test * TransactionIdDidCommit, else we might return a message from * a transaction that is not yet visible to snapshots; compare - * the comments at the head of tqual.c. + * the comments at the head of heapam_visibility.c. * * Also, while our own xact won't be listed in the snapshot, * we need not check for TransactionIdIsCurrentTransactionId @@ -2006,17 +2125,16 @@ static void asyncQueueAdvanceTail(void) { QueuePosition min; - int i; int oldtailpage; int newtailpage; int boundary; LWLockAcquire(AsyncQueueLock, LW_EXCLUSIVE); min = QUEUE_HEAD; - for (i = 1; i <= MaxBackends; i++) + for (BackendId i = QUEUE_FIRST_LISTENER; i > 0; i = QUEUE_NEXT_LISTENER(i)) { - if (QUEUE_BACKEND_PID(i) != InvalidPid) - min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); + Assert(QUEUE_BACKEND_PID(i) != InvalidPid); + min = QUEUE_POS_MIN(min, QUEUE_BACKEND_POS(i)); } oldtailpage = QUEUE_POS_PAGE(QUEUE_TAIL); QUEUE_TAIL = min; @@ -2116,52 +2234,139 @@ NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) elog(INFO, "NOTIFY for \"%s\" payload \"%s\"", channel, payload); } -/* Does pendingNotifies include the given channel/payload? */ +/* Does pendingNotifies include a match for the given event? */ static bool -AsyncExistsPendingNotify(const char *channel, const char *payload) +AsyncExistsPendingNotify(Notification *n) { - ListCell *p; - Notification *n; - - if (pendingNotifies == NIL) + if (pendingNotifies == NULL) return false; - if (payload == NULL) - payload = ""; + if (pendingNotifies->hashtab != NULL) + { + /* Use the hash table to probe for a match */ + if (hash_search(pendingNotifies->hashtab, + &n, + HASH_FIND, + NULL)) + return true; + } + else + { + /* Must scan the event list */ + ListCell *l; - /*---------- - * We need to append new elements to the end of the list in order to keep - * the order. However, on the other hand we'd like to check the list - * backwards in order to make duplicate-elimination a tad faster when the - * same condition is signaled many times in a row. So as a compromise we - * check the tail element first which we can access directly. If this - * doesn't match, we check the whole list. - * - * As we are not checking our parents' lists, we can still get duplicates - * in combination with subtransactions, like in: - * - * begin; - * notify foo '1'; - * savepoint foo; - * notify foo '1'; - * commit; - *---------- - */ - n = (Notification *) llast(pendingNotifies); - if (strcmp(n->channel, channel) == 0 && - strcmp(n->payload, payload) == 0) - return true; + foreach(l, pendingNotifies->events) + { + Notification *oldn = (Notification *) lfirst(l); + + if (n->channel_len == oldn->channel_len && + n->payload_len == oldn->payload_len && + memcmp(n->data, oldn->data, + n->channel_len + n->payload_len + 2) == 0) + return true; + } + } + + return false; +} + +/* + * Add a notification event to a pre-existing pendingNotifies list. + * + * Because pendingNotifies->events is already nonempty, this works + * correctly no matter what CurrentMemoryContext is. + */ +static void +AddEventToPendingNotifies(Notification *n) +{ + Assert(pendingNotifies->events != NIL); - foreach(p, pendingNotifies) + /* Create the hash table if it's time to */ + if (list_length(pendingNotifies->events) >= MIN_HASHABLE_NOTIFIES && + pendingNotifies->hashtab == NULL) { - n = (Notification *) lfirst(p); + HASHCTL hash_ctl; + ListCell *l; + + /* Create the hash table */ + MemSet(&hash_ctl, 0, sizeof(hash_ctl)); + hash_ctl.keysize = sizeof(Notification *); + hash_ctl.entrysize = sizeof(NotificationHash); + hash_ctl.hash = notification_hash; + hash_ctl.match = notification_match; + hash_ctl.hcxt = CurTransactionContext; + pendingNotifies->hashtab = + hash_create("Pending Notifies", + 256L, + &hash_ctl, + HASH_ELEM | HASH_FUNCTION | HASH_COMPARE | HASH_CONTEXT); + + /* Insert all the already-existing events */ + foreach(l, pendingNotifies->events) + { + Notification *oldn = (Notification *) lfirst(l); + NotificationHash *hentry; + bool found; + + hentry = (NotificationHash *) hash_search(pendingNotifies->hashtab, + &oldn, + HASH_ENTER, + &found); + Assert(!found); + hentry->event = oldn; + } + } - if (strcmp(n->channel, channel) == 0 && - strcmp(n->payload, payload) == 0) - return true; + /* Add new event to the list, in order */ + pendingNotifies->events = lappend(pendingNotifies->events, n); + + /* Add event to the hash table if needed */ + if (pendingNotifies->hashtab != NULL) + { + NotificationHash *hentry; + bool found; + + hentry = (NotificationHash *) hash_search(pendingNotifies->hashtab, + &n, + HASH_ENTER, + &found); + Assert(!found); + hentry->event = n; } +} - return false; +/* + * notification_hash: hash function for notification hash table + * + * The hash "keys" are pointers to Notification structs. + */ +static uint32 +notification_hash(const void *key, Size keysize) +{ + const Notification *k = *(const Notification *const *) key; + + Assert(keysize == sizeof(Notification *)); + /* We don't bother to include the payload's trailing null in the hash */ + return DatumGetUInt32(hash_any((const unsigned char *) k->data, + k->channel_len + k->payload_len + 1)); +} + +/* + * notification_match: match function to use with notification_hash + */ +static int +notification_match(const void *key1, const void *key2, Size keysize) +{ + const Notification *k1 = *(const Notification *const *) key1; + const Notification *k2 = *(const Notification *const *) key2; + + Assert(keysize == sizeof(Notification *)); + if (k1->channel_len == k2->channel_len && + k1->payload_len == k2->payload_len && + memcmp(k1->data, k2->data, + k1->channel_len + k1->payload_len + 2) == 0) + return 0; /* equal */ + return 1; /* not equal */ } /* Clear the pendingActions and pendingNotifies lists. */ @@ -2176,5 +2381,5 @@ ClearPendingActionsAndNotifies(void) * pointers. */ pendingActions = NIL; - pendingNotifies = NIL; + pendingNotifies = NULL; } diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index d088dc11a67..a23128d7a09 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -6,7 +6,7 @@ * There is hardly anything left of Paul Brown's original implementation... * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -18,11 +18,12 @@ #include "postgres.h" #include "access/amapi.h" +#include "access/heapam.h" #include "access/multixact.h" #include "access/relscan.h" -#include "access/rewriteheap.h" +#include "access/tableam.h" #include "access/transam.h" -#include "access/tuptoaster.h" +#include "access/toast_internals.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/pg_am.h" @@ -34,14 +35,15 @@ #include "catalog/objectaccess.h" #include "catalog/toasting.h" #include "commands/cluster.h" +#include "commands/progress.h" #include "commands/tablecmds.h" #include "commands/vacuum.h" #include "miscadmin.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" +#include "pgstat.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "storage/predicate.h" -#include "storage/smgr.h" #include "utils/acl.h" #include "utils/fmgroids.h" #include "utils/inval.h" @@ -51,7 +53,6 @@ #include "utils/relmapper.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #include "utils/tuplesort.h" @@ -68,14 +69,10 @@ typedef struct static void rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose); -static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, - bool verbose, bool *pSwapToastByContent, - TransactionId *pFreezeXid, MultiXactId *pCutoffMulti); +static void copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, + bool verbose, bool *pSwapToastByContent, + TransactionId *pFreezeXid, MultiXactId *pCutoffMulti); static List *get_tables_to_cluster(MemoryContext cluster_context); -static void reform_and_rewrite_tuple(HeapTuple tuple, - TupleDesc oldTupDesc, TupleDesc newTupDesc, - Datum *values, bool *isnull, - bool newRelHasOids, RewriteState rwstate); /*--------------------------------------------------------------------------- @@ -117,7 +114,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel) AccessExclusiveLock, 0, RangeVarCallbackOwnsTable, NULL); - rel = heap_open(tableOid, NoLock); + rel = table_open(tableOid, NoLock); /* * Reject clustering a remote temp table ... their local buffer @@ -183,10 +180,10 @@ cluster(ClusterStmt *stmt, bool isTopLevel) } /* close relation, keep lock till commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); /* Do the job. */ - cluster_rel(tableOid, indexOid, false, stmt->verbose); + cluster_rel(tableOid, indexOid, stmt->options); } else { @@ -234,7 +231,8 @@ cluster(ClusterStmt *stmt, bool isTopLevel) /* functions in indexes may want a snapshot set */ PushActiveSnapshot(GetTransactionSnapshot()); /* Do the job. */ - cluster_rel(rvtc->tableOid, rvtc->indexOid, true, stmt->verbose); + cluster_rel(rvtc->tableOid, rvtc->indexOid, + stmt->options | CLUOPT_RECHECK); PopActiveSnapshot(); CommitTransactionCommand(); } @@ -265,13 +263,23 @@ cluster(ClusterStmt *stmt, bool isTopLevel) * and error messages should refer to the operation as VACUUM not CLUSTER. */ void -cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) +cluster_rel(Oid tableOid, Oid indexOid, int options) { Relation OldHeap; + bool verbose = ((options & CLUOPT_VERBOSE) != 0); + bool recheck = ((options & CLUOPT_RECHECK) != 0); /* Check for user-requested abort. */ CHECK_FOR_INTERRUPTS(); + pgstat_progress_start_command(PROGRESS_COMMAND_CLUSTER, tableOid); + if (OidIsValid(indexOid)) + pgstat_progress_update_param(PROGRESS_CLUSTER_COMMAND, + PROGRESS_CLUSTER_COMMAND_CLUSTER); + else + pgstat_progress_update_param(PROGRESS_CLUSTER_COMMAND, + PROGRESS_CLUSTER_COMMAND_VACUUM_FULL); + /* * We grab exclusive access to the target rel and index for the duration * of the transaction. (This is redundant for the single-transaction @@ -282,7 +290,10 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) /* If the table has gone away, we can skip processing it */ if (!OldHeap) + { + pgstat_progress_end_command(); return; + } /* * Since we may open a new transaction for each relation, we have to check @@ -301,6 +312,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) if (!pg_class_ownercheck(tableOid, GetUserId())) { relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } @@ -315,6 +327,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) if (RELATION_IS_OTHER_TEMP(OldHeap)) { relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } @@ -326,6 +339,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(indexOid))) { relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } @@ -336,6 +350,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) if (!HeapTupleIsValid(tuple)) /* probably can't happen */ { relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } indexForm = (Form_pg_index) GETSTRUCT(tuple); @@ -343,6 +358,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) { ReleaseSysCache(tuple); relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } ReleaseSysCache(tuple); @@ -397,6 +413,7 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) !RelationIsPopulated(OldHeap)) { relation_close(OldHeap, AccessExclusiveLock); + pgstat_progress_end_command(); return; } @@ -411,7 +428,9 @@ cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) /* rebuild_relation does all the dirty work */ rebuild_relation(OldHeap, indexOid, verbose); - /* NB: rebuild_relation does heap_close() on OldHeap */ + /* NB: rebuild_relation does table_close() on OldHeap */ + + pgstat_progress_end_command(); } /* @@ -441,7 +460,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMOD RelationGetRelationName(OldHeap)))); /* Index AM must allow clustering */ - if (!OldIndex->rd_amroutine->amclusterable) + if (!OldIndex->rd_indam->amclusterable) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot cluster on index \"%s\" because access method does not support clustering", @@ -467,7 +486,7 @@ check_index_is_clusterable(Relation OldHeap, Oid indexOid, bool recheck, LOCKMOD * might put recently-dead tuples out-of-order in the new table, and there * is little harm in that.) */ - if (!IndexIsValid(OldIndex->rd_index)) + if (!OldIndex->rd_index->indisvalid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot cluster on invalid index \"%s\"", @@ -518,7 +537,7 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) /* * Check each index of the relation and set/clear the bit as needed. */ - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); foreach(index, RelationGetIndexList(rel)) { @@ -542,7 +561,7 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) else if (thisIndexOid == indexOid) { /* this was checked earlier, but let's be real sure */ - if (!IndexIsValid(indexForm)) + if (!indexForm->indisvalid) elog(ERROR, "cannot cluster on invalid index %u", indexOid); indexForm->indisclustered = true; CatalogTupleUpdate(pg_index, &indexTuple->t_self, indexTuple); @@ -554,7 +573,7 @@ mark_index_clustered(Relation rel, Oid indexOid, bool is_internal) heap_freetuple(indexTuple); } - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); } /* @@ -586,7 +605,7 @@ rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose) is_system_catalog = IsSystemRelation(OldHeap); /* Close relcache entry, but keep lock until transaction commit */ - heap_close(OldHeap, NoLock); + table_close(OldHeap, NoLock); /* Create the transient table that will receive the re-ordered data */ OIDNewHeap = make_new_heap(tableOid, tableSpace, @@ -594,8 +613,8 @@ rebuild_relation(Relation OldHeap, Oid indexOid, bool verbose) AccessExclusiveLock); /* Copy the heap data into the new table in the desired order */ - copy_heap_data(OIDNewHeap, tableOid, indexOid, verbose, - &swap_toast_by_content, &frozenXid, &cutoffMulti); + copy_table_data(OIDNewHeap, tableOid, indexOid, verbose, + &swap_toast_by_content, &frozenXid, &cutoffMulti); /* * Swap the physical files of the target and transient tables, then @@ -632,7 +651,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, bool isNull; Oid namespaceid; - OldHeap = heap_open(OIDOldHeap, lockmode); + OldHeap = table_open(OIDOldHeap, lockmode); OldHeapDesc = RelationGetDescr(OldHeap); /* @@ -679,14 +698,13 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, InvalidOid, InvalidOid, OldHeap->rd_rel->relowner, + OldHeap->rd_rel->relam, OldHeapDesc, NIL, RELKIND_RELATION, relpersistence, false, RelationIsMapped(OldHeap), - true, - 0, ONCOMMIT_NOOP, reloptions, false, @@ -700,7 +718,7 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, /* * Advance command counter so that the newly-created relation's catalog - * tuples will be visible to heap_open. + * tuples will be visible to table_open. */ CommandCounterIncrement(); @@ -732,13 +750,13 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, ReleaseSysCache(tuple); } - heap_close(OldHeap, NoLock); + table_close(OldHeap, NoLock); return OIDNewHeap; } /* - * Do the physical copying of heap data. + * Do the physical copying of table data. * * There are three output parameters: * *pSwapToastByContent is set true if toast tables must be swapped by content. @@ -746,9 +764,9 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, * *pCutoffMulti receives the MultiXactId used as a cutoff point. */ static void -copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, - bool *pSwapToastByContent, TransactionId *pFreezeXid, - MultiXactId *pCutoffMulti) +copy_table_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, + bool *pSwapToastByContent, TransactionId *pFreezeXid, + MultiXactId *pCutoffMulti) { Relation NewHeap, OldHeap, @@ -756,21 +774,12 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, Relation relRelation; HeapTuple reltup; Form_pg_class relform; - TupleDesc oldTupDesc; - TupleDesc newTupDesc; - int natts; - Datum *values; - bool *isnull; - IndexScanDesc indexScan; - HeapScanDesc heapScan; - bool use_wal; - bool is_system_catalog; + TupleDesc oldTupDesc PG_USED_FOR_ASSERTS_ONLY; + TupleDesc newTupDesc PG_USED_FOR_ASSERTS_ONLY; TransactionId OldestXmin; TransactionId FreezeXid; MultiXactId MultiXactCutoff; - RewriteState rwstate; bool use_sort; - Tuplesortstate *tuplesort; double num_tuples = 0, tups_vacuumed = 0, tups_recently_dead = 0; @@ -783,8 +792,8 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, /* * Open the relations we need. */ - NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock); - OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock); + NewHeap = table_open(OIDNewHeap, AccessExclusiveLock); + OldHeap = table_open(OIDOldHeap, AccessExclusiveLock); if (OidIsValid(OIDOldIndex)) OldIndex = index_open(OIDOldIndex, AccessExclusiveLock); else @@ -798,11 +807,6 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, newTupDesc = RelationGetDescr(NewHeap); Assert(newTupDesc->natts == oldTupDesc->natts); - /* Preallocate values/isnull arrays */ - natts = newTupDesc->natts; - values = (Datum *) palloc(natts * sizeof(Datum)); - isnull = (bool *) palloc(natts * sizeof(bool)); - /* * If the OldHeap has a toast table, get lock on the toast table to keep * it from being vacuumed. This is needed because autovacuum processes @@ -819,15 +823,6 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, if (OldHeap->rd_rel->reltoastrelid) LockRelationOid(OldHeap->rd_rel->reltoastrelid, AccessExclusiveLock); - /* - * We need to log the copied data in WAL iff WAL archiving/streaming is - * enabled AND it's a WAL-logged rel. - */ - use_wal = XLogIsNeeded() && RelationNeedsWAL(NewHeap); - - /* use_wal off requires smgr_targblock be initially invalid */ - Assert(RelationGetTargetBlock(NewHeap) == InvalidBlockNumber); - /* * If both tables have TOAST tables, perform toast swap by content. It is * possible that the old table has a toast table but the new one doesn't, @@ -875,26 +870,17 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, * FreezeXid will become the table's new relfrozenxid, and that mustn't go * backwards, so take the max. */ - if (TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid)) + if (TransactionIdIsValid(OldHeap->rd_rel->relfrozenxid) && + TransactionIdPrecedes(FreezeXid, OldHeap->rd_rel->relfrozenxid)) FreezeXid = OldHeap->rd_rel->relfrozenxid; /* * MultiXactCutoff, similarly, shouldn't go backwards either. */ - if (MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid)) + if (MultiXactIdIsValid(OldHeap->rd_rel->relminmxid) && + MultiXactIdPrecedes(MultiXactCutoff, OldHeap->rd_rel->relminmxid)) MultiXactCutoff = OldHeap->rd_rel->relminmxid; - /* return selected values to caller */ - *pFreezeXid = FreezeXid; - *pCutoffMulti = MultiXactCutoff; - - /* Remember if it's a system catalog */ - is_system_catalog = IsSystemRelation(OldHeap); - - /* Initialize the rewrite operation */ - rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin, FreezeXid, - MultiXactCutoff, use_wal); - /* * Decide whether to use an indexscan or seqscan-and-optional-sort to scan * the OldHeap. We know how to use a sort to duplicate the ordering of a @@ -907,39 +893,14 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, else use_sort = false; - /* Set up sorting if wanted */ - if (use_sort) - tuplesort = tuplesort_begin_cluster(oldTupDesc, OldIndex, - maintenance_work_mem, - NULL, false); - else - tuplesort = NULL; - - /* - * Prepare to scan the OldHeap. To ensure we see recently-dead tuples - * that still need to be copied, we scan with SnapshotAny and use - * HeapTupleSatisfiesVacuum for the visibility test. - */ - if (OldIndex != NULL && !use_sort) - { - heapScan = NULL; - indexScan = index_beginscan(OldHeap, OldIndex, SnapshotAny, 0, 0); - index_rescan(indexScan, NULL, 0, NULL, 0); - } - else - { - heapScan = heap_beginscan(OldHeap, SnapshotAny, 0, (ScanKey) NULL); - indexScan = NULL; - } - /* Log what we're doing */ - if (indexScan != NULL) + if (OldIndex != NULL && !use_sort) ereport(elevel, (errmsg("clustering \"%s.%s\" using index scan on \"%s\"", get_namespace_name(RelationGetNamespace(OldHeap)), RelationGetRelationName(OldHeap), RelationGetRelationName(OldIndex)))); - else if (tuplesort != NULL) + else if (use_sort) ereport(elevel, (errmsg("clustering \"%s.%s\" using sequential scan and sort", get_namespace_name(RelationGetNamespace(OldHeap)), @@ -951,150 +912,19 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, RelationGetRelationName(OldHeap)))); /* - * Scan through the OldHeap, either in OldIndex order or sequentially; - * copy each tuple into the NewHeap, or transiently to the tuplesort - * module. Note that we don't bother sorting dead tuples (they won't get - * to the new table anyway). - */ - for (;;) - { - HeapTuple tuple; - Buffer buf; - bool isdead; - - CHECK_FOR_INTERRUPTS(); - - if (indexScan != NULL) - { - tuple = index_getnext(indexScan, ForwardScanDirection); - if (tuple == NULL) - break; - - /* Since we used no scan keys, should never need to recheck */ - if (indexScan->xs_recheck) - elog(ERROR, "CLUSTER does not support lossy index conditions"); - - buf = indexScan->xs_cbuf; - } - else - { - tuple = heap_getnext(heapScan, ForwardScanDirection); - if (tuple == NULL) - break; - - buf = heapScan->rs_cbuf; - } - - LockBuffer(buf, BUFFER_LOCK_SHARE); - - switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf)) - { - case HEAPTUPLE_DEAD: - /* Definitely dead */ - isdead = true; - break; - case HEAPTUPLE_RECENTLY_DEAD: - tups_recently_dead += 1; - /* fall through */ - case HEAPTUPLE_LIVE: - /* Live or recently dead, must copy it */ - isdead = false; - break; - case HEAPTUPLE_INSERT_IN_PROGRESS: - - /* - * Since we hold exclusive lock on the relation, normally the - * only way to see this is if it was inserted earlier in our - * own transaction. However, it can happen in system - * catalogs, since we tend to release write lock before commit - * there. Give a warning if neither case applies; but in any - * case we had better copy it. - */ - if (!is_system_catalog && - !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple->t_data))) - elog(WARNING, "concurrent insert in progress within table \"%s\"", - RelationGetRelationName(OldHeap)); - /* treat as live */ - isdead = false; - break; - case HEAPTUPLE_DELETE_IN_PROGRESS: - - /* - * Similar situation to INSERT_IN_PROGRESS case. - */ - if (!is_system_catalog && - !TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple->t_data))) - elog(WARNING, "concurrent delete in progress within table \"%s\"", - RelationGetRelationName(OldHeap)); - /* treat as recently dead */ - tups_recently_dead += 1; - isdead = false; - break; - default: - elog(ERROR, "unexpected HeapTupleSatisfiesVacuum result"); - isdead = false; /* keep compiler quiet */ - break; - } - - LockBuffer(buf, BUFFER_LOCK_UNLOCK); - - if (isdead) - { - tups_vacuumed += 1; - /* heap rewrite module still needs to see it... */ - if (rewrite_heap_dead_tuple(rwstate, tuple)) - { - /* A previous recently-dead tuple is now known dead */ - tups_vacuumed += 1; - tups_recently_dead -= 1; - } - continue; - } - - num_tuples += 1; - if (tuplesort != NULL) - tuplesort_putheaptuple(tuplesort, tuple); - else - reform_and_rewrite_tuple(tuple, - oldTupDesc, newTupDesc, - values, isnull, - NewHeap->rd_rel->relhasoids, rwstate); - } - - if (indexScan != NULL) - index_endscan(indexScan); - if (heapScan != NULL) - heap_endscan(heapScan); - - /* - * In scan-and-sort mode, complete the sort, then read out all live tuples - * from the tuplestore and write them to the new relation. + * Hand of the actual copying to AM specific function, the generic code + * cannot know how to deal with visibility across AMs. Note that this + * routine is allowed to set FreezeXid / MultiXactCutoff to different + * values (e.g. because the AM doesn't use freezing). */ - if (tuplesort != NULL) - { - tuplesort_performsort(tuplesort); - - for (;;) - { - HeapTuple tuple; - - CHECK_FOR_INTERRUPTS(); - - tuple = tuplesort_getheaptuple(tuplesort, true); - if (tuple == NULL) - break; + table_relation_copy_for_cluster(OldHeap, NewHeap, OldIndex, use_sort, + OldestXmin, &FreezeXid, &MultiXactCutoff, + &num_tuples, &tups_vacuumed, + &tups_recently_dead); - reform_and_rewrite_tuple(tuple, - oldTupDesc, newTupDesc, - values, isnull, - NewHeap->rd_rel->relhasoids, rwstate); - } - - tuplesort_end(tuplesort); - } - - /* Write out any remaining tuples, and fsync if needed */ - end_heap_rewrite(rwstate); + /* return selected values to caller, get set as relfrozenxid/minmxid */ + *pFreezeXid = FreezeXid; + *pCutoffMulti = MultiXactCutoff; /* Reset rd_toastoid just to be tidy --- it shouldn't be looked at again */ NewHeap->rd_toastoid = InvalidOid; @@ -1112,17 +942,13 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, tups_recently_dead, pg_rusage_show(&ru0)))); - /* Clean up */ - pfree(values); - pfree(isnull); - if (OldIndex != NULL) index_close(OldIndex, NoLock); - heap_close(OldHeap, NoLock); - heap_close(NewHeap, NoLock); + table_close(OldHeap, NoLock); + table_close(NewHeap, NoLock); /* Update pg_class to reflect the correct values of pages and tuples. */ - relRelation = heap_open(RelationRelationId, RowExclusiveLock); + relRelation = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(OIDNewHeap)); if (!HeapTupleIsValid(reltup)) @@ -1140,7 +966,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose, /* Clean up. */ heap_freetuple(reltup); - heap_close(relRelation, RowExclusiveLock); + table_close(relRelation, RowExclusiveLock); /* Make the update visible */ CommandCounterIncrement(); @@ -1191,7 +1017,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, char swptmpchr; /* We need writable copies of both pg_class tuples. */ - relRelation = heap_open(RelationRelationId, RowExclusiveLock); + relRelation = table_open(RelationRelationId, RowExclusiveLock); reltup1 = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(r1)); if (!HeapTupleIsValid(reltup1)) @@ -1296,9 +1122,9 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, /* set rel1's frozen Xid and minimum MultiXid */ if (relform1->relkind != RELKIND_INDEX) { - Assert(TransactionIdIsNormal(frozenXid)); + Assert(!TransactionIdIsValid(frozenXid) || + TransactionIdIsNormal(frozenXid)); relform1->relfrozenxid = frozenXid; - Assert(MultiXactIdIsValid(cutoffMulti)); relform1->relminmxid = cutoffMulti; } @@ -1485,7 +1311,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class, heap_freetuple(reltup1); heap_freetuple(reltup2); - heap_close(relRelation, RowExclusiveLock); + table_close(relRelation, RowExclusiveLock); /* * Close both relcache entries' smgr links. We need this kluge because @@ -1526,6 +1352,10 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, int reindex_flags; int i; + /* Report that we are now swapping relation files */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_SWAP_REL_FILES); + /* Zero out possible results from swapped_relation_files */ memset(mapped_tables, 0, sizeof(mapped_tables)); @@ -1539,8 +1369,8 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, frozenXid, cutoffMulti, mapped_tables); /* - * If it's a system catalog, queue a sinval message to flush all - * catcaches on the catalog when we reach CommandCounterIncrement. + * If it's a system catalog, queue a sinval message to flush all catcaches + * on the catalog when we reach CommandCounterIncrement. */ if (is_system_catalog) CacheInvalidateCatalog(OIDOldHeap); @@ -1573,15 +1403,23 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, else if (newrelpersistence == RELPERSISTENCE_PERMANENT) reindex_flags |= REINDEX_REL_FORCE_INDEXES_PERMANENT; + /* Report that we are now reindexing relations */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_REBUILD_INDEX); + reindex_relation(OIDOldHeap, reindex_flags, 0); + /* Report that we are now doing clean up */ + pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE, + PROGRESS_CLUSTER_PHASE_FINAL_CLEANUP); + /* * If the relation being rebuild is pg_class, swap_relation_files() * couldn't update pg_class's own pg_class entry (check comments in * swap_relation_files()), thus relfrozenxid was not updated. That's * annoying because a potential reason for doing a VACUUM FULL is a * imminent or actual anti-wraparound shutdown. So, now that we can - * access the new relation using it's indices, update relfrozenxid. + * access the new relation using its indices, update relfrozenxid. * pg_class doesn't have a toast relation, so we don't need to update the * corresponding toast relation. Not that there's little point moving all * relfrozenxid updates here since swap_relation_files() needs to write to @@ -1593,7 +1431,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, HeapTuple reltup; Form_pg_class relform; - relRelation = heap_open(RelationRelationId, RowExclusiveLock); + relRelation = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(OIDOldHeap)); if (!HeapTupleIsValid(reltup)) @@ -1605,7 +1443,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, CatalogTupleUpdate(relRelation, &reltup->t_self, reltup); - heap_close(relRelation, RowExclusiveLock); + table_close(relRelation, RowExclusiveLock); } /* Destroy new heap with old filenode */ @@ -1644,7 +1482,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, { Relation newrel; - newrel = heap_open(OIDOldHeap, NoLock); + newrel = table_open(OIDOldHeap, NoLock); if (OidIsValid(newrel->rd_rel->reltoastrelid)) { Oid toastidx; @@ -1658,14 +1496,14 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u", OIDOldHeap); RenameRelationInternal(newrel->rd_rel->reltoastrelid, - NewToastName, true); + NewToastName, true, false); /* ... and its valid index too. */ snprintf(NewToastName, NAMEDATALEN, "pg_toast_%u_index", OIDOldHeap); RenameRelationInternal(toastidx, - NewToastName, true); + NewToastName, true, true); } relation_close(newrel, NoLock); } @@ -1675,7 +1513,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, { Relation newrel; - newrel = heap_open(OIDOldHeap, NoLock); + newrel = table_open(OIDOldHeap, NoLock); RelationClearMissing(newrel); relation_close(newrel, NoLock); } @@ -1684,7 +1522,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, /* * Get a list of tables that the current user owns and - * have indisclustered set. Return the list in a List * of rvsToCluster + * have indisclustered set. Return the list in a List * of RelToCluster * with the tableOid and the indexOid on which the table is already * clustered. */ @@ -1692,7 +1530,7 @@ static List * get_tables_to_cluster(MemoryContext cluster_context) { Relation indRelation; - HeapScanDesc scan; + TableScanDesc scan; ScanKeyData entry; HeapTuple indexTuple; Form_pg_index index; @@ -1706,12 +1544,12 @@ get_tables_to_cluster(MemoryContext cluster_context) * have indisclustered set, because CLUSTER will refuse to set it when * called with one of them as argument. */ - indRelation = heap_open(IndexRelationId, AccessShareLock); + indRelation = table_open(IndexRelationId, AccessShareLock); ScanKeyInit(&entry, Anum_pg_index_indisclustered, BTEqualStrategyNumber, F_BOOLEQ, BoolGetDatum(true)); - scan = heap_beginscan_catalog(indRelation, 1, &entry); + scan = table_beginscan_catalog(indRelation, 1, &entry); while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { index = (Form_pg_index) GETSTRUCT(indexTuple); @@ -1728,60 +1566,13 @@ get_tables_to_cluster(MemoryContext cluster_context) rvtc = (RelToCluster *) palloc(sizeof(RelToCluster)); rvtc->tableOid = index->indrelid; rvtc->indexOid = index->indexrelid; - rvs = lcons(rvtc, rvs); + rvs = lappend(rvs, rvtc); MemoryContextSwitchTo(old_context); } - heap_endscan(scan); + table_endscan(scan); relation_close(indRelation, AccessShareLock); return rvs; } - - -/* - * Reconstruct and rewrite the given tuple - * - * We cannot simply copy the tuple as-is, for several reasons: - * - * 1. We'd like to squeeze out the values of any dropped columns, both - * to save space and to ensure we have no corner-case failures. (It's - * possible for example that the new table hasn't got a TOAST table - * and so is unable to store any large values of dropped cols.) - * - * 2. The tuple might not even be legal for the new table; this is - * currently only known to happen as an after-effect of ALTER TABLE - * SET WITHOUT OIDS. - * - * So, we must reconstruct the tuple from component Datums. - */ -static void -reform_and_rewrite_tuple(HeapTuple tuple, - TupleDesc oldTupDesc, TupleDesc newTupDesc, - Datum *values, bool *isnull, - bool newRelHasOids, RewriteState rwstate) -{ - HeapTuple copiedTuple; - int i; - - heap_deform_tuple(tuple, oldTupDesc, values, isnull); - - /* Be sure to null out any dropped columns */ - for (i = 0; i < newTupDesc->natts; i++) - { - if (TupleDescAttr(newTupDesc, i)->attisdropped) - isnull[i] = true; - } - - copiedTuple = heap_form_tuple(newTupDesc, values, isnull); - - /* Preserve OID, if any */ - if (newRelHasOids) - HeapTupleSetOid(copiedTuple, HeapTupleGetOid(tuple)); - - /* The heap rewrite module does the rest */ - rewrite_heap_tuple(rwstate, tuple, copiedTuple); - - heap_freetuple(copiedTuple); -} diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index 8fb51e8c3d1..919e092483a 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -3,7 +3,7 @@ * collationcmds.c * collation-related commands support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,8 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" @@ -59,10 +59,12 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e DefElem *lccollateEl = NULL; DefElem *lcctypeEl = NULL; DefElem *providerEl = NULL; + DefElem *deterministicEl = NULL; DefElem *versionEl = NULL; char *collcollate = NULL; char *collctype = NULL; char *collproviderstr = NULL; + bool collisdeterministic = true; int collencoding = 0; char collprovider = 0; char *collversion = NULL; @@ -91,6 +93,8 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e defelp = &lcctypeEl; else if (strcmp(defel->defname, "provider") == 0) defelp = &providerEl; + else if (strcmp(defel->defname, "deterministic") == 0) + defelp = &deterministicEl; else if (strcmp(defel->defname, "version") == 0) defelp = &versionEl; else @@ -125,6 +129,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate)); collctype = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collctype)); collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider; + collisdeterministic = ((Form_pg_collation) GETSTRUCT(tp))->collisdeterministic; collencoding = ((Form_pg_collation) GETSTRUCT(tp))->collencoding; ReleaseSysCache(tp); @@ -157,6 +162,9 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e if (providerEl) collproviderstr = defGetString(providerEl); + if (deterministicEl) + collisdeterministic = defGetBoolean(deterministicEl); + if (versionEl) collversion = defGetString(versionEl); @@ -185,6 +193,16 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("parameter \"lc_ctype\" must be specified"))); + /* + * Nondeterministic collations are currently only supported with ICU + * because that's the only case where it can actually make a difference. + * So we can save writing the code for the other providers. + */ + if (!collisdeterministic && collprovider != COLLPROVIDER_ICU) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations not supported with this provider"))); + if (!fromEl) { if (collprovider == COLLPROVIDER_ICU) @@ -203,6 +221,7 @@ DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_e collNamespace, GetUserId(), collprovider, + collisdeterministic, collencoding, collcollate, collctype, @@ -273,7 +292,7 @@ AlterCollation(AlterCollationStmt *stmt) char *newversion; ObjectAddress address; - rel = heap_open(CollationRelationId, RowExclusiveLock); + rel = table_open(CollationRelationId, RowExclusiveLock); collOid = get_collation_oid(stmt->collname, false); if (!pg_collation_ownercheck(collOid, GetUserId())) @@ -325,7 +344,7 @@ AlterCollation(AlterCollationStmt *stmt) ObjectAddressSet(address, CollationRelationId, collOid); heap_freetuple(tup); - heap_close(rel, NoLock); + table_close(rel, NoLock); return address; } @@ -586,7 +605,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) * about existing ones. */ collid = CollationCreate(localebuf, nspid, GetUserId(), - COLLPROVIDER_LIBC, enc, + COLLPROVIDER_LIBC, true, enc, localebuf, localebuf, get_collation_actual_version(COLLPROVIDER_LIBC, localebuf), true, true); @@ -647,7 +666,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) int enc = aliases[i].enc; collid = CollationCreate(alias, nspid, GetUserId(), - COLLPROVIDER_LIBC, enc, + COLLPROVIDER_LIBC, true, enc, locale, locale, get_collation_actual_version(COLLPROVIDER_LIBC, locale), true, true); @@ -709,7 +728,7 @@ pg_import_system_collations(PG_FUNCTION_ARGS) collid = CollationCreate(psprintf("%s-x-icu", langtag), nspid, GetUserId(), - COLLPROVIDER_ICU, -1, + COLLPROVIDER_ICU, true, -1, collcollate, collcollate, get_collation_actual_version(COLLPROVIDER_ICU, collcollate), true, true); diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c index 2f2e69b4a82..1859fb628fd 100644 --- a/src/backend/commands/comment.c +++ b/src/backend/commands/comment.c @@ -4,7 +4,7 @@ * * PostgreSQL object comments utility code. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/commands/comment.c @@ -15,8 +15,9 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/relation.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/objectaddress.h" #include "catalog/pg_description.h" @@ -27,7 +28,6 @@ #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/rel.h" -#include "utils/tqual.h" /* @@ -184,7 +184,7 @@ CreateComments(Oid oid, Oid classoid, int32 subid, const char *comment) BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(subid)); - description = heap_open(DescriptionRelationId, RowExclusiveLock); + description = table_open(DescriptionRelationId, RowExclusiveLock); sd = systable_beginscan(description, DescriptionObjIndexId, true, NULL, 3, skey); @@ -221,7 +221,7 @@ CreateComments(Oid oid, Oid classoid, int32 subid, const char *comment) /* Done */ - heap_close(description, NoLock); + table_close(description, NoLock); } /* @@ -274,7 +274,7 @@ CreateSharedComments(Oid oid, Oid classoid, const char *comment) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classoid)); - shdescription = heap_open(SharedDescriptionRelationId, RowExclusiveLock); + shdescription = table_open(SharedDescriptionRelationId, RowExclusiveLock); sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true, NULL, 2, skey); @@ -311,7 +311,7 @@ CreateSharedComments(Oid oid, Oid classoid, const char *comment) /* Done */ - heap_close(shdescription, NoLock); + table_close(shdescription, NoLock); } /* @@ -352,7 +352,7 @@ DeleteComments(Oid oid, Oid classoid, int32 subid) else nkeys = 2; - description = heap_open(DescriptionRelationId, RowExclusiveLock); + description = table_open(DescriptionRelationId, RowExclusiveLock); sd = systable_beginscan(description, DescriptionObjIndexId, true, NULL, nkeys, skey); @@ -363,7 +363,7 @@ DeleteComments(Oid oid, Oid classoid, int32 subid) /* Done */ systable_endscan(sd); - heap_close(description, RowExclusiveLock); + table_close(description, RowExclusiveLock); } /* @@ -388,7 +388,7 @@ DeleteSharedComments(Oid oid, Oid classoid) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classoid)); - shdescription = heap_open(SharedDescriptionRelationId, RowExclusiveLock); + shdescription = table_open(SharedDescriptionRelationId, RowExclusiveLock); sd = systable_beginscan(shdescription, SharedDescriptionObjIndexId, true, NULL, 2, skey); @@ -399,7 +399,7 @@ DeleteSharedComments(Oid oid, Oid classoid) /* Done */ systable_endscan(sd); - heap_close(shdescription, RowExclusiveLock); + table_close(shdescription, RowExclusiveLock); } /* @@ -430,7 +430,7 @@ GetComment(Oid oid, Oid classoid, int32 subid) BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(subid)); - description = heap_open(DescriptionRelationId, AccessShareLock); + description = table_open(DescriptionRelationId, AccessShareLock); tupdesc = RelationGetDescr(description); sd = systable_beginscan(description, DescriptionObjIndexId, true, @@ -452,7 +452,7 @@ GetComment(Oid oid, Oid classoid, int32 subid) systable_endscan(sd); /* Done */ - heap_close(description, AccessShareLock); + table_close(description, AccessShareLock); return comment; } diff --git a/src/backend/commands/constraint.c b/src/backend/commands/constraint.c index 90f19ad3dd9..806962a686b 100644 --- a/src/backend/commands/constraint.c +++ b/src/backend/commands/constraint.c @@ -3,7 +3,7 @@ * constraint.c * PostgreSQL CONSTRAINT support code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,12 +13,15 @@ */ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "access/tableam.h" #include "catalog/index.h" #include "commands/trigger.h" #include "executor/executor.h" #include "utils/builtins.h" #include "utils/rel.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" /* @@ -39,7 +42,7 @@ unique_key_recheck(PG_FUNCTION_ARGS) { TriggerData *trigdata = castNode(TriggerData, fcinfo->context); const char *funcname = "unique_key_recheck"; - HeapTuple new_row; + ItemPointerData checktid; ItemPointerData tmptid; Relation indexRel; IndexInfo *indexInfo; @@ -71,28 +74,30 @@ unique_key_recheck(PG_FUNCTION_ARGS) * Get the new data that was inserted/updated. */ if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - new_row = trigdata->tg_trigtuple; + checktid = trigdata->tg_trigslot->tts_tid; else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - new_row = trigdata->tg_newtuple; + checktid = trigdata->tg_newslot->tts_tid; else { ereport(ERROR, (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), errmsg("function \"%s\" must be fired for INSERT or UPDATE", funcname))); - new_row = NULL; /* keep compiler quiet */ + ItemPointerSetInvalid(&checktid); /* keep compiler quiet */ } + slot = table_slot_create(trigdata->tg_relation, NULL); + /* - * If the new_row is now dead (ie, inserted and then deleted within our - * transaction), we can skip the check. However, we have to be careful, - * because this trigger gets queued only in response to index insertions; - * which means it does not get queued for HOT updates. The row we are - * called for might now be dead, but have a live HOT child, in which case - * we still need to make the check --- effectively, we're applying the - * check against the live child row, although we can use the values from - * this row since by definition all columns of interest to us are the - * same. + * If the row pointed at by checktid is now dead (ie, inserted and then + * deleted within our transaction), we can skip the check. However, we + * have to be careful, because this trigger gets queued only in response + * to index insertions; which means it does not get queued e.g. for HOT + * updates. The row we are called for might now be dead, but have a live + * HOT child, in which case we still need to make the check --- + * effectively, we're applying the check against the live child row, + * although we can use the values from this row since by definition all + * columns of interest to us are the same. * * This might look like just an optimization, because the index AM will * make this identical test before throwing an error. But it's actually @@ -101,13 +106,23 @@ unique_key_recheck(PG_FUNCTION_ARGS) * it's possible the index entry has also been marked dead, and even * removed. */ - tmptid = new_row->t_self; - if (!heap_hot_search(&tmptid, trigdata->tg_relation, SnapshotSelf, NULL)) + tmptid = checktid; { - /* - * All rows in the HOT chain are dead, so skip the check. - */ - return PointerGetDatum(NULL); + IndexFetchTableData *scan = table_index_fetch_begin(trigdata->tg_relation); + bool call_again = false; + + if (!table_index_fetch_tuple(scan, &tmptid, SnapshotSelf, slot, + &call_again, NULL)) + { + /* + * All rows referenced by the index entry are dead, so skip the + * check. + */ + ExecDropSingleTupleTableSlot(slot); + table_index_fetch_end(scan); + return PointerGetDatum(NULL); + } + table_index_fetch_end(scan); } /* @@ -119,13 +134,6 @@ unique_key_recheck(PG_FUNCTION_ARGS) RowExclusiveLock); indexInfo = BuildIndexInfo(indexRel); - /* - * The heap tuple must be put into a slot for FormIndexDatum. - */ - slot = MakeSingleTupleTableSlot(RelationGetDescr(trigdata->tg_relation)); - - ExecStoreTuple(new_row, slot, InvalidBuffer, false); - /* * Typically the index won't have expressions, but if it does we need an * EState to evaluate them. We need it for exclusion constraints too, @@ -160,11 +168,12 @@ unique_key_recheck(PG_FUNCTION_ARGS) { /* * Note: this is not a real insert; it is a check that the index entry - * that has already been inserted is unique. Passing t_self is - * correct even if t_self is now dead, because that is the TID the - * index will know about. + * that has already been inserted is unique. Passing the tuple's tid + * (i.e. unmodified by table_index_fetch_tuple()) is correct even if + * the row is now dead, because that is the TID the index will know + * about. */ - index_insert(indexRel, values, isnull, &(new_row->t_self), + index_insert(indexRel, values, isnull, &checktid, trigdata->tg_relation, UNIQUE_CHECK_EXISTING, indexInfo); } diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index e36fc23dd85..cb856e8fee4 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -3,7 +3,7 @@ * conversioncmds.c * conversion creation command support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -72,6 +72,18 @@ CreateConversionCommand(CreateConversionStmt *stmt) errmsg("destination encoding \"%s\" does not exist", to_encoding_name))); + /* + * We consider conversions to or from SQL_ASCII to be meaningless. (If + * you wish to change this, note that pg_do_encoding_conversion() and its + * sister functions have hard-wired fast paths for any conversion in which + * the source or target encoding is SQL_ASCII, so that an encoding + * conversion function declared for such a case will never be used.) + */ + if (from_encoding == PG_SQL_ASCII || to_encoding == PG_SQL_ASCII) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("encoding conversion to or from \"SQL_ASCII\" is not supported"))); + /* * Check the existence of the conversion function. Function name could be * a qualified name. diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 99479eed662..3aeef30b281 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -3,7 +3,7 @@ * copy.c * Implements the COPY utility command * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,6 +21,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/dependency.h" @@ -31,14 +32,18 @@ #include "commands/trigger.h" #include "executor/execPartition.h" #include "executor/executor.h" +#include "executor/nodeModifyTable.h" +#include "executor/tuptable.h" #include "foreign/fdwapi.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "mb/pg_wchar.h" #include "miscadmin.h" -#include "optimizer/clauses.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "nodes/makefuncs.h" +#include "parser/parse_coerce.h" +#include "parser/parse_collate.h" +#include "parser/parse_expr.h" #include "parser/parse_relation.h" #include "port/pg_bswap.h" #include "rewrite/rewriteHandler.h" @@ -47,6 +52,7 @@ #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/partcache.h" #include "utils/portal.h" #include "utils/rel.h" #include "utils/rls.h" @@ -79,6 +85,16 @@ typedef enum EolType EOL_CRNL } EolType; +/* + * Represents the heap insert method to be used during COPY FROM. + */ +typedef enum CopyInsertMethod +{ + CIM_SINGLE, /* use table_tuple_insert or fdw routine */ + CIM_MULTI, /* always use table_multi_insert */ + CIM_MULTI_CONDITIONAL /* use table_multi_insert only if valid */ +} CopyInsertMethod; + /* * This struct contains all the state variables used throughout a COPY * operation. For simplicity, we use the same struct for all variants of COPY, @@ -102,7 +118,9 @@ typedef struct CopyStateData FILE *copy_file; /* used if copy_dest == COPY_FILE */ StringInfo fe_msgbuf; /* used for all dests during COPY TO, only for * dest == COPY_NEW_FE in COPY FROM */ - bool fe_eof; /* true if detected end of copy data */ + bool is_copy_from; /* COPY TO, or COPY FROM? */ + bool reached_eof; /* true if we read to end of copy data (not + * all copy_dest types maintain this) */ EolType eol_type; /* EOL type of input */ int file_encoding; /* file or remote side's character encoding */ bool need_transcoding; /* file encoding diff from server? */ @@ -116,7 +134,6 @@ typedef struct CopyStateData bool is_program; /* is 'filename' a program to popen? */ copy_data_source_cb data_source_cb; /* function for reading data */ bool binary; /* binary format? */ - bool oids; /* include OIDs? */ bool freeze; /* freeze rows on loading? */ bool csv_mode; /* Comma Separated Value format? */ bool header_line; /* CSV header line? */ @@ -136,10 +153,11 @@ typedef struct CopyStateData bool convert_selectively; /* do selective binary conversion? */ List *convert_select; /* list of column names (can be NIL) */ bool *convert_select_flags; /* per-column CSV/TEXT CS flags */ + Node *whereClause; /* WHERE condition (or NULL) */ /* these are just for error messages, see CopyFromErrorCallback */ const char *cur_relname; /* table name for error messages */ - int cur_lineno; /* line number for error messages */ + uint64 cur_lineno; /* line number for error messages */ const char *cur_attname; /* current att for error messages */ const char *cur_attval; /* current att value for error messages */ @@ -158,18 +176,13 @@ typedef struct CopyStateData * Working state for COPY FROM */ AttrNumber num_defaults; - bool file_has_oids; - FmgrInfo oid_in_function; - Oid oid_typioparam; FmgrInfo *in_functions; /* array of input functions for each attrs */ Oid *typioparams; /* array of element types for in_functions */ int *defmap; /* array of default att numbers */ ExprState **defexprs; /* array of default att expressions */ bool volatile_defexprs; /* is any of defexprs volatile? */ List *range_table; - - /* Tuple-routing support info */ - PartitionTupleRouting *partition_tuple_routing; + ExprState *qualexpr; TransitionCaptureState *transition_capture; @@ -221,6 +234,54 @@ typedef struct } DR_copy; +/* + * No more than this many tuples per CopyMultiInsertBuffer + * + * Caution: Don't make this too big, as we could end up with this many + * CopyMultiInsertBuffer items stored in CopyMultiInsertInfo's + * multiInsertBuffers list. Increasing this can cause quadratic growth in + * memory requirements during copies into partitioned tables with a large + * number of partitions. + */ +#define MAX_BUFFERED_TUPLES 1000 + +/* + * Flush buffers if there are >= this many bytes, as counted by the input + * size, of tuples stored. + */ +#define MAX_BUFFERED_BYTES 65535 + +/* Trim the list of buffers back down to this number after flushing */ +#define MAX_PARTITION_BUFFERS 32 + +/* Stores multi-insert data related to a single relation in CopyFrom. */ +typedef struct CopyMultiInsertBuffer +{ + TupleTableSlot *slots[MAX_BUFFERED_TUPLES]; /* Array to store tuples */ + ResultRelInfo *resultRelInfo; /* ResultRelInfo for 'relid' */ + BulkInsertState bistate; /* BulkInsertState for this rel */ + int nused; /* number of 'slots' containing tuples */ + uint64 linenos[MAX_BUFFERED_TUPLES]; /* Line # of tuple in copy + * stream */ +} CopyMultiInsertBuffer; + +/* + * Stores one or many CopyMultiInsertBuffers and details about the size and + * number of tuples which are stored in them. This allows multiple buffers to + * exist at once when COPYing into a partitioned table. + */ +typedef struct CopyMultiInsertInfo +{ + List *multiInsertBuffers; /* List of tracked CopyMultiInsertBuffers */ + int bufferedTuples; /* number of tuples buffered over all buffers */ + int bufferedBytes; /* number of bytes from all buffered tuples */ + CopyState cstate; /* Copy state for this CopyMultiInsertInfo */ + EState *estate; /* Executor state used for COPY */ + CommandId mycid; /* Command Id used for COPY */ + int ti_options; /* table insert options */ +} CopyMultiInsertInfo; + + /* * These macros centralize code used to process line_buf and raw_buf buffers. * They are macros because they often do continue/break control and to avoid @@ -291,37 +352,30 @@ static const char BinarySignature[11] = "PGCOPY\n\377\r\n\0"; /* non-export function prototypes */ static CopyState BeginCopy(ParseState *pstate, bool is_from, Relation rel, - RawStmt *raw_query, Oid queryRelId, List *attnamelist, - List *options); + RawStmt *raw_query, Oid queryRelId, List *attnamelist, + List *options); static void EndCopy(CopyState cstate); static void ClosePipeToProgram(CopyState cstate); static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query, - Oid queryRelId, const char *filename, bool is_program, - List *attnamelist, List *options); + Oid queryRelId, const char *filename, bool is_program, + List *attnamelist, List *options); static void EndCopyTo(CopyState cstate); static uint64 DoCopyTo(CopyState cstate); static uint64 CopyTo(CopyState cstate); -static void CopyOneRowTo(CopyState cstate, Oid tupleOid, - Datum *values, bool *nulls); -static void CopyFromInsertBatch(CopyState cstate, EState *estate, - CommandId mycid, int hi_options, - ResultRelInfo *resultRelInfo, TupleTableSlot *myslot, - BulkInsertState bistate, - int nBufferedTuples, HeapTuple *bufferedTuples, - int firstBufferedLineNo); +static void CopyOneRowTo(CopyState cstate, TupleTableSlot *slot); static bool CopyReadLine(CopyState cstate); static bool CopyReadLineText(CopyState cstate); static int CopyReadAttributesText(CopyState cstate); static int CopyReadAttributesCSV(CopyState cstate); static Datum CopyReadBinaryAttribute(CopyState cstate, - int column_no, FmgrInfo *flinfo, - Oid typioparam, int32 typmod, - bool *isnull); + int column_no, FmgrInfo *flinfo, + Oid typioparam, int32 typmod, + bool *isnull); static void CopyAttributeOutText(CopyState cstate, char *string); static void CopyAttributeOutCSV(CopyState cstate, char *string, - bool use_quote, bool single_attr); + bool use_quote, bool single_attr); static List *CopyGetAttnums(TupleDesc tupDesc, Relation rel, - List *attnamelist); + List *attnamelist); static char *limit_printout_length(const char *str); /* Low-level communications functions */ @@ -332,8 +386,8 @@ static void CopySendData(CopyState cstate, const void *databuf, int datasize); static void CopySendString(CopyState cstate, const char *str); static void CopySendChar(CopyState cstate, char c); static void CopySendEndOfRow(CopyState cstate); -static int CopyGetData(CopyState cstate, void *databuf, - int minread, int maxread); +static int CopyGetData(CopyState cstate, void *databuf, + int minread, int maxread); static void CopySendInt32(CopyState cstate, int32 val); static bool CopyGetInt32(CopyState cstate, int32 *val); static void CopySendInt16(CopyState cstate, int16 val); @@ -566,6 +620,8 @@ CopyGetData(CopyState cstate, void *databuf, int minread, int maxread) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read from COPY file: %m"))); + if (bytesread == 0) + cstate->reached_eof = true; break; case COPY_OLD_FE: @@ -586,7 +642,7 @@ CopyGetData(CopyState cstate, void *databuf, int minread, int maxread) bytesread = minread; break; case COPY_NEW_FE: - while (maxread > 0 && bytesread < minread && !cstate->fe_eof) + while (maxread > 0 && bytesread < minread && !cstate->reached_eof) { int avail; @@ -614,7 +670,7 @@ CopyGetData(CopyState cstate, void *databuf, int minread, int maxread) break; case 'c': /* CopyDone */ /* COPY IN correctly terminated by frontend */ - cstate->fe_eof = true; + cstate->reached_eof = true; return bytesread; case 'f': /* CopyFail */ ereport(ERROR, @@ -772,8 +828,8 @@ CopyLoadRawBuf(CopyState cstate) * input/output stream. The latter could be either stdin/stdout or a * socket, depending on whether we're running under Postmaster control. * - * Do not allow a Postgres user without the 'pg_access_server_files' role to - * read from or write to a file. + * Do not allow a Postgres user without the 'pg_read_server_files' or + * 'pg_write_server_files' role to read from or write to a file. * * Do not allow the copy if user doesn't have proper permission to access * the table or the specifically requested columns. @@ -789,6 +845,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, Relation rel; Oid relid; RawStmt *query = NULL; + Node *whereClause = NULL; /* * Disallow COPY to/from file or program except to users with the @@ -825,22 +882,43 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, if (stmt->relation) { + LOCKMODE lockmode = is_from ? RowExclusiveLock : AccessShareLock; + RangeTblEntry *rte; TupleDesc tupDesc; List *attnums; ListCell *cur; - RangeTblEntry *rte; Assert(!stmt->query); /* Open and lock the relation, using the appropriate lock type. */ - rel = heap_openrv(stmt->relation, - (is_from ? RowExclusiveLock : AccessShareLock)); + rel = table_openrv(stmt->relation, lockmode); relid = RelationGetRelid(rel); - rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, false); + rte = addRangeTableEntryForRelation(pstate, rel, lockmode, + NULL, false, false); rte->requiredPerms = (is_from ? ACL_INSERT : ACL_SELECT); + if (stmt->whereClause) + { + /* add rte to column namespace */ + addRTEtoQuery(pstate, rte, false, true, true); + + /* Transform the raw expression tree */ + whereClause = transformExpr(pstate, stmt->whereClause, EXPR_KIND_COPY_WHERE); + + /* Make sure it yields a boolean result. */ + whereClause = coerce_to_boolean(pstate, whereClause, "WHERE"); + + /* we have to fix its collations too */ + assign_expr_collations(pstate, whereClause); + + whereClause = eval_const_expressions(NULL, whereClause); + + whereClause = (Node *) canonicalize_qual((Expr *) whereClause, false); + whereClause = (Node *) make_ands_implicit((Expr *) whereClause); + } + tupDesc = RelationGetDescr(rel); attnums = CopyGetAttnums(tupDesc, rel, stmt->attlist); foreach(cur, attnums) @@ -961,7 +1039,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, * * We'll reopen it later as part of the query-based COPY. */ - heap_close(rel, NoLock); + table_close(rel, NoLock); rel = NULL; } } @@ -989,6 +1067,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, cstate = BeginCopyFrom(pstate, rel, stmt->filename, stmt->is_program, NULL, stmt->attlist, stmt->options); + cstate->whereClause = whereClause; *processed = CopyFrom(cstate); /* copy from file to database */ EndCopyFrom(cstate); } @@ -1007,7 +1086,7 @@ DoCopy(ParseState *pstate, const CopyStmt *stmt, * ensure that updates will be committed before lock is released. */ if (rel != NULL) - heap_close(rel, (is_from ? NoLock : AccessShareLock)); + table_close(rel, (is_from ? NoLock : AccessShareLock)); } /* @@ -1040,6 +1119,8 @@ ProcessCopyOptions(ParseState *pstate, if (cstate == NULL) cstate = (CopyStateData *) palloc0(sizeof(CopyStateData)); + cstate->is_copy_from = is_from; + cstate->file_encoding = -1; /* Extract options from the statement node tree */ @@ -1069,15 +1150,6 @@ ProcessCopyOptions(ParseState *pstate, errmsg("COPY format \"%s\" not recognized", fmt), parser_errposition(pstate, defel->location))); } - else if (strcmp(defel->defname, "oids") == 0) - { - if (cstate->oids) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); - cstate->oids = defGetBoolean(defel); - } else if (strcmp(defel->defname, "freeze") == 0) { if (cstate->freeze) @@ -1423,13 +1495,6 @@ BeginCopy(ParseState *pstate, cstate->rel = rel; tupDesc = RelationGetDescr(cstate->rel); - - /* Don't allow COPY w/ OIDs to or from a table without them */ - if (cstate->oids && !cstate->rel->rd_rel->relhasoids) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("table \"%s\" does not have OIDs", - RelationGetRelationName(cstate->rel)))); } else { @@ -1441,12 +1506,6 @@ BeginCopy(ParseState *pstate, Assert(!is_from); cstate->rel = NULL; - /* Don't allow COPY w/ OIDs from a query */ - if (cstate->oids) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("COPY (query) WITH OIDS is not supported"))); - /* * Run parse analysis and rewrite. Note this also acquires sufficient * locks on the source table(s). @@ -1717,11 +1776,23 @@ ClosePipeToProgram(CopyState cstate) (errcode_for_file_access(), errmsg("could not close pipe to external command: %m"))); else if (pclose_rc != 0) + { + /* + * If we ended a COPY FROM PROGRAM before reaching EOF, then it's + * expectable for the called program to fail with SIGPIPE, and we + * should not report that as an error. Otherwise, SIGPIPE indicates a + * problem. + */ + if (cstate->is_copy_from && !cstate->reached_eof && + wait_result_is_signal(pclose_rc, SIGPIPE)) + return; + ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), errmsg("program \"%s\" failed", cstate->filename), errdetail_internal("%s", wait_result_to_str(pclose_rc)))); + } } /* @@ -1999,8 +2070,6 @@ CopyTo(CopyState cstate) CopySendData(cstate, BinarySignature, 11); /* Flags field */ tmp = 0; - if (cstate->oids) - tmp |= (1 << 16); CopySendInt32(cstate, tmp); /* No header extension */ tmp = 0; @@ -2043,33 +2112,27 @@ CopyTo(CopyState cstate) if (cstate->rel) { - Datum *values; - bool *nulls; - HeapScanDesc scandesc; - HeapTuple tuple; - - values = (Datum *) palloc(num_phys_attrs * sizeof(Datum)); - nulls = (bool *) palloc(num_phys_attrs * sizeof(bool)); + TupleTableSlot *slot; + TableScanDesc scandesc; - scandesc = heap_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL); + scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL); + slot = table_slot_create(cstate->rel, NULL); processed = 0; - while ((tuple = heap_getnext(scandesc, ForwardScanDirection)) != NULL) + while (table_scan_getnextslot(scandesc, ForwardScanDirection, slot)) { CHECK_FOR_INTERRUPTS(); - /* Deconstruct the tuple ... faster than repeated heap_getattr */ - heap_deform_tuple(tuple, tupDesc, values, nulls); + /* Deconstruct the tuple ... */ + slot_getallattrs(slot); /* Format and send the data */ - CopyOneRowTo(cstate, HeapTupleGetOid(tuple), values, nulls); + CopyOneRowTo(cstate, slot); processed++; } - heap_endscan(scandesc); - - pfree(values); - pfree(nulls); + ExecDropSingleTupleTableSlot(slot); + table_endscan(scandesc); } else { @@ -2095,7 +2158,7 @@ CopyTo(CopyState cstate) * Emit one row during CopyTo(). */ static void -CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls) +CopyOneRowTo(CopyState cstate, TupleTableSlot *slot) { bool need_delim = false; FmgrInfo *out_functions = cstate->out_functions; @@ -2110,32 +2173,16 @@ CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls) { /* Binary per-tuple header */ CopySendInt16(cstate, list_length(cstate->attnumlist)); - /* Send OID if wanted --- note attnumlist doesn't include it */ - if (cstate->oids) - { - /* Hack --- assume Oid is same size as int32 */ - CopySendInt32(cstate, sizeof(int32)); - CopySendInt32(cstate, tupleOid); - } - } - else - { - /* Text format has no per-tuple header, but send OID if wanted */ - /* Assume digits don't need any quoting or encoding conversion */ - if (cstate->oids) - { - string = DatumGetCString(DirectFunctionCall1(oidout, - ObjectIdGetDatum(tupleOid))); - CopySendString(cstate, string); - need_delim = true; - } } + /* Make sure the tuple is fully deconstructed */ + slot_getallattrs(slot); + foreach(cur, cstate->attnumlist) { int attnum = lfirst_int(cur); - Datum value = values[attnum - 1]; - bool isnull = nulls[attnum - 1]; + Datum value = slot->tts_values[attnum - 1]; + bool isnull = slot->tts_isnull[attnum - 1]; if (!cstate->binary) { @@ -2192,17 +2239,21 @@ void CopyFromErrorCallback(void *arg) { CopyState cstate = (CopyState) arg; + char curlineno_str[32]; + + snprintf(curlineno_str, sizeof(curlineno_str), UINT64_FORMAT, + cstate->cur_lineno); if (cstate->binary) { /* can't usefully display the data */ if (cstate->cur_attname) - errcontext("COPY %s, line %d, column %s", - cstate->cur_relname, cstate->cur_lineno, + errcontext("COPY %s, line %s, column %s", + cstate->cur_relname, curlineno_str, cstate->cur_attname); else - errcontext("COPY %s, line %d", - cstate->cur_relname, cstate->cur_lineno); + errcontext("COPY %s, line %s", + cstate->cur_relname, curlineno_str); } else { @@ -2212,16 +2263,16 @@ CopyFromErrorCallback(void *arg) char *attval; attval = limit_printout_length(cstate->cur_attval); - errcontext("COPY %s, line %d, column %s: \"%s\"", - cstate->cur_relname, cstate->cur_lineno, + errcontext("COPY %s, line %s, column %s: \"%s\"", + cstate->cur_relname, curlineno_str, cstate->cur_attname, attval); pfree(attval); } else if (cstate->cur_attname) { /* error is relevant to a particular column, value is NULL */ - errcontext("COPY %s, line %d, column %s: null input", - cstate->cur_relname, cstate->cur_lineno, + errcontext("COPY %s, line %s, column %s: null input", + cstate->cur_relname, curlineno_str, cstate->cur_attname); } else @@ -2242,14 +2293,14 @@ CopyFromErrorCallback(void *arg) char *lineval; lineval = limit_printout_length(cstate->line_buf.data); - errcontext("COPY %s, line %d: \"%s\"", - cstate->cur_relname, cstate->cur_lineno, lineval); + errcontext("COPY %s, line %s: \"%s\"", + cstate->cur_relname, curlineno_str, lineval); pfree(lineval); } else { - errcontext("COPY %s, line %d", - cstate->cur_relname, cstate->cur_lineno); + errcontext("COPY %s, line %s", + cstate->cur_relname, curlineno_str); } } } @@ -2290,37 +2341,342 @@ limit_printout_length(const char *str) return res; } +/* + * Allocate memory and initialize a new CopyMultiInsertBuffer for this + * ResultRelInfo. + */ +static CopyMultiInsertBuffer * +CopyMultiInsertBufferInit(ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer; + + buffer = (CopyMultiInsertBuffer *) palloc(sizeof(CopyMultiInsertBuffer)); + memset(buffer->slots, 0, sizeof(TupleTableSlot *) * MAX_BUFFERED_TUPLES); + buffer->resultRelInfo = rri; + buffer->bistate = GetBulkInsertState(); + buffer->nused = 0; + + return buffer; +} + +/* + * Make a new buffer for this ResultRelInfo. + */ +static inline void +CopyMultiInsertInfoSetupBuffer(CopyMultiInsertInfo *miinfo, + ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer; + + buffer = CopyMultiInsertBufferInit(rri); + + /* Setup back-link so we can easily find this buffer again */ + rri->ri_CopyMultiInsertBuffer = buffer; + /* Record that we're tracking this buffer */ + miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer); +} + +/* + * Initialize an already allocated CopyMultiInsertInfo. + * + * If rri is a non-partitioned table then a CopyMultiInsertBuffer is set up + * for that table. + */ +static void +CopyMultiInsertInfoInit(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, + CopyState cstate, EState *estate, CommandId mycid, + int ti_options) +{ + miinfo->multiInsertBuffers = NIL; + miinfo->bufferedTuples = 0; + miinfo->bufferedBytes = 0; + miinfo->cstate = cstate; + miinfo->estate = estate; + miinfo->mycid = mycid; + miinfo->ti_options = ti_options; + + /* + * Only setup the buffer when not dealing with a partitioned table. + * Buffers for partitioned tables will just be setup when we need to send + * tuples their way for the first time. + */ + if (rri->ri_RelationDesc->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) + CopyMultiInsertInfoSetupBuffer(miinfo, rri); +} + +/* + * Returns true if the buffers are full + */ +static inline bool +CopyMultiInsertInfoIsFull(CopyMultiInsertInfo *miinfo) +{ + if (miinfo->bufferedTuples >= MAX_BUFFERED_TUPLES || + miinfo->bufferedBytes >= MAX_BUFFERED_BYTES) + return true; + return false; +} + +/* + * Returns true if we have no buffered tuples + */ +static inline bool +CopyMultiInsertInfoIsEmpty(CopyMultiInsertInfo *miinfo) +{ + return miinfo->bufferedTuples == 0; +} + +/* + * Write the tuples stored in 'buffer' out to the table. + */ +static inline void +CopyMultiInsertBufferFlush(CopyMultiInsertInfo *miinfo, + CopyMultiInsertBuffer *buffer) +{ + MemoryContext oldcontext; + int i; + uint64 save_cur_lineno; + CopyState cstate = miinfo->cstate; + EState *estate = miinfo->estate; + CommandId mycid = miinfo->mycid; + int ti_options = miinfo->ti_options; + bool line_buf_valid = cstate->line_buf_valid; + int nused = buffer->nused; + ResultRelInfo *resultRelInfo = buffer->resultRelInfo; + TupleTableSlot **slots = buffer->slots; + + /* Set es_result_relation_info to the ResultRelInfo we're flushing. */ + estate->es_result_relation_info = resultRelInfo; + + /* + * Print error context information correctly, if one of the operations + * below fail. + */ + cstate->line_buf_valid = false; + save_cur_lineno = cstate->cur_lineno; + + /* + * table_multi_insert may leak memory, so switch to short-lived memory + * context before calling it. + */ + oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + table_multi_insert(resultRelInfo->ri_RelationDesc, + slots, + nused, + mycid, + ti_options, + buffer->bistate); + MemoryContextSwitchTo(oldcontext); + + for (i = 0; i < nused; i++) + { + /* + * If there are any indexes, update them for all the inserted tuples, + * and run AFTER ROW INSERT triggers. + */ + if (resultRelInfo->ri_NumIndices > 0) + { + List *recheckIndexes; + + cstate->cur_lineno = buffer->linenos[i]; + recheckIndexes = + ExecInsertIndexTuples(buffer->slots[i], estate, false, NULL, + NIL); + ExecARInsertTriggers(estate, resultRelInfo, + slots[i], recheckIndexes, + cstate->transition_capture); + list_free(recheckIndexes); + } + + /* + * There's no indexes, but see if we need to run AFTER ROW INSERT + * triggers anyway. + */ + else if (resultRelInfo->ri_TrigDesc != NULL && + (resultRelInfo->ri_TrigDesc->trig_insert_after_row || + resultRelInfo->ri_TrigDesc->trig_insert_new_table)) + { + cstate->cur_lineno = buffer->linenos[i]; + ExecARInsertTriggers(estate, resultRelInfo, + slots[i], NIL, cstate->transition_capture); + } + + ExecClearTuple(slots[i]); + } + + /* Mark that all slots are free */ + buffer->nused = 0; + + /* reset cur_lineno and line_buf_valid to what they were */ + cstate->line_buf_valid = line_buf_valid; + cstate->cur_lineno = save_cur_lineno; +} + +/* + * Drop used slots and free member for this buffer. + * + * The buffer must be flushed before cleanup. + */ +static inline void +CopyMultiInsertBufferCleanup(CopyMultiInsertInfo *miinfo, + CopyMultiInsertBuffer *buffer) +{ + int i; + + /* Ensure buffer was flushed */ + Assert(buffer->nused == 0); + + /* Remove back-link to ourself */ + buffer->resultRelInfo->ri_CopyMultiInsertBuffer = NULL; + + FreeBulkInsertState(buffer->bistate); + + /* Since we only create slots on demand, just drop the non-null ones. */ + for (i = 0; i < MAX_BUFFERED_TUPLES && buffer->slots[i] != NULL; i++) + ExecDropSingleTupleTableSlot(buffer->slots[i]); + + table_finish_bulk_insert(buffer->resultRelInfo->ri_RelationDesc, + miinfo->ti_options); + + pfree(buffer); +} + +/* + * Write out all stored tuples in all buffers out to the tables. + * + * Once flushed we also trim the tracked buffers list down to size by removing + * the buffers created earliest first. + * + * Callers should pass 'curr_rri' is the ResultRelInfo that's currently being + * used. When cleaning up old buffers we'll never remove the one for + * 'curr_rri'. + */ +static inline void +CopyMultiInsertInfoFlush(CopyMultiInsertInfo *miinfo, ResultRelInfo *curr_rri) +{ + ListCell *lc; + + foreach(lc, miinfo->multiInsertBuffers) + { + CopyMultiInsertBuffer *buffer = (CopyMultiInsertBuffer *) lfirst(lc); + + CopyMultiInsertBufferFlush(miinfo, buffer); + } + + miinfo->bufferedTuples = 0; + miinfo->bufferedBytes = 0; + + /* + * Trim the list of tracked buffers down if it exceeds the limit. Here we + * remove buffers starting with the ones we created first. It seems more + * likely that these older ones are less likely to be needed than ones + * that were just created. + */ + while (list_length(miinfo->multiInsertBuffers) > MAX_PARTITION_BUFFERS) + { + CopyMultiInsertBuffer *buffer; + + buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers); + + /* + * We never want to remove the buffer that's currently being used, so + * if we happen to find that then move it to the end of the list. + */ + if (buffer->resultRelInfo == curr_rri) + { + miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers); + miinfo->multiInsertBuffers = lappend(miinfo->multiInsertBuffers, buffer); + buffer = (CopyMultiInsertBuffer *) linitial(miinfo->multiInsertBuffers); + } + + CopyMultiInsertBufferCleanup(miinfo, buffer); + miinfo->multiInsertBuffers = list_delete_first(miinfo->multiInsertBuffers); + } +} + +/* + * Cleanup allocated buffers and free memory + */ +static inline void +CopyMultiInsertInfoCleanup(CopyMultiInsertInfo *miinfo) +{ + ListCell *lc; + + foreach(lc, miinfo->multiInsertBuffers) + CopyMultiInsertBufferCleanup(miinfo, lfirst(lc)); + + list_free(miinfo->multiInsertBuffers); +} + +/* + * Get the next TupleTableSlot that the next tuple should be stored in. + * + * Callers must ensure that the buffer is not full. + */ +static inline TupleTableSlot * +CopyMultiInsertInfoNextFreeSlot(CopyMultiInsertInfo *miinfo, + ResultRelInfo *rri) +{ + CopyMultiInsertBuffer *buffer = rri->ri_CopyMultiInsertBuffer; + int nused = buffer->nused; + + Assert(buffer != NULL); + Assert(nused < MAX_BUFFERED_TUPLES); + + if (buffer->slots[nused] == NULL) + buffer->slots[nused] = table_slot_create(rri->ri_RelationDesc, NULL); + return buffer->slots[nused]; +} + +/* + * Record the previously reserved TupleTableSlot that was reserved by + * CopyMultiInsertInfoNextFreeSlot as being consumed. + */ +static inline void +CopyMultiInsertInfoStore(CopyMultiInsertInfo *miinfo, ResultRelInfo *rri, + TupleTableSlot *slot, int tuplen, uint64 lineno) +{ + CopyMultiInsertBuffer *buffer = rri->ri_CopyMultiInsertBuffer; + + Assert(buffer != NULL); + Assert(slot == buffer->slots[buffer->nused]); + + /* Store the line number so we can properly report any errors later */ + buffer->linenos[buffer->nused] = lineno; + + /* Record this slot as being used */ + buffer->nused++; + + /* Update how many tuples are stored and their size */ + miinfo->bufferedTuples++; + miinfo->bufferedBytes += tuplen; +} + /* * Copy FROM file to relation. */ uint64 CopyFrom(CopyState cstate) { - HeapTuple tuple; - TupleDesc tupDesc; - Datum *values; - bool *nulls; ResultRelInfo *resultRelInfo; - ResultRelInfo *saved_resultRelInfo = NULL; + ResultRelInfo *target_resultRelInfo; + ResultRelInfo *prevResultRelInfo = NULL; EState *estate = CreateExecutorState(); /* for ExecConstraints() */ ModifyTableState *mtstate; ExprContext *econtext; - TupleTableSlot *myslot; + TupleTableSlot *singleslot = NULL; MemoryContext oldcontext = CurrentMemoryContext; + PartitionTupleRouting *proute = NULL; ErrorContextCallback errcallback; CommandId mycid = GetCurrentCommandId(true); - int hi_options = 0; /* start with default heap_insert options */ - BulkInsertState bistate; + int ti_options = 0; /* start with default options for insert */ + BulkInsertState bistate = NULL; + CopyInsertMethod insertMethod; + CopyMultiInsertInfo multiInsertInfo = {0}; /* pacify compiler */ uint64 processed = 0; - bool useHeapMultiInsert; - int nBufferedTuples = 0; - int prev_leaf_part_index = -1; - -#define MAX_BUFFERED_TUPLES 1000 - HeapTuple *bufferedTuples = NULL; /* initialize to silence warning */ - Size bufferedTuplesSize = 0; - int firstBufferedLineNo = 0; + bool has_before_insert_row_trig; + bool has_instead_insert_row_trig; + bool leafpart_use_multi_insert = false; Assert(cstate->rel); @@ -2358,8 +2714,6 @@ CopyFrom(CopyState cstate) RelationGetRelationName(cstate->rel)))); } - tupDesc = RelationGetDescr(cstate->rel); - /*---------- * Check to see if we can avoid writing WAL * @@ -2368,8 +2722,8 @@ CopyFrom(CopyState cstate) * - data is being written to relfilenode created in this transaction * then we can skip writing WAL. It's safe because if the transaction * doesn't commit, we'll discard the table (or the new relfilenode file). - * If it does commit, we'll have done the heap_sync at the bottom of this - * routine first. + * If it does commit, we'll have done the table_finish_bulk_insert() at + * the bottom of this routine first. * * As mentioned in comments in utils/rel.h, the in-same-transaction test * is not always set correctly, since in rare cases rd_newRelfilenodeSubid @@ -2388,20 +2742,34 @@ CopyFrom(CopyState cstate) * FSM for free space is a waste of time, even if we must use WAL because * of archiving. This could possibly be wrong, but it's unlikely. * - * The comments for heap_insert and RelationGetBufferForTuple specify that - * skipping WAL logging is only safe if we ensure that our tuples do not - * go into pages containing tuples from any other transactions --- but this - * must be the case if we have a new table or new relfilenode, so we need - * no additional work to enforce that. + * The comments for table_tuple_insert and RelationGetBufferForTuple + * specify that skipping WAL logging is only safe if we ensure that our + * tuples do not go into pages containing tuples from any other + * transactions --- but this must be the case if we have a new table or + * new relfilenode, so we need no additional work to enforce that. + * + * We currently don't support this optimization if the COPY target is a + * partitioned table as we currently only lazily initialize partition + * information when routing the first tuple to the partition. We cannot + * know at this stage if we can perform this optimization. It should be + * possible to improve on this, but it does mean maintaining heap insert + * option flags per partition and setting them when we first open the + * partition. + * + * This optimization is not supported for relation types which do not + * have any physical storage, with foreign tables and views using + * INSTEAD OF triggers entering in this category. Partitioned tables + * are not supported as per the description above. *---------- */ /* createSubid is creation check, newRelfilenodeSubid is truncation check */ - if (cstate->rel->rd_createSubid != InvalidSubTransactionId || - cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId) + if (RELKIND_HAS_STORAGE(cstate->rel->rd_rel->relkind) && + (cstate->rel->rd_createSubid != InvalidSubTransactionId || + cstate->rel->rd_newRelfilenodeSubid != InvalidSubTransactionId)) { - hi_options |= HEAP_INSERT_SKIP_FSM; + ti_options |= TABLE_INSERT_SKIP_FSM; if (!XLogIsNeeded()) - hi_options |= HEAP_INSERT_SKIP_WAL; + ti_options |= TABLE_INSERT_SKIP_WAL; } /* @@ -2417,6 +2785,22 @@ CopyFrom(CopyState cstate) */ if (cstate->freeze) { + /* + * We currently disallow COPY FREEZE on partitioned tables. The + * reason for this is that we've simply not yet opened the partitions + * to determine if the optimization can be applied to them. We could + * go and open them all here, but doing so may be quite a costly + * overhead for small copies. In any case, we may just end up routing + * tuples to a small number of partitions. It seems better just to + * raise an ERROR for partitioned tables. + */ + if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot perform COPY FREEZE on a partitioned table"))); + } + /* * Tolerate one registration for the benefit of FirstXactSnapshot. * Scan-bearing queries generally create at least two registrations, @@ -2429,15 +2813,15 @@ CopyFrom(CopyState cstate) if (!ThereAreNoPriorRegisteredSnapshots() || !ThereAreNoReadyPortals()) ereport(ERROR, (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot perform FREEZE because of prior transaction activity"))); + errmsg("cannot perform COPY FREEZE because of prior transaction activity"))); if (cstate->rel->rd_createSubid != GetCurrentSubTransactionId() && cstate->rel->rd_newRelfilenodeSubid != GetCurrentSubTransactionId()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot perform FREEZE because the table was not created or truncated in the current subtransaction"))); + errmsg("cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction"))); - hi_options |= HEAP_INSERT_FROZEN; + ti_options |= TABLE_INSERT_FROZEN; } /* @@ -2448,9 +2832,10 @@ CopyFrom(CopyState cstate) resultRelInfo = makeNode(ResultRelInfo); InitResultRelInfo(resultRelInfo, cstate->rel, - 1, /* dummy rangetable index */ + 1, /* must match rel's position in range_table */ NULL, 0); + target_resultRelInfo = resultRelInfo; /* Verify the named relation is a valid target for INSERT */ CheckValidResultRel(resultRelInfo, CMD_INSERT); @@ -2460,12 +2845,8 @@ CopyFrom(CopyState cstate) estate->es_result_relations = resultRelInfo; estate->es_num_result_relations = 1; estate->es_result_relation_info = resultRelInfo; - estate->es_range_table = cstate->range_table; - /* Set up a tuple slot too */ - myslot = ExecInitExtraTupleSlot(estate, tupDesc); - /* Triggers might need a slot as well */ - estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL); + ExecInitRangeTable(estate, cstate->range_table); /* * Set up a ModifyTableState so we can let FDW(s) init themselves for @@ -2488,8 +2869,12 @@ CopyFrom(CopyState cstate) /* * If there are any triggers with transition tables on the named relation, * we need to be prepared to capture transition tuples. + * + * Because partition tuple routing would like to know about whether + * transition capture is active, we also set it in mtstate, which is + * passed to ExecFindPartition() below. */ - cstate->transition_capture = + cstate->transition_capture = mtstate->mt_transition_capture = MakeTransitionCaptureState(cstate->rel->trigdesc, RelationGetRelid(cstate->rel), CMD_INSERT); @@ -2499,47 +2884,109 @@ CopyFrom(CopyState cstate) * CopyFrom tuple routing. */ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - { - PartitionTupleRouting *proute; + proute = ExecSetupPartitionTupleRouting(estate, NULL, cstate->rel); - proute = cstate->partition_tuple_routing = - ExecSetupPartitionTupleRouting(NULL, cstate->rel); + if (cstate->whereClause) + cstate->qualexpr = ExecInitQual(castNode(List, cstate->whereClause), + &mtstate->ps); + /* + * It's generally more efficient to prepare a bunch of tuples for + * insertion, and insert them in one table_multi_insert() call, than call + * table_tuple_insert() separately for every tuple. However, there are a + * number of reasons why we might not be able to do this. These are + * explained below. + */ + if (resultRelInfo->ri_TrigDesc != NULL && + (resultRelInfo->ri_TrigDesc->trig_insert_before_row || + resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) + { /* - * If we are capturing transition tuples, they may need to be - * converted from partition format back to partitioned table format - * (this is only ever necessary if a BEFORE trigger modifies the - * tuple). + * Can't support multi-inserts when there are any BEFORE/INSTEAD OF + * triggers on the table. Such triggers might query the table we're + * inserting into and act differently if the tuples that have already + * been processed and prepared for insertion are not there. */ - if (cstate->transition_capture != NULL) - ExecSetupChildParentMapForLeaf(proute); + insertMethod = CIM_SINGLE; } - - /* - * It's more efficient to prepare a bunch of tuples for insertion, and - * insert them in one heap_multi_insert() call, than call heap_insert() - * separately for every tuple. However, we can't do that if there are - * BEFORE/INSTEAD OF triggers, or we need to evaluate volatile default - * expressions. Such triggers or expressions might query the table we're - * inserting to, and act differently if the tuples that have already been - * processed and prepared for insertion are not there. We also can't do - * it if the table is foreign or partitioned. - */ - if ((resultRelInfo->ri_TrigDesc != NULL && - (resultRelInfo->ri_TrigDesc->trig_insert_before_row || - resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) || - resultRelInfo->ri_FdwRoutine != NULL || - cstate->partition_tuple_routing != NULL || - cstate->volatile_defexprs) + else if (proute != NULL && resultRelInfo->ri_TrigDesc != NULL && + resultRelInfo->ri_TrigDesc->trig_insert_new_table) + { + /* + * For partitioned tables we can't support multi-inserts when there + * are any statement level insert triggers. It might be possible to + * allow partitioned tables with such triggers in the future, but for + * now, CopyMultiInsertInfoFlush expects that any before row insert + * and statement level insert triggers are on the same relation. + */ + insertMethod = CIM_SINGLE; + } + else if (resultRelInfo->ri_FdwRoutine != NULL || + cstate->volatile_defexprs) + { + /* + * Can't support multi-inserts to foreign tables or if there are any + * volatile default expressions in the table. Similarly to the + * trigger case above, such expressions may query the table we're + * inserting into. + * + * Note: It does not matter if any partitions have any volatile + * default expressions as we use the defaults from the target of the + * COPY command. + */ + insertMethod = CIM_SINGLE; + } + else if (contain_volatile_functions(cstate->whereClause)) { - useHeapMultiInsert = false; + /* + * Can't support multi-inserts if there are any volatile function + * expressions in WHERE clause. Similarly to the trigger case above, + * such expressions may query the table we're inserting into. + */ + insertMethod = CIM_SINGLE; } else { - useHeapMultiInsert = true; - bufferedTuples = palloc(MAX_BUFFERED_TUPLES * sizeof(HeapTuple)); + /* + * For partitioned tables, we may still be able to perform bulk + * inserts. However, the possibility of this depends on which types + * of triggers exist on the partition. We must disable bulk inserts + * if the partition is a foreign table or it has any before row insert + * or insert instead triggers (same as we checked above for the parent + * table). Since the partition's resultRelInfos are initialized only + * when we actually need to insert the first tuple into them, we must + * have the intermediate insert method of CIM_MULTI_CONDITIONAL to + * flag that we must later determine if we can use bulk-inserts for + * the partition being inserted into. + */ + if (proute) + insertMethod = CIM_MULTI_CONDITIONAL; + else + insertMethod = CIM_MULTI; + + CopyMultiInsertInfoInit(&multiInsertInfo, resultRelInfo, cstate, + estate, mycid, ti_options); } + /* + * If not using batch mode (which allocates slots as needed) set up a + * tuple slot too. When inserting into a partitioned table, we also need + * one, even if we might batch insert, to read the tuple in the root + * partition's form. + */ + if (insertMethod == CIM_SINGLE || insertMethod == CIM_MULTI_CONDITIONAL) + { + singleslot = table_slot_create(resultRelInfo->ri_RelationDesc, + &estate->es_tupleTable); + bistate = GetBulkInsertState(); + } + + has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_before_row); + + has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_instead_row); + /* * Check BEFORE STATEMENT insertion triggers. It's debatable whether we * should do this for COPY, since it's not really an "INSERT" statement as @@ -2548,10 +2995,6 @@ CopyFrom(CopyState cstate) */ ExecBSInsertTriggers(estate, resultRelInfo); - values = (Datum *) palloc(tupDesc->natts * sizeof(Datum)); - nulls = (bool *) palloc(tupDesc->natts * sizeof(bool)); - - bistate = GetBulkInsertState(); econtext = GetPerTupleExprContext(estate); /* Set up callback to identify error line number */ @@ -2562,92 +3005,114 @@ CopyFrom(CopyState cstate) for (;;) { - TupleTableSlot *slot; + TupleTableSlot *myslot; bool skip_tuple; - Oid loaded_oid = InvalidOid; CHECK_FOR_INTERRUPTS(); - if (nBufferedTuples == 0) + /* + * Reset the per-tuple exprcontext. We do this after every tuple, to + * clean-up after expression evaluations etc. + */ + ResetPerTupleExprContext(estate); + + /* select slot to (initially) load row into */ + if (insertMethod == CIM_SINGLE || proute) { - /* - * Reset the per-tuple exprcontext. We can only do this if the - * tuple buffer is empty. (Calling the context the per-tuple - * memory context is a bit of a misnomer now.) - */ - ResetPerTupleExprContext(estate); + myslot = singleslot; + Assert(myslot != NULL); + } + else + { + Assert(resultRelInfo == target_resultRelInfo); + Assert(insertMethod == CIM_MULTI); + + myslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, + resultRelInfo); } - /* Switch into its memory context */ + /* + * Switch to per-tuple context before calling NextCopyFrom, which does + * evaluate default expressions etc. and requires per-tuple context. + */ MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - if (!NextCopyFrom(cstate, econtext, values, nulls, &loaded_oid)) - break; + ExecClearTuple(myslot); - /* And now we can form the input tuple. */ - tuple = heap_form_tuple(tupDesc, values, nulls); + /* Directly store the values/nulls array in the slot */ + if (!NextCopyFrom(cstate, econtext, myslot->tts_values, myslot->tts_isnull)) + break; - if (loaded_oid != InvalidOid) - HeapTupleSetOid(tuple, loaded_oid); + ExecStoreVirtualTuple(myslot); /* - * Constraints might reference the tableoid column, so initialize - * t_tableOid before evaluating them. + * Constraints and where clause might reference the tableoid column, + * so (re-)initialize tts_tableOid before evaluating them. */ - tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + myslot->tts_tableOid = RelationGetRelid(target_resultRelInfo->ri_RelationDesc); /* Triggers and stuff need to be invoked in query context. */ MemoryContextSwitchTo(oldcontext); - /* Place tuple in tuple slot --- but slot shouldn't free it */ - slot = myslot; - ExecStoreTuple(tuple, slot, InvalidBuffer, false); + if (cstate->whereClause) + { + econtext->ecxt_scantuple = myslot; + /* Skip items that don't match COPY's WHERE clause */ + if (!ExecQual(cstate->qualexpr, econtext)) + continue; + } - /* Determine the partition to heap_insert the tuple into */ - if (cstate->partition_tuple_routing) + /* Determine the partition to insert the tuple into */ + if (proute) { - int leaf_part_index; - PartitionTupleRouting *proute = cstate->partition_tuple_routing; + TupleConversionMap *map; /* - * Away we go ... If we end up not finding a partition after all, - * ExecFindPartition() does not return and errors out instead. - * Otherwise, the returned value is to be used as an index into - * arrays mt_partitions[] and mt_partition_tupconv_maps[] that - * will get us the ResultRelInfo and TupleConversionMap for the - * partition, respectively. + * Attempt to find a partition suitable for this tuple. + * ExecFindPartition() will raise an error if none can be found or + * if the found partition is not suitable for INSERTs. */ - leaf_part_index = ExecFindPartition(resultRelInfo, - proute->partition_dispatch_info, - slot, - estate); - Assert(leaf_part_index >= 0 && - leaf_part_index < proute->num_partitions); + resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo, + proute, myslot, estate); - /* - * If this tuple is mapped to a partition that is not same as the - * previous one, we'd better make the bulk insert mechanism gets a - * new buffer. - */ - if (prev_leaf_part_index != leaf_part_index) + if (prevResultRelInfo != resultRelInfo) { - ReleaseBulkInsertStatePin(bistate); - prev_leaf_part_index = leaf_part_index; - } + /* Determine which triggers exist on this partition */ + has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_before_row); - /* - * Save the old ResultRelInfo and switch to the one corresponding - * to the selected partition. - */ - saved_resultRelInfo = resultRelInfo; - resultRelInfo = proute->partitions[leaf_part_index]; - if (resultRelInfo == NULL) - { - resultRelInfo = ExecInitPartitionInfo(mtstate, - saved_resultRelInfo, - proute, estate, - leaf_part_index); - Assert(resultRelInfo != NULL); + has_instead_insert_row_trig = (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_instead_row); + + /* + * Disable multi-inserts when the partition has BEFORE/INSTEAD + * OF triggers, or if the partition is a foreign partition. + */ + leafpart_use_multi_insert = insertMethod == CIM_MULTI_CONDITIONAL && + !has_before_insert_row_trig && + !has_instead_insert_row_trig && + resultRelInfo->ri_FdwRoutine == NULL; + + /* Set the multi-insert buffer to use for this partition. */ + if (leafpart_use_multi_insert) + { + if (resultRelInfo->ri_CopyMultiInsertBuffer == NULL) + CopyMultiInsertInfoSetupBuffer(&multiInsertInfo, + resultRelInfo); + } + else if (insertMethod == CIM_MULTI_CONDITIONAL && + !CopyMultiInsertInfoIsEmpty(&multiInsertInfo)) + { + /* + * Flush pending inserts if this partition can't use + * batching, so rows are visible to triggers etc. + */ + CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo); + } + + if (bistate != NULL) + ReleaseBulkInsertStatePin(bistate); + prevResultRelInfo = resultRelInfo; } /* @@ -2657,12 +3122,11 @@ CopyFrom(CopyState cstate) /* * If we're capturing transition tuples, we might need to convert - * from the partition rowtype to parent rowtype. + * from the partition rowtype to root rowtype. */ if (cstate->transition_capture != NULL) { - if (resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_insert_before_row) + if (has_before_insert_row_trig) { /* * If there are any BEFORE triggers on the partition, @@ -2671,8 +3135,7 @@ CopyFrom(CopyState cstate) */ cstate->transition_capture->tcs_original_insert_tuple = NULL; cstate->transition_capture->tcs_map = - TupConvMapForLeaf(proute, saved_resultRelInfo, - leaf_part_index); + resultRelInfo->ri_PartitionInfo->pi_PartitionToRootMap; } else { @@ -2680,96 +3143,128 @@ CopyFrom(CopyState cstate) * Otherwise, just remember the original unconverted * tuple, to avoid a needless round trip conversion. */ - cstate->transition_capture->tcs_original_insert_tuple = tuple; + cstate->transition_capture->tcs_original_insert_tuple = myslot; cstate->transition_capture->tcs_map = NULL; } } /* - * We might need to convert from the parent rowtype to the - * partition rowtype. + * We might need to convert from the root rowtype to the partition + * rowtype. */ - tuple = ConvertPartitionTupleSlot(proute->parent_child_tupconv_maps[leaf_part_index], - tuple, - proute->partition_tuple_slot, - &slot); + map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap; + if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert) + { + /* non batch insert */ + if (map != NULL) + { + TupleTableSlot *new_slot; - tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot; + myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot); + } + } + else + { + /* + * Prepare to queue up tuple for later batch insert into + * current partition. + */ + TupleTableSlot *batchslot; + + /* no other path available for partitioned table */ + Assert(insertMethod == CIM_MULTI_CONDITIONAL); + + batchslot = CopyMultiInsertInfoNextFreeSlot(&multiInsertInfo, + resultRelInfo); + + if (map != NULL) + myslot = execute_attr_map_slot(map->attrMap, myslot, + batchslot); + else + { + /* + * This looks more expensive than it is (Believe me, I + * optimized it away. Twice.). The input is in virtual + * form, and we'll materialize the slot below - for most + * slot types the copy performs the work materialization + * would later require anyway. + */ + ExecCopySlot(batchslot, myslot); + myslot = batchslot; + } + } + + /* ensure that triggers etc see the right relation */ + myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); } skip_tuple = false; /* BEFORE ROW INSERT Triggers */ - if (resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_insert_before_row) + if (has_before_insert_row_trig) { - slot = ExecBRInsertTriggers(estate, resultRelInfo, slot); - - if (slot == NULL) /* "do nothing" */ - skip_tuple = true; - else /* trigger might have changed tuple */ - tuple = ExecMaterializeSlot(slot); + if (!ExecBRInsertTriggers(estate, resultRelInfo, myslot)) + skip_tuple = true; /* "do nothing" */ } if (!skip_tuple) { - if (resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_insert_instead_row) + /* + * If there is an INSTEAD OF INSERT ROW trigger, let it handle the + * tuple. Otherwise, proceed with inserting the tuple into the + * table or foreign table. + */ + if (has_instead_insert_row_trig) { - /* Pass the data to the INSTEAD ROW INSERT trigger */ - ExecIRInsertTriggers(estate, resultRelInfo, slot); + ExecIRInsertTriggers(estate, resultRelInfo, myslot); } else { - /* - * We always check the partition constraint, including when - * the tuple got here via tuple-routing. However we don't - * need to in the latter case if no BR trigger is defined on - * the partition. Note that a BR trigger might modify the - * tuple such that the partition constraint is no longer - * satisfied, so we need to check in that case. - */ - bool check_partition_constr = - (resultRelInfo->ri_PartitionCheck != NIL); - - if (saved_resultRelInfo != NULL && - !(resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_insert_before_row)) - check_partition_constr = false; + /* Compute stored generated columns */ + if (resultRelInfo->ri_RelationDesc->rd_att->constr && + resultRelInfo->ri_RelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, myslot); /* * If the target is a plain table, check the constraints of * the tuple. */ if (resultRelInfo->ri_FdwRoutine == NULL && - (resultRelInfo->ri_RelationDesc->rd_att->constr || - check_partition_constr)) - ExecConstraints(resultRelInfo, slot, estate, true); + resultRelInfo->ri_RelationDesc->rd_att->constr) + ExecConstraints(resultRelInfo, myslot, estate); + + /* + * Also check the tuple against the partition constraint, if + * there is one; except that if we got here via tuple-routing, + * we don't need to if there's no BR trigger defined on the + * partition. + */ + if (resultRelInfo->ri_PartitionCheck && + (proute == NULL || has_before_insert_row_trig)) + ExecPartitionCheck(resultRelInfo, myslot, estate, true); - if (useHeapMultiInsert) + /* Store the slot in the multi-insert buffer, when enabled. */ + if (insertMethod == CIM_MULTI || leafpart_use_multi_insert) { + /* + * The slot previously might point into the per-tuple + * context. For batching it needs to be longer lived. + */ + ExecMaterializeSlot(myslot); + /* Add this tuple to the tuple buffer */ - if (nBufferedTuples == 0) - firstBufferedLineNo = cstate->cur_lineno; - bufferedTuples[nBufferedTuples++] = tuple; - bufferedTuplesSize += tuple->t_len; + CopyMultiInsertInfoStore(&multiInsertInfo, + resultRelInfo, myslot, + cstate->line_buf.len, + cstate->cur_lineno); /* - * If the buffer filled up, flush it. Also flush if the - * total size of all the tuples in the buffer becomes - * large, to avoid using large amounts of memory for the - * buffer when the tuples are exceptionally wide. + * If enough inserts have queued up, then flush all + * buffers out to their tables. */ - if (nBufferedTuples == MAX_BUFFERED_TUPLES || - bufferedTuplesSize > 65535) - { - CopyFromInsertBatch(cstate, estate, mycid, hi_options, - resultRelInfo, myslot, bistate, - nBufferedTuples, bufferedTuples, - firstBufferedLineNo); - nBufferedTuples = 0; - bufferedTuplesSize = 0; - } + if (CopyMultiInsertInfoIsFull(&multiInsertInfo)) + CopyMultiInsertInfoFlush(&multiInsertInfo, resultRelInfo); } else { @@ -2778,39 +3273,37 @@ CopyFrom(CopyState cstate) /* OK, store the tuple */ if (resultRelInfo->ri_FdwRoutine != NULL) { - slot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate, - resultRelInfo, - slot, - NULL); - - if (slot == NULL) /* "do nothing" */ - goto next_tuple; + myslot = resultRelInfo->ri_FdwRoutine->ExecForeignInsert(estate, + resultRelInfo, + myslot, + NULL); - /* FDW might have changed tuple */ - tuple = ExecMaterializeSlot(slot); + if (myslot == NULL) /* "do nothing" */ + continue; /* next tuple please */ /* * AFTER ROW Triggers might reference the tableoid - * column, so initialize t_tableOid before evaluating - * them. + * column, so (re-)initialize tts_tableOid before + * evaluating them. */ - tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + myslot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); } else - heap_insert(resultRelInfo->ri_RelationDesc, tuple, - mycid, hi_options, bistate); - - /* And create index entries for it */ - if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(slot, - &(tuple->t_self), - estate, - false, - NULL, - NIL); + { + /* OK, store the tuple and create index entries for it */ + table_tuple_insert(resultRelInfo->ri_RelationDesc, + myslot, mycid, ti_options, bistate); + + if (resultRelInfo->ri_NumIndices > 0) + recheckIndexes = ExecInsertIndexTuples(myslot, + estate, + false, + NULL, + NIL); + } /* AFTER ROW INSERT Triggers */ - ExecARInsertTriggers(estate, resultRelInfo, tuple, + ExecARInsertTriggers(estate, resultRelInfo, myslot, recheckIndexes, cstate->transition_capture); list_free(recheckIndexes); @@ -2824,27 +3317,20 @@ CopyFrom(CopyState cstate) */ processed++; } - -next_tuple: - /* Restore the saved ResultRelInfo */ - if (saved_resultRelInfo) - { - resultRelInfo = saved_resultRelInfo; - estate->es_result_relation_info = resultRelInfo; - } } /* Flush any remaining buffered tuples */ - if (nBufferedTuples > 0) - CopyFromInsertBatch(cstate, estate, mycid, hi_options, - resultRelInfo, myslot, bistate, - nBufferedTuples, bufferedTuples, - firstBufferedLineNo); + if (insertMethod != CIM_SINGLE) + { + if (!CopyMultiInsertInfoIsEmpty(&multiInsertInfo)) + CopyMultiInsertInfoFlush(&multiInsertInfo, NULL); + } /* Done, clean up */ error_context_stack = errcallback.previous; - FreeBulkInsertState(bistate); + if (bistate != NULL) + FreeBulkInsertState(bistate); MemoryContextSwitchTo(oldcontext); @@ -2856,122 +3342,37 @@ CopyFrom(CopyState cstate) pq_endmsgread(); /* Execute AFTER STATEMENT insertion triggers */ - ExecASInsertTriggers(estate, resultRelInfo, cstate->transition_capture); + ExecASInsertTriggers(estate, target_resultRelInfo, cstate->transition_capture); /* Handle queued AFTER triggers */ AfterTriggerEndQuery(estate); - pfree(values); - pfree(nulls); - ExecResetTupleTable(estate->es_tupleTable, false); /* Allow the FDW to shut down */ - if (resultRelInfo->ri_FdwRoutine != NULL && - resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL) - resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate, - resultRelInfo); + if (target_resultRelInfo->ri_FdwRoutine != NULL && + target_resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL) + target_resultRelInfo->ri_FdwRoutine->EndForeignInsert(estate, + target_resultRelInfo); - ExecCloseIndices(resultRelInfo); + /* Tear down the multi-insert buffer data */ + if (insertMethod != CIM_SINGLE) + CopyMultiInsertInfoCleanup(&multiInsertInfo); + + ExecCloseIndices(target_resultRelInfo); /* Close all the partitioned tables, leaf partitions, and their indices */ - if (cstate->partition_tuple_routing) - ExecCleanupTupleRouting(mtstate, cstate->partition_tuple_routing); + if (proute) + ExecCleanupTupleRouting(mtstate, proute); /* Close any trigger target relations */ ExecCleanUpTriggerState(estate); FreeExecutorState(estate); - /* - * If we skipped writing WAL, then we need to sync the heap (but not - * indexes since those use WAL anyway) - */ - if (hi_options & HEAP_INSERT_SKIP_WAL) - heap_sync(cstate->rel); - return processed; } -/* - * A subroutine of CopyFrom, to write the current batch of buffered heap - * tuples to the heap. Also updates indexes and runs AFTER ROW INSERT - * triggers. - */ -static void -CopyFromInsertBatch(CopyState cstate, EState *estate, CommandId mycid, - int hi_options, ResultRelInfo *resultRelInfo, - TupleTableSlot *myslot, BulkInsertState bistate, - int nBufferedTuples, HeapTuple *bufferedTuples, - int firstBufferedLineNo) -{ - MemoryContext oldcontext; - int i; - int save_cur_lineno; - - /* - * Print error context information correctly, if one of the operations - * below fail. - */ - cstate->line_buf_valid = false; - save_cur_lineno = cstate->cur_lineno; - - /* - * heap_multi_insert leaks memory, so switch to short-lived memory context - * before calling it. - */ - oldcontext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - heap_multi_insert(cstate->rel, - bufferedTuples, - nBufferedTuples, - mycid, - hi_options, - bistate); - MemoryContextSwitchTo(oldcontext); - - /* - * If there are any indexes, update them for all the inserted tuples, and - * run AFTER ROW INSERT triggers. - */ - if (resultRelInfo->ri_NumIndices > 0) - { - for (i = 0; i < nBufferedTuples; i++) - { - List *recheckIndexes; - - cstate->cur_lineno = firstBufferedLineNo + i; - ExecStoreTuple(bufferedTuples[i], myslot, InvalidBuffer, false); - recheckIndexes = - ExecInsertIndexTuples(myslot, &(bufferedTuples[i]->t_self), - estate, false, NULL, NIL); - ExecARInsertTriggers(estate, resultRelInfo, - bufferedTuples[i], - recheckIndexes, cstate->transition_capture); - list_free(recheckIndexes); - } - } - - /* - * There's no indexes, but see if we need to run AFTER ROW INSERT triggers - * anyway. - */ - else if (resultRelInfo->ri_TrigDesc != NULL && - (resultRelInfo->ri_TrigDesc->trig_insert_after_row || - resultRelInfo->ri_TrigDesc->trig_insert_new_table)) - { - for (i = 0; i < nBufferedTuples; i++) - { - cstate->cur_lineno = firstBufferedLineNo + i; - ExecARInsertTriggers(estate, resultRelInfo, - bufferedTuples[i], - NIL, cstate->transition_capture); - } - } - - /* reset cur_lineno to where we were */ - cstate->cur_lineno = save_cur_lineno; -} - /* * Setup to read tuples from a file for COPY FROM. * @@ -3009,7 +3410,7 @@ BeginCopyFrom(ParseState *pstate, oldcontext = MemoryContextSwitchTo(cstate->copycontext); /* Initialize state variables */ - cstate->fe_eof = false; + cstate->reached_eof = false; cstate->eol_type = EOL_UNKNOWN; cstate->cur_relname = RelationGetRelationName(cstate->rel); cstate->cur_lineno = 0; @@ -3061,7 +3462,7 @@ BeginCopyFrom(ParseState *pstate, fmgr_info(in_func_oid, &in_functions[attnum - 1]); /* Get default info if needed */ - if (!list_member_int(cstate->attnumlist, attnum)) + if (!list_member_int(cstate->attnumlist, attnum) && !att->attgenerated) { /* attribute is NOT to be copied from input */ /* use default value if one exists */ @@ -3164,12 +3565,7 @@ BeginCopyFrom(ParseState *pstate, } } - if (!cstate->binary) - { - /* must rely on user to tell us... */ - cstate->file_has_oids = cstate->oids; - } - else + if (cstate->binary) { /* Read and verify binary header */ char readSig[11]; @@ -3186,7 +3582,10 @@ BeginCopyFrom(ParseState *pstate, ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), errmsg("invalid COPY file header (missing flags)"))); - cstate->file_has_oids = (tmp & (1 << 16)) != 0; + if ((tmp & (1 << 16)) != 0) + ereport(ERROR, + (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), + errmsg("invalid COPY file header (WITH OIDS)"))); tmp &= ~(1 << 16); if ((tmp >> 16) != 0) ereport(ERROR, @@ -3208,21 +3607,13 @@ BeginCopyFrom(ParseState *pstate, } } - if (cstate->file_has_oids && cstate->binary) - { - getTypeBinaryInputInfo(OIDOID, - &in_func_oid, &cstate->oid_typioparam); - fmgr_info(in_func_oid, &cstate->oid_in_function); - } - /* create workspace for CopyReadAttributes results */ if (!cstate->binary) { AttrNumber attr_count = list_length(cstate->attnumlist); - int nfields = cstate->file_has_oids ? (attr_count + 1) : attr_count; - cstate->max_fields = nfields; - cstate->raw_fields = (char **) palloc(nfields * sizeof(char *)); + cstate->max_fields = attr_count; + cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *)); } MemoryContextSwitchTo(oldcontext); @@ -3295,7 +3686,7 @@ NextCopyFromRawFields(CopyState cstate, char ***fields, int *nfields) */ bool NextCopyFrom(CopyState cstate, ExprContext *econtext, - Datum *values, bool *nulls, Oid *tupleOid) + Datum *values, bool *nulls) { TupleDesc tupDesc; AttrNumber num_phys_attrs, @@ -3304,16 +3695,12 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext, FmgrInfo *in_functions = cstate->in_functions; Oid *typioparams = cstate->typioparams; int i; - int nfields; - bool isnull; - bool file_has_oids = cstate->file_has_oids; int *defmap = cstate->defmap; ExprState **defexprs = cstate->defexprs; tupDesc = RelationGetDescr(cstate->rel); num_phys_attrs = tupDesc->natts; attr_count = list_length(cstate->attnumlist); - nfields = file_has_oids ? (attr_count + 1) : attr_count; /* Initialize all values for row to NULL */ MemSet(values, 0, num_phys_attrs * sizeof(Datum)); @@ -3332,41 +3719,13 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext, return false; /* check for overflowing fields */ - if (nfields > 0 && fldct > nfields) + if (attr_count > 0 && fldct > attr_count) ereport(ERROR, (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), errmsg("extra data after last expected column"))); fieldno = 0; - /* Read the OID field if present */ - if (file_has_oids) - { - if (fieldno >= fldct) - ereport(ERROR, - (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("missing data for OID column"))); - string = field_strings[fieldno++]; - - if (string == NULL) - ereport(ERROR, - (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("null OID in COPY data"))); - else if (cstate->oids && tupleOid != NULL) - { - cstate->cur_attname = "oid"; - cstate->cur_attval = string; - *tupleOid = DatumGetObjectId(DirectFunctionCall1(oidin, - CStringGetDatum(string))); - if (*tupleOid == InvalidOid) - ereport(ERROR, - (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("invalid OID in COPY data"))); - cstate->cur_attname = NULL; - cstate->cur_attval = NULL; - } - } - /* Loop to read the user attributes on the line. */ foreach(cur, cstate->attnumlist) { @@ -3424,7 +3783,7 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext, cstate->cur_attval = NULL; } - Assert(fieldno == nfields); + Assert(fieldno == attr_count); } else { @@ -3470,27 +3829,6 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext, errmsg("row field count is %d, expected %d", (int) fld_count, attr_count))); - if (file_has_oids) - { - Oid loaded_oid; - - cstate->cur_attname = "oid"; - loaded_oid = - DatumGetObjectId(CopyReadBinaryAttribute(cstate, - 0, - &cstate->oid_in_function, - cstate->oid_typioparam, - -1, - &isnull)); - if (isnull || loaded_oid == InvalidOid) - ereport(ERROR, - (errcode(ERRCODE_BAD_COPY_FILE_FORMAT), - errmsg("invalid OID in COPY data"))); - cstate->cur_attname = NULL; - if (cstate->oids && tupleOid != NULL) - *tupleOid = loaded_oid; - } - i = 0; foreach(cur, cstate->attnumlist) { @@ -3977,9 +4315,14 @@ CopyReadLineText(CopyState cstate) { int mblen; + /* + * It is enough to look at the first byte in all our encodings, to + * get the length. (GB18030 is a bit special, but still works for + * our purposes; see comment in pg_gb18030_mblen()) + */ mblen_str[0] = c; - /* All our encodings only read the first byte to get the length */ mblen = pg_encoding_mblen(cstate->file_encoding, mblen_str); + IF_NEED_REFILL_AND_NOT_EOF_CONTINUE(mblen - 1); IF_NEED_REFILL_AND_EOF_BREAK(mblen - 1); raw_buf_ptr += mblen - 1; @@ -4724,6 +5067,11 @@ CopyAttributeOutCSV(CopyState cstate, char *string, * or NIL if there was none (in which case we want all the non-dropped * columns). * + * We don't include generated columns in the generated full list and we don't + * allow them to be specified explicitly. They don't make sense for COPY + * FROM, but we could possibly allow them for COPY TO. But this way it's at + * least ensured that whatever we copy out can be copied back in. + * * rel can be NULL ... it's only used for error reports. */ static List * @@ -4741,6 +5089,8 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist) { if (TupleDescAttr(tupDesc, i)->attisdropped) continue; + if (TupleDescAttr(tupDesc, i)->attgenerated) + continue; attnums = lappend_int(attnums, i + 1); } } @@ -4765,6 +5115,12 @@ CopyGetAttnums(TupleDesc tupDesc, Relation rel, List *attnamelist) continue; if (namestrcmp(&(att->attname), name) == 0) { + if (att->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), + errmsg("column \"%s\" is a generated column", + name), + errdetail("Generated columns cannot be used in COPY."))); attnum = att->attnum; break; } @@ -4814,11 +5170,8 @@ copy_dest_receive(TupleTableSlot *slot, DestReceiver *self) DR_copy *myState = (DR_copy *) self; CopyState cstate = myState->cstate; - /* Make sure the tuple is fully deconstructed */ - slot_getallattrs(slot); - - /* And send the data */ - CopyOneRowTo(cstate, InvalidOid, slot->tts_values, slot->tts_isnull); + /* Send the data */ + CopyOneRowTo(cstate, slot); myState->processed++; return true; diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index 3d82edbf581..b7d220699fb 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -13,7 +13,7 @@ * we must return a tuples-processed count in the completionTag. (We no * longer do that for CTAS ... WITH NO DATA, however.) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,9 +24,11 @@ */ #include "postgres.h" +#include "access/heapam.h" #include "access/reloptions.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/namespace.h" @@ -58,7 +60,7 @@ typedef struct Relation rel; /* relation to write to */ ObjectAddress reladdr; /* address of rel, for ExecCreateTableAs */ CommandId output_cid; /* cmin to insert in output tuples */ - int hi_options; /* heap_insert performance options */ + int ti_options; /* table_tuple_insert performance options */ BulkInsertState bistate; /* bulk insert state */ } DR_intorel; @@ -107,6 +109,7 @@ create_ctas_internal(List *attrList, IntoClause *into) create->oncommit = into->onCommit; create->tablespacename = into->tableSpaceName; create->if_not_exists = false; + create->accessMethod = into->accessMethod; /* * Create the relation. (This will error out if there's an existing view, @@ -178,7 +181,7 @@ create_ctas_nodata(List *tlist, IntoClause *into) if (lc) { colname = strVal(lfirst(lc)); - lc = lnext(lc); + lc = lnext(into->colNames, lc); } else colname = tle->resname; @@ -391,20 +394,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, int GetIntoRelEFlags(IntoClause *intoClause) { - int flags; - - /* - * We need to tell the executor whether it has to produce OIDs or not, - * because it doesn't have enough information to do so itself (since we - * can't build the target relation until after ExecutorStart). - * - * Disallow the OIDS option for materialized views. - */ - if (interpretOidsOption(intoClause->options, - (intoClause->viewQuery == NULL))) - flags = EXEC_FLAG_WITH_OIDS; - else - flags = EXEC_FLAG_WITHOUT_OIDS; + int flags = 0; if (intoClause->skipData) flags |= EXEC_FLAG_WITH_NO_DATA; @@ -475,7 +465,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) if (lc) { colname = strVal(lfirst(lc)); - lc = lnext(lc); + lc = lnext(into->colNames, lc); } else colname = NameStr(attribute->attname); @@ -516,7 +506,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) /* * Finally we can open the target table */ - intoRelationDesc = heap_open(intoRelationAddr.objectId, AccessExclusiveLock); + intoRelationDesc = table_open(intoRelationAddr.objectId, AccessExclusiveLock); /* * Check INSERT permission on the constructed table. @@ -528,6 +518,7 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) rte->rtekind = RTE_RELATION; rte->relid = intoRelationAddr.objectId; rte->relkind = relkind; + rte->rellockmode = RowExclusiveLock; rte->requiredPerms = ACL_INSERT; for (attnum = 1; attnum <= intoRelationDesc->rd_att->natts; attnum++) @@ -567,8 +558,8 @@ intorel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) * We can skip WAL-logging the insertions, unless PITR or streaming * replication is in use. We can skip the FSM in any case. */ - myState->hi_options = HEAP_INSERT_SKIP_FSM | - (XLogIsNeeded() ? 0 : HEAP_INSERT_SKIP_WAL); + myState->ti_options = TABLE_INSERT_SKIP_FSM | + (XLogIsNeeded() ? 0 : TABLE_INSERT_SKIP_WAL); myState->bistate = GetBulkInsertState(); /* Not using WAL requires smgr_targblock be initially invalid */ @@ -582,25 +573,21 @@ static bool intorel_receive(TupleTableSlot *slot, DestReceiver *self) { DR_intorel *myState = (DR_intorel *) self; - HeapTuple tuple; - - /* - * get the heap tuple out of the tuple table slot, making sure we have a - * writable copy - */ - tuple = ExecMaterializeSlot(slot); /* - * force assignment of new OID (see comments in ExecInsert) + * Note that the input slot might not be of the type of the target + * relation. That's supported by table_tuple_insert(), but slightly less + * efficient than inserting with the right slot - but the alternative + * would be to copy into a slot of the right type, which would not be + * cheap either. This also doesn't allow accessing per-AM data (say a + * tuple's xmin), but since we don't do that here... */ - if (myState->rel->rd_rel->relhasoids) - HeapTupleSetOid(tuple, InvalidOid); - heap_insert(myState->rel, - tuple, - myState->output_cid, - myState->hi_options, - myState->bistate); + table_tuple_insert(myState->rel, + slot, + myState->output_cid, + myState->ti_options, + myState->bistate); /* We know this is a newly created relation, so there are no indexes */ @@ -617,12 +604,10 @@ intorel_shutdown(DestReceiver *self) FreeBulkInsertState(myState->bistate); - /* If we skipped using WAL, must heap_sync before commit */ - if (myState->hi_options & HEAP_INSERT_SKIP_WAL) - heap_sync(myState->rel); + table_finish_bulk_insert(myState->rel, myState->ti_options); /* close rel, but keep lock until commit */ - heap_close(myState->rel, NoLock); + table_close(myState->rel, NoLock); myState->rel = NULL; } diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c index 5342f217c02..01d66212e98 100644 --- a/src/backend/commands/dbcommands.c +++ b/src/backend/commands/dbcommands.c @@ -8,7 +8,7 @@ * stepping on each others' toes. Formerly we used table-level locks * on pg_database, but that's too coarse-grained. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,6 +26,8 @@ #include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" +#include "access/multixact.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xloginsert.h" #include "access/xlogutils.h" @@ -53,6 +55,7 @@ #include "storage/fd.h" #include "storage/lmgr.h" #include "storage/ipc.h" +#include "storage/md.h" #include "storage/procarray.h" #include "storage/smgr.h" #include "utils/acl.h" @@ -61,7 +64,6 @@ #include "utils/pg_locale.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" typedef struct @@ -81,11 +83,11 @@ static void createdb_failure_callback(int code, Datum arg); static void movedb(const char *dbname, const char *tblspcname); static void movedb_failure_callback(int code, Datum arg); static bool get_db_info(const char *name, LOCKMODE lockmode, - Oid *dbIdP, Oid *ownerIdP, - int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, - Oid *dbLastSysOidP, TransactionId *dbFrozenXidP, - MultiXactId *dbMinMultiP, - Oid *dbTablespace, char **dbCollate, char **dbCtype); + Oid *dbIdP, Oid *ownerIdP, + int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP, + Oid *dbLastSysOidP, TransactionId *dbFrozenXidP, + MultiXactId *dbMinMultiP, + Oid *dbTablespace, char **dbCollate, char **dbCtype); static bool have_createdb_privilege(void); static void remove_dbtablespaces(Oid db_id); static bool check_db_file_conflict(Oid db_id); @@ -98,18 +100,18 @@ static int errdetail_busy_db(int notherbackends, int npreparedxacts); Oid createdb(ParseState *pstate, const CreatedbStmt *stmt) { - HeapScanDesc scan; + TableScanDesc scan; Relation rel; Oid src_dboid; Oid src_owner; - int src_encoding; - char *src_collate; - char *src_ctype; + int src_encoding = -1; + char *src_collate = NULL; + char *src_ctype = NULL; bool src_istemplate; bool src_allowconn; - Oid src_lastsysoid; - TransactionId src_frozenxid; - MultiXactId src_minmxid; + Oid src_lastsysoid = InvalidOid; + TransactionId src_frozenxid = InvalidTransactionId; + MultiXactId src_minmxid = InvalidMultiXactId; Oid src_deftablespace; volatile Oid dst_deftablespace; Relation pg_database_rel; @@ -123,6 +125,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) DefElem *downer = NULL; DefElem *dtemplate = NULL; DefElem *dencoding = NULL; + DefElem *dlocale = NULL; DefElem *dcollate = NULL; DefElem *dctype = NULL; DefElem *distemplate = NULL; @@ -183,6 +186,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) parser_errposition(pstate, defel->location))); dencoding = defel; } + else if (strcmp(defel->defname, "locale") == 0) + { + if (dlocale) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + parser_errposition(pstate, defel->location))); + dlocale = defel; + } else if (strcmp(defel->defname, "lc_collate") == 0) { if (dcollate) @@ -243,6 +255,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) parser_errposition(pstate, defel->location))); } + if (dlocale && (dcollate || dctype)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + errdetail("LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE."))); + if (downer && downer->arg) dbowner = defGetString(downer); if (dtemplate && dtemplate->arg) @@ -275,6 +293,11 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) parser_errposition(pstate, dencoding->location))); } } + if (dlocale && dlocale->arg) + { + dbcollate = defGetString(dlocale); + dbctype = defGetString(dlocale); + } if (dcollate && dcollate->arg) dbcollate = defGetString(dcollate); if (dctype && dctype->arg) @@ -469,6 +492,16 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) /* Note there is no additional permission check in this path */ } + /* + * If built with appropriate switch, whine when regression-testing + * conventions for database names are violated. But don't complain during + * initdb. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (IsUnderPostmaster && strstr(dbname, "regression") == NULL) + elog(WARNING, "databases created by regression test cases should have names including \"regression\""); +#endif + /* * Check for db name conflict. This is just to give a more friendly error * message than "unique index violation". There's a race condition but @@ -500,11 +533,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) * filename conflict with anything already existing in the tablespace * directories. */ - pg_database_rel = heap_open(DatabaseRelationId, RowExclusiveLock); + pg_database_rel = table_open(DatabaseRelationId, RowExclusiveLock); do { - dboid = GetNewOid(pg_database_rel); + dboid = GetNewOidWithIndex(pg_database_rel, DatabaseOidIndexId, + Anum_pg_database_oid); } while (check_db_file_conflict(dboid)); /* @@ -517,6 +551,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) MemSet(new_record, 0, sizeof(new_record)); MemSet(new_record_nulls, false, sizeof(new_record_nulls)); + new_record[Anum_pg_database_oid - 1] = ObjectIdGetDatum(dboid); new_record[Anum_pg_database_datname - 1] = DirectFunctionCall1(namein, CStringGetDatum(dbname)); new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba); @@ -543,8 +578,6 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) tuple = heap_form_tuple(RelationGetDescr(pg_database_rel), new_record, new_record_nulls); - HeapTupleSetOid(tuple, dboid); - CatalogTupleInsert(pg_database_rel, tuple); /* @@ -589,11 +622,12 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) * Iterate through all tablespaces of the template database, and copy * each one to the new database. */ - rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(TableSpaceRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid srctablespace = HeapTupleGetOid(tuple); + Form_pg_tablespace spaceform = (Form_pg_tablespace) GETSTRUCT(tuple); + Oid srctablespace = spaceform->oid; Oid dsttablespace; char *srcpath; char *dstpath; @@ -643,8 +677,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) XLOG_DBASE_CREATE | XLR_SPECIAL_REL_UPDATE); } } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); /* * We force a checkpoint before committing. This effectively means @@ -680,7 +714,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt) /* * Close pg_database, but keep lock till commit. */ - heap_close(pg_database_rel, NoLock); + table_close(pg_database_rel, NoLock); /* * Force synchronous commit, thus minimizing the window between @@ -796,7 +830,7 @@ dropdb(const char *dbname, bool missing_ok) * using it as a CREATE DATABASE template or trying to delete it for * themselves. */ - pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock); + pgdbrel = table_open(DatabaseRelationId, RowExclusiveLock); if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL, &db_istemplate, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) @@ -810,7 +844,7 @@ dropdb(const char *dbname, bool missing_ok) else { /* Close pg_database, release the lock, since we changed nothing */ - heap_close(pgdbrel, RowExclusiveLock); + table_close(pgdbrel, RowExclusiveLock); ereport(NOTICE, (errmsg("database \"%s\" does not exist, skipping", dbname))); @@ -940,11 +974,11 @@ dropdb(const char *dbname, bool missing_ok) * worse, it will delete files that belong to a newly created database * with the same OID. */ - ForgetDatabaseFsyncRequests(db_id); + ForgetDatabaseSyncRequests(db_id); /* * Force a checkpoint to make sure the checkpointer has received the - * message sent by ForgetDatabaseFsyncRequests. On Windows, this also + * message sent by ForgetDatabaseSyncRequests. On Windows, this also * ensures that background procs don't hold any open files, which would * cause rmdir() to fail. */ @@ -958,7 +992,7 @@ dropdb(const char *dbname, bool missing_ok) /* * Close pg_database, but keep lock till commit. */ - heap_close(pgdbrel, NoLock); + table_close(pgdbrel, NoLock); /* * Force synchronous commit, thus minimizing the window between removal of @@ -987,7 +1021,7 @@ RenameDatabase(const char *oldname, const char *newname) * Look up the target database's OID, and get exclusive lock on it. We * need this for the same reasons as DROP DATABASE. */ - rel = heap_open(DatabaseRelationId, RowExclusiveLock); + rel = table_open(DatabaseRelationId, RowExclusiveLock); if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) @@ -1006,6 +1040,15 @@ RenameDatabase(const char *oldname, const char *newname) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied to rename database"))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for database names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strstr(newname, "regression") == NULL) + elog(WARNING, "databases created by regression test cases should have names including \"regression\""); +#endif + /* * Make sure the new name doesn't exist. See notes for same error in * CREATE DATABASE. @@ -1053,7 +1096,7 @@ RenameDatabase(const char *oldname, const char *newname) /* * Close pg_database, but keep lock till commit. */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return address; } @@ -1091,7 +1134,7 @@ movedb(const char *dbname, const char *tblspcname) * we are moving it, and that no one is using it as a CREATE DATABASE * template or trying to delete it. */ - pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock); + pgdbrel = table_open(DatabaseRelationId, RowExclusiveLock); if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &src_tblspcoid, NULL, NULL)) @@ -1150,7 +1193,7 @@ movedb(const char *dbname, const char *tblspcname) */ if (src_tblspcoid == dst_tblspcoid) { - heap_close(pgdbrel, NoLock); + table_close(pgdbrel, NoLock); UnlockSharedObjectForSession(DatabaseRelationId, db_id, 0, AccessExclusiveLock); return; @@ -1301,8 +1344,7 @@ movedb(const char *dbname, const char *tblspcname) new_record_nulls, new_record_repl); CatalogTupleUpdate(pgdbrel, &oldtuple->t_self, newtuple); - InvokeObjectPostAlterHook(DatabaseRelationId, - HeapTupleGetOid(newtuple), 0); + InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0); systable_endscan(sysscan); @@ -1325,7 +1367,7 @@ movedb(const char *dbname, const char *tblspcname) /* * Close pg_database, but keep lock till commit. */ - heap_close(pgdbrel, NoLock); + table_close(pgdbrel, NoLock); } PG_END_ENSURE_ERROR_CLEANUP(movedb_failure_callback, PointerGetDatum(&fparms)); @@ -1400,6 +1442,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) Oid dboid; HeapTuple tuple, newtuple; + Form_pg_database datform; ScanKeyData scankey; SysScanDesc scan; ListCell *option; @@ -1499,7 +1542,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) * because we're not going to do anything that would mess up incoming * connections. */ - rel = heap_open(DatabaseRelationId, RowExclusiveLock); + rel = table_open(DatabaseRelationId, RowExclusiveLock); ScanKeyInit(&scankey, Anum_pg_database_datname, BTEqualStrategyNumber, F_NAMEEQ, @@ -1512,9 +1555,10 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", stmt->dbname))); - dboid = HeapTupleGetOid(tuple); + datform = (Form_pg_database) GETSTRUCT(tuple); + dboid = datform->oid; - if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId())) + if (!pg_database_ownercheck(dboid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, stmt->dbname); @@ -1556,13 +1600,12 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel) new_record_nulls, new_record_repl); CatalogTupleUpdate(rel, &tuple->t_self, newtuple); - InvokeObjectPostAlterHook(DatabaseRelationId, - HeapTupleGetOid(newtuple), 0); + InvokeObjectPostAlterHook(DatabaseRelationId, dboid, 0); systable_endscan(scan); /* Close pg_database, but keep lock till commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return dboid; } @@ -1613,7 +1656,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) * because we're not going to do anything that would mess up incoming * connections. */ - rel = heap_open(DatabaseRelationId, RowExclusiveLock); + rel = table_open(DatabaseRelationId, RowExclusiveLock); ScanKeyInit(&scankey, Anum_pg_database_datname, BTEqualStrategyNumber, F_NAMEEQ, @@ -1626,8 +1669,8 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", dbname))); - db_id = HeapTupleGetOid(tuple); datForm = (Form_pg_database) GETSTRUCT(tuple); + db_id = datForm->oid; /* * If the new owner is the same as the existing owner, consider the @@ -1645,7 +1688,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) HeapTuple newtuple; /* Otherwise, must be owner of the existing object */ - if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId())) + if (!pg_database_ownercheck(db_id, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, dbname); @@ -1694,18 +1737,17 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId) heap_freetuple(newtuple); /* Update owner dependency reference */ - changeDependencyOnOwner(DatabaseRelationId, HeapTupleGetOid(tuple), - newOwnerId); + changeDependencyOnOwner(DatabaseRelationId, db_id, newOwnerId); } - InvokeObjectPostAlterHook(DatabaseRelationId, HeapTupleGetOid(tuple), 0); + InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0); ObjectAddressSet(address, DatabaseRelationId, db_id); systable_endscan(scan); /* Close pg_database, but keep lock till commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return address; } @@ -1735,7 +1777,7 @@ get_db_info(const char *name, LOCKMODE lockmode, AssertArg(name); /* Caller may wish to grab a better lock on pg_database beforehand... */ - relation = heap_open(DatabaseRelationId, AccessShareLock); + relation = table_open(DatabaseRelationId, AccessShareLock); /* * Loop covers the rare case where the database is renamed before we can @@ -1770,7 +1812,7 @@ get_db_info(const char *name, LOCKMODE lockmode, break; } - dbOid = HeapTupleGetOid(tuple); + dbOid = ((Form_pg_database) GETSTRUCT(tuple))->oid; systable_endscan(scan); @@ -1813,7 +1855,7 @@ get_db_info(const char *name, LOCKMODE lockmode, /* limit of frozen XIDs */ if (dbFrozenXidP) *dbFrozenXidP = dbform->datfrozenxid; - /* minimum MultixactId */ + /* minimum MultiXactId */ if (dbMinMultiP) *dbMinMultiP = dbform->datminmxid; /* default tablespace for this database */ @@ -1836,7 +1878,7 @@ get_db_info(const char *name, LOCKMODE lockmode, UnlockSharedObject(DatabaseRelationId, dbOid, 0, lockmode); } - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); return result; } @@ -1871,14 +1913,15 @@ static void remove_dbtablespaces(Oid db_id) { Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; - rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(TableSpaceRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid dsttablespace = HeapTupleGetOid(tuple); + Form_pg_tablespace spcform = (Form_pg_tablespace) GETSTRUCT(tuple); + Oid dsttablespace = spcform->oid; char *dstpath; struct stat st; @@ -1917,8 +1960,8 @@ remove_dbtablespaces(Oid db_id) pfree(dstpath); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); } /* @@ -1938,14 +1981,15 @@ check_db_file_conflict(Oid db_id) { bool result = false; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; - rel = heap_open(TableSpaceRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(TableSpaceRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid dsttablespace = HeapTupleGetOid(tuple); + Form_pg_tablespace spcform = (Form_pg_tablespace) GETSTRUCT(tuple); + Oid dsttablespace = spcform->oid; char *dstpath; struct stat st; @@ -1966,8 +2010,8 @@ check_db_file_conflict(Oid db_id) pfree(dstpath); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); return result; } @@ -2018,7 +2062,7 @@ get_database_oid(const char *dbname, bool missing_ok) * There's no syscache for pg_database indexed by name, so we must look * the hard way. */ - pg_database = heap_open(DatabaseRelationId, AccessShareLock); + pg_database = table_open(DatabaseRelationId, AccessShareLock); ScanKeyInit(&entry[0], Anum_pg_database_datname, BTEqualStrategyNumber, F_NAMEEQ, @@ -2030,12 +2074,12 @@ get_database_oid(const char *dbname, bool missing_ok) /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(dbtuple)) - oid = HeapTupleGetOid(dbtuple); + oid = ((Form_pg_database) GETSTRUCT(dbtuple))->oid; else oid = InvalidOid; systable_endscan(scan); - heap_close(pg_database, AccessShareLock); + table_close(pg_database, AccessShareLock); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, @@ -2148,7 +2192,7 @@ dbase_redo(XLogReaderState *record) DropDatabaseBuffers(xlrec->db_id); /* Also, clean out any fsync requests that might be pending in md.c */ - ForgetDatabaseFsyncRequests(xlrec->db_id); + ForgetDatabaseSyncRequests(xlrec->db_id); /* Clean out the xlog relcache too */ XLogDropDatabase(xlrec->db_id); diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c index 00b5721f85f..9c93e415f14 100644 --- a/src/backend/commands/define.c +++ b/src/backend/commands/define.c @@ -4,7 +4,7 @@ * Support routines for various kinds of object creation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -139,7 +139,7 @@ defGetBoolean(DefElem *def) /* * The set of strings accepted here should match up with the - * grammar's opt_boolean production. + * grammar's opt_boolean_or_string production. */ if (pg_strcasecmp(sval, "true") == 0) return true; diff --git a/src/backend/commands/discard.c b/src/backend/commands/discard.c index 01a999c2ac7..23a14586ba5 100644 --- a/src/backend/commands/discard.c +++ b/src/backend/commands/discard.c @@ -3,7 +3,7 @@ * discard.c * The implementation of the DISCARD command * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index 4b38ef68d98..be7a40d5d2d 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -3,19 +3,20 @@ * dropcmds.c * handle various "DROP" operations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * src/backend/catalog/dropcmds.c + * src/backend/commands/dropcmds.c * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" +#include "access/xact.h" #include "catalog/dependency.h" #include "catalog/namespace.h" #include "catalog/objectaddress.h" @@ -31,13 +32,13 @@ static void does_not_exist_skipping(ObjectType objtype, - Node *object); + Node *object); static bool owningrel_does_not_exist_skipping(List *object, - const char **msg, char **name); + const char **msg, char **name); static bool schema_does_not_exist_skipping(List *object, - const char **msg, char **name); + const char **msg, char **name); static bool type_in_list_does_not_exist_skipping(List *typenames, - const char **msg, char **name); + const char **msg, char **name); /* @@ -107,9 +108,16 @@ RemoveObjects(DropStmt *stmt) check_object_ownership(GetUserId(), stmt->removeType, address, object, relation); + /* + * Make note if a temporary namespace has been accessed in this + * transaction. + */ + if (OidIsValid(namespaceId) && isTempNamespace(namespaceId)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + /* Release any relcache reference count, but keep lock until commit. */ if (relation) - heap_close(relation, NoLock); + table_close(relation, NoLock); add_exact_object_address(&address, objects); } diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c index 549c7ea51d7..f7ee9838f7f 100644 --- a/src/backend/commands/event_trigger.c +++ b/src/backend/commands/event_trigger.c @@ -3,7 +3,7 @@ * event_trigger.c * PostgreSQL EVENT TRIGGER support code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,7 +14,9 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -43,7 +45,6 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" #include "utils/syscache.h" #include "tcop/utility.h" @@ -85,7 +86,7 @@ typedef enum } event_trigger_command_tag_check_result; /* XXX merge this with ObjectTypeMap? */ -static event_trigger_support_data event_trigger_support[] = { +static const event_trigger_support_data event_trigger_support[] = { {"ACCESS METHOD", true}, {"AGGREGATE", true}, {"CAST", true}, @@ -147,15 +148,14 @@ typedef struct SQLDropObject } SQLDropObject; static void AlterEventTriggerOwner_internal(Relation rel, - HeapTuple tup, - Oid newOwnerId); + HeapTuple tup, + Oid newOwnerId); static event_trigger_command_tag_check_result check_ddl_tag(const char *tag); -static event_trigger_command_tag_check_result check_table_rewrite_ddl_tag( - const char *tag); +static event_trigger_command_tag_check_result check_table_rewrite_ddl_tag(const char *tag); static void error_duplicate_filter_variable(const char *defname); static Datum filter_list_to_array(List *filterlist); -static Oid insert_event_trigger_tuple(const char *trigname, const char *eventname, - Oid evtOwner, Oid funcoid, List *tags); +static Oid insert_event_trigger_tuple(const char *trigname, const char *eventname, + Oid evtOwner, Oid funcoid, List *tags); static void validate_ddl_tags(const char *filtervar, List *taglist); static void validate_table_rewrite_tags(const char *filtervar, List *taglist); static void EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata); @@ -282,7 +282,7 @@ static event_trigger_command_tag_check_result check_ddl_tag(const char *tag) { const char *obtypename; - event_trigger_support_data *etsd; + const event_trigger_support_data *etsd; /* * Handle some idiosyncratic special cases. @@ -388,9 +388,12 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO referenced; /* Open pg_event_trigger. */ - tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock); + tgrel = table_open(EventTriggerRelationId, RowExclusiveLock); /* Build the new pg_trigger tuple. */ + trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId, + Anum_pg_event_trigger_oid); + values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid); memset(nulls, false, sizeof(nulls)); namestrcpy(&evtnamedata, trigname); values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata); @@ -408,7 +411,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO /* Insert heap tuple. */ tuple = heap_form_tuple(tgrel->rd_att, values, nulls); - trigoid = CatalogTupleInsert(tgrel, tuple); + CatalogTupleInsert(tgrel, tuple); heap_freetuple(tuple); /* Depend on owner. */ @@ -430,7 +433,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO InvokeObjectPostCreateHook(EventTriggerRelationId, trigoid, 0); /* Close pg_event_trigger. */ - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); return trigoid; } @@ -481,7 +484,7 @@ RemoveEventTriggerById(Oid trigOid) Relation tgrel; HeapTuple tup; - tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock); + tgrel = table_open(EventTriggerRelationId, RowExclusiveLock); tup = SearchSysCache1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid)); if (!HeapTupleIsValid(tup)) @@ -491,7 +494,7 @@ RemoveEventTriggerById(Oid trigOid) ReleaseSysCache(tup); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); } /* @@ -506,7 +509,7 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) Form_pg_event_trigger evtForm; char tgenabled = stmt->tgenabled; - tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock); + tgrel = table_open(EventTriggerRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(stmt->trigname)); @@ -516,14 +519,14 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) errmsg("event trigger \"%s\" does not exist", stmt->trigname))); - trigoid = HeapTupleGetOid(tup); + evtForm = (Form_pg_event_trigger) GETSTRUCT(tup); + trigoid = evtForm->oid; if (!pg_event_trigger_ownercheck(trigoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER, stmt->trigname); /* tuple is a copy, so we can modify it below */ - evtForm = (Form_pg_event_trigger) GETSTRUCT(tup); evtForm->evtenabled = tgenabled; CatalogTupleUpdate(tgrel, &tup->t_self, tup); @@ -533,7 +536,7 @@ AlterEventTrigger(AlterEventTrigStmt *stmt) /* clean up */ heap_freetuple(tup); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); return trigoid; } @@ -546,10 +549,11 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId) { Oid evtOid; HeapTuple tup; + Form_pg_event_trigger evtForm; Relation rel; ObjectAddress address; - rel = heap_open(EventTriggerRelationId, RowExclusiveLock); + rel = table_open(EventTriggerRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(EVENTTRIGGERNAME, CStringGetDatum(name)); @@ -558,7 +562,8 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("event trigger \"%s\" does not exist", name))); - evtOid = HeapTupleGetOid(tup); + evtForm = (Form_pg_event_trigger) GETSTRUCT(tup); + evtOid = evtForm->oid; AlterEventTriggerOwner_internal(rel, tup, newOwnerId); @@ -566,7 +571,7 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -580,7 +585,7 @@ AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(EventTriggerRelationId, RowExclusiveLock); + rel = table_open(EventTriggerRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(EVENTTRIGGEROID, ObjectIdGetDatum(trigOid)); @@ -593,7 +598,7 @@ AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -609,7 +614,7 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) if (form->evtowner == newOwnerId) return; - if (!pg_event_trigger_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_event_trigger_ownercheck(form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER, NameStr(form->evtname)); @@ -626,11 +631,11 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* Update owner dependency reference */ changeDependencyOnOwner(EventTriggerRelationId, - HeapTupleGetOid(tup), + form->oid, newOwnerId); InvokeObjectPostAlterHook(EventTriggerRelationId, - HeapTupleGetOid(tup), 0); + form->oid, 0); } /* @@ -644,7 +649,8 @@ get_event_trigger_oid(const char *trigname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(EVENTTRIGGERNAME, CStringGetDatum(trigname)); + oid = GetSysCacheOid1(EVENTTRIGGERNAME, Anum_pg_event_trigger_oid, + CStringGetDatum(trigname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -836,6 +842,19 @@ EventTriggerDDLCommandEnd(Node *parsetree) if (!IsUnderPostmaster) return; + /* + * Also do nothing if our state isn't set up, which it won't be if there + * weren't any relevant event triggers at the start of the current DDL + * command. This test might therefore seem optional, but it's important + * because EventTriggerCommonSetup might find triggers that didn't exist + * at the time the command started. Although this function itself + * wouldn't crash, the event trigger functions would presumably call + * pg_event_trigger_ddl_commands which would fail. Better to do nothing + * until the next command. + */ + if (!currentEventTriggerState) + return; + runlist = EventTriggerCommonSetup(parsetree, EVT_DDLCommandEnd, "ddl_command_end", &trigdata); @@ -887,9 +906,10 @@ EventTriggerSQLDrop(Node *parsetree) &trigdata); /* - * Nothing to do if run list is empty. Note this shouldn't happen, + * Nothing to do if run list is empty. Note this typically can't happen, * because if there are no sql_drop events, then objects-to-drop wouldn't * have been collected in the first place and we would have quit above. + * But it could occur if event triggers were dropped partway through. */ if (runlist == NIL) return; @@ -936,8 +956,6 @@ EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason) List *runlist; EventTriggerData trigdata; - elog(DEBUG1, "EventTriggerTableRewrite(%u)", tableOid); - /* * Event Triggers are completely disabled in standalone mode. There are * (at least) two reasons for this: @@ -957,6 +975,16 @@ EventTriggerTableRewrite(Node *parsetree, Oid tableOid, int reason) if (!IsUnderPostmaster) return; + /* + * Also do nothing if our state isn't set up, which it won't be if there + * weren't any relevant event triggers at the start of the current DDL + * command. This test might therefore seem optional, but it's + * *necessary*, because EventTriggerCommonSetup might find triggers that + * didn't exist at the time the command started. + */ + if (!currentEventTriggerState) + return; + runlist = EventTriggerCommonSetup(parsetree, EVT_TableRewrite, "table_rewrite", @@ -1026,9 +1054,9 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata) /* Call each event trigger. */ foreach(lc, fn_oid_list) { + LOCAL_FCINFO(fcinfo, 0); Oid fnoid = lfirst_oid(lc); FmgrInfo flinfo; - FunctionCallInfoData fcinfo; PgStat_FunctionCallUsage fcusage; elog(DEBUG1, "EventTriggerInvoke %u", fnoid); @@ -1048,10 +1076,10 @@ EventTriggerInvoke(List *fn_oid_list, EventTriggerData *trigdata) fmgr_info(fnoid, &flinfo); /* Call the function, passing no arguments but setting a context. */ - InitFunctionCallInfoData(fcinfo, &flinfo, 0, + InitFunctionCallInfoData(*fcinfo, &flinfo, 0, InvalidOid, (Node *) trigdata, NULL); - pgstat_init_function_usage(&fcinfo, &fcusage); - FunctionCallInvoke(&fcinfo); + pgstat_init_function_usage(fcinfo, &fcusage); + FunctionCallInvoke(fcinfo); pgstat_end_function_usage(&fcusage, true); /* Reclaim memory. */ @@ -1334,8 +1362,10 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no Relation catalog; HeapTuple tuple; - catalog = heap_open(obj->address.classId, AccessShareLock); - tuple = get_catalog_object_by_oid(catalog, obj->address.objectId); + catalog = table_open(obj->address.classId, AccessShareLock); + tuple = get_catalog_object_by_oid(catalog, + get_object_attnum_oid(object->classId), + obj->address.objectId); if (tuple) { @@ -1362,7 +1392,7 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no else if (isAnyTempNamespace(namespaceId)) { pfree(obj); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); MemoryContextSwitchTo(oldcxt); return; } @@ -1388,7 +1418,7 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no } } - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); } else { @@ -1674,11 +1704,6 @@ EventTriggerCollectSimpleCommand(ObjectAddress address, * Note we don't collect the command immediately; instead we keep it in * currentCommand, and only when we're done processing the subcommands we will * add it to the command list. - * - * XXX -- this API isn't considering the possibility of an ALTER TABLE command - * being called reentrantly by an event trigger function. Do we need stackable - * commands at this level? Perhaps at least we should detect the condition and - * raise an error. */ void EventTriggerAlterTableStart(Node *parsetree) @@ -1703,6 +1728,7 @@ EventTriggerAlterTableStart(Node *parsetree) command->d.alterTable.subcmds = NIL; command->parsetree = copyObject(parsetree); + command->parent = currentEventTriggerState->currentCommand; currentEventTriggerState->currentCommand = command; MemoryContextSwitchTo(oldcxt); @@ -1743,6 +1769,7 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address) return; Assert(IsA(subcmd, AlterTableCmd)); + Assert(currentEventTriggerState->currentCommand != NULL); Assert(OidIsValid(currentEventTriggerState->currentCommand->d.alterTable.objectId)); oldcxt = MemoryContextSwitchTo(currentEventTriggerState->cxt); @@ -1768,11 +1795,15 @@ EventTriggerCollectAlterTableSubcmd(Node *subcmd, ObjectAddress address) void EventTriggerAlterTableEnd(void) { + CollectedCommand *parent; + /* ignore if event trigger context not set, or collection disabled */ if (!currentEventTriggerState || currentEventTriggerState->commandCollectionInhibited) return; + parent = currentEventTriggerState->currentCommand->parent; + /* If no subcommands, don't collect */ if (list_length(currentEventTriggerState->currentCommand->d.alterTable.subcmds) != 0) { @@ -1783,7 +1814,7 @@ EventTriggerAlterTableEnd(void) else pfree(currentEventTriggerState->currentCommand); - currentEventTriggerState->currentCommand = NULL; + currentEventTriggerState->currentCommand = parent; } /* @@ -2081,8 +2112,9 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS) Oid schema_oid; bool isnull; - catalog = heap_open(addr.classId, AccessShareLock); + catalog = table_open(addr.classId, AccessShareLock); objtup = get_catalog_object_by_oid(catalog, + get_object_attnum_oid(addr.classId), addr.objectId); if (!HeapTupleIsValid(objtup)) elog(ERROR, "cache lookup failed for object %u/%u", @@ -2100,7 +2132,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS) else schema = get_namespace_name(schema_oid); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); } } @@ -2162,7 +2194,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS) "GRANT" : "REVOKE"); /* object_type */ values[i++] = CStringGetTextDatum(stringify_grant_objtype( - cmd->d.grant.istmt->objtype)); + cmd->d.grant.istmt->objtype)); /* schema */ nulls[i++] = true; /* identity */ @@ -2222,7 +2254,7 @@ stringify_grant_objtype(ObjectType objtype) return "TABLESPACE"; case OBJECT_TYPE: return "TYPE"; - /* these currently aren't used */ + /* these currently aren't used */ case OBJECT_ACCESS_METHOD: case OBJECT_AGGREGATE: case OBJECT_AMOP: @@ -2304,7 +2336,7 @@ stringify_adefprivs_objtype(ObjectType objtype) return "TABLESPACES"; case OBJECT_TYPE: return "TYPES"; - /* these currently aren't used */ + /* these currently aren't used */ case OBJECT_ACCESS_METHOD: case OBJECT_AGGREGATE: case OBJECT_AMOP: diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 989b6aad67b..62fb3434a32 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -3,7 +3,7 @@ * explain.c * Explain query execution plans * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * IDENTIFICATION @@ -14,7 +14,6 @@ #include "postgres.h" #include "access/xact.h" -#include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "commands/createas.h" #include "commands/defrem.h" @@ -23,14 +22,14 @@ #include "foreign/fdwapi.h" #include "jit/jit.h" #include "nodes/extensible.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/planmain.h" #include "parser/parsetree.h" #include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" #include "tcop/tcopprot.h" #include "utils/builtins.h" +#include "utils/guc_tables.h" #include "utils/json.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -55,79 +54,79 @@ explain_get_index_name_hook_type explain_get_index_name_hook = NULL; #define X_NOWHITESPACE 4 static void ExplainOneQuery(Query *query, int cursorOptions, - IntoClause *into, ExplainState *es, - const char *queryString, ParamListInfo params, - QueryEnvironment *queryEnv); + IntoClause *into, ExplainState *es, + const char *queryString, ParamListInfo params, + QueryEnvironment *queryEnv); static void report_triggers(ResultRelInfo *rInfo, bool show_relname, - ExplainState *es); + ExplainState *es); static double elapsed_time(instr_time *starttime); static bool ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used); static void ExplainNode(PlanState *planstate, List *ancestors, - const char *relationship, const char *plan_name, - ExplainState *es); + const char *relationship, const char *plan_name, + ExplainState *es); static void show_plan_tlist(PlanState *planstate, List *ancestors, - ExplainState *es); + ExplainState *es); static void show_expression(Node *node, const char *qlabel, - PlanState *planstate, List *ancestors, - bool useprefix, ExplainState *es); + PlanState *planstate, List *ancestors, + bool useprefix, ExplainState *es); static void show_qual(List *qual, const char *qlabel, - PlanState *planstate, List *ancestors, - bool useprefix, ExplainState *es); + PlanState *planstate, List *ancestors, + bool useprefix, ExplainState *es); static void show_scan_qual(List *qual, const char *qlabel, - PlanState *planstate, List *ancestors, - ExplainState *es); + PlanState *planstate, List *ancestors, + ExplainState *es); static void show_upper_qual(List *qual, const char *qlabel, - PlanState *planstate, List *ancestors, - ExplainState *es); + PlanState *planstate, List *ancestors, + ExplainState *es); static void show_sort_keys(SortState *sortstate, List *ancestors, - ExplainState *es); + ExplainState *es); static void show_merge_append_keys(MergeAppendState *mstate, List *ancestors, - ExplainState *es); + ExplainState *es); static void show_agg_keys(AggState *astate, List *ancestors, - ExplainState *es); + ExplainState *es); static void show_grouping_sets(PlanState *planstate, Agg *agg, - List *ancestors, ExplainState *es); + List *ancestors, ExplainState *es); static void show_grouping_set_keys(PlanState *planstate, - Agg *aggnode, Sort *sortnode, - List *context, bool useprefix, - List *ancestors, ExplainState *es); + Agg *aggnode, Sort *sortnode, + List *context, bool useprefix, + List *ancestors, ExplainState *es); static void show_group_keys(GroupState *gstate, List *ancestors, - ExplainState *es); + ExplainState *es); static void show_sort_group_keys(PlanState *planstate, const char *qlabel, - int nkeys, AttrNumber *keycols, - Oid *sortOperators, Oid *collations, bool *nullsFirst, - List *ancestors, ExplainState *es); + int nkeys, AttrNumber *keycols, + Oid *sortOperators, Oid *collations, bool *nullsFirst, + List *ancestors, ExplainState *es); static void show_sortorder_options(StringInfo buf, Node *sortexpr, - Oid sortOperator, Oid collation, bool nullsFirst); + Oid sortOperator, Oid collation, bool nullsFirst); static void show_tablesample(TableSampleClause *tsc, PlanState *planstate, - List *ancestors, ExplainState *es); + List *ancestors, ExplainState *es); static void show_sort_info(SortState *sortstate, ExplainState *es); static void show_hash_info(HashState *hashstate, ExplainState *es); static void show_tidbitmap_info(BitmapHeapScanState *planstate, - ExplainState *es); + ExplainState *es); static void show_instrumentation_count(const char *qlabel, int which, - PlanState *planstate, ExplainState *es); + PlanState *planstate, ExplainState *es); static void show_foreignscan_info(ForeignScanState *fsstate, ExplainState *es); static void show_eval_params(Bitmapset *bms_params, ExplainState *es); static const char *explain_get_index_name(Oid indexId); static void show_buffer_usage(ExplainState *es, const BufferUsage *usage); static void ExplainIndexScanDetails(Oid indexid, ScanDirection indexorderdir, - ExplainState *es); + ExplainState *es); static void ExplainScanTarget(Scan *plan, ExplainState *es); static void ExplainModifyTarget(ModifyTable *plan, ExplainState *es); static void ExplainTargetRel(Plan *plan, Index rti, ExplainState *es); static void show_modifytable_info(ModifyTableState *mtstate, List *ancestors, - ExplainState *es); + ExplainState *es); static void ExplainMemberNodes(PlanState **planstates, int nsubnodes, - int nplans, List *ancestors, ExplainState *es); + int nplans, List *ancestors, ExplainState *es); static void ExplainSubPlans(List *plans, List *ancestors, - const char *relationship, ExplainState *es); + const char *relationship, ExplainState *es); static void ExplainCustomChildren(CustomScanState *css, - List *ancestors, ExplainState *es); + List *ancestors, ExplainState *es); static void ExplainProperty(const char *qlabel, const char *unit, - const char *value, bool numeric, ExplainState *es); + const char *value, bool numeric, ExplainState *es); static void ExplainDummyGroup(const char *objtype, const char *labelname, - ExplainState *es); + ExplainState *es); static void ExplainXMLTag(const char *tagname, int flags, ExplainState *es); static void ExplainJSONLineEnding(ExplainState *es); static void ExplainYAMLLineStarting(ExplainState *es); @@ -164,6 +163,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, es->costs = defGetBoolean(opt); else if (strcmp(opt->defname, "buffers") == 0) es->buffers = defGetBoolean(opt); + else if (strcmp(opt->defname, "settings") == 0) + es->settings = defGetBoolean(opt); else if (strcmp(opt->defname, "timing") == 0) { timing_set = true; @@ -256,7 +257,7 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, queryString, params, queryEnv); /* Separate plans with an appropriate separator */ - if (lnext(l) != NULL) + if (lnext(rewritten, l) != NULL) ExplainSeparatePlans(es); } } @@ -266,7 +267,8 @@ ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, Assert(es->indent == 0); /* output tuples */ - tstate = begin_tup_output_tupdesc(dest, ExplainResultDesc(stmt)); + tstate = begin_tup_output_tupdesc(dest, ExplainResultDesc(stmt), + &TTSOpsVirtual); if (es->format == EXPLAIN_FORMAT_TEXT) do_text_output_multiline(tstate, es->str->data); else @@ -323,7 +325,7 @@ ExplainResultDesc(ExplainStmt *stmt) } /* Need a tuple descriptor representing a single TEXT or XML column */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN", result_type, -1, 0); return tupdesc; @@ -563,9 +565,8 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, * depending on build options. Might want to separate that out from COSTS * at a later stage. */ - if (queryDesc->estate->es_jit && es->costs && - queryDesc->estate->es_jit->created_functions > 0) - ExplainPrintJIT(es, queryDesc); + if (es->costs) + ExplainPrintJITSummary(es, queryDesc); /* * Close down the query and free resources. Include time for this in the @@ -598,6 +599,73 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, ExplainCloseGroup("Query", NULL, true, es); } +/* + * ExplainPrintSettings - + * Print summary of modified settings affecting query planning. + */ +static void +ExplainPrintSettings(ExplainState *es) +{ + int num; + struct config_generic **gucs; + + /* bail out if information about settings not requested */ + if (!es->settings) + return; + + /* request an array of relevant settings */ + gucs = get_explain_guc_options(&num); + + /* also bail out of there are no options */ + if (!num) + return; + + if (es->format != EXPLAIN_FORMAT_TEXT) + { + int i; + + ExplainOpenGroup("Settings", "Settings", true, es); + + for (i = 0; i < num; i++) + { + char *setting; + struct config_generic *conf = gucs[i]; + + setting = GetConfigOptionByName(conf->name, NULL, true); + + ExplainPropertyText(conf->name, setting, es); + } + + ExplainCloseGroup("Settings", "Settings", true, es); + } + else + { + int i; + StringInfoData str; + + initStringInfo(&str); + + for (i = 0; i < num; i++) + { + char *setting; + struct config_generic *conf = gucs[i]; + + if (i > 0) + appendStringInfoString(&str, ", "); + + setting = GetConfigOptionByName(conf->name, NULL, true); + + if (setting) + appendStringInfo(&str, "%s = '%s'", conf->name, setting); + else + appendStringInfo(&str, "%s = NULL", conf->name); + } + + if (num > 0) + ExplainPropertyText("Settings", str.data, es); + } +} + /* * ExplainPrintPlan - * convert a QueryDesc's plan tree to text and append it to es->str @@ -635,6 +703,12 @@ ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc) if (IsA(ps, GatherState) &&((Gather *) ps->plan)->invisible) ps = outerPlanState(ps); ExplainNode(ps, NIL, NULL, NULL, es); + + /* + * If requested, include information about GUC parameters with values that + * don't match the built-in defaults. + */ + ExplainPrintSettings(es); } /* @@ -688,52 +762,129 @@ ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc) ExplainCloseGroup("Triggers", "Triggers", false, es); } +/* + * ExplainPrintJITSummary - + * Print summarized JIT instrumentation from leader and workers + */ +void +ExplainPrintJITSummary(ExplainState *es, QueryDesc *queryDesc) +{ + JitInstrumentation ji = {0}; + + if (!(queryDesc->estate->es_jit_flags & PGJIT_PERFORM)) + return; + + /* + * Work with a copy instead of modifying the leader state, since this + * function may be called twice + */ + if (queryDesc->estate->es_jit) + InstrJitAgg(&ji, &queryDesc->estate->es_jit->instr); + + /* If this process has done JIT in parallel workers, merge stats */ + if (queryDesc->estate->es_jit_worker_instr) + InstrJitAgg(&ji, queryDesc->estate->es_jit_worker_instr); + + ExplainPrintJIT(es, queryDesc->estate->es_jit_flags, &ji, -1); +} + /* * ExplainPrintJIT - * Append information about JITing to es->str. + * + * Can be used to print the JIT instrumentation of the backend (worker_num = + * -1) or that of a specific worker (worker_num = ...). */ void -ExplainPrintJIT(ExplainState *es, QueryDesc *queryDesc) +ExplainPrintJIT(ExplainState *es, int jit_flags, + JitInstrumentation *ji, int worker_num) { - JitContext *jc = queryDesc->estate->es_jit; + instr_time total_time; + bool for_workers = (worker_num >= 0); + + /* don't print information if no JITing happened */ + if (!ji || ji->created_functions == 0) + return; + + /* calculate total time */ + INSTR_TIME_SET_ZERO(total_time); + INSTR_TIME_ADD(total_time, ji->generation_counter); + INSTR_TIME_ADD(total_time, ji->inlining_counter); + INSTR_TIME_ADD(total_time, ji->optimization_counter); + INSTR_TIME_ADD(total_time, ji->emission_counter); ExplainOpenGroup("JIT", "JIT", true, es); + /* for higher density, open code the text output format */ if (es->format == EXPLAIN_FORMAT_TEXT) { + appendStringInfoSpaces(es->str, es->indent * 2); + if (for_workers) + appendStringInfo(es->str, "JIT for worker %u:\n", worker_num); + else + appendStringInfoString(es->str, "JIT:\n"); es->indent += 1; - appendStringInfo(es->str, "JIT:\n"); - } - ExplainPropertyInteger("Functions", NULL, jc->created_functions, es); - if (es->analyze && es->timing) - ExplainPropertyFloat("Generation Time", "ms", - 1000.0 * INSTR_TIME_GET_DOUBLE(jc->generation_counter), - 3, es); + ExplainPropertyInteger("Functions", NULL, ji->created_functions, es); - ExplainPropertyBool("Inlining", jc->flags & PGJIT_INLINE, es); + appendStringInfoSpaces(es->str, es->indent * 2); + appendStringInfo(es->str, "Options: %s %s, %s %s, %s %s, %s %s\n", + "Inlining", jit_flags & PGJIT_INLINE ? "true" : "false", + "Optimization", jit_flags & PGJIT_OPT3 ? "true" : "false", + "Expressions", jit_flags & PGJIT_EXPR ? "true" : "false", + "Deforming", jit_flags & PGJIT_DEFORM ? "true" : "false"); - if (es->analyze && es->timing) - ExplainPropertyFloat("Inlining Time", "ms", - 1000.0 * INSTR_TIME_GET_DOUBLE(jc->inlining_counter), - 3, es); + if (es->analyze && es->timing) + { + appendStringInfoSpaces(es->str, es->indent * 2); + appendStringInfo(es->str, + "Timing: %s %.3f ms, %s %.3f ms, %s %.3f ms, %s %.3f ms, %s %.3f ms\n", + "Generation", 1000.0 * INSTR_TIME_GET_DOUBLE(ji->generation_counter), + "Inlining", 1000.0 * INSTR_TIME_GET_DOUBLE(ji->inlining_counter), + "Optimization", 1000.0 * INSTR_TIME_GET_DOUBLE(ji->optimization_counter), + "Emission", 1000.0 * INSTR_TIME_GET_DOUBLE(ji->emission_counter), + "Total", 1000.0 * INSTR_TIME_GET_DOUBLE(total_time)); + } - ExplainPropertyBool("Optimization", jc->flags & PGJIT_OPT3, es); - if (es->analyze && es->timing) - ExplainPropertyFloat("Optimization Time", "ms", - 1000.0 * INSTR_TIME_GET_DOUBLE(jc->optimization_counter), - 3, es); + es->indent -= 1; + } + else + { + ExplainPropertyInteger("Worker Number", NULL, worker_num, es); + ExplainPropertyInteger("Functions", NULL, ji->created_functions, es); - if (es->analyze && es->timing) - ExplainPropertyFloat("Emission Time", "ms", - 1000.0 * INSTR_TIME_GET_DOUBLE(jc->emission_counter), - 3, es); + ExplainOpenGroup("Options", "Options", true, es); + ExplainPropertyBool("Inlining", jit_flags & PGJIT_INLINE, es); + ExplainPropertyBool("Optimization", jit_flags & PGJIT_OPT3, es); + ExplainPropertyBool("Expressions", jit_flags & PGJIT_EXPR, es); + ExplainPropertyBool("Deforming", jit_flags & PGJIT_DEFORM, es); + ExplainCloseGroup("Options", "Options", true, es); - ExplainCloseGroup("JIT", "JIT", true, es); - if (es->format == EXPLAIN_FORMAT_TEXT) - { - es->indent -= 1; + if (es->analyze && es->timing) + { + ExplainOpenGroup("Timing", "Timing", true, es); + + ExplainPropertyFloat("Generation", "ms", + 1000.0 * INSTR_TIME_GET_DOUBLE(ji->generation_counter), + 3, es); + ExplainPropertyFloat("Inlining", "ms", + 1000.0 * INSTR_TIME_GET_DOUBLE(ji->inlining_counter), + 3, es); + ExplainPropertyFloat("Optimization", "ms", + 1000.0 * INSTR_TIME_GET_DOUBLE(ji->optimization_counter), + 3, es); + ExplainPropertyFloat("Emission", "ms", + 1000.0 * INSTR_TIME_GET_DOUBLE(ji->emission_counter), + 3, es); + ExplainPropertyFloat("Total", "ms", + 1000.0 * INSTR_TIME_GET_DOUBLE(total_time), + 3, es); + + ExplainCloseGroup("Timing", "Timing", true, es); + } } + + ExplainCloseGroup("JIT", "JIT", true, es); } /* @@ -946,9 +1097,6 @@ ExplainNode(PlanState *planstate, List *ancestors, case CMD_DELETE: pname = operation = "Delete"; break; - case CMD_MERGE: - pname = operation = "Merge"; - break; default: pname = "???"; break; @@ -1459,12 +1607,8 @@ ExplainNode(PlanState *planstate, List *ancestors, show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); if (es->analyze) - { - long heapFetches = - ((IndexOnlyScanState *) planstate)->ioss_HeapFetches; - - ExplainPropertyInteger("Heap Fetches", NULL, heapFetches, es); - } + ExplainPropertyFloat("Heap Fetches", NULL, + planstate->instrument->ntuples2, 0, es); break; case T_BitmapIndexScan: show_scan_qual(((BitmapIndexScan *) plan)->indexqualorig, @@ -1486,7 +1630,8 @@ ExplainNode(PlanState *planstate, List *ancestors, case T_SampleScan: show_tablesample(((SampleScan *) plan)->tablesample, planstate, ancestors, es); - /* FALL THRU to print additional fields the same as SeqScan */ + /* fall through to print additional fields the same as SeqScan */ + /* FALLTHROUGH */ case T_SeqScan: case T_ValuesScan: case T_CteScan: @@ -1521,6 +1666,25 @@ ExplainNode(PlanState *planstate, List *ancestors, ExplainPropertyInteger("Workers Launched", NULL, nworkers, es); } + + /* + * Print per-worker Jit instrumentation. Use same conditions + * as for the leader's JIT instrumentation, see comment there. + */ + if (es->costs && es->verbose && + outerPlanState(planstate)->worker_jit_instrument) + { + PlanState *child = outerPlanState(planstate); + int n; + SharedJitInstrumentation *w = child->worker_jit_instrument; + + for (n = 0; n < w->num_workers; ++n) + { + ExplainPrintJIT(es, child->state->es_jit_flags, + &w->jit_instr[n], n); + } + } + if (gather->single_copy || es->format != EXPLAIN_FORMAT_TEXT) ExplainPropertyBool("Single Copy", gather->single_copy, es); } @@ -2257,11 +2421,13 @@ show_sortorder_options(StringInfo buf, Node *sortexpr, TYPECACHE_LT_OPR | TYPECACHE_GT_OPR); /* - * Print COLLATE if it's not default. There are some cases where this is - * redundant, eg if expression is a column whose declared collation is - * that collation, but it's hard to distinguish that here. + * Print COLLATE if it's not default for the column's type. There are + * some cases where this is redundant, eg if expression is a column whose + * declared collation is that collation, but it's hard to distinguish that + * here (and arguably, printing COLLATE explicitly is a good idea anyway + * in such cases). */ - if (OidIsValid(collation) && collation != DEFAULT_COLLATION_OID) + if (OidIsValid(collation) && collation != get_typcollation(sortcoltype)) { char *collname = get_collation_name(collation); @@ -3015,10 +3181,6 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, operation = "Delete"; foperation = "Foreign Delete"; break; - case CMD_MERGE: - operation = "Merge"; - foperation = "Foreign Merge"; - break; default: operation = "???"; foperation = "Foreign ???"; @@ -3132,7 +3294,7 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, /* count the number of source rows */ total = mtstate->mt_plans[0]->instrument->ntuples; - other_path = mtstate->ps.instrument->nfiltered2; + other_path = mtstate->ps.instrument->ntuples2; insert_path = total - other_path; ExplainPropertyFloat("Tuples Inserted", NULL, @@ -3141,32 +3303,6 @@ show_modifytable_info(ModifyTableState *mtstate, List *ancestors, other_path, 0, es); } } - else if (node->operation == CMD_MERGE) - { - /* EXPLAIN ANALYZE display of actual outcome for each tuple proposed */ - if (es->analyze && mtstate->ps.instrument) - { - double total; - double insert_path; - double update_path; - double delete_path; - double skipped_path; - - InstrEndLoop(mtstate->mt_plans[0]->instrument); - - /* count the number of source rows */ - total = mtstate->mt_plans[0]->instrument->ntuples; - insert_path = mtstate->ps.instrument->nfiltered1; - update_path = mtstate->ps.instrument->nfiltered2; - delete_path = mtstate->ps.instrument->nfiltered3; - skipped_path = total - insert_path - update_path - delete_path; - - ExplainPropertyFloat("Tuples Inserted", NULL, insert_path, 0, es); - ExplainPropertyFloat("Tuples Updated", NULL, update_path, 0, es); - ExplainPropertyFloat("Tuples Deleted", NULL, delete_path, 0, es); - ExplainPropertyFloat("Tuples Skipped", NULL, skipped_path, 0, es); - } - } if (labeltargets) ExplainCloseGroup("Target Tables", "Target Tables", false, es); @@ -3377,7 +3513,7 @@ ExplainPropertyListNested(const char *qlabel, List *data, ExplainState *es) * If "numeric" is true, the value is a number (or other value that * doesn't need quoting in JSON). * - * If unit is is non-NULL the text format will display it after the value. + * If unit is non-NULL the text format will display it after the value. * * This usually should not be invoked directly, but via one of the datatype * specific routines ExplainPropertyText, ExplainPropertyInteger, etc. diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 2e4538146d2..f7202cc9e7d 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -9,10 +9,10 @@ * dependent objects can be associated with it. An extension is created by * populating the pg_extension catalog from a "control" file. * The extension control file is parsed with the same parser we use for - * postgresql.conf and recovery.conf. An extension also has an installation - * script file, containing SQL commands to create the extension's objects. + * postgresql.conf. An extension also has an installation script file, + * containing SQL commands to create the extension's objects. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,9 +29,13 @@ #include #include +#include "access/genam.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -59,7 +63,6 @@ #include "utils/memutils.h" #include "utils/rel.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" #include "utils/varlena.h" @@ -101,27 +104,27 @@ typedef struct ExtensionVersionInfo /* Local functions */ static List *find_update_path(List *evi_list, - ExtensionVersionInfo *evi_start, - ExtensionVersionInfo *evi_target, - bool reject_indirect, - bool reinitialize); -static Oid get_required_extension(char *reqExtensionName, - char *extensionName, - char *origSchemaName, - bool cascade, - List *parents, - bool is_create); + ExtensionVersionInfo *evi_start, + ExtensionVersionInfo *evi_target, + bool reject_indirect, + bool reinitialize); +static Oid get_required_extension(char *reqExtensionName, + char *extensionName, + char *origSchemaName, + bool cascade, + List *parents, + bool is_create); static void get_available_versions_for_extension(ExtensionControlFile *pcontrol, - Tuplestorestate *tupstore, - TupleDesc tupdesc); + Tuplestorestate *tupstore, + TupleDesc tupdesc); static Datum convert_requires_to_datum(List *requires); static void ApplyExtensionUpdates(Oid extensionOid, - ExtensionControlFile *pcontrol, - const char *initialVersion, - List *updateVersions, - char *origSchemaName, - bool cascade, - bool is_create); + ExtensionControlFile *pcontrol, + const char *initialVersion, + List *updateVersions, + char *origSchemaName, + bool cascade, + bool is_create); static char *read_whole_file(const char *filename, int *length); @@ -140,7 +143,7 @@ get_extension_oid(const char *extname, bool missing_ok) HeapTuple tuple; ScanKeyData entry[1]; - rel = heap_open(ExtensionRelationId, AccessShareLock); + rel = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], Anum_pg_extension_extname, @@ -154,13 +157,13 @@ get_extension_oid(const char *extname, bool missing_ok) /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) - result = HeapTupleGetOid(tuple); + result = ((Form_pg_extension) GETSTRUCT(tuple))->oid; else result = InvalidOid; systable_endscan(scandesc); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); if (!OidIsValid(result) && !missing_ok) ereport(ERROR, @@ -185,10 +188,10 @@ get_extension_name(Oid ext_oid) HeapTuple tuple; ScanKeyData entry[1]; - rel = heap_open(ExtensionRelationId, AccessShareLock); + rel = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid)); @@ -205,7 +208,7 @@ get_extension_name(Oid ext_oid) systable_endscan(scandesc); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return result; } @@ -224,10 +227,10 @@ get_extension_schema(Oid ext_oid) HeapTuple tuple; ScanKeyData entry[1]; - rel = heap_open(ExtensionRelationId, AccessShareLock); + rel = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ext_oid)); @@ -244,7 +247,7 @@ get_extension_schema(Oid ext_oid) systable_endscan(scandesc); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return result; } @@ -683,8 +686,6 @@ read_extension_script_file(const ExtensionControlFile *control, /* * Execute given SQL string. * - * filename is used only to report errors. - * * Note: it's tempting to just use SPI to execute the string, but that does * not work very well. The really serious problem is that SPI will parse, * analyze, and plan the whole string before executing any of it; of course @@ -694,7 +695,7 @@ read_extension_script_file(const ExtensionControlFile *control, * could be very long. */ static void -execute_sql_string(const char *sql, const char *filename) +execute_sql_string(const char *sql) { List *raw_parsetree_list; DestReceiver *dest; @@ -716,9 +717,21 @@ execute_sql_string(const char *sql, const char *filename) foreach(lc1, raw_parsetree_list) { RawStmt *parsetree = lfirst_node(RawStmt, lc1); + MemoryContext per_parsetree_context, + oldcontext; List *stmt_list; ListCell *lc2; + /* + * We do the work for each parsetree in a short-lived context, to + * limit the memory used when there are many commands in the string. + */ + per_parsetree_context = + AllocSetContextCreate(CurrentMemoryContext, + "execute_sql_string per-statement context", + ALLOCSET_DEFAULT_SIZES); + oldcontext = MemoryContextSwitchTo(per_parsetree_context); + /* Be sure parser can see any DDL done so far */ CommandCounterIncrement(); @@ -771,6 +784,10 @@ execute_sql_string(const char *sql, const char *filename) PopActiveSnapshot(); } + + /* Clean up per-parsetree context. */ + MemoryContextSwitchTo(oldcontext); + MemoryContextDelete(per_parsetree_context); } /* Be sure to advance the command counter after the last script command */ @@ -900,10 +917,11 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, { const char *qSchemaName = quote_identifier(schemaName); - t_sql = DirectFunctionCall3(replace_text, - t_sql, - CStringGetTextDatum("@extschema@"), - CStringGetTextDatum(qSchemaName)); + t_sql = DirectFunctionCall3Coll(replace_text, + C_COLLATION_OID, + t_sql, + CStringGetTextDatum("@extschema@"), + CStringGetTextDatum(qSchemaName)); } /* @@ -912,16 +930,17 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control, */ if (control->module_pathname) { - t_sql = DirectFunctionCall3(replace_text, - t_sql, - CStringGetTextDatum("MODULE_PATHNAME"), - CStringGetTextDatum(control->module_pathname)); + t_sql = DirectFunctionCall3Coll(replace_text, + C_COLLATION_OID, + t_sql, + CStringGetTextDatum("MODULE_PATHNAME"), + CStringGetTextDatum(control->module_pathname)); } /* And now back to C string */ c_sql = text_to_cstring(DatumGetTextPP(t_sql)); - execute_sql_string(c_sql, filename); + execute_sql_string(c_sql); } PG_CATCH(); { @@ -1474,6 +1493,13 @@ CreateExtensionInternal(char *extensionName, list_free(search_path); } + /* + * Make note if a temporary namespace has been accessed in this + * transaction. + */ + if (isTempNamespace(schemaOid)) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + /* * We don't check creation rights on the target namespace here. If the * extension script actually creates any objects there, it will fail if @@ -1755,11 +1781,14 @@ InsertExtensionTuple(const char *extName, Oid extOwner, /* * Build and insert the pg_extension tuple */ - rel = heap_open(ExtensionRelationId, RowExclusiveLock); + rel = table_open(ExtensionRelationId, RowExclusiveLock); memset(values, 0, sizeof(values)); memset(nulls, 0, sizeof(nulls)); + extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId, + Anum_pg_extension_oid); + values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid); values[Anum_pg_extension_extname - 1] = DirectFunctionCall1(namein, CStringGetDatum(extName)); values[Anum_pg_extension_extowner - 1] = ObjectIdGetDatum(extOwner); @@ -1779,10 +1808,10 @@ InsertExtensionTuple(const char *extName, Oid extOwner, tuple = heap_form_tuple(rel->rd_att, values, nulls); - extensionOid = CatalogTupleInsert(rel, tuple); + CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); /* * Record dependencies on owner, schema, and prerequisite extensions @@ -1847,10 +1876,10 @@ RemoveExtensionById(Oid extId) errmsg("cannot drop extension \"%s\" because it is being modified", get_extension_name(extId)))); - rel = heap_open(ExtensionRelationId, RowExclusiveLock); + rel = table_open(ExtensionRelationId, RowExclusiveLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extId)); scandesc = systable_beginscan(rel, ExtensionOidIndexId, true, @@ -1864,7 +1893,7 @@ RemoveExtensionById(Oid extId) systable_endscan(scandesc); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -2346,8 +2375,8 @@ pg_extension_config_dump(PG_FUNCTION_ARGS) if (!creating_extension) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("pg_extension_config_dump() can only be called " - "from an SQL script executed by CREATE EXTENSION"))); + errmsg("%s can only be called from an SQL script executed by CREATE EXTENSION", + "pg_extension_config_dump()"))); /* * Check that the table exists and is a member of the extension being @@ -2375,10 +2404,10 @@ pg_extension_config_dump(PG_FUNCTION_ARGS) */ /* Find the pg_extension tuple */ - extRel = heap_open(ExtensionRelationId, RowExclusiveLock); + extRel = table_open(ExtensionRelationId, RowExclusiveLock); ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(CurrentExtensionObject)); @@ -2494,7 +2523,7 @@ pg_extension_config_dump(PG_FUNCTION_ARGS) systable_endscan(extScan); - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); PG_RETURN_VOID(); } @@ -2523,10 +2552,10 @@ extension_config_remove(Oid extensionoid, Oid tableoid) ArrayType *a; /* Find the pg_extension tuple */ - extRel = heap_open(ExtensionRelationId, RowExclusiveLock); + extRel = table_open(ExtensionRelationId, RowExclusiveLock); ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extensionoid)); @@ -2581,7 +2610,7 @@ extension_config_remove(Oid extensionoid, Oid tableoid) if (arrayIndex < 0) { systable_endscan(extScan); - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); return; } @@ -2599,14 +2628,13 @@ extension_config_remove(Oid extensionoid, Oid tableoid) { /* squeeze out the target element */ Datum *dvalues; - bool *dnulls; int nelems; int i; + /* We already checked there are no nulls */ deconstruct_array(a, OIDOID, sizeof(Oid), true, 'i', - &dvalues, &dnulls, &nelems); + &dvalues, NULL, &nelems); - /* We already checked there are no nulls, so ignore dnulls */ for (i = arrayIndex; i < arrayLength - 1; i++) dvalues[i] = dvalues[i + 1]; @@ -2646,14 +2674,13 @@ extension_config_remove(Oid extensionoid, Oid tableoid) { /* squeeze out the target element */ Datum *dvalues; - bool *dnulls; int nelems; int i; + /* We already checked there are no nulls */ deconstruct_array(a, TEXTOID, -1, false, 'i', - &dvalues, &dnulls, &nelems); + &dvalues, NULL, &nelems); - /* We already checked there are no nulls, so ignore dnulls */ for (i = arrayIndex; i < arrayLength - 1; i++) dvalues[i] = dvalues[i + 1]; @@ -2671,7 +2698,7 @@ extension_config_remove(Oid extensionoid, Oid tableoid) systable_endscan(extScan); - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); } /* @@ -2724,10 +2751,10 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o extensionName, newschema))); /* Locate the pg_extension tuple */ - extRel = heap_open(ExtensionRelationId, RowExclusiveLock); + extRel = table_open(ExtensionRelationId, RowExclusiveLock); ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extensionOid)); @@ -2752,7 +2779,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o */ if (extForm->extnamespace == nspOid) { - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); return InvalidObjectAddress; } @@ -2769,7 +2796,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o * Scan pg_depend to find objects that depend directly on the extension, * and alter each one's schema. */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -2843,7 +2870,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o CatalogTupleUpdate(extRel, &extTup->t_self, extTup); - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); /* update dependencies to point to the new schema */ changeDependencyFor(ExtensionRelationId, extensionOid, @@ -2889,7 +2916,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt) /* * Look up the extension --- it must already exist in pg_extension */ - extRel = heap_open(ExtensionRelationId, AccessShareLock); + extRel = table_open(ExtensionRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_extension_extname, @@ -2907,7 +2934,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt) errmsg("extension \"%s\" does not exist", stmt->extname))); - extensionOid = HeapTupleGetOid(extTup); + extensionOid = ((Form_pg_extension) GETSTRUCT(extTup))->oid; /* * Determine the existing version we are updating from @@ -2920,7 +2947,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt) systable_endscan(extScan); - heap_close(extRel, AccessShareLock); + table_close(extRel, AccessShareLock); /* Permission check: must own extension */ if (!pg_extension_ownercheck(extensionOid, GetUserId())) @@ -3046,10 +3073,10 @@ ApplyExtensionUpdates(Oid extensionOid, control = read_extension_aux_control_file(pcontrol, versionName); /* Find the pg_extension tuple */ - extRel = heap_open(ExtensionRelationId, RowExclusiveLock); + extRel = table_open(ExtensionRelationId, RowExclusiveLock); ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_extension_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(extensionOid)); @@ -3091,7 +3118,7 @@ ApplyExtensionUpdates(Oid extensionOid, systable_endscan(extScan); - heap_close(extRel, RowExclusiveLock); + table_close(extRel, RowExclusiveLock); /* * Look up the prerequisite extensions for this version, install them diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 5c53aeeaeb6..f96c278a6a1 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -3,7 +3,7 @@ * foreigncmds.c * foreign-data wrapper/server creation/manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -13,10 +13,11 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/reloptions.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -119,11 +120,10 @@ transformGenericOptions(Oid catalogId, { DefElem *od = lfirst(optcell); ListCell *cell; - ListCell *prev = NULL; /* * Find the element in resultOptions. We need this for validation in - * all cases. Also identify the previous element. + * all cases. */ foreach(cell, resultOptions) { @@ -131,8 +131,6 @@ transformGenericOptions(Oid catalogId, if (strcmp(def->defname, od->defname) == 0) break; - else - prev = cell; } /* @@ -149,7 +147,7 @@ transformGenericOptions(Oid catalogId, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("option \"%s\" not found", od->defname))); - resultOptions = list_delete_cell(resultOptions, cell, prev); + resultOptions = list_delete_cell(resultOptions, cell); break; case DEFELEM_SET: @@ -260,12 +258,12 @@ AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerI /* Update owner dependency reference */ changeDependencyOnOwner(ForeignDataWrapperRelationId, - HeapTupleGetOid(tup), + form->oid, newOwnerId); } InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, - HeapTupleGetOid(tup), 0); + form->oid, 0); } /* @@ -280,8 +278,10 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId) HeapTuple tup; Relation rel; ObjectAddress address; + Form_pg_foreign_data_wrapper form; + - rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name)); @@ -290,7 +290,8 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("foreign-data wrapper \"%s\" does not exist", name))); - fdwId = HeapTupleGetOid(tup); + form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup); + fdwId = form->oid; AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId); @@ -298,7 +299,7 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -314,7 +315,7 @@ AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId)); @@ -327,7 +328,7 @@ AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -354,7 +355,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) Oid srvId; AclResult aclresult; - srvId = HeapTupleGetOid(tup); + srvId = form->oid; /* Must be owner */ if (!pg_foreign_server_ownercheck(srvId, GetUserId())) @@ -399,12 +400,12 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) CatalogTupleUpdate(rel, &tup->t_self, tup); /* Update owner dependency reference */ - changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup), + changeDependencyOnOwner(ForeignServerRelationId, form->oid, newOwnerId); } InvokeObjectPostAlterHook(ForeignServerRelationId, - HeapTupleGetOid(tup), 0); + form->oid, 0); } /* @@ -417,8 +418,9 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId) HeapTuple tup; Relation rel; ObjectAddress address; + Form_pg_foreign_server form; - rel = heap_open(ForeignServerRelationId, RowExclusiveLock); + rel = table_open(ForeignServerRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name)); @@ -427,7 +429,8 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("server \"%s\" does not exist", name))); - servOid = HeapTupleGetOid(tup); + form = (Form_pg_foreign_server) GETSTRUCT(tup); + servOid = form->oid; AlterForeignServerOwner_internal(rel, tup, newOwnerId); @@ -435,7 +438,7 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -449,7 +452,7 @@ AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(ForeignServerRelationId, RowExclusiveLock); + rel = table_open(ForeignServerRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId)); @@ -462,7 +465,7 @@ AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -573,7 +576,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) ObjectAddress myself; ObjectAddress referenced; - rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); /* Must be super user */ if (!superuser()) @@ -601,6 +604,9 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId, + Anum_pg_foreign_data_wrapper_oid); + values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId); values[Anum_pg_foreign_data_wrapper_fdwname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname)); values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId); @@ -627,7 +633,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) tuple = heap_form_tuple(rel->rd_att, values, nulls); - fdwId = CatalogTupleInsert(rel, tuple); + CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); @@ -660,7 +666,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt) /* Post creation hook for new foreign data wrapper */ InvokeObjectPostCreateHook(ForeignDataWrapperRelationId, fdwId, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -687,7 +693,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) Oid fdwvalidator; ObjectAddress myself; - rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); /* Must be super user */ if (!superuser()) @@ -706,7 +712,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) errmsg("foreign-data wrapper \"%s\" does not exist", stmt->fdwname))); fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp); - fdwId = HeapTupleGetOid(tp); + fdwId = fdwForm->oid; memset(repl_val, 0, sizeof(repl_val)); memset(repl_null, false, sizeof(repl_null)); @@ -824,7 +830,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt) InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, fdwId, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -839,7 +845,7 @@ RemoveForeignDataWrapperById(Oid fdwId) HeapTuple tp; Relation rel; - rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock); + rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock); tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwId)); @@ -850,7 +856,7 @@ RemoveForeignDataWrapperById(Oid fdwId) ReleaseSysCache(tp); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -872,7 +878,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) ObjectAddress referenced; ForeignDataWrapper *fdw; - rel = heap_open(ForeignServerRelationId, RowExclusiveLock); + rel = table_open(ForeignServerRelationId, RowExclusiveLock); /* For now the owner cannot be specified on create. Use effective user ID. */ ownerId = GetUserId(); @@ -889,7 +895,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("server \"%s\" already exists, skipping", stmt->servername))); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return InvalidObjectAddress; } else @@ -915,6 +921,9 @@ CreateForeignServer(CreateForeignServerStmt *stmt) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId, + Anum_pg_foreign_server_oid); + values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId); values[Anum_pg_foreign_server_srvname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->servername)); values[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(ownerId); @@ -950,7 +959,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) tuple = heap_form_tuple(rel->rd_att, values, nulls); - srvId = CatalogTupleInsert(rel, tuple); + CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); @@ -972,7 +981,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt) /* Post creation hook for new foreign server */ InvokeObjectPostCreateHook(ForeignServerRelationId, srvId, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -993,7 +1002,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt) Form_pg_foreign_server srvForm; ObjectAddress address; - rel = heap_open(ForeignServerRelationId, RowExclusiveLock); + rel = table_open(ForeignServerRelationId, RowExclusiveLock); tp = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(stmt->servername)); @@ -1003,8 +1012,8 @@ AlterForeignServer(AlterForeignServerStmt *stmt) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("server \"%s\" does not exist", stmt->servername))); - srvId = HeapTupleGetOid(tp); srvForm = (Form_pg_foreign_server) GETSTRUCT(tp); + srvId = srvForm->oid; /* * Only owner or a superuser can ALTER a SERVER. @@ -1071,7 +1080,7 @@ AlterForeignServer(AlterForeignServerStmt *stmt) heap_freetuple(tp); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -1086,7 +1095,7 @@ RemoveForeignServerById(Oid srvId) HeapTuple tp; Relation rel; - rel = heap_open(ForeignServerRelationId, RowExclusiveLock); + rel = table_open(ForeignServerRelationId, RowExclusiveLock); tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId)); @@ -1097,7 +1106,7 @@ RemoveForeignServerById(Oid srvId) ReleaseSysCache(tp); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -1147,7 +1156,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt) ForeignDataWrapper *fdw; RoleSpec *role = (RoleSpec *) stmt->user; - rel = heap_open(UserMappingRelationId, RowExclusiveLock); + rel = table_open(UserMappingRelationId, RowExclusiveLock); if (role->roletype == ROLESPEC_PUBLIC) useId = ACL_ID_PUBLIC; @@ -1162,7 +1171,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt) /* * Check that the user mapping is unique within server. */ - umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, + umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid, ObjectIdGetDatum(useId), ObjectIdGetDatum(srv->serverid)); @@ -1172,17 +1181,17 @@ CreateUserMapping(CreateUserMappingStmt *stmt) { ereport(NOTICE, (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user mapping for \"%s\" already exists for server %s, skipping", + errmsg("user mapping for \"%s\" already exists for server \"%s\", skipping", MappingUserName(useId), stmt->servername))); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return InvalidObjectAddress; } else ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), - errmsg("user mapping for \"%s\" already exists for server %s", + errmsg("user mapping for \"%s\" already exists for server \"%s\"", MappingUserName(useId), stmt->servername))); } @@ -1195,6 +1204,9 @@ CreateUserMapping(CreateUserMappingStmt *stmt) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + umId = GetNewOidWithIndex(rel, UserMappingOidIndexId, + Anum_pg_user_mapping_oid); + values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId); values[Anum_pg_user_mapping_umuser - 1] = ObjectIdGetDatum(useId); values[Anum_pg_user_mapping_umserver - 1] = ObjectIdGetDatum(srv->serverid); @@ -1211,7 +1223,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt) tuple = heap_form_tuple(rel->rd_att, values, nulls); - umId = CatalogTupleInsert(rel, tuple); + CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); @@ -1231,13 +1243,17 @@ CreateUserMapping(CreateUserMappingStmt *stmt) recordDependencyOnOwner(UserMappingRelationId, umId, useId); } - /* dependency on extension */ - recordDependencyOnCurrentExtension(&myself, false); + /* + * Perhaps someday there should be a recordDependencyOnCurrentExtension + * call here; but since roles aren't members of extensions, it seems like + * user mappings shouldn't be either. Note that the grammar and pg_dump + * would need to be extended too if we change this. + */ /* Post creation hook for new user mapping */ InvokeObjectPostCreateHook(UserMappingRelationId, umId, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -1260,7 +1276,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt) ObjectAddress address; RoleSpec *role = (RoleSpec *) stmt->user; - rel = heap_open(UserMappingRelationId, RowExclusiveLock); + rel = table_open(UserMappingRelationId, RowExclusiveLock); if (role->roletype == ROLESPEC_PUBLIC) useId = ACL_ID_PUBLIC; @@ -1269,14 +1285,14 @@ AlterUserMapping(AlterUserMappingStmt *stmt) srv = GetForeignServerByName(stmt->servername, false); - umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, + umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid, ObjectIdGetDatum(useId), ObjectIdGetDatum(srv->serverid)); if (!OidIsValid(umId)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user mapping for \"%s\" does not exist for the server", - MappingUserName(useId)))); + errmsg("user mapping for \"%s\" does not exist for server \"%s\"", + MappingUserName(useId), stmt->servername))); user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername); @@ -1332,7 +1348,7 @@ AlterUserMapping(AlterUserMappingStmt *stmt) heap_freetuple(tp); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -1377,11 +1393,13 @@ RemoveUserMapping(DropUserMappingStmt *stmt) errmsg("server \"%s\" does not exist", stmt->servername))); /* IF EXISTS, just note it */ - ereport(NOTICE, (errmsg("server does not exist, skipping"))); + ereport(NOTICE, + (errmsg("server \"%s\" does not exist, skipping", + stmt->servername))); return InvalidOid; } - umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, + umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid, ObjectIdGetDatum(useId), ObjectIdGetDatum(srv->serverid)); @@ -1390,13 +1408,13 @@ RemoveUserMapping(DropUserMappingStmt *stmt) if (!stmt->missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("user mapping for \"%s\" does not exist for the server", - MappingUserName(useId)))); + errmsg("user mapping for \"%s\" does not exist for server \"%s\"", + MappingUserName(useId), stmt->servername))); /* IF EXISTS specified, just note it */ ereport(NOTICE, - (errmsg("user mapping for \"%s\" does not exist for the server, skipping", - MappingUserName(useId)))); + (errmsg("user mapping for \"%s\" does not exist for server \"%s\", skipping", + MappingUserName(useId), stmt->servername))); return InvalidOid; } @@ -1424,7 +1442,7 @@ RemoveUserMappingById(Oid umId) HeapTuple tp; Relation rel; - rel = heap_open(UserMappingRelationId, RowExclusiveLock); + rel = table_open(UserMappingRelationId, RowExclusiveLock); tp = SearchSysCache1(USERMAPPINGOID, ObjectIdGetDatum(umId)); @@ -1435,7 +1453,7 @@ RemoveUserMappingById(Oid umId) ReleaseSysCache(tp); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -1463,7 +1481,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid) */ CommandCounterIncrement(); - ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock); + ftrel = table_open(ForeignTableRelationId, RowExclusiveLock); /* * For now the owner cannot be specified on create. Use effective user ID. @@ -1516,7 +1534,7 @@ CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid) referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); - heap_close(ftrel, RowExclusiveLock); + table_close(ftrel, RowExclusiveLock); } /* diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index 80cbbf94b47..40f1f9a1b6f 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -5,7 +5,7 @@ * Routines for CREATE and DROP FUNCTION commands and CREATE and DROP * CAST commands. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -33,9 +33,10 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/sysattr.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -51,13 +52,15 @@ #include "commands/proclang.h" #include "executor/execdesc.h" #include "executor/executor.h" +#include "funcapi.h" #include "miscadmin.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" #include "parser/parse_func.h" #include "parser/parse_type.h" +#include "pgstat.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -67,7 +70,6 @@ #include "utils/rel.h" #include "utils/syscache.h" #include "utils/typcache.h" -#include "utils/tqual.h" /* * Examine the RETURNS clause of the CREATE FUNCTION statement @@ -168,7 +170,7 @@ compute_return_type(TypeName *returnType, Oid languageOid, * Input parameters: * parameters: list of FunctionParameter structs * languageOid: OID of function language (InvalidOid if it's CREATE AGGREGATE) - * is_aggregate: needed only to determine error handling + * objtype: needed only to determine error handling and required result type * * Results are stored into output parameters. parameterTypes must always * be created, but the other arrays are set to NULL if not needed. @@ -304,7 +306,7 @@ interpret_function_parameter_list(ParseState *pstate, { if (objtype == OBJECT_PROCEDURE) *requiredResultType = RECORDOID; - else if (outCount == 0) /* save first output param's type */ + else if (outCount == 0) /* save first output param's type */ *requiredResultType = toid; outCount++; } @@ -477,6 +479,7 @@ compute_common_attribute(ParseState *pstate, List **set_items, DefElem **cost_item, DefElem **rows_item, + DefElem **support_item, DefElem **parallel_item) { if (strcmp(defel->defname, "volatility") == 0) @@ -535,6 +538,15 @@ compute_common_attribute(ParseState *pstate, *rows_item = defel; } + else if (strcmp(defel->defname, "support") == 0) + { + if (is_procedure) + goto procedure_error; + if (*support_item) + goto duplicate_error; + + *support_item = defel; + } else if (strcmp(defel->defname, "parallel") == 0) { if (is_procedure) @@ -633,6 +645,45 @@ update_proconfig_value(ArrayType *a, List *set_items) return a; } +static Oid +interpret_func_support(DefElem *defel) +{ + List *procName = defGetQualifiedName(defel); + Oid procOid; + Oid argList[1]; + + /* + * Support functions always take one INTERNAL argument and return + * INTERNAL. + */ + argList[0] = INTERNALOID; + + procOid = LookupFuncName(procName, 1, argList, true); + if (!OidIsValid(procOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("function %s does not exist", + func_signature_string(procName, 1, NIL, argList)))); + + if (get_func_rettype(procOid) != INTERNALOID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("support function %s must return type %s", + NameListToString(procName), "internal"))); + + /* + * Someday we might want an ACL check here; but for now, we insist that + * you be superuser to specify a support function, so privilege on the + * support function is moot. + */ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("must be superuser to specify a support function"))); + + return procOid; +} + /* * Dissect the list of options assembled in gram.y into function @@ -653,6 +704,7 @@ compute_function_attributes(ParseState *pstate, ArrayType **proconfig, float4 *procost, float4 *prorows, + Oid *prosupport, char *parallel_p) { ListCell *option; @@ -667,6 +719,7 @@ compute_function_attributes(ParseState *pstate, List *set_items = NIL; DefElem *cost_item = NULL; DefElem *rows_item = NULL; + DefElem *support_item = NULL; DefElem *parallel_item = NULL; foreach(option, options) @@ -724,6 +777,7 @@ compute_function_attributes(ParseState *pstate, &set_items, &cost_item, &rows_item, + &support_item, ¶llel_item)) { /* recognized common option */ @@ -786,6 +840,8 @@ compute_function_attributes(ParseState *pstate, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("ROWS must be positive"))); } + if (support_item) + *prosupport = interpret_func_support(support_item); if (parallel_item) *parallel_p = interpret_func_parallel(parallel_item); } @@ -891,6 +947,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) ArrayType *proconfig; float4 procost; float4 prorows; + Oid prosupport; HeapTuple languageTuple; Form_pg_language languageStruct; List *as_clause; @@ -915,6 +972,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) proconfig = NULL; procost = -1; /* indicates not set */ prorows = -1; /* indicates not set */ + prosupport = InvalidOid; parallel = PROPARALLEL_UNSAFE; /* Extract non-default attributes from stmt->options list */ @@ -924,7 +982,8 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) &as_clause, &language, &transformDefElem, &isWindowFunc, &volatility, &isStrict, &security, &isLeakProof, - &proconfig, &procost, &prorows, ¶llel); + &proconfig, &procost, &prorows, + &prosupport, ¶llel); /* Look up the language and validate permissions */ languageTuple = SearchSysCache1(LANGNAME, PointerGetDatum(language)); @@ -933,10 +992,10 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("language \"%s\" does not exist", language), (PLTemplateExists(language) ? - errhint("Use CREATE LANGUAGE to load the language into the database.") : 0))); + errhint("Use CREATE EXTENSION to load the language into the database.") : 0))); - languageOid = HeapTupleGetOid(languageTuple); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); + languageOid = languageStruct->oid; if (languageStruct->lanpltrusted) { @@ -1111,6 +1170,7 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt) parameterDefaults, PointerGetDatum(trftypes), PointerGetDatum(proconfig), + prosupport, procost, prorows); } @@ -1131,7 +1191,7 @@ RemoveFunctionById(Oid funcOid) /* * Delete the pg_proc tuple. */ - relation = heap_open(ProcedureRelationId, RowExclusiveLock); + relation = table_open(ProcedureRelationId, RowExclusiveLock); tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1143,14 +1203,14 @@ RemoveFunctionById(Oid funcOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); /* * If there's a pg_aggregate tuple, delete that too. */ if (prokind == PROKIND_AGGREGATE) { - relation = heap_open(AggregateRelationId, RowExclusiveLock); + relation = table_open(AggregateRelationId, RowExclusiveLock); tup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(funcOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1160,7 +1220,7 @@ RemoveFunctionById(Oid funcOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } } @@ -1185,13 +1245,16 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) List *set_items = NIL; DefElem *cost_item = NULL; DefElem *rows_item = NULL; + DefElem *support_item = NULL; DefElem *parallel_item = NULL; ObjectAddress address; - rel = heap_open(ProcedureRelationId, RowExclusiveLock); + rel = table_open(ProcedureRelationId, RowExclusiveLock); funcOid = LookupFuncWithArgs(stmt->objtype, stmt->func, false); + ObjectAddressSet(address, ProcedureRelationId, funcOid); + tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for function %u", funcOid); @@ -1226,6 +1289,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) &set_items, &cost_item, &rows_item, + &support_item, ¶llel_item) == false) elog(ERROR, "option \"%s\" not recognized", defel->defname); } @@ -1264,6 +1328,28 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("ROWS is not applicable when function does not return a set"))); } + if (support_item) + { + /* interpret_func_support handles the privilege check */ + Oid newsupport = interpret_func_support(support_item); + + /* Add or replace dependency on support function */ + if (OidIsValid(procForm->prosupport)) + changeDependencyFor(ProcedureRelationId, funcOid, + ProcedureRelationId, procForm->prosupport, + newsupport); + else + { + ObjectAddress referenced; + + referenced.classId = ProcedureRelationId; + referenced.objectId = newsupport; + referenced.objectSubId = 0; + recordDependencyOn(&address, &referenced, DEPENDENCY_NORMAL); + } + + procForm->prosupport = newsupport; + } if (set_items) { Datum datum; @@ -1306,9 +1392,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt) InvokeObjectPostAlterHook(ProcedureRelationId, funcOid, 0); - ObjectAddressSet(address, ProcedureRelationId, funcOid); - - heap_close(rel, NoLock); + table_close(rel, NoLock); heap_freetuple(tup); return address; @@ -1330,7 +1414,7 @@ SetFunctionReturnType(Oid funcOid, Oid newRetType) ObjectAddress func_address; ObjectAddress type_address; - pg_proc_rel = heap_open(ProcedureRelationId, RowExclusiveLock); + pg_proc_rel = table_open(ProcedureRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1346,7 +1430,7 @@ SetFunctionReturnType(Oid funcOid, Oid newRetType) /* update the catalog and its indexes */ CatalogTupleUpdate(pg_proc_rel, &tup->t_self, tup); - heap_close(pg_proc_rel, RowExclusiveLock); + table_close(pg_proc_rel, RowExclusiveLock); /* * Also update the dependency to the new type. Opaque is a pinned type, so @@ -1372,7 +1456,7 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType) ObjectAddress func_address; ObjectAddress type_address; - pg_proc_rel = heap_open(ProcedureRelationId, RowExclusiveLock); + pg_proc_rel = table_open(ProcedureRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1389,7 +1473,7 @@ SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType) /* update the catalog and its indexes */ CatalogTupleUpdate(pg_proc_rel, &tup->t_self, tup); - heap_close(pg_proc_rel, RowExclusiveLock); + table_close(pg_proc_rel, RowExclusiveLock); /* * Also update the dependency to the new type. Opaque is a pinned type, so @@ -1647,7 +1731,7 @@ CreateCast(CreateCastStmt *stmt) break; } - relation = heap_open(CastRelationId, RowExclusiveLock); + relation = table_open(CastRelationId, RowExclusiveLock); /* * Check for duplicate. This is just to give a friendly error message, @@ -1665,6 +1749,8 @@ CreateCast(CreateCastStmt *stmt) format_type_be(targettypeid)))); /* ready to go */ + castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid); + values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid); values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid); values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid); values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid); @@ -1675,7 +1761,7 @@ CreateCast(CreateCastStmt *stmt) tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls); - castid = CatalogTupleInsert(relation, tuple); + CatalogTupleInsert(relation, tuple); /* make dependency entries */ myself.classId = CastRelationId; @@ -1711,7 +1797,7 @@ CreateCast(CreateCastStmt *stmt) heap_freetuple(tuple); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); return myself; } @@ -1727,7 +1813,7 @@ get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok) { Oid oid; - oid = GetSysCacheOid2(CASTSOURCETARGET, + oid = GetSysCacheOid2(CASTSOURCETARGET, Anum_pg_cast_oid, ObjectIdGetDatum(sourcetypeid), ObjectIdGetDatum(targettypeid)); if (!OidIsValid(oid) && !missing_ok) @@ -1747,10 +1833,10 @@ DropCastById(Oid castOid) SysScanDesc scan; HeapTuple tuple; - relation = heap_open(CastRelationId, RowExclusiveLock); + relation = table_open(CastRelationId, RowExclusiveLock); ScanKeyInit(&scankey, - ObjectIdAttributeNumber, + Anum_pg_cast_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(castOid)); scan = systable_beginscan(relation, CastOidIndexId, true, @@ -1762,7 +1848,7 @@ DropCastById(Oid castOid) CatalogTupleDelete(relation, &tuple->t_self); systable_endscan(scan); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } @@ -1915,13 +2001,15 @@ CreateTransform(CreateTransformStmt *stmt) MemSet(nulls, false, sizeof(nulls)); - relation = heap_open(TransformRelationId, RowExclusiveLock); + relation = table_open(TransformRelationId, RowExclusiveLock); tuple = SearchSysCache2(TRFTYPELANG, ObjectIdGetDatum(typeid), ObjectIdGetDatum(langid)); if (HeapTupleIsValid(tuple)) { + Form_pg_transform form = (Form_pg_transform) GETSTRUCT(tuple); + if (!stmt->replace) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), @@ -1936,14 +2024,17 @@ CreateTransform(CreateTransformStmt *stmt) newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces); CatalogTupleUpdate(relation, &newtuple->t_self, newtuple); - transformid = HeapTupleGetOid(tuple); + transformid = form->oid; ReleaseSysCache(tuple); is_replace = true; } else { + transformid = GetNewOidWithIndex(relation, TransformOidIndexId, + Anum_pg_transform_oid); + values[Anum_pg_transform_oid - 1] = ObjectIdGetDatum(transformid); newtuple = heap_form_tuple(RelationGetDescr(relation), values, nulls); - transformid = CatalogTupleInsert(relation, newtuple); + CatalogTupleInsert(relation, newtuple); is_replace = false; } @@ -1991,7 +2082,7 @@ CreateTransform(CreateTransformStmt *stmt) heap_freetuple(newtuple); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); return myself; } @@ -2008,7 +2099,7 @@ get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok) { Oid oid; - oid = GetSysCacheOid2(TRFTYPELANG, + oid = GetSysCacheOid2(TRFTYPELANG, Anum_pg_transform_oid, ObjectIdGetDatum(type_id), ObjectIdGetDatum(lang_id)); if (!OidIsValid(oid) && !missing_ok) @@ -2029,10 +2120,10 @@ DropTransformById(Oid transformOid) SysScanDesc scan; HeapTuple tuple; - relation = heap_open(TransformRelationId, RowExclusiveLock); + relation = table_open(TransformRelationId, RowExclusiveLock); ScanKeyInit(&scankey, - ObjectIdAttributeNumber, + Anum_pg_transform_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(transformOid)); scan = systable_beginscan(relation, TransformOidIndexId, true, @@ -2044,7 +2135,7 @@ DropTransformById(Oid transformOid) CatalogTupleDelete(relation, &tuple->t_self); systable_endscan(scan); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } @@ -2135,10 +2226,10 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("language \"%s\" does not exist", language), (PLTemplateExists(language) ? - errhint("Use CREATE LANGUAGE to load the language into the database.") : 0))); + errhint("Use CREATE EXTENSION to load the language into the database.") : 0))); - codeblock->langOid = HeapTupleGetOid(languageTuple); languageStruct = (Form_pg_language) GETSTRUCT(languageTuple); + codeblock->langOid = languageStruct->oid; codeblock->langIsTrusted = languageStruct->lanpltrusted; codeblock->atomic = atomic; @@ -2206,58 +2297,89 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic) void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest) { + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); ListCell *lc; FuncExpr *fexpr; int nargs; int i; AclResult aclresult; FmgrInfo flinfo; - FunctionCallInfoData fcinfo; CallContext *callcontext; EState *estate; ExprContext *econtext; HeapTuple tp; + PgStat_FunctionCallUsage fcusage; Datum retval; fexpr = stmt->funcexpr; Assert(fexpr); + Assert(IsA(fexpr, FuncExpr)); aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, OBJECT_PROCEDURE, get_func_name(fexpr->funcid)); - nargs = list_length(fexpr->args); - - /* safety check; see ExecInitFunc() */ - if (nargs > FUNC_MAX_ARGS) - ereport(ERROR, - (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg_plural("cannot pass more than %d argument to a procedure", - "cannot pass more than %d arguments to a procedure", - FUNC_MAX_ARGS, - FUNC_MAX_ARGS))); - /* Prep the context object we'll pass to the procedure */ callcontext = makeNode(CallContext); callcontext->atomic = atomic; + tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); + /* * If proconfig is set we can't allow transaction commands because of the * way the GUC stacking works: The transaction boundary would have to pop * the proconfig setting off the stack. That restriction could be lifted * by redesigning the GUC nesting mechanism a bit. */ - tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for function %u", fexpr->funcid); if (!heap_attisnull(tp, Anum_pg_proc_proconfig, NULL)) callcontext->atomic = true; + + /* + * In security definer procedures, we can't allow transaction commands. + * StartTransaction() insists that the security context stack is empty, + * and AbortTransaction() resets the security context. This could be + * reorganized, but right now it doesn't work. + */ + if (((Form_pg_proc) GETSTRUCT(tp))->prosecdef) + callcontext->atomic = true; + + /* + * Expand named arguments, defaults, etc. We do not want to scribble on + * the passed-in CallStmt parse tree, so first flat-copy fexpr, allowing + * us to replace its args field. (Note that expand_function_arguments + * will not modify any of the passed-in data structure.) + */ + { + FuncExpr *nexpr = makeNode(FuncExpr); + + memcpy(nexpr, fexpr, sizeof(FuncExpr)); + fexpr = nexpr; + } + + fexpr->args = expand_function_arguments(fexpr->args, + fexpr->funcresulttype, + tp); + nargs = list_length(fexpr->args); + ReleaseSysCache(tp); + /* safety check; see ExecInitFunc() */ + if (nargs > FUNC_MAX_ARGS) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("cannot pass more than %d argument to a procedure", + "cannot pass more than %d arguments to a procedure", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + /* Initialize function call structure */ InvokeFunctionExecuteHook(fexpr->funcid); fmgr_info(fexpr->funcid, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, nargs, fexpr->inputcollid, (Node *) callcontext, NULL); + fmgr_info_set_expr((Node *) fexpr, &flinfo); + InitFunctionCallInfoData(*fcinfo, &flinfo, nargs, fexpr->inputcollid, + (Node *) callcontext, NULL); /* * Evaluate procedure arguments inside a suitable execution context. Note @@ -2278,13 +2400,15 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver val = ExecEvalExprSwitchContext(exprstate, econtext, &isnull); - fcinfo.arg[i] = val; - fcinfo.argnull[i] = isnull; + fcinfo->args[i].value = val; + fcinfo->args[i].isnull = isnull; i++; } - retval = FunctionCallInvoke(&fcinfo); + pgstat_init_function_usage(fcinfo, &fcusage); + retval = FunctionCallInvoke(fcinfo); + pgstat_end_function_usage(&fcusage, true); if (fexpr->funcresulttype == VOIDOID) { @@ -2304,7 +2428,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver TupOutputState *tstate; TupleTableSlot *slot; - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "procedure returned null record"); td = DatumGetHeapTupleHeader(retval); @@ -2312,14 +2436,15 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver tupTypmod = HeapTupleHeaderGetTypMod(td); retdesc = lookup_rowtype_tupdesc(tupType, tupTypmod); - tstate = begin_tup_output_tupdesc(dest, retdesc); + tstate = begin_tup_output_tupdesc(dest, retdesc, + &TTSOpsHeapTuple); rettupdata.t_len = HeapTupleHeaderGetDatumLength(td); ItemPointerSetInvalid(&(rettupdata.t_self)); rettupdata.t_tableOid = InvalidOid; rettupdata.t_data = td; - slot = ExecStoreTuple(&rettupdata, tstate->slot, InvalidBuffer, false); + slot = ExecStoreHeapTuple(&rettupdata, tstate->slot, false); tstate->dest->receiveSlot(slot, tstate->dest); end_tup_output(tstate); @@ -2332,3 +2457,26 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver FreeExecutorState(estate); } + +/* + * Construct the tuple descriptor for a CALL statement return + */ +TupleDesc +CallStmtResultDesc(CallStmt *stmt) +{ + FuncExpr *fexpr; + HeapTuple tuple; + TupleDesc tupdesc; + + fexpr = stmt->funcexpr; + + tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(fexpr->funcid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for procedure %u", fexpr->funcid); + + tupdesc = build_function_result_tupdesc_t(tuple); + + ReleaseSysCache(tuple); + + return tupdesc; +} diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 860a60d1096..70f9b6729a7 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -3,7 +3,7 @@ * indexcmds.c * POSTGRES define and remove index code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,14 +16,15 @@ #include "postgres.h" #include "access/amapi.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/reloptions.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/index.h" #include "catalog/indexing.h" -#include "catalog/partition.h" #include "catalog/pg_am.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" @@ -34,55 +35,70 @@ #include "commands/comment.h" #include "commands/dbcommands.h" #include "commands/defrem.h" +#include "commands/event_trigger.h" +#include "commands/progress.h" #include "commands/tablecmds.h" #include "commands/tablespace.h" #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/planner.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_coerce.h" #include "parser/parse_func.h" #include "parser/parse_oper.h" +#include "partitioning/partdesc.h" +#include "pgstat.h" #include "rewrite/rewriteManip.h" #include "storage/lmgr.h" #include "storage/proc.h" #include "storage/procarray.h" +#include "storage/sinvaladt.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/partcache.h" +#include "utils/pg_rusage.h" #include "utils/regproc.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* non-export function prototypes */ static void CheckPredicate(Expr *predicate); static void ComputeIndexAttrs(IndexInfo *indexInfo, - Oid *typeOidP, - Oid *collationOidP, - Oid *classOidP, - int16 *colOptionP, - List *attList, - List *exclusionOpNames, - Oid relId, - const char *accessMethodName, Oid accessMethodId, - bool amcanorder, - bool isconstraint); + Oid *typeOidP, + Oid *collationOidP, + Oid *classOidP, + int16 *colOptionP, + List *attList, + List *exclusionOpNames, + Oid relId, + const char *accessMethodName, Oid accessMethodId, + bool amcanorder, + bool isconstraint); static char *ChooseIndexName(const char *tabname, Oid namespaceId, - List *colnames, List *exclusionOpNames, - bool primary, bool isconstraint); + List *colnames, List *exclusionOpNames, + bool primary, bool isconstraint); static char *ChooseIndexNameAddition(List *colnames); static List *ChooseIndexColumnNames(List *indexElems); static void RangeVarCallbackForReindexIndex(const RangeVar *relation, - Oid relId, Oid oldRelId, void *arg); + Oid relId, Oid oldRelId, void *arg); +static bool ReindexRelationConcurrently(Oid relationOid, int options); static void ReindexPartitionedIndex(Relation parentIdx); +static void update_relispartition(Oid relationId, bool newval); + +/* + * callback argument type for RangeVarCallbackForReindexIndex() + */ +struct ReindexIndexCallbackState +{ + bool concurrent; /* flag from statement */ + Oid locked_table_oid; /* tracks previously locked table */ +}; /* * CheckIndexCompatible @@ -170,8 +186,8 @@ CheckIndexCompatible(Oid oldId, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("access method \"%s\" does not exist", accessMethodName))); - accessMethodId = HeapTupleGetOid(tuple); accessMethodForm = (Form_pg_am) GETSTRUCT(tuple); + accessMethodId = accessMethodForm->oid; amRoutine = GetIndexAmRoutine(accessMethodForm->amhandler); ReleaseSysCache(tuple); @@ -186,18 +202,8 @@ CheckIndexCompatible(Oid oldId, * contains only key attributes, thus we're filling ii_NumIndexAttrs and * ii_NumIndexKeyAttrs with same value. */ - indexInfo = makeNode(IndexInfo); - indexInfo->ii_NumIndexAttrs = numberOfAttributes; - indexInfo->ii_NumIndexKeyAttrs = numberOfAttributes; - indexInfo->ii_Expressions = NIL; - indexInfo->ii_ExpressionsState = NIL; - indexInfo->ii_PredicateState = NULL; - indexInfo->ii_ExclusionOps = NULL; - indexInfo->ii_ExclusionProcs = NULL; - indexInfo->ii_ExclusionStrats = NULL; - indexInfo->ii_Am = accessMethodId; - indexInfo->ii_AmCache = NULL; - indexInfo->ii_Context = CurrentMemoryContext; + indexInfo = makeIndexInfo(numberOfAttributes, numberOfAttributes, + accessMethodId, NIL, NIL, false, false, false); typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); classObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); @@ -222,7 +228,7 @@ CheckIndexCompatible(Oid oldId, */ if (!(heap_attisnull(tuple, Anum_pg_index_indpred, NULL) && heap_attisnull(tuple, Anum_pg_index_indexprs, NULL) && - IndexIsValid(indexForm))) + indexForm->indisvalid)) { ReleaseSysCache(tuple); return false; @@ -296,6 +302,104 @@ CheckIndexCompatible(Oid oldId, return ret; } + +/* + * WaitForOlderSnapshots + * + * Wait for transactions that might have an older snapshot than the given xmin + * limit, because it might not contain tuples deleted just before it has + * been taken. Obtain a list of VXIDs of such transactions, and wait for them + * individually. This is used when building an index concurrently. + * + * We can exclude any running transactions that have xmin > the xmin given; + * their oldest snapshot must be newer than our xmin limit. + * We can also exclude any transactions that have xmin = zero, since they + * evidently have no live snapshot at all (and any one they might be in + * process of taking is certainly newer than ours). Transactions in other + * DBs can be ignored too, since they'll never even be able to see the + * index being worked on. + * + * We can also exclude autovacuum processes and processes running manual + * lazy VACUUMs, because they won't be fazed by missing index entries + * either. (Manual ANALYZEs, however, can't be excluded because they + * might be within transactions that are going to do arbitrary operations + * later.) + * + * Also, GetCurrentVirtualXIDs never reports our own vxid, so we need not + * check for that. + * + * If a process goes idle-in-transaction with xmin zero, we do not need to + * wait for it anymore, per the above argument. We do not have the + * infrastructure right now to stop waiting if that happens, but we can at + * least avoid the folly of waiting when it is idle at the time we would + * begin to wait. We do this by repeatedly rechecking the output of + * GetCurrentVirtualXIDs. If, during any iteration, a particular vxid + * doesn't show up in the output, we know we can forget about it. + */ +static void +WaitForOlderSnapshots(TransactionId limitXmin, bool progress) +{ + int n_old_snapshots; + int i; + VirtualTransactionId *old_snapshots; + + old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false, + PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, + &n_old_snapshots); + if (progress) + pgstat_progress_update_param(PROGRESS_WAITFOR_TOTAL, n_old_snapshots); + + for (i = 0; i < n_old_snapshots; i++) + { + if (!VirtualTransactionIdIsValid(old_snapshots[i])) + continue; /* found uninteresting in previous cycle */ + + if (i > 0) + { + /* see if anything's changed ... */ + VirtualTransactionId *newer_snapshots; + int n_newer_snapshots; + int j; + int k; + + newer_snapshots = GetCurrentVirtualXIDs(limitXmin, + true, false, + PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, + &n_newer_snapshots); + for (j = i; j < n_old_snapshots; j++) + { + if (!VirtualTransactionIdIsValid(old_snapshots[j])) + continue; /* found uninteresting in previous cycle */ + for (k = 0; k < n_newer_snapshots; k++) + { + if (VirtualTransactionIdEquals(old_snapshots[j], + newer_snapshots[k])) + break; + } + if (k >= n_newer_snapshots) /* not there anymore */ + SetInvalidVirtualTransactionId(old_snapshots[j]); + } + pfree(newer_snapshots); + } + + if (VirtualTransactionIdIsValid(old_snapshots[i])) + { + if (progress) + { + PGPROC *holder = BackendIdGetProc(old_snapshots[i].backendId); + + pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID, + holder->pid); + } + VirtualXactLock(old_snapshots[i], true); + } + + if (progress) + pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, i + 1); + } +} + + /* * DefineIndex * Creates a new index. @@ -325,7 +429,7 @@ DefineIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId, Oid parentIndexId, - Oid parentConstraintId, + Oid parentConstraintId, bool is_alter_table, bool check_rights, bool check_not_in_use, @@ -342,8 +446,8 @@ DefineIndex(Oid relationId, Oid tablespaceId; Oid createdConstraintId = InvalidOid; List *indexColNames; + List *allIndexParams; Relation rel; - Relation indexRelation; HeapTuple tuple; Form_pg_am accessMethodForm; IndexAmRoutine *amRoutine; @@ -358,19 +462,46 @@ DefineIndex(Oid relationId, int numberOfAttributes; int numberOfKeyAttributes; TransactionId limitXmin; - VirtualTransactionId *old_snapshots; ObjectAddress address; - int n_old_snapshots; LockRelId heaprelid; LOCKTAG heaplocktag; LOCKMODE lockmode; Snapshot snapshot; + int save_nestlevel = -1; int i; - if (list_intersection(stmt->indexParams, stmt->indexIncludingParams) != NIL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("included columns must not intersect with key columns"))); + /* + * Some callers need us to run with an empty default_tablespace; this is a + * necessary hack to be able to reproduce catalog state accurately when + * recreating indexes after table-rewriting ALTER TABLE. + */ + if (stmt->reset_default_tblspc) + { + save_nestlevel = NewGUCNestLevel(); + (void) set_config_option("default_tablespace", "", + PGC_USERSET, PGC_S_SESSION, + GUC_ACTION_SAVE, true, 0, false); + } + + /* + * Start progress report. If we're building a partition, this was already + * done. + */ + if (!OidIsValid(parentIndexId)) + { + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, + relationId); + pgstat_progress_update_param(PROGRESS_CREATEIDX_COMMAND, + stmt->concurrent ? + PROGRESS_CREATEIDX_COMMAND_CREATE_CONCURRENTLY : + PROGRESS_CREATEIDX_COMMAND_CREATE); + } + + /* + * No index OID to report yet + */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, + InvalidOid); /* * count key attributes in index @@ -378,16 +509,16 @@ DefineIndex(Oid relationId, numberOfKeyAttributes = list_length(stmt->indexParams); /* - * We append any INCLUDE columns onto the indexParams list so that we have - * one list with all columns. Later we can determine which of these are - * key columns, and which are just part of the INCLUDE list by checking - * the list position. A list item in a position less than - * ii_NumIndexKeyAttrs is part of the key columns, and anything equal to - * and over is part of the INCLUDE columns. + * Calculate the new list of index columns including both key columns and + * INCLUDE columns. Later we can determine which of these are key + * columns, and which are just part of the INCLUDE list by checking the + * list position. A list item in a position less than ii_NumIndexKeyAttrs + * is part of the key columns, and anything equal to and over is part of + * the INCLUDE columns. */ - stmt->indexParams = list_concat(stmt->indexParams, - stmt->indexIncludingParams); - numberOfAttributes = list_length(stmt->indexParams); + allIndexParams = list_concat_copy(stmt->indexParams, + stmt->indexIncludingParams); + numberOfAttributes = list_length(allIndexParams); if (numberOfAttributes <= 0) ereport(ERROR, @@ -415,9 +546,8 @@ DefineIndex(Oid relationId, * functions will need to be updated, too. */ lockmode = stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock; - rel = heap_open(relationId, lockmode); + rel = table_open(relationId, lockmode); - relationId = RelationGetRelid(rel); namespaceId = RelationGetNamespace(rel); /* Ensure that it makes sense to index this kind of relation */ @@ -429,6 +559,7 @@ DefineIndex(Oid relationId, /* OK */ break; case RELKIND_FOREIGN_TABLE: + /* * Custom error message for FOREIGN TABLE since the term is close * to a regular table and can confuse the user. @@ -437,6 +568,7 @@ DefineIndex(Oid relationId, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot create index on foreign table \"%s\"", RelationGetRelationName(rel)))); + break; default: ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -509,10 +641,15 @@ DefineIndex(Oid relationId, if (stmt->tableSpace) { tablespaceId = get_tablespace_oid(stmt->tableSpace, false); + if (partitioned && tablespaceId == MyDatabaseTableSpace) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot specify default tablespace for partitioned relations"))); } else { - tablespaceId = GetDefaultTablespace(rel->rd_rel->relpersistence); + tablespaceId = GetDefaultTablespace(rel->rd_rel->relpersistence, + partitioned); /* note InvalidOid is OK in this case */ } @@ -544,7 +681,7 @@ DefineIndex(Oid relationId, /* * Choose the index column names. */ - indexColNames = ChooseIndexColumnNames(stmt->indexParams); + indexColNames = ChooseIndexColumnNames(allIndexParams); /* * Select name for index if caller didn't specify @@ -583,16 +720,19 @@ DefineIndex(Oid relationId, errmsg("access method \"%s\" does not exist", accessMethodName))); } - accessMethodId = HeapTupleGetOid(tuple); accessMethodForm = (Form_pg_am) GETSTRUCT(tuple); + accessMethodId = accessMethodForm->oid; amRoutine = GetIndexAmRoutine(accessMethodForm->amhandler); + pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, + accessMethodId); + if (stmt->unique && !amRoutine->amcanunique) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support unique indexes", accessMethodName))); - if (list_length(stmt->indexIncludingParams) > 0 && !amRoutine->amcaninclude) + if (stmt->indexIncludingParams != NIL && !amRoutine->amcaninclude) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("access method \"%s\" does not support included columns", @@ -630,27 +770,17 @@ DefineIndex(Oid relationId, /* * Prepare arguments for index_create, primarily an IndexInfo structure. - * Note that ii_Predicate must be in implicit-AND format. - */ - indexInfo = makeNode(IndexInfo); - indexInfo->ii_NumIndexAttrs = numberOfAttributes; - indexInfo->ii_NumIndexKeyAttrs = numberOfKeyAttributes; - indexInfo->ii_Expressions = NIL; /* for now */ - indexInfo->ii_ExpressionsState = NIL; - indexInfo->ii_Predicate = make_ands_implicit((Expr *) stmt->whereClause); - indexInfo->ii_PredicateState = NULL; - indexInfo->ii_ExclusionOps = NULL; - indexInfo->ii_ExclusionProcs = NULL; - indexInfo->ii_ExclusionStrats = NULL; - indexInfo->ii_Unique = stmt->unique; - /* In a concurrent build, mark it not-ready-for-inserts */ - indexInfo->ii_ReadyForInserts = !stmt->concurrent; - indexInfo->ii_Concurrent = stmt->concurrent; - indexInfo->ii_BrokenHotChain = false; - indexInfo->ii_ParallelWorkers = 0; - indexInfo->ii_Am = accessMethodId; - indexInfo->ii_AmCache = NULL; - indexInfo->ii_Context = CurrentMemoryContext; + * Note that predicates must be in implicit-AND format. In a concurrent + * build, mark it not-ready-for-inserts. + */ + indexInfo = makeIndexInfo(numberOfAttributes, + numberOfKeyAttributes, + accessMethodId, + NIL, /* expressions, NIL for now */ + make_ands_implicit((Expr *) stmt->whereClause), + stmt->unique, + !stmt->concurrent, + stmt->concurrent); typeObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); collationObjectId = (Oid *) palloc(numberOfAttributes * sizeof(Oid)); @@ -658,7 +788,7 @@ DefineIndex(Oid relationId, coloptions = (int16 *) palloc(numberOfAttributes * sizeof(int16)); ComputeIndexAttrs(indexInfo, typeObjectId, collationObjectId, classObjectId, - coloptions, stmt->indexParams, + coloptions, allIndexParams, stmt->excludeOpNames, relationId, accessMethodName, accessMethodId, amcanorder, stmt->isconstraint); @@ -667,7 +797,7 @@ DefineIndex(Oid relationId, * Extra checks when creating a PRIMARY KEY index. */ if (stmt->primary) - index_check_primary_key(rel, indexInfo, is_alter_table); + index_check_primary_key(rel, indexInfo, is_alter_table, stmt); /* * If this table is partitioned and we're creating a unique index or a @@ -689,13 +819,13 @@ DefineIndex(Oid relationId, * partition-local index can enforce global uniqueness iff the PK * value completely determines the partition that a row is in. * - * Thus, verify that all the columns in the partition key appear - * in the unique key definition. + * Thus, verify that all the columns in the partition key appear in + * the unique key definition. */ for (i = 0; i < key->partnatts; i++) { - bool found = false; - int j; + bool found = false; + int j; const char *constraint_type; if (stmt->primary) @@ -720,11 +850,11 @@ DefineIndex(Oid relationId, errmsg("unsupported %s constraint with partition key definition", constraint_type), errdetail("%s constraints cannot be used when partition keys include expressions.", - constraint_type))); + constraint_type))); - for (j = 0; j < indexInfo->ii_NumIndexAttrs; j++) + for (j = 0; j < indexInfo->ii_NumIndexKeyAttrs; j++) { - if (key->partattrs[i] == indexInfo->ii_KeyAttrNumbers[j]) + if (key->partattrs[i] == indexInfo->ii_IndexAttrNumbers[j]) { found = true; break; @@ -748,14 +878,14 @@ DefineIndex(Oid relationId, /* - * We disallow indexes on system columns other than OID. They would not - * necessarily get updated correctly, and they don't seem useful anyway. + * We disallow indexes on system columns. They would not necessarily get + * updated correctly, and they don't seem useful anyway. */ for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) { - AttrNumber attno = indexInfo->ii_KeyAttrNumbers[i]; + AttrNumber attno = indexInfo->ii_IndexAttrNumbers[i]; - if (attno < 0 && attno != ObjectIdAttributeNumber) + if (attno < 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("index creation on system columns is not supported"))); @@ -773,8 +903,7 @@ DefineIndex(Oid relationId, for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++) { - if (i != ObjectIdAttributeNumber && - bms_is_member(i - FirstLowInvalidHeapAttributeNumber, + if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, indexattrs)) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -818,8 +947,8 @@ DefineIndex(Oid relationId, /* * Make the catalog entries for the index, including constraints. This * step also actually builds the index, except if caller requested not to - * or in concurrent mode, in which case it'll be done later, or - * doing a partitioned index (because those don't have storage). + * or in concurrent mode, in which case it'll be done later, or doing a + * partitioned index (because those don't have storage). */ flags = constr_flags = 0; if (stmt->isconstraint) @@ -834,8 +963,18 @@ DefineIndex(Oid relationId, flags |= INDEX_CREATE_PARTITIONED; if (stmt->primary) flags |= INDEX_CREATE_IS_PRIMARY; + + /* + * If the table is partitioned, and recursion was declined but partitions + * exist, mark the index as invalid. + */ if (partitioned && stmt->relation && !stmt->relation->inh) - flags |= INDEX_CREATE_INVALID; + { + PartitionDesc pd = RelationGetPartitionDesc(rel); + + if (pd->nparts != 0) + flags |= INDEX_CREATE_INVALID; + } if (stmt->deferrable) constr_flags |= INDEX_CONSTR_CREATE_DEFERRABLE; @@ -855,9 +994,21 @@ DefineIndex(Oid relationId, ObjectAddressSet(address, RelationRelationId, indexRelationId); + /* + * Revert to original default_tablespace. Must do this before any return + * from this function, but after index_create, so this is a good time. + */ + if (save_nestlevel >= 0) + AtEOXact_GUC(true, save_nestlevel); + if (!OidIsValid(indexRelationId)) { - heap_close(rel, NoLock); + table_close(rel, NoLock); + + /* If this is the top-level index, we're done */ + if (!OidIsValid(parentIndexId)) + pgstat_progress_end_command(); + return address; } @@ -869,8 +1020,8 @@ DefineIndex(Oid relationId, if (partitioned) { /* - * Unless caller specified to skip this step (via ONLY), process - * each partition to make sure they all contain a corresponding index. + * Unless caller specified to skip this step (via ONLY), process each + * partition to make sure they all contain a corresponding index. * * If we're called internally (no stmt->relation), recurse always. */ @@ -883,15 +1034,16 @@ DefineIndex(Oid relationId, TupleDesc parentDesc; Oid *opfamOids; + pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_TOTAL, + nparts); + memcpy(part_oids, partdesc->oids, sizeof(Oid) * nparts); - parentDesc = CreateTupleDescCopy(RelationGetDescr(rel)); - opfamOids = palloc(sizeof(Oid) * numberOfAttributes); - for (i = 0; i < numberOfAttributes; i++) + parentDesc = RelationGetDescr(rel); + opfamOids = palloc(sizeof(Oid) * numberOfKeyAttributes); + for (i = 0; i < numberOfKeyAttributes; i++) opfamOids[i] = get_opclass_family(classObjectId[i]); - heap_close(rel, NoLock); - /* * For each partition, scan all existing indexes; if one matches * our index definition and is not already attached to some other @@ -902,23 +1054,41 @@ DefineIndex(Oid relationId, */ for (i = 0; i < nparts; i++) { - Oid childRelid = part_oids[i]; - Relation childrel; - List *childidxs; - ListCell *cell; + Oid childRelid = part_oids[i]; + Relation childrel; + List *childidxs; + ListCell *cell; AttrNumber *attmap; - bool found = false; - int maplen; + bool found = false; + int maplen; + + childrel = table_open(childRelid, lockmode); + + /* + * Don't try to create indexes on foreign tables, though. Skip + * those if a regular index, or fail if trying to create a + * constraint index. + */ + if (childrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + if (stmt->unique || stmt->primary) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create unique index on partitioned table \"%s\"", + RelationGetRelationName(rel)), + errdetail("Table \"%s\" contains partitions that are foreign tables.", + RelationGetRelationName(rel)))); + + table_close(childrel, lockmode); + continue; + } - childrel = heap_open(childRelid, lockmode); childidxs = RelationGetIndexList(childrel); attmap = convert_tuples_by_name_map(RelationGetDescr(childrel), - parentDesc, - gettext_noop("could not convert row type")); + parentDesc); maplen = parentDesc->natts; - foreach(cell, childidxs) { Oid cldidxid = lfirst_oid(cell); @@ -938,7 +1108,7 @@ DefineIndex(Oid relationId, opfamOids, attmap, maplen)) { - Oid cldConstrOid = InvalidOid; + Oid cldConstrOid = InvalidOid; /* * Found a match. @@ -965,9 +1135,10 @@ DefineIndex(Oid relationId, IndexSetParentIndex(cldidx, indexRelationId); if (createdConstraintId != InvalidOid) ConstraintSetParentConstraint(cldConstrOid, - createdConstraintId); + createdConstraintId, + childRelid); - if (!IndexIsValid(cldidx->rd_index)) + if (!cldidx->rd_index->indisvalid) invalidate_parent = true; found = true; @@ -980,7 +1151,7 @@ DefineIndex(Oid relationId, } list_free(childidxs); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); /* * If no matching index was found, create our own. @@ -989,7 +1160,44 @@ DefineIndex(Oid relationId, { IndexStmt *childStmt = copyObject(stmt); bool found_whole_row; + ListCell *lc; + + /* + * We can't use the same index name for the child index, + * so clear idxname to let the recursive invocation choose + * a new name. Likewise, the existing target relation + * field is wrong, and if indexOid or oldNode are set, + * they mustn't be applied to the child either. + */ + childStmt->idxname = NULL; + childStmt->relation = NULL; + childStmt->indexOid = InvalidOid; + childStmt->oldNode = InvalidOid; + + /* + * Adjust any Vars (both in expressions and in the index's + * WHERE clause) to match the partition's column numbering + * in case it's different from the parent's. + */ + foreach(lc, childStmt->indexParams) + { + IndexElem *ielem = lfirst(lc); + /* + * If the index parameter is an expression, we must + * translate it to contain child Vars. + */ + if (ielem->expr) + { + ielem->expr = + map_variable_attnos((Node *) ielem->expr, + 1, 0, attmap, maplen, + InvalidOid, + &found_whole_row); + if (found_whole_row) + elog(ERROR, "cannot convert whole-row table reference"); + } + } childStmt->whereClause = map_variable_attnos(stmt->whereClause, 1, 0, attmap, maplen, @@ -997,65 +1205,70 @@ DefineIndex(Oid relationId, if (found_whole_row) elog(ERROR, "cannot convert whole-row table reference"); - childStmt->idxname = NULL; - childStmt->relationId = childRelid; DefineIndex(childRelid, childStmt, - InvalidOid, /* no predefined OID */ + InvalidOid, /* no predefined OID */ indexRelationId, /* this is our child */ createdConstraintId, is_alter_table, check_rights, check_not_in_use, - false, quiet); + skip_build, quiet); } + pgstat_progress_update_param(PROGRESS_CREATEIDX_PARTITIONS_DONE, + i + 1); pfree(attmap); } /* * The pg_index row we inserted for this index was marked - * indisvalid=true. But if we attached an existing index that - * is invalid, this is incorrect, so update our row to - * invalid too. + * indisvalid=true. But if we attached an existing index that is + * invalid, this is incorrect, so update our row to invalid too. */ if (invalidate_parent) { - Relation pg_index = heap_open(IndexRelationId, RowExclusiveLock); + Relation pg_index = table_open(IndexRelationId, RowExclusiveLock); HeapTuple tup, newtup; tup = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexRelationId)); - if (!tup) + if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for index %u", indexRelationId); newtup = heap_copytuple(tup); ((Form_pg_index) GETSTRUCT(newtup))->indisvalid = false; CatalogTupleUpdate(pg_index, &tup->t_self, newtup); ReleaseSysCache(tup); - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); heap_freetuple(newtup); } } - else - heap_close(rel, NoLock); /* * Indexes on partitioned tables are not themselves built, so we're * done here. */ + table_close(rel, NoLock); + if (!OidIsValid(parentIndexId)) + pgstat_progress_end_command(); return address; } if (!stmt->concurrent) { /* Close the heap and we're done, in the non-concurrent case */ - heap_close(rel, NoLock); + table_close(rel, NoLock); + + /* If this is the top-level index, we're done. */ + if (!OidIsValid(parentIndexId)) + pgstat_progress_end_command(); + return address; } /* save lockrelid and locktag for below, then close rel */ heaprelid = rel->rd_lockInfo.lockRelId; SET_LOCKTAG_RELATION(heaplocktag, heaprelid.dbId, heaprelid.relId); - heap_close(rel, NoLock); + table_close(rel, NoLock); /* * For a concurrent build, it's important to make the catalog entries @@ -1084,6 +1297,12 @@ DefineIndex(Oid relationId, CommitTransactionCommand(); StartTransactionCommand(); + /* + * The index is now visible, so we can report the OID. + */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, + indexRelationId); + /* * Phase 2 of concurrent index build (see comments for validate_index() * for an overview of how this works) @@ -1100,7 +1319,9 @@ DefineIndex(Oid relationId, * exclusive lock on our table. The lock code will detect deadlock and * error out properly. */ - WaitForLockers(heaplocktag, ShareLock); + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_1); + WaitForLockers(heaplocktag, ShareLock, true); /* * At this moment we are sure that there are no transactions with the @@ -1120,34 +1341,11 @@ DefineIndex(Oid relationId, * HOT-chain or the extension of the chain is HOT-safe for this index. */ - /* Open and lock the parent heap relation */ - rel = heap_openrv(stmt->relation, ShareUpdateExclusiveLock); - - /* And the target index relation */ - indexRelation = index_open(indexRelationId, RowExclusiveLock); - /* Set ActiveSnapshot since functions in the indexes may need it */ PushActiveSnapshot(GetTransactionSnapshot()); - /* We have to re-build the IndexInfo struct, since it was lost in commit */ - indexInfo = BuildIndexInfo(indexRelation); - Assert(!indexInfo->ii_ReadyForInserts); - indexInfo->ii_Concurrent = true; - indexInfo->ii_BrokenHotChain = false; - - /* Now build the index */ - index_build(rel, indexRelation, indexInfo, stmt->primary, false, true); - - /* Close both the relations, but keep the locks */ - heap_close(rel, NoLock); - index_close(indexRelation, NoLock); - - /* - * Update the pg_index row to mark the index as ready for inserts. Once we - * commit this transaction, any new transactions that open the table must - * insert new entries into the index for insertions and non-HOT updates. - */ - index_set_state_flags(indexRelationId, INDEX_CREATE_SET_READY); + /* Perform concurrent build of index */ + index_concurrently_build(relationId, indexRelationId); /* we can do away with our snapshot */ PopActiveSnapshot(); @@ -1164,7 +1362,9 @@ DefineIndex(Oid relationId, * We once again wait until no transaction can have the table open with * the index marked as read-only for updates. */ - WaitForLockers(heaplocktag, ShareLock); + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_2); + WaitForLockers(heaplocktag, ShareLock, true); /* * Now take the "reference snapshot" that will be used by validate_index() @@ -1195,87 +1395,35 @@ DefineIndex(Oid relationId, * doing CREATE INDEX CONCURRENTLY, which would see our snapshot as one * they must wait for. But first, save the snapshot's xmin to use as * limitXmin for GetCurrentVirtualXIDs(). - * - * Our catalog snapshot could have the same effect, so drop that one too. */ limitXmin = snapshot->xmin; PopActiveSnapshot(); UnregisterSnapshot(snapshot); - InvalidateCatalogSnapshot(); + + /* + * The snapshot subsystem could still contain registered snapshots that + * are holding back our process's advertised xmin; in particular, if + * default_transaction_isolation = serializable, there is a transaction + * snapshot that is still active. The CatalogSnapshot is likewise a + * hazard. To ensure no deadlocks, we must commit and start yet another + * transaction, and do our wait before any snapshot has been taken in it. + */ + CommitTransactionCommand(); + StartTransactionCommand(); + + /* We should now definitely not be advertising any xmin. */ + Assert(MyPgXact->xmin == InvalidTransactionId); /* * The index is now valid in the sense that it contains all currently * interesting tuples. But since it might not contain tuples deleted just * before the reference snap was taken, we have to wait out any - * transactions that might have older snapshots. Obtain a list of VXIDs - * of such transactions, and wait for them individually. - * - * We can exclude any running transactions that have xmin > the xmin of - * our reference snapshot; their oldest snapshot must be newer than ours. - * We can also exclude any transactions that have xmin = zero, since they - * evidently have no live snapshot at all (and any one they might be in - * process of taking is certainly newer than ours). Transactions in other - * DBs can be ignored too, since they'll never even be able to see this - * index. - * - * We can also exclude autovacuum processes and processes running manual - * lazy VACUUMs, because they won't be fazed by missing index entries - * either. (Manual ANALYZEs, however, can't be excluded because they - * might be within transactions that are going to do arbitrary operations - * later.) - * - * Also, GetCurrentVirtualXIDs never reports our own vxid, so we need not - * check for that. - * - * If a process goes idle-in-transaction with xmin zero, we do not need to - * wait for it anymore, per the above argument. We do not have the - * infrastructure right now to stop waiting if that happens, but we can at - * least avoid the folly of waiting when it is idle at the time we would - * begin to wait. We do this by repeatedly rechecking the output of - * GetCurrentVirtualXIDs. If, during any iteration, a particular vxid - * doesn't show up in the output, we know we can forget about it. + * transactions that might have older snapshots. */ - old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false, - PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, - &n_old_snapshots); - - for (i = 0; i < n_old_snapshots; i++) - { - if (!VirtualTransactionIdIsValid(old_snapshots[i])) - continue; /* found uninteresting in previous cycle */ - - if (i > 0) - { - /* see if anything's changed ... */ - VirtualTransactionId *newer_snapshots; - int n_newer_snapshots; - int j; - int k; - - newer_snapshots = GetCurrentVirtualXIDs(limitXmin, - true, false, - PROC_IS_AUTOVACUUM | PROC_IN_VACUUM, - &n_newer_snapshots); - for (j = i; j < n_old_snapshots; j++) - { - if (!VirtualTransactionIdIsValid(old_snapshots[j])) - continue; /* found uninteresting in previous cycle */ - for (k = 0; k < n_newer_snapshots; k++) - { - if (VirtualTransactionIdEquals(old_snapshots[j], - newer_snapshots[k])) - break; - } - if (k >= n_newer_snapshots) /* not there anymore */ - SetInvalidVirtualTransactionId(old_snapshots[j]); - } - pfree(newer_snapshots); - } - - if (VirtualTransactionIdIsValid(old_snapshots[i])) - VirtualXactLock(old_snapshots[i], true); - } + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_3); + WaitForOlderSnapshots(limitXmin, true); /* * Index can now be marked valid -- update its pg_index entry @@ -1297,6 +1445,8 @@ DefineIndex(Oid relationId, */ UnlockRelationIdForSession(&heaprelid, ShareUpdateExclusiveLock); + pgstat_progress_end_command(); + return address; } @@ -1359,7 +1509,8 @@ CheckPredicate(Expr *predicate) /* * Compute per-index-column information, including indexed column numbers - * or index expressions, opclasses, and indoptions. + * or index expressions, opclasses, and indoptions. Note, all output vectors + * should be allocated for all columns, including "including" ones. */ static void ComputeIndexAttrs(IndexInfo *indexInfo, @@ -1428,7 +1579,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo, attribute->name))); } attform = (Form_pg_attribute) GETSTRUCT(atttuple); - indexInfo->ii_KeyAttrNumbers[attn] = attform->attnum; + indexInfo->ii_IndexAttrNumbers[attn] = attform->attnum; atttype = attform->atttypid; attcollation = attform->attcollation; ReleaseSysCache(atttuple); @@ -1461,11 +1612,11 @@ ComputeIndexAttrs(IndexInfo *indexInfo, * User wrote "(column)" or "(column COLLATE something)". * Treat it like simple attribute anyway. */ - indexInfo->ii_KeyAttrNumbers[attn] = ((Var *) expr)->varattno; + indexInfo->ii_IndexAttrNumbers[attn] = ((Var *) expr)->varattno; } else { - indexInfo->ii_KeyAttrNumbers[attn] = 0; /* marks expression */ + indexInfo->ii_IndexAttrNumbers[attn] = 0; /* marks expression */ indexInfo->ii_Expressions = lappend(indexInfo->ii_Expressions, expr); @@ -1490,6 +1641,37 @@ ComputeIndexAttrs(IndexInfo *indexInfo, typeOidP[attn] = atttype; + /* + * Included columns have no collation, no opclass and no ordering + * options. + */ + if (attn >= nkeycols) + { + if (attribute->collation) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("including column does not support a collation"))); + if (attribute->opclass) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("including column does not support an operator class"))); + if (attribute->ordering != SORTBY_DEFAULT) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("including column does not support ASC/DESC options"))); + if (attribute->nulls_ordering != SORTBY_NULLS_DEFAULT) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("including column does not support NULLS FIRST/LAST options"))); + + classOidP[attn] = InvalidOid; + colOptionP[attn] = 0; + collationOidP[attn] = InvalidOid; + attn++; + + continue; + } + /* * Apply collation override if any */ @@ -1521,17 +1703,6 @@ ComputeIndexAttrs(IndexInfo *indexInfo, collationOidP[attn] = attcollation; - /* - * Included columns have no opclass and no ordering options. - */ - if (attn >= nkeycols) - { - classOidP[attn] = InvalidOid; - colOptionP[attn] = 0; - attn++; - continue; - } - /* * Identify the opclass to use. */ @@ -1601,7 +1772,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo, indexInfo->ii_ExclusionOps[attn] = opid; indexInfo->ii_ExclusionProcs[attn] = get_opcode(opid); indexInfo->ii_ExclusionStrats[attn] = strat; - nextExclOp = lnext(nextExclOp); + nextExclOp = lnext(exclusionOpNames, nextExclOp); } /* @@ -1656,6 +1827,7 @@ ResolveOpClass(List *opclass, Oid attrType, char *schemaname; char *opcname; HeapTuple tuple; + Form_pg_opclass opform; Oid opClassId, opInputType; @@ -1740,8 +1912,9 @@ ResolveOpClass(List *opclass, Oid attrType, * Verify that the index operator class accepts this datatype. Note we * will accept binary compatibility. */ - opClassId = HeapTupleGetOid(tuple); - opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype; + opform = (Form_pg_opclass) GETSTRUCT(tuple); + opClassId = opform->oid; + opInputType = opform->opcintype; if (!IsBinaryCoercible(attrType, opInputType)) ereport(ERROR, @@ -1790,7 +1963,7 @@ GetDefaultOpClass(Oid type_id, Oid am_id) * we need a tiebreaker.) If we find more than one exact match, then * someone put bogus entries in pg_opclass. */ - rel = heap_open(OperatorClassRelationId, AccessShareLock); + rel = table_open(OperatorClassRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_opclass_opcmethod, @@ -1810,7 +1983,7 @@ GetDefaultOpClass(Oid type_id, Oid am_id) if (opclass->opcintype == type_id) { nexact++; - result = HeapTupleGetOid(tup); + result = opclass->oid; } else if (nexact == 0 && IsBinaryCoercible(type_id, opclass->opcintype)) @@ -1818,19 +1991,19 @@ GetDefaultOpClass(Oid type_id, Oid am_id) if (IsPreferredType(tcategory, opclass->opcintype)) { ncompatiblepreferred++; - result = HeapTupleGetOid(tup); + result = opclass->oid; } else if (ncompatiblepreferred == 0) { ncompatible++; - result = HeapTupleGetOid(tup); + result = opclass->oid; } } } systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* raise error if pg_opclass contains inconsistent data */ if (nexact > 1) @@ -1940,6 +2113,12 @@ makeObjectName(const char *name1, const char *name2, const char *label) * except that the label can't be NULL; digits will be appended to the label * if needed to create a name that is unique within the specified namespace. * + * If isconstraint is true, we also avoid choosing a name matching any + * existing constraint in the same namespace. (This is stricter than what + * Postgres itself requires, but the SQL standard says that constraint names + * should be unique within schemas, so we follow that for autogenerated + * constraint names.) + * * Note: it is theoretically possible to get a collision anyway, if someone * else chooses the same name concurrently. This is fairly unlikely to be * a problem in practice, especially if one is holding an exclusive lock on @@ -1951,7 +2130,8 @@ makeObjectName(const char *name1, const char *name2, const char *label) */ char * ChooseRelationName(const char *name1, const char *name2, - const char *label, Oid namespaceid) + const char *label, Oid namespaceid, + bool isconstraint) { int pass = 0; char *relname = NULL; @@ -1965,7 +2145,11 @@ ChooseRelationName(const char *name1, const char *name2, relname = makeObjectName(name1, name2, modlabel); if (!OidIsValid(get_relname_relid(relname, namespaceid))) - break; + { + if (!isconstraint || + !ConstraintNameExists(relname, namespaceid)) + break; + } /* found a conflict, so try a new name component */ pfree(relname); @@ -1993,28 +2177,32 @@ ChooseIndexName(const char *tabname, Oid namespaceId, indexname = ChooseRelationName(tabname, NULL, "pkey", - namespaceId); + namespaceId, + true); } else if (exclusionOpNames != NIL) { indexname = ChooseRelationName(tabname, ChooseIndexNameAddition(colnames), "excl", - namespaceId); + namespaceId, + true); } else if (isconstraint) { indexname = ChooseRelationName(tabname, ChooseIndexNameAddition(colnames), "key", - namespaceId); + namespaceId, + true); } else { indexname = ChooseRelationName(tabname, ChooseIndexNameAddition(colnames), "idx", - namespaceId); + namespaceId, + false); } return indexname; @@ -2028,7 +2216,8 @@ ChooseIndexName(const char *tabname, Oid namespaceId, * We know that less than NAMEDATALEN characters will actually be used, * so we can truncate the result once we've generated that many. * - * XXX See also ChooseExtendedStatisticNameAddition. + * XXX See also ChooseForeignKeyConstraintNameAddition and + * ChooseExtendedStatisticNameAddition. */ static char * ChooseIndexNameAddition(List *colnames) @@ -2123,10 +2312,10 @@ ChooseIndexColumnNames(List *indexElems) * Recreate a specific index. */ void -ReindexIndex(RangeVar *indexRelation, int options) +ReindexIndex(RangeVar *indexRelation, int options, bool concurrent) { + struct ReindexIndexCallbackState state; Oid indOid; - Oid heapOid = InvalidOid; Relation irel; char persistence; @@ -2135,10 +2324,13 @@ ReindexIndex(RangeVar *indexRelation, int options) * obtain lock on table first, to avoid deadlock hazard. The lock level * used here must match the index lock obtained in reindex_index(). */ - indOid = RangeVarGetRelidExtended(indexRelation, AccessExclusiveLock, + state.concurrent = concurrent; + state.locked_table_oid = InvalidOid; + indOid = RangeVarGetRelidExtended(indexRelation, + concurrent ? ShareUpdateExclusiveLock : AccessExclusiveLock, 0, RangeVarCallbackForReindexIndex, - (void *) &heapOid); + &state); /* * Obtain the current persistence of the existing index. We already hold @@ -2155,7 +2347,11 @@ ReindexIndex(RangeVar *indexRelation, int options) persistence = irel->rd_rel->relpersistence; index_close(irel, NoLock); - reindex_index(indOid, false, persistence, options); + if (concurrent) + ReindexRelationConcurrently(indOid, options); + else + reindex_index(indOid, false, persistence, + options | REINDEXOPT_REPORT_PROGRESS); } /* @@ -2168,7 +2364,15 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg) { char relkind; - Oid *heapOid = (Oid *) arg; + struct ReindexIndexCallbackState *state = arg; + LOCKMODE table_lockmode; + + /* + * Lock level here should match table lock in reindex_index() for + * non-concurrent case and table locks used by index_concurrently_*() for + * concurrent case. + */ + table_lockmode = state->concurrent ? ShareUpdateExclusiveLock : ShareLock; /* * If we previously locked some other index's heap, and the name we're @@ -2177,9 +2381,8 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, */ if (relId != oldRelId && OidIsValid(oldRelId)) { - /* lock level here should match reindex_index() heap lock */ - UnlockRelationOid(*heapOid, ShareLock); - *heapOid = InvalidOid; + UnlockRelationOid(state->locked_table_oid, table_lockmode); + state->locked_table_oid = InvalidOid; } /* If the relation does not exist, there's nothing more to do. */ @@ -2207,14 +2410,17 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, /* Lock heap before index to avoid deadlock. */ if (relId != oldRelId) { + Oid table_oid = IndexGetRelation(relId, true); + /* - * Lock level here should match reindex_index() heap lock. If the OID - * isn't valid, it means the index as concurrently dropped, which is - * not a problem for us; just return normally. + * If the OID isn't valid, it means the index was concurrently + * dropped, which is not a problem for us; just return normally. */ - *heapOid = IndexGetRelation(relId, true); - if (OidIsValid(*heapOid)) - LockRelationOid(*heapOid, ShareLock); + if (OidIsValid(table_oid)) + { + LockRelationOid(table_oid, table_lockmode); + state->locked_table_oid = table_oid; + } } } @@ -2223,21 +2429,37 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation, * Recreate all indexes of a table (and of its toast table, if any) */ Oid -ReindexTable(RangeVar *relation, int options) +ReindexTable(RangeVar *relation, int options, bool concurrent) { Oid heapOid; + bool result; /* The lock level used here should match reindex_relation(). */ - heapOid = RangeVarGetRelidExtended(relation, ShareLock, 0, + heapOid = RangeVarGetRelidExtended(relation, + concurrent ? ShareUpdateExclusiveLock : ShareLock, + 0, RangeVarCallbackOwnsTable, NULL); - if (!reindex_relation(heapOid, - REINDEX_REL_PROCESS_TOAST | - REINDEX_REL_CHECK_CONSTRAINTS, - options)) - ereport(NOTICE, - (errmsg("table \"%s\" has no indexes", - relation->relname))); + if (concurrent) + { + result = ReindexRelationConcurrently(heapOid, options); + + if (!result) + ereport(NOTICE, + (errmsg("table \"%s\" has no indexes that can be reindexed concurrently", + relation->relname))); + } + else + { + result = reindex_relation(heapOid, + REINDEX_REL_PROCESS_TOAST | + REINDEX_REL_CHECK_CONSTRAINTS, + options | REINDEXOPT_REPORT_PROGRESS); + if (!result) + ereport(NOTICE, + (errmsg("table \"%s\" has no indexes to reindex", + relation->relname))); + } return heapOid; } @@ -2252,11 +2474,11 @@ ReindexTable(RangeVar *relation, int options) */ void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, - int options) + int options, bool concurrent) { Oid objectOid; Relation relationRelation; - HeapScanDesc scan; + TableScanDesc scan; ScanKeyData scan_keys[1]; HeapTuple tuple; MemoryContext private_context; @@ -2264,12 +2486,18 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, List *relids = NIL; ListCell *l; int num_keys; + bool concurrent_warning = false; AssertArg(objectName); Assert(objectKind == REINDEX_OBJECT_SCHEMA || objectKind == REINDEX_OBJECT_SYSTEM || objectKind == REINDEX_OBJECT_DATABASE); + if (objectKind == REINDEX_OBJECT_SYSTEM && concurrent) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently"))); + /* * Get OID of object to reindex, being the database currently being used * by session for a database or for system catalogs, or the schema defined @@ -2329,12 +2557,12 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, * We only consider plain relations and materialized views here (toast * rels will be processed indirectly by reindex_relation). */ - relationRelation = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(relationRelation, num_keys, scan_keys); + relationRelation = table_open(RelationRelationId, AccessShareLock); + scan = table_beginscan_catalog(relationRelation, num_keys, scan_keys); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple); - Oid relid = HeapTupleGetOid(tuple); + Oid relid = classtuple->oid; /* * Only regular tables and matviews can have indexes, so ignore any @@ -2360,6 +2588,33 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, !IsSystemClass(relid, classtuple)) continue; + /* + * The table can be reindexed if the user is superuser, the table + * owner, or the database/schema owner (but in the latter case, only + * if it's not a shared relation). pg_class_ownercheck includes the + * superuser case, and depending on objectKind we already know that + * the user has permission to run REINDEX on this database or schema + * per the permission checks at the beginning of this routine. + */ + if (classtuple->relisshared && + !pg_class_ownercheck(relid, GetUserId())) + continue; + + /* + * Skip system tables, since index_create() would reject indexing them + * concurrently (and it would likely fail if we tried). + */ + if (concurrent && + IsCatalogRelationOid(relid)) + { + if (!concurrent_warning) + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently, skipping all"))); + concurrent_warning = true; + continue; + } + /* Save the list of relation OIDs in private context */ old = MemoryContextSwitchTo(private_context); @@ -2377,8 +2632,8 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, MemoryContextSwitchTo(old); } - heap_endscan(scan); - heap_close(relationRelation, AccessShareLock); + table_endscan(scan); + table_close(relationRelation, AccessShareLock); /* Now reindex each rel in a separate transaction */ PopActiveSnapshot(); @@ -2390,22 +2645,672 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, StartTransactionCommand(); /* functions in indexes may want a snapshot set */ PushActiveSnapshot(GetTransactionSnapshot()); - if (reindex_relation(relid, - REINDEX_REL_PROCESS_TOAST | - REINDEX_REL_CHECK_CONSTRAINTS, - options)) - if (options & REINDEXOPT_VERBOSE) - ereport(INFO, - (errmsg("table \"%s.%s\" was reindexed", - get_namespace_name(get_rel_namespace(relid)), - get_rel_name(relid)))); + if (concurrent) + { + (void) ReindexRelationConcurrently(relid, options); + /* ReindexRelationConcurrently() does the verbose output */ + } + else + { + bool result; + + result = reindex_relation(relid, + REINDEX_REL_PROCESS_TOAST | + REINDEX_REL_CHECK_CONSTRAINTS, + options | REINDEXOPT_REPORT_PROGRESS); + + if (result && (options & REINDEXOPT_VERBOSE)) + ereport(INFO, + (errmsg("table \"%s.%s\" was reindexed", + get_namespace_name(get_rel_namespace(relid)), + get_rel_name(relid)))); + + PopActiveSnapshot(); + } + + CommitTransactionCommand(); + } + StartTransactionCommand(); + + MemoryContextDelete(private_context); +} + + +/* + * ReindexRelationConcurrently - process REINDEX CONCURRENTLY for given + * relation OID + * + * 'relationOid' can either belong to an index, a table or a materialized + * view. For tables and materialized views, all its indexes will be rebuilt, + * excluding invalid indexes and any indexes used in exclusion constraints, + * but including its associated toast table indexes. For indexes, the index + * itself will be rebuilt. If 'relationOid' belongs to a partitioned table + * then we issue a warning to mention these are not yet supported. + * + * The locks taken on parent tables and involved indexes are kept until the + * transaction is committed, at which point a session lock is taken on each + * relation. Both of these protect against concurrent schema changes. + * + * Returns true if any indexes have been rebuilt (including toast table's + * indexes, when relevant), otherwise returns false. + */ +static bool +ReindexRelationConcurrently(Oid relationOid, int options) +{ + List *heapRelationIds = NIL; + List *indexIds = NIL; + List *newIndexIds = NIL; + List *relationLocks = NIL; + List *lockTags = NIL; + ListCell *lc, + *lc2; + MemoryContext private_context; + MemoryContext oldcontext; + char relkind; + char *relationName = NULL; + char *relationNamespace = NULL; + PGRUsage ru0; + + /* + * Create a memory context that will survive forced transaction commits we + * do below. Since it is a child of PortalContext, it will go away + * eventually even if we suffer an error; there's no need for special + * abort cleanup logic. + */ + private_context = AllocSetContextCreate(PortalContext, + "ReindexConcurrent", + ALLOCSET_SMALL_SIZES); + + if (options & REINDEXOPT_VERBOSE) + { + /* Save data needed by REINDEX VERBOSE in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + relationName = get_rel_name(relationOid); + relationNamespace = get_namespace_name(get_rel_namespace(relationOid)); + + pg_rusage_init(&ru0); + + MemoryContextSwitchTo(oldcontext); + } + + relkind = get_rel_relkind(relationOid); + + /* + * Extract the list of indexes that are going to be rebuilt based on the + * list of relation Oids given by caller. + */ + switch (relkind) + { + case RELKIND_RELATION: + case RELKIND_MATVIEW: + case RELKIND_TOASTVALUE: + { + /* + * In the case of a relation, find all its indexes including + * toast indexes. + */ + Relation heapRelation; + + /* Save the list of relation OIDs in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + /* Track this relation for session locks */ + heapRelationIds = lappend_oid(heapRelationIds, relationOid); + + MemoryContextSwitchTo(oldcontext); + + if (IsCatalogRelationOid(relationOid)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently"))); + + /* Open relation to get its indexes */ + heapRelation = table_open(relationOid, ShareUpdateExclusiveLock); + + /* Add all the valid indexes of relation to list */ + foreach(lc, RelationGetIndexList(heapRelation)) + { + Oid cellOid = lfirst_oid(lc); + Relation indexRelation = index_open(cellOid, + ShareUpdateExclusiveLock); + + if (!indexRelation->rd_index->indisvalid) + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex invalid index \"%s.%s\" concurrently, skipping", + get_namespace_name(get_rel_namespace(cellOid)), + get_rel_name(cellOid)))); + else if (indexRelation->rd_index->indisexclusion) + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping", + get_namespace_name(get_rel_namespace(cellOid)), + get_rel_name(cellOid)))); + else + { + /* Save the list of relation OIDs in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + indexIds = lappend_oid(indexIds, cellOid); + + MemoryContextSwitchTo(oldcontext); + } + + index_close(indexRelation, NoLock); + } + + /* Also add the toast indexes */ + if (OidIsValid(heapRelation->rd_rel->reltoastrelid)) + { + Oid toastOid = heapRelation->rd_rel->reltoastrelid; + Relation toastRelation = table_open(toastOid, + ShareUpdateExclusiveLock); + + /* Save the list of relation OIDs in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + /* Track this relation for session locks */ + heapRelationIds = lappend_oid(heapRelationIds, toastOid); + + MemoryContextSwitchTo(oldcontext); + + foreach(lc2, RelationGetIndexList(toastRelation)) + { + Oid cellOid = lfirst_oid(lc2); + Relation indexRelation = index_open(cellOid, + ShareUpdateExclusiveLock); + + if (!indexRelation->rd_index->indisvalid) + ereport(WARNING, + (errcode(ERRCODE_INDEX_CORRUPTED), + errmsg("cannot reindex invalid index \"%s.%s\" concurrently, skipping", + get_namespace_name(get_rel_namespace(cellOid)), + get_rel_name(cellOid)))); + else + { + /* + * Save the list of relation OIDs in private + * context + */ + oldcontext = MemoryContextSwitchTo(private_context); + + indexIds = lappend_oid(indexIds, cellOid); + + MemoryContextSwitchTo(oldcontext); + } + + index_close(indexRelation, NoLock); + } + + table_close(toastRelation, NoLock); + } + + table_close(heapRelation, NoLock); + break; + } + case RELKIND_INDEX: + { + Oid heapId = IndexGetRelation(relationOid, false); + + if (IsCatalogRelationOid(heapId)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot reindex system catalogs concurrently"))); + + /* Save the list of relation OIDs in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + /* Track the heap relation of this index for session locks */ + heapRelationIds = list_make1_oid(heapId); + + /* + * Save the list of relation OIDs in private context. Note + * that invalid indexes are allowed here. + */ + indexIds = lappend_oid(indexIds, relationOid); + + MemoryContextSwitchTo(oldcontext); + break; + } + case RELKIND_PARTITIONED_TABLE: + /* see reindex_relation() */ + ereport(WARNING, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("REINDEX of partitioned tables is not yet implemented, skipping \"%s\"", + get_rel_name(relationOid)))); + return false; + default: + /* Return error if type of relation is not supported */ + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot reindex this type of relation concurrently"))); + break; + } + + /* Definitely no indexes, so leave */ + if (indexIds == NIL) + { + PopActiveSnapshot(); + return false; + } + + Assert(heapRelationIds != NIL); + + /*----- + * Now we have all the indexes we want to process in indexIds. + * + * The phases now are: + * + * 1. create new indexes in the catalog + * 2. build new indexes + * 3. let new indexes catch up with tuples inserted in the meantime + * 4. swap index names + * 5. mark old indexes as dead + * 6. drop old indexes + * + * We process each phase for all indexes before moving to the next phase, + * for efficiency. + */ + + /* + * Phase 1 of REINDEX CONCURRENTLY + * + * Create a new index with the same properties as the old one, but it is + * only registered in catalogs and will be built later. Then get session + * locks on all involved tables. See analogous code in DefineIndex() for + * more detailed comments. + */ + + foreach(lc, indexIds) + { + char *concurrentName; + Oid indexId = lfirst_oid(lc); + Oid newIndexId; + Relation indexRel; + Relation heapRel; + Relation newIndexRel; + LockRelId *lockrelid; + + indexRel = index_open(indexId, ShareUpdateExclusiveLock); + heapRel = table_open(indexRel->rd_index->indrelid, + ShareUpdateExclusiveLock); + + pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, + RelationGetRelid(heapRel)); + pgstat_progress_update_param(PROGRESS_CREATEIDX_COMMAND, + PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY); + pgstat_progress_update_param(PROGRESS_CREATEIDX_INDEX_OID, + indexId); + pgstat_progress_update_param(PROGRESS_CREATEIDX_ACCESS_METHOD_OID, + indexRel->rd_rel->relam); + + /* Choose a temporary relation name for the new index */ + concurrentName = ChooseRelationName(get_rel_name(indexId), + NULL, + "ccnew", + get_rel_namespace(indexRel->rd_index->indrelid), + false); + + /* Create new index definition based on given index */ + newIndexId = index_concurrently_create_copy(heapRel, + indexId, + concurrentName); + + /* Now open the relation of the new index, a lock is also needed on it */ + newIndexRel = index_open(indexId, ShareUpdateExclusiveLock); + + /* + * Save the list of OIDs and locks in private context + */ + oldcontext = MemoryContextSwitchTo(private_context); + + newIndexIds = lappend_oid(newIndexIds, newIndexId); + + /* + * Save lockrelid to protect each relation from drop then close + * relations. The lockrelid on parent relation is not taken here to + * avoid multiple locks taken on the same relation, instead we rely on + * parentRelationIds built earlier. + */ + lockrelid = palloc(sizeof(*lockrelid)); + *lockrelid = indexRel->rd_lockInfo.lockRelId; + relationLocks = lappend(relationLocks, lockrelid); + lockrelid = palloc(sizeof(*lockrelid)); + *lockrelid = newIndexRel->rd_lockInfo.lockRelId; + relationLocks = lappend(relationLocks, lockrelid); + + MemoryContextSwitchTo(oldcontext); + + index_close(indexRel, NoLock); + index_close(newIndexRel, NoLock); + table_close(heapRel, NoLock); + } + + /* + * Save the heap lock for following visibility checks with other backends + * might conflict with this session. + */ + foreach(lc, heapRelationIds) + { + Relation heapRelation = table_open(lfirst_oid(lc), ShareUpdateExclusiveLock); + LockRelId *lockrelid; + LOCKTAG *heaplocktag; + + /* Save the list of locks in private context */ + oldcontext = MemoryContextSwitchTo(private_context); + + /* Add lockrelid of heap relation to the list of locked relations */ + lockrelid = palloc(sizeof(*lockrelid)); + *lockrelid = heapRelation->rd_lockInfo.lockRelId; + relationLocks = lappend(relationLocks, lockrelid); + + heaplocktag = (LOCKTAG *) palloc(sizeof(LOCKTAG)); + + /* Save the LOCKTAG for this parent relation for the wait phase */ + SET_LOCKTAG_RELATION(*heaplocktag, lockrelid->dbId, lockrelid->relId); + lockTags = lappend(lockTags, heaplocktag); + + MemoryContextSwitchTo(oldcontext); + + /* Close heap relation */ + table_close(heapRelation, NoLock); + } + + /* Get a session-level lock on each table. */ + foreach(lc, relationLocks) + { + LockRelId *lockrelid = (LockRelId *) lfirst(lc); + + LockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock); + } + + PopActiveSnapshot(); + CommitTransactionCommand(); + StartTransactionCommand(); + + /* + * Phase 2 of REINDEX CONCURRENTLY + * + * Build the new indexes in a separate transaction for each index to avoid + * having open transactions for an unnecessary long time. But before + * doing that, wait until no running transactions could have the table of + * the index open with the old list of indexes. See "phase 2" in + * DefineIndex() for more details. + */ + + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_1); + WaitForLockersMultiple(lockTags, ShareLock, true); + CommitTransactionCommand(); + + forboth(lc, indexIds, lc2, newIndexIds) + { + Relation indexRel; + Oid oldIndexId = lfirst_oid(lc); + Oid newIndexId = lfirst_oid(lc2); + Oid heapId; + + CHECK_FOR_INTERRUPTS(); + + /* Start new transaction for this index's concurrent build */ + StartTransactionCommand(); + + /* Set ActiveSnapshot since functions in the indexes may need it */ + PushActiveSnapshot(GetTransactionSnapshot()); + + /* + * Index relation has been closed by previous commit, so reopen it to + * get its information. + */ + indexRel = index_open(oldIndexId, ShareUpdateExclusiveLock); + heapId = indexRel->rd_index->indrelid; + index_close(indexRel, NoLock); + + /* Perform concurrent build of new index */ + index_concurrently_build(heapId, newIndexId); + PopActiveSnapshot(); CommitTransactionCommand(); } StartTransactionCommand(); + /* + * Phase 3 of REINDEX CONCURRENTLY + * + * During this phase the old indexes catch up with any new tuples that + * were created during the previous phase. See "phase 3" in DefineIndex() + * for more details. + */ + + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_2); + WaitForLockersMultiple(lockTags, ShareLock, true); + CommitTransactionCommand(); + + foreach(lc, newIndexIds) + { + Oid newIndexId = lfirst_oid(lc); + Oid heapId; + TransactionId limitXmin; + Snapshot snapshot; + + CHECK_FOR_INTERRUPTS(); + + StartTransactionCommand(); + + heapId = IndexGetRelation(newIndexId, false); + + /* + * Take the "reference snapshot" that will be used by validate_index() + * to filter candidate tuples. + */ + snapshot = RegisterSnapshot(GetTransactionSnapshot()); + PushActiveSnapshot(snapshot); + + validate_index(heapId, newIndexId, snapshot); + + /* + * We can now do away with our active snapshot, we still need to save + * the xmin limit to wait for older snapshots. + */ + limitXmin = snapshot->xmin; + + PopActiveSnapshot(); + UnregisterSnapshot(snapshot); + + /* + * To ensure no deadlocks, we must commit and start yet another + * transaction, and do our wait before any snapshot has been taken in + * it. + */ + CommitTransactionCommand(); + StartTransactionCommand(); + + /* + * The index is now valid in the sense that it contains all currently + * interesting tuples. But since it might not contain tuples deleted + * just before the reference snap was taken, we have to wait out any + * transactions that might have older snapshots. + */ + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_3); + WaitForOlderSnapshots(limitXmin, true); + + CommitTransactionCommand(); + } + + /* + * Phase 4 of REINDEX CONCURRENTLY + * + * Now that the new indexes have been validated, swap each new index with + * its corresponding old index. + * + * We mark the new indexes as valid and the old indexes as not valid at + * the same time to make sure we only get constraint violations from the + * indexes with the correct names. + */ + + StartTransactionCommand(); + + forboth(lc, indexIds, lc2, newIndexIds) + { + char *oldName; + Oid oldIndexId = lfirst_oid(lc); + Oid newIndexId = lfirst_oid(lc2); + Oid heapId; + + CHECK_FOR_INTERRUPTS(); + + heapId = IndexGetRelation(oldIndexId, false); + + /* Choose a relation name for old index */ + oldName = ChooseRelationName(get_rel_name(oldIndexId), + NULL, + "ccold", + get_rel_namespace(heapId), + false); + + /* + * Swap old index with the new one. This also marks the new one as + * valid and the old one as not valid. + */ + index_concurrently_swap(newIndexId, oldIndexId, oldName); + + /* + * Invalidate the relcache for the table, so that after this commit + * all sessions will refresh any cached plans that might reference the + * index. + */ + CacheInvalidateRelcacheByRelid(heapId); + + /* + * CCI here so that subsequent iterations see the oldName in the + * catalog and can choose a nonconflicting name for their oldName. + * Otherwise, this could lead to conflicts if a table has two indexes + * whose names are equal for the first NAMEDATALEN-minus-a-few + * characters. + */ + CommandCounterIncrement(); + } + + /* Commit this transaction and make index swaps visible */ + CommitTransactionCommand(); + StartTransactionCommand(); + + /* + * Phase 5 of REINDEX CONCURRENTLY + * + * Mark the old indexes as dead. First we must wait until no running + * transaction could be using the index for a query. See also + * index_drop() for more details. + */ + + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_4); + WaitForLockersMultiple(lockTags, AccessExclusiveLock, true); + + foreach(lc, indexIds) + { + Oid oldIndexId = lfirst_oid(lc); + Oid heapId; + + CHECK_FOR_INTERRUPTS(); + heapId = IndexGetRelation(oldIndexId, false); + index_concurrently_set_dead(heapId, oldIndexId); + } + + /* Commit this transaction to make the updates visible. */ + CommitTransactionCommand(); + StartTransactionCommand(); + + /* + * Phase 6 of REINDEX CONCURRENTLY + * + * Drop the old indexes. + */ + + pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE, + PROGRESS_CREATEIDX_PHASE_WAIT_4); + WaitForLockersMultiple(lockTags, AccessExclusiveLock, true); + + PushActiveSnapshot(GetTransactionSnapshot()); + + { + ObjectAddresses *objects = new_object_addresses(); + + foreach(lc, indexIds) + { + Oid oldIndexId = lfirst_oid(lc); + ObjectAddress object; + + object.classId = RelationRelationId; + object.objectId = oldIndexId; + object.objectSubId = 0; + + add_exact_object_address(&object, objects); + } + + /* + * Use PERFORM_DELETION_CONCURRENT_LOCK so that index_drop() uses the + * right lock level. + */ + performMultipleDeletions(objects, DROP_RESTRICT, + PERFORM_DELETION_CONCURRENT_LOCK | PERFORM_DELETION_INTERNAL); + } + + PopActiveSnapshot(); + CommitTransactionCommand(); + + /* + * Finally, release the session-level lock on the table. + */ + foreach(lc, relationLocks) + { + LockRelId *lockrelid = (LockRelId *) lfirst(lc); + + UnlockRelationIdForSession(lockrelid, ShareUpdateExclusiveLock); + } + + /* Start a new transaction to finish process properly */ + StartTransactionCommand(); + + /* Log what we did */ + if (options & REINDEXOPT_VERBOSE) + { + if (relkind == RELKIND_INDEX) + ereport(INFO, + (errmsg("index \"%s.%s\" was reindexed", + relationNamespace, relationName), + errdetail("%s.", + pg_rusage_show(&ru0)))); + else + { + foreach(lc, newIndexIds) + { + Oid indOid = lfirst_oid(lc); + + ereport(INFO, + (errmsg("index \"%s.%s\" was reindexed", + get_namespace_name(get_rel_namespace(indOid)), + get_rel_name(indOid)))); + /* Don't show rusage here, since it's not per index. */ + } + + ereport(INFO, + (errmsg("table \"%s.%s\" was reindexed", + relationNamespace, relationName), + errdetail("%s.", + pg_rusage_show(&ru0)))); + } + } + MemoryContextDelete(private_context); + + pgstat_progress_end_command(); + + return true; } /* @@ -2432,8 +3337,8 @@ void IndexSetParentIndex(Relation partitionIdx, Oid parentOid) { Relation pg_inherits; - ScanKeyData key[2]; - SysScanDesc scan; + ScanKeyData key[2]; + SysScanDesc scan; Oid partRelid = RelationGetRelid(partitionIdx); HeapTuple tuple; bool fix_dependencies; @@ -2463,15 +3368,15 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) if (parentOid == InvalidOid) { /* - * No pg_inherits row, and no parent wanted: nothing to do in - * this case. + * No pg_inherits row, and no parent wanted: nothing to do in this + * case. */ fix_dependencies = false; } else { - Datum values[Natts_pg_inherits]; - bool isnull[Natts_pg_inherits]; + Datum values[Natts_pg_inherits]; + bool isnull[Natts_pg_inherits]; /* * No pg_inherits row exists, and we want a parent for this index, @@ -2492,7 +3397,7 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) } else { - Form_pg_inherits inhForm = (Form_pg_inherits) GETSTRUCT(tuple); + Form_pg_inherits inhForm = (Form_pg_inherits) GETSTRUCT(tuple); if (parentOid == InvalidOid) { @@ -2525,40 +3430,67 @@ IndexSetParentIndex(Relation partitionIdx, Oid parentOid) systable_endscan(scan); relation_close(pg_inherits, RowExclusiveLock); + /* set relhassubclass if an index partition has been added to the parent */ + if (OidIsValid(parentOid)) + SetRelationHasSubclass(parentOid, true); + + /* set relispartition correctly on the partition */ + update_relispartition(partRelid, OidIsValid(parentOid)); + if (fix_dependencies) { - ObjectAddress partIdx; - /* - * Insert/delete pg_depend rows. If setting a parent, add an - * INTERNAL_AUTO dependency to the parent index; if making standalone, - * remove all existing rows and put back the regular dependency on the - * table. + * Insert/delete pg_depend rows. If setting a parent, add PARTITION + * dependencies on the parent index and the table; if removing a + * parent, delete PARTITION dependencies. */ - ObjectAddressSet(partIdx, RelationRelationId, partRelid); - if (OidIsValid(parentOid)) { - ObjectAddress parentIdx; + ObjectAddress partIdx; + ObjectAddress parentIdx; + ObjectAddress partitionTbl; + ObjectAddressSet(partIdx, RelationRelationId, partRelid); ObjectAddressSet(parentIdx, RelationRelationId, parentOid); - recordDependencyOn(&partIdx, &parentIdx, DEPENDENCY_INTERNAL_AUTO); + ObjectAddressSet(partitionTbl, RelationRelationId, + partitionIdx->rd_index->indrelid); + recordDependencyOn(&partIdx, &parentIdx, + DEPENDENCY_PARTITION_PRI); + recordDependencyOn(&partIdx, &partitionTbl, + DEPENDENCY_PARTITION_SEC); } else { - ObjectAddress partitionTbl; - - ObjectAddressSet(partitionTbl, RelationRelationId, - partitionIdx->rd_index->indrelid); - deleteDependencyRecordsForClass(RelationRelationId, partRelid, RelationRelationId, - DEPENDENCY_INTERNAL_AUTO); - - recordDependencyOn(&partIdx, &partitionTbl, DEPENDENCY_AUTO); + DEPENDENCY_PARTITION_PRI); + deleteDependencyRecordsForClass(RelationRelationId, partRelid, + RelationRelationId, + DEPENDENCY_PARTITION_SEC); } /* make our updates visible */ CommandCounterIncrement(); } } + +/* + * Subroutine of IndexSetParentIndex to update the relispartition flag of the + * given index to the given value. + */ +static void +update_relispartition(Oid relationId, bool newval) +{ + HeapTuple tup; + Relation classRel; + + classRel = table_open(RelationRelationId, RowExclusiveLock); + tup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for relation %u", relationId); + Assert(((Form_pg_class) GETSTRUCT(tup))->relispartition != newval); + ((Form_pg_class) GETSTRUCT(tup))->relispartition = newval; + CatalogTupleUpdate(classRel, &tup->t_self, tup); + heap_freetuple(tup); + table_close(classRel, RowExclusiveLock); +} diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index 6daf8e9b453..bae3b38f778 100644 --- a/src/backend/commands/lockcmds.c +++ b/src/backend/commands/lockcmds.c @@ -3,7 +3,7 @@ * lockcmds.c * LOCK command support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,6 +14,8 @@ */ #include "postgres.h" +#include "access/table.h" +#include "access/xact.h" #include "catalog/namespace.h" #include "catalog/pg_inherits.h" #include "commands/lockcmds.h" @@ -24,14 +26,13 @@ #include "utils/lsyscache.h" #include "utils/syscache.h" #include "rewrite/rewriteHandler.h" -#include "access/heapam.h" #include "nodes/nodeFuncs.h" static void LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, Oid userid); static AclResult LockTableAclCheck(Oid relid, LOCKMODE lockmode, Oid userid); static void RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, - Oid oldrelid, void *arg); -static void LockViewRecurse(Oid reloid, Oid root_reloid, LOCKMODE lockmode, bool nowait); + Oid oldrelid, void *arg); +static void LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views); /* * LOCK TABLE @@ -67,7 +68,7 @@ LockTableCommand(LockStmt *lockstmt) (void *) &lockstmt->mode); if (get_rel_relkind(reloid) == RELKIND_VIEW) - LockViewRecurse(reloid, reloid, lockstmt->mode, lockstmt->nowait); + LockViewRecurse(reloid, lockstmt->mode, lockstmt->nowait, NIL); else if (recurse) LockTableRecurse(reloid, lockstmt->mode, lockstmt->nowait, GetUserId()); } @@ -83,6 +84,7 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid, { LOCKMODE lockmode = *(LOCKMODE *) arg; char relkind; + char relpersistence; AclResult aclresult; if (!OidIsValid(relid)) @@ -92,15 +94,22 @@ RangeVarCallbackForLockTable(const RangeVar *rv, Oid relid, Oid oldrelid, return; /* woops, concurrently dropped; no permissions * check */ - /* Currently, we only allow plain tables or views to be locked */ if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE && relkind != RELKIND_VIEW) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table or a view", + errmsg("\"%s\" is not a table or view", rv->relname))); + /* + * Make note if a temporary relation has been accessed in this + * transaction. + */ + relpersistence = get_rel_persistence(relid); + if (relpersistence == RELPERSISTENCE_TEMP) + MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE; + /* Check permissions. */ aclresult = LockTableAclCheck(relid, lockmode, GetUserId()); if (aclresult != ACLCHECK_OK) @@ -178,11 +187,11 @@ LockTableRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, Oid userid) typedef struct { - Oid root_reloid; - LOCKMODE lockmode; - bool nowait; - Oid viewowner; - Oid viewoid; + LOCKMODE lockmode; /* lock mode to use */ + bool nowait; /* no wait mode */ + Oid viewowner; /* view owner for checking the privilege */ + Oid viewoid; /* OID of the view to be locked */ + List *ancestor_views; /* OIDs of ancestor views */ } LockViewRecurse_context; static bool @@ -193,21 +202,25 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) if (IsA(node, Query)) { - Query *query = (Query *) node; - ListCell *rtable; + Query *query = (Query *) node; + ListCell *rtable; foreach(rtable, query->rtable) { - RangeTblEntry *rte = lfirst(rtable); - AclResult aclresult; + RangeTblEntry *rte = lfirst(rtable); + AclResult aclresult; - Oid relid = rte->relid; - char relkind = rte->relkind; - char *relname = get_rel_name(relid); + Oid relid = rte->relid; + char relkind = rte->relkind; + char *relname = get_rel_name(relid); - /* The OLD and NEW placeholder entries in the view's rtable are skipped. */ + /* + * The OLD and NEW placeholder entries in the view's rtable are + * skipped. + */ if (relid == context->viewoid && - (!strcmp(rte->eref->aliasname, "old") || !strcmp(rte->eref->aliasname, "new"))) + (strcmp(rte->eref->aliasname, "old") == 0 || + strcmp(rte->eref->aliasname, "new") == 0)) continue; /* Currently, we only allow plain tables or views to be locked. */ @@ -216,11 +229,11 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) continue; /* Check infinite recursion in the view definition. */ - if (relid == context->root_reloid) + if (list_member_oid(context->ancestor_views, relid)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("infinite recursion detected in rules for relation \"%s\"", - get_rel_name(context->root_reloid)))); + errmsg("infinite recursion detected in rules for relation \"%s\"", + get_rel_name(relid)))); /* Check permissions with the view owner's privilege. */ aclresult = LockTableAclCheck(relid, context->lockmode, context->viewowner); @@ -233,11 +246,11 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) else if (!ConditionalLockRelationOid(relid, context->lockmode)) ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), - errmsg("could not obtain lock on relation \"%s\"", + errmsg("could not obtain lock on relation \"%s\"", relname))); if (relkind == RELKIND_VIEW) - LockViewRecurse(relid, context->root_reloid, context->lockmode, context->nowait); + LockViewRecurse(relid, context->lockmode, context->nowait, context->ancestor_views); else if (rte->inh) LockTableRecurse(relid, context->lockmode, context->nowait, context->viewowner); } @@ -254,25 +267,27 @@ LockViewRecurse_walker(Node *node, LockViewRecurse_context *context) } static void -LockViewRecurse(Oid reloid, Oid root_reloid, LOCKMODE lockmode, bool nowait) +LockViewRecurse(Oid reloid, LOCKMODE lockmode, bool nowait, List *ancestor_views) { LockViewRecurse_context context; - Relation view; - Query *viewquery; + Relation view; + Query *viewquery; - view = heap_open(reloid, NoLock); + view = table_open(reloid, NoLock); viewquery = get_view_query(view); - context.root_reloid = root_reloid; context.lockmode = lockmode; context.nowait = nowait; context.viewowner = view->rd_rel->relowner; context.viewoid = reloid; + context.ancestor_views = lappend_oid(ancestor_views, reloid); LockViewRecurse_walker((Node *) viewquery, &context); - heap_close(view, NoLock); + (void) list_delete_last(context.ancestor_views); + + table_close(view, NoLock); } /* diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c index e1eb7c374b8..537d0e8ceff 100644 --- a/src/backend/commands/matview.c +++ b/src/backend/commands/matview.c @@ -3,7 +3,7 @@ * matview.c * materialized view support * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,11 @@ */ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" @@ -51,7 +54,7 @@ typedef struct /* These fields are filled by transientrel_startup: */ Relation transientrel; /* relation to write to */ CommandId output_cid; /* cmin to insert in output tuples */ - int hi_options; /* heap_insert performance options */ + int ti_options; /* table_tuple_insert performance options */ BulkInsertState bistate; /* bulk insert state */ } DR_transientrel; @@ -62,10 +65,10 @@ static bool transientrel_receive(TupleTableSlot *slot, DestReceiver *self); static void transientrel_shutdown(DestReceiver *self); static void transientrel_destroy(DestReceiver *self); static uint64 refresh_matview_datafill(DestReceiver *dest, Query *query, - const char *queryString); + const char *queryString); static char *make_temptable_name_n(char *tempname, int n); static void refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, - int save_sec_context); + int save_sec_context); static void refresh_by_heap_swap(Oid matviewOid, Oid OIDNewHeap, char relpersistence); static bool is_usable_unique_index(Relation indexRel); static void OpenMatViewIncrementalMaintenance(void); @@ -90,7 +93,7 @@ SetMatViewPopulatedState(Relation relation, bool newstate) * (and this one too!) are sent SI message to make them rebuild relcache * entries. */ - pgrel = heap_open(RelationRelationId, RowExclusiveLock); + pgrel = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(relation))); if (!HeapTupleIsValid(tuple)) @@ -102,7 +105,7 @@ SetMatViewPopulatedState(Relation relation, bool newstate) CatalogTupleUpdate(pgrel, &tuple->t_self, tuple); heap_freetuple(tuple); - heap_close(pgrel, RowExclusiveLock); + table_close(pgrel, RowExclusiveLock); /* * Advance command counter to make the updated pg_class row locally @@ -163,7 +166,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, matviewOid = RangeVarGetRelidExtended(stmt->relation, lockmode, 0, RangeVarCallbackOwnsTable, NULL); - matviewRel = heap_open(matviewOid, NoLock); + matviewRel = table_open(matviewOid, NoLock); /* Make sure it is a materialized view. */ if (matviewRel->rd_rel->relkind != RELKIND_MATVIEW) @@ -184,9 +187,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("CONCURRENTLY and WITH NO DATA options cannot be used together"))); - /* We don't allow an oid column for a materialized view. */ - Assert(!matviewRel->rd_rel->relhasoids); - /* * Check that everything is correct for a refresh. Problems at this point * are internal errors, so elog is sufficient. @@ -258,7 +258,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, * as open scans. * * NB: We count on this to protect us against problems with refreshing the - * data using HEAP_INSERT_FROZEN. + * data using TABLE_INSERT_FROZEN. */ CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW"); @@ -284,7 +284,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, /* Concurrent refresh builds new data in temp tablespace, and does diff. */ if (concurrent) { - tableSpace = GetDefaultTablespace(RELPERSISTENCE_TEMP); + tableSpace = GetDefaultTablespace(RELPERSISTENCE_TEMP, false); relpersistence = RELPERSISTENCE_TEMP; } else @@ -346,7 +346,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, pgstat_count_heap_insert(matviewRel, processed); } - heap_close(matviewRel, NoLock); + table_close(matviewRel, NoLock); /* Roll back any GUC changes */ AtEOXact_GUC(false, save_nestlevel); @@ -408,7 +408,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query, dest, NULL, NULL, 0); /* call ExecutorStart to prepare the plan for execution */ - ExecutorStart(queryDesc, EXEC_FLAG_WITHOUT_OIDS); + ExecutorStart(queryDesc, 0); /* run the plan */ ExecutorRun(queryDesc, ForwardScanDirection, 0L, true); @@ -450,7 +450,7 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) DR_transientrel *myState = (DR_transientrel *) self; Relation transientrel; - transientrel = heap_open(myState->transientoid, NoLock); + transientrel = table_open(myState->transientoid, NoLock); /* * Fill private fields of myState for use by later routines @@ -462,9 +462,9 @@ transientrel_startup(DestReceiver *self, int operation, TupleDesc typeinfo) * We can skip WAL-logging the insertions, unless PITR or streaming * replication is in use. We can skip the FSM in any case. */ - myState->hi_options = HEAP_INSERT_SKIP_FSM | HEAP_INSERT_FROZEN; + myState->ti_options = TABLE_INSERT_SKIP_FSM | TABLE_INSERT_FROZEN; if (!XLogIsNeeded()) - myState->hi_options |= HEAP_INSERT_SKIP_WAL; + myState->ti_options |= TABLE_INSERT_SKIP_WAL; myState->bistate = GetBulkInsertState(); /* Not using WAL requires smgr_targblock be initially invalid */ @@ -478,19 +478,21 @@ static bool transientrel_receive(TupleTableSlot *slot, DestReceiver *self) { DR_transientrel *myState = (DR_transientrel *) self; - HeapTuple tuple; /* - * get the heap tuple out of the tuple table slot, making sure we have a - * writable copy + * Note that the input slot might not be of the type of the target + * relation. That's supported by table_tuple_insert(), but slightly less + * efficient than inserting with the right slot - but the alternative + * would be to copy into a slot of the right type, which would not be + * cheap either. This also doesn't allow accessing per-AM data (say a + * tuple's xmin), but since we don't do that here... */ - tuple = ExecMaterializeSlot(slot); - heap_insert(myState->transientrel, - tuple, - myState->output_cid, - myState->hi_options, - myState->bistate); + table_tuple_insert(myState->transientrel, + slot, + myState->output_cid, + myState->ti_options, + myState->bistate); /* We know this is a newly created relation, so there are no indexes */ @@ -507,12 +509,10 @@ transientrel_shutdown(DestReceiver *self) FreeBulkInsertState(myState->bistate); - /* If we skipped using WAL, must heap_sync before commit */ - if (myState->hi_options & HEAP_INSERT_SKIP_WAL) - heap_sync(myState->transientrel); + table_finish_bulk_insert(myState->transientrel, myState->ti_options); /* close transientrel, but keep lock until commit */ - heap_close(myState->transientrel, NoLock); + table_close(myState->transientrel, NoLock); myState->transientrel = NULL; } @@ -594,10 +594,10 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, Oid *opUsedForQual; initStringInfo(&querybuf); - matviewRel = heap_open(matviewOid, NoLock); + matviewRel = table_open(matviewOid, NoLock); matviewname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(matviewRel)), RelationGetRelationName(matviewRel)); - tempRel = heap_open(tempOid, NoLock); + tempRel = table_open(tempOid, NoLock); tempname = quote_qualified_identifier(get_namespace_name(RelationGetNamespace(tempRel)), RelationGetRelationName(tempRel)); diffname = make_temptable_name_n(tempname, 2); @@ -825,8 +825,8 @@ refresh_by_match_merge(Oid matviewOid, Oid tempOid, Oid relowner, /* We're done maintaining the materialized view. */ CloseMatViewIncrementalMaintenance(); - heap_close(tempRel, NoLock); - heap_close(matviewRel, NoLock); + table_close(tempRel, NoLock); + table_close(matviewRel, NoLock); /* Clean up temp tables. */ resetStringInfo(&querybuf); @@ -870,7 +870,7 @@ is_usable_unique_index(Relation indexRel) if (indexStruct->indisunique && indexStruct->indimmediate && indexRel->rd_rel->relam == BTREE_AM_OID && - IndexIsValid(indexStruct) && + indexStruct->indisvalid && RelationGetIndexPredicate(indexRel) == NIL && indexStruct->indnatts > 0) { diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index e4b1369f193..6a1ccdeb826 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -4,7 +4,7 @@ * * Routines for opclass (and opfamily) manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,10 +19,11 @@ #include "access/genam.h" #include "access/hash.h" -#include "access/heapam.h" #include "access/nbtree.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -48,31 +49,30 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" static void AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, - Oid amoid, Oid opfamilyoid, - int maxOpNumber, int maxProcNumber, - List *items); + Oid amoid, Oid opfamilyoid, + int maxOpNumber, int maxProcNumber, + List *items); static void AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, - Oid amoid, Oid opfamilyoid, - int maxOpNumber, int maxProcNumber, - List *items); + Oid amoid, Oid opfamilyoid, + int maxOpNumber, int maxProcNumber, + List *items); static void processTypesSpec(List *args, Oid *lefttype, Oid *righttype); static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid); static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid); static void addFamilyMember(List **list, OpFamilyMember *member, bool isProc); static void storeOperators(List *opfamilyname, Oid amoid, - Oid opfamilyoid, Oid opclassoid, - List *operators, bool isAdd); + Oid opfamilyoid, Oid opclassoid, + List *operators, bool isAdd); static void storeProcedures(List *opfamilyname, Oid amoid, - Oid opfamilyoid, Oid opclassoid, - List *procedures, bool isAdd); + Oid opfamilyoid, Oid opclassoid, + List *procedures, bool isAdd); static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, - List *operators); + List *operators); static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, - List *procedures); + List *procedures); /* * OpFamilyCacheLookup @@ -142,12 +142,14 @@ Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok) { HeapTuple htup; + Form_pg_opfamily opfamform; Oid opfID; htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok); if (!HeapTupleIsValid(htup)) return InvalidOid; - opfID = HeapTupleGetOid(htup); + opfamform = (Form_pg_opfamily) GETSTRUCT(htup); + opfID = opfamform->oid; ReleaseSysCache(htup); return opfID; @@ -221,12 +223,14 @@ Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok) { HeapTuple htup; + Form_pg_opclass opcform; Oid opcID; htup = OpClassCacheLookup(amID, opclassname, missing_ok); if (!HeapTupleIsValid(htup)) return InvalidOid; - opcID = HeapTupleGetOid(htup); + opcform = (Form_pg_opclass) GETSTRUCT(htup); + opcID = opcform->oid; ReleaseSysCache(htup); return opcID; @@ -250,7 +254,7 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am ObjectAddress myself, referenced; - rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock); + rel = table_open(OperatorFamilyRelationId, RowExclusiveLock); /* * Make sure there is no existing opfamily of this name (this is just to @@ -271,6 +275,9 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId, + Anum_pg_opfamily_oid); + values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid); values[Anum_pg_opfamily_opfmethod - 1] = ObjectIdGetDatum(amoid); namestrcpy(&opfName, opfname); values[Anum_pg_opfamily_opfname - 1] = NameGetDatum(&opfName); @@ -279,7 +286,7 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am tup = heap_form_tuple(rel->rd_att, values, nulls); - opfamilyoid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); @@ -311,7 +318,7 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am /* Post creation hook for new operator family */ InvokeObjectPostCreateHook(OperatorFamilyRelationId, opfamilyoid, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -338,6 +345,7 @@ DefineOpClass(CreateOpClassStmt *stmt) ListCell *l; Relation rel; HeapTuple tup; + Form_pg_am amform; IndexAmRoutine *amroutine; Datum values[Natts_pg_opclass]; bool nulls[Natts_pg_opclass]; @@ -364,7 +372,8 @@ DefineOpClass(CreateOpClassStmt *stmt) errmsg("access method \"%s\" does not exist", stmt->amname))); - amoid = HeapTupleGetOid(tup); + amform = (Form_pg_am) GETSTRUCT(tup); + amoid = amform->oid; amroutine = GetIndexAmRoutineByAmId(amoid, false); ReleaseSysCache(tup); @@ -429,7 +438,7 @@ DefineOpClass(CreateOpClassStmt *stmt) ObjectIdGetDatum(namespaceoid)); if (HeapTupleIsValid(tup)) { - opfamilyoid = HeapTupleGetOid(tup); + opfamilyoid = ((Form_pg_opfamily) GETSTRUCT(tup))->oid; /* * XXX given the superuser check above, there's no need for an @@ -517,7 +526,7 @@ DefineOpClass(CreateOpClassStmt *stmt) if (item->number <= 0 || item->number > maxProcNumber) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("invalid procedure number %d," + errmsg("invalid function number %d," " must be between 1 and %d", item->number, maxProcNumber))); funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false); @@ -577,7 +586,7 @@ DefineOpClass(CreateOpClassStmt *stmt) stmt->amname))); } - rel = heap_open(OperatorClassRelationId, RowExclusiveLock); + rel = table_open(OperatorClassRelationId, RowExclusiveLock); /* * Make sure there is no existing opclass of this name (this is just to @@ -633,6 +642,9 @@ DefineOpClass(CreateOpClassStmt *stmt) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId, + Anum_pg_opclass_oid); + values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid); values[Anum_pg_opclass_opcmethod - 1] = ObjectIdGetDatum(amoid); namestrcpy(&opcName, opcname); values[Anum_pg_opclass_opcname - 1] = NameGetDatum(&opcName); @@ -645,7 +657,7 @@ DefineOpClass(CreateOpClassStmt *stmt) tup = heap_form_tuple(rel->rd_att, values, nulls); - opclassoid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); @@ -705,7 +717,7 @@ DefineOpClass(CreateOpClassStmt *stmt) /* Post creation hook for new operator class */ InvokeObjectPostCreateHook(OperatorClassRelationId, opclassoid, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -768,6 +780,7 @@ AlterOpFamily(AlterOpFamilyStmt *stmt) int maxOpNumber, /* amstrategies value */ maxProcNumber; /* amsupport value */ HeapTuple tup; + Form_pg_am amform; IndexAmRoutine *amroutine; /* Get necessary info about access method */ @@ -778,7 +791,8 @@ AlterOpFamily(AlterOpFamilyStmt *stmt) errmsg("access method \"%s\" does not exist", stmt->amname))); - amoid = HeapTupleGetOid(tup); + amform = (Form_pg_am) GETSTRUCT(tup); + amoid = amform->oid; amroutine = GetIndexAmRoutineByAmId(amoid, false); ReleaseSysCache(tup); @@ -891,7 +905,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, if (item->number <= 0 || item->number > maxProcNumber) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("invalid procedure number %d," + errmsg("invalid function number %d," " must be between 1 and %d", item->number, maxProcNumber))); funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false); @@ -986,7 +1000,7 @@ AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid, if (item->number <= 0 || item->number > maxProcNumber) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("invalid procedure number %d," + errmsg("invalid function number %d," " must be between 1 and %d", item->number, maxProcNumber))); processTypesSpec(item->class_args, &lefttype, &righttype); @@ -1057,7 +1071,7 @@ assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) /* Fetch the operator definition */ optup = SearchSysCache1(OPEROID, ObjectIdGetDatum(member->object)); - if (optup == NULL) + if (!HeapTupleIsValid(optup)) elog(ERROR, "cache lookup failed for operator %u", member->object); opform = (Form_pg_operator) GETSTRUCT(optup); @@ -1123,7 +1137,7 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) /* Fetch the procedure definition */ proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(member->object)); - if (proctup == NULL) + if (!HeapTupleIsValid(proctup)) elog(ERROR, "cache lookup failed for function %u", member->object); procform = (Form_pg_proc) GETSTRUCT(proctup); @@ -1141,11 +1155,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) if (procform->pronargs != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree comparison procedures must have two arguments"))); + errmsg("btree comparison functions must have two arguments"))); if (procform->prorettype != INT4OID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree comparison procedures must return integer"))); + errmsg("btree comparison functions must return integer"))); /* * If lefttype/righttype isn't specified, use the proc's input @@ -1162,11 +1176,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) procform->proargtypes.values[0] != INTERNALOID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree sort support procedures must accept type \"internal\""))); + errmsg("btree sort support functions must accept type \"internal\""))); if (procform->prorettype != VOIDOID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree sort support procedures must return void"))); + errmsg("btree sort support functions must return void"))); /* * Can't infer lefttype/righttype from proc, so use default rule @@ -1177,11 +1191,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) if (procform->pronargs != 5) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree in_range procedures must have five arguments"))); + errmsg("btree in_range functions must have five arguments"))); if (procform->prorettype != BOOLOID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("btree in_range procedures must return boolean"))); + errmsg("btree in_range functions must return boolean"))); /* * If lefttype/righttype isn't specified, use the proc's input @@ -1200,22 +1214,22 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) if (procform->pronargs != 1) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("hash procedure 1 must have one argument"))); + errmsg("hash function 1 must have one argument"))); if (procform->prorettype != INT4OID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("hash procedure 1 must return integer"))); + errmsg("hash function 1 must return integer"))); } else if (member->number == HASHEXTENDED_PROC) { if (procform->pronargs != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("hash procedure 2 must have two arguments"))); + errmsg("hash function 2 must have two arguments"))); if (procform->prorettype != INT8OID) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("hash procedure 2 must return bigint"))); + errmsg("hash function 2 must return bigint"))); } /* @@ -1240,7 +1254,7 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid) if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("associated data types must be specified for index support procedure"))); + errmsg("associated data types must be specified for index support function"))); ReleaseSysCache(proctup); } @@ -1265,7 +1279,7 @@ addFamilyMember(List **list, OpFamilyMember *member, bool isProc) if (isProc) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("procedure number %d for (%s,%s) appears more than once", + errmsg("function number %d for (%s,%s) appears more than once", member->number, format_type_be(member->lefttype), format_type_be(member->righttype)))); @@ -1302,7 +1316,7 @@ storeOperators(List *opfamilyname, Oid amoid, referenced; ListCell *l; - rel = heap_open(AccessMethodOperatorRelationId, RowExclusiveLock); + rel = table_open(AccessMethodOperatorRelationId, RowExclusiveLock); foreach(l, operators) { @@ -1333,6 +1347,9 @@ storeOperators(List *opfamilyname, Oid amoid, memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId, + Anum_pg_amop_oid); + values[Anum_pg_amop_oid - 1] = ObjectIdGetDatum(entryoid); values[Anum_pg_amop_amopfamily - 1] = ObjectIdGetDatum(opfamilyoid); values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype); values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype); @@ -1344,7 +1361,7 @@ storeOperators(List *opfamilyname, Oid amoid, tup = heap_form_tuple(rel->rd_att, values, nulls); - entryoid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); @@ -1393,7 +1410,7 @@ storeOperators(List *opfamilyname, Oid amoid, entryoid, 0); } - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -1417,7 +1434,7 @@ storeProcedures(List *opfamilyname, Oid amoid, referenced; ListCell *l; - rel = heap_open(AccessMethodProcedureRelationId, RowExclusiveLock); + rel = table_open(AccessMethodProcedureRelationId, RowExclusiveLock); foreach(l, procedures) { @@ -1445,6 +1462,9 @@ storeProcedures(List *opfamilyname, Oid amoid, memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId, + Anum_pg_amproc_oid); + values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid); values[Anum_pg_amproc_amprocfamily - 1] = ObjectIdGetDatum(opfamilyoid); values[Anum_pg_amproc_amproclefttype - 1] = ObjectIdGetDatum(proc->lefttype); values[Anum_pg_amproc_amprocrighttype - 1] = ObjectIdGetDatum(proc->righttype); @@ -1453,7 +1473,7 @@ storeProcedures(List *opfamilyname, Oid amoid, tup = heap_form_tuple(rel->rd_att, values, nulls); - entryoid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); @@ -1493,7 +1513,7 @@ storeProcedures(List *opfamilyname, Oid amoid, entryoid, 0); } - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -1515,7 +1535,7 @@ dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, Oid amopid; ObjectAddress object; - amopid = GetSysCacheOid4(AMOPSTRATEGY, + amopid = GetSysCacheOid4(AMOPSTRATEGY, Anum_pg_amop_oid, ObjectIdGetDatum(opfamilyoid), ObjectIdGetDatum(op->lefttype), ObjectIdGetDatum(op->righttype), @@ -1555,7 +1575,7 @@ dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, Oid amprocid; ObjectAddress object; - amprocid = GetSysCacheOid4(AMPROCNUM, + amprocid = GetSysCacheOid4(AMPROCNUM, Anum_pg_amproc_oid, ObjectIdGetDatum(opfamilyoid), ObjectIdGetDatum(op->lefttype), ObjectIdGetDatum(op->righttype), @@ -1586,7 +1606,7 @@ RemoveOpFamilyById(Oid opfamilyOid) Relation rel; HeapTuple tup; - rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock); + rel = table_open(OperatorFamilyRelationId, RowExclusiveLock); tup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1596,7 +1616,7 @@ RemoveOpFamilyById(Oid opfamilyOid) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } void @@ -1605,7 +1625,7 @@ RemoveOpClassById(Oid opclassOid) Relation rel; HeapTuple tup; - rel = heap_open(OperatorClassRelationId, RowExclusiveLock); + rel = table_open(OperatorClassRelationId, RowExclusiveLock); tup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclassOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -1615,7 +1635,7 @@ RemoveOpClassById(Oid opclassOid) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } void @@ -1627,11 +1647,11 @@ RemoveAmOpEntryById(Oid entryOid) SysScanDesc scan; ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amop_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(entryOid)); - rel = heap_open(AccessMethodOperatorRelationId, RowExclusiveLock); + rel = table_open(AccessMethodOperatorRelationId, RowExclusiveLock); scan = systable_beginscan(rel, AccessMethodOperatorOidIndexId, true, NULL, 1, skey); @@ -1644,7 +1664,7 @@ RemoveAmOpEntryById(Oid entryOid) CatalogTupleDelete(rel, &tup->t_self); systable_endscan(scan); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } void @@ -1656,11 +1676,11 @@ RemoveAmProcEntryById(Oid entryOid) SysScanDesc scan; ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_amproc_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(entryOid)); - rel = heap_open(AccessMethodProcedureRelationId, RowExclusiveLock); + rel = table_open(AccessMethodProcedureRelationId, RowExclusiveLock); scan = systable_beginscan(rel, AccessMethodProcedureOidIndexId, true, NULL, 1, skey); @@ -1673,7 +1693,7 @@ RemoveAmProcEntryById(Oid entryOid) CatalogTupleDelete(rel, &tup->t_self); systable_endscan(scan); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index f0da4c52792..d733aa4826b 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -4,7 +4,7 @@ * * Routines for operator manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,21 +21,18 @@ * NOTES * These things must be defined and committed in the following order: * "create function": - * input/output, recv/send procedures + * input/output, recv/send functions * "create type": * type * "create operator": * operators * - * Most of the parse-tree manipulation routines are defined in - * commands/manip.c. - * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -79,8 +76,8 @@ DefineOperator(List *names, List *parameters) Oid rettype; List *commutatorName = NIL; /* optional commutator operator name */ List *negatorName = NIL; /* optional negator operator name */ - List *restrictionName = NIL; /* optional restrict. sel. procedure */ - List *joinName = NIL; /* optional join sel. procedure */ + List *restrictionName = NIL; /* optional restrict. sel. function */ + List *joinName = NIL; /* optional join sel. function */ Oid functionOid; /* functions converted to OID */ Oid restrictionOid; Oid joinOid; @@ -120,6 +117,9 @@ DefineOperator(List *names, List *parameters) (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), errmsg("SETOF type not allowed for operator argument"))); } + /* "function" and "procedure" are equivalent here */ + else if (strcmp(defel->defname, "function") == 0) + functionName = defGetQualifiedName(defel); else if (strcmp(defel->defname, "procedure") == 0) functionName = defGetQualifiedName(defel); else if (strcmp(defel->defname, "commutator") == 0) @@ -159,7 +159,7 @@ DefineOperator(List *names, List *parameters) if (functionName == NIL) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("operator procedure must be specified"))); + errmsg("operator function must be specified"))); /* Transform type names to type OIDs */ if (typeName1) @@ -245,8 +245,8 @@ DefineOperator(List *names, List *parameters) functionOid, /* function for operator */ commutatorName, /* optional commutator operator name */ negatorName, /* optional negator operator name */ - restrictionOid, /* optional restrict. sel. procedure */ - joinOid, /* optional join sel. procedure name */ + restrictionOid, /* optional restrict. sel. function */ + joinOid, /* optional join sel. function name */ canMerge, /* operator merges */ canHash); /* operator hashes */ } @@ -342,7 +342,7 @@ RemoveOperatorById(Oid operOid) HeapTuple tup; Form_pg_operator op; - relation = heap_open(OperatorRelationId, RowExclusiveLock); + relation = table_open(OperatorRelationId, RowExclusiveLock); tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(operOid)); if (!HeapTupleIsValid(tup)) /* should not happen */ @@ -371,7 +371,7 @@ RemoveOperatorById(Oid operOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* @@ -393,18 +393,18 @@ AlterOperator(AlterOperatorStmt *stmt) Datum values[Natts_pg_operator]; bool nulls[Natts_pg_operator]; bool replaces[Natts_pg_operator]; - List *restrictionName = NIL; /* optional restrict. sel. procedure */ + List *restrictionName = NIL; /* optional restrict. sel. function */ bool updateRestriction = false; Oid restrictionOid; - List *joinName = NIL; /* optional join sel. procedure */ + List *joinName = NIL; /* optional join sel. function */ bool updateJoin = false; Oid joinOid; /* Look up the operator */ oprId = LookupOperWithArgs(stmt->opername, false); - catalog = heap_open(OperatorRelationId, RowExclusiveLock); + catalog = table_open(OperatorRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(oprId)); - if (tup == NULL) + if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for operator %u", oprId); oprForm = (Form_pg_operator) GETSTRUCT(tup); @@ -436,6 +436,7 @@ AlterOperator(AlterOperatorStmt *stmt) */ else if (strcmp(defel->defname, "leftarg") == 0 || strcmp(defel->defname, "rightarg") == 0 || + strcmp(defel->defname, "function") == 0 || strcmp(defel->defname, "procedure") == 0 || strcmp(defel->defname, "commutator") == 0 || strcmp(defel->defname, "negator") == 0 || @@ -520,7 +521,7 @@ AlterOperator(AlterOperatorStmt *stmt) InvokeObjectPostAlterHook(OperatorRelationId, oprId, 0); - heap_close(catalog, NoLock); + table_close(catalog, NoLock); return address; } diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c index b2b845613d5..1df76623adb 100644 --- a/src/backend/commands/policy.c +++ b/src/backend/commands/policy.c @@ -3,7 +3,7 @@ * policy.c * Commands for manipulating policies. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/commands/policy.c @@ -13,9 +13,10 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup.h" #include "access/htup_details.h" +#include "access/relation.h" +#include "access/table.h" #include "access/sysattr.h" #include "catalog/catalog.h" #include "catalog/dependency.h" @@ -47,7 +48,7 @@ #include "utils/syscache.h" static void RangeVarCallbackForPolicy(const RangeVar *rv, - Oid relid, Oid oldrelid, void *arg); + Oid relid, Oid oldrelid, void *arg); static char parse_policy_command(const char *cmd_name); static Datum *policy_role_list_to_array(List *roles, int *num_roles); @@ -215,12 +216,12 @@ RelationBuildRowSecurity(Relation relation) HeapTuple tuple; MemoryContextCopyAndSetIdentifier(rscxt, - RelationGetRelationName(relation)); + RelationGetRelationName(relation)); rsdesc = MemoryContextAllocZero(rscxt, sizeof(RowSecurityDesc)); rsdesc->rscxt = rscxt; - catalog = heap_open(PolicyRelationId, AccessShareLock); + catalog = table_open(PolicyRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_policy_polrelid, @@ -327,7 +328,7 @@ RelationBuildRowSecurity(Relation relation) } systable_endscan(sscan); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); } PG_CATCH(); { @@ -359,13 +360,13 @@ RemovePolicyById(Oid policy_id) Oid relid; Relation rel; - pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock); + pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock); /* * Find the policy to delete. */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_policy_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(policy_id)); @@ -386,7 +387,7 @@ RemovePolicyById(Oid policy_id) */ relid = ((Form_pg_policy) GETSTRUCT(tuple))->polrelid; - rel = heap_open(relid, AccessExclusiveLock); + rel = table_open(relid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, @@ -414,10 +415,10 @@ RemovePolicyById(Oid policy_id) */ CacheInvalidateRelcache(rel); - heap_close(rel, NoLock); + table_close(rel, NoLock); /* Clean up */ - heap_close(pg_policy_rel, RowExclusiveLock); + table_close(pg_policy_rel, RowExclusiveLock); } /* @@ -451,13 +452,13 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) Assert(classid == PolicyRelationId); - pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock); + pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock); /* * Find the policy to update. */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_policy_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(policy_id)); @@ -567,7 +568,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) qual_expr = stringToNode(qual_value); /* Add this rel to the parsestate's rangetable, for dependencies */ - addRangeTableEntryForRelation(qual_pstate, rel, NULL, false, false); + addRangeTableEntryForRelation(qual_pstate, rel, + AccessShareLock, + NULL, false, false); qual_parse_rtable = qual_pstate->p_rtable; free_parsestate(qual_pstate); @@ -589,8 +592,9 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) with_check_qual = stringToNode(with_check_value); /* Add this rel to the parsestate's rangetable, for dependencies */ - addRangeTableEntryForRelation(with_check_pstate, rel, NULL, false, - false); + addRangeTableEntryForRelation(with_check_pstate, rel, + AccessShareLock, + NULL, false, false); with_check_parse_rtable = with_check_pstate->p_rtable; free_parsestate(with_check_pstate); @@ -671,7 +675,7 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id) relation_close(rel, NoLock); - heap_close(pg_policy_rel, RowExclusiveLock); + table_close(pg_policy_rel, RowExclusiveLock); return (noperm || num_roles > 0); } @@ -752,11 +756,13 @@ CreatePolicy(CreatePolicyStmt *stmt) /* Add for the regular security quals */ rte = addRangeTableEntryForRelation(qual_pstate, target_table, + AccessShareLock, NULL, false, false); addRTEtoQuery(qual_pstate, rte, false, true, true); /* Add for the with-check quals */ rte = addRangeTableEntryForRelation(with_check_pstate, target_table, + AccessShareLock, NULL, false, false); addRTEtoQuery(with_check_pstate, rte, false, true, true); @@ -775,7 +781,7 @@ CreatePolicy(CreatePolicyStmt *stmt) assign_expr_collations(with_check_pstate, with_check_qual); /* Open pg_policy catalog */ - pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock); + pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock); /* Set key - policy's relation id. */ ScanKeyInit(&skey[0], @@ -802,6 +808,9 @@ CreatePolicy(CreatePolicyStmt *stmt) errmsg("policy \"%s\" for table \"%s\" already exists", stmt->policy_name, RelationGetRelationName(target_table)))); + policy_id = GetNewOidWithIndex(pg_policy_rel, PolicyOidIndexId, + Anum_pg_policy_oid); + values[Anum_pg_policy_oid - 1] = ObjectIdGetDatum(policy_id); values[Anum_pg_policy_polrelid - 1] = ObjectIdGetDatum(table_id); values[Anum_pg_policy_polname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->policy_name)); @@ -824,7 +833,7 @@ CreatePolicy(CreatePolicyStmt *stmt) policy_tuple = heap_form_tuple(RelationGetDescr(pg_policy_rel), values, isnull); - policy_id = CatalogTupleInsert(pg_policy_rel, policy_tuple); + CatalogTupleInsert(pg_policy_rel, policy_tuple); /* Record Dependencies */ target.classId = RelationRelationId; @@ -866,7 +875,7 @@ CreatePolicy(CreatePolicyStmt *stmt) free_parsestate(with_check_pstate); systable_endscan(sscan); relation_close(target_table, NoLock); - heap_close(pg_policy_rel, RowExclusiveLock); + table_close(pg_policy_rel, RowExclusiveLock); return myself; } @@ -928,6 +937,7 @@ AlterPolicy(AlterPolicyStmt *stmt) ParseState *qual_pstate = make_parsestate(NULL); rte = addRangeTableEntryForRelation(qual_pstate, target_table, + AccessShareLock, NULL, false, false); addRTEtoQuery(qual_pstate, rte, false, true, true); @@ -950,6 +960,7 @@ AlterPolicy(AlterPolicyStmt *stmt) ParseState *with_check_pstate = make_parsestate(NULL); rte = addRangeTableEntryForRelation(with_check_pstate, target_table, + AccessShareLock, NULL, false, false); addRTEtoQuery(with_check_pstate, rte, false, true, true); @@ -972,7 +983,7 @@ AlterPolicy(AlterPolicyStmt *stmt) memset(isnull, 0, sizeof(isnull)); /* Find policy to update. */ - pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock); + pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock); /* Set key - policy's relation id. */ ScanKeyInit(&skey[0], @@ -1026,7 +1037,7 @@ AlterPolicy(AlterPolicyStmt *stmt) (errcode(ERRCODE_SYNTAX_ERROR), errmsg("only WITH CHECK expression allowed for INSERT"))); - policy_id = HeapTupleGetOid(policy_tuple); + policy_id = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid; if (role_ids != NULL) { @@ -1096,8 +1107,9 @@ AlterPolicy(AlterPolicyStmt *stmt) qual = stringToNode(qual_value); /* Add this rel to the parsestate's rangetable, for dependencies */ - addRangeTableEntryForRelation(qual_pstate, target_table, NULL, - false, false); + addRangeTableEntryForRelation(qual_pstate, target_table, + AccessShareLock, + NULL, false, false); qual_parse_rtable = qual_pstate->p_rtable; free_parsestate(qual_pstate); @@ -1137,8 +1149,9 @@ AlterPolicy(AlterPolicyStmt *stmt) with_check_qual = stringToNode(with_check_value); /* Add this rel to the parsestate's rangetable, for dependencies */ - addRangeTableEntryForRelation(with_check_pstate, target_table, NULL, - false, false); + addRangeTableEntryForRelation(with_check_pstate, target_table, + AccessShareLock, + NULL, false, false); with_check_parse_rtable = with_check_pstate->p_rtable; free_parsestate(with_check_pstate); @@ -1192,7 +1205,7 @@ AlterPolicy(AlterPolicyStmt *stmt) /* Clean up. */ systable_endscan(sscan); relation_close(target_table, NoLock); - heap_close(pg_policy_rel, RowExclusiveLock); + table_close(pg_policy_rel, RowExclusiveLock); return myself; } @@ -1221,7 +1234,7 @@ rename_policy(RenameStmt *stmt) target_table = relation_open(table_id, NoLock); - pg_policy_rel = heap_open(PolicyRelationId, RowExclusiveLock); + pg_policy_rel = table_open(PolicyRelationId, RowExclusiveLock); /* First pass -- check for conflict */ @@ -1275,7 +1288,7 @@ rename_policy(RenameStmt *stmt) errmsg("policy \"%s\" for table \"%s\" does not exist", stmt->subname, RelationGetRelationName(target_table)))); - opoloid = HeapTupleGetOid(policy_tuple); + opoloid = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid; policy_tuple = heap_copytuple(policy_tuple); @@ -1284,8 +1297,7 @@ rename_policy(RenameStmt *stmt) CatalogTupleUpdate(pg_policy_rel, &policy_tuple->t_self, policy_tuple); - InvokeObjectPostAlterHook(PolicyRelationId, - HeapTupleGetOid(policy_tuple), 0); + InvokeObjectPostAlterHook(PolicyRelationId, opoloid, 0); ObjectAddressSet(address, PolicyRelationId, opoloid); @@ -1298,7 +1310,7 @@ rename_policy(RenameStmt *stmt) /* Clean up. */ systable_endscan(sscan); - heap_close(pg_policy_rel, RowExclusiveLock); + table_close(pg_policy_rel, RowExclusiveLock); relation_close(target_table, NoLock); return address; @@ -1319,7 +1331,7 @@ get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok) HeapTuple policy_tuple; Oid policy_oid; - pg_policy_rel = heap_open(PolicyRelationId, AccessShareLock); + pg_policy_rel = table_open(PolicyRelationId, AccessShareLock); /* Add key - policy's relation id. */ ScanKeyInit(&skey[0], @@ -1350,11 +1362,11 @@ get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok) policy_oid = InvalidOid; } else - policy_oid = HeapTupleGetOid(policy_tuple); + policy_oid = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid; /* Clean up. */ systable_endscan(sscan); - heap_close(pg_policy_rel, AccessShareLock); + table_close(pg_policy_rel, AccessShareLock); return policy_oid; } @@ -1371,7 +1383,7 @@ relation_has_policies(Relation rel) HeapTuple policy_tuple; bool ret = false; - catalog = heap_open(PolicyRelationId, AccessShareLock); + catalog = table_open(PolicyRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_policy_polrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -1383,7 +1395,7 @@ relation_has_policies(Relation rel) ret = true; systable_endscan(sscan); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); return ret; } diff --git a/src/backend/commands/portalcmds.c b/src/backend/commands/portalcmds.c index 73821502ba6..83f9959d54c 100644 --- a/src/backend/commands/portalcmds.c +++ b/src/backend/commands/portalcmds.c @@ -9,7 +9,7 @@ * storage management for portals (but doesn't run any queries in them). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -450,9 +450,9 @@ PersistHoldablePortal(Portal portal) PopActiveSnapshot(); /* - * We can now release any subsidiary memory of the portal's context; - * we'll never use it again. The executor already dropped its context, - * but this will clean up anything that glommed onto the portal's context via + * We can now release any subsidiary memory of the portal's context; we'll + * never use it again. The executor already dropped its context, but this + * will clean up anything that glommed onto the portal's context via * PortalContext. */ MemoryContextDeleteChildren(portal->portalContext); diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c index c3610b18741..7e0a041fabf 100644 --- a/src/backend/commands/prepare.c +++ b/src/backend/commands/prepare.c @@ -7,7 +7,7 @@ * accessed via the extended FE/BE query protocol. * * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/commands/prepare.c @@ -47,7 +47,7 @@ static HTAB *prepared_queries = NULL; static void InitQueryHashTable(void); static ParamListInfo EvaluateParams(PreparedStatement *pstmt, List *params, - const char *queryString, EState *estate); + const char *queryString, EState *estate); static Datum build_regtype_array(Oid *param_types, int num_params); /* @@ -143,7 +143,7 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString, } /* - * grammar only allows OptimizableStmt, so this check should be redundant + * grammar only allows PreparableStmt, so this check should be redundant */ switch (query->commandType) { @@ -151,7 +151,6 @@ PrepareQuery(PrepareStmt *stmt, const char *queryString, case CMD_INSERT: case CMD_UPDATE: case CMD_DELETE: - case CMD_MERGE: /* OK */ break; default: @@ -394,17 +393,7 @@ EvaluateParams(PreparedStatement *pstmt, List *params, /* Prepare the expressions for execution */ exprstates = ExecPrepareExprList(params, estate); - paramLI = (ParamListInfo) - palloc(offsetof(ParamListInfoData, params) + - num_params * sizeof(ParamExternData)); - /* we have static list of params, so no hooks needed */ - paramLI->paramFetch = NULL; - paramLI->paramFetchArg = NULL; - paramLI->paramCompile = NULL; - paramLI->paramCompileArg = NULL; - paramLI->parserSetup = NULL; - paramLI->parserSetupArg = NULL; - paramLI->numParams = num_params; + paramLI = makeParamList(num_params); i = 0; foreach(l, exprstates) @@ -693,7 +682,7 @@ ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, ExplainState *es, /* No need for CommandCounterIncrement, as ExplainOnePlan did it */ /* Separate plans with an appropriate separator */ - if (lnext(p) != NULL) + if (lnext(plan_list, p) != NULL) ExplainSeparatePlans(es); } @@ -735,7 +724,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS) * build tupdesc for result tuples. This must match the definition of the * pg_prepared_statements view in system_views.sql */ - tupdesc = CreateTemplateTupleDesc(5, false); + tupdesc = CreateTemplateTupleDesc(5); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement", diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index c900ad9431a..343cd1dbb05 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * proclang.c - * PostgreSQL PROCEDURAL LANGUAGE support code. + * PostgreSQL LANGUAGE support code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,8 +14,9 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -37,7 +38,6 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" typedef struct @@ -51,13 +51,12 @@ typedef struct } PLTemplate; static ObjectAddress create_proc_lang(const char *languageName, bool replace, - Oid languageOwner, Oid handlerOid, Oid inlineOid, - Oid valOid, bool trusted); + Oid languageOwner, Oid handlerOid, Oid inlineOid, + Oid valOid, bool trusted); static PLTemplate *find_language_template(const char *languageName); -/* --------------------------------------------------------------------- - * CREATE PROCEDURAL LANGUAGE - * --------------------------------------------------------------------- +/* + * CREATE LANGUAGE */ ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt) @@ -141,6 +140,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) NIL, PointerGetDatum(NULL), PointerGetDatum(NULL), + InvalidOid, 1, 0); handlerOid = tmpAddr.objectId; @@ -180,6 +180,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) NIL, PointerGetDatum(NULL), PointerGetDatum(NULL), + InvalidOid, 1, 0); inlineOid = tmpAddr.objectId; @@ -222,6 +223,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt) NIL, PointerGetDatum(NULL), PointerGetDatum(NULL), + InvalidOid, 1, 0); valOid = tmpAddr.objectId; @@ -329,11 +331,12 @@ create_proc_lang(const char *languageName, bool replace, NameData langname; HeapTuple oldtup; HeapTuple tup; + Oid langoid; bool is_update; ObjectAddress myself, referenced; - rel = heap_open(LanguageRelationId, RowExclusiveLock); + rel = table_open(LanguageRelationId, RowExclusiveLock); tupDesc = RelationGetDescr(rel); /* Prepare data to be inserted */ @@ -356,19 +359,22 @@ create_proc_lang(const char *languageName, bool replace, if (HeapTupleIsValid(oldtup)) { + Form_pg_language oldform = (Form_pg_language) GETSTRUCT(oldtup); + /* There is one; okay to replace it? */ if (!replace) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), errmsg("language \"%s\" already exists", languageName))); - if (!pg_language_ownercheck(HeapTupleGetOid(oldtup), languageOwner)) + if (!pg_language_ownercheck(oldform->oid, languageOwner)) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_LANGUAGE, languageName); /* - * Do not change existing ownership or permissions. Note + * Do not change existing oid, ownership or permissions. Note * dependency-update code below has to agree with this decision. */ + replaces[Anum_pg_language_oid - 1] = false; replaces[Anum_pg_language_lanowner - 1] = false; replaces[Anum_pg_language_lanacl - 1] = false; @@ -376,12 +382,16 @@ create_proc_lang(const char *languageName, bool replace, tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces); CatalogTupleUpdate(rel, &tup->t_self, tup); + langoid = oldform->oid; ReleaseSysCache(oldtup); is_update = true; } else { /* Creating a new language */ + langoid = GetNewOidWithIndex(rel, LanguageOidIndexId, + Anum_pg_language_oid); + values[Anum_pg_language_oid - 1] = ObjectIdGetDatum(langoid); tup = heap_form_tuple(tupDesc, values, nulls); CatalogTupleInsert(rel, tup); is_update = false; @@ -394,7 +404,7 @@ create_proc_lang(const char *languageName, bool replace, * shared dependencies do *not* need to change, and we leave them alone.) */ myself.classId = LanguageRelationId; - myself.objectId = HeapTupleGetOid(tup); + myself.objectId = langoid; myself.objectSubId = 0; if (is_update) @@ -435,7 +445,7 @@ create_proc_lang(const char *languageName, bool replace, /* Post creation hook for new procedural language */ InvokeObjectPostCreateHook(LanguageRelationId, myself.objectId, 0); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return myself; } @@ -452,7 +462,7 @@ find_language_template(const char *languageName) ScanKeyData key; HeapTuple tup; - rel = heap_open(PLTemplateRelationId, AccessShareLock); + rel = table_open(PLTemplateRelationId, AccessShareLock); ScanKeyInit(&key, Anum_pg_pltemplate_tmplname, @@ -502,7 +512,7 @@ find_language_template(const char *languageName) systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return result; } @@ -526,7 +536,7 @@ DropProceduralLanguageById(Oid langOid) Relation rel; HeapTuple langTup; - rel = heap_open(LanguageRelationId, RowExclusiveLock); + rel = table_open(LanguageRelationId, RowExclusiveLock); langTup = SearchSysCache1(LANGOID, ObjectIdGetDatum(langOid)); if (!HeapTupleIsValid(langTup)) /* should not happen */ @@ -536,7 +546,7 @@ DropProceduralLanguageById(Oid langOid) ReleaseSysCache(langTup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -550,7 +560,8 @@ get_language_oid(const char *langname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(LANGNAME, CStringGetDatum(langname)); + oid = GetSysCacheOid1(LANGNAME, Anum_pg_language_oid, + CStringGetDatum(langname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c index 6f7762a906c..f115d4bf805 100644 --- a/src/backend/commands/publicationcmds.c +++ b/src/backend/commands/publicationcmds.c @@ -3,7 +3,7 @@ * publicationcmds.c * publication manipulation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,9 +18,8 @@ #include "miscadmin.h" #include "access/genam.h" -#include "access/hash.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -54,7 +53,7 @@ static List *OpenTableList(List *tables); static void CloseTableList(List *rels); static void PublicationAddTables(Oid pubid, List *rels, bool if_not_exists, - AlterPublicationStmt *stmt); + AlterPublicationStmt *stmt); static void PublicationDropTables(Oid pubid, List *rels, bool missing_ok); static void @@ -130,7 +129,7 @@ parse_publication_options(List *options, else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized publication parameter: %s", defel->defname))); + errmsg("unrecognized publication parameter: \"%s\"", defel->defname))); } } @@ -165,10 +164,11 @@ CreatePublication(CreatePublicationStmt *stmt) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to create FOR ALL TABLES publication")))); - rel = heap_open(PublicationRelationId, RowExclusiveLock); + rel = table_open(PublicationRelationId, RowExclusiveLock); /* Check if name is used */ - puboid = GetSysCacheOid1(PUBLICATIONNAME, CStringGetDatum(stmt->pubname)); + puboid = GetSysCacheOid1(PUBLICATIONNAME, Anum_pg_publication_oid, + CStringGetDatum(stmt->pubname)); if (OidIsValid(puboid)) { ereport(ERROR, @@ -190,6 +190,9 @@ CreatePublication(CreatePublicationStmt *stmt) &publish_update, &publish_delete, &publish_truncate); + puboid = GetNewOidWithIndex(rel, PublicationObjectIndexId, + Anum_pg_publication_oid); + values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid); values[Anum_pg_publication_puballtables - 1] = BoolGetDatum(stmt->for_all_tables); values[Anum_pg_publication_pubinsert - 1] = @@ -204,7 +207,7 @@ CreatePublication(CreatePublicationStmt *stmt) tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); /* Insert tuple into catalog. */ - puboid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); recordDependencyOnOwner(PublicationRelationId, puboid, GetUserId()); @@ -225,10 +228,18 @@ CreatePublication(CreatePublicationStmt *stmt) CloseTableList(rels); } - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); InvokeObjectPostCreateHook(PublicationRelationId, puboid, 0); + if (wal_level != WAL_LEVEL_LOGICAL) + { + ereport(WARNING, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("wal_level is insufficient to publish logical changes"), + errhint("Set wal_level to logical before creating subscriptions."))); + } + return myself; } @@ -248,6 +259,7 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel, bool publish_delete; bool publish_truncate; ObjectAddress obj; + Form_pg_publication pubform; parse_publication_options(stmt->options, &publish_given, &publish_insert, @@ -282,14 +294,16 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel, CommandCounterIncrement(); + pubform = (Form_pg_publication) GETSTRUCT(tup); + /* Invalidate the relcache. */ - if (((Form_pg_publication) GETSTRUCT(tup))->puballtables) + if (pubform->puballtables) { CacheInvalidateRelcacheAll(); } else { - List *relids = GetPublicationRelations(HeapTupleGetOid(tup)); + List *relids = GetPublicationRelations(pubform->oid); /* * We don't want to send too many individual messages, at some point @@ -310,11 +324,11 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel, CacheInvalidateRelcacheAll(); } - ObjectAddressSet(obj, PublicationRelationId, HeapTupleGetOid(tup)); + ObjectAddressSet(obj, PublicationRelationId, pubform->oid); EventTriggerCollectSimpleCommand(obj, InvalidObjectAddress, (Node *) stmt); - InvokeObjectPostAlterHook(PublicationRelationId, HeapTupleGetOid(tup), 0); + InvokeObjectPostAlterHook(PublicationRelationId, pubform->oid, 0); } /* @@ -324,9 +338,9 @@ static void AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, HeapTuple tup) { - Oid pubid = HeapTupleGetOid(tup); List *rels = NIL; Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup); + Oid pubid = pubform->oid; /* Check that user is allowed to manipulate the publication tables. */ if (pubform->puballtables) @@ -370,8 +384,8 @@ AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel, if (!found) { - Relation oldrel = heap_open(oldrelid, - ShareUpdateExclusiveLock); + Relation oldrel = table_open(oldrelid, + ShareUpdateExclusiveLock); delrels = lappend(delrels, oldrel); } @@ -403,8 +417,9 @@ AlterPublication(AlterPublicationStmt *stmt) { Relation rel; HeapTuple tup; + Form_pg_publication pubform; - rel = heap_open(PublicationRelationId, RowExclusiveLock); + rel = table_open(PublicationRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(PUBLICATIONNAME, CStringGetDatum(stmt->pubname)); @@ -415,8 +430,10 @@ AlterPublication(AlterPublicationStmt *stmt) errmsg("publication \"%s\" does not exist", stmt->pubname))); + pubform = (Form_pg_publication) GETSTRUCT(tup); + /* must be owner */ - if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_publication_ownercheck(pubform->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION, stmt->pubname); @@ -427,7 +444,7 @@ AlterPublication(AlterPublicationStmt *stmt) /* Cleanup. */ heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -439,7 +456,7 @@ RemovePublicationById(Oid pubid) Relation rel; HeapTuple tup; - rel = heap_open(PublicationRelationId, RowExclusiveLock); + rel = table_open(PublicationRelationId, RowExclusiveLock); tup = SearchSysCache1(PUBLICATIONOID, ObjectIdGetDatum(pubid)); @@ -450,7 +467,7 @@ RemovePublicationById(Oid pubid) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -463,7 +480,7 @@ RemovePublicationRelById(Oid proid) HeapTuple tup; Form_pg_publication_rel pubrel; - rel = heap_open(PublicationRelRelationId, RowExclusiveLock); + rel = table_open(PublicationRelRelationId, RowExclusiveLock); tup = SearchSysCache1(PUBLICATIONREL, ObjectIdGetDatum(proid)); @@ -480,11 +497,11 @@ RemovePublicationRelById(Oid proid) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* - * Open relations based on provided by RangeVar list. + * Open relations specified by a RangeVar list. * The returned tables are locked in ShareUpdateExclusiveLock mode. */ static List * @@ -499,14 +516,15 @@ OpenTableList(List *tables) */ foreach(lc, tables) { - RangeVar *rv = lfirst(lc); - Relation rel; + RangeVar *rv = castNode(RangeVar, lfirst(lc)); bool recurse = rv->inh; + Relation rel; Oid myrelid; + /* Allow query cancel in case this takes a long time */ CHECK_FOR_INTERRUPTS(); - rel = heap_openrv(rv, ShareUpdateExclusiveLock); + rel = table_openrv(rv, ShareUpdateExclusiveLock); myrelid = RelationGetRelid(rel); /* @@ -518,16 +536,18 @@ OpenTableList(List *tables) */ if (list_member_oid(relids, myrelid)) { - heap_close(rel, ShareUpdateExclusiveLock); + table_close(rel, ShareUpdateExclusiveLock); continue; } + rels = lappend(rels, rel); relids = lappend_oid(relids, myrelid); + /* Add children of this rel, if requested */ if (recurse) { - ListCell *child; List *children; + ListCell *child; children = find_all_inheritors(myrelid, ShareUpdateExclusiveLock, NULL); @@ -536,21 +556,18 @@ OpenTableList(List *tables) { Oid childrelid = lfirst_oid(child); - if (list_member_oid(relids, childrelid)) - continue; + /* Allow query cancel in case this takes a long time */ + CHECK_FOR_INTERRUPTS(); /* * Skip duplicates if user specified both parent and child * tables. */ if (list_member_oid(relids, childrelid)) - { - heap_close(rel, ShareUpdateExclusiveLock); continue; - } /* find_all_inheritors already got lock */ - rel = heap_open(childrelid, NoLock); + rel = table_open(childrelid, NoLock); rels = lappend(rels, rel); relids = lappend_oid(relids, childrelid); } @@ -574,7 +591,7 @@ CloseTableList(List *rels) { Relation rel = (Relation) lfirst(lc); - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -626,7 +643,8 @@ PublicationDropTables(Oid pubid, List *rels, bool missing_ok) Relation rel = (Relation) lfirst(lc); Oid relid = RelationGetRelid(rel); - prid = GetSysCacheOid2(PUBLICATIONRELMAP, ObjectIdGetDatum(relid), + prid = GetSysCacheOid2(PUBLICATIONRELMAP, Anum_pg_publication_rel_oid, + ObjectIdGetDatum(relid), ObjectIdGetDatum(pubid)); if (!OidIsValid(prid)) { @@ -662,7 +680,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) AclResult aclresult; /* Must be owner */ - if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_publication_ownercheck(form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION, NameStr(form->pubname)); @@ -688,11 +706,11 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* Update owner dependency reference */ changeDependencyOnOwner(PublicationRelationId, - HeapTupleGetOid(tup), + form->oid, newOwnerId); InvokeObjectPostAlterHook(PublicationRelationId, - HeapTupleGetOid(tup), 0); + form->oid, 0); } /* @@ -705,8 +723,9 @@ AlterPublicationOwner(const char *name, Oid newOwnerId) HeapTuple tup; Relation rel; ObjectAddress address; + Form_pg_publication pubform; - rel = heap_open(PublicationRelationId, RowExclusiveLock); + rel = table_open(PublicationRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(PUBLICATIONNAME, CStringGetDatum(name)); @@ -715,7 +734,8 @@ AlterPublicationOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("publication \"%s\" does not exist", name))); - subid = HeapTupleGetOid(tup); + pubform = (Form_pg_publication) GETSTRUCT(tup); + subid = pubform->oid; AlterPublicationOwner_internal(rel, tup, newOwnerId); @@ -723,7 +743,7 @@ AlterPublicationOwner(const char *name, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -737,7 +757,7 @@ AlterPublicationOwner_oid(Oid subid, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(PublicationRelationId, RowExclusiveLock); + rel = table_open(PublicationRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(PUBLICATIONOID, ObjectIdGetDatum(subid)); @@ -750,5 +770,5 @@ AlterPublicationOwner_oid(Oid subid, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c index dc6cb46e4e7..6cf94a3140b 100644 --- a/src/backend/commands/schemacmds.c +++ b/src/backend/commands/schemacmds.c @@ -3,7 +3,7 @@ * schemacmds.c * schema creation/manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,7 +15,7 @@ #include "postgres.h" #include "access/htup_details.h" -#include "access/heapam.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" @@ -220,7 +220,7 @@ RemoveSchemaById(Oid schemaOid) Relation relation; HeapTuple tup; - relation = heap_open(NamespaceRelationId, RowExclusiveLock); + relation = table_open(NamespaceRelationId, RowExclusiveLock); tup = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(schemaOid)); @@ -231,7 +231,7 @@ RemoveSchemaById(Oid schemaOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } @@ -246,8 +246,9 @@ RenameSchema(const char *oldname, const char *newname) Relation rel; AclResult aclresult; ObjectAddress address; + Form_pg_namespace nspform; - rel = heap_open(NamespaceRelationId, RowExclusiveLock); + rel = table_open(NamespaceRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(NAMESPACENAME, CStringGetDatum(oldname)); if (!HeapTupleIsValid(tup)) @@ -255,7 +256,8 @@ RenameSchema(const char *oldname, const char *newname) (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema \"%s\" does not exist", oldname))); - nspOid = HeapTupleGetOid(tup); + nspform = (Form_pg_namespace) GETSTRUCT(tup); + nspOid = nspform->oid; /* make sure the new name doesn't exist */ if (OidIsValid(get_namespace_oid(newname, true))) @@ -264,7 +266,7 @@ RenameSchema(const char *oldname, const char *newname) errmsg("schema \"%s\" already exists", newname))); /* must be owner */ - if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_namespace_ownercheck(nspOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA, oldname); @@ -281,14 +283,14 @@ RenameSchema(const char *oldname, const char *newname) errdetail("The prefix \"pg_\" is reserved for system schemas."))); /* rename */ - namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname); + namestrcpy(&nspform->nspname, newname); CatalogTupleUpdate(rel, &tup->t_self, tup); - InvokeObjectPostAlterHook(NamespaceRelationId, HeapTupleGetOid(tup), 0); + InvokeObjectPostAlterHook(NamespaceRelationId, nspOid, 0); ObjectAddressSet(address, NamespaceRelationId, nspOid); - heap_close(rel, NoLock); + table_close(rel, NoLock); heap_freetuple(tup); return address; @@ -300,7 +302,7 @@ AlterSchemaOwner_oid(Oid oid, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(NamespaceRelationId, RowExclusiveLock); + rel = table_open(NamespaceRelationId, RowExclusiveLock); tup = SearchSysCache1(NAMESPACEOID, ObjectIdGetDatum(oid)); if (!HeapTupleIsValid(tup)) @@ -310,7 +312,7 @@ AlterSchemaOwner_oid(Oid oid, Oid newOwnerId) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } @@ -324,8 +326,9 @@ AlterSchemaOwner(const char *name, Oid newOwnerId) HeapTuple tup; Relation rel; ObjectAddress address; + Form_pg_namespace nspform; - rel = heap_open(NamespaceRelationId, RowExclusiveLock); + rel = table_open(NamespaceRelationId, RowExclusiveLock); tup = SearchSysCache1(NAMESPACENAME, CStringGetDatum(name)); if (!HeapTupleIsValid(tup)) @@ -333,7 +336,8 @@ AlterSchemaOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema \"%s\" does not exist", name))); - nspOid = HeapTupleGetOid(tup); + nspform = (Form_pg_namespace) GETSTRUCT(tup); + nspOid = nspform->oid; AlterSchemaOwner_internal(tup, rel, newOwnerId); @@ -341,7 +345,7 @@ AlterSchemaOwner(const char *name, Oid newOwnerId) ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -372,7 +376,7 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) AclResult aclresult; /* Otherwise, must be owner of the existing object */ - if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_namespace_ownercheck(nspForm->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA, NameStr(nspForm->nspname)); @@ -422,10 +426,10 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) heap_freetuple(newtuple); /* Update owner dependency reference */ - changeDependencyOnOwner(NamespaceRelationId, HeapTupleGetOid(tup), + changeDependencyOnOwner(NamespaceRelationId, nspForm->oid, newOwnerId); } InvokeObjectPostAlterHook(NamespaceRelationId, - HeapTupleGetOid(tup), 0); + nspForm->oid, 0); } diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c index 5ee46905d84..63219ad589f 100644 --- a/src/backend/commands/seclabel.c +++ b/src/backend/commands/seclabel.c @@ -3,7 +3,7 @@ * seclabel.c * routines to support security label feature. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- @@ -11,8 +11,9 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/relation.h" +#include "access/table.h" #include "catalog/catalog.h" #include "catalog/indexing.h" #include "catalog/pg_seclabel.h" @@ -23,7 +24,6 @@ #include "utils/fmgroids.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" typedef struct { @@ -58,7 +58,7 @@ ExecSecLabelStmt(SecLabelStmt *stmt) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("no security label providers have been loaded"))); - if (lnext(list_head(label_provider_list)) != NULL) + if (list_length(label_provider_list) != 1) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("must specify provider when multiple security label providers have been loaded"))); @@ -167,7 +167,7 @@ GetSharedSecurityLabel(const ObjectAddress *object, const char *provider) BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); - pg_shseclabel = heap_open(SharedSecLabelRelationId, AccessShareLock); + pg_shseclabel = table_open(SharedSecLabelRelationId, AccessShareLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, NULL, 3, keys); @@ -182,7 +182,7 @@ GetSharedSecurityLabel(const ObjectAddress *object, const char *provider) } systable_endscan(scan); - heap_close(pg_shseclabel, AccessShareLock); + table_close(pg_shseclabel, AccessShareLock); return seclabel; } @@ -224,7 +224,7 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider) BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); - pg_seclabel = heap_open(SecLabelRelationId, AccessShareLock); + pg_seclabel = table_open(SecLabelRelationId, AccessShareLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, NULL, 4, keys); @@ -239,7 +239,7 @@ GetSecurityLabel(const ObjectAddress *object, const char *provider) } systable_endscan(scan); - heap_close(pg_seclabel, AccessShareLock); + table_close(pg_seclabel, AccessShareLock); return seclabel; } @@ -284,7 +284,7 @@ SetSharedSecurityLabel(const ObjectAddress *object, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); - pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock); + pg_shseclabel = table_open(SharedSecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, NULL, 3, keys); @@ -315,13 +315,13 @@ SetSharedSecurityLabel(const ObjectAddress *object, if (newtup != NULL) heap_freetuple(newtup); - heap_close(pg_shseclabel, RowExclusiveLock); + table_close(pg_shseclabel, RowExclusiveLock); } /* * SetSecurityLabel attempts to set the security label for the specified * provider on the specified object to the given value. NULL means that any - * any existing label should be deleted. + * existing label should be deleted. */ void SetSecurityLabel(const ObjectAddress *object, @@ -371,7 +371,7 @@ SetSecurityLabel(const ObjectAddress *object, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); - pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock); + pg_seclabel = table_open(SecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, NULL, 4, keys); @@ -403,7 +403,7 @@ SetSecurityLabel(const ObjectAddress *object, if (newtup != NULL) heap_freetuple(newtup); - heap_close(pg_seclabel, RowExclusiveLock); + table_close(pg_seclabel, RowExclusiveLock); } /* @@ -427,7 +427,7 @@ DeleteSharedSecurityLabel(Oid objectId, Oid classId) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); - pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock); + pg_shseclabel = table_open(SharedSecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, NULL, 2, skey); @@ -435,7 +435,7 @@ DeleteSharedSecurityLabel(Oid objectId, Oid classId) CatalogTupleDelete(pg_shseclabel, &oldtup->t_self); systable_endscan(scan); - heap_close(pg_shseclabel, RowExclusiveLock); + table_close(pg_shseclabel, RowExclusiveLock); } /* @@ -478,7 +478,7 @@ DeleteSecurityLabel(const ObjectAddress *object) else nkeys = 2; - pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock); + pg_seclabel = table_open(SecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, NULL, nkeys, skey); @@ -486,7 +486,7 @@ DeleteSecurityLabel(const ObjectAddress *object) CatalogTupleDelete(pg_seclabel, &oldtup->t_self); systable_endscan(scan); - heap_close(pg_seclabel, RowExclusiveLock); + table_close(pg_seclabel, RowExclusiveLock); } void diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 89122d4ad75..a13322b6938 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -3,7 +3,7 @@ * sequence.c * PostgreSQL sequences support code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,8 @@ #include "access/bufmask.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/relation.h" +#include "access/table.h" #include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" @@ -97,13 +99,13 @@ static Relation lock_and_open_sequence(SeqTable seq); static void create_seq_hashtable(void); static void init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel); static Form_pg_sequence_data read_seq_tuple(Relation rel, - Buffer *buf, HeapTuple seqdatatuple); + Buffer *buf, HeapTuple seqdatatuple); static void init_params(ParseState *pstate, List *options, bool for_identity, - bool isInit, - Form_pg_sequence seqform, - Form_pg_sequence_data seqdataform, - bool *need_seq_rewrite, - List **owned_by); + bool isInit, + Form_pg_sequence seqform, + Form_pg_sequence_data seqdataform, + bool *need_seq_rewrite, + List **owned_by); static void do_setval(Oid relid, int64 next, bool iscalled); static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity); @@ -172,7 +174,6 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) coldef->is_local = true; coldef->is_not_null = true; coldef->is_from_type = false; - coldef->is_from_parent = false; coldef->storage = 0; coldef->raw_default = NULL; coldef->cooked_default = NULL; @@ -216,7 +217,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) seqoid = address.objectId; Assert(seqoid != InvalidOid); - rel = heap_open(seqoid, AccessExclusiveLock); + rel = table_open(seqoid, AccessExclusiveLock); tupDesc = RelationGetDescr(rel); /* now initialize the sequence's data */ @@ -227,10 +228,10 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) if (owned_by) process_owned_by(rel, owned_by, seq->for_identity); - heap_close(rel, NoLock); + table_close(rel, NoLock); /* fill in pg_sequence */ - rel = heap_open(SequenceRelationId, RowExclusiveLock); + rel = table_open(SequenceRelationId, RowExclusiveLock); tupDesc = RelationGetDescr(rel); memset(pgs_nulls, 0, sizeof(pgs_nulls)); @@ -248,7 +249,7 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -311,12 +312,17 @@ ResetSequence(Oid seq_relid) seq->log_cnt = 0; /* - * Create a new storage file for the sequence. We want to keep the - * sequence's relfrozenxid at 0, since it won't contain any unfrozen XIDs. - * Same with relminmxid, since a sequence will never contain multixacts. + * Create a new storage file for the sequence. + */ + RelationSetNewRelfilenode(seq_rel, seq_rel->rd_rel->relpersistence); + + /* + * Ensure sequence's relfrozenxid is at 0, since it won't contain any + * unfrozen XIDs. Same with relminmxid, since a sequence will never + * contain multixacts. */ - RelationSetNewRelfilenode(seq_rel, seq_rel->rd_rel->relpersistence, - InvalidTransactionId, InvalidMultiXactId); + Assert(seq_rel->rd_rel->relfrozenxid == InvalidTransactionId); + Assert(seq_rel->rd_rel->relminmxid == InvalidMultiXactId); /* * Insert the modified tuple into the new storage file. @@ -445,7 +451,7 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt) init_sequence(relid, &elm, &seqrel); - rel = heap_open(SequenceRelationId, RowExclusiveLock); + rel = table_open(SequenceRelationId, RowExclusiveLock); seqtuple = SearchSysCacheCopy1(SEQRELID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(seqtuple)) @@ -481,12 +487,17 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt) /* * Create a new storage file for the sequence, making the state - * changes transactional. We want to keep the sequence's relfrozenxid - * at 0, since it won't contain any unfrozen XIDs. Same with - * relminmxid, since a sequence will never contain multixacts. + * changes transactional. + */ + RelationSetNewRelfilenode(seqrel, seqrel->rd_rel->relpersistence); + + /* + * Ensure sequence's relfrozenxid is at 0, since it won't contain any + * unfrozen XIDs. Same with relminmxid, since a sequence will never + * contain multixacts. */ - RelationSetNewRelfilenode(seqrel, seqrel->rd_rel->relpersistence, - InvalidTransactionId, InvalidMultiXactId); + Assert(seqrel->rd_rel->relfrozenxid == InvalidTransactionId); + Assert(seqrel->rd_rel->relminmxid == InvalidMultiXactId); /* * Insert the modified tuple into the new storage file. @@ -505,7 +516,7 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt) ObjectAddressSet(address, RelationRelationId, relid); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); relation_close(seqrel, NoLock); return address; @@ -517,7 +528,7 @@ DeleteSequenceTuple(Oid relid) Relation rel; HeapTuple tuple; - rel = heap_open(SequenceRelationId, RowExclusiveLock); + rel = table_open(SequenceRelationId, RowExclusiveLock); tuple = SearchSysCache1(SEQRELID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) @@ -526,7 +537,7 @@ DeleteSequenceTuple(Oid relid) CatalogTupleDelete(rel, &tuple->t_self); ReleaseSysCache(tuple); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -1104,7 +1115,7 @@ init_sequence(Oid relid, SeqTable *p_elm, Relation *p_rel) /* * Initialize the new hash table entry if it did not exist already. * - * NOTE: seqtable entries are stored for the life of a backend (unless + * NOTE: seqhashtab entries are stored for the life of a backend (unless * explicitly discarded with DISCARD). If the sequence itself is deleted * then the entry becomes wasted memory, but it's small enough that this * should not matter. @@ -1789,7 +1800,7 @@ pg_sequence_parameters(PG_FUNCTION_ARGS) errmsg("permission denied for sequence %s", get_rel_name(relid)))); - tupdesc = CreateTemplateTupleDesc(7, false); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minimum_value", diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c index c4adfd569ea..f51eb7bb64e 100644 --- a/src/backend/commands/statscmds.c +++ b/src/backend/commands/statscmds.c @@ -3,7 +3,7 @@ * statscmds.c * Commands for creating and altering extended statistics objects * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,17 +14,24 @@ */ #include "postgres.h" +#include "access/heapam.h" +#include "access/relation.h" #include "access/relscan.h" +#include "access/table.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" +#include "catalog/objectaccess.h" #include "catalog/pg_namespace.h" #include "catalog/pg_statistic_ext.h" +#include "catalog/pg_statistic_ext_data.h" #include "commands/comment.h" #include "commands/defrem.h" #include "miscadmin.h" #include "statistics/statistics.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" #include "utils/inval.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -33,7 +40,7 @@ static char *ChooseExtendedStatisticName(const char *name1, const char *name2, - const char *label, Oid namespaceid); + const char *label, Oid namespaceid); static char *ChooseExtendedStatisticNameAddition(List *exprs); @@ -64,17 +71,21 @@ CreateStatistics(CreateStatsStmt *stmt) HeapTuple htup; Datum values[Natts_pg_statistic_ext]; bool nulls[Natts_pg_statistic_ext]; + Datum datavalues[Natts_pg_statistic_ext_data]; + bool datanulls[Natts_pg_statistic_ext_data]; int2vector *stxkeys; Relation statrel; + Relation datarel; Relation rel = NULL; Oid relid; ObjectAddress parentobject, myself; - Datum types[2]; /* one for each possible type of statistic */ + Datum types[3]; /* one for each possible type of statistic */ int ntypes; ArrayType *stxkind; bool build_ndistinct; bool build_dependencies; + bool build_mcv; bool requested_type = false; int i; ListCell *cell; @@ -133,7 +144,8 @@ CreateStatistics(CreateStatsStmt *stmt) * If the node has a name, split it up and determine creation namespace. * If not (a possibility not considered by the grammar, but one which can * occur via the "CREATE TABLE ... (LIKE)" command), then we put the - * object in the same namespace as the relation, and cons up a name for it. + * object in the same namespace as the relation, and cons up a name for + * it. */ if (stmt->defnames) namespaceId = QualifiedNameGetCreationNamespace(stmt->defnames, @@ -268,6 +280,7 @@ CreateStatistics(CreateStatsStmt *stmt) */ build_ndistinct = false; build_dependencies = false; + build_mcv = false; foreach(cell, stmt->stat_types) { char *type = strVal((Value *) lfirst(cell)); @@ -282,6 +295,11 @@ CreateStatistics(CreateStatsStmt *stmt) build_dependencies = true; requested_type = true; } + else if (strcmp(type, "mcv") == 0) + { + build_mcv = true; + requested_type = true; + } else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -293,6 +311,7 @@ CreateStatistics(CreateStatsStmt *stmt) { build_ndistinct = true; build_dependencies = true; + build_mcv = true; } /* construct the char array of enabled statistic types */ @@ -301,32 +320,60 @@ CreateStatistics(CreateStatsStmt *stmt) types[ntypes++] = CharGetDatum(STATS_EXT_NDISTINCT); if (build_dependencies) types[ntypes++] = CharGetDatum(STATS_EXT_DEPENDENCIES); + if (build_mcv) + types[ntypes++] = CharGetDatum(STATS_EXT_MCV); Assert(ntypes > 0 && ntypes <= lengthof(types)); stxkind = construct_array(types, ntypes, CHAROID, 1, true, 'c'); + statrel = table_open(StatisticExtRelationId, RowExclusiveLock); + /* * Everything seems fine, so let's build the pg_statistic_ext tuple. */ memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + + statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId, + Anum_pg_statistic_ext_oid); + values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid); values[Anum_pg_statistic_ext_stxrelid - 1] = ObjectIdGetDatum(relid); values[Anum_pg_statistic_ext_stxname - 1] = NameGetDatum(&stxname); values[Anum_pg_statistic_ext_stxnamespace - 1] = ObjectIdGetDatum(namespaceId); + values[Anum_pg_statistic_ext_stxstattarget - 1] = Int32GetDatum(-1); values[Anum_pg_statistic_ext_stxowner - 1] = ObjectIdGetDatum(stxowner); values[Anum_pg_statistic_ext_stxkeys - 1] = PointerGetDatum(stxkeys); values[Anum_pg_statistic_ext_stxkind - 1] = PointerGetDatum(stxkind); - /* no statistics built yet */ - nulls[Anum_pg_statistic_ext_stxndistinct - 1] = true; - nulls[Anum_pg_statistic_ext_stxdependencies - 1] = true; - /* insert it into pg_statistic_ext */ - statrel = heap_open(StatisticExtRelationId, RowExclusiveLock); htup = heap_form_tuple(statrel->rd_att, values, nulls); - statoid = CatalogTupleInsert(statrel, htup); + CatalogTupleInsert(statrel, htup); heap_freetuple(htup); + relation_close(statrel, RowExclusiveLock); + /* + * Also build the pg_statistic_ext_data tuple, to hold the actual + * statistics data. + */ + datarel = table_open(StatisticExtDataRelationId, RowExclusiveLock); + + memset(datavalues, 0, sizeof(datavalues)); + memset(datanulls, false, sizeof(datanulls)); + + datavalues[Anum_pg_statistic_ext_data_stxoid - 1] = ObjectIdGetDatum(statoid); + + /* no statistics built yet */ + datanulls[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true; + datanulls[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; + datanulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; + + /* insert it into pg_statistic_ext_data */ + htup = heap_form_tuple(datarel->rd_att, datavalues, datanulls); + CatalogTupleInsert(datarel, htup); + heap_freetuple(htup); + + relation_close(datarel, RowExclusiveLock); + /* * Invalidate relcache so that others see the new statistics object. */ @@ -371,6 +418,110 @@ CreateStatistics(CreateStatsStmt *stmt) return myself; } +/* + * ALTER STATISTICS + */ +ObjectAddress +AlterStatistics(AlterStatsStmt *stmt) +{ + Relation rel; + Oid stxoid; + HeapTuple oldtup; + HeapTuple newtup; + Datum repl_val[Natts_pg_statistic_ext]; + bool repl_null[Natts_pg_statistic_ext]; + bool repl_repl[Natts_pg_statistic_ext]; + ObjectAddress address; + int newtarget = stmt->stxstattarget; + + /* Limit statistics target to a sane range */ + if (newtarget < -1) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("statistics target %d is too low", + newtarget))); + } + else if (newtarget > 10000) + { + newtarget = 10000; + ereport(WARNING, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("lowering statistics target to %d", + newtarget))); + } + + /* lookup OID of the statistics object */ + stxoid = get_statistics_object_oid(stmt->defnames, stmt->missing_ok); + + /* + * If we got here and the OID is not valid, it means the statistics + * does not exist, but the command specified IF EXISTS. So report + * this as a simple NOTICE and we're done. + */ + if (!OidIsValid(stxoid)) + { + char *schemaname; + char *statname; + + Assert(stmt->missing_ok); + + DeconstructQualifiedName(stmt->defnames, &schemaname, &statname); + + if (schemaname) + ereport(NOTICE, + (errmsg("statistics object \"%s.%s\" does not exist, skipping", + schemaname, statname))); + else + ereport(NOTICE, + (errmsg("statistics object \"%s\" does not exist, skipping", + statname))); + + return InvalidObjectAddress; + } + + /* Search pg_statistic_ext */ + rel = table_open(StatisticExtRelationId, RowExclusiveLock); + + oldtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(stxoid)); + + /* Must be owner of the existing statistics object */ + if (!pg_statistics_object_ownercheck(stxoid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_STATISTIC_EXT, + NameListToString(stmt->defnames)); + + /* Build new tuple. */ + memset(repl_val, 0, sizeof(repl_val)); + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + + /* replace the stxstattarget column */ + repl_repl[Anum_pg_statistic_ext_stxstattarget - 1] = true; + repl_val[Anum_pg_statistic_ext_stxstattarget - 1] = Int32GetDatum(newtarget); + + newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel), + repl_val, repl_null, repl_repl); + + /* Update system catalog. */ + CatalogTupleUpdate(rel, &newtup->t_self, newtup); + + InvokeObjectPostAlterHook(StatisticExtRelationId, stxoid, 0); + + ObjectAddressSet(address, StatisticExtRelationId, stxoid); + + /* + * NOTE: because we only support altering the statistics target, not the + * other fields, there is no need to update dependencies. + */ + + heap_freetuple(newtup); + ReleaseSysCache(oldtup); + + table_close(rel, RowExclusiveLock); + + return address; +} + /* * Guts of statistics object deletion. */ @@ -382,11 +533,28 @@ RemoveStatisticsById(Oid statsOid) Form_pg_statistic_ext statext; Oid relid; + /* + * First delete the pg_statistic_ext_data tuple holding the actual + * statistical data. + */ + relation = table_open(StatisticExtDataRelationId, RowExclusiveLock); + + tup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid)); + + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for statistics data %u", statsOid); + + CatalogTupleDelete(relation, &tup->t_self); + + ReleaseSysCache(tup); + + table_close(relation, RowExclusiveLock); + /* * Delete the pg_statistic_ext tuple. Also send out a cache inval on the * associated table, so that dependent plans will be rebuilt. */ - relation = heap_open(StatisticExtRelationId, RowExclusiveLock); + relation = table_open(StatisticExtRelationId, RowExclusiveLock); tup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statsOid)); @@ -402,7 +570,7 @@ RemoveStatisticsById(Oid statsOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* @@ -410,27 +578,80 @@ RemoveStatisticsById(Oid statsOid) * * This could throw an error if the type change can't be supported. * If it can be supported, but the stats must be recomputed, a likely choice - * would be to set the relevant column(s) of the pg_statistic_ext tuple to - * null until the next ANALYZE. (Note that the type change hasn't actually + * would be to set the relevant column(s) of the pg_statistic_ext_data tuple + * to null until the next ANALYZE. (Note that the type change hasn't actually * happened yet, so one option that's *not* on the table is to recompute * immediately.) + * + * For both ndistinct and functional-dependencies stats, the on-disk + * representation is independent of the source column data types, and it is + * plausible to assume that the old statistic values will still be good for + * the new column contents. (Obviously, if the ALTER COLUMN TYPE has a USING + * expression that substantially alters the semantic meaning of the column + * values, this assumption could fail. But that seems like a corner case + * that doesn't justify zapping the stats in common cases.) + * + * For MCV lists that's not the case, as those statistics store the datums + * internally. In this case we simply reset the statistics value to NULL. + * + * Note that "type change" includes collation change, which means we can rely + * on the MCV list being consistent with the collation info in pg_attribute + * during estimation. */ void UpdateStatisticsForTypeChange(Oid statsOid, Oid relationOid, int attnum, Oid oldColumnType, Oid newColumnType) { + HeapTuple stup, + oldtup; + + Relation rel; + + Datum values[Natts_pg_statistic_ext_data]; + bool nulls[Natts_pg_statistic_ext_data]; + bool replaces[Natts_pg_statistic_ext_data]; + + oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statsOid)); + if (!HeapTupleIsValid(oldtup)) + elog(ERROR, "cache lookup failed for statistics object %u", statsOid); + /* - * Currently, we don't actually need to do anything here. For both - * ndistinct and functional-dependencies stats, the on-disk representation - * is independent of the source column data types, and it is plausible to - * assume that the old statistic values will still be good for the new - * column contents. (Obviously, if the ALTER COLUMN TYPE has a USING - * expression that substantially alters the semantic meaning of the column - * values, this assumption could fail. But that seems like a corner case - * that doesn't justify zapping the stats in common cases.) - * - * Future types of extended stats will likely require us to work harder. + * When none of the defined statistics types contain datum values from the + * table's columns then there's no need to reset the stats. Functional + * dependencies and ndistinct stats should still hold true. */ + if (!statext_is_kind_built(oldtup, STATS_EXT_MCV)) + { + ReleaseSysCache(oldtup); + return; + } + + /* + * OK, we need to reset some statistics. So let's build the new tuple, + * replacing the affected statistics types with NULL. + */ + memset(nulls, 0, Natts_pg_statistic_ext_data * sizeof(bool)); + memset(replaces, 0, Natts_pg_statistic_ext_data * sizeof(bool)); + memset(values, 0, Natts_pg_statistic_ext_data * sizeof(Datum)); + + replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; + nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; + + rel = heap_open(StatisticExtDataRelationId, RowExclusiveLock); + + /* replace the old tuple */ + stup = heap_modify_tuple(oldtup, + RelationGetDescr(rel), + values, + nulls, + replaces); + + ReleaseSysCache(oldtup); + CatalogTupleUpdate(rel, &stup->t_self, stup); + + heap_freetuple(stup); + + heap_close(rel, RowExclusiveLock); } /* @@ -462,11 +683,11 @@ ChooseExtendedStatisticName(const char *name1, const char *name2, for (;;) { - Oid existingstats; + Oid existingstats; stxname = makeObjectName(name1, name2, modlabel); - existingstats = GetSysCacheOid2(STATEXTNAMENSP, + existingstats = GetSysCacheOid2(STATEXTNAMENSP, Anum_pg_statistic_ext_oid, PointerGetDatum(stxname), ObjectIdGetDatum(namespaceid)); if (!OidIsValid(existingstats)) @@ -488,7 +709,8 @@ ChooseExtendedStatisticName(const char *name1, const char *name2, * We know that less than NAMEDATALEN characters will actually be used, * so we can truncate the result once we've generated that many. * - * XXX see also ChooseIndexNameAddition. + * XXX see also ChooseForeignKeyConstraintNameAddition and + * ChooseIndexNameAddition. */ static char * ChooseExtendedStatisticNameAddition(List *exprs) @@ -500,7 +722,7 @@ ChooseExtendedStatisticNameAddition(List *exprs) buf[0] = '\0'; foreach(lc, exprs) { - ColumnRef *cref = (ColumnRef *) lfirst(lc); + ColumnRef *cref = (ColumnRef *) lfirst(lc); const char *name; /* It should be one of these, but just skip if it happens not to be */ diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c index f138e61a8d3..2e67a5889e5 100644 --- a/src/backend/commands/subscriptioncmds.c +++ b/src/backend/commands/subscriptioncmds.c @@ -3,7 +3,7 @@ * subscriptioncmds.c * subscription catalog manipulation functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,10 +16,11 @@ #include "miscadmin.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -184,7 +185,7 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given, else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized subscription parameter: %s", defel->defname))); + errmsg("unrecognized subscription parameter: \"%s\"", defel->defname))); } /* @@ -197,17 +198,21 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given, if (enabled && *enabled_given && *enabled) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("connect = false and enabled = true are mutually exclusive options"))); + /*- translator: both %s are strings of the form "option = value" */ + errmsg("%s and %s are mutually exclusive options", + "connect = false", "enabled = true"))); if (create_slot && create_slot_given && *create_slot) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("connect = false and create_slot = true are mutually exclusive options"))); + errmsg("%s and %s are mutually exclusive options", + "connect = false", "create_slot = true"))); if (copy_data && copy_data_given && *copy_data) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("connect = false and copy_data = true are mutually exclusive options"))); + errmsg("%s and %s are mutually exclusive options", + "connect = false", "copy_data = true"))); /* Change the defaults of other options. */ *enabled = false; @@ -224,22 +229,28 @@ parse_subscription_options(List *options, bool *connect, bool *enabled_given, if (enabled && *enabled_given && *enabled) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("slot_name = NONE and enabled = true are mutually exclusive options"))); + /*- translator: both %s are strings of the form "option = value" */ + errmsg("%s and %s are mutually exclusive options", + "slot_name = NONE", "enabled = true"))); if (create_slot && create_slot_given && *create_slot) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("slot_name = NONE and create_slot = true are mutually exclusive options"))); + errmsg("%s and %s are mutually exclusive options", + "slot_name = NONE", "create_slot = true"))); if (enabled && !*enabled_given && *enabled) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subscription with slot_name = NONE must also set enabled = false"))); + /*- translator: both %s are strings of the form "option = value" */ + errmsg("subscription with %s must also set %s", + "slot_name = NONE", "enabled = false"))); if (create_slot && !create_slot_given && *create_slot) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("subscription with slot_name = NONE must also set create_slot = false"))); + errmsg("subscription with %s must also set %s", + "slot_name = NONE", "create_slot = false"))); } } @@ -346,11 +357,20 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to create subscriptions")))); - rel = heap_open(SubscriptionRelationId, RowExclusiveLock); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for subscription names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->subname, "regress_", 8) != 0) + elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\""); +#endif + + rel = table_open(SubscriptionRelationId, RowExclusiveLock); /* Check if name is used */ - subid = GetSysCacheOid2(SUBSCRIPTIONNAME, MyDatabaseId, - CStringGetDatum(stmt->subname)); + subid = GetSysCacheOid2(SUBSCRIPTIONNAME, Anum_pg_subscription_oid, + MyDatabaseId, CStringGetDatum(stmt->subname)); if (OidIsValid(subid)) { ereport(ERROR, @@ -379,6 +399,9 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId, + Anum_pg_subscription_oid); + values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid); values[Anum_pg_subscription_subdbid - 1] = ObjectIdGetDatum(MyDatabaseId); values[Anum_pg_subscription_subname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->subname)); @@ -399,7 +422,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) tup = heap_form_tuple(RelationGetDescr(rel), values, nulls); /* Insert tuple into catalog. */ - subid = CatalogTupleInsert(rel, tup); + CatalogTupleInsert(rel, tup); heap_freetuple(tup); recordDependencyOnOwner(SubscriptionRelationId, subid, owner); @@ -483,11 +506,11 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel) } else ereport(WARNING, - (errmsg("tables were not subscribed, you will have to run " - "ALTER SUBSCRIPTION ... REFRESH PUBLICATION to " - "subscribe the tables"))); + /* translator: %s is an SQL ALTER statement */ + (errmsg("tables were not subscribed, you will have to run %s to subscribe the tables", + "ALTER SUBSCRIPTION ... REFRESH PUBLICATION"))); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); if (enabled) ApplyLauncherWakeupAtCommit(); @@ -620,8 +643,9 @@ AlterSubscription(AlterSubscriptionStmt *stmt) Oid subid; bool update_tuple = false; Subscription *sub; + Form_pg_subscription form; - rel = heap_open(SubscriptionRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelationId, RowExclusiveLock); /* Fetch the existing tuple. */ tup = SearchSysCacheCopy2(SUBSCRIPTIONNAME, MyDatabaseId, @@ -633,12 +657,14 @@ AlterSubscription(AlterSubscriptionStmt *stmt) errmsg("subscription \"%s\" does not exist", stmt->subname))); + form = (Form_pg_subscription) GETSTRUCT(tup); + subid = form->oid; + /* must be owner */ - if (!pg_subscription_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_subscription_ownercheck(subid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION, stmt->subname); - subid = HeapTupleGetOid(tup); sub = GetSubscription(subid, false); /* Lock the subscription so nobody else can do anything with it. */ @@ -666,7 +692,8 @@ AlterSubscription(AlterSubscriptionStmt *stmt) if (sub->enabled && !slotname) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("cannot set slot_name = NONE for enabled subscription"))); + errmsg("cannot set %s for enabled subscription", + "slot_name = NONE"))); if (slotname) values[Anum_pg_subscription_subslotname - 1] = @@ -792,7 +819,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt) heap_freetuple(tup); } - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); ObjectAddressSet(myself, SubscriptionRelationId, subid); @@ -823,19 +850,20 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) RepOriginId originid; WalReceiverConn *wrconn = NULL; StringInfoData cmd; + Form_pg_subscription form; /* * Lock pg_subscription with AccessExclusiveLock to ensure that the * launcher doesn't restart new worker during dropping the subscription */ - rel = heap_open(SubscriptionRelationId, AccessExclusiveLock); + rel = table_open(SubscriptionRelationId, AccessExclusiveLock); tup = SearchSysCache2(SUBSCRIPTIONNAME, MyDatabaseId, CStringGetDatum(stmt->subname)); if (!HeapTupleIsValid(tup)) { - heap_close(rel, NoLock); + table_close(rel, NoLock); if (!stmt->missing_ok) ereport(ERROR, @@ -850,7 +878,8 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) return; } - subid = HeapTupleGetOid(tup); + form = (Form_pg_subscription) GETSTRUCT(tup); + subid = form->oid; /* must be owner */ if (!pg_subscription_ownercheck(subid, GetUserId())) @@ -953,7 +982,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) */ if (!slotname) { - heap_close(rel, NoLock); + table_close(rel, NoLock); return; } @@ -972,8 +1001,9 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) (errmsg("could not connect to publisher when attempting to " "drop the replication slot \"%s\"", slotname), errdetail("The error was: %s", err), - errhint("Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) " - "to disassociate the subscription from the slot."))); + /* translator: %s is an SQL ALTER command */ + errhint("Use %s to disassociate the subscription from the slot.", + "ALTER SUBSCRIPTION ... SET (slot_name = NONE)"))); PG_TRY(); { @@ -1005,7 +1035,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel) pfree(cmd.data); - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* @@ -1021,7 +1051,7 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) if (form->subowner == newOwnerId) return; - if (!pg_subscription_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_subscription_ownercheck(form->oid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION, NameStr(form->subname)); @@ -1038,11 +1068,11 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) /* Update owner dependency reference */ changeDependencyOnOwner(SubscriptionRelationId, - HeapTupleGetOid(tup), + form->oid, newOwnerId); InvokeObjectPostAlterHook(SubscriptionRelationId, - HeapTupleGetOid(tup), 0); + form->oid, 0); } /* @@ -1055,8 +1085,9 @@ AlterSubscriptionOwner(const char *name, Oid newOwnerId) HeapTuple tup; Relation rel; ObjectAddress address; + Form_pg_subscription form; - rel = heap_open(SubscriptionRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelationId, RowExclusiveLock); tup = SearchSysCacheCopy2(SUBSCRIPTIONNAME, MyDatabaseId, CStringGetDatum(name)); @@ -1066,7 +1097,8 @@ AlterSubscriptionOwner(const char *name, Oid newOwnerId) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("subscription \"%s\" does not exist", name))); - subid = HeapTupleGetOid(tup); + form = (Form_pg_subscription) GETSTRUCT(tup); + subid = form->oid; AlterSubscriptionOwner_internal(rel, tup, newOwnerId); @@ -1074,7 +1106,7 @@ AlterSubscriptionOwner(const char *name, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -1088,7 +1120,7 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId) HeapTuple tup; Relation rel; - rel = heap_open(SubscriptionRelationId, RowExclusiveLock); + rel = table_open(SubscriptionRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(SUBSCRIPTIONOID, ObjectIdGetDatum(subid)); @@ -1101,7 +1133,7 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId) heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -1148,7 +1180,7 @@ fetch_table_list(WalReceiverConn *wrconn, List *publications) res->err))); /* Process tables. */ - slot = MakeSingleTupleTableSlot(res->tupledesc); + slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); while (tuplestore_gettupleslot(res->tuplestore, true, false, slot)) { char *nspname; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 43b2fce2c51..05593f33162 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3,7 +3,7 @@ * tablecmds.c * Commands for creating and altering table structures and settings * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,9 @@ #include "access/multixact.h" #include "access/reloptions.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/tupconvert.h" #include "access/xact.h" #include "access/xlog.h" @@ -63,11 +65,7 @@ #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "nodes/parsenodes.h" -#include "optimizer/clauses.h" -#include "optimizer/planner.h" -#include "optimizer/predtest.h" -#include "optimizer/prep.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_clause.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" @@ -77,6 +75,8 @@ #include "parser/parse_type.h" #include "parser/parse_utilcmd.h" #include "parser/parser.h" +#include "partitioning/partbounds.h" +#include "partitioning/partdesc.h" #include "pgstat.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteHandler.h" @@ -92,11 +92,12 @@ #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/partcache.h" #include "utils/relcache.h" #include "utils/ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" +#include "utils/timestamp.h" #include "utils/typcache.h" @@ -141,9 +142,9 @@ static List *on_commits = NIL; #define AT_PASS_ALTER_TYPE 1 /* ALTER COLUMN TYPE */ #define AT_PASS_OLD_INDEX 2 /* re-add existing indexes */ #define AT_PASS_OLD_CONSTR 3 /* re-add existing constraints */ -#define AT_PASS_COL_ATTRS 4 /* set other column attributes */ /* We could support a RENAME COLUMN pass here, but not currently used */ -#define AT_PASS_ADD_COL 5 /* ADD COLUMN */ +#define AT_PASS_ADD_COL 4 /* ADD COLUMN */ +#define AT_PASS_COL_ATTRS 5 /* set other column attributes */ #define AT_PASS_ADD_INDEX 6 /* ADD indexes */ #define AT_PASS_ADD_CONSTR 7 /* ADD constraints, defaults */ #define AT_PASS_MISC 8 /* other stuff */ @@ -160,7 +161,7 @@ typedef struct AlteredTableInfo /* Information saved by Phases 1/2 for Phase 3: */ List *constraints; /* List of NewConstraint */ List *newvals; /* List of NewColumnValue */ - bool new_notnull; /* T if we added new NOT NULL constraints */ + bool verify_new_notnull; /* T if we should recheck NOT NULL */ int rewrite; /* Reason for forced rewrite, if any */ Oid newTableSpace; /* new tablespace; 0 means no change */ bool chgPersistence; /* T if SET LOGGED/UNLOGGED is used */ @@ -298,164 +299,202 @@ struct DropRelationCallbackState #define child_dependency_type(child_is_partition) \ ((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL) -static void truncate_check_rel(Relation rel); +static void truncate_check_rel(Oid relid, Form_pg_class reltuple); +static void truncate_check_activity(Relation rel); +static void RangeVarCallbackForTruncate(const RangeVar *relation, + Oid relId, Oid oldRelId, void *arg); static List *MergeAttributes(List *schema, List *supers, char relpersistence, - bool is_partition, List **supOids, List **supconstr, - int *supOidCount); + bool is_partition, List **supconstr); static bool MergeCheckConstraint(List *constraints, char *name, Node *expr); static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel); static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel); static void StoreCatalogInheritance(Oid relationId, List *supers, - bool child_is_partition); + bool child_is_partition); static void StoreCatalogInheritance1(Oid relationId, Oid parentOid, - int32 seqNumber, Relation inhRelation, - bool child_is_partition); + int32 seqNumber, Relation inhRelation, + bool child_is_partition); static int findAttrByName(const char *attributeName, List *schema); static void AlterIndexNamespaces(Relation classRel, Relation rel, - Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved); + Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved); static void AlterSeqNamespaces(Relation classRel, Relation rel, - Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved, - LOCKMODE lockmode); + Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved, + LOCKMODE lockmode); static ObjectAddress ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, - bool recurse, bool recursing, LOCKMODE lockmode); + bool recurse, bool recursing, LOCKMODE lockmode); static ObjectAddress ATExecValidateConstraint(Relation rel, char *constrName, - bool recurse, bool recursing, LOCKMODE lockmode); -static int transformColumnNameList(Oid relId, List *colList, - int16 *attnums, Oid *atttypids); -static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, - List **attnamelist, - int16 *attnums, Oid *atttypids, - Oid *opclasses); -static Oid transformFkeyCheckAttrs(Relation pkrel, - int numattrs, int16 *attnums, - Oid *opclasses); + bool recurse, bool recursing, LOCKMODE lockmode); +static int transformColumnNameList(Oid relId, List *colList, + int16 *attnums, Oid *atttypids); +static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, + List **attnamelist, + int16 *attnums, Oid *atttypids, + Oid *opclasses); +static Oid transformFkeyCheckAttrs(Relation pkrel, + int numattrs, int16 *attnums, + Oid *opclasses); static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts); static CoercionPathType findFkeyCast(Oid targetTypeId, Oid sourceTypeId, - Oid *funcid); + Oid *funcid); static void validateCheckConstraint(Relation rel, HeapTuple constrtup); static void validateForeignKeyConstraint(char *conname, - Relation rel, Relation pkrel, - Oid pkindOid, Oid constraintOid); + Relation rel, Relation pkrel, + Oid pkindOid, Oid constraintOid); static void ATController(AlterTableStmt *parsetree, - Relation rel, List *cmds, bool recurse, LOCKMODE lockmode); + Relation rel, List *cmds, bool recurse, LOCKMODE lockmode); static void ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, - bool recurse, bool recursing, LOCKMODE lockmode); + bool recurse, bool recursing, LOCKMODE lockmode); static void ATRewriteCatalogs(List **wqueue, LOCKMODE lockmode); static void ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, - AlterTableCmd *cmd, LOCKMODE lockmode); + AlterTableCmd *cmd, LOCKMODE lockmode); static void ATRewriteTables(AlterTableStmt *parsetree, - List **wqueue, LOCKMODE lockmode); + List **wqueue, LOCKMODE lockmode); static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode); static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel); static void ATSimplePermissions(Relation rel, int allowed_targets); static void ATWrongRelkindError(Relation rel, int allowed_targets); static void ATSimpleRecursion(List **wqueue, Relation rel, - AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode); + AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode); +static void ATCheckPartitionsNotInUse(Relation rel, LOCKMODE lockmode); static void ATTypedTableRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd, - LOCKMODE lockmode); + LOCKMODE lockmode); static List *find_typed_table_dependencies(Oid typeOid, const char *typeName, - DropBehavior behavior); + DropBehavior behavior); static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing, - bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode); + bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode); static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, - Relation rel, ColumnDef *colDef, bool isOid, - bool recurse, bool recursing, - bool if_not_exists, LOCKMODE lockmode); + Relation rel, ColumnDef *colDef, + bool recurse, bool recursing, + bool if_not_exists, LOCKMODE lockmode); static bool check_for_column_name_collision(Relation rel, const char *colname, - bool if_not_exists); + bool if_not_exists); static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid); static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid); -static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse, - AlterTableCmd *cmd, LOCKMODE lockmode); static void ATPrepDropNotNull(Relation rel, bool recurse, bool recursing); static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode); -static void ATPrepSetNotNull(Relation rel, bool recurse, bool recursing); +static void ATPrepSetNotNull(List **wqueue, Relation rel, + AlterTableCmd *cmd, bool recurse, bool recursing, + LOCKMODE lockmode); static ObjectAddress ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, - const char *colName, LOCKMODE lockmode); + const char *colName, LOCKMODE lockmode); +static void ATExecCheckNotNull(AlteredTableInfo *tab, Relation rel, + const char *colName, LOCKMODE lockmode); +static bool NotNullImpliedByRelConstraints(Relation rel, Form_pg_attribute attr); +static bool ConstraintImpliedByRelConstraint(Relation scanrel, + List *testConstraint, List *provenConstraint); static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName, - Node *newDefault, LOCKMODE lockmode); + Node *newDefault, LOCKMODE lockmode); static ObjectAddress ATExecAddIdentity(Relation rel, const char *colName, - Node *def, LOCKMODE lockmode); + Node *def, LOCKMODE lockmode); static ObjectAddress ATExecSetIdentity(Relation rel, const char *colName, - Node *def, LOCKMODE lockmode); + Node *def, LOCKMODE lockmode); static ObjectAddress ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE lockmode); static void ATPrepSetStatistics(Relation rel, const char *colName, int16 colNum, - Node *newValue, LOCKMODE lockmode); + Node *newValue, LOCKMODE lockmode); static ObjectAddress ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, - Node *newValue, LOCKMODE lockmode); + Node *newValue, LOCKMODE lockmode); static ObjectAddress ATExecSetOptions(Relation rel, const char *colName, - Node *options, bool isReset, LOCKMODE lockmode); + Node *options, bool isReset, LOCKMODE lockmode); static ObjectAddress ATExecSetStorage(Relation rel, const char *colName, - Node *newValue, LOCKMODE lockmode); + Node *newValue, LOCKMODE lockmode); static void ATPrepDropColumn(List **wqueue, Relation rel, bool recurse, bool recursing, - AlterTableCmd *cmd, LOCKMODE lockmode); + AlterTableCmd *cmd, LOCKMODE lockmode); static ObjectAddress ATExecDropColumn(List **wqueue, Relation rel, const char *colName, - DropBehavior behavior, - bool recurse, bool recursing, - bool missing_ok, LOCKMODE lockmode); + DropBehavior behavior, + bool recurse, bool recursing, + bool missing_ok, LOCKMODE lockmode); static ObjectAddress ATExecAddIndex(AlteredTableInfo *tab, Relation rel, - IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode); + IndexStmt *stmt, bool is_rebuild, LOCKMODE lockmode); static ObjectAddress ATExecAddConstraint(List **wqueue, - AlteredTableInfo *tab, Relation rel, - Constraint *newConstraint, bool recurse, bool is_readd, - LOCKMODE lockmode); + AlteredTableInfo *tab, Relation rel, + Constraint *newConstraint, bool recurse, bool is_readd, + LOCKMODE lockmode); +static char *ChooseForeignKeyConstraintNameAddition(List *colnames); static ObjectAddress ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, - IndexStmt *stmt, LOCKMODE lockmode); + IndexStmt *stmt, LOCKMODE lockmode); static ObjectAddress ATAddCheckConstraint(List **wqueue, - AlteredTableInfo *tab, Relation rel, - Constraint *constr, - bool recurse, bool recursing, bool is_readd, - LOCKMODE lockmode); + AlteredTableInfo *tab, Relation rel, + Constraint *constr, + bool recurse, bool recursing, bool is_readd, + LOCKMODE lockmode); static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, - Relation rel, Constraint *fkconstraint, Oid parentConstr, - bool recurse, bool recursing, - LOCKMODE lockmode); + Relation rel, Constraint *fkconstraint, Oid parentConstr, + bool recurse, bool recursing, + LOCKMODE lockmode); +static ObjectAddress addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, + Relation rel, Relation pkrel, Oid indexOid, Oid parentConstr, + int numfks, int16 *pkattnum, int16 *fkattnum, + Oid *pfeqoperators, Oid *ppeqoperators, Oid *ffeqoperators, + bool old_check_ok); +static void addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, + Relation rel, Relation pkrel, Oid indexOid, Oid parentConstr, + int numfks, int16 *pkattnum, int16 *fkattnum, + Oid *pfeqoperators, Oid *ppeqoperators, Oid *ffeqoperators, + bool old_check_ok, LOCKMODE lockmode); +static void CloneForeignKeyConstraints(List **wqueue, Relation parentRel, + Relation partitionRel); +static void CloneFkReferenced(Relation parentRel, Relation partitionRel); +static void CloneFkReferencing(List **wqueue, Relation parentRel, + Relation partRel); +static void createForeignKeyCheckTriggers(Oid myRelOid, Oid refRelOid, + Constraint *fkconstraint, Oid constraintOid, + Oid indexOid); +static void createForeignKeyActionTriggers(Relation rel, Oid refRelOid, + Constraint *fkconstraint, Oid constraintOid, + Oid indexOid); +static bool tryAttachPartitionForeignKey(ForeignKeyCacheInfo *fk, + Oid partRelid, + Oid parentConstrOid, int numfks, + AttrNumber *mapped_conkey, AttrNumber *confkey, + Oid *conpfeqop); static void ATExecDropConstraint(Relation rel, const char *constrName, - DropBehavior behavior, - bool recurse, bool recursing, - bool missing_ok, LOCKMODE lockmode); + DropBehavior behavior, + bool recurse, bool recursing, + bool missing_ok, LOCKMODE lockmode); static void ATPrepAlterColumnType(List **wqueue, - AlteredTableInfo *tab, Relation rel, - bool recurse, bool recursing, - AlterTableCmd *cmd, LOCKMODE lockmode); + AlteredTableInfo *tab, Relation rel, + bool recurse, bool recursing, + AlterTableCmd *cmd, LOCKMODE lockmode); static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno); static ObjectAddress ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, - AlterTableCmd *cmd, LOCKMODE lockmode); -static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, - List *options, LOCKMODE lockmode); + AlterTableCmd *cmd, LOCKMODE lockmode); +static void RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab); +static void RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab); static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, - LOCKMODE lockmode); + LOCKMODE lockmode); static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, - char *cmd, List **wqueue, LOCKMODE lockmode, - bool rewrite); + char *cmd, List **wqueue, LOCKMODE lockmode, + bool rewrite); static void RebuildConstraintComment(AlteredTableInfo *tab, int pass, - Oid objid, Relation rel, List *domname, - const char *conname); + Oid objid, Relation rel, List *domname, + const char *conname); static void TryReuseIndex(Oid oldId, IndexStmt *stmt); static void TryReuseForeignKey(Oid oldId, Constraint *con); +static ObjectAddress ATExecAlterColumnGenericOptions(Relation rel, const char *colName, + List *options, LOCKMODE lockmode); static void change_owner_fix_column_acls(Oid relationOid, - Oid oldOwnerId, Oid newOwnerId); + Oid oldOwnerId, Oid newOwnerId); static void change_owner_recurse_to_sequences(Oid relationOid, - Oid newOwnerId, LOCKMODE lockmode); + Oid newOwnerId, LOCKMODE lockmode); static ObjectAddress ATExecClusterOn(Relation rel, const char *indexName, - LOCKMODE lockmode); + LOCKMODE lockmode); static void ATExecDropCluster(Relation rel, LOCKMODE lockmode); static bool ATPrepChangePersistence(Relation rel, bool toLogged); static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, - const char *tablespacename, LOCKMODE lockmode); + const char *tablespacename, LOCKMODE lockmode); static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode); +static void ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace); static void ATExecSetRelOptions(Relation rel, List *defList, - AlterTableType operation, - LOCKMODE lockmode); + AlterTableType operation, + LOCKMODE lockmode); static void ATExecEnableDisableTrigger(Relation rel, const char *trigname, - char fires_when, bool skip_system, LOCKMODE lockmode); + char fires_when, bool skip_system, LOCKMODE lockmode); static void ATExecEnableDisableRule(Relation rel, const char *rulename, - char fires_when, LOCKMODE lockmode); + char fires_when, LOCKMODE lockmode); static void ATPrepAddInherit(Relation child_rel); static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode); static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode); static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid, - DependencyType deptype); + DependencyType deptype); static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode); static void ATExecDropOf(Relation rel, LOCKMODE lockmode); static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode); @@ -464,33 +503,33 @@ static void ATExecEnableRowSecurity(Relation rel); static void ATExecDisableRowSecurity(Relation rel); static void ATExecForceNoForceRowSecurity(Relation rel, bool force_rls); -static void copy_relation_data(SMgrRelation rel, SMgrRelation dst, - ForkNumber forkNum, char relpersistence); +static void index_copy_data(Relation rel, RelFileNode newrnode); static const char *storage_name(char c); static void RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, - Oid oldRelOid, void *arg); + Oid oldRelOid, void *arg); static void RangeVarCallbackForAlterRelation(const RangeVar *rv, Oid relid, - Oid oldrelid, void *arg); + Oid oldrelid, void *arg); static PartitionSpec *transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy); -static void ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, - List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); +static void ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, + List **partexprs, Oid *partopclass, Oid *partcollation, char strategy); static void CreateInheritance(Relation child_rel, Relation parent_rel); static void RemoveInheritance(Relation child_rel, Relation parent_rel); static ObjectAddress ATExecAttachPartition(List **wqueue, Relation rel, - PartitionCmd *cmd); + PartitionCmd *cmd); static void AttachPartitionEnsureIndexes(Relation rel, Relation attachrel); -static void ValidatePartitionConstraints(List **wqueue, Relation scanrel, - List *scanrel_children, - List *partConstraint, - bool validate_default); +static void QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, + List *partConstraint, + bool validate_default); static void CloneRowTriggersToPartition(Relation parent, Relation partition); static ObjectAddress ATExecDetachPartition(Relation rel, RangeVar *name); static ObjectAddress ATExecAttachPartitionIdx(List **wqueue, Relation rel, - RangeVar *name); + RangeVar *name); static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl); static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, - Relation partitionTbl); + Relation partitionTbl); +static List *GetParentedForeignKeyRefs(Relation partition); +static void ATDetachCheckNoForeignKeyRefs(Relation partition); /* ---------------------------------------------------------------- @@ -524,16 +563,18 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, TupleDesc descriptor; List *inheritOids; List *old_constraints; - bool localHasOids; - int parentOidCount; List *rawDefaults; List *cookedDefaults; Datum reloptions; ListCell *listptr; AttrNumber attnum; + bool partitioned; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; Oid ofTypeId; ObjectAddress address; + LOCKMODE parentLockmode; + const char *accessMethod = NULL; + Oid accessMethodId = InvalidOid; /* * Truncate relname to appropriate length (probably a waste of time, as @@ -556,7 +597,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, elog(ERROR, "unexpected relkind: %d", (int) relkind); relkind = RELKIND_PARTITIONED_TABLE; + partitioned = true; } + else + partitioned = false; /* * Look up the namespace in which we are supposed to create the relation, @@ -579,18 +623,74 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, errmsg("cannot create temporary table within security-restricted operation"))); /* - * Select tablespace to use. If not specified, use default tablespace - * (which may in turn default to database's default). + * Determine the lockmode to use when scanning parents. A self-exclusive + * lock is needed here. + * + * For regular inheritance, if two backends attempt to add children to the + * same parent simultaneously, and that parent has no pre-existing + * children, then both will attempt to update the parent's relhassubclass + * field, leading to a "tuple concurrently updated" error. Also, this + * interlocks against a concurrent ANALYZE on the parent table, which + * might otherwise be attempting to clear the parent's relhassubclass + * field, if its previous children were recently dropped. + * + * If the child table is a partition, then we instead grab an exclusive + * lock on the parent because its partition descriptor will be changed by + * addition of the new partition. + */ + parentLockmode = (stmt->partbound != NULL ? AccessExclusiveLock : + ShareUpdateExclusiveLock); + + /* Determine the list of OIDs of the parents. */ + inheritOids = NIL; + foreach(listptr, stmt->inhRelations) + { + RangeVar *rv = (RangeVar *) lfirst(listptr); + Oid parentOid; + + parentOid = RangeVarGetRelid(rv, parentLockmode, false); + + /* + * Reject duplications in the list of parents. + */ + if (list_member_oid(inheritOids, parentOid)) + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_TABLE), + errmsg("relation \"%s\" would be inherited from more than once", + get_rel_name(parentOid)))); + + inheritOids = lappend_oid(inheritOids, parentOid); + } + + /* + * Select tablespace to use: an explicitly indicated one, or (in the case + * of a partitioned table) the parent's, if it has one. */ if (stmt->tablespacename) { tablespaceId = get_tablespace_oid(stmt->tablespacename, false); + + if (partitioned && tablespaceId == MyDatabaseTableSpace) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot specify default tablespace for partitioned relations"))); } - else + else if (stmt->partbound) { - tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence); - /* note InvalidOid is OK in this case */ + /* + * For partitions, when no other tablespace is specified, we default + * the tablespace to the parent partitioned table's. + */ + Assert(list_length(inheritOids) == 1); + tablespaceId = get_rel_tablespace(linitial_oid(inheritOids)); } + else + tablespaceId = InvalidOid; + + /* still nothing? use the default */ + if (!OidIsValid(tablespaceId)) + tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence, + partitioned); /* Check permissions except when using database's default */ if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace) @@ -644,10 +744,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, * modified by MergeAttributes.) */ stmt->tableElts = - MergeAttributes(stmt->tableElts, stmt->inhRelations, + MergeAttributes(stmt->tableElts, inheritOids, stmt->relation->relpersistence, stmt->partbound != NULL, - &inheritOids, &old_constraints, &parentOidCount); + &old_constraints); /* * Create a tuple descriptor from the relation schema. Note that this @@ -656,29 +756,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, */ descriptor = BuildDescForRelation(stmt->tableElts); - /* - * Notice that we allow OIDs here only for plain tables and partitioned - * tables, even though some other relkinds can support them. This is - * necessary because the default_with_oids GUC must apply only to plain - * tables and not any other relkind; doing otherwise would break existing - * pg_dump files. We could allow explicit "WITH OIDS" while not allowing - * default_with_oids to affect other relkinds, but it would complicate - * interpretOidsOption(). - */ - localHasOids = interpretOidsOption(stmt->options, - (relkind == RELKIND_RELATION || - relkind == RELKIND_PARTITIONED_TABLE)); - descriptor->tdhasoid = (localHasOids || parentOidCount > 0); - - /* - * If a partitioned table doesn't have the system OID column, then none of - * its partitions should have it. - */ - if (stmt->partbound && parentOidCount == 0 && localHasOids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create table with OIDs as partition of table without OIDs"))); - /* * Find columns with default values and prepare for insertion of the * defaults. Pre-cooked (that is, inherited) defaults go into a list of @@ -713,6 +790,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, rawEnt->attnum = attnum; rawEnt->raw_default = colDef->raw_default; rawEnt->missingMode = false; + rawEnt->generated = colDef->generated; rawDefaults = lappend(rawDefaults, rawEnt); attr->atthasdef = true; } @@ -736,7 +814,33 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, if (colDef->identity) attr->attidentity = colDef->identity; + + if (colDef->generated) + attr->attgenerated = colDef->generated; + } + + /* + * If the statement hasn't specified an access method, but we're defining + * a type of relation that needs one, use the default. + */ + if (stmt->accessMethod != NULL) + { + accessMethod = stmt->accessMethod; + + if (partitioned) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("specifying a table access method is not supported on a partitioned table"))); + } + else if (relkind == RELKIND_RELATION || + relkind == RELKIND_TOASTVALUE || + relkind == RELKIND_MATVIEW) + accessMethod = default_table_access_method; + + /* look up the access method, verify it is for a table */ + if (accessMethod != NULL) + accessMethodId = get_table_am_oid(accessMethod, false); /* * Create the relation. Inherited defaults and constraints are passed in @@ -750,6 +854,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, InvalidOid, ofTypeId, ownerId, + accessMethodId, descriptor, list_concat(cookedDefaults, old_constraints), @@ -757,8 +862,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, stmt->relation->relpersistence, false, false, - localHasOids, - parentOidCount, stmt->oncommit, reloptions, true, @@ -767,9 +870,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, InvalidOid, typaddress); - /* Store inheritance information for new rel. */ - StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL); - /* * We must bump the command counter to make the newly-created relation * tuple visible for opening. @@ -784,6 +884,27 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, */ rel = relation_open(relationId, AccessExclusiveLock); + /* + * Now add any newly specified column default and generation expressions + * to the new relation. These are passed to us in the form of raw + * parsetrees; we need to transform them to executable expression trees + * before they can be added. The most convenient way to do that is to + * apply the parser's transformExpr routine, but transformExpr doesn't + * work unless we have a pre-existing relation. So, the transformation has + * to be postponed to this final step of CREATE TABLE. + * + * This needs to be before processing the partitioning clauses because + * those could refer to generated columns. + */ + if (rawDefaults) + AddRelationNewConstraints(rel, rawDefaults, NIL, + true, true, false, queryString); + + /* + * Make column generation expressions visible for use by partitioning. + */ + CommandCounterIncrement(); + /* Process and store partition bound, if any. */ if (stmt->partbound) { @@ -793,9 +914,10 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, defaultPartOid; Relation parent, defaultRel = NULL; + RangeTblEntry *rte; /* Already have strong enough lock on the parent */ - parent = heap_open(parentId, NoLock); + parent = table_open(parentId, NoLock); /* * We are going to try to validate the partition bound specification @@ -829,12 +951,20 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(parent)); if (OidIsValid(defaultPartOid)) - defaultRel = heap_open(defaultPartOid, AccessExclusiveLock); + defaultRel = table_open(defaultPartOid, AccessExclusiveLock); - /* Tranform the bound values */ + /* Transform the bound values */ pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; + /* + * Add an RTE containing this relation, so that transformExpr called + * on partition bound expressions is able to report errors using a + * proper context. + */ + rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, + NULL, false, false); + addRTEtoQuery(pstate, rte, false, true, true); bound = transformPartitionBound(pstate, parent, stmt->partbound); /* @@ -852,23 +982,27 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, */ if (OidIsValid(defaultPartOid)) { - check_default_allows_bound(parent, defaultRel, bound); + check_default_partition_contents(parent, defaultRel, bound); /* Keep the lock until commit. */ - heap_close(defaultRel, NoLock); + table_close(defaultRel, NoLock); } /* Update the pg_class entry. */ StorePartitionBound(rel, parent, bound); - heap_close(parent, NoLock); + table_close(parent, NoLock); } + /* Store inheritance information for new rel. */ + StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL); + /* * Process the partitioning specification (if any) and store the partition * key information into the catalog. */ - if (stmt->partspec) + if (partitioned) { + ParseState *pstate; char strategy; int partnatts; AttrNumber partattrs[PARTITION_MAX_KEYS]; @@ -876,6 +1010,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, Oid partcollation[PARTITION_MAX_KEYS]; List *partexprs = NIL; + pstate = make_parsestate(NULL); + pstate->p_sourcetext = queryString; + partnatts = list_length(stmt->partspec->partParams); /* Protect fixed-size arrays here and in executor */ @@ -894,7 +1031,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, stmt->partspec = transformPartitionSpec(rel, stmt->partspec, &strategy); - ComputePartitionAttrs(rel, stmt->partspec->partParams, + ComputePartitionAttrs(pstate, rel, stmt->partspec->partParams, partattrs, &partexprs, partopclass, partcollation, strategy); @@ -920,7 +1057,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ListCell *cell; /* Already have strong enough lock on the parent */ - parent = heap_open(parentId, NoLock); + parent = table_open(parentId, NoLock); idxlist = RelationGetIndexList(parent); /* @@ -933,11 +1070,26 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, IndexStmt *idxstmt; Oid constraintOid; + if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + if (idxRel->rd_index->indisunique) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create foreign partition of partitioned table \"%s\"", + RelationGetRelationName(parent)), + errdetail("Table \"%s\" contains indexes that are unique.", + RelationGetRelationName(parent)))); + else + { + index_close(idxRel, AccessShareLock); + continue; + } + } + attmap = convert_tuples_by_name_map(RelationGetDescr(rel), - RelationGetDescr(parent), - gettext_noop("could not convert row type")); + RelationGetDescr(parent)); idxstmt = - generateClonedIndexStmt(NULL, RelationGetRelid(rel), idxRel, + generateClonedIndexStmt(NULL, idxRel, attmap, RelationGetDescr(rel)->natts, &constraintOid); DefineIndex(RelationGetRelid(rel), @@ -963,23 +1115,19 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, * And foreign keys too. Note that because we're freshly creating the * table, there is no need to verify these new constraints. */ - CloneForeignKeyConstraints(parentId, relationId, NULL); + CloneForeignKeyConstraints(NULL, parent, rel); - heap_close(parent, NoLock); + table_close(parent, NoLock); } /* - * Now add any newly specified column default values and CHECK constraints - * to the new relation. These are passed to us in the form of raw - * parsetrees; we need to transform them to executable expression trees - * before they can be added. The most convenient way to do that is to - * apply the parser's transformExpr routine, but transformExpr doesn't - * work unless we have a pre-existing relation. So, the transformation has - * to be postponed to this final step of CREATE TABLE. + * Now add any newly specified CHECK constraints to the new relation. Same + * as for defaults above, but these need to come after partitioning is set + * up. */ - if (rawDefaults || stmt->constraints) - AddRelationNewConstraints(rel, rawDefaults, stmt->constraints, - true, true, false); + if (stmt->constraints) + AddRelationNewConstraints(rel, NIL, stmt->constraints, + true, true, false, queryString); ObjectAddressSet(address, RelationRelationId, relationId); @@ -1204,6 +1352,7 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, bool is_partition; Form_pg_class classform; LOCKMODE heap_lockmode; + bool invalid_system_index = false; state = (struct DropRelationCallbackState *) arg; relkind = state->relkind; @@ -1266,7 +1415,36 @@ RangeVarCallbackForDropRelation(const RangeVar *rel, Oid relOid, Oid oldRelOid, aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relOid)), rel->relname); - if (!allowSystemTableMods && IsSystemClass(relOid, classform)) + /* + * Check the case of a system index that might have been invalidated by a + * failed concurrent process and allow its drop. For the time being, this + * only concerns indexes of toast relations that became invalid during a + * REINDEX CONCURRENTLY process. + */ + if (IsSystemClass(relOid, classform) && relkind == RELKIND_INDEX) + { + HeapTuple locTuple; + Form_pg_index indexform; + bool indisvalid; + + locTuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(relOid)); + if (!HeapTupleIsValid(locTuple)) + { + ReleaseSysCache(tuple); + return; + } + + indexform = (Form_pg_index) GETSTRUCT(locTuple); + indisvalid = indexform->indisvalid; + ReleaseSysCache(locTuple); + + /* Mark object as being an invalid index of system catalogs */ + if (!indisvalid) + invalid_system_index = true; + } + + /* In the case of an invalid index, it is fine to bypass this check */ + if (!invalid_system_index && !allowSystemTableMods && IsSystemClass(relOid, classform)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", @@ -1332,16 +1510,28 @@ ExecuteTruncate(TruncateStmt *stmt) Relation rel; bool recurse = rv->inh; Oid myrelid; + LOCKMODE lockmode = AccessExclusiveLock; + + myrelid = RangeVarGetRelidExtended(rv, lockmode, + 0, RangeVarCallbackForTruncate, + NULL); + + /* open the relation, we already hold a lock on it */ + rel = table_open(myrelid, NoLock); - rel = heap_openrv(rv, AccessExclusiveLock); - myrelid = RelationGetRelid(rel); /* don't throw error for "TRUNCATE foo, foo" */ if (list_member_oid(relids, myrelid)) { - heap_close(rel, AccessExclusiveLock); + table_close(rel, lockmode); continue; } - truncate_check_rel(rel); + + /* + * RangeVarGetRelidExtended() has done most checks with its callback, + * but other checks with the now-opened Relation remain. + */ + truncate_check_activity(rel); + rels = lappend(rels, rel); relids = lappend_oid(relids, myrelid); /* Log this relation only if needed for logical decoding */ @@ -1353,7 +1543,7 @@ ExecuteTruncate(TruncateStmt *stmt) ListCell *child; List *children; - children = find_all_inheritors(myrelid, AccessExclusiveLock, NULL); + children = find_all_inheritors(myrelid, lockmode, NULL); foreach(child, children) { @@ -1363,8 +1553,26 @@ ExecuteTruncate(TruncateStmt *stmt) continue; /* find_all_inheritors already got lock */ - rel = heap_open(childrelid, NoLock); - truncate_check_rel(rel); + rel = table_open(childrelid, NoLock); + + /* + * It is possible that the parent table has children that are + * temp tables of other backends. We cannot safely access + * such tables (because of buffering issues), and the best + * thing to do is to silently ignore them. Note that this + * check is the same as one of the checks done in + * truncate_check_activity() called below, still it is kept + * here for simplicity. + */ + if (RELATION_IS_OTHER_TEMP(rel)) + { + table_close(rel, lockmode); + continue; + } + + truncate_check_rel(RelationGetRelid(rel), rel->rd_rel); + truncate_check_activity(rel); + rels = lappend(rels, rel); relids = lappend_oid(relids, childrelid); /* Log this relation only if needed for logical decoding */ @@ -1387,7 +1595,7 @@ ExecuteTruncate(TruncateStmt *stmt) { Relation rel = (Relation) lfirst(cell); - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -1418,7 +1626,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, Oid *logrelids; /* - * Open, exclusive-lock, and check all the explicitly-specified relations + * Check the explicitly-specified relations. * * In CASCADE mode, suck in all referencing relations as well. This * requires multiple iterations to find indirectly-dependent relations. At @@ -1443,11 +1651,12 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, Oid relid = lfirst_oid(cell); Relation rel; - rel = heap_open(relid, AccessExclusiveLock); + rel = table_open(relid, AccessExclusiveLock); ereport(NOTICE, (errmsg("truncate cascades to table \"%s\"", RelationGetRelationName(rel)))); - truncate_check_rel(rel); + truncate_check_rel(relid, rel->rd_rel); + truncate_check_activity(rel); rels = lappend(rels, rel); relids = lappend_oid(relids, relid); /* Log this relation only if needed for logical decoding */ @@ -1480,7 +1689,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, foreach(cell, rels) { Relation rel = (Relation) lfirst(cell); - List *seqlist = getOwnedSequences(RelationGetRelid(rel), 0); + List *seqlist = getOwnedSequences(RelationGetRelid(rel)); ListCell *seqcell; foreach(seqcell, seqlist) @@ -1571,7 +1780,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, { Oid heap_relid; Oid toast_relid; - MultiXactId minmulti; /* * This effectively deletes all rows in the table, and may be done @@ -1581,8 +1789,6 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, */ CheckTableForSerializableConflictIn(rel); - minmulti = GetOldestMultiXactId(); - /* * Need the full transaction-safe pushups. * @@ -1590,25 +1796,22 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, * as the relfilenode value. The old storage file is scheduled for * deletion at commit. */ - RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence, - RecentXmin, minmulti); - if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED) - heap_create_init_fork(rel); + RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence); heap_relid = RelationGetRelid(rel); - toast_relid = rel->rd_rel->reltoastrelid; /* * The same for the toast table, if any. */ + toast_relid = rel->rd_rel->reltoastrelid; if (OidIsValid(toast_relid)) { - rel = relation_open(toast_relid, AccessExclusiveLock); - RelationSetNewRelfilenode(rel, rel->rd_rel->relpersistence, - RecentXmin, minmulti); - if (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED) - heap_create_init_fork(rel); - heap_close(rel, NoLock); + Relation toastrel = relation_open(toast_relid, + AccessExclusiveLock); + + RelationSetNewRelfilenode(toastrel, + toastrel->rd_rel->relpersistence); + table_close(toastrel, NoLock); } /* @@ -1631,7 +1834,8 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, } /* - * Write a WAL record to allow this set of actions to be logically decoded. + * Write a WAL record to allow this set of actions to be logically + * decoded. * * Assemble an array of relids so we can write a single WAL record for the * whole action. @@ -1645,7 +1849,7 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, Assert(XLogLogicalInfoActive()); logrelids = palloc(list_length(relids_logged) * sizeof(Oid)); - foreach (cell, relids_logged) + foreach(cell, relids_logged) logrelids[i++] = lfirst_oid(cell); xlrec.dbId = MyDatabaseId; @@ -1691,43 +1895,52 @@ ExecuteTruncateGuts(List *explicit_rels, List *relids, List *relids_logged, { Relation rel = (Relation) lfirst(cell); - heap_close(rel, NoLock); + table_close(rel, NoLock); } } /* - * Check that a given rel is safe to truncate. Subroutine for ExecuteTruncate + * Check that a given relation is safe to truncate. Subroutine for + * ExecuteTruncate() and RangeVarCallbackForTruncate(). */ static void -truncate_check_rel(Relation rel) +truncate_check_rel(Oid relid, Form_pg_class reltuple) { AclResult aclresult; + char *relname = NameStr(reltuple->relname); /* * Only allow truncate on regular tables and partitioned tables (although, * the latter are only being included here for the following checks; no * physical truncation will occur in their case.) */ - if (rel->rd_rel->relkind != RELKIND_RELATION && - rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) + if (reltuple->relkind != RELKIND_RELATION && + reltuple->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is not a table", - RelationGetRelationName(rel)))); + errmsg("\"%s\" is not a table", relname))); /* Permissions checks */ - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_TRUNCATE); + aclresult = pg_class_aclcheck(relid, GetUserId(), ACL_TRUNCATE); if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind), - RelationGetRelationName(rel)); + aclcheck_error(aclresult, get_relkind_objtype(reltuple->relkind), + relname); - if (!allowSystemTableMods && IsSystemRelation(rel)) + if (!allowSystemTableMods && IsSystemClass(relid, reltuple)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", - RelationGetRelationName(rel)))); + relname))); +} +/* + * Set of extra sanity checks to check if a given relation is safe to + * truncate. This is split with truncate_check_rel() as + * RangeVarCallbackForTruncate() cannot open a Relation yet. + */ +static void +truncate_check_activity(Relation rel) +{ /* * Don't allow truncate on temp tables of other backends ... their local * buffer manager is not going to cope. @@ -1773,15 +1986,13 @@ storage_name(char c) * Input arguments: * 'schema' is the column/attribute definition for the table. (It's a list * of ColumnDef's.) It is destructively changed. - * 'supers' is a list of names (as RangeVar nodes) of parent relations. + * 'supers' is a list of OIDs of parent relations, already locked by caller. * 'relpersistence' is a persistence type of the table. * 'is_partition' tells if the table is a partition * * Output arguments: - * 'supOids' receives a list of the OIDs of the parent relations. * 'supconstr' receives a list of constraints belonging to the parents, * updated as necessary to be valid for the child. - * 'supOidCount' is set to the number of parents that have OID columns. * * Return value: * Completed schema list. @@ -1827,18 +2038,15 @@ storage_name(char c) */ static List * MergeAttributes(List *schema, List *supers, char relpersistence, - bool is_partition, List **supOids, List **supconstr, - int *supOidCount) + bool is_partition, List **supconstr) { - ListCell *entry; List *inhSchema = NIL; - List *parentOids = NIL; List *constraints = NIL; - int parentsWithOids = 0; bool have_bogus_defaults = false; int child_attno; static Node bogus_marker = {0}; /* marks conflicting defaults */ List *saved_schema = NIL; + ListCell *entry; /* * Check for and reject tables with too many columns. We perform this @@ -1857,47 +2065,42 @@ MergeAttributes(List *schema, List *supers, char relpersistence, errmsg("tables can have at most %d columns", MaxHeapAttributeNumber))); - /* - * In case of a partition, there are no new column definitions, only dummy - * ColumnDefs created for column constraints. We merge them with the - * constraints inherited from the parent. - */ - if (is_partition) - { - saved_schema = schema; - schema = NIL; - } - /* * Check for duplicate names in the explicit list of attributes. * * Although we might consider merging such entries in the same way that we * handle name conflicts for inherited attributes, it seems to make more * sense to assume such conflicts are errors. + * + * We don't use foreach() here because we have two nested loops over the + * schema list, with possible element deletions in the inner one. If we + * used foreach_delete_current() it could only fix up the state of one of + * the loops, so it seems cleaner to use looping over list indexes for + * both loops. Note that any deletion will happen beyond where the outer + * loop is, so its index never needs adjustment. */ - foreach(entry, schema) + for (int coldefpos = 0; coldefpos < list_length(schema); coldefpos++) { - ColumnDef *coldef = lfirst(entry); - ListCell *rest = lnext(entry); - ListCell *prev = entry; - - if (coldef->typeName == NULL) + ColumnDef *coldef = list_nth_node(ColumnDef, schema, coldefpos); + if (!is_partition && coldef->typeName == NULL) + { /* * Typed table column option that does not belong to a column from * the type. This works because the columns from the type come - * first in the list. + * first in the list. (We omit this check for partition column + * lists; those are processed separately below.) */ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" does not exist", coldef->colname))); + } - while (rest != NULL) + /* restpos scans all entries beyond coldef; incr is in loop body */ + for (int restpos = coldefpos + 1; restpos < list_length(schema);) { - ColumnDef *restdef = lfirst(rest); - ListCell *next = lnext(rest); /* need to save it in case we - * delete it */ + ColumnDef *restdef = list_nth_node(ColumnDef, schema, restpos); if (strcmp(coldef->colname, restdef->colname) == 0) { @@ -1911,7 +2114,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, coldef->cooked_default = restdef->cooked_default; coldef->constraints = restdef->constraints; coldef->is_from_type = false; - list_delete_cell(schema, rest, prev); + schema = list_delete_nth_cell(schema, restpos); } else ereport(ERROR, @@ -1919,11 +2122,22 @@ MergeAttributes(List *schema, List *supers, char relpersistence, errmsg("column \"%s\" specified more than once", coldef->colname))); } - prev = rest; - rest = next; + else + restpos++; } } + /* + * In case of a partition, there are no new column definitions, only dummy + * ColumnDefs created for column constraints. Set them aside for now and + * process them at the end. + */ + if (is_partition) + { + saved_schema = schema; + schema = NIL; + } + /* * Scan the parents left-to-right, and merge their attributes to form a * list of inherited attributes (inhSchema). Also check to see if we need @@ -1932,31 +2146,23 @@ MergeAttributes(List *schema, List *supers, char relpersistence, child_attno = 0; foreach(entry, supers) { - RangeVar *parent = (RangeVar *) lfirst(entry); + Oid parent = lfirst_oid(entry); Relation relation; TupleDesc tupleDesc; TupleConstr *constr; AttrNumber *newattno; AttrNumber parent_attno; + /* caller already got lock */ + relation = table_open(parent, NoLock); + /* - * A self-exclusive lock is needed here. If two backends attempt to - * add children to the same parent simultaneously, and that parent has - * no pre-existing children, then both will attempt to update the - * parent's relhassubclass field, leading to a "tuple concurrently - * updated" error. Also, this interlocks against a concurrent ANALYZE - * on the parent table, which might otherwise be attempting to clear - * the parent's relhassubclass field, if its previous children were - * recently dropped. - * - * If the child table is a partition, then we instead grab an - * exclusive lock on the parent because its partition descriptor will - * be changed by addition of the new partition. + * Check for active uses of the parent partitioned table in the + * current transaction, such as being used in some manner by an + * enclosing command. */ - if (!is_partition) - relation = heap_openrv(parent, ShareUpdateExclusiveLock); - else - relation = heap_openrv(parent, AccessExclusiveLock); + if (is_partition) + CheckTableNotInUse(relation, "CREATE TABLE .. PARTITION OF"); /* * We do not allow partitioned tables and partitions to participate in @@ -1967,12 +2173,12 @@ MergeAttributes(List *schema, List *supers, char relpersistence, ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot inherit from partitioned table \"%s\"", - parent->relname))); + RelationGetRelationName(relation)))); if (relation->rd_rel->relispartition && !is_partition) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot inherit from partition \"%s\"", - parent->relname))); + RelationGetRelationName(relation)))); if (relation->rd_rel->relkind != RELKIND_RELATION && relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE && @@ -1980,7 +2186,20 @@ MergeAttributes(List *schema, List *supers, char relpersistence, ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("inherited relation \"%s\" is not a table or foreign table", - parent->relname))); + RelationGetRelationName(relation)))); + + /* + * If the parent is permanent, so must be all of its partitions. Note + * that inheritance allows that case. + */ + if (is_partition && + relation->rd_rel->relpersistence != RELPERSISTENCE_TEMP && + relpersistence == RELPERSISTENCE_TEMP) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create a temporary relation as partition of permanent relation \"%s\"", + RelationGetRelationName(relation)))); + /* Permanent rels cannot inherit from temporary ones */ if (relpersistence != RELPERSISTENCE_TEMP && relation->rd_rel->relpersistence == RELPERSISTENCE_TEMP) @@ -1989,7 +2208,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, errmsg(!is_partition ? "cannot inherit from temporary relation \"%s\"" : "cannot create a permanent relation as partition of temporary relation \"%s\"", - parent->relname))); + RelationGetRelationName(relation)))); /* If existing rel is temp, it must belong to this session */ if (relation->rd_rel->relpersistence == RELPERSISTENCE_TEMP && @@ -2008,20 +2227,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence, aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(relation->rd_rel->relkind), RelationGetRelationName(relation)); - /* - * Reject duplications in the list of parents. - */ - if (list_member_oid(parentOids, RelationGetRelid(relation))) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_TABLE), - errmsg("relation \"%s\" would be inherited from more than once", - parent->relname))); - - parentOids = lappend_oid(parentOids, RelationGetRelid(relation)); - - if (relation->rd_rel->relhasoids) - parentsWithOids++; - tupleDesc = RelationGetDescr(relation); constr = tupleDesc->constr; @@ -2105,6 +2310,13 @@ MergeAttributes(List *schema, List *supers, char relpersistence, def->is_not_null |= attribute->attnotnull; /* Default and other constraints are handled below */ newattno[parent_attno - 1] = exist_attno; + + /* Check for GENERATED conflicts */ + if (def->generated != attribute->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("inherited column \"%s\" has a generation conflict", + attributeName))); } else { @@ -2119,10 +2331,10 @@ MergeAttributes(List *schema, List *supers, char relpersistence, def->is_local = false; def->is_not_null = attribute->attnotnull; def->is_from_type = false; - def->is_from_parent = true; def->storage = attribute->attstorage; def->raw_default = NULL; def->cooked_default = NULL; + def->generated = attribute->attgenerated; def->collClause = NULL; def->collOid = attribute->attcollation; def->constraints = NIL; @@ -2241,7 +2453,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, * That will prevent someone else from deleting or ALTERing the parent * before the child is committed. */ - heap_close(relation, NoLock); + table_close(relation, NoLock); } /* @@ -2372,59 +2584,51 @@ MergeAttributes(List *schema, List *supers, char relpersistence, /* * Now that we have the column definition list for a partition, we can * check whether the columns referenced in the column constraint specs - * actually exist. Also, we merge the constraints into the corresponding - * column definitions. + * actually exist. Also, we merge NOT NULL and defaults into each + * corresponding column definition. */ - if (is_partition && list_length(saved_schema) > 0) + if (is_partition) { - schema = list_concat(schema, saved_schema); - - foreach(entry, schema) + foreach(entry, saved_schema) { - ColumnDef *coldef = lfirst(entry); - ListCell *rest = lnext(entry); - ListCell *prev = entry; + ColumnDef *restdef = lfirst(entry); + bool found = false; + ListCell *l; - /* - * Partition column option that does not belong to a column from - * the parent. This works because the columns from the parent - * come first in the list (see above). - */ - if (coldef->typeName == NULL) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" does not exist", - coldef->colname))); - while (rest != NULL) + foreach(l, schema) { - ColumnDef *restdef = lfirst(rest); - ListCell *next = lnext(rest); /* need to save it in case we - * delete it */ + ColumnDef *coldef = lfirst(l); if (strcmp(coldef->colname, restdef->colname) == 0) { + found = true; + coldef->is_not_null |= restdef->is_not_null; + /* - * merge the column options into the column from the - * parent + * Override the parent's default value for this column + * (coldef->cooked_default) with the partition's local + * definition (restdef->raw_default), if there's one. It + * should be physically impossible to get a cooked default + * in the local definition or a raw default in the + * inherited definition, but make sure they're nulls, for + * future-proofing. */ - if (coldef->is_from_parent) + Assert(restdef->cooked_default == NULL); + Assert(coldef->raw_default == NULL); + if (restdef->raw_default) { - coldef->is_not_null = restdef->is_not_null; coldef->raw_default = restdef->raw_default; - coldef->cooked_default = restdef->cooked_default; - coldef->constraints = restdef->constraints; - coldef->is_from_parent = false; - list_delete_cell(schema, rest, prev); + coldef->cooked_default = NULL; } - else - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_COLUMN), - errmsg("column \"%s\" specified more than once", - coldef->colname))); } - prev = rest; - rest = next; } + + /* complain for constraints on columns not in parent */ + if (!found) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" does not exist", + restdef->colname))); } } @@ -2447,9 +2651,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, } } - *supOids = parentOids; *supconstr = constraints; - *supOidCount = parentsWithOids; return schema; } @@ -2529,7 +2731,7 @@ StoreCatalogInheritance(Oid relationId, List *supers, * and then entered into pg_ipl. Since that catalog doesn't exist * anymore, there's no need to look for indirect ancestors.) */ - relation = heap_open(InheritsRelationId, RowExclusiveLock); + relation = table_open(InheritsRelationId, RowExclusiveLock); seqNumber = 1; foreach(entry, supers) @@ -2541,7 +2743,7 @@ StoreCatalogInheritance(Oid relationId, List *supers, seqNumber++; } - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* @@ -2635,7 +2837,7 @@ SetRelationHasSubclass(Oid relationId, bool relhassubclass) /* * Fetch a modifiable copy of the tuple, modify it, update pg_class. */ - relationRelation = heap_open(RelationRelationId, RowExclusiveLock); + relationRelation = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relationId); @@ -2653,7 +2855,7 @@ SetRelationHasSubclass(Oid relationId, bool relhassubclass) } heap_freetuple(tuple); - heap_close(relationRelation, RowExclusiveLock); + table_close(relationRelation, RowExclusiveLock); } /* @@ -2798,7 +3000,7 @@ renameatt_internal(Oid myrelid, renameatt_internal(lfirst_oid(lo), oldattname, newattname, true, true, 0, behavior); } - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); atttup = SearchSysCacheCopyAttName(myrelid, oldattname); if (!HeapTupleIsValid(atttup)) @@ -2842,7 +3044,7 @@ renameatt_internal(Oid myrelid, heap_freetuple(atttup); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); relation_close(targetrelation, NoLock); /* close rel but keep lock */ @@ -2995,7 +3197,7 @@ rename_constraint_internal(Oid myrelid, || con->contype == CONSTRAINT_UNIQUE || con->contype == CONSTRAINT_EXCLUSION)) /* rename the index; this renames the constraint as well */ - RenameRelationInternal(con->conindid, newconname, false); + RenameRelationInternal(con->conindid, newconname, false, true); else RenameConstraintById(constraintOid, newconname); @@ -3004,7 +3206,14 @@ rename_constraint_internal(Oid myrelid, ReleaseSysCache(tuple); if (targetrelation) + { + /* + * Invalidate relcache so as others can see the new constraint name. + */ + CacheInvalidateRelcache(targetrelation); + relation_close(targetrelation, NoLock); /* close rel but keep lock */ + } return address; } @@ -3021,13 +3230,13 @@ RenameConstraint(RenameStmt *stmt) HeapTuple tup; typid = typenameTypeId(NULL, makeTypeNameFromNameList(castNode(List, stmt->object))); - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid)); if (!HeapTupleIsValid(tup)) elog(ERROR, "cache lookup failed for type %u", typid); checkDomainOwner(tup); ReleaseSysCache(tup); - heap_close(rel, NoLock); + table_close(rel, NoLock); } else { @@ -3063,6 +3272,7 @@ RenameConstraint(RenameStmt *stmt) ObjectAddress RenameRelation(RenameStmt *stmt) { + bool is_index = stmt->renameType == OBJECT_INDEX; Oid relid; ObjectAddress address; @@ -3074,7 +3284,8 @@ RenameRelation(RenameStmt *stmt) * Lock level used here should match RenameRelationInternal, to avoid lock * escalation. */ - relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, + relid = RangeVarGetRelidExtended(stmt->relation, + is_index ? ShareUpdateExclusiveLock : AccessExclusiveLock, stmt->missing_ok ? RVR_MISSING_OK : 0, RangeVarCallbackForAlterRelation, (void *) stmt); @@ -3088,7 +3299,7 @@ RenameRelation(RenameStmt *stmt) } /* Do the work */ - RenameRelationInternal(relid, stmt->newname, false); + RenameRelationInternal(relid, stmt->newname, false, is_index); ObjectAddressSet(address, RelationRelationId, relid); @@ -3097,15 +3308,9 @@ RenameRelation(RenameStmt *stmt) /* * RenameRelationInternal - change the name of a relation - * - * XXX - When renaming sequences, we don't bother to modify the - * sequence name that is stored within the sequence itself - * (this would cause problems with MVCC). In the future, - * the sequence name should probably be removed from the - * sequence, AFAIK there's no need for it to be there. */ void -RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal) +RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal, bool is_index) { Relation targetrelation; Relation relrelation; /* for RELATION relation */ @@ -3114,17 +3319,22 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal) Oid namespaceId; /* - * Grab an exclusive lock on the target table, index, sequence, view, - * materialized view, or foreign table, which we will NOT release until - * end of transaction. + * Grab a lock on the target relation, which we will NOT release until end + * of transaction. We need at least a self-exclusive lock so that + * concurrent DDL doesn't overwrite the rename if they start updating + * while still seeing the old version. The lock also guards against + * triggering relcache reloads in concurrent sessions, which might not + * handle this information changing under them. For indexes, we can use a + * reduced lock level because RelationReloadIndexInfo() handles indexes + * specially. */ - targetrelation = relation_open(myrelid, AccessExclusiveLock); + targetrelation = relation_open(myrelid, is_index ? ShareUpdateExclusiveLock : AccessExclusiveLock); namespaceId = RelationGetNamespace(targetrelation); /* * Find relation's pg_class tuple, and make sure newrelname isn't in use. */ - relrelation = heap_open(RelationRelationId, RowExclusiveLock); + relrelation = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid)); if (!HeapTupleIsValid(reltup)) /* shouldn't happen */ @@ -3149,7 +3359,7 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal) InvalidOid, is_internal); heap_freetuple(reltup); - heap_close(relrelation, RowExclusiveLock); + table_close(relrelation, RowExclusiveLock); /* * Also rename the associated type, if any. @@ -3171,7 +3381,7 @@ RenameRelationInternal(Oid myrelid, const char *newrelname, bool is_internal) } /* - * Close rel, but keep exclusive lock! + * Close rel, but keep lock! */ relation_close(targetrelation, NoLock); } @@ -3211,8 +3421,7 @@ CheckTableNotInUse(Relation rel, const char *stmt) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), /* translator: first %s is a SQL command, eg ALTER TABLE */ - errmsg("cannot %s \"%s\" because " - "it is being used by active queries in this session", + errmsg("cannot %s \"%s\" because it is being used by active queries in this session", stmt, RelationGetRelationName(rel)))); if (rel->rd_rel->relkind != RELKIND_INDEX && @@ -3221,8 +3430,7 @@ CheckTableNotInUse(Relation rel, const char *stmt) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), /* translator: first %s is a SQL command, eg ALTER TABLE */ - errmsg("cannot %s \"%s\" because " - "it has pending trigger events", + errmsg("cannot %s \"%s\" because it has pending trigger events", stmt, RelationGetRelationName(rel)))); } @@ -3374,7 +3582,6 @@ AlterTableGetLockLevel(List *cmds) * to SELECT */ case AT_SetTableSpace: /* must rewrite heap */ case AT_AlterColumnType: /* must rewrite heap */ - case AT_AddOids: /* must rewrite heap */ cmd_lockmode = AccessExclusiveLock; break; @@ -3391,7 +3598,8 @@ AlterTableGetLockLevel(List *cmds) /* * Removing constraints can affect SELECTs that have been - * optimised assuming the constraint holds true. + * optimized assuming the constraint holds true. See also + * CloneFkReferenced. */ case AT_DropConstraint: /* as DROP INDEX */ case AT_DropNotNull: /* may change some SQL plans */ @@ -3403,7 +3611,7 @@ AlterTableGetLockLevel(List *cmds) */ case AT_DropColumn: /* change visible to SELECT */ case AT_AddColumnToView: /* CREATE VIEW */ - case AT_DropOids: /* calls AT_DropColumn */ + case AT_DropOids: /* used to equiv to DropColumn */ case AT_EnableAlwaysRule: /* may change SELECT rules */ case AT_EnableReplicaRule: /* may change SELECT rules */ case AT_EnableRule: /* may change SELECT rules */ @@ -3574,10 +3782,22 @@ AlterTableGetLockLevel(List *cmds) break; case AT_AttachPartition: + cmd_lockmode = ShareUpdateExclusiveLock; + break; + case AT_DetachPartition: cmd_lockmode = AccessExclusiveLock; break; + case AT_CheckNotNull: + + /* + * This only examines the table's schema; but lock must be + * strong enough to prevent concurrent DROP NOT NULL. + */ + cmd_lockmode = AccessShareLock; + break; + default: /* oops */ elog(ERROR, "unrecognized alter table type: %d", (int) cmd->subtype); @@ -3688,29 +3908,36 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, break; case AT_AddIdentity: ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE); + /* This command never recurses */ pass = AT_PASS_ADD_CONSTR; break; - case AT_DropIdentity: - ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE); - pass = AT_PASS_DROP; - break; case AT_SetIdentity: ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE); + /* This command never recurses */ pass = AT_PASS_COL_ATTRS; break; + case AT_DropIdentity: + ATSimplePermissions(rel, ATT_TABLE | ATT_VIEW | ATT_FOREIGN_TABLE); + /* This command never recurses */ + pass = AT_PASS_DROP; + break; case AT_DropNotNull: /* ALTER COLUMN DROP NOT NULL */ ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); ATPrepDropNotNull(rel, recurse, recursing); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode); - /* No command-specific prep needed */ pass = AT_PASS_DROP; break; case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); - ATPrepSetNotNull(rel, recurse, recursing); + /* Need command-specific recursion decision */ + ATPrepSetNotNull(wqueue, rel, cmd, recurse, recursing, lockmode); + pass = AT_PASS_COL_ATTRS; + break; + case AT_CheckNotNull: /* check column is already marked NOT NULL */ + ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode); /* No command-specific prep needed */ - pass = AT_PASS_ADD_CONSTR; + pass = AT_PASS_COL_ATTRS; break; case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */ ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode); @@ -3759,7 +3986,8 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, break; case AT_DropConstraint: /* DROP CONSTRAINT */ ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); - /* Recursion occurs during execution phase */ + ATCheckPartitionsNotInUse(rel, lockmode); + /* Other recursion occurs during execution phase */ /* No command-specific prep needed except saving recurse flag */ if (recurse) cmd->subtype = AT_DropConstraintRecurse; @@ -3812,29 +4040,13 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd, } pass = AT_PASS_MISC; break; - case AT_AddOids: /* SET WITH OIDS */ - ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); - if (!rel->rd_rel->relhasoids || recursing) - ATPrepAddOids(wqueue, rel, recurse, cmd, lockmode); - /* Recursion occurs during execution phase */ - pass = AT_PASS_ADD_COL; - break; case AT_DropOids: /* SET WITHOUT OIDS */ ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); - /* Performs own recursion */ - if (rel->rd_rel->relhasoids) - { - AlterTableCmd *dropCmd = makeNode(AlterTableCmd); - - dropCmd->subtype = AT_DropColumn; - dropCmd->name = pstrdup("oid"); - dropCmd->behavior = cmd->behavior; - ATPrepCmd(wqueue, rel, dropCmd, recurse, false, lockmode); - } pass = AT_PASS_DROP; break; case AT_SetTableSpace: /* SET TABLESPACE */ - ATSimplePermissions(rel, ATT_TABLE | ATT_MATVIEW | ATT_INDEX); + ATSimplePermissions(rel, ATT_TABLE | ATT_MATVIEW | ATT_INDEX | + ATT_PARTITIONED_INDEX); /* This command never recurses */ ATPrepSetTableSpace(tab, rel, cmd->name, lockmode); pass = AT_PASS_MISC; /* doesn't actually matter */ @@ -4017,12 +4229,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_AddColumn: /* ADD COLUMN */ case AT_AddColumnToView: /* add column via CREATE OR REPLACE VIEW */ address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - false, false, false, - false, lockmode); + false, false, + cmd->missing_ok, lockmode); break; case AT_AddColumnRecurse: address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - false, true, false, + true, false, cmd->missing_ok, lockmode); break; case AT_ColumnDefault: /* ALTER COLUMN DEFAULT */ @@ -4043,6 +4255,9 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_SetNotNull: /* ALTER COLUMN SET NOT NULL */ address = ATExecSetNotNull(tab, rel, cmd->name, lockmode); break; + case AT_CheckNotNull: /* check column is already marked NOT NULL */ + ATExecCheckNotNull(tab, rel, cmd->name, lockmode); + break; case AT_SetStatistics: /* ALTER COLUMN SET STATISTICS */ address = ATExecSetStatistics(rel, cmd->name, cmd->num, cmd->def, lockmode); break; @@ -4146,34 +4361,20 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel, case AT_SetLogged: /* SET LOGGED */ case AT_SetUnLogged: /* SET UNLOGGED */ break; - case AT_AddOids: /* SET WITH OIDS */ - /* Use the ADD COLUMN code, unless prep decided to do nothing */ - if (cmd->def != NULL) - address = - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - true, false, false, - cmd->missing_ok, lockmode); - break; - case AT_AddOidsRecurse: /* SET WITH OIDS */ - /* Use the ADD COLUMN code, unless prep decided to do nothing */ - if (cmd->def != NULL) - address = - ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def, - true, true, false, - cmd->missing_ok, lockmode); - break; case AT_DropOids: /* SET WITHOUT OIDS */ - - /* - * Nothing to do here; we'll have generated a DropColumn - * subcommand to do the real work - */ + /* nothing to do here, oid columns don't exist anymore */ break; case AT_SetTableSpace: /* SET TABLESPACE */ /* - * Nothing to do here; Phase 3 does the work + * Only do this for partitioned tables and indexes, for which this + * is just a catalog change. Other relation types which have + * storage are handled by Phase 3. */ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE || + rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + ATExecSetTableSpaceNoStorage(rel, tab->newTableSpace); + break; case AT_SetRelOptions: /* SET (...) */ case AT_ResetRelOptions: /* RESET (...) */ @@ -4303,13 +4504,8 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) { AlteredTableInfo *tab = (AlteredTableInfo *) lfirst(ltab); - /* - * Foreign tables have no storage, nor do partitioned tables and - * indexes. - */ - if (tab->relkind == RELKIND_FOREIGN_TABLE || - tab->relkind == RELKIND_PARTITIONED_TABLE || - tab->relkind == RELKIND_PARTITIONED_INDEX) + /* Relations without storage may be ignored here */ + if (!RELKIND_HAS_STORAGE(tab->relkind)) continue; /* @@ -4330,9 +4526,9 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) { Relation rel; - rel = heap_open(tab->relid, NoLock); + rel = table_open(tab->relid, NoLock); find_composite_type_dependencies(rel->rd_rel->reltype, rel, NULL); - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* @@ -4355,7 +4551,7 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) Oid NewTableSpace; char persistence; - OldHeap = heap_open(tab->relid, NoLock); + OldHeap = table_open(tab->relid, NoLock); /* * We don't support rewriting of system catalogs; there are too @@ -4399,7 +4595,7 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) persistence = tab->chgPersistence ? tab->newrelpersistence : OldHeap->rd_rel->relpersistence; - heap_close(OldHeap, NoLock); + table_close(OldHeap, NoLock); /* * Fire off an Event Trigger now, before actually rewriting the @@ -4459,10 +4655,11 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) else { /* - * Test the current data within the table against new constraints - * generated by ALTER TABLE commands, but don't rebuild data. + * If required, test the current data within the table against new + * constraints generated by ALTER TABLE commands, but don't + * rebuild data. */ - if (tab->constraints != NIL || tab->new_notnull || + if (tab->constraints != NIL || tab->verify_new_notnull || tab->partition_constraint != NULL) ATRewriteTable(tab, InvalidOid, lockmode); @@ -4488,6 +4685,10 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) Relation rel = NULL; ListCell *lcon; + /* Relations without storage may be ignored here too */ + if (!RELKIND_HAS_STORAGE(tab->relkind)) + continue; + foreach(lcon, tab->constraints) { NewConstraint *con = lfirst(lcon); @@ -4500,10 +4701,10 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) if (rel == NULL) { /* Long since locked, no need for another */ - rel = heap_open(tab->relid, NoLock); + rel = table_open(tab->relid, NoLock); } - refrel = heap_open(con->refrelid, RowShareLock); + refrel = table_open(con->refrelid, RowShareLock); validateForeignKeyConstraint(fkconstraint->conname, rel, refrel, con->refindid, @@ -4514,12 +4715,12 @@ ATRewriteTables(AlterTableStmt *parsetree, List **wqueue, LOCKMODE lockmode) * that when we inserted the row earlier. */ - heap_close(refrel, NoLock); + table_close(refrel, NoLock); } } if (rel) - heap_close(rel, NoLock); + table_close(rel, NoLock); } } @@ -4542,26 +4743,26 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) EState *estate; CommandId mycid; BulkInsertState bistate; - int hi_options; + int ti_options; ExprState *partqualstate = NULL; /* * Open the relation(s). We have surely already locked the existing * table. */ - oldrel = heap_open(tab->relid, NoLock); + oldrel = table_open(tab->relid, NoLock); oldTupDesc = tab->oldDesc; newTupDesc = RelationGetDescr(oldrel); /* includes all mods */ if (OidIsValid(OIDNewHeap)) - newrel = heap_open(OIDNewHeap, lockmode); + newrel = table_open(OIDNewHeap, lockmode); else newrel = NULL; /* - * Prepare a BulkInsertState and options for heap_insert. Because we're - * building a new heap, we can skip WAL-logging and fsync it to disk at - * the end instead (unless WAL-logging is required for archiving or + * Prepare a BulkInsertState and options for table_tuple_insert. Because + * we're building a new heap, we can skip WAL-logging and fsync it to disk + * at the end instead (unless WAL-logging is required for archiving or * streaming replication). The FSM is empty too, so don't bother using it. */ if (newrel) @@ -4569,16 +4770,16 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) mycid = GetCurrentCommandId(true); bistate = GetBulkInsertState(); - hi_options = HEAP_INSERT_SKIP_FSM; + ti_options = TABLE_INSERT_SKIP_FSM; if (!XLogIsNeeded()) - hi_options |= HEAP_INSERT_SKIP_WAL; + ti_options |= TABLE_INSERT_SKIP_WAL; } else { /* keep compiler quiet about using these uninitialized */ mycid = 0; bistate = NULL; - hi_options = 0; + ti_options = 0; } /* @@ -4623,13 +4824,13 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) } notnull_attrs = NIL; - if (newrel || tab->new_notnull) + if (newrel || tab->verify_new_notnull) { /* - * If we are rebuilding the tuples OR if we added any new NOT NULL - * constraints, check all not-null constraints. This is a bit of - * overkill but it minimizes risk of bugs, and heap_attisnull is a - * pretty cheap test anyway. + * If we are rebuilding the tuples OR if we added any new but not + * verified NOT NULL constraints, check all not-null constraints. This + * is a bit of overkill but it minimizes risk of bugs, and + * heap_attisnull is a pretty cheap test anyway. */ for (i = 0; i < newTupDesc->natts; i++) { @@ -4645,12 +4846,9 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) if (newrel || needscan) { ExprContext *econtext; - Datum *values; - bool *isnull; TupleTableSlot *oldslot; TupleTableSlot *newslot; - HeapScanDesc scan; - HeapTuple tuple; + TableScanDesc scan; MemoryContext oldCxt; List *dropped_attrs = NIL; ListCell *lc; @@ -4678,19 +4876,27 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) econtext = GetPerTupleExprContext(estate); /* - * Make tuple slots for old and new tuples. Note that even when the - * tuples are the same, the tupDescs might not be (consider ADD COLUMN - * without a default). + * Create necessary tuple slots. When rewriting, two slots are needed, + * otherwise one suffices. In the case where one slot suffices, we + * need to use the new tuple descriptor, otherwise some constraints + * can't be evaluated. Note that even when the tuple layout is the + * same and no rewrite is required, the tupDescs might not be + * (consider ADD COLUMN without a default). */ - oldslot = MakeSingleTupleTableSlot(oldTupDesc); - newslot = MakeSingleTupleTableSlot(newTupDesc); - - /* Preallocate values/isnull arrays */ - i = Max(newTupDesc->natts, oldTupDesc->natts); - values = (Datum *) palloc(i * sizeof(Datum)); - isnull = (bool *) palloc(i * sizeof(bool)); - memset(values, 0, i * sizeof(Datum)); - memset(isnull, true, i * sizeof(bool)); + if (tab->rewrite) + { + Assert(newrel != NULL); + oldslot = MakeSingleTupleTableSlot(oldTupDesc, + table_slot_callbacks(oldrel)); + newslot = MakeSingleTupleTableSlot(newTupDesc, + table_slot_callbacks(newrel)); + } + else + { + oldslot = MakeSingleTupleTableSlot(newTupDesc, + table_slot_callbacks(oldrel)); + newslot = NULL; + } /* * Any attributes that are dropped according to the new tuple @@ -4708,7 +4914,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) * checking all the constraints. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(oldrel, snapshot, 0, NULL); + scan = table_beginscan(oldrel, snapshot, 0, NULL); /* * Switch to per-tuple memory context and reset it for each tuple @@ -4716,63 +4922,69 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) */ oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while (table_scan_getnextslot(scan, ForwardScanDirection, oldslot)) { + TupleTableSlot *insertslot; + if (tab->rewrite > 0) { - Oid tupOid = InvalidOid; - /* Extract data from old tuple */ - heap_deform_tuple(tuple, oldTupDesc, values, isnull); - if (oldTupDesc->tdhasoid) - tupOid = HeapTupleGetOid(tuple); + slot_getallattrs(oldslot); + ExecClearTuple(newslot); + + /* copy attributes */ + memcpy(newslot->tts_values, oldslot->tts_values, + sizeof(Datum) * oldslot->tts_nvalid); + memcpy(newslot->tts_isnull, oldslot->tts_isnull, + sizeof(bool) * oldslot->tts_nvalid); /* Set dropped attributes to null in new tuple */ foreach(lc, dropped_attrs) - isnull[lfirst_int(lc)] = true; + newslot->tts_isnull[lfirst_int(lc)] = true; /* * Process supplied expressions to replace selected columns. * Expression inputs come from the old tuple. */ - ExecStoreTuple(tuple, oldslot, InvalidBuffer, false); econtext->ecxt_scantuple = oldslot; foreach(l, tab->newvals) { NewColumnValue *ex = lfirst(l); - values[ex->attnum - 1] = ExecEvalExpr(ex->exprstate, - econtext, - &isnull[ex->attnum - 1]); + newslot->tts_values[ex->attnum - 1] + = ExecEvalExpr(ex->exprstate, + econtext, + &newslot->tts_isnull[ex->attnum - 1]); } - /* - * Form the new tuple. Note that we don't explicitly pfree it, - * since the per-tuple memory context will be reset shortly. - */ - tuple = heap_form_tuple(newTupDesc, values, isnull); - - /* Preserve OID, if any */ - if (newTupDesc->tdhasoid) - HeapTupleSetOid(tuple, tupOid); + ExecStoreVirtualTuple(newslot); /* * Constraints might reference the tableoid column, so * initialize t_tableOid before evaluating them. */ - tuple->t_tableOid = RelationGetRelid(oldrel); + newslot->tts_tableOid = RelationGetRelid(oldrel); + insertslot = newslot; + } + else + { + /* + * If there's no rewrite, old and new table are guaranteed to + * have the same AM, so we can just use the old slot to verify + * new constraints etc. + */ + insertslot = oldslot; } /* Now check any constraints on the possibly-changed tuple */ - ExecStoreTuple(tuple, newslot, InvalidBuffer, false); - econtext->ecxt_scantuple = newslot; + econtext->ecxt_scantuple = insertslot; foreach(l, notnull_attrs) { int attn = lfirst_int(l); - if (heap_attisnull(tuple, attn + 1, newTupDesc)) + if (slot_attisnull(insertslot, attn + 1)) { Form_pg_attribute attr = TupleDescAttr(newTupDesc, attn); @@ -4821,7 +5033,8 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) /* Write the tuple out to the new relation */ if (newrel) - heap_insert(newrel, tuple, mycid, hi_options, bistate); + table_tuple_insert(newrel, insertslot, mycid, + ti_options, bistate); ResetExprContext(econtext); @@ -4829,25 +5042,24 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode) } MemoryContextSwitchTo(oldCxt); - heap_endscan(scan); + table_endscan(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(oldslot); - ExecDropSingleTupleTableSlot(newslot); + if (newslot) + ExecDropSingleTupleTableSlot(newslot); } FreeExecutorState(estate); - heap_close(oldrel, NoLock); + table_close(oldrel, NoLock); if (newrel) { FreeBulkInsertState(bistate); - /* If we skipped writing WAL, then we need to sync the heap. */ - if (hi_options & HEAP_INSERT_SKIP_WAL) - heap_sync(newrel); + table_finish_bulk_insert(newrel, ti_options); - heap_close(newrel, NoLock); + table_close(newrel, NoLock); } } @@ -5014,8 +5226,9 @@ ATSimpleRecursion(List **wqueue, Relation rel, AlterTableCmd *cmd, bool recurse, LOCKMODE lockmode) { /* - * Propagate to children if desired. Only plain tables and foreign tables - * have children, so no need to search for other relkinds. + * Propagate to children if desired. Only plain tables, foreign tables + * and partitioned tables have children, so no need to search for other + * relkinds. */ if (recurse && (rel->rd_rel->relkind == RELKIND_RELATION || @@ -5049,6 +5262,36 @@ ATSimpleRecursion(List **wqueue, Relation rel, } } +/* + * Obtain list of partitions of the given table, locking them all at the given + * lockmode and ensuring that they all pass CheckTableNotInUse. + * + * This function is a no-op if the given relation is not a partitioned table; + * in particular, nothing is done if it's a legacy inheritance parent. + */ +static void +ATCheckPartitionsNotInUse(Relation rel, LOCKMODE lockmode) +{ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + List *inh; + ListCell *cell; + + inh = find_all_inheritors(RelationGetRelid(rel), lockmode, NULL); + /* first element is the parent rel; must ignore it */ + for_each_cell(cell, inh, list_second_cell(inh)) + { + Relation childrel; + + /* find_all_inheritors already got lock */ + childrel = table_open(lfirst_oid(cell), NoLock); + CheckTableNotInUse(childrel, "ALTER TABLE"); + table_close(childrel, NoLock); + } + list_free(inh); + } +} + /* * ATTypedTableRecursion * @@ -5117,7 +5360,7 @@ find_composite_type_dependencies(Oid typeOid, Relation origRelation, * We scan pg_depend to find those things that depend on the given type. * (We assume we can ignore refobjsubid for a type.) */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -5224,21 +5467,23 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be { Relation classRel; ScanKeyData key[1]; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; List *result = NIL; - classRel = heap_open(RelationRelationId, AccessShareLock); + classRel = table_open(RelationRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_class_reloftype, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(typeOid)); - scan = heap_beginscan_catalog(classRel, 1, key); + scan = table_beginscan_catalog(classRel, 1, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { + Form_pg_class classform = (Form_pg_class) GETSTRUCT(tuple); + if (behavior == DROP_RESTRICT) ereport(ERROR, (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST), @@ -5246,11 +5491,11 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be typeName), errhint("Use ALTER ... CASCADE to alter the typed tables too."))); else - result = lappend_oid(result, HeapTupleGetOid(tuple)); + result = lappend_oid(result, classform->oid); } - heap_endscan(scan); - heap_close(classRel, AccessShareLock); + table_endscan(scan); + table_close(classRel, AccessShareLock); return result; } @@ -5291,7 +5536,7 @@ check_of_type(HeapTuple typetuple) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("type %s is not a composite type", - format_type_be(HeapTupleGetOid(typetuple))))); + format_type_be(typ->oid)))); } @@ -5326,12 +5571,12 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing, } /* - * Add a column to a table; this handles the AT_AddOids cases as well. The - * return value is the address of the new column in the parent relation. + * Add a column to a table. The return value is the address of the + * new column in the parent relation. */ static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, - ColumnDef *colDef, bool isOid, + ColumnDef *colDef, bool recurse, bool recursing, bool if_not_exists, LOCKMODE lockmode) { @@ -5362,7 +5607,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot add column to a partition"))); - attrdesc = heap_open(AttributeRelationId, RowExclusiveLock); + attrdesc = table_open(AttributeRelationId, RowExclusiveLock); /* * Are we adding the column to a recursion child? If so, check whether to @@ -5401,13 +5646,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, get_collation_name(ccollid), get_collation_name(childatt->attcollation)))); - /* If it's OID, child column must actually be OID */ - if (isOid && childatt->attnum != ObjectIdAttributeNumber) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("child table \"%s\" has a conflicting \"%s\" column", - RelationGetRelationName(rel), colDef->colname))); - /* Bump the existing child att's inhcount */ childatt->attinhcount++; CatalogTupleUpdate(attrdesc, &tuple->t_self, tuple); @@ -5419,12 +5657,12 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, (errmsg("merging definition of column \"%s\" for child \"%s\"", colDef->colname, RelationGetRelationName(rel)))); - heap_close(attrdesc, RowExclusiveLock); + table_close(attrdesc, RowExclusiveLock); return InvalidObjectAddress; } } - pgclass = heap_open(RelationRelationId, RowExclusiveLock); + pgclass = table_open(RelationRelationId, RowExclusiveLock); reltup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(myrelid)); if (!HeapTupleIsValid(reltup)) @@ -5445,28 +5683,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* skip if the name already exists and if_not_exists is true */ if (!check_for_column_name_collision(rel, colDef->colname, if_not_exists)) { - heap_close(attrdesc, RowExclusiveLock); + table_close(attrdesc, RowExclusiveLock); heap_freetuple(reltup); - heap_close(pgclass, RowExclusiveLock); + table_close(pgclass, RowExclusiveLock); return InvalidObjectAddress; } /* Determine the new attribute's number */ - if (isOid) - newattnum = ObjectIdAttributeNumber; - else - { - newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1; - if (newattnum > MaxHeapAttributeNumber) - ereport(ERROR, - (errcode(ERRCODE_TOO_MANY_COLUMNS), - errmsg("tables can have at most %d columns", - MaxHeapAttributeNumber))); - } + newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1; + if (newattnum > MaxHeapAttributeNumber) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_COLUMNS), + errmsg("tables can have at most %d columns", + MaxHeapAttributeNumber))); typeTuple = typenameType(NULL, colDef->typeName, &typmod); tform = (Form_pg_type) GETSTRUCT(typeTuple); - typeOid = HeapTupleGetOid(typeTuple); + typeOid = tform->oid; aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE); if (aclresult != ACLCHECK_OK) @@ -5477,7 +5710,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* make sure datatype is legal for a column */ CheckAttributeType(colDef->colname, typeOid, collOid, list_make1_oid(rel->rd_rel->reltype), - false); + 0); /* construct new attribute's pg_attribute entry */ attribute.attrelid = myrelid; @@ -5485,7 +5718,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.atttypid = typeOid; attribute.attstattarget = (newattnum > 0) ? -1 : 0; attribute.attlen = tform->typlen; - attribute.attcacheoff = -1; attribute.atttypmod = typmod; attribute.attnum = newattnum; attribute.attbyval = tform->typbyval; @@ -5496,6 +5728,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, attribute.atthasdef = false; attribute.atthasmissing = false; attribute.attidentity = colDef->identity; + attribute.attgenerated = colDef->generated; attribute.attisdropped = false; attribute.attislocal = colDef->is_local; attribute.attinhcount = colDef->inhcount; @@ -5506,15 +5739,12 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, InsertPgAttributeTuple(attrdesc, &attribute, NULL); - heap_close(attrdesc, RowExclusiveLock); + table_close(attrdesc, RowExclusiveLock); /* * Update pg_class tuple as appropriate */ - if (isOid) - ((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true; - else - ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum; + ((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum; CatalogTupleUpdate(pgclass, &reltup->t_self, reltup); @@ -5523,7 +5753,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Post creation hook for new attribute */ InvokeObjectPostCreateHook(RelationRelationId, myrelid, newattnum); - heap_close(pgclass, RowExclusiveLock); + table_close(pgclass, RowExclusiveLock); /* Make the attribute's catalog entry visible */ CommandCounterIncrement(); @@ -5544,21 +5774,23 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, * DEFAULT value outside of the heap. This may be disabled inside * AddRelationNewConstraints if the optimization cannot be applied. */ - rawEnt->missingMode = true; + rawEnt->missingMode = (!colDef->generated); + + rawEnt->generated = colDef->generated; /* * This function is intended for CREATE TABLE, so it processes a * _list_ of defaults, but we just do one. */ AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, - false, true, false); + false, true, false, NULL); /* Make the additional catalog changes visible */ CommandCounterIncrement(); /* - * Did the request for a missing value work? If not we'll have to do - * a rewrite + * Did the request for a missing value work? If not we'll have to do a + * rewrite */ if (!rawEnt->missingMode) tab->rewrite |= AT_REWRITE_DEFAULT_VAL; @@ -5654,21 +5886,12 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, { /* * If the new column is NOT NULL, and there is no missing value, - * tell Phase 3 it needs to test that. (Note we don't do this for - * an OID column. OID will be marked not null, but since it's - * filled specially, there's no need to test anything.) + * tell Phase 3 it needs to check for NULLs. */ - tab->new_notnull |= colDef->is_not_null; + tab->verify_new_notnull |= colDef->is_not_null; } } - /* - * If we are adding an OID column, we have to tell Phase 3 to rewrite the - * table to fix that. - */ - if (isOid) - tab->rewrite |= AT_REWRITE_ALTER_OID; - /* * Add needed dependency entries for the new column. */ @@ -5706,7 +5929,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, AlteredTableInfo *childtab; /* find_inheritance_children already got lock */ - childrel = heap_open(childrelid, NoLock); + childrel = table_open(childrelid, NoLock); CheckTableNotInUse(childrel, "ALTER TABLE"); /* Find or create work queue entry for this table */ @@ -5714,10 +5937,10 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel, /* Recurse to child; return value is ignored */ ATExecAddColumn(wqueue, childtab, childrel, - colDef, isOid, recurse, true, + colDef, recurse, true, if_not_exists, lockmode); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } ObjectAddressSubSet(address, RelationRelationId, myrelid, newattnum); @@ -5818,40 +6041,8 @@ add_column_collation_dependency(Oid relid, int32 attnum, Oid collid) } } -/* - * ALTER TABLE SET WITH OIDS - * - * Basically this is an ADD COLUMN for the special OID column. We have - * to cons up a ColumnDef node because the ADD COLUMN code needs one. - */ -static void -ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode) -{ - /* If we're recursing to a child table, the ColumnDef is already set up */ - if (cmd->def == NULL) - { - ColumnDef *cdef = makeNode(ColumnDef); - - cdef->colname = pstrdup("oid"); - cdef->typeName = makeTypeNameFromOid(OIDOID, -1); - cdef->inhcount = 0; - cdef->is_local = true; - cdef->is_not_null = true; - cdef->storage = 0; - cdef->location = -1; - cmd->def = (Node *) cdef; - } - ATPrepAddColumn(wqueue, rel, recurse, false, false, cmd, lockmode); - - if (recurse) - cmd->subtype = AT_AddOidsRecurse; -} - /* * ALTER TABLE ALTER COLUMN DROP NOT NULL - * - * Return the address of the modified column. If the column was already - * nullable, InvalidObjectAddress is returned. */ static void @@ -5873,10 +6064,16 @@ ATPrepDropNotNull(Relation rel, bool recurse, bool recursing) errhint("Do not specify the ONLY keyword."))); } } + +/* + * Return the address of the modified column. If the column was already + * nullable, InvalidObjectAddress is returned. + */ static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) { HeapTuple tuple; + Form_pg_attribute attTup; AttrNumber attnum; Relation attr_rel; List *indexoidlist; @@ -5886,17 +6083,16 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) /* * lookup the attribute */ - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); - if (!HeapTupleIsValid(tuple)) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" of relation \"%s\" does not exist", colName, RelationGetRelationName(rel)))); - - attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum; + attTup = (Form_pg_attribute) GETSTRUCT(tuple); + attnum = attTup->attnum; /* Prevent them from altering a system attribute */ if (attnum <= 0) @@ -5905,7 +6101,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) errmsg("cannot alter system column \"%s\"", colName))); - if (get_attidentity(RelationGetRelid(rel), attnum)) + if (attTup->attidentity) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column \"%s\" of relation \"%s\" is an identity column", @@ -5958,7 +6154,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) if (rel->rd_rel->relispartition) { Oid parentId = get_partition_parent(RelationGetRelid(rel)); - Relation parent = heap_open(parentId, AccessShareLock); + Relation parent = table_open(parentId, AccessShareLock); TupleDesc tupDesc = RelationGetDescr(parent); AttrNumber parent_attnum; @@ -5968,15 +6164,15 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("column \"%s\" is marked NOT NULL in parent table", colName))); - heap_close(parent, AccessShareLock); + table_close(parent, AccessShareLock); } /* * Okay, actually perform the catalog change ... if needed */ - if (((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull) + if (attTup->attnotnull) { - ((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull = false; + attTup->attnotnull = false; CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); @@ -5989,7 +6185,7 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attnum); - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); return address; } @@ -5999,23 +6195,33 @@ ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode) */ static void -ATPrepSetNotNull(Relation rel, bool recurse, bool recursing) +ATPrepSetNotNull(List **wqueue, Relation rel, + AlterTableCmd *cmd, bool recurse, bool recursing, + LOCKMODE lockmode) { /* - * If the parent is a partitioned table, like check constraints, NOT NULL - * constraints must be added to the child tables. Complain if requested - * otherwise and partitions exist. + * If we're already recursing, there's nothing to do; the topmost + * invocation of ATSimpleRecursion already visited all children. */ - if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + if (recursing) + return; + + /* + * If we have ALTER TABLE ONLY ... SET NOT NULL on a partitioned table, + * apply ALTER TABLE ... CHECK NOT NULL to every child. Otherwise, use + * normal recursion logic. + */ + if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE && + !recurse) { - PartitionDesc partdesc = RelationGetPartitionDesc(rel); + AlterTableCmd *newcmd = makeNode(AlterTableCmd); - if (partdesc && partdesc->nparts > 0 && !recurse && !recursing) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("cannot add constraint to only the partitioned table when partitions exist"), - errhint("Do not specify the ONLY keyword."))); + newcmd->subtype = AT_CheckNotNull; + newcmd->name = pstrdup(cmd->name); + ATSimpleRecursion(wqueue, rel, newcmd, true, lockmode); } + else + ATSimpleRecursion(wqueue, rel, cmd, recurse, lockmode); } /* @@ -6034,7 +6240,7 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, /* * lookup the attribute */ - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); @@ -6062,8 +6268,18 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, CatalogTupleUpdate(attr_rel, &tuple->t_self, tuple); - /* Tell Phase 3 it needs to test the constraint */ - tab->new_notnull = true; + /* + * Ordinarily phase 3 must ensure that no NULLs exist in columns that + * are set NOT NULL; however, if we can find a constraint which proves + * this then we can skip that. We needn't bother looking if we've + * already found that we must verify some other NOT NULL constraint. + */ + if (!tab->verify_new_notnull && + !NotNullImpliedByRelConstraints(rel, (Form_pg_attribute) GETSTRUCT(tuple))) + { + /* Tell Phase 3 it needs to test the constraint */ + tab->verify_new_notnull = true; + } ObjectAddressSubSet(address, RelationRelationId, RelationGetRelid(rel), attnum); @@ -6074,11 +6290,87 @@ ATExecSetNotNull(AlteredTableInfo *tab, Relation rel, InvokeObjectPostAlterHook(RelationRelationId, RelationGetRelid(rel), attnum); - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); return address; } +/* + * ALTER TABLE ALTER COLUMN CHECK NOT NULL + * + * This doesn't exist in the grammar, but we generate AT_CheckNotNull + * commands against the partitions of a partitioned table if the user + * writes ALTER TABLE ONLY ... SET NOT NULL on the partitioned table, + * or tries to create a primary key on it (which internally creates + * AT_SetNotNull on the partitioned table). Such a command doesn't + * allow us to actually modify any partition, but we want to let it + * go through if the partitions are already properly marked. + * + * In future, this might need to adjust the child table's state, likely + * by incrementing an inheritance count for the attnotnull constraint. + * For now we need only check for the presence of the flag. + */ +static void +ATExecCheckNotNull(AlteredTableInfo *tab, Relation rel, + const char *colName, LOCKMODE lockmode) +{ + HeapTuple tuple; + + tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName); + + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + colName, RelationGetRelationName(rel)))); + + if (!((Form_pg_attribute) GETSTRUCT(tuple))->attnotnull) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("constraint must be added to child tables too"), + errdetail("Column \"%s\" of relation \"%s\" is not already NOT NULL.", + colName, RelationGetRelationName(rel)), + errhint("Do not specify the ONLY keyword."))); + + ReleaseSysCache(tuple); +} + +/* + * NotNullImpliedByRelConstraints + * Does rel's existing constraints imply NOT NULL for the given attribute? + */ +static bool +NotNullImpliedByRelConstraints(Relation rel, Form_pg_attribute attr) +{ + NullTest *nnulltest = makeNode(NullTest); + + nnulltest->arg = (Expr *) makeVar(1, + attr->attnum, + attr->atttypid, + attr->atttypmod, + attr->attcollation, + 0); + nnulltest->nulltesttype = IS_NOT_NULL; + + /* + * argisrow = false is correct even for a composite column, because + * attnotnull does not represent a SQL-spec IS NOT NULL test in such a + * case, just IS DISTINCT FROM NULL. + */ + nnulltest->argisrow = false; + nnulltest->location = -1; + + if (ConstraintImpliedByRelConstraint(rel, list_make1(nnulltest), NIL)) + { + ereport(DEBUG1, + (errmsg("existing constraints on column \"%s\".\"%s\" are sufficient to prove that it does not contain nulls", + RelationGetRelationName(rel), NameStr(attr->attname)))); + return true; + } + + return false; +} + /* * ALTER TABLE ALTER COLUMN SET/DROP DEFAULT * @@ -6088,6 +6380,7 @@ static ObjectAddress ATExecColumnDefault(Relation rel, const char *colName, Node *newDefault, LOCKMODE lockmode) { + TupleDesc tupdesc = RelationGetDescr(rel); AttrNumber attnum; ObjectAddress address; @@ -6108,13 +6401,19 @@ ATExecColumnDefault(Relation rel, const char *colName, errmsg("cannot alter system column \"%s\"", colName))); - if (get_attidentity(RelationGetRelid(rel), attnum)) + if (TupleDescAttr(tupdesc, attnum - 1)->attidentity) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column \"%s\" of relation \"%s\" is an identity column", colName, RelationGetRelationName(rel)), newDefault ? 0 : errhint("Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead."))); + if (TupleDescAttr(tupdesc, attnum - 1)->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("column \"%s\" of relation \"%s\" is a generated column", + colName, RelationGetRelationName(rel)))); + /* * Remove any old default for the column. We use RESTRICT here for * safety, but at present we do not expect anything to depend on the @@ -6136,13 +6435,14 @@ ATExecColumnDefault(Relation rel, const char *colName, rawEnt->attnum = attnum; rawEnt->raw_default = newDefault; rawEnt->missingMode = false; + rawEnt->generated = '\0'; /* * This function is intended for CREATE TABLE, so it processes a * _list_ of defaults, but we just do one. */ AddRelationNewConstraints(rel, list_make1(rawEnt), NIL, - false, true, false); + false, true, false, NULL); } ObjectAddressSubSet(address, RelationRelationId, @@ -6166,7 +6466,7 @@ ATExecAddIdentity(Relation rel, const char *colName, ObjectAddress address; ColumnDef *cdef = castNode(ColumnDef, def); - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); if (!HeapTupleIsValid(tuple)) @@ -6217,7 +6517,7 @@ ATExecAddIdentity(Relation rel, const char *colName, RelationGetRelid(rel), attnum); heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); return address; } @@ -6261,7 +6561,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod * there. */ - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); if (!HeapTupleIsValid(tuple)) ereport(ERROR, @@ -6299,7 +6599,7 @@ ATExecSetIdentity(Relation rel, const char *colName, Node *def, LOCKMODE lockmod address = InvalidObjectAddress; heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); return address; } @@ -6320,7 +6620,7 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE Oid seqid; ObjectAddress seqaddress; - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); if (!HeapTupleIsValid(tuple)) ereport(ERROR, @@ -6350,7 +6650,7 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE (errmsg("column \"%s\" of relation \"%s\" is not an identity column, skipping", colName, RelationGetRelationName(rel)))); heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); return InvalidObjectAddress; } } @@ -6365,10 +6665,10 @@ ATExecDropIdentity(Relation rel, const char *colName, bool missing_ok, LOCKMODE RelationGetRelid(rel), attnum); heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); /* drop the internal sequence */ - seqid = getOwnedSequence(RelationGetRelid(rel), attnum); + seqid = getIdentitySequence(RelationGetRelid(rel), attnum, false); deleteDependencyRecordsForClass(RelationRelationId, seqid, RelationRelationId, DEPENDENCY_INTERNAL); CommandCounterIncrement(); @@ -6455,7 +6755,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa newtarget))); } - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); if (colName) { @@ -6487,14 +6787,21 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa errmsg("cannot alter system column \"%s\"", colName))); - if ((rel->rd_rel->relkind == RELKIND_INDEX || - rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) && - rel->rd_index->indkey.values[attnum - 1] != 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"", - NameStr(attrtuple->attname), RelationGetRelationName(rel)), - errhint("Alter statistics on table column instead."))); + if (rel->rd_rel->relkind == RELKIND_INDEX || + rel->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) + { + if (attnum > rel->rd_index->indnkeyatts) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot alter statistics on included column \"%s\" of index \"%s\"", + NameStr(attrtuple->attname), RelationGetRelationName(rel)))); + else if (rel->rd_index->indkey.values[attnum - 1] != 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot alter statistics on non-expression column \"%s\" of index \"%s\"", + NameStr(attrtuple->attname), RelationGetRelationName(rel)), + errhint("Alter statistics on table column instead."))); + } attrtuple->attstattarget = newtarget; @@ -6507,7 +6814,7 @@ ATExecSetStatistics(Relation rel, const char *colName, int16 colNum, Node *newVa RelationGetRelid(rel), attnum); heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); return address; } @@ -6532,7 +6839,7 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, bool repl_null[Natts_pg_attribute]; bool repl_repl[Natts_pg_attribute]; - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName); @@ -6583,7 +6890,7 @@ ATExecSetOptions(Relation rel, const char *colName, Node *options, ReleaseSysCache(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); return address; } @@ -6624,7 +6931,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc newstorage = 0; /* keep compiler quiet */ } - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + attrelation = table_open(AttributeRelationId, RowExclusiveLock); tuple = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); @@ -6662,7 +6969,7 @@ ATExecSetStorage(Relation rel, const char *colName, Node *newValue, LOCKMODE loc heap_freetuple(tuple); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); ObjectAddressSubSet(address, RelationRelationId, RelationGetRelid(rel), attnum); @@ -6740,34 +7047,35 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, attnum = targetatt->attnum; - /* Can't drop a system attribute, except OID */ - if (attnum <= 0 && attnum != ObjectIdAttributeNumber) + /* Can't drop a system attribute */ + if (attnum <= 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot drop system column \"%s\"", colName))); - /* Don't drop inherited columns */ + /* + * Don't drop inherited columns, unless recursing (presumably from a drop + * of the parent column) + */ if (targetatt->attinhcount > 0 && !recursing) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("cannot drop inherited column \"%s\"", colName))); - /* Don't drop columns used in the partition key */ + /* + * Don't drop columns used in the partition key, either. (If we let this + * go through, the key column's dependencies would cause a cascaded drop + * of the whole table, which is surely not what the user expected.) + */ if (has_partition_attrs(rel, bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber), &is_expr)) - { - if (!is_expr) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("cannot drop column named in partition key"))); - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("cannot drop column referenced in partition key expression"))); - } + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("cannot drop column \"%s\" because it is part of the partition key of relation \"%s\"", + colName, RelationGetRelationName(rel)))); ReleaseSysCache(tuple); @@ -6793,7 +7101,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, errmsg("cannot drop column from only the partitioned table when partitions exist"), errhint("Do not specify the ONLY keyword."))); - attr_rel = heap_open(AttributeRelationId, RowExclusiveLock); + attr_rel = table_open(AttributeRelationId, RowExclusiveLock); foreach(child, children) { Oid childrelid = lfirst_oid(child); @@ -6801,7 +7109,7 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, Form_pg_attribute childatt; /* find_inheritance_children already got lock */ - childrel = heap_open(childrelid, NoLock); + childrel = table_open(childrelid, NoLock); CheckTableNotInUse(childrel, "ALTER TABLE"); tuple = SearchSysCacheCopyAttName(childrelid, colName); @@ -6857,9 +7165,9 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, heap_freetuple(tuple); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } - heap_close(attr_rel, RowExclusiveLock); + table_close(attr_rel, RowExclusiveLock); } /* @@ -6871,39 +7179,6 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, performDeletion(&object, behavior, 0); - /* - * If we dropped the OID column, must adjust pg_class.relhasoids and tell - * Phase 3 to physically get rid of the column. We formerly left the - * column in place physically, but this caused subtle problems. See - * http://archives.postgresql.org/pgsql-hackers/2009-02/msg00363.php - */ - if (attnum == ObjectIdAttributeNumber) - { - Relation class_rel; - Form_pg_class tuple_class; - AlteredTableInfo *tab; - - class_rel = heap_open(RelationRelationId, RowExclusiveLock); - - tuple = SearchSysCacheCopy1(RELOID, - ObjectIdGetDatum(RelationGetRelid(rel))); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", - RelationGetRelid(rel)); - tuple_class = (Form_pg_class) GETSTRUCT(tuple); - - tuple_class->relhasoids = false; - CatalogTupleUpdate(class_rel, &tuple->t_self, tuple); - - heap_close(class_rel, RowExclusiveLock); - - /* Find or create work queue entry for this table */ - tab = ATGetQueueEntry(wqueue, rel); - - /* Tell Phase 3 to physically remove the OID column */ - tab->rewrite |= AT_REWRITE_ALTER_OID; - } - return object; } @@ -7022,12 +7297,12 @@ ATExecAddIndexConstraint(AlteredTableInfo *tab, Relation rel, ereport(NOTICE, (errmsg("ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"", indexName, constraintName))); - RenameRelationInternal(index_oid, constraintName, false); + RenameRelationInternal(index_oid, constraintName, false, true); } /* Extra checks needed if making primary key */ if (stmt->primary) - index_check_primary_key(rel, indexInfo, true); + index_check_primary_key(rel, indexInfo, true, stmt); /* Note we currently don't support EXCLUSION constraints here */ if (stmt->primary) @@ -7089,16 +7364,12 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, case CONSTR_FOREIGN: /* - * Note that we currently never recurse for FK constraints, so the - * "recurse" flag is silently ignored. - * * Assign or validate constraint name */ if (newConstraint->conname) { if (ConstraintNameIsUsed(CONSTRAINT_RELATION, RelationGetRelid(rel), - RelationGetNamespace(rel), newConstraint->conname)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), @@ -7109,7 +7380,7 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, else newConstraint->conname = ChooseConstraintName(RelationGetRelationName(rel), - strVal(linitial(newConstraint->fk_attrs)), + ChooseForeignKeyConstraintNameAddition(newConstraint->fk_attrs), "fkey", RelationGetNamespace(rel), NIL); @@ -7128,6 +7399,45 @@ ATExecAddConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, return address; } +/* + * Generate the column-name portion of the constraint name for a new foreign + * key given the list of column names that reference the referenced + * table. This will be passed to ChooseConstraintName along with the parent + * table name and the "fkey" suffix. + * + * We know that less than NAMEDATALEN characters will actually be used, so we + * can truncate the result once we've generated that many. + * + * XXX see also ChooseExtendedStatisticNameAddition and + * ChooseIndexNameAddition. + */ +static char * +ChooseForeignKeyConstraintNameAddition(List *colnames) +{ + char buf[NAMEDATALEN * 2]; + int buflen = 0; + ListCell *lc; + + buf[0] = '\0'; + foreach(lc, colnames) + { + const char *name = strVal(lfirst(lc)); + + if (buflen > 0) + buf[buflen++] = '_'; /* insert _ between names */ + + /* + * At this point we have buflen <= NAMEDATALEN. name should be less + * than NAMEDATALEN already, but use strlcpy for paranoia. + */ + strlcpy(buf + buflen, name, NAMEDATALEN); + buflen += strlen(buf + buflen); + if (buflen >= NAMEDATALEN) + break; + } + return pstrdup(buf); +} + /* * Add a check constraint to a single table and its children. Returns the * address of the constraint added to the parent relation, if one gets added, @@ -7172,7 +7482,9 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, list_make1(copyObject(constr)), recursing | is_readd, /* allow_merge */ !recursing, /* is_local */ - is_readd); /* is_internal */ + is_readd, /* is_internal */ + NULL); /* queryString not available + * here */ /* we don't expect more than one constraint here */ Assert(list_length(newcons) <= 1); @@ -7246,7 +7558,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, AlteredTableInfo *childtab; /* find_inheritance_children already got lock */ - childrel = heap_open(childrelid, NoLock); + childrel = table_open(childrelid, NoLock); CheckTableNotInUse(childrel, "ALTER TABLE"); /* Find or create work queue entry for this table */ @@ -7256,7 +7568,7 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, ATAddCheckConstraint(wqueue, childtab, childrel, constr, recurse, true, is_readd, lockmode); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } return address; @@ -7269,6 +7581,13 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * Subroutine for ATExecAddConstraint. Must already hold exclusive * lock on the rel, and have done appropriate validity checks for it. * We do permissions checks here, however. + * + * When the referenced or referencing tables (or both) are partitioned, + * multiple pg_constraint rows are required -- one for each partitioned table + * and each partition on each side (fortunately, not one for every combination + * thereof). We also need action triggers on each leaf partition on the + * referenced side, and check triggers on each leaf partition on the + * referencing side. */ static ObjectAddress ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, @@ -7288,7 +7607,6 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, int numfks, numpks; Oid indexOid; - Oid constrOid; bool old_check_ok; ObjectAddress address; ListCell *old_pfeqop_item = list_head(fkconstraint->old_conpfeqop); @@ -7298,36 +7616,33 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * delete rows out from under us. */ if (OidIsValid(fkconstraint->old_pktable_oid)) - pkrel = heap_open(fkconstraint->old_pktable_oid, ShareRowExclusiveLock); + pkrel = table_open(fkconstraint->old_pktable_oid, ShareRowExclusiveLock); else - pkrel = heap_openrv(fkconstraint->pktable, ShareRowExclusiveLock); + pkrel = table_openrv(fkconstraint->pktable, ShareRowExclusiveLock); /* * Validity checks (permission checks wait till we have the column * numbers) */ - if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot reference partitioned table \"%s\"", - RelationGetRelationName(pkrel)))); - if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { if (!recurse) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("foreign key referencing partitioned table \"%s\" must not be ONLY", + errmsg("cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"", + RelationGetRelationName(rel), RelationGetRelationName(pkrel)))); if (fkconstraint->skip_validation && !fkconstraint->initially_valid) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot add NOT VALID foreign key to relation \"%s\"", + errmsg("cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"", + RelationGetRelationName(rel), RelationGetRelationName(pkrel)), errdetail("This feature is not yet supported on partitioned tables."))); } - if (pkrel->rd_rel->relkind != RELKIND_RELATION) + if (pkrel->rd_rel->relkind != RELKIND_RELATION && + pkrel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("referenced relation \"%s\" is not a table", @@ -7419,6 +7734,34 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, */ checkFkeyPermissions(pkrel, pkattnum, numpks); + /* + * Check some things for generated columns. + */ + for (i = 0; i < numfks; i++) + { + char attgenerated = TupleDescAttr(RelationGetDescr(rel), fkattnum[i] - 1)->attgenerated; + + if (attgenerated) + { + /* + * Check restrictions on UPDATE/DELETE actions, per SQL standard + */ + if (fkconstraint->fk_upd_action == FKCONSTR_ACTION_SETNULL || + fkconstraint->fk_upd_action == FKCONSTR_ACTION_SETDEFAULT || + fkconstraint->fk_upd_action == FKCONSTR_ACTION_CASCADE) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid %s action for foreign key constraint containing generated column", + "ON UPDATE"))); + if (fkconstraint->fk_del_action == FKCONSTR_ACTION_SETNULL || + fkconstraint->fk_del_action == FKCONSTR_ACTION_SETDEFAULT) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid %s action for foreign key constraint containing generated column", + "ON DELETE"))); + } + } + /* * Look up the equality operators to use in the constraint. * @@ -7537,8 +7880,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, if (!(OidIsValid(pfeqop) && OidIsValid(ffeqop))) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("foreign key constraint \"%s\" " - "cannot be implemented", + errmsg("foreign key constraint \"%s\" cannot be implemented", fkconstraint->conname), errdetail("Key columns \"%s\" and \"%s\" " "are of incompatible types: %s and %s.", @@ -7556,7 +7898,8 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * assess ppeqop or ffeqop, which RI_Initial_Check() does not use. */ old_check_ok = (pfeqop == lfirst_oid(old_pfeqop_item)); - old_pfeqop_item = lnext(old_pfeqop_item); + old_pfeqop_item = lnext(fkconstraint->old_conpfeqop, + old_pfeqop_item); } if (old_check_ok) { @@ -7617,7 +7960,6 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, new_castfunc == old_castfunc && (!IsPolymorphicType(pfeqop_right) || new_fktype == old_fktype)); - } pfeqoperators[i] = pfeqop; @@ -7626,112 +7968,984 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, } /* - * Record the FK constraint in pg_constraint. + * Create all the constraint and trigger objects, recursing to partitions + * as necessary. First handle the referenced side. */ - constrOid = CreateConstraintEntry(fkconstraint->conname, - RelationGetNamespace(rel), - CONSTRAINT_FOREIGN, - fkconstraint->deferrable, - fkconstraint->initdeferred, - fkconstraint->initially_valid, - parentConstr, - RelationGetRelid(rel), - fkattnum, - numfks, - numfks, - InvalidOid, /* not a domain constraint */ - indexOid, - RelationGetRelid(pkrel), - pkattnum, - pfeqoperators, - ppeqoperators, - ffeqoperators, - numpks, - fkconstraint->fk_upd_action, - fkconstraint->fk_del_action, - fkconstraint->fk_matchtype, - NULL, /* no exclusion constraint */ + address = addFkRecurseReferenced(wqueue, fkconstraint, rel, pkrel, + indexOid, + InvalidOid, /* no parent constraint */ + numfks, + pkattnum, + fkattnum, + pfeqoperators, + ppeqoperators, + ffeqoperators, + old_check_ok); + + /* Now handle the referencing side. */ + addFkRecurseReferencing(wqueue, fkconstraint, rel, pkrel, + indexOid, + address.objectId, + numfks, + pkattnum, + fkattnum, + pfeqoperators, + ppeqoperators, + ffeqoperators, + old_check_ok, + lockmode); + + /* + * Done. Close pk table, but keep lock until we've committed. + */ + table_close(pkrel, NoLock); + + return address; +} + +/* + * addFkRecurseReferenced + * subroutine for ATAddForeignKeyConstraint; recurses on the referenced + * side of the constraint + * + * Create pg_constraint rows for the referenced side of the constraint, + * referencing the parent of the referencing side; also create action triggers + * on leaf partitions. If the table is partitioned, recurse to handle each + * partition. + * + * wqueue is the ALTER TABLE work queue; can be NULL when not running as part + * of an ALTER TABLE sequence. + * fkconstraint is the constraint being added. + * rel is the root referencing relation. + * pkrel is the referenced relation; might be a partition, if recursing. + * indexOid is the OID of the index (on pkrel) implementing this constraint. + * parentConstr is the OID of a parent constraint; InvalidOid if this is a + * top-level constraint. + * numfks is the number of columns in the foreign key + * pkattnum is the attnum array of referenced attributes. + * fkattnum is the attnum array of referencing attributes. + * pf/pp/ffeqoperators are OID array of operators between columns. + * old_check_ok signals that this constraint replaces an existing one that + * was already validated (thus this one doesn't need validation). + */ +static ObjectAddress +addFkRecurseReferenced(List **wqueue, Constraint *fkconstraint, Relation rel, + Relation pkrel, Oid indexOid, Oid parentConstr, + int numfks, + int16 *pkattnum, int16 *fkattnum, Oid *pfeqoperators, + Oid *ppeqoperators, Oid *ffeqoperators, bool old_check_ok) +{ + ObjectAddress address; + Oid constrOid; + char *conname; + bool conislocal; + int coninhcount; + bool connoinherit; + + /* + * Verify relkind for each referenced partition. At the top level, this + * is redundant with a previous check, but we need it when recursing. + */ + if (pkrel->rd_rel->relkind != RELKIND_RELATION && + pkrel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("referenced relation \"%s\" is not a table", + RelationGetRelationName(pkrel)))); + + /* + * Caller supplies us with a constraint name; however, it may be used in + * this partition, so come up with a different one in that case. + */ + if (ConstraintNameIsUsed(CONSTRAINT_RELATION, + RelationGetRelid(rel), + fkconstraint->conname)) + conname = ChooseConstraintName(RelationGetRelationName(rel), + ChooseForeignKeyConstraintNameAddition(fkconstraint->fk_attrs), + "fkey", + RelationGetNamespace(rel), NIL); + else + conname = fkconstraint->conname; + + if (OidIsValid(parentConstr)) + { + conislocal = false; + coninhcount = 1; + connoinherit = false; + } + else + { + conislocal = true; + coninhcount = 0; + + /* + * always inherit for partitioned tables, never for legacy inheritance + */ + connoinherit = rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE; + } + + /* + * Record the FK constraint in pg_constraint. + */ + constrOid = CreateConstraintEntry(conname, + RelationGetNamespace(rel), + CONSTRAINT_FOREIGN, + fkconstraint->deferrable, + fkconstraint->initdeferred, + fkconstraint->initially_valid, + parentConstr, + RelationGetRelid(rel), + fkattnum, + numfks, + numfks, + InvalidOid, /* not a domain constraint */ + indexOid, + RelationGetRelid(pkrel), + pkattnum, + pfeqoperators, + ppeqoperators, + ffeqoperators, + numfks, + fkconstraint->fk_upd_action, + fkconstraint->fk_del_action, + fkconstraint->fk_matchtype, + NULL, /* no exclusion constraint */ NULL, /* no check constraint */ NULL, - NULL, - true, /* islocal */ - 0, /* inhcount */ - true, /* isnoinherit */ + conislocal, /* islocal */ + coninhcount, /* inhcount */ + connoinherit, /* conNoInherit */ false); /* is_internal */ + ObjectAddressSet(address, ConstraintRelationId, constrOid); /* - * Create the triggers that will enforce the constraint. We only want - * the action triggers to appear for the parent partitioned relation, - * even though the constraints also exist below. + * Mark the child constraint as part of the parent constraint; it must not + * be dropped on its own. (This constraint is deleted when the partition + * is detached, but a special check needs to occur that the partition + * contains no referenced values.) */ - createForeignKeyTriggers(rel, RelationGetRelid(pkrel), fkconstraint, - constrOid, indexOid, !recursing); + if (OidIsValid(parentConstr)) + { + ObjectAddress referenced; + + ObjectAddressSet(referenced, ConstraintRelationId, parentConstr); + recordDependencyOn(&address, &referenced, DEPENDENCY_INTERNAL); + } + + /* make new constraint visible, in case we add more */ + CommandCounterIncrement(); + + /* + * If the referenced table is a plain relation, create the action triggers + * that enforce the constraint. + */ + if (pkrel->rd_rel->relkind == RELKIND_RELATION) + { + createForeignKeyActionTriggers(rel, RelationGetRelid(pkrel), + fkconstraint, + constrOid, indexOid); + } /* - * Tell Phase 3 to check that the constraint is satisfied by existing - * rows. We can skip this during table creation, when requested explicitly - * by specifying NOT VALID in an ADD FOREIGN KEY command, and when we're - * recreating a constraint following a SET DATA TYPE operation that did - * not impugn its validity. + * If the referenced table is partitioned, recurse on ourselves to handle + * each partition. We need one pg_constraint row created for each + * partition in addition to the pg_constraint row for the parent table. */ - if (!old_check_ok && !fkconstraint->skip_validation) + if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) { - NewConstraint *newcon; + PartitionDesc pd = RelationGetPartitionDesc(pkrel); + + for (int i = 0; i < pd->nparts; i++) + { + Relation partRel; + AttrNumber *map; + AttrNumber *mapped_pkattnum; + Oid partIndexId; - newcon = (NewConstraint *) palloc0(sizeof(NewConstraint)); - newcon->name = fkconstraint->conname; - newcon->contype = CONSTR_FOREIGN; - newcon->refrelid = RelationGetRelid(pkrel); - newcon->refindid = indexOid; - newcon->conid = constrOid; - newcon->qual = (Node *) fkconstraint; + partRel = table_open(pd->oids[i], ShareRowExclusiveLock); - tab->constraints = lappend(tab->constraints, newcon); + /* + * Map the attribute numbers in the referenced side of the FK + * definition to match the partition's column layout. + */ + map = convert_tuples_by_name_map_if_req(RelationGetDescr(partRel), + RelationGetDescr(pkrel)); + if (map) + { + mapped_pkattnum = palloc(sizeof(AttrNumber) * numfks); + for (int j = 0; j < numfks; j++) + mapped_pkattnum[j] = map[pkattnum[j] - 1]; + } + else + mapped_pkattnum = pkattnum; + + /* do the deed */ + partIndexId = index_get_partition(partRel, indexOid); + if (!OidIsValid(partIndexId)) + elog(ERROR, "index for %u not found in partition %s", + indexOid, RelationGetRelationName(partRel)); + addFkRecurseReferenced(wqueue, fkconstraint, rel, partRel, + partIndexId, constrOid, numfks, + mapped_pkattnum, fkattnum, + pfeqoperators, ppeqoperators, ffeqoperators, + old_check_ok); + + /* Done -- clean up (but keep the lock) */ + table_close(partRel, NoLock); + if (map) + { + pfree(mapped_pkattnum); + pfree(map); + } + } } + return address; +} + +/* + * addFkRecurseReferencing + * subroutine for ATAddForeignKeyConstraint and CloneFkReferencing + * + * If the referencing relation is a plain relation, create the necessary check + * triggers that implement the constraint, and set up for Phase 3 constraint + * verification. If the referencing relation is a partitioned table, then + * we create a pg_constraint row for it and recurse on this routine for each + * partition. + * + * We assume that the referenced relation is locked against concurrent + * deletions. If it's a partitioned relation, every partition must be so + * locked. + * + * wqueue is the ALTER TABLE work queue; can be NULL when not running as part + * of an ALTER TABLE sequence. + * fkconstraint is the constraint being added. + * rel is the referencing relation; might be a partition, if recursing. + * pkrel is the root referenced relation. + * indexOid is the OID of the index (on pkrel) implementing this constraint. + * parentConstr is the OID of the parent constraint (there is always one). + * numfks is the number of columns in the foreign key + * pkattnum is the attnum array of referenced attributes. + * fkattnum is the attnum array of referencing attributes. + * pf/pp/ffeqoperators are OID array of operators between columns. + * old_check_ok signals that this constraint replaces an existing one that + * was already validated (thus this one doesn't need validation). + * lockmode is the lockmode to acquire on partitions when recursing. + */ +static void +addFkRecurseReferencing(List **wqueue, Constraint *fkconstraint, Relation rel, + Relation pkrel, Oid indexOid, Oid parentConstr, + int numfks, int16 *pkattnum, int16 *fkattnum, + Oid *pfeqoperators, Oid *ppeqoperators, Oid *ffeqoperators, + bool old_check_ok, LOCKMODE lockmode) +{ + AssertArg(OidIsValid(parentConstr)); + + if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("foreign key constraints are not supported on foreign tables"))); + /* - * When called on a partitioned table, recurse to create the constraint on - * the partitions also. + * If the referencing relation is a plain table, add the check triggers to + * it and, if necessary, schedule it to be checked in Phase 3. + * + * If the relation is partitioned, drill down to do it to its partitions. */ - if (recurse && rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + if (rel->rd_rel->relkind == RELKIND_RELATION) { - PartitionDesc partdesc; + createForeignKeyCheckTriggers(RelationGetRelid(rel), + RelationGetRelid(pkrel), + fkconstraint, + parentConstr, + indexOid); + + /* + * Tell Phase 3 to check that the constraint is satisfied by existing + * rows. We can skip this during table creation, when requested + * explicitly by specifying NOT VALID in an ADD FOREIGN KEY command, + * and when we're recreating a constraint following a SET DATA TYPE + * operation that did not impugn its validity. + */ + if (wqueue && !old_check_ok && !fkconstraint->skip_validation) + { + NewConstraint *newcon; + AlteredTableInfo *tab; - partdesc = RelationGetPartitionDesc(rel); + tab = ATGetQueueEntry(wqueue, rel); - for (i = 0; i < partdesc->nparts; i++) + newcon = (NewConstraint *) palloc0(sizeof(NewConstraint)); + newcon->name = get_constraint_name(parentConstr); + newcon->contype = CONSTR_FOREIGN; + newcon->refrelid = RelationGetRelid(pkrel); + newcon->refindid = indexOid; + newcon->conid = parentConstr; + newcon->qual = (Node *) fkconstraint; + + tab->constraints = lappend(tab->constraints, newcon); + } + } + else if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + PartitionDesc pd = RelationGetPartitionDesc(rel); + + /* + * Recurse to take appropriate action on each partition; either we + * find an existing constraint to reparent to ours, or we create a new + * one. + */ + for (int i = 0; i < pd->nparts; i++) { - Oid partitionId = partdesc->oids[i]; - Relation partition = heap_open(partitionId, lockmode); - AlteredTableInfo *childtab; - ObjectAddress childAddr; + Oid partitionId = pd->oids[i]; + Relation partition = table_open(partitionId, lockmode); + List *partFKs; + AttrNumber *attmap; + AttrNumber mapped_fkattnum[INDEX_MAX_KEYS]; + bool attached; + char *conname; + Oid constrOid; + ObjectAddress address, + referenced; + ListCell *cell; CheckTableNotInUse(partition, "ALTER TABLE"); - /* Find or create work queue entry for this table */ - childtab = ATGetQueueEntry(wqueue, partition); + attmap = convert_tuples_by_name_map(RelationGetDescr(partition), + RelationGetDescr(rel)); + for (int j = 0; j < numfks; j++) + mapped_fkattnum[j] = attmap[fkattnum[j] - 1]; - childAddr = - ATAddForeignKeyConstraint(wqueue, childtab, partition, - fkconstraint, constrOid, - recurse, true, lockmode); + /* Check whether an existing constraint can be repurposed */ + partFKs = copyObject(RelationGetFKeyList(partition)); + attached = false; + foreach(cell, partFKs) + { + ForeignKeyCacheInfo *fk; + + fk = lfirst_node(ForeignKeyCacheInfo, cell); + if (tryAttachPartitionForeignKey(fk, + partitionId, + parentConstr, + numfks, + mapped_fkattnum, + pkattnum, + pfeqoperators)) + { + attached = true; + break; + } + } + if (attached) + { + table_close(partition, NoLock); + continue; + } - /* Record this constraint as dependent on the parent one */ - recordDependencyOn(&childAddr, &address, DEPENDENCY_INTERNAL_AUTO); + /* + * No luck finding a good constraint to reuse; create our own. + */ + if (ConstraintNameIsUsed(CONSTRAINT_RELATION, + RelationGetRelid(partition), + fkconstraint->conname)) + conname = ChooseConstraintName(RelationGetRelationName(partition), + ChooseForeignKeyConstraintNameAddition(fkconstraint->fk_attrs), + "fkey", + RelationGetNamespace(partition), NIL); + else + conname = fkconstraint->conname; + constrOid = + CreateConstraintEntry(conname, + RelationGetNamespace(partition), + CONSTRAINT_FOREIGN, + fkconstraint->deferrable, + fkconstraint->initdeferred, + fkconstraint->initially_valid, + parentConstr, + partitionId, + mapped_fkattnum, + numfks, + numfks, + InvalidOid, + indexOid, + RelationGetRelid(pkrel), + pkattnum, + pfeqoperators, + ppeqoperators, + ffeqoperators, + numfks, + fkconstraint->fk_upd_action, + fkconstraint->fk_del_action, + fkconstraint->fk_matchtype, + NULL, + NULL, + NULL, + false, + 1, + false, + false); + + /* + * Give this constraint partition-type dependencies on the parent + * constraint as well as the table. + */ + ObjectAddressSet(address, ConstraintRelationId, constrOid); + ObjectAddressSet(referenced, ConstraintRelationId, parentConstr); + recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_PRI); + ObjectAddressSet(referenced, RelationRelationId, partitionId); + recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_SEC); + + /* Make all this visible before recursing */ + CommandCounterIncrement(); - heap_close(partition, NoLock); + /* call ourselves to finalize the creation and we're done */ + addFkRecurseReferencing(wqueue, fkconstraint, partition, pkrel, + indexOid, + constrOid, + numfks, + pkattnum, + mapped_fkattnum, + pfeqoperators, + ppeqoperators, + ffeqoperators, + old_check_ok, + lockmode); + + table_close(partition, NoLock); } } +} + +/* + * CloneForeignKeyConstraints + * Clone foreign keys from a partitioned table to a newly acquired + * partition. + * + * partitionRel is a partition of parentRel, so we can be certain that it has + * the same columns with the same datatypes. The columns may be in different + * order, though. + * + * wqueue must be passed to set up phase 3 constraint checking, unless the + * referencing-side partition is known to be empty (such as in CREATE TABLE / + * PARTITION OF). + */ +static void +CloneForeignKeyConstraints(List **wqueue, Relation parentRel, + Relation partitionRel) +{ + /* This only works for declarative partitioning */ + Assert(parentRel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); /* - * Close pk table, but keep lock until we've committed. + * Clone constraints for which the parent is on the referenced side. */ - heap_close(pkrel, NoLock); + CloneFkReferenced(parentRel, partitionRel); - return address; + /* + * Now clone constraints where the parent is on the referencing side. + */ + CloneFkReferencing(wqueue, parentRel, partitionRel); +} + +/* + * CloneFkReferenced + * Subroutine for CloneForeignKeyConstraints + * + * Find all the FKs that have the parent relation on the referenced side; + * clone those constraints to the given partition. This is to be called + * when the partition is being created or attached. + * + * This recurses to partitions, if the relation being attached is partitioned. + * Recursion is done by calling addFkRecurseReferenced. + */ +static void +CloneFkReferenced(Relation parentRel, Relation partitionRel) +{ + Relation pg_constraint; + AttrNumber *attmap; + ListCell *cell; + SysScanDesc scan; + ScanKeyData key[2]; + HeapTuple tuple; + List *clone = NIL; + + /* + * Search for any constraints where this partition is in the referenced + * side. However, we must ignore any constraint whose parent constraint + * is also going to be cloned, to avoid duplicates. So do it in two + * steps: first construct the list of constraints to clone, then go over + * that list cloning those whose parents are not in the list. (We must + * not rely on the parent being seen first, since the catalog scan could + * return children first.) + */ + pg_constraint = table_open(ConstraintRelationId, RowShareLock); + ScanKeyInit(&key[0], + Anum_pg_constraint_confrelid, BTEqualStrategyNumber, + F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(parentRel))); + ScanKeyInit(&key[1], + Anum_pg_constraint_contype, BTEqualStrategyNumber, + F_CHAREQ, CharGetDatum(CONSTRAINT_FOREIGN)); + /* This is a seqscan, as we don't have a usable index ... */ + scan = systable_beginscan(pg_constraint, InvalidOid, true, + NULL, 2, key); + while ((tuple = systable_getnext(scan)) != NULL) + { + Form_pg_constraint constrForm = (Form_pg_constraint) GETSTRUCT(tuple); + + /* Only try to clone the top-level constraint; skip child ones. */ + if (constrForm->conparentid != InvalidOid) + continue; + + clone = lappend_oid(clone, constrForm->oid); + } + systable_endscan(scan); + table_close(pg_constraint, RowShareLock); + + attmap = convert_tuples_by_name_map(RelationGetDescr(partitionRel), + RelationGetDescr(parentRel)); + foreach(cell, clone) + { + Oid constrOid = lfirst_oid(cell); + Form_pg_constraint constrForm; + Relation fkRel; + Oid indexOid; + Oid partIndexId; + int numfks; + AttrNumber conkey[INDEX_MAX_KEYS]; + AttrNumber mapped_confkey[INDEX_MAX_KEYS]; + AttrNumber confkey[INDEX_MAX_KEYS]; + Oid conpfeqop[INDEX_MAX_KEYS]; + Oid conppeqop[INDEX_MAX_KEYS]; + Oid conffeqop[INDEX_MAX_KEYS]; + Constraint *fkconstraint; + + tuple = SearchSysCache1(CONSTROID, constrOid); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for constraint %u", constrOid); + constrForm = (Form_pg_constraint) GETSTRUCT(tuple); + + /* + * Because we're only expanding the key space at the referenced side, + * we don't need to prevent any operation in the referencing table, so + * AccessShareLock suffices (assumes that dropping the constraint + * acquires AEL). + */ + fkRel = table_open(constrForm->conrelid, AccessShareLock); + + indexOid = constrForm->conindid; + DeconstructFkConstraintRow(tuple, + &numfks, + conkey, + confkey, + conpfeqop, + conppeqop, + conffeqop); + for (int i = 0; i < numfks; i++) + mapped_confkey[i] = attmap[confkey[i] - 1]; + + fkconstraint = makeNode(Constraint); + /* for now this is all we need */ + fkconstraint->conname = NameStr(constrForm->conname); + fkconstraint->fk_upd_action = constrForm->confupdtype; + fkconstraint->fk_del_action = constrForm->confdeltype; + fkconstraint->deferrable = constrForm->condeferrable; + fkconstraint->initdeferred = constrForm->condeferred; + fkconstraint->initially_valid = true; + fkconstraint->fk_matchtype = constrForm->confmatchtype; + + /* set up colnames that are used to generate the constraint name */ + for (int i = 0; i < numfks; i++) + { + Form_pg_attribute att; + + att = TupleDescAttr(RelationGetDescr(fkRel), + conkey[i] - 1); + fkconstraint->fk_attrs = lappend(fkconstraint->fk_attrs, + makeString(NameStr(att->attname))); + } + + /* + * Add the new foreign key constraint pointing to the new partition. + * Because this new partition appears in the referenced side of the + * constraint, we don't need to set up for Phase 3 check. + */ + partIndexId = index_get_partition(partitionRel, indexOid); + if (!OidIsValid(partIndexId)) + elog(ERROR, "index for %u not found in partition %s", + indexOid, RelationGetRelationName(partitionRel)); + addFkRecurseReferenced(NULL, + fkconstraint, + fkRel, + partitionRel, + partIndexId, + constrOid, + numfks, + mapped_confkey, + conkey, + conpfeqop, + conppeqop, + conffeqop, + true); + + table_close(fkRel, NoLock); + ReleaseSysCache(tuple); + } +} + +/* + * CloneFkReferencing + * Subroutine for CloneForeignKeyConstraints + * + * For each FK constraint of the parent relation in the given list, find an + * equivalent constraint in its partition relation that can be reparented; + * if one cannot be found, create a new constraint in the partition as its + * child. + * + * If wqueue is given, it is used to set up phase-3 verification for each + * cloned constraint; if omitted, we assume that such verification is not + * needed (example: the partition is being created anew). + */ +static void +CloneFkReferencing(List **wqueue, Relation parentRel, Relation partRel) +{ + AttrNumber *attmap; + List *partFKs; + List *clone = NIL; + ListCell *cell; + + /* obtain a list of constraints that we need to clone */ + foreach(cell, RelationGetFKeyList(parentRel)) + { + ForeignKeyCacheInfo *fk = lfirst(cell); + + clone = lappend_oid(clone, fk->conoid); + } + + /* + * Silently do nothing if there's nothing to do. In particular, this + * avoids throwing a spurious error for foreign tables. + */ + if (clone == NIL) + return; + + if (partRel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("foreign key constraints are not supported on foreign tables"))); + + /* + * The constraint key may differ, if the columns in the partition are + * different. This map is used to convert them. + */ + attmap = convert_tuples_by_name_map(RelationGetDescr(partRel), + RelationGetDescr(parentRel)); + + partFKs = copyObject(RelationGetFKeyList(partRel)); + + foreach(cell, clone) + { + Oid parentConstrOid = lfirst_oid(cell); + Form_pg_constraint constrForm; + Relation pkrel; + HeapTuple tuple; + int numfks; + AttrNumber conkey[INDEX_MAX_KEYS]; + AttrNumber mapped_conkey[INDEX_MAX_KEYS]; + AttrNumber confkey[INDEX_MAX_KEYS]; + Oid conpfeqop[INDEX_MAX_KEYS]; + Oid conppeqop[INDEX_MAX_KEYS]; + Oid conffeqop[INDEX_MAX_KEYS]; + Constraint *fkconstraint; + bool attached; + Oid indexOid; + Oid constrOid; + ObjectAddress address, + referenced; + ListCell *cell; + + tuple = SearchSysCache1(CONSTROID, parentConstrOid); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for constraint %u", + parentConstrOid); + constrForm = (Form_pg_constraint) GETSTRUCT(tuple); + + /* Don't clone constraints whose parents are being cloned */ + if (list_member_oid(clone, constrForm->conparentid)) + { + ReleaseSysCache(tuple); + continue; + } + + /* + * Need to prevent concurrent deletions. If pkrel is a partitioned + * relation, that means to lock all partitions. + */ + pkrel = table_open(constrForm->confrelid, ShareRowExclusiveLock); + if (pkrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + (void) find_all_inheritors(RelationGetRelid(pkrel), + ShareRowExclusiveLock, NULL); + + DeconstructFkConstraintRow(tuple, &numfks, conkey, confkey, + conpfeqop, conppeqop, conffeqop); + for (int i = 0; i < numfks; i++) + mapped_conkey[i] = attmap[conkey[i] - 1]; + + /* + * Before creating a new constraint, see whether any existing FKs are + * fit for the purpose. If one is, attach the parent constraint to + * it, and don't clone anything. This way we avoid the expensive + * verification step and don't end up with a duplicate FK, and we + * don't need to recurse to partitions for this constraint. + */ + attached = false; + foreach(cell, partFKs) + { + ForeignKeyCacheInfo *fk = lfirst_node(ForeignKeyCacheInfo, cell); + + if (tryAttachPartitionForeignKey(fk, + RelationGetRelid(partRel), + parentConstrOid, + numfks, + mapped_conkey, + confkey, + conpfeqop)) + { + attached = true; + table_close(pkrel, NoLock); + break; + } + } + if (attached) + { + ReleaseSysCache(tuple); + continue; + } + + /* No dice. Set up to create our own constraint */ + fkconstraint = makeNode(Constraint); + if (ConstraintNameIsUsed(CONSTRAINT_RELATION, + RelationGetRelid(partRel), + NameStr(constrForm->conname))) + fkconstraint->conname = + ChooseConstraintName(RelationGetRelationName(partRel), + ChooseForeignKeyConstraintNameAddition(fkconstraint->fk_attrs), + "fkey", + RelationGetNamespace(partRel), NIL); + else + fkconstraint->conname = pstrdup(NameStr(constrForm->conname)); + fkconstraint->fk_upd_action = constrForm->confupdtype; + fkconstraint->fk_del_action = constrForm->confdeltype; + fkconstraint->deferrable = constrForm->condeferrable; + fkconstraint->initdeferred = constrForm->condeferred; + fkconstraint->fk_matchtype = constrForm->confmatchtype; + for (int i = 0; i < numfks; i++) + { + Form_pg_attribute att; + + att = TupleDescAttr(RelationGetDescr(partRel), + mapped_conkey[i] - 1); + fkconstraint->fk_attrs = lappend(fkconstraint->fk_attrs, + makeString(NameStr(att->attname))); + } + + indexOid = constrForm->conindid; + constrOid = + CreateConstraintEntry(fkconstraint->conname, + constrForm->connamespace, + CONSTRAINT_FOREIGN, + fkconstraint->deferrable, + fkconstraint->initdeferred, + constrForm->convalidated, + parentConstrOid, + RelationGetRelid(partRel), + mapped_conkey, + numfks, + numfks, + InvalidOid, /* not a domain constraint */ + indexOid, + constrForm->confrelid, /* same foreign rel */ + confkey, + conpfeqop, + conppeqop, + conffeqop, + numfks, + fkconstraint->fk_upd_action, + fkconstraint->fk_del_action, + fkconstraint->fk_matchtype, + NULL, + NULL, + NULL, + false, /* islocal */ + 1, /* inhcount */ + false, /* conNoInherit */ + true); + + /* Set up partition dependencies for the new constraint */ + ObjectAddressSet(address, ConstraintRelationId, constrOid); + ObjectAddressSet(referenced, ConstraintRelationId, parentConstrOid); + recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_PRI); + ObjectAddressSet(referenced, RelationRelationId, + RelationGetRelid(partRel)); + recordDependencyOn(&address, &referenced, DEPENDENCY_PARTITION_SEC); + + /* Done with the cloned constraint's tuple */ + ReleaseSysCache(tuple); + + /* Make all this visible before recursing */ + CommandCounterIncrement(); + + addFkRecurseReferencing(wqueue, + fkconstraint, + partRel, + pkrel, + indexOid, + constrOid, + numfks, + confkey, + mapped_conkey, + conpfeqop, + conppeqop, + conffeqop, + false, /* no old check exists */ + AccessExclusiveLock); + table_close(pkrel, NoLock); + } +} + +/* + * When the parent of a partition receives [the referencing side of] a foreign + * key, we must propagate that foreign key to the partition. However, the + * partition might already have an equivalent foreign key; this routine + * compares the given ForeignKeyCacheInfo (in the partition) to the FK defined + * by the other parameters. If they are equivalent, create the link between + * the two constraints and return true. + * + * If the given FK does not match the one defined by rest of the params, + * return false. + */ +static bool +tryAttachPartitionForeignKey(ForeignKeyCacheInfo *fk, + Oid partRelid, + Oid parentConstrOid, + int numfks, + AttrNumber *mapped_conkey, + AttrNumber *confkey, + Oid *conpfeqop) +{ + HeapTuple parentConstrTup; + Form_pg_constraint parentConstr; + HeapTuple partcontup; + Form_pg_constraint partConstr; + Relation trigrel; + ScanKeyData key; + SysScanDesc scan; + HeapTuple trigtup; + + parentConstrTup = SearchSysCache1(CONSTROID, + ObjectIdGetDatum(parentConstrOid)); + if (!HeapTupleIsValid(parentConstrTup)) + elog(ERROR, "cache lookup failed for constraint %u", parentConstrOid); + parentConstr = (Form_pg_constraint) GETSTRUCT(parentConstrTup); + + /* + * Do some quick & easy initial checks. If any of these fail, we cannot + * use this constraint. + */ + if (fk->confrelid != parentConstr->confrelid || fk->nkeys != numfks) + { + ReleaseSysCache(parentConstrTup); + return false; + } + for (int i = 0; i < numfks; i++) + { + if (fk->conkey[i] != mapped_conkey[i] || + fk->confkey[i] != confkey[i] || + fk->conpfeqop[i] != conpfeqop[i]) + { + ReleaseSysCache(parentConstrTup); + return false; + } + } + + /* + * Looks good so far; do some more extensive checks. Presumably the check + * for 'convalidated' could be dropped, since we don't really care about + * that, but let's be careful for now. + */ + partcontup = SearchSysCache1(CONSTROID, + ObjectIdGetDatum(fk->conoid)); + if (!HeapTupleIsValid(partcontup)) + elog(ERROR, "cache lookup failed for constraint %u", fk->conoid); + partConstr = (Form_pg_constraint) GETSTRUCT(partcontup); + if (OidIsValid(partConstr->conparentid) || + !partConstr->convalidated || + partConstr->condeferrable != parentConstr->condeferrable || + partConstr->condeferred != parentConstr->condeferred || + partConstr->confupdtype != parentConstr->confupdtype || + partConstr->confdeltype != parentConstr->confdeltype || + partConstr->confmatchtype != parentConstr->confmatchtype) + { + ReleaseSysCache(parentConstrTup); + ReleaseSysCache(partcontup); + return false; + } + + ReleaseSysCache(partcontup); + ReleaseSysCache(parentConstrTup); + + /* + * Looks good! Attach this constraint. The action triggers in the new + * partition become redundant -- the parent table already has equivalent + * ones, and those will be able to reach the partition. Remove the ones + * in the partition. We identify them because they have our constraint + * OID, as well as being on the referenced rel. + */ + trigrel = table_open(TriggerRelationId, RowExclusiveLock); + ScanKeyInit(&key, + Anum_pg_trigger_tgconstraint, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(fk->conoid)); + + scan = systable_beginscan(trigrel, TriggerConstraintIndexId, true, + NULL, 1, &key); + while ((trigtup = systable_getnext(scan)) != NULL) + { + Form_pg_trigger trgform = (Form_pg_trigger) GETSTRUCT(trigtup); + ObjectAddress trigger; + + if (trgform->tgconstrrelid != fk->conrelid) + continue; + if (trgform->tgrelid != fk->confrelid) + continue; + + /* + * The constraint is originally set up to contain this trigger as an + * implementation object, so there's a dependency record that links + * the two; however, since the trigger is no longer needed, we remove + * the dependency link in order to be able to drop the trigger while + * keeping the constraint intact. + */ + deleteDependencyRecordsFor(TriggerRelationId, + trgform->oid, + false); + /* make dependency deletion visible to performDeletion */ + CommandCounterIncrement(); + ObjectAddressSet(trigger, TriggerRelationId, + trgform->oid); + performDeletion(&trigger, DROP_RESTRICT, 0); + /* make trigger drop visible, in case the loop iterates */ + CommandCounterIncrement(); + } + + systable_endscan(scan); + table_close(trigrel, RowExclusiveLock); + + ConstraintSetParentConstraint(fk->conoid, parentConstrOid, partRelid); + CommandCounterIncrement(); + return true; } + /* * ALTER TABLE ALTER CONSTRAINT * @@ -7752,42 +8966,41 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, Constraint *cmdcon; Relation conrel; SysScanDesc scan; - ScanKeyData key; + ScanKeyData skey[3]; HeapTuple contuple; - Form_pg_constraint currcon = NULL; - bool found = false; + Form_pg_constraint currcon; ObjectAddress address; cmdcon = castNode(Constraint, cmd->def); - conrel = heap_open(ConstraintRelationId, RowExclusiveLock); + conrel = table_open(ConstraintRelationId, RowExclusiveLock); /* * Find and check the target constraint */ - ScanKeyInit(&key, + ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); - scan = systable_beginscan(conrel, ConstraintRelidIndexId, - true, NULL, 1, &key); - - while (HeapTupleIsValid(contuple = systable_getnext(scan))) - { - currcon = (Form_pg_constraint) GETSTRUCT(contuple); - if (strcmp(NameStr(currcon->conname), cmdcon->conname) == 0) - { - found = true; - break; - } - } - - if (!found) + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(cmdcon->conname)); + scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, + true, NULL, 3, skey); + + /* There can be at most one matching row */ + if (!HeapTupleIsValid(contuple = systable_getnext(scan))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("constraint \"%s\" of relation \"%s\" does not exist", cmdcon->conname, RelationGetRelationName(rel)))); + currcon = (Form_pg_constraint) GETSTRUCT(contuple); if (currcon->contype != CONSTRAINT_FOREIGN) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -7816,7 +9029,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, CatalogTupleUpdate(conrel, ©Tuple->t_self, copyTuple); InvokeObjectPostAlterHook(ConstraintRelationId, - HeapTupleGetOid(contuple), 0); + currcon->oid, 0); heap_freetuple(copyTuple); @@ -7824,12 +9037,12 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, * Now we need to update the multiple entries in pg_trigger that * implement the constraint. */ - tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); ScanKeyInit(&tgkey, Anum_pg_trigger_tgconstraint, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(HeapTupleGetOid(contuple))); + ObjectIdGetDatum(currcon->oid)); tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true, NULL, 1, &tgkey); @@ -7852,8 +9065,8 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, /* * Update deferrability of RI_FKey_noaction_del, * RI_FKey_noaction_upd, RI_FKey_check_ins and RI_FKey_check_upd - * triggers, but not others; see createForeignKeyTriggers and - * CreateFKCheckTrigger. + * triggers, but not others; see createForeignKeyActionTriggers + * and CreateFKCheckTrigger. */ if (tgform->tgfoid != F_RI_FKEY_NOACTION_DEL && tgform->tgfoid != F_RI_FKEY_NOACTION_UPD && @@ -7868,15 +9081,14 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, copy_tg->tginitdeferred = cmdcon->initdeferred; CatalogTupleUpdate(tgrel, ©Tuple->t_self, copyTuple); - InvokeObjectPostAlterHook(TriggerRelationId, - HeapTupleGetOid(tgtuple), 0); + InvokeObjectPostAlterHook(TriggerRelationId, currcon->oid, 0); heap_freetuple(copyTuple); } systable_endscan(tgscan); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); /* * Invalidate relcache so that others see the new attributes. We must @@ -7890,15 +9102,14 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd, CacheInvalidateRelcacheByRelid(lfirst_oid(lc)); } - ObjectAddressSet(address, ConstraintRelationId, - HeapTupleGetOid(contuple)); + ObjectAddressSet(address, ConstraintRelationId, currcon->oid); } else address = InvalidObjectAddress; systable_endscan(scan); - heap_close(conrel, RowExclusiveLock); + table_close(conrel, RowExclusiveLock); return address; } @@ -7920,40 +9131,39 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, { Relation conrel; SysScanDesc scan; - ScanKeyData key; + ScanKeyData skey[3]; HeapTuple tuple; - Form_pg_constraint con = NULL; - bool found = false; + Form_pg_constraint con; ObjectAddress address; - conrel = heap_open(ConstraintRelationId, RowExclusiveLock); + conrel = table_open(ConstraintRelationId, RowExclusiveLock); /* * Find and check the target constraint */ - ScanKeyInit(&key, + ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); - scan = systable_beginscan(conrel, ConstraintRelidIndexId, - true, NULL, 1, &key); - - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - con = (Form_pg_constraint) GETSTRUCT(tuple); - if (strcmp(NameStr(con->conname), constrName) == 0) - { - found = true; - break; - } - } - - if (!found) + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(constrName)); + scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, + true, NULL, 3, skey); + + /* There can be at most one matching row */ + if (!HeapTupleIsValid(tuple = systable_getnext(scan))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("constraint \"%s\" of relation \"%s\" does not exist", constrName, RelationGetRelationName(rel)))); + con = (Form_pg_constraint) GETSTRUCT(tuple); if (con->contype != CONSTRAINT_FOREIGN && con->contype != CONSTRAINT_CHECK) ereport(ERROR, @@ -7978,12 +9188,12 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, * might need to fire triggers to perform the check, so we take a * lock at RowShareLock level just in case. */ - refrel = heap_open(con->confrelid, RowShareLock); + refrel = table_open(con->confrelid, RowShareLock); validateForeignKeyConstraint(constrName, rel, refrel, con->conindid, - HeapTupleGetOid(tuple)); - heap_close(refrel, NoLock); + con->oid); + table_close(refrel, NoLock); /* * We disallow creating invalid foreign keys to or from @@ -8031,11 +9241,11 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, errmsg("constraint must be validated on child tables too"))); /* find_all_inheritors already got lock */ - childrel = heap_open(childoid, NoLock); + childrel = table_open(childoid, NoLock); ATExecValidateConstraint(childrel, constrName, false, true, lockmode); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } validateCheckConstraint(rel, tuple); @@ -8055,20 +9265,18 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, copy_con->convalidated = true; CatalogTupleUpdate(conrel, ©Tuple->t_self, copyTuple); - InvokeObjectPostAlterHook(ConstraintRelationId, - HeapTupleGetOid(tuple), 0); + InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0); heap_freetuple(copyTuple); - ObjectAddressSet(address, ConstraintRelationId, - HeapTupleGetOid(tuple)); + ObjectAddressSet(address, ConstraintRelationId, con->oid); } else address = InvalidObjectAddress; /* already validated */ systable_endscan(scan); - heap_close(conrel, RowExclusiveLock); + table_close(conrel, RowExclusiveLock); return address; } @@ -8156,7 +9364,7 @@ transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, if (!HeapTupleIsValid(indexTuple)) elog(ERROR, "cache lookup failed for index %u", indexoid); indexStruct = (Form_pg_index) GETSTRUCT(indexTuple); - if (indexStruct->indisprimary && IndexIsValid(indexStruct)) + if (indexStruct->indisprimary && indexStruct->indisvalid) { /* * Refuse to use a deferrable primary key. This is per SQL spec, @@ -8277,7 +9485,7 @@ transformFkeyCheckAttrs(Relation pkrel, */ if (indexStruct->indnkeyatts == numattrs && indexStruct->indisunique && - IndexIsValid(indexStruct) && + indexStruct->indisvalid && heap_attisnull(indexTuple, Anum_pg_index_indpred, NULL) && heap_attisnull(indexTuple, Anum_pg_index_indexprs, NULL)) { @@ -8428,9 +9636,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) char *conbin; Expr *origexpr; ExprState *exprstate; - TupleDesc tupdesc; - HeapScanDesc scan; - HeapTuple tuple; + TableScanDesc scan; ExprContext *econtext; MemoryContext oldcxt; TupleTableSlot *slot; @@ -8459,18 +9665,17 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) &isnull); if (isnull) elog(ERROR, "null conbin for constraint %u", - HeapTupleGetOid(constrtup)); + constrForm->oid); conbin = TextDatumGetCString(val); origexpr = (Expr *) stringToNode(conbin); exprstate = ExecPrepareExpr(origexpr, estate); econtext = GetPerTupleExprContext(estate); - tupdesc = RelationGetDescr(rel); - slot = MakeSingleTupleTableSlot(tupdesc); + slot = table_slot_create(rel, NULL); econtext->ecxt_scantuple = slot; snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); + scan = table_beginscan(rel, snapshot, 0, NULL); /* * Switch to per-tuple memory context and reset it for each tuple @@ -8478,10 +9683,8 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) */ oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) { - ExecStoreTuple(tuple, slot, InvalidBuffer, false); - if (!ExecCheck(exprstate, econtext)) ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), @@ -8493,7 +9696,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup) } MemoryContextSwitchTo(oldcxt); - heap_endscan(scan); + table_endscan(scan); UnregisterSnapshot(snapshot); ExecDropSingleTupleTableSlot(slot); FreeExecutorState(estate); @@ -8512,10 +9715,12 @@ validateForeignKeyConstraint(char *conname, Oid pkindOid, Oid constraintOid) { - HeapScanDesc scan; - HeapTuple tuple; + TupleTableSlot *slot; + TableScanDesc scan; Trigger trig; Snapshot snapshot; + MemoryContext oldcxt; + MemoryContext perTupCxt; ereport(DEBUG1, (errmsg("validating foreign key constraint \"%s\"", conname))); @@ -8548,19 +9753,27 @@ validateForeignKeyConstraint(char *conname, * ereport(ERROR) and that's that. */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); + slot = table_slot_create(rel, NULL); + scan = table_beginscan(rel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + perTupCxt = AllocSetContextCreate(CurrentMemoryContext, + "validateForeignKeyConstraint", + ALLOCSET_SMALL_SIZES); + oldcxt = MemoryContextSwitchTo(perTupCxt); + + while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 0); TriggerData trigdata; + CHECK_FOR_INTERRUPTS(); + /* * Make a call to the trigger function * * No parameters are passed, but we do set a context */ - MemSet(&fcinfo, 0, sizeof(fcinfo)); + MemSet(fcinfo, 0, SizeForFunctionCallInfo(0)); /* * We assume RI_FKey_check_ins won't look at flinfo... @@ -8568,19 +9781,24 @@ validateForeignKeyConstraint(char *conname, trigdata.type = T_TriggerData; trigdata.tg_event = TRIGGER_EVENT_INSERT | TRIGGER_EVENT_ROW; trigdata.tg_relation = rel; - trigdata.tg_trigtuple = tuple; + trigdata.tg_trigtuple = ExecFetchSlotHeapTuple(slot, false, NULL); + trigdata.tg_trigslot = slot; trigdata.tg_newtuple = NULL; + trigdata.tg_newslot = NULL; trigdata.tg_trigger = &trig; - trigdata.tg_trigtuplebuf = scan->rs_cbuf; - trigdata.tg_newtuplebuf = InvalidBuffer; - fcinfo.context = (Node *) &trigdata; + fcinfo->context = (Node *) &trigdata; - RI_FKey_check_ins(&fcinfo); + RI_FKey_check_ins(fcinfo); + + MemoryContextReset(perTupCxt); } - heap_endscan(scan); + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(perTupCxt); + table_endscan(scan); UnregisterSnapshot(snapshot); + ExecDropSingleTupleTableSlot(slot); } static void @@ -8769,37 +9987,6 @@ createForeignKeyCheckTriggers(Oid myRelOid, Oid refRelOid, indexOid, false); } -/* - * Create the triggers that implement an FK constraint. - * - * NB: if you change any trigger properties here, see also - * ATExecAlterConstraint. - */ -void -createForeignKeyTriggers(Relation rel, Oid refRelOid, Constraint *fkconstraint, - Oid constraintOid, Oid indexOid, bool create_action) -{ - /* - * For the referenced side, create action triggers, if requested. (If the - * referencing side is partitioned, there is still only one trigger, which - * runs on the referenced side and points to the top of the referencing - * hierarchy.) - */ - if (create_action) - createForeignKeyActionTriggers(rel, refRelOid, fkconstraint, constraintOid, - indexOid); - - /* - * For the referencing side, create the check triggers. We only need these - * on the partitions. - */ - if (rel->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) - createForeignKeyCheckTriggers(RelationGetRelid(rel), refRelOid, - fkconstraint, constraintOid, indexOid); - - CommandCounterIncrement(); -} - /* * ALTER TABLE DROP CONSTRAINT * @@ -8816,36 +10003,43 @@ ATExecDropConstraint(Relation rel, const char *constrName, Relation conrel; Form_pg_constraint con; SysScanDesc scan; - ScanKeyData key; + ScanKeyData skey[3]; HeapTuple tuple; bool found = false; bool is_no_inherit_constraint = false; + char contype; /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE); - conrel = heap_open(ConstraintRelationId, RowExclusiveLock); + conrel = table_open(ConstraintRelationId, RowExclusiveLock); /* * Find and drop the target constraint */ - ScanKeyInit(&key, + ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); - scan = systable_beginscan(conrel, ConstraintRelidIndexId, - true, NULL, 1, &key); - - while (HeapTupleIsValid(tuple = systable_getnext(scan))) + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(constrName)); + scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, + true, NULL, 3, skey); + + /* There can be at most one matching row */ + if (HeapTupleIsValid(tuple = systable_getnext(scan))) { ObjectAddress conobj; con = (Form_pg_constraint) GETSTRUCT(tuple); - if (strcmp(NameStr(con->conname), constrName) != 0) - continue; - /* Don't drop inherited constraints */ if (con->coninhcount > 0 && !recursing) ereport(ERROR, @@ -8854,6 +10048,7 @@ ATExecDropConstraint(Relation rel, const char *constrName, constrName, RelationGetRelationName(rel)))); is_no_inherit_constraint = con->connoinherit; + contype = con->contype; /* * If it's a foreign-key constraint, we'd better lock the referenced @@ -8862,30 +10057,27 @@ ATExecDropConstraint(Relation rel, const char *constrName, * that has unfired events). But we can/must skip that in the * self-referential case. */ - if (con->contype == CONSTRAINT_FOREIGN && + if (contype == CONSTRAINT_FOREIGN && con->confrelid != RelationGetRelid(rel)) { Relation frel; /* Must match lock taken by RemoveTriggerById: */ - frel = heap_open(con->confrelid, AccessExclusiveLock); + frel = table_open(con->confrelid, AccessExclusiveLock); CheckTableNotInUse(frel, "ALTER TABLE"); - heap_close(frel, NoLock); + table_close(frel, NoLock); } /* * Perform the actual constraint deletion */ conobj.classId = ConstraintRelationId; - conobj.objectId = HeapTupleGetOid(tuple); + conobj.objectId = con->oid; conobj.objectSubId = 0; performDeletion(&conobj, behavior, 0); found = true; - - /* constraint found and dropped -- no need to keep looping */ - break; } systable_endscan(scan); @@ -8904,11 +10096,22 @@ ATExecDropConstraint(Relation rel, const char *constrName, ereport(NOTICE, (errmsg("constraint \"%s\" of relation \"%s\" does not exist, skipping", constrName, RelationGetRelationName(rel)))); - heap_close(conrel, RowExclusiveLock); + table_close(conrel, RowExclusiveLock); return; } } + /* + * For partitioned tables, non-CHECK inherited constraints are dropped via + * the dependency mechanism, so we're done here. + */ + if (contype != CONSTRAINT_CHECK && + rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + table_close(conrel, RowExclusiveLock); + return; + } + /* * Propagate to children as appropriate. Unlike most other ALTER * routines, we have to do this one level of recursion at a time; we can't @@ -8938,30 +10141,26 @@ ATExecDropConstraint(Relation rel, const char *constrName, HeapTuple copy_tuple; /* find_inheritance_children already got lock */ - childrel = heap_open(childrelid, NoLock); + childrel = table_open(childrelid, NoLock); CheckTableNotInUse(childrel, "ALTER TABLE"); - ScanKeyInit(&key, + ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(childrelid)); - scan = systable_beginscan(conrel, ConstraintRelidIndexId, - true, NULL, 1, &key); - - /* scan for matching tuple - there should only be one */ - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - con = (Form_pg_constraint) GETSTRUCT(tuple); - - /* Right now only CHECK constraints can be inherited */ - if (con->contype != CONSTRAINT_CHECK) - continue; - - if (strcmp(NameStr(con->conname), constrName) == 0) - break; - } - - if (!HeapTupleIsValid(tuple)) + ScanKeyInit(&skey[1], + Anum_pg_constraint_contypid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(constrName)); + scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, + true, NULL, 3, skey); + + /* There can be at most one matching row */ + if (!HeapTupleIsValid(tuple = systable_getnext(scan))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("constraint \"%s\" of relation \"%s\" does not exist", @@ -8974,6 +10173,10 @@ ATExecDropConstraint(Relation rel, const char *constrName, con = (Form_pg_constraint) GETSTRUCT(copy_tuple); + /* Right now only CHECK constraints can be inherited */ + if (con->contype != CONSTRAINT_CHECK) + elog(ERROR, "inherited constraint is not a CHECK constraint"); + if (con->coninhcount <= 0) /* shouldn't happen */ elog(ERROR, "relation %u has non-inherited constraint \"%s\"", childrelid, constrName); @@ -9019,10 +10222,10 @@ ATExecDropConstraint(Relation rel, const char *constrName, heap_freetuple(copy_tuple); - heap_close(childrel, NoLock); + table_close(childrel, NoLock); } - heap_close(conrel, RowExclusiveLock); + table_close(conrel, RowExclusiveLock); } /* @@ -9071,7 +10274,11 @@ ATPrepAlterColumnType(List **wqueue, errmsg("cannot alter system column \"%s\"", colName))); - /* Don't alter inherited columns */ + /* + * Don't alter inherited columns. At outer level, there had better not be + * any inherited definition; when recursing, we assume this was checked at + * the parent level (see below). + */ if (attTup->attinhcount > 0 && !recursing) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -9082,16 +10289,10 @@ ATPrepAlterColumnType(List **wqueue, if (has_partition_attrs(rel, bms_make_singleton(attnum - FirstLowInvalidHeapAttributeNumber), &is_expr)) - { - if (!is_expr) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("cannot alter type of column named in partition key"))); - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("cannot alter type of column referenced in partition key expression"))); - } + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("cannot alter column \"%s\" because it is part of the partition key of relation \"%s\"", + colName, RelationGetRelationName(rel)))); /* Look up the target type */ typenameTypeIdAndMod(NULL, typeName, &targettype, &targettypmod); @@ -9106,7 +10307,7 @@ ATPrepAlterColumnType(List **wqueue, /* make sure datatype is legal for a column */ CheckAttributeType(colName, targettype, targetcollid, list_make1_oid(rel->rd_rel->reltype), - false); + 0); if (tab->relkind == RELKIND_RELATION || tab->relkind == RELKIND_PARTITIONED_TABLE) @@ -9203,20 +10404,26 @@ ATPrepAlterColumnType(List **wqueue, if (recurse) { Oid relid = RelationGetRelid(rel); - ListCell *child; - List *children; + List *child_oids, + *child_numparents; + ListCell *lo, + *li; - children = find_all_inheritors(relid, lockmode, NULL); + child_oids = find_all_inheritors(relid, lockmode, + &child_numparents); /* * find_all_inheritors does the recursive search of the inheritance * hierarchy, so all we have to do is process all of the relids in the * list that it returns. */ - foreach(child, children) + forboth(lo, child_oids, li, child_numparents) { - Oid childrelid = lfirst_oid(child); + Oid childrelid = lfirst_oid(lo); + int numparents = lfirst_int(li); Relation childrel; + HeapTuple childtuple; + Form_pg_attribute childattTup; if (childrelid == relid) continue; @@ -9225,6 +10432,29 @@ ATPrepAlterColumnType(List **wqueue, childrel = relation_open(childrelid, NoLock); CheckTableNotInUse(childrel, "ALTER TABLE"); + /* + * Verify that the child doesn't have any inherited definitions of + * this column that came from outside this inheritance hierarchy. + * (renameatt makes a similar test, though in a different way + * because of its different recursion mechanism.) + */ + childtuple = SearchSysCacheAttName(RelationGetRelid(childrel), + colName); + if (!HeapTupleIsValid(childtuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + colName, RelationGetRelationName(childrel)))); + childattTup = (Form_pg_attribute) GETSTRUCT(childtuple); + + if (childattTup->attinhcount > numparents) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("cannot alter inherited column \"%s\" of relation \"%s\"", + colName, RelationGetRelationName(childrel)))); + + ReleaseSysCache(childtuple); + /* * Remap the attribute numbers. If no USING expression was * specified, there is no need for this step. @@ -9238,8 +10468,7 @@ ATPrepAlterColumnType(List **wqueue, cmd = copyObject(cmd); attmap = convert_tuples_by_name_map(RelationGetDescr(childrel), - RelationGetDescr(rel), - gettext_noop("could not convert row type")); + RelationGetDescr(rel)); ((ColumnDef *) cmd->def)->cooked_default = map_variable_attnos(def->cooked_default, 1, 0, @@ -9271,11 +10500,15 @@ ATPrepAlterColumnType(List **wqueue, * When the data type of a column is changed, a rewrite might not be required * if the new type is sufficiently identical to the old one, and the USING * clause isn't trying to insert some other value. It's safe to skip the - * rewrite if the old type is binary coercible to the new type, or if the - * new type is an unconstrained domain over the old type. In the case of a - * constrained domain, we could get by with scanning the table and checking - * the constraint rather than actually rewriting it, but we don't currently - * try to do that. + * rewrite in these cases: + * + * - the old type is binary coercible to the new type + * - the new type is an unconstrained domain over the old type + * - {NEW,OLD} or {OLD,NEW} is {timestamptz,timestamp} and the timezone is UTC + * + * In the case of a constrained domain, we could get by with scanning the + * table and checking the constraint rather than actually rewriting it, but we + * don't currently try to do that. */ static bool ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno) @@ -9297,6 +10530,23 @@ ATColumnChangeRequiresRewrite(Node *expr, AttrNumber varattno) return true; expr = (Node *) d->arg; } + else if (IsA(expr, FuncExpr)) + { + FuncExpr *f = (FuncExpr *) expr; + + switch (f->funcid) + { + case F_TIMESTAMPTZ_TIMESTAMP: + case F_TIMESTAMP_TIMESTAMPTZ: + if (TimestampTimestampTzRequiresRewrite()) + return true; + else + expr = linitial(f->args); + break; + default: + return true; + } + } else return true; } @@ -9331,7 +10581,22 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, HeapTuple depTup; ObjectAddress address; - attrelation = heap_open(AttributeRelationId, RowExclusiveLock); + /* + * Clear all the missing values if we're rewriting the table, since this + * renders them pointless. + */ + if (tab->rewrite) + { + Relation newrel; + + newrel = table_open(RelationGetRelid(rel), NoLock); + RelationClearMissing(newrel); + relation_close(newrel, NoLock); + /* make sure we don't conflict with later attribute modifications */ + CommandCounterIncrement(); + } + + attrelation = table_open(AttributeRelationId, RowExclusiveLock); /* Look up the target column */ heapTup = SearchSysCacheCopyAttName(RelationGetRelid(rel), colName); @@ -9355,7 +10620,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, /* Look up the target type (should not fail, since prep found it) */ typeTuple = typenameType(NULL, typeName, &targettypmod); tform = (Form_pg_type) GETSTRUCT(typeTuple); - targettype = HeapTupleGetOid(typeTuple); + targettype = tform->oid; /* And the collation */ targetcollid = GetColumnDefCollation(NULL, def, targettype); @@ -9383,10 +10648,18 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, COERCE_IMPLICIT_CAST, -1); if (defaultexpr == NULL) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("default for column \"%s\" cannot be cast automatically to type %s", - colName, format_type_be(targettype)))); + { + if (attTup->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("generation expression for column \"%s\" cannot be cast automatically to type %s", + colName, format_type_be(targettype)))); + else + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("default for column \"%s\" cannot be cast automatically to type %s", + colName, format_type_be(targettype)))); + } } else defaultexpr = NULL; @@ -9399,13 +10672,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, * performed all the individual ALTER TYPE operations. We have to save * the info before executing ALTER TYPE, though, else the deparser will * get confused. - * - * There could be multiple entries for the same object, so we must check - * to ensure we process each one only once. Note: we assume that an index - * that implements a constraint will not show a direct dependency on the - * column. */ - depRel = heap_open(DependRelationId, RowExclusiveLock); + depRel = table_open(DependRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -9446,13 +10714,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, relKind == RELKIND_PARTITIONED_INDEX) { Assert(foundObject.objectSubId == 0); - if (!list_member_oid(tab->changedIndexOids, foundObject.objectId)) - { - tab->changedIndexOids = lappend_oid(tab->changedIndexOids, - foundObject.objectId); - tab->changedIndexDefs = lappend(tab->changedIndexDefs, - pg_get_indexdef_string(foundObject.objectId)); - } + RememberIndexForRebuilding(foundObject.objectId, tab); } else if (relKind == RELKIND_SEQUENCE) { @@ -9462,6 +10724,21 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, */ Assert(foundObject.objectSubId == 0); } + else if (relKind == RELKIND_RELATION && + foundObject.objectSubId != 0 && + get_attgenerated(foundObject.objectId, foundObject.objectSubId)) + { + /* + * Changing the type of a column that is used by a + * generated column is not allowed by SQL standard. It + * might be doable with some thinking and effort. + */ + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cannot alter type of a column used by a generated column"), + errdetail("Column \"%s\" is used by generated column \"%s\".", + colName, get_attname(foundObject.objectId, foundObject.objectSubId, false)))); + } else { /* Not expecting any other direct dependencies... */ @@ -9473,39 +10750,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, case OCLASS_CONSTRAINT: Assert(foundObject.objectSubId == 0); - if (!list_member_oid(tab->changedConstraintOids, - foundObject.objectId)) - { - char *defstring = pg_get_constraintdef_command(foundObject.objectId); - - /* - * Put NORMAL dependencies at the front of the list and - * AUTO dependencies at the back. This makes sure that - * foreign-key constraints depending on this column will - * be dropped before unique or primary-key constraints of - * the column; which we must have because the FK - * constraints depend on the indexes belonging to the - * unique constraints. - */ - if (foundDep->deptype == DEPENDENCY_NORMAL) - { - tab->changedConstraintOids = - lcons_oid(foundObject.objectId, - tab->changedConstraintOids); - tab->changedConstraintDefs = - lcons(defstring, - tab->changedConstraintDefs); - } - else - { - tab->changedConstraintOids = - lappend_oid(tab->changedConstraintOids, - foundObject.objectId); - tab->changedConstraintDefs = - lappend(tab->changedConstraintDefs, - defstring); - } - } + RememberConstraintForRebuilding(foundObject.objectId, tab); break; case OCLASS_REWRITE: @@ -9627,7 +10872,8 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, /* * Now scan for dependencies of this column on other things. The only * thing we should find is the dependency on the column datatype, which we - * want to remove, and possibly a collation dependency. + * want to remove, possibly a collation dependency, and dependencies on + * other columns if it is a generated column. */ ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -9648,27 +10894,103 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, while (HeapTupleIsValid(depTup = systable_getnext(scan))) { Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(depTup); + ObjectAddress foundObject; - if (foundDep->deptype != DEPENDENCY_NORMAL) + foundObject.classId = foundDep->refclassid; + foundObject.objectId = foundDep->refobjid; + foundObject.objectSubId = foundDep->refobjsubid; + + if (foundDep->deptype != DEPENDENCY_NORMAL && + foundDep->deptype != DEPENDENCY_AUTO) elog(ERROR, "found unexpected dependency type '%c'", foundDep->deptype); if (!(foundDep->refclassid == TypeRelationId && foundDep->refobjid == attTup->atttypid) && !(foundDep->refclassid == CollationRelationId && - foundDep->refobjid == attTup->attcollation)) - elog(ERROR, "found unexpected dependency for column"); + foundDep->refobjid == attTup->attcollation) && + !(foundDep->refclassid == RelationRelationId && + foundDep->refobjid == RelationGetRelid(rel) && + foundDep->refobjsubid != 0) + ) + elog(ERROR, "found unexpected dependency for column: %s", + getObjectDescription(&foundObject)); + + CatalogTupleDelete(depRel, &depTup->t_self); + } + + systable_endscan(scan); + + table_close(depRel, RowExclusiveLock); + + /* + * Here we go --- change the recorded column type and collation. (Note + * heapTup is a copy of the syscache entry, so okay to scribble on.) First + * fix up the missing value if any. + */ + if (attTup->atthasmissing) + { + Datum missingval; + bool missingNull; + + /* if rewrite is true the missing value should already be cleared */ + Assert(tab->rewrite == 0); + + /* Get the missing value datum */ + missingval = heap_getattr(heapTup, + Anum_pg_attribute_attmissingval, + attrelation->rd_att, + &missingNull); + + /* if it's a null array there is nothing to do */ + + if (!missingNull) + { + /* + * Get the datum out of the array and repack it in a new array + * built with the new type data. We assume that since the table + * doesn't need rewriting, the actual Datum doesn't need to be + * changed, only the array metadata. + */ - CatalogTupleDelete(depRel, &depTup->t_self); + int one = 1; + bool isNull; + Datum valuesAtt[Natts_pg_attribute]; + bool nullsAtt[Natts_pg_attribute]; + bool replacesAtt[Natts_pg_attribute]; + HeapTuple newTup; + + MemSet(valuesAtt, 0, sizeof(valuesAtt)); + MemSet(nullsAtt, false, sizeof(nullsAtt)); + MemSet(replacesAtt, false, sizeof(replacesAtt)); + + missingval = array_get_element(missingval, + 1, + &one, + 0, + attTup->attlen, + attTup->attbyval, + attTup->attalign, + &isNull); + missingval = PointerGetDatum( + construct_array(&missingval, + 1, + targettype, + tform->typlen, + tform->typbyval, + tform->typalign)); + + valuesAtt[Anum_pg_attribute_attmissingval - 1] = missingval; + replacesAtt[Anum_pg_attribute_attmissingval - 1] = true; + nullsAtt[Anum_pg_attribute_attmissingval - 1] = false; + + newTup = heap_modify_tuple(heapTup, RelationGetDescr(attrelation), + valuesAtt, nullsAtt, replacesAtt); + heap_freetuple(heapTup); + heapTup = newTup; + attTup = (Form_pg_attribute) GETSTRUCT(heapTup); + } } - systable_endscan(scan); - - heap_close(depRel, RowExclusiveLock); - - /* - * Here we go --- change the recorded column type and collation. (Note - * heapTup is a copy of the syscache entry, so okay to scribble on.) - */ attTup->atttypid = targettype; attTup->atttypmod = targettypmod; attTup->attcollation = targetcollid; @@ -9682,7 +11004,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, CatalogTupleUpdate(attrelation, &heapTup->t_self, heapTup); - heap_close(attrelation, RowExclusiveLock); + table_close(attrelation, RowExclusiveLock); /* Install dependencies on new datatype and collation */ add_column_datatype_dependency(RelationGetRelid(rel), attnum, targettype); @@ -9728,132 +11050,102 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel, } /* - * Returns the address of the modified column + * Subroutine for ATExecAlterColumnType: remember that a constraint needs + * to be rebuilt (which we might already know). */ -static ObjectAddress -ATExecAlterColumnGenericOptions(Relation rel, - const char *colName, - List *options, - LOCKMODE lockmode) +static void +RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab) { - Relation ftrel; - Relation attrel; - ForeignServer *server; - ForeignDataWrapper *fdw; - HeapTuple tuple; - HeapTuple newtuple; - bool isnull; - Datum repl_val[Natts_pg_attribute]; - bool repl_null[Natts_pg_attribute]; - bool repl_repl[Natts_pg_attribute]; - Datum datum; - Form_pg_foreign_table fttableform; - Form_pg_attribute atttableform; - AttrNumber attnum; - ObjectAddress address; - - if (options == NIL) - return InvalidObjectAddress; - - /* First, determine FDW validator associated to the foreign table. */ - ftrel = heap_open(ForeignTableRelationId, AccessShareLock); - tuple = SearchSysCache1(FOREIGNTABLEREL, rel->rd_id); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("foreign table \"%s\" does not exist", - RelationGetRelationName(rel)))); - fttableform = (Form_pg_foreign_table) GETSTRUCT(tuple); - server = GetForeignServer(fttableform->ftserver); - fdw = GetForeignDataWrapper(server->fdwid); - - heap_close(ftrel, AccessShareLock); - ReleaseSysCache(tuple); - - attrel = heap_open(AttributeRelationId, RowExclusiveLock); - tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName); - if (!HeapTupleIsValid(tuple)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", - colName, RelationGetRelationName(rel)))); - - /* Prevent them from altering a system attribute */ - atttableform = (Form_pg_attribute) GETSTRUCT(tuple); - attnum = atttableform->attnum; - if (attnum <= 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot alter system column \"%s\"", colName))); - - - /* Initialize buffers for new tuple values */ - memset(repl_val, 0, sizeof(repl_val)); - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - /* Extract the current options */ - datum = SysCacheGetAttr(ATTNAME, - tuple, - Anum_pg_attribute_attfdwoptions, - &isnull); - if (isnull) - datum = PointerGetDatum(NULL); - - /* Transform the options */ - datum = transformGenericOptions(AttributeRelationId, - datum, - options, - fdw->fdwvalidator); - - if (PointerIsValid(DatumGetPointer(datum))) - repl_val[Anum_pg_attribute_attfdwoptions - 1] = datum; - else - repl_null[Anum_pg_attribute_attfdwoptions - 1] = true; - - repl_repl[Anum_pg_attribute_attfdwoptions - 1] = true; - - /* Everything looks good - update the tuple */ - - newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel), - repl_val, repl_null, repl_repl); - - CatalogTupleUpdate(attrel, &newtuple->t_self, newtuple); - - InvokeObjectPostAlterHook(RelationRelationId, - RelationGetRelid(rel), - atttableform->attnum); - ObjectAddressSubSet(address, RelationRelationId, - RelationGetRelid(rel), attnum); + /* + * This de-duplication check is critical for two independent reasons: we + * mustn't try to recreate the same constraint twice, and if a constraint + * depends on more than one column whose type is to be altered, we must + * capture its definition string before applying any of the column type + * changes. ruleutils.c will get confused if we ask again later. + */ + if (!list_member_oid(tab->changedConstraintOids, conoid)) + { + /* OK, capture the constraint's existing definition string */ + char *defstring = pg_get_constraintdef_command(conoid); - ReleaseSysCache(tuple); + tab->changedConstraintOids = lappend_oid(tab->changedConstraintOids, + conoid); + tab->changedConstraintDefs = lappend(tab->changedConstraintDefs, + defstring); + } +} - heap_close(attrel, RowExclusiveLock); +/* + * Subroutine for ATExecAlterColumnType: remember that an index needs + * to be rebuilt (which we might already know). + */ +static void +RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab) +{ + /* + * This de-duplication check is critical for two independent reasons: we + * mustn't try to recreate the same index twice, and if an index depends + * on more than one column whose type is to be altered, we must capture + * its definition string before applying any of the column type changes. + * ruleutils.c will get confused if we ask again later. + */ + if (!list_member_oid(tab->changedIndexOids, indoid)) + { + /* + * Before adding it as an index-to-rebuild, we'd better see if it + * belongs to a constraint, and if so rebuild the constraint instead. + * Typically this check fails, because constraint indexes normally + * have only dependencies on their constraint. But it's possible for + * such an index to also have direct dependencies on table columns, + * for example with a partial exclusion constraint. + */ + Oid conoid = get_index_constraint(indoid); - heap_freetuple(newtuple); + if (OidIsValid(conoid)) + { + RememberConstraintForRebuilding(conoid, tab); + } + else + { + /* OK, capture the index's existing definition string */ + char *defstring = pg_get_indexdef_string(indoid); - return address; + tab->changedIndexOids = lappend_oid(tab->changedIndexOids, + indoid); + tab->changedIndexDefs = lappend(tab->changedIndexDefs, + defstring); + } + } } /* * Cleanup after we've finished all the ALTER TYPE operations for a * particular relation. We have to drop and recreate all the indexes - * and constraints that depend on the altered columns. + * and constraints that depend on the altered columns. We do the + * actual dropping here, but re-creation is managed by adding work + * queue entries to do those steps later. */ static void ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) { ObjectAddress obj; + ObjectAddresses *objects; ListCell *def_item; ListCell *oid_item; + /* + * Collect all the constraints and indexes to drop so we can process them + * in a single call. That way we don't have to worry about dependencies + * among them. + */ + objects = new_object_addresses(); + /* * Re-parse the index and constraint definitions, and attach them to the * appropriate work queue entries. We do this before dropping because in * the case of a FOREIGN KEY constraint, we might not yet have exclusive * lock on the table the constraint is attached to, and we need to get - * that before dropping. It's safe because the parser won't actually look - * at the catalogs to detect the existing entry. + * that before reparsing/dropping. * * We can't rely on the output of deparsing to tell us which relation to * operate on, because concurrent activity might have made the name @@ -9869,6 +11161,7 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) Form_pg_constraint con; Oid relid; Oid confrelid; + char contype; bool conislocal; tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId)); @@ -9885,9 +11178,13 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) elog(ERROR, "could not identify relation associated with constraint %u", oldId); } confrelid = con->confrelid; + contype = con->contype; conislocal = con->conislocal; ReleaseSysCache(tup); + ObjectAddressSet(obj, ConstraintRelationId, oldId); + add_exact_object_address(&obj, objects); + /* * If the constraint is inherited (only), we don't want to inject a * new definition here; it'll get recreated when ATAddCheckConstraint @@ -9897,6 +11194,15 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) if (!conislocal) continue; + /* + * When rebuilding an FK constraint that references the table we're + * modifying, we might not yet have any lock on the FK's table, so get + * one now. We'll need AccessExclusiveLock for the DROP CONSTRAINT + * step, so there's no value in asking for anything weaker. + */ + if (relid != tab->relid && contype == CONSTRAINT_FOREIGN) + LockRelationOid(relid, AccessExclusiveLock); + ATPostAlterTypeParse(oldId, relid, confrelid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); @@ -9911,31 +11217,18 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) ATPostAlterTypeParse(oldId, relid, InvalidOid, (char *) lfirst(def_item), wqueue, lockmode, tab->rewrite); + + ObjectAddressSet(obj, RelationRelationId, oldId); + add_exact_object_address(&obj, objects); } /* - * Now we can drop the existing constraints and indexes --- constraints - * first, since some of them might depend on the indexes. In fact, we - * have to delete FOREIGN KEY constraints before UNIQUE constraints, but - * we already ordered the constraint list to ensure that would happen. It - * should be okay to use DROP_RESTRICT here, since nothing else should be - * depending on these objects. + * It should be okay to use DROP_RESTRICT here, since nothing else should + * be depending on these objects. */ - foreach(oid_item, tab->changedConstraintOids) - { - obj.classId = ConstraintRelationId; - obj.objectId = lfirst_oid(oid_item); - obj.objectSubId = 0; - performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); - } + performMultipleDeletions(objects, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); - foreach(oid_item, tab->changedIndexOids) - { - obj.classId = RelationRelationId; - obj.objectId = lfirst_oid(oid_item); - obj.objectSubId = 0; - performDeletion(&obj, DROP_RESTRICT, PERFORM_DELETION_INTERNAL); - } + free_object_addresses(objects); /* * The objects will get recreated during subsequent passes over the work @@ -9943,6 +11236,14 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode) */ } +/* + * Parse the previously-saved definition string for a constraint or index + * against the newly-established column data type(s), and queue up the + * resulting command parsetrees for execution. + * + * This might fail if, for example, you have a WHERE clause that uses an + * operator that's not available for the new column type. + */ static void ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, List **wqueue, LOCKMODE lockmode, bool rewrite) @@ -10004,6 +11305,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, if (!rewrite) TryReuseIndex(oldId, stmt); + stmt->reset_default_tblspc = true; /* keep the index's comment */ stmt->idxcomment = GetComment(oldId, RelationRelationId, 0); @@ -10035,6 +11337,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, /* keep any comment on the index */ indstmt->idxcomment = GetComment(indoid, RelationRelationId, 0); + indstmt->reset_default_tblspc = true; cmd->subtype = AT_ReAddIndex; tab->subcmds[AT_PASS_OLD_INDEX] = @@ -10057,6 +11360,7 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, if (con->contype == CONSTR_FOREIGN && !rewrite && tab->rewrite == 0) TryReuseForeignKey(oldId, con); + con->reset_default_tblspc = true; cmd->subtype = AT_ReAddConstraint; tab->subcmds[AT_PASS_OLD_CONSTR] = lappend(tab->subcmds[AT_PASS_OLD_CONSTR], cmd); @@ -10069,6 +11373,16 @@ ATPostAlterTypeParse(Oid oldId, Oid oldRelId, Oid refRelId, char *cmd, NIL, con->conname); } + else if (cmd->subtype == AT_SetNotNull) + { + /* + * The parser will create AT_SetNotNull subcommands for + * columns of PRIMARY KEY indexes/constraints, but we need + * not do anything with them here, because the columns' + * NOT NULL marks will already have been propagated into + * the new table definition. + */ + } else elog(ERROR, "unexpected statement subtype: %d", (int) cmd->subtype); @@ -10172,7 +11486,9 @@ TryReuseIndex(Oid oldId, IndexStmt *stmt) { Relation irel = index_open(oldId, NoLock); - stmt->oldNode = irel->rd_node.relNode; + /* If it's a partitioned index, there is no storage to share. */ + if (irel->rd_rel->relkind != RELKIND_PARTITIONED_INDEX) + stmt->oldNode = irel->rd_node.relNode; index_close(irel, NoLock); } } @@ -10195,31 +11511,141 @@ TryReuseForeignKey(Oid oldId, Constraint *con) int numkeys; int i; - Assert(con->contype == CONSTR_FOREIGN); - Assert(con->old_conpfeqop == NIL); /* already prepared this node */ + Assert(con->contype == CONSTR_FOREIGN); + Assert(con->old_conpfeqop == NIL); /* already prepared this node */ + + tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId)); + if (!HeapTupleIsValid(tup)) /* should not happen */ + elog(ERROR, "cache lookup failed for constraint %u", oldId); + + adatum = SysCacheGetAttr(CONSTROID, tup, + Anum_pg_constraint_conpfeqop, &isNull); + if (isNull) + elog(ERROR, "null conpfeqop for constraint %u", oldId); + arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ + numkeys = ARR_DIMS(arr)[0]; + /* test follows the one in ri_FetchConstraintInfo() */ + if (ARR_NDIM(arr) != 1 || + ARR_HASNULL(arr) || + ARR_ELEMTYPE(arr) != OIDOID) + elog(ERROR, "conpfeqop is not a 1-D Oid array"); + rawarr = (Oid *) ARR_DATA_PTR(arr); + + /* stash a List of the operator Oids in our Constraint node */ + for (i = 0; i < numkeys; i++) + con->old_conpfeqop = lappend_oid(con->old_conpfeqop, rawarr[i]); + + ReleaseSysCache(tup); +} + +/* + * ALTER COLUMN .. OPTIONS ( ... ) + * + * Returns the address of the modified column + */ +static ObjectAddress +ATExecAlterColumnGenericOptions(Relation rel, + const char *colName, + List *options, + LOCKMODE lockmode) +{ + Relation ftrel; + Relation attrel; + ForeignServer *server; + ForeignDataWrapper *fdw; + HeapTuple tuple; + HeapTuple newtuple; + bool isnull; + Datum repl_val[Natts_pg_attribute]; + bool repl_null[Natts_pg_attribute]; + bool repl_repl[Natts_pg_attribute]; + Datum datum; + Form_pg_foreign_table fttableform; + Form_pg_attribute atttableform; + AttrNumber attnum; + ObjectAddress address; + + if (options == NIL) + return InvalidObjectAddress; + + /* First, determine FDW validator associated to the foreign table. */ + ftrel = table_open(ForeignTableRelationId, AccessShareLock); + tuple = SearchSysCache1(FOREIGNTABLEREL, rel->rd_id); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("foreign table \"%s\" does not exist", + RelationGetRelationName(rel)))); + fttableform = (Form_pg_foreign_table) GETSTRUCT(tuple); + server = GetForeignServer(fttableform->ftserver); + fdw = GetForeignDataWrapper(server->fdwid); + + table_close(ftrel, AccessShareLock); + ReleaseSysCache(tuple); + + attrel = table_open(AttributeRelationId, RowExclusiveLock); + tuple = SearchSysCacheAttName(RelationGetRelid(rel), colName); + if (!HeapTupleIsValid(tuple)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + colName, RelationGetRelationName(rel)))); + + /* Prevent them from altering a system attribute */ + atttableform = (Form_pg_attribute) GETSTRUCT(tuple); + attnum = atttableform->attnum; + if (attnum <= 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot alter system column \"%s\"", colName))); + + + /* Initialize buffers for new tuple values */ + memset(repl_val, 0, sizeof(repl_val)); + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + + /* Extract the current options */ + datum = SysCacheGetAttr(ATTNAME, + tuple, + Anum_pg_attribute_attfdwoptions, + &isnull); + if (isnull) + datum = PointerGetDatum(NULL); + + /* Transform the options */ + datum = transformGenericOptions(AttributeRelationId, + datum, + options, + fdw->fdwvalidator); + + if (PointerIsValid(DatumGetPointer(datum))) + repl_val[Anum_pg_attribute_attfdwoptions - 1] = datum; + else + repl_null[Anum_pg_attribute_attfdwoptions - 1] = true; + + repl_repl[Anum_pg_attribute_attfdwoptions - 1] = true; - tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(oldId)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for constraint %u", oldId); + /* Everything looks good - update the tuple */ - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conpfeqop, &isNull); - if (isNull) - elog(ERROR, "null conpfeqop for constraint %u", oldId); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - numkeys = ARR_DIMS(arr)[0]; - /* test follows the one in ri_FetchConstraintInfo() */ - if (ARR_NDIM(arr) != 1 || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conpfeqop is not a 1-D Oid array"); - rawarr = (Oid *) ARR_DATA_PTR(arr); + newtuple = heap_modify_tuple(tuple, RelationGetDescr(attrel), + repl_val, repl_null, repl_repl); - /* stash a List of the operator Oids in our Constraint node */ - for (i = 0; i < numkeys; i++) - con->old_conpfeqop = lcons_oid(rawarr[i], con->old_conpfeqop); + CatalogTupleUpdate(attrel, &newtuple->t_self, newtuple); - ReleaseSysCache(tup); + InvokeObjectPostAlterHook(RelationRelationId, + RelationGetRelid(rel), + atttableform->attnum); + ObjectAddressSubSet(address, RelationRelationId, + RelationGetRelid(rel), attnum); + + ReleaseSysCache(tuple); + + table_close(attrel, RowExclusiveLock); + + heap_freetuple(newtuple); + + return address; } /* @@ -10249,7 +11675,7 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock target_rel = relation_open(relationOid, lockmode); /* Get its pg_class tuple, too */ - class_rel = heap_open(RelationRelationId, RowExclusiveLock); + class_rel = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relationOid)); if (!HeapTupleIsValid(tuple)) @@ -10451,23 +11877,19 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock list_free(index_oid_list); } - if (tuple_class->relkind == RELKIND_RELATION || - tuple_class->relkind == RELKIND_MATVIEW) - { - /* If it has a toast table, recurse to change its ownership */ - if (tuple_class->reltoastrelid != InvalidOid) - ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId, - true, lockmode); + /* If it has a toast table, recurse to change its ownership */ + if (tuple_class->reltoastrelid != InvalidOid) + ATExecChangeOwner(tuple_class->reltoastrelid, newOwnerId, + true, lockmode); - /* If it has dependent sequences, recurse to change them too */ - change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode); - } + /* If it has dependent sequences, recurse to change them too */ + change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode); } InvokeObjectPostAlterHook(RelationRelationId, relationOid, 0); ReleaseSysCache(tuple); - heap_close(class_rel, RowExclusiveLock); + table_close(class_rel, RowExclusiveLock); relation_close(target_rel, NoLock); } @@ -10485,7 +11907,7 @@ change_owner_fix_column_acls(Oid relationOid, Oid oldOwnerId, Oid newOwnerId) ScanKeyData key[1]; HeapTuple attributeTuple; - attRelation = heap_open(AttributeRelationId, RowExclusiveLock); + attRelation = table_open(AttributeRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -10532,7 +11954,7 @@ change_owner_fix_column_acls(Oid relationOid, Oid oldOwnerId, Oid newOwnerId) heap_freetuple(newtuple); } systable_endscan(scan); - heap_close(attRelation, RowExclusiveLock); + table_close(attRelation, RowExclusiveLock); } /* @@ -10554,7 +11976,7 @@ change_owner_recurse_to_sequences(Oid relationOid, Oid newOwnerId, LOCKMODE lock * SERIAL sequences are those having an auto dependency on one of the * table's columns (we don't care *which* column, exactly). */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -10701,7 +12123,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, if (defList == NIL && operation != AT_ReplaceRelOptions) return; /* nothing to do */ - pgclass = heap_open(RelationRelationId, RowExclusiveLock); + pgclass = table_open(RelationRelationId, RowExclusiveLock); /* Fetch heap tuple */ relid = RelationGetRelid(rel); @@ -10744,7 +12166,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - (void) index_reloptions(rel->rd_amroutine->amoptions, newOptions, true); + (void) index_reloptions(rel->rd_indam->amoptions, newOptions, true); break; default: ereport(ERROR, @@ -10783,7 +12205,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is supported only on automatically updatable views"), - errhint("%s", view_updatable_error))); + errhint("%s", _(view_updatable_error)))); } } @@ -10819,7 +12241,7 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, Relation toastrel; Oid toastid = rel->rd_rel->reltoastrelid; - toastrel = heap_open(toastid, lockmode); + toastrel = table_open(toastid, lockmode); /* Fetch heap tuple */ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(toastid)); @@ -10872,10 +12294,10 @@ ATExecSetRelOptions(Relation rel, List *defList, AlterTableType operation, ReleaseSysCache(tuple); - heap_close(toastrel, NoLock); + table_close(toastrel, NoLock); } - heap_close(pgclass, RowExclusiveLock); + table_close(pgclass, RowExclusiveLock); } /* @@ -10890,11 +12312,9 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) Oid reltoastrelid; Oid newrelfilenode; RelFileNode newrnode; - SMgrRelation dstrel; Relation pg_class; HeapTuple tuple; Form_pg_class rd_rel; - ForkNumber forkNum; List *reltoastidxids = NIL; ListCell *lc; @@ -10953,21 +12373,13 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) } /* Get a modifiable copy of the relation's pg_class row */ - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(tableOid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", tableOid); rd_rel = (Form_pg_class) GETSTRUCT(tuple); - /* - * Since we copy the file directly without looking at the shared buffers, - * we'd better first flush out any pages of the source relation that are - * in shared buffers. We assume no new changes will be made while we are - * holding exclusive lock on the rel. - */ - FlushRelationBuffers(rel); - /* * Relfilenodes are not unique in databases across tablespaces, so we need * to allocate a new one in the new tablespace. @@ -10979,48 +12391,27 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) newrnode = rel->rd_node; newrnode.relNode = newrelfilenode; newrnode.spcNode = newTableSpace; - dstrel = smgropen(newrnode, rel->rd_backend); - RelationOpenSmgr(rel); + /* hand off to AM to actually create the new filenode and copy the data */ + if (rel->rd_rel->relkind == RELKIND_INDEX) + { + index_copy_data(rel, newrnode); + } + else + { + Assert(rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_MATVIEW || + rel->rd_rel->relkind == RELKIND_TOASTVALUE); + table_relation_copy_data(rel, &newrnode); + } /* - * Create and copy all forks of the relation, and schedule unlinking of - * old physical files. + * Update the pg_class row. * - * NOTE: any conflict in relfilenode value will be caught in - * RelationCreateStorage(). + * NB: This wouldn't work if ATExecSetTableSpace() were allowed to be + * executed on pg_class or its indexes (the above copy wouldn't contain + * the updated pg_class entry), but that's forbidden above. */ - RelationCreateStorage(newrnode, rel->rd_rel->relpersistence); - - /* copy main fork */ - copy_relation_data(rel->rd_smgr, dstrel, MAIN_FORKNUM, - rel->rd_rel->relpersistence); - - /* copy those extra forks that exist */ - for (forkNum = MAIN_FORKNUM + 1; forkNum <= MAX_FORKNUM; forkNum++) - { - if (smgrexists(rel->rd_smgr, forkNum)) - { - smgrcreate(dstrel, forkNum, false); - - /* - * WAL log creation if the relation is persistent, or this is the - * init fork of an unlogged relation. - */ - if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || - (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && - forkNum == INIT_FORKNUM)) - log_smgrcreate(&newrnode, forkNum); - copy_relation_data(rel->rd_smgr, dstrel, forkNum, - rel->rd_rel->relpersistence); - } - } - - /* drop old relation, and close new one */ - RelationDropStorage(rel); - smgrclose(dstrel); - - /* update the pg_class row */ rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace; rd_rel->relfilenode = newrelfilenode; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); @@ -11029,7 +12420,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) heap_freetuple(tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); relation_close(rel, NoLock); @@ -11046,6 +12437,67 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) list_free(reltoastidxids); } +/* + * Special handling of ALTER TABLE SET TABLESPACE for relations with no + * storage that have an interest in preserving tablespace. + * + * Since these have no storage the tablespace can be updated with a simple + * metadata only operation to update the tablespace. + */ +static void +ATExecSetTableSpaceNoStorage(Relation rel, Oid newTableSpace) +{ + HeapTuple tuple; + Oid oldTableSpace; + Relation pg_class; + Form_pg_class rd_rel; + Oid reloid = RelationGetRelid(rel); + + /* + * Shouldn't be called on relations having storage; these are processed in + * phase 3. + */ + Assert(!RELKIND_HAS_STORAGE(rel->rd_rel->relkind)); + + /* Can't allow a non-shared relation in pg_global */ + if (newTableSpace == GLOBALTABLESPACE_OID) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("only shared relations can be placed in pg_global tablespace"))); + + /* + * No work if no change in tablespace. + */ + oldTableSpace = rel->rd_rel->reltablespace; + if (newTableSpace == oldTableSpace || + (newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0)) + { + InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); + return; + } + + /* Get a modifiable copy of the relation's pg_class row */ + pg_class = table_open(RelationRelationId, RowExclusiveLock); + + tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(reloid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", reloid); + rd_rel = (Form_pg_class) GETSTRUCT(tuple); + + /* update the pg_class row */ + rd_rel->reltablespace = (newTableSpace == MyDatabaseTableSpace) ? InvalidOid : newTableSpace; + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + + InvokeObjectPostAlterHook(RelationRelationId, reloid, 0); + + heap_freetuple(tuple); + + table_close(pg_class, RowExclusiveLock); + + /* Make sure the reltablespace change is visible */ + CommandCounterIncrement(); +} + /* * Alter Table ALL ... SET TABLESPACE * @@ -11065,7 +12517,7 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) ListCell *l; ScanKeyData key[1]; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; Oid orig_tablespaceoid; Oid new_tablespaceoid; @@ -11129,14 +12581,12 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(orig_tablespaceoid)); - rel = heap_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 1, key); + rel = table_open(RelationRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 1, key); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid relOid = HeapTupleGetOid(tuple); - Form_pg_class relForm; - - relForm = (Form_pg_class) GETSTRUCT(tuple); + Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple); + Oid relOid = relForm->oid; /* * Do not move objects in pg_catalog as part of this, if an admin @@ -11146,9 +12596,10 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) * Also, explicitly avoid any shared tables, temp tables, or TOAST * (TOAST will be moved with the main table). */ - if (IsSystemNamespace(relForm->relnamespace) || relForm->relisshared || + if (IsCatalogNamespace(relForm->relnamespace) || + relForm->relisshared || isAnyTempNamespace(relForm->relnamespace) || - relForm->relnamespace == PG_TOAST_NAMESPACE) + IsToastNamespace(relForm->relnamespace)) continue; /* Only move the object type requested */ @@ -11191,8 +12642,8 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) relations = lappend_oid(relations, relOid); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); if (relations == NIL) ereport(NOTICE, @@ -11221,99 +12672,59 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt) return new_tablespaceoid; } -/* - * Copy data, block by block - */ static void -copy_relation_data(SMgrRelation src, SMgrRelation dst, - ForkNumber forkNum, char relpersistence) +index_copy_data(Relation rel, RelFileNode newrnode) { - char *buf; - Page page; - bool use_wal; - bool copying_initfork; - BlockNumber nblocks; - BlockNumber blkno; + SMgrRelation dstrel; - /* - * palloc the buffer so that it's MAXALIGN'd. If it were just a local - * char[] array, the compiler might align it on any byte boundary, which - * can seriously hurt transfer speed to and from the kernel; not to - * mention possibly making log_newpage's accesses to the page header fail. - */ - buf = (char *) palloc(BLCKSZ); - page = (Page) buf; + dstrel = smgropen(newrnode, rel->rd_backend); + RelationOpenSmgr(rel); /* - * The init fork for an unlogged relation in many respects has to be - * treated the same as normal relation, changes need to be WAL logged and - * it needs to be synced to disk. + * Since we copy the file directly without looking at the shared buffers, + * we'd better first flush out any pages of the source relation that are + * in shared buffers. We assume no new changes will be made while we are + * holding exclusive lock on the rel. */ - copying_initfork = relpersistence == RELPERSISTENCE_UNLOGGED && - forkNum == INIT_FORKNUM; + FlushRelationBuffers(rel); /* - * We need to log the copied data in WAL iff WAL archiving/streaming is - * enabled AND it's a permanent relation. + * Create and copy all forks of the relation, and schedule unlinking of + * old physical files. + * + * NOTE: any conflict in relfilenode value will be caught in + * RelationCreateStorage(). */ - use_wal = XLogIsNeeded() && - (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork); + RelationCreateStorage(newrnode, rel->rd_rel->relpersistence); - nblocks = smgrnblocks(src, forkNum); + /* copy main fork */ + RelationCopyStorage(rel->rd_smgr, dstrel, MAIN_FORKNUM, + rel->rd_rel->relpersistence); - for (blkno = 0; blkno < nblocks; blkno++) + /* copy those extra forks that exist */ + for (ForkNumber forkNum = MAIN_FORKNUM + 1; + forkNum <= MAX_FORKNUM; forkNum++) { - /* If we got a cancel signal during the copy of the data, quit */ - CHECK_FOR_INTERRUPTS(); - - smgrread(src, forkNum, blkno, buf); - - if (!PageIsVerified(page, blkno)) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid page in block %u of relation %s", - blkno, - relpathbackend(src->smgr_rnode.node, - src->smgr_rnode.backend, - forkNum)))); - - /* - * WAL-log the copied page. Unfortunately we don't know what kind of a - * page this is, so we have to log the full page including any unused - * space. - */ - if (use_wal) - log_newpage(&dst->smgr_rnode.node, forkNum, blkno, page, false); - - PageSetChecksumInplace(page, blkno); + if (smgrexists(rel->rd_smgr, forkNum)) + { + smgrcreate(dstrel, forkNum, false); - /* - * Now write the page. We say isTemp = true even if it's not a temp - * rel, because there's no need for smgr to schedule an fsync for this - * write; we'll do it ourselves below. - */ - smgrextend(dst, forkNum, blkno, buf, true); + /* + * WAL log creation if the relation is persistent, or this is the + * init fork of an unlogged relation. + */ + if (rel->rd_rel->relpersistence == RELPERSISTENCE_PERMANENT || + (rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED && + forkNum == INIT_FORKNUM)) + log_smgrcreate(&newrnode, forkNum); + RelationCopyStorage(rel->rd_smgr, dstrel, forkNum, + rel->rd_rel->relpersistence); + } } - pfree(buf); - - /* - * If the rel is WAL-logged, must fsync before commit. We use heap_sync - * to ensure that the toast table gets fsync'd too. (For a temp or - * unlogged rel we don't care since the data will be gone after a crash - * anyway.) - * - * It's obvious that we must do this when not WAL-logging the copy. It's - * less obvious that we have to do it even if we did WAL-log the copied - * pages. The reason is that since we're copying outside shared buffers, a - * CHECKPOINT occurring during the copy has no way to flush the previously - * written data to disk (indeed it won't know the new rel even exists). A - * crash later on would replay WAL from the checkpoint, therefore it - * wouldn't replay our earlier WAL entries. If we do not fsync those pages - * here, they might still not be on disk when the crash occurs. - */ - if (relpersistence == RELPERSISTENCE_PERMANENT || copying_initfork) - smgrimmedsync(dst, forkNum); + /* drop old relation, and close new one */ + RelationDropStorage(rel); + smgrclose(dstrel); } /* @@ -11381,7 +12792,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) * A self-exclusive lock is needed here. See the similar case in * MergeAttributes() for a full explanation. */ - parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock); + parent_rel = table_openrv(parent, ShareUpdateExclusiveLock); /* * Must be owner of both parent and child -- child was checked by @@ -11449,14 +12860,6 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) parent->relname, RelationGetRelationName(child_rel)))); - /* If parent has OIDs then child must have OIDs */ - if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs", - RelationGetRelationName(child_rel), - RelationGetRelationName(parent_rel)))); - /* * If child_rel has row-level triggers with transition tables, we * currently don't allow it to become an inheritance child. See also @@ -11468,7 +12871,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("trigger \"%s\" prevents table \"%s\" from becoming an inheritance child", trigger_name, RelationGetRelationName(child_rel)), - errdetail("ROW triggers with transition tables are not supported in inheritance hierarchies"))); + errdetail("ROW triggers with transition tables are not supported in inheritance hierarchies."))); /* OK to create inheritance */ CreateInheritance(child_rel, parent_rel); @@ -11477,7 +12880,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) RelationGetRelid(parent_rel)); /* keep our lock on the parent relation until commit */ - heap_close(parent_rel, NoLock); + table_close(parent_rel, NoLock); return address; } @@ -11499,7 +12902,7 @@ CreateInheritance(Relation child_rel, Relation parent_rel) int32 inhseqno; /* Note: get RowExclusiveLock because we will write pg_inherits below. */ - catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock); + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); /* * Check for duplicates in the list of parents, and determine the highest @@ -11551,7 +12954,7 @@ CreateInheritance(Relation child_rel, Relation parent_rel) RELKIND_PARTITIONED_TABLE); /* Now we're done with pg_inherits */ - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); } /* @@ -11569,7 +12972,7 @@ decompile_conbin(HeapTuple contup, TupleDesc tupdesc) con = (Form_pg_constraint) GETSTRUCT(contup); attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull); if (isnull) - elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup)); + elog(ERROR, "null conbin for constraint %u", con->oid); expr = DirectFunctionCall2(pg_get_expr, attr, ObjectIdGetDatum(con->conrelid)); @@ -11622,7 +13025,7 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel) HeapTuple tuple; bool child_is_partition = false; - attrrel = heap_open(AttributeRelationId, RowExclusiveLock); + attrrel = table_open(AttributeRelationId, RowExclusiveLock); tupleDesc = RelationGetDescr(parent_rel); parent_natts = tupleDesc->natts; @@ -11703,46 +13106,7 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel) } } - /* - * If the parent has an OID column, so must the child, and we'd better - * update the child's attinhcount and attislocal the same as for normal - * columns. We needn't check data type or not-nullness though. - */ - if (tupleDesc->tdhasoid) - { - /* - * Here we match by column number not name; the match *must* be the - * system column, not some random column named "oid". - */ - tuple = SearchSysCacheCopy2(ATTNUM, - ObjectIdGetDatum(RelationGetRelid(child_rel)), - Int16GetDatum(ObjectIdAttributeNumber)); - if (HeapTupleIsValid(tuple)) - { - Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple); - - /* See comments above; these changes should be the same */ - childatt->attinhcount++; - - if (child_is_partition) - { - Assert(childatt->attinhcount == 1); - childatt->attislocal = false; - } - - CatalogTupleUpdate(attrrel, &tuple->t_self, tuple); - heap_freetuple(tuple); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("child table is missing column \"%s\"", - "oid"))); - } - } - - heap_close(attrrel, RowExclusiveLock); + table_close(attrrel, RowExclusiveLock); } /* @@ -11772,7 +13136,7 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel) HeapTuple parent_tuple; bool child_is_partition = false; - catalog_relation = heap_open(ConstraintRelationId, RowExclusiveLock); + catalog_relation = table_open(ConstraintRelationId, RowExclusiveLock); tuple_desc = RelationGetDescr(catalog_relation); /* If parent_rel is a partitioned table, child_rel must be a partition */ @@ -11784,7 +13148,7 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel) Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(parent_rel))); - parent_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId, + parent_scan = systable_beginscan(catalog_relation, ConstraintRelidTypidNameIndexId, true, NULL, 1, &parent_key); while (HeapTupleIsValid(parent_tuple = systable_getnext(parent_scan))) @@ -11807,7 +13171,7 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel) Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(child_rel))); - child_scan = systable_beginscan(catalog_relation, ConstraintRelidIndexId, + child_scan = systable_beginscan(catalog_relation, ConstraintRelidTypidNameIndexId, true, NULL, 1, &child_key); while (HeapTupleIsValid(child_tuple = systable_getnext(child_scan))) @@ -11884,7 +13248,7 @@ MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel) } systable_endscan(parent_scan); - heap_close(catalog_relation, RowExclusiveLock); + table_close(catalog_relation, RowExclusiveLock); } /* @@ -11908,7 +13272,7 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) * TABLE doesn't lock parent tables at all. We need some lock since we'll * be inspecting the parent's schema. */ - parent_rel = heap_openrv(parent, AccessShareLock); + parent_rel = table_openrv(parent, AccessShareLock); /* * We don't bother to check ownership of the parent table --- ownership of @@ -11918,12 +13282,12 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) /* Off to RemoveInheritance() where most of the work happens */ RemoveInheritance(rel, parent_rel); - /* keep our lock on the parent relation until commit */ - heap_close(parent_rel, NoLock); - ObjectAddressSet(address, RelationRelationId, RelationGetRelid(parent_rel)); + /* keep our lock on the parent relation until commit */ + table_close(parent_rel, NoLock); + return address; } @@ -11982,7 +13346,7 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) /* * Search through child columns looking for ones matching parent rel */ - catalogRelation = heap_open(AttributeRelationId, RowExclusiveLock); + catalogRelation = table_open(AttributeRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_attribute_attrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -12015,7 +13379,7 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) } } systable_endscan(scan); - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); /* * Likewise, find inherited check constraints and disinherit them. To do @@ -12023,12 +13387,12 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) * constraints. (We cheat a bit by only checking for name matches, * assuming that the expressions will match.) */ - catalogRelation = heap_open(ConstraintRelationId, RowExclusiveLock); + catalogRelation = table_open(ConstraintRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(parent_rel))); - scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId, + scan = systable_beginscan(catalogRelation, ConstraintRelidTypidNameIndexId, true, NULL, 1, key); connames = NIL; @@ -12048,7 +13412,7 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(child_rel))); - scan = systable_beginscan(catalogRelation, ConstraintRelidIndexId, + scan = systable_beginscan(catalogRelation, ConstraintRelidTypidNameIndexId, true, NULL, 1, key); while (HeapTupleIsValid(constraintTuple = systable_getnext(scan))) @@ -12090,7 +13454,7 @@ RemoveInheritance(Relation child_rel, Relation parent_rel) } systable_endscan(scan); - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); drop_parent_dependency(RelationGetRelid(child_rel), RelationRelationId, @@ -12123,7 +13487,7 @@ drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid, ScanKeyData key[3]; HeapTuple depTuple; - catalogRelation = heap_open(DependRelationId, RowExclusiveLock); + catalogRelation = table_open(DependRelationId, RowExclusiveLock); ScanKeyInit(&key[0], Anum_pg_depend_classid, @@ -12153,7 +13517,7 @@ drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid, } systable_endscan(scan); - heap_close(catalogRelation, RowExclusiveLock); + table_close(catalogRelation, RowExclusiveLock); } /* @@ -12171,6 +13535,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) { Oid relid = RelationGetRelid(rel); Type typetuple; + Form_pg_type typeform; Oid typeid; Relation inheritsRelation, relationRelation; @@ -12187,10 +13552,11 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) /* Validate the type. */ typetuple = typenameType(NULL, ofTypename, NULL); check_of_type(typetuple); - typeid = HeapTupleGetOid(typetuple); + typeform = (Form_pg_type) GETSTRUCT(typetuple); + typeid = typeform->oid; /* Fail if the table has any inheritance parents. */ - inheritsRelation = heap_open(InheritsRelationId, AccessShareLock); + inheritsRelation = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&key, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -12202,12 +13568,11 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("typed tables cannot inherit"))); systable_endscan(scan); - heap_close(inheritsRelation, AccessShareLock); + table_close(inheritsRelation, AccessShareLock); /* * Check the tuple descriptors for compatibility. Unlike inheritance, we * require that the order also match. However, attnotnull need not match. - * Also unlike inheritance, we do not require matching relhasoids. */ typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1); tableTupleDesc = RelationGetDescr(rel); @@ -12284,7 +13649,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) recordDependencyOn(&tableobj, &typeobj, DEPENDENCY_NORMAL); /* Update pg_class.reloftype */ - relationRelation = heap_open(RelationRelationId, RowExclusiveLock); + relationRelation = table_open(RelationRelationId, RowExclusiveLock); classtuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(classtuple)) elog(ERROR, "cache lookup failed for relation %u", relid); @@ -12294,7 +13659,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode) InvokeObjectPostAlterHook(RelationRelationId, relid, 0); heap_freetuple(classtuple); - heap_close(relationRelation, RowExclusiveLock); + table_close(relationRelation, RowExclusiveLock); ReleaseSysCache(typetuple); @@ -12329,7 +13694,7 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode) DEPENDENCY_NORMAL); /* Clear pg_class.reloftype */ - relationRelation = heap_open(RelationRelationId, RowExclusiveLock); + relationRelation = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relid); @@ -12339,7 +13704,7 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode) InvokeObjectPostAlterHook(RelationRelationId, relid, 0); heap_freetuple(tuple); - heap_close(relationRelation, RowExclusiveLock); + table_close(relationRelation, RowExclusiveLock); } /* @@ -12364,7 +13729,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid, /* * Check whether relreplident has changed, and update it if so. */ - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); pg_class_tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(rel))); if (!HeapTupleIsValid(pg_class_tuple)) @@ -12376,7 +13741,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid, pg_class_form->relreplident = ri_type; CatalogTupleUpdate(pg_class, &pg_class_tuple->t_self, pg_class_tuple); } - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); heap_freetuple(pg_class_tuple); /* @@ -12404,7 +13769,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid, * Clear the indisreplident flag from any index that had it previously, * and set it for any index that should have it now. */ - pg_index = heap_open(IndexRelationId, RowExclusiveLock); + pg_index = table_open(IndexRelationId, RowExclusiveLock); foreach(index, RelationGetIndexList(rel)) { Oid thisIndexOid = lfirst_oid(index); @@ -12440,7 +13805,7 @@ relation_mark_replica_identity(Relation rel, char ri_type, Oid indexOid, heap_freetuple(pg_index_tuple); } - heap_close(pg_index, RowExclusiveLock); + table_close(pg_index, RowExclusiveLock); } /* @@ -12495,7 +13860,7 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode RelationGetRelationName(indexRel), RelationGetRelationName(rel)))); /* The AM must support uniqueness, and the index must in fact be unique. */ - if (!indexRel->rd_amroutine->amcanunique || + if (!indexRel->rd_indam->amcanunique || !indexRel->rd_index->indisunique) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -12520,7 +13885,7 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode errmsg("cannot use partial index \"%s\" as replica identity", RelationGetRelationName(indexRel)))); /* And neither are invalid indexes. */ - if (!IndexIsValid(indexRel->rd_index)) + if (!indexRel->rd_index->indisvalid) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot use invalid index \"%s\" as replica identity", @@ -12532,10 +13897,6 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode int16 attno = indexRel->rd_index->indkey.values[key]; Form_pg_attribute attr; - /* Allow OID column to be indexed; it's certainly not nullable */ - if (attno == ObjectIdAttributeNumber) - continue; - /* * Reject any other system columns. (Going forward, we'll disallow * indexes containing such columns in the first place, but they might @@ -12574,7 +13935,7 @@ ATExecEnableRowSecurity(Relation rel) relid = RelationGetRelid(rel); - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -12584,7 +13945,7 @@ ATExecEnableRowSecurity(Relation rel) ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = true; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); heap_freetuple(tuple); } @@ -12598,7 +13959,7 @@ ATExecDisableRowSecurity(Relation rel) relid = RelationGetRelid(rel); /* Pull the record for this relation and update it */ - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -12608,7 +13969,7 @@ ATExecDisableRowSecurity(Relation rel) ((Form_pg_class) GETSTRUCT(tuple))->relrowsecurity = false; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); heap_freetuple(tuple); } @@ -12624,7 +13985,7 @@ ATExecForceNoForceRowSecurity(Relation rel, bool force_rls) relid = RelationGetRelid(rel); - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -12634,7 +13995,7 @@ ATExecForceNoForceRowSecurity(Relation rel, bool force_rls) ((Form_pg_class) GETSTRUCT(tuple))->relforcerowsecurity = force_rls; CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); heap_freetuple(tuple); } @@ -12658,7 +14019,7 @@ ATExecGenericOptions(Relation rel, List *options) if (options == NIL) return; - ftrel = heap_open(ForeignTableRelationId, RowExclusiveLock); + ftrel = table_open(ForeignTableRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(FOREIGNTABLEREL, rel->rd_id); if (!HeapTupleIsValid(tuple)) @@ -12711,7 +14072,7 @@ ATExecGenericOptions(Relation rel, List *options) InvokeObjectPostAlterHook(ForeignTableRelationId, RelationGetRelid(rel), 0); - heap_close(ftrel, RowExclusiveLock); + table_close(ftrel, RowExclusiveLock); heap_freetuple(tuple); } @@ -12777,7 +14138,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged) * permanent tables cannot reference unlogged ones. Self-referencing * foreign keys can safely be ignored. */ - pg_constraint = heap_open(ConstraintRelationId, AccessShareLock); + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); /* * Scan conrelid if changing to permanent, else confrelid. This also @@ -12789,7 +14150,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel))); scan = systable_beginscan(pg_constraint, - toLogged ? ConstraintRelidIndexId : InvalidOid, + toLogged ? ConstraintRelidTypidNameIndexId : InvalidOid, true, NULL, 1, skey); while (HeapTupleIsValid(tuple = systable_getnext(scan))) @@ -12837,7 +14198,7 @@ ATPrepChangePersistence(Relation rel, bool toLogged) systable_endscan(scan); - heap_close(pg_constraint, AccessShareLock); + table_close(pg_constraint, AccessShareLock); return true; } @@ -12925,7 +14286,7 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, Assert(objsMoved != NULL); /* OK, modify the pg_class row and pg_depend entry */ - classRel = heap_open(RelationRelationId, RowExclusiveLock); + classRel = table_open(RelationRelationId, RowExclusiveLock); AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid, nspOid, true, objsMoved); @@ -12946,7 +14307,7 @@ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid, false, objsMoved); } - heap_close(classRel, RowExclusiveLock); + table_close(classRel, RowExclusiveLock); } /* @@ -13083,7 +14444,7 @@ AlterSeqNamespaces(Relation classRel, Relation rel, * SERIAL sequences are those having an auto dependency on one of the * table's columns (we don't care *which* column, exactly). */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -13175,6 +14536,11 @@ register_on_commit_action(Oid relid, OnCommitAction action) oc->creating_subid = GetCurrentSubTransactionId(); oc->deleting_subid = InvalidSubTransactionId; + /* + * We use lcons() here so that ON COMMIT actions are processed in reverse + * order of registration. That might not be essential but it seems + * reasonable. + */ on_commits = lcons(oc, on_commits); MemoryContextSwitchTo(oldcxt); @@ -13213,6 +14579,7 @@ PreCommit_on_commit_actions(void) { ListCell *l; List *oids_to_truncate = NIL; + List *oids_to_drop = NIL; foreach(l, on_commits) { @@ -13235,39 +14602,67 @@ PreCommit_on_commit_actions(void) * relations, we can skip truncating ON COMMIT DELETE ROWS * tables, as they must still be empty. */ - if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPREL)) + if ((MyXactFlags & XACT_FLAGS_ACCESSEDTEMPNAMESPACE)) oids_to_truncate = lappend_oid(oids_to_truncate, oc->relid); break; case ONCOMMIT_DROP: - { - ObjectAddress object; + oids_to_drop = lappend_oid(oids_to_drop, oc->relid); + break; + } + } - object.classId = RelationRelationId; - object.objectId = oc->relid; - object.objectSubId = 0; + /* + * Truncate relations before dropping so that all dependencies between + * relations are removed after they are worked on. Doing it like this + * might be a waste as it is possible that a relation being truncated will + * be dropped anyway due to its parent being dropped, but this makes the + * code more robust because of not having to re-check that the relation + * exists at truncation time. + */ + if (oids_to_truncate != NIL) + heap_truncate(oids_to_truncate); - /* - * Since this is an automatic drop, rather than one - * directly initiated by the user, we pass the - * PERFORM_DELETION_INTERNAL flag. - */ - performDeletion(&object, - DROP_CASCADE, PERFORM_DELETION_INTERNAL); + if (oids_to_drop != NIL) + { + ObjectAddresses *targetObjects = new_object_addresses(); + ListCell *l; - /* - * Note that table deletion will call - * remove_on_commit_action, so the entry should get marked - * as deleted. - */ - Assert(oc->deleting_subid != InvalidSubTransactionId); - break; - } + foreach(l, oids_to_drop) + { + ObjectAddress object; + + object.classId = RelationRelationId; + object.objectId = lfirst_oid(l); + object.objectSubId = 0; + + Assert(!object_address_present(&object, targetObjects)); + + add_exact_object_address(&object, targetObjects); + } + + /* + * Since this is an automatic drop, rather than one directly initiated + * by the user, we pass the PERFORM_DELETION_INTERNAL flag. + */ + performMultipleDeletions(targetObjects, DROP_CASCADE, + PERFORM_DELETION_INTERNAL | PERFORM_DELETION_QUIETLY); + +#ifdef USE_ASSERT_CHECKING + + /* + * Note that table deletion will call remove_on_commit_action, so the + * entry should get marked as deleted. + */ + foreach(l, on_commits) + { + OnCommitItem *oc = (OnCommitItem *) lfirst(l); + + if (oc->oncommit != ONCOMMIT_DROP) + continue; + + Assert(oc->deleting_subid != InvalidSubTransactionId); } - } - if (oids_to_truncate != NIL) - { - heap_truncate(oids_to_truncate); - CommandCounterIncrement(); /* XXX needed? */ +#endif } } @@ -13283,12 +14678,8 @@ void AtEOXact_on_commit_actions(bool isCommit) { ListCell *cur_item; - ListCell *prev_item; - - prev_item = NULL; - cur_item = list_head(on_commits); - while (cur_item != NULL) + foreach(cur_item, on_commits) { OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item); @@ -13296,20 +14687,14 @@ AtEOXact_on_commit_actions(bool isCommit) oc->creating_subid != InvalidSubTransactionId) { /* cur_item must be removed */ - on_commits = list_delete_cell(on_commits, cur_item, prev_item); + on_commits = foreach_delete_current(on_commits, cur_item); pfree(oc); - if (prev_item) - cur_item = lnext(prev_item); - else - cur_item = list_head(on_commits); } else { /* cur_item must be preserved */ oc->creating_subid = InvalidSubTransactionId; oc->deleting_subid = InvalidSubTransactionId; - prev_item = cur_item; - cur_item = lnext(prev_item); } } } @@ -13326,24 +14711,16 @@ AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid) { ListCell *cur_item; - ListCell *prev_item; - - prev_item = NULL; - cur_item = list_head(on_commits); - while (cur_item != NULL) + foreach(cur_item, on_commits) { OnCommitItem *oc = (OnCommitItem *) lfirst(cur_item); if (!isCommit && oc->creating_subid == mySubid) { /* cur_item must be removed */ - on_commits = list_delete_cell(on_commits, cur_item, prev_item); + on_commits = foreach_delete_current(on_commits, cur_item); pfree(oc); - if (prev_item) - cur_item = lnext(prev_item); - else - cur_item = list_head(on_commits); } else { @@ -13352,8 +14729,6 @@ AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, oc->creating_subid = parentSubid; if (oc->deleting_subid == mySubid) oc->deleting_subid = isCommit ? parentSubid : InvalidSubTransactionId; - prev_item = cur_item; - cur_item = lnext(prev_item); } } } @@ -13395,6 +14770,28 @@ RangeVarCallbackOwnsTable(const RangeVar *relation, aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(relId)), relation->relname); } +/* + * Callback to RangeVarGetRelidExtended() for TRUNCATE processing. + */ +static void +RangeVarCallbackForTruncate(const RangeVar *relation, + Oid relId, Oid oldRelId, void *arg) +{ + HeapTuple tuple; + + /* Nothing to do if the relation was not found. */ + if (!OidIsValid(relId)) + return; + + tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relId)); + if (!HeapTupleIsValid(tuple)) /* should not happen */ + elog(ERROR, "cache lookup failed for relation %u", relId); + + truncate_check_rel(relId, (Form_pg_class) GETSTRUCT(tuple)); + + ReleaseSysCache(tuple); +} + /* * Callback to RangeVarGetRelidExtended(), similar to * RangeVarCallbackOwnsTable() but without checks on the type of the relation. @@ -13597,28 +14994,14 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) * rangetable entry. We need a ParseState for transformExpr. */ pstate = make_parsestate(NULL); - rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, true); + rte = addRangeTableEntryForRelation(pstate, rel, AccessShareLock, + NULL, false, true); addRTEtoQuery(pstate, rte, true, true, true); /* take care of any partition expressions */ foreach(l, partspec->partParams) { PartitionElem *pelem = castNode(PartitionElem, lfirst(l)); - ListCell *lc; - - /* Check for PARTITION BY ... (foo, foo) */ - foreach(lc, newspec->partParams) - { - PartitionElem *pparam = castNode(PartitionElem, lfirst(lc)); - - if (pelem->name && pparam->name && - strcmp(pelem->name, pparam->name) == 0) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_COLUMN), - errmsg("column \"%s\" appears more than once in partition key", - pelem->name), - parser_errposition(pstate, pelem->location))); - } if (pelem->expr) { @@ -13644,7 +15027,7 @@ transformPartitionSpec(Relation rel, PartitionSpec *partspec, char *strategy) * Expressions in the PartitionElems must be parse-analyzed already. */ static void -ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, +ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNumber *partattrs, List **partexprs, Oid *partopclass, Oid *partcollation, char strategy) { @@ -13671,14 +15054,28 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, ereport(ERROR, (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("column \"%s\" named in partition key does not exist", - pelem->name))); + pelem->name), + parser_errposition(pstate, pelem->location))); attform = (Form_pg_attribute) GETSTRUCT(atttuple); if (attform->attnum <= 0) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot use system column \"%s\" in partition key", - pelem->name))); + pelem->name), + parser_errposition(pstate, pelem->location))); + + /* + * Generated columns cannot work: They are computed after BEFORE + * triggers, but partition routing is done before all triggers. + */ + if (attform->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot use generated column in partition key"), + errdetail("Column \"%s\" is a generated column.", + pelem->name), + parser_errposition(pstate, pelem->location))); partattrs[attn] = attform->attnum; atttype = attform->atttypid; @@ -13767,6 +15164,25 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, errmsg("partition key expressions cannot contain system column references"))); } + /* + * Generated columns cannot work: They are computed after + * BEFORE triggers, but partition routing is done before all + * triggers. + */ + i = -1; + while ((i = bms_next_member(expr_attrs, i)) >= 0) + { + AttrNumber attno = i + FirstLowInvalidHeapAttributeNumber; + + if (TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot use generated column in partition key"), + errdetail("Column \"%s\" is a generated column.", + get_attname(RelationGetRelid(rel), attno, false)), + parser_errposition(pstate, pelem->location))); + } + /* * While it is not exactly *wrong* for a partition expression * to be a constant, it seems better to reject such keys. @@ -13828,14 +15244,14 @@ ComputePartitionAttrs(Relation rel, List *partParams, AttrNumber *partattrs, if (strategy == PARTITION_STRATEGY_HASH) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("data type %s has no default hash operator class", - format_type_be(atttype)), + errmsg("data type %s has no default operator class for access method \"%s\"", + format_type_be(atttype), "hash"), errhint("You must specify a hash operator class or define a default hash operator class for the data type."))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("data type %s has no default btree operator class", - format_type_be(atttype)), + errmsg("data type %s has no default operator class for access method \"%s\"", + format_type_be(atttype), "btree"), errhint("You must specify a btree operator class or define a default btree operator class for the data type."))); } @@ -13864,8 +15280,7 @@ PartConstraintImpliedByRelConstraint(Relation scanrel, { List *existConstraint = NIL; TupleConstr *constr = RelationGetDescr(scanrel)->constr; - int num_check, - i; + int i; if (constr && constr->has_not_null) { @@ -13899,6 +15314,27 @@ PartConstraintImpliedByRelConstraint(Relation scanrel, } } + return ConstraintImpliedByRelConstraint(scanrel, partConstraint, existConstraint); +} + +/* + * ConstraintImpliedByRelConstraint + * Do scanrel's existing constraints imply the given constraint? + * + * testConstraint is the constraint to validate. provenConstraint is a + * caller-provided list of conditions which this function may assume + * to be true. Both provenConstraint and testConstraint must be in + * implicit-AND form, must only contain immutable clauses, and must + * contain only Vars with varno = 1. + */ +bool +ConstraintImpliedByRelConstraint(Relation scanrel, List *testConstraint, List *provenConstraint) +{ + List *existConstraint = list_copy(provenConstraint); + TupleConstr *constr = RelationGetDescr(scanrel)->constr; + int num_check, + i; + num_check = (constr != NULL) ? constr->num_check : 0; for (i = 0; i < num_check; i++) { @@ -13929,115 +15365,94 @@ PartConstraintImpliedByRelConstraint(Relation scanrel, /* * Try to make the proof. Since we are comparing CHECK constraints, we * need to use weak implication, i.e., we assume existConstraint is - * not-false and try to prove the same for partConstraint. + * not-false and try to prove the same for testConstraint. * * Note that predicate_implied_by assumes its first argument is known - * immutable. That should always be true for partition constraints, so we - * don't test it here. + * immutable. That should always be true for both NOT NULL and partition + * constraints, so we don't test it here. */ - return predicate_implied_by(partConstraint, existConstraint, true); + return predicate_implied_by(testConstraint, existConstraint, true); } /* - * ValidatePartitionConstraints + * QueuePartitionConstraintValidation + * + * Add an entry to wqueue to have the given partition constraint validated by + * Phase 3, for the given relation, and all its children. * - * Check whether all rows in the given table obey the given partition - * constraint; if so, it can be attached as a partition.  We do this by - * scanning the table (or all of its leaf partitions) row by row, except when - * the existing constraints are sufficient to prove that the new partitioning - * constraint must already hold. + * We first verify whether the given constraint is implied by pre-existing + * relation constraints; if it is, there's no need to scan the table to + * validate, so don't queue in that case. */ static void -ValidatePartitionConstraints(List **wqueue, Relation scanrel, - List *scanrel_children, - List *partConstraint, - bool validate_default) +QueuePartitionConstraintValidation(List **wqueue, Relation scanrel, + List *partConstraint, + bool validate_default) { - bool found_whole_row; - ListCell *lc; - - if (partConstraint == NIL) - return; - /* - * Based on the table's existing constraints, determine if we can skip - * scanning the table to validate the partition constraint. + * Based on the table's existing constraints, determine whether or not we + * may skip scanning the table. */ if (PartConstraintImpliedByRelConstraint(scanrel, partConstraint)) { if (!validate_default) - ereport(INFO, + ereport(DEBUG1, (errmsg("partition constraint for table \"%s\" is implied by existing constraints", RelationGetRelationName(scanrel)))); else - ereport(INFO, + ereport(DEBUG1, (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", RelationGetRelationName(scanrel)))); return; } - /* Constraints proved insufficient, so we need to scan the table. */ - foreach(lc, scanrel_children) + /* + * Constraints proved insufficient. For plain relations, queue a + * validation item now; for partitioned tables, recurse to process each + * partition. + */ + if (scanrel->rd_rel->relkind == RELKIND_RELATION) { AlteredTableInfo *tab; - Oid part_relid = lfirst_oid(lc); - Relation part_rel; - List *my_partconstr = partConstraint; - /* Lock already taken */ - if (part_relid != RelationGetRelid(scanrel)) - part_rel = heap_open(part_relid, NoLock); - else - part_rel = scanrel; + /* Grab a work queue entry. */ + tab = ATGetQueueEntry(wqueue, scanrel); + Assert(tab->partition_constraint == NULL); + tab->partition_constraint = (Expr *) linitial(partConstraint); + tab->validate_default = validate_default; + } + else if (scanrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + PartitionDesc partdesc = RelationGetPartitionDesc(scanrel); + int i; - /* - * Skip if the partition is itself a partitioned table. We can only - * ever scan RELKIND_RELATION relations. - */ - if (part_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + for (i = 0; i < partdesc->nparts; i++) { - if (part_rel != scanrel) - heap_close(part_rel, NoLock); - continue; - } + Relation part_rel; + bool found_whole_row; + List *thisPartConstraint; + + /* + * This is the minimum lock we need to prevent deadlocks. + */ + part_rel = table_open(partdesc->oids[i], AccessExclusiveLock); - if (part_rel != scanrel) - { /* * Adjust the constraint for scanrel so that it matches this * partition's attribute numbers. */ - my_partconstr = map_partition_varattnos(my_partconstr, 1, - part_rel, scanrel, - &found_whole_row); + thisPartConstraint = + map_partition_varattnos(partConstraint, 1, + part_rel, scanrel, &found_whole_row); /* There can never be a whole-row reference here */ if (found_whole_row) - elog(ERROR, "unexpected whole-row reference found in partition key"); + elog(ERROR, "unexpected whole-row reference found in partition constraint"); - /* Can we skip scanning this part_rel? */ - if (PartConstraintImpliedByRelConstraint(part_rel, my_partconstr)) - { - if (!validate_default) - ereport(INFO, - (errmsg("partition constraint for table \"%s\" is implied by existing constraints", - RelationGetRelationName(part_rel)))); - else - ereport(INFO, - (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", - RelationGetRelationName(part_rel)))); - heap_close(part_rel, NoLock); - continue; - } + QueuePartitionConstraintValidation(wqueue, part_rel, + thisPartConstraint, + validate_default); + table_close(part_rel, NoLock); /* keep lock till commit */ } - - /* Grab a work queue entry. */ - tab = ATGetQueueEntry(wqueue, part_rel); - tab->partition_constraint = (Expr *) linitial(my_partconstr); - tab->validate_default = validate_default; - - /* keep our lock until commit */ - if (part_rel != scanrel) - heap_close(part_rel, NoLock); } } @@ -14063,19 +15478,22 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) bool found_whole_row; Oid defaultPartOid; List *partBoundConstraint; - List *cloned; - ListCell *l; /* - * We must lock the default partition, because attaching a new partition - * will change its partition constraint. + * We must lock the default partition if one exists, because attaching a + * new partition will change its partition constraint. */ defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(rel)); if (OidIsValid(defaultPartOid)) LockRelationOid(defaultPartOid, AccessExclusiveLock); - attachrel = heap_openrv(cmd->name, AccessExclusiveLock); + attachrel = table_openrv(cmd->name, AccessExclusiveLock); + + /* + * XXX I think it'd be a good idea to grab locks on all tables referenced + * by FKs at this point also. + */ /* * Must be owner of both parent and source table -- parent was checked by @@ -14099,7 +15517,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) * Table being attached should not already be part of inheritance; either * as a child table... */ - catalog = heap_open(InheritsRelationId, AccessShareLock); + catalog = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&skey, Anum_pg_inherits_inhrelid, BTEqualStrategyNumber, F_OIDEQ, @@ -14125,7 +15543,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot attach inheritance parent as partition"))); systable_endscan(scan); - heap_close(catalog, AccessShareLock); + table_close(catalog, AccessShareLock); /* * Prevent circularity by seeing if rel is a partition of attachrel. (In @@ -14152,6 +15570,14 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) RelationGetRelationName(rel), RelationGetRelationName(attachrel)))); + /* If the parent is permanent, so must be all of its partitions. */ + if (rel->rd_rel->relpersistence != RELPERSISTENCE_TEMP && + attachrel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot attach a temporary relation as partition of permanent relation \"%s\"", + RelationGetRelationName(rel)))); + /* Temp parent cannot have a partition that is itself not a temp */ if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP && attachrel->rd_rel->relpersistence != RELPERSISTENCE_TEMP) @@ -14174,22 +15600,6 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot attach temporary relation of another session as partition"))); - /* If parent has OIDs then child must have OIDs */ - if (rel->rd_rel->relhasoids && !attachrel->rd_rel->relhasoids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot attach table \"%s\" without OIDs as partition of" - " table \"%s\" with OIDs", RelationGetRelationName(attachrel), - RelationGetRelationName(rel)))); - - /* OTOH, if parent doesn't have them, do not allow in attachrel either */ - if (attachrel->rd_rel->relhasoids && !rel->rd_rel->relhasoids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot attach table \"%s\" with OIDs as partition of table" - " \"%s\" without OIDs", RelationGetRelationName(attachrel), - RelationGetRelationName(rel)))); - /* Check if there are any columns in attachrel that aren't in the parent */ tupleDesc = RelationGetDescr(attachrel); natts = tupleDesc->natts; @@ -14227,9 +15637,6 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) trigger_name, RelationGetRelationName(attachrel)), errdetail("ROW triggers with transition tables are not supported on partitions"))); - /* OK to create inheritance. Rest of the checks performed there */ - CreateInheritance(attachrel, rel); - /* * Check that the new partition's bound is valid and does not overlap any * of existing partitions of the parent - note that it does not return on @@ -14238,6 +15645,9 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) check_new_partition_bound(RelationGetRelationName(attachrel), rel, cmd->bound); + /* OK to create inheritance. Rest of the checks performed there */ + CreateInheritance(attachrel, rel); + /* Update the pg_class entry. */ StorePartitionBound(attachrel, rel, cmd->bound); @@ -14248,33 +15658,10 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) CloneRowTriggersToPartition(rel, attachrel); /* - * Clone foreign key constraints, and setup for Phase 3 to verify them. + * Clone foreign key constraints. Callee is responsible for setting up + * for phase 3 constraint verification. */ - cloned = NIL; - CloneForeignKeyConstraints(RelationGetRelid(rel), - RelationGetRelid(attachrel), &cloned); - foreach(l, cloned) - { - ClonedConstraint *cloned = lfirst(l); - NewConstraint *newcon; - Relation clonedrel; - AlteredTableInfo *parttab; - - clonedrel = relation_open(cloned->relid, NoLock); - parttab = ATGetQueueEntry(wqueue, clonedrel); - - newcon = (NewConstraint *) palloc0(sizeof(NewConstraint)); - newcon->name = cloned->constraint->conname; - newcon->contype = CONSTR_FOREIGN; - newcon->refrelid = cloned->refrelid; - newcon->refindid = cloned->conindid; - newcon->conid = cloned->conid; - newcon->qual = (Node *) cloned->constraint; - - parttab->constraints = lappend(parttab->constraints, newcon); - - relation_close(clonedrel, NoLock); - } + CloneForeignKeyConstraints(wqueue, rel, attachrel); /* * Generate partition constraint from the partition bound specification. @@ -14291,9 +15678,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) /* * Run the partition quals through const-simplification similar to * check constraints. We skip canonicalize_qual, though, because - * partition quals should be in canonical form already; also, since - * the qual is in implicit-AND format, we'd have to explicitly convert - * it to explicit-AND format and back again. + * partition quals should be in canonical form already. */ partConstraint = (List *) eval_const_expressions(NULL, @@ -14314,41 +15699,47 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd) "unexpected whole-row reference found in partition key"); /* Validate partition constraints against the table being attached. */ - ValidatePartitionConstraints(wqueue, attachrel, attachrel_children, - partConstraint, false); + QueuePartitionConstraintValidation(wqueue, attachrel, partConstraint, + false); } /* - * Check whether default partition has a row that would fit the partition - * being attached. + * If we're attaching a partition other than the default partition and a + * default one exists, then that partition's partition constraint changes, + * so add an entry to the work queue to validate it, too. (We must not do + * this when the partition being attached is the default one; we already + * did it above!) */ - defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(rel)); if (OidIsValid(defaultPartOid)) { Relation defaultrel; - List *defaultrel_children; List *defPartConstraint; - /* We already have taken a lock on default partition. */ - defaultrel = heap_open(defaultPartOid, NoLock); + Assert(!cmd->bound->is_default); + + /* we already hold a lock on the default partition */ + defaultrel = table_open(defaultPartOid, NoLock); defPartConstraint = get_proposed_default_constraint(partBoundConstraint); - defaultrel_children = - find_all_inheritors(defaultPartOid, - AccessExclusiveLock, NULL); - ValidatePartitionConstraints(wqueue, defaultrel, - defaultrel_children, - defPartConstraint, true); + + /* + * Map the Vars in the constraint expression from rel's attnos to + * defaultrel's. + */ + defPartConstraint = + map_partition_varattnos(defPartConstraint, + 1, defaultrel, rel, NULL); + QueuePartitionConstraintValidation(wqueue, defaultrel, + defPartConstraint, true); /* keep our lock until commit. */ - heap_close(defaultrel, NoLock); + table_close(defaultrel, NoLock); } ObjectAddressSet(address, RelationRelationId, RelationGetRelid(attachrel)); /* keep our lock until commit */ - heap_close(attachrel, NoLock); + table_close(attachrel, NoLock); return address; } @@ -14394,6 +15785,34 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) i++; } + /* + * If we're attaching a foreign table, we must fail if any of the indexes + * is a constraint index; otherwise, there's nothing to do here. Do this + * before starting work, to avoid wasting the effort of building a few + * non-unique indexes before coming across a unique one. + */ + if (attachrel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + foreach(cell, idxes) + { + Oid idx = lfirst_oid(cell); + Relation idxRel = index_open(idx, AccessShareLock); + + if (idxRel->rd_index->indisunique || + idxRel->rd_index->indisprimary) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot attach foreign table \"%s\" as partition of partitioned table \"%s\"", + RelationGetRelationName(attachrel), + RelationGetRelationName(rel)), + errdetail("Table \"%s\" contains unique indexes.", + RelationGetRelationName(rel)))); + index_close(idxRel, AccessShareLock); + } + + goto out; + } + /* * For each index on the partitioned table, find a matching one in the * partition-to-be; if one is not found, create one. @@ -14420,8 +15839,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) /* construct an indexinfo to compare existing indexes against */ info = BuildIndexInfo(idxRel); attmap = convert_tuples_by_name_map(RelationGetDescr(attachrel), - RelationGetDescr(rel), - gettext_noop("could not convert row type")); + RelationGetDescr(rel)); constraintOid = get_relation_idx_constraint_oid(RelationGetRelid(rel), idx); /* @@ -14431,10 +15849,11 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) */ for (i = 0; i < list_length(attachRelIdxs); i++) { - Oid cldConstrOid = InvalidOid; + Oid cldIdxId = RelationGetRelid(attachrelIdxRels[i]); + Oid cldConstrOid = InvalidOid; /* does this index have a parent? if so, can't use it */ - if (has_superclass(RelationGetRelid(attachrelIdxRels[i]))) + if (attachrelIdxRels[i]->rd_rel->relispartition) continue; if (CompareIndexInfo(attachInfos[i], info, @@ -14455,7 +15874,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) { cldConstrOid = get_relation_idx_constraint_oid(RelationGetRelid(attachrel), - RelationGetRelid(attachrelIdxRels[i])); + cldIdxId); /* no dice */ if (!OidIsValid(cldConstrOid)) continue; @@ -14464,8 +15883,11 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) /* bingo. */ IndexSetParentIndex(attachrelIdxRels[i], idx); if (OidIsValid(constraintOid)) - ConstraintSetParentConstraint(cldConstrOid, constraintOid); + ConstraintSetParentConstraint(cldConstrOid, constraintOid, + RelationGetRelid(attachrel)); found = true; + + CommandCounterIncrement(); break; } } @@ -14479,7 +15901,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) IndexStmt *stmt; Oid constraintOid; - stmt = generateClonedIndexStmt(NULL, RelationGetRelid(attachrel), + stmt = generateClonedIndexStmt(NULL, idxRel, attmap, RelationGetDescr(rel)->natts, &constraintOid); @@ -14492,6 +15914,7 @@ AttachPartitionEnsureIndexes(Relation rel, Relation attachrel) index_close(idxRel, AccessShareLock); } +out: /* Clean up. */ for (i = 0; i < list_length(attachRelIdxs); i++) index_close(attachrelIdxRels[i], AccessShareLock); @@ -14511,29 +15934,27 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) ScanKeyData key; SysScanDesc scan; HeapTuple tuple; - MemoryContext oldcxt, - perTupCxt; + MemoryContext perTupCxt; ScanKeyInit(&key, Anum_pg_trigger_tgrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(parent))); - pg_trigger = heap_open(TriggerRelationId, RowExclusiveLock); + pg_trigger = table_open(TriggerRelationId, RowExclusiveLock); scan = systable_beginscan(pg_trigger, TriggerRelidNameIndexId, true, NULL, 1, &key); perTupCxt = AllocSetContextCreate(CurrentMemoryContext, "clone trig", ALLOCSET_SMALL_SIZES); - oldcxt = MemoryContextSwitchTo(perTupCxt); while (HeapTupleIsValid(tuple = systable_getnext(scan))) { - Form_pg_trigger trigForm; + Form_pg_trigger trigForm = (Form_pg_trigger) GETSTRUCT(tuple); CreateTrigStmt *trigStmt; Node *qual = NULL; Datum value; bool isnull; List *cols = NIL; - - trigForm = (Form_pg_trigger) GETSTRUCT(tuple); + List *trigargs = NIL; + MemoryContext oldcxt; /* * Ignore statement-level triggers; those are not cloned. @@ -14552,6 +15973,9 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) elog(ERROR, "unexpected trigger \"%s\" found", NameStr(trigForm->tgname)); + /* Use short-lived context for CREATE TRIGGER */ + oldcxt = MemoryContextSwitchTo(perTupCxt); + /* * If there is a WHEN clause, generate a 'cooked' version of it that's * appropriate for the partition. @@ -14589,7 +16013,28 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) col = TupleDescAttr(parent->rd_att, trigForm->tgattr.values[i] - 1); - cols = lappend(cols, makeString(NameStr(col->attname))); + cols = lappend(cols, + makeString(pstrdup(NameStr(col->attname)))); + } + } + + /* Reconstruct trigger arguments list. */ + if (trigForm->tgnargs > 0) + { + char *p; + + value = heap_getattr(tuple, Anum_pg_trigger_tgargs, + RelationGetDescr(pg_trigger), &isnull); + if (isnull) + elog(ERROR, "tgargs is null for trigger \"%s\" in partition \"%s\"", + NameStr(trigForm->tgname), RelationGetRelationName(partition)); + + p = (char *) VARDATA_ANY(DatumGetByteaPP(value)); + + for (int i = 0; i < trigForm->tgnargs; i++) + { + trigargs = lappend(trigargs, makeString(pstrdup(p))); + p += strlen(p) + 1; } } @@ -14597,7 +16042,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) trigStmt->trigname = NameStr(trigForm->tgname); trigStmt->relation = NULL; trigStmt->funcname = NULL; /* passed separately */ - trigStmt->args = NULL; /* passed separately */ + trigStmt->args = trigargs; trigStmt->row = true; trigStmt->timing = trigForm->tgtype & TRIGGER_TYPE_TIMING_MASK; trigStmt->events = trigForm->tgtype & TRIGGER_TYPE_EVENT_MASK; @@ -14611,17 +16056,17 @@ CloneRowTriggersToPartition(Relation parent, Relation partition) CreateTrigger(trigStmt, NULL, RelationGetRelid(partition), trigForm->tgconstrrelid, InvalidOid, InvalidOid, - trigForm->tgfoid, HeapTupleGetOid(tuple), qual, + trigForm->tgfoid, trigForm->oid, qual, false, true); + MemoryContextSwitchTo(oldcxt); MemoryContextReset(perTupCxt); } - MemoryContextSwitchTo(oldcxt); MemoryContextDelete(perTupCxt); systable_endscan(scan); - heap_close(pg_trigger, RowExclusiveLock); + table_close(pg_trigger, RowExclusiveLock); } /* @@ -14637,12 +16082,12 @@ ATExecDetachPartition(Relation rel, RangeVar *name) HeapTuple tuple, newtuple; Datum new_val[Natts_pg_class]; - bool isnull, - new_null[Natts_pg_class], + bool new_null[Natts_pg_class], new_repl[Natts_pg_class]; ObjectAddress address; Oid defaultPartOid; List *indexes; + List *fks; ListCell *cell; /* @@ -14654,13 +16099,16 @@ ATExecDetachPartition(Relation rel, RangeVar *name) if (OidIsValid(defaultPartOid)) LockRelationOid(defaultPartOid, AccessExclusiveLock); - partRel = heap_openrv(name, AccessShareLock); + partRel = table_openrv(name, ShareUpdateExclusiveLock); + + /* Ensure that foreign keys still hold after this detach */ + ATDetachCheckNoForeignKeyRefs(partRel); /* All inheritance related checks are performed within the function */ RemoveInheritance(partRel, rel); /* Update pg_class tuple */ - classRel = heap_open(RelationRelationId, RowExclusiveLock); + classRel = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(partRel))); if (!HeapTupleIsValid(tuple)) @@ -14668,10 +16116,6 @@ ATExecDetachPartition(Relation rel, RangeVar *name) RelationGetRelid(partRel)); Assert(((Form_pg_class) GETSTRUCT(tuple))->relispartition); - (void) SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relpartbound, - &isnull); - Assert(!isnull); - /* Clear relpartbound and reset relispartition */ memset(new_val, 0, sizeof(new_val)); memset(new_null, false, sizeof(new_null)); @@ -14685,7 +16129,6 @@ ATExecDetachPartition(Relation rel, RangeVar *name) ((Form_pg_class) GETSTRUCT(newtuple))->relispartition = false; CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple); heap_freetuple(newtuple); - heap_close(classRel, RowExclusiveLock); if (OidIsValid(defaultPartOid)) { @@ -14709,17 +16152,96 @@ ATExecDetachPartition(Relation rel, RangeVar *name) { Oid idxid = lfirst_oid(cell); Relation idx; + Oid constrOid; if (!has_superclass(idxid)) continue; Assert((IndexGetRelation(get_partition_parent(idxid), false) == - RelationGetRelid(rel))); + RelationGetRelid(rel))); idx = index_open(idxid, AccessExclusiveLock); IndexSetParentIndex(idx, InvalidOid); - relation_close(idx, AccessExclusiveLock); + + /* If there's a constraint associated with the index, detach it too */ + constrOid = get_relation_idx_constraint_oid(RelationGetRelid(partRel), + idxid); + if (OidIsValid(constrOid)) + ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid); + + index_close(idx, NoLock); + } + table_close(classRel, RowExclusiveLock); + + /* + * Detach any foreign keys that are inherited. This includes creating + * additional action triggers. + */ + fks = copyObject(RelationGetFKeyList(partRel)); + foreach(cell, fks) + { + ForeignKeyCacheInfo *fk = lfirst(cell); + HeapTuple contup; + Form_pg_constraint conform; + Constraint *fkconstraint; + + contup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fk->conoid)); + if (!HeapTupleIsValid(contup)) + elog(ERROR, "cache lookup failed for constraint %u", fk->conoid); + conform = (Form_pg_constraint) GETSTRUCT(contup); + + /* consider only the inherited foreign keys */ + if (conform->contype != CONSTRAINT_FOREIGN || + !OidIsValid(conform->conparentid)) + { + ReleaseSysCache(contup); + continue; + } + + /* unset conparentid and adjust conislocal, coninhcount, etc. */ + ConstraintSetParentConstraint(fk->conoid, InvalidOid, InvalidOid); + + /* + * Make the action triggers on the referenced relation. When this was + * a partition the action triggers pointed to the parent rel (they + * still do), but now we need separate ones of our own. + */ + fkconstraint = makeNode(Constraint); + fkconstraint->conname = pstrdup(NameStr(conform->conname)); + fkconstraint->fk_upd_action = conform->confupdtype; + fkconstraint->fk_del_action = conform->confdeltype; + fkconstraint->deferrable = conform->condeferrable; + fkconstraint->initdeferred = conform->condeferred; + + createForeignKeyActionTriggers(partRel, conform->confrelid, + fkconstraint, fk->conoid, + conform->conindid); + + ReleaseSysCache(contup); + } + list_free_deep(fks); + + /* + * Any sub-constrains that are in the referenced-side of a larger + * constraint have to be removed. This partition is no longer part of the + * key space of the constraint. + */ + foreach(cell, GetParentedForeignKeyRefs(partRel)) + { + Oid constrOid = lfirst_oid(cell); + ObjectAddress constraint; + + ConstraintSetParentConstraint(constrOid, InvalidOid, InvalidOid); + deleteDependencyRecordsForClass(ConstraintRelationId, + constrOid, + ConstraintRelationId, + DEPENDENCY_INTERNAL); + CommandCounterIncrement(); + + ObjectAddressSet(constraint, ConstraintRelationId, constrOid); + performDeletion(&constraint, DROP_RESTRICT, 0); } + CommandCounterIncrement(); /* * Invalidate the parent's relcache so that the partition is no longer @@ -14730,7 +16252,7 @@ ATExecDetachPartition(Relation rel, RangeVar *name) ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partRel)); /* keep our lock until commit */ - heap_close(partRel, NoLock); + table_close(partRel, NoLock); return address; } @@ -14741,9 +16263,9 @@ ATExecDetachPartition(Relation rel, RangeVar *name) */ struct AttachIndexCallbackState { - Oid partitionOid; - Oid parentTblOid; - bool lockedParentTbl; + Oid partitionOid; + Oid parentTblOid; + bool lockedParentTbl; }; static void @@ -14841,8 +16363,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partIdx)); /* Silently do nothing if already in the right state */ - currParent = !has_superclass(partIdxId) ? InvalidOid : - get_partition_parent(partIdxId); + currParent = partIdx->rd_rel->relispartition ? + get_partition_parent(partIdxId) : InvalidOid; if (currParent != RelationGetRelid(parentIdx)) { IndexInfo *childInfo; @@ -14855,7 +16377,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) cldConstrId = InvalidOid; /* - * If this partition already has an index attached, refuse the operation. + * If this partition already has an index attached, refuse the + * operation. */ refuseDupeIndexAttach(parentIdx, partIdx, partTbl); @@ -14892,15 +16415,14 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) childInfo = BuildIndexInfo(partIdx); parentInfo = BuildIndexInfo(parentIdx); attmap = convert_tuples_by_name_map(RelationGetDescr(partTbl), - RelationGetDescr(parentTbl), - gettext_noop("could not convert row type")); + RelationGetDescr(parentTbl)); if (!CompareIndexInfo(childInfo, parentInfo, partIdx->rd_indcollation, parentIdx->rd_indcollation, partIdx->rd_opfamily, parentIdx->rd_opfamily, attmap, - RelationGetDescr(partTbl)->natts)) + RelationGetDescr(parentTbl)->natts)) ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("cannot attach index \"%s\" as a partition of index \"%s\"", @@ -14909,8 +16431,8 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) errdetail("The index definitions do not match."))); /* - * If there is a constraint in the parent, make sure there is one - * in the child too. + * If there is a constraint in the parent, make sure there is one in + * the child too. */ constraintOid = get_relation_idx_constraint_oid(RelationGetRelid(parentTbl), RelationGetRelid(parentIdx)); @@ -14926,15 +16448,16 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) RelationGetRelationName(partIdx), RelationGetRelationName(parentIdx)), errdetail("The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\".", - RelationGetRelationName(parentIdx), - RelationGetRelationName(parentTbl), - RelationGetRelationName(partIdx)))); + RelationGetRelationName(parentIdx), + RelationGetRelationName(parentTbl), + RelationGetRelationName(partIdx)))); } /* All good -- do it */ IndexSetParentIndex(partIdx, RelationGetRelid(parentIdx)); if (OidIsValid(constraintOid)) - ConstraintSetParentConstraint(cldConstrId, constraintOid); + ConstraintSetParentConstraint(cldConstrId, constraintOid, + RelationGetRelid(partTbl)); pfree(attmap); @@ -14956,36 +16479,18 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name) static void refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTbl) { - Relation pg_inherits; - ScanKeyData key; - HeapTuple tuple; - SysScanDesc scan; - - pg_inherits = heap_open(InheritsRelationId, AccessShareLock); - ScanKeyInit(&key, Anum_pg_inherits_inhparent, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(RelationGetRelid(parentIdx))); - scan = systable_beginscan(pg_inherits, InheritsParentIndexId, true, - NULL, 1, &key); - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - Form_pg_inherits inhForm; - Oid tab; - - inhForm = (Form_pg_inherits) GETSTRUCT(tuple); - tab = IndexGetRelation(inhForm->inhrelid, false); - if (tab == RelationGetRelid(partitionTbl)) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot attach index \"%s\" as a partition of index \"%s\"", - RelationGetRelationName(partIdx), - RelationGetRelationName(parentIdx)), - errdetail("Another index is already attached for partition \"%s\".", - RelationGetRelationName(partitionTbl)))); - } + Oid existingIdx; - systable_endscan(scan); - heap_close(pg_inherits, AccessShareLock); + existingIdx = index_get_partition(partitionTbl, + RelationGetRelid(parentIdx)); + if (OidIsValid(existingIdx)) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot attach index \"%s\" as a partition of index \"%s\"", + RelationGetRelationName(partIdx), + RelationGetRelationName(parentIdx)), + errdetail("Another index is already attached for partition \"%s\".", + RelationGetRelationName(partitionTbl)))); } /* @@ -14997,12 +16502,12 @@ refuseDupeIndexAttach(Relation parentIdx, Relation partIdx, Relation partitionTb static void validatePartitionedIndex(Relation partedIdx, Relation partedTbl) { - Relation inheritsRel; - SysScanDesc scan; - ScanKeyData key; - int tuples = 0; - HeapTuple inhTup; - bool updated = false; + Relation inheritsRel; + SysScanDesc scan; + ScanKeyData key; + int tuples = 0; + HeapTuple inhTup; + bool updated = false; Assert(partedIdx->rd_rel->relkind == RELKIND_PARTITIONED_INDEX); @@ -15011,7 +16516,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) * (verifying the pg_index entry for each), and if we reach the total * amount we expect, we can mark this parent index as valid. */ - inheritsRel = heap_open(InheritsRelationId, AccessShareLock); + inheritsRel = table_open(InheritsRelationId, AccessShareLock); ScanKeyInit(&key, Anum_pg_inherits_inhparent, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(partedIdx))); @@ -15020,23 +16525,22 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) while ((inhTup = systable_getnext(scan)) != NULL) { Form_pg_inherits inhForm = (Form_pg_inherits) GETSTRUCT(inhTup); - HeapTuple indTup; - Form_pg_index indexForm; + HeapTuple indTup; + Form_pg_index indexForm; indTup = SearchSysCache1(INDEXRELID, - ObjectIdGetDatum(inhForm->inhrelid)); - if (!indTup) - elog(ERROR, "cache lookup failed for index %u", - inhForm->inhrelid); + ObjectIdGetDatum(inhForm->inhrelid)); + if (!HeapTupleIsValid(indTup)) + elog(ERROR, "cache lookup failed for index %u", inhForm->inhrelid); indexForm = (Form_pg_index) GETSTRUCT(indTup); - if (IndexIsValid(indexForm)) + if (indexForm->indisvalid) tuples += 1; ReleaseSysCache(indTup); } /* Done with pg_inherits */ systable_endscan(scan); - heap_close(inheritsRel, AccessShareLock); + table_close(inheritsRel, AccessShareLock); /* * If we found as many inherited indexes as the partitioned table has @@ -15047,7 +16551,7 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) Relation idxRel; HeapTuple newtup; - idxRel = heap_open(IndexRelationId, RowExclusiveLock); + idxRel = table_open(IndexRelationId, RowExclusiveLock); newtup = heap_copytuple(partedIdx->rd_indextuple); ((Form_pg_index) GETSTRUCT(newtup))->indisvalid = true; @@ -15055,15 +16559,14 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) CatalogTupleUpdate(idxRel, &partedIdx->rd_indextuple->t_self, newtup); - heap_close(idxRel, RowExclusiveLock); + table_close(idxRel, RowExclusiveLock); } /* * If this index is in turn a partition of a larger index, validating it * might cause the parent to become valid also. Try that. */ - if (updated && - has_superclass(RelationGetRelid(partedIdx))) + if (updated && partedIdx->rd_rel->relispartition) { Oid parentIdxId, parentTblId; @@ -15085,3 +16588,107 @@ validatePartitionedIndex(Relation partedIdx, Relation partedTbl) relation_close(parentTbl, AccessExclusiveLock); } } + +/* + * Return an OID list of constraints that reference the given relation + * that are marked as having a parent constraints. + */ +static List * +GetParentedForeignKeyRefs(Relation partition) +{ + Relation pg_constraint; + HeapTuple tuple; + SysScanDesc scan; + ScanKeyData key[2]; + List *constraints = NIL; + + /* + * If no indexes, or no columns are referenceable by FKs, we can avoid the + * scan. + */ + if (RelationGetIndexList(partition) == NIL || + bms_is_empty(RelationGetIndexAttrBitmap(partition, + INDEX_ATTR_BITMAP_KEY))) + return NIL; + + /* Search for constraints referencing this table */ + pg_constraint = table_open(ConstraintRelationId, AccessShareLock); + ScanKeyInit(&key[0], + Anum_pg_constraint_confrelid, BTEqualStrategyNumber, + F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(partition))); + ScanKeyInit(&key[1], + Anum_pg_constraint_contype, BTEqualStrategyNumber, + F_CHAREQ, CharGetDatum(CONSTRAINT_FOREIGN)); + + /* XXX This is a seqscan, as we don't have a usable index */ + scan = systable_beginscan(pg_constraint, InvalidOid, true, NULL, 2, key); + while ((tuple = systable_getnext(scan)) != NULL) + { + Form_pg_constraint constrForm = (Form_pg_constraint) GETSTRUCT(tuple); + + /* + * We only need to process constraints that are part of larger ones. + */ + if (!OidIsValid(constrForm->conparentid)) + continue; + + constraints = lappend_oid(constraints, constrForm->oid); + } + + systable_endscan(scan); + table_close(pg_constraint, AccessShareLock); + + return constraints; +} + +/* + * During DETACH PARTITION, verify that any foreign keys pointing to the + * partitioned table would not become invalid. An error is raised if any + * referenced values exist. + */ +static void +ATDetachCheckNoForeignKeyRefs(Relation partition) +{ + List *constraints; + ListCell *cell; + + constraints = GetParentedForeignKeyRefs(partition); + + foreach(cell, constraints) + { + Oid constrOid = lfirst_oid(cell); + HeapTuple tuple; + Form_pg_constraint constrForm; + Relation rel; + Trigger trig; + + tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(constrOid)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for constraint %u", constrOid); + constrForm = (Form_pg_constraint) GETSTRUCT(tuple); + + Assert(OidIsValid(constrForm->conparentid)); + Assert(constrForm->confrelid == RelationGetRelid(partition)); + + /* prevent data changes into the referencing table until commit */ + rel = table_open(constrForm->conrelid, ShareLock); + + MemSet(&trig, 0, sizeof(trig)); + trig.tgoid = InvalidOid; + trig.tgname = NameStr(constrForm->conname); + trig.tgenabled = TRIGGER_FIRES_ON_ORIGIN; + trig.tgisinternal = true; + trig.tgconstrrelid = RelationGetRelid(partition); + trig.tgconstrindid = constrForm->conindid; + trig.tgconstraint = constrForm->oid; + trig.tgdeferrable = false; + trig.tginitdeferred = false; + /* we needn't fill in remaining fields */ + + RI_PartitionRemove_Check(&trig, rel, partition); + + ReleaseSysCache(tuple); + + table_close(rel, NoLock); + } +} diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index f7e9160a4f6..84efb414d8c 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -35,7 +35,7 @@ * and munge the system catalogs of the new database. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,6 +54,7 @@ #include "access/reloptions.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "access/xloginsert.h" @@ -81,7 +82,6 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" #include "utils/varlena.h" @@ -91,7 +91,7 @@ char *temp_tablespaces = NULL; static void create_tablespace_directories(const char *location, - const Oid tablespaceoid); + const Oid tablespaceoid); static bool destroy_tablespace_directories(Oid tablespaceoid, bool redo); @@ -307,6 +307,15 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) stmt->tablespacename), errdetail("The prefix \"pg_\" is reserved for system tablespaces."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for tablespace names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->tablespacename, "regress_", 8) != 0) + elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\""); +#endif + /* * Check that there is no other tablespace by this name. (The unique * index would catch this anyway, but might as well give a friendlier @@ -323,10 +332,13 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) * lock the proposed tablename against other would-be creators. The * insertion will roll back if we find problems below. */ - rel = heap_open(TableSpaceRelationId, RowExclusiveLock); + rel = table_open(TableSpaceRelationId, RowExclusiveLock); MemSet(nulls, false, sizeof(nulls)); + tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId, + Anum_pg_tablespace_oid); + values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid); values[Anum_pg_tablespace_spcname - 1] = DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename)); values[Anum_pg_tablespace_spcowner - 1] = @@ -345,7 +357,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) tuple = heap_form_tuple(rel->rd_att, values, nulls); - tablespaceoid = CatalogTupleInsert(rel, tuple); + CatalogTupleInsert(rel, tuple); heap_freetuple(tuple); @@ -382,7 +394,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt) pfree(location); /* We keep the lock on pg_tablespace until commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return tablespaceoid; #else /* !HAVE_SYMLINK */ @@ -403,22 +415,23 @@ DropTableSpace(DropTableSpaceStmt *stmt) { #ifdef HAVE_SYMLINK char *tablespacename = stmt->tablespacename; - HeapScanDesc scandesc; + TableScanDesc scandesc; Relation rel; HeapTuple tuple; + Form_pg_tablespace spcform; ScanKeyData entry[1]; Oid tablespaceoid; /* * Find the target tuple */ - rel = heap_open(TableSpaceRelationId, RowExclusiveLock); + rel = table_open(TableSpaceRelationId, RowExclusiveLock); ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); + scandesc = table_beginscan_catalog(rel, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); if (!HeapTupleIsValid(tuple)) @@ -436,13 +449,14 @@ DropTableSpace(DropTableSpaceStmt *stmt) (errmsg("tablespace \"%s\" does not exist, skipping", tablespacename))); /* XXX I assume I need one or both of these next two calls */ - heap_endscan(scandesc); - heap_close(rel, NoLock); + table_endscan(scandesc); + table_close(rel, NoLock); } return; } - tablespaceoid = HeapTupleGetOid(tuple); + spcform = (Form_pg_tablespace) GETSTRUCT(tuple); + tablespaceoid = spcform->oid; /* Must be tablespace owner */ if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId())) @@ -463,7 +477,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) */ CatalogTupleDelete(rel, &tuple->t_self); - heap_endscan(scandesc); + table_endscan(scandesc); /* * Remove any comments or security labels on this tablespace. @@ -546,7 +560,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) LWLockRelease(TablespaceCreateLock); /* We keep the lock on pg_tablespace until commit */ - heap_close(rel, NoLock); + table_close(rel, NoLock); #else /* !HAVE_SYMLINK */ ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -914,20 +928,20 @@ RenameTableSpace(const char *oldname, const char *newname) Oid tspId; Relation rel; ScanKeyData entry[1]; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; HeapTuple newtuple; Form_pg_tablespace newform; ObjectAddress address; /* Search pg_tablespace */ - rel = heap_open(TableSpaceRelationId, RowExclusiveLock); + rel = table_open(TableSpaceRelationId, RowExclusiveLock); ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(oldname)); - scan = heap_beginscan_catalog(rel, 1, entry); + scan = table_beginscan_catalog(rel, 1, entry); tup = heap_getnext(scan, ForwardScanDirection); if (!HeapTupleIsValid(tup)) ereport(ERROR, @@ -935,14 +949,14 @@ RenameTableSpace(const char *oldname, const char *newname) errmsg("tablespace \"%s\" does not exist", oldname))); - tspId = HeapTupleGetOid(tup); newtuple = heap_copytuple(tup); newform = (Form_pg_tablespace) GETSTRUCT(newtuple); + tspId = newform->oid; - heap_endscan(scan); + table_endscan(scan); /* Must be owner */ - if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId())) + if (!pg_tablespace_ownercheck(tspId, GetUserId())) aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_TABLESPACE, oldname); /* Validate new name */ @@ -952,12 +966,21 @@ RenameTableSpace(const char *oldname, const char *newname) errmsg("unacceptable tablespace name \"%s\"", newname), errdetail("The prefix \"pg_\" is reserved for system tablespaces."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for tablespace names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(newname, "regress_", 8) != 0) + elog(WARNING, "tablespaces created by regression test cases should have names starting with \"regress_\""); +#endif + /* Make sure the new name doesn't exist */ ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(newname)); - scan = heap_beginscan_catalog(rel, 1, entry); + scan = table_beginscan_catalog(rel, 1, entry); tup = heap_getnext(scan, ForwardScanDirection); if (HeapTupleIsValid(tup)) ereport(ERROR, @@ -965,7 +988,7 @@ RenameTableSpace(const char *oldname, const char *newname) errmsg("tablespace \"%s\" already exists", newname))); - heap_endscan(scan); + table_endscan(scan); /* OK, update the entry */ namestrcpy(&(newform->spcname), newname); @@ -976,7 +999,7 @@ RenameTableSpace(const char *oldname, const char *newname) ObjectAddressSet(address, TableSpaceRelationId, tspId); - heap_close(rel, NoLock); + table_close(rel, NoLock); return address; } @@ -989,7 +1012,7 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) { Relation rel; ScanKeyData entry[1]; - HeapScanDesc scandesc; + TableScanDesc scandesc; HeapTuple tup; Oid tablespaceoid; Datum datum; @@ -1001,13 +1024,13 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) HeapTuple newtuple; /* Search pg_tablespace */ - rel = heap_open(TableSpaceRelationId, RowExclusiveLock); + rel = table_open(TableSpaceRelationId, RowExclusiveLock); ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(stmt->tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); + scandesc = table_beginscan_catalog(rel, 1, entry); tup = heap_getnext(scandesc, ForwardScanDirection); if (!HeapTupleIsValid(tup)) ereport(ERROR, @@ -1015,10 +1038,10 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) errmsg("tablespace \"%s\" does not exist", stmt->tablespacename))); - tablespaceoid = HeapTupleGetOid(tup); + tablespaceoid = ((Form_pg_tablespace) GETSTRUCT(tup))->oid; /* Must be owner of the existing object */ - if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLESPACE, stmt->tablespacename); @@ -1044,13 +1067,13 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt) /* Update system catalog. */ CatalogTupleUpdate(rel, &newtuple->t_self, newtuple); - InvokeObjectPostAlterHook(TableSpaceRelationId, HeapTupleGetOid(tup), 0); + InvokeObjectPostAlterHook(TableSpaceRelationId, tablespaceoid, 0); heap_freetuple(newtuple); /* Conclude heap scan. */ - heap_endscan(scandesc); - heap_close(rel, NoLock); + table_endscan(scandesc); + table_close(rel, NoLock); return tablespaceoid; } @@ -1064,10 +1087,11 @@ bool check_default_tablespace(char **newval, void **extra, GucSource source) { /* - * If we aren't inside a transaction, we cannot do database access so - * cannot verify the name. Must accept the value on faith. + * If we aren't inside a transaction, or connected to a database, we + * cannot do the catalog accesses necessary to verify the name. Must + * accept the value on faith. */ - if (IsTransactionState()) + if (IsTransactionState() && MyDatabaseId != InvalidOid) { if (**newval != '\0' && !OidIsValid(get_tablespace_oid(*newval, true))) @@ -1099,7 +1123,9 @@ check_default_tablespace(char **newval, void **extra, GucSource source) * GetDefaultTablespace -- get the OID of the current default tablespace * * Temporary objects have different default tablespaces, hence the - * relpersistence parameter must be specified. + * relpersistence parameter must be specified. Also, for partitioned tables, + * we disallow specifying the database default, so that needs to be specified + * too. * * May return InvalidOid to indicate "use the database's default tablespace". * @@ -1110,7 +1136,7 @@ check_default_tablespace(char **newval, void **extra, GucSource source) * default_tablespace GUC variable. */ Oid -GetDefaultTablespace(char relpersistence) +GetDefaultTablespace(char relpersistence, bool partitioned) { Oid result; @@ -1136,10 +1162,18 @@ GetDefaultTablespace(char relpersistence) /* * Allow explicit specification of database's default tablespace in - * default_tablespace without triggering permissions checks. + * default_tablespace without triggering permissions checks. Don't allow + * specifying that when creating a partitioned table, however, since the + * result is confusing. */ if (result == MyDatabaseTableSpace) + { + if (partitioned) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot specify default tablespace for partitioned relations"))); result = InvalidOid; + } return result; } @@ -1175,11 +1209,12 @@ check_temp_tablespaces(char **newval, void **extra, GucSource source) } /* - * If we aren't inside a transaction, we cannot do database access so - * cannot verify the individual names. Must accept the list on faith. - * Fortunately, there's then also no need to pass the data to fd.c. + * If we aren't inside a transaction, or connected to a database, we + * cannot do the catalog accesses necessary to verify the name. Must + * accept the value on faith. Fortunately, there's then also no need to + * pass the data to fd.c. */ - if (IsTransactionState()) + if (IsTransactionState() && MyDatabaseId != InvalidOid) { temp_tablespaces_extra *myextra; Oid *tblSpcs; @@ -1383,7 +1418,7 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok) { Oid result; Relation rel; - HeapScanDesc scandesc; + TableScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; @@ -1392,23 +1427,23 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok) * index on name, on the theory that pg_tablespace will usually have just * a few entries and so an indexed lookup is a waste of effort. */ - rel = heap_open(TableSpaceRelationId, AccessShareLock); + rel = table_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], Anum_pg_tablespace_spcname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(tablespacename)); - scandesc = heap_beginscan_catalog(rel, 1, entry); + scandesc = table_beginscan_catalog(rel, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ if (HeapTupleIsValid(tuple)) - result = HeapTupleGetOid(tuple); + result = ((Form_pg_tablespace) GETSTRUCT(tuple))->oid; else result = InvalidOid; - heap_endscan(scandesc); - heap_close(rel, AccessShareLock); + table_endscan(scandesc); + table_close(rel, AccessShareLock); if (!OidIsValid(result) && !missing_ok) ereport(ERROR, @@ -1429,7 +1464,7 @@ get_tablespace_name(Oid spc_oid) { char *result; Relation rel; - HeapScanDesc scandesc; + TableScanDesc scandesc; HeapTuple tuple; ScanKeyData entry[1]; @@ -1438,13 +1473,13 @@ get_tablespace_name(Oid spc_oid) * index on oid, on the theory that pg_tablespace will usually have just a * few entries and so an indexed lookup is a waste of effort. */ - rel = heap_open(TableSpaceRelationId, AccessShareLock); + rel = table_open(TableSpaceRelationId, AccessShareLock); ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, + Anum_pg_tablespace_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(spc_oid)); - scandesc = heap_beginscan_catalog(rel, 1, entry); + scandesc = table_beginscan_catalog(rel, 1, entry); tuple = heap_getnext(scandesc, ForwardScanDirection); /* We assume that there can be at most one matching tuple */ @@ -1453,8 +1488,8 @@ get_tablespace_name(Oid spc_oid) else result = NULL; - heap_endscan(scandesc); - heap_close(rel, AccessShareLock); + table_endscan(scandesc); + table_close(rel, AccessShareLock); return result; } diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 0d57d467484..cdb1105b4a7 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -3,7 +3,7 @@ * trigger.c * PostgreSQL TRIGGERs support code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,15 +14,18 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" -#include "access/sysattr.h" #include "access/htup_details.h" +#include "access/relation.h" +#include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" +#include "catalog/partition.h" #include "catalog/pg_constraint.h" #include "catalog/pg_inherits.h" #include "catalog/pg_proc.h" @@ -35,13 +38,13 @@ #include "miscadmin.h" #include "nodes/bitmapset.h" #include "nodes/makefuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_clause.h" #include "parser/parse_collate.h" #include "parser/parse_func.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" +#include "partitioning/partdesc.h" #include "pgstat.h" #include "rewrite/rewriteManip.h" #include "storage/bufmgr.h" @@ -57,7 +60,6 @@ #include "utils/rel.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #include "utils/tuplestore.h" @@ -73,39 +75,34 @@ static int MyTriggerDepth = 0; * they use, so we let them be duplicated. Be sure to update all if one needs * to be changed, however. */ -#define GetUpdatedColumns(relinfo, estate) \ - (rt_fetch((relinfo)->ri_RangeTableIndex, (estate)->es_range_table)->updatedCols) +#define GetAllUpdatedColumns(relinfo, estate) \ + (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \ + exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols)) /* Local function prototypes */ static void ConvertTriggerToFK(CreateTrigStmt *stmt, Oid funcoid); static void SetTriggerFlags(TriggerDesc *trigdesc, Trigger *trigger); -static HeapTuple GetTupleForTrigger(EState *estate, - EPQState *epqstate, - ResultRelInfo *relinfo, - ItemPointer tid, - LockTupleMode lockmode, - TupleTableSlot **newSlot, - HeapUpdateFailureData *hufdp); +static bool GetTupleForTrigger(EState *estate, + EPQState *epqstate, + ResultRelInfo *relinfo, + ItemPointer tid, + LockTupleMode lockmode, + TupleTableSlot *oldslot, + TupleTableSlot **newSlot); static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo, - Trigger *trigger, TriggerEvent event, - Bitmapset *modifiedCols, - HeapTuple oldtup, HeapTuple newtup); + Trigger *trigger, TriggerEvent event, + Bitmapset *modifiedCols, + TupleTableSlot *oldslot, TupleTableSlot *newslot); static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata, - int tgindx, - FmgrInfo *finfo, - Instrumentation *instr, - MemoryContext per_tuple_context); -static Tuplestorestate *AfterTriggerGetTransitionTable(int event, - HeapTuple oldtup, - HeapTuple newtup, - TransitionCaptureState *transition_capture); -static void TransitionTableAddTuple(HeapTuple heaptup, Tuplestorestate *tuplestore, - TupleConversionMap *map); + int tgindx, + FmgrInfo *finfo, + Instrumentation *instr, + MemoryContext per_tuple_context); static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, - int event, bool row_trigger, - HeapTuple oldtup, HeapTuple newtup, - List *recheckIndexes, Bitmapset *modifiedCols, - TransitionCaptureState *transition_capture); + int event, bool row_trigger, + TupleTableSlot *oldtup, TupleTableSlot *newtup, + List *recheckIndexes, Bitmapset *modifiedCols, + TransitionCaptureState *transition_capture); static void AfterTriggerEnlargeQueryState(void); static bool before_stmt_triggers_fired(Oid relid, CmdType cmdType); @@ -195,9 +192,9 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, bool partition_recurse; if (OidIsValid(relOid)) - rel = heap_open(relOid, ShareRowExclusiveLock); + rel = table_open(relOid, ShareRowExclusiveLock); else - rel = heap_openrv(stmt->relation, ShareRowExclusiveLock); + rel = table_openrv(stmt->relation, ShareRowExclusiveLock); /* * Triggers must be on tables or views, and there are additional @@ -583,10 +580,12 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * 'OLD' must always have varno equal to 1 and 'NEW' equal to 2. */ rte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, makeAlias("old", NIL), false, false); addRTEtoQuery(pstate, rte, false, true, true); rte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, makeAlias("new", NIL), false, false); addRTEtoQuery(pstate, rte, false, true, true); @@ -642,6 +641,24 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("BEFORE trigger's WHEN condition cannot reference NEW system columns"), parser_errposition(pstate, var->location))); + if (TRIGGER_FOR_BEFORE(tgtype) && + var->varattno == 0 && + RelationGetDescr(rel)->constr && + RelationGetDescr(rel)->constr->has_generated_stored) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("BEFORE trigger's WHEN condition cannot reference NEW generated columns"), + errdetail("A whole-row reference is used and the table contains generated columns."), + parser_errposition(pstate, var->location))); + if (TRIGGER_FOR_BEFORE(tgtype) && + var->varattno > 0 && + TupleDescAttr(RelationGetDescr(rel), var->varattno - 1)->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("BEFORE trigger's WHEN condition cannot reference NEW generated columns"), + errdetail("Column \"%s\" is a generated column.", + NameStr(TupleDescAttr(RelationGetDescr(rel), var->varattno - 1)->attname)), + parser_errposition(pstate, var->location))); break; default: /* can't happen without add_missing_from, so just elog */ @@ -716,7 +733,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, RI_FKey_trigger_type(funcoid) != RI_TRIGGER_NONE) { /* Keep lock on target rel until end of xact */ - heap_close(rel, NoLock); + table_close(rel, NoLock); ConvertTriggerToFK(stmt, funcoid); @@ -756,10 +773,9 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, NULL, /* no exclusion */ NULL, /* no check constraint */ NULL, - NULL, true, /* islocal */ 0, /* inhcount */ - true, /* isnoinherit */ + true, /* noinherit */ isInternal); /* is_internal */ } @@ -767,9 +783,10 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * Generate the trigger's OID now, so that we can use it in the name if * needed. */ - tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); - trigoid = GetNewOid(tgrel); + trigoid = GetNewOidWithIndex(tgrel, TriggerOidIndexId, + Anum_pg_trigger_oid); /* * If trigger is internally generated, modify the provided trigger name to @@ -829,6 +846,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, */ memset(nulls, false, sizeof(nulls)); + values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid); values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel)); values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein, CStringGetDatum(trigname)); @@ -945,16 +963,13 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, tuple = heap_form_tuple(tgrel->rd_att, values, nulls); - /* force tuple to have the desired OID */ - HeapTupleSetOid(tuple, trigoid); - /* * Insert tuple into pg_trigger. */ CatalogTupleInsert(tgrel, tuple); heap_freetuple(tuple); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); pfree(DatumGetPointer(values[Anum_pg_trigger_tgname - 1])); pfree(DatumGetPointer(values[Anum_pg_trigger_tgargs - 1])); @@ -968,7 +983,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * Update relation's pg_class entry; if necessary; and if not, send an SI * message to make other backends (and this one) rebuild relcache entries. */ - pgrel = heap_open(RelationRelationId, RowExclusiveLock); + pgrel = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(rel))); if (!HeapTupleIsValid(tuple)) @@ -986,7 +1001,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, CacheInvalidateRelcacheByTuple(tuple); heap_freetuple(tuple); - heap_close(pgrel, RowExclusiveLock); + table_close(pgrel, RowExclusiveLock); /* * Record dependencies for trigger. Always place a normal dependency on @@ -1020,17 +1035,11 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * User CREATE TRIGGER, so place dependencies. We make trigger be * auto-dropped if its relation is dropped or if the FK relation is * dropped. (Auto drop is compatible with our pre-7.3 behavior.) - * - * Exception: if this trigger comes from a parent partitioned table, - * then it's not separately drop-able, but goes away if the partition - * does. */ referenced.classId = RelationRelationId; referenced.objectId = RelationGetRelid(rel); referenced.objectSubId = 0; - recordDependencyOn(&myself, &referenced, OidIsValid(parentTriggerOid) ? - DEPENDENCY_INTERNAL_AUTO : - DEPENDENCY_AUTO); + recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO); if (OidIsValid(constrrelid)) { @@ -1054,11 +1063,15 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, recordDependencyOn(&referenced, &myself, DEPENDENCY_INTERNAL); } - /* Depends on the parent trigger, if there is one. */ + /* + * If it's a partition trigger, create the partition dependencies. + */ if (OidIsValid(parentTriggerOid)) { ObjectAddressSet(referenced, TriggerRelationId, parentTriggerOid); - recordDependencyOn(&myself, &referenced, DEPENDENCY_INTERNAL_AUTO); + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_PRI); + ObjectAddressSet(referenced, RelationRelationId, RelationGetRelid(rel)); + recordDependencyOn(&myself, &referenced, DEPENDENCY_PARTITION_SEC); } } @@ -1134,7 +1147,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Node *qual; bool found_whole_row; - childTbl = heap_open(partdesc->oids[i], ShareRowExclusiveLock); + childTbl = table_open(partdesc->oids[i], ShareRowExclusiveLock); /* Find which of the child indexes is the one on this partition */ if (OidIsValid(indexOid)) @@ -1159,7 +1172,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, */ childStmt = (CreateTrigStmt *) copyObject(stmt); childStmt->funcname = NIL; - childStmt->args = NIL; childStmt->whenClause = NULL; /* If there is a WHEN clause, create a modified copy of it */ @@ -1183,7 +1195,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, funcoid, trigoid, qual, isInternal, true); - heap_close(childTbl, NoLock); + table_close(childTbl, NoLock); MemoryContextReset(perChildCxt); } @@ -1195,7 +1207,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, } /* Keep lock on target rel until end of xact */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return myself; } @@ -1493,13 +1505,13 @@ RemoveTriggerById(Oid trigOid) Oid relid; Relation rel; - tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); /* * Find the trigger to delete. */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_trigger_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigOid)); @@ -1515,7 +1527,7 @@ RemoveTriggerById(Oid trigOid) */ relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid; - rel = heap_open(relid, AccessExclusiveLock); + rel = table_open(relid, AccessExclusiveLock); if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_VIEW && @@ -1538,7 +1550,7 @@ RemoveTriggerById(Oid trigOid) CatalogTupleDelete(tgrel, &tup->t_self); systable_endscan(tgscan); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); /* * We do not bother to try to determine whether any other triggers remain, @@ -1552,7 +1564,7 @@ RemoveTriggerById(Oid trigOid) CacheInvalidateRelcache(rel); /* Keep lock on trigger's rel until end of xact */ - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* @@ -1573,7 +1585,7 @@ get_trigger_oid(Oid relid, const char *trigname, bool missing_ok) /* * Find the trigger, verify permissions, set up object address */ - tgrel = heap_open(TriggerRelationId, AccessShareLock); + tgrel = table_open(TriggerRelationId, AccessShareLock); ScanKeyInit(&skey[0], Anum_pg_trigger_tgrelid, @@ -1600,11 +1612,11 @@ get_trigger_oid(Oid relid, const char *trigname, bool missing_ok) } else { - oid = HeapTupleGetOid(tup); + oid = ((Form_pg_trigger) GETSTRUCT(tup))->oid; } systable_endscan(tgscan); - heap_close(tgrel, AccessShareLock); + table_close(tgrel, AccessShareLock); return oid; } @@ -1690,7 +1702,7 @@ renametrig(RenameStmt *stmt) * NOTE that this is cool only because we have AccessExclusiveLock on the * relation, so the trigger set won't be changing underneath us. */ - tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); /* * First pass -- look for name conflict @@ -1727,20 +1739,22 @@ renametrig(RenameStmt *stmt) NULL, 2, key); if (HeapTupleIsValid(tuple = systable_getnext(tgscan))) { - tgoid = HeapTupleGetOid(tuple); + Form_pg_trigger trigform; /* * Update pg_trigger tuple with new tgname. */ tuple = heap_copytuple(tuple); /* need a modifiable copy */ + trigform = (Form_pg_trigger) GETSTRUCT(tuple); + tgoid = trigform->oid; - namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname, + namestrcpy(&trigform->tgname, stmt->newname); CatalogTupleUpdate(tgrel, &tuple->t_self, tuple); InvokeObjectPostAlterHook(TriggerRelationId, - HeapTupleGetOid(tuple), 0); + tgoid, 0); /* * Invalidate relation's relcache entry so that other backends (and @@ -1761,7 +1775,7 @@ renametrig(RenameStmt *stmt) systable_endscan(tgscan); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); /* * Close rel, but keep exclusive lock! @@ -1802,7 +1816,7 @@ EnableDisableTrigger(Relation rel, const char *tgname, bool changed; /* Scan the relevant entries in pg_triggers */ - tgrel = heap_open(TriggerRelationId, RowExclusiveLock); + tgrel = table_open(TriggerRelationId, RowExclusiveLock); ScanKeyInit(&keys[0], Anum_pg_trigger_tgrelid, @@ -1871,7 +1885,7 @@ EnableDisableTrigger(Relation rel, const char *tgname, part = relation_open(partdesc->oids[i], lockmode); EnableDisableTrigger(part, NameStr(oldtrig->tgname), fires_when, skip_system, lockmode); - heap_close(part, NoLock); /* keep lock till commit */ + table_close(part, NoLock); /* keep lock till commit */ } } @@ -1879,12 +1893,12 @@ EnableDisableTrigger(Relation rel, const char *tgname, } InvokeObjectPostAlterHook(TriggerRelationId, - HeapTupleGetOid(tuple), 0); + oldtrig->oid, 0); } systable_endscan(tgscan); - heap_close(tgrel, RowExclusiveLock); + table_close(tgrel, RowExclusiveLock); if (tgname && !found) ereport(ERROR, @@ -1945,7 +1959,7 @@ RelationBuildTriggers(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - tgrel = heap_open(TriggerRelationId, AccessShareLock); + tgrel = table_open(TriggerRelationId, AccessShareLock); tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, NULL, 1, &skey); @@ -1963,7 +1977,7 @@ RelationBuildTriggers(Relation relation) } build = &(triggers[numtrigs]); - build->tgoid = HeapTupleGetOid(htup); + build->tgoid = pg_trigger->oid; build->tgname = DatumGetCString(DirectFunctionCall1(nameout, NameGetDatum(&pg_trigger->tgname))); build->tgfoid = pg_trigger->tgfoid; @@ -2035,7 +2049,7 @@ RelationBuildTriggers(Relation relation) } systable_endscan(tgscan); - heap_close(tgrel, AccessShareLock); + table_close(tgrel, AccessShareLock); /* There might not be any triggers */ if (numtrigs == 0) @@ -2362,7 +2376,7 @@ ExecCallTriggerFunc(TriggerData *trigdata, Instrumentation *instr, MemoryContext per_tuple_context) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 0); PgStat_FunctionCallUsage fcusage; Datum result; MemoryContext oldContext; @@ -2407,15 +2421,15 @@ ExecCallTriggerFunc(TriggerData *trigdata, /* * Call the function, passing no arguments but setting a context. */ - InitFunctionCallInfoData(fcinfo, finfo, 0, + InitFunctionCallInfoData(*fcinfo, finfo, 0, InvalidOid, (Node *) trigdata, NULL); - pgstat_init_function_usage(&fcinfo, &fcusage); + pgstat_init_function_usage(fcinfo, &fcusage); MyTriggerDepth++; PG_TRY(); { - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); } PG_CATCH(); { @@ -2433,11 +2447,11 @@ ExecCallTriggerFunc(TriggerData *trigdata, * Trigger protocol allows function to return a null pointer, but NOT to * set the isnull result flag. */ - if (fcinfo.isnull) + if (fcinfo->isnull) ereport(ERROR, (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), errmsg("trigger function %u returned null value", - fcinfo.flinfo->fn_oid))); + fcinfo->flinfo->fn_oid))); /* * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count @@ -2474,10 +2488,10 @@ ExecBSInsertTriggers(EState *estate, ResultRelInfo *relinfo) LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; @@ -2517,14 +2531,13 @@ ExecASInsertTriggers(EState *estate, ResultRelInfo *relinfo, false, NULL, NULL, NIL, NULL, transition_capture); } -TupleTableSlot * +bool ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - HeapTuple slottuple = ExecMaterializeSlot(slot); - HeapTuple newtuple = slottuple; - HeapTuple oldtuple; + HeapTuple newtuple = false; + bool should_free; TriggerData LocTriggerData; int i; @@ -2533,13 +2546,16 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE; LocTriggerData.tg_relation = relinfo->ri_RelationDesc; + LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; + HeapTuple oldtuple; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, TRIGGER_TYPE_ROW, @@ -2547,45 +2563,44 @@ ExecBRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_TYPE_INSERT)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - NULL, NULL, newtuple)) + NULL, NULL, slot)) continue; + if (!newtuple) + newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free); + + LocTriggerData.tg_trigslot = slot; LocTriggerData.tg_trigtuple = oldtuple = newtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; LocTriggerData.tg_trigger = trigger; newtuple = ExecCallTriggerFunc(&LocTriggerData, i, relinfo->ri_TrigFunctions, relinfo->ri_TrigInstrument, GetPerTupleMemoryContext(estate)); - if (oldtuple != newtuple && oldtuple != slottuple) - heap_freetuple(oldtuple); if (newtuple == NULL) - return NULL; /* "do nothing" */ - } + { + if (should_free) + heap_freetuple(oldtuple); + return false; /* "do nothing" */ + } + else if (newtuple != oldtuple) + { + ExecForceStoreHeapTuple(newtuple, slot, false); - if (newtuple != slottuple) - { - /* - * Return the modified tuple using the es_trig_tuple_slot. We assume - * the tuple was allocated in per-tuple memory context, and therefore - * will go away by itself. The tuple table slot should not try to - * clear it. - */ - TupleTableSlot *newslot = estate->es_trig_tuple_slot; - TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc); + if (should_free) + heap_freetuple(oldtuple); - if (newslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(newslot, tupdesc); - ExecStoreTuple(newtuple, newslot, InvalidBuffer, false); - slot = newslot; + /* signal tuple should be re-fetched if used */ + newtuple = NULL; + } } - return slot; + + return true; } void ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, - HeapTuple trigtuple, List *recheckIndexes, + TupleTableSlot *slot, List *recheckIndexes, TransitionCaptureState *transition_capture) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; @@ -2593,19 +2608,18 @@ ExecARInsertTriggers(EState *estate, ResultRelInfo *relinfo, if ((trigdesc && trigdesc->trig_insert_after_row) || (transition_capture && transition_capture->tcs_insert_new_table)) AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_INSERT, - true, NULL, trigtuple, + true, NULL, slot, recheckIndexes, NULL, transition_capture); } -TupleTableSlot * +bool ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TupleTableSlot *slot) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - HeapTuple slottuple = ExecMaterializeSlot(slot); - HeapTuple newtuple = slottuple; - HeapTuple oldtuple; + HeapTuple newtuple = NULL; + bool should_free; TriggerData LocTriggerData; int i; @@ -2614,13 +2628,16 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_EVENT_ROW | TRIGGER_EVENT_INSTEAD; LocTriggerData.tg_relation = relinfo->ri_RelationDesc; + LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; + HeapTuple oldtuple; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, TRIGGER_TYPE_ROW, @@ -2628,40 +2645,39 @@ ExecIRInsertTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_TYPE_INSERT)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - NULL, NULL, newtuple)) + NULL, NULL, slot)) continue; + if (!newtuple) + newtuple = ExecFetchSlotHeapTuple(slot, true, &should_free); + + LocTriggerData.tg_trigslot = slot; LocTriggerData.tg_trigtuple = oldtuple = newtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; LocTriggerData.tg_trigger = trigger; newtuple = ExecCallTriggerFunc(&LocTriggerData, i, relinfo->ri_TrigFunctions, relinfo->ri_TrigInstrument, GetPerTupleMemoryContext(estate)); - if (oldtuple != newtuple && oldtuple != slottuple) - heap_freetuple(oldtuple); if (newtuple == NULL) - return NULL; /* "do nothing" */ - } + { + if (should_free) + heap_freetuple(oldtuple); + return false; /* "do nothing" */ + } + else if (newtuple != oldtuple) + { + ExecForceStoreHeapTuple(newtuple, slot, false); - if (newtuple != slottuple) - { - /* - * Return the modified tuple using the es_trig_tuple_slot. We assume - * the tuple was allocated in per-tuple memory context, and therefore - * will go away by itself. The tuple table slot should not try to - * clear it. - */ - TupleTableSlot *newslot = estate->es_trig_tuple_slot; - TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc); + if (should_free) + heap_freetuple(oldtuple); - if (newslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(newslot, tupdesc); - ExecStoreTuple(newtuple, newslot, InvalidBuffer, false); - slot = newslot; + /* signal tuple should be re-fetched if used */ + newtuple = NULL; + } } - return slot; + + return true; } void @@ -2689,10 +2705,10 @@ ExecBSDeleteTriggers(EState *estate, ResultRelInfo *relinfo) LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; @@ -2732,43 +2748,71 @@ ExecASDeleteTriggers(EState *estate, ResultRelInfo *relinfo, false, NULL, NULL, NIL, NULL, transition_capture); } +/* + * Execute BEFORE ROW DELETE triggers. + * + * True indicates caller can proceed with the delete. False indicates caller + * need to suppress the delete and additionally if requested, we need to pass + * back the concurrently updated tuple if any. + */ bool ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, - HeapUpdateFailureData *hufdp) + TupleTableSlot **epqslot) { + TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); TriggerDesc *trigdesc = relinfo->ri_TrigDesc; bool result = true; TriggerData LocTriggerData; HeapTuple trigtuple; - HeapTuple newtuple; - TupleTableSlot *newSlot; + bool should_free = false; int i; Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid)); if (fdw_trigtuple == NULL) { - trigtuple = GetTupleForTrigger(estate, epqstate, relinfo, tupleid, - LockTupleExclusive, &newSlot, hufdp); - if (trigtuple == NULL) + TupleTableSlot *newSlot; + + if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid, + LockTupleExclusive, slot, &newSlot)) return false; + + /* + * If the tuple was concurrently updated and the caller of this + * function requested for the updated tuple, skip the trigger + * execution. + */ + if (newSlot != NULL && epqslot != NULL) + { + *epqslot = newSlot; + return false; + } + + trigtuple = ExecFetchSlotHeapTuple(slot, true, &should_free); + } else + { trigtuple = fdw_trigtuple; + ExecForceStoreHeapTuple(trigtuple, slot, false); + } LocTriggerData.type = T_TriggerData; LocTriggerData.tg_event = TRIGGER_EVENT_DELETE | TRIGGER_EVENT_ROW | TRIGGER_EVENT_BEFORE; LocTriggerData.tg_relation = relinfo->ri_RelationDesc; + LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { + HeapTuple newtuple; Trigger *trigger = &trigdesc->triggers[i]; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, @@ -2777,11 +2821,11 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, TRIGGER_TYPE_DELETE)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - NULL, trigtuple, NULL)) + NULL, slot, NULL)) continue; + LocTriggerData.tg_trigslot = slot; LocTriggerData.tg_trigtuple = trigtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; LocTriggerData.tg_trigger = trigger; newtuple = ExecCallTriggerFunc(&LocTriggerData, i, @@ -2796,7 +2840,7 @@ ExecBRDeleteTriggers(EState *estate, EPQState *epqstate, if (newtuple != trigtuple) heap_freetuple(newtuple); } - if (trigtuple != fdw_trigtuple) + if (should_free) heap_freetuple(trigtuple); return result; @@ -2809,29 +2853,26 @@ ExecARDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TransitionCaptureState *transition_capture) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; + TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); if ((trigdesc && trigdesc->trig_delete_after_row) || (transition_capture && transition_capture->tcs_delete_old_table)) { - HeapTuple trigtuple; - Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid)); if (fdw_trigtuple == NULL) - trigtuple = GetTupleForTrigger(estate, - NULL, - relinfo, - tupleid, - LockTupleExclusive, - NULL, - NULL); + GetTupleForTrigger(estate, + NULL, + relinfo, + tupleid, + LockTupleExclusive, + slot, + NULL); else - trigtuple = fdw_trigtuple; + ExecForceStoreHeapTuple(fdw_trigtuple, slot, false); AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_DELETE, - true, trigtuple, NULL, NIL, NULL, + true, slot, NULL, NIL, NULL, transition_capture); - if (trigtuple != fdw_trigtuple) - heap_freetuple(trigtuple); } } @@ -2840,8 +2881,8 @@ ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, HeapTuple trigtuple) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; + TupleTableSlot *slot = ExecGetTriggerOldSlot(estate, relinfo); TriggerData LocTriggerData; - HeapTuple rettuple; int i; LocTriggerData.type = T_TriggerData; @@ -2849,12 +2890,18 @@ ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_EVENT_ROW | TRIGGER_EVENT_INSTEAD; LocTriggerData.tg_relation = relinfo->ri_RelationDesc; + LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; + + ExecForceStoreHeapTuple(trigtuple, slot, false); + for (i = 0; i < trigdesc->numtriggers; i++) { + HeapTuple rettuple; Trigger *trigger = &trigdesc->triggers[i]; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, @@ -2863,11 +2910,11 @@ ExecIRDeleteTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_TYPE_DELETE)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - NULL, trigtuple, NULL)) + NULL, slot, NULL)) continue; + LocTriggerData.tg_trigslot = slot; LocTriggerData.tg_trigtuple = trigtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; LocTriggerData.tg_trigger = trigger; rettuple = ExecCallTriggerFunc(&LocTriggerData, i, @@ -2902,7 +2949,7 @@ ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo) CMD_UPDATE)) return; - updatedCols = GetUpdatedColumns(relinfo, estate); + updatedCols = GetAllUpdatedColumns(relinfo, estate); LocTriggerData.type = T_TriggerData; LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE | @@ -2910,10 +2957,10 @@ ExecBSUpdateTriggers(EState *estate, ResultRelInfo *relinfo) LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; @@ -2951,25 +2998,24 @@ ExecASUpdateTriggers(EState *estate, ResultRelInfo *relinfo, if (trigdesc && trigdesc->trig_update_after_statement) AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE, false, NULL, NULL, NIL, - GetUpdatedColumns(relinfo, estate), + GetAllUpdatedColumns(relinfo, estate), transition_capture); } -TupleTableSlot * +bool ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, - TupleTableSlot *slot, - HeapUpdateFailureData *hufdp) + TupleTableSlot *newslot) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - HeapTuple slottuple = ExecMaterializeSlot(slot); - HeapTuple newtuple = slottuple; - TriggerData LocTriggerData; + TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo); + HeapTuple newtuple = NULL; HeapTuple trigtuple; - HeapTuple oldtuple; - TupleTableSlot *newSlot; + bool should_free_trig = false; + bool should_free_new = false; + TriggerData LocTriggerData; int i; Bitmapset *updatedCols; LockTupleMode lockmode; @@ -2980,37 +3026,40 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, Assert(HeapTupleIsValid(fdw_trigtuple) ^ ItemPointerIsValid(tupleid)); if (fdw_trigtuple == NULL) { + TupleTableSlot *newSlot = NULL; + /* get a copy of the on-disk tuple we are planning to update */ - trigtuple = GetTupleForTrigger(estate, epqstate, relinfo, tupleid, - lockmode, &newSlot, hufdp); - if (trigtuple == NULL) - return NULL; /* cancel the update action */ + if (!GetTupleForTrigger(estate, epqstate, relinfo, tupleid, + lockmode, oldslot, &newSlot)) + return false; /* cancel the update action */ + + /* + * In READ COMMITTED isolation level it's possible that target tuple + * was changed due to concurrent update. In that case we have a raw + * subplan output tuple in newSlot, and need to run it through the + * junk filter to produce an insertable tuple. + * + * Caution: more than likely, the passed-in slot is the same as the + * junkfilter's output slot, so we are clobbering the original value + * of slottuple by doing the filtering. This is OK since neither we + * nor our caller have any more interest in the prior contents of that + * slot. + */ + if (newSlot != NULL) + { + TupleTableSlot *slot = ExecFilterJunk(relinfo->ri_junkFilter, newSlot); + + ExecCopySlot(newslot, slot); + } + + trigtuple = ExecFetchSlotHeapTuple(oldslot, true, &should_free_trig); } else { + ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false); trigtuple = fdw_trigtuple; - newSlot = NULL; - } - - /* - * In READ COMMITTED isolation level it's possible that target tuple was - * changed due to concurrent update. In that case we have a raw subplan - * output tuple in newSlot, and need to run it through the junk filter to - * produce an insertable tuple. - * - * Caution: more than likely, the passed-in slot is the same as the - * junkfilter's output slot, so we are clobbering the original value of - * slottuple by doing the filtering. This is OK since neither we nor our - * caller have any more interest in the prior contents of that slot. - */ - if (newSlot != NULL) - { - slot = ExecFilterJunk(relinfo->ri_junkFilter, newSlot); - slottuple = ExecMaterializeSlot(slot); - newtuple = slottuple; } - LocTriggerData.type = T_TriggerData; LocTriggerData.tg_event = TRIGGER_EVENT_UPDATE | TRIGGER_EVENT_ROW | @@ -3018,10 +3067,11 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - updatedCols = GetUpdatedColumns(relinfo, estate); + updatedCols = GetAllUpdatedColumns(relinfo, estate); for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; + HeapTuple oldtuple; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, TRIGGER_TYPE_ROW, @@ -3029,67 +3079,75 @@ ExecBRUpdateTriggers(EState *estate, EPQState *epqstate, TRIGGER_TYPE_UPDATE)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - updatedCols, trigtuple, newtuple)) + updatedCols, oldslot, newslot)) continue; + if (!newtuple) + newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free_new); + + LocTriggerData.tg_trigslot = oldslot; LocTriggerData.tg_trigtuple = trigtuple; LocTriggerData.tg_newtuple = oldtuple = newtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; + LocTriggerData.tg_newslot = newslot; LocTriggerData.tg_trigger = trigger; newtuple = ExecCallTriggerFunc(&LocTriggerData, i, relinfo->ri_TrigFunctions, relinfo->ri_TrigInstrument, GetPerTupleMemoryContext(estate)); - if (oldtuple != newtuple && oldtuple != slottuple) - heap_freetuple(oldtuple); + if (newtuple == NULL) { - if (trigtuple != fdw_trigtuple) + if (should_free_trig) heap_freetuple(trigtuple); - return NULL; /* "do nothing" */ + if (should_free_new) + heap_freetuple(oldtuple); + return false; /* "do nothing" */ } - } - if (trigtuple != fdw_trigtuple && trigtuple != newtuple) - heap_freetuple(trigtuple); + else if (newtuple != oldtuple) + { + ExecForceStoreHeapTuple(newtuple, newslot, false); - if (newtuple != slottuple) - { - /* - * Return the modified tuple using the es_trig_tuple_slot. We assume - * the tuple was allocated in per-tuple memory context, and therefore - * will go away by itself. The tuple table slot should not try to - * clear it. - */ - TupleTableSlot *newslot = estate->es_trig_tuple_slot; - TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc); + /* + * If the tuple returned by the trigger / being stored, is the old + * row version, and the heap tuple passed to the trigger was + * allocated locally, materialize the slot. Otherwise we might + * free it while still referenced by the slot. + */ + if (should_free_trig && newtuple == trigtuple) + ExecMaterializeSlot(newslot); - if (newslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(newslot, tupdesc); - ExecStoreTuple(newtuple, newslot, InvalidBuffer, false); - slot = newslot; + if (should_free_new) + heap_freetuple(oldtuple); + + /* signal tuple should be re-fetched if used */ + newtuple = NULL; + } } - return slot; + if (should_free_trig) + heap_freetuple(trigtuple); + + return true; } void ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, ItemPointer tupleid, HeapTuple fdw_trigtuple, - HeapTuple newtuple, + TupleTableSlot *newslot, List *recheckIndexes, TransitionCaptureState *transition_capture) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; + TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo); + + ExecClearTuple(oldslot); if ((trigdesc && trigdesc->trig_update_after_row) || (transition_capture && (transition_capture->tcs_update_old_table || transition_capture->tcs_update_new_table))) { - HeapTuple trigtuple; - /* * Note: if the UPDATE is converted into a DELETE+INSERT as part of * update-partition-key operation, then this function is also called @@ -3097,34 +3155,32 @@ ExecARUpdateTriggers(EState *estate, ResultRelInfo *relinfo, * In such case, either old tuple or new tuple can be NULL. */ if (fdw_trigtuple == NULL && ItemPointerIsValid(tupleid)) - trigtuple = GetTupleForTrigger(estate, - NULL, - relinfo, - tupleid, - LockTupleExclusive, - NULL, - NULL); - else - trigtuple = fdw_trigtuple; + GetTupleForTrigger(estate, + NULL, + relinfo, + tupleid, + LockTupleExclusive, + oldslot, + NULL); + else if (fdw_trigtuple != NULL) + ExecForceStoreHeapTuple(fdw_trigtuple, oldslot, false); AfterTriggerSaveEvent(estate, relinfo, TRIGGER_EVENT_UPDATE, - true, trigtuple, newtuple, recheckIndexes, - GetUpdatedColumns(relinfo, estate), + true, oldslot, newslot, recheckIndexes, + GetAllUpdatedColumns(relinfo, estate), transition_capture); - if (trigtuple != fdw_trigtuple) - heap_freetuple(trigtuple); } } -TupleTableSlot * +bool ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, - HeapTuple trigtuple, TupleTableSlot *slot) + HeapTuple trigtuple, TupleTableSlot *newslot) { TriggerDesc *trigdesc = relinfo->ri_TrigDesc; - HeapTuple slottuple = ExecMaterializeSlot(slot); - HeapTuple newtuple = slottuple; + TupleTableSlot *oldslot = ExecGetTriggerOldSlot(estate, relinfo); + HeapTuple newtuple = false; + bool should_free; TriggerData LocTriggerData; - HeapTuple oldtuple; int i; LocTriggerData.type = T_TriggerData; @@ -3134,9 +3190,13 @@ ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; + + ExecForceStoreHeapTuple(trigtuple, oldslot, false); + for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; + HeapTuple oldtuple; if (!TRIGGER_TYPE_MATCHES(trigger->tgtype, TRIGGER_TYPE_ROW, @@ -3144,42 +3204,40 @@ ExecIRUpdateTriggers(EState *estate, ResultRelInfo *relinfo, TRIGGER_TYPE_UPDATE)) continue; if (!TriggerEnabled(estate, relinfo, trigger, LocTriggerData.tg_event, - NULL, trigtuple, newtuple)) + NULL, oldslot, newslot)) continue; + if (!newtuple) + newtuple = ExecFetchSlotHeapTuple(newslot, true, &should_free); + + LocTriggerData.tg_trigslot = oldslot; LocTriggerData.tg_trigtuple = trigtuple; + LocTriggerData.tg_newslot = newslot; LocTriggerData.tg_newtuple = oldtuple = newtuple; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; + LocTriggerData.tg_trigger = trigger; newtuple = ExecCallTriggerFunc(&LocTriggerData, i, relinfo->ri_TrigFunctions, relinfo->ri_TrigInstrument, GetPerTupleMemoryContext(estate)); - if (oldtuple != newtuple && oldtuple != slottuple) - heap_freetuple(oldtuple); if (newtuple == NULL) - return NULL; /* "do nothing" */ - } + { + return false; /* "do nothing" */ + } + else if (newtuple != oldtuple) + { + ExecForceStoreHeapTuple(newtuple, newslot, false); - if (newtuple != slottuple) - { - /* - * Return the modified tuple using the es_trig_tuple_slot. We assume - * the tuple was allocated in per-tuple memory context, and therefore - * will go away by itself. The tuple table slot should not try to - * clear it. - */ - TupleTableSlot *newslot = estate->es_trig_tuple_slot; - TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc); + if (should_free) + heap_freetuple(oldtuple); - if (newslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(newslot, tupdesc); - ExecStoreTuple(newtuple, newslot, InvalidBuffer, false); - slot = newslot; + /* signal tuple should be re-fetched if used */ + newtuple = NULL; + } } - return slot; + + return true; } void @@ -3202,10 +3260,11 @@ ExecBSTruncateTriggers(EState *estate, ResultRelInfo *relinfo) LocTriggerData.tg_relation = relinfo->ri_RelationDesc; LocTriggerData.tg_trigtuple = NULL; LocTriggerData.tg_newtuple = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; LocTriggerData.tg_oldtable = NULL; LocTriggerData.tg_newtable = NULL; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; + for (i = 0; i < trigdesc->numtriggers; i++) { Trigger *trigger = &trigdesc->triggers[i]; @@ -3245,24 +3304,22 @@ ExecASTruncateTriggers(EState *estate, ResultRelInfo *relinfo) } -static HeapTuple +static bool GetTupleForTrigger(EState *estate, EPQState *epqstate, ResultRelInfo *relinfo, ItemPointer tid, LockTupleMode lockmode, - TupleTableSlot **newSlot, - HeapUpdateFailureData *hufdp) + TupleTableSlot *oldslot, + TupleTableSlot **newSlot) { Relation relation = relinfo->ri_RelationDesc; - HeapTupleData tuple; - HeapTuple result; - Buffer buffer; if (newSlot != NULL) { - HTSU_Result test; - HeapUpdateFailureData hufd; + TM_Result test; + TM_FailureData tmfd; + int lockflags = 0; *newSlot = NULL; @@ -3272,20 +3329,17 @@ GetTupleForTrigger(EState *estate, /* * lock tuple for update */ -ltrmark:; - tuple.t_self = *tid; - test = heap_lock_tuple(relation, &tuple, - estate->es_output_cid, - lockmode, LockWaitBlock, - false, &buffer, &hufd); - - /* Let the caller know about failure reason, if any. */ - if (hufdp) - *hufdp = hufd; + if (!IsolationUsesXactSnapshot()) + lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION; + test = table_tuple_lock(relation, tid, estate->es_snapshot, oldslot, + estate->es_output_cid, + lockmode, LockWaitBlock, + lockflags, + &tmfd); switch (test) { - case HeapTupleSelfUpdated: + case TM_SelfModified: /* * The target tuple was already updated or deleted by the @@ -3295,113 +3349,73 @@ ltrmark:; * enumerated in ExecUpdate and ExecDelete in * nodeModifyTable.c. */ - if (hufd.cmax != estate->es_output_cid) + if (tmfd.cmax != estate->es_output_cid) ereport(ERROR, (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION), errmsg("tuple to be updated was already modified by an operation triggered by the current command"), errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows."))); /* treat it as deleted; do not process */ - ReleaseBuffer(buffer); - return NULL; + return false; + + case TM_Ok: + if (tmfd.traversed) + { + TupleTableSlot *epqslot; + + epqslot = EvalPlanQual(epqstate, + relation, + relinfo->ri_RangeTableIndex, + oldslot); - case HeapTupleMayBeUpdated: + /* + * If PlanQual failed for updated tuple - we must not + * process this tuple! + */ + if (TupIsNull(epqslot)) + return false; + + *newSlot = epqslot; + } break; - case HeapTupleUpdated: - ReleaseBuffer(buffer); + case TM_Updated: if (IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("could not serialize access due to concurrent update"))); - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) + elog(ERROR, "unexpected table_tuple_lock status: %u", test); + break; + + case TM_Deleted: + if (IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be locked was already moved to another partition due to concurrent update"))); - - if (!ItemPointerEquals(&hufd.ctid, &tuple.t_self)) - { - /* it was updated, so look at the updated version */ - TupleTableSlot *epqslot; - - /* - * If we're running MERGE then we must install the - * new tuple in the slot of the underlying join query and - * not the result relation itself. If the join does not - * yield any tuple, the caller will take the necessary - * action. - */ - epqslot = EvalPlanQual(estate, - epqstate, - relation, - GetEPQRangeTableIndex(relinfo), - lockmode, - &hufd.ctid, - hufd.xmax); - if (!TupIsNull(epqslot)) - { - *tid = hufd.ctid; - *newSlot = epqslot; - - /* - * EvalPlanQual already locked the tuple, but we - * re-call heap_lock_tuple anyway as an easy way of - * re-fetching the correct tuple. Speed is hardly a - * criterion in this path anyhow. - */ - goto ltrmark; - } - } - - /* - * if tuple was deleted or PlanQual failed for updated tuple - - * we must not process this tuple! - */ - return NULL; + errmsg("could not serialize access due to concurrent delete"))); + /* tuple was deleted */ + return false; - case HeapTupleInvisible: + case TM_Invisible: elog(ERROR, "attempted to lock invisible tuple"); + break; default: - ReleaseBuffer(buffer); - elog(ERROR, "unrecognized heap_lock_tuple status: %u", test); - return NULL; /* keep compiler quiet */ + elog(ERROR, "unrecognized table_tuple_lock status: %u", test); + return false; /* keep compiler quiet */ } } else { - Page page; - ItemId lp; - - buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid)); - /* - * Although we already know this tuple is valid, we must lock the - * buffer to ensure that no one has a buffer cleanup lock; otherwise - * they might move the tuple while we try to copy it. But we can - * release the lock before actually doing the heap_copytuple call, - * since holding pin is sufficient to prevent anyone from getting a - * cleanup lock they don't already hold. + * We expect the tuple to be present, thus very simple error handling + * suffices. */ - LockBuffer(buffer, BUFFER_LOCK_SHARE); - - page = BufferGetPage(buffer); - lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid)); - - Assert(ItemIdIsNormal(lp)); - - tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp); - tuple.t_len = ItemIdGetLength(lp); - tuple.t_self = *tid; - tuple.t_tableOid = RelationGetRelid(relation); - - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); + if (!table_tuple_fetch_row_version(relation, tid, SnapshotAny, + oldslot)) + elog(ERROR, "failed to fetch tuple for trigger"); } - result = heap_copytuple(&tuple); - ReleaseBuffer(buffer); - - return result; + return true; } /* @@ -3411,7 +3425,7 @@ static bool TriggerEnabled(EState *estate, ResultRelInfo *relinfo, Trigger *trigger, TriggerEvent event, Bitmapset *modifiedCols, - HeapTuple oldtup, HeapTuple newtup) + TupleTableSlot *oldslot, TupleTableSlot *newslot) { /* Check replication-role-dependent enable state */ if (SessionReplicationRole == SESSION_REPLICATION_ROLE_REPLICA) @@ -3453,11 +3467,8 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo, /* Check for WHEN clause */ if (trigger->tgqual) { - TupleDesc tupdesc = RelationGetDescr(relinfo->ri_RelationDesc); ExprState **predicate; ExprContext *econtext; - TupleTableSlot *oldslot = NULL; - TupleTableSlot *newslot = NULL; MemoryContext oldContext; int i; @@ -3496,40 +3507,6 @@ TriggerEnabled(EState *estate, ResultRelInfo *relinfo, */ econtext = GetPerTupleExprContext(estate); - /* - * Put OLD and NEW tuples into tupleslots for expression evaluation. - * These slots can be shared across the whole estate, but be careful - * that they have the current resultrel's tupdesc. - */ - if (HeapTupleIsValid(oldtup)) - { - if (estate->es_trig_oldtup_slot == NULL) - { - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); - estate->es_trig_oldtup_slot = - ExecInitExtraTupleSlot(estate, NULL); - MemoryContextSwitchTo(oldContext); - } - oldslot = estate->es_trig_oldtup_slot; - if (oldslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(oldslot, tupdesc); - ExecStoreTuple(oldtup, oldslot, InvalidBuffer, false); - } - if (HeapTupleIsValid(newtup)) - { - if (estate->es_trig_newtup_slot == NULL) - { - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); - estate->es_trig_newtup_slot = - ExecInitExtraTupleSlot(estate, NULL); - MemoryContextSwitchTo(oldContext); - } - newslot = estate->es_trig_newtup_slot; - if (newslot->tts_tupleDescriptor != tupdesc) - ExecSetSlotDescriptor(newslot, tupdesc); - ExecStoreTuple(newtup, newslot, InvalidBuffer, false); - } - /* * Finally evaluate the expression, making the old and/or new tuples * available as INNER_VAR/OUTER_VAR respectively. @@ -3857,40 +3834,29 @@ struct AfterTriggersTableData bool before_trig_done; /* did we already queue BS triggers? */ bool after_trig_done; /* did we already queue AS triggers? */ AfterTriggerEventList after_trig_events; /* if so, saved list pointer */ - - /* - * We maintain separate transaction tables for UPDATE/INSERT/DELETE since - * MERGE can run all three actions in a single statement. Note that UPDATE - * needs both old and new transition tables whereas INSERT needs only new - * and DELETE needs only old. - */ - - /* "old" transition table for UPDATE, if any */ - Tuplestorestate *old_upd_tuplestore; - /* "new" transition table for UPDATE, if any */ - Tuplestorestate *new_upd_tuplestore; - /* "old" transition table for DELETE, if any */ - Tuplestorestate *old_del_tuplestore; - /* "new" transition table INSERT, if any */ - Tuplestorestate *new_ins_tuplestore; + Tuplestorestate *old_tuplestore; /* "old" transition table, if any */ + Tuplestorestate *new_tuplestore; /* "new" transition table, if any */ + TupleTableSlot *storeslot; /* for converting to tuplestore's format */ }; static AfterTriggersData afterTriggers; -static void AfterTriggerExecute(AfterTriggerEvent event, - Relation rel, TriggerDesc *trigdesc, - FmgrInfo *finfo, - Instrumentation *instr, - MemoryContext per_tuple_context, - TupleTableSlot *trig_tuple_slot1, - TupleTableSlot *trig_tuple_slot2); +static void AfterTriggerExecute(EState *estate, + AfterTriggerEvent event, + ResultRelInfo *relInfo, + TriggerDesc *trigdesc, + FmgrInfo *finfo, + Instrumentation *instr, + MemoryContext per_tuple_context, + TupleTableSlot *trig_tuple_slot1, + TupleTableSlot *trig_tuple_slot2); static AfterTriggersTableData *GetAfterTriggersTableData(Oid relid, - CmdType cmdType); + CmdType cmdType); static void AfterTriggerFreeQuery(AfterTriggersQueryData *qs); static SetConstraintState SetConstraintStateCreate(int numalloc); static SetConstraintState SetConstraintStateCopy(SetConstraintState state); static SetConstraintState SetConstraintStateAddItem(SetConstraintState state, - Oid tgoid, bool tgisdeferred); + Oid tgoid, bool tgisdeferred); static void cancel_prior_stmt_triggers(Oid relid, CmdType cmdType, int tgevent); @@ -4212,27 +4178,31 @@ afterTriggerDeleteHeadEventChunk(AfterTriggersQueryData *qs) * ---------- */ static void -AfterTriggerExecute(AfterTriggerEvent event, - Relation rel, TriggerDesc *trigdesc, +AfterTriggerExecute(EState *estate, + AfterTriggerEvent event, + ResultRelInfo *relInfo, + TriggerDesc *trigdesc, FmgrInfo *finfo, Instrumentation *instr, MemoryContext per_tuple_context, TupleTableSlot *trig_tuple_slot1, TupleTableSlot *trig_tuple_slot2) { + Relation rel = relInfo->ri_RelationDesc; AfterTriggerShared evtshared = GetTriggerSharedData(event); Oid tgoid = evtshared->ats_tgoid; TriggerData LocTriggerData; - HeapTupleData tuple1; - HeapTupleData tuple2; HeapTuple rettuple; - Buffer buffer1 = InvalidBuffer; - Buffer buffer2 = InvalidBuffer; int tgindx; + bool should_free_trig = false; + bool should_free_new = false; /* * Locate trigger in trigdesc. */ LocTriggerData.tg_trigger = NULL; + LocTriggerData.tg_trigslot = NULL; + LocTriggerData.tg_newslot = NULL; + for (tgindx = 0; tgindx < trigdesc->numtriggers; tgindx++) { if (trigdesc->triggers[tgindx].tgoid == tgoid) @@ -4274,39 +4244,41 @@ AfterTriggerExecute(AfterTriggerEvent event, case AFTER_TRIGGER_FDW_REUSE: /* - * Using ExecMaterializeSlot() rather than ExecFetchSlotTuple() - * ensures that tg_trigtuple does not reference tuplestore memory. - * (It is formally possible for the trigger function to queue - * trigger events that add to the same tuplestore, which can push - * other tuples out of memory.) The distinction is academic, - * because we start with a minimal tuple that ExecFetchSlotTuple() - * must materialize anyway. + * Store tuple in the slot so that tg_trigtuple does not reference + * tuplestore memory. (It is formally possible for the trigger + * function to queue trigger events that add to the same + * tuplestore, which can push other tuples out of memory.) The + * distinction is academic, because we start with a minimal tuple + * that is stored as a heap tuple, constructed in different memory + * context, in the slot anyway. */ + LocTriggerData.tg_trigslot = trig_tuple_slot1; LocTriggerData.tg_trigtuple = - ExecMaterializeSlot(trig_tuple_slot1); - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; + ExecFetchSlotHeapTuple(trig_tuple_slot1, true, &should_free_trig); + LocTriggerData.tg_newslot = trig_tuple_slot2; LocTriggerData.tg_newtuple = ((evtshared->ats_event & TRIGGER_EVENT_OPMASK) == TRIGGER_EVENT_UPDATE) ? - ExecMaterializeSlot(trig_tuple_slot2) : NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; + ExecFetchSlotHeapTuple(trig_tuple_slot2, true, &should_free_new) : NULL; break; default: if (ItemPointerIsValid(&(event->ate_ctid1))) { - ItemPointerCopy(&(event->ate_ctid1), &(tuple1.t_self)); - if (!heap_fetch(rel, SnapshotAny, &tuple1, &buffer1, false, NULL)) + LocTriggerData.tg_trigslot = ExecGetTriggerOldSlot(estate, relInfo); + + if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid1), + SnapshotAny, + LocTriggerData.tg_trigslot)) elog(ERROR, "failed to fetch tuple1 for AFTER trigger"); - LocTriggerData.tg_trigtuple = &tuple1; - LocTriggerData.tg_trigtuplebuf = buffer1; + LocTriggerData.tg_trigtuple = + ExecFetchSlotHeapTuple(LocTriggerData.tg_trigslot, false, &should_free_trig); } else { LocTriggerData.tg_trigtuple = NULL; - LocTriggerData.tg_trigtuplebuf = InvalidBuffer; } /* don't touch ctid2 if not there */ @@ -4314,16 +4286,18 @@ AfterTriggerExecute(AfterTriggerEvent event, AFTER_TRIGGER_2CTID && ItemPointerIsValid(&(event->ate_ctid2))) { - ItemPointerCopy(&(event->ate_ctid2), &(tuple2.t_self)); - if (!heap_fetch(rel, SnapshotAny, &tuple2, &buffer2, false, NULL)) + LocTriggerData.tg_newslot = ExecGetTriggerNewSlot(estate, relInfo); + + if (!table_tuple_fetch_row_version(rel, &(event->ate_ctid2), + SnapshotAny, + LocTriggerData.tg_newslot)) elog(ERROR, "failed to fetch tuple2 for AFTER trigger"); - LocTriggerData.tg_newtuple = &tuple2; - LocTriggerData.tg_newtuplebuf = buffer2; + LocTriggerData.tg_newtuple = + ExecFetchSlotHeapTuple(LocTriggerData.tg_newslot, false, &should_free_new); } else { LocTriggerData.tg_newtuple = NULL; - LocTriggerData.tg_newtuplebuf = InvalidBuffer; } } @@ -4339,19 +4313,13 @@ AfterTriggerExecute(AfterTriggerEvent event, { if (LocTriggerData.tg_trigger->tgoldtable) { - if (TRIGGER_FIRED_BY_UPDATE(evtshared->ats_event)) - LocTriggerData.tg_oldtable = evtshared->ats_table->old_upd_tuplestore; - else - LocTriggerData.tg_oldtable = evtshared->ats_table->old_del_tuplestore; + LocTriggerData.tg_oldtable = evtshared->ats_table->old_tuplestore; evtshared->ats_table->closed = true; } if (LocTriggerData.tg_trigger->tgnewtable) { - if (TRIGGER_FIRED_BY_INSERT(evtshared->ats_event)) - LocTriggerData.tg_newtable = evtshared->ats_table->new_ins_tuplestore; - else - LocTriggerData.tg_newtable = evtshared->ats_table->new_upd_tuplestore; + LocTriggerData.tg_newtable = evtshared->ats_table->new_tuplestore; evtshared->ats_table->closed = true; } } @@ -4381,12 +4349,17 @@ AfterTriggerExecute(AfterTriggerEvent event, heap_freetuple(rettuple); /* - * Release buffers + * Release resources */ - if (buffer1 != InvalidBuffer) - ReleaseBuffer(buffer1); - if (buffer2 != InvalidBuffer) - ReleaseBuffer(buffer2); + if (should_free_trig) + heap_freetuple(LocTriggerData.tg_trigtuple); + if (should_free_new) + heap_freetuple(LocTriggerData.tg_newtuple); + + if (LocTriggerData.tg_trigslot) + ExecClearTuple(LocTriggerData.tg_trigslot); + if (LocTriggerData.tg_newslot) + ExecClearTuple(LocTriggerData.tg_newslot); /* * If doing EXPLAIN ANALYZE, stop charging time to this trigger, and count @@ -4493,6 +4466,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, AfterTriggerEventChunk *chunk; MemoryContext per_tuple_context; bool local_estate = false; + ResultRelInfo *rInfo = NULL; Relation rel = NULL; TriggerDesc *trigdesc = NULL; FmgrInfo *finfo = NULL; @@ -4534,8 +4508,6 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, */ if (rel == NULL || RelationGetRelid(rel) != evtshared->ats_relid) { - ResultRelInfo *rInfo; - rInfo = ExecGetTriggerResultRel(estate, evtshared->ats_relid); rel = rInfo->ri_RelationDesc; trigdesc = rInfo->ri_TrigDesc; @@ -4548,8 +4520,10 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, ExecDropSingleTupleTableSlot(slot1); ExecDropSingleTupleTableSlot(slot2); } - slot1 = MakeSingleTupleTableSlot(rel->rd_att); - slot2 = MakeSingleTupleTableSlot(rel->rd_att); + slot1 = MakeSingleTupleTableSlot(rel->rd_att, + &TTSOpsMinimalTuple); + slot2 = MakeSingleTupleTableSlot(rel->rd_att, + &TTSOpsMinimalTuple); } if (trigdesc == NULL) /* should not happen */ elog(ERROR, "relation %u has no triggers", @@ -4561,7 +4535,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, * still set, so recursive examinations of the event list * won't try to re-fire it. */ - AfterTriggerExecute(event, rel, trigdesc, finfo, instr, + AfterTriggerExecute(estate, event, rInfo, trigdesc, finfo, instr, per_tuple_context, slot1, slot2); /* @@ -4605,6 +4579,7 @@ afterTriggerInvokeEvents(AfterTriggerEventList *events, if (local_estate) { ExecCleanUpTriggerState(estate); + ExecResetTupleTable(estate->es_tupleTable, false); FreeExecutorState(estate); } @@ -4686,10 +4661,8 @@ TransitionCaptureState * MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType) { TransitionCaptureState *state; - bool need_old_upd, - need_new_upd, - need_old_del, - need_new_ins; + bool need_old, + need_new; AfterTriggersTableData *table; MemoryContext oldcxt; ResourceOwner saveResourceOwner; @@ -4701,31 +4674,23 @@ MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType) switch (cmdType) { case CMD_INSERT: - need_old_upd = need_old_del = need_new_upd = false; - need_new_ins = trigdesc->trig_insert_new_table; + need_old = false; + need_new = trigdesc->trig_insert_new_table; break; case CMD_UPDATE: - need_old_upd = trigdesc->trig_update_old_table; - need_new_upd = trigdesc->trig_update_new_table; - need_old_del = need_new_ins = false; + need_old = trigdesc->trig_update_old_table; + need_new = trigdesc->trig_update_new_table; break; case CMD_DELETE: - need_old_del = trigdesc->trig_delete_old_table; - need_old_upd = need_new_upd = need_new_ins = false; - break; - case CMD_MERGE: - need_old_upd = trigdesc->trig_update_old_table; - need_new_upd = trigdesc->trig_update_new_table; - need_old_del = trigdesc->trig_delete_old_table; - need_new_ins = trigdesc->trig_insert_new_table; + need_old = trigdesc->trig_delete_old_table; + need_new = false; break; default: elog(ERROR, "unexpected CmdType: %d", (int) cmdType); - /* keep compiler quiet */ - need_old_upd = need_new_upd = need_old_del = need_new_ins = false; + need_old = need_new = false; /* keep compiler quiet */ break; } - if (!need_old_upd && !need_new_upd && !need_new_ins && !need_old_del) + if (!need_old && !need_new) return NULL; /* Check state, like AfterTriggerSaveEvent. */ @@ -4755,14 +4720,10 @@ MakeTransitionCaptureState(TriggerDesc *trigdesc, Oid relid, CmdType cmdType) saveResourceOwner = CurrentResourceOwner; CurrentResourceOwner = CurTransactionResourceOwner; - if (need_old_upd && table->old_upd_tuplestore == NULL) - table->old_upd_tuplestore = tuplestore_begin_heap(false, false, work_mem); - if (need_new_upd && table->new_upd_tuplestore == NULL) - table->new_upd_tuplestore = tuplestore_begin_heap(false, false, work_mem); - if (need_old_del && table->old_del_tuplestore == NULL) - table->old_del_tuplestore = tuplestore_begin_heap(false, false, work_mem); - if (need_new_ins && table->new_ins_tuplestore == NULL) - table->new_ins_tuplestore = tuplestore_begin_heap(false, false, work_mem); + if (need_old && table->old_tuplestore == NULL) + table->old_tuplestore = tuplestore_begin_heap(false, false, work_mem); + if (need_new && table->new_tuplestore == NULL) + table->new_tuplestore = tuplestore_begin_heap(false, false, work_mem); CurrentResourceOwner = saveResourceOwner; MemoryContextSwitchTo(oldcxt); @@ -4951,20 +4912,12 @@ AfterTriggerFreeQuery(AfterTriggersQueryData *qs) { AfterTriggersTableData *table = (AfterTriggersTableData *) lfirst(lc); - ts = table->old_upd_tuplestore; - table->old_upd_tuplestore = NULL; - if (ts) - tuplestore_end(ts); - ts = table->new_upd_tuplestore; - table->new_upd_tuplestore = NULL; - if (ts) - tuplestore_end(ts); - ts = table->old_del_tuplestore; - table->old_del_tuplestore = NULL; + ts = table->old_tuplestore; + table->old_tuplestore = NULL; if (ts) tuplestore_end(ts); - ts = table->new_ins_tuplestore; - table->new_ins_tuplestore = NULL; + ts = table->new_tuplestore; + table->new_tuplestore = NULL; if (ts) tuplestore_end(ts); } @@ -5424,7 +5377,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) * A constraint in a partitioned table may have corresponding * constraints in the partitions. Grab those too. */ - conrel = heap_open(ConstraintRelationId, AccessShareLock); + conrel = table_open(ConstraintRelationId, AccessShareLock); foreach(lc, stmt->constraints) { @@ -5485,8 +5438,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup); if (con->condeferrable) - conoidlist = lappend_oid(conoidlist, - HeapTupleGetOid(tup)); + conoidlist = lappend_oid(conoidlist, con->oid); else if (stmt->deferred) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -5538,18 +5490,22 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) scan = systable_beginscan(conrel, ConstraintParentIndexId, true, NULL, 1, &key); while (HeapTupleIsValid(tuple = systable_getnext(scan))) - conoidlist = lappend_oid(conoidlist, HeapTupleGetOid(tuple)); + { + Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); + + conoidlist = lappend_oid(conoidlist, con->oid); + } systable_endscan(scan); } - heap_close(conrel, AccessShareLock); + table_close(conrel, AccessShareLock); /* * Now, locate the trigger(s) implementing each of these constraints, * and make a list of their OIDs. */ - tgrel = heap_open(TriggerRelationId, AccessShareLock); + tgrel = table_open(TriggerRelationId, AccessShareLock); foreach(lc, conoidlist) { @@ -5580,8 +5536,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) * actions. */ if (pg_trigger->tgdeferrable) - tgoidlist = lappend_oid(tgoidlist, - HeapTupleGetOid(htup)); + tgoidlist = lappend_oid(tgoidlist, pg_trigger->oid); found = true; } @@ -5594,7 +5549,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt) conoid); } - heap_close(tgrel, AccessShareLock); + table_close(tgrel, AccessShareLock); /* * Now we can set the trigger states of individual triggers for this @@ -5735,84 +5690,6 @@ AfterTriggerPendingOnRel(Oid relid) return false; } -/* - * Get the transition table for the given event and depending on whether we are - * processing the old or the new tuple. - */ -static Tuplestorestate * -AfterTriggerGetTransitionTable(int event, - HeapTuple oldtup, - HeapTuple newtup, - TransitionCaptureState *transition_capture) -{ - Tuplestorestate *tuplestore = NULL; - bool delete_old_table = transition_capture->tcs_delete_old_table; - bool update_old_table = transition_capture->tcs_update_old_table; - bool update_new_table = transition_capture->tcs_update_new_table; - bool insert_new_table = transition_capture->tcs_insert_new_table;; - - /* - * For INSERT events newtup should be non-NULL, for DELETE events - * oldtup should be non-NULL, whereas for UPDATE events normally both - * oldtup and newtup are non-NULL. But for UPDATE events fired for - * capturing transition tuples during UPDATE partition-key row - * movement, oldtup is NULL when the event is for a row being inserted, - * whereas newtup is NULL when the event is for a row being deleted. - */ - Assert(!(event == TRIGGER_EVENT_DELETE && delete_old_table && - oldtup == NULL)); - Assert(!(event == TRIGGER_EVENT_INSERT && insert_new_table && - newtup == NULL)); - - /* - * We're called either for the newtup or the oldtup, but not both at the - * same time. - */ - Assert((oldtup != NULL) ^ (newtup != NULL)); - - if (oldtup != NULL) - { - if (event == TRIGGER_EVENT_DELETE && delete_old_table) - tuplestore = transition_capture->tcs_private->old_del_tuplestore; - else if (event == TRIGGER_EVENT_UPDATE && update_old_table) - tuplestore = transition_capture->tcs_private->old_upd_tuplestore; - } - - if (newtup != NULL) - { - if (event == TRIGGER_EVENT_INSERT && insert_new_table) - tuplestore = transition_capture->tcs_private->new_ins_tuplestore; - else if (event == TRIGGER_EVENT_UPDATE && update_new_table) - tuplestore = transition_capture->tcs_private->new_upd_tuplestore; - } - - return tuplestore; -} - -/* - * Add the given heap tuple to the given tuplestore, applying the conversion - * map if necessary. - */ -static void -TransitionTableAddTuple(HeapTuple heaptup, Tuplestorestate *tuplestore, - TupleConversionMap *map) -{ - /* - * Nothing needs to be done if we don't have a tuplestore. - */ - if (tuplestore == NULL) - return; - - if (map != NULL) - { - HeapTuple converted = do_convert_tuple(heaptup, map); - - tuplestore_puttuple(tuplestore, converted); - pfree(converted); - } - else - tuplestore_puttuple(tuplestore, heaptup); -} /* ---------- * AfterTriggerSaveEvent() @@ -5840,7 +5717,7 @@ TransitionTableAddTuple(HeapTuple heaptup, Tuplestorestate *tuplestore, static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, int event, bool row_trigger, - HeapTuple oldtup, HeapTuple newtup, + TupleTableSlot *oldslot, TupleTableSlot *newslot, List *recheckIndexes, Bitmapset *modifiedCols, TransitionCaptureState *transition_capture) { @@ -5872,53 +5749,97 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, */ if (row_trigger && transition_capture != NULL) { - HeapTuple original_insert_tuple = transition_capture->tcs_original_insert_tuple; + TupleTableSlot *original_insert_tuple = transition_capture->tcs_original_insert_tuple; TupleConversionMap *map = transition_capture->tcs_map; + bool delete_old_table = transition_capture->tcs_delete_old_table; + bool update_old_table = transition_capture->tcs_update_old_table; + bool update_new_table = transition_capture->tcs_update_new_table; + bool insert_new_table = transition_capture->tcs_insert_new_table; /* - * Capture the old tuple in the appropriate transition table based on - * the event. + * For INSERT events NEW should be non-NULL, for DELETE events OLD + * should be non-NULL, whereas for UPDATE events normally both OLD and + * NEW are non-NULL. But for UPDATE events fired for capturing + * transition tuples during UPDATE partition-key row movement, OLD is + * NULL when the event is for a row being inserted, whereas NEW is + * NULL when the event is for a row being deleted. */ - if (oldtup != NULL) + Assert(!(event == TRIGGER_EVENT_DELETE && delete_old_table && + TupIsNull(oldslot))); + Assert(!(event == TRIGGER_EVENT_INSERT && insert_new_table && + TupIsNull(newslot))); + + if (!TupIsNull(oldslot) && + ((event == TRIGGER_EVENT_DELETE && delete_old_table) || + (event == TRIGGER_EVENT_UPDATE && update_old_table))) { - Tuplestorestate *tuplestore = - AfterTriggerGetTransitionTable(event, - oldtup, - NULL, - transition_capture); - TransitionTableAddTuple(oldtup, tuplestore, map); - } + Tuplestorestate *old_tuplestore; - /* - * Capture the new tuple in the appropriate transition table based on - * the event. - */ - if (newtup != NULL) + old_tuplestore = transition_capture->tcs_private->old_tuplestore; + + if (map != NULL) + { + TupleTableSlot *storeslot; + + storeslot = transition_capture->tcs_private->storeslot; + if (!storeslot) + { + storeslot = ExecAllocTableSlot(&estate->es_tupleTable, + map->outdesc, + &TTSOpsVirtual); + transition_capture->tcs_private->storeslot = storeslot; + } + + execute_attr_map_slot(map->attrMap, oldslot, storeslot); + tuplestore_puttupleslot(old_tuplestore, storeslot); + } + else + tuplestore_puttupleslot(old_tuplestore, oldslot); + } + if (!TupIsNull(newslot) && + ((event == TRIGGER_EVENT_INSERT && insert_new_table) || + (event == TRIGGER_EVENT_UPDATE && update_new_table))) { - Tuplestorestate *tuplestore = - AfterTriggerGetTransitionTable(event, - NULL, - newtup, - transition_capture); + Tuplestorestate *new_tuplestore; + + new_tuplestore = transition_capture->tcs_private->new_tuplestore; if (original_insert_tuple != NULL) - tuplestore_puttuple(tuplestore, original_insert_tuple); + tuplestore_puttupleslot(new_tuplestore, + original_insert_tuple); + else if (map != NULL) + { + TupleTableSlot *storeslot; + + storeslot = transition_capture->tcs_private->storeslot; + + if (!storeslot) + { + storeslot = ExecAllocTableSlot(&estate->es_tupleTable, + map->outdesc, + &TTSOpsVirtual); + transition_capture->tcs_private->storeslot = storeslot; + } + + execute_attr_map_slot(map->attrMap, newslot, storeslot); + tuplestore_puttupleslot(new_tuplestore, storeslot); + } else - TransitionTableAddTuple(newtup, tuplestore, map); + tuplestore_puttupleslot(new_tuplestore, newslot); } /* * If transition tables are the only reason we're here, return. As * mentioned above, we can also be here during update tuple routing in - * presence of transition tables, in which case this function is called - * separately for oldtup and newtup, so we expect exactly one of them - * to be NULL. + * presence of transition tables, in which case this function is + * called separately for oldtup and newtup, so we expect exactly one + * of them to be NULL. */ if (trigdesc == NULL || (event == TRIGGER_EVENT_DELETE && !trigdesc->trig_delete_after_row) || (event == TRIGGER_EVENT_INSERT && !trigdesc->trig_insert_after_row) || (event == TRIGGER_EVENT_UPDATE && !trigdesc->trig_update_after_row) || - (event == TRIGGER_EVENT_UPDATE && ((oldtup == NULL) ^ (newtup == NULL)))) + (event == TRIGGER_EVENT_UPDATE && (TupIsNull(oldslot) ^ TupIsNull(newslot)))) return; } @@ -5940,15 +5861,15 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, tgtype_event = TRIGGER_TYPE_INSERT; if (row_trigger) { - Assert(oldtup == NULL); - Assert(newtup != NULL); - ItemPointerCopy(&(newtup->t_self), &(new_event.ate_ctid1)); + Assert(oldslot == NULL); + Assert(newslot != NULL); + ItemPointerCopy(&(newslot->tts_tid), &(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); } else { - Assert(oldtup == NULL); - Assert(newtup == NULL); + Assert(oldslot == NULL); + Assert(newslot == NULL); ItemPointerSetInvalid(&(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); cancel_prior_stmt_triggers(RelationGetRelid(rel), @@ -5959,15 +5880,15 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, tgtype_event = TRIGGER_TYPE_DELETE; if (row_trigger) { - Assert(oldtup != NULL); - Assert(newtup == NULL); - ItemPointerCopy(&(oldtup->t_self), &(new_event.ate_ctid1)); + Assert(oldslot != NULL); + Assert(newslot == NULL); + ItemPointerCopy(&(oldslot->tts_tid), &(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); } else { - Assert(oldtup == NULL); - Assert(newtup == NULL); + Assert(oldslot == NULL); + Assert(newslot == NULL); ItemPointerSetInvalid(&(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); cancel_prior_stmt_triggers(RelationGetRelid(rel), @@ -5978,15 +5899,15 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, tgtype_event = TRIGGER_TYPE_UPDATE; if (row_trigger) { - Assert(oldtup != NULL); - Assert(newtup != NULL); - ItemPointerCopy(&(oldtup->t_self), &(new_event.ate_ctid1)); - ItemPointerCopy(&(newtup->t_self), &(new_event.ate_ctid2)); + Assert(oldslot != NULL); + Assert(newslot != NULL); + ItemPointerCopy(&(oldslot->tts_tid), &(new_event.ate_ctid1)); + ItemPointerCopy(&(newslot->tts_tid), &(new_event.ate_ctid2)); } else { - Assert(oldtup == NULL); - Assert(newtup == NULL); + Assert(oldslot == NULL); + Assert(newslot == NULL); ItemPointerSetInvalid(&(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); cancel_prior_stmt_triggers(RelationGetRelid(rel), @@ -5995,8 +5916,8 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, break; case TRIGGER_EVENT_TRUNCATE: tgtype_event = TRIGGER_TYPE_TRUNCATE; - Assert(oldtup == NULL); - Assert(newtup == NULL); + Assert(oldslot == NULL); + Assert(newslot == NULL); ItemPointerSetInvalid(&(new_event.ate_ctid1)); ItemPointerSetInvalid(&(new_event.ate_ctid2)); break; @@ -6023,7 +5944,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, tgtype_event)) continue; if (!TriggerEnabled(estate, relinfo, trigger, event, - modifiedCols, oldtup, newtup)) + modifiedCols, oldslot, newslot)) continue; if (relkind == RELKIND_FOREIGN_TABLE && row_trigger) @@ -6043,14 +5964,14 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, * certain cases where we can skip queueing the event because we can * tell by inspection that the FK constraint will still pass. */ - if (TRIGGER_FIRED_BY_UPDATE(event)) + if (TRIGGER_FIRED_BY_UPDATE(event) || TRIGGER_FIRED_BY_DELETE(event)) { switch (RI_FKey_trigger_type(trigger->tgfoid)) { case RI_TRIGGER_PK: - /* Update on trigger's PK table */ + /* Update or delete on trigger's PK table */ if (!RI_FKey_pk_upd_check_required(trigger, rel, - oldtup, newtup)) + oldslot, newslot)) { /* skip queuing this event */ continue; @@ -6060,7 +5981,7 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, case RI_TRIGGER_FK: /* Update on trigger's FK table */ if (!RI_FKey_fk_upd_check_required(trigger, rel, - oldtup, newtup)) + oldslot, newslot)) { /* skip queuing this event */ continue; @@ -6114,10 +6035,10 @@ AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo, */ if (fdw_tuplestore) { - if (oldtup != NULL) - tuplestore_puttuple(fdw_tuplestore, oldtup); - if (newtup != NULL) - tuplestore_puttuple(fdw_tuplestore, newtup); + if (oldslot != NULL) + tuplestore_puttupleslot(fdw_tuplestore, oldslot); + if (newslot != NULL) + tuplestore_puttupleslot(fdw_tuplestore, newslot); } } diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 3a843512d13..5d6528f9cf8 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -4,7 +4,7 @@ * * Routines for tsearch manipulation commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,9 +18,10 @@ #include #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/objectaccess.h" @@ -45,13 +46,12 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, - HeapTuple tup, Relation relMap); + HeapTuple tup, Relation relMap); static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, - HeapTuple tup, Relation relMap); + HeapTuple tup, Relation relMap); /* --------------------- TS Parser commands ------------------------ */ @@ -132,7 +132,7 @@ makeParserDependencies(HeapTuple tuple) referenced; myself.classId = TSParserRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = prs->oid; myself.objectSubId = 0; /* dependency on namespace */ @@ -191,6 +191,8 @@ DefineTSParser(List *names, List *parameters) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to create text search parsers"))); + prsRel = table_open(TSParserRelationId, RowExclusiveLock); + /* Convert list of names to a name and namespace */ namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname); @@ -198,6 +200,9 @@ DefineTSParser(List *names, List *parameters) memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId, + Anum_pg_ts_parser_oid); + values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid); namestrcpy(&pname, prsname); values[Anum_pg_ts_parser_prsname - 1] = NameGetDatum(&pname); values[Anum_pg_ts_parser_prsnamespace - 1] = ObjectIdGetDatum(namespaceoid); @@ -267,11 +272,9 @@ DefineTSParser(List *names, List *parameters) /* * Looks good, insert */ - prsRel = heap_open(TSParserRelationId, RowExclusiveLock); - tup = heap_form_tuple(prsRel->rd_att, values, nulls); - prsOid = CatalogTupleInsert(prsRel, tup); + CatalogTupleInsert(prsRel, tup); address = makeParserDependencies(tup); @@ -280,7 +283,7 @@ DefineTSParser(List *names, List *parameters) heap_freetuple(tup); - heap_close(prsRel, RowExclusiveLock); + table_close(prsRel, RowExclusiveLock); return address; } @@ -294,7 +297,7 @@ RemoveTSParserById(Oid prsId) Relation relation; HeapTuple tup; - relation = heap_open(TSParserRelationId, RowExclusiveLock); + relation = table_open(TSParserRelationId, RowExclusiveLock); tup = SearchSysCache1(TSPARSEROID, ObjectIdGetDatum(prsId)); @@ -305,7 +308,7 @@ RemoveTSParserById(Oid prsId) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* ---------------------- TS Dictionary commands -----------------------*/ @@ -323,7 +326,7 @@ makeDictionaryDependencies(HeapTuple tuple) referenced; myself.classId = TSDictionaryRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = dict->oid; myself.objectSubId = 0; /* dependency on namespace */ @@ -459,12 +462,18 @@ DefineTSDictionary(List *names, List *parameters) verify_dictoptions(templId, dictoptions); + + dictRel = table_open(TSDictionaryRelationId, RowExclusiveLock); + /* * Looks good, insert */ memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId, + Anum_pg_ts_dict_oid); + values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid); namestrcpy(&dname, dictname); values[Anum_pg_ts_dict_dictname - 1] = NameGetDatum(&dname); values[Anum_pg_ts_dict_dictnamespace - 1] = ObjectIdGetDatum(namespaceoid); @@ -476,11 +485,9 @@ DefineTSDictionary(List *names, List *parameters) else nulls[Anum_pg_ts_dict_dictinitoption - 1] = true; - dictRel = heap_open(TSDictionaryRelationId, RowExclusiveLock); - tup = heap_form_tuple(dictRel->rd_att, values, nulls); - dictOid = CatalogTupleInsert(dictRel, tup); + CatalogTupleInsert(dictRel, tup); address = makeDictionaryDependencies(tup); @@ -489,7 +496,7 @@ DefineTSDictionary(List *names, List *parameters) heap_freetuple(tup); - heap_close(dictRel, RowExclusiveLock); + table_close(dictRel, RowExclusiveLock); return address; } @@ -503,7 +510,7 @@ RemoveTSDictionaryById(Oid dictId) Relation relation; HeapTuple tup; - relation = heap_open(TSDictionaryRelationId, RowExclusiveLock); + relation = table_open(TSDictionaryRelationId, RowExclusiveLock); tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId)); @@ -515,7 +522,7 @@ RemoveTSDictionaryById(Oid dictId) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* @@ -539,7 +546,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) dictId = get_ts_dict_oid(stmt->dictname, false); - rel = heap_open(TSDictionaryRelationId, RowExclusiveLock); + rel = table_open(TSDictionaryRelationId, RowExclusiveLock); tup = SearchSysCache1(TSDICTOID, ObjectIdGetDatum(dictId)); @@ -568,22 +575,16 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) { DefElem *defel = (DefElem *) lfirst(pl); ListCell *cell; - ListCell *prev; - ListCell *next; /* * Remove any matches ... */ - prev = NULL; - for (cell = list_head(dictoptions); cell; cell = next) + foreach(cell, dictoptions) { DefElem *oldel = (DefElem *) lfirst(cell); - next = lnext(cell); if (strcmp(oldel->defname, defel->defname) == 0) - dictoptions = list_delete_cell(dictoptions, cell, prev); - else - prev = cell; + dictoptions = foreach_delete_current(dictoptions, cell); } /* @@ -631,7 +632,7 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) heap_freetuple(newtup); ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -694,7 +695,7 @@ makeTSTemplateDependencies(HeapTuple tuple) referenced; myself.classId = TSTemplateRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = tmpl->oid; myself.objectSubId = 0; /* dependency on namespace */ @@ -748,12 +749,17 @@ DefineTSTemplate(List *names, List *parameters) /* Convert list of names to a name and namespace */ namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname); + tmplRel = table_open(TSTemplateRelationId, RowExclusiveLock); + for (i = 0; i < Natts_pg_ts_template; i++) { nulls[i] = false; values[i] = ObjectIdGetDatum(InvalidOid); } + tmplOid = GetNewOidWithIndex(tmplRel, TSTemplateOidIndexId, + Anum_pg_ts_dict_oid); + values[Anum_pg_ts_template_oid - 1] = ObjectIdGetDatum(tmplOid); namestrcpy(&dname, tmplname); values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname); values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid); @@ -795,12 +801,9 @@ DefineTSTemplate(List *names, List *parameters) /* * Looks good, insert */ - - tmplRel = heap_open(TSTemplateRelationId, RowExclusiveLock); - tup = heap_form_tuple(tmplRel->rd_att, values, nulls); - tmplOid = CatalogTupleInsert(tmplRel, tup); + CatalogTupleInsert(tmplRel, tup); address = makeTSTemplateDependencies(tup); @@ -809,7 +812,7 @@ DefineTSTemplate(List *names, List *parameters) heap_freetuple(tup); - heap_close(tmplRel, RowExclusiveLock); + table_close(tmplRel, RowExclusiveLock); return address; } @@ -823,7 +826,7 @@ RemoveTSTemplateById(Oid tmplId) Relation relation; HeapTuple tup; - relation = heap_open(TSTemplateRelationId, RowExclusiveLock); + relation = table_open(TSTemplateRelationId, RowExclusiveLock); tup = SearchSysCache1(TSTEMPLATEOID, ObjectIdGetDatum(tmplId)); @@ -835,7 +838,7 @@ RemoveTSTemplateById(Oid tmplId) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } /* ---------------------- TS Configuration commands -----------------------*/ @@ -879,7 +882,7 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld, referenced; myself.classId = TSConfigRelationId; - myself.objectId = HeapTupleGetOid(tuple); + myself.objectId = cfg->oid; myself.objectSubId = 0; /* for ALTER case, first flush old dependencies, except extension deps */ @@ -1042,23 +1045,26 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied) (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("text search parser is required"))); + cfgRel = table_open(TSConfigRelationId, RowExclusiveLock); + /* * Looks good, build tuple and insert */ memset(values, 0, sizeof(values)); memset(nulls, false, sizeof(nulls)); + cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId, + Anum_pg_ts_config_oid); + values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid); namestrcpy(&cname, cfgname); values[Anum_pg_ts_config_cfgname - 1] = NameGetDatum(&cname); values[Anum_pg_ts_config_cfgnamespace - 1] = ObjectIdGetDatum(namespaceoid); values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId()); values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid); - cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock); - tup = heap_form_tuple(cfgRel->rd_att, values, nulls); - cfgOid = CatalogTupleInsert(cfgRel, tup); + CatalogTupleInsert(cfgRel, tup); if (OidIsValid(sourceOid)) { @@ -1069,7 +1075,7 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied) SysScanDesc scan; HeapTuple maptup; - mapRel = heap_open(TSConfigMapRelationId, RowExclusiveLock); + mapRel = table_open(TSConfigMapRelationId, RowExclusiveLock); ScanKeyInit(&skey, Anum_pg_ts_config_map_mapcfg, @@ -1112,8 +1118,8 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied) heap_freetuple(tup); if (mapRel) - heap_close(mapRel, RowExclusiveLock); - heap_close(cfgRel, RowExclusiveLock); + table_close(mapRel, RowExclusiveLock); + table_close(cfgRel, RowExclusiveLock); return address; } @@ -1131,7 +1137,7 @@ RemoveTSConfigurationById(Oid cfgId) SysScanDesc scan; /* Remove the pg_ts_config entry */ - relCfg = heap_open(TSConfigRelationId, RowExclusiveLock); + relCfg = table_open(TSConfigRelationId, RowExclusiveLock); tup = SearchSysCache1(TSCONFIGOID, ObjectIdGetDatum(cfgId)); @@ -1143,10 +1149,10 @@ RemoveTSConfigurationById(Oid cfgId) ReleaseSysCache(tup); - heap_close(relCfg, RowExclusiveLock); + table_close(relCfg, RowExclusiveLock); /* Remove any pg_ts_config_map entries */ - relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock); + relMap = table_open(TSConfigMapRelationId, RowExclusiveLock); ScanKeyInit(&skey, Anum_pg_ts_config_map_mapcfg, @@ -1163,7 +1169,7 @@ RemoveTSConfigurationById(Oid cfgId) systable_endscan(scan); - heap_close(relMap, RowExclusiveLock); + table_close(relMap, RowExclusiveLock); } /* @@ -1185,14 +1191,14 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) errmsg("text search configuration \"%s\" does not exist", NameListToString(stmt->cfgname)))); - cfgId = HeapTupleGetOid(tup); + cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid; /* must be owner */ - if (!pg_ts_config_ownercheck(HeapTupleGetOid(tup), GetUserId())) + if (!pg_ts_config_ownercheck(cfgId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TSCONFIGURATION, NameListToString(stmt->cfgname)); - relMap = heap_open(TSConfigMapRelationId, RowExclusiveLock); + relMap = table_open(TSConfigMapRelationId, RowExclusiveLock); /* Add or drop mappings */ if (stmt->dicts) @@ -1203,12 +1209,11 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt) /* Update dependencies */ makeConfigurationDependencies(tup, true, relMap); - InvokeObjectPostAlterHook(TSConfigRelationId, - HeapTupleGetOid(tup), 0); + InvokeObjectPostAlterHook(TSConfigRelationId, cfgId, 0); ObjectAddressSet(address, TSConfigRelationId, cfgId); - heap_close(relMap, RowExclusiveLock); + table_close(relMap, RowExclusiveLock); ReleaseSysCache(tup); @@ -1277,7 +1282,8 @@ static void MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap) { - Oid cfgId = HeapTupleGetOid(tup); + Form_pg_ts_config tsform; + Oid cfgId; ScanKeyData skey[2]; SysScanDesc scan; HeapTuple maptup; @@ -1290,7 +1296,9 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt, int ndict; ListCell *c; - prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser; + tsform = (Form_pg_ts_config) GETSTRUCT(tup); + cfgId = tsform->oid; + prsId = tsform->cfgparser; tokens = getTokenTypes(prsId, stmt->tokentype); ntoken = list_length(stmt->tokentype); @@ -1438,7 +1446,8 @@ static void DropConfigurationMapping(AlterTSConfigurationStmt *stmt, HeapTuple tup, Relation relMap) { - Oid cfgId = HeapTupleGetOid(tup); + Form_pg_ts_config tsform; + Oid cfgId; ScanKeyData skey[2]; SysScanDesc scan; HeapTuple maptup; @@ -1447,7 +1456,9 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt, int *tokens; ListCell *c; - prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser; + tsform = (Form_pg_ts_config) GETSTRUCT(tup); + cfgId = tsform->oid; + prsId = tsform->cfgparser; tokens = getTokenTypes(prsId, stmt->tokentype); @@ -1541,7 +1552,7 @@ serialize_deflist(List *deflist) appendStringInfoChar(&buf, ch); } appendStringInfoChar(&buf, '\''); - if (lnext(l) != NULL) + if (lnext(deflist, l) != NULL) appendStringInfoString(&buf, ", "); } diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 7746d182589..89887b8fd75 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -3,7 +3,7 @@ * typecmds.c * Routines for SQL commands that manipulate types (and domains). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -31,7 +31,10 @@ */ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -54,7 +57,7 @@ #include "executor/executor.h" #include "miscadmin.h" #include "nodes/makefuncs.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_coerce.h" #include "parser/parse_collate.h" #include "parser/parse_expr.h" @@ -62,6 +65,7 @@ #include "parser/parse_type.h" #include "utils/builtins.h" #include "utils/fmgroids.h" +#include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -83,7 +87,7 @@ typedef struct Oid binary_upgrade_next_array_pg_type_oid = InvalidOid; static void makeRangeConstructors(const char *name, Oid namespace, - Oid rangeOid, Oid subtype); + Oid rangeOid, Oid subtype); static Oid findTypeInputFunction(List *procname, Oid typeOid); static Oid findTypeOutputFunction(List *procname, Oid typeOid); static Oid findTypeReceiveFunction(List *procname, Oid typeOid); @@ -98,11 +102,11 @@ static void validateDomainConstraint(Oid domainoid, char *ccbin); static List *get_rels_with_domain(Oid domainOid, LOCKMODE lockmode); static void checkEnumOwner(HeapTuple tup); static char *domainAddConstraint(Oid domainOid, Oid domainNamespace, - Oid baseTypeOid, - int typMod, Constraint *constr, - const char *domainName, ObjectAddress *constrAddr); + Oid baseTypeOid, + int typMod, Constraint *constr, + const char *domainName, ObjectAddress *constrAddr); static Node *replace_domain_constraint_value(ParseState *pstate, - ColumnRef *cref); + ColumnRef *cref); /* @@ -195,7 +199,7 @@ DefineType(ParseState *pstate, List *names, List *parameters) * Look to see if type already exists (presumably as a shell; if not, * TypeCreate will complain). */ - typoid = GetSysCacheOid2(TYPENAMENSP, + typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace)); @@ -688,7 +692,7 @@ RemoveTypeById(Oid typeOid) Relation relation; HeapTuple tup; - relation = heap_open(TypeRelationId, RowExclusiveLock); + relation = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tup)) @@ -714,7 +718,7 @@ RemoveTypeById(Oid typeOid) ReleaseSysCache(tup); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); } @@ -776,7 +780,7 @@ DefineDomain(CreateDomainStmt *stmt) * Check for collision with an existing type name. If there is one and * it's an autogenerated array, we can rename it out of the way. */ - old_type_oid = GetSysCacheOid2(TYPENAMENSP, + old_type_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(domainName), ObjectIdGetDatum(domainNamespace)); if (OidIsValid(old_type_oid)) @@ -792,7 +796,7 @@ DefineDomain(CreateDomainStmt *stmt) */ typeTup = typenameType(NULL, stmt->typeName, &basetypeMod); baseType = (Form_pg_type) GETSTRUCT(typeTup); - basetypeoid = HeapTupleGetOid(typeTup); + basetypeoid = baseType->oid; /* * Base type must be a plain base type, a composite type, another domain, @@ -914,7 +918,8 @@ DefineDomain(CreateDomainStmt *stmt) defaultExpr = cookDefault(pstate, constr->raw_expr, basetypeoid, basetypeMod, - domainName); + domainName, + 0); /* * If the expression is just a NULL constant, we treat it @@ -1175,7 +1180,7 @@ DefineEnum(CreateEnumStmt *stmt) * Check for collision with an existing type name. If there is one and * it's an autogenerated array, we can rename it out of the way. */ - old_type_oid = GetSysCacheOid2(TYPENAMENSP, + old_type_oid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(enumName), ObjectIdGetDatum(enumNamespace)); if (OidIsValid(old_type_oid)) @@ -1270,10 +1275,10 @@ DefineEnum(CreateEnumStmt *stmt) /* * AlterEnum - * ALTER TYPE on an enum. + * Adds a new label to an existing enum. */ ObjectAddress -AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) +AlterEnum(AlterEnumStmt *stmt) { Oid enum_type_oid; TypeName *typename; @@ -1291,6 +1296,8 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) /* Check it's an enum and check user has permission to ALTER the enum */ checkEnumOwner(tup); + ReleaseSysCache(tup); + if (stmt->oldVal) { /* Rename an existing label */ @@ -1299,27 +1306,6 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) else { /* Add a new label */ - - /* - * Ordinarily we disallow adding values within transaction blocks, - * because we can't cope with enum OID values getting into indexes and - * then having their defining pg_enum entries go away. However, it's - * okay if the enum type was created in the current transaction, since - * then there can be no such indexes that wouldn't themselves go away - * on rollback. (We support this case because pg_dump - * --binary-upgrade needs it.) We test this by seeing if the pg_type - * row has xmin == current XID and is not HEAP_UPDATED. If it is - * HEAP_UPDATED, we can't be sure whether the type was created or only - * modified in this xact. So we are disallowing some cases that could - * theoretically be safe; but fortunately pg_dump only needs the - * simplest case. - */ - if (HeapTupleHeaderGetXmin(tup->t_data) == GetCurrentTransactionId() && - !(tup->t_data->t_infomask & HEAP_UPDATED)) - /* safe to do inside transaction block */ ; - else - PreventInTransactionBlock(isTopLevel, "ALTER TYPE ... ADD"); - AddEnumLabel(enum_type_oid, stmt->newVal, stmt->newValNeighbor, stmt->newValIsAfter, stmt->skipIfNewValExists); @@ -1329,8 +1315,6 @@ AlterEnum(AlterEnumStmt *stmt, bool isTopLevel) ObjectAddressSet(address, TypeRelationId, enum_type_oid); - ReleaseSysCache(tup); - return address; } @@ -1351,11 +1335,11 @@ checkEnumOwner(HeapTuple tup) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is not an enum", - format_type_be(HeapTupleGetOid(tup))))); + format_type_be(typTup->oid)))); /* Permission check: must own type */ - if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup)); + if (!pg_type_ownercheck(typTup->oid, GetUserId())) + aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); } @@ -1401,7 +1385,7 @@ DefineRange(CreateRangeStmt *stmt) /* * Look to see if type already exists. */ - typoid = GetSysCacheOid2(TYPENAMENSP, + typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(typeName), ObjectIdGetDatum(typeNamespace)); @@ -1682,6 +1666,7 @@ makeRangeConstructors(const char *name, Oid namespace, NIL, /* parameterDefaults */ PointerGetDatum(NULL), /* trftypes */ PointerGetDatum(NULL), /* proconfig */ + InvalidOid, /* prosupport */ 1.0, /* procost */ 0.0); /* prorows */ @@ -1990,7 +1975,7 @@ findRangeSubOpclass(List *opcname, Oid subtype) opcid = GetDefaultOpClass(subtype, BTREE_AM_OID); if (!OidIsValid(opcid)) { - /* We spell the error message identically to GetIndexOpClass */ + /* We spell the error message identically to ResolveOpClass */ ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("data type %s has no default operator class for access method \"%s\"", @@ -2109,10 +2094,11 @@ AssignTypeArrayOid(void) } else { - Relation pg_type = heap_open(TypeRelationId, AccessShareLock); + Relation pg_type = table_open(TypeRelationId, AccessShareLock); - type_array_oid = GetNewOid(pg_type); - heap_close(pg_type, AccessShareLock); + type_array_oid = GetNewOidWithIndex(pg_type, TypeOidIndexId, + Anum_pg_type_oid); + table_close(pg_type, AccessShareLock); } return type_array_oid; @@ -2163,7 +2149,7 @@ DefineCompositeType(RangeVar *typevar, List *coldeflist) NoLock, NULL); RangeVarAdjustRelationPersistence(createStmt->relation, typeNamespace); old_type_oid = - GetSysCacheOid2(TYPENAMENSP, + GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, CStringGetDatum(createStmt->relation->relname), ObjectIdGetDatum(typeNamespace)); if (OidIsValid(old_type_oid)) @@ -2200,6 +2186,9 @@ AlterDomainDefault(List *names, Node *defaultRaw) Relation rel; char *defaultValue; Node *defaultExpr = NULL; /* NULL if no default specified */ + Acl *typacl; + Datum aclDatum; + bool isNull; Datum new_record[Natts_pg_type]; bool new_record_nulls[Natts_pg_type]; bool new_record_repl[Natts_pg_type]; @@ -2212,7 +2201,7 @@ AlterDomainDefault(List *names, Node *defaultRaw) domainoid = typenameTypeId(NULL, typename); /* Look up the domain in the type table */ - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(domainoid)); if (!HeapTupleIsValid(tup)) @@ -2240,7 +2229,8 @@ AlterDomainDefault(List *names, Node *defaultRaw) defaultExpr = cookDefault(pstate, defaultRaw, typTup->typbasetype, typTup->typtypmod, - NameStr(typTup->typname)); + NameStr(typTup->typname), + 0); /* * If the expression is just a NULL constant, we treat the command @@ -2291,32 +2281,30 @@ AlterDomainDefault(List *names, Node *defaultRaw) CatalogTupleUpdate(rel, &tup->t_self, newtuple); + /* Must extract ACL for use of GenerateTypeDependencies */ + aclDatum = heap_getattr(newtuple, Anum_pg_type_typacl, + RelationGetDescr(rel), &isNull); + if (isNull) + typacl = NULL; + else + typacl = DatumGetAclPCopy(aclDatum); + /* Rebuild dependencies */ - GenerateTypeDependencies(typTup->typnamespace, - domainoid, - InvalidOid, /* typrelid is n/a */ + GenerateTypeDependencies(domainoid, + (Form_pg_type) GETSTRUCT(newtuple), + defaultExpr, + typacl, 0, /* relation kind is n/a */ - typTup->typowner, - typTup->typinput, - typTup->typoutput, - typTup->typreceive, - typTup->typsend, - typTup->typmodin, - typTup->typmodout, - typTup->typanalyze, - InvalidOid, false, /* a domain isn't an implicit array */ - typTup->typbasetype, - typTup->typcollation, - defaultExpr, - true); /* Rebuild is true */ + false, /* nor is it any kind of dependent type */ + true); /* We do need to rebuild dependencies */ InvokeObjectPostAlterHook(TypeRelationId, domainoid, 0); ObjectAddressSet(address, TypeRelationId, domainoid); /* Clean up */ - heap_close(rel, NoLock); + table_close(rel, RowExclusiveLock); heap_freetuple(newtuple); return address; @@ -2344,7 +2332,7 @@ AlterDomainNotNull(List *names, bool notNull) domainoid = typenameTypeId(NULL, typename); /* Look up the domain in the type table */ - typrel = heap_open(TypeRelationId, RowExclusiveLock); + typrel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(domainoid)); if (!HeapTupleIsValid(tup)) @@ -2357,7 +2345,7 @@ AlterDomainNotNull(List *names, bool notNull) /* Is the domain already set to the desired constraint? */ if (typTup->typnotnull == notNull) { - heap_close(typrel, RowExclusiveLock); + table_close(typrel, RowExclusiveLock); return address; } @@ -2377,14 +2365,15 @@ AlterDomainNotNull(List *names, bool notNull) RelToCheck *rtc = (RelToCheck *) lfirst(rt); Relation testrel = rtc->rel; TupleDesc tupdesc = RelationGetDescr(testrel); - HeapScanDesc scan; - HeapTuple tuple; + TupleTableSlot *slot; + TableScanDesc scan; Snapshot snapshot; /* Scan all tuples in this relation */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(testrel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + scan = table_beginscan(testrel, snapshot, 0, NULL); + slot = table_slot_create(testrel, NULL); + while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) { int i; @@ -2394,7 +2383,7 @@ AlterDomainNotNull(List *names, bool notNull) int attnum = rtc->atts[i]; Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); - if (heap_attisnull(tuple, attnum, tupdesc)) + if (slot_attisnull(slot, attnum)) { /* * In principle the auxiliary information for this @@ -2413,11 +2402,12 @@ AlterDomainNotNull(List *names, bool notNull) } } } - heap_endscan(scan); + ExecDropSingleTupleTableSlot(slot); + table_endscan(scan); UnregisterSnapshot(snapshot); /* Close each rel after processing, but keep lock */ - heap_close(testrel, NoLock); + table_close(testrel, NoLock); } } @@ -2435,7 +2425,7 @@ AlterDomainNotNull(List *names, bool notNull) /* Clean up */ heap_freetuple(tup); - heap_close(typrel, RowExclusiveLock); + table_close(typrel, RowExclusiveLock); return address; } @@ -2444,6 +2434,8 @@ AlterDomainNotNull(List *names, bool notNull) * AlterDomainDropConstraint * * Implements the ALTER DOMAIN DROP CONSTRAINT statement + * + * Returns ObjectAddress of the modified domain. */ ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, @@ -2455,17 +2447,17 @@ AlterDomainDropConstraint(List *names, const char *constrName, Relation rel; Relation conrel; SysScanDesc conscan; - ScanKeyData key[1]; + ScanKeyData skey[3]; HeapTuple contup; bool found = false; - ObjectAddress address = InvalidObjectAddress; + ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); domainoid = typenameTypeId(NULL, typename); /* Look up the domain in the type table */ - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(domainoid)); if (!HeapTupleIsValid(tup)) @@ -2475,44 +2467,41 @@ AlterDomainDropConstraint(List *names, const char *constrName, checkDomainOwner(tup); /* Grab an appropriate lock on the pg_constraint relation */ - conrel = heap_open(ConstraintRelationId, RowExclusiveLock); + conrel = table_open(ConstraintRelationId, RowExclusiveLock); - /* Use the index to scan only constraints of the target relation */ - ScanKeyInit(&key[0], + /* Find and remove the target constraint */ + ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[1], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(HeapTupleGetOid(tup))); + ObjectIdGetDatum(domainoid)); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(constrName)); - conscan = systable_beginscan(conrel, ConstraintTypidIndexId, true, - NULL, 1, key); + conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - /* - * Scan over the result set, removing any matching entries. - */ - while ((contup = systable_getnext(conscan)) != NULL) + /* There can be at most one matching row */ + if ((contup = systable_getnext(conscan)) != NULL) { - Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(contup); - - if (strcmp(NameStr(con->conname), constrName) == 0) - { - ObjectAddress conobj; + ObjectAddress conobj; - conobj.classId = ConstraintRelationId; - conobj.objectId = HeapTupleGetOid(contup); - conobj.objectSubId = 0; + conobj.classId = ConstraintRelationId; + conobj.objectId = ((Form_pg_constraint) GETSTRUCT(contup))->oid; + conobj.objectSubId = 0; - performDeletion(&conobj, behavior, 0); - found = true; - } + performDeletion(&conobj, behavior, 0); + found = true; } - ObjectAddressSet(address, TypeRelationId, domainoid); - /* Clean up after the scan */ systable_endscan(conscan); - heap_close(conrel, RowExclusiveLock); - - heap_close(rel, NoLock); + table_close(conrel, RowExclusiveLock); if (!found) { @@ -2527,6 +2516,18 @@ AlterDomainDropConstraint(List *names, const char *constrName, constrName, TypeNameToString(typename)))); } + /* + * We must send out an sinval message for the domain, to ensure that any + * dependent plans get rebuilt. Since this command doesn't change the + * domain's pg_type row, that won't happen automatically; do it manually. + */ + CacheInvalidateHeapTuple(rel, tup, NULL); + + ObjectAddressSet(address, TypeRelationId, domainoid); + + /* Clean up */ + table_close(rel, RowExclusiveLock); + return address; } @@ -2553,7 +2554,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint, domainoid = typenameTypeId(NULL, typename); /* Look up the domain in the type table */ - typrel = heap_open(TypeRelationId, RowExclusiveLock); + typrel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(domainoid)); if (!HeapTupleIsValid(tup)) @@ -2631,10 +2632,17 @@ AlterDomainAddConstraint(List *names, Node *newConstraint, if (!constr->skip_validation) validateDomainConstraint(domainoid, ccbin); + /* + * We must send out an sinval message for the domain, to ensure that any + * dependent plans get rebuilt. Since this command doesn't change the + * domain's pg_type row, that won't happen automatically; do it manually. + */ + CacheInvalidateHeapTuple(typrel, tup, NULL); + ObjectAddressSet(address, TypeRelationId, domainoid); /* Clean up */ - heap_close(typrel, RowExclusiveLock); + table_close(typrel, RowExclusiveLock); return address; } @@ -2652,16 +2660,15 @@ AlterDomainValidateConstraint(List *names, const char *constrName) Relation typrel; Relation conrel; HeapTuple tup; - Form_pg_constraint con = NULL; + Form_pg_constraint con; Form_pg_constraint copy_con; char *conbin; SysScanDesc scan; Datum val; - bool found = false; bool isnull; HeapTuple tuple; HeapTuple copyTuple; - ScanKeyData key; + ScanKeyData skey[3]; ObjectAddress address; /* Make a TypeName so we can use standard type lookup machinery */ @@ -2669,7 +2676,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName) domainoid = typenameTypeId(NULL, typename); /* Look up the domain in the type table */ - typrel = heap_open(TypeRelationId, AccessShareLock); + typrel = table_open(TypeRelationId, AccessShareLock); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(domainoid)); if (!HeapTupleIsValid(tup)) @@ -2681,30 +2688,32 @@ AlterDomainValidateConstraint(List *names, const char *constrName) /* * Find and check the target constraint */ - conrel = heap_open(ConstraintRelationId, RowExclusiveLock); - ScanKeyInit(&key, + conrel = table_open(ConstraintRelationId, RowExclusiveLock); + + ScanKeyInit(&skey[0], + Anum_pg_constraint_conrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(InvalidOid)); + ScanKeyInit(&skey[1], Anum_pg_constraint_contypid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(domainoid)); - scan = systable_beginscan(conrel, ConstraintTypidIndexId, - true, NULL, 1, &key); + ScanKeyInit(&skey[2], + Anum_pg_constraint_conname, + BTEqualStrategyNumber, F_NAMEEQ, + CStringGetDatum(constrName)); - while (HeapTupleIsValid(tuple = systable_getnext(scan))) - { - con = (Form_pg_constraint) GETSTRUCT(tuple); - if (strcmp(NameStr(con->conname), constrName) == 0) - { - found = true; - break; - } - } + scan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, + NULL, 3, skey); - if (!found) + /* There can be at most one matching row */ + if (!HeapTupleIsValid(tuple = systable_getnext(scan))) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("constraint \"%s\" of domain \"%s\" does not exist", constrName, TypeNameToString(typename)))); + con = (Form_pg_constraint) GETSTRUCT(tuple); if (con->contype != CONSTRAINT_CHECK) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -2716,7 +2725,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName) &isnull); if (isnull) elog(ERROR, "null conbin for constraint %u", - HeapTupleGetOid(tuple)); + con->oid); conbin = TextDatumGetCString(val); validateDomainConstraint(domainoid, conbin); @@ -2729,8 +2738,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName) copy_con->convalidated = true; CatalogTupleUpdate(conrel, ©Tuple->t_self, copyTuple); - InvokeObjectPostAlterHook(ConstraintRelationId, - HeapTupleGetOid(copyTuple), 0); + InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0); ObjectAddressSet(address, TypeRelationId, domainoid); @@ -2738,8 +2746,8 @@ AlterDomainValidateConstraint(List *names, const char *constrName) systable_endscan(scan); - heap_close(typrel, AccessShareLock); - heap_close(conrel, RowExclusiveLock); + table_close(typrel, AccessShareLock); + table_close(conrel, RowExclusiveLock); ReleaseSysCache(tup); @@ -2773,14 +2781,15 @@ validateDomainConstraint(Oid domainoid, char *ccbin) RelToCheck *rtc = (RelToCheck *) lfirst(rt); Relation testrel = rtc->rel; TupleDesc tupdesc = RelationGetDescr(testrel); - HeapScanDesc scan; - HeapTuple tuple; + TupleTableSlot *slot; + TableScanDesc scan; Snapshot snapshot; /* Scan all tuples in this relation */ snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(testrel, snapshot, 0, NULL); - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + scan = table_beginscan(testrel, snapshot, 0, NULL); + slot = table_slot_create(testrel, NULL); + while (table_scan_getnextslot(scan, ForwardScanDirection, slot)) { int i; @@ -2793,7 +2802,7 @@ validateDomainConstraint(Oid domainoid, char *ccbin) Datum conResult; Form_pg_attribute attr = TupleDescAttr(tupdesc, attnum - 1); - d = heap_getattr(tuple, attnum, tupdesc, &isNull); + d = slot_getattr(slot, attnum, &isNull); econtext->domainValue_datum = d; econtext->domainValue_isNull = isNull; @@ -2823,11 +2832,12 @@ validateDomainConstraint(Oid domainoid, char *ccbin) ResetExprContext(econtext); } - heap_endscan(scan); + ExecDropSingleTupleTableSlot(slot); + table_endscan(scan); UnregisterSnapshot(snapshot); /* Hold relation lock till commit (XXX bad for concurrency) */ - heap_close(testrel, NoLock); + table_close(testrel, NoLock); } FreeExecutorState(estate); @@ -2883,7 +2893,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode) * We scan pg_depend to find those things that depend on the domain. (We * assume we can ignore refobjsubid for a domain.) */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -2989,7 +2999,7 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode) rtc->rel = rel; rtc->natts = 0; rtc->atts = (int *) palloc(sizeof(int) * RelationGetNumberOfAttributes(rel)); - result = lcons(rtc, result); + result = lappend(result, rtc); } /* @@ -3043,11 +3053,11 @@ checkDomainOwner(HeapTuple tup) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("%s is not a domain", - format_type_be(HeapTupleGetOid(tup))))); + format_type_be(typTup->oid)))); /* Permission check: must own type */ - if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup)); + if (!pg_type_ownercheck(typTup->oid, GetUserId())) + aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); } /* @@ -3059,7 +3069,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, const char *domainName, ObjectAddress *constrAddr) { Node *expr; - char *ccsrc; char *ccbin; ParseState *pstate; CoerceToDomainValue *domVal; @@ -3072,7 +3081,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, { if (ConstraintNameIsUsed(CONSTRAINT_DOMAIN, domainOid, - domainNamespace, constr->conname)) ereport(ERROR, (errcode(ERRCODE_DUPLICATE_OBJECT), @@ -3134,12 +3142,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, */ ccbin = nodeToString(expr); - /* - * Deparse it to produce text for consrc. - */ - ccsrc = deparse_expression(expr, - NIL, false, false); - /* * Store the constraint in pg_constraint */ @@ -3169,7 +3171,6 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid, NULL, /* not an exclusion constraint */ expr, /* Tree form of check constraint */ ccbin, /* Binary form of check constraint */ - ccsrc, /* Source form of check constraint */ true, /* is local */ 0, /* inhcount */ false, /* connoinherit */ @@ -3234,7 +3235,7 @@ RenameType(RenameStmt *stmt) typeOid = typenameTypeId(NULL, typename); /* Look up the type in the type table */ - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tup)) @@ -3280,14 +3281,14 @@ RenameType(RenameStmt *stmt) * RenameRelationInternal will call RenameTypeInternal automatically. */ if (typTup->typtype == TYPTYPE_COMPOSITE) - RenameRelationInternal(typTup->typrelid, newTypeName, false); + RenameRelationInternal(typTup->typrelid, newTypeName, false, false); else RenameTypeInternal(typeOid, newTypeName, typTup->typnamespace); ObjectAddressSet(address, TypeRelationId, typeOid); /* Clean up */ - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -3307,7 +3308,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) AclResult aclresult; ObjectAddress address; - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -3367,8 +3368,8 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) if (!superuser()) { /* Otherwise, must be owner of the existing object */ - if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup)); + if (!pg_type_ownercheck(typTup->oid, GetUserId())) + aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid); /* Must be able to become new owner */ check_is_member_of_role(GetUserId(), newOwnerId); @@ -3388,7 +3389,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) ObjectAddressSet(address, TypeRelationId, typeOid); /* Clean up */ - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); return address; } @@ -3411,7 +3412,7 @@ AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry) HeapTuple tup; Form_pg_type typTup; - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tup)) @@ -3435,7 +3436,7 @@ AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry) InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); ReleaseSysCache(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -3457,7 +3458,7 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId) Datum aclDatum; bool isNull; - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tup)) @@ -3493,7 +3494,7 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId) AlterTypeOwnerInternal(typTup->typarray, newOwnerId); /* Clean up */ - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); } /* @@ -3598,7 +3599,7 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, if (object_address_present(&thisobj, objsMoved)) return InvalidOid; - rel = heap_open(TypeRelationId, RowExclusiveLock); + rel = table_open(TypeRelationId, RowExclusiveLock); tup = SearchSysCacheCopy1(TYPEOID, ObjectIdGetDatum(typeOid)); if (!HeapTupleIsValid(tup)) @@ -3659,13 +3660,13 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, { Relation classRel; - classRel = heap_open(RelationRelationId, RowExclusiveLock); + classRel = table_open(RelationRelationId, RowExclusiveLock); AlterRelationNamespaceInternal(classRel, typform->typrelid, oldNspOid, nspOid, false, objsMoved); - heap_close(classRel, RowExclusiveLock); + table_close(classRel, RowExclusiveLock); /* * Check for constraints associated with the composite type (we don't @@ -3698,7 +3699,7 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, heap_freetuple(tup); - heap_close(rel, RowExclusiveLock); + table_close(rel, RowExclusiveLock); add_exact_object_address(&thisobj, objsMoved); diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 71c5caa41b9..aab5aa855d2 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -3,7 +3,7 @@ * user.c * Commands for manipulating roles (formerly called users). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/commands/user.c @@ -13,8 +13,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/binary_upgrade.h" #include "catalog/catalog.h" @@ -37,7 +37,6 @@ #include "utils/fmgroids.h" #include "utils/syscache.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* Potentially set by pg_upgrade_support functions */ Oid binary_upgrade_next_pg_authid_oid = InvalidOid; @@ -50,11 +49,11 @@ int Password_encryption = PASSWORD_TYPE_MD5; check_password_hook_type check_password_hook = NULL; static void AddRoleMems(const char *rolename, Oid roleid, - List *memberSpecs, List *memberIds, - Oid grantorId, bool admin_opt); + List *memberSpecs, List *memberIds, + Oid grantorId, bool admin_opt); static void DelRoleMems(const char *rolename, Oid roleid, - List *memberSpecs, List *memberIds, - bool admin_opt); + List *memberSpecs, List *memberIds, + bool admin_opt); /* Check if current user has createrole privileges */ @@ -327,11 +326,20 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) stmt->role), errdetail("Role names starting with \"pg_\" are reserved."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for role names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(stmt->role, "regress_", 8) != 0) + elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\""); +#endif + /* * Check the pg_authid relation to be certain the role doesn't already * exist. */ - pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock); + pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock); pg_authid_dsc = RelationGetDescr(pg_authid_rel); if (OidIsValid(get_role_oid(stmt->role, true))) @@ -423,8 +431,6 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls); - tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls); - /* * pg_largeobject_metadata contains pg_authid.oid's, so we use the * binary-upgrade override. @@ -436,14 +442,23 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pg_authid OID value not set when in binary upgrade mode"))); - HeapTupleSetOid(tuple, binary_upgrade_next_pg_authid_oid); + roleid = binary_upgrade_next_pg_authid_oid; binary_upgrade_next_pg_authid_oid = InvalidOid; } + else + { + roleid = GetNewOidWithIndex(pg_authid_rel, AuthIdOidIndexId, + Anum_pg_authid_oid); + } + + new_record[Anum_pg_authid_oid - 1] = ObjectIdGetDatum(roleid); + + tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls); /* * Insert new record in the pg_authid table */ - roleid = CatalogTupleInsert(pg_authid_rel, tuple); + CatalogTupleInsert(pg_authid_rel, tuple); /* * Advance command counter so we can see new record; else tests in @@ -459,8 +474,9 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) { RoleSpec *oldrole = lfirst(item); HeapTuple oldroletup = get_rolespec_tuple(oldrole); - Oid oldroleid = HeapTupleGetOid(oldroletup); - char *oldrolename = NameStr(((Form_pg_authid) GETSTRUCT(oldroletup))->rolname); + Form_pg_authid oldroleform = (Form_pg_authid) GETSTRUCT(oldroletup); + Oid oldroleid = oldroleform->oid; + char *oldrolename = NameStr(oldroleform->rolname); AddRoleMems(oldrolename, oldroleid, list_make1(makeString(stmt->role)), @@ -487,7 +503,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt) /* * Close pg_authid, but keep lock till commit. */ - heap_close(pg_authid_rel, NoLock); + table_close(pg_authid_rel, NoLock); return roleid; } @@ -673,13 +689,13 @@ AlterRole(AlterRoleStmt *stmt) /* * Scan the pg_authid relation to be certain the user exists. */ - pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock); + pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock); pg_authid_dsc = RelationGetDescr(pg_authid_rel); tuple = get_rolespec_tuple(stmt->role); authform = (Form_pg_authid) GETSTRUCT(tuple); rolename = pstrdup(NameStr(authform->rolname)); - roleid = HeapTupleGetOid(tuple); + roleid = authform->oid; /* * To mess with a superuser you gotta be superuser; else you need @@ -873,7 +889,7 @@ AlterRole(AlterRoleStmt *stmt) /* * Close pg_authid, but keep lock till commit. */ - heap_close(pg_authid_rel, NoLock); + table_close(pg_authid_rel, NoLock); return roleid; } @@ -886,6 +902,7 @@ Oid AlterRoleSet(AlterRoleSetStmt *stmt) { HeapTuple roletuple; + Form_pg_authid roleform; Oid databaseid = InvalidOid; Oid roleid = InvalidOid; @@ -895,19 +912,20 @@ AlterRoleSet(AlterRoleSetStmt *stmt) "Cannot alter reserved roles."); roletuple = get_rolespec_tuple(stmt->role); - roleid = HeapTupleGetOid(roletuple); + roleform = (Form_pg_authid) GETSTRUCT(roletuple); + roleid = roleform->oid; /* * Obtain a lock on the role and make sure it didn't go away in the * meantime. */ - shdepLockAndCheckObject(AuthIdRelationId, HeapTupleGetOid(roletuple)); + shdepLockAndCheckObject(AuthIdRelationId, roleid); /* * To mess with a superuser you gotta be superuser; else you need * createrole, or just want to change your own settings */ - if (((Form_pg_authid) GETSTRUCT(roletuple))->rolsuper) + if (roleform->rolsuper) { if (!superuser()) ereport(ERROR, @@ -916,8 +934,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt) } else { - if (!have_createrole_privilege() && - HeapTupleGetOid(roletuple) != GetUserId()) + if (!have_createrole_privilege() && roleid != GetUserId()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied"))); @@ -978,8 +995,8 @@ DropRole(DropRoleStmt *stmt) * Scan the pg_authid relation to find the Oid of the role(s) to be * deleted. */ - pg_authid_rel = heap_open(AuthIdRelationId, RowExclusiveLock); - pg_auth_members_rel = heap_open(AuthMemRelationId, RowExclusiveLock); + pg_authid_rel = table_open(AuthIdRelationId, RowExclusiveLock); + pg_auth_members_rel = table_open(AuthMemRelationId, RowExclusiveLock); foreach(item, stmt->roles) { @@ -987,6 +1004,7 @@ DropRole(DropRoleStmt *stmt) char *role; HeapTuple tuple, tmp_tuple; + Form_pg_authid roleform; ScanKeyData scankey; char *detail; char *detail_log; @@ -1018,7 +1036,8 @@ DropRole(DropRoleStmt *stmt) continue; } - roleid = HeapTupleGetOid(tuple); + roleform = (Form_pg_authid) GETSTRUCT(tuple); + roleid = roleform->oid; if (roleid == GetUserId()) ereport(ERROR, @@ -1038,8 +1057,7 @@ DropRole(DropRoleStmt *stmt) * roles but not superuser roles. This is mainly to avoid the * scenario where you accidentally drop the last superuser. */ - if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper && - !superuser()) + if (roleform->rolsuper && !superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to drop superusers"))); @@ -1132,8 +1150,8 @@ DropRole(DropRoleStmt *stmt) /* * Now we can clean up; but keep locks until commit. */ - heap_close(pg_auth_members_rel, NoLock); - heap_close(pg_authid_rel, NoLock); + table_close(pg_auth_members_rel, NoLock); + table_close(pg_authid_rel, NoLock); } /* @@ -1156,7 +1174,7 @@ RenameRole(const char *oldname, const char *newname) ObjectAddress address; Form_pg_authid authform; - rel = heap_open(AuthIdRelationId, RowExclusiveLock); + rel = table_open(AuthIdRelationId, RowExclusiveLock); dsc = RelationGetDescr(rel); oldtuple = SearchSysCache1(AUTHNAME, CStringGetDatum(oldname)); @@ -1173,8 +1191,8 @@ RenameRole(const char *oldname, const char *newname) * effective userid, though. */ - roleid = HeapTupleGetOid(oldtuple); authform = (Form_pg_authid) GETSTRUCT(oldtuple); + roleid = authform->oid; if (roleid == GetSessionUserId()) ereport(ERROR, @@ -1203,6 +1221,15 @@ RenameRole(const char *oldname, const char *newname) newname), errdetail("Role names starting with \"pg_\" are reserved."))); + /* + * If built with appropriate switch, whine when regression-testing + * conventions for role names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(newname, "regress_", 8) != 0) + elog(WARNING, "roles created by regression test cases should have names starting with \"regress_\""); +#endif + /* make sure the new name doesn't exist */ if (SearchSysCacheExists1(AUTHNAME, CStringGetDatum(newname))) ereport(ERROR, @@ -1260,7 +1287,7 @@ RenameRole(const char *oldname, const char *newname) /* * Close pg_authid, but keep lock till commit. */ - heap_close(rel, NoLock); + table_close(rel, NoLock); return address; } @@ -1286,7 +1313,7 @@ GrantRole(GrantRoleStmt *stmt) grantee_ids = roleSpecsToIds(stmt->grantee_roles); /* AccessShareLock is enough since we aren't modifying pg_authid */ - pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock); + pg_authid_rel = table_open(AuthIdRelationId, AccessShareLock); /* * Step through all of the granted roles and add/remove entries for the @@ -1321,7 +1348,7 @@ GrantRole(GrantRoleStmt *stmt) /* * Close pg_authid, but keep lock till commit. */ - heap_close(pg_authid_rel, NoLock); + table_close(pg_authid_rel, NoLock); } /* @@ -1473,7 +1500,7 @@ AddRoleMems(const char *rolename, Oid roleid, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to set grantor"))); - pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock); + pg_authmem_rel = table_open(AuthMemRelationId, RowExclusiveLock); pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); forboth(specitem, memberSpecs, iditem, memberIds) @@ -1551,7 +1578,7 @@ AddRoleMems(const char *rolename, Oid roleid, /* * Close pg_authmem, but keep lock till commit. */ - heap_close(pg_authmem_rel, NoLock); + table_close(pg_authmem_rel, NoLock); } /* @@ -1602,7 +1629,7 @@ DelRoleMems(const char *rolename, Oid roleid, rolename))); } - pg_authmem_rel = heap_open(AuthMemRelationId, RowExclusiveLock); + pg_authmem_rel = table_open(AuthMemRelationId, RowExclusiveLock); pg_authmem_dsc = RelationGetDescr(pg_authmem_rel); forboth(specitem, memberSpecs, iditem, memberIds) @@ -1661,5 +1688,5 @@ DelRoleMems(const char *rolename, Oid roleid, /* * Close pg_authmem, but keep lock till commit. */ - heap_close(pg_authmem_rel, NoLock); + table_close(pg_authmem_rel, NoLock); } diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index d90cb9a9022..e154507ecd0 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -9,7 +9,7 @@ * in cluster.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,6 +28,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/namespace.h" @@ -35,6 +36,7 @@ #include "catalog/pg_inherits.h" #include "catalog/pg_namespace.h" #include "commands/cluster.h" +#include "commands/defrem.h" #include "commands/vacuum.h" #include "miscadmin.h" #include "nodes/makefuncs.h" @@ -50,7 +52,6 @@ #include "utils/memutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -68,14 +69,14 @@ static BufferAccessStrategy vac_strategy; /* non-export function prototypes */ -static List *expand_vacuum_rel(VacuumRelation *vrel); -static List *get_all_vacuum_rels(void); +static List *expand_vacuum_rel(VacuumRelation *vrel, int options); +static List *get_all_vacuum_rels(int options); static void vac_truncate_clog(TransactionId frozenXID, - MultiXactId minMulti, - TransactionId lastSaneFrozenXid, - MultiXactId lastSaneMinMulti); -static bool vacuum_rel(Oid relid, RangeVar *relation, int options, - VacuumParams *params); + MultiXactId minMulti, + TransactionId lastSaneFrozenXid, + MultiXactId lastSaneMinMulti); +static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params); +static VacOptTernaryValue get_vacopt_ternary_value(DefElem *def); /* * Primary entry point for manual VACUUM and ANALYZE commands @@ -84,20 +85,77 @@ static bool vacuum_rel(Oid relid, RangeVar *relation, int options, * happen in vacuum(). */ void -ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel) +ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel) { VacuumParams params; + bool verbose = false; + bool skip_locked = false; + bool analyze = false; + bool freeze = false; + bool full = false; + bool disable_page_skipping = false; + ListCell *lc; + + /* Set default value */ + params.index_cleanup = VACOPT_TERNARY_DEFAULT; + params.truncate = VACOPT_TERNARY_DEFAULT; + + /* Parse options list */ + foreach(lc, vacstmt->options) + { + DefElem *opt = (DefElem *) lfirst(lc); + + /* Parse common options for VACUUM and ANALYZE */ + if (strcmp(opt->defname, "verbose") == 0) + verbose = defGetBoolean(opt); + else if (strcmp(opt->defname, "skip_locked") == 0) + skip_locked = defGetBoolean(opt); + else if (!vacstmt->is_vacuumcmd) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized ANALYZE option \"%s\"", opt->defname), + parser_errposition(pstate, opt->location))); + + /* Parse options available on VACUUM */ + else if (strcmp(opt->defname, "analyze") == 0) + analyze = defGetBoolean(opt); + else if (strcmp(opt->defname, "freeze") == 0) + freeze = defGetBoolean(opt); + else if (strcmp(opt->defname, "full") == 0) + full = defGetBoolean(opt); + else if (strcmp(opt->defname, "disable_page_skipping") == 0) + disable_page_skipping = defGetBoolean(opt); + else if (strcmp(opt->defname, "index_cleanup") == 0) + params.index_cleanup = get_vacopt_ternary_value(opt); + else if (strcmp(opt->defname, "truncate") == 0) + params.truncate = get_vacopt_ternary_value(opt); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("unrecognized VACUUM option \"%s\"", opt->defname), + parser_errposition(pstate, opt->location))); + } + + /* Set vacuum options */ + params.options = + (vacstmt->is_vacuumcmd ? VACOPT_VACUUM : VACOPT_ANALYZE) | + (verbose ? VACOPT_VERBOSE : 0) | + (skip_locked ? VACOPT_SKIP_LOCKED : 0) | + (analyze ? VACOPT_ANALYZE : 0) | + (freeze ? VACOPT_FREEZE : 0) | + (full ? VACOPT_FULL : 0) | + (disable_page_skipping ? VACOPT_DISABLE_PAGE_SKIPPING : 0); /* sanity checks on options */ - Assert(vacstmt->options & (VACOPT_VACUUM | VACOPT_ANALYZE)); - Assert((vacstmt->options & VACOPT_VACUUM) || - !(vacstmt->options & (VACOPT_FULL | VACOPT_FREEZE))); - Assert(!(vacstmt->options & VACOPT_SKIPTOAST)); + Assert(params.options & (VACOPT_VACUUM | VACOPT_ANALYZE)); + Assert((params.options & VACOPT_VACUUM) || + !(params.options & (VACOPT_FULL | VACOPT_FREEZE))); + Assert(!(params.options & VACOPT_SKIPTOAST)); /* * Make sure VACOPT_ANALYZE is specified if any column lists are present. */ - if (!(vacstmt->options & VACOPT_ANALYZE)) + if (!(params.options & VACOPT_ANALYZE)) { ListCell *lc; @@ -116,7 +174,7 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel) * All freeze ages are zero if the FREEZE option is given; otherwise pass * them as -1 which means to use the default values. */ - if (vacstmt->options & VACOPT_FREEZE) + if (params.options & VACOPT_FREEZE) { params.freeze_min_age = 0; params.freeze_table_age = 0; @@ -138,14 +196,12 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel) params.log_min_duration = -1; /* Now go through the common routine */ - vacuum(vacstmt->options, vacstmt->rels, ¶ms, NULL, isTopLevel); + vacuum(vacstmt->rels, ¶ms, NULL, isTopLevel); } /* * Internal entry point for VACUUM and ANALYZE commands. * - * options is a bitmask of VacuumOption flags, indicating what to do. - * * relations, if not NIL, is a list of VacuumRelation to process; otherwise, * we process all relevant tables in the database. For each VacuumRelation, * if a valid OID is supplied, the table with that OID is what to process; @@ -163,7 +219,7 @@ ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel) * memory context that will not disappear at transaction commit. */ void -vacuum(int options, List *relations, VacuumParams *params, +vacuum(List *relations, VacuumParams *params, BufferAccessStrategy bstrategy, bool isTopLevel) { static bool in_vacuum = false; @@ -174,7 +230,7 @@ vacuum(int options, List *relations, VacuumParams *params, Assert(params != NULL); - stmttype = (options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE"; + stmttype = (params->options & VACOPT_VACUUM) ? "VACUUM" : "ANALYZE"; /* * We cannot run VACUUM inside a user transaction block; if we were inside @@ -184,7 +240,7 @@ vacuum(int options, List *relations, VacuumParams *params, * * ANALYZE (without VACUUM) can run either way. */ - if (options & VACOPT_VACUUM) + if (params->options & VACOPT_VACUUM) { PreventInTransactionBlock(isTopLevel, stmttype); in_outer_xact = false; @@ -206,8 +262,8 @@ vacuum(int options, List *relations, VacuumParams *params, /* * Sanity check DISABLE_PAGE_SKIPPING option. */ - if ((options & VACOPT_FULL) != 0 && - (options & VACOPT_DISABLE_PAGE_SKIPPING) != 0) + if ((params->options & VACOPT_FULL) != 0 && + (params->options & VACOPT_DISABLE_PAGE_SKIPPING) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL"))); @@ -216,7 +272,7 @@ vacuum(int options, List *relations, VacuumParams *params, * Send info about dead objects to the statistics collector, unless we are * in autovacuum --- autovacuum.c does this for itself. */ - if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess()) + if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess()) pgstat_vacuum_stat(); /* @@ -257,7 +313,7 @@ vacuum(int options, List *relations, VacuumParams *params, List *sublist; MemoryContext old_context; - sublist = expand_vacuum_rel(vrel); + sublist = expand_vacuum_rel(vrel, params->options); old_context = MemoryContextSwitchTo(vac_context); newrels = list_concat(newrels, sublist); MemoryContextSwitchTo(old_context); @@ -265,7 +321,7 @@ vacuum(int options, List *relations, VacuumParams *params, relations = newrels; } else - relations = get_all_vacuum_rels(); + relations = get_all_vacuum_rels(params->options); /* * Decide whether we need to start/commit our own transactions. @@ -281,11 +337,11 @@ vacuum(int options, List *relations, VacuumParams *params, * transaction block, and also in an autovacuum worker, use own * transactions so we can release locks sooner. */ - if (options & VACOPT_VACUUM) + if (params->options & VACOPT_VACUUM) use_own_xacts = true; else { - Assert(options & VACOPT_ANALYZE); + Assert(params->options & VACOPT_ANALYZE); if (IsAutoVacuumWorkerProcess()) use_own_xacts = true; else if (in_outer_xact) @@ -335,13 +391,13 @@ vacuum(int options, List *relations, VacuumParams *params, { VacuumRelation *vrel = lfirst_node(VacuumRelation, cur); - if (options & VACOPT_VACUUM) + if (params->options & VACOPT_VACUUM) { - if (!vacuum_rel(vrel->oid, vrel->relation, options, params)) + if (!vacuum_rel(vrel->oid, vrel->relation, params)) continue; } - if (options & VACOPT_ANALYZE) + if (params->options & VACOPT_ANALYZE) { /* * If using separate xacts, start one for analyze. Otherwise, @@ -354,7 +410,7 @@ vacuum(int options, List *relations, VacuumParams *params, PushActiveSnapshot(GetTransactionSnapshot()); } - analyze_rel(vrel->oid, vrel->relation, options, params, + analyze_rel(vrel->oid, vrel->relation, params, vrel->va_cols, in_outer_xact, vac_strategy); if (use_own_xacts) @@ -362,6 +418,15 @@ vacuum(int options, List *relations, VacuumParams *params, PopActiveSnapshot(); CommitTransactionCommand(); } + else + { + /* + * If we're not using separate xacts, better separate the + * ANALYZE actions with CCIs. This avoids trouble if user + * says "ANALYZE t, t". + */ + CommandCounterIncrement(); + } } } } @@ -390,7 +455,7 @@ vacuum(int options, List *relations, VacuumParams *params, StartTransactionCommand(); } - if ((options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess()) + if ((params->options & VACOPT_VACUUM) && !IsAutoVacuumWorkerProcess()) { /* * Update pg_database.datfrozenxid, and truncate pg_xact if possible. @@ -408,6 +473,185 @@ vacuum(int options, List *relations, VacuumParams *params, vac_context = NULL; } +/* + * Check if a given relation can be safely vacuumed or analyzed. If the + * user is not the relation owner, issue a WARNING log message and return + * false to let the caller decide what to do with this relation. This + * routine is used to decide if a relation can be processed for VACUUM or + * ANALYZE. + */ +bool +vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, int options) +{ + char *relname; + + Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); + + /* + * Check permissions. + * + * We allow the user to vacuum or analyze a table if he is superuser, the + * table owner, or the database owner (but in the latter case, only if + * it's not a shared relation). pg_class_ownercheck includes the + * superuser case. + * + * Note we choose to treat permissions failure as a WARNING and keep + * trying to vacuum or analyze the rest of the DB --- is this appropriate? + */ + if (pg_class_ownercheck(relid, GetUserId()) || + (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !reltuple->relisshared)) + return true; + + relname = NameStr(reltuple->relname); + + if ((options & VACOPT_VACUUM) != 0) + { + if (reltuple->relisshared) + ereport(WARNING, + (errmsg("skipping \"%s\" --- only superuser can vacuum it", + relname))); + else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE) + ereport(WARNING, + (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it", + relname))); + else + ereport(WARNING, + (errmsg("skipping \"%s\" --- only table or database owner can vacuum it", + relname))); + + /* + * For VACUUM ANALYZE, both logs could show up, but just generate + * information for VACUUM as that would be the first one to be + * processed. + */ + return false; + } + + if ((options & VACOPT_ANALYZE) != 0) + { + if (reltuple->relisshared) + ereport(WARNING, + (errmsg("skipping \"%s\" --- only superuser can analyze it", + relname))); + else if (reltuple->relnamespace == PG_CATALOG_NAMESPACE) + ereport(WARNING, + (errmsg("skipping \"%s\" --- only superuser or database owner can analyze it", + relname))); + else + ereport(WARNING, + (errmsg("skipping \"%s\" --- only table or database owner can analyze it", + relname))); + } + + return false; +} + + +/* + * vacuum_open_relation + * + * This routine is used for attempting to open and lock a relation which + * is going to be vacuumed or analyzed. If the relation cannot be opened + * or locked, a log is emitted if possible. + */ +Relation +vacuum_open_relation(Oid relid, RangeVar *relation, int options, + bool verbose, LOCKMODE lmode) +{ + Relation onerel; + bool rel_lock = true; + int elevel; + + Assert((options & (VACOPT_VACUUM | VACOPT_ANALYZE)) != 0); + + /* + * Open the relation and get the appropriate lock on it. + * + * There's a race condition here: the relation may have gone away since + * the last time we saw it. If so, we don't need to vacuum or analyze it. + * + * If we've been asked not to wait for the relation lock, acquire it first + * in non-blocking mode, before calling try_relation_open(). + */ + if (!(options & VACOPT_SKIP_LOCKED)) + onerel = try_relation_open(relid, lmode); + else if (ConditionalLockRelationOid(relid, lmode)) + onerel = try_relation_open(relid, NoLock); + else + { + onerel = NULL; + rel_lock = false; + } + + /* if relation is opened, leave */ + if (onerel) + return onerel; + + /* + * Relation could not be opened, hence generate if possible a log + * informing on the situation. + * + * If the RangeVar is not defined, we do not have enough information to + * provide a meaningful log statement. Chances are that the caller has + * intentionally not provided this information so that this logging is + * skipped, anyway. + */ + if (relation == NULL) + return NULL; + + /* + * Determine the log level. + * + * For manual VACUUM or ANALYZE, we emit a WARNING to match the log + * statements in the permission checks; otherwise, only log if the caller + * so requested. + */ + if (!IsAutoVacuumWorkerProcess()) + elevel = WARNING; + else if (verbose) + elevel = LOG; + else + return NULL; + + if ((options & VACOPT_VACUUM) != 0) + { + if (!rel_lock) + ereport(elevel, + (errcode(ERRCODE_LOCK_NOT_AVAILABLE), + errmsg("skipping vacuum of \"%s\" --- lock not available", + relation->relname))); + else + ereport(elevel, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("skipping vacuum of \"%s\" --- relation no longer exists", + relation->relname))); + + /* + * For VACUUM ANALYZE, both logs could show up, but just generate + * information for VACUUM as that would be the first one to be + * processed. + */ + return NULL; + } + + if ((options & VACOPT_ANALYZE) != 0) + { + if (!rel_lock) + ereport(elevel, + (errcode(ERRCODE_LOCK_NOT_AVAILABLE), + errmsg("skipping analyze of \"%s\" --- lock not available", + relation->relname))); + else + ereport(elevel, + (errcode(ERRCODE_UNDEFINED_TABLE), + errmsg("skipping analyze of \"%s\" --- relation no longer exists", + relation->relname))); + } + + return NULL; +} + + /* * Given a VacuumRelation, fill in the table OID if it wasn't specified, * and optionally add VacuumRelations for partitions of the table. @@ -423,7 +667,7 @@ vacuum(int options, List *relations, VacuumParams *params, * are made in vac_context. */ static List * -expand_vacuum_rel(VacuumRelation *vrel) +expand_vacuum_rel(VacuumRelation *vrel, int options) { List *vacrels = NIL; MemoryContext oldcontext; @@ -442,31 +686,67 @@ expand_vacuum_rel(VacuumRelation *vrel) HeapTuple tuple; Form_pg_class classForm; bool include_parts; + int rvr_opts; + + /* + * Since autovacuum workers supply OIDs when calling vacuum(), no + * autovacuum worker should reach this code. + */ + Assert(!IsAutoVacuumWorkerProcess()); /* * We transiently take AccessShareLock to protect the syscache lookup * below, as well as find_all_inheritors's expectation that the caller * holds some lock on the starting relation. */ - relid = RangeVarGetRelid(vrel->relation, AccessShareLock, false); + rvr_opts = (options & VACOPT_SKIP_LOCKED) ? RVR_SKIP_LOCKED : 0; + relid = RangeVarGetRelidExtended(vrel->relation, + AccessShareLock, + rvr_opts, + NULL, NULL); /* - * Make a returnable VacuumRelation for this rel. + * If the lock is unavailable, emit the same log statement that + * vacuum_rel() and analyze_rel() would. */ - oldcontext = MemoryContextSwitchTo(vac_context); - vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, - relid, - vrel->va_cols)); - MemoryContextSwitchTo(oldcontext); + if (!OidIsValid(relid)) + { + if (options & VACOPT_VACUUM) + ereport(WARNING, + (errcode(ERRCODE_LOCK_NOT_AVAILABLE), + errmsg("skipping vacuum of \"%s\" --- lock not available", + vrel->relation->relname))); + else + ereport(WARNING, + (errcode(ERRCODE_LOCK_NOT_AVAILABLE), + errmsg("skipping analyze of \"%s\" --- lock not available", + vrel->relation->relname))); + return vacrels; + } /* - * To check whether the relation is a partitioned table, fetch its - * syscache entry. + * To check whether the relation is a partitioned table and its + * ownership, fetch its syscache entry. */ tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relid); classForm = (Form_pg_class) GETSTRUCT(tuple); + + /* + * Make a returnable VacuumRelation for this rel if user is a proper + * owner. + */ + if (vacuum_is_relation_owner(relid, classForm, options)) + { + oldcontext = MemoryContextSwitchTo(vac_context); + vacrels = lappend(vacrels, makeVacuumRelation(vrel->relation, + relid, + vrel->va_cols)); + MemoryContextSwitchTo(oldcontext); + } + + include_parts = (classForm->relkind == RELKIND_PARTITIONED_TABLE); ReleaseSysCache(tuple); @@ -475,7 +755,9 @@ expand_vacuum_rel(VacuumRelation *vrel) * the list returned by find_all_inheritors() includes the passed-in * OID, so we have to skip that. There's no point in taking locks on * the individual partitions yet, and doing so would just add - * unnecessary deadlock risk. + * unnecessary deadlock risk. For this last reason we do not check + * yet the ownership of the partitions, which get added to the list to + * process. Ownership will be checked later on anyway. */ if (include_parts) { @@ -524,21 +806,26 @@ expand_vacuum_rel(VacuumRelation *vrel) * the current database. The list is built in vac_context. */ static List * -get_all_vacuum_rels(void) +get_all_vacuum_rels(int options) { List *vacrels = NIL; Relation pgclass; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; - pgclass = heap_open(RelationRelationId, AccessShareLock); + pgclass = table_open(RelationRelationId, AccessShareLock); - scan = heap_beginscan_catalog(pgclass, 0, NULL); + scan = table_beginscan_catalog(pgclass, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); MemoryContext oldcontext; + Oid relid = classForm->oid; + + /* check permissions of relation */ + if (!vacuum_is_relation_owner(relid, classForm, options)) + continue; /* * We include partitioned tables here; depending on which operation is @@ -557,26 +844,26 @@ get_all_vacuum_rels(void) */ oldcontext = MemoryContextSwitchTo(vac_context); vacrels = lappend(vacrels, makeVacuumRelation(NULL, - HeapTupleGetOid(tuple), + relid, NIL)); MemoryContextSwitchTo(oldcontext); } - heap_endscan(scan); - heap_close(pgclass, AccessShareLock); + table_endscan(scan); + table_close(pgclass, AccessShareLock); return vacrels; } /* - * vacuum_set_xid_limits() -- compute oldest-Xmin and freeze cutoff points + * vacuum_set_xid_limits() -- compute oldestXmin and freeze cutoff points * * The output parameters are: * - oldestXmin is the cutoff value used to distinguish whether tuples are * DEAD or RECENTLY_DEAD (see HeapTupleSatisfiesVacuum). * - freezeLimit is the Xid below which all Xids are replaced by * FrozenTransactionId during vacuum. - * - xidFullScanLimit (computed from table_freeze_age parameter) + * - xidFullScanLimit (computed from freeze_table_age parameter) * represents a minimum Xid value; a table whose relfrozenxid is older than * this will have a full-table vacuum applied to it, to freeze tuples across * the whole table. Vacuuming a table younger than this value can use a @@ -874,7 +1161,7 @@ vac_update_relstats(Relation relation, Form_pg_class pgcform; bool dirty; - rd = heap_open(RelationRelationId, RowExclusiveLock); + rd = table_open(RelationRelationId, RowExclusiveLock); /* Fetch a copy of the tuple to scribble on */ ctup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relid)); @@ -965,7 +1252,7 @@ vac_update_relstats(Relation relation, if (dirty) heap_inplace_update(rd, ctup); - heap_close(rd, RowExclusiveLock); + table_close(rd, RowExclusiveLock); } @@ -1028,7 +1315,7 @@ vac_update_datfrozenxid(void) * We must seqscan pg_class to find the minimum Xid, because there is no * index that can help us here. */ - relation = heap_open(RelationRelationId, AccessShareLock); + relation = table_open(RelationRelationId, AccessShareLock); scan = systable_beginscan(relation, InvalidOid, false, NULL, 0, NULL); @@ -1039,41 +1326,66 @@ vac_update_datfrozenxid(void) /* * Only consider relations able to hold unfrozen XIDs (anything else - * should have InvalidTransactionId in relfrozenxid anyway.) + * should have InvalidTransactionId in relfrozenxid anyway). */ if (classForm->relkind != RELKIND_RELATION && classForm->relkind != RELKIND_MATVIEW && classForm->relkind != RELKIND_TOASTVALUE) + { + Assert(!TransactionIdIsValid(classForm->relfrozenxid)); + Assert(!MultiXactIdIsValid(classForm->relminmxid)); continue; - - Assert(TransactionIdIsNormal(classForm->relfrozenxid)); - Assert(MultiXactIdIsValid(classForm->relminmxid)); + } /* + * Some table AMs might not need per-relation xid / multixid horizons. + * It therefore seems reasonable to allow relfrozenxid and relminmxid + * to not be set (i.e. set to their respective Invalid*Id) + * independently. Thus validate and compute horizon for each only if + * set. + * * If things are working properly, no relation should have a * relfrozenxid or relminmxid that is "in the future". However, such * cases have been known to arise due to bugs in pg_upgrade. If we * see any entries that are "in the future", chicken out and don't do - * anything. This ensures we won't truncate clog before those - * relations have been scanned and cleaned up. + * anything. This ensures we won't truncate clog & multixact SLRUs + * before those relations have been scanned and cleaned up. */ - if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid) || - MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid)) + + if (TransactionIdIsValid(classForm->relfrozenxid)) { - bogus = true; - break; + Assert(TransactionIdIsNormal(classForm->relfrozenxid)); + + /* check for values in the future */ + if (TransactionIdPrecedes(lastSaneFrozenXid, classForm->relfrozenxid)) + { + bogus = true; + break; + } + + /* determine new horizon */ + if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid)) + newFrozenXid = classForm->relfrozenxid; } - if (TransactionIdPrecedes(classForm->relfrozenxid, newFrozenXid)) - newFrozenXid = classForm->relfrozenxid; + if (MultiXactIdIsValid(classForm->relminmxid)) + { + /* check for values in the future */ + if (MultiXactIdPrecedes(lastSaneMinMulti, classForm->relminmxid)) + { + bogus = true; + break; + } - if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti)) - newMinMulti = classForm->relminmxid; + /* determine new horizon */ + if (MultiXactIdPrecedes(classForm->relminmxid, newMinMulti)) + newMinMulti = classForm->relminmxid; + } } /* we're done with pg_class */ systable_endscan(scan); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* chicken out if bogus data found */ if (bogus) @@ -1083,7 +1395,7 @@ vac_update_datfrozenxid(void) Assert(MultiXactIdIsValid(newMinMulti)); /* Now fetch the pg_database tuple we need to update. */ - relation = heap_open(DatabaseRelationId, RowExclusiveLock); + relation = table_open(DatabaseRelationId, RowExclusiveLock); /* Fetch a copy of the tuple to scribble on */ tuple = SearchSysCacheCopy1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); @@ -1121,7 +1433,7 @@ vac_update_datfrozenxid(void) heap_inplace_update(relation, tuple); heap_freetuple(tuple); - heap_close(relation, RowExclusiveLock); + table_close(relation, RowExclusiveLock); /* * If we were able to advance datfrozenxid or datminmxid, see if we can @@ -1159,7 +1471,7 @@ vac_truncate_clog(TransactionId frozenXID, { TransactionId nextXID = ReadNewTransactionId(); Relation relation; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tuple; Oid oldestxid_datoid; Oid minmulti_datoid; @@ -1188,9 +1500,9 @@ vac_truncate_clog(TransactionId frozenXID, * worst possible outcome is that pg_xact is not truncated as aggressively * as it could be. */ - relation = heap_open(DatabaseRelationId, AccessShareLock); + relation = table_open(DatabaseRelationId, AccessShareLock); - scan = heap_beginscan_catalog(relation, 0, NULL); + scan = table_beginscan_catalog(relation, 0, NULL); while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { @@ -1219,19 +1531,19 @@ vac_truncate_clog(TransactionId frozenXID, else if (TransactionIdPrecedes(datfrozenxid, frozenXID)) { frozenXID = datfrozenxid; - oldestxid_datoid = HeapTupleGetOid(tuple); + oldestxid_datoid = dbform->oid; } if (MultiXactIdPrecedes(datminmxid, minMulti)) { minMulti = datminmxid; - minmulti_datoid = HeapTupleGetOid(tuple); + minmulti_datoid = dbform->oid; } } - heap_endscan(scan); + table_endscan(scan); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* * Do not truncate CLOG if we seem to have suffered wraparound already; @@ -1298,7 +1610,7 @@ vac_truncate_clog(TransactionId frozenXID, * At entry and exit, we are not inside a transaction. */ static bool -vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) +vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params) { LOCKMODE lmode; Relation onerel; @@ -1307,7 +1619,6 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) Oid save_userid; int save_sec_context; int save_nestlevel; - bool rel_lock = true; Assert(params != NULL); @@ -1320,7 +1631,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) */ PushActiveSnapshot(GetTransactionSnapshot()); - if (!(options & VACOPT_FULL)) + if (!(params->options & VACOPT_FULL)) { /* * In lazy vacuum, we can set the PROC_IN_VACUUM flag, which lets @@ -1360,100 +1671,33 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) * vacuum, but just ShareUpdateExclusiveLock for concurrent vacuum. Either * way, we can be sure that no other backend is vacuuming the same table. */ - lmode = (options & VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock; + lmode = (params->options & VACOPT_FULL) ? + AccessExclusiveLock : ShareUpdateExclusiveLock; - /* - * Open the relation and get the appropriate lock on it. - * - * There's a race condition here: the rel may have gone away since the - * last time we saw it. If so, we don't need to vacuum it. - * - * If we've been asked not to wait for the relation lock, acquire it first - * in non-blocking mode, before calling try_relation_open(). - */ - if (!(options & VACOPT_NOWAIT)) - onerel = try_relation_open(relid, lmode); - else if (ConditionalLockRelationOid(relid, lmode)) - onerel = try_relation_open(relid, NoLock); - else - { - onerel = NULL; - rel_lock = false; - } + /* open the relation and get the appropriate lock on it */ + onerel = vacuum_open_relation(relid, relation, params->options, + params->log_min_duration >= 0, lmode); - /* - * If we failed to open or lock the relation, emit a log message before - * exiting. - */ + /* leave if relation could not be opened or locked */ if (!onerel) { - int elevel = 0; - - /* - * Determine the log level. - * - * If the RangeVar is not defined, we do not have enough information - * to provide a meaningful log statement. Chances are that - * vacuum_rel's caller has intentionally not provided this information - * so that this logging is skipped, anyway. - * - * Otherwise, for autovacuum logs, we emit a LOG if - * log_autovacuum_min_duration is not disabled. For manual VACUUM, we - * emit a WARNING to match the log statements in the permission - * checks. - */ - if (relation != NULL) - { - if (!IsAutoVacuumWorkerProcess()) - elevel = WARNING; - else if (params->log_min_duration >= 0) - elevel = LOG; - } - - if (elevel != 0) - { - if (!rel_lock) - ereport(elevel, - (errcode(ERRCODE_LOCK_NOT_AVAILABLE), - errmsg("skipping vacuum of \"%s\" --- lock not available", - relation->relname))); - else - ereport(elevel, - (errcode(ERRCODE_UNDEFINED_TABLE), - errmsg("skipping vacuum of \"%s\" --- relation no longer exists", - relation->relname))); - } - PopActiveSnapshot(); CommitTransactionCommand(); return false; } /* - * Check permissions. - * - * We allow the user to vacuum a table if he is superuser, the table - * owner, or the database owner (but in the latter case, only if it's not - * a shared relation). pg_class_ownercheck includes the superuser case. - * - * Note we choose to treat permissions failure as a WARNING and keep - * trying to vacuum the rest of the DB --- is this appropriate? + * Check if relation needs to be skipped based on ownership. This check + * happens also when building the relation list to vacuum for a manual + * operation, and needs to be done additionally here as VACUUM could + * happen across multiple transactions where relation ownership could have + * changed in-between. Make sure to only generate logs for VACUUM in this + * case. */ - if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) || - (pg_database_ownercheck(MyDatabaseId, GetUserId()) && !onerel->rd_rel->relisshared))) + if (!vacuum_is_relation_owner(RelationGetRelid(onerel), + onerel->rd_rel, + params->options & VACOPT_VACUUM)) { - if (onerel->rd_rel->relisshared) - ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser can vacuum it", - RelationGetRelationName(onerel)))); - else if (onerel->rd_rel->relnamespace == PG_CATALOG_NAMESPACE) - ereport(WARNING, - (errmsg("skipping \"%s\" --- only superuser or database owner can vacuum it", - RelationGetRelationName(onerel)))); - else - ereport(WARNING, - (errmsg("skipping \"%s\" --- only table or database owner can vacuum it", - RelationGetRelationName(onerel)))); relation_close(onerel, lmode); PopActiveSnapshot(); CommitTransactionCommand(); @@ -1519,12 +1763,32 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) onerelid = onerel->rd_lockInfo.lockRelId; LockRelationIdForSession(&onerelid, lmode); + /* Set index cleanup option based on reloptions if not yet */ + if (params->index_cleanup == VACOPT_TERNARY_DEFAULT) + { + if (onerel->rd_options == NULL || + ((StdRdOptions *) onerel->rd_options)->vacuum_index_cleanup) + params->index_cleanup = VACOPT_TERNARY_ENABLED; + else + params->index_cleanup = VACOPT_TERNARY_DISABLED; + } + + /* Set truncate option based on reloptions if not yet */ + if (params->truncate == VACOPT_TERNARY_DEFAULT) + { + if (onerel->rd_options == NULL || + ((StdRdOptions *) onerel->rd_options)->vacuum_truncate) + params->truncate = VACOPT_TERNARY_ENABLED; + else + params->truncate = VACOPT_TERNARY_DISABLED; + } + /* * Remember the relation's TOAST relation for later, if the caller asked * us to process it. In VACUUM FULL, though, the toast table is * automatically rebuilt by cluster_rel so we shouldn't recurse to it. */ - if (!(options & VACOPT_SKIPTOAST) && !(options & VACOPT_FULL)) + if (!(params->options & VACOPT_SKIPTOAST) && !(params->options & VACOPT_FULL)) toast_relid = onerel->rd_rel->reltoastrelid; else toast_relid = InvalidOid; @@ -1543,18 +1807,22 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) /* * Do the actual work --- either FULL or "lazy" vacuum */ - if (options & VACOPT_FULL) + if (params->options & VACOPT_FULL) { + int cluster_options = 0; + /* close relation before vacuuming, but hold lock until commit */ relation_close(onerel, NoLock); onerel = NULL; + if ((params->options & VACOPT_VERBOSE) != 0) + cluster_options |= CLUOPT_VERBOSE; + /* VACUUM FULL is now a variant of CLUSTER; see cluster.c */ - cluster_rel(relid, InvalidOid, false, - (options & VACOPT_VERBOSE) != 0); + cluster_rel(relid, InvalidOid, cluster_options); } else - lazy_vacuum_rel(onerel, options, params, vac_strategy); + table_relation_vacuum(onerel, params, vac_strategy); /* Roll back any GUC changes executed by index functions */ AtEOXact_GUC(false, save_nestlevel); @@ -1580,7 +1848,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) * totally unimportant for toast relations. */ if (toast_relid != InvalidOid) - vacuum_rel(toast_relid, NULL, options, params); + vacuum_rel(toast_relid, NULL, params); /* * Now release the session-level lock on the master table. @@ -1597,7 +1865,7 @@ vacuum_rel(Oid relid, RangeVar *relation, int options, VacuumParams *params) * specified kind of lock on each. Return an array of Relation pointers for * the indexes into *Irel, and the number of indexes into *nindexes. * - * We consider an index vacuumable if it is marked insertable (IndexIsReady). + * We consider an index vacuumable if it is marked insertable (indisready). * If it isn't, probably a CREATE INDEX CONCURRENTLY command failed early in * execution, and what we have is too corrupt to be processable. We will * vacuum even if the index isn't indisvalid; this is important because in a @@ -1632,7 +1900,7 @@ vac_open_indexes(Relation relation, LOCKMODE lockmode, Relation indrel; indrel = index_open(indexoid, lockmode); - if (IndexIsReady(indrel->rd_index)) + if (indrel->rd_index->indisready) (*Irel)[i++] = indrel; else index_close(indrel, lockmode); @@ -1678,13 +1946,13 @@ vacuum_delay_point(void) if (VacuumCostActive && !InterruptPending && VacuumCostBalance >= VacuumCostLimit) { - int msec; + double msec; msec = VacuumCostDelay * VacuumCostBalance / VacuumCostLimit; if (msec > VacuumCostDelay * 4) msec = VacuumCostDelay * 4; - pg_usleep(msec * 1000L); + pg_usleep((long) (msec * 1000)); VacuumCostBalance = 0; @@ -1695,3 +1963,15 @@ vacuum_delay_point(void) CHECK_FOR_INTERRUPTS(); } } + +/* + * A wrapper function of defGetBoolean(). + * + * This function returns VACOPT_TERNARY_ENABLED and VACOPT_TERNARY_DISABLED + * instead of true and false. + */ +static VacOptTernaryValue +get_vacopt_ternary_value(DefElem *def) +{ + return defGetBoolean(def) ? VACOPT_TERNARY_ENABLED : VACOPT_TERNARY_DISABLED; +} diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 9a754dae3fd..1119e21d55b 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -4,7 +4,7 @@ * Routines for handling specialized SET variables. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -522,32 +522,9 @@ check_transaction_read_only(bool *newval, void **extra, GucSource source) * As in check_transaction_read_only, allow it if not inside a transaction. */ bool -check_XactIsoLevel(char **newval, void **extra, GucSource source) +check_XactIsoLevel(int *newval, void **extra, GucSource source) { - int newXactIsoLevel; - - if (strcmp(*newval, "serializable") == 0) - { - newXactIsoLevel = XACT_SERIALIZABLE; - } - else if (strcmp(*newval, "repeatable read") == 0) - { - newXactIsoLevel = XACT_REPEATABLE_READ; - } - else if (strcmp(*newval, "read committed") == 0) - { - newXactIsoLevel = XACT_READ_COMMITTED; - } - else if (strcmp(*newval, "read uncommitted") == 0) - { - newXactIsoLevel = XACT_READ_UNCOMMITTED; - } - else if (strcmp(*newval, "default") == 0) - { - newXactIsoLevel = DefaultXactIsoLevel; - } - else - return false; + int newXactIsoLevel = *newval; if (newXactIsoLevel != XactIsoLevel && IsTransactionState()) { @@ -574,39 +551,9 @@ check_XactIsoLevel(char **newval, void **extra, GucSource source) } } - *extra = malloc(sizeof(int)); - if (!*extra) - return false; - *((int *) *extra) = newXactIsoLevel; - return true; } -void -assign_XactIsoLevel(const char *newval, void *extra) -{ - XactIsoLevel = *((int *) extra); -} - -const char * -show_XactIsoLevel(void) -{ - /* We need this because we don't want to show "default". */ - switch (XactIsoLevel) - { - case XACT_READ_UNCOMMITTED: - return "read uncommitted"; - case XACT_READ_COMMITTED: - return "read committed"; - case XACT_REPEATABLE_READ: - return "repeatable read"; - case XACT_SERIALIZABLE: - return "serializable"; - default: - return "bogus"; - } -} - /* * SET TRANSACTION [NOT] DEFERRABLE */ @@ -797,6 +744,7 @@ bool check_session_authorization(char **newval, void **extra, GucSource source) { HeapTuple roleTup; + Form_pg_authid roleform; Oid roleid; bool is_superuser; role_auth_extra *myextra; @@ -823,8 +771,9 @@ check_session_authorization(char **newval, void **extra, GucSource source) return false; } - roleid = HeapTupleGetOid(roleTup); - is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper; + roleform = (Form_pg_authid) GETSTRUCT(roleTup); + roleid = roleform->oid; + is_superuser = roleform->rolsuper; ReleaseSysCache(roleTup); @@ -868,6 +817,7 @@ check_role(char **newval, void **extra, GucSource source) Oid roleid; bool is_superuser; role_auth_extra *myextra; + Form_pg_authid roleform; if (strcmp(*newval, "none") == 0) { @@ -895,8 +845,9 @@ check_role(char **newval, void **extra, GucSource source) return false; } - roleid = HeapTupleGetOid(roleTup); - is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper; + roleform = (Form_pg_authid) GETSTRUCT(roleTup); + roleid = roleform->oid; + is_superuser = roleform->rolsuper; ReleaseSysCache(roleTup); diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 7d4511c585b..bea890f177a 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -3,7 +3,7 @@ * view.c * use rewrite rules to construct views * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,7 +14,7 @@ */ #include "postgres.h" -#include "access/heapam.h" +#include "access/relation.h" #include "access/xact.h" #include "catalog/namespace.h" #include "commands/defrem.h" @@ -38,29 +38,13 @@ static void checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc); -/*--------------------------------------------------------------------- - * Validator for "check_option" reloption on views. The allowed values - * are "local" and "cascaded". - */ -void -validateWithCheckOption(const char *value) -{ - if (value == NULL || - (strcmp(value, "local") != 0 && - strcmp(value, "cascaded") != 0)) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for \"check_option\" option"), - errdetail("Valid values are \"local\" and \"cascaded\"."))); - } -} - /*--------------------------------------------------------------------- * DefineVirtualRelation * * Create a view relation and use the rules system to store the query * for the view. + * + * EventTriggerAlterTableStart must have been called already. *--------------------------------------------------------------------- */ static ObjectAddress @@ -109,11 +93,6 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, } } - if (attrList == NIL) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TABLE_DEFINITION), - errmsg("view must have at least one column"))); - /* * Look up, check permissions on, and lock the creation namespace; also * check for a preexisting view with the same name. This will also set @@ -186,6 +165,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, atcmds = lappend(atcmds, atcmd); } + /* EventTriggerAlterTableStart called by ProcessUtilitySlow */ AlterTableInternal(viewOid, atcmds, true); /* Make the new view columns visible */ @@ -217,6 +197,7 @@ DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, atcmd->def = (Node *) options; atcmds = list_make1(atcmd); + /* EventTriggerAlterTableStart called by ProcessUtilitySlow */ AlterTableInternal(viewOid, atcmds, true); ObjectAddressSet(address, RelationRelationId, viewOid); @@ -279,7 +260,6 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), errmsg("cannot drop columns from view"))); - /* we can ignore tdhasoid */ for (i = 0; i < olddesc->natts; i++) { @@ -353,7 +333,7 @@ DefineViewRules(Oid viewOid, Query *viewParse, bool replace) * by 2... * * These extra RT entries are not actually used in the query, - * except for run-time permission checking. + * except for run-time locking and permission checking. *--------------------------------------------------------------- */ static Query * @@ -386,9 +366,11 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse) * OLD first, then NEW.... */ rt_entry1 = addRangeTableEntryForRelation(pstate, viewRel, + AccessShareLock, makeAlias("old", NIL), false, false); rt_entry2 = addRangeTableEntryForRelation(pstate, viewRel, + AccessShareLock, makeAlias("new", NIL), false, false); /* Must override addRangeTableEntry's default access-check flags */ @@ -502,7 +484,7 @@ DefineView(ViewStmt *stmt, const char *queryString, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("WITH CHECK OPTION is supported only on automatically updatable views"), - errhint("%s", view_updatable_error))); + errhint("%s", _(view_updatable_error)))); } /* @@ -522,7 +504,7 @@ DefineView(ViewStmt *stmt, const char *queryString, if (te->resjunk) continue; te->resname = pstrdup(strVal(lfirst(alist_item))); - alist_item = lnext(alist_item); + alist_item = lnext(stmt->aliases, alist_item); if (alist_item == NULL) break; /* done assigning aliases */ } diff --git a/src/backend/executor/Makefile b/src/backend/executor/Makefile index 76d87eea49c..cc09895fa5c 100644 --- a/src/backend/executor/Makefile +++ b/src/backend/executor/Makefile @@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global OBJS = execAmi.o execCurrent.o execExpr.o execExprInterp.o \ execGrouping.o execIndexing.o execJunk.o \ - execMain.o execMerge.o execParallel.o execPartition.o execProcnode.o \ + execMain.o execParallel.o execPartition.o execProcnode.o \ execReplication.o execScan.o execSRF.o execTuples.o \ execUtils.o functions.o instrument.o nodeAppend.o nodeAgg.o \ nodeBitmapAnd.o nodeBitmapOr.o \ diff --git a/src/backend/executor/README b/src/backend/executor/README index 67736805c26..18b2ac18659 100644 --- a/src/backend/executor/README +++ b/src/backend/executor/README @@ -37,17 +37,6 @@ the plan tree returns the computed tuples to be updated, plus a "junk" one. For DELETE, the plan tree need only deliver a CTID column, and the ModifyTable node visits each of those rows and marks the row deleted. -MERGE runs one generic plan that returns candidate target rows. Each row -consists of a super-row that contains all the columns needed by any of the -individual actions, plus CTID and TABLEOID junk columns. The CTID column is -required to know if a matching target row was found or not and the TABLEOID -column is needed to find the underlying target partition, in case when the -target table is a partitioned table. When a matching target tuple is found, -the CTID column identifies the matching tuple and we attempt to activate -WHEN MATCHED actions. If a matching tuple is not found, then CTID column is -NULL and we attempt to activate WHEN NOT MATCHED actions. Once we know which -action is activated we form the final result row and apply only those changes. - XXX a great deal more documentation needs to be written here... @@ -56,13 +45,21 @@ Plan Trees and State Trees The plan tree delivered by the planner contains a tree of Plan nodes (struct types derived from struct Plan). During executor startup we build a parallel -tree of identical structure containing executor state nodes --- every plan -node type has a corresponding executor state node type. Each node in the -state tree has a pointer to its corresponding node in the plan tree, plus -executor state data as needed to implement that node type. This arrangement -allows the plan tree to be completely read-only so far as the executor is -concerned: all data that is modified during execution is in the state tree. -Read-only plan trees make life much simpler for plan caching and reuse. +tree of identical structure containing executor state nodes --- generally, +every plan node type has a corresponding executor state node type. Each node +in the state tree has a pointer to its corresponding node in the plan tree, +plus executor state data as needed to implement that node type. This +arrangement allows the plan tree to be completely read-only so far as the +executor is concerned: all data that is modified during execution is in the +state tree. Read-only plan trees make life much simpler for plan caching and +reuse. + +A corresponding executor state node may not be created during executor startup +if the executor determines that an entire subplan is not required due to +execution time partition pruning determining that no matching records will be +found there. This currently only occurs for Append and MergeAppend nodes. In +this case the non-required subplans are ignored and the executor state's +subnode array will become out of sequence to the plan's subplan list. Each Plan node may have expression trees associated with it, to represent its target list, qualification conditions, etc. These trees are also @@ -127,7 +124,7 @@ For example, "a + b" (one OpExpr, with two Var expressions) would be represented as two steps to fetch the Var values, and one step for the evaluation of the function underlying the + operator. The steps for the Vars would have their resvalue/resnull pointing directly to the appropriate -arg[] and argnull[] array elements in the FunctionCallInfoData struct that +args[].value .isnull elements in the FunctionCallInfoBaseData struct that is used by the function evaluation step, thus avoiding extra work to copy the result values around. @@ -148,7 +145,7 @@ sub-expressions. Each ExecInitExprRec() call has to specify where that subexpression's results are to be stored (via the resv/resnull parameters). This allows the above scenario of evaluating a (sub-)expression directly into -fcinfo->arg/argnull, but also requires some care: target Datum/isnull +fcinfo->args[].value/isnull, but also requires some care: target Datum/isnull variables may not be shared with another ExecInitExprRec() unless the results are only needed by steps executing before further usages of those target Datum/isnull variables. Due to the non-recursiveness of the @@ -161,7 +158,7 @@ not enough space. Because of that it is *not* allowed to point directly into any of the steps during expression initialization. Therefore, the resv/resnull for a subexpression usually point to some storage that is palloc'd separately from the steps array. For instance, the -FunctionCallInfoData for a function call step is separately allocated +FunctionCallInfoBaseData for a function call step is separately allocated rather than being part of the ExprEvalStep array. The overall result of a complete expression is typically returned into the resvalue/resnull fields of the ExprState node itself. @@ -189,9 +186,9 @@ Expression Evaluation To allow for different methods of expression evaluation, and for better branch/jump target prediction, expressions are evaluated by -calling ExprState->evalfunc (via ExprEvalExpr() and friends). +calling ExprState->evalfunc (via ExecEvalExpr() and friends). -ExprReadyExpr() can choose the method of interpretation by setting +ExecReadyExpr() can choose the method of interpretation by setting evalfunc to an appropriate function. The default execution function, ExecInterpExpr, is implemented in execExprInterp.c; see its header comment for details. Special-case evalfuncs are used for certain diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c index 9e784219786..1f18e5d3a2f 100644 --- a/src/backend/executor/execAmi.c +++ b/src/backend/executor/execAmi.c @@ -3,7 +3,7 @@ * execAmi.c * miscellaneous executor access method routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/executor/execAmi.c @@ -56,8 +56,9 @@ #include "executor/nodeValuesscan.h" #include "executor/nodeWindowAgg.h" #include "executor/nodeWorktablescan.h" +#include "nodes/extensible.h" #include "nodes/nodeFuncs.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "utils/rel.h" #include "utils/syscache.h" @@ -437,12 +438,45 @@ ExecSupportsMarkRestore(Path *pathnode) return ExecSupportsMarkRestore(((ProjectionPath *) pathnode)->subpath); else if (IsA(pathnode, MinMaxAggPath)) return false; /* childless Result */ + else if (IsA(pathnode, GroupResultPath)) + return false; /* childless Result */ else { - Assert(IsA(pathnode, ResultPath)); + /* Simple RTE_RESULT base relation */ + Assert(IsA(pathnode, Path)); return false; /* childless Result */ } + case T_Append: + { + AppendPath *appendPath = castNode(AppendPath, pathnode); + + /* + * If there's exactly one child, then there will be no Append + * in the final plan, so we can handle mark/restore if the + * child plan node can. + */ + if (list_length(appendPath->subpaths) == 1) + return ExecSupportsMarkRestore((Path *) linitial(appendPath->subpaths)); + /* Otherwise, Append can't handle it */ + return false; + } + + case T_MergeAppend: + { + MergeAppendPath *mapath = castNode(MergeAppendPath, pathnode); + + /* + * Like the Append case above, single-subpath MergeAppends + * won't be in the final plan, so just return the child's + * mark/restore ability. + */ + if (list_length(mapath->subpaths) == 1) + return ExecSupportsMarkRestore((Path *) linitial(mapath->subpaths)); + /* Otherwise, MergeAppend can't handle it */ + return false; + } + default: break; } diff --git a/src/backend/executor/execCurrent.c b/src/backend/executor/execCurrent.c index f70e54fe2af..c7f909241b4 100644 --- a/src/backend/executor/execCurrent.c +++ b/src/backend/executor/execCurrent.c @@ -3,7 +3,7 @@ * execCurrent.c * executor support for WHERE CURRENT OF cursor * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/executor/execCurrent.c @@ -12,6 +12,7 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/relscan.h" #include "access/sysattr.h" #include "catalog/pg_type.h" @@ -23,7 +24,8 @@ static char *fetch_cursor_param_value(ExprContext *econtext, int paramId); -static ScanState *search_plan_tree(PlanState *node, Oid table_oid); +static ScanState *search_plan_tree(PlanState *node, Oid table_oid, + bool *pending_rescan); /* @@ -90,21 +92,22 @@ execCurrentOf(CurrentOfExpr *cexpr, * the other code can't, while the non-FOR-UPDATE case allows use of WHERE * CURRENT OF with an insensitive cursor. */ - if (queryDesc->estate->es_rowMarks) + if (queryDesc->estate->es_rowmarks) { ExecRowMark *erm; - ListCell *lc; + Index i; /* * Here, the query must have exactly one FOR UPDATE/SHARE reference to * the target table, and we dig the ctid info out of that. */ erm = NULL; - foreach(lc, queryDesc->estate->es_rowMarks) + for (i = 0; i < queryDesc->estate->es_range_table_size; i++) { - ExecRowMark *thiserm = (ExecRowMark *) lfirst(lc); + ExecRowMark *thiserm = queryDesc->estate->es_rowmarks[i]; - if (!RowMarkRequiresRowShareLock(thiserm->markType)) + if (thiserm == NULL || + !RowMarkRequiresRowShareLock(thiserm->markType)) continue; /* ignore non-FOR UPDATE/SHARE items */ if (thiserm->relid == table_oid) @@ -156,8 +159,10 @@ execCurrentOf(CurrentOfExpr *cexpr, * aggregation. */ ScanState *scanstate; + bool pending_rescan = false; - scanstate = search_plan_tree(queryDesc->planstate, table_oid); + scanstate = search_plan_tree(queryDesc->planstate, table_oid, + &pending_rescan); if (!scanstate) ereport(ERROR, (errcode(ERRCODE_INVALID_CURSOR_STATE), @@ -177,8 +182,12 @@ execCurrentOf(CurrentOfExpr *cexpr, errmsg("cursor \"%s\" is not positioned on a row", cursor_name))); - /* Now OK to return false if we found an inactive scan */ - if (TupIsNull(scanstate->ss_ScanTupleSlot)) + /* + * Now OK to return false if we found an inactive scan. It is + * inactive either if it's not positioned on a row, or there's a + * rescan pending for it. + */ + if (TupIsNull(scanstate->ss_ScanTupleSlot) || pending_rescan) return false; /* @@ -195,7 +204,7 @@ execCurrentOf(CurrentOfExpr *cexpr, */ IndexScanDesc scan = ((IndexOnlyScanState *) scanstate)->ioss_ScanDesc; - *current_tid = scan->xs_ctup.t_self; + *current_tid = scan->xs_heaptid; } else { @@ -210,27 +219,25 @@ execCurrentOf(CurrentOfExpr *cexpr, ItemPointer tuple_tid; #ifdef USE_ASSERT_CHECKING - if (!slot_getsysattr(scanstate->ss_ScanTupleSlot, - TableOidAttributeNumber, - &ldatum, - &lisnull)) + ldatum = slot_getsysattr(scanstate->ss_ScanTupleSlot, + TableOidAttributeNumber, + &lisnull); + if (lisnull) ereport(ERROR, (errcode(ERRCODE_INVALID_CURSOR_STATE), errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"", cursor_name, table_name))); - Assert(!lisnull); Assert(DatumGetObjectId(ldatum) == table_oid); #endif - if (!slot_getsysattr(scanstate->ss_ScanTupleSlot, - SelfItemPointerAttributeNumber, - &ldatum, - &lisnull)) + ldatum = slot_getsysattr(scanstate->ss_ScanTupleSlot, + SelfItemPointerAttributeNumber, + &lisnull); + if (lisnull) ereport(ERROR, (errcode(ERRCODE_INVALID_CURSOR_STATE), errmsg("cursor \"%s\" is not a simply updatable scan of table \"%s\"", cursor_name, table_name))); - Assert(!lisnull); tuple_tid = (ItemPointer) DatumGetPointer(ldatum); *current_tid = *tuple_tid; @@ -291,10 +298,20 @@ fetch_cursor_param_value(ExprContext *econtext, int paramId) * * Search through a PlanState tree for a scan node on the specified table. * Return NULL if not found or multiple candidates. + * + * If a candidate is found, set *pending_rescan to true if that candidate + * or any node above it has a pending rescan action, i.e. chgParam != NULL. + * That indicates that we shouldn't consider the node to be positioned on a + * valid tuple, even if its own state would indicate that it is. (Caller + * must initialize *pending_rescan to false, and should not trust its state + * if multiple candidates are found.) */ static ScanState * -search_plan_tree(PlanState *node, Oid table_oid) +search_plan_tree(PlanState *node, Oid table_oid, + bool *pending_rescan) { + ScanState *result = NULL; + if (node == NULL) return NULL; switch (nodeTag(node)) @@ -314,7 +331,7 @@ search_plan_tree(PlanState *node, Oid table_oid) ScanState *sstate = (ScanState *) node; if (RelationGetRelid(sstate->ss_currentRelation) == table_oid) - return sstate; + result = sstate; break; } @@ -325,13 +342,13 @@ search_plan_tree(PlanState *node, Oid table_oid) case T_AppendState: { AppendState *astate = (AppendState *) node; - ScanState *result = NULL; int i; for (i = 0; i < astate->as_nplans; i++) { ScanState *elem = search_plan_tree(astate->appendplans[i], - table_oid); + table_oid, + pending_rescan); if (!elem) continue; @@ -339,7 +356,7 @@ search_plan_tree(PlanState *node, Oid table_oid) return NULL; /* multiple matches */ result = elem; } - return result; + break; } /* @@ -348,13 +365,13 @@ search_plan_tree(PlanState *node, Oid table_oid) case T_MergeAppendState: { MergeAppendState *mstate = (MergeAppendState *) node; - ScanState *result = NULL; int i; for (i = 0; i < mstate->ms_nplans; i++) { ScanState *elem = search_plan_tree(mstate->mergeplans[i], - table_oid); + table_oid, + pending_rescan); if (!elem) continue; @@ -362,7 +379,7 @@ search_plan_tree(PlanState *node, Oid table_oid) return NULL; /* multiple matches */ result = elem; } - return result; + break; } /* @@ -371,18 +388,31 @@ search_plan_tree(PlanState *node, Oid table_oid) */ case T_ResultState: case T_LimitState: - return search_plan_tree(node->lefttree, table_oid); + result = search_plan_tree(node->lefttree, + table_oid, + pending_rescan); + break; /* * SubqueryScan too, but it keeps the child in a different place */ case T_SubqueryScanState: - return search_plan_tree(((SubqueryScanState *) node)->subplan, - table_oid); + result = search_plan_tree(((SubqueryScanState *) node)->subplan, + table_oid, + pending_rescan); + break; default: /* Otherwise, assume we can't descend through it */ break; } - return NULL; + + /* + * If we found a candidate at or below this node, then this node's + * chgParam indicates a pending rescan that will affect the candidate. + */ + if (result && node->chgParam != NULL) + *pending_rescan = true; + + return result; } diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c index e284fd71d75..7e486449eca 100644 --- a/src/backend/executor/execExpr.c +++ b/src/backend/executor/execExpr.c @@ -19,7 +19,7 @@ * and "Expression Evaluation" sections. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -40,9 +40,9 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "pgstat.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/datum.h" #include "utils/lsyscache.h" @@ -58,26 +58,28 @@ typedef struct LastAttnumInfo static void ExecReadyExpr(ExprState *state); static void ExecInitExprRec(Expr *node, ExprState *state, - Datum *resv, bool *resnull); + Datum *resv, bool *resnull); static void ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, - Oid funcid, Oid inputcollid, - ExprState *state); + Oid funcid, Oid inputcollid, + ExprState *state); static void ExecInitExprSlots(ExprState *state, Node *node); static void ExecPushExprSlots(ExprState *state, LastAttnumInfo *info); static bool get_last_attnums_walker(Node *node, LastAttnumInfo *info); +static bool ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op); static void ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, - ExprState *state); -static void ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, - ExprState *state, - Datum *resv, bool *resnull); + ExprState *state); +static void ExecInitSubscriptingRef(ExprEvalStep *scratch, + SubscriptingRef *sbsref, + ExprState *state, + Datum *resv, bool *resnull); static bool isAssignmentIndirectionExpr(Expr *expr); static void ExecInitCoerceToDomain(ExprEvalStep *scratch, CoerceToDomain *ctest, - ExprState *state, - Datum *resv, bool *resnull); + ExprState *state, + Datum *resv, bool *resnull); static void ExecBuildAggTransCall(ExprState *state, AggState *aggstate, - ExprEvalStep *scratch, - FunctionCallInfo fcinfo, AggStatePerTrans pertrans, - int transno, int setno, int setoff, bool ishash); + ExprEvalStep *scratch, + FunctionCallInfo fcinfo, AggStatePerTrans pertrans, + int transno, int setno, int setoff, bool ishash); /* @@ -359,7 +361,7 @@ ExecBuildProjectionInfo(List *targetList, projInfo->pi_exprContext = econtext; /* We embed ExprState into ProjectionInfo instead of doing extra palloc */ - projInfo->pi_state.tag.type = T_ExprState; + projInfo->pi_state.tag = T_ExprState; state = &projInfo->pi_state; state->expr = (Expr *) targetList; state->parent = parent; @@ -785,7 +787,7 @@ ExecInitExprRec(Expr *node, ExprState *state, { AggState *aggstate = (AggState *) state->parent; - aggstate->aggs = lcons(astate, aggstate->aggs); + aggstate->aggs = lappend(aggstate->aggs, astate); aggstate->numaggs++; } else @@ -833,7 +835,7 @@ ExecInitExprRec(Expr *node, ExprState *state, WindowAggState *winstate = (WindowAggState *) state->parent; int nfuncs; - winstate->funcs = lcons(wfstate, winstate->funcs); + winstate->funcs = lappend(winstate->funcs, wfstate); nfuncs = ++winstate->numfuncs; if (wfunc->winagg) winstate->numaggs++; @@ -867,11 +869,11 @@ ExecInitExprRec(Expr *node, ExprState *state, break; } - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - ExecInitArrayRef(&scratch, aref, state, resv, resnull); + ExecInitSubscriptingRef(&scratch, sbsref, state, resv, resnull); break; } @@ -965,7 +967,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* Set up the primary fmgr lookup information */ finfo = palloc0(sizeof(FmgrInfo)); - fcinfo = palloc0(sizeof(FunctionCallInfoData)); + fcinfo = palloc0(SizeForFunctionCallInfo(2)); fmgr_info(opexpr->opfuncid, finfo); fmgr_info_set_expr((Node *) node, finfo); InitFunctionCallInfoData(*fcinfo, finfo, 2, @@ -973,7 +975,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* Evaluate scalar directly into left function argument */ ExecInitExprRec(scalararg, state, - &fcinfo->arg[0], &fcinfo->argnull[0]); + &fcinfo->args[0].value, &fcinfo->args[0].isnull); /* * Evaluate array argument into our return value. There's no @@ -1186,24 +1188,25 @@ ExecInitExprRec(Expr *node, ExprState *state, /* * Use the CaseTestExpr mechanism to pass down the old * value of the field being replaced; this is needed in - * case the newval is itself a FieldStore or ArrayRef that - * has to obtain and modify the old value. It's safe to - * reuse the CASE mechanism because there cannot be a CASE - * between here and where the value would be needed, and a - * field assignment can't be within a CASE either. (So - * saving and restoring innermost_caseval is just - * paranoia, but let's do it anyway.) + * case the newval is itself a FieldStore or + * SubscriptingRef that has to obtain and modify the old + * value. It's safe to reuse the CASE mechanism because + * there cannot be a CASE between here and where the value + * would be needed, and a field assignment can't be within + * a CASE either. (So saving and restoring + * innermost_caseval is just paranoia, but let's do it + * anyway.) * * Another non-obvious point is that it's safe to use the * field's values[]/nulls[] entries as both the caseval * source and the result address for this subexpression. * That's okay only because (1) both FieldStore and - * ArrayRef evaluate their arg or refexpr inputs first, - * and (2) any such CaseTestExpr is directly the arg or - * refexpr input. So any read of the caseval will occur - * before there's a chance to overwrite it. Also, if - * multiple entries in the newvals/fieldnums lists target - * the same field, they'll effectively be applied + * SubscriptingRef evaluate their arg or refexpr inputs + * first, and (2) any such CaseTestExpr is directly the + * arg or refexpr input. So any read of the caseval will + * occur before there's a chance to overwrite it. Also, + * if multiple entries in the newvals/fieldnums lists + * target the same field, they'll effectively be applied * left-to-right which is what we want. */ save_innermost_caseval = state->innermost_caseval; @@ -1262,7 +1265,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* lookup the source type's output function */ scratch.d.iocoerce.finfo_out = palloc0(sizeof(FmgrInfo)); - scratch.d.iocoerce.fcinfo_data_out = palloc0(sizeof(FunctionCallInfoData)); + scratch.d.iocoerce.fcinfo_data_out = palloc0(SizeForFunctionCallInfo(1)); getTypeOutputInfo(exprType((Node *) iocoerce->arg), &iofunc, &typisvarlena); @@ -1274,7 +1277,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* lookup the result type's input function */ scratch.d.iocoerce.finfo_in = palloc0(sizeof(FmgrInfo)); - scratch.d.iocoerce.fcinfo_data_in = palloc0(sizeof(FunctionCallInfoData)); + scratch.d.iocoerce.fcinfo_data_in = palloc0(SizeForFunctionCallInfo(3)); getTypeInputInfo(iocoerce->resulttype, &iofunc, &typioparam); @@ -1289,10 +1292,10 @@ ExecInitExprRec(Expr *node, ExprState *state, * function, since they're constants. */ fcinfo_in = scratch.d.iocoerce.fcinfo_data_in; - fcinfo_in->arg[1] = ObjectIdGetDatum(typioparam); - fcinfo_in->argnull[1] = false; - fcinfo_in->arg[2] = Int32GetDatum(-1); - fcinfo_in->argnull[2] = false; + fcinfo_in->args[1].value = ObjectIdGetDatum(typioparam); + fcinfo_in->args[1].isnull = false; + fcinfo_in->args[2].value = Int32GetDatum(-1); + fcinfo_in->args[2].isnull = false; ExprEvalPushStep(state, &scratch); break; @@ -1516,10 +1519,11 @@ ExecInitExprRec(Expr *node, ExprState *state, /* * Read from location identified by innermost_caseval. Note * that innermost_caseval could be NULL, if this node isn't - * actually within a CASE structure; some parts of the system - * abuse CaseTestExpr to cause a read of a value externally - * supplied in econtext->caseValue_datum. We'll take care of - * that scenario at runtime. + * actually within a CaseExpr, ArrayCoerceExpr, etc structure. + * That can happen because some parts of the system abuse + * CaseTestExpr to cause a read of a value externally supplied + * in econtext->caseValue_datum. We'll take care of that + * scenario at runtime. */ scratch.opcode = EEOP_CASE_TESTVAL; scratch.d.casetest.value = state->innermost_caseval; @@ -1680,7 +1684,6 @@ ExecInitExprRec(Expr *node, ExprState *state, *l_opfamily, *l_inputcollid; ListCell *lc; - int off; /* * Iterate over each field, prepare comparisons. To handle @@ -1692,20 +1695,11 @@ ExecInitExprRec(Expr *node, ExprState *state, Assert(list_length(rcexpr->opfamilies) == nopers); Assert(list_length(rcexpr->inputcollids) == nopers); - off = 0; - for (off = 0, - l_left_expr = list_head(rcexpr->largs), - l_right_expr = list_head(rcexpr->rargs), - l_opno = list_head(rcexpr->opnos), - l_opfamily = list_head(rcexpr->opfamilies), - l_inputcollid = list_head(rcexpr->inputcollids); - off < nopers; - off++, - l_left_expr = lnext(l_left_expr), - l_right_expr = lnext(l_right_expr), - l_opno = lnext(l_opno), - l_opfamily = lnext(l_opfamily), - l_inputcollid = lnext(l_inputcollid)) + forfive(l_left_expr, rcexpr->largs, + l_right_expr, rcexpr->rargs, + l_opno, rcexpr->opnos, + l_opfamily, rcexpr->opfamilies, + l_inputcollid, rcexpr->inputcollids) { Expr *left_expr = (Expr *) lfirst(l_left_expr); Expr *right_expr = (Expr *) lfirst(l_right_expr); @@ -1733,7 +1727,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* Set up the primary fmgr lookup information */ finfo = palloc0(sizeof(FmgrInfo)); - fcinfo = palloc0(sizeof(FunctionCallInfoData)); + fcinfo = palloc0(SizeForFunctionCallInfo(2)); fmgr_info(proc, finfo); fmgr_info_set_expr((Node *) node, finfo); InitFunctionCallInfoData(*fcinfo, finfo, 2, @@ -1748,9 +1742,9 @@ ExecInitExprRec(Expr *node, ExprState *state, /* evaluate left and right args directly into fcinfo */ ExecInitExprRec(left_expr, state, - &fcinfo->arg[0], &fcinfo->argnull[0]); + &fcinfo->args[0].value, &fcinfo->args[0].isnull); ExecInitExprRec(right_expr, state, - &fcinfo->arg[1], &fcinfo->argnull[1]); + &fcinfo->args[1].value, &fcinfo->args[1].isnull); scratch.opcode = EEOP_ROWCOMPARE_STEP; scratch.d.rowcompare_step.finfo = finfo; @@ -1782,7 +1776,7 @@ ExecInitExprRec(Expr *node, ExprState *state, scratch.d.rowcompare_final.rctype = rcexpr->rctype; ExprEvalPushStep(state, &scratch); - /* adjust jump targetss */ + /* adjust jump targets */ foreach(lc, adjust_jumps) { ExprEvalStep *as = &state->steps[lfirst_int(lc)]; @@ -1876,7 +1870,7 @@ ExecInitExprRec(Expr *node, ExprState *state, /* Perform function lookup */ finfo = palloc0(sizeof(FmgrInfo)); - fcinfo = palloc0(sizeof(FunctionCallInfoData)); + fcinfo = palloc0(SizeForFunctionCallInfo(2)); fmgr_info(typentry->cmp_proc, finfo); fmgr_info_set_expr((Node *) node, finfo); InitFunctionCallInfoData(*fcinfo, finfo, 2, @@ -2185,7 +2179,7 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid, /* Allocate function lookup data and parameter workspace for this call */ scratch->d.func.finfo = palloc0(sizeof(FmgrInfo)); - scratch->d.func.fcinfo_data = palloc0(sizeof(FunctionCallInfoData)); + scratch->d.func.fcinfo_data = palloc0(SizeForFunctionCallInfo(nargs)); flinfo = scratch->d.func.finfo; fcinfo = scratch->d.func.fcinfo_data; @@ -2224,13 +2218,14 @@ ExecInitFunc(ExprEvalStep *scratch, Expr *node, List *args, Oid funcid, */ Const *con = (Const *) arg; - fcinfo->arg[argno] = con->constvalue; - fcinfo->argnull[argno] = con->constisnull; + fcinfo->args[argno].value = con->constvalue; + fcinfo->args[argno].isnull = con->constisnull; } else { ExecInitExprRec(arg, state, - &fcinfo->arg[argno], &fcinfo->argnull[argno]); + &fcinfo->args[argno].value, + &fcinfo->args[argno].isnull); } argno++; } @@ -2287,22 +2282,31 @@ ExecPushExprSlots(ExprState *state, LastAttnumInfo *info) { scratch.opcode = EEOP_INNER_FETCHSOME; scratch.d.fetch.last_var = info->last_inner; + scratch.d.fetch.fixed = false; + scratch.d.fetch.kind = NULL; scratch.d.fetch.known_desc = NULL; - ExprEvalPushStep(state, &scratch); + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); } if (info->last_outer > 0) { scratch.opcode = EEOP_OUTER_FETCHSOME; scratch.d.fetch.last_var = info->last_outer; + scratch.d.fetch.fixed = false; + scratch.d.fetch.kind = NULL; scratch.d.fetch.known_desc = NULL; - ExprEvalPushStep(state, &scratch); + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); } if (info->last_scan > 0) { scratch.opcode = EEOP_SCAN_FETCHSOME; scratch.d.fetch.last_var = info->last_scan; + scratch.d.fetch.fixed = false; + scratch.d.fetch.kind = NULL; scratch.d.fetch.known_desc = NULL; - ExprEvalPushStep(state, &scratch); + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); } } @@ -2354,6 +2358,109 @@ get_last_attnums_walker(Node *node, LastAttnumInfo *info) (void *) info); } +/* + * Compute additional information for EEOP_*_FETCHSOME ops. + * + * The goal is to determine whether a slot is 'fixed', that is, every + * evaluation of the expression will have the same type of slot, with an + * equivalent descriptor. + * + * Returns true if the the deforming step is required, false otherwise. + */ +static bool +ExecComputeSlotInfo(ExprState *state, ExprEvalStep *op) +{ + PlanState *parent = state->parent; + TupleDesc desc = NULL; + const TupleTableSlotOps *tts_ops = NULL; + bool isfixed = false; + ExprEvalOp opcode = op->opcode; + + Assert(opcode == EEOP_INNER_FETCHSOME || + opcode == EEOP_OUTER_FETCHSOME || + opcode == EEOP_SCAN_FETCHSOME); + + if (op->d.fetch.known_desc != NULL) + { + desc = op->d.fetch.known_desc; + tts_ops = op->d.fetch.kind; + isfixed = op->d.fetch.kind != NULL; + } + else if (!parent) + { + isfixed = false; + } + else if (opcode == EEOP_INNER_FETCHSOME) + { + PlanState *is = innerPlanState(parent); + + if (parent->inneropsset && !parent->inneropsfixed) + { + isfixed = false; + } + else if (parent->inneropsset && parent->innerops) + { + isfixed = true; + tts_ops = parent->innerops; + desc = ExecGetResultType(is); + } + else if (is) + { + tts_ops = ExecGetResultSlotOps(is, &isfixed); + desc = ExecGetResultType(is); + } + } + else if (opcode == EEOP_OUTER_FETCHSOME) + { + PlanState *os = outerPlanState(parent); + + if (parent->outeropsset && !parent->outeropsfixed) + { + isfixed = false; + } + else if (parent->outeropsset && parent->outerops) + { + isfixed = true; + tts_ops = parent->outerops; + desc = ExecGetResultType(os); + } + else if (os) + { + tts_ops = ExecGetResultSlotOps(os, &isfixed); + desc = ExecGetResultType(os); + } + } + else if (opcode == EEOP_SCAN_FETCHSOME) + { + desc = parent->scandesc; + + if (parent && parent->scanops) + tts_ops = parent->scanops; + + if (parent->scanopsset) + isfixed = parent->scanopsfixed; + } + + if (isfixed && desc != NULL && tts_ops != NULL) + { + op->d.fetch.fixed = true; + op->d.fetch.kind = tts_ops; + op->d.fetch.known_desc = desc; + } + else + { + op->d.fetch.fixed = false; + op->d.fetch.kind = NULL; + op->d.fetch.known_desc = NULL; + } + + /* if the slot is known to always virtual we never need to deform */ + if (op->d.fetch.fixed && op->d.fetch.kind == &TTSOpsVirtual) + return false; + + return true; +} + /* * Prepare step for the evaluation of a whole-row variable. * The caller still has to push the step. @@ -2421,42 +2528,42 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state) { scratch->d.wholerow.junkFilter = ExecInitJunkFilter(subplan->plan->targetlist, - ExecGetResultType(subplan)->tdhasoid, - ExecInitExtraTupleSlot(parent->state, NULL)); + ExecInitExtraTupleSlot(parent->state, NULL, + &TTSOpsVirtual)); } } } } /* - * Prepare evaluation of an ArrayRef expression. + * Prepare evaluation of a SubscriptingRef expression. */ static void -ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, - ExprState *state, Datum *resv, bool *resnull) +ExecInitSubscriptingRef(ExprEvalStep *scratch, SubscriptingRef *sbsref, + ExprState *state, Datum *resv, bool *resnull) { - bool isAssignment = (aref->refassgnexpr != NULL); - ArrayRefState *arefstate = palloc0(sizeof(ArrayRefState)); + bool isAssignment = (sbsref->refassgnexpr != NULL); + SubscriptingRefState *sbsrefstate = palloc0(sizeof(SubscriptingRefState)); List *adjust_jumps = NIL; ListCell *lc; int i; - /* Fill constant fields of ArrayRefState */ - arefstate->isassignment = isAssignment; - arefstate->refelemtype = aref->refelemtype; - arefstate->refattrlength = get_typlen(aref->refarraytype); - get_typlenbyvalalign(aref->refelemtype, - &arefstate->refelemlength, - &arefstate->refelembyval, - &arefstate->refelemalign); + /* Fill constant fields of SubscriptingRefState */ + sbsrefstate->isassignment = isAssignment; + sbsrefstate->refelemtype = sbsref->refelemtype; + sbsrefstate->refattrlength = get_typlen(sbsref->refcontainertype); + get_typlenbyvalalign(sbsref->refelemtype, + &sbsrefstate->refelemlength, + &sbsrefstate->refelembyval, + &sbsrefstate->refelemalign); /* * Evaluate array input. It's safe to do so into resv/resnull, because we * won't use that as target for any of the other subexpressions, and it'll - * be overwritten by the final EEOP_ARRAYREF_FETCH/ASSIGN step, which is + * be overwritten by the final EEOP_SBSREF_FETCH/ASSIGN step, which is * pushed last. */ - ExecInitExprRec(aref->refexpr, state, resv, resnull); + ExecInitExprRec(sbsref->refexpr, state, resv, resnull); /* * If refexpr yields NULL, and it's a fetch, then result is NULL. We can @@ -2473,87 +2580,87 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, } /* Verify subscript list lengths are within limit */ - if (list_length(aref->refupperindexpr) > MAXDIM) + if (list_length(sbsref->refupperindexpr) > MAXDIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", - list_length(aref->refupperindexpr), MAXDIM))); + list_length(sbsref->refupperindexpr), MAXDIM))); - if (list_length(aref->reflowerindexpr) > MAXDIM) + if (list_length(sbsref->reflowerindexpr) > MAXDIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)", - list_length(aref->reflowerindexpr), MAXDIM))); + list_length(sbsref->reflowerindexpr), MAXDIM))); /* Evaluate upper subscripts */ i = 0; - foreach(lc, aref->refupperindexpr) + foreach(lc, sbsref->refupperindexpr) { Expr *e = (Expr *) lfirst(lc); /* When slicing, individual subscript bounds can be omitted */ if (!e) { - arefstate->upperprovided[i] = false; + sbsrefstate->upperprovided[i] = false; i++; continue; } - arefstate->upperprovided[i] = true; + sbsrefstate->upperprovided[i] = true; /* Each subscript is evaluated into subscriptvalue/subscriptnull */ ExecInitExprRec(e, state, - &arefstate->subscriptvalue, &arefstate->subscriptnull); - - /* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT; - scratch->d.arrayref_subscript.state = arefstate; - scratch->d.arrayref_subscript.off = i; - scratch->d.arrayref_subscript.isupper = true; - scratch->d.arrayref_subscript.jumpdone = -1; /* adjust later */ + &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); + + /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ + scratch->opcode = EEOP_SBSREF_SUBSCRIPT; + scratch->d.sbsref_subscript.state = sbsrefstate; + scratch->d.sbsref_subscript.off = i; + scratch->d.sbsref_subscript.isupper = true; + scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ ExprEvalPushStep(state, scratch); adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1); i++; } - arefstate->numupper = i; + sbsrefstate->numupper = i; /* Evaluate lower subscripts similarly */ i = 0; - foreach(lc, aref->reflowerindexpr) + foreach(lc, sbsref->reflowerindexpr) { Expr *e = (Expr *) lfirst(lc); /* When slicing, individual subscript bounds can be omitted */ if (!e) { - arefstate->lowerprovided[i] = false; + sbsrefstate->lowerprovided[i] = false; i++; continue; } - arefstate->lowerprovided[i] = true; + sbsrefstate->lowerprovided[i] = true; /* Each subscript is evaluated into subscriptvalue/subscriptnull */ ExecInitExprRec(e, state, - &arefstate->subscriptvalue, &arefstate->subscriptnull); - - /* ... and then ARRAYREF_SUBSCRIPT saves it into step's workspace */ - scratch->opcode = EEOP_ARRAYREF_SUBSCRIPT; - scratch->d.arrayref_subscript.state = arefstate; - scratch->d.arrayref_subscript.off = i; - scratch->d.arrayref_subscript.isupper = false; - scratch->d.arrayref_subscript.jumpdone = -1; /* adjust later */ + &sbsrefstate->subscriptvalue, &sbsrefstate->subscriptnull); + + /* ... and then SBSREF_SUBSCRIPT saves it into step's workspace */ + scratch->opcode = EEOP_SBSREF_SUBSCRIPT; + scratch->d.sbsref_subscript.state = sbsrefstate; + scratch->d.sbsref_subscript.off = i; + scratch->d.sbsref_subscript.isupper = false; + scratch->d.sbsref_subscript.jumpdone = -1; /* adjust later */ ExprEvalPushStep(state, scratch); adjust_jumps = lappend_int(adjust_jumps, state->steps_len - 1); i++; } - arefstate->numlower = i; + sbsrefstate->numlower = i; /* Should be impossible if parser is sane, but check anyway: */ - if (arefstate->numlower != 0 && - arefstate->numupper != arefstate->numlower) + if (sbsrefstate->numlower != 0 && + sbsrefstate->numupper != sbsrefstate->numlower) elog(ERROR, "upper and lower index lists are not same length"); if (isAssignment) @@ -2563,49 +2670,51 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, /* * We might have a nested-assignment situation, in which the - * refassgnexpr is itself a FieldStore or ArrayRef that needs to - * obtain and modify the previous value of the array element or slice - * being replaced. If so, we have to extract that value from the - * array and pass it down via the CaseTestExpr mechanism. It's safe - * to reuse the CASE mechanism because there cannot be a CASE between - * here and where the value would be needed, and an array assignment - * can't be within a CASE either. (So saving and restoring + * refassgnexpr is itself a FieldStore or SubscriptingRef that needs + * to obtain and modify the previous value of the array element or + * slice being replaced. If so, we have to extract that value from + * the array and pass it down via the CaseTestExpr mechanism. It's + * safe to reuse the CASE mechanism because there cannot be a CASE + * between here and where the value would be needed, and an array + * assignment can't be within a CASE either. (So saving and restoring * innermost_caseval is just paranoia, but let's do it anyway.) * * Since fetching the old element might be a nontrivial expense, do it * only if the argument actually needs it. */ - if (isAssignmentIndirectionExpr(aref->refassgnexpr)) + if (isAssignmentIndirectionExpr(sbsref->refassgnexpr)) { - scratch->opcode = EEOP_ARRAYREF_OLD; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_OLD; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); } - /* ARRAYREF_OLD puts extracted value into prevvalue/prevnull */ + /* SBSREF_OLD puts extracted value into prevvalue/prevnull */ save_innermost_caseval = state->innermost_caseval; save_innermost_casenull = state->innermost_casenull; - state->innermost_caseval = &arefstate->prevvalue; - state->innermost_casenull = &arefstate->prevnull; + state->innermost_caseval = &sbsrefstate->prevvalue; + state->innermost_casenull = &sbsrefstate->prevnull; /* evaluate replacement value into replacevalue/replacenull */ - ExecInitExprRec(aref->refassgnexpr, state, - &arefstate->replacevalue, &arefstate->replacenull); + ExecInitExprRec(sbsref->refassgnexpr, state, + &sbsrefstate->replacevalue, &sbsrefstate->replacenull); state->innermost_caseval = save_innermost_caseval; state->innermost_casenull = save_innermost_casenull; /* and perform the assignment */ - scratch->opcode = EEOP_ARRAYREF_ASSIGN; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_ASSIGN; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); + } else { /* array fetch is much simpler */ - scratch->opcode = EEOP_ARRAYREF_FETCH; - scratch->d.arrayref.state = arefstate; + scratch->opcode = EEOP_SBSREF_FETCH; + scratch->d.sbsref.state = sbsrefstate; ExprEvalPushStep(state, scratch); + } /* adjust jump targets */ @@ -2613,10 +2722,10 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, { ExprEvalStep *as = &state->steps[lfirst_int(lc)]; - if (as->opcode == EEOP_ARRAYREF_SUBSCRIPT) + if (as->opcode == EEOP_SBSREF_SUBSCRIPT) { - Assert(as->d.arrayref_subscript.jumpdone == -1); - as->d.arrayref_subscript.jumpdone = state->steps_len; + Assert(as->d.sbsref_subscript.jumpdone == -1); + as->d.sbsref_subscript.jumpdone = state->steps_len; } else { @@ -2628,8 +2737,9 @@ ExecInitArrayRef(ExprEvalStep *scratch, ArrayRef *aref, } /* - * Helper for preparing ArrayRef expressions for evaluation: is expr a nested - * FieldStore or ArrayRef that needs the old element value passed down? + * Helper for preparing SubscriptingRef expressions for evaluation: is expr + * a nested FieldStore or SubscriptingRef that needs the old element value + * passed down? * * (We could use this in FieldStore too, but in that case passing the old * value is so cheap there's no need.) @@ -2652,11 +2762,11 @@ isAssignmentIndirectionExpr(Expr *expr) if (fstore->arg && IsA(fstore->arg, CaseTestExpr)) return true; } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *arrayRef = (ArrayRef *) expr; + SubscriptingRef *sbsRef = (SubscriptingRef *) expr; - if (arrayRef->refexpr && IsA(arrayRef->refexpr, CaseTestExpr)) + if (sbsRef->refexpr && IsA(sbsRef->refexpr, CaseTestExpr)) return true; } return false; @@ -2860,13 +2970,13 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, for (transno = 0; transno < aggstate->numtrans; transno++) { AggStatePerTrans pertrans = &aggstate->pertrans[transno]; - int numInputs = pertrans->numInputs; int argno; int setno; - FunctionCallInfo trans_fcinfo = &pertrans->transfn_fcinfo; + FunctionCallInfo trans_fcinfo = pertrans->transfn_fcinfo; ListCell *arg; ListCell *bail; List *adjust_bailout = NIL; + NullableDatum *strictargs = NULL; bool *strictnulls = NULL; /* @@ -2904,7 +3014,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, Assert(pertrans->numSortCols == 0); Assert(list_length(pertrans->aggref->args) == 1); - strictnulls = trans_fcinfo->argnull + 1; + strictargs = trans_fcinfo->args + 1; source_tle = (TargetEntry *) linitial(pertrans->aggref->args); /* @@ -2918,21 +3028,21 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, * value */ ExecInitExprRec(source_tle->expr, state, - &trans_fcinfo->arg[argno + 1], - &trans_fcinfo->argnull[argno + 1]); + &trans_fcinfo->args[argno + 1].value, + &trans_fcinfo->args[argno + 1].isnull); } else { - FunctionCallInfo ds_fcinfo = &pertrans->deserialfn_fcinfo; + FunctionCallInfo ds_fcinfo = pertrans->deserialfn_fcinfo; /* evaluate argument */ ExecInitExprRec(source_tle->expr, state, - &ds_fcinfo->arg[0], - &ds_fcinfo->argnull[0]); + &ds_fcinfo->args[0].value, + &ds_fcinfo->args[0].isnull); /* Dummy second argument for type-safety reasons */ - ds_fcinfo->arg[1] = PointerGetDatum(NULL); - ds_fcinfo->argnull[1] = false; + ds_fcinfo->args[1].value = PointerGetDatum(NULL); + ds_fcinfo->args[1].isnull = false; /* * Don't call a strict deserialization function with NULL @@ -2946,8 +3056,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, scratch.d.agg_deserialize.aggstate = aggstate; scratch.d.agg_deserialize.fcinfo_data = ds_fcinfo; scratch.d.agg_deserialize.jumpnull = -1; /* adjust later */ - scratch.resvalue = &trans_fcinfo->arg[argno + 1]; - scratch.resnull = &trans_fcinfo->argnull[argno + 1]; + scratch.resvalue = &trans_fcinfo->args[argno + 1].value; + scratch.resnull = &trans_fcinfo->args[argno + 1].isnull; ExprEvalPushStep(state, &scratch); adjust_bailout = lappend_int(adjust_bailout, @@ -2964,7 +3074,7 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, /* * Normal transition function without ORDER BY / DISTINCT. */ - strictnulls = trans_fcinfo->argnull + 1; + strictargs = trans_fcinfo->args + 1; foreach(arg, pertrans->aggref->args) { @@ -2975,8 +3085,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, * value */ ExecInitExprRec(source_tle->expr, state, - &trans_fcinfo->arg[argno + 1], - &trans_fcinfo->argnull[argno + 1]); + &trans_fcinfo->args[argno + 1].value, + &trans_fcinfo->args[argno + 1].isnull); argno++; } } @@ -3015,19 +3125,23 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, argno++; } } - Assert(numInputs == argno); + Assert(pertrans->numInputs == argno); /* * For a strict transfn, nothing happens when there's a NULL input; we * just keep the prior transValue. This is true for both plain and * sorted/distinct aggregates. */ - if (trans_fcinfo->flinfo->fn_strict && numInputs > 0) + if (trans_fcinfo->flinfo->fn_strict && pertrans->numTransInputs > 0) { - scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK; + if (strictnulls) + scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_NULLS; + else + scratch.opcode = EEOP_AGG_STRICT_INPUT_CHECK_ARGS; scratch.d.agg_strict_input_check.nulls = strictnulls; + scratch.d.agg_strict_input_check.args = strictargs; scratch.d.agg_strict_input_check.jumpnull = -1; /* adjust later */ - scratch.d.agg_strict_input_check.nargs = numInputs; + scratch.d.agg_strict_input_check.nargs = pertrans->numTransInputs; ExprEvalPushStep(state, &scratch); adjust_bailout = lappend_int(adjust_bailout, state->steps_len - 1); @@ -3079,7 +3193,8 @@ ExecBuildAggTrans(AggState *aggstate, AggStatePerPhase phase, Assert(as->d.jump.jumpdone == -1); as->d.jump.jumpdone = state->steps_len; } - else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK) + else if (as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_ARGS || + as->opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS) { Assert(as->d.agg_strict_input_check.jumpnull == -1); as->d.agg_strict_input_check.jumpnull = state->steps_len; @@ -3214,9 +3329,11 @@ ExecBuildAggTransCall(ExprState *state, AggState *aggstate, */ ExprState * ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, + const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, int numCols, - AttrNumber *keyColIdx, - Oid *eqfunctions, + const AttrNumber *keyColIdx, + const Oid *eqfunctions, + const Oid *collations, PlanState *parent) { ExprState *state = makeNode(ExprState); @@ -3253,13 +3370,19 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, /* push deform steps */ scratch.opcode = EEOP_INNER_FETCHSOME; scratch.d.fetch.last_var = maxatt; + scratch.d.fetch.fixed = false; scratch.d.fetch.known_desc = ldesc; - ExprEvalPushStep(state, &scratch); + scratch.d.fetch.kind = lops; + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); scratch.opcode = EEOP_OUTER_FETCHSOME; scratch.d.fetch.last_var = maxatt; + scratch.d.fetch.fixed = false; scratch.d.fetch.known_desc = rdesc; - ExprEvalPushStep(state, &scratch); + scratch.d.fetch.kind = rops; + if (ExecComputeSlotInfo(state, &scratch)) + ExprEvalPushStep(state, &scratch); /* * Start comparing at the last field (least significant sort key). That's @@ -3271,6 +3394,7 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, Form_pg_attribute latt = TupleDescAttr(ldesc, attno - 1); Form_pg_attribute ratt = TupleDescAttr(rdesc, attno - 1); Oid foid = eqfunctions[natt]; + Oid collid = collations[natt]; FmgrInfo *finfo; FunctionCallInfo fcinfo; AclResult aclresult; @@ -3284,26 +3408,26 @@ ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, /* Set up the primary fmgr lookup information */ finfo = palloc0(sizeof(FmgrInfo)); - fcinfo = palloc0(sizeof(FunctionCallInfoData)); + fcinfo = palloc0(SizeForFunctionCallInfo(2)); fmgr_info(foid, finfo); fmgr_info_set_expr(NULL, finfo); InitFunctionCallInfoData(*fcinfo, finfo, 2, - InvalidOid, NULL, NULL); + collid, NULL, NULL); /* left arg */ scratch.opcode = EEOP_INNER_VAR; scratch.d.var.attnum = attno - 1; scratch.d.var.vartype = latt->atttypid; - scratch.resvalue = &fcinfo->arg[0]; - scratch.resnull = &fcinfo->argnull[0]; + scratch.resvalue = &fcinfo->args[0].value; + scratch.resnull = &fcinfo->args[0].isnull; ExprEvalPushStep(state, &scratch); /* right arg */ scratch.opcode = EEOP_OUTER_VAR; scratch.d.var.attnum = attno - 1; scratch.d.var.vartype = ratt->atttypid; - scratch.resvalue = &fcinfo->arg[1]; - scratch.resnull = &fcinfo->argnull[1]; + scratch.resvalue = &fcinfo->args[1].value; + scratch.resnull = &fcinfo->args[1].isnull; ExprEvalPushStep(state, &scratch); /* evaluate distinctness */ diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c index e530b262dae..0cd6f65bc74 100644 --- a/src/backend/executor/execExprInterp.c +++ b/src/backend/executor/execExprInterp.c @@ -46,7 +46,7 @@ * exported rather than being "static" in this file.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -56,12 +56,13 @@ */ #include "postgres.h" -#include "access/tuptoaster.h" +#include "access/heaptoast.h" #include "catalog/pg_type.h" #include "commands/sequence.h" #include "executor/execExpr.h" #include "executor/nodeSubplan.h" #include "funcapi.h" +#include "utils/array.h" #include "utils/memutils.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" @@ -143,21 +144,28 @@ static void ExecInitInterpreter(void); /* support functions */ static void CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype); +static void CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot); static TupleDesc get_cached_rowtype(Oid type_id, int32 typmod, - TupleDesc *cache_field, ExprContext *econtext); + TupleDesc *cache_field, ExprContext *econtext); static void ShutdownTupleDescRef(Datum arg); static void ExecEvalRowNullInt(ExprState *state, ExprEvalStep *op, - ExprContext *econtext, bool checkisnull); + ExprContext *econtext, bool checkisnull); /* fast-path evaluation functions */ static Datum ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull); -static Datum ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull); static Datum ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustAssignInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustAssignOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); +static Datum ExecJustAssignScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull); /* @@ -253,11 +261,45 @@ ExecReadyInterpretedExpr(ExprState *state) return; } } - else if (state->steps_len == 2 && - state->steps[0].opcode == EEOP_CONST) + else if (state->steps_len == 2) { - state->evalfunc_private = (void *) ExecJustConst; - return; + ExprEvalOp step0 = state->steps[0].opcode; + + if (step0 == EEOP_CONST) + { + state->evalfunc_private = (void *) ExecJustConst; + return; + } + else if (step0 == EEOP_INNER_VAR) + { + state->evalfunc_private = (void *) ExecJustInnerVarVirt; + return; + } + else if (step0 == EEOP_OUTER_VAR) + { + state->evalfunc_private = (void *) ExecJustOuterVarVirt; + return; + } + else if (step0 == EEOP_SCAN_VAR) + { + state->evalfunc_private = (void *) ExecJustScanVarVirt; + return; + } + else if (step0 == EEOP_ASSIGN_INNER_VAR) + { + state->evalfunc_private = (void *) ExecJustAssignInnerVarVirt; + return; + } + else if (step0 == EEOP_ASSIGN_OUTER_VAR) + { + state->evalfunc_private = (void *) ExecJustAssignOuterVarVirt; + return; + } + else if (step0 == EEOP_ASSIGN_SCAN_VAR) + { + state->evalfunc_private = (void *) ExecJustAssignScanVarVirt; + return; + } } #if defined(EEO_USE_COMPUTED_GOTO) @@ -369,10 +411,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_FIELDSELECT, &&CASE_EEOP_FIELDSTORE_DEFORM, &&CASE_EEOP_FIELDSTORE_FORM, - &&CASE_EEOP_ARRAYREF_SUBSCRIPT, - &&CASE_EEOP_ARRAYREF_OLD, - &&CASE_EEOP_ARRAYREF_ASSIGN, - &&CASE_EEOP_ARRAYREF_FETCH, + &&CASE_EEOP_SBSREF_SUBSCRIPT, + &&CASE_EEOP_SBSREF_OLD, + &&CASE_EEOP_SBSREF_ASSIGN, + &&CASE_EEOP_SBSREF_FETCH, &&CASE_EEOP_DOMAIN_TESTVAL, &&CASE_EEOP_DOMAIN_NOTNULL, &&CASE_EEOP_DOMAIN_CHECK, @@ -386,7 +428,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) &&CASE_EEOP_ALTERNATIVE_SUBPLAN, &&CASE_EEOP_AGG_STRICT_DESERIALIZE, &&CASE_EEOP_AGG_DESERIALIZE, - &&CASE_EEOP_AGG_STRICT_INPUT_CHECK, + &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS, + &&CASE_EEOP_AGG_STRICT_INPUT_CHECK_NULLS, &&CASE_EEOP_AGG_INIT_TRANS, &&CASE_EEOP_AGG_STRICT_TRANS_CHECK, &&CASE_EEOP_AGG_PLAIN_TRANS_BYVAL, @@ -425,7 +468,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_INNER_FETCHSOME) { - /* XXX: worthwhile to check tts_nvalid inline first? */ + CheckOpSlotCompatibility(op, innerslot); + slot_getsomeattrs(innerslot, op->d.fetch.last_var); EEO_NEXT(); @@ -433,6 +477,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_OUTER_FETCHSOME) { + CheckOpSlotCompatibility(op, outerslot); + slot_getsomeattrs(outerslot, op->d.fetch.last_var); EEO_NEXT(); @@ -440,6 +486,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_SCAN_FETCHSOME) { + CheckOpSlotCompatibility(op, scanslot); + slot_getsomeattrs(scanslot, op->d.fetch.last_var); EEO_NEXT(); @@ -490,55 +538,19 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_INNER_SYSVAR) { - int attnum = op->d.var.attnum; - Datum d; - - /* these asserts must match defenses in slot_getattr */ - Assert(innerslot->tts_tuple != NULL); - Assert(innerslot->tts_tuple != &(innerslot->tts_minhdr)); - - /* heap_getsysattr has sufficient defenses against bad attnums */ - d = heap_getsysattr(innerslot->tts_tuple, attnum, - innerslot->tts_tupleDescriptor, - op->resnull); - *op->resvalue = d; - + ExecEvalSysVar(state, op, econtext, innerslot); EEO_NEXT(); } EEO_CASE(EEOP_OUTER_SYSVAR) { - int attnum = op->d.var.attnum; - Datum d; - - /* these asserts must match defenses in slot_getattr */ - Assert(outerslot->tts_tuple != NULL); - Assert(outerslot->tts_tuple != &(outerslot->tts_minhdr)); - - /* heap_getsysattr has sufficient defenses against bad attnums */ - d = heap_getsysattr(outerslot->tts_tuple, attnum, - outerslot->tts_tupleDescriptor, - op->resnull); - *op->resvalue = d; - + ExecEvalSysVar(state, op, econtext, outerslot); EEO_NEXT(); } EEO_CASE(EEOP_SCAN_SYSVAR) { - int attnum = op->d.var.attnum; - Datum d; - - /* these asserts must match defenses in slot_getattr */ - Assert(scanslot->tts_tuple != NULL); - Assert(scanslot->tts_tuple != &(scanslot->tts_minhdr)); - - /* heap_getsysattr has sufficient defenses against bad attnums */ - d = heap_getsysattr(scanslot->tts_tuple, attnum, - scanslot->tts_tupleDescriptor, - op->resnull); - *op->resvalue = d; - + ExecEvalSysVar(state, op, econtext, scanslot); EEO_NEXT(); } @@ -661,14 +673,14 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_FUNCEXPR_STRICT) { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; - bool *argnull = fcinfo->argnull; + NullableDatum *args = fcinfo->args; int argno; Datum d; /* strict function, so check for NULL args */ for (argno = 0; argno < op->d.func.nargs; argno++) { - if (argnull[argno]) + if (args[argno].isnull) { *op->resnull = true; goto strictfail; @@ -1084,8 +1096,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) FunctionCallInfo fcinfo_out; fcinfo_out = op->d.iocoerce.fcinfo_data_out; - fcinfo_out->arg[0] = *op->resvalue; - fcinfo_out->argnull[0] = false; + fcinfo_out->args[0].value = *op->resvalue; + fcinfo_out->args[0].isnull = false; fcinfo_out->isnull = false; str = DatumGetCString(FunctionCallInvoke(fcinfo_out)); @@ -1101,8 +1113,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) Datum d; fcinfo_in = op->d.iocoerce.fcinfo_data_in; - fcinfo_in->arg[0] = PointerGetDatum(str); - fcinfo_in->argnull[0] = *op->resnull; + fcinfo_in->args[0].value = PointerGetDatum(str); + fcinfo_in->args[0].isnull = *op->resnull; /* second and third arguments are already set up */ fcinfo_in->isnull = false; @@ -1129,23 +1141,23 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) { /* * IS DISTINCT FROM must evaluate arguments (already done into - * fcinfo->arg/argnull) to determine whether they are NULL; if - * either is NULL then the result is determined. If neither is - * NULL, then proceed to evaluate the comparison function, which - * is just the type's standard equality operator. We need not - * care whether that function is strict. Because the handling of - * nulls is different, we can't just reuse EEOP_FUNCEXPR. + * fcinfo->args) to determine whether they are NULL; if either is + * NULL then the result is determined. If neither is NULL, then + * proceed to evaluate the comparison function, which is just the + * type's standard equality operator. We need not care whether + * that function is strict. Because the handling of nulls is + * different, we can't just reuse EEOP_FUNCEXPR. */ FunctionCallInfo fcinfo = op->d.func.fcinfo_data; /* check function arguments for NULLness */ - if (fcinfo->argnull[0] && fcinfo->argnull[1]) + if (fcinfo->args[0].isnull && fcinfo->args[1].isnull) { /* Both NULL? Then is not distinct... */ *op->resvalue = BoolGetDatum(false); *op->resnull = false; } - else if (fcinfo->argnull[0] || fcinfo->argnull[1]) + else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull) { /* Only one is NULL? Then is distinct... */ *op->resvalue = BoolGetDatum(true); @@ -1171,12 +1183,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; - if (fcinfo->argnull[0] && fcinfo->argnull[1]) + if (fcinfo->args[0].isnull && fcinfo->args[1].isnull) { *op->resvalue = BoolGetDatum(true); *op->resnull = false; } - else if (fcinfo->argnull[0] || fcinfo->argnull[1]) + else if (fcinfo->args[0].isnull || fcinfo->args[1].isnull) { *op->resvalue = BoolGetDatum(false); *op->resnull = false; @@ -1197,12 +1209,12 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_CASE(EEOP_NULLIF) { /* - * The arguments are already evaluated into fcinfo->arg/argnull. + * The arguments are already evaluated into fcinfo->args. */ FunctionCallInfo fcinfo = op->d.func.fcinfo_data; /* if either argument is NULL they can't be equal */ - if (!fcinfo->argnull[0] && !fcinfo->argnull[1]) + if (!fcinfo->args[0].isnull && !fcinfo->args[1].isnull) { Datum result; @@ -1220,8 +1232,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) } /* Arguments aren't equal, so return the first one */ - *op->resvalue = fcinfo->arg[0]; - *op->resnull = fcinfo->argnull[0]; + *op->resvalue = fcinfo->args[0].value; + *op->resnull = fcinfo->args[0].isnull; EEO_NEXT(); } @@ -1287,7 +1299,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* force NULL result if strict fn and NULL input */ if (op->d.rowcompare_step.finfo->fn_strict && - (fcinfo->argnull[0] || fcinfo->argnull[1])) + (fcinfo->args[0].isnull || fcinfo->args[1].isnull)) { *op->resnull = true; EEO_JUMP(op->d.rowcompare_step.jumpnull); @@ -1376,43 +1388,43 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } - EEO_CASE(EEOP_ARRAYREF_SUBSCRIPT) + EEO_CASE(EEOP_SBSREF_SUBSCRIPT) { /* Process an array subscript */ /* too complex for an inline implementation */ - if (ExecEvalArrayRefSubscript(state, op)) + if (ExecEvalSubscriptingRef(state, op)) { EEO_NEXT(); } else { - /* Subscript is null, short-circuit ArrayRef to NULL */ - EEO_JUMP(op->d.arrayref_subscript.jumpdone); + /* Subscript is null, short-circuit SubscriptingRef to NULL */ + EEO_JUMP(op->d.sbsref_subscript.jumpdone); } } - EEO_CASE(EEOP_ARRAYREF_OLD) + EEO_CASE(EEOP_SBSREF_OLD) { /* - * Fetch the old value in an arrayref assignment, in case it's + * Fetch the old value in an sbsref assignment, in case it's * referenced (via a CaseTestExpr) inside the assignment * expression. */ /* too complex for an inline implementation */ - ExecEvalArrayRefOld(state, op); + ExecEvalSubscriptingRefOld(state, op); EEO_NEXT(); } /* - * Perform ArrayRef assignment + * Perform SubscriptingRef assignment */ - EEO_CASE(EEOP_ARRAYREF_ASSIGN) + EEO_CASE(EEOP_SBSREF_ASSIGN) { /* too complex for an inline implementation */ - ExecEvalArrayRefAssign(state, op); + ExecEvalSubscriptingRefAssign(state, op); EEO_NEXT(); } @@ -1420,10 +1432,10 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* * Fetch subset of an array. */ - EEO_CASE(EEOP_ARRAYREF_FETCH) + EEO_CASE(EEOP_SBSREF_FETCH) { /* too complex for an inline implementation */ - ExecEvalArrayRefFetch(state, op); + ExecEvalSubscriptingRefFetch(state, op); EEO_NEXT(); } @@ -1526,10 +1538,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* evaluate a strict aggregate deserialization function */ EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE) { - bool *argnull = op->d.agg_deserialize.fcinfo_data->argnull; - /* Don't call a strict deserialization function with NULL input */ - if (argnull[0]) + if (op->d.agg_deserialize.fcinfo_data->args[0].isnull) EEO_JUMP(op->d.agg_deserialize.jumpnull); /* fallthrough */ @@ -1559,7 +1569,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) * Check that a strict aggregate transition / combination function's * input is not NULL. */ - EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK) + EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_NULLS) { int argno; bool *nulls = op->d.agg_strict_input_check.nulls; @@ -1573,6 +1583,20 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) EEO_NEXT(); } + EEO_CASE(EEOP_AGG_STRICT_INPUT_CHECK_ARGS) + { + int argno; + NullableDatum *args = op->d.agg_strict_input_check.args; + int nargs = op->d.agg_strict_input_check.nargs; + + for (argno = 0; argno < nargs; argno++) + { + if (args[argno].isnull) + EEO_JUMP(op->d.agg_strict_input_check.jumpnull); + } + EEO_NEXT(); + } + /* * Initialize an aggregate's first value if necessary. */ @@ -1622,7 +1646,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* * Evaluate aggregate transition / combine function that has a - * by-value transition type. That's a seperate case from the + * by-value transition type. That's a separate case from the * by-reference implementation because it's a bit simpler. */ EEO_CASE(EEOP_AGG_PLAIN_TRANS_BYVAL) @@ -1643,7 +1667,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) Assert(pertrans->transtypeByVal); - fcinfo = &pertrans->transfn_fcinfo; + fcinfo = pertrans->transfn_fcinfo; /* cf. select_current_set() */ aggstate->curaggcontext = op->d.agg_trans.aggcontext; @@ -1655,8 +1679,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* invoke transition function in per-tuple context */ oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - fcinfo->arg[0] = pergroup->transValue; - fcinfo->argnull[0] = pergroup->transValueIsNull; + fcinfo->args[0].value = pergroup->transValue; + fcinfo->args[0].isnull = pergroup->transValueIsNull; fcinfo->isnull = false; /* just in case transfn doesn't set it */ newVal = FunctionCallInvoke(fcinfo); @@ -1694,7 +1718,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) Assert(!pertrans->transtypeByVal); - fcinfo = &pertrans->transfn_fcinfo; + fcinfo = pertrans->transfn_fcinfo; /* cf. select_current_set() */ aggstate->curaggcontext = op->d.agg_trans.aggcontext; @@ -1706,8 +1730,8 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull) /* invoke transition function in per-tuple context */ oldContext = MemoryContextSwitchTo(aggstate->tmpcontext->ecxt_per_tuple_memory); - fcinfo->arg[0] = pergroup->transValue; - fcinfo->argnull[0] = pergroup->transValueIsNull; + fcinfo->args[0].value = pergroup->transValue; + fcinfo->args[0].isnull = pergroup->transValueIsNull; fcinfo->isnull = false; /* just in case transfn doesn't set it */ newVal = FunctionCallInvoke(fcinfo); @@ -1890,6 +1914,39 @@ CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype) } } +/* + * Verify that the slot is compatible with a EEOP_*_FETCHSOME operation. + */ +static void +CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot) +{ +#ifdef USE_ASSERT_CHECKING + /* there's nothing to check */ + if (!op->d.fetch.fixed) + return; + + /* + * Should probably fixed at some point, but for now it's easier to allow + * buffer and heap tuples to be used interchangeably. + */ + if (slot->tts_ops == &TTSOpsBufferHeapTuple && + op->d.fetch.kind == &TTSOpsHeapTuple) + return; + if (slot->tts_ops == &TTSOpsHeapTuple && + op->d.fetch.kind == &TTSOpsBufferHeapTuple) + return; + + /* + * At the moment we consider it OK if a virtual slot is used instead of a + * specific type of slot, as a virtual slot never needs to be deformed. + */ + if (slot->tts_ops == &TTSOpsVirtual) + return; + + Assert(op->d.fetch.kind == slot->tts_ops); +#endif +} + /* * get_cached_rowtype: utility function to lookup a rowtype tupdesc * @@ -1949,13 +2006,14 @@ ShutdownTupleDescRef(Datum arg) * Fast-path functions, for very simple expressions */ -/* Simple reference to inner Var */ -static Datum -ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) +/* implementation of ExecJust(Inner|Outer|Scan)Var */ +static pg_attribute_always_inline Datum +ExecJustVarImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) { ExprEvalStep *op = &state->steps[1]; int attnum = op->d.var.attnum + 1; - TupleTableSlot *slot = econtext->ecxt_innertuple; + + CheckOpSlotCompatibility(&state->steps[0], slot); /* * Since we use slot_getattr(), we don't need to implement the FETCHSOME @@ -1965,50 +2023,38 @@ ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) return slot_getattr(slot, attnum, isnull); } -/* Simple reference to outer Var */ +/* Simple reference to inner Var */ static Datum -ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull) +ExecJustInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) { - ExprEvalStep *op = &state->steps[1]; - int attnum = op->d.var.attnum + 1; - TupleTableSlot *slot = econtext->ecxt_outertuple; - - /* See comments in ExecJustInnerVar */ - return slot_getattr(slot, attnum, isnull); + return ExecJustVarImpl(state, econtext->ecxt_innertuple, isnull); } -/* Simple reference to scan Var */ +/* Simple reference to outer Var */ static Datum -ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull) +ExecJustOuterVar(ExprState *state, ExprContext *econtext, bool *isnull) { - ExprEvalStep *op = &state->steps[1]; - int attnum = op->d.var.attnum + 1; - TupleTableSlot *slot = econtext->ecxt_scantuple; - - /* See comments in ExecJustInnerVar */ - return slot_getattr(slot, attnum, isnull); + return ExecJustVarImpl(state, econtext->ecxt_outertuple, isnull); } -/* Simple Const expression */ +/* Simple reference to scan Var */ static Datum -ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull) +ExecJustScanVar(ExprState *state, ExprContext *econtext, bool *isnull) { - ExprEvalStep *op = &state->steps[0]; - - *isnull = op->d.constval.isnull; - return op->d.constval.value; + return ExecJustVarImpl(state, econtext->ecxt_scantuple, isnull); } -/* Evaluate inner Var and assign to appropriate column of result tuple */ -static Datum -ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) +/* implementation of ExecJustAssign(Inner|Outer|Scan)Var */ +static pg_attribute_always_inline Datum +ExecJustAssignVarImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull) { ExprEvalStep *op = &state->steps[1]; int attnum = op->d.assign_var.attnum + 1; int resultnum = op->d.assign_var.resultnum; - TupleTableSlot *inslot = econtext->ecxt_innertuple; TupleTableSlot *outslot = state->resultslot; + CheckOpSlotCompatibility(&state->steps[0], inslot); + /* * We do not need CheckVarSlotCompatibility here; that was taken care of * at compilation time. @@ -2022,36 +2068,25 @@ ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) return 0; } +/* Evaluate inner Var and assign to appropriate column of result tuple */ +static Datum +ExecJustAssignInnerVar(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustAssignVarImpl(state, econtext->ecxt_innertuple, isnull); +} + /* Evaluate outer Var and assign to appropriate column of result tuple */ static Datum ExecJustAssignOuterVar(ExprState *state, ExprContext *econtext, bool *isnull) { - ExprEvalStep *op = &state->steps[1]; - int attnum = op->d.assign_var.attnum + 1; - int resultnum = op->d.assign_var.resultnum; - TupleTableSlot *inslot = econtext->ecxt_outertuple; - TupleTableSlot *outslot = state->resultslot; - - /* See comments in ExecJustAssignInnerVar */ - outslot->tts_values[resultnum] = - slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]); - return 0; + return ExecJustAssignVarImpl(state, econtext->ecxt_outertuple, isnull); } /* Evaluate scan Var and assign to appropriate column of result tuple */ static Datum ExecJustAssignScanVar(ExprState *state, ExprContext *econtext, bool *isnull) { - ExprEvalStep *op = &state->steps[1]; - int attnum = op->d.assign_var.attnum + 1; - int resultnum = op->d.assign_var.resultnum; - TupleTableSlot *inslot = econtext->ecxt_scantuple; - TupleTableSlot *outslot = state->resultslot; - - /* See comments in ExecJustAssignInnerVar */ - outslot->tts_values[resultnum] = - slot_getattr(inslot, attnum, &outslot->tts_isnull[resultnum]); - return 0; + return ExecJustAssignVarImpl(state, econtext->ecxt_scantuple, isnull); } /* Evaluate CASE_TESTVAL and apply a strict function to it */ @@ -2060,7 +2095,7 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull) { ExprEvalStep *op = &state->steps[0]; FunctionCallInfo fcinfo; - bool *argnull; + NullableDatum *args; int argno; Datum d; @@ -2074,12 +2109,12 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull) op++; fcinfo = op->d.func.fcinfo_data; - argnull = fcinfo->argnull; + args = fcinfo->args; /* strict function, so check for NULL args */ for (argno = 0; argno < op->d.func.nargs; argno++) { - if (argnull[argno]) + if (args[argno].isnull) { *isnull = true; return (Datum) 0; @@ -2091,6 +2126,101 @@ ExecJustApplyFuncToCase(ExprState *state, ExprContext *econtext, bool *isnull) return d; } +/* Simple Const expression */ +static Datum +ExecJustConst(ExprState *state, ExprContext *econtext, bool *isnull) +{ + ExprEvalStep *op = &state->steps[0]; + + *isnull = op->d.constval.isnull; + return op->d.constval.value; +} + +/* implementation of ExecJust(Inner|Outer|Scan)VarVirt */ +static pg_attribute_always_inline Datum +ExecJustVarVirtImpl(ExprState *state, TupleTableSlot *slot, bool *isnull) +{ + ExprEvalStep *op = &state->steps[0]; + int attnum = op->d.var.attnum; + + /* + * As it is guaranteed that a virtual slot is used, there never is a need + * to perform tuple deforming (nor would it be possible). Therefore + * execExpr.c has not emitted an EEOP_*_FETCHSOME step. Verify, as much as + * possible, that that determination was accurate. + */ + Assert(TTS_IS_VIRTUAL(slot)); + Assert(TTS_FIXED(slot)); + Assert(attnum >= 0 && attnum < slot->tts_nvalid); + + *isnull = slot->tts_isnull[attnum]; + + return slot->tts_values[attnum]; +} + +/* Like ExecJustInnerVar, optimized for virtual slots */ +static Datum +ExecJustInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustVarVirtImpl(state, econtext->ecxt_innertuple, isnull); +} + +/* Like ExecJustOuterVar, optimized for virtual slots */ +static Datum +ExecJustOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustVarVirtImpl(state, econtext->ecxt_outertuple, isnull); +} + +/* Like ExecJustScanVar, optimized for virtual slots */ +static Datum +ExecJustScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustVarVirtImpl(state, econtext->ecxt_scantuple, isnull); +} + +/* implementation of ExecJustAssign(Inner|Outer|Scan)VarVirt */ +static pg_attribute_always_inline Datum +ExecJustAssignVarVirtImpl(ExprState *state, TupleTableSlot *inslot, bool *isnull) +{ + ExprEvalStep *op = &state->steps[0]; + int attnum = op->d.assign_var.attnum; + int resultnum = op->d.assign_var.resultnum; + TupleTableSlot *outslot = state->resultslot; + + /* see ExecJustVarVirtImpl for comments */ + + Assert(TTS_IS_VIRTUAL(inslot)); + Assert(TTS_FIXED(inslot)); + Assert(attnum >= 0 && attnum < inslot->tts_nvalid); + + outslot->tts_values[resultnum] = inslot->tts_values[attnum]; + outslot->tts_isnull[resultnum] = inslot->tts_isnull[attnum]; + + return 0; +} + +/* Like ExecJustAssignInnerVar, optimized for virtual slots */ +static Datum +ExecJustAssignInnerVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustAssignVarVirtImpl(state, econtext->ecxt_innertuple, isnull); +} + +/* Like ExecJustAssignOuterVar, optimized for virtual slots */ +static Datum +ExecJustAssignOuterVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustAssignVarVirtImpl(state, econtext->ecxt_outertuple, isnull); +} + +/* Like ExecJustAssignScanVar, optimized for virtual slots */ +static Datum +ExecJustAssignScanVarVirt(ExprState *state, ExprContext *econtext, bool *isnull) +{ + return ExecJustAssignVarVirtImpl(state, econtext->ecxt_scantuple, isnull); +} + #if defined(EEO_USE_COMPUTED_GOTO) /* * Comparator used when building address->opcode lookup table for @@ -2200,19 +2330,19 @@ ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op, */ void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op, - ExprContext *econtext) + ExprContext *econtext) { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; PgStat_FunctionCallUsage fcusage; - bool *argnull = fcinfo->argnull; + NullableDatum *args = fcinfo->args; int argno; Datum d; /* strict function, so check for NULL args */ for (argno = 0; argno < op->d.func.nargs; argno++) { - if (argnull[argno]) + if (args[argno].isnull) { *op->resnull = true; return; @@ -2252,33 +2382,6 @@ ExecEvalParamExec(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resnull = prm->isnull; } -/* - * ExecEvalParamExecParams - * - * Execute the subplan stored in PARAM_EXEC initplans params, if not executed - * till now. - */ -void -ExecEvalParamExecParams(Bitmapset *params, EState *estate) -{ - ParamExecData *prm; - int paramid; - - paramid = -1; - while ((paramid = bms_next_member(params, paramid)) >= 0) - { - prm = &(estate->es_param_exec_vals[paramid]); - - if (prm->execPlan != NULL) - { - /* Parameter not evaluated yet, so go do it */ - ExecSetParamPlan(prm->execPlan, GetPerTupleExprContext(estate)); - /* ExecSetParamPlan should have processed this param... */ - Assert(prm->execPlan == NULL); - } - } -} - /* * Evaluate a PARAM_EXTERN parameter. * @@ -2329,8 +2432,8 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext) void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op) { + LOCAL_FCINFO(fcinfo, 0); SQLValueFunction *svf = op->d.sqlvaluefunction.svf; - FunctionCallInfoData fcinfo; *op->resnull = false; @@ -2362,24 +2465,24 @@ ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op) case SVFOP_CURRENT_ROLE: case SVFOP_CURRENT_USER: case SVFOP_USER: - InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); - *op->resvalue = current_user(&fcinfo); - *op->resnull = fcinfo.isnull; + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + *op->resvalue = current_user(fcinfo); + *op->resnull = fcinfo->isnull; break; case SVFOP_SESSION_USER: - InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); - *op->resvalue = session_user(&fcinfo); - *op->resnull = fcinfo.isnull; + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + *op->resvalue = session_user(fcinfo); + *op->resnull = fcinfo->isnull; break; case SVFOP_CURRENT_CATALOG: - InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); - *op->resvalue = current_database(&fcinfo); - *op->resnull = fcinfo.isnull; + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + *op->resvalue = current_database(fcinfo); + *op->resnull = fcinfo->isnull; break; case SVFOP_CURRENT_SCHEMA: - InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); - *op->resvalue = current_schema(&fcinfo); - *op->resnull = fcinfo.isnull; + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); + *op->resvalue = current_schema(fcinfo); + *op->resnull = fcinfo->isnull; break; } } @@ -2812,8 +2915,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op) int off; /* set at initialization */ - Assert(fcinfo->argnull[0] == false); - Assert(fcinfo->argnull[1] == false); + Assert(fcinfo->args[0].isnull == false); + Assert(fcinfo->args[1].isnull == false); /* default to null result */ *op->resnull = true; @@ -2835,8 +2938,8 @@ ExecEvalMinMax(ExprState *state, ExprEvalStep *op) int cmpresult; /* apply comparison function */ - fcinfo->arg[0] = *op->resvalue; - fcinfo->arg[1] = values[off]; + fcinfo->args[0].value = *op->resvalue; + fcinfo->args[1].value = values[off]; fcinfo->isnull = false; cmpresult = DatumGetInt32(FunctionCallInvoke(fcinfo)); @@ -3043,27 +3146,27 @@ ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, ExprContext *econtext } /* - * Process a subscript in an ArrayRef expression. + * Process a subscript in a SubscriptingRef expression. * * If subscript is NULL, throw error in assignment case, or in fetch case * set result to NULL and return false (instructing caller to skip the rest - * of the ArrayRef sequence). + * of the SubscriptingRef sequence). * * Subscript expression result is in subscriptvalue/subscriptnull. * On success, integer subscript value has been saved in upperindex[] or * lowerindex[] for use later. */ bool -ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op) +ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op) { - ArrayRefState *arefstate = op->d.arrayref_subscript.state; + SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; int *indexes; int off; /* If any index expr yields NULL, result is NULL or error */ - if (arefstate->subscriptnull) + if (sbsrefstate->subscriptnull) { - if (arefstate->isassignment) + if (sbsrefstate->isassignment) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("array subscript in assignment must not be null"))); @@ -3072,124 +3175,124 @@ ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op) } /* Convert datum to int, save in appropriate place */ - if (op->d.arrayref_subscript.isupper) - indexes = arefstate->upperindex; + if (op->d.sbsref_subscript.isupper) + indexes = sbsrefstate->upperindex; else - indexes = arefstate->lowerindex; - off = op->d.arrayref_subscript.off; + indexes = sbsrefstate->lowerindex; + off = op->d.sbsref_subscript.off; - indexes[off] = DatumGetInt32(arefstate->subscriptvalue); + indexes[off] = DatumGetInt32(sbsrefstate->subscriptvalue); return true; } /* - * Evaluate ArrayRef fetch. + * Evaluate SubscriptingRef fetch. * - * Source array is in step's result variable. + * Source container is in step's result variable. */ void -ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op) +ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op) { - ArrayRefState *arefstate = op->d.arrayref.state; + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; - /* Should not get here if source array (or any subscript) is null */ + /* Should not get here if source container (or any subscript) is null */ Assert(!(*op->resnull)); - if (arefstate->numlower == 0) + if (sbsrefstate->numlower == 0) { /* Scalar case */ *op->resvalue = array_get_element(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign, + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign, op->resnull); } else { /* Slice case */ *op->resvalue = array_get_slice(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->lowerindex, - arefstate->upperprovided, - arefstate->lowerprovided, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign); + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign); } } /* - * Compute old array element/slice value for an ArrayRef assignment - * expression. Will only be generated if the new-value subexpression - * contains ArrayRef or FieldStore. The value is stored into the - * ArrayRefState's prevvalue/prevnull fields. + * Compute old container element/slice value for a SubscriptingRef assignment + * expression. Will only be generated if the new-value subexpression + * contains SubscriptingRef or FieldStore. The value is stored into the + * SubscriptingRefState's prevvalue/prevnull fields. */ void -ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op) +ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op) { - ArrayRefState *arefstate = op->d.arrayref.state; + SubscriptingRefState *sbsrefstate = op->d.sbsref.state; if (*op->resnull) { /* whole array is null, so any element or slice is too */ - arefstate->prevvalue = (Datum) 0; - arefstate->prevnull = true; + sbsrefstate->prevvalue = (Datum) 0; + sbsrefstate->prevnull = true; } - else if (arefstate->numlower == 0) + else if (sbsrefstate->numlower == 0) { /* Scalar case */ - arefstate->prevvalue = array_get_element(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign, - &arefstate->prevnull); + sbsrefstate->prevvalue = array_get_element(*op->resvalue, + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign, + &sbsrefstate->prevnull); } else { /* Slice case */ /* this is currently unreachable */ - arefstate->prevvalue = array_get_slice(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->lowerindex, - arefstate->upperprovided, - arefstate->lowerprovided, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign); - arefstate->prevnull = false; + sbsrefstate->prevvalue = array_get_slice(*op->resvalue, + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign); + sbsrefstate->prevnull = false; } } /* - * Evaluate ArrayRef assignment. + * Evaluate SubscriptingRef assignment. * - * Input array (possibly null) is in result area, replacement value is in - * ArrayRefState's replacevalue/replacenull. + * Input container (possibly null) is in result area, replacement value is in + * SubscriptingRefState's replacevalue/replacenull. */ void -ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op) +ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op) { - ArrayRefState *arefstate = op->d.arrayref.state; + SubscriptingRefState *sbsrefstate = op->d.sbsref_subscript.state; /* - * For an assignment to a fixed-length array type, both the original array - * and the value to be assigned into it must be non-NULL, else we punt and - * return the original array. + * For an assignment to a fixed-length container type, both the original + * container and the value to be assigned into it must be non-NULL, else + * we punt and return the original container. */ - if (arefstate->refattrlength > 0) /* fixed-length array? */ + if (sbsrefstate->refattrlength > 0) { - if (*op->resnull || arefstate->replacenull) + if (*op->resnull || sbsrefstate->replacenull) return; } @@ -3201,38 +3304,38 @@ ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op) */ if (*op->resnull) { - *op->resvalue = PointerGetDatum(construct_empty_array(arefstate->refelemtype)); + *op->resvalue = PointerGetDatum(construct_empty_array(sbsrefstate->refelemtype)); *op->resnull = false; } - if (arefstate->numlower == 0) + if (sbsrefstate->numlower == 0) { /* Scalar case */ *op->resvalue = array_set_element(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->replacevalue, - arefstate->replacenull, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign); + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->replacevalue, + sbsrefstate->replacenull, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign); } else { /* Slice case */ *op->resvalue = array_set_slice(*op->resvalue, - arefstate->numupper, - arefstate->upperindex, - arefstate->lowerindex, - arefstate->upperprovided, - arefstate->lowerprovided, - arefstate->replacevalue, - arefstate->replacenull, - arefstate->refattrlength, - arefstate->refelemlength, - arefstate->refelembyval, - arefstate->refelemalign); + sbsrefstate->numupper, + sbsrefstate->upperindex, + sbsrefstate->lowerindex, + sbsrefstate->upperprovided, + sbsrefstate->lowerprovided, + sbsrefstate->replacevalue, + sbsrefstate->replacenull, + sbsrefstate->refattrlength, + sbsrefstate->refelemlength, + sbsrefstate->refelembyval, + sbsrefstate->refelemalign); } } @@ -3297,9 +3400,7 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext old_cxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); /* prepare map from old to new attribute numbers */ - op->d.convert_rowtype.map = - convert_tuples_by_name(indesc, outdesc, - gettext_noop("could not convert row type")); + op->d.convert_rowtype.map = convert_tuples_by_name(indesc, outdesc); op->d.convert_rowtype.initialized = true; MemoryContextSwitchTo(old_cxt); @@ -3312,7 +3413,7 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext if (op->d.convert_rowtype.map != NULL) { /* Full conversion with attribute rearrangement needed */ - result = do_convert_tuple(&tmptup, op->d.convert_rowtype.map); + result = execute_attr_map_tuple(&tmptup, op->d.convert_rowtype.map); /* Result already has appropriate composite-datum header fields */ *op->resvalue = HeapTupleGetDatum(result); } @@ -3336,7 +3437,7 @@ ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, ExprContext *econtext * Evaluate "scalar op ANY/ALL (array)". * * Source array is in our result area, scalar arg is already evaluated into - * fcinfo->arg[0]/argnull[0]. + * fcinfo->args[0]. * * The operator always yields boolean, and we combine the results across all * array elements using OR and AND (for ANY and ALL respectively). Of course @@ -3388,7 +3489,7 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op) * If the scalar is NULL, and the function is strict, return NULL; no * point in iterating the loop. */ - if (fcinfo->argnull[0] && strictfunc) + if (fcinfo->args[0].isnull && strictfunc) { *op->resnull = true; return; @@ -3428,20 +3529,20 @@ ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op) /* Get array element, checking for NULL */ if (bitmap && (*bitmap & bitmask) == 0) { - fcinfo->arg[1] = (Datum) 0; - fcinfo->argnull[1] = true; + fcinfo->args[1].value = (Datum) 0; + fcinfo->args[1].isnull = true; } else { elt = fetch_att(s, typbyval, typlen); s = att_addlength_pointer(s, typlen, s); s = (char *) att_align_nominal(s, typalign); - fcinfo->arg[1] = elt; - fcinfo->argnull[1] = false; + fcinfo->args[1].value = elt; + fcinfo->args[1].isnull = false; } /* Call comparison function */ - if (fcinfo->argnull[1] && strictfunc) + if (fcinfo->args[1].isnull && strictfunc) { fcinfo->isnull = true; thisresult = (Datum) 0; @@ -3961,10 +4062,10 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext) * perhaps other places.) */ if (econtext->ecxt_estate && - variable->varno <= list_length(econtext->ecxt_estate->es_range_table)) + variable->varno <= econtext->ecxt_estate->es_range_table_size) { - RangeTblEntry *rte = rt_fetch(variable->varno, - econtext->ecxt_estate->es_range_table); + RangeTblEntry *rte = exec_rt_fetch(variable->varno, + econtext->ecxt_estate); if (rte->eref) ExecTypeSetColNames(output_tupdesc, rte->eref->colnames); @@ -4033,6 +4134,22 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext) *op->resnull = false; } +void +ExecEvalSysVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext, + TupleTableSlot *slot) +{ + Datum d; + + /* slot_getsysattr has sufficient defenses against bad attnums */ + d = slot_getsysattr(slot, + op->d.var.attnum, + op->resnull); + *op->resvalue = d; + /* this ought to be unreachable, but it's cheap enough to check */ + if (unlikely(*op->resnull)) + elog(ERROR, "failed to fetch attribute from slot"); +} + /* * Transition value has not been initialized. This is the first non-NULL input * value for a group. We use it as the initial value for transValue. @@ -4040,7 +4157,7 @@ ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, ExprContext *econtext) void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup) { - FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + FunctionCallInfo fcinfo = pertrans->transfn_fcinfo; MemoryContext oldContext; /* @@ -4051,7 +4168,7 @@ ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup */ oldContext = MemoryContextSwitchTo( aggstate->curaggcontext->ecxt_per_tuple_memory); - pergroup->transValue = datumCopy(fcinfo->arg[1], + pergroup->transValue = datumCopy(fcinfo->args[1].value, pertrans->transtypeByVal, pertrans->transtypeLen); pergroup->transValueIsNull = false; diff --git a/src/backend/executor/execGrouping.c b/src/backend/executor/execGrouping.c index c4d0e040587..6349c11e1d5 100644 --- a/src/backend/executor/execGrouping.c +++ b/src/backend/executor/execGrouping.c @@ -7,7 +7,7 @@ * collation-sensitive, so the code in this file has no support for passing * collation settings through from callers. That may have to change someday. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,7 +18,6 @@ */ #include "postgres.h" -#include "access/hash.h" #include "access/parallel.h" #include "executor/executor.h" #include "miscadmin.h" @@ -59,8 +58,9 @@ static int TupleHashTableMatch(struct tuplehash_hash *tb, const MinimalTuple tup ExprState * execTuplesMatchPrepare(TupleDesc desc, int numCols, - AttrNumber *keyColIdx, - Oid *eqOperators, + const AttrNumber *keyColIdx, + const Oid *eqOperators, + const Oid *collations, PlanState *parent) { Oid *eqFunctions = (Oid *) palloc(numCols * sizeof(Oid)); @@ -75,7 +75,8 @@ execTuplesMatchPrepare(TupleDesc desc, eqFunctions[i] = get_opcode(eqOperators[i]); /* build actual expression */ - expr = ExecBuildGroupingEqual(desc, desc, numCols, keyColIdx, eqFunctions, + expr = ExecBuildGroupingEqual(desc, desc, NULL, NULL, + numCols, keyColIdx, eqFunctions, collations, parent); return expr; @@ -93,7 +94,7 @@ execTuplesMatchPrepare(TupleDesc desc, */ void execTuplesHashPrepare(int numCols, - Oid *eqOperators, + const Oid *eqOperators, Oid **eqFuncOids, FmgrInfo **hashFunctions) { @@ -138,7 +139,8 @@ execTuplesHashPrepare(int numCols, * hashfunctions: datatype-specific hashing functions to use * nbuckets: initial estimate of hashtable size * additionalsize: size of data stored in ->additional - * tablecxt: memory context in which to store table and table entries + * metacxt: memory context for long-lived allocation, but not per-entry data + * tablecxt: memory context in which to store table entries * tempcxt: short-lived context for evaluation hash and comparison functions * * The function arrays may be made with execTuplesHashPrepare(). Note they @@ -149,30 +151,36 @@ execTuplesHashPrepare(int numCols, * storage that will live as long as the hashtable does. */ TupleHashTable -BuildTupleHashTable(PlanState *parent, - TupleDesc inputDesc, - int numCols, AttrNumber *keyColIdx, - Oid *eqfuncoids, - FmgrInfo *hashfunctions, - long nbuckets, Size additionalsize, - MemoryContext tablecxt, MemoryContext tempcxt, - bool use_variable_hash_iv) +BuildTupleHashTableExt(PlanState *parent, + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext metacxt, + MemoryContext tablecxt, + MemoryContext tempcxt, + bool use_variable_hash_iv) { TupleHashTable hashtable; Size entrysize = sizeof(TupleHashEntryData) + additionalsize; MemoryContext oldcontext; + bool allow_jit; Assert(nbuckets > 0); /* Limit initial table size request to not more than work_mem */ nbuckets = Min(nbuckets, (long) ((work_mem * 1024L) / entrysize)); - hashtable = (TupleHashTable) - MemoryContextAlloc(tablecxt, sizeof(TupleHashTableData)); + oldcontext = MemoryContextSwitchTo(metacxt); + + hashtable = (TupleHashTable) palloc(sizeof(TupleHashTableData)); hashtable->numCols = numCols; hashtable->keyColIdx = keyColIdx; hashtable->tab_hash_funcs = hashfunctions; + hashtable->tab_collations = collations; hashtable->tablecxt = tablecxt; hashtable->tempcxt = tempcxt; hashtable->entrysize = entrysize; @@ -194,29 +202,88 @@ BuildTupleHashTable(PlanState *parent, else hashtable->hash_iv = 0; - hashtable->hashtab = tuplehash_create(tablecxt, nbuckets, hashtable); - - oldcontext = MemoryContextSwitchTo(hashtable->tablecxt); + hashtable->hashtab = tuplehash_create(metacxt, nbuckets, hashtable); /* * We copy the input tuple descriptor just for safety --- we assume all * input tuples will have equivalent descriptors. */ - hashtable->tableslot = MakeSingleTupleTableSlot(CreateTupleDescCopy(inputDesc)); + hashtable->tableslot = MakeSingleTupleTableSlot(CreateTupleDescCopy(inputDesc), + &TTSOpsMinimalTuple); + + /* + * If the old reset interface is used (i.e. BuildTupleHashTable, rather + * than BuildTupleHashTableExt), allowing JIT would lead to the generated + * functions to a) live longer than the query b) be re-generated each time + * the table is being reset. Therefore prevent JIT from being used in that + * case, by not providing a parent node (which prevents accessing the + * JitContext in the EState). + */ + allow_jit = metacxt != tablecxt; /* build comparator for all columns */ + /* XXX: should we support non-minimal tuples for the inputslot? */ hashtable->tab_eq_func = ExecBuildGroupingEqual(inputDesc, inputDesc, + &TTSOpsMinimalTuple, &TTSOpsMinimalTuple, numCols, - keyColIdx, eqfuncoids, - parent); + keyColIdx, eqfuncoids, collations, + allow_jit ? parent : NULL); - MemoryContextSwitchTo(oldcontext); + /* + * While not pretty, it's ok to not shut down this context, but instead + * rely on the containing memory context being reset, as + * ExecBuildGroupingEqual() only builds a very simple expression calling + * functions (i.e. nothing that'd employ RegisterExprContextCallback()). + */ + hashtable->exprcontext = CreateStandaloneExprContext(); - hashtable->exprcontext = CreateExprContext(parent->state); + MemoryContextSwitchTo(oldcontext); return hashtable; } +/* + * BuildTupleHashTable is a backwards-compatibilty wrapper for + * BuildTupleHashTableExt(), that allocates the hashtable's metadata in + * tablecxt. Note that hashtables created this way cannot be reset leak-free + * with ResetTupleHashTable(). + */ +TupleHashTable +BuildTupleHashTable(PlanState *parent, + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext tablecxt, + MemoryContext tempcxt, + bool use_variable_hash_iv) +{ + return BuildTupleHashTableExt(parent, + inputDesc, + numCols, keyColIdx, + eqfuncoids, + hashfunctions, + collations, + nbuckets, additionalsize, + tablecxt, + tablecxt, + tempcxt, + use_variable_hash_iv); +} + +/* + * Reset contents of the hashtable to be empty, preserving all the non-content + * state. Note that the tablecxt passed to BuildTupleHashTableExt() should + * also be reset, otherwise there will be leaks. + */ +void +ResetTupleHashTable(TupleHashTable hashtable) +{ + tuplehash_reset(hashtable->hashtab); +} + /* * Find or create a hashtable entry for the tuple group containing the * given tuple. The tuple must be the same type as the hashtable entries. @@ -370,8 +437,9 @@ TupleHashTableHash(struct tuplehash_hash *tb, const MinimalTuple tuple) { uint32 hkey; - hkey = DatumGetUInt32(FunctionCall1(&hashfunctions[i], - attr)); + hkey = DatumGetUInt32(FunctionCall1Coll(&hashfunctions[i], + hashtable->tab_collations[i], + attr)); hashkey ^= hkey; } } diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c index 903076ee3c4..40bd8049f05 100644 --- a/src/backend/executor/execIndexing.c +++ b/src/backend/executor/execIndexing.c @@ -95,7 +95,7 @@ * with the higher XID backs out. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -106,13 +106,15 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/index.h" #include "executor/executor.h" #include "nodes/nodeFuncs.h" #include "storage/lmgr.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" /* waitMode argument to check_exclusion_or_unique_constraint() */ typedef enum @@ -123,17 +125,17 @@ typedef enum } CEOUC_WAIT_MODE; static bool check_exclusion_or_unique_constraint(Relation heap, Relation index, - IndexInfo *indexInfo, - ItemPointer tupleid, - Datum *values, bool *isnull, - EState *estate, bool newIndex, - CEOUC_WAIT_MODE waitMode, - bool errorOK, - ItemPointer conflictTid); + IndexInfo *indexInfo, + ItemPointer tupleid, + Datum *values, bool *isnull, + EState *estate, bool newIndex, + CEOUC_WAIT_MODE waitMode, + bool errorOK, + ItemPointer conflictTid); static bool index_recheck_constraint(Relation index, Oid *constr_procs, - Datum *existing_values, bool *existing_isnull, - Datum *new_values); + Datum *existing_values, bool *existing_isnull, + Datum *new_values); /* ---------------------------------------------------------------- * ExecOpenIndices @@ -184,7 +186,7 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative) * For each index, open the index relation and save pg_index info. We * acquire RowExclusiveLock, signifying we will update the index. * - * Note: we do this even if the index is not IndexIsReady; it's not worth + * Note: we do this even if the index is not indisready; it's not worth * the trouble to optimize for the case where it isn't. */ i = 0; @@ -269,12 +271,12 @@ ExecCloseIndices(ResultRelInfo *resultRelInfo) */ List * ExecInsertIndexTuples(TupleTableSlot *slot, - ItemPointer tupleid, EState *estate, bool noDupErr, bool *specConflict, List *arbiterIndexes) { + ItemPointer tupleid = &slot->tts_tid; List *result = NIL; ResultRelInfo *resultRelInfo; int i; @@ -286,6 +288,8 @@ ExecInsertIndexTuples(TupleTableSlot *slot, Datum values[INDEX_MAX_KEYS]; bool isnull[INDEX_MAX_KEYS]; + Assert(ItemPointerIsValid(tupleid)); + /* * Get information from the result relation info structure. */ @@ -295,6 +299,9 @@ ExecInsertIndexTuples(TupleTableSlot *slot, indexInfoArray = resultRelInfo->ri_IndexRelationInfo; heapRelation = resultRelInfo->ri_RelationDesc; + /* Sanity check: slot must belong to the same rel as the resultRelInfo. */ + Assert(slot->tts_tableOid == RelationGetRelid(heapRelation)); + /* * We will use the EState's per-tuple context for evaluating predicates * and index expressions (creating it if it's not already there). @@ -650,7 +657,6 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, Oid *index_collations = index->rd_indcollation; int indnkeyatts = IndexRelationGetNumberOfKeyAttributes(index); IndexScanDesc index_scan; - HeapTuple tup; ScanKeyData scankeys[INDEX_MAX_KEYS]; SnapshotData DirtySnapshot; int i; @@ -706,7 +712,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, * to this slot. Be sure to save and restore caller's value for * scantuple. */ - existing_slot = MakeSingleTupleTableSlot(RelationGetDescr(heap)); + existing_slot = table_slot_create(heap, NULL); econtext = GetPerTupleExprContext(estate); save_scantuple = econtext->ecxt_scantuple; @@ -722,11 +728,9 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, index_scan = index_beginscan(heap, index, &DirtySnapshot, indnkeyatts, 0); index_rescan(index_scan, scankeys, indnkeyatts, NULL, 0); - while ((tup = index_getnext(index_scan, - ForwardScanDirection)) != NULL) + while (index_getnext_slot(index_scan, ForwardScanDirection, existing_slot)) { TransactionId xwait; - ItemPointerData ctid_wait; XLTW_Oper reason_wait; Datum existing_values[INDEX_MAX_KEYS]; bool existing_isnull[INDEX_MAX_KEYS]; @@ -737,7 +741,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, * Ignore the entry for the tuple we're trying to check. */ if (ItemPointerIsValid(tupleid) && - ItemPointerEquals(tupleid, &tup->t_self)) + ItemPointerEquals(tupleid, &existing_slot->tts_tid)) { if (found_self) /* should not happen */ elog(ERROR, "found self tuple multiple times in index \"%s\"", @@ -750,7 +754,6 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, * Extract the index column values and isnull flags from the existing * tuple. */ - ExecStoreTuple(tup, existing_slot, InvalidBuffer, false); FormIndexDatum(indexInfo, existing_slot, estate, existing_values, existing_isnull); @@ -785,7 +788,6 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, DirtySnapshot.speculativeToken && TransactionIdPrecedes(GetCurrentTransactionId(), xwait)))) { - ctid_wait = tup->t_data->t_ctid; reason_wait = indexInfo->ii_ExclusionOps ? XLTW_RecheckExclusionConstr : XLTW_InsertIndex; index_endscan(index_scan); @@ -793,7 +795,8 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, SpeculativeInsertionWait(DirtySnapshot.xmin, DirtySnapshot.speculativeToken); else - XactLockTableWait(xwait, heap, &ctid_wait, reason_wait); + XactLockTableWait(xwait, heap, + &existing_slot->tts_tid, reason_wait); goto retry; } @@ -805,7 +808,7 @@ check_exclusion_or_unique_constraint(Relation heap, Relation index, { conflict = true; if (conflictTid) - *conflictTid = tup->t_self; + *conflictTid = existing_slot->tts_tid; break; } diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c index 57d74e57c1a..897ff52e034 100644 --- a/src/backend/executor/execJunk.c +++ b/src/backend/executor/execJunk.c @@ -3,7 +3,7 @@ * execJunk.c * Junk attribute support stuff.... * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -53,12 +53,11 @@ * Initialize the Junk filter. * * The source targetlist is passed in. The output tuple descriptor is - * built from the non-junk tlist entries, plus the passed specification - * of whether to include room for an OID or not. + * built from the non-junk tlist entries. * An optional resultSlot can be passed as well. */ JunkFilter * -ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot) +ExecInitJunkFilter(List *targetList, TupleTableSlot *slot) { JunkFilter *junkfilter; TupleDesc cleanTupType; @@ -70,7 +69,7 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot) /* * Compute the tuple descriptor for the cleaned tuple. */ - cleanTupType = ExecCleanTypeFromTL(targetList, hasoid); + cleanTupType = ExecCleanTypeFromTL(targetList); /* * Use the given slot, or make a new slot if we weren't given one. @@ -78,7 +77,7 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot) if (slot) ExecSetSlotDescriptor(slot, cleanTupType); else - slot = MakeSingleTupleTableSlot(cleanTupType); + slot = MakeSingleTupleTableSlot(cleanTupType, &TTSOpsVirtual); /* * Now calculate the mapping between the original tuple's attributes and @@ -149,7 +148,7 @@ ExecInitJunkFilterConversion(List *targetList, if (slot) ExecSetSlotDescriptor(slot, cleanTupType); else - slot = MakeSingleTupleTableSlot(cleanTupType); + slot = MakeSingleTupleTableSlot(cleanTupType, &TTSOpsVirtual); /* * Calculate the mapping between the original tuple's attributes and the @@ -174,7 +173,7 @@ ExecInitJunkFilterConversion(List *targetList, { TargetEntry *tle = lfirst(t); - t = lnext(t); + t = lnext(targetList, t); if (!tle->resjunk) { cleanMap[i] = tle->resno; diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 13ad92745e0..ea4b5869848 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * before ExecutorEnd. This can be omitted only in case of EXPLAIN, * which should also omit ExecutorRun. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,33 +37,33 @@ */ #include "postgres.h" +#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/namespace.h" -#include "catalog/partition.h" #include "catalog/pg_publication.h" #include "commands/matview.h" #include "commands/trigger.h" #include "executor/execdebug.h" +#include "executor/nodeSubplan.h" #include "foreign/fdwapi.h" #include "jit/jit.h" #include "mb/pg_wchar.h" #include "miscadmin.h" -#include "optimizer/clauses.h" #include "parser/parsetree.h" -#include "rewrite/rewriteManip.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "tcop/utility.h" #include "utils/acl.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/partcache.h" #include "utils/rls.h" #include "utils/ruleutils.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" /* Hooks for plugins to get control in ExecutorStart/Run/Finish/End */ @@ -81,36 +81,38 @@ static void CheckValidRowMarkRel(Relation rel, RowMarkType markType); static void ExecPostprocessPlan(EState *estate); static void ExecEndPlan(PlanState *planstate, EState *estate); static void ExecutePlan(EState *estate, PlanState *planstate, - bool use_parallel_mode, - CmdType operation, - bool sendTuples, - uint64 numberTuples, - ScanDirection direction, - DestReceiver *dest, - bool execute_once); + bool use_parallel_mode, + CmdType operation, + bool sendTuples, + uint64 numberTuples, + ScanDirection direction, + DestReceiver *dest, + bool execute_once); static bool ExecCheckRTEPerms(RangeTblEntry *rte); static bool ExecCheckRTEPermsModified(Oid relOid, Oid userid, - Bitmapset *modifiedCols, - AclMode requiredPerms); + Bitmapset *modifiedCols, + AclMode requiredPerms); static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt); static char *ExecBuildSlotValueDescription(Oid reloid, - TupleTableSlot *slot, - TupleDesc tupdesc, - Bitmapset *modifiedCols, - int maxfieldlen); -static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, - Plan *planTree); + TupleTableSlot *slot, + TupleDesc tupdesc, + Bitmapset *modifiedCols, + int maxfieldlen); +static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree); /* - * Note that GetUpdatedColumns() also exists in commands/trigger.c. There does + * Note that GetAllUpdatedColumns() also exists in commands/trigger.c. There does * not appear to be any good header to put it into, given the structures that * it uses, so we let them be duplicated. Be sure to update both if one needs * to be changed, however. */ #define GetInsertedColumns(relinfo, estate) \ - (rt_fetch((relinfo)->ri_RangeTableIndex, (estate)->es_range_table)->insertedCols) + (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->insertedCols) #define GetUpdatedColumns(relinfo, estate) \ - (rt_fetch((relinfo)->ri_RangeTableIndex, (estate)->es_range_table)->updatedCols) + (exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols) +#define GetAllUpdatedColumns(relinfo, estate) \ + (bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \ + exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols)) /* end of local decls */ @@ -233,7 +235,6 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags) case CMD_INSERT: case CMD_DELETE: case CMD_UPDATE: - case CMD_MERGE: estate->es_output_cid = GetCurrentCommandId(true); break; @@ -344,7 +345,6 @@ standard_ExecutorRun(QueryDesc *queryDesc, * startup tuple receiver, if we will be emitting tuples */ estate->es_processed = 0; - estate->es_lastoid = InvalidOid; sendTuples = (operation == CMD_SELECT || queryDesc->plannedstmt->hasReturning); @@ -499,10 +499,6 @@ standard_ExecutorEnd(QueryDesc *queryDesc) UnregisterSnapshot(estate->es_snapshot); UnregisterSnapshot(estate->es_crosscheck_snapshot); - /* release JIT context, if allocated */ - if (estate->es_jit) - jit_release_context(estate->es_jit); - /* * Must switch out of context before destroying it */ @@ -827,14 +823,12 @@ InitPlan(QueryDesc *queryDesc, int eflags) /* * initialize the node's execution state */ - estate->es_range_table = rangeTable; + ExecInitRangeTable(estate, rangeTable); + estate->es_plannedstmt = plannedstmt; /* - * initialize result relation stuff, and open/lock the result rels. - * - * We must do this before initializing the plan tree, else we might try to - * do a lock upgrade if a result rel is also a source rel. + * Initialize ResultRelInfo data structures, and open the result rels. */ if (plannedstmt->resultRelations) { @@ -849,12 +843,10 @@ InitPlan(QueryDesc *queryDesc, int eflags) foreach(l, resultRelations) { Index resultRelationIndex = lfirst_int(l); - Oid resultRelationOid; Relation resultRelation; - resultRelationOid = getrelid(resultRelationIndex, rangeTable); - resultRelation = heap_open(resultRelationOid, RowExclusiveLock); - + resultRelation = ExecGetRangeTableRelation(estate, + resultRelationIndex); InitResultRelInfo(resultRelInfo, resultRelation, resultRelationIndex, @@ -864,39 +856,32 @@ InitPlan(QueryDesc *queryDesc, int eflags) } estate->es_result_relations = resultRelInfos; estate->es_num_result_relations = numResultRelations; + /* es_result_relation_info is NULL except when within ModifyTable */ estate->es_result_relation_info = NULL; /* - * In the partitioned result relation case, lock the non-leaf result - * relations too. A subset of these are the roots of respective - * partitioned tables, for which we also allocate ResulRelInfos. + * In the partitioned result relation case, also build ResultRelInfos + * for all the partitioned table roots, because we will need them to + * fire statement-level triggers, if any. */ - estate->es_root_result_relations = NULL; - estate->es_num_root_result_relations = 0; - if (plannedstmt->nonleafResultRelations) + if (plannedstmt->rootResultRelations) { int num_roots = list_length(plannedstmt->rootResultRelations); - /* - * Firstly, build ResultRelInfos for all the partitioned table - * roots, because we will need them to fire the statement-level - * triggers, if any. - */ resultRelInfos = (ResultRelInfo *) palloc(num_roots * sizeof(ResultRelInfo)); resultRelInfo = resultRelInfos; foreach(l, plannedstmt->rootResultRelations) { Index resultRelIndex = lfirst_int(l); - Oid resultRelOid; Relation resultRelDesc; - resultRelOid = getrelid(resultRelIndex, rangeTable); - resultRelDesc = heap_open(resultRelOid, RowExclusiveLock); + resultRelDesc = ExecGetRangeTableRelation(estate, + resultRelIndex); InitResultRelInfo(resultRelInfo, resultRelDesc, - lfirst_int(l), + resultRelIndex, NULL, estate->es_instrument); resultRelInfo++; @@ -904,18 +889,11 @@ InitPlan(QueryDesc *queryDesc, int eflags) estate->es_root_result_relations = resultRelInfos; estate->es_num_root_result_relations = num_roots; - - /* Simply lock the rest of them. */ - foreach(l, plannedstmt->nonleafResultRelations) - { - Index resultRelIndex = lfirst_int(l); - - /* We locked the roots above. */ - if (!list_member_int(plannedstmt->rootResultRelations, - resultRelIndex)) - LockRelationOid(getrelid(resultRelIndex, rangeTable), - RowExclusiveLock); - } + } + else + { + estate->es_root_result_relations = NULL; + estate->es_num_root_result_relations = 0; } } else @@ -931,85 +909,77 @@ InitPlan(QueryDesc *queryDesc, int eflags) } /* - * Similarly, we have to lock relations selected FOR [KEY] UPDATE/SHARE - * before we initialize the plan tree, else we'd be risking lock upgrades. - * While we are at it, build the ExecRowMark list. Any partitioned child - * tables are ignored here (because isParent=true) and will be locked by - * the first Append or MergeAppend node that references them. (Note that - * the RowMarks corresponding to partitioned child tables are present in - * the same list as the rest, i.e., plannedstmt->rowMarks.) + * Next, build the ExecRowMark array from the PlanRowMark(s), if any. */ - estate->es_rowMarks = NIL; - foreach(l, plannedstmt->rowMarks) + if (plannedstmt->rowMarks) { - PlanRowMark *rc = (PlanRowMark *) lfirst(l); - Oid relid; - Relation relation; - ExecRowMark *erm; + estate->es_rowmarks = (ExecRowMark **) + palloc0(estate->es_range_table_size * sizeof(ExecRowMark *)); + foreach(l, plannedstmt->rowMarks) + { + PlanRowMark *rc = (PlanRowMark *) lfirst(l); + Oid relid; + Relation relation; + ExecRowMark *erm; - /* ignore "parent" rowmarks; they are irrelevant at runtime */ - if (rc->isParent) - continue; + /* ignore "parent" rowmarks; they are irrelevant at runtime */ + if (rc->isParent) + continue; - /* get relation's OID (will produce InvalidOid if subquery) */ - relid = getrelid(rc->rti, rangeTable); + /* get relation's OID (will produce InvalidOid if subquery) */ + relid = exec_rt_fetch(rc->rti, estate)->relid; - /* - * If you change the conditions under which rel locks are acquired - * here, be sure to adjust ExecOpenScanRelation to match. - */ - switch (rc->markType) - { - case ROW_MARK_EXCLUSIVE: - case ROW_MARK_NOKEYEXCLUSIVE: - case ROW_MARK_SHARE: - case ROW_MARK_KEYSHARE: - relation = heap_open(relid, RowShareLock); - break; - case ROW_MARK_REFERENCE: - relation = heap_open(relid, AccessShareLock); - break; - case ROW_MARK_COPY: - /* no physical table access is required */ - relation = NULL; - break; - default: - elog(ERROR, "unrecognized markType: %d", rc->markType); - relation = NULL; /* keep compiler quiet */ - break; - } + /* open relation, if we need to access it for this mark type */ + switch (rc->markType) + { + case ROW_MARK_EXCLUSIVE: + case ROW_MARK_NOKEYEXCLUSIVE: + case ROW_MARK_SHARE: + case ROW_MARK_KEYSHARE: + case ROW_MARK_REFERENCE: + relation = ExecGetRangeTableRelation(estate, rc->rti); + break; + case ROW_MARK_COPY: + /* no physical table access is required */ + relation = NULL; + break; + default: + elog(ERROR, "unrecognized markType: %d", rc->markType); + relation = NULL; /* keep compiler quiet */ + break; + } - /* Check that relation is a legal target for marking */ - if (relation) - CheckValidRowMarkRel(relation, rc->markType); - - erm = (ExecRowMark *) palloc(sizeof(ExecRowMark)); - erm->relation = relation; - erm->relid = relid; - erm->rti = rc->rti; - erm->prti = rc->prti; - erm->rowmarkId = rc->rowmarkId; - erm->markType = rc->markType; - erm->strength = rc->strength; - erm->waitPolicy = rc->waitPolicy; - erm->ermActive = false; - ItemPointerSetInvalid(&(erm->curCtid)); - erm->ermExtra = NULL; - estate->es_rowMarks = lappend(estate->es_rowMarks, erm); + /* Check that relation is a legal target for marking */ + if (relation) + CheckValidRowMarkRel(relation, rc->markType); + + erm = (ExecRowMark *) palloc(sizeof(ExecRowMark)); + erm->relation = relation; + erm->relid = relid; + erm->rti = rc->rti; + erm->prti = rc->prti; + erm->rowmarkId = rc->rowmarkId; + erm->markType = rc->markType; + erm->strength = rc->strength; + erm->waitPolicy = rc->waitPolicy; + erm->ermActive = false; + ItemPointerSetInvalid(&(erm->curCtid)); + erm->ermExtra = NULL; + + Assert(erm->rti > 0 && erm->rti <= estate->es_range_table_size && + estate->es_rowmarks[erm->rti - 1] == NULL); + + estate->es_rowmarks[erm->rti - 1] = erm; + } } /* * Initialize the executor's tuple table to empty. */ estate->es_tupleTable = NIL; - estate->es_trig_tuple_slot = NULL; - estate->es_trig_oldtup_slot = NULL; - estate->es_trig_newtup_slot = NULL; - /* mark EvalPlanQual not active */ - estate->es_epqTuple = NULL; - estate->es_epqTupleSet = NULL; - estate->es_epqScanDone = NULL; + /* signal that this EState is not used for EPQ */ + estate->es_epq_active = NULL; /* * Initialize private state information for each SubPlan. We must do this @@ -1077,10 +1047,11 @@ InitPlan(QueryDesc *queryDesc, int eflags) if (junk_filter_needed) { JunkFilter *j; + TupleTableSlot *slot; + slot = ExecInitExtraTupleSlot(estate, NULL, &TTSOpsVirtual); j = ExecInitJunkFilter(planstate->plan->targetlist, - tupType->tdhasoid, - ExecInitExtraTupleSlot(estate, NULL)); + slot); estate->es_junkFilter = j; /* Want to return the cleaned tuple type */ @@ -1346,13 +1317,14 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_FdwState = NULL; resultRelInfo->ri_usesFdwDirectModify = false; resultRelInfo->ri_ConstraintExprs = NULL; + resultRelInfo->ri_GeneratedExprs = NULL; resultRelInfo->ri_junkFilter = NULL; resultRelInfo->ri_projectReturning = NULL; resultRelInfo->ri_onConflictArbiterIndexes = NIL; resultRelInfo->ri_onConflict = NULL; - - resultRelInfo->ri_mergeTargetRTI = 0; - resultRelInfo->ri_mergeState = (MergeState *) palloc0(sizeof (MergeState)); + resultRelInfo->ri_ReturningSlot = NULL; + resultRelInfo->ri_TrigOldSlot = NULL; + resultRelInfo->ri_TrigNewSlot = NULL; /* * Partition constraint, which also includes the partition constraint of @@ -1371,18 +1343,21 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo, resultRelInfo->ri_PartitionCheck = partition_check; resultRelInfo->ri_PartitionRoot = partition_root; - resultRelInfo->ri_PartitionReadyForRouting = false; + resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */ + resultRelInfo->ri_CopyMultiInsertBuffer = NULL; } /* - * ExecGetTriggerResultRel - * - * Get a ResultRelInfo for a trigger target relation. Most of the time, - * triggers are fired on one of the result relations of the query, and so - * we can just return a member of the es_result_relations array, the - * es_root_result_relations array (if any), or the es_leaf_result_relations - * list (if any). (Note: in self-join situations there might be multiple - * members with the same OID; if so it doesn't matter which one we pick.) + * ExecGetTriggerResultRel + * Get a ResultRelInfo for a trigger target relation. + * + * Most of the time, triggers are fired on one of the result relations of the + * query, and so we can just return a member of the es_result_relations array, + * or the es_root_result_relations array (if any), or the + * es_tuple_routing_result_relations list (if any). (Note: in self-join + * situations there might be multiple members with the same OID; if so it + * doesn't matter which one we pick.) + * * However, it is sometimes necessary to fire triggers on other relations; * this happens mainly when an RI update trigger queues additional triggers * on other relations, which will be processed in the context of the outer @@ -1421,6 +1396,7 @@ ExecGetTriggerResultRel(EState *estate, Oid relid) rInfo++; nr--; } + /* * Third, search through the result relations that were created during * tuple routing, if any. @@ -1431,6 +1407,7 @@ ExecGetTriggerResultRel(EState *estate, Oid relid) if (RelationGetRelid(rInfo->ri_RelationDesc) == relid) return rInfo; } + /* Nope, but maybe we already made an extra ResultRelInfo for it */ foreach(l, estate->es_trig_target_relations) { @@ -1446,7 +1423,7 @@ ExecGetTriggerResultRel(EState *estate, Oid relid) * event got queued, so we need take no new lock here. Also, we need not * recheck the relkind, so no need for CheckValidResultRel. */ - rel = heap_open(relid, NoLock); + rel = table_open(relid, NoLock); /* * Make the new entry in the right context. @@ -1482,72 +1459,21 @@ ExecCleanUpTriggerState(EState *estate) { ResultRelInfo *resultRelInfo = (ResultRelInfo *) lfirst(l); - /* Close indices and then the relation itself */ - ExecCloseIndices(resultRelInfo); - heap_close(resultRelInfo->ri_RelationDesc, NoLock); - } -} - -/* - * ExecContextForcesOids - * - * This is pretty grotty: when doing INSERT, UPDATE, or CREATE TABLE AS, - * we need to ensure that result tuples have space for an OID iff they are - * going to be stored into a relation that has OIDs. In other contexts - * we are free to choose whether to leave space for OIDs in result tuples - * (we generally don't want to, but we do if a physical-tlist optimization - * is possible). This routine checks the plan context and returns true if the - * choice is forced, false if the choice is not forced. In the true case, - * *hasoids is set to the required value. - * - * One reason this is ugly is that all plan nodes in the plan tree will emit - * tuples with space for an OID, though we really only need the topmost node - * to do so. However, node types like Sort don't project new tuples but just - * return their inputs, and in those cases the requirement propagates down - * to the input node. Eventually we might make this code smart enough to - * recognize how far down the requirement really goes, but for now we just - * make all plan nodes do the same thing if the top level forces the choice. - * - * We assume that if we are generating tuples for INSERT or UPDATE, - * estate->es_result_relation_info is already set up to describe the target - * relation. Note that in an UPDATE that spans an inheritance tree, some of - * the target relations may have OIDs and some not. We have to make the - * decisions on a per-relation basis as we initialize each of the subplans of - * the ModifyTable node, so ModifyTable has to set es_result_relation_info - * while initializing each subplan. - * - * CREATE TABLE AS is even uglier, because we don't have the target relation's - * descriptor available when this code runs; we have to look aside at the - * flags passed to ExecutorStart(). - */ -bool -ExecContextForcesOids(PlanState *planstate, bool *hasoids) -{ - ResultRelInfo *ri = planstate->state->es_result_relation_info; + /* + * Assert this is a "dummy" ResultRelInfo, see above. Otherwise we + * might be issuing a duplicate close against a Relation opened by + * ExecGetRangeTableRelation. + */ + Assert(resultRelInfo->ri_RangeTableIndex == 0); - if (ri != NULL) - { - Relation rel = ri->ri_RelationDesc; + /* + * Since ExecGetTriggerResultRel doesn't call ExecOpenIndices for + * these rels, we needn't call ExecCloseIndices either. + */ + Assert(resultRelInfo->ri_NumIndices == 0); - if (rel != NULL) - { - *hasoids = rel->rd_rel->relhasoids; - return true; - } + table_close(resultRelInfo->ri_RelationDesc, NoLock); } - - if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS) - { - *hasoids = true; - return true; - } - if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS) - { - *hasoids = false; - return true; - } - - return false; } /* ---------------------------------------------------------------- @@ -1606,7 +1532,8 @@ static void ExecEndPlan(PlanState *planstate, EState *estate) { ResultRelInfo *resultRelInfo; - int i; + Index num_relations; + Index i; ListCell *l; /* @@ -1633,39 +1560,29 @@ ExecEndPlan(PlanState *planstate, EState *estate) ExecResetTupleTable(estate->es_tupleTable, false); /* - * close the result relation(s) if any, but hold locks until xact commit. + * close indexes of result relation(s) if any. (Rels themselves get + * closed next.) */ resultRelInfo = estate->es_result_relations; for (i = estate->es_num_result_relations; i > 0; i--) { - /* Close indices and then the relation itself */ ExecCloseIndices(resultRelInfo); - heap_close(resultRelInfo->ri_RelationDesc, NoLock); resultRelInfo++; } - /* Close the root target relation(s). */ - resultRelInfo = estate->es_root_result_relations; - for (i = estate->es_num_root_result_relations; i > 0; i--) + /* + * close whatever rangetable Relations have been opened. We do not + * release any locks we might hold on those rels. + */ + num_relations = estate->es_range_table_size; + for (i = 0; i < num_relations; i++) { - heap_close(resultRelInfo->ri_RelationDesc, NoLock); - resultRelInfo++; + if (estate->es_relations[i]) + table_close(estate->es_relations[i], NoLock); } /* likewise close any trigger target relations */ ExecCleanUpTriggerState(estate); - - /* - * close any relations selected FOR [KEY] UPDATE/SHARE, again keeping - * locks - */ - foreach(l, estate->es_rowMarks) - { - ExecRowMark *erm = (ExecRowMark *) lfirst(l); - - if (erm->relation) - heap_close(erm->relation, NoLock); - } } /* ---------------------------------------------------------------- @@ -1734,8 +1651,12 @@ ExecutePlan(EState *estate, */ if (TupIsNull(slot)) { - /* Allow nodes to release or shut down resources. */ - (void) ExecShutdownNode(planstate); + /* + * If we know we won't need to back up, we can release resources + * at this point. + */ + if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD)) + (void) ExecShutdownNode(planstate); break; } @@ -1781,8 +1702,12 @@ ExecutePlan(EState *estate, current_tuple_count++; if (numberTuples && numberTuples == current_tuple_count) { - /* Allow nodes to release or shut down resources. */ - (void) ExecShutdownNode(planstate); + /* + * If we know we won't need to back up, we can release resources + * at this point. + */ + if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD)) + (void) ExecShutdownNode(planstate); break; } } @@ -1859,14 +1784,16 @@ ExecRelCheck(ResultRelInfo *resultRelInfo, /* * ExecPartitionCheck --- check that tuple meets the partition constraint. * - * Exported in executor.h for outside use. - * Returns true if it meets the partition constraint, else returns false. + * Returns true if it meets the partition constraint. If the constraint + * fails and we're asked to emit to error, do so and don't return; otherwise + * return false. */ bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, - EState *estate) + EState *estate, bool emitError) { ExprContext *econtext; + bool success; /* * If first time through, build expression state tree for the partition @@ -1893,7 +1820,13 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, * As in case of the catalogued constraints, we treat a NULL result as * success here, not a failure. */ - return ExecCheck(resultRelInfo->ri_PartitionCheckExpr, econtext); + success = ExecCheck(resultRelInfo->ri_PartitionCheckExpr, econtext); + + /* if asked to emit error, don't actually return on failure */ + if (!success && emitError) + ExecPartitionCheckEmitError(resultRelInfo, slot, estate); + + return success; } /* @@ -1905,41 +1838,47 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate) { - Relation rel = resultRelInfo->ri_RelationDesc; - Relation orig_rel = rel; - TupleDesc tupdesc = RelationGetDescr(rel); + Oid root_relid; + TupleDesc tupdesc; char *val_desc; Bitmapset *modifiedCols; - Bitmapset *insertedCols; - Bitmapset *updatedCols; /* - * Need to first convert the tuple to the root partitioned table's row - * type. For details, check similar comments in ExecConstraints(). + * If the tuple has been routed, it's been converted to the partition's + * rowtype, which might differ from the root table's. We must convert it + * back to the root table's rowtype so that val_desc in the error message + * matches the input tuple. */ if (resultRelInfo->ri_PartitionRoot) { - HeapTuple tuple = ExecFetchSlotTuple(slot); - TupleDesc old_tupdesc = RelationGetDescr(rel); - TupleConversionMap *map; + TupleDesc old_tupdesc; + AttrNumber *map; + + root_relid = RelationGetRelid(resultRelInfo->ri_PartitionRoot); + tupdesc = RelationGetDescr(resultRelInfo->ri_PartitionRoot); - rel = resultRelInfo->ri_PartitionRoot; - tupdesc = RelationGetDescr(rel); + old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); /* a reverse map */ - map = convert_tuples_by_name(old_tupdesc, tupdesc, - gettext_noop("could not convert row type")); + map = convert_tuples_by_name_map_if_req(old_tupdesc, tupdesc); + + /* + * Partition-specific slot's tupdesc can't be changed, so allocate a + * new one. + */ if (map != NULL) - { - tuple = do_convert_tuple(tuple, map); - ExecSetSlotDescriptor(slot, tupdesc); - ExecStoreTuple(tuple, slot, InvalidBuffer, false); - } + slot = execute_attr_map_slot(map, slot, + MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); } + else + { + root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc); + tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc); + } + + modifiedCols = bms_union(GetInsertedColumns(resultRelInfo, estate), + GetUpdatedColumns(resultRelInfo, estate)); - insertedCols = GetInsertedColumns(resultRelInfo, estate); - updatedCols = GetUpdatedColumns(resultRelInfo, estate); - modifiedCols = bms_union(insertedCols, updatedCols); - val_desc = ExecBuildSlotValueDescription(RelationGetRelid(rel), + val_desc = ExecBuildSlotValueDescription(root_relid, slot, tupdesc, modifiedCols, @@ -1947,24 +1886,24 @@ ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, ereport(ERROR, (errcode(ERRCODE_CHECK_VIOLATION), errmsg("new row for relation \"%s\" violates partition constraint", - RelationGetRelationName(orig_rel)), + RelationGetRelationName(resultRelInfo->ri_RelationDesc)), val_desc ? errdetail("Failing row contains %s.", val_desc) : 0)); } /* * ExecConstraints - check constraints of the tuple in 'slot' * - * This checks the traditional NOT NULL and check constraints, and if - * requested, checks the partition constraint. + * This checks the traditional NOT NULL and check constraints. + * + * The partition constraint is *NOT* checked. * * Note: 'slot' contains the tuple to check the constraints of, which may * have been converted from the original input tuple after tuple routing. - * 'resultRelInfo' is the original result relation, before tuple routing. + * 'resultRelInfo' is the final result relation, after tuple routing. */ void ExecConstraints(ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, EState *estate, - bool check_partition_constraint) + TupleTableSlot *slot, EState *estate) { Relation rel = resultRelInfo->ri_RelationDesc; TupleDesc tupdesc = RelationGetDescr(rel); @@ -1999,20 +1938,21 @@ ExecConstraints(ResultRelInfo *resultRelInfo, */ if (resultRelInfo->ri_PartitionRoot) { - HeapTuple tuple = ExecFetchSlotTuple(slot); - TupleConversionMap *map; + AttrNumber *map; rel = resultRelInfo->ri_PartitionRoot; tupdesc = RelationGetDescr(rel); /* a reverse map */ - map = convert_tuples_by_name(orig_tupdesc, tupdesc, - gettext_noop("could not convert row type")); + map = convert_tuples_by_name_map_if_req(orig_tupdesc, + tupdesc); + + /* + * Partition-specific slot's tupdesc can't be changed, so + * allocate a new one. + */ if (map != NULL) - { - tuple = do_convert_tuple(tuple, map); - ExecSetSlotDescriptor(slot, tupdesc); - ExecStoreTuple(tuple, slot, InvalidBuffer, false); - } + slot = execute_attr_map_slot(map, slot, + MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); } insertedCols = GetInsertedColumns(resultRelInfo, estate); @@ -2046,21 +1986,22 @@ ExecConstraints(ResultRelInfo *resultRelInfo, /* See the comment above. */ if (resultRelInfo->ri_PartitionRoot) { - HeapTuple tuple = ExecFetchSlotTuple(slot); TupleDesc old_tupdesc = RelationGetDescr(rel); - TupleConversionMap *map; + AttrNumber *map; rel = resultRelInfo->ri_PartitionRoot; tupdesc = RelationGetDescr(rel); /* a reverse map */ - map = convert_tuples_by_name(old_tupdesc, tupdesc, - gettext_noop("could not convert row type")); + map = convert_tuples_by_name_map_if_req(old_tupdesc, + tupdesc); + + /* + * Partition-specific slot's tupdesc can't be changed, so + * allocate a new one. + */ if (map != NULL) - { - tuple = do_convert_tuple(tuple, map); - ExecSetSlotDescriptor(slot, tupdesc); - ExecStoreTuple(tuple, slot, InvalidBuffer, false); - } + slot = execute_attr_map_slot(map, slot, + MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); } insertedCols = GetInsertedColumns(resultRelInfo, estate); @@ -2079,13 +2020,8 @@ ExecConstraints(ResultRelInfo *resultRelInfo, errtableconstraint(orig_rel, failed))); } } - - if (check_partition_constraint && resultRelInfo->ri_PartitionCheck && - !ExecPartitionCheck(resultRelInfo, slot, estate)) - ExecPartitionCheckEmitError(resultRelInfo, slot, estate); } - /* * ExecWithCheckOptions -- check that tuple satisfies any WITH CHECK OPTIONs * of the specified kind. @@ -2157,21 +2093,22 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, /* See the comment in ExecConstraints(). */ if (resultRelInfo->ri_PartitionRoot) { - HeapTuple tuple = ExecFetchSlotTuple(slot); TupleDesc old_tupdesc = RelationGetDescr(rel); - TupleConversionMap *map; + AttrNumber *map; rel = resultRelInfo->ri_PartitionRoot; tupdesc = RelationGetDescr(rel); /* a reverse map */ - map = convert_tuples_by_name(old_tupdesc, tupdesc, - gettext_noop("could not convert row type")); + map = convert_tuples_by_name_map_if_req(old_tupdesc, + tupdesc); + + /* + * Partition-specific slot's tupdesc can't be changed, + * so allocate a new one. + */ if (map != NULL) - { - tuple = do_convert_tuple(tuple, map); - ExecSetSlotDescriptor(slot, tupdesc); - ExecStoreTuple(tuple, slot, InvalidBuffer, false); - } + slot = execute_attr_map_slot(map, slot, + MakeTupleTableSlot(tupdesc, &TTSOpsVirtual)); } insertedCols = GetInsertedColumns(resultRelInfo, estate); @@ -2203,19 +2140,6 @@ ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, errmsg("new row violates row-level security policy for table \"%s\"", wco->relname))); break; - case WCO_RLS_MERGE_UPDATE_CHECK: - case WCO_RLS_MERGE_DELETE_CHECK: - if (wco->polname != NULL) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"", - wco->polname, wco->relname))); - else - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("target row violates row-level security policy (USING expression) for table \"%s\"", - wco->relname))); - break; case WCO_RLS_CONFLICT_CHECK: if (wco->polname != NULL) ereport(ERROR, @@ -2360,7 +2284,7 @@ ExecBuildSlotValueDescription(Oid reloid, /* truncate if needed */ vallen = strlen(val); if (vallen <= maxfieldlen) - appendStringInfoString(&buf, val); + appendBinaryStringInfo(&buf, val, vallen); else { vallen = pg_mbcliplen(val, vallen, maxfieldlen); @@ -2379,7 +2303,7 @@ ExecBuildSlotValueDescription(Oid reloid, if (!table_perm) { appendStringInfoString(&collist, ") = "); - appendStringInfoString(&collist, buf.data); + appendBinaryStringInfo(&collist, buf.data, buf.len); return collist.data; } @@ -2403,7 +2327,7 @@ ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo) * been modified, then we can use a weaker lock, allowing for better * concurrency. */ - updatedCols = GetUpdatedColumns(relinfo, estate); + updatedCols = GetAllUpdatedColumns(relinfo, estate); keyCols = RelationGetIndexAttrBitmap(relinfo->ri_RelationDesc, INDEX_ATTR_BITMAP_KEY); @@ -2421,13 +2345,12 @@ ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo) ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok) { - ListCell *lc; - - foreach(lc, estate->es_rowMarks) + if (rti > 0 && rti <= estate->es_range_table_size && + estate->es_rowmarks != NULL) { - ExecRowMark *erm = (ExecRowMark *) lfirst(lc); + ExecRowMark *erm = estate->es_rowmarks[rti - 1]; - if (erm->rti == rti) + if (erm) return erm; } if (!missing_ok) @@ -2493,66 +2416,46 @@ ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist) /* - * Check a modified tuple to see if we want to process its updated version - * under READ COMMITTED rules. + * Check the updated version of a tuple to see if we want to process it under + * READ COMMITTED rules. * - * estate - outer executor state data * epqstate - state for EvalPlanQual rechecking * relation - table containing tuple * rti - rangetable index of table containing tuple - * lockmode - requested tuple lock mode - * *tid - t_ctid from the outdated tuple (ie, next updated version) - * priorXmax - t_xmax from the outdated tuple + * inputslot - tuple for processing - this can be the slot from + * EvalPlanQualSlot(), for the increased efficiency. * - * *tid is also an output parameter: it's modified to hold the TID of the - * latest version of the tuple (note this may be changed even on failure) + * This tests whether the tuple in inputslot still matches the relevant + * quals. For that result to be useful, typically the input tuple has to be + * last row version (otherwise the result isn't particularly useful) and + * locked (otherwise the result might be out of date). That's typically + * achieved by using table_tuple_lock() with the + * TUPLE_LOCK_FLAG_FIND_LAST_VERSION flag. * * Returns a slot containing the new candidate update/delete tuple, or * NULL if we determine we shouldn't process the row. - * - * Note: properly, lockmode should be declared as enum LockTupleMode, - * but we use "int" to avoid having to include heapam.h in executor.h. */ TupleTableSlot * -EvalPlanQual(EState *estate, EPQState *epqstate, - Relation relation, Index rti, int lockmode, - ItemPointer tid, TransactionId priorXmax) +EvalPlanQual(EPQState *epqstate, Relation relation, + Index rti, TupleTableSlot *inputslot) { TupleTableSlot *slot; - HeapTuple copyTuple; + TupleTableSlot *testslot; Assert(rti > 0); - /* - * Get and lock the updated version of the row; if fail, return NULL. - */ - copyTuple = EvalPlanQualFetch(estate, relation, lockmode, LockWaitBlock, - tid, priorXmax); - - if (copyTuple == NULL) - return NULL; - - /* - * For UPDATE/DELETE we have to return tid of actual row we're executing - * PQ for. - */ - *tid = copyTuple->t_self; - /* * Need to run a recheck subquery. Initialize or reinitialize EPQ state. */ - EvalPlanQualBegin(epqstate, estate); - - /* - * Free old test tuple, if any, and store new tuple where relation's scan - * node will see it - */ - EvalPlanQualSetTuple(epqstate, rti, copyTuple); + EvalPlanQualBegin(epqstate); /* - * Fetch any non-locked source rows + * Callers will often use the EvalPlanQualSlot to store the tuple to avoid + * an unnecessary copy. */ - EvalPlanQualFetchRowMarks(epqstate); + testslot = EvalPlanQualSlot(epqstate, relation, rti); + if (testslot != inputslot) + ExecCopySlot(testslot, inputslot); /* * Run the EPQ query. We assume it will return at most one tuple. @@ -2567,273 +2470,18 @@ EvalPlanQual(EState *estate, EPQState *epqstate, * is to guard against early re-use of the EPQ query. */ if (!TupIsNull(slot)) - (void) ExecMaterializeSlot(slot); + ExecMaterializeSlot(slot); /* * Clear out the test tuple. This is needed in case the EPQ query is * re-used to test a tuple for a different relation. (Not clear that can * really happen, but let's be safe.) */ - EvalPlanQualSetTuple(epqstate, rti, NULL); + ExecClearTuple(testslot); return slot; } -/* - * Fetch a copy of the newest version of an outdated tuple - * - * estate - executor state data - * relation - table containing tuple - * lockmode - requested tuple lock mode - * wait_policy - requested lock wait policy - * *tid - t_ctid from the outdated tuple (ie, next updated version) - * priorXmax - t_xmax from the outdated tuple - * - * Returns a palloc'd copy of the newest tuple version, or NULL if we find - * that there is no newest version (ie, the row was deleted not updated). - * We also return NULL if the tuple is locked and the wait policy is to skip - * such tuples. - * - * If successful, we have locked the newest tuple version, so caller does not - * need to worry about it changing anymore. - * - * Note: properly, lockmode should be declared as enum LockTupleMode, - * but we use "int" to avoid having to include heapam.h in executor.h. - */ -HeapTuple -EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, - LockWaitPolicy wait_policy, - ItemPointer tid, TransactionId priorXmax) -{ - HeapTuple copyTuple = NULL; - HeapTupleData tuple; - SnapshotData SnapshotDirty; - - /* - * fetch target tuple - * - * Loop here to deal with updated or busy tuples - */ - InitDirtySnapshot(SnapshotDirty); - tuple.t_self = *tid; - for (;;) - { - Buffer buffer; - - if (heap_fetch(relation, &SnapshotDirty, &tuple, &buffer, true, NULL)) - { - HTSU_Result test; - HeapUpdateFailureData hufd; - - /* - * If xmin isn't what we're expecting, the slot must have been - * recycled and reused for an unrelated tuple. This implies that - * the latest version of the row was deleted, so we need do - * nothing. (Should be safe to examine xmin without getting - * buffer's content lock. We assume reading a TransactionId to be - * atomic, and Xmin never changes in an existing tuple, except to - * invalid or frozen, and neither of those can match priorXmax.) - */ - if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data), - priorXmax)) - { - ReleaseBuffer(buffer); - return NULL; - } - - /* otherwise xmin should not be dirty... */ - if (TransactionIdIsValid(SnapshotDirty.xmin)) - elog(ERROR, "t_xmin is uncommitted in tuple to be updated"); - - /* - * If tuple is being updated by other transaction then we have to - * wait for its commit/abort, or die trying. - */ - if (TransactionIdIsValid(SnapshotDirty.xmax)) - { - ReleaseBuffer(buffer); - switch (wait_policy) - { - case LockWaitBlock: - XactLockTableWait(SnapshotDirty.xmax, - relation, &tuple.t_self, - XLTW_FetchUpdated); - break; - case LockWaitSkip: - if (!ConditionalXactLockTableWait(SnapshotDirty.xmax)) - return NULL; /* skip instead of waiting */ - break; - case LockWaitError: - if (!ConditionalXactLockTableWait(SnapshotDirty.xmax)) - ereport(ERROR, - (errcode(ERRCODE_LOCK_NOT_AVAILABLE), - errmsg("could not obtain lock on row in relation \"%s\"", - RelationGetRelationName(relation)))); - break; - } - continue; /* loop back to repeat heap_fetch */ - } - - /* - * If tuple was inserted by our own transaction, we have to check - * cmin against es_output_cid: cmin >= current CID means our - * command cannot see the tuple, so we should ignore it. Otherwise - * heap_lock_tuple() will throw an error, and so would any later - * attempt to update or delete the tuple. (We need not check cmax - * because HeapTupleSatisfiesDirty will consider a tuple deleted - * by our transaction dead, regardless of cmax.) We just checked - * that priorXmax == xmin, so we can test that variable instead of - * doing HeapTupleHeaderGetXmin again. - */ - if (TransactionIdIsCurrentTransactionId(priorXmax) && - HeapTupleHeaderGetCmin(tuple.t_data) >= estate->es_output_cid) - { - ReleaseBuffer(buffer); - return NULL; - } - - /* - * This is a live tuple, so now try to lock it. - */ - test = heap_lock_tuple(relation, &tuple, - estate->es_output_cid, - lockmode, wait_policy, - false, &buffer, &hufd); - /* We now have two pins on the buffer, get rid of one */ - ReleaseBuffer(buffer); - - switch (test) - { - case HeapTupleSelfUpdated: - - /* - * The target tuple was already updated or deleted by the - * current command, or by a later command in the current - * transaction. We *must* ignore the tuple in the former - * case, so as to avoid the "Halloween problem" of - * repeated update attempts. In the latter case it might - * be sensible to fetch the updated tuple instead, but - * doing so would require changing heap_update and - * heap_delete to not complain about updating "invisible" - * tuples, which seems pretty scary (heap_lock_tuple will - * not complain, but few callers expect - * HeapTupleInvisible, and we're not one of them). So for - * now, treat the tuple as deleted and do not process. - */ - ReleaseBuffer(buffer); - return NULL; - - case HeapTupleMayBeUpdated: - /* successfully locked */ - break; - - case HeapTupleUpdated: - ReleaseBuffer(buffer); - if (IsolationUsesXactSnapshot()) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("could not serialize access due to concurrent update"))); - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be locked was already moved to another partition due to concurrent update"))); - - /* Should not encounter speculative tuple on recheck */ - Assert(!HeapTupleHeaderIsSpeculative(tuple.t_data)); - if (!ItemPointerEquals(&hufd.ctid, &tuple.t_self)) - { - /* it was updated, so look at the updated version */ - tuple.t_self = hufd.ctid; - /* updated row should have xmin matching this xmax */ - priorXmax = hufd.xmax; - continue; - } - /* tuple was deleted, so give up */ - return NULL; - - case HeapTupleWouldBlock: - ReleaseBuffer(buffer); - return NULL; - - case HeapTupleInvisible: - elog(ERROR, "attempted to lock invisible tuple"); - - default: - ReleaseBuffer(buffer); - elog(ERROR, "unrecognized heap_lock_tuple status: %u", - test); - return NULL; /* keep compiler quiet */ - } - - /* - * We got tuple - now copy it for use by recheck query. - */ - copyTuple = heap_copytuple(&tuple); - ReleaseBuffer(buffer); - break; - } - - /* - * If the referenced slot was actually empty, the latest version of - * the row must have been deleted, so we need do nothing. - */ - if (tuple.t_data == NULL) - { - ReleaseBuffer(buffer); - return NULL; - } - - /* - * As above, if xmin isn't what we're expecting, do nothing. - */ - if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data), - priorXmax)) - { - ReleaseBuffer(buffer); - return NULL; - } - - /* - * If we get here, the tuple was found but failed SnapshotDirty. - * Assuming the xmin is either a committed xact or our own xact (as it - * certainly should be if we're trying to modify the tuple), this must - * mean that the row was updated or deleted by either a committed xact - * or our own xact. If it was deleted, we can ignore it; if it was - * updated then chain up to the next version and repeat the whole - * process. - * - * As above, it should be safe to examine xmax and t_ctid without the - * buffer content lock, because they can't be changing. - */ - - /* check whether next version would be in a different partition */ - if (HeapTupleHeaderIndicatesMovedPartitions(tuple.t_data)) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be locked was already moved to another partition due to concurrent update"))); - - /* check whether tuple has been deleted */ - if (ItemPointerEquals(&tuple.t_self, &tuple.t_data->t_ctid)) - { - /* deleted, so forget about it */ - ReleaseBuffer(buffer); - return NULL; - } - - /* updated, so look at the updated row */ - tuple.t_self = tuple.t_data->t_ctid; - /* updated row should have xmin matching this xmax */ - priorXmax = HeapTupleHeaderGetUpdateXid(tuple.t_data); - ReleaseBuffer(buffer); - /* loop back to fetch next in chain */ - } - - /* - * Return the copied tuple - */ - return copyTuple; -} - /* * EvalPlanQualInit -- initialize during creation of a plan state node * that might need to invoke EPQ processing. @@ -2842,17 +2490,36 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode, * with EvalPlanQualSetPlan. */ void -EvalPlanQualInit(EPQState *epqstate, EState *estate, +EvalPlanQualInit(EPQState *epqstate, EState *parentestate, Plan *subplan, List *auxrowmarks, int epqParam) { - /* Mark the EPQ state inactive */ - epqstate->estate = NULL; - epqstate->planstate = NULL; - epqstate->origslot = NULL; + Index rtsize = parentestate->es_range_table_size; + + /* initialize data not changing over EPQState's lifetime */ + epqstate->parentestate = parentestate; + epqstate->epqParam = epqParam; + + /* + * Allocate space to reference a slot for each potential rti - do so now + * rather than in EvalPlanQualBegin(), as done for other dynamically + * allocated resources, so EvalPlanQualSlot() can be used to hold tuples + * that *may* need EPQ later, without forcing the overhead of + * EvalPlanQualBegin(). + */ + epqstate->tuple_table = NIL; + epqstate->relsubs_slot = (TupleTableSlot **) + palloc0(rtsize * sizeof(TupleTableSlot *)); + /* ... and remember data that EvalPlanQualBegin will need */ epqstate->plan = subplan; epqstate->arowMarks = auxrowmarks; - epqstate->epqParam = epqParam; + + /* ... and mark the EPQ state inactive */ + epqstate->origslot = NULL; + epqstate->recheckestate = NULL; + epqstate->recheckplanstate = NULL; + epqstate->relsubs_rowmark = NULL; + epqstate->relsubs_done = NULL; } /* @@ -2872,182 +2539,141 @@ EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks) } /* - * Install one test tuple into EPQ state, or clear test tuple if tuple == NULL + * Return, and create if necessary, a slot for an EPQ test tuple. * - * NB: passed tuple must be palloc'd; it may get freed later + * Note this only requires EvalPlanQualInit() to have been called, + * EvalPlanQualBegin() is not necessary. */ -void -EvalPlanQualSetTuple(EPQState *epqstate, Index rti, HeapTuple tuple) +TupleTableSlot * +EvalPlanQualSlot(EPQState *epqstate, + Relation relation, Index rti) { - EState *estate = epqstate->estate; - - Assert(rti > 0); + TupleTableSlot **slot; - /* - * free old test tuple, if any, and store new tuple where relation's scan - * node will see it - */ - if (estate->es_epqTuple[rti - 1] != NULL) - heap_freetuple(estate->es_epqTuple[rti - 1]); - estate->es_epqTuple[rti - 1] = tuple; - estate->es_epqTupleSet[rti - 1] = true; -} + Assert(relation); + Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size); + slot = &epqstate->relsubs_slot[rti - 1]; -/* - * Fetch back the current test tuple (if any) for the specified RTI - */ -HeapTuple -EvalPlanQualGetTuple(EPQState *epqstate, Index rti) -{ - EState *estate = epqstate->estate; + if (*slot == NULL) + { + MemoryContext oldcontext; - Assert(rti > 0); + oldcontext = MemoryContextSwitchTo(epqstate->parentestate->es_query_cxt); + *slot = table_slot_create(relation, &epqstate->tuple_table); + MemoryContextSwitchTo(oldcontext); + } - return estate->es_epqTuple[rti - 1]; + return *slot; } /* - * Fetch the current row values for any non-locked relations that need - * to be scanned by an EvalPlanQual operation. origslot must have been set - * to contain the current result row (top-level row) that we need to recheck. + * Fetch the current row value for a non-locked relation, identified by rti, + * that needs to be scanned by an EvalPlanQual operation. origslot must have + * been set to contain the current result row (top-level row) that we need to + * recheck. Returns true if a substitution tuple was found, false if not. */ -void -EvalPlanQualFetchRowMarks(EPQState *epqstate) +bool +EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot) { - ListCell *l; + ExecAuxRowMark *earm = epqstate->relsubs_rowmark[rti - 1]; + ExecRowMark *erm = earm->rowmark; + Datum datum; + bool isNull; + Assert(earm != NULL); Assert(epqstate->origslot != NULL); - foreach(l, epqstate->arowMarks) + if (RowMarkRequiresRowShareLock(erm->markType)) + elog(ERROR, "EvalPlanQual doesn't support locking rowmarks"); + + /* if child rel, must check whether it produced this row */ + if (erm->rti != erm->prti) { - ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(l); - ExecRowMark *erm = aerm->rowmark; - Datum datum; - bool isNull; - HeapTupleData tuple; + Oid tableoid; - if (RowMarkRequiresRowShareLock(erm->markType)) - elog(ERROR, "EvalPlanQual doesn't support locking rowmarks"); + datum = ExecGetJunkAttribute(epqstate->origslot, + earm->toidAttNo, + &isNull); + /* non-locked rels could be on the inside of outer joins */ + if (isNull) + return false; - /* clear any leftover test tuple for this rel */ - EvalPlanQualSetTuple(epqstate, erm->rti, NULL); + tableoid = DatumGetObjectId(datum); - /* if child rel, must check whether it produced this row */ - if (erm->rti != erm->prti) + Assert(OidIsValid(erm->relid)); + if (tableoid != erm->relid) { - Oid tableoid; - - datum = ExecGetJunkAttribute(epqstate->origslot, - aerm->toidAttNo, - &isNull); - /* non-locked rels could be on the inside of outer joins */ - if (isNull) - continue; - tableoid = DatumGetObjectId(datum); - - Assert(OidIsValid(erm->relid)); - if (tableoid != erm->relid) - { - /* this child is inactive right now */ - continue; - } + /* this child is inactive right now */ + return false; } + } - if (erm->markType == ROW_MARK_REFERENCE) - { - HeapTuple copyTuple; - - Assert(erm->relation != NULL); - - /* fetch the tuple's ctid */ - datum = ExecGetJunkAttribute(epqstate->origslot, - aerm->ctidAttNo, - &isNull); - /* non-locked rels could be on the inside of outer joins */ - if (isNull) - continue; - - /* fetch requests on foreign tables must be passed to their FDW */ - if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) - { - FdwRoutine *fdwroutine; - bool updated = false; - - fdwroutine = GetFdwRoutineForRelation(erm->relation, false); - /* this should have been checked already, but let's be safe */ - if (fdwroutine->RefetchForeignRow == NULL) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot lock rows in foreign table \"%s\"", - RelationGetRelationName(erm->relation)))); - copyTuple = fdwroutine->RefetchForeignRow(epqstate->estate, - erm, - datum, - &updated); - if (copyTuple == NULL) - elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); + if (erm->markType == ROW_MARK_REFERENCE) + { + Assert(erm->relation != NULL); + + /* fetch the tuple's ctid */ + datum = ExecGetJunkAttribute(epqstate->origslot, + earm->ctidAttNo, + &isNull); + /* non-locked rels could be on the inside of outer joins */ + if (isNull) + return false; - /* - * Ideally we'd insist on updated == false here, but that - * assumes that FDWs can track that exactly, which they might - * not be able to. So just ignore the flag. - */ - } - else - { - /* ordinary table, fetch the tuple */ - Buffer buffer; + /* fetch requests on foreign tables must be passed to their FDW */ + if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + { + FdwRoutine *fdwroutine; + bool updated = false; - tuple.t_self = *((ItemPointer) DatumGetPointer(datum)); - if (!heap_fetch(erm->relation, SnapshotAny, &tuple, &buffer, - false, NULL)) - elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); + fdwroutine = GetFdwRoutineForRelation(erm->relation, false); + /* this should have been checked already, but let's be safe */ + if (fdwroutine->RefetchForeignRow == NULL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot lock rows in foreign table \"%s\"", + RelationGetRelationName(erm->relation)))); - if (HeapTupleHeaderGetNatts(tuple.t_data) < - RelationGetDescr(erm->relation)->natts) - { - copyTuple = heap_expand_tuple(&tuple, - RelationGetDescr(erm->relation)); - } - else - { - /* successful, copy tuple */ - copyTuple = heap_copytuple(&tuple); - } - ReleaseBuffer(buffer); - } + fdwroutine->RefetchForeignRow(epqstate->recheckestate, + erm, + datum, + slot, + &updated); + if (TupIsNull(slot)) + elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); - /* store tuple */ - EvalPlanQualSetTuple(epqstate, erm->rti, copyTuple); + /* + * Ideally we'd insist on updated == false here, but that assumes + * that FDWs can track that exactly, which they might not be able + * to. So just ignore the flag. + */ + return true; } else { - HeapTupleHeader td; - - Assert(erm->markType == ROW_MARK_COPY); - - /* fetch the whole-row Var for the relation */ - datum = ExecGetJunkAttribute(epqstate->origslot, - aerm->wholeAttNo, - &isNull); - /* non-locked rels could be on the inside of outer joins */ - if (isNull) - continue; - td = DatumGetHeapTupleHeader(datum); - - /* build a temporary HeapTuple control structure */ - tuple.t_len = HeapTupleHeaderGetDatumLength(td); - tuple.t_data = td; - /* relation might be a foreign table, if so provide tableoid */ - tuple.t_tableOid = erm->relid; - /* also copy t_ctid in case there's valid data there */ - tuple.t_self = td->t_ctid; - - /* copy and store tuple */ - EvalPlanQualSetTuple(epqstate, erm->rti, - heap_copytuple(&tuple)); + /* ordinary table, fetch the tuple */ + if (!table_tuple_fetch_row_version(erm->relation, + (ItemPointer) DatumGetPointer(datum), + SnapshotAny, slot)) + elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); + return true; } } + else + { + Assert(erm->markType == ROW_MARK_COPY); + + /* fetch the whole-row Var for the relation */ + datum = ExecGetJunkAttribute(epqstate->origslot, + earm->wholeAttNo, + &isNull); + /* non-locked rels could be on the inside of outer joins */ + if (isNull) + return false; + + ExecStoreHeapTupleDatum(datum, slot); + return true; + } } /* @@ -3061,8 +2687,8 @@ EvalPlanQualNext(EPQState *epqstate) MemoryContext oldcontext; TupleTableSlot *slot; - oldcontext = MemoryContextSwitchTo(epqstate->estate->es_query_cxt); - slot = ExecProcNode(epqstate->planstate); + oldcontext = MemoryContextSwitchTo(epqstate->recheckestate->es_query_cxt); + slot = ExecProcNode(epqstate->recheckplanstate); MemoryContextSwitchTo(oldcontext); return slot; @@ -3072,38 +2698,47 @@ EvalPlanQualNext(EPQState *epqstate) * Initialize or reset an EvalPlanQual state tree */ void -EvalPlanQualBegin(EPQState *epqstate, EState *parentestate) +EvalPlanQualBegin(EPQState *epqstate) { - EState *estate = epqstate->estate; + EState *parentestate = epqstate->parentestate; + EState *recheckestate = epqstate->recheckestate; - if (estate == NULL) + if (recheckestate == NULL) { /* First time through, so create a child EState */ - EvalPlanQualStart(epqstate, parentestate, epqstate->plan); + EvalPlanQualStart(epqstate, epqstate->plan); } else { /* * We already have a suitable child EPQ tree, so just reset it. */ - int rtsize = list_length(parentestate->es_range_table); - PlanState *planstate = epqstate->planstate; + Index rtsize = parentestate->es_range_table_size; + PlanState *rcplanstate = epqstate->recheckplanstate; - MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool)); + MemSet(epqstate->relsubs_done, 0, rtsize * sizeof(bool)); /* Recopy current values of parent parameters */ if (parentestate->es_plannedstmt->paramExecTypes != NIL) { int i; + /* + * Force evaluation of any InitPlan outputs that could be needed + * by the subplan, just in case they got reset since + * EvalPlanQualStart (see comments therein). + */ + ExecSetParamPlanMulti(rcplanstate->plan->extParam, + GetPerTupleExprContext(parentestate)); + i = list_length(parentestate->es_plannedstmt->paramExecTypes); while (--i >= 0) { /* copy value if any, but not execPlan link */ - estate->es_param_exec_vals[i].value = + recheckestate->es_param_exec_vals[i].value = parentestate->es_param_exec_vals[i].value; - estate->es_param_exec_vals[i].isnull = + recheckestate->es_param_exec_vals[i].isnull = parentestate->es_param_exec_vals[i].isnull; } } @@ -3112,8 +2747,8 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate) * Mark child plan tree as needing rescan at all scan nodes. The * first ExecProcNode will take care of actually doing the rescan. */ - planstate->chgParam = bms_add_member(planstate->chgParam, - epqstate->epqParam); + rcplanstate->chgParam = bms_add_member(rcplanstate->chgParam, + epqstate->epqParam); } } @@ -3124,18 +2759,20 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate) * the top-level estate rather than initializing it fresh. */ static void -EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) +EvalPlanQualStart(EPQState *epqstate, Plan *planTree) { - EState *estate; - int rtsize; + EState *parentestate = epqstate->parentestate; + Index rtsize = parentestate->es_range_table_size; + EState *rcestate; MemoryContext oldcontext; ListCell *l; - rtsize = list_length(parentestate->es_range_table); + epqstate->recheckestate = rcestate = CreateExecutorState(); - epqstate->estate = estate = CreateExecutorState(); + oldcontext = MemoryContextSwitchTo(rcestate->es_query_cxt); - oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + /* signal that this is an EState for executing EPQ */ + rcestate->es_epq_active = epqstate; /* * Child EPQ EStates share the parent's copy of unchanging state such as @@ -3144,37 +2781,52 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) * es_param_exec_vals, etc. * * The ResultRelInfo array management is trickier than it looks. We - * create a fresh array for the child but copy all the content from the + * create fresh arrays for the child but copy all the content from the * parent. This is because it's okay for the child to share any * per-relation state the parent has already created --- but if the child * sets up any ResultRelInfo fields, such as its own junkfilter, that * state must *not* propagate back to the parent. (For one thing, the * pointed-to data is in a memory context that won't last long enough.) */ - estate->es_direction = ForwardScanDirection; - estate->es_snapshot = parentestate->es_snapshot; - estate->es_crosscheck_snapshot = parentestate->es_crosscheck_snapshot; - estate->es_range_table = parentestate->es_range_table; - estate->es_plannedstmt = parentestate->es_plannedstmt; - estate->es_junkFilter = parentestate->es_junkFilter; - estate->es_output_cid = parentestate->es_output_cid; + rcestate->es_direction = ForwardScanDirection; + rcestate->es_snapshot = parentestate->es_snapshot; + rcestate->es_crosscheck_snapshot = parentestate->es_crosscheck_snapshot; + rcestate->es_range_table = parentestate->es_range_table; + rcestate->es_range_table_size = parentestate->es_range_table_size; + rcestate->es_relations = parentestate->es_relations; + rcestate->es_queryEnv = parentestate->es_queryEnv; + rcestate->es_rowmarks = parentestate->es_rowmarks; + rcestate->es_plannedstmt = parentestate->es_plannedstmt; + rcestate->es_junkFilter = parentestate->es_junkFilter; + rcestate->es_output_cid = parentestate->es_output_cid; if (parentestate->es_num_result_relations > 0) { int numResultRelations = parentestate->es_num_result_relations; + int numRootResultRels = parentestate->es_num_root_result_relations; ResultRelInfo *resultRelInfos; resultRelInfos = (ResultRelInfo *) palloc(numResultRelations * sizeof(ResultRelInfo)); memcpy(resultRelInfos, parentestate->es_result_relations, numResultRelations * sizeof(ResultRelInfo)); - estate->es_result_relations = resultRelInfos; - estate->es_num_result_relations = numResultRelations; + rcestate->es_result_relations = resultRelInfos; + rcestate->es_num_result_relations = numResultRelations; + + /* Also transfer partitioned root result relations. */ + if (numRootResultRels > 0) + { + resultRelInfos = (ResultRelInfo *) + palloc(numRootResultRels * sizeof(ResultRelInfo)); + memcpy(resultRelInfos, parentestate->es_root_result_relations, + numRootResultRels * sizeof(ResultRelInfo)); + rcestate->es_root_result_relations = resultRelInfos; + rcestate->es_num_root_result_relations = numRootResultRels; + } } /* es_result_relation_info must NOT be copied */ /* es_trig_target_relations must NOT be copied */ - estate->es_rowMarks = parentestate->es_rowMarks; - estate->es_top_eflags = parentestate->es_top_eflags; - estate->es_instrument = parentestate->es_instrument; + rcestate->es_top_eflags = parentestate->es_top_eflags; + rcestate->es_instrument = parentestate->es_instrument; /* es_auxmodifytables must NOT be copied */ /* @@ -3183,48 +2835,47 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) * from the parent, so as to have access to any param values that were * already set from other parts of the parent's plan tree. */ - estate->es_param_list_info = parentestate->es_param_list_info; + rcestate->es_param_list_info = parentestate->es_param_list_info; if (parentestate->es_plannedstmt->paramExecTypes != NIL) { int i; + /* + * Force evaluation of any InitPlan outputs that could be needed by + * the subplan. (With more complexity, maybe we could postpone this + * till the subplan actually demands them, but it doesn't seem worth + * the trouble; this is a corner case already, since usually the + * InitPlans would have been evaluated before reaching EvalPlanQual.) + * + * This will not touch output params of InitPlans that occur somewhere + * within the subplan tree, only those that are attached to the + * ModifyTable node or above it and are referenced within the subplan. + * That's OK though, because the planner would only attach such + * InitPlans to a lower-level SubqueryScan node, and EPQ execution + * will not descend into a SubqueryScan. + * + * The EState's per-output-tuple econtext is sufficiently short-lived + * for this, since it should get reset before there is any chance of + * doing EvalPlanQual again. + */ + ExecSetParamPlanMulti(planTree->extParam, + GetPerTupleExprContext(parentestate)); + + /* now make the internal param workspace ... */ i = list_length(parentestate->es_plannedstmt->paramExecTypes); - estate->es_param_exec_vals = (ParamExecData *) + rcestate->es_param_exec_vals = (ParamExecData *) palloc0(i * sizeof(ParamExecData)); + /* ... and copy down all values, whether really needed or not */ while (--i >= 0) { /* copy value if any, but not execPlan link */ - estate->es_param_exec_vals[i].value = + rcestate->es_param_exec_vals[i].value = parentestate->es_param_exec_vals[i].value; - estate->es_param_exec_vals[i].isnull = + rcestate->es_param_exec_vals[i].isnull = parentestate->es_param_exec_vals[i].isnull; } } - /* - * Each EState must have its own es_epqScanDone state, but if we have - * nested EPQ checks they should share es_epqTuple arrays. This allows - * sub-rechecks to inherit the values being examined by an outer recheck. - */ - estate->es_epqScanDone = (bool *) palloc0(rtsize * sizeof(bool)); - if (parentestate->es_epqTuple != NULL) - { - estate->es_epqTuple = parentestate->es_epqTuple; - estate->es_epqTupleSet = parentestate->es_epqTupleSet; - } - else - { - estate->es_epqTuple = (HeapTuple *) - palloc0(rtsize * sizeof(HeapTuple)); - estate->es_epqTupleSet = (bool *) - palloc0(rtsize * sizeof(bool)); - } - - /* - * Each estate also has its own tuple table. - */ - estate->es_tupleTable = NIL; - /* * Initialize private state information for each SubPlan. We must do this * before running ExecInitNode on the main query tree, since @@ -3233,15 +2884,49 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) * run, but since it's not easy to tell which, we just initialize them * all. */ - Assert(estate->es_subplanstates == NIL); + Assert(rcestate->es_subplanstates == NIL); foreach(l, parentestate->es_plannedstmt->subplans) { Plan *subplan = (Plan *) lfirst(l); PlanState *subplanstate; - subplanstate = ExecInitNode(subplan, estate, 0); - estate->es_subplanstates = lappend(estate->es_subplanstates, - subplanstate); + subplanstate = ExecInitNode(subplan, rcestate, 0); + rcestate->es_subplanstates = lappend(rcestate->es_subplanstates, + subplanstate); + } + + /* + * These arrays are reused across different plans set with + * EvalPlanQualSetPlan(), which is safe because they all use the same + * parent EState. Therefore we can reuse if already allocated. + */ + if (epqstate->relsubs_rowmark == NULL) + { + Assert(epqstate->relsubs_done == NULL); + epqstate->relsubs_rowmark = (ExecAuxRowMark **) + palloc0(rtsize * sizeof(ExecAuxRowMark *)); + epqstate->relsubs_done = (bool *) + palloc0(rtsize * sizeof(bool)); + } + else + { + Assert(epqstate->relsubs_done != NULL); + memset(epqstate->relsubs_rowmark, 0, + rtsize * sizeof(ExecAuxRowMark *)); + memset(epqstate->relsubs_done, 0, + rtsize * sizeof(bool)); + } + + /* + * Build an RTI indexed array of rowmarks, so that + * EvalPlanQualFetchRowMark() can efficiently access the to be fetched + * rowmark. + */ + foreach(l, epqstate->arowMarks) + { + ExecAuxRowMark *earm = (ExecAuxRowMark *) lfirst(l); + + epqstate->relsubs_rowmark[earm->rowmark->rti - 1] = earm; } /* @@ -3249,7 +2934,7 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) * of the plan tree we need to run. This opens files, allocates storage * and leaves us ready to start processing tuples. */ - epqstate->planstate = ExecInitNode(planTree, estate, 0); + epqstate->recheckplanstate = ExecInitNode(planTree, rcestate, 0); MemoryContextSwitchTo(oldcontext); } @@ -3267,16 +2952,32 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree) void EvalPlanQualEnd(EPQState *epqstate) { - EState *estate = epqstate->estate; + EState *estate = epqstate->recheckestate; + Index rtsize; MemoryContext oldcontext; ListCell *l; + rtsize = epqstate->parentestate->es_range_table_size; + + /* + * We may have a tuple table, even if EPQ wasn't started, because we allow + * use of EvalPlanQualSlot() without calling EvalPlanQualBegin(). + */ + if (epqstate->tuple_table != NIL) + { + memset(epqstate->relsubs_slot, 0, + rtsize * sizeof(TupleTableSlot *)); + ExecResetTupleTable(epqstate->tuple_table, true); + epqstate->tuple_table = NIL; + } + + /* EPQ wasn't started, nothing further to do */ if (estate == NULL) - return; /* idle, so nothing to do */ + return; oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); - ExecEndNode(epqstate->planstate); + ExecEndNode(epqstate->recheckplanstate); foreach(l, estate->es_subplanstates) { @@ -3285,7 +2986,7 @@ EvalPlanQualEnd(EPQState *epqstate) ExecEndNode(subplanstate); } - /* throw away the per-estate tuple table */ + /* throw away the per-estate tuple table, some node may have used it */ ExecResetTupleTable(estate->es_tupleTable, false); /* close any trigger target relations attached to this EState */ @@ -3296,7 +2997,7 @@ EvalPlanQualEnd(EPQState *epqstate) FreeExecutorState(estate); /* Mark EPQState idle */ - epqstate->estate = NULL; - epqstate->planstate = NULL; + epqstate->recheckestate = NULL; + epqstate->recheckplanstate = NULL; epqstate->origslot = NULL; } diff --git a/src/backend/executor/execMerge.c b/src/backend/executor/execMerge.c deleted file mode 100644 index d75d7e5ab26..00000000000 --- a/src/backend/executor/execMerge.c +++ /dev/null @@ -1,682 +0,0 @@ -/*------------------------------------------------------------------------- - * - * execMerge.c - * routines to handle Merge nodes relating to the MERGE command - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/executor/execMerge.c - * - *------------------------------------------------------------------------- - */ - - -#include "postgres.h" - -#include "access/htup_details.h" -#include "access/xact.h" -#include "commands/trigger.h" -#include "executor/execPartition.h" -#include "executor/executor.h" -#include "executor/nodeModifyTable.h" -#include "executor/execMerge.h" -#include "miscadmin.h" -#include "nodes/nodeFuncs.h" -#include "storage/bufmgr.h" -#include "storage/lmgr.h" -#include "utils/builtins.h" -#include "utils/memutils.h" -#include "utils/rel.h" -#include "utils/tqual.h" - -static void ExecMergeNotMatched(ModifyTableState *mtstate, EState *estate, - TupleTableSlot *slot); -static bool ExecMergeMatched(ModifyTableState *mtstate, EState *estate, - TupleTableSlot *slot, JunkFilter *junkfilter, - ItemPointer tupleid); -/* - * Perform MERGE. - */ -void -ExecMerge(ModifyTableState *mtstate, EState *estate, TupleTableSlot *slot, - JunkFilter *junkfilter, ResultRelInfo *resultRelInfo) -{ - ExprContext *econtext = mtstate->ps.ps_ExprContext; - ItemPointer tupleid; - ItemPointerData tuple_ctid; - bool matched = false; - Datum datum; - bool isNull; - - Assert(resultRelInfo->ri_RelationDesc->rd_rel->relkind == RELKIND_RELATION || - resultRelInfo->ri_RelationDesc->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - - /* - * Reset per-tuple memory context to free any expression evaluation - * storage allocated in the previous cycle. - */ - ResetExprContext(econtext); - - /* - * We run a JOIN between the target relation and the source relation to - * find a set of candidate source rows that has matching row in the target - * table and a set of candidate source rows that does not have matching - * row in the target table. If the join returns us a tuple with target - * relation's tid set, that implies that the join found a matching row for - * the given source tuple. This case triggers the WHEN MATCHED clause of - * the MERGE. Whereas a NULL in the target relation's ctid column - * indicates a NOT MATCHED case. - */ - datum = ExecGetJunkAttribute(slot, junkfilter->jf_junkAttNo, &isNull); - - if (!isNull) - { - matched = true; - tupleid = (ItemPointer) DatumGetPointer(datum); - tuple_ctid = *tupleid; /* be sure we don't free ctid!! */ - tupleid = &tuple_ctid; - } - else - { - matched = false; - tupleid = NULL; /* we don't need it for INSERT actions */ - } - - /* - * If we are dealing with a WHEN MATCHED case, we execute the first action - * for which the additional WHEN MATCHED AND quals pass. If an action - * without quals is found, that action is executed. - * - * Similarly, if we are dealing with WHEN NOT MATCHED case, we look at the - * given WHEN NOT MATCHED actions in sequence until one passes. - * - * Things get interesting in case of concurrent update/delete of the - * target tuple. Such concurrent update/delete is detected while we are - * executing a WHEN MATCHED action. - * - * A concurrent update can: - * - * 1. modify the target tuple so that it no longer satisfies the - * additional quals attached to the current WHEN MATCHED action OR - * - * In this case, we are still dealing with a WHEN MATCHED case, but - * we should recheck the list of WHEN MATCHED actions and choose the first - * one that satisfies the new target tuple. - * - * 2. modify the target tuple so that the join quals no longer pass and - * hence the source tuple no longer has a match. - * - * In the second case, the source tuple no longer matches the target tuple, - * so we now instead find a qualifying WHEN NOT MATCHED action to execute. - * - * A concurrent delete, changes a WHEN MATCHED case to WHEN NOT MATCHED. - * - * ExecMergeMatched takes care of following the update chain and - * re-finding the qualifying WHEN MATCHED action, as long as the updated - * target tuple still satisfies the join quals i.e. it still remains a - * WHEN MATCHED case. If the tuple gets deleted or the join quals fail, it - * returns and we try ExecMergeNotMatched. Given that ExecMergeMatched - * always make progress by following the update chain and we never switch - * from ExecMergeNotMatched to ExecMergeMatched, there is no risk of a - * livelock. - */ - if (matched) - matched = ExecMergeMatched(mtstate, estate, slot, junkfilter, tupleid); - - /* - * Either we were dealing with a NOT MATCHED tuple or ExecMergeNotMatched() - * returned "false", indicating the previously MATCHED tuple is no longer a - * matching tuple. - */ - if (!matched) - ExecMergeNotMatched(mtstate, estate, slot); -} - -/* - * Check and execute the first qualifying MATCHED action. The current target - * tuple is identified by tupleid. - * - * We start from the first WHEN MATCHED action and check if the WHEN AND quals - * pass, if any. If the WHEN AND quals for the first action do not pass, we - * check the second, then the third and so on. If we reach to the end, no - * action is taken and we return true, indicating that no further action is - * required for this tuple. - * - * If we do find a qualifying action, then we attempt to execute the action. - * - * If the tuple is concurrently updated, EvalPlanQual is run with the updated - * tuple to recheck the join quals. Note that the additional quals associated - * with individual actions are evaluated separately by the MERGE code, while - * EvalPlanQual checks for the join quals. If EvalPlanQual tells us that the - * updated tuple still passes the join quals, then we restart from the first - * action to look for a qualifying action. Otherwise, we return false meaning - * that a NOT MATCHED action must now be executed for the current source tuple. - */ -static bool -ExecMergeMatched(ModifyTableState *mtstate, EState *estate, - TupleTableSlot *slot, JunkFilter *junkfilter, - ItemPointer tupleid) -{ - ExprContext *econtext = mtstate->ps.ps_ExprContext; - bool isNull; - List *mergeMatchedActionStates = NIL; - HeapUpdateFailureData hufd; - bool tuple_updated, - tuple_deleted; - Buffer buffer; - HeapTupleData tuple; - EPQState *epqstate = &mtstate->mt_epqstate; - ResultRelInfo *saved_resultRelInfo; - ResultRelInfo *resultRelInfo = estate->es_result_relation_info; - ListCell *l; - TupleTableSlot *saved_slot = slot; - - if (mtstate->mt_partition_tuple_routing) - { - Datum datum; - Oid tableoid = InvalidOid; - int leaf_part_index; - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - - /* - * In case of partitioned table, we fetch the tableoid while performing - * MATCHED MERGE action. - */ - datum = ExecGetJunkAttribute(slot, junkfilter->jf_otherJunkAttNo, - &isNull); - Assert(!isNull); - tableoid = DatumGetObjectId(datum); - - /* - * If we're dealing with a MATCHED tuple, then tableoid must have been - * set correctly. In case of partitioned table, we must now fetch the - * correct result relation corresponding to the child table emitting - * the matching target row. For normal table, there is just one result - * relation and it must be the one emitting the matching row. - */ - leaf_part_index = ExecFindPartitionByOid(proute, tableoid); - - resultRelInfo = proute->partitions[leaf_part_index]; - if (resultRelInfo == NULL) - { - resultRelInfo = ExecInitPartitionInfo(mtstate, - mtstate->resultRelInfo, - proute, estate, leaf_part_index); - Assert(resultRelInfo != NULL); - } - } - - /* - * Save the current information and work with the correct result relation. - */ - saved_resultRelInfo = resultRelInfo; - estate->es_result_relation_info = resultRelInfo; - - /* - * And get the correct action lists. - */ - mergeMatchedActionStates = - resultRelInfo->ri_mergeState->matchedActionStates; - - /* - * If there are not WHEN MATCHED actions, we are done. - */ - if (mergeMatchedActionStates == NIL) - return true; - - /* - * Make tuple and any needed join variables available to ExecQual and - * ExecProject. The target's existing tuple is installed in the scantuple. - * Again, this target relation's slot is required only in the case of a - * MATCHED tuple and UPDATE/DELETE actions. - */ - if (mtstate->mt_partition_tuple_routing) - ExecSetSlotDescriptor(mtstate->mt_existing, - resultRelInfo->ri_RelationDesc->rd_att); - econtext->ecxt_scantuple = mtstate->mt_existing; - econtext->ecxt_innertuple = slot; - econtext->ecxt_outertuple = NULL; - -lmerge_matched:; - slot = saved_slot; - - /* - * UPDATE/DELETE is only invoked for matched rows. And we must have found - * the tupleid of the target row in that case. We fetch using SnapshotAny - * because we might get called again after EvalPlanQual returns us a new - * tuple. This tuple may not be visible to our MVCC snapshot. - */ - Assert(tupleid != NULL); - - tuple.t_self = *tupleid; - if (!heap_fetch(resultRelInfo->ri_RelationDesc, SnapshotAny, &tuple, - &buffer, true, NULL)) - elog(ERROR, "Failed to fetch the target tuple"); - - /* Store target's existing tuple in the state's dedicated slot */ - ExecStoreTuple(&tuple, mtstate->mt_existing, buffer, false); - - foreach(l, mergeMatchedActionStates) - { - MergeActionState *action = (MergeActionState *) lfirst(l); - - /* - * Test condition, if any - * - * In the absence of a condition we perform the action unconditionally - * (no need to check separately since ExecQual() will return true if - * there are no conditions to evaluate). - */ - if (!ExecQual(action->whenqual, econtext)) - continue; - - /* - * Check if the existing target tuple meet the USING checks of - * UPDATE/DELETE RLS policies. If those checks fail, we throw an - * error. - * - * The WITH CHECK quals are applied in ExecUpdate() and hence we need - * not do anything special to handle them. - * - * NOTE: We must do this after WHEN quals are evaluated so that we - * check policies only when they matter. - */ - if (resultRelInfo->ri_WithCheckOptions) - { - ExecWithCheckOptions(action->commandType == CMD_UPDATE ? - WCO_RLS_MERGE_UPDATE_CHECK : WCO_RLS_MERGE_DELETE_CHECK, - resultRelInfo, - mtstate->mt_existing, - mtstate->ps.state); - } - - /* Perform stated action */ - switch (action->commandType) - { - case CMD_UPDATE: - - /* - * We set up the projection earlier, so all we do here is - * Project, no need for any other tasks prior to the - * ExecUpdate. - */ - if (mtstate->mt_partition_tuple_routing) - ExecSetSlotDescriptor(mtstate->mt_mergeproj, action->tupDesc); - ExecProject(action->proj); - - /* - * We don't call ExecFilterJunk() because the projected tuple - * using the UPDATE action's targetlist doesn't have a junk - * attribute. - */ - slot = ExecUpdate(mtstate, tupleid, NULL, - mtstate->mt_mergeproj, - slot, epqstate, estate, - &tuple_updated, &hufd, - action, mtstate->canSetTag); - break; - - case CMD_DELETE: - /* Nothing to Project for a DELETE action */ - slot = ExecDelete(mtstate, tupleid, NULL, - slot, epqstate, estate, - &tuple_deleted, false, &hufd, action, - mtstate->canSetTag, - false /* changingPart */); - - break; - - default: - elog(ERROR, "unknown action in MERGE WHEN MATCHED clause"); - - } - - /* - * Check for any concurrent update/delete operation which may have - * prevented our update/delete. We also check for situations where we - * might be trying to update/delete the same tuple twice. - */ - if ((action->commandType == CMD_UPDATE && !tuple_updated) || - (action->commandType == CMD_DELETE && !tuple_deleted)) - - { - switch (hufd.result) - { - case HeapTupleMayBeUpdated: - break; - case HeapTupleInvisible: - - /* - * This state should never be reached since the underlying - * JOIN runs with a MVCC snapshot and EvalPlanQual runs - * with a dirty snapshot. So such a row should have never - * been returned for MERGE. - */ - elog(ERROR, "unexpected invisible tuple"); - break; - - case HeapTupleSelfUpdated: - - /* - * SQLStandard disallows this for MERGE. - */ - if (TransactionIdIsCurrentTransactionId(hufd.xmax)) - ereport(ERROR, - (errcode(ERRCODE_CARDINALITY_VIOLATION), - errmsg("MERGE command cannot affect row a second time"), - errhint("Ensure that not more than one source row matches any one target row"))); - /* This shouldn't happen */ - elog(ERROR, "attempted to update or delete invisible tuple"); - break; - - case HeapTupleUpdated: - - /* - * The target tuple was concurrently updated/deleted by - * some other transaction. - * - * If the current tuple is that last tuple in the update - * chain, then we know that the tuple was concurrently - * deleted. Just return and let the caller try NOT MATCHED - * actions. - * - * If the current tuple was concurrently updated, then we - * must run the EvalPlanQual() with the new version of the - * tuple. If EvalPlanQual() does not return a tuple then - * we switch to the NOT MATCHED list of actions. - * If it does return a tuple and the join qual is - * still satisfied, then we just need to recheck the - * MATCHED actions, starting from the top, and execute the - * first qualifying action. - */ - if (!ItemPointerEquals(tupleid, &hufd.ctid)) - { - TupleTableSlot *epqslot; - - /* - * Since we generate a JOIN query with a target table - * RTE different than the result relation RTE, we must - * pass in the RTI of the relation used in the join - * query and not the one from result relation. - */ - Assert(resultRelInfo->ri_mergeTargetRTI > 0); - epqslot = EvalPlanQual(estate, - epqstate, - resultRelInfo->ri_RelationDesc, - GetEPQRangeTableIndex(resultRelInfo), - LockTupleExclusive, - &hufd.ctid, - hufd.xmax); - - if (!TupIsNull(epqslot)) - { - (void) ExecGetJunkAttribute(epqslot, - resultRelInfo->ri_junkFilter->jf_junkAttNo, - &isNull); - - /* - * A non-NULL ctid means that we are still dealing - * with MATCHED case. But we must retry from the - * start with the updated tuple to ensure that the - * first qualifying WHEN MATCHED action is - * executed. - * - * We don't use the new slot returned by - * EvalPlanQual because we anyways re-install the - * new target tuple in econtext->ecxt_scantuple - * before re-evaluating WHEN AND conditions and - * re-projecting the update targetlists. The - * source side tuple does not change and hence we - * can safely continue to use the old slot. - */ - if (!isNull) - { - /* - * Must update *tupleid to the TID of the - * newer tuple found in the update chain. - */ - *tupleid = hufd.ctid; - ReleaseBuffer(buffer); - goto lmerge_matched; - } - } - } - - /* - * Tell the caller about the updated TID, restore the - * state back and return. - */ - *tupleid = hufd.ctid; - estate->es_result_relation_info = saved_resultRelInfo; - ReleaseBuffer(buffer); - return false; - - default: - break; - - } - } - - if (action->commandType == CMD_UPDATE && tuple_updated) - InstrCountFiltered2(&mtstate->ps, 1); - if (action->commandType == CMD_DELETE && tuple_deleted) - InstrCountFiltered3(&mtstate->ps, 1); - - /* - * We've activated one of the WHEN clauses, so we don't search - * further. This is required behaviour, not an optimization. - */ - estate->es_result_relation_info = saved_resultRelInfo; - break; - } - - ReleaseBuffer(buffer); - - /* - * Successfully executed an action or no qualifying action was found. - */ - return true; -} - -/* - * Execute the first qualifying NOT MATCHED action. - */ -static void -ExecMergeNotMatched(ModifyTableState *mtstate, EState *estate, - TupleTableSlot *slot) -{ - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - ExprContext *econtext = mtstate->ps.ps_ExprContext; - List *mergeNotMatchedActionStates = NIL; - ResultRelInfo *resultRelInfo; - ListCell *l; - TupleTableSlot *myslot; - - /* - * We are dealing with NOT MATCHED tuple. Since for MERGE, the partition - * tree is not expanded for the result relation, we continue to work with - * the currently active result relation, which corresponds to the root - * of the partition tree. - */ - resultRelInfo = mtstate->resultRelInfo; - - /* - * For INSERT actions, root relation's merge action is OK since the - * INSERT's targetlist and the WHEN conditions can only refer to the - * source relation and hence it does not matter which result relation we - * work with. - */ - mergeNotMatchedActionStates = - resultRelInfo->ri_mergeState->notMatchedActionStates; - - /* - * Make source tuple available to ExecQual and ExecProject. We don't need - * the target tuple since the WHEN quals and the targetlist can't refer to - * the target columns. - */ - econtext->ecxt_scantuple = NULL; - econtext->ecxt_innertuple = slot; - econtext->ecxt_outertuple = NULL; - - foreach(l, mergeNotMatchedActionStates) - { - MergeActionState *action = (MergeActionState *) lfirst(l); - - /* - * Test condition, if any - * - * In the absence of a condition we perform the action unconditionally - * (no need to check separately since ExecQual() will return true if - * there are no conditions to evaluate). - */ - if (!ExecQual(action->whenqual, econtext)) - continue; - - /* Perform stated action */ - switch (action->commandType) - { - case CMD_INSERT: - - /* - * We set up the projection earlier, so all we do here is - * Project, no need for any other tasks prior to the - * ExecInsert. - */ - if (mtstate->mt_partition_tuple_routing) - ExecSetSlotDescriptor(mtstate->mt_mergeproj, action->tupDesc); - ExecProject(action->proj); - - /* - * ExecPrepareTupleRouting may modify the passed-in slot. Hence - * pass a local reference so that action->slot is not modified. - */ - myslot = mtstate->mt_mergeproj; - - /* Prepare for tuple routing if needed. */ - if (proute) - myslot = ExecPrepareTupleRouting(mtstate, estate, proute, - resultRelInfo, myslot); - slot = ExecInsert(mtstate, myslot, slot, - estate, action, - mtstate->canSetTag); - /* Revert ExecPrepareTupleRouting's state change. */ - if (proute) - estate->es_result_relation_info = resultRelInfo; - InstrCountFiltered1(&mtstate->ps, 1); - break; - case CMD_NOTHING: - /* Do Nothing */ - break; - default: - elog(ERROR, "unknown action in MERGE WHEN NOT MATCHED clause"); - } - - break; - } -} - -void -ExecInitMerge(ModifyTableState *mtstate, EState *estate, - ResultRelInfo *resultRelInfo) -{ - ListCell *l; - ExprContext *econtext; - List *mergeMatchedActionStates = NIL; - List *mergeNotMatchedActionStates = NIL; - TupleDesc relationDesc = resultRelInfo->ri_RelationDesc->rd_att; - ModifyTable *node = (ModifyTable *) mtstate->ps.plan; - - if (node->mergeActionList == NIL) - return; - - mtstate->mt_merge_subcommands = 0; - - if (mtstate->ps.ps_ExprContext == NULL) - ExecAssignExprContext(estate, &mtstate->ps); - - econtext = mtstate->ps.ps_ExprContext; - - /* initialize slot for the existing tuple */ - Assert(mtstate->mt_existing == NULL); - mtstate->mt_existing = - ExecInitExtraTupleSlot(mtstate->ps.state, - mtstate->mt_partition_tuple_routing ? - NULL : relationDesc); - - /* initialize slot for merge actions */ - Assert(mtstate->mt_mergeproj == NULL); - mtstate->mt_mergeproj = - ExecInitExtraTupleSlot(mtstate->ps.state, - mtstate->mt_partition_tuple_routing ? - NULL : relationDesc); - - /* - * Create a MergeActionState for each action on the mergeActionList - * and add it to either a list of matched actions or not-matched - * actions. - */ - foreach(l, node->mergeActionList) - { - MergeAction *action = (MergeAction *) lfirst(l); - MergeActionState *action_state = makeNode(MergeActionState); - TupleDesc tupDesc; - - action_state->matched = action->matched; - action_state->commandType = action->commandType; - action_state->whenqual = ExecInitQual((List *) action->qual, - &mtstate->ps); - - /* create target slot for this action's projection */ - tupDesc = ExecTypeFromTL((List *) action->targetList, - resultRelInfo->ri_RelationDesc->rd_rel->relhasoids); - action_state->tupDesc = tupDesc; - - /* build action projection state */ - action_state->proj = - ExecBuildProjectionInfo(action->targetList, econtext, - mtstate->mt_mergeproj, &mtstate->ps, - resultRelInfo->ri_RelationDesc->rd_att); - - /* - * We create two lists - one for WHEN MATCHED actions and one - * for WHEN NOT MATCHED actions - and stick the - * MergeActionState into the appropriate list. - */ - if (action_state->matched) - mergeMatchedActionStates = - lappend(mergeMatchedActionStates, action_state); - else - mergeNotMatchedActionStates = - lappend(mergeNotMatchedActionStates, action_state); - - switch (action->commandType) - { - case CMD_INSERT: - ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc, - action->targetList); - mtstate->mt_merge_subcommands |= MERGE_INSERT; - break; - case CMD_UPDATE: - ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc, - action->targetList); - mtstate->mt_merge_subcommands |= MERGE_UPDATE; - break; - case CMD_DELETE: - mtstate->mt_merge_subcommands |= MERGE_DELETE; - break; - case CMD_NOTHING: - break; - default: - elog(ERROR, "unknown operation"); - break; - } - - resultRelInfo->ri_mergeState->matchedActionStates = - mergeMatchedActionStates; - resultRelInfo->ri_mergeState->notMatchedActionStates = - mergeNotMatchedActionStates; - } -} diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index 52f1a96db5f..53cd2fc666b 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -3,7 +3,7 @@ * execParallel.c * Support routines for parallel execution. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file contains routines that are intended to support setting up, @@ -23,7 +23,6 @@ #include "postgres.h" -#include "executor/execExpr.h" #include "executor/execParallel.h" #include "executor/executor.h" #include "executor/nodeAppend.h" @@ -36,10 +35,10 @@ #include "executor/nodeIndexonlyscan.h" #include "executor/nodeSeqscan.h" #include "executor/nodeSort.h" +#include "executor/nodeSubplan.h" #include "executor/tqueue.h" +#include "jit/jit.h" #include "nodes/nodeFuncs.h" -#include "optimizer/planmain.h" -#include "optimizer/planner.h" #include "storage/spin.h" #include "tcop/tcopprot.h" #include "utils/datum.h" @@ -62,6 +61,7 @@ #define PARALLEL_KEY_INSTRUMENTATION UINT64CONST(0xE000000000000006) #define PARALLEL_KEY_DSA UINT64CONST(0xE000000000000007) #define PARALLEL_KEY_QUERY_TEXT UINT64CONST(0xE000000000000008) +#define PARALLEL_KEY_JIT_INSTRUMENTATION UINT64CONST(0xE000000000000009) #define PARALLEL_TUPLE_QUEUE_SIZE 65536 @@ -123,15 +123,15 @@ typedef struct ExecParallelInitializeDSMContext /* Helper functions that run in the parallel leader. */ static char *ExecSerializePlan(Plan *plan, EState *estate); static bool ExecParallelEstimate(PlanState *node, - ExecParallelEstimateContext *e); + ExecParallelEstimateContext *e); static bool ExecParallelInitializeDSM(PlanState *node, - ExecParallelInitializeDSMContext *d); + ExecParallelInitializeDSMContext *d); static shm_mq_handle **ExecParallelSetupTupleQueues(ParallelContext *pcxt, - bool reinitialize); + bool reinitialize); static bool ExecParallelReInitializeDSM(PlanState *planstate, - ParallelContext *pcxt); + ParallelContext *pcxt); static bool ExecParallelRetrieveInstrumentation(PlanState *planstate, - SharedExecutorInstrumentation *instrumentation); + SharedExecutorInstrumentation *instrumentation); /* Helper function that runs in the parallel worker. */ static DestReceiver *ExecParallelGetReceiver(dsm_segment *seg, shm_toc *toc); @@ -181,7 +181,6 @@ ExecSerializePlan(Plan *plan, EState *estate) pstmt->planTree = plan; pstmt->rtable = estate->es_range_table; pstmt->resultRelations = NIL; - pstmt->nonleafResultRelations = NIL; /* * Transfer only parallel-safe subplans, leaving a NULL "hole" in the list @@ -220,7 +219,7 @@ ExecSerializePlan(Plan *plan, EState *estate) * &pcxt->estimator. * * While we're at it, count the number of PlanState nodes in the tree, so - * we know how many SharedPlanStateInstrumentation structures we need. + * we know how many Instrumentation structures we need. */ static bool ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e) @@ -573,16 +572,28 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, char *paramlistinfo_space; BufferUsage *bufusage_space; SharedExecutorInstrumentation *instrumentation = NULL; + SharedJitInstrumentation *jit_instrumentation = NULL; int pstmt_len; int paramlistinfo_len; int instrumentation_len = 0; + int jit_instrumentation_len = 0; int instrument_offset = 0; Size dsa_minsize = dsa_minimum_size(); char *query_string; int query_len; - /* Force parameters we're going to pass to workers to be evaluated. */ - ExecEvalParamExecParams(sendParams, estate); + /* + * Force any initplan outputs that we're going to pass to workers to be + * evaluated, if they weren't already. + * + * For simplicity, we use the EState's per-output-tuple ExprContext here. + * That risks intra-query memory leakage, since we might pass through here + * many times before that ExprContext gets reset; but ExecSetParamPlan + * doesn't normally leak any memory in the context (see its comments), so + * it doesn't seem worth complicating this function's API to pass it a + * shorter-lived ExprContext. This might need to change someday. + */ + ExecSetParamPlanMulti(sendParams, GetPerTupleExprContext(estate)); /* Allocate object for return value. */ pei = palloc0(sizeof(ParallelExecutorInfo)); @@ -593,7 +604,7 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, pstmt_data = ExecSerializePlan(planstate->plan, estate); /* Create a parallel context. */ - pcxt = CreateParallelContext("postgres", "ParallelQueryMain", nworkers, false); + pcxt = CreateParallelContext("postgres", "ParallelQueryMain", nworkers); pei->pcxt = pcxt; /* @@ -659,6 +670,16 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, mul_size(e.nnodes, nworkers)); shm_toc_estimate_chunk(&pcxt->estimator, instrumentation_len); shm_toc_estimate_keys(&pcxt->estimator, 1); + + /* Estimate space for JIT instrumentation, if required. */ + if (estate->es_jit_flags != PGJIT_NONE) + { + jit_instrumentation_len = + offsetof(SharedJitInstrumentation, jit_instr) + + sizeof(JitInstrumentation) * nworkers; + shm_toc_estimate_chunk(&pcxt->estimator, jit_instrumentation_len); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } } /* Estimate space for DSA area. */ @@ -732,6 +753,18 @@ ExecInitParallelPlan(PlanState *planstate, EState *estate, shm_toc_insert(pcxt->toc, PARALLEL_KEY_INSTRUMENTATION, instrumentation); pei->instrumentation = instrumentation; + + if (estate->es_jit_flags != PGJIT_NONE) + { + jit_instrumentation = shm_toc_allocate(pcxt->toc, + jit_instrumentation_len); + jit_instrumentation->num_workers = nworkers; + memset(jit_instrumentation->jit_instr, 0, + sizeof(JitInstrumentation) * nworkers); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_JIT_INSTRUMENTATION, + jit_instrumentation); + pei->jit_instrumentation = jit_instrumentation; + } } /* @@ -831,8 +864,12 @@ ExecParallelReinitialize(PlanState *planstate, /* Old workers must already be shut down */ Assert(pei->finished); - /* Force parameters we're going to pass to workers to be evaluated. */ - ExecEvalParamExecParams(sendParams, estate); + /* + * Force any initplan outputs that we're going to pass to workers to be + * evaluated, if they weren't already (see comments in + * ExecInitParallelPlan). + */ + ExecSetParamPlanMulti(sendParams, GetPerTupleExprContext(estate)); ReinitializeParallelDSM(pei->pcxt); pei->tqueue = ExecParallelSetupTupleQueues(pei->pcxt, true); @@ -989,6 +1026,45 @@ ExecParallelRetrieveInstrumentation(PlanState *planstate, instrumentation); } +/* + * Add up the workers' JIT instrumentation from dynamic shared memory. + */ +static void +ExecParallelRetrieveJitInstrumentation(PlanState *planstate, + SharedJitInstrumentation *shared_jit) +{ + JitInstrumentation *combined; + int ibytes; + + int n; + + /* + * Accumulate worker JIT instrumentation into the combined JIT + * instrumentation, allocating it if required. + */ + if (!planstate->state->es_jit_worker_instr) + planstate->state->es_jit_worker_instr = + MemoryContextAllocZero(planstate->state->es_query_cxt, sizeof(JitInstrumentation)); + combined = planstate->state->es_jit_worker_instr; + + /* Accumulate all the workers' instrumentations. */ + for (n = 0; n < shared_jit->num_workers; ++n) + InstrJitAgg(combined, &shared_jit->jit_instr[n]); + + /* + * Store the per-worker detail. + * + * Similar to ExecParallelRetrieveInstrumentation(), allocate the + * instrumentation in per-query context. + */ + ibytes = offsetof(SharedJitInstrumentation, jit_instr) + + mul_size(shared_jit->num_workers, sizeof(JitInstrumentation)); + planstate->worker_jit_instrument = + MemoryContextAlloc(planstate->state->es_query_cxt, ibytes); + + memcpy(planstate->worker_jit_instrument, shared_jit, ibytes); +} + /* * Finish parallel execution. We wait for parallel workers to finish, and * accumulate their buffer usage. @@ -1054,6 +1130,11 @@ ExecParallelCleanup(ParallelExecutorInfo *pei) ExecParallelRetrieveInstrumentation(pei->planstate, pei->instrumentation); + /* Accumulate JIT instrumentation, if any. */ + if (pei->jit_instrumentation) + ExecParallelRetrieveJitInstrumentation(pei->planstate, + pei->jit_instrumentation); + /* Free any serialized parameters. */ if (DsaPointerIsValid(pei->param_exec)) { @@ -1114,14 +1195,7 @@ ExecParallelGetQueryDesc(shm_toc *toc, DestReceiver *receiver, paramspace = shm_toc_lookup(toc, PARALLEL_KEY_PARAMLISTINFO, false); paramLI = RestoreParamList(¶mspace); - /* - * Create a QueryDesc for the query. - * - * It's not obvious how to obtain the query string from here; and even if - * we could copying it would take more cycles than not copying it. But - * it's a bit unsatisfying to just use a dummy string here, so consider - * revising this someday. - */ + /* Create a QueryDesc for the query. */ return CreateQueryDesc(pstmt, queryString, GetActiveSnapshot(), InvalidSnapshot, @@ -1260,6 +1334,7 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) DestReceiver *receiver; QueryDesc *queryDesc; SharedExecutorInstrumentation *instrumentation; + SharedJitInstrumentation *jit_instrumentation; int instrument_options = 0; void *area_space; dsa_area *area; @@ -1273,6 +1348,8 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) instrumentation = shm_toc_lookup(toc, PARALLEL_KEY_INSTRUMENTATION, true); if (instrumentation != NULL) instrument_options = instrumentation->instrument_options; + jit_instrumentation = shm_toc_lookup(toc, PARALLEL_KEY_JIT_INSTRUMENTATION, + true); queryDesc = ExecParallelGetQueryDesc(toc, receiver, instrument_options); /* Setting debug_query_string for individual workers */ @@ -1281,9 +1358,6 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) /* Report workers' query for monitoring purposes */ pgstat_report_activity(STATE_RUNNING, debug_query_string); - /* Prepare to track buffer usage during query execution. */ - InstrStartParallelQuery(); - /* Attach to the dynamic shared memory area. */ area_space = shm_toc_lookup(toc, PARALLEL_KEY_DSA, false); area = dsa_attach_in_place(area_space, seg); @@ -1309,6 +1383,15 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) /* Pass down any tuple bound */ ExecSetTupleBound(fpes->tuples_needed, queryDesc->planstate); + /* + * Prepare to track buffer usage during query execution. + * + * We do this after starting up the executor to match what happens in the + * leader, which also doesn't count buffer accesses that occur during + * executor startup. + */ + InstrStartParallelQuery(); + /* * Run the plan. If we specified a tuple bound, be careful not to demand * more tuples than that. @@ -1330,6 +1413,14 @@ ParallelQueryMain(dsm_segment *seg, shm_toc *toc) ExecParallelReportInstrumentation(queryDesc->planstate, instrumentation); + /* Report JIT instrumentation data if any */ + if (queryDesc->estate->es_jit && jit_instrumentation != NULL) + { + Assert(ParallelWorkerNumber < jit_instrumentation->num_workers); + jit_instrumentation->jit_instr[ParallelWorkerNumber] = + queryDesc->estate->es_jit->instr; + } + /* Must do this after capturing instrumentation. */ ExecutorEnd(queryDesc); diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index d4d54e927a5..d23f292cb08 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -3,7 +3,7 @@ * execPartition.c * Support routines for partitioning. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -11,9 +11,11 @@ * *------------------------------------------------------------------------- */ - #include "postgres.h" +#include "access/table.h" +#include "access/tableam.h" +#include "catalog/partition.h" #include "catalog/pg_inherits.h" #include "catalog/pg_type.h" #include "executor/execPartition.h" @@ -22,28 +24,174 @@ #include "mb/pg_wchar.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "partitioning/partbounds.h" +#include "partitioning/partdesc.h" +#include "partitioning/partprune.h" +#include "rewrite/rewriteManip.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" +#include "utils/rel.h" #include "utils/rls.h" #include "utils/ruleutils.h" -static PartitionDispatch *RelationGetPartitionDispatchInfo(Relation rel, - int *num_parted, List **leaf_part_oids); -static void get_partition_dispatch_recurse(Relation rel, Relation parent, - List **pds, List **leaf_part_oids); + +/*----------------------- + * PartitionTupleRouting - Encapsulates all information required to + * route a tuple inserted into a partitioned table to one of its leaf + * partitions. + * + * partition_root + * The partitioned table that's the target of the command. + * + * partition_dispatch_info + * Array of 'max_dispatch' elements containing a pointer to a + * PartitionDispatch object for every partitioned table touched by tuple + * routing. The entry for the target partitioned table is *always* + * present in the 0th element of this array. See comment for + * PartitionDispatchData->indexes for details on how this array is + * indexed. + * + * num_dispatch + * The current number of items stored in the 'partition_dispatch_info' + * array. Also serves as the index of the next free array element for + * new PartitionDispatch objects that need to be stored. + * + * max_dispatch + * The current allocated size of the 'partition_dispatch_info' array. + * + * partitions + * Array of 'max_partitions' elements containing a pointer to a + * ResultRelInfo for every leaf partitions touched by tuple routing. + * Some of these are pointers to ResultRelInfos which are borrowed out of + * 'subplan_resultrel_htab'. The remainder have been built especially + * for tuple routing. See comment for PartitionDispatchData->indexes for + * details on how this array is indexed. + * + * num_partitions + * The current number of items stored in the 'partitions' array. Also + * serves as the index of the next free array element for new + * ResultRelInfo objects that need to be stored. + * + * max_partitions + * The current allocated size of the 'partitions' array. + * + * subplan_resultrel_htab + * Hash table to store subplan ResultRelInfos by Oid. This is used to + * cache ResultRelInfos from subplans of an UPDATE ModifyTable node; + * NULL in other cases. Some of these may be useful for tuple routing + * to save having to build duplicates. + * + * memcxt + * Memory context used to allocate subsidiary structs. + *----------------------- + */ +struct PartitionTupleRouting +{ + Relation partition_root; + PartitionDispatch *partition_dispatch_info; + int num_dispatch; + int max_dispatch; + ResultRelInfo **partitions; + int num_partitions; + int max_partitions; + HTAB *subplan_resultrel_htab; + MemoryContext memcxt; +}; + +/*----------------------- + * PartitionDispatch - information about one partitioned table in a partition + * hierarchy required to route a tuple to any of its partitions. A + * PartitionDispatch is always encapsulated inside a PartitionTupleRouting + * struct and stored inside its 'partition_dispatch_info' array. + * + * reldesc + * Relation descriptor of the table + * + * key + * Partition key information of the table + * + * keystate + * Execution state required for expressions in the partition key + * + * partdesc + * Partition descriptor of the table + * + * tupslot + * A standalone TupleTableSlot initialized with this table's tuple + * descriptor, or NULL if no tuple conversion between the parent is + * required. + * + * tupmap + * TupleConversionMap to convert from the parent's rowtype to this table's + * rowtype (when extracting the partition key of a tuple just before + * routing it through this table). A NULL value is stored if no tuple + * conversion is required. + * + * indexes + * Array of partdesc->nparts elements. For leaf partitions the index + * corresponds to the partition's ResultRelInfo in the encapsulating + * PartitionTupleRouting's partitions array. For partitioned partitions, + * the index corresponds to the PartitionDispatch for it in its + * partition_dispatch_info array. -1 indicates we've not yet allocated + * anything in PartitionTupleRouting for the partition. + *----------------------- + */ +typedef struct PartitionDispatchData +{ + Relation reldesc; + PartitionKey key; + List *keystate; /* list of ExprState */ + PartitionDesc partdesc; + TupleTableSlot *tupslot; + AttrNumber *tupmap; + int indexes[FLEXIBLE_ARRAY_MEMBER]; +} PartitionDispatchData; + +/* struct to hold result relations coming from UPDATE subplans */ +typedef struct SubplanResultRelHashElem +{ + Oid relid; /* hash key -- must be first */ + ResultRelInfo *rri; +} SubplanResultRelHashElem; + + +static void ExecHashSubPlanResultRelsByOid(ModifyTableState *mtstate, + PartitionTupleRouting *proute); +static ResultRelInfo *ExecInitPartitionInfo(ModifyTableState *mtstate, + EState *estate, PartitionTupleRouting *proute, + PartitionDispatch dispatch, + ResultRelInfo *rootResultRelInfo, + int partidx); +static void ExecInitRoutingInfo(ModifyTableState *mtstate, + EState *estate, + PartitionTupleRouting *proute, + PartitionDispatch dispatch, + ResultRelInfo *partRelInfo, + int partidx); +static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, + PartitionTupleRouting *proute, + Oid partoid, PartitionDispatch parent_pd, int partidx); static void FormPartitionKeyDatum(PartitionDispatch pd, - TupleTableSlot *slot, - EState *estate, - Datum *values, - bool *isnull); + TupleTableSlot *slot, + EState *estate, + Datum *values, + bool *isnull); +static int get_partition_for_tuple(PartitionDispatch pd, Datum *values, + bool *isnull); static char *ExecBuildSlotPartitionKeyDescription(Relation rel, - Datum *values, - bool *isnull, - int maxfieldlen); + Datum *values, + bool *isnull, + int maxfieldlen); static List *adjust_partition_tlist(List *tlist, TupleConversionMap *map); -static void find_subplans_for_params_recurse(PartitionPruneState *prunestate, - PartitionPruningData *pprune, - bool allparams, - Bitmapset **validsubplans); +static void ExecInitPruningContext(PartitionPruneContext *context, + List *pruning_steps, + PartitionDesc partdesc, + PartitionKey partkey, + PlanState *planstate); +static void find_matching_subplans_recurse(PartitionPruningData *prunedata, + PartitionedRelPruningData *pprune, + bool initial_prune, + Bitmapset **validsubplans); /* @@ -51,187 +199,122 @@ static void find_subplans_for_params_recurse(PartitionPruneState *prunestate, * tuple routing for partitioned tables, encapsulates it in * PartitionTupleRouting, and returns it. * - * Note that all the relations in the partition tree are locked using the - * RowExclusiveLock mode upon return from this function. + * Callers must use the returned PartitionTupleRouting during calls to + * ExecFindPartition(). The actual ResultRelInfo for a partition is only + * allocated when the partition is found for the first time. * - * While we allocate the arrays of pointers of ResultRelInfo and - * TupleConversionMap for all partitions here, actual objects themselves are - * lazily allocated for a given partition if a tuple is actually routed to it; - * see ExecInitPartitionInfo. However, if the function is invoked for update - * tuple routing, caller would already have initialized ResultRelInfo's for - * some of the partitions, which are reused and assigned to their respective - * slot in the aforementioned array. For such partitions, we delay setting - * up objects such as TupleConversionMap until those are actually chosen as - * the partitions to route tuples to. See ExecPrepareTupleRouting. + * The current memory context is used to allocate this struct and all + * subsidiary structs that will be allocated from it later on. Typically + * it should be estate->es_query_cxt. */ PartitionTupleRouting * -ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, Relation rel) +ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate, + Relation rel) { - List *leaf_parts; - ListCell *cell; - int i; - ResultRelInfo *update_rri = NULL; - int num_update_rri = 0, - update_rri_index = 0; - bool is_update = false; - bool is_merge = false; PartitionTupleRouting *proute; - int nparts; ModifyTable *node = mtstate ? (ModifyTable *) mtstate->ps.plan : NULL; /* - * Get the information about the partition tree after locking all the - * partitions. + * Here we attempt to expend as little effort as possible in setting up + * the PartitionTupleRouting. Each partition's ResultRelInfo is built on + * demand, only when we actually need to route a tuple to that partition. + * The reason for this is that a common case is for INSERT to insert a + * single tuple into a partitioned table and this must be fast. */ - (void) find_all_inheritors(RelationGetRelid(rel), RowExclusiveLock, NULL); proute = (PartitionTupleRouting *) palloc0(sizeof(PartitionTupleRouting)); - proute->partition_dispatch_info = - RelationGetPartitionDispatchInfo(rel, &proute->num_dispatch, - &leaf_parts); - proute->num_partitions = nparts = list_length(leaf_parts); - proute->partitions = - (ResultRelInfo **) palloc(nparts * sizeof(ResultRelInfo *)); - proute->parent_child_tupconv_maps = - (TupleConversionMap **) palloc0(nparts * sizeof(TupleConversionMap *)); - proute->partition_oids = (Oid *) palloc(nparts * sizeof(Oid)); - - /* Set up details specific to the type of tuple routing we are doing. */ - if (node && node->operation == CMD_UPDATE) - is_update = true; - else if (node && node->operation == CMD_MERGE) - is_merge = true; - - if (is_update) - { - update_rri = mtstate->resultRelInfo; - num_update_rri = list_length(node->plans); - proute->subplan_partition_offsets = - palloc(num_update_rri * sizeof(int)); - proute->num_subplan_partition_offsets = num_update_rri; - } - - - if (is_update || is_merge) - { - /* - * We need an additional tuple slot for storing transient tuples that - * are converted to the root table descriptor. - */ - proute->root_tuple_slot = MakeTupleTableSlot(NULL); - } + proute->partition_root = rel; + proute->memcxt = CurrentMemoryContext; + /* Rest of members initialized by zeroing */ /* - * Initialize an empty slot that will be used to manipulate tuples of any - * given partition's rowtype. It is attached to the caller-specified node - * (such as ModifyTableState) and released when the node finishes - * processing. + * Initialize this table's PartitionDispatch object. Here we pass in the + * parent as NULL as we don't need to care about any parent of the target + * partitioned table. */ - proute->partition_tuple_slot = MakeTupleTableSlot(NULL); - - i = 0; - foreach(cell, leaf_parts) - { - ResultRelInfo *leaf_part_rri = NULL; - Oid leaf_oid = lfirst_oid(cell); - - proute->partition_oids[i] = leaf_oid; - - /* - * If the leaf partition is already present in the per-subplan result - * rels, we re-use that rather than initialize a new result rel. The - * per-subplan resultrels and the resultrels of the leaf partitions - * are both in the same canonical order. So while going through the - * leaf partition oids, we need to keep track of the next per-subplan - * result rel to be looked for in the leaf partition resultrels. - */ - if (update_rri_index < num_update_rri && - RelationGetRelid(update_rri[update_rri_index].ri_RelationDesc) == leaf_oid) - { - leaf_part_rri = &update_rri[update_rri_index]; - - /* - * This is required in order to convert the partition's tuple to - * be compatible with the root partitioned table's tuple - * descriptor. When generating the per-subplan result rels, this - * was not set. - */ - leaf_part_rri->ri_PartitionRoot = rel; - - /* Remember the subplan offset for this ResultRelInfo */ - proute->subplan_partition_offsets[update_rri_index] = i; - - update_rri_index++; - } - - proute->partitions[i] = leaf_part_rri; - i++; - } + ExecInitPartitionDispatchInfo(estate, proute, RelationGetRelid(rel), + NULL, 0); /* - * For UPDATE, we should have found all the per-subplan resultrels in the - * leaf partitions. (If this is an INSERT, both values will be zero.) + * If performing an UPDATE with tuple routing, we can reuse partition + * sub-plan result rels. We build a hash table to map the OIDs of + * partitions present in mtstate->resultRelInfo to their ResultRelInfos. + * Every time a tuple is routed to a partition that we've yet to set the + * ResultRelInfo for, before we go to the trouble of making one, we check + * for a pre-made one in the hash table. */ - Assert(update_rri_index == num_update_rri); + if (node && node->operation == CMD_UPDATE) + ExecHashSubPlanResultRelsByOid(mtstate, proute); return proute; } /* - * ExecFindPartition -- Find a leaf partition in the partition tree rooted - * at parent, for the heap tuple contained in *slot + * ExecFindPartition -- Return the ResultRelInfo for the leaf partition that + * the tuple contained in *slot should belong to. + * + * If the partition's ResultRelInfo does not yet exist in 'proute' then we set + * one up or reuse one from mtstate's resultRelInfo array. When reusing a + * ResultRelInfo from the mtstate we verify that the relation is a valid + * target for INSERTs and then set up a PartitionRoutingInfo for it. + * + * rootResultRelInfo is the relation named in the query. * * estate must be non-NULL; we'll need it to compute any expressions in the - * partition key(s) + * partition keys. Also, its per-tuple contexts are used as evaluation + * scratch space. * * If no leaf partition is found, this routine errors out with the appropriate - * error message, else it returns the leaf partition sequence number - * as an index into the array of (ResultRelInfos of) all leaf partitions in - * the partition tree. + * error message. An error may also be raised if the found target partition + * is not a valid target for an INSERT. */ -int -ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, +ResultRelInfo * +ExecFindPartition(ModifyTableState *mtstate, + ResultRelInfo *rootResultRelInfo, + PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate) { - int result; + PartitionDispatch *pd = proute->partition_dispatch_info; Datum values[PARTITION_MAX_KEYS]; bool isnull[PARTITION_MAX_KEYS]; Relation rel; - PartitionDispatch parent; + PartitionDispatch dispatch; + PartitionDesc partdesc; ExprContext *ecxt = GetPerTupleExprContext(estate); TupleTableSlot *ecxt_scantuple_old = ecxt->ecxt_scantuple; + TupleTableSlot *myslot = NULL; + MemoryContext oldcxt; + + /* use per-tuple context here to avoid leaking memory */ + oldcxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); /* * First check the root table's partition constraint, if any. No point in * routing the tuple if it doesn't belong in the root table itself. */ - if (resultRelInfo->ri_PartitionCheck && - !ExecPartitionCheck(resultRelInfo, slot, estate)) - ExecPartitionCheckEmitError(resultRelInfo, slot, estate); + if (rootResultRelInfo->ri_PartitionCheck) + ExecPartitionCheck(rootResultRelInfo, slot, estate, true); /* start with the root partitioned table */ - parent = pd[0]; + dispatch = pd[0]; while (true) { - PartitionDesc partdesc; - TupleTableSlot *myslot = parent->tupslot; - TupleConversionMap *map = parent->tupmap; - int cur_index = -1; + AttrNumber *map = dispatch->tupmap; + int partidx = -1; - rel = parent->reldesc; - partdesc = RelationGetPartitionDesc(rel); + CHECK_FOR_INTERRUPTS(); + + rel = dispatch->reldesc; + partdesc = dispatch->partdesc; /* - * Convert the tuple to this parent's layout so that we can do certain - * things we do below. + * Convert the tuple to this parent's layout, if different from the + * current relation. */ - if (myslot != NULL && map != NULL) + myslot = dispatch->tupslot; + if (myslot != NULL) { - HeapTuple tuple = ExecFetchSlotTuple(slot); - - ExecClearTuple(myslot); - tuple = do_convert_tuple(tuple, map); - ExecStoreTuple(tuple, myslot, InvalidBuffer, true); - slot = myslot; + Assert(map != NULL); + slot = execute_attr_map_slot(map, slot, myslot); } /* @@ -243,136 +326,211 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd, * So update ecxt_scantuple accordingly. */ ecxt->ecxt_scantuple = slot; - FormPartitionKeyDatum(parent, slot, estate, values, isnull); + FormPartitionKeyDatum(dispatch, slot, estate, values, isnull); /* - * Nothing for get_partition_for_tuple() to do if there are no - * partitions to begin with. + * If this partitioned table has no partitions or no partition for + * these values, error out. */ - if (partdesc->nparts == 0) + if (partdesc->nparts == 0 || + (partidx = get_partition_for_tuple(dispatch, values, isnull)) < 0) { - result = -1; - break; + char *val_desc; + + val_desc = ExecBuildSlotPartitionKeyDescription(rel, + values, isnull, 64); + Assert(OidIsValid(RelationGetRelid(rel))); + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("no partition of relation \"%s\" found for row", + RelationGetRelationName(rel)), + val_desc ? + errdetail("Partition key of the failing row contains %s.", + val_desc) : 0)); } - cur_index = get_partition_for_tuple(rel, values, isnull); - - /* - * cur_index < 0 means we failed to find a partition of this parent. - * cur_index >= 0 means we either found the leaf partition, or the - * next parent to find a partition of. - */ - if (cur_index < 0) + if (partdesc->is_leaf[partidx]) { - result = -1; - break; - } - else if (parent->indexes[cur_index] >= 0) - { - result = parent->indexes[cur_index]; - break; + ResultRelInfo *rri; + + /* + * Look to see if we've already got a ResultRelInfo for this + * partition. + */ + if (likely(dispatch->indexes[partidx] >= 0)) + { + /* ResultRelInfo already built */ + Assert(dispatch->indexes[partidx] < proute->num_partitions); + rri = proute->partitions[dispatch->indexes[partidx]]; + } + else + { + bool found = false; + + /* + * We have not yet set up a ResultRelInfo for this partition, + * but if we have a subplan hash table, we might have one + * there. If not, we'll have to create one. + */ + if (proute->subplan_resultrel_htab) + { + Oid partoid = partdesc->oids[partidx]; + SubplanResultRelHashElem *elem; + + elem = hash_search(proute->subplan_resultrel_htab, + &partoid, HASH_FIND, NULL); + if (elem) + { + found = true; + rri = elem->rri; + + /* Verify this ResultRelInfo allows INSERTs */ + CheckValidResultRel(rri, CMD_INSERT); + + /* Set up the PartitionRoutingInfo for it */ + ExecInitRoutingInfo(mtstate, estate, proute, dispatch, + rri, partidx); + } + } + + /* We need to create a new one. */ + if (!found) + rri = ExecInitPartitionInfo(mtstate, estate, proute, + dispatch, + rootResultRelInfo, partidx); + } + + /* Release the tuple in the lowest parent's dedicated slot. */ + if (slot == myslot) + ExecClearTuple(myslot); + + MemoryContextSwitchTo(oldcxt); + ecxt->ecxt_scantuple = ecxt_scantuple_old; + return rri; } else - parent = pd[-parent->indexes[cur_index]]; - } + { + /* + * Partition is a sub-partitioned table; get the PartitionDispatch + */ + if (likely(dispatch->indexes[partidx] >= 0)) + { + /* Already built. */ + Assert(dispatch->indexes[partidx] < proute->num_dispatch); - /* A partition was not found. */ - if (result < 0) - { - char *val_desc; - - val_desc = ExecBuildSlotPartitionKeyDescription(rel, - values, isnull, 64); - Assert(OidIsValid(RelationGetRelid(rel))); - ereport(ERROR, - (errcode(ERRCODE_CHECK_VIOLATION), - errmsg("no partition of relation \"%s\" found for row", - RelationGetRelationName(rel)), - val_desc ? errdetail("Partition key of the failing row contains %s.", val_desc) : 0)); - } + /* + * Move down to the next partition level and search again + * until we find a leaf partition that matches this tuple + */ + dispatch = pd[dispatch->indexes[partidx]]; + } + else + { + /* Not yet built. Do that now. */ + PartitionDispatch subdispatch; - ecxt->ecxt_scantuple = ecxt_scantuple_old; - return result; + /* + * Create the new PartitionDispatch. We pass the current one + * in as the parent PartitionDispatch + */ + subdispatch = ExecInitPartitionDispatchInfo(mtstate->ps.state, + proute, + partdesc->oids[partidx], + dispatch, partidx); + Assert(dispatch->indexes[partidx] >= 0 && + dispatch->indexes[partidx] < proute->num_dispatch); + dispatch = subdispatch; + } + } + } } /* - * Given OID of the partition leaf, return the index of the leaf in the - * partition hierarchy. - * - * XXX This is an O(N) operation and further optimization would be beneficial + * ExecHashSubPlanResultRelsByOid + * Build a hash table to allow fast lookups of subplan ResultRelInfos by + * partition Oid. We also populate the subplan ResultRelInfo with an + * ri_PartitionRoot. */ -int -ExecFindPartitionByOid(PartitionTupleRouting *proute, Oid partoid) +static void +ExecHashSubPlanResultRelsByOid(ModifyTableState *mtstate, + PartitionTupleRouting *proute) { - int i; + HASHCTL ctl; + HTAB *htab; + int i; - for (i = 0; i < proute->num_partitions; i++) + memset(&ctl, 0, sizeof(ctl)); + ctl.keysize = sizeof(Oid); + ctl.entrysize = sizeof(SubplanResultRelHashElem); + ctl.hcxt = CurrentMemoryContext; + + htab = hash_create("PartitionTupleRouting table", mtstate->mt_nplans, + &ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + proute->subplan_resultrel_htab = htab; + + /* Hash all subplans by their Oid */ + for (i = 0; i < mtstate->mt_nplans; i++) { - if (proute->partition_oids[i] == partoid) - break; - } + ResultRelInfo *rri = &mtstate->resultRelInfo[i]; + bool found; + Oid partoid = RelationGetRelid(rri->ri_RelationDesc); + SubplanResultRelHashElem *elem; - if (i >= proute->num_partitions) - ereport(ERROR, - (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("no partition found for OID %u", partoid))); - return i; + elem = (SubplanResultRelHashElem *) + hash_search(htab, &partoid, HASH_ENTER, &found); + Assert(!found); + elem->rri = rri; + + /* + * This is required in order to convert the partition's tuple to be + * compatible with the root partitioned table's tuple descriptor. When + * generating the per-subplan result rels, this was not set. + */ + rri->ri_PartitionRoot = proute->partition_root; + } } /* * ExecInitPartitionInfo - * Initialize ResultRelInfo and other information for a partition if not - * already done + * Lock the partition and initialize ResultRelInfo. Also setup other + * information for the partition and store it in the next empty slot in + * the proute->partitions array. * * Returns the ResultRelInfo */ -ResultRelInfo * -ExecInitPartitionInfo(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo, +static ResultRelInfo * +ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, - EState *estate, int partidx) + PartitionDispatch dispatch, + ResultRelInfo *rootResultRelInfo, + int partidx) { ModifyTable *node = (ModifyTable *) mtstate->ps.plan; - Relation rootrel = resultRelInfo->ri_RelationDesc, + Relation rootrel = rootResultRelInfo->ri_RelationDesc, partrel; + Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; ResultRelInfo *leaf_part_rri; - MemoryContext oldContext; + MemoryContext oldcxt; + AttrNumber *part_attnos = NULL; + bool found_whole_row; - /* - * We locked all the partitions in ExecSetupPartitionTupleRouting - * including the leaf partitions. - */ - partrel = heap_open(proute->partition_oids[partidx], NoLock); + oldcxt = MemoryContextSwitchTo(proute->memcxt); - /* - * Keep ResultRelInfo and other information for this partition in the - * per-query memory context so they'll survive throughout the query. - */ - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + partrel = table_open(dispatch->partdesc->oids[partidx], RowExclusiveLock); leaf_part_rri = makeNode(ResultRelInfo); InitResultRelInfo(leaf_part_rri, partrel, - node ? node->nominalRelation : 1, + node ? node->rootRelation : 1, rootrel, estate->es_instrument); - leaf_part_rri->ri_PartitionLeafIndex = partidx; - /* - * Since we've just initialized this ResultRelInfo, it's not in any list - * attached to the estate as yet. Add it, so that it can be found later. - * - * Note that the entries in this list appear in no predetermined order, - * because partition result rels are initialized as and when they're - * needed. + * Verify result relation is a valid target for an INSERT. An UPDATE of a + * partition-key becomes a DELETE+INSERT operation, so this check is still + * required when the operation is CMD_UPDATE. */ - estate->es_tuple_routing_result_relations = - lappend(estate->es_tuple_routing_result_relations, - leaf_part_rri); - - /* Set up information needed for routing tuples to this partition. */ - ExecInitRoutingInfo(mtstate, estate, proute, leaf_part_rri, partidx); + CheckValidResultRel(leaf_part_rri, CMD_INSERT); /* * Open partition indices. The user may have asked to check for conflicts @@ -399,7 +557,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, List *wcoExprs = NIL; ListCell *ll; int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; - Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; /* * In the case of INSERT on a partitioned table, there is only one @@ -427,8 +584,18 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, /* * Convert Vars in it to contain this partition's attribute numbers. */ - wcoList = map_partition_varattnos(wcoList, firstVarno, - partrel, firstResultRel, NULL); + part_attnos = + convert_tuples_by_name_map(RelationGetDescr(partrel), + RelationGetDescr(firstResultRel)); + wcoList = (List *) + map_variable_attnos((Node *) wcoList, + firstVarno, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ + foreach(ll, wcoList) { WithCheckOption *wco = castNode(WithCheckOption, lfirst(ll)); @@ -455,7 +622,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, ExprContext *econtext; List *returningList; int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; - Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; /* See the comment above for WCO lists. */ Assert((node->operation == CMD_INSERT && @@ -476,9 +642,19 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, /* * Convert Vars in it to contain this partition's attribute numbers. */ - returningList = map_partition_varattnos(returningList, firstVarno, - partrel, firstResultRel, - NULL); + if (part_attnos == NULL) + part_attnos = + convert_tuples_by_name_map(RelationGetDescr(partrel), + RelationGetDescr(firstResultRel)); + returningList = (List *) + map_variable_attnos((Node *) returningList, + firstVarno, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ + leaf_part_rri->ri_returningList = returningList; /* @@ -496,14 +672,16 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, &mtstate->ps, RelationGetDescr(partrel)); } + /* Set up information needed for routing tuples to the partition. */ + ExecInitRoutingInfo(mtstate, estate, proute, dispatch, + leaf_part_rri, partidx); + /* * If there is an ON CONFLICT clause, initialize state for it. */ if (node && node->onConflictAction != ONCONFLICT_NONE) { - TupleConversionMap *map = proute->parent_child_tupconv_maps[partidx]; int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; - Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; TupleDesc partrelDesc = RelationGetDescr(partrel); ExprContext *econtext = mtstate->ps.ps_ExprContext; ListCell *lc; @@ -515,7 +693,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, * list and searching for ancestry relationships to each index in the * ancestor table. */ - if (list_length(resultRelInfo->ri_onConflictArbiterIndexes) > 0) + if (list_length(rootResultRelInfo->ri_onConflictArbiterIndexes) > 0) { List *childIdxs; @@ -528,7 +706,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, ListCell *lc2; ancestors = get_partition_ancestors(childIdx); - foreach(lc2, resultRelInfo->ri_onConflictArbiterIndexes) + foreach(lc2, rootResultRelInfo->ri_onConflictArbiterIndexes) { if (list_member_oid(ancestors, lfirst_oid(lc2))) arbiterIndexes = lappend_oid(arbiterIndexes, childIdx); @@ -542,7 +720,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, * (This shouldn't happen, since arbiter index selection should not * pick up an invalid index.) */ - if (list_length(resultRelInfo->ri_onConflictArbiterIndexes) != + if (list_length(rootResultRelInfo->ri_onConflictArbiterIndexes) != list_length(arbiterIndexes)) elog(ERROR, "invalid arbiter index list"); leaf_part_rri->ri_onConflictArbiterIndexes = arbiterIndexes; @@ -552,25 +730,53 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, */ if (node->onConflictAction == ONCONFLICT_UPDATE) { + TupleConversionMap *map; + + map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap; + Assert(node->onConflictSet != NIL); - Assert(resultRelInfo->ri_onConflict != NULL); + Assert(rootResultRelInfo->ri_onConflict != NULL); + + leaf_part_rri->ri_onConflict = makeNode(OnConflictSetState); + + /* + * Need a separate existing slot for each partition, as the + * partition could be of a different AM, even if the tuple + * descriptors match. + */ + leaf_part_rri->ri_onConflict->oc_Existing = + table_slot_create(leaf_part_rri->ri_RelationDesc, + &mtstate->ps.state->es_tupleTable); /* * If the partition's tuple descriptor matches exactly the root - * parent (the common case), we can simply re-use the parent's ON + * parent (the common case), we can re-use most of the parent's ON * CONFLICT SET state, skipping a bunch of work. Otherwise, we * need to create state specific to this partition. */ if (map == NULL) - leaf_part_rri->ri_onConflict = resultRelInfo->ri_onConflict; + { + /* + * It's safe to reuse these from the partition root, as we + * only process one tuple at a time (therefore we won't + * overwrite needed data in slots), and the results of + * projections are independent of the underlying storage. + * Projections and where clauses themselves don't store state + * / are independent of the underlying storage. + */ + leaf_part_rri->ri_onConflict->oc_ProjSlot = + rootResultRelInfo->ri_onConflict->oc_ProjSlot; + leaf_part_rri->ri_onConflict->oc_ProjInfo = + rootResultRelInfo->ri_onConflict->oc_ProjInfo; + leaf_part_rri->ri_onConflict->oc_WhereClause = + rootResultRelInfo->ri_onConflict->oc_WhereClause; + } else { List *onconflset; TupleDesc tupDesc; bool found_whole_row; - leaf_part_rri->ri_onConflict = makeNode(OnConflictSetState); - /* * Translate expressions in onConflictSet to account for * different attribute numbers. For that, map partition @@ -579,32 +785,41 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, * target relation (firstVarno). */ onconflset = (List *) copyObject((Node *) node->onConflictSet); - onconflset = - map_partition_varattnos(onconflset, INNER_VAR, partrel, - firstResultRel, &found_whole_row); - Assert(!found_whole_row); - onconflset = - map_partition_varattnos(onconflset, firstVarno, partrel, - firstResultRel, &found_whole_row); - Assert(!found_whole_row); + if (part_attnos == NULL) + part_attnos = + convert_tuples_by_name_map(RelationGetDescr(partrel), + RelationGetDescr(firstResultRel)); + onconflset = (List *) + map_variable_attnos((Node *) onconflset, + INNER_VAR, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ + onconflset = (List *) + map_variable_attnos((Node *) onconflset, + firstVarno, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ /* Finally, adjust this tlist to match the partition. */ onconflset = adjust_partition_tlist(onconflset, map); - /* - * Build UPDATE SET's projection info. The user of this - * projection is responsible for setting the slot's tupdesc! - * We set aside a tupdesc that's good for the common case of a - * partition that's tupdesc-equal to the partitioned table; - * partitions of different tupdescs must generate their own. - */ - tupDesc = ExecTypeFromTL(onconflset, partrelDesc->tdhasoid); - ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc); + /* create the tuple slot for the UPDATE SET projection */ + tupDesc = ExecTypeFromTL(onconflset); + leaf_part_rri->ri_onConflict->oc_ProjSlot = + ExecInitExtraTupleSlot(mtstate->ps.state, tupDesc, + &TTSOpsVirtual); + + /* build UPDATE SET projection state */ leaf_part_rri->ri_onConflict->oc_ProjInfo = ExecBuildProjectionInfo(onconflset, econtext, - mtstate->mt_conflproj, + leaf_part_rri->ri_onConflict->oc_ProjSlot, &mtstate->ps, partrelDesc); - leaf_part_rri->ri_onConflict->oc_ProjTupdesc = tupDesc; /* * If there is a WHERE clause, initialize state where it will @@ -617,14 +832,22 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, List *clause; clause = copyObject((List *) node->onConflictWhere); - clause = map_partition_varattnos(clause, INNER_VAR, - partrel, firstResultRel, - &found_whole_row); - Assert(!found_whole_row); - clause = map_partition_varattnos(clause, firstVarno, - partrel, firstResultRel, - &found_whole_row); - Assert(!found_whole_row); + clause = (List *) + map_variable_attnos((Node *) clause, + INNER_VAR, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ + clause = (List *) + map_variable_attnos((Node *) clause, + firstVarno, 0, + part_attnos, + RelationGetDescr(firstResultRel)->natts, + RelationGetForm(partrel)->reltype, + &found_whole_row); + /* We ignore the value of found_whole_row. */ leaf_part_rri->ri_onConflict->oc_WhereClause = ExecInitQual((List *) clause, &mtstate->ps); } @@ -632,128 +855,88 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, } } - Assert(proute->partitions[partidx] == NULL); - proute->partitions[partidx] = leaf_part_rri; - /* - * Initialize information about this partition that's needed to handle - * MERGE. + * Since we've just initialized this ResultRelInfo, it's not in any list + * attached to the estate as yet. Add it, so that it can be found later. + * + * Note that the entries in this list appear in no predetermined order, + * because partition result rels are initialized as and when they're + * needed. */ - if (node && node->operation == CMD_MERGE) - { - TupleDesc partrelDesc = RelationGetDescr(partrel); - TupleConversionMap *map = proute->parent_child_tupconv_maps[partidx]; - int firstVarno = mtstate->resultRelInfo[0].ri_RangeTableIndex; - Relation firstResultRel = mtstate->resultRelInfo[0].ri_RelationDesc; - - /* - * If the root parent and partition have the same tuple - * descriptor, just reuse the original MERGE state for partition. - */ - if (map == NULL) - { - leaf_part_rri->ri_mergeState = resultRelInfo->ri_mergeState; - } - else - { - /* Convert expressions contain partition's attnos. */ - List *conv_tl, *conv_qual; - ListCell *l; - List *matchedActionStates = NIL; - List *notMatchedActionStates = NIL; - - foreach (l, node->mergeActionList) - { - MergeAction *action = lfirst_node(MergeAction, l); - MergeActionState *action_state = makeNode(MergeActionState); - TupleDesc tupDesc; - ExprContext *econtext; - - action_state->matched = action->matched; - action_state->commandType = action->commandType; - - conv_qual = (List *) action->qual; - conv_qual = map_partition_varattnos(conv_qual, - firstVarno, partrel, - firstResultRel, NULL); - - action_state->whenqual = ExecInitQual(conv_qual, &mtstate->ps); - - conv_tl = (List *) action->targetList; - conv_tl = map_partition_varattnos(conv_tl, - firstVarno, partrel, - firstResultRel, NULL); - - conv_tl = adjust_partition_tlist( conv_tl, map); - - tupDesc = ExecTypeFromTL(conv_tl, partrelDesc->tdhasoid); - action_state->tupDesc = tupDesc; - - /* build action projection state */ - econtext = mtstate->ps.ps_ExprContext; - action_state->proj = - ExecBuildProjectionInfo(conv_tl, econtext, - mtstate->mt_mergeproj, - &mtstate->ps, - partrelDesc); - - if (action_state->matched) - matchedActionStates = - lappend(matchedActionStates, action_state); - else - notMatchedActionStates = - lappend(notMatchedActionStates, action_state); - } - leaf_part_rri->ri_mergeState->matchedActionStates = - matchedActionStates; - leaf_part_rri->ri_mergeState->notMatchedActionStates = - notMatchedActionStates; - } + MemoryContextSwitchTo(estate->es_query_cxt); + estate->es_tuple_routing_result_relations = + lappend(estate->es_tuple_routing_result_relations, + leaf_part_rri); - /* - * get_partition_dispatch_recurse() and expand_partitioned_rtentry() - * fetch the leaf OIDs in the same order. So we can safely derive the - * index of the merge target relation corresponding to this partition - * by simply adding partidx + 1 to the root's merge target relation. - */ - leaf_part_rri->ri_mergeTargetRTI = node->mergeTargetRelation + - partidx + 1; - } - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldcxt); return leaf_part_rri; } /* * ExecInitRoutingInfo - * Set up information needed for routing tuples to a leaf partition if - * routable; else abort the operation + * Set up information needed for translating tuples between root + * partitioned table format and partition format, and keep track of it + * in PartitionTupleRouting. */ -void +static void ExecInitRoutingInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, + PartitionDispatch dispatch, ResultRelInfo *partRelInfo, int partidx) { - MemoryContext oldContext; + MemoryContext oldcxt; + PartitionRoutingInfo *partrouteinfo; + int rri_index; - /* Verify the partition is a valid target for INSERT */ - CheckValidResultRel(partRelInfo, CMD_INSERT); + oldcxt = MemoryContextSwitchTo(proute->memcxt); - /* - * Switch into per-query memory context. - */ - oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + partrouteinfo = palloc(sizeof(PartitionRoutingInfo)); /* * Set up a tuple conversion map to convert a tuple routed to the * partition from the parent's type to the partition's. */ - proute->parent_child_tupconv_maps[partidx] = + partrouteinfo->pi_RootToPartitionMap = convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot), - RelationGetDescr(partRelInfo->ri_RelationDesc), - gettext_noop("could not convert row type")); + RelationGetDescr(partRelInfo->ri_RelationDesc)); + + /* + * If a partition has a different rowtype than the root parent, initialize + * a slot dedicated to storing this partition's tuples. The slot is used + * for various operations that are applied to tuples after routing, such + * as checking constraints. + */ + if (partrouteinfo->pi_RootToPartitionMap != NULL) + { + Relation partrel = partRelInfo->ri_RelationDesc; + + /* + * Initialize the slot itself setting its descriptor to this + * partition's TupleDesc; TupleDesc reference will be released at the + * end of the command. + */ + partrouteinfo->pi_PartitionTupleSlot = + table_slot_create(partrel, &estate->es_tupleTable); + } + else + partrouteinfo->pi_PartitionTupleSlot = NULL; + + /* + * Also, if transition capture is required, store a map to convert tuples + * from partition's rowtype to the root partition table's. + */ + if (mtstate && + (mtstate->mt_transition_capture || mtstate->mt_oc_transition_capture)) + { + partrouteinfo->pi_PartitionToRootMap = + convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_RelationDesc), + RelationGetDescr(partRelInfo->ri_PartitionRoot)); + } + else + partrouteinfo->pi_PartitionToRootMap = NULL; /* * If the partition is a foreign table, let the FDW init itself for @@ -763,104 +946,149 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, partRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL) partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo); - MemoryContextSwitchTo(oldContext); - - partRelInfo->ri_PartitionReadyForRouting = true; -} - -/* - * ExecSetupChildParentMapForLeaf -- Initialize the per-leaf-partition - * child-to-root tuple conversion map array. - * - * This map is required for capturing transition tuples when the target table - * is a partitioned table. For a tuple that is routed by an INSERT or UPDATE, - * we need to convert it from the leaf partition to the target table - * descriptor. - */ -void -ExecSetupChildParentMapForLeaf(PartitionTupleRouting *proute) -{ - Assert(proute != NULL); + partRelInfo->ri_PartitionInfo = partrouteinfo; + partRelInfo->ri_CopyMultiInsertBuffer = NULL; /* - * These array elements get filled up with maps on an on-demand basis. - * Initially just set all of them to NULL. + * Keep track of it in the PartitionTupleRouting->partitions array. */ - proute->child_parent_tupconv_maps = - (TupleConversionMap **) palloc0(sizeof(TupleConversionMap *) * - proute->num_partitions); + Assert(dispatch->indexes[partidx] == -1); + + rri_index = proute->num_partitions++; - /* Same is the case for this array. All the values are set to false */ - proute->child_parent_map_not_required = - (bool *) palloc0(sizeof(bool) * proute->num_partitions); + /* Allocate or enlarge the array, as needed */ + if (proute->num_partitions >= proute->max_partitions) + { + if (proute->max_partitions == 0) + { + proute->max_partitions = 8; + proute->partitions = (ResultRelInfo **) + palloc(sizeof(ResultRelInfo *) * proute->max_partitions); + } + else + { + proute->max_partitions *= 2; + proute->partitions = (ResultRelInfo **) + repalloc(proute->partitions, sizeof(ResultRelInfo *) * + proute->max_partitions); + } + } + + proute->partitions[rri_index] = partRelInfo; + dispatch->indexes[partidx] = rri_index; + + MemoryContextSwitchTo(oldcxt); } /* - * TupConvMapForLeaf -- Get the tuple conversion map for a given leaf partition - * index. + * ExecInitPartitionDispatchInfo + * Lock the partitioned table (if not locked already) and initialize + * PartitionDispatch for a partitioned table and store it in the next + * available slot in the proute->partition_dispatch_info array. Also, + * record the index into this array in the parent_pd->indexes[] array in + * the partidx element so that we can properly retrieve the newly created + * PartitionDispatch later. */ -TupleConversionMap * -TupConvMapForLeaf(PartitionTupleRouting *proute, - ResultRelInfo *rootRelInfo, int leaf_index) +static PartitionDispatch +ExecInitPartitionDispatchInfo(EState *estate, + PartitionTupleRouting *proute, Oid partoid, + PartitionDispatch parent_pd, int partidx) { - ResultRelInfo **resultRelInfos = proute->partitions; - TupleConversionMap **map; - TupleDesc tupdesc; + Relation rel; + PartitionDesc partdesc; + PartitionDispatch pd; + int dispatchidx; + MemoryContext oldcxt; - /* Don't call this if we're not supposed to be using this type of map. */ - Assert(proute->child_parent_tupconv_maps != NULL); + if (estate->es_partition_directory == NULL) + estate->es_partition_directory = + CreatePartitionDirectory(estate->es_query_cxt); - /* If it's already known that we don't need a map, return NULL. */ - if (proute->child_parent_map_not_required[leaf_index]) - return NULL; + oldcxt = MemoryContextSwitchTo(proute->memcxt); - /* If we've already got a map, return it. */ - map = &proute->child_parent_tupconv_maps[leaf_index]; - if (*map != NULL) - return *map; + /* + * Only sub-partitioned tables need to be locked here. The root + * partitioned table will already have been locked as it's referenced in + * the query's rtable. + */ + if (partoid != RelationGetRelid(proute->partition_root)) + rel = table_open(partoid, RowExclusiveLock); + else + rel = proute->partition_root; + partdesc = PartitionDirectoryLookup(estate->es_partition_directory, rel); - /* No map yet; try to create one. */ - tupdesc = RelationGetDescr(resultRelInfos[leaf_index]->ri_RelationDesc); - *map = - convert_tuples_by_name(tupdesc, - RelationGetDescr(rootRelInfo->ri_RelationDesc), - gettext_noop("could not convert row type")); + pd = (PartitionDispatch) palloc(offsetof(PartitionDispatchData, indexes) + + partdesc->nparts * sizeof(int)); + pd->reldesc = rel; + pd->key = RelationGetPartitionKey(rel); + pd->keystate = NIL; + pd->partdesc = partdesc; + if (parent_pd != NULL) + { + TupleDesc tupdesc = RelationGetDescr(rel); - /* If it turns out no map is needed, remember for next time. */ - proute->child_parent_map_not_required[leaf_index] = (*map == NULL); + /* + * For sub-partitioned tables where the column order differs from its + * direct parent partitioned table, we must store a tuple table slot + * initialized with its tuple descriptor and a tuple conversion map to + * convert a tuple from its parent's rowtype to its own. This is to + * make sure that we are looking at the correct row using the correct + * tuple descriptor when computing its partition key for tuple + * routing. + */ + pd->tupmap = convert_tuples_by_name_map_if_req(RelationGetDescr(parent_pd->reldesc), + tupdesc); + pd->tupslot = pd->tupmap ? + MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual) : NULL; + } + else + { + /* Not required for the root partitioned table */ + pd->tupmap = NULL; + pd->tupslot = NULL; + } - return *map; -} + /* + * Initialize with -1 to signify that the corresponding partition's + * ResultRelInfo or PartitionDispatch has not been created yet. + */ + memset(pd->indexes, -1, sizeof(int) * partdesc->nparts); -/* - * ConvertPartitionTupleSlot -- convenience function for tuple conversion. - * The tuple, if converted, is stored in new_slot, and *p_my_slot is - * updated to point to it. new_slot typically should be one of the - * dedicated partition tuple slots. If map is NULL, *p_my_slot is not changed. - * - * Returns the converted tuple, unless map is NULL, in which case original - * tuple is returned unmodified. - */ -HeapTuple -ConvertPartitionTupleSlot(TupleConversionMap *map, - HeapTuple tuple, - TupleTableSlot *new_slot, - TupleTableSlot **p_my_slot) -{ - if (!map) - return tuple; + /* Track in PartitionTupleRouting for later use */ + dispatchidx = proute->num_dispatch++; - tuple = do_convert_tuple(tuple, map); + /* Allocate or enlarge the array, as needed */ + if (proute->num_dispatch >= proute->max_dispatch) + { + if (proute->max_dispatch == 0) + { + proute->max_dispatch = 4; + proute->partition_dispatch_info = (PartitionDispatch *) + palloc(sizeof(PartitionDispatch) * proute->max_dispatch); + } + else + { + proute->max_dispatch *= 2; + proute->partition_dispatch_info = (PartitionDispatch *) + repalloc(proute->partition_dispatch_info, + sizeof(PartitionDispatch) * proute->max_dispatch); + } + } + proute->partition_dispatch_info[dispatchidx] = pd; /* - * Change the partition tuple slot descriptor, as per converted tuple. + * Finally, if setting up a PartitionDispatch for a sub-partitioned table, + * install a downlink in the parent to allow quick descent. */ - *p_my_slot = new_slot; - Assert(new_slot != NULL); - ExecSetSlotDescriptor(new_slot, map->outdesc); - ExecStoreTuple(tuple, new_slot, InvalidBuffer, true); + if (parent_pd) + { + Assert(parent_pd->indexes[partidx] == -1); + parent_pd->indexes[partidx] = dispatchidx; + } - return tuple; + MemoryContextSwitchTo(oldcxt); + + return pd; } /* @@ -873,8 +1101,8 @@ void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute) { + HTAB *htab = proute->subplan_resultrel_htab; int i; - int subplan_index = 0; /* * Remember, proute->partition_dispatch_info[0] corresponds to the root @@ -887,193 +1115,40 @@ ExecCleanupTupleRouting(ModifyTableState *mtstate, { PartitionDispatch pd = proute->partition_dispatch_info[i]; - heap_close(pd->reldesc, NoLock); - ExecDropSingleTupleTableSlot(pd->tupslot); + table_close(pd->reldesc, NoLock); + + if (pd->tupslot) + ExecDropSingleTupleTableSlot(pd->tupslot); } for (i = 0; i < proute->num_partitions; i++) { ResultRelInfo *resultRelInfo = proute->partitions[i]; - /* skip further processsing for uninitialized partitions */ - if (resultRelInfo == NULL) - continue; - - /* Allow any FDWs to shut down if they've been exercised */ - if (resultRelInfo->ri_PartitionReadyForRouting && - resultRelInfo->ri_FdwRoutine != NULL && + /* Allow any FDWs to shut down */ + if (resultRelInfo->ri_FdwRoutine != NULL && resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL) resultRelInfo->ri_FdwRoutine->EndForeignInsert(mtstate->ps.state, resultRelInfo); /* - * If this result rel is one of the UPDATE subplan result rels, let - * ExecEndPlan() close it. For INSERT or COPY, - * proute->subplan_partition_offsets will always be NULL. Note that - * the subplan_partition_offsets array and the partitions array have - * the partitions in the same order. So, while we iterate over - * partitions array, we also iterate over the - * subplan_partition_offsets array in order to figure out which of the - * result rels are present in the UPDATE subplans. + * Check if this result rel is one belonging to the node's subplans, + * if so, let ExecEndPlan() clean it up. */ - if (proute->subplan_partition_offsets && - subplan_index < proute->num_subplan_partition_offsets && - proute->subplan_partition_offsets[subplan_index] == i) + if (htab) { - subplan_index++; - continue; - } - - ExecCloseIndices(resultRelInfo); - heap_close(resultRelInfo->ri_RelationDesc, NoLock); - } - - /* Release the standalone partition tuple descriptors, if any */ - if (proute->root_tuple_slot) - ExecDropSingleTupleTableSlot(proute->root_tuple_slot); - if (proute->partition_tuple_slot) - ExecDropSingleTupleTableSlot(proute->partition_tuple_slot); -} - -/* - * RelationGetPartitionDispatchInfo - * Returns information necessary to route tuples down a partition tree - * - * The number of elements in the returned array (that is, the number of - * PartitionDispatch objects for the partitioned tables in the partition tree) - * is returned in *num_parted and a list of the OIDs of all the leaf - * partitions of rel is returned in *leaf_part_oids. - * - * All the relations in the partition tree (including 'rel') must have been - * locked (using at least the AccessShareLock) by the caller. - */ -static PartitionDispatch * -RelationGetPartitionDispatchInfo(Relation rel, - int *num_parted, List **leaf_part_oids) -{ - List *pdlist = NIL; - PartitionDispatchData **pd; - ListCell *lc; - int i; - - Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - - *num_parted = 0; - *leaf_part_oids = NIL; - - get_partition_dispatch_recurse(rel, NULL, &pdlist, leaf_part_oids); - *num_parted = list_length(pdlist); - pd = (PartitionDispatchData **) palloc(*num_parted * - sizeof(PartitionDispatchData *)); - i = 0; - foreach(lc, pdlist) - { - pd[i++] = lfirst(lc); - } - - return pd; -} - -/* - * get_partition_dispatch_recurse - * Recursively expand partition tree rooted at rel - * - * As the partition tree is expanded in a depth-first manner, we maintain two - * global lists: of PartitionDispatch objects corresponding to partitioned - * tables in *pds and of the leaf partition OIDs in *leaf_part_oids. - * - * Note that the order of OIDs of leaf partitions in leaf_part_oids matches - * the order in which the planner's expand_partitioned_rtentry() processes - * them. It's not necessarily the case that the offsets match up exactly, - * because constraint exclusion might prune away some partitions on the - * planner side, whereas we'll always have the complete list; but unpruned - * partitions will appear in the same order in the plan as they are returned - * here. - */ -static void -get_partition_dispatch_recurse(Relation rel, Relation parent, - List **pds, List **leaf_part_oids) -{ - TupleDesc tupdesc = RelationGetDescr(rel); - PartitionDesc partdesc = RelationGetPartitionDesc(rel); - PartitionKey partkey = RelationGetPartitionKey(rel); - PartitionDispatch pd; - int i; - - check_stack_depth(); - - /* Build a PartitionDispatch for this table and add it to *pds. */ - pd = (PartitionDispatch) palloc(sizeof(PartitionDispatchData)); - *pds = lappend(*pds, pd); - pd->reldesc = rel; - pd->key = partkey; - pd->keystate = NIL; - pd->partdesc = partdesc; - if (parent != NULL) - { - /* - * For every partitioned table other than the root, we must store a - * tuple table slot initialized with its tuple descriptor and a tuple - * conversion map to convert a tuple from its parent's rowtype to its - * own. That is to make sure that we are looking at the correct row - * using the correct tuple descriptor when computing its partition key - * for tuple routing. - */ - pd->tupslot = MakeSingleTupleTableSlot(tupdesc); - pd->tupmap = convert_tuples_by_name(RelationGetDescr(parent), - tupdesc, - gettext_noop("could not convert row type")); - } - else - { - /* Not required for the root partitioned table */ - pd->tupslot = NULL; - pd->tupmap = NULL; - } + Oid partoid; + bool found; - /* - * Go look at each partition of this table. If it's a leaf partition, - * simply add its OID to *leaf_part_oids. If it's a partitioned table, - * recursively call get_partition_dispatch_recurse(), so that its - * partitions are processed as well and a corresponding PartitionDispatch - * object gets added to *pds. - * - * About the values in pd->indexes: for a leaf partition, it contains the - * leaf partition's position in the global list *leaf_part_oids minus 1, - * whereas for a partitioned table partition, it contains the partition's - * position in the global list *pds multiplied by -1. The latter is - * multiplied by -1 to distinguish partitioned tables from leaf partitions - * when going through the values in pd->indexes. So, for example, when - * using it during tuple-routing, encountering a value >= 0 means we found - * a leaf partition. It is immediately returned as the index in the array - * of ResultRelInfos of all the leaf partitions, using which we insert the - * tuple into that leaf partition. A negative value means we found a - * partitioned table. The value multiplied by -1 is returned as the index - * in the array of PartitionDispatch objects of all partitioned tables in - * the tree. This value is used to continue the search in the next level - * of the partition tree. - */ - pd->indexes = (int *) palloc(partdesc->nparts * sizeof(int)); - for (i = 0; i < partdesc->nparts; i++) - { - Oid partrelid = partdesc->oids[i]; + partoid = RelationGetRelid(resultRelInfo->ri_RelationDesc); - if (get_rel_relkind(partrelid) != RELKIND_PARTITIONED_TABLE) - { - *leaf_part_oids = lappend_oid(*leaf_part_oids, partrelid); - pd->indexes[i] = list_length(*leaf_part_oids) - 1; + (void) hash_search(htab, &partoid, HASH_FIND, &found); + if (found) + continue; } - else - { - /* - * We assume all tables in the partition tree were already locked - * by the caller. - */ - Relation partrel = heap_open(partrelid, NoLock); - pd->indexes[i] = -list_length(*pds); - get_partition_dispatch_recurse(partrel, rel, pds, leaf_part_oids); - } + ExecCloseIndices(resultRelInfo); + table_close(resultRelInfo->ri_RelationDesc, NoLock); } } @@ -1133,7 +1208,7 @@ FormPartitionKeyDatum(PartitionDispatch pd, datum = ExecEvalExprSwitchContext((ExprState *) lfirst(partexpr_item), GetPerTupleExprContext(estate), &isNull); - partexpr_item = lnext(partexpr_item); + partexpr_item = lnext(pd->keystate, partexpr_item); } values[i] = datum; isnull[i] = isNull; @@ -1143,6 +1218,114 @@ FormPartitionKeyDatum(PartitionDispatch pd, elog(ERROR, "wrong number of partition key expressions"); } +/* + * get_partition_for_tuple + * Finds partition of relation which accepts the partition key specified + * in values and isnull + * + * Return value is index of the partition (>= 0 and < partdesc->nparts) if one + * found or -1 if none found. + */ +static int +get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull) +{ + int bound_offset; + int part_index = -1; + PartitionKey key = pd->key; + PartitionDesc partdesc = pd->partdesc; + PartitionBoundInfo boundinfo = partdesc->boundinfo; + + /* Route as appropriate based on partitioning strategy. */ + switch (key->strategy) + { + case PARTITION_STRATEGY_HASH: + { + int greatest_modulus; + uint64 rowHash; + + greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); + rowHash = compute_partition_hash_value(key->partnatts, + key->partsupfunc, + key->partcollation, + values, isnull); + + part_index = boundinfo->indexes[rowHash % greatest_modulus]; + } + break; + + case PARTITION_STRATEGY_LIST: + if (isnull[0]) + { + if (partition_bound_accepts_nulls(boundinfo)) + part_index = boundinfo->null_index; + } + else + { + bool equal = false; + + bound_offset = partition_list_bsearch(key->partsupfunc, + key->partcollation, + boundinfo, + values[0], &equal); + if (bound_offset >= 0 && equal) + part_index = boundinfo->indexes[bound_offset]; + } + break; + + case PARTITION_STRATEGY_RANGE: + { + bool equal = false, + range_partkey_has_null = false; + int i; + + /* + * No range includes NULL, so this will be accepted by the + * default partition if there is one, and otherwise rejected. + */ + for (i = 0; i < key->partnatts; i++) + { + if (isnull[i]) + { + range_partkey_has_null = true; + break; + } + } + + if (!range_partkey_has_null) + { + bound_offset = partition_range_datum_bsearch(key->partsupfunc, + key->partcollation, + boundinfo, + key->partnatts, + values, + &equal); + + /* + * The bound at bound_offset is less than or equal to the + * tuple value, so the bound at offset+1 is the upper + * bound of the partition we're looking for, if there + * actually exists one. + */ + part_index = boundinfo->indexes[bound_offset + 1]; + } + } + break; + + default: + elog(ERROR, "unexpected partition strategy: %d", + (int) key->strategy); + } + + /* + * part_index < 0 means we failed to find a partition of this parent. Use + * the default partition, if there is one. + */ + if (part_index < 0) + part_index = boundinfo->default_index; + + return part_index; +} + /* * ExecBuildSlotPartitionKeyDescription * @@ -1217,7 +1400,7 @@ ExecBuildSlotPartitionKeyDescription(Relation rel, /* truncate if needed */ vallen = strlen(val); if (vallen <= maxfieldlen) - appendStringInfoString(&buf, val); + appendBinaryStringInfo(&buf, val, vallen); else { vallen = pg_mbcliplen(val, vallen, maxfieldlen); @@ -1302,97 +1485,108 @@ adjust_partition_tlist(List *tlist, TupleConversionMap *map) * Run-Time Partition Pruning Support. * * The following series of functions exist to support the removal of unneeded - * subnodes for queries against partitioned tables. The supporting functions - * here are designed to work with any node type which supports an arbitrary - * number of subnodes, e.g. Append, MergeAppend. + * subplans for queries against partitioned tables. The supporting functions + * here are designed to work with any plan type which supports an arbitrary + * number of subplans, e.g. Append, MergeAppend. * - * Normally this pruning work is performed by the query planner's partition - * pruning code, however, the planner is limited to only being able to prune - * away unneeded partitions using quals which compare the partition key to a - * value which is known to be Const during planning. To allow the same - * pruning to be performed for values which are only determined during - * execution, we must make an additional pruning attempt during execution. + * When pruning involves comparison of a partition key to a constant, it's + * done by the planner. However, if we have a comparison to a non-constant + * but not volatile expression, that presents an opportunity for run-time + * pruning by the executor, allowing irrelevant partitions to be skipped + * dynamically. * - * Here we support pruning using both external and exec Params. The main - * difference between these that we need to concern ourselves with is the - * time when the values of the Params are known. External Param values are - * known at any time of execution, including executor startup, but exec Param - * values are only known when the executor is running. + * We must distinguish expressions containing PARAM_EXEC Params from + * expressions that don't contain those. Even though a PARAM_EXEC Param is + * considered to be a stable expression, it can change value from one plan + * node scan to the next during query execution. Stable comparison + * expressions that don't involve such Params allow partition pruning to be + * done once during executor startup. Expressions that do involve such Params + * require us to prune separately for each scan of the parent plan node. * - * For external Params we may be able to prune away unneeded partitions - * during executor startup. This has the added benefit of not having to - * initialize the unneeded subnodes at all. This is useful as it can save - * quite a bit of effort during executor startup. + * Note that pruning away unneeded subplans during executor startup has the + * added benefit of not having to initialize the unneeded subplans at all. * - * For exec Params, we must delay pruning until the executor is running. * * Functions: * - * ExecSetupPartitionPruneState: - * This must be called by nodes before any partition pruning is - * attempted. Normally executor startup is a good time. This function - * creates the PartitionPruneState details which are required by each - * of the two pruning functions, details include information about - * how to map the partition index details which are returned by the - * planner's partition prune function into subnode indexes. + * ExecCreatePartitionPruneState: + * Creates the PartitionPruneState required by each of the two pruning + * functions. Details stored include how to map the partition index + * returned by the partition pruning code into subplan indexes. * * ExecFindInitialMatchingSubPlans: - * Returns indexes of matching subnodes utilizing only external Params - * to eliminate subnodes. The function must only be called during - * executor startup for the given node before the subnodes themselves - * are initialized. Subnodes which are found not to match by this - * function must not be included in the node's list of subnodes as this - * function performs a remap of the partition index to subplan index map - * and the newly created map provides indexes only for subnodes which - * remain after calling this function. + * Returns indexes of matching subplans. Partition pruning is attempted + * without any evaluation of expressions containing PARAM_EXEC Params. + * This function must be called during executor startup for the parent + * plan before the subplans themselves are initialized. Subplans which + * are found not to match by this function must be removed from the + * plan's list of subplans during execution, as this function performs a + * remap of the partition index to subplan index map and the newly + * created map provides indexes only for subplans which remain after + * calling this function. * * ExecFindMatchingSubPlans: - * Returns indexes of matching subnodes utilizing all Params to eliminate - * subnodes which can't possibly contain matching tuples. This function - * can only be called while the executor is running. + * Returns indexes of matching subplans after evaluating all available + * expressions. This function can only be called during execution and + * must be called again each time the value of a Param listed in + * PartitionPruneState's 'execparamids' changes. *------------------------------------------------------------------------- */ /* - * ExecSetupPartitionPruneState - * Setup the required data structure which is required for calling + * ExecCreatePartitionPruneState + * Build the data structure required for calling * ExecFindInitialMatchingSubPlans and ExecFindMatchingSubPlans. * - * 'partitionpruneinfo' is a List of PartitionPruneInfos as generated by - * make_partition_pruneinfo. Here we build a PartitionPruneContext for each - * item in the List. These contexts can be re-used each time we re-evaulate - * which partitions match the pruning steps provided in each - * PartitionPruneInfo. + * 'planstate' is the parent plan node's execution state. + * + * 'partitionpruneinfo' is a PartitionPruneInfo as generated by + * make_partition_pruneinfo. Here we build a PartitionPruneState containing a + * PartitionPruningData for each partitioning hierarchy (i.e., each sublist of + * partitionpruneinfo->prune_infos), each of which contains a + * PartitionedRelPruningData for each PartitionedRelPruneInfo appearing in + * that sublist. This two-level system is needed to keep from confusing the + * different hierarchies when a UNION ALL contains multiple partitioned tables + * as children. The data stored in each PartitionedRelPruningData can be + * re-used each time we re-evaluate which partitions match the pruning steps + * provided in each PartitionedRelPruneInfo. */ PartitionPruneState * -ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo) +ExecCreatePartitionPruneState(PlanState *planstate, + PartitionPruneInfo *partitionpruneinfo) { - PartitionPruningData *prunedata; + EState *estate = planstate->state; PartitionPruneState *prunestate; + int n_part_hierarchies; ListCell *lc; int i; - Assert(partitionpruneinfo != NIL); + if (estate->es_partition_directory == NULL) + estate->es_partition_directory = + CreatePartitionDirectory(estate->es_query_cxt); - prunestate = (PartitionPruneState *) palloc(sizeof(PartitionPruneState)); - prunedata = (PartitionPruningData *) - palloc(sizeof(PartitionPruningData) * list_length(partitionpruneinfo)); + n_part_hierarchies = list_length(partitionpruneinfo->prune_infos); + Assert(n_part_hierarchies > 0); /* - * The first item in the array contains the details for the query's target - * partition, so record that as the root of the partition hierarchy. + * Allocate the data structure */ - prunestate->partprunedata = prunedata; - prunestate->num_partprunedata = list_length(partitionpruneinfo); - prunestate->extparams = NULL; - prunestate->execparams = NULL; + prunestate = (PartitionPruneState *) + palloc(offsetof(PartitionPruneState, partprunedata) + + sizeof(PartitionPruningData *) * n_part_hierarchies); + + prunestate->execparamids = NULL; + /* other_subplans can change at runtime, so we need our own copy */ + prunestate->other_subplans = bms_copy(partitionpruneinfo->other_subplans); + prunestate->do_initial_prune = false; /* may be set below */ + prunestate->do_exec_prune = false; /* may be set below */ + prunestate->num_partprunedata = n_part_hierarchies; /* - * Create a sub memory context which we'll use when making calls to the - * query planner's function to determine which partitions will match. The - * planner is not too careful about freeing memory, so we'll ensure we - * call the function in this context to avoid any memory leaking in the - * executor's memory context. + * Create a short-term memory context which we'll use when making calls to + * the partition pruning functions. This avoids possible memory leaks, + * since the pruning functions call comparison functions that aren't under + * our control. */ prunestate->prune_context = AllocSetContextCreate(CurrentMemoryContext, @@ -1400,209 +1594,381 @@ ExecSetupPartitionPruneState(PlanState *planstate, List *partitionpruneinfo) ALLOCSET_DEFAULT_SIZES); i = 0; - foreach(lc, partitionpruneinfo) + foreach(lc, partitionpruneinfo->prune_infos) { - PartitionPruneInfo *pinfo = (PartitionPruneInfo *) lfirst(lc); - PartitionPruningData *pprune = &prunedata[i]; - PartitionPruneContext *context = &pprune->context; - PartitionDesc partdesc; - Relation rel; - PartitionKey partkey; - int partnatts; + List *partrelpruneinfos = lfirst_node(List, lc); + int npartrelpruneinfos = list_length(partrelpruneinfos); + PartitionPruningData *prunedata; + ListCell *lc2; + int j; + + prunedata = (PartitionPruningData *) + palloc(offsetof(PartitionPruningData, partrelprunedata) + + npartrelpruneinfos * sizeof(PartitionedRelPruningData)); + prunestate->partprunedata[i] = prunedata; + prunedata->num_partrelprunedata = npartrelpruneinfos; + + j = 0; + foreach(lc2, partrelpruneinfos) + { + PartitionedRelPruneInfo *pinfo = lfirst_node(PartitionedRelPruneInfo, lc2); + PartitionedRelPruningData *pprune = &prunedata->partrelprunedata[j]; + Relation partrel; + PartitionDesc partdesc; + PartitionKey partkey; - pprune->present_parts = bms_copy(pinfo->present_parts); - pprune->subnode_map = palloc(sizeof(int) * pinfo->nparts); + /* + * We can rely on the copies of the partitioned table's partition + * key and partition descriptor appearing in its relcache entry, + * because that entry will be held open and locked for the + * duration of this executor run. + */ + partrel = ExecGetRangeTableRelation(estate, pinfo->rtindex); + partkey = RelationGetPartitionKey(partrel); + partdesc = PartitionDirectoryLookup(estate->es_partition_directory, + partrel); - /* - * We must make a copy of this rather than pointing directly to the - * plan's version as we may end up making modifications to it later. - */ - memcpy(pprune->subnode_map, pinfo->subnode_map, - sizeof(int) * pinfo->nparts); + /* + * Initialize the subplan_map and subpart_map. Since detaching a + * partition requires AccessExclusiveLock, no partitions can have + * disappeared, nor can the bounds for any partition have changed. + * However, new partitions may have been added. + */ + Assert(partdesc->nparts >= pinfo->nparts); + pprune->nparts = partdesc->nparts; + pprune->subplan_map = palloc(sizeof(int) * partdesc->nparts); + if (partdesc->nparts == pinfo->nparts) + { + /* + * There are no new partitions, so this is simple. We can + * simply point to the subpart_map from the plan, but we must + * copy the subplan_map since we may change it later. + */ + pprune->subpart_map = pinfo->subpart_map; + memcpy(pprune->subplan_map, pinfo->subplan_map, + sizeof(int) * pinfo->nparts); - /* We can use the subpart_map verbatim, since we never modify it */ - pprune->subpart_map = pinfo->subpart_map; + /* + * Double-check that the list of unpruned relations has not + * changed. (Pruned partitions are not in relid_map[].) + */ +#ifdef USE_ASSERT_CHECKING + for (int k = 0; k < pinfo->nparts; k++) + { + Assert(partdesc->oids[k] == pinfo->relid_map[k] || + pinfo->subplan_map[k] == -1); + } +#endif + } + else + { + int pd_idx = 0; + int pp_idx; - /* - * Grab some info from the table's relcache; lock was already obtained - * by ExecLockNonLeafAppendTables. - */ - rel = relation_open(pinfo->reloid, NoLock); - - partkey = RelationGetPartitionKey(rel); - partdesc = RelationGetPartitionDesc(rel); - - context->strategy = partkey->strategy; - context->partnatts = partnatts = partkey->partnatts; - context->partopfamily = partkey->partopfamily; - context->partopcintype = partkey->partopcintype; - context->partcollation = partkey->partcollation; - context->partsupfunc = partkey->partsupfunc; - context->nparts = pinfo->nparts; - context->boundinfo = partition_bounds_copy(partdesc->boundinfo, partkey); - context->planstate = planstate; - context->safeparams = NULL; /* empty for now */ - - pprune->pruning_steps = pinfo->pruning_steps; - pprune->extparams = bms_copy(pinfo->extparams); - pprune->allparams = bms_union(pinfo->extparams, pinfo->execparams); + /* + * Some new partitions have appeared since plan time, and + * those are reflected in our PartitionDesc but were not + * present in the one used to construct subplan_map and + * subpart_map. So we must construct new and longer arrays + * where the partitions that were originally present map to + * the same place, and any added indexes map to -1, as if the + * new partitions had been pruned. + */ + pprune->subpart_map = palloc(sizeof(int) * partdesc->nparts); + for (pp_idx = 0; pp_idx < partdesc->nparts; ++pp_idx) + { + if (pinfo->relid_map[pd_idx] != partdesc->oids[pp_idx]) + { + pprune->subplan_map[pp_idx] = -1; + pprune->subpart_map[pp_idx] = -1; + } + else + { + pprune->subplan_map[pp_idx] = + pinfo->subplan_map[pd_idx]; + pprune->subpart_map[pp_idx] = + pinfo->subpart_map[pd_idx++]; + } + } + Assert(pd_idx == pinfo->nparts); + } - /* - * Accumulate the paramids which match the partitioned keys of all - * partitioned tables. - */ - prunestate->extparams = bms_add_members(prunestate->extparams, - pinfo->extparams); + /* present_parts is also subject to later modification */ + pprune->present_parts = bms_copy(pinfo->present_parts); - prunestate->execparams = bms_add_members(prunestate->execparams, - pinfo->execparams); + /* + * Initialize pruning contexts as needed. + */ + pprune->initial_pruning_steps = pinfo->initial_pruning_steps; + if (pinfo->initial_pruning_steps) + { + ExecInitPruningContext(&pprune->initial_context, + pinfo->initial_pruning_steps, + partdesc, partkey, planstate); + /* Record whether initial pruning is needed at any level */ + prunestate->do_initial_prune = true; + } + pprune->exec_pruning_steps = pinfo->exec_pruning_steps; + if (pinfo->exec_pruning_steps) + { + ExecInitPruningContext(&pprune->exec_context, + pinfo->exec_pruning_steps, + partdesc, partkey, planstate); + /* Record whether exec pruning is needed at any level */ + prunestate->do_exec_prune = true; + } - relation_close(rel, NoLock); + /* + * Accumulate the IDs of all PARAM_EXEC Params affecting the + * partitioning decisions at this plan node. + */ + prunestate->execparamids = bms_add_members(prunestate->execparamids, + pinfo->execparamids); + j++; + } i++; } - /* - * Cache the union of the paramids of both types. This saves having to - * recalculate it everytime we need to know what they are. - */ - prunestate->allparams = bms_union(prunestate->extparams, - prunestate->execparams); - return prunestate; } +/* + * Initialize a PartitionPruneContext for the given list of pruning steps. + */ +static void +ExecInitPruningContext(PartitionPruneContext *context, + List *pruning_steps, + PartitionDesc partdesc, + PartitionKey partkey, + PlanState *planstate) +{ + int n_steps; + int partnatts; + ListCell *lc; + + n_steps = list_length(pruning_steps); + + context->strategy = partkey->strategy; + context->partnatts = partnatts = partkey->partnatts; + context->nparts = partdesc->nparts; + context->boundinfo = partdesc->boundinfo; + context->partcollation = partkey->partcollation; + context->partsupfunc = partkey->partsupfunc; + + /* We'll look up type-specific support functions as needed */ + context->stepcmpfuncs = (FmgrInfo *) + palloc0(sizeof(FmgrInfo) * n_steps * partnatts); + + context->ppccontext = CurrentMemoryContext; + context->planstate = planstate; + + /* Initialize expression state for each expression we need */ + context->exprstates = (ExprState **) + palloc0(sizeof(ExprState *) * n_steps * partnatts); + foreach(lc, pruning_steps) + { + PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc); + ListCell *lc2; + int keyno; + + /* not needed for other step kinds */ + if (!IsA(step, PartitionPruneStepOp)) + continue; + + Assert(list_length(step->exprs) <= partnatts); + + keyno = 0; + foreach(lc2, step->exprs) + { + Expr *expr = (Expr *) lfirst(lc2); + + /* not needed for Consts */ + if (!IsA(expr, Const)) + { + int stateidx = PruneCxtStateIdx(partnatts, + step->step.step_id, + keyno); + + context->exprstates[stateidx] = + ExecInitExpr(expr, context->planstate); + } + keyno++; + } + } +} + /* * ExecFindInitialMatchingSubPlans - * Determine which subset of subplan nodes we need to initialize based - * on the details stored in 'prunestate'. Here we only determine the - * matching partitions using values known during plan startup, which is - * only external Params. Exec Params will be unknown at this time. We - * must delay pruning using exec Params until the actual executor run. + * Identify the set of subplans that cannot be eliminated by initial + * pruning, disregarding any pruning constraints involving PARAM_EXEC + * Params. * - * It is expected that callers of this function do so only once during their - * init plan. The caller must only initialize the subnodes which are returned - * by this function. The remaining subnodes should be discarded. Once this - * function has been called, future calls to ExecFindMatchingSubPlans will - * return its matching subnode indexes assuming that the caller discarded - * the original non-matching subnodes. + * If additional pruning passes will be required (because of PARAM_EXEC + * Params), we must also update the translation data that allows conversion + * of partition indexes into subplan indexes to account for the unneeded + * subplans having been removed. * - * This function must only be called if 'prunestate' has any extparams. + * Must only be called once per 'prunestate', and only if initial pruning + * is required. * - * 'nsubnodes' must be passed as the total number of unpruned subnodes. + * 'nsubplans' must be passed as the total number of unpruned subplans. */ Bitmapset * -ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubnodes) +ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans) { - PartitionPruningData *pprune; - MemoryContext oldcontext; Bitmapset *result = NULL; + MemoryContext oldcontext; + int i; - /* - * Ensure there's actually external params, or we've not been called - * already. - */ - Assert(!bms_is_empty(prunestate->extparams)); - - pprune = prunestate->partprunedata; + /* Caller error if we get here without do_initial_prune */ + Assert(prunestate->do_initial_prune); /* * Switch to a temp context to avoid leaking memory in the executor's - * memory context. + * query-lifespan memory context. */ oldcontext = MemoryContextSwitchTo(prunestate->prune_context); - /* Determine which subnodes match the external params */ - find_subplans_for_params_recurse(prunestate, pprune, false, &result); + /* + * For each hierarchy, do the pruning tests, and add nondeletable + * subplans' indexes to "result". + */ + for (i = 0; i < prunestate->num_partprunedata; i++) + { + PartitionPruningData *prunedata; + PartitionedRelPruningData *pprune; + + prunedata = prunestate->partprunedata[i]; + pprune = &prunedata->partrelprunedata[0]; + + /* Perform pruning without using PARAM_EXEC Params */ + find_matching_subplans_recurse(prunedata, pprune, true, &result); + + /* Expression eval may have used space in node's ps_ExprContext too */ + if (pprune->initial_pruning_steps) + ResetExprContext(pprune->initial_context.planstate->ps_ExprContext); + } + + /* Add in any subplans that partition pruning didn't account for */ + result = bms_add_members(result, prunestate->other_subplans); MemoryContextSwitchTo(oldcontext); - /* Move to the correct memory context */ + /* Copy result out of the temp context before we reset it */ result = bms_copy(result); MemoryContextReset(prunestate->prune_context); /* - * Record that partition pruning has been performed for external params. - * These are not required again afterwards, and nullifying them helps - * ensure nothing accidentally calls this function twice on the same - * PartitionPruneState. + * If exec-time pruning is required and we pruned subplans above, then we + * must re-sequence the subplan indexes so that ExecFindMatchingSubPlans + * properly returns the indexes from the subplans which will remain after + * execution of this function. * - * (Note we keep prunestate->allparams, because we do use that one - * repeatedly in ExecFindMatchingSubPlans). + * We can safely skip this when !do_exec_prune, even though that leaves + * invalid data in prunestate, because that data won't be consulted again + * (cf initial Assert in ExecFindMatchingSubPlans). */ - bms_free(prunestate->extparams); - prunestate->extparams = NULL; - - /* - * If any subnodes were pruned, we must re-sequence the subnode indexes so - * that ExecFindMatchingSubPlans properly returns the indexes from the - * subnodes which will remain after execution of this function. - */ - if (bms_num_members(result) < nsubnodes) + if (prunestate->do_exec_prune && bms_num_members(result) < nsubplans) { - int *new_subnode_indexes; + int *new_subplan_indexes; + Bitmapset *new_other_subplans; int i; int newidx; /* - * First we must build an array which we can use to adjust the - * existing subnode_map so that it contains the new subnode indexes. + * First we must build a temporary array which maps old subplan + * indexes to new ones. For convenience of initialization, we use + * 1-based indexes in this array and leave pruned items as 0. */ - new_subnode_indexes = (int *) palloc(sizeof(int) * nsubnodes); - newidx = 0; - for (i = 0; i < nsubnodes; i++) + new_subplan_indexes = (int *) palloc0(sizeof(int) * nsubplans); + newidx = 1; + i = -1; + while ((i = bms_next_member(result, i)) >= 0) { - if (bms_is_member(i, result)) - new_subnode_indexes[i] = newidx++; - else - new_subnode_indexes[i] = -1; /* Newly pruned */ + Assert(i < nsubplans); + new_subplan_indexes[i] = newidx++; } /* - * Now we can re-sequence each PartitionPruneInfo's subnode_map so - * that they point to the new index of the subnode. + * Now we can update each PartitionedRelPruneInfo's subplan_map with + * new subplan indexes. We must also recompute its present_parts + * bitmap. */ for (i = 0; i < prunestate->num_partprunedata; i++) { - int nparts; + PartitionPruningData *prunedata = prunestate->partprunedata[i]; int j; - pprune = &prunestate->partprunedata[i]; - nparts = pprune->context.nparts; - /* - * We also need to reset the present_parts field so that it only - * contains partition indexes that we actually still have subnodes - * for. It seems easier to build a fresh one, rather than trying - * to update the existing one. + * Within each hierarchy, we perform this loop in back-to-front + * order so that we determine present_parts for the lowest-level + * partitioned tables first. This way we can tell whether a + * sub-partitioned table's partitions were entirely pruned so we + * can exclude it from the current level's present_parts. */ - bms_free(pprune->present_parts); - pprune->present_parts = NULL; - - for (j = 0; j < nparts; j++) + for (j = prunedata->num_partrelprunedata - 1; j >= 0; j--) { - int oldidx = pprune->subnode_map[j]; + PartitionedRelPruningData *pprune = &prunedata->partrelprunedata[j]; + int nparts = pprune->nparts; + int k; - /* - * If this partition existed as a subnode then change the old - * subnode index to the new subnode index. The new index may - * become -1 if the partition was pruned above, or it may just - * come earlier in the subnode list due to some subnodes being - * removed earlier in the list. - */ - if (oldidx >= 0) - { - pprune->subnode_map[j] = new_subnode_indexes[oldidx]; + /* We just rebuild present_parts from scratch */ + bms_free(pprune->present_parts); + pprune->present_parts = NULL; - if (new_subnode_indexes[oldidx] >= 0) - pprune->present_parts = - bms_add_member(pprune->present_parts, j); + for (k = 0; k < nparts; k++) + { + int oldidx = pprune->subplan_map[k]; + int subidx; + + /* + * If this partition existed as a subplan then change the + * old subplan index to the new subplan index. The new + * index may become -1 if the partition was pruned above, + * or it may just come earlier in the subplan list due to + * some subplans being removed earlier in the list. If + * it's a subpartition, add it to present_parts unless + * it's entirely pruned. + */ + if (oldidx >= 0) + { + Assert(oldidx < nsubplans); + pprune->subplan_map[k] = new_subplan_indexes[oldidx] - 1; + + if (new_subplan_indexes[oldidx] > 0) + pprune->present_parts = + bms_add_member(pprune->present_parts, k); + } + else if ((subidx = pprune->subpart_map[k]) >= 0) + { + PartitionedRelPruningData *subprune; + + subprune = &prunedata->partrelprunedata[subidx]; + + if (!bms_is_empty(subprune->present_parts)) + pprune->present_parts = + bms_add_member(pprune->present_parts, k); + } } } } - pfree(new_subnode_indexes); + /* + * We must also recompute the other_subplans set, since indexes in it + * may change. + */ + new_other_subplans = NULL; + i = -1; + while ((i = bms_next_member(prunestate->other_subplans, i)) >= 0) + new_other_subplans = bms_add_member(new_other_subplans, + new_subplan_indexes[i] - 1); + + bms_free(prunestate->other_subplans); + prunestate->other_subplans = new_other_subplans; + + pfree(new_subplan_indexes); } return result; @@ -1611,30 +1977,55 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubnodes) /* * ExecFindMatchingSubPlans * Determine which subplans match the pruning steps detailed in - * 'pprune' for the current Param values. + * 'prunestate' for the current comparison expression values. * - * Here we utilize both external and exec Params for pruning. + * Here we assume we may evaluate PARAM_EXEC Params. */ Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate) { - PartitionPruningData *pprune; - MemoryContext oldcontext; Bitmapset *result = NULL; + MemoryContext oldcontext; + int i; - pprune = prunestate->partprunedata; + /* + * If !do_exec_prune, we've got problems because + * ExecFindInitialMatchingSubPlans will not have bothered to update + * prunestate for whatever pruning it did. + */ + Assert(prunestate->do_exec_prune); /* * Switch to a temp context to avoid leaking memory in the executor's - * memory context. + * query-lifespan memory context. */ oldcontext = MemoryContextSwitchTo(prunestate->prune_context); - find_subplans_for_params_recurse(prunestate, pprune, true, &result); + /* + * For each hierarchy, do the pruning tests, and add nondeletable + * subplans' indexes to "result". + */ + for (i = 0; i < prunestate->num_partprunedata; i++) + { + PartitionPruningData *prunedata; + PartitionedRelPruningData *pprune; + + prunedata = prunestate->partprunedata[i]; + pprune = &prunedata->partrelprunedata[0]; + + find_matching_subplans_recurse(prunedata, pprune, false, &result); + + /* Expression eval may have used space in node's ps_ExprContext too */ + if (pprune->exec_pruning_steps) + ResetExprContext(pprune->exec_context.planstate->ps_ExprContext); + } + + /* Add in any subplans that partition pruning didn't account for */ + result = bms_add_members(result, prunestate->other_subplans); MemoryContextSwitchTo(oldcontext); - /* Move to the correct memory context */ + /* Copy result out of the temp context before we reset it */ result = bms_copy(result); MemoryContextReset(prunestate->prune_context); @@ -1643,74 +2034,68 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate) } /* - * find_subplans_for_params_recurse + * find_matching_subplans_recurse * Recursive worker function for ExecFindMatchingSubPlans and * ExecFindInitialMatchingSubPlans + * + * Adds valid (non-prunable) subplan IDs to *validsubplans */ static void -find_subplans_for_params_recurse(PartitionPruneState *prunestate, - PartitionPruningData *pprune, - bool allparams, - Bitmapset **validsubplans) +find_matching_subplans_recurse(PartitionPruningData *prunedata, + PartitionedRelPruningData *pprune, + bool initial_prune, + Bitmapset **validsubplans) { - PartitionPruneContext *context = &pprune->context; Bitmapset *partset; - Bitmapset *pruneparams; int i; /* Guard against stack overflow due to overly deep partition hierarchy. */ check_stack_depth(); - /* - * Use only external params unless we've been asked to also use exec - * params too. - */ - if (allparams) - pruneparams = pprune->allparams; - else - pruneparams = pprune->extparams; - - /* - * We only need to determine the matching partitions if there are any - * params matching the partition key at this level. If there are no - * matching params, then we can simply return all subnodes which belong to - * this parent partition. The planner should have already determined - * these to be the minimum possible set. We must still recursively visit - * any subpartitioned tables as we may find their partition keys match - * some Params at their level. - */ - if (!bms_is_empty(pruneparams)) + /* Only prune if pruning would be useful at this level. */ + if (initial_prune && pprune->initial_pruning_steps) + { + partset = get_matching_partitions(&pprune->initial_context, + pprune->initial_pruning_steps); + } + else if (!initial_prune && pprune->exec_pruning_steps) { - context->safeparams = pruneparams; - partset = get_matching_partitions(context, - pprune->pruning_steps); + partset = get_matching_partitions(&pprune->exec_context, + pprune->exec_pruning_steps); } else + { + /* + * If no pruning is to be done, just include all partitions at this + * level. + */ partset = pprune->present_parts; + } - /* Translate partset into subnode indexes */ + /* Translate partset into subplan indexes */ i = -1; while ((i = bms_next_member(partset, i)) >= 0) { - if (pprune->subnode_map[i] >= 0) + if (pprune->subplan_map[i] >= 0) *validsubplans = bms_add_member(*validsubplans, - pprune->subnode_map[i]); + pprune->subplan_map[i]); else { int partidx = pprune->subpart_map[i]; - if (partidx != -1) - find_subplans_for_params_recurse(prunestate, - &prunestate->partprunedata[partidx], - allparams, validsubplans); + if (partidx >= 0) + find_matching_subplans_recurse(prunedata, + &prunedata->partrelprunedata[partidx], + initial_prune, validsubplans); else { /* - * This could only happen if clauses used in planning where - * more restrictive than those used here, or if the maps are - * somehow corrupt. + * We get here if the planner already pruned all the sub- + * partitions for this partition. Silently ignore this + * partition in this case. The end result is the same: we + * would have pruned all partitions just the same, but we + * don't have any pruning steps to execute to verify this. */ - elog(ERROR, "partition missing from subplans"); } } } diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c index a3fb4495d22..c227282975a 100644 --- a/src/backend/executor/execProcnode.c +++ b/src/backend/executor/execProcnode.c @@ -7,7 +7,7 @@ * ExecProcNode, or ExecEndNode on its subnodes and do the appropriate * processing. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -407,10 +407,9 @@ ExecSetExecProcNode(PlanState *node, ExecProcNodeMtd function) { /* * Add a wrapper around the ExecProcNode callback that checks stack depth - * during the first execution and maybe adds an instrumentation - * wrapper. When the callback is changed after execution has already begun - * that means we'll superfluously execute ExecProcNodeFirst, but that seems - * ok. + * during the first execution and maybe adds an instrumentation wrapper. + * When the callback is changed after execution has already begun that + * means we'll superfluously execute ExecProcNodeFirst, but that seems ok. */ node->ExecProcNodeReal = function; node->ExecProcNode = ExecProcNodeFirst; @@ -737,11 +736,7 @@ ExecEndNode(PlanState *node) * ExecShutdownNode * * Give execution nodes a chance to stop asynchronous resource consumption - * and release any resources still held. Currently, this is only used for - * parallel query, but we might want to extend it to other cases also (e.g. - * FDW). We might also want to call it sooner, as soon as it's evident that - * no more rows will be needed (e.g. when a Limit is filled) rather than only - * at the end of ExecutorRun. + * and release any resources still held. */ bool ExecShutdownNode(PlanState *node) @@ -753,6 +748,19 @@ ExecShutdownNode(PlanState *node) planstate_tree_walker(node, ExecShutdownNode, NULL); + /* + * Treat the node as running while we shut it down, but only if it's run + * at least once already. We don't expect much CPU consumption during + * node shutdown, but in the case of Gather or Gather Merge, we may shut + * down workers at this stage. If so, their buffer usage will get + * propagated into pgBufferUsage at this point, and we want to make sure + * that it gets associated with the Gather node. We skip this if the node + * has never been executed, so as to avoid incorrectly making it appear + * that it has. + */ + if (node->instrument && node->instrument->running) + InstrStartNode(node->instrument); + switch (nodeTag(node)) { case T_GatherState: @@ -777,6 +785,10 @@ ExecShutdownNode(PlanState *node) break; } + /* Stop the node if we started it above, reporting 0 tuples. */ + if (node->instrument && node->instrument->running) + InstrStopNode(node->instrument, 0); + return false; } @@ -828,6 +840,19 @@ ExecSetTupleBound(int64 tuples_needed, PlanState *child_node) sortState->bound = tuples_needed; } } + else if (IsA(child_node, AppendState)) + { + /* + * If it is an Append, we can apply the bound to any nodes that are + * children of the Append, since the Append surely need read no more + * than that many tuples from any one input. + */ + AppendState *aState = (AppendState *) child_node; + int i; + + for (i = 0; i < aState->as_nplans; i++) + ExecSetTupleBound(tuples_needed, aState->appendplans[i]); + } else if (IsA(child_node, MergeAppendState)) { /* diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index b66346702dc..95e027c970b 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -3,7 +3,7 @@ * execReplication.c * miscellaneous executor routines for logical replication * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,11 +14,14 @@ #include "postgres.h" +#include "access/genam.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "commands/trigger.h" #include "executor/executor.h" +#include "executor/nodeModifyTable.h" #include "nodes/nodeFuncs.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" @@ -32,7 +35,6 @@ #include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/typcache.h" -#include "utils/tqual.h" /* @@ -94,6 +96,8 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel, regop, searchslot->tts_values[mainattno - 1]); + skey[attoff].sk_collation = idxrel->rd_indcollation[attoff]; + /* Check for null value. */ if (searchslot->tts_isnull[mainattno - 1]) { @@ -117,7 +121,6 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid, TupleTableSlot *searchslot, TupleTableSlot *outslot) { - HeapTuple scantuple; ScanKeyData skey[INDEX_MAX_KEYS]; IndexScanDesc scan; SnapshotData snap; @@ -143,10 +146,9 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid, index_rescan(scan, skey, IndexRelationGetNumberOfKeyAttributes(idxrel), NULL, 0); /* Try to find the tuple */ - if ((scantuple = index_getnext(scan, ForwardScanDirection)) != NULL) + if (index_getnext_slot(scan, ForwardScanDirection, outslot)) { found = true; - ExecStoreTuple(scantuple, outslot, InvalidBuffer, false); ExecMaterializeSlot(outslot); xwait = TransactionIdIsValid(snap.xmin) ? @@ -166,32 +168,28 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid, /* Found tuple, try to lock it in the lockmode. */ if (found) { - Buffer buf; - HeapUpdateFailureData hufd; - HTSU_Result res; - HeapTupleData locktup; - - ItemPointerCopy(&outslot->tts_tuple->t_self, &locktup.t_self); + TM_FailureData tmfd; + TM_Result res; PushActiveSnapshot(GetLatestSnapshot()); - res = heap_lock_tuple(rel, &locktup, GetCurrentCommandId(false), - lockmode, - LockWaitBlock, - false /* don't follow updates */ , - &buf, &hufd); - /* the tuple slot already has the buffer pinned */ - ReleaseBuffer(buf); + res = table_tuple_lock(rel, &(outslot->tts_tid), GetLatestSnapshot(), + outslot, + GetCurrentCommandId(false), + lockmode, + LockWaitBlock, + 0 /* don't follow updates */ , + &tmfd); PopActiveSnapshot(); switch (res) { - case HeapTupleMayBeUpdated: + case TM_Ok: break; - case HeapTupleUpdated: + case TM_Updated: /* XXX: Improve handling here */ - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) + if (ItemPointerIndicatesMovedPartitions(&tmfd.ctid)) ereport(LOG, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("tuple to be locked was already moved to another partition due to concurrent update, retrying"))); @@ -200,10 +198,17 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("concurrent update, retrying"))); goto retry; - case HeapTupleInvisible: + case TM_Deleted: + /* XXX: Improve handling here */ + ereport(LOG, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("concurrent delete, retrying"))); + goto retry; + case TM_Invisible: elog(ERROR, "attempted to lock invisible tuple"); + break; default: - elog(ERROR, "unexpected heap_lock_tuple status: %u", res); + elog(ERROR, "unexpected table_tuple_lock status: %u", res); break; } } @@ -217,24 +222,21 @@ RelationFindReplTupleByIndex(Relation rel, Oid idxoid, } /* - * Compare the tuple and slot and check if they have equal values. - * - * We use binary datum comparison which might return false negatives but - * that's the best we can do here as there may be multiple notions of - * equality for the data types and table columns don't specify which one - * to use. + * Compare the tuples in the slots by checking if they have equal values. */ static bool -tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot) +tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2) { - Datum values[MaxTupleAttributeNumber]; - bool isnull[MaxTupleAttributeNumber]; int attrnum; - heap_deform_tuple(tup, desc, values, isnull); + Assert(slot1->tts_tupleDescriptor->natts == + slot2->tts_tupleDescriptor->natts); + + slot_getallattrs(slot1); + slot_getallattrs(slot2); /* Check equality of the attributes. */ - for (attrnum = 0; attrnum < desc->natts; attrnum++) + for (attrnum = 0; attrnum < slot1->tts_tupleDescriptor->natts; attrnum++) { Form_pg_attribute att; TypeCacheEntry *typentry; @@ -243,16 +245,16 @@ tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot) * If one value is NULL and other is not, then they are certainly not * equal */ - if (isnull[attrnum] != slot->tts_isnull[attrnum]) + if (slot1->tts_isnull[attrnum] != slot2->tts_isnull[attrnum]) return false; /* * If both are NULL, they can be considered equal. */ - if (isnull[attrnum]) + if (slot1->tts_isnull[attrnum] || slot2->tts_isnull[attrnum]) continue; - att = TupleDescAttr(desc, attrnum); + att = TupleDescAttr(slot1->tts_tupleDescriptor, attrnum); typentry = lookup_type_cache(att->atttypid, TYPECACHE_EQ_OPR_FINFO); if (!OidIsValid(typentry->eq_opr_finfo.fn_oid)) @@ -261,9 +263,10 @@ tuple_equals_slot(TupleDesc desc, HeapTuple tup, TupleTableSlot *slot) errmsg("could not identify an equality operator for type %s", format_type_be(att->atttypid)))); - if (!DatumGetBool(FunctionCall2(&typentry->eq_opr_finfo, - values[attrnum], - slot->tts_values[attrnum]))) + if (!DatumGetBool(FunctionCall2Coll(&typentry->eq_opr_finfo, + att->attcollation, + slot1->tts_values[attrnum], + slot2->tts_values[attrnum]))) return false; } @@ -284,33 +287,33 @@ bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, TupleTableSlot *searchslot, TupleTableSlot *outslot) { - HeapTuple scantuple; - HeapScanDesc scan; + TupleTableSlot *scanslot; + TableScanDesc scan; SnapshotData snap; TransactionId xwait; bool found; - TupleDesc desc = RelationGetDescr(rel); + TupleDesc desc PG_USED_FOR_ASSERTS_ONLY = RelationGetDescr(rel); Assert(equalTupleDescs(desc, outslot->tts_tupleDescriptor)); /* Start a heap scan. */ InitDirtySnapshot(snap); - scan = heap_beginscan(rel, &snap, 0, NULL); + scan = table_beginscan(rel, &snap, 0, NULL); + scanslot = table_slot_create(rel, NULL); retry: found = false; - heap_rescan(scan, NULL); + table_rescan(scan, NULL); /* Try to find the tuple */ - while ((scantuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + while (table_scan_getnextslot(scan, ForwardScanDirection, scanslot)) { - if (!tuple_equals_slot(desc, scantuple, searchslot)) + if (!tuples_equal(scanslot, searchslot)) continue; found = true; - ExecStoreTuple(scantuple, outslot, InvalidBuffer, false); - ExecMaterializeSlot(outslot); + ExecCopySlot(outslot, scanslot); xwait = TransactionIdIsValid(snap.xmin) ? snap.xmin : snap.xmax; @@ -329,32 +332,28 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, /* Found tuple, try to lock it in the lockmode. */ if (found) { - Buffer buf; - HeapUpdateFailureData hufd; - HTSU_Result res; - HeapTupleData locktup; - - ItemPointerCopy(&outslot->tts_tuple->t_self, &locktup.t_self); + TM_FailureData tmfd; + TM_Result res; PushActiveSnapshot(GetLatestSnapshot()); - res = heap_lock_tuple(rel, &locktup, GetCurrentCommandId(false), - lockmode, - LockWaitBlock, - false /* don't follow updates */ , - &buf, &hufd); - /* the tuple slot already has the buffer pinned */ - ReleaseBuffer(buf); + res = table_tuple_lock(rel, &(outslot->tts_tid), GetLatestSnapshot(), + outslot, + GetCurrentCommandId(false), + lockmode, + LockWaitBlock, + 0 /* don't follow updates */ , + &tmfd); PopActiveSnapshot(); switch (res) { - case HeapTupleMayBeUpdated: + case TM_Ok: break; - case HeapTupleUpdated: + case TM_Updated: /* XXX: Improve handling here */ - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) + if (ItemPointerIndicatesMovedPartitions(&tmfd.ctid)) ereport(LOG, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("tuple to be locked was already moved to another partition due to concurrent update, retrying"))); @@ -363,15 +362,23 @@ RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("concurrent update, retrying"))); goto retry; - case HeapTupleInvisible: + case TM_Deleted: + /* XXX: Improve handling here */ + ereport(LOG, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("concurrent delete, retrying"))); + goto retry; + case TM_Invisible: elog(ERROR, "attempted to lock invisible tuple"); + break; default: - elog(ERROR, "unexpected heap_lock_tuple status: %u", res); + elog(ERROR, "unexpected table_tuple_lock status: %u", res); break; } } - heap_endscan(scan); + table_endscan(scan); + ExecDropSingleTupleTableSlot(scanslot); return found; } @@ -386,7 +393,6 @@ void ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot) { bool skip_tuple = false; - HeapTuple tuple; ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; @@ -399,33 +405,34 @@ ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot) if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_before_row) { - slot = ExecBRInsertTriggers(estate, resultRelInfo, slot); - - if (slot == NULL) /* "do nothing" */ - skip_tuple = true; + if (!ExecBRInsertTriggers(estate, resultRelInfo, slot)) + skip_tuple = true; /* "do nothing" */ } if (!skip_tuple) { List *recheckIndexes = NIL; + /* Compute stored generated columns */ + if (rel->rd_att->constr && + rel->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); + /* Check the constraints of the tuple */ if (rel->rd_att->constr) - ExecConstraints(resultRelInfo, slot, estate, true); - - /* Store the slot into tuple that we can inspect. */ - tuple = ExecMaterializeSlot(slot); + ExecConstraints(resultRelInfo, slot, estate); + if (resultRelInfo->ri_PartitionCheck) + ExecPartitionCheck(resultRelInfo, slot, estate, true); /* OK, store the tuple and create index entries for it */ - simple_heap_insert(rel, tuple); + simple_table_tuple_insert(resultRelInfo->ri_RelationDesc, slot); if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), - estate, false, NULL, + recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, NIL); /* AFTER ROW INSERT Triggers */ - ExecARInsertTriggers(estate, resultRelInfo, tuple, + ExecARInsertTriggers(estate, resultRelInfo, slot, recheckIndexes, NULL); /* @@ -449,9 +456,9 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, TupleTableSlot *searchslot, TupleTableSlot *slot) { bool skip_tuple = false; - HeapTuple tuple; ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; + ItemPointer tid = &(searchslot->tts_tid); /* For now we support only tables. */ Assert(rel->rd_rel->relkind == RELKIND_RELATION); @@ -462,39 +469,38 @@ ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_update_before_row) { - slot = ExecBRUpdateTriggers(estate, epqstate, resultRelInfo, - &searchslot->tts_tuple->t_self, - NULL, slot, NULL); - - if (slot == NULL) /* "do nothing" */ - skip_tuple = true; + if (!ExecBRUpdateTriggers(estate, epqstate, resultRelInfo, + tid, NULL, slot)) + skip_tuple = true; /* "do nothing" */ } if (!skip_tuple) { List *recheckIndexes = NIL; + bool update_indexes; + + /* Compute stored generated columns */ + if (rel->rd_att->constr && + rel->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); /* Check the constraints of the tuple */ if (rel->rd_att->constr) - ExecConstraints(resultRelInfo, slot, estate, true); - - /* Store the slot into tuple that we can write. */ - tuple = ExecMaterializeSlot(slot); + ExecConstraints(resultRelInfo, slot, estate); + if (resultRelInfo->ri_PartitionCheck) + ExecPartitionCheck(resultRelInfo, slot, estate, true); - /* OK, update the tuple and index entries for it */ - simple_heap_update(rel, &searchslot->tts_tuple->t_self, - slot->tts_tuple); + simple_table_tuple_update(rel, tid, slot, estate->es_snapshot, + &update_indexes); - if (resultRelInfo->ri_NumIndices > 0 && - !HeapTupleIsHeapOnly(slot->tts_tuple)) - recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), - estate, false, NULL, + if (resultRelInfo->ri_NumIndices > 0 && update_indexes) + recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, NIL); /* AFTER ROW UPDATE Triggers */ ExecARUpdateTriggers(estate, resultRelInfo, - &searchslot->tts_tuple->t_self, - NULL, tuple, recheckIndexes, NULL); + tid, NULL, slot, + recheckIndexes, NULL); list_free(recheckIndexes); } @@ -513,9 +519,7 @@ ExecSimpleRelationDelete(EState *estate, EPQState *epqstate, bool skip_tuple = false; ResultRelInfo *resultRelInfo = estate->es_result_relation_info; Relation rel = resultRelInfo->ri_RelationDesc; - - /* For now we support only tables. */ - Assert(rel->rd_rel->relkind == RELKIND_RELATION); + ItemPointer tid = &searchslot->tts_tid; CheckCmdReplicaIdentity(rel, CMD_DELETE); @@ -524,22 +528,18 @@ ExecSimpleRelationDelete(EState *estate, EPQState *epqstate, resultRelInfo->ri_TrigDesc->trig_delete_before_row) { skip_tuple = !ExecBRDeleteTriggers(estate, epqstate, resultRelInfo, - &searchslot->tts_tuple->t_self, - NULL, NULL); + tid, NULL, NULL); + } if (!skip_tuple) { - List *recheckIndexes = NIL; - /* OK, delete the tuple */ - simple_heap_delete(rel, &searchslot->tts_tuple->t_self); + simple_table_tuple_delete(rel, tid, estate->es_snapshot); /* AFTER ROW DELETE Triggers */ ExecARDeleteTriggers(estate, resultRelInfo, - &searchslot->tts_tuple->t_self, NULL, NULL); - - list_free(recheckIndexes); + tid, NULL, NULL); } } @@ -591,11 +591,29 @@ CheckSubscriptionRelkind(char relkind, const char *nspname, const char *relname) { /* - * We currently only support writing to regular tables. + * We currently only support writing to regular tables. However, give a + * more specific error for partitioned and foreign tables. */ + if (relkind == RELKIND_PARTITIONED_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot use relation \"%s.%s\" as logical replication target", + nspname, relname), + errdetail("\"%s.%s\" is a partitioned table.", + nspname, relname))); + else if (relkind == RELKIND_FOREIGN_TABLE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot use relation \"%s.%s\" as logical replication target", + nspname, relname), + errdetail("\"%s.%s\" is a foreign table.", + nspname, relname))); + if (relkind != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("logical replication target relation \"%s.%s\" is not a table", - nspname, relname))); + errmsg("cannot use relation \"%s.%s\" as logical replication target", + nspname, relname), + errdetail("\"%s.%s\" is not a table.", + nspname, relname))); } diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c index b97b8d797ec..c8a3efc3654 100644 --- a/src/backend/executor/execSRF.c +++ b/src/backend/executor/execSRF.c @@ -7,7 +7,7 @@ * common code for calling set-returning functions according to the * ReturnSetInfo API. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,15 +35,15 @@ /* static function decls */ static void init_sexpr(Oid foid, Oid input_collation, Expr *node, - SetExprState *sexpr, PlanState *parent, - MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF); + SetExprState *sexpr, PlanState *parent, + MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF); static void ShutdownSetExpr(Datum arg); static void ExecEvalFuncArgs(FunctionCallInfo fcinfo, - List *argList, ExprContext *econtext); + List *argList, ExprContext *econtext); static void ExecPrepareTuplestoreResult(SetExprState *sexpr, - ExprContext *econtext, - Tuplestorestate *resultStore, - TupleDesc resultDesc); + ExprContext *econtext, + Tuplestorestate *resultStore, + TupleDesc resultDesc); static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc); @@ -109,7 +109,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, Oid funcrettype; bool returnsTuple; bool returnsSet = false; - FunctionCallInfoData fcinfo; + FunctionCallInfo fcinfo; PgStat_FunctionCallUsage fcusage; ReturnSetInfo rsinfo; HeapTupleData tmptup; @@ -141,6 +141,8 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, rsinfo.setResult = NULL; rsinfo.setDesc = NULL; + fcinfo = palloc(SizeForFunctionCallInfo(list_length(setexpr->args))); + /* * Normally the passed expression tree will be a SetExprState, since the * grammar only allows a function call at the top level of a table @@ -157,9 +159,9 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, * This path is similar to ExecMakeFunctionResultSet. */ returnsSet = setexpr->funcReturnsSet; - InitFunctionCallInfoData(fcinfo, &(setexpr->func), + InitFunctionCallInfoData(*fcinfo, &(setexpr->func), list_length(setexpr->args), - setexpr->fcinfo_data.fncollation, + setexpr->fcinfo->fncollation, NULL, (Node *) &rsinfo); /* @@ -174,7 +176,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, */ MemoryContextReset(argContext); oldcontext = MemoryContextSwitchTo(argContext); - ExecEvalFuncArgs(&fcinfo, setexpr->args, econtext); + ExecEvalFuncArgs(fcinfo, setexpr->args, econtext); MemoryContextSwitchTo(oldcontext); /* @@ -186,9 +188,9 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, { int i; - for (i = 0; i < fcinfo.nargs; i++) + for (i = 0; i < fcinfo->nargs; i++) { - if (fcinfo.argnull[i]) + if (fcinfo->args[i].isnull) goto no_function_result; } } @@ -196,7 +198,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, else { /* Treat setexpr as a generic expression */ - InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL); } /* @@ -224,11 +226,11 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, /* Call the function or expression one time */ if (!setexpr->elidedFuncState) { - pgstat_init_function_usage(&fcinfo, &fcusage); + pgstat_init_function_usage(fcinfo, &fcusage); - fcinfo.isnull = false; + fcinfo->isnull = false; rsinfo.isDone = ExprSingleResult; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); pgstat_end_function_usage(&fcusage, rsinfo.isDone != ExprMultipleResult); @@ -236,7 +238,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, else { result = - ExecEvalExpr(setexpr->elidedFuncState, econtext, &fcinfo.isnull); + ExecEvalExpr(setexpr->elidedFuncState, econtext, &fcinfo->isnull); rsinfo.isDone = ExprSingleResult; } @@ -260,7 +262,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, rsinfo.setResult = tupstore; if (!returnsTuple) { - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "column", @@ -277,7 +279,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, */ if (returnsTuple) { - if (!fcinfo.isnull) + if (!fcinfo->isnull) { HeapTupleHeader td = DatumGetHeapTupleHeader(result); @@ -338,7 +340,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr, else { /* Scalar-type case: just store the function result */ - tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo.isnull); + tuplestore_putvalues(tupstore, tupdesc, &result, &fcinfo->isnull); } /* @@ -521,7 +523,7 @@ ExecMakeFunctionResultSet(SetExprState *fcache, { /* We must return the whole tuple as a Datum. */ *isNull = false; - return ExecFetchSlotTupleDatum(fcache->funcResultSlot); + return ExecFetchSlotHeapTupleDatum(fcache->funcResultSlot); } else { @@ -547,7 +549,7 @@ ExecMakeFunctionResultSet(SetExprState *fcache, * rows from this SRF have been returned, otherwise ValuePerCall SRFs * would reference freed memory after the first returned row. */ - fcinfo = &fcache->fcinfo_data; + fcinfo = fcache->fcinfo; arguments = fcache->args; if (!fcache->setArgsValid) { @@ -587,7 +589,7 @@ ExecMakeFunctionResultSet(SetExprState *fcache, { for (i = 0; i < fcinfo->nargs; i++) { - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) { callit = false; break; @@ -678,6 +680,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node, MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF) { AclResult aclresult; + size_t numargs = list_length(sexpr->args); /* Check permission to call function */ aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE); @@ -704,8 +707,10 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node, fmgr_info_set_expr((Node *) sexpr->expr, &(sexpr->func)); /* Initialize the function call parameter struct as well */ - InitFunctionCallInfoData(sexpr->fcinfo_data, &(sexpr->func), - list_length(sexpr->args), + sexpr->fcinfo = + (FunctionCallInfo) palloc(SizeForFunctionCallInfo(numargs)); + InitFunctionCallInfoData(*sexpr->fcinfo, &(sexpr->func), + numargs, input_collation, NULL, NULL); /* If function returns set, check if that's allowed by caller */ @@ -746,7 +751,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node, else if (functypclass == TYPEFUNC_SCALAR) { /* Base data type, i.e. scalar */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, NULL, @@ -820,9 +825,9 @@ ExecEvalFuncArgs(FunctionCallInfo fcinfo, { ExprState *argstate = (ExprState *) lfirst(arg); - fcinfo->arg[i] = ExecEvalExpr(argstate, - econtext, - &fcinfo->argnull[i]); + fcinfo->args[i].value = ExecEvalExpr(argstate, + econtext, + &fcinfo->args[i].isnull); i++; } @@ -873,7 +878,8 @@ ExecPrepareTuplestoreResult(SetExprState *sexpr, slotDesc = NULL; /* keep compiler quiet */ } - sexpr->funcResultSlot = MakeSingleTupleTableSlot(slotDesc); + sexpr->funcResultSlot = MakeSingleTupleTableSlot(slotDesc, + &TTSOpsMinimalTuple); MemoryContextSwitchTo(oldcontext); } diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c index caf91730ce1..b7fcd94439c 100644 --- a/src/backend/executor/execScan.c +++ b/src/backend/executor/execScan.c @@ -7,7 +7,7 @@ * stuff - checking the qualification and projecting the tuple * appropriately. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -40,8 +40,10 @@ ExecScanFetch(ScanState *node, CHECK_FOR_INTERRUPTS(); - if (estate->es_epqTuple != NULL) + if (estate->es_epq_active != NULL) { + EPQState *epqstate = estate->es_epq_active; + /* * We are inside an EvalPlanQual recheck. Return the test tuple if * one is available, after rechecking any access-method-specific @@ -51,40 +53,76 @@ ExecScanFetch(ScanState *node, if (scanrelid == 0) { - TupleTableSlot *slot = node->ss_ScanTupleSlot; - /* * This is a ForeignScan or CustomScan which has pushed down a * join to the remote side. The recheck method is responsible not * only for rechecking the scan/join quals but also for storing * the correct tuple in the slot. */ + + TupleTableSlot *slot = node->ss_ScanTupleSlot; + if (!(*recheckMtd) (node, slot)) ExecClearTuple(slot); /* would not be returned by scan */ return slot; } - else if (estate->es_epqTupleSet[scanrelid - 1]) + else if (epqstate->relsubs_done[scanrelid - 1]) { + /* + * Return empty slot, as we already performed an EPQ substitution + * for this relation. + */ + TupleTableSlot *slot = node->ss_ScanTupleSlot; - /* Return empty slot if we already returned a tuple */ - if (estate->es_epqScanDone[scanrelid - 1]) - return ExecClearTuple(slot); - /* Else mark to remember that we shouldn't return more */ - estate->es_epqScanDone[scanrelid - 1] = true; + /* Return empty slot, as we already returned a tuple */ + return ExecClearTuple(slot); + } + else if (epqstate->relsubs_slot[scanrelid - 1] != NULL) + { + /* + * Return replacement tuple provided by the EPQ caller. + */ - /* Return empty slot if we haven't got a test tuple */ - if (estate->es_epqTuple[scanrelid - 1] == NULL) - return ExecClearTuple(slot); + TupleTableSlot *slot = epqstate->relsubs_slot[scanrelid - 1]; + + Assert(epqstate->relsubs_rowmark[scanrelid - 1] == NULL); - /* Store test tuple in the plan node's scan slot */ - ExecStoreTuple(estate->es_epqTuple[scanrelid - 1], - slot, InvalidBuffer, false); + /* Mark to remember that we shouldn't return more */ + epqstate->relsubs_done[scanrelid - 1] = true; + + /* Return empty slot if we haven't got a test tuple */ + if (TupIsNull(slot)) + return NULL; /* Check if it meets the access-method conditions */ if (!(*recheckMtd) (node, slot)) - ExecClearTuple(slot); /* would not be returned by scan */ + return ExecClearTuple(slot); /* would not be returned by + * scan */ + return slot; + } + else if (epqstate->relsubs_rowmark[scanrelid - 1] != NULL) + { + /* + * Fetch and return replacement tuple using a non-locking rowmark. + */ + + TupleTableSlot *slot = node->ss_ScanTupleSlot; + + /* Mark to remember that we shouldn't return more */ + epqstate->relsubs_done[scanrelid - 1] = true; + if (!EvalPlanQualFetchRowMark(epqstate, scanrelid, slot)) + return NULL; + + /* Return empty slot if we haven't got a test tuple */ + if (TupIsNull(slot)) + return NULL; + + /* Check if it meets the access-method conditions */ + if (!(*recheckMtd) (node, slot)) + return ExecClearTuple(slot); /* would not be returned by + * scan */ return slot; } } @@ -99,8 +137,7 @@ ExecScanFetch(ScanState *node, * ExecScan * * Scans the relation using the 'access method' indicated and - * returns the next qualifying tuple in the direction specified - * in the global variable ExecDirection. + * returns the next qualifying tuple. * The access method returns the next tuple and ExecScan() is * responsible for checking the tuple returned against the qual-clause. * @@ -263,13 +300,20 @@ ExecScanReScan(ScanState *node) { EState *estate = node->ps.state; + /* + * We must clear the scan tuple so that observers (e.g., execCurrent.c) + * can tell that this plan node is not positioned on a tuple. + */ + ExecClearTuple(node->ss_ScanTupleSlot); + /* Rescan EvalPlanQual tuple if we're inside an EvalPlanQual recheck */ - if (estate->es_epqScanDone != NULL) + if (estate->es_epq_active != NULL) { + EPQState *epqstate = estate->es_epq_active; Index scanrelid = ((Scan *) node->ps.plan)->scanrelid; if (scanrelid > 0) - estate->es_epqScanDone[scanrelid - 1] = false; + epqstate->relsubs_done[scanrelid - 1] = false; else { Bitmapset *relids; @@ -291,7 +335,7 @@ ExecScanReScan(ScanState *node) while ((rtindex = bms_next_member(relids, rtindex)) >= 0) { Assert(rtindex > 0); - estate->es_epqScanDone[rtindex - 1] = false; + epqstate->relsubs_done[rtindex - 1] = false; } } } diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index d14bf2ad694..87bc510b31b 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -12,44 +12,6 @@ * This information is needed by routines manipulating tuples * (getattribute, formtuple, etc.). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/executor/execTuples.c - * - *------------------------------------------------------------------------- - */ -/* - * INTERFACE ROUTINES - * - * SLOT CREATION/DESTRUCTION - * MakeTupleTableSlot - create an empty slot - * ExecAllocTableSlot - create a slot within a tuple table - * ExecResetTupleTable - clear and optionally delete a tuple table - * MakeSingleTupleTableSlot - make a standalone slot, set its descriptor - * ExecDropSingleTupleTableSlot - destroy a standalone slot - * - * SLOT ACCESSORS - * ExecSetSlotDescriptor - set a slot's tuple descriptor - * ExecStoreTuple - store a physical tuple in the slot - * ExecStoreMinimalTuple - store a minimal physical tuple in the slot - * ExecClearTuple - clear contents of a slot - * ExecStoreVirtualTuple - mark slot as containing a virtual tuple - * ExecCopySlotTuple - build a physical tuple from a slot - * ExecCopySlotMinimalTuple - build a minimal physical tuple from a slot - * ExecMaterializeSlot - convert virtual to physical storage - * ExecCopySlot - copy one slot's contents to another - * - * CONVENIENCE INITIALIZATION ROUTINES - * ExecInitResultTupleSlot \ convenience routines to initialize - * ExecInitScanTupleSlot \ the various tuple slots for nodes - * ExecInitExtraTupleSlot / which store copies of tuples. - * ExecInitNullTupleSlot / - * - * Routines that probably belong somewhere else: - * ExecTypeFromTL - form a TupleDesc from a target list * * EXAMPLE OF HOW TABLE ROUTINES WORK * Suppose we have a query such as SELECT emp.name FROM emp and we have @@ -57,18 +19,22 @@ * * At ExecutorStart() * ---------------- - * - ExecInitSeqScan() calls ExecInitScanTupleSlot() and - * ExecInitResultTupleSlotTL() to construct TupleTableSlots - * for the tuples returned by the access methods and the - * tuples resulting from performing target list projections. + + * - ExecInitSeqScan() calls ExecInitScanTupleSlot() to construct a + * TupleTableSlots for the tuples returned by the access method, and + * ExecInitResultTypeTL() to define the node's return + * type. ExecAssignScanProjectionInfo() will, if necessary, create + * another TupleTableSlot for the tuples resulting from performing + * target list projections. * * During ExecutorRun() * ---------------- - * - SeqNext() calls ExecStoreTuple() to place the tuple returned - * by the access methods into the scan tuple slot. + * - SeqNext() calls ExecStoreBufferHeapTuple() to place the tuple + * returned by the access method into the scan tuple slot. * - * - ExecSeqScan() calls ExecStoreTuple() to take the result - * tuple from ExecProject() and place it into the result tuple slot. + * - ExecSeqScan() (via ExecScan), if necessary, calls ExecProject(), + * putting the result of the projection in the result tuple slot. If + * not necessary, it directly returns the slot returned by SeqNext(). * * - ExecutePlan() calls the output function. * @@ -78,22 +44,1019 @@ * (such as whether or not a tuple should be pfreed, what buffer contains * this tuple, the tuple's tuple descriptor, etc). It also allows us * to avoid physically constructing projection tuples in many cases. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/executor/execTuples.c + * + *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/heaptoast.h" #include "access/htup_details.h" -#include "access/tuptoaster.h" +#include "access/tupdesc_details.h" #include "funcapi.h" #include "catalog/pg_type.h" #include "nodes/nodeFuncs.h" #include "storage/bufmgr.h" #include "utils/builtins.h" +#include "utils/expandeddatum.h" #include "utils/lsyscache.h" #include "utils/typcache.h" static TupleDesc ExecTypeFromTLInternal(List *targetList, - bool hasoid, bool skipjunk); + bool skipjunk); +static pg_attribute_always_inline void slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, + int natts); +static inline void tts_buffer_heap_store_tuple(TupleTableSlot *slot, + HeapTuple tuple, + Buffer buffer, + bool transfer_pin); +static void tts_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, bool shouldFree); + + +const TupleTableSlotOps TTSOpsVirtual; +const TupleTableSlotOps TTSOpsHeapTuple; +const TupleTableSlotOps TTSOpsMinimalTuple; +const TupleTableSlotOps TTSOpsBufferHeapTuple; + + +/* + * TupleTableSlotOps implementations. + */ + +/* + * TupleTableSlotOps implementation for VirtualTupleTableSlot. + */ +static void +tts_virtual_init(TupleTableSlot *slot) +{ +} + +static void +tts_virtual_release(TupleTableSlot *slot) +{ +} + +static void +tts_virtual_clear(TupleTableSlot *slot) +{ + if (unlikely(TTS_SHOULDFREE(slot))) + { + VirtualTupleTableSlot *vslot = (VirtualTupleTableSlot *) slot; + + pfree(vslot->data); + vslot->data = NULL; + + slot->tts_flags &= ~TTS_FLAG_SHOULDFREE; + } + + slot->tts_nvalid = 0; + slot->tts_flags |= TTS_FLAG_EMPTY; + ItemPointerSetInvalid(&slot->tts_tid); +} + +/* + * Attribute values are readily available in tts_values and tts_isnull array + * in a VirtualTupleTableSlot. So there should be no need to call either of the + * following two functions. + */ +static void +tts_virtual_getsomeattrs(TupleTableSlot *slot, int natts) +{ + elog(ERROR, "getsomeattrs is not required to be called on a virtual tuple table slot"); +} + +static Datum +tts_virtual_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + elog(ERROR, "virtual tuple table slot does not have system attributes"); + + return 0; /* silence compiler warnings */ +} + +/* + * To materialize a virtual slot all the datums that aren't passed by value + * have to be copied into the slot's memory context. To do so, compute the + * required size, and allocate enough memory to store all attributes. That's + * good for cache hit ratio, but more importantly requires only memory + * allocation/deallocation. + */ +static void +tts_virtual_materialize(TupleTableSlot *slot) +{ + VirtualTupleTableSlot *vslot = (VirtualTupleTableSlot *) slot; + TupleDesc desc = slot->tts_tupleDescriptor; + Size sz = 0; + char *data; + + /* already materialized */ + if (TTS_SHOULDFREE(slot)) + return; + + /* compute size of memory required */ + for (int natt = 0; natt < desc->natts; natt++) + { + Form_pg_attribute att = TupleDescAttr(desc, natt); + Datum val; + + if (att->attbyval || slot->tts_isnull[natt]) + continue; + + val = slot->tts_values[natt]; + + if (att->attlen == -1 && + VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(val))) + { + /* + * We want to flatten the expanded value so that the materialized + * slot doesn't depend on it. + */ + sz = att_align_nominal(sz, att->attalign); + sz += EOH_get_flat_size(DatumGetEOHP(val)); + } + else + { + sz = att_align_nominal(sz, att->attalign); + sz = att_addlength_datum(sz, att->attlen, val); + } + } + + /* all data is byval */ + if (sz == 0) + return; + + /* allocate memory */ + vslot->data = data = MemoryContextAlloc(slot->tts_mcxt, sz); + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + + /* and copy all attributes into the pre-allocated space */ + for (int natt = 0; natt < desc->natts; natt++) + { + Form_pg_attribute att = TupleDescAttr(desc, natt); + Datum val; + + if (att->attbyval || slot->tts_isnull[natt]) + continue; + + val = slot->tts_values[natt]; + + if (att->attlen == -1 && + VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(val))) + { + Size data_length; + + /* + * We want to flatten the expanded value so that the materialized + * slot doesn't depend on it. + */ + ExpandedObjectHeader *eoh = DatumGetEOHP(val); + + data = (char *) att_align_nominal(data, + att->attalign); + data_length = EOH_get_flat_size(eoh); + EOH_flatten_into(eoh, data, data_length); + + slot->tts_values[natt] = PointerGetDatum(data); + data += data_length; + } + else + { + Size data_length = 0; + + data = (char *) att_align_nominal(data, att->attalign); + data_length = att_addlength_datum(data_length, att->attlen, val); + + memcpy(data, DatumGetPointer(val), data_length); + + slot->tts_values[natt] = PointerGetDatum(data); + data += data_length; + } + } +} + +static void +tts_virtual_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + TupleDesc srcdesc = srcslot->tts_tupleDescriptor; + + Assert(srcdesc->natts <= dstslot->tts_tupleDescriptor->natts); + + tts_virtual_clear(dstslot); + + slot_getallattrs(srcslot); + + for (int natt = 0; natt < srcdesc->natts; natt++) + { + dstslot->tts_values[natt] = srcslot->tts_values[natt]; + dstslot->tts_isnull[natt] = srcslot->tts_isnull[natt]; + } + + dstslot->tts_nvalid = srcdesc->natts; + dstslot->tts_flags &= ~TTS_FLAG_EMPTY; + + /* make sure storage doesn't depend on external memory */ + tts_virtual_materialize(dstslot); +} + +static HeapTuple +tts_virtual_copy_heap_tuple(TupleTableSlot *slot) +{ + Assert(!TTS_EMPTY(slot)); + + return heap_form_tuple(slot->tts_tupleDescriptor, + slot->tts_values, + slot->tts_isnull); + +} + +static MinimalTuple +tts_virtual_copy_minimal_tuple(TupleTableSlot *slot) +{ + Assert(!TTS_EMPTY(slot)); + + return heap_form_minimal_tuple(slot->tts_tupleDescriptor, + slot->tts_values, + slot->tts_isnull); +} + + +/* + * TupleTableSlotOps implementation for HeapTupleTableSlot. + */ + +static void +tts_heap_init(TupleTableSlot *slot) +{ +} + +static void +tts_heap_release(TupleTableSlot *slot) +{ +} + +static void +tts_heap_clear(TupleTableSlot *slot) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + /* Free the memory for the heap tuple if it's allowed. */ + if (TTS_SHOULDFREE(slot)) + { + heap_freetuple(hslot->tuple); + slot->tts_flags &= ~TTS_FLAG_SHOULDFREE; + } + + slot->tts_nvalid = 0; + slot->tts_flags |= TTS_FLAG_EMPTY; + ItemPointerSetInvalid(&slot->tts_tid); + hslot->off = 0; + hslot->tuple = NULL; +} + +static void +tts_heap_getsomeattrs(TupleTableSlot *slot, int natts) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + slot_deform_heap_tuple(slot, hslot->tuple, &hslot->off, natts); +} + +static Datum +tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + return heap_getsysattr(hslot->tuple, attnum, + slot->tts_tupleDescriptor, isnull); +} + +static void +tts_heap_materialize(TupleTableSlot *slot) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + MemoryContext oldContext; + + Assert(!TTS_EMPTY(slot)); + + /* This slot has it's tuple already materialized. Nothing to do. */ + if (TTS_SHOULDFREE(slot)) + return; + + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + if (!hslot->tuple) + hslot->tuple = heap_form_tuple(slot->tts_tupleDescriptor, + slot->tts_values, + slot->tts_isnull); + else + { + /* + * The tuple contained in this slot is not allocated in the memory + * context of the given slot (else it would have TTS_SHOULDFREE set). + * Copy the tuple into the given slot's memory context. + */ + hslot->tuple = heap_copytuple(hslot->tuple); + } + + /* + * Have to deform from scratch, otherwise tts_values[] entries could point + * into the non-materialized tuple (which might be gone when accessed). + */ + slot->tts_nvalid = 0; + hslot->off = 0; + + MemoryContextSwitchTo(oldContext); +} + +static void +tts_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + HeapTuple tuple; + MemoryContext oldcontext; + + oldcontext = MemoryContextSwitchTo(dstslot->tts_mcxt); + tuple = ExecCopySlotHeapTuple(srcslot); + MemoryContextSwitchTo(oldcontext); + + ExecStoreHeapTuple(tuple, dstslot, true); +} + +static HeapTuple +tts_heap_get_heap_tuple(TupleTableSlot *slot) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + if (!hslot->tuple) + tts_heap_materialize(slot); + + return hslot->tuple; +} + +static HeapTuple +tts_heap_copy_heap_tuple(TupleTableSlot *slot) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + if (!hslot->tuple) + tts_heap_materialize(slot); + + return heap_copytuple(hslot->tuple); +} + +static MinimalTuple +tts_heap_copy_minimal_tuple(TupleTableSlot *slot) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + if (!hslot->tuple) + tts_heap_materialize(slot); + + return minimal_tuple_from_heap_tuple(hslot->tuple); +} + +static void +tts_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, bool shouldFree) +{ + HeapTupleTableSlot *hslot = (HeapTupleTableSlot *) slot; + + tts_heap_clear(slot); + + slot->tts_nvalid = 0; + hslot->tuple = tuple; + hslot->off = 0; + slot->tts_flags &= ~TTS_FLAG_EMPTY; + slot->tts_tid = tuple->t_self; + + if (shouldFree) + slot->tts_flags |= TTS_FLAG_SHOULDFREE; +} + + +/* + * TupleTableSlotOps implementation for MinimalTupleTableSlot. + */ + +static void +tts_minimal_init(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + /* + * Initialize the heap tuple pointer to access attributes of the minimal + * tuple contained in the slot as if its a heap tuple. + */ + mslot->tuple = &mslot->minhdr; +} + +static void +tts_minimal_release(TupleTableSlot *slot) +{ +} + +static void +tts_minimal_clear(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + if (TTS_SHOULDFREE(slot)) + { + heap_free_minimal_tuple(mslot->mintuple); + slot->tts_flags &= ~TTS_FLAG_SHOULDFREE; + } + + slot->tts_nvalid = 0; + slot->tts_flags |= TTS_FLAG_EMPTY; + ItemPointerSetInvalid(&slot->tts_tid); + mslot->off = 0; + mslot->mintuple = NULL; +} + +static void +tts_minimal_getsomeattrs(TupleTableSlot *slot, int natts) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + slot_deform_heap_tuple(slot, mslot->tuple, &mslot->off, natts); +} + +static Datum +tts_minimal_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + elog(ERROR, "minimal tuple table slot does not have system attributes"); + + return 0; /* silence compiler warnings */ +} + +static void +tts_minimal_materialize(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + MemoryContext oldContext; + + Assert(!TTS_EMPTY(slot)); + + /* This slot has it's tuple already materialized. Nothing to do. */ + if (TTS_SHOULDFREE(slot)) + return; + + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + if (!mslot->mintuple) + { + mslot->mintuple = heap_form_minimal_tuple(slot->tts_tupleDescriptor, + slot->tts_values, + slot->tts_isnull); + } + else + { + /* + * The minimal tuple contained in this slot is not allocated in the + * memory context of the given slot (else it would have TTS_SHOULDFREE + * set). Copy the minimal tuple into the given slot's memory context. + */ + mslot->mintuple = heap_copy_minimal_tuple(mslot->mintuple); + } + + Assert(mslot->tuple == &mslot->minhdr); + + mslot->minhdr.t_len = mslot->mintuple->t_len + MINIMAL_TUPLE_OFFSET; + mslot->minhdr.t_data = (HeapTupleHeader) ((char *) mslot->mintuple - MINIMAL_TUPLE_OFFSET); + + MemoryContextSwitchTo(oldContext); + + /* + * Have to deform from scratch, otherwise tts_values[] entries could point + * into the non-materialized tuple (which might be gone when accessed). + */ + slot->tts_nvalid = 0; + mslot->off = 0; +} + +static void +tts_minimal_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + MemoryContext oldcontext; + MinimalTuple mintuple; + + oldcontext = MemoryContextSwitchTo(dstslot->tts_mcxt); + mintuple = ExecCopySlotMinimalTuple(srcslot); + MemoryContextSwitchTo(oldcontext); + + ExecStoreMinimalTuple(mintuple, dstslot, true); +} + +static MinimalTuple +tts_minimal_get_minimal_tuple(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + if (!mslot->mintuple) + tts_minimal_materialize(slot); + + return mslot->mintuple; +} + +static HeapTuple +tts_minimal_copy_heap_tuple(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + if (!mslot->mintuple) + tts_minimal_materialize(slot); + + return heap_tuple_from_minimal_tuple(mslot->mintuple); +} + +static MinimalTuple +tts_minimal_copy_minimal_tuple(TupleTableSlot *slot) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + if (!mslot->mintuple) + tts_minimal_materialize(slot); + + return heap_copy_minimal_tuple(mslot->mintuple); +} + +static void +tts_minimal_store_tuple(TupleTableSlot *slot, MinimalTuple mtup, bool shouldFree) +{ + MinimalTupleTableSlot *mslot = (MinimalTupleTableSlot *) slot; + + tts_minimal_clear(slot); + + Assert(!TTS_SHOULDFREE(slot)); + Assert(TTS_EMPTY(slot)); + + slot->tts_flags &= ~TTS_FLAG_EMPTY; + slot->tts_nvalid = 0; + mslot->off = 0; + + mslot->mintuple = mtup; + Assert(mslot->tuple == &mslot->minhdr); + mslot->minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET; + mslot->minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET); + /* no need to set t_self or t_tableOid since we won't allow access */ + + if (shouldFree) + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + else + Assert(!TTS_SHOULDFREE(slot)); +} + + +/* + * TupleTableSlotOps implementation for BufferHeapTupleTableSlot. + */ + +static void +tts_buffer_heap_init(TupleTableSlot *slot) +{ +} + +static void +tts_buffer_heap_release(TupleTableSlot *slot) +{ +} + +static void +tts_buffer_heap_clear(TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + /* + * Free the memory for heap tuple if allowed. A tuple coming from buffer + * can never be freed. But we may have materialized a tuple from buffer. + * Such a tuple can be freed. + */ + if (TTS_SHOULDFREE(slot)) + { + /* We should have unpinned the buffer while materializing the tuple. */ + Assert(!BufferIsValid(bslot->buffer)); + + heap_freetuple(bslot->base.tuple); + slot->tts_flags &= ~TTS_FLAG_SHOULDFREE; + + Assert(!BufferIsValid(bslot->buffer)); + } + + if (BufferIsValid(bslot->buffer)) + ReleaseBuffer(bslot->buffer); + + slot->tts_nvalid = 0; + slot->tts_flags |= TTS_FLAG_EMPTY; + ItemPointerSetInvalid(&slot->tts_tid); + bslot->base.tuple = NULL; + bslot->base.off = 0; + bslot->buffer = InvalidBuffer; +} + +static void +tts_buffer_heap_getsomeattrs(TupleTableSlot *slot, int natts) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + slot_deform_heap_tuple(slot, bslot->base.tuple, &bslot->base.off, natts); +} + +static Datum +tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + return heap_getsysattr(bslot->base.tuple, attnum, + slot->tts_tupleDescriptor, isnull); +} + +static void +tts_buffer_heap_materialize(TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + MemoryContext oldContext; + + Assert(!TTS_EMPTY(slot)); + + /* If already materialized nothing to do. */ + if (TTS_SHOULDFREE(slot)) + return; + + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + + if (!bslot->base.tuple) + { + /* + * Normally BufferHeapTupleTableSlot should have a tuple + buffer + * associated with it, unless it's materialized (which would've + * returned above). But when it's useful to allow storing virtual + * tuples in a buffer slot, which then also needs to be + * materializable. + */ + bslot->base.tuple = heap_form_tuple(slot->tts_tupleDescriptor, + slot->tts_values, + slot->tts_isnull); + + } + else + { + bslot->base.tuple = heap_copytuple(bslot->base.tuple); + + /* + * A heap tuple stored in a BufferHeapTupleTableSlot should have a + * buffer associated with it, unless it's materialized or virtual. + */ + Assert(BufferIsValid(bslot->buffer)); + if (likely(BufferIsValid(bslot->buffer))) + ReleaseBuffer(bslot->buffer); + bslot->buffer = InvalidBuffer; + } + MemoryContextSwitchTo(oldContext); + + /* + * Have to deform from scratch, otherwise tts_values[] entries could point + * into the non-materialized tuple (which might be gone when accessed). + */ + bslot->base.off = 0; + slot->tts_nvalid = 0; +} + +static void +tts_buffer_heap_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + BufferHeapTupleTableSlot *bsrcslot = (BufferHeapTupleTableSlot *) srcslot; + BufferHeapTupleTableSlot *bdstslot = (BufferHeapTupleTableSlot *) dstslot; + + /* + * If the source slot is of a different kind, or is a buffer slot that has + * been materialized / is virtual, make a new copy of the tuple. Otherwise + * make a new reference to the in-buffer tuple. + */ + if (dstslot->tts_ops != srcslot->tts_ops || + TTS_SHOULDFREE(srcslot) || + !bsrcslot->base.tuple) + { + MemoryContext oldContext; + + ExecClearTuple(dstslot); + dstslot->tts_flags |= TTS_FLAG_SHOULDFREE; + dstslot->tts_flags &= ~TTS_FLAG_EMPTY; + oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt); + bdstslot->base.tuple = ExecCopySlotHeapTuple(srcslot); + MemoryContextSwitchTo(oldContext); + } + else + { + Assert(BufferIsValid(bsrcslot->buffer)); + + tts_buffer_heap_store_tuple(dstslot, bsrcslot->base.tuple, + bsrcslot->buffer, false); + + /* + * The HeapTupleData portion of the source tuple might be shorter + * lived than the destination slot. Therefore copy the HeapTuple into + * our slot's tupdata, which is guaranteed to live long enough (but + * will still point into the buffer). + */ + memcpy(&bdstslot->base.tupdata, bdstslot->base.tuple, sizeof(HeapTupleData)); + bdstslot->base.tuple = &bdstslot->base.tupdata; + } +} + +static HeapTuple +tts_buffer_heap_get_heap_tuple(TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + if (!bslot->base.tuple) + tts_buffer_heap_materialize(slot); + + return bslot->base.tuple; +} + +static HeapTuple +tts_buffer_heap_copy_heap_tuple(TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + if (!bslot->base.tuple) + tts_buffer_heap_materialize(slot); + + return heap_copytuple(bslot->base.tuple); +} + +static MinimalTuple +tts_buffer_heap_copy_minimal_tuple(TupleTableSlot *slot) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + Assert(!TTS_EMPTY(slot)); + + if (!bslot->base.tuple) + tts_buffer_heap_materialize(slot); + + return minimal_tuple_from_heap_tuple(bslot->base.tuple); +} + +static inline void +tts_buffer_heap_store_tuple(TupleTableSlot *slot, HeapTuple tuple, + Buffer buffer, bool transfer_pin) +{ + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; + + if (TTS_SHOULDFREE(slot)) + { + /* materialized slot shouldn't have a buffer to release */ + Assert(!BufferIsValid(bslot->buffer)); + + heap_freetuple(bslot->base.tuple); + slot->tts_flags &= ~TTS_FLAG_SHOULDFREE; + } + + slot->tts_flags &= ~TTS_FLAG_EMPTY; + slot->tts_nvalid = 0; + bslot->base.tuple = tuple; + bslot->base.off = 0; + slot->tts_tid = tuple->t_self; + + /* + * If tuple is on a disk page, keep the page pinned as long as we hold a + * pointer into it. We assume the caller already has such a pin. If + * transfer_pin is true, we'll transfer that pin to this slot, if not + * we'll pin it again ourselves. + * + * This is coded to optimize the case where the slot previously held a + * tuple on the same disk page: in that case releasing and re-acquiring + * the pin is a waste of cycles. This is a common situation during + * seqscans, so it's worth troubling over. + */ + if (bslot->buffer != buffer) + { + if (BufferIsValid(bslot->buffer)) + ReleaseBuffer(bslot->buffer); + + bslot->buffer = buffer; + + if (!transfer_pin && BufferIsValid(buffer)) + IncrBufferRefCount(buffer); + } + else if (transfer_pin && BufferIsValid(buffer)) + { + /* + * In transfer_pin mode the caller won't know about the same-page + * optimization, so we gotta release its pin. + */ + ReleaseBuffer(buffer); + } +} + +/* + * slot_deform_heap_tuple + * Given a TupleTableSlot, extract data from the slot's physical tuple + * into its Datum/isnull arrays. Data is extracted up through the + * natts'th column (caller must ensure this is a legal column number). + * + * This is essentially an incremental version of heap_deform_tuple: + * on each call we extract attributes up to the one needed, without + * re-computing information about previously extracted attributes. + * slot->tts_nvalid is the number of attributes already extracted. + * + * This is marked as always inline, so the different offp for different types + * of slots gets optimized away. + */ +static pg_attribute_always_inline void +slot_deform_heap_tuple(TupleTableSlot *slot, HeapTuple tuple, uint32 *offp, + int natts) +{ + TupleDesc tupleDesc = slot->tts_tupleDescriptor; + Datum *values = slot->tts_values; + bool *isnull = slot->tts_isnull; + HeapTupleHeader tup = tuple->t_data; + bool hasnulls = HeapTupleHasNulls(tuple); + int attnum; + char *tp; /* ptr to tuple data */ + uint32 off; /* offset in tuple data */ + bits8 *bp = tup->t_bits; /* ptr to null bitmap in tuple */ + bool slow; /* can we use/set attcacheoff? */ + + /* We can only fetch as many attributes as the tuple has. */ + natts = Min(HeapTupleHeaderGetNatts(tuple->t_data), natts); + + /* + * Check whether the first call for this tuple, and initialize or restore + * loop state. + */ + attnum = slot->tts_nvalid; + if (attnum == 0) + { + /* Start from the first attribute */ + off = 0; + slow = false; + } + else + { + /* Restore state from previous execution */ + off = *offp; + slow = TTS_SLOW(slot); + } + + tp = (char *) tup + tup->t_hoff; + + for (; attnum < natts; attnum++) + { + Form_pg_attribute thisatt = TupleDescAttr(tupleDesc, attnum); + + if (hasnulls && att_isnull(attnum, bp)) + { + values[attnum] = (Datum) 0; + isnull[attnum] = true; + slow = true; /* can't use attcacheoff anymore */ + continue; + } + + isnull[attnum] = false; + + if (!slow && thisatt->attcacheoff >= 0) + off = thisatt->attcacheoff; + else if (thisatt->attlen == -1) + { + /* + * We can only cache the offset for a varlena attribute if the + * offset is already suitably aligned, so that there would be no + * pad bytes in any case: then the offset will be valid for either + * an aligned or unaligned value. + */ + if (!slow && + off == att_align_nominal(off, thisatt->attalign)) + thisatt->attcacheoff = off; + else + { + off = att_align_pointer(off, thisatt->attalign, -1, + tp + off); + slow = true; + } + } + else + { + /* not varlena, so safe to use att_align_nominal */ + off = att_align_nominal(off, thisatt->attalign); + + if (!slow) + thisatt->attcacheoff = off; + } + + values[attnum] = fetchatt(thisatt, tp + off); + + off = att_addlength_pointer(off, thisatt->attlen, tp + off); + + if (thisatt->attlen <= 0) + slow = true; /* can't use attcacheoff anymore */ + } + + /* + * Save state for next execution + */ + slot->tts_nvalid = attnum; + *offp = off; + if (slow) + slot->tts_flags |= TTS_FLAG_SLOW; + else + slot->tts_flags &= ~TTS_FLAG_SLOW; +} + + +const TupleTableSlotOps TTSOpsVirtual = { + .base_slot_size = sizeof(VirtualTupleTableSlot), + .init = tts_virtual_init, + .release = tts_virtual_release, + .clear = tts_virtual_clear, + .getsomeattrs = tts_virtual_getsomeattrs, + .getsysattr = tts_virtual_getsysattr, + .materialize = tts_virtual_materialize, + .copyslot = tts_virtual_copyslot, + + /* + * A virtual tuple table slot can not "own" a heap tuple or a minimal + * tuple. + */ + .get_heap_tuple = NULL, + .get_minimal_tuple = NULL, + .copy_heap_tuple = tts_virtual_copy_heap_tuple, + .copy_minimal_tuple = tts_virtual_copy_minimal_tuple +}; + +const TupleTableSlotOps TTSOpsHeapTuple = { + .base_slot_size = sizeof(HeapTupleTableSlot), + .init = tts_heap_init, + .release = tts_heap_release, + .clear = tts_heap_clear, + .getsomeattrs = tts_heap_getsomeattrs, + .getsysattr = tts_heap_getsysattr, + .materialize = tts_heap_materialize, + .copyslot = tts_heap_copyslot, + .get_heap_tuple = tts_heap_get_heap_tuple, + + /* A heap tuple table slot can not "own" a minimal tuple. */ + .get_minimal_tuple = NULL, + .copy_heap_tuple = tts_heap_copy_heap_tuple, + .copy_minimal_tuple = tts_heap_copy_minimal_tuple +}; + +const TupleTableSlotOps TTSOpsMinimalTuple = { + .base_slot_size = sizeof(MinimalTupleTableSlot), + .init = tts_minimal_init, + .release = tts_minimal_release, + .clear = tts_minimal_clear, + .getsomeattrs = tts_minimal_getsomeattrs, + .getsysattr = tts_minimal_getsysattr, + .materialize = tts_minimal_materialize, + .copyslot = tts_minimal_copyslot, + + /* A minimal tuple table slot can not "own" a heap tuple. */ + .get_heap_tuple = NULL, + .get_minimal_tuple = tts_minimal_get_minimal_tuple, + .copy_heap_tuple = tts_minimal_copy_heap_tuple, + .copy_minimal_tuple = tts_minimal_copy_minimal_tuple +}; + +const TupleTableSlotOps TTSOpsBufferHeapTuple = { + .base_slot_size = sizeof(BufferHeapTupleTableSlot), + .init = tts_buffer_heap_init, + .release = tts_buffer_heap_release, + .clear = tts_buffer_heap_clear, + .getsomeattrs = tts_buffer_heap_getsomeattrs, + .getsysattr = tts_buffer_heap_getsysattr, + .materialize = tts_buffer_heap_materialize, + .copyslot = tts_buffer_heap_copyslot, + .get_heap_tuple = tts_buffer_heap_get_heap_tuple, + + /* A buffer heap tuple table slot can not "own" a minimal tuple. */ + .get_minimal_tuple = NULL, + .copy_heap_tuple = tts_buffer_heap_copy_heap_tuple, + .copy_minimal_tuple = tts_buffer_heap_copy_minimal_tuple +}; /* ---------------------------------------------------------------- @@ -104,56 +1067,62 @@ static TupleDesc ExecTypeFromTLInternal(List *targetList, /* -------------------------------- * MakeTupleTableSlot * - * Basic routine to make an empty TupleTableSlot. If tupleDesc is - * specified the slot's descriptor is fixed for it's lifetime, gaining - * some efficiency. If that's undesirable, pass NULL. + * Basic routine to make an empty TupleTableSlot of given + * TupleTableSlotType. If tupleDesc is specified the slot's descriptor is + * fixed for its lifetime, gaining some efficiency. If that's + * undesirable, pass NULL. * -------------------------------- */ TupleTableSlot * -MakeTupleTableSlot(TupleDesc tupleDesc) +MakeTupleTableSlot(TupleDesc tupleDesc, + const TupleTableSlotOps *tts_ops) { - Size sz; + Size basesz, + allocsz; TupleTableSlot *slot; + basesz = tts_ops->base_slot_size; + /* * When a fixed descriptor is specified, we can reduce overhead by * allocating the entire slot in one go. */ if (tupleDesc) - sz = MAXALIGN(sizeof(TupleTableSlot)) + + allocsz = MAXALIGN(basesz) + MAXALIGN(tupleDesc->natts * sizeof(Datum)) + MAXALIGN(tupleDesc->natts * sizeof(bool)); else - sz = sizeof(TupleTableSlot); + allocsz = basesz; - slot = palloc0(sz); + slot = palloc0(allocsz); + /* const for optimization purposes, OK to modify at allocation time */ + *((const TupleTableSlotOps **) &slot->tts_ops) = tts_ops; slot->type = T_TupleTableSlot; - slot->tts_isempty = true; - slot->tts_shouldFree = false; - slot->tts_shouldFreeMin = false; - slot->tts_tuple = NULL; - slot->tts_fixedTupleDescriptor = tupleDesc != NULL; + slot->tts_flags |= TTS_FLAG_EMPTY; + if (tupleDesc != NULL) + slot->tts_flags |= TTS_FLAG_FIXED; slot->tts_tupleDescriptor = tupleDesc; slot->tts_mcxt = CurrentMemoryContext; - slot->tts_buffer = InvalidBuffer; slot->tts_nvalid = 0; - slot->tts_values = NULL; - slot->tts_isnull = NULL; - slot->tts_mintuple = NULL; if (tupleDesc != NULL) { slot->tts_values = (Datum *) (((char *) slot) - + MAXALIGN(sizeof(TupleTableSlot))); + + MAXALIGN(basesz)); slot->tts_isnull = (bool *) (((char *) slot) - + MAXALIGN(sizeof(TupleTableSlot)) + + MAXALIGN(basesz) + MAXALIGN(tupleDesc->natts * sizeof(Datum))); PinTupleDesc(tupleDesc); } + /* + * And allow slot type specific initialization. + */ + slot->tts_ops->init(slot); + return slot; } @@ -164,9 +1133,10 @@ MakeTupleTableSlot(TupleDesc tupleDesc) * -------------------------------- */ TupleTableSlot * -ExecAllocTableSlot(List **tupleTable, TupleDesc desc) +ExecAllocTableSlot(List **tupleTable, TupleDesc desc, + const TupleTableSlotOps *tts_ops) { - TupleTableSlot *slot = MakeTupleTableSlot(desc); + TupleTableSlot *slot = MakeTupleTableSlot(desc, tts_ops); *tupleTable = lappend(*tupleTable, slot); @@ -179,7 +1149,7 @@ ExecAllocTableSlot(List **tupleTable, TupleDesc desc) * This releases any resources (buffer pins, tupdesc refcounts) * held by the tuple table, and optionally releases the memory * occupied by the tuple table data structure. - * It is expected that this routine be called by EndPlan(). + * It is expected that this routine be called by ExecEndPlan(). * -------------------------------- */ void @@ -194,6 +1164,7 @@ ExecResetTupleTable(List *tupleTable, /* tuple table */ /* Always release resources and reset the slot to empty */ ExecClearTuple(slot); + slot->tts_ops->release(slot); if (slot->tts_tupleDescriptor) { ReleaseTupleDesc(slot->tts_tupleDescriptor); @@ -203,7 +1174,7 @@ ExecResetTupleTable(List *tupleTable, /* tuple table */ /* If shouldFree, release memory occupied by the slot itself */ if (shouldFree) { - if (!slot->tts_fixedTupleDescriptor) + if (!TTS_FIXED(slot)) { if (slot->tts_values) pfree(slot->tts_values); @@ -222,16 +1193,17 @@ ExecResetTupleTable(List *tupleTable, /* tuple table */ /* -------------------------------- * MakeSingleTupleTableSlot * - * This is a convenience routine for operations that need a - * standalone TupleTableSlot not gotten from the main executor - * tuple table. It makes a single slot and initializes it - * to use the given tuple descriptor. + * This is a convenience routine for operations that need a standalone + * TupleTableSlot not gotten from the main executor tuple table. It makes + * a single slot of given TupleTableSlotType and initializes it to use the + * given tuple descriptor. * -------------------------------- */ TupleTableSlot * -MakeSingleTupleTableSlot(TupleDesc tupdesc) +MakeSingleTupleTableSlot(TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops) { - TupleTableSlot *slot = MakeTupleTableSlot(tupdesc); + TupleTableSlot *slot = MakeTupleTableSlot(tupdesc, tts_ops); return slot; } @@ -249,9 +1221,10 @@ ExecDropSingleTupleTableSlot(TupleTableSlot *slot) /* This should match ExecResetTupleTable's processing of one slot */ Assert(IsA(slot, TupleTableSlot)); ExecClearTuple(slot); + slot->tts_ops->release(slot); if (slot->tts_tupleDescriptor) ReleaseTupleDesc(slot->tts_tupleDescriptor); - if (!slot->tts_fixedTupleDescriptor) + if (!TTS_FIXED(slot)) { if (slot->tts_values) pfree(slot->tts_values); @@ -281,7 +1254,7 @@ void ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */ TupleDesc tupdesc) /* new tuple descriptor */ { - Assert(!slot->tts_fixedTupleDescriptor); + Assert(!TTS_FIXED(slot)); /* For safety, make sure slot is empty before changing it */ ExecClearTuple(slot); @@ -315,48 +1288,35 @@ ExecSetSlotDescriptor(TupleTableSlot *slot, /* slot to change */ } /* -------------------------------- - * ExecStoreTuple + * ExecStoreHeapTuple * - * This function is used to store a physical tuple into a specified + * This function is used to store an on-the-fly physical tuple into a specified * slot in the tuple table. * * tuple: tuple to store - * slot: slot to store it in - * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer + * slot: TTSOpsHeapTuple type slot to store it in * shouldFree: true if ExecClearTuple should pfree() the tuple * when done with it * - * If 'buffer' is not InvalidBuffer, the tuple table code acquires a pin - * on the buffer which is held until the slot is cleared, so that the tuple - * won't go away on us. - * - * shouldFree is normally set 'true' for tuples constructed on-the-fly. - * It must always be 'false' for tuples that are stored in disk pages, - * since we don't want to try to pfree those. - * - * Another case where it is 'false' is when the referenced tuple is held - * in a tuple table slot belonging to a lower-level executor Proc node. - * In this case the lower-level slot retains ownership and responsibility - * for eventually releasing the tuple. When this method is used, we must - * be certain that the upper-level Proc node will lose interest in the tuple - * sooner than the lower-level one does! If you're not certain, copy the - * lower-level tuple with heap_copytuple and let the upper-level table - * slot assume ownership of the copy! + * shouldFree is normally set 'true' for tuples constructed on-the-fly. But it + * can be 'false' when the referenced tuple is held in a tuple table slot + * belonging to a lower-level executor Proc node. In this case the lower-level + * slot retains ownership and responsibility for eventually releasing the + * tuple. When this method is used, we must be certain that the upper-level + * Proc node will lose interest in the tuple sooner than the lower-level one + * does! If you're not certain, copy the lower-level tuple with heap_copytuple + * and let the upper-level table slot assume ownership of the copy! * * Return value is just the passed-in slot pointer. * - * NOTE: before PostgreSQL 8.1, this function would accept a NULL tuple - * pointer and effectively behave like ExecClearTuple (though you could - * still specify a buffer to pin, which would be an odd combination). - * This saved a couple lines of code in a few places, but seemed more likely - * to mask logic errors than to be really useful, so it's now disallowed. + * If the target slot is not guaranteed to be TTSOpsHeapTuple type slot, use + * the, more expensive, ExecForceStoreHeapTuple(). * -------------------------------- */ TupleTableSlot * -ExecStoreTuple(HeapTuple tuple, - TupleTableSlot *slot, - Buffer buffer, - bool shouldFree) +ExecStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree) { /* * sanity checks @@ -364,149 +1324,182 @@ ExecStoreTuple(HeapTuple tuple, Assert(tuple != NULL); Assert(slot != NULL); Assert(slot->tts_tupleDescriptor != NULL); - /* passing shouldFree=true for a tuple on a disk page is not sane */ - Assert(BufferIsValid(buffer) ? (!shouldFree) : true); - - /* - * Free any old physical tuple belonging to the slot. - */ - if (slot->tts_shouldFree) - heap_freetuple(slot->tts_tuple); - if (slot->tts_shouldFreeMin) - heap_free_minimal_tuple(slot->tts_mintuple); - /* - * Store the new tuple into the specified slot. - */ - slot->tts_isempty = false; - slot->tts_shouldFree = shouldFree; - slot->tts_shouldFreeMin = false; - slot->tts_tuple = tuple; - slot->tts_mintuple = NULL; - - /* Mark extracted state invalid */ - slot->tts_nvalid = 0; + if (unlikely(!TTS_IS_HEAPTUPLE(slot))) + elog(ERROR, "trying to store a heap tuple into wrong type of slot"); + tts_heap_store_tuple(slot, tuple, shouldFree); - /* - * If tuple is on a disk page, keep the page pinned as long as we hold a - * pointer into it. We assume the caller already has such a pin. - * - * This is coded to optimize the case where the slot previously held a - * tuple on the same disk page: in that case releasing and re-acquiring - * the pin is a waste of cycles. This is a common situation during - * seqscans, so it's worth troubling over. - */ - if (slot->tts_buffer != buffer) - { - if (BufferIsValid(slot->tts_buffer)) - ReleaseBuffer(slot->tts_buffer); - slot->tts_buffer = buffer; - if (BufferIsValid(buffer)) - IncrBufferRefCount(buffer); - } + slot->tts_tableOid = tuple->t_tableOid; return slot; } /* -------------------------------- - * ExecStoreMinimalTuple + * ExecStoreBufferHeapTuple + * + * This function is used to store an on-disk physical tuple from a buffer + * into a specified slot in the tuple table. + * + * tuple: tuple to store + * slot: TTSOpsBufferHeapTuple type slot to store it in + * buffer: disk buffer if tuple is in a disk page, else InvalidBuffer * - * Like ExecStoreTuple, but insert a "minimal" tuple into the slot. + * The tuple table code acquires a pin on the buffer which is held until the + * slot is cleared, so that the tuple won't go away on us. * - * No 'buffer' parameter since minimal tuples are never stored in relations. + * Return value is just the passed-in slot pointer. + * + * If the target slot is not guaranteed to be TTSOpsBufferHeapTuple type slot, + * use the, more expensive, ExecForceStoreHeapTuple(). * -------------------------------- */ TupleTableSlot * -ExecStoreMinimalTuple(MinimalTuple mtup, - TupleTableSlot *slot, - bool shouldFree) +ExecStoreBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer) { /* * sanity checks */ - Assert(mtup != NULL); + Assert(tuple != NULL); Assert(slot != NULL); Assert(slot->tts_tupleDescriptor != NULL); + Assert(BufferIsValid(buffer)); - /* - * Free any old physical tuple belonging to the slot. - */ - if (slot->tts_shouldFree) - heap_freetuple(slot->tts_tuple); - if (slot->tts_shouldFreeMin) - heap_free_minimal_tuple(slot->tts_mintuple); + if (unlikely(!TTS_IS_BUFFERTUPLE(slot))) + elog(ERROR, "trying to store an on-disk heap tuple into wrong type of slot"); + tts_buffer_heap_store_tuple(slot, tuple, buffer, false); - /* - * Drop the pin on the referenced buffer, if there is one. - */ - if (BufferIsValid(slot->tts_buffer)) - ReleaseBuffer(slot->tts_buffer); + slot->tts_tableOid = tuple->t_tableOid; - slot->tts_buffer = InvalidBuffer; + return slot; +} +/* + * Like ExecStoreBufferHeapTuple, but transfer an existing pin from the caller + * to the slot, i.e. the caller doesn't need to, and may not, release the pin. + */ +TupleTableSlot * +ExecStorePinnedBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer) +{ /* - * Store the new tuple into the specified slot. + * sanity checks */ - slot->tts_isempty = false; - slot->tts_shouldFree = false; - slot->tts_shouldFreeMin = shouldFree; - slot->tts_tuple = &slot->tts_minhdr; - slot->tts_mintuple = mtup; - - slot->tts_minhdr.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET; - slot->tts_minhdr.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET); - /* no need to set t_self or t_tableOid since we won't allow access */ + Assert(tuple != NULL); + Assert(slot != NULL); + Assert(slot->tts_tupleDescriptor != NULL); + Assert(BufferIsValid(buffer)); - /* Mark extracted state invalid */ - slot->tts_nvalid = 0; + if (unlikely(!TTS_IS_BUFFERTUPLE(slot))) + elog(ERROR, "trying to store an on-disk heap tuple into wrong type of slot"); + tts_buffer_heap_store_tuple(slot, tuple, buffer, true); + + slot->tts_tableOid = tuple->t_tableOid; return slot; } -/* -------------------------------- - * ExecClearTuple - * - * This function is used to clear out a slot in the tuple table. +/* + * Store a minimal tuple into TTSOpsMinimalTuple type slot. * - * NB: only the tuple is cleared, not the tuple descriptor (if any). - * -------------------------------- + * If the target slot is not guaranteed to be TTSOpsMinimalTuple type slot, + * use the, more expensive, ExecForceStoreMinimalTuple(). */ -TupleTableSlot * /* return: slot passed */ -ExecClearTuple(TupleTableSlot *slot) /* slot in which to store tuple */ +TupleTableSlot * +ExecStoreMinimalTuple(MinimalTuple mtup, + TupleTableSlot *slot, + bool shouldFree) { /* * sanity checks */ + Assert(mtup != NULL); Assert(slot != NULL); + Assert(slot->tts_tupleDescriptor != NULL); - /* - * Free the old physical tuple if necessary. - */ - if (slot->tts_shouldFree) - heap_freetuple(slot->tts_tuple); - if (slot->tts_shouldFreeMin) - heap_free_minimal_tuple(slot->tts_mintuple); + if (unlikely(!TTS_IS_MINIMALTUPLE(slot))) + elog(ERROR, "trying to store a minimal tuple into wrong type of slot"); + tts_minimal_store_tuple(slot, mtup, shouldFree); - slot->tts_tuple = NULL; - slot->tts_mintuple = NULL; - slot->tts_shouldFree = false; - slot->tts_shouldFreeMin = false; + return slot; +} - /* - * Drop the pin on the referenced buffer, if there is one. - */ - if (BufferIsValid(slot->tts_buffer)) - ReleaseBuffer(slot->tts_buffer); +/* + * Store a HeapTuple into any kind of slot, performing conversion if + * necessary. + */ +void +ExecForceStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree) +{ + if (TTS_IS_HEAPTUPLE(slot)) + { + ExecStoreHeapTuple(tuple, slot, shouldFree); + } + else if (TTS_IS_BUFFERTUPLE(slot)) + { + MemoryContext oldContext; + BufferHeapTupleTableSlot *bslot = (BufferHeapTupleTableSlot *) slot; - slot->tts_buffer = InvalidBuffer; + ExecClearTuple(slot); + slot->tts_flags |= TTS_FLAG_SHOULDFREE; + slot->tts_flags &= ~TTS_FLAG_EMPTY; + oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + bslot->base.tuple = heap_copytuple(tuple); + MemoryContextSwitchTo(oldContext); - /* - * Mark it empty. - */ - slot->tts_isempty = true; - slot->tts_nvalid = 0; + if (shouldFree) + pfree(tuple); + } + else + { + ExecClearTuple(slot); + heap_deform_tuple(tuple, slot->tts_tupleDescriptor, + slot->tts_values, slot->tts_isnull); + ExecStoreVirtualTuple(slot); - return slot; + if (shouldFree) + { + ExecMaterializeSlot(slot); + pfree(tuple); + } + } +} + +/* + * Store a MinimalTuple into any kind of slot, performing conversion if + * necessary. + */ +void +ExecForceStoreMinimalTuple(MinimalTuple mtup, + TupleTableSlot *slot, + bool shouldFree) +{ + if (TTS_IS_MINIMALTUPLE(slot)) + { + tts_minimal_store_tuple(slot, mtup, shouldFree); + } + else + { + HeapTupleData htup; + + ExecClearTuple(slot); + + htup.t_len = mtup->t_len + MINIMAL_TUPLE_OFFSET; + htup.t_data = (HeapTupleHeader) ((char *) mtup - MINIMAL_TUPLE_OFFSET); + heap_deform_tuple(&htup, slot->tts_tupleDescriptor, + slot->tts_values, slot->tts_isnull); + ExecStoreVirtualTuple(slot); + + if (shouldFree) + { + ExecMaterializeSlot(slot); + pfree(mtup); + } + } } /* -------------------------------- @@ -528,9 +1521,9 @@ ExecStoreVirtualTuple(TupleTableSlot *slot) */ Assert(slot != NULL); Assert(slot->tts_tupleDescriptor != NULL); - Assert(slot->tts_isempty); + Assert(TTS_EMPTY(slot)); - slot->tts_isempty = false; + slot->tts_flags &= ~TTS_FLAG_EMPTY; slot->tts_nvalid = slot->tts_tupleDescriptor->natts; return slot; @@ -567,310 +1560,170 @@ ExecStoreAllNullTuple(TupleTableSlot *slot) return ExecStoreVirtualTuple(slot); } -/* -------------------------------- - * ExecCopySlotTuple - * Obtain a copy of a slot's regular physical tuple. The copy is - * palloc'd in the current memory context. - * The slot itself is undisturbed. +/* + * Store a HeapTuple in datum form, into a slot. That always requires + * deforming it and storing it in virtual form. * - * This works even if the slot contains a virtual or minimal tuple; - * however the "system columns" of the result will not be meaningful. - * -------------------------------- + * Until the slot is materialized, the contents of the slot depend on the + * datum. */ -HeapTuple -ExecCopySlotTuple(TupleTableSlot *slot) +void +ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot) { - /* - * sanity checks - */ - Assert(slot != NULL); - Assert(!slot->tts_isempty); - - /* - * If we have a physical tuple (either format) then just copy it. - */ - if (TTS_HAS_PHYSICAL_TUPLE(slot)) - return heap_copytuple(slot->tts_tuple); - if (slot->tts_mintuple) - return heap_tuple_from_minimal_tuple(slot->tts_mintuple); + HeapTupleData tuple = {0}; + HeapTupleHeader td; - /* - * Otherwise we need to build a tuple from the Datum array. - */ - return heap_form_tuple(slot->tts_tupleDescriptor, - slot->tts_values, - slot->tts_isnull); -} + td = DatumGetHeapTupleHeader(data); -/* -------------------------------- - * ExecCopySlotMinimalTuple - * Obtain a copy of a slot's minimal physical tuple. The copy is - * palloc'd in the current memory context. - * The slot itself is undisturbed. - * -------------------------------- - */ -MinimalTuple -ExecCopySlotMinimalTuple(TupleTableSlot *slot) -{ - /* - * sanity checks - */ - Assert(slot != NULL); - Assert(!slot->tts_isempty); + tuple.t_len = HeapTupleHeaderGetDatumLength(td); + tuple.t_self = td->t_ctid; + tuple.t_data = td; - /* - * If we have a physical tuple then just copy it. Prefer to copy - * tts_mintuple since that's a tad cheaper. - */ - if (slot->tts_mintuple) - return heap_copy_minimal_tuple(slot->tts_mintuple); - if (slot->tts_tuple) - { - if (HeapTupleHeaderGetNatts(slot->tts_tuple->t_data) - < slot->tts_tupleDescriptor->natts) - return minimal_expand_tuple(slot->tts_tuple, - slot->tts_tupleDescriptor); - else - return minimal_tuple_from_heap_tuple(slot->tts_tuple); - } + ExecClearTuple(slot); - /* - * Otherwise we need to build a tuple from the Datum array. - */ - return heap_form_minimal_tuple(slot->tts_tupleDescriptor, - slot->tts_values, - slot->tts_isnull); + heap_deform_tuple(&tuple, slot->tts_tupleDescriptor, + slot->tts_values, slot->tts_isnull); + ExecStoreVirtualTuple(slot); } -/* -------------------------------- - * ExecFetchSlotTuple - * Fetch the slot's regular physical tuple. +/* + * ExecFetchSlotHeapTuple - fetch HeapTuple representing the slot's content * - * If the slot contains a virtual tuple, we convert it to physical - * form. The slot retains ownership of the physical tuple. - * If it contains a minimal tuple we convert to regular form and store - * that in addition to the minimal tuple (not instead of, because - * callers may hold pointers to Datums within the minimal tuple). + * The returned HeapTuple represents the slot's content as closely as + * possible. * - * The main difference between this and ExecMaterializeSlot() is that this - * does not guarantee that the contained tuple is local storage. - * Hence, the result must be treated as read-only. - * -------------------------------- + * If materialize is true, the contents of the slots will be made independent + * from the underlying storage (i.e. all buffer pins are released, memory is + * allocated in the slot's context). + * + * If shouldFree is not-NULL it'll be set to true if the returned tuple has + * been allocated in the calling memory context, and must be freed by the + * caller (via explicit pfree() or a memory context reset). + * + * NB: If materialize is true, modifications of the returned tuple are + * allowed. But it depends on the type of the slot whether such modifications + * will also affect the slot's contents. While that is not the nicest + * behaviour, all such modifications are in the process of being removed. */ HeapTuple -ExecFetchSlotTuple(TupleTableSlot *slot) +ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree) { /* * sanity checks */ Assert(slot != NULL); - Assert(!slot->tts_isempty); + Assert(!TTS_EMPTY(slot)); - /* - * If we have a regular physical tuple then just return it. - */ - if (TTS_HAS_PHYSICAL_TUPLE(slot)) - { - if (HeapTupleHeaderGetNatts(slot->tts_tuple->t_data) < - slot->tts_tupleDescriptor->natts) - { - HeapTuple tuple; - MemoryContext oldContext = MemoryContextSwitchTo(slot->tts_mcxt); + /* Materialize the tuple so that the slot "owns" it, if requested. */ + if (materialize) + slot->tts_ops->materialize(slot); - tuple = heap_expand_tuple(slot->tts_tuple, - slot->tts_tupleDescriptor); - MemoryContextSwitchTo(oldContext); - slot = ExecStoreTuple(tuple, slot, InvalidBuffer, true); - } - return slot->tts_tuple; + if (slot->tts_ops->get_heap_tuple == NULL) + { + if (shouldFree) + *shouldFree = true; + return slot->tts_ops->copy_heap_tuple(slot); + } + else + { + if (shouldFree) + *shouldFree = false; + return slot->tts_ops->get_heap_tuple(slot); } - - /* - * Otherwise materialize the slot... - */ - return ExecMaterializeSlot(slot); } /* -------------------------------- * ExecFetchSlotMinimalTuple * Fetch the slot's minimal physical tuple. * - * If the slot contains a virtual tuple, we convert it to minimal - * physical form. The slot retains ownership of the minimal tuple. - * If it contains a regular tuple we convert to minimal form and store - * that in addition to the regular tuple (not instead of, because - * callers may hold pointers to Datums within the regular tuple). + * If the given tuple table slot can hold a minimal tuple, indicated by a + * non-NULL get_minimal_tuple callback, the function returns the minimal + * tuple returned by that callback. It assumes that the minimal tuple + * returned by the callback is "owned" by the slot i.e. the slot is + * responsible for freeing the memory consumed by the tuple. Hence it sets + * *shouldFree to false, indicating that the caller should not free the + * memory consumed by the minimal tuple. In this case the returned minimal + * tuple should be considered as read-only. * - * As above, the result must be treated as read-only. + * If that callback is not supported, it calls copy_minimal_tuple callback + * which is expected to return a copy of minimal tuple representing the + * contents of the slot. In this case *shouldFree is set to true, + * indicating the caller that it should free the memory consumed by the + * minimal tuple. In this case the returned minimal tuple may be written + * up. * -------------------------------- */ MinimalTuple -ExecFetchSlotMinimalTuple(TupleTableSlot *slot) +ExecFetchSlotMinimalTuple(TupleTableSlot *slot, + bool *shouldFree) { - MemoryContext oldContext; - /* * sanity checks */ Assert(slot != NULL); - Assert(!slot->tts_isempty); - - /* - * If we have a minimal physical tuple (local or not) then just return it. - */ - if (slot->tts_mintuple) - return slot->tts_mintuple; - - /* - * Otherwise, copy or build a minimal tuple, and store it into the slot. - * - * We may be called in a context that is shorter-lived than the tuple - * slot, but we have to ensure that the materialized tuple will survive - * anyway. - */ - oldContext = MemoryContextSwitchTo(slot->tts_mcxt); - slot->tts_mintuple = ExecCopySlotMinimalTuple(slot); - slot->tts_shouldFreeMin = true; - MemoryContextSwitchTo(oldContext); - - /* - * Note: we may now have a situation where we have a local minimal tuple - * attached to a virtual or non-local physical tuple. There seems no harm - * in that at the moment, but if any materializes, we should change this - * function to force the slot into minimal-tuple-only state. - */ + Assert(!TTS_EMPTY(slot)); - return slot->tts_mintuple; + if (slot->tts_ops->get_minimal_tuple) + { + if (shouldFree) + *shouldFree = false; + return slot->tts_ops->get_minimal_tuple(slot); + } + else + { + if (shouldFree) + *shouldFree = true; + return slot->tts_ops->copy_minimal_tuple(slot); + } } /* -------------------------------- - * ExecFetchSlotTupleDatum + * ExecFetchSlotHeapTupleDatum * Fetch the slot's tuple as a composite-type Datum. * * The result is always freshly palloc'd in the caller's memory context. * -------------------------------- */ Datum -ExecFetchSlotTupleDatum(TupleTableSlot *slot) +ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot) { HeapTuple tup; TupleDesc tupdesc; + bool shouldFree; + Datum ret; /* Fetch slot's contents in regular-physical-tuple form */ - tup = ExecFetchSlotTuple(slot); + tup = ExecFetchSlotHeapTuple(slot, false, &shouldFree); tupdesc = slot->tts_tupleDescriptor; /* Convert to Datum form */ - return heap_copy_tuple_as_datum(tup, tupdesc); -} - -/* -------------------------------- - * ExecMaterializeSlot - * Force a slot into the "materialized" state. - * - * This causes the slot's tuple to be a local copy not dependent on - * any external storage. A pointer to the contained tuple is returned. - * - * A typical use for this operation is to prepare a computed tuple - * for being stored on disk. The original data may or may not be - * virtual, but in any case we need a private copy for heap_insert - * to scribble on. - * -------------------------------- - */ -HeapTuple -ExecMaterializeSlot(TupleTableSlot *slot) -{ - MemoryContext oldContext; - - /* - * sanity checks - */ - Assert(slot != NULL); - Assert(!slot->tts_isempty); - - /* - * If we have a regular physical tuple, and it's locally palloc'd, we have - * nothing to do. - */ - if (slot->tts_tuple && slot->tts_shouldFree) - return slot->tts_tuple; - - /* - * Otherwise, copy or build a physical tuple, and store it into the slot. - * - * We may be called in a context that is shorter-lived than the tuple - * slot, but we have to ensure that the materialized tuple will survive - * anyway. - */ - oldContext = MemoryContextSwitchTo(slot->tts_mcxt); - slot->tts_tuple = ExecCopySlotTuple(slot); - slot->tts_shouldFree = true; - MemoryContextSwitchTo(oldContext); + ret = heap_copy_tuple_as_datum(tup, tupdesc); - /* - * Drop the pin on the referenced buffer, if there is one. - */ - if (BufferIsValid(slot->tts_buffer)) - ReleaseBuffer(slot->tts_buffer); - - slot->tts_buffer = InvalidBuffer; - - /* - * Mark extracted state invalid. This is important because the slot is - * not supposed to depend any more on the previous external data; we - * mustn't leave any dangling pass-by-reference datums in tts_values. - * However, we have not actually invalidated any such datums, if there - * happen to be any previously fetched from the slot. (Note in particular - * that we have not pfree'd tts_mintuple, if there is one.) - */ - slot->tts_nvalid = 0; - - /* - * On the same principle of not depending on previous remote storage, - * forget the mintuple if it's not local storage. (If it is local - * storage, we must not pfree it now, since callers might have already - * fetched datum pointers referencing it.) - */ - if (!slot->tts_shouldFreeMin) - slot->tts_mintuple = NULL; + if (shouldFree) + pfree(tup); - return slot->tts_tuple; + return ret; } -/* -------------------------------- - * ExecCopySlot - * Copy the source slot's contents into the destination slot. - * - * The destination acquires a private copy that will not go away - * if the source is cleared. +/* ---------------------------------------------------------------- + * convenience initialization routines + * ---------------------------------------------------------------- + */ + +/* ---------------- + * ExecInitResultTypeTL * - * The caller must ensure the slots have compatible tupdescs. - * -------------------------------- + * Initialize result type, using the plan node's targetlist. + * ---------------- */ -TupleTableSlot * -ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +void +ExecInitResultTypeTL(PlanState *planstate) { - HeapTuple newTuple; - MemoryContext oldContext; + TupleDesc tupDesc = ExecTypeFromTL(planstate->plan->targetlist); - /* - * There might be ways to optimize this when the source is virtual, but - * for now just always build a physical copy. Make sure it is in the - * right context. - */ - oldContext = MemoryContextSwitchTo(dstslot->tts_mcxt); - newTuple = ExecCopySlotTuple(srcslot); - MemoryContextSwitchTo(oldContext); - - return ExecStoreTuple(newTuple, dstslot, InvalidBuffer, true); + planstate->ps_ResultTupleDesc = tupDesc; } - -/* ---------------------------------------------------------------- - * convenience initialization routines - * ---------------------------------------------------------------- - */ - /* -------------------------------- * ExecInit{Result,Scan,Extra}TupleSlot[TL] * @@ -883,28 +1736,36 @@ ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) /* ---------------- * ExecInitResultTupleSlotTL * - * Initialize result tuple slot, using the plan node's targetlist. + * Initialize result tuple slot, using the tuple descriptor previously + * computed with ExecInitResultTypeTL(). * ---------------- */ void -ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate) +ExecInitResultSlot(PlanState *planstate, const TupleTableSlotOps *tts_ops) { - bool hasoid; - TupleDesc tupDesc; + TupleTableSlot *slot; - if (ExecContextForcesOids(planstate, &hasoid)) - { - /* context forces OID choice; hasoid is now set correctly */ - } - else - { - /* given free choice, don't leave space for OIDs in result tuples */ - hasoid = false; - } + slot = ExecAllocTableSlot(&planstate->state->es_tupleTable, + planstate->ps_ResultTupleDesc, tts_ops); + planstate->ps_ResultTupleSlot = slot; - tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid); + planstate->resultopsfixed = planstate->ps_ResultTupleDesc != NULL; + planstate->resultops = tts_ops; + planstate->resultopsset = true; +} - planstate->ps_ResultTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable, tupDesc); +/* ---------------- + * ExecInitResultTupleSlotTL + * + * Initialize result tuple slot, using the plan node's targetlist. + * ---------------- + */ +void +ExecInitResultTupleSlotTL(PlanState *planstate, + const TupleTableSlotOps *tts_ops) +{ + ExecInitResultTypeTL(planstate); + ExecInitResultSlot(planstate, tts_ops); } /* ---------------- @@ -912,11 +1773,15 @@ ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate) * ---------------- */ void -ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc) +ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, + TupleDesc tupledesc, const TupleTableSlotOps *tts_ops) { scanstate->ss_ScanTupleSlot = ExecAllocTableSlot(&estate->es_tupleTable, - tupledesc); + tupledesc, tts_ops); scanstate->ps.scandesc = tupledesc; + scanstate->ps.scanopsfixed = tupledesc != NULL; + scanstate->ps.scanops = tts_ops; + scanstate->ps.scanopsset = true; } /* ---------------- @@ -928,9 +1793,11 @@ ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc) * ---------------- */ TupleTableSlot * -ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc) +ExecInitExtraTupleSlot(EState *estate, + TupleDesc tupledesc, + const TupleTableSlotOps *tts_ops) { - return ExecAllocTableSlot(&estate->es_tupleTable, tupledesc); + return ExecAllocTableSlot(&estate->es_tupleTable, tupledesc, tts_ops); } /* ---------------- @@ -942,13 +1809,85 @@ ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc) * ---------------- */ TupleTableSlot * -ExecInitNullTupleSlot(EState *estate, TupleDesc tupType) +ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, + const TupleTableSlotOps *tts_ops) { - TupleTableSlot *slot = ExecInitExtraTupleSlot(estate, tupType); + TupleTableSlot *slot = ExecInitExtraTupleSlot(estate, tupType, tts_ops); return ExecStoreAllNullTuple(slot); } +/* --------------------------------------------------------------- + * Routines for setting/accessing attributes in a slot. + * --------------------------------------------------------------- + */ + +/* + * Fill in missing values for a TupleTableSlot. + * + * This is only exposed because it's needed for JIT compiled tuple + * deforming. That exception aside, there should be no callers outside of this + * file. + */ +void +slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum) +{ + AttrMissing *attrmiss = NULL; + + if (slot->tts_tupleDescriptor->constr) + attrmiss = slot->tts_tupleDescriptor->constr->missing; + + if (!attrmiss) + { + /* no missing values array at all, so just fill everything in as NULL */ + memset(slot->tts_values + startAttNum, 0, + (lastAttNum - startAttNum) * sizeof(Datum)); + memset(slot->tts_isnull + startAttNum, 1, + (lastAttNum - startAttNum) * sizeof(bool)); + } + else + { + int missattnum; + + /* if there is a missing values array we must process them one by one */ + for (missattnum = startAttNum; + missattnum < lastAttNum; + missattnum++) + { + slot->tts_values[missattnum] = attrmiss[missattnum].am_value; + slot->tts_isnull[missattnum] = !attrmiss[missattnum].am_present; + } + + } +} + +/* + * slot_getsomeattrs_int - workhorse for slot_getsomeattrs() + */ +void +slot_getsomeattrs_int(TupleTableSlot *slot, int attnum) +{ + /* Check for caller errors */ + Assert(slot->tts_nvalid < attnum); /* checked in slot_getsomeattrs */ + Assert(attnum > 0); + + if (unlikely(attnum > slot->tts_tupleDescriptor->natts)) + elog(ERROR, "invalid attribute number %d", attnum); + + /* Fetch as many attributes as possible from the underlying tuple. */ + slot->tts_ops->getsomeattrs(slot, attnum); + + /* + * If the underlying tuple doesn't have enough attributes, tuple + * descriptor must have the missing attributes. + */ + if (unlikely(slot->tts_nvalid < attnum)) + { + slot_getmissingattrs(slot, slot->tts_nvalid, attnum); + slot->tts_nvalid = attnum; + } +} + /* ---------------------------------------------------------------- * ExecTypeFromTL * @@ -962,9 +1901,9 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType) * ---------------------------------------------------------------- */ TupleDesc -ExecTypeFromTL(List *targetList, bool hasoid) +ExecTypeFromTL(List *targetList) { - return ExecTypeFromTLInternal(targetList, hasoid, false); + return ExecTypeFromTLInternal(targetList, false); } /* ---------------------------------------------------------------- @@ -974,13 +1913,13 @@ ExecTypeFromTL(List *targetList, bool hasoid) * ---------------------------------------------------------------- */ TupleDesc -ExecCleanTypeFromTL(List *targetList, bool hasoid) +ExecCleanTypeFromTL(List *targetList) { - return ExecTypeFromTLInternal(targetList, hasoid, true); + return ExecTypeFromTLInternal(targetList, true); } static TupleDesc -ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk) +ExecTypeFromTLInternal(List *targetList, bool skipjunk) { TupleDesc typeInfo; ListCell *l; @@ -991,7 +1930,7 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk) len = ExecCleanTargetListLength(targetList); else len = ExecTargetListLength(targetList); - typeInfo = CreateTemplateTupleDesc(len, hasoid); + typeInfo = CreateTemplateTupleDesc(len); foreach(l, targetList) { @@ -1027,7 +1966,7 @@ ExecTypeFromExprList(List *exprList) ListCell *lc; int cur_resno = 1; - typeInfo = CreateTemplateTupleDesc(list_length(exprList), false); + typeInfo = CreateTemplateTupleDesc(list_length(exprList)); foreach(lc, exprList) { @@ -1115,28 +2054,6 @@ BlessTupleDesc(TupleDesc tupdesc) return tupdesc; /* just for notational convenience */ } -/* - * TupleDescGetSlot - Initialize a slot based on the supplied tupledesc - * - * Note: this is obsolete; it is sufficient to call BlessTupleDesc on - * the tupdesc. We keep it around just for backwards compatibility with - * existing user-written SRFs. - */ -TupleTableSlot * -TupleDescGetSlot(TupleDesc tupdesc) -{ - TupleTableSlot *slot; - - /* The useful work is here */ - BlessTupleDesc(tupdesc); - - /* Make a standalone slot */ - slot = MakeSingleTupleTableSlot(tupdesc); - - /* Return the slot */ - return slot; -} - /* * TupleDescGetAttInMetadata - Build an AttInMetadata structure based on the * supplied TupleDesc. AttInMetadata can be used in conjunction with C strings @@ -1312,13 +2229,15 @@ HeapTupleHeaderGetDatum(HeapTupleHeader tuple) * table function capability. Currently used by EXPLAIN and SHOW ALL. */ TupOutputState * -begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc) +begin_tup_output_tupdesc(DestReceiver *dest, + TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops) { TupOutputState *tstate; tstate = (TupOutputState *) palloc(sizeof(TupOutputState)); - tstate->slot = MakeSingleTupleTableSlot(tupdesc); + tstate->slot = MakeSingleTupleTableSlot(tupdesc, tts_ops); tstate->dest = dest; tstate->dest->rStartup(tstate->dest, (int) CMD_SELECT, tupdesc); diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index b963cae730c..ee0239b146a 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -3,7 +3,7 @@ * execUtils.c * miscellaneous executor utility routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,7 +25,10 @@ * etc * * ExecOpenScanRelation Common code for scan node init routines. - * ExecCloseScanRelation + * + * ExecInitRangeTable Set up executor's range-table-related data. + * + * ExecGetRangeTableRelation Fetch Relation for a rangetable entry. * * executor_errposition Report syntactic position of an error. * @@ -42,12 +45,17 @@ #include "postgres.h" +#include "access/parallel.h" #include "access/relscan.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/transam.h" #include "executor/executor.h" +#include "jit/jit.h" #include "mb/pg_wchar.h" #include "nodes/nodeFuncs.h" #include "parser/parsetree.h" +#include "partitioning/partdesc.h" #include "storage/lmgr.h" #include "utils/builtins.h" #include "utils/memutils.h" @@ -105,6 +113,9 @@ CreateExecutorState(void) estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */ estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */ estate->es_range_table = NIL; + estate->es_range_table_size = 0; + estate->es_relations = NULL; + estate->es_rowmarks = NULL; estate->es_plannedstmt = NULL; estate->es_junkFilter = NULL; @@ -121,9 +132,6 @@ CreateExecutorState(void) estate->es_tuple_routing_result_relations = NIL; estate->es_trig_target_relations = NIL; - estate->es_trig_tuple_slot = NULL; - estate->es_trig_oldtup_slot = NULL; - estate->es_trig_newtup_slot = NULL; estate->es_param_list_info = NULL; estate->es_param_exec_vals = NULL; @@ -134,10 +142,7 @@ CreateExecutorState(void) estate->es_tupleTable = NIL; - estate->es_rowMarks = NIL; - estate->es_processed = 0; - estate->es_lastoid = InvalidOid; estate->es_top_eflags = 0; estate->es_instrument = 0; @@ -151,9 +156,6 @@ CreateExecutorState(void) estate->es_per_tuple_exprcontext = NULL; - estate->es_epqTuple = NULL; - estate->es_epqTupleSet = NULL; - estate->es_epqScanDone = NULL; estate->es_sourceText = NULL; estate->es_use_parallel_mode = false; @@ -174,11 +176,11 @@ CreateExecutorState(void) * * Release an EState along with all remaining working storage. * - * Note: this is not responsible for releasing non-memory resources, - * such as open relations or buffer pins. But it will shut down any - * still-active ExprContexts within the EState. That is sufficient - * cleanup for situations where the EState has only been used for expression - * evaluation, and not to run a complete Plan. + * Note: this is not responsible for releasing non-memory resources, such as + * open relations or buffer pins. But it will shut down any still-active + * ExprContexts within the EState and deallocate associated JITed expressions. + * That is sufficient cleanup for situations where the EState has only been + * used for expression evaluation, and not to run a complete Plan. * * This can be called in any memory context ... so long as it's not one * of the ones to be freed. @@ -204,6 +206,20 @@ FreeExecutorState(EState *estate) /* FreeExprContext removed the list link for us */ } + /* release JIT context, if allocated */ + if (estate->es_jit) + { + jit_release_context(estate->es_jit); + estate->es_jit = NULL; + } + + /* release partition directory, if allocated */ + if (estate->es_partition_directory) + { + DestroyPartitionDirectory(estate->es_partition_directory); + estate->es_partition_directory = NULL; + } + /* * Free the per-query memory context, thereby releasing all working * memory, including the EState node itself. @@ -437,9 +453,36 @@ ExecAssignExprContext(EState *estate, PlanState *planstate) TupleDesc ExecGetResultType(PlanState *planstate) { - TupleTableSlot *slot = planstate->ps_ResultTupleSlot; + return planstate->ps_ResultTupleDesc; +} + +/* + * ExecGetResultSlotOps - information about node's type of result slot + */ +const TupleTableSlotOps * +ExecGetResultSlotOps(PlanState *planstate, bool *isfixed) +{ + if (planstate->resultopsset && planstate->resultops) + { + if (isfixed) + *isfixed = planstate->resultopsfixed; + return planstate->resultops; + } - return slot->tts_tupleDescriptor; + if (isfixed) + { + if (planstate->resultopsset) + *isfixed = planstate->resultopsfixed; + else if (planstate->ps_ResultTupleSlot) + *isfixed = TTS_FIXED(planstate->ps_ResultTupleSlot); + else + *isfixed = false; + } + + if (!planstate->ps_ResultTupleSlot) + return &TTSOpsVirtual; + + return planstate->ps_ResultTupleSlot->tts_ops; } @@ -480,9 +523,23 @@ ExecConditionalAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc, planstate->plan->targetlist, varno, inputDesc)) + { planstate->ps_ProjInfo = NULL; + planstate->resultopsset = planstate->scanopsset; + planstate->resultopsfixed = planstate->scanopsfixed; + planstate->resultops = planstate->scanops; + } else + { + if (!planstate->ps_ResultTupleSlot) + { + ExecInitResultSlot(planstate, &TTSOpsVirtual); + planstate->resultops = &TTSOpsVirtual; + planstate->resultopsfixed = true; + planstate->resultopsset = true; + } ExecAssignProjectionInfo(planstate, inputDesc); + } } static bool @@ -490,7 +547,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc { int numattrs = tupdesc->natts; int attrno; - bool hasoid; ListCell *tlist_item = list_head(tlist); /* Check the tlist attributes */ @@ -529,20 +585,12 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc var->vartypmod != -1)) return false; /* type mismatch */ - tlist_item = lnext(tlist_item); + tlist_item = lnext(tlist, tlist_item); } if (tlist_item) return false; /* tlist too long */ - /* - * If the plan context requires a particular hasoid setting, then that has - * to match, too. - */ - if (ExecContextForcesOids(ps, &hasoid) && - hasoid != tupdesc->tdhasoid) - return false; - return true; } @@ -591,11 +639,13 @@ ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc) } /* ---------------- - * ExecCreateSlotFromOuterPlan + * ExecCreateScanSlotFromOuterPlan * ---------------- */ void -ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate) +ExecCreateScanSlotFromOuterPlan(EState *estate, + ScanState *scanstate, + const TupleTableSlotOps *tts_ops) { PlanState *outerPlan; TupleDesc tupDesc; @@ -603,7 +653,7 @@ ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate) outerPlan = outerPlanState(scanstate); tupDesc = ExecGetResultType(outerPlan); - ExecInitScanTupleSlot(estate, scanstate, tupDesc); + ExecInitScanTupleSlot(estate, scanstate, tupDesc, tts_ops); } /* ---------------------------------------------------------------- @@ -611,6 +661,10 @@ ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate) * * Detect whether a relation (identified by rangetable index) * is one of the target relations of the query. + * + * Note: This is currently no longer used in core. We keep it around + * because FDWs may wish to use it to determine if their foreign table + * is a target relation. * ---------------------------------------------------------------- */ bool @@ -633,39 +687,15 @@ ExecRelationIsTargetRelation(EState *estate, Index scanrelid) * * Open the heap relation to be scanned by a base-level scan plan node. * This should be called during the node's ExecInit routine. - * - * By default, this acquires AccessShareLock on the relation. However, - * if the relation was already locked by InitPlan, we don't need to acquire - * any additional lock. This saves trips to the shared lock manager. * ---------------------------------------------------------------- */ Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags) { Relation rel; - Oid reloid; - LOCKMODE lockmode; - - /* - * Determine the lock type we need. First, scan to see if target relation - * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE - * relation. In either of those cases, we got the lock already. - */ - lockmode = AccessShareLock; - if (ExecRelationIsTargetRelation(estate, scanrelid)) - lockmode = NoLock; - else - { - /* Keep this check in sync with InitPlan! */ - ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true); - - if (erm != NULL && erm->relation != NULL) - lockmode = NoLock; - } - /* Open the relation and acquire lock as needed */ - reloid = getrelid(scanrelid, estate->es_range_table); - rel = heap_open(reloid, lockmode); + /* Open the relation. */ + rel = ExecGetRangeTableRelation(estate, scanrelid); /* * Complain if we're attempting a scan of an unscannable relation, except @@ -683,24 +713,85 @@ ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags) return rel; } -/* ---------------------------------------------------------------- - * ExecCloseScanRelation - * - * Close the heap relation scanned by a base-level scan plan node. - * This should be called during the node's ExecEnd routine. - * - * Currently, we do not release the lock acquired by ExecOpenScanRelation. - * This lock should be held till end of transaction. (There is a faction - * that considers this too much locking, however.) +/* + * ExecInitRangeTable + * Set up executor's range-table-related data * - * If we did want to release the lock, we'd have to repeat the logic in - * ExecOpenScanRelation in order to figure out what to release. - * ---------------------------------------------------------------- + * In addition to the range table proper, initialize arrays that are + * indexed by rangetable index. */ void -ExecCloseScanRelation(Relation scanrel) +ExecInitRangeTable(EState *estate, List *rangeTable) { - heap_close(scanrel, NoLock); + /* Remember the range table List as-is */ + estate->es_range_table = rangeTable; + + /* Set size of associated arrays */ + estate->es_range_table_size = list_length(rangeTable); + + /* + * Allocate an array to store an open Relation corresponding to each + * rangetable entry, and initialize entries to NULL. Relations are opened + * and stored here as needed. + */ + estate->es_relations = (Relation *) + palloc0(estate->es_range_table_size * sizeof(Relation)); + + /* + * es_rowmarks is also parallel to the es_range_table, but it's allocated + * only if needed. + */ + estate->es_rowmarks = NULL; +} + +/* + * ExecGetRangeTableRelation + * Open the Relation for a range table entry, if not already done + * + * The Relations will be closed again in ExecEndPlan(). + */ +Relation +ExecGetRangeTableRelation(EState *estate, Index rti) +{ + Relation rel; + + Assert(rti > 0 && rti <= estate->es_range_table_size); + + rel = estate->es_relations[rti - 1]; + if (rel == NULL) + { + /* First time through, so open the relation */ + RangeTblEntry *rte = exec_rt_fetch(rti, estate); + + Assert(rte->rtekind == RTE_RELATION); + + if (!IsParallelWorker()) + { + /* + * In a normal query, we should already have the appropriate lock, + * but verify that through an Assert. Since there's already an + * Assert inside table_open that insists on holding some lock, it + * seems sufficient to check this only when rellockmode is higher + * than the minimum. + */ + rel = table_open(rte->relid, NoLock); + Assert(rte->rellockmode == AccessShareLock || + CheckRelationLockedByMe(rel, rte->rellockmode, false)); + } + else + { + /* + * If we are a parallel worker, we need to obtain our own local + * lock on the relation. This ensures sane behavior in case the + * parent process exits before we do. + */ + rel = table_open(rte->relid, rte->rellockmode); + } + + estate->es_relations[rti - 1] = rel; + } + + return rel; } /* @@ -855,61 +946,6 @@ ShutdownExprContext(ExprContext *econtext, bool isCommit) MemoryContextSwitchTo(oldcontext); } -/* - * ExecLockNonLeafAppendTables - * - * Locks, if necessary, the tables indicated by the RT indexes contained in - * the partitioned_rels list. These are the non-leaf tables in the partition - * tree controlled by a given Append or MergeAppend node. - */ -void -ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate) -{ - PlannedStmt *stmt = estate->es_plannedstmt; - ListCell *lc; - - foreach(lc, partitioned_rels) - { - ListCell *l; - Index rti = lfirst_int(lc); - bool is_result_rel = false; - Oid relid = getrelid(rti, estate->es_range_table); - - /* If this is a result relation, already locked in InitPlan */ - foreach(l, stmt->nonleafResultRelations) - { - if (rti == lfirst_int(l)) - { - is_result_rel = true; - break; - } - } - - /* - * Not a result relation; check if there is a RowMark that requires - * taking a RowShareLock on this rel. - */ - if (!is_result_rel) - { - PlanRowMark *rc = NULL; - - foreach(l, stmt->rowMarks) - { - if (((PlanRowMark *) lfirst(l))->rti == rti) - { - rc = lfirst(l); - break; - } - } - - if (rc && RowMarkRequiresRowShareLock(rc->markType)) - LockRelationOid(relid, RowShareLock); - else - LockRelationOid(relid, AccessShareLock); - } - } -} - /* * GetAttributeByName * GetAttributeByNum @@ -1060,3 +1096,69 @@ ExecCleanTargetListLength(List *targetlist) } return len; } + +/* + * Return a relInfo's tuple slot for a trigger's OLD tuples. + */ +TupleTableSlot * +ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo) +{ + if (relInfo->ri_TrigOldSlot == NULL) + { + Relation rel = relInfo->ri_RelationDesc; + MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + + relInfo->ri_TrigOldSlot = + ExecInitExtraTupleSlot(estate, + RelationGetDescr(rel), + table_slot_callbacks(rel)); + + MemoryContextSwitchTo(oldcontext); + } + + return relInfo->ri_TrigOldSlot; +} + +/* + * Return a relInfo's tuple slot for a trigger's NEW tuples. + */ +TupleTableSlot * +ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo) +{ + if (relInfo->ri_TrigNewSlot == NULL) + { + Relation rel = relInfo->ri_RelationDesc; + MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + + relInfo->ri_TrigNewSlot = + ExecInitExtraTupleSlot(estate, + RelationGetDescr(rel), + table_slot_callbacks(rel)); + + MemoryContextSwitchTo(oldcontext); + } + + return relInfo->ri_TrigNewSlot; +} + +/* + * Return a relInfo's tuple slot for processing returning tuples. + */ +TupleTableSlot * +ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo) +{ + if (relInfo->ri_ReturningSlot == NULL) + { + Relation rel = relInfo->ri_RelationDesc; + MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt); + + relInfo->ri_ReturningSlot = + ExecInitExtraTupleSlot(estate, + RelationGetDescr(rel), + table_slot_callbacks(rel)); + + MemoryContextSwitchTo(oldcontext); + } + + return relInfo->ri_ReturningSlot; +} diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 23545896d4d..83337c2eed4 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -3,7 +3,7 @@ * functions.c * Execution of SQL-language functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -146,24 +146,24 @@ typedef struct SQLFunctionParseInfo /* non-export function prototypes */ static Node *sql_fn_param_ref(ParseState *pstate, ParamRef *pref); static Node *sql_fn_post_column_ref(ParseState *pstate, - ColumnRef *cref, Node *var); + ColumnRef *cref, Node *var); static Node *sql_fn_make_param(SQLFunctionParseInfoPtr pinfo, - int paramno, int location); + int paramno, int location); static Node *sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo, - const char *paramname, int location); + const char *paramname, int location); static List *init_execution_state(List *queryTree_list, - SQLFunctionCachePtr fcache, - bool lazyEvalOK); + SQLFunctionCachePtr fcache, + bool lazyEvalOK); static void init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK); static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache); static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache); static void postquel_end(execution_state *es); static void postquel_sub_params(SQLFunctionCachePtr fcache, - FunctionCallInfo fcinfo); + FunctionCallInfo fcinfo); static Datum postquel_get_single_result(TupleTableSlot *slot, - FunctionCallInfo fcinfo, - SQLFunctionCachePtr fcache, - MemoryContext resultcontext); + FunctionCallInfo fcinfo, + SQLFunctionCachePtr fcache, + MemoryContext resultcontext); static void sql_exec_error_callback(void *arg); static void ShutdownSQLFunction(Datum arg); static void sqlfunction_startup(DestReceiver *self, int operation, TupleDesc typeinfo); @@ -719,8 +719,7 @@ init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK) fcache->pinfo, NULL); queryTree_list = lappend(queryTree_list, queryTree_sublist); - flat_query_list = list_concat(flat_query_list, - list_copy(queryTree_sublist)); + flat_query_list = list_concat(flat_query_list, queryTree_sublist); } check_sql_fn_statements(flat_query_list); @@ -906,21 +905,10 @@ postquel_sub_params(SQLFunctionCachePtr fcache, if (nargs > 0) { ParamListInfo paramLI; - int i; if (fcache->paramLI == NULL) { - paramLI = (ParamListInfo) - palloc(offsetof(ParamListInfoData, params) + - nargs * sizeof(ParamExternData)); - /* we have static list of params, so no hooks needed */ - paramLI->paramFetch = NULL; - paramLI->paramFetchArg = NULL; - paramLI->paramCompile = NULL; - paramLI->paramCompileArg = NULL; - paramLI->parserSetup = NULL; - paramLI->parserSetupArg = NULL; - paramLI->numParams = nargs; + paramLI = makeParamList(nargs); fcache->paramLI = paramLI; } else @@ -929,12 +917,12 @@ postquel_sub_params(SQLFunctionCachePtr fcache, Assert(paramLI->numParams == nargs); } - for (i = 0; i < nargs; i++) + for (int i = 0; i < nargs; i++) { ParamExternData *prm = ¶mLI->params[i]; - prm->value = fcinfo->arg[i]; - prm->isnull = fcinfo->argnull[i]; + prm->value = fcinfo->args[i].value; + prm->isnull = fcinfo->args[i].isnull; prm->pflags = 0; prm->ptype = fcache->pinfo->argtypes[i]; } @@ -969,7 +957,7 @@ postquel_get_single_result(TupleTableSlot *slot, { /* We must return the whole tuple as a Datum. */ fcinfo->isnull = false; - value = ExecFetchSlotTupleDatum(slot); + value = ExecFetchSlotHeapTupleDatum(slot); } else { @@ -1192,7 +1180,7 @@ fmgr_sql(PG_FUNCTION_ARGS) es = es->next; while (!es) { - eslc = lnext(eslc); + eslc = lnext(eslist, eslc); if (!eslc) break; /* end of function */ @@ -1717,7 +1705,8 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, /* Set up junk filter if needed */ if (junkFilter) - *junkFilter = ExecInitJunkFilter(tlist, false, NULL); + *junkFilter = ExecInitJunkFilter(tlist, + MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple)); } else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID) { @@ -1770,7 +1759,12 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, } /* Set up junk filter if needed */ if (junkFilter) - *junkFilter = ExecInitJunkFilter(tlist, false, NULL); + { + TupleTableSlot *slot = + MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple); + + *junkFilter = ExecInitJunkFilter(tlist, slot); + } return false; /* NOT returning whole tuple */ } } @@ -1786,7 +1780,12 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, * what the caller expects will happen at runtime. */ if (junkFilter) - *junkFilter = ExecInitJunkFilter(tlist, false, NULL); + { + TupleTableSlot *slot; + + slot = MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple); + *junkFilter = ExecInitJunkFilter(tlist, slot); + } return true; } Assert(tupdesc); @@ -1927,9 +1926,14 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList, /* Set up junk filter if needed */ if (junkFilter) + { + TupleTableSlot *slot = + MakeSingleTupleTableSlot(NULL, &TTSOpsMinimalTuple); + *junkFilter = ExecInitJunkFilterConversion(tlist, CreateTupleDescCopy(tupdesc), - NULL); + slot); + } /* Report that we are returning entire tuple result */ return true; diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c index 86252cee1f3..bd36f8ee685 100644 --- a/src/backend/executor/instrument.c +++ b/src/backend/executor/instrument.c @@ -4,7 +4,7 @@ * functions for instrumentation of plan execution * * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/executor/instrument.c @@ -22,7 +22,7 @@ static BufferUsage save_pgBufferUsage; static void BufferUsageAdd(BufferUsage *dst, const BufferUsage *add); static void BufferUsageAccumDiff(BufferUsage *dst, - const BufferUsage *add, const BufferUsage *sub); + const BufferUsage *add, const BufferUsage *sub); /* Allocate new instrumentation structure(s) */ @@ -62,13 +62,9 @@ InstrInit(Instrumentation *instr, int instrument_options) void InstrStartNode(Instrumentation *instr) { - if (instr->need_timer) - { - if (INSTR_TIME_IS_ZERO(instr->starttime)) - INSTR_TIME_SET_CURRENT(instr->starttime); - else - elog(ERROR, "InstrStartNode called twice in a row"); - } + if (instr->need_timer && + !INSTR_TIME_SET_CURRENT_LAZY(instr->starttime)) + elog(ERROR, "InstrStartNode called twice in a row"); /* save buffer usage totals at node entry, if needed */ if (instr->need_bufusage) @@ -156,6 +152,7 @@ InstrAggNode(Instrumentation *dst, Instrumentation *add) dst->startup += add->startup; dst->total += add->total; dst->ntuples += add->ntuples; + dst->ntuples2 += add->ntuples2; dst->nloops += add->nloops; dst->nfiltered1 += add->nfiltered1; dst->nfiltered2 += add->nfiltered2; diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c index 1b1334006fa..58c376aeb74 100644 --- a/src/backend/executor/nodeAgg.c +++ b/src/backend/executor/nodeAgg.c @@ -205,7 +205,7 @@ * to filter expressions having to be evaluated early, and allows to JIT * the entire expression into one native function. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -226,12 +226,12 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/tlist.h" +#include "optimizer/optimizer.h" #include "parser/parse_agg.h" #include "parser/parse_coerce.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/expandeddatum.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/syscache.h" @@ -243,32 +243,32 @@ static void select_current_set(AggState *aggstate, int setno, bool is_hash); static void initialize_phase(AggState *aggstate, int newphase); static TupleTableSlot *fetch_input_tuple(AggState *aggstate); static void initialize_aggregates(AggState *aggstate, - AggStatePerGroup *pergroups, - int numReset); + AggStatePerGroup *pergroups, + int numReset); static void advance_transition_function(AggState *aggstate, - AggStatePerTrans pertrans, - AggStatePerGroup pergroupstate); + AggStatePerTrans pertrans, + AggStatePerGroup pergroupstate); static void advance_aggregates(AggState *aggstate); static void process_ordered_aggregate_single(AggState *aggstate, - AggStatePerTrans pertrans, - AggStatePerGroup pergroupstate); + AggStatePerTrans pertrans, + AggStatePerGroup pergroupstate); static void process_ordered_aggregate_multi(AggState *aggstate, - AggStatePerTrans pertrans, - AggStatePerGroup pergroupstate); + AggStatePerTrans pertrans, + AggStatePerGroup pergroupstate); static void finalize_aggregate(AggState *aggstate, - AggStatePerAgg peragg, - AggStatePerGroup pergroupstate, - Datum *resultVal, bool *resultIsNull); + AggStatePerAgg peragg, + AggStatePerGroup pergroupstate, + Datum *resultVal, bool *resultIsNull); static void finalize_partialaggregate(AggState *aggstate, - AggStatePerAgg peragg, - AggStatePerGroup pergroupstate, - Datum *resultVal, bool *resultIsNull); + AggStatePerAgg peragg, + AggStatePerGroup pergroupstate, + Datum *resultVal, bool *resultIsNull); static void prepare_projection_slot(AggState *aggstate, - TupleTableSlot *slot, - int currentSet); + TupleTableSlot *slot, + int currentSet); static void finalize_aggregates(AggState *aggstate, - AggStatePerAgg peragg, - AggStatePerGroup pergroup); + AggStatePerAgg peragg, + AggStatePerGroup pergroup); static TupleTableSlot *project_aggregates(AggState *aggstate); static Bitmapset *find_unaggregated_cols(AggState *aggstate); static bool find_unaggregated_cols_walker(Node *node, Bitmapset **colnos); @@ -280,19 +280,19 @@ static void agg_fill_hash_table(AggState *aggstate); static TupleTableSlot *agg_retrieve_hash_table(AggState *aggstate); static Datum GetAggInitVal(Datum textInitVal, Oid transtype); static void build_pertrans_for_aggref(AggStatePerTrans pertrans, - AggState *aggstate, EState *estate, - Aggref *aggref, Oid aggtransfn, Oid aggtranstype, - Oid aggserialfn, Oid aggdeserialfn, - Datum initValue, bool initValueIsNull, - Oid *inputTypes, int numArguments); -static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, - int lastaggno, List **same_input_transnos); -static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, - bool sharable, - Oid aggtransfn, Oid aggtranstype, - Oid aggserialfn, Oid aggdeserialfn, - Datum initValue, bool initValueIsNull, - List *transnos); + AggState *aggstate, EState *estate, + Aggref *aggref, Oid aggtransfn, Oid aggtranstype, + Oid aggserialfn, Oid aggdeserialfn, + Datum initValue, bool initValueIsNull, + Oid *inputTypes, int numArguments); +static int find_compatible_peragg(Aggref *newagg, AggState *aggstate, + int lastaggno, List **same_input_transnos); +static int find_compatible_pertrans(AggState *aggstate, Aggref *newagg, + bool shareable, + Oid aggtransfn, Oid aggtranstype, + Oid aggserialfn, Oid aggdeserialfn, + Datum initValue, bool initValueIsNull, + List *transnos); /* @@ -553,7 +553,7 @@ advance_transition_function(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroupstate) { - FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + FunctionCallInfo fcinfo = pertrans->transfn_fcinfo; MemoryContext oldContext; Datum newVal; @@ -568,7 +568,7 @@ advance_transition_function(AggState *aggstate, for (i = 1; i <= numTransInputs; i++) { - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) return; } if (pergroupstate->noTransValue) @@ -584,7 +584,7 @@ advance_transition_function(AggState *aggstate, */ oldContext = MemoryContextSwitchTo( aggstate->curaggcontext->ecxt_per_tuple_memory); - pergroupstate->transValue = datumCopy(fcinfo->arg[1], + pergroupstate->transValue = datumCopy(fcinfo->args[1].value, pertrans->transtypeByVal, pertrans->transtypeLen); pergroupstate->transValueIsNull = false; @@ -613,8 +613,8 @@ advance_transition_function(AggState *aggstate, /* * OK to call the transition function */ - fcinfo->arg[0] = pergroupstate->transValue; - fcinfo->argnull[0] = pergroupstate->transValueIsNull; + fcinfo->args[0].value = pergroupstate->transValue; + fcinfo->args[0].isnull = pergroupstate->transValueIsNull; fcinfo->isnull = false; /* just in case transfn doesn't set it */ newVal = FunctionCallInvoke(fcinfo); @@ -717,7 +717,7 @@ process_ordered_aggregate_single(AggState *aggstate, bool isDistinct = (pertrans->numDistinctCols > 0); Datum newAbbrevVal = (Datum) 0; Datum oldAbbrevVal = (Datum) 0; - FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + FunctionCallInfo fcinfo = pertrans->transfn_fcinfo; Datum *newVal; bool *isNull; @@ -726,8 +726,8 @@ process_ordered_aggregate_single(AggState *aggstate, tuplesort_performsort(pertrans->sortstates[aggstate->current_set]); /* Load the column into argument 1 (arg 0 will be transition value) */ - newVal = fcinfo->arg + 1; - isNull = fcinfo->argnull + 1; + newVal = &fcinfo->args[1].value; + isNull = &fcinfo->args[1].isnull; /* * Note: if input type is pass-by-ref, the datums returned by the sort are @@ -747,16 +747,15 @@ process_ordered_aggregate_single(AggState *aggstate, /* * If DISTINCT mode, and not distinct from prior, skip it. - * - * Note: we assume equality functions don't care about collation. */ if (isDistinct && haveOldVal && ((oldIsNull && *isNull) || (!oldIsNull && !*isNull && oldAbbrevVal == newAbbrevVal && - DatumGetBool(FunctionCall2(&pertrans->equalfnOne, - oldVal, *newVal))))) + DatumGetBool(FunctionCall2Coll(&pertrans->equalfnOne, + pertrans->aggCollation, + oldVal, *newVal))))) { /* equal to prior, so forget this one */ if (!pertrans->inputtypeByVal && !*isNull) @@ -803,7 +802,7 @@ process_ordered_aggregate_multi(AggState *aggstate, AggStatePerGroup pergroupstate) { ExprContext *tmpcontext = aggstate->tmpcontext; - FunctionCallInfo fcinfo = &pertrans->transfn_fcinfo; + FunctionCallInfo fcinfo = pertrans->transfn_fcinfo; TupleTableSlot *slot1 = pertrans->sortslot; TupleTableSlot *slot2 = pertrans->uniqslot; int numTransInputs = pertrans->numTransInputs; @@ -843,8 +842,8 @@ process_ordered_aggregate_multi(AggState *aggstate, /* Start from 1, since the 0th arg will be the transition value */ for (i = 0; i < numTransInputs; i++) { - fcinfo->arg[i + 1] = slot1->tts_values[i]; - fcinfo->argnull[i + 1] = slot1->tts_isnull[i]; + fcinfo->args[i + 1].value = slot1->tts_values[i]; + fcinfo->args[i + 1].isnull = slot1->tts_isnull[i]; } advance_transition_function(aggstate, pertrans, pergroupstate); @@ -884,7 +883,7 @@ process_ordered_aggregate_multi(AggState *aggstate, * This function handles only one grouping set (already set in * aggstate->current_set). * - * The finalfunction will be run, and the result delivered, in the + * The finalfn will be run, and the result delivered, in the * output-tuple context; caller's CurrentMemoryContext does not matter. * * The finalfn uses the state as set in the transno. This also might be @@ -897,7 +896,7 @@ finalize_aggregate(AggState *aggstate, AggStatePerGroup pergroupstate, Datum *resultVal, bool *resultIsNull) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); bool anynull = false; MemoryContext oldContext; int i; @@ -917,10 +916,10 @@ finalize_aggregate(AggState *aggstate, { ExprState *expr = (ExprState *) lfirst(lc); - fcinfo.arg[i] = ExecEvalExpr(expr, - aggstate->ss.ps.ps_ExprContext, - &fcinfo.argnull[i]); - anynull |= fcinfo.argnull[i]; + fcinfo->args[i].value = ExecEvalExpr(expr, + aggstate->ss.ps.ps_ExprContext, + &fcinfo->args[i].isnull); + anynull |= fcinfo->args[i].isnull; i++; } @@ -934,27 +933,28 @@ finalize_aggregate(AggState *aggstate, /* set up aggstate->curperagg for AggGetAggref() */ aggstate->curperagg = peragg; - InitFunctionCallInfoData(fcinfo, &peragg->finalfn, + InitFunctionCallInfoData(*fcinfo, &peragg->finalfn, numFinalArgs, pertrans->aggCollation, (void *) aggstate, NULL); /* Fill in the transition state value */ - fcinfo.arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue, - pergroupstate->transValueIsNull, - pertrans->transtypeLen); - fcinfo.argnull[0] = pergroupstate->transValueIsNull; + fcinfo->args[0].value = + MakeExpandedObjectReadOnly(pergroupstate->transValue, + pergroupstate->transValueIsNull, + pertrans->transtypeLen); + fcinfo->args[0].isnull = pergroupstate->transValueIsNull; anynull |= pergroupstate->transValueIsNull; /* Fill any remaining argument positions with nulls */ for (; i < numFinalArgs; i++) { - fcinfo.arg[i] = (Datum) 0; - fcinfo.argnull[i] = true; + fcinfo->args[i].value = (Datum) 0; + fcinfo->args[i].isnull = true; anynull = true; } - if (fcinfo.flinfo->fn_strict && anynull) + if (fcinfo->flinfo->fn_strict && anynull) { /* don't call a strict function with NULL inputs */ *resultVal = (Datum) 0; @@ -962,8 +962,8 @@ finalize_aggregate(AggState *aggstate, } else { - *resultVal = FunctionCallInvoke(&fcinfo); - *resultIsNull = fcinfo.isnull; + *resultVal = FunctionCallInvoke(fcinfo); + *resultIsNull = fcinfo->isnull; } aggstate->curperagg = NULL; } @@ -1018,12 +1018,13 @@ finalize_partialaggregate(AggState *aggstate, } else { - FunctionCallInfo fcinfo = &pertrans->serialfn_fcinfo; + FunctionCallInfo fcinfo = pertrans->serialfn_fcinfo; - fcinfo->arg[0] = MakeExpandedObjectReadOnly(pergroupstate->transValue, - pergroupstate->transValueIsNull, - pertrans->transtypeLen); - fcinfo->argnull[0] = pergroupstate->transValueIsNull; + fcinfo->args[0].value = + MakeExpandedObjectReadOnly(pergroupstate->transValue, + pergroupstate->transValueIsNull, + pertrans->transtypeLen); + fcinfo->args[0].isnull = pergroupstate->transValueIsNull; *resultVal = FunctionCallInvoke(fcinfo); *resultIsNull = fcinfo->isnull; @@ -1080,7 +1081,7 @@ prepare_projection_slot(AggState *aggstate, TupleTableSlot *slot, int currentSet aggstate->grouped_cols = grouped_cols; - if (slot->tts_isempty) + if (TTS_EMPTY(slot)) { /* * Force all values to be NULL if working on an empty input tuple @@ -1245,7 +1246,7 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos) } /* - * Initialize the hash table(s) to empty. + * (Re-)initialize the hash table(s) to empty. * * To implement hashed aggregation, we need a hashtable that stores a * representative tuple and an array of AggStatePerGroup structs for each @@ -1256,9 +1257,9 @@ find_unaggregated_cols_walker(Node *node, Bitmapset **colnos) * We have a separate hashtable and associated perhash data structure for each * grouping set for which we're doing hashing. * - * The hash tables always live in the hashcontext's per-tuple memory context - * (there is only one of these for all tables together, since they are all - * reset at the same time). + * The contents of the hash tables always live in the hashcontext's per-tuple + * memory context (there is only one of these for all tables together, since + * they are all reset at the same time). */ static void build_hash_table(AggState *aggstate) @@ -1277,17 +1278,22 @@ build_hash_table(AggState *aggstate) Assert(perhash->aggnode->numGroups > 0); - perhash->hashtable = BuildTupleHashTable(&aggstate->ss.ps, - perhash->hashslot->tts_tupleDescriptor, - perhash->numCols, - perhash->hashGrpColIdxHash, - perhash->eqfuncoids, - perhash->hashfunctions, - perhash->aggnode->numGroups, - additionalsize, - aggstate->hashcontext->ecxt_per_tuple_memory, - tmpmem, - DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit)); + if (perhash->hashtable) + ResetTupleHashTable(perhash->hashtable); + else + perhash->hashtable = BuildTupleHashTableExt(&aggstate->ss.ps, + perhash->hashslot->tts_tupleDescriptor, + perhash->numCols, + perhash->hashGrpColIdxHash, + perhash->eqfuncoids, + perhash->hashfunctions, + perhash->aggnode->grpCollations, + perhash->aggnode->numGroups, + additionalsize, + aggstate->ss.ps.state->es_query_cxt, + aggstate->hashcontext->ecxt_per_tuple_memory, + tmpmem, + DO_AGGSPLIT_SKIPFINAL(aggstate->aggsplit)); } } @@ -1307,9 +1313,14 @@ build_hash_table(AggState *aggstate) * by themselves, and secondly ctids for row-marks. * * To eliminate duplicates, we build a bitmapset of the needed columns, and - * then build an array of the columns included in the hashtable. Note that - * the array is preserved over ExecReScanAgg, so we allocate it in the - * per-query context (unlike the hash table itself). + * then build an array of the columns included in the hashtable. We might + * still have duplicates if the passed-in grpColIdx has them, which can happen + * in edge cases from semijoins/distinct; these can't always be removed, + * because it's not certain that the duplicate cols will be using the same + * hash function. + * + * Note that the array is preserved over ExecReScanAgg, so we allocate it in + * the per-query context (unlike the hash table itself). */ static void find_hash_columns(AggState *aggstate) @@ -1330,6 +1341,7 @@ find_hash_columns(AggState *aggstate) AttrNumber *grpColIdx = perhash->aggnode->grpColIdx; List *hashTlist = NIL; TupleDesc hashDesc; + int maxCols; int i; perhash->largestGrpColIdx = 0; @@ -1354,15 +1366,24 @@ find_hash_columns(AggState *aggstate) colnos = bms_del_member(colnos, attnum); } } - /* Add in all the grouping columns */ - for (i = 0; i < perhash->numCols; i++) - colnos = bms_add_member(colnos, grpColIdx[i]); + + /* + * Compute maximum number of input columns accounting for possible + * duplications in the grpColIdx array, which can happen in some edge + * cases where HashAggregate was generated as part of a semijoin or a + * DISTINCT. + */ + maxCols = bms_num_members(colnos) + perhash->numCols; perhash->hashGrpColIdxInput = - palloc(bms_num_members(colnos) * sizeof(AttrNumber)); + palloc(maxCols * sizeof(AttrNumber)); perhash->hashGrpColIdxHash = palloc(perhash->numCols * sizeof(AttrNumber)); + /* Add all the grouping columns to colnos */ + for (i = 0; i < perhash->numCols; i++) + colnos = bms_add_member(colnos, grpColIdx[i]); + /* * First build mapping for columns directly hashed. These are the * first, because they'll be accessed when computing hash values and @@ -1396,14 +1417,15 @@ find_hash_columns(AggState *aggstate) Max(varNumber + 1, perhash->largestGrpColIdx); } - hashDesc = ExecTypeFromTL(hashTlist, false); + hashDesc = ExecTypeFromTL(hashTlist); execTuplesHashPrepare(perhash->numCols, perhash->aggnode->grpOperators, &perhash->eqfuncoids, &perhash->hashfunctions); perhash->hashslot = - ExecAllocTableSlot(&estate->es_tupleTable, hashDesc); + ExecAllocTableSlot(&estate->es_tupleTable, hashDesc, + &TTSOpsMinimalTuple); list_free(hashTlist); bms_free(colnos); @@ -1740,7 +1762,7 @@ agg_retrieve_direct(AggState *aggstate) * Make a copy of the first input tuple; we will use this * for comparisons (in group mode) and for projection. */ - aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot); + aggstate->grp_firstTuple = ExecCopySlotHeapTuple(outerslot); } else { @@ -1799,10 +1821,8 @@ agg_retrieve_direct(AggState *aggstate) * reserved for it. The tuple will be deleted when it is * cleared from the slot. */ - ExecStoreTuple(aggstate->grp_firstTuple, - firstSlot, - InvalidBuffer, - true); + ExecForceStoreHeapTuple(aggstate->grp_firstTuple, + firstSlot, true); aggstate->grp_firstTuple = NULL; /* don't keep two pointers */ /* set up for first advance_aggregates call */ @@ -1858,7 +1878,7 @@ agg_retrieve_direct(AggState *aggstate) if (!ExecQual(aggstate->phase->eqfunctions[node->numCols - 1], tmpcontext)) { - aggstate->grp_firstTuple = ExecCopySlotTuple(outerslot); + aggstate->grp_firstTuple = ExecCopySlotHeapTuple(outerslot); break; } } @@ -2212,15 +2232,47 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* * initialize source tuple type. */ - ExecCreateScanSlotFromOuterPlan(estate, &aggstate->ss); + aggstate->ss.ps.outerops = + ExecGetResultSlotOps(outerPlanState(&aggstate->ss), + &aggstate->ss.ps.outeropsfixed); + aggstate->ss.ps.outeropsset = true; + + ExecCreateScanSlotFromOuterPlan(estate, &aggstate->ss, + aggstate->ss.ps.outerops); scanDesc = aggstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; - if (node->chain) - aggstate->sort_slot = ExecInitExtraTupleSlot(estate, scanDesc); + + /* + * If there are more than two phases (including a potential dummy phase + * 0), input will be resorted using tuplesort. Need a slot for that. + */ + if (numPhases > 2) + { + aggstate->sort_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + + /* + * The output of the tuplesort, and the output from the outer child + * might not use the same type of slot. In most cases the child will + * be a Sort, and thus return a TTSOpsMinimalTuple type slot - but the + * input can also be be presorted due an index, in which case it could + * be a different type of slot. + * + * XXX: For efficiency it would be good to instead/additionally + * generate expressions with corresponding settings of outerops* for + * the individual phases - deforming is often a bottleneck for + * aggregations with lots of rows per group. If there's multiple + * sorts, we know that all but the first use TTSOpsMinimalTuple (via + * the nodeAgg.c internal tuplesort). + */ + if (aggstate->ss.ps.outeropsfixed && + aggstate->ss.ps.outerops != &TTSOpsMinimalTuple) + aggstate->ss.ps.outeropsfixed = false; + } /* * Initialize result type, slot and projection. */ - ExecInitResultTupleSlotTL(estate, &aggstate->ss.ps); + ExecInitResultTupleSlotTL(&aggstate->ss.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&aggstate->ss.ps, NULL); /* @@ -2365,7 +2417,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* for each grouping set */ for (i = 0; i < phasedata->numsets; i++) { - int length = phasedata->gset_lengths[i]; + int length = phasedata->gset_lengths[i]; if (phasedata->eqfunctions[length - 1] != NULL) continue; @@ -2375,6 +2427,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) length, aggnode->grpColIdx, aggnode->grpOperators, + aggnode->grpCollations, (PlanState *) aggstate); } @@ -2386,6 +2439,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) aggnode->numCols, aggnode->grpColIdx, aggnode->grpOperators, + aggnode->grpCollations, (PlanState *) aggstate); } } @@ -2522,7 +2576,7 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) AclResult aclresult; Oid transfn_oid, finalfn_oid; - bool sharable; + bool shareable; Oid serialfn_oid, deserialfn_oid; Expr *finalfnexpr; @@ -2597,12 +2651,12 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) /* * If finalfn is marked read-write, we can't share transition states; - * but it is okay to share states for AGGMODIFY_SHARABLE aggs. Also, + * but it is okay to share states for AGGMODIFY_SHAREABLE aggs. Also, * if we're not executing the finalfn here, we can share regardless. */ - sharable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) || + shareable = (aggform->aggfinalmodify != AGGMODIFY_READ_WRITE) || (finalfn_oid == InvalidOid); - peragg->sharable = sharable; + peragg->shareable = shareable; serialfn_oid = InvalidOid; deserialfn_oid = InvalidOid; @@ -2746,12 +2800,12 @@ ExecInitAgg(Agg *node, EState *estate, int eflags) * 2. Build working state for invoking the transition function, or * look up previously initialized working state, if we can share it. * - * find_compatible_peragg() already collected a list of sharable + * find_compatible_peragg() already collected a list of shareable * per-Trans's with the same inputs. Check if any of them have the * same transition function and initial value. */ existing_transno = find_compatible_pertrans(aggstate, aggref, - sharable, + shareable, transfn_oid, aggtranstype, serialfn_oid, deserialfn_oid, initValue, initValueIsNull, @@ -2903,12 +2957,6 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, pertrans->aggtranstype = aggtranstype; - /* Detect how many arguments to pass to the transfn */ - if (AGGKIND_IS_ORDERED_SET(aggref->aggkind)) - pertrans->numTransInputs = numInputs; - else - pertrans->numTransInputs = numArguments; - /* * When combining states, we have no use at all for the aggregate * function's transfn. Instead we use the combinefn. In this case, the @@ -2918,6 +2966,17 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, if (DO_AGGSPLIT_COMBINE(aggstate->aggsplit)) { Expr *combinefnexpr; + size_t numTransArgs; + + /* + * When combining there's only one input, the to-be-combined added + * transition value from below (this node's transition value is + * counted separately). + */ + pertrans->numTransInputs = 1; + + /* account for the current transition state */ + numTransArgs = pertrans->numTransInputs + 1; build_aggregate_combinefn_expr(aggtranstype, aggref->inputcollid, @@ -2926,9 +2985,11 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, fmgr_info(aggtransfn, &pertrans->transfn); fmgr_info_set_expr((Node *) combinefnexpr, &pertrans->transfn); - InitFunctionCallInfoData(pertrans->transfn_fcinfo, + pertrans->transfn_fcinfo = + (FunctionCallInfo) palloc(SizeForFunctionCallInfo(2)); + InitFunctionCallInfoData(*pertrans->transfn_fcinfo, &pertrans->transfn, - 2, + numTransArgs, pertrans->aggCollation, (void *) aggstate, NULL); @@ -2940,16 +3001,26 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, if (pertrans->transfn.fn_strict && aggtranstype == INTERNALOID) ereport(ERROR, (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("combine function for aggregate %u must be declared as STRICT", - aggref->aggfnoid))); + errmsg("combine function with transition type %s must not be declared STRICT", + format_type_be(aggtranstype)))); } else { Expr *transfnexpr; + size_t numTransArgs; + + /* Detect how many arguments to pass to the transfn */ + if (AGGKIND_IS_ORDERED_SET(aggref->aggkind)) + pertrans->numTransInputs = numInputs; + else + pertrans->numTransInputs = numArguments; + + /* account for the current transition state */ + numTransArgs = pertrans->numTransInputs + 1; /* - * Set up infrastructure for calling the transfn. Note that invtrans - * is not needed here. + * Set up infrastructure for calling the transfn. Note that + * invtransfn is not needed here. */ build_aggregate_transfn_expr(inputTypes, numArguments, @@ -2964,9 +3035,11 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, fmgr_info(aggtransfn, &pertrans->transfn); fmgr_info_set_expr((Node *) transfnexpr, &pertrans->transfn); - InitFunctionCallInfoData(pertrans->transfn_fcinfo, + pertrans->transfn_fcinfo = + (FunctionCallInfo) palloc(SizeForFunctionCallInfo(numTransArgs)); + InitFunctionCallInfoData(*pertrans->transfn_fcinfo, &pertrans->transfn, - pertrans->numTransInputs + 1, + numTransArgs, pertrans->aggCollation, (void *) aggstate, NULL); @@ -3002,7 +3075,9 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, fmgr_info(aggserialfn, &pertrans->serialfn); fmgr_info_set_expr((Node *) serialfnexpr, &pertrans->serialfn); - InitFunctionCallInfoData(pertrans->serialfn_fcinfo, + pertrans->serialfn_fcinfo = + (FunctionCallInfo) palloc(SizeForFunctionCallInfo(1)); + InitFunctionCallInfoData(*pertrans->serialfn_fcinfo, &pertrans->serialfn, 1, InvalidOid, @@ -3016,7 +3091,9 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, fmgr_info(aggdeserialfn, &pertrans->deserialfn); fmgr_info_set_expr((Node *) deserialfnexpr, &pertrans->deserialfn); - InitFunctionCallInfoData(pertrans->deserialfn_fcinfo, + pertrans->deserialfn_fcinfo = + (FunctionCallInfo) palloc(SizeForFunctionCallInfo(2)); + InitFunctionCallInfoData(*pertrans->deserialfn_fcinfo, &pertrans->deserialfn, 2, InvalidOid, @@ -3061,9 +3138,10 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, */ if (numSortCols > 0 || aggref->aggfilter) { - pertrans->sortdesc = ExecTypeFromTL(aggref->args, false); + pertrans->sortdesc = ExecTypeFromTL(aggref->args); pertrans->sortslot = - ExecInitExtraTupleSlot(estate, pertrans->sortdesc); + ExecInitExtraTupleSlot(estate, pertrans->sortdesc, + &TTSOpsMinimalTuple); } if (numSortCols > 0) @@ -3085,7 +3163,8 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, { /* we will need an extra slot to store prior values */ pertrans->uniqslot = - ExecInitExtraTupleSlot(estate, pertrans->sortdesc); + ExecInitExtraTupleSlot(estate, pertrans->sortdesc, + &TTSOpsMinimalTuple); } /* Extract the sort information for use later */ @@ -3138,6 +3217,7 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans, numDistinctCols, pertrans->sortColIdx, ops, + pertrans->sortCollations, &aggstate->ss.ps); pfree(ops); } @@ -3170,7 +3250,7 @@ GetAggInitVal(Datum textInitVal, Oid transtype) * with this one, with the same input parameters. If no compatible aggregate * can be found, returns -1. * - * As a side-effect, this also collects a list of existing, sharable per-Trans + * As a side-effect, this also collects a list of existing, shareable per-Trans * structs with matching inputs. If no identical Aggref is found, the list is * passed later to find_compatible_pertrans, to see if we can at least reuse * the state value of another aggregate. @@ -3237,7 +3317,7 @@ find_compatible_peragg(Aggref *newagg, AggState *aggstate, * we might report a transno more than once. find_compatible_pertrans * is cheap enough that it's not worth spending cycles to avoid that.) */ - if (peragg->sharable) + if (peragg->shareable) *same_input_transnos = lappend_int(*same_input_transnos, peragg->transno); } @@ -3254,7 +3334,7 @@ find_compatible_peragg(Aggref *newagg, AggState *aggstate, * verified to match.) */ static int -find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable, +find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool shareable, Oid aggtransfn, Oid aggtranstype, Oid aggserialfn, Oid aggdeserialfn, Datum initValue, bool initValueIsNull, @@ -3263,7 +3343,7 @@ find_compatible_pertrans(AggState *aggstate, Aggref *newagg, bool sharable, ListCell *lc; /* If this aggregate can't share transition states, give up */ - if (!sharable) + if (!shareable) return -1; foreach(lc, transnos) diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index d062cfddacc..5ff986ac7d3 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -3,7 +3,7 @@ * nodeAppend.c * routines to handle append nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -104,19 +104,13 @@ ExecInitAppend(Append *node, EState *estate, int eflags) PlanState **appendplanstates; Bitmapset *validsubplans; int nplans; + int firstvalid; int i, j; - ListCell *lc; /* check for unsupported flags */ Assert(!(eflags & EXEC_FLAG_MARK)); - /* - * Lock the non-leaf tables in the partition tree controlled by this node. - * It's a no-op for non-partitioned parent tables. - */ - ExecLockNonLeafAppendTables(node->partitioned_rels, estate); - /* * create new AppendState for our append node */ @@ -128,33 +122,33 @@ ExecInitAppend(Append *node, EState *estate, int eflags) appendstate->as_whichplan = INVALID_SUBPLAN_INDEX; /* If run-time partition pruning is enabled, then set that up now */ - if (node->part_prune_infos != NIL) + if (node->part_prune_info != NULL) { PartitionPruneState *prunestate; + /* We may need an expression context to evaluate partition exprs */ ExecAssignExprContext(estate, &appendstate->ps); - prunestate = ExecSetupPartitionPruneState(&appendstate->ps, - node->part_prune_infos); + /* Create the working data structure for pruning. */ + prunestate = ExecCreatePartitionPruneState(&appendstate->ps, + node->part_prune_info); + appendstate->as_prune_state = prunestate; - /* - * When there are external params matching the partition key we may be - * able to prune away Append subplans now. - */ - if (!bms_is_empty(prunestate->extparams)) + /* Perform an initial partition prune, if required. */ + if (prunestate->do_initial_prune) { - /* Determine which subplans match the external params */ + /* Determine which subplans survive initial pruning */ validsubplans = ExecFindInitialMatchingSubPlans(prunestate, list_length(node->appendplans)); /* - * If no subplans match the given parameters then we must handle - * this case in a special way. The problem here is that code in - * explain.c requires an Append to have at least one subplan in - * order for it to properly determine the Vars in that subplan's - * targetlist. We sidestep this issue by just initializing the - * first subplan and setting as_whichplan to NO_MATCHING_SUBPLANS - * to indicate that we don't need to scan any subnodes. + * The case where no subplans survive pruning must be handled + * specially. The problem here is that code in explain.c requires + * an Append to have at least one subplan in order for it to + * properly determine the Vars in that subplan's targetlist. We + * sidestep this issue by just initializing the first subplan and + * setting as_whichplan to NO_MATCHING_SUBPLANS to indicate that + * we don't really need to scan any subnodes. */ if (bms_is_empty(validsubplans)) { @@ -170,18 +164,19 @@ ExecInitAppend(Append *node, EState *estate, int eflags) { /* We'll need to initialize all subplans */ nplans = list_length(node->appendplans); + Assert(nplans > 0); validsubplans = bms_add_range(NULL, 0, nplans - 1); } /* - * If there's no exec params then no further pruning can be done, we - * can just set the valid subplans to all remaining subplans. + * If no runtime pruning is required, we can fill as_valid_subplans + * immediately, preventing later calls to ExecFindMatchingSubPlans. */ - if (bms_is_empty(prunestate->execparams)) + if (!prunestate->do_exec_prune) + { + Assert(nplans > 0); appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1); - - appendstate->as_prune_state = prunestate; - + } } else { @@ -189,8 +184,9 @@ ExecInitAppend(Append *node, EState *estate, int eflags) /* * When run-time partition pruning is not enabled we can just mark all - * subplans as valid, they must also all be initialized. + * subplans as valid; they must also all be initialized. */ + Assert(nplans > 0); appendstate->as_valid_subplans = validsubplans = bms_add_range(NULL, 0, nplans - 1); appendstate->as_prune_state = NULL; @@ -199,7 +195,11 @@ ExecInitAppend(Append *node, EState *estate, int eflags) /* * Initialize result tuple type and slot. */ - ExecInitResultTupleSlotTL(estate, &appendstate->ps); + ExecInitResultTupleSlotTL(&appendstate->ps, &TTSOpsVirtual); + + /* node returns slots from each of its subnodes, therefore not fixed */ + appendstate->ps.resultopsset = true; + appendstate->ps.resultopsfixed = false; appendplanstates = (PlanState **) palloc(nplans * sizeof(PlanState *)); @@ -207,19 +207,26 @@ ExecInitAppend(Append *node, EState *estate, int eflags) /* * call ExecInitNode on each of the valid plans to be executed and save * the results into the appendplanstates array. + * + * While at it, find out the first valid partial plan. */ - j = i = 0; - foreach(lc, node->appendplans) + j = 0; + firstvalid = nplans; + i = -1; + while ((i = bms_next_member(validsubplans, i)) >= 0) { - if (bms_is_member(i, validsubplans)) - { - Plan *initNode = (Plan *) lfirst(lc); + Plan *initNode = (Plan *) list_nth(node->appendplans, i); - appendplanstates[j++] = ExecInitNode(initNode, estate, eflags); - } - i++; + /* + * Record the lowest appendplans index which is a valid partial plan. + */ + if (i >= node->first_partial_plan && j < firstvalid) + firstvalid = j; + + appendplanstates[j++] = ExecInitNode(initNode, estate, eflags); } + appendstate->as_first_partial_plan = firstvalid; appendstate->appendplans = appendplanstates; appendstate->as_nplans = nplans; @@ -329,13 +336,13 @@ ExecReScanAppend(AppendState *node) int i; /* - * If any of the parameters being used for partition pruning have changed, - * then we'd better unset the valid subplans so that they are reselected - * for the new parameter values. + * If any PARAM_EXEC Params used in pruning expressions have changed, then + * we'd better unset the valid subplans so that they are reselected for + * the new parameter values. */ if (node->as_prune_state && bms_overlap(node->ps.chgParam, - node->as_prune_state->execparams)) + node->as_prune_state->execparamids)) { bms_free(node->as_valid_subplans); node->as_valid_subplans = NULL; @@ -499,7 +506,6 @@ static bool choose_next_subplan_for_leader(AppendState *node) { ParallelAppendState *pstate = node->as_pstate; - Append *append = (Append *) node->ps.plan; /* Backward scan is not supported by parallel-aware plans */ Assert(ScanDirectionIsForward(node->ps.state->es_direction)); @@ -520,9 +526,9 @@ choose_next_subplan_for_leader(AppendState *node) node->as_whichplan = node->as_nplans - 1; /* - * If we've yet to determine the valid subplans for these parameters - * then do so now. If run-time pruning is disabled then the valid - * subplans will always be set to all subplans. + * If we've yet to determine the valid subplans then do so now. If + * run-time pruning is disabled then the valid subplans will always be + * set to all subplans. */ if (node->as_valid_subplans == NULL) { @@ -556,7 +562,7 @@ choose_next_subplan_for_leader(AppendState *node) } /* If non-partial, immediately mark as finished. */ - if (node->as_whichplan < append->first_partial_plan) + if (node->as_whichplan < node->as_first_partial_plan) node->as_pstate->pa_finished[node->as_whichplan] = true; LWLockRelease(&pstate->pa_lock); @@ -581,7 +587,6 @@ static bool choose_next_subplan_for_worker(AppendState *node) { ParallelAppendState *pstate = node->as_pstate; - Append *append = (Append *) node->ps.plan; /* Backward scan is not supported by parallel-aware plans */ Assert(ScanDirectionIsForward(node->ps.state->es_direction)); @@ -596,9 +601,9 @@ choose_next_subplan_for_worker(AppendState *node) node->as_pstate->pa_finished[node->as_whichplan] = true; /* - * If we've yet to determine the valid subplans for these parameters then - * do so now. If run-time pruning is disabled then the valid subplans - * will always be set to all subplans. + * If we've yet to determine the valid subplans then do so now. If + * run-time pruning is disabled then the valid subplans will always be set + * to all subplans. */ else if (node->as_valid_subplans == NULL) { @@ -629,14 +634,14 @@ choose_next_subplan_for_worker(AppendState *node) /* Advance to the next valid plan. */ pstate->pa_next_plan = nextplan; } - else if (node->as_whichplan > append->first_partial_plan) + else if (node->as_whichplan > node->as_first_partial_plan) { /* * Try looping back to the first valid partial plan, if there is * one. If there isn't, arrange to bail out below. */ nextplan = bms_next_member(node->as_valid_subplans, - append->first_partial_plan - 1); + node->as_first_partial_plan - 1); pstate->pa_next_plan = nextplan < 0 ? node->as_whichplan : nextplan; } @@ -670,7 +675,7 @@ choose_next_subplan_for_worker(AppendState *node) if (pstate->pa_next_plan < 0) { int nextplan = bms_next_member(node->as_valid_subplans, - append->first_partial_plan - 1); + node->as_first_partial_plan - 1); if (nextplan >= 0) pstate->pa_next_plan = nextplan; @@ -686,7 +691,7 @@ choose_next_subplan_for_worker(AppendState *node) } /* If non-partial, immediately mark as finished. */ - if (node->as_whichplan < append->first_partial_plan) + if (node->as_whichplan < node->as_first_partial_plan) node->as_pstate->pa_finished[node->as_whichplan] = true; LWLockRelease(&pstate->pa_lock); diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c index 23d0d943269..7ae6dd63fe7 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -3,7 +3,7 @@ * nodeBitmapAnd.c * routines to handle BitmapAnd nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c index 3e1c9e07145..f62105f5284 100644 --- a/src/backend/executor/nodeBitmapHeapscan.c +++ b/src/backend/executor/nodeBitmapHeapscan.c @@ -16,7 +16,7 @@ * required index qual conditions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -38,6 +38,7 @@ #include #include "access/relscan.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/visibilitymap.h" #include "executor/execdebug.h" @@ -50,20 +51,16 @@ #include "utils/rel.h" #include "utils/spccache.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" static TupleTableSlot *BitmapHeapNext(BitmapHeapScanState *node); -static void bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres); -static inline void BitmapDoneInitializingSharedState( - ParallelBitmapHeapState *pstate); +static inline void BitmapDoneInitializingSharedState(ParallelBitmapHeapState *pstate); static inline void BitmapAdjustPrefetchIterator(BitmapHeapScanState *node, - TBMIterateResult *tbmres); + TBMIterateResult *tbmres); static inline void BitmapAdjustPrefetchTarget(BitmapHeapScanState *node); static inline void BitmapPrefetch(BitmapHeapScanState *node, - HeapScanDesc scan); -static bool BitmapShouldInitializeSharedState( - ParallelBitmapHeapState *pstate); + TableScanDesc scan); +static bool BitmapShouldInitializeSharedState(ParallelBitmapHeapState *pstate); /* ---------------------------------------------------------------- @@ -76,12 +73,11 @@ static TupleTableSlot * BitmapHeapNext(BitmapHeapScanState *node) { ExprContext *econtext; - HeapScanDesc scan; + TableScanDesc scan; TIDBitmap *tbm; TBMIterator *tbmiterator = NULL; TBMSharedIterator *shared_tbmiterator = NULL; TBMIterateResult *tbmres; - OffsetNumber targoffset; TupleTableSlot *slot; ParallelBitmapHeapState *pstate = node->pstate; dsa_area *dsa = node->ss.ps.state->es_query_dsa; @@ -191,8 +187,7 @@ BitmapHeapNext(BitmapHeapScanState *node) for (;;) { - Page dp; - ItemId lp; + bool skip_fetch; CHECK_FOR_INTERRUPTS(); @@ -213,43 +208,35 @@ BitmapHeapNext(BitmapHeapScanState *node) BitmapAdjustPrefetchIterator(node, tbmres); - /* - * Ignore any claimed entries past what we think is the end of the - * relation. (This is probably not necessary given that we got at - * least AccessShareLock on the table before performing any of the - * indexscans, but let's be safe.) - */ - if (tbmres->blockno >= scan->rs_nblocks) - { - node->tbmres = tbmres = NULL; - continue; - } - /* * We can skip fetching the heap page if we don't need any fields * from the heap, and the bitmap entries don't need rechecking, * and all tuples on the page are visible to our transaction. + * + * XXX: It's a layering violation that we do these checks above + * tableam, they should probably moved below it at some point. */ - node->skip_fetch = (node->can_skip_fetch && - !tbmres->recheck && - VM_ALL_VISIBLE(node->ss.ss_currentRelation, - tbmres->blockno, - &node->vmbuffer)); + skip_fetch = (node->can_skip_fetch && + !tbmres->recheck && + VM_ALL_VISIBLE(node->ss.ss_currentRelation, + tbmres->blockno, + &node->vmbuffer)); - if (node->skip_fetch) + if (skip_fetch) { + /* can't be lossy in the skip_fetch case */ + Assert(tbmres->ntuples >= 0); + /* * The number of tuples on this page is put into - * scan->rs_ntuples; note we don't fill scan->rs_vistuples. + * node->return_empty_tuples. */ - scan->rs_ntuples = tbmres->ntuples; + node->return_empty_tuples = tbmres->ntuples; } - else + else if (!table_scan_bitmap_next_block(scan, tbmres)) { - /* - * Fetch the current heap page and identify candidate tuples. - */ - bitgetpage(scan, tbmres); + /* AM doesn't think this block is valid, skip */ + continue; } if (tbmres->ntuples >= 0) @@ -257,20 +244,14 @@ BitmapHeapNext(BitmapHeapScanState *node) else node->lossy_pages++; - /* - * Set rs_cindex to first slot to examine - */ - scan->rs_cindex = 0; - /* Adjust the prefetch target */ BitmapAdjustPrefetchTarget(node); } else { /* - * Continuing in previously obtained page; advance rs_cindex + * Continuing in previously obtained page. */ - scan->rs_cindex++; #ifdef USE_PREFETCH @@ -294,56 +275,42 @@ BitmapHeapNext(BitmapHeapScanState *node) #endif /* USE_PREFETCH */ } - /* - * Out of range? If so, nothing more to look at on this page - */ - if (scan->rs_cindex < 0 || scan->rs_cindex >= scan->rs_ntuples) - { - node->tbmres = tbmres = NULL; - continue; - } - /* * We issue prefetch requests *after* fetching the current page to try * to avoid having prefetching interfere with the main I/O. Also, this * should happen only when we have determined there is still something * to do on the current page, else we may uselessly prefetch the same * page we are just about to request for real. + * + * XXX: It's a layering violation that we do these checks above + * tableam, they should probably moved below it at some point. */ BitmapPrefetch(node, scan); - if (node->skip_fetch) + if (node->return_empty_tuples > 0) { /* * If we don't have to fetch the tuple, just return nulls. */ ExecStoreAllNullTuple(slot); + + if (--node->return_empty_tuples == 0) + { + /* no more tuples to return in the next round */ + node->tbmres = tbmres = NULL; + } } else { /* - * Okay to fetch the tuple. + * Attempt to fetch tuple from AM. */ - targoffset = scan->rs_vistuples[scan->rs_cindex]; - dp = (Page) BufferGetPage(scan->rs_cbuf); - lp = PageGetItemId(dp, targoffset); - Assert(ItemIdIsNormal(lp)); - - scan->rs_ctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); - scan->rs_ctup.t_len = ItemIdGetLength(lp); - scan->rs_ctup.t_tableOid = scan->rs_rd->rd_id; - ItemPointerSet(&scan->rs_ctup.t_self, tbmres->blockno, targoffset); - - pgstat_count_heap_fetch(scan->rs_rd); - - /* - * Set up the result slot to point to this tuple. Note that the - * slot acquires a pin on the buffer. - */ - ExecStoreTuple(&scan->rs_ctup, - slot, - scan->rs_cbuf, - false); + if (!table_scan_bitmap_next_tuple(scan, tbmres, slot)) + { + /* nothing more to look at on this page */ + node->tbmres = tbmres = NULL; + continue; + } /* * If we are using lossy info, we have to recheck the qual @@ -372,110 +339,6 @@ BitmapHeapNext(BitmapHeapScanState *node) return ExecClearTuple(slot); } -/* - * bitgetpage - subroutine for BitmapHeapNext() - * - * This routine reads and pins the specified page of the relation, then - * builds an array indicating which tuples on the page are both potentially - * interesting according to the bitmap, and visible according to the snapshot. - */ -static void -bitgetpage(HeapScanDesc scan, TBMIterateResult *tbmres) -{ - BlockNumber page = tbmres->blockno; - Buffer buffer; - Snapshot snapshot; - int ntup; - - /* - * Acquire pin on the target heap page, trading in any pin we held before. - */ - Assert(page < scan->rs_nblocks); - - scan->rs_cbuf = ReleaseAndReadBuffer(scan->rs_cbuf, - scan->rs_rd, - page); - buffer = scan->rs_cbuf; - snapshot = scan->rs_snapshot; - - ntup = 0; - - /* - * Prune and repair fragmentation for the whole page, if possible. - */ - heap_page_prune_opt(scan->rs_rd, buffer); - - /* - * We must hold share lock on the buffer content while examining tuple - * visibility. Afterwards, however, the tuples we have found to be - * visible are guaranteed good as long as we hold the buffer pin. - */ - LockBuffer(buffer, BUFFER_LOCK_SHARE); - - /* - * We need two separate strategies for lossy and non-lossy cases. - */ - if (tbmres->ntuples >= 0) - { - /* - * Bitmap is non-lossy, so we just look through the offsets listed in - * tbmres; but we have to follow any HOT chain starting at each such - * offset. - */ - int curslot; - - for (curslot = 0; curslot < tbmres->ntuples; curslot++) - { - OffsetNumber offnum = tbmres->offsets[curslot]; - ItemPointerData tid; - HeapTupleData heapTuple; - - ItemPointerSet(&tid, page, offnum); - if (heap_hot_search_buffer(&tid, scan->rs_rd, buffer, snapshot, - &heapTuple, NULL, true)) - scan->rs_vistuples[ntup++] = ItemPointerGetOffsetNumber(&tid); - } - } - else - { - /* - * Bitmap is lossy, so we must examine each item pointer on the page. - * But we can ignore HOT chains, since we'll check each tuple anyway. - */ - Page dp = (Page) BufferGetPage(buffer); - OffsetNumber maxoff = PageGetMaxOffsetNumber(dp); - OffsetNumber offnum; - - for (offnum = FirstOffsetNumber; offnum <= maxoff; offnum = OffsetNumberNext(offnum)) - { - ItemId lp; - HeapTupleData loctup; - bool valid; - - lp = PageGetItemId(dp, offnum); - if (!ItemIdIsNormal(lp)) - continue; - loctup.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp); - loctup.t_len = ItemIdGetLength(lp); - loctup.t_tableOid = scan->rs_rd->rd_id; - ItemPointerSet(&loctup.t_self, page, offnum); - valid = HeapTupleSatisfiesVisibility(&loctup, snapshot, buffer); - if (valid) - { - scan->rs_vistuples[ntup++] = offnum; - PredicateLockTuple(scan->rs_rd, &loctup, snapshot); - } - CheckForSerializableConflictOut(valid, scan->rs_rd, &loctup, - buffer, snapshot); - } - } - - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); - - Assert(ntup <= MaxHeapTuplesPerPage); - scan->rs_ntuples = ntup; -} - /* * BitmapDoneInitializingSharedState - Shared state is initialized * @@ -599,7 +462,7 @@ BitmapAdjustPrefetchTarget(BitmapHeapScanState *node) * BitmapPrefetch - Prefetch, if prefetch_pages are behind prefetch_target */ static inline void -BitmapPrefetch(BitmapHeapScanState *node, HeapScanDesc scan) +BitmapPrefetch(BitmapHeapScanState *node, TableScanDesc scan) { #ifdef USE_PREFETCH ParallelBitmapHeapState *pstate = node->pstate; @@ -742,7 +605,7 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node) PlanState *outerPlan = outerPlanState(node); /* rescan to release any page pin */ - heap_rescan(node->ss.ss_currentScanDesc, NULL); + table_rescan(node->ss.ss_currentScanDesc, NULL); /* release bitmaps and buffers if any */ if (node->tbmiterator) @@ -786,13 +649,11 @@ ExecReScanBitmapHeapScan(BitmapHeapScanState *node) void ExecEndBitmapHeapScan(BitmapHeapScanState *node) { - Relation relation; - HeapScanDesc scanDesc; + TableScanDesc scanDesc; /* * extract information from the node */ - relation = node->ss.ss_currentRelation; scanDesc = node->ss.ss_currentScanDesc; /* @@ -803,7 +664,8 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node) /* * clear out tuple table slots */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -832,12 +694,7 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node) /* * close heap scan */ - heap_endscan(scanDesc); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(relation); + table_endscan(scanDesc); } /* ---------------------------------------------------------------- @@ -873,7 +730,7 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) scanstate->tbm = NULL; scanstate->tbmiterator = NULL; scanstate->tbmres = NULL; - scanstate->skip_fetch = false; + scanstate->return_empty_tuples = 0; scanstate->vmbuffer = InvalidBuffer; scanstate->pvmbuffer = InvalidBuffer; scanstate->exact_pages = 0; @@ -907,16 +764,12 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &scanstate->ss.ps); /* - * open the base relation and acquire appropriate lock on it. + * open the scan relation */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); /* * initialize child nodes - * - * We do this after ExecOpenScanRelation because the child nodes will open - * indexscans on our relation's indexes, and we want to be sure we have - * acquired a lock on the relation first. */ outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, eflags); @@ -924,13 +777,13 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) * get the scan type from the relation descriptor. */ ExecInitScanTupleSlot(estate, &scanstate->ss, - RelationGetDescr(currentRelation)); - + RelationGetDescr(currentRelation), + table_slot_callbacks(currentRelation)); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -959,14 +812,10 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags) scanstate->ss.ss_currentRelation = currentRelation; - /* - * Even though we aren't going to do a conventional seqscan, it is useful - * to create a HeapScanDesc --- most of the fields in it are usable. - */ - scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation, - estate->es_snapshot, - 0, - NULL); + scanstate->ss.ss_currentScanDesc = table_beginscan_bm(currentRelation, + estate->es_snapshot, + 0, + NULL); /* * all done. @@ -1114,5 +963,5 @@ ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node, node->pstate = pstate; snapshot = RestoreSnapshot(pstate->phs_snapshot_data); - heap_update_snapshot(node->ss.ss_currentScanDesc, snapshot); + table_scan_update_snapshot(node->ss.ss_currentScanDesc, snapshot); } diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c index d04f4901b48..604f4f1132f 100644 --- a/src/backend/executor/nodeBitmapIndexscan.c +++ b/src/backend/executor/nodeBitmapIndexscan.c @@ -3,7 +3,7 @@ * nodeBitmapIndexscan.c * Routines to support bitmapped index scans of relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,6 +21,7 @@ */ #include "postgres.h" +#include "access/genam.h" #include "executor/execdebug.h" #include "executor/nodeBitmapIndexscan.h" #include "executor/nodeIndexscan.h" @@ -210,7 +211,7 @@ BitmapIndexScanState * ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) { BitmapIndexScanState *indexstate; - bool relistarget; + LOCKMODE lockmode; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -259,16 +260,9 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; - /* - * Open the index relation. - * - * If the parent table is one of the target relations of the query, then - * InitPlan already opened and write-locked the index, so we can avoid - * taking another lock here. Otherwise we need a normal reader's lock. - */ - relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); - indexstate->biss_RelationDesc = index_open(node->indexid, - relistarget ? NoLock : AccessShareLock); + /* Open the index relation. */ + lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; + indexstate->biss_RelationDesc = index_open(node->indexid, lockmode); /* * Initialize index-specific scan state diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c index 3f0a0a05442..89d5a0c073a 100644 --- a/src/backend/executor/nodeBitmapOr.c +++ b/src/backend/executor/nodeBitmapOr.c @@ -3,7 +3,7 @@ * nodeBitmapOr.c * routines to handle BitmapOr nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/executor/nodeCtescan.c b/src/backend/executor/nodeCtescan.c index 24700dd3965..6195214f662 100644 --- a/src/backend/executor/nodeCtescan.c +++ b/src/backend/executor/nodeCtescan.c @@ -3,7 +3,7 @@ * nodeCtescan.c * routines to handle CteScan nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -260,12 +260,13 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags) * table) is the same as the result rowtype of the CTE query. */ ExecInitScanTupleSlot(estate, &scanstate->ss, - ExecGetResultType(scanstate->cteplanstate)); + ExecGetResultType(scanstate->cteplanstate), + &TTSOpsMinimalTuple); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -294,7 +295,8 @@ ExecEndCteScan(CteScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -318,7 +320,8 @@ ExecReScanCteScan(CteScanState *node) { Tuplestorestate *tuplestorestate = node->leader->cte_table; - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c index b816e0b31db..6dd0916818f 100644 --- a/src/backend/executor/nodeCustom.c +++ b/src/backend/executor/nodeCustom.c @@ -3,7 +3,7 @@ * nodeCustom.c * Routines to handle execution of custom scan node * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------ @@ -14,6 +14,7 @@ #include "executor/executor.h" #include "executor/nodeCustom.h" #include "nodes/execnodes.h" +#include "nodes/extensible.h" #include "nodes/plannodes.h" #include "miscadmin.h" #include "parser/parsetree.h" @@ -55,7 +56,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) ExecAssignExprContext(estate, &css->ss.ps); /* - * open the base relation, if any, and acquire an appropriate lock on it + * open the scan relation, if any */ if (scanrelid > 0) { @@ -72,14 +73,15 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) { TupleDesc scan_tupdesc; - scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist, false); - ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc); + scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist); + ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, &TTSOpsVirtual); /* Node's targetlist will contain Vars with varno = INDEX_VAR */ tlistvarno = INDEX_VAR; } else { - ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel)); + ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel), + &TTSOpsVirtual); /* Node's targetlist will contain Vars with varno = scanrelid */ tlistvarno = scanrelid; } @@ -87,7 +89,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags) /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &css->ss.ps); + ExecInitResultTupleSlotTL(&css->ss.ps, &TTSOpsVirtual); ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno); /* initialize child expressions */ @@ -126,10 +128,6 @@ ExecEndCustomScan(CustomScanState *node) /* Clean out the tuple table */ ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); - - /* Close the heap relation */ - if (node->ss.ss_currentRelation) - ExecCloseScanRelation(node->ss.ss_currentRelation); } void diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index a2a28b7ec26..52af1dac5c4 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -3,7 +3,7 @@ * nodeForeignscan.c * Routines to support scans of foreign tables * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -55,17 +55,11 @@ ForeignNext(ForeignScanState *node) MemoryContextSwitchTo(oldcontext); /* - * If any system columns are requested, we have to force the tuple into - * physical-tuple form to avoid "cannot extract system attribute from - * virtual tuple" errors later. We also insert a valid value for - * tableoid, which is the only actually-useful system column. + * Insert valid value into tableoid, the only actually-useful system + * column. */ if (plan->fsSystemCol && !TupIsNull(slot)) - { - HeapTuple tup = ExecMaterializeSlot(slot); - - tup->t_tableOid = RelationGetRelid(node->ss.ss_currentRelation); - } + slot->tts_tableOid = RelationGetRelid(node->ss.ss_currentRelation); return slot; } @@ -156,8 +150,8 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &scanstate->ss.ps); /* - * open the base relation, if any, and acquire an appropriate lock on it; - * also acquire function pointers from the FDW's handler + * open the scan relation, if any; also acquire function pointers from the + * FDW's handler */ if (scanrelid > 0) { @@ -179,8 +173,9 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) { TupleDesc scan_tupdesc; - scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false); - ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc); + scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist); + ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc, + &TTSOpsHeapTuple); /* Node's targetlist will contain Vars with varno = INDEX_VAR */ tlistvarno = INDEX_VAR; } @@ -190,15 +185,20 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags) /* don't trust FDWs to return tuples fulfilling NOT NULL constraints */ scan_tupdesc = CreateTupleDescCopy(RelationGetDescr(currentRelation)); - ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc); + ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc, + &TTSOpsHeapTuple); /* Node's targetlist will contain Vars with varno = scanrelid */ tlistvarno = scanrelid; } + /* Don't know what an FDW might return */ + scanstate->ss.ps.scanopsfixed = false; + scanstate->ss.ps.scanopsset = true; + /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfoWithVarno(&scanstate->ss, tlistvarno); /* @@ -256,12 +256,9 @@ ExecEndForeignScan(ForeignScanState *node) ExecFreeExprContext(&node->ss.ps); /* clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); - - /* close the relation. */ - if (node->ss.ss_currentRelation) - ExecCloseScanRelation(node->ss.ss_currentRelation); } /* ---------------------------------------------------------------- diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c index fb7c9f67875..0370f2e2b70 100644 --- a/src/backend/executor/nodeFunctionscan.c +++ b/src/backend/executor/nodeFunctionscan.c @@ -3,7 +3,7 @@ * nodeFunctionscan.c * Support routines for scanning RangeFunctions (functions in rangetable). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -383,7 +383,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) else if (functypclass == TYPEFUNC_SCALAR) { /* Base data type, i.e. scalar */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, NULL, /* don't care about the name here */ @@ -424,7 +424,8 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) */ if (!scanstate->simple) { - fs->func_slot = ExecInitExtraTupleSlot(estate, fs->tupdesc); + fs->func_slot = ExecInitExtraTupleSlot(estate, fs->tupdesc, + &TTSOpsMinimalTuple); } else fs->func_slot = NULL; @@ -453,7 +454,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) if (node->funcordinality) natts++; - scan_tupdesc = CreateTemplateTupleDesc(natts, false); + scan_tupdesc = CreateTemplateTupleDesc(natts); for (i = 0; i < nfuncs; i++) { @@ -482,12 +483,13 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags) /* * Initialize scan slot and type. */ - ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc); + ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc, + &TTSOpsMinimalTuple); /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -529,7 +531,8 @@ ExecEndFunctionScan(FunctionScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -563,7 +566,8 @@ ExecReScanFunctionScan(FunctionScanState *node) int i; Bitmapset *chgparam = node->ss.ps.chgParam; - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); for (i = 0; i < node->nfuncs; i++) { FunctionScanPerFuncState *fs = &node->funcstates[i]; diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index eaf7d2d5632..69d5a1f2398 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -3,7 +3,7 @@ * nodeGather.c * Support routines for scanning a plan via multiple workers. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * A Gather executor launches parallel workers to run multiple copies of a @@ -38,7 +38,7 @@ #include "executor/nodeSubplan.h" #include "executor/tqueue.h" #include "miscadmin.h" -#include "optimizer/planmain.h" +#include "optimizer/optimizer.h" #include "pgstat.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -92,15 +92,35 @@ ExecInitGather(Gather *node, EState *estate, int eflags) tupDesc = ExecGetResultType(outerPlanState(gatherstate)); /* - * Initialize result slot, type and projection. + * Leader may access ExecProcNode result directly (if + * need_to_scan_locally), or from workers via tuple queue. So we can't + * trivially rely on the slot type being fixed for expressions evaluated + * within this node. */ - ExecInitResultTupleSlotTL(estate, &gatherstate->ps); + gatherstate->ps.outeropsset = true; + gatherstate->ps.outeropsfixed = false; + + /* + * Initialize result type and projection. + */ + ExecInitResultTypeTL(&gatherstate->ps); ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR); + /* + * Without projections result slot type is not trivially known, see + * comment above. + */ + if (gatherstate->ps.ps_ProjInfo == NULL) + { + gatherstate->ps.resultopsset = true; + gatherstate->ps.resultopsfixed = false; + } + /* * Initialize funnel slot to same tuple descriptor as outer plan. */ - gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate, tupDesc); + gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate, tupDesc, + &TTSOpsHeapTuple); /* * Gather doesn't support checking a qual (it's always more efficient to @@ -231,7 +251,8 @@ ExecEndGather(GatherState *node) ExecEndNode(outerPlanState(node)); /* let children clean up first */ ExecShutdownGather(node); ExecFreeExprContext(&node->ps); - ExecClearTuple(node->ps.ps_ResultTupleSlot); + if (node->ps.ps_ResultTupleSlot) + ExecClearTuple(node->ps.ps_ResultTupleSlot); } /* @@ -257,18 +278,16 @@ gather_getnext(GatherState *gatherstate) if (HeapTupleIsValid(tup)) { - ExecStoreTuple(tup, /* tuple to store */ - fslot, /* slot in which to store the tuple */ - InvalidBuffer, /* buffer associated with this - * tuple */ - true); /* pfree tuple when done with it */ + ExecStoreHeapTuple(tup, /* tuple to store */ + fslot, /* slot to store the tuple */ + true); /* pfree tuple when done with it */ return fslot; } } if (gatherstate->need_to_scan_locally) { - EState *estate = gatherstate->ps.state; + EState *estate = gatherstate->ps.state; /* Install our DSA area while executing the plan. */ estate->es_query_dsa = @@ -324,7 +343,10 @@ gather_readnext(GatherState *gatherstate) Assert(!tup); --gatherstate->nreaders; if (gatherstate->nreaders == 0) + { + ExecShutdownGatherWorkers(gatherstate); return NULL; + } memmove(&gatherstate->reader[gatherstate->nextreader], &gatherstate->reader[gatherstate->nextreader + 1], sizeof(TupleQueueReader *) @@ -361,7 +383,8 @@ gather_readnext(GatherState *gatherstate) return NULL; /* Nothing to do except wait for developments. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_EXECUTE_GATHER); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_EXECUTE_GATHER); ResetLatch(MyLatch); nvisited = 0; } diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c index 83221cdbaee..6ef128e2aba 100644 --- a/src/backend/executor/nodeGatherMerge.c +++ b/src/backend/executor/nodeGatherMerge.c @@ -3,7 +3,7 @@ * nodeGatherMerge.c * Scan a plan in multiple workers, and do order-preserving merge. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -23,7 +23,7 @@ #include "executor/tqueue.h" #include "lib/binaryheap.h" #include "miscadmin.h" -#include "optimizer/planmain.h" +#include "optimizer/optimizer.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -55,13 +55,13 @@ static TupleTableSlot *ExecGatherMerge(PlanState *pstate); static int32 heap_compare_slots(Datum a, Datum b, void *arg); static TupleTableSlot *gather_merge_getnext(GatherMergeState *gm_state); static HeapTuple gm_readnext_tuple(GatherMergeState *gm_state, int nreader, - bool nowait, bool *done); + bool nowait, bool *done); static void ExecShutdownGatherMergeWorkers(GatherMergeState *node); static void gather_merge_setup(GatherMergeState *gm_state); static void gather_merge_init(GatherMergeState *gm_state); static void gather_merge_clear_tuples(GatherMergeState *gm_state); static bool gather_merge_readnext(GatherMergeState *gm_state, int reader, - bool nowait); + bool nowait); static void load_tuple_array(GatherMergeState *gm_state, int reader); /* ---------------------------------------------------------------- @@ -109,6 +109,15 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) outerNode = outerPlan(node); outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags); + /* + * Leader may access ExecProcNode result directly (if + * need_to_scan_locally), or from workers via tuple queue. So we can't + * trivially rely on the slot type being fixed for expressions evaluated + * within this node. + */ + gm_state->ps.outeropsset = true; + gm_state->ps.outeropsfixed = false; + /* * Store the tuple descriptor into gather merge state, so we can use it * while initializing the gather merge slots. @@ -117,11 +126,21 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) gm_state->tupDesc = tupDesc; /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &gm_state->ps); + ExecInitResultTypeTL(&gm_state->ps); ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR); + /* + * Without projections result slot type is not trivially known, see + * comment above. + */ + if (gm_state->ps.ps_ProjInfo == NULL) + { + gm_state->ps.resultopsset = true; + gm_state->ps.resultopsfixed = false; + } + /* * initialize sort-key information */ @@ -272,7 +291,8 @@ ExecEndGatherMerge(GatherMergeState *node) ExecEndNode(outerPlanState(node)); /* let children clean up first */ ExecShutdownGatherMerge(node); ExecFreeExprContext(&node->ps); - ExecClearTuple(node->ps.ps_ResultTupleSlot); + if (node->ps.ps_ResultTupleSlot) + ExecClearTuple(node->ps.ps_ResultTupleSlot); } /* ---------------------------------------------------------------- @@ -403,7 +423,8 @@ gather_merge_setup(GatherMergeState *gm_state) /* Initialize tuple slot for worker */ gm_state->gm_slots[i + 1] = - ExecInitExtraTupleSlot(gm_state->ps.state, gm_state->tupDesc); + ExecInitExtraTupleSlot(gm_state->ps.state, gm_state->tupDesc, + &TTSOpsHeapTuple); } /* Allocate the resources for the merge */ @@ -628,7 +649,7 @@ gather_merge_readnext(GatherMergeState *gm_state, int reader, bool nowait) { PlanState *outerPlan = outerPlanState(gm_state); TupleTableSlot *outerTupleSlot; - EState *estate = gm_state->ps.state; + EState *estate = gm_state->ps.state; /* Install our DSA area while executing the plan. */ estate->es_query_dsa = gm_state->pei ? gm_state->pei->area : NULL; @@ -679,11 +700,10 @@ gather_merge_readnext(GatherMergeState *gm_state, int reader, bool nowait) Assert(HeapTupleIsValid(tup)); /* Build the TupleTableSlot for the given tuple */ - ExecStoreTuple(tup, /* tuple to store */ - gm_state->gm_slots[reader], /* slot in which to store the - * tuple */ - InvalidBuffer, /* no buffer associated with tuple */ - true); /* pfree tuple when done with it */ + ExecStoreHeapTuple(tup, /* tuple to store */ + gm_state->gm_slots[reader], /* slot in which to store + * the tuple */ + true); /* pfree tuple when done with it */ return true; } @@ -756,7 +776,10 @@ heap_compare_slots(Datum a, Datum b, void *arg) datum2, isNull2, sortKey); if (compare != 0) - return -compare; + { + INVERT_COMPARE_RESULT(compare); + return compare; + } } return 0; } diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c index 2ea80e817d4..05f1d33150f 100644 --- a/src/backend/executor/nodeGroup.c +++ b/src/backend/executor/nodeGroup.c @@ -3,7 +3,7 @@ * nodeGroup.c * Routines to handle group nodes (used for queries with GROUP BY clause). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -162,6 +162,7 @@ GroupState * ExecInitGroup(Group *node, EState *estate, int eflags) { GroupState *grpstate; + const TupleTableSlotOps *tts_ops; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -188,12 +189,13 @@ ExecInitGroup(Group *node, EState *estate, int eflags) /* * Initialize scan slot and type. */ - ExecCreateScanSlotFromOuterPlan(estate, &grpstate->ss); + tts_ops = ExecGetResultSlotOps(outerPlanState(&grpstate->ss), NULL); + ExecCreateScanSlotFromOuterPlan(estate, &grpstate->ss, tts_ops); /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &grpstate->ss.ps); + ExecInitResultTupleSlotTL(&grpstate->ss.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&grpstate->ss.ps, NULL); /* @@ -210,6 +212,7 @@ ExecInitGroup(Group *node, EState *estate, int eflags) node->numCols, node->grpColIdx, node->grpOperators, + node->grpCollations, &grpstate->ss.ps); return grpstate; diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c index 4f069d17fd8..224cbb32bad 100644 --- a/src/backend/executor/nodeHash.c +++ b/src/backend/executor/nodeHash.c @@ -3,7 +3,7 @@ * nodeHash.c * Routines to hash relations for hashjoin * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -48,35 +48,35 @@ static void ExecHashIncreaseNumBuckets(HashJoinTable hashtable); static void ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable); static void ExecParallelHashIncreaseNumBuckets(HashJoinTable hashtable); static void ExecHashBuildSkewHash(HashJoinTable hashtable, Hash *node, - int mcvsToUse); + int mcvsToUse); static void ExecHashSkewTableInsert(HashJoinTable hashtable, - TupleTableSlot *slot, - uint32 hashvalue, - int bucketNumber); + TupleTableSlot *slot, + uint32 hashvalue, + int bucketNumber); static void ExecHashRemoveNextSkewBucket(HashJoinTable hashtable); static void *dense_alloc(HashJoinTable hashtable, Size size); static HashJoinTuple ExecParallelHashTupleAlloc(HashJoinTable hashtable, - size_t size, - dsa_pointer *shared); + size_t size, + dsa_pointer *shared); static void MultiExecPrivateHash(HashState *node); static void MultiExecParallelHash(HashState *node); static inline HashJoinTuple ExecParallelHashFirstTuple(HashJoinTable table, - int bucketno); + int bucketno); static inline HashJoinTuple ExecParallelHashNextTuple(HashJoinTable table, - HashJoinTuple tuple); + HashJoinTuple tuple); static inline void ExecParallelHashPushTuple(dsa_pointer_atomic *head, - HashJoinTuple tuple, - dsa_pointer tuple_shared); + HashJoinTuple tuple, + dsa_pointer tuple_shared); static void ExecParallelHashJoinSetUpBatches(HashJoinTable hashtable, int nbatch); static void ExecParallelHashEnsureBatchAccessors(HashJoinTable hashtable); static void ExecParallelHashRepartitionFirst(HashJoinTable hashtable); static void ExecParallelHashRepartitionRest(HashJoinTable hashtable); static HashMemoryChunk ExecParallelHashPopChunkQueue(HashJoinTable table, - dsa_pointer *shared); + dsa_pointer *shared); static bool ExecParallelHashTuplePrealloc(HashJoinTable hashtable, - int batchno, - size_t size); + int batchno, + size_t size); static void ExecParallelHashMergeCounters(HashJoinTable hashtable); static void ExecParallelHashCloseBatchAccessors(HashJoinTable hashtable); @@ -157,7 +157,8 @@ MultiExecPrivateHash(HashState *node) econtext = node->ps.ps_ExprContext; /* - * get all inner tuples and insert into the hash table (or temp files) + * Get all tuples from the node below the Hash node and insert into the + * hash table (or temp files). */ for (;;) { @@ -165,7 +166,7 @@ MultiExecPrivateHash(HashState *node) if (TupIsNull(slot)) break; /* We have to compute the hash value */ - econtext->ecxt_innertuple = slot; + econtext->ecxt_outertuple = slot; if (ExecHashGetHashValue(hashtable, econtext, hashkeys, false, hashtable->keepNulls, &hashvalue)) @@ -281,7 +282,7 @@ MultiExecParallelHash(HashState *node) slot = ExecProcNode(outerNode); if (TupIsNull(slot)) break; - econtext->ecxt_innertuple = slot; + econtext->ecxt_outertuple = slot; if (ExecHashGetHashValue(hashtable, econtext, hashkeys, false, hashtable->keepNulls, &hashvalue)) @@ -382,14 +383,15 @@ ExecInitHash(Hash *node, EState *estate, int eflags) * initialize our result slot and type. No need to build projection * because this node doesn't do projections. */ - ExecInitResultTupleSlotTL(estate, &hashstate->ps); + ExecInitResultTupleSlotTL(&hashstate->ps, &TTSOpsMinimalTuple); hashstate->ps.ps_ProjInfo = NULL; /* * initialize child expressions */ - hashstate->ps.qual = - ExecInitQual(node->plan.qual, (PlanState *) hashstate); + Assert(node->plan.qual == NIL); + hashstate->hashkeys = + ExecInitExprList(node->hashkeys, (PlanState *) hashstate); return hashstate; } @@ -425,7 +427,7 @@ ExecEndHash(HashState *node) * ---------------------------------------------------------------- */ HashJoinTable -ExecHashTableCreate(HashState *state, List *hashOperators, bool keepNulls) +ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations, bool keepNulls) { Hash *node; HashJoinTable hashtable; @@ -439,6 +441,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, bool keepNulls) int nkeys; int i; ListCell *ho; + ListCell *hc; MemoryContext oldcxt; /* @@ -541,8 +544,9 @@ ExecHashTableCreate(HashState *state, List *hashOperators, bool keepNulls) hashtable->inner_hashfunctions = (FmgrInfo *) palloc(nkeys * sizeof(FmgrInfo)); hashtable->hashStrict = (bool *) palloc(nkeys * sizeof(bool)); + hashtable->collations = (Oid *) palloc(nkeys * sizeof(Oid)); i = 0; - foreach(ho, hashOperators) + forboth(ho, hashOperators, hc, hashCollations) { Oid hashop = lfirst_oid(ho); Oid left_hashfn; @@ -554,6 +558,7 @@ ExecHashTableCreate(HashState *state, List *hashOperators, bool keepNulls) fmgr_info(left_hashfn, &hashtable->outer_hashfunctions[i]); fmgr_info(right_hashfn, &hashtable->inner_hashfunctions[i]); hashtable->hashStrict[i] = op_strict(hashop); + hashtable->collations[i] = lfirst_oid(hc); i++; } @@ -1046,8 +1051,8 @@ ExecHashIncreaseNumBatches(HashJoinTable hashtable) /* * ExecParallelHashIncreaseNumBatches - * Every participant attached to grow_barrier must run this function - * when it observes growth == PHJ_GROWTH_NEED_MORE_BATCHES. + * Every participant attached to grow_batches_barrier must run this + * function when it observes growth == PHJ_GROWTH_NEED_MORE_BATCHES. */ static void ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable) @@ -1103,7 +1108,7 @@ ExecParallelHashIncreaseNumBatches(HashJoinTable hashtable) * The combined work_mem of all participants wasn't * enough. Therefore one batch per participant would be * approximately equivalent and would probably also be - * insufficient. So try two batches per particiant, + * insufficient. So try two batches per participant, * rounded up to a power of two. */ new_nbatch = 1 << my_log2(pstate->nparticipants * 2); @@ -1590,7 +1595,8 @@ ExecHashTableInsert(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue) { - MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot); + bool shouldFree; + MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot, &shouldFree); int bucketno; int batchno; @@ -1664,10 +1670,13 @@ ExecHashTableInsert(HashJoinTable hashtable, hashvalue, &hashtable->innerBatchFile[batchno]); } + + if (shouldFree) + heap_free_minimal_tuple(tuple); } /* - * ExecHashTableParallelInsert + * ExecParallelHashTableInsert * insert a tuple into a shared hash table or shared batch tuplestore */ void @@ -1675,7 +1684,8 @@ ExecParallelHashTableInsert(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue) { - MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot); + bool shouldFree; + MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot, &shouldFree); dsa_pointer shared; int bucketno; int batchno; @@ -1723,6 +1733,9 @@ ExecParallelHashTableInsert(HashJoinTable hashtable, tuple); } ++hashtable->batches[batchno].ntuples; + + if (shouldFree) + heap_free_minimal_tuple(tuple); } /* @@ -1736,7 +1749,8 @@ ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue) { - MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot); + bool shouldFree; + MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot, &shouldFree); HashJoinTuple hashTuple; dsa_pointer shared; int batchno; @@ -1752,15 +1766,22 @@ ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, HeapTupleHeaderClearMatch(HJTUPLE_MINTUPLE(hashTuple)); ExecParallelHashPushTuple(&hashtable->buckets.shared[bucketno], hashTuple, shared); + + if (shouldFree) + heap_free_minimal_tuple(tuple); } /* * ExecHashGetHashValue * Compute the hash value for a tuple * - * The tuple to be tested must be in either econtext->ecxt_outertuple or - * econtext->ecxt_innertuple. Vars in the hashkeys expressions should have - * varno either OUTER_VAR or INNER_VAR. + * The tuple to be tested must be in econtext->ecxt_outertuple (thus Vars in + * the hashkeys expressions need to have OUTER_VAR as varno). If outer_tuple + * is false (meaning it's the HashJoin's inner node, Hash), econtext, + * hashkeys, and slot need to be from Hash, with hashkeys/slot referencing and + * being suitable for tuples from the node below the Hash. Conversely, if + * outer_tuple is true, econtext is from HashJoin, and hashkeys/slot need to + * be appropriate for tuples from HashJoin's outer node. * * A true result means the tuple's hash value has been successfully computed * and stored at *hashvalue. A false result means the tuple cannot match @@ -1835,7 +1856,7 @@ ExecHashGetHashValue(HashJoinTable hashtable, /* Compute the hash function */ uint32 hkey; - hkey = DatumGetUInt32(FunctionCall1(&hashfunctions[i], keyval)); + hkey = DatumGetUInt32(FunctionCall1Coll(&hashfunctions[i], hashtable->collations[i], keyval)); hashkey ^= hkey; } @@ -2291,8 +2312,9 @@ ExecHashBuildSkewHash(HashJoinTable hashtable, Hash *node, int mcvsToUse) uint32 hashvalue; int bucket; - hashvalue = DatumGetUInt32(FunctionCall1(&hashfunctions[0], - sslot.values[i])); + hashvalue = DatumGetUInt32(FunctionCall1Coll(&hashfunctions[0], + hashtable->collations[0], + sslot.values[i])); /* * While we have not hit a hole in the hashtable and have not hit @@ -2391,7 +2413,8 @@ ExecHashSkewTableInsert(HashJoinTable hashtable, uint32 hashvalue, int bucketNumber) { - MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot); + bool shouldFree; + MinimalTuple tuple = ExecFetchSlotMinimalTuple(slot, &shouldFree); HashJoinTuple hashTuple; int hashTupleSize; @@ -2419,6 +2442,9 @@ ExecHashSkewTableInsert(HashJoinTable hashtable, /* Check we are not over the total spaceAllowed, either */ if (hashtable->spaceUsed > hashtable->spaceAllowed) ExecHashIncreaseNumBatches(hashtable); + + if (shouldFree) + heap_free_minimal_tuple(tuple); } /* @@ -2818,9 +2844,12 @@ ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size, { hashtable->batches[0].shared->ntuples += hashtable->batches[0].ntuples; hashtable->batches[0].ntuples = 0; + /* Guard against integer overflow and alloc size overflow */ if (hashtable->batches[0].shared->ntuples + 1 > hashtable->nbuckets * NTUP_PER_BUCKET && - hashtable->nbuckets < (INT_MAX / 2)) + hashtable->nbuckets < (INT_MAX / 2) && + hashtable->nbuckets * 2 <= + MaxAllocSize / sizeof(dsa_pointer_atomic)) { pstate->growth = PHJ_GROWTH_NEED_MORE_BUCKETS; LWLockRelease(&pstate->lock); diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c index ab91eb25273..ec37558c127 100644 --- a/src/backend/executor/nodeHashjoin.c +++ b/src/backend/executor/nodeHashjoin.c @@ -3,7 +3,7 @@ * nodeHashjoin.c * Routines to handle hash join nodes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -134,15 +134,15 @@ #define HJ_FILL_INNER(hjstate) ((hjstate)->hj_NullOuterTupleSlot != NULL) static TupleTableSlot *ExecHashJoinOuterGetTuple(PlanState *outerNode, - HashJoinState *hjstate, - uint32 *hashvalue); + HashJoinState *hjstate, + uint32 *hashvalue); static TupleTableSlot *ExecParallelHashJoinOuterGetTuple(PlanState *outerNode, - HashJoinState *hjstate, - uint32 *hashvalue); + HashJoinState *hjstate, + uint32 *hashvalue); static TupleTableSlot *ExecHashJoinGetSavedTuple(HashJoinState *hjstate, - BufFile *file, - uint32 *hashvalue, - TupleTableSlot *tupleSlot); + BufFile *file, + uint32 *hashvalue, + TupleTableSlot *tupleSlot); static bool ExecHashJoinNewBatch(HashJoinState *hjstate); static bool ExecParallelHashJoinNewBatch(HashJoinState *hjstate); static void ExecParallelHashJoinPartitionOuter(HashJoinState *node); @@ -278,6 +278,7 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel) */ hashtable = ExecHashTableCreate(hashNode, node->hj_HashOperators, + node->hj_Collations, HJ_FILL_INNER(node)); node->hj_HashTable = hashtable; @@ -389,16 +390,22 @@ ExecHashJoinImpl(PlanState *pstate, bool parallel) if (batchno != hashtable->curbatch && node->hj_CurSkewBucketNo == INVALID_SKEW_BUCKET_NO) { + bool shouldFree; + MinimalTuple mintuple = ExecFetchSlotMinimalTuple(outerTupleSlot, + &shouldFree); + /* * Need to postpone this outer tuple to a later batch. * Save it in the corresponding outer-batch file. */ Assert(parallel_state == NULL); Assert(batchno > hashtable->curbatch); - ExecHashJoinSaveTuple(ExecFetchSlotMinimalTuple(outerTupleSlot), - hashvalue, + ExecHashJoinSaveTuple(mintuple, hashvalue, &hashtable->outerBatchFile[batchno]); + if (shouldFree) + heap_free_minimal_tuple(mintuple); + /* Loop around, staying in HJ_NEED_NEW_OUTER state */ continue; } @@ -593,11 +600,9 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) HashJoinState *hjstate; Plan *outerNode; Hash *hashNode; - List *lclauses; - List *rclauses; - List *hoperators; - TupleDesc outerDesc, innerDesc; - ListCell *l; + TupleDesc outerDesc, + innerDesc; + const TupleTableSlotOps *ops; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -642,13 +647,15 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &hjstate->js.ps); + ExecInitResultTupleSlotTL(&hjstate->js.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&hjstate->js.ps, NULL); /* * tuple table initialization */ - hjstate->hj_OuterTupleSlot = ExecInitExtraTupleSlot(estate, outerDesc); + ops = ExecGetResultSlotOps(outerPlanState(hjstate), NULL); + hjstate->hj_OuterTupleSlot = ExecInitExtraTupleSlot(estate, outerDesc, + ops); /* * detect whether we need only consider the first matching inner tuple @@ -665,17 +672,17 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) case JOIN_LEFT: case JOIN_ANTI: hjstate->hj_NullInnerTupleSlot = - ExecInitNullTupleSlot(estate, innerDesc); + ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual); break; case JOIN_RIGHT: hjstate->hj_NullOuterTupleSlot = - ExecInitNullTupleSlot(estate, outerDesc); + ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual); break; case JOIN_FULL: hjstate->hj_NullOuterTupleSlot = - ExecInitNullTupleSlot(estate, outerDesc); + ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual); hjstate->hj_NullInnerTupleSlot = - ExecInitNullTupleSlot(estate, innerDesc); + ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual); break; default: elog(ERROR, "unrecognized join type: %d", @@ -717,30 +724,10 @@ ExecInitHashJoin(HashJoin *node, EState *estate, int eflags) hjstate->hj_CurSkewBucketNo = INVALID_SKEW_BUCKET_NO; hjstate->hj_CurTuple = NULL; - /* - * Deconstruct the hash clauses into outer and inner argument values, so - * that we can evaluate those subexpressions separately. Also make a list - * of the hash operator OIDs, in preparation for looking up the hash - * functions to use. - */ - lclauses = NIL; - rclauses = NIL; - hoperators = NIL; - foreach(l, node->hashclauses) - { - OpExpr *hclause = lfirst_node(OpExpr, l); - - lclauses = lappend(lclauses, ExecInitExpr(linitial(hclause->args), - (PlanState *) hjstate)); - rclauses = lappend(rclauses, ExecInitExpr(lsecond(hclause->args), - (PlanState *) hjstate)); - hoperators = lappend_oid(hoperators, hclause->opno); - } - hjstate->hj_OuterHashKeys = lclauses; - hjstate->hj_InnerHashKeys = rclauses; - hjstate->hj_HashOperators = hoperators; - /* child Hash node needs to evaluate inner hash keys, too */ - ((HashState *) innerPlanState(hjstate))->hashkeys = rclauses; + hjstate->hj_OuterHashKeys = ExecInitExprList(node->hashkeys, + (PlanState *) hjstate); + hjstate->hj_HashOperators = node->hashoperators; + hjstate->hj_Collations = node->hashcollations; hjstate->hj_JoinState = HJ_BUILD_HASHTABLE; hjstate->hj_MatchedOuter = false; @@ -917,9 +904,10 @@ ExecParallelHashJoinOuterGetTuple(PlanState *outerNode, hashvalue); if (tuple != NULL) { - slot = ExecStoreMinimalTuple(tuple, - hjstate->hj_OuterTupleSlot, - false); + ExecForceStoreMinimalTuple(tuple, + hjstate->hj_OuterTupleSlot, + false); + slot = hjstate->hj_OuterTupleSlot; return slot; } else @@ -1146,9 +1134,10 @@ ExecParallelHashJoinNewBatch(HashJoinState *hjstate) while ((tuple = sts_parallel_scan_next(inner_tuples, &hashvalue))) { - slot = ExecStoreMinimalTuple(tuple, - hjstate->hj_HashTupleSlot, - false); + ExecForceStoreMinimalTuple(tuple, + hjstate->hj_HashTupleSlot, + false); + slot = hjstate->hj_HashTupleSlot; ExecParallelHashTableInsertCurrentBatch(hashtable, slot, hashvalue); } @@ -1282,7 +1271,8 @@ ExecHashJoinGetSavedTuple(HashJoinState *hjstate, ereport(ERROR, (errcode_for_file_access(), errmsg("could not read from hash-join temporary file: %m"))); - return ExecStoreMinimalTuple(tuple, tupleSlot, true); + ExecForceStoreMinimalTuple(tuple, tupleSlot, true); + return tupleSlot; } @@ -1394,16 +1384,21 @@ ExecParallelHashJoinPartitionOuter(HashJoinState *hjstate) if (ExecHashGetHashValue(hashtable, econtext, hjstate->hj_OuterHashKeys, true, /* outer tuple */ - false, /* outer join, currently unsupported */ + HJ_FILL_OUTER(hjstate), &hashvalue)) { int batchno; int bucketno; + bool shouldFree; + MinimalTuple mintup = ExecFetchSlotMinimalTuple(slot, &shouldFree); ExecHashGetBucketAndBatch(hashtable, hashvalue, &bucketno, &batchno); sts_puttuple(hashtable->batches[batchno].outer_tuples, - &hashvalue, ExecFetchSlotMinimalTuple(slot)); + &hashvalue, mintup); + + if (shouldFree) + heap_free_minimal_tuple(mintup); } CHECK_FOR_INTERRUPTS(); } diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index ddc0ae90615..784486f0c80 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -3,7 +3,7 @@ * nodeIndexonlyscan.c * Routines to support index-only scans * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,7 +30,10 @@ */ #include "postgres.h" +#include "access/genam.h" #include "access/relscan.h" +#include "access/tableam.h" +#include "access/tupdesc.h" #include "access/visibilitymap.h" #include "executor/execdebug.h" #include "executor/nodeIndexonlyscan.h" @@ -44,7 +47,7 @@ static TupleTableSlot *IndexOnlyNext(IndexOnlyScanState *node); static void StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, - TupleDesc itupdesc); + TupleDesc itupdesc); /* ---------------------------------------------------------------- @@ -84,8 +87,8 @@ IndexOnlyNext(IndexOnlyScanState *node) { /* * We reach here if the index only scan is not parallel, or if we're - * executing a index only scan that was intended to be parallel - * serially. + * serially executing an index only scan that was planned to be + * parallel. */ scandesc = index_beginscan(node->ss.ss_currentRelation, node->ioss_RelationDesc, @@ -117,7 +120,7 @@ IndexOnlyNext(IndexOnlyScanState *node) */ while ((tid = index_getnext_tid(scandesc, direction)) != NULL) { - HeapTuple tuple = NULL; + bool tuple_from_heap = false; CHECK_FOR_INTERRUPTS(); @@ -162,18 +165,19 @@ IndexOnlyNext(IndexOnlyScanState *node) /* * Rats, we have to visit the heap to check visibility. */ - node->ioss_HeapFetches++; - tuple = index_fetch_heap(scandesc); - if (tuple == NULL) + InstrCountTuples2(node, 1); + if (!index_fetch_heap(scandesc, node->ioss_TableSlot)) continue; /* no visible tuple, try next index entry */ + ExecClearTuple(node->ioss_TableSlot); + /* * Only MVCC snapshots are supported here, so there should be no * need to keep following the HOT chain once a visible entry has * been found. If we did want to allow that, we'd need to keep * more state to remember not to call index_getnext_tid next time. */ - if (scandesc->xs_continue_hot) + if (scandesc->xs_heap_continue) elog(ERROR, "non-MVCC snapshots are not supported in index-only scans"); /* @@ -182,6 +186,8 @@ IndexOnlyNext(IndexOnlyScanState *node) * but it's not clear whether it's a win to do so. The next index * entry might require a visit to the same heap page. */ + + tuple_from_heap = true; } /* @@ -199,7 +205,7 @@ IndexOnlyNext(IndexOnlyScanState *node) */ Assert(slot->tts_tupleDescriptor->natts == scandesc->xs_hitupdesc->natts); - ExecStoreTuple(scandesc->xs_hitup, slot, InvalidBuffer, false); + ExecForceStoreHeapTuple(scandesc->xs_hitup, slot, false); } else if (scandesc->xs_itup) StoreIndexTuple(slot, scandesc->xs_itup, scandesc->xs_itupdesc); @@ -236,13 +242,10 @@ IndexOnlyNext(IndexOnlyScanState *node) errmsg("lossy distance functions are not supported in index-only scans"))); /* - * Predicate locks for index-only scans must be acquired at the page - * level when the heap is not accessed, since tuple-level predicate - * locks need the tuple's xmin value. If we had to visit the tuple - * anyway, then we already have the tuple-level lock and can skip the - * page lock. + * If we didn't access the heap, then we'll need to take a predicate + * lock explicitly, as if we had. For now we do that at page level. */ - if (tuple == NULL) + if (!tuple_from_heap) PredicateLockPage(scandesc->heapRelation, ItemPointerGetBlockNumber(tid), estate->es_snapshot); @@ -267,23 +270,17 @@ IndexOnlyNext(IndexOnlyScanState *node) static void StoreIndexTuple(TupleTableSlot *slot, IndexTuple itup, TupleDesc itupdesc) { - int nindexatts = itupdesc->natts; - Datum *values = slot->tts_values; - bool *isnull = slot->tts_isnull; - int i; - /* - * Note: we must use the tupdesc supplied by the AM in index_getattr, not - * the slot's tupdesc, in case the latter has different datatypes (this - * happens for btree name_ops in particular). They'd better have the same - * number of columns though, as well as being datatype-compatible which is - * something we can't so easily check. + * Note: we must use the tupdesc supplied by the AM in index_deform_tuple, + * not the slot's tupdesc, in case the latter has different datatypes + * (this happens for btree name_ops in particular). They'd better have + * the same number of columns though, as well as being datatype-compatible + * which is something we can't so easily check. */ - Assert(slot->tts_tupleDescriptor->natts == nindexatts); + Assert(slot->tts_tupleDescriptor->natts == itupdesc->natts); ExecClearTuple(slot); - for (i = 0; i < nindexatts; i++) - values[i] = index_getattr(itup, i + 1, itupdesc, &isnull[i]); + index_deform_tuple(itup, itupdesc, slot->tts_values, slot->tts_isnull); ExecStoreVirtualTuple(slot); } @@ -373,14 +370,12 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node) { Relation indexRelationDesc; IndexScanDesc indexScanDesc; - Relation relation; /* * extract information from the node */ indexRelationDesc = node->ioss_RelationDesc; indexScanDesc = node->ioss_ScanDesc; - relation = node->ss.ss_currentRelation; /* Release VM buffer pin, if any. */ if (node->ioss_VMBuffer != InvalidBuffer) @@ -401,7 +396,8 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node) /* * clear out tuple table slots */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -411,11 +407,6 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node) index_endscan(indexScanDesc); if (indexRelationDesc) index_close(indexRelationDesc, NoLock); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(relation); } /* ---------------------------------------------------------------- @@ -429,25 +420,27 @@ void ExecIndexOnlyMarkPos(IndexOnlyScanState *node) { EState *estate = node->ss.ps.state; + EPQState *epqstate = estate->es_epq_active; - if (estate->es_epqTuple != NULL) + if (epqstate != NULL) { /* * We are inside an EvalPlanQual recheck. If a test tuple exists for * this relation, then we shouldn't access the index at all. We would * instead need to save, and later restore, the state of the - * es_epqScanDone flag, so that re-fetching the test tuple is - * possible. However, given the assumption that no caller sets a mark - * at the start of the scan, we can only get here with es_epqScanDone + * relsubs_done flag, so that re-fetching the test tuple is possible. + * However, given the assumption that no caller sets a mark at the + * start of the scan, we can only get here with relsubs_done[i] * already set, and so no state need be saved. */ Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid; Assert(scanrelid > 0); - if (estate->es_epqTupleSet[scanrelid - 1]) + if (epqstate->relsubs_slot[scanrelid - 1] != NULL || + epqstate->relsubs_rowmark[scanrelid - 1] != NULL) { /* Verify the claim above */ - if (!estate->es_epqScanDone[scanrelid - 1]) + if (!epqstate->relsubs_done[scanrelid - 1]) elog(ERROR, "unexpected ExecIndexOnlyMarkPos call in EPQ recheck"); return; } @@ -464,17 +457,19 @@ void ExecIndexOnlyRestrPos(IndexOnlyScanState *node) { EState *estate = node->ss.ps.state; + EPQState *epqstate = estate->es_epq_active; - if (estate->es_epqTuple != NULL) + if (estate->es_epq_active != NULL) { - /* See comments in ExecIndexOnlyMarkPos */ + /* See comments in ExecIndexMarkPos */ Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid; Assert(scanrelid > 0); - if (estate->es_epqTupleSet[scanrelid - 1]) + if (epqstate->relsubs_slot[scanrelid - 1] != NULL || + epqstate->relsubs_rowmark[scanrelid - 1] != NULL) { /* Verify the claim above */ - if (!estate->es_epqScanDone[scanrelid - 1]) + if (!epqstate->relsubs_done[scanrelid - 1]) elog(ERROR, "unexpected ExecIndexOnlyRestrPos call in EPQ recheck"); return; } @@ -499,7 +494,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) { IndexOnlyScanState *indexstate; Relation currentRelation; - bool relistarget; + LOCKMODE lockmode; TupleDesc tupDesc; /* @@ -509,7 +504,6 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) indexstate->ss.ps.plan = (Plan *) node; indexstate->ss.ps.state = estate; indexstate->ss.ps.ExecProcNode = ExecIndexOnlyScan; - indexstate->ioss_HeapFetches = 0; /* * Miscellaneous initialization @@ -519,7 +513,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &indexstate->ss.ps); /* - * open the base relation and acquire appropriate lock on it. + * open the scan relation */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); @@ -533,15 +527,24 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) * types of the original datums. (It's the AM's responsibility to return * suitable data anyway.) */ - tupDesc = ExecTypeFromTL(node->indextlist, false); - ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc); + tupDesc = ExecTypeFromTL(node->indextlist); + ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc, + &TTSOpsVirtual); /* - * Initialize result slot, type and projection info. The node's - * targetlist will contain Vars with varno = INDEX_VAR, referencing the - * scan tuple. + * We need another slot, in a format that's suitable for the table AM, for + * when we need to fetch a tuple from the table for rechecking visibility. */ - ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps); + indexstate->ioss_TableSlot = + ExecAllocTableSlot(&estate->es_tupleTable, + RelationGetDescr(currentRelation), + table_slot_callbacks(currentRelation)); + + /* + * Initialize result type and projection info. The node's targetlist will + * contain Vars with varno = INDEX_VAR, referencing the scan tuple. + */ + ExecInitResultTypeTL(&indexstate->ss.ps); ExecAssignScanProjectionInfoWithVarno(&indexstate->ss, INDEX_VAR); /* @@ -563,16 +566,9 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; - /* - * Open the index relation. - * - * If the parent table is one of the target relations of the query, then - * InitPlan already opened and write-locked the index, so we can avoid - * taking another lock here. Otherwise we need a normal reader's lock. - */ - relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); - indexstate->ioss_RelationDesc = index_open(node->indexid, - relistarget ? NoLock : AccessShareLock); + /* Open the index relation. */ + lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; + indexstate->ioss_RelationDesc = index_open(node->indexid, lockmode); /* * Initialize index-specific scan state diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index d6012192a14..c06d07aa467 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -3,7 +3,7 @@ * nodeIndexscan.c * Routines to support indexed scans of relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -31,13 +31,13 @@ #include "access/nbtree.h" #include "access/relscan.h" +#include "access/tableam.h" #include "catalog/pg_am.h" #include "executor/execdebug.h" #include "executor/nodeIndexscan.h" #include "lib/pairingheap.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" #include "utils/array.h" #include "utils/datum.h" #include "utils/lsyscache.h" @@ -60,13 +60,13 @@ static TupleTableSlot *IndexNext(IndexScanState *node); static TupleTableSlot *IndexNextWithReorder(IndexScanState *node); static void EvalOrderByExpressions(IndexScanState *node, ExprContext *econtext); static bool IndexRecheck(IndexScanState *node, TupleTableSlot *slot); -static int cmp_orderbyvals(const Datum *adist, const bool *anulls, - const Datum *bdist, const bool *bnulls, - IndexScanState *node); -static int reorderqueue_cmp(const pairingheap_node *a, - const pairingheap_node *b, void *arg); -static void reorderqueue_push(IndexScanState *node, HeapTuple tuple, - Datum *orderbyvals, bool *orderbynulls); +static int cmp_orderbyvals(const Datum *adist, const bool *anulls, + const Datum *bdist, const bool *bnulls, + IndexScanState *node); +static int reorderqueue_cmp(const pairingheap_node *a, + const pairingheap_node *b, void *arg); +static void reorderqueue_push(IndexScanState *node, TupleTableSlot *slot, + Datum *orderbyvals, bool *orderbynulls); static HeapTuple reorderqueue_pop(IndexScanState *node); @@ -84,7 +84,6 @@ IndexNext(IndexScanState *node) ExprContext *econtext; ScanDirection direction; IndexScanDesc scandesc; - HeapTuple tuple; TupleTableSlot *slot; /* @@ -108,7 +107,7 @@ IndexNext(IndexScanState *node) { /* * We reach here if the index scan is not parallel, or if we're - * executing a index scan that was intended to be parallel serially. + * serially executing an index scan that was planned to be parallel. */ scandesc = index_beginscan(node->ss.ss_currentRelation, node->iss_RelationDesc, @@ -131,20 +130,10 @@ IndexNext(IndexScanState *node) /* * ok, now that we have what we need, fetch the next tuple. */ - while ((tuple = index_getnext(scandesc, direction)) != NULL) + while (index_getnext_slot(scandesc, direction, slot)) { CHECK_FOR_INTERRUPTS(); - /* - * Store the scanned tuple in the scan tuple slot of the scan state. - * Note: we pass 'false' because tuples returned by amgetnext are - * pointers onto disk pages and must not be pfree()'d. - */ - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - scandesc->xs_cbuf, /* buffer containing tuple */ - false); /* don't pfree */ - /* * If the index was lossy, we have to recheck the index quals using * the fetched tuple. @@ -184,7 +173,6 @@ IndexNextWithReorder(IndexScanState *node) EState *estate; ExprContext *econtext; IndexScanDesc scandesc; - HeapTuple tuple; TupleTableSlot *slot; ReorderTuple *topmost = NULL; bool was_exact; @@ -214,7 +202,7 @@ IndexNextWithReorder(IndexScanState *node) { /* * We reach here if the index scan is not parallel, or if we're - * executing a index scan that was intended to be parallel serially. + * serially executing an index scan that was planned to be parallel. */ scandesc = index_beginscan(node->ss.ss_currentRelation, node->iss_RelationDesc, @@ -254,10 +242,12 @@ IndexNextWithReorder(IndexScanState *node) scandesc->xs_orderbynulls, node) <= 0) { + HeapTuple tuple; + tuple = reorderqueue_pop(node); /* Pass 'true', as the tuple in the queue is a palloc'd copy */ - ExecStoreTuple(tuple, slot, InvalidBuffer, true); + ExecForceStoreHeapTuple(tuple, slot, true); return slot; } } @@ -271,8 +261,7 @@ IndexNextWithReorder(IndexScanState *node) * Fetch next tuple from the index. */ next_indextuple: - tuple = index_getnext(scandesc, ForwardScanDirection); - if (!tuple) + if (!index_getnext_slot(scandesc, ForwardScanDirection, slot)) { /* * No more tuples from the index. But we still need to drain any @@ -282,16 +271,6 @@ IndexNextWithReorder(IndexScanState *node) continue; } - /* - * Store the scanned tuple in the scan tuple slot of the scan state. - * Note: we pass 'false' because tuples returned by amgetnext are - * pointers onto disk pages and must not be pfree()'d. - */ - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - scandesc->xs_cbuf, /* buffer containing tuple */ - false); /* don't pfree */ - /* * If the index was lossy, we have to recheck the index quals and * ORDER BY expressions using the fetched tuple. @@ -360,7 +339,7 @@ IndexNextWithReorder(IndexScanState *node) node) > 0)) { /* Put this tuple to the queue */ - reorderqueue_push(node, tuple, lastfetched_vals, lastfetched_nulls); + reorderqueue_push(node, slot, lastfetched_vals, lastfetched_nulls); continue; } else @@ -469,16 +448,17 @@ reorderqueue_cmp(const pairingheap_node *a, const pairingheap_node *b, ReorderTuple *rtb = (ReorderTuple *) b; IndexScanState *node = (IndexScanState *) arg; - return -cmp_orderbyvals(rta->orderbyvals, rta->orderbynulls, - rtb->orderbyvals, rtb->orderbynulls, - node); + /* exchange argument order to invert the sort order */ + return cmp_orderbyvals(rtb->orderbyvals, rtb->orderbynulls, + rta->orderbyvals, rta->orderbynulls, + node); } /* * Helper function to push a tuple to the reorder queue. */ static void -reorderqueue_push(IndexScanState *node, HeapTuple tuple, +reorderqueue_push(IndexScanState *node, TupleTableSlot *slot, Datum *orderbyvals, bool *orderbynulls) { IndexScanDesc scandesc = node->iss_ScanDesc; @@ -488,7 +468,7 @@ reorderqueue_push(IndexScanState *node, HeapTuple tuple, int i; rt = (ReorderTuple *) palloc(sizeof(ReorderTuple)); - rt->htup = heap_copytuple(tuple); + rt->htup = ExecCopySlotHeapTuple(slot); rt->orderbyvals = (Datum *) palloc(sizeof(Datum) * scandesc->numberOfOrderBys); rt->orderbynulls = @@ -804,14 +784,12 @@ ExecEndIndexScan(IndexScanState *node) { Relation indexRelationDesc; IndexScanDesc indexScanDesc; - Relation relation; /* * extract information from the node */ indexRelationDesc = node->iss_RelationDesc; indexScanDesc = node->iss_ScanDesc; - relation = node->ss.ss_currentRelation; /* * Free the exprcontext(s) ... now dead code, see ExecFreeExprContext @@ -825,7 +803,8 @@ ExecEndIndexScan(IndexScanState *node) /* * clear out tuple table slots */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -835,11 +814,6 @@ ExecEndIndexScan(IndexScanState *node) index_endscan(indexScanDesc); if (indexRelationDesc) index_close(indexRelationDesc, NoLock); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(relation); } /* ---------------------------------------------------------------- @@ -853,25 +827,27 @@ void ExecIndexMarkPos(IndexScanState *node) { EState *estate = node->ss.ps.state; + EPQState *epqstate = estate->es_epq_active; - if (estate->es_epqTuple != NULL) + if (epqstate != NULL) { /* * We are inside an EvalPlanQual recheck. If a test tuple exists for * this relation, then we shouldn't access the index at all. We would * instead need to save, and later restore, the state of the - * es_epqScanDone flag, so that re-fetching the test tuple is - * possible. However, given the assumption that no caller sets a mark - * at the start of the scan, we can only get here with es_epqScanDone + * relsubs_done flag, so that re-fetching the test tuple is possible. + * However, given the assumption that no caller sets a mark at the + * start of the scan, we can only get here with relsubs_done[i] * already set, and so no state need be saved. */ Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid; Assert(scanrelid > 0); - if (estate->es_epqTupleSet[scanrelid - 1]) + if (epqstate->relsubs_slot[scanrelid - 1] != NULL || + epqstate->relsubs_rowmark[scanrelid - 1] != NULL) { /* Verify the claim above */ - if (!estate->es_epqScanDone[scanrelid - 1]) + if (!epqstate->relsubs_done[scanrelid - 1]) elog(ERROR, "unexpected ExecIndexMarkPos call in EPQ recheck"); return; } @@ -888,17 +864,19 @@ void ExecIndexRestrPos(IndexScanState *node) { EState *estate = node->ss.ps.state; + EPQState *epqstate = estate->es_epq_active; - if (estate->es_epqTuple != NULL) + if (estate->es_epq_active != NULL) { /* See comments in ExecIndexMarkPos */ Index scanrelid = ((Scan *) node->ss.ps.plan)->scanrelid; Assert(scanrelid > 0); - if (estate->es_epqTupleSet[scanrelid - 1]) + if (epqstate->relsubs_slot[scanrelid - 1] != NULL || + epqstate->relsubs_rowmark[scanrelid - 1] != NULL) { /* Verify the claim above */ - if (!estate->es_epqScanDone[scanrelid - 1]) + if (!epqstate->relsubs_done[scanrelid - 1]) elog(ERROR, "unexpected ExecIndexRestrPos call in EPQ recheck"); return; } @@ -923,7 +901,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) { IndexScanState *indexstate; Relation currentRelation; - bool relistarget; + LOCKMODE lockmode; /* * create state structure @@ -941,7 +919,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &indexstate->ss.ps); /* - * open the base relation and acquire appropriate lock on it. + * open the scan relation */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); @@ -952,12 +930,13 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) * get the scan type from the relation descriptor. */ ExecInitScanTupleSlot(estate, &indexstate->ss, - RelationGetDescr(currentRelation)); + RelationGetDescr(currentRelation), + table_slot_callbacks(currentRelation)); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &indexstate->ss.ps); + ExecInitResultTypeTL(&indexstate->ss.ps); ExecAssignScanProjectionInfo(&indexstate->ss); /* @@ -985,16 +964,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags) if (eflags & EXEC_FLAG_EXPLAIN_ONLY) return indexstate; - /* - * Open the index relation. - * - * If the parent table is one of the target relations of the query, then - * InitPlan already opened and write-locked the index, so we can avoid - * taking another lock here. Otherwise we need a normal reader's lock. - */ - relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid); - indexstate->iss_RelationDesc = index_open(node->indexid, - relistarget ? NoLock : AccessShareLock); + /* Open the index relation. */ + lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode; + indexstate->iss_RelationDesc = index_open(node->indexid, lockmode); /* * Initialize index-specific scan state @@ -1331,12 +1303,12 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, { /* (indexkey, indexkey, ...) op (expression, expression, ...) */ RowCompareExpr *rc = (RowCompareExpr *) clause; - ListCell *largs_cell = list_head(rc->largs); - ListCell *rargs_cell = list_head(rc->rargs); - ListCell *opnos_cell = list_head(rc->opnos); - ListCell *collids_cell = list_head(rc->inputcollids); ScanKey first_sub_key; int n_sub_key; + ListCell *largs_cell; + ListCell *rargs_cell; + ListCell *opnos_cell; + ListCell *collids_cell; Assert(!isorderby); @@ -1345,19 +1317,22 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, n_sub_key = 0; /* Scan RowCompare columns and generate subsidiary ScanKey items */ - while (opnos_cell != NULL) + forfour(largs_cell, rc->largs, rargs_cell, rc->rargs, + opnos_cell, rc->opnos, collids_cell, rc->inputcollids) { ScanKey this_sub_key = &first_sub_key[n_sub_key]; int flags = SK_ROW_MEMBER; Datum scanvalue; Oid inputcollation; + leftop = (Expr *) lfirst(largs_cell); + rightop = (Expr *) lfirst(rargs_cell); + opno = lfirst_oid(opnos_cell); + inputcollation = lfirst_oid(collids_cell); + /* * leftop should be the index key Var, possibly relabeled */ - leftop = (Expr *) lfirst(largs_cell); - largs_cell = lnext(largs_cell); - if (leftop && IsA(leftop, RelabelType)) leftop = ((RelabelType *) leftop)->arg; @@ -1373,9 +1348,6 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, * We have to look up the operator's associated btree support * function */ - opno = lfirst_oid(opnos_cell); - opnos_cell = lnext(opnos_cell); - if (index->rd_rel->relam != BTREE_AM_OID || varattno < 1 || varattno > indnkeyatts) elog(ERROR, "bogus RowCompare index qualification"); @@ -1397,15 +1369,9 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, elog(ERROR, "missing support function %d(%u,%u) in opfamily %u", BTORDER_PROC, op_lefttype, op_righttype, opfamily); - inputcollation = lfirst_oid(collids_cell); - collids_cell = lnext(collids_cell); - /* * rightop is the constant or variable comparison value */ - rightop = (Expr *) lfirst(rargs_cell); - rargs_cell = lnext(rargs_cell); - if (rightop && IsA(rightop, RelabelType)) rightop = ((RelabelType *) rightop)->arg; @@ -1525,7 +1491,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index, Assert(rightop != NULL); - if (index->rd_amroutine->amsearcharray) + if (index->rd_indam->amsearcharray) { /* Index AM will handle this like a simple operator */ flags |= SK_SEARCHARRAY; diff --git a/src/backend/executor/nodeLimit.c b/src/backend/executor/nodeLimit.c index 56d98b4490b..baa669abe84 100644 --- a/src/backend/executor/nodeLimit.c +++ b/src/backend/executor/nodeLimit.c @@ -3,7 +3,7 @@ * nodeLimit.c * Routines to handle limiting of query results where appropriate * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -134,6 +134,14 @@ ExecLimit(PlanState *pstate) node->position - node->offset >= node->count) { node->lstate = LIMIT_WINDOWEND; + + /* + * If we know we won't need to back up, we can release + * resources at this point. + */ + if (!(node->ps.state->es_top_eflags & EXEC_FLAG_BACKWARD)) + (void) ExecShutdownNode(outerPlan); + return NULL; } @@ -368,10 +376,13 @@ ExecInitLimit(Limit *node, EState *estate, int eflags) (PlanState *) limitstate); /* - * Initialize result slot and type. (XXX not actually used, but upper - * nodes access it to get this node's result tupledesc...) + * Initialize result type. */ - ExecInitResultTupleSlotTL(estate, &limitstate->ps); + ExecInitResultTypeTL(&limitstate->ps); + + limitstate->ps.resultopsset = true; + limitstate->ps.resultops = ExecGetResultSlotOps(outerPlanState(limitstate), + &limitstate->ps.resultopsfixed); /* * limit nodes do no projections, so initialize projection info for this diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c index ace126cbf24..72c5b7cab2d 100644 --- a/src/backend/executor/nodeLockRows.c +++ b/src/backend/executor/nodeLockRows.c @@ -3,7 +3,7 @@ * nodeLockRows.c * Routines to handle FOR UPDATE/FOR SHARE row locking * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,15 +21,13 @@ #include "postgres.h" -#include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "executor/executor.h" #include "executor/nodeLockRows.h" #include "foreign/fdwapi.h" #include "miscadmin.h" -#include "storage/bufmgr.h" #include "utils/rel.h" -#include "utils/tqual.h" /* ---------------------------------------------------------------- @@ -74,21 +72,18 @@ ExecLockRows(PlanState *pstate) { ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(lc); ExecRowMark *erm = aerm->rowmark; - HeapTuple *testTuple; Datum datum; bool isNull; - HeapTupleData tuple; - Buffer buffer; - HeapUpdateFailureData hufd; + ItemPointerData tid; + TM_FailureData tmfd; LockTupleMode lockmode; - HTSU_Result test; - HeapTuple copyTuple; + int lockflags = 0; + TM_Result test; + TupleTableSlot *markSlot; /* clear any leftover test tuple for this rel */ - testTuple = &(node->lr_curtuples[erm->rti - 1]); - if (*testTuple != NULL) - heap_freetuple(*testTuple); - *testTuple = NULL; + markSlot = EvalPlanQualSlot(&node->lr_epqstate, erm->relation, erm->rti); + ExecClearTuple(markSlot); /* if child rel, must check whether it produced this row */ if (erm->rti != erm->prti) @@ -109,6 +104,7 @@ ExecLockRows(PlanState *pstate) /* this child is inactive right now */ erm->ermActive = false; ItemPointerSetInvalid(&(erm->curCtid)); + ExecClearTuple(markSlot); continue; } } @@ -135,19 +131,18 @@ ExecLockRows(PlanState *pstate) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot lock rows in foreign table \"%s\"", RelationGetRelationName(erm->relation)))); - copyTuple = fdwroutine->RefetchForeignRow(estate, - erm, - datum, - &updated); - if (copyTuple == NULL) + + fdwroutine->RefetchForeignRow(estate, + erm, + datum, + markSlot, + &updated); + if (TupIsNull(markSlot)) { /* couldn't get the lock, so skip this row */ goto lnext; } - /* save locked tuple for possible EvalPlanQual testing below */ - *testTuple = copyTuple; - /* * if FDW says tuple was updated before getting locked, we need to * perform EPQ testing to see if quals are still satisfied @@ -158,8 +153,8 @@ ExecLockRows(PlanState *pstate) continue; } - /* okay, try to lock the tuple */ - tuple.t_self = *((ItemPointer) DatumGetPointer(datum)); + /* okay, try to lock (and fetch) the tuple */ + tid = *((ItemPointer) DatumGetPointer(datum)); switch (erm->markType) { case ROW_MARK_EXCLUSIVE: @@ -180,18 +175,23 @@ ExecLockRows(PlanState *pstate) break; } - test = heap_lock_tuple(erm->relation, &tuple, - estate->es_output_cid, - lockmode, erm->waitPolicy, true, - &buffer, &hufd); - ReleaseBuffer(buffer); + lockflags = TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS; + if (!IsolationUsesXactSnapshot()) + lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION; + + test = table_tuple_lock(erm->relation, &tid, estate->es_snapshot, + markSlot, estate->es_output_cid, + lockmode, erm->waitPolicy, + lockflags, + &tmfd); + switch (test) { - case HeapTupleWouldBlock: + case TM_WouldBlock: /* couldn't lock tuple in SKIP LOCKED mode */ goto lnext; - case HeapTupleSelfUpdated: + case TM_SelfModified: /* * The target tuple was already updated or deleted by the @@ -202,68 +202,50 @@ ExecLockRows(PlanState *pstate) * to fetch the updated tuple instead, but doing so would * require changing heap_update and heap_delete to not * complain about updating "invisible" tuples, which seems - * pretty scary (heap_lock_tuple will not complain, but few - * callers expect HeapTupleInvisible, and we're not one of - * them). So for now, treat the tuple as deleted and do not - * process. + * pretty scary (table_tuple_lock will not complain, but few + * callers expect TM_Invisible, and we're not one of them). So + * for now, treat the tuple as deleted and do not process. */ goto lnext; - case HeapTupleMayBeUpdated: - /* got the lock successfully */ + case TM_Ok: + + /* + * Got the lock successfully, the locked tuple saved in + * markSlot for, if needed, EvalPlanQual testing below. + */ + if (tmfd.traversed) + epq_needed = true; break; - case HeapTupleUpdated: + case TM_Updated: if (IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("could not serialize access due to concurrent update"))); - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) + elog(ERROR, "unexpected table_tuple_lock status: %u", + test); + break; + + case TM_Deleted: + if (IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be locked was already moved to another partition due to concurrent update"))); - - if (ItemPointerEquals(&hufd.ctid, &tuple.t_self)) - { - /* Tuple was deleted, so don't return it */ - goto lnext; - } - - /* updated, so fetch and lock the updated version */ - copyTuple = EvalPlanQualFetch(estate, erm->relation, - lockmode, erm->waitPolicy, - &hufd.ctid, hufd.xmax); - - if (copyTuple == NULL) - { - /* - * Tuple was deleted; or it's locked and we're under SKIP - * LOCKED policy, so don't return it - */ - goto lnext; - } - /* remember the actually locked tuple's TID */ - tuple.t_self = copyTuple->t_self; - - /* Save locked tuple for EvalPlanQual testing below */ - *testTuple = copyTuple; - - /* Remember we need to do EPQ testing */ - epq_needed = true; - - /* Continue loop until we have all target tuples */ - break; + errmsg("could not serialize access due to concurrent update"))); + /* tuple was deleted so don't return it */ + goto lnext; - case HeapTupleInvisible: + case TM_Invisible: elog(ERROR, "attempted to lock invisible tuple"); + break; default: - elog(ERROR, "unrecognized heap_lock_tuple status: %u", + elog(ERROR, "unrecognized table_tuple_lock status: %u", test); } /* Remember locked tuple's TID for EPQ testing and WHERE CURRENT OF */ - erm->curCtid = tuple.t_self; + erm->curCtid = tid; } /* @@ -272,64 +254,13 @@ ExecLockRows(PlanState *pstate) if (epq_needed) { /* Initialize EPQ machinery */ - EvalPlanQualBegin(&node->lr_epqstate, estate); - - /* - * Transfer any already-fetched tuples into the EPQ state, and fetch a - * copy of any rows that were successfully locked without any update - * having occurred. (We do this in a separate pass so as to avoid - * overhead in the common case where there are no concurrent updates.) - * Make sure any inactive child rels have NULL test tuples in EPQ. - */ - foreach(lc, node->lr_arowMarks) - { - ExecAuxRowMark *aerm = (ExecAuxRowMark *) lfirst(lc); - ExecRowMark *erm = aerm->rowmark; - HeapTupleData tuple; - Buffer buffer; - - /* skip non-active child tables, but clear their test tuples */ - if (!erm->ermActive) - { - Assert(erm->rti != erm->prti); /* check it's child table */ - EvalPlanQualSetTuple(&node->lr_epqstate, erm->rti, NULL); - continue; - } - - /* was tuple updated and fetched above? */ - if (node->lr_curtuples[erm->rti - 1] != NULL) - { - /* yes, so set it as the EPQ test tuple for this rel */ - EvalPlanQualSetTuple(&node->lr_epqstate, - erm->rti, - node->lr_curtuples[erm->rti - 1]); - /* freeing this tuple is now the responsibility of EPQ */ - node->lr_curtuples[erm->rti - 1] = NULL; - continue; - } - - /* foreign tables should have been fetched above */ - Assert(erm->relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE); - Assert(ItemPointerIsValid(&(erm->curCtid))); - - /* okay, fetch the tuple */ - tuple.t_self = erm->curCtid; - if (!heap_fetch(erm->relation, SnapshotAny, &tuple, &buffer, - false, NULL)) - elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck"); - - /* successful, copy and store tuple */ - EvalPlanQualSetTuple(&node->lr_epqstate, erm->rti, - heap_copytuple(&tuple)); - ReleaseBuffer(buffer); - } + EvalPlanQualBegin(&node->lr_epqstate); /* - * Now fetch any non-locked source rows --- the EPQ logic knows how to - * do that. + * To fetch non-locked source rows the EPQ logic needs to access junk + * columns from the tuple being tested. */ EvalPlanQualSetSlot(&node->lr_epqstate, slot); - EvalPlanQualFetchRowMarks(&node->lr_epqstate); /* * And finally we can re-evaluate the tuple. @@ -380,29 +311,26 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) */ /* - * Tuple table initialization (XXX not actually used, but upper nodes - * access it to get this node's result tupledesc...) + * Initialize result type. */ - ExecInitResultTupleSlotTL(estate, &lrstate->ps); + ExecInitResultTypeTL(&lrstate->ps); /* * then initialize outer plan */ outerPlanState(lrstate) = ExecInitNode(outerPlan, estate, eflags); + /* node returns unmodified slots from the outer plan */ + lrstate->ps.resultopsset = true; + lrstate->ps.resultops = ExecGetResultSlotOps(outerPlanState(lrstate), + &lrstate->ps.resultopsfixed); + /* * LockRows nodes do no projections, so initialize projection info for * this node appropriately */ lrstate->ps.ps_ProjInfo = NULL; - /* - * Create workspace in which we can remember per-RTE locked tuples - */ - lrstate->lr_ntables = list_length(estate->es_range_table); - lrstate->lr_curtuples = (HeapTuple *) - palloc0(lrstate->lr_ntables * sizeof(HeapTuple)); - /* * Locate the ExecRowMark(s) that this node is responsible for, and * construct ExecAuxRowMarks for them. (InitPlan should already have @@ -420,9 +348,6 @@ ExecInitLockRows(LockRows *node, EState *estate, int eflags) if (rc->isParent) continue; - /* safety check on size of lr_curtuples array */ - Assert(rc->rti > 0 && rc->rti <= lrstate->lr_ntables); - /* find ExecRowMark and build ExecAuxRowMark */ erm = ExecFindRowMark(estate, rc->rti, false); aerm = ExecBuildAuxRowMark(erm, outerPlan->targetlist); diff --git a/src/backend/executor/nodeMaterial.c b/src/backend/executor/nodeMaterial.c index 8c2e57dbd07..cc93bbe45b0 100644 --- a/src/backend/executor/nodeMaterial.c +++ b/src/backend/executor/nodeMaterial.c @@ -3,7 +3,7 @@ * nodeMaterial.c * Routines to handle materialization nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -146,10 +146,8 @@ ExecMaterial(PlanState *pstate) if (tuplestorestate) tuplestore_puttupleslot(tuplestorestate, outerslot); - /* - * We can just return the subplan's returned tuple, without copying. - */ - return outerslot; + ExecCopySlot(slot, outerslot); + return slot; } /* @@ -223,13 +221,13 @@ ExecInitMaterial(Material *node, EState *estate, int eflags) * * material nodes only return tuples from their materialized relation. */ - ExecInitResultTupleSlotTL(estate, &matstate->ss.ps); + ExecInitResultTupleSlotTL(&matstate->ss.ps, &TTSOpsMinimalTuple); matstate->ss.ps.ps_ProjInfo = NULL; /* * initialize tuple type. */ - ExecCreateScanSlotFromOuterPlan(estate, &matstate->ss); + ExecCreateScanSlotFromOuterPlan(estate, &matstate->ss, &TTSOpsMinimalTuple); return matstate; } diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 118f4ef07df..18d13377dc3 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -3,7 +3,7 @@ * nodeMergeAppend.c * routines to handle MergeAppend nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -39,6 +39,7 @@ #include "postgres.h" #include "executor/execdebug.h" +#include "executor/execPartition.h" #include "executor/nodeMergeAppend.h" #include "lib/binaryheap.h" #include "miscadmin.h" @@ -65,32 +66,93 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) { MergeAppendState *mergestate = makeNode(MergeAppendState); PlanState **mergeplanstates; + Bitmapset *validsubplans; int nplans; - int i; - ListCell *lc; + int i, + j; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); - /* - * Lock the non-leaf tables in the partition tree controlled by this node. - * It's a no-op for non-partitioned parent tables. - */ - ExecLockNonLeafAppendTables(node->partitioned_rels, estate); - - /* - * Set up empty vector of subplan states - */ - nplans = list_length(node->mergeplans); - - mergeplanstates = (PlanState **) palloc0(nplans * sizeof(PlanState *)); - /* * create new MergeAppendState for our node */ mergestate->ps.plan = (Plan *) node; mergestate->ps.state = estate; mergestate->ps.ExecProcNode = ExecMergeAppend; + mergestate->ms_noopscan = false; + + /* If run-time partition pruning is enabled, then set that up now */ + if (node->part_prune_info != NULL) + { + PartitionPruneState *prunestate; + + /* We may need an expression context to evaluate partition exprs */ + ExecAssignExprContext(estate, &mergestate->ps); + + prunestate = ExecCreatePartitionPruneState(&mergestate->ps, + node->part_prune_info); + mergestate->ms_prune_state = prunestate; + + /* Perform an initial partition prune, if required. */ + if (prunestate->do_initial_prune) + { + /* Determine which subplans survive initial pruning */ + validsubplans = ExecFindInitialMatchingSubPlans(prunestate, + list_length(node->mergeplans)); + + /* + * The case where no subplans survive pruning must be handled + * specially. The problem here is that code in explain.c requires + * a MergeAppend to have at least one subplan in order for it to + * properly determine the Vars in that subplan's targetlist. We + * sidestep this issue by just initializing the first subplan and + * setting ms_noopscan to true to indicate that we don't really + * need to scan any subnodes. + */ + if (bms_is_empty(validsubplans)) + { + mergestate->ms_noopscan = true; + + /* Mark the first as valid so that it's initialized below */ + validsubplans = bms_make_singleton(0); + } + + nplans = bms_num_members(validsubplans); + } + else + { + /* We'll need to initialize all subplans */ + nplans = list_length(node->mergeplans); + Assert(nplans > 0); + validsubplans = bms_add_range(NULL, 0, nplans - 1); + } + + /* + * If no runtime pruning is required, we can fill ms_valid_subplans + * immediately, preventing later calls to ExecFindMatchingSubPlans. + */ + if (!prunestate->do_exec_prune) + { + Assert(nplans > 0); + mergestate->ms_valid_subplans = bms_add_range(NULL, 0, nplans - 1); + } + } + else + { + nplans = list_length(node->mergeplans); + + /* + * When run-time partition pruning is not enabled we can just mark all + * subplans as valid; they must also all be initialized. + */ + Assert(nplans > 0); + mergestate->ms_valid_subplans = validsubplans = + bms_add_range(NULL, 0, nplans - 1); + mergestate->ms_prune_state = NULL; + } + + mergeplanstates = (PlanState **) palloc(nplans * sizeof(PlanState *)); mergestate->mergeplans = mergeplanstates; mergestate->ms_nplans = nplans; @@ -101,27 +163,26 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) /* * Miscellaneous initialization * - * MergeAppend plans don't have expression contexts because they never - * call ExecQual or ExecProject. - */ - - /* * MergeAppend nodes do have Result slots, which hold pointers to tuples, - * so we have to initialize them. + * so we have to initialize them. FIXME */ - ExecInitResultTupleSlotTL(estate, &mergestate->ps); + ExecInitResultTupleSlotTL(&mergestate->ps, &TTSOpsVirtual); + + /* node returns slots from each of its subnodes, therefore not fixed */ + mergestate->ps.resultopsset = true; + mergestate->ps.resultopsfixed = false; /* - * call ExecInitNode on each of the plans to be executed and save the - * results into the array "mergeplans". + * call ExecInitNode on each of the valid plans to be executed and save + * the results into the mergeplanstates array. */ - i = 0; - foreach(lc, node->mergeplans) + j = 0; + i = -1; + while ((i = bms_next_member(validsubplans, i)) >= 0) { - Plan *initNode = (Plan *) lfirst(lc); + Plan *initNode = (Plan *) list_nth(node->mergeplans, i); - mergeplanstates[i] = ExecInitNode(initNode, estate, eflags); - i++; + mergeplanstates[j++] = ExecInitNode(initNode, estate, eflags); } mergestate->ps.ps_ProjInfo = NULL; @@ -178,11 +239,25 @@ ExecMergeAppend(PlanState *pstate) if (!node->ms_initialized) { + /* Nothing to do if all subplans were pruned */ + if (node->ms_noopscan) + return ExecClearTuple(node->ps.ps_ResultTupleSlot); + + /* + * If we've yet to determine the valid subplans then do so now. If + * run-time pruning is disabled then the valid subplans will always be + * set to all subplans. + */ + if (node->ms_valid_subplans == NULL) + node->ms_valid_subplans = + ExecFindMatchingSubPlans(node->ms_prune_state); + /* - * First time through: pull the first tuple from each subplan, and set - * up the heap. + * First time through: pull the first tuple from each valid subplan, + * and set up the heap. */ - for (i = 0; i < node->ms_nplans; i++) + i = -1; + while ((i = bms_next_member(node->ms_valid_subplans, i)) >= 0) { node->ms_slots[i] = ExecProcNode(node->mergeplans[i]); if (!TupIsNull(node->ms_slots[i])) @@ -257,7 +332,10 @@ heap_compare_slots(Datum a, Datum b, void *arg) datum2, isNull2, sortKey); if (compare != 0) - return -compare; + { + INVERT_COMPARE_RESULT(compare); + return compare; + } } return 0; } @@ -295,6 +373,19 @@ ExecReScanMergeAppend(MergeAppendState *node) { int i; + /* + * If any PARAM_EXEC Params used in pruning expressions have changed, then + * we'd better unset the valid subplans so that they are reselected for + * the new parameter values. + */ + if (node->ms_prune_state && + bms_overlap(node->ps.chgParam, + node->ms_prune_state->execparamids)) + { + bms_free(node->ms_valid_subplans); + node->ms_valid_subplans = NULL; + } + for (i = 0; i < node->ms_nplans; i++) { PlanState *subnode = node->mergeplans[i]; diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c index f3cbe2f889b..2a1d000b03d 100644 --- a/src/backend/executor/nodeMergejoin.c +++ b/src/backend/executor/nodeMergejoin.c @@ -3,7 +3,7 @@ * nodeMergejoin.c * routines supporting merge joins * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -1436,7 +1436,9 @@ MergeJoinState * ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) { MergeJoinState *mergestate; - TupleDesc outerDesc, innerDesc; + TupleDesc outerDesc, + innerDesc; + const TupleTableSlotOps *innerOps; /* check for unsupported flags */ Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK))); @@ -1511,13 +1513,15 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &mergestate->js.ps); + ExecInitResultTupleSlotTL(&mergestate->js.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&mergestate->js.ps, NULL); /* * tuple table initialization */ - mergestate->mj_MarkedTupleSlot = ExecInitExtraTupleSlot(estate, innerDesc); + innerOps = ExecGetResultSlotOps(innerPlanState(mergestate), NULL); + mergestate->mj_MarkedTupleSlot = ExecInitExtraTupleSlot(estate, innerDesc, + innerOps); /* * initialize child expressions @@ -1547,13 +1551,13 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) mergestate->mj_FillOuter = true; mergestate->mj_FillInner = false; mergestate->mj_NullInnerTupleSlot = - ExecInitNullTupleSlot(estate, innerDesc); + ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual); break; case JOIN_RIGHT: mergestate->mj_FillOuter = false; mergestate->mj_FillInner = true; mergestate->mj_NullOuterTupleSlot = - ExecInitNullTupleSlot(estate, outerDesc); + ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual); /* * Can't handle right or full join with non-constant extra @@ -1569,9 +1573,9 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags) mergestate->mj_FillOuter = true; mergestate->mj_FillInner = true; mergestate->mj_NullOuterTupleSlot = - ExecInitNullTupleSlot(estate, outerDesc); + ExecInitNullTupleSlot(estate, outerDesc, &TTSOpsVirtual); mergestate->mj_NullInnerTupleSlot = - ExecInitNullTupleSlot(estate, innerDesc); + ExecInitNullTupleSlot(estate, innerDesc, &TTSOpsVirtual); /* * Can't handle right or full join with non-constant extra diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index f47649d0517..c9d024ead56 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -3,7 +3,7 @@ * nodeModifyTable.c * routines to handle ModifyTable nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,37 +37,44 @@ #include "postgres.h" +#include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "commands/trigger.h" #include "executor/execPartition.h" #include "executor/executor.h" -#include "executor/execMerge.h" #include "executor/nodeModifyTable.h" #include "foreign/fdwapi.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" +#include "rewrite/rewriteHandler.h" #include "storage/bufmgr.h" #include "storage/lmgr.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/tqual.h" static bool ExecOnConflictUpdate(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo, - ItemPointer conflictTid, - TupleTableSlot *planSlot, - TupleTableSlot *excludedSlot, - EState *estate, - bool canSetTag, - TupleTableSlot **returning); + ResultRelInfo *resultRelInfo, + ItemPointer conflictTid, + TupleTableSlot *planSlot, + TupleTableSlot *excludedSlot, + EState *estate, + bool canSetTag, + TupleTableSlot **returning); +static TupleTableSlot *ExecPrepareTupleRouting(ModifyTableState *mtstate, + EState *estate, + PartitionTupleRouting *proute, + ResultRelInfo *targetRelInfo, + TupleTableSlot *slot); static ResultRelInfo *getTargetResultRelInfo(ModifyTableState *node); -static void ExecSetupChildParentMapForTcs(ModifyTableState *mtstate); static void ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate); static TupleConversionMap *tupconv_map_for_subplan(ModifyTableState *node, - int whichplan); + int whichplan); /* * Verify that the tuples to be produced by INSERT or UPDATE match the @@ -81,7 +88,7 @@ static TupleConversionMap *tupconv_map_for_subplan(ModifyTableState *node, * The plan output is represented by its targetlist, because that makes * handling the dropped-column case easier. */ -void +static void ExecCheckPlanOutput(Relation resultRel, List *targetList) { TupleDesc resultDesc = RelationGetDescr(resultRel); @@ -159,35 +166,24 @@ ExecProcessReturning(ResultRelInfo *resultRelInfo, ProjectionInfo *projectReturning = resultRelInfo->ri_projectReturning; ExprContext *econtext = projectReturning->pi_exprContext; - /* - * Reset per-tuple memory context to free any expression evaluation - * storage allocated in the previous cycle. - */ - ResetExprContext(econtext); - /* Make tuple and any needed join variables available to ExecProject */ if (tupleSlot) econtext->ecxt_scantuple = tupleSlot; - else - { - HeapTuple tuple; - - /* - * RETURNING expressions might reference the tableoid column, so - * initialize t_tableOid before evaluating them. - */ - Assert(!TupIsNull(econtext->ecxt_scantuple)); - tuple = ExecMaterializeSlot(econtext->ecxt_scantuple); - tuple->t_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); - } econtext->ecxt_outertuple = planSlot; + /* + * RETURNING expressions might reference the tableoid column, so + * reinitialize tts_tableOid before evaluating them. + */ + econtext->ecxt_scantuple->tts_tableOid = + RelationGetRelid(resultRelInfo->ri_RelationDesc); + /* Compute the RETURNING expressions */ return ExecProject(projectReturning); } /* - * ExecCheckHeapTupleVisible -- verify heap tuple is visible + * ExecCheckTupleVisible -- verify tuple is visible * * It would not be consistent with guarantees of the higher isolation levels to * proceed with avoiding insertion (taking speculative insertion's alternative @@ -195,55 +191,143 @@ ExecProcessReturning(ResultRelInfo *resultRelInfo, * Check for the need to raise a serialization failure, and do so as necessary. */ static void -ExecCheckHeapTupleVisible(EState *estate, - HeapTuple tuple, - Buffer buffer) +ExecCheckTupleVisible(EState *estate, + Relation rel, + TupleTableSlot *slot) { if (!IsolationUsesXactSnapshot()) return; - /* - * We need buffer pin and lock to call HeapTupleSatisfiesVisibility. - * Caller should be holding pin, but not lock. - */ - LockBuffer(buffer, BUFFER_LOCK_SHARE); - if (!HeapTupleSatisfiesVisibility(tuple, estate->es_snapshot, buffer)) + if (!table_tuple_satisfies_snapshot(rel, slot, estate->es_snapshot)) { + Datum xminDatum; + TransactionId xmin; + bool isnull; + + xminDatum = slot_getsysattr(slot, MinTransactionIdAttributeNumber, &isnull); + Assert(!isnull); + xmin = DatumGetTransactionId(xminDatum); + /* * We should not raise a serialization failure if the conflict is * against a tuple inserted by our own transaction, even if it's not * visible to our snapshot. (This would happen, for example, if * conflicting keys are proposed for insertion in a single command.) */ - if (!TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple->t_data))) + if (!TransactionIdIsCurrentTransactionId(xmin)) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("could not serialize access due to concurrent update"))); } - LockBuffer(buffer, BUFFER_LOCK_UNLOCK); } /* - * ExecCheckTIDVisible -- convenience variant of ExecCheckHeapTupleVisible() + * ExecCheckTIDVisible -- convenience variant of ExecCheckTupleVisible() */ static void ExecCheckTIDVisible(EState *estate, ResultRelInfo *relinfo, - ItemPointer tid) + ItemPointer tid, + TupleTableSlot *tempSlot) { Relation rel = relinfo->ri_RelationDesc; - Buffer buffer; - HeapTupleData tuple; /* Redundantly check isolation level */ if (!IsolationUsesXactSnapshot()) return; - tuple.t_self = *tid; - if (!heap_fetch(rel, SnapshotAny, &tuple, &buffer, false, NULL)) + if (!table_tuple_fetch_row_version(rel, tid, SnapshotAny, tempSlot)) elog(ERROR, "failed to fetch conflicting tuple for ON CONFLICT"); - ExecCheckHeapTupleVisible(estate, &tuple, buffer); - ReleaseBuffer(buffer); + ExecCheckTupleVisible(estate, rel, tempSlot); + ExecClearTuple(tempSlot); +} + +/* + * Compute stored generated columns for a tuple + */ +void +ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot) +{ + ResultRelInfo *resultRelInfo = estate->es_result_relation_info; + Relation rel = resultRelInfo->ri_RelationDesc; + TupleDesc tupdesc = RelationGetDescr(rel); + int natts = tupdesc->natts; + MemoryContext oldContext; + Datum *values; + bool *nulls; + + Assert(tupdesc->constr && tupdesc->constr->has_generated_stored); + + /* + * If first time through for this result relation, build expression + * nodetrees for rel's stored generation expressions. Keep them in the + * per-query memory context so they'll survive throughout the query. + */ + if (resultRelInfo->ri_GeneratedExprs == NULL) + { + oldContext = MemoryContextSwitchTo(estate->es_query_cxt); + + resultRelInfo->ri_GeneratedExprs = + (ExprState **) palloc(natts * sizeof(ExprState *)); + + for (int i = 0; i < natts; i++) + { + if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED) + { + Expr *expr; + + expr = (Expr *) build_column_default(rel, i + 1); + if (expr == NULL) + elog(ERROR, "no generation expression found for column number %d of table \"%s\"", + i + 1, RelationGetRelationName(rel)); + + resultRelInfo->ri_GeneratedExprs[i] = ExecPrepareExpr(expr, estate); + } + } + + MemoryContextSwitchTo(oldContext); + } + + oldContext = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + + values = palloc(sizeof(*values) * natts); + nulls = palloc(sizeof(*nulls) * natts); + + slot_getallattrs(slot); + memcpy(nulls, slot->tts_isnull, sizeof(*nulls) * natts); + + for (int i = 0; i < natts; i++) + { + Form_pg_attribute attr = TupleDescAttr(tupdesc, i); + + if (attr->attgenerated == ATTRIBUTE_GENERATED_STORED) + { + ExprContext *econtext; + Datum val; + bool isnull; + + econtext = GetPerTupleExprContext(estate); + econtext->ecxt_scantuple = slot; + + val = ExecEvalExpr(resultRelInfo->ri_GeneratedExprs[i], econtext, &isnull); + + values[i] = val; + nulls[i] = isnull; + } + else + { + if (!nulls[i]) + values[i] = datumCopy(slot->tts_values[i], attr->attbyval, attr->attlen); + } + } + + ExecClearTuple(slot); + memcpy(slot->tts_values, values, sizeof(*values) * natts); + memcpy(slot->tts_isnull, nulls, sizeof(*nulls) * natts); + ExecStoreVirtualTuple(slot); + ExecMaterializeSlot(slot); + + MemoryContextSwitchTo(oldContext); } /* ---------------------------------------------------------------- @@ -255,29 +339,22 @@ ExecCheckTIDVisible(EState *estate, * Returns RETURNING result if any, otherwise NULL. * ---------------------------------------------------------------- */ -extern TupleTableSlot * +static TupleTableSlot * ExecInsert(ModifyTableState *mtstate, TupleTableSlot *slot, TupleTableSlot *planSlot, EState *estate, - MergeActionState *actionState, bool canSetTag) { - HeapTuple tuple; ResultRelInfo *resultRelInfo; Relation resultRelationDesc; - Oid newId; List *recheckIndexes = NIL; TupleTableSlot *result = NULL; TransitionCaptureState *ar_insert_trig_tcs; ModifyTable *node = (ModifyTable *) mtstate->ps.plan; OnConflictAction onconflict = node->onConflictAction; - /* - * get the heap tuple out of the tuple table slot, making sure we have a - * writable copy - */ - tuple = ExecMaterializeSlot(slot); + ExecMaterializeSlot(slot); /* * get information on the (current) result relation @@ -285,21 +362,6 @@ ExecInsert(ModifyTableState *mtstate, resultRelInfo = estate->es_result_relation_info; resultRelationDesc = resultRelInfo->ri_RelationDesc; - /* - * If the result relation has OIDs, force the tuple's OID to zero so that - * heap_insert will assign a fresh OID. Usually the OID already will be - * zero at this point, but there are corner cases where the plan tree can - * return a tuple extracted literally from some table with the same - * rowtype. - * - * XXX if we ever wanted to allow users to assign their own OIDs to new - * rows, this'd be the place to do it. For the moment, we make a point of - * doing this before calling triggers, so that a user-supplied trigger - * could hack the OID if desired. - */ - if (resultRelationDesc->rd_rel->relhasoids) - HeapTupleSetOid(tuple, InvalidOid); - /* * BEFORE ROW INSERT Triggers. * @@ -312,31 +374,26 @@ ExecInsert(ModifyTableState *mtstate, if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_before_row) { - slot = ExecBRInsertTriggers(estate, resultRelInfo, slot); - - if (slot == NULL) /* "do nothing" */ - return NULL; - - /* trigger might have changed tuple */ - tuple = ExecMaterializeSlot(slot); + if (!ExecBRInsertTriggers(estate, resultRelInfo, slot)) + return NULL; /* "do nothing" */ } /* INSTEAD OF ROW INSERT Triggers */ if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_insert_instead_row) { - slot = ExecIRInsertTriggers(estate, resultRelInfo, slot); - - if (slot == NULL) /* "do nothing" */ - return NULL; - - /* trigger might have changed tuple */ - tuple = ExecMaterializeSlot(slot); - - newId = InvalidOid; + if (!ExecIRInsertTriggers(estate, resultRelInfo, slot)) + return NULL; /* "do nothing" */ } else if (resultRelInfo->ri_FdwRoutine) { + /* + * Compute stored generated columns + */ + if (resultRelationDesc->rd_att->constr && + resultRelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); + /* * insert into foreign table: let the FDW do it */ @@ -348,36 +405,30 @@ ExecInsert(ModifyTableState *mtstate, if (slot == NULL) /* "do nothing" */ return NULL; - /* FDW might have changed tuple */ - tuple = ExecMaterializeSlot(slot); - /* * AFTER ROW Triggers or RETURNING expressions might reference the - * tableoid column, so initialize t_tableOid before evaluating them. + * tableoid column, so (re-)initialize tts_tableOid before evaluating + * them. */ - tuple->t_tableOid = RelationGetRelid(resultRelationDesc); + slot->tts_tableOid = RelationGetRelid(resultRelInfo->ri_RelationDesc); - newId = InvalidOid; } else { WCOKind wco_kind; - bool check_partition_constr; /* - * We always check the partition constraint, including when the tuple - * got here via tuple-routing. However we don't need to in the latter - * case if no BR trigger is defined on the partition. Note that a BR - * trigger might modify the tuple such that the partition constraint - * is no longer satisfied, so we need to check in that case. + * Constraints might reference the tableoid column, so (re-)initialize + * tts_tableOid before evaluating them. */ - check_partition_constr = (resultRelInfo->ri_PartitionCheck != NIL); + slot->tts_tableOid = RelationGetRelid(resultRelationDesc); /* - * Constraints might reference the tableoid column, so initialize - * t_tableOid before evaluating them. + * Compute stored generated columns */ - tuple->t_tableOid = RelationGetRelid(resultRelationDesc); + if (resultRelationDesc->rd_att->constr && + resultRelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); /* * Check any RLS WITH CHECK policies. @@ -387,17 +438,9 @@ ExecInsert(ModifyTableState *mtstate, * partition, we should instead check UPDATE policies, because we are * executing policies defined on the target table, and not those * defined on the child partitions. - * - * If we're running MERGE, we refer to the action that we're executing - * to know if we're doing an INSERT or UPDATE to a partition table. */ - if (mtstate->operation == CMD_UPDATE) - wco_kind = WCO_RLS_UPDATE_CHECK; - else if (mtstate->operation == CMD_MERGE) - wco_kind = (actionState->commandType == CMD_UPDATE) ? - WCO_RLS_UPDATE_CHECK : WCO_RLS_INSERT_CHECK; - else - wco_kind = WCO_RLS_INSERT_CHECK; + wco_kind = (mtstate->operation == CMD_UPDATE) ? + WCO_RLS_UPDATE_CHECK : WCO_RLS_INSERT_CHECK; /* * ExecWithCheckOptions() will skip any WCOs which are not of the kind @@ -407,17 +450,21 @@ ExecInsert(ModifyTableState *mtstate, ExecWithCheckOptions(wco_kind, resultRelInfo, slot, estate); /* - * No need though if the tuple has been routed, and a BR trigger - * doesn't exist. + * Check the constraints of the tuple. */ - if (resultRelInfo->ri_PartitionRoot != NULL && - !(resultRelInfo->ri_TrigDesc && - resultRelInfo->ri_TrigDesc->trig_insert_before_row)) - check_partition_constr = false; + if (resultRelationDesc->rd_att->constr) + ExecConstraints(resultRelInfo, slot, estate); - /* Check the constraints of the tuple */ - if (resultRelationDesc->rd_att->constr || check_partition_constr) - ExecConstraints(resultRelInfo, slot, estate, true); + /* + * Also check the tuple against the partition constraint, if there is + * one; except that if we got here via tuple-routing, we don't need to + * if there's no BR trigger defined on the partition. + */ + if (resultRelInfo->ri_PartitionCheck && + (resultRelInfo->ri_PartitionRoot == NULL || + (resultRelInfo->ri_TrigDesc && + resultRelInfo->ri_TrigDesc->trig_insert_before_row))) + ExecPartitionCheck(resultRelInfo, slot, estate, true); if (onconflict != ONCONFLICT_NONE && resultRelInfo->ri_NumIndices > 0) { @@ -461,7 +508,7 @@ ExecInsert(ModifyTableState *mtstate, &conflictTid, planSlot, slot, estate, canSetTag, &returning)) { - InstrCountFiltered2(&mtstate->ps, 1); + InstrCountTuples2(&mtstate->ps, 1); return returning; } else @@ -473,10 +520,17 @@ ExecInsert(ModifyTableState *mtstate, * In case of ON CONFLICT DO NOTHING, do nothing. However, * verify that the tuple is visible to the executor's MVCC * snapshot at higher isolation levels. + * + * Using ExecGetReturningSlot() to store the tuple for the + * recheck isn't that pretty, but we can't trivially use + * the input slot, because it might not be of a compatible + * type. As there's no conflicting usage of + * ExecGetReturningSlot() in the DO NOTHING case... */ Assert(onconflict == ONCONFLICT_NOTHING); - ExecCheckTIDVisible(estate, resultRelInfo, &conflictTid); - InstrCountFiltered2(&mtstate->ps, 1); + ExecCheckTIDVisible(estate, resultRelInfo, &conflictTid, + ExecGetReturningSlot(estate, resultRelInfo)); + InstrCountTuples2(&mtstate->ps, 1); return NULL; } } @@ -488,24 +542,22 @@ ExecInsert(ModifyTableState *mtstate, * waiting for the whole transaction to complete. */ specToken = SpeculativeInsertionLockAcquire(GetCurrentTransactionId()); - HeapTupleHeaderSetSpeculativeToken(tuple->t_data, specToken); /* insert the tuple, with the speculative token */ - newId = heap_insert(resultRelationDesc, tuple, - estate->es_output_cid, - HEAP_INSERT_SPECULATIVE, - NULL); + table_tuple_insert_speculative(resultRelationDesc, slot, + estate->es_output_cid, + 0, + NULL, + specToken); /* insert index entries for tuple */ - recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), - estate, true, &specConflict, + recheckIndexes = ExecInsertIndexTuples(slot, estate, true, + &specConflict, arbiterIndexes); /* adjust the tuple's state accordingly */ - if (!specConflict) - heap_finish_speculative(resultRelationDesc, tuple); - else - heap_abort_speculative(resultRelationDesc, tuple); + table_tuple_complete_speculative(resultRelationDesc, slot, + specToken, !specConflict); /* * Wake up anyone waiting for our decision. They will re-check @@ -531,20 +583,14 @@ ExecInsert(ModifyTableState *mtstate, } else { - /* - * insert the tuple normally. - * - * Note: heap_insert returns the tid (location) of the new tuple - * in the t_self field. - */ - newId = heap_insert(resultRelationDesc, tuple, - estate->es_output_cid, - 0, NULL); + /* insert the tuple normally */ + table_tuple_insert(resultRelationDesc, slot, + estate->es_output_cid, + 0, NULL); /* insert index entries for tuple */ if (resultRelInfo->ri_NumIndices > 0) - recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), - estate, false, NULL, + recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, NIL); } } @@ -552,8 +598,7 @@ ExecInsert(ModifyTableState *mtstate, if (canSetTag) { (estate->es_processed)++; - estate->es_lastoid = newId; - setLastTid(&(tuple->t_self)); + setLastTid(&slot->tts_tid); } /* @@ -568,7 +613,7 @@ ExecInsert(ModifyTableState *mtstate, { ExecARUpdateTriggers(estate, resultRelInfo, NULL, NULL, - tuple, + slot, NULL, mtstate->mt_transition_capture); @@ -580,7 +625,7 @@ ExecInsert(ModifyTableState *mtstate, } /* AFTER ROW INSERT Triggers */ - ExecARInsertTriggers(estate, resultRelInfo, tuple, recheckIndexes, + ExecARInsertTriggers(estate, resultRelInfo, slot, recheckIndexes, ar_insert_trig_tcs); list_free(recheckIndexes); @@ -620,52 +665,38 @@ ExecInsert(ModifyTableState *mtstate, * foreign table, tupleid is invalid; the FDW has to figure out * which row to delete using data from the planSlot. oldtuple is * passed to foreign table triggers; it is NULL when the foreign - * table has no relevant triggers. - * - * MERGE passes actionState of the action it's currently executing; - * regular DELETE passes NULL. This is used by ExecDelete to know if it's - * being called from MERGE or regular DELETE operation. - * - * If the DELETE fails because the tuple is concurrently updated/deleted - * by this or some other transaction, hufdp is filled with the reason as - * well as other important information. Currently only MERGE needs this - * information. + * table has no relevant triggers. We use tupleDeleted to indicate + * whether the tuple is actually deleted, callers can use it to + * decide whether to continue the operation. When this DELETE is a + * part of an UPDATE of partition-key, then the slot returned by + * EvalPlanQual() is passed back using output parameter epqslot. * * Returns RETURNING result if any, otherwise NULL. * ---------------------------------------------------------------- */ -TupleTableSlot * +static TupleTableSlot * ExecDelete(ModifyTableState *mtstate, ItemPointer tupleid, HeapTuple oldtuple, TupleTableSlot *planSlot, EPQState *epqstate, EState *estate, - bool *tupleDeleted, bool processReturning, - HeapUpdateFailureData *hufdp, - MergeActionState *actionState, bool canSetTag, - bool changingPart) + bool changingPart, + bool *tupleDeleted, + TupleTableSlot **epqreturnslot) { ResultRelInfo *resultRelInfo; Relation resultRelationDesc; - HTSU_Result result; - HeapUpdateFailureData hufd; + TM_Result result; + TM_FailureData tmfd; TupleTableSlot *slot = NULL; TransitionCaptureState *ar_delete_trig_tcs; if (tupleDeleted) *tupleDeleted = false; - /* - * Initialize hufdp. Since the caller is only interested in the failure - * status, initialize with the state that is used to indicate successful - * operation. - */ - if (hufdp) - hufdp->result = HeapTupleMayBeUpdated; - /* * get information on the (current) result relation */ @@ -679,7 +710,7 @@ ExecDelete(ModifyTableState *mtstate, bool dodelete; dodelete = ExecBRDeleteTriggers(estate, epqstate, resultRelInfo, - tupleid, oldtuple, hufdp); + tupleid, oldtuple, epqreturnslot); if (!dodelete) /* "do nothing" */ return NULL; @@ -699,19 +730,13 @@ ExecDelete(ModifyTableState *mtstate, } else if (resultRelInfo->ri_FdwRoutine) { - HeapTuple tuple; - /* * delete from foreign table: let the FDW do it * - * We offer the trigger tuple slot as a place to store RETURNING data, - * although the FDW can return some other slot if it wants. Set up - * the slot's tupdesc so the FDW doesn't need to do that for itself. + * We offer the returning slot as a place to store RETURNING data, + * although the FDW can return some other slot if it wants. */ - slot = estate->es_trig_tuple_slot; - if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc)) - ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc)); - + slot = ExecGetReturningSlot(estate, resultRelInfo); slot = resultRelInfo->ri_FdwRoutine->ExecForeignDelete(estate, resultRelInfo, slot, @@ -722,12 +747,12 @@ ExecDelete(ModifyTableState *mtstate, /* * RETURNING expressions might reference the tableoid column, so - * initialize t_tableOid before evaluating them. + * (re)initialize tts_tableOid before evaluating them. */ - if (slot->tts_isempty) + if (TTS_EMPTY(slot)) ExecStoreAllNullTuple(slot); - tuple = ExecMaterializeSlot(slot); - tuple->t_tableOid = RelationGetRelid(resultRelationDesc); + + slot->tts_tableOid = RelationGetRelid(resultRelationDesc); } else { @@ -741,24 +766,17 @@ ExecDelete(ModifyTableState *mtstate, * mode transactions. */ ldelete:; - result = heap_delete(resultRelationDesc, tupleid, - estate->es_output_cid, - estate->es_crosscheck_snapshot, - true /* wait for commit */ , - &hufd, - changingPart); - - /* - * Copy the necessary information, if the caller has asked for it. We - * must do this irrespective of whether the tuple was updated or - * deleted. - */ - if (hufdp) - *hufdp = hufd; + result = table_tuple_delete(resultRelationDesc, tupleid, + estate->es_output_cid, + estate->es_snapshot, + estate->es_crosscheck_snapshot, + true /* wait for commit */ , + &tmfd, + changingPart); switch (result) { - case HeapTupleSelfUpdated: + case TM_SelfModified: /* * The target tuple was already updated or deleted by the @@ -784,68 +802,123 @@ ldelete:; * can re-execute the DELETE and then return NULL to cancel * the outer delete. */ - if (hufd.cmax != estate->es_output_cid) + if (tmfd.cmax != estate->es_output_cid) ereport(ERROR, (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION), - errmsg("tuple to be updated was already modified by an operation triggered by the current command"), + errmsg("tuple to be deleted was already modified by an operation triggered by the current command"), errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows."))); - /* - * Else, already deleted by self; nothing to do but inform - * MERGE about it anyways so that it can take necessary - * action. - */ + /* Else, already deleted by self; nothing to do */ return NULL; - case HeapTupleMayBeUpdated: + case TM_Ok: break; - case HeapTupleUpdated: - if (IsolationUsesXactSnapshot()) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("could not serialize access due to concurrent update"))); - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be deleted was already moved to another partition due to concurrent update"))); - - if (!ItemPointerEquals(tupleid, &hufd.ctid)) + case TM_Updated: { + TupleTableSlot *inputslot; TupleTableSlot *epqslot; + if (IsolationUsesXactSnapshot()) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent update"))); + /* - * If we're executing MERGE, then the onus of running - * EvalPlanQual() and handling its outcome lies with the - * caller. + * Already know that we're going to need to do EPQ, so + * fetch tuple directly into the right slot. */ - if (actionState != NULL) - return NULL; - - /* Normal DELETE path. */ - epqslot = EvalPlanQual(estate, - epqstate, - resultRelationDesc, - GetEPQRangeTableIndex(resultRelInfo), - LockTupleExclusive, - &hufd.ctid, - hufd.xmax); - if (!TupIsNull(epqslot)) + EvalPlanQualBegin(epqstate); + inputslot = EvalPlanQualSlot(epqstate, resultRelationDesc, + resultRelInfo->ri_RangeTableIndex); + + result = table_tuple_lock(resultRelationDesc, tupleid, + estate->es_snapshot, + inputslot, estate->es_output_cid, + LockTupleExclusive, LockWaitBlock, + TUPLE_LOCK_FLAG_FIND_LAST_VERSION, + &tmfd); + + switch (result) { - *tupleid = hufd.ctid; - goto ldelete; + case TM_Ok: + Assert(tmfd.traversed); + epqslot = EvalPlanQual(epqstate, + resultRelationDesc, + resultRelInfo->ri_RangeTableIndex, + inputslot); + if (TupIsNull(epqslot)) + /* Tuple not passing quals anymore, exiting... */ + return NULL; + + /* + * If requested, skip delete and pass back the + * updated row. + */ + if (epqreturnslot) + { + *epqreturnslot = epqslot; + return NULL; + } + else + goto ldelete; + + case TM_SelfModified: + + /* + * This can be reached when following an update + * chain from a tuple updated by another session, + * reaching a tuple that was already updated in + * this transaction. If previously updated by this + * command, ignore the delete, otherwise error + * out. + * + * See also TM_SelfModified response to + * table_tuple_delete() above. + */ + if (tmfd.cmax != estate->es_output_cid) + ereport(ERROR, + (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION), + errmsg("tuple to be deleted was already modified by an operation triggered by the current command"), + errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows."))); + return NULL; + + case TM_Deleted: + /* tuple already deleted; nothing to do */ + return NULL; + + default: + + /* + * TM_Invisible should be impossible because we're + * waiting for updated row versions, and would + * already have errored out if the first version + * is invisible. + * + * TM_Updated should be impossible, because we're + * locking the latest version via + * TUPLE_LOCK_FLAG_FIND_LAST_VERSION. + */ + elog(ERROR, "unexpected table_tuple_lock status: %u", + result); + return NULL; } + + Assert(false); + break; } - /* - * tuple already deleted; nothing to do. But MERGE might want - * to handle it differently. We've already filled-in hufdp - * with sufficient information for MERGE to look at. - */ + case TM_Deleted: + if (IsolationUsesXactSnapshot()) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent delete"))); + /* tuple already deleted; nothing to do */ return NULL; default: - elog(ERROR, "unrecognized heap_delete status: %u", result); + elog(ERROR, "unrecognized table_tuple_delete status: %u", + result); return NULL; } @@ -902,34 +975,25 @@ ldelete:; * gotta fetch it. We can use the trigger tuple slot. */ TupleTableSlot *rslot; - HeapTupleData deltuple; - Buffer delbuffer; if (resultRelInfo->ri_FdwRoutine) { /* FDW must have provided a slot containing the deleted row */ Assert(!TupIsNull(slot)); - delbuffer = InvalidBuffer; } else { - slot = estate->es_trig_tuple_slot; + slot = ExecGetReturningSlot(estate, resultRelInfo); if (oldtuple != NULL) { - deltuple = *oldtuple; - delbuffer = InvalidBuffer; + ExecForceStoreHeapTuple(oldtuple, slot, false); } else { - deltuple.t_self = *tupleid; - if (!heap_fetch(resultRelationDesc, SnapshotAny, - &deltuple, &delbuffer, false, NULL)) + if (!table_tuple_fetch_row_version(resultRelationDesc, tupleid, + SnapshotAny, slot)) elog(ERROR, "failed to fetch deleted tuple for DELETE RETURNING"); } - - if (slot->tts_tupleDescriptor != RelationGetDescr(resultRelationDesc)) - ExecSetSlotDescriptor(slot, RelationGetDescr(resultRelationDesc)); - ExecStoreTuple(&deltuple, slot, InvalidBuffer, false); } rslot = ExecProcessReturning(resultRelInfo, slot, planSlot); @@ -941,8 +1005,6 @@ ldelete:; ExecMaterializeSlot(rslot); ExecClearTuple(slot); - if (BufferIsValid(delbuffer)) - ReleaseBuffer(delbuffer); return rslot; } @@ -969,21 +1031,10 @@ ldelete:; * foreign table triggers; it is NULL when the foreign table has * no relevant triggers. * - * MERGE passes actionState of the action it's currently executing; - * regular UPDATE passes NULL. This is used by ExecUpdate to know if it's - * being called from MERGE or regular UPDATE operation. ExecUpdate may - * pass this information to ExecInsert if it ends up running DELETE+INSERT - * for partition key updates. - * - * If the UPDATE fails because the tuple is concurrently updated/deleted - * by this or some other transaction, hufdp is filled with the reason as - * well as other important information. Currently only MERGE needs this - * information. - * * Returns RETURNING result if any, otherwise NULL. * ---------------------------------------------------------------- */ -extern TupleTableSlot * +static TupleTableSlot * ExecUpdate(ModifyTableState *mtstate, ItemPointer tupleid, HeapTuple oldtuple, @@ -991,16 +1042,12 @@ ExecUpdate(ModifyTableState *mtstate, TupleTableSlot *planSlot, EPQState *epqstate, EState *estate, - bool *tuple_updated, - HeapUpdateFailureData *hufdp, - MergeActionState *actionState, bool canSetTag) { - HeapTuple tuple; ResultRelInfo *resultRelInfo; Relation resultRelationDesc; - HTSU_Result result; - HeapUpdateFailureData hufd; + TM_Result result; + TM_FailureData tmfd; List *recheckIndexes = NIL; TupleConversionMap *saved_tcs_map = NULL; @@ -1010,22 +1057,7 @@ ExecUpdate(ModifyTableState *mtstate, if (IsBootstrapProcessingMode()) elog(ERROR, "cannot UPDATE during bootstrap"); - if (tuple_updated) - *tuple_updated = false; - - /* - * Initialize hufdp. Since the caller is only interested in the failure - * status, initialize with the state that is used to indicate successful - * operation. - */ - if (hufdp) - hufdp->result = HeapTupleMayBeUpdated; - - /* - * get the heap tuple out of the tuple table slot, making sure we have a - * writable copy - */ - tuple = ExecMaterializeSlot(slot); + ExecMaterializeSlot(slot); /* * get information on the (current) result relation @@ -1037,31 +1069,28 @@ ExecUpdate(ModifyTableState *mtstate, if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_update_before_row) { - slot = ExecBRUpdateTriggers(estate, epqstate, resultRelInfo, - tupleid, oldtuple, slot, hufdp); - - if (slot == NULL) /* "do nothing" */ - return NULL; - - /* trigger might have changed tuple */ - tuple = ExecMaterializeSlot(slot); + if (!ExecBRUpdateTriggers(estate, epqstate, resultRelInfo, + tupleid, oldtuple, slot)) + return NULL; /* "do nothing" */ } /* INSTEAD OF ROW UPDATE Triggers */ if (resultRelInfo->ri_TrigDesc && resultRelInfo->ri_TrigDesc->trig_update_instead_row) { - slot = ExecIRUpdateTriggers(estate, resultRelInfo, - oldtuple, slot); - - if (slot == NULL) /* "do nothing" */ - return NULL; - - /* trigger might have changed tuple */ - tuple = ExecMaterializeSlot(slot); + if (!ExecIRUpdateTriggers(estate, resultRelInfo, + oldtuple, slot)) + return NULL; /* "do nothing" */ } else if (resultRelInfo->ri_FdwRoutine) { + /* + * Compute stored generated columns + */ + if (resultRelationDesc->rd_att->constr && + resultRelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); + /* * update in foreign table: let the FDW do it */ @@ -1073,24 +1102,31 @@ ExecUpdate(ModifyTableState *mtstate, if (slot == NULL) /* "do nothing" */ return NULL; - /* FDW might have changed tuple */ - tuple = ExecMaterializeSlot(slot); - /* * AFTER ROW Triggers or RETURNING expressions might reference the - * tableoid column, so initialize t_tableOid before evaluating them. + * tableoid column, so (re-)initialize tts_tableOid before evaluating + * them. */ - tuple->t_tableOid = RelationGetRelid(resultRelationDesc); + slot->tts_tableOid = RelationGetRelid(resultRelationDesc); } else { + LockTupleMode lockmode; bool partition_constraint_failed; + bool update_indexes; /* - * Constraints might reference the tableoid column, so initialize - * t_tableOid before evaluating them. + * Constraints might reference the tableoid column, so (re-)initialize + * tts_tableOid before evaluating them. */ - tuple->t_tableOid = RelationGetRelid(resultRelationDesc); + slot->tts_tableOid = RelationGetRelid(resultRelationDesc); + + /* + * Compute stored generated columns + */ + if (resultRelationDesc->rd_att->constr && + resultRelationDesc->rd_att->constr->has_generated_stored) + ExecComputeStoredGenerated(estate, slot); /* * Check any RLS UPDATE WITH CHECK policies @@ -1098,11 +1134,14 @@ ExecUpdate(ModifyTableState *mtstate, * If we generate a new candidate tuple after EvalPlanQual testing, we * must loop back here and recheck any RLS policies and constraints. * (We don't need to redo triggers, however. If there are any BEFORE - * triggers then trigger.c will have done heap_lock_tuple to lock the + * triggers then trigger.c will have done table_tuple_lock to lock the * correct tuple, so there's no need to do them again.) */ lreplace:; + /* ensure slot is independent, consider e.g. EPQ */ + ExecMaterializeSlot(slot); + /* * If partition constraint fails, this row might get moved to another * partition, in which case we should check the RLS CHECK policy just @@ -1112,7 +1151,7 @@ lreplace:; */ partition_constraint_failed = resultRelInfo->ri_PartitionCheck && - !ExecPartitionCheck(resultRelInfo, slot, estate); + !ExecPartitionCheck(resultRelInfo, slot, estate, false); if (!partition_constraint_failed && resultRelInfo->ri_WithCheckOptions != NIL) @@ -1133,6 +1172,7 @@ lreplace:; { bool tuple_deleted; TupleTableSlot *ret_slot; + TupleTableSlot *epqslot = NULL; PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; int map_index; TupleConversionMap *tupconv_map; @@ -1162,8 +1202,8 @@ lreplace:; * processing. We want to return rows from INSERT. */ ExecDelete(mtstate, tupleid, oldtuple, planSlot, epqstate, - estate, &tuple_deleted, false, hufdp, NULL, - false /* canSetTag */, true /* changingPart */); + estate, false, false /* canSetTag */ , + true /* changingPart */ , &tuple_deleted, &epqslot); /* * For some reason if DELETE didn't happen (e.g. trigger prevented @@ -1186,7 +1226,22 @@ lreplace:; * resurrect it. */ if (!tuple_deleted) - return NULL; + { + /* + * epqslot will be typically NULL. But when ExecDelete() + * finds that another transaction has concurrently updated the + * same row, it re-fetches the row, skips the delete, and + * epqslot is set to the re-fetched tuple slot. In that case, + * we need to do all the checks again. + */ + if (TupIsNull(epqslot)) + return NULL; + else + { + slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); + goto lreplace; + } + } /* * Updates set the transition capture map only when a new subplan @@ -1199,55 +1254,31 @@ lreplace:; saved_tcs_map = mtstate->mt_transition_capture->tcs_map; /* - * We should convert the tuple into root's tuple descriptor, since - * ExecInsert() starts the search from root. To do that, we need to - * retrieve the tuple conversion map for this resultRelInfo. - * - * If we're running MERGE then resultRelInfo is per-partition - * resultRelInfo as initialized in ExecInitPartitionInfo(). Note - * that we don't expand inheritance for the resultRelation in case - * of MERGE and hence there is just one subplan. Whereas for - * regular UPDATE, resultRelInfo is one of the per-subplan - * resultRelInfos. In either case the position of this partition in - * tracked in ri_PartitionLeafIndex; - * - * Retrieve the map either by looking at the resultRelInfo's - * position in mtstate->resultRelInfo[] (for UPDATE) or by simply - * using the ri_PartitionLeafIndex value (for MERGE). + * resultRelInfo is one of the per-subplan resultRelInfos. So we + * should convert the tuple into root's tuple descriptor, since + * ExecInsert() starts the search from root. The tuple conversion + * map list is in the order of mtstate->resultRelInfo[], so to + * retrieve the one for this resultRel, we need to know the + * position of the resultRel in mtstate->resultRelInfo[]. */ - if (mtstate->operation == CMD_MERGE) - { - map_index = resultRelInfo->ri_PartitionLeafIndex; - Assert(mtstate->rootResultRelInfo == NULL); - tupconv_map = TupConvMapForLeaf(proute, - mtstate->resultRelInfo, - map_index); - } - else - { - map_index = resultRelInfo - mtstate->resultRelInfo; - Assert(map_index >= 0 && map_index < mtstate->mt_nplans); - tupconv_map = tupconv_map_for_subplan(mtstate, map_index); - } - tuple = ConvertPartitionTupleSlot(tupconv_map, - tuple, - proute->root_tuple_slot, - &slot); + map_index = resultRelInfo - mtstate->resultRelInfo; + Assert(map_index >= 0 && map_index < mtstate->mt_nplans); + tupconv_map = tupconv_map_for_subplan(mtstate, map_index); + if (tupconv_map != NULL) + slot = execute_attr_map_slot(tupconv_map->attrMap, + slot, + mtstate->mt_root_tuple_slot); /* * Prepare for tuple routing, making it look like we're inserting * into the root. */ + Assert(mtstate->rootResultRelInfo != NULL); slot = ExecPrepareTupleRouting(mtstate, estate, proute, - getTargetResultRelInfo(mtstate), - slot); + mtstate->rootResultRelInfo, slot); ret_slot = ExecInsert(mtstate, slot, planSlot, - estate, actionState, canSetTag); - - /* Update is successful. */ - if (tuple_updated) - *tuple_updated = true; + estate, canSetTag); /* Revert ExecPrepareTupleRouting's node change. */ estate->es_result_relation_info = resultRelInfo; @@ -1261,16 +1292,13 @@ lreplace:; } /* - * Check the constraints of the tuple. Note that we pass the same - * slot for the orig_slot argument, because unlike ExecInsert(), no - * tuple-routing is performed here, hence the slot remains unchanged. - * We've already checked the partition constraint above; however, we - * must still ensure the tuple passes all other constraints, so we - * will call ExecConstraints() and have it validate all remaining - * checks. + * Check the constraints of the tuple. We've already checked the + * partition constraint above; however, we must still ensure the tuple + * passes all other constraints, so we will call ExecConstraints() and + * have it validate all remaining checks. */ if (resultRelationDesc->rd_att->constr) - ExecConstraints(resultRelInfo, slot, estate, false); + ExecConstraints(resultRelInfo, slot, estate); /* * replace the heap tuple @@ -1281,23 +1309,16 @@ lreplace:; * needed for referential integrity updates in transaction-snapshot * mode transactions. */ - result = heap_update(resultRelationDesc, tupleid, tuple, - estate->es_output_cid, - estate->es_crosscheck_snapshot, - true /* wait for commit */ , - &hufd); - - /* - * Copy the necessary information, if the caller has asked for it. We - * must do this irrespective of whether the tuple was updated or - * deleted. - */ - if (hufdp) - *hufdp = hufd; + result = table_tuple_update(resultRelationDesc, tupleid, slot, + estate->es_output_cid, + estate->es_snapshot, + estate->es_crosscheck_snapshot, + true /* wait for commit */ , + &tmfd, &lockmode, &update_indexes); switch (result) { - case HeapTupleSelfUpdated: + case TM_SelfModified: /* * The target tuple was already updated or deleted by the @@ -1322,7 +1343,7 @@ lreplace:; * can re-execute the UPDATE (assuming it can figure out how) * and then return NULL to cancel the outer update. */ - if (hufd.cmax != estate->es_output_cid) + if (tmfd.cmax != estate->es_output_cid) ereport(ERROR, (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION), errmsg("tuple to be updated was already modified by an operation triggered by the current command"), @@ -1331,90 +1352,107 @@ lreplace:; /* Else, already updated by self; nothing to do */ return NULL; - case HeapTupleMayBeUpdated: + case TM_Ok: break; - case HeapTupleUpdated: - if (IsolationUsesXactSnapshot()) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("could not serialize access due to concurrent update"))); - if (ItemPointerIndicatesMovedPartitions(&hufd.ctid)) - ereport(ERROR, - (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), - errmsg("tuple to be updated was already moved to another partition due to concurrent update"))); - - if (!ItemPointerEquals(tupleid, &hufd.ctid)) + case TM_Updated: { + TupleTableSlot *inputslot; TupleTableSlot *epqslot; + if (IsolationUsesXactSnapshot()) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent update"))); + /* - * If we're executing MERGE, then the onus of running - * EvalPlanQual() and handling its outcome lies with the - * caller. + * Already know that we're going to need to do EPQ, so + * fetch tuple directly into the right slot. */ - if (actionState != NULL) - return NULL; - - /* Regular UPDATE path. */ - epqslot = EvalPlanQual(estate, - epqstate, - resultRelationDesc, - GetEPQRangeTableIndex(resultRelInfo), - hufd.lockmode, - &hufd.ctid, - hufd.xmax); - if (!TupIsNull(epqslot)) + inputslot = EvalPlanQualSlot(epqstate, resultRelationDesc, + resultRelInfo->ri_RangeTableIndex); + + result = table_tuple_lock(resultRelationDesc, tupleid, + estate->es_snapshot, + inputslot, estate->es_output_cid, + lockmode, LockWaitBlock, + TUPLE_LOCK_FLAG_FIND_LAST_VERSION, + &tmfd); + + switch (result) { - *tupleid = hufd.ctid; - /* Normal UPDATE path */ - slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); - tuple = ExecMaterializeSlot(slot); - goto lreplace; + case TM_Ok: + Assert(tmfd.traversed); + + epqslot = EvalPlanQual(epqstate, + resultRelationDesc, + resultRelInfo->ri_RangeTableIndex, + inputslot); + if (TupIsNull(epqslot)) + /* Tuple not passing quals anymore, exiting... */ + return NULL; + + slot = ExecFilterJunk(resultRelInfo->ri_junkFilter, epqslot); + goto lreplace; + + case TM_Deleted: + /* tuple already deleted; nothing to do */ + return NULL; + + case TM_SelfModified: + + /* + * This can be reached when following an update + * chain from a tuple updated by another session, + * reaching a tuple that was already updated in + * this transaction. If previously modified by + * this command, ignore the redundant update, + * otherwise error out. + * + * See also TM_SelfModified response to + * table_tuple_update() above. + */ + if (tmfd.cmax != estate->es_output_cid) + ereport(ERROR, + (errcode(ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION), + errmsg("tuple to be updated was already modified by an operation triggered by the current command"), + errhint("Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows."))); + return NULL; + + default: + /* see table_tuple_lock call in ExecDelete() */ + elog(ERROR, "unexpected table_tuple_lock status: %u", + result); + return NULL; } } - /* - * tuple already deleted; nothing to do. But MERGE might want - * to handle it differently. We've already filled-in hufdp - * with sufficient information for MERGE to look at. - */ + break; + + case TM_Deleted: + if (IsolationUsesXactSnapshot()) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent delete"))); + /* tuple already deleted; nothing to do */ return NULL; default: - elog(ERROR, "unrecognized heap_update status: %u", result); + elog(ERROR, "unrecognized table_tuple_update status: %u", + result); return NULL; } - /* - * Note: instead of having to update the old index tuples associated - * with the heap tuple, all we do is form and insert new index tuples. - * This is because UPDATEs are actually DELETEs and INSERTs, and index - * tuple deletion is done later by VACUUM (see notes in ExecDelete). - * All we do here is insert new index tuples. -cim 9/27/89 - */ - - /* - * insert index entries for tuple - * - * Note: heap_update returns the tid (location) of the new tuple in - * the t_self field. - * - * If it's a HOT update, we mustn't insert new index entries. - */ - if (resultRelInfo->ri_NumIndices > 0 && !HeapTupleIsHeapOnly(tuple)) - recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), - estate, false, NULL, NIL); + /* insert index entries for tuple if necessary */ + if (resultRelInfo->ri_NumIndices > 0 && update_indexes) + recheckIndexes = ExecInsertIndexTuples(slot, estate, false, NULL, NIL); } - if (tuple_updated) - *tuple_updated = true; - if (canSetTag) (estate->es_processed)++; /* AFTER ROW UPDATE Triggers */ - ExecARUpdateTriggers(estate, resultRelInfo, tupleid, oldtuple, tuple, + ExecARUpdateTriggers(estate, resultRelInfo, tupleid, oldtuple, slot, recheckIndexes, mtstate->operation == CMD_INSERT ? mtstate->mt_oc_transition_capture : @@ -1449,7 +1487,7 @@ lreplace:; * (but still lock row, even though it may not satisfy estate's * snapshot). * - * Returns true if if we're done (with or without an update), or false if + * Returns true if we're done (with or without an update), or false if * the caller must retry the INSERT from scratch. */ static bool @@ -1465,11 +1503,13 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, ExprContext *econtext = mtstate->ps.ps_ExprContext; Relation relation = resultRelInfo->ri_RelationDesc; ExprState *onConflictSetWhere = resultRelInfo->ri_onConflict->oc_WhereClause; - HeapTupleData tuple; - HeapUpdateFailureData hufd; + TupleTableSlot *existing = resultRelInfo->ri_onConflict->oc_Existing; + TM_FailureData tmfd; LockTupleMode lockmode; - HTSU_Result test; - Buffer buffer; + TM_Result test; + Datum xminDatum; + TransactionId xmin; + bool isnull; /* Determine lock mode to use */ lockmode = ExecUpdateLockMode(estate, resultRelInfo); @@ -1480,35 +1520,42 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * previous conclusion that the tuple is conclusively committed is not * true anymore. */ - tuple.t_self = *conflictTid; - test = heap_lock_tuple(relation, &tuple, estate->es_output_cid, - lockmode, LockWaitBlock, false, &buffer, - &hufd); + test = table_tuple_lock(relation, conflictTid, + estate->es_snapshot, + existing, estate->es_output_cid, + lockmode, LockWaitBlock, 0, + &tmfd); switch (test) { - case HeapTupleMayBeUpdated: + case TM_Ok: /* success! */ break; - case HeapTupleInvisible: + case TM_Invisible: /* * This can occur when a just inserted tuple is updated again in * the same command. E.g. because multiple rows with the same * conflicting key values are inserted. * - * This is somewhat similar to the ExecUpdate() - * HeapTupleSelfUpdated case. We do not want to proceed because - * it would lead to the same row being updated a second time in - * some unspecified order, and in contrast to plain UPDATEs - * there's no historical behavior to break. + * This is somewhat similar to the ExecUpdate() TM_SelfModified + * case. We do not want to proceed because it would lead to the + * same row being updated a second time in some unspecified order, + * and in contrast to plain UPDATEs there's no historical behavior + * to break. * * It is the user's responsibility to prevent this situation from - * occurring. These problems are why SQL Standard similarly - * specifies that for SQL MERGE, an exception must be raised in - * the event of an attempt to update the same row twice. + * occurring. These problems are why SQL-2003 similarly specifies + * that for SQL MERGE, an exception must be raised in the event of + * an attempt to update the same row twice. */ - if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(tuple.t_data))) + xminDatum = slot_getsysattr(existing, + MinTransactionIdAttributeNumber, + &isnull); + Assert(!isnull); + xmin = DatumGetTransactionId(xminDatum); + + if (TransactionIdIsCurrentTransactionId(xmin)) ereport(ERROR, (errcode(ERRCODE_CARDINALITY_VIOLATION), errmsg("ON CONFLICT DO UPDATE command cannot affect row a second time"), @@ -1516,8 +1563,9 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, /* This shouldn't happen */ elog(ERROR, "attempted to lock invisible tuple"); + break; - case HeapTupleSelfUpdated: + case TM_SelfModified: /* * This state should never be reached. As a dirty snapshot is used @@ -1525,8 +1573,9 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * seen this row to conflict with. */ elog(ERROR, "unexpected self-updated tuple"); + break; - case HeapTupleUpdated: + case TM_Updated: if (IsolationUsesXactSnapshot()) ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), @@ -1538,7 +1587,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * be lock is moved to another partition due to concurrent update * of the partition key. */ - Assert(!ItemPointerIndicatesMovedPartitions(&hufd.ctid)); + Assert(!ItemPointerIndicatesMovedPartitions(&tmfd.ctid)); /* * Tell caller to try again from the very start. @@ -1547,20 +1596,25 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * loop here, as the new version of the row might not conflict * anymore, or the conflicting tuple has actually been deleted. */ - ReleaseBuffer(buffer); + ExecClearTuple(existing); + return false; + + case TM_Deleted: + if (IsolationUsesXactSnapshot()) + ereport(ERROR, + (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), + errmsg("could not serialize access due to concurrent delete"))); + + /* see TM_Updated case */ + Assert(!ItemPointerIndicatesMovedPartitions(&tmfd.ctid)); + ExecClearTuple(existing); return false; default: - elog(ERROR, "unrecognized heap_lock_tuple status: %u", test); + elog(ERROR, "unrecognized table_tuple_lock status: %u", test); } - /* - * Success, the tuple is locked. - * - * Reset per-tuple memory context to free any expression evaluation - * storage allocated in the previous cycle. - */ - ResetExprContext(econtext); + /* Success, the tuple is locked. */ /* * Verify that the tuple is visible to our MVCC snapshot if the current @@ -1575,10 +1629,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * snapshot. This is in line with the way UPDATE deals with newer tuple * versions. */ - ExecCheckHeapTupleVisible(estate, &tuple, buffer); - - /* Store target's existing tuple in the state's dedicated slot */ - ExecStoreTuple(&tuple, mtstate->mt_existing, buffer, false); + ExecCheckTupleVisible(estate, relation, existing); /* * Make tuple and any needed join variables available to ExecQual and @@ -1587,13 +1638,13 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * has been made to reference INNER_VAR in setrefs.c, but there is no * other redirection. */ - econtext->ecxt_scantuple = mtstate->mt_existing; + econtext->ecxt_scantuple = existing; econtext->ecxt_innertuple = excludedSlot; econtext->ecxt_outertuple = NULL; if (!ExecQual(onConflictSetWhere, econtext)) { - ReleaseBuffer(buffer); + ExecClearTuple(existing); /* see return below */ InstrCountFiltered1(&mtstate->ps, 1); return true; /* done with the tuple */ } @@ -1616,7 +1667,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, * INSERT or UPDATE path. */ ExecWithCheckOptions(WCO_RLS_CONFLICT_CHECK, resultRelInfo, - mtstate->mt_existing, + existing, mtstate->ps.state); } @@ -1625,7 +1676,7 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, /* * Note that it is possible that the target tuple has been modified in - * this session, after the above heap_lock_tuple. We choose to not error + * this session, after the above table_tuple_lock. We choose to not error * out in that case, in line with ExecUpdate's treatment of similar cases. * This can happen if an UPDATE is triggered from within ExecQual(), * ExecWithCheckOptions() or ExecProject() above, e.g. by selecting from a @@ -1633,12 +1684,18 @@ ExecOnConflictUpdate(ModifyTableState *mtstate, */ /* Execute UPDATE with projection */ - *returning = ExecUpdate(mtstate, &tuple.t_self, NULL, - mtstate->mt_conflproj, planSlot, + *returning = ExecUpdate(mtstate, conflictTid, NULL, + resultRelInfo->ri_onConflict->oc_ProjSlot, + planSlot, &mtstate->mt_epqstate, mtstate->ps.state, - NULL, NULL, NULL, canSetTag); + canSetTag); - ReleaseBuffer(buffer); + /* + * Clear out existing tuple, as there might not be another conflict among + * the next input rows. Don't want to hold resources till the end of the + * query. + */ + ExecClearTuple(existing); return true; } @@ -1674,14 +1731,6 @@ fireBSTriggers(ModifyTableState *node) case CMD_DELETE: ExecBSDeleteTriggers(node->ps.state, resultRelInfo); break; - case CMD_MERGE: - if (node->mt_merge_subcommands & MERGE_INSERT) - ExecBSInsertTriggers(node->ps.state, resultRelInfo); - if (node->mt_merge_subcommands & MERGE_UPDATE) - ExecBSUpdateTriggers(node->ps.state, resultRelInfo); - if (node->mt_merge_subcommands & MERGE_DELETE) - ExecBSDeleteTriggers(node->ps.state, resultRelInfo); - break; default: elog(ERROR, "unknown operation"); break; @@ -1737,17 +1786,6 @@ fireASTriggers(ModifyTableState *node) ExecASDeleteTriggers(node->ps.state, resultRelInfo, node->mt_transition_capture); break; - case CMD_MERGE: - if (node->mt_merge_subcommands & MERGE_DELETE) - ExecASDeleteTriggers(node->ps.state, resultRelInfo, - node->mt_transition_capture); - if (node->mt_merge_subcommands & MERGE_UPDATE) - ExecASUpdateTriggers(node->ps.state, resultRelInfo, - node->mt_transition_capture); - if (node->mt_merge_subcommands & MERGE_INSERT) - ExecASInsertTriggers(node->ps.state, resultRelInfo, - node->mt_transition_capture); - break; default: elog(ERROR, "unknown operation"); break; @@ -1785,7 +1823,7 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) if (mtstate->mt_transition_capture != NULL || mtstate->mt_oc_transition_capture != NULL) { - ExecSetupChildParentMapForTcs(mtstate); + ExecSetupChildParentMapForSubplan(mtstate); /* * Install the conversion map for the first plan for UPDATE and DELETE @@ -1810,67 +1848,36 @@ ExecSetupTransitionCaptureState(ModifyTableState *mtstate, EState *estate) * * Returns a slot holding the tuple of the partition rowtype. */ -TupleTableSlot * +static TupleTableSlot * ExecPrepareTupleRouting(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, ResultRelInfo *targetRelInfo, TupleTableSlot *slot) { - ModifyTable *node; - int partidx; ResultRelInfo *partrel; - HeapTuple tuple; - - /* - * Determine the target partition. If ExecFindPartition does not find - * a partition after all, it doesn't return here; otherwise, the returned - * value is to be used as an index into the arrays for the ResultRelInfo - * and TupleConversionMap for the partition. - */ - partidx = ExecFindPartition(targetRelInfo, - proute->partition_dispatch_info, - slot, - estate); - Assert(partidx >= 0 && partidx < proute->num_partitions); + PartitionRoutingInfo *partrouteinfo; + TupleConversionMap *map; /* - * Get the ResultRelInfo corresponding to the selected partition; if not - * yet there, initialize it. - */ - partrel = proute->partitions[partidx]; - if (partrel == NULL) - partrel = ExecInitPartitionInfo(mtstate, targetRelInfo, - proute, estate, - partidx); - - /* - * Set up information needed for routing tuples to the partition if we - * didn't yet (ExecInitRoutingInfo would abort the operation if the - * partition isn't routable). - * - * Note: an UPDATE of a partition key invokes an INSERT that moves the - * tuple to a new partition. This setup would be needed for a subplan - * partition of such an UPDATE that is chosen as the partition to route - * the tuple to. The reason we do this setup here rather than in - * ExecSetupPartitionTupleRouting is to avoid aborting such an UPDATE - * unnecessarily due to non-routable subplan partitions that may not be - * chosen for update tuple movement after all. + * Lookup the target partition's ResultRelInfo. If ExecFindPartition does + * not find a valid partition for the tuple in 'slot' then an error is + * raised. An error may also be raised if the found partition is not a + * valid target for INSERTs. This is required since a partitioned table + * UPDATE to another partition becomes a DELETE+INSERT. */ - if (!partrel->ri_PartitionReadyForRouting) - ExecInitRoutingInfo(mtstate, estate, proute, partrel, partidx); + partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate); + partrouteinfo = partrel->ri_PartitionInfo; + Assert(partrouteinfo != NULL); /* * Make it look like we are inserting into the partition. */ estate->es_result_relation_info = partrel; - /* Get the heap tuple out of the given slot. */ - tuple = ExecMaterializeSlot(slot); - /* * If we're capturing transition tuples, we might need to convert from the - * partition rowtype to parent rowtype. + * partition rowtype to root partitioned table's rowtype. */ if (mtstate->mt_transition_capture != NULL) { @@ -1883,7 +1890,7 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, */ mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL; mtstate->mt_transition_capture->tcs_map = - TupConvMapForLeaf(proute, targetRelInfo, partidx); + partrouteinfo->pi_PartitionToRootMap; } else { @@ -1891,35 +1898,25 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate, * Otherwise, just remember the original unconverted tuple, to * avoid a needless round trip conversion. */ - mtstate->mt_transition_capture->tcs_original_insert_tuple = tuple; + mtstate->mt_transition_capture->tcs_original_insert_tuple = slot; mtstate->mt_transition_capture->tcs_map = NULL; } } if (mtstate->mt_oc_transition_capture != NULL) { mtstate->mt_oc_transition_capture->tcs_map = - TupConvMapForLeaf(proute, targetRelInfo, partidx); + partrouteinfo->pi_PartitionToRootMap; } /* * Convert the tuple, if necessary. */ - ConvertPartitionTupleSlot(proute->parent_child_tupconv_maps[partidx], - tuple, - proute->partition_tuple_slot, - &slot); - - /* Initialize information needed to handle ON CONFLICT DO UPDATE. */ - Assert(mtstate != NULL); - node = (ModifyTable *) mtstate->ps.plan; - if (node->onConflictAction == ONCONFLICT_UPDATE) + map = partrouteinfo->pi_RootToPartitionMap; + if (map != NULL) { - Assert(mtstate->mt_existing != NULL); - ExecSetSlotDescriptor(mtstate->mt_existing, - RelationGetDescr(partrel->ri_RelationDesc)); - Assert(mtstate->mt_conflproj != NULL); - ExecSetSlotDescriptor(mtstate->mt_conflproj, - partrel->ri_onConflict->oc_ProjTupdesc); + TupleTableSlot *new_slot = partrouteinfo->pi_PartitionTupleSlot; + + slot = execute_attr_map_slot(map->attrMap, slot, new_slot); } return slot; @@ -1943,17 +1940,6 @@ ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate) int numResultRelInfos = mtstate->mt_nplans; int i; - /* - * First check if there is already a per-subplan array allocated. Even if - * there is already a per-leaf map array, we won't require a per-subplan - * one, since we will use the subplan offset array to convert the subplan - * index to per-leaf index. - */ - if (mtstate->mt_per_subplan_tupconv_maps || - (mtstate->mt_partition_tuple_routing && - mtstate->mt_partition_tuple_routing->child_parent_tupconv_maps)) - return; - /* * Build array of conversion maps from each child's TupleDesc to the one * used in the target relation. The map pointers may be NULL when no @@ -1970,84 +1956,22 @@ ExecSetupChildParentMapForSubplan(ModifyTableState *mtstate) { mtstate->mt_per_subplan_tupconv_maps[i] = convert_tuples_by_name(RelationGetDescr(resultRelInfos[i].ri_RelationDesc), - outdesc, - gettext_noop("could not convert row type")); + outdesc); } } -/* - * Initialize the child-to-root tuple conversion map array required for - * capturing transition tuples. - * - * The map array can be indexed either by subplan index or by leaf-partition - * index. For transition tables, we need a subplan-indexed access to the map, - * and where tuple-routing is present, we also require a leaf-indexed access. - */ -static void -ExecSetupChildParentMapForTcs(ModifyTableState *mtstate) -{ - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - - /* - * If partition tuple routing is set up, we will require partition-indexed - * access. In that case, create the map array indexed by partition; we - * will still be able to access the maps using a subplan index by - * converting the subplan index to a partition index using - * subplan_partition_offsets. If tuple routing is not set up, it means we - * don't require partition-indexed access. In that case, create just a - * subplan-indexed map. - */ - if (proute) - { - /* - * If a partition-indexed map array is to be created, the subplan map - * array has to be NULL. If the subplan map array is already created, - * we won't be able to access the map using a partition index. - */ - Assert(mtstate->mt_per_subplan_tupconv_maps == NULL); - - ExecSetupChildParentMapForLeaf(proute); - } - else - ExecSetupChildParentMapForSubplan(mtstate); -} - /* * For a given subplan index, get the tuple conversion map. */ static TupleConversionMap * tupconv_map_for_subplan(ModifyTableState *mtstate, int whichplan) { - /* - * If a partition-index tuple conversion map array is allocated, we need - * to first get the index into the partition array. Exactly *one* of the - * two arrays is allocated. This is because if there is a partition array - * required, we don't require subplan-indexed array since we can translate - * subplan index into partition index. And, we create a subplan-indexed - * array *only* if partition-indexed array is not required. - */ + /* If nobody else set the per-subplan array of maps, do so ourselves. */ if (mtstate->mt_per_subplan_tupconv_maps == NULL) - { - int leaf_index; - PartitionTupleRouting *proute = mtstate->mt_partition_tuple_routing; - - /* - * If subplan-indexed array is NULL, things should have been arranged - * to convert the subplan index to partition index. - */ - Assert(proute && proute->subplan_partition_offsets != NULL && - whichplan < proute->num_subplan_partition_offsets); - - leaf_index = proute->subplan_partition_offsets[whichplan]; + ExecSetupChildParentMapForSubplan(mtstate); - return TupConvMapForLeaf(proute, getTargetResultRelInfo(mtstate), - leaf_index); - } - else - { - Assert(whichplan >= 0 && whichplan < mtstate->mt_nplans); - return mtstate->mt_per_subplan_tupconv_maps[whichplan]; - } + Assert(whichplan >= 0 && whichplan < mtstate->mt_nplans); + return mtstate->mt_per_subplan_tupconv_maps[whichplan]; } /* ---------------------------------------------------------------- @@ -2086,7 +2010,7 @@ ExecModifyTable(PlanState *pstate) * case it is within a CTE subplan. Hence this test must be here, not in * ExecInitModifyTable.) */ - if (estate->es_epqTuple != NULL) + if (estate->es_epq_active != NULL) elog(ERROR, "ModifyTable should not be called during EvalPlanQual"); /* @@ -2137,13 +2061,20 @@ ExecModifyTable(PlanState *pstate) */ ResetPerTupleExprContext(estate); + /* + * Reset per-tuple memory context used for processing on conflict and + * returning clauses, to free any expression evaluation storage + * allocated in the previous cycle. + */ + if (pstate->ps_ExprContext) + ResetExprContext(pstate->ps_ExprContext); + planSlot = ExecProcNode(subplanstate); if (TupIsNull(planSlot)) { /* advance to next subplan if any */ node->mt_whichplan++; - if (node->mt_whichplan < node->mt_nplans) { resultRelInfo++; @@ -2169,6 +2100,15 @@ ExecModifyTable(PlanState *pstate) break; } + /* + * Ensure input tuple is the right format for the target relation. + */ + if (node->mt_scans[node->mt_whichplan]->tts_ops != planSlot->tts_ops) + { + ExecCopySlot(node->mt_scans[node->mt_whichplan], planSlot); + planSlot = node->mt_scans[node->mt_whichplan]; + } + /* * If resultRelInfo->ri_usesFdwDirectModify is true, all we need to do * here is compute the RETURNING expressions. @@ -2192,12 +2132,6 @@ ExecModifyTable(PlanState *pstate) EvalPlanQualSetSlot(&node->mt_epqstate, planSlot); slot = planSlot; - if (operation == CMD_MERGE) - { - ExecMerge(node, estate, slot, junkfilter, resultRelInfo); - continue; - } - tupleid = NULL; oldtuple = NULL; if (junkfilter != NULL) @@ -2279,21 +2213,20 @@ ExecModifyTable(PlanState *pstate) slot = ExecPrepareTupleRouting(node, estate, proute, resultRelInfo, slot); slot = ExecInsert(node, slot, planSlot, - estate, NULL, node->canSetTag); + estate, node->canSetTag); /* Revert ExecPrepareTupleRouting's state change. */ if (proute) estate->es_result_relation_info = resultRelInfo; break; case CMD_UPDATE: slot = ExecUpdate(node, tupleid, oldtuple, slot, planSlot, - &node->mt_epqstate, estate, - NULL, NULL, NULL, node->canSetTag); + &node->mt_epqstate, estate, node->canSetTag); break; case CMD_DELETE: slot = ExecDelete(node, tupleid, oldtuple, planSlot, &node->mt_epqstate, estate, - NULL, true, NULL, NULL, node->canSetTag, - false /* changingPart */); + true, node->canSetTag, + false /* changingPart */ , NULL, NULL); break; default: elog(ERROR, "unknown operation"); @@ -2359,6 +2292,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->mt_plans = (PlanState **) palloc0(sizeof(PlanState *) * nplans); mtstate->resultRelInfo = estate->es_result_relations + node->resultRelIndex; + mtstate->mt_scans = (TupleTableSlot **) palloc0(sizeof(TupleTableSlot *) * nplans); /* If modifying a partitioned table, initialize the root table info */ if (node->rootResultRelIndex >= 0) @@ -2378,21 +2312,13 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * verify that the proposed target relations are valid and open their * indexes for insertion of new index entries. Note we *must* set * estate->es_result_relation_info correctly while we initialize each - * sub-plan; ExecContextForcesOids depends on that! + * sub-plan; external modules such as FDWs may depend on that (see + * contrib/postgres_fdw/postgres_fdw.c: postgresBeginDirectModify() as one + * example). */ saved_resultRelInfo = estate->es_result_relation_info; resultRelInfo = mtstate->resultRelInfo; - - /* - * mergeTargetRelation must be set if we're running MERGE and mustn't be - * set if we're not. - */ - Assert(operation != CMD_MERGE || node->mergeTargetRelation > 0); - Assert(operation == CMD_MERGE || node->mergeTargetRelation == 0); - - resultRelInfo->ri_mergeTargetRTI = node->mergeTargetRelation; - i = 0; foreach(l, node->plans) { @@ -2435,6 +2361,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) /* Now init the plan for this result rel */ estate->es_result_relation_info = resultRelInfo; mtstate->mt_plans[i] = ExecInitNode(subplan, estate, eflags); + mtstate->mt_scans[i] = + ExecInitExtraTupleSlot(mtstate->ps.state, ExecGetResultType(mtstate->mt_plans[i]), + table_slot_callbacks(resultRelInfo->ri_RelationDesc)); /* Also let FDWs init themselves for foreign-table result rels */ if (!resultRelInfo->ri_usesFdwDirectModify && @@ -2471,10 +2400,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * partition key. */ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE && - (operation == CMD_INSERT || operation == CMD_MERGE || - update_tuple_routing_needed)) + (operation == CMD_INSERT || update_tuple_routing_needed)) mtstate->mt_partition_tuple_routing = - ExecSetupPartitionTupleRouting(mtstate, rel); + ExecSetupPartitionTupleRouting(estate, mtstate, rel); /* * Build state for collecting transition tuples. This requires having a @@ -2483,25 +2411,20 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) if (!(eflags & EXEC_FLAG_EXPLAIN_ONLY)) ExecSetupTransitionCaptureState(mtstate, estate); - /* - * If we are doing MERGE then setup child-parent mapping. This will be - * required in case we end up doing a partition-key update, triggering a - * tuple routing. - */ - if (mtstate->operation == CMD_MERGE && - mtstate->mt_partition_tuple_routing != NULL) - ExecSetupChildParentMapForLeaf(mtstate->mt_partition_tuple_routing); - /* * Construct mapping from each of the per-subplan partition attnos to the * root attno. This is required when during update row movement the tuple * descriptor of a source partition does not match the root partitioned * table descriptor. In such a case we need to convert tuples to the root * tuple descriptor, because the search for destination partition starts - * from the root. Skip this setup if it's not a partition key update. + * from the root. We'll also need a slot to store these converted tuples. + * We can skip this setup if it's not a partition key update. */ if (update_tuple_routing_needed) + { ExecSetupChildParentMapForSubplan(mtstate); + mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL); + } /* * Initialize any WITH CHECK OPTION constraints if needed. @@ -2518,7 +2441,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) { WithCheckOption *wco = (WithCheckOption *) lfirst(ll); ExprState *wcoExpr = ExecInitQual((List *) wco->qual, - mtstate->mt_plans[i]); + &mtstate->ps); wcoExprs = lappend(wcoExprs, wcoExpr); } @@ -2544,7 +2467,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) mtstate->ps.plan->targetlist = (List *) linitial(node->returningLists); /* Set up a slot for the output of the RETURNING projection(s) */ - ExecInitResultTupleSlotTL(estate, &mtstate->ps); + ExecInitResultTupleSlotTL(&mtstate->ps, &TTSOpsVirtual); slot = mtstate->ps.ps_ResultTupleSlot; /* Need an econtext too */ @@ -2574,7 +2497,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * expects one (maybe should change that?). */ mtstate->ps.plan->targetlist = NIL; - ExecInitResultTupleSlotTL(estate, &mtstate->ps); + ExecInitResultTypeTL(&mtstate->ps); mtstate->ps.ps_ExprContext = NULL; } @@ -2604,44 +2527,33 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) econtext = mtstate->ps.ps_ExprContext; relationDesc = resultRelInfo->ri_RelationDesc->rd_att; - /* - * Initialize slot for the existing tuple. If we'll be performing - * tuple routing, the tuple descriptor to use for this will be - * determined based on which relation the update is actually applied - * to, so we don't set its tuple descriptor here. - */ - mtstate->mt_existing = - ExecInitExtraTupleSlot(mtstate->ps.state, - mtstate->mt_partition_tuple_routing ? - NULL : relationDesc); - /* carried forward solely for the benefit of explain */ mtstate->mt_excludedtlist = node->exclRelTlist; /* create state for DO UPDATE SET operation */ resultRelInfo->ri_onConflict = makeNode(OnConflictSetState); + /* initialize slot for the existing tuple */ + resultRelInfo->ri_onConflict->oc_Existing = + table_slot_create(resultRelInfo->ri_RelationDesc, + &mtstate->ps.state->es_tupleTable); + /* - * Create the tuple slot for the UPDATE SET projection. - * - * Just like mt_existing above, we leave it without a tuple descriptor - * in the case of partitioning tuple routing, so that it can be - * changed by ExecPrepareTupleRouting. In that case, we still save - * the tupdesc in the parent's state: it can be reused by partitions - * with an identical descriptor to the parent. + * Create the tuple slot for the UPDATE SET projection. We want a slot + * of the table's type here, because the slot will be used to insert + * into the table, and for RETURNING processing - which may access + * system attributes. */ - tupDesc = ExecTypeFromTL((List *) node->onConflictSet, - relationDesc->tdhasoid); - mtstate->mt_conflproj = - ExecInitExtraTupleSlot(mtstate->ps.state, - mtstate->mt_partition_tuple_routing ? - NULL : tupDesc); - resultRelInfo->ri_onConflict->oc_ProjTupdesc = tupDesc; + tupDesc = ExecTypeFromTL((List *) node->onConflictSet); + resultRelInfo->ri_onConflict->oc_ProjSlot = + ExecInitExtraTupleSlot(mtstate->ps.state, tupDesc, + table_slot_callbacks(resultRelInfo->ri_RelationDesc)); /* build UPDATE SET projection state */ resultRelInfo->ri_onConflict->oc_ProjInfo = ExecBuildProjectionInfo(node->onConflictSet, econtext, - mtstate->mt_conflproj, &mtstate->ps, + resultRelInfo->ri_onConflict->oc_ProjSlot, + &mtstate->ps, relationDesc); /* initialize state to evaluate the WHERE clause, if any */ @@ -2684,10 +2596,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) } } - resultRelInfo = mtstate->resultRelInfo; - if (mtstate->operation == CMD_MERGE) - ExecInitMerge(mtstate, estate, resultRelInfo); - /* select first subplan */ mtstate->mt_whichplan = 0; subplan = (Plan *) linitial(node->plans); @@ -2701,7 +2609,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) * --- no need to look first. Typically, this will be a 'ctid' or * 'wholerow' attribute, but in the case of a foreign data wrapper it * might be a set of junk attributes sufficient to identify the remote - * row. We follow this logic for MERGE, so it always has a junk attributes. + * row. * * If there are multiple result relations, each one needs its own junk * filter. Note multiple rels are only possible for UPDATE/DELETE, so we @@ -2729,7 +2637,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) break; case CMD_UPDATE: case CMD_DELETE: - case CMD_MERGE: junk_filter_needed = true; break; default: @@ -2743,20 +2650,20 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) for (i = 0; i < nplans; i++) { JunkFilter *j; + TupleTableSlot *junkresslot; subplan = mtstate->mt_plans[i]->plan; - if (operation == CMD_INSERT || operation == CMD_UPDATE) ExecCheckPlanOutput(resultRelInfo->ri_RelationDesc, subplan->targetlist); + junkresslot = + ExecInitExtraTupleSlot(estate, NULL, + table_slot_callbacks(resultRelInfo->ri_RelationDesc)); j = ExecInitJunkFilter(subplan->targetlist, - resultRelInfo->ri_RelationDesc->rd_att->tdhasoid, - ExecInitExtraTupleSlot(estate, NULL)); + junkresslot); - if (operation == CMD_UPDATE || - operation == CMD_DELETE || - operation == CMD_MERGE) + if (operation == CMD_UPDATE || operation == CMD_DELETE) { /* For UPDATE/DELETE, find the appropriate junk attr now */ char relkind; @@ -2769,15 +2676,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid"); if (!AttributeNumberIsValid(j->jf_junkAttNo)) elog(ERROR, "could not find junk ctid column"); - - if (operation == CMD_MERGE && - relkind == RELKIND_PARTITIONED_TABLE) - { - j->jf_otherJunkAttNo = ExecFindJunkAttribute(j, "tableoid"); - if (!AttributeNumberIsValid(j->jf_otherJunkAttNo)) - elog(ERROR, "could not find junk tableoid column"); - - } } else if (relkind == RELKIND_FOREIGN_TABLE) { @@ -2807,14 +2705,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags) } } - /* - * Set up a tuple table slot for use for trigger output tuples. In a plan - * containing multiple ModifyTable nodes, all can share one such slot, so - * we keep it in the estate. - */ - if (estate->es_trig_tuple_slot == NULL) - estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL); - /* * Lastly, if this is not the primary (canSetTag) ModifyTable node, add it * to estate->es_auxmodifytables so that it will be run to completion by @@ -2858,10 +2748,18 @@ ExecEndModifyTable(ModifyTableState *node) resultRelInfo); } - /* Close all the partitioned tables, leaf partitions, and their indices */ + /* + * Close all the partitioned tables, leaf partitions, and their indices + * and release the slot used for tuple routing, if set. + */ if (node->mt_partition_tuple_routing) + { ExecCleanupTupleRouting(node, node->mt_partition_tuple_routing); + if (node->mt_root_tuple_slot) + ExecDropSingleTupleTableSlot(node->mt_root_tuple_slot); + } + /* * Free the exprcontext */ @@ -2870,7 +2768,8 @@ ExecEndModifyTable(ModifyTableState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ps.ps_ResultTupleSlot); + if (node->ps.ps_ResultTupleSlot) + ExecClearTuple(node->ps.ps_ResultTupleSlot); /* * Terminate EPQ execution if active diff --git a/src/backend/executor/nodeNamedtuplestorescan.c b/src/backend/executor/nodeNamedtuplestorescan.c index b260ad25948..67b0a441862 100644 --- a/src/backend/executor/nodeNamedtuplestorescan.c +++ b/src/backend/executor/nodeNamedtuplestorescan.c @@ -3,7 +3,7 @@ * nodeNamedtuplestorescan.c * routines to handle NamedTuplestoreScan nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -135,22 +135,22 @@ ExecInitNamedTuplestoreScan(NamedTuplestoreScan *node, EState *estate, int eflag ExecAssignExprContext(estate, &scanstate->ss.ps); /* - * Tuple table and result type initialization. The scan tuple type is - * specified for the tuplestore. + * The scan tuple type is specified for the tuplestore. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); - ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc); + ExecInitScanTupleSlot(estate, &scanstate->ss, scanstate->tupdesc, + &TTSOpsMinimalTuple); /* - * initialize child expressions + * Initialize result type and projection. */ - scanstate->ss.ps.qual = - ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate); + ExecInitResultTypeTL(&scanstate->ss.ps); + ExecAssignScanProjectionInfo(&scanstate->ss); /* - * Initialize projection. + * initialize child expressions */ - ExecAssignScanProjectionInfo(&scanstate->ss); + scanstate->ss.ps.qual = + ExecInitQual(node->scan.plan.qual, (PlanState *) scanstate); return scanstate; } @@ -172,7 +172,8 @@ ExecEndNamedTuplestoreScan(NamedTuplestoreScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); } @@ -187,7 +188,8 @@ ExecReScanNamedTuplestoreScan(NamedTuplestoreScanState *node) { Tuplestorestate *tuplestorestate = node->relation; - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index 9ae9863226c..fc6667ef826 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -3,7 +3,7 @@ * nodeNestloop.c * routines to support nest-loop joins * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -304,7 +304,7 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &nlstate->js.ps); + ExecInitResultTupleSlotTL(&nlstate->js.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&nlstate->js.ps, NULL); /* @@ -332,7 +332,8 @@ ExecInitNestLoop(NestLoop *node, EState *estate, int eflags) case JOIN_ANTI: nlstate->nl_NullInnerTupleSlot = ExecInitNullTupleSlot(estate, - ExecGetResultType(innerPlanState(nlstate))); + ExecGetResultType(innerPlanState(nlstate)), + &TTSOpsVirtual); break; default: elog(ERROR, "unrecognized join type: %d", diff --git a/src/backend/executor/nodeProjectSet.c b/src/backend/executor/nodeProjectSet.c index 6d6ed38ceeb..facdb4232e6 100644 --- a/src/backend/executor/nodeProjectSet.c +++ b/src/backend/executor/nodeProjectSet.c @@ -11,7 +11,7 @@ * can't be inside more-complex expressions. If that'd otherwise be * the case, the planner adds additional ProjectSet nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -196,8 +196,8 @@ ExecProjectSRF(ProjectSetState *node, bool continuing) Assert(hassrf); /* - * If all the SRFs returned EndResult, we consider that as no row being - * produced. + * If all the SRFs returned ExprEndResult, we consider that as no row + * being produced. */ if (hasresult) { @@ -256,7 +256,7 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags) /* * tuple table and result type initialization */ - ExecInitResultTupleSlotTL(estate, &state->ps); + ExecInitResultTupleSlotTL(&state->ps, &TTSOpsVirtual); /* Create workspace for per-tlist-entry expr state & SRF-is-done state */ state->nelems = list_length(node->plan.targetlist); @@ -297,11 +297,12 @@ ExecInitProjectSet(ProjectSet *node, EState *estate, int eflags) Assert(node->plan.qual == NIL); /* - * Create a memory context that ExecMakeFunctionResult can use to evaluate - * function arguments in. We can't use the per-tuple context for this - * because it gets reset too often; but we don't want to leak evaluation - * results into the query-lifespan context either. We use one context for - * the arguments of all tSRFs, as they have roughly equivalent lifetimes. + * Create a memory context that ExecMakeFunctionResultSet can use to + * evaluate function arguments in. We can't use the per-tuple context for + * this because it gets reset too often; but we don't want to leak + * evaluation results into the query-lifespan context either. We use one + * context for the arguments of all tSRFs, as they have roughly equivalent + * lifetimes. */ state->argcontext = AllocSetContextCreate(CurrentMemoryContext, "tSRF function arguments", diff --git a/src/backend/executor/nodeRecursiveunion.c b/src/backend/executor/nodeRecursiveunion.c index 6b3ea5afb31..81deb61c215 100644 --- a/src/backend/executor/nodeRecursiveunion.c +++ b/src/backend/executor/nodeRecursiveunion.c @@ -7,7 +7,7 @@ * already seen. The hash key is computed from the grouping columns. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -37,17 +37,19 @@ build_hash_table(RecursiveUnionState *rustate) Assert(node->numCols > 0); Assert(node->numGroups > 0); - rustate->hashtable = BuildTupleHashTable(&rustate->ps, - desc, - node->numCols, - node->dupColIdx, - rustate->eqfuncoids, - rustate->hashfunctions, - node->numGroups, - 0, - rustate->tableContext, - rustate->tempContext, - false); + rustate->hashtable = BuildTupleHashTableExt(&rustate->ps, + desc, + node->numCols, + node->dupColIdx, + rustate->eqfuncoids, + rustate->hashfunctions, + node->dupCollations, + node->numGroups, + 0, + rustate->ps.state->es_query_cxt, + rustate->tableContext, + rustate->tempContext, + false); } @@ -158,7 +160,7 @@ ExecRecursiveUnion(PlanState *pstate) } /* ---------------------------------------------------------------- - * ExecInitRecursiveUnionScan + * ExecInitRecursiveUnion * ---------------------------------------------------------------- */ RecursiveUnionState * @@ -229,7 +231,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags) * RecursiveUnion nodes still have Result slots, which hold pointers to * tuples, so we have to initialize them. */ - ExecInitResultTupleSlotTL(estate, &rustate->ps); + ExecInitResultTypeTL(&rustate->ps); /* * Initialize result tuple type. (Note: we have to set up the result type @@ -261,7 +263,7 @@ ExecInitRecursiveUnion(RecursiveUnion *node, EState *estate, int eflags) } /* ---------------------------------------------------------------- - * ExecEndRecursiveUnionScan + * ExecEndRecursiveUnion * * frees any storage allocated through C routines. * ---------------------------------------------------------------- @@ -279,11 +281,6 @@ ExecEndRecursiveUnion(RecursiveUnionState *node) if (node->tableContext) MemoryContextDelete(node->tableContext); - /* - * clean out the upper tuple table - */ - ExecClearTuple(node->ps.ps_ResultTupleSlot); - /* * close down subplans */ @@ -322,9 +319,9 @@ ExecReScanRecursiveUnion(RecursiveUnionState *node) if (node->tableContext) MemoryContextResetAndDeleteChildren(node->tableContext); - /* And rebuild empty hashtable if needed */ + /* Empty hashtable if needed */ if (plan->numCols > 0) - build_hash_table(node); + ResetTupleHashTable(node->hashtable); /* reset processing state */ node->recursing = false; diff --git a/src/backend/executor/nodeResult.c b/src/backend/executor/nodeResult.c index e4418a29bba..80ed9cca6e4 100644 --- a/src/backend/executor/nodeResult.c +++ b/src/backend/executor/nodeResult.c @@ -34,7 +34,7 @@ * plan normally and pass back the results. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -217,7 +217,7 @@ ExecInitResult(Result *node, EState *estate, int eflags) /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &resstate->ps); + ExecInitResultTupleSlotTL(&resstate->ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&resstate->ps, NULL); /* diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c index 872d6e5735e..14a0a6357d4 100644 --- a/src/backend/executor/nodeSamplescan.c +++ b/src/backend/executor/nodeSamplescan.c @@ -3,7 +3,7 @@ * nodeSamplescan.c * Support routines for sample scans of relations (table sampling). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,23 +14,21 @@ */ #include "postgres.h" -#include "access/hash.h" #include "access/relscan.h" +#include "access/tableam.h" #include "access/tsmapi.h" #include "executor/executor.h" #include "executor/nodeSamplescan.h" #include "miscadmin.h" #include "pgstat.h" +#include "storage/bufmgr.h" #include "storage/predicate.h" #include "utils/builtins.h" #include "utils/rel.h" -#include "utils/tqual.h" static TupleTableSlot *SampleNext(SampleScanState *node); static void tablesample_init(SampleScanState *scanstate); -static HeapTuple tablesample_getnext(SampleScanState *scanstate); -static bool SampleTupleVisible(HeapTuple tuple, OffsetNumber tupoffset, - HeapScanDesc scan); +static TupleTableSlot *tablesample_getnext(SampleScanState *scanstate); /* ---------------------------------------------------------------- * Scan Support @@ -46,9 +44,6 @@ static bool SampleTupleVisible(HeapTuple tuple, OffsetNumber tupoffset, static TupleTableSlot * SampleNext(SampleScanState *node) { - HeapTuple tuple; - TupleTableSlot *slot; - /* * if this is first call within a scan, initialize */ @@ -58,19 +53,7 @@ SampleNext(SampleScanState *node) /* * get the next tuple, and store it in our result slot */ - tuple = tablesample_getnext(node); - - slot = node->ss.ss_ScanTupleSlot; - - if (tuple) - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - node->ss.ss_currentScanDesc->rs_cbuf, /* tuple's buffer */ - false); /* don't pfree this pointer */ - else - ExecClearTuple(slot); - - return slot; + return tablesample_getnext(node); } /* @@ -135,10 +118,7 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &scanstate->ss.ps); /* - * Initialize scan relation. - * - * Get the relation object id from the relid'th entry in the range table, - * open that relation and acquire appropriate lock on it. + * open the scan relation */ scanstate->ss.ss_currentRelation = ExecOpenScanRelation(estate, @@ -150,13 +130,13 @@ ExecInitSampleScan(SampleScan *node, EState *estate, int eflags) /* and create slot with appropriate rowtype */ ExecInitScanTupleSlot(estate, &scanstate->ss, - RelationGetDescr(scanstate->ss.ss_currentRelation)); + RelationGetDescr(scanstate->ss.ss_currentRelation), + table_slot_callbacks(scanstate->ss.ss_currentRelation)); /* - * Initialize result slot, type and projection. - * tuple table and result tuple initialization + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -215,19 +195,15 @@ ExecEndSampleScan(SampleScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * close heap scan */ if (node->ss.ss_currentScanDesc) - heap_endscan(node->ss.ss_currentScanDesc); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(node->ss.ss_currentRelation); + table_endscan(node->ss.ss_currentScanDesc); } /* ---------------------------------------------------------------- @@ -242,6 +218,9 @@ ExecReScanSampleScan(SampleScanState *node) { /* Remember we need to do BeginSampleScan again (if we did it at all) */ node->begun = false; + node->done = false; + node->haveblock = false; + node->donetuples = 0; ExecScanReScan(&node->ss); } @@ -263,6 +242,7 @@ tablesample_init(SampleScanState *scanstate) int i; ListCell *arg; + scanstate->donetuples = 0; params = (Datum *) palloc(list_length(scanstate->args) * sizeof(Datum)); i = 0; @@ -327,19 +307,19 @@ tablesample_init(SampleScanState *scanstate) if (scanstate->ss.ss_currentScanDesc == NULL) { scanstate->ss.ss_currentScanDesc = - heap_beginscan_sampling(scanstate->ss.ss_currentRelation, - scanstate->ss.ps.state->es_snapshot, - 0, NULL, - scanstate->use_bulkread, - allow_sync, - scanstate->use_pagemode); + table_beginscan_sampling(scanstate->ss.ss_currentRelation, + scanstate->ss.ps.state->es_snapshot, + 0, NULL, + scanstate->use_bulkread, + allow_sync, + scanstate->use_pagemode); } else { - heap_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL, - scanstate->use_bulkread, - allow_sync, - scanstate->use_pagemode); + table_rescan_set_params(scanstate->ss.ss_currentScanDesc, NULL, + scanstate->use_bulkread, + allow_sync, + scanstate->use_pagemode); } pfree(params); @@ -350,224 +330,49 @@ tablesample_init(SampleScanState *scanstate) /* * Get next tuple from TABLESAMPLE method. - * - * Note: an awful lot of this is copied-and-pasted from heapam.c. It would - * perhaps be better to refactor to share more code. */ -static HeapTuple +static TupleTableSlot * tablesample_getnext(SampleScanState *scanstate) { - TsmRoutine *tsm = scanstate->tsmroutine; - HeapScanDesc scan = scanstate->ss.ss_currentScanDesc; - HeapTuple tuple = &(scan->rs_ctup); - Snapshot snapshot = scan->rs_snapshot; - bool pagemode = scan->rs_pageatatime; - BlockNumber blockno; - Page page; - bool all_visible; - OffsetNumber maxoffset; - - if (!scan->rs_inited) - { - /* - * return null immediately if relation is empty - */ - if (scan->rs_nblocks == 0) - { - Assert(!BufferIsValid(scan->rs_cbuf)); - tuple->t_data = NULL; - return NULL; - } - if (tsm->NextSampleBlock) - { - blockno = tsm->NextSampleBlock(scanstate); - if (!BlockNumberIsValid(blockno)) - { - tuple->t_data = NULL; - return NULL; - } - } - else - blockno = scan->rs_startblock; - Assert(blockno < scan->rs_nblocks); - heapgetpage(scan, blockno); - scan->rs_inited = true; - } - else - { - /* continue from previously returned page/tuple */ - blockno = scan->rs_cblock; /* current page */ - } + TableScanDesc scan = scanstate->ss.ss_currentScanDesc; + TupleTableSlot *slot = scanstate->ss.ss_ScanTupleSlot; - /* - * When not using pagemode, we must lock the buffer during tuple - * visibility checks. - */ - if (!pagemode) - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); + ExecClearTuple(slot); - page = (Page) BufferGetPage(scan->rs_cbuf); - all_visible = PageIsAllVisible(page) && !snapshot->takenDuringRecovery; - maxoffset = PageGetMaxOffsetNumber(page); + if (scanstate->done) + return NULL; for (;;) { - OffsetNumber tupoffset; - bool finished; - - CHECK_FOR_INTERRUPTS(); - - /* Ask the tablesample method which tuples to check on this page. */ - tupoffset = tsm->NextSampleTuple(scanstate, - blockno, - maxoffset); - - if (OffsetNumberIsValid(tupoffset)) + if (!scanstate->haveblock) { - ItemId itemid; - bool visible; - - /* Skip invalid tuple pointers. */ - itemid = PageGetItemId(page, tupoffset); - if (!ItemIdIsNormal(itemid)) - continue; - - tuple->t_data = (HeapTupleHeader) PageGetItem(page, itemid); - tuple->t_len = ItemIdGetLength(itemid); - ItemPointerSet(&(tuple->t_self), blockno, tupoffset); - - if (all_visible) - visible = true; - else - visible = SampleTupleVisible(tuple, tupoffset, scan); - - /* in pagemode, heapgetpage did this for us */ - if (!pagemode) - CheckForSerializableConflictOut(visible, scan->rs_rd, tuple, - scan->rs_cbuf, snapshot); - - if (visible) + if (!table_scan_sample_next_block(scan, scanstate)) { - /* Found visible tuple, return it. */ - if (!pagemode) - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); - break; - } - else - { - /* Try next tuple from same page. */ - continue; - } - } + scanstate->haveblock = false; + scanstate->done = true; - /* - * if we get here, it means we've exhausted the items on this page and - * it's time to move to the next. - */ - if (!pagemode) - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); + /* exhausted relation */ + return NULL; + } - if (tsm->NextSampleBlock) - { - blockno = tsm->NextSampleBlock(scanstate); - Assert(!scan->rs_syncscan); - finished = !BlockNumberIsValid(blockno); + scanstate->haveblock = true; } - else - { - /* Without NextSampleBlock, just do a plain forward seqscan. */ - blockno++; - if (blockno >= scan->rs_nblocks) - blockno = 0; + if (!table_scan_sample_next_tuple(scan, scanstate, slot)) + { /* - * Report our new scan position for synchronization purposes. - * - * Note: we do this before checking for end of scan so that the - * final state of the position hint is back at the start of the - * rel. That's not strictly necessary, but otherwise when you run - * the same query multiple times the starting position would shift - * a little bit backwards on every invocation, which is confusing. - * We don't guarantee any specific ordering in general, though. + * If we get here, it means we've exhausted the items on this page + * and it's time to move to the next. */ - if (scan->rs_syncscan) - ss_report_location(scan->rs_rd, blockno); - - finished = (blockno == scan->rs_startblock); + scanstate->haveblock = false; + continue; } - /* - * Reached end of scan? - */ - if (finished) - { - if (BufferIsValid(scan->rs_cbuf)) - ReleaseBuffer(scan->rs_cbuf); - scan->rs_cbuf = InvalidBuffer; - scan->rs_cblock = InvalidBlockNumber; - tuple->t_data = NULL; - scan->rs_inited = false; - return NULL; - } - - Assert(blockno < scan->rs_nblocks); - heapgetpage(scan, blockno); - - /* Re-establish state for new page */ - if (!pagemode) - LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - - page = (Page) BufferGetPage(scan->rs_cbuf); - all_visible = PageIsAllVisible(page) && !snapshot->takenDuringRecovery; - maxoffset = PageGetMaxOffsetNumber(page); + /* Found visible tuple, return it. */ + break; } - /* Count successfully-fetched tuples as heap fetches */ - pgstat_count_heap_getnext(scan->rs_rd); + scanstate->donetuples++; - return &(scan->rs_ctup); -} - -/* - * Check visibility of the tuple. - */ -static bool -SampleTupleVisible(HeapTuple tuple, OffsetNumber tupoffset, HeapScanDesc scan) -{ - if (scan->rs_pageatatime) - { - /* - * In pageatatime mode, heapgetpage() already did visibility checks, - * so just look at the info it left in rs_vistuples[]. - * - * We use a binary search over the known-sorted array. Note: we could - * save some effort if we insisted that NextSampleTuple select tuples - * in increasing order, but it's not clear that there would be enough - * gain to justify the restriction. - */ - int start = 0, - end = scan->rs_ntuples - 1; - - while (start <= end) - { - int mid = (start + end) / 2; - OffsetNumber curoffset = scan->rs_vistuples[mid]; - - if (tupoffset == curoffset) - return true; - else if (tupoffset < curoffset) - end = mid - 1; - else - start = mid + 1; - } - - return false; - } - else - { - /* Otherwise, we have to check the tuple individually. */ - return HeapTupleSatisfiesVisibility(tuple, - scan->rs_snapshot, - scan->rs_cbuf); - } + return slot; } diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index 9db368922a3..436b43f8ca5 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -3,7 +3,7 @@ * nodeSeqscan.c * Support routines for sequential scans of relations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,6 +28,7 @@ #include "postgres.h" #include "access/relscan.h" +#include "access/tableam.h" #include "executor/execdebug.h" #include "executor/nodeSeqscan.h" #include "utils/rel.h" @@ -48,8 +49,7 @@ static TupleTableSlot *SeqNext(SeqScanState *node); static TupleTableSlot * SeqNext(SeqScanState *node) { - HeapTuple tuple; - HeapScanDesc scandesc; + TableScanDesc scandesc; EState *estate; ScanDirection direction; TupleTableSlot *slot; @@ -65,38 +65,21 @@ SeqNext(SeqScanState *node) if (scandesc == NULL) { /* - * We reach here if the scan is not parallel, or if we're executing a - * scan that was intended to be parallel serially. + * We reach here if the scan is not parallel, or if we're serially + * executing a scan that was planned to be parallel. */ - scandesc = heap_beginscan(node->ss.ss_currentRelation, - estate->es_snapshot, - 0, NULL); + scandesc = table_beginscan(node->ss.ss_currentRelation, + estate->es_snapshot, + 0, NULL); node->ss.ss_currentScanDesc = scandesc; } /* * get the next tuple from the table */ - tuple = heap_getnext(scandesc, direction); - - /* - * save the tuple and the buffer returned to us by the access methods in - * our scan tuple slot and return the slot. Note: we pass 'false' because - * tuples returned by heap_getnext() are pointers onto disk pages and were - * not created with palloc() and so should not be pfree()'d. Note also - * that ExecStoreTuple will increment the refcount of the buffer; the - * refcount will not be dropped until the tuple table slot is cleared. - */ - if (tuple) - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - scandesc->rs_cbuf, /* buffer associated with this - * tuple */ - false); /* don't pfree this pointer */ - else - ExecClearTuple(slot); - - return slot; + if (table_scan_getnextslot(scandesc, direction, slot)) + return slot; + return NULL; } /* @@ -164,10 +147,7 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags) ExecAssignExprContext(estate, &scanstate->ss.ps); /* - * Initialize scan relation. - * - * Get the relation object id from the relid'th entry in the range table, - * open that relation and acquire appropriate lock on it. + * open the scan relation */ scanstate->ss.ss_currentRelation = ExecOpenScanRelation(estate, @@ -176,12 +156,13 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags) /* and create slot with the appropriate rowtype */ ExecInitScanTupleSlot(estate, &scanstate->ss, - RelationGetDescr(scanstate->ss.ss_currentRelation)); + RelationGetDescr(scanstate->ss.ss_currentRelation), + table_slot_callbacks(scanstate->ss.ss_currentRelation)); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -202,13 +183,11 @@ ExecInitSeqScan(SeqScan *node, EState *estate, int eflags) void ExecEndSeqScan(SeqScanState *node) { - Relation relation; - HeapScanDesc scanDesc; + TableScanDesc scanDesc; /* * get information from node */ - relation = node->ss.ss_currentRelation; scanDesc = node->ss.ss_currentScanDesc; /* @@ -219,19 +198,15 @@ ExecEndSeqScan(SeqScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* * close heap scan */ if (scanDesc != NULL) - heap_endscan(scanDesc); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(relation); + table_endscan(scanDesc); } /* ---------------------------------------------------------------- @@ -248,13 +223,13 @@ ExecEndSeqScan(SeqScanState *node) void ExecReScanSeqScan(SeqScanState *node) { - HeapScanDesc scan; + TableScanDesc scan; scan = node->ss.ss_currentScanDesc; if (scan != NULL) - heap_rescan(scan, /* scan desc */ - NULL); /* new scan keys */ + table_rescan(scan, /* scan desc */ + NULL); /* new scan keys */ ExecScanReScan((ScanState *) node); } @@ -277,7 +252,8 @@ ExecSeqScanEstimate(SeqScanState *node, { EState *estate = node->ss.ps.state; - node->pscan_len = heap_parallelscan_estimate(estate->es_snapshot); + node->pscan_len = table_parallelscan_estimate(node->ss.ss_currentRelation, + estate->es_snapshot); shm_toc_estimate_chunk(&pcxt->estimator, node->pscan_len); shm_toc_estimate_keys(&pcxt->estimator, 1); } @@ -293,15 +269,15 @@ ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt) { EState *estate = node->ss.ps.state; - ParallelHeapScanDesc pscan; + ParallelTableScanDesc pscan; pscan = shm_toc_allocate(pcxt->toc, node->pscan_len); - heap_parallelscan_initialize(pscan, - node->ss.ss_currentRelation, - estate->es_snapshot); + table_parallelscan_initialize(node->ss.ss_currentRelation, + pscan, + estate->es_snapshot); shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan); node->ss.ss_currentScanDesc = - heap_beginscan_parallel(node->ss.ss_currentRelation, pscan); + table_beginscan_parallel(node->ss.ss_currentRelation, pscan); } /* ---------------------------------------------------------------- @@ -314,9 +290,10 @@ void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt) { - HeapScanDesc scan = node->ss.ss_currentScanDesc; + ParallelTableScanDesc pscan; - heap_parallelscan_reinitialize(scan->rs_parallel); + pscan = node->ss.ss_currentScanDesc->rs_parallel; + table_parallelscan_reinitialize(node->ss.ss_currentRelation, pscan); } /* ---------------------------------------------------------------- @@ -329,9 +306,9 @@ void ExecSeqScanInitializeWorker(SeqScanState *node, ParallelWorkerContext *pwcxt) { - ParallelHeapScanDesc pscan; + ParallelTableScanDesc pscan; pscan = shm_toc_lookup(pwcxt->toc, node->ss.ps.plan->plan_node_id, false); node->ss.ss_currentScanDesc = - heap_beginscan_parallel(node->ss.ss_currentRelation, pscan); + table_beginscan_parallel(node->ss.ss_currentRelation, pscan); } diff --git a/src/backend/executor/nodeSetOp.c b/src/backend/executor/nodeSetOp.c index 3fa4a5fcc65..044246aa09f 100644 --- a/src/backend/executor/nodeSetOp.c +++ b/src/backend/executor/nodeSetOp.c @@ -32,7 +32,7 @@ * input group. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -126,17 +126,19 @@ build_hash_table(SetOpState *setopstate) Assert(node->strategy == SETOP_HASHED); Assert(node->numGroups > 0); - setopstate->hashtable = BuildTupleHashTable(&setopstate->ps, - desc, - node->numCols, - node->dupColIdx, - setopstate->eqfuncoids, - setopstate->hashfunctions, - node->numGroups, - 0, - setopstate->tableContext, - econtext->ecxt_per_tuple_memory, - false); + setopstate->hashtable = BuildTupleHashTableExt(&setopstate->ps, + desc, + node->numCols, + node->dupColIdx, + setopstate->eqfuncoids, + setopstate->hashfunctions, + node->dupCollations, + node->numGroups, + 0, + setopstate->ps.state->es_query_cxt, + setopstate->tableContext, + econtext->ecxt_per_tuple_memory, + false); } /* @@ -252,7 +254,7 @@ setop_retrieve_direct(SetOpState *setopstate) if (!TupIsNull(outerslot)) { /* Make a copy of the first input tuple */ - setopstate->grp_firstTuple = ExecCopySlotTuple(outerslot); + setopstate->grp_firstTuple = ExecCopySlotHeapTuple(outerslot); } else { @@ -267,10 +269,9 @@ setop_retrieve_direct(SetOpState *setopstate) * for it. The tuple will be deleted when it is cleared from the * slot. */ - ExecStoreTuple(setopstate->grp_firstTuple, - resultTupleSlot, - InvalidBuffer, - true); + ExecStoreHeapTuple(setopstate->grp_firstTuple, + resultTupleSlot, + true); setopstate->grp_firstTuple = NULL; /* don't keep two pointers */ /* Initialize working state for a new input tuple group */ @@ -304,7 +305,7 @@ setop_retrieve_direct(SetOpState *setopstate) /* * Save the first input tuple of the next group. */ - setopstate->grp_firstTuple = ExecCopySlotTuple(outerslot); + setopstate->grp_firstTuple = ExecCopySlotHeapTuple(outerslot); break; } @@ -533,7 +534,9 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags) * Initialize result slot and type. Setop nodes do no projections, so * initialize projection info for this node appropriately. */ - ExecInitResultTupleSlotTL(estate, &setopstate->ps); + ExecInitResultTupleSlotTL(&setopstate->ps, + node->strategy == SETOP_HASHED ? + &TTSOpsMinimalTuple : &TTSOpsHeapTuple); setopstate->ps.ps_ProjInfo = NULL; /* @@ -552,6 +555,7 @@ ExecInitSetOp(SetOp *node, EState *estate, int eflags) node->numCols, node->dupColIdx, node->dupOperators, + node->dupCollations, &setopstate->ps); if (node->strategy == SETOP_HASHED) @@ -634,7 +638,7 @@ ExecReScanSetOp(SetOpState *node) /* And rebuild empty hashtable if needed */ if (((SetOp *) node->ps.plan)->strategy == SETOP_HASHED) { - build_hash_table(node); + ResetTupleHashTable(node->hashtable); node->table_filled = false; } diff --git a/src/backend/executor/nodeSort.c b/src/backend/executor/nodeSort.c index 73f16c9abaa..92855278adb 100644 --- a/src/backend/executor/nodeSort.c +++ b/src/backend/executor/nodeSort.c @@ -3,7 +3,7 @@ * nodeSort.c * Routines to handle sorting of relations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -211,13 +211,13 @@ ExecInitSort(Sort *node, EState *estate, int eflags) /* * Initialize scan slot and type. */ - ExecCreateScanSlotFromOuterPlan(estate, &sortstate->ss); + ExecCreateScanSlotFromOuterPlan(estate, &sortstate->ss, &TTSOpsVirtual); /* - * Initialize return slot and type. No need to initialize projection info because - * this node doesn't do projections. + * Initialize return slot and type. No need to initialize projection info + * because this node doesn't do projections. */ - ExecInitResultTupleSlotTL(estate, &sortstate->ss.ps); + ExecInitResultTupleSlotTL(&sortstate->ss.ps, &TTSOpsMinimalTuple); sortstate->ss.ps.ps_ProjInfo = NULL; SO1_printf("ExecInitSort: %s\n", diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index d5411500a2b..1991b90a55f 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -11,7 +11,7 @@ * subplans, which are re-evaluated every time their result is required. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -33,22 +33,22 @@ #include "executor/executor.h" #include "executor/nodeSubplan.h" #include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" #include "miscadmin.h" -#include "optimizer/clauses.h" #include "utils/array.h" #include "utils/lsyscache.h" #include "utils/memutils.h" static Datum ExecHashSubPlan(SubPlanState *node, - ExprContext *econtext, - bool *isNull); + ExprContext *econtext, + bool *isNull); static Datum ExecScanSubPlan(SubPlanState *node, - ExprContext *econtext, - bool *isNull); + ExprContext *econtext, + bool *isNull); static void buildSubPlanHash(SubPlanState *node, ExprContext *econtext); static bool findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot, - FmgrInfo *eqfunctions); + FmgrInfo *eqfunctions); static bool slotAllNulls(TupleTableSlot *slot); static bool slotNoNulls(TupleTableSlot *slot); @@ -65,6 +65,9 @@ ExecSubPlan(SubPlanState *node, bool *isNull) { SubPlan *subplan = node->subplan; + EState *estate = node->planstate->state; + ScanDirection dir = estate->es_direction; + Datum retval; CHECK_FOR_INTERRUPTS(); @@ -77,11 +80,19 @@ ExecSubPlan(SubPlanState *node, if (subplan->setParam != NIL && subplan->subLinkType != MULTIEXPR_SUBLINK) elog(ERROR, "cannot set parent params from subquery"); + /* Force forward-scan mode for evaluation */ + estate->es_direction = ForwardScanDirection; + /* Select appropriate evaluation strategy */ if (subplan->useHashTable) - return ExecHashSubPlan(node, econtext, isNull); + retval = ExecHashSubPlan(node, econtext, isNull); else - return ExecScanSubPlan(node, econtext, isNull); + retval = ExecScanSubPlan(node, econtext, isNull); + + /* restore scan direction */ + estate->es_direction = dir; + + return retval; } /* @@ -346,7 +357,7 @@ ExecScanSubPlan(SubPlanState *node, */ if (node->curTuple) heap_freetuple(node->curTuple); - node->curTuple = ExecCopySlotTuple(slot); + node->curTuple = ExecCopySlotHeapTuple(slot); result = heap_getattr(node->curTuple, 1, tdesc, isNull); /* keep scanning subplan to make sure there's only one tuple */ @@ -470,8 +481,8 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) Assert(subplan->subLinkType == ANY_SUBLINK); /* - * If we already had any hash tables, destroy 'em; then create empty hash - * table(s). + * If we already had any hash tables, reset 'em; otherwise create empty + * hash table(s). * * If we need to distinguish accurately between FALSE and UNKNOWN (i.e., * NULL) results of the IN operation, then we have to store subplan output @@ -494,17 +505,22 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; - node->hashtable = BuildTupleHashTable(node->parent, - node->descRight, - ncols, - node->keyColIdx, - node->tab_eq_funcoids, - node->tab_hash_funcs, - nbuckets, - 0, - node->hashtablecxt, - node->hashtempcxt, - false); + if (node->hashtable) + ResetTupleHashTable(node->hashtable); + else + node->hashtable = BuildTupleHashTableExt(node->parent, + node->descRight, + ncols, + node->keyColIdx, + node->tab_eq_funcoids, + node->tab_hash_funcs, + node->tab_collations, + nbuckets, + 0, + node->planstate->state->es_query_cxt, + node->hashtablecxt, + node->hashtempcxt, + false); if (!subplan->unknownEqFalse) { @@ -516,17 +532,23 @@ buildSubPlanHash(SubPlanState *node, ExprContext *econtext) if (nbuckets < 1) nbuckets = 1; } - node->hashnulls = BuildTupleHashTable(node->parent, - node->descRight, - ncols, - node->keyColIdx, - node->tab_eq_funcoids, - node->tab_hash_funcs, - nbuckets, - 0, - node->hashtablecxt, - node->hashtempcxt, - false); + + if (node->hashnulls) + ResetTupleHashTable(node->hashtable); + else + node->hashnulls = BuildTupleHashTableExt(node->parent, + node->descRight, + ncols, + node->keyColIdx, + node->tab_eq_funcoids, + node->tab_hash_funcs, + node->tab_collations, + nbuckets, + 0, + node->planstate->state->es_query_cxt, + node->hashtablecxt, + node->hashtempcxt, + false); } /* @@ -622,6 +644,7 @@ execTuplesUnequal(TupleTableSlot *slot1, int numCols, AttrNumber *matchColIdx, FmgrInfo *eqfunctions, + const Oid *collations, MemoryContext evalContext) { MemoryContext oldContext; @@ -659,9 +682,9 @@ execTuplesUnequal(TupleTableSlot *slot1, continue; /* can't prove anything here */ /* Apply the type-specific equality function */ - - if (!DatumGetBool(FunctionCall2(&eqfunctions[i], - attr1, attr2))) + if (!DatumGetBool(FunctionCall2Coll(&eqfunctions[i], + collations[i], + attr1, attr2))) { result = true; /* they are unequal */ break; @@ -702,6 +725,7 @@ findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot, if (!execTuplesUnequal(slot, hashtable->tableslot, numCols, keyColIdx, eqfunctions, + hashtable->tab_collations, hashtable->tempcxt)) { TermTupleHashIterator(&hashiter); @@ -797,6 +821,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) sstate->tab_eq_funcoids = NULL; sstate->tab_hash_funcs = NULL; sstate->tab_eq_funcs = NULL; + sstate->tab_collations = NULL; sstate->lhs_hash_funcs = NULL; sstate->cur_eq_funcs = NULL; @@ -835,6 +860,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) i; TupleDesc tupDescLeft; TupleDesc tupDescRight; + Oid *cross_eq_funcoids; TupleTableSlot *slot; List *oplist, *lefttlist, @@ -877,7 +903,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* single combining operator */ oplist = list_make1(subplan->testexpr); } - else if (and_clause((Node *) subplan->testexpr)) + else if (is_andclause(subplan->testexpr)) { /* multiple combining operators */ oplist = castNode(BoolExpr, subplan->testexpr)->args; @@ -895,8 +921,12 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) sstate->tab_eq_funcoids = (Oid *) palloc(ncols * sizeof(Oid)); sstate->tab_hash_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo)); sstate->tab_eq_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo)); + sstate->tab_collations = (Oid *) palloc(ncols * sizeof(Oid)); sstate->lhs_hash_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo)); sstate->cur_eq_funcs = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo)); + /* we'll need the cross-type equality fns below, but not in sstate */ + cross_eq_funcoids = (Oid *) palloc(ncols * sizeof(Oid)); + i = 1; foreach(l, oplist) { @@ -926,7 +956,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) righttlist = lappend(righttlist, tle); /* Lookup the equality function (potentially cross-type) */ - sstate->tab_eq_funcoids[i - 1] = opexpr->opfuncid; + cross_eq_funcoids[i - 1] = opexpr->opfuncid; fmgr_info(opexpr->opfuncid, &sstate->cur_eq_funcs[i - 1]); fmgr_info_set_expr((Node *) opexpr, &sstate->cur_eq_funcs[i - 1]); @@ -935,7 +965,9 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) NULL, &rhs_eq_oper)) elog(ERROR, "could not find compatible hash operator for operator %u", opexpr->opno); - fmgr_info(get_opcode(rhs_eq_oper), &sstate->tab_eq_funcs[i - 1]); + sstate->tab_eq_funcoids[i - 1] = get_opcode(rhs_eq_oper); + fmgr_info(sstate->tab_eq_funcoids[i - 1], + &sstate->tab_eq_funcs[i - 1]); /* Lookup the associated hash functions */ if (!get_op_hash_functions(opexpr->opno, @@ -945,6 +977,9 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) fmgr_info(left_hashfn, &sstate->lhs_hash_funcs[i - 1]); fmgr_info(right_hashfn, &sstate->tab_hash_funcs[i - 1]); + /* Set collation */ + sstate->tab_collations[i - 1] = opexpr->inputcollid; + i++; } @@ -956,16 +991,16 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) * (hack alert!). The righthand expressions will be evaluated in our * own innerecontext. */ - tupDescLeft = ExecTypeFromTL(lefttlist, false); - slot = ExecInitExtraTupleSlot(estate, tupDescLeft); + tupDescLeft = ExecTypeFromTL(lefttlist); + slot = ExecInitExtraTupleSlot(estate, tupDescLeft, &TTSOpsVirtual); sstate->projLeft = ExecBuildProjectionInfo(lefttlist, NULL, slot, parent, NULL); - sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist, false); - slot = ExecInitExtraTupleSlot(estate, tupDescRight); + sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist); + slot = ExecInitExtraTupleSlot(estate, tupDescRight, &TTSOpsVirtual); sstate->projRight = ExecBuildProjectionInfo(righttlist, sstate->innerecontext, slot, @@ -974,14 +1009,15 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) /* * Create comparator for lookups of rows in the table (potentially - * across-type comparison). + * cross-type comparisons). */ sstate->cur_eq_comp = ExecBuildGroupingEqual(tupDescLeft, tupDescRight, + &TTSOpsVirtual, &TTSOpsMinimalTuple, ncols, sstate->keyColIdx, - sstate->tab_eq_funcoids, + cross_eq_funcoids, + sstate->tab_collations, parent); - } return sstate; @@ -998,6 +1034,17 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent) * of initplans: we don't run the subplan until/unless we need its output. * Note that this routine MUST clear the execPlan fields of the plan's * output parameters after evaluating them! + * + * The results of this function are stored in the EState associated with the + * ExprContext (particularly, its ecxt_param_exec_vals); any pass-by-ref + * result Datums are allocated in the EState's per-query memory. The passed + * econtext can be any ExprContext belonging to that EState; which one is + * important only to the extent that the ExprContext's per-tuple memory + * context is used to evaluate any parameters passed down to the subplan. + * (Thus in principle, the shorter-lived the ExprContext the better, since + * that data isn't needed after we return. In practice, because initplan + * parameters are never more complex than Vars, Aggrefs, etc, evaluating them + * currently never leaks any memory anyway.) * ---------------------------------------------------------------- */ void @@ -1006,6 +1053,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) SubPlan *subplan = node->subplan; PlanState *planstate = node->planstate; SubLinkType subLinkType = subplan->subLinkType; + EState *estate = planstate->state; + ScanDirection dir = estate->es_direction; MemoryContext oldcontext; TupleTableSlot *slot; ListCell *pvar; @@ -1019,6 +1068,12 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) if (subLinkType == CTE_SUBLINK) elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan"); + /* + * Enforce forward scan direction regardless of caller. It's hard but not + * impossible to get here in backward scan, so make it work anyway. + */ + estate->es_direction = ForwardScanDirection; + /* Initialize ArrayBuildStateAny in caller's context, if needed */ if (subLinkType == ARRAY_SUBLINK) astate = initArrayResultAny(subplan->firstColType, @@ -1106,7 +1161,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) */ if (node->curTuple) heap_freetuple(node->curTuple); - node->curTuple = ExecCopySlotTuple(slot); + node->curTuple = ExecCopySlotHeapTuple(slot); /* * Now set all the setParam params from the columns of the tuple @@ -1171,6 +1226,40 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) } MemoryContextSwitchTo(oldcontext); + + /* restore scan direction */ + estate->es_direction = dir; +} + +/* + * ExecSetParamPlanMulti + * + * Apply ExecSetParamPlan to evaluate any not-yet-evaluated initplan output + * parameters whose ParamIDs are listed in "params". Any listed params that + * are not initplan outputs are ignored. + * + * As with ExecSetParamPlan, any ExprContext belonging to the current EState + * can be used, but in principle a shorter-lived ExprContext is better than a + * longer-lived one. + */ +void +ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext) +{ + int paramid; + + paramid = -1; + while ((paramid = bms_next_member(params, paramid)) >= 0) + { + ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); + + if (prm->execPlan != NULL) + { + /* Parameter not evaluated yet, so go do it */ + ExecSetParamPlan(prm->execPlan, econtext); + /* ExecSetParamPlan should have processed this param... */ + Assert(prm->execPlan == NULL); + } + } } /* diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c index fa618847851..de8c0060510 100644 --- a/src/backend/executor/nodeSubqueryscan.c +++ b/src/backend/executor/nodeSubqueryscan.c @@ -7,7 +7,7 @@ * we need two sets of code. Ought to look at trying to unify the cases. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -126,15 +126,27 @@ ExecInitSubqueryScan(SubqueryScan *node, EState *estate, int eflags) subquerystate->subplan = ExecInitNode(node->subplan, estate, eflags); /* - * Initialize scan slot and type (needed by ExecInitResultTupleSlotTL) + * Initialize scan slot and type (needed by ExecAssignScanProjectionInfo) */ ExecInitScanTupleSlot(estate, &subquerystate->ss, - ExecGetResultType(subquerystate->subplan)); + ExecGetResultType(subquerystate->subplan), + ExecGetResultSlotOps(subquerystate->subplan, NULL)); /* - * Initialize result slot, type and projection. + * The slot used as the scantuple isn't the slot above (outside of EPQ), + * but the one from the node below. */ - ExecInitResultTupleSlotTL(estate, &subquerystate->ss.ps); + subquerystate->ss.ps.scanopsset = true; + subquerystate->ss.ps.scanops = ExecGetResultSlotOps(subquerystate->subplan, + &subquerystate->ss.ps.scanopsfixed); + subquerystate->ss.ps.resultopsset = true; + subquerystate->ss.ps.resultops = subquerystate->ss.ps.scanops; + subquerystate->ss.ps.resultopsfixed = subquerystate->ss.ps.scanopsfixed; + + /* + * Initialize result type and projection. + */ + ExecInitResultTypeTL(&subquerystate->ss.ps); ExecAssignScanProjectionInfo(&subquerystate->ss); /* @@ -163,7 +175,8 @@ ExecEndSubqueryScan(SubqueryScanState *node) /* * clean out the upper tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* diff --git a/src/backend/executor/nodeTableFuncscan.c b/src/backend/executor/nodeTableFuncscan.c index fed6f2b3a53..d264337899a 100644 --- a/src/backend/executor/nodeTableFuncscan.c +++ b/src/backend/executor/nodeTableFuncscan.c @@ -3,7 +3,7 @@ * nodeTableFuncscan.c * Support routines for scanning RangeTableFunc (XMLTABLE like functions). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -147,12 +147,13 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags) tf->coltypmods, tf->colcollations); /* and the corresponding scan slot */ - ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc); + ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc, + &TTSOpsMinimalTuple); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -164,7 +165,7 @@ ExecInitTableFuncScan(TableFuncScan *node, EState *estate, int eflags) /* Only XMLTABLE is supported currently */ scanstate->routine = &XmlTableRoutine; - scanstate->perValueCxt = + scanstate->perTableCxt = AllocSetContextCreate(CurrentMemoryContext, "TableFunc per value context", ALLOCSET_DEFAULT_SIZES); @@ -221,7 +222,8 @@ ExecEndTableFuncScan(TableFuncScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); /* @@ -243,7 +245,8 @@ ExecReScanTableFuncScan(TableFuncScanState *node) { Bitmapset *chgparam = node->ss.ps.chgParam; - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); /* @@ -282,6 +285,16 @@ tfuncFetchRows(TableFuncScanState *tstate, ExprContext *econtext) oldcxt = MemoryContextSwitchTo(econtext->ecxt_per_query_memory); tstate->tupstore = tuplestore_begin_heap(false, false, work_mem); + /* + * Each call to fetch a new set of rows - of which there may be very many + * if XMLTABLE is being used in a lateral join - will allocate a possibly + * substantial amount of memory, so we cannot use the per-query context + * here. perTableCxt now serves the same function as "argcontext" does in + * FunctionScan - a place to store per-one-call (i.e. one result table) + * lifetime data (as opposed to per-query or per-result-tuple). + */ + MemoryContextSwitchTo(tstate->perTableCxt); + PG_TRY(); { routine->InitOpaque(tstate, @@ -313,8 +326,7 @@ tfuncFetchRows(TableFuncScanState *tstate, ExprContext *econtext) } PG_END_TRY(); - /* return to original memory context, and clean up */ - MemoryContextSwitchTo(oldcxt); + /* clean up and return to original memory context */ if (tstate->opaque != NULL) { @@ -322,6 +334,9 @@ tfuncFetchRows(TableFuncScanState *tstate, ExprContext *econtext) tstate->opaque = NULL; } + MemoryContextSwitchTo(oldcxt); + MemoryContextReset(tstate->perTableCxt); + return; } @@ -352,8 +367,9 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc) forboth(lc1, tstate->ns_uris, lc2, tstate->ns_names) { ExprState *expr = (ExprState *) lfirst(lc1); - char *ns_name = strVal(lfirst(lc2)); + Value *ns_node = (Value *) lfirst(lc2); char *ns_uri; + char *ns_name; value = ExecEvalExpr((ExprState *) expr, econtext, &isnull); if (isnull) @@ -362,6 +378,9 @@ tfuncInitialize(TableFuncScanState *tstate, ExprContext *econtext, Datum doc) errmsg("namespace URI must not be null"))); ns_uri = TextDatumGetCString(value); + /* DEFAULT is passed down to SetNamespace as NULL */ + ns_name = ns_node ? strVal(ns_node) : NULL; + routine->SetNamespace(tstate, ns_name, ns_uri); } @@ -428,7 +447,14 @@ tfuncLoadRows(TableFuncScanState *tstate, ExprContext *econtext) ordinalitycol = ((TableFuncScan *) (tstate->ss.ps.plan))->tablefunc->ordinalitycol; - oldcxt = MemoryContextSwitchTo(tstate->perValueCxt); + + /* + * We need a short-lived memory context that we can clean up each time + * around the loop, to avoid wasting space. Our default per-tuple context + * is fine for the job, since we won't have used it for anything yet in + * this tuple cycle. + */ + oldcxt = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory); /* * Keep requesting rows from the table builder until there aren't any. @@ -488,12 +514,12 @@ tfuncLoadRows(TableFuncScanState *tstate, ExprContext *econtext) /* advance list of default expressions */ if (cell != NULL) - cell = lnext(cell); + cell = lnext(tstate->coldefexprs, cell); } tuplestore_putvalues(tstate->tupstore, tupdesc, values, nulls); - MemoryContextReset(tstate->perValueCxt); + MemoryContextReset(econtext->ecxt_per_tuple_memory); } MemoryContextSwitchTo(oldcxt); diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c index e207b1ffb51..8cf22d5bf00 100644 --- a/src/backend/executor/nodeTidscan.c +++ b/src/backend/executor/nodeTidscan.c @@ -3,7 +3,7 @@ * nodeTidscan.c * Routines to support direct tid scans of relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,11 +23,12 @@ #include "postgres.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "catalog/pg_type.h" #include "executor/execdebug.h" #include "executor/nodeTidscan.h" #include "miscadmin.h" -#include "optimizer/clauses.h" +#include "nodes/nodeFuncs.h" #include "storage/bufmgr.h" #include "utils/array.h" #include "utils/rel.h" @@ -128,19 +129,23 @@ static void TidListEval(TidScanState *tidstate) { ExprContext *econtext = tidstate->ss.ps.ps_ExprContext; - BlockNumber nblocks; + TableScanDesc scan; ItemPointerData *tidList; int numAllocTids; int numTids; ListCell *l; /* - * We silently discard any TIDs that are out of range at the time of scan - * start. (Since we hold at least AccessShareLock on the table, it won't - * be possible for someone to truncate away the blocks we intend to - * visit.) + * Start scan on-demand - initializing a scan isn't free (e.g. heap stats + * the size of the table), so it makes sense to delay that until needed - + * the node might never get executed. */ - nblocks = RelationGetNumberOfBlocks(tidstate->ss.ss_currentRelation); + if (tidstate->ss.ss_currentScanDesc == NULL) + tidstate->ss.ss_currentScanDesc = + table_beginscan(tidstate->ss.ss_currentRelation, + tidstate->ss.ps.state->es_snapshot, + 0, NULL); + scan = tidstate->ss.ss_currentScanDesc; /* * We initialize the array with enough slots for the case that all quals @@ -164,19 +169,27 @@ TidListEval(TidScanState *tidstate) DatumGetPointer(ExecEvalExprSwitchContext(tidexpr->exprstate, econtext, &isNull)); - if (!isNull && - ItemPointerIsValid(itemptr) && - ItemPointerGetBlockNumber(itemptr) < nblocks) + if (isNull) + continue; + + /* + * We silently discard any TIDs that the AM considers invalid + * (E.g. for heap, they could be out of range at the time of scan + * start. Since we hold at least AccessShareLock on the table, it + * won't be possible for someone to truncate away the blocks we + * intend to visit.). + */ + if (!table_tuple_tid_valid(scan, itemptr)) + continue; + + if (numTids >= numAllocTids) { - if (numTids >= numAllocTids) - { - numAllocTids *= 2; - tidList = (ItemPointerData *) - repalloc(tidList, - numAllocTids * sizeof(ItemPointerData)); - } - tidList[numTids++] = *itemptr; + numAllocTids *= 2; + tidList = (ItemPointerData *) + repalloc(tidList, + numAllocTids * sizeof(ItemPointerData)); } + tidList[numTids++] = *itemptr; } else if (tidexpr->exprstate && tidexpr->isarray) { @@ -205,13 +218,15 @@ TidListEval(TidScanState *tidstate) } for (i = 0; i < ndatums; i++) { - if (!ipnulls[i]) - { - itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]); - if (ItemPointerIsValid(itemptr) && - ItemPointerGetBlockNumber(itemptr) < nblocks) - tidList[numTids++] = *itemptr; - } + if (ipnulls[i]) + continue; + + itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]); + + if (!table_tuple_tid_valid(scan, itemptr)) + continue; + + tidList[numTids++] = *itemptr; } pfree(ipdatums); pfree(ipnulls); @@ -305,10 +320,9 @@ TidNext(TidScanState *node) EState *estate; ScanDirection direction; Snapshot snapshot; + TableScanDesc scan; Relation heapRelation; - HeapTuple tuple; TupleTableSlot *slot; - Buffer buffer = InvalidBuffer; ItemPointerData *tidList; int numTids; bool bBackward; @@ -328,15 +342,10 @@ TidNext(TidScanState *node) if (node->tss_TidList == NULL) TidListEval(node); + scan = node->ss.ss_currentScanDesc; tidList = node->tss_TidList; numTids = node->tss_NumTids; - /* - * We use node->tss_htup as the tuple pointer; note this can't just be a - * local variable here, as the scan tuple slot will keep a pointer to it. - */ - tuple = &(node->tss_htup); - /* * Initialize or advance scan position, depending on direction. */ @@ -364,7 +373,7 @@ TidNext(TidScanState *node) while (node->tss_TidPtr >= 0 && node->tss_TidPtr < numTids) { - tuple->t_self = tidList[node->tss_TidPtr]; + ItemPointerData tid = tidList[node->tss_TidPtr]; /* * For WHERE CURRENT OF, the tuple retrieved from the cursor might @@ -372,30 +381,11 @@ TidNext(TidScanState *node) * current according to our snapshot. */ if (node->tss_isCurrentOf) - heap_get_latest_tid(heapRelation, snapshot, &tuple->t_self); - - if (heap_fetch(heapRelation, snapshot, tuple, &buffer, false, NULL)) - { - /* - * store the scanned tuple in the scan tuple slot of the scan - * state. Eventually we will only do this and not return a tuple. - * Note: we pass 'false' because tuples returned by amgetnext are - * pointers onto disk pages and were not created with palloc() and - * so should not be pfree()'d. - */ - ExecStoreTuple(tuple, /* tuple to store */ - slot, /* slot to store in */ - buffer, /* buffer associated with tuple */ - false); /* don't pfree */ - - /* - * At this point we have an extra pin on the buffer, because - * ExecStoreTuple incremented the pin count. Drop our local pin. - */ - ReleaseBuffer(buffer); + table_tuple_get_latest_tid(scan, &tid); + if (table_tuple_fetch_row_version(heapRelation, &tid, snapshot, slot)) return slot; - } + /* Bad TID or failed snapshot qual; try next */ if (bBackward) node->tss_TidPtr--; @@ -442,7 +432,7 @@ TidRecheck(TidScanState *node, TupleTableSlot *slot) * Initial States: * -- the relation indicated is opened for scanning so that the * "cursor" is positioned before the first qualifying tuple. - * -- tidPtr is -1. + * -- tss_TidPtr is -1. * ---------------------------------------------------------------- */ static TupleTableSlot * @@ -468,6 +458,10 @@ ExecReScanTidScan(TidScanState *node) node->tss_NumTids = 0; node->tss_TidPtr = -1; + /* not really necessary, but seems good form */ + if (node->ss.ss_currentScanDesc) + table_rescan(node->ss.ss_currentScanDesc, NULL); + ExecScanReScan(&node->ss); } @@ -481,6 +475,9 @@ ExecReScanTidScan(TidScanState *node) void ExecEndTidScan(TidScanState *node) { + if (node->ss.ss_currentScanDesc) + table_endscan(node->ss.ss_currentScanDesc); + /* * Free the exprcontext */ @@ -489,13 +486,9 @@ ExecEndTidScan(TidScanState *node) /* * clear out tuple table slots */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); - - /* - * close the heap relation. - */ - ExecCloseScanRelation(node->ss.ss_currentRelation); } /* ---------------------------------------------------------------- @@ -505,7 +498,7 @@ ExecEndTidScan(TidScanState *node) * scan keys, and opens the base and tid relations. * * Parameters: - * node: TidNode node produced by the planner. + * node: TidScan node produced by the planner. * estate: the execution state initialized in InitPlan. * ---------------------------------------------------------------- */ @@ -538,7 +531,7 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags) tidstate->tss_TidPtr = -1; /* - * open the base relation and acquire appropriate lock on it. + * open the scan relation */ currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, eflags); @@ -549,12 +542,13 @@ ExecInitTidScan(TidScan *node, EState *estate, int eflags) * get the scan type from the relation descriptor. */ ExecInitScanTupleSlot(estate, &tidstate->ss, - RelationGetDescr(currentRelation)); + RelationGetDescr(currentRelation), + table_slot_callbacks(currentRelation)); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &tidstate->ss.ps); + ExecInitResultTypeTL(&tidstate->ss.ps); ExecAssignScanProjectionInfo(&tidstate->ss); /* diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c index 05d65330a0e..c553f150b8d 100644 --- a/src/backend/executor/nodeUnique.c +++ b/src/backend/executor/nodeUnique.c @@ -11,7 +11,7 @@ * (It's debatable whether the savings justifies carrying two plan node * types, though.) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -141,7 +141,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) * Initialize result slot and type. Unique nodes do no projections, so * initialize projection info for this node appropriately. */ - ExecInitResultTupleSlotTL(estate, &uniquestate->ps); + ExecInitResultTupleSlotTL(&uniquestate->ps, &TTSOpsMinimalTuple); uniquestate->ps.ps_ProjInfo = NULL; /* @@ -152,6 +152,7 @@ ExecInitUnique(Unique *node, EState *estate, int eflags) node->numCols, node->uniqColIdx, node->uniqOperators, + node->uniqCollations, &uniquestate->ps); return uniquestate; diff --git a/src/backend/executor/nodeValuesscan.c b/src/backend/executor/nodeValuesscan.c index 6ec087b9688..0069a73588a 100644 --- a/src/backend/executor/nodeValuesscan.c +++ b/src/backend/executor/nodeValuesscan.c @@ -4,7 +4,7 @@ * Support routines for scanning Values lists * ("VALUES (...), (...), ..." in rangetable). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -131,8 +131,8 @@ ValuesNext(ValuesScanState *node) node->ss.ps.subPlan = NIL; /* - * As the expressions are only ever used once, disable JIT for - * them. This is worthwhile because it's common to insert significant + * As the expressions are only ever used once, disable JIT for them. + * This is worthwhile because it's common to insert significant * amounts of data via VALUES(). */ saved_jit_flags = econtext->ecxt_estate->es_jit_flags; @@ -261,12 +261,12 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags) * Get info about values list, initialize scan slot with it. */ tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists)); - ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc); + ExecInitScanTupleSlot(estate, &scanstate->ss, tupdesc, &TTSOpsVirtual); /* - * Initialize result slot, type and projection. + * Initialize result type and projection. */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); + ExecInitResultTypeTL(&scanstate->ss.ps); ExecAssignScanProjectionInfo(&scanstate->ss); /* @@ -312,7 +312,8 @@ ExecEndValuesScan(ValuesScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); } @@ -325,7 +326,8 @@ ExecEndValuesScan(ValuesScanState *node) void ExecReScanValuesScan(ValuesScanState *node) { - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index fe5369a0c7b..b5d3f3c4219 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -23,7 +23,7 @@ * aggregate function over all rows in the current row's window frame. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -41,11 +41,12 @@ #include "executor/nodeWindowAgg.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "parser/parse_agg.h" #include "parser/parse_coerce.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/expandeddatum.h" #include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -93,7 +94,7 @@ typedef struct WindowStatePerFuncData bool resulttypeByVal; bool plain_agg; /* is it just a plain aggregate function? */ - int aggno; /* if so, index of its PerAggData */ + int aggno; /* if so, index of its WindowStatePerAggData */ WindowObject winobj; /* object used in window function API */ } WindowStatePerFuncData; @@ -142,7 +143,7 @@ typedef struct WindowStatePerAggData resulttypeByVal, transtypeByVal; - int wfuncno; /* index of associated PerFuncData */ + int wfuncno; /* index of associated WindowStatePerFuncData */ /* Context holding transition value and possibly other subsidiary data */ MemoryContext aggcontext; /* may be private, or winstate->aggcontext */ @@ -158,43 +159,43 @@ typedef struct WindowStatePerAggData } WindowStatePerAggData; static void initialize_windowaggregate(WindowAggState *winstate, - WindowStatePerFunc perfuncstate, - WindowStatePerAgg peraggstate); + WindowStatePerFunc perfuncstate, + WindowStatePerAgg peraggstate); static void advance_windowaggregate(WindowAggState *winstate, - WindowStatePerFunc perfuncstate, - WindowStatePerAgg peraggstate); + WindowStatePerFunc perfuncstate, + WindowStatePerAgg peraggstate); static bool advance_windowaggregate_base(WindowAggState *winstate, - WindowStatePerFunc perfuncstate, - WindowStatePerAgg peraggstate); + WindowStatePerFunc perfuncstate, + WindowStatePerAgg peraggstate); static void finalize_windowaggregate(WindowAggState *winstate, - WindowStatePerFunc perfuncstate, - WindowStatePerAgg peraggstate, - Datum *result, bool *isnull); + WindowStatePerFunc perfuncstate, + WindowStatePerAgg peraggstate, + Datum *result, bool *isnull); static void eval_windowaggregates(WindowAggState *winstate); static void eval_windowfunction(WindowAggState *winstate, - WindowStatePerFunc perfuncstate, - Datum *result, bool *isnull); + WindowStatePerFunc perfuncstate, + Datum *result, bool *isnull); static void begin_partition(WindowAggState *winstate); static void spool_tuples(WindowAggState *winstate, int64 pos); static void release_partition(WindowAggState *winstate); -static int row_is_in_frame(WindowAggState *winstate, int64 pos, - TupleTableSlot *slot); +static int row_is_in_frame(WindowAggState *winstate, int64 pos, + TupleTableSlot *slot); static void update_frameheadpos(WindowAggState *winstate); static void update_frametailpos(WindowAggState *winstate); static void update_grouptailpos(WindowAggState *winstate); static WindowStatePerAggData *initialize_peragg(WindowAggState *winstate, - WindowFunc *wfunc, - WindowStatePerAgg peraggstate); + WindowFunc *wfunc, + WindowStatePerAgg peraggstate); static Datum GetAggInitVal(Datum textInitVal, Oid transtype); static bool are_peers(WindowAggState *winstate, TupleTableSlot *slot1, - TupleTableSlot *slot2); + TupleTableSlot *slot2); static bool window_gettupleslot(WindowObject winobj, int64 pos, - TupleTableSlot *slot); + TupleTableSlot *slot); /* @@ -241,10 +242,9 @@ advance_windowaggregate(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate) { + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); WindowFuncExprState *wfuncstate = perfuncstate->wfuncstate; int numArguments = perfuncstate->numArguments; - FunctionCallInfoData fcinfodata; - FunctionCallInfo fcinfo = &fcinfodata; Datum newVal; ListCell *arg; int i; @@ -273,8 +273,8 @@ advance_windowaggregate(WindowAggState *winstate, { ExprState *argstate = (ExprState *) lfirst(arg); - fcinfo->arg[i] = ExecEvalExpr(argstate, econtext, - &fcinfo->argnull[i]); + fcinfo->args[i].value = ExecEvalExpr(argstate, econtext, + &fcinfo->args[i].isnull); i++; } @@ -287,7 +287,7 @@ advance_windowaggregate(WindowAggState *winstate, */ for (i = 1; i <= numArguments; i++) { - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) { MemoryContextSwitchTo(oldContext); return; @@ -306,7 +306,7 @@ advance_windowaggregate(WindowAggState *winstate, if (peraggstate->transValueCount == 0 && peraggstate->transValueIsNull) { MemoryContextSwitchTo(peraggstate->aggcontext); - peraggstate->transValue = datumCopy(fcinfo->arg[1], + peraggstate->transValue = datumCopy(fcinfo->args[1].value, peraggstate->transtypeByVal, peraggstate->transtypeLen); peraggstate->transValueIsNull = false; @@ -339,8 +339,8 @@ advance_windowaggregate(WindowAggState *winstate, numArguments + 1, perfuncstate->winCollation, (void *) winstate, NULL); - fcinfo->arg[0] = peraggstate->transValue; - fcinfo->argnull[0] = peraggstate->transValueIsNull; + fcinfo->args[0].value = peraggstate->transValue; + fcinfo->args[0].isnull = peraggstate->transValueIsNull; winstate->curaggcontext = peraggstate->aggcontext; newVal = FunctionCallInvoke(fcinfo); winstate->curaggcontext = NULL; @@ -418,10 +418,9 @@ advance_windowaggregate_base(WindowAggState *winstate, WindowStatePerFunc perfuncstate, WindowStatePerAgg peraggstate) { + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); WindowFuncExprState *wfuncstate = perfuncstate->wfuncstate; int numArguments = perfuncstate->numArguments; - FunctionCallInfoData fcinfodata; - FunctionCallInfo fcinfo = &fcinfodata; Datum newVal; ListCell *arg; int i; @@ -450,8 +449,8 @@ advance_windowaggregate_base(WindowAggState *winstate, { ExprState *argstate = (ExprState *) lfirst(arg); - fcinfo->arg[i] = ExecEvalExpr(argstate, econtext, - &fcinfo->argnull[i]); + fcinfo->args[i].value = ExecEvalExpr(argstate, econtext, + &fcinfo->args[i].isnull); i++; } @@ -464,7 +463,7 @@ advance_windowaggregate_base(WindowAggState *winstate, */ for (i = 1; i <= numArguments; i++) { - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) { MemoryContextSwitchTo(oldContext); return true; @@ -510,8 +509,8 @@ advance_windowaggregate_base(WindowAggState *winstate, numArguments + 1, perfuncstate->winCollation, (void *) winstate, NULL); - fcinfo->arg[0] = peraggstate->transValue; - fcinfo->argnull[0] = peraggstate->transValueIsNull; + fcinfo->args[0].value = peraggstate->transValue; + fcinfo->args[0].isnull = peraggstate->transValueIsNull; winstate->curaggcontext = peraggstate->aggcontext; newVal = FunctionCallInvoke(fcinfo); winstate->curaggcontext = NULL; @@ -591,30 +590,31 @@ finalize_windowaggregate(WindowAggState *winstate, */ if (OidIsValid(peraggstate->finalfn_oid)) { + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); int numFinalArgs = peraggstate->numFinalArgs; - FunctionCallInfoData fcinfo; bool anynull; int i; - InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), + InitFunctionCallInfoData(fcinfodata.fcinfo, &(peraggstate->finalfn), numFinalArgs, perfuncstate->winCollation, (void *) winstate, NULL); - fcinfo.arg[0] = MakeExpandedObjectReadOnly(peraggstate->transValue, - peraggstate->transValueIsNull, - peraggstate->transtypeLen); - fcinfo.argnull[0] = peraggstate->transValueIsNull; + fcinfo->args[0].value = + MakeExpandedObjectReadOnly(peraggstate->transValue, + peraggstate->transValueIsNull, + peraggstate->transtypeLen); + fcinfo->args[0].isnull = peraggstate->transValueIsNull; anynull = peraggstate->transValueIsNull; /* Fill any remaining argument positions with nulls */ for (i = 1; i < numFinalArgs; i++) { - fcinfo.arg[i] = (Datum) 0; - fcinfo.argnull[i] = true; + fcinfo->args[i].value = (Datum) 0; + fcinfo->args[i].isnull = true; anynull = true; } - if (fcinfo.flinfo->fn_strict && anynull) + if (fcinfo->flinfo->fn_strict && anynull) { /* don't call a strict function with NULL inputs */ *result = (Datum) 0; @@ -623,9 +623,9 @@ finalize_windowaggregate(WindowAggState *winstate, else { winstate->curaggcontext = peraggstate->aggcontext; - *result = FunctionCallInvoke(&fcinfo); + *result = FunctionCallInvoke(fcinfo); winstate->curaggcontext = NULL; - *isnull = fcinfo.isnull; + *isnull = fcinfo->isnull; } } else @@ -1032,7 +1032,7 @@ static void eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, Datum *result, bool *isnull) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); MemoryContext oldContext; oldContext = MemoryContextSwitchTo(winstate->ss.ps.ps_ExprContext->ecxt_per_tuple_memory); @@ -1043,24 +1043,25 @@ eval_windowfunction(WindowAggState *winstate, WindowStatePerFunc perfuncstate, * implementations to support varying numbers of arguments. The real info * goes through the WindowObject, which is passed via fcinfo->context. */ - InitFunctionCallInfoData(fcinfo, &(perfuncstate->flinfo), + InitFunctionCallInfoData(*fcinfo, &(perfuncstate->flinfo), perfuncstate->numArguments, perfuncstate->winCollation, (void *) perfuncstate->winobj, NULL); /* Just in case, make all the regular argument slots be null */ - memset(fcinfo.argnull, true, perfuncstate->numArguments); + for (int argno = 0; argno < perfuncstate->numArguments; argno++) + fcinfo->args[argno].isnull = true; /* Window functions don't have a current aggregate context, either */ winstate->curaggcontext = NULL; - *result = FunctionCallInvoke(&fcinfo); - *isnull = fcinfo.isnull; + *result = FunctionCallInvoke(fcinfo); + *isnull = fcinfo->isnull; /* * Make sure pass-by-ref data is allocated in the appropriate context. (We * need this in case the function returns a pointer into some short-lived * tuple, as is entirely possible.) */ - if (!perfuncstate->resulttypeByVal && !fcinfo.isnull && + if (!perfuncstate->resulttypeByVal && !fcinfo->isnull && !MemoryContextContains(CurrentMemoryContext, DatumGetPointer(*result))) *result = datumCopy(*result, @@ -1079,6 +1080,7 @@ begin_partition(WindowAggState *winstate) { WindowAgg *node = (WindowAgg *) winstate->ss.ps.plan; PlanState *outerPlan = outerPlanState(winstate); + int frameOptions = winstate->frameOptions; int numfuncs = winstate->numfuncs; int i; @@ -1143,8 +1145,8 @@ begin_partition(WindowAggState *winstate) * If the frame head is potentially movable, or we have an EXCLUSION * clause, we might need to restart aggregation ... */ - if (!(winstate->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) || - (winstate->frameOptions & FRAMEOPTION_EXCLUSION)) + if (!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING) || + (frameOptions & FRAMEOPTION_EXCLUSION)) { /* ... so create a mark pointer to track the frame head */ agg_winobj->markptr = tuplestore_alloc_read_pointer(winstate->buffer, 0); @@ -1182,21 +1184,24 @@ begin_partition(WindowAggState *winstate) /* * If we are in RANGE or GROUPS mode, then determining frame boundaries - * requires physical access to the frame endpoint rows, except in + * requires physical access to the frame endpoint rows, except in certain * degenerate cases. We create read pointers to point to those rows, to * simplify access and ensure that the tuplestore doesn't discard the - * endpoint rows prematurely. (Must match logic in update_frameheadpos - * and update_frametailpos.) + * endpoint rows prematurely. (Must create pointers in exactly the same + * cases that update_frameheadpos and update_frametailpos need them.) */ winstate->framehead_ptr = winstate->frametail_ptr = -1; /* if not used */ - if ((winstate->frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) && - node->ordNumCols != 0) + if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) { - if (!(winstate->frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)) + if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && + node->ordNumCols != 0) || + (frameOptions & FRAMEOPTION_START_OFFSET)) winstate->framehead_ptr = tuplestore_alloc_read_pointer(winstate->buffer, 0); - if (!(winstate->frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)) + if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && + node->ordNumCols != 0) || + (frameOptions & FRAMEOPTION_END_OFFSET)) winstate->frametail_ptr = tuplestore_alloc_read_pointer(winstate->buffer, 0); } @@ -1210,8 +1215,8 @@ begin_partition(WindowAggState *winstate) */ winstate->grouptail_ptr = -1; - if ((winstate->frameOptions & (FRAMEOPTION_EXCLUDE_GROUP | - FRAMEOPTION_EXCLUDE_TIES)) && + if ((frameOptions & (FRAMEOPTION_EXCLUDE_GROUP | + FRAMEOPTION_EXCLUDE_TIES)) && node->ordNumCols != 0) { winstate->grouptail_ptr = @@ -1563,6 +1568,9 @@ update_frameheadpos(WindowAggState *winstate) bool sub, less; + /* We must have an ordering column */ + Assert(node->ordNumCols == 1); + /* Precompute flags for in_range checks */ if (frameOptions & FRAMEOPTION_START_OFFSET_PRECEDING) sub = true; /* subtract startOffset from current row */ @@ -1814,6 +1822,9 @@ update_frametailpos(WindowAggState *winstate) bool sub, less; + /* We must have an ordering column */ + Assert(node->ordNumCols == 1); + /* Precompute flags for in_range checks */ if (frameOptions & FRAMEOPTION_END_OFFSET_PRECEDING) sub = true; /* subtract endOffset from current row */ @@ -2056,7 +2067,7 @@ ExecWindowAgg(PlanState *pstate) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("frame starting offset must not be negative"))); } } @@ -2081,7 +2092,7 @@ ExecWindowAgg(PlanState *pstate) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("frame ending offset must not be negative"))); } } @@ -2306,35 +2317,51 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) * initialize source tuple type (which is also the tuple type that we'll * store in the tuplestore and use in all our working slots). */ - ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss); + ExecCreateScanSlotFromOuterPlan(estate, &winstate->ss, &TTSOpsMinimalTuple); scanDesc = winstate->ss.ss_ScanTupleSlot->tts_tupleDescriptor; + /* the outer tuple isn't the child's tuple, but always a minimal tuple */ + winstate->ss.ps.outeropsset = true; + winstate->ss.ps.outerops = &TTSOpsMinimalTuple; + winstate->ss.ps.outeropsfixed = true; + /* * tuple table initialization */ - winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc); - winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc); - winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc); - winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc); + winstate->first_part_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + winstate->agg_row_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + winstate->temp_slot_1 = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + winstate->temp_slot_2 = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); /* - * create frame head and tail slots only if needed (must match logic in - * update_frameheadpos and update_frametailpos) + * create frame head and tail slots only if needed (must create slots in + * exactly the same cases that update_frameheadpos and update_frametailpos + * need them) */ winstate->framehead_slot = winstate->frametail_slot = NULL; if (frameOptions & (FRAMEOPTION_RANGE | FRAMEOPTION_GROUPS)) { - if (!(frameOptions & FRAMEOPTION_START_UNBOUNDED_PRECEDING)) - winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc); - if (!(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)) - winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc); + if (((frameOptions & FRAMEOPTION_START_CURRENT_ROW) && + node->ordNumCols != 0) || + (frameOptions & FRAMEOPTION_START_OFFSET)) + winstate->framehead_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); + if (((frameOptions & FRAMEOPTION_END_CURRENT_ROW) && + node->ordNumCols != 0) || + (frameOptions & FRAMEOPTION_END_OFFSET)) + winstate->frametail_slot = ExecInitExtraTupleSlot(estate, scanDesc, + &TTSOpsMinimalTuple); } /* * Initialize result slot, type and projection. */ - ExecInitResultTupleSlotTL(estate, &winstate->ss.ps); + ExecInitResultTupleSlotTL(&winstate->ss.ps, &TTSOpsVirtual); ExecAssignProjectionInfo(&winstate->ss.ps, NULL); /* Set up data for comparing tuples */ @@ -2344,6 +2371,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) node->partNumCols, node->partColIdx, node->partOperators, + node->partCollations, &winstate->ss.ps); if (node->ordNumCols > 0) @@ -2352,6 +2380,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) node->ordNumCols, node->ordColIdx, node->ordOperators, + node->ordCollations, &winstate->ss.ps); /* diff --git a/src/backend/executor/nodeWorktablescan.c b/src/backend/executor/nodeWorktablescan.c index 2ff9a215b12..c85a9360be4 100644 --- a/src/backend/executor/nodeWorktablescan.c +++ b/src/backend/executor/nodeWorktablescan.c @@ -3,7 +3,7 @@ * nodeWorktablescan.c * routines to handle WorkTableScan nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -159,8 +159,13 @@ ExecInitWorkTableScan(WorkTableScan *node, EState *estate, int eflags) /* * tuple table initialization */ - ExecInitResultTupleSlotTL(estate, &scanstate->ss.ps); - ExecInitScanTupleSlot(estate, &scanstate->ss, NULL); + ExecInitResultTypeTL(&scanstate->ss.ps); + + /* signal that return type is not yet known */ + scanstate->ss.ps.resultopsset = true; + scanstate->ss.ps.resultopsfixed = false; + + ExecInitScanTupleSlot(estate, &scanstate->ss, NULL, &TTSOpsMinimalTuple); /* * initialize child expressions @@ -193,7 +198,8 @@ ExecEndWorkTableScan(WorkTableScanState *node) /* * clean out the tuple table */ - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecClearTuple(node->ss.ss_ScanTupleSlot); } @@ -206,7 +212,8 @@ ExecEndWorkTableScan(WorkTableScanState *node) void ExecReScanWorkTableScan(WorkTableScanState *node) { - ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); + if (node->ss.ps.ps_ResultTupleSlot) + ExecClearTuple(node->ss.ps.ps_ResultTupleSlot); ExecScanReScan(&node->ss); diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index a49015e7cbc..2c0ae395ba6 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -3,7 +3,7 @@ * spi.c * Server Programming Interface * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -36,10 +36,15 @@ #include "utils/typcache.h" +/* + * These global variables are part of the API for various SPI functions + * (a horrible API choice, but it's too late now). To reduce the risk of + * interference between different SPI callers, we save and restore them + * when entering/exiting a SPI nesting level. + */ uint64 SPI_processed = 0; -Oid SPI_lastoid = InvalidOid; SPITupleTable *SPI_tuptable = NULL; -int SPI_result; +int SPI_result = 0; static _SPI_connection *_SPI_stack = NULL; static _SPI_connection *_SPI_current = NULL; @@ -47,26 +52,26 @@ static int _SPI_stack_depth = 0; /* allocated size of _SPI_stack */ static int _SPI_connected = -1; /* current stack index */ static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, - ParamListInfo paramLI, bool read_only); + ParamListInfo paramLI, bool read_only); static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan); static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan); -static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, - Snapshot snapshot, Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, uint64 tcount); +static int _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, + Snapshot snapshot, Snapshot crosscheck_snapshot, + bool read_only, bool fire_triggers, uint64 tcount); static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes, - Datum *Values, const char *Nulls); + Datum *Values, const char *Nulls); static int _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount); static void _SPI_error_callback(void *arg); static void _SPI_cursor_operation(Portal portal, - FetchDirection direction, long count, - DestReceiver *dest); + FetchDirection direction, long count, + DestReceiver *dest); static SPIPlanPtr _SPI_make_plan_non_temp(SPIPlanPtr plan); static SPIPlanPtr _SPI_save_plan(SPIPlanPtr plan); @@ -122,7 +127,6 @@ SPI_connect_ext(int options) _SPI_current = &(_SPI_stack[_SPI_connected]); _SPI_current->processed = 0; - _SPI_current->lastoid = InvalidOid; _SPI_current->tuptable = NULL; _SPI_current->execSubid = InvalidSubTransactionId; slist_init(&_SPI_current->tuptables); @@ -132,6 +136,9 @@ SPI_connect_ext(int options) _SPI_current->queryEnv = NULL; _SPI_current->atomic = (options & SPI_OPT_NONATOMIC ? false : true); _SPI_current->internal_xact = false; + _SPI_current->outer_processed = SPI_processed; + _SPI_current->outer_tuptable = SPI_tuptable; + _SPI_current->outer_result = SPI_result; /* * Create memory contexts for this procedure @@ -154,6 +161,14 @@ SPI_connect_ext(int options) /* ... and switch to procedure's context */ _SPI_current->savedcxt = MemoryContextSwitchTo(_SPI_current->procCxt); + /* + * Reset API global variables so that current caller cannot accidentally + * depend on state of an outer caller. + */ + SPI_processed = 0; + SPI_tuptable = NULL; + SPI_result = 0; + return SPI_OK_CONNECT; } @@ -176,12 +191,12 @@ SPI_finish(void) _SPI_current->procCxt = NULL; /* - * Reset result variables, especially SPI_tuptable which is probably + * Restore outer API variables, especially SPI_tuptable which is probably * pointing at a just-deleted tuptable */ - SPI_processed = 0; - SPI_lastoid = InvalidOid; - SPI_tuptable = NULL; + SPI_processed = _SPI_current->outer_processed; + SPI_tuptable = _SPI_current->outer_tuptable; + SPI_result = _SPI_current->outer_result; /* Exit stack level */ _SPI_connected--; @@ -202,8 +217,8 @@ SPI_start_transaction(void) MemoryContextSwitchTo(oldcontext); } -void -SPI_commit(void) +static void +_SPI_commit(bool chain) { MemoryContext oldcontext = CurrentMemoryContext; @@ -226,18 +241,53 @@ SPI_commit(void) (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), errmsg("cannot commit while a subtransaction is active"))); + /* + * Hold any pinned portals that any PLs might be using. We have to do + * this before changing transaction state, since this will run + * user-defined code that might throw an error. + */ + HoldPinnedPortals(); + + /* Start the actual commit */ _SPI_current->internal_xact = true; - if (ActiveSnapshotSet()) + /* + * Before committing, pop all active snapshots to avoid error about + * "snapshot %p still active". + */ + while (ActiveSnapshotSet()) PopActiveSnapshot(); + + if (chain) + SaveTransactionCharacteristics(); + CommitTransactionCommand(); + + if (chain) + { + StartTransactionCommand(); + RestoreTransactionCharacteristics(); + } + MemoryContextSwitchTo(oldcontext); _SPI_current->internal_xact = false; } void -SPI_rollback(void) +SPI_commit(void) +{ + _SPI_commit(false); +} + +void +SPI_commit_and_chain(void) +{ + _SPI_commit(true); +} + +static void +_SPI_rollback(bool chain) { MemoryContext oldcontext = CurrentMemoryContext; @@ -252,43 +302,77 @@ SPI_rollback(void) (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), errmsg("cannot roll back while a subtransaction is active"))); + /* + * Hold any pinned portals that any PLs might be using. We have to do + * this before changing transaction state, since this will run + * user-defined code that might throw an error, and in any case couldn't + * be run in an already-aborted transaction. + */ + HoldPinnedPortals(); + + /* Start the actual rollback */ _SPI_current->internal_xact = true; + if (chain) + SaveTransactionCharacteristics(); + AbortCurrentTransaction(); + + if (chain) + { + StartTransactionCommand(); + RestoreTransactionCharacteristics(); + } + MemoryContextSwitchTo(oldcontext); _SPI_current->internal_xact = false; } +void +SPI_rollback(void) +{ + _SPI_rollback(false); +} + +void +SPI_rollback_and_chain(void) +{ + _SPI_rollback(true); +} + +/* + * Clean up SPI state. Called on transaction end (of non-SPI-internal + * transactions) and when returning to the main loop on error. + */ +void +SPICleanup(void) +{ + _SPI_current = NULL; + _SPI_connected = -1; + /* Reset API global variables, too */ + SPI_processed = 0; + SPI_tuptable = NULL; + SPI_result = 0; +} + /* * Clean up SPI state at transaction commit or abort. */ void AtEOXact_SPI(bool isCommit) { - /* - * Do nothing if the transaction end was initiated by SPI. - */ + /* Do nothing if the transaction end was initiated by SPI. */ if (_SPI_current && _SPI_current->internal_xact) return; - /* - * Note that memory contexts belonging to SPI stack entries will be freed - * automatically, so we can ignore them here. We just need to restore our - * static variables to initial state. - */ if (isCommit && _SPI_connected != -1) ereport(WARNING, (errcode(ERRCODE_WARNING), errmsg("transaction left non-empty SPI stack"), errhint("Check for missing \"SPI_finish\" calls."))); - _SPI_current = _SPI_stack = NULL; - _SPI_stack_depth = 0; - _SPI_connected = -1; - SPI_processed = 0; - SPI_lastoid = InvalidOid; - SPI_tuptable = NULL; + SPICleanup(); } /* @@ -329,18 +413,19 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid) } /* - * Pop the stack entry and reset global variables. Unlike + * Restore outer global variables and pop the stack entry. Unlike * SPI_finish(), we don't risk switching to memory contexts that might * be already gone. */ + SPI_processed = connection->outer_processed; + SPI_tuptable = connection->outer_tuptable; + SPI_result = connection->outer_result; + _SPI_connected--; if (_SPI_connected < 0) _SPI_current = NULL; else _SPI_current = &(_SPI_stack[_SPI_connected]); - SPI_processed = 0; - SPI_lastoid = InvalidOid; - SPI_tuptable = NULL; } if (found && isCommit) @@ -392,6 +477,19 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid) } } +/* + * Are we executing inside a procedure (that is, a nonatomic SPI context)? + */ +bool +SPI_inside_nonatomic_context(void) +{ + if (_SPI_current == NULL) + return false; /* not in any SPI context at all */ + if (_SPI_current->atomic) + return false; /* it's atomic (ie function not procedure) */ + return true; +} + /* Parse, plan, and execute a query string */ int @@ -834,8 +932,6 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum, mtuple->t_data->t_ctid = tuple->t_data->t_ctid; mtuple->t_self = tuple->t_self; mtuple->t_tableOid = tuple->t_tableOid; - if (rel->rd_att->tdhasoid) - HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple)); } else { @@ -855,7 +951,7 @@ int SPI_fnumber(TupleDesc tupdesc, const char *fname) { int res; - Form_pg_attribute sysatt; + const FormData_pg_attribute *sysatt; for (res = 0; res < tupdesc->natts; res++) { @@ -866,7 +962,7 @@ SPI_fnumber(TupleDesc tupdesc, const char *fname) return res + 1; } - sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ ); + sysatt = SystemAttributeByName(fname); if (sysatt != NULL) return sysatt->attnum; @@ -877,7 +973,7 @@ SPI_fnumber(TupleDesc tupdesc, const char *fname) char * SPI_fname(TupleDesc tupdesc, int fnumber) { - Form_pg_attribute att; + const FormData_pg_attribute *att; SPI_result = 0; @@ -891,7 +987,7 @@ SPI_fname(TupleDesc tupdesc, int fnumber) if (fnumber > 0) att = TupleDescAttr(tupdesc, fnumber - 1); else - att = SystemAttributeDefinition(fnumber, true); + att = SystemAttributeDefinition(fnumber); return pstrdup(NameStr(att->attname)); } @@ -921,7 +1017,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) if (fnumber > 0) typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid; else - typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; + typoid = (SystemAttributeDefinition(fnumber))->atttypid; getTypeOutputInfo(typoid, &foutoid, &typisvarlena); @@ -963,7 +1059,7 @@ SPI_gettype(TupleDesc tupdesc, int fnumber) if (fnumber > 0) typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid; else - typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; + typoid = (SystemAttributeDefinition(fnumber))->atttypid; typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid)); @@ -999,7 +1095,7 @@ SPI_gettypeid(TupleDesc tupdesc, int fnumber) if (fnumber > 0) return TupleDescAttr(tupdesc, fnumber - 1)->atttypid; else - return (SystemAttributeDefinition(fnumber, true))->atttypid; + return (SystemAttributeDefinition(fnumber))->atttypid; } char * @@ -1279,7 +1375,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, * throws an error. */ spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = (void *) plansource->query_string; + spierrcontext.arg = unconstify(char *, plansource->query_string); spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -1718,7 +1814,7 @@ SPI_plan_get_cached_plan(SPIPlanPtr plan) /* Setup error traceback support for ereport() */ spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = (void *) plansource->query_string; + spierrcontext.arg = unconstify(char *, plansource->query_string); spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -1776,8 +1872,9 @@ spi_dest_startup(DestReceiver *self, int operation, TupleDesc typeinfo) slist_push_head(&_SPI_current->tuptables, &tuptable->next); /* set up initial allocations */ - tuptable->alloced = tuptable->free = 128; + tuptable->alloced = 128; tuptable->vals = (HeapTuple *) palloc(tuptable->alloced * sizeof(HeapTuple)); + tuptable->numvals = 0; tuptable->tupdesc = CreateTupleDescCopy(typeinfo); MemoryContextSwitchTo(oldcxt); @@ -1803,18 +1900,18 @@ spi_printtup(TupleTableSlot *slot, DestReceiver *self) oldcxt = MemoryContextSwitchTo(tuptable->tuptabcxt); - if (tuptable->free == 0) + if (tuptable->numvals >= tuptable->alloced) { /* Double the size of the pointer array */ - tuptable->free = tuptable->alloced; - tuptable->alloced += tuptable->free; + uint64 newalloced = tuptable->alloced * 2; + tuptable->vals = (HeapTuple *) repalloc_huge(tuptable->vals, - tuptable->alloced * sizeof(HeapTuple)); + newalloced * sizeof(HeapTuple)); + tuptable->alloced = newalloced; } - tuptable->vals[tuptable->alloced - tuptable->free] = - ExecCopySlotTuple(slot); - (tuptable->free)--; + tuptable->vals[tuptable->numvals] = ExecCopySlotHeapTuple(slot); + (tuptable->numvals)++; MemoryContextSwitchTo(oldcxt); @@ -1849,7 +1946,7 @@ _SPI_prepare_plan(const char *src, SPIPlanPtr plan) * Setup error traceback support for ereport() */ spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = (void *) src; + spierrcontext.arg = unconstify(char *, src); spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -1954,7 +2051,7 @@ _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan) * Setup error traceback support for ereport() */ spierrcontext.callback = _SPI_error_callback; - spierrcontext.arg = (void *) src; + spierrcontext.arg = unconstify(char *, src); spierrcontext.previous = error_context_stack; error_context_stack = &spierrcontext; @@ -2007,7 +2104,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, { int my_res = 0; uint64 my_processed = 0; - Oid my_lastoid = InvalidOid; SPITupleTable *my_tuptable = NULL; int res = 0; bool pushed_active_snap = false; @@ -2066,7 +2162,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, List *stmt_list; ListCell *lc2; - spierrcontext.arg = (void *) plansource->query_string; + spierrcontext.arg = unconstify(char *, plansource->query_string); /* * If this is a one-shot plan, we still need to do parse analysis. @@ -2139,7 +2235,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, DestReceiver *dest; _SPI_current->processed = 0; - _SPI_current->lastoid = InvalidOid; _SPI_current->tuptable = NULL; if (stmt->utilityStmt) @@ -2230,8 +2325,7 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* Update "processed" if stmt returned tuples */ if (_SPI_current->tuptable) - _SPI_current->processed = _SPI_current->tuptable->alloced - - _SPI_current->tuptable->free; + _SPI_current->processed = _SPI_current->tuptable->numvals; res = SPI_OK_UTILITY; @@ -2275,12 +2369,11 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* * The last canSetTag query sets the status values returned to the * caller. Be careful to free any tuptables not returned, to - * avoid intratransaction memory leak. + * avoid intra-transaction memory leak. */ if (canSetTag) { my_processed = _SPI_current->processed; - my_lastoid = _SPI_current->lastoid; SPI_freetuptable(my_tuptable); my_tuptable = _SPI_current->tuptable; my_res = res; @@ -2328,7 +2421,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI, /* Save results for caller */ SPI_processed = my_processed; - SPI_lastoid = my_lastoid; SPI_tuptable = my_tuptable; /* tuptable now is caller's responsibility, not SPI's */ @@ -2356,20 +2448,9 @@ _SPI_convert_params(int nargs, Oid *argtypes, if (nargs > 0) { - int i; + paramLI = makeParamList(nargs); - paramLI = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) + - nargs * sizeof(ParamExternData)); - /* we have static list of params, so no hooks needed */ - paramLI->paramFetch = NULL; - paramLI->paramFetchArg = NULL; - paramLI->paramCompile = NULL; - paramLI->paramCompileArg = NULL; - paramLI->parserSetup = NULL; - paramLI->parserSetupArg = NULL; - paramLI->numParams = nargs; - - for (i = 0; i < nargs; i++) + for (int i = 0; i < nargs; i++) { ParamExternData *prm = ¶mLI->params[i]; @@ -2420,9 +2501,6 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount) else res = SPI_OK_UPDATE; break; - case CMD_MERGE: - res = SPI_OK_MERGE; - break; default: return SPI_ERROR_OPUNKNOWN; } @@ -2443,7 +2521,6 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount) ExecutorRun(queryDesc, ForwardScanDirection, tcount, true); _SPI_current->processed = queryDesc->estate->es_processed; - _SPI_current->lastoid = queryDesc->estate->es_lastoid; if ((res == SPI_OK_SELECT || queryDesc->plannedstmt->hasReturning) && queryDesc->dest->mydest == DestSPI) @@ -2526,7 +2603,7 @@ _SPI_cursor_operation(Portal portal, FetchDirection direction, long count, /* * Think not to combine this store with the preceding function call. If - * the portal contains calls to functions that use SPI, then SPI_stack is + * the portal contains calls to functions that use SPI, then _SPI_stack is * likely to move around while the portal runs. When control returns, * _SPI_current will point to the correct stack entry... but the pointer * may be different than it was beforehand. So we must be sure to re-fetch @@ -2617,7 +2694,7 @@ _SPI_checktuples(void) if (tuptable == NULL) /* spi_dest_startup was not called */ failed = true; - else if (processed != (tuptable->alloced - tuptable->free)) + else if (processed != tuptable->numvals) failed = true; return failed; @@ -2656,7 +2733,7 @@ _SPI_make_plan_non_temp(SPIPlanPtr plan) ALLOCSET_SMALL_SIZES); oldcxt = MemoryContextSwitchTo(plancxt); - /* Copy the SPI_plan struct and subsidiary data into the new context */ + /* Copy the _SPI_plan struct and subsidiary data into the new context */ newplan = (SPIPlanPtr) palloc0(sizeof(_SPI_plan)); newplan->magic = _SPI_PLAN_MAGIC; newplan->plancxt = plancxt; diff --git a/src/backend/executor/tqueue.c b/src/backend/executor/tqueue.c index ecdbe7f79f6..2b27b418501 100644 --- a/src/backend/executor/tqueue.c +++ b/src/backend/executor/tqueue.c @@ -8,7 +8,7 @@ * * A TupleQueueReader reads tuples from a shm_mq and returns the tuples. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -56,11 +56,15 @@ tqueueReceiveSlot(TupleTableSlot *slot, DestReceiver *self) TQueueDestReceiver *tqueue = (TQueueDestReceiver *) self; HeapTuple tuple; shm_mq_result result; + bool should_free; /* Send the tuple itself. */ - tuple = ExecMaterializeSlot(slot); + tuple = ExecFetchSlotHeapTuple(slot, true, &should_free); result = shm_mq_send(tqueue->queue, tuple->t_len, tuple->t_data, false); + if (should_free) + heap_freetuple(tuple); + /* Check for failure. */ if (result == SHM_MQ_DETACHED) return false; diff --git a/src/backend/executor/tstoreReceiver.c b/src/backend/executor/tstoreReceiver.c index d02ca3afd12..c0c81c82da0 100644 --- a/src/backend/executor/tstoreReceiver.c +++ b/src/backend/executor/tstoreReceiver.c @@ -9,7 +9,7 @@ * data even if the underlying table is dropped. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,7 +20,7 @@ #include "postgres.h" -#include "access/tuptoaster.h" +#include "access/detoast.h" #include "executor/tstoreReceiver.h" diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c index eac78a5d315..c917ec40ffa 100644 --- a/src/backend/foreign/foreign.c +++ b/src/backend/foreign/foreign.c @@ -3,7 +3,7 @@ * foreign.c * support for foreign-data wrappers, servers and user mappings. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/foreign/foreign.c @@ -33,6 +33,18 @@ */ ForeignDataWrapper * GetForeignDataWrapper(Oid fdwid) +{ + return GetForeignDataWrapperExtended(fdwid, 0); +} + + +/* + * GetForeignDataWrapperExtended - look up the foreign-data wrapper + * by OID. If flags uses FDW_MISSING_OK, return NULL if the object cannot + * be found instead of raising an error. + */ +ForeignDataWrapper * +GetForeignDataWrapperExtended(Oid fdwid, bits16 flags) { Form_pg_foreign_data_wrapper fdwform; ForeignDataWrapper *fdw; @@ -43,7 +55,11 @@ GetForeignDataWrapper(Oid fdwid) tp = SearchSysCache1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid)); if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid); + { + if ((flags & FDW_MISSING_OK) == 0) + elog(ERROR, "cache lookup failed for foreign-data wrapper %u", fdwid); + return NULL; + } fdwform = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp); @@ -91,6 +107,18 @@ GetForeignDataWrapperByName(const char *fdwname, bool missing_ok) */ ForeignServer * GetForeignServer(Oid serverid) +{ + return GetForeignServerExtended(serverid, 0); +} + + +/* + * GetForeignServerExtended - look up the foreign server definition. If + * flags uses FSV_MISSING_OK, return NULL if the object cannot be found + * instead of raising an error. + */ +ForeignServer * +GetForeignServerExtended(Oid serverid, bits16 flags) { Form_pg_foreign_server serverform; ForeignServer *server; @@ -101,7 +129,11 @@ GetForeignServer(Oid serverid) tp = SearchSysCache1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid)); if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for foreign server %u", serverid); + { + if ((flags & FSV_MISSING_OK) == 0) + elog(ERROR, "cache lookup failed for foreign server %u", serverid); + return NULL; + } serverform = (Form_pg_foreign_server) GETSTRUCT(tp); @@ -189,7 +221,7 @@ GetUserMapping(Oid userid, Oid serverid) MappingUserName(userid)))); um = (UserMapping *) palloc(sizeof(UserMapping)); - um->umid = HeapTupleGetOid(tp); + um->umid = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid; um->userid = userid; um->serverid = serverid; @@ -560,7 +592,7 @@ struct ConnectionOption * * The list is small - don't bother with bsearch if it stays so. */ -static struct ConnectionOption libpq_conninfo_options[] = { +static const struct ConnectionOption libpq_conninfo_options[] = { {"authtype", ForeignServerRelationId}, {"service", ForeignServerRelationId}, {"user", UserMappingRelationId}, @@ -587,7 +619,7 @@ static struct ConnectionOption libpq_conninfo_options[] = { static bool is_conninfo_option(const char *option, Oid context) { - struct ConnectionOption *opt; + const struct ConnectionOption *opt; for (opt = libpq_conninfo_options; opt->optname; opt++) if (context == opt->optcontext && strcmp(opt->optname, option) == 0) @@ -622,7 +654,7 @@ postgresql_fdw_validator(PG_FUNCTION_ARGS) if (!is_conninfo_option(def->defname, catalog)) { - struct ConnectionOption *opt; + const struct ConnectionOption *opt; StringInfoData buf; /* @@ -660,7 +692,9 @@ get_foreign_data_wrapper_oid(const char *fdwname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(fdwname)); + oid = GetSysCacheOid1(FOREIGNDATAWRAPPERNAME, + Anum_pg_foreign_data_wrapper_oid, + CStringGetDatum(fdwname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -681,7 +715,8 @@ get_foreign_server_oid(const char *servername, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(FOREIGNSERVERNAME, CStringGetDatum(servername)); + oid = GetSysCacheOid1(FOREIGNSERVERNAME, Anum_pg_foreign_server_oid, + CStringGetDatum(servername)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), diff --git a/src/backend/jit/README b/src/backend/jit/README index 6271677163a..e2fac8558e8 100644 --- a/src/backend/jit/README +++ b/src/backend/jit/README @@ -11,10 +11,10 @@ is possible to generate a function than can be natively executed by the CPU that just handles that expression, yielding a speedup. That this is done at query execution time, possibly even only in cases -the relevant task is done a number of times, makes it JIT, rather than -ahead-of-time (AOT). Given the way JIT compilation is used in -PostgreSQL, the lines between interpretation, AOT and JIT are somewhat -blurry. +where the relevant task is done a number of times, makes it JIT, +rather than ahead-of-time (AOT). Given the way JIT compilation is used +in PostgreSQL, the lines between interpretation, AOT and JIT are +somewhat blurry. Note that the interpreted program turned into a native program does not necessarily have to be a program in the classical sense. E.g. it diff --git a/src/backend/jit/jit.c b/src/backend/jit/jit.c index c1703094db7..43e65b1a543 100644 --- a/src/backend/jit/jit.c +++ b/src/backend/jit/jit.c @@ -8,7 +8,7 @@ * should end up here. * * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/jit.c @@ -33,7 +33,7 @@ /* GUCs */ bool jit_enabled = true; -char *jit_provider = "llvmjit"; +char *jit_provider = NULL; bool jit_debugging_support = false; bool jit_dump_bitcode = false; bool jit_expressions = true; @@ -182,6 +182,17 @@ jit_compile_expr(struct ExprState *state) return false; } +/* Aggregate JIT instrumentation information */ +void +InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add) +{ + dst->created_functions += add->created_functions; + INSTR_TIME_ADD(dst->generation_counter, add->generation_counter); + INSTR_TIME_ADD(dst->inlining_counter, add->inlining_counter); + INSTR_TIME_ADD(dst->optimization_counter, add->optimization_counter); + INSTR_TIME_ADD(dst->emission_counter, add->emission_counter); +} + static bool file_exists(const char *name) { diff --git a/src/backend/jit/llvm/Makefile b/src/backend/jit/llvm/Makefile index e2db4cea65c..17ff0691f37 100644 --- a/src/backend/jit/llvm/Makefile +++ b/src/backend/jit/llvm/Makefile @@ -22,7 +22,7 @@ endif PGFILEDESC = "llvmjit - JIT using LLVM" NAME = llvmjit -# All files in this directy use LLVM. +# All files in this directory use LLVM. CFLAGS += $(LLVM_CFLAGS) CXXFLAGS += $(LLVM_CXXFLAGS) override CPPFLAGS := $(LLVM_CPPFLAGS) $(CPPFLAGS) diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c index daae964b1ce..82c4afb7011 100644 --- a/src/backend/jit/llvm/llvmjit.c +++ b/src/backend/jit/llvm/llvmjit.c @@ -3,7 +3,7 @@ * llvmjit.c * Core part of the LLVM JIT provider. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/jit/llvm/llvmjit.c @@ -28,12 +28,16 @@ #include #include #include +#include #include #include #include #include #include #include +#if LLVM_VERSION_MAJOR > 6 +#include +#endif /* Handle of a module emitted via ORC JIT */ @@ -49,6 +53,7 @@ LLVMTypeRef TypeSizeT; LLVMTypeRef TypeParamBool; LLVMTypeRef TypeStorageBool; LLVMTypeRef TypePGFunction; +LLVMTypeRef StructNullableDatum; LLVMTypeRef StructHeapTupleFieldsField3; LLVMTypeRef StructHeapTupleFields; LLVMTypeRef StructHeapTupleHeaderData; @@ -59,8 +64,10 @@ LLVMTypeRef StructItemPointerData; LLVMTypeRef StructBlockId; LLVMTypeRef StructFormPgAttribute; LLVMTypeRef StructTupleConstr; -LLVMTypeRef StructtupleDesc; +LLVMTypeRef StructTupleDescData; LLVMTypeRef StructTupleTableSlot; +LLVMTypeRef StructHeapTupleTableSlot; +LLVMTypeRef StructMinimalTupleTableSlot; LLVMTypeRef StructMemoryContextData; LLVMTypeRef StructPGFinfoRecord; LLVMTypeRef StructFmgrInfo; @@ -75,11 +82,11 @@ LLVMTypeRef StructAggStatePerTransData; LLVMValueRef AttributeTemplate; LLVMValueRef FuncStrlen; LLVMValueRef FuncVarsizeAny; -LLVMValueRef FuncSlotGetsomeattrs; +LLVMValueRef FuncSlotGetsomeattrsInt; LLVMValueRef FuncSlotGetmissingattrs; -LLVMValueRef FuncHeapGetsysattr; LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal; -LLVMValueRef FuncExecEvalArrayRefSubscript; +LLVMValueRef FuncExecEvalSubscriptingRef; +LLVMValueRef FuncExecEvalSysVar; LLVMValueRef FuncExecAggTransReparent; LLVMValueRef FuncExecAggInitGroup; @@ -220,7 +227,7 @@ llvm_expand_funcname(struct LLVMJitContext *context, const char *basename) { Assert(context->module != NULL); - context->base.created_functions++; + context->base.instr.created_functions++; /* * Previously we used dots to separate, but turns out some tools, e.g. @@ -394,7 +401,6 @@ llvm_function_reference(LLVMJitContext *context, LLVMSetGlobalConstant(v_fn, true); return LLVMBuildLoad(builder, v_fn, ""); - return v_fn; } /* check if function already has been added */ @@ -435,7 +441,7 @@ llvm_optimize_module(LLVMJitContext *context, LLVMModuleRef module) if (context->base.flags & PGJIT_OPT3) { - /* TODO: Unscientifically determined threshhold */ + /* TODO: Unscientifically determined threshold */ LLVMPassManagerBuilderUseInlinerWithThreshold(llvm_pmb, 512); } else @@ -501,7 +507,7 @@ llvm_compile_module(LLVMJitContext *context) INSTR_TIME_SET_CURRENT(starttime); llvm_inline(context->module); INSTR_TIME_SET_CURRENT(endtime); - INSTR_TIME_ACCUM_DIFF(context->base.inlining_counter, + INSTR_TIME_ACCUM_DIFF(context->base.instr.inlining_counter, endtime, starttime); } @@ -521,7 +527,7 @@ llvm_compile_module(LLVMJitContext *context) INSTR_TIME_SET_CURRENT(starttime); llvm_optimize_module(context, context->module); INSTR_TIME_SET_CURRENT(endtime); - INSTR_TIME_ACCUM_DIFF(context->base.optimization_counter, + INSTR_TIME_ACCUM_DIFF(context->base.instr.optimization_counter, endtime, starttime); if (jit_dump_bitcode) @@ -572,7 +578,7 @@ llvm_compile_module(LLVMJitContext *context) } #endif INSTR_TIME_SET_CURRENT(endtime); - INSTR_TIME_ACCUM_DIFF(context->base.emission_counter, + INSTR_TIME_ACCUM_DIFF(context->base.instr.emission_counter, endtime, starttime); context->module = NULL; @@ -593,9 +599,9 @@ llvm_compile_module(LLVMJitContext *context) ereport(DEBUG1, (errmsg("time to inline: %.3fs, opt: %.3fs, emit: %.3fs", - INSTR_TIME_GET_DOUBLE(context->base.inlining_counter), - INSTR_TIME_GET_DOUBLE(context->base.optimization_counter), - INSTR_TIME_GET_DOUBLE(context->base.emission_counter)), + INSTR_TIME_GET_DOUBLE(context->base.instr.inlining_counter), + INSTR_TIME_GET_DOUBLE(context->base.instr.optimization_counter), + INSTR_TIME_GET_DOUBLE(context->base.instr.emission_counter)), errhidestmt(true), errhidecontext(true))); } @@ -664,18 +670,22 @@ llvm_session_initialize(void) llvm_opt0_orc = LLVMOrcCreateInstance(llvm_opt0_targetmachine); llvm_opt3_orc = LLVMOrcCreateInstance(llvm_opt3_targetmachine); -#if defined(HAVE_DECL_LLVMORCREGISTERGDB) && HAVE_DECL_LLVMORCREGISTERGDB +#if defined(HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER) && HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER if (jit_debugging_support) { - LLVMOrcRegisterGDB(llvm_opt0_orc); - LLVMOrcRegisterGDB(llvm_opt3_orc); + LLVMJITEventListenerRef l = LLVMCreateGDBRegistrationListener(); + + LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l); + LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l); } #endif -#if defined(HAVE_DECL_LLVMORCREGISTERPERF) && HAVE_DECL_LLVMORCREGISTERPERF +#if defined(HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER) && HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER if (jit_profiling_support) { - LLVMOrcRegisterPerf(llvm_opt0_orc); - LLVMOrcRegisterPerf(llvm_opt3_orc); + LLVMJITEventListenerRef l = LLVMCreatePerfJITEventListener(); + + LLVMOrcRegisterJITEventListener(llvm_opt0_orc, l); + LLVMOrcRegisterJITEventListener(llvm_opt3_orc, l); } #endif @@ -798,14 +808,17 @@ llvm_create_types(void) TypeParamBool = load_return_type(mod, "FunctionReturningBool"); TypeStorageBool = load_type(mod, "TypeStorageBool"); TypePGFunction = load_type(mod, "TypePGFunction"); + StructNullableDatum = load_type(mod, "StructNullableDatum"); StructExprContext = load_type(mod, "StructExprContext"); StructExprEvalStep = load_type(mod, "StructExprEvalStep"); StructExprState = load_type(mod, "StructExprState"); StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData"); StructMemoryContextData = load_type(mod, "StructMemoryContextData"); StructTupleTableSlot = load_type(mod, "StructTupleTableSlot"); + StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot"); + StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot"); StructHeapTupleData = load_type(mod, "StructHeapTupleData"); - StructtupleDesc = load_type(mod, "StructtupleDesc"); + StructTupleDescData = load_type(mod, "StructTupleDescData"); StructAggState = load_type(mod, "StructAggState"); StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData"); StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData"); @@ -813,11 +826,11 @@ llvm_create_types(void) AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate"); FuncStrlen = LLVMGetNamedFunction(mod, "strlen"); FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any"); - FuncSlotGetsomeattrs = LLVMGetNamedFunction(mod, "slot_getsomeattrs"); + FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int"); FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs"); - FuncHeapGetsysattr = LLVMGetNamedFunction(mod, "heap_getsysattr"); FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal"); - FuncExecEvalArrayRefSubscript = LLVMGetNamedFunction(mod, "ExecEvalArrayRefSubscript"); + FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(mod, "ExecEvalSubscriptingRef"); + FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar"); FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent"); FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup"); @@ -846,7 +859,7 @@ llvm_split_symbol_name(const char *name, char **modname, char **funcname) { /* * Symbol names cannot contain a ., therefore we can split based on - * first and last occurance of one. + * first and last occurrence of one. */ *funcname = rindex(name, '.'); (*funcname)++; /* jump over . */ diff --git a/src/backend/jit/llvm/llvmjit_deform.c b/src/backend/jit/llvm/llvmjit_deform.c index 795f67114e6..835aea83e97 100644 --- a/src/backend/jit/llvm/llvmjit_deform.c +++ b/src/backend/jit/llvm/llvmjit_deform.c @@ -7,7 +7,7 @@ * knowledge of the tuple descriptor. Fixed column widths, NOT NULLness, etc * can be taken advantage of. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -31,7 +31,8 @@ * Create a function that deforms a tuple of type desc up to natts columns. */ LLVMValueRef -slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) +slot_compile_deform(LLVMJitContext *context, TupleDesc desc, + const TupleTableSlotOps *ops, int natts) { char *funcname; @@ -60,7 +61,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) LLVMValueRef v_tts_values; LLVMValueRef v_tts_nulls; LLVMValueRef v_slotoffp; - LLVMValueRef v_slowp; + LLVMValueRef v_flagsp; LLVMValueRef v_nvalidp; LLVMValueRef v_nvalid; LLVMValueRef v_maxatt; @@ -88,32 +89,41 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) int attnum; + /* virtual tuples never need deforming, so don't generate code */ + if (ops == &TTSOpsVirtual) + return NULL; + + /* decline to JIT for slot types we don't know to handle */ + if (ops != &TTSOpsHeapTuple && ops != &TTSOpsBufferHeapTuple && + ops != &TTSOpsMinimalTuple) + return NULL; + mod = llvm_mutable_module(context); funcname = llvm_expand_funcname(context, "deform"); /* - * Check which columns do have to exist, so we don't have to check the - * rows natts unnecessarily. + * Check which columns have to exist, so we don't have to check the row's + * natts unnecessarily. */ for (attnum = 0; attnum < desc->natts; attnum++) { Form_pg_attribute att = TupleDescAttr(desc, attnum); /* - * If the column is possibly missing, we can't rely on its (or - * subsequent) NOT NULL constraints to indicate minimum attributes in - * the tuple, so stop here. - */ - if (att->atthasmissing) - break; - - /* - * Column is NOT NULL and there've been no preceding missing columns, - * it's guaranteed that all columns up to here exist at least in the - * NULL bitmap. + * If the column is declared NOT NULL then it must be present in every + * tuple, unless there's a "missing" entry that could provide a + * non-NULL value for it. That in turn guarantees that the NULL bitmap + * - if there are any NULLable columns - is at least long enough to + * cover columns up to attnum. + * + * Be paranoid and also check !attisdropped, even though the + * combination of attisdropped && attnotnull combination shouldn't + * exist. */ - if (att->attnotnull) + if (att->attnotnull && + !att->atthasmissing && + !att->attisdropped) guaranteed_column_number = attnum; } @@ -166,14 +176,44 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) v_tts_nulls = l_load_struct_gep(b, v_slot, FIELDNO_TUPLETABLESLOT_ISNULL, "tts_ISNULL"); - - v_slotoffp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_OFF, ""); - v_slowp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_SLOW, ""); + v_flagsp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_FLAGS, ""); v_nvalidp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_NVALID, ""); - v_tupleheaderp = - l_load_struct_gep(b, v_slot, FIELDNO_TUPLETABLESLOT_TUPLE, - "tupleheader"); + if (ops == &TTSOpsHeapTuple || ops == &TTSOpsBufferHeapTuple) + { + LLVMValueRef v_heapslot; + + v_heapslot = + LLVMBuildBitCast(b, + v_slot, + l_ptr(StructHeapTupleTableSlot), + "heapslot"); + v_slotoffp = LLVMBuildStructGEP(b, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_OFF, ""); + v_tupleheaderp = + l_load_struct_gep(b, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_TUPLE, + "tupleheader"); + + } + else if (ops == &TTSOpsMinimalTuple) + { + LLVMValueRef v_minimalslot; + + v_minimalslot = + LLVMBuildBitCast(b, + v_slot, + l_ptr(StructMinimalTupleTableSlot), + "minimalslot"); + v_slotoffp = LLVMBuildStructGEP(b, v_minimalslot, FIELDNO_MINIMALTUPLETABLESLOT_OFF, ""); + v_tupleheaderp = + l_load_struct_gep(b, v_minimalslot, FIELDNO_MINIMALTUPLETABLESLOT_TUPLE, + "tupleheader"); + } + else + { + /* should've returned at the start of the function */ + pg_unreachable(); + } + v_tuplep = l_load_struct_gep(b, v_tupleheaderp, FIELDNO_HEAPTUPLEDATA_DATA, "tuple"); @@ -208,10 +248,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) v_infomask2, "maxatt"); + /* + * Need to zext, as getelementptr otherwise treats hoff as a signed 8bit + * integer, which'd yield a negative offset for t_hoff > 127. + */ v_hoff = - l_load_struct_gep(b, v_tuplep, - FIELDNO_HEAPTUPLEHEADERDATA_HOFF, - "t_hoff"); + LLVMBuildZExt(b, + l_load_struct_gep(b, v_tuplep, + FIELDNO_HEAPTUPLEHEADERDATA_HOFF, + ""), + LLVMInt32Type(), "t_hoff"); v_tupdata_base = LLVMBuildGEP(b, @@ -252,9 +298,12 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) } /* - * Check if's guaranteed the all the desired attributes are available in - * tuple. If so, we can start deforming. If not, need to make sure to - * fetch the missing columns. + * Check if it is guaranteed that all the desired attributes are available + * in the tuple (but still possibly NULL), by dint of either the last + * to-be-deformed column being NOT NULL, or subsequent ones not accessed + * here being NOT NULL. If that's not guaranteed the tuple headers natt's + * has to be checked, and missing attributes potentially have to be + * fetched (using slot_getmissingattrs(). */ if ((natts - 1) <= guaranteed_column_number) { @@ -304,7 +353,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) for (attnum = 0; attnum < natts; attnum++) { - LLVMValueRef v_attno = l_int32_const(attnum); + LLVMValueRef v_attno = l_int16_const(attnum); LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[attnum]); } @@ -337,7 +386,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) /* * If this is the first attribute, slot->tts_nvalid was 0. Therefore - * reset offset to 0 to, it be from a previous execution. + * also reset offset to 0, it may be from a previous execution. */ if (attnum == 0) { @@ -367,7 +416,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) /* * Check for nulls if necessary. No need to take missing attributes - * into account, because in case they're present the heaptuple's natts + * into account, because if they're present the heaptuple's natts * would have indicated that a slot_getmissingattrs() is needed. */ if (!att->attnotnull) @@ -454,13 +503,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) (known_alignment < 0 || known_alignment != TYPEALIGN(alignto, known_alignment))) { /* - * When accessing a varlena field we have to "peek" to see if we + * When accessing a varlena field, we have to "peek" to see if we * are looking at a pad byte or the first byte of a 1-byte-header * datum. A zero byte must be either a pad byte, or the first - * byte of a correctly aligned 4-byte length word; in either case + * byte of a correctly aligned 4-byte length word; in either case, * we can align safely. A non-zero byte must be either a 1-byte * length word, or the first byte of a correctly aligned 4-byte - * length word; in either case we need not align. + * length word; in either case, we need not align. */ if (att->attlen == -1) { @@ -554,8 +603,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) else if (att->attnotnull && attguaranteedalign && known_alignment >= 0) { /* - * If the offset to the column was previously known a NOT NULL & - * fixed width column guarantees that alignment is just the + * If the offset to the column was previously known, a NOT NULL & + * fixed-width column guarantees that alignment is just the * previous alignment plus column width. */ Assert(att->attlen > 0); @@ -596,8 +645,8 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1, "")); /* - * Store datum. For byval datums copy the value, extend to Datum's - * width, and store. For byref types, store pointer to data. + * Store datum. For byval: datums copy the value, extend to Datum's + * width, and store. For byref types: store pointer to data. */ if (att->attbyval) { @@ -690,11 +739,14 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc, int natts) { LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, ""); + LLVMValueRef v_flags; - LLVMBuildStore(b, l_int32_const(natts), v_nvalidp); + LLVMBuildStore(b, l_int16_const(natts), v_nvalidp); v_off = LLVMBuildTrunc(b, v_off, LLVMInt32Type(), ""); LLVMBuildStore(b, v_off, v_slotoffp); - LLVMBuildStore(b, l_int8_const(1), v_slowp); + v_flags = LLVMBuildLoad(b, v_flagsp, "tts_flags"); + v_flags = LLVMBuildOr(b, v_flags, l_int16_const(TTS_FLAG_SLOW), ""); + LLVMBuildStore(b, v_flags, v_flagsp); LLVMBuildRetVoid(b); } diff --git a/src/backend/jit/llvm/llvmjit_error.cpp b/src/backend/jit/llvm/llvmjit_error.cpp index a2bdfe3fb87..9c6e8026e73 100644 --- a/src/backend/jit/llvm/llvmjit_error.cpp +++ b/src/backend/jit/llvm/llvmjit_error.cpp @@ -6,10 +6,10 @@ * Unfortunately neither (re)setting the C++ new handler, nor the LLVM OOM * handler are exposed to C. Therefore this file wraps the necessary code. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION - * src/backend/jit/llvm/llvmjit_error.c + * src/backend/jit/llvm/llvmjit_error.cpp * *------------------------------------------------------------------------- */ diff --git a/src/backend/jit/llvm/llvmjit_expr.c b/src/backend/jit/llvm/llvmjit_expr.c index f37ff826c9b..d09324637b9 100644 --- a/src/backend/jit/llvm/llvmjit_expr.c +++ b/src/backend/jit/llvm/llvmjit_expr.c @@ -3,7 +3,7 @@ * llvmjit_expr.c * JIT compile expressions. * - * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -33,7 +33,6 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/planner.h" #include "parser/parse_coerce.h" #include "parser/parsetree.h" #include "pgstat.h" @@ -58,12 +57,12 @@ typedef struct CompiledExprState static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull); static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, - LLVMModuleRef mod, FunctionCallInfo fcinfo, - LLVMValueRef *v_fcinfo_isnull); + LLVMModuleRef mod, FunctionCallInfo fcinfo, + LLVMValueRef *v_fcinfo_isnull); static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, - const char *funcname, - LLVMValueRef v_state, LLVMValueRef v_econtext, - ExprEvalStep *op); + const char *funcname, + LLVMValueRef v_state, LLVMValueRef v_econtext, + ExprEvalStep *op); static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod); @@ -276,6 +275,8 @@ llvm_compile_expr(ExprState *state) LLVMValueRef v_slot; LLVMBasicBlockRef b_fetch; LLVMValueRef v_nvalid; + LLVMValueRef l_jit_deform = NULL; + const TupleTableSlotOps *tts_ops = NULL; b_fetch = l_bb_before_v(opblocks[i + 1], "op.%d.fetch", i); @@ -283,36 +284,18 @@ llvm_compile_expr(ExprState *state) if (op->d.fetch.known_desc) desc = op->d.fetch.known_desc; - if (opcode == EEOP_INNER_FETCHSOME) - { - PlanState *is = innerPlanState(parent); + if (op->d.fetch.fixed) + tts_ops = op->d.fetch.kind; - v_slot = v_innerslot; + /* step should not have been generated */ + Assert(tts_ops != &TTSOpsVirtual); - if (!desc && - is && - is->ps_ResultTupleSlot && - is->ps_ResultTupleSlot->tts_fixedTupleDescriptor) - desc = is->ps_ResultTupleSlot->tts_tupleDescriptor; - } + if (opcode == EEOP_INNER_FETCHSOME) + v_slot = v_innerslot; else if (opcode == EEOP_OUTER_FETCHSOME) - { - PlanState *os = outerPlanState(parent); - v_slot = v_outerslot; - - if (!desc && - os && - os->ps_ResultTupleSlot && - os->ps_ResultTupleSlot->tts_fixedTupleDescriptor) - desc = os->ps_ResultTupleSlot->tts_tupleDescriptor; - } else - { v_slot = v_scanslot; - if (!desc && parent) - desc = parent->scandesc; - } /* * Check if all required attributes are available, or @@ -324,7 +307,7 @@ llvm_compile_expr(ExprState *state) ""); LLVMBuildCondBr(b, LLVMBuildICmp(b, LLVMIntUGE, v_nvalid, - l_int32_const(op->d.fetch.last_var), + l_int16_const(op->d.fetch.last_var), ""), opblocks[i + 1], b_fetch); @@ -336,19 +319,22 @@ llvm_compile_expr(ExprState *state) * function specific to tupledesc and the exact number of * to-be-extracted attributes. */ - if (desc && (context->base.flags & PGJIT_DEFORM)) + if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM)) { - LLVMValueRef params[1]; - LLVMValueRef l_jit_deform; - l_jit_deform = slot_compile_deform(context, desc, + tts_ops, op->d.fetch.last_var); + } + + if (l_jit_deform) + { + LLVMValueRef params[1]; + params[0] = v_slot; LLVMBuildCall(b, l_jit_deform, params, lengthof(params), ""); - } else { @@ -358,7 +344,7 @@ llvm_compile_expr(ExprState *state) params[1] = l_int32_const(op->d.fetch.last_var); LLVMBuildCall(b, - llvm_get_decl(mod, FuncSlotGetsomeattrs), + llvm_get_decl(mod, FuncSlotGetsomeattrsInt), params, lengthof(params), ""); } @@ -406,13 +392,8 @@ llvm_compile_expr(ExprState *state) case EEOP_OUTER_SYSVAR: case EEOP_SCAN_SYSVAR: { - int attnum = op->d.var.attnum; - LLVMValueRef v_attnum; - LLVMValueRef v_tuple; - LLVMValueRef v_tupleDescriptor; - LLVMValueRef v_params[4]; - LLVMValueRef v_syscol; LLVMValueRef v_slot; + LLVMValueRef v_params[4]; if (opcode == EEOP_INNER_SYSVAR) v_slot = v_innerslot; @@ -421,31 +402,14 @@ llvm_compile_expr(ExprState *state) else v_slot = v_scanslot; - Assert(op->d.var.attnum < 0); - - v_tuple = l_load_struct_gep(b, v_slot, - FIELDNO_TUPLETABLESLOT_TUPLE, - "v.tuple"); + v_params[0] = v_state; + v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); + v_params[2] = v_econtext; + v_params[3] = v_slot; - /* - * Could optimize this a bit for fixed descriptors, but - * this shouldn't be that critical a path. - */ - v_tupleDescriptor = - l_load_struct_gep(b, v_slot, - FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR, - "v.tupledesc"); - v_attnum = l_int32_const(attnum); - - v_params[0] = v_tuple; - v_params[1] = v_attnum; - v_params[2] = v_tupleDescriptor; - v_params[3] = v_resnullp; - v_syscol = LLVMBuildCall(b, - llvm_get_decl(mod, FuncHeapGetsysattr), - v_params, lengthof(v_params), - ""); - LLVMBuildStore(b, v_syscol, v_resvaluep); + LLVMBuildCall(b, + llvm_get_decl(mod, FuncExecEvalSysVar), + v_params, lengthof(v_params), ""); LLVMBuildBr(b, opblocks[i + 1]); break; @@ -605,7 +569,6 @@ llvm_compile_expr(ExprState *state) LLVMBasicBlockRef b_nonull; int argno; LLVMValueRef v_fcinfo; - LLVMValueRef v_argnullp; LLVMBasicBlockRef *b_checkargnulls; /* @@ -622,12 +585,6 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - v_argnullp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - /* * set resnull to true, if the function is actually * called, it'll be reset @@ -659,8 +616,7 @@ llvm_compile_expr(ExprState *state) b_argnotnull = b_checkargnulls[argno + 1]; /* and finally load & check NULLness of arg */ - v_argisnull = l_load_struct_gep(b, v_argnullp, - argno, ""); + v_argisnull = l_funcnull(b, v_fcinfo, argno); LLVMBuildCondBr(b, LLVMBuildICmp(b, LLVMIntEQ, v_argisnull, @@ -672,7 +628,8 @@ llvm_compile_expr(ExprState *state) LLVMPositionBuilderAtEnd(b, b_nonull); } - /* explicit fallthrough */ + /* FALLTHROUGH */ + case EEOP_FUNCEXPR: { FunctionCallInfo fcinfo = op->d.func.fcinfo_data; @@ -709,8 +666,8 @@ llvm_compile_expr(ExprState *state) l_ptr(TypeStorageBool)); LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp); - /* intentionally fall through */ } + /* FALLTHROUGH */ /* * Treat them the same for now, optimizer can remove @@ -810,9 +767,8 @@ llvm_compile_expr(ExprState *state) v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull, l_ptr(TypeStorageBool)); LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp); - - /* intentionally fall through */ } + /* FALLTHROUGH */ /* * Treat them the same for now, optimizer can remove @@ -1188,20 +1144,20 @@ llvm_compile_expr(ExprState *state) break; } - case EEOP_ARRAYREF_OLD: - build_EvalXFunc(b, mod, "ExecEvalArrayRefOld", + case EEOP_SBSREF_OLD: + build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefOld", v_state, v_econtext, op); LLVMBuildBr(b, opblocks[i + 1]); break; - case EEOP_ARRAYREF_ASSIGN: - build_EvalXFunc(b, mod, "ExecEvalArrayRefAssign", + case EEOP_SBSREF_ASSIGN: + build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefAssign", v_state, v_econtext, op); LLVMBuildBr(b, opblocks[i + 1]); break; - case EEOP_ARRAYREF_FETCH: - build_EvalXFunc(b, mod, "ExecEvalArrayRefFetch", + case EEOP_SBSREF_FETCH: + build_EvalXFunc(b, mod, "ExecEvalSubscriptingRefFetch", v_state, v_econtext, op); LLVMBuildBr(b, opblocks[i + 1]); break; @@ -1311,10 +1267,6 @@ llvm_compile_expr(ExprState *state) LLVMValueRef v_fn_addr_out, v_fn_addr_in; LLVMValueRef v_fcinfo_in_isnullp; - LLVMValueRef v_in_argp, - v_out_argp; - LLVMValueRef v_in_argnullp, - v_out_argnullp; LLVMValueRef v_retval; LLVMValueRef v_resvalue; LLVMValueRef v_resnull; @@ -1348,22 +1300,6 @@ llvm_compile_expr(ExprState *state) LLVMBuildStructGEP(b, v_fcinfo_in, FIELDNO_FUNCTIONCALLINFODATA_ISNULL, "v_fcinfo_in_isnull"); - v_out_argnullp = - LLVMBuildStructGEP(b, v_fcinfo_out, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_fcinfo_out_argnullp"); - v_in_argnullp = - LLVMBuildStructGEP(b, v_fcinfo_in, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_fcinfo_in_argnullp"); - v_out_argp = - LLVMBuildStructGEP(b, v_fcinfo_out, - FIELDNO_FUNCTIONCALLINFODATA_ARG, - "v_fcinfo_out_argp"); - v_in_argp = - LLVMBuildStructGEP(b, v_fcinfo_in, - FIELDNO_FUNCTIONCALLINFODATA_ARG, - "v_fcinfo_in_argp"); /* output functions are not called on nulls */ v_resnull = LLVMBuildLoad(b, v_resnullp, ""); @@ -1383,11 +1319,10 @@ llvm_compile_expr(ExprState *state) /* set arg[0] */ LLVMBuildStore(b, v_resvalue, - LLVMBuildStructGEP(b, v_out_argp, 0, "")); + l_funcvaluep(b, v_fcinfo_out, 0)); LLVMBuildStore(b, l_sbool_const(0), - LLVMBuildStructGEP(b, v_out_argnullp, - 0, "")); + l_funcnullp(b, v_fcinfo_out, 0)); /* and call output function (can never return NULL) */ v_output = LLVMBuildCall(b, v_fn_addr_out, &v_fcinfo_out, 1, "funccall_coerce_out"); @@ -1434,9 +1369,9 @@ llvm_compile_expr(ExprState *state) /* set arguments */ /* arg0: output */ LLVMBuildStore(b, v_output, - LLVMBuildStructGEP(b, v_in_argp, 0, "")); + l_funcvaluep(b, v_fcinfo_in, 0)); LLVMBuildStore(b, v_resnull, - LLVMBuildStructGEP(b, v_in_argnullp, 0, "")); + l_funcnullp(b, v_fcinfo_in, 0)); /* arg1: ioparam: preset in execExpr.c */ /* arg2: typmod: preset in execExpr.c */ @@ -1461,7 +1396,6 @@ llvm_compile_expr(ExprState *state) LLVMValueRef v_fcinfo; LLVMValueRef v_fcinfo_isnull; - LLVMValueRef v_argnullp; LLVMValueRef v_argnull0, v_argisnull0; LLVMValueRef v_argnull1, @@ -1484,18 +1418,11 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - v_argnullp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - - /* load argnull[0|1] for both arguments */ - v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, ""); + /* load args[0|1].isnull for both arguments */ + v_argnull0 = l_funcnull(b, v_fcinfo, 0); v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0, l_sbool_const(1), ""); - - v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, ""); + v_argnull1 = l_funcnull(b, v_fcinfo, 1); v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1, l_sbool_const(1), ""); @@ -1567,11 +1494,9 @@ llvm_compile_expr(ExprState *state) LLVMValueRef v_fcinfo; LLVMValueRef v_fcinfo_isnull; - LLVMValueRef v_argnullp; LLVMValueRef v_argnull0; LLVMValueRef v_argnull1; LLVMValueRef v_anyargisnull; - LLVMValueRef v_argp; LLVMValueRef v_arg0; LLVMBasicBlockRef b_hasnull; LLVMBasicBlockRef b_nonull; @@ -1588,21 +1513,9 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - v_argnullp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - - v_argp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARG, - "v_argp"); - /* if either argument is NULL they can't be equal */ - v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, ""); - v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, ""); + v_argnull0 = l_funcnull(b, v_fcinfo, 0); + v_argnull1 = l_funcnull(b, v_fcinfo, 1); v_anyargisnull = LLVMBuildOr(b, @@ -1616,7 +1529,7 @@ llvm_compile_expr(ExprState *state) /* one (or both) of the arguments are null, return arg[0] */ LLVMPositionBuilderAtEnd(b, b_hasnull); - v_arg0 = l_load_struct_gep(b, v_argp, 0, ""); + v_arg0 = l_funcvalue(b, v_fcinfo, 0); LLVMBuildStore(b, v_argnull0, v_resnullp); LLVMBuildStore(b, v_arg0, v_resvaluep); LLVMBuildBr(b, opblocks[i + 1]); @@ -1715,7 +1628,6 @@ llvm_compile_expr(ExprState *state) if (op->d.rowcompare_step.finfo->fn_strict) { LLVMValueRef v_fcinfo; - LLVMValueRef v_argnullp; LLVMValueRef v_argnull0; LLVMValueRef v_argnull1; LLVMValueRef v_anyargisnull; @@ -1723,13 +1635,8 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - v_argnullp = - LLVMBuildStructGEP(b, v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - - v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, ""); - v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, ""); + v_argnull0 = l_funcnull(b, v_fcinfo, 0); + v_argnull1 = l_funcnull(b, v_fcinfo, 1); v_anyargisnull = LLVMBuildOr(b, @@ -1868,14 +1775,14 @@ llvm_compile_expr(ExprState *state) LLVMBuildBr(b, opblocks[i + 1]); break; - case EEOP_ARRAYREF_SUBSCRIPT: + case EEOP_SBSREF_SUBSCRIPT: { LLVMValueRef v_fn; - int jumpdone = op->d.arrayref_subscript.jumpdone; + int jumpdone = op->d.sbsref_subscript.jumpdone; LLVMValueRef v_params[2]; LLVMValueRef v_ret; - v_fn = llvm_get_decl(mod, FuncExecEvalArrayRefSubscript); + v_fn = llvm_get_decl(mod, FuncExecEvalSubscriptingRef); v_params[0] = v_state; v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); @@ -2019,8 +1926,8 @@ llvm_compile_expr(ExprState *state) isnull; /* - * At this point aggref->wfuncno is not yet set (it's - * set up in ExecInitWindowAgg() after initializing the + * At this point aggref->wfuncno is not yet set (it's set + * up in ExecInitWindowAgg() after initializing the * expression). So load it from memory each time round. */ v_wfuncnop = l_ptr_const(&wfunc->wfuncno, @@ -2056,7 +1963,6 @@ llvm_compile_expr(ExprState *state) { FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data; LLVMValueRef v_fcinfo; - LLVMValueRef v_argnullp; LLVMValueRef v_argnull0; LLVMBasicBlockRef b_deserialize; @@ -2065,14 +1971,7 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - - v_argnullp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - v_argnull0 = - l_load_struct_gep(b, v_argnullp, 0, "v_argnull0"); + v_argnull0 = l_funcnull(b, v_fcinfo, 0); LLVMBuildCondBr(b, LLVMBuildICmp(b, @@ -2083,9 +1982,8 @@ llvm_compile_expr(ExprState *state) opblocks[op->d.agg_deserialize.jumpnull], b_deserialize); LLVMPositionBuilderAtEnd(b, b_deserialize); - - /* fallthrough */ } + /* FALLTHROUGH */ case EEOP_AGG_DESERIALIZE: { @@ -2115,18 +2013,24 @@ llvm_compile_expr(ExprState *state) break; } - case EEOP_AGG_STRICT_INPUT_CHECK: + case EEOP_AGG_STRICT_INPUT_CHECK_NULLS: + case EEOP_AGG_STRICT_INPUT_CHECK_ARGS: { int nargs = op->d.agg_strict_input_check.nargs; + NullableDatum *args = op->d.agg_strict_input_check.args; bool *nulls = op->d.agg_strict_input_check.nulls; int jumpnull; int argno; - LLVMValueRef v_nullp; + LLVMValueRef v_argsp; + LLVMValueRef v_nullsp; LLVMBasicBlockRef *b_checknulls; + Assert(nargs > 0); + jumpnull = op->d.agg_strict_input_check.jumpnull; - v_nullp = l_ptr_const(nulls, l_ptr(TypeStorageBool)); + v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum)); + v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool)); /* create blocks for checking args */ b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs); @@ -2154,7 +2058,18 @@ llvm_compile_expr(ExprState *state) else b_argnotnull = b_checknulls[argno + 1]; - v_argisnull = l_load_gep1(b, v_nullp, v_argno, ""); + if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS) + v_argisnull = l_load_gep1(b, v_nullsp, v_argno, ""); + else + { + LLVMValueRef v_argn; + + v_argn = LLVMBuildGEP(b, v_argsp, &v_argno, 1, ""); + v_argisnull = + l_load_struct_gep(b, v_argn, + FIELDNO_NULLABLE_DATUM_ISNULL, + ""); + } LLVMBuildCondBr(b, LLVMBuildICmp(b, @@ -2229,6 +2144,28 @@ llvm_compile_expr(ExprState *state) { LLVMValueRef params[3]; + LLVMValueRef v_curaggcontext; + LLVMValueRef v_current_set; + LLVMValueRef v_aggcontext; + + v_aggcontext = l_ptr_const(op->d.agg_init_trans.aggcontext, + l_ptr(StructExprContext)); + + v_current_set = + LLVMBuildStructGEP(b, + v_aggstatep, + FIELDNO_AGGSTATE_CURRENT_SET, + "aggstate.current_set"); + v_curaggcontext = + LLVMBuildStructGEP(b, + v_aggstatep, + FIELDNO_AGGSTATE_CURAGGCONTEXT, + "aggstate.curaggcontext"); + + LLVMBuildStore(b, l_int32_const(op->d.agg_init_trans.setno), + v_current_set); + LLVMBuildStore(b, v_aggcontext, + v_curaggcontext); params[0] = v_aggstatep; params[1] = v_pertransp; @@ -2303,8 +2240,6 @@ llvm_compile_expr(ExprState *state) LLVMValueRef v_aggstatep; LLVMValueRef v_fcinfo; LLVMValueRef v_fcinfo_isnull; - LLVMValueRef v_argp, - v_argnullp; LLVMValueRef v_transvaluep; LLVMValueRef v_transnullp; @@ -2331,7 +2266,7 @@ llvm_compile_expr(ExprState *state) aggstate = op->d.agg_trans.aggstate; pertrans = op->d.agg_trans.pertrans; - fcinfo = &pertrans->transfn_fcinfo; + fcinfo = pertrans->transfn_fcinfo; v_aggstatep = l_ptr_const(aggstate, l_ptr(StructAggState)); @@ -2356,18 +2291,6 @@ llvm_compile_expr(ExprState *state) v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); - - v_argnullp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARGNULL, - "v_argnullp"); - v_argp = - LLVMBuildStructGEP(b, - v_fcinfo, - FIELDNO_FUNCTIONCALLINFODATA_ARG, - "v_argp"); - v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext, l_ptr(StructExprContext)); @@ -2399,7 +2322,7 @@ llvm_compile_expr(ExprState *state) l_ptr(StructMemoryContextData)); v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext); - /* store transvalue in fcinfo->arg/argnull[0] */ + /* store transvalue in fcinfo->args[0] */ v_transvaluep = LLVMBuildStructGEP(b, v_pergroupp, FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE, @@ -2411,10 +2334,10 @@ llvm_compile_expr(ExprState *state) LLVMBuildStore(b, LLVMBuildLoad(b, v_transvaluep, "transvalue"), - LLVMBuildStructGEP(b, v_argp, 0, "")); + l_funcvaluep(b, v_fcinfo, 0)); LLVMBuildStore(b, LLVMBuildLoad(b, v_transnullp, "transnull"), - LLVMBuildStructGEP(b, v_argnullp, 0, "")); + l_funcnullp(b, v_fcinfo, 0)); /* and invoke transition function */ v_retval = BuildV1Call(context, b, mod, fcinfo, @@ -2478,6 +2401,8 @@ llvm_compile_expr(ExprState *state) /* store trans value */ LLVMBuildStore(b, v_newval, v_transvaluep); LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp); + + l_mcxt_switch(mod, b, v_oldcontext); LLVMBuildBr(b, opblocks[i + 1]); /* returned datum passed datum, no need to reparent */ @@ -2534,7 +2459,7 @@ llvm_compile_expr(ExprState *state) llvm_leave_fatal_on_oom(); INSTR_TIME_SET_CURRENT(endtime); - INSTR_TIME_ACCUM_DIFF(context->base.generation_counter, + INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter, endtime, starttime); return true; @@ -2599,12 +2524,8 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b, LLVMValueRef v_lifetime = create_LifetimeEnd(mod); LLVMValueRef params[2]; - params[0] = l_int64_const(sizeof(fcinfo->arg)); - params[1] = l_ptr_const(fcinfo->arg, l_ptr(LLVMInt8Type())); - LLVMBuildCall(b, v_lifetime, params, lengthof(params), ""); - - params[0] = l_int64_const(sizeof(fcinfo->argnull)); - params[1] = l_ptr_const(fcinfo->argnull, l_ptr(LLVMInt8Type())); + params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs); + params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type())); LLVMBuildCall(b, v_lifetime, params, lengthof(params), ""); params[0] = l_int64_const(sizeof(fcinfo->isnull)); diff --git a/src/backend/jit/llvm/llvmjit_inline.cpp b/src/backend/jit/llvm/llvmjit_inline.cpp index 130e2ab415e..688edfe5254 100644 --- a/src/backend/jit/llvm/llvmjit_inline.cpp +++ b/src/backend/jit/llvm/llvmjit_inline.cpp @@ -9,12 +9,12 @@ * for an external function is found - not guaranteed! - the index will then * be used to judge their instruction count / inline worthiness. After doing * so for all external functions, all the referenced functions (and - * prerequisites) will be imorted. + * prerequisites) will be imported. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION - * src/backend/lib/llvmjit/llvmjit_inline.c + * src/backend/lib/llvmjit/llvmjit_inline.cpp * *------------------------------------------------------------------------- */ @@ -42,6 +42,9 @@ extern "C" #include #include +/* Avoid macro clash with LLVM's C++ headers */ +#undef Min + #include #include #include @@ -171,7 +174,7 @@ llvm_inline(LLVMModuleRef M) static std::unique_ptr llvm_build_inline_plan(llvm::Module *mod) { - std::unique_ptr globalsToInline = llvm::make_unique(); + std::unique_ptr globalsToInline(new ImportMapTy()); FunctionInlineStates functionStates; InlineWorkList worklist; @@ -287,14 +290,6 @@ llvm_build_inline_plan(llvm::Module *mod) Assert(!funcDef->isDeclaration()); Assert(funcDef->hasExternalLinkage()); - /* don't inline functions marked as noinline */ - if (funcDef->getAttributes().hasFnAttribute(llvm::Attribute::NoInline)) - { - ilog(DEBUG1, "ineligibile to import %s due to noinline", - symbolName.data()); - continue; - } - llvm::StringSet<> importVars; llvm::SmallPtrSet visitedFunctions; int running_instcount = 0; @@ -316,7 +311,7 @@ llvm_build_inline_plan(llvm::Module *mod) * Check whether function and all its dependencies are too * big. Dependencies already counted for other functions that * will get inlined are not counted again. While this make - * things somewhat order dependant, I can't quite see a point + * things somewhat order dependent, I can't quite see a point * in a different behaviour. */ if (running_instcount > inlineState.costLimit) @@ -600,6 +595,13 @@ function_inlinable(llvm::Function &F, if (F.materialize()) elog(FATAL, "failed to materialize metadata"); + if (F.getAttributes().hasFnAttribute(llvm::Attribute::NoInline)) + { + ilog(DEBUG1, "ineligibile to import %s due to noinline", + F.getName().data()); + return false; + } + function_references(F, running_instcount, referencedVars, referencedFunctions); for (llvm::GlobalVariable* rv: referencedVars) diff --git a/src/backend/jit/llvm/llvmjit_types.c b/src/backend/jit/llvm/llvmjit_types.c index 42304d06401..9522b972c1a 100644 --- a/src/backend/jit/llvm/llvmjit_types.c +++ b/src/backend/jit/llvm/llvmjit_types.c @@ -16,10 +16,10 @@ * bitcode. * * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION - * src/backend/lib/llvmjit_types.c + * src/backend/jit/llvm/llvmjit_types.c * *------------------------------------------------------------------------- */ @@ -49,17 +49,20 @@ PGFunction TypePGFunction; size_t TypeSizeT; bool TypeStorageBool; +NullableDatum StructNullableDatum; AggState StructAggState; AggStatePerGroupData StructAggStatePerGroupData; AggStatePerTransData StructAggStatePerTransData; ExprContext StructExprContext; ExprEvalStep StructExprEvalStep; ExprState StructExprState; -FunctionCallInfoData StructFunctionCallInfoData; +FunctionCallInfoBaseData StructFunctionCallInfoData; HeapTupleData StructHeapTupleData; MemoryContextData StructMemoryContextData; TupleTableSlot StructTupleTableSlot; -struct tupleDesc StructtupleDesc; +HeapTupleTableSlot StructHeapTupleTableSlot; +MinimalTupleTableSlot StructMinimalTupleTableSlot; +TupleDescData StructTupleDescData; /* @@ -97,11 +100,11 @@ void *referenced_functions[] = { strlen, varsize_any, - slot_getsomeattrs, + slot_getsomeattrs_int, slot_getmissingattrs, - heap_getsysattr, MakeExpandedObjectReadOnlyInternal, - ExecEvalArrayRefSubscript, + ExecEvalSubscriptingRef, + ExecEvalSysVar, ExecAggTransReparent, ExecAggInitGroup }; diff --git a/src/backend/jit/llvm/llvmjit_wrap.cpp b/src/backend/jit/llvm/llvmjit_wrap.cpp index 5d1a17cde04..18876ec5209 100644 --- a/src/backend/jit/llvm/llvmjit_wrap.cpp +++ b/src/backend/jit/llvm/llvmjit_wrap.cpp @@ -3,10 +3,10 @@ * llvmjit_wrap.cpp * Parts of the LLVM interface not (yet) exposed to C. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION - * src/backend/lib/llvm/llvmjit_wrap.c + * src/backend/lib/llvm/llvmjit_wrap.cpp * *------------------------------------------------------------------------- */ @@ -32,6 +32,7 @@ char *LLVMGetHostCPUName(void) { #endif +#if defined(HAVE_DECL_LLVMGETHOSTCPUFEATURES) && !HAVE_DECL_LLVMGETHOSTCPUFEATURES char *LLVMGetHostCPUFeatures(void) { llvm::SubtargetFeatures Features; llvm::StringMap HostFeatures; @@ -42,3 +43,4 @@ char *LLVMGetHostCPUFeatures(void) { return strdup(Features.getString().c_str()); } +#endif diff --git a/src/backend/lib/Makefile b/src/backend/lib/Makefile index 191ea9bca26..3c1ee1df83a 100644 --- a/src/backend/lib/Makefile +++ b/src/backend/lib/Makefile @@ -13,6 +13,6 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global OBJS = binaryheap.o bipartite_match.o bloomfilter.o dshash.o hyperloglog.o \ - ilist.o knapsack.o pairingheap.o rbtree.o stringinfo.o + ilist.o integerset.o knapsack.o pairingheap.o rbtree.o stringinfo.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/lib/README b/src/backend/lib/README index 376ae273a90..f2fb591237d 100644 --- a/src/backend/lib/README +++ b/src/backend/lib/README @@ -3,16 +3,24 @@ in the backend: binaryheap.c - a binary heap +bipartite_match.c - Hopcroft-Karp maximum cardinality algorithm for bipartite graphs + bloomfilter.c - probabilistic, space-efficient set membership testing +dshash.c - concurrent hash tables backed by dynamic shared memory areas + hyperloglog.c - a streaming cardinality estimator +ilist.c - single and double-linked lists + +integerset.c - a data structure for holding large set of integers + +knapsack.c - knapsack problem solver + pairingheap.c - a pairing heap rbtree.c - a red-black tree -ilist.c - single and double-linked lists. - stringinfo.c - an extensible string type diff --git a/src/backend/lib/binaryheap.c b/src/backend/lib/binaryheap.c index a8adf065a94..a2c89678132 100644 --- a/src/backend/lib/binaryheap.c +++ b/src/backend/lib/binaryheap.c @@ -3,7 +3,7 @@ * binaryheap.c * A simple binary heap implementation * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/binaryheap.c diff --git a/src/backend/lib/bipartite_match.c b/src/backend/lib/bipartite_match.c index 5be5ed24f1c..5d13c5c69e7 100644 --- a/src/backend/lib/bipartite_match.c +++ b/src/backend/lib/bipartite_match.c @@ -5,9 +5,9 @@ * * This implementation is based on pseudocode found at: * - * http://en.wikipedia.org/w/index.php?title=Hopcroft%E2%80%93Karp_algorithm&oldid=593898016 + * https://en.wikipedia.org/w/index.php?title=Hopcroft%E2%80%93Karp_algorithm&oldid=593898016 * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/bipartite_match.c diff --git a/src/backend/lib/bloomfilter.c b/src/backend/lib/bloomfilter.c index 3565480d13e..859aac07b7d 100644 --- a/src/backend/lib/bloomfilter.c +++ b/src/backend/lib/bloomfilter.c @@ -24,7 +24,7 @@ * caller many authoritative lookups, such as expensive probes of a much larger * on-disk structure. * - * Copyright (c) 2018, PostgreSQL Global Development Group + * Copyright (c) 2018-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/bloomfilter.c @@ -35,8 +35,9 @@ #include -#include "access/hash.h" #include "lib/bloomfilter.h" +#include "port/pg_bitutils.h" +#include "utils/hashutils.h" #define MAX_HASH_FUNCS 10 @@ -53,7 +54,7 @@ struct bloom_filter static int my_bloom_power(uint64 target_bitset_bits); static int optimal_k(uint64 bitset_bits, int64 total_elems); static void k_hashes(bloom_filter *filter, uint32 *hashes, unsigned char *elem, - size_t len); + size_t len); static inline uint32 mod_m(uint32 a, uint64 m); /* @@ -187,19 +188,7 @@ double bloom_prop_bits_set(bloom_filter *filter) { int bitset_bytes = filter->m / BITS_PER_BYTE; - uint64 bits_set = 0; - int i; - - for (i = 0; i < bitset_bytes; i++) - { - unsigned char byte = filter->bitset[i]; - - while (byte) - { - bits_set++; - byte &= (byte - 1); - } - } + uint64 bits_set = pg_popcount((char *) filter->bitset, bitset_bytes); return bits_set / (double) filter->m; } @@ -262,7 +251,8 @@ static void k_hashes(bloom_filter *filter, uint32 *hashes, unsigned char *elem, size_t len) { uint64 hash; - uint32 x, y; + uint32 x, + y; uint64 m; int i; diff --git a/src/backend/lib/dshash.c b/src/backend/lib/dshash.c index b46f7c4cfd0..350f8c0a665 100644 --- a/src/backend/lib/dshash.c +++ b/src/backend/lib/dshash.c @@ -20,7 +20,7 @@ * Future versions may support iterators and incremental resizing; for now * the implementation is minimalist. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -160,28 +160,28 @@ struct dshash_table hash_table->size_log2)]) static void delete_item(dshash_table *hash_table, - dshash_table_item *item); + dshash_table_item *item); static void resize(dshash_table *hash_table, size_t new_size); static inline void ensure_valid_bucket_pointers(dshash_table *hash_table); static inline dshash_table_item *find_in_bucket(dshash_table *hash_table, - const void *key, - dsa_pointer item_pointer); + const void *key, + dsa_pointer item_pointer); static void insert_item_into_bucket(dshash_table *hash_table, - dsa_pointer item_pointer, - dshash_table_item *item, - dsa_pointer *bucket); + dsa_pointer item_pointer, + dshash_table_item *item, + dsa_pointer *bucket); static dshash_table_item *insert_into_bucket(dshash_table *hash_table, - const void *key, - dsa_pointer *bucket); + const void *key, + dsa_pointer *bucket); static bool delete_key_from_bucket(dshash_table *hash_table, - const void *key, - dsa_pointer *bucket_head); + const void *key, + dsa_pointer *bucket_head); static bool delete_item_from_bucket(dshash_table *hash_table, - dshash_table_item *item, - dsa_pointer *bucket_head); + dshash_table_item *item, + dsa_pointer *bucket_head); static inline dshash_hash hash_key(dshash_table *hash_table, const void *key); static inline bool equal_keys(dshash_table *hash_table, - const void *a, const void *b); + const void *a, const void *b); #define PARTITION_LOCK(hash_table, i) \ (&(hash_table)->control->partitions[(i)].lock) @@ -409,7 +409,7 @@ dshash_find(dshash_table *hash_table, const void *key, bool exclusive) } else { - /* The caller will free the lock by calling dshash_release. */ + /* The caller will free the lock by calling dshash_release_lock. */ hash_table->find_locked = true; hash_table->find_exclusively_locked = exclusive; return ENTRY_FROM_ITEM(item); @@ -672,9 +672,7 @@ delete_item(dshash_table *hash_table, dshash_table_item *item) /* * Grow the hash table if necessary to the requested number of buckets. The - * requested size must be double some previously observed size. Returns true - * if the table was successfully expanded or found to be big enough already - * (because another backend expanded it). + * requested size must be double some previously observed size. * * Must be called without any partition lock held. */ diff --git a/src/backend/lib/hyperloglog.c b/src/backend/lib/hyperloglog.c index 3c50375a925..c782ad04ef0 100644 --- a/src/backend/lib/hyperloglog.c +++ b/src/backend/lib/hyperloglog.c @@ -3,7 +3,7 @@ * hyperloglog.c * HyperLogLog cardinality estimator * - * Portions Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2014-2019, PostgreSQL Global Development Group * * Based on Hideaki Ohno's C++ implementation. This is probably not ideally * suited to estimating the cardinality of very large sets; in particular, we diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c index 58bee57c760..256c84f2671 100644 --- a/src/backend/lib/ilist.c +++ b/src/backend/lib/ilist.c @@ -3,7 +3,7 @@ * ilist.c * support for integrated/inline doubly- and singly- linked lists * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/lib/integerset.c b/src/backend/lib/integerset.c new file mode 100644 index 00000000000..58b0be1f32f --- /dev/null +++ b/src/backend/lib/integerset.c @@ -0,0 +1,1045 @@ +/*------------------------------------------------------------------------- + * + * integerset.c + * Data structure to hold a large set of 64-bit integers efficiently + * + * IntegerSet provides an in-memory data structure to hold a set of + * arbitrary 64-bit integers. Internally, the values are stored in a + * B-tree, with a special packed representation at the leaf level using + * the Simple-8b algorithm, which can pack clusters of nearby values + * very tightly. + * + * Memory consumption depends on the number of values stored, but also + * on how far the values are from each other. In the best case, with + * long runs of consecutive integers, memory consumption can be as low as + * 0.1 bytes per integer. In the worst case, if integers are more than + * 2^32 apart, it uses about 8 bytes per integer. In typical use, the + * consumption per integer is somewhere between those extremes, depending + * on the range of integers stored, and how "clustered" they are. + * + * + * Interface + * --------- + * + * intset_create - Create a new, empty set + * intset_add_member - Add an integer to the set + * intset_is_member - Test if an integer is in the set + * intset_begin_iterate - Begin iterating through all integers in set + * intset_iterate_next - Return next set member, if any + * + * intset_create() creates the set in the current memory context. Subsequent + * operations that add to the data structure will continue to allocate from + * that same context, even if it's not current anymore. + * + * Note that there is no function to free an integer set. If you need to do + * that, create a dedicated memory context to hold it, and destroy the memory + * context instead. + * + * + * Limitations + * ----------- + * + * - Values must be added in order. (Random insertions would require + * splitting nodes, which hasn't been implemented.) + * + * - Values cannot be added while iteration is in progress. + * + * - No support for removing values. + * + * None of these limitations are fundamental to the data structure, so they + * could be lifted if needed, by writing some new code. But the current + * users of this facility don't need them. + * + * + * References + * ---------- + * + * Simple-8b encoding is based on: + * + * Vo Ngoc Anh, Alistair Moffat, Index compression using 64-bit words, + * Software - Practice & Experience, v.40 n.2, p.131-147, February 2010 + * (https://doi.org/10.1002/spe.948) + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/lib/integerset.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/htup_details.h" +#include "lib/integerset.h" +#include "port/pg_bitutils.h" +#include "utils/memutils.h" + + +/* + * Maximum number of integers that can be encoded in a single Simple-8b + * codeword. (Defined here before anything else, so that we can size arrays + * using this.) + */ +#define SIMPLE8B_MAX_VALUES_PER_CODEWORD 240 + +/* + * Parameters for shape of the in-memory B-tree. + * + * These set the size of each internal and leaf node. They don't necessarily + * need to be the same, because the tree is just an in-memory structure. + * With the default 64, each node is about 1 kb. + * + * If you change these, you must recalculate MAX_TREE_LEVELS, too! + */ +#define MAX_INTERNAL_ITEMS 64 +#define MAX_LEAF_ITEMS 64 + +/* + * Maximum height of the tree. + * + * MAX_TREE_ITEMS is calculated from the "fan-out" of the B-tree. The + * theoretical maximum number of items that we can store in a set is 2^64, + * so MAX_TREE_LEVELS should be set so that: + * + * MAX_LEAF_ITEMS * MAX_INTERNAL_ITEMS ^ (MAX_TREE_LEVELS - 1) >= 2^64. + * + * In practice, we'll need far fewer levels, because you will run out of + * memory long before reaching that number, but let's be conservative. + */ +#define MAX_TREE_LEVELS 11 + +/* + * Node structures, for the in-memory B-tree. + * + * An internal node holds a number of downlink pointers to leaf nodes, or + * to internal nodes on a lower level. For each downlink, the key value + * corresponding to the lower level node is stored in a sorted array. The + * stored key values are low keys. In other words, if the downlink has value + * X, then all items stored on that child are >= X. + * + * Each leaf node holds a number of "items", with a varying number of + * integers packed into each item. Each item consists of two 64-bit words: + * The first word holds the first integer stored in the item, in plain format. + * The second word contains between 0 and 240 more integers, packed using + * Simple-8b encoding. By storing the first integer in plain, unpacked, + * format, we can use binary search to quickly find an item that holds (or + * would hold) a particular integer. And by storing the rest in packed form, + * we still get pretty good memory density, if there are clusters of integers + * with similar values. + * + * Each leaf node also has a pointer to the next leaf node, so that the leaf + * nodes can be easily walked from beginning to end when iterating. + */ +typedef struct intset_node intset_node; +typedef struct intset_leaf_node intset_leaf_node; +typedef struct intset_internal_node intset_internal_node; + +/* Common structure of both leaf and internal nodes. */ +struct intset_node +{ + uint16 level; /* tree level of this node */ + uint16 num_items; /* number of items in this node */ +}; + +/* Internal node */ +struct intset_internal_node +{ + /* common header, must match intset_node */ + uint16 level; /* >= 1 on internal nodes */ + uint16 num_items; + + /* + * 'values' is an array of key values, and 'downlinks' are pointers to + * lower-level nodes, corresponding to the key values. + */ + uint64 values[MAX_INTERNAL_ITEMS]; + intset_node *downlinks[MAX_INTERNAL_ITEMS]; +}; + +/* Leaf node */ +typedef struct +{ + uint64 first; /* first integer in this item */ + uint64 codeword; /* simple8b encoded differences from 'first' */ +} leaf_item; + +#define MAX_VALUES_PER_LEAF_ITEM (1 + SIMPLE8B_MAX_VALUES_PER_CODEWORD) + +struct intset_leaf_node +{ + /* common header, must match intset_node */ + uint16 level; /* 0 on leafs */ + uint16 num_items; + + intset_leaf_node *next; /* right sibling, if any */ + + leaf_item items[MAX_LEAF_ITEMS]; +}; + +/* + * We buffer insertions in a simple array, before packing and inserting them + * into the B-tree. MAX_BUFFERED_VALUES sets the size of the buffer. The + * encoder assumes that it is large enough that we can always fill a leaf + * item with buffered new items. In other words, MAX_BUFFERED_VALUES must be + * larger than MAX_VALUES_PER_LEAF_ITEM. For efficiency, make it much larger. + */ +#define MAX_BUFFERED_VALUES (MAX_VALUES_PER_LEAF_ITEM * 2) + +/* + * IntegerSet is the top-level object representing the set. + * + * The integers are stored in an in-memory B-tree structure, plus an array + * for newly-added integers. IntegerSet also tracks information about memory + * usage, as well as the current position when iterating the set with + * intset_begin_iterate / intset_iterate_next. + */ +struct IntegerSet +{ + /* + * 'context' is the memory context holding this integer set and all its + * tree nodes. + * + * 'mem_used' tracks the amount of memory used. We don't do anything with + * it in integerset.c itself, but the callers can ask for it with + * intset_memory_usage(). + */ + MemoryContext context; + uint64 mem_used; + + uint64 num_entries; /* total # of values in the set */ + uint64 highest_value; /* highest value stored in this set */ + + /* + * B-tree to hold the packed values. + * + * 'rightmost_nodes' hold pointers to the rightmost node on each level. + * rightmost_parent[0] is rightmost leaf, rightmost_parent[1] is its + * parent, and so forth, all the way up to the root. These are needed when + * adding new values. (Currently, we require that new values are added at + * the end.) + */ + int num_levels; /* height of the tree */ + intset_node *root; /* root node */ + intset_node *rightmost_nodes[MAX_TREE_LEVELS]; + intset_leaf_node *leftmost_leaf; /* leftmost leaf node */ + + /* + * Holding area for new items that haven't been inserted to the tree yet. + */ + uint64 buffered_values[MAX_BUFFERED_VALUES]; + int num_buffered_values; + + /* + * Iterator support. + * + * 'iter_values' is an array of integers ready to be returned to the + * caller; 'iter_num_values' is the length of that array, and + * 'iter_valueno' is the next index. 'iter_node' and 'iter_itemno' point + * to the leaf node, and item within the leaf node, to get the next batch + * of values from. + * + * Normally, 'iter_values' points to 'iter_values_buf', which holds items + * decoded from a leaf item. But after we have scanned the whole B-tree, + * we iterate through all the unbuffered values, too, by pointing + * iter_values to 'buffered_values'. + */ + bool iter_active; /* is iteration in progress? */ + + const uint64 *iter_values; + int iter_num_values; /* number of elements in 'iter_values' */ + int iter_valueno; /* next index into 'iter_values' */ + + intset_leaf_node *iter_node; /* current leaf node */ + int iter_itemno; /* next item in 'iter_node' to decode */ + + uint64 iter_values_buf[MAX_VALUES_PER_LEAF_ITEM]; +}; + +/* + * Prototypes for internal functions. + */ +static void intset_update_upper(IntegerSet *intset, int level, + intset_node *child, uint64 child_key); +static void intset_flush_buffered_values(IntegerSet *intset); + +static int intset_binsrch_uint64(uint64 value, uint64 *arr, int arr_elems, + bool nextkey); +static int intset_binsrch_leaf(uint64 value, leaf_item *arr, int arr_elems, + bool nextkey); + +static uint64 simple8b_encode(const uint64 *ints, int *num_encoded, uint64 base); +static int simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base); +static bool simple8b_contains(uint64 codeword, uint64 key, uint64 base); + + +/* + * Create a new, initially empty, integer set. + * + * The integer set is created in the current memory context. + * We will do all subsequent allocations in the same context, too, regardless + * of which memory context is current when new integers are added to the set. + */ +IntegerSet * +intset_create(void) +{ + IntegerSet *intset; + + intset = (IntegerSet *) palloc(sizeof(IntegerSet)); + intset->context = CurrentMemoryContext; + intset->mem_used = GetMemoryChunkSpace(intset); + + intset->num_entries = 0; + intset->highest_value = 0; + + intset->num_levels = 0; + intset->root = NULL; + memset(intset->rightmost_nodes, 0, sizeof(intset->rightmost_nodes)); + intset->leftmost_leaf = NULL; + + intset->num_buffered_values = 0; + + intset->iter_active = false; + intset->iter_node = NULL; + intset->iter_itemno = 0; + intset->iter_valueno = 0; + intset->iter_num_values = 0; + intset->iter_values = NULL; + + return intset; +} + +/* + * Allocate a new node. + */ +static intset_internal_node * +intset_new_internal_node(IntegerSet *intset) +{ + intset_internal_node *n; + + n = (intset_internal_node *) MemoryContextAlloc(intset->context, + sizeof(intset_internal_node)); + intset->mem_used += GetMemoryChunkSpace(n); + + n->level = 0; /* caller must set */ + n->num_items = 0; + + return n; +} + +static intset_leaf_node * +intset_new_leaf_node(IntegerSet *intset) +{ + intset_leaf_node *n; + + n = (intset_leaf_node *) MemoryContextAlloc(intset->context, + sizeof(intset_leaf_node)); + intset->mem_used += GetMemoryChunkSpace(n); + + n->level = 0; + n->num_items = 0; + n->next = NULL; + + return n; +} + +/* + * Return the number of entries in the integer set. + */ +uint64 +intset_num_entries(IntegerSet *intset) +{ + return intset->num_entries; +} + +/* + * Return the amount of memory used by the integer set. + */ +uint64 +intset_memory_usage(IntegerSet *intset) +{ + return intset->mem_used; +} + +/* + * Add a value to the set. + * + * Values must be added in order. + */ +void +intset_add_member(IntegerSet *intset, uint64 x) +{ + if (intset->iter_active) + elog(ERROR, "cannot add new values to integer set while iteration is in progress"); + + if (x <= intset->highest_value && intset->num_entries > 0) + elog(ERROR, "cannot add value to integer set out of order"); + + if (intset->num_buffered_values >= MAX_BUFFERED_VALUES) + { + /* Time to flush our buffer */ + intset_flush_buffered_values(intset); + Assert(intset->num_buffered_values < MAX_BUFFERED_VALUES); + } + + /* Add it to the buffer of newly-added values */ + intset->buffered_values[intset->num_buffered_values] = x; + intset->num_buffered_values++; + intset->num_entries++; + intset->highest_value = x; +} + +/* + * Take a batch of buffered values, and pack them into the B-tree. + */ +static void +intset_flush_buffered_values(IntegerSet *intset) +{ + uint64 *values = intset->buffered_values; + uint64 num_values = intset->num_buffered_values; + int num_packed = 0; + intset_leaf_node *leaf; + + leaf = (intset_leaf_node *) intset->rightmost_nodes[0]; + + /* + * If the tree is completely empty, create the first leaf page, which is + * also the root. + */ + if (leaf == NULL) + { + /* + * This is the very first item in the set. + * + * Allocate root node. It's also a leaf. + */ + leaf = intset_new_leaf_node(intset); + + intset->root = (intset_node *) leaf; + intset->leftmost_leaf = leaf; + intset->rightmost_nodes[0] = (intset_node *) leaf; + intset->num_levels = 1; + } + + /* + * If there are less than MAX_VALUES_PER_LEAF_ITEM values in the buffer, + * stop. In most cases, we cannot encode that many values in a single + * value, but this way, the encoder doesn't have to worry about running + * out of input. + */ + while (num_values - num_packed >= MAX_VALUES_PER_LEAF_ITEM) + { + leaf_item item; + int num_encoded; + + /* + * Construct the next leaf item, packing as many buffered values as + * possible. + */ + item.first = values[num_packed]; + item.codeword = simple8b_encode(&values[num_packed + 1], + &num_encoded, + item.first); + + /* + * Add the item to the node, allocating a new node if the old one is + * full. + */ + if (leaf->num_items >= MAX_LEAF_ITEMS) + { + /* Allocate new leaf and link it to the tree */ + intset_leaf_node *old_leaf = leaf; + + leaf = intset_new_leaf_node(intset); + old_leaf->next = leaf; + intset->rightmost_nodes[0] = (intset_node *) leaf; + intset_update_upper(intset, 1, (intset_node *) leaf, item.first); + } + leaf->items[leaf->num_items++] = item; + + num_packed += 1 + num_encoded; + } + + /* + * Move any remaining buffered values to the beginning of the array. + */ + if (num_packed < intset->num_buffered_values) + { + memmove(&intset->buffered_values[0], + &intset->buffered_values[num_packed], + (intset->num_buffered_values - num_packed) * sizeof(uint64)); + } + intset->num_buffered_values -= num_packed; +} + +/* + * Insert a downlink into parent node, after creating a new node. + * + * Recurses if the parent node is full, too. + */ +static void +intset_update_upper(IntegerSet *intset, int level, intset_node *child, + uint64 child_key) +{ + intset_internal_node *parent; + + Assert(level > 0); + + /* + * Create a new root node, if necessary. + */ + if (level >= intset->num_levels) + { + intset_node *oldroot = intset->root; + uint64 downlink_key; + + /* MAX_TREE_LEVELS should be more than enough, this shouldn't happen */ + if (intset->num_levels == MAX_TREE_LEVELS) + elog(ERROR, "could not expand integer set, maximum number of levels reached"); + intset->num_levels++; + + /* + * Get the first value on the old root page, to be used as the + * downlink. + */ + if (intset->root->level == 0) + downlink_key = ((intset_leaf_node *) oldroot)->items[0].first; + else + downlink_key = ((intset_internal_node *) oldroot)->values[0]; + + parent = intset_new_internal_node(intset); + parent->level = level; + parent->values[0] = downlink_key; + parent->downlinks[0] = oldroot; + parent->num_items = 1; + + intset->root = (intset_node *) parent; + intset->rightmost_nodes[level] = (intset_node *) parent; + } + + /* + * Place the downlink on the parent page. + */ + parent = (intset_internal_node *) intset->rightmost_nodes[level]; + + if (parent->num_items < MAX_INTERNAL_ITEMS) + { + parent->values[parent->num_items] = child_key; + parent->downlinks[parent->num_items] = child; + parent->num_items++; + } + else + { + /* + * Doesn't fit. Allocate new parent, with the downlink as the first + * item on it, and recursively insert the downlink to the new parent + * to the grandparent. + */ + parent = intset_new_internal_node(intset); + parent->level = level; + parent->values[0] = child_key; + parent->downlinks[0] = child; + parent->num_items = 1; + + intset->rightmost_nodes[level] = (intset_node *) parent; + + intset_update_upper(intset, level + 1, (intset_node *) parent, child_key); + } +} + +/* + * Does the set contain the given value? + */ +bool +intset_is_member(IntegerSet *intset, uint64 x) +{ + intset_node *node; + intset_leaf_node *leaf; + int level; + int itemno; + leaf_item *item; + + /* + * The value might be in the buffer of newly-added values. + */ + if (intset->num_buffered_values > 0 && x >= intset->buffered_values[0]) + { + int itemno; + + itemno = intset_binsrch_uint64(x, + intset->buffered_values, + intset->num_buffered_values, + false); + if (itemno >= intset->num_buffered_values) + return false; + else + return (intset->buffered_values[itemno] == x); + } + + /* + * Start from the root, and walk down the B-tree to find the right leaf + * node. + */ + if (!intset->root) + return false; + node = intset->root; + for (level = intset->num_levels - 1; level > 0; level--) + { + intset_internal_node *n = (intset_internal_node *) node; + + Assert(node->level == level); + + itemno = intset_binsrch_uint64(x, n->values, n->num_items, true); + if (itemno == 0) + return false; + node = n->downlinks[itemno - 1]; + } + Assert(node->level == 0); + leaf = (intset_leaf_node *) node; + + /* + * Binary search to find the right item on the leaf page + */ + itemno = intset_binsrch_leaf(x, leaf->items, leaf->num_items, true); + if (itemno == 0) + return false; + item = &leaf->items[itemno - 1]; + + /* Is this a match to the first value on the item? */ + if (item->first == x) + return true; + Assert(x > item->first); + + /* Is it in the packed codeword? */ + if (simple8b_contains(item->codeword, x, item->first)) + return true; + + return false; +} + +/* + * Begin in-order scan through all the values. + * + * While the iteration is in-progress, you cannot add new values to the set. + */ +void +intset_begin_iterate(IntegerSet *intset) +{ + /* Note that we allow an iteration to be abandoned midway */ + intset->iter_active = true; + intset->iter_node = intset->leftmost_leaf; + intset->iter_itemno = 0; + intset->iter_valueno = 0; + intset->iter_num_values = 0; + intset->iter_values = intset->iter_values_buf; +} + +/* + * Returns the next integer, when iterating. + * + * intset_begin_iterate() must be called first. intset_iterate_next() returns + * the next value in the set. Returns true, if there was another value, and + * stores the value in *next. Otherwise, returns false. + */ +bool +intset_iterate_next(IntegerSet *intset, uint64 *next) +{ + Assert(intset->iter_active); + for (;;) + { + /* Return next iter_values[] entry if any */ + if (intset->iter_valueno < intset->iter_num_values) + { + *next = intset->iter_values[intset->iter_valueno++]; + return true; + } + + /* Decode next item in current leaf node, if any */ + if (intset->iter_node && + intset->iter_itemno < intset->iter_node->num_items) + { + leaf_item *item; + int num_decoded; + + item = &intset->iter_node->items[intset->iter_itemno++]; + + intset->iter_values_buf[0] = item->first; + num_decoded = simple8b_decode(item->codeword, + &intset->iter_values_buf[1], + item->first); + intset->iter_num_values = num_decoded + 1; + intset->iter_valueno = 0; + continue; + } + + /* No more items on this leaf, step to next node */ + if (intset->iter_node) + { + intset->iter_node = intset->iter_node->next; + intset->iter_itemno = 0; + continue; + } + + /* + * We have reached the end of the B-tree. But we might still have + * some integers in the buffer of newly-added values. + */ + if (intset->iter_values == (const uint64 *) intset->iter_values_buf) + { + intset->iter_values = intset->buffered_values; + intset->iter_num_values = intset->num_buffered_values; + intset->iter_valueno = 0; + continue; + } + + break; + } + + /* No more results. */ + intset->iter_active = false; + *next = 0; /* prevent uninitialized-variable warnings */ + return false; +} + +/* + * intset_binsrch_uint64() -- search a sorted array of uint64s + * + * Returns the first position with key equal or less than the given key. + * The returned position would be the "insert" location for the given key, + * that is, the position where the new key should be inserted to. + * + * 'nextkey' affects the behavior on equal keys. If true, and there is an + * equal key in the array, this returns the position immediately after the + * equal key. If false, this returns the position of the equal key itself. + */ +static int +intset_binsrch_uint64(uint64 item, uint64 *arr, int arr_elems, bool nextkey) +{ + int low, + high, + mid; + + low = 0; + high = arr_elems; + while (high > low) + { + mid = low + (high - low) / 2; + + if (nextkey) + { + if (item >= arr[mid]) + low = mid + 1; + else + high = mid; + } + else + { + if (item > arr[mid]) + low = mid + 1; + else + high = mid; + } + } + + return low; +} + +/* same, but for an array of leaf items */ +static int +intset_binsrch_leaf(uint64 item, leaf_item *arr, int arr_elems, bool nextkey) +{ + int low, + high, + mid; + + low = 0; + high = arr_elems; + while (high > low) + { + mid = low + (high - low) / 2; + + if (nextkey) + { + if (item >= arr[mid].first) + low = mid + 1; + else + high = mid; + } + else + { + if (item > arr[mid].first) + low = mid + 1; + else + high = mid; + } + } + + return low; +} + +/* + * Simple-8b encoding. + * + * The simple-8b algorithm packs between 1 and 240 integers into 64-bit words, + * called "codewords". The number of integers packed into a single codeword + * depends on the integers being packed; small integers are encoded using + * fewer bits than large integers. A single codeword can store a single + * 60-bit integer, or two 30-bit integers, for example. + * + * Since we're storing a unique, sorted, set of integers, we actually encode + * the *differences* between consecutive integers. That way, clusters of + * integers that are close to each other are packed efficiently, regardless + * of their absolute values. + * + * In Simple-8b, each codeword consists of a 4-bit selector, which indicates + * how many integers are encoded in the codeword, and the encoded integers are + * packed into the remaining 60 bits. The selector allows for 16 different + * ways of using the remaining 60 bits, called "modes". The number of integers + * packed into a single codeword in each mode is listed in the simple8b_modes + * table below. For example, consider the following codeword: + * + * 20-bit integer 20-bit integer 20-bit integer + * 1101 00000000000000010010 01111010000100100000 00000000000000010100 + * ^ + * selector + * + * The selector 1101 is 13 in decimal. From the modes table below, we see + * that it means that the codeword encodes three 20-bit integers. In decimal, + * those integers are 18, 500000 and 20. Because we encode deltas rather than + * absolute values, the actual values that they represent are 18, 500018 and + * 500038. + * + * Modes 0 and 1 are a bit special; they encode a run of 240 or 120 zeroes + * (which means 240 or 120 consecutive integers, since we're encoding the + * deltas between integers), without using the rest of the codeword bits + * for anything. + * + * Simple-8b cannot encode integers larger than 60 bits. Values larger than + * that are always stored in the 'first' field of a leaf item, never in the + * packed codeword. If there is a sequence of integers that are more than + * 2^60 apart, the codeword will go unused on those items. To represent that, + * we use a magic EMPTY_CODEWORD codeword value. + */ +static const struct simple8b_mode +{ + uint8 bits_per_int; + uint8 num_ints; +} simple8b_modes[17] = + +{ + {0, 240}, /* mode 0: 240 zeroes */ + {0, 120}, /* mode 1: 120 zeroes */ + {1, 60}, /* mode 2: sixty 1-bit integers */ + {2, 30}, /* mode 3: thirty 2-bit integers */ + {3, 20}, /* mode 4: twenty 3-bit integers */ + {4, 15}, /* mode 5: fifteen 4-bit integers */ + {5, 12}, /* mode 6: twelve 5-bit integers */ + {6, 10}, /* mode 7: ten 6-bit integers */ + {7, 8}, /* mode 8: eight 7-bit integers (four bits + * are wasted) */ + {8, 7}, /* mode 9: seven 8-bit integers (four bits + * are wasted) */ + {10, 6}, /* mode 10: six 10-bit integers */ + {12, 5}, /* mode 11: five 12-bit integers */ + {15, 4}, /* mode 12: four 15-bit integers */ + {20, 3}, /* mode 13: three 20-bit integers */ + {30, 2}, /* mode 14: two 30-bit integers */ + {60, 1}, /* mode 15: one 60-bit integer */ + + {0, 0} /* sentinel value */ +}; + +/* + * EMPTY_CODEWORD is a special value, used to indicate "no values". + * It is used if the next value is too large to be encoded with Simple-8b. + * + * This value looks like a mode-0 codeword, but we can distinguish it + * because a regular mode-0 codeword would have zeroes in the unused bits. + */ +#define EMPTY_CODEWORD UINT64CONST(0x0FFFFFFFFFFFFFFF) + +/* + * Encode a number of integers into a Simple-8b codeword. + * + * (What we actually encode are deltas between successive integers. + * "base" is the value before ints[0].) + * + * The input array must contain at least SIMPLE8B_MAX_VALUES_PER_CODEWORD + * elements, ensuring that we can produce a full codeword. + * + * Returns the encoded codeword, and sets *num_encoded to the number of + * input integers that were encoded. That can be zero, if the first delta + * is too large to be encoded. + */ +static uint64 +simple8b_encode(const uint64 *ints, int *num_encoded, uint64 base) +{ + int selector; + int nints; + int bits; + uint64 diff; + uint64 last_val; + uint64 codeword; + int i; + + Assert(ints[0] > base); + + /* + * Select the "mode" to use for this codeword. + * + * In each iteration, check if the next value can be represented in the + * current mode we're considering. If it's too large, then step up the + * mode to a wider one, and repeat. If it fits, move on to the next + * integer. Repeat until the codeword is full, given the current mode. + * + * Note that we don't have any way to represent unused slots in the + * codeword, so we require each codeword to be "full". It is always + * possible to produce a full codeword unless the very first delta is too + * large to be encoded. For example, if the first delta is small but the + * second is too large to be encoded, we'll end up using the last "mode", + * which has nints == 1. + */ + selector = 0; + nints = simple8b_modes[0].num_ints; + bits = simple8b_modes[0].bits_per_int; + diff = ints[0] - base - 1; + last_val = ints[0]; + i = 0; /* number of deltas we have accepted */ + for (;;) + { + if (diff >= (UINT64CONST(1) << bits)) + { + /* too large, step up to next mode */ + selector++; + nints = simple8b_modes[selector].num_ints; + bits = simple8b_modes[selector].bits_per_int; + /* we might already have accepted enough deltas for this mode */ + if (i >= nints) + break; + } + else + { + /* accept this delta; then done if codeword is full */ + i++; + if (i >= nints) + break; + /* examine next delta */ + Assert(ints[i] > last_val); + diff = ints[i] - last_val - 1; + last_val = ints[i]; + } + } + + if (nints == 0) + { + /* + * The first delta is too large to be encoded with Simple-8b. + * + * If there is at least one not-too-large integer in the input, we + * will encode it using mode 15 (or a more compact mode). Hence, we + * can only get here if the *first* delta is >= 2^60. + */ + Assert(i == 0); + *num_encoded = 0; + return EMPTY_CODEWORD; + } + + /* + * Encode the integers using the selected mode. Note that we shift them + * into the codeword in reverse order, so that they will come out in the + * correct order in the decoder. + */ + codeword = 0; + if (bits > 0) + { + for (i = nints - 1; i > 0; i--) + { + diff = ints[i] - ints[i - 1] - 1; + codeword |= diff; + codeword <<= bits; + } + diff = ints[0] - base - 1; + codeword |= diff; + } + + /* add selector to the codeword, and return */ + codeword |= (uint64) selector << 60; + + *num_encoded = nints; + return codeword; +} + +/* + * Decode a codeword into an array of integers. + * Returns the number of integers decoded. + */ +static int +simple8b_decode(uint64 codeword, uint64 *decoded, uint64 base) +{ + int selector = (codeword >> 60); + int nints = simple8b_modes[selector].num_ints; + int bits = simple8b_modes[selector].bits_per_int; + uint64 mask = (UINT64CONST(1) << bits) - 1; + uint64 curr_value; + + if (codeword == EMPTY_CODEWORD) + return 0; + + curr_value = base; + for (int i = 0; i < nints; i++) + { + uint64 diff = codeword & mask; + + curr_value += 1 + diff; + decoded[i] = curr_value; + codeword >>= bits; + } + return nints; +} + +/* + * This is very similar to simple8b_decode(), but instead of decoding all + * the values to an array, it just checks if the given "key" is part of + * the codeword. + */ +static bool +simple8b_contains(uint64 codeword, uint64 key, uint64 base) +{ + int selector = (codeword >> 60); + int nints = simple8b_modes[selector].num_ints; + int bits = simple8b_modes[selector].bits_per_int; + + if (codeword == EMPTY_CODEWORD) + return false; + + if (bits == 0) + { + /* Special handling for 0-bit cases. */ + return (key - base) <= nints; + } + else + { + uint64 mask = (UINT64CONST(1) << bits) - 1; + uint64 curr_value; + + curr_value = base; + for (int i = 0; i < nints; i++) + { + uint64 diff = codeword & mask; + + curr_value += 1 + diff; + + if (curr_value >= key) + { + if (curr_value == key) + return true; + else + return false; + } + + codeword >>= bits; + } + } + return false; +} diff --git a/src/backend/lib/knapsack.c b/src/backend/lib/knapsack.c index c7d9c4d8d24..e22c4b4cd85 100644 --- a/src/backend/lib/knapsack.c +++ b/src/backend/lib/knapsack.c @@ -15,7 +15,7 @@ * allows approximate solutions in polynomial time (the general case of the * exact problem is NP-hard). * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/knapsack.c diff --git a/src/backend/lib/pairingheap.c b/src/backend/lib/pairingheap.c index 89d0f62f8f9..bdaa3b1ad73 100644 --- a/src/backend/lib/pairingheap.c +++ b/src/backend/lib/pairingheap.c @@ -14,7 +14,7 @@ * The pairing heap: a new form of self-adjusting heap. * Algorithmica 1, 1 (January 1986), pages 111-129. DOI: 10.1007/BF01840439 * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/pairingheap.c @@ -27,9 +27,9 @@ #include "lib/pairingheap.h" static pairingheap_node *merge(pairingheap *heap, pairingheap_node *a, - pairingheap_node *b); + pairingheap_node *b); static pairingheap_node *merge_children(pairingheap *heap, - pairingheap_node *children); + pairingheap_node *children); /* * pairingheap_allocate diff --git a/src/backend/lib/rbtree.c b/src/backend/lib/rbtree.c index a43d5938d59..33181e9211a 100644 --- a/src/backend/lib/rbtree.c +++ b/src/backend/lib/rbtree.c @@ -17,7 +17,7 @@ * longest path from root to leaf is only about twice as long as the shortest, * so lookups are guaranteed to run in O(lg n) time. * - * Copyright (c) 2009-2018, PostgreSQL Global Development Group + * Copyright (c) 2009-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/lib/rbtree.c @@ -30,26 +30,26 @@ /* - * Colors of nodes (values of RBNode.color) + * Colors of nodes (values of RBTNode.color) */ -#define RBBLACK (0) -#define RBRED (1) +#define RBTBLACK (0) +#define RBTRED (1) /* * RBTree control structure */ struct RBTree { - RBNode *root; /* root node, or RBNIL if tree is empty */ + RBTNode *root; /* root node, or RBTNIL if tree is empty */ - /* Remaining fields are constant after rb_create */ + /* Remaining fields are constant after rbt_create */ Size node_size; /* actual size of tree nodes */ /* The caller-supplied manipulation functions */ - rb_comparator comparator; - rb_combiner combiner; - rb_allocfunc allocfunc; - rb_freefunc freefunc; + rbt_comparator comparator; + rbt_combiner combiner; + rbt_allocfunc allocfunc; + rbt_freefunc freefunc; /* Passthrough arg passed to all manipulation functions */ void *arg; }; @@ -58,28 +58,31 @@ struct RBTree * all leafs are sentinels, use customized NIL name to prevent * collision with system-wide constant NIL which is actually NULL */ -#define RBNIL (&sentinel) +#define RBTNIL (&sentinel) -static RBNode sentinel = {RBBLACK, RBNIL, RBNIL, NULL}; +static RBTNode sentinel = +{ + RBTBLACK, RBTNIL, RBTNIL, NULL +}; /* - * rb_create: create an empty RBTree + * rbt_create: create an empty RBTree * * Arguments are: - * node_size: actual size of tree nodes (> sizeof(RBNode)) + * node_size: actual size of tree nodes (> sizeof(RBTNode)) * The manipulation functions: - * comparator: compare two RBNodes for less/equal/greater + * comparator: compare two RBTNodes for less/equal/greater * combiner: merge an existing tree entry with a new one - * allocfunc: allocate a new RBNode - * freefunc: free an old RBNode + * allocfunc: allocate a new RBTNode + * freefunc: free an old RBTNode * arg: passthrough pointer that will be passed to the manipulation functions * * Note that the combiner's righthand argument will be a "proposed" tree node, - * ie the input to rb_insert, in which the RBNode fields themselves aren't + * ie the input to rbt_insert, in which the RBTNode fields themselves aren't * valid. Similarly, either input to the comparator may be a "proposed" node. * This shouldn't matter since the functions aren't supposed to look at the - * RBNode fields, only the extra fields of the struct the RBNode is embedded + * RBTNode fields, only the extra fields of the struct the RBTNode is embedded * in. * * The freefunc should just be pfree or equivalent; it should NOT attempt @@ -96,18 +99,18 @@ static RBNode sentinel = {RBBLACK, RBNIL, RBNIL, NULL}; * the RBTree node if you feel the urge. */ RBTree * -rb_create(Size node_size, - rb_comparator comparator, - rb_combiner combiner, - rb_allocfunc allocfunc, - rb_freefunc freefunc, - void *arg) +rbt_create(Size node_size, + rbt_comparator comparator, + rbt_combiner combiner, + rbt_allocfunc allocfunc, + rbt_freefunc freefunc, + void *arg) { RBTree *tree = (RBTree *) palloc(sizeof(RBTree)); - Assert(node_size > sizeof(RBNode)); + Assert(node_size > sizeof(RBTNode)); - tree->root = RBNIL; + tree->root = RBTNIL; tree->node_size = node_size; tree->comparator = comparator; tree->combiner = combiner; @@ -119,11 +122,11 @@ rb_create(Size node_size, return tree; } -/* Copy the additional data fields from one RBNode to another */ +/* Copy the additional data fields from one RBTNode to another */ static inline void -rb_copy_data(RBTree *rb, RBNode *dest, const RBNode *src) +rbt_copy_data(RBTree *rbt, RBTNode *dest, const RBTNode *src) { - memcpy(dest + 1, src + 1, rb->node_size - sizeof(RBNode)); + memcpy(dest + 1, src + 1, rbt->node_size - sizeof(RBTNode)); } /********************************************************************** @@ -131,21 +134,21 @@ rb_copy_data(RBTree *rb, RBNode *dest, const RBNode *src) **********************************************************************/ /* - * rb_find: search for a value in an RBTree + * rbt_find: search for a value in an RBTree * - * data represents the value to try to find. Its RBNode fields need not + * data represents the value to try to find. Its RBTNode fields need not * be valid, it's the extra data in the larger struct that is of interest. * * Returns the matching tree entry, or NULL if no match is found. */ -RBNode * -rb_find(RBTree *rb, const RBNode *data) +RBTNode * +rbt_find(RBTree *rbt, const RBTNode *data) { - RBNode *node = rb->root; + RBTNode *node = rbt->root; - while (node != RBNIL) + while (node != RBTNIL) { - int cmp = rb->comparator(data, node, rb->arg); + int cmp = rbt->comparator(data, node, rbt->arg); if (cmp == 0) return node; @@ -159,26 +162,26 @@ rb_find(RBTree *rb, const RBNode *data) } /* - * rb_leftmost: fetch the leftmost (smallest-valued) tree node. + * rbt_leftmost: fetch the leftmost (smallest-valued) tree node. * Returns NULL if tree is empty. * * Note: in the original implementation this included an unlink step, but - * that's a bit awkward. Just call rb_delete on the result if that's what + * that's a bit awkward. Just call rbt_delete on the result if that's what * you want. */ -RBNode * -rb_leftmost(RBTree *rb) +RBTNode * +rbt_leftmost(RBTree *rbt) { - RBNode *node = rb->root; - RBNode *leftmost = rb->root; + RBTNode *node = rbt->root; + RBTNode *leftmost = rbt->root; - while (node != RBNIL) + while (node != RBTNIL) { leftmost = node; node = node->left; } - if (leftmost != RBNIL) + if (leftmost != RBTNIL) return leftmost; return NULL; @@ -195,17 +198,17 @@ rb_leftmost(RBTree *rb) * child of that node. */ static void -rb_rotate_left(RBTree *rb, RBNode *x) +rbt_rotate_left(RBTree *rbt, RBTNode *x) { - RBNode *y = x->right; + RBTNode *y = x->right; /* establish x->right link */ x->right = y->left; - if (y->left != RBNIL) + if (y->left != RBTNIL) y->left->parent = x; /* establish y->parent link */ - if (y != RBNIL) + if (y != RBTNIL) y->parent = x->parent; if (x->parent) { @@ -216,12 +219,12 @@ rb_rotate_left(RBTree *rb, RBNode *x) } else { - rb->root = y; + rbt->root = y; } /* link x and y */ y->left = x; - if (x != RBNIL) + if (x != RBTNIL) x->parent = y; } @@ -232,17 +235,17 @@ rb_rotate_left(RBTree *rb, RBNode *x) * child of that node. */ static void -rb_rotate_right(RBTree *rb, RBNode *x) +rbt_rotate_right(RBTree *rbt, RBTNode *x) { - RBNode *y = x->left; + RBTNode *y = x->left; /* establish x->left link */ x->left = y->right; - if (y->right != RBNIL) + if (y->right != RBTNIL) y->right->parent = x; /* establish y->parent link */ - if (y != RBNIL) + if (y != RBTNIL) y->parent = x->parent; if (x->parent) { @@ -253,12 +256,12 @@ rb_rotate_right(RBTree *rb, RBNode *x) } else { - rb->root = y; + rbt->root = y; } /* link x and y */ y->right = x; - if (x != RBNIL) + if (x != RBTNIL) x->parent = y; } @@ -276,13 +279,13 @@ rb_rotate_right(RBTree *rb, RBNode *x) * the invariant that every leaf has equal black-height.) */ static void -rb_insert_fixup(RBTree *rb, RBNode *x) +rbt_insert_fixup(RBTree *rbt, RBTNode *x) { /* * x is always a red node. Initially, it is the newly inserted node. Each * iteration of this loop moves it higher up in the tree. */ - while (x != rb->root && x->parent->color == RBRED) + while (x != rbt->root && x->parent->color == RBTRED) { /* * x and x->parent are both red. Fix depends on whether x->parent is @@ -302,60 +305,60 @@ rb_insert_fixup(RBTree *rb, RBNode *x) */ if (x->parent == x->parent->parent->left) { - RBNode *y = x->parent->parent->right; + RBTNode *y = x->parent->parent->right; - if (y->color == RBRED) + if (y->color == RBTRED) { - /* uncle is RBRED */ - x->parent->color = RBBLACK; - y->color = RBBLACK; - x->parent->parent->color = RBRED; + /* uncle is RBTRED */ + x->parent->color = RBTBLACK; + y->color = RBTBLACK; + x->parent->parent->color = RBTRED; x = x->parent->parent; } else { - /* uncle is RBBLACK */ + /* uncle is RBTBLACK */ if (x == x->parent->right) { /* make x a left child */ x = x->parent; - rb_rotate_left(rb, x); + rbt_rotate_left(rbt, x); } /* recolor and rotate */ - x->parent->color = RBBLACK; - x->parent->parent->color = RBRED; + x->parent->color = RBTBLACK; + x->parent->parent->color = RBTRED; - rb_rotate_right(rb, x->parent->parent); + rbt_rotate_right(rbt, x->parent->parent); } } else { /* mirror image of above code */ - RBNode *y = x->parent->parent->left; + RBTNode *y = x->parent->parent->left; - if (y->color == RBRED) + if (y->color == RBTRED) { - /* uncle is RBRED */ - x->parent->color = RBBLACK; - y->color = RBBLACK; - x->parent->parent->color = RBRED; + /* uncle is RBTRED */ + x->parent->color = RBTBLACK; + y->color = RBTBLACK; + x->parent->parent->color = RBTRED; x = x->parent->parent; } else { - /* uncle is RBBLACK */ + /* uncle is RBTBLACK */ if (x == x->parent->left) { x = x->parent; - rb_rotate_right(rb, x); + rbt_rotate_right(rbt, x); } - x->parent->color = RBBLACK; - x->parent->parent->color = RBRED; + x->parent->color = RBTBLACK; + x->parent->parent->color = RBTRED; - rb_rotate_left(rb, x->parent->parent); + rbt_rotate_left(rbt, x->parent->parent); } } } @@ -364,13 +367,13 @@ rb_insert_fixup(RBTree *rb, RBNode *x) * The root may already have been black; if not, the black-height of every * node in the tree increases by one. */ - rb->root->color = RBBLACK; + rbt->root->color = RBTBLACK; } /* - * rb_insert: insert a new value into the tree. + * rbt_insert: insert a new value into the tree. * - * data represents the value to insert. Its RBNode fields need not + * data represents the value to insert. Its RBTNode fields need not * be valid, it's the extra data in the larger struct that is of interest. * * If the value represented by "data" is not present in the tree, then @@ -384,28 +387,28 @@ rb_insert_fixup(RBTree *rb, RBNode *x) * "data" is unmodified in either case; it's typically just a local * variable in the caller. */ -RBNode * -rb_insert(RBTree *rb, const RBNode *data, bool *isNew) +RBTNode * +rbt_insert(RBTree *rbt, const RBTNode *data, bool *isNew) { - RBNode *current, + RBTNode *current, *parent, *x; int cmp; /* find where node belongs */ - current = rb->root; + current = rbt->root; parent = NULL; cmp = 0; /* just to prevent compiler warning */ - while (current != RBNIL) + while (current != RBTNIL) { - cmp = rb->comparator(data, current, rb->arg); + cmp = rbt->comparator(data, current, rbt->arg); if (cmp == 0) { /* * Found node with given key. Apply combiner. */ - rb->combiner(current, data, rb->arg); + rbt->combiner(current, data, rbt->arg); *isNew = false; return current; } @@ -418,14 +421,14 @@ rb_insert(RBTree *rb, const RBNode *data, bool *isNew) */ *isNew = true; - x = rb->allocfunc(rb->arg); + x = rbt->allocfunc(rbt->arg); - x->color = RBRED; + x->color = RBTRED; - x->left = RBNIL; - x->right = RBNIL; + x->left = RBTNIL; + x->right = RBTNIL; x->parent = parent; - rb_copy_data(rb, x, data); + rbt_copy_data(rbt, x, data); /* insert node in tree */ if (parent) @@ -437,10 +440,10 @@ rb_insert(RBTree *rb, const RBNode *data, bool *isNew) } else { - rb->root = x; + rbt->root = x; } - rb_insert_fixup(rb, x); + rbt_insert_fixup(rbt, x); return x; } @@ -453,14 +456,14 @@ rb_insert(RBTree *rb, const RBNode *data, bool *isNew) * Maintain Red-Black tree balance after deleting a black node. */ static void -rb_delete_fixup(RBTree *rb, RBNode *x) +rbt_delete_fixup(RBTree *rbt, RBTNode *x) { /* * x is always a black node. Initially, it is the former child of the * deleted node. Each iteration of this loop moves it higher up in the * tree. */ - while (x != rb->root && x->color == RBBLACK) + while (x != rbt->root && x->color == RBTBLACK) { /* * Left and right cases are symmetric. Any nodes that are children of @@ -471,93 +474,93 @@ rb_delete_fixup(RBTree *rb, RBNode *x) */ if (x == x->parent->left) { - RBNode *w = x->parent->right; + RBTNode *w = x->parent->right; - if (w->color == RBRED) + if (w->color == RBTRED) { - w->color = RBBLACK; - x->parent->color = RBRED; + w->color = RBTBLACK; + x->parent->color = RBTRED; - rb_rotate_left(rb, x->parent); + rbt_rotate_left(rbt, x->parent); w = x->parent->right; } - if (w->left->color == RBBLACK && w->right->color == RBBLACK) + if (w->left->color == RBTBLACK && w->right->color == RBTBLACK) { - w->color = RBRED; + w->color = RBTRED; x = x->parent; } else { - if (w->right->color == RBBLACK) + if (w->right->color == RBTBLACK) { - w->left->color = RBBLACK; - w->color = RBRED; + w->left->color = RBTBLACK; + w->color = RBTRED; - rb_rotate_right(rb, w); + rbt_rotate_right(rbt, w); w = x->parent->right; } w->color = x->parent->color; - x->parent->color = RBBLACK; - w->right->color = RBBLACK; + x->parent->color = RBTBLACK; + w->right->color = RBTBLACK; - rb_rotate_left(rb, x->parent); - x = rb->root; /* Arrange for loop to terminate. */ + rbt_rotate_left(rbt, x->parent); + x = rbt->root; /* Arrange for loop to terminate. */ } } else { - RBNode *w = x->parent->left; + RBTNode *w = x->parent->left; - if (w->color == RBRED) + if (w->color == RBTRED) { - w->color = RBBLACK; - x->parent->color = RBRED; + w->color = RBTBLACK; + x->parent->color = RBTRED; - rb_rotate_right(rb, x->parent); + rbt_rotate_right(rbt, x->parent); w = x->parent->left; } - if (w->right->color == RBBLACK && w->left->color == RBBLACK) + if (w->right->color == RBTBLACK && w->left->color == RBTBLACK) { - w->color = RBRED; + w->color = RBTRED; x = x->parent; } else { - if (w->left->color == RBBLACK) + if (w->left->color == RBTBLACK) { - w->right->color = RBBLACK; - w->color = RBRED; + w->right->color = RBTBLACK; + w->color = RBTRED; - rb_rotate_left(rb, w); + rbt_rotate_left(rbt, w); w = x->parent->left; } w->color = x->parent->color; - x->parent->color = RBBLACK; - w->left->color = RBBLACK; + x->parent->color = RBTBLACK; + w->left->color = RBTBLACK; - rb_rotate_right(rb, x->parent); - x = rb->root; /* Arrange for loop to terminate. */ + rbt_rotate_right(rbt, x->parent); + x = rbt->root; /* Arrange for loop to terminate. */ } } } - x->color = RBBLACK; + x->color = RBTBLACK; } /* * Delete node z from tree. */ static void -rb_delete_node(RBTree *rb, RBNode *z) +rbt_delete_node(RBTree *rbt, RBTNode *z) { - RBNode *x, + RBTNode *x, *y; /* This is just paranoia: we should only get called on a valid node */ - if (!z || z == RBNIL) + if (!z || z == RBTNIL) return; /* @@ -565,21 +568,21 @@ rb_delete_node(RBTree *rb, RBNode *z) * be z if z has fewer than two children, or the tree successor of z * otherwise. */ - if (z->left == RBNIL || z->right == RBNIL) + if (z->left == RBTNIL || z->right == RBTNIL) { - /* y has a RBNIL node as a child */ + /* y has a RBTNIL node as a child */ y = z; } else { /* find tree successor */ y = z->right; - while (y->left != RBNIL) + while (y->left != RBTNIL) y = y->left; } /* x is y's only child */ - if (y->left != RBNIL) + if (y->left != RBTNIL) x = y->left; else x = y->right; @@ -595,7 +598,7 @@ rb_delete_node(RBTree *rb, RBNode *z) } else { - rb->root = x; + rbt->root = x; } /* @@ -603,55 +606,55 @@ rb_delete_node(RBTree *rb, RBNode *z) * the data for the removed node to the one we were supposed to remove. */ if (y != z) - rb_copy_data(rb, z, y); + rbt_copy_data(rbt, z, y); /* * Removing a black node might make some paths from root to leaf contain * fewer black nodes than others, or it might make two red nodes adjacent. */ - if (y->color == RBBLACK) - rb_delete_fixup(rb, x); + if (y->color == RBTBLACK) + rbt_delete_fixup(rbt, x); /* Now we can recycle the y node */ - if (rb->freefunc) - rb->freefunc(y, rb->arg); + if (rbt->freefunc) + rbt->freefunc(y, rbt->arg); } /* - * rb_delete: remove the given tree entry + * rbt_delete: remove the given tree entry * - * "node" must have previously been found via rb_find or rb_leftmost. + * "node" must have previously been found via rbt_find or rbt_leftmost. * It is caller's responsibility to free any subsidiary data attached - * to the node before calling rb_delete. (Do *not* try to push that + * to the node before calling rbt_delete. (Do *not* try to push that * responsibility off to the freefunc, as some other physical node * may be the one actually freed!) */ void -rb_delete(RBTree *rb, RBNode *node) +rbt_delete(RBTree *rbt, RBTNode *node) { - rb_delete_node(rb, node); + rbt_delete_node(rbt, node); } /********************************************************************** * Traverse * **********************************************************************/ -static RBNode * -rb_left_right_iterator(RBTreeIterator *iter) +static RBTNode * +rbt_left_right_iterator(RBTreeIterator *iter) { if (iter->last_visited == NULL) { - iter->last_visited = iter->rb->root; - while (iter->last_visited->left != RBNIL) + iter->last_visited = iter->rbt->root; + while (iter->last_visited->left != RBTNIL) iter->last_visited = iter->last_visited->left; return iter->last_visited; } - if (iter->last_visited->right != RBNIL) + if (iter->last_visited->right != RBTNIL) { iter->last_visited = iter->last_visited->right; - while (iter->last_visited->left != RBNIL) + while (iter->last_visited->left != RBTNIL) iter->last_visited = iter->last_visited->left; return iter->last_visited; @@ -659,7 +662,7 @@ rb_left_right_iterator(RBTreeIterator *iter) for (;;) { - RBNode *came_from = iter->last_visited; + RBTNode *came_from = iter->last_visited; iter->last_visited = iter->last_visited->parent; if (iter->last_visited == NULL) @@ -678,22 +681,22 @@ rb_left_right_iterator(RBTreeIterator *iter) return iter->last_visited; } -static RBNode * -rb_right_left_iterator(RBTreeIterator *iter) +static RBTNode * +rbt_right_left_iterator(RBTreeIterator *iter) { if (iter->last_visited == NULL) { - iter->last_visited = iter->rb->root; - while (iter->last_visited->right != RBNIL) + iter->last_visited = iter->rbt->root; + while (iter->last_visited->right != RBTNIL) iter->last_visited = iter->last_visited->right; return iter->last_visited; } - if (iter->last_visited->left != RBNIL) + if (iter->last_visited->left != RBTNIL) { iter->last_visited = iter->last_visited->left; - while (iter->last_visited->right != RBNIL) + while (iter->last_visited->right != RBTNIL) iter->last_visited = iter->last_visited->right; return iter->last_visited; @@ -701,7 +704,7 @@ rb_right_left_iterator(RBTreeIterator *iter) for (;;) { - RBNode *came_from = iter->last_visited; + RBTNode *came_from = iter->last_visited; iter->last_visited = iter->last_visited->parent; if (iter->last_visited == NULL) @@ -721,33 +724,33 @@ rb_right_left_iterator(RBTreeIterator *iter) } /* - * rb_begin_iterate: prepare to traverse the tree in any of several orders + * rbt_begin_iterate: prepare to traverse the tree in any of several orders * - * After calling rb_begin_iterate, call rb_iterate repeatedly until it + * After calling rbt_begin_iterate, call rbt_iterate repeatedly until it * returns NULL or the traversal stops being of interest. * * If the tree is changed during traversal, results of further calls to - * rb_iterate are unspecified. Multiple concurrent iterators on the same + * rbt_iterate are unspecified. Multiple concurrent iterators on the same * tree are allowed. * * The iterator state is stored in the 'iter' struct. The caller should * treat it as an opaque struct. */ void -rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, RBTreeIterator *iter) +rbt_begin_iterate(RBTree *rbt, RBTOrderControl ctrl, RBTreeIterator *iter) { /* Common initialization for all traversal orders */ - iter->rb = rb; + iter->rbt = rbt; iter->last_visited = NULL; - iter->is_over = (rb->root == RBNIL); + iter->is_over = (rbt->root == RBTNIL); switch (ctrl) { case LeftRightWalk: /* visit left, then self, then right */ - iter->iterate = rb_left_right_iterator; + iter->iterate = rbt_left_right_iterator; break; case RightLeftWalk: /* visit right, then self, then left */ - iter->iterate = rb_right_left_iterator; + iter->iterate = rbt_right_left_iterator; break; default: elog(ERROR, "unrecognized rbtree iteration order: %d", ctrl); @@ -755,10 +758,10 @@ rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, RBTreeIterator *iter) } /* - * rb_iterate: return the next node in traversal order, or NULL if no more + * rbt_iterate: return the next node in traversal order, or NULL if no more */ -RBNode * -rb_iterate(RBTreeIterator *iter) +RBTNode * +rbt_iterate(RBTreeIterator *iter) { if (iter->is_over) return NULL; diff --git a/src/backend/lib/stringinfo.c b/src/backend/lib/stringinfo.c index 798a823ac9f..99c83c1549c 100644 --- a/src/backend/lib/stringinfo.c +++ b/src/backend/lib/stringinfo.c @@ -6,7 +6,7 @@ * It can be used to buffer either ordinary C strings (null-terminated text) * or arbitrary binary data. All storage is allocated with palloc(). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/lib/stringinfo.c @@ -77,12 +77,15 @@ resetStringInfo(StringInfo str) void appendStringInfo(StringInfo str, const char *fmt,...) { + int save_errno = errno; + for (;;) { va_list args; int needed; /* Try to format the data. */ + errno = save_errno; va_start(args, fmt); needed = appendStringInfoVA(str, fmt, args); va_end(args); @@ -105,6 +108,9 @@ appendStringInfo(StringInfo str, const char *fmt,...) * pass the return value to enlargeStringInfo() before trying again; see * appendStringInfo for standard usage pattern. * + * Caution: callers must be sure to preserve their entry-time errno + * when looping, in case the fmt contains "%m". + * * XXX This API is ugly, but there seems no alternative given the C spec's * restrictions on what can portably be done with va_list arguments: you have * to redo va_start before you can rescan the argument list, and we can't do diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index 3dbec23e30a..47efef0682d 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -21,4 +21,8 @@ ifeq ($(with_openssl),yes) OBJS += be-secure-openssl.o endif +ifeq ($(with_gssapi),yes) +OBJS += be-gssapi-common.o be-secure-gssapi.o +endif + include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c index 48eb531d0f0..68792cb45e7 100644 --- a/src/backend/libpq/auth-scram.c +++ b/src/backend/libpq/auth-scram.c @@ -17,6 +17,19 @@ * by the SASLprep profile, we skip the SASLprep pre-processing and use * the raw bytes in calculating the hash. * + * - If channel binding is used, the channel binding type is always + * "tls-server-end-point". The spec says the default is "tls-unique" + * (RFC 5802, section 6.1. Default Channel Binding), but there are some + * problems with that. Firstly, not all SSL libraries provide an API to + * get the TLS Finished message, required to use "tls-unique". Secondly, + * "tls-unique" is not specified for TLS v1.3, and as of this writing, + * it's not clear if there will be a replacement. We could support both + * "tls-server-end-point" and "tls-unique", but for our use case, + * "tls-unique" doesn't really have any advantages. The main advantage + * of "tls-unique" would be that it works even if the server doesn't + * have a certificate, but PostgreSQL requires a server certificate + * whenever SSL is used, anyway. + * * * The password stored in pg_authid consists of the iteration count, salt, * StoredKey and ServerKey. @@ -67,7 +80,7 @@ * general, after logging in, but let's do what we can here. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/auth-scram.c @@ -89,7 +102,6 @@ #include "libpq/crypt.h" #include "libpq/scram.h" #include "miscadmin.h" -#include "utils/backend_random.h" #include "utils/builtins.h" #include "utils/timestamp.h" @@ -111,8 +123,7 @@ typedef struct const char *username; /* username from startup packet */ Port *port; - char cbind_flag; - char *channel_binding_type; + bool channel_binding_in_use; int iterations; char *salt; /* base64-encoded */ @@ -120,6 +131,7 @@ typedef struct uint8 ServerKey[SCRAM_KEY_LEN]; /* Fields of the first message from client */ + char cbind_flag; char *client_first_message_bare; char *client_username; char *client_nonce; @@ -143,20 +155,48 @@ typedef struct char *logdetail; } scram_state; -static void read_client_first_message(scram_state *state, char *input); -static void read_client_final_message(scram_state *state, char *input); +static void read_client_first_message(scram_state *state, const char *input); +static void read_client_final_message(scram_state *state, const char *input); static char *build_server_first_message(scram_state *state); static char *build_server_final_message(scram_state *state); static bool verify_client_proof(scram_state *state); static bool verify_final_nonce(scram_state *state); -static bool parse_scram_verifier(const char *verifier, int *iterations, - char **salt, uint8 *stored_key, uint8 *server_key); static void mock_scram_verifier(const char *username, int *iterations, - char **salt, uint8 *stored_key, uint8 *server_key); + char **salt, uint8 *stored_key, uint8 *server_key); static bool is_scram_printable(char *p); static char *sanitize_char(char c); +static char *sanitize_str(const char *s); static char *scram_mock_salt(const char *username); +/* + * pg_be_scram_get_mechanisms + * + * Get a list of SASL mechanisms that this module supports. + * + * For the convenience of building the FE/BE packet that lists the + * mechanisms, the names are appended to the given StringInfo buffer, + * separated by '\0' bytes. + */ +void +pg_be_scram_get_mechanisms(Port *port, StringInfo buf) +{ + /* + * Advertise the mechanisms in decreasing order of importance. So the + * channel-binding variants go first, if they are supported. Channel + * binding is only supported with SSL, and only if the SSL implementation + * has a function to get the certificate's hash. + */ +#ifdef HAVE_BE_TLS_GET_CERTIFICATE_HASH + if (port->ssl_in_use) + { + appendStringInfoString(buf, SCRAM_SHA_256_PLUS_NAME); + appendStringInfoChar(buf, '\0'); + } +#endif + appendStringInfoString(buf, SCRAM_SHA_256_NAME); + appendStringInfoChar(buf, '\0'); +} + /* * pg_be_scram_init * @@ -164,13 +204,19 @@ static char *scram_mock_salt(const char *username); * needs to be called before doing any exchange. It will be filled later * after the beginning of the exchange with verifier data. * - * 'username' is the username provided by the client in the startup message. + * 'selected_mech' identifies the SASL mechanism that the client selected. + * It should be one of the mechanisms that we support, as returned by + * pg_be_scram_get_mechanisms(). + * * 'shadow_pass' is the role's password verifier, from pg_authid.rolpassword. - * If 'shadow_pass' is NULL, we still perform an authentication exchange, but - * it will fail, as if an incorrect password was given. + * The username was provided by the client in the startup message, and is + * available in port->user_name. If 'shadow_pass' is NULL, we still perform + * an authentication exchange, but it will fail, as if an incorrect password + * was given. */ void * pg_be_scram_init(Port *port, + const char *selected_mech, const char *shadow_pass) { scram_state *state; @@ -179,7 +225,27 @@ pg_be_scram_init(Port *port, state = (scram_state *) palloc0(sizeof(scram_state)); state->port = port; state->state = SCRAM_AUTH_INIT; - state->channel_binding_type = NULL; + + /* + * Parse the selected mechanism. + * + * Note that if we don't support channel binding, either because the SSL + * implementation doesn't support it or we're not using SSL at all, we + * would not have advertised the PLUS variant in the first place. If the + * client nevertheless tries to select it, it's a protocol violation like + * selecting any other SASL mechanism we don't support. + */ +#ifdef HAVE_BE_TLS_GET_CERTIFICATE_HASH + if (strcmp(selected_mech, SCRAM_SHA_256_PLUS_NAME) == 0 && port->ssl_in_use) + state->channel_binding_in_use = true; + else +#endif + if (strcmp(selected_mech, SCRAM_SHA_256_NAME) == 0) + state->channel_binding_in_use = false; + else + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("client selected an invalid SASL authentication mechanism"))); /* * Parse the stored password verifier. @@ -259,7 +325,7 @@ pg_be_scram_init(Port *port, * the client). */ int -pg_be_scram_exchange(void *opaq, char *input, int inputlen, +pg_be_scram_exchange(void *opaq, const char *input, int inputlen, char **output, int *outputlen, char **logdetail) { scram_state *state = (scram_state *) opaq; @@ -384,7 +450,7 @@ pg_be_scram_exchange(void *opaq, char *input, int inputlen, char * pg_be_scram_build_verifier(const char *password) { - char *prep_password = NULL; + char *prep_password; pg_saslprep_rc rc; char saltbuf[SCRAM_DEFAULT_SALT_LEN]; char *result; @@ -399,7 +465,7 @@ pg_be_scram_build_verifier(const char *password) password = (const char *) prep_password; /* Generate random salt */ - if (!pg_backend_random(saltbuf, SCRAM_DEFAULT_SALT_LEN)) + if (!pg_strong_random(saltbuf, SCRAM_DEFAULT_SALT_LEN)) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("could not generate random salt"))); @@ -430,7 +496,7 @@ scram_verify_plain_password(const char *username, const char *password, uint8 stored_key[SCRAM_KEY_LEN]; uint8 server_key[SCRAM_KEY_LEN]; uint8 computed_key[SCRAM_KEY_LEN]; - char *prep_password = NULL; + char *prep_password; pg_saslprep_rc rc; if (!parse_scram_verifier(verifier, &iterations, &encoded_salt, @@ -444,9 +510,11 @@ scram_verify_plain_password(const char *username, const char *password, return false; } - salt = palloc(pg_b64_dec_len(strlen(encoded_salt))); - saltlen = pg_b64_decode(encoded_salt, strlen(encoded_salt), salt); - if (saltlen == -1) + saltlen = pg_b64_dec_len(strlen(encoded_salt)); + salt = palloc(saltlen); + saltlen = pg_b64_decode(encoded_salt, strlen(encoded_salt), salt, + saltlen); + if (saltlen < 0) { ereport(LOG, (errmsg("invalid SCRAM verifier for user \"%s\"", username))); @@ -476,9 +544,15 @@ scram_verify_plain_password(const char *username, const char *password, /* * Parse and validate format of given SCRAM verifier. * + * On success, the iteration count, salt, stored key, and server key are + * extracted from the verifier, and returned to the caller. For 'stored_key' + * and 'server_key', the caller must pass pre-allocated buffers of size + * SCRAM_KEY_LEN. Salt is returned as a base64-encoded, null-terminated + * string. The buffer for the salt is palloc'd by this function. + * * Returns true if the SCRAM verifier has been parsed, and false otherwise. */ -static bool +bool parse_scram_verifier(const char *verifier, int *iterations, char **salt, uint8 *stored_key, uint8 *server_key) { @@ -491,6 +565,8 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt, char *serverkey_str; int decoded_len; char *decoded_salt_buf; + char *decoded_stored_buf; + char *decoded_server_buf; /* * The verifier is of form: @@ -522,8 +598,10 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt, * Verify that the salt is in Base64-encoded format, by decoding it, * although we return the encoded version to the caller. */ - decoded_salt_buf = palloc(pg_b64_dec_len(strlen(salt_str))); - decoded_len = pg_b64_decode(salt_str, strlen(salt_str), decoded_salt_buf); + decoded_len = pg_b64_dec_len(strlen(salt_str)); + decoded_salt_buf = palloc(decoded_len); + decoded_len = pg_b64_decode(salt_str, strlen(salt_str), + decoded_salt_buf, decoded_len); if (decoded_len < 0) goto invalid_verifier; *salt = pstrdup(salt_str); @@ -531,28 +609,40 @@ parse_scram_verifier(const char *verifier, int *iterations, char **salt, /* * Decode StoredKey and ServerKey. */ - if (pg_b64_dec_len(strlen(storedkey_str) != SCRAM_KEY_LEN)) - goto invalid_verifier; + decoded_len = pg_b64_dec_len(strlen(storedkey_str)); + decoded_stored_buf = palloc(decoded_len); decoded_len = pg_b64_decode(storedkey_str, strlen(storedkey_str), - (char *) stored_key); + decoded_stored_buf, decoded_len); if (decoded_len != SCRAM_KEY_LEN) goto invalid_verifier; + memcpy(stored_key, decoded_stored_buf, SCRAM_KEY_LEN); - if (pg_b64_dec_len(strlen(serverkey_str) != SCRAM_KEY_LEN)) - goto invalid_verifier; + decoded_len = pg_b64_dec_len(strlen(serverkey_str)); + decoded_server_buf = palloc(decoded_len); decoded_len = pg_b64_decode(serverkey_str, strlen(serverkey_str), - (char *) server_key); + decoded_server_buf, decoded_len); if (decoded_len != SCRAM_KEY_LEN) goto invalid_verifier; + memcpy(server_key, decoded_server_buf, SCRAM_KEY_LEN); return true; invalid_verifier: - pfree(v); *salt = NULL; return false; } +/* + * Generate plausible SCRAM verifier parameters for mock authentication. + * + * In a normal authentication, these are extracted from the verifier + * stored in the server. This function generates values that look + * realistic, for when there is no stored verifier. + * + * Like in parse_scram_verifier(), for 'stored_key' and 'server_key', the + * caller must pass pre-allocated buffers of size SCRAM_KEY_LEN, and + * the buffer for the salt is palloc'd by this function. + */ static void mock_scram_verifier(const char *username, int *iterations, char **salt, uint8 *stored_key, uint8 *server_key) @@ -564,8 +654,20 @@ mock_scram_verifier(const char *username, int *iterations, char **salt, /* Generate deterministic salt */ raw_salt = scram_mock_salt(username); - encoded_salt = (char *) palloc(pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN) + 1); - encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt); + encoded_len = pg_b64_enc_len(SCRAM_DEFAULT_SALT_LEN); + /* don't forget the zero-terminator */ + encoded_salt = (char *) palloc(encoded_len + 1); + encoded_len = pg_b64_encode(raw_salt, SCRAM_DEFAULT_SALT_LEN, encoded_salt, + encoded_len); + + /* + * Note that we cannot reveal any information to an attacker here so the + * error message needs to remain generic. This should never fail anyway + * as the salt generated for mock authentication uses the cluster's nonce + * value. + */ + if (encoded_len < 0) + elog(ERROR, "could not encode salt"); encoded_salt[encoded_len] = '\0'; *salt = encoded_salt; @@ -655,10 +757,41 @@ sanitize_char(char c) return buf; } +/* + * Convert an arbitrary string to printable form, for error messages. + * + * Anything that's not a printable ASCII character is replaced with + * '?', and the string is truncated at 30 characters. + * + * The returned pointer points to a static buffer. + */ +static char * +sanitize_str(const char *s) +{ + static char buf[30 + 1]; + int i; + + for (i = 0; i < sizeof(buf) - 1; i++) + { + char c = s[i]; + + if (c == '\0') + break; + + if (c >= 0x21 && c <= 0x7E) + buf[i] = c; + else + buf[i] = '?'; + } + buf[i] = '\0'; + return buf; +} + /* * Read the next attribute and value in a SCRAM exchange message. * - * Returns NULL if there is attribute. + * The attribute character is set in *attr_p, the attribute value is the + * return value. */ static char * read_any_attr(char **input, char *attr_p) @@ -667,6 +800,12 @@ read_any_attr(char **input, char *attr_p) char *end; char attr = *begin; + if (attr == '\0') + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("malformed SCRAM message"), + errdetail("Attribute expected, but found end of string."))); + /*------ * attr-val = ALPHA "=" value * ;; Generic syntax of any attribute sent @@ -713,9 +852,11 @@ read_any_attr(char **input, char *attr_p) * At this stage, any errors will be reported directly with ereport(ERROR). */ static void -read_client_first_message(scram_state *state, char *input) +read_client_first_message(scram_state *state, const char *input) { - input = pstrdup(input); + char *p = pstrdup(input); + char *channel_binding_type; + /*------ * The syntax for the client-first-message is: (RFC 5802) @@ -781,8 +922,8 @@ read_client_first_message(scram_state *state, char *input) * Read gs2-cbind-flag. (For details see also RFC 5802 Section 6 "Channel * Binding".) */ - state->cbind_flag = *input; - switch (*input) + state->cbind_flag = *p; + switch (*p) { case 'n': @@ -790,105 +931,99 @@ read_client_first_message(scram_state *state, char *input) * The client does not support channel binding or has simply * decided to not use it. In that case just let it go. */ - input++; - if (*input != ',') + if (state->channel_binding_in_use) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("malformed SCRAM message"), + errdetail("The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data."))); + + p++; + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Comma expected, but found character \"%s\".", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; break; case 'y': /* * The client supports channel binding and thinks that the server * does not. In this case, the server must fail authentication if - * it supports channel binding, which in this implementation is - * the case if a connection is using SSL. + * it supports channel binding. */ + if (state->channel_binding_in_use) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("malformed SCRAM message"), + errdetail("The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data."))); + +#ifdef HAVE_BE_TLS_GET_CERTIFICATE_HASH if (state->port->ssl_in_use) ereport(ERROR, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), errmsg("SCRAM channel binding negotiation error"), errdetail("The client supports SCRAM channel binding but thinks the server does not. " "However, this server does support channel binding."))); - input++; - if (*input != ',') +#endif + p++; + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Comma expected, but found character \"%s\".", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; break; case 'p': /* * The client requires channel binding. Channel binding type - * follows, e.g., "p=tls-unique". + * follows, e.g., "p=tls-server-end-point". */ - { - char *channel_binding_type; - - if (!state->port->ssl_in_use) - { - /* - * Without SSL, we don't support channel binding. - * - * RFC 5802 specifies a particular error code, - * e=server-does-support-channel-binding, for this. But - * it can only be sent in the server-final message, and we - * don't want to go through the motions of the - * authentication, knowing it will fail, just to send that - * error message. - */ - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("client requires SCRAM channel binding, but it is not supported"))); - } + if (!state->channel_binding_in_use) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + errmsg("malformed SCRAM message"), + errdetail("The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data."))); - /* - * Read value provided by client. (It is not safe to print - * the name of an unsupported binding type in the error - * message. Pranksters could print arbitrary strings into the - * log that way.) - */ - channel_binding_type = read_attr_value(&input, 'p'); - if (strcmp(channel_binding_type, SCRAM_CHANNEL_BINDING_TLS_UNIQUE) != 0 && - strcmp(channel_binding_type, SCRAM_CHANNEL_BINDING_TLS_END_POINT) != 0) - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - (errmsg("unsupported SCRAM channel-binding type")))); - - /* Save the name for handling of subsequent messages */ - state->channel_binding_type = pstrdup(channel_binding_type); - } + channel_binding_type = read_attr_value(&p, 'p'); + + /* + * The only channel binding type we support is + * tls-server-end-point. + */ + if (strcmp(channel_binding_type, "tls-server-end-point") != 0) + ereport(ERROR, + (errcode(ERRCODE_PROTOCOL_VIOLATION), + (errmsg("unsupported SCRAM channel-binding type \"%s\"", + sanitize_str(channel_binding_type))))); break; default: ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Unexpected channel-binding flag \"%s\".", - sanitize_char(*input)))); + sanitize_char(*p)))); } /* * Forbid optional authzid (authorization identity). We don't support it. */ - if (*input == 'a') + if (*p == 'a') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("client uses authorization identity, but it is not supported"))); - if (*input != ',') + if (*p != ',') ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), errdetail("Unexpected attribute \"%s\" in client-first-message.", - sanitize_char(*input)))); - input++; + sanitize_char(*p)))); + p++; - state->client_first_message_bare = pstrdup(input); + state->client_first_message_bare = pstrdup(p); /* * Any mandatory extensions would go here. We don't support any. @@ -897,7 +1032,7 @@ read_client_first_message(scram_state *state, char *input) * but it can only be sent in the server-final message. We prefer to fail * immediately (which the RFC also allows). */ - if (*input == 'm') + if (*p == 'm') ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("client requires an unsupported SCRAM extension"))); @@ -907,10 +1042,10 @@ read_client_first_message(scram_state *state, char *input) * startup message instead, still it is kept around if provided as it * proves to be useful for debugging purposes. */ - state->client_username = read_attr_value(&input, 'n'); + state->client_username = read_attr_value(&p, 'n'); /* read nonce and check that it is made of only printable characters */ - state->client_nonce = read_attr_value(&input, 'r'); + state->client_nonce = read_attr_value(&p, 'r'); if (!is_scram_printable(state->client_nonce)) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -920,8 +1055,8 @@ read_client_first_message(scram_state *state, char *input) * There can be any number of optional extensions after this. We don't * support any extensions, so ignore them. */ - while (*input != '\0') - read_any_attr(&input, NULL); + while (*p != '\0') + read_any_attr(&p, NULL); /* success! */ } @@ -1028,13 +1163,20 @@ build_server_first_message(scram_state *state) char raw_nonce[SCRAM_RAW_NONCE_LEN]; int encoded_len; - if (!pg_backend_random(raw_nonce, SCRAM_RAW_NONCE_LEN)) + if (!pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN)) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("could not generate random nonce"))); - state->server_nonce = palloc(pg_b64_enc_len(SCRAM_RAW_NONCE_LEN) + 1); - encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN, state->server_nonce); + encoded_len = pg_b64_enc_len(SCRAM_RAW_NONCE_LEN); + /* don't forget the zero-terminator */ + state->server_nonce = palloc(encoded_len + 1); + encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN, + state->server_nonce, encoded_len); + if (encoded_len < 0) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not encode random nonce"))); state->server_nonce[encoded_len] = '\0'; state->server_first_message = @@ -1050,7 +1192,7 @@ build_server_first_message(scram_state *state) * Read and parse the final message received from client. */ static void -read_client_final_message(scram_state *state, char *input) +read_client_final_message(scram_state *state, const char *input) { char attr; char *channel_binding; @@ -1059,6 +1201,7 @@ read_client_final_message(scram_state *state, char *input) *proof; char *p; char *client_proof; + int client_proof_len; begin = p = pstrdup(input); @@ -1096,8 +1239,9 @@ read_client_final_message(scram_state *state, char *input) * then followed by the actual binding data depending on the type. */ channel_binding = read_attr_value(&p, 'c'); - if (state->channel_binding_type) + if (state->channel_binding_in_use) { +#ifdef HAVE_BE_TLS_GET_CERTIFICATE_HASH const char *cbind_data = NULL; size_t cbind_data_len = 0; size_t cbind_header_len; @@ -1108,44 +1252,27 @@ read_client_final_message(scram_state *state, char *input) Assert(state->cbind_flag == 'p'); - /* - * Fetch data appropriate for channel binding type - */ - if (strcmp(state->channel_binding_type, SCRAM_CHANNEL_BINDING_TLS_UNIQUE) == 0) - { -#ifdef USE_SSL - cbind_data = be_tls_get_peer_finished(state->port, &cbind_data_len); -#endif - } - else if (strcmp(state->channel_binding_type, - SCRAM_CHANNEL_BINDING_TLS_END_POINT) == 0) - { - /* Fetch hash data of server's SSL certificate */ -#ifdef USE_SSL - cbind_data = be_tls_get_certificate_hash(state->port, - &cbind_data_len); -#endif - } - else - { - /* should not happen */ - elog(ERROR, "invalid channel binding type"); - } + /* Fetch hash data of server's SSL certificate */ + cbind_data = be_tls_get_certificate_hash(state->port, + &cbind_data_len); /* should not happen */ if (cbind_data == NULL || cbind_data_len == 0) - elog(ERROR, "empty channel binding data for channel binding type \"%s\"", - state->channel_binding_type); + elog(ERROR, "could not get server certificate hash"); - cbind_header_len = 4 + strlen(state->channel_binding_type); /* p=type,, */ + cbind_header_len = strlen("p=tls-server-end-point,,"); /* p=type,, */ cbind_input_len = cbind_header_len + cbind_data_len; cbind_input = palloc(cbind_input_len); - snprintf(cbind_input, cbind_input_len, "p=%s,,", state->channel_binding_type); + snprintf(cbind_input, cbind_input_len, "p=tls-server-end-point,,"); memcpy(cbind_input + cbind_header_len, cbind_data, cbind_data_len); - b64_message = palloc(pg_b64_enc_len(cbind_input_len) + 1); + b64_message_len = pg_b64_enc_len(cbind_input_len); + /* don't forget the zero-terminator */ + b64_message = palloc(b64_message_len + 1); b64_message_len = pg_b64_encode(cbind_input, cbind_input_len, - b64_message); + b64_message, b64_message_len); + if (b64_message_len < 0) + elog(ERROR, "could not encode channel binding data"); b64_message[b64_message_len] = '\0'; /* @@ -1156,6 +1283,10 @@ read_client_final_message(scram_state *state, char *input) ereport(ERROR, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), (errmsg("SCRAM channel binding check failed")))); +#else + /* shouldn't happen, because we checked this earlier already */ + elog(ERROR, "channel binding not supported by this build"); +#endif } else { @@ -1174,15 +1305,17 @@ read_client_final_message(scram_state *state, char *input) state->client_final_nonce = read_attr_value(&p, 'r'); - /* ignore optional extensions */ + /* ignore optional extensions, read until we find "p" attribute */ do { proof = p - 1; value = read_any_attr(&p, &attr); } while (attr != 'p'); - client_proof = palloc(pg_b64_dec_len(strlen(value))); - if (pg_b64_decode(value, strlen(value), client_proof) != SCRAM_KEY_LEN) + client_proof_len = pg_b64_dec_len(strlen(value)); + client_proof = palloc(client_proof_len); + if (pg_b64_decode(value, strlen(value), client_proof, + client_proof_len) != SCRAM_KEY_LEN) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("malformed SCRAM message"), @@ -1227,9 +1360,14 @@ build_server_final_message(scram_state *state) strlen(state->client_final_message_without_proof)); scram_HMAC_final(ServerSignature, &ctx); - server_signature_base64 = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1); + siglen = pg_b64_enc_len(SCRAM_KEY_LEN); + /* don't forget the zero-terminator */ + server_signature_base64 = palloc(siglen + 1); siglen = pg_b64_encode((const char *) ServerSignature, - SCRAM_KEY_LEN, server_signature_base64); + SCRAM_KEY_LEN, server_signature_base64, + siglen); + if (siglen < 0) + elog(ERROR, "could not encode server signature"); server_signature_base64[siglen] = '\0'; /*------ diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 3014b17a7c1..3ef0171192f 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -3,7 +3,7 @@ * auth.c * Routines to handle network authentication * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -36,7 +36,7 @@ #include "port/pg_bswap.h" #include "replication/walsender.h" #include "storage/ipc.h" -#include "utils/backend_random.h" +#include "utils/memutils.h" #include "utils/timestamp.h" @@ -45,7 +45,7 @@ *---------------------------------------------------------------- */ static void sendAuthRequest(Port *port, AuthRequest areq, const char *extradata, - int extralen); + int extralen); static void auth_failed(Port *port, int status, char *logdetail); static char *recv_password_packet(Port *port); @@ -93,8 +93,8 @@ static int auth_peer(hbaPort *port); #define PGSQL_PAM_SERVICE "postgresql" /* Service name passed to PAM */ static int CheckPAMAuth(Port *port, const char *user, const char *password); -static int pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, - struct pam_response **resp, void *appdata_ptr); +static int pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); static struct pam_conv pam_passw_conv = { &pam_passwd_conv_proc, @@ -133,8 +133,7 @@ static int CheckBSDAuth(Port *port, char *user); /* Correct header from the Platform SDK */ typedef -ULONG (*__ldap_start_tls_sA) ( - IN PLDAP ExternalHandle, +ULONG (*__ldap_start_tls_sA) (IN PLDAP ExternalHandle, OUT PULONG ServerReturnValue, OUT LDAPMessage **result, IN PLDAPControlA * ServerControls, @@ -173,12 +172,9 @@ bool pg_krb_caseins_users; *---------------------------------------------------------------- */ #ifdef ENABLE_GSS -#if defined(HAVE_GSSAPI_H) -#include -#else -#include -#endif +#include "libpq/be-gssapi-common.h" +static int pg_GSS_checkauth(Port *port); static int pg_GSS_recvauth(Port *port); #endif /* ENABLE_GSS */ @@ -192,11 +188,11 @@ typedef SECURITY_STATUS (WINAPI * QUERY_SECURITY_CONTEXT_TOKEN_FN) ( PCtxtHandle, void **); static int pg_SSPI_recvauth(Port *port); -static int pg_SSPI_make_upn(char *accountname, - size_t accountnamesize, - char *domainname, - size_t domainnamesize, - bool update_accountname); +static int pg_SSPI_make_upn(char *accountname, + size_t accountnamesize, + char *domainname, + size_t domainnamesize, + bool update_accountname); #endif /*---------------------------------------------------------------- @@ -364,7 +360,7 @@ ClientAuthentication(Port *port) * current connection, so perform any verifications based on the hba * options field that should be done *before* the authentication here. */ - if (port->hba->clientcert) + if (port->hba->clientcert != clientCertOff) { /* If we haven't loaded a root certificate store, fail */ if (!secure_loaded_verify_locations()) @@ -384,6 +380,17 @@ ClientAuthentication(Port *port) errmsg("connection requires a valid client certificate"))); } +#ifdef ENABLE_GSS + if (port->gss->enc && port->hba->auth_method != uaReject && + port->hba->auth_method != uaImplicitReject && + port->hba->auth_method != uaTrust && + port->hba->auth_method != uaGSS) + { + ereport(FATAL, (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION), + errmsg("GSSAPI encryption can only be used with gss, trust, or reject authentication methods"))); + } +#endif + /* * Now proceed to do the actual authentication check */ @@ -524,8 +531,14 @@ ClientAuthentication(Port *port) case uaGSS: #ifdef ENABLE_GSS - sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0); - status = pg_GSS_recvauth(port); + port->gss->auth = true; + if (port->gss->enc) + status = pg_GSS_checkauth(port); + else + { + sendAuthRequest(port, AUTH_REQ_GSS, NULL, 0); + status = pg_GSS_recvauth(port); + } #else Assert(false); #endif @@ -582,24 +595,32 @@ ClientAuthentication(Port *port) status = CheckLDAPAuth(port); #else Assert(false); -#endif - break; - - case uaCert: -#ifdef USE_SSL - status = CheckCertAuth(port); -#else - Assert(false); #endif break; case uaRADIUS: status = CheckRADIUSAuth(port); break; + case uaCert: + /* uaCert will be treated as if clientcert=verify-full (uaTrust) */ case uaTrust: status = STATUS_OK; break; } + if ((status == STATUS_OK && port->hba->clientcert == clientCertFull) + || port->hba->auth_method == uaCert) + { + /* + * Make sure we only check the certificate if we use the cert method + * or verify-full option. + */ +#ifdef USE_SSL + status = CheckCertAuth(port); +#else + Assert(false); +#endif + } + if (ClientAuthentication_hook) (*ClientAuthentication_hook) (port, status); @@ -835,7 +856,7 @@ CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail) errmsg("MD5 authentication is not supported when \"db_user_namespace\" is enabled"))); /* include the salt to use for computing the response */ - if (!pg_backend_random(md5Salt, 4)) + if (!pg_strong_random(md5Salt, 4)) { ereport(LOG, (errmsg("could not generate random MD5 salt"))); @@ -862,14 +883,13 @@ CheckMD5Auth(Port *port, char *shadow_pass, char **logdetail) static int CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) { - char *sasl_mechs; - char *p; + StringInfoData sasl_mechs; int mtype; StringInfoData buf; - void *scram_opaq; + void *scram_opaq = NULL; char *output = NULL; int outputlen = 0; - char *input; + const char *input; int inputlen; int result; bool initial; @@ -889,42 +909,16 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) /* * Send the SASL authentication request to user. It includes the list of - * authentication mechanisms that are supported. The order of mechanisms - * is advertised in decreasing order of importance. So the - * channel-binding variants go first, if they are supported. Channel - * binding is only supported in SSL builds. + * authentication mechanisms that are supported. */ - sasl_mechs = palloc(strlen(SCRAM_SHA_256_PLUS_NAME) + - strlen(SCRAM_SHA_256_NAME) + 3); - p = sasl_mechs; - - if (port->ssl_in_use) - { - strcpy(p, SCRAM_SHA_256_PLUS_NAME); - p += strlen(SCRAM_SHA_256_PLUS_NAME) + 1; - } - - strcpy(p, SCRAM_SHA_256_NAME); - p += strlen(SCRAM_SHA_256_NAME) + 1; + initStringInfo(&sasl_mechs); + pg_be_scram_get_mechanisms(port, &sasl_mechs); /* Put another '\0' to mark that list is finished. */ - p[0] = '\0'; + appendStringInfoChar(&sasl_mechs, '\0'); - sendAuthRequest(port, AUTH_REQ_SASL, sasl_mechs, p - sasl_mechs + 1); - pfree(sasl_mechs); - - /* - * Initialize the status tracker for message exchanges. - * - * If the user doesn't exist, or doesn't have a valid password, or it's - * expired, we still go through the motions of SASL authentication, but - * tell the authentication method that the authentication is "doomed". - * That is, it's going to fail, no matter what. - * - * This is because we don't want to reveal to an attacker what usernames - * are valid, nor which users have a valid password. - */ - scram_opaq = pg_be_scram_init(port, shadow_pass); + sendAuthRequest(port, AUTH_REQ_SASL, sasl_mechs.data, sasl_mechs.len); + pfree(sasl_mechs.data); /* * Loop through SASL message exchange. This exchange can consist of @@ -973,26 +967,33 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) const char *selected_mech; selected_mech = pq_getmsgrawstring(&buf); - if (strcmp(selected_mech, SCRAM_SHA_256_NAME) != 0 && - strcmp(selected_mech, SCRAM_SHA_256_PLUS_NAME) != 0) - { - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("client selected an invalid SASL authentication mechanism"))); - } + + /* + * Initialize the status tracker for message exchanges. + * + * If the user doesn't exist, or doesn't have a valid password, or + * it's expired, we still go through the motions of SASL + * authentication, but tell the authentication method that the + * authentication is "doomed". That is, it's going to fail, no + * matter what. + * + * This is because we don't want to reveal to an attacker what + * usernames are valid, nor which users have a valid password. + */ + scram_opaq = pg_be_scram_init(port, selected_mech, shadow_pass); inputlen = pq_getmsgint(&buf, 4); if (inputlen == -1) input = NULL; else - input = (char *) pq_getmsgbytes(&buf, inputlen); + input = pq_getmsgbytes(&buf, inputlen); initial = false; } else { inputlen = buf.len; - input = (char *) pq_getmsgbytes(&buf, buf.len); + input = pq_getmsgbytes(&buf, buf.len); } pq_getmsgend(&buf); @@ -1044,64 +1045,6 @@ CheckSCRAMAuth(Port *port, char *shadow_pass, char **logdetail) *---------------------------------------------------------------- */ #ifdef ENABLE_GSS - -#if defined(WIN32) && !defined(_MSC_VER) -/* - * MIT Kerberos GSSAPI DLL doesn't properly export the symbols for MingW - * that contain the OIDs required. Redefine here, values copied - * from src/athena/auth/krb5/src/lib/gssapi/generic/gssapi_generic.c - */ -static const gss_OID_desc GSS_C_NT_USER_NAME_desc = -{10, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"}; -static GSS_DLLIMP gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_desc; -#endif - - -static void -pg_GSS_error(int severity, const char *errmsg, OM_uint32 maj_stat, OM_uint32 min_stat) -{ - gss_buffer_desc gmsg; - OM_uint32 lmin_s, - msg_ctx; - char msg_major[128], - msg_minor[128]; - - /* Fetch major status message */ - msg_ctx = 0; - gss_display_status(&lmin_s, maj_stat, GSS_C_GSS_CODE, - GSS_C_NO_OID, &msg_ctx, &gmsg); - strlcpy(msg_major, gmsg.value, sizeof(msg_major)); - gss_release_buffer(&lmin_s, &gmsg); - - if (msg_ctx) - - /* - * More than one message available. XXX: Should we loop and read all - * messages? (same below) - */ - ereport(WARNING, - (errmsg_internal("incomplete GSS error report"))); - - /* Fetch mechanism minor status message */ - msg_ctx = 0; - gss_display_status(&lmin_s, min_stat, GSS_C_MECH_CODE, - GSS_C_NO_OID, &msg_ctx, &gmsg); - strlcpy(msg_minor, gmsg.value, sizeof(msg_minor)); - gss_release_buffer(&lmin_s, &gmsg); - - if (msg_ctx) - ereport(WARNING, - (errmsg_internal("incomplete GSS minor error report"))); - - /* - * errmsg_internal, since translation of the first part must be done - * before calling this function anyway. - */ - ereport(severity, - (errmsg_internal("%s", errmsg), - errdetail_internal("%s: %s", msg_major, msg_minor))); -} - static int pg_GSS_recvauth(Port *port) { @@ -1110,7 +1053,6 @@ pg_GSS_recvauth(Port *port) lmin_s, gflags; int mtype; - int ret; StringInfoData buf; gss_buffer_desc gbuf; @@ -1247,7 +1189,7 @@ pg_GSS_recvauth(Port *port) { gss_delete_sec_context(&lmin_s, &port->gss->ctx, GSS_C_NO_BUFFER); pg_GSS_error(ERROR, - gettext_noop("accepting GSS security context failed"), + _("accepting GSS security context failed"), maj_stat, min_stat); } @@ -1263,19 +1205,38 @@ pg_GSS_recvauth(Port *port) */ gss_release_cred(&min_stat, &port->gss->cred); } + return pg_GSS_checkauth(port); +} + +/* + * Check whether the GSSAPI-authenticated user is allowed to connect as the + * claimed username. + */ +static int +pg_GSS_checkauth(Port *port) +{ + int ret; + OM_uint32 maj_stat, + min_stat, + lmin_s; + gss_buffer_desc gbuf; /* - * GSS_S_COMPLETE indicates that authentication is now complete. - * * Get the name of the user that authenticated, and compare it to the pg * username that was specified for the connection. */ maj_stat = gss_display_name(&min_stat, port->gss->name, &gbuf, NULL); if (maj_stat != GSS_S_COMPLETE) pg_GSS_error(ERROR, - gettext_noop("retrieving GSS user name failed"), + _("retrieving GSS user name failed"), maj_stat, min_stat); + /* + * Copy the original name of the authenticated principal into our backend + * memory for display later. + */ + port->gss->princ = MemoryContextStrdup(TopMemoryContext, gbuf.value); + /* * Split the username at the realm separator */ @@ -1337,6 +1298,11 @@ pg_GSS_recvauth(Port *port) *---------------------------------------------------------------- */ #ifdef ENABLE_SSPI + +/* + * Generate an error for SSPI authentication. The caller should apply + * _() to errmsg to make it translatable. + */ static void pg_SSPI_error(int severity, const char *errmsg, SECURITY_STATUS r) { @@ -1829,14 +1795,9 @@ interpret_ident_response(const char *ident_response, /* - * Talk to the ident server on host "remote_ip_addr" and find out who - * owns the tcp connection from his port "remote_port" to port - * "local_port_addr" on host "local_ip_addr". Return the user name the - * ident server gives as "*ident_user". - * - * IP addresses and port numbers are in network byte order. - * - * But iff we're unable to get the information from ident, return false. + * Talk to the ident server on "remote_addr" and find out who + * owns the tcp connection to "local_addr" + * If the username is successfully retrieved, check the usermap. * * XXX: Using WaitLatchOrSocket() and doing a CHECK_FOR_INTERRUPTS() if the * latch was set would improve the responsiveness to timeouts/cancellations. @@ -2041,10 +2002,12 @@ auth_peer(hbaPort *port) pw = getpwuid(uid); if (!pw) { + int save_errno = errno; + ereport(LOG, (errmsg("could not look up local user ID %ld: %s", (long) uid, - errno ? strerror(errno) : _("user does not exist")))); + save_errno ? strerror(save_errno) : _("user does not exist")))); return STATUS_ERROR; } @@ -2171,18 +2134,6 @@ CheckPAMAuth(Port *port, const char *user, const char *password) { int retval; pam_handle_t *pamh = NULL; - char hostinfo[NI_MAXHOST]; - - retval = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, - hostinfo, sizeof(hostinfo), NULL, 0, - port->hba->pam_use_hostname ? 0 : NI_NUMERICHOST | NI_NUMERICSERV); - if (retval != 0) - { - ereport(WARNING, - (errmsg_internal("pg_getnameinfo_all() failed: %s", - gai_strerror(retval)))); - return STATUS_ERROR; - } /* * We can't entirely rely on PAM to pass through appdata --- it appears @@ -2197,8 +2148,8 @@ CheckPAMAuth(Port *port, const char *user, const char *password) * later used inside the PAM conversation to pass the password to the * authentication module. */ - pam_passw_conv.appdata_ptr = (char *) password; /* from password above, - * not allocated */ + pam_passw_conv.appdata_ptr = unconstify(char *, password); /* from password above, + * not allocated */ /* Optionally, one can set the service name in pg_hba.conf */ if (port->hba->pamservice && port->hba->pamservice[0] != '\0') @@ -2228,15 +2179,37 @@ CheckPAMAuth(Port *port, const char *user, const char *password) return STATUS_ERROR; } - retval = pam_set_item(pamh, PAM_RHOST, hostinfo); - - if (retval != PAM_SUCCESS) + if (port->hba->conntype != ctLocal) { - ereport(LOG, - (errmsg("pam_set_item(PAM_RHOST) failed: %s", - pam_strerror(pamh, retval)))); - pam_passwd = NULL; - return STATUS_ERROR; + char hostinfo[NI_MAXHOST]; + int flags; + + if (port->hba->pam_use_hostname) + flags = 0; + else + flags = NI_NUMERICHOST | NI_NUMERICSERV; + + retval = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen, + hostinfo, sizeof(hostinfo), NULL, 0, + flags); + if (retval != 0) + { + ereport(WARNING, + (errmsg_internal("pg_getnameinfo_all() failed: %s", + gai_strerror(retval)))); + return STATUS_ERROR; + } + + retval = pam_set_item(pamh, PAM_RHOST, hostinfo); + + if (retval != PAM_SUCCESS) + { + ereport(LOG, + (errmsg("pam_set_item(PAM_RHOST) failed: %s", + pam_strerror(pamh, retval)))); + pam_passwd = NULL; + return STATUS_ERROR; + } } retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv); @@ -2360,13 +2333,95 @@ InitializeLDAPConnection(Port *port, LDAP **ldap) } #else #ifdef HAVE_LDAP_INITIALIZE + + /* + * OpenLDAP provides a non-standard extension ldap_initialize() that takes + * a list of URIs, allowing us to request "ldaps" instead of "ldap". It + * also provides ldap_domain2hostlist() to find LDAP servers automatically + * using DNS SRV. They were introduced in the same version, so for now we + * don't have an extra configure check for the latter. + */ { - char *uri; + StringInfoData uris; + char *hostlist = NULL; + char *p; + bool append_port; - uri = psprintf("%s://%s:%d", scheme, port->hba->ldapserver, - port->hba->ldapport); - r = ldap_initialize(ldap, uri); - pfree(uri); + /* We'll build a space-separated scheme://hostname:port list here */ + initStringInfo(&uris); + + /* + * If pg_hba.conf provided no hostnames, we can ask OpenLDAP to try to + * find some by extracting a domain name from the base DN and looking + * up DSN SRV records for _ldap._tcp.. + */ + if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0') + { + char *domain; + + /* ou=blah,dc=foo,dc=bar -> foo.bar */ + if (ldap_dn2domain(port->hba->ldapbasedn, &domain)) + { + ereport(LOG, + (errmsg("could not extract domain name from ldapbasedn"))); + return STATUS_ERROR; + } + + /* Look up a list of LDAP server hosts and port numbers */ + if (ldap_domain2hostlist(domain, &hostlist)) + { + ereport(LOG, + (errmsg("LDAP authentication could not find DNS SRV records for \"%s\"", + domain), + (errhint("Set an LDAP server name explicitly.")))); + ldap_memfree(domain); + return STATUS_ERROR; + } + ldap_memfree(domain); + + /* We have a space-separated list of host:port entries */ + p = hostlist; + append_port = false; + } + else + { + /* We have a space-separated list of hosts from pg_hba.conf */ + p = port->hba->ldapserver; + append_port = true; + } + + /* Convert the list of host[:port] entries to full URIs */ + do + { + size_t size; + + /* Find the span of the next entry */ + size = strcspn(p, " "); + + /* Append a space separator if this isn't the first URI */ + if (uris.len > 0) + appendStringInfoChar(&uris, ' '); + + /* Append scheme://host:port */ + appendStringInfoString(&uris, scheme); + appendStringInfoString(&uris, "://"); + appendBinaryStringInfo(&uris, p, size); + if (append_port) + appendStringInfo(&uris, ":%d", port->hba->ldapport); + + /* Step over this entry and any number of trailing spaces */ + p += size; + while (*p == ' ') + ++p; + } while (*p); + + /* Free memory from OpenLDAP if we looked up SRV records */ + if (hostlist) + ldap_memfree(hostlist); + + /* Finally, try to connect using the URI list */ + r = ldap_initialize(ldap, uris.data); + pfree(uris.data); if (r != LDAP_SUCCESS) { ereport(LOG, @@ -2512,13 +2567,35 @@ CheckLDAPAuth(Port *port) LDAP *ldap; int r; char *fulluser; + const char *server_name; + +#ifdef HAVE_LDAP_INITIALIZE + /* + * For OpenLDAP, allow empty hostname if we have a basedn. We'll look for + * servers with DNS SRV records via OpenLDAP library facilities. + */ + if ((!port->hba->ldapserver || port->hba->ldapserver[0] == '\0') && + (!port->hba->ldapbasedn || port->hba->ldapbasedn[0] == '\0')) + { + ereport(LOG, + (errmsg("LDAP server not specified, and no ldapbasedn"))); + return STATUS_ERROR; + } +#else if (!port->hba->ldapserver || port->hba->ldapserver[0] == '\0') { ereport(LOG, (errmsg("LDAP server not specified"))); return STATUS_ERROR; } +#endif + + /* + * If we're using SRV records, we don't have a server name so we'll just + * show an empty string in error messages. + */ + server_name = port->hba->ldapserver ? port->hba->ldapserver : ""; if (port->hba->ldapport == 0) { @@ -2590,7 +2667,7 @@ CheckLDAPAuth(Port *port) ereport(LOG, (errmsg("could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s", port->hba->ldapbinddn ? port->hba->ldapbinddn : "", - port->hba->ldapserver, + server_name, ldap_err2string(r)), errdetail_for_ldap(ldap))); ldap_unbind(ldap); @@ -2618,7 +2695,7 @@ CheckLDAPAuth(Port *port) { ereport(LOG, (errmsg("could not search LDAP for filter \"%s\" on server \"%s\": %s", - filter, port->hba->ldapserver, ldap_err2string(r)), + filter, server_name, ldap_err2string(r)), errdetail_for_ldap(ldap))); ldap_unbind(ldap); pfree(passwd); @@ -2633,14 +2710,14 @@ CheckLDAPAuth(Port *port) ereport(LOG, (errmsg("LDAP user \"%s\" does not exist", port->user_name), errdetail("LDAP search for filter \"%s\" on server \"%s\" returned no entries.", - filter, port->hba->ldapserver))); + filter, server_name))); else ereport(LOG, (errmsg("LDAP user \"%s\" is not unique", port->user_name), errdetail_plural("LDAP search for filter \"%s\" on server \"%s\" returned %d entry.", "LDAP search for filter \"%s\" on server \"%s\" returned %d entries.", count, - filter, port->hba->ldapserver, count))); + filter, server_name, count))); ldap_unbind(ldap); pfree(passwd); @@ -2658,7 +2735,7 @@ CheckLDAPAuth(Port *port) (void) ldap_get_option(ldap, LDAP_OPT_ERROR_NUMBER, &error); ereport(LOG, (errmsg("could not get dn for the first entry matching \"%s\" on server \"%s\": %s", - filter, port->hba->ldapserver, + filter, server_name, ldap_err2string(error)), errdetail_for_ldap(ldap))); ldap_unbind(ldap); @@ -2679,7 +2756,7 @@ CheckLDAPAuth(Port *port) { ereport(LOG, (errmsg("could not unbind after searching for user \"%s\" on server \"%s\"", - fulluser, port->hba->ldapserver))); + fulluser, server_name))); pfree(passwd); pfree(fulluser); return STATUS_ERROR; @@ -2710,7 +2787,7 @@ CheckLDAPAuth(Port *port) { ereport(LOG, (errmsg("LDAP login failed for user \"%s\" on server \"%s\": %s", - fulluser, port->hba->ldapserver, ldap_err2string(r)), + fulluser, server_name, ldap_err2string(r)), errdetail_for_ldap(ldap))); ldap_unbind(ldap); pfree(passwd); @@ -2756,6 +2833,8 @@ errdetail_for_ldap(LDAP *ldap) static int CheckCertAuth(Port *port) { + int status_check_usermap = STATUS_ERROR; + Assert(port->ssl); /* Make sure we have received a username in the certificate */ @@ -2768,8 +2847,23 @@ CheckCertAuth(Port *port) return STATUS_ERROR; } - /* Just pass the certificate CN to the usermap check */ - return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false); + /* Just pass the certificate cn to the usermap check */ + status_check_usermap = check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false); + if (status_check_usermap != STATUS_OK) + { + /* + * If clientcert=verify-full was specified and the authentication + * method is other than uaCert, log the reason for rejecting the + * authentication. + */ + if (port->hba->clientcert == clientCertFull && port->hba->auth_method != uaCert) + { + ereport(LOG, + (errmsg("certificate validation (clientcert=verify-full) failed for user \"%s\": CN mismatch", + port->user_name))); + } + } + return status_check_usermap; } #endif @@ -2931,11 +3025,11 @@ CheckRADIUSAuth(Port *port) * don't and will then reuse the correct value. */ if (list_length(port->hba->radiussecrets) > 1) - secrets = lnext(secrets); + secrets = lnext(port->hba->radiussecrets, secrets); if (list_length(port->hba->radiusports) > 1) - radiusports = lnext(radiusports); + radiusports = lnext(port->hba->radiusports, radiusports); if (list_length(port->hba->radiusidentifiers) > 1) - identifiers = lnext(identifiers); + identifiers = lnext(port->hba->radiusidentifiers, identifiers); } /* No servers left to try, so give up */ @@ -3003,7 +3097,7 @@ PerformRadiusTransaction(const char *server, const char *secret, const char *por /* Construct RADIUS packet */ packet->code = RADIUS_ACCESS_REQUEST; packet->length = RADIUS_HEADER_LENGTH; - if (!pg_backend_random((char *) packet->vector, RADIUS_VECTOR_LENGTH)) + if (!pg_strong_random(packet->vector, RADIUS_VECTOR_LENGTH)) { ereport(LOG, (errmsg("could not generate random encryption vector"))); diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index 0b802b54e43..a750f921fa1 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -3,7 +3,7 @@ * be-fsstubs.c * Builtin functions for open/close/read/write operations on large objects * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -62,7 +62,7 @@ * A non-null entry is a pointer to a LargeObjectDesc allocated in the * LO private memory context "fscxt". The cookies array itself is also * dynamically allocated in that context. Its current allocated size is - * cookies_len entries, of which any unused entries will be NULL. + * cookies_size entries, of which any unused entries will be NULL. */ static LargeObjectDesc **cookies = NULL; static int cookies_size = 0; @@ -455,7 +455,12 @@ lo_import_internal(text *filename, Oid lobjOid) fnamebuf))); inv_close(lobj); - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + fnamebuf))); return oid; } @@ -524,7 +529,12 @@ be_lo_export(PG_FUNCTION_ARGS) fnamebuf))); } - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + fnamebuf))); + inv_close(lobj); PG_RETURN_INT32(1); diff --git a/src/backend/libpq/be-gssapi-common.c b/src/backend/libpq/be-gssapi-common.c new file mode 100644 index 00000000000..edb34026d41 --- /dev/null +++ b/src/backend/libpq/be-gssapi-common.c @@ -0,0 +1,74 @@ +/*------------------------------------------------------------------------- + * + * be-gssapi-common.c + * Common code for GSSAPI authentication and encryption + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/libpq/be-gssapi-common.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "libpq/be-gssapi-common.h" + +/* + * Helper function for getting all strings of a GSSAPI error (of specified + * stat). Call once for GSS_CODE and once for MECH_CODE. + */ +static void +pg_GSS_error_int(char *s, size_t len, OM_uint32 stat, int type) +{ + gss_buffer_desc gmsg; + size_t i = 0; + OM_uint32 lmin_s, + msg_ctx = 0; + + gmsg.value = NULL; + gmsg.length = 0; + + do + { + gss_display_status(&lmin_s, stat, type, + GSS_C_NO_OID, &msg_ctx, &gmsg); + strlcpy(s + i, gmsg.value, len - i); + i += gmsg.length; + gss_release_buffer(&lmin_s, &gmsg); + } + while (msg_ctx && i < len); + + if (msg_ctx || i == len) + ereport(WARNING, + (errmsg_internal("incomplete GSS error report"))); +} + +/* + * Fetch and report all error messages from GSSAPI. To avoid allocation, + * total error size is capped (at 128 bytes for each of major and minor). No + * known mechanisms will produce error messages beyond this cap. + */ +void +pg_GSS_error(int severity, const char *errmsg, + OM_uint32 maj_stat, OM_uint32 min_stat) +{ + char msg_major[128], + msg_minor[128]; + + /* Fetch major status message */ + pg_GSS_error_int(msg_major, sizeof(msg_major), maj_stat, GSS_C_GSS_CODE); + + /* Fetch mechanism minor status message */ + pg_GSS_error_int(msg_minor, sizeof(msg_minor), min_stat, GSS_C_MECH_CODE); + + /* + * errmsg_internal, since translation of the first part must be done + * before calling this function anyway. + */ + ereport(severity, + (errmsg_internal("%s", errmsg), + errdetail_internal("%s: %s", msg_major, msg_minor))); +} diff --git a/src/backend/libpq/be-secure-common.c b/src/backend/libpq/be-secure-common.c index 46f0b5f4a32..d801929ea28 100644 --- a/src/backend/libpq/be-secure-common.c +++ b/src/backend/libpq/be-secure-common.c @@ -8,7 +8,7 @@ * communications code calls, this file contains support routines that are * used by the library-specific implementations such as be-secure-openssl.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,6 +22,7 @@ #include #include +#include "common/string.h" #include "libpq/libpq.h" #include "storage/fd.h" @@ -86,6 +87,7 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, { if (ferror(fh)) { + explicit_bzero(buf, size); ereport(loglevel, (errcode_for_file_access(), errmsg("could not read from command \"%s\": %m", @@ -97,6 +99,7 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, pclose_rc = ClosePipeStream(fh); if (pclose_rc == -1) { + explicit_bzero(buf, size); ereport(loglevel, (errcode_for_file_access(), errmsg("could not close pipe to external command: %m"))); @@ -104,6 +107,7 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, } else if (pclose_rc != 0) { + explicit_bzero(buf, size); ereport(loglevel, (errcode_for_file_access(), errmsg("command \"%s\" failed", @@ -112,10 +116,8 @@ run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, goto error; } - /* strip trailing newline */ - len = strlen(buf); - if (buf[len - 1] == '\n') - buf[len-- -1] = '\0'; + /* strip trailing newline and carriage return */ + len = pg_strip_crlf(buf); error: pfree(command.data); @@ -130,7 +132,7 @@ bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart) { int loglevel = isServerStart ? FATAL : LOG; - struct stat buf; + struct stat buf; if (stat(ssl_key_file, &buf) != 0) { diff --git a/src/backend/libpq/be-secure-gssapi.c b/src/backend/libpq/be-secure-gssapi.c new file mode 100644 index 00000000000..a0855a9401e --- /dev/null +++ b/src/backend/libpq/be-secure-gssapi.c @@ -0,0 +1,639 @@ +/*------------------------------------------------------------------------- + * + * be-secure-gssapi.c + * GSSAPI encryption support + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/backend/libpq/be-secure-gssapi.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include + +#include "libpq/auth.h" +#include "libpq/be-gssapi-common.h" +#include "libpq/libpq.h" +#include "libpq/pqformat.h" +#include "miscadmin.h" +#include "pgstat.h" + + +/* + * Handle the encryption/decryption of data using GSSAPI. + * + * In the encrypted data stream on the wire, we break up the data + * into packets where each packet starts with a sizeof(uint32)-byte + * length (not allowed to be larger than the buffer sizes defined + * below) and then the encrypted data of that length immediately + * following. + * + * Encrypted data typically ends up being larger than the same data + * unencrypted, so we use fixed-size buffers for handling the + * encryption/decryption which are larger than PQComm's buffer will + * typically be to minimize the times where we have to make multiple + * packets and therefore sets of recv/send calls for a single + * read/write call to us. + * + * NOTE: The client and server have to agree on the max packet size, + * because we have to pass an entire packet to GSSAPI at a time and we + * don't want the other side to send arbitrairly huge packets as we + * would have to allocate memory for them to then pass them to GSSAPI. + */ +#define PQ_GSS_SEND_BUFFER_SIZE 16384 +#define PQ_GSS_RECV_BUFFER_SIZE 16384 + +/* PqGSSSendBuffer is for *encrypted* data */ +static char PqGSSSendBuffer[PQ_GSS_SEND_BUFFER_SIZE]; +static int PqGSSSendPointer; /* Next index to store a byte in + * PqGSSSendBuffer */ +static int PqGSSSendStart; /* Next index to send a byte in + * PqGSSSendBuffer */ + +/* PqGSSRecvBuffer is for *encrypted* data */ +static char PqGSSRecvBuffer[PQ_GSS_RECV_BUFFER_SIZE]; +static int PqGSSRecvLength; /* End of data available in PqGSSRecvBuffer */ + +/* PqGSSResultBuffer is for *unencrypted* data */ +static char PqGSSResultBuffer[PQ_GSS_RECV_BUFFER_SIZE]; +static int PqGSSResultPointer; /* Next index to read a byte from + * PqGSSResultBuffer */ +static int PqGSSResultLength; /* End of data available in PqGSSResultBuffer */ + +uint32 max_packet_size; /* Maximum size we can encrypt and fit the + * results into our output buffer */ + +/* + * Attempt to write len bytes of data from ptr along a GSSAPI-encrypted connection. + * + * Connection must be fully established (including authentication step) before + * calling. Returns the bytes actually consumed once complete. Data is + * internally buffered; in the case of an incomplete write, the amount of data we + * processed (encrypted into our output buffer to be sent) will be returned. If + * an error occurs or we would block, a negative value is returned and errno is + * set appropriately. + * + * To continue writing in the case of EWOULDBLOCK and similar, call this function + * again with matching ptr and len parameters. + */ +ssize_t +be_gssapi_write(Port *port, void *ptr, size_t len) +{ + size_t bytes_to_encrypt = len; + size_t bytes_encrypted = 0; + + /* + * Loop through encrypting data and sending it out until + * secure_raw_write() complains (which would likely mean that the socket + * is non-blocking and the requested send() would block, or there was some + * kind of actual error) and then return. + */ + while (bytes_to_encrypt || PqGSSSendPointer) + { + OM_uint32 major, + minor; + gss_buffer_desc input, + output; + int conf_state = 0; + uint32 netlen; + pg_gssinfo *gss = port->gss; + + /* + * Check if we have data in the encrypted output buffer that needs to + * be sent, and if so, try to send it. If we aren't able to, return + * that back up to the caller. + */ + if (PqGSSSendPointer) + { + ssize_t ret; + ssize_t amount = PqGSSSendPointer - PqGSSSendStart; + + ret = secure_raw_write(port, PqGSSSendBuffer + PqGSSSendStart, amount); + if (ret <= 0) + { + /* + * If we encrypted some data and it's in our output buffer, + * but send() is saying that we would block, then tell the + * caller how far we got with encrypting the data so that they + * can call us again with whatever is left, at which point we + * will try to send the remaining encrypted data first and + * then move on to encrypting the rest of the data. + */ + if (bytes_encrypted != 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) + return bytes_encrypted; + else + return ret; + } + + /* + * Check if this was a partial write, and if so, move forward that + * far in our buffer and try again. + */ + if (ret != amount) + { + PqGSSSendStart += ret; + continue; + } + + /* All encrypted data was sent, our buffer is empty now. */ + PqGSSSendPointer = PqGSSSendStart = 0; + } + + /* + * Check if there are any bytes left to encrypt. If not, we're done. + */ + if (!bytes_to_encrypt) + return bytes_encrypted; + + /* + * max_packet_size is the maximum amount of unencrypted data that, + * when encrypted, will fit into our encrypted-data output buffer. + * + * If we are being asked to send more than max_packet_size unencrypted + * data, then we will loop and create multiple packets, each with + * max_packet_size unencrypted data encrypted in them (at least, until + * secure_raw_write returns a failure saying we would be blocked, at + * which point we will let the caller know how far we got). + */ + if (bytes_to_encrypt > max_packet_size) + input.length = max_packet_size; + else + input.length = bytes_to_encrypt; + + input.value = (char *) ptr + bytes_encrypted; + + output.value = NULL; + output.length = 0; + + /* Create the next encrypted packet */ + major = gss_wrap(&minor, gss->ctx, 1, GSS_C_QOP_DEFAULT, + &input, &conf_state, &output); + if (major != GSS_S_COMPLETE) + pg_GSS_error(FATAL, gettext_noop("GSSAPI wrap error"), major, minor); + + if (conf_state == 0) + ereport(FATAL, + (errmsg("outgoing GSSAPI message would not use confidentiality"))); + + if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) + ereport(FATAL, + (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)", + (size_t) output.length, + PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)))); + + bytes_encrypted += input.length; + bytes_to_encrypt -= input.length; + + /* 4 network-order length bytes, then payload */ + netlen = htonl(output.length); + memcpy(PqGSSSendBuffer + PqGSSSendPointer, &netlen, sizeof(uint32)); + PqGSSSendPointer += sizeof(uint32); + + memcpy(PqGSSSendBuffer + PqGSSSendPointer, output.value, output.length); + PqGSSSendPointer += output.length; + } + + return bytes_encrypted; +} + +/* + * Read up to len bytes from a GSSAPI-encrypted connection into ptr. Call + * only after the connection has been fully established (i.e., GSSAPI + * authentication is complete). On success, returns the number of bytes + * written into ptr; otherwise, returns -1 and sets errno appropriately. + */ +ssize_t +be_gssapi_read(Port *port, void *ptr, size_t len) +{ + OM_uint32 major, + minor; + gss_buffer_desc input, + output; + ssize_t ret; + size_t bytes_to_return = len; + size_t bytes_returned = 0; + int conf_state = 0; + pg_gssinfo *gss = port->gss; + + /* + * The goal here is to read an incoming encrypted packet, one at a time, + * decrypt it into our out buffer, returning to the caller what they asked + * for, and then saving anything else for the next call. + * + * First we look to see if we have unencrypted bytes available and, if so, + * copy those to the result. If the caller asked for more than we had + * immediately available, then we try to read a packet off the wire and + * decrypt it. If the read would block, then return the amount of + * unencrypted data we copied into the caller's ptr. + */ + while (bytes_to_return) + { + /* Check if we have data in our buffer that we can return immediately */ + if (PqGSSResultPointer < PqGSSResultLength) + { + int bytes_in_buffer = PqGSSResultLength - PqGSSResultPointer; + int bytes_to_copy = bytes_in_buffer < len - bytes_returned ? bytes_in_buffer : len - bytes_returned; + + /* + * Copy the data from our output buffer into the caller's buffer, + * at the point where we last left off filling their buffer + */ + memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultPointer, bytes_to_copy); + PqGSSResultPointer += bytes_to_copy; + bytes_to_return -= bytes_to_copy; + bytes_returned += bytes_to_copy; + + /* Check if our result buffer is now empty and, if so, reset */ + if (PqGSSResultPointer == PqGSSResultLength) + PqGSSResultPointer = PqGSSResultLength = 0; + + continue; + } + + /* + * At this point, our output buffer should be empty with more bytes + * being requested to be read. We are now ready to load the next + * packet and decrypt it (entirely) into our buffer. + * + * If we get a partial read back while trying to read a packet off the + * wire then we return the number of unencrypted bytes we were able to + * copy (if any, if we didn't copy any, then we return whatever + * secure_raw_read returned when we called it; likely -1) into the + * caller's ptr and wait to be called again, until we get a full + * packet to decrypt. + */ + + /* Check if we have the size of the packet already in our buffer. */ + if (PqGSSRecvLength < sizeof(uint32)) + { + /* + * We were not able to get the length of the packet last time, so + * we need to do that first. + */ + ret = secure_raw_read(port, PqGSSRecvBuffer + PqGSSRecvLength, + sizeof(uint32) - PqGSSRecvLength); + if (ret < 0) + return bytes_returned ? bytes_returned : ret; + + PqGSSRecvLength += ret; + + /* + * If we only got part of the packet length, then return however + * many unencrypted bytes we copied to the caller and wait to be + * called again. + */ + if (PqGSSRecvLength < sizeof(uint32)) + return bytes_returned; + } + + /* + * We have the length of the next packet at this point, so pull it out + * and then read whatever we have left of the packet to read. + */ + input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + + /* Check for over-length packet */ + if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)) + ereport(FATAL, + (errmsg("oversize GSSAPI packet sent by the client (%zu > %zu)", + (size_t) input.length, + PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)))); + + /* + * Read as much of the packet as we are able to on this call into + * wherever we left off from the last time we were called. + */ + ret = secure_raw_read(port, PqGSSRecvBuffer + PqGSSRecvLength, + input.length - (PqGSSRecvLength - sizeof(uint32))); + if (ret < 0) + return bytes_returned ? bytes_returned : ret; + + PqGSSRecvLength += ret; + + /* + * If we got less than the rest of the packet then we need to return + * and be called again. If we didn't have any bytes to return on this + * run then return -1 and set errno to EWOULDBLOCK. + */ + if (PqGSSRecvLength - sizeof(uint32) < input.length) + { + if (!bytes_returned) + { + errno = EWOULDBLOCK; + return -1; + } + + return bytes_returned; + } + + /* + * We now have the full packet and we can perform the decryption and + * refill our output buffer, then loop back up to pass that back to + * the user. + */ + output.value = NULL; + output.length = 0; + input.value = PqGSSRecvBuffer + sizeof(uint32); + + major = gss_unwrap(&minor, gss->ctx, &input, &output, &conf_state, NULL); + if (major != GSS_S_COMPLETE) + pg_GSS_error(FATAL, gettext_noop("GSSAPI unwrap error"), + major, minor); + + if (conf_state == 0) + ereport(FATAL, + (errmsg("incoming GSSAPI message did not use confidentiality"))); + + memcpy(PqGSSResultBuffer, output.value, output.length); + + PqGSSResultLength = output.length; + + /* Our buffer is now empty, reset it */ + PqGSSRecvLength = 0; + + gss_release_buffer(&minor, &output); + } + + return bytes_returned; +} + +/* + * Read the specified number of bytes off the wire, waiting using + * WaitLatchOrSocket if we would block. + * + * Results are read into PqGSSRecvBuffer. + * + * Will always return either -1, to indicate a permanent error, or len. + */ +static ssize_t +read_or_wait(Port *port, ssize_t len) +{ + ssize_t ret; + + /* + * Keep going until we either read in everything we were asked to, or we + * error out. + */ + while (PqGSSRecvLength != len) + { + ret = secure_raw_read(port, PqGSSRecvBuffer + PqGSSRecvLength, len - PqGSSRecvLength); + + /* + * If we got back an error and it wasn't just EWOULDBLOCK/EAGAIN, then + * give up. + */ + if (ret < 0 && !(errno == EWOULDBLOCK || errno == EAGAIN)) + return -1; + + /* + * Ok, we got back either a positive value, zero, or a negative result + * but EWOULDBLOCK or EAGAIN was set. + * + * If it was zero or negative, then we try to wait on the socket to be + * readable again. + */ + if (ret <= 0) + { + /* + * If we got back less than zero, indicating an error, and that + * wasn't just a EWOULDBLOCK/EAGAIN, then give up. + */ + if (ret < 0 && !(errno == EWOULDBLOCK || errno == EAGAIN)) + return -1; + + /* + * We got back either zero, or -1 with EWOULDBLOCK/EAGAIN, so wait + * on socket to be readable again. + */ + WaitLatchOrSocket(MyLatch, + WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH, + port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER); + + /* + * If we got back zero bytes, and then waited on the socket to be + * readable and got back zero bytes on a second read, then this is + * EOF and the client hung up on us. + * + * If we did get data here, then we can just fall through and + * handle it just as if we got data the first time. + * + * Otherwise loop back to the top and try again. + */ + if (ret == 0) + { + ret = secure_raw_read(port, PqGSSRecvBuffer + PqGSSRecvLength, len - PqGSSRecvLength); + if (ret == 0) + return -1; + } + else + continue; + } + + PqGSSRecvLength += ret; + } + + return len; +} + +/* + * Start up a GSSAPI-encrypted connection. This performs GSSAPI + * authentication; after this function completes, it is safe to call + * be_gssapi_read and be_gssapi_write. Returns -1 and logs on failure; + * otherwise, returns 0 and marks the connection as ready for GSSAPI + * encryption. + * + * Note that unlike the be_gssapi_read/be_gssapi_write functions, this + * function WILL block on the socket to be ready for read/write (using + * WaitLatchOrSocket) as appropriate while establishing the GSSAPI + * session. + */ +ssize_t +secure_open_gssapi(Port *port) +{ + bool complete_next = false; + OM_uint32 major, + minor; + + /* initialize state variables */ + PqGSSSendPointer = PqGSSSendStart = PqGSSRecvLength = PqGSSResultPointer = PqGSSResultLength = 0; + + /* + * Use the configured keytab, if there is one. Unfortunately, Heimdal + * doesn't support the cred store extensions, so use the env var. + */ + if (pg_krb_server_keyfile != NULL && strlen(pg_krb_server_keyfile) > 0) + setenv("KRB5_KTNAME", pg_krb_server_keyfile, 1); + + while (true) + { + ssize_t ret; + gss_buffer_desc input, + output = GSS_C_EMPTY_BUFFER; + + /* + * The client always sends first, so try to go ahead and read the + * length and wait on the socket to be readable again if that fails. + */ + ret = read_or_wait(port, sizeof(uint32)); + if (ret < 0) + return ret; + + /* + * Get the length for this packet from the length header. + */ + input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + + /* Done with the length, reset our buffer */ + PqGSSRecvLength = 0; + + /* + * During initialization, packets are always fully consumed and + * shouldn't ever be over PQ_GSS_RECV_BUFFER_SIZE in length. + * + * Verify on our side that the client doesn't do something funny. + */ + if (input.length > PQ_GSS_RECV_BUFFER_SIZE) + ereport(FATAL, + (errmsg("oversize GSSAPI packet sent by the client (%zu > %d)", + (size_t) input.length, + PQ_GSS_RECV_BUFFER_SIZE))); + + /* + * Get the rest of the packet so we can pass it to GSSAPI to accept + * the context. + */ + ret = read_or_wait(port, input.length); + if (ret < 0) + return ret; + + input.value = PqGSSRecvBuffer; + + /* Process incoming data. (The client sends first.) */ + major = gss_accept_sec_context(&minor, &port->gss->ctx, + GSS_C_NO_CREDENTIAL, &input, + GSS_C_NO_CHANNEL_BINDINGS, + &port->gss->name, NULL, &output, NULL, + NULL, NULL); + if (GSS_ERROR(major)) + { + pg_GSS_error(ERROR, gettext_noop("could not accept GSSAPI security context"), + major, minor); + gss_release_buffer(&minor, &output); + return -1; + } + else if (!(major & GSS_S_CONTINUE_NEEDED)) + { + /* + * rfc2744 technically permits context negotiation to be complete + * both with and without a packet to be sent. + */ + complete_next = true; + } + + /* Done handling the incoming packet, reset our buffer */ + PqGSSRecvLength = 0; + + /* + * Check if we have data to send and, if we do, make sure to send it + * all + */ + if (output.length != 0) + { + uint32 netlen = htonl(output.length); + + if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) + ereport(FATAL, + (errmsg("server tried to send oversize GSSAPI packet (%zu > %zu)", + (size_t) output.length, + PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)))); + + memcpy(PqGSSSendBuffer, (char *) &netlen, sizeof(uint32)); + PqGSSSendPointer += sizeof(uint32); + + memcpy(PqGSSSendBuffer + PqGSSSendPointer, output.value, output.length); + PqGSSSendPointer += output.length; + + while (PqGSSSendStart != sizeof(uint32) + output.length) + { + ret = secure_raw_write(port, PqGSSSendBuffer + PqGSSSendStart, sizeof(uint32) + output.length - PqGSSSendStart); + if (ret <= 0) + { + WaitLatchOrSocket(MyLatch, + WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH, + port->sock, 0, WAIT_EVENT_GSS_OPEN_SERVER); + continue; + } + + PqGSSSendStart += ret; + } + + /* Done sending the packet, reset our buffer */ + PqGSSSendStart = PqGSSSendPointer = 0; + + gss_release_buffer(&minor, &output); + } + + /* + * If we got back that the connection is finished being set up, now + * that's we've sent the last packet, exit our loop. + */ + if (complete_next) + break; + } + + /* + * Determine the max packet size which will fit in our buffer, after + * accounting for the length + */ + major = gss_wrap_size_limit(&minor, port->gss->ctx, 1, GSS_C_QOP_DEFAULT, + PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32), &max_packet_size); + + if (GSS_ERROR(major)) + pg_GSS_error(FATAL, gettext_noop("GSSAPI size check error"), + major, minor); + + port->gss->enc = true; + + return 0; +} + +/* + * Return if GSSAPI authentication was used on this connection. + */ +bool +be_gssapi_get_auth(Port *port) +{ + if (!port || !port->gss) + return false; + + return port->gss->auth; +} + +/* + * Return if GSSAPI encryption is enabled and being used on this connection. + */ +bool +be_gssapi_get_enc(Port *port) +{ + if (!port || !port->gss) + return false; + + return port->gss->enc; +} + +/* + * Return the GSSAPI principal used for authentication on this connection. + */ +const char * +be_gssapi_get_princ(Port *port) +{ + if (!port || !port->gss->auth) + return NULL; + + return port->gss->princ; +} diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 54cb352b8f3..629919cc6e1 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -4,7 +4,7 @@ * functions for OpenSSL support in the backend. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -67,6 +67,13 @@ static bool SSL_initialized = false; static bool dummy_ssl_passwd_cb_called = false; static bool ssl_is_server_start; +static int ssl_protocol_version_to_openssl(int v, const char *guc_name, + int loglevel); +#ifndef SSL_CTX_set_min_proto_version +static int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version); +static int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); +#endif + /* ------------------------------------------------------------ */ /* Public interface */ @@ -125,6 +132,7 @@ be_tls_init(bool isServerStart) if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload) SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb); else + /* * If reloading and no external command is configured, override * OpenSSL's default handling of passphrase-protected files, @@ -182,11 +190,40 @@ be_tls_init(bool isServerStart) goto error; } - /* disallow SSL v2/v3 */ - SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + if (ssl_min_protocol_version) + { + int ssl_ver = ssl_protocol_version_to_openssl(ssl_min_protocol_version, + "ssl_min_protocol_version", + isServerStart ? FATAL : LOG); + + if (ssl_ver == -1) + goto error; + if (!SSL_CTX_set_min_proto_version(context, ssl_ver)) + { + ereport(isServerStart ? FATAL : LOG, + (errmsg("could not set minimum SSL protocol version"))); + goto error; + } + } + + if (ssl_max_protocol_version) + { + int ssl_ver = ssl_protocol_version_to_openssl(ssl_max_protocol_version, + "ssl_max_protocol_version", + isServerStart ? FATAL : LOG); + + if (ssl_ver == -1) + goto error; + if (!SSL_CTX_set_max_proto_version(context, ssl_ver)) + { + ereport(isServerStart ? FATAL : LOG, + (errmsg("could not set maximum SSL protocol version"))); + goto error; + } + } /* disallow SSL session tickets */ -#ifdef SSL_OP_NO_TICKET /* added in openssl 0.9.8f */ +#ifdef SSL_OP_NO_TICKET /* added in OpenSSL 0.9.8f */ SSL_CTX_set_options(context, SSL_OP_NO_TICKET); #endif @@ -242,17 +279,8 @@ be_tls_init(bool isServerStart) /* Set the flags to check against the complete CRL chain */ if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1) { - /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ -#ifdef X509_V_FLAG_CRL_CHECK X509_STORE_set_flags(cvstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); -#else - ereport(LOG, - (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("SSL certificate revocation list file \"%s\" ignored", - ssl_crl_file), - errdetail("SSL library does not support certificate revocation lists."))); -#endif } else { @@ -393,12 +421,12 @@ be_tls_open_server(Port *port) * StartupPacketTimeoutHandler() which directly exits. */ if (err == SSL_ERROR_WANT_READ) - waitfor = WL_SOCKET_READABLE; + waitfor = WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH; else - waitfor = WL_SOCKET_WRITEABLE; + waitfor = WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH; - WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0, - WAIT_EVENT_SSL_OPEN_SERVER); + (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0, + WAIT_EVENT_SSL_OPEN_SERVER); goto aloop; case SSL_ERROR_SYSCALL: if (r < 0) @@ -637,7 +665,7 @@ be_tls_write(Port *port, void *ptr, size_t len, int *waitfor) * Private substitute BIO: this does the sending and receiving using send() and * recv() instead. This is so that we can enable and disable interrupts * just while calling recv(). We cannot have interrupts occurring while - * the bulk of openssl runs, because it uses malloc() and possibly other + * the bulk of OpenSSL runs, because it uses malloc() and possibly other * non-reentrant libc facilities. We also need to call send() and recv() * directly so it gets passed through the socket/signals layer on Win32. * @@ -735,7 +763,7 @@ my_BIO_s_socket(void) return my_bio_methods; } -/* This should exactly match openssl's SSL_set_fd except for using my BIO */ +/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */ static int my_SSL_set_fd(Port *port, int fd) { @@ -841,7 +869,7 @@ load_dh_buffer(const char *buffer, size_t len) BIO *bio; DH *dh = NULL; - bio = BIO_new_mem_buf((char *) buffer, len); + bio = BIO_new_mem_buf(unconstify(char *, buffer), len); if (bio == NULL) return NULL; dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); @@ -955,8 +983,8 @@ info_cb(const SSL *ssl, int type, int args) * precomputed. * * Since few sites will bother to create a parameter file, we also - * also provide a fallback to the parameters provided by the - * OpenSSL project. + * provide a fallback to the parameters provided by the OpenSSL + * project. * * These values can be static (once loaded or computed) since the * OpenSSL library can efficiently generate random keys from the @@ -1096,7 +1124,7 @@ be_tls_get_cipher(Port *port) } void -be_tls_get_peerdn_name(Port *port, char *ptr, size_t len) +be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len) { if (port->peer) strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len); @@ -1104,28 +1132,40 @@ be_tls_get_peerdn_name(Port *port, char *ptr, size_t len) ptr[0] = '\0'; } -char * -be_tls_get_peer_finished(Port *port, size_t *len) +void +be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len) { - char dummy[1]; - char *result; + if (port->peer) + strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len); + else + ptr[0] = '\0'; +} - /* - * OpenSSL does not offer an API to directly get the length of the - * expected TLS Finished message, so just do a dummy call to grab this - * information to allow caller to do an allocation with a correct size. - */ - *len = SSL_get_peer_finished(port->ssl, dummy, sizeof(dummy)); - result = palloc(*len); - (void) SSL_get_peer_finished(port->ssl, result, *len); +void +be_tls_get_peer_serial(Port *port, char *ptr, size_t len) +{ + if (port->peer) + { + ASN1_INTEGER *serial; + BIGNUM *b; + char *decimal; - return result; + serial = X509_get_serialNumber(port->peer); + b = ASN1_INTEGER_to_BN(serial, NULL); + decimal = BN_bn2dec(b); + + BN_free(b); + strlcpy(ptr, decimal, len); + OPENSSL_free(decimal); + } + else + ptr[0] = '\0'; } +#ifdef HAVE_X509_GET_SIGNATURE_NID char * be_tls_get_certificate_hash(Port *port, size_t *len) { -#ifdef HAVE_X509_GET_SIGNATURE_NID X509 *server_cert; char *cert_hash; const EVP_MD *algo_type = NULL; @@ -1139,8 +1179,8 @@ be_tls_get_certificate_hash(Port *port, size_t *len) return NULL; /* - * Get the signature algorithm of the certificate to determine the - * hash algorithm to use for the result. + * Get the signature algorithm of the certificate to determine the hash + * algorithm to use for the result. */ if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert), &algo_nid, NULL)) @@ -1175,13 +1215,8 @@ be_tls_get_certificate_hash(Port *port, size_t *len) *len = hash_size; return cert_hash; -#else - ereport(ERROR, - (errcode(ERRCODE_PROTOCOL_VIOLATION), - errmsg("channel binding type \"tls-server-end-point\" is not supported by this build"))); - return NULL; -#endif } +#endif /* * Convert an X509 subject name to a cstring. @@ -1231,3 +1266,143 @@ X509_NAME_to_cstring(X509_NAME *name) return result; } + +/* + * Convert TLS protocol version GUC enum to OpenSSL values + * + * This is a straightforward one-to-one mapping, but doing it this way makes + * guc.c independent of OpenSSL availability and version. + * + * If a version is passed that is not supported by the current OpenSSL + * version, then we log with the given loglevel and return (if we return) -1. + * If a nonnegative value is returned, subsequent code can assume it's working + * with a supported version. + */ +static int +ssl_protocol_version_to_openssl(int v, const char *guc_name, int loglevel) +{ + switch (v) + { + case PG_TLS_ANY: + return 0; + case PG_TLS1_VERSION: + return TLS1_VERSION; + case PG_TLS1_1_VERSION: +#ifdef TLS1_1_VERSION + return TLS1_1_VERSION; +#else + break; +#endif + case PG_TLS1_2_VERSION: +#ifdef TLS1_2_VERSION + return TLS1_2_VERSION; +#else + break; +#endif + case PG_TLS1_3_VERSION: +#ifdef TLS1_3_VERSION + return TLS1_3_VERSION; +#else + break; +#endif + } + + ereport(loglevel, + (errmsg("%s setting %s not supported by this build", + guc_name, + GetConfigOption(guc_name, false, false)))); + return -1; +} + +/* + * Replacements for APIs present in newer versions of OpenSSL + */ +#ifndef SSL_CTX_set_min_proto_version + +/* + * OpenSSL versions that support TLS 1.3 shouldn't get here because they + * already have these functions. So we don't have to keep updating the below + * code for every new TLS version, and eventually it can go away. But let's + * just check this to make sure ... + */ +#ifdef TLS1_3_VERSION +#error OpenSSL version mismatch +#endif + +static int +SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) +{ + int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; + + if (version > TLS1_VERSION) + ssl_options |= SSL_OP_NO_TLSv1; + /* + * Some OpenSSL versions define TLS*_VERSION macros but not the + * corresponding SSL_OP_NO_* macro, so in those cases we have to return + * unsuccessfully here. + */ +#ifdef TLS1_1_VERSION + if (version > TLS1_1_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_1 + ssl_options |= SSL_OP_NO_TLSv1_1; +#else + return 0; +#endif + } +#endif +#ifdef TLS1_2_VERSION + if (version > TLS1_2_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_2 + ssl_options |= SSL_OP_NO_TLSv1_2; +#else + return 0; +#endif + } +#endif + + SSL_CTX_set_options(ctx, ssl_options); + + return 1; /* success */ +} + +static int +SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) +{ + int ssl_options = 0; + + AssertArg(version != 0); + + /* + * Some OpenSSL versions define TLS*_VERSION macros but not the + * corresponding SSL_OP_NO_* macro, so in those cases we have to return + * unsuccessfully here. + */ +#ifdef TLS1_1_VERSION + if (version < TLS1_1_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_1 + ssl_options |= SSL_OP_NO_TLSv1_1; +#else + return 0; +#endif + } +#endif +#ifdef TLS1_2_VERSION + if (version < TLS1_2_VERSION) + { +#ifdef SSL_OP_NO_TLSv1_2 + ssl_options |= SSL_OP_NO_TLSv1_2; +#else + return 0; +#endif + } +#endif + + SSL_CTX_set_options(ctx, ssl_options); + + return 1; /* success */ +} + +#endif /* !SSL_CTX_set_min_proto_version */ diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c index edfe2c0751c..b90eb0ab6b7 100644 --- a/src/backend/libpq/be-secure.c +++ b/src/backend/libpq/be-secure.c @@ -6,7 +6,7 @@ * message integrity and endpoint authentication. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -38,6 +38,7 @@ #include "storage/proc.h" +char *ssl_library; char *ssl_cert_file; char *ssl_key_file; char *ssl_ca_file; @@ -59,6 +60,9 @@ char *SSLECDHCurve; /* GUC variable: if false, prefer client ciphers */ bool SSLPreferServerCiphers; +int ssl_min_protocol_version; +int ssl_max_protocol_version; + /* ------------------------------------------------------------ */ /* Procedures common to all secure sessions */ /* ------------------------------------------------------------ */ @@ -144,6 +148,9 @@ secure_read(Port *port, void *ptr, size_t len) ssize_t n; int waitfor; + /* Deal with any already-pending interrupt condition. */ + ProcessClientReadInterrupt(false); + retry: #ifdef USE_SSL waitfor = 0; @@ -152,6 +159,14 @@ secure_read(Port *port, void *ptr, size_t len) n = be_tls_read(port, ptr, len, &waitfor); } else +#endif +#ifdef ENABLE_GSS + if (port->gss->enc) + { + n = be_gssapi_read(port, ptr, len); + waitfor = WL_SOCKET_READABLE; + } + else #endif { n = secure_raw_read(port, ptr, len); @@ -173,7 +188,7 @@ secure_read(Port *port, void *ptr, size_t len) /* * If the postmaster has died, it's not safe to continue running, * because it is the postmaster's job to kill us if some other backend - * exists uncleanly. Moreover, we won't run very well in this state; + * exits uncleanly. Moreover, we won't run very well in this state; * helper processes like walwriter and the bgwriter will exit, so * performance may be poor. Finally, if we don't exit, pg_ctl will be * unable to restart the postmaster without manual intervention, so no @@ -208,9 +223,8 @@ secure_read(Port *port, void *ptr, size_t len) } /* - * Process interrupts that happened while (or before) receiving. Note that - * we signal that we're not blocking, which will prevent some types of - * interrupts from being processed. + * Process interrupts that happened during a successful (or non-blocking, + * or hard-failed) read. */ ProcessClientReadInterrupt(false); @@ -247,6 +261,9 @@ secure_write(Port *port, void *ptr, size_t len) ssize_t n; int waitfor; + /* Deal with any already-pending interrupt condition. */ + ProcessClientWriteInterrupt(false); + retry: waitfor = 0; #ifdef USE_SSL @@ -255,6 +272,14 @@ secure_write(Port *port, void *ptr, size_t len) n = be_tls_write(port, ptr, len, &waitfor); } else +#endif +#ifdef ENABLE_GSS + if (port->gss->enc) + { + n = be_gssapi_write(port, ptr, len); + waitfor = WL_SOCKET_WRITEABLE; + } + else #endif { n = secure_raw_write(port, ptr, len); @@ -286,17 +311,16 @@ secure_write(Port *port, void *ptr, size_t len) /* * We'll retry the write. Most likely it will return immediately - * because there's still no data available, and we'll wait for the - * socket to become ready again. + * because there's still no buffer space available, and we'll wait + * for the socket to become ready again. */ } goto retry; } /* - * Process interrupts that happened while (or before) sending. Note that - * we signal that we're not blocking, which will prevent some types of - * interrupts from being processed. + * Process interrupts that happened during a successful (or non-blocking, + * or hard-failed) write. */ ProcessClientWriteInterrupt(false); diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c index 2c5ce4a47e1..784fb227aa2 100644 --- a/src/backend/libpq/crypt.c +++ b/src/backend/libpq/crypt.c @@ -4,7 +4,7 @@ * Functions for dealing with encrypted passwords stored in * pg_authid.rolpassword. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/crypt.c @@ -14,12 +14,10 @@ #include "postgres.h" #include -#ifdef HAVE_CRYPT_H -#include -#endif #include "catalog/pg_authid.h" #include "common/md5.h" +#include "common/scram-common.h" #include "libpq/crypt.h" #include "libpq/scram.h" #include "miscadmin.h" @@ -90,9 +88,17 @@ get_role_password(const char *role, char **logdetail) PasswordType get_password_type(const char *shadow_pass) { - if (strncmp(shadow_pass, "md5", 3) == 0 && strlen(shadow_pass) == MD5_PASSWD_LEN) + char *encoded_salt; + int iterations; + uint8 stored_key[SCRAM_KEY_LEN]; + uint8 server_key[SCRAM_KEY_LEN]; + + if (strncmp(shadow_pass, "md5", 3) == 0 && + strlen(shadow_pass) == MD5_PASSWD_LEN && + strspn(shadow_pass + 3, MD5_PASSWD_CHARSET) == MD5_PASSWD_LEN - 3) return PASSWORD_TYPE_MD5; - if (strncmp(shadow_pass, "SCRAM-SHA-256$", strlen("SCRAM-SHA-256$")) == 0) + if (parse_scram_verifier(shadow_pass, &iterations, &encoded_salt, + stored_key, server_key)) return PASSWORD_TYPE_SCRAM_SHA_256; return PASSWORD_TYPE_PLAINTEXT; } diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index acf625e4ec1..2221c04fef6 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -5,7 +5,7 @@ * wherein you authenticate a user by seeing what IP address the system * says he comes from and choosing authentication method based on it). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -139,16 +139,16 @@ static const char *const UserAuthName[] = static MemoryContext tokenize_file(const char *filename, FILE *file, - List **tok_lines, int elevel); + List **tok_lines, int elevel); static List *tokenize_inc_file(List *tokens, const char *outer_filename, - const char *inc_filename, int elevel, char **err_msg); + const char *inc_filename, int elevel, char **err_msg); static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, - int elevel, char **err_msg); + int elevel, char **err_msg); static bool verify_option_list_length(List *options, const char *optionname, - List *masters, const char *mastername, int line_num); + List *masters, const char *mastername, int line_num); static ArrayType *gethba_options(HbaLine *hba); static void fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, - int lineno, HbaLine *hba, const char *err_msg); + int lineno, HbaLine *hba, const char *err_msg); static void fill_hba_view(Tuplestorestate *tuple_store, TupleDesc tupdesc); @@ -994,7 +994,9 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } else if (strcmp(token->string, "host") == 0 || strcmp(token->string, "hostssl") == 0 || - strcmp(token->string, "hostnossl") == 0) + strcmp(token->string, "hostnossl") == 0 || + strcmp(token->string, "hostgssenc") == 0 || + strcmp(token->string, "hostnogssenc") == 0) { if (token->string[4] == 's') /* "hostssl" */ @@ -1022,10 +1024,23 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) *err_msg = "hostssl record cannot match because SSL is not supported by this build"; #endif } - else if (token->string[4] == 'n') /* "hostnossl" */ + else if (token->string[4] == 'g') /* "hostgssenc" */ { - parsedline->conntype = ctHostNoSSL; + parsedline->conntype = ctHostGSS; +#ifndef ENABLE_GSS + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("hostgssenc record cannot match because GSSAPI is not supported by this build"), + errhint("Compile with --with-gssapi to use GSSAPI connections."), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "hostgssenc record cannot match because GSSAPI is not supported by this build"; +#endif } + else if (token->string[4] == 'n' && token->string[6] == 's') + parsedline->conntype = ctHostNoSSL; + else if (token->string[4] == 'n' && token->string[6] == 'g') + parsedline->conntype = ctHostNoGSS; else { /* "host" */ @@ -1045,7 +1060,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } /* Get the databases. */ - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -1065,7 +1080,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } /* Get the roles. */ - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -1087,7 +1102,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) if (parsedline->conntype != ctLocal) { /* Read the IP address field. (with or without CIDR netmask) */ - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -1207,7 +1222,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) { /* Read the mask field. */ pfree(str); - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -1268,7 +1283,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } /* != ctLocal */ /* Get the authentication method */ - field = lnext(field); + field = lnext(tok_line->fields, field); if (!field) { ereport(elevel, @@ -1404,6 +1419,19 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) *err_msg = "gssapi authentication is not supported on local sockets"; return NULL; } + if (parsedline->conntype == ctHostGSS && + parsedline->auth_method != uaGSS && + parsedline->auth_method != uaReject && + parsedline->auth_method != uaTrust) + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("GSSAPI encryption only supports gss, trust, or reject authentication"), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + *err_msg = "GSSAPI encryption only supports gss, trust, or reject authentication"; + return NULL; + } if (parsedline->conntype != ctLocal && parsedline->auth_method == uaPeer) @@ -1460,7 +1488,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } /* Parse remaining arguments */ - while ((field = lnext(field)) != NULL) + while ((field = lnext(tok_line->fields, field)) != NULL) { tokens = lfirst(field); foreach(tokencell, tokens) @@ -1500,7 +1528,10 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) */ if (parsedline->auth_method == uaLDAP) { +#ifndef HAVE_LDAP_INITIALIZE + /* Not mandatory for OpenLDAP, because it can use DNS SRV records */ MANDATORY_AUTH_ARG(parsedline->ldapserver, "ldapserver", "ldap"); +#endif /* * LDAP can operate in two modes: either with a direct bind, using @@ -1519,10 +1550,10 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) { ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter or ldapurl together with ldapprefix"), + errmsg("cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); - *err_msg = "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter or ldapurl together with ldapprefix"; + *err_msg = "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix"; return NULL; } } @@ -1609,7 +1640,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) */ if (parsedline->auth_method == uaCert) { - parsedline->clientcert = true; + parsedline->clientcert = clientCertCA; } return parsedline; @@ -1675,23 +1706,38 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, *err_msg = "clientcert can only be configured for \"hostssl\" rows"; return false; } - if (strcmp(val, "1") == 0) + if (strcmp(val, "1") == 0 + || strcmp(val, "verify-ca") == 0) { - hbaline->clientcert = true; + hbaline->clientcert = clientCertCA; } - else + else if (strcmp(val, "verify-full") == 0) + { + hbaline->clientcert = clientCertFull; + } + else if (strcmp(val, "0") == 0 + || strcmp(val, "no-verify") == 0) { if (hbaline->auth_method == uaCert) { ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), - errmsg("clientcert can not be set to 0 when using \"cert\" authentication"), + errmsg("clientcert can not be set to \"no-verify\" when using \"cert\" authentication"), errcontext("line %d of configuration file \"%s\"", line_num, HbaFileName))); - *err_msg = "clientcert can not be set to 0 when using \"cert\" authentication"; + *err_msg = "clientcert can not be set to \"no-verify\" when using \"cert\" authentication"; return false; } - hbaline->clientcert = false; + hbaline->clientcert = clientCertOff; + } + else + { + ereport(elevel, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("invalid value for clientcert: \"%s\"", val), + errcontext("line %d of configuration file \"%s\"", + line_num, HbaFileName))); + return false; } } else if (strcmp(name, "pamservice") == 0) @@ -2060,6 +2106,17 @@ check_hba(hbaPort *port) continue; } + /* Check GSSAPI state */ +#ifdef ENABLE_GSS + if (port->gss->enc && hba->conntype == ctHostNoGSS) + continue; + else if (!port->gss->enc && hba->conntype == ctHostGSS) + continue; +#else + if (hba->conntype == ctHostGSS) + continue; +#endif + /* Check IP address */ switch (hba->ip_cmp_method) { @@ -2218,10 +2275,12 @@ load_hba(void) /* * This macro specifies the maximum number of authentication options * that are possible with any given authentication method that is supported. - * Currently LDAP supports 10, so the macro value is well above the most any - * method needs. + * Currently LDAP supports 11, and there are 3 that are not dependent on + * the auth method here. It may not actually be possible to set all of them + * at the same time, but we'll set the macro value high enough to be + * conservative and avoid warnings from static analysis tools. */ -#define MAX_HBA_OPTIONS 12 +#define MAX_HBA_OPTIONS 14 /* * Create a text array listing the options specified in the HBA line. @@ -2250,9 +2309,9 @@ gethba_options(HbaLine *hba) options[noptions++] = CStringGetTextDatum(psprintf("map=%s", hba->usermap)); - if (hba->clientcert) + if (hba->clientcert != clientCertOff) options[noptions++] = - CStringGetTextDatum("clientcert=true"); + CStringGetTextDatum(psprintf("clientcert=%s", (hba->clientcert == clientCertCA) ? "verify-ca" : "verify-full")); if (hba->pamservice) options[noptions++] = @@ -2327,6 +2386,7 @@ gethba_options(HbaLine *hba) CStringGetTextDatum(psprintf("radiusports=%s", hba->radiusports_s)); } + /* If you add more options, consider increasing MAX_HBA_OPTIONS. */ Assert(noptions <= MAX_HBA_OPTIONS); if (noptions > 0) @@ -2393,6 +2453,12 @@ fill_hba_line(Tuplestorestate *tuple_store, TupleDesc tupdesc, case ctHostNoSSL: typestr = "hostnossl"; break; + case ctHostGSS: + typestr = "hostgssenc"; + break; + case ctHostNoGSS: + typestr = "hostnogssenc"; + break; } if (typestr) values[index++] = CStringGetTextDatum(typestr); @@ -2663,7 +2729,7 @@ parse_ident_line(TokenizedLine *tok_line) parsedline->usermap = pstrdup(token->string); /* Get the ident user token */ - field = lnext(field); + field = lnext(tok_line->fields, field); IDENT_FIELD_ABSENT(field); tokens = lfirst(field); IDENT_MULTI_VALUE(tokens); @@ -2671,7 +2737,7 @@ parse_ident_line(TokenizedLine *tok_line) parsedline->ident_user = pstrdup(token->string); /* Get the PG rolename token */ - field = lnext(field); + field = lnext(tok_line->fields, field); IDENT_FIELD_ABSENT(field); tokens = lfirst(field); IDENT_MULTI_VALUE(tokens); diff --git a/src/backend/libpq/ifaddr.c b/src/backend/libpq/ifaddr.c index 274c0843622..3c8237798a3 100644 --- a/src/backend/libpq/ifaddr.c +++ b/src/backend/libpq/ifaddr.c @@ -3,7 +3,7 @@ * ifaddr.c * IP netmask calculations, and enumerating network interfaces. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,14 +32,14 @@ #include "libpq/ifaddr.h" #include "port/pg_bswap.h" -static int range_sockaddr_AF_INET(const struct sockaddr_in *addr, - const struct sockaddr_in *netaddr, - const struct sockaddr_in *netmask); +static int range_sockaddr_AF_INET(const struct sockaddr_in *addr, + const struct sockaddr_in *netaddr, + const struct sockaddr_in *netmask); #ifdef HAVE_IPV6 -static int range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr, - const struct sockaddr_in6 *netaddr, - const struct sockaddr_in6 *netmask); +static int range_sockaddr_AF_INET6(const struct sockaddr_in6 *addr, + const struct sockaddr_in6 *netaddr, + const struct sockaddr_in6 *netmask); #endif diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index a4f6d4deeb4..ce846a022a0 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -27,7 +27,7 @@ * the backend's "backend/libpq" is quite separate from "interfaces/libpq". * All that remains is similarities of names to trap the unwary... * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqcomm.c @@ -44,8 +44,8 @@ * StreamClose - Close a client/backend connection * TouchSocketFiles - Protect socket files against /tmp cleaners * pq_init - initialize libpq at backend startup - * pq_comm_reset - reset libpq during error recovery - * pq_close - shutdown libpq at backend exit + * socket_comm_reset - reset libpq during error recovery + * socket_close - shutdown libpq at backend exit * * low-level I/O: * pq_getbytes - get a known number of bytes from connection @@ -170,7 +170,7 @@ static int Lock_AF_UNIX(char *unixSocketDir, char *unixSocketPath); static int Setup_AF_UNIX(char *sock_path); #endif /* HAVE_UNIX_SOCKETS */ -static PQcommMethods PqCommSocketMethods = { +static const PQcommMethods PqCommSocketMethods = { socket_comm_reset, socket_flush, socket_flush_if_writable, @@ -181,7 +181,7 @@ static PQcommMethods PqCommSocketMethods = { socket_endcopyout }; -PQcommMethods *PqCommMethods = &PqCommSocketMethods; +const PQcommMethods *PqCommMethods = &PqCommSocketMethods; WaitEventSet *FeBeWaitSet; @@ -485,10 +485,10 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, * error on TCP ports. * * On win32, however, this behavior only happens if the - * SO_EXLUSIVEADDRUSE is set. With SO_REUSEADDR, win32 allows multiple - * servers to listen on the same address, resulting in unpredictable - * behavior. With no flags at all, win32 behaves as Unix with - * SO_REUSEADDR. + * SO_EXCLUSIVEADDRUSE is set. With SO_REUSEADDR, win32 allows + * multiple servers to listen on the same address, resulting in + * unpredictable behavior. With no flags at all, win32 behaves as Unix + * with SO_REUSEADDR. */ if (!IS_AF_UNIX(addr->ai_family)) { @@ -503,6 +503,17 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, closesocket(fd); continue; } + if ((setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, + (char *) &one, sizeof(one))) == -1) + { + ereport(LOG, + (errcode_for_socket_access(), + /* translator: first %s is IPv4, IPv6, or Unix */ + errmsg("setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m", + familyDesc, addrDesc))); + closesocket(fd); + continue; + } } #endif @@ -825,6 +836,7 @@ StreamConnection(pgsocket server_fd, Port *port) (void) pq_setkeepalivesidle(tcp_keepalives_idle, port); (void) pq_setkeepalivesinterval(tcp_keepalives_interval, port); (void) pq_setkeepalivescount(tcp_keepalives_count, port); + (void) pq_settcpusertimeout(tcp_user_timeout, port); } return STATUS_OK; @@ -1926,3 +1938,75 @@ pq_setkeepalivescount(int count, Port *port) return STATUS_OK; } + +int +pq_gettcpusertimeout(Port *port) +{ +#ifdef TCP_USER_TIMEOUT + if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family)) + return 0; + + if (port->tcp_user_timeout != 0) + return port->tcp_user_timeout; + + if (port->default_tcp_user_timeout == 0) + { + ACCEPT_TYPE_ARG3 size = sizeof(port->default_tcp_user_timeout); + + if (getsockopt(port->sock, IPPROTO_TCP, TCP_USER_TIMEOUT, + (char *) &port->default_tcp_user_timeout, + &size) < 0) + { + elog(LOG, "getsockopt(%s) failed: %m", "TCP_USER_TIMEOUT"); + port->default_tcp_user_timeout = -1; /* don't know */ + } + } + + return port->default_tcp_user_timeout; +#else + return 0; +#endif +} + +int +pq_settcpusertimeout(int timeout, Port *port) +{ + if (port == NULL || IS_AF_UNIX(port->laddr.addr.ss_family)) + return STATUS_OK; + +#ifdef TCP_USER_TIMEOUT + if (timeout == port->tcp_user_timeout) + return STATUS_OK; + + if (port->default_tcp_user_timeout <= 0) + { + if (pq_gettcpusertimeout(port) < 0) + { + if (timeout == 0) + return STATUS_OK; /* default is set but unknown */ + else + return STATUS_ERROR; + } + } + + if (timeout == 0) + timeout = port->default_tcp_user_timeout; + + if (setsockopt(port->sock, IPPROTO_TCP, TCP_USER_TIMEOUT, + (char *) &timeout, sizeof(timeout)) < 0) + { + elog(LOG, "setsockopt(%s) failed: %m", "TCP_USER_TIMEOUT"); + return STATUS_ERROR; + } + + port->tcp_user_timeout = timeout; +#else + if (timeout != 0) + { + elog(LOG, "setsockopt(%s) not supported", "TCP_USER_TIMEOUT"); + return STATUS_ERROR; + } +#endif + + return STATUS_OK; +} diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 1c7e99019d4..aca44a0aece 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -21,7 +21,7 @@ * are different. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqformat.c @@ -308,7 +308,7 @@ pq_endmessage(StringInfo buf) * pq_endmessage_reuse - send the completed message to the frontend * * The data buffer is *not* freed, allowing to reuse the buffer with - * pg_beginmessage_reuse. + * pq_beginmessage_reuse. -------------------------------- */ diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c index 201075dd477..a9bd47d9371 100644 --- a/src/backend/libpq/pqmq.c +++ b/src/backend/libpq/pqmq.c @@ -3,7 +3,7 @@ * pqmq.c * Use the frontend/backend protocol for communication over a shm_mq * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/libpq/pqmq.c @@ -36,7 +36,7 @@ static void mq_putmessage_noblock(char msgtype, const char *s, size_t len); static void mq_startcopyout(void); static void mq_endcopyout(bool errorAbort); -static PQcommMethods PqCommMqMethods = { +static const PQcommMethods PqCommMqMethods = { mq_comm_reset, mq_flush, mq_flush_if_writable, @@ -168,8 +168,8 @@ mq_putmessage(char msgtype, const char *s, size_t len) if (result != SHM_MQ_WOULD_BLOCK) break; - WaitLatch(MyLatch, WL_LATCH_SET, 0, - WAIT_EVENT_MQ_PUT_MESSAGE); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_MQ_PUT_MESSAGE); ResetLatch(MyLatch); CHECK_FOR_INTERRUPTS(); } @@ -286,10 +286,10 @@ pq_parse_errornotice(StringInfo msg, ErrorData *edata) edata->hint = pstrdup(value); break; case PG_DIAG_STATEMENT_POSITION: - edata->cursorpos = pg_atoi(value, sizeof(int), '\0'); + edata->cursorpos = pg_strtoint32(value); break; case PG_DIAG_INTERNAL_POSITION: - edata->internalpos = pg_atoi(value, sizeof(int), '\0'); + edata->internalpos = pg_strtoint32(value); break; case PG_DIAG_INTERNAL_QUERY: edata->internalquery = pstrdup(value); @@ -316,7 +316,7 @@ pq_parse_errornotice(StringInfo msg, ErrorData *edata) edata->filename = pstrdup(value); break; case PG_DIAG_SOURCE_LINE: - edata->lineno = pg_atoi(value, sizeof(int), '\0'); + edata->lineno = pg_strtoint32(value); break; case PG_DIAG_SOURCE_FUNCTION: edata->funcname = pstrdup(value); diff --git a/src/backend/libpq/pqsignal.c b/src/backend/libpq/pqsignal.c index a24de5d4101..68c32bb60d7 100644 --- a/src/backend/libpq/pqsignal.c +++ b/src/backend/libpq/pqsignal.c @@ -3,7 +3,7 @@ * pqsignal.c * Backend signal(2) support (see also src/port/pqsignal.c) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/main/main.c b/src/backend/main/main.c index 38853e38eb3..a9edbfd4a44 100644 --- a/src/backend/main/main.c +++ b/src/backend/main/main.c @@ -9,7 +9,7 @@ * proper FooMain() routine for the incarnation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -99,42 +99,24 @@ main(int argc, char *argv[]) MemoryContextInit(); /* - * Set up locale information from environment. Note that LC_CTYPE and - * LC_COLLATE will be overridden later from pg_control if we are in an - * already-initialized database. We set them here so that they will be - * available to fill pg_control during initdb. LC_MESSAGES will get set - * later during GUC option processing, but we set it here to allow startup - * error messages to be localized. + * Set up locale information */ - set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres")); -#ifdef WIN32 - /* - * Windows uses codepages rather than the environment, so we work around - * that by querying the environment explicitly first for LC_COLLATE and - * LC_CTYPE. We have to do this because initdb passes those values in the - * environment. If there is nothing there we fall back on the codepage. + * In the postmaster, absorb the environment values for LC_COLLATE and + * LC_CTYPE. Individual backends will change these later to settings + * taken from pg_database, but the postmaster cannot do that. If we leave + * these set to "C" then message localization might not work well in the + * postmaster. */ - { - char *env_locale; - - if ((env_locale = getenv("LC_COLLATE")) != NULL) - init_locale("LC_COLLATE", LC_COLLATE, env_locale); - else - init_locale("LC_COLLATE", LC_COLLATE, ""); - - if ((env_locale = getenv("LC_CTYPE")) != NULL) - init_locale("LC_CTYPE", LC_CTYPE, env_locale); - else - init_locale("LC_CTYPE", LC_CTYPE, ""); - } -#else init_locale("LC_COLLATE", LC_COLLATE, ""); init_locale("LC_CTYPE", LC_CTYPE, ""); -#endif + /* + * LC_MESSAGES will get set later during GUC option processing, but we set + * it here to allow startup error messages to be localized. + */ #ifdef LC_MESSAGES init_locale("LC_MESSAGES", LC_MESSAGES, ""); #endif @@ -377,7 +359,7 @@ help(const char *progname) printf(_("\nPlease read the documentation for the complete list of run-time\n" "configuration settings and how to set them on the command line or in\n" "the configuration file.\n\n" - "Report bugs to .\n")); + "Report bugs to .\n")); } diff --git a/src/backend/nls.mk b/src/backend/nls.mk index 627492df171..ad94947f5e9 100644 --- a/src/backend/nls.mk +++ b/src/backend/nls.mk @@ -1,6 +1,6 @@ # src/backend/nls.mk CATALOG_NAME = postgres -AVAIL_LANGUAGES = de es fr id it ja ko pl pt_BR ru zh_CN +AVAIL_LANGUAGES = de es fr id it ja ko pl pt_BR ru sv tr zh_CN GETTEXT_FILES = + gettext-files GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) \ GUC_check_errmsg GUC_check_errdetail GUC_check_errhint \ diff --git a/src/backend/nodes/README b/src/backend/nodes/README index 2df4389437e..dcd66d7243c 100644 --- a/src/backend/nodes/README +++ b/src/backend/nodes/README @@ -36,8 +36,8 @@ FILES IN src/include/nodes/ nodes.h - define node tags (NodeTag) primnodes.h - primitive nodes parsenodes.h - parse tree nodes + pathnodes.h - path tree nodes and planner internal structures plannodes.h - plan tree nodes - relation.h - planner internal nodes execnodes.h - executor nodes memnodes.h - memory nodes pg_list.h - generic list diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 9341bf579e3..665149defe2 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -11,7 +11,7 @@ * bms_is_empty() in preference to testing for NULL.) * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/nodes/bitmapset.c @@ -20,8 +20,10 @@ */ #include "postgres.h" -#include "access/hash.h" +#include "nodes/bitmapset.h" #include "nodes/pg_list.h" +#include "port/pg_bitutils.h" +#include "utils/hashutils.h" #define WORDNUM(x) ((x) / BITS_PER_BITMAPWORD) @@ -51,79 +53,18 @@ #define HAS_MULTIPLE_ONES(x) ((bitmapword) RIGHTMOST_ONE(x) != (x)) - -/* - * Lookup tables to avoid need for bit-by-bit groveling - * - * rightmost_one_pos[x] gives the bit number (0-7) of the rightmost one bit - * in a nonzero byte value x. The entry for x=0 is never used. - * - * leftmost_one_pos[x] gives the bit number (0-7) of the leftmost one bit in a - * nonzero byte value x. The entry for x=0 is never used. - * - * number_of_ones[x] gives the number of one-bits (0-8) in a byte value x. - * - * We could make these tables larger and reduce the number of iterations - * in the functions that use them, but bytewise shifts and masks are - * especially fast on many machines, so working a byte at a time seems best. - */ - -static const uint8 rightmost_one_pos[256] = { - 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -static const uint8 leftmost_one_pos[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -}; - -static const uint8 number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; +/* Select appropriate bit-twiddling functions for bitmap word size */ +#if BITS_PER_BITMAPWORD == 32 +#define bmw_leftmost_one_pos(w) pg_leftmost_one_pos32(w) +#define bmw_rightmost_one_pos(w) pg_rightmost_one_pos32(w) +#define bmw_popcount(w) pg_popcount32(w) +#elif BITS_PER_BITMAPWORD == 64 +#define bmw_leftmost_one_pos(w) pg_leftmost_one_pos64(w) +#define bmw_rightmost_one_pos(w) pg_rightmost_one_pos64(w) +#define bmw_popcount(w) pg_popcount64(w) +#else +#error "invalid BITS_PER_BITMAPWORD" +#endif /* @@ -502,6 +443,50 @@ bms_is_member(int x, const Bitmapset *a) return false; } +/* + * bms_member_index + * determine 0-based index of member x in the bitmap + * + * Returns (-1) when x is not a member. + */ +int +bms_member_index(Bitmapset *a, int x) +{ + int i; + int bitnum; + int wordnum; + int result = 0; + bitmapword mask; + + /* return -1 if not a member of the bitmap */ + if (!bms_is_member(x, a)) + return -1; + + wordnum = WORDNUM(x); + bitnum = BITNUM(x); + + /* count bits in preceding words */ + for (i = 0; i < wordnum; i++) + { + bitmapword w = a->words[i]; + + /* No need to count the bits in a zero word */ + if (w != 0) + result += bmw_popcount(w); + } + + /* + * Now add bits of the last word, but only those before the item. We can + * do that by applying a mask and then using popcount again. To get + * 0-based index, we want to count only preceding bits, not the item + * itself, so we subtract 1. + */ + mask = ((bitmapword) 1 << bitnum) - 1; + result += bmw_popcount(a->words[wordnum] & mask); + + return result; +} + /* * bms_overlap - do sets overlap (ie, have a nonempty intersection)? */ @@ -607,12 +592,7 @@ bms_singleton_member(const Bitmapset *a) if (result >= 0 || HAS_MULTIPLE_ONES(w)) elog(ERROR, "bitmapset has multiple members"); result = wordnum * BITS_PER_BITMAPWORD; - while ((w & 255) == 0) - { - w >>= 8; - result += 8; - } - result += rightmost_one_pos[w & 255]; + result += bmw_rightmost_one_pos(w); } } if (result < 0) @@ -650,12 +630,7 @@ bms_get_singleton_member(const Bitmapset *a, int *member) if (result >= 0 || HAS_MULTIPLE_ONES(w)) return false; result = wordnum * BITS_PER_BITMAPWORD; - while ((w & 255) == 0) - { - w >>= 8; - result += 8; - } - result += rightmost_one_pos[w & 255]; + result += bmw_rightmost_one_pos(w); } } if (result < 0) @@ -681,12 +656,9 @@ bms_num_members(const Bitmapset *a) { bitmapword w = a->words[wordnum]; - /* we assume here that bitmapword is an unsigned type */ - while (w != 0) - { - result += number_of_ones[w & 255]; - w >>= 8; - } + /* No need to count the bits in a zero word */ + if (w != 0) + result += bmw_popcount(w); } return result; } @@ -867,10 +839,12 @@ bms_add_range(Bitmapset *a, int lower, int upper) ushiftbits, wordnum; - if (lower < 0 || upper < 0) + /* do nothing if nothing is called for, without further checking */ + if (upper < lower) + return a; + + if (lower < 0) elog(ERROR, "negative bitmapset member not allowed"); - if (lower > upper) - elog(ERROR, "lower range must not be above upper range"); uwordnum = WORDNUM(upper); if (a == NULL) @@ -878,13 +852,12 @@ bms_add_range(Bitmapset *a, int lower, int upper) a = (Bitmapset *) palloc0(BITMAPSET_SIZE(uwordnum + 1)); a->nwords = uwordnum + 1; } - - /* ensure we have enough words to store the upper bit */ else if (uwordnum >= a->nwords) { int oldnwords = a->nwords; int i; + /* ensure we have enough words to store the upper bit */ a = (Bitmapset *) repalloc(a, BITMAPSET_SIZE(uwordnum + 1)); a->nwords = uwordnum + 1; /* zero out the enlarged portion */ @@ -1040,12 +1013,7 @@ bms_first_member(Bitmapset *a) a->words[wordnum] &= ~w; result = wordnum * BITS_PER_BITMAPWORD; - while ((w & 255) == 0) - { - w >>= 8; - result += 8; - } - result += rightmost_one_pos[w & 255]; + result += bmw_rightmost_one_pos(w); return result; } } @@ -1095,12 +1063,7 @@ bms_next_member(const Bitmapset *a, int prevbit) int result; result = wordnum * BITS_PER_BITMAPWORD; - while ((w & 255) == 0) - { - w >>= 8; - result += 8; - } - result += rightmost_one_pos[w & 255]; + result += bmw_rightmost_one_pos(w); return result; } @@ -1167,13 +1130,9 @@ bms_prev_member(const Bitmapset *a, int prevbit) if (w != 0) { int result; - int shift = 24; - result = wordnum * BITS_PER_BITMAPWORD; - - while ((w >> shift) == 0) - shift -= 8; - result += shift + leftmost_one_pos[(w >> shift) & 255]; + result = wordnum * BITS_PER_BITMAPWORD; + result += bmw_leftmost_one_pos(w); return result; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index b856fe29b59..3432bb921dd 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -11,7 +11,7 @@ * be handled easily in a simple depth-first traversal. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,8 +24,8 @@ #include "miscadmin.h" #include "nodes/extensible.h" +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" #include "utils/datum.h" #include "utils/rel.h" @@ -91,7 +91,6 @@ _copyPlannedStmt(const PlannedStmt *from) COPY_NODE_FIELD(planTree); COPY_NODE_FIELD(rtable); COPY_NODE_FIELD(resultRelations); - COPY_NODE_FIELD(nonleafResultRelations); COPY_NODE_FIELD(rootResultRelations); COPY_NODE_FIELD(subplans); COPY_BITMAPSET_FIELD(rewindPlanIDs); @@ -204,10 +203,9 @@ _copyModifyTable(const ModifyTable *from) COPY_SCALAR_FIELD(operation); COPY_SCALAR_FIELD(canSetTag); COPY_SCALAR_FIELD(nominalRelation); - COPY_NODE_FIELD(partitioned_rels); + COPY_SCALAR_FIELD(rootRelation); COPY_SCALAR_FIELD(partColsUpdated); COPY_NODE_FIELD(resultRelations); - COPY_SCALAR_FIELD(mergeTargetRelation); COPY_SCALAR_FIELD(resultRelIndex); COPY_SCALAR_FIELD(rootResultRelIndex); COPY_NODE_FIELD(plans); @@ -223,8 +221,6 @@ _copyModifyTable(const ModifyTable *from) COPY_NODE_FIELD(onConflictWhere); COPY_SCALAR_FIELD(exclRelRTI); COPY_NODE_FIELD(exclRelTlist); - COPY_NODE_FIELD(mergeSourceTargetList); - COPY_NODE_FIELD(mergeActionList); return newnode; } @@ -245,10 +241,9 @@ _copyAppend(const Append *from) /* * copy remainder of node */ - COPY_NODE_FIELD(partitioned_rels); COPY_NODE_FIELD(appendplans); COPY_SCALAR_FIELD(first_partial_plan); - COPY_NODE_FIELD(part_prune_infos); + COPY_NODE_FIELD(part_prune_info); return newnode; } @@ -269,13 +264,13 @@ _copyMergeAppend(const MergeAppend *from) /* * copy remainder of node */ - COPY_NODE_FIELD(partitioned_rels); COPY_NODE_FIELD(mergeplans); COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(sortColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(sortOperators, from->numCols * sizeof(Oid)); COPY_POINTER_FIELD(collations, from->numCols * sizeof(Oid)); COPY_POINTER_FIELD(nullsFirst, from->numCols * sizeof(bool)); + COPY_NODE_FIELD(part_prune_info); return newnode; } @@ -302,6 +297,7 @@ _copyRecursiveUnion(const RecursiveUnion *from) { COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); } COPY_SCALAR_FIELD(numGroups); @@ -903,6 +899,9 @@ _copyHashJoin(const HashJoin *from) * copy remainder of node */ COPY_NODE_FIELD(hashclauses); + COPY_NODE_FIELD(hashoperators); + COPY_NODE_FIELD(hashcollations); + COPY_NODE_FIELD(hashkeys); return newnode; } @@ -961,6 +960,7 @@ _copyGroup(const Group *from) COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); return newnode; } @@ -982,6 +982,7 @@ _copyAgg(const Agg *from) { COPY_POINTER_FIELD(grpColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(grpOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(grpCollations, from->numCols * sizeof(Oid)); } COPY_SCALAR_FIELD(numGroups); COPY_BITMAPSET_FIELD(aggParams); @@ -1007,12 +1008,14 @@ _copyWindowAgg(const WindowAgg *from) { COPY_POINTER_FIELD(partColIdx, from->partNumCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(partOperators, from->partNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(partCollations, from->partNumCols * sizeof(Oid)); } COPY_SCALAR_FIELD(ordNumCols); if (from->ordNumCols > 0) { COPY_POINTER_FIELD(ordColIdx, from->ordNumCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(ordOperators, from->ordNumCols * sizeof(Oid)); + COPY_POINTER_FIELD(ordCollations, from->ordNumCols * sizeof(Oid)); } COPY_SCALAR_FIELD(frameOptions); COPY_NODE_FIELD(startOffset); @@ -1045,6 +1048,7 @@ _copyUnique(const Unique *from) COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(uniqColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(uniqOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(uniqCollations, from->numCols * sizeof(Oid)); return newnode; } @@ -1065,6 +1069,7 @@ _copyHash(const Hash *from) /* * copy remainder of node */ + COPY_NODE_FIELD(hashkeys); COPY_SCALAR_FIELD(skewTable); COPY_SCALAR_FIELD(skewColumn); COPY_SCALAR_FIELD(skewInherit); @@ -1094,6 +1099,7 @@ _copySetOp(const SetOp *from) COPY_SCALAR_FIELD(numCols); COPY_POINTER_FIELD(dupColIdx, from->numCols * sizeof(AttrNumber)); COPY_POINTER_FIELD(dupOperators, from->numCols * sizeof(Oid)); + COPY_POINTER_FIELD(dupCollations, from->numCols * sizeof(Oid)); COPY_SCALAR_FIELD(flagColIdx); COPY_SCALAR_FIELD(firstFlag); COPY_SCALAR_FIELD(numGroups); @@ -1179,6 +1185,67 @@ _copyPlanRowMark(const PlanRowMark *from) return newnode; } +static PartitionPruneInfo * +_copyPartitionPruneInfo(const PartitionPruneInfo *from) +{ + PartitionPruneInfo *newnode = makeNode(PartitionPruneInfo); + + COPY_NODE_FIELD(prune_infos); + COPY_BITMAPSET_FIELD(other_subplans); + + return newnode; +} + +static PartitionedRelPruneInfo * +_copyPartitionedRelPruneInfo(const PartitionedRelPruneInfo *from) +{ + PartitionedRelPruneInfo *newnode = makeNode(PartitionedRelPruneInfo); + + COPY_SCALAR_FIELD(rtindex); + COPY_BITMAPSET_FIELD(present_parts); + COPY_SCALAR_FIELD(nparts); + COPY_POINTER_FIELD(subplan_map, from->nparts * sizeof(int)); + COPY_POINTER_FIELD(subpart_map, from->nparts * sizeof(int)); + COPY_POINTER_FIELD(relid_map, from->nparts * sizeof(Oid)); + COPY_NODE_FIELD(initial_pruning_steps); + COPY_NODE_FIELD(exec_pruning_steps); + COPY_BITMAPSET_FIELD(execparamids); + + return newnode; +} + +/* + * _copyPartitionPruneStepOp + */ +static PartitionPruneStepOp * +_copyPartitionPruneStepOp(const PartitionPruneStepOp *from) +{ + PartitionPruneStepOp *newnode = makeNode(PartitionPruneStepOp); + + COPY_SCALAR_FIELD(step.step_id); + COPY_SCALAR_FIELD(opstrategy); + COPY_NODE_FIELD(exprs); + COPY_NODE_FIELD(cmpfns); + COPY_BITMAPSET_FIELD(nullkeys); + + return newnode; +} + +/* + * _copyPartitionPruneStepCombine + */ +static PartitionPruneStepCombine * +_copyPartitionPruneStepCombine(const PartitionPruneStepCombine *from) +{ + PartitionPruneStepCombine *newnode = makeNode(PartitionPruneStepCombine); + + COPY_SCALAR_FIELD(step.step_id); + COPY_SCALAR_FIELD(combineOp); + COPY_NODE_FIELD(source_stepids); + + return newnode; +} + /* * _copyPlanInvalItem */ @@ -1266,6 +1333,7 @@ _copyIntoClause(const IntoClause *from) COPY_NODE_FIELD(rel); COPY_NODE_FIELD(colNames); + COPY_STRING_FIELD(accessMethod); COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(onCommit); COPY_STRING_FIELD(tableSpaceName); @@ -1428,14 +1496,14 @@ _copyWindowFunc(const WindowFunc *from) } /* - * _copyArrayRef + * _copySubscriptingRef */ -static ArrayRef * -_copyArrayRef(const ArrayRef *from) +static SubscriptingRef * +_copySubscriptingRef(const SubscriptingRef *from) { - ArrayRef *newnode = makeNode(ArrayRef); + SubscriptingRef *newnode = makeNode(SubscriptingRef); - COPY_SCALAR_FIELD(refarraytype); + COPY_SCALAR_FIELD(refcontainertype); COPY_SCALAR_FIELD(refelemtype); COPY_SCALAR_FIELD(reftypmod); COPY_SCALAR_FIELD(refcollid); @@ -2137,71 +2205,8 @@ _copyOnConflictExpr(const OnConflictExpr *from) return newnode; } -static MergeAction * -_copyMergeAction(const MergeAction *from) -{ - MergeAction *newnode = makeNode(MergeAction); - - COPY_SCALAR_FIELD(matched); - COPY_SCALAR_FIELD(commandType); - COPY_SCALAR_FIELD(override); - COPY_NODE_FIELD(qual); - COPY_NODE_FIELD(targetList); - - return newnode; -} - -/* - * _copyPartitionPruneStepOp - */ -static PartitionPruneStepOp * -_copyPartitionPruneStepOp(const PartitionPruneStepOp *from) -{ - PartitionPruneStepOp *newnode = makeNode(PartitionPruneStepOp); - - COPY_SCALAR_FIELD(step.step_id); - COPY_SCALAR_FIELD(opstrategy); - COPY_NODE_FIELD(exprs); - COPY_NODE_FIELD(cmpfns); - COPY_BITMAPSET_FIELD(nullkeys); - - return newnode; -} - -/* - * _copyPartitionPruneStepCombine - */ -static PartitionPruneStepCombine * -_copyPartitionPruneStepCombine(const PartitionPruneStepCombine *from) -{ - PartitionPruneStepCombine *newnode = makeNode(PartitionPruneStepCombine); - - COPY_SCALAR_FIELD(step.step_id); - COPY_SCALAR_FIELD(combineOp); - COPY_NODE_FIELD(source_stepids); - - return newnode; -} - -static PartitionPruneInfo * -_copyPartitionPruneInfo(const PartitionPruneInfo *from) -{ - PartitionPruneInfo *newnode = makeNode(PartitionPruneInfo); - - COPY_SCALAR_FIELD(reloid); - COPY_NODE_FIELD(pruning_steps); - COPY_BITMAPSET_FIELD(present_parts); - COPY_SCALAR_FIELD(nparts); - COPY_POINTER_FIELD(subnode_map, from->nparts * sizeof(int)); - COPY_POINTER_FIELD(subpart_map, from->nparts * sizeof(int)); - COPY_BITMAPSET_FIELD(extparams); - COPY_BITMAPSET_FIELD(execparams); - - return newnode; -} - /* **************************************************************** - * relation.h copy functions + * pathnodes.h copy functions * * We don't support copying RelOptInfo, IndexOptInfo, or Path nodes. * There are some subsidiary structs that are useful to copy, though. @@ -2358,6 +2363,7 @@ _copyRangeTblEntry(const RangeTblEntry *from) COPY_SCALAR_FIELD(rtekind); COPY_SCALAR_FIELD(relid); COPY_SCALAR_FIELD(relkind); + COPY_SCALAR_FIELD(rellockmode); COPY_NODE_FIELD(tablesample); COPY_NODE_FIELD(subquery); COPY_SCALAR_FIELD(security_barrier); @@ -2385,6 +2391,7 @@ _copyRangeTblEntry(const RangeTblEntry *from) COPY_BITMAPSET_FIELD(selectedCols); COPY_BITMAPSET_FIELD(insertedCols); COPY_BITMAPSET_FIELD(updatedCols); + COPY_BITMAPSET_FIELD(extraUpdatedCols); COPY_NODE_FIELD(securityQuals); return newnode; @@ -2540,6 +2547,7 @@ _copyCommonTableExpr(const CommonTableExpr *from) COPY_STRING_FIELD(ctename); COPY_NODE_FIELD(aliascolnames); + COPY_SCALAR_FIELD(ctematerialized); COPY_NODE_FIELD(ctequery); COPY_LOCATION_FIELD(location); COPY_SCALAR_FIELD(cterecursive); @@ -2877,12 +2885,12 @@ _copyColumnDef(const ColumnDef *from) COPY_SCALAR_FIELD(is_local); COPY_SCALAR_FIELD(is_not_null); COPY_SCALAR_FIELD(is_from_type); - COPY_SCALAR_FIELD(is_from_parent); COPY_SCALAR_FIELD(storage); COPY_NODE_FIELD(raw_default); COPY_NODE_FIELD(cooked_default); COPY_SCALAR_FIELD(identity); COPY_NODE_FIELD(identitySequence); + COPY_SCALAR_FIELD(generated); COPY_NODE_FIELD(collClause); COPY_SCALAR_FIELD(collOid); COPY_NODE_FIELD(constraints); @@ -2912,6 +2920,7 @@ _copyConstraint(const Constraint *from) COPY_NODE_FIELD(options); COPY_STRING_FIELD(indexname); COPY_STRING_FIELD(indexspace); + COPY_SCALAR_FIELD(reset_default_tblspc); COPY_STRING_FIELD(access_method); COPY_NODE_FIELD(where_clause); COPY_NODE_FIELD(pktable); @@ -3030,9 +3039,6 @@ _copyQuery(const Query *from) COPY_NODE_FIELD(setOperations); COPY_NODE_FIELD(constraintDeps); COPY_NODE_FIELD(withCheckOptions); - COPY_SCALAR_FIELD(mergeTarget_relation); - COPY_NODE_FIELD(mergeSourceTargetList); - COPY_NODE_FIELD(mergeActionList); COPY_LOCATION_FIELD(stmt_location); COPY_LOCATION_FIELD(stmt_len); @@ -3096,35 +3102,6 @@ _copyUpdateStmt(const UpdateStmt *from) return newnode; } -static MergeStmt * -_copyMergeStmt(const MergeStmt *from) -{ - MergeStmt *newnode = makeNode(MergeStmt); - - COPY_NODE_FIELD(relation); - COPY_NODE_FIELD(source_relation); - COPY_NODE_FIELD(join_condition); - COPY_NODE_FIELD(mergeWhenClauses); - COPY_NODE_FIELD(withClause); - - return newnode; -} - -static MergeWhenClause * -_copyMergeWhenClause(const MergeWhenClause *from) -{ - MergeWhenClause *newnode = makeNode(MergeWhenClause); - - COPY_SCALAR_FIELD(matched); - COPY_SCALAR_FIELD(commandType); - COPY_NODE_FIELD(condition); - COPY_NODE_FIELD(targetList); - COPY_NODE_FIELD(cols); - COPY_NODE_FIELD(values); - COPY_SCALAR_FIELD(override); - return newnode; -} - static SelectStmt * _copySelectStmt(const SelectStmt *from) { @@ -3329,7 +3306,7 @@ _copyClusterStmt(const ClusterStmt *from) COPY_NODE_FIELD(relation); COPY_STRING_FIELD(indexname); - COPY_SCALAR_FIELD(verbose); + COPY_SCALAR_FIELD(options); return newnode; } @@ -3346,6 +3323,7 @@ _copyCopyStmt(const CopyStmt *from) COPY_SCALAR_FIELD(is_program); COPY_STRING_FIELD(filename); COPY_NODE_FIELD(options); + COPY_NODE_FIELD(whereClause); return newnode; } @@ -3369,6 +3347,7 @@ CopyCreateStmtFields(const CreateStmt *from, CreateStmt *newnode) COPY_NODE_FIELD(options); COPY_SCALAR_FIELD(oncommit); COPY_STRING_FIELD(tablespacename); + COPY_STRING_FIELD(accessMethod); COPY_SCALAR_FIELD(if_not_exists); } @@ -3404,6 +3383,7 @@ _copyDefineStmt(const DefineStmt *from) COPY_NODE_FIELD(args); COPY_NODE_FIELD(definition); COPY_SCALAR_FIELD(if_not_exists); + COPY_SCALAR_FIELD(replace); return newnode; } @@ -3479,7 +3459,6 @@ _copyIndexStmt(const IndexStmt *from) COPY_STRING_FIELD(idxname); COPY_NODE_FIELD(relation); - COPY_SCALAR_FIELD(relationId); COPY_STRING_FIELD(accessMethod); COPY_STRING_FIELD(tableSpace); COPY_NODE_FIELD(indexParams); @@ -3498,6 +3477,7 @@ _copyIndexStmt(const IndexStmt *from) COPY_SCALAR_FIELD(transformed); COPY_SCALAR_FIELD(concurrent); COPY_SCALAR_FIELD(if_not_exists); + COPY_SCALAR_FIELD(reset_default_tblspc); return newnode; } @@ -3517,6 +3497,18 @@ _copyCreateStatsStmt(const CreateStatsStmt *from) return newnode; } +static AlterStatsStmt * +_copyAlterStatsStmt(const AlterStatsStmt *from) +{ + AlterStatsStmt *newnode = makeNode(AlterStatsStmt); + + COPY_NODE_FIELD(defnames); + COPY_SCALAR_FIELD(stxstattarget); + COPY_SCALAR_FIELD(missing_ok); + + return newnode; +} + static CreateFunctionStmt * _copyCreateFunctionStmt(const CreateFunctionStmt *from) { @@ -3691,6 +3683,7 @@ _copyTransactionStmt(const TransactionStmt *from) COPY_NODE_FIELD(options); COPY_STRING_FIELD(savepoint_name); COPY_STRING_FIELD(gid); + COPY_SCALAR_FIELD(chain); return newnode; } @@ -3884,8 +3877,9 @@ _copyVacuumStmt(const VacuumStmt *from) { VacuumStmt *newnode = makeNode(VacuumStmt); - COPY_SCALAR_FIELD(options); + COPY_NODE_FIELD(options); COPY_NODE_FIELD(rels); + COPY_SCALAR_FIELD(is_vacuumcmd); return newnode; } @@ -4390,6 +4384,7 @@ _copyReindexStmt(const ReindexStmt *from) COPY_NODE_FIELD(relation); COPY_STRING_FIELD(name); COPY_SCALAR_FIELD(options); + COPY_SCALAR_FIELD(concurrent); return newnode; } @@ -4679,48 +4674,6 @@ _copyDropSubscriptionStmt(const DropSubscriptionStmt *from) return newnode; } -/* **************************************************************** - * pg_list.h copy functions - * **************************************************************** - */ - -/* - * Perform a deep copy of the specified list, using copyObject(). The - * list MUST be of type T_List; T_IntList and T_OidList nodes don't - * need deep copies, so they should be copied via list_copy() - */ -#define COPY_NODE_CELL(new, old) \ - (new) = (ListCell *) palloc(sizeof(ListCell)); \ - lfirst(new) = copyObjectImpl(lfirst(old)); - -static List * -_copyList(const List *from) -{ - List *new; - ListCell *curr_old; - ListCell *prev_new; - - Assert(list_length(from) >= 1); - - new = makeNode(List); - new->length = from->length; - - COPY_NODE_CELL(new->head, from->head); - prev_new = new->head; - curr_old = lnext(from->head); - - while (curr_old) - { - COPY_NODE_CELL(prev_new->next, curr_old); - prev_new = prev_new->next; - curr_old = curr_old->next; - } - prev_new->next = NULL; - new->tail = prev_new; - - return new; -} - /* **************************************************************** * extensible.h copy functions * **************************************************************** @@ -4781,6 +4734,7 @@ _copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from) { ForeignKeyCacheInfo *newnode = makeNode(ForeignKeyCacheInfo); + COPY_SCALAR_FIELD(conoid); COPY_SCALAR_FIELD(conrelid); COPY_SCALAR_FIELD(confrelid); COPY_SCALAR_FIELD(nkeys); @@ -4950,6 +4904,18 @@ copyObjectImpl(const void *from) case T_PlanRowMark: retval = _copyPlanRowMark(from); break; + case T_PartitionPruneInfo: + retval = _copyPartitionPruneInfo(from); + break; + case T_PartitionedRelPruneInfo: + retval = _copyPartitionedRelPruneInfo(from); + break; + case T_PartitionPruneStepOp: + retval = _copyPartitionPruneStepOp(from); + break; + case T_PartitionPruneStepCombine: + retval = _copyPartitionPruneStepCombine(from); + break; case T_PlanInvalItem: retval = _copyPlanInvalItem(from); break; @@ -4987,8 +4953,8 @@ copyObjectImpl(const void *from) case T_WindowFunc: retval = _copyWindowFunc(from); break; - case T_ArrayRef: - retval = _copyArrayRef(from); + case T_SubscriptingRef: + retval = _copySubscriptingRef(from); break; case T_FuncExpr: retval = _copyFuncExpr(from); @@ -5110,15 +5076,6 @@ copyObjectImpl(const void *from) case T_OnConflictExpr: retval = _copyOnConflictExpr(from); break; - case T_MergeAction: - retval = _copyMergeAction(from); - break; - case T_PartitionPruneStepOp: - retval = _copyPartitionPruneStepOp(from); - break; - case T_PartitionPruneStepCombine: - retval = _copyPartitionPruneStepCombine(from); - break; /* * RELATION NODES @@ -5141,9 +5098,6 @@ copyObjectImpl(const void *from) case T_PlaceHolderInfo: retval = _copyPlaceHolderInfo(from); break; - case T_PartitionPruneInfo: - retval = _copyPartitionPruneInfo(from); - break; /* * VALUE NODES @@ -5160,7 +5114,7 @@ copyObjectImpl(const void *from) * LIST NODES */ case T_List: - retval = _copyList(from); + retval = list_copy_deep(from); break; /* @@ -5197,12 +5151,6 @@ copyObjectImpl(const void *from) case T_UpdateStmt: retval = _copyUpdateStmt(from); break; - case T_MergeStmt: - retval = _copyMergeStmt(from); - break; - case T_MergeWhenClause: - retval = _copyMergeWhenClause(from); - break; case T_SelectStmt: retval = _copySelectStmt(from); break; @@ -5275,6 +5223,9 @@ copyObjectImpl(const void *from) case T_CreateStatsStmt: retval = _copyCreateStatsStmt(from); break; + case T_AlterStatsStmt: + retval = _copyAlterStatsStmt(from); + break; case T_CreateFunctionStmt: retval = _copyCreateFunctionStmt(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 39946959afd..18cb0143733 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * "x" to be considered equal() to another reference to "x" in the query. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -29,8 +29,9 @@ #include "postgres.h" +#include "miscadmin.h" #include "nodes/extensible.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "utils/datum.h" @@ -141,6 +142,7 @@ _equalIntoClause(const IntoClause *a, const IntoClause *b) { COMPARE_NODE_FIELD(rel); COMPARE_NODE_FIELD(colNames); + COMPARE_STRING_FIELD(accessMethod); COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(onCommit); COMPARE_STRING_FIELD(tableSpaceName); @@ -264,9 +266,9 @@ _equalWindowFunc(const WindowFunc *a, const WindowFunc *b) } static bool -_equalArrayRef(const ArrayRef *a, const ArrayRef *b) +_equalSubscriptingRef(const SubscriptingRef *a, const SubscriptingRef *b) { - COMPARE_SCALAR_FIELD(refarraytype); + COMPARE_SCALAR_FIELD(refcontainertype); COMPARE_SCALAR_FIELD(refelemtype); COMPARE_SCALAR_FIELD(reftypmod); COMPARE_SCALAR_FIELD(refcollid); @@ -812,20 +814,8 @@ _equalOnConflictExpr(const OnConflictExpr *a, const OnConflictExpr *b) return true; } - -static bool -_equalMergeAction(const MergeAction *a, const MergeAction *b) -{ - COMPARE_SCALAR_FIELD(matched); - COMPARE_SCALAR_FIELD(commandType); - COMPARE_SCALAR_FIELD(override); - COMPARE_NODE_FIELD(qual); - COMPARE_NODE_FIELD(targetList); - - return true; -} /* - * Stuff from relation.h + * Stuff from pathnodes.h */ static bool @@ -989,8 +979,6 @@ _equalQuery(const Query *a, const Query *b) COMPARE_NODE_FIELD(setOperations); COMPARE_NODE_FIELD(constraintDeps); COMPARE_NODE_FIELD(withCheckOptions); - COMPARE_NODE_FIELD(mergeSourceTargetList); - COMPARE_NODE_FIELD(mergeActionList); COMPARE_LOCATION_FIELD(stmt_location); COMPARE_LOCATION_FIELD(stmt_len); @@ -1046,32 +1034,6 @@ _equalUpdateStmt(const UpdateStmt *a, const UpdateStmt *b) return true; } -static bool -_equalMergeStmt(const MergeStmt *a, const MergeStmt *b) -{ - COMPARE_NODE_FIELD(relation); - COMPARE_NODE_FIELD(source_relation); - COMPARE_NODE_FIELD(join_condition); - COMPARE_NODE_FIELD(mergeWhenClauses); - COMPARE_NODE_FIELD(withClause); - - return true; -} - -static bool -_equalMergeWhenClause(const MergeWhenClause *a, const MergeWhenClause *b) -{ - COMPARE_SCALAR_FIELD(matched); - COMPARE_SCALAR_FIELD(commandType); - COMPARE_NODE_FIELD(condition); - COMPARE_NODE_FIELD(targetList); - COMPARE_NODE_FIELD(cols); - COMPARE_NODE_FIELD(values); - COMPARE_SCALAR_FIELD(override); - - return true; -} - static bool _equalSelectStmt(const SelectStmt *a, const SelectStmt *b) { @@ -1246,7 +1208,7 @@ _equalClusterStmt(const ClusterStmt *a, const ClusterStmt *b) { COMPARE_NODE_FIELD(relation); COMPARE_STRING_FIELD(indexname); - COMPARE_SCALAR_FIELD(verbose); + COMPARE_SCALAR_FIELD(options); return true; } @@ -1261,6 +1223,7 @@ _equalCopyStmt(const CopyStmt *a, const CopyStmt *b) COMPARE_SCALAR_FIELD(is_program); COMPARE_STRING_FIELD(filename); COMPARE_NODE_FIELD(options); + COMPARE_NODE_FIELD(whereClause); return true; } @@ -1278,6 +1241,7 @@ _equalCreateStmt(const CreateStmt *a, const CreateStmt *b) COMPARE_NODE_FIELD(options); COMPARE_SCALAR_FIELD(oncommit); COMPARE_STRING_FIELD(tablespacename); + COMPARE_STRING_FIELD(accessMethod); COMPARE_SCALAR_FIELD(if_not_exists); return true; @@ -1301,6 +1265,7 @@ _equalDefineStmt(const DefineStmt *a, const DefineStmt *b) COMPARE_NODE_FIELD(args); COMPARE_NODE_FIELD(definition); COMPARE_SCALAR_FIELD(if_not_exists); + COMPARE_SCALAR_FIELD(replace); return true; } @@ -1364,7 +1329,6 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b) { COMPARE_STRING_FIELD(idxname); COMPARE_NODE_FIELD(relation); - COMPARE_SCALAR_FIELD(relationId); COMPARE_STRING_FIELD(accessMethod); COMPARE_STRING_FIELD(tableSpace); COMPARE_NODE_FIELD(indexParams); @@ -1383,6 +1347,7 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b) COMPARE_SCALAR_FIELD(transformed); COMPARE_SCALAR_FIELD(concurrent); COMPARE_SCALAR_FIELD(if_not_exists); + COMPARE_SCALAR_FIELD(reset_default_tblspc); return true; } @@ -1400,6 +1365,16 @@ _equalCreateStatsStmt(const CreateStatsStmt *a, const CreateStatsStmt *b) return true; } +static bool +_equalAlterStatsStmt(const AlterStatsStmt *a, const AlterStatsStmt *b) +{ + COMPARE_NODE_FIELD(defnames); + COMPARE_SCALAR_FIELD(stxstattarget); + COMPARE_SCALAR_FIELD(missing_ok); + + return true; +} + static bool _equalCreateFunctionStmt(const CreateFunctionStmt *a, const CreateFunctionStmt *b) { @@ -1546,6 +1521,7 @@ _equalTransactionStmt(const TransactionStmt *a, const TransactionStmt *b) COMPARE_NODE_FIELD(options); COMPARE_STRING_FIELD(savepoint_name); COMPARE_STRING_FIELD(gid); + COMPARE_SCALAR_FIELD(chain); return true; } @@ -1707,8 +1683,9 @@ _equalDropdbStmt(const DropdbStmt *a, const DropdbStmt *b) static bool _equalVacuumStmt(const VacuumStmt *a, const VacuumStmt *b) { - COMPARE_SCALAR_FIELD(options); + COMPARE_NODE_FIELD(options); COMPARE_NODE_FIELD(rels); + COMPARE_SCALAR_FIELD(is_vacuumcmd); return true; } @@ -2137,6 +2114,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b) COMPARE_NODE_FIELD(relation); COMPARE_STRING_FIELD(name); COMPARE_SCALAR_FIELD(options); + COMPARE_SCALAR_FIELD(concurrent); return true; } @@ -2593,12 +2571,12 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b) COMPARE_SCALAR_FIELD(is_local); COMPARE_SCALAR_FIELD(is_not_null); COMPARE_SCALAR_FIELD(is_from_type); - COMPARE_SCALAR_FIELD(is_from_parent); COMPARE_SCALAR_FIELD(storage); COMPARE_NODE_FIELD(raw_default); COMPARE_NODE_FIELD(cooked_default); COMPARE_SCALAR_FIELD(identity); COMPARE_NODE_FIELD(identitySequence); + COMPARE_SCALAR_FIELD(generated); COMPARE_NODE_FIELD(collClause); COMPARE_SCALAR_FIELD(collOid); COMPARE_NODE_FIELD(constraints); @@ -2626,6 +2604,7 @@ _equalConstraint(const Constraint *a, const Constraint *b) COMPARE_NODE_FIELD(options); COMPARE_STRING_FIELD(indexname); COMPARE_STRING_FIELD(indexspace); + COMPARE_SCALAR_FIELD(reset_default_tblspc); COMPARE_STRING_FIELD(access_method); COMPARE_NODE_FIELD(where_clause); COMPARE_NODE_FIELD(pktable); @@ -2670,6 +2649,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b) COMPARE_SCALAR_FIELD(rtekind); COMPARE_SCALAR_FIELD(relid); COMPARE_SCALAR_FIELD(relkind); + COMPARE_SCALAR_FIELD(rellockmode); COMPARE_NODE_FIELD(tablesample); COMPARE_NODE_FIELD(subquery); COMPARE_SCALAR_FIELD(security_barrier); @@ -2697,6 +2677,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b) COMPARE_BITMAPSET_FIELD(selectedCols); COMPARE_BITMAPSET_FIELD(insertedCols); COMPARE_BITMAPSET_FIELD(updatedCols); + COMPARE_BITMAPSET_FIELD(extraUpdatedCols); COMPARE_NODE_FIELD(securityQuals); return true; @@ -2830,6 +2811,7 @@ _equalCommonTableExpr(const CommonTableExpr *a, const CommonTableExpr *b) { COMPARE_STRING_FIELD(ctename); COMPARE_NODE_FIELD(aliascolnames); + COMPARE_SCALAR_FIELD(ctematerialized); COMPARE_NODE_FIELD(ctequery); COMPARE_LOCATION_FIELD(location); COMPARE_SCALAR_FIELD(cterecursive); @@ -3042,6 +3024,9 @@ equal(const void *a, const void *b) if (nodeTag(a) != nodeTag(b)) return false; + /* Guard against stack overflow due to overly complex expressions */ + check_stack_depth(); + switch (nodeTag(a)) { /* @@ -3077,8 +3062,8 @@ equal(const void *a, const void *b) case T_WindowFunc: retval = _equalWindowFunc(a, b); break; - case T_ArrayRef: - retval = _equalArrayRef(a, b); + case T_SubscriptingRef: + retval = _equalSubscriptingRef(a, b); break; case T_FuncExpr: retval = _equalFuncExpr(a, b); @@ -3197,9 +3182,6 @@ equal(const void *a, const void *b) case T_OnConflictExpr: retval = _equalOnConflictExpr(a, b); break; - case T_MergeAction: - retval = _equalMergeAction(a, b); - break; case T_JoinExpr: retval = _equalJoinExpr(a, b); break; @@ -3265,12 +3247,6 @@ equal(const void *a, const void *b) case T_UpdateStmt: retval = _equalUpdateStmt(a, b); break; - case T_MergeStmt: - retval = _equalMergeStmt(a, b); - break; - case T_MergeWhenClause: - retval = _equalMergeWhenClause(a, b); - break; case T_SelectStmt: retval = _equalSelectStmt(a, b); break; @@ -3343,6 +3319,9 @@ equal(const void *a, const void *b) case T_CreateStatsStmt: retval = _equalCreateStatsStmt(a, b); break; + case T_AlterStatsStmt: + retval = _equalAlterStatsStmt(a, b); + break; case T_CreateFunctionStmt: retval = _equalCreateFunctionStmt(a, b); break; diff --git a/src/backend/nodes/extensible.c b/src/backend/nodes/extensible.c index f301c11fa98..d35c0149adb 100644 --- a/src/backend/nodes/extensible.c +++ b/src/backend/nodes/extensible.c @@ -10,7 +10,7 @@ * and GetExtensibleNodeMethods to get information about a previously * registered type of extensible node. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/nodes/list.c b/src/backend/nodes/list.c index f3e18007086..6bf13ae0d4a 100644 --- a/src/backend/nodes/list.c +++ b/src/backend/nodes/list.c @@ -1,10 +1,12 @@ /*------------------------------------------------------------------------- * * list.c - * implementation for PostgreSQL generic linked list package + * implementation for PostgreSQL generic list package * + * See comments in pg_list.h. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,10 +18,35 @@ #include "postgres.h" #include "nodes/pg_list.h" +#include "utils/memutils.h" /* - * Routines to simplify writing assertions about the type of a list; a + * The previous List implementation, since it used a separate palloc chunk + * for each cons cell, had the property that adding or deleting list cells + * did not move the storage of other existing cells in the list. Quite a + * bit of existing code depended on that, by retaining ListCell pointers + * across such operations on a list. There is no such guarantee in this + * implementation, so instead we have debugging support that is meant to + * help flush out now-broken assumptions. Defining DEBUG_LIST_MEMORY_USAGE + * while building this file causes the List operations to forcibly move + * all cells in a list whenever a cell is added or deleted. In combination + * with MEMORY_CONTEXT_CHECKING and/or Valgrind, this can usually expose + * broken code. It's a bit expensive though, as there's many more palloc + * cycles and a lot more data-copying than in a default build. + * + * By default, we enable this when building for Valgrind. + */ +#ifdef USE_VALGRIND +#define DEBUG_LIST_MEMORY_USAGE +#endif + +/* Overhead for the fixed part of a List header, measured in ListCells */ +#define LIST_HEADER_OVERHEAD \ + ((int) ((offsetof(List, initial_elements) - 1) / sizeof(ListCell) + 1)) + +/* + * Macros to simplify writing assertions about the type of a list; a * NIL list is considered to be an empty list of any type. */ #define IsPointerList(l) ((l) == NIL || IsA((l), List)) @@ -37,50 +64,221 @@ check_list_invariants(const List *list) return; Assert(list->length > 0); - Assert(list->head != NULL); - Assert(list->tail != NULL); + Assert(list->length <= list->max_length); + Assert(list->elements != NULL); Assert(list->type == T_List || list->type == T_IntList || list->type == T_OidList); - - if (list->length == 1) - Assert(list->head == list->tail); - if (list->length == 2) - Assert(list->head->next == list->tail); - Assert(list->tail->next == NULL); } #else -#define check_list_invariants(l) +#define check_list_invariants(l) ((void) 0) #endif /* USE_ASSERT_CHECKING */ /* - * Return a freshly allocated List. Since empty non-NIL lists are - * invalid, new_list() also allocates the head cell of the new list: - * the caller should be sure to fill in that cell's data. + * Return a freshly allocated List with room for at least min_size cells. + * + * Since empty non-NIL lists are invalid, new_list() sets the initial length + * to min_size, effectively marking that number of cells as valid; the caller + * is responsible for filling in their data. */ static List * -new_list(NodeTag type) +new_list(NodeTag type, int min_size) +{ + List *newlist; + int max_size; + + Assert(min_size > 0); + + /* + * We allocate all the requested cells, and possibly some more, as part of + * the same palloc request as the List header. This is a big win for the + * typical case of short fixed-length lists. It can lose if we allocate a + * moderately long list and then it gets extended; we'll be wasting more + * initial_elements[] space than if we'd made the header small. However, + * rounding up the request as we do in the normal code path provides some + * defense against small extensions. + */ + +#ifndef DEBUG_LIST_MEMORY_USAGE + + /* + * Normally, we set up a list with some extra cells, to allow it to grow + * without a repalloc. Prefer cell counts chosen to make the total + * allocation a power-of-2, since palloc would round it up to that anyway. + * (That stops being true for very large allocations, but very long lists + * are infrequent, so it doesn't seem worth special logic for such cases.) + * + * The minimum allocation is 8 ListCell units, providing either 4 or 5 + * available ListCells depending on the machine's word width. Counting + * palloc's overhead, this uses the same amount of space as a one-cell + * list did in the old implementation, and less space for any longer list. + * + * We needn't worry about integer overflow; no caller passes min_size + * that's more than twice the size of an existing list, so the size limits + * within palloc will ensure that we don't overflow here. + */ + max_size = 8; /* semi-arbitrary small power of 2 */ + while (max_size < min_size + LIST_HEADER_OVERHEAD) + max_size *= 2; + max_size -= LIST_HEADER_OVERHEAD; +#else + + /* + * For debugging, don't allow any extra space. This forces any cell + * addition to go through enlarge_list() and thus move the existing data. + */ + max_size = min_size; +#endif + + newlist = (List *) palloc(offsetof(List, initial_elements) + + max_size * sizeof(ListCell)); + newlist->type = type; + newlist->length = min_size; + newlist->max_length = max_size; + newlist->elements = newlist->initial_elements; + + return newlist; +} + +/* + * Enlarge an existing non-NIL List to have room for at least min_size cells. + * + * This does *not* update list->length, as some callers would find that + * inconvenient. (list->length had better be the correct number of existing + * valid cells, though.) + */ +static void +enlarge_list(List *list, int min_size) +{ + int new_max_len; + + Assert(min_size > list->max_length); /* else we shouldn't be here */ + +#ifndef DEBUG_LIST_MEMORY_USAGE + + /* + * As above, we prefer power-of-two total allocations; but here we need + * not account for list header overhead. The existing max length might + * not be a power of 2, so don't rely on that. + */ + new_max_len = 16; /* semi-arbitrary small power of 2 */ + while (new_max_len < min_size) + new_max_len *= 2; +#else + /* As above, don't allocate anything extra */ + new_max_len = min_size; +#endif + + if (list->elements == list->initial_elements) + { + List *newlist PG_USED_FOR_ASSERTS_ONLY; + + /* + * Replace original in-line allocation with a separate palloc block. + * Ensure it is in the same memory context as the List header. (The + * previous List implementation did not offer any guarantees about + * keeping all list cells in the same context, but it seems reasonable + * to create such a guarantee now.) + */ + list->elements = (ListCell *) + MemoryContextAlloc(GetMemoryChunkContext(list), + new_max_len * sizeof(ListCell)); + memcpy(list->elements, list->initial_elements, + list->length * sizeof(ListCell)); + + /* + * Currently, asking aset.c to reduce the allocated size of the List + * header is pointless in terms of reclaiming space, unless the list + * is very long. However, it seems worth doing anyway to cause the + * no-longer-needed initial_elements[] space to be cleared in + * debugging builds. + */ + newlist = (List *) repalloc(list, offsetof(List, initial_elements)); + + /* That better not have failed, nor moved the list header */ + Assert(newlist == list); + } + else + { +#ifndef DEBUG_LIST_MEMORY_USAGE + /* Normally, let repalloc deal with enlargement */ + list->elements = (ListCell *) repalloc(list->elements, + new_max_len * sizeof(ListCell)); +#else + /* + * repalloc() might enlarge the space in-place, which we don't want + * for debugging purposes, so forcibly move the data somewhere else. + */ + ListCell *newelements; + + newelements = (ListCell *) + MemoryContextAlloc(GetMemoryChunkContext(list), + new_max_len * sizeof(ListCell)); + memcpy(newelements, list->elements, + list->length * sizeof(ListCell)); + pfree(list->elements); + list->elements = newelements; +#endif + } + + list->max_length = new_max_len; +} + +/* + * Convenience functions to construct short Lists from given values. + * (These are normally invoked via the list_makeN macros.) + */ +List * +list_make1_impl(NodeTag t, ListCell datum1) +{ + List *list = new_list(t, 1); + + list->elements[0] = datum1; + check_list_invariants(list); + return list; +} + +List * +list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2) +{ + List *list = new_list(t, 2); + + list->elements[0] = datum1; + list->elements[1] = datum2; + check_list_invariants(list); + return list; +} + +List * +list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3) { - List *new_list; - ListCell *new_head; + List *list = new_list(t, 3); - new_head = (ListCell *) palloc(sizeof(*new_head)); - new_head->next = NULL; - /* new_head->data is left undefined! */ + list->elements[0] = datum1; + list->elements[1] = datum2; + list->elements[2] = datum3; + check_list_invariants(list); + return list; +} - new_list = (List *) palloc(sizeof(*new_list)); - new_list->type = type; - new_list->length = 1; - new_list->head = new_head; - new_list->tail = new_head; +List * +list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4) +{ + List *list = new_list(t, 4); - return new_list; + list->elements[0] = datum1; + list->elements[1] = datum2; + list->elements[2] = datum3; + list->elements[3] = datum4; + check_list_invariants(list); + return list; } /* - * Allocate a new cell and make it the head of the specified - * list. Assumes the list it is passed is non-NIL. + * Make room for a new head cell in the given (non-NIL) list. * * The data in the new head cell is undefined; the caller should be * sure to fill it in @@ -88,18 +286,17 @@ new_list(NodeTag type) static void new_head_cell(List *list) { - ListCell *new_head; - - new_head = (ListCell *) palloc(sizeof(*new_head)); - new_head->next = list->head; - - list->head = new_head; + /* Enlarge array if necessary */ + if (list->length >= list->max_length) + enlarge_list(list, list->length + 1); + /* Now shove the existing data over */ + memmove(&list->elements[1], &list->elements[0], + list->length * sizeof(ListCell)); list->length++; } /* - * Allocate a new cell and make it the tail of the specified - * list. Assumes the list it is passed is non-NIL. + * Make room for a new tail cell in the given (non-NIL) list. * * The data in the new tail cell is undefined; the caller should be * sure to fill it in @@ -107,13 +304,9 @@ new_head_cell(List *list) static void new_tail_cell(List *list) { - ListCell *new_tail; - - new_tail = (ListCell *) palloc(sizeof(*new_tail)); - new_tail->next = NULL; - - list->tail->next = new_tail; - list->tail = new_tail; + /* Enlarge array if necessary */ + if (list->length >= list->max_length) + enlarge_list(list, list->length + 1); list->length++; } @@ -130,11 +323,11 @@ lappend(List *list, void *datum) Assert(IsPointerList(list)); if (list == NIL) - list = new_list(T_List); + list = new_list(T_List, 1); else new_tail_cell(list); - lfirst(list->tail) = datum; + lfirst(list_tail(list)) = datum; check_list_invariants(list); return list; } @@ -148,11 +341,11 @@ lappend_int(List *list, int datum) Assert(IsIntegerList(list)); if (list == NIL) - list = new_list(T_IntList); + list = new_list(T_IntList, 1); else new_tail_cell(list); - lfirst_int(list->tail) = datum; + lfirst_int(list_tail(list)) = datum; check_list_invariants(list); return list; } @@ -166,82 +359,83 @@ lappend_oid(List *list, Oid datum) Assert(IsOidList(list)); if (list == NIL) - list = new_list(T_OidList); + list = new_list(T_OidList, 1); else new_tail_cell(list); - lfirst_oid(list->tail) = datum; + lfirst_oid(list_tail(list)) = datum; check_list_invariants(list); return list; } /* - * Add a new cell to the list, in the position after 'prev_cell'. The - * data in the cell is left undefined, and must be filled in by the - * caller. 'list' is assumed to be non-NIL, and 'prev_cell' is assumed - * to be non-NULL and a member of 'list'. + * Make room for a new cell at position 'pos' (measured from 0). + * The data in the cell is left undefined, and must be filled in by the + * caller. 'list' is assumed to be non-NIL, and 'pos' must be a valid + * list position, ie, 0 <= pos <= list's length. + * Returns address of the new cell. */ static ListCell * -add_new_cell(List *list, ListCell *prev_cell) +insert_new_cell(List *list, int pos) { - ListCell *new_cell; - - new_cell = (ListCell *) palloc(sizeof(*new_cell)); - /* new_cell->data is left undefined! */ - new_cell->next = prev_cell->next; - prev_cell->next = new_cell; - - if (list->tail == prev_cell) - list->tail = new_cell; - + Assert(pos >= 0 && pos <= list->length); + + /* Enlarge array if necessary */ + if (list->length >= list->max_length) + enlarge_list(list, list->length + 1); + /* Now shove the existing data over */ + if (pos < list->length) + memmove(&list->elements[pos + 1], &list->elements[pos], + (list->length - pos) * sizeof(ListCell)); list->length++; - return new_cell; + return &list->elements[pos]; } /* - * Add a new cell to the specified list (which must be non-NIL); - * it will be placed after the list cell 'prev' (which must be - * non-NULL and a member of 'list'). The data placed in the new cell - * is 'datum'. The newly-constructed cell is returned. + * Insert the given datum at position 'pos' (measured from 0) in the list. + * 'pos' must be valid, ie, 0 <= pos <= list's length. */ -ListCell * -lappend_cell(List *list, ListCell *prev, void *datum) +List * +list_insert_nth(List *list, int pos, void *datum) { - ListCell *new_cell; - + if (list == NIL) + { + Assert(pos == 0); + return list_make1(datum); + } Assert(IsPointerList(list)); - - new_cell = add_new_cell(list, prev); - lfirst(new_cell) = datum; + lfirst(insert_new_cell(list, pos)) = datum; check_list_invariants(list); - return new_cell; + return list; } -ListCell * -lappend_cell_int(List *list, ListCell *prev, int datum) +List * +list_insert_nth_int(List *list, int pos, int datum) { - ListCell *new_cell; - + if (list == NIL) + { + Assert(pos == 0); + return list_make1_int(datum); + } Assert(IsIntegerList(list)); - - new_cell = add_new_cell(list, prev); - lfirst_int(new_cell) = datum; + lfirst_int(insert_new_cell(list, pos)) = datum; check_list_invariants(list); - return new_cell; + return list; } -ListCell * -lappend_cell_oid(List *list, ListCell *prev, Oid datum) +List * +list_insert_nth_oid(List *list, int pos, Oid datum) { - ListCell *new_cell; - + if (list == NIL) + { + Assert(pos == 0); + return list_make1_oid(datum); + } Assert(IsOidList(list)); - - new_cell = add_new_cell(list, prev); - lfirst_oid(new_cell) = datum; + lfirst_oid(insert_new_cell(list, pos)) = datum; check_list_invariants(list); - return new_cell; + return list; } /* @@ -261,11 +455,11 @@ lcons(void *datum, List *list) Assert(IsPointerList(list)); if (list == NIL) - list = new_list(T_List); + list = new_list(T_List, 1); else new_head_cell(list); - lfirst(list->head) = datum; + lfirst(list_head(list)) = datum; check_list_invariants(list); return list; } @@ -279,11 +473,11 @@ lcons_int(int datum, List *list) Assert(IsIntegerList(list)); if (list == NIL) - list = new_list(T_IntList); + list = new_list(T_IntList, 1); else new_head_cell(list); - lfirst_int(list->head) = datum; + lfirst_int(list_head(list)) = datum; check_list_invariants(list); return list; } @@ -297,46 +491,87 @@ lcons_oid(Oid datum, List *list) Assert(IsOidList(list)); if (list == NIL) - list = new_list(T_OidList); + list = new_list(T_OidList, 1); else new_head_cell(list); - lfirst_oid(list->head) = datum; + lfirst_oid(list_head(list)) = datum; check_list_invariants(list); return list; } /* - * Concatenate list2 to the end of list1, and return list1. list1 is - * destructively changed. Callers should be sure to use the return - * value as the new pointer to the concatenated list: the 'list1' - * input pointer may or may not be the same as the returned pointer. + * Concatenate list2 to the end of list1, and return list1. + * + * This is equivalent to lappend'ing each element of list2, in order, to list1. + * list1 is destructively changed, list2 is not. (However, in the case of + * pointer lists, list1 and list2 will point to the same structures.) * - * The nodes in list2 are merely appended to the end of list1 in-place - * (i.e. they aren't copied; the two lists will share some of the same - * storage). Therefore, invoking list_free() on list2 will also - * invalidate a portion of list1. + * Callers should be sure to use the return value as the new pointer to the + * concatenated list: the 'list1' input pointer may or may not be the same + * as the returned pointer. */ List * -list_concat(List *list1, List *list2) +list_concat(List *list1, const List *list2) { + int new_len; + if (list1 == NIL) - return list2; + return list_copy(list2); if (list2 == NIL) return list1; - if (list1 == list2) - elog(ERROR, "cannot list_concat() a list to itself"); Assert(list1->type == list2->type); - list1->length += list2->length; - list1->tail->next = list2->head; - list1->tail = list2->tail; + new_len = list1->length + list2->length; + /* Enlarge array if necessary */ + if (new_len > list1->max_length) + enlarge_list(list1, new_len); + + /* Even if list1 == list2, using memcpy should be safe here */ + memcpy(&list1->elements[list1->length], &list2->elements[0], + list2->length * sizeof(ListCell)); + list1->length = new_len; check_list_invariants(list1); return list1; } +/* + * Form a new list by concatenating the elements of list1 and list2. + * + * Neither input list is modified. (However, if they are pointer lists, + * the output list will point to the same structures.) + * + * This is equivalent to, but more efficient than, + * list_concat(list_copy(list1), list2). + * Note that some pre-v13 code might list_copy list2 as well, but that's + * pointless now. + */ +List * +list_concat_copy(const List *list1, const List *list2) +{ + List *result; + int new_len; + + if (list1 == NIL) + return list_copy(list2); + if (list2 == NIL) + return list_copy(list1); + + Assert(list1->type == list2->type); + + new_len = list1->length + list2->length; + result = new_list(list1->type, new_len); + memcpy(result->elements, list1->elements, + list1->length * sizeof(ListCell)); + memcpy(result->elements + list1->length, list2->elements, + list2->length * sizeof(ListCell)); + + check_list_invariants(result); + return result; +} + /* * Truncate 'list' to contain no more than 'new_size' elements. This * modifies the list in-place! Despite this, callers should use the @@ -349,92 +584,26 @@ list_concat(List *list1, List *list2) List * list_truncate(List *list, int new_size) { - ListCell *cell; - int n; - if (new_size <= 0) return NIL; /* truncate to zero length */ /* If asked to effectively extend the list, do nothing */ - if (new_size >= list_length(list)) - return list; + if (new_size < list_length(list)) + list->length = new_size; - n = 1; - foreach(cell, list) - { - if (n == new_size) - { - cell->next = NULL; - list->tail = cell; - list->length = new_size; - check_list_invariants(list); - return list; - } - n++; - } + /* + * Note: unlike the individual-list-cell deletion functions, we don't move + * the list cells to new storage, even in DEBUG_LIST_MEMORY_USAGE mode. + * This is because none of them can move in this operation, so just like + * in the old cons-cell-based implementation, this function doesn't + * invalidate any pointers to cells of the list. This is also the reason + * for not wiping the memory of the deleted cells: the old code didn't + * free them either. Perhaps later we'll tighten this up. + */ - /* keep the compiler quiet; never reached */ - Assert(false); return list; } -/* - * Locate the n'th cell (counting from 0) of the list. It is an assertion - * failure if there is no such cell. - */ -ListCell * -list_nth_cell(const List *list, int n) -{ - ListCell *match; - - Assert(list != NIL); - Assert(n >= 0); - Assert(n < list->length); - check_list_invariants(list); - - /* Does the caller actually mean to fetch the tail? */ - if (n == list->length - 1) - return list->tail; - - for (match = list->head; n-- > 0; match = match->next) - ; - - return match; -} - -/* - * Return the data value contained in the n'th element of the - * specified list. (List elements begin at 0.) - */ -void * -list_nth(const List *list, int n) -{ - Assert(IsPointerList(list)); - return lfirst(list_nth_cell(list, n)); -} - -/* - * Return the integer value contained in the n'th element of the - * specified list. - */ -int -list_nth_int(const List *list, int n) -{ - Assert(IsIntegerList(list)); - return lfirst_int(list_nth_cell(list, n)); -} - -/* - * Return the OID value contained in the n'th element of the specified - * list. - */ -Oid -list_nth_oid(const List *list, int n) -{ - Assert(IsOidList(list)); - return lfirst_oid(list_nth_cell(list, n)); -} - /* * Return true iff 'datum' is a member of the list. Equality is * determined via equal(), so callers should ensure that they pass a @@ -519,16 +688,16 @@ list_member_oid(const List *list, Oid datum) } /* - * Delete 'cell' from 'list'; 'prev' is the previous element to 'cell' - * in 'list', if any (i.e. prev == NULL iff list->head == cell) + * Delete the n'th cell (counting from 0) in list. * - * The cell is pfree'd, as is the List header if this was the last member. + * The List is pfree'd if this was the last member. */ List * -list_delete_cell(List *list, ListCell *cell, ListCell *prev) +list_delete_nth_cell(List *list, int n) { check_list_invariants(list); - Assert(prev != NULL ? lnext(prev) == cell : list_head(list) == cell); + + Assert(n >= 0 && n < list->length); /* * If we're about to delete the last node from the list, free the whole @@ -542,23 +711,61 @@ list_delete_cell(List *list, ListCell *cell, ListCell *prev) } /* - * Otherwise, adjust the necessary list links, deallocate the particular - * node we have just removed, and return the list we were given. + * Otherwise, we normally just collapse out the removed element. But for + * debugging purposes, move the whole list contents someplace else. + * + * (Note that we *must* keep the contents in the same memory context.) */ +#ifndef DEBUG_LIST_MEMORY_USAGE + memmove(&list->elements[n], &list->elements[n + 1], + (list->length - 1 - n) * sizeof(ListCell)); list->length--; +#else + { + ListCell *newelems; + int newmaxlen = list->length - 1; + + newelems = (ListCell *) + MemoryContextAlloc(GetMemoryChunkContext(list), + newmaxlen * sizeof(ListCell)); + memcpy(newelems, list->elements, n * sizeof(ListCell)); + memcpy(&newelems[n], &list->elements[n + 1], + (list->length - 1 - n) * sizeof(ListCell)); + if (list->elements != list->initial_elements) + pfree(list->elements); + else + { + /* + * As in enlarge_list(), tell palloc code we're not using the + * initial_elements space anymore. + */ + List *newlist PG_USED_FOR_ASSERTS_ONLY; + + newlist = (List *) repalloc(list, offsetof(List, initial_elements)); + Assert(newlist == list); + } + list->elements = newelems; + list->max_length = newmaxlen; + list->length--; + check_list_invariants(list); + } +#endif - if (prev) - prev->next = cell->next; - else - list->head = cell->next; - - if (list->tail == cell) - list->tail = prev; - - pfree(cell); return list; } +/* + * Delete 'cell' from 'list'. + * + * The List is pfree'd if this was the last member. However, we do not + * touch any data the cell might've been pointing to. + */ +List * +list_delete_cell(List *list, ListCell *cell) +{ + return list_delete_nth_cell(list, cell - list->elements); +} + /* * Delete the first cell in list that matches datum, if any. * Equality is determined via equal(). @@ -567,18 +774,14 @@ List * list_delete(List *list, void *datum) { ListCell *cell; - ListCell *prev; Assert(IsPointerList(list)); check_list_invariants(list); - prev = NULL; foreach(cell, list) { if (equal(lfirst(cell), datum)) - return list_delete_cell(list, cell, prev); - - prev = cell; + return list_delete_cell(list, cell); } /* Didn't find a match: return the list unmodified */ @@ -590,18 +793,14 @@ List * list_delete_ptr(List *list, void *datum) { ListCell *cell; - ListCell *prev; Assert(IsPointerList(list)); check_list_invariants(list); - prev = NULL; foreach(cell, list) { if (lfirst(cell) == datum) - return list_delete_cell(list, cell, prev); - - prev = cell; + return list_delete_cell(list, cell); } /* Didn't find a match: return the list unmodified */ @@ -613,18 +812,14 @@ List * list_delete_int(List *list, int datum) { ListCell *cell; - ListCell *prev; Assert(IsIntegerList(list)); check_list_invariants(list); - prev = NULL; foreach(cell, list) { if (lfirst_int(cell) == datum) - return list_delete_cell(list, cell, prev); - - prev = cell; + return list_delete_cell(list, cell); } /* Didn't find a match: return the list unmodified */ @@ -636,18 +831,14 @@ List * list_delete_oid(List *list, Oid datum) { ListCell *cell; - ListCell *prev; Assert(IsOidList(list)); check_list_invariants(list); - prev = NULL; foreach(cell, list) { if (lfirst_oid(cell) == datum) - return list_delete_cell(list, cell, prev); - - prev = cell; + return list_delete_cell(list, cell); } /* Didn't find a match: return the list unmodified */ @@ -659,8 +850,8 @@ list_delete_oid(List *list, Oid datum) * * This is useful to replace the Lisp-y code "list = lnext(list);" in cases * where the intent is to alter the list rather than just traverse it. - * Beware that the removed cell is freed, whereas the lnext() coding leaves - * the original list head intact if there's another pointer to it. + * Beware that the list is modified, whereas the Lisp-y coding leaves + * the original list head intact in case there's another pointer to it. */ List * list_delete_first(List *list) @@ -670,7 +861,31 @@ list_delete_first(List *list) if (list == NIL) return NIL; /* would an error be better? */ - return list_delete_cell(list, list_head(list), NULL); + return list_delete_nth_cell(list, 0); +} + +/* + * Delete the last element of the list. + * + * This is the opposite of list_delete_first(), but is noticeably cheaper + * with a long list, since no data need be moved. + */ +List * +list_delete_last(List *list) +{ + check_list_invariants(list); + + if (list == NIL) + return NIL; /* would an error be better? */ + + /* list_truncate won't free list if it goes to empty, but this should */ + if (list_length(list) <= 1) + { + list_free(list); + return NIL; + } + + return list_truncate(list, list_length(list) - 1); } /* @@ -688,7 +903,7 @@ list_delete_first(List *list) * in list1 (so it only performs a "union" if list1 is known unique to * start with). Also, if you are about to write "x = list_union(x, y)" * you probably want to use list_concat_unique() instead to avoid wasting - * the list cells of the old x list. + * the storage of the old x list. * * This function could probably be implemented a lot faster if it is a * performance bottleneck. @@ -1011,11 +1226,12 @@ list_append_unique_oid(List *list, Oid datum) * via equal(). * * This is almost the same functionality as list_union(), but list1 is - * modified in-place rather than being copied. Note also that list2's cells - * are not inserted in list1, so the analogy to list_concat() isn't perfect. + * modified in-place rather than being copied. However, callers of this + * function may have strict ordering expectations -- i.e. that the relative + * order of those list2 elements that are not duplicates is preserved. */ List * -list_concat_unique(List *list1, List *list2) +list_concat_unique(List *list1, const List *list2) { ListCell *cell; @@ -1037,7 +1253,7 @@ list_concat_unique(List *list1, List *list2) * simple pointer equality. */ List * -list_concat_unique_ptr(List *list1, List *list2) +list_concat_unique_ptr(List *list1, const List *list2) { ListCell *cell; @@ -1058,7 +1274,7 @@ list_concat_unique_ptr(List *list1, List *list2) * This variant of list_concat_unique() operates upon lists of integers. */ List * -list_concat_unique_int(List *list1, List *list2) +list_concat_unique_int(List *list1, const List *list2) { ListCell *cell; @@ -1079,7 +1295,7 @@ list_concat_unique_int(List *list1, List *list2) * This variant of list_concat_unique() operates upon lists of OIDs. */ List * -list_concat_unique_oid(List *list1, List *list2) +list_concat_unique_oid(List *list1, const List *list2) { ListCell *cell; @@ -1096,29 +1312,53 @@ list_concat_unique_oid(List *list1, List *list2) return list1; } +/* + * Remove adjacent duplicates in a list of OIDs. + * + * It is caller's responsibility to have sorted the list to bring duplicates + * together, perhaps via list_sort(list, list_oid_cmp). + */ +void +list_deduplicate_oid(List *list) +{ + int len; + + Assert(IsOidList(list)); + len = list_length(list); + if (len > 1) + { + ListCell *elements = list->elements; + int i = 0; + + for (int j = 1; j < len; j++) + { + if (elements[i].oid_value != elements[j].oid_value) + elements[++i].oid_value = elements[j].oid_value; + } + list->length = i + 1; + } + check_list_invariants(list); +} + /* * Free all storage in a list, and optionally the pointed-to elements */ static void list_free_private(List *list, bool deep) { - ListCell *cell; + if (list == NIL) + return; /* nothing to do */ check_list_invariants(list); - cell = list_head(list); - while (cell != NULL) + if (deep) { - ListCell *tmp = cell; - - cell = lnext(cell); - if (deep) - pfree(lfirst(tmp)); - pfree(tmp); + for (int i = 0; i < list->length; i++) + pfree(lfirst(&list->elements[i])); } - - if (list) - pfree(list); + if (list->elements != list->initial_elements) + pfree(list->elements); + pfree(list); } /* @@ -1160,37 +1400,13 @@ List * list_copy(const List *oldlist) { List *newlist; - ListCell *newlist_prev; - ListCell *oldlist_cur; if (oldlist == NIL) return NIL; - newlist = new_list(oldlist->type); - newlist->length = oldlist->length; - - /* - * Copy over the data in the first cell; new_list() has already allocated - * the head cell itself - */ - newlist->head->data = oldlist->head->data; - - newlist_prev = newlist->head; - oldlist_cur = oldlist->head->next; - while (oldlist_cur) - { - ListCell *newlist_cur; - - newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur)); - newlist_cur->data = oldlist_cur->data; - newlist_prev->next = newlist_cur; - - newlist_prev = newlist_cur; - oldlist_cur = oldlist_cur->next; - } - - newlist_prev->next = NULL; - newlist->tail = newlist_prev; + newlist = new_list(oldlist->type, oldlist->length); + memcpy(newlist->elements, oldlist->elements, + newlist->length * sizeof(ListCell)); check_list_invariants(newlist); return newlist; @@ -1203,8 +1419,6 @@ List * list_copy_tail(const List *oldlist, int nskip) { List *newlist; - ListCell *newlist_prev; - ListCell *oldlist_cur; if (nskip < 0) nskip = 0; /* would it be better to elog? */ @@ -1212,125 +1426,80 @@ list_copy_tail(const List *oldlist, int nskip) if (oldlist == NIL || nskip >= oldlist->length) return NIL; - newlist = new_list(oldlist->type); - newlist->length = oldlist->length - nskip; - - /* - * Skip over the unwanted elements. - */ - oldlist_cur = oldlist->head; - while (nskip-- > 0) - oldlist_cur = oldlist_cur->next; - - /* - * Copy over the data in the first remaining cell; new_list() has already - * allocated the head cell itself - */ - newlist->head->data = oldlist_cur->data; - - newlist_prev = newlist->head; - oldlist_cur = oldlist_cur->next; - while (oldlist_cur) - { - ListCell *newlist_cur; - - newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur)); - newlist_cur->data = oldlist_cur->data; - newlist_prev->next = newlist_cur; - - newlist_prev = newlist_cur; - oldlist_cur = oldlist_cur->next; - } - - newlist_prev->next = NULL; - newlist->tail = newlist_prev; + newlist = new_list(oldlist->type, oldlist->length - nskip); + memcpy(newlist->elements, &oldlist->elements[nskip], + newlist->length * sizeof(ListCell)); check_list_invariants(newlist); return newlist; } /* - * Sort a list as though by qsort. + * Return a deep copy of the specified list. * - * A new list is built and returned. Like list_copy, this doesn't make - * fresh copies of any pointed-to data. - * - * The comparator function receives arguments of type ListCell **. + * The list elements are copied via copyObject(), so that this function's + * idea of a "deep" copy is considerably deeper than what list_free_deep() + * means by the same word. */ List * -list_qsort(const List *list, list_qsort_comparator cmp) +list_copy_deep(const List *oldlist) { - int len = list_length(list); - ListCell **list_arr; List *newlist; - ListCell *newlist_prev; - ListCell *cell; - int i; - /* Empty list is easy */ - if (len == 0) + if (oldlist == NIL) return NIL; - /* Flatten list cells into an array, so we can use qsort */ - list_arr = (ListCell **) palloc(sizeof(ListCell *) * len); - i = 0; - foreach(cell, list) - list_arr[i++] = cell; - - qsort(list_arr, len, sizeof(ListCell *), cmp); - - /* Construct new list (this code is much like list_copy) */ - newlist = new_list(list->type); - newlist->length = len; - - /* - * Copy over the data in the first cell; new_list() has already allocated - * the head cell itself - */ - newlist->head->data = list_arr[0]->data; - - newlist_prev = newlist->head; - for (i = 1; i < len; i++) - { - ListCell *newlist_cur; - - newlist_cur = (ListCell *) palloc(sizeof(*newlist_cur)); - newlist_cur->data = list_arr[i]->data; - newlist_prev->next = newlist_cur; + /* This is only sensible for pointer Lists */ + Assert(IsA(oldlist, List)); - newlist_prev = newlist_cur; - } - - newlist_prev->next = NULL; - newlist->tail = newlist_prev; - - /* Might as well free the workspace array */ - pfree(list_arr); + newlist = new_list(oldlist->type, oldlist->length); + for (int i = 0; i < newlist->length; i++) + lfirst(&newlist->elements[i]) = + copyObjectImpl(lfirst(&oldlist->elements[i])); check_list_invariants(newlist); return newlist; } /* - * Temporary compatibility functions + * Sort a list according to the specified comparator function. + * + * The list is sorted in-place. * - * In order to avoid warnings for these function definitions, we need - * to include a prototype here as well as in pg_list.h. That's because - * we don't enable list API compatibility in list.c, so we - * don't see the prototypes for these functions. + * The comparator function is declared to receive arguments of type + * const ListCell *; this allows it to use lfirst() and variants + * without casting its arguments. Otherwise it behaves the same as + * the comparator function for standard qsort(). + * + * Like qsort(), this provides no guarantees about sort stability + * for equal keys. */ +void +list_sort(List *list, list_sort_comparator cmp) +{ + typedef int (*qsort_comparator) (const void *a, const void *b); + int len; + + check_list_invariants(list); + + /* Nothing to do if there's less than two elements */ + len = list_length(list); + if (len > 1) + qsort(list->elements, len, sizeof(ListCell), (qsort_comparator) cmp); +} /* - * Given a list, return its length. This is merely defined for the - * sake of backward compatibility: we can't afford to define a macro - * called "length", so it must be a function. New code should use the - * list_length() macro in order to avoid the overhead of a function - * call. + * list_sort comparator for sorting a list into ascending OID order. */ -int length(const List *list); - int -length(const List *list) +list_oid_cmp(const ListCell *p1, const ListCell *p2) { - return list_length(list); + Oid v1 = lfirst_oid(p1); + Oid v2 = lfirst_oid(p2); + + if (v1 < v2) + return -1; + if (v1 > v2) + return 1; + return 0; } diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index 1bd2599c2c5..18466ac5687 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * makefuncs.c - * creator functions for primitive nodes. The functions here are for - * the most frequently created nodes. + * creator functions for various nodes. The functions here are for the + * most frequently created nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,7 +17,6 @@ #include "catalog/pg_class.h" #include "catalog/pg_type.h" -#include "fmgr.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "utils/lsyscache.h" @@ -496,7 +495,6 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid) n->is_local = true; n->is_not_null = false; n->is_from_type = false; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -599,6 +597,189 @@ makeFuncCall(List *name, List *args, int location) return n; } +/* + * make_opclause + * Creates an operator clause given its operator info, left operand + * and right operand (pass NULL to create single-operand clause), + * and collation info. + */ +Expr * +make_opclause(Oid opno, Oid opresulttype, bool opretset, + Expr *leftop, Expr *rightop, + Oid opcollid, Oid inputcollid) +{ + OpExpr *expr = makeNode(OpExpr); + + expr->opno = opno; + expr->opfuncid = InvalidOid; + expr->opresulttype = opresulttype; + expr->opretset = opretset; + expr->opcollid = opcollid; + expr->inputcollid = inputcollid; + if (rightop) + expr->args = list_make2(leftop, rightop); + else + expr->args = list_make1(leftop); + expr->location = -1; + return (Expr *) expr; +} + +/* + * make_andclause + * + * Creates an 'and' clause given a list of its subclauses. + */ +Expr * +make_andclause(List *andclauses) +{ + BoolExpr *expr = makeNode(BoolExpr); + + expr->boolop = AND_EXPR; + expr->args = andclauses; + expr->location = -1; + return (Expr *) expr; +} + +/* + * make_orclause + * + * Creates an 'or' clause given a list of its subclauses. + */ +Expr * +make_orclause(List *orclauses) +{ + BoolExpr *expr = makeNode(BoolExpr); + + expr->boolop = OR_EXPR; + expr->args = orclauses; + expr->location = -1; + return (Expr *) expr; +} + +/* + * make_notclause + * + * Create a 'not' clause given the expression to be negated. + */ +Expr * +make_notclause(Expr *notclause) +{ + BoolExpr *expr = makeNode(BoolExpr); + + expr->boolop = NOT_EXPR; + expr->args = list_make1(notclause); + expr->location = -1; + return (Expr *) expr; +} + +/* + * make_and_qual + * + * Variant of make_andclause for ANDing two qual conditions together. + * Qual conditions have the property that a NULL nodetree is interpreted + * as 'true'. + * + * NB: this makes no attempt to preserve AND/OR flatness; so it should not + * be used on a qual that has already been run through prepqual.c. + */ +Node * +make_and_qual(Node *qual1, Node *qual2) +{ + if (qual1 == NULL) + return qual2; + if (qual2 == NULL) + return qual1; + return (Node *) make_andclause(list_make2(qual1, qual2)); +} + +/* + * The planner and executor usually represent qualification expressions + * as lists of boolean expressions with implicit AND semantics. + * + * These functions convert between an AND-semantics expression list and the + * ordinary representation of a boolean expression. + * + * Note that an empty list is considered equivalent to TRUE. + */ +Expr * +make_ands_explicit(List *andclauses) +{ + if (andclauses == NIL) + return (Expr *) makeBoolConst(true, false); + else if (list_length(andclauses) == 1) + return (Expr *) linitial(andclauses); + else + return make_andclause(andclauses); +} + +List * +make_ands_implicit(Expr *clause) +{ + /* + * NB: because the parser sets the qual field to NULL in a query that has + * no WHERE clause, we must consider a NULL input clause as TRUE, even + * though one might more reasonably think it FALSE. + */ + if (clause == NULL) + return NIL; /* NULL -> NIL list == TRUE */ + else if (is_andclause(clause)) + return ((BoolExpr *) clause)->args; + else if (IsA(clause, Const) && + !((Const *) clause)->constisnull && + DatumGetBool(((Const *) clause)->constvalue)) + return NIL; /* constant TRUE input -> NIL list */ + else + return list_make1(clause); +} + +/* + * makeIndexInfo + * create an IndexInfo node + */ +IndexInfo * +makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions, + List *predicates, bool unique, bool isready, bool concurrent) +{ + IndexInfo *n = makeNode(IndexInfo); + + n->ii_NumIndexAttrs = numattrs; + n->ii_NumIndexKeyAttrs = numkeyattrs; + Assert(n->ii_NumIndexKeyAttrs != 0); + Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs); + n->ii_Unique = unique; + n->ii_ReadyForInserts = isready; + n->ii_Concurrent = concurrent; + + /* expressions */ + n->ii_Expressions = expressions; + n->ii_ExpressionsState = NIL; + + /* predicates */ + n->ii_Predicate = predicates; + n->ii_PredicateState = NULL; + + /* exclusion constraints */ + n->ii_ExclusionOps = NULL; + n->ii_ExclusionProcs = NULL; + n->ii_ExclusionStrats = NULL; + + /* speculative inserts */ + n->ii_UniqueOps = NULL; + n->ii_UniqueProcs = NULL; + n->ii_UniqueStrats = NULL; + + /* initialize index-build state to default */ + n->ii_BrokenHotChain = false; + n->ii_ParallelWorkers = 0; + + /* set up for possible use by index AM */ + n->ii_Am = amoid; + n->ii_AmCache = NULL; + n->ii_Context = CurrentMemoryContext; + + return n; +} + /* * makeGroupingSet * diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 4c309d236a3..18bd5ac903e 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -3,7 +3,7 @@ * nodeFuncs.c * Various general-purpose manipulations of Node trees * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,7 @@ #include "nodes/makefuncs.h" #include "nodes/execnodes.h" #include "nodes/nodeFuncs.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -31,7 +31,7 @@ static bool fix_opfuncids_walker(Node *node, void *context); static bool planstate_walk_subplans(List *plans, bool (*walker) (), void *context); static bool planstate_walk_members(PlanState **planstates, int nplans, - bool (*walker) (), void *context); + bool (*walker) (), void *context); /* @@ -66,15 +66,15 @@ exprType(const Node *expr) case T_WindowFunc: type = ((const WindowFunc *) expr)->wintype; break; - case T_ArrayRef: + case T_SubscriptingRef: { - const ArrayRef *arrayref = (const ArrayRef *) expr; + const SubscriptingRef *sbsref = (const SubscriptingRef *) expr; - /* slice and/or store operations yield the array type */ - if (arrayref->reflowerindexpr || arrayref->refassgnexpr) - type = arrayref->refarraytype; + /* slice and/or store operations yield the container type */ + if (sbsref->reflowerindexpr || sbsref->refassgnexpr) + type = sbsref->refcontainertype; else - type = arrayref->refelemtype; + type = sbsref->refelemtype; } break; case T_FuncExpr: @@ -286,9 +286,9 @@ exprTypmod(const Node *expr) return ((const Const *) expr)->consttypmod; case T_Param: return ((const Param *) expr)->paramtypmod; - case T_ArrayRef: - /* typmod is the same for array or element */ - return ((const ArrayRef *) expr)->reftypmod; + case T_SubscriptingRef: + /* typmod is the same for container or element */ + return ((const SubscriptingRef *) expr)->reftypmod; case T_FuncExpr: { int32 coercedTypmod; @@ -442,7 +442,7 @@ exprTypmod(const Node *expr) typmod = exprTypmod((Node *) linitial(cexpr->args)); if (typmod < 0) return -1; /* no point in trying harder */ - for_each_cell(arg, lnext(list_head(cexpr->args))) + for_each_cell(arg, cexpr->args, list_second_cell(cexpr->args)) { Node *e = (Node *) lfirst(arg); @@ -470,7 +470,7 @@ exprTypmod(const Node *expr) typmod = exprTypmod((Node *) linitial(mexpr->args)); if (typmod < 0) return -1; /* no point in trying harder */ - for_each_cell(arg, lnext(list_head(mexpr->args))) + for_each_cell(arg, mexpr->args, list_second_cell(mexpr->args)) { Node *e = (Node *) lfirst(arg); @@ -744,8 +744,8 @@ exprCollation(const Node *expr) case T_WindowFunc: coll = ((const WindowFunc *) expr)->wincollid; break; - case T_ArrayRef: - coll = ((const ArrayRef *) expr)->refcollid; + case T_SubscriptingRef: + coll = ((const SubscriptingRef *) expr)->refcollid; break; case T_FuncExpr: coll = ((const FuncExpr *) expr)->funccollid; @@ -862,7 +862,11 @@ exprCollation(const Node *expr) coll = ((const MinMaxExpr *) expr)->minmaxcollid; break; case T_SQLValueFunction: - coll = InvalidOid; /* all cases return non-collatable types */ + /* Returns either NAME or a non-collatable type */ + if (((const SQLValueFunction *) expr)->type == NAMEOID) + coll = C_COLLATION_OID; + else + coll = InvalidOid; break; case T_XmlExpr: @@ -988,8 +992,8 @@ exprSetCollation(Node *expr, Oid collation) case T_WindowFunc: ((WindowFunc *) expr)->wincollid = collation; break; - case T_ArrayRef: - ((ArrayRef *) expr)->refcollid = collation; + case T_SubscriptingRef: + ((SubscriptingRef *) expr)->refcollid = collation; break; case T_FuncExpr: ((FuncExpr *) expr)->funccollid = collation; @@ -1075,7 +1079,9 @@ exprSetCollation(Node *expr, Oid collation) ((MinMaxExpr *) expr)->minmaxcollid = collation; break; case T_SQLValueFunction: - Assert(!OidIsValid(collation)); /* no collatable results */ + Assert((((SQLValueFunction *) expr)->type == NAMEOID) ? + (collation == C_COLLATION_OID) : + (collation == InvalidOid)); break; case T_XmlExpr: Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ? @@ -1217,9 +1223,9 @@ exprLocation(const Node *expr) /* function name should always be the first thing */ loc = ((const WindowFunc *) expr)->location; break; - case T_ArrayRef: - /* just use array argument's location */ - loc = exprLocation((Node *) ((const ArrayRef *) expr)->refexpr); + case T_SubscriptingRef: + /* just use container argument's location */ + loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr); break; case T_FuncExpr: { @@ -1910,21 +1916,22 @@ expression_tree_walker(Node *node, return true; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - /* recurse directly for upper/lower array index lists */ - if (expression_tree_walker((Node *) aref->refupperindexpr, + /* recurse directly for upper/lower container index lists */ + if (expression_tree_walker((Node *) sbsref->refupperindexpr, walker, context)) return true; - if (expression_tree_walker((Node *) aref->reflowerindexpr, + if (expression_tree_walker((Node *) sbsref->reflowerindexpr, walker, context)) return true; /* walker must see the refexpr and refassgnexpr, however */ - if (walker(aref->refexpr, context)) + if (walker(sbsref->refexpr, context)) return true; - if (walker(aref->refassgnexpr, context)) + + if (walker(sbsref->refassgnexpr, context)) return true; } break; @@ -2146,16 +2153,6 @@ expression_tree_walker(Node *node, return true; } break; - case T_MergeAction: - { - MergeAction *action = (MergeAction *) node; - - if (walker(action->targetList, context)) - return true; - if (walker(action->qual, context)) - return true; - } - break; case T_PartitionPruneStepOp: { PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node; @@ -2195,6 +2192,17 @@ expression_tree_walker(Node *node, /* groupClauses are deemed uninteresting */ } break; + case T_IndexClause: + { + IndexClause *iclause = (IndexClause *) node; + + if (walker(iclause->rinfo, context)) + return true; + if (expression_tree_walker((Node *) iclause->indexquals, + walker, context)) + return true; + } + break; case T_PlaceHolderVar: return walker(((PlaceHolderVar *) node)->phexpr, context); case T_InferenceElem: @@ -2259,7 +2267,7 @@ expression_tree_walker(Node *node, * Some callers want to suppress visitation of certain items in the sub-Query, * typically because they need to process them specially, or don't actually * want to recurse into subqueries. This is supported by the flags argument, - * which is the bitwise OR of flag values to suppress visitation of + * which is the bitwise OR of flag values to add or suppress visitation of * indicated items. (More flag bits may be added as needed.) */ bool @@ -2276,10 +2284,6 @@ query_tree_walker(Query *query, return true; if (walker((Node *) query->onConflict, context)) return true; - if (walker((Node *) query->mergeSourceTargetList, context)) - return true; - if (walker((Node *) query->mergeActionList, context)) - return true; if (walker((Node *) query->returningList, context)) return true; if (walker((Node *) query->jointree, context)) @@ -2322,8 +2326,12 @@ range_table_walker(List *rtable, { RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt); - /* For historical reasons, visiting RTEs is not the default */ - if (flags & QTW_EXAMINE_RTES) + /* + * Walkers might need to examine the RTE node itself either before or + * after visiting its contents (or, conceivably, both). Note that if + * you specify neither flag, the walker won't visit the RTE at all. + */ + if (flags & QTW_EXAMINE_RTES_BEFORE) if (walker(rte, context)) return true; @@ -2333,10 +2341,6 @@ range_table_walker(List *rtable, if (walker(rte->tablesample, context)) return true; break; - case RTE_CTE: - case RTE_NAMEDTUPLESTORE: - /* nothing to do */ - break; case RTE_SUBQUERY: if (!(flags & QTW_IGNORE_RT_SUBQUERIES)) if (walker(rte->subquery, context)) @@ -2359,10 +2363,19 @@ range_table_walker(List *rtable, if (walker(rte->values_lists, context)) return true; break; + case RTE_CTE: + case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: + /* nothing to do */ + break; } if (walker(rte->securityQuals, context)) return true; + + if (flags & QTW_EXAMINE_RTES_AFTER) + if (walker(rte, context)) + return true; } return false; } @@ -2553,20 +2566,21 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *arrayref = (ArrayRef *) node; - ArrayRef *newnode; + SubscriptingRef *sbsref = (SubscriptingRef *) node; + SubscriptingRef *newnode; - FLATCOPY(newnode, arrayref, ArrayRef); - MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr, + FLATCOPY(newnode, sbsref, SubscriptingRef); + MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr, List *); - MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr, + MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr, List *); - MUTATE(newnode->refexpr, arrayref->refexpr, + MUTATE(newnode->refexpr, sbsref->refexpr, Expr *); - MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr, + MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr, Expr *); + return (Node *) newnode; } break; @@ -2957,18 +2971,6 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; - case T_MergeAction: - { - MergeAction *action = (MergeAction *) node; - MergeAction *newnode; - - FLATCOPY(newnode, action, MergeAction); - MUTATE(newnode->qual, action->qual, Node *); - MUTATE(newnode->targetList, action->targetList, List *); - - return (Node *) newnode; - } - break; case T_PartitionPruneStepOp: { PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node; @@ -3008,6 +3010,17 @@ expression_tree_mutator(Node *node, return (Node *) newnode; } break; + case T_IndexClause: + { + IndexClause *iclause = (IndexClause *) node; + IndexClause *newnode; + + FLATCOPY(newnode, iclause, IndexClause); + MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *); + MUTATE(newnode->indexquals, iclause->indexquals, List *); + return (Node *) newnode; + } + break; case T_PlaceHolderVar: { PlaceHolderVar *phv = (PlaceHolderVar *) node; @@ -3134,8 +3147,6 @@ query_tree_mutator(Query *query, MUTATE(query->targetList, query->targetList, List *); MUTATE(query->withCheckOptions, query->withCheckOptions, List *); MUTATE(query->onConflict, query->onConflict, OnConflictExpr *); - MUTATE(query->mergeSourceTargetList, query->mergeSourceTargetList, List *); - MUTATE(query->mergeActionList, query->mergeActionList, List *); MUTATE(query->returningList, query->returningList, List *); MUTATE(query->jointree, query->jointree, FromExpr *); MUTATE(query->setOperations, query->setOperations, Node *); @@ -3178,10 +3189,6 @@ range_table_mutator(List *rtable, TableSampleClause *); /* we don't bother to copy eref, aliases, etc; OK? */ break; - case RTE_CTE: - case RTE_NAMEDTUPLESTORE: - /* nothing to do */ - break; case RTE_SUBQUERY: if (!(flags & QTW_IGNORE_RT_SUBQUERIES)) { @@ -3212,6 +3219,11 @@ range_table_mutator(List *rtable, case RTE_VALUES: MUTATE(newrte->values_lists, rte->values_lists, List *); break; + case RTE_CTE: + case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: + /* nothing to do */ + break; } MUTATE(newrte->securityQuals, rte->securityQuals, List *); newrt = lappend(newrt, newrte); @@ -3277,9 +3289,9 @@ query_or_expression_tree_mutator(Node *node, * boundaries: we descend to everything that's possibly interesting. * * Currently, the node type coverage here extends only to DML statements - * (SELECT/INSERT/UPDATE/DELETE/MERGE) and nodes that can appear in them, - * because this is used mainly during analysis of CTEs, and only DML - * statements can appear in CTEs. + * (SELECT/INSERT/UPDATE/DELETE) and nodes that can appear in them, because + * this is used mainly during analysis of CTEs, and only DML statements can + * appear in CTEs. */ bool raw_expression_tree_walker(Node *node, @@ -3459,36 +3471,6 @@ raw_expression_tree_walker(Node *node, return true; } break; - case T_MergeStmt: - { - MergeStmt *stmt = (MergeStmt *) node; - - if (walker(stmt->relation, context)) - return true; - if (walker(stmt->source_relation, context)) - return true; - if (walker(stmt->join_condition, context)) - return true; - if (walker(stmt->mergeWhenClauses, context)) - return true; - if (walker(stmt->withClause, context)) - return true; - } - break; - case T_MergeWhenClause: - { - MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node; - - if (walker(mergeWhenClause->condition, context)) - return true; - if (walker(mergeWhenClause->targetList, context)) - return true; - if (walker(mergeWhenClause->cols, context)) - return true; - if (walker(mergeWhenClause->values, context)) - return true; - } - break; case T_SelectStmt: { SelectStmt *stmt = (SelectStmt *) node; @@ -3784,6 +3766,9 @@ planstate_tree_walker(PlanState *planstate, Plan *plan = planstate->plan; ListCell *lc; + /* Guard against stack overflow due to overly complex plan trees */ + check_stack_depth(); + /* initPlan-s */ if (planstate_walk_subplans(planstate->initPlan, walker, context)) return true; diff --git a/src/backend/nodes/nodes.c b/src/backend/nodes/nodes.c index f5ede390e0e..06787a649e3 100644 --- a/src/backend/nodes/nodes.c +++ b/src/backend/nodes/nodes.c @@ -4,7 +4,7 @@ * support code for nodes (now that we have removed the home-brew * inheritance system, our support code for nodes is much simpler) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index ef626b34b3d..b0dcd02ff68 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -3,7 +3,7 @@ * outfuncs.c * Output functions for Postgres tree nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,13 @@ * have an output function defined here (as well as an input function * in readfuncs.c). In addition, plan nodes should have input and * output functions so that they can be sent to parallel workers. + * * For use in debugging, we also provide output functions for nodes - * that appear in raw parsetrees and path. These nodes however need - * not have input functions. + * that appear in raw parsetrees and planner Paths. These node types + * need not have input functions. Output support for raw parsetrees + * is somewhat incomplete, too; in particular, utility statements are + * almost entirely unsupported. We try to support everything that can + * appear in a raw SELECT, though. * *------------------------------------------------------------------------- */ @@ -26,9 +30,10 @@ #include #include "lib/stringinfo.h" +#include "miscadmin.h" #include "nodes/extensible.h" +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" #include "utils/datum.h" #include "utils/rel.h" @@ -105,6 +110,34 @@ static void outChar(StringInfo str, char c); (appendStringInfoString(str, " :" CppAsString(fldname) " "), \ outBitmapset(str, node->fldname)) +#define WRITE_ATTRNUMBER_ARRAY(fldname, len) \ + do { \ + appendStringInfoString(str, " :" CppAsString(fldname) " "); \ + for (int i = 0; i < len; i++) \ + appendStringInfo(str, " %d", node->fldname[i]); \ + } while(0) + +#define WRITE_OID_ARRAY(fldname, len) \ + do { \ + appendStringInfoString(str, " :" CppAsString(fldname) " "); \ + for (int i = 0; i < len; i++) \ + appendStringInfo(str, " %u", node->fldname[i]); \ + } while(0) + +#define WRITE_INT_ARRAY(fldname, len) \ + do { \ + appendStringInfoString(str, " :" CppAsString(fldname) " "); \ + for (int i = 0; i < len; i++) \ + appendStringInfo(str, " %d", node->fldname[i]); \ + } while(0) + +#define WRITE_BOOL_ARRAY(fldname, len) \ + do { \ + appendStringInfoString(str, " :" CppAsString(fldname) " "); \ + for (int i = 0; i < len; i++) \ + appendStringInfo(str, " %s", booltostr(node->fldname[i])); \ + } while(0) + #define booltostr(x) ((x) ? "true" : "false") @@ -185,7 +218,7 @@ _outList(StringInfo str, const List *node) if (IsA(node, List)) { outNode(str, lfirst(lc)); - if (lnext(lc)) + if (lnext(node, lc)) appendStringInfoChar(str, ' '); } else if (IsA(node, IntList)) @@ -272,11 +305,10 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node) WRITE_BOOL_FIELD(transientPlan); WRITE_BOOL_FIELD(dependsOnRole); WRITE_BOOL_FIELD(parallelModeNeeded); - WRITE_BOOL_FIELD(jitFlags); + WRITE_INT_FIELD(jitFlags); WRITE_NODE_FIELD(planTree); WRITE_NODE_FIELD(rtable); WRITE_NODE_FIELD(resultRelations); - WRITE_NODE_FIELD(nonleafResultRelations); WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(subplans); WRITE_BITMAPSET_FIELD(rewindPlanIDs); @@ -372,10 +404,9 @@ _outModifyTable(StringInfo str, const ModifyTable *node) WRITE_ENUM_FIELD(operation, CmdType); WRITE_BOOL_FIELD(canSetTag); WRITE_UINT_FIELD(nominalRelation); - WRITE_NODE_FIELD(partitioned_rels); + WRITE_UINT_FIELD(rootRelation); WRITE_BOOL_FIELD(partColsUpdated); WRITE_NODE_FIELD(resultRelations); - WRITE_INT_FIELD(mergeTargetRelation); WRITE_INT_FIELD(resultRelIndex); WRITE_INT_FIELD(rootResultRelIndex); WRITE_NODE_FIELD(plans); @@ -391,22 +422,6 @@ _outModifyTable(StringInfo str, const ModifyTable *node) WRITE_NODE_FIELD(onConflictWhere); WRITE_UINT_FIELD(exclRelRTI); WRITE_NODE_FIELD(exclRelTlist); - WRITE_NODE_FIELD(mergeSourceTargetList); - WRITE_NODE_FIELD(mergeActionList); -} - -static void -_outMergeWhenClause(StringInfo str, const MergeWhenClause *node) -{ - WRITE_NODE_TYPE("MERGEWHENCLAUSE"); - - WRITE_BOOL_FIELD(matched); - WRITE_ENUM_FIELD(commandType, CmdType); - WRITE_NODE_FIELD(condition); - WRITE_NODE_FIELD(targetList); - WRITE_NODE_FIELD(cols); - WRITE_NODE_FIELD(values); - WRITE_ENUM_FIELD(override, OverridingKind); } static void @@ -416,63 +431,39 @@ _outAppend(StringInfo str, const Append *node) _outPlanInfo(str, (const Plan *) node); - WRITE_NODE_FIELD(partitioned_rels); WRITE_NODE_FIELD(appendplans); WRITE_INT_FIELD(first_partial_plan); - WRITE_NODE_FIELD(part_prune_infos); + WRITE_NODE_FIELD(part_prune_info); } static void _outMergeAppend(StringInfo str, const MergeAppend *node) { - int i; - WRITE_NODE_TYPE("MERGEAPPEND"); _outPlanInfo(str, (const Plan *) node); - WRITE_NODE_FIELD(partitioned_rels); WRITE_NODE_FIELD(mergeplans); - WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :sortColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->sortColIdx[i]); - - appendStringInfoString(str, " :sortOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->sortOperators[i]); - - appendStringInfoString(str, " :collations"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->collations[i]); - - appendStringInfoString(str, " :nullsFirst"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %s", booltostr(node->nullsFirst[i])); + WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols); + WRITE_OID_ARRAY(sortOperators, node->numCols); + WRITE_OID_ARRAY(collations, node->numCols); + WRITE_BOOL_ARRAY(nullsFirst, node->numCols); + WRITE_NODE_FIELD(part_prune_info); } static void _outRecursiveUnion(StringInfo str, const RecursiveUnion *node) { - int i; - WRITE_NODE_TYPE("RECURSIVEUNION"); _outPlanInfo(str, (const Plan *) node); WRITE_INT_FIELD(wtParam); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :dupColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->dupColIdx[i]); - - appendStringInfoString(str, " :dupOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->dupOperators[i]); - + WRITE_ATTRNUMBER_ARRAY(dupColIdx, node->numCols); + WRITE_OID_ARRAY(dupOperators, node->numCols); + WRITE_OID_ARRAY(dupCollations, node->numCols); WRITE_LONG_FIELD(numGroups); } @@ -514,8 +505,6 @@ _outGather(StringInfo str, const Gather *node) static void _outGatherMerge(StringInfo str, const GatherMerge *node) { - int i; - WRITE_NODE_TYPE("GATHERMERGE"); _outPlanInfo(str, (const Plan *) node); @@ -523,23 +512,10 @@ _outGatherMerge(StringInfo str, const GatherMerge *node) WRITE_INT_FIELD(num_workers); WRITE_INT_FIELD(rescan_param); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :sortColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->sortColIdx[i]); - - appendStringInfoString(str, " :sortOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->sortOperators[i]); - - appendStringInfoString(str, " :collations"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->collations[i]); - - appendStringInfoString(str, " :nullsFirst"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %s", booltostr(node->nullsFirst[i])); - + WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols); + WRITE_OID_ARRAY(sortOperators, node->numCols); + WRITE_OID_ARRAY(collations, node->numCols); + WRITE_BOOL_ARRAY(nullsFirst, node->numCols); WRITE_BITMAPSET_FIELD(initParam); } @@ -761,7 +737,6 @@ static void _outMergeJoin(StringInfo str, const MergeJoin *node) { int numCols; - int i; WRITE_NODE_TYPE("MERGEJOIN"); @@ -772,21 +747,10 @@ _outMergeJoin(StringInfo str, const MergeJoin *node) numCols = list_length(node->mergeclauses); - appendStringInfoString(str, " :mergeFamilies"); - for (i = 0; i < numCols; i++) - appendStringInfo(str, " %u", node->mergeFamilies[i]); - - appendStringInfoString(str, " :mergeCollations"); - for (i = 0; i < numCols; i++) - appendStringInfo(str, " %u", node->mergeCollations[i]); - - appendStringInfoString(str, " :mergeStrategies"); - for (i = 0; i < numCols; i++) - appendStringInfo(str, " %d", node->mergeStrategies[i]); - - appendStringInfoString(str, " :mergeNullsFirst"); - for (i = 0; i < numCols; i++) - appendStringInfo(str, " %s", booltostr(node->mergeNullsFirst[i])); + WRITE_OID_ARRAY(mergeFamilies, numCols); + WRITE_OID_ARRAY(mergeCollations, numCols); + WRITE_INT_ARRAY(mergeStrategies, numCols); + WRITE_BOOL_ARRAY(mergeNullsFirst, numCols); } static void @@ -797,13 +761,14 @@ _outHashJoin(StringInfo str, const HashJoin *node) _outJoinPlanInfo(str, (const Join *) node); WRITE_NODE_FIELD(hashclauses); + WRITE_NODE_FIELD(hashoperators); + WRITE_NODE_FIELD(hashcollations); + WRITE_NODE_FIELD(hashkeys); } static void _outAgg(StringInfo str, const Agg *node) { - int i; - WRITE_NODE_TYPE("AGG"); _outPlanInfo(str, (const Plan *) node); @@ -811,15 +776,9 @@ _outAgg(StringInfo str, const Agg *node) WRITE_ENUM_FIELD(aggstrategy, AggStrategy); WRITE_ENUM_FIELD(aggsplit, AggSplit); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :grpColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->grpColIdx[i]); - - appendStringInfoString(str, " :grpOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->grpOperators[i]); - + WRITE_ATTRNUMBER_ARRAY(grpColIdx, node->numCols); + WRITE_OID_ARRAY(grpOperators, node->numCols); + WRITE_OID_ARRAY(grpCollations, node->numCols); WRITE_LONG_FIELD(numGroups); WRITE_BITMAPSET_FIELD(aggParams); WRITE_NODE_FIELD(groupingSets); @@ -829,33 +788,19 @@ _outAgg(StringInfo str, const Agg *node) static void _outWindowAgg(StringInfo str, const WindowAgg *node) { - int i; - WRITE_NODE_TYPE("WINDOWAGG"); _outPlanInfo(str, (const Plan *) node); WRITE_UINT_FIELD(winref); WRITE_INT_FIELD(partNumCols); - - appendStringInfoString(str, " :partColIdx"); - for (i = 0; i < node->partNumCols; i++) - appendStringInfo(str, " %d", node->partColIdx[i]); - - appendStringInfoString(str, " :partOperations"); - for (i = 0; i < node->partNumCols; i++) - appendStringInfo(str, " %u", node->partOperators[i]); - + WRITE_ATTRNUMBER_ARRAY(partColIdx, node->partNumCols); + WRITE_OID_ARRAY(partOperators, node->partNumCols); + WRITE_OID_ARRAY(partCollations, node->partNumCols); WRITE_INT_FIELD(ordNumCols); - - appendStringInfoString(str, " :ordColIdx"); - for (i = 0; i < node->ordNumCols; i++) - appendStringInfo(str, " %d", node->ordColIdx[i]); - - appendStringInfoString(str, " :ordOperations"); - for (i = 0; i < node->ordNumCols; i++) - appendStringInfo(str, " %u", node->ordOperators[i]); - + WRITE_ATTRNUMBER_ARRAY(ordColIdx, node->ordNumCols); + WRITE_OID_ARRAY(ordOperators, node->ordNumCols); + WRITE_OID_ARRAY(ordCollations, node->ordNumCols); WRITE_INT_FIELD(frameOptions); WRITE_NODE_FIELD(startOffset); WRITE_NODE_FIELD(endOffset); @@ -869,21 +814,14 @@ _outWindowAgg(StringInfo str, const WindowAgg *node) static void _outGroup(StringInfo str, const Group *node) { - int i; - WRITE_NODE_TYPE("GROUP"); _outPlanInfo(str, (const Plan *) node); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :grpColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->grpColIdx[i]); - - appendStringInfoString(str, " :grpOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->grpOperators[i]); + WRITE_ATTRNUMBER_ARRAY(grpColIdx, node->numCols); + WRITE_OID_ARRAY(grpOperators, node->numCols); + WRITE_OID_ARRAY(grpCollations, node->numCols); } static void @@ -897,49 +835,28 @@ _outMaterial(StringInfo str, const Material *node) static void _outSort(StringInfo str, const Sort *node) { - int i; - WRITE_NODE_TYPE("SORT"); _outPlanInfo(str, (const Plan *) node); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :sortColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->sortColIdx[i]); - - appendStringInfoString(str, " :sortOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->sortOperators[i]); - - appendStringInfoString(str, " :collations"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->collations[i]); - - appendStringInfoString(str, " :nullsFirst"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %s", booltostr(node->nullsFirst[i])); + WRITE_ATTRNUMBER_ARRAY(sortColIdx, node->numCols); + WRITE_OID_ARRAY(sortOperators, node->numCols); + WRITE_OID_ARRAY(collations, node->numCols); + WRITE_BOOL_ARRAY(nullsFirst, node->numCols); } static void _outUnique(StringInfo str, const Unique *node) { - int i; - WRITE_NODE_TYPE("UNIQUE"); _outPlanInfo(str, (const Plan *) node); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :uniqColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->uniqColIdx[i]); - - appendStringInfoString(str, " :uniqOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->uniqOperators[i]); + WRITE_ATTRNUMBER_ARRAY(uniqColIdx, node->numCols); + WRITE_OID_ARRAY(uniqOperators, node->numCols); + WRITE_OID_ARRAY(uniqCollations, node->numCols); } static void @@ -949,6 +866,7 @@ _outHash(StringInfo str, const Hash *node) _outPlanInfo(str, (const Plan *) node); + WRITE_NODE_FIELD(hashkeys); WRITE_OID_FIELD(skewTable); WRITE_INT_FIELD(skewColumn); WRITE_BOOL_FIELD(skewInherit); @@ -958,8 +876,6 @@ _outHash(StringInfo str, const Hash *node) static void _outSetOp(StringInfo str, const SetOp *node) { - int i; - WRITE_NODE_TYPE("SETOP"); _outPlanInfo(str, (const Plan *) node); @@ -967,15 +883,9 @@ _outSetOp(StringInfo str, const SetOp *node) WRITE_ENUM_FIELD(cmd, SetOpCmd); WRITE_ENUM_FIELD(strategy, SetOpStrategy); WRITE_INT_FIELD(numCols); - - appendStringInfoString(str, " :dupColIdx"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %d", node->dupColIdx[i]); - - appendStringInfoString(str, " :dupOperators"); - for (i = 0; i < node->numCols; i++) - appendStringInfo(str, " %u", node->dupOperators[i]); - + WRITE_ATTRNUMBER_ARRAY(dupColIdx, node->numCols); + WRITE_OID_ARRAY(dupOperators, node->numCols); + WRITE_OID_ARRAY(dupCollations, node->numCols); WRITE_INT_FIELD(flagColIdx); WRITE_INT_FIELD(firstFlag); WRITE_LONG_FIELD(numGroups); @@ -1027,6 +937,53 @@ _outPlanRowMark(StringInfo str, const PlanRowMark *node) WRITE_BOOL_FIELD(isParent); } +static void +_outPartitionPruneInfo(StringInfo str, const PartitionPruneInfo *node) +{ + WRITE_NODE_TYPE("PARTITIONPRUNEINFO"); + + WRITE_NODE_FIELD(prune_infos); + WRITE_BITMAPSET_FIELD(other_subplans); +} + +static void +_outPartitionedRelPruneInfo(StringInfo str, const PartitionedRelPruneInfo *node) +{ + WRITE_NODE_TYPE("PARTITIONEDRELPRUNEINFO"); + + WRITE_UINT_FIELD(rtindex); + WRITE_BITMAPSET_FIELD(present_parts); + WRITE_INT_FIELD(nparts); + WRITE_INT_ARRAY(subplan_map, node->nparts); + WRITE_INT_ARRAY(subpart_map, node->nparts); + WRITE_OID_ARRAY(relid_map, node->nparts); + WRITE_NODE_FIELD(initial_pruning_steps); + WRITE_NODE_FIELD(exec_pruning_steps); + WRITE_BITMAPSET_FIELD(execparamids); +} + +static void +_outPartitionPruneStepOp(StringInfo str, const PartitionPruneStepOp *node) +{ + WRITE_NODE_TYPE("PARTITIONPRUNESTEPOP"); + + WRITE_INT_FIELD(step.step_id); + WRITE_INT_FIELD(opstrategy); + WRITE_NODE_FIELD(exprs); + WRITE_NODE_FIELD(cmpfns); + WRITE_BITMAPSET_FIELD(nullkeys); +} + +static void +_outPartitionPruneStepCombine(StringInfo str, const PartitionPruneStepCombine *node) +{ + WRITE_NODE_TYPE("PARTITIONPRUNESTEPCOMBINE"); + + WRITE_INT_FIELD(step.step_id); + WRITE_ENUM_FIELD(combineOp, PartitionPruneCombineOp); + WRITE_NODE_FIELD(source_stepids); +} + static void _outPlanInvalItem(StringInfo str, const PlanInvalItem *node) { @@ -1095,6 +1052,7 @@ _outIntoClause(StringInfo str, const IntoClause *node) WRITE_NODE_FIELD(rel); WRITE_NODE_FIELD(colNames); + WRITE_STRING_FIELD(accessMethod); WRITE_NODE_FIELD(options); WRITE_ENUM_FIELD(onCommit, OnCommitAction); WRITE_STRING_FIELD(tableSpaceName); @@ -1205,11 +1163,11 @@ _outWindowFunc(StringInfo str, const WindowFunc *node) } static void -_outArrayRef(StringInfo str, const ArrayRef *node) +_outSubscriptingRef(StringInfo str, const SubscriptingRef *node) { - WRITE_NODE_TYPE("ARRAYREF"); + WRITE_NODE_TYPE("SUBSCRIPTINGREF"); - WRITE_OID_FIELD(refarraytype); + WRITE_OID_FIELD(refcontainertype); WRITE_OID_FIELD(refelemtype); WRITE_INT_FIELD(reftypmod); WRITE_OID_FIELD(refcollid); @@ -1711,28 +1669,6 @@ _outFromExpr(StringInfo str, const FromExpr *node) WRITE_NODE_FIELD(quals); } -static void -_outPartitionPruneStepOp(StringInfo str, const PartitionPruneStepOp *node) -{ - WRITE_NODE_TYPE("PARTITIONPRUNESTEPOP"); - - WRITE_INT_FIELD(step.step_id); - WRITE_INT_FIELD(opstrategy); - WRITE_NODE_FIELD(exprs); - WRITE_NODE_FIELD(cmpfns); - WRITE_BITMAPSET_FIELD(nullkeys); -} - -static void -_outPartitionPruneStepCombine(StringInfo str, const PartitionPruneStepCombine *node) -{ - WRITE_NODE_TYPE("PARTITIONPRUNESTEPCOMBINE"); - - WRITE_INT_FIELD(step.step_id); - WRITE_ENUM_FIELD(combineOp, PartitionPruneCombineOp); - WRITE_NODE_FIELD(source_stepids); -} - static void _outOnConflictExpr(StringInfo str, const OnConflictExpr *node) { @@ -1748,44 +1684,9 @@ _outOnConflictExpr(StringInfo str, const OnConflictExpr *node) WRITE_NODE_FIELD(exclRelTlist); } -static void -_outMergeAction(StringInfo str, const MergeAction *node) -{ - WRITE_NODE_TYPE("MERGEACTION"); - - WRITE_BOOL_FIELD(matched); - WRITE_ENUM_FIELD(commandType, CmdType); - WRITE_NODE_FIELD(qual); - WRITE_NODE_FIELD(targetList); -} - -static void -_outPartitionPruneInfo(StringInfo str, const PartitionPruneInfo *node) -{ - int i; - - WRITE_NODE_TYPE("PARTITIONPRUNEINFO"); - - WRITE_OID_FIELD(reloid); - WRITE_NODE_FIELD(pruning_steps); - WRITE_BITMAPSET_FIELD(present_parts); - WRITE_INT_FIELD(nparts); - - appendStringInfoString(str, " :subnode_map"); - for (i = 0; i < node->nparts; i++) - appendStringInfo(str, " %d", node->subnode_map[i]); - - appendStringInfoString(str, " :subpart_map"); - for (i = 0; i < node->nparts; i++) - appendStringInfo(str, " %d", node->subpart_map[i]); - - WRITE_BITMAPSET_FIELD(extparams); - WRITE_BITMAPSET_FIELD(execparams); -} - /***************************************************************************** * - * Stuff from relation.h. + * Stuff from pathnodes.h. * *****************************************************************************/ @@ -1853,8 +1754,6 @@ _outIndexPath(StringInfo str, const IndexPath *node) WRITE_NODE_FIELD(indexinfo); WRITE_NODE_FIELD(indexclauses); - WRITE_NODE_FIELD(indexquals); - WRITE_NODE_FIELD(indexqualcols); WRITE_NODE_FIELD(indexorderbys); WRITE_NODE_FIELD(indexorderbycols); WRITE_ENUM_FIELD(indexscandir, ScanDirection); @@ -1948,6 +1847,8 @@ _outAppendPath(StringInfo str, const AppendPath *node) WRITE_NODE_FIELD(partitioned_rels); WRITE_NODE_FIELD(subpaths); + WRITE_INT_FIELD(first_partial_path); + WRITE_FLOAT_FIELD(limit_tuples, "%.0f"); } static void @@ -1963,9 +1864,9 @@ _outMergeAppendPath(StringInfo str, const MergeAppendPath *node) } static void -_outResultPath(StringInfo str, const ResultPath *node) +_outGroupResultPath(StringInfo str, const GroupResultPath *node) { - WRITE_NODE_TYPE("RESULTPATH"); + WRITE_NODE_TYPE("GROUPRESULTPATH"); _outPathInfo(str, (const Path *) node); @@ -2131,7 +2032,6 @@ _outWindowAggPath(StringInfo str, const WindowAggPath *node) WRITE_NODE_FIELD(subpath); WRITE_NODE_FIELD(winclause); - WRITE_NODE_FIELD(winpathkeys); } static void @@ -2186,10 +2086,9 @@ _outModifyTablePath(StringInfo str, const ModifyTablePath *node) WRITE_ENUM_FIELD(operation, CmdType); WRITE_BOOL_FIELD(canSetTag); WRITE_UINT_FIELD(nominalRelation); - WRITE_NODE_FIELD(partitioned_rels); + WRITE_UINT_FIELD(rootRelation); WRITE_BOOL_FIELD(partColsUpdated); WRITE_NODE_FIELD(resultRelations); - WRITE_INT_FIELD(mergeTargetRelation); WRITE_NODE_FIELD(subpaths); WRITE_NODE_FIELD(subroots); WRITE_NODE_FIELD(withCheckOptionLists); @@ -2197,8 +2096,6 @@ _outModifyTablePath(StringInfo str, const ModifyTablePath *node) WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(onconflict); WRITE_INT_FIELD(epqParam); - WRITE_NODE_FIELD(mergeSourceTargetList); - WRITE_NODE_FIELD(mergeActionList); } static void @@ -2255,6 +2152,7 @@ _outHashPath(StringInfo str, const HashPath *node) WRITE_NODE_FIELD(path_hashclauses); WRITE_INT_FIELD(num_batches); + WRITE_FLOAT_FIELD(inner_rows_total, "%.0f"); } static void @@ -2268,7 +2166,6 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node) WRITE_NODE_FIELD(finalrtable); WRITE_NODE_FIELD(finalrowmarks); WRITE_NODE_FIELD(resultRelations); - WRITE_NODE_FIELD(nonleafResultRelations); WRITE_NODE_FIELD(rootResultRelations); WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(invalItems); @@ -2302,6 +2199,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node) WRITE_NODE_FIELD(cte_plan_ids); WRITE_NODE_FIELD(multiexpr_params); WRITE_NODE_FIELD(eq_classes); + WRITE_BOOL_FIELD(ec_merging_done); WRITE_NODE_FIELD(canon_pathkeys); WRITE_NODE_FIELD(left_join_clauses); WRITE_NODE_FIELD(right_join_clauses); @@ -2322,10 +2220,9 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node) WRITE_FLOAT_FIELD(tuple_fraction, "%.4f"); WRITE_FLOAT_FIELD(limit_tuples, "%.0f"); WRITE_UINT_FIELD(qual_security_level); - WRITE_BOOL_FIELD(hasInheritedTarget); + WRITE_ENUM_FIELD(inhTargetKind, InheritanceKind); WRITE_BOOL_FIELD(hasJoinRTEs); WRITE_BOOL_FIELD(hasLateralRTEs); - WRITE_BOOL_FIELD(hasDeletedRTEs); WRITE_BOOL_FIELD(hasHavingQual); WRITE_BOOL_FIELD(hasPseudoConstantQuals); WRITE_BOOL_FIELD(hasRecursion); @@ -2369,6 +2266,7 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node) WRITE_UINT_FIELD(pages); WRITE_FLOAT_FIELD(tuples, "%.0f"); WRITE_FLOAT_FIELD(allvisfrac, "%.6f"); + WRITE_BITMAPSET_FIELD(eclass_indexes); WRITE_NODE_FIELD(subroot); WRITE_NODE_FIELD(subplan_params); WRITE_INT_FIELD(rel_parallel_workers); @@ -2381,6 +2279,7 @@ _outRelOptInfo(StringInfo str, const RelOptInfo *node) WRITE_UINT_FIELD(baserestrict_min_security); WRITE_NODE_FIELD(joininfo); WRITE_BOOL_FIELD(has_eclass_joins); + WRITE_BOOL_FIELD(consider_partitionwise_join); WRITE_BITMAPSET_FIELD(top_parent_relids); WRITE_NODE_FIELD(partitioned_child_rels); } @@ -2420,15 +2319,9 @@ _outForeignKeyOptInfo(StringInfo str, const ForeignKeyOptInfo *node) WRITE_UINT_FIELD(con_relid); WRITE_UINT_FIELD(ref_relid); WRITE_INT_FIELD(nkeys); - appendStringInfoString(str, " :conkey"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %d", node->conkey[i]); - appendStringInfoString(str, " :confkey"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %d", node->confkey[i]); - appendStringInfoString(str, " :conpfeqop"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %u", node->conpfeqop[i]); + WRITE_ATTRNUMBER_ARRAY(conkey, node->nkeys); + WRITE_ATTRNUMBER_ARRAY(confkey, node->nkeys); + WRITE_OID_ARRAY(conpfeqop, node->nkeys); WRITE_INT_FIELD(nmatched_ec); WRITE_INT_FIELD(nmatched_rcols); WRITE_INT_FIELD(nmatched_ri); @@ -2565,6 +2458,18 @@ _outRestrictInfo(StringInfo str, const RestrictInfo *node) WRITE_OID_FIELD(hashjoinoperator); } +static void +_outIndexClause(StringInfo str, const IndexClause *node) +{ + WRITE_NODE_TYPE("INDEXCLAUSE"); + + WRITE_NODE_FIELD(rinfo); + WRITE_NODE_FIELD(indexquals); + WRITE_BOOL_FIELD(lossy); + WRITE_INT_FIELD(indexcol); + WRITE_NODE_FIELD(indexcols); +} + static void _outPlaceHolderVar(StringInfo str, const PlaceHolderVar *node) { @@ -2686,6 +2591,7 @@ _outCreateStmtInfo(StringInfo str, const CreateStmt *node) WRITE_NODE_FIELD(options); WRITE_ENUM_FIELD(oncommit, OnCommitAction); WRITE_STRING_FIELD(tablespacename); + WRITE_STRING_FIELD(accessMethod); WRITE_BOOL_FIELD(if_not_exists); } @@ -2728,7 +2634,6 @@ _outIndexStmt(StringInfo str, const IndexStmt *node) WRITE_STRING_FIELD(idxname); WRITE_NODE_FIELD(relation); - WRITE_OID_FIELD(relationId); WRITE_STRING_FIELD(accessMethod); WRITE_STRING_FIELD(tableSpace); WRITE_NODE_FIELD(indexParams); @@ -2747,6 +2652,7 @@ _outIndexStmt(StringInfo str, const IndexStmt *node) WRITE_BOOL_FIELD(transformed); WRITE_BOOL_FIELD(concurrent); WRITE_BOOL_FIELD(if_not_exists); + WRITE_BOOL_FIELD(reset_default_tblspc); } static void @@ -2762,6 +2668,16 @@ _outCreateStatsStmt(StringInfo str, const CreateStatsStmt *node) WRITE_BOOL_FIELD(if_not_exists); } +static void +_outAlterStatsStmt(StringInfo str, const AlterStatsStmt *node) +{ + WRITE_NODE_TYPE("ALTERSTATSSTMT"); + + WRITE_NODE_FIELD(defnames); + WRITE_INT_FIELD(stxstattarget); + WRITE_BOOL_FIELD(missing_ok); +} + static void _outNotifyStmt(StringInfo str, const NotifyStmt *node) { @@ -2886,12 +2802,12 @@ _outColumnDef(StringInfo str, const ColumnDef *node) WRITE_BOOL_FIELD(is_local); WRITE_BOOL_FIELD(is_not_null); WRITE_BOOL_FIELD(is_from_type); - WRITE_BOOL_FIELD(is_from_parent); WRITE_CHAR_FIELD(storage); WRITE_NODE_FIELD(raw_default); WRITE_NODE_FIELD(cooked_default); WRITE_CHAR_FIELD(identity); WRITE_NODE_FIELD(identitySequence); + WRITE_CHAR_FIELD(generated); WRITE_NODE_FIELD(collClause); WRITE_OID_FIELD(collOid); WRITE_NODE_FIELD(constraints); @@ -3011,10 +2927,7 @@ _outQuery(StringInfo str, const Query *node) WRITE_NODE_FIELD(rowMarks); WRITE_NODE_FIELD(setOperations); WRITE_NODE_FIELD(constraintDeps); - /* withCheckOptions intentionally omitted, see comment in parsenodes.h */ - WRITE_INT_FIELD(mergeTarget_relation); - WRITE_NODE_FIELD(mergeSourceTargetList); - WRITE_NODE_FIELD(mergeActionList); + WRITE_NODE_FIELD(withCheckOptions); WRITE_LOCATION_FIELD(stmt_location); WRITE_LOCATION_FIELD(stmt_len); } @@ -3102,6 +3015,7 @@ _outCommonTableExpr(StringInfo str, const CommonTableExpr *node) WRITE_STRING_FIELD(ctename); WRITE_NODE_FIELD(aliascolnames); + WRITE_ENUM_FIELD(ctematerialized, CTEMaterialize); WRITE_NODE_FIELD(ctequery); WRITE_LOCATION_FIELD(location); WRITE_BOOL_FIELD(cterecursive); @@ -3142,6 +3056,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) case RTE_RELATION: WRITE_OID_FIELD(relid); WRITE_CHAR_FIELD(relkind); + WRITE_INT_FIELD(rellockmode); WRITE_NODE_FIELD(tablesample); break; case RTE_SUBQUERY: @@ -3181,6 +3096,9 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) WRITE_NODE_FIELD(coltypmods); WRITE_NODE_FIELD(colcollations); break; + case RTE_RESULT: + /* no extra fields */ + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) node->rtekind); break; @@ -3194,6 +3112,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node) WRITE_BITMAPSET_FIELD(selectedCols); WRITE_BITMAPSET_FIELD(insertedCols); WRITE_BITMAPSET_FIELD(updatedCols); + WRITE_BITMAPSET_FIELD(extraUpdatedCols); WRITE_NODE_FIELD(securityQuals); } @@ -3362,6 +3281,20 @@ _outParamRef(StringInfo str, const ParamRef *node) WRITE_LOCATION_FIELD(location); } +/* + * Node types found in raw parse trees (supported for debug purposes) + */ + +static void +_outRawStmt(StringInfo str, const RawStmt *node) +{ + WRITE_NODE_TYPE("RAWSTMT"); + + WRITE_NODE_FIELD(stmt); + WRITE_LOCATION_FIELD(stmt_location); + WRITE_INT_FIELD(stmt_len); +} + static void _outAConst(StringInfo str, const A_Const *node) { @@ -3551,6 +3484,13 @@ _outConstraint(StringInfo str, const Constraint *node) WRITE_CHAR_FIELD(generated_when); break; + case CONSTR_GENERATED: + appendStringInfoString(str, "GENERATED"); + WRITE_NODE_FIELD(raw_expr); + WRITE_STRING_FIELD(cooked_expr); + WRITE_CHAR_FIELD(generated_when); + break; + case CONSTR_CHECK: appendStringInfoString(str, "CHECK"); WRITE_BOOL_FIELD(is_no_inherit); @@ -3565,6 +3505,7 @@ _outConstraint(StringInfo str, const Constraint *node) WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexname); WRITE_STRING_FIELD(indexspace); + WRITE_BOOL_FIELD(reset_default_tblspc); /* access_method and where_clause not currently used */ break; @@ -3575,6 +3516,7 @@ _outConstraint(StringInfo str, const Constraint *node) WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexname); WRITE_STRING_FIELD(indexspace); + WRITE_BOOL_FIELD(reset_default_tblspc); /* access_method and where_clause not currently used */ break; @@ -3585,6 +3527,7 @@ _outConstraint(StringInfo str, const Constraint *node) WRITE_NODE_FIELD(options); WRITE_STRING_FIELD(indexname); WRITE_STRING_FIELD(indexspace); + WRITE_BOOL_FIELD(reset_default_tblspc); WRITE_STRING_FIELD(access_method); WRITE_NODE_FIELD(where_clause); break; @@ -3629,22 +3572,15 @@ _outConstraint(StringInfo str, const Constraint *node) static void _outForeignKeyCacheInfo(StringInfo str, const ForeignKeyCacheInfo *node) { - int i; - WRITE_NODE_TYPE("FOREIGNKEYCACHEINFO"); + WRITE_OID_FIELD(conoid); WRITE_OID_FIELD(conrelid); WRITE_OID_FIELD(confrelid); WRITE_INT_FIELD(nkeys); - appendStringInfoString(str, " :conkey"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %d", node->conkey[i]); - appendStringInfoString(str, " :confkey"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %d", node->confkey[i]); - appendStringInfoString(str, " :conpfeqop"); - for (i = 0; i < node->nkeys; i++) - appendStringInfo(str, " %u", node->conpfeqop[i]); + WRITE_ATTRNUMBER_ARRAY(conkey, node->nkeys); + WRITE_ATTRNUMBER_ARRAY(confkey, node->nkeys); + WRITE_OID_ARRAY(conpfeqop, node->nkeys); } static void @@ -3701,6 +3637,9 @@ _outPartitionRangeDatum(StringInfo str, const PartitionRangeDatum *node) void outNode(StringInfo str, const void *obj) { + /* Guard against stack overflow due to overly complex expressions */ + check_stack_depth(); + if (obj == NULL) appendStringInfoString(str, "<>"); else if (IsA(obj, List) ||IsA(obj, IntList) || IsA(obj, OidList)) @@ -3733,9 +3672,6 @@ outNode(StringInfo str, const void *obj) case T_ModifyTable: _outModifyTable(str, obj); break; - case T_MergeWhenClause: - _outMergeWhenClause(str, obj); - break; case T_Append: _outAppend(str, obj); break; @@ -3856,6 +3792,18 @@ outNode(StringInfo str, const void *obj) case T_PlanRowMark: _outPlanRowMark(str, obj); break; + case T_PartitionPruneInfo: + _outPartitionPruneInfo(str, obj); + break; + case T_PartitionedRelPruneInfo: + _outPartitionedRelPruneInfo(str, obj); + break; + case T_PartitionPruneStepOp: + _outPartitionPruneStepOp(str, obj); + break; + case T_PartitionPruneStepCombine: + _outPartitionPruneStepCombine(str, obj); + break; case T_PlanInvalItem: _outPlanInvalItem(str, obj); break; @@ -3889,8 +3837,8 @@ outNode(StringInfo str, const void *obj) case T_WindowFunc: _outWindowFunc(str, obj); break; - case T_ArrayRef: - _outArrayRef(str, obj); + case T_SubscriptingRef: + _outSubscriptingRef(str, obj); break; case T_FuncExpr: _outFuncExpr(str, obj); @@ -4012,18 +3960,6 @@ outNode(StringInfo str, const void *obj) case T_OnConflictExpr: _outOnConflictExpr(str, obj); break; - case T_MergeAction: - _outMergeAction(str, obj); - break; - case T_PartitionPruneStepOp: - _outPartitionPruneStepOp(str, obj); - break; - case T_PartitionPruneStepCombine: - _outPartitionPruneStepCombine(str, obj); - break; - case T_PartitionPruneInfo: - _outPartitionPruneInfo(str, obj); - break; case T_Path: _outPath(str, obj); break; @@ -4057,8 +3993,8 @@ outNode(StringInfo str, const void *obj) case T_MergeAppendPath: _outMergeAppendPath(str, obj); break; - case T_ResultPath: - _outResultPath(str, obj); + case T_GroupResultPath: + _outGroupResultPath(str, obj); break; case T_MaterialPath: _outMaterialPath(str, obj); @@ -4156,6 +4092,9 @@ outNode(StringInfo str, const void *obj) case T_RestrictInfo: _outRestrictInfo(str, obj); break; + case T_IndexClause: + _outIndexClause(str, obj); + break; case T_PlaceHolderVar: _outPlaceHolderVar(str, obj); break; @@ -4201,6 +4140,9 @@ outNode(StringInfo str, const void *obj) case T_CreateStatsStmt: _outCreateStatsStmt(str, obj); break; + case T_AlterStatsStmt: + _outAlterStatsStmt(str, obj); + break; case T_NotifyStmt: _outNotifyStmt(str, obj); break; @@ -4270,6 +4212,9 @@ outNode(StringInfo str, const void *obj) case T_ParamRef: _outParamRef(str, obj); break; + case T_RawStmt: + _outRawStmt(str, obj); + break; case T_A_Const: _outAConst(str, obj); break; diff --git a/src/backend/nodes/params.c b/src/backend/nodes/params.c index 79197b18b48..cf4387e40f0 100644 --- a/src/backend/nodes/params.c +++ b/src/backend/nodes/params.c @@ -4,7 +4,7 @@ * Support for finding the values associated with Param nodes. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,6 +22,33 @@ #include "utils/lsyscache.h" +/* + * Allocate and initialize a new ParamListInfo structure. + * + * To make a new structure for the "dynamic" way (with hooks), pass 0 for + * numParams and set numParams manually. + */ +ParamListInfo +makeParamList(int numParams) +{ + ParamListInfo retval; + Size size; + + size = offsetof(ParamListInfoData, params) + + numParams * sizeof(ParamExternData); + + retval = (ParamListInfo) palloc(size); + retval->paramFetch = NULL; + retval->paramFetchArg = NULL; + retval->paramCompile = NULL; + retval->paramCompileArg = NULL; + retval->parserSetup = NULL; + retval->parserSetupArg = NULL; + retval->numParams = numParams; + + return retval; +} + /* * Copy a ParamListInfo structure. * @@ -36,25 +63,13 @@ ParamListInfo copyParamList(ParamListInfo from) { ParamListInfo retval; - Size size; - int i; if (from == NULL || from->numParams <= 0) return NULL; - size = offsetof(ParamListInfoData, params) + - from->numParams * sizeof(ParamExternData); - - retval = (ParamListInfo) palloc(size); - retval->paramFetch = NULL; - retval->paramFetchArg = NULL; - retval->paramCompile = NULL; - retval->paramCompileArg = NULL; - retval->parserSetup = NULL; - retval->parserSetupArg = NULL; - retval->numParams = from->numParams; + retval = makeParamList(from->numParams); - for (i = 0; i < from->numParams; i++) + for (int i = 0; i < from->numParams; i++) { ParamExternData *oprm; ParamExternData *nprm = &retval->params[i]; @@ -129,7 +144,7 @@ EstimateParamListSpace(ParamListInfo paramLI) } /* - * Serialize a paramListInfo structure into caller-provided storage. + * Serialize a ParamListInfo structure into caller-provided storage. * * We write the number of parameters first, as a 4-byte integer, and then * write details for each parameter in turn. The details for each parameter @@ -211,26 +226,14 @@ ParamListInfo RestoreParamList(char **start_address) { ParamListInfo paramLI; - Size size; - int i; int nparams; memcpy(&nparams, *start_address, sizeof(int)); *start_address += sizeof(int); - size = offsetof(ParamListInfoData, params) + - nparams * sizeof(ParamExternData); - - paramLI = (ParamListInfo) palloc(size); - paramLI->paramFetch = NULL; - paramLI->paramFetchArg = NULL; - paramLI->paramCompile = NULL; - paramLI->paramCompileArg = NULL; - paramLI->parserSetup = NULL; - paramLI->parserSetupArg = NULL; - paramLI->numParams = nparams; + paramLI = makeParamList(nparams); - for (i = 0; i < nparams; i++) + for (int i = 0; i < nparams; i++) { ParamExternData *prm = ¶mLI->params[i]; diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index b9bad5eacca..4ecde6b4211 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -3,7 +3,7 @@ * print.c * various print routines (used mostly for debugging) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,8 +21,9 @@ #include "access/printtup.h" #include "lib/stringinfo.h" +#include "nodes/nodeFuncs.h" +#include "nodes/pathnodes.h" #include "nodes/print.h" -#include "optimizer/clauses.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" @@ -295,6 +296,10 @@ print_rt(const List *rtable) printf("%d\t%s\t[tuplestore]", i, rte->eref->aliasname); break; + case RTE_RESULT: + printf("%d\t%s\t[result]", + i, rte->eref->aliasname); + break; default: printf("%d\t%s\t[unknown rtekind]", i, rte->eref->aliasname); @@ -405,7 +410,7 @@ print_expr(const Node *expr, const List *rtable) foreach(l, e->args) { print_expr(lfirst(l), rtable); - if (lnext(l)) + if (lnext(e->args, l)) printf(","); } printf(")"); @@ -448,7 +453,7 @@ print_pathkeys(const List *pathkeys, const List *rtable) print_expr((Node *) mem->em_expr, rtable); } printf(")"); - if (lnext(i)) + if (lnext(pathkeys, i)) printf(", "); } printf(")\n"); diff --git a/src/backend/nodes/read.c b/src/backend/nodes/read.c index d3c742693bb..fdf68fdcaea 100644 --- a/src/backend/nodes/read.c +++ b/src/backend/nodes/read.c @@ -4,7 +4,7 @@ * routines to convert a string (legal ascii representation of node) back * to nodes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,18 +28,30 @@ /* Static state for pg_strtok */ -static char *pg_strtok_ptr = NULL; +static const char *pg_strtok_ptr = NULL; + +/* State flag that determines how readfuncs.c should treat location fields */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +bool restore_location_fields = false; +#endif /* * stringToNode - - * returns a Node with a given legal ASCII representation + * builds a Node tree from its string representation (assumed valid) + * + * restore_loc_fields instructs readfuncs.c whether to restore location + * fields rather than set them to -1. This is currently only supported + * in builds with the WRITE_READ_PARSE_PLAN_TREES debugging flag set. */ -void * -stringToNode(char *str) +static void * +stringToNodeInternal(const char *str, bool restore_loc_fields) { - char *save_strtok; void *retval; + const char *save_strtok; +#ifdef WRITE_READ_PARSE_PLAN_TREES + bool save_restore_location_fields; +#endif /* * We save and restore the pre-existing state of pg_strtok. This makes the @@ -51,13 +63,45 @@ stringToNode(char *str) pg_strtok_ptr = str; /* point pg_strtok at the string to read */ + /* + * If enabled, likewise save/restore the location field handling flag. + */ +#ifdef WRITE_READ_PARSE_PLAN_TREES + save_restore_location_fields = restore_location_fields; + restore_location_fields = restore_loc_fields; +#endif + retval = nodeRead(NULL, 0); /* do the reading */ pg_strtok_ptr = save_strtok; +#ifdef WRITE_READ_PARSE_PLAN_TREES + restore_location_fields = save_restore_location_fields; +#endif + return retval; } +/* + * Externally visible entry points + */ +void * +stringToNode(const char *str) +{ + return stringToNodeInternal(str, false); +} + +#ifdef WRITE_READ_PARSE_PLAN_TREES + +void * +stringToNodeWithLocations(const char *str) +{ + return stringToNodeInternal(str, true); +} + +#endif + + /***************************************************************************** * * the lisp token parser @@ -104,11 +148,11 @@ stringToNode(char *str) * code should add backslashes to a string constant to ensure it is treated * as a single token. */ -char * +const char * pg_strtok(int *length) { - char *local_str; /* working pointer to string */ - char *ret_str; /* start of token to return */ + const char *local_str; /* working pointer to string */ + const char *ret_str; /* start of token to return */ local_str = pg_strtok_ptr; @@ -166,7 +210,7 @@ pg_strtok(int *length) * any protective backslashes in the token are removed. */ char * -debackslash(char *token, int length) +debackslash(const char *token, int length) { char *result = palloc(length + 1); char *ptr = result; @@ -198,10 +242,10 @@ debackslash(char *token, int length) * Assumption: the ascii representation is legal */ static NodeTag -nodeTokenType(char *token, int length) +nodeTokenType(const char *token, int length) { NodeTag retval; - char *numptr; + const char *numptr; int numlen; /* @@ -216,9 +260,9 @@ nodeTokenType(char *token, int length) { /* * Yes. Figure out whether it is integral or float; this requires - * both a syntax check and a range check. strtoint() can do both for us. - * We know the token will end at a character that strtoint will stop at, - * so we do not need to modify the string. + * both a syntax check and a range check. strtoint() can do both for + * us. We know the token will end at a character that strtoint will + * stop at, so we do not need to modify the string. */ char *endptr; @@ -269,7 +313,7 @@ nodeTokenType(char *token, int length) * this should only be invoked from within a stringToNode operation). */ void * -nodeRead(char *token, int tok_len) +nodeRead(const char *token, int tok_len) { Node *result; NodeTag type; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 93785e3bdfd..764e3bb90c9 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -3,7 +3,7 @@ * readfuncs.c * Reader functions for Postgres tree nodes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,10 +17,14 @@ * never read executor state trees, either. * * Parse location fields are written out by outfuncs.c, but only for - * possible debugging use. When reading a location field, we discard + * debugging use. When reading a location field, we normally discard * the stored value and set the location field to -1 (ie, "unknown"). * This is because nodes coming from a stored rule should not be thought * to have a known location in the current query's text. + * However, if restore_location_fields is true, we do restore location + * fields from the string. This is currently intended only for use by the + * WRITE_READ_PARSE_PLAN_TREES test code, which doesn't want to cause + * any change in the node contents. * *------------------------------------------------------------------------- */ @@ -29,6 +33,7 @@ #include #include "fmgr.h" +#include "miscadmin.h" #include "nodes/extensible.h" #include "nodes/parsenodes.h" #include "nodes/plannodes.h" @@ -51,7 +56,7 @@ /* And a few guys need only the pg_strtok support fields */ #define READ_TEMP_LOCALS() \ - char *token; \ + const char *token; \ int length /* ... but most need both */ @@ -120,12 +125,19 @@ token = pg_strtok(&length); /* get field value */ \ local_node->fldname = nullable_string(token, length) -/* Read a parse location field (and throw away the value, per notes above) */ +/* Read a parse location field (and possibly throw away the value) */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +#define READ_LOCATION_FIELD(fldname) \ + token = pg_strtok(&length); /* skip :fldname */ \ + token = pg_strtok(&length); /* get field value */ \ + local_node->fldname = restore_location_fields ? atoi(token) : -1 +#else #define READ_LOCATION_FIELD(fldname) \ token = pg_strtok(&length); /* skip :fldname */ \ token = pg_strtok(&length); /* get field value */ \ (void) token; /* in case not used elsewhere */ \ local_node->fldname = -1 /* set field to "unknown" */ +#endif /* Read a Node field */ #define READ_NODE_FIELD(fldname) \ @@ -269,10 +281,7 @@ _readQuery(void) READ_NODE_FIELD(rowMarks); READ_NODE_FIELD(setOperations); READ_NODE_FIELD(constraintDeps); - /* withCheckOptions intentionally omitted, see comment in parsenodes.h */ - READ_INT_FIELD(mergeTarget_relation); - READ_NODE_FIELD(mergeSourceTargetList); - READ_NODE_FIELD(mergeActionList); + READ_NODE_FIELD(withCheckOptions); READ_LOCATION_FIELD(stmt_location); READ_LOCATION_FIELD(stmt_len); @@ -409,6 +418,7 @@ _readCommonTableExpr(void) READ_STRING_FIELD(ctename); READ_NODE_FIELD(aliascolnames); + READ_ENUM_FIELD(ctematerialized, CTEMaterialize); READ_NODE_FIELD(ctequery); READ_LOCATION_FIELD(location); READ_BOOL_FIELD(cterecursive); @@ -506,6 +516,7 @@ _readIntoClause(void) READ_NODE_FIELD(rel); READ_NODE_FIELD(colNames); + READ_STRING_FIELD(accessMethod); READ_NODE_FIELD(options); READ_ENUM_FIELD(onCommit, OnCommitAction); READ_STRING_FIELD(tableSpaceName); @@ -648,14 +659,14 @@ _readWindowFunc(void) } /* - * _readArrayRef + * _readSubscriptingRef */ -static ArrayRef * -_readArrayRef(void) +static SubscriptingRef * +_readSubscriptingRef(void) { - READ_LOCALS(ArrayRef); + READ_LOCALS(SubscriptingRef); - READ_OID_FIELD(refarraytype); + READ_OID_FIELD(refcontainertype); READ_OID_FIELD(refelemtype); READ_INT_FIELD(reftypmod); READ_OID_FIELD(refcollid); @@ -1331,65 +1342,6 @@ _readOnConflictExpr(void) READ_DONE(); } -static PartitionPruneStepOp * -_readPartitionPruneStepOp(void) -{ - READ_LOCALS(PartitionPruneStepOp); - - READ_INT_FIELD(step.step_id); - READ_INT_FIELD(opstrategy); - READ_NODE_FIELD(exprs); - READ_NODE_FIELD(cmpfns); - READ_BITMAPSET_FIELD(nullkeys); - - READ_DONE(); -} - -static PartitionPruneStepCombine * -_readPartitionPruneStepCombine(void) -{ - READ_LOCALS(PartitionPruneStepCombine); - - READ_INT_FIELD(step.step_id); - READ_ENUM_FIELD(combineOp, PartitionPruneCombineOp); - READ_NODE_FIELD(source_stepids); - - READ_DONE(); -} - -/* - * _readMergeAction - */ -static MergeAction * -_readMergeAction(void) -{ - READ_LOCALS(MergeAction); - - READ_BOOL_FIELD(matched); - READ_ENUM_FIELD(commandType, CmdType); - READ_NODE_FIELD(qual); - READ_NODE_FIELD(targetList); - - READ_DONE(); -} - -static PartitionPruneInfo * -_readPartitionPruneInfo(void) -{ - READ_LOCALS(PartitionPruneInfo); - - READ_OID_FIELD(reloid); - READ_NODE_FIELD(pruning_steps); - READ_BITMAPSET_FIELD(present_parts); - READ_INT_FIELD(nparts); - READ_INT_ARRAY(subnode_map, local_node->nparts); - READ_INT_ARRAY(subpart_map, local_node->nparts); - READ_BITMAPSET_FIELD(extparams); - READ_BITMAPSET_FIELD(execparams); - - READ_DONE(); -} - /* * Stuff from parsenodes.h. */ @@ -1412,6 +1364,7 @@ _readRangeTblEntry(void) case RTE_RELATION: READ_OID_FIELD(relid); READ_CHAR_FIELD(relkind); + READ_INT_FIELD(rellockmode); READ_NODE_FIELD(tablesample); break; case RTE_SUBQUERY: @@ -1428,6 +1381,15 @@ _readRangeTblEntry(void) break; case RTE_TABLEFUNC: READ_NODE_FIELD(tablefunc); + /* The RTE must have a copy of the column type info, if any */ + if (local_node->tablefunc) + { + TableFunc *tf = local_node->tablefunc; + + local_node->coltypes = tf->coltypes; + local_node->coltypmods = tf->coltypmods; + local_node->colcollations = tf->colcollations; + } break; case RTE_VALUES: READ_NODE_FIELD(values_lists); @@ -1451,6 +1413,9 @@ _readRangeTblEntry(void) READ_NODE_FIELD(coltypmods); READ_NODE_FIELD(colcollations); break; + case RTE_RESULT: + /* no extra fields */ + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) local_node->rtekind); @@ -1465,6 +1430,7 @@ _readRangeTblEntry(void) READ_BITMAPSET_FIELD(selectedCols); READ_BITMAPSET_FIELD(insertedCols); READ_BITMAPSET_FIELD(updatedCols); + READ_BITMAPSET_FIELD(extraUpdatedCols); READ_NODE_FIELD(securityQuals); READ_DONE(); @@ -1521,6 +1487,10 @@ _readDefElem(void) READ_DONE(); } +/* + * Stuff from plannodes.h. + */ + /* * _readPlannedStmt */ @@ -1537,11 +1507,10 @@ _readPlannedStmt(void) READ_BOOL_FIELD(transientPlan); READ_BOOL_FIELD(dependsOnRole); READ_BOOL_FIELD(parallelModeNeeded); - READ_BOOL_FIELD(jitFlags); + READ_INT_FIELD(jitFlags); READ_NODE_FIELD(planTree); READ_NODE_FIELD(rtable); READ_NODE_FIELD(resultRelations); - READ_NODE_FIELD(nonleafResultRelations); READ_NODE_FIELD(rootResultRelations); READ_NODE_FIELD(subplans); READ_BITMAPSET_FIELD(rewindPlanIDs); @@ -1635,10 +1604,9 @@ _readModifyTable(void) READ_ENUM_FIELD(operation, CmdType); READ_BOOL_FIELD(canSetTag); READ_UINT_FIELD(nominalRelation); - READ_NODE_FIELD(partitioned_rels); + READ_UINT_FIELD(rootRelation); READ_BOOL_FIELD(partColsUpdated); READ_NODE_FIELD(resultRelations); - READ_INT_FIELD(mergeTargetRelation); READ_INT_FIELD(resultRelIndex); READ_INT_FIELD(rootResultRelIndex); READ_NODE_FIELD(plans); @@ -1654,27 +1622,6 @@ _readModifyTable(void) READ_NODE_FIELD(onConflictWhere); READ_UINT_FIELD(exclRelRTI); READ_NODE_FIELD(exclRelTlist); - READ_NODE_FIELD(mergeSourceTargetList); - READ_NODE_FIELD(mergeActionList); - - READ_DONE(); -} - -/* - * _readMergeWhenClause - */ -static MergeWhenClause * -_readMergeWhenClause(void) -{ - READ_LOCALS(MergeWhenClause); - - READ_BOOL_FIELD(matched); - READ_ENUM_FIELD(commandType, CmdType); - READ_NODE_FIELD(condition); - READ_NODE_FIELD(targetList); - READ_NODE_FIELD(cols); - READ_NODE_FIELD(values); - READ_ENUM_FIELD(override, OverridingKind); READ_DONE(); } @@ -1689,10 +1636,9 @@ _readAppend(void) ReadCommonPlan(&local_node->plan); - READ_NODE_FIELD(partitioned_rels); READ_NODE_FIELD(appendplans); READ_INT_FIELD(first_partial_plan); - READ_NODE_FIELD(part_prune_infos); + READ_NODE_FIELD(part_prune_info); READ_DONE(); } @@ -1707,13 +1653,13 @@ _readMergeAppend(void) ReadCommonPlan(&local_node->plan); - READ_NODE_FIELD(partitioned_rels); READ_NODE_FIELD(mergeplans); READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(sortColIdx, local_node->numCols); READ_OID_ARRAY(sortOperators, local_node->numCols); READ_OID_ARRAY(collations, local_node->numCols); READ_BOOL_ARRAY(nullsFirst, local_node->numCols); + READ_NODE_FIELD(part_prune_info); READ_DONE(); } @@ -1732,6 +1678,7 @@ _readRecursiveUnion(void) READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols); READ_OID_ARRAY(dupOperators, local_node->numCols); + READ_OID_ARRAY(dupCollations, local_node->numCols); READ_LONG_FIELD(numGroups); READ_DONE(); @@ -1988,6 +1935,21 @@ _readCteScan(void) READ_DONE(); } +/* + * _readNamedTuplestoreScan + */ +static NamedTuplestoreScan * +_readNamedTuplestoreScan(void) +{ + READ_LOCALS(NamedTuplestoreScan); + + ReadCommonScan(&local_node->scan); + + READ_STRING_FIELD(enrname); + + READ_DONE(); +} + /* * _readWorkTableScan */ @@ -2134,6 +2096,9 @@ _readHashJoin(void) ReadCommonJoin(&local_node->join); READ_NODE_FIELD(hashclauses); + READ_NODE_FIELD(hashoperators); + READ_NODE_FIELD(hashcollations); + READ_NODE_FIELD(hashkeys); READ_DONE(); } @@ -2183,6 +2148,7 @@ _readGroup(void) READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols); READ_OID_ARRAY(grpOperators, local_node->numCols); + READ_OID_ARRAY(grpCollations, local_node->numCols); READ_DONE(); } @@ -2202,6 +2168,7 @@ _readAgg(void) READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(grpColIdx, local_node->numCols); READ_OID_ARRAY(grpOperators, local_node->numCols); + READ_OID_ARRAY(grpCollations, local_node->numCols); READ_LONG_FIELD(numGroups); READ_BITMAPSET_FIELD(aggParams); READ_NODE_FIELD(groupingSets); @@ -2224,9 +2191,11 @@ _readWindowAgg(void) READ_INT_FIELD(partNumCols); READ_ATTRNUMBER_ARRAY(partColIdx, local_node->partNumCols); READ_OID_ARRAY(partOperators, local_node->partNumCols); + READ_OID_ARRAY(partCollations, local_node->partNumCols); READ_INT_FIELD(ordNumCols); READ_ATTRNUMBER_ARRAY(ordColIdx, local_node->ordNumCols); READ_OID_ARRAY(ordOperators, local_node->ordNumCols); + READ_OID_ARRAY(ordCollations, local_node->ordNumCols); READ_INT_FIELD(frameOptions); READ_NODE_FIELD(startOffset); READ_NODE_FIELD(endOffset); @@ -2252,6 +2221,7 @@ _readUnique(void) READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(uniqColIdx, local_node->numCols); READ_OID_ARRAY(uniqOperators, local_node->numCols); + READ_OID_ARRAY(uniqCollations, local_node->numCols); READ_DONE(); } @@ -2307,6 +2277,7 @@ _readHash(void) ReadCommonPlan(&local_node->plan); + READ_NODE_FIELD(hashkeys); READ_OID_FIELD(skewTable); READ_INT_FIELD(skewColumn); READ_BOOL_FIELD(skewInherit); @@ -2330,6 +2301,7 @@ _readSetOp(void) READ_INT_FIELD(numCols); READ_ATTRNUMBER_ARRAY(dupColIdx, local_node->numCols); READ_OID_ARRAY(dupOperators, local_node->numCols); + READ_OID_ARRAY(dupCollations, local_node->numCols); READ_INT_FIELD(flagColIdx); READ_INT_FIELD(firstFlag); READ_LONG_FIELD(numGroups); @@ -2403,6 +2375,61 @@ _readPlanRowMark(void) READ_DONE(); } +static PartitionPruneInfo * +_readPartitionPruneInfo(void) +{ + READ_LOCALS(PartitionPruneInfo); + + READ_NODE_FIELD(prune_infos); + READ_BITMAPSET_FIELD(other_subplans); + + READ_DONE(); +} + +static PartitionedRelPruneInfo * +_readPartitionedRelPruneInfo(void) +{ + READ_LOCALS(PartitionedRelPruneInfo); + + READ_UINT_FIELD(rtindex); + READ_BITMAPSET_FIELD(present_parts); + READ_INT_FIELD(nparts); + READ_INT_ARRAY(subplan_map, local_node->nparts); + READ_INT_ARRAY(subpart_map, local_node->nparts); + READ_OID_ARRAY(relid_map, local_node->nparts); + READ_NODE_FIELD(initial_pruning_steps); + READ_NODE_FIELD(exec_pruning_steps); + READ_BITMAPSET_FIELD(execparamids); + + READ_DONE(); +} + +static PartitionPruneStepOp * +_readPartitionPruneStepOp(void) +{ + READ_LOCALS(PartitionPruneStepOp); + + READ_INT_FIELD(step.step_id); + READ_INT_FIELD(opstrategy); + READ_NODE_FIELD(exprs); + READ_NODE_FIELD(cmpfns); + READ_BITMAPSET_FIELD(nullkeys); + + READ_DONE(); +} + +static PartitionPruneStepCombine * +_readPartitionPruneStepCombine(void) +{ + READ_LOCALS(PartitionPruneStepCombine); + + READ_INT_FIELD(step.step_id); + READ_ENUM_FIELD(combineOp, PartitionPruneCombineOp); + READ_NODE_FIELD(source_stepids); + + READ_DONE(); +} + /* * _readPlanInvalItem */ @@ -2538,6 +2565,9 @@ parseNodeString(void) READ_TEMP_LOCALS(); + /* Guard against stack overflow due to overly complex expressions */ + check_stack_depth(); + token = pg_strtok(&length); #define MATCH(tokname, namelen) \ @@ -2579,8 +2609,8 @@ parseNodeString(void) return_value = _readGroupingFunc(); else if (MATCH("WINDOWFUNC", 10)) return_value = _readWindowFunc(); - else if (MATCH("ARRAYREF", 8)) - return_value = _readArrayRef(); + else if (MATCH("SUBSCRIPTINGREF", 15)) + return_value = _readSubscriptingRef(); else if (MATCH("FUNCEXPR", 8)) return_value = _readFuncExpr(); else if (MATCH("NAMEDARGEXPR", 12)) @@ -2657,14 +2687,6 @@ parseNodeString(void) return_value = _readFromExpr(); else if (MATCH("ONCONFLICTEXPR", 14)) return_value = _readOnConflictExpr(); - else if (MATCH("MERGEACTION", 11)) - return_value = _readMergeAction(); - else if (MATCH("PARTITIONPRUNESTEPOP", 20)) - return_value = _readPartitionPruneStepOp(); - else if (MATCH("PARTITIONPRUNESTEPCOMBINE", 25)) - return_value = _readPartitionPruneStepCombine(); - else if (MATCH("PARTITIONPRUNEINFO", 18)) - return_value = _readPartitionPruneInfo(); else if (MATCH("RTE", 3)) return_value = _readRangeTblEntry(); else if (MATCH("RANGETBLFUNCTION", 16)) @@ -2687,8 +2709,6 @@ parseNodeString(void) return_value = _readProjectSet(); else if (MATCH("MODIFYTABLE", 11)) return_value = _readModifyTable(); - else if (MATCH("MERGEWHENCLAUSE", 15)) - return_value = _readMergeWhenClause(); else if (MATCH("APPEND", 6)) return_value = _readAppend(); else if (MATCH("MERGEAPPEND", 11)) @@ -2725,6 +2745,8 @@ parseNodeString(void) return_value = _readTableFuncScan(); else if (MATCH("CTESCAN", 7)) return_value = _readCteScan(); + else if (MATCH("NAMEDTUPLESTORESCAN", 19)) + return_value = _readNamedTuplestoreScan(); else if (MATCH("WORKTABLESCAN", 13)) return_value = _readWorkTableScan(); else if (MATCH("FOREIGNSCAN", 11)) @@ -2767,6 +2789,14 @@ parseNodeString(void) return_value = _readNestLoopParam(); else if (MATCH("PLANROWMARK", 11)) return_value = _readPlanRowMark(); + else if (MATCH("PARTITIONPRUNEINFO", 18)) + return_value = _readPartitionPruneInfo(); + else if (MATCH("PARTITIONEDRELPRUNEINFO", 23)) + return_value = _readPartitionedRelPruneInfo(); + else if (MATCH("PARTITIONPRUNESTEPOP", 20)) + return_value = _readPartitionPruneStepOp(); + else if (MATCH("PARTITIONPRUNESTEPCOMBINE", 25)) + return_value = _readPartitionPruneStepCombine(); else if (MATCH("PLANINVALITEM", 13)) return_value = _readPlanInvalItem(); else if (MATCH("SUBPLAN", 7)) @@ -2802,7 +2832,7 @@ readDatum(bool typbyval) Size length, i; int tokenLength; - char *token; + const char *token; Datum res; char *s; @@ -2815,7 +2845,7 @@ readDatum(bool typbyval) token = pg_strtok(&tokenLength); /* read the '[' */ if (token == NULL || token[0] != '[') elog(ERROR, "expected \"[\" to start datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); + token ? token : "[NULL]", length); if (typbyval) { @@ -2845,7 +2875,7 @@ readDatum(bool typbyval) token = pg_strtok(&tokenLength); /* read the ']' */ if (token == NULL || token[0] != ']') elog(ERROR, "expected \"]\" to end datum, but got \"%s\"; length = %zu", - token ? (const char *) token : "[NULL]", length); + token ? token : "[NULL]", length); return res; } @@ -2858,7 +2888,7 @@ readAttrNumberCols(int numCols) { int tokenLength, i; - char *token; + const char *token; AttrNumber *attr_vals; if (numCols <= 0) @@ -2882,7 +2912,7 @@ readOidCols(int numCols) { int tokenLength, i; - char *token; + const char *token; Oid *oid_vals; if (numCols <= 0) @@ -2906,7 +2936,7 @@ readIntCols(int numCols) { int tokenLength, i; - char *token; + const char *token; int *int_vals; if (numCols <= 0) @@ -2930,7 +2960,7 @@ readBoolCols(int numCols) { int tokenLength, i; - char *token; + const char *token; bool *bool_vals; if (numCols <= 0) diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index 17dc53898f0..23905a9c352 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -29,7 +29,7 @@ * and a non-lossy page. * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/nodes/tidbitmap.c @@ -227,16 +227,16 @@ struct TBMSharedIterator /* Local function prototypes */ static void tbm_union_page(TIDBitmap *a, const PagetableEntry *bpage); static bool tbm_intersect_page(TIDBitmap *a, PagetableEntry *apage, - const TIDBitmap *b); + const TIDBitmap *b); static const PagetableEntry *tbm_find_pageentry(const TIDBitmap *tbm, - BlockNumber pageno); + BlockNumber pageno); static PagetableEntry *tbm_get_pageentry(TIDBitmap *tbm, BlockNumber pageno); static bool tbm_page_is_lossy(const TIDBitmap *tbm, BlockNumber pageno); static void tbm_mark_page_lossy(TIDBitmap *tbm, BlockNumber pageno); static void tbm_lossify(TIDBitmap *tbm); static int tbm_comparator(const void *left, const void *right); -static int tbm_shared_comparator(const void *left, const void *right, - void *arg); +static int tbm_shared_comparator(const void *left, const void *right, + void *arg); /* define hashtable mapping block numbers to PagetableEntry's */ #define SH_USE_NONDEFAULT_ALLOCATOR @@ -934,7 +934,7 @@ tbm_extract_page_tuple(PagetableEntry *page, TBMIterateResult *output) } /* - * tbm_advance_schunkbit - Advance the chunkbit + * tbm_advance_schunkbit - Advance the schunkbit */ static inline void tbm_advance_schunkbit(PagetableEntry *chunk, int *schunkbitp) @@ -1021,7 +1021,7 @@ tbm_iterate(TBMIterator *iterator) PagetableEntry *page; int ntuples; - /* In ONE_PAGE state, we don't allocate an spages[] array */ + /* In TBM_ONE_PAGE state, we don't allocate an spages[] array */ if (tbm->status == TBM_ONE_PAGE) page = &tbm->entry1; else diff --git a/src/backend/nodes/value.c b/src/backend/nodes/value.c index 2a30307baf4..159c11ab4a4 100644 --- a/src/backend/nodes/value.c +++ b/src/backend/nodes/value.c @@ -4,7 +4,7 @@ * implementation of Value nodes * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/optimizer/README b/src/backend/optimizer/README index 87a38f9aaa0..89ce373d5e6 100644 --- a/src/backend/optimizer/README +++ b/src/backend/optimizer/README @@ -320,7 +320,7 @@ set up for recursive handling of subqueries split up the qual into restrictions (a=1) and joins (b=c) find qual clauses that enable merge and hash joins ----make_one_rel() - set_base_rel_pathlist() + set_base_rel_pathlists() find seqscan and all index paths for each base relation find selectivity of columns used in joins make_rel_from_joinlist() @@ -361,7 +361,16 @@ RelOptInfo - a relation or joined relations join clauses) Path - every way to generate a RelOptInfo(sequential,index,joins) - SeqScan - represents a sequential scan plan + A plain Path node can represent several simple plans, per its pathtype: + T_SeqScan - sequential scan + T_SampleScan - tablesample scan + T_FunctionScan - function-in-FROM scan + T_TableFuncScan - table function scan + T_ValuesScan - VALUES scan + T_CteScan - CTE (WITH) scan + T_NamedTuplestoreScan - ENR scan + T_WorkTableScan - scan worktable of a recursive CTE + T_Result - childless Result plan node (used for FROM-less SELECT) IndexPath - index scan BitmapHeapPath - top of a bitmapped index scan TidPath - scan by CTID @@ -370,7 +379,7 @@ RelOptInfo - a relation or joined relations CustomPath - for custom scan providers AppendPath - append multiple subpaths together MergeAppendPath - merge multiple subpaths, preserving their common sort order - ResultPath - a childless Result plan node (used for FROM-less SELECT) + GroupResultPath - childless Result plan node (used for degenerate grouping) MaterialPath - a Material plan node UniquePath - remove duplicate rows (either by hashing or sorting) GatherPath - collect the results of parallel workers @@ -1106,10 +1115,10 @@ PartitionSchemeData object. This reduces memory consumed by PartitionSchemeData objects and makes it easy to compare the partition schemes of joining relations. -Partition-wise aggregates/grouping ----------------------------------- +Partitionwise aggregates/grouping +--------------------------------- -If the GROUP BY clause has contains all of the partition keys, all the rows +If the GROUP BY clause contains all of the partition keys, all the rows that belong to a given group must come from a single partition; therefore, aggregation can be done completely separately for each partition. Otherwise, partial aggregates can be computed for each partition, and then finalized diff --git a/src/backend/optimizer/geqo/geqo_copy.c b/src/backend/optimizer/geqo/geqo_copy.c index 111caa2a2ab..5087cb2228f 100644 --- a/src/backend/optimizer/geqo/geqo_copy.c +++ b/src/backend/optimizer/geqo/geqo_copy.c @@ -2,7 +2,7 @@ * * geqo_copy.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_copy.c diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c index 3ef7d7d8aa2..7b67a29c88a 100644 --- a/src/backend/optimizer/geqo/geqo_eval.c +++ b/src/backend/optimizer/geqo/geqo_eval.c @@ -3,7 +3,7 @@ * geqo_eval.c * Routines to evaluate query trees * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_eval.c @@ -40,9 +40,9 @@ typedef struct } Clump; static List *merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, - int num_gene, bool force); + int num_gene, bool force); static bool desirable_join(PlannerInfo *root, - RelOptInfo *outer_rel, RelOptInfo *inner_rel); + RelOptInfo *outer_rel, RelOptInfo *inner_rel); /* @@ -238,11 +238,10 @@ static List * merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, bool force) { - ListCell *prev; ListCell *lc; + int pos; /* Look for a clump that new_clump can join to */ - prev = NULL; foreach(lc, clumps) { Clump *old_clump = (Clump *) lfirst(lc); @@ -286,7 +285,7 @@ merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, pfree(new_clump); /* Remove old_clump from list */ - clumps = list_delete_cell(clumps, lc, prev); + clumps = foreach_delete_current(clumps, lc); /* * Recursively try to merge the enlarged old_clump with @@ -296,7 +295,6 @@ merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, return merge_clump(root, clumps, old_clump, num_gene, force); } } - prev = lc; } /* @@ -307,21 +305,15 @@ merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, if (clumps == NIL || new_clump->size == 1) return lappend(clumps, new_clump); - /* Check if it belongs at the front */ - lc = list_head(clumps); - if (new_clump->size > ((Clump *) lfirst(lc))->size) - return lcons(new_clump, clumps); - /* Else search for the place to insert it */ - for (;;) + for (pos = 0; pos < list_length(clumps); pos++) { - ListCell *nxt = lnext(lc); + Clump *old_clump = (Clump *) list_nth(clumps, pos); - if (nxt == NULL || new_clump->size > ((Clump *) lfirst(nxt))->size) - break; /* it belongs after 'lc', before 'nxt' */ - lc = nxt; + if (new_clump->size > old_clump->size) + break; /* new_clump belongs before old_clump */ } - lappend_cell(clumps, lc, new_clump); + clumps = list_insert_nth(clumps, pos, new_clump); return clumps; } diff --git a/src/backend/optimizer/geqo/geqo_main.c b/src/backend/optimizer/geqo/geqo_main.c index 3eb8bcb76f6..dc51829dec0 100644 --- a/src/backend/optimizer/geqo/geqo_main.c +++ b/src/backend/optimizer/geqo/geqo_main.c @@ -4,7 +4,7 @@ * solution to the query optimization problem * by means of a Genetic Algorithm (GA) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_main.c diff --git a/src/backend/optimizer/geqo/geqo_misc.c b/src/backend/optimizer/geqo/geqo_misc.c index 0f96912e49d..554c3df24e5 100644 --- a/src/backend/optimizer/geqo/geqo_misc.c +++ b/src/backend/optimizer/geqo/geqo_misc.c @@ -3,7 +3,7 @@ * geqo_misc.c * misc. printout and debug stuff * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_misc.c diff --git a/src/backend/optimizer/geqo/geqo_pool.c b/src/backend/optimizer/geqo/geqo_pool.c index b2c9f31c8b5..f29fcc2cebf 100644 --- a/src/backend/optimizer/geqo/geqo_pool.c +++ b/src/backend/optimizer/geqo/geqo_pool.c @@ -3,7 +3,7 @@ * geqo_pool.c * Genetic Algorithm (GA) pool stuff * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_pool.c diff --git a/src/backend/optimizer/geqo/geqo_random.c b/src/backend/optimizer/geqo/geqo_random.c index 850bfe5ebe3..c482cdead13 100644 --- a/src/backend/optimizer/geqo/geqo_random.c +++ b/src/backend/optimizer/geqo/geqo_random.c @@ -3,7 +3,7 @@ * geqo_random.c * random number generator * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_random.c diff --git a/src/backend/optimizer/geqo/geqo_selection.c b/src/backend/optimizer/geqo/geqo_selection.c index ebd34b6db23..0a6bacc2f2a 100644 --- a/src/backend/optimizer/geqo/geqo_selection.c +++ b/src/backend/optimizer/geqo/geqo_selection.c @@ -3,7 +3,7 @@ * geqo_selection.c * linear selection scheme for the genetic query optimizer * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/optimizer/geqo/geqo_selection.c @@ -91,7 +91,7 @@ geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy, static int linear_rand(PlannerInfo *root, int pool_size, double bias) { - double index; /* index between 0 and pop_size */ + double index; /* index between 0 and pool_size */ double max = (double) pool_size; /* diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index 3ba3f87eb7c..db3a68a51dd 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -3,7 +3,7 @@ * allpaths.c * Routines to find possible search paths for processing a query * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,19 +30,21 @@ #ifdef OPTIMIZER_DEBUG #include "nodes/print.h" #endif +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/geqo.h" +#include "optimizer/inherit.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/plancat.h" #include "optimizer/planner.h" -#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parse_clause.h" #include "parser/parsetree.h" +#include "partitioning/partbounds.h" #include "partitioning/partprune.h" #include "rewrite/rewriteManip.h" #include "utils/lsyscache.h" @@ -73,67 +75,71 @@ static void set_base_rel_consider_startup(PlannerInfo *root); static void set_base_rel_sizes(PlannerInfo *root); static void set_base_rel_pathlists(PlannerInfo *root); static void set_rel_size(PlannerInfo *root, RelOptInfo *rel, - Index rti, RangeTblEntry *rte); + Index rti, RangeTblEntry *rte); static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, - Index rti, RangeTblEntry *rte); + Index rti, RangeTblEntry *rte); static void set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel); static void set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_tablesample_rel_size(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_tablesample_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_foreign_size(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, - Index rti, RangeTblEntry *rte); + Index rti, RangeTblEntry *rte); static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, - Index rti, RangeTblEntry *rte); -static void generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel, - List *live_childrels, - List *all_child_pathkeys, - List *partitioned_rels); + Index rti, RangeTblEntry *rte); +static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, + List *live_childrels, + List *all_child_pathkeys, + List *partitioned_rels); static Path *get_cheapest_parameterized_child_path(PlannerInfo *root, - RelOptInfo *rel, - Relids required_outer); + RelOptInfo *rel, + Relids required_outer); static void accumulate_append_subpath(Path *path, - List **subpaths, List **special_subpaths); + List **subpaths, List **special_subpaths); +static Path *get_singleton_append_subpath(Path *path); +static void set_dummy_rel_pathlist(RelOptInfo *rel); static void set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, - Index rti, RangeTblEntry *rte); + Index rti, RangeTblEntry *rte); static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_values_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_tablefunc_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static void set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); -static void set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte); +static void set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte); +static void set_result_pathlist(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte); static void set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, - RangeTblEntry *rte); + RangeTblEntry *rte); static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist); static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery, - pushdown_safety_info *safetyInfo); + pushdown_safety_info *safetyInfo); static bool recurse_pushdown_safe(Node *setOp, Query *topquery, - pushdown_safety_info *safetyInfo); + pushdown_safety_info *safetyInfo); static void check_output_expressions(Query *subquery, - pushdown_safety_info *safetyInfo); + pushdown_safety_info *safetyInfo); static void compare_tlist_datatypes(List *tlist, List *colTypes, - pushdown_safety_info *safetyInfo); + pushdown_safety_info *safetyInfo); static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query); static bool qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual, - pushdown_safety_info *safetyInfo); + pushdown_safety_info *safetyInfo); static void subquery_push_qual(Query *subquery, - RangeTblEntry *rte, Index rti, Node *qual); + RangeTblEntry *rte, Index rti, Node *qual); static void recurse_push_qual(Node *setOp, Query *topquery, - RangeTblEntry *rte, Index rti, Node *qual); + RangeTblEntry *rte, Index rti, Node *qual); static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel); @@ -147,6 +153,7 @@ make_one_rel(PlannerInfo *root, List *joinlist) { RelOptInfo *rel; Index rti; + double total_pages; /* * Construct the all_baserels Relids set. @@ -173,10 +180,45 @@ make_one_rel(PlannerInfo *root, List *joinlist) set_base_rel_consider_startup(root); /* - * Compute size estimates and consider_parallel flags for each base rel, - * then generate access paths. + * Compute size estimates and consider_parallel flags for each base rel. */ set_base_rel_sizes(root); + + /* + * We should now have size estimates for every actual table involved in + * the query, and we also know which if any have been deleted from the + * query by join removal, pruned by partition pruning, or eliminated by + * constraint exclusion. So we can now compute total_table_pages. + * + * Note that appendrels are not double-counted here, even though we don't + * bother to distinguish RelOptInfos for appendrel parents, because the + * parents will have pages = 0. + * + * XXX if a table is self-joined, we will count it once per appearance, + * which perhaps is the wrong thing ... but that's not completely clear, + * and detecting self-joins here is difficult, so ignore it for now. + */ + total_pages = 0; + for (rti = 1; rti < root->simple_rel_array_size; rti++) + { + RelOptInfo *brel = root->simple_rel_array[rti]; + + if (brel == NULL) + continue; + + Assert(brel->relid == rti); /* sanity check on array */ + + if (IS_DUMMY_REL(brel)) + continue; + + if (IS_SIMPLE_REL(brel)) + total_pages += (double) brel->pages; + } + root->total_table_pages = total_pages; + + /* + * Generate access paths for each base rel. + */ set_base_rel_pathlists(root); /* @@ -353,8 +395,9 @@ set_rel_size(PlannerInfo *root, RelOptInfo *rel, else if (rte->relkind == RELKIND_PARTITIONED_TABLE) { /* - * A partitioned table without any partitions is marked as - * a dummy rel. + * We could get here if asked to scan a partitioned table + * with ONLY. In that case we shouldn't scan any of the + * partitions, so mark it as a dummy rel. */ set_dummy_rel_pathlist(rel); } @@ -400,8 +443,13 @@ set_rel_size(PlannerInfo *root, RelOptInfo *rel, set_cte_pathlist(root, rel, rte); break; case RTE_NAMEDTUPLESTORE: + /* Might as well just build the path immediately */ set_namedtuplestore_pathlist(root, rel, rte); break; + case RTE_RESULT: + /* Might as well just build the path immediately */ + set_result_pathlist(root, rel, rte); + break; default: elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind); break; @@ -473,15 +521,29 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, case RTE_NAMEDTUPLESTORE: /* tuplestore reference --- fully handled during set_rel_size */ break; + case RTE_RESULT: + /* simple Result --- fully handled during set_rel_size */ + break; default: elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind); break; } } + /* + * Allow a plugin to editorialize on the set of Paths for this base + * relation. It could add new paths (such as CustomPaths) by calling + * add_path(), or add_partial_path() if parallel aware. It could also + * delete or modify paths added by the core code. + */ + if (set_rel_pathlist_hook) + (*set_rel_pathlist_hook) (root, rel, rti, rte); + /* * If this is a baserel, we should normally consider gathering any partial - * paths we may have created for it. + * paths we may have created for it. We have to do this after calling the + * set_rel_pathlist_hook, else it cannot add partial paths to be included + * here. * * However, if this is an inheritance child, skip it. Otherwise, we could * end up with a very large number of gather nodes, each trying to grab @@ -489,21 +551,13 @@ set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, * paths for the parent appendrel. * * Also, if this is the topmost scan/join rel (that is, the only baserel), - * we postpone this until the final scan/join targelist is available (see - * grouping_planner). + * we postpone gathering until the final scan/join targetlist is available + * (see grouping_planner). */ if (rel->reloptkind == RELOPT_BASEREL && bms_membership(root->all_baserels) != BMS_SINGLETON) generate_gather_paths(root, rel, false); - /* - * Allow a plugin to editorialize on the set of Paths for this base - * relation. It could add new paths (such as CustomPaths) by calling - * add_path(), or delete or modify paths added by the core code. - */ - if (set_rel_pathlist_hook) - (*set_rel_pathlist_hook) (root, rel, rti, rte); - /* Now find the cheapest of the paths for this rel */ set_cheapest(rel); @@ -620,7 +674,20 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel, * the SubqueryScanPath as not parallel-safe. (Note that * set_subquery_pathlist() might push some of these quals down * into the subquery itself, but that doesn't change anything.) + * + * We can't push sub-select containing LIMIT/OFFSET to workers as + * there is no guarantee that the row order will be fully + * deterministic, and applying LIMIT/OFFSET will lead to + * inconsistent results at the top-level. (In some cases, where + * the result is ordered, we could relax this restriction. But it + * doesn't currently seem worth expending extra effort to do so.) */ + { + Query *subquery = castNode(Query, rte->subquery); + + if (limit_needed(subquery)) + return; + } break; case RTE_JOIN: @@ -662,6 +729,10 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel, * infrastructure to support that. */ return; + + case RTE_RESULT: + /* RESULT RTEs, in themselves, are no problem. */ + break; } /* @@ -875,8 +946,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, double *parent_attrsizes; int nattrs; ListCell *l; - Relids live_children = NULL; - bool did_pruning = false; /* Guard against stack overflow due to overly deep inheritance tree. */ check_stack_depth(); @@ -895,18 +964,15 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, rel->partitioned_child_rels = list_make1_int(rti); /* - * If the partitioned relation has any baserestrictinfo quals then we - * attempt to use these quals to prune away partitions that cannot - * possibly contain any tuples matching these quals. In this case we'll - * store the relids of all partitions which could possibly contain a - * matching tuple, and skip anything else in the loop below. + * If this is a partitioned baserel, set the consider_partitionwise_join + * flag; currently, we only consider partitionwise joins with the baserel + * if its targetlist doesn't contain a whole-row Var. */ - if (rte->relkind == RELKIND_PARTITIONED_TABLE && - rel->baserestrictinfo != NIL) - { - live_children = prune_append_rel_partitions(rel); - did_pruning = true; - } + if (enable_partitionwise_join && + rel->reloptkind == RELOPT_BASEREL && + rte->relkind == RELKIND_PARTITIONED_TABLE && + rel->attr_needed[InvalidAttrNumber - rel->min_attr] == NULL) + rel->consider_partitionwise_join = true; /* * Initialize to compute size estimates for whole append relation. @@ -934,12 +1000,8 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, int childRTindex; RangeTblEntry *childRTE; RelOptInfo *childrel; - List *childquals; - Index cq_min_security; - bool have_const_false_cq; ListCell *parentvars; ListCell *childvars; - ListCell *lc; /* append_rel_list contains all append rels; ignore others */ if (appinfo->parent_relid != parentRTindex) @@ -950,63 +1012,35 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, /* * The child rel's RelOptInfo was already created during - * add_base_rels_to_query. + * add_other_rels_to_query. */ childrel = find_base_rel(root, childRTindex); Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL); - if (rel->part_scheme) - { - AttrNumber attno; + /* We may have already proven the child to be dummy. */ + if (IS_DUMMY_REL(childrel)) + continue; + /* + * We have to copy the parent's targetlist and quals to the child, + * with appropriate substitution of variables. However, the + * baserestrictinfo quals were already copied/substituted when the + * child RelOptInfo was built. So we don't need any additional setup + * before applying constraint exclusion. + */ + if (relation_excluded_by_constraints(root, childrel, childRTE)) + { /* - * We need attr_needed data for building targetlist of a join - * relation representing join between matching partitions for - * partitionwise join. A given attribute of a child will be - * needed in the same highest joinrel where the corresponding - * attribute of parent is needed. Hence it suffices to use the - * same Relids set for parent and child. + * This child need not be scanned, so we can omit it from the + * appendrel. */ - for (attno = rel->min_attr; attno <= rel->max_attr; attno++) - { - int index = attno - rel->min_attr; - Relids attr_needed = rel->attr_needed[index]; - - /* System attributes do not need translation. */ - if (attno <= 0) - { - Assert(rel->min_attr == childrel->min_attr); - childrel->attr_needed[index] = attr_needed; - } - else - { - Var *var = list_nth_node(Var, - appinfo->translated_vars, - attno - 1); - int child_index; - - /* - * Ignore any column dropped from the parent. - * Corresponding Var won't have any translation. It won't - * have attr_needed information, since it can not be - * referenced in the query. - */ - if (var == NULL) - { - Assert(attr_needed == NULL); - continue; - } - - child_index = var->varattno - childrel->min_attr; - childrel->attr_needed[child_index] = attr_needed; - } - } + set_dummy_rel_pathlist(childrel); + continue; } /* - * Copy/Modify targetlist. Even if this child is deemed empty, we need - * its targetlist in case it falls on nullable side in a child-join - * because of partitionwise join. + * Constraint exclusion failed, so copy the parent's join quals and + * targetlist to the child, with appropriate variable substitutions. * * NB: the resulting childrel->reltarget->exprs may contain arbitrary * expressions, which otherwise would not occur in a rel's targetlist. @@ -1015,6 +1049,10 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, * PlaceHolderVars.) XXX we do not bother to update the cost or width * fields of childrel->reltarget; not clear if that would be useful. */ + childrel->joininfo = (List *) + adjust_appendrel_attrs(root, + (Node *) rel->joininfo, + 1, &appinfo); childrel->reltarget->exprs = (List *) adjust_appendrel_attrs(root, (Node *) rel->reltarget->exprs, @@ -1026,158 +1064,33 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, * participates in some eclass joins (because we will want to consider * inner-indexscan joins on the individual children) or if the parent * has useful pathkeys (because we should try to build MergeAppend - * paths that produce those sort orderings). Even if this child is - * deemed dummy, it may fall on nullable side in a child-join, which - * in turn may participate in a MergeAppend, where we will need the - * EquivalenceClass data structures. + * paths that produce those sort orderings). */ if (rel->has_eclass_joins || has_useful_pathkeys(root, rel)) add_child_rel_equivalences(root, appinfo, rel, childrel); childrel->has_eclass_joins = rel->has_eclass_joins; /* - * We have to copy the parent's quals to the child, with appropriate - * substitution of variables. However, only the baserestrictinfo - * quals are needed before we can check for constraint exclusion; so - * do that first and then check to see if we can disregard this child. - * - * The child rel's targetlist might contain non-Var expressions, which - * means that substitution into the quals could produce opportunities - * for const-simplification, and perhaps even pseudoconstant quals. - * Therefore, transform each RestrictInfo separately to see if it - * reduces to a constant or pseudoconstant. (We must process them - * separately to keep track of the security level of each qual.) + * Note: we could compute appropriate attr_needed data for the child's + * variables, by transforming the parent's attr_needed through the + * translated_vars mapping. However, currently there's no need + * because attr_needed is only examined for base relations not + * otherrels. So we just leave the child's attr_needed empty. */ - childquals = NIL; - cq_min_security = UINT_MAX; - have_const_false_cq = false; - foreach(lc, rel->baserestrictinfo) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); - Node *childqual; - ListCell *lc2; - - Assert(IsA(rinfo, RestrictInfo)); - childqual = adjust_appendrel_attrs(root, - (Node *) rinfo->clause, - 1, &appinfo); - childqual = eval_const_expressions(root, childqual); - /* check for flat-out constant */ - if (childqual && IsA(childqual, Const)) - { - if (((Const *) childqual)->constisnull || - !DatumGetBool(((Const *) childqual)->constvalue)) - { - /* Restriction reduces to constant FALSE or NULL */ - have_const_false_cq = true; - break; - } - /* Restriction reduces to constant TRUE, so drop it */ - continue; - } - /* might have gotten an AND clause, if so flatten it */ - foreach(lc2, make_ands_implicit((Expr *) childqual)) - { - Node *onecq = (Node *) lfirst(lc2); - bool pseudoconstant; - - /* check for pseudoconstant (no Vars or volatile functions) */ - pseudoconstant = - !contain_vars_of_level(onecq, 0) && - !contain_volatile_functions(onecq); - if (pseudoconstant) - { - /* tell createplan.c to check for gating quals */ - root->hasPseudoConstantQuals = true; - } - /* reconstitute RestrictInfo with appropriate properties */ - childquals = lappend(childquals, - make_restrictinfo((Expr *) onecq, - rinfo->is_pushed_down, - rinfo->outerjoin_delayed, - pseudoconstant, - rinfo->security_level, - NULL, NULL, NULL)); - /* track minimum security level among child quals */ - cq_min_security = Min(cq_min_security, rinfo->security_level); - } - } /* - * In addition to the quals inherited from the parent, we might have - * securityQuals associated with this particular child node. - * (Currently this can only happen in appendrels originating from - * UNION ALL; inheritance child tables don't have their own - * securityQuals, see expand_inherited_rtentry().) Pull any such - * securityQuals up into the baserestrictinfo for the child. This is - * similar to process_security_barrier_quals() for the parent rel, - * except that we can't make any general deductions from such quals, - * since they don't hold for the whole appendrel. + * If we consider partitionwise joins with the parent rel, do the same + * for partitioned child rels. + * + * Note: here we abuse the consider_partitionwise_join flag by setting + * it for child rels that are not themselves partitioned. We do so to + * tell try_partitionwise_join() that the child rel is sufficiently + * valid to be used as a per-partition input, even if it later gets + * proven to be dummy. (It's not usable until we've set up the + * reltarget and EC entries, which we just did.) */ - if (childRTE->securityQuals) - { - Index security_level = 0; - - foreach(lc, childRTE->securityQuals) - { - List *qualset = (List *) lfirst(lc); - ListCell *lc2; - - foreach(lc2, qualset) - { - Expr *qual = (Expr *) lfirst(lc2); - - /* not likely that we'd see constants here, so no check */ - childquals = lappend(childquals, - make_restrictinfo(qual, - true, false, false, - security_level, - NULL, NULL, NULL)); - cq_min_security = Min(cq_min_security, security_level); - } - security_level++; - } - Assert(security_level <= root->qual_security_level); - } - - /* - * OK, we've got all the baserestrictinfo quals for this child. - */ - childrel->baserestrictinfo = childquals; - childrel->baserestrict_min_security = cq_min_security; - - if (have_const_false_cq) - { - /* - * Some restriction clause reduced to constant FALSE or NULL after - * substitution, so this child need not be scanned. - */ - set_dummy_rel_pathlist(childrel); - continue; - } - - if (did_pruning && !bms_is_member(appinfo->child_relid, live_children)) - { - /* This partition was pruned; skip it. */ - set_dummy_rel_pathlist(childrel); - continue; - } - - if (relation_excluded_by_constraints(root, childrel, childRTE)) - { - /* - * This child need not be scanned, so we can omit it from the - * appendrel. - */ - set_dummy_rel_pathlist(childrel); - continue; - } - - /* CE failed, so finish copying/modifying join quals. */ - childrel->joininfo = (List *) - adjust_appendrel_attrs(root, - (Node *) rel->joininfo, - 1, &appinfo); + if (rel->consider_partitionwise_join) + childrel->consider_partitionwise_join = true; /* * If parallelism is allowable for this query in general, see whether @@ -1278,6 +1191,11 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel, * because some places assume rel->tuples is valid for any baserel. */ rel->tuples = parent_rows; + + /* + * Note that we leave rel->pages as zero; this is important to avoid + * double-counting the appendrel tree in total_table_pages. + */ } else { @@ -1348,7 +1266,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, if (rel->part_scheme) rel->partitioned_child_rels = list_concat(rel->partitioned_child_rels, - list_copy(childrel->partitioned_child_rels)); + childrel->partitioned_child_rels); /* * Child is live, so add it to the live_childrels list for use below. @@ -1382,14 +1300,16 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *pa_partial_subpaths = NIL; List *pa_nonpartial_subpaths = NIL; bool partial_subpaths_valid = true; - bool pa_subpaths_valid = enable_parallel_append; + bool pa_subpaths_valid; List *all_child_pathkeys = NIL; List *all_child_outers = NIL; ListCell *l; List *partitioned_rels = NIL; - bool build_partitioned_rels = false; double partial_rows = -1; + /* If appropriate, consider parallel append */ + pa_subpaths_valid = enable_parallel_append && rel->consider_parallel; + /* * AppendPath generated for partitioned tables must record the RT indexes * of partitioned tables that are direct or indirect children of this @@ -1409,10 +1329,11 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (rel->part_scheme != NULL) { if (IS_SIMPLE_REL(rel)) - partitioned_rels = rel->partitioned_child_rels; + partitioned_rels = list_make1(rel->partitioned_child_rels); else if (IS_JOIN_REL(rel)) { int relid = -1; + List *partrels = NIL; /* * For a partitioned joinrel, concatenate the component rels' @@ -1426,16 +1347,15 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, component = root->simple_rel_array[relid]; Assert(component->part_scheme != NULL); Assert(list_length(component->partitioned_child_rels) >= 1); - partitioned_rels = - list_concat(partitioned_rels, - list_copy(component->partitioned_child_rels)); + partrels = list_concat(partrels, + component->partitioned_child_rels); } + + partitioned_rels = list_make1(partrels); } Assert(list_length(partitioned_rels) >= 1); } - else if (rel->rtekind == RTE_SUBQUERY) - build_partitioned_rels = true; /* * For every non-dummy child, remember the cheapest path. Also, identify @@ -1449,16 +1369,12 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, Path *cheapest_partial_path = NULL; /* - * If we need to build partitioned_rels, accumulate the partitioned - * rels for this child. + * For UNION ALLs with non-empty partitioned_child_rels, accumulate + * the Lists of child relations. */ - if (build_partitioned_rels) - { - List *cprels = childrel->partitioned_child_rels; - - partitioned_rels = list_concat(partitioned_rels, - list_copy(cprels)); - } + if (rel->rtekind == RTE_SUBQUERY && childrel->partitioned_child_rels != NIL) + partitioned_rels = lappend(partitioned_rels, + childrel->partitioned_child_rels); /* * If child has an unparameterized cheapest-total path, add that to @@ -1605,14 +1521,14 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, */ if (subpaths_valid) add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, - NULL, 0, false, + NIL, NULL, 0, false, partitioned_rels, -1)); /* * Consider an append of unordered, unparameterized partial paths. Make * it parallel-aware if possible. */ - if (partial_subpaths_valid) + if (partial_subpaths_valid && partial_subpaths != NIL) { AppendPath *appendpath; ListCell *lc; @@ -1647,7 +1563,7 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, /* Generate a partial append path. */ appendpath = create_append_path(root, rel, NIL, partial_subpaths, - NULL, parallel_workers, + NIL, NULL, parallel_workers, enable_parallel_append, partitioned_rels, -1); @@ -1697,19 +1613,19 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, appendpath = create_append_path(root, rel, pa_nonpartial_subpaths, pa_partial_subpaths, - NULL, parallel_workers, true, + NIL, NULL, parallel_workers, true, partitioned_rels, partial_rows); add_partial_path(rel, (Path *) appendpath); } /* - * Also build unparameterized MergeAppend paths based on the collected + * Also build unparameterized ordered append paths based on the collected * list of child pathkeys. */ if (subpaths_valid) - generate_mergeappend_paths(root, rel, live_childrels, - all_child_pathkeys, - partitioned_rels); + generate_orderedappend_paths(root, rel, live_childrels, + all_child_pathkeys, + partitioned_rels); /* * Build Append paths for each parameterization seen among the child rels. @@ -1759,23 +1675,59 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, if (subpaths_valid) add_path(rel, (Path *) create_append_path(root, rel, subpaths, NIL, - required_outer, 0, false, + NIL, required_outer, 0, false, partitioned_rels, -1)); } + + /* + * When there is only a single child relation, the Append path can inherit + * any ordering available for the child rel's path, so that it's useful to + * consider ordered partial paths. Above we only considered the cheapest + * partial path for each child, but let's also make paths using any + * partial paths that have pathkeys. + */ + if (list_length(live_childrels) == 1) + { + RelOptInfo *childrel = (RelOptInfo *) linitial(live_childrels); + + foreach(l, childrel->partial_pathlist) + { + Path *path = (Path *) lfirst(l); + AppendPath *appendpath; + + /* + * Skip paths with no pathkeys. Also skip the cheapest partial + * path, since we already used that above. + */ + if (path->pathkeys == NIL || + path == linitial(childrel->partial_pathlist)) + continue; + + appendpath = create_append_path(root, rel, NIL, list_make1(path), + NIL, NULL, + path->parallel_workers, true, + partitioned_rels, partial_rows); + add_partial_path(rel, (Path *) appendpath); + } + } } /* - * generate_mergeappend_paths - * Generate MergeAppend paths for an append relation + * generate_orderedappend_paths + * Generate ordered append paths for an append relation * - * Generate a path for each ordering (pathkey list) appearing in + * Usually we generate MergeAppend paths here, but there are some special + * cases where we can generate simple Append paths, because the subpaths + * can provide tuples in the required order already. + * + * We generate a path for each ordering (pathkey list) appearing in * all_child_pathkeys. * * We consider both cheapest-startup and cheapest-total cases, ie, for each * interesting ordering, collect all the cheapest startup subpaths and all the - * cheapest total paths, and build a MergeAppend path for each case. + * cheapest total paths, and build a suitable path for each case. * - * We don't currently generate any parameterized MergeAppend paths. While + * We don't currently generate any parameterized ordered paths here. While * it would not take much more code here to do so, it's very unclear that it * is worth the planning cycles to investigate such paths: there's little * use for an ordered path on the inside of a nestloop. In fact, it's likely @@ -1784,17 +1736,52 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, * and a parameterized MergeAppend is going to be more expensive than the * corresponding parameterized Append path. If we ever try harder to support * parameterized mergejoin plans, it might be worth adding support for - * parameterized MergeAppends to feed such joins. (See notes in + * parameterized paths here to feed such joins. (See notes in * optimizer/README for why that might not ever happen, though.) */ static void -generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel, - List *live_childrels, - List *all_child_pathkeys, - List *partitioned_rels) +generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel, + List *live_childrels, + List *all_child_pathkeys, + List *partitioned_rels) { ListCell *lcp; + List *partition_pathkeys = NIL; + List *partition_pathkeys_desc = NIL; + bool partition_pathkeys_partial = true; + bool partition_pathkeys_desc_partial = true; + /* + * Some partitioned table setups may allow us to use an Append node + * instead of a MergeAppend. This is possible in cases such as RANGE + * partitioned tables where it's guaranteed that an earlier partition must + * contain rows which come earlier in the sort order. To detect whether + * this is relevant, build pathkey descriptions of the partition ordering, + * for both forward and reverse scans. + */ + if (rel->part_scheme != NULL && IS_SIMPLE_REL(rel) && + partitions_are_ordered(rel->boundinfo, rel->nparts)) + { + partition_pathkeys = build_partition_pathkeys(root, rel, + ForwardScanDirection, + &partition_pathkeys_partial); + + partition_pathkeys_desc = build_partition_pathkeys(root, rel, + BackwardScanDirection, + &partition_pathkeys_desc_partial); + + /* + * You might think we should truncate_useless_pathkeys here, but + * allowing partition keys which are a subset of the query's pathkeys + * can often be useful. For example, consider a table partitioned by + * RANGE (a, b), and a query with ORDER BY a, b, c. If we have child + * paths that can produce the a, b, c ordering (perhaps via indexes on + * (a, b, c)) then it works to consider the appendrel output as + * ordered by a, b, c. + */ + } + + /* Now consider each interesting sort ordering */ foreach(lcp, all_child_pathkeys) { List *pathkeys = (List *) lfirst(lcp); @@ -1802,6 +1789,27 @@ generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel, List *total_subpaths = NIL; bool startup_neq_total = false; ListCell *lcr; + bool match_partition_order; + bool match_partition_order_desc; + + /* + * Determine if this sort ordering matches any partition pathkeys we + * have, for both ascending and descending partition order. If the + * partition pathkeys happen to be contained in pathkeys then it still + * works, as described above, providing that the partition pathkeys + * are complete and not just a prefix of the partition keys. (In such + * cases we'll be relying on the child paths to have sorted the + * lower-order columns of the required pathkeys.) + */ + match_partition_order = + pathkeys_contained_in(pathkeys, partition_pathkeys) || + (!partition_pathkeys_partial && + pathkeys_contained_in(partition_pathkeys, pathkeys)); + + match_partition_order_desc = !match_partition_order && + (pathkeys_contained_in(pathkeys, partition_pathkeys_desc) || + (!partition_pathkeys_desc_partial && + pathkeys_contained_in(partition_pathkeys_desc, pathkeys))); /* Select the child paths for this ordering... */ foreach(lcr, live_childrels) @@ -1844,26 +1852,94 @@ generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel, if (cheapest_startup != cheapest_total) startup_neq_total = true; - accumulate_append_subpath(cheapest_startup, - &startup_subpaths, NULL); - accumulate_append_subpath(cheapest_total, - &total_subpaths, NULL); + /* + * Collect the appropriate child paths. The required logic varies + * for the Append and MergeAppend cases. + */ + if (match_partition_order) + { + /* + * We're going to make a plain Append path. We don't need + * most of what accumulate_append_subpath would do, but we do + * want to cut out child Appends or MergeAppends if they have + * just a single subpath (and hence aren't doing anything + * useful). + */ + cheapest_startup = get_singleton_append_subpath(cheapest_startup); + cheapest_total = get_singleton_append_subpath(cheapest_total); + + startup_subpaths = lappend(startup_subpaths, cheapest_startup); + total_subpaths = lappend(total_subpaths, cheapest_total); + } + else if (match_partition_order_desc) + { + /* + * As above, but we need to reverse the order of the children, + * because nodeAppend.c doesn't know anything about reverse + * ordering and will scan the children in the order presented. + */ + cheapest_startup = get_singleton_append_subpath(cheapest_startup); + cheapest_total = get_singleton_append_subpath(cheapest_total); + + startup_subpaths = lcons(cheapest_startup, startup_subpaths); + total_subpaths = lcons(cheapest_total, total_subpaths); + } + else + { + /* + * Otherwise, rely on accumulate_append_subpath to collect the + * child paths for the MergeAppend. + */ + accumulate_append_subpath(cheapest_startup, + &startup_subpaths, NULL); + accumulate_append_subpath(cheapest_total, + &total_subpaths, NULL); + } } - /* ... and build the MergeAppend paths */ - add_path(rel, (Path *) create_merge_append_path(root, - rel, - startup_subpaths, - pathkeys, - NULL, - partitioned_rels)); - if (startup_neq_total) + /* ... and build the Append or MergeAppend paths */ + if (match_partition_order || match_partition_order_desc) + { + /* We only need Append */ + add_path(rel, (Path *) create_append_path(root, + rel, + startup_subpaths, + NIL, + pathkeys, + NULL, + 0, + false, + partitioned_rels, + -1)); + if (startup_neq_total) + add_path(rel, (Path *) create_append_path(root, + rel, + total_subpaths, + NIL, + pathkeys, + NULL, + 0, + false, + partitioned_rels, + -1)); + } + else + { + /* We need MergeAppend */ add_path(rel, (Path *) create_merge_append_path(root, rel, - total_subpaths, + startup_subpaths, pathkeys, NULL, partitioned_rels)); + if (startup_neq_total) + add_path(rel, (Path *) create_merge_append_path(root, + rel, + total_subpaths, + pathkeys, + NULL, + partitioned_rels)); + } } } @@ -1954,7 +2030,6 @@ get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel, * omitting a sort step, which seems fine: if the parent is to be an Append, * its result would be unsorted anyway, while if the parent is to be a * MergeAppend, there's no point in a separate sort on a child. - * its result would be unsorted anyway. * * Normally, either path is a partial path and subpaths is a list of partial * paths, or else path is a non-partial plan and subpaths is a list of those. @@ -1972,8 +2047,7 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) if (!apath->path.parallel_aware || apath->first_partial_path == 0) { - /* list_copy is important here to avoid sharing list substructure */ - *subpaths = list_concat(*subpaths, list_copy(apath->subpaths)); + *subpaths = list_concat(*subpaths, apath->subpaths); return; } else if (special_subpaths != NULL) @@ -1996,24 +2070,55 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) { MergeAppendPath *mpath = (MergeAppendPath *) path; - /* list_copy is important here to avoid sharing list substructure */ - *subpaths = list_concat(*subpaths, list_copy(mpath->subpaths)); + *subpaths = list_concat(*subpaths, mpath->subpaths); return; } *subpaths = lappend(*subpaths, path); } +/* + * get_singleton_append_subpath + * Returns the single subpath of an Append/MergeAppend, or just + * return 'path' if it's not a single sub-path Append/MergeAppend. + * + * Note: 'path' must not be a parallel-aware path. + */ +static Path * +get_singleton_append_subpath(Path *path) +{ + Assert(!path->parallel_aware); + + if (IsA(path, AppendPath)) + { + AppendPath *apath = (AppendPath *) path; + + if (list_length(apath->subpaths) == 1) + return (Path *) linitial(apath->subpaths); + } + else if (IsA(path, MergeAppendPath)) + { + MergeAppendPath *mpath = (MergeAppendPath *) path; + + if (list_length(mpath->subpaths) == 1) + return (Path *) linitial(mpath->subpaths); + } + + return path; +} + /* * set_dummy_rel_pathlist * Build a dummy path for a relation that's been excluded by constraints * * Rather than inventing a special "dummy" path type, we represent this as an - * AppendPath with no members (see also IS_DUMMY_PATH/IS_DUMMY_REL macros). + * AppendPath with no members (see also IS_DUMMY_APPEND/IS_DUMMY_REL macros). * - * This is exported because inheritance_planner() has need for it. + * (See also mark_dummy_rel, which does basically the same thing, but is + * typically used to change a rel into dummy state after we already made + * paths for it.) */ -void +static void set_dummy_rel_pathlist(RelOptInfo *rel) { /* Set dummy size estimates --- we leave attr_widths[] as zeroes */ @@ -2024,14 +2129,16 @@ set_dummy_rel_pathlist(RelOptInfo *rel) rel->pathlist = NIL; rel->partial_pathlist = NIL; - add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, NULL, + /* Set up the dummy path */ + add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, + NIL, rel->lateral_relids, 0, false, NIL, -1)); /* - * We set the cheapest path immediately, to ensure that IS_DUMMY_REL() - * will recognize the relation as dummy if anyone asks. This is redundant - * when we're called from set_rel_size(), but not when called from - * elsewhere, and doing it twice is harmless anyway. + * We set the cheapest-path fields immediately, just in case they were + * pointing at some discarded path. This is redundant when we're called + * from set_rel_size(), but not when called from elsewhere, and doing it + * twice is harmless anyway. */ set_cheapest(rel); } @@ -2242,26 +2349,31 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel, pathkeys, required_outer)); } - /* If consider_parallel is false, there should be no partial paths. */ - Assert(sub_final_rel->consider_parallel || - sub_final_rel->partial_pathlist == NIL); - - /* Same for partial paths. */ - foreach(lc, sub_final_rel->partial_pathlist) + /* If outer rel allows parallelism, do same for partial paths. */ + if (rel->consider_parallel && bms_is_empty(required_outer)) { - Path *subpath = (Path *) lfirst(lc); - List *pathkeys; - - /* Convert subpath's pathkeys to outer representation */ - pathkeys = convert_subquery_pathkeys(root, - rel, - subpath->pathkeys, - make_tlist_from_pathtarget(subpath->pathtarget)); + /* If consider_parallel is false, there should be no partial paths. */ + Assert(sub_final_rel->consider_parallel || + sub_final_rel->partial_pathlist == NIL); - /* Generate outer path using this subpath */ - add_partial_path(rel, (Path *) - create_subqueryscan_path(root, rel, subpath, - pathkeys, required_outer)); + /* Same for partial paths. */ + foreach(lc, sub_final_rel->partial_pathlist) + { + Path *subpath = (Path *) lfirst(lc); + List *pathkeys; + + /* Convert subpath's pathkeys to outer representation */ + pathkeys = convert_subquery_pathkeys(root, + rel, + subpath->pathkeys, + make_tlist_from_pathtarget(subpath->pathtarget)); + + /* Generate outer path using this subpath */ + add_partial_path(rel, (Path *) + create_subqueryscan_path(root, rel, subpath, + pathkeys, + required_outer)); + } } } @@ -2470,6 +2582,36 @@ set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel, set_cheapest(rel); } +/* + * set_result_pathlist + * Build the (single) access path for an RTE_RESULT RTE + * + * There's no need for a separate set_result_size phase, since we + * don't support join-qual-parameterized paths for these RTEs. + */ +static void +set_result_pathlist(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte) +{ + Relids required_outer; + + /* Mark rel with estimated output rows, width, etc */ + set_result_size_estimates(root, rel); + + /* + * We don't support pushing join clauses into the quals of a Result scan, + * but it could still have required parameterization due to LATERAL refs + * in its tlist. + */ + required_outer = rel->lateral_relids; + + /* Generate appropriate path */ + add_path(rel, create_resultscan_path(root, rel, required_outer)); + + /* Select cheapest path (pretty easy in this case...) */ + set_cheapest(rel); +} + /* * set_worktable_pathlist * Build the (single) access path for a self-reference CTE RTE @@ -2736,11 +2878,10 @@ standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels) join_search_one_level(root, lev); /* - * Run generate_partitionwise_join_paths() and - * generate_gather_paths() for each just-processed joinrel. We could - * not do this earlier because both regular and partial paths can get - * added to a particular joinrel at multiple times within - * join_search_one_level. + * Run generate_partitionwise_join_paths() and generate_gather_paths() + * for each just-processed joinrel. We could not do this earlier + * because both regular and partial paths can get added to a + * particular joinrel at multiple times within join_search_one_level. * * After that, we're done creating paths for the joinrel, so run * set_cheapest(). @@ -3060,7 +3201,7 @@ compare_tlist_datatypes(List *tlist, List *colTypes, elog(ERROR, "wrong number of tlist entries"); if (exprType((Node *) tle->expr) != lfirst_oid(colType)) safetyInfo->unsafeColumns[tle->resno] = true; - colType = lnext(colType); + colType = lnext(colTypes, colType); } if (colType != NULL) elog(ERROR, "wrong number of tlist entries"); @@ -3534,6 +3675,9 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel) if (!IS_PARTITIONED_REL(rel)) return; + /* The relation should have consider_partitionwise_join set. */ + Assert(rel->consider_partitionwise_join); + /* Guard against stack overflow due to overly deep partition hierarchy. */ check_stack_depth(); @@ -3545,17 +3689,19 @@ generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel) { RelOptInfo *child_rel = part_rels[cnt_parts]; - Assert(child_rel != NULL); + /* If it's been pruned entirely, it's certainly dummy. */ + if (child_rel == NULL) + continue; /* Add partitionwise join paths for partitioned child-joins. */ generate_partitionwise_join_paths(root, child_rel); + set_cheapest(child_rel); + /* Dummy children will not be scanned, so ignore those. */ if (IS_DUMMY_REL(child_rel)) continue; - set_cheapest(child_rel); - #ifdef OPTIMIZER_DEBUG debug_print_rel(root, child_rel); #endif @@ -3612,7 +3758,7 @@ print_restrictclauses(PlannerInfo *root, List *clauses) RestrictInfo *c = lfirst(l); print_expr((Node *) c->clause, root->parse->rtable); - if (lnext(l)) + if (lnext(clauses, l)) printf(", "); } } @@ -3636,9 +3782,6 @@ print_path(PlannerInfo *root, Path *path, int indent) case T_SampleScan: ptype = "SampleScan"; break; - case T_SubqueryScan: - ptype = "SubqueryScan"; - break; case T_FunctionScan: ptype = "FunctionScan"; break; @@ -3651,6 +3794,12 @@ print_path(PlannerInfo *root, Path *path, int indent) case T_CteScan: ptype = "CteScan"; break; + case T_NamedTuplestoreScan: + ptype = "NamedTuplestoreScan"; + break; + case T_Result: + ptype = "Result"; + break; case T_WorkTableScan: ptype = "WorkTableScan"; break; @@ -3675,19 +3824,34 @@ print_path(PlannerInfo *root, Path *path, int indent) ptype = "TidScan"; break; case T_SubqueryScanPath: - ptype = "SubqueryScanScan"; + ptype = "SubqueryScan"; break; case T_ForeignPath: ptype = "ForeignScan"; break; + case T_CustomPath: + ptype = "CustomScan"; + break; + case T_NestPath: + ptype = "NestLoop"; + join = true; + break; + case T_MergePath: + ptype = "MergeJoin"; + join = true; + break; + case T_HashPath: + ptype = "HashJoin"; + join = true; + break; case T_AppendPath: ptype = "Append"; break; case T_MergeAppendPath: ptype = "MergeAppend"; break; - case T_ResultPath: - ptype = "Result"; + case T_GroupResultPath: + ptype = "GroupResult"; break; case T_MaterialPath: ptype = "Material"; @@ -3701,6 +3865,10 @@ print_path(PlannerInfo *root, Path *path, int indent) ptype = "Gather"; subpath = ((GatherPath *) path)->subpath; break; + case T_GatherMergePath: + ptype = "GatherMerge"; + subpath = ((GatherMergePath *) path)->subpath; + break; case T_ProjectionPath: ptype = "Projection"; subpath = ((ProjectionPath *) path)->subpath; @@ -3754,18 +3922,6 @@ print_path(PlannerInfo *root, Path *path, int indent) ptype = "Limit"; subpath = ((LimitPath *) path)->subpath; break; - case T_NestPath: - ptype = "NestLoop"; - join = true; - break; - case T_MergePath: - ptype = "MergeJoin"; - join = true; - break; - case T_HashPath: - ptype = "HashJoin"; - join = true; - break; default: ptype = "???Path"; break; diff --git a/src/backend/optimizer/path/clausesel.c b/src/backend/optimizer/path/clausesel.c index f4717942c3a..4bf777d82d3 100644 --- a/src/backend/optimizer/path/clausesel.c +++ b/src/backend/optimizer/path/clausesel.c @@ -3,7 +3,7 @@ * clausesel.c * Routines to compute clause selectivities * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,10 @@ #include "postgres.h" #include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/plancat.h" #include "utils/fmgroids.h" @@ -40,9 +42,9 @@ typedef struct RangeQueryClause } RangeQueryClause; static void addRangeClause(RangeQueryClause **rqlist, Node *clause, - bool varonleft, bool isLTsel, Selectivity s2); + bool varonleft, bool isLTsel, Selectivity s2); static RelOptInfo *find_single_rel_for_clauses(PlannerInfo *root, - List *clauses); + List *clauses); /**************************************************************************** * ROUTINES TO COMPUTE SELECTIVITIES @@ -58,17 +60,67 @@ static RelOptInfo *find_single_rel_for_clauses(PlannerInfo *root, * * See clause_selectivity() for the meaning of the additional parameters. * + * The basic approach is to apply extended statistics first, on as many + * clauses as possible, in order to capture cross-column dependencies etc. + * The remaining clauses are then estimated using regular statistics tracked + * for individual columns. This is done by simply passing the clauses to + * clauselist_selectivity_simple. + */ +Selectivity +clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo) +{ + Selectivity s1 = 1.0; + RelOptInfo *rel; + Bitmapset *estimatedclauses = NULL; + + /* + * Determine if these clauses reference a single relation. If so, and if + * it has extended statistics, try to apply those. + */ + rel = find_single_rel_for_clauses(root, clauses); + if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL) + { + /* + * Estimate as many clauses as possible using extended statistics. + * + * 'estimatedclauses' tracks the 0-based list position index of + * clauses that we've estimated using extended statistics, and that + * should be ignored. + */ + s1 *= statext_clauselist_selectivity(root, clauses, varRelid, + jointype, sjinfo, rel, + &estimatedclauses); + } + + /* + * Apply normal selectivity estimates for the remaining clauses, passing + * 'estimatedclauses' so that it skips already estimated ones. + */ + return s1 * clauselist_selectivity_simple(root, clauses, varRelid, + jointype, sjinfo, + estimatedclauses); +} + +/* + * clauselist_selectivity_simple - + * Compute the selectivity of an implicitly-ANDed list of boolean + * expression clauses. The list can be empty, in which case 1.0 + * must be returned. List elements may be either RestrictInfos + * or bare expression clauses --- the former is preferred since + * it allows caching of results. The estimatedclauses bitmap tracks + * clauses that have already been estimated by other means. + * + * See clause_selectivity() for the meaning of the additional parameters. + * * Our basic approach is to take the product of the selectivities of the * subclauses. However, that's only right if the subclauses have independent * probabilities, and in reality they are often NOT independent. So, * we want to be smarter where we can. * - * If the clauses taken together refer to just one relation, we'll try to - * apply selectivity estimates using any extended statistics for that rel. - * Currently we only have (soft) functional dependencies, so apply these in as - * many cases as possible, and fall back on normal estimates for remaining - * clauses. - * * We also recognize "range queries", such as "x > 34 AND x < 42". Clauses * are recognized as possible range query components if they are restriction * opclauses whose operators have scalarltsel or a related function as their @@ -96,54 +148,29 @@ static RelOptInfo *find_single_rel_for_clauses(PlannerInfo *root, * selectivity functions; perhaps some day we can generalize the approach. */ Selectivity -clauselist_selectivity(PlannerInfo *root, - List *clauses, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo) +clauselist_selectivity_simple(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + Bitmapset *estimatedclauses) { Selectivity s1 = 1.0; - RelOptInfo *rel; - Bitmapset *estimatedclauses = NULL; RangeQueryClause *rqlist = NULL; ListCell *l; int listidx; /* - * If there's exactly one clause, just go directly to - * clause_selectivity(). None of what we might do below is relevant. + * If there's exactly one clause (and it was not estimated yet), just go + * directly to clause_selectivity(). None of what we might do below is + * relevant. */ - if (list_length(clauses) == 1) + if ((list_length(clauses) == 1) && + bms_num_members(estimatedclauses) == 0) return clause_selectivity(root, (Node *) linitial(clauses), varRelid, jointype, sjinfo); /* - * Determine if these clauses reference a single relation. If so, and if - * it has extended statistics, try to apply those. - */ - rel = find_single_rel_for_clauses(root, clauses); - if (rel && rel->rtekind == RTE_RELATION && rel->statlist != NIL) - { - /* - * Perform selectivity estimations on any clauses found applicable by - * dependencies_clauselist_selectivity. 'estimatedclauses' will be - * filled with the 0-based list positions of clauses used that way, so - * that we can ignore them below. - */ - s1 *= dependencies_clauselist_selectivity(root, clauses, varRelid, - jointype, sjinfo, rel, - &estimatedclauses); - - /* - * This would be the place to apply any other types of extended - * statistics selectivity estimations for remaining clauses. - */ - } - - /* - * Apply normal selectivity estimates for remaining clauses. We'll be - * careful to skip any clauses which were already estimated above. - * * Anything that doesn't look like a potential rangequery clause gets * multiplied into s1 and forgotten. Anything that does gets inserted into * an rqlist entry. @@ -688,7 +715,7 @@ clause_selectivity(PlannerInfo *root, /* XXX any way to do better than default? */ } } - else if (not_clause(clause)) + else if (is_notclause(clause)) { /* inverse of the selectivity of the underlying clause */ s1 = 1.0 - clause_selectivity(root, @@ -697,7 +724,7 @@ clause_selectivity(PlannerInfo *root, jointype, sjinfo); } - else if (and_clause(clause)) + else if (is_andclause(clause)) { /* share code with clauselist_selectivity() */ s1 = clauselist_selectivity(root, @@ -706,7 +733,7 @@ clause_selectivity(PlannerInfo *root, jointype, sjinfo); } - else if (or_clause(clause)) + else if (is_orclause(clause)) { /* * Selectivities for an OR clause are computed as s1+s2 - s1*s2 to @@ -760,6 +787,21 @@ clause_selectivity(PlannerInfo *root, if (IsA(clause, DistinctExpr)) s1 = 1.0 - s1; } + else if (is_funcclause(clause)) + { + FuncExpr *funcclause = (FuncExpr *) clause; + + /* Try to get an estimate from the support function, if any */ + s1 = function_selectivity(root, + funcclause->funcid, + funcclause->args, + funcclause->inputcollid, + treat_as_join_clause(clause, rinfo, + varRelid, sjinfo), + varRelid, + jointype, + sjinfo); + } else if (IsA(clause, ScalarArrayOpExpr)) { /* Use node specific selectivity calculation function */ diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 47729de8969..c5f65934859 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -60,7 +60,7 @@ * values. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -71,9 +71,6 @@ #include "postgres.h" -#ifdef _MSC_VER -#include /* for _isnan */ -#endif #include #include "access/amapi.h" @@ -82,9 +79,11 @@ #include "executor/executor.h" #include "executor/nodeHash.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/placeholder.h" @@ -138,6 +137,7 @@ bool enable_partitionwise_join = false; bool enable_partitionwise_aggregate = false; bool enable_parallel_append = true; bool enable_parallel_hash = true; +bool enable_partition_pruning = true; typedef struct { @@ -145,33 +145,34 @@ typedef struct QualCost total; } cost_qual_eval_context; -static List *extract_nonindex_conditions(List *qual_clauses, List *indexquals); +static List *extract_nonindex_conditions(List *qual_clauses, List *indexclauses); static MergeScanSelCache *cached_scansel(PlannerInfo *root, - RestrictInfo *rinfo, - PathKey *pathkey); + RestrictInfo *rinfo, + PathKey *pathkey); static void cost_rescan(PlannerInfo *root, Path *path, - Cost *rescan_startup_cost, Cost *rescan_total_cost); + Cost *rescan_startup_cost, Cost *rescan_total_cost); static bool cost_qual_eval_walker(Node *node, cost_qual_eval_context *context); static void get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel, - ParamPathInfo *param_info, - QualCost *qpqual_cost); + ParamPathInfo *param_info, + QualCost *qpqual_cost); static bool has_indexed_join_quals(NestPath *joinpath); static double approx_tuple_count(PlannerInfo *root, JoinPath *path, - List *quals); + List *quals); static double calc_joinrel_size_estimate(PlannerInfo *root, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel, - double outer_rows, - double inner_rows, - SpecialJoinInfo *sjinfo, - List *restrictlist); + RelOptInfo *joinrel, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel, + double outer_rows, + double inner_rows, + SpecialJoinInfo *sjinfo, + List *restrictlist); static Selectivity get_foreign_key_join_selectivity(PlannerInfo *root, - Relids outer_relids, - Relids inner_relids, - SpecialJoinInfo *sjinfo, - List **restrictlist); + Relids outer_relids, + Relids inner_relids, + SpecialJoinInfo *sjinfo, + List **restrictlist); static Cost append_nonpartial_cost(List *subpaths, int numpaths, - int parallel_workers); + int parallel_workers); static void set_rel_width(PlannerInfo *root, RelOptInfo *rel); static double relation_byte_size(double tuples, int width); static double page_size(double tuples, int width); @@ -516,18 +517,17 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count, { path->path.rows = path->path.param_info->ppi_rows; /* qpquals come from the rel's restriction clauses and ppi_clauses */ - qpquals = list_concat( - extract_nonindex_conditions(path->indexinfo->indrestrictinfo, - path->indexquals), + qpquals = list_concat(extract_nonindex_conditions(path->indexinfo->indrestrictinfo, + path->indexclauses), extract_nonindex_conditions(path->path.param_info->ppi_clauses, - path->indexquals)); + path->indexclauses)); } else { path->path.rows = baserel->rows; /* qpquals come from just the rel's restriction clauses */ qpquals = extract_nonindex_conditions(path->indexinfo->indrestrictinfo, - path->indexquals); + path->indexclauses); } if (!enable_indexscan) @@ -539,7 +539,7 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count, * for scanning the index, as well as the selectivity of the index (ie, * the fraction of main-table tuples we will have to retrieve) and its * correlation to the main-table tuple order. We need a cast here because - * relation.h uses a weak function type to avoid including amapi.h. + * pathnodes.h uses a weak function type to avoid including amapi.h. */ amcostestimate = (amcostestimate_function) index->amcostestimate; amcostestimate(root, path, loop_count, @@ -752,20 +752,19 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count, * * Given a list of quals to be enforced in an indexscan, extract the ones that * will have to be applied as qpquals (ie, the index machinery won't handle - * them). The actual rules for this appear in create_indexscan_plan() in - * createplan.c, but the full rules are fairly expensive and we don't want to - * go to that much effort for index paths that don't get selected for the - * final plan. So we approximate it as quals that don't appear directly in - * indexquals and also are not redundant children of the same EquivalenceClass - * as some indexqual. This method neglects some infrequently-relevant - * considerations, specifically clauses that needn't be checked because they - * are implied by an indexqual. It does not seem worth the cycles to try to - * factor that in at this stage, even though createplan.c will take pains to - * remove such unnecessary clauses from the qpquals list if this path is - * selected for use. + * them). Here we detect only whether a qual clause is directly redundant + * with some indexclause. If the index path is chosen for use, createplan.c + * will try a bit harder to get rid of redundant qual conditions; specifically + * it will see if quals can be proven to be implied by the indexquals. But + * it does not seem worth the cycles to try to factor that in at this stage, + * since we're only trying to estimate qual eval costs. Otherwise this must + * match the logic in create_indexscan_plan(). + * + * qual_clauses, and the result, are lists of RestrictInfos. + * indexclauses is a list of IndexClauses. */ static List * -extract_nonindex_conditions(List *qual_clauses, List *indexquals) +extract_nonindex_conditions(List *qual_clauses, List *indexclauses) { List *result = NIL; ListCell *lc; @@ -776,10 +775,8 @@ extract_nonindex_conditions(List *qual_clauses, List *indexquals) if (rinfo->pseudoconstant) continue; /* we may drop pseudoconstants here */ - if (list_member_ptr(indexquals, rinfo)) - continue; /* simple duplicate */ - if (is_redundant_derived_clause(rinfo, indexquals)) - continue; /* derived from same EquivalenceClass */ + if (is_redundant_with_indexclauses(rinfo, indexclauses)) + continue; /* dup or derived from same EquivalenceClass */ /* ... skip the predicate proof attempt createplan.c will try ... */ result = lappend(result, rinfo); } @@ -818,7 +815,7 @@ extract_nonindex_conditions(List *qual_clauses, List *indexquals) * product rather than calculating it here. "pages" is the number of pages * in the object under consideration (either an index or a table). * "index_pages" is the amount to add to the total table space, which was - * computed for us by query_planner. + * computed for us by make_one_rel. * * Caller is expected to have ensured that tuples_fetched is greater than zero * and rounded to integer (see clamp_row_est). The result will likewise be @@ -1203,15 +1200,18 @@ cost_tidscan(Path *path, PlannerInfo *root, ntuples = 0; foreach(l, tidquals) { - if (IsA(lfirst(l), ScalarArrayOpExpr)) + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + Expr *qual = rinfo->clause; + + if (IsA(qual, ScalarArrayOpExpr)) { /* Each element of the array yields 1 tuple */ - ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) lfirst(l); + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) qual; Node *arraynode = (Node *) lsecond(saop->args); ntuples += estimate_array_length(arraynode); } - else if (IsA(lfirst(l), CurrentOfExpr)) + else if (IsA(qual, CurrentOfExpr)) { /* CURRENT OF yields 1 tuple */ isCurrentOf = true; @@ -1568,6 +1568,40 @@ cost_namedtuplestorescan(Path *path, PlannerInfo *root, path->total_cost = startup_cost + run_cost; } +/* + * cost_resultscan + * Determines and returns the cost of scanning an RTE_RESULT relation. + */ +void +cost_resultscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info) +{ + Cost startup_cost = 0; + Cost run_cost = 0; + QualCost qpqual_cost; + Cost cpu_per_tuple; + + /* Should only be applied to RTE_RESULT base relations */ + Assert(baserel->relid > 0); + Assert(baserel->rtekind == RTE_RESULT); + + /* Mark the path with the correct row estimate */ + if (param_info) + path->rows = param_info->ppi_rows; + else + path->rows = baserel->rows; + + /* We charge qual cost plus cpu_tuple_cost */ + get_restriction_qual_cost(root, baserel, param_info, &qpqual_cost); + + startup_cost += qpqual_cost.startup; + cpu_per_tuple = cpu_tuple_cost + qpqual_cost.per_tuple; + run_cost += cpu_per_tuple * baserel->tuples; + + path->startup_cost = startup_cost; + path->total_cost = startup_cost + run_cost; +} + /* * cost_recursive_union * Determines and returns the cost of performing a recursive union, @@ -1777,7 +1811,7 @@ append_nonpartial_cost(List *subpaths, int numpaths, int parallel_workers) return 0; /* - * Array length is number of workers or number of relevants paths, + * Array length is number of workers or number of relevant paths, * whichever is less. */ arrlen = Min(parallel_workers, numpaths); @@ -1804,7 +1838,7 @@ append_nonpartial_cost(List *subpaths, int numpaths, int parallel_workers) * For each of the remaining subpaths, add its cost to the array element * with minimum cost. */ - for_each_cell(l, cell) + for_each_cell(l, subpaths, cell) { Path *subpath = (Path *) lfirst(l); int i; @@ -1844,27 +1878,83 @@ cost_append(AppendPath *apath) apath->path.startup_cost = 0; apath->path.total_cost = 0; + apath->path.rows = 0; if (apath->subpaths == NIL) return; if (!apath->path.parallel_aware) { - Path *subpath = (Path *) linitial(apath->subpaths); + List *pathkeys = apath->path.pathkeys; - /* - * Startup cost of non-parallel-aware Append is the startup cost of - * first subpath. - */ - apath->path.startup_cost = subpath->startup_cost; + if (pathkeys == NIL) + { + Path *subpath = (Path *) linitial(apath->subpaths); - /* Compute rows and costs as sums of subplan rows and costs. */ - foreach(l, apath->subpaths) + /* + * For an unordered, non-parallel-aware Append we take the startup + * cost as the startup cost of the first subpath. + */ + apath->path.startup_cost = subpath->startup_cost; + + /* Compute rows and costs as sums of subplan rows and costs. */ + foreach(l, apath->subpaths) + { + Path *subpath = (Path *) lfirst(l); + + apath->path.rows += subpath->rows; + apath->path.total_cost += subpath->total_cost; + } + } + else { - Path *subpath = (Path *) lfirst(l); + /* + * For an ordered, non-parallel-aware Append we take the startup + * cost as the sum of the subpath startup costs. This ensures + * that we don't underestimate the startup cost when a query's + * LIMIT is such that several of the children have to be run to + * satisfy it. This might be overkill --- another plausible hack + * would be to take the Append's startup cost as the maximum of + * the child startup costs. But we don't want to risk believing + * that an ORDER BY LIMIT query can be satisfied at small cost + * when the first child has small startup cost but later ones + * don't. (If we had the ability to deal with nonlinear cost + * interpolation for partial retrievals, we would not need to be + * so conservative about this.) + * + * This case is also different from the above in that we have to + * account for possibly injecting sorts into subpaths that aren't + * natively ordered. + */ + foreach(l, apath->subpaths) + { + Path *subpath = (Path *) lfirst(l); + Path sort_path; /* dummy for result of cost_sort */ - apath->path.rows += subpath->rows; - apath->path.total_cost += subpath->total_cost; + if (!pathkeys_contained_in(pathkeys, subpath->pathkeys)) + { + /* + * We'll need to insert a Sort node, so include costs for + * that. We can use the parent's LIMIT if any, since we + * certainly won't pull more than that many tuples from + * any child. + */ + cost_sort(&sort_path, + NULL, /* doesn't currently need root */ + pathkeys, + subpath->total_cost, + subpath->rows, + subpath->pathtarget->width, + 0.0, + work_mem, + apath->limit_tuples); + subpath = &sort_path; + } + + apath->path.rows += subpath->rows; + apath->path.startup_cost += subpath->startup_cost; + apath->path.total_cost += subpath->total_cost; + } } } else /* parallel-aware */ @@ -1872,6 +1962,9 @@ cost_append(AppendPath *apath) int i = 0; double parallel_divisor = get_parallel_divisor(&apath->path); + /* Parallel-aware Append never produces ordered output. */ + Assert(apath->path.pathkeys == NIL); + /* Calculate startup cost. */ foreach(l, apath->subpaths) { @@ -2078,9 +2171,9 @@ cost_agg(Path *path, PlannerInfo *root, /* * The transCost.per_tuple component of aggcosts should be charged once * per input tuple, corresponding to the costs of evaluating the aggregate - * transfns and their input expressions (with any startup cost of course - * charged but once). The finalCost component is charged once per output - * tuple, corresponding to the costs of evaluating the finalfns. + * transfns and their input expressions. The finalCost.per_tuple component + * is charged once per output tuple, corresponding to the costs of + * evaluating the finalfns. Startup costs are of course charged but once. * * If we are grouping, we charge an additional cpu_operator_cost per * grouping column per input tuple for grouping comparisons. @@ -2102,7 +2195,8 @@ cost_agg(Path *path, PlannerInfo *root, startup_cost = input_total_cost; startup_cost += aggcosts->transCost.startup; startup_cost += aggcosts->transCost.per_tuple * input_tuples; - startup_cost += aggcosts->finalCost; + startup_cost += aggcosts->finalCost.startup; + startup_cost += aggcosts->finalCost.per_tuple; /* we aren't grouping */ total_cost = startup_cost + cpu_tuple_cost; output_tuples = 1; @@ -2121,7 +2215,8 @@ cost_agg(Path *path, PlannerInfo *root, total_cost += aggcosts->transCost.startup; total_cost += aggcosts->transCost.per_tuple * input_tuples; total_cost += (cpu_operator_cost * numGroupCols) * input_tuples; - total_cost += aggcosts->finalCost * numGroups; + total_cost += aggcosts->finalCost.startup; + total_cost += aggcosts->finalCost.per_tuple * numGroups; total_cost += cpu_tuple_cost * numGroups; output_tuples = numGroups; } @@ -2134,8 +2229,9 @@ cost_agg(Path *path, PlannerInfo *root, startup_cost += aggcosts->transCost.startup; startup_cost += aggcosts->transCost.per_tuple * input_tuples; startup_cost += (cpu_operator_cost * numGroupCols) * input_tuples; + startup_cost += aggcosts->finalCost.startup; total_cost = startup_cost; - total_cost += aggcosts->finalCost * numGroups; + total_cost += aggcosts->finalCost.per_tuple * numGroups; total_cost += cpu_tuple_cost * numGroups; output_tuples = numGroups; } @@ -2200,7 +2296,11 @@ cost_windowagg(Path *path, PlannerInfo *root, Cost wfunccost; QualCost argcosts; - wfunccost = get_func_cost(wfunc->winfnoid) * cpu_operator_cost; + argcosts.startup = argcosts.per_tuple = 0; + add_function_cost(root, wfunc->winfnoid, (Node *) wfunc, + &argcosts); + startup_cost += argcosts.startup; + wfunccost = argcosts.per_tuple; /* also add the input expressions' cost to per-input-row costs */ cost_qual_eval_node(&argcosts, (Node *) wfunc->args, root); @@ -2942,8 +3042,13 @@ final_cost_mergejoin(PlannerInfo *root, MergePath *path, if (rescannedtuples < 0) rescannedtuples = 0; } - /* We'll inflate various costs this much to account for rescanning */ - rescanratio = 1.0 + (rescannedtuples / inner_path_rows); + + /* + * We'll inflate various costs this much to account for rescanning. Note + * that this is to be multiplied by something involving inner_rows, or + * another number related to the portion of the inner rel we'll scan. + */ + rescanratio = 1.0 + (rescannedtuples / inner_rows); /* * Decide whether we want to materialize the inner input to shield it from @@ -2970,7 +3075,7 @@ final_cost_mergejoin(PlannerInfo *root, MergePath *path, * of the generated Material node. */ mat_inner_cost = inner_run_cost + - cpu_operator_cost * inner_path_rows * rescanratio; + cpu_operator_cost * inner_rows * rescanratio; /* * If we don't need mark/restore at all, we don't need materialization. @@ -3455,10 +3560,10 @@ final_cost_hashjoin(PlannerInfo *root, HashPath *path, clamp_row_est(inner_path_rows / virtualbuckets) * 0.05; /* Get # of tuples that will pass the basic join */ - if (path->jpath.jointype == JOIN_SEMI) - hashjointuples = outer_matched_rows; - else + if (path->jpath.jointype == JOIN_ANTI) hashjointuples = outer_path_rows - outer_matched_rows; + else + hashjointuples = outer_matched_rows; } else { @@ -3825,8 +3930,8 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) */ if (IsA(node, FuncExpr)) { - context->total.per_tuple += - get_func_cost(((FuncExpr *) node)->funcid) * cpu_operator_cost; + add_function_cost(context->root, ((FuncExpr *) node)->funcid, node, + &context->total); } else if (IsA(node, OpExpr) || IsA(node, DistinctExpr) || @@ -3834,8 +3939,8 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) { /* rely on struct equivalence to treat these all alike */ set_opfuncid((OpExpr *) node); - context->total.per_tuple += - get_func_cost(((OpExpr *) node)->opfuncid) * cpu_operator_cost; + add_function_cost(context->root, ((OpExpr *) node)->opfuncid, node, + &context->total); } else if (IsA(node, ScalarArrayOpExpr)) { @@ -3845,10 +3950,15 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) */ ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) node; Node *arraynode = (Node *) lsecond(saop->args); + QualCost sacosts; set_sa_opfuncid(saop); - context->total.per_tuple += get_func_cost(saop->opfuncid) * - cpu_operator_cost * estimate_array_length(arraynode) * 0.5; + sacosts.startup = sacosts.per_tuple = 0; + add_function_cost(context->root, saop->opfuncid, NULL, + &sacosts); + context->total.startup += sacosts.startup; + context->total.per_tuple += sacosts.per_tuple * + estimate_array_length(arraynode) * 0.5; } else if (IsA(node, Aggref) || IsA(node, WindowFunc)) @@ -3874,11 +3984,13 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) /* check the result type's input function */ getTypeInputInfo(iocoerce->resulttype, &iofunc, &typioparam); - context->total.per_tuple += get_func_cost(iofunc) * cpu_operator_cost; + add_function_cost(context->root, iofunc, NULL, + &context->total); /* check the input type's output function */ getTypeOutputInfo(exprType((Node *) iocoerce->arg), &iofunc, &typisvarlena); - context->total.per_tuple += get_func_cost(iofunc) * cpu_operator_cost; + add_function_cost(context->root, iofunc, NULL, + &context->total); } else if (IsA(node, ArrayCoerceExpr)) { @@ -3902,8 +4014,8 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context) { Oid opid = lfirst_oid(lc); - context->total.per_tuple += get_func_cost(get_opcode(opid)) * - cpu_operator_cost; + add_function_cost(context->root, get_opcode(opid), NULL, + &context->total); } } else if (IsA(node, MinMaxExpr) || @@ -4022,16 +4134,18 @@ get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel, * them to all the join cost estimation functions. * * Input parameters: + * joinrel: join relation under consideration * outerrel: outer relation under consideration * innerrel: inner relation under consideration * jointype: if not JOIN_SEMI or JOIN_ANTI, we assume it's inner_unique * sjinfo: SpecialJoinInfo relevant to this join * restrictlist: join quals * Output parameters: - * *semifactors is filled in (see relation.h for field definitions) + * *semifactors is filled in (see pathnodes.h for field definitions) */ void compute_semi_anti_join_factors(PlannerInfo *root, + RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, @@ -4060,7 +4174,7 @@ compute_semi_anti_join_factors(PlannerInfo *root, { RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); - if (!rinfo->is_pushed_down) + if (!RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) joinquals = lappend(joinquals, rinfo); } } @@ -4197,8 +4311,7 @@ has_indexed_join_quals(NestPath *joinpath) innerpath->parent->relids, joinrelids)) { - if (!(list_member_ptr(indexclauses, rinfo) || - is_redundant_derived_clause(rinfo, indexclauses))) + if (!is_redundant_with_indexclauses(rinfo, indexclauses)) return false; found_one = true; } @@ -4330,8 +4443,7 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel, * restriction clauses. Note that we force the clauses to be treated as * non-join clauses during selectivity estimation. */ - allclauses = list_concat(list_copy(param_clauses), - rel->baserestrictinfo); + allclauses = list_concat_copy(param_clauses, rel->baserestrictinfo); nrows = rel->tuples * clauselist_selectivity(root, allclauses, @@ -4375,6 +4487,7 @@ set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel, List *restrictlist) { rel->rows = calc_joinrel_size_estimate(root, + rel, outer_rel, inner_rel, outer_rel->rows, @@ -4417,6 +4530,7 @@ get_parameterized_joinrel_size(PlannerInfo *root, RelOptInfo *rel, * estimate for any pair with the same parameterization. */ nrows = calc_joinrel_size_estimate(root, + rel, outer_path->parent, inner_path->parent, outer_path->rows, @@ -4440,6 +4554,7 @@ get_parameterized_joinrel_size(PlannerInfo *root, RelOptInfo *rel, */ static double calc_joinrel_size_estimate(PlannerInfo *root, + RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, double outer_rows, @@ -4492,7 +4607,7 @@ calc_joinrel_size_estimate(PlannerInfo *root, { RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); - if (rinfo->is_pushed_down) + if (RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) pushedquals = lappend(pushedquals, rinfo); else joinquals = lappend(joinquals, rinfo); @@ -4608,8 +4723,6 @@ get_foreign_key_join_selectivity(PlannerInfo *root, bool ref_is_outer; List *removedlist; ListCell *cell; - ListCell *prev; - ListCell *next; /* * This FK is not relevant unless it connects a baserel on one side of @@ -4650,14 +4763,12 @@ get_foreign_key_join_selectivity(PlannerInfo *root, worklist = list_copy(worklist); removedlist = NIL; - prev = NULL; - for (cell = list_head(worklist); cell; cell = next) + foreach(cell, worklist) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(cell); bool remove_it = false; int i; - next = lnext(cell); /* Drop this clause if it matches any column of the FK */ for (i = 0; i < fkinfo->nkeys; i++) { @@ -4697,11 +4808,9 @@ get_foreign_key_join_selectivity(PlannerInfo *root, } if (remove_it) { - worklist = list_delete_cell(worklist, cell, prev); + worklist = foreach_delete_current(worklist, cell); removedlist = lappend(removedlist, rinfo); } - else - prev = cell; } /* @@ -4898,7 +5007,7 @@ set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel) foreach(lc, rte->functions) { RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); - double ntup = expression_returns_set_rows(rtfunc->funcexpr); + double ntup = expression_returns_set_rows(root, rtfunc->funcexpr); if (ntup > rel->tuples) rel->tuples = ntup; @@ -5032,6 +5141,29 @@ set_namedtuplestore_size_estimates(PlannerInfo *root, RelOptInfo *rel) set_baserel_size_estimates(root, rel); } +/* + * set_result_size_estimates + * Set the size estimates for an RTE_RESULT base relation + * + * The rel's targetlist and restrictinfo list must have been constructed + * already. + * + * We set the same fields as set_baserel_size_estimates. + */ +void +set_result_size_estimates(PlannerInfo *root, RelOptInfo *rel) +{ + /* Should only be applied to RTE_RESULT base relations */ + Assert(rel->relid > 0); + Assert(planner_rt_fetch(rel->relid, root)->rtekind == RTE_RESULT); + + /* RTE_RESULT always generates a single row, natively */ + rel->tuples = 1; + + /* Now estimate number of output rows, etc */ + set_baserel_size_estimates(root, rel); +} + /* * set_foreign_size_estimates * Set the size estimates for a base relation that is a foreign table. diff --git a/src/backend/optimizer/path/equivclass.c b/src/backend/optimizer/path/equivclass.c index 70a925c63a1..ccc07ba9f0d 100644 --- a/src/backend/optimizer/path/equivclass.c +++ b/src/backend/optimizer/path/equivclass.c @@ -6,7 +6,7 @@ * See src/backend/optimizer/README for discussion of EquivalenceClasses. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,48 +22,52 @@ #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" -#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" #include "utils/lsyscache.h" static EquivalenceMember *add_eq_member(EquivalenceClass *ec, - Expr *expr, Relids relids, Relids nullable_relids, - bool is_child, Oid datatype); + Expr *expr, Relids relids, Relids nullable_relids, + bool is_child, Oid datatype); static void generate_base_implied_equalities_const(PlannerInfo *root, - EquivalenceClass *ec); + EquivalenceClass *ec); static void generate_base_implied_equalities_no_const(PlannerInfo *root, - EquivalenceClass *ec); + EquivalenceClass *ec); static void generate_base_implied_equalities_broken(PlannerInfo *root, - EquivalenceClass *ec); + EquivalenceClass *ec); static List *generate_join_implied_equalities_normal(PlannerInfo *root, - EquivalenceClass *ec, - Relids join_relids, - Relids outer_relids, - Relids inner_relids); + EquivalenceClass *ec, + Relids join_relids, + Relids outer_relids, + Relids inner_relids); static List *generate_join_implied_equalities_broken(PlannerInfo *root, - EquivalenceClass *ec, - Relids nominal_join_relids, - Relids outer_relids, - Relids nominal_inner_relids, - RelOptInfo *inner_rel); -static Oid select_equality_operator(EquivalenceClass *ec, - Oid lefttype, Oid righttype); + EquivalenceClass *ec, + Relids nominal_join_relids, + Relids outer_relids, + Relids nominal_inner_relids, + RelOptInfo *inner_rel); +static Oid select_equality_operator(EquivalenceClass *ec, + Oid lefttype, Oid righttype); static RestrictInfo *create_join_clause(PlannerInfo *root, - EquivalenceClass *ec, Oid opno, - EquivalenceMember *leftem, - EquivalenceMember *rightem, - EquivalenceClass *parent_ec); + EquivalenceClass *ec, Oid opno, + EquivalenceMember *leftem, + EquivalenceMember *rightem, + EquivalenceClass *parent_ec); static bool reconsider_outer_join_clause(PlannerInfo *root, - RestrictInfo *rinfo, - bool outer_on_left); + RestrictInfo *rinfo, + bool outer_on_left); static bool reconsider_full_join_clause(PlannerInfo *root, - RestrictInfo *rinfo); + RestrictInfo *rinfo); +static Bitmapset *get_eclass_indexes_for_relids(PlannerInfo *root, + Relids relids); +static Bitmapset *get_common_eclass_indexes(PlannerInfo *root, Relids relids1, + Relids relids2); /* @@ -341,10 +345,11 @@ process_equivalence(PlannerInfo *root, /* * Case 2: need to merge ec1 and ec2. This should never happen after - * we've built any canonical pathkeys; if it did, those pathkeys might - * be rendered non-canonical by the merge. + * the ECs have reached canonical state; otherwise, pathkeys could be + * rendered non-canonical by the merge, and relation eclass indexes + * would get broken by removal of an eq_classes list entry. */ - if (root->canon_pathkeys != NIL) + if (root->ec_merging_done) elog(ERROR, "too late to merge equivalence classes"); /* @@ -497,8 +502,9 @@ canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation) /* * For a polymorphic-input-type opclass, just keep the same exposed type. + * RECORD opclasses work like polymorphic-type ones for this purpose. */ - if (IsPolymorphicType(req_type)) + if (IsPolymorphicType(req_type) || req_type == RECORDOID) req_type = expr_type; /* @@ -742,6 +748,27 @@ get_eclass_for_sort_expr(PlannerInfo *root, root->eq_classes = lappend(root->eq_classes, newec); + /* + * If EC merging is already complete, we have to mop up by adding the new + * EC to the eclass_indexes of the relation(s) mentioned in it. + */ + if (root->ec_merging_done) + { + int ec_index = list_length(root->eq_classes) - 1; + int i = -1; + + while ((i = bms_next_member(newec->ec_relids, i)) > 0) + { + RelOptInfo *rel = root->simple_rel_array[i]; + + Assert(rel->reloptkind == RELOPT_BASEREL || + rel->reloptkind == RELOPT_DEADREL); + + rel->eclass_indexes = bms_add_member(rel->eclass_indexes, + ec_index); + } + } + MemoryContextSwitchTo(oldcontext); return newec; @@ -799,42 +826,71 @@ get_eclass_for_sort_expr(PlannerInfo *root, void generate_base_implied_equalities(PlannerInfo *root) { + int ec_index; ListCell *lc; - Index rti; + /* + * At this point, we're done absorbing knowledge of equivalences in the + * query, so no further EC merging should happen, and ECs remaining in the + * eq_classes list can be considered canonical. (But note that it's still + * possible for new single-member ECs to be added through + * get_eclass_for_sort_expr().) + */ + root->ec_merging_done = true; + + ec_index = 0; foreach(lc, root->eq_classes) { EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc); + bool can_generate_joinclause = false; + int i; Assert(ec->ec_merged == NULL); /* else shouldn't be in list */ Assert(!ec->ec_broken); /* not yet anyway... */ - /* Single-member ECs won't generate any deductions */ - if (list_length(ec->ec_members) <= 1) - continue; + /* + * Generate implied equalities that are restriction clauses. + * Single-member ECs won't generate any deductions, either here or at + * the join level. + */ + if (list_length(ec->ec_members) > 1) + { + if (ec->ec_has_const) + generate_base_implied_equalities_const(root, ec); + else + generate_base_implied_equalities_no_const(root, ec); - if (ec->ec_has_const) - generate_base_implied_equalities_const(root, ec); - else - generate_base_implied_equalities_no_const(root, ec); + /* Recover if we failed to generate required derived clauses */ + if (ec->ec_broken) + generate_base_implied_equalities_broken(root, ec); - /* Recover if we failed to generate required derived clauses */ - if (ec->ec_broken) - generate_base_implied_equalities_broken(root, ec); - } + /* Detect whether this EC might generate join clauses */ + can_generate_joinclause = + (bms_membership(ec->ec_relids) == BMS_MULTIPLE); + } - /* - * This is also a handy place to mark base rels (which should all exist by - * now) with flags showing whether they have pending eclass joins. - */ - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; + /* + * Mark the base rels cited in each eclass (which should all exist by + * now) with the eq_classes indexes of all eclasses mentioning them. + * This will let us avoid searching in subsequent lookups. While + * we're at it, we can mark base rels that have pending eclass joins; + * this is a cheap version of has_relevant_eclass_joinclause(). + */ + i = -1; + while ((i = bms_next_member(ec->ec_relids, i)) > 0) + { + RelOptInfo *rel = root->simple_rel_array[i]; - if (brel == NULL) - continue; + Assert(rel->reloptkind == RELOPT_BASEREL); - brel->has_eclass_joins = has_relevant_eclass_joinclause(root, brel); + rel->eclass_indexes = bms_add_member(rel->eclass_indexes, + ec_index); + + if (can_generate_joinclause) + rel->has_eclass_joins = true; + } + + ec_index++; } } @@ -928,11 +984,10 @@ generate_base_implied_equalities_no_const(PlannerInfo *root, /* * We scan the EC members once and track the last-seen member for each * base relation. When we see another member of the same base relation, - * we generate "prev_mem = cur_mem". This results in the minimum number - * of derived clauses, but it's possible that it will fail when a - * different ordering would succeed. XXX FIXME: use a UNION-FIND - * algorithm similar to the way we build merged ECs. (Use a list-of-lists - * for each rel.) + * we generate "prev_em = cur_em". This results in the minimum number of + * derived clauses, but it's possible that it will fail when a different + * ordering would succeed. XXX FIXME: use a UNION-FIND algorithm similar + * to the way we build merged ECs. (Use a list-of-lists for each rel.) */ prev_ems = (EquivalenceMember **) palloc0(root->simple_rel_array_size * sizeof(EquivalenceMember *)); @@ -1073,11 +1128,72 @@ generate_join_implied_equalities(PlannerInfo *root, Relids outer_relids, RelOptInfo *inner_rel) { - return generate_join_implied_equalities_for_ecs(root, - root->eq_classes, - join_relids, - outer_relids, - inner_rel); + List *result = NIL; + Relids inner_relids = inner_rel->relids; + Relids nominal_inner_relids; + Relids nominal_join_relids; + Bitmapset * matching_ecs; + int i; + + /* If inner rel is a child, extra setup work is needed */ + if (IS_OTHER_REL(inner_rel)) + { + Assert(!bms_is_empty(inner_rel->top_parent_relids)); + + /* Fetch relid set for the topmost parent rel */ + nominal_inner_relids = inner_rel->top_parent_relids; + /* ECs will be marked with the parent's relid, not the child's */ + nominal_join_relids = bms_union(outer_relids, nominal_inner_relids); + } + else + { + nominal_inner_relids = inner_relids; + nominal_join_relids = join_relids; + } + + /* + * Get all eclasses in common between inner_rel's relids and outer_relids + */ + matching_ecs = get_common_eclass_indexes(root, inner_rel->relids, + outer_relids); + + i = -1; + while ((i = bms_next_member(matching_ecs, i)) >= 0) + { + EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, i); + List *sublist = NIL; + + /* ECs containing consts do not need any further enforcement */ + if (ec->ec_has_const) + continue; + + /* Single-member ECs won't generate any deductions */ + if (list_length(ec->ec_members) <= 1) + continue; + + /* Sanity check that this eclass overlaps the join */ + Assert(bms_overlap(ec->ec_relids, nominal_join_relids)); + + if (!ec->ec_broken) + sublist = generate_join_implied_equalities_normal(root, + ec, + join_relids, + outer_relids, + inner_relids); + + /* Recover if we failed to generate required derived clauses */ + if (ec->ec_broken) + sublist = generate_join_implied_equalities_broken(root, + ec, + nominal_join_relids, + outer_relids, + nominal_inner_relids, + inner_rel); + + result = list_concat(result, sublist); + } + + return result; } /* @@ -1573,8 +1689,6 @@ reconsider_outer_join_clauses(PlannerInfo *root) { bool found; ListCell *cell; - ListCell *prev; - ListCell *next; /* Outer loop repeats until we find no more deductions */ do @@ -1582,72 +1696,60 @@ reconsider_outer_join_clauses(PlannerInfo *root) found = false; /* Process the LEFT JOIN clauses */ - prev = NULL; - for (cell = list_head(root->left_join_clauses); cell; cell = next) + foreach(cell, root->left_join_clauses) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(cell); - next = lnext(cell); if (reconsider_outer_join_clause(root, rinfo, true)) { found = true; /* remove it from the list */ root->left_join_clauses = - list_delete_cell(root->left_join_clauses, cell, prev); + foreach_delete_current(root->left_join_clauses, cell); /* we throw it back anyway (see notes above) */ /* but the thrown-back clause has no extra selectivity */ rinfo->norm_selec = 2.0; rinfo->outer_selec = 1.0; distribute_restrictinfo_to_rels(root, rinfo); } - else - prev = cell; } /* Process the RIGHT JOIN clauses */ - prev = NULL; - for (cell = list_head(root->right_join_clauses); cell; cell = next) + foreach(cell, root->right_join_clauses) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(cell); - next = lnext(cell); if (reconsider_outer_join_clause(root, rinfo, false)) { found = true; /* remove it from the list */ root->right_join_clauses = - list_delete_cell(root->right_join_clauses, cell, prev); + foreach_delete_current(root->right_join_clauses, cell); /* we throw it back anyway (see notes above) */ /* but the thrown-back clause has no extra selectivity */ rinfo->norm_selec = 2.0; rinfo->outer_selec = 1.0; distribute_restrictinfo_to_rels(root, rinfo); } - else - prev = cell; } /* Process the FULL JOIN clauses */ - prev = NULL; - for (cell = list_head(root->full_join_clauses); cell; cell = next) + foreach(cell, root->full_join_clauses) { RestrictInfo *rinfo = (RestrictInfo *) lfirst(cell); - next = lnext(cell); if (reconsider_full_join_clause(root, rinfo)) { found = true; /* remove it from the list */ root->full_join_clauses = - list_delete_cell(root->full_join_clauses, cell, prev); + foreach_delete_current(root->full_join_clauses, cell); /* we throw it back anyway (see notes above) */ /* but the thrown-back clause has no extra selectivity */ rinfo->norm_selec = 2.0; rinfo->outer_selec = 1.0; distribute_restrictinfo_to_rels(root, rinfo); } - else - prev = cell; } } while (found); @@ -2036,12 +2138,24 @@ match_eclasses_to_foreign_key_col(PlannerInfo *root, Index var2varno = fkinfo->ref_relid; AttrNumber var2attno = fkinfo->confkey[colno]; Oid eqop = fkinfo->conpfeqop[colno]; + RelOptInfo *rel1 = root->simple_rel_array[var1varno]; + RelOptInfo *rel2 = root->simple_rel_array[var2varno]; List *opfamilies = NIL; /* compute only if needed */ - ListCell *lc1; - - foreach(lc1, root->eq_classes) + Bitmapset *matching_ecs; + int i; + + /* Consider only eclasses mentioning both relations */ + Assert(root->ec_merging_done); + Assert(IS_SIMPLE_REL(rel1)); + Assert(IS_SIMPLE_REL(rel2)); + matching_ecs = bms_intersect(rel1->eclass_indexes, + rel2->eclass_indexes); + + i = -1; + while ((i = bms_next_member(matching_ecs, i)) >= 0) { - EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc1); + EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, + i); bool item1member = false; bool item2member = false; ListCell *lc2; @@ -2110,12 +2224,20 @@ add_child_rel_equivalences(PlannerInfo *root, RelOptInfo *parent_rel, RelOptInfo *child_rel) { - ListCell *lc1; + int i; - foreach(lc1, root->eq_classes) + /* + * EC merging should be complete already, so we can use the parent rel's + * eclass_indexes to avoid searching all of root->eq_classes. + */ + Assert(root->ec_merging_done); + Assert(IS_SIMPLE_REL(parent_rel)); + + i = -1; + while ((i = bms_next_member(parent_rel->eclass_indexes, i)) >= 0) { - EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1); - ListCell *lc2; + EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i); + int num_members; /* * If this EC contains a volatile expression, then generating child @@ -2125,33 +2247,57 @@ add_child_rel_equivalences(PlannerInfo *root, if (cur_ec->ec_has_volatile) continue; + /* Sanity check eclass_indexes only contain ECs for parent_rel */ + Assert(bms_is_subset(child_rel->top_parent_relids, cur_ec->ec_relids)); + /* - * No point in searching if parent rel not mentioned in eclass; but we - * can't tell that for sure if parent rel is itself a child. + * We don't use foreach() here because there's no point in scanning + * newly-added child members, so we can stop after the last + * pre-existing EC member. */ - if (parent_rel->reloptkind == RELOPT_BASEREL && - !bms_is_subset(parent_rel->relids, cur_ec->ec_relids)) - continue; - - foreach(lc2, cur_ec->ec_members) + num_members = list_length(cur_ec->ec_members); + for (int pos = 0; pos < num_members; pos++) { - EquivalenceMember *cur_em = (EquivalenceMember *) lfirst(lc2); + EquivalenceMember *cur_em = (EquivalenceMember *) list_nth(cur_ec->ec_members, pos); if (cur_em->em_is_const) continue; /* ignore consts here */ - /* Does it reference parent_rel? */ - if (bms_overlap(cur_em->em_relids, parent_rel->relids)) + /* + * We consider only original EC members here, not + * already-transformed child members. Otherwise, if some original + * member expression references more than one appendrel, we'd get + * an O(N^2) explosion of useless derived expressions for + * combinations of children. + */ + if (cur_em->em_is_child) + continue; /* ignore children here */ + + /* Does this member reference child's topmost parent rel? */ + if (bms_overlap(cur_em->em_relids, child_rel->top_parent_relids)) { /* Yes, generate transformed child version */ Expr *child_expr; Relids new_relids; Relids new_nullable_relids; - child_expr = (Expr *) - adjust_appendrel_attrs(root, - (Node *) cur_em->em_expr, - 1, &appinfo); + if (parent_rel->reloptkind == RELOPT_BASEREL) + { + /* Simple single-level transformation */ + child_expr = (Expr *) + adjust_appendrel_attrs(root, + (Node *) cur_em->em_expr, + 1, &appinfo); + } + else + { + /* Must do multi-level transformation */ + child_expr = (Expr *) + adjust_appendrel_attrs_multilevel(root, + (Node *) cur_em->em_expr, + child_rel->relids, + child_rel->top_parent_relids); + } /* * Transform em_relids to match. Note we do *not* do @@ -2160,7 +2306,7 @@ add_child_rel_equivalences(PlannerInfo *root, * don't want the child member to be marked as constant. */ new_relids = bms_difference(cur_em->em_relids, - parent_rel->relids); + child_rel->top_parent_relids); new_relids = bms_add_members(new_relids, child_rel->relids); /* @@ -2168,10 +2314,11 @@ add_child_rel_equivalences(PlannerInfo *root, * parent and child relids are singletons. */ new_nullable_relids = cur_em->em_nullable_relids; - if (bms_overlap(new_nullable_relids, parent_rel->relids)) + if (bms_overlap(new_nullable_relids, + child_rel->top_parent_relids)) { new_nullable_relids = bms_difference(new_nullable_relids, - parent_rel->relids); + child_rel->top_parent_relids); new_nullable_relids = bms_add_members(new_nullable_relids, child_rel->relids); } @@ -2179,6 +2326,9 @@ add_child_rel_equivalences(PlannerInfo *root, (void) add_eq_member(cur_ec, child_expr, new_relids, new_nullable_relids, true, cur_em->em_datatype); + + /* Record this EC index for the child rel */ + child_rel->eclass_indexes = bms_add_member(child_rel->eclass_indexes, i); } } } @@ -2218,7 +2368,10 @@ generate_implied_equalities_for_column(PlannerInfo *root, List *result = NIL; bool is_child_rel = (rel->reloptkind == RELOPT_OTHER_MEMBER_REL); Relids parent_relids; - ListCell *lc1; + int i; + + /* Should be OK to rely on eclass_indexes */ + Assert(root->ec_merging_done); /* Indexes are available only on base or "other" member relations. */ Assert(IS_SIMPLE_REL(rel)); @@ -2229,12 +2382,16 @@ generate_implied_equalities_for_column(PlannerInfo *root, else parent_relids = NULL; /* not used, but keep compiler quiet */ - foreach(lc1, root->eq_classes) + i = -1; + while ((i = bms_next_member(rel->eclass_indexes, i)) >= 0) { - EquivalenceClass *cur_ec = (EquivalenceClass *) lfirst(lc1); + EquivalenceClass *cur_ec = (EquivalenceClass *) list_nth(root->eq_classes, i); EquivalenceMember *cur_em; ListCell *lc2; + /* Sanity check eclass_indexes only contain ECs for rel */ + Assert(is_child_rel || bms_is_subset(rel->relids, cur_ec->ec_relids)); + /* * Won't generate joinclauses if const or single-member (the latter * test covers the volatile case too) @@ -2242,14 +2399,6 @@ generate_implied_equalities_for_column(PlannerInfo *root, if (cur_ec->ec_has_const || list_length(cur_ec->ec_members) <= 1) continue; - /* - * No point in searching if rel not mentioned in eclass (but we can't - * tell that for a child rel). - */ - if (!is_child_rel && - !bms_is_subset(rel->relids, cur_ec->ec_relids)) - continue; - /* * Scan members, looking for a match to the target column. Note that * child EC members are considered, but only when they belong to the @@ -2343,11 +2492,25 @@ bool have_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2) { - ListCell *lc1; + Bitmapset *matching_ecs; + int i; - foreach(lc1, root->eq_classes) + /* Examine only eclasses mentioning both rel1 and rel2 */ + matching_ecs = get_common_eclass_indexes(root, rel1->relids, + rel2->relids); + + i = -1; + while ((i = bms_next_member(matching_ecs, i)) >= 0) { - EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc1); + EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, + i); + + /* + * Sanity check that get_common_eclass_indexes gave only ECs + * containing both rels. + */ + Assert(bms_overlap(rel1->relids, ec->ec_relids)); + Assert(bms_overlap(rel2->relids, ec->ec_relids)); /* * Won't generate joinclauses if single-member (this test covers the @@ -2359,12 +2522,12 @@ have_relevant_eclass_joinclause(PlannerInfo *root, /* * We do not need to examine the individual members of the EC, because * all that we care about is whether each rel overlaps the relids of - * at least one member, and a test on ec_relids is sufficient to prove - * that. (As with have_relevant_joinclause(), it is not necessary - * that the EC be able to form a joinclause relating exactly the two - * given rels, only that it be able to form a joinclause mentioning - * both, and this will surely be true if both of them overlap - * ec_relids.) + * at least one member, and get_common_eclass_indexes() and the single + * member check above are sufficient to prove that. (As with + * have_relevant_joinclause(), it is not necessary that the EC be able + * to form a joinclause relating exactly the two given rels, only that + * it be able to form a joinclause mentioning both, and this will + * surely be true if both of them overlap ec_relids.) * * Note we don't test ec_broken; if we did, we'd need a separate code * path to look through ec_sources. Checking the membership anyway is @@ -2376,9 +2539,8 @@ have_relevant_eclass_joinclause(PlannerInfo *root, * since the join result is likely to be small even though it'll end * up being an unqualified nestloop. */ - if (bms_overlap(rel1->relids, ec->ec_relids) && - bms_overlap(rel2->relids, ec->ec_relids)) - return true; + + return true; } return false; @@ -2396,11 +2558,17 @@ have_relevant_eclass_joinclause(PlannerInfo *root, bool has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1) { - ListCell *lc1; + Bitmapset *matched_ecs; + int i; - foreach(lc1, root->eq_classes) + /* Examine only eclasses mentioning rel1 */ + matched_ecs = get_eclass_indexes_for_relids(root, rel1->relids); + + i = -1; + while ((i = bms_next_member(matched_ecs, i)) >= 0) { - EquivalenceClass *ec = (EquivalenceClass *) lfirst(lc1); + EquivalenceClass *ec = (EquivalenceClass *) list_nth(root->eq_classes, + i); /* * Won't generate joinclauses if single-member (this test covers the @@ -2413,8 +2581,7 @@ has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1) * Per the comment in have_relevant_eclass_joinclause, it's sufficient * to find an EC that mentions both this rel and some other rel. */ - if (bms_overlap(rel1->relids, ec->ec_relids) && - !bms_is_subset(ec->ec_relids, rel1->relids)) + if (!bms_is_subset(ec->ec_relids, rel1->relids)) return true; } @@ -2510,3 +2677,91 @@ is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist) return false; } + +/* + * is_redundant_with_indexclauses + * Test whether rinfo is redundant with any clause in the IndexClause + * list. Here, for convenience, we test both simple identity and + * whether it is derived from the same EC as any member of the list. + */ +bool +is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses) +{ + EquivalenceClass *parent_ec = rinfo->parent_ec; + ListCell *lc; + + foreach(lc, indexclauses) + { + IndexClause *iclause = lfirst_node(IndexClause, lc); + RestrictInfo *otherrinfo = iclause->rinfo; + + /* If indexclause is lossy, it won't enforce the condition exactly */ + if (iclause->lossy) + continue; + + /* Match if it's same clause (pointer equality should be enough) */ + if (rinfo == otherrinfo) + return true; + /* Match if derived from same EC */ + if (parent_ec && otherrinfo->parent_ec == parent_ec) + return true; + + /* + * No need to look at the derived clauses in iclause->indexquals; they + * couldn't match if the parent clause didn't. + */ + } + + return false; +} + +/* + * get_eclass_indexes_for_relids + * Build and return a Bitmapset containing the indexes into root's + * eq_classes list for all eclasses that mention any of these relids + */ +static Bitmapset * +get_eclass_indexes_for_relids(PlannerInfo *root, Relids relids) +{ + Bitmapset *ec_indexes = NULL; + int i = -1; + + /* Should be OK to rely on eclass_indexes */ + Assert(root->ec_merging_done); + + while ((i = bms_next_member(relids, i)) > 0) + { + RelOptInfo *rel = root->simple_rel_array[i]; + + ec_indexes = bms_add_members(ec_indexes, rel->eclass_indexes); + } + return ec_indexes; +} + +/* + * get_common_eclass_indexes + * Build and return a Bitmapset containing the indexes into root's + * eq_classes list for all eclasses that mention rels in both + * relids1 and relids2. + */ +static Bitmapset * +get_common_eclass_indexes(PlannerInfo *root, Relids relids1, Relids relids2) +{ + Bitmapset *rel1ecs; + Bitmapset *rel2ecs; + int relid; + + rel1ecs = get_eclass_indexes_for_relids(root, relids1); + + /* + * We can get away with just using the relation's eclass_indexes directly + * when relids2 is a singleton set. + */ + if (bms_get_singleton_member(relids2, &relid)) + rel2ecs = root->simple_rel_array[relid]->eclass_indexes; + else + rel2ecs = get_eclass_indexes_for_relids(root, relids2); + + /* Calculate and return the common EC indexes, recycling the left input. */ + return bms_int_members(rel1ecs, rel2ecs); +} diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index bf42b54970c..37b257cd0e9 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -4,7 +4,7 @@ * Routines to determine which indexes are usable for scanning a * given relation, and create Paths accordingly. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,23 +20,19 @@ #include "access/stratnum.h" #include "access/sysattr.h" #include "catalog/pg_am.h" -#include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "catalog/pg_opfamily.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" -#include "optimizer/clauses.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" -#include "optimizer/predtest.h" #include "optimizer/prep.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" -#include "utils/builtins.h" -#include "utils/bytea.h" #include "utils/lsyscache.h" -#include "utils/pg_locale.h" #include "utils/selfuncs.h" @@ -56,7 +52,7 @@ typedef enum typedef struct { bool nonempty; /* True if lists are not all empty */ - /* Lists of RestrictInfos, one per index column */ + /* Lists of IndexClause nodes, one list per index column */ List *indexclauses[INDEX_MAX_KEYS]; } IndexClauseSet; @@ -67,6 +63,7 @@ typedef struct List *quals; /* the WHERE clauses it uses */ List *preds; /* predicates of its partial index(es) */ Bitmapset *clauseids; /* quals+preds represented as a bitmapset */ + bool unclassifiable; /* has too many quals+preds to process? */ } PathClauseUsage; /* Callback argument for ec_member_matches_indexcol */ @@ -78,115 +75,120 @@ typedef struct static void consider_index_join_clauses(PlannerInfo *root, RelOptInfo *rel, - IndexOptInfo *index, - IndexClauseSet *rclauseset, - IndexClauseSet *jclauseset, - IndexClauseSet *eclauseset, - List **bitindexpaths); + IndexOptInfo *index, + IndexClauseSet *rclauseset, + IndexClauseSet *jclauseset, + IndexClauseSet *eclauseset, + List **bitindexpaths); static void consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel, - IndexOptInfo *index, - IndexClauseSet *rclauseset, - IndexClauseSet *jclauseset, - IndexClauseSet *eclauseset, - List **bitindexpaths, - List *indexjoinclauses, - int considered_clauses, - List **considered_relids); + IndexOptInfo *index, + IndexClauseSet *rclauseset, + IndexClauseSet *jclauseset, + IndexClauseSet *eclauseset, + List **bitindexpaths, + List *indexjoinclauses, + int considered_clauses, + List **considered_relids); static void get_join_index_paths(PlannerInfo *root, RelOptInfo *rel, - IndexOptInfo *index, - IndexClauseSet *rclauseset, - IndexClauseSet *jclauseset, - IndexClauseSet *eclauseset, - List **bitindexpaths, - Relids relids, - List **considered_relids); + IndexOptInfo *index, + IndexClauseSet *rclauseset, + IndexClauseSet *jclauseset, + IndexClauseSet *eclauseset, + List **bitindexpaths, + Relids relids, + List **considered_relids); static bool eclass_already_used(EquivalenceClass *parent_ec, Relids oldrelids, - List *indexjoinclauses); + List *indexjoinclauses); static bool bms_equal_any(Relids relids, List *relids_list); static void get_index_paths(PlannerInfo *root, RelOptInfo *rel, - IndexOptInfo *index, IndexClauseSet *clauses, - List **bitindexpaths); + IndexOptInfo *index, IndexClauseSet *clauses, + List **bitindexpaths); static List *build_index_paths(PlannerInfo *root, RelOptInfo *rel, - IndexOptInfo *index, IndexClauseSet *clauses, - bool useful_predicate, - ScanTypeControl scantype, - bool *skip_nonnative_saop, - bool *skip_lower_saop); + IndexOptInfo *index, IndexClauseSet *clauses, + bool useful_predicate, + ScanTypeControl scantype, + bool *skip_nonnative_saop, + bool *skip_lower_saop); static List *build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel, - List *clauses, List *other_clauses); + List *clauses, List *other_clauses); static List *generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, - List *clauses, List *other_clauses); + List *clauses, List *other_clauses); static Path *choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, - List *paths); + List *paths); static int path_usage_comparator(const void *a, const void *b); static Cost bitmap_scan_cost_est(PlannerInfo *root, RelOptInfo *rel, - Path *ipath); + Path *ipath); static Cost bitmap_and_cost_est(PlannerInfo *root, RelOptInfo *rel, - List *paths); + List *paths); static PathClauseUsage *classify_index_clause_usage(Path *path, - List **clauselist); + List **clauselist); static Relids get_bitmap_tree_required_outer(Path *bitmapqual); static void find_indexpath_quals(Path *bitmapqual, List **quals, List **preds); static int find_list_position(Node *node, List **nodelist); static bool check_index_only(RelOptInfo *rel, IndexOptInfo *index); static double get_loop_count(PlannerInfo *root, Index cur_relid, Relids outer_relids); static double adjust_rowcount_for_semijoins(PlannerInfo *root, - Index cur_relid, - Index outer_relid, - double rowcount); + Index cur_relid, + Index outer_relid, + double rowcount); static double approximate_joinrel_size(PlannerInfo *root, Relids relids); -static void match_restriction_clauses_to_index(RelOptInfo *rel, - IndexOptInfo *index, - IndexClauseSet *clauseset); +static void match_restriction_clauses_to_index(PlannerInfo *root, + IndexOptInfo *index, + IndexClauseSet *clauseset); static void match_join_clauses_to_index(PlannerInfo *root, - RelOptInfo *rel, IndexOptInfo *index, - IndexClauseSet *clauseset, - List **joinorclauses); + RelOptInfo *rel, IndexOptInfo *index, + IndexClauseSet *clauseset, + List **joinorclauses); static void match_eclass_clauses_to_index(PlannerInfo *root, - IndexOptInfo *index, - IndexClauseSet *clauseset); -static void match_clauses_to_index(IndexOptInfo *index, - List *clauses, - IndexClauseSet *clauseset); -static void match_clause_to_index(IndexOptInfo *index, - RestrictInfo *rinfo, - IndexClauseSet *clauseset); -static bool match_clause_to_indexcol(IndexOptInfo *index, - int indexcol, - RestrictInfo *rinfo); -static bool is_indexable_operator(Oid expr_op, Oid opfamily, - bool indexkey_on_left); -static bool match_rowcompare_to_indexcol(IndexOptInfo *index, - int indexcol, - Oid opfamily, - Oid idxcollation, - RowCompareExpr *clause); + IndexOptInfo *index, + IndexClauseSet *clauseset); +static void match_clauses_to_index(PlannerInfo *root, + List *clauses, + IndexOptInfo *index, + IndexClauseSet *clauseset); +static void match_clause_to_index(PlannerInfo *root, + RestrictInfo *rinfo, + IndexOptInfo *index, + IndexClauseSet *clauseset); +static IndexClause *match_clause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index); +static IndexClause *match_boolean_index_clause(RestrictInfo *rinfo, + int indexcol, IndexOptInfo *index); +static IndexClause *match_opclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index); +static IndexClause *match_funcclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index); +static IndexClause *get_index_clause_from_support(PlannerInfo *root, + RestrictInfo *rinfo, + Oid funcid, + int indexarg, + int indexcol, + IndexOptInfo *index); +static IndexClause *match_saopclause_to_indexcol(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index); +static IndexClause *match_rowcompare_to_indexcol(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index); +static IndexClause *expand_indexqual_rowcompare(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index, + Oid expr_op, + bool var_on_left); static void match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys, - List **orderby_clauses_p, - List **clause_columns_p); + List **orderby_clauses_p, + List **clause_columns_p); static Expr *match_clause_to_ordering_op(IndexOptInfo *index, - int indexcol, Expr *clause, Oid pk_opfamily); + int indexcol, Expr *clause, Oid pk_opfamily); static bool ec_member_matches_indexcol(PlannerInfo *root, RelOptInfo *rel, - EquivalenceClass *ec, EquivalenceMember *em, - void *arg); -static bool match_boolean_index_clause(Node *clause, int indexcol, - IndexOptInfo *index); -static bool match_special_index_operator(Expr *clause, - Oid opfamily, Oid idxcollation, - bool indexkey_on_left); -static Expr *expand_boolean_index_clause(Node *clause, int indexcol, - IndexOptInfo *index); -static List *expand_indexqual_opclause(RestrictInfo *rinfo, - Oid opfamily, Oid idxcollation); -static RestrictInfo *expand_indexqual_rowcompare(RestrictInfo *rinfo, - IndexOptInfo *index, - int indexcol); -static List *prefix_quals(Node *leftop, Oid opfamily, Oid collation, - Const *prefix, Pattern_Prefix_Status pstatus); -static List *network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, - Datum rightop); -static Datum string_to_datum(const char *str, Oid datatype); -static Const *string_to_const(const char *str, Oid datatype); + EquivalenceClass *ec, EquivalenceMember *em, + void *arg); /* @@ -251,7 +253,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) IndexOptInfo *index = (IndexOptInfo *) lfirst(lc); /* Protect limited-size array in IndexClauseSets */ - Assert(index->ncolumns <= INDEX_MAX_KEYS); + Assert(index->nkeycolumns <= INDEX_MAX_KEYS); /* * Ignore partial indexes that do not match the query. @@ -265,7 +267,7 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel) * Identify the restriction clauses that can match the index. */ MemSet(&rclauseset, 0, sizeof(rclauseset)); - match_restriction_clauses_to_index(rel, index, &rclauseset); + match_restriction_clauses_to_index(root, index, &rclauseset); /* * Build index paths from the restriction clauses. These will be @@ -466,7 +468,7 @@ consider_index_join_clauses(PlannerInfo *root, RelOptInfo *rel, * relation itself is also included in the relids set. considered_relids * lists all relids sets we've already tried. */ - for (indexcol = 0; indexcol < index->ncolumns; indexcol++) + for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++) { /* Consider each applicable simple join clause */ considered_clauses += list_length(jclauseset->indexclauses[indexcol]); @@ -495,7 +497,7 @@ consider_index_join_clauses(PlannerInfo *root, RelOptInfo *rel, * * 'rel', 'index', 'rclauseset', 'jclauseset', 'eclauseset', and * 'bitindexpaths' as above - * 'indexjoinclauses' is a list of RestrictInfos for join clauses + * 'indexjoinclauses' is a list of IndexClauses for join clauses * 'considered_clauses' is the total number of clauses considered (so far) * '*considered_relids' is a list of all relids sets already considered */ @@ -515,9 +517,10 @@ consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel, /* Examine relids of each joinclause in the given list */ foreach(lc, indexjoinclauses) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); - Relids clause_relids = rinfo->clause_relids; - ListCell *lc2; + IndexClause *iclause = (IndexClause *) lfirst(lc); + Relids clause_relids = iclause->rinfo->clause_relids; + EquivalenceClass *parent_ec = iclause->rinfo->parent_ec; + int num_considered_relids; /* If we already tried its relids set, no need to do so again */ if (bms_equal_any(clause_relids, *considered_relids)) @@ -530,15 +533,16 @@ consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel, * exponential growth of planning time when there are many clauses, * limit the number of relid sets accepted to 10 * considered_clauses. * - * Note: get_join_index_paths adds entries to *considered_relids, but - * it prepends them to the list, so that we won't visit new entries - * during the inner foreach loop. No real harm would be done if we - * did, since the subset check would reject them; but it would waste - * some cycles. + * Note: get_join_index_paths appends entries to *considered_relids, + * but we do not need to visit such newly-added entries within this + * loop, so we don't use foreach() here. No real harm would be done + * if we did visit them, since the subset check would reject them; but + * it would waste some cycles. */ - foreach(lc2, *considered_relids) + num_considered_relids = list_length(*considered_relids); + for (int pos = 0; pos < num_considered_relids; pos++) { - Relids oldrelids = (Relids) lfirst(lc2); + Relids oldrelids = (Relids) list_nth(*considered_relids, pos); /* * If either is a subset of the other, no new set is possible. @@ -557,8 +561,8 @@ consider_index_join_outer_rels(PlannerInfo *root, RelOptInfo *rel, * parameterization; so skip if any clause derived from the same * eclass would already have been included when using oldrelids. */ - if (rinfo->parent_ec && - eclass_already_used(rinfo->parent_ec, oldrelids, + if (parent_ec && + eclass_already_used(parent_ec, oldrelids, indexjoinclauses)) continue; @@ -620,18 +624,18 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel, /* Identify indexclauses usable with this relids set */ MemSet(&clauseset, 0, sizeof(clauseset)); - for (indexcol = 0; indexcol < index->ncolumns; indexcol++) + for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++) { ListCell *lc; /* First find applicable simple join clauses */ foreach(lc, jclauseset->indexclauses[indexcol]) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + IndexClause *iclause = (IndexClause *) lfirst(lc); - if (bms_is_subset(rinfo->clause_relids, relids)) + if (bms_is_subset(iclause->rinfo->clause_relids, relids)) clauseset.indexclauses[indexcol] = - lappend(clauseset.indexclauses[indexcol], rinfo); + lappend(clauseset.indexclauses[indexcol], iclause); } /* @@ -642,17 +646,17 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel, */ foreach(lc, eclauseset->indexclauses[indexcol]) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + IndexClause *iclause = (IndexClause *) lfirst(lc); - if (bms_is_subset(rinfo->clause_relids, relids)) + if (bms_is_subset(iclause->rinfo->clause_relids, relids)) { clauseset.indexclauses[indexcol] = - lappend(clauseset.indexclauses[indexcol], rinfo); + lappend(clauseset.indexclauses[indexcol], iclause); break; } } - /* Add restriction clauses (this is nondestructive to rclauseset) */ + /* Add restriction clauses */ clauseset.indexclauses[indexcol] = list_concat(clauseset.indexclauses[indexcol], rclauseset->indexclauses[indexcol]); @@ -668,10 +672,9 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel, get_index_paths(root, rel, index, &clauseset, bitindexpaths); /* - * Remember we considered paths for this set of relids. We use lcons not - * lappend to avoid confusing the loop in consider_index_join_outer_rels. + * Remember we considered paths for this set of relids. */ - *considered_relids = lcons(relids, *considered_relids); + *considered_relids = lappend(*considered_relids, relids); } /* @@ -687,7 +690,8 @@ eclass_already_used(EquivalenceClass *parent_ec, Relids oldrelids, foreach(lc, indexjoinclauses) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + IndexClause *iclause = (IndexClause *) lfirst(lc); + RestrictInfo *rinfo = iclause->rinfo; if (rinfo->parent_ec == parent_ec && bms_is_subset(rinfo->clause_relids, oldrelids)) @@ -847,7 +851,7 @@ get_index_paths(PlannerInfo *root, RelOptInfo *rel, * * 'rel' is the index's heap relation * 'index' is the index for which we want to generate paths - * 'clauses' is the collection of indexable clauses (RestrictInfo nodes) + * 'clauses' is the collection of indexable clauses (IndexClause nodes) * 'useful_predicate' indicates whether the index has a useful predicate * 'scantype' indicates whether we need plain or bitmap scan support * 'skip_nonnative_saop' indicates whether to accept SAOP if index AM doesn't @@ -864,7 +868,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, List *result = NIL; IndexPath *ipath; List *index_clauses; - List *clause_columns; Relids outer_relids; double loop_count; List *orderbyclauses; @@ -896,14 +899,12 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, } /* - * 1. Collect the index clauses into a single list. + * 1. Combine the per-column IndexClause lists into an overall list. * - * We build a list of RestrictInfo nodes for clauses to be used with this - * index, along with an integer list of the index column numbers (zero - * based) that each clause should be used with. The clauses are ordered - * by index key, so that the column numbers form a nondecreasing sequence. - * (This order is depended on by btree and possibly other places.) The - * lists can be empty, if the index AM allows that. + * In the resulting list, clauses are ordered by index key, so that the + * column numbers form a nondecreasing sequence. (This order is depended + * on by btree and possibly other places.) The list can be empty, if the + * index AM allows that. * * found_lower_saop_clause is set true if we accept a ScalarArrayOpExpr * index clause for a non-first index column. This prevents us from @@ -917,17 +918,18 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, * otherwise accounted for. */ index_clauses = NIL; - clause_columns = NIL; found_lower_saop_clause = false; outer_relids = bms_copy(rel->lateral_relids); - for (indexcol = 0; indexcol < index->ncolumns; indexcol++) + for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++) { ListCell *lc; foreach(lc, clauses->indexclauses[indexcol]) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + IndexClause *iclause = (IndexClause *) lfirst(lc); + RestrictInfo *rinfo = iclause->rinfo; + /* We might need to omit ScalarArrayOpExpr clauses */ if (IsA(rinfo->clause, ScalarArrayOpExpr)) { if (!index->amsearcharray) @@ -952,8 +954,9 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, found_lower_saop_clause = true; } } - index_clauses = lappend(index_clauses, rinfo); - clause_columns = lappend_int(clause_columns, indexcol); + + /* OK to include this clause */ + index_clauses = lappend(index_clauses, iclause); outer_relids = bms_add_members(outer_relids, rinfo->clause_relids); } @@ -1035,7 +1038,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, { ipath = create_index_path(root, index, index_clauses, - clause_columns, orderbyclauses, orderbyclausecols, useful_pathkeys, @@ -1058,7 +1060,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, { ipath = create_index_path(root, index, index_clauses, - clause_columns, orderbyclauses, orderbyclausecols, useful_pathkeys, @@ -1094,7 +1095,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, { ipath = create_index_path(root, index, index_clauses, - clause_columns, NIL, NIL, useful_pathkeys, @@ -1112,7 +1112,6 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel, { ipath = create_index_path(root, index, index_clauses, - clause_columns, NIL, NIL, useful_pathkeys, @@ -1205,8 +1204,7 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel, { /* Form all_clauses if not done already */ if (all_clauses == NIL) - all_clauses = list_concat(list_copy(clauses), - other_clauses); + all_clauses = list_concat_copy(clauses, other_clauses); if (!predicate_implied_by(index->indpred, all_clauses, false)) continue; /* can't use it at all */ @@ -1220,7 +1218,7 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel, * Identify the restriction clauses that can match the index. */ MemSet(&clauseset, 0, sizeof(clauseset)); - match_clauses_to_index(index, clauses, &clauseset); + match_clauses_to_index(root, clauses, index, &clauseset); /* * If no matches so far, and the index predicate isn't useful, we @@ -1232,7 +1230,7 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel, /* * Add "other" restriction clauses to the clauseset. */ - match_clauses_to_index(index, other_clauses, &clauseset); + match_clauses_to_index(root, other_clauses, index, &clauseset); /* * Construct paths if possible. @@ -1271,7 +1269,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, * We can use both the current and other clauses as context for * build_paths_for_OR; no need to remove ORs from the lists. */ - all_clauses = list_concat(list_copy(clauses), other_clauses); + all_clauses = list_concat_copy(clauses, other_clauses); foreach(lc, clauses) { @@ -1295,7 +1293,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, List *indlist; /* OR arguments should be ANDs or sub-RestrictInfos */ - if (and_clause(orarg)) + if (is_andclause(orarg)) { List *andargs = ((BoolExpr *) orarg)->args; @@ -1447,9 +1445,18 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) Path *ipath = (Path *) lfirst(l); pathinfo = classify_index_clause_usage(ipath, &clauselist); + + /* If it's unclassifiable, treat it as distinct from all others */ + if (pathinfo->unclassifiable) + { + pathinfoarray[npaths++] = pathinfo; + continue; + } + for (i = 0; i < npaths; i++) { - if (bms_equal(pathinfo->clauseids, pathinfoarray[i]->clauseids)) + if (!pathinfoarray[i]->unclassifiable && + bms_equal(pathinfo->clauseids, pathinfoarray[i]->clauseids)) break; } if (i < npaths) @@ -1484,21 +1491,22 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) * For each surviving index, consider it as an "AND group leader", and see * whether adding on any of the later indexes results in an AND path with * cheaper total cost than before. Then take the cheapest AND group. + * + * Note: paths that are either clauseless or unclassifiable will have + * empty clauseids, so that they will not be rejected by the clauseids + * filter here, nor will they cause later paths to be rejected by it. */ for (i = 0; i < npaths; i++) { Cost costsofar; List *qualsofar; Bitmapset *clauseidsofar; - ListCell *lastcell; pathinfo = pathinfoarray[i]; paths = list_make1(pathinfo->path); costsofar = bitmap_scan_cost_est(root, rel, pathinfo->path); - qualsofar = list_concat(list_copy(pathinfo->quals), - list_copy(pathinfo->preds)); + qualsofar = list_concat_copy(pathinfo->quals, pathinfo->preds); clauseidsofar = bms_copy(pathinfo->clauseids); - lastcell = list_head(paths); /* for quick deletions */ for (j = i + 1; j < npaths; j++) { @@ -1533,20 +1541,16 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) { /* keep new path in paths, update subsidiary variables */ costsofar = newcost; - qualsofar = list_concat(qualsofar, - list_copy(pathinfo->quals)); - qualsofar = list_concat(qualsofar, - list_copy(pathinfo->preds)); + qualsofar = list_concat(qualsofar, pathinfo->quals); + qualsofar = list_concat(qualsofar, pathinfo->preds); clauseidsofar = bms_add_members(clauseidsofar, pathinfo->clauseids); - lastcell = lnext(lastcell); } else { /* reject new path, remove it from paths list */ - paths = list_delete_cell(paths, lnext(lastcell), lastcell); + paths = list_truncate(paths, list_length(paths) - 1); } - Assert(lnext(lastcell) == NULL); } /* Keep the cheapest AND-group (or singleton) */ @@ -1711,6 +1715,21 @@ classify_index_clause_usage(Path *path, List **clauselist) result->preds = NIL; find_indexpath_quals(path, &result->quals, &result->preds); + /* + * Some machine-generated queries have outlandish numbers of qual clauses. + * To avoid getting into O(N^2) behavior even in this preliminary + * classification step, we want to limit the number of entries we can + * accumulate in *clauselist. Treat any path with more than 100 quals + + * preds as unclassifiable, which will cause calling code to consider it + * distinct from all other paths. + */ + if (list_length(result->quals) + list_length(result->preds) > 100) + { + result->clauseids = NULL; + result->unclassifiable = true; + return result; + } + /* Build up a bitmapset representing the quals and preds */ clauseids = NULL; foreach(lc, result->quals) @@ -1728,6 +1747,7 @@ classify_index_clause_usage(Path *path, List **clauselist) find_list_position(node, clauselist)); } result->clauseids = clauseids; + result->unclassifiable = false; return result; } @@ -1780,7 +1800,7 @@ get_bitmap_tree_required_outer(Path *bitmapqual) * find_indexpath_quals * * Given the Path structure for a plain or bitmap indexscan, extract lists - * of all the indexquals and index predicate conditions used in the Path. + * of all the index clauses and index predicate conditions used in the Path. * These are appended to the initial contents of *quals and *preds (hence * caller should initialize those to NIL). * @@ -1817,9 +1837,15 @@ find_indexpath_quals(Path *bitmapqual, List **quals, List **preds) else if (IsA(bitmapqual, IndexPath)) { IndexPath *ipath = (IndexPath *) bitmapqual; + ListCell *l; - *quals = list_concat(*quals, get_actual_clauses(ipath->indexclauses)); - *preds = list_concat(*preds, list_copy(ipath->indexinfo->indpred)); + foreach(l, ipath->indexclauses) + { + IndexClause *iclause = (IndexClause *) lfirst(l); + + *quals = lappend(*quals, iclause->rinfo->clause); + } + *preds = list_concat(*preds, ipath->indexinfo->indpred); } else elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual)); @@ -2109,11 +2135,12 @@ approximate_joinrel_size(PlannerInfo *root, Relids relids) * Matching clauses are added to *clauseset. */ static void -match_restriction_clauses_to_index(RelOptInfo *rel, IndexOptInfo *index, +match_restriction_clauses_to_index(PlannerInfo *root, + IndexOptInfo *index, IndexClauseSet *clauseset) { /* We can ignore clauses that are implied by the index predicate */ - match_clauses_to_index(index, index->indrestrictinfo, clauseset); + match_clauses_to_index(root, index->indrestrictinfo, index, clauseset); } /* @@ -2143,7 +2170,7 @@ match_join_clauses_to_index(PlannerInfo *root, if (restriction_is_or_clause(rinfo)) *joinorclauses = lappend(*joinorclauses, rinfo); else - match_clause_to_index(index, rinfo, clauseset); + match_clause_to_index(root, rinfo, index, clauseset); } } @@ -2181,7 +2208,7 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index, * since for non-btree indexes the EC's equality operators might not * be in the index opclass (cf ec_member_matches_indexcol). */ - match_clauses_to_index(index, clauses, clauseset); + match_clauses_to_index(root, clauses, index, clauseset); } } @@ -2191,8 +2218,9 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index, * Matching clauses are added to *clauseset. */ static void -match_clauses_to_index(IndexOptInfo *index, +match_clauses_to_index(PlannerInfo *root, List *clauses, + IndexOptInfo *index, IndexClauseSet *clauseset) { ListCell *lc; @@ -2201,7 +2229,7 @@ match_clauses_to_index(IndexOptInfo *index, { RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); - match_clause_to_index(index, rinfo, clauseset); + match_clause_to_index(root, rinfo, index, clauseset); } } @@ -2209,8 +2237,9 @@ match_clauses_to_index(IndexOptInfo *index, * match_clause_to_index * Test whether a qual clause can be used with an index. * - * If the clause is usable, add it to the appropriate list in *clauseset. - * *clauseset must be initialized to zeroes before first call. + * If the clause is usable, add an IndexClause entry for it to the appropriate + * list in *clauseset. (*clauseset must be initialized to zeroes before first + * call.) * * Note: in some circumstances we may find the same RestrictInfos coming from * multiple places. Defend against redundant outputs by refusing to add a @@ -2222,8 +2251,9 @@ match_clauses_to_index(IndexOptInfo *index, * same clause multiple times with different index columns. */ static void -match_clause_to_index(IndexOptInfo *index, +match_clause_to_index(PlannerInfo *root, RestrictInfo *rinfo, + IndexOptInfo *index, IndexClauseSet *clauseset) { int indexcol; @@ -2247,13 +2277,28 @@ match_clause_to_index(IndexOptInfo *index, /* OK, check each index key column for a match */ for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++) { - if (match_clause_to_indexcol(index, - indexcol, - rinfo)) + IndexClause *iclause; + ListCell *lc; + + /* Ignore duplicates */ + foreach(lc, clauseset->indexclauses[indexcol]) + { + IndexClause *iclause = (IndexClause *) lfirst(lc); + + if (iclause->rinfo == rinfo) + return; + } + + /* OK, try to match the clause to the index column */ + iclause = match_clause_to_indexcol(root, + rinfo, + indexcol, + index); + if (iclause) { + /* Success, so record it */ clauseset->indexclauses[indexcol] = - list_append_unique_ptr(clauseset->indexclauses[indexcol], - rinfo); + lappend(clauseset->indexclauses[indexcol], iclause); clauseset->nonempty = true; return; } @@ -2262,16 +2307,15 @@ match_clause_to_index(IndexOptInfo *index, /* * match_clause_to_indexcol() - * Determines whether a restriction clause matches a column of an index. + * Determine whether a restriction clause matches a column of an index, + * and if so, build an IndexClause node describing the details. * - * To match an index normally, the clause: + * To match an index normally, an operator clause: * * (1) must be in the form (indexkey op const) or (const op indexkey); * and - * (2) must contain an operator which is in the same family as the index - * operator for this column, or is a "special" operator as recognized - * by match_special_index_operator(); - * and + * (2) must contain an operator which is in the index's operator family + * for this column; and * (3) must match the collation of the index, if collation is relevant. * * Our definition of "const" is exceedingly liberal: we allow anything that @@ -2289,8 +2333,8 @@ match_clause_to_index(IndexOptInfo *index, * Presently, the executor can only deal with indexquals that have the * indexkey on the left, so we can only use clauses that have the indexkey * on the right if we can commute the clause to put the key on the left. - * We do not actually do the commuting here, but we check whether a - * suitable commutator operator is available. + * We handle that by generating an IndexClause with the correctly-commuted + * opclause as a derived indexqual. * * If the index has a collation, the clause must have the same collation. * For collation-less indexes, we assume it doesn't matter; this is @@ -2300,12 +2344,7 @@ match_clause_to_index(IndexOptInfo *index, * embodied in the macro IndexCollMatchesExprColl.) * * It is also possible to match RowCompareExpr clauses to indexes (but - * currently, only btree indexes handle this). In this routine we will - * report a match if the first column of the row comparison matches the - * target index column. This is sufficient to guarantee that some index - * condition can be constructed from the RowCompareExpr --- whether the - * remaining columns match the index too is considered in - * adjust_rowcompare_for_index(). + * currently, only btree indexes handle this). * * It is also possible to match ScalarArrayOpExpr clauses to indexes, when * the clause is of the form "indexkey op ANY (arrayconst)". @@ -2313,77 +2352,71 @@ match_clause_to_index(IndexOptInfo *index, * For boolean indexes, it is also possible to match the clause directly * to the indexkey; or perhaps the clause is (NOT indexkey). * - * 'index' is the index of interest. - * 'indexcol' is a column number of 'index' (counting from 0). + * And, last but not least, some operators and functions can be processed + * to derive (typically lossy) indexquals from a clause that isn't in + * itself indexable. If we see that any operand of an OpExpr or FuncExpr + * matches the index key, and the function has a planner support function + * attached to it, we'll invoke the support function to see if such an + * indexqual can be built. + * * 'rinfo' is the clause to be tested (as a RestrictInfo node). + * 'indexcol' is a column number of 'index' (counting from 0). + * 'index' is the index of interest. * - * Returns true if the clause can be used with this index key. + * Returns an IndexClause if the clause can be used with this index key, + * or NULL if not. * - * NOTE: returns false if clause is an OR or AND clause; it is the + * NOTE: returns NULL if clause is an OR or AND clause; it is the * responsibility of higher-level routines to cope with those. */ -static bool -match_clause_to_indexcol(IndexOptInfo *index, +static IndexClause * +match_clause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, int indexcol, - RestrictInfo *rinfo) + IndexOptInfo *index) { + IndexClause *iclause; Expr *clause = rinfo->clause; - Index index_relid = index->rel->relid; - Oid opfamily = index->opfamily[indexcol]; - Oid idxcollation = index->indexcollations[indexcol]; - Node *leftop, - *rightop; - Relids left_relids; - Relids right_relids; - Oid expr_op; - Oid expr_coll; - bool plain_op; + Oid opfamily; + + Assert(indexcol < index->nkeycolumns); + + /* + * Historically this code has coped with NULL clauses. That's probably + * not possible anymore, but we might as well continue to cope. + */ + if (clause == NULL) + return NULL; /* First check for boolean-index cases. */ + opfamily = index->opfamily[indexcol]; if (IsBooleanOpfamily(opfamily)) { - if (match_boolean_index_clause((Node *) clause, indexcol, index)) - return true; + iclause = match_boolean_index_clause(rinfo, indexcol, index); + if (iclause) + return iclause; } /* - * Clause must be a binary opclause, or possibly a ScalarArrayOpExpr - * (which is always binary, by definition). Or it could be a - * RowCompareExpr, which we pass off to match_rowcompare_to_indexcol(). - * Or, if the index supports it, we can handle IS NULL/NOT NULL clauses. + * Clause must be an opclause, funcclause, ScalarArrayOpExpr, or + * RowCompareExpr. Or, if the index supports it, we can handle IS + * NULL/NOT NULL clauses. */ - if (is_opclause(clause)) + if (IsA(clause, OpExpr)) { - leftop = get_leftop(clause); - rightop = get_rightop(clause); - if (!leftop || !rightop) - return false; - left_relids = rinfo->left_relids; - right_relids = rinfo->right_relids; - expr_op = ((OpExpr *) clause)->opno; - expr_coll = ((OpExpr *) clause)->inputcollid; - plain_op = true; + return match_opclause_to_indexcol(root, rinfo, indexcol, index); } - else if (clause && IsA(clause, ScalarArrayOpExpr)) + else if (IsA(clause, FuncExpr)) { - ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; - - /* We only accept ANY clauses, not ALL */ - if (!saop->useOr) - return false; - leftop = (Node *) linitial(saop->args); - rightop = (Node *) lsecond(saop->args); - left_relids = NULL; /* not actually needed */ - right_relids = pull_varnos(rightop); - expr_op = saop->opno; - expr_coll = saop->inputcollid; - plain_op = false; + return match_funcclause_to_indexcol(root, rinfo, indexcol, index); } - else if (clause && IsA(clause, RowCompareExpr)) + else if (IsA(clause, ScalarArrayOpExpr)) { - return match_rowcompare_to_indexcol(index, indexcol, - opfamily, idxcollation, - (RowCompareExpr *) clause); + return match_saopclause_to_indexcol(rinfo, indexcol, index); + } + else if (IsA(clause, RowCompareExpr)) + { + return match_rowcompare_to_indexcol(rinfo, indexcol, index); } else if (index->amsearchnulls && IsA(clause, NullTest)) { @@ -2391,130 +2424,471 @@ match_clause_to_indexcol(IndexOptInfo *index, if (!nt->argisrow && match_index_to_operand((Node *) nt->arg, indexcol, index)) - return true; - return false; + { + iclause = makeNode(IndexClause); + iclause->rinfo = rinfo; + iclause->indexquals = list_make1(rinfo); + iclause->lossy = false; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + return iclause; + } } - else - return false; + + return NULL; +} + +/* + * match_boolean_index_clause + * Recognize restriction clauses that can be matched to a boolean index. + * + * The idea here is that, for an index on a boolean column that supports the + * BooleanEqualOperator, we can transform a plain reference to the indexkey + * into "indexkey = true", or "NOT indexkey" into "indexkey = false", etc, + * so as to make the expression indexable using the index's "=" operator. + * Since Postgres 8.1, we must do this because constant simplification does + * the reverse transformation; without this code there'd be no way to use + * such an index at all. + * + * This should be called only when IsBooleanOpfamily() recognizes the + * index's operator family. We check to see if the clause matches the + * index's key, and if so, build a suitable IndexClause. + */ +static IndexClause * +match_boolean_index_clause(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index) +{ + Node *clause = (Node *) rinfo->clause; + Expr *op = NULL; + + /* Direct match? */ + if (match_index_to_operand(clause, indexcol, index)) + { + /* convert to indexkey = TRUE */ + op = make_opclause(BooleanEqualOperator, BOOLOID, false, + (Expr *) clause, + (Expr *) makeBoolConst(true, false), + InvalidOid, InvalidOid); + } + /* NOT clause? */ + else if (is_notclause(clause)) + { + Node *arg = (Node *) get_notclausearg((Expr *) clause); + + if (match_index_to_operand(arg, indexcol, index)) + { + /* convert to indexkey = FALSE */ + op = make_opclause(BooleanEqualOperator, BOOLOID, false, + (Expr *) arg, + (Expr *) makeBoolConst(false, false), + InvalidOid, InvalidOid); + } + } + + /* + * Since we only consider clauses at top level of WHERE, we can convert + * indexkey IS TRUE and indexkey IS FALSE to index searches as well. The + * different meaning for NULL isn't important. + */ + else if (clause && IsA(clause, BooleanTest)) + { + BooleanTest *btest = (BooleanTest *) clause; + Node *arg = (Node *) btest->arg; + + if (btest->booltesttype == IS_TRUE && + match_index_to_operand(arg, indexcol, index)) + { + /* convert to indexkey = TRUE */ + op = make_opclause(BooleanEqualOperator, BOOLOID, false, + (Expr *) arg, + (Expr *) makeBoolConst(true, false), + InvalidOid, InvalidOid); + } + else if (btest->booltesttype == IS_FALSE && + match_index_to_operand(arg, indexcol, index)) + { + /* convert to indexkey = FALSE */ + op = make_opclause(BooleanEqualOperator, BOOLOID, false, + (Expr *) arg, + (Expr *) makeBoolConst(false, false), + InvalidOid, InvalidOid); + } + } + + /* + * If we successfully made an operator clause from the given qual, we must + * wrap it in an IndexClause. It's not lossy. + */ + if (op) + { + IndexClause *iclause = makeNode(IndexClause); + + iclause->rinfo = rinfo; + iclause->indexquals = list_make1(make_simple_restrictinfo(op)); + iclause->lossy = false; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + return iclause; + } + + return NULL; +} + +/* + * match_opclause_to_indexcol() + * Handles the OpExpr case for match_clause_to_indexcol(), + * which see for comments. + */ +static IndexClause * +match_opclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index) +{ + IndexClause *iclause; + OpExpr *clause = (OpExpr *) rinfo->clause; + Node *leftop, + *rightop; + Oid expr_op; + Oid expr_coll; + Index index_relid; + Oid opfamily; + Oid idxcollation; + + /* + * Only binary operators need apply. (In theory, a planner support + * function could do something with a unary operator, but it seems + * unlikely to be worth the cycles to check.) + */ + if (list_length(clause->args) != 2) + return NULL; + + leftop = (Node *) linitial(clause->args); + rightop = (Node *) lsecond(clause->args); + expr_op = clause->opno; + expr_coll = clause->inputcollid; + + index_relid = index->rel->relid; + opfamily = index->opfamily[indexcol]; + idxcollation = index->indexcollations[indexcol]; /* * Check for clauses of the form: (indexkey operator constant) or - * (constant operator indexkey). See above notes about const-ness. + * (constant operator indexkey). See match_clause_to_indexcol's notes + * about const-ness. + * + * Note that we don't ask the support function about clauses that don't + * have one of these forms. Again, in principle it might be possible to + * do something, but it seems unlikely to be worth the cycles to check. */ if (match_index_to_operand(leftop, indexcol, index) && - !bms_is_member(index_relid, right_relids) && + !bms_is_member(index_relid, rinfo->right_relids) && !contain_volatile_functions(rightop)) { if (IndexCollMatchesExprColl(idxcollation, expr_coll) && - is_indexable_operator(expr_op, opfamily, true)) - return true; + op_in_opfamily(expr_op, opfamily)) + { + iclause = makeNode(IndexClause); + iclause->rinfo = rinfo; + iclause->indexquals = list_make1(rinfo); + iclause->lossy = false; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + return iclause; + } /* - * If we didn't find a member of the index's opfamily, see whether it - * is a "special" indexable operator. + * If we didn't find a member of the index's opfamily, try the support + * function for the operator's underlying function. */ - if (plain_op && - match_special_index_operator(clause, opfamily, - idxcollation, true)) - return true; - return false; + set_opfuncid(clause); /* make sure we have opfuncid */ + return get_index_clause_from_support(root, + rinfo, + clause->opfuncid, + 0, /* indexarg on left */ + indexcol, + index); } - if (plain_op && - match_index_to_operand(rightop, indexcol, index) && - !bms_is_member(index_relid, left_relids) && + if (match_index_to_operand(rightop, indexcol, index) && + !bms_is_member(index_relid, rinfo->left_relids) && !contain_volatile_functions(leftop)) { - if (IndexCollMatchesExprColl(idxcollation, expr_coll) && - is_indexable_operator(expr_op, opfamily, false)) - return true; + if (IndexCollMatchesExprColl(idxcollation, expr_coll)) + { + Oid comm_op = get_commutator(expr_op); + + if (OidIsValid(comm_op) && + op_in_opfamily(comm_op, opfamily)) + { + RestrictInfo *commrinfo; + + /* Build a commuted OpExpr and RestrictInfo */ + commrinfo = commute_restrictinfo(rinfo, comm_op); + + /* Make an IndexClause showing that as a derived qual */ + iclause = makeNode(IndexClause); + iclause->rinfo = rinfo; + iclause->indexquals = list_make1(commrinfo); + iclause->lossy = false; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + return iclause; + } + } /* - * If we didn't find a member of the index's opfamily, see whether it - * is a "special" indexable operator. + * If we didn't find a member of the index's opfamily, try the support + * function for the operator's underlying function. */ - if (match_special_index_operator(clause, opfamily, - idxcollation, false)) - return true; - return false; + set_opfuncid(clause); /* make sure we have opfuncid */ + return get_index_clause_from_support(root, + rinfo, + clause->opfuncid, + 1, /* indexarg on right */ + indexcol, + index); } - return false; + return NULL; } /* - * is_indexable_operator - * Does the operator match the specified index opfamily? - * - * If the indexkey is on the right, what we actually want to know - * is whether the operator has a commutator operator that matches - * the opfamily. + * match_funcclause_to_indexcol() + * Handles the FuncExpr case for match_clause_to_indexcol(), + * which see for comments. */ -static bool -is_indexable_operator(Oid expr_op, Oid opfamily, bool indexkey_on_left) +static IndexClause * +match_funcclause_to_indexcol(PlannerInfo *root, + RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index) +{ + FuncExpr *clause = (FuncExpr *) rinfo->clause; + int indexarg; + ListCell *lc; + + /* + * We have no built-in intelligence about function clauses, but if there's + * a planner support function, it might be able to do something. But, to + * cut down on wasted planning cycles, only call the support function if + * at least one argument matches the target index column. + * + * Note that we don't insist on the other arguments being pseudoconstants; + * the support function has to check that. This is to allow cases where + * only some of the other arguments need to be included in the indexqual. + */ + indexarg = 0; + foreach(lc, clause->args) + { + Node *op = (Node *) lfirst(lc); + + if (match_index_to_operand(op, indexcol, index)) + { + return get_index_clause_from_support(root, + rinfo, + clause->funcid, + indexarg, + indexcol, + index); + } + + indexarg++; + } + + return NULL; +} + +/* + * get_index_clause_from_support() + * If the function has a planner support function, try to construct + * an IndexClause using indexquals created by the support function. + */ +static IndexClause * +get_index_clause_from_support(PlannerInfo *root, + RestrictInfo *rinfo, + Oid funcid, + int indexarg, + int indexcol, + IndexOptInfo *index) { - /* Get the commuted operator if necessary */ - if (!indexkey_on_left) + Oid prosupport = get_func_support(funcid); + SupportRequestIndexCondition req; + List *sresult; + + if (!OidIsValid(prosupport)) + return NULL; + + req.type = T_SupportRequestIndexCondition; + req.root = root; + req.funcid = funcid; + req.node = (Node *) rinfo->clause; + req.indexarg = indexarg; + req.index = index; + req.indexcol = indexcol; + req.opfamily = index->opfamily[indexcol]; + req.indexcollation = index->indexcollations[indexcol]; + + req.lossy = true; /* default assumption */ + + sresult = (List *) + DatumGetPointer(OidFunctionCall1(prosupport, + PointerGetDatum(&req))); + + if (sresult != NIL) { - expr_op = get_commutator(expr_op); - if (expr_op == InvalidOid) - return false; + IndexClause *iclause = makeNode(IndexClause); + List *indexquals = NIL; + ListCell *lc; + + /* + * The support function API says it should just give back bare + * clauses, so here we must wrap each one in a RestrictInfo. + */ + foreach(lc, sresult) + { + Expr *clause = (Expr *) lfirst(lc); + + indexquals = lappend(indexquals, make_simple_restrictinfo(clause)); + } + + iclause->rinfo = rinfo; + iclause->indexquals = indexquals; + iclause->lossy = req.lossy; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + + return iclause; } - /* OK if the (commuted) operator is a member of the index's opfamily */ - return op_in_opfamily(expr_op, opfamily); + return NULL; } /* - * match_rowcompare_to_indexcol() - * Handles the RowCompareExpr case for match_clause_to_indexcol(), + * match_saopclause_to_indexcol() + * Handles the ScalarArrayOpExpr case for match_clause_to_indexcol(), * which see for comments. */ -static bool -match_rowcompare_to_indexcol(IndexOptInfo *index, +static IndexClause * +match_saopclause_to_indexcol(RestrictInfo *rinfo, int indexcol, - Oid opfamily, - Oid idxcollation, - RowCompareExpr *clause) + IndexOptInfo *index) { - Index index_relid = index->rel->relid; + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) rinfo->clause; Node *leftop, *rightop; + Relids right_relids; Oid expr_op; Oid expr_coll; + Index index_relid; + Oid opfamily; + Oid idxcollation; - /* Forget it if we're not dealing with a btree index */ - if (index->relam != BTREE_AM_OID) - return false; - - /* - * We could do the matching on the basis of insisting that the opfamily - * shown in the RowCompareExpr be the same as the index column's opfamily, - * but that could fail in the presence of reverse-sort opfamilies: it'd be - * a matter of chance whether RowCompareExpr had picked the forward or - * reverse-sort family. So look only at the operator, and match if it is - * a member of the index's opfamily (after commutation, if the indexkey is - * on the right). We'll worry later about whether any additional - * operators are matchable to the index. - */ - leftop = (Node *) linitial(clause->largs); - rightop = (Node *) linitial(clause->rargs); - expr_op = linitial_oid(clause->opnos); - expr_coll = linitial_oid(clause->inputcollids); + /* We only accept ANY clauses, not ALL */ + if (!saop->useOr) + return NULL; + leftop = (Node *) linitial(saop->args); + rightop = (Node *) lsecond(saop->args); + right_relids = pull_varnos(rightop); + expr_op = saop->opno; + expr_coll = saop->inputcollid; - /* Collations must match, if relevant */ - if (!IndexCollMatchesExprColl(idxcollation, expr_coll)) - return false; + index_relid = index->rel->relid; + opfamily = index->opfamily[indexcol]; + idxcollation = index->indexcollations[indexcol]; /* - * These syntactic tests are the same as in match_clause_to_indexcol() + * We must have indexkey on the left and a pseudo-constant array argument. */ if (match_index_to_operand(leftop, indexcol, index) && - !bms_is_member(index_relid, pull_varnos(rightop)) && + !bms_is_member(index_relid, right_relids) && !contain_volatile_functions(rightop)) { - /* OK, indexkey is on left */ - } + if (IndexCollMatchesExprColl(idxcollation, expr_coll) && + op_in_opfamily(expr_op, opfamily)) + { + IndexClause *iclause = makeNode(IndexClause); + + iclause->rinfo = rinfo; + iclause->indexquals = list_make1(rinfo); + iclause->lossy = false; + iclause->indexcol = indexcol; + iclause->indexcols = NIL; + return iclause; + } + + /* + * We do not currently ask support functions about ScalarArrayOpExprs, + * though in principle we could. + */ + } + + return NULL; +} + +/* + * match_rowcompare_to_indexcol() + * Handles the RowCompareExpr case for match_clause_to_indexcol(), + * which see for comments. + * + * In this routine we check whether the first column of the row comparison + * matches the target index column. This is sufficient to guarantee that some + * index condition can be constructed from the RowCompareExpr --- the rest + * is handled by expand_indexqual_rowcompare(). + */ +static IndexClause * +match_rowcompare_to_indexcol(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index) +{ + RowCompareExpr *clause = (RowCompareExpr *) rinfo->clause; + Index index_relid; + Oid opfamily; + Oid idxcollation; + Node *leftop, + *rightop; + bool var_on_left; + Oid expr_op; + Oid expr_coll; + + /* Forget it if we're not dealing with a btree index */ + if (index->relam != BTREE_AM_OID) + return NULL; + + index_relid = index->rel->relid; + opfamily = index->opfamily[indexcol]; + idxcollation = index->indexcollations[indexcol]; + + /* + * We could do the matching on the basis of insisting that the opfamily + * shown in the RowCompareExpr be the same as the index column's opfamily, + * but that could fail in the presence of reverse-sort opfamilies: it'd be + * a matter of chance whether RowCompareExpr had picked the forward or + * reverse-sort family. So look only at the operator, and match if it is + * a member of the index's opfamily (after commutation, if the indexkey is + * on the right). We'll worry later about whether any additional + * operators are matchable to the index. + */ + leftop = (Node *) linitial(clause->largs); + rightop = (Node *) linitial(clause->rargs); + expr_op = linitial_oid(clause->opnos); + expr_coll = linitial_oid(clause->inputcollids); + + /* Collations must match, if relevant */ + if (!IndexCollMatchesExprColl(idxcollation, expr_coll)) + return NULL; + + /* + * These syntactic tests are the same as in match_opclause_to_indexcol() + */ + if (match_index_to_operand(leftop, indexcol, index) && + !bms_is_member(index_relid, pull_varnos(rightop)) && + !contain_volatile_functions(rightop)) + { + /* OK, indexkey is on left */ + var_on_left = true; + } else if (match_index_to_operand(rightop, indexcol, index) && !bms_is_member(index_relid, pull_varnos(leftop)) && !contain_volatile_functions(leftop)) @@ -2522,10 +2896,11 @@ match_rowcompare_to_indexcol(IndexOptInfo *index, /* indexkey is on right, so commute the operator */ expr_op = get_commutator(expr_op); if (expr_op == InvalidOid) - return false; + return NULL; + var_on_left = false; } else - return false; + return NULL; /* We're good if the operator is the right type of opfamily member */ switch (get_op_opfamily_strategy(expr_op, opfamily)) @@ -2534,10 +2909,239 @@ match_rowcompare_to_indexcol(IndexOptInfo *index, case BTLessEqualStrategyNumber: case BTGreaterEqualStrategyNumber: case BTGreaterStrategyNumber: - return true; + return expand_indexqual_rowcompare(rinfo, + indexcol, + index, + expr_op, + var_on_left); } - return false; + return NULL; +} + +/* + * expand_indexqual_rowcompare --- expand a single indexqual condition + * that is a RowCompareExpr + * + * It's already known that the first column of the row comparison matches + * the specified column of the index. We can use additional columns of the + * row comparison as index qualifications, so long as they match the index + * in the "same direction", ie, the indexkeys are all on the same side of the + * clause and the operators are all the same-type members of the opfamilies. + * + * If all the columns of the RowCompareExpr match in this way, we just use it + * as-is, except for possibly commuting it to put the indexkeys on the left. + * + * Otherwise, we build a shortened RowCompareExpr (if more than one + * column matches) or a simple OpExpr (if the first-column match is all + * there is). In these cases the modified clause is always "<=" or ">=" + * even when the original was "<" or ">" --- this is necessary to match all + * the rows that could match the original. (We are building a lossy version + * of the row comparison when we do this, so we set lossy = true.) + * + * Note: this is really just the last half of match_rowcompare_to_indexcol, + * but we split it out for comprehensibility. + */ +static IndexClause * +expand_indexqual_rowcompare(RestrictInfo *rinfo, + int indexcol, + IndexOptInfo *index, + Oid expr_op, + bool var_on_left) +{ + IndexClause *iclause = makeNode(IndexClause); + RowCompareExpr *clause = (RowCompareExpr *) rinfo->clause; + int op_strategy; + Oid op_lefttype; + Oid op_righttype; + int matching_cols; + List *expr_ops; + List *opfamilies; + List *lefttypes; + List *righttypes; + List *new_ops; + List *var_args; + List *non_var_args; + + iclause->rinfo = rinfo; + iclause->indexcol = indexcol; + + if (var_on_left) + { + var_args = clause->largs; + non_var_args = clause->rargs; + } + else + { + var_args = clause->rargs; + non_var_args = clause->largs; + } + + get_op_opfamily_properties(expr_op, index->opfamily[indexcol], false, + &op_strategy, + &op_lefttype, + &op_righttype); + + /* Initialize returned list of which index columns are used */ + iclause->indexcols = list_make1_int(indexcol); + + /* Build lists of ops, opfamilies and operator datatypes in case needed */ + expr_ops = list_make1_oid(expr_op); + opfamilies = list_make1_oid(index->opfamily[indexcol]); + lefttypes = list_make1_oid(op_lefttype); + righttypes = list_make1_oid(op_righttype); + + /* + * See how many of the remaining columns match some index column in the + * same way. As in match_clause_to_indexcol(), the "other" side of any + * potential index condition is OK as long as it doesn't use Vars from the + * indexed relation. + */ + matching_cols = 1; + + while (matching_cols < list_length(var_args)) + { + Node *varop = (Node *) list_nth(var_args, matching_cols); + Node *constop = (Node *) list_nth(non_var_args, matching_cols); + int i; + + expr_op = list_nth_oid(clause->opnos, matching_cols); + if (!var_on_left) + { + /* indexkey is on right, so commute the operator */ + expr_op = get_commutator(expr_op); + if (expr_op == InvalidOid) + break; /* operator is not usable */ + } + if (bms_is_member(index->rel->relid, pull_varnos(constop))) + break; /* no good, Var on wrong side */ + if (contain_volatile_functions(constop)) + break; /* no good, volatile comparison value */ + + /* + * The Var side can match any key column of the index. + */ + for (i = 0; i < index->nkeycolumns; i++) + { + if (match_index_to_operand(varop, i, index) && + get_op_opfamily_strategy(expr_op, + index->opfamily[i]) == op_strategy && + IndexCollMatchesExprColl(index->indexcollations[i], + list_nth_oid(clause->inputcollids, + matching_cols))) + break; + } + if (i >= index->nkeycolumns) + break; /* no match found */ + + /* Add column number to returned list */ + iclause->indexcols = lappend_int(iclause->indexcols, i); + + /* Add operator info to lists */ + get_op_opfamily_properties(expr_op, index->opfamily[i], false, + &op_strategy, + &op_lefttype, + &op_righttype); + expr_ops = lappend_oid(expr_ops, expr_op); + opfamilies = lappend_oid(opfamilies, index->opfamily[i]); + lefttypes = lappend_oid(lefttypes, op_lefttype); + righttypes = lappend_oid(righttypes, op_righttype); + + /* This column matches, keep scanning */ + matching_cols++; + } + + /* Result is non-lossy if all columns are usable as index quals */ + iclause->lossy = (matching_cols != list_length(clause->opnos)); + + /* + * We can use rinfo->clause as-is if we have var on left and it's all + * usable as index quals. + */ + if (var_on_left && !iclause->lossy) + iclause->indexquals = list_make1(rinfo); + else + { + /* + * We have to generate a modified rowcompare (possibly just one + * OpExpr). The painful part of this is changing < to <= or > to >=, + * so deal with that first. + */ + if (!iclause->lossy) + { + /* very easy, just use the commuted operators */ + new_ops = expr_ops; + } + else if (op_strategy == BTLessEqualStrategyNumber || + op_strategy == BTGreaterEqualStrategyNumber) + { + /* easy, just use the same (possibly commuted) operators */ + new_ops = list_truncate(expr_ops, matching_cols); + } + else + { + ListCell *opfamilies_cell; + ListCell *lefttypes_cell; + ListCell *righttypes_cell; + + if (op_strategy == BTLessStrategyNumber) + op_strategy = BTLessEqualStrategyNumber; + else if (op_strategy == BTGreaterStrategyNumber) + op_strategy = BTGreaterEqualStrategyNumber; + else + elog(ERROR, "unexpected strategy number %d", op_strategy); + new_ops = NIL; + forthree(opfamilies_cell, opfamilies, + lefttypes_cell, lefttypes, + righttypes_cell, righttypes) + { + Oid opfam = lfirst_oid(opfamilies_cell); + Oid lefttype = lfirst_oid(lefttypes_cell); + Oid righttype = lfirst_oid(righttypes_cell); + + expr_op = get_opfamily_member(opfam, lefttype, righttype, + op_strategy); + if (!OidIsValid(expr_op)) /* should not happen */ + elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", + op_strategy, lefttype, righttype, opfam); + new_ops = lappend_oid(new_ops, expr_op); + } + } + + /* If we have more than one matching col, create a subset rowcompare */ + if (matching_cols > 1) + { + RowCompareExpr *rc = makeNode(RowCompareExpr); + + rc->rctype = (RowCompareType) op_strategy; + rc->opnos = new_ops; + rc->opfamilies = list_truncate(list_copy(clause->opfamilies), + matching_cols); + rc->inputcollids = list_truncate(list_copy(clause->inputcollids), + matching_cols); + rc->largs = list_truncate(copyObject(var_args), + matching_cols); + rc->rargs = list_truncate(copyObject(non_var_args), + matching_cols); + iclause->indexquals = list_make1(make_simple_restrictinfo((Expr *) rc)); + } + else + { + Expr *op; + + /* We don't report an index column list in this case */ + iclause->indexcols = NIL; + + op = make_opclause(linitial_oid(new_ops), BOOLOID, false, + copyObject(linitial(var_args)), + copyObject(linitial(non_var_args)), + InvalidOid, + linitial_oid(clause->inputcollids)); + iclause->indexquals = list_make1(make_simple_restrictinfo(op)); + } + } + + return iclause; } @@ -2614,11 +3218,12 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys, /* * We allow any column of the index to match each pathkey; they * don't have to match left-to-right as you might expect. This is - * correct for GiST, which is the sole existing AM supporting - * amcanorderbyop. We might need different logic in future for - * other implementations. + * correct for GiST, and it doesn't matter for SP-GiST because + * that doesn't handle multiple columns anyway, and no other + * existing AMs support amcanorderbyop. We might need different + * logic in future for other implementations. */ - for (indexcol = 0; indexcol < index->ncolumns; indexcol++) + for (indexcol = 0; indexcol < index->nkeycolumns; indexcol++) { Expr *expr; @@ -2678,8 +3283,8 @@ match_clause_to_ordering_op(IndexOptInfo *index, Expr *clause, Oid pk_opfamily) { - Oid opfamily = index->opfamily[indexcol]; - Oid idxcollation = index->indexcollations[indexcol]; + Oid opfamily; + Oid idxcollation; Node *leftop, *rightop; Oid expr_op; @@ -2687,6 +3292,11 @@ match_clause_to_ordering_op(IndexOptInfo *index, Oid sortfamily; bool commuted; + Assert(indexcol < index->nkeycolumns); + + opfamily = index->opfamily[indexcol]; + idxcollation = index->indexcollations[indexcol]; + /* * Clause must be a binary opclause. */ @@ -2921,8 +3531,13 @@ ec_member_matches_indexcol(PlannerInfo *root, RelOptInfo *rel, { IndexOptInfo *index = ((ec_member_matches_arg *) arg)->index; int indexcol = ((ec_member_matches_arg *) arg)->indexcol; - Oid curFamily = index->opfamily[indexcol]; - Oid curCollation = index->indexcollations[indexcol]; + Oid curFamily; + Oid curCollation; + + Assert(indexcol < index->nkeycolumns); + + curFamily = index->opfamily[indexcol]; + curCollation = index->indexcollations[indexcol]; /* * If it's a btree index, we can reject it if its opfamily isn't @@ -3039,7 +3654,7 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, * Try to find each index column in the lists of conditions. This is * O(N^2) or worse, but we expect all the lists to be short. */ - for (c = 0; c < ind->ncolumns; c++) + for (c = 0; c < ind->nkeycolumns; c++) { bool matched = false; ListCell *lc; @@ -3114,8 +3729,8 @@ relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, break; /* no match; this index doesn't help us */ } - /* Matched all columns of this index? */ - if (c == ind->ncolumns) + /* Matched all key columns of this index? */ + if (c == ind->nkeycolumns) return true; } @@ -3161,7 +3776,7 @@ indexcol_is_bool_constant_for_query(IndexOptInfo *index, int indexcol) continue; /* See if we can match the clause's expression to the index column */ - if (match_boolean_index_clause((Node *) rinfo->clause, indexcol, index)) + if (match_boolean_index_clause(rinfo, indexcol, index)) return true; } @@ -3232,7 +3847,7 @@ match_index_to_operand(Node *operand, { if (indexpr_item == NULL) elog(ERROR, "wrong number of index expressions"); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(index->indexprs, indexpr_item); } } if (indexpr_item == NULL) @@ -3252,1062 +3867,33 @@ match_index_to_operand(Node *operand, return false; } -/**************************************************************************** - * ---- ROUTINES FOR "SPECIAL" INDEXABLE OPERATORS ---- - ****************************************************************************/ - -/* - * These routines handle special optimization of operators that can be - * used with index scans even though they are not known to the executor's - * indexscan machinery. The key idea is that these operators allow us - * to derive approximate indexscan qual clauses, such that any tuples - * that pass the operator clause itself must also satisfy the simpler - * indexscan condition(s). Then we can use the indexscan machinery - * to avoid scanning as much of the table as we'd otherwise have to, - * while applying the original operator as a qpqual condition to ensure - * we deliver only the tuples we want. (In essence, we're using a regular - * index as if it were a lossy index.) - * - * An example of what we're doing is - * textfield LIKE 'abc%' - * from which we can generate the indexscanable conditions - * textfield >= 'abc' AND textfield < 'abd' - * which allow efficient scanning of an index on textfield. - * (In reality, character set and collation issues make the transformation - * from LIKE to indexscan limits rather harder than one might think ... - * but that's the basic idea.) - * - * Another thing that we do with this machinery is to provide special - * smarts for "boolean" indexes (that is, indexes on boolean columns - * that support boolean equality). We can transform a plain reference - * to the indexkey into "indexkey = true", or "NOT indexkey" into - * "indexkey = false", so as to make the expression indexable using the - * regular index operators. (As of Postgres 8.1, we must do this here - * because constant simplification does the reverse transformation; - * without this code there'd be no way to use such an index at all.) - * - * Three routines are provided here: - * - * match_special_index_operator() is just an auxiliary function for - * match_clause_to_indexcol(); after the latter fails to recognize a - * restriction opclause's operator as a member of an index's opfamily, - * it asks match_special_index_operator() whether the clause should be - * considered an indexqual anyway. - * - * match_boolean_index_clause() similarly detects clauses that can be - * converted into boolean equality operators. - * - * expand_indexqual_conditions() converts a list of RestrictInfo nodes - * (with implicit AND semantics across list elements) into a list of clauses - * that the executor can actually handle. For operators that are members of - * the index's opfamily this transformation is a no-op, but clauses recognized - * by match_special_index_operator() or match_boolean_index_clause() must be - * converted into one or more "regular" indexqual conditions. - */ - -/* - * match_boolean_index_clause - * Recognize restriction clauses that can be matched to a boolean index. - * - * This should be called only when IsBooleanOpfamily() recognizes the - * index's operator family. We check to see if the clause matches the - * index's key. - */ -static bool -match_boolean_index_clause(Node *clause, - int indexcol, - IndexOptInfo *index) -{ - /* Direct match? */ - if (match_index_to_operand(clause, indexcol, index)) - return true; - /* NOT clause? */ - if (not_clause(clause)) - { - if (match_index_to_operand((Node *) get_notclausearg((Expr *) clause), - indexcol, index)) - return true; - } - - /* - * Since we only consider clauses at top level of WHERE, we can convert - * indexkey IS TRUE and indexkey IS FALSE to index searches as well. The - * different meaning for NULL isn't important. - */ - else if (clause && IsA(clause, BooleanTest)) - { - BooleanTest *btest = (BooleanTest *) clause; - - if (btest->booltesttype == IS_TRUE || - btest->booltesttype == IS_FALSE) - if (match_index_to_operand((Node *) btest->arg, - indexcol, index)) - return true; - } - return false; -} - /* - * match_special_index_operator - * Recognize restriction clauses that can be used to generate - * additional indexscanable qualifications. - * - * The given clause is already known to be a binary opclause having - * the form (indexkey OP pseudoconst) or (pseudoconst OP indexkey), - * but the OP proved not to be one of the index's opfamily operators. - * Return 'true' if we can do something with it anyway. + * is_pseudo_constant_for_index() + * Test whether the given expression can be used as an indexscan + * comparison value. + * + * An indexscan comparison value must not contain any volatile functions, + * and it can't contain any Vars of the index's own table. Vars of + * other tables are okay, though; in that case we'd be producing an + * indexqual usable in a parameterized indexscan. This is, therefore, + * a weaker condition than is_pseudo_constant_clause(). + * + * This function is exported for use by planner support functions, + * which will have available the IndexOptInfo, but not any RestrictInfo + * infrastructure. It is making the same test made by functions above + * such as match_opclause_to_indexcol(), but those rely where possible + * on RestrictInfo information about variable membership. + * + * expr: the nodetree to be checked + * index: the index of interest */ -static bool -match_special_index_operator(Expr *clause, Oid opfamily, Oid idxcollation, - bool indexkey_on_left) +bool +is_pseudo_constant_for_index(Node *expr, IndexOptInfo *index) { - bool isIndexable = false; - Node *rightop; - Oid expr_op; - Oid expr_coll; - Const *patt; - Const *prefix = NULL; - Pattern_Prefix_Status pstatus = Pattern_Prefix_None; - - /* - * Currently, all known special operators require the indexkey on the - * left, but this test could be pushed into the switch statement if some - * are added that do not... - */ - if (!indexkey_on_left) - return false; - - /* we know these will succeed */ - rightop = get_rightop(clause); - expr_op = ((OpExpr *) clause)->opno; - expr_coll = ((OpExpr *) clause)->inputcollid; - - /* again, required for all current special ops: */ - if (!IsA(rightop, Const) || - ((Const *) rightop)->constisnull) - return false; - patt = (Const *) rightop; - - switch (expr_op) - { - case OID_TEXT_LIKE_OP: - case OID_BPCHAR_LIKE_OP: - case OID_NAME_LIKE_OP: - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like, expr_coll, - &prefix, NULL); - isIndexable = (pstatus != Pattern_Prefix_None); - break; - - case OID_BYTEA_LIKE_OP: - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like, expr_coll, - &prefix, NULL); - isIndexable = (pstatus != Pattern_Prefix_None); - break; - - case OID_TEXT_ICLIKE_OP: - case OID_BPCHAR_ICLIKE_OP: - case OID_NAME_ICLIKE_OP: - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC, expr_coll, - &prefix, NULL); - isIndexable = (pstatus != Pattern_Prefix_None); - break; - - case OID_TEXT_REGEXEQ_OP: - case OID_BPCHAR_REGEXEQ_OP: - case OID_NAME_REGEXEQ_OP: - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex, expr_coll, - &prefix, NULL); - isIndexable = (pstatus != Pattern_Prefix_None); - break; - - case OID_TEXT_ICREGEXEQ_OP: - case OID_BPCHAR_ICREGEXEQ_OP: - case OID_NAME_ICREGEXEQ_OP: - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC, expr_coll, - &prefix, NULL); - isIndexable = (pstatus != Pattern_Prefix_None); - break; - - case OID_INET_SUB_OP: - case OID_INET_SUBEQ_OP: - isIndexable = true; - break; - } - - if (prefix) - { - pfree(DatumGetPointer(prefix->constvalue)); - pfree(prefix); - } - - /* done if the expression doesn't look indexable */ - if (!isIndexable) - return false; - - /* - * Must also check that index's opfamily supports the operators we will - * want to apply. (A hash index, for example, will not support ">=".) - * Currently, only btree and spgist support the operators we need. - * - * Note: actually, in the Pattern_Prefix_Exact case, we only need "=" so a - * hash index would work. Currently it doesn't seem worth checking for - * that, however. - * - * We insist on the opfamily being the specific one we expect, else we'd - * do the wrong thing if someone were to make a reverse-sort opfamily with - * the same operators. - * - * The non-pattern opclasses will not sort the way we need in most non-C - * locales. We can use such an index anyway for an exact match (simple - * equality), but not for prefix-match cases. Note that here we are - * looking at the index's collation, not the expression's collation -- - * this test is *not* dependent on the LIKE/regex operator's collation. - */ - switch (expr_op) - { - case OID_TEXT_LIKE_OP: - case OID_TEXT_ICLIKE_OP: - case OID_TEXT_REGEXEQ_OP: - case OID_TEXT_ICREGEXEQ_OP: - isIndexable = - (opfamily == TEXT_PATTERN_BTREE_FAM_OID) || - (opfamily == TEXT_SPGIST_FAM_OID) || - (opfamily == TEXT_BTREE_FAM_OID && - (pstatus == Pattern_Prefix_Exact || - lc_collate_is_c(idxcollation))); - break; - - case OID_BPCHAR_LIKE_OP: - case OID_BPCHAR_ICLIKE_OP: - case OID_BPCHAR_REGEXEQ_OP: - case OID_BPCHAR_ICREGEXEQ_OP: - isIndexable = - (opfamily == BPCHAR_PATTERN_BTREE_FAM_OID) || - (opfamily == BPCHAR_BTREE_FAM_OID && - (pstatus == Pattern_Prefix_Exact || - lc_collate_is_c(idxcollation))); - break; - - case OID_NAME_LIKE_OP: - case OID_NAME_ICLIKE_OP: - case OID_NAME_REGEXEQ_OP: - case OID_NAME_ICREGEXEQ_OP: - /* name uses locale-insensitive sorting */ - isIndexable = (opfamily == NAME_BTREE_FAM_OID); - break; - - case OID_BYTEA_LIKE_OP: - isIndexable = (opfamily == BYTEA_BTREE_FAM_OID); - break; - - case OID_INET_SUB_OP: - case OID_INET_SUBEQ_OP: - isIndexable = (opfamily == NETWORK_BTREE_FAM_OID); - break; - } - - return isIndexable; -} - -/* - * expand_indexqual_conditions - * Given a list of RestrictInfo nodes, produce a list of directly usable - * index qual clauses. - * - * Standard qual clauses (those in the index's opfamily) are passed through - * unchanged. Boolean clauses and "special" index operators are expanded - * into clauses that the indexscan machinery will know what to do with. - * RowCompare clauses are simplified if necessary to create a clause that is - * fully checkable by the index. - * - * In addition to the expressions themselves, there are auxiliary lists - * of the index column numbers that the clauses are meant to be used with; - * we generate an updated column number list for the result. (This is not - * the identical list because one input clause sometimes produces more than - * one output clause.) - * - * The input clauses are sorted by column number, and so the output is too. - * (This is depended on in various places in both planner and executor.) - */ -void -expand_indexqual_conditions(IndexOptInfo *index, - List *indexclauses, List *indexclausecols, - List **indexquals_p, List **indexqualcols_p) -{ - List *indexquals = NIL; - List *indexqualcols = NIL; - ListCell *lcc, - *lci; - - forboth(lcc, indexclauses, lci, indexclausecols) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(lcc); - int indexcol = lfirst_int(lci); - Expr *clause = rinfo->clause; - Oid curFamily = index->opfamily[indexcol]; - Oid curCollation = index->indexcollations[indexcol]; - - /* First check for boolean cases */ - if (IsBooleanOpfamily(curFamily)) - { - Expr *boolqual; - - boolqual = expand_boolean_index_clause((Node *) clause, - indexcol, - index); - if (boolqual) - { - indexquals = lappend(indexquals, - make_simple_restrictinfo(boolqual)); - indexqualcols = lappend_int(indexqualcols, indexcol); - continue; - } - } - - /* - * Else it must be an opclause (usual case), ScalarArrayOp, - * RowCompare, or NullTest - */ - if (is_opclause(clause)) - { - indexquals = list_concat(indexquals, - expand_indexqual_opclause(rinfo, - curFamily, - curCollation)); - /* expand_indexqual_opclause can produce multiple clauses */ - while (list_length(indexqualcols) < list_length(indexquals)) - indexqualcols = lappend_int(indexqualcols, indexcol); - } - else if (IsA(clause, ScalarArrayOpExpr)) - { - /* no extra work at this time */ - indexquals = lappend(indexquals, rinfo); - indexqualcols = lappend_int(indexqualcols, indexcol); - } - else if (IsA(clause, RowCompareExpr)) - { - indexquals = lappend(indexquals, - expand_indexqual_rowcompare(rinfo, - index, - indexcol)); - indexqualcols = lappend_int(indexqualcols, indexcol); - } - else if (IsA(clause, NullTest)) - { - Assert(index->amsearchnulls); - indexquals = lappend(indexquals, rinfo); - indexqualcols = lappend_int(indexqualcols, indexcol); - } - else - elog(ERROR, "unsupported indexqual type: %d", - (int) nodeTag(clause)); - } - - *indexquals_p = indexquals; - *indexqualcols_p = indexqualcols; -} - -/* - * expand_boolean_index_clause - * Convert a clause recognized by match_boolean_index_clause into - * a boolean equality operator clause. - * - * Returns NULL if the clause isn't a boolean index qual. - */ -static Expr * -expand_boolean_index_clause(Node *clause, - int indexcol, - IndexOptInfo *index) -{ - /* Direct match? */ - if (match_index_to_operand(clause, indexcol, index)) - { - /* convert to indexkey = TRUE */ - return make_opclause(BooleanEqualOperator, BOOLOID, false, - (Expr *) clause, - (Expr *) makeBoolConst(true, false), - InvalidOid, InvalidOid); - } - /* NOT clause? */ - if (not_clause(clause)) - { - Node *arg = (Node *) get_notclausearg((Expr *) clause); - - /* It must have matched the indexkey */ - Assert(match_index_to_operand(arg, indexcol, index)); - /* convert to indexkey = FALSE */ - return make_opclause(BooleanEqualOperator, BOOLOID, false, - (Expr *) arg, - (Expr *) makeBoolConst(false, false), - InvalidOid, InvalidOid); - } - if (clause && IsA(clause, BooleanTest)) - { - BooleanTest *btest = (BooleanTest *) clause; - Node *arg = (Node *) btest->arg; - - /* It must have matched the indexkey */ - Assert(match_index_to_operand(arg, indexcol, index)); - if (btest->booltesttype == IS_TRUE) - { - /* convert to indexkey = TRUE */ - return make_opclause(BooleanEqualOperator, BOOLOID, false, - (Expr *) arg, - (Expr *) makeBoolConst(true, false), - InvalidOid, InvalidOid); - } - if (btest->booltesttype == IS_FALSE) - { - /* convert to indexkey = FALSE */ - return make_opclause(BooleanEqualOperator, BOOLOID, false, - (Expr *) arg, - (Expr *) makeBoolConst(false, false), - InvalidOid, InvalidOid); - } - /* Oops */ - Assert(false); - } - - return NULL; -} - -/* - * expand_indexqual_opclause --- expand a single indexqual condition - * that is an operator clause - * - * The input is a single RestrictInfo, the output a list of RestrictInfos. - * - * In the base case this is just list_make1(), but we have to be prepared to - * expand special cases that were accepted by match_special_index_operator(). - */ -static List * -expand_indexqual_opclause(RestrictInfo *rinfo, Oid opfamily, Oid idxcollation) -{ - Expr *clause = rinfo->clause; - - /* we know these will succeed */ - Node *leftop = get_leftop(clause); - Node *rightop = get_rightop(clause); - Oid expr_op = ((OpExpr *) clause)->opno; - Oid expr_coll = ((OpExpr *) clause)->inputcollid; - Const *patt = (Const *) rightop; - Const *prefix = NULL; - Pattern_Prefix_Status pstatus; - - /* - * LIKE and regex operators are not members of any btree index opfamily, - * but they can be members of opfamilies for more exotic index types such - * as GIN. Therefore, we should only do expansion if the operator is - * actually not in the opfamily. But checking that requires a syscache - * lookup, so it's best to first see if the operator is one we are - * interested in. - */ - switch (expr_op) - { - case OID_TEXT_LIKE_OP: - case OID_BPCHAR_LIKE_OP: - case OID_NAME_LIKE_OP: - case OID_BYTEA_LIKE_OP: - if (!op_in_opfamily(expr_op, opfamily)) - { - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like, expr_coll, - &prefix, NULL); - return prefix_quals(leftop, opfamily, idxcollation, prefix, pstatus); - } - break; - - case OID_TEXT_ICLIKE_OP: - case OID_BPCHAR_ICLIKE_OP: - case OID_NAME_ICLIKE_OP: - if (!op_in_opfamily(expr_op, opfamily)) - { - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Like_IC, expr_coll, - &prefix, NULL); - return prefix_quals(leftop, opfamily, idxcollation, prefix, pstatus); - } - break; - - case OID_TEXT_REGEXEQ_OP: - case OID_BPCHAR_REGEXEQ_OP: - case OID_NAME_REGEXEQ_OP: - if (!op_in_opfamily(expr_op, opfamily)) - { - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex, expr_coll, - &prefix, NULL); - return prefix_quals(leftop, opfamily, idxcollation, prefix, pstatus); - } - break; - - case OID_TEXT_ICREGEXEQ_OP: - case OID_BPCHAR_ICREGEXEQ_OP: - case OID_NAME_ICREGEXEQ_OP: - if (!op_in_opfamily(expr_op, opfamily)) - { - /* the right-hand const is type text for all of these */ - pstatus = pattern_fixed_prefix(patt, Pattern_Type_Regex_IC, expr_coll, - &prefix, NULL); - return prefix_quals(leftop, opfamily, idxcollation, prefix, pstatus); - } - break; - - case OID_INET_SUB_OP: - case OID_INET_SUBEQ_OP: - if (!op_in_opfamily(expr_op, opfamily)) - { - return network_prefix_quals(leftop, expr_op, opfamily, - patt->constvalue); - } - break; - } - - /* Default case: just make a list of the unmodified indexqual */ - return list_make1(rinfo); -} - -/* - * expand_indexqual_rowcompare --- expand a single indexqual condition - * that is a RowCompareExpr - * - * This is a thin wrapper around adjust_rowcompare_for_index; we export the - * latter so that createplan.c can use it to re-discover which columns of the - * index are used by a row comparison indexqual. - */ -static RestrictInfo * -expand_indexqual_rowcompare(RestrictInfo *rinfo, - IndexOptInfo *index, - int indexcol) -{ - RowCompareExpr *clause = (RowCompareExpr *) rinfo->clause; - Expr *newclause; - List *indexcolnos; - bool var_on_left; - - newclause = adjust_rowcompare_for_index(clause, - index, - indexcol, - &indexcolnos, - &var_on_left); - - /* - * If we didn't have to change the RowCompareExpr, return the original - * RestrictInfo. - */ - if (newclause == (Expr *) clause) - return rinfo; - - /* Else we need a new RestrictInfo */ - return make_simple_restrictinfo(newclause); -} - -/* - * adjust_rowcompare_for_index --- expand a single indexqual condition - * that is a RowCompareExpr - * - * It's already known that the first column of the row comparison matches - * the specified column of the index. We can use additional columns of the - * row comparison as index qualifications, so long as they match the index - * in the "same direction", ie, the indexkeys are all on the same side of the - * clause and the operators are all the same-type members of the opfamilies. - * If all the columns of the RowCompareExpr match in this way, we just use it - * as-is. Otherwise, we build a shortened RowCompareExpr (if more than one - * column matches) or a simple OpExpr (if the first-column match is all - * there is). In these cases the modified clause is always "<=" or ">=" - * even when the original was "<" or ">" --- this is necessary to match all - * the rows that could match the original. (We are essentially building a - * lossy version of the row comparison when we do this.) - * - * *indexcolnos receives an integer list of the index column numbers (zero - * based) used in the resulting expression. The reason we need to return - * that is that if the index is selected for use, createplan.c will need to - * call this again to extract that list. (This is a bit grotty, but row - * comparison indexquals aren't used enough to justify finding someplace to - * keep the information in the Path representation.) Since createplan.c - * also needs to know which side of the RowCompareExpr is the index side, - * we also return *var_on_left_p rather than re-deducing that there. - */ -Expr * -adjust_rowcompare_for_index(RowCompareExpr *clause, - IndexOptInfo *index, - int indexcol, - List **indexcolnos, - bool *var_on_left_p) -{ - bool var_on_left; - int op_strategy; - Oid op_lefttype; - Oid op_righttype; - int matching_cols; - Oid expr_op; - List *opfamilies; - List *lefttypes; - List *righttypes; - List *new_ops; - ListCell *largs_cell; - ListCell *rargs_cell; - ListCell *opnos_cell; - ListCell *collids_cell; - - /* We have to figure out (again) how the first col matches */ - var_on_left = match_index_to_operand((Node *) linitial(clause->largs), - indexcol, index); - Assert(var_on_left || - match_index_to_operand((Node *) linitial(clause->rargs), - indexcol, index)); - *var_on_left_p = var_on_left; - - expr_op = linitial_oid(clause->opnos); - if (!var_on_left) - expr_op = get_commutator(expr_op); - get_op_opfamily_properties(expr_op, index->opfamily[indexcol], false, - &op_strategy, - &op_lefttype, - &op_righttype); - - /* Initialize returned list of which index columns are used */ - *indexcolnos = list_make1_int(indexcol); - - /* Build lists of the opfamilies and operator datatypes in case needed */ - opfamilies = list_make1_oid(index->opfamily[indexcol]); - lefttypes = list_make1_oid(op_lefttype); - righttypes = list_make1_oid(op_righttype); - - /* - * See how many of the remaining columns match some index column in the - * same way. As in match_clause_to_indexcol(), the "other" side of any - * potential index condition is OK as long as it doesn't use Vars from the - * indexed relation. - */ - matching_cols = 1; - largs_cell = lnext(list_head(clause->largs)); - rargs_cell = lnext(list_head(clause->rargs)); - opnos_cell = lnext(list_head(clause->opnos)); - collids_cell = lnext(list_head(clause->inputcollids)); - - while (largs_cell != NULL) - { - Node *varop; - Node *constop; - int i; - - expr_op = lfirst_oid(opnos_cell); - if (var_on_left) - { - varop = (Node *) lfirst(largs_cell); - constop = (Node *) lfirst(rargs_cell); - } - else - { - varop = (Node *) lfirst(rargs_cell); - constop = (Node *) lfirst(largs_cell); - /* indexkey is on right, so commute the operator */ - expr_op = get_commutator(expr_op); - if (expr_op == InvalidOid) - break; /* operator is not usable */ - } - if (bms_is_member(index->rel->relid, pull_varnos(constop))) - break; /* no good, Var on wrong side */ - if (contain_volatile_functions(constop)) - break; /* no good, volatile comparison value */ - - /* - * The Var side can match any column of the index. - */ - for (i = 0; i < index->ncolumns; i++) - { - if (match_index_to_operand(varop, i, index) && - get_op_opfamily_strategy(expr_op, - index->opfamily[i]) == op_strategy && - IndexCollMatchesExprColl(index->indexcollations[i], - lfirst_oid(collids_cell))) - break; - } - if (i >= index->ncolumns) - break; /* no match found */ - - /* Add column number to returned list */ - *indexcolnos = lappend_int(*indexcolnos, i); - - /* Add opfamily and datatypes to lists */ - get_op_opfamily_properties(expr_op, index->opfamily[i], false, - &op_strategy, - &op_lefttype, - &op_righttype); - opfamilies = lappend_oid(opfamilies, index->opfamily[i]); - lefttypes = lappend_oid(lefttypes, op_lefttype); - righttypes = lappend_oid(righttypes, op_righttype); - - /* This column matches, keep scanning */ - matching_cols++; - largs_cell = lnext(largs_cell); - rargs_cell = lnext(rargs_cell); - opnos_cell = lnext(opnos_cell); - collids_cell = lnext(collids_cell); - } - - /* Return clause as-is if it's all usable as index quals */ - if (matching_cols == list_length(clause->opnos)) - return (Expr *) clause; - - /* - * We have to generate a subset rowcompare (possibly just one OpExpr). The - * painful part of this is changing < to <= or > to >=, so deal with that - * first. - */ - if (op_strategy == BTLessEqualStrategyNumber || - op_strategy == BTGreaterEqualStrategyNumber) - { - /* easy, just use the same operators */ - new_ops = list_truncate(list_copy(clause->opnos), matching_cols); - } - else - { - ListCell *opfamilies_cell; - ListCell *lefttypes_cell; - ListCell *righttypes_cell; - - if (op_strategy == BTLessStrategyNumber) - op_strategy = BTLessEqualStrategyNumber; - else if (op_strategy == BTGreaterStrategyNumber) - op_strategy = BTGreaterEqualStrategyNumber; - else - elog(ERROR, "unexpected strategy number %d", op_strategy); - new_ops = NIL; - lefttypes_cell = list_head(lefttypes); - righttypes_cell = list_head(righttypes); - foreach(opfamilies_cell, opfamilies) - { - Oid opfam = lfirst_oid(opfamilies_cell); - Oid lefttype = lfirst_oid(lefttypes_cell); - Oid righttype = lfirst_oid(righttypes_cell); - - expr_op = get_opfamily_member(opfam, lefttype, righttype, - op_strategy); - if (!OidIsValid(expr_op)) /* should not happen */ - elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", - op_strategy, lefttype, righttype, opfam); - if (!var_on_left) - { - expr_op = get_commutator(expr_op); - if (!OidIsValid(expr_op)) /* should not happen */ - elog(ERROR, "could not find commutator of operator %d(%u,%u) of opfamily %u", - op_strategy, lefttype, righttype, opfam); - } - new_ops = lappend_oid(new_ops, expr_op); - lefttypes_cell = lnext(lefttypes_cell); - righttypes_cell = lnext(righttypes_cell); - } - } - - /* If we have more than one matching col, create a subset rowcompare */ - if (matching_cols > 1) - { - RowCompareExpr *rc = makeNode(RowCompareExpr); - - if (var_on_left) - rc->rctype = (RowCompareType) op_strategy; - else - rc->rctype = (op_strategy == BTLessEqualStrategyNumber) ? - ROWCOMPARE_GE : ROWCOMPARE_LE; - rc->opnos = new_ops; - rc->opfamilies = list_truncate(list_copy(clause->opfamilies), - matching_cols); - rc->inputcollids = list_truncate(list_copy(clause->inputcollids), - matching_cols); - rc->largs = list_truncate(copyObject(clause->largs), - matching_cols); - rc->rargs = list_truncate(copyObject(clause->rargs), - matching_cols); - return (Expr *) rc; - } - else - { - return make_opclause(linitial_oid(new_ops), BOOLOID, false, - copyObject(linitial(clause->largs)), - copyObject(linitial(clause->rargs)), - InvalidOid, - linitial_oid(clause->inputcollids)); - } -} - -/* - * Given a fixed prefix that all the "leftop" values must have, - * generate suitable indexqual condition(s). opfamily is the index - * operator family; we use it to deduce the appropriate comparison - * operators and operand datatypes. collation is the input collation to use. - */ -static List * -prefix_quals(Node *leftop, Oid opfamily, Oid collation, - Const *prefix_const, Pattern_Prefix_Status pstatus) -{ - List *result; - Oid datatype; - Oid oproid; - Expr *expr; - FmgrInfo ltproc; - Const *greaterstr; - - Assert(pstatus != Pattern_Prefix_None); - - switch (opfamily) - { - case TEXT_BTREE_FAM_OID: - case TEXT_PATTERN_BTREE_FAM_OID: - case TEXT_SPGIST_FAM_OID: - datatype = TEXTOID; - break; - - case BPCHAR_BTREE_FAM_OID: - case BPCHAR_PATTERN_BTREE_FAM_OID: - datatype = BPCHAROID; - break; - - case NAME_BTREE_FAM_OID: - datatype = NAMEOID; - break; - - case BYTEA_BTREE_FAM_OID: - datatype = BYTEAOID; - break; - - default: - /* shouldn't get here */ - elog(ERROR, "unexpected opfamily: %u", opfamily); - return NIL; - } - - /* - * If necessary, coerce the prefix constant to the right type. The given - * prefix constant is either text or bytea type. - */ - if (prefix_const->consttype != datatype) - { - char *prefix; - - switch (prefix_const->consttype) - { - case TEXTOID: - prefix = TextDatumGetCString(prefix_const->constvalue); - break; - case BYTEAOID: - prefix = DatumGetCString(DirectFunctionCall1(byteaout, - prefix_const->constvalue)); - break; - default: - elog(ERROR, "unexpected const type: %u", - prefix_const->consttype); - return NIL; - } - prefix_const = string_to_const(prefix, datatype); - pfree(prefix); - } - - /* - * If we found an exact-match pattern, generate an "=" indexqual. - */ - if (pstatus == Pattern_Prefix_Exact) - { - oproid = get_opfamily_member(opfamily, datatype, datatype, - BTEqualStrategyNumber); - if (oproid == InvalidOid) - elog(ERROR, "no = operator for opfamily %u", opfamily); - expr = make_opclause(oproid, BOOLOID, false, - (Expr *) leftop, (Expr *) prefix_const, - InvalidOid, collation); - result = list_make1(make_simple_restrictinfo(expr)); - return result; - } - - /* - * Otherwise, we have a nonempty required prefix of the values. - * - * We can always say "x >= prefix". - */ - oproid = get_opfamily_member(opfamily, datatype, datatype, - BTGreaterEqualStrategyNumber); - if (oproid == InvalidOid) - elog(ERROR, "no >= operator for opfamily %u", opfamily); - expr = make_opclause(oproid, BOOLOID, false, - (Expr *) leftop, (Expr *) prefix_const, - InvalidOid, collation); - result = list_make1(make_simple_restrictinfo(expr)); - - /*------- - * If we can create a string larger than the prefix, we can say - * "x < greaterstr". NB: we rely on make_greater_string() to generate - * a guaranteed-greater string, not just a probably-greater string. - * In general this is only guaranteed in C locale, so we'd better be - * using a C-locale index collation. - *------- - */ - oproid = get_opfamily_member(opfamily, datatype, datatype, - BTLessStrategyNumber); - if (oproid == InvalidOid) - elog(ERROR, "no < operator for opfamily %u", opfamily); - fmgr_info(get_opcode(oproid), <proc); - greaterstr = make_greater_string(prefix_const, <proc, collation); - if (greaterstr) - { - expr = make_opclause(oproid, BOOLOID, false, - (Expr *) leftop, (Expr *) greaterstr, - InvalidOid, collation); - result = lappend(result, make_simple_restrictinfo(expr)); - } - - return result; -} - -/* - * Given a leftop and a rightop, and an inet-family sup/sub operator, - * generate suitable indexqual condition(s). expr_op is the original - * operator, and opfamily is the index opfamily. - */ -static List * -network_prefix_quals(Node *leftop, Oid expr_op, Oid opfamily, Datum rightop) -{ - bool is_eq; - Oid datatype; - Oid opr1oid; - Oid opr2oid; - Datum opr1right; - Datum opr2right; - List *result; - Expr *expr; - - switch (expr_op) - { - case OID_INET_SUB_OP: - datatype = INETOID; - is_eq = false; - break; - case OID_INET_SUBEQ_OP: - datatype = INETOID; - is_eq = true; - break; - default: - elog(ERROR, "unexpected operator: %u", expr_op); - return NIL; - } - - /* - * create clause "key >= network_scan_first( rightop )", or ">" if the - * operator disallows equality. - */ - if (is_eq) - { - opr1oid = get_opfamily_member(opfamily, datatype, datatype, - BTGreaterEqualStrategyNumber); - if (opr1oid == InvalidOid) - elog(ERROR, "no >= operator for opfamily %u", opfamily); - } - else - { - opr1oid = get_opfamily_member(opfamily, datatype, datatype, - BTGreaterStrategyNumber); - if (opr1oid == InvalidOid) - elog(ERROR, "no > operator for opfamily %u", opfamily); - } - - opr1right = network_scan_first(rightop); - - expr = make_opclause(opr1oid, BOOLOID, false, - (Expr *) leftop, - (Expr *) makeConst(datatype, -1, - InvalidOid, /* not collatable */ - -1, opr1right, - false, false), - InvalidOid, InvalidOid); - result = list_make1(make_simple_restrictinfo(expr)); - - /* create clause "key <= network_scan_last( rightop )" */ - - opr2oid = get_opfamily_member(opfamily, datatype, datatype, - BTLessEqualStrategyNumber); - if (opr2oid == InvalidOid) - elog(ERROR, "no <= operator for opfamily %u", opfamily); - - opr2right = network_scan_last(rightop); - - expr = make_opclause(opr2oid, BOOLOID, false, - (Expr *) leftop, - (Expr *) makeConst(datatype, -1, - InvalidOid, /* not collatable */ - -1, opr2right, - false, false), - InvalidOid, InvalidOid); - result = lappend(result, make_simple_restrictinfo(expr)); - - return result; -} - -/* - * Handy subroutines for match_special_index_operator() and friends. - */ - -/* - * Generate a Datum of the appropriate type from a C string. - * Note that all of the supported types are pass-by-ref, so the - * returned value should be pfree'd if no longer needed. - */ -static Datum -string_to_datum(const char *str, Oid datatype) -{ - /* - * We cheat a little by assuming that CStringGetTextDatum() will do for - * bpchar and varchar constants too... - */ - if (datatype == NAMEOID) - return DirectFunctionCall1(namein, CStringGetDatum(str)); - else if (datatype == BYTEAOID) - return DirectFunctionCall1(byteain, CStringGetDatum(str)); - else - return CStringGetTextDatum(str); -} - -/* - * Generate a Const node of the appropriate type from a C string. - */ -static Const * -string_to_const(const char *str, Oid datatype) -{ - Datum conval = string_to_datum(str, datatype); - Oid collation; - int constlen; - - /* - * We only need to support a few datatypes here, so hard-wire properties - * instead of incurring the expense of catalog lookups. - */ - switch (datatype) - { - case TEXTOID: - case VARCHAROID: - case BPCHAROID: - collation = DEFAULT_COLLATION_OID; - constlen = -1; - break; - - case NAMEOID: - collation = InvalidOid; - constlen = NAMEDATALEN; - break; - - case BYTEAOID: - collation = InvalidOid; - constlen = -1; - break; - - default: - elog(ERROR, "unexpected datatype in string_to_const: %u", - datatype); - return NULL; - } - - return makeConst(datatype, -1, collation, constlen, - conval, false, false); + /* pull_varnos is cheaper than volatility check, so do that first */ + if (bms_is_member(index->rel->relid, pull_varnos(expr))) + return false; /* no good, contains Var of table */ + if (contain_volatile_functions(expr)) + return false; /* no good, volatile comparison value */ + return true; } diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 3fd3cc7670b..dc28b56e742 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -3,7 +3,7 @@ * joinpath.c * Routines to find all possible paths for processing a set of joins * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -40,54 +40,54 @@ set_join_pathlist_hook_type set_join_pathlist_hook = NULL; (PATH_PARAM_BY_REL_SELF(path, rel) || PATH_PARAM_BY_PARENT(path, rel)) static void try_partial_mergejoin_path(PlannerInfo *root, - RelOptInfo *joinrel, - Path *outer_path, - Path *inner_path, - List *pathkeys, - List *mergeclauses, - List *outersortkeys, - List *innersortkeys, - JoinType jointype, - JoinPathExtraData *extra); + RelOptInfo *joinrel, + Path *outer_path, + Path *inner_path, + List *pathkeys, + List *mergeclauses, + List *outersortkeys, + List *innersortkeys, + JoinType jointype, + JoinPathExtraData *extra); static void sort_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinType jointype, JoinPathExtraData *extra); + RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinType jointype, JoinPathExtraData *extra); static void match_unsorted_outer(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinType jointype, JoinPathExtraData *extra); + RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinType jointype, JoinPathExtraData *extra); static void consider_parallel_nestloop(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - JoinType jointype, - JoinPathExtraData *extra); + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra); static void consider_parallel_mergejoin(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - JoinType jointype, - JoinPathExtraData *extra, - Path *inner_cheapest_total); + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + JoinPathExtraData *extra, + Path *inner_cheapest_total); static void hash_inner_and_outer(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinType jointype, JoinPathExtraData *extra); + RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinType jointype, JoinPathExtraData *extra); static List *select_mergejoin_clauses(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - List *restrictlist, - JoinType jointype, - bool *mergejoin_allowed); + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + List *restrictlist, + JoinType jointype, + bool *mergejoin_allowed); static void generate_mergejoin_paths(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *innerrel, - Path *outerpath, - JoinType jointype, - JoinPathExtraData *extra, - bool useallclauses, - Path *inner_cheapest_total, - List *merge_pathkeys, - bool is_partial); + RelOptInfo *joinrel, + RelOptInfo *innerrel, + Path *outerpath, + JoinType jointype, + JoinPathExtraData *extra, + bool useallclauses, + Path *inner_cheapest_total, + List *merge_pathkeys, + bool is_partial); /* @@ -171,6 +171,7 @@ add_paths_to_joinrel(PlannerInfo *root, break; case JOIN_UNIQUE_OUTER: extra.inner_unique = innerrel_is_unique(root, + joinrel->relids, outerrel->relids, innerrel, JOIN_INNER, @@ -179,6 +180,7 @@ add_paths_to_joinrel(PlannerInfo *root, break; default: extra.inner_unique = innerrel_is_unique(root, + joinrel->relids, outerrel->relids, innerrel, jointype, @@ -207,7 +209,7 @@ add_paths_to_joinrel(PlannerInfo *root, * for cost estimation. These will be the same for all paths. */ if (jointype == JOIN_SEMI || jointype == JOIN_ANTI || extra.inner_unique) - compute_semi_anti_join_factors(root, outerrel, innerrel, + compute_semi_anti_join_factors(root, joinrel, outerrel, innerrel, jointype, sjinfo, restrictlist, &extra.semifactors); @@ -496,7 +498,7 @@ try_partial_nestloop_path(PlannerInfo *root, /* * The inner and outer paths are parameterized, if at all, by the top * level parents, not the child relations, so we must use those relids - * for our paramaterization tests. + * for our parameterization tests. */ if (outerrel->top_parent_relids) outerrelids = outerrel->top_parent_relids; @@ -1700,7 +1702,7 @@ hash_inner_and_outer(PlannerInfo *root, * If processing an outer join, only use its own join clauses for * hashing. For inner joins we need not be so picky. */ - if (isouterjoin && restrictinfo->is_pushed_down) + if (isouterjoin && RINFO_IS_PUSHED_DOWN(restrictinfo, joinrel->relids)) continue; if (!restrictinfo->can_join || @@ -1865,9 +1867,12 @@ hash_inner_and_outer(PlannerInfo *root, /* * Can we use a partial inner plan too, so that we can build a - * shared hash table in parallel? + * shared hash table in parallel? We can't handle + * JOIN_UNIQUE_INNER because we can't guarantee uniqueness. */ - if (innerrel->partial_pathlist != NIL && enable_parallel_hash) + if (innerrel->partial_pathlist != NIL && + save_jointype != JOIN_UNIQUE_INNER && + enable_parallel_hash) { cheapest_partial_inner = (Path *) linitial(innerrel->partial_pathlist); @@ -1947,7 +1952,7 @@ select_mergejoin_clauses(PlannerInfo *root, * we don't set have_nonmergeable_joinclause here because pushed-down * clauses will become otherquals not joinquals.) */ - if (isouterjoin && restrictinfo->is_pushed_down) + if (isouterjoin && RINFO_IS_PUSHED_DOWN(restrictinfo, joinrel->relids)) continue; /* Check that clause is a mergeable operator clause */ diff --git a/src/backend/optimizer/path/joinrels.c b/src/backend/optimizer/path/joinrels.c index 2e289d475ed..6a480ab7644 100644 --- a/src/backend/optimizer/path/joinrels.c +++ b/src/backend/optimizer/path/joinrels.c @@ -3,7 +3,7 @@ * joinrels.c * Routines to determine which relations should be joined * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,36 +15,39 @@ #include "postgres.h" #include "miscadmin.h" -#include "catalog/partition.h" -#include "optimizer/clauses.h" +#include "optimizer/appendinfo.h" #include "optimizer/joininfo.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" -#include "optimizer/prep.h" +#include "partitioning/partbounds.h" #include "utils/lsyscache.h" #include "utils/memutils.h" static void make_rels_by_clause_joins(PlannerInfo *root, - RelOptInfo *old_rel, - ListCell *other_rels); + RelOptInfo *old_rel, + List *other_rels_list, + ListCell *other_rels); static void make_rels_by_clauseless_joins(PlannerInfo *root, - RelOptInfo *old_rel, - ListCell *other_rels); + RelOptInfo *old_rel, + List *other_rels); static bool has_join_restriction(PlannerInfo *root, RelOptInfo *rel); static bool has_legal_joinclause(PlannerInfo *root, RelOptInfo *rel); -static bool is_dummy_rel(RelOptInfo *rel); static bool restriction_is_constant_false(List *restrictlist, - bool only_pushed_down); + RelOptInfo *joinrel, + bool only_pushed_down); static void populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, - RelOptInfo *rel2, RelOptInfo *joinrel, - SpecialJoinInfo *sjinfo, List *restrictlist); + RelOptInfo *rel2, RelOptInfo *joinrel, + SpecialJoinInfo *sjinfo, List *restrictlist); static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, - RelOptInfo *rel2, RelOptInfo *joinrel, - SpecialJoinInfo *parent_sjinfo, - List *parent_restrictlist); -static int match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel, - bool strict_op); + RelOptInfo *rel2, RelOptInfo *joinrel, + SpecialJoinInfo *parent_sjinfo, + List *parent_restrictlist); +static SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root, + SpecialJoinInfo *parent_sjinfo, + Relids left_relids, Relids right_relids); +static int match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel, + bool strict_op); /* @@ -99,15 +102,23 @@ join_search_one_level(PlannerInfo *root, int level) * to each initial rel they don't already include but have a join * clause or restriction with. */ + List *other_rels_list; ListCell *other_rels; if (level == 2) /* consider remaining initial rels */ - other_rels = lnext(r); + { + other_rels_list = joinrels[level - 1]; + other_rels = lnext(other_rels_list, r); + } else /* consider all initial rels */ - other_rels = list_head(joinrels[1]); + { + other_rels_list = joinrels[1]; + other_rels = list_head(other_rels_list); + } make_rels_by_clause_joins(root, old_rel, + other_rels_list, other_rels); } else @@ -126,7 +137,7 @@ join_search_one_level(PlannerInfo *root, int level) */ make_rels_by_clauseless_joins(root, old_rel, - list_head(joinrels[1])); + joinrels[1]); } } @@ -152,6 +163,7 @@ join_search_one_level(PlannerInfo *root, int level) foreach(r, joinrels[k]) { RelOptInfo *old_rel = (RelOptInfo *) lfirst(r); + List *other_rels_list; ListCell *other_rels; ListCell *r2; @@ -165,11 +177,18 @@ join_search_one_level(PlannerInfo *root, int level) continue; if (k == other_level) - other_rels = lnext(r); /* only consider remaining rels */ + { + /* only consider remaining rels */ + other_rels_list = joinrels[k]; + other_rels = lnext(other_rels_list, r); + } else - other_rels = list_head(joinrels[other_level]); + { + other_rels_list = joinrels[other_level]; + other_rels = list_head(other_rels_list); + } - for_each_cell(r2, other_rels) + for_each_cell(r2, other_rels_list, other_rels) { RelOptInfo *new_rel = (RelOptInfo *) lfirst(r2); @@ -221,7 +240,7 @@ join_search_one_level(PlannerInfo *root, int level) make_rels_by_clauseless_joins(root, old_rel, - list_head(joinrels[1])); + joinrels[1]); } /*---------- @@ -263,8 +282,9 @@ join_search_one_level(PlannerInfo *root, int level) * automatically ensures that each new joinrel is only added to the list once. * * 'old_rel' is the relation entry for the relation to be joined - * 'other_rels': the first cell in a linked list containing the other + * 'other_rels_list': a list containing the other * rels to be considered for joining + * 'other_rels': the first cell to be considered * * Currently, this is only used with initial rels in other_rels, but it * will work for joining to joinrels too. @@ -272,11 +292,12 @@ join_search_one_level(PlannerInfo *root, int level) static void make_rels_by_clause_joins(PlannerInfo *root, RelOptInfo *old_rel, + List *other_rels_list, ListCell *other_rels) { ListCell *l; - for_each_cell(l, other_rels) + for_each_cell(l, other_rels_list, other_rels) { RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); @@ -297,8 +318,7 @@ make_rels_by_clause_joins(PlannerInfo *root, * The join rels are returned in root->join_rel_level[join_cur_level]. * * 'old_rel' is the relation entry for the relation to be joined - * 'other_rels': the first cell of a linked list containing the - * other rels to be considered for joining + * 'other_rels': a list containing the other rels to be considered for joining * * Currently, this is only used with initial rels in other_rels, but it would * work for joining to joinrels too. @@ -306,11 +326,11 @@ make_rels_by_clause_joins(PlannerInfo *root, static void make_rels_by_clauseless_joins(PlannerInfo *root, RelOptInfo *old_rel, - ListCell *other_rels) + List *other_rels) { ListCell *l; - for_each_cell(l, other_rels) + foreach(l, other_rels) { RelOptInfo *other_rel = (RelOptInfo *) lfirst(l); @@ -621,6 +641,10 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(l); + /* ignore full joins --- their ordering is predetermined */ + if (sjinfo->jointype == JOIN_FULL) + continue; + if (bms_overlap(sjinfo->min_lefthand, join_plus_rhs) && !bms_is_subset(sjinfo->min_righthand, join_plus_rhs)) { @@ -628,15 +652,6 @@ join_is_legal(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, sjinfo->min_righthand); more = true; } - /* full joins constrain both sides symmetrically */ - if (sjinfo->jointype == JOIN_FULL && - bms_overlap(sjinfo->min_righthand, join_plus_rhs) && - !bms_is_subset(sjinfo->min_lefthand, join_plus_rhs)) - { - join_plus_rhs = bms_add_members(join_plus_rhs, - sjinfo->min_lefthand); - more = true; - } } } while (more); if (bms_overlap(join_plus_rhs, join_lateral_rels)) @@ -780,7 +795,7 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, { case JOIN_INNER: if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || - restriction_is_constant_false(restrictlist, false)) + restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; @@ -794,12 +809,12 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, break; case JOIN_LEFT: if (is_dummy_rel(rel1) || - restriction_is_constant_false(restrictlist, true)) + restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; } - if (restriction_is_constant_false(restrictlist, false) && + if (restriction_is_constant_false(restrictlist, joinrel, false) && bms_is_subset(rel2->relids, sjinfo->syn_righthand)) mark_dummy_rel(rel2); add_paths_to_joinrel(root, joinrel, rel1, rel2, @@ -811,7 +826,7 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, break; case JOIN_FULL: if ((is_dummy_rel(rel1) && is_dummy_rel(rel2)) || - restriction_is_constant_false(restrictlist, true)) + restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; @@ -847,7 +862,7 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, bms_is_subset(sjinfo->min_righthand, rel2->relids)) { if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || - restriction_is_constant_false(restrictlist, false)) + restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; @@ -870,7 +885,7 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, sjinfo) != NULL) { if (is_dummy_rel(rel1) || is_dummy_rel(rel2) || - restriction_is_constant_false(restrictlist, false)) + restriction_is_constant_false(restrictlist, joinrel, false)) { mark_dummy_rel(joinrel); break; @@ -885,12 +900,12 @@ populate_joinrel_with_paths(PlannerInfo *root, RelOptInfo *rel1, break; case JOIN_ANTI: if (is_dummy_rel(rel1) || - restriction_is_constant_false(restrictlist, true)) + restriction_is_constant_false(restrictlist, joinrel, true)) { mark_dummy_rel(joinrel); break; } - if (restriction_is_constant_false(restrictlist, false) && + if (restriction_is_constant_false(restrictlist, joinrel, false) && bms_is_subset(rel2->relids, sjinfo->syn_righthand)) mark_dummy_rel(rel2); add_paths_to_joinrel(root, joinrel, rel1, rel2, @@ -1189,10 +1204,38 @@ have_dangerous_phv(PlannerInfo *root, /* * is_dummy_rel --- has relation been proven empty? */ -static bool +bool is_dummy_rel(RelOptInfo *rel) { - return IS_DUMMY_REL(rel); + Path *path; + + /* + * A rel that is known dummy will have just one path that is a childless + * Append. (Even if somehow it has more paths, a childless Append will + * have cost zero and hence should be at the front of the pathlist.) + */ + if (rel->pathlist == NIL) + return false; + path = (Path *) linitial(rel->pathlist); + + /* + * Initially, a dummy path will just be a childless Append. But in later + * planning stages we might stick a ProjectSetPath and/or ProjectionPath + * on top, since Append can't project. Rather than make assumptions about + * which combinations can occur, just descend through whatever we find. + */ + for (;;) + { + if (IsA(path, ProjectionPath)) + path = ((ProjectionPath *) path)->subpath; + else if (IsA(path, ProjectSetPath)) + path = ((ProjectSetPath *) path)->subpath; + else + break; + } + if (IS_DUMMY_APPEND(path)) + return true; + return false; } /* @@ -1230,7 +1273,8 @@ mark_dummy_rel(RelOptInfo *rel) rel->partial_pathlist = NIL; /* Set up the dummy path */ - add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, NULL, + add_path(rel, (Path *) create_append_path(NULL, rel, NIL, NIL, + NIL, rel->lateral_relids, 0, false, NIL, -1)); /* Set or update cheapest_total_path and related fields */ @@ -1249,10 +1293,13 @@ mark_dummy_rel(RelOptInfo *rel) * decide there's no match for an outer row, which is pretty stupid. So, * we need to detect the case. * - * If only_pushed_down is true, then consider only pushed-down quals. + * If only_pushed_down is true, then consider only quals that are pushed-down + * from the point of view of the joinrel. */ static bool -restriction_is_constant_false(List *restrictlist, bool only_pushed_down) +restriction_is_constant_false(List *restrictlist, + RelOptInfo *joinrel, + bool only_pushed_down) { ListCell *lc; @@ -1266,7 +1313,7 @@ restriction_is_constant_false(List *restrictlist, bool only_pushed_down) { RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc); - if (only_pushed_down && !rinfo->is_pushed_down) + if (only_pushed_down && !RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) continue; if (rinfo->clause && IsA(rinfo->clause, Const)) @@ -1305,9 +1352,11 @@ restriction_is_constant_false(List *restrictlist, bool only_pushed_down) */ static void try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, - RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, - List *parent_restrictlist) + RelOptInfo *joinrel, SpecialJoinInfo *parent_sjinfo, + List *parent_restrictlist) { + bool rel1_is_simple = IS_SIMPLE_REL(rel1); + bool rel2_is_simple = IS_SIMPLE_REL(rel2); int nparts; int cnt_parts; @@ -1318,6 +1367,9 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, if (!IS_PARTITIONED_REL(joinrel)) return; + /* The join relation should have consider_partitionwise_join set. */ + Assert(joinrel->consider_partitionwise_join); + /* * Since this join relation is partitioned, all the base relations * participating in this join must be partitioned and so are all the @@ -1326,6 +1378,10 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, Assert(IS_PARTITIONED_REL(rel1) && IS_PARTITIONED_REL(rel2)); Assert(REL_HAS_ALL_PART_PROPS(rel1) && REL_HAS_ALL_PART_PROPS(rel2)); + /* The joining relations should have consider_partitionwise_join set. */ + Assert(rel1->consider_partitionwise_join && + rel2->consider_partitionwise_join); + /* * The partition scheme of the join relation should match that of the * joining relations. @@ -1334,8 +1390,8 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, joinrel->part_scheme == rel2->part_scheme); /* - * Since we allow partitionwise join only when the partition bounds of - * the joining relations exactly match, the partition bounds of the join + * Since we allow partitionwise join only when the partition bounds of the + * joining relations exactly match, the partition bounds of the join * should match those of the joining relations. */ Assert(partition_bounds_equal(joinrel->part_scheme->partnatts, @@ -1358,6 +1414,10 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, { RelOptInfo *child_rel1 = rel1->part_rels[cnt_parts]; RelOptInfo *child_rel2 = rel2->part_rels[cnt_parts]; + bool rel1_empty = (child_rel1 == NULL || + IS_DUMMY_REL(child_rel1)); + bool rel2_empty = (child_rel2 == NULL || + IS_DUMMY_REL(child_rel2)); SpecialJoinInfo *child_sjinfo; List *child_restrictlist; RelOptInfo *child_joinrel; @@ -1365,6 +1425,72 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, AppendRelInfo **appinfos; int nappinfos; + /* + * Check for cases where we can prove that this segment of the join + * returns no rows, due to one or both inputs being empty (including + * inputs that have been pruned away entirely). If so just ignore it. + * These rules are equivalent to populate_joinrel_with_paths's rules + * for dummy input relations. + */ + switch (parent_sjinfo->jointype) + { + case JOIN_INNER: + case JOIN_SEMI: + if (rel1_empty || rel2_empty) + continue; /* ignore this join segment */ + break; + case JOIN_LEFT: + case JOIN_ANTI: + if (rel1_empty) + continue; /* ignore this join segment */ + break; + case JOIN_FULL: + if (rel1_empty && rel2_empty) + continue; /* ignore this join segment */ + break; + default: + /* other values not expected here */ + elog(ERROR, "unrecognized join type: %d", + (int) parent_sjinfo->jointype); + break; + } + + /* + * If a child has been pruned entirely then we can't generate paths + * for it, so we have to reject partitionwise joining unless we were + * able to eliminate this partition above. + */ + if (child_rel1 == NULL || child_rel2 == NULL) + { + /* + * Mark the joinrel as unpartitioned so that later functions treat + * it correctly. + */ + joinrel->nparts = 0; + return; + } + + /* + * If a leaf relation has consider_partitionwise_join=false, it means + * that it's a dummy relation for which we skipped setting up tlist + * expressions and adding EC members in set_append_rel_size(), so + * again we have to fail here. + */ + if (rel1_is_simple && !child_rel1->consider_partitionwise_join) + { + Assert(child_rel1->reloptkind == RELOPT_OTHER_MEMBER_REL); + Assert(IS_DUMMY_REL(child_rel1)); + joinrel->nparts = 0; + return; + } + if (rel2_is_simple && !child_rel2->consider_partitionwise_join) + { + Assert(child_rel2->reloptkind == RELOPT_OTHER_MEMBER_REL); + Assert(IS_DUMMY_REL(child_rel2)); + joinrel->nparts = 0; + return; + } + /* We should never try to join two overlapping sets of rels. */ Assert(!bms_overlap(child_rel1->relids, child_rel2->relids)); child_joinrelids = bms_union(child_rel1->relids, child_rel2->relids); @@ -1406,13 +1532,56 @@ try_partitionwise_join(PlannerInfo *root, RelOptInfo *rel1, RelOptInfo *rel2, } } +/* + * Construct the SpecialJoinInfo for a child-join by translating + * SpecialJoinInfo for the join between parents. left_relids and right_relids + * are the relids of left and right side of the join respectively. + */ +static SpecialJoinInfo * +build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo, + Relids left_relids, Relids right_relids) +{ + SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo); + AppendRelInfo **left_appinfos; + int left_nappinfos; + AppendRelInfo **right_appinfos; + int right_nappinfos; + + memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo)); + left_appinfos = find_appinfos_by_relids(root, left_relids, + &left_nappinfos); + right_appinfos = find_appinfos_by_relids(root, right_relids, + &right_nappinfos); + + sjinfo->min_lefthand = adjust_child_relids(sjinfo->min_lefthand, + left_nappinfos, left_appinfos); + sjinfo->min_righthand = adjust_child_relids(sjinfo->min_righthand, + right_nappinfos, + right_appinfos); + sjinfo->syn_lefthand = adjust_child_relids(sjinfo->syn_lefthand, + left_nappinfos, left_appinfos); + sjinfo->syn_righthand = adjust_child_relids(sjinfo->syn_righthand, + right_nappinfos, + right_appinfos); + sjinfo->semi_rhs_exprs = (List *) adjust_appendrel_attrs(root, + (Node *) sjinfo->semi_rhs_exprs, + right_nappinfos, + right_appinfos); + + pfree(left_appinfos); + pfree(right_appinfos); + + return sjinfo; +} + /* * Returns true if there exists an equi-join condition for each pair of * partition keys from given relations being joined. */ bool -have_partkey_equi_join(RelOptInfo *rel1, RelOptInfo *rel2, JoinType jointype, - List *restrictlist) +have_partkey_equi_join(RelOptInfo *joinrel, + RelOptInfo *rel1, RelOptInfo *rel2, + JoinType jointype, List *restrictlist) { PartitionScheme part_scheme = rel1->part_scheme; ListCell *lc; @@ -1438,7 +1607,8 @@ have_partkey_equi_join(RelOptInfo *rel1, RelOptInfo *rel2, JoinType jointype, int ipk2; /* If processing an outer join, only use its own join clauses. */ - if (IS_OUTER_JOIN(jointype) && rinfo->is_pushed_down) + if (IS_OUTER_JOIN(jointype) && + RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids)) continue; /* Skip clauses which can not be used for a join. */ @@ -1449,8 +1619,7 @@ have_partkey_equi_join(RelOptInfo *rel1, RelOptInfo *rel2, JoinType jointype, if (!rinfo->mergeopfamilies && !OidIsValid(rinfo->hashjoinoperator)) continue; - opexpr = (OpExpr *) rinfo->clause; - Assert(is_opclause(opexpr)); + opexpr = castNode(OpExpr, rinfo->clause); /* * The equi-join between partition keys is strict if equi-join between diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index ec66cb9c3c5..2f4fea241a0 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -7,7 +7,7 @@ * the nature and use of path keys. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,17 +18,22 @@ #include "postgres.h" #include "access/stratnum.h" +#include "catalog/pg_opfamily.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "nodes/plannodes.h" -#include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" -#include "optimizer/tlist.h" +#include "partitioning/partbounds.h" #include "utils/lsyscache.h" static bool pathkey_is_redundant(PathKey *new_pathkey, List *pathkeys); +static bool matches_boolean_partition_clause(RestrictInfo *rinfo, + RelOptInfo *partrel, + int partkeycol); +static Var *find_var_for_subquery_tle(RelOptInfo *rel, TargetEntry *tle); static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey); @@ -43,9 +48,7 @@ static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey); * entry if there's not one already. * * Note that this function must not be used until after we have completed - * merging EquivalenceClasses. (We don't try to enforce that here; instead, - * equivclass.c will complain if a merge occurs after root->canon_pathkeys - * has become nonempty.) + * merging EquivalenceClasses. */ PathKey * make_canonical_pathkey(PlannerInfo *root, @@ -56,6 +59,10 @@ make_canonical_pathkey(PlannerInfo *root, ListCell *lc; MemoryContext oldcontext; + /* Can't make canonical pathkeys if the set of ECs might still change */ + if (!root->ec_merging_done) + elog(ERROR, "too soon to build canonical pathkeys"); + /* The passed eclass might be non-canonical, so chase up to the top */ while (eclass->ec_merged) eclass = eclass->ec_merged; @@ -547,6 +554,165 @@ build_index_pathkeys(PlannerInfo *root, return retval; } +/* + * partkey_is_bool_constant_for_query + * + * If a partition key column is constrained to have a constant value by the + * query's WHERE conditions, then it's irrelevant for sort-order + * considerations. Usually that means we have a restriction clause + * WHERE partkeycol = constant, which gets turned into an EquivalenceClass + * containing a constant, which is recognized as redundant by + * build_partition_pathkeys(). But if the partition key column is a + * boolean variable (or expression), then we are not going to see such a + * WHERE clause, because expression preprocessing will have simplified it + * to "WHERE partkeycol" or "WHERE NOT partkeycol". So we are not going + * to have a matching EquivalenceClass (unless the query also contains + * "ORDER BY partkeycol"). To allow such cases to work the same as they would + * for non-boolean values, this function is provided to detect whether the + * specified partition key column matches a boolean restriction clause. + */ +static bool +partkey_is_bool_constant_for_query(RelOptInfo *partrel, int partkeycol) +{ + PartitionScheme partscheme = partrel->part_scheme; + ListCell *lc; + + /* If the partkey isn't boolean, we can't possibly get a match */ + if (!IsBooleanOpfamily(partscheme->partopfamily[partkeycol])) + return false; + + /* Check each restriction clause for the partitioned rel */ + foreach(lc, partrel->baserestrictinfo) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + + /* Ignore pseudoconstant quals, they won't match */ + if (rinfo->pseudoconstant) + continue; + + /* See if we can match the clause's expression to the partkey column */ + if (matches_boolean_partition_clause(rinfo, partrel, partkeycol)) + return true; + } + + return false; +} + +/* + * matches_boolean_partition_clause + * Determine if the boolean clause described by rinfo matches + * partrel's partkeycol-th partition key column. + * + * "Matches" can be either an exact match (equivalent to partkey = true), + * or a NOT above an exact match (equivalent to partkey = false). + */ +static bool +matches_boolean_partition_clause(RestrictInfo *rinfo, + RelOptInfo *partrel, int partkeycol) +{ + Node *clause = (Node *) rinfo->clause; + Node *partexpr = (Node *) linitial(partrel->partexprs[partkeycol]); + + /* Direct match? */ + if (equal(partexpr, clause)) + return true; + /* NOT clause? */ + else if (is_notclause(clause)) + { + Node *arg = (Node *) get_notclausearg((Expr *) clause); + + if (equal(partexpr, arg)) + return true; + } + + return false; +} + +/* + * build_partition_pathkeys + * Build a pathkeys list that describes the ordering induced by the + * partitions of partrel, under either forward or backward scan + * as per scandir. + * + * Caller must have checked that the partitions are properly ordered, + * as detected by partitions_are_ordered(). + * + * Sets *partialkeys to true if pathkeys were only built for a prefix of the + * partition key, or false if the pathkeys include all columns of the + * partition key. + */ +List * +build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel, + ScanDirection scandir, bool *partialkeys) +{ + List *retval = NIL; + PartitionScheme partscheme = partrel->part_scheme; + int i; + + Assert(partscheme != NULL); + Assert(partitions_are_ordered(partrel->boundinfo, partrel->nparts)); + /* For now, we can only cope with baserels */ + Assert(IS_SIMPLE_REL(partrel)); + + for (i = 0; i < partscheme->partnatts; i++) + { + PathKey *cpathkey; + Expr *keyCol = (Expr *) linitial(partrel->partexprs[i]); + + /* + * Try to make a canonical pathkey for this partkey. + * + * We're considering a baserel scan, so nullable_relids should be + * NULL. Also, we assume the PartitionDesc lists any NULL partition + * last, so we treat the scan like a NULLS LAST index: we have + * nulls_first for backwards scan only. + */ + cpathkey = make_pathkey_from_sortinfo(root, + keyCol, + NULL, + partscheme->partopfamily[i], + partscheme->partopcintype[i], + partscheme->partcollation[i], + ScanDirectionIsBackward(scandir), + ScanDirectionIsBackward(scandir), + 0, + partrel->relids, + false); + + + if (cpathkey) + { + /* + * We found the sort key in an EquivalenceClass, so it's relevant + * for this query. Add it to list, unless it's redundant. + */ + if (!pathkey_is_redundant(cpathkey, retval)) + retval = lappend(retval, cpathkey); + } + else + { + /* + * Boolean partition keys might be redundant even if they do not + * appear in an EquivalenceClass, because of our special treatment + * of boolean equality conditions --- see the comment for + * partkey_is_bool_constant_for_query(). If that applies, we can + * continue to examine lower-order partition keys. Otherwise, the + * sort key is not an interesting sort order for this query, so we + * should stop considering partition columns; any lower-order sort + * keys won't be useful either. + */ + if (!partkey_is_bool_constant_for_query(partrel, i)) + { + *partialkeys = true; + return retval; + } + } + } + + *partialkeys = false; + return retval; +} + /* * build_expression_pathkey * Build a pathkeys list that describes an ordering by a single expression @@ -608,9 +774,11 @@ build_expression_pathkey(PlannerInfo *root, * 'subquery_pathkeys': the subquery's output pathkeys, in its terms. * 'subquery_tlist': the subquery's output targetlist, in its terms. * - * It is not necessary for caller to do truncate_useless_pathkeys(), - * because we select keys in a way that takes usefulness of the keys into - * account. + * We intentionally don't do truncate_useless_pathkeys() here, because there + * are situations where seeing the raw ordering of the subquery is helpful. + * For example, if it returns ORDER BY x DESC, that may prompt us to + * construct a mergejoin using DESC order rather than ASC order; but the + * right_merge_direction heuristic would have us throw the knowledge away. */ List * convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, @@ -636,22 +804,22 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, * that same targetlist entry. */ TargetEntry *tle; + Var *outer_var; if (sub_eclass->ec_sortref == 0) /* can't happen */ elog(ERROR, "volatile EquivalenceClass has no sortref"); tle = get_sortgroupref_tle(sub_eclass->ec_sortref, subquery_tlist); Assert(tle); - /* resjunk items aren't visible to outer query */ - if (!tle->resjunk) + /* Is TLE actually available to the outer query? */ + outer_var = find_var_for_subquery_tle(rel, tle); + if (outer_var) { /* We can represent this sub_pathkey */ EquivalenceMember *sub_member; - Expr *outer_expr; EquivalenceClass *outer_ec; Assert(list_length(sub_eclass->ec_members) == 1); sub_member = (EquivalenceMember *) linitial(sub_eclass->ec_members); - outer_expr = (Expr *) makeVarFromTargetEntry(rel->relid, tle); /* * Note: it might look funny to be setting sortref = 0 for a @@ -665,7 +833,7 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, */ outer_ec = get_eclass_for_sort_expr(root, - outer_expr, + (Expr *) outer_var, NULL, sub_eclass->ec_opfamilies, sub_member->em_datatype, @@ -722,14 +890,15 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, foreach(k, subquery_tlist) { TargetEntry *tle = (TargetEntry *) lfirst(k); + Var *outer_var; Expr *tle_expr; - Expr *outer_expr; EquivalenceClass *outer_ec; PathKey *outer_pk; int score; - /* resjunk items aren't visible to outer query */ - if (tle->resjunk) + /* Is TLE actually available to the outer query? */ + outer_var = find_var_for_subquery_tle(rel, tle); + if (!outer_var) continue; /* @@ -744,16 +913,9 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, if (!equal(tle_expr, sub_expr)) continue; - /* - * Build a representation of this targetlist entry as an - * outer Var. - */ - outer_expr = (Expr *) makeVarFromTargetEntry(rel->relid, - tle); - - /* See if we have a matching EC for that */ + /* See if we have a matching EC for the TLE */ outer_ec = get_eclass_for_sort_expr(root, - outer_expr, + (Expr *) outer_var, NULL, sub_eclass->ec_opfamilies, sub_expr_type, @@ -810,6 +972,41 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, return retval; } +/* + * find_var_for_subquery_tle + * + * If the given subquery tlist entry is due to be emitted by the subquery's + * scan node, return a Var for it, else return NULL. + * + * We need this to ensure that we don't return pathkeys describing values + * that are unavailable above the level of the subquery scan. + */ +static Var * +find_var_for_subquery_tle(RelOptInfo *rel, TargetEntry *tle) +{ + ListCell *lc; + + /* If the TLE is resjunk, it's certainly not visible to the outer query */ + if (tle->resjunk) + return NULL; + + /* Search the rel's targetlist to see what it will return */ + foreach(lc, rel->reltarget->exprs) + { + Var *var = (Var *) lfirst(lc); + + /* Ignore placeholders */ + if (!IsA(var, Var)) + continue; + Assert(var->varno == rel->relid); + + /* If we find a Var referencing this TLE, we're good */ + if (var->varattno == tle->resno) + return copyObject(var); /* Make a copy for safety */ + } + return NULL; +} + /* * build_join_pathkeys * Build the path keys for a join relation constructed by mergejoin or @@ -1334,7 +1531,7 @@ make_inner_pathkeys_for_merge(PlannerInfo *root, if (!lop) elog(ERROR, "too few pathkeys for mergeclauses"); opathkey = (PathKey *) lfirst(lop); - lop = lnext(lop); + lop = lnext(outer_pathkeys, lop); lastoeclass = opathkey->pk_eclass; if (oeclass != lastoeclass) elog(ERROR, "outer pathkeys do not match mergeclause"); @@ -1414,7 +1611,7 @@ trim_mergeclauses_for_inner_pathkeys(PlannerInfo *root, lip = list_head(pathkeys); pathkey = (PathKey *) lfirst(lip); pathkey_ec = pathkey->pk_eclass; - lip = lnext(lip); + lip = lnext(pathkeys, lip); matched_pathkey = false; /* Scan mergeclauses to see how many we can use */ @@ -1441,7 +1638,7 @@ trim_mergeclauses_for_inner_pathkeys(PlannerInfo *root, break; pathkey = (PathKey *) lfirst(lip); pathkey_ec = pathkey->pk_eclass; - lip = lnext(lip); + lip = lnext(pathkeys, lip); matched_pathkey = false; } diff --git a/src/backend/optimizer/path/tidpath.c b/src/backend/optimizer/path/tidpath.c index 3bb5b8def60..466e9960119 100644 --- a/src/backend/optimizer/path/tidpath.c +++ b/src/backend/optimizer/path/tidpath.c @@ -12,20 +12,19 @@ * this allows * WHERE ctid IN (tid1, tid2, ...) * + * As with indexscans, our definition of "pseudoconstant" is pretty liberal: + * we allow anything that doesn't involve a volatile function or a Var of + * the relation under consideration. Vars belonging to other relations of + * the query are allowed, giving rise to parameterized TID scans. + * * We also support "WHERE CURRENT OF cursor" conditions (CurrentOfExpr), * which amount to "CTID = run-time-determined-TID". These could in * theory be translated to a simple comparison of CTID to the result of * a function, but in practice it works better to keep the special node * representation all the way through to execution. * - * There is currently no special support for joins involving CTID; in - * particular nothing corresponding to best_inner_indexscan(). Since it's - * not very useful to store TIDs of one table in another table, there - * doesn't seem to be enough use-case to justify adding a lot of code - * for that. - * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -41,85 +40,100 @@ #include "catalog/pg_type.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/restrictinfo.h" -static bool IsTidEqualClause(OpExpr *node, int varno); -static bool IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno); -static List *TidQualFromExpr(Node *expr, int varno); -static List *TidQualFromBaseRestrictinfo(RelOptInfo *rel); - +/* + * Does this Var represent the CTID column of the specified baserel? + */ +static inline bool +IsCTIDVar(Var *var, RelOptInfo *rel) +{ + /* The vartype check is strictly paranoia */ + if (var->varattno == SelfItemPointerAttributeNumber && + var->vartype == TIDOID && + var->varno == rel->relid && + var->varlevelsup == 0) + return true; + return false; +} /* - * Check to see if an opclause is of the form + * Check to see if a RestrictInfo is of the form * CTID = pseudoconstant * or * pseudoconstant = CTID - * - * We check that the CTID Var belongs to relation "varno". That is probably - * redundant considering this is only applied to restriction clauses, but - * let's be safe. + * where the CTID Var belongs to relation "rel", and nothing on the + * other side of the clause does. */ static bool -IsTidEqualClause(OpExpr *node, int varno) +IsTidEqualClause(RestrictInfo *rinfo, RelOptInfo *rel) { + OpExpr *node; Node *arg1, *arg2, *other; - Var *var; + Relids other_relids; + + /* Must be an OpExpr */ + if (!is_opclause(rinfo->clause)) + return false; + node = (OpExpr *) rinfo->clause; /* Operator must be tideq */ if (node->opno != TIDEqualOperator) return false; - if (list_length(node->args) != 2) - return false; + Assert(list_length(node->args) == 2); arg1 = linitial(node->args); arg2 = lsecond(node->args); /* Look for CTID as either argument */ other = NULL; - if (arg1 && IsA(arg1, Var)) + other_relids = NULL; + if (arg1 && IsA(arg1, Var) && + IsCTIDVar((Var *) arg1, rel)) { - var = (Var *) arg1; - if (var->varattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID && - var->varno == varno && - var->varlevelsup == 0) - other = arg2; + other = arg2; + other_relids = rinfo->right_relids; } - if (!other && arg2 && IsA(arg2, Var)) + if (!other && arg2 && IsA(arg2, Var) && + IsCTIDVar((Var *) arg2, rel)) { - var = (Var *) arg2; - if (var->varattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID && - var->varno == varno && - var->varlevelsup == 0) - other = arg1; + other = arg1; + other_relids = rinfo->left_relids; } if (!other) return false; - if (exprType(other) != TIDOID) - return false; /* probably can't happen */ /* The other argument must be a pseudoconstant */ - if (!is_pseudo_constant_clause(other)) + if (bms_is_member(rel->relid, other_relids) || + contain_volatile_functions(other)) return false; return true; /* success */ } /* - * Check to see if a clause is of the form + * Check to see if a RestrictInfo is of the form * CTID = ANY (pseudoconstant_array) + * where the CTID Var belongs to relation "rel", and nothing on the + * other side of the clause does. */ static bool -IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno) +IsTidEqualAnyClause(RestrictInfo *rinfo, RelOptInfo *rel) { + ScalarArrayOpExpr *node; Node *arg1, *arg2; + /* Must be a ScalarArrayOpExpr */ + if (!(rinfo->clause && IsA(rinfo->clause, ScalarArrayOpExpr))) + return false; + node = (ScalarArrayOpExpr *) rinfo->clause; + /* Operator must be tideq */ if (node->opno != TIDEqualOperator) return false; @@ -130,117 +144,235 @@ IsTidEqualAnyClause(ScalarArrayOpExpr *node, int varno) arg2 = lsecond(node->args); /* CTID must be first argument */ - if (arg1 && IsA(arg1, Var)) + if (arg1 && IsA(arg1, Var) && + IsCTIDVar((Var *) arg1, rel)) { - Var *var = (Var *) arg1; + /* The other argument must be a pseudoconstant */ + if (bms_is_member(rel->relid, pull_varnos(arg2)) || + contain_volatile_functions(arg2)) + return false; - if (var->varattno == SelfItemPointerAttributeNumber && - var->vartype == TIDOID && - var->varno == varno && - var->varlevelsup == 0) - { - /* The other argument must be a pseudoconstant */ - if (is_pseudo_constant_clause(arg2)) - return true; /* success */ - } + return true; /* success */ } return false; } /* - * Extract a set of CTID conditions from the given qual expression + * Check to see if a RestrictInfo is a CurrentOfExpr referencing "rel". + */ +static bool +IsCurrentOfClause(RestrictInfo *rinfo, RelOptInfo *rel) +{ + CurrentOfExpr *node; + + /* Must be a CurrentOfExpr */ + if (!(rinfo->clause && IsA(rinfo->clause, CurrentOfExpr))) + return false; + node = (CurrentOfExpr *) rinfo->clause; + + /* If it references this rel, we're good */ + if (node->cvarno == rel->relid) + return true; + + return false; +} + +/* + * Extract a set of CTID conditions from the given RestrictInfo + * + * Returns a List of CTID qual RestrictInfos for the specified rel (with + * implicit OR semantics across the list), or NIL if there are no usable + * conditions. * - * Returns a List of CTID qual expressions (with implicit OR semantics - * across the list), or NIL if there are no usable conditions. + * This function considers only base cases; AND/OR combination is handled + * below. Therefore the returned List never has more than one element. + * (Using a List may seem a bit weird, but it simplifies the caller.) + */ +static List * +TidQualFromRestrictInfo(RestrictInfo *rinfo, RelOptInfo *rel) +{ + /* + * We may ignore pseudoconstant clauses (they can't contain Vars, so could + * not match anyway). + */ + if (rinfo->pseudoconstant) + return NIL; + + /* + * If clause must wait till after some lower-security-level restriction + * clause, reject it. + */ + if (!restriction_is_securely_promotable(rinfo, rel)) + return NIL; + + /* + * Check all base cases. If we get a match, return the clause. + */ + if (IsTidEqualClause(rinfo, rel) || + IsTidEqualAnyClause(rinfo, rel) || + IsCurrentOfClause(rinfo, rel)) + return list_make1(rinfo); + + return NIL; +} + +/* + * Extract a set of CTID conditions from implicit-AND List of RestrictInfos * - * If the expression is an AND clause, we can use a CTID condition - * from any sub-clause. If it is an OR clause, we must be able to - * extract a CTID condition from every sub-clause, or we can't use it. + * Returns a List of CTID qual RestrictInfos for the specified rel (with + * implicit OR semantics across the list), or NIL if there are no usable + * conditions. * - * In theory, in the AND case we could get CTID conditions from different - * sub-clauses, in which case we could try to pick the most efficient one. - * In practice, such usage seems very unlikely, so we don't bother; we - * just exit as soon as we find the first candidate. + * This function is just concerned with handling AND/OR recursion. */ static List * -TidQualFromExpr(Node *expr, int varno) +TidQualFromRestrictInfoList(List *rlist, RelOptInfo *rel) { List *rlst = NIL; ListCell *l; - if (is_opclause(expr)) - { - /* base case: check for tideq opclause */ - if (IsTidEqualClause((OpExpr *) expr, varno)) - rlst = list_make1(expr); - } - else if (expr && IsA(expr, ScalarArrayOpExpr)) - { - /* another base case: check for tid = ANY clause */ - if (IsTidEqualAnyClause((ScalarArrayOpExpr *) expr, varno)) - rlst = list_make1(expr); - } - else if (expr && IsA(expr, CurrentOfExpr)) - { - /* another base case: check for CURRENT OF on this rel */ - if (((CurrentOfExpr *) expr)->cvarno == varno) - rlst = list_make1(expr); - } - else if (and_clause(expr)) - { - foreach(l, ((BoolExpr *) expr)->args) - { - rlst = TidQualFromExpr((Node *) lfirst(l), varno); - if (rlst) - break; - } - } - else if (or_clause(expr)) + foreach(l, rlist) { - foreach(l, ((BoolExpr *) expr)->args) + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + + if (restriction_is_or_clause(rinfo)) { - List *frtn = TidQualFromExpr((Node *) lfirst(l), varno); + ListCell *j; - if (frtn) - rlst = list_concat(rlst, frtn); - else + /* + * We must be able to extract a CTID condition from every + * sub-clause of an OR, or we can't use it. + */ + foreach(j, ((BoolExpr *) rinfo->orclause)->args) { - if (rlst) - list_free(rlst); - rlst = NIL; - break; + Node *orarg = (Node *) lfirst(j); + List *sublist; + + /* OR arguments should be ANDs or sub-RestrictInfos */ + if (is_andclause(orarg)) + { + List *andargs = ((BoolExpr *) orarg)->args; + + /* Recurse in case there are sub-ORs */ + sublist = TidQualFromRestrictInfoList(andargs, rel); + } + else + { + RestrictInfo *rinfo = castNode(RestrictInfo, orarg); + + Assert(!restriction_is_or_clause(rinfo)); + sublist = TidQualFromRestrictInfo(rinfo, rel); + } + + /* + * If nothing found in this arm, we can't do anything with + * this OR clause. + */ + if (sublist == NIL) + { + rlst = NIL; /* forget anything we had */ + break; /* out of loop over OR args */ + } + + /* + * OK, continue constructing implicitly-OR'ed result list. + */ + rlst = list_concat(rlst, sublist); } } + else + { + /* Not an OR clause, so handle base cases */ + rlst = TidQualFromRestrictInfo(rinfo, rel); + } + + /* + * Stop as soon as we find any usable CTID condition. In theory we + * could get CTID equality conditions from different AND'ed clauses, + * in which case we could try to pick the most efficient one. In + * practice, such usage seems very unlikely, so we don't bother; we + * just exit as soon as we find the first candidate. + */ + if (rlst) + break; } + return rlst; } /* - * Extract a set of CTID conditions from the rel's baserestrictinfo list + * Given a list of join clauses involving our rel, create a parameterized + * TidPath for each one that is a suitable TidEqual clause. + * + * In principle we could combine clauses that reference the same outer rels, + * but it doesn't seem like such cases would arise often enough to be worth + * troubling over. */ -static List * -TidQualFromBaseRestrictinfo(RelOptInfo *rel) +static void +BuildParameterizedTidPaths(PlannerInfo *root, RelOptInfo *rel, List *clauses) { - List *rlst = NIL; ListCell *l; - foreach(l, rel->baserestrictinfo) + foreach(l, clauses) { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + List *tidquals; + Relids required_outer; /* - * If clause must wait till after some lower-security-level - * restriction clause, reject it. + * Validate whether each clause is actually usable; we must check this + * even when examining clauses generated from an EquivalenceClass, + * since they might not satisfy the restriction on not having Vars of + * our rel on the other side, or somebody might've built an operator + * class that accepts type "tid" but has other operators in it. + * + * We currently consider only TidEqual join clauses. In principle we + * might find a suitable ScalarArrayOpExpr in the rel's joininfo list, + * but it seems unlikely to be worth expending the cycles to check. + * And we definitely won't find a CurrentOfExpr here. Hence, we don't + * use TidQualFromRestrictInfo; but this must match that function + * otherwise. */ - if (!restriction_is_securely_promotable(rinfo, rel)) + if (rinfo->pseudoconstant || + !restriction_is_securely_promotable(rinfo, rel) || + !IsTidEqualClause(rinfo, rel)) continue; - rlst = TidQualFromExpr((Node *) rinfo->clause, rel->relid); - if (rlst) - break; + /* + * Check if clause can be moved to this rel; this is probably + * redundant when considering EC-derived clauses, but we must check it + * for "loose" join clauses. + */ + if (!join_clause_is_movable_to(rinfo, rel)) + continue; + + /* OK, make list of clauses for this path */ + tidquals = list_make1(rinfo); + + /* Compute required outer rels for this path */ + required_outer = bms_union(rinfo->required_relids, rel->lateral_relids); + required_outer = bms_del_member(required_outer, rel->relid); + + add_path(rel, (Path *) create_tidscan_path(root, rel, tidquals, + required_outer)); } - return rlst; +} + +/* + * Test whether an EquivalenceClass member matches our rel's CTID Var. + * + * This is a callback for use by generate_implied_equalities_for_column. + */ +static bool +ec_member_matches_ctid(PlannerInfo *root, RelOptInfo *rel, + EquivalenceClass *ec, EquivalenceMember *em, + void *arg) +{ + if (em->em_expr && IsA(em->em_expr, Var) && + IsCTIDVar((Var *) em->em_expr, rel)) + return true; + return false; } /* @@ -252,19 +384,50 @@ TidQualFromBaseRestrictinfo(RelOptInfo *rel) void create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel) { - Relids required_outer; List *tidquals; /* - * We don't support pushing join clauses into the quals of a tidscan, but - * it could still have required parameterization due to LATERAL refs in - * its tlist. + * If any suitable quals exist in the rel's baserestrict list, generate a + * plain (unparameterized) TidPath with them. */ - required_outer = rel->lateral_relids; - - tidquals = TidQualFromBaseRestrictinfo(rel); + tidquals = TidQualFromRestrictInfoList(rel->baserestrictinfo, rel); if (tidquals) + { + /* + * This path uses no join clauses, but it could still have required + * parameterization due to LATERAL refs in its tlist. + */ + Relids required_outer = rel->lateral_relids; + add_path(rel, (Path *) create_tidscan_path(root, rel, tidquals, required_outer)); + } + + /* + * Try to generate parameterized TidPaths using equality clauses extracted + * from EquivalenceClasses. (This is important since simple "t1.ctid = + * t2.ctid" clauses will turn into ECs.) + */ + if (rel->has_eclass_joins) + { + List *clauses; + + /* Generate clauses, skipping any that join to lateral_referencers */ + clauses = generate_implied_equalities_for_column(root, + rel, + ec_member_matches_ctid, + NULL, + rel->lateral_referencers); + + /* Generate a path for each usable join clause */ + BuildParameterizedTidPaths(root, rel, clauses); + } + + /* + * Also consider parameterized TidPaths using "loose" join quals. Quals + * of the form "t1.ctid = t2.ctid" would turn into these if they are outer + * join quals, for example. + */ + BuildParameterizedTidPaths(root, rel, rel->joininfo); } diff --git a/src/backend/optimizer/plan/analyzejoins.c b/src/backend/optimizer/plan/analyzejoins.c index ef25fefa455..d19ff4138e5 100644 --- a/src/backend/optimizer/plan/analyzejoins.c +++ b/src/backend/optimizer/plan/analyzejoins.c @@ -11,7 +11,7 @@ * is that we have to work harder to clean up after ourselves when we modify * the query, since the derived data structures have to be updated too. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,27 +25,28 @@ #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/joininfo.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "utils/lsyscache.h" /* local functions */ static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo); static void remove_rel_from_query(PlannerInfo *root, int relid, - Relids joinrelids); + Relids joinrelids); static List *remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved); static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel); static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, - List *clause_list); + List *clause_list); static Oid distinct_col_search(int colno, List *colnos, List *opids); static bool is_innerrel_unique_for(PlannerInfo *root, - Relids outerrelids, - RelOptInfo *innerrel, - JoinType jointype, - List *restrictlist); + Relids joinrelids, + Relids outerrelids, + RelOptInfo *innerrel, + JoinType jointype, + List *restrictlist); /* @@ -95,17 +96,16 @@ remove_useless_joins(PlannerInfo *root, List *joinlist) /* * We can delete this SpecialJoinInfo from the list too, since it's no - * longer of interest. + * longer of interest. (Since we'll restart the foreach loop + * immediately, we don't bother with foreach_delete_current.) */ - root->join_info_list = list_delete_ptr(root->join_info_list, sjinfo); + root->join_info_list = list_delete_cell(root->join_info_list, lc); /* * Restart the scan. This is necessary to ensure we find all * removable joins independently of ordering of the join_info_list * (note that removal of attr_needed bits may make a join appear - * removable that did not before). Also, since we just deleted the - * current list cell, we'd have to have some kluge to continue the - * list scan anyway. + * removable that did not before). */ goto restart; } @@ -253,8 +253,7 @@ join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo) * above the outer join, even if it references no other rels (it might * be from WHERE, for example). */ - if (restrictinfo->is_pushed_down || - !bms_equal(restrictinfo->required_relids, joinrelids)) + if (RINFO_IS_PUSHED_DOWN(restrictinfo, joinrelids)) { /* * If such a clause actually references the inner rel then join @@ -316,7 +315,6 @@ remove_rel_from_query(PlannerInfo *root, int relid, Relids joinrelids) List *joininfos; Index rti; ListCell *l; - ListCell *nextl; /* * Mark the rel as "dead" to show it is no longer part of the join tree. @@ -383,16 +381,15 @@ remove_rel_from_query(PlannerInfo *root, int relid, Relids joinrelids) * remove or just update the PHV. There is no corresponding test in * join_is_removable because it doesn't need to distinguish those cases. */ - for (l = list_head(root->placeholder_list); l != NULL; l = nextl) + foreach(l, root->placeholder_list) { PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(l); - nextl = lnext(l); Assert(!bms_is_member(relid, phinfo->ph_lateral)); if (bms_is_subset(phinfo->ph_needed, joinrelids) && bms_is_member(relid, phinfo->ph_eval_at)) - root->placeholder_list = list_delete_ptr(root->placeholder_list, - phinfo); + root->placeholder_list = foreach_delete_current(root->placeholder_list, + l); else { phinfo->ph_eval_at = bms_del_member(phinfo->ph_eval_at, relid); @@ -422,8 +419,7 @@ remove_rel_from_query(PlannerInfo *root, int relid, Relids joinrelids) remove_join_clause_from_rels(root, rinfo, rinfo->required_relids); - if (rinfo->is_pushed_down || - !bms_equal(rinfo->required_relids, joinrelids)) + if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)) { /* Recheck that qual doesn't actually reference the target rel */ Assert(!bms_is_member(relid, rinfo->clause_relids)); @@ -512,13 +508,11 @@ void reduce_unique_semijoins(PlannerInfo *root) { ListCell *lc; - ListCell *next; /* - * Scan the join_info_list to find semijoins. We can't use foreach - * because we may delete the current cell. + * Scan the join_info_list to find semijoins. */ - for (lc = list_head(root->join_info_list); lc != NULL; lc = next) + foreach(lc, root->join_info_list) { SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc); int innerrelid; @@ -526,8 +520,6 @@ reduce_unique_semijoins(PlannerInfo *root) Relids joinrelids; List *restrictlist; - next = lnext(lc); - /* * Must be a non-delaying semijoin to a single baserel, else we aren't * going to be able to do anything with it. (It's probably not @@ -567,12 +559,13 @@ reduce_unique_semijoins(PlannerInfo *root) innerrel->joininfo); /* Test whether the innerrel is unique for those clauses. */ - if (!innerrel_is_unique(root, sjinfo->min_lefthand, innerrel, + if (!innerrel_is_unique(root, + joinrelids, sjinfo->min_lefthand, innerrel, JOIN_SEMI, restrictlist, true)) continue; /* OK, remove the SpecialJoinInfo from the list. */ - root->join_info_list = list_delete_ptr(root->join_info_list, sjinfo); + root->join_info_list = foreach_delete_current(root->join_info_list, lc); } } @@ -897,7 +890,7 @@ query_is_distinct_for(Query *query, List *colnos, List *opids) /* non-resjunk columns should have grouping clauses */ Assert(lg != NULL); sgc = (SortGroupClause *) lfirst(lg); - lg = lnext(lg); + lg = lnext(topop->groupClauses, lg); opid = distinct_col_search(tle->resno, colnos, opids); if (!OidIsValid(opid) || @@ -949,7 +942,8 @@ distinct_col_search(int colno, List *colnos, List *opids) * * We need an actual RelOptInfo for the innerrel, but it's sufficient to * identify the outerrel by its Relids. This asymmetry supports use of this - * function before joinrels have been built. + * function before joinrels have been built. (The caller is expected to + * also supply the joinrelids, just to save recalculating that.) * * The proof must be made based only on clauses that will be "joinquals" * rather than "otherquals" at execution. For an inner join there's no @@ -968,6 +962,7 @@ distinct_col_search(int colno, List *colnos, List *opids) */ bool innerrel_is_unique(PlannerInfo *root, + Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, @@ -1016,7 +1011,7 @@ innerrel_is_unique(PlannerInfo *root, } /* No cached information, so try to make the proof. */ - if (is_innerrel_unique_for(root, outerrelids, innerrel, + if (is_innerrel_unique_for(root, joinrelids, outerrelids, innerrel, jointype, restrictlist)) { /* @@ -1075,6 +1070,7 @@ innerrel_is_unique(PlannerInfo *root, */ static bool is_innerrel_unique_for(PlannerInfo *root, + Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, @@ -1098,7 +1094,8 @@ is_innerrel_unique_for(PlannerInfo *root, * As noted above, if it's a pushed-down clause and we're at an outer * join, we can't use it. */ - if (restrictinfo->is_pushed_down && IS_OUTER_JOIN(jointype)) + if (IS_OUTER_JOIN(jointype) && + RINFO_IS_PUSHED_DOWN(restrictinfo, joinrelids)) continue; /* Ignore if it's not a mergejoinable clause */ diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 048bdf4ad1e..0c036209f09 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -5,7 +5,7 @@ * Planning is complete, we just need to convert the selected * Path into a Plan. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,7 +19,6 @@ #include #include -#include "access/stratnum.h" #include "access/sysattr.h" #include "catalog/pg_class.h" #include "foreign/fdwapi.h" @@ -29,16 +28,15 @@ #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" +#include "optimizer/paramassign.h" #include "optimizer/paths.h" #include "optimizer/placeholder.h" #include "optimizer/plancat.h" #include "optimizer/planmain.h" -#include "optimizer/planner.h" -#include "optimizer/predtest.h" #include "optimizer/restrictinfo.h" #include "optimizer/subselect.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parse_clause.h" #include "parser/parsetree.h" #include "partitioning/partprune.h" @@ -65,7 +63,7 @@ * and Group, which need these values to be available in their inputs. * * CP_IGNORE_TLIST specifies that the caller plans to replace the targetlist, - * and therefore it doens't matter a bit what target list gets generated. + * and therefore it doesn't matter a bit what target list gets generated. */ #define CP_EXACT_TLIST 0x0001 /* Plan must return specified tlist */ #define CP_SMALL_TLIST 0x0002 /* Prefer narrower tlists */ @@ -74,230 +72,226 @@ static Plan *create_plan_recurse(PlannerInfo *root, Path *best_path, - int flags); + int flags); static Plan *create_scan_plan(PlannerInfo *root, Path *best_path, - int flags); + int flags); static List *build_path_tlist(PlannerInfo *root, Path *path); static bool use_physical_tlist(PlannerInfo *root, Path *path, int flags); static List *get_gating_quals(PlannerInfo *root, List *quals); static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, - List *gating_quals); + List *gating_quals); static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path); -static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path); -static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path); -static Result *create_result_plan(PlannerInfo *root, ResultPath *best_path); +static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path, + int flags); +static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, + int flags); +static Result *create_group_result_plan(PlannerInfo *root, + GroupResultPath *best_path); static ProjectSet *create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path); static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path, - int flags); + int flags); static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path, - int flags); + int flags); static Gather *create_gather_plan(PlannerInfo *root, GatherPath *best_path); static Plan *create_projection_plan(PlannerInfo *root, - ProjectionPath *best_path, - int flags); + ProjectionPath *best_path, + int flags); static Plan *inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe); static Sort *create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags); static Group *create_group_plan(PlannerInfo *root, GroupPath *best_path); static Unique *create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, - int flags); + int flags); static Agg *create_agg_plan(PlannerInfo *root, AggPath *best_path); static Plan *create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path); static Result *create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path); static WindowAgg *create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path); static SetOp *create_setop_plan(PlannerInfo *root, SetOpPath *best_path, - int flags); + int flags); static RecursiveUnion *create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path); -static void get_column_info_for_window(PlannerInfo *root, WindowClause *wc, - List *tlist, - int numSortCols, AttrNumber *sortColIdx, - int *partNumCols, - AttrNumber **partColIdx, - Oid **partOperators, - int *ordNumCols, - AttrNumber **ordColIdx, - Oid **ordOperators); static LockRows *create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path, - int flags); + int flags); static ModifyTable *create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path); static Limit *create_limit_plan(PlannerInfo *root, LimitPath *best_path, - int flags); + int flags); static SeqScan *create_seqscan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static SampleScan *create_samplescan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static Scan *create_indexscan_plan(PlannerInfo *root, IndexPath *best_path, - List *tlist, List *scan_clauses, bool indexonly); + List *tlist, List *scan_clauses, bool indexonly); static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root, - BitmapHeapPath *best_path, - List *tlist, List *scan_clauses); + BitmapHeapPath *best_path, + List *tlist, List *scan_clauses); static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, - List **qual, List **indexqual, List **indexECs); + List **qual, List **indexqual, List **indexECs); static void bitmap_subplan_mark_shared(Plan *plan); static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root, - SubqueryScanPath *best_path, - List *tlist, List *scan_clauses); + SubqueryScanPath *best_path, + List *tlist, List *scan_clauses); static FunctionScan *create_functionscan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static ValuesScan *create_valuesscan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static TableFuncScan *create_tablefuncscan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static CteScan *create_ctescan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static NamedTuplestoreScan *create_namedtuplestorescan_plan(PlannerInfo *root, - Path *best_path, List *tlist, List *scan_clauses); + Path *best_path, List *tlist, List *scan_clauses); +static Result *create_resultscan_plan(PlannerInfo *root, Path *best_path, + List *tlist, List *scan_clauses); static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, - List *tlist, List *scan_clauses); + List *tlist, List *scan_clauses); static CustomScan *create_customscan_plan(PlannerInfo *root, - CustomPath *best_path, - List *tlist, List *scan_clauses); + CustomPath *best_path, + List *tlist, List *scan_clauses); static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path); static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path); static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path); static Node *replace_nestloop_params(PlannerInfo *root, Node *expr); static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root); -static void process_subquery_nestloop_params(PlannerInfo *root, - List *subplan_params); -static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path); +static void fix_indexqual_references(PlannerInfo *root, IndexPath *index_path, + List **stripped_indexquals_p, + List **fixed_indexquals_p); static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path); +static Node *fix_indexqual_clause(PlannerInfo *root, + IndexOptInfo *index, int indexcol, + Node *clause, List *indexcolnos); static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol); static List *get_switched_clauses(List *clauses, Relids outerrelids); static List *order_qual_clauses(PlannerInfo *root, List *clauses); static void copy_generic_path_info(Plan *dest, Path *src); static void copy_plan_costsize(Plan *dest, Plan *src); static void label_sort_with_costsize(PlannerInfo *root, Sort *plan, - double limit_tuples); + double limit_tuples); static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid); static SampleScan *make_samplescan(List *qptlist, List *qpqual, Index scanrelid, - TableSampleClause *tsc); + TableSampleClause *tsc); static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid, - Oid indexid, List *indexqual, List *indexqualorig, - List *indexorderby, List *indexorderbyorig, - List *indexorderbyops, - ScanDirection indexscandir); + Oid indexid, List *indexqual, List *indexqualorig, + List *indexorderby, List *indexorderbyorig, + List *indexorderbyops, + ScanDirection indexscandir); static IndexOnlyScan *make_indexonlyscan(List *qptlist, List *qpqual, - Index scanrelid, Oid indexid, - List *indexqual, List *indexorderby, - List *indextlist, - ScanDirection indexscandir); + Index scanrelid, Oid indexid, + List *indexqual, List *indexorderby, + List *indextlist, + ScanDirection indexscandir); static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid, - List *indexqual, - List *indexqualorig); + List *indexqual, + List *indexqualorig); static BitmapHeapScan *make_bitmap_heapscan(List *qptlist, - List *qpqual, - Plan *lefttree, - List *bitmapqualorig, - Index scanrelid); + List *qpqual, + Plan *lefttree, + List *bitmapqualorig, + Index scanrelid); static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid, - List *tidquals); + List *tidquals); static SubqueryScan *make_subqueryscan(List *qptlist, - List *qpqual, - Index scanrelid, - Plan *subplan); + List *qpqual, + Index scanrelid, + Plan *subplan); static FunctionScan *make_functionscan(List *qptlist, List *qpqual, - Index scanrelid, List *functions, bool funcordinality); + Index scanrelid, List *functions, bool funcordinality); static ValuesScan *make_valuesscan(List *qptlist, List *qpqual, - Index scanrelid, List *values_lists); + Index scanrelid, List *values_lists); static TableFuncScan *make_tablefuncscan(List *qptlist, List *qpqual, - Index scanrelid, TableFunc *tablefunc); + Index scanrelid, TableFunc *tablefunc); static CteScan *make_ctescan(List *qptlist, List *qpqual, - Index scanrelid, int ctePlanId, int cteParam); + Index scanrelid, int ctePlanId, int cteParam); static NamedTuplestoreScan *make_namedtuplestorescan(List *qptlist, List *qpqual, - Index scanrelid, char *enrname); + Index scanrelid, char *enrname); static WorkTableScan *make_worktablescan(List *qptlist, List *qpqual, - Index scanrelid, int wtParam); -static Append *make_append(List *appendplans, int first_partial_plan, - List *tlist, List *partitioned_rels, List *partpruneinfos); + Index scanrelid, int wtParam); static RecursiveUnion *make_recursive_union(List *tlist, - Plan *lefttree, - Plan *righttree, - int wtParam, - List *distinctList, - long numGroups); + Plan *lefttree, + Plan *righttree, + int wtParam, + List *distinctList, + long numGroups); static BitmapAnd *make_bitmap_and(List *bitmapplans); static BitmapOr *make_bitmap_or(List *bitmapplans); static NestLoop *make_nestloop(List *tlist, - List *joinclauses, List *otherclauses, List *nestParams, - Plan *lefttree, Plan *righttree, - JoinType jointype, bool inner_unique); + List *joinclauses, List *otherclauses, List *nestParams, + Plan *lefttree, Plan *righttree, + JoinType jointype, bool inner_unique); static HashJoin *make_hashjoin(List *tlist, - List *joinclauses, List *otherclauses, - List *hashclauses, - Plan *lefttree, Plan *righttree, - JoinType jointype, bool inner_unique); + List *joinclauses, List *otherclauses, + List *hashclauses, + List *hashoperators, List *hashcollations, + List *hashkeys, + Plan *lefttree, Plan *righttree, + JoinType jointype, bool inner_unique); static Hash *make_hash(Plan *lefttree, - Oid skewTable, - AttrNumber skewColumn, - bool skewInherit); + List *hashkeys, + Oid skewTable, + AttrNumber skewColumn, + bool skewInherit); static MergeJoin *make_mergejoin(List *tlist, - List *joinclauses, List *otherclauses, - List *mergeclauses, - Oid *mergefamilies, - Oid *mergecollations, - int *mergestrategies, - bool *mergenullsfirst, - Plan *lefttree, Plan *righttree, - JoinType jointype, bool inner_unique, - bool skip_mark_restore); + List *joinclauses, List *otherclauses, + List *mergeclauses, + Oid *mergefamilies, + Oid *mergecollations, + int *mergestrategies, + bool *mergenullsfirst, + Plan *lefttree, Plan *righttree, + JoinType jointype, bool inner_unique, + bool skip_mark_restore); static Sort *make_sort(Plan *lefttree, int numCols, - AttrNumber *sortColIdx, Oid *sortOperators, - Oid *collations, bool *nullsFirst); + AttrNumber *sortColIdx, Oid *sortOperators, + Oid *collations, bool *nullsFirst); static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, - Relids relids, - const AttrNumber *reqColIdx, - bool adjust_tlist_in_place, - int *p_numsortkeys, - AttrNumber **p_sortColIdx, - Oid **p_sortOperators, - Oid **p_collations, - bool **p_nullsFirst); + Relids relids, + const AttrNumber *reqColIdx, + bool adjust_tlist_in_place, + int *p_numsortkeys, + AttrNumber **p_sortColIdx, + Oid **p_sortOperators, + Oid **p_collations, + bool **p_nullsFirst); static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec, - TargetEntry *tle, - Relids relids); + TargetEntry *tle, + Relids relids); static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, - Relids relids); + Relids relids); static Sort *make_sort_from_groupcols(List *groupcls, - AttrNumber *grpColIdx, - Plan *lefttree); + AttrNumber *grpColIdx, + Plan *lefttree); static Material *make_material(Plan *lefttree); static WindowAgg *make_windowagg(List *tlist, Index winref, - int partNumCols, AttrNumber *partColIdx, Oid *partOperators, - int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, - int frameOptions, Node *startOffset, Node *endOffset, - Oid startInRangeFunc, Oid endInRangeFunc, - Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst, - Plan *lefttree); + int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, + int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, + int frameOptions, Node *startOffset, Node *endOffset, + Oid startInRangeFunc, Oid endInRangeFunc, + Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst, + Plan *lefttree); static Group *make_group(List *tlist, List *qual, int numGroupCols, - AttrNumber *grpColIdx, Oid *grpOperators, - Plan *lefttree); + AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, + Plan *lefttree); static Unique *make_unique_from_sortclauses(Plan *lefttree, List *distinctList); static Unique *make_unique_from_pathkeys(Plan *lefttree, - List *pathkeys, int numCols); + List *pathkeys, int numCols); static Gather *make_gather(List *qptlist, List *qpqual, - int nworkers, int rescan_param, bool single_copy, Plan *subplan); + int nworkers, int rescan_param, bool single_copy, Plan *subplan); static SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, - List *distinctList, AttrNumber flagColIdx, int firstFlag, - long numGroups); + List *distinctList, AttrNumber flagColIdx, int firstFlag, + long numGroups); static LockRows *make_lockrows(Plan *lefttree, List *rowMarks, int epqParam); static Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan); static ProjectSet *make_project_set(List *tlist, Plan *subplan); static ModifyTable *make_modifytable(PlannerInfo *root, - CmdType operation, bool canSetTag, - Index nominalRelation, List *partitioned_rels, - bool partColsUpdated, - List *resultRelations, - Index mergeTargetRelation, - List *subplans, - List *withCheckOptionLists, List *returningLists, - List *rowMarks, OnConflictExpr *onconflict, - List *mergeSourceTargetList, - List *mergeActionList, int epqParam); + CmdType operation, bool canSetTag, + Index nominalRelation, Index rootRelation, + bool partColsUpdated, + List *resultRelations, List *subplans, List *subroots, + List *withCheckOptionLists, List *returningLists, + List *rowMarks, OnConflictExpr *onconflict, int epqParam); static GatherMerge *create_gather_merge_plan(PlannerInfo *root, - GatherMergePath *best_path); + GatherMergePath *best_path); /* @@ -323,7 +317,7 @@ create_plan(PlannerInfo *root, Path *best_path) /* plan_params should not be in use in current query level */ Assert(root->plan_params == NIL); - /* Initialize this module's private workspace in PlannerInfo */ + /* Initialize this module's workspace in PlannerInfo */ root->curOuterRels = NULL; root->curOuterParams = NIL; @@ -401,11 +395,13 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) break; case T_Append: plan = create_append_plan(root, - (AppendPath *) best_path); + (AppendPath *) best_path, + flags); break; case T_MergeAppend: plan = create_merge_append_plan(root, - (MergeAppendPath *) best_path); + (MergeAppendPath *) best_path, + flags); break; case T_Result: if (IsA(best_path, ProjectionPath)) @@ -419,11 +415,16 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) plan = (Plan *) create_minmaxagg_plan(root, (MinMaxAggPath *) best_path); } + else if (IsA(best_path, GroupResultPath)) + { + plan = (Plan *) create_group_result_plan(root, + (GroupResultPath *) best_path); + } else { - Assert(IsA(best_path, ResultPath)); - plan = (Plan *) create_result_plan(root, - (ResultPath *) best_path); + /* Simple RTE_RESULT base relation */ + Assert(IsA(best_path, Path)); + plan = create_scan_plan(root, best_path, flags); } break; case T_ProjectSet: @@ -558,8 +559,8 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) * For paranoia's sake, don't modify the stored baserestrictinfo list. */ if (best_path->param_info) - scan_clauses = list_concat(list_copy(scan_clauses), - best_path->param_info->ppi_clauses); + scan_clauses = list_concat_copy(scan_clauses, + best_path->param_info->ppi_clauses); /* * Detect whether we have any pseudoconstant quals to deal with. Then, if @@ -592,10 +593,10 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) tlist = copyObject(((IndexPath *) best_path)->indexinfo->indextlist); /* - * Transfer any sortgroupref data to the replacement tlist, unless - * we don't care because the gating Result will handle it. + * Transfer sortgroupref data to the replacement tlist, if + * requested (use_physical_tlist checked that this will work). */ - if (!gating_clauses) + if (flags & CP_LABEL_TLIST) apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget); } else @@ -609,7 +610,7 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) else { /* As above, transfer sortgroupref data to replacement tlist */ - if (!gating_clauses) + if (flags & CP_LABEL_TLIST) apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget); } } @@ -707,6 +708,13 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) scan_clauses); break; + case T_Result: + plan = (Plan *) create_resultscan_plan(root, + best_path, + tlist, + scan_clauses); + break; + case T_WorkTableScan: plan = (Plan *) create_worktablescan_plan(root, best_path, @@ -938,9 +946,26 @@ create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, List *gating_quals) { Plan *gplan; + Plan *splan; Assert(gating_quals); + /* + * We might have a trivial Result plan already. Stacking one Result atop + * another is silly, so if that applies, just discard the input plan. + * (We're assuming its targetlist is uninteresting; it should be either + * the same as the result of build_path_tlist, or a simplified version.) + */ + splan = plan; + if (IsA(plan, Result)) + { + Result *rplan = (Result *) plan; + + if (rplan->plan.lefttree == NULL && + rplan->resconstantqual == NULL) + splan = NULL; + } + /* * Since we need a Result node anyway, always return the path's requested * tlist; that's never a wrong choice, even if the parent node didn't ask @@ -948,7 +973,7 @@ create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, */ gplan = (Plan *) make_result(build_path_tlist(root, path), (Node *) gating_quals, - plan); + splan); /* * Notice that we don't change cost or size estimates when doing gating. @@ -1036,14 +1061,22 @@ create_join_plan(PlannerInfo *root, JoinPath *best_path) * Returns a Plan node. */ static Plan * -create_append_plan(PlannerInfo *root, AppendPath *best_path) +create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) { Append *plan; List *tlist = build_path_tlist(root, &best_path->path); + int orig_tlist_length = list_length(tlist); + bool tlist_was_changed = false; + List *pathkeys = best_path->path.pathkeys; List *subplans = NIL; ListCell *subpaths; RelOptInfo *rel = best_path->path.parent; - List *partpruneinfos = NIL; + PartitionPruneInfo *partpruneinfo = NULL; + int nodenumsortkeys = 0; + AttrNumber *nodeSortColIdx = NULL; + Oid *nodeSortOperators = NULL; + Oid *nodeCollations = NULL; + bool *nodeNullsFirst = NULL; /* * The subpaths list could be empty, if every child was proven empty by @@ -1052,7 +1085,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) * * Note that an AppendPath with no members is also generated in certain * cases where there was no appending construct at all, but we know the - * relation is empty (see set_dummy_rel_pathlist). + * relation is empty (see set_dummy_rel_pathlist and mark_dummy_rel). */ if (best_path->subpaths == NIL) { @@ -1069,6 +1102,43 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) return plan; } + /* + * Otherwise build an Append plan. Note that if there's just one child, + * the Append is pretty useless; but we wait till setrefs.c to get rid of + * it. Doing so here doesn't work because the varno of the child scan + * plan won't match the parent-rel Vars it'll be asked to emit. + * + * We don't have the actual creation of the Append node split out into a + * separate make_xxx function. This is because we want to run + * prepare_sort_from_pathkeys on it before we do so on the individual + * child plans, to make cross-checking the sort info easier. + */ + plan = makeNode(Append); + plan->plan.targetlist = tlist; + plan->plan.qual = NIL; + plan->plan.lefttree = NULL; + plan->plan.righttree = NULL; + + if (pathkeys != NIL) + { + /* + * Compute sort column info, and adjust the Append's tlist as needed. + * Because we pass adjust_tlist_in_place = true, we may ignore the + * function result; it must be the same plan node. However, we then + * need to detect whether any tlist entries were added. + */ + (void) prepare_sort_from_pathkeys((Plan *) plan, pathkeys, + best_path->path.parent->relids, + NULL, + true, + &nodenumsortkeys, + &nodeSortColIdx, + &nodeSortOperators, + &nodeCollations, + &nodeNullsFirst); + tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist)); + } + /* Build the plan for each child */ foreach(subpaths, best_path->subpaths) { @@ -1078,10 +1148,73 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) /* Must insist that all children return the same tlist */ subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST); + /* + * For ordered Appends, we must insert a Sort node if subplan isn't + * sufficiently ordered. + */ + if (pathkeys != NIL) + { + int numsortkeys; + AttrNumber *sortColIdx; + Oid *sortOperators; + Oid *collations; + bool *nullsFirst; + + /* + * Compute sort column info, and adjust subplan's tlist as needed. + * We must apply prepare_sort_from_pathkeys even to subplans that + * don't need an explicit sort, to make sure they are returning + * the same sort key columns the Append expects. + */ + subplan = prepare_sort_from_pathkeys(subplan, pathkeys, + subpath->parent->relids, + nodeSortColIdx, + false, + &numsortkeys, + &sortColIdx, + &sortOperators, + &collations, + &nullsFirst); + + /* + * Check that we got the same sort key information. We just + * Assert that the sortops match, since those depend only on the + * pathkeys; but it seems like a good idea to check the sort + * column numbers explicitly, to ensure the tlists match up. + */ + Assert(numsortkeys == nodenumsortkeys); + if (memcmp(sortColIdx, nodeSortColIdx, + numsortkeys * sizeof(AttrNumber)) != 0) + elog(ERROR, "Append child's targetlist doesn't match Append"); + Assert(memcmp(sortOperators, nodeSortOperators, + numsortkeys * sizeof(Oid)) == 0); + Assert(memcmp(collations, nodeCollations, + numsortkeys * sizeof(Oid)) == 0); + Assert(memcmp(nullsFirst, nodeNullsFirst, + numsortkeys * sizeof(bool)) == 0); + + /* Now, insert a Sort node if subplan isn't sufficiently ordered */ + if (!pathkeys_contained_in(pathkeys, subpath->pathkeys)) + { + Sort *sort = make_sort(subplan, numsortkeys, + sortColIdx, sortOperators, + collations, nullsFirst); + + label_sort_with_costsize(root, sort, best_path->limit_tuples); + subplan = (Plan *) sort; + } + } + subplans = lappend(subplans, subplan); } - if (rel->reloptkind == RELOPT_BASEREL && + /* + * If any quals exist, they may be useful to perform further partition + * pruning during execution. Gather information needed by the executor to + * do partition pruning. + */ + if (enable_partition_pruning && + rel->reloptkind == RELOPT_BASEREL && best_path->partitioned_rels != NIL) { List *prunequal; @@ -1090,7 +1223,6 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) if (best_path->path.param_info) { - List *prmquals = best_path->path.param_info->ppi_clauses; prmquals = extract_actual_clauses(prmquals, false); @@ -1100,33 +1232,34 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) prunequal = list_concat(prunequal, prmquals); } - /* - * If any quals exist, they may be useful to perform further partition - * pruning during execution. Generate a PartitionPruneInfo for each - * partitioned rel to store these quals and allow translation of - * partition indexes into subpath indexes. - */ if (prunequal != NIL) - partpruneinfos = - make_partition_pruneinfo(root, + partpruneinfo = + make_partition_pruneinfo(root, rel, + best_path->subpaths, best_path->partitioned_rels, - best_path->subpaths, prunequal); + prunequal); } - /* - * XXX ideally, if there's just one child, we'd not bother to generate an - * Append node but just return the single child. At the moment this does - * not work because the varno of the child scan plan won't match the - * parent-rel Vars it'll be asked to emit. - */ - - plan = make_append(subplans, best_path->first_partial_path, - tlist, best_path->partitioned_rels, - partpruneinfos); + plan->appendplans = subplans; + plan->first_partial_plan = best_path->first_partial_path; + plan->part_prune_info = partpruneinfo; copy_generic_path_info(&plan->plan, (Path *) best_path); - return (Plan *) plan; + /* + * If prepare_sort_from_pathkeys added sort columns, but we were told to + * produce either the exact tlist or a narrow tlist, we should get rid of + * the sort columns again. We must inject a projection node to do so. + */ + if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))) + { + tlist = list_truncate(list_copy(plan->plan.targetlist), + orig_tlist_length); + return inject_projection_plan((Plan *) plan, tlist, + plan->plan.parallel_safe); + } + else + return (Plan *) plan; } /* @@ -1137,14 +1270,19 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) * Returns a Plan node. */ static Plan * -create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) +create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, + int flags) { MergeAppend *node = makeNode(MergeAppend); Plan *plan = &node->plan; List *tlist = build_path_tlist(root, &best_path->path); + int orig_tlist_length = list_length(tlist); + bool tlist_was_changed; List *pathkeys = best_path->path.pathkeys; List *subplans = NIL; ListCell *subpaths; + RelOptInfo *rel = best_path->path.parent; + PartitionPruneInfo *partpruneinfo = NULL; /* * We don't have the actual creation of the MergeAppend node split out @@ -1158,7 +1296,12 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) plan->lefttree = NULL; plan->righttree = NULL; - /* Compute sort column info, and adjust MergeAppend's tlist as needed */ + /* + * Compute sort column info, and adjust MergeAppend's tlist as needed. + * Because we pass adjust_tlist_in_place = true, we may ignore the + * function result; it must be the same plan node. However, we then need + * to detect whether any tlist entries were added. + */ (void) prepare_sort_from_pathkeys(plan, pathkeys, best_path->path.parent->relids, NULL, @@ -1168,6 +1311,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) &node->sortOperators, &node->collations, &node->nullsFirst); + tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist)); /* * Now prepare the child plans. We must apply prepare_sort_from_pathkeys @@ -1230,22 +1374,63 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) subplans = lappend(subplans, subplan); } - node->partitioned_rels = best_path->partitioned_rels; + /* + * If any quals exist, they may be useful to perform further partition + * pruning during execution. Gather information needed by the executor to + * do partition pruning. + */ + if (enable_partition_pruning && + rel->reloptkind == RELOPT_BASEREL && + best_path->partitioned_rels != NIL) + { + List *prunequal; + + prunequal = extract_actual_clauses(rel->baserestrictinfo, false); + + if (best_path->path.param_info) + { + List *prmquals = best_path->path.param_info->ppi_clauses; + + prmquals = extract_actual_clauses(prmquals, false); + prmquals = (List *) replace_nestloop_params(root, + (Node *) prmquals); + + prunequal = list_concat(prunequal, prmquals); + } + + if (prunequal != NIL) + partpruneinfo = make_partition_pruneinfo(root, rel, + best_path->subpaths, + best_path->partitioned_rels, + prunequal); + } + node->mergeplans = subplans; + node->part_prune_info = partpruneinfo; - return (Plan *) node; + /* + * If prepare_sort_from_pathkeys added sort columns, but we were told to + * produce either the exact tlist or a narrow tlist, we should get rid of + * the sort columns again. We must inject a projection node to do so. + */ + if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))) + { + tlist = list_truncate(list_copy(plan->targetlist), orig_tlist_length); + return inject_projection_plan(plan, tlist, plan->parallel_safe); + } + else + return plan; } /* - * create_result_plan + * create_group_result_plan * Create a Result plan for 'best_path'. - * This is only used for degenerate cases, such as a query with an empty - * jointree. + * This is only used for degenerate grouping cases. * * Returns a Plan node. */ static Result * -create_result_plan(PlannerInfo *root, ResultPath *best_path) +create_group_result_plan(PlannerInfo *root, GroupResultPath *best_path) { Result *plan; List *tlist; @@ -1335,6 +1520,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) bool newitems; int numGroupCols; AttrNumber *groupColIdx; + Oid *groupCollations; int groupColPos; ListCell *l; @@ -1387,20 +1573,10 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) } } + /* Use change_plan_targetlist in case we need to insert a Result node */ if (newitems || best_path->umethod == UNIQUE_PATH_SORT) - { - /* - * If the top plan node can't do projections and its existing target - * list isn't already what we need, we need to add a Result node to - * help it along. - */ - if (!is_projection_capable_plan(subplan) && - !tlist_same_exprs(newtlist, subplan->targetlist)) - subplan = inject_projection_plan(subplan, newtlist, - best_path->path.parallel_safe); - else - subplan->targetlist = newtlist; - } + subplan = change_plan_targetlist(subplan, newtlist, + best_path->path.parallel_safe); /* * Build control information showing which subplan output columns are to @@ -1411,6 +1587,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) newtlist = subplan->targetlist; numGroupCols = list_length(uniq_exprs); groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber)); + groupCollations = (Oid *) palloc(numGroupCols * sizeof(Oid)); groupColPos = 0; foreach(l, uniq_exprs) @@ -1421,7 +1598,9 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) tle = tlist_member(uniqexpr, newtlist); if (!tle) /* shouldn't happen */ elog(ERROR, "failed to find unique expression in subplan tlist"); - groupColIdx[groupColPos++] = tle->resno; + groupColIdx[groupColPos] = tle->resno; + groupCollations[groupColPos] = exprCollation((Node *) tle->expr); + groupColPos++; } if (best_path->umethod == UNIQUE_PATH_HASH) @@ -1459,6 +1638,7 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags) numGroupCols, groupColIdx, groupOperators, + groupCollations, NIL, NIL, best_path->path.rows, @@ -1544,7 +1724,7 @@ create_gather_plan(PlannerInfo *root, GatherPath *best_path) gather_plan = make_gather(tlist, NIL, best_path->num_workers, - SS_assign_special_param(root), + assign_special_exec_param(root), best_path->single_copy, subplan); @@ -1580,7 +1760,7 @@ create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path) copy_generic_path_info(&gm_plan->plan, &best_path->path); /* Assign the rescan Param. */ - gm_plan->rescan_param = SS_assign_special_param(root); + gm_plan->rescan_param = assign_special_exec_param(root); /* Gather Merge is pointless with no pathkeys; use Gather instead. */ Assert(pathkeys != NIL); @@ -1651,7 +1831,7 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags) */ subplan = create_plan_recurse(root, best_path->subpath, 0); tlist = subplan->targetlist; - if ((flags & CP_LABEL_TLIST) != 0) + if (flags & CP_LABEL_TLIST) apply_pathtarget_labeling_to_tlist(tlist, best_path->path.pathtarget); } @@ -1742,6 +1922,40 @@ inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe) return plan; } +/* + * change_plan_targetlist + * Externally available wrapper for inject_projection_plan. + * + * This is meant for use by FDW plan-generation functions, which might + * want to adjust the tlist computed by some subplan tree. In general, + * a Result node is needed to compute the new tlist, but we can optimize + * some cases. + * + * In most cases, tlist_parallel_safe can just be passed as the parallel_safe + * flag of the FDW's own Path node. + */ +Plan * +change_plan_targetlist(Plan *subplan, List *tlist, bool tlist_parallel_safe) +{ + /* + * If the top plan node can't do projections and its existing target list + * isn't already what we need, we need to add a Result node to help it + * along. + */ + if (!is_projection_capable_plan(subplan) && + !tlist_same_exprs(tlist, subplan->targetlist)) + subplan = inject_projection_plan(subplan, tlist, + subplan->parallel_safe && + tlist_parallel_safe); + else + { + /* Else we can just replace the plan node's tlist */ + subplan->targetlist = tlist; + subplan->parallel_safe &= tlist_parallel_safe; + } + return subplan; +} + /* * create_sort_plan * @@ -1807,6 +2021,8 @@ create_group_plan(PlannerInfo *root, GroupPath *best_path) extract_grouping_cols(best_path->groupClause, subplan->targetlist), extract_grouping_ops(best_path->groupClause), + extract_grouping_collations(best_path->groupClause, + subplan->targetlist), subplan); copy_generic_path_info(&plan->plan, (Path *) best_path); @@ -1873,6 +2089,8 @@ create_agg_plan(PlannerInfo *root, AggPath *best_path) extract_grouping_cols(best_path->groupClause, subplan->targetlist), extract_grouping_ops(best_path->groupClause), + extract_grouping_collations(best_path->groupClause, + subplan->targetlist), NIL, NIL, best_path->numGroups, @@ -1983,7 +2201,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) * create_modifytable_plan). Fortunately we can't be because there would * never be grouping in an UPDATE/DELETE; but let's Assert that. */ - Assert(!root->hasInheritedTarget); + Assert(root->inhTargetKind == INHKIND_NONE); Assert(root->grouping_map == NULL); root->grouping_map = grouping_map; @@ -1996,10 +2214,9 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) chain = NIL; if (list_length(rollups) > 1) { - ListCell *lc2 = lnext(list_head(rollups)); bool is_first_sort = ((RollupData *) linitial(rollups))->is_hashed; - for_each_cell(lc, lc2) + for_each_cell(lc, rollups, list_second_cell(rollups)) { RollupData *rollup = lfirst(lc); AttrNumber *new_grpColIdx; @@ -2034,6 +2251,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) list_length((List *) linitial(rollup->gsets)), new_grpColIdx, extract_grouping_ops(rollup->groupClause), + extract_grouping_collations(rollup->groupClause, subplan->targetlist), rollup->gsets, NIL, rollup->numGroups, @@ -2071,6 +2289,7 @@ create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path) numGroupCols, top_grpColIdx, extract_grouping_ops(rollup->groupClause), + extract_grouping_collations(rollup->groupClause, subplan->targetlist), rollup->gsets, chain, rollup->numGroups, @@ -2145,7 +2364,7 @@ create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path) * create_modifytable_plan). Fortunately we can't be because there would * never be aggregates in an UPDATE/DELETE; but let's Assert that. */ - Assert(!root->hasInheritedTarget); + Assert(root->inhTargetKind == INHKIND_NONE); Assert(root->minmax_aggs == NIL); root->minmax_aggs = best_path->mmaggregates; @@ -2163,19 +2382,19 @@ create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) { WindowAgg *plan; WindowClause *wc = best_path->winclause; + int numPart = list_length(wc->partitionClause); + int numOrder = list_length(wc->orderClause); Plan *subplan; List *tlist; - int numsortkeys; - AttrNumber *sortColIdx; - Oid *sortOperators; - Oid *collations; - bool *nullsFirst; int partNumCols; AttrNumber *partColIdx; Oid *partOperators; + Oid *partCollations; int ordNumCols; AttrNumber *ordColIdx; Oid *ordOperators; + Oid *ordCollations; + ListCell *lc; /* * WindowAgg can project, so no need to be terribly picky about child @@ -2186,32 +2405,47 @@ create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) tlist = build_path_tlist(root, &best_path->path); /* - * We shouldn't need to actually sort, but it's convenient to use - * prepare_sort_from_pathkeys to identify the input's sort columns. + * Convert SortGroupClause lists into arrays of attr indexes and equality + * operators, as wanted by executor. (Note: in principle, it's possible + * to drop some of the sort columns, if they were proved redundant by + * pathkey logic. However, it doesn't seem worth going out of our way to + * optimize such cases. In any case, we must *not* remove the ordering + * column for RANGE OFFSET cases, as the executor needs that for in_range + * tests even if it's known to be equal to some partitioning column.) */ - subplan = prepare_sort_from_pathkeys(subplan, - best_path->winpathkeys, - NULL, - NULL, - false, - &numsortkeys, - &sortColIdx, - &sortOperators, - &collations, - &nullsFirst); - - /* Now deconstruct that into partition and ordering portions */ - get_column_info_for_window(root, - wc, - subplan->targetlist, - numsortkeys, - sortColIdx, - &partNumCols, - &partColIdx, - &partOperators, - &ordNumCols, - &ordColIdx, - &ordOperators); + partColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numPart); + partOperators = (Oid *) palloc(sizeof(Oid) * numPart); + partCollations = (Oid *) palloc(sizeof(Oid) * numPart); + + partNumCols = 0; + foreach(lc, wc->partitionClause) + { + SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); + TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist); + + Assert(OidIsValid(sgc->eqop)); + partColIdx[partNumCols] = tle->resno; + partOperators[partNumCols] = sgc->eqop; + partCollations[partNumCols] = exprCollation((Node *) tle->expr); + partNumCols++; + } + + ordColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numOrder); + ordOperators = (Oid *) palloc(sizeof(Oid) * numOrder); + ordCollations = (Oid *) palloc(sizeof(Oid) * numOrder); + + ordNumCols = 0; + foreach(lc, wc->orderClause) + { + SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); + TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist); + + Assert(OidIsValid(sgc->eqop)); + ordColIdx[ordNumCols] = tle->resno; + ordOperators[ordNumCols] = sgc->eqop; + ordCollations[ordNumCols] = exprCollation((Node *) tle->expr); + ordNumCols++; + } /* And finally we can make the WindowAgg node */ plan = make_windowagg(tlist, @@ -2219,9 +2453,11 @@ create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) partNumCols, partColIdx, partOperators, + partCollations, ordNumCols, ordColIdx, ordOperators, + ordCollations, wc->frameOptions, wc->startOffset, wc->endOffset, @@ -2237,112 +2473,6 @@ create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path) return plan; } -/* - * get_column_info_for_window - * Get the partitioning/ordering column numbers and equality operators - * for a WindowAgg node. - * - * This depends on the behavior of planner.c's make_pathkeys_for_window! - * - * We are given the target WindowClause and an array of the input column - * numbers associated with the resulting pathkeys. In the easy case, there - * are the same number of pathkey columns as partitioning + ordering columns - * and we just have to copy some data around. However, it's possible that - * some of the original partitioning + ordering columns were eliminated as - * redundant during the transformation to pathkeys. (This can happen even - * though the parser gets rid of obvious duplicates. A typical scenario is a - * window specification "PARTITION BY x ORDER BY y" coupled with a clause - * "WHERE x = y" that causes the two sort columns to be recognized as - * redundant.) In that unusual case, we have to work a lot harder to - * determine which keys are significant. - * - * The method used here is a bit brute-force: add the sort columns to a list - * one at a time and note when the resulting pathkey list gets longer. But - * it's a sufficiently uncommon case that a faster way doesn't seem worth - * the amount of code refactoring that'd be needed. - */ -static void -get_column_info_for_window(PlannerInfo *root, WindowClause *wc, List *tlist, - int numSortCols, AttrNumber *sortColIdx, - int *partNumCols, - AttrNumber **partColIdx, - Oid **partOperators, - int *ordNumCols, - AttrNumber **ordColIdx, - Oid **ordOperators) -{ - int numPart = list_length(wc->partitionClause); - int numOrder = list_length(wc->orderClause); - - if (numSortCols == numPart + numOrder) - { - /* easy case */ - *partNumCols = numPart; - *partColIdx = sortColIdx; - *partOperators = extract_grouping_ops(wc->partitionClause); - *ordNumCols = numOrder; - *ordColIdx = sortColIdx + numPart; - *ordOperators = extract_grouping_ops(wc->orderClause); - } - else - { - List *sortclauses; - List *pathkeys; - int scidx; - ListCell *lc; - - /* first, allocate what's certainly enough space for the arrays */ - *partNumCols = 0; - *partColIdx = (AttrNumber *) palloc(numPart * sizeof(AttrNumber)); - *partOperators = (Oid *) palloc(numPart * sizeof(Oid)); - *ordNumCols = 0; - *ordColIdx = (AttrNumber *) palloc(numOrder * sizeof(AttrNumber)); - *ordOperators = (Oid *) palloc(numOrder * sizeof(Oid)); - sortclauses = NIL; - pathkeys = NIL; - scidx = 0; - foreach(lc, wc->partitionClause) - { - SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); - List *new_pathkeys; - - sortclauses = lappend(sortclauses, sgc); - new_pathkeys = make_pathkeys_for_sortclauses(root, - sortclauses, - tlist); - if (list_length(new_pathkeys) > list_length(pathkeys)) - { - /* this sort clause is actually significant */ - (*partColIdx)[*partNumCols] = sortColIdx[scidx++]; - (*partOperators)[*partNumCols] = sgc->eqop; - (*partNumCols)++; - pathkeys = new_pathkeys; - } - } - foreach(lc, wc->orderClause) - { - SortGroupClause *sgc = (SortGroupClause *) lfirst(lc); - List *new_pathkeys; - - sortclauses = lappend(sortclauses, sgc); - new_pathkeys = make_pathkeys_for_sortclauses(root, - sortclauses, - tlist); - if (list_length(new_pathkeys) > list_length(pathkeys)) - { - /* this sort clause is actually significant */ - (*ordColIdx)[*ordNumCols] = sortColIdx[scidx++]; - (*ordOperators)[*ordNumCols] = sgc->eqop; - (*ordNumCols)++; - pathkeys = new_pathkeys; - } - } - /* complain if we didn't eat exactly the right number of sort cols */ - if (scidx != numSortCols) - elog(ERROR, "failed to deconstruct sort operators into partitioning/ordering operators"); - } -} - /* * create_setop_plan * @@ -2483,17 +2613,15 @@ create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path) best_path->operation, best_path->canSetTag, best_path->nominalRelation, - best_path->partitioned_rels, + best_path->rootRelation, best_path->partColsUpdated, best_path->resultRelations, - best_path->mergeTargetRelation, subplans, + best_path->subroots, best_path->withCheckOptionLists, best_path->returningLists, best_path->rowMarks, best_path->onconflict, - best_path->mergeSourceTargetList, - best_path->mergeActionList, best_path->epqParam); copy_generic_path_info(&plan->plan, &best_path->path); @@ -2635,7 +2763,7 @@ create_indexscan_plan(PlannerInfo *root, bool indexonly) { Scan *scan_plan; - List *indexquals = best_path->indexquals; + List *indexclauses = best_path->indexclauses; List *indexorderbys = best_path->indexorderbys; Index baserelid = best_path->path.parent->relid; Oid indexoid = best_path->indexinfo->indexoid; @@ -2651,16 +2779,14 @@ create_indexscan_plan(PlannerInfo *root, Assert(best_path->path.parent->rtekind == RTE_RELATION); /* - * Build "stripped" indexquals structure (no RestrictInfos) to pass to - * executor as indexqualorig + * Extract the index qual expressions (stripped of RestrictInfos) from the + * IndexClauses list, and prepare a copy with index Vars substituted for + * table Vars. (This step also does replace_nestloop_params on the + * fixed_indexquals.) */ - stripped_indexquals = get_actual_clauses(indexquals); - - /* - * The executor needs a copy with the indexkey on the left of each clause - * and with index Vars substituted for table ones. - */ - fixed_indexquals = fix_indexqual_references(root, best_path); + fix_indexqual_references(root, best_path, + &stripped_indexquals, + &fixed_indexquals); /* * Likewise fix up index attr references in the ORDER BY expressions. @@ -2676,14 +2802,14 @@ create_indexscan_plan(PlannerInfo *root, * included in qpqual. The upshot is that qpqual must contain * scan_clauses minus whatever appears in indexquals. * - * In normal cases simple pointer equality checks will be enough to spot - * duplicate RestrictInfos, so we try that first. - * - * Another common case is that a scan_clauses entry is generated from the - * same EquivalenceClass as some indexqual, and is therefore redundant - * with it, though not equal. (This happens when indxpath.c prefers a + * is_redundant_with_indexclauses() detects cases where a scan clause is + * present in the indexclauses list or is generated from the same + * EquivalenceClass as some indexclause, and is therefore redundant with + * it, though not equal. (The latter happens when indxpath.c prefers a * different derived equality than what generate_join_implied_equalities - * picked for a parameterized scan's ppi_clauses.) + * picked for a parameterized scan's ppi_clauses.) Note that it will not + * match to lossy index clauses, which is critical because we have to + * include the original clause in qpqual in that case. * * In some situations (particularly with OR'd index conditions) we may * have scan_clauses that are not equal to, but are logically implied by, @@ -2702,12 +2828,11 @@ create_indexscan_plan(PlannerInfo *root, if (rinfo->pseudoconstant) continue; /* we may drop pseudoconstants here */ - if (list_member_ptr(indexquals, rinfo)) - continue; /* simple duplicate */ - if (is_redundant_derived_clause(rinfo, indexquals)) - continue; /* derived from same EquivalenceClass */ + if (is_redundant_with_indexclauses(rinfo, indexclauses)) + continue; /* dup or derived from same EquivalenceClass */ if (!contain_mutable_functions((Node *) rinfo->clause) && - predicate_implied_by(list_make1(rinfo->clause), indexquals, false)) + predicate_implied_by(list_make1(rinfo->clause), stripped_indexquals, + false)) continue; /* provably implied by indexquals */ qpqual = lappend(qpqual, rinfo); } @@ -3068,6 +3193,8 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, { IndexPath *ipath = (IndexPath *) bitmapqual; IndexScan *iscan; + List *subquals; + List *subindexquals; List *subindexECs; ListCell *l; @@ -3088,8 +3215,23 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, plan->plan_width = 0; /* meaningless */ plan->parallel_aware = false; plan->parallel_safe = ipath->path.parallel_safe; - *qual = get_actual_clauses(ipath->indexclauses); - *indexqual = get_actual_clauses(ipath->indexquals); + /* Extract original index clauses, actual index quals, relevant ECs */ + subquals = NIL; + subindexquals = NIL; + subindexECs = NIL; + foreach(l, ipath->indexclauses) + { + IndexClause *iclause = (IndexClause *) lfirst(l); + RestrictInfo *rinfo = iclause->rinfo; + + Assert(!rinfo->pseudoconstant); + subquals = lappend(subquals, rinfo->clause); + subindexquals = list_concat(subindexquals, + get_actual_clauses(iclause->indexquals)); + if (rinfo->parent_ec) + subindexECs = lappend(subindexECs, rinfo->parent_ec); + } + /* We can add any index predicate conditions, too */ foreach(l, ipath->indexinfo->indpred) { Expr *pred = (Expr *) lfirst(l); @@ -3100,21 +3242,14 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, * the conditions that got pushed into the bitmapqual. Avoid * generating redundant conditions. */ - if (!predicate_implied_by(list_make1(pred), ipath->indexclauses, - false)) + if (!predicate_implied_by(list_make1(pred), subquals, false)) { - *qual = lappend(*qual, pred); - *indexqual = lappend(*indexqual, pred); + subquals = lappend(subquals, pred); + subindexquals = lappend(subindexquals, pred); } } - subindexECs = NIL; - foreach(l, ipath->indexquals) - { - RestrictInfo *rinfo = (RestrictInfo *) lfirst(l); - - if (rinfo->parent_ec) - subindexECs = lappend(subindexECs, rinfo->parent_ec); - } + *qual = subquals; + *indexqual = subindexquals; *indexECs = subindexECs; } else @@ -3138,18 +3273,72 @@ create_tidscan_plan(PlannerInfo *root, TidPath *best_path, TidScan *scan_plan; Index scan_relid = best_path->path.parent->relid; List *tidquals = best_path->tidquals; - List *ortidquals; /* it should be a base rel... */ Assert(scan_relid > 0); Assert(best_path->path.parent->rtekind == RTE_RELATION); + /* + * The qpqual list must contain all restrictions not enforced by the + * tidquals list. Since tidquals has OR semantics, we have to be careful + * about matching it up to scan_clauses. It's convenient to handle the + * single-tidqual case separately from the multiple-tidqual case. In the + * single-tidqual case, we look through the scan_clauses while they are + * still in RestrictInfo form, and drop any that are redundant with the + * tidqual. + * + * In normal cases simple pointer equality checks will be enough to spot + * duplicate RestrictInfos, so we try that first. + * + * Another common case is that a scan_clauses entry is generated from the + * same EquivalenceClass as some tidqual, and is therefore redundant with + * it, though not equal. + * + * Unlike indexpaths, we don't bother with predicate_implied_by(); the + * number of cases where it could win are pretty small. + */ + if (list_length(tidquals) == 1) + { + List *qpqual = NIL; + ListCell *l; + + foreach(l, scan_clauses) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); + + if (rinfo->pseudoconstant) + continue; /* we may drop pseudoconstants here */ + if (list_member_ptr(tidquals, rinfo)) + continue; /* simple duplicate */ + if (is_redundant_derived_clause(rinfo, tidquals)) + continue; /* derived from same EquivalenceClass */ + qpqual = lappend(qpqual, rinfo); + } + scan_clauses = qpqual; + } + /* Sort clauses into best execution order */ scan_clauses = order_qual_clauses(root, scan_clauses); - /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */ + /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */ + tidquals = extract_actual_clauses(tidquals, false); scan_clauses = extract_actual_clauses(scan_clauses, false); + /* + * If we have multiple tidquals, it's more convenient to remove duplicate + * scan_clauses after stripping the RestrictInfos. In this situation, + * because the tidquals represent OR sub-clauses, they could not have come + * from EquivalenceClasses so we don't have to worry about matching up + * non-identical clauses. On the other hand, because tidpath.c will have + * extracted those sub-clauses from some OR clause and built its own list, + * we will certainly not have pointer equality to any scan clause. So + * convert the tidquals list to an explicit OR clause and see if we can + * match it via equal() to any scan clause. + */ + if (list_length(tidquals) > 1) + scan_clauses = list_difference(scan_clauses, + list_make1(make_orclause(tidquals))); + /* Replace any outer-relation variables with nestloop params */ if (best_path->path.param_info) { @@ -3159,15 +3348,6 @@ create_tidscan_plan(PlannerInfo *root, TidPath *best_path, replace_nestloop_params(root, (Node *) scan_clauses); } - /* - * Remove any clauses that are TID quals. This is a bit tricky since the - * tidquals list has implicit OR semantics. - */ - ortidquals = tidquals; - if (list_length(ortidquals) > 1) - ortidquals = list_make1(make_orclause(ortidquals)); - scan_clauses = list_difference(scan_clauses, ortidquals); - scan_plan = make_tidscan(tlist, scan_clauses, scan_relid, @@ -3490,6 +3670,44 @@ create_namedtuplestorescan_plan(PlannerInfo *root, Path *best_path, return scan_plan; } +/* + * create_resultscan_plan + * Returns a Result plan for the RTE_RESULT base relation scanned by + * 'best_path' with restriction clauses 'scan_clauses' and targetlist + * 'tlist'. + */ +static Result * +create_resultscan_plan(PlannerInfo *root, Path *best_path, + List *tlist, List *scan_clauses) +{ + Result *scan_plan; + Index scan_relid = best_path->parent->relid; + RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY; + + Assert(scan_relid > 0); + rte = planner_rt_fetch(scan_relid, root); + Assert(rte->rtekind == RTE_RESULT); + + /* Sort clauses into best execution order */ + scan_clauses = order_qual_clauses(root, scan_clauses); + + /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */ + scan_clauses = extract_actual_clauses(scan_clauses, false); + + /* Replace any outer-relation variables with nestloop params */ + if (best_path->param_info) + { + scan_clauses = (List *) + replace_nestloop_params(root, (Node *) scan_clauses); + } + + scan_plan = make_result(tlist, (Node *) scan_clauses, NULL); + + copy_generic_path_info(&scan_plan->plan, best_path); + + return scan_plan; +} + /* * create_worktablescan_plan * Returns a worktablescan plan for the base relation scanned by 'best_path' @@ -3695,7 +3913,7 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, } /* - * create_custom_plan + * create_customscan_plan * * Transform a CustomPath into a Plan. */ @@ -3784,9 +4002,6 @@ create_nestloop_plan(PlannerInfo *root, Relids outerrelids; List *nestParams; Relids saveOuterRels = root->curOuterRels; - ListCell *cell; - ListCell *prev; - ListCell *next; /* NestLoop can project, so no need to be picky about child tlists */ outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0); @@ -3809,6 +4024,7 @@ create_nestloop_plan(PlannerInfo *root, if (IS_OUTER_JOIN(best_path->jointype)) { extract_actual_join_clauses(joinrestrictclauses, + best_path->path.parent->relids, &joinclauses, &otherclauses); } else @@ -3829,38 +4045,10 @@ create_nestloop_plan(PlannerInfo *root, /* * Identify any nestloop parameters that should be supplied by this join - * node, and move them from root->curOuterParams to the nestParams list. + * node, and remove them from root->curOuterParams. */ outerrelids = best_path->outerjoinpath->parent->relids; - nestParams = NIL; - prev = NULL; - for (cell = list_head(root->curOuterParams); cell; cell = next) - { - NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); - - next = lnext(cell); - if (IsA(nlp->paramval, Var) && - bms_is_member(nlp->paramval->varno, outerrelids)) - { - root->curOuterParams = list_delete_cell(root->curOuterParams, - cell, prev); - nestParams = lappend(nestParams, nlp); - } - else if (IsA(nlp->paramval, PlaceHolderVar) && - bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, - outerrelids) && - bms_is_subset(find_placeholder_info(root, - (PlaceHolderVar *) nlp->paramval, - false)->ph_eval_at, - outerrelids)) - { - root->curOuterParams = list_delete_cell(root->curOuterParams, - cell, prev); - nestParams = lappend(nestParams, nlp); - } - else - prev = cell; - } + nestParams = identify_current_nestloop_params(root, outerrelids); join_plan = make_nestloop(tlist, joinclauses, @@ -3924,6 +4112,7 @@ create_mergejoin_plan(PlannerInfo *root, if (IS_OUTER_JOIN(best_path->jpath.jointype)) { extract_actual_join_clauses(joinclauses, + best_path->jpath.path.parent->relids, &joinclauses, &otherclauses); } else @@ -4074,7 +4263,7 @@ create_mergejoin_plan(PlannerInfo *root, elog(ERROR, "outer pathkeys do not match mergeclauses"); opathkey = (PathKey *) lfirst(lop); opeclass = opathkey->pk_eclass; - lop = lnext(lop); + lop = lnext(outerpathkeys, lop); if (oeclass != opeclass) elog(ERROR, "outer pathkeys do not match mergeclauses"); } @@ -4101,7 +4290,7 @@ create_mergejoin_plan(PlannerInfo *root, if (ieclass == ipeclass) { /* successful first match to this inner pathkey */ - lip = lnext(lip); + lip = lnext(innerpathkeys, lip); first_inner_match = true; } } @@ -4194,9 +4383,14 @@ create_hashjoin_plan(PlannerInfo *root, List *joinclauses; List *otherclauses; List *hashclauses; + List *hashoperators = NIL; + List *hashcollations = NIL; + List *inner_hashkeys = NIL; + List *outer_hashkeys = NIL; Oid skewTable = InvalidOid; AttrNumber skewColumn = InvalidAttrNumber; bool skewInherit = false; + ListCell *lc; /* * HashJoin can project, so we don't have to demand exact tlists from the @@ -4220,6 +4414,7 @@ create_hashjoin_plan(PlannerInfo *root, if (IS_OUTER_JOIN(best_path->jpath.jointype)) { extract_actual_join_clauses(joinclauses, + best_path->jpath.path.parent->relids, &joinclauses, &otherclauses); } else @@ -4287,10 +4482,29 @@ create_hashjoin_plan(PlannerInfo *root, } } + /* + * Collect hash related information. The hashed expressions are + * deconstructed into outer/inner expressions, so they can be computed + * separately (inner expressions are used to build the hashtable via Hash, + * outer expressions to perform lookups of tuples from HashJoin's outer + * plan in the hashtable). Also collect operator information necessary to + * build the hashtable. + */ + foreach(lc, hashclauses) + { + OpExpr *hclause = lfirst_node(OpExpr, lc); + + hashoperators = lappend_oid(hashoperators, hclause->opno); + hashcollations = lappend_oid(hashcollations, hclause->inputcollid); + outer_hashkeys = lappend(outer_hashkeys, linitial(hclause->args)); + inner_hashkeys = lappend(inner_hashkeys, lsecond(hclause->args)); + } + /* * Build the hash node and hash join node. */ hash_plan = make_hash(inner_plan, + inner_hashkeys, skewTable, skewColumn, skewInherit); @@ -4317,6 +4531,9 @@ create_hashjoin_plan(PlannerInfo *root, joinclauses, otherclauses, hashclauses, + hashoperators, + hashcollations, + outer_hashkeys, outer_plan, (Plan *) hash_plan, best_path->jpath.jointype, @@ -4358,42 +4575,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) if (IsA(node, Var)) { Var *var = (Var *) node; - Param *param; - NestLoopParam *nlp; - ListCell *lc; /* Upper-level Vars should be long gone at this point */ Assert(var->varlevelsup == 0); /* If not to be replaced, we can just return the Var unmodified */ if (!bms_is_member(var->varno, root->curOuterRels)) return node; - /* Create a Param representing the Var */ - param = assign_nestloop_param_var(root, var); - /* Is this param already listed in root->curOuterParams? */ - foreach(lc, root->curOuterParams) - { - nlp = (NestLoopParam *) lfirst(lc); - if (nlp->paramno == param->paramid) - { - Assert(equal(var, nlp->paramval)); - /* Present, so we can just return the Param */ - return (Node *) param; - } - } - /* No, so add it */ - nlp = makeNode(NestLoopParam); - nlp->paramno = param->paramid; - nlp->paramval = var; - root->curOuterParams = lappend(root->curOuterParams, nlp); - /* And return the replacement Param */ - return (Node *) param; + /* Replace the Var with a nestloop Param */ + return (Node *) replace_nestloop_param_var(root, var); } if (IsA(node, PlaceHolderVar)) { PlaceHolderVar *phv = (PlaceHolderVar *) node; - Param *param; - NestLoopParam *nlp; - ListCell *lc; /* Upper-level PlaceHolderVars should be long gone at this point */ Assert(phv->phlevelsup == 0); @@ -4430,255 +4623,65 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) root); return (Node *) newphv; } - /* Create a Param representing the PlaceHolderVar */ - param = assign_nestloop_param_placeholdervar(root, phv); - /* Is this param already listed in root->curOuterParams? */ - foreach(lc, root->curOuterParams) - { - nlp = (NestLoopParam *) lfirst(lc); - if (nlp->paramno == param->paramid) - { - Assert(equal(phv, nlp->paramval)); - /* Present, so we can just return the Param */ - return (Node *) param; - } - } - /* No, so add it */ - nlp = makeNode(NestLoopParam); - nlp->paramno = param->paramid; - nlp->paramval = (Var *) phv; - root->curOuterParams = lappend(root->curOuterParams, nlp); - /* And return the replacement Param */ - return (Node *) param; + /* Replace the PlaceHolderVar with a nestloop Param */ + return (Node *) replace_nestloop_param_placeholdervar(root, phv); } return expression_tree_mutator(node, replace_nestloop_params_mutator, (void *) root); } -/* - * process_subquery_nestloop_params - * Handle params of a parameterized subquery that need to be fed - * from an outer nestloop. - * - * Currently, that would be *all* params that a subquery in FROM has demanded - * from the current query level, since they must be LATERAL references. - * - * The subplan's references to the outer variables are already represented - * as PARAM_EXEC Params, so we need not modify the subplan here. What we - * do need to do is add entries to root->curOuterParams to signal the parent - * nestloop plan node that it must provide these values. - */ -static void -process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) -{ - ListCell *ppl; - - foreach(ppl, subplan_params) - { - PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl); - - if (IsA(pitem->item, Var)) - { - Var *var = (Var *) pitem->item; - NestLoopParam *nlp; - ListCell *lc; - - /* If not from a nestloop outer rel, complain */ - if (!bms_is_member(var->varno, root->curOuterRels)) - elog(ERROR, "non-LATERAL parameter required by subquery"); - /* Is this param already listed in root->curOuterParams? */ - foreach(lc, root->curOuterParams) - { - nlp = (NestLoopParam *) lfirst(lc); - if (nlp->paramno == pitem->paramId) - { - Assert(equal(var, nlp->paramval)); - /* Present, so nothing to do */ - break; - } - } - if (lc == NULL) - { - /* No, so add it */ - nlp = makeNode(NestLoopParam); - nlp->paramno = pitem->paramId; - nlp->paramval = copyObject(var); - root->curOuterParams = lappend(root->curOuterParams, nlp); - } - } - else if (IsA(pitem->item, PlaceHolderVar)) - { - PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; - NestLoopParam *nlp; - ListCell *lc; - - /* If not from a nestloop outer rel, complain */ - if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, - root->curOuterRels)) - elog(ERROR, "non-LATERAL parameter required by subquery"); - /* Is this param already listed in root->curOuterParams? */ - foreach(lc, root->curOuterParams) - { - nlp = (NestLoopParam *) lfirst(lc); - if (nlp->paramno == pitem->paramId) - { - Assert(equal(phv, nlp->paramval)); - /* Present, so nothing to do */ - break; - } - } - if (lc == NULL) - { - /* No, so add it */ - nlp = makeNode(NestLoopParam); - nlp->paramno = pitem->paramId; - nlp->paramval = (Var *) copyObject(phv); - root->curOuterParams = lappend(root->curOuterParams, nlp); - } - } - else - elog(ERROR, "unexpected type of subquery parameter"); - } -} - /* * fix_indexqual_references * Adjust indexqual clauses to the form the executor's indexqual * machinery needs. * - * We have four tasks here: - * * Remove RestrictInfo nodes from the input clauses. + * We have three tasks here: + * * Select the actual qual clauses out of the input IndexClause list, + * and remove RestrictInfo nodes from the qual clauses. * * Replace any outer-relation Var or PHV nodes with nestloop Params. * (XXX eventually, that responsibility should go elsewhere?) * * Index keys must be represented by Var nodes with varattno set to the * index's attribute number, not the attribute number in the original rel. - * * If the index key is on the right, commute the clause to put it on the - * left. * - * The result is a modified copy of the path's indexquals list --- the - * original is not changed. Note also that the copy shares no substructure - * with the original; this is needed in case there is a subplan in it (we need - * two separate copies of the subplan tree, or things will go awry). + * *stripped_indexquals_p receives a list of the actual qual clauses. + * + * *fixed_indexquals_p receives a list of the adjusted quals. This is a copy + * that shares no substructure with the original; this is needed in case there + * are subplans in it (we need two separate copies of the subplan tree, or + * things will go awry). */ -static List * -fix_indexqual_references(PlannerInfo *root, IndexPath *index_path) +static void +fix_indexqual_references(PlannerInfo *root, IndexPath *index_path, + List **stripped_indexquals_p, List **fixed_indexquals_p) { IndexOptInfo *index = index_path->indexinfo; + List *stripped_indexquals; List *fixed_indexquals; - ListCell *lcc, - *lci; + ListCell *lc; - fixed_indexquals = NIL; + stripped_indexquals = fixed_indexquals = NIL; - forboth(lcc, index_path->indexquals, lci, index_path->indexqualcols) + foreach(lc, index_path->indexclauses) { - RestrictInfo *rinfo = lfirst_node(RestrictInfo, lcc); - int indexcol = lfirst_int(lci); - Node *clause; - - /* - * Replace any outer-relation variables with nestloop params. - * - * This also makes a copy of the clause, so it's safe to modify it - * in-place below. - */ - clause = replace_nestloop_params(root, (Node *) rinfo->clause); - - if (IsA(clause, OpExpr)) - { - OpExpr *op = (OpExpr *) clause; - - if (list_length(op->args) != 2) - elog(ERROR, "indexqual clause is not binary opclause"); + IndexClause *iclause = lfirst_node(IndexClause, lc); + int indexcol = iclause->indexcol; + ListCell *lc2; - /* - * Check to see if the indexkey is on the right; if so, commute - * the clause. The indexkey should be the side that refers to - * (only) the base relation. - */ - if (!bms_equal(rinfo->left_relids, index->rel->relids)) - CommuteOpExpr(op); - - /* - * Now replace the indexkey expression with an index Var. - */ - linitial(op->args) = fix_indexqual_operand(linitial(op->args), - index, - indexcol); - } - else if (IsA(clause, RowCompareExpr)) - { - RowCompareExpr *rc = (RowCompareExpr *) clause; - Expr *newrc; - List *indexcolnos; - bool var_on_left; - ListCell *lca, - *lcai; - - /* - * Re-discover which index columns are used in the rowcompare. - */ - newrc = adjust_rowcompare_for_index(rc, - index, - indexcol, - &indexcolnos, - &var_on_left); - - /* - * Trouble if adjust_rowcompare_for_index thought the - * RowCompareExpr didn't match the index as-is; the clause should - * have gone through that routine already. - */ - if (newrc != (Expr *) rc) - elog(ERROR, "inconsistent results from adjust_rowcompare_for_index"); - - /* - * Check to see if the indexkey is on the right; if so, commute - * the clause. - */ - if (!var_on_left) - CommuteRowCompareExpr(rc); - - /* - * Now replace the indexkey expressions with index Vars. - */ - Assert(list_length(rc->largs) == list_length(indexcolnos)); - forboth(lca, rc->largs, lcai, indexcolnos) - { - lfirst(lca) = fix_indexqual_operand(lfirst(lca), - index, - lfirst_int(lcai)); - } - } - else if (IsA(clause, ScalarArrayOpExpr)) + foreach(lc2, iclause->indexquals) { - ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2); + Node *clause = (Node *) rinfo->clause; - /* Never need to commute... */ - - /* Replace the indexkey expression with an index Var. */ - linitial(saop->args) = fix_indexqual_operand(linitial(saop->args), - index, - indexcol); + stripped_indexquals = lappend(stripped_indexquals, clause); + clause = fix_indexqual_clause(root, index, indexcol, + clause, iclause->indexcols); + fixed_indexquals = lappend(fixed_indexquals, clause); } - else if (IsA(clause, NullTest)) - { - NullTest *nt = (NullTest *) clause; - - /* Replace the indexkey expression with an index Var. */ - nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg, - index, - indexcol); - } - else - elog(ERROR, "unsupported indexqual type: %d", - (int) nodeTag(clause)); - - fixed_indexquals = lappend(fixed_indexquals, clause); } - return fixed_indexquals; + *stripped_indexquals_p = stripped_indexquals; + *fixed_indexquals_p = fixed_indexquals; } /* @@ -4686,11 +4689,8 @@ fix_indexqual_references(PlannerInfo *root, IndexPath *index_path) * Adjust indexorderby clauses to the form the executor's index * machinery needs. * - * This is a simplified version of fix_indexqual_references. The input does - * not have RestrictInfo nodes, and we assume that indxpath.c already - * commuted the clauses to put the index keys on the left. Also, we don't - * bother to support any cases except simple OpExprs, since nothing else - * is allowed for ordering operators. + * This is a simplified version of fix_indexqual_references. The input is + * bare clauses and a separate indexcol list, instead of IndexClauses. */ static List * fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path) @@ -4707,36 +4707,79 @@ fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path) Node *clause = (Node *) lfirst(lcc); int indexcol = lfirst_int(lci); - /* - * Replace any outer-relation variables with nestloop params. - * - * This also makes a copy of the clause, so it's safe to modify it - * in-place below. - */ - clause = replace_nestloop_params(root, clause); + clause = fix_indexqual_clause(root, index, indexcol, clause, NIL); + fixed_indexorderbys = lappend(fixed_indexorderbys, clause); + } - if (IsA(clause, OpExpr)) - { - OpExpr *op = (OpExpr *) clause; + return fixed_indexorderbys; +} - if (list_length(op->args) != 2) - elog(ERROR, "indexorderby clause is not binary opclause"); +/* + * fix_indexqual_clause + * Convert a single indexqual clause to the form needed by the executor. + * + * We replace nestloop params here, and replace the index key variables + * or expressions by index Var nodes. + */ +static Node * +fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol, + Node *clause, List *indexcolnos) +{ + /* + * Replace any outer-relation variables with nestloop params. + * + * This also makes a copy of the clause, so it's safe to modify it + * in-place below. + */ + clause = replace_nestloop_params(root, clause); - /* - * Now replace the indexkey expression with an index Var. - */ - linitial(op->args) = fix_indexqual_operand(linitial(op->args), - index, - indexcol); + if (IsA(clause, OpExpr)) + { + OpExpr *op = (OpExpr *) clause; + + /* Replace the indexkey expression with an index Var. */ + linitial(op->args) = fix_indexqual_operand(linitial(op->args), + index, + indexcol); + } + else if (IsA(clause, RowCompareExpr)) + { + RowCompareExpr *rc = (RowCompareExpr *) clause; + ListCell *lca, + *lcai; + + /* Replace the indexkey expressions with index Vars. */ + Assert(list_length(rc->largs) == list_length(indexcolnos)); + forboth(lca, rc->largs, lcai, indexcolnos) + { + lfirst(lca) = fix_indexqual_operand(lfirst(lca), + index, + lfirst_int(lcai)); } - else - elog(ERROR, "unsupported indexorderby type: %d", - (int) nodeTag(clause)); + } + else if (IsA(clause, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; - fixed_indexorderbys = lappend(fixed_indexorderbys, clause); + /* Replace the indexkey expression with an index Var. */ + linitial(saop->args) = fix_indexqual_operand(linitial(saop->args), + index, + indexcol); } + else if (IsA(clause, NullTest)) + { + NullTest *nt = (NullTest *) clause; - return fixed_indexorderbys; + /* Replace the indexkey expression with an index Var. */ + nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg, + index, + indexcol); + } + else + elog(ERROR, "unsupported indexqual type: %d", + (int) nodeTag(clause)); + + return clause; } /* @@ -4806,7 +4849,7 @@ fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol) else elog(ERROR, "index key does not match expected index column"); } - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(index->indexprs, indexpr_item); } } @@ -5416,25 +5459,6 @@ make_foreignscan(List *qptlist, return node; } -static Append * -make_append(List *appendplans, int first_partial_plan, - List *tlist, List *partitioned_rels, - List *partpruneinfos) -{ - Append *node = makeNode(Append); - Plan *plan = &node->plan; - - plan->targetlist = tlist; - plan->qual = NIL; - plan->lefttree = NULL; - plan->righttree = NULL; - node->partitioned_rels = partitioned_rels; - node->appendplans = appendplans; - node->first_partial_plan = first_partial_plan; - node->part_prune_infos = partpruneinfos; - return node; -} - static RecursiveUnion * make_recursive_union(List *tlist, Plan *lefttree, @@ -5463,10 +5487,12 @@ make_recursive_union(List *tlist, int keyno = 0; AttrNumber *dupColIdx; Oid *dupOperators; + Oid *dupCollations; ListCell *slitem; dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols); dupOperators = (Oid *) palloc(sizeof(Oid) * numCols); + dupCollations = (Oid *) palloc(sizeof(Oid) * numCols); foreach(slitem, distinctList) { @@ -5476,11 +5502,13 @@ make_recursive_union(List *tlist, dupColIdx[keyno] = tle->resno; dupOperators[keyno] = sortcl->eqop; + dupCollations[keyno] = exprCollation((Node *) tle->expr); Assert(OidIsValid(dupOperators[keyno])); keyno++; } node->dupColIdx = dupColIdx; node->dupOperators = dupOperators; + node->dupCollations = dupCollations; } node->numGroups = numGroups; @@ -5547,6 +5575,9 @@ make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, + List *hashoperators, + List *hashcollations, + List *hashkeys, Plan *lefttree, Plan *righttree, JoinType jointype, @@ -5560,6 +5591,9 @@ make_hashjoin(List *tlist, plan->lefttree = lefttree; plan->righttree = righttree; node->hashclauses = hashclauses; + node->hashoperators = hashoperators; + node->hashcollations = hashcollations; + node->hashkeys = hashkeys; node->join.jointype = jointype; node->join.inner_unique = inner_unique; node->join.joinqual = joinclauses; @@ -5569,6 +5603,7 @@ make_hashjoin(List *tlist, static Hash * make_hash(Plan *lefttree, + List *hashkeys, Oid skewTable, AttrNumber skewColumn, bool skewInherit) @@ -5581,6 +5616,7 @@ make_hash(Plan *lefttree, plan->lefttree = lefttree; plan->righttree = NULL; + node->hashkeys = hashkeys; node->skewTable = skewTable; node->skewColumn = skewColumn; node->skewInherit = skewInherit; @@ -6152,7 +6188,7 @@ materialize_finished_plan(Plan *subplan) Agg * make_agg(List *tlist, List *qual, AggStrategy aggstrategy, AggSplit aggsplit, - int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, + int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, List *groupingSets, List *chain, double dNumGroups, Plan *lefttree) { @@ -6168,6 +6204,7 @@ make_agg(List *tlist, List *qual, node->numCols = numGroupCols; node->grpColIdx = grpColIdx; node->grpOperators = grpOperators; + node->grpCollations = grpCollations; node->numGroups = numGroups; node->aggParams = NULL; /* SS_finalize_plan() will fill this */ node->groupingSets = groupingSets; @@ -6183,8 +6220,8 @@ make_agg(List *tlist, List *qual, static WindowAgg * make_windowagg(List *tlist, Index winref, - int partNumCols, AttrNumber *partColIdx, Oid *partOperators, - int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, + int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, + int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, int frameOptions, Node *startOffset, Node *endOffset, Oid startInRangeFunc, Oid endInRangeFunc, Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst, @@ -6197,9 +6234,11 @@ make_windowagg(List *tlist, Index winref, node->partNumCols = partNumCols; node->partColIdx = partColIdx; node->partOperators = partOperators; + node->partCollations = partCollations; node->ordNumCols = ordNumCols; node->ordColIdx = ordColIdx; node->ordOperators = ordOperators; + node->ordCollations = ordCollations; node->frameOptions = frameOptions; node->startOffset = startOffset; node->endOffset = endOffset; @@ -6224,6 +6263,7 @@ make_group(List *tlist, int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, + Oid *grpCollations, Plan *lefttree) { Group *node = makeNode(Group); @@ -6232,6 +6272,7 @@ make_group(List *tlist, node->numCols = numGroupCols; node->grpColIdx = grpColIdx; node->grpOperators = grpOperators; + node->grpCollations = grpCollations; plan->qual = qual; plan->targetlist = tlist; @@ -6255,6 +6296,7 @@ make_unique_from_sortclauses(Plan *lefttree, List *distinctList) int keyno = 0; AttrNumber *uniqColIdx; Oid *uniqOperators; + Oid *uniqCollations; ListCell *slitem; plan->targetlist = lefttree->targetlist; @@ -6269,6 +6311,7 @@ make_unique_from_sortclauses(Plan *lefttree, List *distinctList) Assert(numCols > 0); uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols); uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols); + uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols); foreach(slitem, distinctList) { @@ -6277,6 +6320,7 @@ make_unique_from_sortclauses(Plan *lefttree, List *distinctList) uniqColIdx[keyno] = tle->resno; uniqOperators[keyno] = sortcl->eqop; + uniqCollations[keyno] = exprCollation((Node *) tle->expr); Assert(OidIsValid(uniqOperators[keyno])); keyno++; } @@ -6284,6 +6328,7 @@ make_unique_from_sortclauses(Plan *lefttree, List *distinctList) node->numCols = numCols; node->uniqColIdx = uniqColIdx; node->uniqOperators = uniqOperators; + node->uniqCollations = uniqCollations; return node; } @@ -6299,6 +6344,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) int keyno = 0; AttrNumber *uniqColIdx; Oid *uniqOperators; + Oid *uniqCollations; ListCell *lc; plan->targetlist = lefttree->targetlist; @@ -6314,6 +6360,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) Assert(numCols >= 0 && numCols <= list_length(pathkeys)); uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols); uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols); + uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols); foreach(lc, pathkeys) { @@ -6382,6 +6429,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) uniqColIdx[keyno] = tle->resno; uniqOperators[keyno] = eqop; + uniqCollations[keyno] = ec->ec_collation; keyno++; } @@ -6389,6 +6437,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) node->numCols = numCols; node->uniqColIdx = uniqColIdx; node->uniqOperators = uniqOperators; + node->uniqCollations = uniqCollations; return node; } @@ -6433,6 +6482,7 @@ make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, int keyno = 0; AttrNumber *dupColIdx; Oid *dupOperators; + Oid *dupCollations; ListCell *slitem; plan->targetlist = lefttree->targetlist; @@ -6446,6 +6496,7 @@ make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, */ dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols); dupOperators = (Oid *) palloc(sizeof(Oid) * numCols); + dupCollations = (Oid *) palloc(sizeof(Oid) * numCols); foreach(slitem, distinctList) { @@ -6454,6 +6505,7 @@ make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, dupColIdx[keyno] = tle->resno; dupOperators[keyno] = sortcl->eqop; + dupCollations[keyno] = exprCollation((Node *) tle->expr); Assert(OidIsValid(dupOperators[keyno])); keyno++; } @@ -6463,6 +6515,7 @@ make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree, node->numCols = numCols; node->dupColIdx = dupColIdx; node->dupOperators = dupOperators; + node->dupCollations = dupCollations; node->flagColIdx = flagColIdx; node->firstFlag = firstFlag; node->numGroups = numGroups; @@ -6559,23 +6612,21 @@ make_project_set(List *tlist, static ModifyTable * make_modifytable(PlannerInfo *root, CmdType operation, bool canSetTag, - Index nominalRelation, List *partitioned_rels, + Index nominalRelation, Index rootRelation, bool partColsUpdated, - List *resultRelations, - Index mergeTargetRelation, - List *subplans, + List *resultRelations, List *subplans, List *subroots, List *withCheckOptionLists, List *returningLists, - List *rowMarks, OnConflictExpr *onconflict, - List *mergeSourceTargetList, - List *mergeActionList, int epqParam) + List *rowMarks, OnConflictExpr *onconflict, int epqParam) { ModifyTable *node = makeNode(ModifyTable); List *fdw_private_list; Bitmapset *direct_modify_plans; ListCell *lc; + ListCell *lc2; int i; Assert(list_length(resultRelations) == list_length(subplans)); + Assert(list_length(resultRelations) == list_length(subroots)); Assert(withCheckOptionLists == NIL || list_length(resultRelations) == list_length(withCheckOptionLists)); Assert(returningLists == NIL || @@ -6590,10 +6641,9 @@ make_modifytable(PlannerInfo *root, node->operation = operation; node->canSetTag = canSetTag; node->nominalRelation = nominalRelation; - node->partitioned_rels = partitioned_rels; + node->rootRelation = rootRelation; node->partColsUpdated = partColsUpdated; node->resultRelations = resultRelations; - node->mergeTargetRelation = mergeTargetRelation; node->resultRelIndex = -1; /* will be set correctly in setrefs.c */ node->rootResultRelIndex = -1; /* will be set correctly in setrefs.c */ node->plans = subplans; @@ -6626,8 +6676,6 @@ make_modifytable(PlannerInfo *root, node->withCheckOptionLists = withCheckOptionLists; node->returningLists = returningLists; node->rowMarks = rowMarks; - node->mergeSourceTargetList = mergeSourceTargetList; - node->mergeActionList = mergeActionList; node->epqParam = epqParam; /* @@ -6637,9 +6685,10 @@ make_modifytable(PlannerInfo *root, fdw_private_list = NIL; direct_modify_plans = NULL; i = 0; - foreach(lc, resultRelations) + forboth(lc, resultRelations, lc2, subroots) { Index rti = lfirst_int(lc); + PlannerInfo *subroot = lfirst_node(PlannerInfo, lc2); FdwRoutine *fdwroutine; List *fdw_private; bool direct_modify; @@ -6651,16 +6700,16 @@ make_modifytable(PlannerInfo *root, * so it's not a baserel; and there are also corner cases for * updatable views where the target rel isn't a baserel.) */ - if (rti < root->simple_rel_array_size && - root->simple_rel_array[rti] != NULL) + if (rti < subroot->simple_rel_array_size && + subroot->simple_rel_array[rti] != NULL) { - RelOptInfo *resultRel = root->simple_rel_array[rti]; + RelOptInfo *resultRel = subroot->simple_rel_array[rti]; fdwroutine = resultRel->fdwroutine; } else { - RangeTblEntry *rte = planner_rt_fetch(rti, root); + RangeTblEntry *rte = planner_rt_fetch(rti, subroot); Assert(rte->rtekind == RTE_RELATION); if (rte->relkind == RELKIND_FOREIGN_TABLE) @@ -6671,8 +6720,9 @@ make_modifytable(PlannerInfo *root, /* * Try to modify the foreign table directly if (1) the FDW provides - * callback functions needed for that, (2) there are no row-level - * triggers on the foreign table, and (3) there are no WITH CHECK + * callback functions needed for that and (2) there are no local + * structures that need to be run for each modified row: row-level + * triggers on the foreign table, stored generated columns, WITH CHECK * OPTIONs from parent views. */ direct_modify = false; @@ -6682,15 +6732,16 @@ make_modifytable(PlannerInfo *root, fdwroutine->IterateDirectModify != NULL && fdwroutine->EndDirectModify != NULL && withCheckOptionLists == NIL && - !has_row_triggers(root, rti, operation)) - direct_modify = fdwroutine->PlanDirectModify(root, node, rti, i); + !has_row_triggers(subroot, rti, operation) && + !has_stored_generated_columns(subroot, rti)) + direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i); if (direct_modify) direct_modify_plans = bms_add_member(direct_modify_plans, i); if (!direct_modify && fdwroutine != NULL && fdwroutine->PlanForeignModify != NULL) - fdw_private = fdwroutine->PlanForeignModify(root, node, rti, i); + fdw_private = fdwroutine->PlanForeignModify(subroot, node, rti, i); else fdw_private = NIL; fdw_private_list = lappend(fdw_private_list, fdw_private); @@ -6726,12 +6777,11 @@ is_projection_capable_path(Path *path) case T_Append: /* - * Append can't project, but if it's being used to represent a - * dummy path, claim that it can project. This prevents us from - * converting a rel from dummy to non-dummy status by applying a - * projection to its dummy path. + * Append can't project, but if an AppendPath is being used to + * represent a dummy path, what will actually be generated is a + * Result which can project. */ - return IS_DUMMY_PATH(path); + return IS_DUMMY_APPEND(path); case T_ProjectSet: /* diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index a436b538062..274fea076cb 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -3,7 +3,7 @@ * initsplan.c * Target list, qualification, joininfo initialization routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,10 +16,13 @@ #include "catalog/pg_type.h" #include "catalog/pg_class.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/inherit.h" #include "optimizer/joininfo.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/placeholder.h" @@ -27,7 +30,6 @@ #include "optimizer/planner.h" #include "optimizer/prep.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" #include "parser/analyze.h" #include "rewrite/rewriteManip.h" #include "utils/lsyscache.h" @@ -47,33 +49,33 @@ typedef struct PostponedQual static void extract_lateral_references(PlannerInfo *root, RelOptInfo *brel, - Index rtindex); + Index rtindex); static List *deconstruct_recurse(PlannerInfo *root, Node *jtnode, - bool below_outer_join, - Relids *qualscope, Relids *inner_join_rels, - List **postponed_qual_list); + bool below_outer_join, + Relids *qualscope, Relids *inner_join_rels, + List **postponed_qual_list); static void process_security_barrier_quals(PlannerInfo *root, - int rti, Relids qualscope, - bool below_outer_join); + int rti, Relids qualscope, + bool below_outer_join); static SpecialJoinInfo *make_outerjoininfo(PlannerInfo *root, - Relids left_rels, Relids right_rels, - Relids inner_join_rels, - JoinType jointype, List *clause); + Relids left_rels, Relids right_rels, + Relids inner_join_rels, + JoinType jointype, List *clause); static void compute_semijoin_info(SpecialJoinInfo *sjinfo, List *clause); static void distribute_qual_to_rels(PlannerInfo *root, Node *clause, - bool is_deduced, - bool below_outer_join, - JoinType jointype, - Index security_level, - Relids qualscope, - Relids ojscope, - Relids outerjoin_nonnullable, - Relids deduced_nullable_relids, - List **postponed_qual_list); + bool is_deduced, + bool below_outer_join, + JoinType jointype, + Index security_level, + Relids qualscope, + Relids ojscope, + Relids outerjoin_nonnullable, + Relids deduced_nullable_relids, + List **postponed_qual_list); static bool check_outerjoin_delay(PlannerInfo *root, Relids *relids_p, - Relids *nullable_relids_p, bool is_pushed_down); + Relids *nullable_relids_p, bool is_pushed_down); static bool check_equivalence_delay(PlannerInfo *root, - RestrictInfo *restrictinfo); + RestrictInfo *restrictinfo); static bool check_redundant_nullability_qual(PlannerInfo *root, Node *clause); static void check_mergejoinable(RestrictInfo *restrictinfo); static void check_hashjoinable(RestrictInfo *restrictinfo); @@ -89,17 +91,16 @@ static void check_hashjoinable(RestrictInfo *restrictinfo); * add_base_rels_to_query * * Scan the query's jointree and create baserel RelOptInfos for all - * the base relations (ie, table, subquery, and function RTEs) + * the base relations (e.g., table, subquery, and function RTEs) * appearing in the jointree. * * The initial invocation must pass root->parse->jointree as the value of * jtnode. Internally, the function recurses through the jointree. * * At the end of this process, there should be one baserel RelOptInfo for - * every non-join RTE that is used in the query. Therefore, this routine - * is the only place that should call build_simple_rel with reloptkind - * RELOPT_BASEREL. (Note: build_simple_rel recurses internally to build - * "other rel" RelOptInfos for the members of any appendrels we find here.) + * every non-join RTE that is used in the query. Some of the baserels + * may be appendrel parents, which will require additional "otherrel" + * RelOptInfos for their member rels, but those are added later. */ void add_base_rels_to_query(PlannerInfo *root, Node *jtnode) @@ -132,6 +133,37 @@ add_base_rels_to_query(PlannerInfo *root, Node *jtnode) (int) nodeTag(jtnode)); } +/* + * add_other_rels_to_query + * create "otherrel" RelOptInfos for the children of appendrel baserels + * + * At the end of this process, there should be RelOptInfos for all relations + * that will be scanned by the query. + */ +void +add_other_rels_to_query(PlannerInfo *root) +{ + int rti; + + for (rti = 1; rti < root->simple_rel_array_size; rti++) + { + RelOptInfo *rel = root->simple_rel_array[rti]; + RangeTblEntry *rte = root->simple_rte_array[rti]; + + /* there may be empty slots corresponding to non-baserel RTEs */ + if (rel == NULL) + continue; + + /* Ignore any "otherrels" that were already added. */ + if (rel->reloptkind != RELOPT_BASEREL) + continue; + + /* If it's marked as inheritable, look for children. */ + if (rte->inh) + expand_inherited_rtentry(root, rel, rte, rti); + } +} + /***************************************************************************** * @@ -616,64 +648,6 @@ create_lateral_join_info(PlannerInfo *root) bms_add_member(brel2->lateral_referencers, rti); } } - - /* - * Lastly, propagate lateral_relids and lateral_referencers from appendrel - * parent rels to their child rels. We intentionally give each child rel - * the same minimum parameterization, even though it's quite possible that - * some don't reference all the lateral rels. This is because any append - * path for the parent will have to have the same parameterization for - * every child anyway, and there's no value in forcing extra - * reparameterize_path() calls. Similarly, a lateral reference to the - * parent prevents use of otherwise-movable join rels for each child. - */ - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; - RangeTblEntry *brte = root->simple_rte_array[rti]; - - /* - * Skip empty slots. Also skip non-simple relations i.e. dead - * relations. - */ - if (brel == NULL || !IS_SIMPLE_REL(brel)) - continue; - - /* - * In the case of table inheritance, the parent RTE is directly linked - * to every child table via an AppendRelInfo. In the case of table - * partitioning, the inheritance hierarchy is expanded one level at a - * time rather than flattened. Therefore, an other member rel that is - * a partitioned table may have children of its own, and must - * therefore be marked with the appropriate lateral info so that those - * children eventually get marked also. - */ - Assert(brte); - if (brel->reloptkind == RELOPT_OTHER_MEMBER_REL && - (brte->rtekind != RTE_RELATION || - brte->relkind != RELKIND_PARTITIONED_TABLE)) - continue; - - if (brte->inh) - { - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc); - RelOptInfo *childrel; - - if (appinfo->parent_relid != rti) - continue; - childrel = root->simple_rel_array[appinfo->child_relid]; - Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL); - Assert(childrel->direct_lateral_relids == NULL); - childrel->direct_lateral_relids = brel->direct_lateral_relids; - Assert(childrel->lateral_relids == NULL); - childrel->lateral_relids = brel->lateral_relids; - Assert(childrel->lateral_referencers == NULL); - childrel->lateral_referencers = brel->lateral_referencers; - } - } - } } @@ -827,7 +801,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, * all below it, so we should report inner_join_rels = qualscope. If * there was exactly one element, we should (and already did) report * whatever its inner_join_rels were. If there were no elements (is - * that possible?) the initialization before the loop fixed it. + * that still possible?) the initialization before the loop fixed it. */ if (list_length(f->fromlist) > 1) *inner_join_rels = *qualscope; @@ -999,7 +973,6 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, *postponed_qual_list = lappend(*postponed_qual_list, pq); } } - /* list_concat is nondestructive of its second argument */ my_quals = list_concat(my_quals, (List *) j->quals); /* @@ -1775,6 +1748,11 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, * attach quals to the lowest level where they can be evaluated. But * if we were ever to re-introduce a mechanism for delaying evaluation * of "expensive" quals, this area would need work. + * + * Note: generally, use of is_pushed_down has to go through the macro + * RINFO_IS_PUSHED_DOWN, because that flag alone is not always sufficient + * to tell whether a clause must be treated as pushed-down in context. + * This seems like another reason why it should perhaps be rethought. *---------- */ if (is_deduced) diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c index 95cbffbd694..9381939c822 100644 --- a/src/backend/optimizer/plan/planagg.c +++ b/src/backend/optimizer/plan/planagg.c @@ -17,7 +17,7 @@ * scan all the rows anyway. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,6 +35,7 @@ #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" @@ -49,7 +50,7 @@ static bool find_minmax_aggs_walker(Node *node, List **context); static bool build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, - Oid eqop, Oid sortop, bool nulls_first); + Oid eqop, Oid sortop, bool nulls_first); static void minmax_qp_callback(PlannerInfo *root, void *extra); static Oid fetch_agg_sort_op(Oid aggfnoid); @@ -67,12 +68,9 @@ static Oid fetch_agg_sort_op(Oid aggfnoid); * planner's state and invoking query_planner() on a modified version of * the query parsetree. Thus, all preprocessing needed before query_planner() * must already be done. - * - * Note: we are passed the preprocessed targetlist separately, because it's - * not necessarily equal to root->parse->targetList. */ void -preprocess_minmax_aggregates(PlannerInfo *root, List *tlist) +preprocess_minmax_aggregates(PlannerInfo *root) { Query *parse = root->parse; FromExpr *jtnode; @@ -143,7 +141,7 @@ preprocess_minmax_aggregates(PlannerInfo *root, List *tlist) * all are MIN/MAX aggregates. Stop as soon as we find one that isn't. */ aggs_list = NIL; - if (find_minmax_aggs_walker((Node *) tlist, &aggs_list)) + if (find_minmax_aggs_walker((Node *) root->processed_tlist, &aggs_list)) return; if (find_minmax_aggs_walker(parse->havingQual, &aggs_list)) return; @@ -217,11 +215,14 @@ preprocess_minmax_aggregates(PlannerInfo *root, List *tlist) * consider_parallel value in it, but MinMaxAggPath paths are currently * never parallel-safe anyway, so that doesn't matter. Likewise, it * doesn't matter that we haven't filled FDW-related fields in the rel. + * Also, because there are no rowmarks, we know that the processed_tlist + * doesn't need to change anymore, so making the pathtarget now is safe. */ grouped_rel = fetch_upper_rel(root, UPPERREL_GROUP_AGG, NULL); add_path(grouped_rel, (Path *) create_minmaxagg_path(root, grouped_rel, - create_pathtarget(root, tlist), + create_pathtarget(root, + root->processed_tlist), aggs_list, (List *) parse->havingQual)); } @@ -420,7 +421,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, /* Build suitable ORDER BY clause */ sortcl = makeNode(SortGroupClause); - sortcl->tleSortGroupRef = assignSortGroupRef(tle, tlist); + sortcl->tleSortGroupRef = assignSortGroupRef(tle, subroot->processed_tlist); sortcl->eqop = eqop; sortcl->sortop = sortop; sortcl->nulls_first = nulls_first; @@ -441,7 +442,7 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, subroot->tuple_fraction = 1.0; subroot->limit_tuples = 1.0; - final_rel = query_planner(subroot, tlist, minmax_qp_callback, NULL); + final_rel = query_planner(subroot, minmax_qp_callback, NULL); /* * Since we didn't go through subquery_planner() to handle the subquery, @@ -475,7 +476,8 @@ build_minmax_path(PlannerInfo *root, MinMaxAggInfo *mminfo, * cheapest path.) */ sorted_path = apply_projection_to_path(subroot, final_rel, sorted_path, - create_pathtarget(subroot, tlist)); + create_pathtarget(subroot, + subroot->processed_tlist)); /* * Determine cost to get just the first row of the presorted path. diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 7a34abca048..f0c1b52a2e5 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -9,7 +9,7 @@ * shorn of features like subselects, inheritance, aggregates, grouping, * and so on. (Those are the things planner.c deals with.) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,10 @@ */ #include "postgres.h" +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" +#include "optimizer/inherit.h" +#include "optimizer/optimizer.h" #include "optimizer/orclauses.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" @@ -39,8 +42,6 @@ * (grouping_planner) can choose among the surviving paths for the rel. * * root describes the query to plan - * tlist is the target list the query should produce - * (this is NOT necessarily root->parse->targetList!) * qp_callback is a function to compute query_pathkeys once it's safe to do so * qp_extra is optional extra data to pass to qp_callback * @@ -51,52 +52,12 @@ * (We cannot construct canonical pathkeys until that's done.) */ RelOptInfo * -query_planner(PlannerInfo *root, List *tlist, +query_planner(PlannerInfo *root, query_pathkeys_callback qp_callback, void *qp_extra) { Query *parse = root->parse; List *joinlist; RelOptInfo *final_rel; - Index rti; - double total_pages; - - /* - * If the query has an empty join tree, then it's something easy like - * "SELECT 2+2;" or "INSERT ... VALUES()". Fall through quickly. - */ - if (parse->jointree->fromlist == NIL) - { - /* We need a dummy joinrel to describe the empty set of baserels */ - final_rel = build_empty_join_rel(root); - - /* - * If query allows parallelism in general, check whether the quals are - * parallel-restricted. (We need not check final_rel->reltarget - * because it's empty at this point. Anything parallel-restricted in - * the query tlist will be dealt with later.) - */ - if (root->glob->parallelModeOK) - final_rel->consider_parallel = - is_parallel_safe(root, parse->jointree->quals); - - /* The only path for it is a trivial Result path */ - add_path(final_rel, (Path *) - create_result_path(root, final_rel, - final_rel->reltarget, - (List *) parse->jointree->quals)); - - /* Select cheapest path (pretty easy in this case...) */ - set_cheapest(final_rel); - - /* - * We still are required to call qp_callback, in case it's something - * like "SELECT 2+2 ORDER BY 1". - */ - root->canon_pathkeys = NIL; - (*qp_callback) (root, qp_extra); - - return final_rel; - } /* * Init planner lists to empty. @@ -118,22 +79,89 @@ query_planner(PlannerInfo *root, List *tlist, root->initial_rels = NIL; /* - * Make a flattened version of the rangetable for faster access (this is - * OK because the rangetable won't change any more), and set up an empty - * array for indexing base relations. + * Set up arrays for accessing base relations and AppendRelInfos. */ setup_simple_rel_arrays(root); /* - * Construct RelOptInfo nodes for all base relations in query, and - * indirectly for all appendrel member relations ("other rels"). This - * will give us a RelOptInfo for every "simple" (non-join) rel involved in - * the query. + * In the trivial case where the jointree is a single RTE_RESULT relation, + * bypass all the rest of this function and just make a RelOptInfo and its + * one access path. This is worth optimizing because it applies for + * common cases like "SELECT expression" and "INSERT ... VALUES()". + */ + Assert(parse->jointree->fromlist != NIL); + if (list_length(parse->jointree->fromlist) == 1) + { + Node *jtnode = (Node *) linitial(parse->jointree->fromlist); + + if (IsA(jtnode, RangeTblRef)) + { + int varno = ((RangeTblRef *) jtnode)->rtindex; + RangeTblEntry *rte = root->simple_rte_array[varno]; + + Assert(rte != NULL); + if (rte->rtekind == RTE_RESULT) + { + /* Make the RelOptInfo for it directly */ + final_rel = build_simple_rel(root, varno, NULL); + + /* + * If query allows parallelism in general, check whether the + * quals are parallel-restricted. (We need not check + * final_rel->reltarget because it's empty at this point. + * Anything parallel-restricted in the query tlist will be + * dealt with later.) This is normally pretty silly, because + * a Result-only plan would never be interesting to + * parallelize. However, if force_parallel_mode is on, then + * we want to execute the Result in a parallel worker if + * possible, so we must do this. + */ + if (root->glob->parallelModeOK && + force_parallel_mode != FORCE_PARALLEL_OFF) + final_rel->consider_parallel = + is_parallel_safe(root, parse->jointree->quals); + + /* + * The only path for it is a trivial Result path. We cheat a + * bit here by using a GroupResultPath, because that way we + * can just jam the quals into it without preprocessing them. + * (But, if you hold your head at the right angle, a FROM-less + * SELECT is a kind of degenerate-grouping case, so it's not + * that much of a cheat.) + */ + add_path(final_rel, (Path *) + create_group_result_path(root, final_rel, + final_rel->reltarget, + (List *) parse->jointree->quals)); + + /* Select cheapest path (pretty easy in this case...) */ + set_cheapest(final_rel); + + /* + * We don't need to run generate_base_implied_equalities, but + * we do need to pretend that EC merging is complete. + */ + root->ec_merging_done = true; + + /* + * We still are required to call qp_callback, in case it's + * something like "SELECT 2+2 ORDER BY 1". + */ + (*qp_callback) (root, qp_extra); + + return final_rel; + } + } + } + + /* + * Construct RelOptInfo nodes for all base relations used in the query. + * Appendrel member relations ("other rels") will be added later. * - * Note: the reason we find the rels by searching the jointree and - * appendrel list, rather than just scanning the rangetable, is that the - * rangetable may contain RTEs for rels not actively part of the query, - * for example views. We don't want to make RelOptInfos for them. + * Note: the reason we find the baserels by searching the jointree, rather + * than scanning the rangetable, is that the rangetable may contain RTEs + * for rels not actively part of the query, for example views. We don't + * want to make RelOptInfos for them. */ add_base_rels_to_query(root, (Node *) parse->jointree); @@ -147,7 +175,7 @@ query_planner(PlannerInfo *root, List *tlist, * restrictions. Finally, we form a target joinlist for make_one_rel() to * work from. */ - build_base_rel_tlists(root, tlist); + build_base_rel_tlists(root, root->processed_tlist); find_placeholders_in_jointree(root); @@ -226,32 +254,14 @@ query_planner(PlannerInfo *root, List *tlist, extract_restriction_or_clauses(root); /* - * We should now have size estimates for every actual table involved in - * the query, and we also know which if any have been deleted from the - * query by join removal; so we can compute total_table_pages. - * - * Note that appendrels are not double-counted here, even though we don't - * bother to distinguish RelOptInfos for appendrel parents, because the - * parents will still have size zero. - * - * XXX if a table is self-joined, we will count it once per appearance, - * which perhaps is the wrong thing ... but that's not completely clear, - * and detecting self-joins here is difficult, so ignore it for now. + * Now expand appendrels by adding "otherrels" for their children. We + * delay this to the end so that we have as much information as possible + * available for each baserel, including all restriction clauses. That + * let us prune away partitions that don't satisfy a restriction clause. + * Also note that some information such as lateral_relids is propagated + * from baserels to otherrels here, so we must have computed it already. */ - total_pages = 0; - for (rti = 1; rti < root->simple_rel_array_size; rti++) - { - RelOptInfo *brel = root->simple_rel_array[rti]; - - if (brel == NULL) - continue; - - Assert(brel->relid == rti); /* sanity check on array */ - - if (IS_SIMPLE_REL(brel)) - total_pages += (double) brel->pages; - } - root->total_table_pages = total_pages; + add_other_rels_to_query(root); /* * Ready to do the primary planning. diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 20f49e5d432..17c5f086fbf 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -3,7 +3,7 @@ * planner.c * The query optimizer external interface. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,11 +18,14 @@ #include #include +#include "access/genam.h" #include "access/htup_details.h" #include "access/parallel.h" #include "access/sysattr.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/pg_constraint.h" +#include "catalog/pg_inherits.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "executor/executor.h" @@ -37,8 +40,12 @@ #ifdef OPTIMIZER_DEBUG #include "nodes/print.h" #endif +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/inherit.h" +#include "optimizer/optimizer.h" +#include "optimizer/paramassign.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/plancat.h" @@ -47,10 +54,10 @@ #include "optimizer/prep.h" #include "optimizer/subselect.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/analyze.h" #include "parser/parsetree.h" #include "parser/parse_agg.h" +#include "partitioning/partdesc.h" #include "rewrite/rewriteManip.h" #include "storage/dsm_impl.h" #include "utils/rel.h" @@ -89,7 +96,6 @@ create_upper_paths_hook_type create_upper_paths_hook = NULL; /* Passthrough data for standard_qp_callback */ typedef struct { - List *tlist; /* preprocessed query targetlist */ List *activeWindows; /* active windows, if any */ List *groupClause; /* overrides parse->groupClause */ } standard_qp_extra; @@ -110,133 +116,139 @@ typedef struct int *tleref_to_colnum_map; } grouping_sets_data; +/* + * Temporary structure for use during WindowClause reordering in order to be + * able to sort WindowClauses on partitioning/ordering prefix. + */ +typedef struct +{ + WindowClause *wc; + List *uniqueOrder; /* A List of unique ordering/partitioning + * clauses per Window */ +} WindowClauseSortData; + /* Local functions */ static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind); static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode); static void inheritance_planner(PlannerInfo *root); static void grouping_planner(PlannerInfo *root, bool inheritance_update, - double tuple_fraction); + double tuple_fraction); static grouping_sets_data *preprocess_grouping_sets(PlannerInfo *root); static List *remap_to_groupclause_idx(List *groupClause, List *gsets, - int *tleref_to_colnum_map); + int *tleref_to_colnum_map); static void preprocess_rowmarks(PlannerInfo *root); static double preprocess_limit(PlannerInfo *root, - double tuple_fraction, - int64 *offset_est, int64 *count_est); -static bool limit_needed(Query *parse); + double tuple_fraction, + int64 *offset_est, int64 *count_est); static void remove_useless_groupby_columns(PlannerInfo *root); static List *preprocess_groupclause(PlannerInfo *root, List *force); static List *extract_rollup_sets(List *groupingSets); static List *reorder_grouping_sets(List *groupingSets, List *sortclause); static void standard_qp_callback(PlannerInfo *root, void *extra); static double get_number_of_groups(PlannerInfo *root, - double path_rows, - grouping_sets_data *gd, - List *target_list); -static Size estimate_hashagg_tablesize(Path *path, - const AggClauseCosts *agg_costs, - double dNumGroups); + double path_rows, + grouping_sets_data *gd, + List *target_list); static RelOptInfo *create_grouping_paths(PlannerInfo *root, - RelOptInfo *input_rel, - PathTarget *target, - bool target_parallel_safe, - const AggClauseCosts *agg_costs, - grouping_sets_data *gd); + RelOptInfo *input_rel, + PathTarget *target, + bool target_parallel_safe, + const AggClauseCosts *agg_costs, + grouping_sets_data *gd); static bool is_degenerate_grouping(PlannerInfo *root); static void create_degenerate_grouping_paths(PlannerInfo *root, - RelOptInfo *input_rel, - RelOptInfo *grouped_rel); + RelOptInfo *input_rel, + RelOptInfo *grouped_rel); static RelOptInfo *make_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, - PathTarget *target, bool target_parallel_safe, - Node *havingQual); + PathTarget *target, bool target_parallel_safe, + Node *havingQual); static void create_ordinary_grouping_paths(PlannerInfo *root, - RelOptInfo *input_rel, - RelOptInfo *grouped_rel, - const AggClauseCosts *agg_costs, - grouping_sets_data *gd, - GroupPathExtraData *extra, - RelOptInfo **partially_grouped_rel_p); + RelOptInfo *input_rel, + RelOptInfo *grouped_rel, + const AggClauseCosts *agg_costs, + grouping_sets_data *gd, + GroupPathExtraData *extra, + RelOptInfo **partially_grouped_rel_p); static void consider_groupingsets_paths(PlannerInfo *root, - RelOptInfo *grouped_rel, - Path *path, - bool is_sorted, - bool can_hash, - grouping_sets_data *gd, - const AggClauseCosts *agg_costs, - double dNumGroups); + RelOptInfo *grouped_rel, + Path *path, + bool is_sorted, + bool can_hash, + grouping_sets_data *gd, + const AggClauseCosts *agg_costs, + double dNumGroups); static RelOptInfo *create_window_paths(PlannerInfo *root, - RelOptInfo *input_rel, - PathTarget *input_target, - PathTarget *output_target, - bool output_target_parallel_safe, - List *tlist, - WindowFuncLists *wflists, - List *activeWindows); + RelOptInfo *input_rel, + PathTarget *input_target, + PathTarget *output_target, + bool output_target_parallel_safe, + WindowFuncLists *wflists, + List *activeWindows); static void create_one_window_path(PlannerInfo *root, - RelOptInfo *window_rel, - Path *path, - PathTarget *input_target, - PathTarget *output_target, - List *tlist, - WindowFuncLists *wflists, - List *activeWindows); + RelOptInfo *window_rel, + Path *path, + PathTarget *input_target, + PathTarget *output_target, + WindowFuncLists *wflists, + List *activeWindows); static RelOptInfo *create_distinct_paths(PlannerInfo *root, - RelOptInfo *input_rel); + RelOptInfo *input_rel); static RelOptInfo *create_ordered_paths(PlannerInfo *root, - RelOptInfo *input_rel, - PathTarget *target, - bool target_parallel_safe, - double limit_tuples); + RelOptInfo *input_rel, + PathTarget *target, + bool target_parallel_safe, + double limit_tuples); static PathTarget *make_group_input_target(PlannerInfo *root, - PathTarget *final_target); + PathTarget *final_target); static PathTarget *make_partial_grouping_target(PlannerInfo *root, - PathTarget *grouping_target, - Node *havingQual); + PathTarget *grouping_target, + Node *havingQual); static List *postprocess_setop_tlist(List *new_tlist, List *orig_tlist); static List *select_active_windows(PlannerInfo *root, WindowFuncLists *wflists); static PathTarget *make_window_input_target(PlannerInfo *root, - PathTarget *final_target, - List *activeWindows); + PathTarget *final_target, + List *activeWindows); static List *make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, - List *tlist); + List *tlist); static PathTarget *make_sort_input_target(PlannerInfo *root, - PathTarget *final_target, - bool *have_postponed_srfs); + PathTarget *final_target, + bool *have_postponed_srfs); static void adjust_paths_for_srfs(PlannerInfo *root, RelOptInfo *rel, - List *targets, List *targets_contain_srfs); + List *targets, List *targets_contain_srfs); static void add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, - RelOptInfo *grouped_rel, - RelOptInfo *partially_grouped_rel, - const AggClauseCosts *agg_costs, - grouping_sets_data *gd, - double dNumGroups, - GroupPathExtraData *extra); + RelOptInfo *grouped_rel, + RelOptInfo *partially_grouped_rel, + const AggClauseCosts *agg_costs, + grouping_sets_data *gd, + double dNumGroups, + GroupPathExtraData *extra); static RelOptInfo *create_partial_grouping_paths(PlannerInfo *root, - RelOptInfo *grouped_rel, - RelOptInfo *input_rel, - grouping_sets_data *gd, - GroupPathExtraData *extra, - bool force_rel_creation); + RelOptInfo *grouped_rel, + RelOptInfo *input_rel, + grouping_sets_data *gd, + GroupPathExtraData *extra, + bool force_rel_creation); static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel); static bool can_partial_agg(PlannerInfo *root, - const AggClauseCosts *agg_costs); + const AggClauseCosts *agg_costs); static void apply_scanjoin_target_to_paths(PlannerInfo *root, - RelOptInfo *rel, - List *scanjoin_targets, - List *scanjoin_targets_contain_srfs, - bool scanjoin_target_parallel_safe, - bool tlist_same_exprs); + RelOptInfo *rel, + List *scanjoin_targets, + List *scanjoin_targets_contain_srfs, + bool scanjoin_target_parallel_safe, + bool tlist_same_exprs); static void create_partitionwise_grouping_paths(PlannerInfo *root, - RelOptInfo *input_rel, - RelOptInfo *grouped_rel, - RelOptInfo *partially_grouped_rel, - const AggClauseCosts *agg_costs, - grouping_sets_data *gd, - PartitionwiseAggregateType patype, - GroupPathExtraData *extra); + RelOptInfo *input_rel, + RelOptInfo *grouped_rel, + RelOptInfo *partially_grouped_rel, + const AggClauseCosts *agg_costs, + grouping_sets_data *gd, + PartitionwiseAggregateType patype, + GroupPathExtraData *extra); static bool group_by_has_partkey(RelOptInfo *input_rel, - List *targetList, - List *groupClause); + List *targetList, + List *groupClause); +static int common_prefix_cmp(const void *a, const void *b); /***************************************************************************** @@ -292,7 +304,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) glob->finalrtable = NIL; glob->finalrowmarks = NIL; glob->resultRelations = NIL; - glob->nonleafResultRelations = NIL; glob->rootResultRelations = NIL; glob->relationOids = NIL; glob->invalItems = NIL; @@ -324,23 +335,13 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) * parallel worker. We might eventually be able to relax this * restriction, but for now it seems best not to have parallel workers * trying to create their own parallel workers. - * - * We can't use parallelism in serializable mode because the predicate - * locking code is not parallel-aware. It's not catastrophic if someone - * tries to run a parallel plan in serializable mode; it just won't get - * any workers and will run serially. But it seems like a good heuristic - * to assume that the same serialization level will be in effect at plan - * time and execution time, so don't generate a parallel plan if we're in - * serializable mode. */ if ((cursorOptions & CURSOR_OPT_PARALLEL_OK) != 0 && IsUnderPostmaster && - dynamic_shared_memory_type != DSM_IMPL_NONE && parse->commandType == CMD_SELECT && !parse->hasModifyingCTE && max_parallel_workers_per_gather > 0 && - !IsParallelWorker() && - !IsolationIsSerializable()) + !IsParallelWorker()) { /* all the cheap tests pass, so scan the query tree */ glob->maxParallelHazard = max_parallel_hazard(parse); @@ -493,7 +494,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) Assert(glob->finalrtable == NIL); Assert(glob->finalrowmarks == NIL); Assert(glob->resultRelations == NIL); - Assert(glob->nonleafResultRelations == NIL); Assert(glob->rootResultRelations == NIL); top_plan = set_plan_references(root, top_plan); /* ... and the subplans (both regular subplans and initplans) */ @@ -520,7 +520,6 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) result->planTree = top_plan; result->rtable = glob->finalrtable; result->resultRelations = glob->resultRelations; - result->nonleafResultRelations = glob->nonleafResultRelations; result->rootResultRelations = glob->rootResultRelations; result->subplans = glob->subplans; result->rewindPlanIDs = glob->rewindPlanIDs; @@ -558,6 +557,9 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) result->jitFlags |= PGJIT_DEFORM; } + if (glob->partition_directory != NULL) + DestroyPartitionDirectory(glob->partition_directory); + return result; } @@ -599,6 +601,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, List *newWithCheckOptions; List *newHaving; bool hasOuterJoins; + bool hasResultRTEs; RelOptInfo *final_rel; ListCell *l; @@ -615,6 +618,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, root->cte_plan_ids = NIL; root->multiexpr_params = NIL; root->eq_classes = NIL; + root->ec_merging_done = false; root->append_rel_list = NIL; root->rowMarks = NIL; memset(root->upper_rels, 0, sizeof(root->upper_rels)); @@ -623,22 +627,28 @@ subquery_planner(PlannerGlobal *glob, Query *parse, root->grouping_map = NULL; root->minmax_aggs = NIL; root->qual_security_level = 0; - root->hasInheritedTarget = false; + root->inhTargetKind = INHKIND_NONE; root->hasRecursion = hasRecursion; if (hasRecursion) - root->wt_param_id = SS_assign_special_param(root); + root->wt_param_id = assign_special_exec_param(root); else root->wt_param_id = -1; root->non_recursive_path = NULL; root->partColsUpdated = false; /* - * If there is a WITH list, process each WITH query and build an initplan - * SubPlan structure for it. + * If there is a WITH list, process each WITH query and either convert it + * to RTE_SUBQUERY RTE(s) or build an initplan SubPlan structure for it. */ if (parse->cteList) SS_process_ctes(root); + /* + * If the FROM clause is empty, replace it with a dummy RTE_RESULT RTE, so + * that we don't need so many special cases to deal with that situation. + */ + replace_empty_jointree(parse); + /* * Look for ANY and EXISTS SubLinks in WHERE and JOIN/ON clauses, and try * to transform them into joins. Note that this step does not descend @@ -649,11 +659,12 @@ subquery_planner(PlannerGlobal *glob, Query *parse, pull_up_sublinks(root); /* - * Scan the rangetable for set-returning functions, and inline them if - * possible (producing subqueries that might get pulled up next). - * Recursion issues here are handled in the same way as for SubLinks. + * Scan the rangetable for function RTEs, do const-simplification on them, + * and then inline them if possible (producing subqueries that might get + * pulled up next). Recursion issues here are handled in the same way as + * for SubLinks. */ - inline_set_returning_functions(root); + preprocess_function_rtes(root); /* * Check to see if any subqueries in the jointree can be merged into this @@ -671,47 +682,75 @@ subquery_planner(PlannerGlobal *glob, Query *parse, flatten_simple_union_all(root); /* - * Detect whether any rangetable entries are RTE_JOIN kind; if not, we can - * avoid the expense of doing flatten_join_alias_vars(). Also check for - * outer joins --- if none, we can skip reduce_outer_joins(). And check - * for LATERAL RTEs, too. This must be done after we have done - * pull_up_subqueries(), of course. + * Survey the rangetable to see what kinds of entries are present. We can + * skip some later processing if relevant SQL features are not used; for + * example if there are no JOIN RTEs we can avoid the expense of doing + * flatten_join_alias_vars(). This must be done after we have finished + * adding rangetable entries, of course. (Note: actually, processing of + * inherited or partitioned rels can cause RTEs for their child tables to + * get added later; but those must all be RTE_RELATION entries, so they + * don't invalidate the conclusions drawn here.) */ root->hasJoinRTEs = false; root->hasLateralRTEs = false; hasOuterJoins = false; + hasResultRTEs = false; foreach(l, parse->rtable) { RangeTblEntry *rte = lfirst_node(RangeTblEntry, l); - if (rte->rtekind == RTE_JOIN) + switch (rte->rtekind) { - root->hasJoinRTEs = true; - if (IS_OUTER_JOIN(rte->jointype)) - hasOuterJoins = true; + case RTE_RELATION: + if (rte->inh) + { + /* + * Check to see if the relation actually has any children; + * if not, clear the inh flag so we can treat it as a + * plain base relation. + * + * Note: this could give a false-positive result, if the + * rel once had children but no longer does. We used to + * be able to clear rte->inh later on when we discovered + * that, but no more; we have to handle such cases as + * full-fledged inheritance. + */ + rte->inh = has_subclass(rte->relid); + } + break; + case RTE_JOIN: + root->hasJoinRTEs = true; + if (IS_OUTER_JOIN(rte->jointype)) + hasOuterJoins = true; + break; + case RTE_RESULT: + hasResultRTEs = true; + break; + default: + /* No work here for other RTE types */ + break; } + if (rte->lateral) root->hasLateralRTEs = true; + + /* + * We can also determine the maximum security level required for any + * securityQuals now. Addition of inheritance-child RTEs won't affect + * this, because child tables don't have their own securityQuals; see + * expand_single_inheritance_child(). + */ + if (rte->securityQuals) + root->qual_security_level = Max(root->qual_security_level, + list_length(rte->securityQuals)); } /* * Preprocess RowMark information. We need to do this after subquery - * pullup (so that all non-inherited RTEs are present) and before - * inheritance expansion (so that the info is available for - * expand_inherited_tables to examine and modify). + * pullup, so that all base relations are present. */ preprocess_rowmarks(root); - /* - * Expand any rangetable entries that are inheritance sets into "append - * relations". This can add entries to the rangetable, but they must be - * plain base relations not joins, so it's OK (and marginally more - * efficient) to do it after checking for join RTEs. We must do it after - * pulling up subqueries, else we'd fail to handle inherited tables in - * subqueries. - */ - expand_inherited_tables(root); - /* * Set hasHavingQual to remember if HAVING clause is present. Needed * because preprocess_expression will reduce a constant-true condition to @@ -794,24 +833,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse, /* exclRelTlist contains only Vars, so no preprocessing needed */ } - foreach(l, parse->mergeActionList) - { - MergeAction *action = (MergeAction *) lfirst(l); - - action->targetList = (List *) - preprocess_expression(root, - (Node *) action->targetList, - EXPRKIND_TARGET); - action->qual = - preprocess_expression(root, - (Node *) action->qual, - EXPRKIND_QUAL); - } - - parse->mergeSourceTargetList = (List *) - preprocess_expression(root, (Node *) parse->mergeSourceTargetList, - EXPRKIND_TARGET); - root->append_rel_list = (List *) preprocess_expression(root, (Node *) root->append_rel_list, EXPRKIND_APPINFO); @@ -842,7 +863,8 @@ subquery_planner(PlannerGlobal *glob, Query *parse, */ if (rte->lateral && root->hasJoinRTEs) rte->subquery = (Query *) - flatten_join_alias_vars(root, (Node *) rte->subquery); + flatten_join_alias_vars(root->parse, + (Node *) rte->subquery); } else if (rte->rtekind == RTE_FUNCTION) { @@ -973,6 +995,14 @@ subquery_planner(PlannerGlobal *glob, Query *parse, if (hasOuterJoins) reduce_outer_joins(root); + /* + * If we have any RTE_RESULT relations, see if they can be deleted from + * the jointree. This step is most effectively done after we've done + * expression preprocessing and outer join reduction. + */ + if (hasResultRTEs) + remove_useless_result_rtes(root); + /* * Do the main planning. If we have an inherited target relation, that * needs special processing, else go straight to grouping_planner. @@ -1039,10 +1069,12 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind) kind == EXPRKIND_VALUES || kind == EXPRKIND_TABLESAMPLE || kind == EXPRKIND_TABLEFUNC)) - expr = flatten_join_alias_vars(root, expr); + expr = flatten_join_alias_vars(root->parse, expr); /* - * Simplify constant expressions. + * Simplify constant expressions. For function RTEs, this was already + * done by preprocess_function_rtes ... but we have to do it again if the + * RTE is LATERAL and might have contained join alias variables. * * Note: an essential effect of this is to convert named-argument function * calls to positional notation and insert the current actual values of @@ -1056,7 +1088,9 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind) * careful to maintain AND/OR flatness --- that is, do not generate a tree * with AND directly under AND, nor OR directly under OR. */ - expr = eval_const_expressions(root, expr); + if (!(kind == EXPRKIND_RTFUNC || + (kind == EXPRKIND_RTFUNC_LATERAL && !root->hasJoinRTEs))) + expr = eval_const_expressions(root, expr); /* * If it's a qual or havingQual, canonicalize it. @@ -1175,12 +1209,20 @@ inheritance_planner(PlannerInfo *root) { Query *parse = root->parse; int top_parentRTindex = parse->resultRelation; + List *select_rtable; + List *select_appinfos; + List *child_appinfos; + List *old_child_rtis; + List *new_child_rtis; Bitmapset *subqueryRTindexes; - Bitmapset *modifiableARIindexes; + Index next_subquery_rti; int nominalRelation = -1; + Index rootRelation = 0; List *final_rtable = NIL; + List *final_rowmarks = NIL; int save_rel_array_size = 0; RelOptInfo **save_rel_array = NULL; + AppendRelInfo **save_append_rel_array = NULL; List *subpaths = NIL; List *subroots = NIL; List *resultRelations = NIL; @@ -1189,16 +1231,15 @@ inheritance_planner(PlannerInfo *root) List *rowMarks; RelOptInfo *final_rel; ListCell *lc; + ListCell *lc2; Index rti; RangeTblEntry *parent_rte; - Relids partitioned_relids = NULL; - List *partitioned_rels = NIL; - PlannerInfo *parent_root; - Query *parent_parse; - Bitmapset *parent_relids = bms_make_singleton(top_parentRTindex); - PlannerInfo **parent_roots = NULL; + Bitmapset *parent_relids; + Query **parent_parses; - Assert(parse->commandType != CMD_INSERT); + /* Should only get here for UPDATE or DELETE */ + Assert(parse->commandType == CMD_UPDATE || + parse->commandType == CMD_DELETE); /* * We generate a modified instance of the original Query for each target @@ -1229,96 +1270,233 @@ inheritance_planner(PlannerInfo *root) } /* - * Next, we want to identify which AppendRelInfo items contain references - * to any of the aforesaid subquery RTEs. These items will need to be - * copied and modified to adjust their subquery references; whereas the - * other ones need not be touched. It's worth being tense over this - * because we can usually avoid processing most of the AppendRelInfo - * items, thereby saving O(N^2) space and time when the target is a large - * inheritance tree. We can identify AppendRelInfo items by their - * child_relid, since that should be unique within the list. + * If the parent RTE is a partitioned table, we should use that as the + * nominal target relation, because the RTEs added for partitioned tables + * (including the root parent) as child members of the inheritance set do + * not appear anywhere else in the plan, so the confusion explained below + * for non-partitioning inheritance cases is not possible. */ - modifiableARIindexes = NULL; - if (subqueryRTindexes != NULL) + parent_rte = rt_fetch(top_parentRTindex, parse->rtable); + Assert(parent_rte->inh); + if (parent_rte->relkind == RELKIND_PARTITIONED_TABLE) { - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); - - if (bms_is_member(appinfo->parent_relid, subqueryRTindexes) || - bms_is_member(appinfo->child_relid, subqueryRTindexes) || - bms_overlap(pull_varnos((Node *) appinfo->translated_vars), - subqueryRTindexes)) - modifiableARIindexes = bms_add_member(modifiableARIindexes, - appinfo->child_relid); - } + nominalRelation = top_parentRTindex; + rootRelation = top_parentRTindex; } /* - * If the parent RTE is a partitioned table, we should use that as the - * nominal relation, because the RTEs added for partitioned tables - * (including the root parent) as child members of the inheritance set do - * not appear anywhere else in the plan. The situation is exactly the - * opposite in the case of non-partitioned inheritance parent as described - * below. For the same reason, collect the list of descendant partitioned - * tables to be saved in ModifyTable node, so that executor can lock those - * as well. + * Before generating the real per-child-relation plans, do a cycle of + * planning as though the query were a SELECT. The objective here is to + * find out which child relations need to be processed, using the same + * expansion and pruning logic as for a SELECT. We'll then pull out the + * RangeTblEntry-s generated for the child rels, and make use of the + * AppendRelInfo entries for them to guide the real planning. (This is + * rather inefficient; we could perhaps stop short of making a full Path + * tree. But this whole function is inefficient and slated for + * destruction, so let's not contort query_planner for that.) */ - parent_rte = rt_fetch(top_parentRTindex, root->parse->rtable); - if (parent_rte->relkind == RELKIND_PARTITIONED_TABLE) { - nominalRelation = top_parentRTindex; + PlannerInfo *subroot; + + /* + * Flat-copy the PlannerInfo to prevent modification of the original. + */ + subroot = makeNode(PlannerInfo); + memcpy(subroot, root, sizeof(PlannerInfo)); + + /* + * Make a deep copy of the parsetree for this planning cycle to mess + * around with, and change it to look like a SELECT. (Hack alert: the + * target RTE still has updatedCols set if this is an UPDATE, so that + * expand_partitioned_rtentry will correctly update + * subroot->partColsUpdated.) + */ + subroot->parse = copyObject(root->parse); + + subroot->parse->commandType = CMD_SELECT; + subroot->parse->resultRelation = 0; + + /* + * Ensure the subroot has its own copy of the original + * append_rel_list, since it'll be scribbled on. (Note that at this + * point, the list only contains AppendRelInfos for flattened UNION + * ALL subqueries.) + */ + subroot->append_rel_list = copyObject(root->append_rel_list); + + /* + * Better make a private copy of the rowMarks, too. + */ + subroot->rowMarks = copyObject(root->rowMarks); + + /* There shouldn't be any OJ info to translate, as yet */ + Assert(subroot->join_info_list == NIL); + /* and we haven't created PlaceHolderInfos, either */ + Assert(subroot->placeholder_list == NIL); + + /* Generate Path(s) for accessing this result relation */ + grouping_planner(subroot, true, 0.0 /* retrieve all tuples */ ); + + /* Extract the info we need. */ + select_rtable = subroot->parse->rtable; + select_appinfos = subroot->append_rel_list; /* - * Root parent's RT index is always present in the partitioned_rels of - * the ModifyTable node, if one is needed at all. + * We need to propagate partColsUpdated back, too. (The later + * planning cycles will not set this because they won't run + * expand_partitioned_rtentry for the UPDATE target.) */ - partitioned_relids = bms_make_singleton(top_parentRTindex); + root->partColsUpdated = subroot->partColsUpdated; + } + + /*---------- + * Since only one rangetable can exist in the final plan, we need to make + * sure that it contains all the RTEs needed for any child plan. This is + * complicated by the need to use separate subquery RTEs for each child. + * We arrange the final rtable as follows: + * 1. All original rtable entries (with their original RT indexes). + * 2. All the relation RTEs generated for children of the target table. + * 3. Subquery RTEs for children after the first. We need N * (K - 1) + * RT slots for this, if there are N subqueries and K child tables. + * 4. Additional RTEs generated during the child planning runs, such as + * children of inheritable RTEs other than the target table. + * We assume that each child planning run will create an identical set + * of type-4 RTEs. + * + * So the next thing to do is append the type-2 RTEs (the target table's + * children) to the original rtable. We look through select_appinfos + * to find them. + * + * To identify which AppendRelInfos are relevant as we thumb through + * select_appinfos, we need to look for both direct and indirect children + * of top_parentRTindex, so we use a bitmap of known parent relids. + * expand_inherited_rtentry() always processes a parent before any of that + * parent's children, so we should see an intermediate parent before its + * children. + *---------- + */ + child_appinfos = NIL; + old_child_rtis = NIL; + new_child_rtis = NIL; + parent_relids = bms_make_singleton(top_parentRTindex); + foreach(lc, select_appinfos) + { + AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); + RangeTblEntry *child_rte; + + /* append_rel_list contains all append rels; ignore others */ + if (!bms_is_member(appinfo->parent_relid, parent_relids)) + continue; + + /* remember relevant AppendRelInfos for use below */ + child_appinfos = lappend(child_appinfos, appinfo); + + /* extract RTE for this child rel */ + child_rte = rt_fetch(appinfo->child_relid, select_rtable); + + /* and append it to the original rtable */ + parse->rtable = lappend(parse->rtable, child_rte); + + /* remember child's index in the SELECT rtable */ + old_child_rtis = lappend_int(old_child_rtis, appinfo->child_relid); + + /* and its new index in the final rtable */ + new_child_rtis = lappend_int(new_child_rtis, list_length(parse->rtable)); + + /* if child is itself partitioned, update parent_relids */ + if (child_rte->inh) + { + Assert(child_rte->relkind == RELKIND_PARTITIONED_TABLE); + parent_relids = bms_add_member(parent_relids, appinfo->child_relid); + } } /* - * The PlannerInfo for each child is obtained by translating the relevant - * members of the PlannerInfo for its immediate parent, which we find - * using the parent_relid in its AppendRelInfo. We save the PlannerInfo - * for each parent in an array indexed by relid for fast retrieval. Since - * the maximum number of parents is limited by the number of RTEs in the - * query, we use that number to allocate the array. An extra entry is - * needed since relids start from 1. + * It's possible that the RTIs we just assigned for the child rels in the + * final rtable are different from what they were in the SELECT query. + * Adjust the AppendRelInfos so that they will correctly map RT indexes to + * the final indexes. We can do this left-to-right since no child rel's + * final RT index could be greater than what it had in the SELECT query. */ - parent_roots = (PlannerInfo **) palloc0((list_length(parse->rtable) + 1) * - sizeof(PlannerInfo *)); - parent_roots[top_parentRTindex] = root; + forboth(lc, old_child_rtis, lc2, new_child_rtis) + { + int old_child_rti = lfirst_int(lc); + int new_child_rti = lfirst_int(lc2); + + if (old_child_rti == new_child_rti) + continue; /* nothing to do */ + + Assert(old_child_rti > new_child_rti); + + ChangeVarNodes((Node *) child_appinfos, + old_child_rti, new_child_rti, 0); + } + + /* + * Now set up rangetable entries for subqueries for additional children + * (the first child will just use the original ones). These all have to + * look more or less real, or EXPLAIN will get unhappy; so we just make + * them all clones of the original subqueries. + */ + next_subquery_rti = list_length(parse->rtable) + 1; + if (subqueryRTindexes != NULL) + { + int n_children = list_length(child_appinfos); + + while (n_children-- > 1) + { + int oldrti = -1; + + while ((oldrti = bms_next_member(subqueryRTindexes, oldrti)) >= 0) + { + RangeTblEntry *subqrte; + + subqrte = rt_fetch(oldrti, parse->rtable); + parse->rtable = lappend(parse->rtable, copyObject(subqrte)); + } + } + } + + /* + * The query for each child is obtained by translating the query for its + * immediate parent, since the AppendRelInfo data we have shows deltas + * between parents and children. We use the parent_parses array to + * remember the appropriate query trees. This is indexed by parent relid. + * Since the maximum number of parents is limited by the number of RTEs in + * the SELECT query, we use that number to allocate the array. An extra + * entry is needed since relids start from 1. + */ + parent_parses = (Query **) palloc0((list_length(select_rtable) + 1) * + sizeof(Query *)); + parent_parses[top_parentRTindex] = parse; /* * And now we can get on with generating a plan for each child table. */ - foreach(lc, root->append_rel_list) + foreach(lc, child_appinfos) { AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); + Index this_subquery_rti = next_subquery_rti; + Query *parent_parse; PlannerInfo *subroot; RangeTblEntry *child_rte; RelOptInfo *sub_final_rel; Path *subpath; - /* append_rel_list contains all append rels; ignore others */ - if (!bms_is_member(appinfo->parent_relid, parent_relids)) - continue; - /* * expand_inherited_rtentry() always processes a parent before any of - * that parent's children, so the parent_root for this relation should - * already be available. + * that parent's children, so the parent query for this relation + * should already be available. */ - parent_root = parent_roots[appinfo->parent_relid]; - Assert(parent_root != NULL); - parent_parse = parent_root->parse; + parent_parse = parent_parses[appinfo->parent_relid]; + Assert(parent_parse != NULL); /* * We need a working copy of the PlannerInfo so that we can control * propagation of information back to the main copy. */ subroot = makeNode(PlannerInfo); - memcpy(subroot, parent_root, sizeof(PlannerInfo)); + memcpy(subroot, root, sizeof(PlannerInfo)); /* * Generate modified query with this rel as target. We first apply @@ -1327,7 +1505,7 @@ inheritance_planner(PlannerInfo *root) * then fool around with subquery RTEs. */ subroot->parse = (Query *) - adjust_appendrel_attrs(parent_root, + adjust_appendrel_attrs(subroot, (Node *) parent_parse, 1, &appinfo); @@ -1341,100 +1519,82 @@ inheritance_planner(PlannerInfo *root) parent_rte->securityQuals = NIL; /* - * The rowMarks list might contain references to subquery RTEs, so - * make a copy that we can apply ChangeVarNodes to. (Fortunately, the - * executor doesn't need to see the modified copies --- we can just - * pass it the original rowMarks list.) + * HACK: setting this to a value other than INHKIND_NONE signals to + * relation_excluded_by_constraints() to treat the result relation as + * being an appendrel member. */ - subroot->rowMarks = copyObject(parent_root->rowMarks); + subroot->inhTargetKind = + (rootRelation != 0) ? INHKIND_PARTITIONED : INHKIND_INHERITED; /* - * The append_rel_list likewise might contain references to subquery - * RTEs (if any subqueries were flattenable UNION ALLs). So prepare - * to apply ChangeVarNodes to that, too. As explained above, we only - * want to copy items that actually contain such references; the rest - * can just get linked into the subroot's append_rel_list. + * If this child is further partitioned, remember it as a parent. + * Since a partitioned table does not have any data, we don't need to + * create a plan for it, and we can stop processing it here. We do, + * however, need to remember its modified PlannerInfo for use when + * processing its children, since we'll update their varnos based on + * the delta from immediate parent to child, not from top to child. * - * If we know there are no such references, we can just use the outer - * append_rel_list unmodified. + * Note: a very non-obvious point is that we have not yet added + * duplicate subquery RTEs to the subroot's rtable. We mustn't, + * because then its children would have two sets of duplicates, + * confusing matters. */ - if (modifiableARIindexes != NULL) + if (child_rte->inh) { - ListCell *lc2; - - subroot->append_rel_list = NIL; - foreach(lc2, parent_root->append_rel_list) - { - AppendRelInfo *appinfo2 = lfirst_node(AppendRelInfo, lc2); - - if (bms_is_member(appinfo2->child_relid, modifiableARIindexes)) - appinfo2 = copyObject(appinfo2); - - subroot->append_rel_list = lappend(subroot->append_rel_list, - appinfo2); - } + Assert(child_rte->relkind == RELKIND_PARTITIONED_TABLE); + parent_parses[appinfo->child_relid] = subroot->parse; + continue; } /* - * Add placeholders to the child Query's rangetable list to fill the - * RT indexes already reserved for subqueries in previous children. - * These won't be referenced, so there's no need to make them very - * valid-looking. + * Set the nominal target relation of the ModifyTable node if not + * already done. If the target is a partitioned table, we already set + * nominalRelation to refer to the partition root, above. For + * non-partitioned inheritance cases, we'll use the first child + * relation (even if it's excluded) as the nominal target relation. + * Because of the way expand_inherited_rtentry works, that should be + * the RTE representing the parent table in its role as a simple + * member of the inheritance set. + * + * It would be logically cleaner to *always* use the inheritance + * parent RTE as the nominal relation; but that RTE is not otherwise + * referenced in the plan in the non-partitioned inheritance case. + * Instead the duplicate child RTE created by expand_inherited_rtentry + * is used elsewhere in the plan, so using the original parent RTE + * would give rise to confusing use of multiple aliases in EXPLAIN + * output for what the user will think is the "same" table. OTOH, + * it's not a problem in the partitioned inheritance case, because + * there is no duplicate RTE for the parent. + */ + if (nominalRelation < 0) + nominalRelation = appinfo->child_relid; + + /* + * As above, each child plan run needs its own append_rel_list and + * rowmarks, which should start out as pristine copies of the + * originals. There can't be any references to UPDATE/DELETE target + * rels in them; but there could be subquery references, which we'll + * fix up in a moment. */ - while (list_length(subroot->parse->rtable) < list_length(final_rtable)) - subroot->parse->rtable = lappend(subroot->parse->rtable, - makeNode(RangeTblEntry)); + subroot->append_rel_list = copyObject(root->append_rel_list); + subroot->rowMarks = copyObject(root->rowMarks); /* - * If this isn't the first child Query, generate duplicates of all - * subquery RTEs, and adjust Var numbering to reference the - * duplicates. To simplify the loop logic, we scan the original rtable - * not the copy just made by adjust_appendrel_attrs; that should be OK - * since subquery RTEs couldn't contain any references to the target - * rel. + * If this isn't the first child Query, adjust Vars and jointree + * entries to reference the appropriate set of subquery RTEs. */ if (final_rtable != NIL && subqueryRTindexes != NULL) { - ListCell *lr; + int oldrti = -1; - rti = 1; - foreach(lr, parent_parse->rtable) + while ((oldrti = bms_next_member(subqueryRTindexes, oldrti)) >= 0) { - RangeTblEntry *rte = lfirst_node(RangeTblEntry, lr); - - if (bms_is_member(rti, subqueryRTindexes)) - { - Index newrti; + Index newrti = next_subquery_rti++; - /* - * The RTE can't contain any references to its own RT - * index, except in its securityQuals, so we can save a - * few cycles by applying ChangeVarNodes to the rest of - * the rangetable before we append the RTE to it. - */ - newrti = list_length(subroot->parse->rtable) + 1; - ChangeVarNodes((Node *) subroot->parse, rti, newrti, 0); - ChangeVarNodes((Node *) subroot->rowMarks, rti, newrti, 0); - /* Skip processing unchanging parts of append_rel_list */ - if (modifiableARIindexes != NULL) - { - ListCell *lc2; - - foreach(lc2, subroot->append_rel_list) - { - AppendRelInfo *appinfo2 = lfirst_node(AppendRelInfo, lc2); - - if (bms_is_member(appinfo2->child_relid, - modifiableARIindexes)) - ChangeVarNodes((Node *) appinfo2, rti, newrti, 0); - } - } - rte = copyObject(rte); - ChangeVarNodes((Node *) rte->securityQuals, rti, newrti, 0); - subroot->parse->rtable = lappend(subroot->parse->rtable, - rte); - } - rti++; + ChangeVarNodes((Node *) subroot->parse, oldrti, newrti, 0); + ChangeVarNodes((Node *) subroot->append_rel_list, + oldrti, newrti, 0); + ChangeVarNodes((Node *) subroot->rowMarks, oldrti, newrti, 0); } } @@ -1442,52 +1602,10 @@ inheritance_planner(PlannerInfo *root) Assert(subroot->join_info_list == NIL); /* and we haven't created PlaceHolderInfos, either */ Assert(subroot->placeholder_list == NIL); - /* hack to mark target relation as an inheritance partition */ - subroot->hasInheritedTarget = true; - - /* - * If the child is further partitioned, remember it as a parent. Since - * a partitioned table does not have any data, we don't need to create - * a plan for it. We do, however, need to remember the PlannerInfo for - * use when processing its children. - */ - if (child_rte->inh) - { - Assert(child_rte->relkind == RELKIND_PARTITIONED_TABLE); - parent_relids = - bms_add_member(parent_relids, appinfo->child_relid); - parent_roots[appinfo->child_relid] = subroot; - - continue; - } /* Generate Path(s) for accessing this result relation */ grouping_planner(subroot, true, 0.0 /* retrieve all tuples */ ); - /* - * Set the nomimal target relation of the ModifyTable node if not - * already done. We use the inheritance parent RTE as the nominal - * target relation if it's a partitioned table (see just above this - * loop). In the non-partitioned parent case, we'll use the first - * child relation (even if it's excluded) as the nominal target - * relation. Because of the way expand_inherited_rtentry works, the - * latter should be the RTE representing the parent table in its role - * as a simple member of the inheritance set. - * - * It would be logically cleaner to *always* use the inheritance - * parent RTE as the nominal relation; but that RTE is not otherwise - * referenced in the plan in the non-partitioned inheritance case. - * Instead the duplicate child RTE created by expand_inherited_rtentry - * is used elsewhere in the plan, so using the original parent RTE - * would give rise to confusing use of multiple aliases in EXPLAIN - * output for what the user will think is the "same" table. OTOH, - * it's not a problem in the partitioned inheritance case, because the - * duplicate child RTE added for the parent does not appear anywhere - * else in the plan tree. - */ - if (nominalRelation < 0) - nominalRelation = appinfo->child_relid; - /* * Select cheapest path in case there's more than one. We always run * modification queries to conclusion, so we care only for the @@ -1501,36 +1619,48 @@ inheritance_planner(PlannerInfo *root) * If this child rel was excluded by constraint exclusion, exclude it * from the result plan. */ - if (IS_DUMMY_PATH(subpath)) + if (IS_DUMMY_REL(sub_final_rel)) continue; - /* - * Add the current parent's RT index to the partitione_rels set if - * we're going to create the ModifyTable path for a partitioned root - * table. - */ - if (partitioned_relids) - partitioned_relids = bms_add_member(partitioned_relids, - appinfo->parent_relid); - /* * If this is the first non-excluded child, its post-planning rtable - * becomes the initial contents of final_rtable; otherwise, append - * just its modified subquery RTEs to final_rtable. + * becomes the initial contents of final_rtable; otherwise, copy its + * modified subquery RTEs into final_rtable, to ensure we have sane + * copies of those. Also save the first non-excluded child's version + * of the rowmarks list; we assume all children will end up with + * equivalent versions of that. */ if (final_rtable == NIL) + { final_rtable = subroot->parse->rtable; + final_rowmarks = subroot->rowMarks; + } else - final_rtable = list_concat(final_rtable, - list_copy_tail(subroot->parse->rtable, - list_length(final_rtable))); + { + Assert(list_length(final_rtable) == + list_length(subroot->parse->rtable)); + if (subqueryRTindexes != NULL) + { + int oldrti = -1; + + while ((oldrti = bms_next_member(subqueryRTindexes, oldrti)) >= 0) + { + Index newrti = this_subquery_rti++; + RangeTblEntry *subqrte; + ListCell *newrticell; + + subqrte = rt_fetch(newrti, subroot->parse->rtable); + newrticell = list_nth_cell(final_rtable, newrti - 1); + lfirst(newrticell) = subqrte; + } + } + } /* * We need to collect all the RelOptInfos from all child plans into * the main PlannerInfo, since setrefs.c will need them. We use the - * last child's simple_rel_array (previous ones are too short), so we - * have to propagate forward the RelOptInfos that were already built - * in previous children. + * last child's simple_rel_array, so we have to propagate forward the + * RelOptInfos that were already built in previous children. */ Assert(subroot->simple_rel_array_size >= save_rel_array_size); for (rti = 1; rti < save_rel_array_size; rti++) @@ -1542,8 +1672,13 @@ inheritance_planner(PlannerInfo *root) } save_rel_array_size = subroot->simple_rel_array_size; save_rel_array = subroot->simple_rel_array; + save_append_rel_array = subroot->append_rel_array; - /* Make sure any initplans from this rel get into the outer list */ + /* + * Make sure any initplans from this rel get into the outer list. Note + * we're effectively assuming all children generate the same + * init_plans. + */ root->init_plans = subroot->init_plans; /* Build list of sub-paths */ @@ -1564,7 +1699,6 @@ inheritance_planner(PlannerInfo *root) subroot->parse->returningList); Assert(!parse->onConflict); - Assert(parse->mergeActionList == NIL); } /* Result path must go into outer query's FINAL upperrel */ @@ -1576,32 +1710,63 @@ inheritance_planner(PlannerInfo *root) * to get control here. */ - /* - * If we managed to exclude every child rel, return a dummy plan; it - * doesn't even need a ModifyTable node. - */ if (subpaths == NIL) { - set_dummy_rel_pathlist(final_rel); - return; - } + /* + * We managed to exclude every child rel, so generate a dummy path + * representing the empty set. Although it's clear that no data will + * be updated or deleted, we will still need to have a ModifyTable + * node so that any statement triggers are executed. (This could be + * cleaner if we fixed nodeModifyTable.c to support zero child nodes, + * but that probably wouldn't be a net win.) + */ + Path *dummy_path; - /* - * Put back the final adjusted rtable into the master copy of the Query. - * (We mustn't do this if we found no non-excluded children.) - */ - parse->rtable = final_rtable; - root->simple_rel_array_size = save_rel_array_size; - root->simple_rel_array = save_rel_array; - /* Must reconstruct master's simple_rte_array, too */ - root->simple_rte_array = (RangeTblEntry **) - palloc0((list_length(final_rtable) + 1) * sizeof(RangeTblEntry *)); - rti = 1; - foreach(lc, final_rtable) + /* tlist processing never got done, either */ + root->processed_tlist = preprocess_targetlist(root); + final_rel->reltarget = create_pathtarget(root, root->processed_tlist); + + /* Make a dummy path, cf set_dummy_rel_pathlist() */ + dummy_path = (Path *) create_append_path(NULL, final_rel, NIL, NIL, + NIL, NULL, 0, false, + NIL, -1); + + /* These lists must be nonempty to make a valid ModifyTable node */ + subpaths = list_make1(dummy_path); + subroots = list_make1(root); + resultRelations = list_make1_int(parse->resultRelation); + if (parse->withCheckOptions) + withCheckOptionLists = list_make1(parse->withCheckOptions); + if (parse->returningList) + returningLists = list_make1(parse->returningList); + /* Disable tuple routing, too, just to be safe */ + root->partColsUpdated = false; + } + else { - RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); + /* + * Put back the final adjusted rtable into the master copy of the + * Query. (We mustn't do this if we found no non-excluded children, + * since we never saved an adjusted rtable at all.) + */ + parse->rtable = final_rtable; + root->simple_rel_array_size = save_rel_array_size; + root->simple_rel_array = save_rel_array; + root->append_rel_array = save_append_rel_array; + + /* Must reconstruct master's simple_rte_array, too */ + root->simple_rte_array = (RangeTblEntry **) + palloc0((list_length(final_rtable) + 1) * sizeof(RangeTblEntry *)); + rti = 1; + foreach(lc, final_rtable) + { + RangeTblEntry *rte = lfirst_node(RangeTblEntry, lc); + + root->simple_rte_array[rti++] = rte; + } - root->simple_rte_array[rti++] = rte; + /* Put back adjusted rowmarks, too */ + root->rowMarks = final_rowmarks; } /* @@ -1614,40 +1779,22 @@ inheritance_planner(PlannerInfo *root) else rowMarks = root->rowMarks; - if (partitioned_relids) - { - int i; - - i = -1; - while ((i = bms_next_member(partitioned_relids, i)) >= 0) - partitioned_rels = lappend_int(partitioned_rels, i); - - /* - * If we're going to create ModifyTable at all, the list should - * contain at least one member, that is, the root parent's index. - */ - Assert(list_length(partitioned_rels) >= 1); - } - /* Create Path representing a ModifyTable to do the UPDATE/DELETE work */ add_path(final_rel, (Path *) create_modifytable_path(root, final_rel, parse->commandType, parse->canSetTag, nominalRelation, - partitioned_rels, + rootRelation, root->partColsUpdated, resultRelations, - 0, subpaths, subroots, withCheckOptionLists, returningLists, rowMarks, NULL, - NULL, - NULL, - SS_assign_special_param(root))); + assign_special_exec_param(root))); } /*-------------------- @@ -1683,7 +1830,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, double tuple_fraction) { Query *parse = root->parse; - List *tlist; int64 offset_est = 0; int64 count_est = 0; double limit_tuples = -1.0; @@ -1694,6 +1840,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, bool final_target_parallel_safe; RelOptInfo *current_rel; RelOptInfo *final_rel; + FinalPathExtraData extra; ListCell *lc; /* Tweak caller-supplied tuple_fraction if have LIMIT/OFFSET */ @@ -1736,20 +1883,17 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, /* * We should not need to call preprocess_targetlist, since we must be - * in a SELECT query node. Instead, use the targetlist returned by - * plan_set_operations (since this tells whether it returned any + * in a SELECT query node. Instead, use the processed_tlist returned + * by plan_set_operations (since this tells whether it returned any * resjunk columns!), and transfer any sort key information from the * original tlist. */ Assert(parse->commandType == CMD_SELECT); - tlist = root->processed_tlist; /* from plan_set_operations */ - /* for safety, copy processed_tlist instead of modifying in-place */ - tlist = postprocess_setop_tlist(copyObject(tlist), parse->targetList); - - /* Save aside the final decorated tlist */ - root->processed_tlist = tlist; + root->processed_tlist = + postprocess_setop_tlist(copyObject(root->processed_tlist), + parse->targetList); /* Also extract the PathTarget form of the setop result tlist */ final_target = current_rel->cheapest_total_path->pathtarget; @@ -1781,7 +1925,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, Assert(parse->distinctClause == NIL); root->sort_pathkeys = make_pathkeys_for_sortclauses(root, parse->sortClause, - tlist); + root->processed_tlist); } else { @@ -1821,17 +1965,14 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, parse->groupClause = preprocess_groupclause(root, NIL); } - /* Preprocess targetlist */ - tlist = preprocess_targetlist(root); - /* - * We are now done hacking up the query's targetlist. Most of the - * remaining planning work will be done with the PathTarget - * representation of tlists, but save aside the full representation so + * Preprocess targetlist. Note that much of the remaining planning + * work will be done with the PathTarget representation of tlists, but + * we must also maintain the full representation of the final tlist so * that we can transfer its decoration (resnames etc) to the topmost - * tlist of the finished Plan. + * tlist of the finished Plan. This is kept in processed_tlist. */ - root->processed_tlist = tlist; + root->processed_tlist = preprocess_targetlist(root); /* * Collect statistics about aggregates for estimating costs, and mark @@ -1849,8 +1990,8 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, MemSet(&agg_costs, 0, sizeof(AggClauseCosts)); if (parse->hasAggs) { - get_agg_clause_costs(root, (Node *) tlist, AGGSPLIT_SIMPLE, - &agg_costs); + get_agg_clause_costs(root, (Node *) root->processed_tlist, + AGGSPLIT_SIMPLE, &agg_costs); get_agg_clause_costs(root, parse->havingQual, AGGSPLIT_SIMPLE, &agg_costs); } @@ -1863,7 +2004,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, */ if (parse->hasWindowFuncs) { - wflists = find_window_functions((Node *) tlist, + wflists = find_window_functions((Node *) root->processed_tlist, list_length(parse->windowClause)); if (wflists->numWindowFuncs > 0) activeWindows = select_active_windows(root, wflists); @@ -1878,7 +2019,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, * duplicated in planagg.c. */ if (parse->hasAggs) - preprocess_minmax_aggregates(root, tlist); + preprocess_minmax_aggregates(root); /* * Figure out whether there's a hard limit on the number of rows that @@ -1898,7 +2039,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, root->limit_tuples = limit_tuples; /* Set up data needed by standard_qp_callback */ - qp_extra.tlist = tlist; qp_extra.activeWindows = activeWindows; qp_extra.groupClause = (gset_data ? (gset_data->rollups ? linitial_node(RollupData, gset_data->rollups)->groupClause : NIL) @@ -1911,17 +2051,18 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, * We also generate (in standard_qp_callback) pathkey representations * of the query's sort clause, distinct clause, etc. */ - current_rel = query_planner(root, tlist, - standard_qp_callback, &qp_extra); + current_rel = query_planner(root, standard_qp_callback, &qp_extra); /* * Convert the query's result tlist into PathTarget format. * - * Note: it's desirable to not do this till after query_planner(), + * Note: this cannot be done before query_planner() has performed + * appendrel expansion, because that might add resjunk entries to + * root->processed_tlist. Waiting till afterwards is also helpful * because the target width estimates can use per-Var width numbers * that were obtained within query_planner(). */ - final_target = create_pathtarget(root, tlist); + final_target = create_pathtarget(root, root->processed_tlist); final_target_parallel_safe = is_parallel_safe(root, (Node *) final_target->exprs); @@ -1974,7 +2115,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, { scanjoin_target = make_group_input_target(root, final_target); scanjoin_target_parallel_safe = - is_parallel_safe(root, (Node *) grouping_target->exprs); + is_parallel_safe(root, (Node *) scanjoin_target->exprs); } else { @@ -2041,6 +2182,8 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, * of the corresponding upperrels might not be needed for this query. */ root->upper_targets[UPPERREL_FINAL] = final_target; + root->upper_targets[UPPERREL_ORDERED] = final_target; + root->upper_targets[UPPERREL_DISTINCT] = sort_input_target; root->upper_targets[UPPERREL_WINDOW] = sort_input_target; root->upper_targets[UPPERREL_GROUP_AGG] = grouping_target; @@ -2075,7 +2218,6 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, grouping_target, sort_input_target, sort_input_target_parallel_safe, - tlist, wflists, activeWindows); /* Fix things up if sort_input_target contains SRFs */ @@ -2162,7 +2304,7 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, { path = (Path *) create_lockrows_path(root, final_rel, path, root->rowMarks, - SS_assign_special_param(root)); + assign_special_exec_param(root)); } /* @@ -2177,15 +2319,26 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, } /* - * If this is an INSERT/UPDATE/DELETE/MERGE, and we're not being - * called from inheritance_planner, add the ModifyTable node. + * If this is an INSERT/UPDATE/DELETE, and we're not being called from + * inheritance_planner, add the ModifyTable node. */ if (parse->commandType != CMD_SELECT && !inheritance_update) { + Index rootRelation; List *withCheckOptionLists; List *returningLists; List *rowMarks; + /* + * If target is a partition root table, we need to mark the + * ModifyTable node appropriately for that. + */ + if (rt_fetch(parse->resultRelation, parse->rtable)->relkind == + RELKIND_PARTITIONED_TABLE) + rootRelation = parse->resultRelation; + else + rootRelation = 0; + /* * Set up the WITH CHECK OPTION and RETURNING lists-of-lists, if * needed. @@ -2215,19 +2368,16 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, parse->commandType, parse->canSetTag, parse->resultRelation, - NIL, + rootRelation, false, list_make1_int(parse->resultRelation), - parse->mergeTarget_relation, list_make1(path), list_make1(root), withCheckOptionLists, returningLists, rowMarks, parse->onConflict, - parse->mergeSourceTargetList, - parse->mergeActionList, - SS_assign_special_param(root)); + assign_special_exec_param(root)); } /* And shove it into final_rel */ @@ -2250,6 +2400,11 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, } } + extra.limit_needed = limit_needed(parse); + extra.limit_tuples = limit_tuples; + extra.count_est = count_est; + extra.offset_est = offset_est; + /* * If there is an FDW that's responsible for all baserels of the query, * let it consider adding ForeignPaths. @@ -2258,12 +2413,12 @@ grouping_planner(PlannerInfo *root, bool inheritance_update, final_rel->fdwroutine->GetForeignUpperPaths) final_rel->fdwroutine->GetForeignUpperPaths(root, UPPERREL_FINAL, current_rel, final_rel, - NULL); + &extra); /* Let extensions possibly add some more paths */ if (create_upper_paths_hook) (*create_upper_paths_hook) (root, UPPERREL_FINAL, - current_rel, final_rel, NULL); + current_rel, final_rel, &extra); /* Note: currently, we leave it to callers to do set_cheapest() */ } @@ -2483,38 +2638,6 @@ remap_to_groupclause_idx(List *groupClause, } - -/* - * Detect whether a plan node is a "dummy" plan created when a relation - * is deemed not to need scanning due to constraint exclusion. - * - * Currently, such dummy plans are Result nodes with constant FALSE - * filter quals (see set_dummy_rel_pathlist and create_append_plan). - * - * XXX this probably ought to be somewhere else, but not clear where. - */ -bool -is_dummy_plan(Plan *plan) -{ - if (IsA(plan, Result)) - { - List *rcqual = (List *) ((Result *) plan)->resconstantqual; - - if (list_length(rcqual) == 1) - { - Const *constqual = (Const *) linitial(rcqual); - - if (constqual && IsA(constqual, Const)) - { - if (!constqual->constisnull && - !DatumGetBool(constqual->constvalue)) - return true; - } - } - } - return false; -} - /* * preprocess_rowmarks - set up PlanRowMarks if needed */ @@ -2880,7 +3003,7 @@ preprocess_limit(PlannerInfo *root, double tuple_fraction, * a key distinction: here we need hard constants in OFFSET/LIMIT, whereas * in preprocess_limit it's good enough to consider estimated values. */ -static bool +bool limit_needed(Query *parse) { Node *node; @@ -3007,6 +3130,14 @@ remove_useless_groupby_columns(PlannerInfo *root) if (rte->rtekind != RTE_RELATION) continue; + /* + * We must skip inheritance parent tables as some of the child rels + * may cause duplicate rows. This cannot happen with partitioned + * tables, however. + */ + if (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE) + continue; + /* Nothing to do unless this rel has multiple Vars in GROUP BY */ relattnos = groupbyattnos[relid]; if (bms_membership(relattnos) != BMS_MULTIPLE) @@ -3226,7 +3357,7 @@ extract_rollup_sets(List *groupingSets) while (lc1 && lfirst(lc1) == NIL) { ++num_empty; - lc1 = lnext(lc1); + lc1 = lnext(groupingSets, lc1); } /* bail out now if it turns out that all we had were empty sets. */ @@ -3260,7 +3391,7 @@ extract_rollup_sets(List *groupingSets) j = 0; i = 1; - for_each_cell(lc, lc1) + for_each_cell(lc, groupingSets, lc1) { List *candidate = (List *) lfirst(lc); Bitmapset *candidate_set = NULL; @@ -3413,7 +3544,6 @@ static List * reorder_grouping_sets(List *groupingsets, List *sortclause) { ListCell *lc; - ListCell *lc2; List *previous = NIL; List *result = NIL; @@ -3423,35 +3553,29 @@ reorder_grouping_sets(List *groupingsets, List *sortclause) List *new_elems = list_difference_int(candidate, previous); GroupingSetData *gs = makeNode(GroupingSetData); - if (list_length(new_elems) > 0) + while (list_length(sortclause) > list_length(previous) && + list_length(new_elems) > 0) { - while (list_length(sortclause) > list_length(previous)) - { - SortGroupClause *sc = list_nth(sortclause, list_length(previous)); - int ref = sc->tleSortGroupRef; + SortGroupClause *sc = list_nth(sortclause, list_length(previous)); + int ref = sc->tleSortGroupRef; - if (list_member_int(new_elems, ref)) - { - previous = lappend_int(previous, ref); - new_elems = list_delete_int(new_elems, ref); - } - else - { - /* diverged from the sortclause; give up on it */ - sortclause = NIL; - break; - } + if (list_member_int(new_elems, ref)) + { + previous = lappend_int(previous, ref); + new_elems = list_delete_int(new_elems, ref); } - - foreach(lc2, new_elems) + else { - previous = lappend_int(previous, lfirst_int(lc2)); + /* diverged from the sortclause; give up on it */ + sortclause = NIL; + break; } } + previous = list_concat(previous, new_elems); + gs->set = list_copy(previous); result = lcons(gs, result); - list_free(new_elems); } list_free(previous); @@ -3467,7 +3591,7 @@ standard_qp_callback(PlannerInfo *root, void *extra) { Query *parse = root->parse; standard_qp_extra *qp_extra = (standard_qp_extra *) extra; - List *tlist = qp_extra->tlist; + List *tlist = root->processed_tlist; List *activeWindows = qp_extra->activeWindows; /* @@ -3655,40 +3779,6 @@ get_number_of_groups(PlannerInfo *root, return dNumGroups; } -/* - * estimate_hashagg_tablesize - * estimate the number of bytes that a hash aggregate hashtable will - * require based on the agg_costs, path width and dNumGroups. - * - * XXX this may be over-estimating the size now that hashagg knows to omit - * unneeded columns from the hashtable. Also for mixed-mode grouping sets, - * grouping columns not in the hashed set are counted here even though hashagg - * won't store them. Is this a problem? - */ -static Size -estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs, - double dNumGroups) -{ - Size hashentrysize; - - /* Estimate per-hash-entry space at tuple width... */ - hashentrysize = MAXALIGN(path->pathtarget->width) + - MAXALIGN(SizeofMinimalTupleHeader); - - /* plus space for pass-by-ref transition values... */ - hashentrysize += agg_costs->transitionSpace; - /* plus the per-hash-entry overhead */ - hashentrysize += hash_agg_entry_size(agg_costs->numAggs); - - /* - * Note that this disregards the effect of fill-factor and growth policy - * of the hash-table. That's probably ok, given default the default - * fill-factor is relatively high. It'd be hard to meaningfully factor in - * "double-in-size" growth policies here. - */ - return hashentrysize * dNumGroups; -} - /* * create_grouping_paths * @@ -3914,9 +4004,9 @@ create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, while (--nrows >= 0) { path = (Path *) - create_result_path(root, grouped_rel, - grouped_rel->reltarget, - (List *) parse->havingQual); + create_group_result_path(root, grouped_rel, + grouped_rel->reltarget, + (List *) parse->havingQual); paths = lappend(paths, path); } path = (Path *) @@ -3924,6 +4014,7 @@ create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, grouped_rel, paths, NIL, + NIL, NULL, 0, false, @@ -3934,9 +4025,9 @@ create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, { /* No grouping sets, or just one, so one output row */ path = (Path *) - create_result_path(root, grouped_rel, - grouped_rel->reltarget, - (List *) parse->havingQual); + create_group_result_path(root, grouped_rel, + grouped_rel->reltarget, + (List *) parse->havingQual); } add_path(grouped_rel, path); @@ -3972,12 +4063,10 @@ create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, * If this is the topmost grouping relation or if the parent relation is * doing some form of partitionwise aggregation, then we may be able to do * it at this level also. However, if the input relation is not - * partitioned, partitionwise aggregate is impossible, and if it is dummy, - * partitionwise aggregate is pointless. + * partitioned, partitionwise aggregate is impossible. */ if (extra->patype != PARTITIONWISE_AGGREGATE_NONE && - input_rel->part_scheme && input_rel->part_rels && - !IS_DUMMY_REL(input_rel)) + IS_PARTITIONED_REL(input_rel)) { /* * If this is the topmost relation or if the parent relation is doing @@ -4126,7 +4215,7 @@ consider_groupingsets_paths(PlannerInfo *root, ListCell *lc; ListCell *l_start = list_head(gd->rollups); AggStrategy strat = AGG_HASHED; - Size hashsize; + double hashsize; double exclude_groups = 0.0; Assert(can_hash); @@ -4149,14 +4238,14 @@ consider_groupingsets_paths(PlannerInfo *root, * 2) If there are no empty sets and only unsortable sets, then the * rollups list will be empty (and thus l_start == NULL), and * group_pathkeys will be NIL; we must ensure that the vacuously-true - * pathkeys_contain_in test doesn't cause us to crash. + * pathkeys_contained_in test doesn't cause us to crash. */ if (l_start != NULL && pathkeys_contained_in(root->group_pathkeys, path->pathkeys)) { unhashed_rollup = lfirst_node(RollupData, l_start); exclude_groups = unhashed_rollup->numGroups; - l_start = lnext(l_start); + l_start = lnext(gd->rollups, l_start); } hashsize = estimate_hashagg_tablesize(path, @@ -4177,7 +4266,7 @@ consider_groupingsets_paths(PlannerInfo *root, */ sets_data = list_copy(gd->unsortable_sets); - for_each_cell(lc, l_start) + for_each_cell(lc, gd->rollups, l_start) { RollupData *rollup = lfirst_node(RollupData, lc); @@ -4194,8 +4283,8 @@ consider_groupingsets_paths(PlannerInfo *root, */ if (!rollup->hashable) return; - else - sets_data = list_concat(sets_data, list_copy(rollup->gsets_data)); + + sets_data = list_concat(sets_data, rollup->gsets_data); } foreach(lc, sets_data) { @@ -4293,9 +4382,9 @@ consider_groupingsets_paths(PlannerInfo *root, /* * Account first for space needed for groups we can't sort at all. */ - availspace -= (double) estimate_hashagg_tablesize(path, - agg_costs, - gd->dNumHashGroups); + availspace -= estimate_hashagg_tablesize(path, + agg_costs, + gd->dNumHashGroups); if (availspace > 0 && list_length(gd->rollups) > 1) { @@ -4338,7 +4427,7 @@ consider_groupingsets_paths(PlannerInfo *root, * below, must use the same condition. */ i = 0; - for_each_cell(lc, lnext(list_head(gd->rollups))) + for_each_cell(lc, gd->rollups, list_second_cell(gd->rollups)) { RollupData *rollup = lfirst_node(RollupData, lc); @@ -4372,7 +4461,7 @@ consider_groupingsets_paths(PlannerInfo *root, rollups = list_make1(linitial(gd->rollups)); i = 0; - for_each_cell(lc, lnext(list_head(gd->rollups))) + for_each_cell(lc, gd->rollups, list_second_cell(gd->rollups)) { RollupData *rollup = lfirst_node(RollupData, lc); @@ -4380,7 +4469,7 @@ consider_groupingsets_paths(PlannerInfo *root, { if (bms_is_member(i, hash_items)) hash_sets = list_concat(hash_sets, - list_copy(rollup->gsets_data)); + rollup->gsets_data); else rollups = lappend(rollups, rollup); ++i; @@ -4449,7 +4538,6 @@ consider_groupingsets_paths(PlannerInfo *root, * input_rel: contains the source-data Paths * input_target: result of make_window_input_target * output_target: what the topmost WindowAggPath should return - * tlist: query's target list (needed to look up pathkeys) * wflists: result of find_window_functions * activeWindows: result of select_active_windows * @@ -4461,7 +4549,6 @@ create_window_paths(PlannerInfo *root, PathTarget *input_target, PathTarget *output_target, bool output_target_parallel_safe, - List *tlist, WindowFuncLists *wflists, List *activeWindows) { @@ -4504,7 +4591,6 @@ create_window_paths(PlannerInfo *root, path, input_target, output_target, - tlist, wflists, activeWindows); } @@ -4538,7 +4624,6 @@ create_window_paths(PlannerInfo *root, * path: input Path to use (must return input_target) * input_target: result of make_window_input_target * output_target: what the topmost WindowAggPath should return - * tlist: query's target list (needed to look up pathkeys) * wflists: result of find_window_functions * activeWindows: result of select_active_windows */ @@ -4548,7 +4633,6 @@ create_one_window_path(PlannerInfo *root, Path *path, PathTarget *input_target, PathTarget *output_target, - List *tlist, WindowFuncLists *wflists, List *activeWindows) { @@ -4579,7 +4663,7 @@ create_one_window_path(PlannerInfo *root, window_pathkeys = make_pathkeys_for_window(root, wc, - tlist); + root->processed_tlist); /* Sort if necessary */ if (!pathkeys_contained_in(window_pathkeys, path->pathkeys)) @@ -4590,7 +4674,7 @@ create_one_window_path(PlannerInfo *root, -1.0); } - if (lnext(l)) + if (lnext(activeWindows, l)) { /* * Add the current WindowFuncs to the output target for this @@ -4620,8 +4704,7 @@ create_one_window_path(PlannerInfo *root, path = (Path *) create_windowagg_path(root, window_rel, path, window_target, wflists->windowFuncs[wc->winref], - wc, - window_pathkeys); + wc); } add_path(window_rel, path); @@ -5090,7 +5173,7 @@ make_group_input_target(PlannerInfo *root, PathTarget *final_target) * a regular aggregation node would, plus any aggregates used in HAVING; * except that the Aggref nodes should be marked as partial aggregates. * - * In addition, we'd better emit any Vars and PlaceholderVars that are + * In addition, we'd better emit any Vars and PlaceHolderVars that are * used outside of Aggrefs in the aggregation tlist and HAVING. (Presumably, * these would be Vars that are grouped by or used in grouping expressions.) * @@ -5252,7 +5335,7 @@ postprocess_setop_tlist(List *new_tlist, List *orig_tlist) Assert(orig_tlist_item != NULL); orig_tle = lfirst_node(TargetEntry, orig_tlist_item); - orig_tlist_item = lnext(orig_tlist_item); + orig_tlist_item = lnext(orig_tlist, orig_tlist_item); if (orig_tle->resjunk) /* should not happen */ elog(ERROR, "resjunk output columns are not implemented"); Assert(new_tle->resno == orig_tle->resno); @@ -5271,67 +5354,119 @@ postprocess_setop_tlist(List *new_tlist, List *orig_tlist) static List * select_active_windows(PlannerInfo *root, WindowFuncLists *wflists) { - List *result; - List *actives; + List *windowClause = root->parse->windowClause; + List *result = NIL; ListCell *lc; + int nActive = 0; + WindowClauseSortData *actives = palloc(sizeof(WindowClauseSortData) + * list_length(windowClause)); - /* First, make a list of the active windows */ - actives = NIL; - foreach(lc, root->parse->windowClause) + /* First, construct an array of the active windows */ + foreach(lc, windowClause) { WindowClause *wc = lfirst_node(WindowClause, lc); /* It's only active if wflists shows some related WindowFuncs */ Assert(wc->winref <= wflists->maxWinRef); - if (wflists->windowFuncs[wc->winref] != NIL) - actives = lappend(actives, wc); + if (wflists->windowFuncs[wc->winref] == NIL) + continue; + + actives[nActive].wc = wc; /* original clause */ + + /* + * For sorting, we want the list of partition keys followed by the + * list of sort keys. But pathkeys construction will remove duplicates + * between the two, so we can as well (even though we can't detect all + * of the duplicates, since some may come from ECs - that might mean + * we miss optimization chances here). We must, however, ensure that + * the order of entries is preserved with respect to the ones we do + * keep. + * + * partitionClause and orderClause had their own duplicates removed in + * parse analysis, so we're only concerned here with removing + * orderClause entries that also appear in partitionClause. + */ + actives[nActive].uniqueOrder = + list_concat_unique(list_copy(wc->partitionClause), + wc->orderClause); + nActive++; } /* - * Now, ensure that windows with identical partitioning/ordering clauses - * are adjacent in the list. This is required by the SQL standard, which - * says that only one sort is to be used for such windows, even if they - * are otherwise distinct (eg, different names or framing clauses). + * Sort active windows by their partitioning/ordering clauses, ignoring + * any framing clauses, so that the windows that need the same sorting are + * adjacent in the list. When we come to generate paths, this will avoid + * inserting additional Sort nodes. * - * There is room to be much smarter here, for example detecting whether - * one window's sort keys are a prefix of another's (so that sorting for - * the latter would do for the former), or putting windows first that - * match a sort order available for the underlying query. For the moment - * we are content with meeting the spec. - */ - result = NIL; - while (actives != NIL) - { - WindowClause *wc = linitial_node(WindowClause, actives); - ListCell *prev; - ListCell *next; - - /* Move wc from actives to result */ - actives = list_delete_first(actives); - result = lappend(result, wc); - - /* Now move any matching windows from actives to result */ - prev = NULL; - for (lc = list_head(actives); lc; lc = next) - { - WindowClause *wc2 = lfirst_node(WindowClause, lc); + * This is how we implement a specific requirement from the SQL standard, + * which says that when two or more windows are order-equivalent (i.e. + * have matching partition and order clauses, even if their names or + * framing clauses differ), then all peer rows must be presented in the + * same order in all of them. If we allowed multiple sort nodes for such + * cases, we'd risk having the peer rows end up in different orders in + * equivalent windows due to sort instability. (See General Rule 4 of + * in SQL2008 - SQL2016.) + * + * Additionally, if the entire list of clauses of one window is a prefix + * of another, put first the window with stronger sorting requirements. + * This way we will first sort for stronger window, and won't have to sort + * again for the weaker one. + */ + qsort(actives, nActive, sizeof(WindowClauseSortData), common_prefix_cmp); - next = lnext(lc); - /* framing options are NOT to be compared here! */ - if (equal(wc->partitionClause, wc2->partitionClause) && - equal(wc->orderClause, wc2->orderClause)) - { - actives = list_delete_cell(actives, lc, prev); - result = lappend(result, wc2); - } - else - prev = lc; - } - } + /* build ordered list of the original WindowClause nodes */ + for (int i = 0; i < nActive; i++) + result = lappend(result, actives[i].wc); + + pfree(actives); return result; } +/* + * common_prefix_cmp + * QSort comparison function for WindowClauseSortData + * + * Sort the windows by the required sorting clauses. First, compare the sort + * clauses themselves. Second, if one window's clauses are a prefix of another + * one's clauses, put the window with more sort clauses first. + */ +static int +common_prefix_cmp(const void *a, const void *b) +{ + const WindowClauseSortData *wcsa = a; + const WindowClauseSortData *wcsb = b; + ListCell *item_a; + ListCell *item_b; + + forboth(item_a, wcsa->uniqueOrder, item_b, wcsb->uniqueOrder) + { + SortGroupClause *sca = lfirst_node(SortGroupClause, item_a); + SortGroupClause *scb = lfirst_node(SortGroupClause, item_b); + + if (sca->tleSortGroupRef > scb->tleSortGroupRef) + return -1; + else if (sca->tleSortGroupRef < scb->tleSortGroupRef) + return 1; + else if (sca->sortop > scb->sortop) + return -1; + else if (sca->sortop < scb->sortop) + return 1; + else if (sca->nulls_first && !scb->nulls_first) + return -1; + else if (!sca->nulls_first && scb->nulls_first) + return 1; + /* no need to compare eqop, since it is fully determined by sortop */ + } + + if (list_length(wcsa->uniqueOrder) > list_length(wcsb->uniqueOrder)) + return -1; + else if (list_length(wcsa->uniqueOrder) < list_length(wcsb->uniqueOrder)) + return 1; + + return 0; +} + /* * make_window_input_target * Generate appropriate PathTarget for initial input to WindowAgg nodes. @@ -5482,8 +5617,6 @@ make_window_input_target(PlannerInfo *root, * The required ordering is first the PARTITION keys, then the ORDER keys. * In the future we might try to implement windowing using hashing, in which * case the ordering could be relaxed, but for now we always sort. - * - * Caution: if you change this, see createplan.c's get_column_info_for_window! */ static List * make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, @@ -5505,8 +5638,7 @@ make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, errdetail("Window ordering columns must be of sortable datatypes."))); /* Okay, make the combined pathkeys */ - window_sortclauses = list_concat(list_copy(wc->partitionClause), - list_copy(wc->orderClause)); + window_sortclauses = list_concat_copy(wc->partitionClause, wc->orderClause); window_pathkeys = make_pathkeys_for_sortclauses(root, window_sortclauses, tlist); @@ -5899,10 +6031,16 @@ adjust_paths_for_srfs(PlannerInfo *root, RelOptInfo *rel, * side-effect that is useful when the expression will get evaluated more than * once. Also, we must fix operator function IDs. * + * This does not return any information about dependencies of the expression. + * Hence callers should use the results only for the duration of the current + * query. Callers that would like to cache the results for longer should use + * expression_planner_with_deps, probably via the plancache. + * * Note: this must not make any damaging changes to the passed-in expression * tree. (It would actually be okay to apply fix_opfuncids to it, but since * we first do an expression_tree_mutator-based walk, what is returned will - * be a new node tree.) + * be a new node tree.) The result is constructed in the current memory + * context; beware that this can leak a lot of additional stuff there, too. */ Expr * expression_planner(Expr *expr) @@ -5921,6 +6059,57 @@ expression_planner(Expr *expr) return (Expr *) result; } +/* + * expression_planner_with_deps + * Perform planner's transformations on a standalone expression, + * returning expression dependency information along with the result. + * + * This is identical to expression_planner() except that it also returns + * information about possible dependencies of the expression, ie identities of + * objects whose definitions affect the result. As in a PlannedStmt, these + * are expressed as a list of relation Oids and a list of PlanInvalItems. + */ +Expr * +expression_planner_with_deps(Expr *expr, + List **relationOids, + List **invalItems) +{ + Node *result; + PlannerGlobal glob; + PlannerInfo root; + + /* Make up dummy planner state so we can use setrefs machinery */ + MemSet(&glob, 0, sizeof(glob)); + glob.type = T_PlannerGlobal; + glob.relationOids = NIL; + glob.invalItems = NIL; + + MemSet(&root, 0, sizeof(root)); + root.type = T_PlannerInfo; + root.glob = &glob; + + /* + * Convert named-argument function calls, insert default arguments and + * simplify constant subexprs. Collect identities of inlined functions + * and elided domains, too. + */ + result = eval_const_expressions(&root, (Node *) expr); + + /* Fill in opfuncid values if missing */ + fix_opfuncids(result); + + /* + * Now walk the finished expression to find anything else we ought to + * record as an expression dependency. + */ + (void) extract_query_dependencies_walker(result, &root); + + *relationOids = glob.relationOids; + *invalItems = glob.invalItems; + + return (Expr *) result; +} + /* * plan_cluster_use_sort @@ -5971,6 +6160,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid) rte->rtekind = RTE_RELATION; rte->relid = tableOid; rte->relkind = RELKIND_RELATION; /* Don't be too picky. */ + rte->rellockmode = AccessShareLock; rte->lateral = false; rte->inh = false; rte->inFromCl = true; @@ -6027,7 +6217,7 @@ plan_cluster_use_sort(Oid tableOid, Oid indexOid) /* Estimate the cost of index scan */ indexScanPath = create_index_path(root, indexInfo, - NIL, NIL, NIL, NIL, NIL, + NIL, NIL, NIL, NIL, ForwardScanDirection, false, NULL, 1.0, false); @@ -6066,8 +6256,7 @@ plan_create_index_workers(Oid tableOid, Oid indexOid) double allvisfrac; /* Return immediately when parallelism disabled */ - if (dynamic_shared_memory_type == DSM_IMPL_NONE || - max_parallel_maintenance_workers == 0) + if (max_parallel_maintenance_workers == 0) return 0; /* Set up largely-dummy planner state */ @@ -6086,14 +6275,16 @@ plan_create_index_workers(Oid tableOid, Oid indexOid) /* * Build a minimal RTE. * - * Set the target's table to be an inheritance parent. This is a kludge - * that prevents problems within get_relation_info(), which does not - * expect that any IndexOptInfo is currently undergoing REINDEX. + * Mark the RTE with inh = true. This is a kludge to prevent + * get_relation_info() from fetching index info, which is necessary + * because it does not expect that any IndexOptInfo is currently + * undergoing REINDEX. */ rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; rte->relid = tableOid; rte->relkind = RELKIND_RELATION; /* Don't be too picky. */ + rte->rellockmode = AccessShareLock; rte->lateral = false; rte->inh = true; rte->inFromCl = true; @@ -6105,7 +6296,8 @@ plan_create_index_workers(Oid tableOid, Oid indexOid) /* Build RelOptInfo */ rel = build_simple_rel(root, 1, NULL); - heap = heap_open(tableOid, NoLock); + /* Rels are assumed already locked by the caller */ + heap = table_open(tableOid, NoLock); index = index_open(indexOid, NoLock); /* @@ -6166,7 +6358,7 @@ plan_create_index_workers(Oid tableOid, Oid indexOid) done: index_close(index, NoLock); - heap_close(heap, NoLock); + table_close(heap, NoLock); return parallel_workers; } @@ -6313,7 +6505,7 @@ add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, if (can_hash) { - Size hashaggtablesize; + double hashaggtablesize; if (parse->groupingSets) { @@ -6624,7 +6816,7 @@ create_partial_grouping_paths(PlannerInfo *root, if (can_hash && cheapest_total_path != NULL) { - Size hashaggtablesize; + double hashaggtablesize; /* Checked above */ Assert(parse->hasAggs || parse->groupClause); @@ -6657,7 +6849,7 @@ create_partial_grouping_paths(PlannerInfo *root, if (can_hash && cheapest_partial_path != NULL) { - Size hashaggtablesize; + double hashaggtablesize; hashaggtablesize = estimate_hashagg_tablesize(cheapest_partial_path, @@ -6803,12 +6995,34 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, bool scanjoin_target_parallel_safe, bool tlist_same_exprs) { - ListCell *lc; + bool rel_is_partitioned = IS_PARTITIONED_REL(rel); PathTarget *scanjoin_target; - bool is_dummy_rel = IS_DUMMY_REL(rel); + ListCell *lc; + /* This recurses, so be paranoid. */ check_stack_depth(); + /* + * If the rel is partitioned, we want to drop its existing paths and + * generate new ones. This function would still be correct if we kept the + * existing paths: we'd modify them to generate the correct target above + * the partitioning Append, and then they'd compete on cost with paths + * generating the target below the Append. However, in our current cost + * model the latter way is always the same or cheaper cost, so modifying + * the existing paths would just be useless work. Moreover, when the cost + * is the same, varying roundoff errors might sometimes allow an existing + * path to be picked, resulting in undesirable cross-platform plan + * variations. So we drop old paths and thereby force the work to be done + * below the Append, except in the case of a non-parallel-safe target. + * + * Some care is needed, because we have to allow generate_gather_paths to + * see the old partial paths in the next stanza. Hence, zap the main + * pathlist here, then allow generate_gather_paths to add path(s) to the + * main list, and finally zap the partial pathlist. + */ + if (rel_is_partitioned) + rel->pathlist = NIL; + /* * If the scan/join target is not parallel-safe, partial paths cannot * generate it. @@ -6816,14 +7030,13 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, if (!scanjoin_target_parallel_safe) { /* - * Since we can't generate the final scan/join target, this is our - * last opportunity to use any partial paths that exist. We don't - * do this if the case where the target is parallel-safe, since we - * will be able to generate superior paths by doing it after the - * final scan/join target has been applied. - * - * Note that this may invalidate rel->cheapest_total_path, so we must - * not rely on it after this point without first calling set_cheapest. + * Since we can't generate the final scan/join target in parallel + * workers, this is our last opportunity to use any partial paths that + * exist; so build Gather path(s) that use them and emit whatever the + * current reltarget is. We don't do this in the case where the + * target is parallel-safe, since we will be able to generate superior + * paths by doing it after the final scan/join target has been + * applied. */ generate_gather_paths(root, rel, false); @@ -6832,61 +7045,27 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, rel->consider_parallel = false; } - /* - * Update the reltarget. This may not be strictly necessary in all cases, - * but it is at least necessary when create_append_path() gets called - * below directly or indirectly, since that function uses the reltarget as - * the pathtarget for the resulting path. It seems like a good idea to do - * it unconditionally. - */ - rel->reltarget = llast_node(PathTarget, scanjoin_targets); - - /* Special case: handle dummy relations separately. */ - if (is_dummy_rel) - { - /* - * Since this is a dummy rel, it's got a single Append path with no - * child paths. Replace it with a new path having the final scan/join - * target. (Note that since Append is not projection-capable, it - * would be bad to handle this using the general purpose code below; - * we'd end up putting a ProjectionPath on top of the existing Append - * node, which would cause this relation to stop appearing to be a - * dummy rel.) - */ - rel->pathlist = list_make1(create_append_path(root, rel, NIL, NIL, - NULL, 0, false, NIL, - -1)); + /* Finish dropping old paths for a partitioned rel, per comment above */ + if (rel_is_partitioned) rel->partial_pathlist = NIL; - set_cheapest(rel); - Assert(IS_DUMMY_REL(rel)); - - /* - * Forget about any child relations. There's no point in adjusting - * them and no point in using them for later planning stages (in - * particular, partitionwise aggregate). - */ - rel->nparts = 0; - rel->part_rels = NULL; - rel->boundinfo = NULL; - - return; - } /* Extract SRF-free scan/join target. */ scanjoin_target = linitial_node(PathTarget, scanjoin_targets); /* - * Adjust each input path. If the tlist exprs are the same, we can just - * inject the sortgroupref information into the existing pathtarget. - * Otherwise, replace each path with a projection path that generates the - * SRF-free scan/join target. This can't change the ordering of paths - * within rel->pathlist, so we just modify the list in place. + * Apply the SRF-free scan/join target to each existing path. + * + * If the tlist exprs are the same, we can just inject the sortgroupref + * information into the existing pathtargets. Otherwise, replace each + * path with a projection path that generates the SRF-free scan/join + * target. This can't change the ordering of paths within rel->pathlist, + * so we just modify the list in place. */ foreach(lc, rel->pathlist) { Path *subpath = (Path *) lfirst(lc); - Path *newpath; + /* Shouldn't have any parameterized paths anymore */ Assert(subpath->param_info == NULL); if (tlist_same_exprs) @@ -6894,17 +7073,18 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, scanjoin_target->sortgrouprefs; else { + Path *newpath; + newpath = (Path *) create_projection_path(root, rel, subpath, scanjoin_target); lfirst(lc) = newpath; } } - /* Same for partial paths. */ + /* Likewise adjust the targets for any partial paths. */ foreach(lc, rel->partial_pathlist) { Path *subpath = (Path *) lfirst(lc); - Path *newpath; /* Shouldn't have any parameterized paths anymore */ Assert(subpath->param_info == NULL); @@ -6914,39 +7094,62 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, scanjoin_target->sortgrouprefs; else { - newpath = (Path *) create_projection_path(root, - rel, - subpath, + Path *newpath; + + newpath = (Path *) create_projection_path(root, rel, subpath, scanjoin_target); lfirst(lc) = newpath; } } - /* Now fix things up if scan/join target contains SRFs */ + /* + * Now, if final scan/join target contains SRFs, insert ProjectSetPath(s) + * atop each existing path. (Note that this function doesn't look at the + * cheapest-path fields, which is a good thing because they're bogus right + * now.) + */ if (root->parse->hasTargetSRFs) adjust_paths_for_srfs(root, rel, scanjoin_targets, scanjoin_targets_contain_srfs); /* - * If the relation is partitioned, recurseively apply the same changes to - * all partitions and generate new Append paths. Since Append is not - * projection-capable, that might save a separate Result node, and it also - * is important for partitionwise aggregate. + * Update the rel's target to be the final (with SRFs) scan/join target. + * This now matches the actual output of all the paths, and we might get + * confused in createplan.c if they don't agree. We must do this now so + * that any append paths made in the next part will use the correct + * pathtarget (cf. create_append_path). + * + * Note that this is also necessary if GetForeignUpperPaths() gets called + * on the final scan/join relation or on any of its children, since the + * FDW might look at the rel's target to create ForeignPaths. + */ + rel->reltarget = llast_node(PathTarget, scanjoin_targets); + + /* + * If the relation is partitioned, recursively apply the scan/join target + * to all partitions, and generate brand-new Append paths in which the + * scan/join target is computed below the Append rather than above it. + * Since Append is not projection-capable, that might save a separate + * Result node, and it also is important for partitionwise aggregate. */ - if (rel->part_scheme && rel->part_rels) + if (rel_is_partitioned) { - int partition_idx; List *live_children = NIL; + int partition_idx; /* Adjust each partition. */ for (partition_idx = 0; partition_idx < rel->nparts; partition_idx++) { RelOptInfo *child_rel = rel->part_rels[partition_idx]; - ListCell *lc; AppendRelInfo **appinfos; int nappinfos; List *child_scanjoin_targets = NIL; + ListCell *lc; + + /* Pruned or dummy children can be ignored. */ + if (child_rel == NULL || IS_DUMMY_REL(child_rel)) + continue; /* Translate scan/join targets for this child. */ appinfos = find_appinfos_by_relids(root, child_rel->relids, @@ -6978,8 +7181,7 @@ apply_scanjoin_target_to_paths(PlannerInfo *root, } /* Build new paths for this relation by appending child paths. */ - if (live_children != NIL) - add_paths_to_append_rel(root, rel, live_children); + add_paths_to_append_rel(root, rel, live_children); } /* @@ -7032,6 +7234,7 @@ create_partitionwise_grouping_paths(PlannerInfo *root, List *grouped_live_children = NIL; List *partially_grouped_live_children = NIL; PathTarget *target = grouped_rel->reltarget; + bool partial_grouping_valid = true; Assert(patype != PARTITIONWISE_AGGREGATE_NONE); Assert(patype != PARTITIONWISE_AGGREGATE_PARTIAL || @@ -7048,8 +7251,9 @@ create_partitionwise_grouping_paths(PlannerInfo *root, RelOptInfo *child_grouped_rel; RelOptInfo *child_partially_grouped_rel; - /* Input child rel must have a path */ - Assert(child_input_rel->pathlist != NIL); + /* Pruned or dummy children can be ignored. */ + if (child_input_rel == NULL || IS_DUMMY_REL(child_input_rel)) + continue; /* * Copy the given "extra" structure as is and then override the @@ -7091,14 +7295,6 @@ create_partitionwise_grouping_paths(PlannerInfo *root, extra->target_parallel_safe, child_extra.havingQual); - /* Ignore empty children. They contribute nothing. */ - if (IS_DUMMY_REL(child_input_rel)) - { - mark_dummy_rel(child_grouped_rel); - - continue; - } - /* Create grouping paths for this child relation. */ create_ordinary_grouping_paths(root, child_input_rel, child_grouped_rel, @@ -7111,6 +7307,8 @@ create_partitionwise_grouping_paths(PlannerInfo *root, lappend(partially_grouped_live_children, child_partially_grouped_rel); } + else + partial_grouping_valid = false; if (patype == PARTITIONWISE_AGGREGATE_FULL) { @@ -7122,21 +7320,19 @@ create_partitionwise_grouping_paths(PlannerInfo *root, pfree(appinfos); } - /* - * All children can't be dummy at this point. If they are, then the parent - * too marked as dummy. - */ - Assert(grouped_live_children != NIL || - partially_grouped_live_children != NIL); - /* * Try to create append paths for partially grouped children. For full * partitionwise aggregation, we might have paths in the partial_pathlist * if parallel aggregation is possible. For partial partitionwise * aggregation, we may have paths in both pathlist and partial_pathlist. + * + * NB: We must have a partially grouped path for every child in order to + * generate a partially grouped path for this relation. */ - if (partially_grouped_rel) + if (partially_grouped_rel && partial_grouping_valid) { + Assert(partially_grouped_live_children != NIL); + add_paths_to_append_rel(root, partially_grouped_rel, partially_grouped_live_children); @@ -7150,7 +7346,11 @@ create_partitionwise_grouping_paths(PlannerInfo *root, /* If possible, create append paths for fully grouped children. */ if (patype == PARTITIONWISE_AGGREGATE_FULL) + { + Assert(grouped_live_children != NIL); + add_paths_to_append_rel(root, grouped_rel, grouped_live_children); + } } /* diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 833a92f5387..566ee96da8c 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -4,7 +4,7 @@ * Post-processing of a completed plan tree: fix references to subplan * vars, compute regproc values for operators, etc * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,6 +19,7 @@ #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/planmain.h" #include "optimizer/planner.h" @@ -41,9 +42,6 @@ typedef struct int num_vars; /* number of plain Var tlist entries */ bool has_ph_vars; /* are there PlaceHolderVar entries? */ bool has_non_vars; /* are there other entries? */ - bool has_conv_whole_rows; /* are there ConvertRowtypeExpr - * entries encapsulating a whole-row - * Var? */ tlist_vinfo vars[FLEXIBLE_ARRAY_MEMBER]; /* has num_vars entries */ } indexed_tlist; @@ -90,18 +88,26 @@ static bool flatten_rtes_walker(Node *node, PlannerGlobal *glob); static void add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte); static Plan *set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset); static Plan *set_indexonlyscan_references(PlannerInfo *root, - IndexOnlyScan *plan, - int rtoffset); + IndexOnlyScan *plan, + int rtoffset); static Plan *set_subqueryscan_references(PlannerInfo *root, - SubqueryScan *plan, - int rtoffset); + SubqueryScan *plan, + int rtoffset); static bool trivial_subqueryscan(SubqueryScan *plan); +static Plan *clean_up_removed_plan_level(Plan *parent, Plan *child); static void set_foreignscan_references(PlannerInfo *root, - ForeignScan *fscan, - int rtoffset); + ForeignScan *fscan, + int rtoffset); static void set_customscan_references(PlannerInfo *root, - CustomScan *cscan, - int rtoffset); + CustomScan *cscan, + int rtoffset); +static Plan *set_append_references(PlannerInfo *root, + Append *aplan, + int rtoffset); +static Plan *set_mergeappend_references(PlannerInfo *root, + MergeAppend *mplan, + int rtoffset); +static void set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset); static Node *fix_scan_expr(PlannerInfo *root, Node *node, int rtoffset); static Node *fix_scan_expr_mutator(Node *node, fix_scan_expr_context *context); static bool fix_scan_expr_walker(Node *node, fix_scan_expr_context *context); @@ -112,38 +118,36 @@ static Node *convert_combining_aggrefs(Node *node, void *context); static void set_dummy_tlist_references(Plan *plan, int rtoffset); static indexed_tlist *build_tlist_index(List *tlist); static Var *search_indexed_tlist_for_var(Var *var, - indexed_tlist *itlist, - Index newvarno, - int rtoffset); + indexed_tlist *itlist, + Index newvarno, + int rtoffset); static Var *search_indexed_tlist_for_non_var(Expr *node, - indexed_tlist *itlist, - Index newvarno); + indexed_tlist *itlist, + Index newvarno); static Var *search_indexed_tlist_for_sortgroupref(Expr *node, - Index sortgroupref, - indexed_tlist *itlist, - Index newvarno); + Index sortgroupref, + indexed_tlist *itlist, + Index newvarno); static List *fix_join_expr(PlannerInfo *root, - List *clauses, - indexed_tlist *outer_itlist, - indexed_tlist *inner_itlist, - Index acceptable_rel, int rtoffset); + List *clauses, + indexed_tlist *outer_itlist, + indexed_tlist *inner_itlist, + Index acceptable_rel, int rtoffset); static Node *fix_join_expr_mutator(Node *node, - fix_join_expr_context *context); + fix_join_expr_context *context); static Node *fix_upper_expr(PlannerInfo *root, - Node *node, - indexed_tlist *subplan_itlist, - Index newvarno, - int rtoffset); + Node *node, + indexed_tlist *subplan_itlist, + Index newvarno, + int rtoffset); static Node *fix_upper_expr_mutator(Node *node, - fix_upper_expr_context *context); + fix_upper_expr_context *context); static List *set_returning_clause_references(PlannerInfo *root, - List *rlist, - Plan *topplan, - Index resultRelation, - int rtoffset); -static bool extract_query_dependencies_walker(Node *node, - PlannerInfo *context); -static bool is_converted_whole_row_reference(Node *node); + List *rlist, + Plan *topplan, + Index resultRelation, + int rtoffset); + /***************************************************************************** * @@ -179,25 +183,28 @@ static bool is_converted_whole_row_reference(Node *node); * This will be used by plancache.c to drive invalidation of cached plans. * Relation dependencies are represented by OIDs, and everything else by * PlanInvalItems (this distinction is motivated by the shared-inval APIs). - * Currently, relations and user-defined functions are the only types of - * objects that are explicitly tracked this way. + * Currently, relations, user-defined functions, and domains are the only + * types of objects that are explicitly tracked this way. * * 8. We assign every plan node in the tree a unique ID. * * We also perform one final optimization step, which is to delete - * SubqueryScan plan nodes that aren't doing anything useful (ie, have - * no qual and a no-op targetlist). The reason for doing this last is that + * SubqueryScan, Append, and MergeAppend plan nodes that aren't doing + * anything useful. The reason for doing this last is that * it can't readily be done before set_plan_references, because it would - * break set_upper_references: the Vars in the subquery's top tlist - * wouldn't match up with the Vars in the outer plan tree. The SubqueryScan + * break set_upper_references: the Vars in the child plan's top tlist + * wouldn't match up with the Vars in the outer plan tree. A SubqueryScan * serves a necessary function as a buffer between outer query and subquery * variable numbering ... but after we've flattened the rangetable this is * no longer a problem, since then there's only one rtindex namespace. + * Likewise, Append and MergeAppend buffer between the parent and child vars + * of an appendrel, but we don't need to worry about that once we've done + * set_plan_references. * * set_plan_references recursively traverses the whole plan tree. * * The return value is normally the same Plan node passed in, but can be - * different when the passed-in Plan is a SubqueryScan we decide isn't needed. + * different when the passed-in Plan is a node we decide isn't needed. * * The flattened rangetable entries are appended to root->glob->finalrtable. * Also, rowmarks entries are appended to root->glob->finalrowmarks, and the @@ -345,7 +352,7 @@ flatten_unplanned_rtes(PlannerGlobal *glob, RangeTblEntry *rte) (void) query_tree_walker(rte->subquery, flatten_rtes_walker, (void *) glob, - QTW_EXAMINE_RTES); + QTW_EXAMINE_RTES_BEFORE); } static bool @@ -368,7 +375,7 @@ flatten_rtes_walker(Node *node, PlannerGlobal *glob) return query_tree_walker((Query *) node, flatten_rtes_walker, (void *) glob, - QTW_EXAMINE_RTES); + QTW_EXAMINE_RTES_BEFORE); } return expression_tree_walker(node, flatten_rtes_walker, (void *) glob); @@ -640,6 +647,9 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) break; case T_Hash: + set_hash_references(root, plan, rtoffset); + break; + case T_Material: case T_Sort: case T_Unique: @@ -851,67 +861,11 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) fix_scan_list(root, splan->exclRelTlist, rtoffset); } - /* - * The MERGE statement produces the target rows by performing a - * right join between the target relation and the source - * relation (which could be a plain relation or a subquery). - * The INSERT and UPDATE actions of the MERGE statement - * requires access to the columns from the source relation. We - * arrange things so that the source relation attributes are - * available as INNER_VAR and the target relation attributes - * are available from the scan tuple. - */ - if (splan->mergeActionList != NIL) - { - /* - * mergeSourceTargetList is already setup correctly to - * include all Vars coming from the source relation. So we - * fix the targetList of individual action nodes by - * ensuring that the source relation Vars are referenced - * as INNER_VAR. Note that for this to work correctly, - * during execution, the ecxt_innertuple must be set to - * the tuple obtained from the source relation. - * - * We leave the Vars from the result relation (i.e. the - * target relation) unchanged i.e. those Vars would be - * picked from the scan slot. So during execution, we must - * ensure that ecxt_scantuple is setup correctly to refer - * to the tuple from the target relation. - */ - - indexed_tlist *itlist; - - itlist = build_tlist_index(splan->mergeSourceTargetList); - - splan->mergeTargetRelation += rtoffset; - - foreach(l, splan->mergeActionList) - { - MergeAction *action = (MergeAction *) lfirst(l); - - /* Fix targetList of each action. */ - action->targetList = fix_join_expr(root, - action->targetList, - NULL, itlist, - linitial_int(splan->resultRelations), - rtoffset); - - /* Fix quals too. */ - action->qual = (Node *) fix_join_expr(root, - (List *) action->qual, - NULL, itlist, - linitial_int(splan->resultRelations), - rtoffset); - } - } - splan->nominalRelation += rtoffset; + if (splan->rootRelation) + splan->rootRelation += rtoffset; splan->exclRelRTI += rtoffset; - foreach(l, splan->partitioned_rels) - { - lfirst_int(l) += rtoffset; - } foreach(l, splan->resultRelations) { lfirst_int(l) += rtoffset; @@ -939,74 +893,33 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->resultRelIndex = list_length(root->glob->resultRelations); root->glob->resultRelations = list_concat(root->glob->resultRelations, - list_copy(splan->resultRelations)); + splan->resultRelations); /* - * If the main target relation is a partitioned table, the - * following list contains the RT indexes of partitioned child - * relations including the root, which are not included in the - * above list. We also keep RT indexes of the roots - * separately to be identified as such during the executor - * initialization. + * If the main target relation is a partitioned table, also + * add the partition root's RT index to rootResultRelations, + * and remember its index in that list in rootResultRelIndex. */ - if (splan->partitioned_rels != NIL) + if (splan->rootRelation) { - root->glob->nonleafResultRelations = - list_concat(root->glob->nonleafResultRelations, - list_copy(splan->partitioned_rels)); - /* Remember where this root will be in the global list. */ splan->rootResultRelIndex = list_length(root->glob->rootResultRelations); root->glob->rootResultRelations = lappend_int(root->glob->rootResultRelations, - linitial_int(splan->partitioned_rels)); + splan->rootRelation); } } break; case T_Append: - { - Append *splan = (Append *) plan; - - /* - * Append, like Sort et al, doesn't actually evaluate its - * targetlist or check quals. - */ - set_dummy_tlist_references(plan, rtoffset); - Assert(splan->plan.qual == NIL); - foreach(l, splan->partitioned_rels) - { - lfirst_int(l) += rtoffset; - } - foreach(l, splan->appendplans) - { - lfirst(l) = set_plan_refs(root, - (Plan *) lfirst(l), - rtoffset); - } - } - break; + /* Needs special treatment, see comments below */ + return set_append_references(root, + (Append *) plan, + rtoffset); case T_MergeAppend: - { - MergeAppend *splan = (MergeAppend *) plan; - - /* - * MergeAppend, like Sort et al, doesn't actually evaluate its - * targetlist or check quals. - */ - set_dummy_tlist_references(plan, rtoffset); - Assert(splan->plan.qual == NIL); - foreach(l, splan->partitioned_rels) - { - lfirst_int(l) += rtoffset; - } - foreach(l, splan->mergeplans) - { - lfirst(l) = set_plan_refs(root, - (Plan *) lfirst(l), + /* Needs special treatment, see comments below */ + return set_mergeappend_references(root, + (MergeAppend *) plan, rtoffset); - } - } - break; case T_RecursiveUnion: /* This doesn't evaluate targetlist or check quals either */ set_dummy_tlist_references(plan, rtoffset); @@ -1131,30 +1044,7 @@ set_subqueryscan_references(PlannerInfo *root, /* * We can omit the SubqueryScan node and just pull up the subplan. */ - ListCell *lp, - *lc; - - result = plan->subplan; - - /* We have to be sure we don't lose any initplans */ - result->initPlan = list_concat(plan->scan.plan.initPlan, - result->initPlan); - - /* - * We also have to transfer the SubqueryScan's result-column names - * into the subplan, else columns sent to client will be improperly - * labeled if this is the topmost plan level. Copy the "source - * column" information too. - */ - forboth(lp, plan->scan.plan.targetlist, lc, result->targetlist) - { - TargetEntry *ptle = (TargetEntry *) lfirst(lp); - TargetEntry *ctle = (TargetEntry *) lfirst(lc); - - ctle->resname = ptle->resname; - ctle->resorigtbl = ptle->resorigtbl; - ctle->resorigcol = ptle->resorigcol; - } + result = clean_up_removed_plan_level((Plan *) plan, plan->subplan); } else { @@ -1235,6 +1125,30 @@ trivial_subqueryscan(SubqueryScan *plan) return true; } +/* + * clean_up_removed_plan_level + * Do necessary cleanup when we strip out a SubqueryScan, Append, etc + * + * We are dropping the "parent" plan in favor of returning just its "child". + * A few small tweaks are needed. + */ +static Plan * +clean_up_removed_plan_level(Plan *parent, Plan *child) +{ + /* We have to be sure we don't lose any initplans */ + child->initPlan = list_concat(parent->initPlan, + child->initPlan); + + /* + * We also have to transfer the parent's column labeling info into the + * child, else columns sent to client will be improperly labeled if this + * is the topmost plan level. resjunk and so on may be important too. + */ + apply_tlist_labeling(child->targetlist, parent->targetlist); + + return child; +} + /* * set_foreignscan_references * Do set_plan_references processing on a ForeignScan @@ -1385,6 +1299,161 @@ set_customscan_references(PlannerInfo *root, } } +/* + * set_append_references + * Do set_plan_references processing on an Append + * + * We try to strip out the Append entirely; if we can't, we have + * to do the normal processing on it. + */ +static Plan * +set_append_references(PlannerInfo *root, + Append *aplan, + int rtoffset) +{ + ListCell *l; + + /* + * Append, like Sort et al, doesn't actually evaluate its targetlist or + * check quals. If it's got exactly one child plan, then it's not doing + * anything useful at all, and we can strip it out. + */ + Assert(aplan->plan.qual == NIL); + + /* First, we gotta recurse on the children */ + foreach(l, aplan->appendplans) + { + lfirst(l) = set_plan_refs(root, (Plan *) lfirst(l), rtoffset); + } + + /* Now, if there's just one, forget the Append and return that child */ + if (list_length(aplan->appendplans) == 1) + return clean_up_removed_plan_level((Plan *) aplan, + (Plan *) linitial(aplan->appendplans)); + + /* + * Otherwise, clean up the Append as needed. It's okay to do this after + * recursing to the children, because set_dummy_tlist_references doesn't + * look at those. + */ + set_dummy_tlist_references((Plan *) aplan, rtoffset); + + if (aplan->part_prune_info) + { + foreach(l, aplan->part_prune_info->prune_infos) + { + List *prune_infos = lfirst(l); + ListCell *l2; + + foreach(l2, prune_infos) + { + PartitionedRelPruneInfo *pinfo = lfirst(l2); + + pinfo->rtindex += rtoffset; + } + } + } + + /* We don't need to recurse to lefttree or righttree ... */ + Assert(aplan->plan.lefttree == NULL); + Assert(aplan->plan.righttree == NULL); + + return (Plan *) aplan; +} + +/* + * set_mergeappend_references + * Do set_plan_references processing on a MergeAppend + * + * We try to strip out the MergeAppend entirely; if we can't, we have + * to do the normal processing on it. + */ +static Plan * +set_mergeappend_references(PlannerInfo *root, + MergeAppend *mplan, + int rtoffset) +{ + ListCell *l; + + /* + * MergeAppend, like Sort et al, doesn't actually evaluate its targetlist + * or check quals. If it's got exactly one child plan, then it's not + * doing anything useful at all, and we can strip it out. + */ + Assert(mplan->plan.qual == NIL); + + /* First, we gotta recurse on the children */ + foreach(l, mplan->mergeplans) + { + lfirst(l) = set_plan_refs(root, (Plan *) lfirst(l), rtoffset); + } + + /* Now, if there's just one, forget the MergeAppend and return that child */ + if (list_length(mplan->mergeplans) == 1) + return clean_up_removed_plan_level((Plan *) mplan, + (Plan *) linitial(mplan->mergeplans)); + + /* + * Otherwise, clean up the MergeAppend as needed. It's okay to do this + * after recursing to the children, because set_dummy_tlist_references + * doesn't look at those. + */ + set_dummy_tlist_references((Plan *) mplan, rtoffset); + + if (mplan->part_prune_info) + { + foreach(l, mplan->part_prune_info->prune_infos) + { + List *prune_infos = lfirst(l); + ListCell *l2; + + foreach(l2, prune_infos) + { + PartitionedRelPruneInfo *pinfo = lfirst(l2); + + pinfo->rtindex += rtoffset; + } + } + } + + /* We don't need to recurse to lefttree or righttree ... */ + Assert(mplan->plan.lefttree == NULL); + Assert(mplan->plan.righttree == NULL); + + return (Plan *) mplan; +} + +/* + * set_hash_references + * Do set_plan_references processing on a Hash node + */ +static void +set_hash_references(PlannerInfo *root, Plan *plan, int rtoffset) +{ + Hash *hplan = (Hash *) plan; + Plan *outer_plan = plan->lefttree; + indexed_tlist *outer_itlist; + + /* + * Hash's hashkeys are used when feeding tuples into the hashtable, + * therefore have them reference Hash's outer plan (which itself is the + * inner plan of the HashJoin). + */ + outer_itlist = build_tlist_index(outer_plan->targetlist); + hplan->hashkeys = (List *) + fix_upper_expr(root, + (Node *) hplan->hashkeys, + outer_itlist, + OUTER_VAR, + rtoffset); + + /* Hash doesn't project */ + set_dummy_tlist_references(plan, rtoffset); + + /* Hash nodes don't have their own quals */ + Assert(plan->qual == NIL); +} + /* * copyVar * Copy a Var node. @@ -1719,6 +1788,16 @@ set_join_references(PlannerInfo *root, Join *join, int rtoffset) inner_itlist, (Index) 0, rtoffset); + + /* + * HashJoin's hashkeys are used to look for matching tuples from its + * outer plan (not the Hash node!) in the hashtable. + */ + hj->hashkeys = (List *) fix_upper_expr(root, + (Node *) hj->hashkeys, + outer_itlist, + OUTER_VAR, + rtoffset); } /* @@ -2051,7 +2130,6 @@ build_tlist_index(List *tlist) itlist->tlist = tlist; itlist->has_ph_vars = false; itlist->has_non_vars = false; - itlist->has_conv_whole_rows = false; /* Find the Vars and fill in the index array */ vinfo = itlist->vars; @@ -2070,8 +2148,6 @@ build_tlist_index(List *tlist) } else if (tle->expr && IsA(tle->expr, PlaceHolderVar)) itlist->has_ph_vars = true; - else if (is_converted_whole_row_reference((Node *) tle->expr)) - itlist->has_conv_whole_rows = true; else itlist->has_non_vars = true; } @@ -2087,10 +2163,7 @@ build_tlist_index(List *tlist) * This is like build_tlist_index, but we only index tlist entries that * are Vars belonging to some rel other than the one specified. We will set * has_ph_vars (allowing PlaceHolderVars to be matched), but not has_non_vars - * (so nothing other than Vars and PlaceHolderVars can be matched). In case of - * DML, where this function will be used, returning lists from child relations - * will be appended similar to a simple append relation. That does not require - * fixing ConvertRowtypeExpr references. So, those are not considered here. + * (so nothing other than Vars and PlaceHolderVars can be matched). */ static indexed_tlist * build_tlist_index_other_vars(List *tlist, Index ignore_rel) @@ -2107,7 +2180,6 @@ build_tlist_index_other_vars(List *tlist, Index ignore_rel) itlist->tlist = tlist; itlist->has_ph_vars = false; itlist->has_non_vars = false; - itlist->has_conv_whole_rows = false; /* Find the desired Vars and fill in the index array */ vinfo = itlist->vars; @@ -2310,7 +2382,6 @@ static Node * fix_join_expr_mutator(Node *node, fix_join_expr_context *context) { Var *newvar; - bool converted_whole_row; if (node == NULL) return NULL; @@ -2378,14 +2449,8 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) /* If not supplied by input plans, evaluate the contained expr */ return fix_join_expr_mutator((Node *) phv->phexpr, context); } - if (IsA(node, Param)) - return fix_param_node(context->root, (Param *) node); - /* Try matching more complex expressions too, if tlists have any */ - converted_whole_row = is_converted_whole_row_reference(node); - if (context->outer_itlist && - (context->outer_itlist->has_non_vars || - (context->outer_itlist->has_conv_whole_rows && converted_whole_row))) + if (context->outer_itlist && context->outer_itlist->has_non_vars) { newvar = search_indexed_tlist_for_non_var((Expr *) node, context->outer_itlist, @@ -2393,9 +2458,7 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) if (newvar) return (Node *) newvar; } - if (context->inner_itlist && - (context->inner_itlist->has_non_vars || - (context->inner_itlist->has_conv_whole_rows && converted_whole_row))) + if (context->inner_itlist && context->inner_itlist->has_non_vars) { newvar = search_indexed_tlist_for_non_var((Expr *) node, context->inner_itlist, @@ -2403,6 +2466,9 @@ fix_join_expr_mutator(Node *node, fix_join_expr_context *context) if (newvar) return (Node *) newvar; } + /* Special cases (apply only AFTER failing to match to lower tlist) */ + if (IsA(node, Param)) + return fix_param_node(context->root, (Param *) node); fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_join_expr_mutator, @@ -2490,6 +2556,16 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) /* If not supplied by input plan, evaluate the contained expr */ return fix_upper_expr_mutator((Node *) phv->phexpr, context); } + /* Try matching more complex expressions too, if tlist has any */ + if (context->subplan_itlist->has_non_vars) + { + newvar = search_indexed_tlist_for_non_var((Expr *) node, + context->subplan_itlist, + context->newvarno); + if (newvar) + return (Node *) newvar; + } + /* Special cases (apply only AFTER failing to match to lower tlist) */ if (IsA(node, Param)) return fix_param_node(context->root, (Param *) node); if (IsA(node, Aggref)) @@ -2514,17 +2590,6 @@ fix_upper_expr_mutator(Node *node, fix_upper_expr_context *context) } /* If no match, just fall through to process it normally */ } - /* Try matching more complex expressions too, if tlist has any */ - if (context->subplan_itlist->has_non_vars || - (context->subplan_itlist->has_conv_whole_rows && - is_converted_whole_row_reference(node))) - { - newvar = search_indexed_tlist_for_non_var((Expr *) node, - context->subplan_itlist, - context->newvarno); - if (newvar) - return (Node *) newvar; - } fix_expr_common(context->root, node); return expression_tree_mutator(node, fix_upper_expr_mutator, @@ -2636,6 +2701,42 @@ record_plan_function_dependency(PlannerInfo *root, Oid funcid) } } +/* + * record_plan_type_dependency + * Mark the current plan as depending on a particular type. + * + * This is exported so that eval_const_expressions can record a + * dependency on a domain that it's removed a CoerceToDomain node for. + * + * We don't currently need to record dependencies on domains that the + * plan contains CoerceToDomain nodes for, though that might change in + * future. Hence, this isn't actually called in this module, though + * someday fix_expr_common might call it. + */ +void +record_plan_type_dependency(PlannerInfo *root, Oid typid) +{ + /* + * As in record_plan_function_dependency, ignore the possibility that + * someone would change a built-in domain. + */ + if (typid >= (Oid) FirstBootstrapObjectId) + { + PlanInvalItem *inval_item = makeNode(PlanInvalItem); + + /* + * It would work to use any syscache on pg_type, but the easiest is + * TYPEOID since we already have the type's OID at hand. Note that + * plancache.c knows we use TYPEOID. + */ + inval_item->cacheId = TYPEOID; + inval_item->hashValue = GetSysCacheHashValue1(TYPEOID, + ObjectIdGetDatum(typid)); + + root->glob->invalItems = lappend(root->glob->invalItems, inval_item); + } +} + /* * extract_query_dependencies * Given a rewritten, but not yet planned, query or queries @@ -2645,6 +2746,13 @@ record_plan_function_dependency(PlannerInfo *root, Oid funcid) * * This is needed by plancache.c to handle invalidation of cached unplanned * queries. + * + * Note: this does not go through eval_const_expressions, and hence doesn't + * reflect its additions of inlined functions and elided CoerceToDomain nodes + * to the invalItems list. This is obviously OK for functions, since we'll + * see them in the original query tree anyway. For domains, it's OK because + * we don't care about domains unless they get elided. That is, a plan might + * have domain dependencies that the query tree doesn't. */ void extract_query_dependencies(Node *query, @@ -2674,14 +2782,20 @@ extract_query_dependencies(Node *query, *hasRowSecurity = glob.dependsOnRole; } -static bool +/* + * Tree walker for extract_query_dependencies. + * + * This is exported so that expression_planner_with_deps can call it on + * simple expressions (post-planning, not before planning, in that case). + * In that usage, glob.dependsOnRole isn't meaningful, but the relationOids + * and invalItems lists are added to as needed. + */ +bool extract_query_dependencies_walker(Node *node, PlannerInfo *context) { if (node == NULL) return false; Assert(!IsA(node, PlaceHolderVar)); - /* Extract function dependencies and check for regclass Consts */ - fix_expr_common(context, node); if (IsA(node, Query)) { Query *query = (Query *) node; @@ -2721,36 +2835,8 @@ extract_query_dependencies_walker(Node *node, PlannerInfo *context) return query_tree_walker(query, extract_query_dependencies_walker, (void *) context, 0); } + /* Extract function dependencies and check for regclass Consts */ + fix_expr_common(context, node); return expression_tree_walker(node, extract_query_dependencies_walker, (void *) context); } - -/* - * is_converted_whole_row_reference - * If the given node is a ConvertRowtypeExpr encapsulating a whole-row - * reference as implicit cast, return true. Otherwise return false. - */ -static bool -is_converted_whole_row_reference(Node *node) -{ - ConvertRowtypeExpr *convexpr; - - if (!node || !IsA(node, ConvertRowtypeExpr)) - return false; - - /* Traverse nested ConvertRowtypeExpr's. */ - convexpr = castNode(ConvertRowtypeExpr, node); - while (convexpr->convertformat == COERCE_IMPLICIT_CAST && - IsA(convexpr->arg, ConvertRowtypeExpr)) - convexpr = castNode(ConvertRowtypeExpr, convexpr->arg); - - if (IsA(convexpr->arg, Var)) - { - Var *var = castNode(Var, convexpr->arg); - - if (var->varattno == 0) - return true; - } - - return false; -} diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c index 83008d76619..48b62a55de8 100644 --- a/src/backend/optimizer/plan/subselect.c +++ b/src/backend/optimizer/plan/subselect.c @@ -1,9 +1,12 @@ /*------------------------------------------------------------------------- * * subselect.c - * Planning routines for subselects and parameters. + * Planning routines for subselects. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * This module deals with SubLinks and CTEs, but not subquery RTEs (i.e., + * not sub-SELECT-in-FROM cases). + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,12 +25,13 @@ #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" +#include "optimizer/paramassign.h" #include "optimizer/pathnode.h" #include "optimizer/planmain.h" #include "optimizer/planner.h" #include "optimizer/prep.h" #include "optimizer/subselect.h" -#include "optimizer/var.h" #include "parser/parse_relation.h" #include "rewrite/rewriteManip.h" #include "utils/builtins.h" @@ -53,388 +57,53 @@ typedef struct finalize_primnode_context Bitmapset *paramids; /* Non-local PARAM_EXEC paramids found */ } finalize_primnode_context; +typedef struct inline_cte_walker_context +{ + const char *ctename; /* name and relative level of target CTE */ + int levelsup; + int refcount; /* number of remaining references */ + Query *ctequery; /* query to substitute */ +} inline_cte_walker_context; + static Node *build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, - List *plan_params, - SubLinkType subLinkType, int subLinkId, - Node *testexpr, bool adjust_testexpr, - bool unknownEqFalse); + List *plan_params, + SubLinkType subLinkType, int subLinkId, + Node *testexpr, bool adjust_testexpr, + bool unknownEqFalse); static List *generate_subquery_params(PlannerInfo *root, List *tlist, - List **paramIds); + List **paramIds); static List *generate_subquery_vars(PlannerInfo *root, List *tlist, - Index varno); + Index varno); static Node *convert_testexpr(PlannerInfo *root, - Node *testexpr, - List *subst_nodes); + Node *testexpr, + List *subst_nodes); static Node *convert_testexpr_mutator(Node *node, - convert_testexpr_context *context); + convert_testexpr_context *context); static bool subplan_is_hashable(Plan *plan); static bool testexpr_is_hashable(Node *testexpr); static bool hash_ok_operator(OpExpr *expr); +static bool contain_dml(Node *node); +static bool contain_dml_walker(Node *node, void *context); +static bool contain_outer_selfref(Node *node); +static bool contain_outer_selfref_walker(Node *node, Index *depth); +static void inline_cte(PlannerInfo *root, CommonTableExpr *cte); +static bool inline_cte_walker(Node *node, inline_cte_walker_context *context); static bool simplify_EXISTS_query(PlannerInfo *root, Query *query); static Query *convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect, - Node **testexpr, List **paramIds); + Node **testexpr, List **paramIds); static Node *replace_correlation_vars_mutator(Node *node, PlannerInfo *root); static Node *process_sublinks_mutator(Node *node, - process_sublinks_context *context); + process_sublinks_context *context); static Bitmapset *finalize_plan(PlannerInfo *root, - Plan *plan, - int gather_param, - Bitmapset *valid_params, - Bitmapset *scan_params); + Plan *plan, + int gather_param, + Bitmapset *valid_params, + Bitmapset *scan_params); static bool finalize_primnode(Node *node, finalize_primnode_context *context); static bool finalize_agg_primnode(Node *node, finalize_primnode_context *context); -/* - * Select a PARAM_EXEC number to identify the given Var as a parameter for - * the current subquery, or for a nestloop's inner scan. - * If the Var already has a param in the current context, return that one. - */ -static int -assign_param_for_var(PlannerInfo *root, Var *var) -{ - ListCell *ppl; - PlannerParamItem *pitem; - Index levelsup; - - /* Find the query level the Var belongs to */ - for (levelsup = var->varlevelsup; levelsup > 0; levelsup--) - root = root->parent_root; - - /* If there's already a matching PlannerParamItem there, just use it */ - foreach(ppl, root->plan_params) - { - pitem = (PlannerParamItem *) lfirst(ppl); - if (IsA(pitem->item, Var)) - { - Var *pvar = (Var *) pitem->item; - - /* - * This comparison must match _equalVar(), except for ignoring - * varlevelsup. Note that _equalVar() ignores the location. - */ - if (pvar->varno == var->varno && - pvar->varattno == var->varattno && - pvar->vartype == var->vartype && - pvar->vartypmod == var->vartypmod && - pvar->varcollid == var->varcollid && - pvar->varnoold == var->varnoold && - pvar->varoattno == var->varoattno) - return pitem->paramId; - } - } - - /* Nope, so make a new one */ - var = copyObject(var); - var->varlevelsup = 0; - - pitem = makeNode(PlannerParamItem); - pitem->item = (Node *) var; - pitem->paramId = list_length(root->glob->paramExecTypes); - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - var->vartype); - - root->plan_params = lappend(root->plan_params, pitem); - - return pitem->paramId; -} - -/* - * Generate a Param node to replace the given Var, - * which is expected to have varlevelsup > 0 (ie, it is not local). - */ -static Param * -replace_outer_var(PlannerInfo *root, Var *var) -{ - Param *retval; - int i; - - Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level); - - /* Find the Var in the appropriate plan_params, or add it if not present */ - i = assign_param_for_var(root, var); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = i; - retval->paramtype = var->vartype; - retval->paramtypmod = var->vartypmod; - retval->paramcollid = var->varcollid; - retval->location = var->location; - - return retval; -} - -/* - * Generate a Param node to replace the given Var, which will be supplied - * from an upper NestLoop join node. - * - * This is effectively the same as replace_outer_var, except that we expect - * the Var to be local to the current query level. - */ -Param * -assign_nestloop_param_var(PlannerInfo *root, Var *var) -{ - Param *retval; - int i; - - Assert(var->varlevelsup == 0); - - i = assign_param_for_var(root, var); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = i; - retval->paramtype = var->vartype; - retval->paramtypmod = var->vartypmod; - retval->paramcollid = var->varcollid; - retval->location = var->location; - - return retval; -} - -/* - * Select a PARAM_EXEC number to identify the given PlaceHolderVar as a - * parameter for the current subquery, or for a nestloop's inner scan. - * If the PHV already has a param in the current context, return that one. - * - * This is just like assign_param_for_var, except for PlaceHolderVars. - */ -static int -assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) -{ - ListCell *ppl; - PlannerParamItem *pitem; - Index levelsup; - - /* Find the query level the PHV belongs to */ - for (levelsup = phv->phlevelsup; levelsup > 0; levelsup--) - root = root->parent_root; - - /* If there's already a matching PlannerParamItem there, just use it */ - foreach(ppl, root->plan_params) - { - pitem = (PlannerParamItem *) lfirst(ppl); - if (IsA(pitem->item, PlaceHolderVar)) - { - PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item; - - /* We assume comparing the PHIDs is sufficient */ - if (pphv->phid == phv->phid) - return pitem->paramId; - } - } - - /* Nope, so make a new one */ - phv = copyObject(phv); - if (phv->phlevelsup != 0) - { - IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0); - Assert(phv->phlevelsup == 0); - } - - pitem = makeNode(PlannerParamItem); - pitem->item = (Node *) phv; - pitem->paramId = list_length(root->glob->paramExecTypes); - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - exprType((Node *) phv->phexpr)); - - root->plan_params = lappend(root->plan_params, pitem); - - return pitem->paramId; -} - -/* - * Generate a Param node to replace the given PlaceHolderVar, - * which is expected to have phlevelsup > 0 (ie, it is not local). - * - * This is just like replace_outer_var, except for PlaceHolderVars. - */ -static Param * -replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) -{ - Param *retval; - int i; - - Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level); - - /* Find the PHV in the appropriate plan_params, or add it if not present */ - i = assign_param_for_placeholdervar(root, phv); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = i; - retval->paramtype = exprType((Node *) phv->phexpr); - retval->paramtypmod = exprTypmod((Node *) phv->phexpr); - retval->paramcollid = exprCollation((Node *) phv->phexpr); - retval->location = -1; - - return retval; -} - -/* - * Generate a Param node to replace the given PlaceHolderVar, which will be - * supplied from an upper NestLoop join node. - * - * This is just like assign_nestloop_param_var, except for PlaceHolderVars. - */ -Param * -assign_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) -{ - Param *retval; - int i; - - Assert(phv->phlevelsup == 0); - - i = assign_param_for_placeholdervar(root, phv); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = i; - retval->paramtype = exprType((Node *) phv->phexpr); - retval->paramtypmod = exprTypmod((Node *) phv->phexpr); - retval->paramcollid = exprCollation((Node *) phv->phexpr); - retval->location = -1; - - return retval; -} - -/* - * Generate a Param node to replace the given Aggref - * which is expected to have agglevelsup > 0 (ie, it is not local). - */ -static Param * -replace_outer_agg(PlannerInfo *root, Aggref *agg) -{ - Param *retval; - PlannerParamItem *pitem; - Index levelsup; - - Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level); - - /* Find the query level the Aggref belongs to */ - for (levelsup = agg->agglevelsup; levelsup > 0; levelsup--) - root = root->parent_root; - - /* - * It does not seem worthwhile to try to match duplicate outer aggs. Just - * make a new slot every time. - */ - agg = copyObject(agg); - IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0); - Assert(agg->agglevelsup == 0); - - pitem = makeNode(PlannerParamItem); - pitem->item = (Node *) agg; - pitem->paramId = list_length(root->glob->paramExecTypes); - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - agg->aggtype); - - root->plan_params = lappend(root->plan_params, pitem); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = pitem->paramId; - retval->paramtype = agg->aggtype; - retval->paramtypmod = -1; - retval->paramcollid = agg->aggcollid; - retval->location = agg->location; - - return retval; -} - -/* - * Generate a Param node to replace the given GroupingFunc expression which is - * expected to have agglevelsup > 0 (ie, it is not local). - */ -static Param * -replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp) -{ - Param *retval; - PlannerParamItem *pitem; - Index levelsup; - Oid ptype; - - Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level); - - /* Find the query level the GroupingFunc belongs to */ - for (levelsup = grp->agglevelsup; levelsup > 0; levelsup--) - root = root->parent_root; - - /* - * It does not seem worthwhile to try to match duplicate outer aggs. Just - * make a new slot every time. - */ - grp = copyObject(grp); - IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0); - Assert(grp->agglevelsup == 0); - ptype = exprType((Node *) grp); - - pitem = makeNode(PlannerParamItem); - pitem->item = (Node *) grp; - pitem->paramId = list_length(root->glob->paramExecTypes); - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - ptype); - - root->plan_params = lappend(root->plan_params, pitem); - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = pitem->paramId; - retval->paramtype = ptype; - retval->paramtypmod = -1; - retval->paramcollid = InvalidOid; - retval->location = grp->location; - - return retval; -} - -/* - * Generate a new Param node that will not conflict with any other. - * - * This is used to create Params representing subplan outputs. - * We don't need to build a PlannerParamItem for such a Param, but we do - * need to make sure we record the type in paramExecTypes (otherwise, - * there won't be a slot allocated for it). - */ -static Param * -generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, - Oid paramcollation) -{ - Param *retval; - - retval = makeNode(Param); - retval->paramkind = PARAM_EXEC; - retval->paramid = list_length(root->glob->paramExecTypes); - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - paramtype); - retval->paramtype = paramtype; - retval->paramtypmod = paramtypmod; - retval->paramcollid = paramcollation; - retval->location = -1; - - return retval; -} - -/* - * Assign a (nonnegative) PARAM_EXEC ID for a special parameter (one that - * is not actually used to carry a value at runtime). Such parameters are - * used for special runtime signaling purposes, such as connecting a - * recursive union node to its worktable scan node or forcing plan - * re-evaluation within the EvalPlanQual mechanism. No actual Param node - * exists with this ID, however. - */ -int -SS_assign_special_param(PlannerInfo *root) -{ - int paramId = list_length(root->glob->paramExecTypes); - - root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, - InvalidOid); - return paramId; -} - /* * Get the datatype/typmod/collation of the first column of the plan's output. * @@ -716,7 +385,7 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, Param *prm; Assert(testexpr == NULL); - prm = generate_new_param(root, BOOLOID, -1, InvalidOid); + prm = generate_new_exec_param(root, BOOLOID, -1, InvalidOid); splan->setParam = list_make1_int(prm->paramid); isInitPlan = true; result = (Node *) prm; @@ -728,10 +397,10 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, Assert(!te->resjunk); Assert(testexpr == NULL); - prm = generate_new_param(root, - exprType((Node *) te->expr), - exprTypmod((Node *) te->expr), - exprCollation((Node *) te->expr)); + prm = generate_new_exec_param(root, + exprType((Node *) te->expr), + exprTypmod((Node *) te->expr), + exprCollation((Node *) te->expr)); splan->setParam = list_make1_int(prm->paramid); isInitPlan = true; result = (Node *) prm; @@ -748,10 +417,10 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, if (!OidIsValid(arraytype)) elog(ERROR, "could not find array type for datatype %s", format_type_be(exprType((Node *) te->expr))); - prm = generate_new_param(root, - arraytype, - exprTypmod((Node *) te->expr), - exprCollation((Node *) te->expr)); + prm = generate_new_exec_param(root, + arraytype, + exprTypmod((Node *) te->expr), + exprCollation((Node *) te->expr)); splan->setParam = list_make1_int(prm->paramid); isInitPlan = true; result = (Node *) prm; @@ -898,7 +567,7 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot, { ptr += sprintf(ptr, "$%d%s", lfirst_int(lc), - lnext(lc) ? "," : ")"); + lnext(splan->setParam, lc) ? "," : ")"); } } @@ -930,10 +599,10 @@ generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds) if (tent->resjunk) continue; - param = generate_new_param(root, - exprType((Node *) tent->expr), - exprTypmod((Node *) tent->expr), - exprCollation((Node *) tent->expr)); + param = generate_new_exec_param(root, + exprType((Node *) tent->expr), + exprTypmod((Node *) tent->expr), + exprCollation((Node *) tent->expr)); result = lappend(result, param); ids = lappend_int(ids, param->paramid); } @@ -1084,7 +753,7 @@ testexpr_is_hashable(Node *testexpr) if (hash_ok_operator((OpExpr *) testexpr)) return true; } - else if (and_clause(testexpr)) + else if (is_andclause(testexpr)) { ListCell *l; @@ -1149,10 +818,13 @@ hash_ok_operator(OpExpr *expr) /* * SS_process_ctes: process a query's WITH list * - * We plan each interesting WITH item and convert it to an initplan. + * Consider each CTE in the WITH list and either ignore it (if it's an + * unreferenced SELECT), "inline" it to create a regular sub-SELECT-in-FROM, + * or convert it to an initplan. + * * A side effect is to fill in root->cte_plan_ids with a list that * parallels root->parse->cteList and provides the subplan ID for - * each CTE's initplan. + * each CTE's initplan, or a dummy ID (-1) if we didn't make an initplan. */ void SS_process_ctes(PlannerInfo *root) @@ -1183,6 +855,53 @@ SS_process_ctes(PlannerInfo *root) continue; } + /* + * Consider inlining the CTE (creating RTE_SUBQUERY RTE(s)) instead of + * implementing it as a separately-planned CTE. + * + * We cannot inline if any of these conditions hold: + * + * 1. The user said not to (the CTEMaterializeAlways option). + * + * 2. The CTE is recursive. + * + * 3. The CTE has side-effects; this includes either not being a plain + * SELECT, or containing volatile functions. Inlining might change + * the side-effects, which would be bad. + * + * 4. The CTE is multiply-referenced and contains a self-reference to + * a recursive CTE outside itself. Inlining would result in multiple + * recursive self-references, which we don't support. + * + * Otherwise, we have an option whether to inline or not. That should + * always be a win if there's just a single reference, but if the CTE + * is multiply-referenced then it's unclear: inlining adds duplicate + * computations, but the ability to absorb restrictions from the outer + * query level could outweigh that. We do not have nearly enough + * information at this point to tell whether that's true, so we let + * the user express a preference. Our default behavior is to inline + * only singly-referenced CTEs, but a CTE marked CTEMaterializeNever + * will be inlined even if multiply referenced. + * + * Note: we check for volatile functions last, because that's more + * expensive than the other tests needed. + */ + if ((cte->ctematerialized == CTEMaterializeNever || + (cte->ctematerialized == CTEMaterializeDefault && + cte->cterefcount == 1)) && + !cte->cterecursive && + cmdType == CMD_SELECT && + !contain_dml(cte->ctequery) && + (cte->cterefcount <= 1 || + !contain_outer_selfref(cte->ctequery)) && + !contain_volatile_functions(cte->ctequery)) + { + inline_cte(root, cte); + /* Make a dummy entry in cte_plan_ids */ + root->cte_plan_ids = lappend_int(root->cte_plan_ids, -1); + continue; + } + /* * Copy the source Query node. Probably not necessary, but let's keep * this similar to make_subplan. @@ -1257,7 +976,7 @@ SS_process_ctes(PlannerInfo *root) * ParamExecData slot for this param ID for communication among * multiple CteScan nodes that might be scanning this CTE.) */ - paramid = SS_assign_special_param(root); + paramid = assign_special_exec_param(root); splan->setParam = list_make1_int(paramid); /* @@ -1279,6 +998,182 @@ SS_process_ctes(PlannerInfo *root) } } +/* + * contain_dml: is any subquery not a plain SELECT? + * + * We reject SELECT FOR UPDATE/SHARE as well as INSERT etc. + */ +static bool +contain_dml(Node *node) +{ + return contain_dml_walker(node, NULL); +} + +static bool +contain_dml_walker(Node *node, void *context) +{ + if (node == NULL) + return false; + if (IsA(node, Query)) + { + Query *query = (Query *) node; + + if (query->commandType != CMD_SELECT || + query->rowMarks != NIL) + return true; + + return query_tree_walker(query, contain_dml_walker, context, 0); + } + return expression_tree_walker(node, contain_dml_walker, context); +} + +/* + * contain_outer_selfref: is there an external recursive self-reference? + */ +static bool +contain_outer_selfref(Node *node) +{ + Index depth = 0; + + /* + * We should be starting with a Query, so that depth will be 1 while + * examining its immediate contents. + */ + Assert(IsA(node, Query)); + + return contain_outer_selfref_walker(node, &depth); +} + +static bool +contain_outer_selfref_walker(Node *node, Index *depth) +{ + if (node == NULL) + return false; + if (IsA(node, RangeTblEntry)) + { + RangeTblEntry *rte = (RangeTblEntry *) node; + + /* + * Check for a self-reference to a CTE that's above the Query that our + * search started at. + */ + if (rte->rtekind == RTE_CTE && + rte->self_reference && + rte->ctelevelsup >= *depth) + return true; + return false; /* allow range_table_walker to continue */ + } + if (IsA(node, Query)) + { + /* Recurse into subquery, tracking nesting depth properly */ + Query *query = (Query *) node; + bool result; + + (*depth)++; + + result = query_tree_walker(query, contain_outer_selfref_walker, + (void *) depth, QTW_EXAMINE_RTES_BEFORE); + + (*depth)--; + + return result; + } + return expression_tree_walker(node, contain_outer_selfref_walker, + (void *) depth); +} + +/* + * inline_cte: convert RTE_CTE references to given CTE into RTE_SUBQUERYs + */ +static void +inline_cte(PlannerInfo *root, CommonTableExpr *cte) +{ + struct inline_cte_walker_context context; + + context.ctename = cte->ctename; + /* Start at levelsup = -1 because we'll immediately increment it */ + context.levelsup = -1; + context.refcount = cte->cterefcount; + context.ctequery = castNode(Query, cte->ctequery); + + (void) inline_cte_walker((Node *) root->parse, &context); + + /* Assert we replaced all references */ + Assert(context.refcount == 0); +} + +static bool +inline_cte_walker(Node *node, inline_cte_walker_context *context) +{ + if (node == NULL) + return false; + if (IsA(node, Query)) + { + Query *query = (Query *) node; + + context->levelsup++; + + /* + * Visit the query's RTE nodes after their contents; otherwise + * query_tree_walker would descend into the newly inlined CTE query, + * which we don't want. + */ + (void) query_tree_walker(query, inline_cte_walker, context, + QTW_EXAMINE_RTES_AFTER); + + context->levelsup--; + + return false; + } + else if (IsA(node, RangeTblEntry)) + { + RangeTblEntry *rte = (RangeTblEntry *) node; + + if (rte->rtekind == RTE_CTE && + strcmp(rte->ctename, context->ctename) == 0 && + rte->ctelevelsup == context->levelsup) + { + /* + * Found a reference to replace. Generate a copy of the CTE query + * with appropriate level adjustment for outer references (e.g., + * to other CTEs). + */ + Query *newquery = copyObject(context->ctequery); + + if (context->levelsup > 0) + IncrementVarSublevelsUp((Node *) newquery, context->levelsup, 1); + + /* + * Convert the RTE_CTE RTE into a RTE_SUBQUERY. + * + * Historically, a FOR UPDATE clause has been treated as extending + * into views and subqueries, but not into CTEs. We preserve this + * distinction by not trying to push rowmarks into the new + * subquery. + */ + rte->rtekind = RTE_SUBQUERY; + rte->subquery = newquery; + rte->security_barrier = false; + + /* Zero out CTE-specific fields */ + rte->ctename = NULL; + rte->ctelevelsup = 0; + rte->self_reference = false; + rte->coltypes = NIL; + rte->coltypmods = NIL; + rte->colcollations = NIL; + + /* Count the number of replacements we've done */ + context->refcount--; + } + + return false; + } + + return expression_tree_walker(node, inline_cte_walker, context); +} + + /* * convert_ANY_sublink_to_join: try to convert an ANY SubLink to a join * @@ -1459,12 +1354,6 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, if (!simplify_EXISTS_query(root, subselect)) return NULL; - /* - * The subquery must have a nonempty jointree, else we won't have a join. - */ - if (subselect->jointree->fromlist == NIL) - return NULL; - /* * Separate out the WHERE clause. (We could theoretically also remove * top-level plain JOIN/ON clauses, but it's probably not worth the @@ -1493,6 +1382,11 @@ convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, if (contain_volatile_functions(whereClause)) return NULL; + /* + * The subquery must have a nonempty jointree, but we can make it so. + */ + replace_empty_jointree(subselect); + /* * Prepare to pull up the sub-select into top range table. * @@ -1852,9 +1746,7 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect, */ tlist = testlist = paramids = NIL; resno = 1; - /* there's no "forfour" so we have to chase one of the lists manually */ - cc = list_head(opcollations); - forthree(lc, leftargs, rc, rightargs, oc, opids) + forfour(lc, leftargs, rc, rightargs, oc, opids, cc, opcollations) { Node *leftarg = (Node *) lfirst(lc); Node *rightarg = (Node *) lfirst(rc); @@ -1862,11 +1754,10 @@ convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect, Oid opcollation = lfirst_oid(cc); Param *param; - cc = lnext(cc); - param = generate_new_param(root, - exprType(rightarg), - exprTypmod(rightarg), - exprCollation(rightarg)); + param = generate_new_exec_param(root, + exprType(rightarg), + exprTypmod(rightarg), + exprCollation(rightarg)); tlist = lappend(tlist, makeTargetEntry((Expr *) rightarg, resno++, @@ -2039,7 +1930,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context) * propagates down in both cases. (Note that this is unlike the meaning * of "top level qual" used in most other places in Postgres.) */ - if (and_clause(node)) + if (is_andclause(node)) { List *newargs = NIL; ListCell *l; @@ -2052,7 +1943,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context) Node *newarg; newarg = process_sublinks_mutator(lfirst(l), &locContext); - if (and_clause(newarg)) + if (is_andclause(newarg)) newargs = list_concat(newargs, ((BoolExpr *) newarg)->args); else newargs = lappend(newargs, newarg); @@ -2060,7 +1951,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context) return (Node *) make_andclause(newargs); } - if (or_clause(node)) + if (is_orclause(node)) { List *newargs = NIL; ListCell *l; @@ -2073,7 +1964,7 @@ process_sublinks_mutator(Node *node, process_sublinks_context *context) Node *newarg; newarg = process_sublinks_mutator(lfirst(l), &locContext); - if (or_clause(newarg)) + if (is_orclause(newarg)) newargs = list_concat(newargs, ((BoolExpr *) newarg)->args); else newargs = lappend(newargs, newarg); @@ -2917,7 +2808,7 @@ finalize_primnode(Node *node, finalize_primnode_context *context) * parameter change signaling since we always re-evaluate the subplan. * Note that this wouldn't work too well if there might be uses of the * same param IDs elsewhere in the plan, but that can't happen because - * generate_new_param never tries to merge params. + * generate_new_exec_param never tries to merge params. */ foreach(lc, subplan->paramIds) { @@ -2983,7 +2874,8 @@ SS_make_initplan_output_param(PlannerInfo *root, Oid resulttype, int32 resulttypmod, Oid resultcollation) { - return generate_new_param(root, resulttype, resulttypmod, resultcollation); + return generate_new_exec_param(root, resulttype, + resulttypmod, resultcollation); } /* diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 45d82da4591..f489f140e37 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -4,15 +4,17 @@ * Planner preprocessing for subqueries and join tree manipulation. * * NOTE: the intended sequence for invoking these operations is + * replace_empty_jointree * pull_up_sublinks - * inline_set_returning_functions + * preprocess_function_rtes * pull_up_subqueries * flatten_simple_union_all * do expression preprocessing (including flattening JOIN alias vars) * reduce_outer_joins + * remove_useless_result_rtes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,14 +26,15 @@ #include "postgres.h" #include "catalog/pg_type.h" +#include "funcapi.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/placeholder.h" #include "optimizer/prep.h" #include "optimizer/subselect.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" #include "rewrite/rewriteManip.h" @@ -59,65 +62,116 @@ typedef struct reduce_outer_joins_state } reduce_outer_joins_state; static Node *pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode, - Relids *relids); + Relids *relids); static Node *pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, - Node **jtlink1, Relids available_rels1, - Node **jtlink2, Relids available_rels2); + Node **jtlink1, Relids available_rels1, + Node **jtlink2, Relids available_rels2); static Node *pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, - JoinExpr *lowest_outer_join, - JoinExpr *lowest_nulling_outer_join, - AppendRelInfo *containing_appendrel, - bool deletion_ok); + JoinExpr *lowest_outer_join, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel); static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, - RangeTblEntry *rte, - JoinExpr *lowest_outer_join, - JoinExpr *lowest_nulling_outer_join, - AppendRelInfo *containing_appendrel, - bool deletion_ok); + RangeTblEntry *rte, + JoinExpr *lowest_outer_join, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel); static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, - RangeTblEntry *rte); + RangeTblEntry *rte); static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, - int parentRTindex, Query *setOpQuery, - int childRToffset); + int parentRTindex, Query *setOpQuery, + int childRToffset); static void make_setop_translation_list(Query *query, Index newvarno, - List **translated_vars); + List **translated_vars); static bool is_simple_subquery(Query *subquery, RangeTblEntry *rte, - JoinExpr *lowest_outer_join, - bool deletion_ok); + JoinExpr *lowest_outer_join); static Node *pull_up_simple_values(PlannerInfo *root, Node *jtnode, - RangeTblEntry *rte); -static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte, - bool deletion_ok); + RangeTblEntry *rte); +static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte); +static Node *pull_up_constant_function(PlannerInfo *root, Node *jtnode, + RangeTblEntry *rte, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel); static bool is_simple_union_all(Query *subquery); static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, - List *colTypes); + List *colTypes); static bool is_safe_append_member(Query *subquery); static bool jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, - Relids safe_upper_varnos); + Relids safe_upper_varnos); +static void perform_pullup_replace_vars(PlannerInfo *root, + pullup_replace_vars_context *rvcontext, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel); static void replace_vars_in_jointree(Node *jtnode, - pullup_replace_vars_context *context, - JoinExpr *lowest_nulling_outer_join); + pullup_replace_vars_context *context, + JoinExpr *lowest_nulling_outer_join); static Node *pullup_replace_vars(Node *expr, - pullup_replace_vars_context *context); + pullup_replace_vars_context *context); static Node *pullup_replace_vars_callback(Var *var, - replace_rte_variables_context *context); + replace_rte_variables_context *context); static Query *pullup_replace_vars_subquery(Query *query, - pullup_replace_vars_context *context); -static Node *pull_up_subqueries_cleanup(Node *jtnode); + pullup_replace_vars_context *context); static reduce_outer_joins_state *reduce_outer_joins_pass1(Node *jtnode); static void reduce_outer_joins_pass2(Node *jtnode, - reduce_outer_joins_state *state, - PlannerInfo *root, - Relids nonnullable_rels, - List *nonnullable_vars, - List *forced_null_vars); -static void substitute_multiple_relids(Node *node, - int varno, Relids subrelids); + reduce_outer_joins_state *state, + PlannerInfo *root, + Relids nonnullable_rels, + List *nonnullable_vars, + List *forced_null_vars); +static Node *remove_useless_results_recurse(PlannerInfo *root, Node *jtnode); +static int get_result_relid(PlannerInfo *root, Node *jtnode); +static void remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc); +static bool find_dependent_phvs(Node *node, int varno); +static void substitute_phv_relids(Node *node, + int varno, Relids subrelids); static void fix_append_rel_relids(List *append_rel_list, int varno, - Relids subrelids); + Relids subrelids); static Node *find_jointree_node_for_rel(Node *jtnode, int relid); +/* + * replace_empty_jointree + * If the Query's jointree is empty, replace it with a dummy RTE_RESULT + * relation. + * + * By doing this, we can avoid a bunch of corner cases that formerly existed + * for SELECTs with omitted FROM clauses. An example is that a subquery + * with empty jointree previously could not be pulled up, because that would + * have resulted in an empty relid set, making the subquery not uniquely + * identifiable for join or PlaceHolderVar processing. + * + * Unlike most other functions in this file, this function doesn't recurse; + * we rely on other processing to invoke it on sub-queries at suitable times. + */ +void +replace_empty_jointree(Query *parse) +{ + RangeTblEntry *rte; + Index rti; + RangeTblRef *rtr; + + /* Nothing to do if jointree is already nonempty */ + if (parse->jointree->fromlist != NIL) + return; + + /* We mustn't change it in the top level of a setop tree, either */ + if (parse->setOperations) + return; + + /* Create suitable RTE */ + rte = makeNode(RangeTblEntry); + rte->rtekind = RTE_RESULT; + rte->eref = makeAlias("*RESULT*", NIL); + + /* Add it to rangetable */ + parse->rtable = lappend(parse->rtable, rte); + rti = list_length(parse->rtable); + + /* And jam a reference into the jointree */ + rtr = makeNode(RangeTblRef); + rtr->rtindex = rti; + parse->jointree->fromlist = list_make1(rtr); +} + /* * pull_up_sublinks * Attempt to pull up ANY and EXISTS SubLinks to be treated as @@ -452,7 +506,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, /* Else return it unmodified */ return node; } - if (not_clause(node)) + if (is_notclause(node)) { /* If the immediate argument of NOT is EXISTS, try to convert */ SubLink *sublink = (SubLink *) get_notclausearg((Expr *) node); @@ -519,7 +573,7 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, /* Else return it unmodified */ return node; } - if (and_clause(node)) + if (is_andclause(node)) { /* Recurse into AND clause */ List *newclauses = NIL; @@ -552,8 +606,9 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, } /* - * inline_set_returning_functions - * Attempt to "inline" set-returning functions in the FROM clause. + * preprocess_function_rtes + * Constant-simplify any FUNCTION RTEs in the FROM clause, and then + * attempt to "inline" any that are set-returning functions. * * If an RTE_FUNCTION rtable entry invokes a set-returning function that * contains just a simple SELECT, we can convert the rtable entry to an @@ -566,11 +621,18 @@ pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, * obtained via inlining. However, we do it after pull_up_sublinks * so that we can inline any functions used in SubLink subselects. * + * The reason for applying const-simplification at this stage is that + * (a) we'd need to do it anyway to inline a SRF, and (b) by doing it now, + * we can be sure that pull_up_constant_function() will see constants + * if there are constants to be seen. This approach also guarantees + * that every FUNCTION RTE has been const-simplified, allowing planner.c's + * preprocess_expression() to skip doing it again. + * * Like most of the planner, this feels free to scribble on its input data * structure. */ void -inline_set_returning_functions(PlannerInfo *root) +preprocess_function_rtes(PlannerInfo *root) { ListCell *rt; @@ -582,14 +644,21 @@ inline_set_returning_functions(PlannerInfo *root) { Query *funcquery; + /* Apply const-simplification */ + rte->functions = (List *) + eval_const_expressions(root, (Node *) rte->functions); + /* Check safety of expansion, and expand if possible */ funcquery = inline_set_returning_function(root, rte); if (funcquery) { - /* Successful expansion, replace the rtable entry */ + /* Successful expansion, convert the RTE to a subquery */ rte->rtekind = RTE_SUBQUERY; rte->subquery = funcquery; + rte->security_barrier = false; + /* Clear fields that should not be set in a subquery RTE */ rte->functions = NIL; + rte->funcordinality = false; } } } @@ -608,16 +677,11 @@ pull_up_subqueries(PlannerInfo *root) { /* Top level of jointree must always be a FromExpr */ Assert(IsA(root->parse->jointree, FromExpr)); - /* Reset flag saying we need a deletion cleanup pass */ - root->hasDeletedRTEs = false; /* Recursion starts with no containing join nor appendrel */ root->parse->jointree = (FromExpr *) pull_up_subqueries_recurse(root, (Node *) root->parse->jointree, - NULL, NULL, NULL, false); - /* Apply cleanup phase if necessary */ - if (root->hasDeletedRTEs) - root->parse->jointree = (FromExpr *) - pull_up_subqueries_cleanup((Node *) root->parse->jointree); + NULL, NULL, NULL); + /* We should still have a FromExpr */ Assert(IsA(root->parse->jointree, FromExpr)); } @@ -626,8 +690,6 @@ pull_up_subqueries(PlannerInfo *root) * Recursive guts of pull_up_subqueries. * * This recursively processes the jointree and returns a modified jointree. - * Or, if it's valid to drop the current node from the jointree completely, - * it returns NULL. * * If this jointree node is within either side of an outer join, then * lowest_outer_join references the lowest such JoinExpr node; otherwise @@ -644,37 +706,27 @@ pull_up_subqueries(PlannerInfo *root) * This forces use of the PlaceHolderVar mechanism for all non-Var targetlist * items, and puts some additional restrictions on what can be pulled up. * - * deletion_ok is true if the caller can cope with us returning NULL for a - * deletable leaf node (for example, a VALUES RTE that could be pulled up). - * If it's false, we'll avoid pullup in such cases. - * * A tricky aspect of this code is that if we pull up a subquery we have * to replace Vars that reference the subquery's outputs throughout the * parent query, including quals attached to jointree nodes above the one - * we are currently processing! We handle this by being careful not to - * change the jointree structure while recursing: no nodes other than leaf - * RangeTblRef entries and entirely-empty FromExprs will be replaced or - * deleted. Also, we can't turn pullup_replace_vars loose on the whole - * jointree, because it'll return a mutated copy of the tree; we have to + * we are currently processing! We handle this by being careful to maintain + * validity of the jointree structure while recursing, in the following sense: + * whenever we recurse, all qual expressions in the tree must be reachable + * from the top level, in case the recursive call needs to modify them. + * + * Notice also that we can't turn pullup_replace_vars loose on the whole + * jointree, because it'd return a mutated copy of the tree; we have to * invoke it just on the quals, instead. This behavior is what makes it * reasonable to pass lowest_outer_join and lowest_nulling_outer_join as * pointers rather than some more-indirect way of identifying the lowest * OJs. Likewise, we don't replace append_rel_list members but only their * substructure, so the containing_appendrel reference is safe to use. - * - * Because of the rule that no jointree nodes with substructure can be - * replaced, we cannot fully handle the case of deleting nodes from the tree: - * when we delete one child of a JoinExpr, we need to replace the JoinExpr - * with a FromExpr, and that can't happen here. Instead, we set the - * root->hasDeletedRTEs flag, which tells pull_up_subqueries() that an - * additional pass over the tree is needed to clean up. */ static Node * pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, JoinExpr *lowest_outer_join, JoinExpr *lowest_nulling_outer_join, - AppendRelInfo *containing_appendrel, - bool deletion_ok) + AppendRelInfo *containing_appendrel) { Assert(jtnode != NULL); if (IsA(jtnode, RangeTblRef)) @@ -690,15 +742,13 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, * unless is_safe_append_member says so. */ if (rte->rtekind == RTE_SUBQUERY && - is_simple_subquery(rte->subquery, rte, - lowest_outer_join, deletion_ok) && + is_simple_subquery(rte->subquery, rte, lowest_outer_join) && (containing_appendrel == NULL || is_safe_append_member(rte->subquery))) return pull_up_simple_subquery(root, jtnode, rte, lowest_outer_join, lowest_nulling_outer_join, - containing_appendrel, - deletion_ok); + containing_appendrel); /* * Alternatively, is it a simple UNION ALL subquery? If so, flatten @@ -722,58 +772,32 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, if (rte->rtekind == RTE_VALUES && lowest_outer_join == NULL && containing_appendrel == NULL && - is_simple_values(root, rte, deletion_ok)) + is_simple_values(root, rte)) return pull_up_simple_values(root, jtnode, rte); + /* + * Or perhaps it's a FUNCTION RTE that we could inline? + */ + if (rte->rtekind == RTE_FUNCTION) + return pull_up_constant_function(root, jtnode, rte, + lowest_nulling_outer_join, + containing_appendrel); + /* Otherwise, do nothing at this node. */ } else if (IsA(jtnode, FromExpr)) { FromExpr *f = (FromExpr *) jtnode; - bool have_undeleted_child = false; ListCell *l; Assert(containing_appendrel == NULL); - - /* - * If the FromExpr has quals, it's not deletable even if its parent - * would allow deletion. - */ - if (f->quals) - deletion_ok = false; - + /* Recursively transform all the child nodes */ foreach(l, f->fromlist) { - /* - * In a non-deletable FromExpr, we can allow deletion of child - * nodes so long as at least one child remains; so it's okay - * either if any previous child survives, or if there's more to - * come. If all children are deletable in themselves, we'll force - * the last one to remain unflattened. - * - * As a separate matter, we can allow deletion of all children of - * the top-level FromExpr in a query, since that's a special case - * anyway. - */ - bool sub_deletion_ok = (deletion_ok || - have_undeleted_child || - lnext(l) != NULL || - f == root->parse->jointree); - lfirst(l) = pull_up_subqueries_recurse(root, lfirst(l), lowest_outer_join, lowest_nulling_outer_join, - NULL, - sub_deletion_ok); - if (lfirst(l) != NULL) - have_undeleted_child = true; - } - - if (deletion_ok && !have_undeleted_child) - { - /* OK to delete this FromExpr entirely */ - root->hasDeletedRTEs = true; /* probably is set already */ - return NULL; + NULL); } } else if (IsA(jtnode, JoinExpr)) @@ -785,22 +809,14 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, switch (j->jointype) { case JOIN_INNER: - - /* - * INNER JOIN can allow deletion of either child node, but not - * both. So right child gets permission to delete only if - * left child didn't get removed. - */ j->larg = pull_up_subqueries_recurse(root, j->larg, lowest_outer_join, lowest_nulling_outer_join, - NULL, - true); + NULL); j->rarg = pull_up_subqueries_recurse(root, j->rarg, lowest_outer_join, lowest_nulling_outer_join, - NULL, - j->larg != NULL); + NULL); break; case JOIN_LEFT: case JOIN_SEMI: @@ -808,37 +824,31 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, j->larg = pull_up_subqueries_recurse(root, j->larg, j, lowest_nulling_outer_join, - NULL, - false); + NULL); j->rarg = pull_up_subqueries_recurse(root, j->rarg, j, j, - NULL, - false); + NULL); break; case JOIN_FULL: j->larg = pull_up_subqueries_recurse(root, j->larg, j, j, - NULL, - false); + NULL); j->rarg = pull_up_subqueries_recurse(root, j->rarg, j, j, - NULL, - false); + NULL); break; case JOIN_RIGHT: j->larg = pull_up_subqueries_recurse(root, j->larg, j, j, - NULL, - false); + NULL); j->rarg = pull_up_subqueries_recurse(root, j->rarg, j, lowest_nulling_outer_join, - NULL, - false); + NULL); break; default: elog(ERROR, "unrecognized join type: %d", @@ -858,8 +868,8 @@ pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, * * jtnode is a RangeTblRef that has been tentatively identified as a simple * subquery by pull_up_subqueries. We return the replacement jointree node, - * or NULL if the subquery can be deleted entirely, or jtnode itself if we - * determine that the subquery can't be pulled up after all. + * or jtnode itself if we determine that the subquery can't be pulled up + * after all. * * rte is the RangeTblEntry referenced by jtnode. Remaining parameters are * as for pull_up_subqueries_recurse. @@ -868,8 +878,7 @@ static Node * pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, JoinExpr *lowest_outer_join, JoinExpr *lowest_nulling_outer_join, - AppendRelInfo *containing_appendrel, - bool deletion_ok) + AppendRelInfo *containing_appendrel) { Query *parse = root->parse; int varno = ((RangeTblRef *) jtnode)->rtindex; @@ -906,6 +915,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, subroot->cte_plan_ids = NIL; subroot->multiexpr_params = NIL; subroot->eq_classes = NIL; + subroot->ec_merging_done = false; subroot->append_rel_list = NIL; subroot->rowMarks = NIL; memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels)); @@ -914,7 +924,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, subroot->grouping_map = NULL; subroot->minmax_aggs = NIL; subroot->qual_security_level = 0; - subroot->hasInheritedTarget = false; + subroot->inhTargetKind = INHKIND_NONE; subroot->hasRecursion = false; subroot->wt_param_id = -1; subroot->non_recursive_path = NULL; @@ -922,6 +932,12 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, /* No CTEs to worry about */ Assert(subquery->cteList == NIL); + /* + * If the FROM clause is empty, replace it with a dummy RTE_RESULT RTE, so + * that we don't need so many special cases to deal with that situation. + */ + replace_empty_jointree(subquery); + /* * Pull up any SubLinks within the subquery's quals, so that we don't * leave unoptimized SubLinks behind. @@ -930,9 +946,10 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, pull_up_sublinks(subroot); /* - * Similarly, inline any set-returning functions in its rangetable. + * Similarly, preprocess its function RTEs to inline any set-returning + * functions in its rangetable. */ - inline_set_returning_functions(subroot); + preprocess_function_rtes(subroot); /* * Recursively pull up the subquery's subqueries, so that @@ -954,8 +971,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, * easier just to keep this "if" looking the same as the one in * pull_up_subqueries_recurse. */ - if (is_simple_subquery(subquery, rte, - lowest_outer_join, deletion_ok) && + if (is_simple_subquery(subquery, rte, lowest_outer_join) && (containing_appendrel == NULL || is_safe_append_member(subquery))) { /* good to go */ @@ -983,7 +999,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, * maybe even in the rewriter; but for now let's just fix this case here.) */ subquery->targetList = (List *) - flatten_join_alias_vars(subroot, (Node *) subquery->targetList); + flatten_join_alias_vars(subroot->parse, (Node *) subquery->targetList); /* * Adjust level-0 varnos in subquery so that we can append its rangetable @@ -1061,72 +1077,11 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, /* * Replace all of the top query's references to the subquery's outputs * with copies of the adjusted subtlist items, being careful not to - * replace any of the jointree structure. (This'd be a lot cleaner if we - * could use query_tree_mutator.) We have to use PHVs in the targetList, - * returningList, and havingQual, since those are certainly above any - * outer join. replace_vars_in_jointree tracks its location in the - * jointree and uses PHVs or not appropriately. + * replace any of the jointree structure. */ - parse->targetList = (List *) - pullup_replace_vars((Node *) parse->targetList, &rvcontext); - parse->returningList = (List *) - pullup_replace_vars((Node *) parse->returningList, &rvcontext); - if (parse->onConflict) - { - parse->onConflict->onConflictSet = (List *) - pullup_replace_vars((Node *) parse->onConflict->onConflictSet, - &rvcontext); - parse->onConflict->onConflictWhere = - pullup_replace_vars(parse->onConflict->onConflictWhere, - &rvcontext); - - /* - * We assume ON CONFLICT's arbiterElems, arbiterWhere, exclRelTlist - * can't contain any references to a subquery - */ - } - replace_vars_in_jointree((Node *) parse->jointree, &rvcontext, - lowest_nulling_outer_join); - Assert(parse->setOperations == NULL); - parse->havingQual = pullup_replace_vars(parse->havingQual, &rvcontext); - - /* - * Replace references in the translated_vars lists of appendrels. When - * pulling up an appendrel member, we do not need PHVs in the list of the - * parent appendrel --- there isn't any outer join between. Elsewhere, use - * PHVs for safety. (This analysis could be made tighter but it seems - * unlikely to be worth much trouble.) - */ - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc); - bool save_need_phvs = rvcontext.need_phvs; - - if (appinfo == containing_appendrel) - rvcontext.need_phvs = false; - appinfo->translated_vars = (List *) - pullup_replace_vars((Node *) appinfo->translated_vars, &rvcontext); - rvcontext.need_phvs = save_need_phvs; - } - - /* - * Replace references in the joinaliasvars lists of join RTEs. - * - * You might think that we could avoid using PHVs for alias vars of joins - * below lowest_nulling_outer_join, but that doesn't work because the - * alias vars could be referenced above that join; we need the PHVs to be - * present in such references after the alias vars get flattened. (It - * might be worth trying to be smarter here, someday.) - */ - foreach(lc, parse->rtable) - { - RangeTblEntry *otherrte = (RangeTblEntry *) lfirst(lc); - - if (otherrte->rtekind == RTE_JOIN) - otherrte->joinaliasvars = (List *) - pullup_replace_vars((Node *) otherrte->joinaliasvars, - &rvcontext); - } + perform_pullup_replace_vars(root, &rvcontext, + lowest_nulling_outer_join, + containing_appendrel); /* * If the subquery had a LATERAL marker, propagate that to any of its @@ -1156,6 +1111,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, case RTE_JOIN: case RTE_CTE: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* these can't contain any lateral references */ break; } @@ -1192,7 +1148,7 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, Relids subrelids; subrelids = get_relids_in_jointree((Node *) subquery->jointree, false); - substitute_multiple_relids((Node *) parse, varno, subrelids); + substitute_phv_relids((Node *) parse, varno, subrelids); fix_append_rel_relids(root->append_rel_list, varno, subrelids); } @@ -1232,17 +1188,14 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, /* * Return the adjusted subquery jointree to replace the RangeTblRef entry - * in parent's jointree; or, if we're flattening a subquery with empty - * FROM list, return NULL to signal deletion of the subquery from the - * parent jointree (and set hasDeletedRTEs to ensure cleanup later). + * in parent's jointree; or, if the FromExpr is degenerate, just return + * its single member. */ - if (subquery->jointree->fromlist == NIL) - { - Assert(deletion_ok); - Assert(subquery->jointree->quals == NULL); - root->hasDeletedRTEs = true; - return NULL; - } + Assert(IsA(subquery->jointree, FromExpr)); + Assert(subquery->jointree->fromlist != NIL); + if (subquery->jointree->quals == NULL && + list_length(subquery->jointree->fromlist) == 1) + return (Node *) linitial(subquery->jointree->fromlist); return (Node *) subquery->jointree; } @@ -1378,7 +1331,7 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex, rtr = makeNode(RangeTblRef); rtr->rtindex = childRTindex; (void) pull_up_subqueries_recurse(root, (Node *) rtr, - NULL, NULL, appinfo, false); + NULL, NULL, appinfo); } else if (IsA(setOp, SetOperationStmt)) { @@ -1433,12 +1386,10 @@ make_setop_translation_list(Query *query, Index newvarno, * (Note subquery is not necessarily equal to rte->subquery; it could be a * processed copy of that.) * lowest_outer_join is the lowest outer join above the subquery, or NULL. - * deletion_ok is true if it'd be okay to delete the subquery entirely. */ static bool is_simple_subquery(Query *subquery, RangeTblEntry *rte, - JoinExpr *lowest_outer_join, - bool deletion_ok) + JoinExpr *lowest_outer_join) { /* * Let's just make sure it's a valid subselect ... @@ -1487,44 +1438,6 @@ is_simple_subquery(Query *subquery, RangeTblEntry *rte, if (rte->security_barrier) return false; - /* - * Don't pull up a subquery with an empty jointree, unless it has no quals - * and deletion_ok is true and we're not underneath an outer join. - * - * query_planner() will correctly generate a Result plan for a jointree - * that's totally empty, but we can't cope with an empty FromExpr - * appearing lower down in a jointree: we identify join rels via baserelid - * sets, so we couldn't distinguish a join containing such a FromExpr from - * one without it. We can only handle such cases if the place where the - * subquery is linked is a FromExpr or inner JOIN that would still be - * nonempty after removal of the subquery, so that it's still identifiable - * via its contained baserelids. Safe contexts are signaled by - * deletion_ok. - * - * But even in a safe context, we must keep the subquery if it has any - * quals, because it's unclear where to put them in the upper query. - * - * Also, we must forbid pullup if such a subquery is underneath an outer - * join, because then we might need to wrap its output columns with - * PlaceHolderVars, and the PHVs would then have empty relid sets meaning - * we couldn't tell where to evaluate them. (This test is separate from - * the deletion_ok flag for possible future expansion: deletion_ok tells - * whether the immediate parent site in the jointree could cope, not - * whether we'd have PHV issues. It's possible this restriction could be - * fixed by letting the PHVs use the relids of the parent jointree item, - * but that complication is for another day.) - * - * Note that deletion of a subquery is also dependent on the check below - * that its targetlist contains no set-returning functions. Deletion from - * a FROM list or inner JOIN is okay only if the subquery must return - * exactly one row. - */ - if (subquery->jointree->fromlist == NIL && - (subquery->jointree->quals != NULL || - !deletion_ok || - lowest_outer_join != NULL)) - return false; - /* * If the subquery is LATERAL, check for pullup restrictions from that. */ @@ -1599,9 +1512,10 @@ is_simple_subquery(Query *subquery, RangeTblEntry *rte, * Pull up a single simple VALUES RTE. * * jtnode is a RangeTblRef that has been identified as a simple VALUES RTE - * by pull_up_subqueries. We always return NULL indicating that the RTE - * can be deleted entirely (all failure cases should have been detected by - * is_simple_values()). + * by pull_up_subqueries. We always return a RangeTblRef representing a + * RESULT RTE to replace it (all failure cases should have been detected by + * is_simple_values()). Actually, what we return is just jtnode, because + * we replace the VALUES RTE in the rangetable with the RESULT RTE. * * rte is the RangeTblEntry referenced by jtnode. Because of the limited * possible usage of VALUES RTEs, we do not need the remaining parameters @@ -1663,48 +1577,37 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte) /* * Replace all of the top query's references to the RTE's outputs with * copies of the adjusted VALUES expressions, being careful not to replace - * any of the jointree structure. (This'd be a lot cleaner if we could use - * query_tree_mutator.) Much of this should be no-ops in the dummy Query - * that surrounds a VALUES RTE, but it's not enough code to be worth - * removing. + * any of the jointree structure. We can assume there's no outer joins or + * appendrels in the dummy Query that surrounds a VALUES RTE. */ - parse->targetList = (List *) - pullup_replace_vars((Node *) parse->targetList, &rvcontext); - parse->returningList = (List *) - pullup_replace_vars((Node *) parse->returningList, &rvcontext); - if (parse->onConflict) - { - parse->onConflict->onConflictSet = (List *) - pullup_replace_vars((Node *) parse->onConflict->onConflictSet, - &rvcontext); - parse->onConflict->onConflictWhere = - pullup_replace_vars(parse->onConflict->onConflictWhere, - &rvcontext); - - /* - * We assume ON CONFLICT's arbiterElems, arbiterWhere, exclRelTlist - * can't contain any references to a subquery - */ - } - replace_vars_in_jointree((Node *) parse->jointree, &rvcontext, NULL); - Assert(parse->setOperations == NULL); - parse->havingQual = pullup_replace_vars(parse->havingQual, &rvcontext); + perform_pullup_replace_vars(root, &rvcontext, NULL, NULL); /* - * There should be no appendrels to fix, nor any join alias Vars, nor any - * outer joins and hence no PlaceHolderVars. + * There should be no appendrels to fix, nor any outer joins and hence no + * PlaceHolderVars. */ Assert(root->append_rel_list == NIL); - Assert(list_length(parse->rtable) == 1); Assert(root->join_info_list == NIL); Assert(root->placeholder_list == NIL); /* - * Return NULL to signal deletion of the VALUES RTE from the parent - * jointree (and set hasDeletedRTEs to ensure cleanup later). + * Replace the VALUES RTE with a RESULT RTE. The VALUES RTE is the only + * rtable entry in the current query level, so this is easy. */ - root->hasDeletedRTEs = true; - return NULL; + Assert(list_length(parse->rtable) == 1); + + /* Create suitable RTE */ + rte = makeNode(RangeTblEntry); + rte->rtekind = RTE_RESULT; + rte->eref = makeAlias("*RESULT*", NIL); + + /* Replace rangetable */ + parse->rtable = list_make1(rte); + + /* We could manufacture a new RangeTblRef, but the one we have is fine */ + Assert(varno == 1); + + return jtnode; } /* @@ -1713,24 +1616,16 @@ pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte) * to pull up into the parent query. * * rte is the RTE_VALUES RangeTblEntry to check. - * deletion_ok is true if it'd be okay to delete the VALUES RTE entirely. */ static bool -is_simple_values(PlannerInfo *root, RangeTblEntry *rte, bool deletion_ok) +is_simple_values(PlannerInfo *root, RangeTblEntry *rte) { Assert(rte->rtekind == RTE_VALUES); /* - * We can only pull up a VALUES RTE if deletion_ok is true. It's - * basically the same case as a sub-select with empty FROM list; see - * comments in is_simple_subquery(). - */ - if (!deletion_ok) - return false; - - /* - * Also, there must be exactly one VALUES list, else it's not semantically - * correct to delete the VALUES RTE. + * There must be exactly one VALUES list, else it's not semantically + * correct to replace the VALUES RTE with a RESULT RTE, nor would we have + * a unique set of expressions to substitute into the parent query. */ if (list_length(rte->values_lists) != 1) return false; @@ -1743,8 +1638,8 @@ is_simple_values(PlannerInfo *root, RangeTblEntry *rte, bool deletion_ok) /* * Don't pull up a VALUES that contains any set-returning or volatile - * functions. Again, the considerations here are basically identical to - * restrictions on a subquery's targetlist. + * functions. The considerations here are basically identical to the + * restrictions on a pull-able subquery's targetlist. */ if (expression_returns_set((Node *) rte->values_lists) || contain_volatile_functions((Node *) rte->values_lists)) @@ -1763,6 +1658,142 @@ is_simple_values(PlannerInfo *root, RangeTblEntry *rte, bool deletion_ok) return true; } +/* + * pull_up_constant_function + * Pull up an RTE_FUNCTION expression that was simplified to a constant. + * + * jtnode is a RangeTblRef that has been identified as a FUNCTION RTE by + * pull_up_subqueries. If its expression is just a Const, hoist that value + * up into the parent query, and replace the RTE_FUNCTION with RTE_RESULT. + * + * In principle we could pull up any immutable expression, but we don't. + * That might result in multiple evaluations of the expression, which could + * be costly if it's not just a Const. Also, the main value of this is + * to let the constant participate in further const-folding, and of course + * that won't happen for a non-Const. + * + * The pulled-up value might need to be wrapped in a PlaceHolderVar if the + * RTE is below an outer join or is part of an appendrel; the extra + * parameters show whether that's needed. + */ +static Node * +pull_up_constant_function(PlannerInfo *root, Node *jtnode, + RangeTblEntry *rte, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel) +{ + Query *parse = root->parse; + RangeTblFunction *rtf; + TypeFuncClass functypclass; + Oid funcrettype; + TupleDesc tupdesc; + pullup_replace_vars_context rvcontext; + + /* Fail if the RTE has ORDINALITY - we don't implement that here. */ + if (rte->funcordinality) + return jtnode; + + /* Fail if RTE isn't a single, simple Const expr */ + if (list_length(rte->functions) != 1) + return jtnode; + rtf = linitial_node(RangeTblFunction, rte->functions); + if (!IsA(rtf->funcexpr, Const)) + return jtnode; + + /* + * If the function's result is not a scalar, we punt. In principle we + * could break the composite constant value apart into per-column + * constants, but for now it seems not worth the work. + */ + if (rtf->funccolcount != 1) + return jtnode; /* definitely composite */ + + functypclass = get_expr_result_type(rtf->funcexpr, + &funcrettype, + &tupdesc); + if (functypclass != TYPEFUNC_SCALAR) + return jtnode; /* must be a one-column composite type */ + + /* Create context for applying pullup_replace_vars */ + rvcontext.root = root; + rvcontext.targetlist = list_make1(makeTargetEntry((Expr *) rtf->funcexpr, + 1, /* resno */ + NULL, /* resname */ + false)); /* resjunk */ + rvcontext.target_rte = rte; + + /* + * Since this function was reduced to a Const, it doesn't contain any + * lateral references, even if it's marked as LATERAL. This means we + * don't need to fill relids. + */ + rvcontext.relids = NULL; + + rvcontext.outer_hasSubLinks = &parse->hasSubLinks; + rvcontext.varno = ((RangeTblRef *) jtnode)->rtindex; + /* these flags will be set below, if needed */ + rvcontext.need_phvs = false; + rvcontext.wrap_non_vars = false; + /* initialize cache array with indexes 0 .. length(tlist) */ + rvcontext.rv_cache = palloc0((list_length(rvcontext.targetlist) + 1) * + sizeof(Node *)); + + /* + * If we are under an outer join then non-nullable items and lateral + * references may have to be turned into PlaceHolderVars. + */ + if (lowest_nulling_outer_join != NULL) + rvcontext.need_phvs = true; + + /* + * If we are dealing with an appendrel member then anything that's not a + * simple Var has to be turned into a PlaceHolderVar. (See comments in + * pull_up_simple_subquery().) + */ + if (containing_appendrel != NULL) + { + rvcontext.need_phvs = true; + rvcontext.wrap_non_vars = true; + } + + /* + * If the parent query uses grouping sets, we need a PlaceHolderVar for + * anything that's not a simple Var. + */ + if (parse->groupingSets) + { + rvcontext.need_phvs = true; + rvcontext.wrap_non_vars = true; + } + + /* + * Replace all of the top query's references to the RTE's output with + * copies of the funcexpr, being careful not to replace any of the + * jointree structure. + */ + perform_pullup_replace_vars(root, &rvcontext, + lowest_nulling_outer_join, + containing_appendrel); + + /* + * We don't need to bother with changing PlaceHolderVars in the parent + * query. Their references to the RT index are still good for now, and + * will get removed later if we're able to drop the RTE_RESULT. + */ + + /* + * Convert the RTE to be RTE_RESULT type, signifying that we don't need to + * scan it anymore, and zero out RTE_FUNCTION-specific fields. + */ + rte->rtekind = RTE_RESULT; + rte->functions = NIL; + + /* + * We can reuse the RangeTblRef node. + */ + return jtnode; +} + /* * is_simple_union_all * Check a subquery to see if it's a simple UNION ALL. @@ -1847,7 +1878,9 @@ is_safe_append_member(Query *subquery) /* * It's only safe to pull up the child if its jointree contains exactly * one RTE, else the AppendRelInfo data structure breaks. The one base RTE - * could be buried in several levels of FromExpr, however. + * could be buried in several levels of FromExpr, however. Also, if the + * child's jointree is completely empty, we can pull up because + * pull_up_simple_subquery will insert a single RTE_RESULT RTE instead. * * Also, the child can't have any WHERE quals because there's no place to * put them in an appendrel. (This is a bit annoying...) If we didn't @@ -1856,6 +1889,11 @@ is_safe_append_member(Query *subquery) * fix_append_rel_relids(). */ jtnode = subquery->jointree; + Assert(IsA(jtnode, FromExpr)); + /* Check the completely-empty case */ + if (jtnode->fromlist == NIL && jtnode->quals == NULL) + return true; + /* Check the more general case */ while (IsA(jtnode, FromExpr)) { if (jtnode->quals != NULL) @@ -1945,9 +1983,97 @@ jointree_contains_lateral_outer_refs(Node *jtnode, bool restricted, } /* - * Helper routine for pull_up_subqueries: do pullup_replace_vars on every - * expression in the jointree, without changing the jointree structure itself. - * Ugly, but there's no other way... + * Perform pullup_replace_vars everyplace it's needed in the query tree. + * + * Caller has already filled *rvcontext with data describing what to + * substitute for Vars referencing the target subquery. In addition + * we need the identity of the lowest outer join that can null the + * target subquery, and its containing appendrel if any. + */ +static void +perform_pullup_replace_vars(PlannerInfo *root, + pullup_replace_vars_context *rvcontext, + JoinExpr *lowest_nulling_outer_join, + AppendRelInfo *containing_appendrel) +{ + Query *parse = root->parse; + ListCell *lc; + + /* + * Replace all of the top query's references to the subquery's outputs + * with copies of the adjusted subtlist items, being careful not to + * replace any of the jointree structure. (This'd be a lot cleaner if we + * could use query_tree_mutator.) We have to use PHVs in the targetList, + * returningList, and havingQual, since those are certainly above any + * outer join. replace_vars_in_jointree tracks its location in the + * jointree and uses PHVs or not appropriately. + */ + parse->targetList = (List *) + pullup_replace_vars((Node *) parse->targetList, rvcontext); + parse->returningList = (List *) + pullup_replace_vars((Node *) parse->returningList, rvcontext); + if (parse->onConflict) + { + parse->onConflict->onConflictSet = (List *) + pullup_replace_vars((Node *) parse->onConflict->onConflictSet, + rvcontext); + parse->onConflict->onConflictWhere = + pullup_replace_vars(parse->onConflict->onConflictWhere, + rvcontext); + + /* + * We assume ON CONFLICT's arbiterElems, arbiterWhere, exclRelTlist + * can't contain any references to a subquery. + */ + } + replace_vars_in_jointree((Node *) parse->jointree, rvcontext, + lowest_nulling_outer_join); + Assert(parse->setOperations == NULL); + parse->havingQual = pullup_replace_vars(parse->havingQual, rvcontext); + + /* + * Replace references in the translated_vars lists of appendrels. When + * pulling up an appendrel member, we do not need PHVs in the list of the + * parent appendrel --- there isn't any outer join between. Elsewhere, + * use PHVs for safety. (This analysis could be made tighter but it seems + * unlikely to be worth much trouble.) + */ + foreach(lc, root->append_rel_list) + { + AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc); + bool save_need_phvs = rvcontext->need_phvs; + + if (appinfo == containing_appendrel) + rvcontext->need_phvs = false; + appinfo->translated_vars = (List *) + pullup_replace_vars((Node *) appinfo->translated_vars, rvcontext); + rvcontext->need_phvs = save_need_phvs; + } + + /* + * Replace references in the joinaliasvars lists of join RTEs. + * + * You might think that we could avoid using PHVs for alias vars of joins + * below lowest_nulling_outer_join, but that doesn't work because the + * alias vars could be referenced above that join; we need the PHVs to be + * present in such references after the alias vars get flattened. (It + * might be worth trying to be smarter here, someday.) + */ + foreach(lc, parse->rtable) + { + RangeTblEntry *otherrte = (RangeTblEntry *) lfirst(lc); + + if (otherrte->rtekind == RTE_JOIN) + otherrte->joinaliasvars = (List *) + pullup_replace_vars((Node *) otherrte->joinaliasvars, + rvcontext); + } +} + +/* + * Helper routine for perform_pullup_replace_vars: do pullup_replace_vars on + * every expression in the jointree, without changing the jointree structure + * itself. Ugly, but there's no other way... * * If we are at or below lowest_nulling_outer_join, we can suppress use of * PlaceHolderVars wrapped around the replacement expressions. @@ -2011,6 +2137,7 @@ replace_vars_in_jointree(Node *jtnode, case RTE_JOIN: case RTE_CTE: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* these shouldn't be marked LATERAL */ Assert(false); break; @@ -2041,6 +2168,18 @@ replace_vars_in_jointree(Node *jtnode, } replace_vars_in_jointree(j->larg, context, lowest_nulling_outer_join); replace_vars_in_jointree(j->rarg, context, lowest_nulling_outer_join); + + /* + * Use PHVs within the join quals of a full join, even when it's the + * lowest nulling outer join. Otherwise, we cannot identify which + * side of the join a pulled-up var-free expression came from, which + * can lead to failure to make a plan at all because none of the quals + * appear to be mergeable or hashable conditions. For this purpose we + * don't care about the state of wrap_non_vars, so leave it alone. + */ + if (j->jointype == JOIN_FULL) + context->need_phvs = true; + j->quals = pullup_replace_vars(j->quals, context); /* @@ -2275,65 +2414,6 @@ pullup_replace_vars_subquery(Query *query, NULL); } -/* - * pull_up_subqueries_cleanup - * Recursively fix up jointree after deletion of some subqueries. - * - * The jointree now contains some NULL subtrees, which we need to get rid of. - * In a FromExpr, just rebuild the child-node list with null entries deleted. - * In an inner JOIN, replace the JoinExpr node with a one-child FromExpr. - */ -static Node * -pull_up_subqueries_cleanup(Node *jtnode) -{ - Assert(jtnode != NULL); - if (IsA(jtnode, RangeTblRef)) - { - /* Nothing to do at leaf nodes. */ - } - else if (IsA(jtnode, FromExpr)) - { - FromExpr *f = (FromExpr *) jtnode; - List *newfrom = NIL; - ListCell *l; - - foreach(l, f->fromlist) - { - Node *child = (Node *) lfirst(l); - - if (child == NULL) - continue; - child = pull_up_subqueries_cleanup(child); - newfrom = lappend(newfrom, child); - } - f->fromlist = newfrom; - } - else if (IsA(jtnode, JoinExpr)) - { - JoinExpr *j = (JoinExpr *) jtnode; - - if (j->larg) - j->larg = pull_up_subqueries_cleanup(j->larg); - if (j->rarg) - j->rarg = pull_up_subqueries_cleanup(j->rarg); - if (j->larg == NULL) - { - Assert(j->jointype == JOIN_INNER); - Assert(j->rarg != NULL); - return (Node *) makeFromExpr(list_make1(j->rarg), j->quals); - } - else if (j->rarg == NULL) - { - Assert(j->jointype == JOIN_INNER); - return (Node *) makeFromExpr(list_make1(j->larg), j->quals); - } - } - else - elog(ERROR, "unrecognized node type: %d", - (int) nodeTag(jtnode)); - return jtnode; -} - /* * flatten_simple_union_all @@ -2597,7 +2677,6 @@ reduce_outer_joins_pass2(Node *jtnode, pass_nonnullable_rels = find_nonnullable_rels(f->quals); pass_nonnullable_rels = bms_add_members(pass_nonnullable_rels, nonnullable_rels); - /* NB: we rely on list_concat to not damage its second argument */ pass_nonnullable_vars = find_nonnullable_vars(f->quals); pass_nonnullable_vars = list_concat(pass_nonnullable_vars, nonnullable_vars); @@ -2843,9 +2922,387 @@ reduce_outer_joins_pass2(Node *jtnode, (int) nodeTag(jtnode)); } + +/* + * remove_useless_result_rtes + * Attempt to remove RTE_RESULT RTEs from the join tree. + * + * We can remove RTE_RESULT entries from the join tree using the knowledge + * that RTE_RESULT returns exactly one row and has no output columns. Hence, + * if one is inner-joined to anything else, we can delete it. Optimizations + * are also possible for some outer-join cases, as detailed below. + * + * Some of these optimizations depend on recognizing empty (constant-true) + * quals for FromExprs and JoinExprs. That makes it useful to apply this + * optimization pass after expression preprocessing, since that will have + * eliminated constant-true quals, allowing more cases to be recognized as + * optimizable. What's more, the usual reason for an RTE_RESULT to be present + * is that we pulled up a subquery or VALUES clause, thus very possibly + * replacing Vars with constants, making it more likely that a qual can be + * reduced to constant true. Also, because some optimizations depend on + * the outer-join type, it's best to have done reduce_outer_joins() first. + * + * A PlaceHolderVar referencing an RTE_RESULT RTE poses an obstacle to this + * process: we must remove the RTE_RESULT's relid from the PHV's phrels, but + * we must not reduce the phrels set to empty. If that would happen, and + * the RTE_RESULT is an immediate child of an outer join, we have to give up + * and not remove the RTE_RESULT: there is noplace else to evaluate the + * PlaceHolderVar. (That is, in such cases the RTE_RESULT *does* have output + * columns.) But if the RTE_RESULT is an immediate child of an inner join, + * we can change the PlaceHolderVar's phrels so as to evaluate it at the + * inner join instead. This is OK because we really only care that PHVs are + * evaluated above or below the correct outer joins. + * + * We used to try to do this work as part of pull_up_subqueries() where the + * potentially-optimizable cases get introduced; but it's way simpler, and + * more effective, to do it separately. + */ +void +remove_useless_result_rtes(PlannerInfo *root) +{ + ListCell *cell; + + /* Top level of jointree must always be a FromExpr */ + Assert(IsA(root->parse->jointree, FromExpr)); + /* Recurse ... */ + root->parse->jointree = (FromExpr *) + remove_useless_results_recurse(root, (Node *) root->parse->jointree); + /* We should still have a FromExpr */ + Assert(IsA(root->parse->jointree, FromExpr)); + + /* + * Remove any PlanRowMark referencing an RTE_RESULT RTE. We obviously + * must do that for any RTE_RESULT that we just removed. But one for a + * RTE that we did not remove can be dropped anyway: since the RTE has + * only one possible output row, there is no need for EPQ to mark and + * restore that row. + * + * It's necessary, not optional, to remove the PlanRowMark for a surviving + * RTE_RESULT RTE; otherwise we'll generate a whole-row Var for the + * RTE_RESULT, which the executor has no support for. + */ + foreach(cell, root->rowMarks) + { + PlanRowMark *rc = (PlanRowMark *) lfirst(cell); + + if (rt_fetch(rc->rti, root->parse->rtable)->rtekind == RTE_RESULT) + root->rowMarks = foreach_delete_current(root->rowMarks, cell); + } +} + +/* + * remove_useless_results_recurse + * Recursive guts of remove_useless_result_rtes. + * + * This recursively processes the jointree and returns a modified jointree. + */ +static Node * +remove_useless_results_recurse(PlannerInfo *root, Node *jtnode) +{ + Assert(jtnode != NULL); + if (IsA(jtnode, RangeTblRef)) + { + /* Can't immediately do anything with a RangeTblRef */ + } + else if (IsA(jtnode, FromExpr)) + { + FromExpr *f = (FromExpr *) jtnode; + Relids result_relids = NULL; + ListCell *cell; + + /* + * We can drop RTE_RESULT rels from the fromlist so long as at least + * one child remains, since joining to a one-row table changes + * nothing. The easiest way to mechanize this rule is to modify the + * list in-place. + */ + foreach(cell, f->fromlist) + { + Node *child = (Node *) lfirst(cell); + int varno; + + /* Recursively transform child ... */ + child = remove_useless_results_recurse(root, child); + /* ... and stick it back into the tree */ + lfirst(cell) = child; + + /* + * If it's an RTE_RESULT with at least one sibling, we can drop + * it. We don't yet know what the inner join's final relid set + * will be, so postpone cleanup of PHVs etc till after this loop. + */ + if (list_length(f->fromlist) > 1 && + (varno = get_result_relid(root, child)) != 0) + { + f->fromlist = foreach_delete_current(f->fromlist, cell); + result_relids = bms_add_member(result_relids, varno); + } + } + + /* + * Clean up if we dropped any RTE_RESULT RTEs. This is a bit + * inefficient if there's more than one, but it seems better to + * optimize the support code for the single-relid case. + */ + if (result_relids) + { + int varno = -1; + + while ((varno = bms_next_member(result_relids, varno)) >= 0) + remove_result_refs(root, varno, (Node *) f); + } + + /* + * If we're not at the top of the jointree, it's valid to simplify a + * degenerate FromExpr into its single child. (At the top, we must + * keep the FromExpr since Query.jointree is required to point to a + * FromExpr.) + */ + if (f != root->parse->jointree && + f->quals == NULL && + list_length(f->fromlist) == 1) + return (Node *) linitial(f->fromlist); + } + else if (IsA(jtnode, JoinExpr)) + { + JoinExpr *j = (JoinExpr *) jtnode; + int varno; + + /* First, recurse */ + j->larg = remove_useless_results_recurse(root, j->larg); + j->rarg = remove_useless_results_recurse(root, j->rarg); + + /* Apply join-type-specific optimization rules */ + switch (j->jointype) + { + case JOIN_INNER: + + /* + * An inner join is equivalent to a FromExpr, so if either + * side was simplified to an RTE_RESULT rel, we can replace + * the join with a FromExpr with just the other side; and if + * the qual is empty (JOIN ON TRUE) then we can omit the + * FromExpr as well. + */ + if ((varno = get_result_relid(root, j->larg)) != 0) + { + remove_result_refs(root, varno, j->rarg); + if (j->quals) + jtnode = (Node *) + makeFromExpr(list_make1(j->rarg), j->quals); + else + jtnode = j->rarg; + } + else if ((varno = get_result_relid(root, j->rarg)) != 0) + { + remove_result_refs(root, varno, j->larg); + if (j->quals) + jtnode = (Node *) + makeFromExpr(list_make1(j->larg), j->quals); + else + jtnode = j->larg; + } + break; + case JOIN_LEFT: + + /* + * We can simplify this case if the RHS is an RTE_RESULT, with + * two different possibilities: + * + * If the qual is empty (JOIN ON TRUE), then the join can be + * strength-reduced to a plain inner join, since each LHS row + * necessarily has exactly one join partner. So we can always + * discard the RHS, much as in the JOIN_INNER case above. + * + * Otherwise, it's still true that each LHS row should be + * returned exactly once, and since the RHS returns no columns + * (unless there are PHVs that have to be evaluated there), we + * don't much care if it's null-extended or not. So in this + * case also, we can just ignore the qual and discard the left + * join. + */ + if ((varno = get_result_relid(root, j->rarg)) != 0 && + (j->quals == NULL || + !find_dependent_phvs((Node *) root->parse, varno))) + { + remove_result_refs(root, varno, j->larg); + jtnode = j->larg; + } + break; + case JOIN_RIGHT: + /* Mirror-image of the JOIN_LEFT case */ + if ((varno = get_result_relid(root, j->larg)) != 0 && + (j->quals == NULL || + !find_dependent_phvs((Node *) root->parse, varno))) + { + remove_result_refs(root, varno, j->rarg); + jtnode = j->rarg; + } + break; + case JOIN_SEMI: + + /* + * We may simplify this case if the RHS is an RTE_RESULT; the + * join qual becomes effectively just a filter qual for the + * LHS, since we should either return the LHS row or not. For + * simplicity we inject the filter qual into a new FromExpr. + * + * Unlike the LEFT/RIGHT cases, we just Assert that there are + * no PHVs that need to be evaluated at the semijoin's RHS, + * since the rest of the query couldn't reference any outputs + * of the semijoin's RHS. + */ + if ((varno = get_result_relid(root, j->rarg)) != 0) + { + Assert(!find_dependent_phvs((Node *) root->parse, varno)); + remove_result_refs(root, varno, j->larg); + if (j->quals) + jtnode = (Node *) + makeFromExpr(list_make1(j->larg), j->quals); + else + jtnode = j->larg; + } + break; + case JOIN_FULL: + case JOIN_ANTI: + /* We have no special smarts for these cases */ + break; + default: + elog(ERROR, "unrecognized join type: %d", + (int) j->jointype); + break; + } + } + else + elog(ERROR, "unrecognized node type: %d", + (int) nodeTag(jtnode)); + return jtnode; +} + +/* + * get_result_relid + * If jtnode is a RangeTblRef for an RTE_RESULT RTE, return its relid; + * otherwise return 0. + */ +static int +get_result_relid(PlannerInfo *root, Node *jtnode) +{ + int varno; + + if (!IsA(jtnode, RangeTblRef)) + return 0; + varno = ((RangeTblRef *) jtnode)->rtindex; + if (rt_fetch(varno, root->parse->rtable)->rtekind != RTE_RESULT) + return 0; + return varno; +} + +/* + * remove_result_refs + * Helper routine for dropping an unneeded RTE_RESULT RTE. + * + * This doesn't physically remove the RTE from the jointree, because that's + * more easily handled in remove_useless_results_recurse. What it does do + * is the necessary cleanup in the rest of the tree: we must adjust any PHVs + * that may reference the RTE. Be sure to call this at a point where the + * jointree is valid (no disconnected nodes). + * + * Note that we don't need to process the append_rel_list, since RTEs + * referenced directly in the jointree won't be appendrel members. + * + * varno is the RTE_RESULT's relid. + * newjtloc is the jointree location at which any PHVs referencing the + * RTE_RESULT should be evaluated instead. + */ +static void +remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) +{ + /* Fix up PlaceHolderVars as needed */ + /* If there are no PHVs anywhere, we can skip this bit */ + if (root->glob->lastPHId != 0) + { + Relids subrelids; + + subrelids = get_relids_in_jointree(newjtloc, false); + Assert(!bms_is_empty(subrelids)); + substitute_phv_relids((Node *) root->parse, varno, subrelids); + } + + /* + * We also need to remove any PlanRowMark referencing the RTE, but we + * postpone that work until we return to remove_useless_result_rtes. + */ +} + + +/* + * find_dependent_phvs - are there any PlaceHolderVars whose relids are + * exactly the given varno? + */ + +typedef struct +{ + Relids relids; + int sublevels_up; +} find_dependent_phvs_context; + +static bool +find_dependent_phvs_walker(Node *node, + find_dependent_phvs_context *context) +{ + if (node == NULL) + return false; + if (IsA(node, PlaceHolderVar)) + { + PlaceHolderVar *phv = (PlaceHolderVar *) node; + + if (phv->phlevelsup == context->sublevels_up && + bms_equal(context->relids, phv->phrels)) + return true; + /* fall through to examine children */ + } + if (IsA(node, Query)) + { + /* Recurse into subselects */ + bool result; + + context->sublevels_up++; + result = query_tree_walker((Query *) node, + find_dependent_phvs_walker, + (void *) context, 0); + context->sublevels_up--; + return result; + } + /* Shouldn't need to handle planner auxiliary nodes here */ + Assert(!IsA(node, SpecialJoinInfo)); + Assert(!IsA(node, AppendRelInfo)); + Assert(!IsA(node, PlaceHolderInfo)); + Assert(!IsA(node, MinMaxAggInfo)); + + return expression_tree_walker(node, find_dependent_phvs_walker, + (void *) context); +} + +static bool +find_dependent_phvs(Node *node, int varno) +{ + find_dependent_phvs_context context; + + context.relids = bms_make_singleton(varno); + context.sublevels_up = 0; + + /* + * Must be prepared to start with a Query or a bare expression tree. + */ + return query_or_expression_tree_walker(node, + find_dependent_phvs_walker, + (void *) &context, + 0); +} + /* - * substitute_multiple_relids - adjust node relid sets after pulling up - * a subquery + * substitute_phv_relids - adjust PlaceHolderVar relid sets after pulling up + * a subquery or removing an RTE_RESULT jointree item * * Find any PlaceHolderVar nodes in the given tree that reference the * pulled-up relid, and change them to reference the replacement relid(s). @@ -2861,11 +3318,11 @@ typedef struct int varno; int sublevels_up; Relids subrelids; -} substitute_multiple_relids_context; +} substitute_phv_relids_context; static bool -substitute_multiple_relids_walker(Node *node, - substitute_multiple_relids_context *context) +substitute_phv_relids_walker(Node *node, + substitute_phv_relids_context *context) { if (node == NULL) return false; @@ -2880,6 +3337,8 @@ substitute_multiple_relids_walker(Node *node, context->subrelids); phv->phrels = bms_del_member(phv->phrels, context->varno); + /* Assert we haven't broken the PHV */ + Assert(!bms_is_empty(phv->phrels)); } /* fall through to examine children */ } @@ -2890,7 +3349,7 @@ substitute_multiple_relids_walker(Node *node, context->sublevels_up++; result = query_tree_walker((Query *) node, - substitute_multiple_relids_walker, + substitute_phv_relids_walker, (void *) context, 0); context->sublevels_up--; return result; @@ -2901,14 +3360,14 @@ substitute_multiple_relids_walker(Node *node, Assert(!IsA(node, PlaceHolderInfo)); Assert(!IsA(node, MinMaxAggInfo)); - return expression_tree_walker(node, substitute_multiple_relids_walker, + return expression_tree_walker(node, substitute_phv_relids_walker, (void *) context); } static void -substitute_multiple_relids(Node *node, int varno, Relids subrelids) +substitute_phv_relids(Node *node, int varno, Relids subrelids) { - substitute_multiple_relids_context context; + substitute_phv_relids_context context; context.varno = varno; context.sublevels_up = 0; @@ -2918,7 +3377,7 @@ substitute_multiple_relids(Node *node, int varno, Relids subrelids) * Must be prepared to start with a Query or a bare expression tree. */ query_or_expression_tree_walker(node, - substitute_multiple_relids_walker, + substitute_phv_relids_walker, (void *) &context, 0); } @@ -2928,7 +3387,7 @@ substitute_multiple_relids(Node *node, int varno, Relids subrelids) * * When we pull up a subquery, any AppendRelInfo references to the subquery's * RT index have to be replaced by the substituted relid (and there had better - * be only one). We also need to apply substitute_multiple_relids to their + * be only one). We also need to apply substitute_phv_relids to their * translated_vars lists, since those might contain PlaceHolderVars. * * We assume we may modify the AppendRelInfo nodes in-place. @@ -2959,9 +3418,9 @@ fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids) appinfo->child_relid = subvarno; } - /* Also finish fixups for its translated vars */ - substitute_multiple_relids((Node *) appinfo->translated_vars, - varno, subrelids); + /* Also fix up any PHVs in its translated vars */ + substitute_phv_relids((Node *) appinfo->translated_vars, + varno, subrelids); } } @@ -3016,11 +3475,11 @@ get_relids_in_jointree(Node *jtnode, bool include_joins) * get_relids_for_join: get set of base RT indexes making up a join */ Relids -get_relids_for_join(PlannerInfo *root, int joinrelid) +get_relids_for_join(Query *query, int joinrelid) { Node *jtnode; - jtnode = find_jointree_node_for_rel((Node *) root->parse->jointree, + jtnode = find_jointree_node_for_rel((Node *) query->jointree, joinrelid); if (!jtnode) elog(ERROR, "could not find join node %d", joinrelid); diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c index 52f8893f4f0..ee919575c52 100644 --- a/src/backend/optimizer/prep/prepqual.c +++ b/src/backend/optimizer/prep/prepqual.c @@ -19,7 +19,7 @@ * tree after local transformations that might introduce nested AND/ORs. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,7 +32,8 @@ #include "postgres.h" #include "nodes/makefuncs.h" -#include "optimizer/clauses.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" #include "optimizer/prep.h" #include "utils/lsyscache.h" @@ -327,13 +328,7 @@ pull_ands(List *andlist) { Node *subexpr = (Node *) lfirst(arg); - /* - * Note: we can destructively concat the subexpression's arglist - * because we know the recursive invocation of pull_ands will have - * built a new arglist not shared with any other expr. Otherwise we'd - * need a list_copy here. - */ - if (and_clause(subexpr)) + if (is_andclause(subexpr)) out_list = list_concat(out_list, pull_ands(((BoolExpr *) subexpr)->args)); else @@ -359,13 +354,7 @@ pull_ors(List *orlist) { Node *subexpr = (Node *) lfirst(arg); - /* - * Note: we can destructively concat the subexpression's arglist - * because we know the recursive invocation of pull_ors will have - * built a new arglist not shared with any other expr. Otherwise we'd - * need a list_copy here. - */ - if (or_clause(subexpr)) + if (is_orclause(subexpr)) out_list = list_concat(out_list, pull_ors(((BoolExpr *) subexpr)->args)); else @@ -415,7 +404,7 @@ pull_ors(List *orlist) static Expr * find_duplicate_ors(Expr *qual, bool is_check) { - if (or_clause((Node *) qual)) + if (is_orclause(qual)) { List *orlist = NIL; ListCell *temp; @@ -459,7 +448,7 @@ find_duplicate_ors(Expr *qual, bool is_check) /* Now we can look for duplicate ORs */ return process_duplicate_ors(orlist); } - else if (and_clause((Node *) qual)) + else if (is_andclause(qual)) { List *andlist = NIL; ListCell *temp; @@ -550,7 +539,7 @@ process_duplicate_ors(List *orlist) { Expr *clause = (Expr *) lfirst(temp); - if (and_clause((Node *) clause)) + if (is_andclause(clause)) { List *subclauses = ((BoolExpr *) clause)->args; int nclauses = list_length(subclauses); @@ -588,7 +577,7 @@ process_duplicate_ors(List *orlist) { Expr *clause = (Expr *) lfirst(temp2); - if (and_clause((Node *) clause)) + if (is_andclause(clause)) { if (!list_member(((BoolExpr *) clause)->args, refclause)) { @@ -631,7 +620,7 @@ process_duplicate_ors(List *orlist) { Expr *clause = (Expr *) lfirst(temp); - if (and_clause((Node *) clause)) + if (is_andclause(clause)) { List *subclauses = ((BoolExpr *) clause)->args; diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index 8a87cfd14ae..792ae393d97 100644 --- a/src/backend/optimizer/prep/preptlist.c +++ b/src/backend/optimizer/prep/preptlist.c @@ -29,7 +29,7 @@ * that because it's faster in typical non-inherited cases. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -40,13 +40,13 @@ #include "postgres.h" -#include "access/heapam.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/pg_type.h" #include "nodes/makefuncs.h" +#include "optimizer/optimizer.h" #include "optimizer/prep.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parsetree.h" #include "parser/parse_coerce.h" #include "rewrite/rewriteHandler.h" @@ -54,7 +54,7 @@ static List *expand_targetlist(List *tlist, int command_type, - Index result_relation, Relation rel); + Index result_relation, Relation rel); /* @@ -94,7 +94,7 @@ preprocess_targetlist(PlannerInfo *root) if (target_rte->rtekind != RTE_RELATION) elog(ERROR, "result relation must be a regular relation"); - target_relation = heap_open(target_rte->relid, NoLock); + target_relation = table_open(target_rte->relid, NoLock); } else Assert(command_type == CMD_SELECT); @@ -118,50 +118,12 @@ preprocess_targetlist(PlannerInfo *root) tlist = expand_targetlist(tlist, command_type, result_relation, target_relation); - if (command_type == CMD_MERGE) - { - ListCell *l; - - /* - * For MERGE, add any junk column(s) needed to allow the executor to - * identify the rows to be updated or deleted, with different - * handling for partitioned tables. - */ - rewriteTargetListMerge(parse, target_relation); - - /* - * For MERGE command, handle targetlist of each MergeAction separately. - * Give the same treatment to MergeAction->targetList as we would have - * given to a regular INSERT/UPDATE/DELETE. - */ - foreach(l, parse->mergeActionList) - { - MergeAction *action = (MergeAction *) lfirst(l); - - switch (action->commandType) - { - case CMD_INSERT: - case CMD_UPDATE: - action->targetList = expand_targetlist(action->targetList, - action->commandType, - result_relation, - target_relation); - break; - case CMD_DELETE: - break; - case CMD_NOTHING: - break; - default: - elog(ERROR, "unknown action in MERGE WHEN clause"); - - } - } - } - /* * Add necessary junk columns for rowmarked rels. These values are needed * for locking of rels selected FOR UPDATE/SHARE, and to do EvalPlanQual - * rechecking. See comments for PlanRowMark in plannodes.h. + * rechecking. See comments for PlanRowMark in plannodes.h. If you + * change this stanza, see also expand_inherited_rtentry(), which has to + * be able to add on junk columns equivalent to these. */ foreach(lc, root->rowMarks) { @@ -273,7 +235,7 @@ preprocess_targetlist(PlannerInfo *root) target_relation); if (target_relation) - heap_close(target_relation, NoLock); + table_close(target_relation, NoLock); return tlist; } @@ -323,7 +285,7 @@ expand_targetlist(List *tlist, int command_type, if (!old_tle->resjunk && old_tle->resno == attrno) { new_tle = old_tle; - tlist_item = lnext(tlist_item); + tlist_item = lnext(tlist, tlist_item); } } @@ -388,7 +350,6 @@ expand_targetlist(List *tlist, int command_type, true /* byval */ ); } break; - case CMD_MERGE: case CMD_UPDATE: if (!att_tup->attisdropped) { @@ -449,7 +410,7 @@ expand_targetlist(List *tlist, int command_type, } new_tlist = lappend(new_tlist, old_tle); attrno++; - tlist_item = lnext(tlist_item); + tlist_item = lnext(tlist, tlist_item); } return new_tlist; diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 8d86e98adc1..b01c9bbae7d 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -12,12 +12,7 @@ * case, but most of the heavy lifting for that is done elsewhere, * notably in prepjointree.c and allpaths.c. * - * There is also some code here to support planning of queries that use - * inheritance (SELECT FROM foo*). Inheritance trees are converted into - * append relations, and thenceforth share code with the UNION ALL case. - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,9 +23,6 @@ */ #include "postgres.h" -#include - -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" #include "catalog/partition.h" @@ -51,78 +43,47 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/selfuncs.h" +#include "utils/syscache.h" -typedef struct -{ - PlannerInfo *root; - int nappinfos; - AppendRelInfo **appinfos; -} adjust_appendrel_attrs_context; - static RelOptInfo *recurse_set_operations(Node *setOp, PlannerInfo *root, - List *colTypes, List *colCollations, - bool junkOK, - int flag, List *refnames_tlist, - List **pTargetList, - double *pNumGroups); + List *colTypes, List *colCollations, + bool junkOK, + int flag, List *refnames_tlist, + List **pTargetList, + double *pNumGroups); static RelOptInfo *generate_recursion_path(SetOperationStmt *setOp, - PlannerInfo *root, - List *refnames_tlist, - List **pTargetList); + PlannerInfo *root, + List *refnames_tlist, + List **pTargetList); static RelOptInfo *generate_union_paths(SetOperationStmt *op, PlannerInfo *root, - List *refnames_tlist, - List **pTargetList); + List *refnames_tlist, + List **pTargetList); static RelOptInfo *generate_nonunion_paths(SetOperationStmt *op, PlannerInfo *root, - List *refnames_tlist, - List **pTargetList); + List *refnames_tlist, + List **pTargetList); static List *plan_union_children(PlannerInfo *root, - SetOperationStmt *top_union, - List *refnames_tlist, - List **tlist_list); + SetOperationStmt *top_union, + List *refnames_tlist, + List **tlist_list); static Path *make_union_unique(SetOperationStmt *op, Path *path, List *tlist, - PlannerInfo *root); + PlannerInfo *root); static void postprocess_setop_rel(PlannerInfo *root, RelOptInfo *rel); static bool choose_hashed_setop(PlannerInfo *root, List *groupClauses, - Path *input_path, - double dNumGroups, double dNumOutputRows, - const char *construct); + Path *input_path, + double dNumGroups, double dNumOutputRows, + const char *construct); static List *generate_setop_tlist(List *colTypes, List *colCollations, - int flag, - Index varno, - bool hack_constants, - List *input_tlist, - List *refnames_tlist); + int flag, + Index varno, + bool hack_constants, + List *input_tlist, + List *refnames_tlist); static List *generate_append_tlist(List *colTypes, List *colCollations, - bool flag, - List *input_tlists, - List *refnames_tlist); + bool flag, + List *input_tlists, + List *refnames_tlist); static List *generate_setop_grouplist(SetOperationStmt *op, List *targetlist); -static void expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, - Index rti); -static void expand_partitioned_rtentry(PlannerInfo *root, - RangeTblEntry *parentrte, - Index parentRTindex, Relation parentrel, - PlanRowMark *top_parentrc, LOCKMODE lockmode, - List **appinfos); -static void expand_single_inheritance_child(PlannerInfo *root, - RangeTblEntry *parentrte, - Index parentRTindex, Relation parentrel, - PlanRowMark *top_parentrc, Relation childrel, - List **appinfos, RangeTblEntry **childrte_p, - Index *childRTindex_p); -static void make_inh_translation_list(Relation oldrelation, - Relation newrelation, - Index newvarno, - List **translated_vars); -static Bitmapset *translate_col_privs(const Bitmapset *parent_privs, - List *translated_vars); -static Node *adjust_appendrel_attrs_mutator(Node *node, - adjust_appendrel_attrs_context *context); -static Relids adjust_child_relids(Relids relids, int nappinfos, - AppendRelInfo **appinfos); -static List *adjust_inherited_tlist(List *tlist, - AppendRelInfo *context); /* @@ -159,10 +120,19 @@ plan_set_operations(PlannerInfo *root) Assert(parse->windowClause == NIL); Assert(parse->distinctClause == NIL); + /* + * In the outer query level, we won't have any true equivalences to deal + * with; but we do want to be able to make pathkeys, which will require + * single-member EquivalenceClasses. Indicate that EC merging is complete + * so that pathkeys.c won't complain. + */ + Assert(root->eq_classes == NIL); + root->ec_merging_done = true; + /* * We'll need to build RelOptInfos for each of the leaf subqueries, which * are RTE_SUBQUERY rangetable entries in this Query. Prepare the index - * arrays for that. + * arrays for those, and for AppendRelInfos in case they're needed. */ setup_simple_rel_arrays(root); @@ -330,7 +300,8 @@ recurse_set_operations(Node *setOp, PlannerInfo *root, * to build a partial path for this relation. But there's no point in * considering any path but the cheapest. */ - if (final_rel->partial_pathlist != NIL) + if (rel->consider_parallel && bms_is_empty(rel->lateral_relids) && + final_rel->partial_pathlist != NIL) { Path *partial_subpath; Path *partial_path; @@ -394,8 +365,8 @@ recurse_set_operations(Node *setOp, PlannerInfo *root, * fix_upper_expr() to the Result node's tlist. This would fail if the * Vars generated by generate_setop_tlist() were not exactly equal() * to the corresponding tlist entries of the subplan. However, since - * the subplan was generated by generate_union_plan() or - * generate_nonunion_plan(), and hence its tlist was generated by + * the subplan was generated by generate_union_paths() or + * generate_nonunion_paths(), and hence its tlist was generated by * generate_append_tlist(), this will work. We just tell * generate_setop_tlist() to use varno 0. */ @@ -649,7 +620,7 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, * Append the child results together. */ path = (Path *) create_append_path(root, result_rel, pathlist, NIL, - NULL, 0, false, NIL, -1); + NIL, NULL, 0, false, NIL, -1); /* * For UNION ALL, we just need the Append path. For UNION, need to add @@ -704,7 +675,8 @@ generate_union_paths(SetOperationStmt *op, PlannerInfo *root, ppath = (Path *) create_append_path(root, result_rel, NIL, partial_pathlist, - NULL, parallel_workers, enable_parallel_append, + NIL, NULL, + parallel_workers, enable_parallel_append, NIL, -1); ppath = (Path *) create_gather_path(root, result_rel, ppath, @@ -809,13 +781,13 @@ generate_nonunion_paths(SetOperationStmt *op, PlannerInfo *root, /* Build result relation. */ result_rel = fetch_upper_rel(root, UPPERREL_SETOP, bms_union(lrel->relids, rrel->relids)); - result_rel->reltarget = create_pathtarget(root, tlist);; + result_rel->reltarget = create_pathtarget(root, tlist); /* * Append the child results together. */ path = (Path *) create_append_path(root, result_rel, pathlist, NIL, - NULL, 0, false, NIL, -1); + NIL, NULL, 0, false, NIL, -1); /* Identify the grouping semantics */ groupList = generate_setop_grouplist(op, tlist); @@ -1162,17 +1134,14 @@ generate_setop_tlist(List *colTypes, List *colCollations, TargetEntry *tle; Node *expr; - /* there's no forfour() so we must chase one list manually */ - rtlc = list_head(refnames_tlist); - forthree(ctlc, colTypes, cclc, colCollations, itlc, input_tlist) + forfour(ctlc, colTypes, cclc, colCollations, + itlc, input_tlist, rtlc, refnames_tlist) { Oid colType = lfirst_oid(ctlc); Oid colColl = lfirst_oid(cclc); TargetEntry *inputtle = (TargetEntry *) lfirst(itlc); TargetEntry *reftle = (TargetEntry *) lfirst(rtlc); - rtlc = lnext(rtlc); - Assert(inputtle->resno == resno); Assert(reftle->resno == resno); Assert(!inputtle->resjunk); @@ -1344,7 +1313,7 @@ generate_append_tlist(List *colTypes, List *colCollations, /* types disagree, so force typmod to -1 */ colTypmods[colindex] = -1; } - curColType = lnext(curColType); + curColType = lnext(colTypes, curColType); colindex++; } Assert(curColType == NULL); @@ -1444,7 +1413,7 @@ generate_setop_grouplist(SetOperationStmt *op, List *targetlist) /* non-resjunk columns should have grouping clauses */ Assert(lg != NULL); sgc = (SortGroupClause *) lfirst(lg); - lg = lnext(lg); + lg = lnext(grouplist, lg); Assert(sgc->tleSortGroupRef == 0); sgc->tleSortGroupRef = tle->ressortgroupref; @@ -1452,1193 +1421,3 @@ generate_setop_grouplist(SetOperationStmt *op, List *targetlist) Assert(lg == NULL); return grouplist; } - - -/* - * expand_inherited_tables - * Expand each rangetable entry that represents an inheritance set - * into an "append relation". At the conclusion of this process, - * the "inh" flag is set in all and only those RTEs that are append - * relation parents. - */ -void -expand_inherited_tables(PlannerInfo *root) -{ - Index nrtes; - Index rti; - ListCell *rl; - - /* - * expand_inherited_rtentry may add RTEs to parse->rtable. The function is - * expected to recursively handle any RTEs that it creates with inh=true. - * So just scan as far as the original end of the rtable list. - */ - nrtes = list_length(root->parse->rtable); - rl = list_head(root->parse->rtable); - for (rti = 1; rti <= nrtes; rti++) - { - RangeTblEntry *rte = (RangeTblEntry *) lfirst(rl); - - expand_inherited_rtentry(root, rte, rti); - rl = lnext(rl); - } -} - -/* - * expand_inherited_rtentry - * Check whether a rangetable entry represents an inheritance set. - * If so, add entries for all the child tables to the query's - * rangetable, and build AppendRelInfo nodes for all the child tables - * and add them to root->append_rel_list. If not, clear the entry's - * "inh" flag to prevent later code from looking for AppendRelInfos. - * - * Note that the original RTE is considered to represent the whole - * inheritance set. The first of the generated RTEs is an RTE for the same - * table, but with inh = false, to represent the parent table in its role - * as a simple member of the inheritance set. - * - * A childless table is never considered to be an inheritance set. For - * regular inheritance, a parent RTE must always have at least two associated - * AppendRelInfos: one corresponding to the parent table as a simple member of - * inheritance set and one or more corresponding to the actual children. - * Since a partitioned table is not scanned, it might have only one associated - * AppendRelInfo. - */ -static void -expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti) -{ - Query *parse = root->parse; - Oid parentOID; - PlanRowMark *oldrc; - Relation oldrelation; - LOCKMODE lockmode; - List *inhOIDs; - ListCell *l; - - /* Does RT entry allow inheritance? */ - if (!rte->inh) - return; - /* Ignore any already-expanded UNION ALL nodes */ - if (rte->rtekind != RTE_RELATION) - { - Assert(rte->rtekind == RTE_SUBQUERY); - return; - } - /* Fast path for common case of childless table */ - parentOID = rte->relid; - if (!has_subclass(parentOID)) - { - /* Clear flag before returning */ - rte->inh = false; - return; - } - - /* - * The rewriter should already have obtained an appropriate lock on each - * relation named in the query. However, for each child relation we add - * to the query, we must obtain an appropriate lock, because this will be - * the first use of those relations in the parse/rewrite/plan pipeline. - * - * If the parent relation is the query's result relation, then we need - * RowExclusiveLock. Otherwise, if it's accessed FOR UPDATE/SHARE, we - * need RowShareLock; otherwise AccessShareLock. We can't just grab - * AccessShareLock because then the executor would be trying to upgrade - * the lock, leading to possible deadlocks. (This code should match the - * parser and rewriter.) - */ - oldrc = get_plan_rowmark(root->rowMarks, rti); - if (rti == parse->resultRelation) - lockmode = RowExclusiveLock; - else if (oldrc && RowMarkRequiresRowShareLock(oldrc->markType)) - lockmode = RowShareLock; - else - lockmode = AccessShareLock; - - /* Scan for all members of inheritance set, acquire needed locks */ - inhOIDs = find_all_inheritors(parentOID, lockmode, NULL); - - /* - * Check that there's at least one descendant, else treat as no-child - * case. This could happen despite above has_subclass() check, if table - * once had a child but no longer does. - */ - if (list_length(inhOIDs) < 2) - { - /* Clear flag before returning */ - rte->inh = false; - return; - } - - /* - * If parent relation is selected FOR UPDATE/SHARE, we need to mark its - * PlanRowMark as isParent = true, and generate a new PlanRowMark for each - * child. - */ - if (oldrc) - oldrc->isParent = true; - - /* - * Must open the parent relation to examine its tupdesc. We need not lock - * it; we assume the rewriter already did. - */ - oldrelation = heap_open(parentOID, NoLock); - - /* Scan the inheritance set and expand it */ - if (RelationGetPartitionDesc(oldrelation) != NULL) - { - Assert(rte->relkind == RELKIND_PARTITIONED_TABLE); - - /* - * If this table has partitions, recursively expand them in the order - * in which they appear in the PartitionDesc. While at it, also - * extract the partition key columns of all the partitioned tables. - */ - expand_partitioned_rtentry(root, rte, rti, oldrelation, oldrc, - lockmode, &root->append_rel_list); - } - else - { - List *appinfos = NIL; - RangeTblEntry *childrte; - Index childRTindex; - - /* - * This table has no partitions. Expand any plain inheritance - * children in the order the OIDs were returned by - * find_all_inheritors. - */ - foreach(l, inhOIDs) - { - Oid childOID = lfirst_oid(l); - Relation newrelation; - - /* Open rel if needed; we already have required locks */ - if (childOID != parentOID) - newrelation = heap_open(childOID, NoLock); - else - newrelation = oldrelation; - - /* - * It is possible that the parent table has children that are temp - * tables of other backends. We cannot safely access such tables - * (because of buffering issues), and the best thing to do seems - * to be to silently ignore them. - */ - if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation)) - { - heap_close(newrelation, lockmode); - continue; - } - - expand_single_inheritance_child(root, rte, rti, oldrelation, oldrc, - newrelation, - &appinfos, &childrte, - &childRTindex); - - /* Close child relations, but keep locks */ - if (childOID != parentOID) - heap_close(newrelation, NoLock); - } - - /* - * If all the children were temp tables, pretend it's a - * non-inheritance situation; we don't need Append node in that case. - * The duplicate RTE we added for the parent table is harmless, so we - * don't bother to get rid of it; ditto for the useless PlanRowMark - * node. - */ - if (list_length(appinfos) < 2) - rte->inh = false; - else - root->append_rel_list = list_concat(root->append_rel_list, - appinfos); - - } - - heap_close(oldrelation, NoLock); -} - -/* - * expand_partitioned_rtentry - * Recursively expand an RTE for a partitioned table. - * - * Note that RelationGetPartitionDispatchInfo will expand partitions in the - * same order as this code. - */ -static void -expand_partitioned_rtentry(PlannerInfo *root, RangeTblEntry *parentrte, - Index parentRTindex, Relation parentrel, - PlanRowMark *top_parentrc, LOCKMODE lockmode, - List **appinfos) -{ - int i; - RangeTblEntry *childrte; - Index childRTindex; - bool has_child = false; - PartitionDesc partdesc = RelationGetPartitionDesc(parentrel); - - check_stack_depth(); - - /* A partitioned table should always have a partition descriptor. */ - Assert(partdesc); - - Assert(parentrte->inh); - - /* - * Note down whether any partition key cols are being updated. Though it's - * the root partitioned table's updatedCols we are interested in, we - * instead use parentrte to get the updatedCols. This is convenient because - * parentrte already has the root partrel's updatedCols translated to match - * the attribute ordering of parentrel. - */ - if (!root->partColsUpdated) - root->partColsUpdated = - has_partition_attrs(parentrel, parentrte->updatedCols, NULL); - - /* First expand the partitioned table itself. */ - expand_single_inheritance_child(root, parentrte, parentRTindex, parentrel, - top_parentrc, parentrel, - appinfos, &childrte, &childRTindex); - - for (i = 0; i < partdesc->nparts; i++) - { - Oid childOID = partdesc->oids[i]; - Relation childrel; - - /* Open rel; we already have required locks */ - childrel = heap_open(childOID, NoLock); - - /* As in expand_inherited_rtentry, skip non-local temp tables */ - if (RELATION_IS_OTHER_TEMP(childrel)) - { - heap_close(childrel, lockmode); - continue; - } - - /* We have a real partition. */ - has_child = true; - - expand_single_inheritance_child(root, parentrte, parentRTindex, - parentrel, top_parentrc, childrel, - appinfos, &childrte, &childRTindex); - - /* If this child is itself partitioned, recurse */ - if (childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - expand_partitioned_rtentry(root, childrte, childRTindex, - childrel, top_parentrc, lockmode, - appinfos); - - /* Close child relation, but keep locks */ - heap_close(childrel, NoLock); - } - - /* - * If the partitioned table has no partitions or all the partitions are - * temporary tables from other backends, treat this as non-inheritance - * case. - */ - if (!has_child) - parentrte->inh = false; -} - -/* - * expand_single_inheritance_child - * Build a RangeTblEntry and an AppendRelInfo, if appropriate, plus - * maybe a PlanRowMark. - * - * We now expand the partition hierarchy level by level, creating a - * corresponding hierarchy of AppendRelInfos and RelOptInfos, where each - * partitioned descendant acts as a parent of its immediate partitions. - * (This is a difference from what older versions of PostgreSQL did and what - * is still done in the case of table inheritance for unpartitioned tables, - * where the hierarchy is flattened during RTE expansion.) - * - * PlanRowMarks still carry the top-parent's RTI, and the top-parent's - * allMarkTypes field still accumulates values from all descendents. - * - * "parentrte" and "parentRTindex" are immediate parent's RTE and - * RTI. "top_parentrc" is top parent's PlanRowMark. - * - * The child RangeTblEntry and its RTI are returned in "childrte_p" and - * "childRTindex_p" resp. - */ -static void -expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, - Index parentRTindex, Relation parentrel, - PlanRowMark *top_parentrc, Relation childrel, - List **appinfos, RangeTblEntry **childrte_p, - Index *childRTindex_p) -{ - Query *parse = root->parse; - Oid parentOID = RelationGetRelid(parentrel); - Oid childOID = RelationGetRelid(childrel); - RangeTblEntry *childrte; - Index childRTindex; - AppendRelInfo *appinfo; - - /* - * Build an RTE for the child, and attach to query's rangetable list. We - * copy most fields of the parent's RTE, but replace relation OID and - * relkind, and set inh = false. Also, set requiredPerms to zero since - * all required permissions checks are done on the original RTE. Likewise, - * set the child's securityQuals to empty, because we only want to apply - * the parent's RLS conditions regardless of what RLS properties - * individual children may have. (This is an intentional choice to make - * inherited RLS work like regular permissions checks.) The parent - * securityQuals will be propagated to children along with other base - * restriction clauses, so we don't need to do it here. - */ - childrte = copyObject(parentrte); - *childrte_p = childrte; - childrte->relid = childOID; - childrte->relkind = childrel->rd_rel->relkind; - /* A partitioned child will need to be expanded further. */ - if (childOID != parentOID && - childrte->relkind == RELKIND_PARTITIONED_TABLE) - childrte->inh = true; - else - childrte->inh = false; - childrte->requiredPerms = 0; - childrte->securityQuals = NIL; - parse->rtable = lappend(parse->rtable, childrte); - childRTindex = list_length(parse->rtable); - *childRTindex_p = childRTindex; - - /* - * We need an AppendRelInfo if paths will be built for the child RTE. If - * childrte->inh is true, then we'll always need to generate append paths - * for it. If childrte->inh is false, we must scan it if it's not a - * partitioned table; but if it is a partitioned table, then it never has - * any data of its own and need not be scanned. - */ - if (childrte->relkind != RELKIND_PARTITIONED_TABLE || childrte->inh) - { - appinfo = makeNode(AppendRelInfo); - appinfo->parent_relid = parentRTindex; - appinfo->child_relid = childRTindex; - appinfo->parent_reltype = parentrel->rd_rel->reltype; - appinfo->child_reltype = childrel->rd_rel->reltype; - make_inh_translation_list(parentrel, childrel, childRTindex, - &appinfo->translated_vars); - appinfo->parent_reloid = parentOID; - *appinfos = lappend(*appinfos, appinfo); - - /* - * Translate the column permissions bitmaps to the child's attnums (we - * have to build the translated_vars list before we can do this). But - * if this is the parent table, leave copyObject's result alone. - * - * Note: we need to do this even though the executor won't run any - * permissions checks on the child RTE. The insertedCols/updatedCols - * bitmaps may be examined for trigger-firing purposes. - */ - if (childOID != parentOID) - { - childrte->selectedCols = translate_col_privs(parentrte->selectedCols, - appinfo->translated_vars); - childrte->insertedCols = translate_col_privs(parentrte->insertedCols, - appinfo->translated_vars); - childrte->updatedCols = translate_col_privs(parentrte->updatedCols, - appinfo->translated_vars); - } - } - - /* - * Build a PlanRowMark if parent is marked FOR UPDATE/SHARE. - */ - if (top_parentrc) - { - PlanRowMark *childrc = makeNode(PlanRowMark); - - childrc->rti = childRTindex; - childrc->prti = top_parentrc->rti; - childrc->rowmarkId = top_parentrc->rowmarkId; - /* Reselect rowmark type, because relkind might not match parent */ - childrc->markType = select_rowmark_type(childrte, - top_parentrc->strength); - childrc->allMarkTypes = (1 << childrc->markType); - childrc->strength = top_parentrc->strength; - childrc->waitPolicy = top_parentrc->waitPolicy; - - /* - * We mark RowMarks for partitioned child tables as parent RowMarks so - * that the executor ignores them (except their existence means that - * the child tables be locked using appropriate mode). - */ - childrc->isParent = (childrte->relkind == RELKIND_PARTITIONED_TABLE); - - /* Include child's rowmark type in top parent's allMarkTypes */ - top_parentrc->allMarkTypes |= childrc->allMarkTypes; - - root->rowMarks = lappend(root->rowMarks, childrc); - } -} - -/* - * make_inh_translation_list - * Build the list of translations from parent Vars to child Vars for - * an inheritance child. - * - * For paranoia's sake, we match type/collation as well as attribute name. - */ -static void -make_inh_translation_list(Relation oldrelation, Relation newrelation, - Index newvarno, - List **translated_vars) -{ - List *vars = NIL; - TupleDesc old_tupdesc = RelationGetDescr(oldrelation); - TupleDesc new_tupdesc = RelationGetDescr(newrelation); - int oldnatts = old_tupdesc->natts; - int newnatts = new_tupdesc->natts; - int old_attno; - - for (old_attno = 0; old_attno < oldnatts; old_attno++) - { - Form_pg_attribute att; - char *attname; - Oid atttypid; - int32 atttypmod; - Oid attcollation; - int new_attno; - - att = TupleDescAttr(old_tupdesc, old_attno); - if (att->attisdropped) - { - /* Just put NULL into this list entry */ - vars = lappend(vars, NULL); - continue; - } - attname = NameStr(att->attname); - atttypid = att->atttypid; - atttypmod = att->atttypmod; - attcollation = att->attcollation; - - /* - * When we are generating the "translation list" for the parent table - * of an inheritance set, no need to search for matches. - */ - if (oldrelation == newrelation) - { - vars = lappend(vars, makeVar(newvarno, - (AttrNumber) (old_attno + 1), - atttypid, - atttypmod, - attcollation, - 0)); - continue; - } - - /* - * Otherwise we have to search for the matching column by name. - * There's no guarantee it'll have the same column position, because - * of cases like ALTER TABLE ADD COLUMN and multiple inheritance. - * However, in simple cases it will be the same column number, so try - * that before we go groveling through all the columns. - * - * Note: the test for (att = ...) != NULL cannot fail, it's just a - * notational device to include the assignment into the if-clause. - */ - if (old_attno < newnatts && - (att = TupleDescAttr(new_tupdesc, old_attno)) != NULL && - !att->attisdropped && - strcmp(attname, NameStr(att->attname)) == 0) - new_attno = old_attno; - else - { - for (new_attno = 0; new_attno < newnatts; new_attno++) - { - att = TupleDescAttr(new_tupdesc, new_attno); - if (!att->attisdropped && - strcmp(attname, NameStr(att->attname)) == 0) - break; - } - if (new_attno >= newnatts) - elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"", - attname, RelationGetRelationName(newrelation)); - } - - /* Found it, check type and collation match */ - if (atttypid != att->atttypid || atttypmod != att->atttypmod) - elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type", - attname, RelationGetRelationName(newrelation)); - if (attcollation != att->attcollation) - elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's collation", - attname, RelationGetRelationName(newrelation)); - - vars = lappend(vars, makeVar(newvarno, - (AttrNumber) (new_attno + 1), - atttypid, - atttypmod, - attcollation, - 0)); - } - - *translated_vars = vars; -} - -/* - * translate_col_privs - * Translate a bitmapset representing per-column privileges from the - * parent rel's attribute numbering to the child's. - * - * The only surprise here is that we don't translate a parent whole-row - * reference into a child whole-row reference. That would mean requiring - * permissions on all child columns, which is overly strict, since the - * query is really only going to reference the inherited columns. Instead - * we set the per-column bits for all inherited columns. - */ -static Bitmapset * -translate_col_privs(const Bitmapset *parent_privs, - List *translated_vars) -{ - Bitmapset *child_privs = NULL; - bool whole_row; - int attno; - ListCell *lc; - - /* System attributes have the same numbers in all tables */ - for (attno = FirstLowInvalidHeapAttributeNumber + 1; attno < 0; attno++) - { - if (bms_is_member(attno - FirstLowInvalidHeapAttributeNumber, - parent_privs)) - child_privs = bms_add_member(child_privs, - attno - FirstLowInvalidHeapAttributeNumber); - } - - /* Check if parent has whole-row reference */ - whole_row = bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber, - parent_privs); - - /* And now translate the regular user attributes, using the vars list */ - attno = InvalidAttrNumber; - foreach(lc, translated_vars) - { - Var *var = lfirst_node(Var, lc); - - attno++; - if (var == NULL) /* ignore dropped columns */ - continue; - if (whole_row || - bms_is_member(attno - FirstLowInvalidHeapAttributeNumber, - parent_privs)) - child_privs = bms_add_member(child_privs, - var->varattno - FirstLowInvalidHeapAttributeNumber); - } - - return child_privs; -} - -/* - * adjust_appendrel_attrs - * Copy the specified query or expression and translate Vars referring to a - * parent rel to refer to the corresponding child rel instead. We also - * update rtindexes appearing outside Vars, such as resultRelation and - * jointree relids. - * - * Note: this is only applied after conversion of sublinks to subplans, - * so we don't need to cope with recursion into sub-queries. - * - * Note: this is not hugely different from what pullup_replace_vars() does; - * maybe we should try to fold the two routines together. - */ -Node * -adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, - AppendRelInfo **appinfos) -{ - Node *result; - adjust_appendrel_attrs_context context; - - context.root = root; - context.nappinfos = nappinfos; - context.appinfos = appinfos; - - /* If there's nothing to adjust, don't call this function. */ - Assert(nappinfos >= 1 && appinfos != NULL); - - /* - * Must be prepared to start with a Query or a bare expression tree. - */ - if (node && IsA(node, Query)) - { - Query *newnode; - int cnt; - - newnode = query_tree_mutator((Query *) node, - adjust_appendrel_attrs_mutator, - (void *) &context, - QTW_IGNORE_RC_SUBQUERIES); - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - if (newnode->resultRelation == appinfo->parent_relid) - { - newnode->resultRelation = appinfo->child_relid; - /* Fix tlist resnos too, if it's inherited UPDATE */ - if (newnode->commandType == CMD_UPDATE) - newnode->targetList = - adjust_inherited_tlist(newnode->targetList, - appinfo); - break; - } - } - - result = (Node *) newnode; - } - else - result = adjust_appendrel_attrs_mutator(node, &context); - - return result; -} - -static Node * -adjust_appendrel_attrs_mutator(Node *node, - adjust_appendrel_attrs_context *context) -{ - AppendRelInfo **appinfos = context->appinfos; - int nappinfos = context->nappinfos; - int cnt; - - if (node == NULL) - return NULL; - if (IsA(node, Var)) - { - Var *var = (Var *) copyObject(node); - AppendRelInfo *appinfo = NULL; - - for (cnt = 0; cnt < nappinfos; cnt++) - { - if (var->varno == appinfos[cnt]->parent_relid) - { - appinfo = appinfos[cnt]; - break; - } - } - - if (var->varlevelsup == 0 && appinfo) - { - var->varno = appinfo->child_relid; - var->varnoold = appinfo->child_relid; - if (var->varattno > 0) - { - Node *newnode; - - if (var->varattno > list_length(appinfo->translated_vars)) - elog(ERROR, "attribute %d of relation \"%s\" does not exist", - var->varattno, get_rel_name(appinfo->parent_reloid)); - newnode = copyObject(list_nth(appinfo->translated_vars, - var->varattno - 1)); - if (newnode == NULL) - elog(ERROR, "attribute %d of relation \"%s\" does not exist", - var->varattno, get_rel_name(appinfo->parent_reloid)); - return newnode; - } - else if (var->varattno == 0) - { - /* - * Whole-row Var: if we are dealing with named rowtypes, we - * can use a whole-row Var for the child table plus a coercion - * step to convert the tuple layout to the parent's rowtype. - * Otherwise we have to generate a RowExpr. - */ - if (OidIsValid(appinfo->child_reltype)) - { - Assert(var->vartype == appinfo->parent_reltype); - if (appinfo->parent_reltype != appinfo->child_reltype) - { - ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr); - - r->arg = (Expr *) var; - r->resulttype = appinfo->parent_reltype; - r->convertformat = COERCE_IMPLICIT_CAST; - r->location = -1; - /* Make sure the Var node has the right type ID, too */ - var->vartype = appinfo->child_reltype; - return (Node *) r; - } - } - else - { - /* - * Build a RowExpr containing the translated variables. - * - * In practice var->vartype will always be RECORDOID here, - * so we need to come up with some suitable column names. - * We use the parent RTE's column names. - * - * Note: we can't get here for inheritance cases, so there - * is no need to worry that translated_vars might contain - * some dummy NULLs. - */ - RowExpr *rowexpr; - List *fields; - RangeTblEntry *rte; - - rte = rt_fetch(appinfo->parent_relid, - context->root->parse->rtable); - fields = copyObject(appinfo->translated_vars); - rowexpr = makeNode(RowExpr); - rowexpr->args = fields; - rowexpr->row_typeid = var->vartype; - rowexpr->row_format = COERCE_IMPLICIT_CAST; - rowexpr->colnames = copyObject(rte->eref->colnames); - rowexpr->location = -1; - - return (Node *) rowexpr; - } - } - /* system attributes don't need any other translation */ - } - return (Node *) var; - } - if (IsA(node, CurrentOfExpr)) - { - CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node); - - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - if (cexpr->cvarno == appinfo->parent_relid) - { - cexpr->cvarno = appinfo->child_relid; - break; - } - } - return (Node *) cexpr; - } - if (IsA(node, RangeTblRef)) - { - RangeTblRef *rtr = (RangeTblRef *) copyObject(node); - - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - if (rtr->rtindex == appinfo->parent_relid) - { - rtr->rtindex = appinfo->child_relid; - break; - } - } - return (Node *) rtr; - } - if (IsA(node, JoinExpr)) - { - /* Copy the JoinExpr node with correct mutation of subnodes */ - JoinExpr *j; - AppendRelInfo *appinfo; - - j = (JoinExpr *) expression_tree_mutator(node, - adjust_appendrel_attrs_mutator, - (void *) context); - /* now fix JoinExpr's rtindex (probably never happens) */ - for (cnt = 0; cnt < nappinfos; cnt++) - { - appinfo = appinfos[cnt]; - - if (j->rtindex == appinfo->parent_relid) - { - j->rtindex = appinfo->child_relid; - break; - } - } - return (Node *) j; - } - if (IsA(node, PlaceHolderVar)) - { - /* Copy the PlaceHolderVar node with correct mutation of subnodes */ - PlaceHolderVar *phv; - - phv = (PlaceHolderVar *) expression_tree_mutator(node, - adjust_appendrel_attrs_mutator, - (void *) context); - /* now fix PlaceHolderVar's relid sets */ - if (phv->phlevelsup == 0) - phv->phrels = adjust_child_relids(phv->phrels, context->nappinfos, - context->appinfos); - return (Node *) phv; - } - /* Shouldn't need to handle planner auxiliary nodes here */ - Assert(!IsA(node, SpecialJoinInfo)); - Assert(!IsA(node, AppendRelInfo)); - Assert(!IsA(node, PlaceHolderInfo)); - Assert(!IsA(node, MinMaxAggInfo)); - - /* - * We have to process RestrictInfo nodes specially. (Note: although - * set_append_rel_pathlist will hide RestrictInfos in the parent's - * baserestrictinfo list from us, it doesn't hide those in joininfo.) - */ - if (IsA(node, RestrictInfo)) - { - RestrictInfo *oldinfo = (RestrictInfo *) node; - RestrictInfo *newinfo = makeNode(RestrictInfo); - - /* Copy all flat-copiable fields */ - memcpy(newinfo, oldinfo, sizeof(RestrictInfo)); - - /* Recursively fix the clause itself */ - newinfo->clause = (Expr *) - adjust_appendrel_attrs_mutator((Node *) oldinfo->clause, context); - - /* and the modified version, if an OR clause */ - newinfo->orclause = (Expr *) - adjust_appendrel_attrs_mutator((Node *) oldinfo->orclause, context); - - /* adjust relid sets too */ - newinfo->clause_relids = adjust_child_relids(oldinfo->clause_relids, - context->nappinfos, - context->appinfos); - newinfo->required_relids = adjust_child_relids(oldinfo->required_relids, - context->nappinfos, - context->appinfos); - newinfo->outer_relids = adjust_child_relids(oldinfo->outer_relids, - context->nappinfos, - context->appinfos); - newinfo->nullable_relids = adjust_child_relids(oldinfo->nullable_relids, - context->nappinfos, - context->appinfos); - newinfo->left_relids = adjust_child_relids(oldinfo->left_relids, - context->nappinfos, - context->appinfos); - newinfo->right_relids = adjust_child_relids(oldinfo->right_relids, - context->nappinfos, - context->appinfos); - - /* - * Reset cached derivative fields, since these might need to have - * different values when considering the child relation. Note we - * don't reset left_ec/right_ec: each child variable is implicitly - * equivalent to its parent, so still a member of the same EC if any. - */ - newinfo->eval_cost.startup = -1; - newinfo->norm_selec = -1; - newinfo->outer_selec = -1; - newinfo->left_em = NULL; - newinfo->right_em = NULL; - newinfo->scansel_cache = NIL; - newinfo->left_bucketsize = -1; - newinfo->right_bucketsize = -1; - newinfo->left_mcvfreq = -1; - newinfo->right_mcvfreq = -1; - - return (Node *) newinfo; - } - - /* - * NOTE: we do not need to recurse into sublinks, because they should - * already have been converted to subplans before we see them. - */ - Assert(!IsA(node, SubLink)); - Assert(!IsA(node, Query)); - - return expression_tree_mutator(node, adjust_appendrel_attrs_mutator, - (void *) context); -} - -/* - * Substitute child relids for parent relids in a Relid set. The array of - * appinfos specifies the substitutions to be performed. - */ -static Relids -adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos) -{ - Bitmapset *result = NULL; - int cnt; - - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - /* Remove parent, add child */ - if (bms_is_member(appinfo->parent_relid, relids)) - { - /* Make a copy if we are changing the set. */ - if (!result) - result = bms_copy(relids); - - result = bms_del_member(result, appinfo->parent_relid); - result = bms_add_member(result, appinfo->child_relid); - } - } - - /* If we made any changes, return the modified copy. */ - if (result) - return result; - - /* Otherwise, return the original set without modification. */ - return relids; -} - -/* - * Replace any relid present in top_parent_relids with its child in - * child_relids. Members of child_relids can be multiple levels below top - * parent in the partition hierarchy. - */ -Relids -adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, - Relids child_relids, Relids top_parent_relids) -{ - AppendRelInfo **appinfos; - int nappinfos; - Relids parent_relids = NULL; - Relids result; - Relids tmp_result = NULL; - int cnt; - - /* - * If the given relids set doesn't contain any of the top parent relids, - * it will remain unchanged. - */ - if (!bms_overlap(relids, top_parent_relids)) - return relids; - - appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos); - - /* Construct relids set for the immediate parent of the given child. */ - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - parent_relids = bms_add_member(parent_relids, appinfo->parent_relid); - } - - /* Recurse if immediate parent is not the top parent. */ - if (!bms_equal(parent_relids, top_parent_relids)) - { - tmp_result = adjust_child_relids_multilevel(root, relids, - parent_relids, - top_parent_relids); - relids = tmp_result; - } - - result = adjust_child_relids(relids, nappinfos, appinfos); - - /* Free memory consumed by any intermediate result. */ - if (tmp_result) - bms_free(tmp_result); - bms_free(parent_relids); - pfree(appinfos); - - return result; -} - -/* - * Adjust the targetlist entries of an inherited UPDATE operation - * - * The expressions have already been fixed, but we have to make sure that - * the target resnos match the child table (they may not, in the case of - * a column that was added after-the-fact by ALTER TABLE). In some cases - * this can force us to re-order the tlist to preserve resno ordering. - * (We do all this work in special cases so that preptlist.c is fast for - * the typical case.) - * - * The given tlist has already been through expression_tree_mutator; - * therefore the TargetEntry nodes are fresh copies that it's okay to - * scribble on. - * - * Note that this is not needed for INSERT because INSERT isn't inheritable. - */ -static List * -adjust_inherited_tlist(List *tlist, AppendRelInfo *context) -{ - bool changed_it = false; - ListCell *tl; - List *new_tlist; - bool more; - int attrno; - - /* This should only happen for an inheritance case, not UNION ALL */ - Assert(OidIsValid(context->parent_reloid)); - - /* Scan tlist and update resnos to match attnums of child rel */ - foreach(tl, tlist) - { - TargetEntry *tle = (TargetEntry *) lfirst(tl); - Var *childvar; - - if (tle->resjunk) - continue; /* ignore junk items */ - - /* Look up the translation of this column: it must be a Var */ - if (tle->resno <= 0 || - tle->resno > list_length(context->translated_vars)) - elog(ERROR, "attribute %d of relation \"%s\" does not exist", - tle->resno, get_rel_name(context->parent_reloid)); - childvar = (Var *) list_nth(context->translated_vars, tle->resno - 1); - if (childvar == NULL || !IsA(childvar, Var)) - elog(ERROR, "attribute %d of relation \"%s\" does not exist", - tle->resno, get_rel_name(context->parent_reloid)); - - if (tle->resno != childvar->varattno) - { - tle->resno = childvar->varattno; - changed_it = true; - } - } - - /* - * If we changed anything, re-sort the tlist by resno, and make sure - * resjunk entries have resnos above the last real resno. The sort - * algorithm is a bit stupid, but for such a seldom-taken path, small is - * probably better than fast. - */ - if (!changed_it) - return tlist; - - new_tlist = NIL; - more = true; - for (attrno = 1; more; attrno++) - { - more = false; - foreach(tl, tlist) - { - TargetEntry *tle = (TargetEntry *) lfirst(tl); - - if (tle->resjunk) - continue; /* ignore junk items */ - - if (tle->resno == attrno) - new_tlist = lappend(new_tlist, tle); - else if (tle->resno > attrno) - more = true; - } - } - - foreach(tl, tlist) - { - TargetEntry *tle = (TargetEntry *) lfirst(tl); - - if (!tle->resjunk) - continue; /* here, ignore non-junk items */ - - tle->resno = attrno; - new_tlist = lappend(new_tlist, tle); - attrno++; - } - - return new_tlist; -} - -/* - * adjust_appendrel_attrs_multilevel - * Apply Var translations from a toplevel appendrel parent down to a child. - * - * In some cases we need to translate expressions referencing a parent relation - * to reference an appendrel child that's multiple levels removed from it. - */ -Node * -adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, - Relids child_relids, - Relids top_parent_relids) -{ - AppendRelInfo **appinfos; - Bitmapset *parent_relids = NULL; - int nappinfos; - int cnt; - - Assert(bms_num_members(child_relids) == bms_num_members(top_parent_relids)); - - appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos); - - /* Construct relids set for the immediate parent of given child. */ - for (cnt = 0; cnt < nappinfos; cnt++) - { - AppendRelInfo *appinfo = appinfos[cnt]; - - parent_relids = bms_add_member(parent_relids, appinfo->parent_relid); - } - - /* Recurse if immediate parent is not the top parent. */ - if (!bms_equal(parent_relids, top_parent_relids)) - node = adjust_appendrel_attrs_multilevel(root, node, parent_relids, - top_parent_relids); - - /* Now translate for this child */ - node = adjust_appendrel_attrs(root, node, nappinfos, appinfos); - - pfree(appinfos); - - return node; -} - -/* - * Construct the SpecialJoinInfo for a child-join by translating - * SpecialJoinInfo for the join between parents. left_relids and right_relids - * are the relids of left and right side of the join respectively. - */ -SpecialJoinInfo * -build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo, - Relids left_relids, Relids right_relids) -{ - SpecialJoinInfo *sjinfo = makeNode(SpecialJoinInfo); - AppendRelInfo **left_appinfos; - int left_nappinfos; - AppendRelInfo **right_appinfos; - int right_nappinfos; - - memcpy(sjinfo, parent_sjinfo, sizeof(SpecialJoinInfo)); - left_appinfos = find_appinfos_by_relids(root, left_relids, - &left_nappinfos); - right_appinfos = find_appinfos_by_relids(root, right_relids, - &right_nappinfos); - - sjinfo->min_lefthand = adjust_child_relids(sjinfo->min_lefthand, - left_nappinfos, left_appinfos); - sjinfo->min_righthand = adjust_child_relids(sjinfo->min_righthand, - right_nappinfos, - right_appinfos); - sjinfo->syn_lefthand = adjust_child_relids(sjinfo->syn_lefthand, - left_nappinfos, left_appinfos); - sjinfo->syn_righthand = adjust_child_relids(sjinfo->syn_righthand, - right_nappinfos, - right_appinfos); - sjinfo->semi_rhs_exprs = (List *) adjust_appendrel_attrs(root, - (Node *) sjinfo->semi_rhs_exprs, - right_nappinfos, - right_appinfos); - - pfree(left_appinfos); - pfree(right_appinfos); - - return sjinfo; -} - -/* - * find_appinfos_by_relids - * Find AppendRelInfo structures for all relations specified by relids. - * - * The AppendRelInfos are returned in an array, which can be pfree'd by the - * caller. *nappinfos is set to the number of entries in the array. - */ -AppendRelInfo ** -find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos) -{ - ListCell *lc; - AppendRelInfo **appinfos; - int cnt = 0; - - *nappinfos = bms_num_members(relids); - appinfos = (AppendRelInfo **) palloc(sizeof(AppendRelInfo *) * *nappinfos); - - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = lfirst(lc); - - if (bms_is_member(appinfo->child_relid, relids)) - { - appinfos[cnt] = appinfo; - cnt++; - - /* Stop when we have gathered all the AppendRelInfos. */ - if (cnt == *nappinfos) - return appinfos; - } - } - - /* Should have found the entries ... */ - elog(ERROR, "did not find all requested child rels in append_rel_list"); - return NULL; /* not reached */ -} diff --git a/src/backend/optimizer/util/Makefile b/src/backend/optimizer/util/Makefile index c54d0a690d8..bb33e2cc7c4 100644 --- a/src/backend/optimizer/util/Makefile +++ b/src/backend/optimizer/util/Makefile @@ -12,7 +12,8 @@ subdir = src/backend/optimizer/util top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = clauses.o joininfo.o orclauses.o pathnode.o placeholder.o \ - plancat.o predtest.o relnode.o restrictinfo.o tlist.o var.o +OBJS = appendinfo.o clauses.o inherit.o joininfo.o orclauses.o \ + paramassign.o pathnode.o placeholder.o plancat.o predtest.o \ + relnode.o restrictinfo.o tlist.o var.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/optimizer/util/appendinfo.c b/src/backend/optimizer/util/appendinfo.c new file mode 100644 index 00000000000..16d315176eb --- /dev/null +++ b/src/backend/optimizer/util/appendinfo.c @@ -0,0 +1,729 @@ +/*------------------------------------------------------------------------- + * + * appendinfo.c + * Routines for mapping between append parent(s) and children + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/optimizer/path/appendinfo.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/htup_details.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/appendinfo.h" +#include "parser/parsetree.h" +#include "utils/lsyscache.h" +#include "utils/rel.h" +#include "utils/syscache.h" + + +typedef struct +{ + PlannerInfo *root; + int nappinfos; + AppendRelInfo **appinfos; +} adjust_appendrel_attrs_context; + +static void make_inh_translation_list(Relation oldrelation, + Relation newrelation, + Index newvarno, + List **translated_vars); +static Node *adjust_appendrel_attrs_mutator(Node *node, + adjust_appendrel_attrs_context *context); +static List *adjust_inherited_tlist(List *tlist, + AppendRelInfo *context); + + +/* + * make_append_rel_info + * Build an AppendRelInfo for the parent-child pair + */ +AppendRelInfo * +make_append_rel_info(Relation parentrel, Relation childrel, + Index parentRTindex, Index childRTindex) +{ + AppendRelInfo *appinfo = makeNode(AppendRelInfo); + + appinfo->parent_relid = parentRTindex; + appinfo->child_relid = childRTindex; + appinfo->parent_reltype = parentrel->rd_rel->reltype; + appinfo->child_reltype = childrel->rd_rel->reltype; + make_inh_translation_list(parentrel, childrel, childRTindex, + &appinfo->translated_vars); + appinfo->parent_reloid = RelationGetRelid(parentrel); + + return appinfo; +} + +/* + * make_inh_translation_list + * Build the list of translations from parent Vars to child Vars for + * an inheritance child. + * + * For paranoia's sake, we match type/collation as well as attribute name. + */ +static void +make_inh_translation_list(Relation oldrelation, Relation newrelation, + Index newvarno, + List **translated_vars) +{ + List *vars = NIL; + TupleDesc old_tupdesc = RelationGetDescr(oldrelation); + TupleDesc new_tupdesc = RelationGetDescr(newrelation); + Oid new_relid = RelationGetRelid(newrelation); + int oldnatts = old_tupdesc->natts; + int newnatts = new_tupdesc->natts; + int old_attno; + int new_attno = 0; + + for (old_attno = 0; old_attno < oldnatts; old_attno++) + { + Form_pg_attribute att; + char *attname; + Oid atttypid; + int32 atttypmod; + Oid attcollation; + + att = TupleDescAttr(old_tupdesc, old_attno); + if (att->attisdropped) + { + /* Just put NULL into this list entry */ + vars = lappend(vars, NULL); + continue; + } + attname = NameStr(att->attname); + atttypid = att->atttypid; + atttypmod = att->atttypmod; + attcollation = att->attcollation; + + /* + * When we are generating the "translation list" for the parent table + * of an inheritance set, no need to search for matches. + */ + if (oldrelation == newrelation) + { + vars = lappend(vars, makeVar(newvarno, + (AttrNumber) (old_attno + 1), + atttypid, + atttypmod, + attcollation, + 0)); + continue; + } + + /* + * Otherwise we have to search for the matching column by name. + * There's no guarantee it'll have the same column position, because + * of cases like ALTER TABLE ADD COLUMN and multiple inheritance. + * However, in simple cases, the relative order of columns is mostly + * the same in both relations, so try the column of newrelation that + * follows immediately after the one that we just found, and if that + * fails, let syscache handle it. + */ + if (new_attno >= newnatts || + (att = TupleDescAttr(new_tupdesc, new_attno))->attisdropped || + strcmp(attname, NameStr(att->attname)) != 0) + { + HeapTuple newtup; + + newtup = SearchSysCacheAttName(new_relid, attname); + if (!HeapTupleIsValid(newtup)) + elog(ERROR, "could not find inherited attribute \"%s\" of relation \"%s\"", + attname, RelationGetRelationName(newrelation)); + new_attno = ((Form_pg_attribute) GETSTRUCT(newtup))->attnum - 1; + ReleaseSysCache(newtup); + + att = TupleDescAttr(new_tupdesc, new_attno); + } + + /* Found it, check type and collation match */ + if (atttypid != att->atttypid || atttypmod != att->atttypmod) + elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type", + attname, RelationGetRelationName(newrelation)); + if (attcollation != att->attcollation) + elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's collation", + attname, RelationGetRelationName(newrelation)); + + vars = lappend(vars, makeVar(newvarno, + (AttrNumber) (new_attno + 1), + atttypid, + atttypmod, + attcollation, + 0)); + new_attno++; + } + + *translated_vars = vars; +} + +/* + * adjust_appendrel_attrs + * Copy the specified query or expression and translate Vars referring to a + * parent rel to refer to the corresponding child rel instead. We also + * update rtindexes appearing outside Vars, such as resultRelation and + * jointree relids. + * + * Note: this is only applied after conversion of sublinks to subplans, + * so we don't need to cope with recursion into sub-queries. + * + * Note: this is not hugely different from what pullup_replace_vars() does; + * maybe we should try to fold the two routines together. + */ +Node * +adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, + AppendRelInfo **appinfos) +{ + Node *result; + adjust_appendrel_attrs_context context; + + context.root = root; + context.nappinfos = nappinfos; + context.appinfos = appinfos; + + /* If there's nothing to adjust, don't call this function. */ + Assert(nappinfos >= 1 && appinfos != NULL); + + /* + * Must be prepared to start with a Query or a bare expression tree. + */ + if (node && IsA(node, Query)) + { + Query *newnode; + int cnt; + + newnode = query_tree_mutator((Query *) node, + adjust_appendrel_attrs_mutator, + (void *) &context, + QTW_IGNORE_RC_SUBQUERIES); + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + if (newnode->resultRelation == appinfo->parent_relid) + { + newnode->resultRelation = appinfo->child_relid; + /* Fix tlist resnos too, if it's inherited UPDATE */ + if (newnode->commandType == CMD_UPDATE) + newnode->targetList = + adjust_inherited_tlist(newnode->targetList, + appinfo); + break; + } + } + + result = (Node *) newnode; + } + else + result = adjust_appendrel_attrs_mutator(node, &context); + + return result; +} + +static Node * +adjust_appendrel_attrs_mutator(Node *node, + adjust_appendrel_attrs_context *context) +{ + AppendRelInfo **appinfos = context->appinfos; + int nappinfos = context->nappinfos; + int cnt; + + if (node == NULL) + return NULL; + if (IsA(node, Var)) + { + Var *var = (Var *) copyObject(node); + AppendRelInfo *appinfo = NULL; + + for (cnt = 0; cnt < nappinfos; cnt++) + { + if (var->varno == appinfos[cnt]->parent_relid) + { + appinfo = appinfos[cnt]; + break; + } + } + + if (var->varlevelsup == 0 && appinfo) + { + var->varno = appinfo->child_relid; + var->varnoold = appinfo->child_relid; + if (var->varattno > 0) + { + Node *newnode; + + if (var->varattno > list_length(appinfo->translated_vars)) + elog(ERROR, "attribute %d of relation \"%s\" does not exist", + var->varattno, get_rel_name(appinfo->parent_reloid)); + newnode = copyObject(list_nth(appinfo->translated_vars, + var->varattno - 1)); + if (newnode == NULL) + elog(ERROR, "attribute %d of relation \"%s\" does not exist", + var->varattno, get_rel_name(appinfo->parent_reloid)); + return newnode; + } + else if (var->varattno == 0) + { + /* + * Whole-row Var: if we are dealing with named rowtypes, we + * can use a whole-row Var for the child table plus a coercion + * step to convert the tuple layout to the parent's rowtype. + * Otherwise we have to generate a RowExpr. + */ + if (OidIsValid(appinfo->child_reltype)) + { + Assert(var->vartype == appinfo->parent_reltype); + if (appinfo->parent_reltype != appinfo->child_reltype) + { + ConvertRowtypeExpr *r = makeNode(ConvertRowtypeExpr); + + r->arg = (Expr *) var; + r->resulttype = appinfo->parent_reltype; + r->convertformat = COERCE_IMPLICIT_CAST; + r->location = -1; + /* Make sure the Var node has the right type ID, too */ + var->vartype = appinfo->child_reltype; + return (Node *) r; + } + } + else + { + /* + * Build a RowExpr containing the translated variables. + * + * In practice var->vartype will always be RECORDOID here, + * so we need to come up with some suitable column names. + * We use the parent RTE's column names. + * + * Note: we can't get here for inheritance cases, so there + * is no need to worry that translated_vars might contain + * some dummy NULLs. + */ + RowExpr *rowexpr; + List *fields; + RangeTblEntry *rte; + + rte = rt_fetch(appinfo->parent_relid, + context->root->parse->rtable); + fields = copyObject(appinfo->translated_vars); + rowexpr = makeNode(RowExpr); + rowexpr->args = fields; + rowexpr->row_typeid = var->vartype; + rowexpr->row_format = COERCE_IMPLICIT_CAST; + rowexpr->colnames = copyObject(rte->eref->colnames); + rowexpr->location = -1; + + return (Node *) rowexpr; + } + } + /* system attributes don't need any other translation */ + } + return (Node *) var; + } + if (IsA(node, CurrentOfExpr)) + { + CurrentOfExpr *cexpr = (CurrentOfExpr *) copyObject(node); + + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + if (cexpr->cvarno == appinfo->parent_relid) + { + cexpr->cvarno = appinfo->child_relid; + break; + } + } + return (Node *) cexpr; + } + if (IsA(node, RangeTblRef)) + { + RangeTblRef *rtr = (RangeTblRef *) copyObject(node); + + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + if (rtr->rtindex == appinfo->parent_relid) + { + rtr->rtindex = appinfo->child_relid; + break; + } + } + return (Node *) rtr; + } + if (IsA(node, JoinExpr)) + { + /* Copy the JoinExpr node with correct mutation of subnodes */ + JoinExpr *j; + AppendRelInfo *appinfo; + + j = (JoinExpr *) expression_tree_mutator(node, + adjust_appendrel_attrs_mutator, + (void *) context); + /* now fix JoinExpr's rtindex (probably never happens) */ + for (cnt = 0; cnt < nappinfos; cnt++) + { + appinfo = appinfos[cnt]; + + if (j->rtindex == appinfo->parent_relid) + { + j->rtindex = appinfo->child_relid; + break; + } + } + return (Node *) j; + } + if (IsA(node, PlaceHolderVar)) + { + /* Copy the PlaceHolderVar node with correct mutation of subnodes */ + PlaceHolderVar *phv; + + phv = (PlaceHolderVar *) expression_tree_mutator(node, + adjust_appendrel_attrs_mutator, + (void *) context); + /* now fix PlaceHolderVar's relid sets */ + if (phv->phlevelsup == 0) + phv->phrels = adjust_child_relids(phv->phrels, context->nappinfos, + context->appinfos); + return (Node *) phv; + } + /* Shouldn't need to handle planner auxiliary nodes here */ + Assert(!IsA(node, SpecialJoinInfo)); + Assert(!IsA(node, AppendRelInfo)); + Assert(!IsA(node, PlaceHolderInfo)); + Assert(!IsA(node, MinMaxAggInfo)); + + /* + * We have to process RestrictInfo nodes specially. (Note: although + * set_append_rel_pathlist will hide RestrictInfos in the parent's + * baserestrictinfo list from us, it doesn't hide those in joininfo.) + */ + if (IsA(node, RestrictInfo)) + { + RestrictInfo *oldinfo = (RestrictInfo *) node; + RestrictInfo *newinfo = makeNode(RestrictInfo); + + /* Copy all flat-copiable fields */ + memcpy(newinfo, oldinfo, sizeof(RestrictInfo)); + + /* Recursively fix the clause itself */ + newinfo->clause = (Expr *) + adjust_appendrel_attrs_mutator((Node *) oldinfo->clause, context); + + /* and the modified version, if an OR clause */ + newinfo->orclause = (Expr *) + adjust_appendrel_attrs_mutator((Node *) oldinfo->orclause, context); + + /* adjust relid sets too */ + newinfo->clause_relids = adjust_child_relids(oldinfo->clause_relids, + context->nappinfos, + context->appinfos); + newinfo->required_relids = adjust_child_relids(oldinfo->required_relids, + context->nappinfos, + context->appinfos); + newinfo->outer_relids = adjust_child_relids(oldinfo->outer_relids, + context->nappinfos, + context->appinfos); + newinfo->nullable_relids = adjust_child_relids(oldinfo->nullable_relids, + context->nappinfos, + context->appinfos); + newinfo->left_relids = adjust_child_relids(oldinfo->left_relids, + context->nappinfos, + context->appinfos); + newinfo->right_relids = adjust_child_relids(oldinfo->right_relids, + context->nappinfos, + context->appinfos); + + /* + * Reset cached derivative fields, since these might need to have + * different values when considering the child relation. Note we + * don't reset left_ec/right_ec: each child variable is implicitly + * equivalent to its parent, so still a member of the same EC if any. + */ + newinfo->eval_cost.startup = -1; + newinfo->norm_selec = -1; + newinfo->outer_selec = -1; + newinfo->left_em = NULL; + newinfo->right_em = NULL; + newinfo->scansel_cache = NIL; + newinfo->left_bucketsize = -1; + newinfo->right_bucketsize = -1; + newinfo->left_mcvfreq = -1; + newinfo->right_mcvfreq = -1; + + return (Node *) newinfo; + } + + /* + * NOTE: we do not need to recurse into sublinks, because they should + * already have been converted to subplans before we see them. + */ + Assert(!IsA(node, SubLink)); + Assert(!IsA(node, Query)); + + return expression_tree_mutator(node, adjust_appendrel_attrs_mutator, + (void *) context); +} + +/* + * adjust_appendrel_attrs_multilevel + * Apply Var translations from a toplevel appendrel parent down to a child. + * + * In some cases we need to translate expressions referencing a parent relation + * to reference an appendrel child that's multiple levels removed from it. + */ +Node * +adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, + Relids child_relids, + Relids top_parent_relids) +{ + AppendRelInfo **appinfos; + Bitmapset *parent_relids = NULL; + int nappinfos; + int cnt; + + Assert(bms_num_members(child_relids) == bms_num_members(top_parent_relids)); + + appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos); + + /* Construct relids set for the immediate parent of given child. */ + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + parent_relids = bms_add_member(parent_relids, appinfo->parent_relid); + } + + /* Recurse if immediate parent is not the top parent. */ + if (!bms_equal(parent_relids, top_parent_relids)) + node = adjust_appendrel_attrs_multilevel(root, node, parent_relids, + top_parent_relids); + + /* Now translate for this child */ + node = adjust_appendrel_attrs(root, node, nappinfos, appinfos); + + pfree(appinfos); + + return node; +} + +/* + * Substitute child relids for parent relids in a Relid set. The array of + * appinfos specifies the substitutions to be performed. + */ +Relids +adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos) +{ + Bitmapset *result = NULL; + int cnt; + + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + /* Remove parent, add child */ + if (bms_is_member(appinfo->parent_relid, relids)) + { + /* Make a copy if we are changing the set. */ + if (!result) + result = bms_copy(relids); + + result = bms_del_member(result, appinfo->parent_relid); + result = bms_add_member(result, appinfo->child_relid); + } + } + + /* If we made any changes, return the modified copy. */ + if (result) + return result; + + /* Otherwise, return the original set without modification. */ + return relids; +} + +/* + * Replace any relid present in top_parent_relids with its child in + * child_relids. Members of child_relids can be multiple levels below top + * parent in the partition hierarchy. + */ +Relids +adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, + Relids child_relids, Relids top_parent_relids) +{ + AppendRelInfo **appinfos; + int nappinfos; + Relids parent_relids = NULL; + Relids result; + Relids tmp_result = NULL; + int cnt; + + /* + * If the given relids set doesn't contain any of the top parent relids, + * it will remain unchanged. + */ + if (!bms_overlap(relids, top_parent_relids)) + return relids; + + appinfos = find_appinfos_by_relids(root, child_relids, &nappinfos); + + /* Construct relids set for the immediate parent of the given child. */ + for (cnt = 0; cnt < nappinfos; cnt++) + { + AppendRelInfo *appinfo = appinfos[cnt]; + + parent_relids = bms_add_member(parent_relids, appinfo->parent_relid); + } + + /* Recurse if immediate parent is not the top parent. */ + if (!bms_equal(parent_relids, top_parent_relids)) + { + tmp_result = adjust_child_relids_multilevel(root, relids, + parent_relids, + top_parent_relids); + relids = tmp_result; + } + + result = adjust_child_relids(relids, nappinfos, appinfos); + + /* Free memory consumed by any intermediate result. */ + if (tmp_result) + bms_free(tmp_result); + bms_free(parent_relids); + pfree(appinfos); + + return result; +} + +/* + * Adjust the targetlist entries of an inherited UPDATE operation + * + * The expressions have already been fixed, but we have to make sure that + * the target resnos match the child table (they may not, in the case of + * a column that was added after-the-fact by ALTER TABLE). In some cases + * this can force us to re-order the tlist to preserve resno ordering. + * (We do all this work in special cases so that preptlist.c is fast for + * the typical case.) + * + * The given tlist has already been through expression_tree_mutator; + * therefore the TargetEntry nodes are fresh copies that it's okay to + * scribble on. + * + * Note that this is not needed for INSERT because INSERT isn't inheritable. + */ +static List * +adjust_inherited_tlist(List *tlist, AppendRelInfo *context) +{ + bool changed_it = false; + ListCell *tl; + List *new_tlist; + bool more; + int attrno; + + /* This should only happen for an inheritance case, not UNION ALL */ + Assert(OidIsValid(context->parent_reloid)); + + /* Scan tlist and update resnos to match attnums of child rel */ + foreach(tl, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(tl); + Var *childvar; + + if (tle->resjunk) + continue; /* ignore junk items */ + + /* Look up the translation of this column: it must be a Var */ + if (tle->resno <= 0 || + tle->resno > list_length(context->translated_vars)) + elog(ERROR, "attribute %d of relation \"%s\" does not exist", + tle->resno, get_rel_name(context->parent_reloid)); + childvar = (Var *) list_nth(context->translated_vars, tle->resno - 1); + if (childvar == NULL || !IsA(childvar, Var)) + elog(ERROR, "attribute %d of relation \"%s\" does not exist", + tle->resno, get_rel_name(context->parent_reloid)); + + if (tle->resno != childvar->varattno) + { + tle->resno = childvar->varattno; + changed_it = true; + } + } + + /* + * If we changed anything, re-sort the tlist by resno, and make sure + * resjunk entries have resnos above the last real resno. The sort + * algorithm is a bit stupid, but for such a seldom-taken path, small is + * probably better than fast. + */ + if (!changed_it) + return tlist; + + new_tlist = NIL; + more = true; + for (attrno = 1; more; attrno++) + { + more = false; + foreach(tl, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(tl); + + if (tle->resjunk) + continue; /* ignore junk items */ + + if (tle->resno == attrno) + new_tlist = lappend(new_tlist, tle); + else if (tle->resno > attrno) + more = true; + } + } + + foreach(tl, tlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(tl); + + if (!tle->resjunk) + continue; /* here, ignore non-junk items */ + + tle->resno = attrno; + new_tlist = lappend(new_tlist, tle); + attrno++; + } + + return new_tlist; +} + +/* + * find_appinfos_by_relids + * Find AppendRelInfo structures for all relations specified by relids. + * + * The AppendRelInfos are returned in an array, which can be pfree'd by the + * caller. *nappinfos is set to the number of entries in the array. + */ +AppendRelInfo ** +find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos) +{ + AppendRelInfo **appinfos; + int cnt = 0; + int i; + + *nappinfos = bms_num_members(relids); + appinfos = (AppendRelInfo **) palloc(sizeof(AppendRelInfo *) * *nappinfos); + + i = -1; + while ((i = bms_next_member(relids, i)) >= 0) + { + AppendRelInfo *appinfo = root->append_rel_array[i]; + + if (!appinfo) + elog(ERROR, "child rel %d not found in append_rel_array", i); + + appinfos[cnt++] = appinfo; + } + return appinfos; +} diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index ed6b680ed86..a04b62274d2 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -3,7 +3,7 @@ * clauses.c * routines to manipulate qualification clauses * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,11 +32,12 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" +#include "optimizer/plancat.h" #include "optimizer/planmain.h" -#include "optimizer/prep.h" -#include "optimizer/var.h" #include "parser/analyze.h" #include "parser/parse_agg.h" #include "parser/parse_coerce.h" @@ -98,14 +99,14 @@ typedef struct static bool contain_agg_clause_walker(Node *node, void *context); static bool get_agg_clause_costs_walker(Node *node, - get_agg_clause_costs_context *context); + get_agg_clause_costs_context *context); static bool find_window_functions_walker(Node *node, WindowFuncLists *lists); static bool contain_subplans_walker(Node *node, void *context); static bool contain_mutable_functions_walker(Node *node, void *context); static bool contain_volatile_functions_walker(Node *node, void *context); static bool contain_volatile_functions_not_nextval_walker(Node *node, void *context); static bool max_parallel_hazard_walker(Node *node, - max_parallel_hazard_context *context); + max_parallel_hazard_context *context); static bool contain_nonstrict_functions_walker(Node *node, void *context); static bool contain_context_dependent_node(Node *clause); static bool contain_context_dependent_node_walker(Node *node, int *flags); @@ -114,291 +115,49 @@ static Relids find_nonnullable_rels_walker(Node *node, bool top_level); static List *find_nonnullable_vars_walker(Node *node, bool top_level); static bool is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK); static Node *eval_const_expressions_mutator(Node *node, - eval_const_expressions_context *context); + eval_const_expressions_context *context); static bool contain_non_const_walker(Node *node, void *context); static bool ece_function_is_safe(Oid funcid, - eval_const_expressions_context *context); + eval_const_expressions_context *context); static List *simplify_or_arguments(List *args, - eval_const_expressions_context *context, - bool *haveNull, bool *forceTrue); + eval_const_expressions_context *context, + bool *haveNull, bool *forceTrue); static List *simplify_and_arguments(List *args, - eval_const_expressions_context *context, - bool *haveNull, bool *forceFalse); + eval_const_expressions_context *context, + bool *haveNull, bool *forceFalse); static Node *simplify_boolean_equality(Oid opno, List *args); static Expr *simplify_function(Oid funcid, - Oid result_type, int32 result_typmod, - Oid result_collid, Oid input_collid, List **args_p, - bool funcvariadic, bool process_args, bool allow_non_const, - eval_const_expressions_context *context); -static List *expand_function_arguments(List *args, Oid result_type, - HeapTuple func_tuple); + Oid result_type, int32 result_typmod, + Oid result_collid, Oid input_collid, List **args_p, + bool funcvariadic, bool process_args, bool allow_non_const, + eval_const_expressions_context *context); static List *reorder_function_arguments(List *args, HeapTuple func_tuple); static List *add_function_defaults(List *args, HeapTuple func_tuple); static List *fetch_function_defaults(HeapTuple func_tuple); static void recheck_cast_function_args(List *args, Oid result_type, - HeapTuple func_tuple); + HeapTuple func_tuple); static Expr *evaluate_function(Oid funcid, Oid result_type, int32 result_typmod, - Oid result_collid, Oid input_collid, List *args, - bool funcvariadic, - HeapTuple func_tuple, - eval_const_expressions_context *context); + Oid result_collid, Oid input_collid, List *args, + bool funcvariadic, + HeapTuple func_tuple, + eval_const_expressions_context *context); static Expr *inline_function(Oid funcid, Oid result_type, Oid result_collid, - Oid input_collid, List *args, - bool funcvariadic, - HeapTuple func_tuple, - eval_const_expressions_context *context); + Oid input_collid, List *args, + bool funcvariadic, + HeapTuple func_tuple, + eval_const_expressions_context *context); static Node *substitute_actual_parameters(Node *expr, int nargs, List *args, - int *usecounts); + int *usecounts); static Node *substitute_actual_parameters_mutator(Node *node, - substitute_actual_parameters_context *context); + substitute_actual_parameters_context *context); static void sql_inline_error_callback(void *arg); -static Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, - Oid result_collation); static Query *substitute_actual_srf_parameters(Query *expr, - int nargs, List *args); + int nargs, List *args); static Node *substitute_actual_srf_parameters_mutator(Node *node, - substitute_actual_srf_parameters_context *context); + substitute_actual_srf_parameters_context *context); static bool tlist_matches_coltypelist(List *tlist, List *coltypelist); -/***************************************************************************** - * OPERATOR clause functions - *****************************************************************************/ - -/* - * make_opclause - * Creates an operator clause given its operator info, left operand - * and right operand (pass NULL to create single-operand clause), - * and collation info. - */ -Expr * -make_opclause(Oid opno, Oid opresulttype, bool opretset, - Expr *leftop, Expr *rightop, - Oid opcollid, Oid inputcollid) -{ - OpExpr *expr = makeNode(OpExpr); - - expr->opno = opno; - expr->opfuncid = InvalidOid; - expr->opresulttype = opresulttype; - expr->opretset = opretset; - expr->opcollid = opcollid; - expr->inputcollid = inputcollid; - if (rightop) - expr->args = list_make2(leftop, rightop); - else - expr->args = list_make1(leftop); - expr->location = -1; - return (Expr *) expr; -} - -/* - * get_leftop - * - * Returns the left operand of a clause of the form (op expr expr) - * or (op expr) - */ -Node * -get_leftop(const Expr *clause) -{ - const OpExpr *expr = (const OpExpr *) clause; - - if (expr->args != NIL) - return linitial(expr->args); - else - return NULL; -} - -/* - * get_rightop - * - * Returns the right operand in a clause of the form (op expr expr). - * NB: result will be NULL if applied to a unary op clause. - */ -Node * -get_rightop(const Expr *clause) -{ - const OpExpr *expr = (const OpExpr *) clause; - - if (list_length(expr->args) >= 2) - return lsecond(expr->args); - else - return NULL; -} - -/***************************************************************************** - * NOT clause functions - *****************************************************************************/ - -/* - * not_clause - * - * Returns t iff this is a 'not' clause: (NOT expr). - */ -bool -not_clause(Node *clause) -{ - return (clause != NULL && - IsA(clause, BoolExpr) && - ((BoolExpr *) clause)->boolop == NOT_EXPR); -} - -/* - * make_notclause - * - * Create a 'not' clause given the expression to be negated. - */ -Expr * -make_notclause(Expr *notclause) -{ - BoolExpr *expr = makeNode(BoolExpr); - - expr->boolop = NOT_EXPR; - expr->args = list_make1(notclause); - expr->location = -1; - return (Expr *) expr; -} - -/* - * get_notclausearg - * - * Retrieve the clause within a 'not' clause - */ -Expr * -get_notclausearg(Expr *notclause) -{ - return linitial(((BoolExpr *) notclause)->args); -} - -/***************************************************************************** - * OR clause functions - *****************************************************************************/ - -/* - * or_clause - * - * Returns t iff the clause is an 'or' clause: (OR { expr }). - */ -bool -or_clause(Node *clause) -{ - return (clause != NULL && - IsA(clause, BoolExpr) && - ((BoolExpr *) clause)->boolop == OR_EXPR); -} - -/* - * make_orclause - * - * Creates an 'or' clause given a list of its subclauses. - */ -Expr * -make_orclause(List *orclauses) -{ - BoolExpr *expr = makeNode(BoolExpr); - - expr->boolop = OR_EXPR; - expr->args = orclauses; - expr->location = -1; - return (Expr *) expr; -} - -/***************************************************************************** - * AND clause functions - *****************************************************************************/ - - -/* - * and_clause - * - * Returns t iff its argument is an 'and' clause: (AND { expr }). - */ -bool -and_clause(Node *clause) -{ - return (clause != NULL && - IsA(clause, BoolExpr) && - ((BoolExpr *) clause)->boolop == AND_EXPR); -} - -/* - * make_andclause - * - * Creates an 'and' clause given a list of its subclauses. - */ -Expr * -make_andclause(List *andclauses) -{ - BoolExpr *expr = makeNode(BoolExpr); - - expr->boolop = AND_EXPR; - expr->args = andclauses; - expr->location = -1; - return (Expr *) expr; -} - -/* - * make_and_qual - * - * Variant of make_andclause for ANDing two qual conditions together. - * Qual conditions have the property that a NULL nodetree is interpreted - * as 'true'. - * - * NB: this makes no attempt to preserve AND/OR flatness; so it should not - * be used on a qual that has already been run through prepqual.c. - */ -Node * -make_and_qual(Node *qual1, Node *qual2) -{ - if (qual1 == NULL) - return qual2; - if (qual2 == NULL) - return qual1; - return (Node *) make_andclause(list_make2(qual1, qual2)); -} - -/* - * The planner frequently prefers to represent qualification expressions - * as lists of boolean expressions with implicit AND semantics. - * - * These functions convert between an AND-semantics expression list and the - * ordinary representation of a boolean expression. - * - * Note that an empty list is considered equivalent to TRUE. - */ -Expr * -make_ands_explicit(List *andclauses) -{ - if (andclauses == NIL) - return (Expr *) makeBoolConst(true, false); - else if (list_length(andclauses) == 1) - return (Expr *) linitial(andclauses); - else - return make_andclause(andclauses); -} - -List * -make_ands_implicit(Expr *clause) -{ - /* - * NB: because the parser sets the qual field to NULL in a query that has - * no WHERE clause, we must consider a NULL input clause as TRUE, even - * though one might more reasonably think it FALSE. Grumble. If this - * causes trouble, consider changing the parser's behavior. - */ - if (clause == NULL) - return NIL; /* NULL -> NIL list == TRUE */ - else if (and_clause((Node *) clause)) - return ((BoolExpr *) clause)->args; - else if (IsA(clause, Const) && - !((Const *) clause)->constisnull && - DatumGetBool(((Const *) clause)->constvalue)) - return NIL; /* constant TRUE input -> NIL list */ - else - return list_make1(clause); -} - - /***************************************************************************** * Aggregate-function clause manipulation *****************************************************************************/ @@ -584,19 +343,24 @@ get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context) if (DO_AGGSPLIT_COMBINE(context->aggsplit)) { /* charge for combining previously aggregated states */ - costs->transCost.per_tuple += get_func_cost(aggcombinefn) * cpu_operator_cost; + add_function_cost(context->root, aggcombinefn, NULL, + &costs->transCost); } else - costs->transCost.per_tuple += get_func_cost(aggtransfn) * cpu_operator_cost; + add_function_cost(context->root, aggtransfn, NULL, + &costs->transCost); if (DO_AGGSPLIT_DESERIALIZE(context->aggsplit) && OidIsValid(aggdeserialfn)) - costs->transCost.per_tuple += get_func_cost(aggdeserialfn) * cpu_operator_cost; + add_function_cost(context->root, aggdeserialfn, NULL, + &costs->transCost); if (DO_AGGSPLIT_SERIALIZE(context->aggsplit) && OidIsValid(aggserialfn)) - costs->finalCost += get_func_cost(aggserialfn) * cpu_operator_cost; + add_function_cost(context->root, aggserialfn, NULL, + &costs->finalCost); if (!DO_AGGSPLIT_SKIPFINAL(context->aggsplit) && OidIsValid(aggfinalfn)) - costs->finalCost += get_func_cost(aggfinalfn) * cpu_operator_cost; + add_function_cost(context->root, aggfinalfn, NULL, + &costs->finalCost); /* * These costs are incurred only by the initial aggregate node, so we @@ -633,8 +397,8 @@ get_agg_clause_costs_walker(Node *node, get_agg_clause_costs_context *context) { cost_qual_eval_node(&argcosts, (Node *) aggref->aggdirectargs, context->root); - costs->transCost.startup += argcosts.startup; - costs->finalCost += argcosts.per_tuple; + costs->finalCost.startup += argcosts.startup; + costs->finalCost.per_tuple += argcosts.per_tuple; } /* @@ -802,7 +566,7 @@ find_window_functions_walker(Node *node, WindowFuncLists *lists) * Note: keep this in sync with expression_returns_set() in nodes/nodeFuncs.c. */ double -expression_returns_set_rows(Node *clause) +expression_returns_set_rows(PlannerInfo *root, Node *clause) { if (clause == NULL) return 1.0; @@ -811,7 +575,7 @@ expression_returns_set_rows(Node *clause) FuncExpr *expr = (FuncExpr *) clause; if (expr->funcretset) - return clamp_row_est(get_func_rows(expr->funcid)); + return clamp_row_est(get_function_rows(root, expr->funcid, clause)); } if (IsA(clause, OpExpr)) { @@ -820,7 +584,7 @@ expression_returns_set_rows(Node *clause) if (expr->opretset) { set_opfuncid(expr); - return clamp_row_est(get_func_rows(expr->opfuncid)); + return clamp_row_est(get_function_rows(root, expr->opfuncid, clause)); } } return 1.0; @@ -1117,11 +881,9 @@ is_parallel_safe(PlannerInfo *root, Node *node) foreach(l, proot->init_plans) { SubPlan *initsubplan = (SubPlan *) lfirst(l); - ListCell *l2; - foreach(l2, initsubplan->setParam) - context.safe_param_ids = lcons_int(lfirst_int(l2), - context.safe_param_ids); + context.safe_param_ids = list_concat(context.safe_param_ids, + initsubplan->setParam); } } @@ -1192,12 +954,26 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context) return true; } - if (IsA(node, NextValueExpr)) + else if (IsA(node, NextValueExpr)) { if (max_parallel_hazard_test(PROPARALLEL_UNSAFE, context)) return true; } + /* + * Treat window functions as parallel-restricted because we aren't sure + * whether the input row ordering is fully deterministic, and the output + * of window functions might vary across workers if not. (In some cases, + * like where the window frame orders by a primary key, we could relax + * this restriction. But it doesn't currently seem worth expending extra + * effort to do so.) + */ + else if (IsA(node, WindowFunc)) + { + if (max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) + return true; + } + /* * As a notational convenience for callers, look through RestrictInfo. */ @@ -1233,10 +1009,11 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context) max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) return true; save_safe_param_ids = context->safe_param_ids; - context->safe_param_ids = list_concat(list_copy(subplan->paramIds), - context->safe_param_ids); + context->safe_param_ids = list_concat_copy(context->safe_param_ids, + subplan->paramIds); if (max_parallel_hazard_walker(subplan->testexpr, context)) return true; /* no need to restore safe_param_ids */ + list_free(context->safe_param_ids); context->safe_param_ids = save_safe_param_ids; /* we must also check args, but no special Param treatment there */ if (max_parallel_hazard_walker((Node *) subplan->args, context)) @@ -1348,11 +1125,15 @@ contain_nonstrict_functions_walker(Node *node, void *context) /* a window function could return non-null with null input */ return true; } - if (IsA(node, ArrayRef)) + if (IsA(node, SubscriptingRef)) { - /* array assignment is nonstrict, but subscripting is strict */ - if (((ArrayRef *) node)->refassgnexpr != NULL) + /* + * subscripting assignment is nonstrict, but subscripting itself is + * strict + */ + if (((SubscriptingRef *) node)->refassgnexpr != NULL) return true; + /* else fall through to check args */ } if (IsA(node, DistinctExpr)) @@ -1390,6 +1171,16 @@ contain_nonstrict_functions_walker(Node *node, void *context) return true; if (IsA(node, FieldStore)) return true; + if (IsA(node, CoerceViaIO)) + { + /* + * CoerceViaIO is strict regardless of whether the I/O functions are, + * so just go look at its argument; asking check_functions_in_node is + * useless expense and could deliver the wrong answer. + */ + return contain_nonstrict_functions_walker((Node *) ((CoerceViaIO *) node)->arg, + context); + } if (IsA(node, ArrayCoerceExpr)) { /* @@ -1397,9 +1188,8 @@ contain_nonstrict_functions_walker(Node *node, void *context) * the per-element expression is; so we should ignore elemexpr and * recurse only into the arg. */ - return expression_tree_walker((Node *) ((ArrayCoerceExpr *) node)->arg, - contain_nonstrict_functions_walker, - context); + return contain_nonstrict_functions_walker((Node *) ((ArrayCoerceExpr *) node)->arg, + context); } if (IsA(node, CaseExpr)) return true; @@ -1440,7 +1230,8 @@ contain_nonstrict_functions_walker(Node *node, void *context) * CaseTestExpr nodes must appear directly within the corresponding CaseExpr, * not nested within another one, or they'll see the wrong test value. If one * appears "bare" in the arguments of a SQL function, then we can't inline the - * SQL function for fear of creating such a situation. + * SQL function for fear of creating such a situation. The same applies for + * CaseTestExpr used within the elemexpr of an ArrayCoerceExpr. * * CoerceToDomainValue would have the same issue if domain CHECK expressions * could get inlined into larger expressions, but presently that's impossible. @@ -1456,7 +1247,7 @@ contain_context_dependent_node(Node *clause) return contain_context_dependent_node_walker(clause, &flags); } -#define CCDN_IN_CASEEXPR 0x0001 /* CaseTestExpr okay here? */ +#define CCDN_CASETESTEXPR_OK 0x0001 /* CaseTestExpr okay here? */ static bool contain_context_dependent_node_walker(Node *node, int *flags) @@ -1464,8 +1255,8 @@ contain_context_dependent_node_walker(Node *node, int *flags) if (node == NULL) return false; if (IsA(node, CaseTestExpr)) - return !(*flags & CCDN_IN_CASEEXPR); - if (IsA(node, CaseExpr)) + return !(*flags & CCDN_CASETESTEXPR_OK); + else if (IsA(node, CaseExpr)) { CaseExpr *caseexpr = (CaseExpr *) node; @@ -1487,7 +1278,7 @@ contain_context_dependent_node_walker(Node *node, int *flags) * seem worth any extra code. If there are any bare CaseTestExprs * elsewhere in the CASE, something's wrong already. */ - *flags |= CCDN_IN_CASEEXPR; + *flags |= CCDN_CASETESTEXPR_OK; res = expression_tree_walker(node, contain_context_dependent_node_walker, (void *) flags); @@ -1495,6 +1286,24 @@ contain_context_dependent_node_walker(Node *node, int *flags) return res; } } + else if (IsA(node, ArrayCoerceExpr)) + { + ArrayCoerceExpr *ac = (ArrayCoerceExpr *) node; + int save_flags; + bool res; + + /* Check the array expression */ + if (contain_context_dependent_node_walker((Node *) ac->arg, flags)) + return true; + + /* Check the elemexpr, which is allowed to contain CaseTestExpr */ + save_flags = *flags; + *flags |= CCDN_CASETESTEXPR_OK; + res = contain_context_dependent_node_walker((Node *) ac->elemexpr, + flags); + *flags = save_flags; + return res; + } return expression_tree_walker(node, contain_context_dependent_node_walker, (void *) flags); } @@ -1537,7 +1346,6 @@ contain_leaked_vars_walker(Node *node, void *context) case T_Var: case T_Const: case T_Param: - case T_ArrayRef: case T_ArrayExpr: case T_FieldSelect: case T_FieldStore: @@ -1548,7 +1356,6 @@ contain_leaked_vars_walker(Node *node, void *context) case T_CaseExpr: case T_CaseTestExpr: case T_RowExpr: - case T_MinMaxExpr: case T_SQLValueFunction: case T_NullTest: case T_BooleanTest: @@ -1568,6 +1375,7 @@ contain_leaked_vars_walker(Node *node, void *context) case T_ScalarArrayOpExpr: case T_CoerceViaIO: case T_ArrayCoerceExpr: + case T_SubscriptingRef: /* * If node contains a leaky function call, and there's any Var @@ -1605,6 +1413,36 @@ contain_leaked_vars_walker(Node *node, void *context) } break; + case T_MinMaxExpr: + { + /* + * MinMaxExpr is leakproof if the comparison function it calls + * is leakproof. + */ + MinMaxExpr *minmaxexpr = (MinMaxExpr *) node; + TypeCacheEntry *typentry; + bool leakproof; + + /* Look up the btree comparison function for the datatype */ + typentry = lookup_type_cache(minmaxexpr->minmaxtype, + TYPECACHE_CMP_PROC); + if (OidIsValid(typentry->cmp_proc)) + leakproof = get_func_leakproof(typentry->cmp_proc); + else + { + /* + * The executor will throw an error, but here we just + * treat the missing function as leaky. + */ + leakproof = false; + } + + if (!leakproof && + contain_var_clause((Node *) minmaxexpr->args)) + return true; + } + break; + case T_CurrentOfExpr: /* @@ -1649,7 +1487,7 @@ contain_leaked_vars_walker(Node *node, void *context) * find_nonnullable_vars() is that the tested conditions really are different: * a clause like "t1.v1 IS NOT NULL OR t1.v2 IS NOT NULL" does not prove * that either v1 or v2 can't be NULL, but it does prove that the t1 row - * as a whole can't be all-NULL. + * as a whole can't be all-NULL. Also, the behavior for PHVs is different. * * top_level is true while scanning top-level AND/OR structure; here, showing * the result is either FALSE or NULL is good enough. top_level is false when @@ -1835,7 +1673,24 @@ find_nonnullable_rels_walker(Node *node, bool top_level) { PlaceHolderVar *phv = (PlaceHolderVar *) node; + /* + * If the contained expression forces any rels non-nullable, so does + * the PHV. + */ result = find_nonnullable_rels_walker((Node *) phv->phexpr, top_level); + + /* + * If the PHV's syntactic scope is exactly one rel, it will be forced + * to be evaluated at that rel, and so it will behave like a Var of + * that rel: if the rel's entire output goes to null, so will the PHV. + * (If the syntactic scope is a join, we know that the PHV will go to + * null if the whole join does; but that is AND semantics while we + * need OR semantics for find_nonnullable_rels' result, so we can't do + * anything with the knowledge.) + */ + if (phv->phlevelsup == 0 && + bms_membership(phv->phrels) == BMS_SINGLETON) + result = bms_add_members(result, phv->phrels); } return result; } @@ -2220,7 +2075,8 @@ is_strict_saop(ScalarArrayOpExpr *expr, bool falseOK) * Params and outer-level Vars, not to mention functions whose results * may vary from one statement to the next. However, the expr's value * will be constant over any one scan of the current query, so it can be - * used as, eg, an indexscan key. + * used as, eg, an indexscan key. (Actually, the condition for indexscan + * keys is weaker than this; see is_pseudo_constant_for_index().) * * CAUTION: this function omits to test for one very important class of * not-constant expressions, namely aggregates (Aggrefs). In current usage @@ -2315,71 +2171,6 @@ CommuteOpExpr(OpExpr *clause) lsecond(clause->args) = temp; } -/* - * CommuteRowCompareExpr: commute a RowCompareExpr clause - * - * XXX the clause is destructively modified! - */ -void -CommuteRowCompareExpr(RowCompareExpr *clause) -{ - List *newops; - List *temp; - ListCell *l; - - /* Sanity checks: caller is at fault if these fail */ - if (!IsA(clause, RowCompareExpr)) - elog(ERROR, "expected a RowCompareExpr"); - - /* Build list of commuted operators */ - newops = NIL; - foreach(l, clause->opnos) - { - Oid opoid = lfirst_oid(l); - - opoid = get_commutator(opoid); - if (!OidIsValid(opoid)) - elog(ERROR, "could not find commutator for operator %u", - lfirst_oid(l)); - newops = lappend_oid(newops, opoid); - } - - /* - * modify the clause in-place! - */ - switch (clause->rctype) - { - case ROWCOMPARE_LT: - clause->rctype = ROWCOMPARE_GT; - break; - case ROWCOMPARE_LE: - clause->rctype = ROWCOMPARE_GE; - break; - case ROWCOMPARE_GE: - clause->rctype = ROWCOMPARE_LE; - break; - case ROWCOMPARE_GT: - clause->rctype = ROWCOMPARE_LT; - break; - default: - elog(ERROR, "unexpected RowCompare type: %d", - (int) clause->rctype); - break; - } - - clause->opnos = newops; - - /* - * Note: we need not change the opfamilies list; we assume any btree - * opfamily containing an operator will also contain its commutator. - * Collations don't change either. - */ - - temp = clause->largs; - clause->largs = clause->rargs; - clause->rargs = temp; -} - /* * Helper for eval_const_expressions: check that datatype of an attribute * is still what it was when the expression was parsed. This is needed to @@ -2569,7 +2360,14 @@ eval_const_expressions_mutator(Node *node, else prm = ¶mLI->params[param->paramid - 1]; - if (OidIsValid(prm->ptype)) + /* + * We don't just check OidIsValid, but insist that the + * fetched type match the Param, just in case the hook did + * something unexpected. No need to throw an error here + * though; leave that for runtime. + */ + if (OidIsValid(prm->ptype) && + prm->ptype == param->paramtype) { /* OK to substitute parameter value? */ if (context->estimate || @@ -2585,7 +2383,6 @@ eval_const_expressions_mutator(Node *node, bool typByVal; Datum pval; - Assert(prm->ptype == param->paramtype); get_typlenbyval(param->paramtype, &typLen, &typByVal); if (prm->isnull || typByVal) @@ -3107,10 +2904,31 @@ eval_const_expressions_mutator(Node *node, } case T_ArrayCoerceExpr: { - ArrayCoerceExpr *ac; + ArrayCoerceExpr *ac = makeNode(ArrayCoerceExpr); + Node *save_case_val; - /* Copy the node and const-simplify its arguments */ - ac = (ArrayCoerceExpr *) ece_generic_processing(node); + /* + * Copy the node and const-simplify its arguments. We can't + * use ece_generic_processing() here because we need to mess + * with case_val only while processing the elemexpr. + */ + memcpy(ac, node, sizeof(ArrayCoerceExpr)); + ac->arg = (Expr *) + eval_const_expressions_mutator((Node *) ac->arg, + context); + + /* + * Set up for the CaseTestExpr node contained in the elemexpr. + * We must prevent it from absorbing any outer CASE value. + */ + save_case_val = context->case_val; + context->case_val = NULL; + + ac->elemexpr = (Expr *) + eval_const_expressions_mutator((Node *) ac->elemexpr, + context); + + context->case_val = save_case_val; /* * If constant argument and the per-element expression is @@ -3124,6 +2942,7 @@ eval_const_expressions_mutator(Node *node, ac->elemexpr && !IsA(ac->elemexpr, CoerceToDomain) && !contain_mutable_functions((Node *) ac->elemexpr)) return ece_evaluate_expr(ac); + return (Node *) ac; } case T_CollateExpr: @@ -3316,14 +3135,19 @@ eval_const_expressions_mutator(Node *node, else return copyObject(node); } - case T_ArrayRef: + case T_SubscriptingRef: case T_ArrayExpr: case T_RowExpr: + case T_MinMaxExpr: { /* * Generic handling for node types whose own processing is * known to be immutable, and for which we need no smarts * beyond "simplify if all inputs are constants". + * + * Treating MinMaxExpr this way amounts to assuming that the + * btree comparison function it calls is immutable; see the + * reasoning in contain_mutable_functions_walker. */ /* Copy the node and const-simplify its arguments */ @@ -3584,10 +3408,10 @@ eval_const_expressions_mutator(Node *node, { /* * This case could be folded into the generic handling used - * for ArrayRef etc. But because the simplification logic is - * so trivial, applying evaluate_expr() to perform it would be - * a heavy overhead. BooleanTest is probably common enough to - * justify keeping this bespoke implementation. + * for SubscriptingRef etc. But because the simplification + * logic is so trivial, applying evaluate_expr() to perform it + * would be a heavy overhead. BooleanTest is probably common + * enough to justify keeping this bespoke implementation. */ BooleanTest *btest = (BooleanTest *) node; BooleanTest *newbtest; @@ -3640,6 +3464,70 @@ eval_const_expressions_mutator(Node *node, newbtest->location = btest->location; return (Node *) newbtest; } + case T_CoerceToDomain: + { + /* + * If the domain currently has no constraints, we replace the + * CoerceToDomain node with a simple RelabelType, which is + * both far faster to execute and more amenable to later + * optimization. We must then mark the plan as needing to be + * rebuilt if the domain's constraints change. + * + * Also, in estimation mode, always replace CoerceToDomain + * nodes, effectively assuming that the coercion will succeed. + */ + CoerceToDomain *cdomain = (CoerceToDomain *) node; + CoerceToDomain *newcdomain; + Node *arg; + + arg = eval_const_expressions_mutator((Node *) cdomain->arg, + context); + if (context->estimate || + !DomainHasConstraints(cdomain->resulttype)) + { + /* Record dependency, if this isn't estimation mode */ + if (context->root && !context->estimate) + record_plan_type_dependency(context->root, + cdomain->resulttype); + + /* Generate RelabelType to substitute for CoerceToDomain */ + /* This should match the RelabelType logic above */ + + while (arg && IsA(arg, RelabelType)) + arg = (Node *) ((RelabelType *) arg)->arg; + + if (arg && IsA(arg, Const)) + { + Const *con = (Const *) arg; + + con->consttype = cdomain->resulttype; + con->consttypmod = cdomain->resulttypmod; + con->constcollid = cdomain->resultcollid; + return (Node *) con; + } + else + { + RelabelType *newrelabel = makeNode(RelabelType); + + newrelabel->arg = (Expr *) arg; + newrelabel->resulttype = cdomain->resulttype; + newrelabel->resulttypmod = cdomain->resulttypmod; + newrelabel->resultcollid = cdomain->resultcollid; + newrelabel->relabelformat = cdomain->coercionformat; + newrelabel->location = cdomain->location; + return (Node *) newrelabel; + } + } + + newcdomain = makeNode(CoerceToDomain); + newcdomain->arg = (Expr *) arg; + newcdomain->resulttype = cdomain->resulttype; + newcdomain->resulttypmod = cdomain->resulttypmod; + newcdomain->resultcollid = cdomain->resultcollid; + newcdomain->coercionformat = cdomain->coercionformat; + newcdomain->location = cdomain->location; + return (Node *) newcdomain; + } case T_PlaceHolderVar: /* @@ -3657,6 +3545,52 @@ eval_const_expressions_mutator(Node *node, context); } break; + case T_ConvertRowtypeExpr: + { + ConvertRowtypeExpr *cre = castNode(ConvertRowtypeExpr, node); + Node *arg; + ConvertRowtypeExpr *newcre; + + arg = eval_const_expressions_mutator((Node *) cre->arg, + context); + + newcre = makeNode(ConvertRowtypeExpr); + newcre->resulttype = cre->resulttype; + newcre->convertformat = cre->convertformat; + newcre->location = cre->location; + + /* + * In case of a nested ConvertRowtypeExpr, we can convert the + * leaf row directly to the topmost row format without any + * intermediate conversions. (This works because + * ConvertRowtypeExpr is used only for child->parent + * conversion in inheritance trees, which works by exact match + * of column name, and a column absent in an intermediate + * result can't be present in the final result.) + * + * No need to check more than one level deep, because the + * above recursion will have flattened anything else. + */ + if (arg != NULL && IsA(arg, ConvertRowtypeExpr)) + { + ConvertRowtypeExpr *argcre = (ConvertRowtypeExpr *) arg; + + arg = (Node *) argcre->arg; + + /* + * Make sure an outer implicit conversion can't hide an + * inner explicit one. + */ + if (newcre->convertformat == COERCE_IMPLICIT_CAST) + newcre->convertformat = argcre->convertformat; + } + + newcre->arg = (Expr *) arg; + + if (arg != NULL && IsA(arg, Const)) + return ece_evaluate_expr((Node *) newcre); + return (Node *) newcre; + } default: break; } @@ -3665,7 +3599,7 @@ eval_const_expressions_mutator(Node *node, * For any node type not handled above, copy the node unchanged but * const-simplify its subexpressions. This is the correct thing for node * types whose behavior might change between planning and execution, such - * as CoerceToDomain. It's also a safe default for new node types not + * as CurrentOfExpr. It's also a safe default for new node types not * known to this routine. */ return ece_generic_processing(node); @@ -3761,20 +3695,14 @@ simplify_or_arguments(List *args, unprocessed_args = list_delete_first(unprocessed_args); /* flatten nested ORs as per above comment */ - if (or_clause(arg)) + if (is_orclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; + List *oldlist = unprocessed_args; - /* overly tense code to avoid leaking unused list header */ - if (!unprocessed_args) - unprocessed_args = subargs; - else - { - List *oldhdr = unprocessed_args; - - unprocessed_args = list_concat(subargs, unprocessed_args); - pfree(oldhdr); - } + unprocessed_args = list_concat_copy(subargs, unprocessed_args); + /* perhaps-overly-tense code to avoid leaking old lists */ + list_free(oldlist); continue; } @@ -3784,14 +3712,14 @@ simplify_or_arguments(List *args, /* * It is unlikely but not impossible for simplification of a non-OR * clause to produce an OR. Recheck, but don't be too tense about it - * since it's not a mainstream case. In particular we don't worry - * about const-simplifying the input twice. + * since it's not a mainstream case. In particular we don't worry + * about const-simplifying the input twice, nor about list leakage. */ - if (or_clause(arg)) + if (is_orclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; - unprocessed_args = list_concat(subargs, unprocessed_args); + unprocessed_args = list_concat_copy(subargs, unprocessed_args); continue; } @@ -3863,20 +3791,14 @@ simplify_and_arguments(List *args, unprocessed_args = list_delete_first(unprocessed_args); /* flatten nested ANDs as per above comment */ - if (and_clause(arg)) + if (is_andclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; + List *oldlist = unprocessed_args; - /* overly tense code to avoid leaking unused list header */ - if (!unprocessed_args) - unprocessed_args = subargs; - else - { - List *oldhdr = unprocessed_args; - - unprocessed_args = list_concat(subargs, unprocessed_args); - pfree(oldhdr); - } + unprocessed_args = list_concat_copy(subargs, unprocessed_args); + /* perhaps-overly-tense code to avoid leaking old lists */ + list_free(oldlist); continue; } @@ -3886,14 +3808,14 @@ simplify_and_arguments(List *args, /* * It is unlikely but not impossible for simplification of a non-AND * clause to produce an AND. Recheck, but don't be too tense about it - * since it's not a mainstream case. In particular we don't worry - * about const-simplifying the input twice. + * since it's not a mainstream case. In particular we don't worry + * about const-simplifying the input twice, nor about list leakage. */ - if (and_clause(arg)) + if (is_andclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; - unprocessed_args = list_concat(subargs, unprocessed_args); + unprocessed_args = list_concat_copy(subargs, unprocessed_args); continue; } @@ -4066,13 +3988,16 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, args, funcvariadic, func_tuple, context); - if (!newexpr && allow_non_const && OidIsValid(func_form->protransform)) + if (!newexpr && allow_non_const && OidIsValid(func_form->prosupport)) { /* - * Build a dummy FuncExpr node containing the simplified arg list. We - * use this approach to present a uniform interface to the transform - * function regardless of how the function is actually being invoked. + * Build a SupportRequestSimplify node to pass to the support + * function, pointing to a dummy FuncExpr node containing the + * simplified arg list. We use this approach to present a uniform + * interface to the support function regardless of how the target + * function is actually being invoked. */ + SupportRequestSimplify req; FuncExpr fexpr; fexpr.xpr.type = T_FuncExpr; @@ -4086,9 +4011,16 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, fexpr.args = args; fexpr.location = -1; + req.type = T_SupportRequestSimplify; + req.root = context->root; + req.fcall = &fexpr; + newexpr = (Expr *) - DatumGetPointer(OidFunctionCall1(func_form->protransform, - PointerGetDatum(&fexpr))); + DatumGetPointer(OidFunctionCall1(func_form->prosupport, + PointerGetDatum(&req))); + + /* catch a possible API misunderstanding */ + Assert(newexpr != (Expr *) &fexpr); } if (!newexpr && allow_non_const) @@ -4112,7 +4044,7 @@ simplify_function(Oid funcid, Oid result_type, int32 result_typmod, * cases it handles should never occur there. This should be OK since it * will fall through very quickly if there's nothing to do. */ -static List * +List * expand_function_arguments(List *args, Oid result_type, HeapTuple func_tuple) { Form_pg_proc funcform = (Form_pg_proc) GETSTRUCT(func_tuple); @@ -4240,11 +4172,11 @@ add_function_defaults(List *args, HeapTuple func_tuple) ndelete = nargsprovided + list_length(defaults) - funcform->pronargs; if (ndelete < 0) elog(ERROR, "not enough default arguments"); - while (ndelete-- > 0) - defaults = list_delete_first(defaults); + if (ndelete > 0) + defaults = list_copy_tail(defaults, ndelete); /* And form the combined argument list, not modifying the input list */ - return list_concat(list_copy(args), defaults); + return list_concat_copy(args, defaults); } /* @@ -4756,9 +4688,9 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid, * Recursively try to simplify the modified expression. Here we must add * the current function to the context list of active functions. */ - context->active_fns = lcons_oid(funcid, context->active_fns); + context->active_fns = lappend_oid(context->active_fns, funcid); newexpr = eval_const_expressions_mutator(newexpr, context); - context->active_fns = list_delete_first(context->active_fns); + context->active_fns = list_delete_last(context->active_fns); error_context_stack = sqlerrcontext.previous; @@ -4842,7 +4774,7 @@ sql_inline_error_callback(void *arg) * We use the executor's routine ExecEvalExpr() to avoid duplication of * code and ensure we get the same result as the executor would get. */ -static Expr * +Expr * evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, Oid result_collation) { @@ -4926,6 +4858,10 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, * set-returning SQL function that can safely be inlined, expand the function * and return the substitute Query structure. Otherwise, return NULL. * + * We assume that the RTE's expression has already been put through + * eval_const_expressions(), which among other things will take care of + * default arguments and named-argument notation. + * * This has a good deal of similarity to inline_function(), but that's * for the non-set-returning case, and there are enough differences to * justify separate functions. @@ -4944,7 +4880,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) bool modifyTargetList; MemoryContext oldcxt; MemoryContext mycxt; - List *saveInvalItems; inline_error_callback_arg callback_arg; ErrorContextCallback sqlerrcontext; SQLFunctionParseInfoPtr pinfo; @@ -5022,7 +4957,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) * sharing the snapshot of the calling query. We also disallow returning * SETOF VOID, because inlining would result in exposing the actual result * of the function's last SELECT, which should not happen in that case. - * (Rechecking prokind and proretset is just paranoia.) + * (Rechecking prokind, proretset, and pronargs is just paranoia.) */ if (funcform->prolang != SQLlanguageId || funcform->prokind != PROKIND_FUNCTION || @@ -5031,6 +4966,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) funcform->prorettype == VOIDOID || funcform->prosecdef || !funcform->proretset || + list_length(fexpr->args) != funcform->pronargs || !heap_attisnull(func_tuple, Anum_pg_proc_proconfig, NULL)) { ReleaseSysCache(func_tuple); @@ -5046,16 +4982,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) ALLOCSET_DEFAULT_SIZES); oldcxt = MemoryContextSwitchTo(mycxt); - /* - * When we call eval_const_expressions below, it might try to add items to - * root->glob->invalItems. Since it is running in the temp context, those - * items will be in that context, and will need to be copied out if we're - * successful. Temporarily reset the list so that we can keep those items - * separate from the pre-existing list contents. - */ - saveInvalItems = root->glob->invalItems; - root->glob->invalItems = NIL; - /* Fetch the function body */ tmp = SysCacheGetAttr(PROCOID, func_tuple, @@ -5077,24 +5003,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) sqlerrcontext.previous = error_context_stack; error_context_stack = &sqlerrcontext; - /* - * Run eval_const_expressions on the function call. This is necessary to - * ensure that named-argument notation is converted to positional notation - * and any default arguments are inserted. It's a bit of overkill for the - * arguments, since they'll get processed again later, but no harm will be - * done. - */ - fexpr = (FuncExpr *) eval_const_expressions(root, (Node *) fexpr); - - /* It should still be a call of the same function, but let's check */ - if (!IsA(fexpr, FuncExpr) || - fexpr->funcid != func_oid) - goto fail; - - /* Arg list length should now match the function */ - if (list_length(fexpr->args) != funcform->pronargs) - goto fail; - /* * Set up to handle parameters while parsing the function body. We can * use the FuncExpr just created as the input for @@ -5185,10 +5093,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) querytree = copyObject(querytree); - /* copy up any new invalItems, too */ - root->glob->invalItems = list_concat(saveInvalItems, - copyObject(root->glob->invalItems)); - MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); @@ -5209,7 +5113,6 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte) /* Here if func is not inlinable: release temp memory and return NULL */ fail: MemoryContextSwitchTo(oldcxt); - root->glob->invalItems = saveInvalItems; MemoryContextDelete(mycxt); error_context_stack = sqlerrcontext.previous; ReleaseSysCache(func_tuple); @@ -5310,7 +5213,7 @@ tlist_matches_coltypelist(List *tlist, List *coltypelist) return false; /* too many tlist items */ coltype = lfirst_oid(clistitem); - clistitem = lnext(clistitem); + clistitem = lnext(coltypelist, clistitem); if (exprType((Node *) tle->expr) != coltype) return false; /* column type mismatch */ diff --git a/src/backend/optimizer/util/inherit.c b/src/backend/optimizer/util/inherit.c new file mode 100644 index 00000000000..38bc61e6878 --- /dev/null +++ b/src/backend/optimizer/util/inherit.c @@ -0,0 +1,740 @@ +/*------------------------------------------------------------------------- + * + * inherit.c + * Routines to process child relations in inheritance trees + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/optimizer/path/inherit.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/sysattr.h" +#include "access/table.h" +#include "catalog/partition.h" +#include "catalog/pg_inherits.h" +#include "catalog/pg_type.h" +#include "miscadmin.h" +#include "nodes/makefuncs.h" +#include "optimizer/appendinfo.h" +#include "optimizer/inherit.h" +#include "optimizer/optimizer.h" +#include "optimizer/pathnode.h" +#include "optimizer/planmain.h" +#include "optimizer/planner.h" +#include "optimizer/prep.h" +#include "optimizer/restrictinfo.h" +#include "parser/parsetree.h" +#include "partitioning/partdesc.h" +#include "partitioning/partprune.h" +#include "utils/rel.h" + + +static void expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo, + RangeTblEntry *parentrte, + Index parentRTindex, Relation parentrel, + PlanRowMark *top_parentrc, LOCKMODE lockmode); +static void expand_single_inheritance_child(PlannerInfo *root, + RangeTblEntry *parentrte, + Index parentRTindex, Relation parentrel, + PlanRowMark *top_parentrc, Relation childrel, + RangeTblEntry **childrte_p, + Index *childRTindex_p); +static Bitmapset *translate_col_privs(const Bitmapset *parent_privs, + List *translated_vars); +static void expand_appendrel_subquery(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte, Index rti); + + +/* + * expand_inherited_rtentry + * Expand a rangetable entry that has the "inh" bit set. + * + * "inh" is only allowed in two cases: RELATION and SUBQUERY RTEs. + * + * "inh" on a plain RELATION RTE means that it is a partitioned table or the + * parent of a traditional-inheritance set. In this case we must add entries + * for all the interesting child tables to the query's rangetable, and build + * additional planner data structures for them, including RelOptInfos, + * AppendRelInfos, and possibly PlanRowMarks. + * + * Note that the original RTE is considered to represent the whole inheritance + * set. In the case of traditional inheritance, the first of the generated + * RTEs is an RTE for the same table, but with inh = false, to represent the + * parent table in its role as a simple member of the inheritance set. For + * partitioning, we don't need a second RTE because the partitioned table + * itself has no data and need not be scanned. + * + * "inh" on a SUBQUERY RTE means that it's the parent of a UNION ALL group, + * which is treated as an appendrel similarly to inheritance cases; however, + * we already made RTEs and AppendRelInfos for the subqueries. We only need + * to build RelOptInfos for them, which is done by expand_appendrel_subquery. + */ +void +expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte, Index rti) +{ + Oid parentOID; + Relation oldrelation; + LOCKMODE lockmode; + PlanRowMark *oldrc; + bool old_isParent = false; + int old_allMarkTypes = 0; + + Assert(rte->inh); /* else caller error */ + + if (rte->rtekind == RTE_SUBQUERY) + { + expand_appendrel_subquery(root, rel, rte, rti); + return; + } + + Assert(rte->rtekind == RTE_RELATION); + + parentOID = rte->relid; + + /* + * We used to check has_subclass() here, but there's no longer any need + * to, because subquery_planner already did. + */ + + /* + * The rewriter should already have obtained an appropriate lock on each + * relation named in the query, so we can open the parent relation without + * locking it. However, for each child relation we add to the query, we + * must obtain an appropriate lock, because this will be the first use of + * those relations in the parse/rewrite/plan pipeline. Child rels should + * use the same lockmode as their parent. + */ + oldrelation = table_open(parentOID, NoLock); + lockmode = rte->rellockmode; + + /* + * If parent relation is selected FOR UPDATE/SHARE, we need to mark its + * PlanRowMark as isParent = true, and generate a new PlanRowMark for each + * child. + */ + oldrc = get_plan_rowmark(root->rowMarks, rti); + if (oldrc) + { + old_isParent = oldrc->isParent; + oldrc->isParent = true; + /* Save initial value of allMarkTypes before children add to it */ + old_allMarkTypes = oldrc->allMarkTypes; + } + + /* Scan the inheritance set and expand it */ + if (oldrelation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + { + /* + * Partitioned table, so set up for partitioning. + */ + Assert(rte->relkind == RELKIND_PARTITIONED_TABLE); + + /* + * Recursively expand and lock the partitions. While at it, also + * extract the partition key columns of all the partitioned tables. + */ + expand_partitioned_rtentry(root, rel, rte, rti, + oldrelation, oldrc, lockmode); + } + else + { + /* + * Ordinary table, so process traditional-inheritance children. (Note + * that partitioned tables are not allowed to have inheritance + * children, so it's not possible for both cases to apply.) + */ + List *inhOIDs; + ListCell *l; + + /* Scan for all members of inheritance set, acquire needed locks */ + inhOIDs = find_all_inheritors(parentOID, lockmode, NULL); + + /* + * We used to special-case the situation where the table no longer has + * any children, by clearing rte->inh and exiting. That no longer + * works, because this function doesn't get run until after decisions + * have been made that depend on rte->inh. We have to treat such + * situations as normal inheritance. The table itself should always + * have been found, though. + */ + Assert(inhOIDs != NIL); + Assert(linitial_oid(inhOIDs) == parentOID); + + /* Expand simple_rel_array and friends to hold child objects. */ + expand_planner_arrays(root, list_length(inhOIDs)); + + /* + * Expand inheritance children in the order the OIDs were returned by + * find_all_inheritors. + */ + foreach(l, inhOIDs) + { + Oid childOID = lfirst_oid(l); + Relation newrelation; + RangeTblEntry *childrte; + Index childRTindex; + + /* Open rel if needed; we already have required locks */ + if (childOID != parentOID) + newrelation = table_open(childOID, NoLock); + else + newrelation = oldrelation; + + /* + * It is possible that the parent table has children that are temp + * tables of other backends. We cannot safely access such tables + * (because of buffering issues), and the best thing to do seems + * to be to silently ignore them. + */ + if (childOID != parentOID && RELATION_IS_OTHER_TEMP(newrelation)) + { + table_close(newrelation, lockmode); + continue; + } + + /* Create RTE and AppendRelInfo, plus PlanRowMark if needed. */ + expand_single_inheritance_child(root, rte, rti, oldrelation, + oldrc, newrelation, + &childrte, &childRTindex); + + /* Create the otherrel RelOptInfo too. */ + (void) build_simple_rel(root, childRTindex, rel); + + /* Close child relations, but keep locks */ + if (childOID != parentOID) + table_close(newrelation, NoLock); + } + } + + /* + * Some children might require different mark types, which would've been + * reported into oldrc. If so, add relevant entries to the top-level + * targetlist and update parent rel's reltarget. This should match what + * preprocess_targetlist() would have added if the mark types had been + * requested originally. + */ + if (oldrc) + { + int new_allMarkTypes = oldrc->allMarkTypes; + Var *var; + TargetEntry *tle; + char resname[32]; + List *newvars = NIL; + + /* The old PlanRowMark should already have necessitated adding TID */ + Assert(old_allMarkTypes & ~(1 << ROW_MARK_COPY)); + + /* Add whole-row junk Var if needed, unless we had it already */ + if ((new_allMarkTypes & (1 << ROW_MARK_COPY)) && + !(old_allMarkTypes & (1 << ROW_MARK_COPY))) + { + var = makeWholeRowVar(planner_rt_fetch(oldrc->rti, root), + oldrc->rti, + 0, + false); + snprintf(resname, sizeof(resname), "wholerow%u", oldrc->rowmarkId); + tle = makeTargetEntry((Expr *) var, + list_length(root->processed_tlist) + 1, + pstrdup(resname), + true); + root->processed_tlist = lappend(root->processed_tlist, tle); + newvars = lappend(newvars, var); + } + + /* Add tableoid junk Var, unless we had it already */ + if (!old_isParent) + { + var = makeVar(oldrc->rti, + TableOidAttributeNumber, + OIDOID, + -1, + InvalidOid, + 0); + snprintf(resname, sizeof(resname), "tableoid%u", oldrc->rowmarkId); + tle = makeTargetEntry((Expr *) var, + list_length(root->processed_tlist) + 1, + pstrdup(resname), + true); + root->processed_tlist = lappend(root->processed_tlist, tle); + newvars = lappend(newvars, var); + } + + /* + * Add the newly added Vars to parent's reltarget. We needn't worry + * about the children's reltargets, they'll be made later. + */ + add_vars_to_targetlist(root, newvars, bms_make_singleton(0), false); + } + + table_close(oldrelation, NoLock); +} + +/* + * expand_partitioned_rtentry + * Recursively expand an RTE for a partitioned table. + */ +static void +expand_partitioned_rtentry(PlannerInfo *root, RelOptInfo *relinfo, + RangeTblEntry *parentrte, + Index parentRTindex, Relation parentrel, + PlanRowMark *top_parentrc, LOCKMODE lockmode) +{ + PartitionDesc partdesc; + Bitmapset *live_parts; + int num_live_parts; + int i; + + check_stack_depth(); + + Assert(parentrte->inh); + + partdesc = PartitionDirectoryLookup(root->glob->partition_directory, + parentrel); + + /* A partitioned table should always have a partition descriptor. */ + Assert(partdesc); + + /* + * Note down whether any partition key cols are being updated. Though it's + * the root partitioned table's updatedCols we are interested in, we + * instead use parentrte to get the updatedCols. This is convenient + * because parentrte already has the root partrel's updatedCols translated + * to match the attribute ordering of parentrel. + */ + if (!root->partColsUpdated) + root->partColsUpdated = + has_partition_attrs(parentrel, parentrte->updatedCols, NULL); + + /* + * There shouldn't be any generated columns in the partition key. + */ + Assert(!has_partition_attrs(parentrel, parentrte->extraUpdatedCols, NULL)); + + /* Nothing further to do here if there are no partitions. */ + if (partdesc->nparts == 0) + return; + + /* + * Perform partition pruning using restriction clauses assigned to parent + * relation. live_parts will contain PartitionDesc indexes of partitions + * that survive pruning. Below, we will initialize child objects for the + * surviving partitions. + */ + live_parts = prune_append_rel_partitions(relinfo); + + /* Expand simple_rel_array and friends to hold child objects. */ + num_live_parts = bms_num_members(live_parts); + if (num_live_parts > 0) + expand_planner_arrays(root, num_live_parts); + + /* + * We also store partition RelOptInfo pointers in the parent relation. + * Since we're palloc0'ing, slots corresponding to pruned partitions will + * contain NULL. + */ + Assert(relinfo->part_rels == NULL); + relinfo->part_rels = (RelOptInfo **) + palloc0(relinfo->nparts * sizeof(RelOptInfo *)); + + /* + * Create a child RTE for each live partition. Note that unlike + * traditional inheritance, we don't need a child RTE for the partitioned + * table itself, because it's not going to be scanned. + */ + i = -1; + while ((i = bms_next_member(live_parts, i)) >= 0) + { + Oid childOID = partdesc->oids[i]; + Relation childrel; + RangeTblEntry *childrte; + Index childRTindex; + RelOptInfo *childrelinfo; + + /* Open rel, acquiring required locks */ + childrel = table_open(childOID, lockmode); + + /* + * Temporary partitions belonging to other sessions should have been + * disallowed at definition, but for paranoia's sake, let's double + * check. + */ + if (RELATION_IS_OTHER_TEMP(childrel)) + elog(ERROR, "temporary relation from another session found as partition"); + + /* Create RTE and AppendRelInfo, plus PlanRowMark if needed. */ + expand_single_inheritance_child(root, parentrte, parentRTindex, + parentrel, top_parentrc, childrel, + &childrte, &childRTindex); + + /* Create the otherrel RelOptInfo too. */ + childrelinfo = build_simple_rel(root, childRTindex, relinfo); + relinfo->part_rels[i] = childrelinfo; + + /* If this child is itself partitioned, recurse */ + if (childrel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + expand_partitioned_rtentry(root, childrelinfo, + childrte, childRTindex, + childrel, top_parentrc, lockmode); + + /* Close child relation, but keep locks */ + table_close(childrel, NoLock); + } +} + +/* + * expand_single_inheritance_child + * Build a RangeTblEntry and an AppendRelInfo, plus maybe a PlanRowMark. + * + * We now expand the partition hierarchy level by level, creating a + * corresponding hierarchy of AppendRelInfos and RelOptInfos, where each + * partitioned descendant acts as a parent of its immediate partitions. + * (This is a difference from what older versions of PostgreSQL did and what + * is still done in the case of table inheritance for unpartitioned tables, + * where the hierarchy is flattened during RTE expansion.) + * + * PlanRowMarks still carry the top-parent's RTI, and the top-parent's + * allMarkTypes field still accumulates values from all descendents. + * + * "parentrte" and "parentRTindex" are immediate parent's RTE and + * RTI. "top_parentrc" is top parent's PlanRowMark. + * + * The child RangeTblEntry and its RTI are returned in "childrte_p" and + * "childRTindex_p" resp. + */ +static void +expand_single_inheritance_child(PlannerInfo *root, RangeTblEntry *parentrte, + Index parentRTindex, Relation parentrel, + PlanRowMark *top_parentrc, Relation childrel, + RangeTblEntry **childrte_p, + Index *childRTindex_p) +{ + Query *parse = root->parse; + Oid parentOID = RelationGetRelid(parentrel); + Oid childOID = RelationGetRelid(childrel); + RangeTblEntry *childrte; + Index childRTindex; + AppendRelInfo *appinfo; + + /* + * Build an RTE for the child, and attach to query's rangetable list. We + * copy most fields of the parent's RTE, but replace relation OID, + * relkind, and inh for the child. Also, set requiredPerms to zero since + * all required permissions checks are done on the original RTE. Likewise, + * set the child's securityQuals to empty, because we only want to apply + * the parent's RLS conditions regardless of what RLS properties + * individual children may have. (This is an intentional choice to make + * inherited RLS work like regular permissions checks.) The parent + * securityQuals will be propagated to children along with other base + * restriction clauses, so we don't need to do it here. + */ + childrte = copyObject(parentrte); + *childrte_p = childrte; + childrte->relid = childOID; + childrte->relkind = childrel->rd_rel->relkind; + /* A partitioned child will need to be expanded further. */ + if (childrte->relkind == RELKIND_PARTITIONED_TABLE) + { + Assert(childOID != parentOID); + childrte->inh = true; + } + else + childrte->inh = false; + childrte->requiredPerms = 0; + childrte->securityQuals = NIL; + parse->rtable = lappend(parse->rtable, childrte); + childRTindex = list_length(parse->rtable); + *childRTindex_p = childRTindex; + + /* + * Build an AppendRelInfo struct for each parent/child pair. + */ + appinfo = make_append_rel_info(parentrel, childrel, + parentRTindex, childRTindex); + root->append_rel_list = lappend(root->append_rel_list, appinfo); + + /* + * Translate the column permissions bitmaps to the child's attnums (we + * have to build the translated_vars list before we can do this). But if + * this is the parent table, we can leave copyObject's result alone. + * + * Note: we need to do this even though the executor won't run any + * permissions checks on the child RTE. The insertedCols/updatedCols + * bitmaps may be examined for trigger-firing purposes. + */ + if (childOID != parentOID) + { + childrte->selectedCols = translate_col_privs(parentrte->selectedCols, + appinfo->translated_vars); + childrte->insertedCols = translate_col_privs(parentrte->insertedCols, + appinfo->translated_vars); + childrte->updatedCols = translate_col_privs(parentrte->updatedCols, + appinfo->translated_vars); + childrte->extraUpdatedCols = translate_col_privs(parentrte->extraUpdatedCols, + appinfo->translated_vars); + } + + /* + * Store the RTE and appinfo in the respective PlannerInfo arrays, which + * the caller must already have allocated space for. + */ + Assert(childRTindex < root->simple_rel_array_size); + Assert(root->simple_rte_array[childRTindex] == NULL); + root->simple_rte_array[childRTindex] = childrte; + Assert(root->append_rel_array[childRTindex] == NULL); + root->append_rel_array[childRTindex] = appinfo; + + /* + * Build a PlanRowMark if parent is marked FOR UPDATE/SHARE. + */ + if (top_parentrc) + { + PlanRowMark *childrc = makeNode(PlanRowMark); + + childrc->rti = childRTindex; + childrc->prti = top_parentrc->rti; + childrc->rowmarkId = top_parentrc->rowmarkId; + /* Reselect rowmark type, because relkind might not match parent */ + childrc->markType = select_rowmark_type(childrte, + top_parentrc->strength); + childrc->allMarkTypes = (1 << childrc->markType); + childrc->strength = top_parentrc->strength; + childrc->waitPolicy = top_parentrc->waitPolicy; + + /* + * We mark RowMarks for partitioned child tables as parent RowMarks so + * that the executor ignores them (except their existence means that + * the child tables will be locked using the appropriate mode). + */ + childrc->isParent = (childrte->relkind == RELKIND_PARTITIONED_TABLE); + + /* Include child's rowmark type in top parent's allMarkTypes */ + top_parentrc->allMarkTypes |= childrc->allMarkTypes; + + root->rowMarks = lappend(root->rowMarks, childrc); + } +} + +/* + * translate_col_privs + * Translate a bitmapset representing per-column privileges from the + * parent rel's attribute numbering to the child's. + * + * The only surprise here is that we don't translate a parent whole-row + * reference into a child whole-row reference. That would mean requiring + * permissions on all child columns, which is overly strict, since the + * query is really only going to reference the inherited columns. Instead + * we set the per-column bits for all inherited columns. + */ +static Bitmapset * +translate_col_privs(const Bitmapset *parent_privs, + List *translated_vars) +{ + Bitmapset *child_privs = NULL; + bool whole_row; + int attno; + ListCell *lc; + + /* System attributes have the same numbers in all tables */ + for (attno = FirstLowInvalidHeapAttributeNumber + 1; attno < 0; attno++) + { + if (bms_is_member(attno - FirstLowInvalidHeapAttributeNumber, + parent_privs)) + child_privs = bms_add_member(child_privs, + attno - FirstLowInvalidHeapAttributeNumber); + } + + /* Check if parent has whole-row reference */ + whole_row = bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber, + parent_privs); + + /* And now translate the regular user attributes, using the vars list */ + attno = InvalidAttrNumber; + foreach(lc, translated_vars) + { + Var *var = lfirst_node(Var, lc); + + attno++; + if (var == NULL) /* ignore dropped columns */ + continue; + if (whole_row || + bms_is_member(attno - FirstLowInvalidHeapAttributeNumber, + parent_privs)) + child_privs = bms_add_member(child_privs, + var->varattno - FirstLowInvalidHeapAttributeNumber); + } + + return child_privs; +} + +/* + * expand_appendrel_subquery + * Add "other rel" RelOptInfos for the children of an appendrel baserel + * + * "rel" is a subquery relation that has the rte->inh flag set, meaning it + * is a UNION ALL subquery that's been flattened into an appendrel, with + * child subqueries listed in root->append_rel_list. We need to build + * a RelOptInfo for each child relation so that we can plan scans on them. + */ +static void +expand_appendrel_subquery(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte, Index rti) +{ + ListCell *l; + + foreach(l, root->append_rel_list) + { + AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l); + Index childRTindex = appinfo->child_relid; + RangeTblEntry *childrte; + RelOptInfo *childrel; + + /* append_rel_list contains all append rels; ignore others */ + if (appinfo->parent_relid != rti) + continue; + + /* find the child RTE, which should already exist */ + Assert(childRTindex < root->simple_rel_array_size); + childrte = root->simple_rte_array[childRTindex]; + Assert(childrte != NULL); + + /* Build the child RelOptInfo. */ + childrel = build_simple_rel(root, childRTindex, rel); + + /* Child may itself be an inherited rel, either table or subquery. */ + if (childrte->inh) + expand_inherited_rtentry(root, childrel, childrte, childRTindex); + } +} + + +/* + * apply_child_basequals + * Populate childrel's base restriction quals from parent rel's quals, + * translating them using appinfo. + * + * If any of the resulting clauses evaluate to constant false or NULL, we + * return false and don't apply any quals. Caller should mark the relation as + * a dummy rel in this case, since it doesn't need to be scanned. + */ +bool +apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, + RelOptInfo *childrel, RangeTblEntry *childRTE, + AppendRelInfo *appinfo) +{ + List *childquals; + Index cq_min_security; + ListCell *lc; + + /* + * The child rel's targetlist might contain non-Var expressions, which + * means that substitution into the quals could produce opportunities for + * const-simplification, and perhaps even pseudoconstant quals. Therefore, + * transform each RestrictInfo separately to see if it reduces to a + * constant or pseudoconstant. (We must process them separately to keep + * track of the security level of each qual.) + */ + childquals = NIL; + cq_min_security = UINT_MAX; + foreach(lc, parentrel->baserestrictinfo) + { + RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); + Node *childqual; + ListCell *lc2; + + Assert(IsA(rinfo, RestrictInfo)); + childqual = adjust_appendrel_attrs(root, + (Node *) rinfo->clause, + 1, &appinfo); + childqual = eval_const_expressions(root, childqual); + /* check for flat-out constant */ + if (childqual && IsA(childqual, Const)) + { + if (((Const *) childqual)->constisnull || + !DatumGetBool(((Const *) childqual)->constvalue)) + { + /* Restriction reduces to constant FALSE or NULL */ + return false; + } + /* Restriction reduces to constant TRUE, so drop it */ + continue; + } + /* might have gotten an AND clause, if so flatten it */ + foreach(lc2, make_ands_implicit((Expr *) childqual)) + { + Node *onecq = (Node *) lfirst(lc2); + bool pseudoconstant; + + /* check for pseudoconstant (no Vars or volatile functions) */ + pseudoconstant = + !contain_vars_of_level(onecq, 0) && + !contain_volatile_functions(onecq); + if (pseudoconstant) + { + /* tell createplan.c to check for gating quals */ + root->hasPseudoConstantQuals = true; + } + /* reconstitute RestrictInfo with appropriate properties */ + childquals = lappend(childquals, + make_restrictinfo((Expr *) onecq, + rinfo->is_pushed_down, + rinfo->outerjoin_delayed, + pseudoconstant, + rinfo->security_level, + NULL, NULL, NULL)); + /* track minimum security level among child quals */ + cq_min_security = Min(cq_min_security, rinfo->security_level); + } + } + + /* + * In addition to the quals inherited from the parent, we might have + * securityQuals associated with this particular child node. (Currently + * this can only happen in appendrels originating from UNION ALL; + * inheritance child tables don't have their own securityQuals, see + * expand_single_inheritance_child().) Pull any such securityQuals up + * into the baserestrictinfo for the child. This is similar to + * process_security_barrier_quals() for the parent rel, except that we + * can't make any general deductions from such quals, since they don't + * hold for the whole appendrel. + */ + if (childRTE->securityQuals) + { + Index security_level = 0; + + foreach(lc, childRTE->securityQuals) + { + List *qualset = (List *) lfirst(lc); + ListCell *lc2; + + foreach(lc2, qualset) + { + Expr *qual = (Expr *) lfirst(lc2); + + /* not likely that we'd see constants here, so no check */ + childquals = lappend(childquals, + make_restrictinfo(qual, + true, false, false, + security_level, + NULL, NULL, NULL)); + cq_min_security = Min(cq_min_security, security_level); + } + security_level++; + } + Assert(security_level <= root->qual_security_level); + } + + /* + * OK, we've got all the baserestrictinfo quals for this child. + */ + childrel->baserestrictinfo = childquals; + childrel->baserestrict_min_security = cq_min_security; + + return true; +} diff --git a/src/backend/optimizer/util/joininfo.c b/src/backend/optimizer/util/joininfo.c index 3aaa0042754..09aea210850 100644 --- a/src/backend/optimizer/util/joininfo.c +++ b/src/backend/optimizer/util/joininfo.c @@ -3,7 +3,7 @@ * joininfo.c * joininfo list manipulation routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c index 1e78028abee..412a3964c30 100644 --- a/src/backend/optimizer/util/orclauses.c +++ b/src/backend/optimizer/util/orclauses.c @@ -3,7 +3,7 @@ * orclauses.c * Routines to extract restriction OR clauses from join OR clauses * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,8 +15,11 @@ #include "postgres.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/orclauses.h" #include "optimizer/restrictinfo.h" @@ -24,7 +27,7 @@ static bool is_safe_restriction_clause_for(RestrictInfo *rinfo, RelOptInfo *rel); static Expr *extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel); static void consider_new_or_clause(PlannerInfo *root, RelOptInfo *rel, - Expr *orclause, RestrictInfo *join_or_rinfo); + Expr *orclause, RestrictInfo *join_or_rinfo); /* @@ -173,7 +176,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) * selectivity and other cached data is computed exactly the same way for * a restriction clause as for a join clause, which seems undesirable. */ - Assert(or_clause((Node *) or_rinfo->orclause)); + Assert(is_orclause(or_rinfo->orclause)); foreach(lc, ((BoolExpr *) or_rinfo->orclause)->args) { Node *orarg = (Node *) lfirst(lc); @@ -181,7 +184,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) Node *subclause; /* OR arguments should be ANDs or sub-RestrictInfos */ - if (and_clause(orarg)) + if (is_andclause(orarg)) { List *andargs = ((BoolExpr *) orarg)->args; ListCell *lc2; @@ -231,9 +234,9 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) * to preserve AND/OR flatness (ie, no OR directly underneath OR). */ subclause = (Node *) make_ands_explicit(subclauses); - if (or_clause(subclause)) + if (is_orclause(subclause)) clauselist = list_concat(clauselist, - list_copy(((BoolExpr *) subclause)->args)); + ((BoolExpr *) subclause)->args); else clauselist = lappend(clauselist, subclause); } diff --git a/src/backend/optimizer/util/paramassign.c b/src/backend/optimizer/util/paramassign.c new file mode 100644 index 00000000000..536d80a2756 --- /dev/null +++ b/src/backend/optimizer/util/paramassign.c @@ -0,0 +1,592 @@ +/*------------------------------------------------------------------------- + * + * paramassign.c + * Functions for assigning PARAM_EXEC slots during planning. + * + * This module is responsible for managing three planner data structures: + * + * root->glob->paramExecTypes: records actual assignments of PARAM_EXEC slots. + * The i'th list element holds the data type OID of the i'th parameter slot. + * (Elements can be InvalidOid if they represent slots that are needed for + * chgParam signaling, but will never hold a value at runtime.) This list is + * global to the whole plan since the executor has only one PARAM_EXEC array. + * Assignments are permanent for the plan: we never remove entries once added. + * + * root->plan_params: a list of PlannerParamItem nodes, recording Vars and + * PlaceHolderVars that the root's query level needs to supply to lower-level + * subqueries, along with the PARAM_EXEC number to use for each such value. + * Elements are added to this list while planning a subquery, and the list + * is reset to empty after completion of each subquery. + * + * root->curOuterParams: a list of NestLoopParam nodes, recording Vars and + * PlaceHolderVars that some outer level of nestloop needs to pass down to + * a lower-level plan node in its righthand side. Elements are added to this + * list as createplan.c creates lower Plan nodes that need such Params, and + * are removed when it creates a NestLoop Plan node that will supply those + * values. + * + * The latter two data structures are used to prevent creating multiple + * PARAM_EXEC slots (each requiring work to fill) when the same upper + * SubPlan or NestLoop supplies a value that is referenced in more than + * one place in its child plan nodes. However, when the same Var has to + * be supplied to different subplan trees by different SubPlan or NestLoop + * parent nodes, we don't recognize any commonality; a fresh plan_params or + * curOuterParams entry will be made (since the old one has been removed + * when we finished processing the earlier SubPlan or NestLoop) and a fresh + * PARAM_EXEC number will be assigned. At one time we tried to avoid + * allocating duplicate PARAM_EXEC numbers in such cases, but it's harder + * than it seems to avoid bugs due to overlapping Param lifetimes, so we + * don't risk that anymore. Minimizing the number of PARAM_EXEC slots + * doesn't really save much executor work anyway. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/optimizer/util/paramassign.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "nodes/nodeFuncs.h" +#include "nodes/plannodes.h" +#include "optimizer/paramassign.h" +#include "optimizer/placeholder.h" +#include "rewrite/rewriteManip.h" + + +/* + * Select a PARAM_EXEC number to identify the given Var as a parameter for + * the current subquery. (It might already have one.) + * Record the need for the Var in the proper upper-level root->plan_params. + */ +static int +assign_param_for_var(PlannerInfo *root, Var *var) +{ + ListCell *ppl; + PlannerParamItem *pitem; + Index levelsup; + + /* Find the query level the Var belongs to */ + for (levelsup = var->varlevelsup; levelsup > 0; levelsup--) + root = root->parent_root; + + /* If there's already a matching PlannerParamItem there, just use it */ + foreach(ppl, root->plan_params) + { + pitem = (PlannerParamItem *) lfirst(ppl); + if (IsA(pitem->item, Var)) + { + Var *pvar = (Var *) pitem->item; + + /* + * This comparison must match _equalVar(), except for ignoring + * varlevelsup. Note that _equalVar() ignores the location. + */ + if (pvar->varno == var->varno && + pvar->varattno == var->varattno && + pvar->vartype == var->vartype && + pvar->vartypmod == var->vartypmod && + pvar->varcollid == var->varcollid && + pvar->varnoold == var->varnoold && + pvar->varoattno == var->varoattno) + return pitem->paramId; + } + } + + /* Nope, so make a new one */ + var = copyObject(var); + var->varlevelsup = 0; + + pitem = makeNode(PlannerParamItem); + pitem->item = (Node *) var; + pitem->paramId = list_length(root->glob->paramExecTypes); + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + var->vartype); + + root->plan_params = lappend(root->plan_params, pitem); + + return pitem->paramId; +} + +/* + * Generate a Param node to replace the given Var, + * which is expected to have varlevelsup > 0 (ie, it is not local). + * Record the need for the Var in the proper upper-level root->plan_params. + */ +Param * +replace_outer_var(PlannerInfo *root, Var *var) +{ + Param *retval; + int i; + + Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level); + + /* Find the Var in the appropriate plan_params, or add it if not present */ + i = assign_param_for_var(root, var); + + retval = makeNode(Param); + retval->paramkind = PARAM_EXEC; + retval->paramid = i; + retval->paramtype = var->vartype; + retval->paramtypmod = var->vartypmod; + retval->paramcollid = var->varcollid; + retval->location = var->location; + + return retval; +} + +/* + * Select a PARAM_EXEC number to identify the given PlaceHolderVar as a + * parameter for the current subquery. (It might already have one.) + * Record the need for the PHV in the proper upper-level root->plan_params. + * + * This is just like assign_param_for_var, except for PlaceHolderVars. + */ +static int +assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) +{ + ListCell *ppl; + PlannerParamItem *pitem; + Index levelsup; + + /* Find the query level the PHV belongs to */ + for (levelsup = phv->phlevelsup; levelsup > 0; levelsup--) + root = root->parent_root; + + /* If there's already a matching PlannerParamItem there, just use it */ + foreach(ppl, root->plan_params) + { + pitem = (PlannerParamItem *) lfirst(ppl); + if (IsA(pitem->item, PlaceHolderVar)) + { + PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item; + + /* We assume comparing the PHIDs is sufficient */ + if (pphv->phid == phv->phid) + return pitem->paramId; + } + } + + /* Nope, so make a new one */ + phv = copyObject(phv); + IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0); + Assert(phv->phlevelsup == 0); + + pitem = makeNode(PlannerParamItem); + pitem->item = (Node *) phv; + pitem->paramId = list_length(root->glob->paramExecTypes); + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + exprType((Node *) phv->phexpr)); + + root->plan_params = lappend(root->plan_params, pitem); + + return pitem->paramId; +} + +/* + * Generate a Param node to replace the given PlaceHolderVar, + * which is expected to have phlevelsup > 0 (ie, it is not local). + * Record the need for the PHV in the proper upper-level root->plan_params. + * + * This is just like replace_outer_var, except for PlaceHolderVars. + */ +Param * +replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) +{ + Param *retval; + int i; + + Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level); + + /* Find the PHV in the appropriate plan_params, or add it if not present */ + i = assign_param_for_placeholdervar(root, phv); + + retval = makeNode(Param); + retval->paramkind = PARAM_EXEC; + retval->paramid = i; + retval->paramtype = exprType((Node *) phv->phexpr); + retval->paramtypmod = exprTypmod((Node *) phv->phexpr); + retval->paramcollid = exprCollation((Node *) phv->phexpr); + retval->location = -1; + + return retval; +} + +/* + * Generate a Param node to replace the given Aggref + * which is expected to have agglevelsup > 0 (ie, it is not local). + * Record the need for the Aggref in the proper upper-level root->plan_params. + */ +Param * +replace_outer_agg(PlannerInfo *root, Aggref *agg) +{ + Param *retval; + PlannerParamItem *pitem; + Index levelsup; + + Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level); + + /* Find the query level the Aggref belongs to */ + for (levelsup = agg->agglevelsup; levelsup > 0; levelsup--) + root = root->parent_root; + + /* + * It does not seem worthwhile to try to de-duplicate references to outer + * aggs. Just make a new slot every time. + */ + agg = copyObject(agg); + IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0); + Assert(agg->agglevelsup == 0); + + pitem = makeNode(PlannerParamItem); + pitem->item = (Node *) agg; + pitem->paramId = list_length(root->glob->paramExecTypes); + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + agg->aggtype); + + root->plan_params = lappend(root->plan_params, pitem); + + retval = makeNode(Param); + retval->paramkind = PARAM_EXEC; + retval->paramid = pitem->paramId; + retval->paramtype = agg->aggtype; + retval->paramtypmod = -1; + retval->paramcollid = agg->aggcollid; + retval->location = agg->location; + + return retval; +} + +/* + * Generate a Param node to replace the given GroupingFunc expression which is + * expected to have agglevelsup > 0 (ie, it is not local). + * Record the need for the GroupingFunc in the proper upper-level + * root->plan_params. + */ +Param * +replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp) +{ + Param *retval; + PlannerParamItem *pitem; + Index levelsup; + Oid ptype = exprType((Node *) grp); + + Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level); + + /* Find the query level the GroupingFunc belongs to */ + for (levelsup = grp->agglevelsup; levelsup > 0; levelsup--) + root = root->parent_root; + + /* + * It does not seem worthwhile to try to de-duplicate references to outer + * aggs. Just make a new slot every time. + */ + grp = copyObject(grp); + IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0); + Assert(grp->agglevelsup == 0); + + pitem = makeNode(PlannerParamItem); + pitem->item = (Node *) grp; + pitem->paramId = list_length(root->glob->paramExecTypes); + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + ptype); + + root->plan_params = lappend(root->plan_params, pitem); + + retval = makeNode(Param); + retval->paramkind = PARAM_EXEC; + retval->paramid = pitem->paramId; + retval->paramtype = ptype; + retval->paramtypmod = -1; + retval->paramcollid = InvalidOid; + retval->location = grp->location; + + return retval; +} + +/* + * Generate a Param node to replace the given Var, + * which is expected to come from some upper NestLoop plan node. + * Record the need for the Var in root->curOuterParams. + */ +Param * +replace_nestloop_param_var(PlannerInfo *root, Var *var) +{ + Param *param; + NestLoopParam *nlp; + ListCell *lc; + + /* Is this Var already listed in root->curOuterParams? */ + foreach(lc, root->curOuterParams) + { + nlp = (NestLoopParam *) lfirst(lc); + if (equal(var, nlp->paramval)) + { + /* Yes, so just make a Param referencing this NLP's slot */ + param = makeNode(Param); + param->paramkind = PARAM_EXEC; + param->paramid = nlp->paramno; + param->paramtype = var->vartype; + param->paramtypmod = var->vartypmod; + param->paramcollid = var->varcollid; + param->location = var->location; + return param; + } + } + + /* No, so assign a PARAM_EXEC slot for a new NLP */ + param = generate_new_exec_param(root, + var->vartype, + var->vartypmod, + var->varcollid); + param->location = var->location; + + /* Add it to the list of required NLPs */ + nlp = makeNode(NestLoopParam); + nlp->paramno = param->paramid; + nlp->paramval = copyObject(var); + root->curOuterParams = lappend(root->curOuterParams, nlp); + + /* And return the replacement Param */ + return param; +} + +/* + * Generate a Param node to replace the given PlaceHolderVar, + * which is expected to come from some upper NestLoop plan node. + * Record the need for the PHV in root->curOuterParams. + * + * This is just like replace_nestloop_param_var, except for PlaceHolderVars. + */ +Param * +replace_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv) +{ + Param *param; + NestLoopParam *nlp; + ListCell *lc; + + /* Is this PHV already listed in root->curOuterParams? */ + foreach(lc, root->curOuterParams) + { + nlp = (NestLoopParam *) lfirst(lc); + if (equal(phv, nlp->paramval)) + { + /* Yes, so just make a Param referencing this NLP's slot */ + param = makeNode(Param); + param->paramkind = PARAM_EXEC; + param->paramid = nlp->paramno; + param->paramtype = exprType((Node *) phv->phexpr); + param->paramtypmod = exprTypmod((Node *) phv->phexpr); + param->paramcollid = exprCollation((Node *) phv->phexpr); + param->location = -1; + return param; + } + } + + /* No, so assign a PARAM_EXEC slot for a new NLP */ + param = generate_new_exec_param(root, + exprType((Node *) phv->phexpr), + exprTypmod((Node *) phv->phexpr), + exprCollation((Node *) phv->phexpr)); + + /* Add it to the list of required NLPs */ + nlp = makeNode(NestLoopParam); + nlp->paramno = param->paramid; + nlp->paramval = (Var *) copyObject(phv); + root->curOuterParams = lappend(root->curOuterParams, nlp); + + /* And return the replacement Param */ + return param; +} + +/* + * process_subquery_nestloop_params + * Handle params of a parameterized subquery that need to be fed + * from an outer nestloop. + * + * Currently, that would be *all* params that a subquery in FROM has demanded + * from the current query level, since they must be LATERAL references. + * + * subplan_params is a list of PlannerParamItems that we intend to pass to + * a subquery-in-FROM. (This was constructed in root->plan_params while + * planning the subquery, but isn't there anymore when this is called.) + * + * The subplan's references to the outer variables are already represented + * as PARAM_EXEC Params, since that conversion was done by the routines above + * while planning the subquery. So we need not modify the subplan or the + * PlannerParamItems here. What we do need to do is add entries to + * root->curOuterParams to signal the parent nestloop plan node that it must + * provide these values. This differs from replace_nestloop_param_var in + * that the PARAM_EXEC slots to use have already been determined. + * + * Note that we also use root->curOuterRels as an implicit parameter for + * sanity checks. + */ +void +process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params) +{ + ListCell *lc; + + foreach(lc, subplan_params) + { + PlannerParamItem *pitem = castNode(PlannerParamItem, lfirst(lc)); + + if (IsA(pitem->item, Var)) + { + Var *var = (Var *) pitem->item; + NestLoopParam *nlp; + ListCell *lc; + + /* If not from a nestloop outer rel, complain */ + if (!bms_is_member(var->varno, root->curOuterRels)) + elog(ERROR, "non-LATERAL parameter required by subquery"); + + /* Is this param already listed in root->curOuterParams? */ + foreach(lc, root->curOuterParams) + { + nlp = (NestLoopParam *) lfirst(lc); + if (nlp->paramno == pitem->paramId) + { + Assert(equal(var, nlp->paramval)); + /* Present, so nothing to do */ + break; + } + } + if (lc == NULL) + { + /* No, so add it */ + nlp = makeNode(NestLoopParam); + nlp->paramno = pitem->paramId; + nlp->paramval = copyObject(var); + root->curOuterParams = lappend(root->curOuterParams, nlp); + } + } + else if (IsA(pitem->item, PlaceHolderVar)) + { + PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item; + NestLoopParam *nlp; + ListCell *lc; + + /* If not from a nestloop outer rel, complain */ + if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, + root->curOuterRels)) + elog(ERROR, "non-LATERAL parameter required by subquery"); + + /* Is this param already listed in root->curOuterParams? */ + foreach(lc, root->curOuterParams) + { + nlp = (NestLoopParam *) lfirst(lc); + if (nlp->paramno == pitem->paramId) + { + Assert(equal(phv, nlp->paramval)); + /* Present, so nothing to do */ + break; + } + } + if (lc == NULL) + { + /* No, so add it */ + nlp = makeNode(NestLoopParam); + nlp->paramno = pitem->paramId; + nlp->paramval = (Var *) copyObject(phv); + root->curOuterParams = lappend(root->curOuterParams, nlp); + } + } + else + elog(ERROR, "unexpected type of subquery parameter"); + } +} + +/* + * Identify any NestLoopParams that should be supplied by a NestLoop plan + * node with the specified lefthand rels. Remove them from the active + * root->curOuterParams list and return them as the result list. + */ +List * +identify_current_nestloop_params(PlannerInfo *root, Relids leftrelids) +{ + List *result; + ListCell *cell; + + result = NIL; + foreach(cell, root->curOuterParams) + { + NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); + + /* + * We are looking for Vars and PHVs that can be supplied by the + * lefthand rels. The "bms_overlap" test is just an optimization to + * allow skipping find_placeholder_info() if the PHV couldn't match. + */ + if (IsA(nlp->paramval, Var) && + bms_is_member(nlp->paramval->varno, leftrelids)) + { + root->curOuterParams = foreach_delete_current(root->curOuterParams, + cell); + result = lappend(result, nlp); + } + else if (IsA(nlp->paramval, PlaceHolderVar) && + bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, + leftrelids) && + bms_is_subset(find_placeholder_info(root, + (PlaceHolderVar *) nlp->paramval, + false)->ph_eval_at, + leftrelids)) + { + root->curOuterParams = foreach_delete_current(root->curOuterParams, + cell); + result = lappend(result, nlp); + } + } + return result; +} + +/* + * Generate a new Param node that will not conflict with any other. + * + * This is used to create Params representing subplan outputs or + * NestLoop parameters. + * + * We don't need to build a PlannerParamItem for such a Param, but we do + * need to make sure we record the type in paramExecTypes (otherwise, + * there won't be a slot allocated for it). + */ +Param * +generate_new_exec_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, + Oid paramcollation) +{ + Param *retval; + + retval = makeNode(Param); + retval->paramkind = PARAM_EXEC; + retval->paramid = list_length(root->glob->paramExecTypes); + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + paramtype); + retval->paramtype = paramtype; + retval->paramtypmod = paramtypmod; + retval->paramcollid = paramcollation; + retval->location = -1; + + return retval; +} + +/* + * Assign a (nonnegative) PARAM_EXEC ID for a special parameter (one that + * is not actually used to carry a value at runtime). Such parameters are + * used for special runtime signaling purposes, such as connecting a + * recursive union node to its worktable scan node or forcing plan + * re-evaluation within the EvalPlanQual mechanism. No actual Param node + * exists with this ID, however. + */ +int +assign_special_exec_param(PlannerInfo *root) +{ + int paramId = list_length(root->glob->paramExecTypes); + + root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes, + InvalidOid); + return paramId; +} diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index bd9442c22d6..34acb732ee2 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -3,7 +3,7 @@ * pathnode.c * Routines to manipulate pathlists and create path nodes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,15 +20,16 @@ #include "foreign/fdwapi.h" #include "nodes/extensible.h" #include "nodes/nodeFuncs.h" +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" #include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -51,11 +52,11 @@ typedef enum #define STD_FUZZ_FACTOR 1.01 static List *translate_sub_tlist(List *tlist, int relid); -static int append_total_cost_compare(const void *a, const void *b); -static int append_startup_cost_compare(const void *a, const void *b); +static int append_total_cost_compare(const ListCell *a, const ListCell *b); +static int append_startup_cost_compare(const ListCell *a, const ListCell *b); static List *reparameterize_pathlist_by_child(PlannerInfo *root, - List *pathlist, - RelOptInfo *child_rel); + List *pathlist, + RelOptInfo *child_rel); /***************************************************************************** @@ -422,11 +423,9 @@ void add_path(RelOptInfo *parent_rel, Path *new_path) { bool accept_new = true; /* unless we find a superior old path */ - ListCell *insert_after = NULL; /* where to insert new item */ + int insert_at = 0; /* where to insert new item */ List *new_path_pathkeys; ListCell *p1; - ListCell *p1_prev; - ListCell *p1_next; /* * This is a convenient place to check for query cancel --- no part of the @@ -441,12 +440,8 @@ add_path(RelOptInfo *parent_rel, Path *new_path) * Loop to check proposed new path against old paths. Note it is possible * for more than one old path to be tossed out because new_path dominates * it. - * - * We can't use foreach here because the loop body may delete the current - * list cell. */ - p1_prev = NULL; - for (p1 = list_head(parent_rel->pathlist); p1 != NULL; p1 = p1_next) + foreach(p1, parent_rel->pathlist) { Path *old_path = (Path *) lfirst(p1); bool remove_old = false; /* unless new proves superior */ @@ -454,8 +449,6 @@ add_path(RelOptInfo *parent_rel, Path *new_path) PathKeysComparison keyscmp; BMS_Comparison outercmp; - p1_next = lnext(p1); - /* * Do a fuzzy cost comparison with standard fuzziness limit. */ @@ -592,23 +585,20 @@ add_path(RelOptInfo *parent_rel, Path *new_path) */ if (remove_old) { - parent_rel->pathlist = list_delete_cell(parent_rel->pathlist, - p1, p1_prev); + parent_rel->pathlist = foreach_delete_current(parent_rel->pathlist, + p1); /* * Delete the data pointed-to by the deleted cell, if possible */ if (!IsA(old_path, IndexPath)) pfree(old_path); - /* p1_prev does not advance */ } else { /* new belongs after this old path if it has cost >= old's */ if (new_path->total_cost >= old_path->total_cost) - insert_after = p1; - /* p1_prev advances */ - p1_prev = p1; + insert_at = foreach_current_index(p1) + 1; } /* @@ -623,10 +613,8 @@ add_path(RelOptInfo *parent_rel, Path *new_path) if (accept_new) { /* Accept the new path: insert it at proper place in pathlist */ - if (insert_after) - lappend_cell(parent_rel->pathlist, insert_after, new_path); - else - parent_rel->pathlist = lcons(new_path, parent_rel->pathlist); + parent_rel->pathlist = + list_insert_nth(parent_rel->pathlist, insert_at, new_path); } else { @@ -762,32 +750,32 @@ void add_partial_path(RelOptInfo *parent_rel, Path *new_path) { bool accept_new = true; /* unless we find a superior old path */ - ListCell *insert_after = NULL; /* where to insert new item */ + int insert_at = 0; /* where to insert new item */ ListCell *p1; - ListCell *p1_prev; - ListCell *p1_next; /* Check for query cancel. */ CHECK_FOR_INTERRUPTS(); + /* Path to be added must be parallel safe. */ + Assert(new_path->parallel_safe); + + /* Relation should be OK for parallelism, too. */ + Assert(parent_rel->consider_parallel); + /* * As in add_path, throw out any paths which are dominated by the new * path, but throw out the new path if some existing path dominates it. */ - p1_prev = NULL; - for (p1 = list_head(parent_rel->partial_pathlist); p1 != NULL; - p1 = p1_next) + foreach(p1, parent_rel->partial_pathlist) { Path *old_path = (Path *) lfirst(p1); bool remove_old = false; /* unless new proves superior */ PathKeysComparison keyscmp; - p1_next = lnext(p1); - /* Compare pathkeys. */ keyscmp = compare_pathkeys(new_path->pathkeys, old_path->pathkeys); - /* Unless pathkeys are incompable, keep just one of the two paths. */ + /* Unless pathkeys are incompatible, keep just one of the two paths. */ if (keyscmp != PATHKEYS_DIFFERENT) { if (new_path->total_cost > old_path->total_cost * STD_FUZZ_FACTOR) @@ -834,17 +822,14 @@ add_partial_path(RelOptInfo *parent_rel, Path *new_path) if (remove_old) { parent_rel->partial_pathlist = - list_delete_cell(parent_rel->partial_pathlist, p1, p1_prev); + foreach_delete_current(parent_rel->partial_pathlist, p1); pfree(old_path); - /* p1_prev does not advance */ } else { /* new belongs after this old path if it has cost >= old's */ if (new_path->total_cost >= old_path->total_cost) - insert_after = p1; - /* p1_prev advances */ - p1_prev = p1; + insert_at = foreach_current_index(p1) + 1; } /* @@ -859,11 +844,8 @@ add_partial_path(RelOptInfo *parent_rel, Path *new_path) if (accept_new) { /* Accept the new path: insert it at proper place */ - if (insert_after) - lappend_cell(parent_rel->partial_pathlist, insert_after, new_path); - else - parent_rel->partial_pathlist = - lcons(new_path, parent_rel->partial_pathlist); + parent_rel->partial_pathlist = + list_insert_nth(parent_rel->partial_pathlist, insert_at, new_path); } else { @@ -994,10 +976,8 @@ create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer * Creates a path node for an index scan. * * 'index' is a usable index. - * 'indexclauses' is a list of RestrictInfo nodes representing clauses - * to be used as index qual conditions in the scan. - * 'indexclausecols' is an integer list of index column numbers (zero based) - * the indexclauses can be used with. + * 'indexclauses' is a list of IndexClause nodes representing clauses + * to be enforced as qual conditions in the scan. * 'indexorderbys' is a list of bare expressions (no RestrictInfos) * to be used as index ordering operators in the scan. * 'indexorderbycols' is an integer list of index column numbers (zero based) @@ -1018,7 +998,6 @@ IndexPath * create_index_path(PlannerInfo *root, IndexOptInfo *index, List *indexclauses, - List *indexclausecols, List *indexorderbys, List *indexorderbycols, List *pathkeys, @@ -1030,8 +1009,6 @@ create_index_path(PlannerInfo *root, { IndexPath *pathnode = makeNode(IndexPath); RelOptInfo *rel = index->rel; - List *indexquals, - *indexqualcols; pathnode->path.pathtype = indexonly ? T_IndexOnlyScan : T_IndexScan; pathnode->path.parent = rel; @@ -1043,15 +1020,8 @@ create_index_path(PlannerInfo *root, pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = pathkeys; - /* Convert clauses to indexquals the executor can handle */ - expand_indexqual_conditions(index, indexclauses, indexclausecols, - &indexquals, &indexqualcols); - - /* Fill in the pathnode */ pathnode->indexinfo = index; pathnode->indexclauses = indexclauses; - pathnode->indexquals = indexquals; - pathnode->indexqualcols = indexqualcols; pathnode->indexorderbys = indexorderbys; pathnode->indexorderbycols = indexorderbycols; pathnode->indexscandir = indexscandir; @@ -1208,12 +1178,13 @@ create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, * pathnode. * * Note that we must handle subpaths = NIL, representing a dummy access path. + * Also, there are callers that pass root = NULL. */ AppendPath * create_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *partial_subpaths, - Relids required_outer, + List *pathkeys, Relids required_outer, int parallel_workers, bool parallel_aware, List *partitioned_rels, double rows) { @@ -1247,7 +1218,7 @@ create_append_path(PlannerInfo *root, pathnode->path.parallel_aware = parallel_aware; pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = parallel_workers; - pathnode->path.pathkeys = NIL; /* result is always considered unsorted */ + pathnode->path.pathkeys = pathkeys; pathnode->partitioned_rels = list_copy(partitioned_rels); /* @@ -1261,14 +1232,29 @@ create_append_path(PlannerInfo *root, */ if (pathnode->path.parallel_aware) { - subpaths = list_qsort(subpaths, append_total_cost_compare); - partial_subpaths = list_qsort(partial_subpaths, - append_startup_cost_compare); + /* + * We mustn't fiddle with the order of subpaths when the Append has + * pathkeys. The order they're listed in is critical to keeping the + * pathkeys valid. + */ + Assert(pathkeys == NIL); + + list_sort(subpaths, append_total_cost_compare); + list_sort(partial_subpaths, append_startup_cost_compare); } pathnode->first_partial_path = list_length(subpaths); pathnode->subpaths = list_concat(subpaths, partial_subpaths); - foreach(l, subpaths) + /* + * Apply query-wide LIMIT if known and path is for sole base relation. + * (Handling this at this low level is a bit klugy.) + */ + if (root != NULL && bms_equal(rel->relids, root->all_baserels)) + pathnode->limit_tuples = root->limit_tuples; + else + pathnode->limit_tuples = -1.0; + + foreach(l, pathnode->subpaths) { Path *subpath = (Path *) lfirst(l); @@ -1281,7 +1267,24 @@ create_append_path(PlannerInfo *root, Assert(!parallel_aware || pathnode->path.parallel_safe); - cost_append(pathnode); + /* + * If there's exactly one child path, the Append is a no-op and will be + * discarded later (in setrefs.c); therefore, we can inherit the child's + * size and cost, as well as its pathkeys if any (overriding whatever the + * caller might've said). Otherwise, we must do the normal costsize + * calculation. + */ + if (list_length(pathnode->subpaths) == 1) + { + Path *child = (Path *) linitial(pathnode->subpaths); + + pathnode->path.rows = child->rows; + pathnode->path.startup_cost = child->startup_cost; + pathnode->path.total_cost = child->total_cost; + pathnode->path.pathkeys = child->pathkeys; + } + else + cost_append(pathnode); /* If the caller provided a row estimate, override the computed value. */ if (rows >= 0) @@ -1292,17 +1295,18 @@ create_append_path(PlannerInfo *root, /* * append_total_cost_compare - * qsort comparator for sorting append child paths by total_cost descending + * list_sort comparator for sorting append child paths + * by total_cost descending * * For equal total costs, we fall back to comparing startup costs; if those * are equal too, break ties using bms_compare on the paths' relids. - * (This is to avoid getting unpredictable results from qsort.) + * (This is to avoid getting unpredictable results from list_sort.) */ static int -append_total_cost_compare(const void *a, const void *b) +append_total_cost_compare(const ListCell *a, const ListCell *b) { - Path *path1 = (Path *) lfirst(*(ListCell **) a); - Path *path2 = (Path *) lfirst(*(ListCell **) b); + Path *path1 = (Path *) lfirst(a); + Path *path2 = (Path *) lfirst(b); int cmp; cmp = compare_path_costs(path1, path2, TOTAL_COST); @@ -1313,17 +1317,18 @@ append_total_cost_compare(const void *a, const void *b) /* * append_startup_cost_compare - * qsort comparator for sorting append child paths by startup_cost descending + * list_sort comparator for sorting append child paths + * by startup_cost descending * * For equal startup costs, we fall back to comparing total costs; if those * are equal too, break ties using bms_compare on the paths' relids. - * (This is to avoid getting unpredictable results from qsort.) + * (This is to avoid getting unpredictable results from list_sort.) */ static int -append_startup_cost_compare(const void *a, const void *b) +append_startup_cost_compare(const ListCell *a, const ListCell *b) { - Path *path1 = (Path *) lfirst(*(ListCell **) a); - Path *path2 = (Path *) lfirst(*(ListCell **) b); + Path *path1 = (Path *) lfirst(a); + Path *path2 = (Path *) lfirst(b); int cmp; cmp = compare_path_costs(path1, path2, STARTUP_COST); @@ -1413,27 +1418,37 @@ create_merge_append_path(PlannerInfo *root, Assert(bms_equal(PATH_REQ_OUTER(subpath), required_outer)); } - /* Now we can compute total costs of the MergeAppend */ - cost_merge_append(&pathnode->path, root, - pathkeys, list_length(subpaths), - input_startup_cost, input_total_cost, - pathnode->path.rows); + /* + * Now we can compute total costs of the MergeAppend. If there's exactly + * one child path, the MergeAppend is a no-op and will be discarded later + * (in setrefs.c); otherwise we do the normal cost calculation. + */ + if (list_length(subpaths) == 1) + { + pathnode->path.startup_cost = input_startup_cost; + pathnode->path.total_cost = input_total_cost; + } + else + cost_merge_append(&pathnode->path, root, + pathkeys, list_length(subpaths), + input_startup_cost, input_total_cost, + pathnode->path.rows); return pathnode; } /* - * create_result_path + * create_group_result_path * Creates a path representing a Result-and-nothing-else plan. * - * This is only used for degenerate cases, such as a query with an empty - * jointree. + * This is only used for degenerate grouping cases, in which we know we + * need to produce one result row, possibly filtered by a HAVING qual. */ -ResultPath * -create_result_path(PlannerInfo *root, RelOptInfo *rel, - PathTarget *target, List *resconstantqual) +GroupResultPath * +create_group_result_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, List *havingqual) { - ResultPath *pathnode = makeNode(ResultPath); + GroupResultPath *pathnode = makeNode(GroupResultPath); pathnode->path.pathtype = T_Result; pathnode->path.parent = rel; @@ -1443,9 +1458,13 @@ create_result_path(PlannerInfo *root, RelOptInfo *rel, pathnode->path.parallel_safe = rel->consider_parallel; pathnode->path.parallel_workers = 0; pathnode->path.pathkeys = NIL; - pathnode->quals = resconstantqual; + pathnode->quals = havingqual; - /* Hardly worth defining a cost_result() function ... just do it */ + /* + * We can't quite use cost_resultscan() because the quals we want to + * account for are not baserestrict quals of the rel. Might as well just + * hack it here. + */ pathnode->path.rows = 1; pathnode->path.startup_cost = target->cost.startup; pathnode->path.total_cost = target->cost.startup + @@ -1455,12 +1474,12 @@ create_result_path(PlannerInfo *root, RelOptInfo *rel, * Add cost of qual, if any --- but we ignore its selectivity, since our * rowcount estimate should be 1 no matter what the qual is. */ - if (resconstantqual) + if (havingqual) { QualCost qual_cost; - cost_qual_eval(&qual_cost, resconstantqual, root); - /* resconstantqual is evaluated once at startup */ + cost_qual_eval(&qual_cost, havingqual, root); + /* havingqual is evaluated once at startup */ pathnode->path.startup_cost += qual_cost.startup + qual_cost.per_tuple; pathnode->path.total_cost += qual_cost.startup + qual_cost.per_tuple; } @@ -2013,6 +2032,32 @@ create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, return pathnode; } +/* + * create_resultscan_path + * Creates a path corresponding to a scan of an RTE_RESULT relation, + * returning the pathnode. + */ +Path * +create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer) +{ + Path *pathnode = makeNode(Path); + + pathnode->pathtype = T_Result; + pathnode->parent = rel; + pathnode->pathtarget = rel->reltarget; + pathnode->param_info = get_baserel_parampathinfo(root, rel, + required_outer); + pathnode->parallel_aware = false; + pathnode->parallel_safe = rel->consider_parallel; + pathnode->parallel_workers = 0; + pathnode->pathkeys = NIL; /* result is always unordered */ + + cost_resultscan(pathnode, root, rel, pathnode->param_info); + + return pathnode; +} + /* * create_worktablescan_path * Creates a path corresponding to a scan of a self-reference CTE, @@ -2042,15 +2087,14 @@ create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, /* * create_foreignscan_path - * Creates a path corresponding to a scan of a foreign table, foreign join, - * or foreign upper-relation processing, returning the pathnode. + * Creates a path corresponding to a scan of a foreign base table, + * returning the pathnode. * * This function is never called from core Postgres; rather, it's expected - * to be called by the GetForeignPaths, GetForeignJoinPaths, or - * GetForeignUpperPaths function of a foreign data wrapper. We make the FDW - * supply all fields of the path, since we do not have any way to calculate - * them in core. However, there is a usually-sane default for the pathtarget - * (rel->reltarget), so we let a NULL for "target" select that. + * to be called by the GetForeignPaths function of a foreign data wrapper. + * We make the FDW supply all fields of the path, since we do not have any way + * to calculate them in core. However, there is a usually-sane default for + * the pathtarget (rel->reltarget), so we let a NULL for "target" select that. */ ForeignPath * create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, @@ -2063,6 +2107,9 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, { ForeignPath *pathnode = makeNode(ForeignPath); + /* Historically some FDWs were confused about when to use this */ + Assert(IS_SIMPLE_REL(rel)); + pathnode->path.pathtype = T_ForeignScan; pathnode->path.parent = rel; pathnode->path.pathtarget = target ? target : rel->reltarget; @@ -2082,6 +2129,101 @@ create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, return pathnode; } +/* + * create_foreign_join_path + * Creates a path corresponding to a scan of a foreign join, + * returning the pathnode. + * + * This function is never called from core Postgres; rather, it's expected + * to be called by the GetForeignJoinPaths function of a foreign data wrapper. + * We make the FDW supply all fields of the path, since we do not have any way + * to calculate them in core. However, there is a usually-sane default for + * the pathtarget (rel->reltarget), so we let a NULL for "target" select that. + */ +ForeignPath * +create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Relids required_outer, + Path *fdw_outerpath, + List *fdw_private) +{ + ForeignPath *pathnode = makeNode(ForeignPath); + + /* + * We should use get_joinrel_parampathinfo to handle parameterized paths, + * but the API of this function doesn't support it, and existing + * extensions aren't yet trying to build such paths anyway. For the + * moment just throw an error if someone tries it; eventually we should + * revisit this. + */ + if (!bms_is_empty(required_outer) || !bms_is_empty(rel->lateral_relids)) + elog(ERROR, "parameterized foreign joins are not supported yet"); + + pathnode->path.pathtype = T_ForeignScan; + pathnode->path.parent = rel; + pathnode->path.pathtarget = target ? target : rel->reltarget; + pathnode->path.param_info = NULL; /* XXX see above */ + pathnode->path.parallel_aware = false; + pathnode->path.parallel_safe = rel->consider_parallel; + pathnode->path.parallel_workers = 0; + pathnode->path.rows = rows; + pathnode->path.startup_cost = startup_cost; + pathnode->path.total_cost = total_cost; + pathnode->path.pathkeys = pathkeys; + + pathnode->fdw_outerpath = fdw_outerpath; + pathnode->fdw_private = fdw_private; + + return pathnode; +} + +/* + * create_foreign_upper_path + * Creates a path corresponding to an upper relation that's computed + * directly by an FDW, returning the pathnode. + * + * This function is never called from core Postgres; rather, it's expected to + * be called by the GetForeignUpperPaths function of a foreign data wrapper. + * We make the FDW supply all fields of the path, since we do not have any way + * to calculate them in core. However, there is a usually-sane default for + * the pathtarget (rel->reltarget), so we let a NULL for "target" select that. + */ +ForeignPath * +create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Path *fdw_outerpath, + List *fdw_private) +{ + ForeignPath *pathnode = makeNode(ForeignPath); + + /* + * Upper relations should never have any lateral references, since joining + * is complete. + */ + Assert(bms_is_empty(rel->lateral_relids)); + + pathnode->path.pathtype = T_ForeignScan; + pathnode->path.parent = rel; + pathnode->path.pathtarget = target ? target : rel->reltarget; + pathnode->path.param_info = NULL; + pathnode->path.parallel_aware = false; + pathnode->path.parallel_safe = rel->consider_parallel; + pathnode->path.parallel_workers = 0; + pathnode->path.rows = rows; + pathnode->path.startup_cost = startup_cost; + pathnode->path.total_cost = total_cost; + pathnode->path.pathkeys = pathkeys; + + pathnode->fdw_outerpath = fdw_outerpath; + pathnode->fdw_private = fdw_private; + + return pathnode; +} + /* * calc_nestloop_required_outer * Compute the required_outer set for a nestloop join path @@ -2589,7 +2731,7 @@ create_set_projection_path(PlannerInfo *root, Node *node = (Node *) lfirst(lc); double itemrows; - itemrows = expression_returns_set_rows(node); + itemrows = expression_returns_set_rows(root, node); if (tlist_rows < itemrows) tlist_rows = itemrows; } @@ -3066,10 +3208,9 @@ create_minmaxagg_path(PlannerInfo *root, * 'target' is the PathTarget to be computed * 'windowFuncs' is a list of WindowFunc structs * 'winclause' is a WindowClause that is common to all the WindowFuncs - * 'winpathkeys' is the pathkeys for the PARTITION keys + ORDER keys * - * The actual sort order of the input must match winpathkeys, but might - * have additional keys after those. + * The input must be sorted according to the WindowClause's PARTITION keys + * plus ORDER BY keys. */ WindowAggPath * create_windowagg_path(PlannerInfo *root, @@ -3077,8 +3218,7 @@ create_windowagg_path(PlannerInfo *root, Path *subpath, PathTarget *target, List *windowFuncs, - WindowClause *winclause, - List *winpathkeys) + WindowClause *winclause) { WindowAggPath *pathnode = makeNode(WindowAggPath); @@ -3096,7 +3236,6 @@ create_windowagg_path(PlannerInfo *root, pathnode->subpath = subpath; pathnode->winclause = winclause; - pathnode->winpathkeys = winpathkeys; /* * For costing purposes, assume that there are no redundant partitioning @@ -3289,9 +3428,7 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, * 'operation' is the operation type * 'canSetTag' is true if we set the command tag/es_processed * 'nominalRelation' is the parent RT index for use of EXPLAIN - * 'partitioned_rels' is an integer list of RT indexes of non-leaf tables in - * the partition tree, if this is an UPDATE/DELETE to a partitioned table. - * Otherwise NIL. + * 'rootRelation' is the partitioned table root RT index, or 0 if none * 'partColsUpdated' is true if any partitioning columns are being updated, * either from the target relation or a descendent partitioned table. * 'resultRelations' is an integer list of actual RT indexes of target rel(s) @@ -3302,21 +3439,17 @@ create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, * 'rowMarks' is a list of PlanRowMarks (non-locking only) * 'onconflict' is the ON CONFLICT clause, or NULL * 'epqParam' is the ID of Param for EvalPlanQual re-eval - * 'mergeActionList' is a list of MERGE actions */ ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, CmdType operation, bool canSetTag, - Index nominalRelation, List *partitioned_rels, + Index nominalRelation, Index rootRelation, bool partColsUpdated, - List *resultRelations, - Index mergeTargetRelation, - List *subpaths, + List *resultRelations, List *subpaths, List *subroots, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, - List *mergeSourceTargetList, - List *mergeActionList, int epqParam) + int epqParam) { ModifyTablePath *pathnode = makeNode(ModifyTablePath); double total_size; @@ -3378,10 +3511,9 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, pathnode->operation = operation; pathnode->canSetTag = canSetTag; pathnode->nominalRelation = nominalRelation; - pathnode->partitioned_rels = list_copy(partitioned_rels); + pathnode->rootRelation = rootRelation; pathnode->partColsUpdated = partColsUpdated; pathnode->resultRelations = resultRelations; - pathnode->mergeTargetRelation = mergeTargetRelation; pathnode->subpaths = subpaths; pathnode->subroots = subroots; pathnode->withCheckOptionLists = withCheckOptionLists; @@ -3389,8 +3521,6 @@ create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, pathnode->rowMarks = rowMarks; pathnode->onconflict = onconflict; pathnode->epqParam = epqParam; - pathnode->mergeSourceTargetList = mergeSourceTargetList; - pathnode->mergeActionList = mergeActionList; return pathnode; } @@ -3440,17 +3570,42 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, /* * Adjust the output rows count and costs according to the offset/limit. - * This is only a cosmetic issue if we are at top level, but if we are - * building a subquery then it's important to report correct info to the - * outer planner. - * - * When the offset or count couldn't be estimated, use 10% of the - * estimated number of rows emitted from the subpath. - * - * XXX we don't bother to add eval costs of the offset/limit expressions - * themselves to the path costs. In theory we should, but in most cases - * those expressions are trivial and it's just not worth the trouble. */ + adjust_limit_rows_costs(&pathnode->path.rows, + &pathnode->path.startup_cost, + &pathnode->path.total_cost, + offset_est, count_est); + + return pathnode; +} + +/* + * adjust_limit_rows_costs + * Adjust the size and cost estimates for a LimitPath node according to the + * offset/limit. + * + * This is only a cosmetic issue if we are at top level, but if we are + * building a subquery then it's important to report correct info to the outer + * planner. + * + * When the offset or count couldn't be estimated, use 10% of the estimated + * number of rows emitted from the subpath. + * + * XXX we don't bother to add eval costs of the offset/limit expressions + * themselves to the path costs. In theory we should, but in most cases those + * expressions are trivial and it's just not worth the trouble. + */ +void +adjust_limit_rows_costs(double *rows, /* in/out parameter */ + Cost *startup_cost, /* in/out parameter */ + Cost *total_cost, /* in/out parameter */ + int64 offset_est, + int64 count_est) +{ + double input_rows = *rows; + Cost input_startup_cost = *startup_cost; + Cost input_total_cost = *total_cost; + if (offset_est != 0) { double offset_rows; @@ -3458,16 +3613,16 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, if (offset_est > 0) offset_rows = (double) offset_est; else - offset_rows = clamp_row_est(subpath->rows * 0.10); - if (offset_rows > pathnode->path.rows) - offset_rows = pathnode->path.rows; - if (subpath->rows > 0) - pathnode->path.startup_cost += - (subpath->total_cost - subpath->startup_cost) - * offset_rows / subpath->rows; - pathnode->path.rows -= offset_rows; - if (pathnode->path.rows < 1) - pathnode->path.rows = 1; + offset_rows = clamp_row_est(input_rows * 0.10); + if (offset_rows > *rows) + offset_rows = *rows; + if (input_rows > 0) + *startup_cost += + (input_total_cost - input_startup_cost) + * offset_rows / input_rows; + *rows -= offset_rows; + if (*rows < 1) + *rows = 1; } if (count_est != 0) @@ -3477,19 +3632,17 @@ create_limit_path(PlannerInfo *root, RelOptInfo *rel, if (count_est > 0) count_rows = (double) count_est; else - count_rows = clamp_row_est(subpath->rows * 0.10); - if (count_rows > pathnode->path.rows) - count_rows = pathnode->path.rows; - if (subpath->rows > 0) - pathnode->path.total_cost = pathnode->path.startup_cost + - (subpath->total_cost - subpath->startup_cost) - * count_rows / subpath->rows; - pathnode->path.rows = count_rows; - if (pathnode->path.rows < 1) - pathnode->path.rows = 1; + count_rows = clamp_row_est(input_rows * 0.10); + if (count_rows > *rows) + count_rows = *rows; + if (input_rows > 0) + *total_cost = *startup_cost + + (input_total_cost - input_startup_cost) + * count_rows / input_rows; + *rows = count_rows; + if (*rows < 1) + *rows = 1; } - - return pathnode; } @@ -3565,6 +3718,11 @@ reparameterize_path(PlannerInfo *root, Path *path, spath->path.pathkeys, required_outer); } + case T_Result: + /* Supported only for RTE_RESULT scan paths */ + if (IsA(path, Path)) + return create_resultscan_path(root, rel, required_outer); + break; case T_Append: { AppendPath *apath = (AppendPath *) path; @@ -3593,7 +3751,7 @@ reparameterize_path(PlannerInfo *root, Path *path, } return (Path *) create_append_path(root, rel, childpaths, partialpaths, - required_outer, + apath->path.pathkeys, required_outer, apath->path.parallel_workers, apath->path.parallel_aware, apath->partitioned_rels, @@ -3682,7 +3840,6 @@ do { \ FLAT_COPY_PATH(ipath, path, IndexPath); ADJUST_CHILD_ATTRS(ipath->indexclauses); - ADJUST_CHILD_ATTRS(ipath->indexquals); new_path = (Path *) ipath; } break; @@ -3721,12 +3878,8 @@ do { \ { TidPath *tpath; - /* - * TidPath contains tidquals, which do not contain any - * external parameters per create_tidscan_path(). So don't - * bother to translate those. - */ FLAT_COPY_PATH(tpath, path, TidPath); + ADJUST_CHILD_ATTRS(tpath->tidquals); new_path = (Path *) tpath; } break; @@ -3821,7 +3974,7 @@ do { \ } break; - case T_MergeAppend: + case T_MergeAppendPath: { MergeAppendPath *mapath; diff --git a/src/backend/optimizer/util/placeholder.c b/src/backend/optimizer/util/placeholder.c index c79d0f25d47..798aa8c5978 100644 --- a/src/backend/optimizer/util/placeholder.c +++ b/src/backend/optimizer/util/placeholder.c @@ -4,7 +4,7 @@ * PlaceHolderVar and PlaceHolderInfo manipulation routines * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,11 +17,10 @@ #include "nodes/nodeFuncs.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/placeholder.h" #include "optimizer/planmain.h" -#include "optimizer/prep.h" -#include "optimizer/var.h" #include "utils/lsyscache.h" /* Local functions */ @@ -415,10 +414,6 @@ add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, Relids relids = joinrel->relids; ListCell *lc; - /* This function is called only on the parent relations. */ - Assert(!IS_OTHER_REL(joinrel) && !IS_OTHER_REL(outer_rel) && - !IS_OTHER_REL(inner_rel)); - foreach(lc, root->placeholder_list) { PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc); @@ -464,56 +459,3 @@ add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, } } } - -/* - * add_placeholders_to_child_joinrel - * Translate the PHVs in parent's targetlist and add them to the child's - * targetlist. Also adjust the cost - */ -void -add_placeholders_to_child_joinrel(PlannerInfo *root, RelOptInfo *childrel, - RelOptInfo *parentrel) -{ - ListCell *lc; - AppendRelInfo **appinfos; - int nappinfos; - - Assert(IS_JOIN_REL(childrel) && IS_JOIN_REL(parentrel)); - Assert(IS_OTHER_REL(childrel)); - - /* Nothing to do if no PHVs. */ - if (root->placeholder_list == NIL) - return; - - appinfos = find_appinfos_by_relids(root, childrel->relids, &nappinfos); - foreach(lc, parentrel->reltarget->exprs) - { - PlaceHolderVar *phv = lfirst(lc); - - if (IsA(phv, PlaceHolderVar)) - { - /* - * In case the placeholder Var refers to any of the parent - * relations, translate it to refer to the corresponding child. - */ - if (bms_overlap(phv->phrels, parentrel->relids) && - childrel->reloptkind == RELOPT_OTHER_JOINREL) - { - phv = (PlaceHolderVar *) adjust_appendrel_attrs(root, - (Node *) phv, - nappinfos, - appinfos); - } - - childrel->reltarget->exprs = lappend(childrel->reltarget->exprs, - phv); - } - } - - /* Adjust the cost and width of child targetlist. */ - childrel->reltarget->cost.startup = parentrel->reltarget->cost.startup; - childrel->reltarget->cost.per_tuple = parentrel->reltarget->cost.per_tuple; - childrel->reltarget->width = parentrel->reltarget->width; - - pfree(appinfos); -} diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 90bb0c28041..cf1761401dd 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -4,7 +4,7 @@ * routines for accessing the system catalogs * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,26 +18,29 @@ #include #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/nbtree.h" +#include "access/tableam.h" #include "access/sysattr.h" +#include "access/table.h" #include "access/transam.h" #include "access/xlog.h" #include "catalog/catalog.h" #include "catalog/dependency.h" #include "catalog/heap.h" -#include "catalog/partition.h" #include "catalog/pg_am.h" +#include "catalog/pg_proc.h" #include "catalog/pg_statistic_ext.h" #include "foreign/fdwapi.h" #include "miscadmin.h" #include "nodes/makefuncs.h" +#include "nodes/supportnodes.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/plancat.h" -#include "optimizer/predtest.h" #include "optimizer/prep.h" +#include "partitioning/partdesc.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" #include "rewrite/rewriteManip.h" @@ -45,8 +48,9 @@ #include "storage/bufmgr.h" #include "utils/builtins.h" #include "utils/lsyscache.h" -#include "utils/syscache.h" +#include "utils/partcache.h" #include "utils/rel.h" +#include "utils/syscache.h" #include "utils/snapmgr.h" @@ -58,21 +62,25 @@ get_relation_info_hook_type get_relation_info_hook = NULL; static void get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel, - Relation relation, bool inhparent); + Relation relation, bool inhparent); static bool infer_collation_opclass_match(InferenceElem *elem, Relation idxRel, - List *idxExprs); -static int32 get_rel_data_width(Relation rel, int32 *attr_widths); + List *idxExprs); static List *get_relation_constraints(PlannerInfo *root, - Oid relationObjectId, RelOptInfo *rel, - bool include_notnull); + Oid relationObjectId, RelOptInfo *rel, + bool include_noinherit, + bool include_notnull, + bool include_partition); static List *build_index_tlist(PlannerInfo *root, IndexOptInfo *index, - Relation heapRelation); + Relation heapRelation); static List *get_relation_statistics(RelOptInfo *rel, Relation relation); static void set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel, - Relation relation); + Relation relation); static PartitionScheme find_partition_scheme(PlannerInfo *root, Relation rel); static void set_baserel_partition_key_exprs(Relation relation, - RelOptInfo *rel); + RelOptInfo *rel); +static void set_baserel_partition_constraint(Relation relation, + RelOptInfo *rel); + /* * get_relation_info - @@ -116,7 +124,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, * the rewriter or when expand_inherited_rtentry() added it to the query's * rangetable. */ - relation = heap_open(relationObjectId, NoLock); + relation = table_open(relationObjectId, NoLock); /* Temporary and unlogged relations are inaccessible during recovery. */ if (!RelationNeedsWAL(relation) && RecoveryInProgress()) @@ -136,9 +144,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, /* * Estimate relation size --- unless it's an inheritance parent, in which - * case the size will be computed later in set_append_rel_pathlist, and we - * must leave it zero for now to avoid bollixing the total_table_pages - * calculation. + * case the size we want is not the rel's own size but the size of its + * inheritance tree. That will be computed in set_append_rel_size(). */ if (!inhparent) estimate_rel_size(relation, rel->attr_widths - rel->min_attr, @@ -160,8 +167,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (hasindex) { List *indexoidlist; - ListCell *l; LOCKMODE lmode; + ListCell *l; indexoidlist = RelationGetIndexList(relation); @@ -170,13 +177,10 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, * need, and do not release it. This saves a couple of trips to the * shared lock manager while not creating any real loss of * concurrency, because no schema changes could be happening on the - * index while we hold lock on the parent rel, and neither lock type - * blocks any other kind of index operation. + * index while we hold lock on the parent rel, and no lock type used + * for queries blocks any other kind of index operation. */ - if (rel->relid == root->parse->resultRelation) - lmode = RowExclusiveLock; - else - lmode = AccessShareLock; + lmode = root->simple_rte_array[varno]->rellockmode; foreach(l, indexoidlist) { @@ -200,9 +204,9 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, * queries. Note that this is OK because the data structure we * are constructing is only used by the planner --- the executor * still needs to insert into "invalid" indexes, if they're marked - * IndexIsReady. + * indisready. */ - if (!IndexIsValid(index)) + if (!index->indisvalid) { index_close(indexRelation, NoLock); continue; @@ -242,7 +246,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->nkeycolumns = nkeycolumns = index->indnkeyatts; info->indexkeys = (int *) palloc(sizeof(int) * ncolumns); - info->indexcollations = (Oid *) palloc(sizeof(Oid) * ncolumns); + info->indexcollations = (Oid *) palloc(sizeof(Oid) * nkeycolumns); info->opfamily = (Oid *) palloc(sizeof(Oid) * nkeycolumns); info->opcintype = (Oid *) palloc(sizeof(Oid) * nkeycolumns); info->canreturn = (bool *) palloc(sizeof(bool) * ncolumns); @@ -250,7 +254,6 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, for (i = 0; i < ncolumns; i++) { info->indexkeys[i] = index->indkey.values[i]; - info->indexcollations[i] = indexRelation->rd_indcollation[i]; info->canreturn[i] = index_can_return(indexRelation, i + 1); } @@ -258,19 +261,21 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, { info->opfamily[i] = indexRelation->rd_opfamily[i]; info->opcintype[i] = indexRelation->rd_opcintype[i]; + info->indexcollations[i] = indexRelation->rd_indcollation[i]; } info->relam = indexRelation->rd_rel->relam; - /* We copy just the fields we need, not all of rd_amroutine */ - amroutine = indexRelation->rd_amroutine; + /* We copy just the fields we need, not all of rd_indam */ + amroutine = indexRelation->rd_indam; info->amcanorderbyop = amroutine->amcanorderbyop; info->amoptionalkey = amroutine->amoptionalkey; info->amsearcharray = amroutine->amsearcharray; info->amsearchnulls = amroutine->amsearchnulls; info->amcanparallel = amroutine->amcanparallel; info->amhasgettuple = (amroutine->amgettuple != NULL); - info->amhasgetbitmap = (amroutine->amgetbitmap != NULL); + info->amhasgetbitmap = amroutine->amgetbitmap != NULL && + relation->rd_tableam->scan_bitmap_next_block != NULL; info->amcostestimate = amroutine->amcostestimate; Assert(info->amcostestimate != NULL); @@ -417,6 +422,13 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, index_close(indexRelation, NoLock); + /* + * We've historically used lcons() here. It'd make more sense to + * use lappend(), but that causes the planner to change behavior + * in cases where two indexes seem equally attractive. For now, + * stick with lcons() --- few tables should have so many indexes + * that the O(N^2) behavior of lcons() is really a problem. + */ indexinfos = lcons(info, indexinfos); } @@ -449,7 +461,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, if (inhparent && relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) set_relation_partition_info(root, rel, relation); - heap_close(relation, NoLock); + table_close(relation, NoLock); /* * Allow a plugin to editorialize on the info we obtained from the @@ -589,8 +601,8 @@ infer_arbiter_indexes(PlannerInfo *root) OnConflictExpr *onconflict = root->parse->onConflict; /* Iteration state */ + RangeTblEntry *rte; Relation relation; - Oid relationObjectId; Oid indexOidFromConstraint = InvalidOid; List *indexList; ListCell *l; @@ -617,10 +629,9 @@ infer_arbiter_indexes(PlannerInfo *root) * the rewriter or when expand_inherited_rtentry() added it to the query's * rangetable. */ - relationObjectId = rt_fetch(root->parse->resultRelation, - root->parse->rtable)->relid; + rte = rt_fetch(root->parse->resultRelation, root->parse->rtable); - relation = heap_open(relationObjectId, NoLock); + relation = table_open(rte->relid, NoLock); /* * Build normalized/BMS representation of plain indexed attributes, as @@ -684,18 +695,17 @@ infer_arbiter_indexes(PlannerInfo *root) ListCell *el; /* - * Extract info from the relation descriptor for the index. We know - * that this is a target, so get lock type it is known will ultimately - * be required by the executor. + * Extract info from the relation descriptor for the index. Obtain + * the same lock type that the executor will ultimately use. * * Let executor complain about !indimmediate case directly, because * enforcement needs to occur there anyway when an inference clause is * omitted. */ - idxRel = index_open(indexoid, RowExclusiveLock); + idxRel = index_open(indexoid, rte->rellockmode); idxForm = idxRel->rd_index; - if (!IndexIsValid(idxForm)) + if (!idxForm->indisvalid) goto next; /* @@ -719,7 +729,7 @@ infer_arbiter_indexes(PlannerInfo *root) results = lappend_oid(results, idxForm->indexrelid); list_free(indexList); index_close(idxRel, NoLock); - heap_close(relation, NoLock); + table_close(relation, NoLock); return results; } else if (indexOidFromConstraint != InvalidOid) @@ -814,7 +824,7 @@ infer_arbiter_indexes(PlannerInfo *root) } list_free(indexList); - heap_close(relation, NoLock); + table_close(relation, NoLock); if (results == NIL) ereport(ERROR, @@ -946,47 +956,26 @@ estimate_rel_size(Relation rel, int32 *attr_widths, switch (rel->rd_rel->relkind) { case RELKIND_RELATION: - case RELKIND_INDEX: case RELKIND_MATVIEW: case RELKIND_TOASTVALUE: - /* it has storage, ok to call the smgr */ - curpages = RelationGetNumberOfBlocks(rel); + table_relation_estimate_size(rel, attr_widths, pages, tuples, + allvisfrac); + break; + + case RELKIND_INDEX: /* - * HACK: if the relation has never yet been vacuumed, use a - * minimum size estimate of 10 pages. The idea here is to avoid - * assuming a newly-created table is really small, even if it - * currently is, because that may not be true once some data gets - * loaded into it. Once a vacuum or analyze cycle has been done - * on it, it's more reasonable to believe the size is somewhat - * stable. - * - * (Note that this is only an issue if the plan gets cached and - * used again after the table has been filled. What we're trying - * to avoid is using a nestloop-type plan on a table that has - * grown substantially since the plan was made. Normally, - * autovacuum/autoanalyze will occur once enough inserts have - * happened and cause cached-plan invalidation; but that doesn't - * happen instantaneously, and it won't happen at all for cases - * such as temporary tables.) - * - * We approximate "never vacuumed" by "has relpages = 0", which - * means this will also fire on genuinely empty relations. Not - * great, but fortunately that's a seldom-seen case in the real - * world, and it shouldn't degrade the quality of the plan too - * much anyway to err in this direction. - * - * There are two exceptions wherein we don't apply this heuristic. - * One is if the table has inheritance children. Totally empty - * parent tables are quite common, so we should be willing to - * believe that they are empty. Also, we don't apply the 10-page - * minimum to indexes. + * XXX: It'd probably be good to move this into a callback, + * individual index types e.g. know if they have a metapage. */ - if (curpages < 10 && - rel->rd_rel->relpages == 0 && - !rel->rd_rel->relhassubclass && - rel->rd_rel->relkind != RELKIND_INDEX) - curpages = 10; + + /* it has storage, ok to call the smgr */ + curpages = RelationGetNumberOfBlocks(rel); + + /* coerce values in pg_class to more desirable types */ + relpages = (BlockNumber) rel->rd_rel->relpages; + reltuples = (double) rel->rd_rel->reltuples; + relallvisible = (BlockNumber) rel->rd_rel->relallvisible; /* report estimated # pages */ *pages = curpages; @@ -1003,13 +992,12 @@ estimate_rel_size(Relation rel, int32 *attr_widths, relallvisible = (BlockNumber) rel->rd_rel->relallvisible; /* - * If it's an index, discount the metapage while estimating the - * number of tuples. This is a kluge because it assumes more than - * it ought to about index structure. Currently it's OK for - * btree, hash, and GIN indexes but suspect for GiST indexes. + * Discount the metapage while estimating the number of tuples. + * This is a kluge because it assumes more than it ought to about + * index structure. Currently it's OK for btree, hash, and GIN + * indexes but suspect for GiST indexes. */ - if (rel->rd_rel->relkind == RELKIND_INDEX && - relpages > 0) + if (relpages > 0) { curpages--; relpages--; @@ -1034,6 +1022,8 @@ estimate_rel_size(Relation rel, int32 *attr_widths, * considering how crude the estimate is, and (b) it creates * platform dependencies in the default plans which are kind * of a headache for regression testing. + * + * XXX: Should this logic be more index specific? */ int32 tuple_width; @@ -1058,6 +1048,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths, else *allvisfrac = (double) relallvisible / curpages; break; + case RELKIND_SEQUENCE: /* Sequences always have a known size */ *pages = 1; @@ -1093,7 +1084,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths, * since they might be mostly NULLs, treating them as zero-width is not * necessarily the wrong thing anyway. */ -static int32 +int32 get_rel_data_width(Relation rel, int32 *attr_widths) { int32 tuple_width = 0; @@ -1142,11 +1133,11 @@ get_relation_data_width(Oid relid, int32 *attr_widths) Relation relation; /* As above, assume relation is already locked */ - relation = heap_open(relid, NoLock); + relation = table_open(relid, NoLock); result = get_rel_data_width(relation, attr_widths); - heap_close(relation, NoLock); + table_close(relation, NoLock); return result; } @@ -1155,16 +1146,22 @@ get_relation_data_width(Oid relid, int32 *attr_widths) /* * get_relation_constraints * - * Retrieve the validated CHECK constraint expressions of the given relation. + * Retrieve the applicable constraint expressions of the given relation. * * Returns a List (possibly empty) of constraint expressions. Each one * has been canonicalized, and its Vars are changed to have the varno * indicated by rel->relid. This allows the expressions to be easily * compared to expressions taken from WHERE. * + * If include_noinherit is true, it's okay to include constraints that + * are marked NO INHERIT. + * * If include_notnull is true, "col IS NOT NULL" expressions are generated * and added to the result for each column that's marked attnotnull. * + * If include_partition is true, and the relation is a partition, + * also include the partitioning constraints. + * * Note: at present this is invoked at most once per relation per planner * run, and in many cases it won't be invoked at all, so there seems no * point in caching the data in RelOptInfo. @@ -1172,7 +1169,9 @@ get_relation_data_width(Oid relid, int32 *attr_widths) static List * get_relation_constraints(PlannerInfo *root, Oid relationObjectId, RelOptInfo *rel, - bool include_notnull) + bool include_noinherit, + bool include_notnull, + bool include_partition) { List *result = NIL; Index varno = rel->relid; @@ -1182,7 +1181,7 @@ get_relation_constraints(PlannerInfo *root, /* * We assume the relation has already been safely locked. */ - relation = heap_open(relationObjectId, NoLock); + relation = table_open(relationObjectId, NoLock); constr = relation->rd_att->constr; if (constr != NULL) @@ -1196,10 +1195,13 @@ get_relation_constraints(PlannerInfo *root, /* * If this constraint hasn't been fully validated yet, we must - * ignore it here. + * ignore it here. Also ignore if NO INHERIT and we weren't told + * that that's safe. */ if (!constr->check[i].ccvalid) continue; + if (constr->check[i].ccnoinherit && !include_noinherit) + continue; cexpr = stringToNode(constr->check[i].ccbin); @@ -1264,36 +1266,16 @@ get_relation_constraints(PlannerInfo *root, } /* - * Append partition predicates, if any. - * - * For selects, partition pruning uses the parent table's partition bound - * descriptor, instead of constraint exclusion which is driven by the - * individual partition's partition constraint. + * Add partitioning constraints, if requested. */ - if (root->parse->commandType != CMD_SELECT) + if (include_partition && relation->rd_rel->relispartition) { - List *pcqual = RelationGetPartitionQual(relation); - - if (pcqual) - { - /* - * Run the partition quals through const-simplification similar to - * check constraints. We skip canonicalize_qual, though, because - * partition quals should be in canonical form already; also, - * since the qual is in implicit-AND format, we'd have to - * explicitly convert it to explicit-AND format and back again. - */ - pcqual = (List *) eval_const_expressions(root, (Node *) pcqual); - - /* Fix Vars to have the desired varno */ - if (varno != 1) - ChangeVarNodes((Node *) pcqual, 1, varno, 0); - - result = list_concat(result, pcqual); - } + /* make sure rel->partition_qual is set */ + set_baserel_partition_constraint(relation, rel); + result = list_concat(result, rel->partition_qual); } - heap_close(relation, NoLock); + table_close(relation, NoLock); return result; } @@ -1320,14 +1302,19 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) Oid statOid = lfirst_oid(l); Form_pg_statistic_ext staForm; HeapTuple htup; + HeapTuple dtup; Bitmapset *keys = NULL; int i; htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statOid)); - if (!htup) + if (!HeapTupleIsValid(htup)) elog(ERROR, "cache lookup failed for statistics object %u", statOid); staForm = (Form_pg_statistic_ext) GETSTRUCT(htup); + dtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statOid)); + if (!HeapTupleIsValid(dtup)) + elog(ERROR, "cache lookup failed for statistics object %u", statOid); + /* * First, build the array of columns covered. This is ultimately * wasted if no stats within the object have actually been built, but @@ -1337,7 +1324,7 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) keys = bms_add_member(keys, staForm->stxkeys.values[i]); /* add one StatisticExtInfo for each kind built */ - if (statext_is_kind_built(htup, STATS_EXT_NDISTINCT)) + if (statext_is_kind_built(dtup, STATS_EXT_NDISTINCT)) { StatisticExtInfo *info = makeNode(StatisticExtInfo); @@ -1346,10 +1333,10 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) info->kind = STATS_EXT_NDISTINCT; info->keys = bms_copy(keys); - stainfos = lcons(info, stainfos); + stainfos = lappend(stainfos, info); } - if (statext_is_kind_built(htup, STATS_EXT_DEPENDENCIES)) + if (statext_is_kind_built(dtup, STATS_EXT_DEPENDENCIES)) { StatisticExtInfo *info = makeNode(StatisticExtInfo); @@ -1358,10 +1345,23 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) info->kind = STATS_EXT_DEPENDENCIES; info->keys = bms_copy(keys); - stainfos = lcons(info, stainfos); + stainfos = lappend(stainfos, info); + } + + if (statext_is_kind_built(dtup, STATS_EXT_MCV)) + { + StatisticExtInfo *info = makeNode(StatisticExtInfo); + + info->statOid = statOid; + info->rel = rel; + info->kind = STATS_EXT_MCV; + info->keys = bms_copy(keys); + + stainfos = lappend(stainfos, info); } ReleaseSysCache(htup); + ReleaseSysCache(dtup); bms_free(keys); } @@ -1375,7 +1375,7 @@ get_relation_statistics(RelOptInfo *rel, Relation relation) * * Detect whether the relation need not be scanned because it has either * self-inconsistent restrictions, or restrictions inconsistent with the - * relation's validated CHECK constraints. + * relation's applicable constraints. * * Note: this examines only rel->relid, rel->reloptkind, and * rel->baserestrictinfo; therefore it can be called before filling in @@ -1385,6 +1385,9 @@ bool relation_excluded_by_constraints(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte) { + bool include_noinherit; + bool include_notnull; + bool include_partition = false; List *safe_restrictions; List *constraint_pred; List *safe_constraints; @@ -1393,6 +1396,13 @@ relation_excluded_by_constraints(PlannerInfo *root, /* As of now, constraint exclusion works only with simple relations. */ Assert(IS_SIMPLE_REL(rel)); + /* + * If there are no base restriction clauses, we have no hope of proving + * anything below, so fall out quickly. + */ + if (rel->baserestrictinfo == NIL) + return false; + /* * Regardless of the setting of constraint_exclusion, detect * constant-FALSE-or-NULL restriction clauses. Because const-folding will @@ -1413,14 +1423,49 @@ relation_excluded_by_constraints(PlannerInfo *root, return true; } - /* Skip further tests if constraint exclusion is disabled for the rel */ - if (constraint_exclusion == CONSTRAINT_EXCLUSION_OFF || - (constraint_exclusion == CONSTRAINT_EXCLUSION_PARTITION && - !(rel->reloptkind == RELOPT_OTHER_MEMBER_REL || - (root->hasInheritedTarget && - rel->reloptkind == RELOPT_BASEREL && - rel->relid == root->parse->resultRelation)))) - return false; + /* + * Skip further tests, depending on constraint_exclusion. + */ + switch (constraint_exclusion) + { + case CONSTRAINT_EXCLUSION_OFF: + /* In 'off' mode, never make any further tests */ + return false; + + case CONSTRAINT_EXCLUSION_PARTITION: + + /* + * When constraint_exclusion is set to 'partition' we only handle + * appendrel members. Normally, they are RELOPT_OTHER_MEMBER_REL + * relations, but we also consider inherited target relations as + * appendrel members for the purposes of constraint exclusion + * (since, indeed, they were appendrel members earlier in + * inheritance_planner). + * + * In both cases, partition pruning was already applied, so there + * is no need to consider the rel's partition constraints here. + */ + if (rel->reloptkind == RELOPT_OTHER_MEMBER_REL || + (rel->relid == root->parse->resultRelation && + root->inhTargetKind != INHKIND_NONE)) + break; /* appendrel member, so process it */ + return false; + + case CONSTRAINT_EXCLUSION_ON: + + /* + * In 'on' mode, always apply constraint exclusion. If we are + * considering a baserel that is a partition (i.e., it was + * directly named rather than expanded from a parent table), then + * its partition constraints haven't been considered yet, so + * include them in the processing here. + */ + if (rel->reloptkind == RELOPT_BASEREL && + !(rel->relid == root->parse->resultRelation && + root->inhTargetKind != INHKIND_NONE)) + include_partition = true; + break; /* always try to exclude */ + } /* * Check for self-contradictory restriction clauses. We dare not make @@ -1447,24 +1492,33 @@ relation_excluded_by_constraints(PlannerInfo *root, return true; /* - * Only plain relations have constraints. In a partitioning hierarchy, - * but not with regular table inheritance, it's OK to assume that any - * constraints that hold for the parent also hold for every child; for - * instance, table inheritance allows the parent to have constraints - * marked NO INHERIT, but table partitioning does not. We choose to check - * whether the partitioning parents can be excluded here; doing so - * consumes some cycles, but potentially saves us the work of excluding - * each child individually. + * Only plain relations have constraints, so stop here for other rtekinds. */ - if (rte->rtekind != RTE_RELATION || - (rte->inh && rte->relkind != RELKIND_PARTITIONED_TABLE)) + if (rte->rtekind != RTE_RELATION) return false; /* - * OK to fetch the constraint expressions. Include "col IS NOT NULL" - * expressions for attnotnull columns, in case we can refute those. + * If we are scanning just this table, we can use NO INHERIT constraints, + * but not if we're scanning its children too. (Note that partitioned + * tables should never have NO INHERIT constraints; but it's not necessary + * for us to assume that here.) + */ + include_noinherit = !rte->inh; + + /* + * Currently, attnotnull constraints must be treated as NO INHERIT unless + * this is a partitioned table. In future we might track their + * inheritance status more accurately, allowing this to be refined. + */ + include_notnull = (!rte->inh || rte->relkind == RELKIND_PARTITIONED_TABLE); + + /* + * Fetch the appropriate set of constraint expressions. */ - constraint_pred = get_relation_constraints(root, rte->relid, rel, true); + constraint_pred = get_relation_constraints(root, rte->relid, rel, + include_noinherit, + include_notnull, + include_partition); /* * We do not currently enforce that CHECK constraints contain only @@ -1541,7 +1595,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel) { case RTE_RELATION: /* Assume we already have adequate lock */ - relation = heap_open(rte->relid, NoLock); + relation = table_open(rte->relid, NoLock); numattrs = RelationGetNumberOfAttributes(relation); for (attrno = 1; attrno <= numattrs; attrno++) @@ -1570,7 +1624,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel) false)); } - heap_close(relation, NoLock); + table_close(relation, NoLock); break; case RTE_SUBQUERY: @@ -1598,6 +1652,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel) case RTE_VALUES: case RTE_CTE: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* Not all of these can have dropped cols, but share code anyway */ expandRTE(rte, varno, 0, -1, true /* include dropped */ , NULL, &colvars); @@ -1661,11 +1716,10 @@ build_index_tlist(PlannerInfo *root, IndexOptInfo *index, if (indexkey != 0) { /* simple column */ - Form_pg_attribute att_tup; + const FormData_pg_attribute *att_tup; if (indexkey < 0) - att_tup = SystemAttributeDefinition(indexkey, - heapRelation->rd_rel->relhasoids); + att_tup = SystemAttributeDefinition(indexkey); else att_tup = TupleDescAttr(heapRelation->rd_att, indexkey - 1); @@ -1682,7 +1736,7 @@ build_index_tlist(PlannerInfo *root, IndexOptInfo *index, if (indexpr_item == NULL) elog(ERROR, "wrong number of index expressions"); indexvar = (Expr *) lfirst(indexpr_item); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(index->indexprs, indexpr_item); } tlist = lappend(tlist, @@ -1742,6 +1796,8 @@ restriction_selectivity(PlannerInfo *root, * Returns the selectivity of a specified join operator clause. * This code executes registered procedures stored in the * operator relation, by calling the function manager. + * + * See clause_selectivity() for the meaning of the additional parameters. */ Selectivity join_selectivity(PlannerInfo *root, @@ -1775,6 +1831,184 @@ join_selectivity(PlannerInfo *root, return (Selectivity) result; } +/* + * function_selectivity + * + * Returns the selectivity of a specified boolean function clause. + * This code executes registered procedures stored in the + * pg_proc relation, by calling the function manager. + * + * See clause_selectivity() for the meaning of the additional parameters. + */ +Selectivity +function_selectivity(PlannerInfo *root, + Oid funcid, + List *args, + Oid inputcollid, + bool is_join, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo) +{ + RegProcedure prosupport = get_func_support(funcid); + SupportRequestSelectivity req; + SupportRequestSelectivity *sresult; + + /* + * If no support function is provided, use our historical default + * estimate, 0.3333333. This seems a pretty unprincipled choice, but + * Postgres has been using that estimate for function calls since 1992. + * The hoariness of this behavior suggests that we should not be in too + * much hurry to use another value. + */ + if (!prosupport) + return (Selectivity) 0.3333333; + + req.type = T_SupportRequestSelectivity; + req.root = root; + req.funcid = funcid; + req.args = args; + req.inputcollid = inputcollid; + req.is_join = is_join; + req.varRelid = varRelid; + req.jointype = jointype; + req.sjinfo = sjinfo; + req.selectivity = -1; /* to catch failure to set the value */ + + sresult = (SupportRequestSelectivity *) + DatumGetPointer(OidFunctionCall1(prosupport, + PointerGetDatum(&req))); + + /* If support function fails, use default */ + if (sresult != &req) + return (Selectivity) 0.3333333; + + if (req.selectivity < 0.0 || req.selectivity > 1.0) + elog(ERROR, "invalid function selectivity: %f", req.selectivity); + + return (Selectivity) req.selectivity; +} + +/* + * add_function_cost + * + * Get an estimate of the execution cost of a function, and *add* it to + * the contents of *cost. The estimate may include both one-time and + * per-tuple components, since QualCost does. + * + * The funcid must always be supplied. If it is being called as the + * implementation of a specific parsetree node (FuncExpr, OpExpr, + * WindowFunc, etc), pass that as "node", else pass NULL. + * + * In some usages root might be NULL, too. + */ +void +add_function_cost(PlannerInfo *root, Oid funcid, Node *node, + QualCost *cost) +{ + HeapTuple proctup; + Form_pg_proc procform; + + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + if (!HeapTupleIsValid(proctup)) + elog(ERROR, "cache lookup failed for function %u", funcid); + procform = (Form_pg_proc) GETSTRUCT(proctup); + + if (OidIsValid(procform->prosupport)) + { + SupportRequestCost req; + SupportRequestCost *sresult; + + req.type = T_SupportRequestCost; + req.root = root; + req.funcid = funcid; + req.node = node; + + /* Initialize cost fields so that support function doesn't have to */ + req.startup = 0; + req.per_tuple = 0; + + sresult = (SupportRequestCost *) + DatumGetPointer(OidFunctionCall1(procform->prosupport, + PointerGetDatum(&req))); + + if (sresult == &req) + { + /* Success, so accumulate support function's estimate into *cost */ + cost->startup += req.startup; + cost->per_tuple += req.per_tuple; + ReleaseSysCache(proctup); + return; + } + } + + /* No support function, or it failed, so rely on procost */ + cost->per_tuple += procform->procost * cpu_operator_cost; + + ReleaseSysCache(proctup); +} + +/* + * get_function_rows + * + * Get an estimate of the number of rows returned by a set-returning function. + * + * The funcid must always be supplied. In current usage, the calling node + * will always be supplied, and will be either a FuncExpr or OpExpr. + * But it's a good idea to not fail if it's NULL. + * + * In some usages root might be NULL, too. + * + * Note: this returns the unfiltered result of the support function, if any. + * It's usually a good idea to apply clamp_row_est() to the result, but we + * leave it to the caller to do so. + */ +double +get_function_rows(PlannerInfo *root, Oid funcid, Node *node) +{ + HeapTuple proctup; + Form_pg_proc procform; + double result; + + proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); + if (!HeapTupleIsValid(proctup)) + elog(ERROR, "cache lookup failed for function %u", funcid); + procform = (Form_pg_proc) GETSTRUCT(proctup); + + Assert(procform->proretset); /* else caller error */ + + if (OidIsValid(procform->prosupport)) + { + SupportRequestRows req; + SupportRequestRows *sresult; + + req.type = T_SupportRequestRows; + req.root = root; + req.funcid = funcid; + req.node = node; + + req.rows = 0; /* just for sanity */ + + sresult = (SupportRequestRows *) + DatumGetPointer(OidFunctionCall1(procform->prosupport, + PointerGetDatum(&req))); + + if (sresult == &req) + { + /* Success */ + ReleaseSysCache(proctup); + return req.rows; + } + } + + /* No support function, or it failed, so rely on prorows */ + result = procform->prorows; + + ReleaseSysCache(proctup); + + return result; +} + /* * has_unique_index * @@ -1828,7 +2062,7 @@ has_row_triggers(PlannerInfo *root, Index rti, CmdType event) bool result = false; /* Assume we already have adequate lock */ - relation = heap_open(rte->relid, NoLock); + relation = table_open(rte->relid, NoLock); trigDesc = relation->trigdesc; switch (event) @@ -1851,16 +2085,31 @@ has_row_triggers(PlannerInfo *root, Index rti, CmdType event) trigDesc->trig_delete_before_row)) result = true; break; - /* There is no separate event for MERGE, only INSERT/UPDATE/DELETE */ - case CMD_MERGE: - result = false; - break; default: elog(ERROR, "unrecognized CmdType: %d", (int) event); break; } + table_close(relation, NoLock); + return result; +} + +bool +has_stored_generated_columns(PlannerInfo *root, Index rti) +{ + RangeTblEntry *rte = planner_rt_fetch(rti, root); + Relation relation; + TupleDesc tupdesc; + bool result = false; + + /* Assume we already have adequate lock */ + relation = heap_open(rte->relid, NoLock); + + tupdesc = RelationGetDescr(relation); + result = tupdesc->constr && tupdesc->constr->has_generated_stored; + heap_close(relation, NoLock); + return result; } @@ -1874,18 +2123,20 @@ set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel, Relation relation) { PartitionDesc partdesc; - PartitionKey partkey; - Assert(relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); + /* Create the PartitionDirectory infrastructure if we didn't already */ + if (root->glob->partition_directory == NULL) + root->glob->partition_directory = + CreatePartitionDirectory(CurrentMemoryContext); - partdesc = RelationGetPartitionDesc(relation); - partkey = RelationGetPartitionKey(relation); + partdesc = PartitionDirectoryLookup(root->glob->partition_directory, + relation); rel->part_scheme = find_partition_scheme(root, relation); Assert(partdesc != NULL && rel->part_scheme != NULL); - rel->boundinfo = partition_bounds_copy(partdesc->boundinfo, partkey); + rel->boundinfo = partdesc->boundinfo; rel->nparts = partdesc->nparts; set_baserel_partition_key_exprs(relation, rel); - rel->partition_qual = RelationGetPartitionQual(relation); + set_baserel_partition_constraint(relation, rel); } /* @@ -2044,7 +2295,7 @@ set_baserel_partition_key_exprs(Relation relation, /* Re-stamp the expression with given varno. */ partexpr = (Expr *) copyObject(lfirst(lc)); ChangeVarNodes((Node *) partexpr, 1, varno, 0); - lc = lnext(lc); + lc = lnext(partkey->partexprs, lc); } partexprs[cnt] = list_make1(partexpr); @@ -2060,3 +2311,35 @@ set_baserel_partition_key_exprs(Relation relation, */ rel->nullable_partexprs = (List **) palloc0(sizeof(List *) * partnatts); } + +/* + * set_baserel_partition_constraint + * + * Builds the partition constraint for the given base relation and sets it + * in the given RelOptInfo. All Var nodes are restamped with the relid of the + * given relation. + */ +static void +set_baserel_partition_constraint(Relation relation, RelOptInfo *rel) +{ + List *partconstr; + + if (rel->partition_qual) /* already done */ + return; + + /* + * Run the partition quals through const-simplification similar to check + * constraints. We skip canonicalize_qual, though, because partition + * quals should be in canonical form already; also, since the qual is in + * implicit-AND format, we'd have to explicitly convert it to explicit-AND + * format and back again. + */ + partconstr = RelationGetPartitionQual(relation); + if (partconstr) + { + partconstr = (List *) expression_planner((Expr *) partconstr); + if (rel->relid != 1) + ChangeVarNodes((Node *) partconstr, 1, rel->relid, 0); + rel->partition_qual = partconstr; + } +} diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c index 446207de30f..08a160fff60 100644 --- a/src/backend/optimizer/util/predtest.c +++ b/src/backend/optimizer/util/predtest.c @@ -4,7 +4,7 @@ * Routines to attempt to prove logical implications between predicate * expressions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,9 +19,10 @@ #include "catalog/pg_type.h" #include "executor/executor.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/predtest.h" +#include "nodes/pathnodes.h" +#include "optimizer/optimizer.h" #include "utils/array.h" #include "utils/inval.h" #include "utils/lsyscache.h" @@ -58,6 +59,7 @@ typedef struct PredIterInfoData { /* node-type-specific iteration state */ void *state; + List *state_list; /* initialize to do the iteration */ void (*startup_fn) (Node *clause, PredIterInfo info); /* next-component iteration function */ @@ -78,9 +80,9 @@ typedef struct PredIterInfoData static bool predicate_implied_by_recurse(Node *clause, Node *predicate, - bool weak); + bool weak); static bool predicate_refuted_by_recurse(Node *clause, Node *predicate, - bool weak); + bool weak); static PredClass predicate_classify(Node *clause, PredIterInfo info); static void list_startup_fn(Node *clause, PredIterInfo info); static Node *list_next_fn(PredIterInfo info); @@ -93,18 +95,18 @@ static void arrayexpr_startup_fn(Node *clause, PredIterInfo info); static Node *arrayexpr_next_fn(PredIterInfo info); static void arrayexpr_cleanup_fn(PredIterInfo info); static bool predicate_implied_by_simple_clause(Expr *predicate, Node *clause, - bool weak); + bool weak); static bool predicate_refuted_by_simple_clause(Expr *predicate, Node *clause, - bool weak); + bool weak); static Node *extract_not_arg(Node *clause); static Node *extract_strong_not_arg(Node *clause); -static bool clause_is_strict_for(Node *clause, Node *subexpr); +static bool clause_is_strict_for(Node *clause, Node *subexpr, bool allow_false); static bool operator_predicate_proof(Expr *predicate, Node *clause, - bool refute_it, bool weak); + bool refute_it, bool weak); static bool operator_same_subexprs_proof(Oid pred_op, Oid clause_op, - bool refute_it); + bool refute_it); static bool operator_same_subexprs_lookup(Oid pred_op, Oid clause_op, - bool refute_it); + bool refute_it); static Oid get_btree_test_op(Oid pred_op, Oid clause_op, bool refute_it); static void InvalidateOprProofCacheCallBack(Datum arg, int cacheid, uint32 hashvalue); @@ -815,7 +817,7 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate, * This function also implements enforcement of MAX_SAOP_ARRAY_SIZE: if a * ScalarArrayOpExpr's array has too many elements, we just classify it as an * atom. (This will result in its being passed as-is to the simple_clause - * functions, which will fail to prove anything about it.) Note that we + * functions, many of which will fail to prove anything about it.) Note that we * cannot just stop after considering MAX_SAOP_ARRAY_SIZE elements; in general * that would result in wrong proofs, rather than failing to prove anything. */ @@ -839,14 +841,14 @@ predicate_classify(Node *clause, PredIterInfo info) } /* Handle normal AND and OR boolean clauses */ - if (and_clause(clause)) + if (is_andclause(clause)) { info->startup_fn = boolexpr_startup_fn; info->next_fn = list_next_fn; info->cleanup_fn = list_cleanup_fn; return CLASS_AND; } - if (or_clause(clause)) + if (is_orclause(clause)) { info->startup_fn = boolexpr_startup_fn; info->next_fn = list_next_fn; @@ -904,7 +906,8 @@ predicate_classify(Node *clause, PredIterInfo info) static void list_startup_fn(Node *clause, PredIterInfo info) { - info->state = (void *) list_head((List *) clause); + info->state_list = (List *) clause; + info->state = (void *) list_head(info->state_list); } static Node * @@ -916,7 +919,7 @@ list_next_fn(PredIterInfo info) if (l == NULL) return NULL; n = lfirst(l); - info->state = (void *) lnext(l); + info->state = (void *) lnext(info->state_list, l); return n; } @@ -933,7 +936,8 @@ list_cleanup_fn(PredIterInfo info) static void boolexpr_startup_fn(Node *clause, PredIterInfo info) { - info->state = (void *) list_head(((BoolExpr *) clause)->args); + info->state_list = ((BoolExpr *) clause)->args; + info->state = (void *) list_head(info->state_list); } /* @@ -1056,6 +1060,7 @@ arrayexpr_startup_fn(Node *clause, PredIterInfo info) /* Initialize iteration variable to first member of ArrayExpr */ arrayexpr = (ArrayExpr *) lsecond(saop->args); + info->state_list = arrayexpr->elements; state->next = list_head(arrayexpr->elements); } @@ -1067,7 +1072,7 @@ arrayexpr_next_fn(PredIterInfo info) if (state->next == NULL) return NULL; lsecond(state->opexpr.args) = lfirst(state->next); - state->next = lnext(state->next); + state->next = lnext(info->state_list, state->next); return (Node *) &(state->opexpr); } @@ -1098,8 +1103,8 @@ arrayexpr_cleanup_fn(PredIterInfo info) * * If the predicate is of the form "foo IS NOT NULL", and we are considering * strong implication, we can conclude that the predicate is implied if the - * clause is strict for "foo", i.e., it must yield NULL when "foo" is NULL. - * In that case truth of the clause requires that "foo" isn't NULL. + * clause is strict for "foo", i.e., it must yield false or NULL when "foo" + * is NULL. In that case truth of the clause ensures that "foo" isn't NULL. * (Again, this is a safe conclusion because "foo" must be immutable.) * This doesn't work for weak implication, though. * @@ -1130,7 +1135,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause, !ntest->argisrow) { /* strictness of clause for foo implies foo IS NOT NULL */ - if (clause_is_strict_for(clause, (Node *) ntest->arg)) + if (clause_is_strict_for(clause, (Node *) ntest->arg, true)) return true; } return false; /* we can't succeed below... */ @@ -1159,8 +1164,8 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause, * * A clause "foo IS NULL" refutes a predicate "foo IS NOT NULL" in all cases. * If we are considering weak refutation, it also refutes a predicate that - * is strict for "foo", since then the predicate must yield NULL (and since - * "foo" appears in the predicate, it's known immutable). + * is strict for "foo", since then the predicate must yield false or NULL + * (and since "foo" appears in the predicate, it's known immutable). * * (The main motivation for covering these IS [NOT] NULL cases is to support * using IS NULL/IS NOT NULL as partition-defining constraints.) @@ -1193,7 +1198,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause, return false; /* strictness of clause for foo refutes foo IS NULL */ - if (clause_is_strict_for(clause, (Node *) isnullarg)) + if (clause_is_strict_for(clause, (Node *) isnullarg, true)) return true; /* foo IS NOT NULL refutes foo IS NULL */ @@ -1225,7 +1230,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause, /* foo IS NULL weakly refutes any predicate that is strict for foo */ if (weak && - clause_is_strict_for((Node *) predicate, (Node *) isnullarg)) + clause_is_strict_for((Node *) predicate, (Node *) isnullarg, true)) return true; return false; /* we can't succeed below... */ @@ -1292,17 +1297,30 @@ extract_strong_not_arg(Node *clause) /* - * Can we prove that "clause" returns NULL if "subexpr" does? + * Can we prove that "clause" returns NULL (or FALSE) if "subexpr" is + * assumed to yield NULL? * - * The base case is that clause and subexpr are equal(). (We assume that - * the caller knows at least one of the input expressions is immutable, - * as this wouldn't hold for volatile expressions.) + * In most places in the planner, "strictness" refers to a guarantee that + * an expression yields NULL output for a NULL input, and that's mostly what + * we're looking for here. However, at top level where the clause is known + * to yield boolean, it may be sufficient to prove that it cannot return TRUE + * when "subexpr" is NULL. The caller should pass allow_false = true when + * this weaker property is acceptable. (When this function recurses + * internally, we pass down allow_false = false since we need to prove actual + * nullness of the subexpression.) + * + * We assume that the caller checked that least one of the input expressions + * is immutable. All of the proof rules here involve matching "subexpr" to + * some portion of "clause", so that this allows assuming that "subexpr" is + * immutable without a separate check. + * + * The base case is that clause and subexpr are equal(). * * We can also report success if the subexpr appears as a subexpression * of "clause" in a place where it'd force nullness of the overall result. */ static bool -clause_is_strict_for(Node *clause, Node *subexpr) +clause_is_strict_for(Node *clause, Node *subexpr, bool allow_false) { ListCell *lc; @@ -1335,7 +1353,7 @@ clause_is_strict_for(Node *clause, Node *subexpr) { foreach(lc, ((OpExpr *) clause)->args) { - if (clause_is_strict_for((Node *) lfirst(lc), subexpr)) + if (clause_is_strict_for((Node *) lfirst(lc), subexpr, false)) return true; } return false; @@ -1345,12 +1363,106 @@ clause_is_strict_for(Node *clause, Node *subexpr) { foreach(lc, ((FuncExpr *) clause)->args) { - if (clause_is_strict_for((Node *) lfirst(lc), subexpr)) + if (clause_is_strict_for((Node *) lfirst(lc), subexpr, false)) return true; } return false; } + /* + * CoerceViaIO is strict (whether or not the I/O functions it calls are). + * Likewise, ArrayCoerceExpr is strict for its array argument (regardless + * of what the per-element expression is), ConvertRowtypeExpr is strict at + * the row level, and CoerceToDomain is strict too. These are worth + * checking mainly because it saves us having to explain to users why some + * type coercions are known strict and others aren't. + */ + if (IsA(clause, CoerceViaIO)) + return clause_is_strict_for((Node *) ((CoerceViaIO *) clause)->arg, + subexpr, false); + if (IsA(clause, ArrayCoerceExpr)) + return clause_is_strict_for((Node *) ((ArrayCoerceExpr *) clause)->arg, + subexpr, false); + if (IsA(clause, ConvertRowtypeExpr)) + return clause_is_strict_for((Node *) ((ConvertRowtypeExpr *) clause)->arg, + subexpr, false); + if (IsA(clause, CoerceToDomain)) + return clause_is_strict_for((Node *) ((CoerceToDomain *) clause)->arg, + subexpr, false); + + /* + * ScalarArrayOpExpr is a special case. Note that we'd only reach here + * with a ScalarArrayOpExpr clause if we failed to deconstruct it into an + * AND or OR tree, as for example if it has too many array elements. + */ + if (IsA(clause, ScalarArrayOpExpr)) + { + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; + Node *scalarnode = (Node *) linitial(saop->args); + Node *arraynode = (Node *) lsecond(saop->args); + + /* + * If we can prove the scalar input to be null, and the operator is + * strict, then the SAOP result has to be null --- unless the array is + * empty. For an empty array, we'd get either false (for ANY) or true + * (for ALL). So if allow_false = true then the proof succeeds anyway + * for the ANY case; otherwise we can only make the proof if we can + * prove the array non-empty. + */ + if (clause_is_strict_for(scalarnode, subexpr, false) && + op_strict(saop->opno)) + { + int nelems = 0; + + if (allow_false && saop->useOr) + return true; /* can succeed even if array is empty */ + + if (arraynode && IsA(arraynode, Const)) + { + Const *arrayconst = (Const *) arraynode; + ArrayType *arrval; + + /* + * If array is constant NULL then we can succeed, as in the + * case below. + */ + if (arrayconst->constisnull) + return true; + + /* Otherwise, we can compute the number of elements. */ + arrval = DatumGetArrayTypeP(arrayconst->constvalue); + nelems = ArrayGetNItems(ARR_NDIM(arrval), ARR_DIMS(arrval)); + } + else if (arraynode && IsA(arraynode, ArrayExpr) && + !((ArrayExpr *) arraynode)->multidims) + { + /* + * We can also reliably count the number of array elements if + * the input is a non-multidim ARRAY[] expression. + */ + nelems = list_length(((ArrayExpr *) arraynode)->elements); + } + + /* Proof succeeds if array is definitely non-empty */ + if (nelems > 0) + return true; + } + + /* + * If we can prove the array input to be null, the proof succeeds in + * all cases, since ScalarArrayOpExpr will always return NULL for a + * NULL array. Otherwise, we're done here. + */ + return clause_is_strict_for(arraynode, subexpr, false); + } + + /* + * When recursing into an expression, we might find a NULL constant. + * That's certainly NULL, whether it matches subexpr or not. + */ + if (IsA(clause, Const)) + return ((Const *) clause)->constisnull; + return false; } diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index b9aa7486bae..85415381fb1 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -3,7 +3,7 @@ * relnode.c * Relation-node lookup/construction routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,16 +17,17 @@ #include #include "miscadmin.h" -#include "catalog/partition.h" +#include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/inherit.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/placeholder.h" #include "optimizer/plancat.h" -#include "optimizer/prep.h" #include "optimizer/restrictinfo.h" #include "optimizer/tlist.h" +#include "partitioning/partbounds.h" #include "utils/hsearch.h" @@ -37,48 +38,59 @@ typedef struct JoinHashEntry } JoinHashEntry; static void build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *input_rel); + RelOptInfo *input_rel); static List *build_joinrel_restrictlist(PlannerInfo *root, - RelOptInfo *joinrel, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel); + RelOptInfo *joinrel, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); static void build_joinrel_joinlist(RelOptInfo *joinrel, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel); + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); static List *subbuild_joinrel_restrictlist(RelOptInfo *joinrel, - List *joininfo_list, - List *new_restrictlist); + List *joininfo_list, + List *new_restrictlist); static List *subbuild_joinrel_joinlist(RelOptInfo *joinrel, - List *joininfo_list, - List *new_joininfo); + List *joininfo_list, + List *new_joininfo); static void set_foreign_rel_properties(RelOptInfo *joinrel, - RelOptInfo *outer_rel, RelOptInfo *inner_rel); + RelOptInfo *outer_rel, RelOptInfo *inner_rel); static void add_join_rel(PlannerInfo *root, RelOptInfo *joinrel); static void build_joinrel_partition_info(RelOptInfo *joinrel, - RelOptInfo *outer_rel, RelOptInfo *inner_rel, - List *restrictlist, JoinType jointype); + RelOptInfo *outer_rel, RelOptInfo *inner_rel, + List *restrictlist, JoinType jointype); +static void build_child_join_reltarget(PlannerInfo *root, + RelOptInfo *parentrel, + RelOptInfo *childrel, + int nappinfos, + AppendRelInfo **appinfos); /* * setup_simple_rel_arrays - * Prepare the arrays we use for quickly accessing base relations. + * Prepare the arrays we use for quickly accessing base relations + * and AppendRelInfos. */ void setup_simple_rel_arrays(PlannerInfo *root) { + int size; Index rti; ListCell *lc; /* Arrays are accessed using RT indexes (1..N) */ - root->simple_rel_array_size = list_length(root->parse->rtable) + 1; + size = list_length(root->parse->rtable) + 1; + root->simple_rel_array_size = size; - /* simple_rel_array is initialized to all NULLs */ + /* + * simple_rel_array is initialized to all NULLs, since no RelOptInfos + * exist yet. It'll be filled by later calls to build_simple_rel(). + */ root->simple_rel_array = (RelOptInfo **) - palloc0(root->simple_rel_array_size * sizeof(RelOptInfo *)); + palloc0(size * sizeof(RelOptInfo *)); /* simple_rte_array is an array equivalent of the rtable list */ root->simple_rte_array = (RangeTblEntry **) - palloc0(root->simple_rel_array_size * sizeof(RangeTblEntry *)); + palloc0(size * sizeof(RangeTblEntry *)); rti = 1; foreach(lc, root->parse->rtable) { @@ -86,6 +98,83 @@ setup_simple_rel_arrays(PlannerInfo *root) root->simple_rte_array[rti++] = rte; } + + /* append_rel_array is not needed if there are no AppendRelInfos */ + if (root->append_rel_list == NIL) + { + root->append_rel_array = NULL; + return; + } + + root->append_rel_array = (AppendRelInfo **) + palloc0(size * sizeof(AppendRelInfo *)); + + /* + * append_rel_array is filled with any already-existing AppendRelInfos, + * which currently could only come from UNION ALL flattening. We might + * add more later during inheritance expansion, but it's the + * responsibility of the expansion code to update the array properly. + */ + foreach(lc, root->append_rel_list) + { + AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc); + int child_relid = appinfo->child_relid; + + /* Sanity check */ + Assert(child_relid < size); + + if (root->append_rel_array[child_relid]) + elog(ERROR, "child relation already exists"); + + root->append_rel_array[child_relid] = appinfo; + } +} + +/* + * expand_planner_arrays + * Expand the PlannerInfo's per-RTE arrays by add_size members + * and initialize the newly added entries to NULLs + * + * Note: this causes the append_rel_array to become allocated even if + * it was not before. This is okay for current uses, because we only call + * this when adding child relations, which always have AppendRelInfos. + */ +void +expand_planner_arrays(PlannerInfo *root, int add_size) +{ + int new_size; + + Assert(add_size > 0); + + new_size = root->simple_rel_array_size + add_size; + + root->simple_rel_array = (RelOptInfo **) + repalloc(root->simple_rel_array, + sizeof(RelOptInfo *) * new_size); + MemSet(root->simple_rel_array + root->simple_rel_array_size, + 0, sizeof(RelOptInfo *) * add_size); + + root->simple_rte_array = (RangeTblEntry **) + repalloc(root->simple_rte_array, + sizeof(RangeTblEntry *) * new_size); + MemSet(root->simple_rte_array + root->simple_rel_array_size, + 0, sizeof(RangeTblEntry *) * add_size); + + if (root->append_rel_array) + { + root->append_rel_array = (AppendRelInfo **) + repalloc(root->append_rel_array, + sizeof(AppendRelInfo *) * new_size); + MemSet(root->append_rel_array + root->simple_rel_array_size, + 0, sizeof(AppendRelInfo *) * add_size); + } + else + { + root->append_rel_array = (AppendRelInfo **) + palloc0(sizeof(AppendRelInfo *) * new_size); + } + + root->simple_rel_array_size = new_size; } /* @@ -123,18 +212,16 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->cheapest_total_path = NULL; rel->cheapest_unique_path = NULL; rel->cheapest_parameterized_paths = NIL; - rel->direct_lateral_relids = NULL; - rel->lateral_relids = NULL; rel->relid = relid; rel->rtekind = rte->rtekind; /* min_attr, max_attr, attr_needed, attr_widths are set below */ rel->lateral_vars = NIL; - rel->lateral_referencers = NULL; rel->indexlist = NIL; rel->statlist = NIL; rel->pages = 0; rel->tuples = 0; rel->allvisfrac = 0; + rel->eclass_indexes = NULL; rel->subroot = NULL; rel->subplan_params = NIL; rel->rel_parallel_workers = -1; /* set up in get_relation_info */ @@ -151,6 +238,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->baserestrict_min_security = UINT_MAX; rel->joininfo = NIL; rel->has_eclass_joins = false; + rel->consider_partitionwise_join = false; /* might get changed later */ rel->part_scheme = NULL; rel->nparts = 0; rel->boundinfo = NULL; @@ -161,20 +249,44 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->partitioned_child_rels = NIL; /* - * Pass top parent's relids down the inheritance hierarchy. If the parent - * has top_parent_relids set, it's a direct or an indirect child of the - * top parent indicated by top_parent_relids. By extension this child is - * also an indirect child of that parent. + * Pass assorted information down the inheritance hierarchy. */ if (parent) { + /* + * Each direct or indirect child wants to know the relids of its + * topmost parent. + */ if (parent->top_parent_relids) rel->top_parent_relids = parent->top_parent_relids; else rel->top_parent_relids = bms_copy(parent->relids); + + /* + * Also propagate lateral-reference information from appendrel parent + * rels to their child rels. We intentionally give each child rel the + * same minimum parameterization, even though it's quite possible that + * some don't reference all the lateral rels. This is because any + * append path for the parent will have to have the same + * parameterization for every child anyway, and there's no value in + * forcing extra reparameterize_path() calls. Similarly, a lateral + * reference to the parent prevents use of otherwise-movable join rels + * for each child. + * + * It's possible for child rels to have their own children, in which + * case the topmost parent's lateral info propagates all the way down. + */ + rel->direct_lateral_relids = parent->direct_lateral_relids; + rel->lateral_relids = parent->lateral_relids; + rel->lateral_referencers = parent->lateral_referencers; } else + { rel->top_parent_relids = NULL; + rel->direct_lateral_relids = NULL; + rel->lateral_relids = NULL; + rel->lateral_referencers = NULL; + } /* Check type of rtable entry */ switch (rte->rtekind) @@ -203,71 +315,43 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent) rel->attr_widths = (int32 *) palloc0((rel->max_attr - rel->min_attr + 1) * sizeof(int32)); break; + case RTE_RESULT: + /* RTE_RESULT has no columns, nor could it have whole-row Var */ + rel->min_attr = 0; + rel->max_attr = -1; + rel->attr_needed = NULL; + rel->attr_widths = NULL; + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); break; } - /* Save the finished struct in the query's simple_rel_array */ - root->simple_rel_array[relid] = rel; - - /* - * This is a convenient spot at which to note whether rels participating - * in the query have any securityQuals attached. If so, increase - * root->qual_security_level to ensure it's larger than the maximum - * security level needed for securityQuals. - */ - if (rte->securityQuals) - root->qual_security_level = Max(root->qual_security_level, - list_length(rte->securityQuals)); - /* - * If this rel is an appendrel parent, recurse to build "other rel" - * RelOptInfos for its children. They are "other rels" because they are - * not in the main join tree, but we will need RelOptInfos to plan access - * to them. + * Copy the parent's quals to the child, with appropriate substitution of + * variables. If any constant false or NULL clauses turn up, we can mark + * the child as dummy right away. (We must do this immediately so that + * pruning works correctly when recursing in expand_partitioned_rtentry.) */ - if (rte->inh) + if (parent) { - ListCell *l; - int nparts = rel->nparts; - int cnt_parts = 0; + AppendRelInfo *appinfo = root->append_rel_array[relid]; - if (nparts > 0) - rel->part_rels = (RelOptInfo **) - palloc(sizeof(RelOptInfo *) * nparts); - - foreach(l, root->append_rel_list) + Assert(appinfo != NULL); + if (!apply_child_basequals(root, parent, rel, rte, appinfo)) { - AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l); - RelOptInfo *childrel; - - /* append_rel_list contains all append rels; ignore others */ - if (appinfo->parent_relid != relid) - continue; - - childrel = build_simple_rel(root, appinfo->child_relid, - rel); - - /* Nothing more to do for an unpartitioned table. */ - if (!rel->part_scheme) - continue; - /* - * The order of partition OIDs in append_rel_list is the same as - * the order in the PartitionDesc, so the order of part_rels will - * also match the PartitionDesc. See expand_partitioned_rtentry. + * Some restriction clause reduced to constant FALSE or NULL after + * substitution, so this child need not be scanned. */ - Assert(cnt_parts < nparts); - rel->part_rels[cnt_parts] = childrel; - cnt_parts++; + mark_dummy_rel(rel); } - - /* We should have seen all the child partitions. */ - Assert(cnt_parts == nparts); } + /* Save the finished struct in the query's simple_rel_array */ + root->simple_rel_array[relid] = rel; + return rel; } @@ -549,6 +633,7 @@ build_join_rel(PlannerInfo *root, joinrel->pages = 0; joinrel->tuples = 0; joinrel->allvisfrac = 0; + joinrel->eclass_indexes = NULL; joinrel->subroot = NULL; joinrel->subplan_params = NIL; joinrel->rel_parallel_workers = -1; @@ -565,6 +650,7 @@ build_join_rel(PlannerInfo *root, joinrel->baserestrict_min_security = UINT_MAX; joinrel->joininfo = NIL; joinrel->has_eclass_joins = false; + joinrel->consider_partitionwise_join = false; /* might get changed later */ joinrel->top_parent_relids = NULL; joinrel->part_scheme = NULL; joinrel->nparts = 0; @@ -695,6 +781,9 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, /* Only joins between "other" relations land here. */ Assert(IS_OTHER_REL(outer_rel) && IS_OTHER_REL(inner_rel)); + /* The parent joinrel should have consider_partitionwise_join set. */ + Assert(parent_joinrel->consider_partitionwise_join); + joinrel->reloptkind = RELOPT_OTHER_JOINREL; joinrel->relids = bms_union(outer_rel->relids, inner_rel->relids); joinrel->rows = 0; @@ -724,6 +813,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, joinrel->pages = 0; joinrel->tuples = 0; joinrel->allvisfrac = 0; + joinrel->eclass_indexes = NULL; joinrel->subroot = NULL; joinrel->subplan_params = NIL; joinrel->serverid = InvalidOid; @@ -736,6 +826,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, joinrel->baserestrictcost.per_tuple = 0; joinrel->joininfo = NIL; joinrel->has_eclass_joins = false; + joinrel->consider_partitionwise_join = false; /* might get changed later */ joinrel->top_parent_relids = NULL; joinrel->part_scheme = NULL; joinrel->nparts = 0; @@ -752,14 +843,13 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, /* Compute information relevant to foreign relations. */ set_foreign_rel_properties(joinrel, outer_rel, inner_rel); - /* Build targetlist */ - build_joinrel_tlist(root, joinrel, outer_rel); - build_joinrel_tlist(root, joinrel, inner_rel); - /* Add placeholder variables. */ - add_placeholders_to_child_joinrel(root, joinrel, parent_joinrel); + appinfos = find_appinfos_by_relids(root, joinrel->relids, &nappinfos); + + /* Set up reltarget struct */ + build_child_join_reltarget(root, parent_joinrel, joinrel, + nappinfos, appinfos); /* Construct joininfo list. */ - appinfos = find_appinfos_by_relids(root, joinrel->relids, &nappinfos); joinrel->joininfo = (List *) adjust_appendrel_attrs(root, (Node *) parent_joinrel->joininfo, nappinfos, @@ -768,11 +858,8 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, /* * Lateral relids referred in child join will be same as that referred in - * the parent relation. Throw any partial result computed while building - * the targetlist. + * the parent relation. */ - bms_free(joinrel->direct_lateral_relids); - bms_free(joinrel->lateral_relids); joinrel->direct_lateral_relids = (Relids) bms_copy(parent_joinrel->direct_lateral_relids); joinrel->lateral_relids = (Relids) bms_copy(parent_joinrel->lateral_relids); @@ -789,7 +876,6 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, /* Child joinrel is parallel safe if parent is parallel safe. */ joinrel->consider_parallel = parent_joinrel->consider_parallel; - /* Set estimates of the child-joinrel's size. */ set_joinrel_size_estimates(root, joinrel, outer_rel, inner_rel, sjinfo, restrictlist); @@ -858,15 +944,9 @@ static void build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *input_rel) { - Relids relids; + Relids relids = joinrel->relids; ListCell *vars; - /* attrs_needed refers to parent relids and not those of a child. */ - if (joinrel->top_parent_relids) - relids = joinrel->top_parent_relids; - else - relids = joinrel->relids; - foreach(vars, input_rel->reltarget->exprs) { Var *var = (Var *) lfirst(vars); @@ -882,54 +962,23 @@ build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, /* * Otherwise, anything in a baserel or joinrel targetlist ought to be - * a Var. Children of a partitioned table may have ConvertRowtypeExpr - * translating whole-row Var of a child to that of the parent. - * Children of an inherited table or subquery child rels can not - * directly participate in a join, so other kinds of nodes here. + * a Var. (More general cases can only appear in appendrel child + * rels, which will never be seen here.) */ - if (IsA(var, Var)) - { - baserel = find_base_rel(root, var->varno); - ndx = var->varattno - baserel->min_attr; - } - else if (IsA(var, ConvertRowtypeExpr)) - { - ConvertRowtypeExpr *child_expr = (ConvertRowtypeExpr *) var; - Var *childvar = (Var *) child_expr->arg; - - /* - * Child's whole-row references are converted to look like those - * of parent using ConvertRowtypeExpr. There can be as many - * ConvertRowtypeExpr decorations as the depth of partition tree. - * The argument to the deepest ConvertRowtypeExpr is expected to - * be a whole-row reference of the child. - */ - while (IsA(childvar, ConvertRowtypeExpr)) - { - child_expr = (ConvertRowtypeExpr *) childvar; - childvar = (Var *) child_expr->arg; - } - Assert(IsA(childvar, Var) &&childvar->varattno == 0); - - baserel = find_base_rel(root, childvar->varno); - ndx = 0 - baserel->min_attr; - } - else + if (!IsA(var, Var)) elog(ERROR, "unexpected node type in rel targetlist: %d", (int) nodeTag(var)); + /* Get the Var's original base rel */ + baserel = find_base_rel(root, var->varno); - /* Is the target expression still needed above this joinrel? */ + /* Is it still needed above this joinrel? */ + ndx = var->varattno - baserel->min_attr; if (bms_nonempty_difference(baserel->attr_needed[ndx], relids)) { /* Yup, add it to the output */ joinrel->reltarget->exprs = lappend(joinrel->reltarget->exprs, var); - - /* - * Vars have cost zero, so no need to adjust reltarget->cost. Even - * if it's a ConvertRowtypeExpr, it will be computed only for the - * base relation, costing nothing for a join. - */ + /* Vars have cost zero, so no need to adjust reltarget->cost */ joinrel->reltarget->width += baserel->attr_widths[ndx]; } } @@ -1098,36 +1147,6 @@ subbuild_joinrel_joinlist(RelOptInfo *joinrel, } -/* - * build_empty_join_rel - * Build a dummy join relation describing an empty set of base rels. - * - * This is used for queries with empty FROM clauses, such as "SELECT 2+2" or - * "INSERT INTO foo VALUES(...)". We don't try very hard to make the empty - * joinrel completely valid, since no real planning will be done with it --- - * we just need it to carry a simple Result path out of query_planner(). - */ -RelOptInfo * -build_empty_join_rel(PlannerInfo *root) -{ - RelOptInfo *joinrel; - - /* The dummy join relation should be the only one ... */ - Assert(root->join_rel_list == NIL); - - joinrel = makeNode(RelOptInfo); - joinrel->reloptkind = RELOPT_JOINREL; - joinrel->relids = NULL; /* empty set */ - joinrel->rows = 1; /* we produce one row for such cases */ - joinrel->rtekind = RTE_JOIN; - joinrel->reltarget = create_empty_pathtarget(); - - root->join_rel_list = lappend(root->join_rel_list, joinrel); - - return joinrel; -} - - /* * fetch_upper_rel * Build a RelOptInfo describing some post-scan/join query processing, @@ -1184,36 +1203,6 @@ fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids) } -/* - * find_childrel_appendrelinfo - * Get the AppendRelInfo associated with an appendrel child rel. - * - * This search could be eliminated by storing a link in child RelOptInfos, - * but for now it doesn't seem performance-critical. (Also, it might be - * difficult to maintain such a link during mutation of the append_rel_list.) - */ -AppendRelInfo * -find_childrel_appendrelinfo(PlannerInfo *root, RelOptInfo *rel) -{ - Index relid = rel->relid; - ListCell *lc; - - /* Should only be called on child rels */ - Assert(rel->reloptkind == RELOPT_OTHER_MEMBER_REL); - - foreach(lc, root->append_rel_list) - { - AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc); - - if (appinfo->child_relid == relid) - return appinfo; - } - /* should have found the entry ... */ - elog(ERROR, "child rel %d not found in append_rel_list", relid); - return NULL; /* not reached */ -} - - /* * find_childrel_parents * Compute the set of parent relids of an appendrel child rel. @@ -1228,10 +1217,11 @@ find_childrel_parents(PlannerInfo *root, RelOptInfo *rel) Relids result = NULL; Assert(rel->reloptkind == RELOPT_OTHER_MEMBER_REL); + Assert(rel->relid > 0 && rel->relid < root->simple_rel_array_size); do { - AppendRelInfo *appinfo = find_childrel_appendrelinfo(root, rel); + AppendRelInfo *appinfo = root->append_rel_array[rel->relid]; Index prelid = appinfo->parent_relid; result = bms_add_member(result, prelid); @@ -1267,6 +1257,9 @@ get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel, double rows; ListCell *lc; + /* If rel has LATERAL refs, every path for it should account for them */ + Assert(bms_is_subset(baserel->lateral_relids, required_outer)); + /* Unparameterized paths have no ParamPathInfo */ if (bms_is_empty(required_outer)) return NULL; @@ -1362,6 +1355,9 @@ get_joinrel_parampathinfo(PlannerInfo *root, RelOptInfo *joinrel, double rows; ListCell *lc; + /* If rel has LATERAL refs, every path for it should account for them */ + Assert(bms_is_subset(joinrel->lateral_relids, required_outer)); + /* Unparameterized paths have no ParamPathInfo or extra join clauses */ if (bms_is_empty(required_outer)) return NULL; @@ -1553,6 +1549,9 @@ get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer) { ParamPathInfo *ppi; + /* If rel has LATERAL refs, every path for it should account for them */ + Assert(bms_is_subset(appendrel->lateral_relids, required_outer)); + /* Unparameterized paths have no ParamPathInfo */ if (bms_is_empty(required_outer)) return NULL; @@ -1618,18 +1617,21 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, /* * We can only consider this join as an input to further partitionwise - * joins if (a) the input relations are partitioned, (b) the partition - * schemes match, and (c) we can identify an equi-join between the - * partition keys. Note that if it were possible for - * have_partkey_equi_join to return different answers for the same joinrel - * depending on which join ordering we try first, this logic would break. - * That shouldn't happen, though, because of the way the query planner - * deduces implied equalities and reorders the joins. Please see - * optimizer/README for details. + * joins if (a) the input relations are partitioned and have + * consider_partitionwise_join=true, (b) the partition schemes match, and + * (c) we can identify an equi-join between the partition keys. Note that + * if it were possible for have_partkey_equi_join to return different + * answers for the same joinrel depending on which join ordering we try + * first, this logic would break. That shouldn't happen, though, because + * of the way the query planner deduces implied equalities and reorders + * the joins. Please see optimizer/README for details. */ if (!IS_PARTITIONED_REL(outer_rel) || !IS_PARTITIONED_REL(inner_rel) || + !outer_rel->consider_partitionwise_join || + !inner_rel->consider_partitionwise_join || outer_rel->part_scheme != inner_rel->part_scheme || - !have_partkey_equi_join(outer_rel, inner_rel, jointype, restrictlist)) + !have_partkey_equi_join(joinrel, outer_rel, inner_rel, + jointype, restrictlist)) { Assert(!IS_PARTITIONED_REL(joinrel)); return; @@ -1678,6 +1680,12 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, joinrel->part_rels = (RelOptInfo **) palloc0(sizeof(RelOptInfo *) * joinrel->nparts); + /* + * Set the consider_partitionwise_join flag. + */ + Assert(outer_rel->consider_partitionwise_join); + Assert(inner_rel->consider_partitionwise_join); + joinrel->consider_partitionwise_join = true; /* * Construct partition keys for the join. @@ -1707,43 +1715,39 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, */ for (cnt = 0; cnt < partnatts; cnt++) { - List *outer_expr; - List *outer_null_expr; - List *inner_expr; - List *inner_null_expr; + /* mark these const to enforce that we copy them properly */ + const List *outer_expr = outer_rel->partexprs[cnt]; + const List *outer_null_expr = outer_rel->nullable_partexprs[cnt]; + const List *inner_expr = inner_rel->partexprs[cnt]; + const List *inner_null_expr = inner_rel->nullable_partexprs[cnt]; List *partexpr = NIL; List *nullable_partexpr = NIL; - outer_expr = list_copy(outer_rel->partexprs[cnt]); - outer_null_expr = list_copy(outer_rel->nullable_partexprs[cnt]); - inner_expr = list_copy(inner_rel->partexprs[cnt]); - inner_null_expr = list_copy(inner_rel->nullable_partexprs[cnt]); - switch (jointype) { case JOIN_INNER: - partexpr = list_concat(outer_expr, inner_expr); - nullable_partexpr = list_concat(outer_null_expr, - inner_null_expr); + partexpr = list_concat_copy(outer_expr, inner_expr); + nullable_partexpr = list_concat_copy(outer_null_expr, + inner_null_expr); break; case JOIN_SEMI: case JOIN_ANTI: - partexpr = outer_expr; - nullable_partexpr = outer_null_expr; + partexpr = list_copy(outer_expr); + nullable_partexpr = list_copy(outer_null_expr); break; case JOIN_LEFT: - partexpr = outer_expr; - nullable_partexpr = list_concat(inner_expr, - outer_null_expr); + partexpr = list_copy(outer_expr); + nullable_partexpr = list_concat_copy(inner_expr, + outer_null_expr); nullable_partexpr = list_concat(nullable_partexpr, inner_null_expr); break; case JOIN_FULL: - nullable_partexpr = list_concat(outer_expr, - inner_expr); + nullable_partexpr = list_concat_copy(outer_expr, + inner_expr); nullable_partexpr = list_concat(nullable_partexpr, outer_null_expr); nullable_partexpr = list_concat(nullable_partexpr, @@ -1759,3 +1763,26 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, joinrel->nullable_partexprs[cnt] = nullable_partexpr; } } + +/* + * build_child_join_reltarget + * Set up a child-join relation's reltarget from a parent-join relation. + */ +static void +build_child_join_reltarget(PlannerInfo *root, + RelOptInfo *parentrel, + RelOptInfo *childrel, + int nappinfos, + AppendRelInfo **appinfos) +{ + /* Build the targetlist */ + childrel->reltarget->exprs = (List *) + adjust_appendrel_attrs(root, + (Node *) parentrel->reltarget->exprs, + nappinfos, appinfos); + + /* Set the cost and width fields */ + childrel->reltarget->cost.startup = parentrel->reltarget->cost.startup; + childrel->reltarget->cost.per_tuple = parentrel->reltarget->cost.per_tuple; + childrel->reltarget->width = parentrel->reltarget->width; +} diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c index 1075dde40c8..3b50fd29ad6 100644 --- a/src/backend/optimizer/util/restrictinfo.c +++ b/src/backend/optimizer/util/restrictinfo.c @@ -3,7 +3,7 @@ * restrictinfo.c * RestrictInfo node manipulation routines. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,28 +14,30 @@ */ #include "postgres.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "optimizer/restrictinfo.h" -#include "optimizer/var.h" static RestrictInfo *make_restrictinfo_internal(Expr *clause, - Expr *orclause, - bool is_pushed_down, - bool outerjoin_delayed, - bool pseudoconstant, - Index security_level, - Relids required_relids, - Relids outer_relids, - Relids nullable_relids); + Expr *orclause, + bool is_pushed_down, + bool outerjoin_delayed, + bool pseudoconstant, + Index security_level, + Relids required_relids, + Relids outer_relids, + Relids nullable_relids); static Expr *make_sub_restrictinfos(Expr *clause, - bool is_pushed_down, - bool outerjoin_delayed, - bool pseudoconstant, - Index security_level, - Relids required_relids, - Relids outer_relids, - Relids nullable_relids); + bool is_pushed_down, + bool outerjoin_delayed, + bool pseudoconstant, + Index security_level, + Relids required_relids, + Relids outer_relids, + Relids nullable_relids); /* @@ -67,7 +69,7 @@ make_restrictinfo(Expr *clause, * If it's an OR clause, build a modified copy with RestrictInfos inserted * above each subclause of the top-level AND/OR structure. */ - if (or_clause((Node *) clause)) + if (is_orclause(clause)) return (RestrictInfo *) make_sub_restrictinfos(clause, is_pushed_down, outerjoin_delayed, @@ -78,7 +80,7 @@ make_restrictinfo(Expr *clause, nullable_relids); /* Shouldn't be an AND clause, else AND/OR flattening messed up */ - Assert(!and_clause((Node *) clause)); + Assert(!is_andclause(clause)); return make_restrictinfo_internal(clause, NULL, @@ -232,7 +234,7 @@ make_sub_restrictinfos(Expr *clause, Relids outer_relids, Relids nullable_relids) { - if (or_clause((Node *) clause)) + if (is_orclause(clause)) { List *orlist = NIL; ListCell *temp; @@ -257,7 +259,7 @@ make_sub_restrictinfos(Expr *clause, outer_relids, nullable_relids); } - else if (and_clause((Node *) clause)) + else if (is_andclause(clause)) { List *andlist = NIL; ListCell *temp; @@ -286,6 +288,70 @@ make_sub_restrictinfos(Expr *clause, nullable_relids); } +/* + * commute_restrictinfo + * + * Given a RestrictInfo containing a binary opclause, produce a RestrictInfo + * representing the commutation of that clause. The caller must pass the + * OID of the commutator operator (which it's presumably looked up, else + * it would not know this is valid). + * + * Beware that the result shares sub-structure with the given RestrictInfo. + * That's okay for the intended usage with derived index quals, but might + * be hazardous if the source is subject to change. Also notice that we + * assume without checking that the commutator op is a member of the same + * btree and hash opclasses as the original op. + */ +RestrictInfo * +commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op) +{ + RestrictInfo *result; + OpExpr *newclause; + OpExpr *clause = castNode(OpExpr, rinfo->clause); + + Assert(list_length(clause->args) == 2); + + /* flat-copy all the fields of clause ... */ + newclause = makeNode(OpExpr); + memcpy(newclause, clause, sizeof(OpExpr)); + + /* ... and adjust those we need to change to commute it */ + newclause->opno = comm_op; + newclause->opfuncid = InvalidOid; + newclause->args = list_make2(lsecond(clause->args), + linitial(clause->args)); + + /* likewise, flat-copy all the fields of rinfo ... */ + result = makeNode(RestrictInfo); + memcpy(result, rinfo, sizeof(RestrictInfo)); + + /* + * ... and adjust those we need to change. Note in particular that we can + * preserve any cached selectivity or cost estimates, since those ought to + * be the same for the new clause. Likewise we can keep the source's + * parent_ec. + */ + result->clause = (Expr *) newclause; + result->left_relids = rinfo->right_relids; + result->right_relids = rinfo->left_relids; + Assert(result->orclause == NULL); + result->left_ec = rinfo->right_ec; + result->right_ec = rinfo->left_ec; + result->left_em = rinfo->right_em; + result->right_em = rinfo->left_em; + result->scansel_cache = NIL; /* not worth updating this */ + if (rinfo->hashjoinoperator == clause->opno) + result->hashjoinoperator = comm_op; + else + result->hashjoinoperator = InvalidOid; + result->left_bucketsize = rinfo->right_bucketsize; + result->right_bucketsize = rinfo->left_bucketsize; + result->left_mcvfreq = rinfo->right_mcvfreq; + result->right_mcvfreq = rinfo->left_mcvfreq; + + return result; +} + /* * restriction_is_or_clause * @@ -373,7 +439,7 @@ extract_actual_clauses(List *restrictinfo_list, * extract_actual_join_clauses * * Extract bare clauses from 'restrictinfo_list', separating those that - * syntactically match the join level from those that were pushed down. + * semantically match the join level from those that were pushed down. * Pseudoconstant clauses are excluded from the results. * * This is only used at outer joins, since for plain joins we don't care @@ -381,6 +447,7 @@ extract_actual_clauses(List *restrictinfo_list, */ void extract_actual_join_clauses(List *restrictinfo_list, + Relids joinrelids, List **joinquals, List **otherquals) { @@ -393,7 +460,7 @@ extract_actual_join_clauses(List *restrictinfo_list, { RestrictInfo *rinfo = lfirst_node(RestrictInfo, l); - if (rinfo->is_pushed_down) + if (RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)) { if (!rinfo->pseudoconstant) *otherquals = lappend(*otherquals, rinfo->clause); diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index 32160d57165..d75796ac8b9 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -3,7 +3,7 @@ * tlist.c * Target list manipulation routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,7 @@ #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/tlist.h" @@ -25,20 +26,38 @@ ((IsA(node, FuncExpr) && ((FuncExpr *) (node))->funcretset) || \ (IsA(node, OpExpr) && ((OpExpr *) (node))->opretset)) -/* Workspace for split_pathtarget_walker */ +/* + * Data structures for split_pathtarget_at_srfs(). To preserve the identity + * of sortgroupref items even if they are textually equal(), what we track is + * not just bare expressions but expressions plus their sortgroupref indexes. + */ +typedef struct +{ + Node *expr; /* some subexpression of a PathTarget */ + Index sortgroupref; /* its sortgroupref, or 0 if none */ +} split_pathtarget_item; + typedef struct { + /* This is a List of bare expressions: */ List *input_target_exprs; /* exprs available from input */ - List *level_srfs; /* list of lists of SRF exprs */ - List *level_input_vars; /* vars needed by SRFs of each level */ - List *level_input_srfs; /* SRFs needed by SRFs of each level */ + /* These are Lists of Lists of split_pathtarget_items: */ + List *level_srfs; /* SRF exprs to evaluate at each level */ + List *level_input_vars; /* input vars needed at each level */ + List *level_input_srfs; /* input SRFs needed at each level */ + /* These are Lists of split_pathtarget_items: */ List *current_input_vars; /* vars needed in current subexpr */ List *current_input_srfs; /* SRFs needed in current subexpr */ + /* Auxiliary data for current split_pathtarget_walker traversal: */ int current_depth; /* max SRF depth in current subexpr */ + Index current_sgref; /* current subexpr's sortgroupref, or 0 */ } split_pathtarget_context; static bool split_pathtarget_walker(Node *node, - split_pathtarget_context *context); + split_pathtarget_context *context); +static void add_sp_item_to_pathtarget(PathTarget *target, + split_pathtarget_item *item); +static void add_sp_items_to_pathtarget(PathTarget *target, List *items); /***************************************************************************** @@ -268,7 +287,7 @@ tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK) return false; /* tlist longer than colTypes */ if (exprType((Node *) tle->expr) != lfirst_oid(curColType)) return false; - curColType = lnext(curColType); + curColType = lnext(colTypes, curColType); } } if (curColType != NULL) @@ -302,7 +321,7 @@ tlist_same_collations(List *tlist, List *colCollations, bool junkOK) return false; /* tlist longer than colCollations */ if (exprCollation((Node *) tle->expr) != lfirst_oid(curColColl)) return false; - curColColl = lnext(curColColl); + curColColl = lnext(colCollations, curColColl); } } if (curColColl != NULL) @@ -484,6 +503,31 @@ extract_grouping_ops(List *groupClause) return groupOperators; } +/* + * extract_grouping_collations - make an array of the grouping column collations + * for a SortGroupClause list + */ +Oid * +extract_grouping_collations(List *groupClause, List *tlist) +{ + int numCols = list_length(groupClause); + int colno = 0; + Oid *grpCollations; + ListCell *glitem; + + grpCollations = (Oid *) palloc(sizeof(Oid) * numCols); + + foreach(glitem, groupClause) + { + SortGroupClause *groupcl = (SortGroupClause *) lfirst(glitem); + TargetEntry *tle = get_sortgroupclause_tle(groupcl, tlist); + + grpCollations[colno++] = exprCollation((Node *) tle->expr); + } + + return grpCollations; +} + /* * extract_grouping_cols - make an array of the grouping column resnos * for a SortGroupClause list @@ -621,9 +665,8 @@ make_tlist_from_pathtarget(PathTarget *target) * copy_pathtarget * Copy a PathTarget. * - * The new PathTarget has its own List cells, but shares the underlying - * target expression trees with the old one. We duplicate the List cells - * so that items can be added to one target without damaging the other. + * The new PathTarget has its own exprs List, but shares the underlying + * target expression trees with the old one. */ PathTarget * copy_pathtarget(PathTarget *src) @@ -822,6 +865,9 @@ apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target) * already meant as a reference to a lower subexpression). So, don't expand * any tlist expressions that appear in input_target, if that's not NULL. * + * It's also important that we preserve any sortgroupref annotation appearing + * in the given target, especially on expressions matching input_target items. + * * The outputs of this function are two parallel lists, one a list of * PathTargets and the other an integer list of bool flags indicating * whether the corresponding PathTarget contains any evaluatable SRFs. @@ -845,6 +891,7 @@ split_pathtarget_at_srfs(PlannerInfo *root, int max_depth; bool need_extra_projection; List *prev_level_tlist; + int lci; ListCell *lc, *lc1, *lc2, @@ -884,10 +931,15 @@ split_pathtarget_at_srfs(PlannerInfo *root, need_extra_projection = false; /* Scan each expression in the PathTarget looking for SRFs */ + lci = 0; foreach(lc, target->exprs) { Node *node = (Node *) lfirst(lc); + /* Tell split_pathtarget_walker about this expr's sortgroupref */ + context.current_sgref = get_pathtarget_sortgroupref(target, lci); + lci++; + /* * Find all SRFs and Vars (and Var-like nodes) in this expression, and * enter them into appropriate lists within the context struct. @@ -969,7 +1021,7 @@ split_pathtarget_at_srfs(PlannerInfo *root, List *level_srfs = (List *) lfirst(lc1); PathTarget *ntarget; - if (lnext(lc1) == NULL) + if (lnext(context.level_srfs, lc1) == NULL) { ntarget = target; } @@ -981,28 +1033,28 @@ split_pathtarget_at_srfs(PlannerInfo *root, * This target should actually evaluate any SRFs of the current * level, and it needs to propagate forward any Vars needed by * later levels, as well as SRFs computed earlier and needed by - * later levels. We rely on add_new_columns_to_pathtarget() to - * remove duplicate items. Also, for safety, make a separate copy - * of each item for each PathTarget. + * later levels. */ - add_new_columns_to_pathtarget(ntarget, copyObject(level_srfs)); - for_each_cell(lc, lnext(lc2)) + add_sp_items_to_pathtarget(ntarget, level_srfs); + for_each_cell(lc, context.level_input_vars, + lnext(context.level_input_vars, lc2)) { List *input_vars = (List *) lfirst(lc); - add_new_columns_to_pathtarget(ntarget, copyObject(input_vars)); + add_sp_items_to_pathtarget(ntarget, input_vars); } - for_each_cell(lc, lnext(lc3)) + for_each_cell(lc, context.level_input_srfs, + lnext(context.level_input_srfs, lc3)) { List *input_srfs = (List *) lfirst(lc); ListCell *lcx; foreach(lcx, input_srfs) { - Expr *srf = (Expr *) lfirst(lcx); + split_pathtarget_item *item = lfirst(lcx); - if (list_member(prev_level_tlist, srf)) - add_new_column_to_pathtarget(ntarget, copyObject(srf)); + if (list_member(prev_level_tlist, item->expr)) + add_sp_item_to_pathtarget(ntarget, item); } } set_pathtarget_cost_width(root, ntarget); @@ -1037,12 +1089,17 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) * input_target can be treated like a Var (which indeed it will be after * setrefs.c gets done with it), even if it's actually a SRF. Record it * as being needed for the current expression, and ignore any - * substructure. + * substructure. (Note in particular that this preserves the identity of + * any expressions that appear as sortgrouprefs in input_target.) */ if (list_member(context->input_target_exprs, node)) { + split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item)); + + item->expr = node; + item->sortgroupref = context->current_sgref; context->current_input_vars = lappend(context->current_input_vars, - node); + item); return false; } @@ -1057,8 +1114,12 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) IsA(node, GroupingFunc) || IsA(node, WindowFunc)) { + split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item)); + + item->expr = node; + item->sortgroupref = context->current_sgref; context->current_input_vars = lappend(context->current_input_vars, - node); + item); return false; } @@ -1068,15 +1129,20 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) */ if (IS_SRF_CALL(node)) { + split_pathtarget_item *item = palloc(sizeof(split_pathtarget_item)); List *save_input_vars = context->current_input_vars; List *save_input_srfs = context->current_input_srfs; int save_current_depth = context->current_depth; int srf_depth; ListCell *lc; + item->expr = node; + item->sortgroupref = context->current_sgref; + context->current_input_vars = NIL; context->current_input_srfs = NIL; context->current_depth = 0; + context->current_sgref = 0; /* subexpressions are not sortgroup items */ (void) expression_tree_walker(node, split_pathtarget_walker, (void *) context); @@ -1094,7 +1160,7 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) /* Record this SRF as needing to be evaluated at appropriate level */ lc = list_nth_cell(context->level_srfs, srf_depth); - lfirst(lc) = lappend(lfirst(lc), node); + lfirst(lc) = lappend(lfirst(lc), item); /* Record its inputs as being needed at the same level */ lc = list_nth_cell(context->level_input_vars, srf_depth); @@ -1108,7 +1174,7 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) * surrounding expression. */ context->current_input_vars = save_input_vars; - context->current_input_srfs = lappend(save_input_srfs, node); + context->current_input_srfs = lappend(save_input_srfs, item); context->current_depth = Max(save_current_depth, srf_depth); /* We're done here */ @@ -1119,6 +1185,79 @@ split_pathtarget_walker(Node *node, split_pathtarget_context *context) * Otherwise, the node is a scalar (non-set) expression, so recurse to * examine its inputs. */ + context->current_sgref = 0; /* subexpressions are not sortgroup items */ return expression_tree_walker(node, split_pathtarget_walker, (void *) context); } + +/* + * Add a split_pathtarget_item to the PathTarget, unless a matching item is + * already present. This is like add_new_column_to_pathtarget, but allows + * for sortgrouprefs to be handled. An item having zero sortgroupref can + * be merged with one that has a sortgroupref, acquiring the latter's + * sortgroupref. + * + * Note that we don't worry about possibly adding duplicate sortgrouprefs + * to the PathTarget. That would be bad, but it should be impossible unless + * the target passed to split_pathtarget_at_srfs already had duplicates. + * As long as it didn't, we can have at most one split_pathtarget_item with + * any particular nonzero sortgroupref. + */ +static void +add_sp_item_to_pathtarget(PathTarget *target, split_pathtarget_item *item) +{ + int lci; + ListCell *lc; + + /* + * Look for a pre-existing entry that is equal() and does not have a + * conflicting sortgroupref already. + */ + lci = 0; + foreach(lc, target->exprs) + { + Node *node = (Node *) lfirst(lc); + Index sgref = get_pathtarget_sortgroupref(target, lci); + + if ((item->sortgroupref == sgref || + item->sortgroupref == 0 || + sgref == 0) && + equal(item->expr, node)) + { + /* Found a match. Assign item's sortgroupref if it has one. */ + if (item->sortgroupref) + { + if (target->sortgrouprefs == NULL) + { + target->sortgrouprefs = (Index *) + palloc0(list_length(target->exprs) * sizeof(Index)); + } + target->sortgrouprefs[lci] = item->sortgroupref; + } + return; + } + lci++; + } + + /* + * No match, so add item to PathTarget. Copy the expr for safety. + */ + add_column_to_pathtarget(target, (Expr *) copyObject(item->expr), + item->sortgroupref); +} + +/* + * Apply add_sp_item_to_pathtarget to each element of list. + */ +static void +add_sp_items_to_pathtarget(PathTarget *target, List *items) +{ + ListCell *lc; + + foreach(lc, items) + { + split_pathtarget_item *item = lfirst(lc); + + add_sp_item_to_pathtarget(target, item); + } +} diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index b16b1e46562..15cc518a82e 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -9,7 +9,7 @@ * contains variables. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,8 +22,8 @@ #include "access/sysattr.h" #include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" #include "optimizer/prep.h" -#include "optimizer/var.h" #include "parser/parsetree.h" #include "rewrite/rewriteManip.h" @@ -60,25 +60,25 @@ typedef struct typedef struct { - PlannerInfo *root; + Query *query; /* outer Query */ int sublevels_up; bool possible_sublink; /* could aliases include a SubLink? */ bool inserted_sublink; /* have we inserted a SubLink? */ } flatten_join_alias_vars_context; static bool pull_varnos_walker(Node *node, - pull_varnos_context *context); + pull_varnos_context *context); static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context); static bool pull_vars_walker(Node *node, pull_vars_context *context); static bool contain_var_clause_walker(Node *node, void *context); static bool contain_vars_of_level_walker(Node *node, int *sublevels_up); static bool locate_var_of_level_walker(Node *node, - locate_var_of_level_context *context); + locate_var_of_level_context *context); static bool pull_var_clause_walker(Node *node, - pull_var_clause_context *context); + pull_var_clause_context *context); static Node *flatten_join_alias_vars_mutator(Node *node, - flatten_join_alias_vars_context *context); -static Relids alias_relid_set(PlannerInfo *root, Relids relids); + flatten_join_alias_vars_context *context); +static Relids alias_relid_set(Query *query, Relids relids); /* @@ -667,16 +667,16 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context) * subqueries). */ Node * -flatten_join_alias_vars(PlannerInfo *root, Node *node) +flatten_join_alias_vars(Query *query, Node *node) { flatten_join_alias_vars_context context; - context.root = root; + context.query = query; context.sublevels_up = 0; /* flag whether join aliases could possibly contain SubLinks */ - context.possible_sublink = root->parse->hasSubLinks; + context.possible_sublink = query->hasSubLinks; /* if hasSubLinks is already true, no need to work hard */ - context.inserted_sublink = root->parse->hasSubLinks; + context.inserted_sublink = query->hasSubLinks; return flatten_join_alias_vars_mutator(node, &context); } @@ -696,7 +696,7 @@ flatten_join_alias_vars_mutator(Node *node, /* No change unless Var belongs to a JOIN of the target level */ if (var->varlevelsup != context->sublevels_up) return node; /* no need to copy, really */ - rte = rt_fetch(var->varno, context->root->parse->rtable); + rte = rt_fetch(var->varno, context->query->rtable); if (rte->rtekind != RTE_JOIN) return node; if (var->varattno == InvalidAttrNumber) @@ -783,7 +783,7 @@ flatten_join_alias_vars_mutator(Node *node, /* now fix PlaceHolderVar's relid sets */ if (phv->phlevelsup == context->sublevels_up) { - phv->phrels = alias_relid_set(context->root, + phv->phrels = alias_relid_set(context->query, phv->phrels); } return (Node *) phv; @@ -823,7 +823,7 @@ flatten_join_alias_vars_mutator(Node *node, * underlying base relids */ static Relids -alias_relid_set(PlannerInfo *root, Relids relids) +alias_relid_set(Query *query, Relids relids) { Relids result = NULL; int rtindex; @@ -831,10 +831,10 @@ alias_relid_set(PlannerInfo *root, Relids relids) rtindex = -1; while ((rtindex = bms_next_member(relids, rtindex)) >= 0) { - RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable); + RangeTblEntry *rte = rt_fetch(rtindex, query->rtable); if (rte->rtekind == RTE_JOIN) - result = bms_join(result, get_relids_for_join(root, rtindex)); + result = bms_join(result, get_relids_for_join(query, rtindex)); else result = bms_add_member(result, rtindex); } diff --git a/src/backend/parser/Makefile b/src/backend/parser/Makefile index 95fdf0b9732..f14febdbda0 100644 --- a/src/backend/parser/Makefile +++ b/src/backend/parser/Makefile @@ -14,7 +14,7 @@ override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) OBJS= analyze.o gram.o scan.o parser.o \ parse_agg.o parse_clause.o parse_coerce.o parse_collate.o parse_cte.o \ - parse_enr.o parse_expr.o parse_func.o parse_merge.o parse_node.o parse_oper.o \ + parse_enr.o parse_expr.o parse_func.o parse_node.o parse_oper.o \ parse_param.o parse_relation.o parse_target.o parse_type.o \ parse_utilcmd.o scansup.o diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 606021bc94f..85d7a96406e 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -14,7 +14,7 @@ * contain optimizable statements, which we should transform. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/parser/analyze.c @@ -29,7 +29,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parse_agg.h" #include "parser/parse_clause.h" @@ -38,7 +38,6 @@ #include "parser/parse_cte.h" #include "parser/parse_expr.h" #include "parser/parse_func.h" -#include "parser/parse_merge.h" #include "parser/parse_oper.h" #include "parser/parse_param.h" #include "parser/parse_relation.h" @@ -54,28 +53,33 @@ post_parse_analyze_hook_type post_parse_analyze_hook = NULL; static Query *transformOptionalSelectInto(ParseState *pstate, Node *parseTree); static Query *transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt); static Query *transformInsertStmt(ParseState *pstate, InsertStmt *stmt); +static List *transformInsertRow(ParseState *pstate, List *exprlist, + List *stmtcols, List *icolumns, List *attrnos, + bool strip_indirection); static OnConflictExpr *transformOnConflictClause(ParseState *pstate, - OnConflictClause *onConflictClause); + OnConflictClause *onConflictClause); static int count_rowexpr_columns(ParseState *pstate, Node *expr); static Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt); static Query *transformValuesClause(ParseState *pstate, SelectStmt *stmt); static Query *transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt); static Node *transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, - bool isTopLevel, List **targetlist); + bool isTopLevel, List **targetlist); static void determineRecursiveColTypes(ParseState *pstate, - Node *larg, List *nrtargetlist); + Node *larg, List *nrtargetlist); static Query *transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt); static List *transformReturningList(ParseState *pstate, List *returningList); +static List *transformUpdateTargetList(ParseState *pstate, + List *targetList); static Query *transformDeclareCursorStmt(ParseState *pstate, - DeclareCursorStmt *stmt); + DeclareCursorStmt *stmt); static Query *transformExplainStmt(ParseState *pstate, - ExplainStmt *stmt); + ExplainStmt *stmt); static Query *transformCreateTableAsStmt(ParseState *pstate, - CreateTableAsStmt *stmt); + CreateTableAsStmt *stmt); static Query *transformCallStmt(ParseState *pstate, - CallStmt *stmt); + CallStmt *stmt); static void transformLockingClause(ParseState *pstate, Query *qry, - LockingClause *lc, bool pushedDown); + LockingClause *lc, bool pushedDown); #ifdef RAW_EXPRESSION_COVERAGE_TEST static bool test_raw_expression_coverage(Node *node, void *context); #endif @@ -263,7 +267,6 @@ transformStmt(ParseState *pstate, Node *parseTree) case T_InsertStmt: case T_UpdateStmt: case T_DeleteStmt: - case T_MergeStmt: (void) test_raw_expression_coverage(parseTree, NULL); break; default: @@ -288,10 +291,6 @@ transformStmt(ParseState *pstate, Node *parseTree) result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree); break; - case T_MergeStmt: - result = transformMergeStmt(pstate, (MergeStmt *) parseTree); - break; - case T_SelectStmt: { SelectStmt *n = (SelectStmt *) parseTree; @@ -367,7 +366,6 @@ analyze_requires_snapshot(RawStmt *parseTree) case T_InsertStmt: case T_DeleteStmt: case T_UpdateStmt: - case T_MergeStmt: case T_SelectStmt: result = true; break; @@ -453,11 +451,13 @@ transformDeleteStmt(ParseState *pstate, DeleteStmt *stmt) qry->hasWindowFuncs = pstate->p_hasWindowFuncs; qry->hasTargetSRFs = pstate->p_hasTargetSRFs; qry->hasAggs = pstate->p_hasAggs; - if (pstate->p_hasAggs) - parseCheckAggregates(pstate, qry); assign_query_collations(pstate, qry); + /* this must be done after collations, for reliable comparison of exprs */ + if (pstate->p_hasAggs) + parseCheckAggregates(pstate, qry); + return qry; } @@ -831,18 +831,14 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) */ rte = pstate->p_target_rangetblentry; qry->targetList = NIL; - icols = list_head(icolumns); - attnos = list_head(attrnos); - foreach(lc, exprList) + Assert(list_length(exprList) <= list_length(icolumns)); + forthree(lc, exprList, icols, icolumns, attnos, attrnos) { Expr *expr = (Expr *) lfirst(lc); - ResTarget *col; - AttrNumber attr_num; + ResTarget *col = lfirst_node(ResTarget, icols); + AttrNumber attr_num = (AttrNumber) lfirst_int(attnos); TargetEntry *tle; - col = lfirst_node(ResTarget, icols); - attr_num = (AttrNumber) lfirst_int(attnos); - tle = makeTargetEntry(expr, attr_num, col->name, @@ -851,9 +847,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) rte->insertedCols = bms_add_member(rte->insertedCols, attr_num - FirstLowInvalidHeapAttributeNumber); - - icols = lnext(icols); - attnos = lnext(attnos); } /* Process ON CONFLICT, if any. */ @@ -898,7 +891,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt) * attrnos: integer column numbers (must be same length as icolumns) * strip_indirection: if true, remove any field/array assignment nodes */ -List * +static List * transformInsertRow(ParseState *pstate, List *exprlist, List *stmtcols, List *icolumns, List *attrnos, bool strip_indirection) @@ -950,19 +943,16 @@ transformInsertRow(ParseState *pstate, List *exprlist, * Prepare columns for assignment to target table. */ result = NIL; - icols = list_head(icolumns); - attnos = list_head(attrnos); - foreach(lc, exprlist) + forthree(lc, exprlist, icols, icolumns, attnos, attrnos) { Expr *expr = (Expr *) lfirst(lc); - ResTarget *col; - - col = lfirst_node(ResTarget, icols); + ResTarget *col = lfirst_node(ResTarget, icols); + int attno = lfirst_int(attnos); expr = transformAssignedExpr(pstate, expr, EXPR_KIND_INSERT_TARGET, col->name, - lfirst_int(attnos), + attno, col->indirection, col->location); @@ -976,13 +966,14 @@ transformInsertRow(ParseState *pstate, List *exprlist, expr = (Expr *) linitial(fstore->newvals); } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) expr; + SubscriptingRef *sbsref = (SubscriptingRef *) expr; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - expr = aref->refassgnexpr; + + expr = sbsref->refassgnexpr; } else break; @@ -990,9 +981,6 @@ transformInsertRow(ParseState *pstate, List *exprlist, } result = lappend(result, expr); - - icols = lnext(icols); - attnos = lnext(attnos); } return result; @@ -1024,9 +1012,6 @@ transformOnConflictClause(ParseState *pstate, if (onConflictClause->action == ONCONFLICT_UPDATE) { Relation targetrel = pstate->p_target_relation; - Var *var; - TargetEntry *te; - int attno; /* * All INSERT expressions have been parsed, get ready for potentially @@ -1035,75 +1020,37 @@ transformOnConflictClause(ParseState *pstate, pstate->p_is_insert = false; /* - * Add range table entry for the EXCLUDED pseudo relation; relkind is + * Add range table entry for the EXCLUDED pseudo relation. relkind is * set to composite to signal that we're not dealing with an actual - * relation. + * relation, and no permission checks are required on it. (We'll + * check the actual target relation, instead.) */ exclRte = addRangeTableEntryForRelation(pstate, targetrel, + RowExclusiveLock, makeAlias("excluded", NIL), false, false); exclRte->relkind = RELKIND_COMPOSITE_TYPE; - exclRelIndex = list_length(pstate->p_rtable); - - /* - * Build a targetlist representing the columns of the EXCLUDED pseudo - * relation. Have to be careful to use resnos that correspond to - * attnos of the underlying relation. - */ - for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++) - { - Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno); - char *name; - - if (attr->attisdropped) - { - /* - * can't use atttypid here, but it doesn't really matter what - * type the Const claims to be. - */ - var = (Var *) makeNullConst(INT4OID, -1, InvalidOid); - name = ""; - } - else - { - var = makeVar(exclRelIndex, attno + 1, - attr->atttypid, attr->atttypmod, - attr->attcollation, - 0); - name = pstrdup(NameStr(attr->attname)); - } - - te = makeTargetEntry((Expr *) var, - attno + 1, - name, - false); + exclRte->requiredPerms = 0; + /* other permissions fields in exclRte are already empty */ - /* don't require select access yet */ - exclRelTlist = lappend(exclRelTlist, te); - } + exclRelIndex = list_length(pstate->p_rtable); - /* - * Add a whole-row-Var entry to support references to "EXCLUDED.*". - * Like the other entries in exclRelTlist, its resno must match the - * Var's varattno, else the wrong things happen while resolving - * references in setrefs.c. This is against normal conventions for - * targetlists, but it's okay since we don't use this as a real tlist. - */ - var = makeVar(exclRelIndex, InvalidAttrNumber, - targetrel->rd_rel->reltype, - -1, InvalidOid, 0); - te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true); - exclRelTlist = lappend(exclRelTlist, te); + /* Create EXCLUDED rel's targetlist for use by EXPLAIN */ + exclRelTlist = BuildOnConflictExcludedTargetlist(targetrel, + exclRelIndex); /* * Add EXCLUDED and the target RTE to the namespace, so that they can - * be used in the UPDATE statement. + * be used in the UPDATE subexpressions. */ addRTEtoQuery(pstate, exclRte, false, true, true); addRTEtoQuery(pstate, pstate->p_target_rangetblentry, false, true, true); + /* + * Now transform the UPDATE subexpressions. + */ onConflictSet = transformUpdateTargetList(pstate, onConflictClause->targetList); @@ -1128,6 +1075,74 @@ transformOnConflictClause(ParseState *pstate, } +/* + * BuildOnConflictExcludedTargetlist + * Create target list for the EXCLUDED pseudo-relation of ON CONFLICT, + * representing the columns of targetrel with varno exclRelIndex. + * + * Note: Exported for use in the rewriter. + */ +List * +BuildOnConflictExcludedTargetlist(Relation targetrel, + Index exclRelIndex) +{ + List *result = NIL; + int attno; + Var *var; + TargetEntry *te; + + /* + * Note that resnos of the tlist must correspond to attnos of the + * underlying relation, hence we need entries for dropped columns too. + */ + for (attno = 0; attno < RelationGetNumberOfAttributes(targetrel); attno++) + { + Form_pg_attribute attr = TupleDescAttr(targetrel->rd_att, attno); + char *name; + + if (attr->attisdropped) + { + /* + * can't use atttypid here, but it doesn't really matter what type + * the Const claims to be. + */ + var = (Var *) makeNullConst(INT4OID, -1, InvalidOid); + name = NULL; + } + else + { + var = makeVar(exclRelIndex, attno + 1, + attr->atttypid, attr->atttypmod, + attr->attcollation, + 0); + name = pstrdup(NameStr(attr->attname)); + } + + te = makeTargetEntry((Expr *) var, + attno + 1, + name, + false); + + result = lappend(result, te); + } + + /* + * Add a whole-row-Var entry to support references to "EXCLUDED.*". Like + * the other entries in the EXCLUDED tlist, its resno must match the Var's + * varattno, else the wrong things happen while resolving references in + * setrefs.c. This is against normal conventions for targetlists, but + * it's okay since we don't use this as a real tlist. + */ + var = makeVar(exclRelIndex, InvalidAttrNumber, + targetrel->rd_rel->reltype, + -1, InvalidOid, 0); + te = makeTargetEntry((Expr *) var, InvalidAttrNumber, NULL, true); + result = lappend(result, te); + + return result; +} + + /* * count_rowexpr_columns - * get number of columns contained in a ROW() expression; @@ -1294,8 +1309,6 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) qry->hasWindowFuncs = pstate->p_hasWindowFuncs; qry->hasTargetSRFs = pstate->p_hasTargetSRFs; qry->hasAggs = pstate->p_hasAggs; - if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) - parseCheckAggregates(pstate, qry); foreach(l, stmt->lockingClause) { @@ -1305,6 +1318,10 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt) assign_query_collations(pstate, qry); + /* this must be done after collations, for reliable comparison of exprs */ + if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) + parseCheckAggregates(pstate, qry); + return qry; } @@ -1669,11 +1686,11 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) qry->targetList = NIL; targetvars = NIL; targetnames = NIL; - left_tlist = list_head(leftmostQuery->targetList); - forthree(lct, sostmt->colTypes, - lcm, sostmt->colTypmods, - lcc, sostmt->colCollations) + forfour(lct, sostmt->colTypes, + lcm, sostmt->colTypmods, + lcc, sostmt->colCollations, + left_tlist, leftmostQuery->targetList) { Oid colType = lfirst_oid(lct); int32 colTypmod = lfirst_int(lcm); @@ -1699,7 +1716,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) qry->targetList = lappend(qry->targetList, tle); targetvars = lappend(targetvars, var); targetnames = lappend(targetnames, makeString(colName)); - left_tlist = lnext(left_tlist); } /* @@ -1766,8 +1782,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) qry->hasWindowFuncs = pstate->p_hasWindowFuncs; qry->hasTargetSRFs = pstate->p_hasTargetSRFs; qry->hasAggs = pstate->p_hasAggs; - if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) - parseCheckAggregates(pstate, qry); foreach(l, lockingClause) { @@ -1777,6 +1791,10 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt) assign_query_collations(pstate, qry); + /* this must be done after collations, for reliable comparison of exprs */ + if (pstate->p_hasAggs || qry->groupClause || qry->groupingSets || qry->havingQual) + parseCheckAggregates(pstate, qry); + return qry; } @@ -2064,7 +2082,7 @@ transformSetOperationTree(ParseState *pstate, SelectStmt *stmt, * Select common collation. A common collation is required for * all set operators except UNION ALL; see SQL:2008 7.13 Syntax Rule 15c. (If we fail to identify a common - * collation for a UNION ALL column, the curCollations element + * collation for a UNION ALL column, the colCollations element * will be set to InvalidOid, which may result in a runtime error * if something at a higher query level wants to use the column's * collation.) @@ -2169,10 +2187,9 @@ determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist) * dummy result expressions of the non-recursive term. */ targetList = NIL; - left_tlist = list_head(leftmostQuery->targetList); next_resno = 1; - foreach(nrtl, nrtargetlist) + forboth(nrtl, nrtargetlist, left_tlist, leftmostQuery->targetList) { TargetEntry *nrtle = (TargetEntry *) lfirst(nrtl); TargetEntry *lefttle = (TargetEntry *) lfirst(left_tlist); @@ -2186,7 +2203,6 @@ determineRecursiveColTypes(ParseState *pstate, Node *larg, List *nrtargetlist) colName, false); targetList = lappend(targetList, tle); - left_tlist = lnext(left_tlist); } /* Now build CTE's output column info using dummy targetlist */ @@ -2262,15 +2278,16 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt) /* * transformUpdateTargetList - - * handle SET clause in UPDATE/MERGE/INSERT ... ON CONFLICT UPDATE + * handle SET clause in UPDATE/INSERT ... ON CONFLICT UPDATE */ -List * +static List * transformUpdateTargetList(ParseState *pstate, List *origTlist) { List *tlist = NIL; RangeTblEntry *target_rte; ListCell *orig_tl; ListCell *tl; + TupleDesc tupdesc = pstate->p_target_relation->rd_att; tlist = transformTargetList(pstate, origTlist, EXPR_KIND_UPDATE_SOURCE); @@ -2324,11 +2341,37 @@ transformUpdateTargetList(ParseState *pstate, List *origTlist) target_rte->updatedCols = bms_add_member(target_rte->updatedCols, attrno - FirstLowInvalidHeapAttributeNumber); - orig_tl = lnext(orig_tl); + orig_tl = lnext(origTlist, orig_tl); } if (orig_tl != NULL) elog(ERROR, "UPDATE target count mismatch --- internal error"); + /* + * Record in extraUpdatedCols generated columns referencing updated base + * columns. + */ + if (tupdesc->constr && + tupdesc->constr->has_generated_stored) + { + for (int i = 0; i < tupdesc->constr->num_defval; i++) + { + AttrDefault defval = tupdesc->constr->defval[i]; + Node *expr; + Bitmapset *attrs_used = NULL; + + /* skip if not generated column */ + if (!TupleDescAttr(tupdesc, defval.adnum - 1)->attgenerated) + continue; + + expr = stringToNode(defval.adbin); + pull_varattnos(expr, 1, &attrs_used); + + if (bms_overlap(target_rte->updatedCols, attrs_used)) + target_rte->extraUpdatedCols = bms_add_member(target_rte->extraUpdatedCols, + defval.adnum - FirstLowInvalidHeapAttributeNumber); + } + } + return tlist; } @@ -2556,7 +2599,7 @@ transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt) if (stmt->into->rel->relpersistence == RELPERSISTENCE_UNLOGGED) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("materialized views cannot be UNLOGGED"))); + errmsg("materialized views cannot be unlogged"))); /* * At runtime, we'll need a copy of the parsed-but-not-rewritten Query @@ -2604,6 +2647,8 @@ transformCallStmt(ParseState *pstate, CallStmt *stmt) true, stmt->funccall->location); + assign_expr_collations(pstate, node); + stmt->funcexpr = castNode(FuncExpr, node); result = makeNode(Query); @@ -2853,6 +2898,9 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, LCS_asString(lc->strength)), parser_errposition(pstate, thisrel->location))); break; + + /* Shouldn't be possible to see RTE_RESULT here */ + default: elog(ERROR, "unrecognized RTE type: %d", (int) rte->rtekind); diff --git a/src/backend/parser/check_keywords.pl b/src/backend/parser/check_keywords.pl index d8ebddec9f9..5d2db4197be 100644 --- a/src/backend/parser/check_keywords.pl +++ b/src/backend/parser/check_keywords.pl @@ -4,7 +4,7 @@ # Usage: check_keywords.pl gram.y kwlist.h # src/backend/parser/check_keywords.pl -# Copyright (c) 2009-2018, PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group use warnings; use strict; @@ -18,6 +18,7 @@ sub error { print STDERR @_; $errors = 1; + return; } $, = ' '; # set output field separator @@ -177,14 +178,14 @@ sub error if ($kwstring !~ /^[a-z_]+$/) { error -"'$kwstring' is not a valid keyword string, must be all lower-case ASCII chars"; + "'$kwstring' is not a valid keyword string, must be all lower-case ASCII chars"; } # Check that the keyword name is valid: all upper-case ASCII chars if ($kwname !~ /^[A-Z_]+$/) { error -"'$kwname' is not a valid keyword name, must be all upper-case ASCII chars"; + "'$kwname' is not a valid keyword name, must be all upper-case ASCII chars"; } # Check that the keyword string matches keyword name @@ -193,7 +194,7 @@ sub error if ($bare_kwname ne uc($kwstring)) { error -"keyword name '$kwname' doesn't match keyword string '$kwstring'"; + "keyword name '$kwname' doesn't match keyword string '$kwstring'"; } # Check that the keyword is present in the grammar diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index dd0c26c11b8..3f67aaf30ea 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -6,7 +6,7 @@ * gram.y * POSTGRESQL BISON rules/actions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -48,6 +48,7 @@ #include #include +#include "access/tableam.h" #include "catalog/index.h" #include "catalog/namespace.h" #include "catalog/pg_am.h" @@ -241,7 +242,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); PartitionSpec *partspec; PartitionBoundSpec *partboundspec; RoleSpec *rolespec; - MergeWhenClause *mergewhen; } %type stmt schema_stmt @@ -252,7 +252,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); AlterOperatorStmt AlterSeqStmt AlterSystemStmt AlterTableStmt AlterTblSpcStmt AlterExtensionStmt AlterExtensionContentsStmt AlterForeignTableStmt AlterCompositeTypeStmt AlterUserMappingStmt - AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt + AlterRoleStmt AlterRoleSetStmt AlterPolicyStmt AlterStatsStmt AlterDefaultPrivilegesStmt DefACLAction AnalyzeStmt CallStmt ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt @@ -260,11 +260,11 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt CreateSchemaStmt CreateSeqStmt CreateStmt CreateStatsStmt CreateTableSpaceStmt CreateFdwStmt CreateForeignServerStmt CreateForeignTableStmt - CreateAssertStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt + CreateAssertionStmt CreateTransformStmt CreateTrigStmt CreateEventTrigStmt CreateUserStmt CreateUserMappingStmt CreateRoleStmt CreatePolicyStmt CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt DoStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt - DropAssertStmt DropCastStmt DropRoleStmt + DropCastStmt DropRoleStmt DropdbStmt DropTableSpaceStmt DropTransformStmt DropUserMappingStmt ExplainStmt FetchStmt @@ -283,7 +283,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); CreateMatViewStmt RefreshMatViewStmt CreateAmStmt CreatePublicationStmt AlterPublicationStmt CreateSubscriptionStmt AlterSubscriptionStmt DropSubscriptionStmt - MergeStmt %type select_no_parens select_with_parens select_clause simple_select values_clause @@ -307,11 +306,14 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); create_extension_opt_item alter_extension_opt_item %type opt_lock lock_type cast_context -%type vacuum_option_list vacuum_option_elem - analyze_option_list analyze_option_elem +%type vac_analyze_option_name +%type vac_analyze_option_elem +%type vac_analyze_option_list +%type vac_analyze_option_arg %type opt_or_replace opt_grant_grant_option opt_grant_admin_option opt_nowait opt_if_exists opt_with_data + opt_transaction_chain %type opt_nowait_or_skip %type OptRoleList AlterOptRoleList @@ -324,6 +326,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type OptSchemaName %type OptSchemaEltList +%type am_type + %type TriggerForSpec TriggerForType %type TriggerActionTime %type TriggerEvents TriggerOneEvent @@ -339,7 +343,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type copy_file_name database_name access_method_clause access_method attr_name - name cursor_name file_name + table_access_method_clause name cursor_name file_name index_name opt_index_name cluster_index_specification %type func_name handler_name qual_Op qual_all_Op subquery_Op @@ -402,7 +406,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); TriggerTransitions TriggerReferencing publication_name_list vacuum_relation_list opt_vacuum_relation_list - merge_values_clause %type group_by_list %type group_by_item empty_grouping_set rollup_clause cube_clause @@ -443,7 +446,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type opt_instead %type opt_unique opt_concurrently opt_verbose opt_full %type opt_freeze opt_analyze opt_default opt_recheck -%type opt_binary opt_oids copy_delimiter +%type opt_binary copy_delimiter %type copy_from opt_program @@ -454,7 +457,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type fetch_args limit_clause select_limit_value offset_clause select_offset_value - select_offset_value2 opt_select_fetch_first_value + select_fetch_first_value I_or_F_const %type row_or_rows first_or_next %type OptSeqOptList SeqOptList OptParenthesizedSeqOptList @@ -463,7 +466,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type insert_rest %type opt_conf_expr %type opt_on_conflict -%type merge_insert merge_update merge_delete %type generic_set set_rest set_rest_more generic_reset reset_rest SetResetClause FunctionSetResetClause @@ -483,7 +485,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type row explicit_row implicit_row type_list array_expr_list %type case_expr case_arg when_clause case_default %type when_clause_list -%type sub_type +%type sub_type opt_materialized %type NumericOnly %type NumericOnly_list %type alias_clause opt_alias_clause @@ -585,13 +587,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type part_elem %type part_params %type PartitionBoundSpec -%type partbound_datum PartitionRangeDatum -%type hash_partbound partbound_datum_list range_datum_list +%type hash_partbound %type hash_partbound_elem -%type merge_when_clause opt_merge_when_and_condition -%type merge_when_list - /* * Non-keyword token types. These are hard-wired into the "flex" lexer. * They must be listed first so that their numeric codes do not depend on @@ -659,8 +657,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); LEADING LEAKPROOF LEAST LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P LOCKED LOGGED - MAPPING MATCH MATCHED MATERIALIZED MAXVALUE MERGE METHOD - MINUTE_P MINVALUE MODE MONTH_P MOVE + MAPPING MATCH MATERIALIZED MAXVALUE METHOD MINUTE_P MINVALUE MODE MONTH_P MOVE NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NONE NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF @@ -684,8 +681,8 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); SAVEPOINT SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SQL_P STABLE STANDALONE_P - START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P - SUBSCRIPTION SUBSTRING SYMMETRIC SYSID SYSTEM_P + START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRIP_P + SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P TABLE TABLES TABLESAMPLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIES TIME TIMESTAMP TO TRAILING TRANSACTION TRANSFORM @@ -855,6 +852,7 @@ stmt : | AlterRoleSetStmt | AlterRoleStmt | AlterSubscriptionStmt + | AlterStatsStmt | AlterTSConfigurationStmt | AlterTSDictionaryStmt | AlterUserMappingStmt @@ -868,7 +866,7 @@ stmt : | CopyStmt | CreateAmStmt | CreateAsStmt - | CreateAssertStmt + | CreateAssertionStmt | CreateCastStmt | CreateConversionStmt | CreateDomainStmt @@ -904,7 +902,6 @@ stmt : | DeleteStmt | DiscardStmt | DoStmt - | DropAssertStmt | DropCastStmt | DropOpClassStmt | DropOpFamilyStmt @@ -929,7 +926,6 @@ stmt : | RefreshMatViewStmt | LoadStmt | LockStmt - | MergeStmt | NotifyStmt | PrepareStmt | ReassignOwnedStmt @@ -1476,6 +1472,7 @@ generic_set: n->name = $1; $$ = n; } + ; set_rest_more: /* Generic SET syntaxes: */ generic_set {$$ = $1;} @@ -2321,14 +2318,7 @@ alter_table_cmd: n->missing_ok = false; $$ = (Node *)n; } - /* ALTER TABLE SET WITH OIDS */ - | SET WITH OIDS - { - AlterTableCmd *n = makeNode(AlterTableCmd); - n->subtype = AT_AddOids; - $$ = (Node *)n; - } - /* ALTER TABLE SET WITHOUT OIDS */ + /* ALTER TABLE SET WITHOUT OIDS, for backward compat */ | SET WITHOUT OIDS { AlterTableCmd *n = makeNode(AlterTableCmd); @@ -2694,7 +2684,7 @@ alter_identity_column_option: ; PartitionBoundSpec: - /* a HASH partition*/ + /* a HASH partition */ FOR VALUES WITH '(' hash_partbound ')' { ListCell *lc; @@ -2748,7 +2738,7 @@ PartitionBoundSpec: } /* a LIST partition */ - | FOR VALUES IN_P '(' partbound_datum_list ')' + | FOR VALUES IN_P '(' expr_list ')' { PartitionBoundSpec *n = makeNode(PartitionBoundSpec); @@ -2761,7 +2751,7 @@ PartitionBoundSpec: } /* a RANGE partition */ - | FOR VALUES FROM '(' range_datum_list ')' TO '(' range_datum_list ')' + | FOR VALUES FROM '(' expr_list ')' TO '(' expr_list ')' { PartitionBoundSpec *n = makeNode(PartitionBoundSpec); @@ -2804,57 +2794,6 @@ hash_partbound: } ; -partbound_datum: - Sconst { $$ = makeStringConst($1, @1); } - | NumericOnly { $$ = makeAConst($1, @1); } - | NULL_P { $$ = makeNullAConst(@1); } - ; - -partbound_datum_list: - partbound_datum { $$ = list_make1($1); } - | partbound_datum_list ',' partbound_datum - { $$ = lappend($1, $3); } - ; - -range_datum_list: - PartitionRangeDatum { $$ = list_make1($1); } - | range_datum_list ',' PartitionRangeDatum - { $$ = lappend($1, $3); } - ; - -PartitionRangeDatum: - MINVALUE - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_MINVALUE; - n->value = NULL; - n->location = @1; - - $$ = (Node *) n; - } - | MAXVALUE - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_MAXVALUE; - n->value = NULL; - n->location = @1; - - $$ = (Node *) n; - } - | partbound_datum - { - PartitionRangeDatum *n = makeNode(PartitionRangeDatum); - - n->kind = PARTITION_RANGE_DATUM_VALUE; - n->value = $1; - n->location = @1; - - $$ = (Node *) n; - } - ; - /***************************************************************************** * * ALTER TYPE @@ -2969,23 +2908,25 @@ ClosePortalStmt: * syntax had a hard-wired, space-separated set of options. * * Really old syntax, from versions 7.2 and prior: - * COPY [ BINARY ] table [ WITH OIDS ] FROM/TO file + * COPY [ BINARY ] table FROM/TO file * [ [ USING ] DELIMITERS 'delimiter' ] ] * [ WITH NULL AS 'null string' ] * This option placement is not supported with COPY (query...). * *****************************************************************************/ -CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids - copy_from opt_program copy_file_name copy_delimiter opt_with copy_options +CopyStmt: COPY opt_binary qualified_name opt_column_list + copy_from opt_program copy_file_name copy_delimiter opt_with + copy_options where_clause { CopyStmt *n = makeNode(CopyStmt); n->relation = $3; n->query = NULL; n->attlist = $4; - n->is_from = $6; - n->is_program = $7; - n->filename = $8; + n->is_from = $5; + n->is_program = $6; + n->filename = $7; + n->whereClause = $11; if (n->is_program && n->filename == NULL) ereport(ERROR, @@ -2993,16 +2934,20 @@ CopyStmt: COPY opt_binary qualified_name opt_column_list opt_oids errmsg("STDIN/STDOUT not allowed with PROGRAM"), parser_errposition(@8))); + if (!n->is_from && n->whereClause != NULL) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("WHERE clause not allowed with COPY TO"), + parser_errposition(@11))); + n->options = NIL; /* Concatenate user-supplied flags */ if ($2) n->options = lappend(n->options, $2); - if ($5) - n->options = lappend(n->options, $5); - if ($9) - n->options = lappend(n->options, $9); - if ($11) - n->options = list_concat(n->options, $11); + if ($8) + n->options = lappend(n->options, $8); + if ($10) + n->options = list_concat(n->options, $10); $$ = (Node *)n; } | COPY '(' PreparableStmt ')' TO opt_program copy_file_name opt_with copy_options @@ -3062,10 +3007,6 @@ copy_opt_item: { $$ = makeDefElem("format", (Node *)makeString("binary"), @1); } - | OIDS - { - $$ = makeDefElem("oids", (Node *)makeInteger(true), @1); - } | FREEZE { $$ = makeDefElem("freeze", (Node *)makeInteger(true), @1); @@ -3126,14 +3067,6 @@ opt_binary: | /*EMPTY*/ { $$ = NULL; } ; -opt_oids: - WITH OIDS - { - $$ = makeDefElem("oids", (Node *)makeInteger(true), @1); - } - | /*EMPTY*/ { $$ = NULL; } - ; - copy_delimiter: opt_using DELIMITERS Sconst { @@ -3199,7 +3132,8 @@ copy_generic_opt_arg_list_item: *****************************************************************************/ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' - OptInherit OptPartitionSpec OptWith OnCommitOption OptTableSpace + OptInherit OptPartitionSpec table_access_method_clause OptWith + OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $4->relpersistence = $2; @@ -3209,15 +3143,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->partspec = $9; n->ofTypename = NULL; n->constraints = NIL; - n->options = $10; - n->oncommit = $11; - n->tablespacename = $12; + n->accessMethod = $10; + n->options = $11; + n->oncommit = $12; + n->tablespacename = $13; n->if_not_exists = false; $$ = (Node *)n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '(' - OptTableElementList ')' OptInherit OptPartitionSpec OptWith - OnCommitOption OptTableSpace + OptTableElementList ')' OptInherit OptPartitionSpec table_access_method_clause + OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $7->relpersistence = $2; @@ -3227,15 +3162,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->partspec = $12; n->ofTypename = NULL; n->constraints = NIL; - n->options = $13; - n->oncommit = $14; - n->tablespacename = $15; + n->accessMethod = $13; + n->options = $14; + n->oncommit = $15; + n->tablespacename = $16; n->if_not_exists = true; $$ = (Node *)n; } | CREATE OptTemp TABLE qualified_name OF any_name - OptTypedTableElementList OptPartitionSpec OptWith OnCommitOption - OptTableSpace + OptTypedTableElementList OptPartitionSpec table_access_method_clause + OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $4->relpersistence = $2; @@ -3246,15 +3182,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = makeTypeNameFromNameList($6); n->ofTypename->location = @6; n->constraints = NIL; - n->options = $9; - n->oncommit = $10; - n->tablespacename = $11; + n->accessMethod = $9; + n->options = $10; + n->oncommit = $11; + n->tablespacename = $12; n->if_not_exists = false; $$ = (Node *)n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name - OptTypedTableElementList OptPartitionSpec OptWith OnCommitOption - OptTableSpace + OptTypedTableElementList OptPartitionSpec table_access_method_clause + OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $7->relpersistence = $2; @@ -3265,15 +3202,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->ofTypename = makeTypeNameFromNameList($9); n->ofTypename->location = @9; n->constraints = NIL; - n->options = $12; - n->oncommit = $13; - n->tablespacename = $14; + n->accessMethod = $12; + n->options = $13; + n->oncommit = $14; + n->tablespacename = $15; n->if_not_exists = true; $$ = (Node *)n; } | CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name - OptTypedTableElementList PartitionBoundSpec OptPartitionSpec OptWith - OnCommitOption OptTableSpace + OptTypedTableElementList PartitionBoundSpec OptPartitionSpec + table_access_method_clause OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $4->relpersistence = $2; @@ -3284,15 +3222,16 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->partspec = $10; n->ofTypename = NULL; n->constraints = NIL; - n->options = $11; - n->oncommit = $12; - n->tablespacename = $13; + n->accessMethod = $11; + n->options = $12; + n->oncommit = $13; + n->tablespacename = $14; n->if_not_exists = false; $$ = (Node *)n; } | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name OptTypedTableElementList PartitionBoundSpec OptPartitionSpec - OptWith OnCommitOption OptTableSpace + table_access_method_clause OptWith OnCommitOption OptTableSpace { CreateStmt *n = makeNode(CreateStmt); $7->relpersistence = $2; @@ -3303,9 +3242,10 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' n->partspec = $13; n->ofTypename = NULL; n->constraints = NIL; - n->options = $14; - n->oncommit = $15; - n->tablespacename = $16; + n->accessMethod = $14; + n->options = $15; + n->oncommit = $16; + n->tablespacename = $17; n->if_not_exists = true; $$ = (Node *)n; } @@ -3396,7 +3336,6 @@ columnDef: ColId Typename create_generic_options ColQualList n->is_local = true; n->is_not_null = false; n->is_from_type = false; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -3418,7 +3357,6 @@ columnOptions: ColId ColQualList n->is_local = true; n->is_not_null = false; n->is_from_type = false; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -3437,7 +3375,6 @@ columnOptions: ColId ColQualList n->is_local = true; n->is_not_null = false; n->is_from_type = false; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -3561,6 +3498,29 @@ ColConstraintElem: n->location = @1; $$ = (Node *)n; } + | GENERATED generated_when AS '(' a_expr ')' STORED + { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_GENERATED; + n->generated_when = $2; + n->raw_expr = $5; + n->cooked_expr = NULL; + n->location = @1; + + /* + * Can't do this in the grammar because of shift/reduce + * conflicts. (IDENTITY allows both ALWAYS and BY + * DEFAULT, but generated columns only allow ALWAYS.) We + * can also give a more useful error message and location. + */ + if ($2 != ATTRIBUTE_IDENTITY_ALWAYS) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("for a generated column, GENERATED ALWAYS must be specified"), + parser_errposition(@2))); + + $$ = (Node *)n; + } | REFERENCES qualified_name opt_column_list key_match key_actions { Constraint *n = makeNode(Constraint); @@ -3651,6 +3611,7 @@ TableLikeOption: | CONSTRAINTS { $$ = CREATE_TABLE_LIKE_CONSTRAINTS; } | DEFAULTS { $$ = CREATE_TABLE_LIKE_DEFAULTS; } | IDENTITY_P { $$ = CREATE_TABLE_LIKE_IDENTITY; } + | GENERATED { $$ = CREATE_TABLE_LIKE_GENERATED; } | INDEXES { $$ = CREATE_TABLE_LIKE_INDEXES; } | STATISTICS { $$ = CREATE_TABLE_LIKE_STATISTICS; } | STORAGE { $$ = CREATE_TABLE_LIKE_STORAGE; } @@ -3953,11 +3914,16 @@ part_elem: ColId opt_collate opt_class $$ = n; } ; -/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */ + +table_access_method_clause: + USING access_method { $$ = $2; } + | /*EMPTY*/ { $$ = NULL; } + ; + +/* WITHOUT OIDS is legacy only */ OptWith: WITH reloptions { $$ = $2; } - | WITH OIDS { $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(true), @1)); } - | WITHOUT OIDS { $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(false), @1)); } + | WITHOUT OIDS { $$ = NIL; } | /*EMPTY*/ { $$ = NIL; } ; @@ -4019,6 +3985,34 @@ CreateStatsStmt: } ; + +/***************************************************************************** + * + * QUERY : + * ALTER STATISTICS [IF EXISTS] stats_name + * SET STATISTICS + * + *****************************************************************************/ + +AlterStatsStmt: + ALTER STATISTICS any_name SET STATISTICS SignedIconst + { + AlterStatsStmt *n = makeNode(AlterStatsStmt); + n->defnames = $3; + n->missing_ok = false; + n->stxstattarget = $6; + $$ = (Node *)n; + } + | ALTER STATISTICS IF_P EXISTS any_name SET STATISTICS SignedIconst + { + AlterStatsStmt *n = makeNode(AlterStatsStmt); + n->defnames = $5; + n->missing_ok = true; + n->stxstattarget = $8; + $$ = (Node *)n; + } + ; + /***************************************************************************** * * QUERY : @@ -4059,14 +4053,16 @@ CreateAsStmt: ; create_as_target: - qualified_name opt_column_list OptWith OnCommitOption OptTableSpace + qualified_name opt_column_list table_access_method_clause + OptWith OnCommitOption OptTableSpace { $$ = makeNode(IntoClause); $$->rel = $1; $$->colNames = $2; - $$->options = $3; - $$->onCommit = $4; - $$->tableSpaceName = $5; + $$->accessMethod = $3; + $$->options = $4; + $$->onCommit = $5; + $$->tableSpaceName = $6; $$->viewQuery = NULL; $$->skipData = false; /* might get changed later */ } @@ -4116,14 +4112,15 @@ CreateMatViewStmt: ; create_mv_target: - qualified_name opt_column_list opt_reloptions OptTableSpace + qualified_name opt_column_list table_access_method_clause opt_reloptions OptTableSpace { $$ = makeNode(IntoClause); $$->rel = $1; $$->colNames = $2; - $$->options = $3; + $$->accessMethod = $3; + $$->options = $4; $$->onCommit = ONCOMMIT_NOOP; - $$->tableSpaceName = $4; + $$->tableSpaceName = $5; $$->viewQuery = NULL; /* filled at analysis time */ $$->skipData = false; /* might get changed later */ } @@ -5331,16 +5328,21 @@ row_security_cmd: * *****************************************************************************/ -CreateAmStmt: CREATE ACCESS METHOD name TYPE_P INDEX HANDLER handler_name +CreateAmStmt: CREATE ACCESS METHOD name TYPE_P am_type HANDLER handler_name { CreateAmStmt *n = makeNode(CreateAmStmt); n->amname = $4; n->handler_name = $8; - n->amtype = AMTYPE_INDEX; + n->amtype = $6; $$ = (Node *) n; } ; +am_type: + INDEX { $$ = AMTYPE_INDEX; } + | TABLE { $$ = AMTYPE_TABLE; } + ; + /***************************************************************************** * * QUERIES : @@ -5351,7 +5353,7 @@ CreateAmStmt: CREATE ACCESS METHOD name TYPE_P INDEX HANDLER handler_name CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON qualified_name TriggerReferencing TriggerForSpec TriggerWhen - EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')' + EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $3; @@ -5373,7 +5375,7 @@ CreateTrigStmt: | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON qualified_name OptConstrFromTable ConstraintAttributeSpec FOR EACH ROW TriggerWhen - EXECUTE PROCEDURE func_name '(' TriggerFuncArgs ')' + EXECUTE FUNCTION_or_PROCEDURE func_name '(' TriggerFuncArgs ')' { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->trigname = $4; @@ -5511,6 +5513,11 @@ TriggerWhen: | /*EMPTY*/ { $$ = NULL; } ; +FUNCTION_or_PROCEDURE: + FUNCTION + | PROCEDURE + ; + TriggerFuncArgs: TriggerFuncArg { $$ = list_make1($1); } | TriggerFuncArgs ',' TriggerFuncArg { $$ = lappend($1, $3); } @@ -5581,7 +5588,7 @@ ConstraintAttributeElem: CreateEventTrigStmt: CREATE EVENT TRIGGER name ON ColLabel - EXECUTE PROCEDURE func_name '(' ')' + EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')' { CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); n->trigname = $4; @@ -5592,7 +5599,7 @@ CreateEventTrigStmt: } | CREATE EVENT TRIGGER name ON ColLabel WHEN event_trigger_when_list - EXECUTE PROCEDURE func_name '(' ')' + EXECUTE FUNCTION_or_PROCEDURE func_name '(' ')' { CreateEventTrigStmt *n = makeNode(CreateEventTrigStmt); n->trigname = $4; @@ -5641,43 +5648,19 @@ enable_trigger: /***************************************************************************** * - * QUERIES : + * QUERY : * CREATE ASSERTION ... - * DROP ASSERTION ... * *****************************************************************************/ -CreateAssertStmt: - CREATE ASSERTION name CHECK '(' a_expr ')' - ConstraintAttributeSpec +CreateAssertionStmt: + CREATE ASSERTION any_name CHECK '(' a_expr ')' ConstraintAttributeSpec { - CreateTrigStmt *n = makeNode(CreateTrigStmt); - n->trigname = $3; - n->args = list_make1($6); - n->isconstraint = true; - processCASbits($8, @8, "ASSERTION", - &n->deferrable, &n->initdeferred, NULL, - NULL, yyscanner); - ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("CREATE ASSERTION is not yet implemented"))); - $$ = (Node *)n; - } - ; - -DropAssertStmt: - DROP ASSERTION name opt_drop_behavior - { - DropStmt *n = makeNode(DropStmt); - n->objects = NIL; - n->behavior = $4; - n->removeType = OBJECT_TRIGGER; /* XXX */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("DROP ASSERTION is not yet implemented"))); - $$ = (Node *) n; + $$ = NULL; } ; @@ -5690,25 +5673,27 @@ DropAssertStmt: *****************************************************************************/ DefineStmt: - CREATE AGGREGATE func_name aggr_args definition + CREATE opt_or_replace AGGREGATE func_name aggr_args definition { DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_AGGREGATE; n->oldstyle = false; - n->defnames = $3; - n->args = $4; - n->definition = $5; + n->replace = $2; + n->defnames = $4; + n->args = $5; + n->definition = $6; $$ = (Node *)n; } - | CREATE AGGREGATE func_name old_aggr_definition + | CREATE opt_or_replace AGGREGATE func_name old_aggr_definition { /* old-style (pre-8.2) syntax for CREATE AGGREGATE */ DefineStmt *n = makeNode(DefineStmt); n->kind = OBJECT_AGGREGATE; n->oldstyle = true; - n->defnames = $3; + n->replace = $2; + n->defnames = $4; n->args = NIL; - n->definition = $4; + n->definition = $5; $$ = (Node *)n; } | CREATE OPERATOR any_operator definition @@ -6380,6 +6365,7 @@ attrs: '.' attr_name type_name_list: Typename { $$ = list_make1($1); } | type_name_list ',' Typename { $$ = lappend($1, $3); } + ; /***************************************************************************** * @@ -7390,7 +7376,6 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->concurrent = $4; n->idxname = $5; n->relation = $7; - n->relationId = InvalidOid; n->accessMethod = $8; n->indexParams = $10; n->indexIncludingParams = $12; @@ -7407,6 +7392,7 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->initdeferred = false; n->transformed = false; n->if_not_exists = false; + n->reset_default_tblspc = false; $$ = (Node *)n; } | CREATE opt_unique INDEX opt_concurrently IF_P NOT EXISTS index_name @@ -7418,7 +7404,6 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->concurrent = $4; n->idxname = $8; n->relation = $10; - n->relationId = InvalidOid; n->accessMethod = $11; n->indexParams = $13; n->indexIncludingParams = $15; @@ -7435,6 +7420,7 @@ IndexStmt: CREATE opt_unique INDEX opt_concurrently opt_index_name n->initdeferred = false; n->transformed = false; n->if_not_exists = true; + n->reset_default_tblspc = false; $$ = (Node *)n; } ; @@ -7934,6 +7920,10 @@ common_func_opt_item: { $$ = makeDefElem("rows", (Node *)$2, @1); } + | SUPPORT any_name + { + $$ = makeDefElem("support", (Node *)$2, @1); + } | FunctionSetResetClause { /* we abuse the normal content of a DefElem here */ @@ -8366,42 +8356,46 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d * * QUERY: * - * REINDEX [ (options) ] type + * REINDEX [ (options) ] type [CONCURRENTLY] *****************************************************************************/ ReindexStmt: - REINDEX reindex_target_type qualified_name + REINDEX reindex_target_type opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $2; - n->relation = $3; + n->concurrent = $3; + n->relation = $4; n->name = NULL; n->options = 0; $$ = (Node *)n; } - | REINDEX reindex_target_multitable name + | REINDEX reindex_target_multitable opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $2; - n->name = $3; + n->concurrent = $3; + n->name = $4; n->relation = NULL; n->options = 0; $$ = (Node *)n; } - | REINDEX '(' reindex_option_list ')' reindex_target_type qualified_name + | REINDEX '(' reindex_option_list ')' reindex_target_type opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $5; - n->relation = $6; + n->concurrent = $6; + n->relation = $7; n->name = NULL; n->options = $3; $$ = (Node *)n; } - | REINDEX '(' reindex_option_list ')' reindex_target_multitable name + | REINDEX '(' reindex_option_list ')' reindex_target_multitable opt_concurrently name { ReindexStmt *n = makeNode(ReindexStmt); n->kind = $5; - n->name = $6; + n->concurrent = $6; + n->name = $7; n->relation = NULL; n->options = $3; $$ = (Node *)n; @@ -9859,11 +9853,12 @@ UnlistenStmt: *****************************************************************************/ TransactionStmt: - ABORT_P opt_transaction + ABORT_P opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); n->kind = TRANS_STMT_ROLLBACK; n->options = NIL; + n->chain = $3; $$ = (Node *)n; } | BEGIN_P opt_transaction transaction_mode_list_or_empty @@ -9880,25 +9875,28 @@ TransactionStmt: n->options = $3; $$ = (Node *)n; } - | COMMIT opt_transaction + | COMMIT opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); n->kind = TRANS_STMT_COMMIT; n->options = NIL; + n->chain = $3; $$ = (Node *)n; } - | END_P opt_transaction + | END_P opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); n->kind = TRANS_STMT_COMMIT; n->options = NIL; + n->chain = $3; $$ = (Node *)n; } - | ROLLBACK opt_transaction + | ROLLBACK opt_transaction opt_transaction_chain { TransactionStmt *n = makeNode(TransactionStmt); n->kind = TRANS_STMT_ROLLBACK; n->options = NIL; + n->chain = $3; $$ = (Node *)n; } | SAVEPOINT ColId @@ -9998,6 +9996,12 @@ transaction_mode_list_or_empty: { $$ = NIL; } ; +opt_transaction_chain: + AND CHAIN { $$ = true; } + | AND NO CHAIN { $$ = false; } + | /* EMPTY */ { $$ = false; } + ; + /***************************************************************************** * @@ -10485,7 +10489,9 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = $3; n->indexname = $4; - n->verbose = $2; + n->options = 0; + if ($2) + n->options |= CLUOPT_VERBOSE; $$ = (Node*)n; } | CLUSTER opt_verbose @@ -10493,7 +10499,9 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = NULL; n->indexname = NULL; - n->verbose = $2; + n->options = 0; + if ($2) + n->options |= CLUOPT_VERBOSE; $$ = (Node*)n; } /* kept for pre-8.3 compatibility */ @@ -10502,7 +10510,9 @@ ClusterStmt: ClusterStmt *n = makeNode(ClusterStmt); n->relation = $5; n->indexname = $3; - n->verbose = $2; + n->options = 0; + if ($2) + n->options |= CLUOPT_VERBOSE; $$ = (Node*)n; } ; @@ -10524,74 +10534,63 @@ cluster_index_specification: VacuumStmt: VACUUM opt_full opt_freeze opt_verbose opt_analyze opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_VACUUM; + n->options = NIL; if ($2) - n->options |= VACOPT_FULL; + n->options = lappend(n->options, + makeDefElem("full", NULL, @2)); if ($3) - n->options |= VACOPT_FREEZE; + n->options = lappend(n->options, + makeDefElem("freeze", NULL, @3)); if ($4) - n->options |= VACOPT_VERBOSE; + n->options = lappend(n->options, + makeDefElem("verbose", NULL, @4)); if ($5) - n->options |= VACOPT_ANALYZE; + n->options = lappend(n->options, + makeDefElem("analyze", NULL, @5)); n->rels = $6; + n->is_vacuumcmd = true; $$ = (Node *)n; } - | VACUUM '(' vacuum_option_list ')' opt_vacuum_relation_list + | VACUUM '(' vac_analyze_option_list ')' opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_VACUUM | $3; + n->options = $3; n->rels = $5; + n->is_vacuumcmd = true; $$ = (Node *) n; } ; -vacuum_option_list: - vacuum_option_elem { $$ = $1; } - | vacuum_option_list ',' vacuum_option_elem { $$ = $1 | $3; } - ; - -vacuum_option_elem: - analyze_keyword { $$ = VACOPT_ANALYZE; } - | VERBOSE { $$ = VACOPT_VERBOSE; } - | FREEZE { $$ = VACOPT_FREEZE; } - | FULL { $$ = VACOPT_FULL; } - | IDENT - { - if (strcmp($1, "disable_page_skipping") == 0) - $$ = VACOPT_DISABLE_PAGE_SKIPPING; - else - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unrecognized VACUUM option \"%s\"", $1), - parser_errposition(@1))); - } - ; - AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_ANALYZE; + n->options = NIL; if ($2) - n->options |= VACOPT_VERBOSE; + n->options = lappend(n->options, + makeDefElem("verbose", NULL, @2)); n->rels = $3; + n->is_vacuumcmd = false; $$ = (Node *)n; } - | analyze_keyword '(' analyze_option_list ')' opt_vacuum_relation_list + | analyze_keyword '(' vac_analyze_option_list ')' opt_vacuum_relation_list { VacuumStmt *n = makeNode(VacuumStmt); - n->options = VACOPT_ANALYZE | $3; + n->options = $3; n->rels = $5; + n->is_vacuumcmd = false; $$ = (Node *) n; } ; -analyze_option_list: - analyze_option_elem { $$ = $1; } - | analyze_option_list ',' analyze_option_elem { $$ = $1 | $3; } - ; - -analyze_option_elem: - VERBOSE { $$ = VACOPT_VERBOSE; } +vac_analyze_option_list: + vac_analyze_option_elem + { + $$ = list_make1($1); + } + | vac_analyze_option_list ',' vac_analyze_option_elem + { + $$ = lappend($1, $3); + } ; analyze_keyword: @@ -10599,6 +10598,24 @@ analyze_keyword: | ANALYSE /* British */ {} ; +vac_analyze_option_elem: + vac_analyze_option_name vac_analyze_option_arg + { + $$ = makeDefElem($1, $2, @1); + } + ; + +vac_analyze_option_name: + NonReservedWord { $$ = $1; } + | analyze_keyword { $$ = "analyze"; } + ; + +vac_analyze_option_arg: + opt_boolean_or_string { $$ = (Node *) makeString($1); } + | NumericOnly { $$ = (Node *) $1; } + | /* EMPTY */ { $$ = NULL; } + ; + opt_analyze: analyze_keyword { $$ = true; } | /*EMPTY*/ { $$ = false; } @@ -10689,7 +10706,6 @@ ExplainableStmt: | InsertStmt | UpdateStmt | DeleteStmt - | MergeStmt | DeclareCursorStmt | CreateAsStmt | CreateMatViewStmt @@ -10752,7 +10768,6 @@ PreparableStmt: | InsertStmt | UpdateStmt | DeleteStmt /* by default all are $$=$1 */ - | MergeStmt ; /***************************************************************************** @@ -10780,11 +10795,29 @@ ExecuteStmt: EXECUTE name execute_param_clause ctas->into = $4; ctas->relkind = OBJECT_TABLE; ctas->is_select_into = false; + ctas->if_not_exists = false; /* cram additional flags into the IntoClause */ $4->rel->relpersistence = $2; $4->skipData = !($9); $$ = (Node *) ctas; } + | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS + EXECUTE name execute_param_clause opt_with_data + { + CreateTableAsStmt *ctas = makeNode(CreateTableAsStmt); + ExecuteStmt *n = makeNode(ExecuteStmt); + n->name = $10; + n->params = $11; + ctas->query = (Node *) n; + ctas->into = $7; + ctas->relkind = OBJECT_TABLE; + ctas->is_select_into = false; + ctas->if_not_exists = true; + /* cram additional flags into the IntoClause */ + $7->rel->relpersistence = $2; + $7->skipData = !($12); + $$ = (Node *) ctas; + } ; execute_param_clause: '(' expr_list ')' { $$ = $2; } @@ -11119,142 +11152,6 @@ set_target_list: ; -/***************************************************************************** - * - * QUERY: - * MERGE STATEMENTS - * - *****************************************************************************/ - -MergeStmt: - opt_with_clause MERGE INTO relation_expr_opt_alias - USING table_ref - ON a_expr - merge_when_list - { - MergeStmt *m = makeNode(MergeStmt); - - m->withClause = $1; - m->relation = $4; - m->source_relation = $6; - m->join_condition = $8; - m->mergeWhenClauses = $9; - - $$ = (Node *)m; - } - ; - - -merge_when_list: - merge_when_clause { $$ = list_make1($1); } - | merge_when_list merge_when_clause { $$ = lappend($1,$2); } - ; - -merge_when_clause: - WHEN MATCHED opt_merge_when_and_condition THEN merge_update - { - $5->matched = true; - $5->commandType = CMD_UPDATE; - $5->condition = $3; - - $$ = (Node *) $5; - } - | WHEN MATCHED opt_merge_when_and_condition THEN merge_delete - { - MergeWhenClause *m = makeNode(MergeWhenClause); - - m->matched = true; - m->commandType = CMD_DELETE; - m->condition = $3; - - $$ = (Node *)m; - } - | WHEN NOT MATCHED opt_merge_when_and_condition THEN merge_insert - { - $6->matched = false; - $6->commandType = CMD_INSERT; - $6->condition = $4; - - $$ = (Node *) $6; - } - | WHEN NOT MATCHED opt_merge_when_and_condition THEN DO NOTHING - { - MergeWhenClause *m = makeNode(MergeWhenClause); - - m->matched = false; - m->commandType = CMD_NOTHING; - m->condition = $4; - - $$ = (Node *)m; - } - ; - -opt_merge_when_and_condition: - AND a_expr { $$ = $2; } - | { $$ = NULL; } - ; - -merge_delete: - DELETE_P { $$ = NULL; } - ; - -merge_update: - UPDATE SET set_clause_list - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->targetList = $3; - - $$ = n; - } - ; - -merge_insert: - INSERT merge_values_clause - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->cols = NIL; - n->values = $2; - $$ = n; - } - | INSERT OVERRIDING override_kind VALUE_P merge_values_clause - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->cols = NIL; - n->override = $3; - n->values = $5; - $$ = n; - } - | INSERT '(' insert_column_list ')' merge_values_clause - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->cols = $3; - n->values = $5; - $$ = n; - } - | INSERT '(' insert_column_list ')' OVERRIDING override_kind VALUE_P merge_values_clause - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->cols = $3; - n->override = $6; - n->values = $8; - $$ = n; - } - | INSERT DEFAULT VALUES - { - MergeWhenClause *n = makeNode(MergeWhenClause); - n->cols = NIL; - n->values = NIL; - $$ = n; - } - ; - -merge_values_clause: - VALUES '(' expr_list ')' - { - $$ = $3; - } - ; - /***************************************************************************** * * QUERY: @@ -11542,17 +11439,24 @@ cte_list: | cte_list ',' common_table_expr { $$ = lappend($1, $3); } ; -common_table_expr: name opt_name_list AS '(' PreparableStmt ')' +common_table_expr: name opt_name_list AS opt_materialized '(' PreparableStmt ')' { CommonTableExpr *n = makeNode(CommonTableExpr); n->ctename = $1; n->aliascolnames = $2; - n->ctequery = $5; + n->ctematerialized = $4; + n->ctequery = $6; n->location = @1; $$ = (Node *) n; } ; +opt_materialized: + MATERIALIZED { $$ = CTEMaterializeAlways; } + | NOT MATERIALIZED { $$ = CTEMaterializeNever; } + | /*EMPTY*/ { $$ = CTEMaterializeDefault; } + ; + opt_with_clause: with_clause { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } @@ -11715,15 +11619,23 @@ limit_clause: parser_errposition(@1))); } /* SQL:2008 syntax */ - | FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY + /* to avoid shift/reduce conflicts, handle the optional value with + * a separate production rather than an opt_ expression. The fact + * that ONLY is fully reserved means that this way, we defer any + * decision about what rule reduces ROW or ROWS to the point where + * we can see the ONLY token in the lookahead slot. + */ + | FETCH first_or_next select_fetch_first_value row_or_rows ONLY { $$ = $3; } + | FETCH first_or_next row_or_rows ONLY + { $$ = makeIntConst(1, -1); } ; offset_clause: OFFSET select_offset_value { $$ = $2; } /* SQL:2008 syntax */ - | OFFSET select_offset_value2 row_or_rows + | OFFSET select_fetch_first_value row_or_rows { $$ = $2; } ; @@ -11742,22 +11654,31 @@ select_offset_value: /* * Allowing full expressions without parentheses causes various parsing - * problems with the trailing ROW/ROWS key words. SQL only calls for - * constants, so we allow the rest only with parentheses. If omitted, - * default to 1. + * problems with the trailing ROW/ROWS key words. SQL spec only calls for + * , which is either a literal or a parameter (but + * an could be an identifier, bringing up conflicts + * with ROW/ROWS). We solve this by leveraging the presence of ONLY (see above) + * to determine whether the expression is missing rather than trying to make it + * optional in this rule. + * + * c_expr covers almost all the spec-required cases (and more), but it doesn't + * cover signed numeric literals, which are allowed by the spec. So we include + * those here explicitly. We need FCONST as well as ICONST because values that + * don't fit in the platform's "long", but do fit in bigint, should still be + * accepted here. (This is possible in 64-bit Windows as well as all 32-bit + * builds.) */ -opt_select_fetch_first_value: - SignedIconst { $$ = makeIntConst($1, @1); } - | '(' a_expr ')' { $$ = $2; } - | /*EMPTY*/ { $$ = makeIntConst(1, -1); } +select_fetch_first_value: + c_expr { $$ = $1; } + | '+' I_or_F_const + { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); } + | '-' I_or_F_const + { $$ = doNegate($2, @1); } ; -/* - * Again, the trailing ROW/ROWS in this case prevent the full expression - * syntax. c_expr is the best we can do. - */ -select_offset_value2: - c_expr { $$ = $1; } +I_or_F_const: + Iconst { $$ = makeIntConst($1,@1); } + | FCONST { $$ = makeFloatConst($1,@1); } ; /* noise words */ @@ -12397,7 +12318,6 @@ TableFuncElement: ColId Typename opt_collate_clause n->is_local = true; n->is_not_null = false; n->is_from_type = false; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -12651,7 +12571,7 @@ SimpleTypename: * Note that ConstInterval is not included here since it must * be pushed up higher in the rules to accommodate the postfix * options (e.g. INTERVAL '1' YEAR). Likewise, we have to handle - * the generic-type-name case in AExprConst to avoid premature + * the generic-type-name case in AexprConst to avoid premature * reduce/reduce conflicts against function names. */ ConstTypename: @@ -13182,15 +13102,15 @@ a_expr: c_expr { $$ = $1; } | a_expr SIMILAR TO a_expr %prec SIMILAR { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2($4, makeNullAConst(-1)), + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make1($4), @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", $1, (Node *) n, @2); } | a_expr SIMILAR TO a_expr ESCAPE a_expr %prec SIMILAR { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make2($4, $6), @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "~", @@ -13198,15 +13118,15 @@ a_expr: c_expr { $$ = $1; } } | a_expr NOT_LA SIMILAR TO a_expr %prec NOT_LA { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), - list_make2($5, makeNullAConst(-1)), + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), + list_make1($5), @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", $1, (Node *) n, @2); } | a_expr NOT_LA SIMILAR TO a_expr ESCAPE a_expr %prec NOT_LA { - FuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), + FuncCall *n = makeFuncCall(SystemFuncName("similar_to_escape"), list_make2($5, $7), @2); $$ = (Node *) makeSimpleA_Expr(AEXPR_SIMILAR, "!~", @@ -14100,20 +14020,25 @@ xmlexists_argument: { $$ = $2; } - | PASSING c_expr BY REF + | PASSING c_expr xml_passing_mech { $$ = $2; } - | PASSING BY REF c_expr + | PASSING xml_passing_mech c_expr { - $$ = $4; + $$ = $3; } - | PASSING BY REF c_expr BY REF + | PASSING xml_passing_mech c_expr xml_passing_mech { - $$ = $4; + $$ = $3; } ; +xml_passing_mech: + BY REF + | BY VALUE_P + ; + /* * Aggregate decoration clauses @@ -14427,9 +14352,9 @@ subquery_Op: | NOT_LA ILIKE { $$ = list_make1(makeString("!~~*")); } /* cannot put SIMILAR TO here, because SIMILAR TO is a hack. - * the regular expression is preprocessed by a function (similar_escape), + * the regular expression is preprocessed by a function (similar_to_escape), * and the ~ operator for posix regular expressions is used. - * x SIMILAR TO y -> x ~ similar_escape(y) + * x SIMILAR TO y -> x ~ similar_to_escape(y) * this transformation is made on the fly by the parser upwards. * however the SubLink structure which handles any/some/all stuff * is not ready for such a thing. @@ -15000,18 +14925,21 @@ RoleId: RoleSpec errmsg("role name \"%s\" is reserved", "public"), parser_errposition(@1))); + break; case ROLESPEC_SESSION_USER: ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), errmsg("%s cannot be used as a role name here", "SESSION_USER"), parser_errposition(@1))); + break; case ROLESPEC_CURRENT_USER: ereport(ERROR, (errcode(ERRCODE_RESERVED_NAME), errmsg("%s cannot be used as a role name here", "CURRENT_USER"), parser_errposition(@1))); + break; } } ; @@ -15256,10 +15184,8 @@ unreserved_keyword: | LOGGED | MAPPING | MATCH - | MATCHED | MATERIALIZED | MAXVALUE - | MERGE | METHOD | MINUTE_P | MINVALUE @@ -15364,9 +15290,11 @@ unreserved_keyword: | STDIN | STDOUT | STORAGE + | STORED | STRICT_P | STRIP_P | SUBSCRIPTION + | SUPPORT | SYSID | SYSTEM_P | TABLES @@ -15680,7 +15608,7 @@ makeColumnRef(char *colname, List *indirection, else if (IsA(lfirst(l), A_Star)) { /* We only allow '*' at the end of a ColumnRef */ - if (lnext(l) != NULL) + if (lnext(indirection, l) != NULL) parser_yyerror("improper use of \"*\""); } nfields++; @@ -15869,7 +15797,7 @@ check_indirection(List *indirection, core_yyscan_t yyscanner) { if (IsA(lfirst(l), A_Star)) { - if (lnext(l) != NULL) + if (lnext(indirection, l) != NULL) parser_yyerror("improper use of \"*\""); } } @@ -16282,20 +16210,15 @@ SplitColQualList(List *qualList, core_yyscan_t yyscanner) { ListCell *cell; - ListCell *prev; - ListCell *next; *collClause = NULL; - prev = NULL; - for (cell = list_head(qualList); cell; cell = next) + foreach(cell, qualList) { Node *n = (Node *) lfirst(cell); - next = lnext(cell); if (IsA(n, Constraint)) { /* keep it in list */ - prev = cell; continue; } if (IsA(n, CollateClause)) @@ -16312,7 +16235,7 @@ SplitColQualList(List *qualList, else elog(ERROR, "unexpected node type %d", (int) n->type); /* remove non-Constraint nodes from qualList */ - qualList = list_delete_cell(qualList, cell, prev); + qualList = foreach_delete_current(qualList, cell); } *constraintList = qualList; } @@ -16417,6 +16340,7 @@ makeRecursiveViewSelect(char *relname, List *aliases, Node *query) /* create common table expression */ cte->ctename = relname; cte->aliascolnames = aliases; + cte->ctematerialized = CTEMaterializeDefault; cte->ctequery = query; cte->location = -1; diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 0307738946a..f418c615458 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -3,7 +3,7 @@ * parse_agg.c * handle aggregates and window functions in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,8 +19,7 @@ #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/tlist.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/parse_agg.h" #include "parser/parse_clause.h" #include "parser/parse_coerce.h" @@ -43,7 +42,7 @@ typedef struct { ParseState *pstate; Query *qry; - PlannerInfo *root; + bool hasJoinRTEs; List *groupClauses; List *groupClauseCommonVars; bool have_non_var_grouping; @@ -52,23 +51,23 @@ typedef struct bool in_agg_direct_args; } check_ungrouped_columns_context; -static int check_agg_arguments(ParseState *pstate, - List *directargs, - List *args, - Expr *filter); +static int check_agg_arguments(ParseState *pstate, + List *directargs, + List *args, + Expr *filter); static bool check_agg_arguments_walker(Node *node, - check_agg_arguments_context *context); + check_agg_arguments_context *context); static void check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry, - List *groupClauses, List *groupClauseVars, - bool have_non_var_grouping, - List **func_grouped_rels); + List *groupClauses, List *groupClauseCommonVars, + bool have_non_var_grouping, + List **func_grouped_rels); static bool check_ungrouped_columns_walker(Node *node, - check_ungrouped_columns_context *context); + check_ungrouped_columns_context *context); static void finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry, - List *groupClauses, PlannerInfo *root, - bool have_non_var_grouping); + List *groupClauses, bool hasJoinRTEs, + bool have_non_var_grouping); static bool finalize_grouping_exprs_walker(Node *node, - check_ungrouped_columns_context *context); + check_ungrouped_columns_context *context); static void check_agglevels_and_constraints(ParseState *pstate, Node *expr); static List *expand_groupingset_node(GroupingSet *gs); static Node *make_agg_arg(Oid argtype, Oid argcollation); @@ -455,13 +454,6 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) case EXPR_KIND_VALUES_SINGLE: errkind = true; break; - case EXPR_KIND_MERGE_WHEN_AND: - if (isAgg) - err = _("aggregate functions are not allowed in WHEN AND conditions"); - else - err = _("grouping operations are not allowed in WHEN AND conditions"); - - break; case EXPR_KIND_CHECK_CONSTRAINT: case EXPR_KIND_DOMAIN_CHECK: if (isAgg) @@ -513,6 +505,13 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) else err = _("grouping operations are not allowed in trigger WHEN conditions"); + break; + case EXPR_KIND_PARTITION_BOUND: + if (isAgg) + err = _("aggregate functions are not allowed in partition bound"); + else + err = _("grouping operations are not allowed in partition bound"); + break; case EXPR_KIND_PARTITION_EXPRESSION: if (isAgg) @@ -521,6 +520,14 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) err = _("grouping operations are not allowed in partition key expressions"); break; + case EXPR_KIND_GENERATED_COLUMN: + + if (isAgg) + err = _("aggregate functions are not allowed in column generation expressions"); + else + err = _("grouping operations are not allowed in column generation expressions"); + + break; case EXPR_KIND_CALL_ARGUMENT: if (isAgg) @@ -530,6 +537,14 @@ check_agglevels_and_constraints(ParseState *pstate, Node *expr) break; + case EXPR_KIND_COPY_WHERE: + if (isAgg) + err = _("aggregate functions are not allowed in COPY FROM WHERE conditions"); + else + err = _("grouping operations are not allowed in COPY FROM WHERE conditions"); + + break; + /* * There is intentionally no default: case here, so that the * compiler will warn if we add a new ParseExprKind without @@ -880,9 +895,6 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, case EXPR_KIND_VALUES_SINGLE: errkind = true; break; - case EXPR_KIND_MERGE_WHEN_AND: - err = _("window functions are not allowed in WHEN AND conditions"); - break; case EXPR_KIND_CHECK_CONSTRAINT: case EXPR_KIND_DOMAIN_CHECK: err = _("window functions are not allowed in check constraints"); @@ -906,12 +918,21 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, case EXPR_KIND_TRIGGER_WHEN: err = _("window functions are not allowed in trigger WHEN conditions"); break; + case EXPR_KIND_PARTITION_BOUND: + err = _("window functions are not allowed in partition bound"); + break; case EXPR_KIND_PARTITION_EXPRESSION: err = _("window functions are not allowed in partition key expressions"); break; case EXPR_KIND_CALL_ARGUMENT: err = _("window functions are not allowed in CALL arguments"); break; + case EXPR_KIND_COPY_WHERE: + err = _("window functions are not allowed in COPY FROM WHERE conditions"); + break; + case EXPR_KIND_GENERATED_COLUMN: + err = _("window functions are not allowed in column generation expressions"); + break; /* * There is intentionally no default: case here, so that the @@ -1028,7 +1049,6 @@ parseCheckAggregates(ParseState *pstate, Query *qry) ListCell *l; bool hasJoinRTEs; bool hasSelfRefRTEs; - PlannerInfo *root = NULL; Node *clause; /* This should only be called if we found aggregates or grouping */ @@ -1063,7 +1083,7 @@ parseCheckAggregates(ParseState *pstate, Query *qry) if (gset_common) { - for_each_cell(l, lnext(list_head(gsets))) + for_each_cell(l, gsets, list_second_cell(gsets)) { gset_common = list_intersection_int(gset_common, lfirst(l)); if (!gset_common) @@ -1112,27 +1132,18 @@ parseCheckAggregates(ParseState *pstate, Query *qry) if (expr == NULL) continue; /* probably cannot happen */ - groupClauses = lcons(expr, groupClauses); + groupClauses = lappend(groupClauses, expr); } /* * If there are join alias vars involved, we have to flatten them to the * underlying vars, so that aliased and unaliased vars will be correctly * taken as equal. We can skip the expense of doing this if no rangetable - * entries are RTE_JOIN kind. We use the planner's flatten_join_alias_vars - * routine to do the flattening; it wants a PlannerInfo root node, which - * fortunately can be mostly dummy. + * entries are RTE_JOIN kind. */ if (hasJoinRTEs) - { - root = makeNode(PlannerInfo); - root->parse = qry; - root->planner_cxt = CurrentMemoryContext; - root->hasJoinRTEs = true; - - groupClauses = (List *) flatten_join_alias_vars(root, + groupClauses = (List *) flatten_join_alias_vars(qry, (Node *) groupClauses); - } /* * Detect whether any of the grouping expressions aren't simple Vars; if @@ -1172,10 +1183,10 @@ parseCheckAggregates(ParseState *pstate, Query *qry) */ clause = (Node *) qry->targetList; finalize_grouping_exprs(clause, pstate, qry, - groupClauses, root, + groupClauses, hasJoinRTEs, have_non_var_grouping); if (hasJoinRTEs) - clause = flatten_join_alias_vars(root, clause); + clause = flatten_join_alias_vars(qry, clause); check_ungrouped_columns(clause, pstate, qry, groupClauses, groupClauseCommonVars, have_non_var_grouping, @@ -1183,10 +1194,10 @@ parseCheckAggregates(ParseState *pstate, Query *qry) clause = (Node *) qry->havingQual; finalize_grouping_exprs(clause, pstate, qry, - groupClauses, root, + groupClauses, hasJoinRTEs, have_non_var_grouping); if (hasJoinRTEs) - clause = flatten_join_alias_vars(root, clause); + clause = flatten_join_alias_vars(qry, clause); check_ungrouped_columns(clause, pstate, qry, groupClauses, groupClauseCommonVars, have_non_var_grouping, @@ -1234,7 +1245,7 @@ check_ungrouped_columns(Node *node, ParseState *pstate, Query *qry, context.pstate = pstate; context.qry = qry; - context.root = NULL; + context.hasJoinRTEs = false; /* assume caller flattened join Vars */ context.groupClauses = groupClauses; context.groupClauseCommonVars = groupClauseCommonVars; context.have_non_var_grouping = have_non_var_grouping; @@ -1434,14 +1445,14 @@ check_ungrouped_columns_walker(Node *node, */ static void finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry, - List *groupClauses, PlannerInfo *root, + List *groupClauses, bool hasJoinRTEs, bool have_non_var_grouping) { check_ungrouped_columns_context context; context.pstate = pstate; context.qry = qry; - context.root = root; + context.hasJoinRTEs = hasJoinRTEs; context.groupClauses = groupClauses; context.groupClauseCommonVars = NIL; context.have_non_var_grouping = have_non_var_grouping; @@ -1514,8 +1525,8 @@ finalize_grouping_exprs_walker(Node *node, Node *expr = lfirst(lc); Index ref = 0; - if (context->root) - expr = flatten_join_alias_vars(context->root, expr); + if (context->hasJoinRTEs) + expr = flatten_join_alias_vars(context->qry, expr); /* * Each expression must match a grouping entry at the current @@ -1638,9 +1649,8 @@ expand_groupingset_node(GroupingSet *gs) Assert(gs_current->kind == GROUPING_SET_SIMPLE); - current_result - = list_concat(current_result, - list_copy(gs_current->content)); + current_result = list_concat(current_result, + gs_current->content); /* If we are done with making the current group, break */ if (--i == 0) @@ -1680,11 +1690,8 @@ expand_groupingset_node(GroupingSet *gs) Assert(gs_current->kind == GROUPING_SET_SIMPLE); if (mask & i) - { - current_result - = list_concat(current_result, - list_copy(gs_current->content)); - } + current_result = list_concat(current_result, + gs_current->content); mask <<= 1; } @@ -1711,11 +1718,12 @@ expand_groupingset_node(GroupingSet *gs) return result; } +/* list_sort comparator to sort sub-lists by length */ static int -cmp_list_len_asc(const void *a, const void *b) +cmp_list_len_asc(const ListCell *a, const ListCell *b) { - int la = list_length(*(List *const *) a); - int lb = list_length(*(List *const *) b); + int la = list_length((const List *) lfirst(a)); + int lb = list_length((const List *) lfirst(b)); return (la > lb) ? 1 : (la == lb) ? 0 : -1; } @@ -1766,7 +1774,7 @@ expand_grouping_sets(List *groupingSets, int limit) result = lappend(result, list_union_int(NIL, (List *) lfirst(lc))); } - for_each_cell(lc, lnext(list_head(expanded_groups))) + for_each_cell(lc, expanded_groups, list_second_cell(expanded_groups)) { List *p = lfirst(lc); List *new_result = NIL; @@ -1786,27 +1794,8 @@ expand_grouping_sets(List *groupingSets, int limit) result = new_result; } - if (list_length(result) > 1) - { - int result_len = list_length(result); - List **buf = palloc(sizeof(List *) * result_len); - List **ptr = buf; - - foreach(lc, result) - { - *ptr++ = lfirst(lc); - } - - qsort(buf, result_len, sizeof(List *), cmp_list_len_asc); - - result = NIL; - ptr = buf; - - while (result_len-- > 0) - result = lappend(result, *ptr++); - - pfree(buf); - } + /* Now sort the lists by length */ + list_sort(result, cmp_list_len_asc); return result; } diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index c73d06b3917..260ccd4d7fa 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -3,7 +3,7 @@ * parse_clause.c * handle clauses in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,9 +17,9 @@ #include "miscadmin.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/nbtree.h" +#include "access/table.h" #include "access/tsmapi.h" #include "catalog/catalog.h" #include "catalog/heap.h" @@ -31,8 +31,7 @@ #include "commands/defrem.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/tlist.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parsetree.h" #include "parser/parser.h" @@ -58,48 +57,51 @@ #define makeDefaultNSItem(rte) makeNamespaceItem(rte, true, true, false, true) static void extractRemainingColumns(List *common_colnames, - List *src_colnames, List *src_colvars, - List **res_colnames, List **res_colvars); + List *src_colnames, List *src_colvars, + List **res_colnames, List **res_colvars); static Node *transformJoinUsingClause(ParseState *pstate, - RangeTblEntry *leftRTE, RangeTblEntry *rightRTE, - List *leftVars, List *rightVars); + RangeTblEntry *leftRTE, RangeTblEntry *rightRTE, + List *leftVars, List *rightVars); static Node *transformJoinOnClause(ParseState *pstate, JoinExpr *j, - List *namespace); + List *namespace); static RangeTblEntry *getRTEForSpecialRelationTypes(ParseState *pstate, - RangeVar *rv); + RangeVar *rv); static RangeTblEntry *transformTableEntry(ParseState *pstate, RangeVar *r); static RangeTblEntry *transformRangeSubselect(ParseState *pstate, - RangeSubselect *r); + RangeSubselect *r); static RangeTblEntry *transformRangeFunction(ParseState *pstate, - RangeFunction *r); + RangeFunction *r); static RangeTblEntry *transformRangeTableFunc(ParseState *pstate, - RangeTableFunc *t); + RangeTableFunc *t); static TableSampleClause *transformRangeTableSample(ParseState *pstate, - RangeTableSample *rts); + RangeTableSample *rts); +static Node *transformFromClauseItem(ParseState *pstate, Node *n, + RangeTblEntry **top_rte, int *top_rti, + List **namespace); static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype, - Var *l_colvar, Var *r_colvar); + Var *l_colvar, Var *r_colvar); static ParseNamespaceItem *makeNamespaceItem(RangeTblEntry *rte, - bool rel_visible, bool cols_visible, - bool lateral_only, bool lateral_ok); + bool rel_visible, bool cols_visible, + bool lateral_only, bool lateral_ok); static void setNamespaceColumnVisibility(List *namespace, bool cols_visible); static void setNamespaceLateralState(List *namespace, - bool lateral_only, bool lateral_ok); + bool lateral_only, bool lateral_ok); static void checkExprIsVarFree(ParseState *pstate, Node *n, - const char *constructName); + const char *constructName); static TargetEntry *findTargetlistEntrySQL92(ParseState *pstate, Node *node, - List **tlist, ParseExprKind exprKind); + List **tlist, ParseExprKind exprKind); static TargetEntry *findTargetlistEntrySQL99(ParseState *pstate, Node *node, - List **tlist, ParseExprKind exprKind); -static int get_matching_location(int sortgroupref, - List *sortgrouprefs, List *exprs); + List **tlist, ParseExprKind exprKind); +static int get_matching_location(int sortgroupref, + List *sortgrouprefs, List *exprs); static List *resolve_unique_index_expr(ParseState *pstate, InferClause *infer, - Relation heapRel); + Relation heapRel); static List *addTargetToGroupList(ParseState *pstate, TargetEntry *tle, - List *grouplist, List *targetlist, int location); + List *grouplist, List *targetlist, int location); static WindowClause *findWindowClause(List *wclist, const char *name); static Node *transformFrameOffset(ParseState *pstate, int frameOptions, - Oid rangeopfamily, Oid rangeopcintype, Oid *inRangeFunc, - Node *clause); + Oid rangeopfamily, Oid rangeopcintype, Oid *inRangeFunc, + Node *clause); /* @@ -136,7 +138,6 @@ transformFromClause(ParseState *pstate, List *frmList) n = transformFromClauseItem(pstate, n, &rte, &rtindex, - NULL, NULL, &namespace); checkNameSpaceConflicts(pstate, pstate->p_namespace, namespace); @@ -199,13 +200,13 @@ setTargetTable(ParseState *pstate, RangeVar *relation, /* Close old target; this could only happen for multi-action rules */ if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation, NoLock); + table_close(pstate->p_target_relation, NoLock); /* * Open target rel and grab suitable lock (which we will hold till end of * transaction). * - * free_parsestate() will eventually do the corresponding heap_close(), + * free_parsestate() will eventually do the corresponding table_close(), * but *not* release the lock. */ pstate->p_target_relation = parserOpenTable(pstate, relation, @@ -215,6 +216,7 @@ setTargetTable(ParseState *pstate, RangeVar *relation, * Now build an RTE. */ rte = addRangeTableEntryForRelation(pstate, pstate->p_target_relation, + RowExclusiveLock, relation->alias, inh, false); pstate->p_target_rangetblentry = rte; @@ -246,46 +248,6 @@ setTargetTable(ParseState *pstate, RangeVar *relation, return rtindex; } -/* - * Given a relation-options list (of DefElems), return true iff the specified - * table/result set should be created with OIDs. This needs to be done after - * parsing the query string because the return value can depend upon the - * default_with_oids GUC var. - * - * In some situations, we want to reject an OIDS option even if it's present. - * That's (rather messily) handled here rather than reloptions.c, because that - * code explicitly punts checking for oids to here. - */ -bool -interpretOidsOption(List *defList, bool allowOids) -{ - ListCell *cell; - - /* Scan list to see if OIDS was included */ - foreach(cell, defList) - { - DefElem *def = (DefElem *) lfirst(cell); - - if (def->defnamespace == NULL && - strcmp(def->defname, "oids") == 0) - { - if (!allowOids) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unrecognized parameter \"%s\"", - def->defname))); - return defGetBoolean(def); - } - } - - /* Force no-OIDS result if caller disallows OIDS. */ - if (!allowOids) - return false; - - /* OIDS option was not specified, so use default. */ - return default_with_oids; -} - /* * Extract all not-in-common columns from column lists of a source table */ @@ -777,7 +739,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) /* undef ordinality column number */ tf->ordinalitycol = -1; - + /* Process column specs */ names = palloc(sizeof(char *) * list_length(rtf->columns)); colno = 0; @@ -825,7 +787,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) tf->coltypes = lappend_oid(tf->coltypes, typid); tf->coltypmods = lappend_int(tf->coltypmods, typmod); tf->colcollations = lappend_oid(tf->colcollations, - type_is_collatable(typid) ? DEFAULT_COLLATION_OID : InvalidOid); + get_typcollation(typid)); /* Transform the PATH and DEFAULT expressions */ if (rawc->colexpr) @@ -898,15 +860,15 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) { foreach(lc2, ns_names) { - char *name = strVal(lfirst(lc2)); + Value *ns_node = (Value *) lfirst(lc2); - if (name == NULL) + if (ns_node == NULL) continue; - if (strcmp(name, r->name) == 0) + if (strcmp(strVal(ns_node), r->name) == 0) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("namespace name \"%s\" is not unique", - name), + r->name), parser_errposition(pstate, r->location))); } } @@ -920,8 +882,9 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) default_ns_seen = true; } - /* Note the string may be NULL */ - ns_names = lappend(ns_names, makeString(r->name)); + /* We represent DEFAULT by a null pointer */ + ns_names = lappend(ns_names, + r->name ? makeString(r->name) : NULL); } tf->ns_uris = ns_uris; @@ -1094,21 +1057,14 @@ getRTEForSpecialRelationTypes(ParseState *pstate, RangeVar *rv) * * *top_rti: receives the rangetable index of top_rte. (Ditto.) * - * *right_rte: receives the RTE corresponding to the right side of the - * jointree. Only MERGE really needs to know about this and only MERGE passes a - * non-NULL pointer. - * - * *right_rti: receives the rangetable index of the right_rte. - * * *namespace: receives a List of ParseNamespaceItems for the RTEs exposed * as table/column names by this item. (The lateral_only flags in these items * are indeterminate and should be explicitly set by the caller before use.) */ -Node * +static Node * transformFromClauseItem(ParseState *pstate, Node *n, RangeTblEntry **top_rte, int *top_rti, - RangeTblEntry **right_rte, int *right_rti, - List **fnamespace) + List **namespace) { if (IsA(n, RangeVar)) { @@ -1130,7 +1086,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); *top_rte = rte; *top_rti = rtindex; - *fnamespace = list_make1(makeDefaultNSItem(rte)); + *namespace = list_make1(makeDefaultNSItem(rte)); rtr = makeNode(RangeTblRef); rtr->rtindex = rtindex; return (Node *) rtr; @@ -1148,7 +1104,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); *top_rte = rte; *top_rti = rtindex; - *fnamespace = list_make1(makeDefaultNSItem(rte)); + *namespace = list_make1(makeDefaultNSItem(rte)); rtr = makeNode(RangeTblRef); rtr->rtindex = rtindex; return (Node *) rtr; @@ -1166,7 +1122,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); *top_rte = rte; *top_rti = rtindex; - *fnamespace = list_make1(makeDefaultNSItem(rte)); + *namespace = list_make1(makeDefaultNSItem(rte)); rtr = makeNode(RangeTblRef); rtr->rtindex = rtindex; return (Node *) rtr; @@ -1184,7 +1140,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, Assert(rte == rt_fetch(rtindex, pstate->p_rtable)); *top_rte = rte; *top_rti = rtindex; - *fnamespace = list_make1(makeDefaultNSItem(rte)); + *namespace = list_make1(makeDefaultNSItem(rte)); rtr = makeNode(RangeTblRef); rtr->rtindex = rtindex; return (Node *) rtr; @@ -1199,7 +1155,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, /* Recursively transform the contained relation */ rel = transformFromClauseItem(pstate, rts->relation, - top_rte, top_rti, NULL, NULL, fnamespace); + top_rte, top_rti, namespace); /* Currently, grammar could only return a RangeVar as contained rel */ rtr = castNode(RangeTblRef, rel); rte = rt_fetch(rtr->rtindex, pstate->p_rtable); @@ -1227,7 +1183,6 @@ transformFromClauseItem(ParseState *pstate, Node *n, List *l_namespace, *r_namespace, *my_namespace, - *save_namespace, *l_colnames, *r_colnames, *res_colnames, @@ -1246,7 +1201,6 @@ transformFromClauseItem(ParseState *pstate, Node *n, j->larg = transformFromClauseItem(pstate, j->larg, &l_rte, &l_rtindex, - NULL, NULL, &l_namespace); /* @@ -1260,9 +1214,6 @@ transformFromClauseItem(ParseState *pstate, Node *n, * * Notice that we don't require the merged namespace list to be * conflict-free. See the comments for scanNameSpaceForRefname(). - * - * NB: this coding relies on the fact that list_concat is not - * destructive to its second argument. */ lateral_ok = (j->jointype == JOIN_INNER || j->jointype == JOIN_LEFT); setNamespaceLateralState(l_namespace, true, lateral_ok); @@ -1270,34 +1221,12 @@ transformFromClauseItem(ParseState *pstate, Node *n, sv_namespace_length = list_length(pstate->p_namespace); pstate->p_namespace = list_concat(pstate->p_namespace, l_namespace); - /* - * If we are running MERGE, don't make the other RTEs visible while - * parsing the source relation. It mustn't see them. - * - * Currently, only MERGE passes non-NULL value for right_rte, so we - * can safely deduce if we're running MERGE or not by just looking at - * the right_rte. If that ever changes, we should look at other means - * to find that. - */ - if (right_rte) - { - save_namespace = pstate->p_namespace; - pstate->p_namespace = NIL; - } - /* And now we can process the RHS */ j->rarg = transformFromClauseItem(pstate, j->rarg, &r_rte, &r_rtindex, - NULL, NULL, &r_namespace); - /* - * And now restore the namespace again so that join-quals can see it. - */ - if (right_rte) - pstate->p_namespace = save_namespace; - /* Remove the left-side RTEs from the namespace list again */ pstate->p_namespace = list_truncate(pstate->p_namespace, sv_namespace_length); @@ -1324,12 +1253,6 @@ transformFromClauseItem(ParseState *pstate, Node *n, expandRTE(r_rte, r_rtindex, 0, -1, false, &r_colnames, &r_colvars); - if (right_rte) - *right_rte = r_rte; - - if (right_rti) - *right_rti = r_rtindex; - /* * Natural join does not explicitly specify columns; must generate * columns to join. Need to run through the list of columns from each @@ -1558,7 +1481,7 @@ transformFromClauseItem(ParseState *pstate, Node *n, * The join RTE itself is always made visible for unqualified column * names. It's visible as a relation name only if it has an alias. */ - *fnamespace = lappend(my_namespace, + *namespace = lappend(my_namespace, makeNamespaceItem(rte, (j->alias != NULL), true, @@ -2190,9 +2113,7 @@ flatten_grouping_sets(Node *expr, bool toplevel, bool *hasGroupingSets) if (IsA(n1, GroupingSet) && ((GroupingSet *) n1)->kind == GROUPING_SET_SETS) - { result_set = list_concat(result_set, (List *) n2); - } else result_set = lappend(result_set, n2); } @@ -2830,6 +2751,16 @@ transformWindowDefinitions(ParseState *pstate, wc->inRangeNullsFirst = sortcl->nulls_first; } + /* Per spec, GROUPS mode requires an ORDER BY clause */ + if (wc->frameOptions & FRAMEOPTION_GROUPS) + { + if (wc->orderClause == NIL) + ereport(ERROR, + (errcode(ERRCODE_WINDOWING_ERROR), + errmsg("GROUPS mode requires an ORDER BY clause"), + parser_errposition(pstate, windef->location))); + } + /* Process frame offset expressions */ wc->startOffset = transformFrameOffset(pstate, wc->frameOptions, rangeopfamily, rangeopcintype, diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index c31a5630b2f..a6c51a95dae 100644 --- a/src/backend/parser/parse_coerce.c +++ b/src/backend/parser/parse_coerce.c @@ -3,7 +3,7 @@ * parse_coerce.c * handle type coercions/conversions for parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -33,22 +33,22 @@ static Node *coerce_type_typmod(Node *node, - Oid targetTypeId, int32 targetTypMod, - CoercionContext ccontext, CoercionForm cformat, - int location, - bool hideInputCoercion); + Oid targetTypeId, int32 targetTypMod, + CoercionContext ccontext, CoercionForm cformat, + int location, + bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, - CoercionPathType pathtype, - Oid funcId, - Oid targetTypeId, int32 targetTypMod, - CoercionContext ccontext, CoercionForm cformat, - int location); + CoercionPathType pathtype, + Oid funcId, + Oid targetTypeId, int32 targetTypMod, + CoercionContext ccontext, CoercionForm cformat, + int location); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, - Oid targetTypeId, - CoercionContext ccontext, - CoercionForm cformat, - int location); + Oid targetTypeId, + CoercionContext ccontext, + CoercionForm cformat, + int location); static bool is_complex_array(Oid typid); static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId); @@ -540,7 +540,7 @@ coerce_type(ParseState *pstate, Node *node, * as this determines the set of available casts. */ bool -can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids, +can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, CoercionContext ccontext) { bool have_generics = false; @@ -907,7 +907,12 @@ build_coercion_expression(Node *node, sourceBaseTypeId = getBaseTypeAndTypmod(exprType(node), &sourceBaseTypeMod); - /* Set up CaseTestExpr representing one element of source array */ + /* + * Set up a CaseTestExpr representing one element of the source array. + * This is an abuse of CaseTestExpr, but it's OK as long as there + * can't be any CaseExpr or ArrayCoerceExpr within the completed + * elemexpr. + */ ctest->typeId = get_element_type(sourceBaseTypeId); Assert(OidIsValid(ctest->typeId)); ctest->typeMod = sourceBaseTypeMod; @@ -1080,7 +1085,7 @@ coerce_record_to_complex(ParseState *pstate, Node *node, parser_coercion_errposition(pstate, location, expr))); newargs = lappend(newargs, cexpr); ucolno++; - arg = lnext(arg); + arg = lnext(args, arg); } if (arg != NULL) ereport(ERROR, @@ -1278,7 +1283,7 @@ select_common_type(ParseState *pstate, List *exprs, const char *context, Assert(exprs != NIL); pexpr = (Node *) linitial(exprs); - lc = lnext(list_head(exprs)); + lc = list_second_cell(exprs); ptype = exprType(pexpr); /* @@ -1288,7 +1293,7 @@ select_common_type(ParseState *pstate, List *exprs, const char *context, */ if (ptype != UNKNOWNOID) { - for_each_cell(lc, lc) + for_each_cell(lc, exprs, lc) { Node *nexpr = (Node *) lfirst(lc); Oid ntype = exprType(nexpr); @@ -1312,7 +1317,7 @@ select_common_type(ParseState *pstate, List *exprs, const char *context, ptype = getBaseType(ptype); get_type_category_preferred(ptype, &pcategory, &pispreferred); - for_each_cell(lc, lc) + for_each_cell(lc, exprs, lc) { Node *nexpr = (Node *) lfirst(lc); Oid ntype = getBaseType(exprType(nexpr)); @@ -1467,8 +1472,8 @@ coerce_to_common_type(ParseState *pstate, Node *node, * We do not ereport here, but just return false if a rule is violated. */ bool -check_generic_type_consistency(Oid *actual_arg_types, - Oid *declared_arg_types, +check_generic_type_consistency(const Oid *actual_arg_types, + const Oid *declared_arg_types, int nargs) { int j; @@ -1664,7 +1669,7 @@ check_generic_type_consistency(Oid *actual_arg_types, * assume that successive inputs are of the same actual element type. */ Oid -enforce_generic_type_consistency(Oid *actual_arg_types, +enforce_generic_type_consistency(const Oid *actual_arg_types, Oid *declared_arg_types, int nargs, Oid rettype, diff --git a/src/backend/parser/parse_collate.c b/src/backend/parser/parse_collate.c index 51c73c4018a..31a5f702a9a 100644 --- a/src/backend/parser/parse_collate.c +++ b/src/backend/parser/parse_collate.c @@ -29,7 +29,7 @@ * at runtime. If we knew exactly which functions require collation * information, we could throw those errors at parse time instead. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -74,19 +74,19 @@ typedef struct static bool assign_query_collations_walker(Node *node, ParseState *pstate); static bool assign_collations_walker(Node *node, - assign_collations_context *context); + assign_collations_context *context); static void merge_collation_state(Oid collation, - CollateStrength strength, - int location, - Oid collation2, - int location2, - assign_collations_context *context); + CollateStrength strength, + int location, + Oid collation2, + int location2, + assign_collations_context *context); static void assign_aggregate_collations(Aggref *aggref, - assign_collations_context *loccontext); + assign_collations_context *loccontext); static void assign_ordered_set_collations(Aggref *aggref, - assign_collations_context *loccontext); + assign_collations_context *loccontext); static void assign_hypothetical_collations(Aggref *aggref, - assign_collations_context *loccontext); + assign_collations_context *loccontext); /* @@ -485,7 +485,6 @@ assign_collations_walker(Node *node, assign_collations_context *context) case T_FromExpr: case T_OnConflictExpr: case T_SortGroupClause: - case T_MergeAction: (void) expression_tree_walker(node, assign_collations_walker, (void *) &loccontext); @@ -947,7 +946,7 @@ assign_hypothetical_collations(Aggref *aggref, while (extra_args-- > 0) { (void) assign_collations_walker((Node *) lfirst(h_cell), loccontext); - h_cell = lnext(h_cell); + h_cell = lnext(aggref->aggdirectargs, h_cell); } /* Scan hypothetical args and aggregated args in parallel */ @@ -1028,8 +1027,8 @@ assign_hypothetical_collations(Aggref *aggref, paircontext.location2, loccontext); - h_cell = lnext(h_cell); - s_cell = lnext(s_cell); + h_cell = lnext(aggref->aggdirectargs, h_cell); + s_cell = lnext(aggref->args, s_cell); } Assert(h_cell == NULL && s_cell == NULL); } diff --git a/src/backend/parser/parse_cte.c b/src/backend/parser/parse_cte.c index d28c421b6f7..63eea2a431c 100644 --- a/src/backend/parser/parse_cte.c +++ b/src/backend/parser/parse_cte.c @@ -3,7 +3,7 @@ * parse_cte.c * handle CTEs (common table expressions) in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -122,7 +122,7 @@ transformWithClause(ParseState *pstate, WithClause *withClause) CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc); ListCell *rest; - for_each_cell(rest, lnext(lc)) + for_each_cell(rest, withClause->ctes, lnext(withClause->ctes, lc)) { CommonTableExpr *cte2 = (CommonTableExpr *) lfirst(rest); @@ -327,9 +327,9 @@ analyzeCTE(ParseState *pstate, CommonTableExpr *cte) get_collation_name(exprCollation(texpr))), errhint("Use the COLLATE clause to set the collation of the non-recursive term."), parser_errposition(pstate, exprLocation(texpr)))); - lctyp = lnext(lctyp); - lctypmod = lnext(lctypmod); - lccoll = lnext(lccoll); + lctyp = lnext(cte->ctecoltypes, lctyp); + lctypmod = lnext(cte->ctecoltypmods, lctypmod); + lccoll = lnext(cte->ctecolcollations, lccoll); } if (lctyp != NULL || lctypmod != NULL || lccoll != NULL) /* shouldn't happen */ elog(ERROR, "wrong number of output columns in WITH"); diff --git a/src/backend/parser/parse_enr.c b/src/backend/parser/parse_enr.c index 069249b7324..fdf69761174 100644 --- a/src/backend/parser/parse_enr.c +++ b/src/backend/parser/parse_enr.c @@ -3,7 +3,7 @@ * parse_enr.c * parser support routines dealing with ephemeral named relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 38fbe3366fc..76f3dd7076f 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -3,7 +3,7 @@ * parse_expr.c * handle expressions in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,8 +20,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/tlist.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parse_clause.h" #include "parser/parse_coerce.h" @@ -105,35 +104,35 @@ static Node *transformMultiAssignRef(ParseState *pstate, MultiAssignRef *maref); static Node *transformCaseExpr(ParseState *pstate, CaseExpr *c); static Node *transformSubLink(ParseState *pstate, SubLink *sublink); static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, - Oid array_type, Oid element_type, int32 typmod); + Oid array_type, Oid element_type, int32 typmod); static Node *transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault); static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c); static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m); static Node *transformSQLValueFunction(ParseState *pstate, - SQLValueFunction *svf); + SQLValueFunction *svf); static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x); static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs); static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b); static Node *transformCurrentOfExpr(ParseState *pstate, CurrentOfExpr *cexpr); static Node *transformColumnRef(ParseState *pstate, ColumnRef *cref); static Node *transformWholeRowRef(ParseState *pstate, RangeTblEntry *rte, - int location); + int location); static Node *transformIndirection(ParseState *pstate, A_Indirection *ind); static Node *transformTypeCast(ParseState *pstate, TypeCast *tc); static Node *transformCollateClause(ParseState *pstate, CollateClause *c); static Node *make_row_comparison_op(ParseState *pstate, List *opname, - List *largs, List *rargs, int location); + List *largs, List *rargs, int location); static Node *make_row_distinct_op(ParseState *pstate, List *opname, - RowExpr *lrow, RowExpr *rrow, int location); + RowExpr *lrow, RowExpr *rrow, int location); static Expr *make_distinct_op(ParseState *pstate, List *opname, - Node *ltree, Node *rtree, int location); + Node *ltree, Node *rtree, int location); static Node *make_nulltest_from_distinct(ParseState *pstate, - A_Expr *distincta, Node *arg); + A_Expr *distincta, Node *arg); static int operator_precedence_group(Node *node, const char **nodename); static void emit_precedence_warnings(ParseState *pstate, - int opgroup, const char *opname, - Node *lchild, Node *rchild, - int location); + int opgroup, const char *opname, + Node *lchild, Node *rchild, + int location); /* @@ -466,13 +465,13 @@ transformIndirection(ParseState *pstate, A_Indirection *ind) /* process subscripts before this field selection */ if (subscripts) - result = (Node *) transformArraySubscripts(pstate, - result, - exprType(result), - InvalidOid, - exprTypmod(result), - subscripts, - NULL); + result = (Node *) transformContainerSubscripts(pstate, + result, + exprType(result), + InvalidOid, + exprTypmod(result), + subscripts, + NULL); subscripts = NIL; newresult = ParseFuncOrColumn(pstate, @@ -489,13 +488,13 @@ transformIndirection(ParseState *pstate, A_Indirection *ind) } /* process trailing subscripts, if any */ if (subscripts) - result = (Node *) transformArraySubscripts(pstate, - result, - exprType(result), - InvalidOid, - exprTypmod(result), - subscripts, - NULL); + result = (Node *) transformContainerSubscripts(pstate, + result, + exprType(result), + InvalidOid, + exprTypmod(result), + subscripts, + NULL); return result; } @@ -521,6 +520,80 @@ transformColumnRef(ParseState *pstate, ColumnRef *cref) CRERR_WRONG_DB, CRERR_TOO_MANY } crerr = CRERR_NO_COLUMN; + const char *err; + + /* + * Check to see if the column reference is in an invalid place within the + * query. We allow column references in most places, except in default + * expressions and partition bound expressions. + */ + err = NULL; + switch (pstate->p_expr_kind) + { + case EXPR_KIND_NONE: + Assert(false); /* can't happen */ + break; + case EXPR_KIND_OTHER: + case EXPR_KIND_JOIN_ON: + case EXPR_KIND_JOIN_USING: + case EXPR_KIND_FROM_SUBSELECT: + case EXPR_KIND_FROM_FUNCTION: + case EXPR_KIND_WHERE: + case EXPR_KIND_POLICY: + case EXPR_KIND_HAVING: + case EXPR_KIND_FILTER: + case EXPR_KIND_WINDOW_PARTITION: + case EXPR_KIND_WINDOW_ORDER: + case EXPR_KIND_WINDOW_FRAME_RANGE: + case EXPR_KIND_WINDOW_FRAME_ROWS: + case EXPR_KIND_WINDOW_FRAME_GROUPS: + case EXPR_KIND_SELECT_TARGET: + case EXPR_KIND_INSERT_TARGET: + case EXPR_KIND_UPDATE_SOURCE: + case EXPR_KIND_UPDATE_TARGET: + case EXPR_KIND_GROUP_BY: + case EXPR_KIND_ORDER_BY: + case EXPR_KIND_DISTINCT_ON: + case EXPR_KIND_LIMIT: + case EXPR_KIND_OFFSET: + case EXPR_KIND_RETURNING: + case EXPR_KIND_VALUES: + case EXPR_KIND_VALUES_SINGLE: + case EXPR_KIND_CHECK_CONSTRAINT: + case EXPR_KIND_DOMAIN_CHECK: + case EXPR_KIND_FUNCTION_DEFAULT: + case EXPR_KIND_INDEX_EXPRESSION: + case EXPR_KIND_INDEX_PREDICATE: + case EXPR_KIND_ALTER_COL_TRANSFORM: + case EXPR_KIND_EXECUTE_PARAMETER: + case EXPR_KIND_TRIGGER_WHEN: + case EXPR_KIND_PARTITION_EXPRESSION: + case EXPR_KIND_CALL_ARGUMENT: + case EXPR_KIND_COPY_WHERE: + case EXPR_KIND_GENERATED_COLUMN: + /* okay */ + break; + + case EXPR_KIND_COLUMN_DEFAULT: + err = _("cannot use column reference in DEFAULT expression"); + break; + case EXPR_KIND_PARTITION_BOUND: + err = _("cannot use column reference in partition bound expression"); + break; + + /* + * There is intentionally no default: case here, so that the + * compiler will warn if we add a new ParseExprKind without + * extending this switch. If we do see an unrecognized value at + * runtime, the behavior will be the same as for EXPR_KIND_OTHER, + * which is sane anyway. + */ + } + if (err) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg_internal("%s", err), + parser_errposition(pstate, cref->location))); /* * Give the PreParseColumnRefHook, if any, first shot. If it returns @@ -1818,7 +1891,6 @@ transformSubLink(ParseState *pstate, SubLink *sublink) case EXPR_KIND_RETURNING: case EXPR_KIND_VALUES: case EXPR_KIND_VALUES_SINGLE: - case EXPR_KIND_MERGE_WHEN_AND: /* okay */ break; case EXPR_KIND_CHECK_CONSTRAINT: @@ -1844,12 +1916,21 @@ transformSubLink(ParseState *pstate, SubLink *sublink) case EXPR_KIND_TRIGGER_WHEN: err = _("cannot use subquery in trigger WHEN condition"); break; + case EXPR_KIND_PARTITION_BOUND: + err = _("cannot use subquery in partition bound"); + break; case EXPR_KIND_PARTITION_EXPRESSION: err = _("cannot use subquery in partition key expression"); break; case EXPR_KIND_CALL_ARGUMENT: err = _("cannot use subquery in CALL argument"); break; + case EXPR_KIND_COPY_WHERE: + err = _("cannot use subquery in COPY FROM WHERE condition"); + break; + case EXPR_KIND_GENERATED_COLUMN: + err = _("cannot use subquery in column generation expression"); + break; /* * There is intentionally no default: case here, so that the @@ -2178,7 +2259,6 @@ transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault) RowExpr *newr; char fname[16]; int fnum; - ListCell *lc; newr = makeNode(RowExpr); @@ -2192,10 +2272,9 @@ transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault) /* ROW() has anonymous columns, so invent some field names */ newr->colnames = NIL; - fnum = 1; - foreach(lc, newr->args) + for (fnum = 1; fnum <= list_length(newr->args); fnum++) { - snprintf(fname, sizeof(fname), "f%d", fnum++); + snprintf(fname, sizeof(fname), "f%d", fnum); newr->colnames = lappend(newr->colnames, makeString(pstrdup(fname))); } @@ -3155,7 +3234,7 @@ operator_precedence_group(Node *node, const char **nodename) *nodename = strVal(linitial(aexpr->name)); /* Ignore if op was always higher priority than IS-tests */ if (strcmp(*nodename, "+") == 0 || - strcmp(*nodename, "-")) + strcmp(*nodename, "-") == 0) group = 0; else group = PREC_GROUP_PREFIX_OP; @@ -3472,12 +3551,16 @@ ParseExprKindName(ParseExprKind exprKind) return "EXECUTE"; case EXPR_KIND_TRIGGER_WHEN: return "WHEN"; + case EXPR_KIND_PARTITION_BOUND: + return "partition bound"; case EXPR_KIND_PARTITION_EXPRESSION: return "PARTITION BY"; case EXPR_KIND_CALL_ARGUMENT: return "CALL"; - case EXPR_KIND_MERGE_WHEN_AND: - return "MERGE WHEN AND"; + case EXPR_KIND_COPY_WHERE: + return "WHERE"; + case EXPR_KIND_GENERATED_COLUMN: + return "GENERATED AS"; /* * There is intentionally no default: case here, so that the diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 615aee6d15f..8e926539e6a 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -3,7 +3,7 @@ * parse_func.c * handle function calls in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,12 +35,22 @@ #include "utils/syscache.h" +/* Possible error codes from LookupFuncNameInternal */ +typedef enum +{ + FUNCLOOKUP_NOSUCHFUNC, + FUNCLOOKUP_AMBIGUOUS +} FuncLookupError; + static void unify_hypothetical_args(ParseState *pstate, - List *fargs, int numAggregatedArgs, - Oid *actual_arg_types, Oid *declared_arg_types); + List *fargs, int numAggregatedArgs, + Oid *actual_arg_types, Oid *declared_arg_types); static Oid FuncNameAsType(List *funcname); static Node *ParseComplexProjection(ParseState *pstate, const char *funcname, - Node *first_arg, int location); + Node *first_arg, int location); +static Oid LookupFuncNameInternal(List *funcname, int nargs, + const Oid *argtypes, + bool missing_ok, FuncLookupError *lookupError); /* @@ -49,15 +59,17 @@ static Node *ParseComplexProjection(ParseState *pstate, const char *funcname, * For historical reasons, Postgres tries to treat the notations tab.col * and col(tab) as equivalent: if a single-argument function call has an * argument of complex type and the (unqualified) function name matches - * any attribute of the type, we take it as a column projection. Conversely - * a function of a single complex-type argument can be written like a - * column reference, allowing functions to act like computed columns. + * any attribute of the type, we can interpret it as a column projection. + * Conversely a function of a single complex-type argument can be written + * like a column reference, allowing functions to act like computed columns. + * + * If both interpretations are possible, we prefer the one matching the + * syntactic form, but otherwise the form does not matter. * * Hence, both cases come through here. If fn is null, we're dealing with - * column syntax not function syntax, but in principle that should not - * affect the lookup behavior, only which error messages we deliver. - * The FuncCall struct is needed however to carry various decoration that - * applies to aggregate and window functions. + * column syntax not function syntax. In the function-syntax case, + * the FuncCall struct is needed to carry various decoration that applies + * to aggregate and window functions. * * Also, when fn is null, we return NULL on failure rather than * reporting a no-such-function error. @@ -68,6 +80,9 @@ static Node *ParseComplexProjection(ParseState *pstate, const char *funcname, * last_srf should be a copy of pstate->p_last_srf from just before we * started transforming fargs. If the caller knows that fargs couldn't * contain any SRF calls, last_srf can just be pstate->p_last_srf. + * + * proc_call is true if we are considering a CALL statement, so that the + * name must resolve to a procedure name, not anything else. */ Node * ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, @@ -81,10 +96,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, bool agg_distinct = (fn ? fn->agg_distinct : false); bool func_variadic = (fn ? fn->func_variadic : false); WindowDef *over = (fn ? fn->over : NULL); + bool could_be_projection; Oid rettype; Oid funcid; ListCell *l; - ListCell *nextl; Node *first_arg = NULL; int nargs; int nargsplusdefs; @@ -131,21 +146,18 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, * to distinguish "input" and "output" parameter symbols while parsing * function-call constructs. Don't do this if dealing with column syntax, * nor if we had WITHIN GROUP (because in that case it's critical to keep - * the argument count unchanged). We can't use foreach() because we may - * modify the list ... + * the argument count unchanged). */ nargs = 0; - for (l = list_head(fargs); l != NULL; l = nextl) + foreach(l, fargs) { Node *arg = lfirst(l); Oid argtype = exprType(arg); - nextl = lnext(l); - if (argtype == VOIDOID && IsA(arg, Param) && !is_column && !agg_within_group) { - fargs = list_delete_ptr(fargs, arg); + fargs = foreach_delete_current(fargs, l); continue; } @@ -199,35 +211,39 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, } /* - * Check for column projection: if function has one argument, and that - * argument is of complex type, and function name is not qualified, then - * the "function call" could be a projection. We also check that there - * wasn't any aggregate or variadic decoration, nor an argument name. + * Decide whether it's legitimate to consider the construct to be a column + * projection. For that, there has to be a single argument of complex + * type, the function name must not be qualified, and there cannot be any + * syntactic decoration that'd require it to be a function (such as + * aggregate or variadic decoration, or named arguments). */ - if (nargs == 1 && agg_order == NIL && agg_filter == NULL && !agg_star && - !agg_distinct && over == NULL && !func_variadic && argnames == NIL && - list_length(funcname) == 1) - { - Oid argtype = actual_arg_types[0]; + could_be_projection = (nargs == 1 && !proc_call && + agg_order == NIL && agg_filter == NULL && + !agg_star && !agg_distinct && over == NULL && + !func_variadic && argnames == NIL && + list_length(funcname) == 1 && + (actual_arg_types[0] == RECORDOID || + ISCOMPLEX(actual_arg_types[0]))); - if (argtype == RECORDOID || ISCOMPLEX(argtype)) - { - retval = ParseComplexProjection(pstate, - strVal(linitial(funcname)), - first_arg, - location); - if (retval) - return retval; + /* + * If it's column syntax, check for column projection case first. + */ + if (could_be_projection && is_column) + { + retval = ParseComplexProjection(pstate, + strVal(linitial(funcname)), + first_arg, + location); + if (retval) + return retval; - /* - * If ParseComplexProjection doesn't recognize it as a projection, - * just press on. - */ - } + /* + * If ParseComplexProjection doesn't recognize it as a projection, + * just press on. + */ } /* - * Okay, it's not a column projection, so it must really be a function. * func_get_detail looks up the function in the catalogs, does * disambiguation for polymorphic functions, handles inheritance, and * returns the funcid and type and set or singleton status of the @@ -253,21 +269,42 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, cancel_parser_errposition_callback(&pcbstate); - if (fdresult == FUNCDETAIL_COERCION) - { - /* - * We interpreted it as a type coercion. coerce_type can handle these - * cases, so why duplicate code... - */ - return coerce_type(pstate, linitial(fargs), - actual_arg_types[0], rettype, -1, - COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location); - } - else if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE) + /* + * Check for various wrong-kind-of-routine cases. + */ + + /* If this is a CALL, reject things that aren't procedures */ + if (proc_call && + (fdresult == FUNCDETAIL_NORMAL || + fdresult == FUNCDETAIL_AGGREGATE || + fdresult == FUNCDETAIL_WINDOWFUNC || + fdresult == FUNCDETAIL_COERCION)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("%s is not a procedure", + func_signature_string(funcname, nargs, + argnames, + actual_arg_types)), + errhint("To call a function, use SELECT."), + parser_errposition(pstate, location))); + /* Conversely, if not a CALL, reject procedures */ + if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("%s is a procedure", + func_signature_string(funcname, nargs, + argnames, + actual_arg_types)), + errhint("To call a procedure, use CALL."), + parser_errposition(pstate, location))); + + if (fdresult == FUNCDETAIL_NORMAL || + fdresult == FUNCDETAIL_PROCEDURE || + fdresult == FUNCDETAIL_COERCION) { /* - * Normal function found; was there anything indicating it must be an - * aggregate? + * In these cases, complain if there was anything indicating it must + * be an aggregate or window function. */ if (agg_star) ereport(ERROR, @@ -306,26 +343,14 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errmsg("OVER specified, but %s is not a window function nor an aggregate function", NameListToString(funcname)), parser_errposition(pstate, location))); + } - if (fdresult == FUNCDETAIL_NORMAL && proc_call) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("%s is not a procedure", - func_signature_string(funcname, nargs, - argnames, - actual_arg_types)), - errhint("To call a function, use SELECT."), - parser_errposition(pstate, location))); - - if (fdresult == FUNCDETAIL_PROCEDURE && !proc_call) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("%s is a procedure", - func_signature_string(funcname, nargs, - argnames, - actual_arg_types)), - errhint("To call a procedure, use CALL."), - parser_errposition(pstate, location))); + /* + * So far so good, so do some fdresult-type-specific processing. + */ + if (fdresult == FUNCDETAIL_NORMAL || fdresult == FUNCDETAIL_PROCEDURE) + { + /* Nothing special to do for these cases. */ } else if (fdresult == FUNCDETAIL_AGGREGATE) { @@ -336,15 +361,6 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, Form_pg_aggregate classForm; int catDirectArgs; - if (proc_call) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("%s is not a procedure", - func_signature_string(funcname, nargs, - argnames, - actual_arg_types)), - parser_errposition(pstate, location))); - tup = SearchSysCache1(AGGFNOID, ObjectIdGetDatum(funcid)); if (!HeapTupleIsValid(tup)) /* should not happen */ elog(ERROR, "cache lookup failed for aggregate %u", funcid); @@ -510,21 +526,38 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, NameListToString(funcname)), parser_errposition(pstate, location))); } - else + else if (fdresult == FUNCDETAIL_COERCION) { /* - * Oops. Time to die. - * - * If we are dealing with the attribute notation rel.function, let the - * caller handle failure. + * We interpreted it as a type coercion. coerce_type can handle these + * cases, so why duplicate code... + */ + return coerce_type(pstate, linitial(fargs), + actual_arg_types[0], rettype, -1, + COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location); + } + else if (fdresult == FUNCDETAIL_MULTIPLE) + { + /* + * We found multiple possible functional matches. If we are dealing + * with attribute notation, return failure, letting the caller report + * "no such column" (we already determined there wasn't one). If + * dealing with function notation, report "ambiguous function", + * regardless of whether there's also a column by this name. */ if (is_column) return NULL; - /* - * Else generate a detailed complaint for a function - */ - if (fdresult == FUNCDETAIL_MULTIPLE) + if (proc_call) + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("procedure %s is not unique", + func_signature_string(funcname, nargs, argnames, + actual_arg_types)), + errhint("Could not choose a best candidate procedure. " + "You might need to add explicit type casts."), + parser_errposition(pstate, location))); + else ereport(ERROR, (errcode(ERRCODE_AMBIGUOUS_FUNCTION), errmsg("function %s is not unique", @@ -533,7 +566,35 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, errhint("Could not choose a best candidate function. " "You might need to add explicit type casts."), parser_errposition(pstate, location))); - else if (list_length(agg_order) > 1 && !agg_within_group) + } + else + { + /* + * Not found as a function. If we are dealing with attribute + * notation, return failure, letting the caller report "no such + * column" (we already determined there wasn't one). + */ + if (is_column) + return NULL; + + /* + * Check for column projection interpretation, since we didn't before. + */ + if (could_be_projection) + { + retval = ParseComplexProjection(pstate, + strVal(linitial(funcname)), + first_arg, + location); + if (retval) + return retval; + } + + /* + * No function, and no column either. Since we're dealing with + * function notation, report "function does not exist". + */ + if (list_length(agg_order) > 1 && !agg_within_group) { /* It's agg(x, ORDER BY y,z) ... perhaps misplaced ORDER BY */ ereport(ERROR, @@ -546,6 +607,15 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, "after all regular arguments of the aggregate."), parser_errposition(pstate, location))); } + else if (proc_call) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("procedure %s does not exist", + func_signature_string(funcname, nargs, argnames, + actual_arg_types)), + errhint("No procedure matches the given name and argument types. " + "You might need to add explicit type casts."), + parser_errposition(pstate, location))); else ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FUNCTION), @@ -1609,8 +1679,8 @@ func_get_detail(List *funcname, int ndelete; ndelete = list_length(defaults) - best_candidate->ndargs; - while (ndelete-- > 0) - defaults = list_delete_first(defaults); + if (ndelete > 0) + defaults = list_copy_tail(defaults, ndelete); *argdefaults = defaults; } } @@ -1664,11 +1734,9 @@ unify_hypothetical_args(ParseState *pstate, Oid *actual_arg_types, Oid *declared_arg_types) { - Node *args[FUNC_MAX_ARGS]; int numDirectArgs, numNonHypotheticalArgs; - int i; - ListCell *lc; + int hargpos; numDirectArgs = list_length(fargs) - numAggregatedArgs; numNonHypotheticalArgs = numDirectArgs - numAggregatedArgs; @@ -1676,25 +1744,20 @@ unify_hypothetical_args(ParseState *pstate, if (numNonHypotheticalArgs < 0) elog(ERROR, "incorrect number of arguments to hypothetical-set aggregate"); - /* Deconstruct fargs into an array for ease of subscripting */ - i = 0; - foreach(lc, fargs) - { - args[i++] = (Node *) lfirst(lc); - } - /* Check each hypothetical arg and corresponding aggregated arg */ - for (i = numNonHypotheticalArgs; i < numDirectArgs; i++) + for (hargpos = numNonHypotheticalArgs; hargpos < numDirectArgs; hargpos++) { - int aargpos = numDirectArgs + (i - numNonHypotheticalArgs); + int aargpos = numDirectArgs + (hargpos - numNonHypotheticalArgs); + ListCell *harg = list_nth_cell(fargs, hargpos); + ListCell *aarg = list_nth_cell(fargs, aargpos); Oid commontype; /* A mismatch means AggregateCreate didn't check properly ... */ - if (declared_arg_types[i] != declared_arg_types[aargpos]) + if (declared_arg_types[hargpos] != declared_arg_types[aargpos]) elog(ERROR, "hypothetical-set aggregate has inconsistent declared argument types"); /* No need to unify if make_fn_arguments will coerce */ - if (declared_arg_types[i] != ANYOID) + if (declared_arg_types[hargpos] != ANYOID) continue; /* @@ -1703,7 +1766,7 @@ unify_hypothetical_args(ParseState *pstate, * the aggregated values). */ commontype = select_common_type(pstate, - list_make2(args[aargpos], args[i]), + list_make2(lfirst(aarg), lfirst(harg)), "WITHIN GROUP", NULL); @@ -1711,30 +1774,23 @@ unify_hypothetical_args(ParseState *pstate, * Perform the coercions. We don't need to worry about NamedArgExprs * here because they aren't supported with aggregates. */ - args[i] = coerce_type(pstate, - args[i], - actual_arg_types[i], - commontype, -1, - COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, - -1); - actual_arg_types[i] = commontype; - args[aargpos] = coerce_type(pstate, - args[aargpos], - actual_arg_types[aargpos], - commontype, -1, - COERCION_IMPLICIT, - COERCE_IMPLICIT_CAST, - -1); + lfirst(harg) = coerce_type(pstate, + (Node *) lfirst(harg), + actual_arg_types[hargpos], + commontype, -1, + COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, + -1); + actual_arg_types[hargpos] = commontype; + lfirst(aarg) = coerce_type(pstate, + (Node *) lfirst(aarg), + actual_arg_types[aargpos], + commontype, -1, + COERCION_IMPLICIT, + COERCE_IMPLICIT_CAST, + -1); actual_arg_types[aargpos] = commontype; } - - /* Reconstruct fargs from array */ - i = 0; - foreach(lc, fargs) - { - lfirst(lc) = args[i++]; - } } @@ -1813,7 +1869,12 @@ FuncNameAsType(List *funcname) Oid result; Type typtup; - typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL, false); + /* + * temp_ok=false protects the + * contract for writing SECURITY DEFINER functions safely. + */ + typtup = LookupTypeNameExtended(NULL, makeTypeNameFromNameList(funcname), + NULL, false, false); if (typtup == NULL) return InvalidOid; @@ -1935,7 +1996,7 @@ funcname_signature_string(const char *funcname, int nargs, if (i >= numposargs) { appendStringInfo(&argbuf, "%s => ", (char *) lfirst(lc)); - lc = lnext(lc); + lc = lnext(argnames, lc); } appendStringInfoString(&argbuf, format_type_be(argtypes[i])); } @@ -1958,57 +2019,55 @@ func_signature_string(List *funcname, int nargs, } /* - * LookupFuncName + * LookupFuncNameInternal + * Workhorse for LookupFuncName/LookupFuncWithArgs * - * Given a possibly-qualified function name and optionally a set of argument - * types, look up the function. Pass nargs == -1 to indicate that no argument - * types are specified. + * In an error situation, e.g. can't find the function, then we return + * InvalidOid and set *lookupError to indicate what went wrong. * - * If the function name is not schema-qualified, it is sought in the current - * namespace search path. - * - * If the function is not found, we return InvalidOid if noError is true, - * else raise an error. + * Possible errors: + * FUNCLOOKUP_NOSUCHFUNC: we can't find a function of this name. + * FUNCLOOKUP_AMBIGUOUS: nargs == -1 and more than one function matches. */ -Oid -LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError) +static Oid +LookupFuncNameInternal(List *funcname, int nargs, const Oid *argtypes, + bool missing_ok, FuncLookupError *lookupError) { FuncCandidateList clist; /* Passing NULL for argtypes is no longer allowed */ Assert(argtypes); - clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError); + /* Always set *lookupError, to forestall uninitialized-variable warnings */ + *lookupError = FUNCLOOKUP_NOSUCHFUNC; + + clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, + missing_ok); /* * If no arguments were specified, the name must yield a unique candidate. */ - if (nargs == -1) + if (nargs < 0) { if (clist) { + /* If there is a second match then it's ambiguous */ if (clist->next) { - if (!noError) - ereport(ERROR, - (errcode(ERRCODE_AMBIGUOUS_FUNCTION), - errmsg("function name \"%s\" is not unique", - NameListToString(funcname)), - errhint("Specify the argument list to select the function unambiguously."))); + *lookupError = FUNCLOOKUP_AMBIGUOUS; + return InvalidOid; } - else - return clist->oid; + /* Otherwise return the match */ + return clist->oid; } else - { - if (!noError) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("could not find a function named \"%s\"", - NameListToString(funcname)))); - } + return InvalidOid; } + /* + * Otherwise, look for a match to the arg types. FuncnameGetCandidates + * has ensured that there's at most one match in the returned list. + */ while (clist) { if (memcmp(argtypes, clist->args, nargs * sizeof(Oid)) == 0) @@ -2016,35 +2075,97 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError) clist = clist->next; } - if (!noError) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("function %s does not exist", - func_signature_string(funcname, nargs, - NIL, argtypes)))); - return InvalidOid; } +/* + * LookupFuncName + * + * Given a possibly-qualified function name and optionally a set of argument + * types, look up the function. Pass nargs == -1 to indicate that the number + * and types of the arguments are unspecified (this is NOT the same as + * specifying that there are no arguments). + * + * If the function name is not schema-qualified, it is sought in the current + * namespace search path. + * + * If the function is not found, we return InvalidOid if missing_ok is true, + * else raise an error. + * + * If nargs == -1 and multiple functions are found matching this function name + * we will raise an ambiguous-function error, regardless of what missing_ok is + * set to. + */ +Oid +LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool missing_ok) +{ + Oid funcoid; + FuncLookupError lookupError; + + funcoid = LookupFuncNameInternal(funcname, nargs, argtypes, missing_ok, + &lookupError); + + if (OidIsValid(funcoid)) + return funcoid; + + switch (lookupError) + { + case FUNCLOOKUP_NOSUCHFUNC: + /* Let the caller deal with it when missing_ok is true */ + if (missing_ok) + return InvalidOid; + + if (nargs < 0) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not find a function named \"%s\"", + NameListToString(funcname)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("function %s does not exist", + func_signature_string(funcname, nargs, + NIL, argtypes)))); + break; + + case FUNCLOOKUP_AMBIGUOUS: + /* Raise an error regardless of missing_ok */ + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("function name \"%s\" is not unique", + NameListToString(funcname)), + errhint("Specify the argument list to select the function unambiguously."))); + break; + } + + return InvalidOid; /* Keep compiler quiet */ +} + /* * LookupFuncWithArgs * - * Like LookupFuncName, but the argument types are specified by a + * Like LookupFuncName, but the argument types are specified by an * ObjectWithArgs node. Also, this function can check whether the result is a * function, procedure, or aggregate, based on the objtype argument. Pass * OBJECT_ROUTINE to accept any of them. * * For historical reasons, we also accept aggregates when looking for a * function. + * + * When missing_ok is true we don't generate any error for missing objects and + * return InvalidOid. Other types of errors can still be raised, regardless + * of the value of missing_ok. */ Oid -LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError) +LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool missing_ok) { Oid argoids[FUNC_MAX_ARGS]; int argcount; + int nargs; int i; ListCell *args_item; Oid oid; + FuncLookupError lookupError; Assert(objtype == OBJECT_AGGREGATE || objtype == OBJECT_FUNCTION || @@ -2053,114 +2174,194 @@ LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, bool noError) argcount = list_length(func->objargs); if (argcount > FUNC_MAX_ARGS) - ereport(ERROR, - (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg_plural("functions cannot have more than %d argument", - "functions cannot have more than %d arguments", - FUNC_MAX_ARGS, - FUNC_MAX_ARGS))); + { + if (objtype == OBJECT_PROCEDURE) + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("procedures cannot have more than %d argument", + "procedures cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + else + ereport(ERROR, + (errcode(ERRCODE_TOO_MANY_ARGUMENTS), + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); + } - args_item = list_head(func->objargs); - for (i = 0; i < argcount; i++) + i = 0; + foreach(args_item, func->objargs) { TypeName *t = (TypeName *) lfirst(args_item); - argoids[i] = LookupTypeNameOid(NULL, t, noError); - args_item = lnext(args_item); + argoids[i] = LookupTypeNameOid(NULL, t, missing_ok); + if (!OidIsValid(argoids[i])) + return InvalidOid; /* missing_ok must be true */ + i++; } /* - * When looking for a function or routine, we pass noError through to - * LookupFuncName and let it make any error messages. Otherwise, we make - * our own errors for the aggregate and procedure cases. + * Set nargs for LookupFuncNameInternal. It expects -1 to mean no args + * were specified. */ - oid = LookupFuncName(func->objname, func->args_unspecified ? -1 : argcount, argoids, - (objtype == OBJECT_FUNCTION || objtype == OBJECT_ROUTINE) ? noError : true); + nargs = func->args_unspecified ? -1 : argcount; - if (objtype == OBJECT_FUNCTION) - { - /* Make sure it's a function, not a procedure */ - if (oid && get_func_prokind(oid) == PROKIND_PROCEDURE) - { - if (noError) - return InvalidOid; - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("%s is not a function", - func_signature_string(func->objname, argcount, - NIL, argoids)))); - } - } - else if (objtype == OBJECT_PROCEDURE) + oid = LookupFuncNameInternal(func->objname, nargs, argoids, missing_ok, + &lookupError); + + if (OidIsValid(oid)) { - if (!OidIsValid(oid)) + /* + * Even if we found the function, perform validation that the objtype + * matches the prokind of the found function. For historical reasons + * we allow the objtype of FUNCTION to include aggregates and window + * functions; but we draw the line if the object is a procedure. That + * is a new enough feature that this historical rule does not apply. + */ + switch (objtype) { - if (noError) - return InvalidOid; - else if (func->args_unspecified) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("could not find a procedure named \"%s\"", - NameListToString(func->objname)))); - else - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("procedure %s does not exist", - func_signature_string(func->objname, argcount, - NIL, argoids)))); - } + case OBJECT_FUNCTION: + /* Only complain if it's a procedure. */ + if (get_func_prokind(oid) == PROKIND_PROCEDURE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("%s is not a function", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; - /* Make sure it's a procedure */ - if (get_func_prokind(oid) != PROKIND_PROCEDURE) - { - if (noError) - return InvalidOid; - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("%s is not a procedure", - func_signature_string(func->objname, argcount, - NIL, argoids)))); + case OBJECT_PROCEDURE: + /* Reject if found object is not a procedure. */ + if (get_func_prokind(oid) != PROKIND_PROCEDURE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("%s is not a procedure", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; + + case OBJECT_AGGREGATE: + /* Reject if found object is not an aggregate. */ + if (get_func_prokind(oid) != PROKIND_AGGREGATE) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("function %s is not an aggregate", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; + + default: + /* OBJECT_ROUTINE accepts anything. */ + break; } + + return oid; /* All good */ } - else if (objtype == OBJECT_AGGREGATE) + else { - if (!OidIsValid(oid)) + /* Deal with cases where the lookup failed */ + switch (lookupError) { - if (noError) - return InvalidOid; - else if (func->args_unspecified) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("could not find a aggregate named \"%s\"", - NameListToString(func->objname)))); - else if (argcount == 0) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("aggregate %s(*) does not exist", - NameListToString(func->objname)))); - else - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_FUNCTION), - errmsg("aggregate %s does not exist", - func_signature_string(func->objname, argcount, - NIL, argoids)))); - } + case FUNCLOOKUP_NOSUCHFUNC: + /* Suppress no-such-func errors when missing_ok is true */ + if (missing_ok) + break; - /* Make sure it's an aggregate */ - if (get_func_prokind(oid) != PROKIND_AGGREGATE) - { - if (noError) - return InvalidOid; - /* we do not use the (*) notation for functions... */ - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("function %s is not an aggregate", - func_signature_string(func->objname, argcount, - NIL, argoids)))); + switch (objtype) + { + case OBJECT_PROCEDURE: + if (func->args_unspecified) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not find a procedure named \"%s\"", + NameListToString(func->objname)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("procedure %s does not exist", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; + + case OBJECT_AGGREGATE: + if (func->args_unspecified) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not find an aggregate named \"%s\"", + NameListToString(func->objname)))); + else if (argcount == 0) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("aggregate %s(*) does not exist", + NameListToString(func->objname)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("aggregate %s does not exist", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; + + default: + /* FUNCTION and ROUTINE */ + if (func->args_unspecified) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("could not find a function named \"%s\"", + NameListToString(func->objname)))); + else + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_FUNCTION), + errmsg("function %s does not exist", + func_signature_string(func->objname, argcount, + NIL, argoids)))); + break; + } + break; + + case FUNCLOOKUP_AMBIGUOUS: + switch (objtype) + { + case OBJECT_FUNCTION: + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("function name \"%s\" is not unique", + NameListToString(func->objname)), + errhint("Specify the argument list to select the function unambiguously."))); + break; + case OBJECT_PROCEDURE: + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("procedure name \"%s\" is not unique", + NameListToString(func->objname)), + errhint("Specify the argument list to select the procedure unambiguously."))); + break; + case OBJECT_AGGREGATE: + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("aggregate name \"%s\" is not unique", + NameListToString(func->objname)), + errhint("Specify the argument list to select the aggregate unambiguously."))); + break; + case OBJECT_ROUTINE: + ereport(ERROR, + (errcode(ERRCODE_AMBIGUOUS_FUNCTION), + errmsg("routine name \"%s\" is not unique", + NameListToString(func->objname)), + errhint("Specify the argument list to select the routine unambiguously."))); + break; + + default: + Assert(false); /* Disallowed by Assert above */ + break; + } + break; } - } - return oid; + return InvalidOid; + } } /* @@ -2277,9 +2478,6 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) /* okay, since we process this like a SELECT tlist */ pstate->p_hasTargetSRFs = true; break; - case EXPR_KIND_MERGE_WHEN_AND: - err = _("set-returning functions are not allowed in WHEN AND conditions"); - break; case EXPR_KIND_CHECK_CONSTRAINT: case EXPR_KIND_DOMAIN_CHECK: err = _("set-returning functions are not allowed in check constraints"); @@ -2303,12 +2501,21 @@ check_srf_call_placement(ParseState *pstate, Node *last_srf, int location) case EXPR_KIND_TRIGGER_WHEN: err = _("set-returning functions are not allowed in trigger WHEN conditions"); break; + case EXPR_KIND_PARTITION_BOUND: + err = _("set-returning functions are not allowed in partition bound"); + break; case EXPR_KIND_PARTITION_EXPRESSION: err = _("set-returning functions are not allowed in partition key expressions"); break; case EXPR_KIND_CALL_ARGUMENT: err = _("set-returning functions are not allowed in CALL arguments"); break; + case EXPR_KIND_COPY_WHERE: + err = _("set-returning functions are not allowed in COPY FROM WHERE conditions"); + break; + case EXPR_KIND_GENERATED_COLUMN: + err = _("set-returning functions are not allowed in column generation expressions"); + break; /* * There is intentionally no default: case here, so that the diff --git a/src/backend/parser/parse_merge.c b/src/backend/parser/parse_merge.c deleted file mode 100644 index 722cb23b86c..00000000000 --- a/src/backend/parser/parse_merge.c +++ /dev/null @@ -1,654 +0,0 @@ -/*------------------------------------------------------------------------- - * - * parse_merge.c - * handle merge-statement in parser - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/parser/parse_merge.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include "miscadmin.h" - -#include "access/sysattr.h" -#include "nodes/makefuncs.h" -#include "parser/analyze.h" -#include "parser/parse_collate.h" -#include "parser/parsetree.h" -#include "parser/parser.h" -#include "parser/parse_clause.h" -#include "parser/parse_cte.h" -#include "parser/parse_merge.h" -#include "parser/parse_relation.h" -#include "parser/parse_target.h" -#include "utils/rel.h" -#include "utils/relcache.h" - -static int transformMergeJoinClause(ParseState *pstate, Node *merge, - List **mergeSourceTargetList); -static void setNamespaceForMergeWhen(ParseState *pstate, - MergeWhenClause *mergeWhenClause); -static void setNamespaceVisibilityForRTE(List *namespace, RangeTblEntry *rte, - bool rel_visible, - bool cols_visible); -static List *expandSourceTL(ParseState *pstate, RangeTblEntry *rte, - int rtindex); - -/* - * Special handling for MERGE statement is required because we assemble - * the query manually. This is similar to setTargetTable() followed - * by transformFromClause() but with a few less steps. - * - * Process the FROM clause and add items to the query's range table, - * joinlist, and namespace. - * - * A special targetlist comprising of the columns from the right-subtree of - * the join is populated and returned. Note that when the JoinExpr is - * setup by transformMergeStmt, the left subtree has the target result - * relation and the right subtree has the source relation. - * - * Returns the rangetable index of the target relation. - */ -static int -transformMergeJoinClause(ParseState *pstate, Node *merge, - List **mergeSourceTargetList) -{ - RangeTblEntry *rte, - *rt_rte; - List *namespace; - int rtindex, - rt_rtindex; - Node *n; - int mergeTarget_relation = list_length(pstate->p_rtable) + 1; - Var *var; - TargetEntry *te; - - n = transformFromClauseItem(pstate, merge, - &rte, - &rtindex, - &rt_rte, - &rt_rtindex, - &namespace); - - pstate->p_joinlist = list_make1(n); - - /* - * We created an internal join between the target and the source relation - * to carry out the MERGE actions. Normally such an unaliased join hides - * the joining relations, unless the column references are qualified. - * Also, any unqualified column references are resolved to the Join RTE, if - * there is a matching entry in the targetlist. But the way MERGE - * execution is later setup, we expect all column references to resolve to - * either the source or the target relation. Hence we must not add the - * Join RTE to the namespace. - * - * The last entry must be for the top-level Join RTE. We don't want to - * resolve any references to the Join RTE. So discard that. - * - * We also do not want to resolve any references from the leftside of the - * Join since that corresponds to the target relation. References to the - * columns of the target relation must be resolved from the result - * relation and not the one that is used in the join. So the - * mergeTarget_relation is marked invisible to both qualified as well as - * unqualified references. - */ - Assert(list_length(namespace) > 1); - namespace = list_truncate(namespace, list_length(namespace) - 1); - pstate->p_namespace = list_concat(pstate->p_namespace, namespace); - - setNamespaceVisibilityForRTE(pstate->p_namespace, - rt_fetch(mergeTarget_relation, pstate->p_rtable), false, false); - - /* - * Expand the right relation and add its columns to the - * mergeSourceTargetList. Note that the right relation can either be a - * plain relation or a subquery or anything that can have a - * RangeTableEntry. - */ - *mergeSourceTargetList = expandSourceTL(pstate, rt_rte, rt_rtindex); - - /* - * Add a whole-row-Var entry to support references to "source.*". - */ - var = makeWholeRowVar(rt_rte, rt_rtindex, 0, false); - te = makeTargetEntry((Expr *) var, list_length(*mergeSourceTargetList) + 1, - NULL, true); - *mergeSourceTargetList = lappend(*mergeSourceTargetList, te); - - return mergeTarget_relation; -} - -/* - * Make appropriate changes to the namespace visibility while transforming - * individual action's quals and targetlist expressions. In particular, for - * INSERT actions we must only see the source relation (since INSERT action is - * invoked for NOT MATCHED tuples and hence there is no target tuple to deal - * with). On the other hand, UPDATE and DELETE actions can see both source and - * target relations. - * - * Also, since the internal Join node can hide the source and target - * relations, we must explicitly make the respective relation as visible so - * that columns can be referenced unqualified from these relations. - */ -static void -setNamespaceForMergeWhen(ParseState *pstate, MergeWhenClause *mergeWhenClause) -{ - RangeTblEntry *targetRelRTE, - *sourceRelRTE; - - /* Assume target relation is at index 1 */ - targetRelRTE = rt_fetch(1, pstate->p_rtable); - - /* - * Assume that the top-level join RTE is at the end. The source relation - * is just before that. - */ - sourceRelRTE = rt_fetch(list_length(pstate->p_rtable) - 1, pstate->p_rtable); - - switch (mergeWhenClause->commandType) - { - case CMD_INSERT: - - /* - * Inserts can't see target relation, but they can see source - * relation. - */ - setNamespaceVisibilityForRTE(pstate->p_namespace, - targetRelRTE, false, false); - setNamespaceVisibilityForRTE(pstate->p_namespace, - sourceRelRTE, true, true); - break; - - case CMD_UPDATE: - case CMD_DELETE: - - /* - * Updates and deletes can see both target and source relations. - */ - setNamespaceVisibilityForRTE(pstate->p_namespace, - targetRelRTE, true, true); - setNamespaceVisibilityForRTE(pstate->p_namespace, - sourceRelRTE, true, true); - break; - - case CMD_NOTHING: - break; - default: - elog(ERROR, "unknown action in MERGE WHEN clause"); - } -} - -/* - * transformMergeStmt - - * transforms a MERGE statement - */ -Query * -transformMergeStmt(ParseState *pstate, MergeStmt *stmt) -{ - Query *qry = makeNode(Query); - ListCell *l; - AclMode targetPerms = ACL_NO_RIGHTS; - bool is_terminal[2]; - JoinExpr *joinexpr; - RangeTblEntry *resultRelRTE, *mergeRelRTE; - List *mergeActionList; - - /* There can't be any outer WITH to worry about */ - Assert(pstate->p_ctenamespace == NIL); - - qry->commandType = CMD_MERGE; - qry->hasRecursive = false; - - /* process the WITH clause independently of all else */ - if (stmt->withClause) - { - if (stmt->withClause->recursive) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("WITH RECURSIVE is not supported for MERGE statement"))); - - qry->cteList = transformWithClause(pstate, stmt->withClause); - qry->hasModifyingCTE = pstate->p_hasModifyingCTE; - } - - /* - * Check WHEN clauses for permissions and sanity - */ - is_terminal[0] = false; - is_terminal[1] = false; - foreach(l, stmt->mergeWhenClauses) - { - MergeWhenClause *mergeWhenClause = (MergeWhenClause *) lfirst(l); - int when_type = (mergeWhenClause->matched ? 0 : 1); - - /* - * Collect action types so we can check Target permissions - */ - switch (mergeWhenClause->commandType) - { - case CMD_INSERT: - targetPerms |= ACL_INSERT; - break; - case CMD_UPDATE: - targetPerms |= ACL_UPDATE; - break; - case CMD_DELETE: - targetPerms |= ACL_DELETE; - break; - case CMD_NOTHING: - break; - default: - elog(ERROR, "unknown action in MERGE WHEN clause"); - } - - /* - * Check for unreachable WHEN clauses - */ - if (mergeWhenClause->condition == NULL) - is_terminal[when_type] = true; - else if (is_terminal[when_type]) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("unreachable WHEN clause specified after unconditional WHEN clause"))); - } - - /* - * Construct a query of the form - * SELECT relation.ctid --junk attribute - * ,relation.tableoid --junk attribute - * ,source_relation. - * ,relation. - * FROM relation RIGHT JOIN source_relation - * ON join_condition; -- no WHERE clause - all conditions are applied in - * executor - * - * stmt->relation is the target relation, given as a RangeVar - * stmt->source_relation is a RangeVar or subquery - * - * We specify the join as a RIGHT JOIN as a simple way of forcing the - * first (larg) RTE to refer to the target table. - * - * The MERGE query's join can be tuned in some cases, see below for these - * special case tweaks. - * - * We set QSRC_PARSER to show query constructed in parse analysis - * - * Note that we have only one Query for a MERGE statement and the planner - * is called only once. That query is executed once to produce our stream - * of candidate change rows, so the query must contain all of the columns - * required by each of the targetlist or conditions for each action. - * - * As top-level statements INSERT, UPDATE and DELETE have a Query, whereas - * with MERGE the individual actions do not require separate planning, - * only different handling in the executor. See nodeModifyTable handling - * of commandType CMD_MERGE. - * - * A sub-query can include the Target, but otherwise the sub-query cannot - * reference the outermost Target table at all. - */ - qry->querySource = QSRC_PARSER; - - /* - * Setup the target table. Unlike regular UPDATE/DELETE, we don't expand - * inheritance for the target relation in case of MERGE. - * - * This special arrangement is required for handling partitioned tables - * because we perform an JOIN between the target and the source relation to - * identify the matching and not-matching rows. If we take the usual path - * of expanding the target table's inheritance and create one subplan per - * partition, then we we won't be able to correctly identify the matching - * and not-matching rows since for a given source row, there may not be a - * matching row in one partition, but it may exists in some other - * partition. So we must first append all the qualifying rows from all the - * partitions and then do the matching. - * - * Once a target row is returned by the underlying join, we find the - * correct partition and setup required state to carry out UPDATE/DELETE. - * All of this happens during execution. - */ - qry->resultRelation = setTargetTable(pstate, stmt->relation, - false, /* do not expand inheritance */ - true, targetPerms); - - /* - * Create a JOIN between the target and the source relation. - */ - joinexpr = makeNode(JoinExpr); - joinexpr->isNatural = false; - joinexpr->alias = NULL; - joinexpr->usingClause = NIL; - joinexpr->quals = stmt->join_condition; - joinexpr->larg = (Node *) stmt->relation; - joinexpr->rarg = (Node *) stmt->source_relation; - - /* - * Simplify the MERGE query as much as possible - * - * These seem like things that could go into Optimizer, but they are - * semantic simplifications rather than optimizations, per se. - * - * If there are no INSERT actions we won't be using the non-matching - * candidate rows for anything, so no need for an outer join. We do still - * need an inner join for UPDATE and DELETE actions. - */ - if (targetPerms & ACL_INSERT) - joinexpr->jointype = JOIN_RIGHT; - else - joinexpr->jointype = JOIN_INNER; - - /* - * We use a special purpose transformation here because the normal - * routines don't quite work right for the MERGE case. - * - * A special mergeSourceTargetList is setup by transformMergeJoinClause(). - * It refers to all the attributes provided by the source relation. This - * is later used by set_plan_refs() to fix the UPDATE/INSERT target lists - * to so that they can correctly fetch the attributes from the source - * relation. - * - * The target relation when used in the underlying join, gets a new RTE - * with rte->inh set to true. We remember this RTE (and later pass on to - * the planner and executor) for two main reasons: - * - * 1. If we ever need to run EvalPlanQual while performing MERGE, we must - * make the modified tuple available to the underlying join query, which is - * using a different RTE from the resultRelation RTE. - * - * 2. rewriteTargetListMerge() requires the RTE of the underlying join in - * order to add junk CTID and TABLEOID attributes. - */ - qry->mergeTarget_relation = transformMergeJoinClause(pstate, (Node *) joinexpr, - &qry->mergeSourceTargetList); - - /* - * The target table referenced in the MERGE is looked up twice; once while - * setting it up as the result relation and again when it's used in the - * underlying the join query. In some rare situations, it may happen that - * these lookups return different results, for example, if a new relation - * with the same name gets created in a schema which is ahead in the - * search_path, in between the two lookups. - * - * It's a very narrow case, but nevertheless we guard against it by simply - * checking if the OIDs returned by the two lookups is the same. If not, we - * just throw an error. - */ - Assert(qry->resultRelation > 0); - Assert(qry->mergeTarget_relation > 0); - - /* Fetch both the RTEs */ - resultRelRTE = rt_fetch(qry->resultRelation, pstate->p_rtable); - mergeRelRTE = rt_fetch(qry->mergeTarget_relation, pstate->p_rtable); - - if (resultRelRTE->relid != mergeRelRTE->relid) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("relation referenced by MERGE statement has changed"))); - - /* - * This query should just provide the source relation columns. Later, in - * preprocess_targetlist(), we shall also add "ctid" attribute of the - * target relation to ensure that the target tuple can be fetched - * correctly. - */ - qry->targetList = qry->mergeSourceTargetList; - - /* qry has no WHERE clause so absent quals are shown as NULL */ - qry->jointree = makeFromExpr(pstate->p_joinlist, NULL); - qry->rtable = pstate->p_rtable; - - /* - * XXX MERGE is unsupported in various cases - */ - if (!(pstate->p_target_relation->rd_rel->relkind == RELKIND_RELATION || - pstate->p_target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MERGE is not supported for this relation type"))); - - if (pstate->p_target_relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE && - pstate->p_target_relation->rd_rel->relhassubclass) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MERGE is not supported for relations with inheritance"))); - - if (pstate->p_target_relation->rd_rel->relhasrules) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MERGE is not supported for relations with rules"))); - - /* - * We now have a good query shape, so now look at the when conditions and - * action targetlists. - * - * Overall, the MERGE Query's targetlist is NIL. - * - * Each individual action has its own targetlist that needs separate - * transformation. These transforms don't do anything to the overall - * targetlist, since that is only used for resjunk columns. - * - * We can reference any column in Target or Source, which is OK because - * both of those already have RTEs. There is nothing like the EXCLUDED - * pseudo-relation for INSERT ON CONFLICT. - */ - mergeActionList = NIL; - foreach(l, stmt->mergeWhenClauses) - { - MergeWhenClause *mergeWhenClause = (MergeWhenClause *) lfirst(l); - MergeAction *action = makeNode(MergeAction); - - action->commandType = mergeWhenClause->commandType; - action->matched = mergeWhenClause->matched; - - /* - * Set namespace for the specific action. This must be done before - * analyzing the WHEN quals and the action targetlisst. - */ - setNamespaceForMergeWhen(pstate, mergeWhenClause); - - /* - * Transform the when condition. - * - * Note that these quals are NOT added to the join quals; instead they - * are evaluated separately during execution to decide which of the - * WHEN MATCHED or WHEN NOT MATCHED actions to execute. - */ - action->qual = transformWhereClause(pstate, mergeWhenClause->condition, - EXPR_KIND_MERGE_WHEN_AND, "WHEN"); - - /* - * Transform target lists for each INSERT and UPDATE action stmt - */ - switch (action->commandType) - { - case CMD_INSERT: - { - List *exprList = NIL; - ListCell *lc; - RangeTblEntry *rte; - ListCell *icols; - ListCell *attnos; - List *icolumns; - List *attrnos; - - pstate->p_is_insert = true; - - icolumns = checkInsertTargets(pstate, - mergeWhenClause->cols, - &attrnos); - Assert(list_length(icolumns) == list_length(attrnos)); - - action->override = mergeWhenClause->override; - - /* - * Handle INSERT much like in transformInsertStmt - */ - if (mergeWhenClause->values == NIL) - { - /* - * We have INSERT ... DEFAULT VALUES. We can handle - * this case by emitting an empty targetlist --- all - * columns will be defaulted when the planner expands - * the targetlist. - */ - exprList = NIL; - } - else - { - /* - * Process INSERT ... VALUES with a single VALUES - * sublist. We treat this case separately for - * efficiency. The sublist is just computed directly - * as the Query's targetlist, with no VALUES RTE. So - * it works just like a SELECT without any FROM. - */ - - /* - * Do basic expression transformation (same as a ROW() - * expr, but allow SetToDefault at top level) - */ - exprList = transformExpressionList(pstate, - mergeWhenClause->values, - EXPR_KIND_VALUES_SINGLE, - true); - - /* Prepare row for assignment to target table */ - exprList = transformInsertRow(pstate, exprList, - mergeWhenClause->cols, - icolumns, attrnos, - false); - } - - /* - * Generate action's target list using the computed list - * of expressions. Also, mark all the target columns as - * needing insert permissions. - */ - rte = pstate->p_target_rangetblentry; - icols = list_head(icolumns); - attnos = list_head(attrnos); - foreach(lc, exprList) - { - Expr *expr = (Expr *) lfirst(lc); - ResTarget *col; - AttrNumber attr_num; - TargetEntry *tle; - - col = lfirst_node(ResTarget, icols); - attr_num = (AttrNumber) lfirst_int(attnos); - - tle = makeTargetEntry(expr, - attr_num, - col->name, - false); - action->targetList = lappend(action->targetList, tle); - - rte->insertedCols = bms_add_member(rte->insertedCols, - attr_num - FirstLowInvalidHeapAttributeNumber); - - icols = lnext(icols); - attnos = lnext(attnos); - } - } - break; - case CMD_UPDATE: - { - pstate->p_is_insert = false; - action->targetList = transformUpdateTargetList(pstate, - mergeWhenClause->targetList); - } - break; - case CMD_DELETE: - break; - - case CMD_NOTHING: - action->targetList = NIL; - break; - default: - elog(ERROR, "unknown action in MERGE WHEN clause"); - } - - mergeActionList = lappend(mergeActionList, action); - } - - qry->mergeActionList = mergeActionList; - - /* XXX maybe later */ - qry->returningList = NULL; - - qry->hasTargetSRFs = false; - qry->hasSubLinks = pstate->p_hasSubLinks; - - assign_query_collations(pstate, qry); - - return qry; -} - -static void -setNamespaceVisibilityForRTE(List *namespace, RangeTblEntry *rte, - bool rel_visible, - bool cols_visible) -{ - ListCell *lc; - - foreach(lc, namespace) - { - ParseNamespaceItem *nsitem = (ParseNamespaceItem *) lfirst(lc); - - if (nsitem->p_rte == rte) - { - nsitem->p_rel_visible = rel_visible; - nsitem->p_cols_visible = cols_visible; - break; - } - } - -} - -/* - * Expand the source relation to include all attributes of this RTE. - * - * This function is very similar to expandRelAttrs except that we don't mark - * columns for SELECT privileges. That will be decided later when we transform - * the action targetlists and the WHEN quals for actual references to the - * source relation. - */ -static List * -expandSourceTL(ParseState *pstate, RangeTblEntry *rte, int rtindex) -{ - List *names, - *vars; - ListCell *name, - *var; - List *te_list = NIL; - - expandRTE(rte, rtindex, 0, -1, false, &names, &vars); - - /* - * Require read access to the table. - */ - rte->requiredPerms |= ACL_SELECT; - - forboth(name, names, var, vars) - { - char *label = strVal(lfirst(name)); - Var *varnode = (Var *) lfirst(var); - TargetEntry *te; - - te = makeTargetEntry((Expr *) varnode, - (AttrNumber) pstate->p_next_resno++, - label, - false); - te_list = lappend(te_list, te); - } - - Assert(name == NULL && var == NULL); /* lists not the same length? */ - - return te_list; -} diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c index d2672882d76..1baf7ef31f1 100644 --- a/src/backend/parser/parse_node.c +++ b/src/backend/parser/parse_node.c @@ -3,7 +3,7 @@ * parse_node.c * various routines that make nodes for querytrees * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,8 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/pg_type.h" #include "mb/pg_wchar.h" #include "nodes/makefuncs.h" @@ -88,7 +88,7 @@ free_parsestate(ParseState *pstate) MaxTupleAttributeNumber))); if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation, NoLock); + table_close(pstate->p_target_relation, NoLock); pfree(pstate); } @@ -203,121 +203,125 @@ make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, int location) } /* - * transformArrayType() - * Identify the types involved in a subscripting operation + * transformContainerType() + * Identify the types involved in a subscripting operation for container * - * On entry, arrayType/arrayTypmod identify the type of the input value - * to be subscripted (which could be a domain type). These are modified - * if necessary to identify the actual array type and typmod, and the - * array's element type is returned. An error is thrown if the input isn't + * + * On entry, containerType/containerTypmod identify the type of the input value + * to be subscripted (which could be a domain type). These are modified if + * necessary to identify the actual container type and typmod, and the + * container's element type is returned. An error is thrown if the input isn't * an array type. */ Oid -transformArrayType(Oid *arrayType, int32 *arrayTypmod) +transformContainerType(Oid *containerType, int32 *containerTypmod) { - Oid origArrayType = *arrayType; + Oid origContainerType = *containerType; Oid elementType; - HeapTuple type_tuple_array; - Form_pg_type type_struct_array; + HeapTuple type_tuple_container; + Form_pg_type type_struct_container; /* * If the input is a domain, smash to base type, and extract the actual - * typmod to be applied to the base type. Subscripting a domain is an - * operation that necessarily works on the base array type, not the domain - * itself. (Note that we provide no method whereby the creator of a - * domain over an array type could hide its ability to be subscripted.) + * typmod to be applied to the base type. Subscripting a domain is an + * operation that necessarily works on the base container type, not the + * domain itself. (Note that we provide no method whereby the creator of a + * domain over a container type could hide its ability to be subscripted.) */ - *arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod); + *containerType = getBaseTypeAndTypmod(*containerType, containerTypmod); /* - * We treat int2vector and oidvector as though they were domains over - * int2[] and oid[]. This is needed because array slicing could create an - * array that doesn't satisfy the dimensionality constraints of the - * xxxvector type; so we want the result of a slice operation to be - * considered to be of the more general type. + * Here is an array specific code. We treat int2vector and oidvector as + * though they were domains over int2[] and oid[]. This is needed because + * array slicing could create an array that doesn't satisfy the + * dimensionality constraints of the xxxvector type; so we want the result + * of a slice operation to be considered to be of the more general type. */ - if (*arrayType == INT2VECTOROID) - *arrayType = INT2ARRAYOID; - else if (*arrayType == OIDVECTOROID) - *arrayType = OIDARRAYOID; + if (*containerType == INT2VECTOROID) + *containerType = INT2ARRAYOID; + else if (*containerType == OIDVECTOROID) + *containerType = OIDARRAYOID; - /* Get the type tuple for the array */ - type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType)); - if (!HeapTupleIsValid(type_tuple_array)) - elog(ERROR, "cache lookup failed for type %u", *arrayType); - type_struct_array = (Form_pg_type) GETSTRUCT(type_tuple_array); + /* Get the type tuple for the container */ + type_tuple_container = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*containerType)); + if (!HeapTupleIsValid(type_tuple_container)) + elog(ERROR, "cache lookup failed for type %u", *containerType); + type_struct_container = (Form_pg_type) GETSTRUCT(type_tuple_container); /* needn't check typisdefined since this will fail anyway */ - elementType = type_struct_array->typelem; + elementType = type_struct_container->typelem; if (elementType == InvalidOid) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("cannot subscript type %s because it is not an array", - format_type_be(origArrayType)))); + format_type_be(origContainerType)))); - ReleaseSysCache(type_tuple_array); + ReleaseSysCache(type_tuple_container); return elementType; } /* - * transformArraySubscripts() - * Transform array subscripting. This is used for both - * array fetch and array assignment. + * transformContainerSubscripts() + * Transform container (array, etc) subscripting. This is used for both + * container fetch and container assignment. * - * In an array fetch, we are given a source array value and we produce an - * expression that represents the result of extracting a single array element - * or an array slice. + * In a container fetch, we are given a source container value and we produce + * an expression that represents the result of extracting a single container + * element or a container slice. * - * In an array assignment, we are given a destination array value plus a - * source value that is to be assigned to a single element or a slice of - * that array. We produce an expression that represents the new array value - * with the source data inserted into the right part of the array. + * In a container assignment, we are given a destination container value plus a + * source value that is to be assigned to a single element or a slice of that + * container. We produce an expression that represents the new container value + * with the source data inserted into the right part of the container. * - * For both cases, if the source array is of a domain-over-array type, + * For both cases, if the source container is of a domain-over-array type, * the result is of the base array type or its element type; essentially, * we must fold a domain to its base type before applying subscripting. * (Note that int2vector and oidvector are treated as domains here.) * - * pstate Parse state - * arrayBase Already-transformed expression for the array as a whole - * arrayType OID of array's datatype (should match type of arrayBase, - * or be the base type of arrayBase's domain type) - * elementType OID of array's element type (fetch with transformArrayType, - * or pass InvalidOid to do it here) - * arrayTypMod typmod for the array (which is also typmod for the elements) - * indirection Untransformed list of subscripts (must not be NIL) - * assignFrom NULL for array fetch, else transformed expression for source. + * pstate Parse state + * containerBase Already-transformed expression for the container as a whole + * containerType OID of container's datatype (should match type of + * containerBase, or be the base type of containerBase's + * domain type) + * elementType OID of container's element type (fetch with + * transformContainerType, or pass InvalidOid to do it here) + * containerTypMod typmod for the container (which is also typmod for the + * elements) + * indirection Untransformed list of subscripts (must not be NIL) + * assignFrom NULL for container fetch, else transformed expression for + * source. */ -ArrayRef * -transformArraySubscripts(ParseState *pstate, - Node *arrayBase, - Oid arrayType, - Oid elementType, - int32 arrayTypMod, - List *indirection, - Node *assignFrom) +SubscriptingRef * +transformContainerSubscripts(ParseState *pstate, + Node *containerBase, + Oid containerType, + Oid elementType, + int32 containerTypMod, + List *indirection, + Node *assignFrom) { bool isSlice = false; List *upperIndexpr = NIL; List *lowerIndexpr = NIL; ListCell *idx; - ArrayRef *aref; + SubscriptingRef *sbsref; /* * Caller may or may not have bothered to determine elementType. Note - * that if the caller did do so, arrayType/arrayTypMod must be as modified - * by transformArrayType, ie, smash domain to base type. + * that if the caller did do so, containerType/containerTypMod must be as + * modified by transformContainerType, ie, smash domain to base type. */ if (!OidIsValid(elementType)) - elementType = transformArrayType(&arrayType, &arrayTypMod); + elementType = transformContainerType(&containerType, &containerTypMod); /* - * A list containing only simple subscripts refers to a single array + * A list containing only simple subscripts refers to a single container * element. If any of the items are slice specifiers (lower:upper), then - * the subscript expression means an array slice operation. In this case, - * we convert any non-slice items to slices by treating the single + * the subscript expression means a container slice operation. In this + * case, we convert any non-slice items to slices by treating the single * subscript as the upper bound and supplying an assumed lower bound of 1. * We have to prescan the list to see if there are any slice items. */ @@ -411,12 +415,12 @@ transformArraySubscripts(ParseState *pstate, if (assignFrom != NULL) { Oid typesource = exprType(assignFrom); - Oid typeneeded = isSlice ? arrayType : elementType; + Oid typeneeded = isSlice ? containerType : elementType; Node *newFrom; newFrom = coerce_to_target_type(pstate, assignFrom, typesource, - typeneeded, arrayTypMod, + typeneeded, containerTypMod, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); @@ -433,19 +437,22 @@ transformArraySubscripts(ParseState *pstate, } /* - * Ready to build the ArrayRef node. + * Ready to build the SubscriptingRef node. */ - aref = makeNode(ArrayRef); - aref->refarraytype = arrayType; - aref->refelemtype = elementType; - aref->reftypmod = arrayTypMod; + sbsref = (SubscriptingRef *) makeNode(SubscriptingRef); + if (assignFrom != NULL) + sbsref->refassgnexpr = (Expr *) assignFrom; + + sbsref->refcontainertype = containerType; + sbsref->refelemtype = elementType; + sbsref->reftypmod = containerTypMod; /* refcollid will be set by parse_collate.c */ - aref->refupperindexpr = upperIndexpr; - aref->reflowerindexpr = lowerIndexpr; - aref->refexpr = (Expr *) arrayBase; - aref->refassgnexpr = (Expr *) assignFrom; + sbsref->refupperindexpr = upperIndexpr; + sbsref->reflowerindexpr = lowerIndexpr; + sbsref->refexpr = (Expr *) containerBase; + sbsref->refassgnexpr = (Expr *) assignFrom; - return aref; + return sbsref; } /* diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c index b279e1236ad..20abbb3b55a 100644 --- a/src/backend/parser/parse_oper.c +++ b/src/backend/parser/parse_oper.c @@ -3,7 +3,7 @@ * parse_oper.c * handle operator things for parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -67,17 +67,17 @@ typedef struct OprCacheEntry static Oid binary_oper_exact(List *opname, Oid arg1, Oid arg2); static FuncDetailCode oper_select_candidate(int nargs, - Oid *input_typeids, - FuncCandidateList candidates, - Oid *operOid); + Oid *input_typeids, + FuncCandidateList candidates, + Oid *operOid); static const char *op_signature_string(List *op, char oprkind, - Oid arg1, Oid arg2); + Oid arg1, Oid arg2); static void op_error(ParseState *pstate, List *op, char oprkind, - Oid arg1, Oid arg2, - FuncDetailCode fdresult, int location); + Oid arg1, Oid arg2, + FuncDetailCode fdresult, int location); static bool make_oper_cache_key(ParseState *pstate, OprCacheKey *key, - List *opname, Oid ltypeId, Oid rtypeId, - int location); + List *opname, Oid ltypeId, Oid rtypeId, + int location); static Oid find_oper_cache_entry(OprCacheKey *key); static void make_oper_cache_entry(OprCacheKey *key, Oid opr_oid); static void InvalidateOprCacheCallBack(Datum arg, int cacheid, uint32 hashvalue); @@ -134,7 +134,7 @@ LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright, /* * LookupOperWithArgs * Like LookupOperName, but the argument types are specified by - * a ObjectWithArg node. + * a ObjectWithArgs node. */ Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError) @@ -244,7 +244,7 @@ get_sort_group_operators(Oid argtype, Oid oprid(Operator op) { - return HeapTupleGetOid(op); + return ((Form_pg_operator) GETSTRUCT(op))->oid; } /* given operator tuple, return the underlying function's OID */ diff --git a/src/backend/parser/parse_param.c b/src/backend/parser/parse_param.c index 454a3e07f75..38915fbce19 100644 --- a/src/backend/parser/parse_param.c +++ b/src/backend/parser/parse_param.c @@ -12,7 +12,7 @@ * Note that other approaches to parameters are possible using the parser * hooks defined in ParseState. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,8 +54,8 @@ typedef struct VarParamState static Node *fixed_paramref_hook(ParseState *pstate, ParamRef *pref); static Node *variable_paramref_hook(ParseState *pstate, ParamRef *pref); static Node *variable_coerce_param_hook(ParseState *pstate, Param *param, - Oid targetTypeId, int32 targetTypeMod, - int location); + Oid targetTypeId, int32 targetTypeMod, + int location); static bool check_parameter_resolution_walker(Node *node, ParseState *pstate); static bool query_contains_extern_params_walker(Node *node, void *context); diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 8b912eeea31..4dd81507a78 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -3,7 +3,7 @@ * parse_relation.c * parser support routines dealing with relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,7 +17,9 @@ #include #include "access/htup_details.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/heap.h" #include "catalog/namespace.h" #include "catalog/pg_type.h" @@ -28,6 +30,7 @@ #include "parser/parse_enr.h" #include "parser/parse_relation.h" #include "parser/parse_type.h" +#include "storage/lmgr.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/rel.h" @@ -38,22 +41,22 @@ #define MAX_FUZZY_DISTANCE 3 static RangeTblEntry *scanNameSpaceForRefname(ParseState *pstate, - const char *refname, int location); + const char *refname, int location); static RangeTblEntry *scanNameSpaceForRelid(ParseState *pstate, Oid relid, - int location); + int location); static void check_lateral_ref_ok(ParseState *pstate, ParseNamespaceItem *nsitem, - int location); + int location); static void markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte, - int rtindex, AttrNumber col); + int rtindex, AttrNumber col); static void expandRelation(Oid relid, Alias *eref, - int rtindex, int sublevels_up, - int location, bool include_dropped, - List **colnames, List **colvars); + int rtindex, int sublevels_up, + int location, bool include_dropped, + List **colnames, List **colvars); static void expandTupleDesc(TupleDesc tupdesc, Alias *eref, - int count, int offset, - int rtindex, int sublevels_up, - int location, bool include_dropped, - List **colnames, List **colvars); + int count, int offset, + int rtindex, int sublevels_up, + int location, bool include_dropped, + List **colnames, List **colvars); static int specialAttNum(const char *attname); static bool isQueryUsingTempRelation_walker(Node *node, void *context); @@ -728,13 +731,14 @@ scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, const char *colname, colname), parser_errposition(pstate, location))); - /* In MERGE WHEN AND condition, no system column is allowed except tableOid or OID */ - if (pstate->p_expr_kind == EXPR_KIND_MERGE_WHEN_AND && - attnum < InvalidAttrNumber && - !(attnum == TableOidAttributeNumber || attnum == ObjectIdAttributeNumber)) + /* + * In generated column, no system column is allowed except tableOid. + */ + if (pstate->p_expr_kind == EXPR_KIND_GENERATED_COLUMN && + attnum < InvalidAttrNumber && attnum != TableOidAttributeNumber) ereport(ERROR, (errcode(ERRCODE_INVALID_COLUMN_REFERENCE), - errmsg("system column \"%s\" reference in WHEN AND condition is invalid", + errmsg("cannot use system column \"%s\" in column generation expression", colname), parser_errposition(pstate, location))); @@ -1040,6 +1044,7 @@ static void buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref) { int maxattrs = tupdesc->natts; + List *aliaslist; ListCell *aliaslc; int numaliases; int varattno; @@ -1049,13 +1054,15 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref) if (alias) { - aliaslc = list_head(alias->colnames); - numaliases = list_length(alias->colnames); + aliaslist = alias->colnames; + aliaslc = list_head(aliaslist); + numaliases = list_length(aliaslist); /* We'll rebuild the alias colname list */ alias->colnames = NIL; } else { + aliaslist = NIL; aliaslc = NULL; numaliases = 0; } @@ -1077,7 +1084,7 @@ buildRelationAliases(TupleDesc tupdesc, Alias *alias, Alias *eref) { /* Use the next user-supplied alias */ attrname = (Value *) lfirst(aliaslc); - aliaslc = lnext(aliaslc); + aliaslc = lnext(aliaslist, aliaslc); alias->colnames = lappend(alias->colnames, attrname); } else @@ -1144,7 +1151,7 @@ chooseScalarFunctionAlias(Node *funcexpr, char *funcname, /* * Open a table during parse analysis * - * This is essentially just the same as heap_openrv(), except that it caters + * This is essentially just the same as table_openrv(), except that it caters * to some parser-specific error reporting needs, notably that it arranges * to include the RangeVar's parse location in any resulting error. * @@ -1159,7 +1166,7 @@ parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode) ParseCallbackState pcbstate; setup_parser_errposition_callback(&pcbstate, pstate, relation->location); - rel = heap_openrv_extended(relation, lockmode, true); + rel = table_openrv_extended(relation, lockmode, true); if (rel == NULL) { if (relation->schemaname) @@ -1217,16 +1224,23 @@ addRangeTableEntry(ParseState *pstate, rte->rtekind = RTE_RELATION; rte->alias = alias; + /* + * Identify the type of lock we'll need on this relation. It's not the + * query's target table (that case is handled elsewhere), so we need + * either RowShareLock if it's locked by FOR UPDATE/SHARE, or plain + * AccessShareLock otherwise. + */ + lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock; + /* * Get the rel's OID. This access also ensures that we have an up-to-date * relcache entry for the rel. Since this is typically the first access - * to a rel in a statement, be careful to get the right access level - * depending on whether we're doing SELECT FOR UPDATE/SHARE. + * to a rel in a statement, we must open the rel with the proper lockmode. */ - lockmode = isLockedRefname(pstate, refname) ? RowShareLock : AccessShareLock; rel = parserOpenTable(pstate, relation, lockmode); rte->relid = RelationGetRelid(rel); rte->relkind = rel->rd_rel->relkind; + rte->rellockmode = lockmode; /* * Build the list of effective column names using user-supplied aliases @@ -1240,7 +1254,7 @@ addRangeTableEntry(ParseState *pstate, * so that the table can't be deleted or have its schema modified * underneath us. */ - heap_close(rel, NoLock); + table_close(rel, NoLock); /* * Set flags and access permissions. @@ -1257,6 +1271,7 @@ addRangeTableEntry(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1272,10 +1287,20 @@ addRangeTableEntry(ParseState *pstate, * * This is just like addRangeTableEntry() except that it makes an RTE * given an already-open relation instead of a RangeVar reference. + * + * lockmode is the lock type required for query execution; it must be one + * of AccessShareLock, RowShareLock, or RowExclusiveLock depending on the + * RTE's role within the query. The caller must hold that lock mode + * or a stronger one. + * + * Note: properly, lockmode should be declared LOCKMODE not int, but that + * would require importing storage/lock.h into parse_relation.h. Since + * LOCKMODE is typedef'd as int anyway, that seems like overkill. */ RangeTblEntry * addRangeTableEntryForRelation(ParseState *pstate, Relation rel, + int lockmode, Alias *alias, bool inh, bool inFromCl) @@ -1285,10 +1310,16 @@ addRangeTableEntryForRelation(ParseState *pstate, Assert(pstate != NULL); + Assert(lockmode == AccessShareLock || + lockmode == RowShareLock || + lockmode == RowExclusiveLock); + Assert(CheckRelationLockedByMe(rel, lockmode, true)); + rte->rtekind = RTE_RELATION; rte->alias = alias; rte->relid = RelationGetRelid(rel); rte->relkind = rel->rd_rel->relkind; + rte->rellockmode = lockmode; /* * Build the list of effective column names using user-supplied aliases @@ -1312,6 +1343,7 @@ addRangeTableEntryForRelation(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1345,7 +1377,6 @@ addRangeTableEntryForSubquery(ParseState *pstate, Assert(pstate != NULL); rte->rtekind = RTE_SUBQUERY; - rte->relid = InvalidOid; rte->subquery = subquery; rte->alias = alias; @@ -1392,6 +1423,7 @@ addRangeTableEntryForSubquery(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1515,7 +1547,7 @@ addRangeTableEntryForFunction(ParseState *pstate, else if (functypclass == TYPEFUNC_SCALAR) { /* Base data type, i.e. scalar */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, chooseScalarFunctionAlias(funcexpr, funcname, @@ -1532,7 +1564,7 @@ addRangeTableEntryForFunction(ParseState *pstate, * Use the column definition list to construct a tupdesc and fill * in the RangeTblFunction's lists. */ - tupdesc = CreateTemplateTupleDesc(list_length(coldeflist), false); + tupdesc = CreateTemplateTupleDesc(list_length(coldeflist)); i = 1; foreach(col, coldeflist) { @@ -1575,9 +1607,15 @@ addRangeTableEntryForFunction(ParseState *pstate, /* * Ensure that the coldeflist defines a legal set of names (no - * duplicates) and datatypes (no pseudo-types, for instance). + * duplicates, but we needn't worry about system column names) and + * datatypes. Although we mostly can't allow pseudo-types, it + * seems safe to allow RECORD and RECORD[], since values within + * those type classes are self-identifying at runtime, and the + * coldeflist doesn't represent anything that will be visible to + * other sessions. */ - CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE, false); + CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE, + CHKATYPE_ANYRECORD); } else ereport(ERROR, @@ -1606,7 +1644,7 @@ addRangeTableEntryForFunction(ParseState *pstate, totalatts++; /* Merge the tuple descs of each function into a composite one */ - tupdesc = CreateTemplateTupleDesc(totalatts, false); + tupdesc = CreateTemplateTupleDesc(totalatts); natts = 0; for (i = 0; i < nfuncs; i++) { @@ -1649,6 +1687,7 @@ addRangeTableEntryForFunction(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1712,6 +1751,7 @@ addRangeTableEntryForTableFunc(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1790,6 +1830,7 @@ addRangeTableEntryForValues(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1860,6 +1901,7 @@ addRangeTableEntryForJoin(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -1962,6 +2004,7 @@ addRangeTableEntryForCTE(ParseState *pstate, rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; + rte->extraUpdatedCols = NULL; /* * Add completed RTE to pstate's range table list, but not to join list @@ -2247,7 +2290,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, *colvars = lappend(*colvars, varnode); } - aliasp_item = lnext(aliasp_item); + aliasp_item = lnext(rte->eref->colnames, aliasp_item); } } break; @@ -2474,7 +2517,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, *colnames = lappend(*colnames, makeString(pstrdup(""))); - aliasp_item = lnext(aliasp_item); + aliasp_item = lnext(rte->eref->colnames, aliasp_item); } if (colvars) @@ -2504,6 +2547,9 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, } } break; + case RTE_RESULT: + /* These expose no columns, so nothing to do */ + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); } @@ -2543,19 +2589,11 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, int location, bool include_dropped, List **colnames, List **colvars) { - ListCell *aliascell = list_head(eref->colnames); + ListCell *aliascell; int varattno; - if (colnames) - { - int i; - - for (i = 0; i < offset; i++) - { - if (aliascell) - aliascell = lnext(aliascell); - } - } + aliascell = (offset < list_length(eref->colnames)) ? + list_nth_cell(eref->colnames, offset) : NULL; Assert(count <= tupdesc->natts); for (varattno = 0; varattno < count; varattno++) @@ -2579,7 +2617,7 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, } } if (aliascell) - aliascell = lnext(aliascell); + aliascell = lnext(eref->colnames, aliascell); continue; } @@ -2590,7 +2628,7 @@ expandTupleDesc(TupleDesc tupdesc, Alias *eref, int count, int offset, if (aliascell) { label = strVal(lfirst(aliascell)); - aliascell = lnext(aliascell); + aliascell = lnext(eref->colnames, aliascell); } else { @@ -2896,6 +2934,14 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, rte->eref->aliasname))); } break; + case RTE_RESULT: + /* this probably can't happen ... */ + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column %d of relation \"%s\" does not exist", + attnum, + rte->eref->aliasname))); + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); } @@ -3024,6 +3070,15 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum) result = false; /* keep compiler quiet */ } break; + case RTE_RESULT: + /* this probably can't happen ... */ + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column %d of relation \"%s\" does not exist", + attnum, + rte->eref->aliasname))); + result = false; /* keep compiler quiet */ + break; default: elog(ERROR, "unrecognized RTE kind: %d", (int) rte->rtekind); result = false; /* keep compiler quiet */ @@ -3081,7 +3136,7 @@ get_parse_rowmark(Query *qry, Index rtindex) * Returns InvalidAttrNumber if the attr doesn't exist (or is dropped). * * This should only be used if the relation is already - * heap_open()'ed. Use the cache version get_attnum() + * table_open()'ed. Use the cache version get_attnum() * for access to non-opened relations. */ int @@ -3100,10 +3155,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK) if (sysColOK) { if ((i = specialAttNum(attname)) != InvalidAttrNumber) - { - if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids) - return i; - } + return i; } /* on failure */ @@ -3112,20 +3164,18 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK) /* specialAttNum() * - * Check attribute name to see if it is "special", e.g. "oid". + * Check attribute name to see if it is "special", e.g. "xmin". * - thomas 2000-02-07 * * Note: this only discovers whether the name could be a system attribute. - * Caller needs to verify that it really is an attribute of the rel, - * at least in the case of "oid", which is now optional. + * Caller needs to ensure that it really is an attribute of the rel. */ static int specialAttNum(const char *attname) { - Form_pg_attribute sysatt; + const FormData_pg_attribute *sysatt; - sysatt = SystemAttributeByName(attname, - true /* "oid" will be accepted */ ); + sysatt = SystemAttributeByName(attname); if (sysatt != NULL) return sysatt->attnum; return InvalidAttrNumber; @@ -3136,17 +3186,17 @@ specialAttNum(const char *attname) * given attribute id, return name of that attribute * * This should only be used if the relation is already - * heap_open()'ed. Use the cache version get_atttype() + * table_open()'ed. Use the cache version get_atttype() * for access to non-opened relations. */ -Name +const NameData * attnumAttName(Relation rd, int attid) { if (attid <= 0) { - Form_pg_attribute sysatt; + const FormData_pg_attribute *sysatt; - sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids); + sysatt = SystemAttributeDefinition(attid); return &sysatt->attname; } if (attid > rd->rd_att->natts) @@ -3158,7 +3208,7 @@ attnumAttName(Relation rd, int attid) * given attribute id, return type of that attribute * * This should only be used if the relation is already - * heap_open()'ed. Use the cache version get_atttype() + * table_open()'ed. Use the cache version get_atttype() * for access to non-opened relations. */ Oid @@ -3166,9 +3216,9 @@ attnumTypeId(Relation rd, int attid) { if (attid <= 0) { - Form_pg_attribute sysatt; + const FormData_pg_attribute *sysatt; - sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids); + sysatt = SystemAttributeDefinition(attid); return sysatt->atttypid; } if (attid > rd->rd_att->natts) @@ -3179,7 +3229,7 @@ attnumTypeId(Relation rd, int attid) /* * given attribute id, return collation of that attribute * - * This should only be used if the relation is already heap_open()'ed. + * This should only be used if the relation is already table_open()'ed. */ Oid attnumCollationId(Relation rd, int attid) @@ -3351,10 +3401,10 @@ isQueryUsingTempRelation_walker(Node *node, void *context) if (rte->rtekind == RTE_RELATION) { - Relation rel = heap_open(rte->relid, AccessShareLock); + Relation rel = table_open(rte->relid, AccessShareLock); char relpersistence = rel->rd_rel->relpersistence; - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); if (relpersistence == RELPERSISTENCE_TEMP) return true; } diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 4932e58022b..29010250151 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -3,7 +3,7 @@ * parse_target.c * handle target lists * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -34,37 +34,39 @@ static void markTargetListOrigin(ParseState *pstate, TargetEntry *tle, - Var *var, int levelsup); + Var *var, int levelsup); static Node *transformAssignmentIndirection(ParseState *pstate, - Node *basenode, - const char *targetName, - bool targetIsArray, - Oid targetTypeId, - int32 targetTypMod, - Oid targetCollation, - ListCell *indirection, - Node *rhs, - int location); + Node *basenode, + const char *targetName, + bool targetIsSubscripting, + Oid targetTypeId, + int32 targetTypMod, + Oid targetCollation, + List *indirection, + ListCell *indirection_cell, + Node *rhs, + int location); static Node *transformAssignmentSubscripts(ParseState *pstate, - Node *basenode, - const char *targetName, - Oid targetTypeId, - int32 targetTypMod, - Oid targetCollation, - List *subscripts, - bool isSlice, - ListCell *next_indirection, - Node *rhs, - int location); + Node *basenode, + const char *targetName, + Oid targetTypeId, + int32 targetTypMod, + Oid targetCollation, + List *subscripts, + bool isSlice, + List *indirection, + ListCell *next_indirection, + Node *rhs, + int location); static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref, - bool make_target_entry); + bool make_target_entry); static List *ExpandAllTables(ParseState *pstate, int location); static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind, - bool make_target_entry, ParseExprKind exprKind); + bool make_target_entry, ParseExprKind exprKind); static List *ExpandSingleTable(ParseState *pstate, RangeTblEntry *rte, - int location, bool make_target_entry); + int location, bool make_target_entry); static List *ExpandRowReference(ParseState *pstate, Node *expr, - bool make_target_entry); + bool make_target_entry); static int FigureColnameInternal(Node *node, char **name); @@ -398,6 +400,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle, case RTE_VALUES: case RTE_TABLEFUNC: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* not a simple relation, leave it unmarked */ break; case RTE_CTE: @@ -560,6 +563,7 @@ transformAssignedExpr(ParseState *pstate, attrtype, attrtypmod, attrcollation, + indirection, list_head(indirection), (Node *) expr, location); @@ -654,15 +658,16 @@ updateTargetListEntry(ParseState *pstate, * needed. * * targetName is the name of the field or subfield we're assigning to, and - * targetIsArray is true if we're subscripting it. These are just for + * targetIsSubscripting is true if we're subscripting it. These are just for * error reporting. * * targetTypeId, targetTypMod, targetCollation indicate the datatype and * collation of the object to be assigned to (initially the target column, * later some subobject). * - * indirection is the sublist remaining to process. When it's NULL, we're - * done recursing and can just coerce and return the RHS. + * indirection is the list of indirection nodes, and indirection_cell is the + * start of the sublist remaining to process. When it's NULL, we're done + * recursing and can just coerce and return the RHS. * * rhs is the already-transformed value to be assigned; note it has not been * coerced to any particular type. @@ -676,11 +681,12 @@ static Node * transformAssignmentIndirection(ParseState *pstate, Node *basenode, const char *targetName, - bool targetIsArray, + bool targetIsSubscripting, Oid targetTypeId, int32 targetTypMod, Oid targetCollation, - ListCell *indirection, + List *indirection, + ListCell *indirection_cell, Node *rhs, int location) { @@ -689,9 +695,15 @@ transformAssignmentIndirection(ParseState *pstate, bool isSlice = false; ListCell *i; - if (indirection && !basenode) + if (indirection_cell && !basenode) { - /* Set up a substitution. We reuse CaseTestExpr for this. */ + /* + * Set up a substitution. We abuse CaseTestExpr for this. It's safe + * to do so because the only nodes that will be above the CaseTestExpr + * in the finished expression will be FieldStore and SubscriptingRef + * nodes. (There could be other stuff in the tree, but it will be + * within other child fields of those node types.) + */ CaseTestExpr *ctest = makeNode(CaseTestExpr); ctest->typeId = targetTypeId; @@ -705,7 +717,7 @@ transformAssignmentIndirection(ParseState *pstate, * subscripting. Adjacent A_Indices nodes have to be treated as a single * multidimensional subscript operation. */ - for_each_cell(i, indirection) + for_each_cell(i, indirection, indirection_cell) { Node *n = lfirst(i); @@ -747,6 +759,7 @@ transformAssignmentIndirection(ParseState *pstate, targetCollation, subscripts, isSlice, + indirection, i, rhs, location); @@ -796,7 +809,8 @@ transformAssignmentIndirection(ParseState *pstate, fieldTypeId, fieldTypMod, fieldCollation, - lnext(i), + indirection, + lnext(indirection, i), rhs, location); @@ -833,6 +847,7 @@ transformAssignmentIndirection(ParseState *pstate, targetCollation, subscripts, isSlice, + indirection, NULL, rhs, location); @@ -848,7 +863,7 @@ transformAssignmentIndirection(ParseState *pstate, -1); if (result == NULL) { - if (targetIsArray) + if (targetIsSubscripting) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("array assignment to \"%s\" requires type %s" @@ -874,7 +889,7 @@ transformAssignmentIndirection(ParseState *pstate, } /* - * helper for transformAssignmentIndirection: process array assignment + * helper for transformAssignmentIndirection: process container assignment */ static Node * transformAssignmentSubscripts(ParseState *pstate, @@ -885,13 +900,14 @@ transformAssignmentSubscripts(ParseState *pstate, Oid targetCollation, List *subscripts, bool isSlice, + List *indirection, ListCell *next_indirection, Node *rhs, int location) { Node *result; - Oid arrayType; - int32 arrayTypMod; + Oid containerType; + int32 containerTypMod; Oid elementTypeId; Oid typeNeeded; Oid collationNeeded; @@ -899,46 +915,47 @@ transformAssignmentSubscripts(ParseState *pstate, Assert(subscripts != NIL); /* Identify the actual array type and element type involved */ - arrayType = targetTypeId; - arrayTypMod = targetTypMod; - elementTypeId = transformArrayType(&arrayType, &arrayTypMod); + containerType = targetTypeId; + containerTypMod = targetTypMod; + elementTypeId = transformContainerType(&containerType, &containerTypMod); /* Identify type that RHS must provide */ - typeNeeded = isSlice ? arrayType : elementTypeId; + typeNeeded = isSlice ? containerType : elementTypeId; /* - * Array normally has same collation as elements, but there's an - * exception: we might be subscripting a domain over an array type. In + * container normally has same collation as elements, but there's an + * exception: we might be subscripting a domain over a container type. In * that case use collation of the base type. */ - if (arrayType == targetTypeId) + if (containerType == targetTypeId) collationNeeded = targetCollation; else - collationNeeded = get_typcollation(arrayType); + collationNeeded = get_typcollation(containerType); - /* recurse to create appropriate RHS for array assign */ + /* recurse to create appropriate RHS for container assign */ rhs = transformAssignmentIndirection(pstate, NULL, targetName, true, typeNeeded, - arrayTypMod, + containerTypMod, collationNeeded, + indirection, next_indirection, rhs, location); /* process subscripts */ - result = (Node *) transformArraySubscripts(pstate, - basenode, - arrayType, - elementTypeId, - arrayTypMod, - subscripts, - rhs); - - /* If target was a domain over array, need to coerce up to the domain */ - if (arrayType != targetTypeId) + result = (Node *) transformContainerSubscripts(pstate, + basenode, + containerType, + elementTypeId, + containerTypMod, + subscripts, + rhs); + + /* If target was a domain over container, need to coerce up to the domain */ + if (containerType != targetTypeId) { Oid resulttype = exprType(result); @@ -1497,7 +1514,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup) expandRTE(rte, var->varno, 0, var->location, false, &names, &vars); - tupleDesc = CreateTemplateTupleDesc(list_length(vars), false); + tupleDesc = CreateTemplateTupleDesc(list_length(vars)); i = 1; forboth(lname, names, lvar, vars) { @@ -1525,6 +1542,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup) case RTE_RELATION: case RTE_VALUES: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* * This case should not occur: a column of a table, values list, diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index d959b6122a5..7932a960983 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -3,7 +3,7 @@ * parse_type.c * handle type operations for parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,11 +28,23 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, - Type typ); + Type typ); /* * LookupTypeName + * Wrapper for typical case. + */ +Type +LookupTypeName(ParseState *pstate, const TypeName *typeName, + int32 *typmod_p, bool missing_ok) +{ + return LookupTypeNameExtended(pstate, + typeName, typmod_p, true, missing_ok); +} + +/* + * LookupTypeNameExtended * Given a TypeName object, lookup the pg_type syscache entry of the type. * Returns NULL if no such type can be found. If the type is found, * the typmod value represented in the TypeName struct is computed and @@ -51,11 +63,17 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName, * found but is a shell, and there is typmod decoration, an error will be * thrown --- this is intentional. * + * If temp_ok is false, ignore types in the temporary namespace. Pass false + * when the caller will decide, using goodness of fit criteria, whether the + * typeName is actually a type or something else. If typeName always denotes + * a type (or denotes nothing), pass true. + * * pstate is only used for error location info, and may be NULL. */ Type -LookupTypeName(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p, bool missing_ok) +LookupTypeNameExtended(ParseState *pstate, + const TypeName *typeName, int32 *typmod_p, + bool temp_ok, bool missing_ok) { Oid typoid; HeapTuple tup; @@ -161,7 +179,7 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, namespaceId = LookupExplicitNamespace(schemaname, missing_ok); if (OidIsValid(namespaceId)) - typoid = GetSysCacheOid2(TYPENAMENSP, + typoid = GetSysCacheOid2(TYPENAMENSP, Anum_pg_type_oid, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId)); else @@ -172,7 +190,7 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName, else { /* Unqualified type name, so search the search path */ - typoid = TypenameGetTypid(typname); + typoid = TypenameGetTypidExtended(typname, temp_ok); } /* If an array reference, return the array type instead */ @@ -230,7 +248,7 @@ LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok) return InvalidOid; } - typoid = HeapTupleGetOid(tup); + typoid = ((Form_pg_type) GETSTRUCT(tup))->oid; ReleaseSysCache(tup); return typoid; @@ -277,7 +295,7 @@ typenameTypeId(ParseState *pstate, const TypeName *typeName) Type tup; tup = typenameType(pstate, typeName, NULL); - typoid = HeapTupleGetOid(tup); + typoid = ((Form_pg_type) GETSTRUCT(tup))->oid; ReleaseSysCache(tup); return typoid; @@ -296,7 +314,7 @@ typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, Type tup; tup = typenameType(pstate, typeName, typmod_p); - *typeid_p = HeapTupleGetOid(tup); + *typeid_p = ((Form_pg_type) GETSTRUCT(tup))->oid; ReleaseSysCache(tup); } @@ -572,7 +590,7 @@ typeTypeId(Type tp) { if (tp == NULL) /* probably useless */ elog(ERROR, "typeTypeId() called with NULL type struct"); - return HeapTupleGetOid(tp); + return ((Form_pg_type) GETSTRUCT(tp))->oid; } /* given type (as type struct), return the length of type */ @@ -739,7 +757,7 @@ typeStringToTypeName(const char *str) * Setup error traceback support in case of ereport() during parse */ ptserrcontext.callback = pts_error_callback; - ptserrcontext.arg = (void *) str; + ptserrcontext.arg = unconstify(char *, str); ptserrcontext.previous = error_context_stack; error_context_stack = &ptserrcontext; @@ -832,13 +850,15 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok } else { - if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined) + Form_pg_type typ = (Form_pg_type) GETSTRUCT(tup); + + if (!typ->typisdefined) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" is only a shell", TypeNameToString(typeName)), parser_errposition(NULL, typeName->location))); - *typeid_p = HeapTupleGetOid(tup); + *typeid_p = typ->oid; ReleaseSysCache(tup); } } diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index f9f9904bad8..ee475476248 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -16,7 +16,7 @@ * a quick copyObject() call before manipulating the query tree. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/parser/parse_utilcmd.c @@ -28,7 +28,9 @@ #include "access/amapi.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/reloptions.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/heap.h" #include "catalog/index.h" @@ -48,7 +50,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parse_clause.h" #include "parser/parse_coerce.h" @@ -63,6 +65,7 @@ #include "utils/acl.h" #include "utils/builtins.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" #include "utils/rel.h" #include "utils/ruleutils.h" #include "utils/syscache.h" @@ -79,7 +82,6 @@ typedef struct List *inhRelations; /* relations to inherit from */ bool isforeign; /* true if CREATE/ALTER FOREIGN TABLE */ bool isalter; /* true if altering existing table */ - bool hasoids; /* does relation have an OID column? */ List *columns; /* ColumnDef items */ List *ckconstraints; /* CHECK constraints */ List *fkconstraints; /* FOREIGN KEY constraints */ @@ -112,34 +114,37 @@ typedef struct static void transformColumnDefinition(CreateStmtContext *cxt, - ColumnDef *column); + ColumnDef *column); static void transformTableConstraint(CreateStmtContext *cxt, - Constraint *constraint); + Constraint *constraint); static void transformTableLikeClause(CreateStmtContext *cxt, - TableLikeClause *table_like_clause); + TableLikeClause *table_like_clause); static void transformOfType(CreateStmtContext *cxt, - TypeName *ofTypename); + TypeName *ofTypename); static CreateStatsStmt *generateClonedExtStatsStmt(RangeVar *heapRel, - Oid heapRelid, Oid source_statsid); + Oid heapRelid, Oid source_statsid); static List *get_collation(Oid collation, Oid actual_datatype); static List *get_opclass(Oid opclass, Oid actual_datatype); static void transformIndexConstraints(CreateStmtContext *cxt); static IndexStmt *transformIndexConstraint(Constraint *constraint, - CreateStmtContext *cxt); + CreateStmtContext *cxt); static void transformExtendedStatistics(CreateStmtContext *cxt); static void transformFKConstraints(CreateStmtContext *cxt, - bool skipValidation, - bool isAddConstraint); + bool skipValidation, + bool isAddConstraint); static void transformCheckConstraints(CreateStmtContext *cxt, - bool skipValidation); + bool skipValidation); static void transformConstraintAttrs(CreateStmtContext *cxt, - List *constraintList); + List *constraintList); static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column); static void setSchemaName(char *context_schema, char **stmt_schema_name); static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd); +static List *transformPartitionRangeBounds(ParseState *pstate, List *blist, + Relation parent); static void validateInfiniteBounds(ParseState *pstate, List *blist); -static Const *transformPartitionBoundValue(ParseState *pstate, A_Const *con, - const char *colName, Oid colType, int32 colTypmod); +static Const *transformPartitionBoundValue(ParseState *pstate, Node *con, + const char *colName, Oid colType, int32 colTypmod, + Oid partCollation); /* @@ -167,7 +172,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) Oid namespaceid; Oid existing_relid; ParseCallbackState pcbstate; - bool like_found = false; bool is_foreign_table = IsA(stmt, CreateForeignTableStmt); /* @@ -246,18 +250,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) cxt.partbound = stmt->partbound; cxt.ofType = (stmt->ofTypename != NULL); - /* - * Notice that we allow OIDs here only for plain tables, even though - * foreign tables also support them. This is necessary because the - * default_with_oids GUC must apply only to plain tables and not any other - * relkind; doing otherwise would break existing pg_dump files. We could - * allow explicit "WITH OIDS" while not allowing default_with_oids to - * affect other relkinds, but it would complicate interpretOidsOption(), - * and right now there's no WITH OIDS option in CREATE FOREIGN TABLE - * anyway. - */ - cxt.hasoids = interpretOidsOption(stmt->options, !cxt.isforeign); - Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */ if (stmt->ofTypename) @@ -290,7 +282,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) break; case T_TableLikeClause: - like_found = true; transformTableLikeClause(&cxt, (TableLikeClause *) element); break; @@ -302,22 +293,10 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) } /* - * If we had any LIKE tables, they may require creation of an OID column - * even though the command's own WITH clause didn't ask for one (or, - * perhaps, even specifically rejected having one). Insert a WITH option - * to ensure that happens. We prepend to the list because the first oid - * option will be honored, and we want to override anything already there. - * (But note that DefineRelation will override this again to add an OID - * column if one appears in an inheritance parent table.) - */ - if (like_found && cxt.hasoids) - stmt->options = lcons(makeDefElem("oids", - (Node *) makeInteger(true), -1), - stmt->options); - - /* - * transformIndexConstraints wants cxt.alist to contain only index - * statements, so transfer anything we already have into save_alist. + * Transfer anything we already have in cxt.alist into save_alist, to keep + * it separate from the output of transformIndexConstraints. (This may + * not be necessary anymore, but we'll keep doing it to preserve the + * historical order of execution of the alist commands.) */ save_alist = cxt.alist; cxt.alist = NIL; @@ -439,7 +418,8 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, sname = ChooseRelationName(cxt->relation->relname, column->colname, "seq", - snamespaceid); + snamespaceid, + false); } ereport(DEBUG1, @@ -483,10 +463,10 @@ generateSerialExtraStmts(CreateStmtContext *cxt, ColumnDef *column, cxt->blist = lappend(cxt->blist, seqstmt); /* - * Store the identity sequence name that we decided on. ALTER TABLE - * ... ADD COLUMN ... IDENTITY needs this so that it can fill the new - * column with values from the sequence, while the association of the - * sequence with the table is not set until after the ALTER TABLE. + * Store the identity sequence name that we decided on. ALTER TABLE ... + * ADD COLUMN ... IDENTITY needs this so that it can fill the new column + * with values from the sequence, while the association of the sequence + * with the table is not set until after the ALTER TABLE. */ column->identitySequence = seqstmt->sequence; @@ -524,6 +504,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) bool saw_nullable; bool saw_default; bool saw_identity; + bool saw_generated; ListCell *clist; cxt->columns = lappend(cxt->columns, column); @@ -631,6 +612,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) saw_nullable = false; saw_default = false; saw_identity = false; + saw_generated = false; foreach(clist, column->constraints) { @@ -690,7 +672,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) errmsg("identity columns are not supported on partitions"))); ctype = typenameType(cxt->pstate, column->typeName, NULL); - typeOid = HeapTupleGetOid(ctype); + typeOid = ((Form_pg_type) GETSTRUCT(ctype))->oid; ReleaseSysCache(ctype); if (saw_identity) @@ -711,6 +693,29 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) break; } + case CONSTR_GENERATED: + if (cxt->ofType) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("generated columns are not supported on typed tables"))); + if (cxt->partbound) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("generated columns are not supported on partitions"))); + + if (saw_generated) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("multiple generation clauses specified for column \"%s\" of table \"%s\"", + column->colname, cxt->relation->relname), + parser_errposition(cxt->pstate, + constraint->location))); + column->generated = ATTRIBUTE_GENERATED_STORED; + column->raw_default = constraint->raw_expr; + Assert(constraint->cooked_expr == NULL); + saw_generated = true; + break; + case CONSTR_CHECK: cxt->ckconstraints = lappend(cxt->ckconstraints, constraint); break; @@ -777,6 +782,22 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column) column->colname, cxt->relation->relname), parser_errposition(cxt->pstate, constraint->location))); + + if (saw_default && saw_generated) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("both default and generation expression specified for column \"%s\" of table \"%s\"", + column->colname, cxt->relation->relname), + parser_errposition(cxt->pstate, + constraint->location))); + + if (saw_identity && saw_generated) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("both identity and generation expression specified for column \"%s\" of table \"%s\"", + column->colname, cxt->relation->relname), + parser_errposition(cxt->pstate, + constraint->location))); } /* @@ -986,7 +1007,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla def->is_local = true; def->is_not_null = attribute->attnotnull; def->is_from_type = false; - def->is_from_parent = false; def->storage = 0; def->raw_default = NULL; def->cooked_default = NULL; @@ -1003,14 +1023,18 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla attmap[parent_attno - 1] = list_length(cxt->columns); /* - * Copy default, if present and the default has been requested + * Copy default, if present and it should be copied. We have separate + * options for plain default expressions and GENERATED defaults. */ if (attribute->atthasdef && - (table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS)) + (attribute->attgenerated ? + (table_like_clause->options & CREATE_TABLE_LIKE_GENERATED) : + (table_like_clause->options & CREATE_TABLE_LIKE_DEFAULTS))) { Node *this_default = NULL; AttrDefault *attrdef; int i; + bool found_whole_row; /* Find default in constraint structure */ Assert(constr != NULL); @@ -1025,12 +1049,25 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla } Assert(this_default != NULL); + def->cooked_default = map_variable_attnos(this_default, + 1, 0, + attmap, tupleDesc->natts, + InvalidOid, &found_whole_row); + /* - * If default expr could contain any vars, we'd need to fix 'em, - * but it can't; so default is ready to apply to child. + * Prevent this for the same reason as for constraints below. Note + * that defaults cannot contain any vars, so it's OK that the + * error message refers to generated columns. */ + if (found_whole_row) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert whole-row table reference"), + errdetail("Generation expression for column \"%s\" contains a whole-row reference to table \"%s\".", + attributeName, + RelationGetRelationName(relation)))); - def->cooked_default = this_default; + def->generated = attribute->attgenerated; } /* @@ -1046,7 +1083,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla * find sequence owned by old column; extract sequence parameters; * build new create sequence command */ - seq_relid = getOwnedSequence(RelationGetRelid(relation), attribute->attnum); + seq_relid = getIdentitySequence(RelationGetRelid(relation), attribute->attnum, false); seq_options = sequence_options(seq_relid); generateSerialExtraStmts(cxt, def, InvalidOid, seq_options, true, @@ -1078,9 +1115,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla } } - /* We use oids if at least one LIKE'ed table has oids. */ - cxt->hasoids |= relation->rd_rel->relhasoids; - /* * Copy CHECK constraints if requested, being careful to adjust attribute * numbers so they match the child. @@ -1164,9 +1198,10 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla parent_index = index_open(parent_index_oid, AccessShareLock); /* Build CREATE INDEX statement to recreate the parent_index */ - index_stmt = generateClonedIndexStmt(cxt->relation, InvalidOid, + index_stmt = generateClonedIndexStmt(cxt->relation, parent_index, - attmap, tupleDesc->natts, NULL); + attmap, tupleDesc->natts, + NULL); /* Copy comment on index, if requested */ if (table_like_clause->options & CREATE_TABLE_LIKE_COMMENTS) @@ -1192,14 +1227,14 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla */ if (table_like_clause->options & CREATE_TABLE_LIKE_STATISTICS) { - List *parent_extstats; - ListCell *l; + List *parent_extstats; + ListCell *l; parent_extstats = RelationGetStatExtList(relation); foreach(l, parent_extstats) { - Oid parent_stat_oid = lfirst_oid(l); + Oid parent_stat_oid = lfirst_oid(l); CreateStatsStmt *stats_stmt; stats_stmt = generateClonedExtStatsStmt(cxt->relation, @@ -1229,7 +1264,7 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla * commit. That will prevent someone else from deleting or ALTERing the * parent before the child is committed. */ - heap_close(relation, NoLock); + table_close(relation, NoLock); } static void @@ -1244,7 +1279,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) tuple = typenameType(NULL, ofTypename, NULL); check_of_type(tuple); - ofTypeId = HeapTupleGetOid(tuple); + ofTypeId = ((Form_pg_type) GETSTRUCT(tuple))->oid; ofTypename->typeOid = ofTypeId; /* cached for later */ tupdesc = lookup_rowtype_tupdesc(ofTypeId, -1); @@ -1263,7 +1298,6 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) n->is_local = true; n->is_not_null = false; n->is_from_type = true; - n->is_from_parent = false; n->storage = 0; n->raw_default = NULL; n->cooked_default = NULL; @@ -1280,13 +1314,26 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) /* * Generate an IndexStmt node using information from an already existing index - * "source_idx", for the rel identified either by heapRel or heapRelid. + * "source_idx". + * + * heapRel is stored into the IndexStmt's relation field, but we don't use it + * otherwise; some callers pass NULL, if they don't need it to be valid. + * (The target relation might not exist yet, so we mustn't try to access it.) + * + * Attribute numbers in expression Vars are adjusted according to attmap. * - * Attribute numbers should be adjusted according to attmap. + * If constraintOid isn't NULL, we store the OID of any constraint associated + * with the index there. + * + * Unlike transformIndexConstraint, we don't make any effort to force primary + * key columns to be NOT NULL. The larger cloning process this is part of + * should have cloned their NOT NULL status separately (and DefineIndex will + * complain if that fails to happen). */ IndexStmt * -generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, - const AttrNumber *attmap, int attmap_length, Oid *constraintOid) +generateClonedIndexStmt(RangeVar *heapRel, Relation source_idx, + const AttrNumber *attmap, int attmap_length, + Oid *constraintOid) { Oid source_relid = RelationGetRelid(source_idx); HeapTuple ht_idxrel; @@ -1306,8 +1353,8 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, Datum datum; bool isnull; - Assert((heapRel == NULL && OidIsValid(heapRelid)) || - (heapRel != NULL && !OidIsValid(heapRelid))); + if (constraintOid) + *constraintOid = InvalidOid; /* * Fetch pg_class tuple of source index. We can't use the copy in the @@ -1345,7 +1392,6 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, /* Begin building the IndexStmt */ index = makeNode(IndexStmt); index->relation = heapRel; - index->relationId = heapRelid; index->accessMethod = pstrdup(NameStr(amrec->amname)); if (OidIsValid(idxrelrec->reltablespace)) index->tableSpace = get_tablespace_name(idxrelrec->reltablespace); @@ -1360,6 +1406,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, index->transformed = true; /* don't need transformIndexStmt */ index->concurrent = false; index->if_not_exists = false; + index->reset_default_tblspc = false; /* * We don't try to preserve the name of the source index; instead, just @@ -1500,7 +1547,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, if (indexpr_item == NULL) elog(ERROR, "too few entries in indexprs list"); indexkey = (Node *) lfirst(indexpr_item); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(indexprs, indexpr_item); /* Adjust Vars to match new table's column numbering */ indexkey = map_variable_attnos(indexkey, @@ -1535,7 +1582,7 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, iparam->nulls_ordering = SORTBY_NULLS_DEFAULT; /* Adjust options if necessary */ - if (source_idx->rd_amroutine->amcanorder) + if (source_idx->rd_indam->amcanorder) { /* * If it supports sort ordering, copy DESC and NULLS opts. Don't @@ -1588,9 +1635,6 @@ generateClonedIndexStmt(RangeVar *heapRel, Oid heapRelid, Relation source_idx, /* Copy the original index column name */ iparam->indexcolname = pstrdup(NameStr(attr->attname)); - /* Add the collation name, if non-default */ - iparam->collation = get_collation(indcollation->values[keyno], keycoltype); - index->indexIncludingParams = lappend(index->indexIncludingParams, iparam); } /* Copy reloptions if any */ @@ -1645,16 +1689,16 @@ static CreateStatsStmt * generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid, Oid source_statsid) { - HeapTuple ht_stats; + HeapTuple ht_stats; Form_pg_statistic_ext statsrec; CreateStatsStmt *stats; - List *stat_types = NIL; - List *def_names = NIL; - bool isnull; - Datum datum; - ArrayType *arr; - char *enabled; - int i; + List *stat_types = NIL; + List *def_names = NIL; + bool isnull; + Datum datum; + ArrayType *arr; + char *enabled; + int i; Assert(OidIsValid(heapRelid)); Assert(heapRel != NULL); @@ -1683,6 +1727,8 @@ generateClonedExtStatsStmt(RangeVar *heapRel, Oid heapRelid, stat_types = lappend(stat_types, makeString("ndistinct")); else if (enabled[i] == STATS_EXT_DEPENDENCIES) stat_types = lappend(stat_types, makeString("dependencies")); + else if (enabled[i] == STATS_EXT_MCV) + stat_types = lappend(stat_types, makeString("mcv")); else elog(ERROR, "unrecognized statistics kind %c", enabled[i]); } @@ -1792,6 +1838,7 @@ transformIndexConstraints(CreateStmtContext *cxt) { IndexStmt *index; List *indexlist = NIL; + List *finalindexlist = NIL; ListCell *lc; /* @@ -1840,11 +1887,10 @@ transformIndexConstraints(CreateStmtContext *cxt) * XXX in ALTER TABLE case, it'd be nice to look for duplicate * pre-existing indexes, too. */ - Assert(cxt->alist == NIL); if (cxt->pkey != NULL) { /* Make sure we keep the PKEY index in preference to others... */ - cxt->alist = list_make1(cxt->pkey); + finalindexlist = list_make1(cxt->pkey); } foreach(lc, indexlist) @@ -1854,11 +1900,11 @@ transformIndexConstraints(CreateStmtContext *cxt) index = lfirst(lc); - /* if it's pkey, it's already in cxt->alist */ + /* if it's pkey, it's already in finalindexlist */ if (index == cxt->pkey) continue; - foreach(k, cxt->alist) + foreach(k, finalindexlist) { IndexStmt *priorindex = lfirst(k); @@ -1886,19 +1932,32 @@ transformIndexConstraints(CreateStmtContext *cxt) } if (keep) - cxt->alist = lappend(cxt->alist, index); + finalindexlist = lappend(finalindexlist, index); } + + /* + * Now append all the IndexStmts to cxt->alist. If we generated an ALTER + * TABLE SET NOT NULL statement to support a primary key, it's already in + * cxt->alist. + */ + cxt->alist = list_concat(cxt->alist, finalindexlist); } /* * transformIndexConstraint * Transform one UNIQUE, PRIMARY KEY, or EXCLUDE constraint for * transformIndexConstraints. + * + * We return an IndexStmt. For a PRIMARY KEY constraint, we additionally + * produce NOT NULL constraints, either by marking ColumnDefs in cxt->columns + * as is_not_null or by adding an ALTER TABLE SET NOT NULL command to + * cxt->alist. */ static IndexStmt * transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) { IndexStmt *index; + List *notnullcmds = NIL; ListCell *lc; index = makeNode(IndexStmt); @@ -1943,6 +2002,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) index->transformed = false; index->concurrent = false; index->if_not_exists = false; + index->reset_default_tblspc = constraint->reset_default_tblspc; /* * If it's ALTER TABLE ADD CONSTRAINT USING INDEX, look up the index and @@ -2005,7 +2065,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) index_name, RelationGetRelationName(heap_rel)), parser_errposition(cxt->pstate, constraint->location))); - if (!IndexIsValid(index_form)) + if (!index_form->indisvalid) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("index \"%s\" is not valid", index_name), @@ -2066,7 +2126,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) for (i = 0; i < index_form->indnatts; i++) { int16 attnum = index_form->indkey.values[i]; - Form_pg_attribute attform; + const FormData_pg_attribute *attform; char *attname; Oid defopclass; @@ -2081,8 +2141,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) attform = TupleDescAttr(heap_rel->rd_att, attnum - 1); } else - attform = SystemAttributeDefinition(attnum, - heap_rel->rd_rel->relhasoids); + attform = SystemAttributeDefinition(attnum); attname = pstrdup(NameStr(attform->attname)); if (i < index_form->indnkeyatts) @@ -2100,7 +2159,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) index_rel->rd_indoption[i] != 0) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("index \"%s\" does not have default sorting behavior", index_name), + errmsg("index \"%s\" column number %d does not have default sorting behavior", index_name, i + 1), errdetail("Cannot create a primary key or unique constraint using such an index."), parser_errposition(cxt->pstate, constraint->location))); @@ -2142,9 +2201,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) * For UNIQUE and PRIMARY KEY, we just have a list of column names. * * Make sure referenced keys exist. If we are making a PRIMARY KEY index, - * also make sure they are NOT NULL, if possible. (Although we could leave - * it to DefineIndex to mark the columns NOT NULL, it's more efficient to - * get it right the first time.) + * also make sure they are NOT NULL. */ else { @@ -2152,11 +2209,12 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) { char *key = strVal(lfirst(lc)); bool found = false; + bool forced_not_null = false; ColumnDef *column = NULL; ListCell *columns; IndexElem *iparam; - /* Make sure referenced column exist. */ + /* Make sure referenced column exists. */ foreach(columns, cxt->columns) { column = castNode(ColumnDef, lfirst(columns)); @@ -2168,11 +2226,20 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) } if (found) { - /* found column in the new table; force it to be NOT NULL */ - if (constraint->contype == CONSTR_PRIMARY) + /* + * column is defined in the new table. For PRIMARY KEY, we + * can apply the NOT NULL constraint cheaply here ... unless + * the column is marked is_from_type, in which case marking it + * here would be ineffective (see MergeAttributes). + */ + if (constraint->contype == CONSTR_PRIMARY && + !column->is_from_type) + { column->is_not_null = true; + forced_not_null = true; + } } - else if (SystemAttributeByName(key, cxt->hasoids) != NULL) + else if (SystemAttributeByName(key) != NULL) { /* * column will be a system column in the new table, so accept @@ -2192,7 +2259,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) Relation rel; int count; - rel = heap_openrv(inh, AccessShareLock); + rel = table_openrv(inh, AccessShareLock); /* check user requested inheritance from valid relkind */ if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE && @@ -2214,15 +2281,16 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) found = true; /* - * We currently have no easy way to force an - * inherited column to be NOT NULL at creation, if - * its parent wasn't so already. We leave it to - * DefineIndex to fix things up in this case. + * It's tempting to set forced_not_null if the + * parent column is already NOT NULL, but that + * seems unsafe because the column's NOT NULL + * marking might disappear between now and + * execution. Do the runtime check to be safe. */ break; } } - heap_close(rel, NoLock); + table_close(rel, NoLock); if (found) break; } @@ -2231,8 +2299,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) /* * In the ALTER TABLE case, don't complain about index keys not * created in the command; they may well exist already. - * DefineIndex will complain about them if not, and will also take - * care of marking them NOT NULL. + * DefineIndex will complain about them if not. */ if (!found && !cxt->isalter) ereport(ERROR, @@ -2271,10 +2338,29 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) iparam->ordering = SORTBY_DEFAULT; iparam->nulls_ordering = SORTBY_NULLS_DEFAULT; index->indexParams = lappend(index->indexParams, iparam); + + /* + * For a primary-key column, also create an item for ALTER TABLE + * SET NOT NULL if we couldn't ensure it via is_not_null above. + */ + if (constraint->contype == CONSTR_PRIMARY && !forced_not_null) + { + AlterTableCmd *notnullcmd = makeNode(AlterTableCmd); + + notnullcmd->subtype = AT_SetNotNull; + notnullcmd->name = pstrdup(key); + notnullcmds = lappend(notnullcmds, notnullcmd); + } } } - /* Add included columns to index definition */ + /* + * Add included columns to index definition. This is much like the + * simple-column-name-list code above, except that we don't worry about + * NOT NULL marking; included columns in a primary key should not be + * forced NOT NULL. We don't complain about duplicate columns, either, + * though maybe we should? + */ foreach(lc, constraint->including) { char *key = strVal(lfirst(lc)); @@ -2295,12 +2381,11 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) if (!found) { - if (SystemAttributeByName(key, cxt->hasoids) != NULL) + if (SystemAttributeByName(key) != NULL) { /* * column will be a system column in the new table, so accept - * it. System columns can't ever be null, so no need to worry - * about PRIMARY/NOT NULL constraint. + * it. */ found = true; } @@ -2315,7 +2400,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) Relation rel; int count; - rel = heap_openrv(inh, AccessShareLock); + rel = table_openrv(inh, AccessShareLock); /* check user requested inheritance from valid relkind */ if (rel->rd_rel->relkind != RELKIND_RELATION && rel->rd_rel->relkind != RELKIND_FOREIGN_TABLE && @@ -2335,17 +2420,10 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) if (strcmp(key, inhname) == 0) { found = true; - - /* - * We currently have no easy way to force an - * inherited column to be NOT NULL at creation, if - * its parent wasn't so already. We leave it to - * DefineIndex to fix things up in this case. - */ break; } } - heap_close(rel, NoLock); + table_close(rel, NoLock); if (found) break; } @@ -2355,8 +2433,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) /* * In the ALTER TABLE case, don't complain about index keys not * created in the command; they may well exist already. DefineIndex - * will complain about them if not, and will also take care of marking - * them NOT NULL. + * will complain about them if not. */ if (!found && !cxt->isalter) ereport(ERROR, @@ -2374,6 +2451,22 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) index->indexIncludingParams = lappend(index->indexIncludingParams, iparam); } + /* + * If we found anything that requires run-time SET NOT NULL, build a full + * ALTER TABLE command for that and add it to cxt->alist. + */ + if (notnullcmds) + { + AlterTableStmt *alterstmt = makeNode(AlterTableStmt); + + alterstmt->relation = copyObject(cxt->relation); + alterstmt->cmds = notnullcmds; + alterstmt->relkind = OBJECT_TABLE; + alterstmt->missing_ok = false; + + cxt->alist = lappend(cxt->alist, alterstmt); + } + return index; } @@ -2527,7 +2620,9 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) * relation, but we still need to open it. */ rel = relation_open(relid, NoLock); - rte = addRangeTableEntryForRelation(pstate, rel, NULL, false, true); + rte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, + NULL, false, true); /* no to join list, yes to namespaces */ addRTEtoQuery(pstate, rte, false, true, true); @@ -2583,7 +2678,7 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString) free_parsestate(pstate); /* Close relation */ - heap_close(rel, NoLock); + table_close(rel, NoLock); /* Mark statement as successfully transformed */ stmt->transformed = true; @@ -2619,7 +2714,7 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, * DefineQueryRewrite(), and we don't want to grab a lesser lock * beforehand. */ - rel = heap_openrv(stmt->relation, AccessExclusiveLock); + rel = table_openrv(stmt->relation, AccessExclusiveLock); if (rel->rd_rel->relkind == RELKIND_MATVIEW) ereport(ERROR, @@ -2636,9 +2731,11 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, * qualification. */ oldrte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, makeAlias("old", NIL), false, false); newrte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, makeAlias("new", NIL), false, false); /* Must override addRangeTableEntry's default access-check flags */ @@ -2734,9 +2831,11 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, * them in the joinlist. */ oldrte = addRangeTableEntryForRelation(sub_pstate, rel, + AccessShareLock, makeAlias("old", NIL), false, false); newrte = addRangeTableEntryForRelation(sub_pstate, rel, + AccessShareLock, makeAlias("new", NIL), false, false); oldrte->requiredPerms = 0; @@ -2893,7 +2992,7 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, free_parsestate(pstate); /* Close relation, but keep the exclusive lock */ - heap_close(rel, NoLock); + table_close(rel, NoLock); } @@ -2914,6 +3013,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, const char *queryString) { Relation rel; + TupleDesc tupdesc; ParseState *pstate; CreateStmtContext cxt; List *result; @@ -2933,12 +3033,14 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, /* Caller is responsible for locking the relation */ rel = relation_open(relid, NoLock); + tupdesc = RelationGetDescr(rel); /* Set up pstate */ pstate = make_parsestate(NULL); pstate->p_sourcetext = queryString; rte = addRangeTableEntryForRelation(pstate, rel, + AccessShareLock, NULL, false, true); @@ -2960,7 +3062,6 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, cxt.rel = rel; cxt.inhRelations = NIL; cxt.isalter = true; - cxt.hasoids = false; /* need not be right */ cxt.columns = NIL; cxt.ckconstraints = NIL; cxt.fkconstraints = NIL; @@ -3061,9 +3162,10 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, * if attribute not found, something will error about it * later */ - if (attnum != InvalidAttrNumber && get_attidentity(relid, attnum)) + if (attnum != InvalidAttrNumber && + TupleDescAttr(tupdesc, attnum - 1)->attidentity) { - Oid seq_relid = getOwnedSequence(relid, attnum); + Oid seq_relid = getIdentitySequence(relid, attnum, false); Oid typeOid = typenameTypeId(pstate, def->typeName); AlterSeqStmt *altseqstmt = makeNode(AlterSeqStmt); @@ -3114,7 +3216,6 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, ListCell *lc; List *newseqopts = NIL; List *newdef = NIL; - List *seqlist; AttrNumber attnum; /* @@ -3135,14 +3236,13 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, if (attnum) { - seqlist = getOwnedSequences(relid, attnum); - if (seqlist) + Oid seq_relid = getIdentitySequence(relid, attnum, true); + + if (seq_relid) { AlterSeqStmt *seqstmt; - Oid seq_relid; seqstmt = makeNode(AlterSeqStmt); - seq_relid = linitial_oid(seqlist); seqstmt->sequence = makeRangeVar(get_namespace_name(get_rel_namespace(seq_relid)), get_rel_name(seq_relid), -1); seqstmt->options = newseqopts; @@ -3183,9 +3283,8 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, } /* - * transformIndexConstraints wants cxt.alist to contain only index - * statements, so transfer anything we already have into save_alist - * immediately. + * Transfer anything we already have in cxt.alist into save_alist, to keep + * it separate from the output of transformIndexConstraints. */ save_alist = cxt.alist; cxt.alist = NIL; @@ -3203,13 +3302,31 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, */ foreach(l, cxt.alist) { - IndexStmt *idxstmt = lfirst_node(IndexStmt, l); + Node *istmt = (Node *) lfirst(l); - idxstmt = transformIndexStmt(relid, idxstmt, queryString); - newcmd = makeNode(AlterTableCmd); - newcmd->subtype = OidIsValid(idxstmt->indexOid) ? AT_AddIndexConstraint : AT_AddIndex; - newcmd->def = (Node *) idxstmt; - newcmds = lappend(newcmds, newcmd); + /* + * We assume here that cxt.alist contains only IndexStmts and possibly + * ALTER TABLE SET NOT NULL statements generated from primary key + * constraints. We absorb the subcommands of the latter directly. + */ + if (IsA(istmt, IndexStmt)) + { + IndexStmt *idxstmt = (IndexStmt *) istmt; + + idxstmt = transformIndexStmt(relid, idxstmt, queryString); + newcmd = makeNode(AlterTableCmd); + newcmd->subtype = OidIsValid(idxstmt->indexOid) ? AT_AddIndexConstraint : AT_AddIndex; + newcmd->def = (Node *) idxstmt; + newcmds = lappend(newcmds, newcmd); + } + else if (IsA(istmt, AlterTableStmt)) + { + AlterTableStmt *alterstmt = (AlterTableStmt *) istmt; + + newcmds = list_concat(newcmds, alterstmt->cmds); + } + else + elog(ERROR, "unexpected stmt type %d", (int) nodeTag(istmt)); } cxt.alist = NIL; @@ -3393,7 +3510,7 @@ transformColumnType(CreateStmtContext *cxt, ColumnDef *column) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("collations are not supported by type %s", - format_type_be(HeapTupleGetOid(ctype))), + format_type_be(typtup->oid)), parser_errposition(cxt->pstate, column->collClause->location))); } @@ -3610,6 +3727,12 @@ transformPartitionBound(ParseState *pstate, Relation parent, if (spec->is_default) { + /* + * Hash partitioning does not support a default partition; there's no + * use case for it (since the set of partitions to create is perfectly + * defined), and if users do get into it accidentally, it's hard to + * back out from it afterwards. + */ if (strategy == PARTITION_STRATEGY_HASH) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -3651,6 +3774,7 @@ transformPartitionBound(ParseState *pstate, Relation parent, char *colname; Oid coltype; int32 coltypmod; + Oid partcollation; if (spec->strategy != PARTITION_STRATEGY_LIST) ereport(ERROR, @@ -3670,17 +3794,19 @@ transformPartitionBound(ParseState *pstate, Relation parent, /* Need its type data too */ coltype = get_partition_col_typid(key, 0); coltypmod = get_partition_col_typmod(key, 0); + partcollation = get_partition_col_collation(key, 0); result_spec->listdatums = NIL; foreach(cell, spec->listdatums) { - A_Const *con = castNode(A_Const, lfirst(cell)); + Node *expr = lfirst(cell); Const *value; ListCell *cell2; bool duplicate; - value = transformPartitionBoundValue(pstate, con, - colname, coltype, coltypmod); + value = transformPartitionBoundValue(pstate, expr, + colname, coltype, coltypmod, + partcollation); /* Don't add to the result if the value is a duplicate */ duplicate = false; @@ -3703,11 +3829,6 @@ transformPartitionBound(ParseState *pstate, Relation parent, } else if (strategy == PARTITION_STRATEGY_RANGE) { - ListCell *cell1, - *cell2; - int i, - j; - if (spec->strategy != PARTITION_STRATEGY_RANGE) ereport(ERROR, (errcode(ERRCODE_INVALID_TABLE_DEFINITION), @@ -3724,23 +3845,90 @@ transformPartitionBound(ParseState *pstate, Relation parent, errmsg("TO must specify exactly one value per partitioning column"))); /* - * Once we see MINVALUE or MAXVALUE for one column, the remaining - * columns must be the same. + * Convert raw parse nodes into PartitionRangeDatum nodes and perform + * any necessary validation. */ - validateInfiniteBounds(pstate, spec->lowerdatums); - validateInfiniteBounds(pstate, spec->upperdatums); + result_spec->lowerdatums = + transformPartitionRangeBounds(pstate, spec->lowerdatums, + parent); + result_spec->upperdatums = + transformPartitionRangeBounds(pstate, spec->upperdatums, + parent); + } + else + elog(ERROR, "unexpected partition strategy: %d", (int) strategy); + + return result_spec; +} + +/* + * transformPartitionRangeBounds + * This converts the expressions for range partition bounds from the raw + * grammar representation to PartitionRangeDatum structs + */ +static List * +transformPartitionRangeBounds(ParseState *pstate, List *blist, + Relation parent) +{ + List *result = NIL; + PartitionKey key = RelationGetPartitionKey(parent); + List *partexprs = get_partition_exprs(key); + ListCell *lc; + int i, + j; + + i = j = 0; + foreach(lc, blist) + { + Node *expr = lfirst(lc); + PartitionRangeDatum *prd = NULL; + + /* + * Infinite range bounds -- "minvalue" and "maxvalue" -- get passed in + * as ColumnRefs. + */ + if (IsA(expr, ColumnRef)) + { + ColumnRef *cref = (ColumnRef *) expr; + char *cname = NULL; + + /* + * There should be a single field named either "minvalue" or + * "maxvalue". + */ + if (list_length(cref->fields) == 1 && + IsA(linitial(cref->fields), String)) + cname = strVal(linitial(cref->fields)); + + if (cname == NULL) + { + /* + * ColumnRef is not in the desired single-field-name form. For + * consistency between all partition strategies, let the + * expression transformation report any errors rather than + * doing it ourselves. + */ + } + else if (strcmp("minvalue", cname) == 0) + { + prd = makeNode(PartitionRangeDatum); + prd->kind = PARTITION_RANGE_DATUM_MINVALUE; + prd->value = NULL; + } + else if (strcmp("maxvalue", cname) == 0) + { + prd = makeNode(PartitionRangeDatum); + prd->kind = PARTITION_RANGE_DATUM_MAXVALUE; + prd->value = NULL; + } + } - /* Transform all the constants */ - i = j = 0; - result_spec->lowerdatums = result_spec->upperdatums = NIL; - forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums) + if (prd == NULL) { - PartitionRangeDatum *ldatum = (PartitionRangeDatum *) lfirst(cell1); - PartitionRangeDatum *rdatum = (PartitionRangeDatum *) lfirst(cell2); char *colname; Oid coltype; int32 coltypmod; - A_Const *con; + Oid partcollation; Const *value; /* Get the column's name in case we need to output an error */ @@ -3755,50 +3943,38 @@ transformPartitionBound(ParseState *pstate, Relation parent, false, false); ++j; } + /* Need its type data too */ coltype = get_partition_col_typid(key, i); coltypmod = get_partition_col_typmod(key, i); + partcollation = get_partition_col_collation(key, i); - if (ldatum->value) - { - con = castNode(A_Const, ldatum->value); - value = transformPartitionBoundValue(pstate, con, - colname, - coltype, coltypmod); - if (value->constisnull) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot specify NULL in range bound"))); - ldatum = copyObject(ldatum); /* don't scribble on input */ - ldatum->value = (Node *) value; - } - - if (rdatum->value) - { - con = castNode(A_Const, rdatum->value); - value = transformPartitionBoundValue(pstate, con, - colname, - coltype, coltypmod); - if (value->constisnull) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("cannot specify NULL in range bound"))); - rdatum = copyObject(rdatum); /* don't scribble on input */ - rdatum->value = (Node *) value; - } - - result_spec->lowerdatums = lappend(result_spec->lowerdatums, - ldatum); - result_spec->upperdatums = lappend(result_spec->upperdatums, - rdatum); - + value = transformPartitionBoundValue(pstate, expr, + colname, + coltype, coltypmod, + partcollation); + if (value->constisnull) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("cannot specify NULL in range bound"))); + prd = makeNode(PartitionRangeDatum); + prd->kind = PARTITION_RANGE_DATUM_VALUE; + prd->value = (Node *) value; ++i; } + + prd->location = exprLocation(expr); + + result = lappend(result, prd); } - else - elog(ERROR, "unexpected partition strategy: %d", (int) strategy); - return result_spec; + /* + * Once we see MINVALUE or MAXVALUE for one column, the remaining columns + * must be the same. + */ + validateInfiniteBounds(pstate, result); + + return result; } /* @@ -3831,12 +4007,14 @@ validateInfiniteBounds(ParseState *pstate, List *blist) (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("every bound following MAXVALUE must also be MAXVALUE"), parser_errposition(pstate, exprLocation((Node *) prd)))); + break; case PARTITION_RANGE_DATUM_MINVALUE: ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("every bound following MINVALUE must also be MINVALUE"), parser_errposition(pstate, exprLocation((Node *) prd)))); + break; } } } @@ -3845,13 +4023,34 @@ validateInfiniteBounds(ParseState *pstate, List *blist) * Transform one constant in a partition bound spec */ static Const * -transformPartitionBoundValue(ParseState *pstate, A_Const *con, - const char *colName, Oid colType, int32 colTypmod) +transformPartitionBoundValue(ParseState *pstate, Node *val, + const char *colName, Oid colType, int32 colTypmod, + Oid partCollation) { Node *value; - /* Make it into a Const */ - value = (Node *) make_const(pstate, &con->val, con->location); + /* Transform raw parsetree */ + value = transformExpr(pstate, val, EXPR_KIND_PARTITION_BOUND); + + /* + * Check that the input expression's collation is compatible with one + * specified for the parent's partition key (partcollation). Don't throw + * an error if it's the default collation which we'll replace with the + * parent's collation anyway. + */ + if (IsA(value, CollateExpr)) + { + Oid exprCollOid = exprCollation(value); + + if (OidIsValid(exprCollOid) && + exprCollOid != DEFAULT_COLLATION_OID && + exprCollOid != partCollation) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"", + colName, get_collation_name(partCollation)), + parser_errposition(pstate, exprLocation(value)))); + } /* Coerce to correct type */ value = coerce_to_target_type(pstate, @@ -3867,21 +4066,27 @@ transformPartitionBoundValue(ParseState *pstate, A_Const *con, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("specified value cannot be cast to type %s for column \"%s\"", format_type_be(colType), colName), - parser_errposition(pstate, con->location))); + parser_errposition(pstate, exprLocation(val)))); /* Simplify the expression, in case we had a coercion */ if (!IsA(value, Const)) value = (Node *) expression_planner((Expr *) value); - /* Fail if we don't have a constant (i.e., non-immutable coercion) */ + /* + * transformExpr() should have already rejected column references, + * subqueries, aggregates, window functions, and SRFs, based on the + * EXPR_KIND_ for a default expression. + */ + Assert(!contain_var_clause(value)); + + /* + * Evaluate the expression, assigning the partition key's collation to the + * resulting Const expression. + */ + value = (Node *) evaluate_expr((Expr *) value, colType, colTypmod, + partCollation); if (!IsA(value, Const)) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("specified value cannot be cast to type %s for column \"%s\"", - format_type_be(colType), colName), - errdetail("The cast requires a non-immutable conversion."), - errhint("Try putting the literal value in single quotes."), - parser_errposition(pstate, con->location))); + elog(ERROR, "could not evaluate partition bound expression"); return (Const *) value; } diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index db304834592..4c0c258cd7f 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -10,7 +10,7 @@ * analyze.c and related files. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -41,7 +41,7 @@ raw_parser(const char *str) /* initialize the flex scanner */ yyscanner = scanner_init(str, &yyextra.core_yy_extra, - ScanKeywords, NumScanKeywords); + &ScanKeywords, ScanKeywordTokens); /* base_yylex() only needs this much initialization */ yyextra.have_lookahead = false; diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 0cd782827ac..e1cae859e8f 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -6,7 +6,8 @@ * * NOTE NOTE NOTE: * - * The rules in this file must be kept in sync with src/fe_utils/psqlscan.l! + * The rules in this file must be kept in sync with src/fe_utils/psqlscan.l + * and src/interfaces/ecpg/preproc/pgc.l! * * The rules are designed so that the scanner never has to backtrack, * in the sense that there is always a rule that can match the input @@ -21,7 +22,7 @@ * Postgres 9.2, this check is made automatically by the Makefile.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -65,6 +66,21 @@ int backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING; bool escape_string_warning = true; bool standard_conforming_strings = true; +/* + * Constant data exported from this file. This array maps from the + * zero-based keyword numbers returned by ScanKeywordLookup to the + * Bison token numbers needed by gram.y. This is exported because + * callers need to pass it to scanner_init, if they are using the + * standard keyword list ScanKeywords. + */ +#define PG_KEYWORD(kwname, value, category) value, + +const uint16 ScanKeywordTokens[] = { +#include "parser/kwlist.h" +}; + +#undef PG_KEYWORD + /* * Set the type of YYSTYPE. */ @@ -168,8 +184,8 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); %x xc %x xd %x xh -%x xe %x xq +%x xe %x xdolq %x xui %x xuiend @@ -192,7 +208,7 @@ extern void core_yyset_column(int column_no, yyscan_t yyscanner); * XXX perhaps \f (formfeed) should be treated as a newline as well? * * XXX if you change the set of whitespace characters, fix scanner_isspace() - * to agree, and see also the plpgsql lexer. + * to agree. */ space [ \t\n\r\f] @@ -339,6 +355,15 @@ identifier {ident_start}{ident_cont}* typecast "::" dot_dot \.\. colon_equals ":=" + +/* + * These operator-like tokens (unlike the above ones) also match the {operator} + * rule, which means that they might be overridden by a longer match if they + * are followed by a comment start or a + or - character. Accordingly, if you + * add to this list, you must also add corresponding code to the {operator} + * block to return the correct token in such cases. (This is not needed in + * psqlscan.l since the token value is ignored there.) + */ equals_greater "=>" less_equals "<=" greater_equals ">=" @@ -408,32 +433,36 @@ other . yyless(2); } -{xcstart} { +{ +{xcstart} { (yyextra->xcdepth)++; /* Put back any characters past slash-star; see above */ yyless(2); } -{xcstop} { +{xcstop} { if (yyextra->xcdepth <= 0) BEGIN(INITIAL); else (yyextra->xcdepth)--; } -{xcinside} { +{xcinside} { /* ignore */ } -{op_chars} { +{op_chars} { /* ignore */ } -\*+ { +\*+ { /* ignore */ } -<> { yyerror("unterminated /* comment"); } +<> { + yyerror("unterminated /* comment"); + } +} /* */ {xbstart} { /* Binary bit type. @@ -490,18 +519,18 @@ other . * We will pass this along as a normal character string, * but preceded with an internally-generated "NCHAR". */ - const ScanKeyword *keyword; + int kwnum; SET_YYLLOC(); yyless(1); /* eat only 'n' this time */ - keyword = ScanKeywordLookup("nchar", - yyextra->keywords, - yyextra->num_keywords); - if (keyword != NULL) + kwnum = ScanKeywordLookup("nchar", + yyextra->keywordlist); + if (kwnum >= 0) { - yylval->keyword = keyword->name; - return keyword->value; + yylval->keyword = GetScanKeyword(kwnum, + yyextra->keywordlist); + return yyextra->keyword_tokens[kwnum]; } else { @@ -885,20 +914,33 @@ other . * to forbid operator names like '?-' that could not be * sequences of SQL operators. */ - while (nchars > 1 && - (yytext[nchars - 1] == '+' || - yytext[nchars - 1] == '-')) + if (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')) { int ic; for (ic = nchars - 2; ic >= 0; ic--) { - if (strchr("~!@#^&|`?%", yytext[ic])) + char c = yytext[ic]; + if (c == '~' || c == '!' || c == '@' || + c == '#' || c == '^' || c == '&' || + c == '|' || c == '`' || c == '?' || + c == '%') break; } - if (ic >= 0) - break; /* found a char that makes it OK */ - nchars--; /* else remove the +/-, and check again */ + if (ic < 0) + { + /* + * didn't find a qualifying character, so remove + * all trailing [+-] + */ + do { + nchars--; + } while (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')); + } } SET_YYLLOC(); @@ -916,6 +958,25 @@ other . if (nchars == 1 && strchr(",()[].;:+-*/%^<>=", yytext[0])) return yytext[0]; + /* + * Likewise, if what we have left is two chars, and + * those match the tokens ">=", "<=", "=>", "<>" or + * "!=", then we must return the appropriate token + * rather than the generic Op. + */ + if (nchars == 2) + { + if (yytext[0] == '=' && yytext[1] == '>') + return EQUALS_GREATER; + if (yytext[0] == '>' && yytext[1] == '=') + return GREATER_EQUALS; + if (yytext[0] == '<' && yytext[1] == '=') + return LESS_EQUALS; + if (yytext[0] == '<' && yytext[1] == '>') + return NOT_EQUALS; + if (yytext[0] == '!' && yytext[1] == '=') + return NOT_EQUALS; + } } /* @@ -959,39 +1020,35 @@ other . } {realfail1} { /* - * throw back the [Ee], and treat as {decimal}. Note - * that it is possible the input is actually {integer}, - * but since this case will almost certainly lead to a - * syntax error anyway, we don't bother to distinguish. + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. */ yyless(yyleng - 1); SET_YYLLOC(); - yylval->str = pstrdup(yytext); - return FCONST; + return process_integer_literal(yytext, yylval); } {realfail2} { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); SET_YYLLOC(); - yylval->str = pstrdup(yytext); - return FCONST; + return process_integer_literal(yytext, yylval); } {identifier} { - const ScanKeyword *keyword; + int kwnum; char *ident; SET_YYLLOC(); /* Is it a keyword? */ - keyword = ScanKeywordLookup(yytext, - yyextra->keywords, - yyextra->num_keywords); - if (keyword != NULL) + kwnum = ScanKeywordLookup(yytext, + yyextra->keywordlist); + if (kwnum >= 0) { - yylval->keyword = keyword->name; - return keyword->value; + yylval->keyword = GetScanKeyword(kwnum, + yyextra->keywordlist); + return yyextra->keyword_tokens[kwnum]; } /* @@ -1100,8 +1157,8 @@ scanner_yyerror(const char *message, core_yyscan_t yyscanner) core_yyscan_t scanner_init(const char *str, core_yy_extra_type *yyext, - const ScanKeyword *keywords, - int num_keywords) + const ScanKeywordList *keywordlist, + const uint16 *keyword_tokens) { Size slen = strlen(str); yyscan_t scanner; @@ -1111,8 +1168,8 @@ scanner_init(const char *str, core_yyset_extra(yyext, scanner); - yyext->keywords = keywords; - yyext->num_keywords = num_keywords; + yyext->keywordlist = keywordlist; + yyext->keyword_tokens = keyword_tokens; yyext->backslash_quote = backslash_quote; yyext->escape_string_warning = escape_string_warning; @@ -1209,6 +1266,10 @@ litbufdup(core_yyscan_t yyscanner) return new; } +/* + * Process {integer}. Note this will also do the right thing with {decimal}, + * ie digits and a decimal point. + */ static int process_integer_literal(const char *token, YYSTYPE *lval) { @@ -1219,7 +1280,7 @@ process_integer_literal(const char *token, YYSTYPE *lval) val = strtoint(token, &endptr, 10); if (*endptr != '\0' || errno == ERANGE) { - /* integer too large, treat it as a float */ + /* integer too large (or contains decimal pt), treat it as a float */ lval->str = pstrdup(token); return FCONST; } diff --git a/src/backend/parser/scansup.c b/src/backend/parser/scansup.c index 9256524b8d5..53e3ae2a9c7 100644 --- a/src/backend/parser/scansup.c +++ b/src/backend/parser/scansup.c @@ -4,7 +4,7 @@ * support routines for the lex/flex scanner, used by both the normal * backend as well as the bootstrap backend * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/partitioning/Makefile b/src/backend/partitioning/Makefile index 429207c4eba..82093c615f3 100644 --- a/src/backend/partitioning/Makefile +++ b/src/backend/partitioning/Makefile @@ -12,6 +12,6 @@ subdir = src/backend/partitioning top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -OBJS = partprune.o +OBJS = partbounds.o partdesc.o partprune.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c new file mode 100644 index 00000000000..318d8ecae9a --- /dev/null +++ b/src/backend/partitioning/partbounds.c @@ -0,0 +1,2998 @@ +/*------------------------------------------------------------------------- + * + * partbounds.c + * Support routines for manipulating partition bounds + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/partitioning/partbounds.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/relation.h" +#include "access/table.h" +#include "access/tableam.h" +#include "catalog/partition.h" +#include "catalog/pg_inherits.h" +#include "catalog/pg_type.h" +#include "commands/tablecmds.h" +#include "executor/executor.h" +#include "miscadmin.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "parser/parse_coerce.h" +#include "partitioning/partbounds.h" +#include "partitioning/partdesc.h" +#include "partitioning/partprune.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/fmgroids.h" +#include "utils/hashutils.h" +#include "utils/lsyscache.h" +#include "utils/partcache.h" +#include "utils/rel.h" +#include "utils/snapmgr.h" +#include "utils/ruleutils.h" +#include "utils/syscache.h" + +/* + * When qsort'ing partition bounds after reading from the catalog, each bound + * is represented with one of the following structs. + */ + +/* One bound of a hash partition */ +typedef struct PartitionHashBound +{ + int modulus; + int remainder; + int index; +} PartitionHashBound; + +/* One value coming from some (index'th) list partition */ +typedef struct PartitionListValue +{ + int index; + Datum value; +} PartitionListValue; + +/* One bound of a range partition */ +typedef struct PartitionRangeBound +{ + int index; + Datum *datums; /* range bound datums */ + PartitionRangeDatumKind *kind; /* the kind of each datum */ + bool lower; /* this is the lower (vs upper) bound */ +} PartitionRangeBound; + +static int32 qsort_partition_hbound_cmp(const void *a, const void *b); +static int32 qsort_partition_list_value_cmp(const void *a, const void *b, + void *arg); +static int32 qsort_partition_rbound_cmp(const void *a, const void *b, + void *arg); +static PartitionBoundInfo create_hash_bounds(PartitionBoundSpec **boundspecs, + int nparts, PartitionKey key, int **mapping); +static PartitionBoundInfo create_list_bounds(PartitionBoundSpec **boundspecs, + int nparts, PartitionKey key, int **mapping); +static PartitionBoundInfo create_range_bounds(PartitionBoundSpec **boundspecs, + int nparts, PartitionKey key, int **mapping); +static PartitionRangeBound *make_one_partition_rbound(PartitionKey key, int index, + List *datums, bool lower); +static int32 partition_hbound_cmp(int modulus1, int remainder1, int modulus2, + int remainder2); +static int32 partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, Datum *datums1, + PartitionRangeDatumKind *kind1, bool lower1, + PartitionRangeBound *b2); +static int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + PartitionRangeBound *probe, bool *is_equal); +static int get_partition_bound_num_indexes(PartitionBoundInfo b); +static Expr *make_partition_op_expr(PartitionKey key, int keynum, + uint16 strategy, Expr *arg1, Expr *arg2); +static Oid get_partition_operator(PartitionKey key, int col, + StrategyNumber strategy, bool *need_relabel); +static List *get_qual_for_hash(Relation parent, PartitionBoundSpec *spec); +static List *get_qual_for_list(Relation parent, PartitionBoundSpec *spec); +static List *get_qual_for_range(Relation parent, PartitionBoundSpec *spec, + bool for_default); +static void get_range_key_properties(PartitionKey key, int keynum, + PartitionRangeDatum *ldatum, + PartitionRangeDatum *udatum, + ListCell **partexprs_item, + Expr **keyCol, + Const **lower_val, Const **upper_val); +static List *get_range_nulltest(PartitionKey key); + +/* + * get_qual_from_partbound + * Given a parser node for partition bound, return the list of executable + * expressions as partition constraint + */ +List * +get_qual_from_partbound(Relation rel, Relation parent, + PartitionBoundSpec *spec) +{ + PartitionKey key = RelationGetPartitionKey(parent); + List *my_qual = NIL; + + Assert(key != NULL); + + switch (key->strategy) + { + case PARTITION_STRATEGY_HASH: + Assert(spec->strategy == PARTITION_STRATEGY_HASH); + my_qual = get_qual_for_hash(parent, spec); + break; + + case PARTITION_STRATEGY_LIST: + Assert(spec->strategy == PARTITION_STRATEGY_LIST); + my_qual = get_qual_for_list(parent, spec); + break; + + case PARTITION_STRATEGY_RANGE: + Assert(spec->strategy == PARTITION_STRATEGY_RANGE); + my_qual = get_qual_for_range(parent, spec, false); + break; + + default: + elog(ERROR, "unexpected partition strategy: %d", + (int) key->strategy); + } + + return my_qual; +} + +/* + * partition_bounds_create + * Build a PartitionBoundInfo struct from a list of PartitionBoundSpec + * nodes + * + * This function creates a PartitionBoundInfo and fills the values of its + * various members based on the input list. Importantly, 'datums' array will + * contain Datum representation of individual bounds (possibly after + * de-duplication as in case of range bounds), sorted in a canonical order + * defined by qsort_partition_* functions of respective partitioning methods. + * 'indexes' array will contain as many elements as there are bounds (specific + * exceptions to this rule are listed in the function body), which represent + * the 0-based canonical positions of partitions. + * + * Upon return from this function, *mapping is set to an array of + * list_length(boundspecs) elements, each of which maps the original index of + * a partition to its canonical index. + * + * Note: The objects returned by this function are wholly allocated in the + * current memory context. + */ +PartitionBoundInfo +partition_bounds_create(PartitionBoundSpec **boundspecs, int nparts, + PartitionKey key, int **mapping) +{ + int i; + + Assert(nparts > 0); + + /* + * For each partitioning method, we first convert the partition bounds + * from their parser node representation to the internal representation, + * along with any additional preprocessing (such as de-duplicating range + * bounds). Resulting bound datums are then added to the 'datums' array + * in PartitionBoundInfo. For each datum added, an integer indicating the + * canonical partition index is added to the 'indexes' array. + * + * For each bound, we remember its partition's position (0-based) in the + * original list to later map it to the canonical index. + */ + + /* + * Initialize mapping array with invalid values, this is filled within + * each sub-routine below depending on the bound type. + */ + *mapping = (int *) palloc(sizeof(int) * nparts); + for (i = 0; i < nparts; i++) + (*mapping)[i] = -1; + + switch (key->strategy) + { + case PARTITION_STRATEGY_HASH: + return create_hash_bounds(boundspecs, nparts, key, mapping); + + case PARTITION_STRATEGY_LIST: + return create_list_bounds(boundspecs, nparts, key, mapping); + + case PARTITION_STRATEGY_RANGE: + return create_range_bounds(boundspecs, nparts, key, mapping); + + default: + elog(ERROR, "unexpected partition strategy: %d", + (int) key->strategy); + break; + } + + Assert(false); + return NULL; /* keep compiler quiet */ +} + +/* + * create_hash_bounds + * Create a PartitionBoundInfo for a hash partitioned table + */ +static PartitionBoundInfo +create_hash_bounds(PartitionBoundSpec **boundspecs, int nparts, + PartitionKey key, int **mapping) +{ + PartitionBoundInfo boundinfo; + PartitionHashBound **hbounds = NULL; + int i; + int ndatums = 0; + int greatest_modulus; + + boundinfo = (PartitionBoundInfoData *) + palloc0(sizeof(PartitionBoundInfoData)); + boundinfo->strategy = key->strategy; + /* No special hash partitions. */ + boundinfo->null_index = -1; + boundinfo->default_index = -1; + + ndatums = nparts; + hbounds = (PartitionHashBound **) + palloc(nparts * sizeof(PartitionHashBound *)); + + /* Convert from node to the internal representation */ + for (i = 0; i < nparts; i++) + { + PartitionBoundSpec *spec = boundspecs[i]; + + if (spec->strategy != PARTITION_STRATEGY_HASH) + elog(ERROR, "invalid strategy in partition bound spec"); + + hbounds[i] = (PartitionHashBound *) palloc(sizeof(PartitionHashBound)); + hbounds[i]->modulus = spec->modulus; + hbounds[i]->remainder = spec->remainder; + hbounds[i]->index = i; + } + + /* Sort all the bounds in ascending order */ + qsort(hbounds, nparts, sizeof(PartitionHashBound *), + qsort_partition_hbound_cmp); + + /* After sorting, moduli are now stored in ascending order. */ + greatest_modulus = hbounds[ndatums - 1]->modulus; + + boundinfo->ndatums = ndatums; + boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->indexes = (int *) palloc(greatest_modulus * sizeof(int)); + for (i = 0; i < greatest_modulus; i++) + boundinfo->indexes[i] = -1; + + /* + * For hash partitioning, there are as many datums (modulus and remainder + * pairs) as there are partitions. Indexes are simply values ranging from + * 0 to (nparts - 1). + */ + for (i = 0; i < nparts; i++) + { + int modulus = hbounds[i]->modulus; + int remainder = hbounds[i]->remainder; + + boundinfo->datums[i] = (Datum *) palloc(2 * sizeof(Datum)); + boundinfo->datums[i][0] = Int32GetDatum(modulus); + boundinfo->datums[i][1] = Int32GetDatum(remainder); + + while (remainder < greatest_modulus) + { + /* overlap? */ + Assert(boundinfo->indexes[remainder] == -1); + boundinfo->indexes[remainder] = i; + remainder += modulus; + } + + (*mapping)[hbounds[i]->index] = i; + pfree(hbounds[i]); + } + pfree(hbounds); + + return boundinfo; +} + +/* + * create_list_bounds + * Create a PartitionBoundInfo for a list partitioned table + */ +static PartitionBoundInfo +create_list_bounds(PartitionBoundSpec **boundspecs, int nparts, + PartitionKey key, int **mapping) +{ + PartitionBoundInfo boundinfo; + PartitionListValue **all_values = NULL; + ListCell *cell; + int i = 0; + int ndatums = 0; + int next_index = 0; + int default_index = -1; + int null_index = -1; + List *non_null_values = NIL; + + boundinfo = (PartitionBoundInfoData *) + palloc0(sizeof(PartitionBoundInfoData)); + boundinfo->strategy = key->strategy; + /* Will be set correctly below. */ + boundinfo->null_index = -1; + boundinfo->default_index = -1; + + /* Create a unified list of non-null values across all partitions. */ + for (i = 0; i < nparts; i++) + { + PartitionBoundSpec *spec = boundspecs[i]; + ListCell *c; + + if (spec->strategy != PARTITION_STRATEGY_LIST) + elog(ERROR, "invalid strategy in partition bound spec"); + + /* + * Note the index of the partition bound spec for the default + * partition. There's no datum to add to the list on non-null datums + * for this partition. + */ + if (spec->is_default) + { + default_index = i; + continue; + } + + foreach(c, spec->listdatums) + { + Const *val = castNode(Const, lfirst(c)); + PartitionListValue *list_value = NULL; + + if (!val->constisnull) + { + list_value = (PartitionListValue *) + palloc0(sizeof(PartitionListValue)); + list_value->index = i; + list_value->value = val->constvalue; + } + else + { + /* + * Never put a null into the values array, flag instead for + * the code further down below where we construct the actual + * relcache struct. + */ + if (null_index != -1) + elog(ERROR, "found null more than once"); + null_index = i; + } + + if (list_value) + non_null_values = lappend(non_null_values, list_value); + } + } + + ndatums = list_length(non_null_values); + + /* + * Collect all list values in one array. Alongside the value, we also save + * the index of partition the value comes from. + */ + all_values = (PartitionListValue **) + palloc(ndatums * sizeof(PartitionListValue *)); + i = 0; + foreach(cell, non_null_values) + { + PartitionListValue *src = lfirst(cell); + + all_values[i] = (PartitionListValue *) + palloc(sizeof(PartitionListValue)); + all_values[i]->value = src->value; + all_values[i]->index = src->index; + i++; + } + + qsort_arg(all_values, ndatums, sizeof(PartitionListValue *), + qsort_partition_list_value_cmp, (void *) key); + + boundinfo->ndatums = ndatums; + boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->indexes = (int *) palloc(ndatums * sizeof(int)); + + /* + * Copy values. Canonical indexes are values ranging from 0 to (nparts - + * 1) assigned to each partition such that all datums of a given partition + * receive the same value. The value for a given partition is the index of + * that partition's smallest datum in the all_values[] array. + */ + for (i = 0; i < ndatums; i++) + { + int orig_index = all_values[i]->index; + + boundinfo->datums[i] = (Datum *) palloc(sizeof(Datum)); + boundinfo->datums[i][0] = datumCopy(all_values[i]->value, + key->parttypbyval[0], + key->parttyplen[0]); + + /* If the old index has no mapping, assign one */ + if ((*mapping)[orig_index] == -1) + (*mapping)[orig_index] = next_index++; + + boundinfo->indexes[i] = (*mapping)[orig_index]; + } + + /* + * Set the canonical value for null_index, if any. + * + * It is possible that the null-accepting partition has not been assigned + * an index yet, which could happen if such partition accepts only null + * and hence not handled in the above loop which only looked at non-null + * values. + */ + if (null_index != -1) + { + Assert(null_index >= 0); + if ((*mapping)[null_index] == -1) + (*mapping)[null_index] = next_index++; + boundinfo->null_index = (*mapping)[null_index]; + } + + /* Set the canonical value for default_index, if any. */ + if (default_index != -1) + { + /* + * The default partition accepts any value not specified in the lists + * of other partitions, hence it should not get mapped index while + * assigning those for non-null datums. + */ + Assert(default_index >= 0); + Assert((*mapping)[default_index] == -1); + (*mapping)[default_index] = next_index++; + boundinfo->default_index = (*mapping)[default_index]; + } + + /* All partitions must now have been assigned canonical indexes. */ + Assert(next_index == nparts); + return boundinfo; +} + +/* + * create_range_bounds + * Create a PartitionBoundInfo for a range partitioned table + */ +static PartitionBoundInfo +create_range_bounds(PartitionBoundSpec **boundspecs, int nparts, + PartitionKey key, int **mapping) +{ + PartitionBoundInfo boundinfo; + PartitionRangeBound **rbounds = NULL; + PartitionRangeBound **all_bounds, + *prev; + int i, + k; + int ndatums = 0; + int default_index = -1; + int next_index = 0; + + boundinfo = (PartitionBoundInfoData *) + palloc0(sizeof(PartitionBoundInfoData)); + boundinfo->strategy = key->strategy; + /* There is no special null-accepting range partition. */ + boundinfo->null_index = -1; + /* Will be set correctly below. */ + boundinfo->default_index = -1; + + all_bounds = (PartitionRangeBound **) + palloc0(2 * nparts * sizeof(PartitionRangeBound *)); + + /* Create a unified list of range bounds across all the partitions. */ + ndatums = 0; + for (i = 0; i < nparts; i++) + { + PartitionBoundSpec *spec = boundspecs[i]; + PartitionRangeBound *lower, + *upper; + + if (spec->strategy != PARTITION_STRATEGY_RANGE) + elog(ERROR, "invalid strategy in partition bound spec"); + + /* + * Note the index of the partition bound spec for the default + * partition. There's no datum to add to the all_bounds array for + * this partition. + */ + if (spec->is_default) + { + default_index = i; + continue; + } + + lower = make_one_partition_rbound(key, i, spec->lowerdatums, true); + upper = make_one_partition_rbound(key, i, spec->upperdatums, false); + all_bounds[ndatums++] = lower; + all_bounds[ndatums++] = upper; + } + + Assert(ndatums == nparts * 2 || + (default_index != -1 && ndatums == (nparts - 1) * 2)); + + /* Sort all the bounds in ascending order */ + qsort_arg(all_bounds, ndatums, + sizeof(PartitionRangeBound *), + qsort_partition_rbound_cmp, + (void *) key); + + /* Save distinct bounds from all_bounds into rbounds. */ + rbounds = (PartitionRangeBound **) + palloc(ndatums * sizeof(PartitionRangeBound *)); + k = 0; + prev = NULL; + for (i = 0; i < ndatums; i++) + { + PartitionRangeBound *cur = all_bounds[i]; + bool is_distinct = false; + int j; + + /* Is the current bound distinct from the previous one? */ + for (j = 0; j < key->partnatts; j++) + { + Datum cmpval; + + if (prev == NULL || cur->kind[j] != prev->kind[j]) + { + is_distinct = true; + break; + } + + /* + * If the bounds are both MINVALUE or MAXVALUE, stop now and treat + * them as equal, since any values after this point must be + * ignored. + */ + if (cur->kind[j] != PARTITION_RANGE_DATUM_VALUE) + break; + + cmpval = FunctionCall2Coll(&key->partsupfunc[j], + key->partcollation[j], + cur->datums[j], + prev->datums[j]); + if (DatumGetInt32(cmpval) != 0) + { + is_distinct = true; + break; + } + } + + /* + * Only if the bound is distinct save it into a temporary array, i.e, + * rbounds which is later copied into boundinfo datums array. + */ + if (is_distinct) + rbounds[k++] = all_bounds[i]; + + prev = cur; + } + + /* Update ndatums to hold the count of distinct datums. */ + ndatums = k; + + /* + * Add datums to boundinfo. Canonical indexes are values ranging from 0 + * to nparts - 1, assigned in that order to each partition's upper bound. + * For 'datums' elements that are lower bounds, there is -1 in the + * 'indexes' array to signify that no partition exists for the values less + * than such a bound and greater than or equal to the previous upper + * bound. + */ + boundinfo->ndatums = ndatums; + boundinfo->datums = (Datum **) palloc0(ndatums * sizeof(Datum *)); + boundinfo->kind = (PartitionRangeDatumKind **) + palloc(ndatums * + sizeof(PartitionRangeDatumKind *)); + + /* + * For range partitioning, an additional value of -1 is stored as the last + * element. + */ + boundinfo->indexes = (int *) palloc((ndatums + 1) * sizeof(int)); + + for (i = 0; i < ndatums; i++) + { + int j; + + boundinfo->datums[i] = (Datum *) palloc(key->partnatts * + sizeof(Datum)); + boundinfo->kind[i] = (PartitionRangeDatumKind *) + palloc(key->partnatts * + sizeof(PartitionRangeDatumKind)); + for (j = 0; j < key->partnatts; j++) + { + if (rbounds[i]->kind[j] == PARTITION_RANGE_DATUM_VALUE) + boundinfo->datums[i][j] = + datumCopy(rbounds[i]->datums[j], + key->parttypbyval[j], + key->parttyplen[j]); + boundinfo->kind[i][j] = rbounds[i]->kind[j]; + } + + /* + * There is no mapping for invalid indexes. + * + * Any lower bounds in the rbounds array have invalid indexes + * assigned, because the values between the previous bound (if there + * is one) and this (lower) bound are not part of the range of any + * existing partition. + */ + if (rbounds[i]->lower) + boundinfo->indexes[i] = -1; + else + { + int orig_index = rbounds[i]->index; + + /* If the old index has no mapping, assign one */ + if ((*mapping)[orig_index] == -1) + (*mapping)[orig_index] = next_index++; + + boundinfo->indexes[i] = (*mapping)[orig_index]; + } + } + + /* Set the canonical value for default_index, if any. */ + if (default_index != -1) + { + Assert(default_index >= 0 && (*mapping)[default_index] == -1); + (*mapping)[default_index] = next_index++; + boundinfo->default_index = (*mapping)[default_index]; + } + + /* The extra -1 element. */ + Assert(i == ndatums); + boundinfo->indexes[i] = -1; + + /* All partitions must now have been assigned canonical indexes. */ + Assert(next_index == nparts); + return boundinfo; +} + +/* + * Are two partition bound collections logically equal? + * + * Used in the keep logic of relcache.c (ie, in RelationClearRelation()). + * This is also useful when b1 and b2 are bound collections of two separate + * relations, respectively, because PartitionBoundInfo is a canonical + * representation of partition bounds. + */ +bool +partition_bounds_equal(int partnatts, int16 *parttyplen, bool *parttypbyval, + PartitionBoundInfo b1, PartitionBoundInfo b2) +{ + int i; + + if (b1->strategy != b2->strategy) + return false; + + if (b1->ndatums != b2->ndatums) + return false; + + if (b1->null_index != b2->null_index) + return false; + + if (b1->default_index != b2->default_index) + return false; + + if (b1->strategy == PARTITION_STRATEGY_HASH) + { + int greatest_modulus = get_hash_partition_greatest_modulus(b1); + + /* + * If two hash partitioned tables have different greatest moduli, + * their partition schemes don't match. + */ + if (greatest_modulus != get_hash_partition_greatest_modulus(b2)) + return false; + + /* + * We arrange the partitions in the ascending order of their moduli + * and remainders. Also every modulus is factor of next larger + * modulus. Therefore we can safely store index of a given partition + * in indexes array at remainder of that partition. Also entries at + * (remainder + N * modulus) positions in indexes array are all same + * for (modulus, remainder) specification for any partition. Thus + * datums array from both the given bounds are same, if and only if + * their indexes array will be same. So, it suffices to compare + * indexes array. + */ + for (i = 0; i < greatest_modulus; i++) + if (b1->indexes[i] != b2->indexes[i]) + return false; + +#ifdef USE_ASSERT_CHECKING + + /* + * Nonetheless make sure that the bounds are indeed same when the + * indexes match. Hash partition bound stores modulus and remainder + * at b1->datums[i][0] and b1->datums[i][1] position respectively. + */ + for (i = 0; i < b1->ndatums; i++) + Assert((b1->datums[i][0] == b2->datums[i][0] && + b1->datums[i][1] == b2->datums[i][1])); +#endif + } + else + { + for (i = 0; i < b1->ndatums; i++) + { + int j; + + for (j = 0; j < partnatts; j++) + { + /* For range partitions, the bounds might not be finite. */ + if (b1->kind != NULL) + { + /* The different kinds of bound all differ from each other */ + if (b1->kind[i][j] != b2->kind[i][j]) + return false; + + /* + * Non-finite bounds are equal without further + * examination. + */ + if (b1->kind[i][j] != PARTITION_RANGE_DATUM_VALUE) + continue; + } + + /* + * Compare the actual values. Note that it would be both + * incorrect and unsafe to invoke the comparison operator + * derived from the partitioning specification here. It would + * be incorrect because we want the relcache entry to be + * updated for ANY change to the partition bounds, not just + * those that the partitioning operator thinks are + * significant. It would be unsafe because we might reach + * this code in the context of an aborted transaction, and an + * arbitrary partitioning operator might not be safe in that + * context. datumIsEqual() should be simple enough to be + * safe. + */ + if (!datumIsEqual(b1->datums[i][j], b2->datums[i][j], + parttypbyval[j], parttyplen[j])) + return false; + } + + if (b1->indexes[i] != b2->indexes[i]) + return false; + } + + /* There are ndatums+1 indexes in case of range partitions */ + if (b1->strategy == PARTITION_STRATEGY_RANGE && + b1->indexes[i] != b2->indexes[i]) + return false; + } + return true; +} + +/* + * Return a copy of given PartitionBoundInfo structure. The data types of bounds + * are described by given partition key specification. + */ +PartitionBoundInfo +partition_bounds_copy(PartitionBoundInfo src, + PartitionKey key) +{ + PartitionBoundInfo dest; + int i; + int ndatums; + int partnatts; + int num_indexes; + + dest = (PartitionBoundInfo) palloc(sizeof(PartitionBoundInfoData)); + + dest->strategy = src->strategy; + ndatums = dest->ndatums = src->ndatums; + partnatts = key->partnatts; + + num_indexes = get_partition_bound_num_indexes(src); + + /* List partitioned tables have only a single partition key. */ + Assert(key->strategy != PARTITION_STRATEGY_LIST || partnatts == 1); + + dest->datums = (Datum **) palloc(sizeof(Datum *) * ndatums); + + if (src->kind != NULL) + { + dest->kind = (PartitionRangeDatumKind **) palloc(ndatums * + sizeof(PartitionRangeDatumKind *)); + for (i = 0; i < ndatums; i++) + { + dest->kind[i] = (PartitionRangeDatumKind *) palloc(partnatts * + sizeof(PartitionRangeDatumKind)); + + memcpy(dest->kind[i], src->kind[i], + sizeof(PartitionRangeDatumKind) * key->partnatts); + } + } + else + dest->kind = NULL; + + for (i = 0; i < ndatums; i++) + { + int j; + + /* + * For a corresponding to hash partition, datums array will have two + * elements - modulus and remainder. + */ + bool hash_part = (key->strategy == PARTITION_STRATEGY_HASH); + int natts = hash_part ? 2 : partnatts; + + dest->datums[i] = (Datum *) palloc(sizeof(Datum) * natts); + + for (j = 0; j < natts; j++) + { + bool byval; + int typlen; + + if (hash_part) + { + typlen = sizeof(int32); /* Always int4 */ + byval = true; /* int4 is pass-by-value */ + } + else + { + byval = key->parttypbyval[j]; + typlen = key->parttyplen[j]; + } + + if (dest->kind == NULL || + dest->kind[i][j] == PARTITION_RANGE_DATUM_VALUE) + dest->datums[i][j] = datumCopy(src->datums[i][j], + byval, typlen); + } + } + + dest->indexes = (int *) palloc(sizeof(int) * num_indexes); + memcpy(dest->indexes, src->indexes, sizeof(int) * num_indexes); + + dest->null_index = src->null_index; + dest->default_index = src->default_index; + + return dest; +} + +/* + * partitions_are_ordered + * Determine whether the partitions described by 'boundinfo' are ordered, + * that is partitions appearing earlier in the PartitionDesc sequence + * contain partition keys strictly less than those appearing later. + * Also, if NULL values are possible, they must come in the last + * partition defined in the PartitionDesc. + * + * If out of order, or there is insufficient info to know the order, + * then we return false. + */ +bool +partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts) +{ + Assert(boundinfo != NULL); + + switch (boundinfo->strategy) + { + case PARTITION_STRATEGY_RANGE: + + /* + * RANGE-type partitioning guarantees that the partitions can be + * scanned in the order that they're defined in the PartitionDesc + * to provide sequential, non-overlapping ranges of tuples. + * However, if a DEFAULT partition exists then it doesn't work, as + * that could contain tuples from either below or above the + * defined range, or tuples belonging to gaps between partitions. + */ + if (!partition_bound_has_default(boundinfo)) + return true; + break; + + case PARTITION_STRATEGY_LIST: + + /* + * LIST partitioning can also guarantee ordering, but only if the + * partitions don't accept interleaved values. We could likely + * check for this by looping over the PartitionBound's indexes + * array to check that the indexes are in order. For now, let's + * just keep it simple and just accept LIST partitioning when + * there's no DEFAULT partition, exactly one value per partition, + * and optionally a NULL partition that does not accept any other + * values. Such a NULL partition will come last in the + * PartitionDesc, and the other partitions will be properly + * ordered. This is a cheap test to make as it does not require + * any per-partition processing. Maybe we'd like to handle more + * complex cases in the future. + */ + if (partition_bound_has_default(boundinfo)) + return false; + + if (boundinfo->ndatums + partition_bound_accepts_nulls(boundinfo) + == nparts) + return true; + break; + + default: + /* HASH, or some other strategy */ + break; + } + + return false; +} + +/* + * check_new_partition_bound + * + * Checks if the new partition's bound overlaps any of the existing partitions + * of parent. Also performs additional checks as necessary per strategy. + */ +void +check_new_partition_bound(char *relname, Relation parent, + PartitionBoundSpec *spec) +{ + PartitionKey key = RelationGetPartitionKey(parent); + PartitionDesc partdesc = RelationGetPartitionDesc(parent); + PartitionBoundInfo boundinfo = partdesc->boundinfo; + ParseState *pstate = make_parsestate(NULL); + int with = -1; + bool overlap = false; + + if (spec->is_default) + { + /* + * The default partition bound never conflicts with any other + * partition's; if that's what we're attaching, the only possible + * problem is that one already exists, so check for that and we're + * done. + */ + if (boundinfo == NULL || !partition_bound_has_default(boundinfo)) + return; + + /* Default partition already exists, error out. */ + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("partition \"%s\" conflicts with existing default partition \"%s\"", + relname, get_rel_name(partdesc->oids[boundinfo->default_index])), + parser_errposition(pstate, spec->location))); + } + + switch (key->strategy) + { + case PARTITION_STRATEGY_HASH: + { + Assert(spec->strategy == PARTITION_STRATEGY_HASH); + Assert(spec->remainder >= 0 && spec->remainder < spec->modulus); + + if (partdesc->nparts > 0) + { + Datum **datums = boundinfo->datums; + int ndatums = boundinfo->ndatums; + int greatest_modulus; + int remainder; + int offset; + bool valid_modulus = true; + int prev_modulus, /* Previous largest modulus */ + next_modulus; /* Next largest modulus */ + + /* + * Check rule that every modulus must be a factor of the + * next larger modulus. For example, if you have a bunch + * of partitions that all have modulus 5, you can add a + * new partition with modulus 10 or a new partition with + * modulus 15, but you cannot add both a partition with + * modulus 10 and a partition with modulus 15, because 10 + * is not a factor of 15. + * + * Get the greatest (modulus, remainder) pair contained in + * boundinfo->datums that is less than or equal to the + * (spec->modulus, spec->remainder) pair. + */ + offset = partition_hash_bsearch(boundinfo, + spec->modulus, + spec->remainder); + if (offset < 0) + { + next_modulus = DatumGetInt32(datums[0][0]); + valid_modulus = (next_modulus % spec->modulus) == 0; + } + else + { + prev_modulus = DatumGetInt32(datums[offset][0]); + valid_modulus = (spec->modulus % prev_modulus) == 0; + + if (valid_modulus && (offset + 1) < ndatums) + { + next_modulus = DatumGetInt32(datums[offset + 1][0]); + valid_modulus = (next_modulus % spec->modulus) == 0; + } + } + + if (!valid_modulus) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("every hash partition modulus must be a factor of the next larger modulus"))); + + greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); + remainder = spec->remainder; + + /* + * Normally, the lowest remainder that could conflict with + * the new partition is equal to the remainder specified + * for the new partition, but when the new partition has a + * modulus higher than any used so far, we need to adjust. + */ + if (remainder >= greatest_modulus) + remainder = remainder % greatest_modulus; + + /* Check every potentially-conflicting remainder. */ + do + { + if (boundinfo->indexes[remainder] != -1) + { + overlap = true; + with = boundinfo->indexes[remainder]; + break; + } + remainder += spec->modulus; + } while (remainder < greatest_modulus); + } + + break; + } + + case PARTITION_STRATEGY_LIST: + { + Assert(spec->strategy == PARTITION_STRATEGY_LIST); + + if (partdesc->nparts > 0) + { + ListCell *cell; + + Assert(boundinfo && + boundinfo->strategy == PARTITION_STRATEGY_LIST && + (boundinfo->ndatums > 0 || + partition_bound_accepts_nulls(boundinfo) || + partition_bound_has_default(boundinfo))); + + foreach(cell, spec->listdatums) + { + Const *val = castNode(Const, lfirst(cell)); + + if (!val->constisnull) + { + int offset; + bool equal; + + offset = partition_list_bsearch(&key->partsupfunc[0], + key->partcollation, + boundinfo, + val->constvalue, + &equal); + if (offset >= 0 && equal) + { + overlap = true; + with = boundinfo->indexes[offset]; + break; + } + } + else if (partition_bound_accepts_nulls(boundinfo)) + { + overlap = true; + with = boundinfo->null_index; + break; + } + } + } + + break; + } + + case PARTITION_STRATEGY_RANGE: + { + PartitionRangeBound *lower, + *upper; + + Assert(spec->strategy == PARTITION_STRATEGY_RANGE); + lower = make_one_partition_rbound(key, -1, spec->lowerdatums, true); + upper = make_one_partition_rbound(key, -1, spec->upperdatums, false); + + /* + * First check if the resulting range would be empty with + * specified lower and upper bounds + */ + if (partition_rbound_cmp(key->partnatts, key->partsupfunc, + key->partcollation, lower->datums, + lower->kind, true, upper) >= 0) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("empty range bound specified for partition \"%s\"", + relname), + errdetail("Specified lower bound %s is greater than or equal to upper bound %s.", + get_range_partbound_string(spec->lowerdatums), + get_range_partbound_string(spec->upperdatums)), + parser_errposition(pstate, spec->location))); + } + + if (partdesc->nparts > 0) + { + int offset; + bool equal; + + Assert(boundinfo && + boundinfo->strategy == PARTITION_STRATEGY_RANGE && + (boundinfo->ndatums > 0 || + partition_bound_has_default(boundinfo))); + + /* + * Test whether the new lower bound (which is treated + * inclusively as part of the new partition) lies inside + * an existing partition, or in a gap. + * + * If it's inside an existing partition, the bound at + * offset + 1 will be the upper bound of that partition, + * and its index will be >= 0. + * + * If it's in a gap, the bound at offset + 1 will be the + * lower bound of the next partition, and its index will + * be -1. This is also true if there is no next partition, + * since the index array is initialised with an extra -1 + * at the end. + */ + offset = partition_range_bsearch(key->partnatts, + key->partsupfunc, + key->partcollation, + boundinfo, lower, + &equal); + + if (boundinfo->indexes[offset + 1] < 0) + { + /* + * Check that the new partition will fit in the gap. + * For it to fit, the new upper bound must be less + * than or equal to the lower bound of the next + * partition, if there is one. + */ + if (offset + 1 < boundinfo->ndatums) + { + int32 cmpval; + Datum *datums; + PartitionRangeDatumKind *kind; + bool is_lower; + + datums = boundinfo->datums[offset + 1]; + kind = boundinfo->kind[offset + 1]; + is_lower = (boundinfo->indexes[offset + 1] == -1); + + cmpval = partition_rbound_cmp(key->partnatts, + key->partsupfunc, + key->partcollation, + datums, kind, + is_lower, upper); + if (cmpval < 0) + { + /* + * The new partition overlaps with the + * existing partition between offset + 1 and + * offset + 2. + */ + overlap = true; + with = boundinfo->indexes[offset + 2]; + } + } + } + else + { + /* + * The new partition overlaps with the existing + * partition between offset and offset + 1. + */ + overlap = true; + with = boundinfo->indexes[offset + 1]; + } + } + + break; + } + + default: + elog(ERROR, "unexpected partition strategy: %d", + (int) key->strategy); + } + + if (overlap) + { + Assert(with >= 0); + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("partition \"%s\" would overlap partition \"%s\"", + relname, get_rel_name(partdesc->oids[with])), + parser_errposition(pstate, spec->location))); + } +} + +/* + * check_default_partition_contents + * + * This function checks if there exists a row in the default partition that + * would properly belong to the new partition being added. If it finds one, + * it throws an error. + */ +void +check_default_partition_contents(Relation parent, Relation default_rel, + PartitionBoundSpec *new_spec) +{ + List *new_part_constraints; + List *def_part_constraints; + List *all_parts; + ListCell *lc; + + new_part_constraints = (new_spec->strategy == PARTITION_STRATEGY_LIST) + ? get_qual_for_list(parent, new_spec) + : get_qual_for_range(parent, new_spec, false); + def_part_constraints = + get_proposed_default_constraint(new_part_constraints); + + /* + * Map the Vars in the constraint expression from parent's attnos to + * default_rel's. + */ + def_part_constraints = + map_partition_varattnos(def_part_constraints, 1, default_rel, + parent, NULL); + + /* + * If the existing constraints on the default partition imply that it will + * not contain any row that would belong to the new partition, we can + * avoid scanning the default partition. + */ + if (PartConstraintImpliedByRelConstraint(default_rel, def_part_constraints)) + { + ereport(DEBUG1, + (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", + RelationGetRelationName(default_rel)))); + return; + } + + /* + * Scan the default partition and its subpartitions, and check for rows + * that do not satisfy the revised partition constraints. + */ + if (default_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) + all_parts = find_all_inheritors(RelationGetRelid(default_rel), + AccessExclusiveLock, NULL); + else + all_parts = list_make1_oid(RelationGetRelid(default_rel)); + + foreach(lc, all_parts) + { + Oid part_relid = lfirst_oid(lc); + Relation part_rel; + Expr *partition_constraint; + EState *estate; + ExprState *partqualstate = NULL; + Snapshot snapshot; + ExprContext *econtext; + TableScanDesc scan; + MemoryContext oldCxt; + TupleTableSlot *tupslot; + + /* Lock already taken above. */ + if (part_relid != RelationGetRelid(default_rel)) + { + part_rel = table_open(part_relid, NoLock); + + /* + * Map the Vars in the constraint expression from default_rel's + * the sub-partition's. + */ + partition_constraint = make_ands_explicit(def_part_constraints); + partition_constraint = (Expr *) + map_partition_varattnos((List *) partition_constraint, 1, + part_rel, default_rel, NULL); + + /* + * If the partition constraints on default partition child imply + * that it will not contain any row that would belong to the new + * partition, we can avoid scanning the child table. + */ + if (PartConstraintImpliedByRelConstraint(part_rel, + def_part_constraints)) + { + ereport(DEBUG1, + (errmsg("updated partition constraint for default partition \"%s\" is implied by existing constraints", + RelationGetRelationName(part_rel)))); + + table_close(part_rel, NoLock); + continue; + } + } + else + { + part_rel = default_rel; + partition_constraint = make_ands_explicit(def_part_constraints); + } + + /* + * Only RELKIND_RELATION relations (i.e. leaf partitions) need to be + * scanned. + */ + if (part_rel->rd_rel->relkind != RELKIND_RELATION) + { + if (part_rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE) + ereport(WARNING, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"", + RelationGetRelationName(part_rel), + RelationGetRelationName(default_rel)))); + + if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel)) + table_close(part_rel, NoLock); + + continue; + } + + estate = CreateExecutorState(); + + /* Build expression execution states for partition check quals */ + partqualstate = ExecPrepareExpr(partition_constraint, estate); + + econtext = GetPerTupleExprContext(estate); + snapshot = RegisterSnapshot(GetLatestSnapshot()); + tupslot = table_slot_create(part_rel, &estate->es_tupleTable); + scan = table_beginscan(part_rel, snapshot, 0, NULL); + + /* + * Switch to per-tuple memory context and reset it for each tuple + * produced, so we don't leak memory. + */ + oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); + + while (table_scan_getnextslot(scan, ForwardScanDirection, tupslot)) + { + econtext->ecxt_scantuple = tupslot; + + if (!ExecCheck(partqualstate, econtext)) + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("updated partition constraint for default partition \"%s\" would be violated by some row", + RelationGetRelationName(default_rel)))); + + ResetExprContext(econtext); + CHECK_FOR_INTERRUPTS(); + } + + MemoryContextSwitchTo(oldCxt); + table_endscan(scan); + UnregisterSnapshot(snapshot); + ExecDropSingleTupleTableSlot(tupslot); + FreeExecutorState(estate); + + if (RelationGetRelid(default_rel) != RelationGetRelid(part_rel)) + table_close(part_rel, NoLock); /* keep the lock until commit */ + } +} + +/* + * get_hash_partition_greatest_modulus + * + * Returns the greatest modulus of the hash partition bound. The greatest + * modulus will be at the end of the datums array because hash partitions are + * arranged in the ascending order of their moduli and remainders. + */ +int +get_hash_partition_greatest_modulus(PartitionBoundInfo bound) +{ + Assert(bound && bound->strategy == PARTITION_STRATEGY_HASH); + Assert(bound->datums && bound->ndatums > 0); + Assert(DatumGetInt32(bound->datums[bound->ndatums - 1][0]) > 0); + + return DatumGetInt32(bound->datums[bound->ndatums - 1][0]); +} + +/* + * make_one_partition_rbound + * + * Return a PartitionRangeBound given a list of PartitionRangeDatum elements + * and a flag telling whether the bound is lower or not. Made into a function + * because there are multiple sites that want to use this facility. + */ +static PartitionRangeBound * +make_one_partition_rbound(PartitionKey key, int index, List *datums, bool lower) +{ + PartitionRangeBound *bound; + ListCell *lc; + int i; + + Assert(datums != NIL); + + bound = (PartitionRangeBound *) palloc0(sizeof(PartitionRangeBound)); + bound->index = index; + bound->datums = (Datum *) palloc0(key->partnatts * sizeof(Datum)); + bound->kind = (PartitionRangeDatumKind *) palloc0(key->partnatts * + sizeof(PartitionRangeDatumKind)); + bound->lower = lower; + + i = 0; + foreach(lc, datums) + { + PartitionRangeDatum *datum = castNode(PartitionRangeDatum, lfirst(lc)); + + /* What's contained in this range datum? */ + bound->kind[i] = datum->kind; + + if (datum->kind == PARTITION_RANGE_DATUM_VALUE) + { + Const *val = castNode(Const, datum->value); + + if (val->constisnull) + elog(ERROR, "invalid range bound datum"); + bound->datums[i] = val->constvalue; + } + + i++; + } + + return bound; +} + +/* + * partition_rbound_cmp + * + * Return for two range bounds whether the 1st one (specified in datums1, + * kind1, and lower1) is <, =, or > the bound specified in *b2. + * + * partnatts, partsupfunc and partcollation give the number of attributes in the + * bounds to be compared, comparison function to be used and the collations of + * attributes, respectively. + * + * Note that if the values of the two range bounds compare equal, then we take + * into account whether they are upper or lower bounds, and an upper bound is + * considered to be smaller than a lower bound. This is important to the way + * that RelationBuildPartitionDesc() builds the PartitionBoundInfoData + * structure, which only stores the upper bound of a common boundary between + * two contiguous partitions. + */ +static int32 +partition_rbound_cmp(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, + Datum *datums1, PartitionRangeDatumKind *kind1, + bool lower1, PartitionRangeBound *b2) +{ + int32 cmpval = 0; /* placate compiler */ + int i; + Datum *datums2 = b2->datums; + PartitionRangeDatumKind *kind2 = b2->kind; + bool lower2 = b2->lower; + + for (i = 0; i < partnatts; i++) + { + /* + * First, handle cases where the column is unbounded, which should not + * invoke the comparison procedure, and should not consider any later + * columns. Note that the PartitionRangeDatumKind enum elements + * compare the same way as the values they represent. + */ + if (kind1[i] < kind2[i]) + return -1; + else if (kind1[i] > kind2[i]) + return 1; + else if (kind1[i] != PARTITION_RANGE_DATUM_VALUE) + + /* + * The column bounds are both MINVALUE or both MAXVALUE. No later + * columns should be considered, but we still need to compare + * whether they are upper or lower bounds. + */ + break; + + cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i], + partcollation[i], + datums1[i], + datums2[i])); + if (cmpval != 0) + break; + } + + /* + * If the comparison is anything other than equal, we're done. If they + * compare equal though, we still have to consider whether the boundaries + * are inclusive or exclusive. Exclusive one is considered smaller of the + * two. + */ + if (cmpval == 0 && lower1 != lower2) + cmpval = lower1 ? 1 : -1; + + return cmpval; +} + +/* + * partition_rbound_datum_cmp + * + * Return whether range bound (specified in rb_datums and rb_kind) + * is <, =, or > partition key of tuple (tuple_datums) + * + * n_tuple_datums, partsupfunc and partcollation give number of attributes in + * the bounds to be compared, comparison function to be used and the collations + * of attributes resp. + * + */ +int32 +partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, + Datum *rb_datums, PartitionRangeDatumKind *rb_kind, + Datum *tuple_datums, int n_tuple_datums) +{ + int i; + int32 cmpval = -1; + + for (i = 0; i < n_tuple_datums; i++) + { + if (rb_kind[i] == PARTITION_RANGE_DATUM_MINVALUE) + return -1; + else if (rb_kind[i] == PARTITION_RANGE_DATUM_MAXVALUE) + return 1; + + cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[i], + partcollation[i], + rb_datums[i], + tuple_datums[i])); + if (cmpval != 0) + break; + } + + return cmpval; +} + +/* + * partition_hbound_cmp + * + * Compares modulus first, then remainder if modulus is equal. + */ +static int32 +partition_hbound_cmp(int modulus1, int remainder1, int modulus2, int remainder2) +{ + if (modulus1 < modulus2) + return -1; + if (modulus1 > modulus2) + return 1; + if (modulus1 == modulus2 && remainder1 != remainder2) + return (remainder1 > remainder2) ? 1 : -1; + return 0; +} + +/* + * partition_list_bsearch + * Returns the index of the greatest bound datum that is less than equal + * to the given value or -1 if all of the bound datums are greater + * + * *is_equal is set to true if the bound datum at the returned index is equal + * to the input value. + */ +int +partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, + PartitionBoundInfo boundinfo, + Datum value, bool *is_equal) +{ + int lo, + hi, + mid; + + lo = -1; + hi = boundinfo->ndatums - 1; + while (lo < hi) + { + int32 cmpval; + + mid = (lo + hi + 1) / 2; + cmpval = DatumGetInt32(FunctionCall2Coll(&partsupfunc[0], + partcollation[0], + boundinfo->datums[mid][0], + value)); + if (cmpval <= 0) + { + lo = mid; + *is_equal = (cmpval == 0); + if (*is_equal) + break; + } + else + hi = mid - 1; + } + + return lo; +} + +/* + * partition_range_bsearch + * Returns the index of the greatest range bound that is less than or + * equal to the given range bound or -1 if all of the range bounds are + * greater + * + * *is_equal is set to true if the range bound at the returned index is equal + * to the input range bound + */ +static int +partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + PartitionRangeBound *probe, bool *is_equal) +{ + int lo, + hi, + mid; + + lo = -1; + hi = boundinfo->ndatums - 1; + while (lo < hi) + { + int32 cmpval; + + mid = (lo + hi + 1) / 2; + cmpval = partition_rbound_cmp(partnatts, partsupfunc, + partcollation, + boundinfo->datums[mid], + boundinfo->kind[mid], + (boundinfo->indexes[mid] == -1), + probe); + if (cmpval <= 0) + { + lo = mid; + *is_equal = (cmpval == 0); + + if (*is_equal) + break; + } + else + hi = mid - 1; + } + + return lo; +} + +/* + * partition_range_bsearch + * Returns the index of the greatest range bound that is less than or + * equal to the given tuple or -1 if all of the range bounds are greater + * + * *is_equal is set to true if the range bound at the returned index is equal + * to the input tuple. + */ +int +partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, + PartitionBoundInfo boundinfo, + int nvalues, Datum *values, bool *is_equal) +{ + int lo, + hi, + mid; + + lo = -1; + hi = boundinfo->ndatums - 1; + while (lo < hi) + { + int32 cmpval; + + mid = (lo + hi + 1) / 2; + cmpval = partition_rbound_datum_cmp(partsupfunc, + partcollation, + boundinfo->datums[mid], + boundinfo->kind[mid], + values, + nvalues); + if (cmpval <= 0) + { + lo = mid; + *is_equal = (cmpval == 0); + + if (*is_equal) + break; + } + else + hi = mid - 1; + } + + return lo; +} + +/* + * partition_hash_bsearch + * Returns the index of the greatest (modulus, remainder) pair that is + * less than or equal to the given (modulus, remainder) pair or -1 if + * all of them are greater + */ +int +partition_hash_bsearch(PartitionBoundInfo boundinfo, + int modulus, int remainder) +{ + int lo, + hi, + mid; + + lo = -1; + hi = boundinfo->ndatums - 1; + while (lo < hi) + { + int32 cmpval, + bound_modulus, + bound_remainder; + + mid = (lo + hi + 1) / 2; + bound_modulus = DatumGetInt32(boundinfo->datums[mid][0]); + bound_remainder = DatumGetInt32(boundinfo->datums[mid][1]); + cmpval = partition_hbound_cmp(bound_modulus, bound_remainder, + modulus, remainder); + if (cmpval <= 0) + { + lo = mid; + + if (cmpval == 0) + break; + } + else + hi = mid - 1; + } + + return lo; +} + +/* + * qsort_partition_hbound_cmp + * + * Hash bounds are sorted by modulus, then by remainder. + */ +static int32 +qsort_partition_hbound_cmp(const void *a, const void *b) +{ + PartitionHashBound *h1 = (*(PartitionHashBound *const *) a); + PartitionHashBound *h2 = (*(PartitionHashBound *const *) b); + + return partition_hbound_cmp(h1->modulus, h1->remainder, + h2->modulus, h2->remainder); +} + +/* + * qsort_partition_list_value_cmp + * + * Compare two list partition bound datums. + */ +static int32 +qsort_partition_list_value_cmp(const void *a, const void *b, void *arg) +{ + Datum val1 = (*(PartitionListValue *const *) a)->value, + val2 = (*(PartitionListValue *const *) b)->value; + PartitionKey key = (PartitionKey) arg; + + return DatumGetInt32(FunctionCall2Coll(&key->partsupfunc[0], + key->partcollation[0], + val1, val2)); +} + +/* + * qsort_partition_rbound_cmp + * + * Used when sorting range bounds across all range partitions. + */ +static int32 +qsort_partition_rbound_cmp(const void *a, const void *b, void *arg) +{ + PartitionRangeBound *b1 = (*(PartitionRangeBound *const *) a); + PartitionRangeBound *b2 = (*(PartitionRangeBound *const *) b); + PartitionKey key = (PartitionKey) arg; + + return partition_rbound_cmp(key->partnatts, key->partsupfunc, + key->partcollation, b1->datums, b1->kind, + b1->lower, b2); +} + +/* + * get_partition_bound_num_indexes + * + * Returns the number of the entries in the partition bound indexes array. + */ +static int +get_partition_bound_num_indexes(PartitionBoundInfo bound) +{ + int num_indexes; + + Assert(bound); + + switch (bound->strategy) + { + case PARTITION_STRATEGY_HASH: + + /* + * The number of the entries in the indexes array is same as the + * greatest modulus. + */ + num_indexes = get_hash_partition_greatest_modulus(bound); + break; + + case PARTITION_STRATEGY_LIST: + num_indexes = bound->ndatums; + break; + + case PARTITION_STRATEGY_RANGE: + /* Range partitioned table has an extra index. */ + num_indexes = bound->ndatums + 1; + break; + + default: + elog(ERROR, "unexpected partition strategy: %d", + (int) bound->strategy); + } + + return num_indexes; +} + +/* + * get_partition_operator + * + * Return oid of the operator of the given strategy for the given partition + * key column. It is assumed that the partitioning key is of the same type as + * the chosen partitioning opclass, or at least binary-compatible. In the + * latter case, *need_relabel is set to true if the opclass is not of a + * polymorphic type (indicating a RelabelType node needed on top), otherwise + * false. + */ +static Oid +get_partition_operator(PartitionKey key, int col, StrategyNumber strategy, + bool *need_relabel) +{ + Oid operoid; + + /* + * Get the operator in the partitioning opfamily using the opclass' + * declared input type as both left- and righttype. + */ + operoid = get_opfamily_member(key->partopfamily[col], + key->partopcintype[col], + key->partopcintype[col], + strategy); + if (!OidIsValid(operoid)) + elog(ERROR, "missing operator %d(%u,%u) in partition opfamily %u", + strategy, key->partopcintype[col], key->partopcintype[col], + key->partopfamily[col]); + + /* + * If the partition key column is not of the same type as the operator + * class and not polymorphic, tell caller to wrap the non-Const expression + * in a RelabelType. This matches what parse_coerce.c does. + */ + *need_relabel = (key->parttypid[col] != key->partopcintype[col] && + key->partopcintype[col] != RECORDOID && + !IsPolymorphicType(key->partopcintype[col])); + + return operoid; +} + +/* + * make_partition_op_expr + * Returns an Expr for the given partition key column with arg1 and + * arg2 as its leftop and rightop, respectively + */ +static Expr * +make_partition_op_expr(PartitionKey key, int keynum, + uint16 strategy, Expr *arg1, Expr *arg2) +{ + Oid operoid; + bool need_relabel = false; + Expr *result = NULL; + + /* Get the correct btree operator for this partitioning column */ + operoid = get_partition_operator(key, keynum, strategy, &need_relabel); + + /* + * Chosen operator may be such that the non-Const operand needs to be + * coerced, so apply the same; see the comment in + * get_partition_operator(). + */ + if (!IsA(arg1, Const) && + (need_relabel || + key->partcollation[keynum] != key->parttypcoll[keynum])) + arg1 = (Expr *) makeRelabelType(arg1, + key->partopcintype[keynum], + -1, + key->partcollation[keynum], + COERCE_EXPLICIT_CAST); + + /* Generate the actual expression */ + switch (key->strategy) + { + case PARTITION_STRATEGY_LIST: + { + List *elems = (List *) arg2; + int nelems = list_length(elems); + + Assert(nelems >= 1); + Assert(keynum == 0); + + if (nelems > 1 && + !type_is_array(key->parttypid[keynum])) + { + ArrayExpr *arrexpr; + ScalarArrayOpExpr *saopexpr; + + /* Construct an ArrayExpr for the right-hand inputs */ + arrexpr = makeNode(ArrayExpr); + arrexpr->array_typeid = + get_array_type(key->parttypid[keynum]); + arrexpr->array_collid = key->parttypcoll[keynum]; + arrexpr->element_typeid = key->parttypid[keynum]; + arrexpr->elements = elems; + arrexpr->multidims = false; + arrexpr->location = -1; + + /* Build leftop = ANY (rightop) */ + saopexpr = makeNode(ScalarArrayOpExpr); + saopexpr->opno = operoid; + saopexpr->opfuncid = get_opcode(operoid); + saopexpr->useOr = true; + saopexpr->inputcollid = key->partcollation[keynum]; + saopexpr->args = list_make2(arg1, arrexpr); + saopexpr->location = -1; + + result = (Expr *) saopexpr; + } + else + { + List *elemops = NIL; + ListCell *lc; + + foreach(lc, elems) + { + Expr *elem = lfirst(lc), + *elemop; + + elemop = make_opclause(operoid, + BOOLOID, + false, + arg1, elem, + InvalidOid, + key->partcollation[keynum]); + elemops = lappend(elemops, elemop); + } + + result = nelems > 1 ? makeBoolExpr(OR_EXPR, elemops, -1) : linitial(elemops); + } + break; + } + + case PARTITION_STRATEGY_RANGE: + result = make_opclause(operoid, + BOOLOID, + false, + arg1, arg2, + InvalidOid, + key->partcollation[keynum]); + break; + + default: + elog(ERROR, "invalid partitioning strategy"); + break; + } + + return result; +} + +/* + * get_qual_for_hash + * + * Returns a CHECK constraint expression to use as a hash partition's + * constraint, given the parent relation and partition bound structure. + * + * The partition constraint for a hash partition is always a call to the + * built-in function satisfies_hash_partition(). + */ +static List * +get_qual_for_hash(Relation parent, PartitionBoundSpec *spec) +{ + PartitionKey key = RelationGetPartitionKey(parent); + FuncExpr *fexpr; + Node *relidConst; + Node *modulusConst; + Node *remainderConst; + List *args; + ListCell *partexprs_item; + int i; + + /* Fixed arguments. */ + relidConst = (Node *) makeConst(OIDOID, + -1, + InvalidOid, + sizeof(Oid), + ObjectIdGetDatum(RelationGetRelid(parent)), + false, + true); + + modulusConst = (Node *) makeConst(INT4OID, + -1, + InvalidOid, + sizeof(int32), + Int32GetDatum(spec->modulus), + false, + true); + + remainderConst = (Node *) makeConst(INT4OID, + -1, + InvalidOid, + sizeof(int32), + Int32GetDatum(spec->remainder), + false, + true); + + args = list_make3(relidConst, modulusConst, remainderConst); + partexprs_item = list_head(key->partexprs); + + /* Add an argument for each key column. */ + for (i = 0; i < key->partnatts; i++) + { + Node *keyCol; + + /* Left operand */ + if (key->partattrs[i] != 0) + { + keyCol = (Node *) makeVar(1, + key->partattrs[i], + key->parttypid[i], + key->parttypmod[i], + key->parttypcoll[i], + 0); + } + else + { + keyCol = (Node *) copyObject(lfirst(partexprs_item)); + partexprs_item = lnext(key->partexprs, partexprs_item); + } + + args = lappend(args, keyCol); + } + + fexpr = makeFuncExpr(F_SATISFIES_HASH_PARTITION, + BOOLOID, + args, + InvalidOid, + InvalidOid, + COERCE_EXPLICIT_CALL); + + return list_make1(fexpr); +} + +/* + * get_qual_for_list + * + * Returns an implicit-AND list of expressions to use as a list partition's + * constraint, given the parent relation and partition bound structure. + * + * The function returns NIL for a default partition when it's the only + * partition since in that case there is no constraint. + */ +static List * +get_qual_for_list(Relation parent, PartitionBoundSpec *spec) +{ + PartitionKey key = RelationGetPartitionKey(parent); + List *result; + Expr *keyCol; + Expr *opexpr; + NullTest *nulltest; + ListCell *cell; + List *elems = NIL; + bool list_has_null = false; + + /* + * Only single-column list partitioning is supported, so we are worried + * only about the partition key with index 0. + */ + Assert(key->partnatts == 1); + + /* Construct Var or expression representing the partition column */ + if (key->partattrs[0] != 0) + keyCol = (Expr *) makeVar(1, + key->partattrs[0], + key->parttypid[0], + key->parttypmod[0], + key->parttypcoll[0], + 0); + else + keyCol = (Expr *) copyObject(linitial(key->partexprs)); + + /* + * For default list partition, collect datums for all the partitions. The + * default partition constraint should check that the partition key is + * equal to none of those. + */ + if (spec->is_default) + { + int i; + int ndatums = 0; + PartitionDesc pdesc = RelationGetPartitionDesc(parent); + PartitionBoundInfo boundinfo = pdesc->boundinfo; + + if (boundinfo) + { + ndatums = boundinfo->ndatums; + + if (partition_bound_accepts_nulls(boundinfo)) + list_has_null = true; + } + + /* + * If default is the only partition, there need not be any partition + * constraint on it. + */ + if (ndatums == 0 && !list_has_null) + return NIL; + + for (i = 0; i < ndatums; i++) + { + Const *val; + + /* + * Construct Const from known-not-null datum. We must be careful + * to copy the value, because our result has to be able to outlive + * the relcache entry we're copying from. + */ + val = makeConst(key->parttypid[0], + key->parttypmod[0], + key->parttypcoll[0], + key->parttyplen[0], + datumCopy(*boundinfo->datums[i], + key->parttypbyval[0], + key->parttyplen[0]), + false, /* isnull */ + key->parttypbyval[0]); + + elems = lappend(elems, val); + } + } + else + { + /* + * Create list of Consts for the allowed values, excluding any nulls. + */ + foreach(cell, spec->listdatums) + { + Const *val = castNode(Const, lfirst(cell)); + + if (val->constisnull) + list_has_null = true; + else + elems = lappend(elems, copyObject(val)); + } + } + + if (elems) + { + /* + * Generate the operator expression from the non-null partition + * values. + */ + opexpr = make_partition_op_expr(key, 0, BTEqualStrategyNumber, + keyCol, (Expr *) elems); + } + else + { + /* + * If there are no partition values, we don't need an operator + * expression. + */ + opexpr = NULL; + } + + if (!list_has_null) + { + /* + * Gin up a "col IS NOT NULL" test that will be AND'd with the main + * expression. This might seem redundant, but the partition routing + * machinery needs it. + */ + nulltest = makeNode(NullTest); + nulltest->arg = keyCol; + nulltest->nulltesttype = IS_NOT_NULL; + nulltest->argisrow = false; + nulltest->location = -1; + + result = opexpr ? list_make2(nulltest, opexpr) : list_make1(nulltest); + } + else + { + /* + * Gin up a "col IS NULL" test that will be OR'd with the main + * expression. + */ + nulltest = makeNode(NullTest); + nulltest->arg = keyCol; + nulltest->nulltesttype = IS_NULL; + nulltest->argisrow = false; + nulltest->location = -1; + + if (opexpr) + { + Expr *or; + + or = makeBoolExpr(OR_EXPR, list_make2(nulltest, opexpr), -1); + result = list_make1(or); + } + else + result = list_make1(nulltest); + } + + /* + * Note that, in general, applying NOT to a constraint expression doesn't + * necessarily invert the set of rows it accepts, because NOT (NULL) is + * NULL. However, the partition constraints we construct here never + * evaluate to NULL, so applying NOT works as intended. + */ + if (spec->is_default) + { + result = list_make1(make_ands_explicit(result)); + result = list_make1(makeBoolExpr(NOT_EXPR, result, -1)); + } + + return result; +} + +/* + * get_qual_for_range + * + * Returns an implicit-AND list of expressions to use as a range partition's + * constraint, given the parent relation and partition bound structure. + * + * For a multi-column range partition key, say (a, b, c), with (al, bl, cl) + * as the lower bound tuple and (au, bu, cu) as the upper bound tuple, we + * generate an expression tree of the following form: + * + * (a IS NOT NULL) and (b IS NOT NULL) and (c IS NOT NULL) + * AND + * (a > al OR (a = al AND b > bl) OR (a = al AND b = bl AND c >= cl)) + * AND + * (a < au OR (a = au AND b < bu) OR (a = au AND b = bu AND c < cu)) + * + * It is often the case that a prefix of lower and upper bound tuples contains + * the same values, for example, (al = au), in which case, we will emit an + * expression tree of the following form: + * + * (a IS NOT NULL) and (b IS NOT NULL) and (c IS NOT NULL) + * AND + * (a = al) + * AND + * (b > bl OR (b = bl AND c >= cl)) + * AND + * (b < bu) OR (b = bu AND c < cu)) + * + * If a bound datum is either MINVALUE or MAXVALUE, these expressions are + * simplified using the fact that any value is greater than MINVALUE and less + * than MAXVALUE. So, for example, if cu = MAXVALUE, c < cu is automatically + * true, and we need not emit any expression for it, and the last line becomes + * + * (b < bu) OR (b = bu), which is simplified to (b <= bu) + * + * In most common cases with only one partition column, say a, the following + * expression tree will be generated: a IS NOT NULL AND a >= al AND a < au + * + * For default partition, it returns the negation of the constraints of all + * the other partitions. + * + * External callers should pass for_default as false; we set it to true only + * when recursing. + */ +static List * +get_qual_for_range(Relation parent, PartitionBoundSpec *spec, + bool for_default) +{ + List *result = NIL; + ListCell *cell1, + *cell2, + *partexprs_item, + *partexprs_item_saved; + int i, + j; + PartitionRangeDatum *ldatum, + *udatum; + PartitionKey key = RelationGetPartitionKey(parent); + Expr *keyCol; + Const *lower_val, + *upper_val; + List *lower_or_arms, + *upper_or_arms; + int num_or_arms, + current_or_arm; + ListCell *lower_or_start_datum, + *upper_or_start_datum; + bool need_next_lower_arm, + need_next_upper_arm; + + if (spec->is_default) + { + List *or_expr_args = NIL; + PartitionDesc pdesc = RelationGetPartitionDesc(parent); + Oid *inhoids = pdesc->oids; + int nparts = pdesc->nparts, + i; + + for (i = 0; i < nparts; i++) + { + Oid inhrelid = inhoids[i]; + HeapTuple tuple; + Datum datum; + bool isnull; + PartitionBoundSpec *bspec; + + tuple = SearchSysCache1(RELOID, inhrelid); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", inhrelid); + + datum = SysCacheGetAttr(RELOID, tuple, + Anum_pg_class_relpartbound, + &isnull); + if (isnull) + elog(ERROR, "null relpartbound for relation %u", inhrelid); + + bspec = (PartitionBoundSpec *) + stringToNode(TextDatumGetCString(datum)); + if (!IsA(bspec, PartitionBoundSpec)) + elog(ERROR, "expected PartitionBoundSpec"); + + if (!bspec->is_default) + { + List *part_qual; + + part_qual = get_qual_for_range(parent, bspec, true); + + /* + * AND the constraints of the partition and add to + * or_expr_args + */ + or_expr_args = lappend(or_expr_args, list_length(part_qual) > 1 + ? makeBoolExpr(AND_EXPR, part_qual, -1) + : linitial(part_qual)); + } + ReleaseSysCache(tuple); + } + + if (or_expr_args != NIL) + { + Expr *other_parts_constr; + + /* + * Combine the constraints obtained for non-default partitions + * using OR. As requested, each of the OR's args doesn't include + * the NOT NULL test for partition keys (which is to avoid its + * useless repetition). Add the same now. + */ + other_parts_constr = + makeBoolExpr(AND_EXPR, + lappend(get_range_nulltest(key), + list_length(or_expr_args) > 1 + ? makeBoolExpr(OR_EXPR, or_expr_args, + -1) + : linitial(or_expr_args)), + -1); + + /* + * Finally, the default partition contains everything *NOT* + * contained in the non-default partitions. + */ + result = list_make1(makeBoolExpr(NOT_EXPR, + list_make1(other_parts_constr), -1)); + } + + return result; + } + + lower_or_start_datum = list_head(spec->lowerdatums); + upper_or_start_datum = list_head(spec->upperdatums); + num_or_arms = key->partnatts; + + /* + * If it is the recursive call for default, we skip the get_range_nulltest + * to avoid accumulating the NullTest on the same keys for each partition. + */ + if (!for_default) + result = get_range_nulltest(key); + + /* + * Iterate over the key columns and check if the corresponding lower and + * upper datums are equal using the btree equality operator for the + * column's type. If equal, we emit single keyCol = common_value + * expression. Starting from the first column for which the corresponding + * lower and upper bound datums are not equal, we generate OR expressions + * as shown in the function's header comment. + */ + i = 0; + partexprs_item = list_head(key->partexprs); + partexprs_item_saved = partexprs_item; /* placate compiler */ + forboth(cell1, spec->lowerdatums, cell2, spec->upperdatums) + { + EState *estate; + MemoryContext oldcxt; + Expr *test_expr; + ExprState *test_exprstate; + Datum test_result; + bool isNull; + + ldatum = castNode(PartitionRangeDatum, lfirst(cell1)); + udatum = castNode(PartitionRangeDatum, lfirst(cell2)); + + /* + * Since get_range_key_properties() modifies partexprs_item, and we + * might need to start over from the previous expression in the later + * part of this function, save away the current value. + */ + partexprs_item_saved = partexprs_item; + + get_range_key_properties(key, i, ldatum, udatum, + &partexprs_item, + &keyCol, + &lower_val, &upper_val); + + /* + * If either value is NULL, the corresponding partition bound is + * either MINVALUE or MAXVALUE, and we treat them as unequal, because + * even if they're the same, there is no common value to equate the + * key column with. + */ + if (!lower_val || !upper_val) + break; + + /* Create the test expression */ + estate = CreateExecutorState(); + oldcxt = MemoryContextSwitchTo(estate->es_query_cxt); + test_expr = make_partition_op_expr(key, i, BTEqualStrategyNumber, + (Expr *) lower_val, + (Expr *) upper_val); + fix_opfuncids((Node *) test_expr); + test_exprstate = ExecInitExpr(test_expr, NULL); + test_result = ExecEvalExprSwitchContext(test_exprstate, + GetPerTupleExprContext(estate), + &isNull); + MemoryContextSwitchTo(oldcxt); + FreeExecutorState(estate); + + /* If not equal, go generate the OR expressions */ + if (!DatumGetBool(test_result)) + break; + + /* + * The bounds for the last key column can't be equal, because such a + * range partition would never be allowed to be defined (it would have + * an empty range otherwise). + */ + if (i == key->partnatts - 1) + elog(ERROR, "invalid range bound specification"); + + /* Equal, so generate keyCol = lower_val expression */ + result = lappend(result, + make_partition_op_expr(key, i, BTEqualStrategyNumber, + keyCol, (Expr *) lower_val)); + + i++; + } + + /* First pair of lower_val and upper_val that are not equal. */ + lower_or_start_datum = cell1; + upper_or_start_datum = cell2; + + /* OR will have as many arms as there are key columns left. */ + num_or_arms = key->partnatts - i; + current_or_arm = 0; + lower_or_arms = upper_or_arms = NIL; + need_next_lower_arm = need_next_upper_arm = true; + while (current_or_arm < num_or_arms) + { + List *lower_or_arm_args = NIL, + *upper_or_arm_args = NIL; + + /* Restart scan of columns from the i'th one */ + j = i; + partexprs_item = partexprs_item_saved; + + for_both_cell(cell1, spec->lowerdatums, lower_or_start_datum, + cell2, spec->upperdatums, upper_or_start_datum) + { + PartitionRangeDatum *ldatum_next = NULL, + *udatum_next = NULL; + + ldatum = castNode(PartitionRangeDatum, lfirst(cell1)); + if (lnext(spec->lowerdatums, cell1)) + ldatum_next = castNode(PartitionRangeDatum, + lfirst(lnext(spec->lowerdatums, cell1))); + udatum = castNode(PartitionRangeDatum, lfirst(cell2)); + if (lnext(spec->upperdatums, cell2)) + udatum_next = castNode(PartitionRangeDatum, + lfirst(lnext(spec->upperdatums, cell2))); + get_range_key_properties(key, j, ldatum, udatum, + &partexprs_item, + &keyCol, + &lower_val, &upper_val); + + if (need_next_lower_arm && lower_val) + { + uint16 strategy; + + /* + * For the non-last columns of this arm, use the EQ operator. + * For the last column of this arm, use GT, unless this is the + * last column of the whole bound check, or the next bound + * datum is MINVALUE, in which case use GE. + */ + if (j - i < current_or_arm) + strategy = BTEqualStrategyNumber; + else if (j == key->partnatts - 1 || + (ldatum_next && + ldatum_next->kind == PARTITION_RANGE_DATUM_MINVALUE)) + strategy = BTGreaterEqualStrategyNumber; + else + strategy = BTGreaterStrategyNumber; + + lower_or_arm_args = lappend(lower_or_arm_args, + make_partition_op_expr(key, j, + strategy, + keyCol, + (Expr *) lower_val)); + } + + if (need_next_upper_arm && upper_val) + { + uint16 strategy; + + /* + * For the non-last columns of this arm, use the EQ operator. + * For the last column of this arm, use LT, unless the next + * bound datum is MAXVALUE, in which case use LE. + */ + if (j - i < current_or_arm) + strategy = BTEqualStrategyNumber; + else if (udatum_next && + udatum_next->kind == PARTITION_RANGE_DATUM_MAXVALUE) + strategy = BTLessEqualStrategyNumber; + else + strategy = BTLessStrategyNumber; + + upper_or_arm_args = lappend(upper_or_arm_args, + make_partition_op_expr(key, j, + strategy, + keyCol, + (Expr *) upper_val)); + } + + /* + * Did we generate enough of OR's arguments? First arm considers + * the first of the remaining columns, second arm considers first + * two of the remaining columns, and so on. + */ + ++j; + if (j - i > current_or_arm) + { + /* + * We must not emit any more arms if the new column that will + * be considered is unbounded, or this one was. + */ + if (!lower_val || !ldatum_next || + ldatum_next->kind != PARTITION_RANGE_DATUM_VALUE) + need_next_lower_arm = false; + if (!upper_val || !udatum_next || + udatum_next->kind != PARTITION_RANGE_DATUM_VALUE) + need_next_upper_arm = false; + break; + } + } + + if (lower_or_arm_args != NIL) + lower_or_arms = lappend(lower_or_arms, + list_length(lower_or_arm_args) > 1 + ? makeBoolExpr(AND_EXPR, lower_or_arm_args, -1) + : linitial(lower_or_arm_args)); + + if (upper_or_arm_args != NIL) + upper_or_arms = lappend(upper_or_arms, + list_length(upper_or_arm_args) > 1 + ? makeBoolExpr(AND_EXPR, upper_or_arm_args, -1) + : linitial(upper_or_arm_args)); + + /* If no work to do in the next iteration, break away. */ + if (!need_next_lower_arm && !need_next_upper_arm) + break; + + ++current_or_arm; + } + + /* + * Generate the OR expressions for each of lower and upper bounds (if + * required), and append to the list of implicitly ANDed list of + * expressions. + */ + if (lower_or_arms != NIL) + result = lappend(result, + list_length(lower_or_arms) > 1 + ? makeBoolExpr(OR_EXPR, lower_or_arms, -1) + : linitial(lower_or_arms)); + if (upper_or_arms != NIL) + result = lappend(result, + list_length(upper_or_arms) > 1 + ? makeBoolExpr(OR_EXPR, upper_or_arms, -1) + : linitial(upper_or_arms)); + + /* + * As noted above, for non-default, we return list with constant TRUE. If + * the result is NIL during the recursive call for default, it implies + * this is the only other partition which can hold every value of the key + * except NULL. Hence we return the NullTest result skipped earlier. + */ + if (result == NIL) + result = for_default + ? get_range_nulltest(key) + : list_make1(makeBoolConst(true, false)); + + return result; +} + +/* + * get_range_key_properties + * Returns range partition key information for a given column + * + * This is a subroutine for get_qual_for_range, and its API is pretty + * specialized to that caller. + * + * Constructs an Expr for the key column (returned in *keyCol) and Consts + * for the lower and upper range limits (returned in *lower_val and + * *upper_val). For MINVALUE/MAXVALUE limits, NULL is returned instead of + * a Const. All of these structures are freshly palloc'd. + * + * *partexprs_item points to the cell containing the next expression in + * the key->partexprs list, or NULL. It may be advanced upon return. + */ +static void +get_range_key_properties(PartitionKey key, int keynum, + PartitionRangeDatum *ldatum, + PartitionRangeDatum *udatum, + ListCell **partexprs_item, + Expr **keyCol, + Const **lower_val, Const **upper_val) +{ + /* Get partition key expression for this column */ + if (key->partattrs[keynum] != 0) + { + *keyCol = (Expr *) makeVar(1, + key->partattrs[keynum], + key->parttypid[keynum], + key->parttypmod[keynum], + key->parttypcoll[keynum], + 0); + } + else + { + if (*partexprs_item == NULL) + elog(ERROR, "wrong number of partition key expressions"); + *keyCol = copyObject(lfirst(*partexprs_item)); + *partexprs_item = lnext(key->partexprs, *partexprs_item); + } + + /* Get appropriate Const nodes for the bounds */ + if (ldatum->kind == PARTITION_RANGE_DATUM_VALUE) + *lower_val = castNode(Const, copyObject(ldatum->value)); + else + *lower_val = NULL; + + if (udatum->kind == PARTITION_RANGE_DATUM_VALUE) + *upper_val = castNode(Const, copyObject(udatum->value)); + else + *upper_val = NULL; +} + +/* + * get_range_nulltest + * + * A non-default range partition table does not currently allow partition + * keys to be null, so emit an IS NOT NULL expression for each key column. + */ +static List * +get_range_nulltest(PartitionKey key) +{ + List *result = NIL; + NullTest *nulltest; + ListCell *partexprs_item; + int i; + + partexprs_item = list_head(key->partexprs); + for (i = 0; i < key->partnatts; i++) + { + Expr *keyCol; + + if (key->partattrs[i] != 0) + { + keyCol = (Expr *) makeVar(1, + key->partattrs[i], + key->parttypid[i], + key->parttypmod[i], + key->parttypcoll[i], + 0); + } + else + { + if (partexprs_item == NULL) + elog(ERROR, "wrong number of partition key expressions"); + keyCol = copyObject(lfirst(partexprs_item)); + partexprs_item = lnext(key->partexprs, partexprs_item); + } + + nulltest = makeNode(NullTest); + nulltest->arg = keyCol; + nulltest->nulltesttype = IS_NOT_NULL; + nulltest->argisrow = false; + nulltest->location = -1; + result = lappend(result, nulltest); + } + + return result; +} + +/* + * compute_partition_hash_value + * + * Compute the hash value for given partition key values. + */ +uint64 +compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, Oid *partcollation, + Datum *values, bool *isnull) +{ + int i; + uint64 rowHash = 0; + Datum seed = UInt64GetDatum(HASH_PARTITION_SEED); + + for (i = 0; i < partnatts; i++) + { + /* Nulls are just ignored */ + if (!isnull[i]) + { + Datum hash; + + Assert(OidIsValid(partsupfunc[i].fn_oid)); + + /* + * Compute hash for each datum value by calling respective + * datatype-specific hash functions of each partition key + * attribute. + */ + hash = FunctionCall2Coll(&partsupfunc[i], partcollation[i], + values[i], seed); + + /* Form a single 64-bit hash value */ + rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); + } + } + + return rowHash; +} + +/* + * satisfies_hash_partition + * + * This is an SQL-callable function for use in hash partition constraints. + * The first three arguments are the parent table OID, modulus, and remainder. + * The remaining arguments are the value of the partitioning columns (or + * expressions); these are hashed and the results are combined into a single + * hash value by calling hash_combine64. + * + * Returns true if remainder produced when this computed single hash value is + * divided by the given modulus is equal to given remainder, otherwise false. + * + * See get_qual_for_hash() for usage. + */ +Datum +satisfies_hash_partition(PG_FUNCTION_ARGS) +{ + typedef struct ColumnsHashData + { + Oid relid; + int nkeys; + Oid variadic_type; + int16 variadic_typlen; + bool variadic_typbyval; + char variadic_typalign; + Oid partcollid[PARTITION_MAX_KEYS]; + FmgrInfo partsupfunc[FLEXIBLE_ARRAY_MEMBER]; + } ColumnsHashData; + Oid parentId; + int modulus; + int remainder; + Datum seed = UInt64GetDatum(HASH_PARTITION_SEED); + ColumnsHashData *my_extra; + uint64 rowHash = 0; + + /* Return null if the parent OID, modulus, or remainder is NULL. */ + if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) + PG_RETURN_NULL(); + parentId = PG_GETARG_OID(0); + modulus = PG_GETARG_INT32(1); + remainder = PG_GETARG_INT32(2); + + /* Sanity check modulus and remainder. */ + if (modulus <= 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("modulus for hash partition must be a positive integer"))); + if (remainder < 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("remainder for hash partition must be a non-negative integer"))); + if (remainder >= modulus) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("remainder for hash partition must be less than modulus"))); + + /* + * Cache hash function information. + */ + my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; + if (my_extra == NULL || my_extra->relid != parentId) + { + Relation parent; + PartitionKey key; + int j; + + /* Open parent relation and fetch partition key info */ + parent = try_relation_open(parentId, AccessShareLock); + if (parent == NULL) + PG_RETURN_NULL(); + key = RelationGetPartitionKey(parent); + + /* Reject parent table that is not hash-partitioned. */ + if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE || + key->strategy != PARTITION_STRATEGY_HASH) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"%s\" is not a hash partitioned table", + get_rel_name(parentId)))); + + if (!get_fn_expr_variadic(fcinfo->flinfo)) + { + int nargs = PG_NARGS() - 3; + + /* complain if wrong number of column values */ + if (key->partnatts != nargs) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("number of partitioning columns (%d) does not match number of partition keys provided (%d)", + key->partnatts, nargs))); + + /* allocate space for our cache */ + fcinfo->flinfo->fn_extra = + MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, + offsetof(ColumnsHashData, partsupfunc) + + sizeof(FmgrInfo) * nargs); + my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; + my_extra->relid = parentId; + my_extra->nkeys = key->partnatts; + memcpy(my_extra->partcollid, key->partcollation, + key->partnatts * sizeof(Oid)); + + /* check argument types and save fmgr_infos */ + for (j = 0; j < key->partnatts; ++j) + { + Oid argtype = get_fn_expr_argtype(fcinfo->flinfo, j + 3); + + if (argtype != key->parttypid[j] && !IsBinaryCoercible(argtype, key->parttypid[j])) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"", + j + 1, format_type_be(key->parttypid[j]), format_type_be(argtype)))); + + fmgr_info_copy(&my_extra->partsupfunc[j], + &key->partsupfunc[j], + fcinfo->flinfo->fn_mcxt); + } + } + else + { + ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); + + /* allocate space for our cache -- just one FmgrInfo in this case */ + fcinfo->flinfo->fn_extra = + MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, + offsetof(ColumnsHashData, partsupfunc) + + sizeof(FmgrInfo)); + my_extra = (ColumnsHashData *) fcinfo->flinfo->fn_extra; + my_extra->relid = parentId; + my_extra->nkeys = key->partnatts; + my_extra->variadic_type = ARR_ELEMTYPE(variadic_array); + get_typlenbyvalalign(my_extra->variadic_type, + &my_extra->variadic_typlen, + &my_extra->variadic_typbyval, + &my_extra->variadic_typalign); + my_extra->partcollid[0] = key->partcollation[0]; + + /* check argument types */ + for (j = 0; j < key->partnatts; ++j) + if (key->parttypid[j] != my_extra->variadic_type) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"", + j + 1, + format_type_be(key->parttypid[j]), + format_type_be(my_extra->variadic_type)))); + + fmgr_info_copy(&my_extra->partsupfunc[0], + &key->partsupfunc[0], + fcinfo->flinfo->fn_mcxt); + } + + /* Hold lock until commit */ + relation_close(parent, NoLock); + } + + if (!OidIsValid(my_extra->variadic_type)) + { + int nkeys = my_extra->nkeys; + int i; + + /* + * For a non-variadic call, neither the number of arguments nor their + * types can change across calls, so avoid the expense of rechecking + * here. + */ + + for (i = 0; i < nkeys; i++) + { + Datum hash; + + /* keys start from fourth argument of function. */ + int argno = i + 3; + + if (PG_ARGISNULL(argno)) + continue; + + hash = FunctionCall2Coll(&my_extra->partsupfunc[i], + my_extra->partcollid[i], + PG_GETARG_DATUM(argno), + seed); + + /* Form a single 64-bit hash value */ + rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); + } + } + else + { + ArrayType *variadic_array = PG_GETARG_ARRAYTYPE_P(3); + int i; + int nelems; + Datum *datum; + bool *isnull; + + deconstruct_array(variadic_array, + my_extra->variadic_type, + my_extra->variadic_typlen, + my_extra->variadic_typbyval, + my_extra->variadic_typalign, + &datum, &isnull, &nelems); + + /* complain if wrong number of column values */ + if (nelems != my_extra->nkeys) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("number of partitioning columns (%d) does not match number of partition keys provided (%d)", + my_extra->nkeys, nelems))); + + for (i = 0; i < nelems; i++) + { + Datum hash; + + if (isnull[i]) + continue; + + hash = FunctionCall2Coll(&my_extra->partsupfunc[0], + my_extra->partcollid[0], + datum[i], + seed); + + /* Form a single 64-bit hash value */ + rowHash = hash_combine64(rowHash, DatumGetUInt64(hash)); + } + } + + PG_RETURN_BOOL(rowHash % modulus == remainder); +} diff --git a/src/backend/partitioning/partdesc.c b/src/backend/partitioning/partdesc.c new file mode 100644 index 00000000000..b207b765f2a --- /dev/null +++ b/src/backend/partitioning/partdesc.c @@ -0,0 +1,380 @@ +/*------------------------------------------------------------------------- + * + * partdesc.c + * Support routines for manipulating partition descriptors + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/partitioning/partdesc.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/genam.h" +#include "access/htup_details.h" +#include "access/table.h" +#include "catalog/indexing.h" +#include "catalog/partition.h" +#include "catalog/pg_inherits.h" +#include "partitioning/partbounds.h" +#include "partitioning/partdesc.h" +#include "storage/bufmgr.h" +#include "storage/sinval.h" +#include "utils/builtins.h" +#include "utils/inval.h" +#include "utils/fmgroids.h" +#include "utils/hsearch.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/rel.h" +#include "utils/partcache.h" +#include "utils/syscache.h" + +typedef struct PartitionDirectoryData +{ + MemoryContext pdir_mcxt; + HTAB *pdir_hash; +} PartitionDirectoryData; + +typedef struct PartitionDirectoryEntry +{ + Oid reloid; + Relation rel; + PartitionDesc pd; +} PartitionDirectoryEntry; + +/* + * RelationBuildPartitionDesc + * Form rel's partition descriptor, and store in relcache entry + * + * Note: the descriptor won't be flushed from the cache by + * RelationClearRelation() unless it's changed because of + * addition or removal of a partition. Hence, code holding a lock + * that's sufficient to prevent that can assume that rd_partdesc + * won't change underneath it. + */ +void +RelationBuildPartitionDesc(Relation rel) +{ + PartitionDesc partdesc; + PartitionBoundInfo boundinfo = NULL; + List *inhoids; + PartitionBoundSpec **boundspecs = NULL; + Oid *oids = NULL; + ListCell *cell; + int i, + nparts; + PartitionKey key = RelationGetPartitionKey(rel); + MemoryContext oldcxt; + int *mapping; + + /* + * Get partition oids from pg_inherits. This uses a single snapshot to + * fetch the list of children, so while more children may be getting added + * concurrently, whatever this function returns will be accurate as of + * some well-defined point in time. + */ + inhoids = find_inheritance_children(RelationGetRelid(rel), NoLock); + nparts = list_length(inhoids); + + /* Allocate arrays for OIDs and boundspecs. */ + if (nparts > 0) + { + oids = palloc(nparts * sizeof(Oid)); + boundspecs = palloc(nparts * sizeof(PartitionBoundSpec *)); + } + + /* Collect bound spec nodes for each partition. */ + i = 0; + foreach(cell, inhoids) + { + Oid inhrelid = lfirst_oid(cell); + HeapTuple tuple; + PartitionBoundSpec *boundspec = NULL; + + /* Try fetching the tuple from the catcache, for speed. */ + tuple = SearchSysCache1(RELOID, inhrelid); + if (HeapTupleIsValid(tuple)) + { + Datum datum; + bool isnull; + + datum = SysCacheGetAttr(RELOID, tuple, + Anum_pg_class_relpartbound, + &isnull); + if (!isnull) + boundspec = stringToNode(TextDatumGetCString(datum)); + ReleaseSysCache(tuple); + } + + /* + * The system cache may be out of date; if so, we may find no pg_class + * tuple or an old one where relpartbound is NULL. In that case, try + * the table directly. We can't just AcceptInvalidationMessages() and + * retry the system cache lookup because it's possible that a + * concurrent ATTACH PARTITION operation has removed itself to the + * ProcArray but yet added invalidation messages to the shared queue; + * InvalidateSystemCaches() would work, but seems excessive. + * + * Note that this algorithm assumes that PartitionBoundSpec we manage + * to fetch is the right one -- so this is only good enough for + * concurrent ATTACH PARTITION, not concurrent DETACH PARTITION or + * some hypothetical operation that changes the partition bounds. + */ + if (boundspec == NULL) + { + Relation pg_class; + SysScanDesc scan; + ScanKeyData key[1]; + Datum datum; + bool isnull; + + pg_class = table_open(RelationRelationId, AccessShareLock); + ScanKeyInit(&key[0], + Anum_pg_class_oid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(inhrelid)); + scan = systable_beginscan(pg_class, ClassOidIndexId, true, + NULL, 1, key); + tuple = systable_getnext(scan); + datum = heap_getattr(tuple, Anum_pg_class_relpartbound, + RelationGetDescr(pg_class), &isnull); + if (!isnull) + boundspec = stringToNode(TextDatumGetCString(datum)); + systable_endscan(scan); + table_close(pg_class, AccessShareLock); + } + + /* Sanity checks. */ + if (!boundspec) + elog(ERROR, "missing relpartbound for relation %u", inhrelid); + if (!IsA(boundspec, PartitionBoundSpec)) + elog(ERROR, "invalid relpartbound for relation %u", inhrelid); + + /* + * If the PartitionBoundSpec says this is the default partition, its + * OID should match pg_partitioned_table.partdefid; if not, the + * catalog is corrupt. + */ + if (boundspec->is_default) + { + Oid partdefid; + + partdefid = get_default_partition_oid(RelationGetRelid(rel)); + if (partdefid != inhrelid) + elog(ERROR, "expected partdefid %u, but got %u", + inhrelid, partdefid); + } + + /* Save results. */ + oids[i] = inhrelid; + boundspecs[i] = boundspec; + ++i; + } + + /* Assert we aren't about to leak any old data structure */ + Assert(rel->rd_pdcxt == NULL); + Assert(rel->rd_partdesc == NULL); + + /* + * Now build the actual relcache partition descriptor. Note that the + * order of operations here is fairly critical. If we fail partway + * through this code, we won't have leaked memory because the rd_pdcxt is + * attached to the relcache entry immediately, so it'll be freed whenever + * the entry is rebuilt or destroyed. However, we don't assign to + * rd_partdesc until the cached data structure is fully complete and + * valid, so that no other code might try to use it. + */ + rel->rd_pdcxt = AllocSetContextCreate(CacheMemoryContext, + "partition descriptor", + ALLOCSET_SMALL_SIZES); + MemoryContextCopyAndSetIdentifier(rel->rd_pdcxt, + RelationGetRelationName(rel)); + + partdesc = (PartitionDescData *) + MemoryContextAllocZero(rel->rd_pdcxt, sizeof(PartitionDescData)); + partdesc->nparts = nparts; + /* If there are no partitions, the rest of the partdesc can stay zero */ + if (nparts > 0) + { + /* Create PartitionBoundInfo, using the caller's context. */ + boundinfo = partition_bounds_create(boundspecs, nparts, key, &mapping); + + /* Now copy all info into relcache's partdesc. */ + oldcxt = MemoryContextSwitchTo(rel->rd_pdcxt); + partdesc->boundinfo = partition_bounds_copy(boundinfo, key); + partdesc->oids = (Oid *) palloc(nparts * sizeof(Oid)); + partdesc->is_leaf = (bool *) palloc(nparts * sizeof(bool)); + MemoryContextSwitchTo(oldcxt); + + /* + * Assign OIDs from the original array into mapped indexes of the + * result array. The order of OIDs in the former is defined by the + * catalog scan that retrieved them, whereas that in the latter is + * defined by canonicalized representation of the partition bounds. + * + * Also record leaf-ness of each partition. For this we use + * get_rel_relkind() which may leak memory, so be sure to run it in + * the caller's context. + */ + for (i = 0; i < nparts; i++) + { + int index = mapping[i]; + + partdesc->oids[index] = oids[i]; + partdesc->is_leaf[index] = + (get_rel_relkind(oids[i]) != RELKIND_PARTITIONED_TABLE); + } + } + + rel->rd_partdesc = partdesc; +} + +/* + * CreatePartitionDirectory + * Create a new partition directory object. + */ +PartitionDirectory +CreatePartitionDirectory(MemoryContext mcxt) +{ + MemoryContext oldcontext = MemoryContextSwitchTo(mcxt); + PartitionDirectory pdir; + HASHCTL ctl; + + MemSet(&ctl, 0, sizeof(HASHCTL)); + ctl.keysize = sizeof(Oid); + ctl.entrysize = sizeof(PartitionDirectoryEntry); + ctl.hcxt = mcxt; + + pdir = palloc(sizeof(PartitionDirectoryData)); + pdir->pdir_mcxt = mcxt; + pdir->pdir_hash = hash_create("partition directory", 256, &ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + + MemoryContextSwitchTo(oldcontext); + return pdir; +} + +/* + * PartitionDirectoryLookup + * Look up the partition descriptor for a relation in the directory. + * + * The purpose of this function is to ensure that we get the same + * PartitionDesc for each relation every time we look it up. In the + * face of current DDL, different PartitionDescs may be constructed with + * different views of the catalog state, but any single particular OID + * will always get the same PartitionDesc for as long as the same + * PartitionDirectory is used. + */ +PartitionDesc +PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel) +{ + PartitionDirectoryEntry *pde; + Oid relid = RelationGetRelid(rel); + bool found; + + pde = hash_search(pdir->pdir_hash, &relid, HASH_ENTER, &found); + if (!found) + { + /* + * We must keep a reference count on the relation so that the + * PartitionDesc to which we are pointing can't get destroyed. + */ + RelationIncrementReferenceCount(rel); + pde->rel = rel; + pde->pd = RelationGetPartitionDesc(rel); + Assert(pde->pd != NULL); + } + return pde->pd; +} + +/* + * DestroyPartitionDirectory + * Destroy a partition directory. + * + * Release the reference counts we're holding. + */ +void +DestroyPartitionDirectory(PartitionDirectory pdir) +{ + HASH_SEQ_STATUS status; + PartitionDirectoryEntry *pde; + + hash_seq_init(&status, pdir->pdir_hash); + while ((pde = hash_seq_search(&status)) != NULL) + RelationDecrementReferenceCount(pde->rel); +} + +/* + * equalPartitionDescs + * Compare two partition descriptors for logical equality + */ +bool +equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1, + PartitionDesc partdesc2) +{ + int i; + + if (partdesc1 != NULL) + { + if (partdesc2 == NULL) + return false; + if (partdesc1->nparts != partdesc2->nparts) + return false; + + Assert(key != NULL || partdesc1->nparts == 0); + + /* + * Same oids? If the partitioning structure did not change, that is, + * no partitions were added or removed to the relation, the oids array + * should still match element-by-element. + */ + for (i = 0; i < partdesc1->nparts; i++) + { + if (partdesc1->oids[i] != partdesc2->oids[i]) + return false; + } + + /* + * Now compare partition bound collections. The logic to iterate over + * the collections is private to partition.c. + */ + if (partdesc1->boundinfo != NULL) + { + if (partdesc2->boundinfo == NULL) + return false; + + if (!partition_bounds_equal(key->partnatts, key->parttyplen, + key->parttypbyval, + partdesc1->boundinfo, + partdesc2->boundinfo)) + return false; + } + else if (partdesc2->boundinfo != NULL) + return false; + } + else if (partdesc2 != NULL) + return false; + + return true; +} + +/* + * get_default_oid_from_partdesc + * + * Given a partition descriptor, return the OID of the default partition, if + * one exists; else, return InvalidOid. + */ +Oid +get_default_oid_from_partdesc(PartitionDesc partdesc) +{ + if (partdesc && partdesc->boundinfo && + partition_bound_has_default(partdesc->boundinfo)) + return partdesc->oids[partdesc->boundinfo->default_index]; + + return InvalidOid; +} diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 7666c6c412d..29f1c11b242 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -4,32 +4,28 @@ * Support for partition pruning during query planning and execution * * This module implements partition pruning using the information contained in - * table's partition descriptor, query clauses, and run-time parameters. + * a table's partition descriptor, query clauses, and run-time parameters. * * During planning, clauses that can be matched to the table's partition key * are turned into a set of "pruning steps", which are then executed to - * produce a set of partitions (as indexes of the RelOptInfo->part_rels array) - * that satisfy the constraints in the step. Partitions not in the set are said - * to have been pruned. + * identify a set of partitions (as indexes in the RelOptInfo->part_rels + * array) that satisfy the constraints in the step. Partitions not in the set + * are said to have been pruned. * - * A base pruning step may also consist of expressions whose values are only - * known during execution, such as Params, in which case pruning cannot occur + * A base pruning step may involve expressions whose values are only known + * during execution, such as Params, in which case pruning cannot occur * entirely during planning. In that case, such steps are included alongside * the plan, so that they can be used by the executor for further pruning. * - * There are two kinds of pruning steps: a "base" pruning step, which contains - * information extracted from one or more clauses that are matched to the - * (possibly multi-column) partition key, such as the expressions whose values - * to match against partition bounds and operator strategy to associate to - * each expression. The other kind is a "combine" pruning step, which combines - * the outputs of some other steps using the appropriate combination method. - * All steps that are constructed are executed in succession such that for any - * "combine" step, all of the steps whose output it depends on are executed - * first and their ouput preserved. + * There are two kinds of pruning steps. A "base" pruning step represents + * tests on partition key column(s), typically comparisons to expressions. + * A "combine" pruning step represents a Boolean connector (AND/OR), and + * combines the outputs of some previous steps using the appropriate + * combination method. * * See gen_partprune_steps_internal() for more details on step generation. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -43,19 +39,21 @@ #include "access/nbtree.h" #include "catalog/pg_operator.h" #include "catalog/pg_opfamily.h" +#include "catalog/pg_proc.h" #include "catalog/pg_type.h" #include "executor/executor.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" +#include "optimizer/appendinfo.h" +#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" -#include "optimizer/planner.h" -#include "optimizer/predtest.h" -#include "optimizer/prep.h" -#include "partitioning/partprune.h" +#include "parser/parsetree.h" #include "partitioning/partbounds.h" +#include "partitioning/partprune.h" #include "rewrite/rewriteManip.h" +#include "utils/array.h" #include "utils/lsyscache.h" @@ -64,19 +62,18 @@ */ typedef struct PartClauseInfo { - int keyno; /* Partition key number (0 to partnatts - 1) */ - Oid opno; /* operator used to compare partkey to 'expr' */ + int keyno; /* Partition key number (0 to partnatts - 1) */ + Oid opno; /* operator used to compare partkey to expr */ bool op_is_ne; /* is clause's original operator <> ? */ Expr *expr; /* expr the partition key is compared to */ Oid cmpfn; /* Oid of function to compare 'expr' to the * partition key */ - int op_strategy; /* cached info. */ + int op_strategy; /* btree strategy identifying the operator */ } PartClauseInfo; /* * PartClauseMatchStatus - * Describes the result match_clause_to_partition_key produces for a - * given clause and the partition key to match with that are passed to it + * Describes the result of match_clause_to_partition_key() */ typedef enum PartClauseMatchStatus { @@ -88,18 +85,43 @@ typedef enum PartClauseMatchStatus PARTCLAUSE_UNSUPPORTED } PartClauseMatchStatus; +/* + * PartClauseTarget + * Identifies which qual clauses we can use for generating pruning steps + */ +typedef enum PartClauseTarget +{ + PARTTARGET_PLANNER, /* want to prune during planning */ + PARTTARGET_INITIAL, /* want to prune during executor startup */ + PARTTARGET_EXEC /* want to prune during each plan node scan */ +} PartClauseTarget; + /* * GeneratePruningStepsContext * Information about the current state of generation of "pruning steps" * for a given set of clauses * - * gen_partprune_steps() initializes an instance of this struct, which is used - * throughout the step generation process. + * gen_partprune_steps() initializes and returns an instance of this struct. + * + * Note that has_mutable_op, has_mutable_arg, and has_exec_param are set if + * we found any potentially-useful-for-pruning clause having those properties, + * whether or not we actually used the clause in the steps list. This + * definition allows us to skip the PARTTARGET_EXEC pass in some cases. */ typedef struct GeneratePruningStepsContext { + /* Copies of input arguments for gen_partprune_steps: */ + RelOptInfo *rel; /* the partitioned relation */ + PartClauseTarget target; /* use-case we're generating steps for */ + /* Result data: */ + List *steps; /* list of PartitionPruneSteps */ + bool has_mutable_op; /* clauses include any stable operators */ + bool has_mutable_arg; /* clauses include any mutable comparison + * values, *other than* exec params */ + bool has_exec_param; /* clauses include any PARAM_EXEC params */ + bool contradictory; /* clauses were proven self-contradictory */ + /* Working state: */ int next_step_id; - List *steps; } GeneratePruningStepsContext; /* The result of performing one PartitionPruneStep */ @@ -116,94 +138,117 @@ typedef struct PruneStepResult } PruneStepResult; +static List *make_partitionedrel_pruneinfo(PlannerInfo *root, + RelOptInfo *parentrel, + int *relid_subplan_map, + List *partitioned_rels, List *prunequal, + Bitmapset **matchedsubplans); +static void gen_partprune_steps(RelOptInfo *rel, List *clauses, + PartClauseTarget target, + GeneratePruningStepsContext *context); static List *gen_partprune_steps_internal(GeneratePruningStepsContext *context, - RelOptInfo *rel, List *clauses, - bool *contradictory); + List *clauses); static PartitionPruneStep *gen_prune_step_op(GeneratePruningStepsContext *context, - StrategyNumber opstrategy, bool op_is_ne, - List *exprs, List *cmpfns, Bitmapset *nullkeys); + StrategyNumber opstrategy, bool op_is_ne, + List *exprs, List *cmpfns, Bitmapset *nullkeys); static PartitionPruneStep *gen_prune_step_combine(GeneratePruningStepsContext *context, - List *source_stepids, - PartitionPruneCombineOp combineOp); -static PartitionPruneStep *gen_prune_steps_from_opexps(PartitionScheme part_scheme, - GeneratePruningStepsContext *context, - List **keyclauses, Bitmapset *nullkeys); -static PartClauseMatchStatus match_clause_to_partition_key(RelOptInfo *rel, - GeneratePruningStepsContext *context, - Expr *clause, Expr *partkey, int partkeyidx, - bool *clause_is_not_null, - PartClauseInfo **pc, List **clause_steps); + List *source_stepids, + PartitionPruneCombineOp combineOp); +static PartitionPruneStep *gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, + List **keyclauses, Bitmapset *nullkeys); +static PartClauseMatchStatus match_clause_to_partition_key(GeneratePruningStepsContext *context, + Expr *clause, Expr *partkey, int partkeyidx, + bool *clause_is_not_null, + PartClauseInfo **pc, List **clause_steps); static List *get_steps_using_prefix(GeneratePruningStepsContext *context, - StrategyNumber step_opstrategy, - bool step_op_is_ne, - Expr *step_lastexpr, - Oid step_lastcmpfn, - int step_lastkeyno, - Bitmapset *step_nullkeys, - List *prefix); + StrategyNumber step_opstrategy, + bool step_op_is_ne, + Expr *step_lastexpr, + Oid step_lastcmpfn, + int step_lastkeyno, + Bitmapset *step_nullkeys, + List *prefix); static List *get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, - StrategyNumber step_opstrategy, - bool step_op_is_ne, - Expr *step_lastexpr, - Oid step_lastcmpfn, - int step_lastkeyno, - Bitmapset *step_nullkeys, - ListCell *start, - List *step_exprs, - List *step_cmpfns); + StrategyNumber step_opstrategy, + bool step_op_is_ne, + Expr *step_lastexpr, + Oid step_lastcmpfn, + int step_lastkeyno, + Bitmapset *step_nullkeys, + List *prefix, + ListCell *start, + List *step_exprs, + List *step_cmpfns); static PruneStepResult *get_matching_hash_bounds(PartitionPruneContext *context, - StrategyNumber opstrategy, Datum *values, int nvalues, - FmgrInfo *partsupfunc, Bitmapset *nullkeys); + StrategyNumber opstrategy, Datum *values, int nvalues, + FmgrInfo *partsupfunc, Bitmapset *nullkeys); static PruneStepResult *get_matching_list_bounds(PartitionPruneContext *context, - StrategyNumber opstrategy, Datum value, int nvalues, - FmgrInfo *partsupfunc, Bitmapset *nullkeys); + StrategyNumber opstrategy, Datum value, int nvalues, + FmgrInfo *partsupfunc, Bitmapset *nullkeys); static PruneStepResult *get_matching_range_bounds(PartitionPruneContext *context, - StrategyNumber opstrategy, Datum *values, int nvalues, - FmgrInfo *partsupfunc, Bitmapset *nullkeys); -static bool pull_partkey_params(PartitionPruneInfo *pinfo, List *steps); + StrategyNumber opstrategy, Datum *values, int nvalues, + FmgrInfo *partsupfunc, Bitmapset *nullkeys); +static Bitmapset *pull_exec_paramids(Expr *expr); +static bool pull_exec_paramids_walker(Node *node, Bitmapset **context); +static Bitmapset *get_partkey_exec_paramids(List *steps); static PruneStepResult *perform_pruning_base_step(PartitionPruneContext *context, - PartitionPruneStepOp *opstep); + PartitionPruneStepOp *opstep); static PruneStepResult *perform_pruning_combine_step(PartitionPruneContext *context, - PartitionPruneStepCombine *cstep, - PruneStepResult **step_results); -static bool match_boolean_partition_clause(Oid partopfamily, Expr *clause, - Expr *partkey, Expr **outconst); -static bool partkey_datum_from_expr(PartitionPruneContext *context, - Expr *expr, Datum *value); + PartitionPruneStepCombine *cstep, + PruneStepResult **step_results); +static PartClauseMatchStatus match_boolean_partition_clause(Oid partopfamily, + Expr *clause, + Expr *partkey, + Expr **outconst); +static void partkey_datum_from_expr(PartitionPruneContext *context, + Expr *expr, int stateidx, + Datum *value, bool *isnull); + /* * make_partition_pruneinfo - * Build List of PartitionPruneInfos, one for each 'partitioned_rels'. - * These can be used in the executor to allow additional partition - * pruning to take place. + * Builds a PartitionPruneInfo which can be used in the executor to allow + * additional partition pruning to take place. Returns NULL when + * partition pruning would be useless. * - * Here we generate partition pruning steps for 'prunequal' and also build a - * data stucture which allows mapping of partition indexes into 'subpaths' - * indexes. + * 'parentrel' is the RelOptInfo for an appendrel, and 'subpaths' is the list + * of scan paths for its child rels. * - * If no Params were found to match the partition key in any of the - * 'partitioned_rels', then we return NIL. In such a case run-time partition - * pruning would be useless. + * 'partitioned_rels' is a List containing Lists of relids of partitioned + * tables (a/k/a non-leaf partitions) that are parents of some of the child + * rels. Here we attempt to populate the PartitionPruneInfo by adding a + * 'prune_infos' item for each sublist in the 'partitioned_rels' list. + * However, some of the sets of partitioned relations may not require any + * run-time pruning. In these cases we'll simply not include a 'prune_infos' + * item for that set and instead we'll add all the subplans which belong to + * that set into the PartitionPruneInfo's 'other_subplans' field. Callers + * will likely never want to prune subplans which are mentioned in this field. + * + * 'prunequal' is a list of potential pruning quals. */ -List * -make_partition_pruneinfo(PlannerInfo *root, List *partition_rels, - List *subpaths, List *prunequal) +PartitionPruneInfo * +make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, + List *subpaths, List *partitioned_rels, + List *prunequal) { - RelOptInfo *targetpart = NULL; + PartitionPruneInfo *pruneinfo; + Bitmapset *allmatchedsubplans = NULL; + int *relid_subplan_map; ListCell *lc; - List *pinfolist = NIL; - int *relid_subnode_map; - int *relid_subpart_map; + List *prunerelinfos; int i; - bool gotparam = false; /* - * Allocate two arrays to store the 1-based indexes of the 'subpaths' and - * 'partitioned_rels' by relid. + * Construct a temporary array to map from planner relids to subplan + * indexes. For convenience, we use 1-based indexes here, so that zero + * can represent an un-filled array entry. */ - relid_subnode_map = palloc0(sizeof(int) * root->simple_rel_array_size); - relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size); + relid_subplan_map = palloc0(sizeof(int) * root->simple_rel_array_size); + /* + * relid_subplan_map maps relid of a leaf partition to the index in + * 'subpaths' of the scan plan for that partition. + */ i = 1; foreach(lc, subpaths) { @@ -212,43 +257,170 @@ make_partition_pruneinfo(PlannerInfo *root, List *partition_rels, Assert(IS_SIMPLE_REL(pathrel)); Assert(pathrel->relid < root->simple_rel_array_size); + /* No duplicates please */ + Assert(relid_subplan_map[pathrel->relid] == 0); - relid_subnode_map[pathrel->relid] = i++; + relid_subplan_map[pathrel->relid] = i++; } - /* Likewise for the partition_rels */ - i = 1; - foreach(lc, partition_rels) + /* We now build a PartitionedRelPruneInfo for each partitioned rel. */ + prunerelinfos = NIL; + foreach(lc, partitioned_rels) { - Index rti = lfirst_int(lc); + List *rels = (List *) lfirst(lc); + List *pinfolist; + Bitmapset *matchedsubplans = NULL; - Assert(rti < root->simple_rel_array_size); + pinfolist = make_partitionedrel_pruneinfo(root, parentrel, + relid_subplan_map, + rels, prunequal, + &matchedsubplans); - relid_subpart_map[rti] = i++; + /* When pruning is possible, record the matched subplans */ + if (pinfolist != NIL) + { + prunerelinfos = lappend(prunerelinfos, pinfolist); + allmatchedsubplans = bms_join(matchedsubplans, + allmatchedsubplans); + } } - /* We now build a PartitionPruneInfo for each partition_rels */ - foreach(lc, partition_rels) + pfree(relid_subplan_map); + + /* + * If none of the partition hierarchies had any useful run-time pruning + * quals, then we can just not bother with run-time pruning. + */ + if (prunerelinfos == NIL) + return NULL; + + /* Else build the result data structure */ + pruneinfo = makeNode(PartitionPruneInfo); + pruneinfo->prune_infos = prunerelinfos; + + /* + * Some subplans may not belong to any of the listed partitioned rels. + * This can happen for UNION ALL queries which include a non-partitioned + * table, or when some of the hierarchies aren't run-time prunable. Build + * a bitmapset of the indexes of all such subplans, so that the executor + * can identify which subplans should never be pruned. + */ + if (bms_num_members(allmatchedsubplans) < list_length(subpaths)) + { + Bitmapset *other_subplans; + + /* Create the complement of allmatchedsubplans */ + other_subplans = bms_add_range(NULL, 0, list_length(subpaths) - 1); + other_subplans = bms_del_members(other_subplans, allmatchedsubplans); + + pruneinfo->other_subplans = other_subplans; + } + else + pruneinfo->other_subplans = NULL; + + return pruneinfo; +} + +/* + * make_partitionedrel_pruneinfo + * Build a List of PartitionedRelPruneInfos, one for each partitioned + * rel. These can be used in the executor to allow additional partition + * pruning to take place. + * + * Here we generate partition pruning steps for 'prunequal' and also build a + * data structure which allows mapping of partition indexes into 'subpaths' + * indexes. + * + * If no non-Const expressions are being compared to the partition key in any + * of the 'partitioned_rels', then we return NIL to indicate no run-time + * pruning should be performed. Run-time pruning would be useless since the + * pruning done during planning will have pruned everything that can be. + * + * On non-NIL return, 'matchedsubplans' is set to the subplan indexes which + * were matched to this partition hierarchy. + */ +static List * +make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, + int *relid_subplan_map, + List *partitioned_rels, List *prunequal, + Bitmapset **matchedsubplans) +{ + RelOptInfo *targetpart = NULL; + List *pinfolist = NIL; + bool doruntimeprune = false; + int *relid_subpart_map; + Bitmapset *subplansfound = NULL; + ListCell *lc; + int i; + + /* + * Examine each partitioned rel, constructing a temporary array to map + * from planner relids to index of the partitioned rel, and building a + * PartitionedRelPruneInfo for each partitioned rel. + * + * In this phase we discover whether runtime pruning is needed at all; if + * not, we can avoid doing further work. + */ + relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size); + + i = 1; + foreach(lc, partitioned_rels) { Index rti = lfirst_int(lc); RelOptInfo *subpart = find_base_rel(root, rti); - PartitionPruneInfo *pinfo; - RangeTblEntry *rte; - Bitmapset *present_parts; - int nparts = subpart->nparts; - int *subnode_map; - int *subpart_map; + PartitionedRelPruneInfo *pinfo; List *partprunequal; - List *pruning_steps; - bool contradictory; + List *initial_pruning_steps; + List *exec_pruning_steps; + Bitmapset *execparamids; + GeneratePruningStepsContext context; /* - * The first item in the list is the target partitioned relation. The - * quals belong to this relation, so require no translation. + * Fill the mapping array. + * + * relid_subpart_map maps relid of a non-leaf partition to the index + * in 'partitioned_rels' of that rel (which will also be the index in + * the returned PartitionedRelPruneInfo list of the info for that + * partition). We use 1-based indexes here, so that zero can + * represent an un-filled array entry. + */ + Assert(rti < root->simple_rel_array_size); + /* No duplicates please */ + Assert(relid_subpart_map[rti] == 0); + relid_subpart_map[rti] = i++; + + /* + * Translate pruning qual, if necessary, for this partition. + * + * The first item in the list is the target partitioned relation. */ if (!targetpart) { targetpart = subpart; + + /* + * The prunequal is presented to us as a qual for 'parentrel'. + * Frequently this rel is the same as targetpart, so we can skip + * an adjust_appendrel_attrs step. But it might not be, and then + * we have to translate. We update the prunequal parameter here, + * because in later iterations of the loop for child partitions, + * we want to translate from parent to child variables. + */ + if (!bms_equal(parentrel->relids, subpart->relids)) + { + int nappinfos; + AppendRelInfo **appinfos = find_appinfos_by_relids(root, + subpart->relids, + &nappinfos); + + prunequal = (List *) adjust_appendrel_attrs(root, (Node *) + prunequal, + nappinfos, + appinfos); + + pfree(appinfos); + } + partprunequal = prunequal; } else @@ -265,10 +437,17 @@ make_partition_pruneinfo(PlannerInfo *root, List *partition_rels, targetpart->relids); } - pruning_steps = gen_partprune_steps(subpart, partprunequal, - &contradictory); + /* + * Convert pruning qual to pruning steps. We may need to do this + * twice, once to obtain executor startup pruning steps, and once for + * executor per-scan pruning steps. This first pass creates startup + * pruning steps and detects whether there's any possibly-useful quals + * that would require per-scan pruning. + */ + gen_partprune_steps(subpart, partprunequal, PARTTARGET_INITIAL, + &context); - if (contradictory) + if (context.contradictory) { /* * This shouldn't happen as the planner should have detected this @@ -282,142 +461,199 @@ make_partition_pruneinfo(PlannerInfo *root, List *partition_rels, return NIL; } - subnode_map = (int *) palloc(nparts * sizeof(int)); - subpart_map = (int *) palloc(nparts * sizeof(int)); - present_parts = NULL; + /* + * If no mutable operators or expressions appear in usable pruning + * clauses, then there's no point in running startup pruning, because + * plan-time pruning should have pruned everything prunable. + */ + if (context.has_mutable_op || context.has_mutable_arg) + initial_pruning_steps = context.steps; + else + initial_pruning_steps = NIL; /* - * Loop over each partition of the partitioned rel and record the - * subpath index for each. Any partitions which are not present in - * the subpaths List will be set to -1, and any sub-partitioned table - * which is not present will also be set to -1. + * If no exec Params appear in potentially-usable pruning clauses, + * then there's no point in even thinking about per-scan pruning. */ - for (i = 0; i < nparts; i++) + if (context.has_exec_param) { - RelOptInfo *partrel = subpart->part_rels[i]; - int subnodeidx = relid_subnode_map[partrel->relid] - 1; - int subpartidx = relid_subpart_map[partrel->relid] - 1; + /* ... OK, we'd better think about it */ + gen_partprune_steps(subpart, partprunequal, PARTTARGET_EXEC, + &context); - subnode_map[i] = subnodeidx; - subpart_map[i] = subpartidx; + if (context.contradictory) + { + /* As above, skip run-time pruning if anything fishy happens */ + return NIL; + } + + exec_pruning_steps = context.steps; /* - * Record the indexes of all the partition indexes that we have - * subnodes or subparts for. This allows an optimization to skip - * attempting any run-time pruning when no Params are found - * matching the partition key at this level. + * Detect which exec Params actually got used; the fact that some + * were in available clauses doesn't mean we actually used them. + * Skip per-scan pruning if there are none. */ - if (subnodeidx >= 0 || subpartidx >= 0) - present_parts = bms_add_member(present_parts, i); + execparamids = get_partkey_exec_paramids(exec_pruning_steps); + + if (bms_is_empty(execparamids)) + exec_pruning_steps = NIL; + } + else + { + /* No exec Params anywhere, so forget about scan-time pruning */ + exec_pruning_steps = NIL; + execparamids = NULL; } - rte = root->simple_rte_array[subpart->relid]; + if (initial_pruning_steps || exec_pruning_steps) + doruntimeprune = true; - pinfo = makeNode(PartitionPruneInfo); - pinfo->reloid = rte->relid; - pinfo->pruning_steps = pruning_steps; - pinfo->present_parts = present_parts; - pinfo->nparts = nparts; - pinfo->extparams = NULL; - pinfo->execparams = NULL; - pinfo->subnode_map = subnode_map; - pinfo->subpart_map = subpart_map; + /* Begin constructing the PartitionedRelPruneInfo for this rel */ + pinfo = makeNode(PartitionedRelPruneInfo); + pinfo->rtindex = rti; + pinfo->initial_pruning_steps = initial_pruning_steps; + pinfo->exec_pruning_steps = exec_pruning_steps; + pinfo->execparamids = execparamids; + /* Remaining fields will be filled in the next loop */ + + pinfolist = lappend(pinfolist, pinfo); + } + + if (!doruntimeprune) + { + /* No run-time pruning required. */ + pfree(relid_subpart_map); + return NIL; + } + + /* + * Run-time pruning will be required, so initialize other information. + * That includes two maps -- one needed to convert partition indexes of + * leaf partitions to the indexes of their subplans in the subplan list, + * another needed to convert partition indexes of sub-partitioned + * partitions to the indexes of their PartitionedRelPruneInfo in the + * PartitionedRelPruneInfo list. + */ + foreach(lc, pinfolist) + { + PartitionedRelPruneInfo *pinfo = lfirst(lc); + RelOptInfo *subpart = find_base_rel(root, pinfo->rtindex); + Bitmapset *present_parts; + int nparts = subpart->nparts; + int *subplan_map; + int *subpart_map; + Oid *relid_map; /* - * Extract Params matching partition key and record if we got any. - * We'll not bother enabling run-time pruning if no params matched the - * partition key at any level of partitioning. + * Construct the subplan and subpart maps for this partitioning level. + * Here we convert to zero-based indexes, with -1 for empty entries. + * Also construct a Bitmapset of all partitions that are present (that + * is, not pruned already). */ - gotparam |= pull_partkey_params(pinfo, pruning_steps); + subplan_map = (int *) palloc(nparts * sizeof(int)); + memset(subplan_map, -1, nparts * sizeof(int)); + subpart_map = (int *) palloc(nparts * sizeof(int)); + memset(subpart_map, -1, nparts * sizeof(int)); + relid_map = (Oid *) palloc0(nparts * sizeof(Oid)); + present_parts = NULL; - pinfolist = lappend(pinfolist, pinfo); + for (i = 0; i < nparts; i++) + { + RelOptInfo *partrel = subpart->part_rels[i]; + int subplanidx; + int subpartidx; + + /* Skip processing pruned partitions. */ + if (partrel == NULL) + continue; + + subplan_map[i] = subplanidx = relid_subplan_map[partrel->relid] - 1; + subpart_map[i] = subpartidx = relid_subpart_map[partrel->relid] - 1; + relid_map[i] = planner_rt_fetch(partrel->relid, root)->relid; + if (subplanidx >= 0) + { + present_parts = bms_add_member(present_parts, i); + + /* Record finding this subplan */ + subplansfound = bms_add_member(subplansfound, subplanidx); + } + else if (subpartidx >= 0) + present_parts = bms_add_member(present_parts, i); + } + + /* Record the maps and other information. */ + pinfo->present_parts = present_parts; + pinfo->nparts = nparts; + pinfo->subplan_map = subplan_map; + pinfo->subpart_map = subpart_map; + pinfo->relid_map = relid_map; } - pfree(relid_subnode_map); pfree(relid_subpart_map); - if (gotparam) - return pinfolist; + *matchedsubplans = subplansfound; - /* - * If no Params were found to match the partition key on any of the - * partitioned relations then there's no point doing any run-time - * partition pruning. - */ - return NIL; + return pinfolist; } /* * gen_partprune_steps - * Process 'clauses' (a rel's baserestrictinfo list of clauses) and return - * a list of "partition pruning steps" + * Process 'clauses' (typically a rel's baserestrictinfo list of clauses) + * and create a list of "partition pruning steps". + * + * 'target' tells whether to generate pruning steps for planning (use + * immutable clauses only), or for executor startup (use any allowable + * clause except ones containing PARAM_EXEC Params), or for executor + * per-scan pruning (use any allowable clause). * - * If the clauses in the input list are contradictory or there is a - * pseudo-constant "false", *contradictory is set to true upon return. + * 'context' is an output argument that receives the steps list as well as + * some subsidiary flags; see the GeneratePruningStepsContext typedef. */ -List * -gen_partprune_steps(RelOptInfo *rel, List *clauses, bool *contradictory) +static void +gen_partprune_steps(RelOptInfo *rel, List *clauses, PartClauseTarget target, + GeneratePruningStepsContext *context) { - GeneratePruningStepsContext context; - - context.next_step_id = 0; - context.steps = NIL; - - /* The clauses list may be modified below, so better make a copy. */ - clauses = list_copy(clauses); + /* Initialize all output values to zero/false/NULL */ + memset(context, 0, sizeof(GeneratePruningStepsContext)); + context->rel = rel; + context->target = target; /* - * For sub-partitioned tables there's a corner case where if the - * sub-partitioned table shares any partition keys with its parent, then - * it's possible that the partitioning hierarchy allows the parent - * partition to only contain a narrower range of values than the - * sub-partitioned table does. In this case it is possible that we'd - * include partitions that could not possibly have any tuples matching - * 'clauses'. The possibility of such a partition arrangement is perhaps - * unlikely for non-default partitions, but it may be more likely in the - * case of default partitions, so we'll add the parent partition table's - * partition qual to the clause list in this case only. This may result - * in the default partition being eliminated. + * If this partitioned table is in turn a partition, and it shares any + * partition keys with its parent, then it's possible that the hierarchy + * allows the parent a narrower range of values than some of its + * partitions (particularly the default one). This is normally not + * useful, but it can be to prune the default partition. */ - if (partition_bound_has_default(rel->boundinfo) && - rel->partition_qual != NIL) + if (partition_bound_has_default(rel->boundinfo) && rel->partition_qual) { - List *partqual = rel->partition_qual; - - partqual = (List *) expression_planner((Expr *) partqual); - - /* Fix Vars to have the desired varno */ - if (rel->relid != 1) - ChangeVarNodes((Node *) partqual, 1, rel->relid, 0); - - clauses = list_concat(clauses, partqual); + /* Make a copy to avoid modifying the passed-in List */ + clauses = list_concat_copy(clauses, rel->partition_qual); } /* Down into the rabbit-hole. */ - gen_partprune_steps_internal(&context, rel, clauses, contradictory); - - return context.steps; + (void) gen_partprune_steps_internal(context, clauses); } /* * prune_append_rel_partitions - * Returns RT indexes of the minimum set of child partitions which must - * be scanned to satisfy rel's baserestrictinfo quals. + * Process rel's baserestrictinfo and make use of quals which can be + * evaluated during query planning in order to determine the minimum set + * of partitions which must be scanned to satisfy these quals. Returns + * the matching partitions in the form of a Bitmapset containing the + * partitions' indexes in the rel's part_rels array. * * Callers must ensure that 'rel' is a partitioned table. */ -Relids +Bitmapset * prune_append_rel_partitions(RelOptInfo *rel) { - Relids result; List *clauses = rel->baserestrictinfo; List *pruning_steps; - bool contradictory; + GeneratePruningStepsContext gcontext; PartitionPruneContext context; - Bitmapset *partindexes; - int i; - Assert(clauses != NIL); Assert(rel->part_scheme != NULL); /* If there are no partitions, return the empty set */ @@ -425,42 +661,54 @@ prune_append_rel_partitions(RelOptInfo *rel) return NULL; /* - * Process clauses. If the clauses are found to be contradictory, we can - * return the empty set. + * If pruning is disabled or if there are no clauses to prune with, return + * all partitions. */ - pruning_steps = gen_partprune_steps(rel, clauses, &contradictory); - if (contradictory) + if (!enable_partition_pruning || clauses == NIL) + return bms_add_range(NULL, 0, rel->nparts - 1); + + /* + * Process clauses to extract pruning steps that are usable at plan time. + * If the clauses are found to be contradictory, we can return the empty + * set. + */ + gen_partprune_steps(rel, clauses, PARTTARGET_PLANNER, + &gcontext); + if (gcontext.contradictory) return NULL; + pruning_steps = gcontext.steps; + + /* If there's nothing usable, return all partitions */ + if (pruning_steps == NIL) + return bms_add_range(NULL, 0, rel->nparts - 1); + /* Set up PartitionPruneContext */ context.strategy = rel->part_scheme->strategy; context.partnatts = rel->part_scheme->partnatts; - context.partopfamily = rel->part_scheme->partopfamily; - context.partopcintype = rel->part_scheme->partopcintype; - context.partcollation = rel->part_scheme->partcollation; - context.partsupfunc = rel->part_scheme->partsupfunc; context.nparts = rel->nparts; context.boundinfo = rel->boundinfo; + context.partcollation = rel->part_scheme->partcollation; + context.partsupfunc = rel->part_scheme->partsupfunc; + context.stepcmpfuncs = (FmgrInfo *) palloc0(sizeof(FmgrInfo) * + context.partnatts * + list_length(pruning_steps)); + context.ppccontext = CurrentMemoryContext; - /* Not valid when being called from the planner */ + /* These are not valid when being called from the planner */ context.planstate = NULL; - context.safeparams = NULL; + context.exprstates = NULL; /* Actual pruning happens here. */ - partindexes = get_matching_partitions(&context, pruning_steps); - - /* Add selected partitions' RT indexes to result. */ - i = -1; - result = NULL; - while ((i = bms_next_member(partindexes, i)) >= 0) - result = bms_add_member(result, rel->part_rels[i]->relid); - - return result; + return get_matching_partitions(&context, pruning_steps); } /* * get_matching_partitions * Determine partitions that survive partition pruning * + * Note: context->planstate must be set to a valid PlanState when the + * pruning_steps were generated with a target other than PARTTARGET_PLANNER. + * * Returns a Bitmapset of the RelOptInfo->part_rels indexes of the surviving * partitions. */ @@ -473,10 +721,14 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) PruneStepResult **results, *final_result; ListCell *lc; + bool scan_default; /* If there are no pruning steps then all partitions match. */ if (num_steps == 0) + { + Assert(context->nparts > 0); return bms_add_range(NULL, 0, context->nparts - 1); + } /* * Allocate space for individual pruning steps to store its result. Each @@ -521,30 +773,39 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) Assert(final_result != NULL); i = -1; result = NULL; + scan_default = final_result->scan_default; while ((i = bms_next_member(final_result->bound_offsets, i)) >= 0) { int partindex = context->boundinfo->indexes[i]; - /* - * In range and hash partitioning cases, some slots may contain -1, - * indicating that no partition has been defined to accept a given - * range of data or for a given remainder, respectively. The default - * partition, if any, in case of range partitioning, will be added to - * the result, because the specified range still satisfies the query's - * conditions. - */ - if (partindex >= 0) - result = bms_add_member(result, partindex); + if (partindex < 0) + { + /* + * In range partitioning cases, if a partition index is -1 it + * means that the bound at the offset is the upper bound for a + * range not covered by any partition (other than a possible + * default partition). In hash partitioning, the same means no + * partition has been defined for the corresponding remainder + * value. + * + * In either case, the value is still part of the queried range of + * values, so mark to scan the default partition if one exists. + */ + scan_default |= partition_bound_has_default(context->boundinfo); + continue; + } + + result = bms_add_member(result, partindex); } - /* Add the null and/or default partition if needed and if present. */ + /* Add the null and/or default partition if needed and present. */ if (final_result->scan_null) { Assert(context->strategy == PARTITION_STRATEGY_LIST); Assert(partition_bound_accepts_nulls(context->boundinfo)); result = bms_add_member(result, context->boundinfo->null_index); } - if (final_result->scan_default) + if (scan_default) { Assert(context->strategy == PARTITION_STRATEGY_LIST || context->strategy == PARTITION_STRATEGY_RANGE); @@ -570,23 +831,21 @@ get_matching_partitions(PartitionPruneContext *context, List *pruning_steps) * For BoolExpr clauses, we recursively generate steps for each argument, and * return a PartitionPruneStepCombine of their results. * - * The generated steps are added to the context's steps list. Each step is - * assigned a step identifier, unique even across recursive calls. + * The return value is a list of the steps generated, which are also added to + * the context's steps list. Each step is assigned a step identifier, unique + * even across recursive calls. * - * If we find clauses that are mutually contradictory, or a pseudoconstant - * clause that contains false, we set *contradictory to true and return NIL - * (that is, no pruning steps). Caller should consider all partitions as - * pruned in that case. Otherwise, *contradictory is set to false. - * - * Note: the 'clauses' List may be modified inside this function. Callers may - * like to make a copy of it before passing them to this function. + * If we find clauses that are mutually contradictory, or contradictory with + * the partitioning constraint, or a pseudoconstant clause that contains + * false, we set context->contradictory to true and return NIL (that is, no + * pruning steps). Caller should consider all partitions as pruned in that + * case. */ static List * gen_partprune_steps_internal(GeneratePruningStepsContext *context, - RelOptInfo *rel, List *clauses, - bool *contradictory) + List *clauses) { - PartitionScheme part_scheme = rel->part_scheme; + PartitionScheme part_scheme = context->rel->part_scheme; List *keyclauses[PARTITION_MAX_KEYS]; Bitmapset *nullkeys = NULL, *notnullkeys = NULL; @@ -594,7 +853,24 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, List *result = NIL; ListCell *lc; - *contradictory = false; + /* + * If this partitioned relation has a default partition and is itself + * a partition (as evidenced by partition_qual being not NIL), we first + * check if the clauses contradict the partition constraint. If they do, + * there's no need to generate any steps as it'd already be proven that no + * partitions need to be scanned. + * + * This is a measure of last resort only to be used because the default + * partition cannot be pruned using the steps generated from clauses that + * contradict the parent's partition constraint; regular pruning, which is + * cheaper, is sufficient when no default partition exists. + */ + if (partition_bound_has_default(context->rel->boundinfo) && + predicate_refuted_by(context->rel->partition_qual, clauses, false)) + { + context->contradictory = true; + return NIL; + } memset(keyclauses, 0, sizeof(keyclauses)); foreach(lc, clauses) @@ -602,18 +878,17 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, Expr *clause = (Expr *) lfirst(lc); int i; + /* Look through RestrictInfo, if any */ if (IsA(clause, RestrictInfo)) - { - RestrictInfo *rinfo = (RestrictInfo *) clause; + clause = ((RestrictInfo *) clause)->clause; - clause = rinfo->clause; - if (rinfo->pseudoconstant && - IsA(rinfo->clause, Const) && - !DatumGetBool(((Const *) clause)->constvalue)) - { - *contradictory = true; - return NIL; - } + /* Constant-false-or-null is contradictory */ + if (IsA(clause, Const) && + (((Const *) clause)->constisnull || + !DatumGetBool(((Const *) clause)->constvalue))) + { + context->contradictory = true; + return NIL; } /* Get the BoolExpr's out of the way. */ @@ -627,12 +902,18 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, * independently, collect their step IDs to be stored in the * combine step we'll be creating. */ - if (or_clause((Node *) clause)) + if (is_orclause(clause)) { List *arg_stepids = NIL; bool all_args_contradictory = true; ListCell *lc1; + /* + * We can share the outer context area with the recursive + * call, but contradictory had better not be true yet. + */ + Assert(!context->contradictory); + /* * Get pruning step for each arg. If we get contradictory for * all args, it means the OR expression is false as a whole. @@ -643,11 +924,18 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, bool arg_contradictory; List *argsteps; - argsteps = - gen_partprune_steps_internal(context, rel, - list_make1(arg), - &arg_contradictory); - if (!arg_contradictory) + argsteps = gen_partprune_steps_internal(context, + list_make1(arg)); + arg_contradictory = context->contradictory; + /* Keep context->contradictory clear till we're done */ + context->contradictory = false; + + if (arg_contradictory) + { + /* Just ignore self-contradictory arguments. */ + continue; + } + else all_args_contradictory = false; if (argsteps != NIL) @@ -660,52 +948,27 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } else { - /* - * No steps either means that arg_contradictory is - * true or the arg didn't contain a clause matching - * this partition key. - * - * In case of the latter, we cannot prune using such - * an arg. To indicate that to the pruning code, we - * must construct a dummy PartitionPruneStepCombine - * whose source_stepids is set to an empty List. - * However, if we can prove using constraint exclusion - * that the clause refutes the table's partition - * constraint (if it's sub-partitioned), we need not - * bother with that. That is, we effectively ignore - * this OR arm. - */ - List *partconstr = rel->partition_qual; PartitionPruneStep *orstep; - /* Just ignore this argument. */ - if (arg_contradictory) - continue; - - if (partconstr) - { - partconstr = (List *) - expression_planner((Expr *) partconstr); - if (rel->relid != 1) - ChangeVarNodes((Node *) partconstr, 1, - rel->relid, 0); - if (predicate_refuted_by(partconstr, - list_make1(arg), - false)) - continue; - } - + /* + * The arg didn't contain a clause matching this + * partition key. We cannot prune using such an arg. + * To indicate that to the pruning code, we must + * construct a dummy PartitionPruneStepCombine whose + * source_stepids is set to an empty List. + */ orstep = gen_prune_step_combine(context, NIL, PARTPRUNE_COMBINE_UNION); arg_stepids = lappend_int(arg_stepids, orstep->step_id); } } - *contradictory = all_args_contradictory; - - /* Check if any contradicting clauses were found */ - if (*contradictory) + /* If all the OR arms are contradictory, we can stop */ + if (all_args_contradictory) + { + context->contradictory = true; return NIL; + } if (arg_stepids != NIL) { @@ -717,7 +980,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } continue; } - else if (and_clause((Node *) clause)) + else if (is_andclause(clause)) { List *args = ((BoolExpr *) clause)->args; List *argsteps, @@ -729,9 +992,10 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, * recurse and later combine the component partitions sets * using a combine step. */ - argsteps = gen_partprune_steps_internal(context, rel, args, - contradictory); - if (*contradictory) + argsteps = gen_partprune_steps_internal(context, args); + + /* If any AND arm is contradictory, we can stop immediately */ + if (context->contradictory) return NIL; foreach(lc1, argsteps) @@ -761,17 +1025,16 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } /* - * Must be a clause for which we can check if one of its args matches - * the partition key. + * See if we can match this clause to any of the partition keys. */ for (i = 0; i < part_scheme->partnatts; i++) { - Expr *partkey = linitial(rel->partexprs[i]); + Expr *partkey = linitial(context->rel->partexprs[i]); bool clause_is_not_null = false; PartClauseInfo *pc = NULL; List *clause_steps = NIL; - switch (match_clause_to_partition_key(rel, context, + switch (match_clause_to_partition_key(context, clause, partkey, i, &clause_is_not_null, &pc, &clause_steps)) @@ -785,7 +1048,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, */ if (bms_is_member(i, nullkeys)) { - *contradictory = true; + context->contradictory = true; return NIL; } generate_opsteps = true; @@ -798,7 +1061,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, /* check for conflicting IS NOT NULL */ if (bms_is_member(i, notnullkeys)) { - *contradictory = true; + context->contradictory = true; return NIL; } nullkeys = bms_add_member(nullkeys, i); @@ -808,7 +1071,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, /* check for conflicting IS NULL */ if (bms_is_member(i, nullkeys)) { - *contradictory = true; + context->contradictory = true; return NIL; } notnullkeys = bms_add_member(notnullkeys, i); @@ -822,7 +1085,7 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, case PARTCLAUSE_MATCH_CONTRADICT: /* We've nothing more to do if a contradiction was found. */ - *contradictory = true; + context->contradictory = true; return NIL; case PARTCLAUSE_NOMATCH: @@ -836,10 +1099,6 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, case PARTCLAUSE_UNSUPPORTED: /* This clause cannot be used for pruning. */ break; - - default: - Assert(false); - break; } /* done; go check the next clause. */ @@ -847,54 +1106,59 @@ gen_partprune_steps_internal(GeneratePruningStepsContext *context, } } - /* - * If generate_opsteps is set to false it means no OpExprs were directly - * present in the input list. + /*----------- + * Now generate some (more) pruning steps. We have three strategies: + * + * 1) Generate pruning steps based on IS NULL clauses: + * a) For list partitioning, null partition keys can only be found in + * the designated null-accepting partition, so if there are IS NULL + * clauses containing partition keys we should generate a pruning + * step that gets rid of all partitions but that one. We can + * disregard any OpExpr we may have found. + * b) For range partitioning, only the default partition can contain + * NULL values, so the same rationale applies. + * c) For hash partitioning, we only apply this strategy if we have + * IS NULL clauses for all the keys. Strategy 2 below will take + * care of the case where some keys have OpExprs and others have + * IS NULL clauses. + * + * 2) If not, generate steps based on OpExprs we have (if any). + * + * 3) If this doesn't work either, we may be able to generate steps to + * prune just the null-accepting partition (if one exists), if we have + * IS NOT NULL clauses for all partition keys. */ - if (!generate_opsteps) + if (!bms_is_empty(nullkeys) && + (part_scheme->strategy == PARTITION_STRATEGY_LIST || + part_scheme->strategy == PARTITION_STRATEGY_RANGE || + (part_scheme->strategy == PARTITION_STRATEGY_HASH && + bms_num_members(nullkeys) == part_scheme->partnatts))) { - /* - * Generate one prune step for the information derived from IS NULL, - * if any. To prune hash partitions, we must have found IS NULL - * clauses for all partition keys. - */ - if (!bms_is_empty(nullkeys) && - (part_scheme->strategy != PARTITION_STRATEGY_HASH || - bms_num_members(nullkeys) == part_scheme->partnatts)) - { - PartitionPruneStep *step; - - step = gen_prune_step_op(context, InvalidStrategy, - false, NIL, NIL, nullkeys); - result = lappend(result, step); - } - - /* - * Note that for IS NOT NULL clauses, simply having step suffices; - * there is no need to propagate the exact details of which keys are - * required to be NOT NULL. Hash partitioning expects to see actual - * values to perform any pruning. - */ - if (!bms_is_empty(notnullkeys) && - part_scheme->strategy != PARTITION_STRATEGY_HASH) - { - PartitionPruneStep *step; + PartitionPruneStep *step; - step = gen_prune_step_op(context, InvalidStrategy, - false, NIL, NIL, NULL); - result = lappend(result, step); - } + /* Strategy 1 */ + step = gen_prune_step_op(context, InvalidStrategy, + false, NIL, NIL, nullkeys); + result = lappend(result, step); } - else + else if (generate_opsteps) { PartitionPruneStep *step; - /* Generate pruning steps from OpExpr clauses in keyclauses. */ - step = gen_prune_steps_from_opexps(part_scheme, context, - keyclauses, nullkeys); + /* Strategy 2 */ + step = gen_prune_steps_from_opexps(context, keyclauses, nullkeys); if (step != NULL) result = lappend(result, step); } + else if (bms_num_members(notnullkeys) == part_scheme->partnatts) + { + PartitionPruneStep *step; + + /* Strategy 3 */ + step = gen_prune_step_op(context, InvalidStrategy, + false, NIL, NIL, NULL); + result = lappend(result, step); + } /* * Finally, results from all entries appearing in result should be @@ -946,13 +1210,7 @@ gen_prune_step_op(GeneratePruningStepsContext *context, * InvalidStrategy to signal get_matching_list_bounds to do the right * thing. */ - if (op_is_ne) - { - Assert(opstrategy == BTEqualStrategyNumber); - opstep->opstrategy = InvalidStrategy; - } - else - opstep->opstrategy = opstrategy; + opstep->opstrategy = op_is_ne ? InvalidStrategy : opstrategy; Assert(list_length(exprs) == list_length(cmpfns)); opstep->exprs = exprs; opstep->cmpfns = cmpfns; @@ -997,18 +1255,15 @@ gen_prune_step_combine(GeneratePruningStepsContext *context, * found for any subsequent keys; see specific notes below. */ static PartitionPruneStep * -gen_prune_steps_from_opexps(PartitionScheme part_scheme, - GeneratePruningStepsContext *context, +gen_prune_steps_from_opexps(GeneratePruningStepsContext *context, List **keyclauses, Bitmapset *nullkeys) { - ListCell *lc; + PartitionScheme part_scheme = context->rel->part_scheme; List *opsteps = NIL; List *btree_clauses[BTMaxStrategyNumber + 1], *hash_clauses[HTMaxStrategyNumber + 1]; - bool need_next_less, - need_next_eq, - need_next_greater; int i; + ListCell *lc; memset(btree_clauses, 0, sizeof(btree_clauses)); memset(hash_clauses, 0, sizeof(hash_clauses)); @@ -1018,9 +1273,8 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, bool consider_next_key = true; /* - * To be useful for pruning, we must have clauses for a prefix of - * partition keys in the case of range partitioning. So, ignore - * clauses for keys after this one. + * For range partitioning, if we have no clauses for the current key, + * we can't consider any later keys either, so we can stop here. */ if (part_scheme->strategy == PARTITION_STRATEGY_RANGE && clauselist == NIL) @@ -1035,7 +1289,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, clauselist == NIL && !bms_is_member(i, nullkeys)) return NULL; - need_next_eq = need_next_less = need_next_greater = true; foreach(lc, clauselist) { PartClauseInfo *pc = (PartClauseInfo *) lfirst(lc); @@ -1057,7 +1310,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, case PARTITION_STRATEGY_RANGE: { PartClauseInfo *last = NULL; - bool inclusive = false; /* * Add this clause to the list of clauses to be used @@ -1075,35 +1327,13 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, lappend(btree_clauses[pc->op_strategy], pc); /* - * We may not need the next clause if they're of - * certain strategy. + * We can't consider subsequent partition keys if the + * clause for the current key contains a non-inclusive + * operator. */ - switch (pc->op_strategy) - { - case BTLessEqualStrategyNumber: - inclusive = true; - /* fall through */ - case BTLessStrategyNumber: - if (!inclusive) - need_next_eq = need_next_less = false; - break; - case BTEqualStrategyNumber: - /* always accept clauses for the next key. */ - break; - case BTGreaterEqualStrategyNumber: - inclusive = true; - /* fall through */ - case BTGreaterStrategyNumber: - if (!inclusive) - need_next_eq = need_next_greater = false; - break; - } - - /* We may want to change our mind. */ - if (consider_next_key) - consider_next_key = (need_next_eq || - need_next_less || - need_next_greater); + if (pc->op_strategy == BTLessStrategyNumber || + pc->op_strategy == BTGreaterStrategyNumber) + consider_next_key = false; break; } @@ -1237,7 +1467,7 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, pc->keyno, NULL, prefix); - opsteps = list_concat(opsteps, list_copy(pc_steps)); + opsteps = list_concat(opsteps, pc_steps); } } break; @@ -1281,14 +1511,14 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, /* * For each clause for the "last" column, after appending * the clause's own expression to the 'prefix', we'll - * generate one step using the so generated vector and and + * generate one step using the so generated vector and * assign = as its strategy. Actually, 'prefix' might * contain multiple clauses for the same key, in which * case, we must generate steps for various combinations * of expressions of different keys, which * get_steps_using_prefix will take care of for us. */ - for_each_cell(lc1, lc) + for_each_cell(lc1, eq_clauses, lc) { pc = lfirst(lc1); @@ -1308,7 +1538,7 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, pc->keyno, nullkeys, prefix); - opsteps = list_concat(opsteps, list_copy(pc_steps)); + opsteps = list_concat(opsteps, pc_steps); } } break; @@ -1377,32 +1607,34 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme, * Output arguments: *clause_steps is set to a list of PartitionPruneStep * generated for the clause. * - * * PARTCLAUSE_MATCH_CONTRADICT if the clause is self-contradictory. This can - * only happen if it's a BoolExpr whose arguments are self-contradictory. + * * PARTCLAUSE_MATCH_CONTRADICT if the clause is self-contradictory, ie + * it provably returns FALSE or NULL. * Output arguments: none set. * - * * PARTCLAUSE_UNSUPPORTED if the clause cannot be used for pruning at all - * due to one of its properties, such as argument volatility, even if it may - * have been matched with a key. + * * PARTCLAUSE_UNSUPPORTED if the clause doesn't match this partition key + * and couldn't possibly match any other one either, due to its form or + * properties (such as containing a volatile function). * Output arguments: none set. */ static PartClauseMatchStatus -match_clause_to_partition_key(RelOptInfo *rel, - GeneratePruningStepsContext *context, +match_clause_to_partition_key(GeneratePruningStepsContext *context, Expr *clause, Expr *partkey, int partkeyidx, bool *clause_is_not_null, PartClauseInfo **pc, List **clause_steps) { - PartitionScheme part_scheme = rel->part_scheme; - Expr *expr; + PartClauseMatchStatus boolmatchstatus; + PartitionScheme part_scheme = context->rel->part_scheme; Oid partopfamily = part_scheme->partopfamily[partkeyidx], partcoll = part_scheme->partcollation[partkeyidx]; + Expr *expr; /* - * Recognize specially shaped clauses that match with the Boolean - * partition key. + * Recognize specially shaped clauses that match a Boolean partition key. */ - if (match_boolean_partition_clause(partopfamily, clause, partkey, &expr)) + boolmatchstatus = match_boolean_partition_clause(partopfamily, clause, + partkey, &expr); + + if (boolmatchstatus == PARTCLAUSE_MATCH_CLAUSE) { PartClauseInfo *partclause; @@ -1413,7 +1645,7 @@ match_clause_to_partition_key(RelOptInfo *rel, partclause->op_is_ne = false; partclause->expr = expr; /* We know that expr is of Boolean type. */ - partclause->cmpfn = rel->part_scheme->partsupfunc[partkeyidx].fn_oid; + partclause->cmpfn = part_scheme->partsupfunc[partkeyidx].fn_oid; partclause->op_strategy = InvalidStrategy; *pc = partclause; @@ -1426,10 +1658,12 @@ match_clause_to_partition_key(RelOptInfo *rel, OpExpr *opclause = (OpExpr *) clause; Expr *leftop, *rightop; - Oid commutator = InvalidOid, + Oid opno, + op_lefttype, + op_righttype, negator = InvalidOid; Oid cmpfn; - Oid exprtype; + int op_strategy; bool is_opne_listp = false; PartClauseInfo *partclause; @@ -1439,142 +1673,231 @@ match_clause_to_partition_key(RelOptInfo *rel, rightop = (Expr *) get_rightop(clause); if (IsA(rightop, RelabelType)) rightop = ((RelabelType *) rightop)->arg; + opno = opclause->opno; /* check if the clause matches this partition key */ if (equal(leftop, partkey)) expr = rightop; else if (equal(rightop, partkey)) { - expr = leftop; - commutator = get_commutator(opclause->opno); - - /* nothing we can do unless we can swap the operands */ - if (!OidIsValid(commutator)) + /* + * It's only useful if we can commute the operator to put the + * partkey on the left. If we can't, the clause can be deemed + * UNSUPPORTED. Even if its leftop matches some later partkey, we + * now know it has Vars on the right, so it's no use. + */ + opno = get_commutator(opno); + if (!OidIsValid(opno)) return PARTCLAUSE_UNSUPPORTED; + expr = leftop; } else /* clause does not match this partition key, but perhaps next. */ return PARTCLAUSE_NOMATCH; /* - * Partition key also consists of a collation that's specified for it, - * so try to match it too. There may be multiple keys with the same - * expression but different collations. + * Partition key match also requires collation match. There may be + * multiple partkeys with the same expression but different + * collations, so failure is NOMATCH. */ if (!PartCollMatchesExprColl(partcoll, opclause->inputcollid)) return PARTCLAUSE_NOMATCH; /* - * Matched with this key. Now check various properties of the clause - * to see if it's sane to use it for pruning. If any of the - * properties makes it unsuitable for pruning, then the clause is - * useless no matter which key it's matched to. + * See if the operator is relevant to the partitioning opfamily. + * + * Normally we only care about operators that are listed as being part + * of the partitioning operator family. But there is one exception: + * the not-equals operators are not listed in any operator family + * whatsoever, but their negators (equality) are. We can use one of + * those if we find it, but only for list partitioning. + * + * Note: we report NOMATCH on failure, in case a later partkey has the + * same expression but different opfamily. That's unlikely, but not + * much more so than duplicate expressions with different collations. */ + if (op_in_opfamily(opno, partopfamily)) + { + get_op_opfamily_properties(opno, partopfamily, false, + &op_strategy, &op_lefttype, + &op_righttype); + } + else + { + if (part_scheme->strategy != PARTITION_STRATEGY_LIST) + return PARTCLAUSE_NOMATCH; + + /* See if the negator is equality */ + negator = get_negator(opno); + if (OidIsValid(negator) && op_in_opfamily(negator, partopfamily)) + { + get_op_opfamily_properties(negator, partopfamily, false, + &op_strategy, &op_lefttype, + &op_righttype); + if (op_strategy == BTEqualStrategyNumber) + is_opne_listp = true; /* bingo */ + } + + /* Nope, it's not <> either. */ + if (!is_opne_listp) + return PARTCLAUSE_NOMATCH; + } /* * Only allow strict operators. This will guarantee nulls are - * filtered. + * filtered. (This test is likely useless, since btree and hash + * comparison operators are generally strict.) */ - if (!op_strict(opclause->opno)) + if (!op_strict(opno)) return PARTCLAUSE_UNSUPPORTED; - /* We can't use any volatile expressions to prune partitions. */ - if (contain_volatile_functions((Node *) expr)) - return PARTCLAUSE_UNSUPPORTED; + /* + * OK, we have a match to the partition key and a suitable operator. + * Examine the other argument to see if it's usable for pruning. + * + * In most of these cases, we can return UNSUPPORTED because the same + * failure would occur no matter which partkey it's matched to. (In + * particular, now that we've successfully matched one side of the + * opclause to a partkey, there is no chance that matching the other + * side to another partkey will produce a usable result, since that'd + * mean there are Vars on both sides.) + * + * Also, if we reject an argument for a target-dependent reason, set + * appropriate fields of *context to report that. We postpone these + * tests until after matching the partkey and the operator, so as to + * reduce the odds of setting the context fields for clauses that do + * not end up contributing to pruning steps. + * + * First, check for non-Const argument. (We assume that any immutable + * subexpression will have been folded to a Const already.) + */ + if (!IsA(expr, Const)) + { + Bitmapset *paramids; + + /* + * When pruning in the planner, we only support pruning using + * comparisons to constants. We cannot prune on the basis of + * anything that's not immutable. (Note that has_mutable_arg and + * has_exec_param do not get set for this target value.) + */ + if (context->target == PARTTARGET_PLANNER) + return PARTCLAUSE_UNSUPPORTED; + + /* + * We can never prune using an expression that contains Vars. + */ + if (contain_var_clause((Node *) expr)) + return PARTCLAUSE_UNSUPPORTED; + + /* + * And we must reject anything containing a volatile function. + * Stable functions are OK though. + */ + if (contain_volatile_functions((Node *) expr)) + return PARTCLAUSE_UNSUPPORTED; + + /* + * See if there are any exec Params. If so, we can only use this + * expression during per-scan pruning. + */ + paramids = pull_exec_paramids(expr); + if (!bms_is_empty(paramids)) + { + context->has_exec_param = true; + if (context->target != PARTTARGET_EXEC) + return PARTCLAUSE_UNSUPPORTED; + } + else + { + /* It's potentially usable, but mutable */ + context->has_mutable_arg = true; + } + } /* - * Normally we only bother with operators that are listed as being - * part of the partitioning operator family. But we make an exception - * in one case -- operators named '<>' are not listed in any operator - * family whatsoever, in which case, we try to perform partition - * pruning with it only if list partitioning is in use. + * Check whether the comparison operator itself is immutable. (We + * assume anything that's in a btree or hash opclass is at least + * stable, but we need to check for immutability.) */ - if (!op_in_opfamily(opclause->opno, partopfamily)) + if (op_volatile(opno) != PROVOLATILE_IMMUTABLE) { - if (part_scheme->strategy != PARTITION_STRATEGY_LIST) - return PARTCLAUSE_UNSUPPORTED; + context->has_mutable_op = true; /* - * To confirm if the operator is really '<>', check if its negator - * is a btree equality operator. + * When pruning in the planner, we cannot prune with mutable + * operators. */ - negator = get_negator(opclause->opno); - if (OidIsValid(negator) && op_in_opfamily(negator, partopfamily)) - { - Oid lefttype; - Oid righttype; - int strategy; - - get_op_opfamily_properties(negator, partopfamily, false, - &strategy, &lefttype, &righttype); - - if (strategy == BTEqualStrategyNumber) - is_opne_listp = true; - } - - /* Operator isn't really what we were hoping it'd be. */ - if (!is_opne_listp) + if (context->target == PARTTARGET_PLANNER) return PARTCLAUSE_UNSUPPORTED; } - /* Check if we're going to need a cross-type comparison function. */ - exprtype = exprType((Node *) expr); - if (exprtype != part_scheme->partopcintype[partkeyidx]) + /* + * Now find the procedure to use, based on the types. If the clause's + * other argument is of the same type as the partitioning opclass's + * declared input type, we can use the procedure cached in + * PartitionKey. If not, search for a cross-type one in the same + * opfamily; if one doesn't exist, report no match. + */ + if (op_righttype == part_scheme->partopcintype[partkeyidx]) + cmpfn = part_scheme->partsupfunc[partkeyidx].fn_oid; + else { switch (part_scheme->strategy) { + /* + * For range and list partitioning, we need the ordering + * procedure with lefttype being the partition key's type, + * and righttype the clause's operator's right type. + */ case PARTITION_STRATEGY_LIST: case PARTITION_STRATEGY_RANGE: cmpfn = get_opfamily_proc(part_scheme->partopfamily[partkeyidx], part_scheme->partopcintype[partkeyidx], - exprtype, BTORDER_PROC); + op_righttype, BTORDER_PROC); break; + /* + * For hash partitioning, we need the hashing procedure + * for the clause's type. + */ case PARTITION_STRATEGY_HASH: cmpfn = get_opfamily_proc(part_scheme->partopfamily[partkeyidx], - exprtype, exprtype, HASHEXTENDED_PROC); + op_righttype, op_righttype, + HASHEXTENDED_PROC); break; default: elog(ERROR, "invalid partition strategy: %c", part_scheme->strategy); + cmpfn = InvalidOid; /* keep compiler quiet */ break; } - /* If we couldn't find one, we cannot use this expression. */ if (!OidIsValid(cmpfn)) - return PARTCLAUSE_UNSUPPORTED; + return PARTCLAUSE_NOMATCH; } - else - cmpfn = part_scheme->partsupfunc[partkeyidx].fn_oid; + /* + * Build the clause, passing the negator if applicable. + */ partclause = (PartClauseInfo *) palloc(sizeof(PartClauseInfo)); partclause->keyno = partkeyidx; - - /* For <> operator clauses, pass on the negator. */ - partclause->op_is_ne = false; - partclause->op_strategy = InvalidStrategy; - if (is_opne_listp) { Assert(OidIsValid(negator)); partclause->opno = negator; partclause->op_is_ne = true; - - /* - * We already know the strategy in this case, so may as well set - * it rather than having to look it up later. - */ - partclause->op_strategy = BTEqualStrategyNumber; + partclause->op_strategy = InvalidStrategy; } - /* And if commuted before matching, pass on the commutator */ - else if (OidIsValid(commutator)) - partclause->opno = commutator; else - partclause->opno = opclause->opno; - + { + partclause->opno = opno; + partclause->op_is_ne = false; + partclause->op_strategy = op_strategy; + } partclause->expr = expr; partclause->cmpfn = cmpfn; @@ -1596,39 +1919,25 @@ match_clause_to_partition_key(RelOptInfo *rel, if (IsA(leftop, RelabelType)) leftop = ((RelabelType *) leftop)->arg; - /* Check it matches this partition key */ + /* check if the LHS matches this partition key */ if (!equal(leftop, partkey) || !PartCollMatchesExprColl(partcoll, saop->inputcollid)) return PARTCLAUSE_NOMATCH; /* - * Matched with this key. Check various properties of the clause to - * see if it can sanely be used for partition pruning. - */ - - /* - * Only allow strict operators. This will guarantee nulls are - * filtered. - */ - if (!op_strict(saop->opno)) - return PARTCLAUSE_UNSUPPORTED; - - /* Useless if the array has any volatile functions. */ - if (contain_volatile_functions((Node *) rightop)) - return PARTCLAUSE_UNSUPPORTED; - - /* + * See if the operator is relevant to the partitioning opfamily. + * * In case of NOT IN (..), we get a '<>', which we handle if list * partitioning is in use and we're able to confirm that it's negator * is a btree equality operator belonging to the partitioning operator - * family. + * family. As above, report NOMATCH for non-matching operator. */ if (!op_in_opfamily(saop_op, partopfamily)) { Oid negator; if (part_scheme->strategy != PARTITION_STRATEGY_LIST) - return PARTCLAUSE_UNSUPPORTED; + return PARTCLAUSE_NOMATCH; negator = get_negator(saop_op); if (OidIsValid(negator) && op_in_opfamily(negator, partopfamily)) @@ -1641,19 +1950,98 @@ match_clause_to_partition_key(RelOptInfo *rel, false, &strategy, &lefttype, &righttype); if (strategy != BTEqualStrategyNumber) + return PARTCLAUSE_NOMATCH; + } + else + return PARTCLAUSE_NOMATCH; /* no useful negator */ + } + + /* + * Only allow strict operators. This will guarantee nulls are + * filtered. (This test is likely useless, since btree and hash + * comparison operators are generally strict.) + */ + if (!op_strict(saop_op)) + return PARTCLAUSE_UNSUPPORTED; + + /* + * OK, we have a match to the partition key and a suitable operator. + * Examine the array argument to see if it's usable for pruning. This + * is identical to the logic for a plain OpExpr. + */ + if (!IsA(rightop, Const)) + { + Bitmapset *paramids; + + /* + * When pruning in the planner, we only support pruning using + * comparisons to constants. We cannot prune on the basis of + * anything that's not immutable. (Note that has_mutable_arg and + * has_exec_param do not get set for this target value.) + */ + if (context->target == PARTTARGET_PLANNER) + return PARTCLAUSE_UNSUPPORTED; + + /* + * We can never prune using an expression that contains Vars. + */ + if (contain_var_clause((Node *) rightop)) + return PARTCLAUSE_UNSUPPORTED; + + /* + * And we must reject anything containing a volatile function. + * Stable functions are OK though. + */ + if (contain_volatile_functions((Node *) rightop)) + return PARTCLAUSE_UNSUPPORTED; + + /* + * See if there are any exec Params. If so, we can only use this + * expression during per-scan pruning. + */ + paramids = pull_exec_paramids(rightop); + if (!bms_is_empty(paramids)) + { + context->has_exec_param = true; + if (context->target != PARTTARGET_EXEC) return PARTCLAUSE_UNSUPPORTED; } + else + { + /* It's potentially usable, but mutable */ + context->has_mutable_arg = true; + } + } + + /* + * Check whether the comparison operator itself is immutable. (We + * assume anything that's in a btree or hash opclass is at least + * stable, but we need to check for immutability.) + */ + if (op_volatile(saop_op) != PROVOLATILE_IMMUTABLE) + { + context->has_mutable_op = true; + + /* + * When pruning in the planner, we cannot prune with mutable + * operators. + */ + if (context->target == PARTTARGET_PLANNER) + return PARTCLAUSE_UNSUPPORTED; } /* - * First generate a list of Const nodes, one for each array element - * (excepting nulls). + * Examine the contents of the array argument. */ elem_exprs = NIL; if (IsA(rightop, Const)) { - Const *arr = castNode(Const, rightop); - ArrayType *arrval = DatumGetArrayTypeP(arr->constvalue); + /* + * For a constant array, convert the elements to a list of Const + * nodes, one for each array element (excepting nulls). + */ + Const *arr = (Const *) rightop; + ArrayType *arrval; int16 elemlen; bool elembyval; char elemalign; @@ -1662,6 +2050,11 @@ match_clause_to_partition_key(RelOptInfo *rel, int num_elems, i; + /* If the array itself is null, the saop returns null */ + if (arr->constisnull) + return PARTCLAUSE_MATCH_CONTRADICT; + + arrval = DatumGetArrayTypeP(arr->constvalue); get_typlenbyvalalign(ARR_ELEMTYPE(arrval), &elemlen, &elembyval, &elemalign); deconstruct_array(arrval, @@ -1673,9 +2066,17 @@ match_clause_to_partition_key(RelOptInfo *rel, { Const *elem_expr; - /* Only consider non-null values. */ + /* + * A null array element must lead to a null comparison result, + * since saop_op is known strict. We can ignore it in the + * useOr case, but otherwise it implies self-contradiction. + */ if (elem_nulls[i]) - continue; + { + if (saop->useOr) + continue; + return PARTCLAUSE_MATCH_CONTRADICT; + } elem_expr = makeConst(ARR_ELEMTYPE(arrval), -1, arr->constcollid, elemlen, @@ -1683,7 +2084,7 @@ match_clause_to_partition_key(RelOptInfo *rel, elem_exprs = lappend(elem_exprs, elem_expr); } } - else + else if (IsA(rightop, ArrayExpr)) { ArrayExpr *arrexpr = castNode(ArrayExpr, rightop); @@ -1695,12 +2096,20 @@ match_clause_to_partition_key(RelOptInfo *rel, if (arrexpr->multidims) return PARTCLAUSE_UNSUPPORTED; + /* + * Otherwise, we can just use the list of element values. + */ elem_exprs = arrexpr->elements; } + else + { + /* Give up on any other clause types. */ + return PARTCLAUSE_UNSUPPORTED; + } /* * Now generate a list of clauses, one for each array element, of the - * form saop_leftop saop_op elem_expr + * form leftop saop_op elem_expr */ elem_clauses = NIL; foreach(lc1, elem_exprs) @@ -1715,36 +2124,19 @@ match_clause_to_partition_key(RelOptInfo *rel, } /* - * Build a combine step as if for an OR clause or add the clauses to - * the end of the list that's being processed currently. + * If we have an ANY clause and multiple elements, now turn the list + * of clauses into an OR expression. */ if (saop->useOr && list_length(elem_clauses) > 1) - { - Expr *orexpr; - bool contradictory; - - orexpr = makeBoolExpr(OR_EXPR, elem_clauses, -1); - *clause_steps = - gen_partprune_steps_internal(context, rel, list_make1(orexpr), - &contradictory); - if (contradictory) - return PARTCLAUSE_MATCH_CONTRADICT; - - Assert(list_length(*clause_steps) == 1); - return PARTCLAUSE_MATCH_STEPS; - } - else - { - bool contradictory; - - *clause_steps = - gen_partprune_steps_internal(context, rel, elem_clauses, - &contradictory); - if (contradictory) - return PARTCLAUSE_MATCH_CONTRADICT; - Assert(list_length(*clause_steps) >= 1); - return PARTCLAUSE_MATCH_STEPS; - } + elem_clauses = list_make1(makeBoolExpr(OR_EXPR, elem_clauses, -1)); + + /* Finally, generate steps */ + *clause_steps = gen_partprune_steps_internal(context, elem_clauses); + if (context->contradictory) + return PARTCLAUSE_MATCH_CONTRADICT; + else if (*clause_steps == NIL) + return PARTCLAUSE_UNSUPPORTED; /* step generation failed */ + return PARTCLAUSE_MATCH_STEPS; } else if (IsA(clause, NullTest)) { @@ -1758,12 +2150,26 @@ match_clause_to_partition_key(RelOptInfo *rel, if (!equal(arg, partkey)) return PARTCLAUSE_NOMATCH; - *clause_is_not_null = nulltest->nulltesttype == IS_NOT_NULL; + *clause_is_not_null = (nulltest->nulltesttype == IS_NOT_NULL); return PARTCLAUSE_MATCH_NULLNESS; } - return PARTCLAUSE_UNSUPPORTED; + /* + * If we get here then the return value depends on the result of the + * match_boolean_partition_clause call above. If the call returned + * PARTCLAUSE_UNSUPPORTED then we're either not dealing with a bool qual + * or the bool qual is not suitable for pruning. Since the qual didn't + * match up to any of the other qual types supported here, then trying to + * match it against any other partition key is a waste of time, so just + * return PARTCLAUSE_UNSUPPORTED. If the qual just couldn't be matched to + * this partition key, then it may match another, so return + * PARTCLAUSE_NOMATCH. The only other value that + * match_boolean_partition_clause can return is PARTCLAUSE_MATCH_CLAUSE, + * and since that value was already dealt with above, then we can just + * return boolmatchstatus. + */ + return boolmatchstatus; } /* @@ -1809,6 +2215,7 @@ get_steps_using_prefix(GeneratePruningStepsContext *context, step_lastcmpfn, step_lastkeyno, step_nullkeys, + prefix, list_head(prefix), NIL, NIL); } @@ -1820,6 +2227,7 @@ get_steps_using_prefix(GeneratePruningStepsContext *context, * column that is less than the one for which we're currently generating * steps (that is, step_lastkeyno) * + * 'prefix' is the list of PartClauseInfos. * 'start' is where we should start iterating for the current invocation. * 'step_exprs' and 'step_cmpfns' each contains the expressions and cmpfns * we've generated so far from the clauses for the previous part keys. @@ -1832,6 +2240,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, Oid step_lastcmpfn, int step_lastkeyno, Bitmapset *step_nullkeys, + List *prefix, ListCell *start, List *step_exprs, List *step_cmpfns) @@ -1857,7 +2266,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, * next_start to the ListCell of the first clause for the next * partition key. */ - for_each_cell(lc, start) + for_each_cell(lc, prefix, start) { pc = lfirst(lc); @@ -1866,7 +2275,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, } next_start = lc; - for_each_cell(lc, start) + for_each_cell(lc, prefix, start) { List *moresteps; @@ -1900,6 +2309,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, step_lastcmpfn, step_lastkeyno, step_nullkeys, + prefix, next_start, step_exprs, step_cmpfns); @@ -1914,7 +2324,7 @@ get_steps_using_prefix_recurse(GeneratePruningStepsContext *context, * till the end of the list. */ Assert(list_length(step_exprs) == cur_keyno); - for_each_cell(lc, start) + for_each_cell(lc, prefix, start) { PartClauseInfo *pc = lfirst(lc); PartitionPruneStep *step; @@ -1980,6 +2390,7 @@ get_matching_hash_bounds(PartitionPruneContext *context, int i; uint64 rowHash; int greatest_modulus; + Oid *partcollation = context->partcollation; Assert(context->strategy == PARTITION_STRATEGY_HASH); @@ -2000,15 +2411,20 @@ get_matching_hash_bounds(PartitionPruneContext *context, isnull[i] = bms_is_member(i, nullkeys); greatest_modulus = get_hash_partition_greatest_modulus(boundinfo); - rowHash = compute_hash_value(partnatts, partsupfunc, values, isnull); + rowHash = compute_partition_hash_value(partnatts, partsupfunc, partcollation, + values, isnull); if (partindices[rowHash % greatest_modulus] >= 0) result->bound_offsets = bms_make_singleton(rowHash % greatest_modulus); } else + { + /* Getting here means at least one hash partition exists. */ + Assert(boundinfo->ndatums > 0); result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); + } /* * There is neither a special hash null partition or the default hash @@ -2023,6 +2439,11 @@ get_matching_hash_bounds(PartitionPruneContext *context, * get_matching_list_bounds * Determine the offsets of list bounds matching the specified value, * according to the semantics of the given operator strategy + * + * scan_default will be set in the returned struct, if the default partition + * needs to be scanned, provided one exists at all. scan_null will be set if + * the special null-accepting partition needs to be scanned. + * * 'opstrategy' if non-zero must be a btree strategy number. * * 'value' contains the value to use for pruning. @@ -2087,6 +2508,7 @@ get_matching_list_bounds(PartitionPruneContext *context, */ if (nvalues == 0) { + Assert(boundinfo->ndatums > 0); result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); result->scan_default = partition_bound_has_default(boundinfo); @@ -2099,6 +2521,7 @@ get_matching_list_bounds(PartitionPruneContext *context, /* * First match to all bounds. We'll remove any matching datums below. */ + Assert(boundinfo->ndatums > 0); result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); @@ -2209,21 +2632,27 @@ get_matching_list_bounds(PartitionPruneContext *context, break; } + Assert(minoff >= 0 && maxoff >= 0); result->bound_offsets = bms_add_range(NULL, minoff, maxoff); return result; } /* - * get_matching_range_datums + * get_matching_range_bounds * Determine the offsets of range bounds matching the specified values, * according to the semantics of the given operator strategy * * Each datum whose offset is in result is to be treated as the upper bound of * the partition that will contain the desired values. * - * If default partition needs to be scanned for given values, set scan_default - * in result if present. + * scan_default is set in the returned struct if a default partition exists + * and we're absolutely certain that it needs to be scanned. We do *not* set + * it just because values match portions of the key space uncovered by + * partitions other than default (space which we normally assume to belong to + * the default partition): the final set of bounds obtained after combining + * multiple pruning steps might exclude it, so we infer its inclusion + * elsewhere. * * 'opstrategy' if non-zero must be a btree strategy number. * @@ -2249,8 +2678,7 @@ get_matching_range_bounds(PartitionPruneContext *context, int *partindices = boundinfo->indexes; int off, minoff, - maxoff, - i; + maxoff; bool is_equal; bool inclusive = false; @@ -2280,12 +2708,15 @@ get_matching_range_bounds(PartitionPruneContext *context, */ if (nvalues == 0) { + /* ignore key space not covered by any partitions */ if (partindices[minoff] < 0) minoff++; if (partindices[maxoff] < 0) maxoff--; result->scan_default = partition_bound_has_default(boundinfo); + Assert(partindices[minoff] >= 0 && + partindices[maxoff] >= 0); result->bound_offsets = bms_add_range(NULL, minoff, maxoff); return result; @@ -2293,7 +2724,7 @@ get_matching_range_bounds(PartitionPruneContext *context, /* * If the query does not constrain all key columns, we'll need to scan the - * the default partition, if any. + * default partition, if any. */ if (nvalues < partnatts) result->scan_default = partition_bound_has_default(boundinfo); @@ -2313,11 +2744,7 @@ get_matching_range_bounds(PartitionPruneContext *context, if (nvalues == partnatts) { /* There can only be zero or one matching partition. */ - if (partindices[off + 1] >= 0) - result->bound_offsets = bms_make_singleton(off + 1); - else - result->scan_default = - partition_bound_has_default(boundinfo); + result->bound_offsets = bms_make_singleton(off + 1); return result; } else @@ -2405,57 +2832,21 @@ get_matching_range_bounds(PartitionPruneContext *context, maxoff = off + 1; } - /* - * Skip if minoff/maxoff are actually the upper bound of a - * un-assigned portion of values. - */ - if (partindices[minoff] < 0 && minoff < boundinfo->ndatums) - minoff++; - if (partindices[maxoff] < 0 && maxoff >= 1) - maxoff--; - - /* - * There may exist a range of values unassigned to any - * non-default partition between the datums at minoff and - * maxoff. Add the default partition in that case. - */ - if (partition_bound_has_default(boundinfo)) - { - for (i = minoff; i <= maxoff; i++) - { - if (partindices[i] < 0) - { - result->scan_default = true; - break; - } - } - } - Assert(minoff >= 0 && maxoff >= 0); result->bound_offsets = bms_add_range(NULL, minoff, maxoff); } - else if (off >= 0) /* !is_equal */ + else { /* * The lookup value falls in the range between some bounds in * boundinfo. 'off' would be the offset of the greatest bound * that is <= lookup value, so add off + 1 to the result * instead as the offset of the upper bound of the only - * partition that may contain the lookup value. - */ - if (partindices[off + 1] >= 0) - result->bound_offsets = bms_make_singleton(off + 1); - else - result->scan_default = - partition_bound_has_default(boundinfo); - } - else - { - /* - * off < 0: the lookup value is smaller than all bounds, so - * only the default partition qualifies, if there is one. + * partition that may contain the lookup value. If 'off' is + * -1 indicating that all bounds are greater, then we simply + * end up adding the first bound's offset, that is, 0. */ - result->scan_default = partition_bound_has_default(boundinfo); + result->bound_offsets = bms_make_singleton(off + 1); } return result; @@ -2526,16 +2917,18 @@ get_matching_range_bounds(PartitionPruneContext *context, minoff = inclusive ? off : off + 1; } - - /* - * lookup value falls in the range between some bounds in - * boundinfo. off would be the offset of the greatest bound - * that is <= lookup value, so add off + 1 to the result - * instead as the offset of the upper bound of the smallest - * partition that may contain the lookup value. - */ else + { + + /* + * lookup value falls in the range between some bounds in + * boundinfo. off would be the offset of the greatest + * bound that is <= lookup value, so add off + 1 to the + * result instead as the offset of the upper bound of the + * smallest partition that may contain the lookup value. + */ minoff = off + 1; + } } break; @@ -2546,23 +2939,14 @@ get_matching_range_bounds(PartitionPruneContext *context, /* * Look for the greatest bound that is < or <= lookup value and - * set minoff to its offset. + * set maxoff to its offset. */ off = partition_range_datum_bsearch(partsupfunc, partcollation, boundinfo, nvalues, values, &is_equal); - if (off < 0) - { - /* - * All bounds are greater than the key, so we could only - * expect to find the lookup key in the default partition. - */ - result->scan_default = partition_bound_has_default(boundinfo); - return result; - } - else + if (off >= 0) { /* * See the comment above. @@ -2610,6 +2994,14 @@ get_matching_range_bounds(PartitionPruneContext *context, else maxoff = off; } + else + { + /* + * 'off' is -1 indicating that all bounds are greater, so just + * set the first bound's offset as maxoff. + */ + maxoff = off + 1; + } break; default: @@ -2617,58 +3009,43 @@ get_matching_range_bounds(PartitionPruneContext *context, break; } + Assert(minoff >= 0 && minoff <= boundinfo->ndatums); + Assert(maxoff >= 0 && maxoff <= boundinfo->ndatums); + /* - * Skip a gap and when doing so, check if the bound contains a finite - * value to decide if we need to add the default partition. If it's an - * infinite bound, we need not add the default partition, as having an - * infinite bound means the partition in question catches any values that - * would otherwise be in the default partition. + * If the smallest partition to return has MINVALUE (negative infinity) as + * its lower bound, increment it to point to the next finite bound + * (supposedly its upper bound), so that we don't advertently end up + * scanning the default partition. */ - if (partindices[minoff] < 0) + if (minoff < boundinfo->ndatums && partindices[minoff] < 0) { int lastkey = nvalues - 1; - if (minoff >= 0 && - minoff < boundinfo->ndatums && - boundinfo->kind[minoff][lastkey] == - PARTITION_RANGE_DATUM_VALUE) - result->scan_default = partition_bound_has_default(boundinfo); - - minoff++; + if (boundinfo->kind[minoff][lastkey] == + PARTITION_RANGE_DATUM_MINVALUE) + { + minoff++; + Assert(boundinfo->indexes[minoff] >= 0); + } } /* - * Skip a gap. See the above comment about how we decide whether or or - * not to scan the default partition based whether the datum that will - * become the maximum datum is finite or not. + * If the previous greatest partition has MAXVALUE (positive infinity) as + * its upper bound (something only possible to do with multi-column range + * partitioning), we scan switch to it as the greatest partition to + * return. Again, so that we don't advertently end up scanning the + * default partition. */ if (maxoff >= 1 && partindices[maxoff] < 0) { int lastkey = nvalues - 1; - if (maxoff >= 0 && - maxoff <= boundinfo->ndatums && - boundinfo->kind[maxoff - 1][lastkey] == - PARTITION_RANGE_DATUM_VALUE) - result->scan_default = partition_bound_has_default(boundinfo); - - maxoff--; - } - - if (partition_bound_has_default(boundinfo)) - { - /* - * There may exist a range of values unassigned to any non-default - * partition between the datums at minoff and maxoff. Add the default - * partition in that case. - */ - for (i = minoff; i <= maxoff; i++) + if (boundinfo->kind[maxoff - 1][lastkey] == + PARTITION_RANGE_DATUM_MAXVALUE) { - if (partindices[i] < 0) - { - result->scan_default = true; - break; - } + maxoff--; + Assert(boundinfo->indexes[maxoff] >= 0); } } @@ -2680,54 +3057,70 @@ get_matching_range_bounds(PartitionPruneContext *context, } /* - * pull_partkey_params - * Loop through each pruning step and record each external and exec - * Params being compared to the partition keys. + * pull_exec_paramids + * Returns a Bitmapset containing the paramids of all Params with + * paramkind = PARAM_EXEC in 'expr'. */ +static Bitmapset * +pull_exec_paramids(Expr *expr) +{ + Bitmapset *result = NULL; + + (void) pull_exec_paramids_walker((Node *) expr, &result); + + return result; +} + static bool -pull_partkey_params(PartitionPruneInfo *pinfo, List *steps) +pull_exec_paramids_walker(Node *node, Bitmapset **context) +{ + if (node == NULL) + return false; + if (IsA(node, Param)) + { + Param *param = (Param *) node; + + if (param->paramkind == PARAM_EXEC) + *context = bms_add_member(*context, param->paramid); + return false; + } + return expression_tree_walker(node, pull_exec_paramids_walker, + (void *) context); +} + +/* + * get_partkey_exec_paramids + * Loop through given pruning steps and find out which exec Params + * are used. + * + * Returns a Bitmapset of Param IDs. + */ +static Bitmapset * +get_partkey_exec_paramids(List *steps) { + Bitmapset *execparamids = NULL; ListCell *lc; - bool gotone = false; foreach(lc, steps) { - PartitionPruneStepOp *stepop = lfirst(lc); + PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc); ListCell *lc2; - if (!IsA(stepop, PartitionPruneStepOp)) + if (!IsA(step, PartitionPruneStepOp)) continue; - foreach(lc2, stepop->exprs) + foreach(lc2, step->exprs) { Expr *expr = lfirst(lc2); - if (IsA(expr, Param)) - { - Param *param = (Param *) expr; - - switch (param->paramkind) - { - case PARAM_EXTERN: - pinfo->extparams = bms_add_member(pinfo->extparams, - param->paramid); - break; - case PARAM_EXEC: - pinfo->execparams = bms_add_member(pinfo->execparams, - param->paramid); - break; - - default: - elog(ERROR, "unrecognized paramkind: %d", - (int) param->paramkind); - break; - } - gotone = true; - } + /* We can be quick for plain Consts */ + if (!IsA(expr, Const)) + execparamids = bms_join(execparamids, + pull_exec_paramids(expr)); } } - return gotone; + return execparamids; } /* @@ -2747,7 +3140,8 @@ perform_pruning_base_step(PartitionPruneContext *context, int keyno, nvalues; Datum values[PARTITION_MAX_KEYS]; - FmgrInfo partsupfunc[PARTITION_MAX_KEYS]; + FmgrInfo *partsupfunc; + int stateidx; /* * There better be the same number of expressions and compare functions. @@ -2783,35 +3177,67 @@ perform_pruning_base_step(PartitionPruneContext *context, { Expr *expr; Datum datum; + bool isnull; + Oid cmpfn; expr = lfirst(lc1); - if (partkey_datum_from_expr(context, expr, &datum)) + stateidx = PruneCxtStateIdx(context->partnatts, + opstep->step.step_id, keyno); + partkey_datum_from_expr(context, expr, stateidx, + &datum, &isnull); + + /* + * Since we only allow strict operators in pruning steps, any + * null-valued comparison value must cause the comparison to fail, + * so that no partitions could match. + */ + if (isnull) { - Oid cmpfn; + PruneStepResult *result; + result = (PruneStepResult *) palloc(sizeof(PruneStepResult)); + result->bound_offsets = NULL; + result->scan_default = false; + result->scan_null = false; + + return result; + } + + /* Set up the stepcmpfuncs entry, unless we already did */ + cmpfn = lfirst_oid(lc2); + Assert(OidIsValid(cmpfn)); + if (cmpfn != context->stepcmpfuncs[stateidx].fn_oid) + { /* - * If we're going to need a different comparison function than - * the one cached in the PartitionKey, we'll need to look up - * the FmgrInfo. + * If the needed support function is the same one cached in + * the relation's partition key, copy the cached FmgrInfo. + * Otherwise (i.e., when we have a cross-type comparison), an + * actual lookup is required. */ - cmpfn = lfirst_oid(lc2); - Assert(OidIsValid(cmpfn)); - if (cmpfn != context->partsupfunc[keyno].fn_oid) - fmgr_info(cmpfn, &partsupfunc[keyno]); - else - fmgr_info_copy(&partsupfunc[keyno], + if (cmpfn == context->partsupfunc[keyno].fn_oid) + fmgr_info_copy(&context->stepcmpfuncs[stateidx], &context->partsupfunc[keyno], - CurrentMemoryContext); - - values[keyno] = datum; - nvalues++; + context->ppccontext); + else + fmgr_info_cxt(cmpfn, &context->stepcmpfuncs[stateidx], + context->ppccontext); } - lc1 = lnext(lc1); - lc2 = lnext(lc2); + values[keyno] = datum; + nvalues++; + + lc1 = lnext(opstep->exprs, lc1); + lc2 = lnext(opstep->cmpfns, lc2); } } + /* + * Point partsupfunc to the entry for the 0th key of this step; the + * additional support functions, if any, follow consecutively. + */ + stateidx = PruneCxtStateIdx(context->partnatts, opstep->step.step_id, 0); + partsupfunc = &context->stepcmpfuncs[stateidx]; + switch (context->strategy) { case PARTITION_STRATEGY_HASH: @@ -2864,14 +3290,24 @@ perform_pruning_combine_step(PartitionPruneContext *context, /* * A combine step without any source steps is an indication to not perform - * any partition pruning, we just return all partitions. + * any partition pruning. Return all datum indexes in that case. */ result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); if (list_length(cstep->source_stepids) == 0) { PartitionBoundInfo boundinfo = context->boundinfo; + int rangemax; - result->bound_offsets = bms_add_range(NULL, 0, boundinfo->ndatums - 1); + /* + * Add all valid offsets into the boundinfo->indexes array. For range + * partitioning, boundinfo->indexes contains (boundinfo->ndatums + 1) + * valid entries; otherwise there are boundinfo->ndatums. + */ + rangemax = context->strategy == PARTITION_STRATEGY_RANGE ? + boundinfo->ndatums : boundinfo->ndatums - 1; + + result->bound_offsets = + bms_add_range(result->bound_offsets, 0, rangemax); result->scan_default = partition_bound_has_default(boundinfo); result->scan_null = partition_bound_accepts_nulls(boundinfo); return result; @@ -2944,10 +3380,6 @@ perform_pruning_combine_step(PartitionPruneContext *context, } } break; - - default: - elog(ERROR, "invalid pruning combine op: %d", - (int) cstep->combineOp); } return result; @@ -2956,11 +3388,15 @@ perform_pruning_combine_step(PartitionPruneContext *context, /* * match_boolean_partition_clause * - * Sets *outconst to a Const containing true or false value and returns true if - * we're able to match the clause to the partition key as specially-shaped - * Boolean clause. Returns false otherwise with *outconst set to NULL. + * If we're able to match the clause to the partition key as specially-shaped + * boolean clause, set *outconst to a Const containing a true or false value + * and return PARTCLAUSE_MATCH_CLAUSE. Returns PARTCLAUSE_UNSUPPORTED if the + * clause is not a boolean clause or if the boolean clause is unsuitable for + * partition pruning. Returns PARTCLAUSE_NOMATCH if it's a bool quals but + * just does not match this partition key. *outconst is set to NULL in the + * latter two cases. */ -static bool +static PartClauseMatchStatus match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey, Expr **outconst) { @@ -2969,7 +3405,7 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey, *outconst = NULL; if (!IsBooleanOpfamily(partopfamily)) - return false; + return PARTCLAUSE_UNSUPPORTED; if (IsA(clause, BooleanTest)) { @@ -2978,7 +3414,7 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey, /* Only IS [NOT] TRUE/FALSE are any good to us */ if (btest->booltesttype == IS_UNKNOWN || btest->booltesttype == IS_NOT_UNKNOWN) - return false; + return PARTCLAUSE_UNSUPPORTED; leftop = btest->arg; if (IsA(leftop, RelabelType)) @@ -2991,11 +3427,11 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey, : (Expr *) makeBoolConst(false, false); if (*outconst) - return true; + return PARTCLAUSE_MATCH_CLAUSE; } else { - bool is_not_clause = not_clause((Node *) clause); + bool is_not_clause = is_notclause(clause); leftop = is_not_clause ? get_notclausearg(clause) : clause; @@ -3011,53 +3447,52 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey, *outconst = (Expr *) makeBoolConst(false, false); if (*outconst) - return true; + return PARTCLAUSE_MATCH_CLAUSE; } - return false; + return PARTCLAUSE_NOMATCH; } /* * partkey_datum_from_expr - * Evaluate 'expr', set *value to the resulting Datum. Return true if - * evaluation was possible, otherwise false. + * Evaluate expression for potential partition pruning + * + * Evaluate 'expr'; set *value and *isnull to the resulting Datum and nullflag. + * + * If expr isn't a Const, its ExprState is in stateidx of the context + * exprstate array. + * + * Note that the evaluated result may be in the per-tuple memory context of + * context->planstate->ps_ExprContext, and we may have leaked other memory + * there too. This memory must be recovered by resetting that ExprContext + * after we're done with the pruning operation (see execPartition.c). */ -static bool +static void partkey_datum_from_expr(PartitionPruneContext *context, - Expr *expr, Datum *value) + Expr *expr, int stateidx, + Datum *value, bool *isnull) { - switch (nodeTag(expr)) + if (IsA(expr, Const)) { - case T_Const: - *value = ((Const *) expr)->constvalue; - return true; - - case T_Param: - - /* - * When being called from the executor we may be able to evaluate - * the Param's value. - */ - if (context->planstate && - bms_is_member(((Param *) expr)->paramid, context->safeparams)) - { - ExprState *exprstate; - bool isNull; + /* We can always determine the value of a constant */ + Const *con = (Const *) expr; - exprstate = ExecInitExpr(expr, context->planstate); - - *value = ExecEvalExprSwitchContext(exprstate, - context->planstate->ps_ExprContext, - &isNull); - if (isNull) - return false; + *value = con->constvalue; + *isnull = con->constisnull; + } + else + { + ExprState *exprstate; + ExprContext *ectx; - return true; - } + /* + * We should never see a non-Const in a step unless we're running in + * the executor. + */ + Assert(context->planstate != NULL); - default: - break; + exprstate = context->exprstates[stateidx]; + ectx = context->planstate->ps_ExprContext; + *value = ExecEvalExprSwitchContext(exprstate, ectx, isnull); } - - return false; } diff --git a/src/backend/po/de.po b/src/backend/po/de.po index 09622423fbb..494bfcc08b5 100644 --- a/src/backend/po/de.po +++ b/src/backend/po/de.po @@ -1,14 +1,14 @@ # German message translation file for PostgreSQL server -# Peter Eisentraut , 2001 - 2017. +# Peter Eisentraut , 2001 - 2018. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" +"Project-Id-Version: PostgreSQL 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-13 20:08+0000\n" -"PO-Revision-Date: 2017-03-13 17:04-0400\n" +"POT-Creation-Date: 2019-02-11 10:09+0000\n" +"PO-Revision-Date: 2019-02-11 13:08+0100\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -17,48 +17,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../common/config_info.c:131 ../common/config_info.c:139 -#: ../common/config_info.c:147 ../common/config_info.c:155 -#: ../common/config_info.c:163 ../common/config_info.c:171 -#: ../common/config_info.c:179 ../common/config_info.c:187 -#: ../common/config_info.c:195 +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 msgid "not recorded" msgstr "nicht aufgezeichnet" -#: ../common/controldata_utils.c:57 commands/copy.c:3028 -#: commands/extension.c:3323 utils/adt/genfile.c:134 +#: ../common/controldata_utils.c:58 commands/copy.c:3196 +#: commands/extension.c:3337 utils/adt/genfile.c:151 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: ../common/controldata_utils.c:61 +#: ../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: konnte Datei »%s« nicht zum Lesen öffnen: %s\n" -#: ../common/controldata_utils.c:71 access/transam/timeline.c:345 -#: access/transam/xlog.c:3368 access/transam/xlog.c:10701 -#: access/transam/xlog.c:10714 access/transam/xlog.c:11106 -#: access/transam/xlog.c:11149 access/transam/xlog.c:11188 -#: access/transam/xlog.c:11231 access/transam/xlogfuncs.c:664 -#: access/transam/xlogfuncs.c:683 commands/extension.c:3333 libpq/hba.c:496 -#: replication/logical/origin.c:658 replication/logical/origin.c:688 -#: replication/logical/reorderbuffer.c:3055 replication/walsender.c:469 -#: storage/file/copydir.c:176 utils/adt/genfile.c:151 utils/adt/misc.c:924 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 +#: access/transam/xlog.c:3440 access/transam/xlog.c:10942 +#: access/transam/xlog.c:10955 access/transam/xlog.c:11380 +#: access/transam/xlog.c:11460 access/transam/xlog.c:11499 +#: access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 +#: access/transam/xlogfuncs.c:677 commands/extension.c:3347 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3304 replication/walsender.c:510 +#: storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format msgid "could not read file \"%s\": %m" msgstr "konnte Datei »%s« nicht lesen: %m" -#: ../common/controldata_utils.c:74 +#: ../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: konnte Datei »%s« nicht lesen: %s\n" -#: ../common/controldata_utils.c:95 +#: ../common/controldata_utils.c:86 +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "konnte Datei »%s« nicht lesen: %d von %d gelesen" + +#: ../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: konnte Datei »%s« nicht lesen: %d von %d gelesen\n" + +#: ../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "falsche Byte-Reihenfolge" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -108,7 +118,7 @@ msgid "pclose failed: %s" msgstr "pclose fehlgeschlagen: %s" #: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:182 ../port/path.c:632 #: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 #: utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 #: utils/misc/ps_status.c:217 @@ -121,33 +131,33 @@ msgstr "Speicher aufgebraucht\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" -#: ../common/file_utils.c:82 ../common/file_utils.c:167 +#: ../common/file_utils.c:82 ../common/file_utils.c:186 #, c-format msgid "%s: could not stat file \"%s\": %s\n" msgstr "%s: konnte »stat« für Datei »%s« nicht ausführen: %s\n" -#: ../common/file_utils.c:143 +#: ../common/file_utils.c:162 #, c-format msgid "%s: could not open directory \"%s\": %s\n" msgstr "%s: konnte Verzeichnis »%s« nicht öffnen: %s\n" -#: ../common/file_utils.c:179 +#: ../common/file_utils.c:198 #, c-format msgid "%s: could not read directory \"%s\": %s\n" msgstr "%s: konnte Verzeichnis »%s« nicht lesen: %s\n" -#: ../common/file_utils.c:212 ../common/file_utils.c:272 -#: ../common/file_utils.c:348 +#: ../common/file_utils.c:231 ../common/file_utils.c:291 +#: ../common/file_utils.c:367 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: konnte Datei »%s« nicht öffnen: %s\n" -#: ../common/file_utils.c:285 ../common/file_utils.c:357 +#: ../common/file_utils.c:304 ../common/file_utils.c:376 #, c-format msgid "%s: could not fsync file \"%s\": %s\n" msgstr "%s: konnte Datei »%s« nicht fsyncen: %s\n" -#: ../common/file_utils.c:368 +#: ../common/file_utils.c:387 #, c-format msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" msgstr "%s: konnte Datei »%s« nicht in »%s« umbenennen: %s\n" @@ -167,43 +177,43 @@ msgstr "konnte Verzeichnis »%s« nicht lesen: %s\n" msgid "could not close directory \"%s\": %s\n" msgstr "konnte Verzeichnis »%s« nicht schließen: %s\n" -#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1261 -#: access/transam/xlog.c:6317 lib/stringinfo.c:300 libpq/auth.c:1011 -#: libpq/auth.c:1376 libpq/auth.c:1444 libpq/auth.c:1960 -#: postmaster/bgworker.c:318 postmaster/bgworker.c:874 -#: postmaster/postmaster.c:2363 postmaster/postmaster.c:2385 -#: postmaster/postmaster.c:3935 postmaster/postmaster.c:4635 -#: postmaster/postmaster.c:4710 postmaster/postmaster.c:5379 -#: postmaster/postmaster.c:5660 -#: replication/libpqwalreceiver/libpqwalreceiver.c:246 -#: replication/logical/logical.c:168 storage/buffer/localbuf.c:436 -#: storage/file/fd.c:736 storage/file/fd.c:1164 storage/file/fd.c:1282 -#: storage/file/fd.c:1993 storage/ipc/procarray.c:1054 -#: storage/ipc/procarray.c:1540 storage/ipc/procarray.c:1547 -#: storage/ipc/procarray.c:1961 storage/ipc/procarray.c:2564 -#: utils/adt/formatting.c:1509 utils/adt/formatting.c:1629 -#: utils/adt/formatting.c:1750 utils/adt/pg_locale.c:462 -#: utils/adt/pg_locale.c:646 utils/adt/regexp.c:219 utils/adt/varlena.c:4427 -#: utils/adt/varlena.c:4448 utils/fmgr/dfmgr.c:216 utils/hash/dynahash.c:429 -#: utils/hash/dynahash.c:535 utils/hash/dynahash.c:1047 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3954 utils/misc/guc.c:3970 -#: utils/misc/guc.c:3983 utils/misc/guc.c:6929 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:404 utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 -#: utils/mmgr/mcxt.c:725 utils/mmgr/mcxt.c:760 utils/mmgr/mcxt.c:797 -#: utils/mmgr/mcxt.c:834 utils/mmgr/mcxt.c:868 utils/mmgr/mcxt.c:897 -#: utils/mmgr/mcxt.c:931 utils/mmgr/mcxt.c:982 utils/mmgr/mcxt.c:1016 -#: utils/mmgr/mcxt.c:1050 +#: ../common/psprintf.c:180 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6482 +#: lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 +#: libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2390 +#: postmaster/postmaster.c:2412 postmaster/postmaster.c:3979 +#: postmaster/postmaster.c:4687 postmaster/postmaster.c:4762 +#: postmaster/postmaster.c:5454 postmaster/postmaster.c:5791 +#: replication/libpqwalreceiver/libpqwalreceiver.c:260 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:781 storage/file/fd.c:1220 storage/file/fd.c:1381 +#: storage/file/fd.c:2294 storage/ipc/procarray.c:1066 +#: storage/ipc/procarray.c:1554 storage/ipc/procarray.c:1561 +#: storage/ipc/procarray.c:1982 storage/ipc/procarray.c:2606 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 +#: utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 +#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4240 utils/misc/guc.c:4256 utils/misc/guc.c:4269 +#: utils/misc/guc.c:7244 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 utils/mmgr/generation.c:249 +#: utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 +#: utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 utils/mmgr/mcxt.c:975 +#: utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 +#: utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format msgid "out of memory" msgstr "Speicher aufgebraucht" -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "ungültiger Fork-Name" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "Gültige Fork-Namen sind »main«, »fsm«, »vm« und »init«." @@ -253,12 +263,17 @@ msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %s\ msgid "could not remove file or directory \"%s\": %s\n" msgstr "konnte Datei oder Verzeichnis »%s« nicht entfernen: %s\n" +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "Passwort zu lang" + #: ../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "konnte effektive Benutzer-ID %ld nicht nachschlagen: %s" -#: ../common/username.c:45 libpq/auth.c:1907 +#: ../common/username.c:45 libpq/auth.c:2038 msgid "user does not exist" msgstr "Benutzer existiert nicht" @@ -365,159 +380,209 @@ msgstr "konnte aktuelles Arbeitsverzeichnis nicht ermitteln: %s\n" msgid "unrecognized error %d" msgstr "unbekannter Fehler %d" -#: ../port/win32security.c:68 -#, c-format -msgid "could not open process token: error code %lu\n" -msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" - -#: ../port/win32security.c:89 +#: ../port/win32security.c:62 #, c-format msgid "could not get SID for Administrators group: error code %lu\n" msgstr "konnte SID der Administrators-Gruppe nicht ermitteln: Fehlercode %lu\n" -#: ../port/win32security.c:99 +#: ../port/win32security.c:72 #, c-format msgid "could not get SID for PowerUsers group: error code %lu\n" msgstr "konnte SID der PowerUsers-Gruppe nicht ermitteln: Fehlercode %lu\n" -#: access/brin/brin.c:820 +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "konnte Access-Token-Mitgliedschaft nicht prüfen: Fehlercode %lu\n" + +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 +#: access/transam/xlog.c:10354 access/transam/xlog.c:10881 +#: access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 +#: access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 +#: access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 +#: access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "Wiederherstellung läuft" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Während der Wiederherstellung können keine BRIN-Kontrollfunktionen ausgeführt werden." + +#: access/brin/brin.c:886 access/brin/brin.c:963 +#, c-format +msgid "block number out of range: %s" +msgstr "Blocknummer ist außerhalb des gültigen Bereichs: %s" + +#: access/brin/brin.c:909 access/brin/brin.c:986 #, c-format msgid "\"%s\" is not a BRIN index" msgstr "»%s« ist kein BRIN-Index" -#: access/brin/brin.c:836 +#: access/brin/brin.c:925 access/brin/brin.c:1002 #, c-format msgid "could not open parent table of index %s" msgstr "konnte Basistabelle von Index %s nicht öffnen" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:360 -#: access/brin/brin_pageops.c:826 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1381 access/nbtree/nbtinsert.c:678 +#: access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "Größe %zu der Indexzeile überschreitet Maximum %zu für Index »%s«" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "verfälschter BRIN-Index: inkonsistente Range-Map" + +#: access/brin/brin_revmap.c:404 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -msgstr "Größe %lu der Indexzeile überschreitet Maximum %lu für Index »%s«" +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "übrig gebliebenes Platzhaltertupel in BRIN-Index »%s« entdeckt, wird gelöscht" -#: access/brin/brin_revmap.c:459 +#: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "unerwarteter Seitentyp 0x%04X in BRIN-Index »%s« Block %u" -#: access/brin/brin_validate.c:116 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format -msgid "brin operator family \"%s\" contains function %s with invalid support number %d" -msgstr "BRIN-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Funktion %s mit ungültiger Support-Nummer %d" -#: access/brin/brin_validate.c:132 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format -msgid "brin operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "BRIN-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Funktion %s mit falscher Signatur für Support-Nummer %d" -#: access/brin/brin_validate.c:154 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 #, c-format -msgid "brin operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "BRIN-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Operator %s mit ungültiger Strategienummer %d" -#: access/brin/brin_validate.c:183 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:209 #, c-format -msgid "brin operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "BRIN-Operatorfamilie »%s« enthält ungültige ORDER-BY-Angabe für Operator %s" +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält ungültige ORDER-BY-Angabe für Operator %s" -#: access/brin/brin_validate.c:196 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 #, c-format -msgid "brin operator family \"%s\" contains operator %s with wrong signature" -msgstr "BRIN-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Operator %s mit falscher Signatur" -#: access/brin/brin_validate.c:234 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 #, c-format -msgid "brin operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "in BRIN-Operatorfamilie »%s« fehlen Operatoren für Typen %s und %s" +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen Operatoren für Typen %s und %s" #: access/brin/brin_validate.c:244 #, c-format -msgid "brin operator family \"%s\" is missing support function(s) for types %s and %s" -msgstr "in BRIN-Operatorfamilie »%s« fehlen Support-Funktionen für Typen %s und %s" +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen Support-Funktionen für Typen %s und %s" -#: access/brin/brin_validate.c:257 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format -msgid "brin operator class \"%s\" is missing operator(s)" -msgstr "in BRIN-Operatorklasse »%s« fehlen Operatoren" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlen Operatoren" -#: access/brin/brin_validate.c:268 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -msgid "brin operator class \"%s\" is missing support function %d" -msgstr "in BRIN-Operatorklasse »%s« fehlt Support-Funktion %d" +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1407 +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "Anzahl der Spalten (%d) überschreitet Maximum (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "Anzahl der Indexspalten (%d) überschreitet Maximum (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:647 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "Indexzeile benötigt %zu Bytes, Maximalgröße ist %zu" -#: access/common/printtup.c:290 tcop/fastpath.c:182 tcop/fastpath.c:544 -#: tcop/postgres.c:1727 +#: access/common/printtup.c:365 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1778 #, c-format msgid "unsupported format code: %d" msgstr "nicht unterstützter Formatcode: %d" -#: access/common/reloptions.c:531 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "Wertebereich des Typs für benutzerdefinierte Relationsparameter überschritten" -#: access/common/reloptions.c:812 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "RESET darf keinen Parameterwert enthalten" -#: access/common/reloptions.c:845 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "unbekannter Parameter-Namensraum »%s«" -#: access/common/reloptions.c:1087 parser/parse_clause.c:259 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "unbekannter Parameter »%s«" -#: access/common/reloptions.c:1117 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "Parameter »%s« mehrmals angegeben" -#: access/common/reloptions.c:1133 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "ungültiger Wert für Boole’sche Option »%s«: »%s«" -#: access/common/reloptions.c:1145 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "ungültiger Wert für ganzzahlige Option »%s«: »%s«" -#: access/common/reloptions.c:1151 access/common/reloptions.c:1171 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "Wert %s ist außerhalb des gültigen Bereichs für Option »%s«" -#: access/common/reloptions.c:1153 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "Gültige Werte sind zwischen »%d« und »%d«." -#: access/common/reloptions.c:1165 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "ungültiger Wert für Gleitkommaoption »%s«: »%s«" -#: access/common/reloptions.c:1173 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "Gültige Werte sind zwischen »%f« und »%f«." @@ -532,18 +597,18 @@ msgstr "Zurückgegebener Typ %1$s stimmt in Spalte %3$d nicht mit erwartetem Typ msgid "Number of returned columns (%d) does not match expected column count (%d)." msgstr "Anzahl der zurückgegebenen Spalten (%d) entspricht nicht der erwarteten Spaltenanzahl (%d)." -#: access/common/tupconvert.c:316 +#: access/common/tupconvert.c:329 #, c-format msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." msgstr "Attribut »%s« von Typ %s stimmt nicht mit dem entsprechenden Attribut von Typ %s überein." -#: access/common/tupconvert.c:328 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "Attribut »%s« von Typ %s existiert nicht in Typ %s." -#: access/common/tupdesc.c:722 parser/parse_clause.c:791 -#: parser/parse_relation.c:1517 +#: access/common/tupdesc.c:837 parser/parse_clause.c:819 +#: parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "Spalte »%s« kann nicht als SETOF deklariert werden" @@ -558,124 +623,79 @@ msgstr "Posting-Liste ist zu lang" msgid "Reduce maintenance_work_mem." msgstr "Reduzieren Sie maintenance_work_mem." -#: access/gin/ginentrypage.c:110 access/gist/gist.c:1363 -#: access/nbtree/nbtinsert.c:577 access/nbtree/nbtsort.c:488 -#: access/spgist/spgdoinsert.c:1933 -#, c-format -msgid "index row size %zu exceeds maximum %zu for index \"%s\"" -msgstr "Größe %zu der Indexzeile überschreitet Maximum %zu für Index »%s«" - -#: access/gin/ginfast.c:991 access/transam/xlog.c:10136 -#: access/transam/xlog.c:10640 access/transam/xlogfuncs.c:292 -#: access/transam/xlogfuncs.c:319 access/transam/xlogfuncs.c:358 -#: access/transam/xlogfuncs.c:379 access/transam/xlogfuncs.c:400 -#: access/transam/xlogfuncs.c:470 access/transam/xlogfuncs.c:526 -#, c-format -msgid "recovery is in progress" -msgstr "Wiederherstellung läuft" - -#: access/gin/ginfast.c:992 +#: access/gin/ginfast.c:1019 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "GIN-Pending-Liste kann nicht während der Wiederherstellung aufgeräumt werden." -#: access/gin/ginfast.c:999 +#: access/gin/ginfast.c:1026 #, c-format msgid "\"%s\" is not a GIN index" msgstr "»%s« ist kein GIN-Index" -#: access/gin/ginfast.c:1010 +#: access/gin/ginfast.c:1037 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "auf temporäre Indexe anderer Sitzungen kann nicht zugegriffen werden" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "alte GIN-Indexe unterstützen keine Scans des ganzen Index oder Suchen nach NULL-Werten" -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "Um das zu reparieren, führen Sie REINDEX INDEX \"%s\" aus." -#: access/gin/ginutil.c:134 executor/execQual.c:4865 -#: utils/adt/arrayfuncs.c:3803 utils/adt/arrayfuncs.c:6325 -#: utils/adt/rowtypes.c:927 +#: access/gin/ginutil.c:138 executor/execExpr.c:1868 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 +#: utils/adt/rowtypes.c:935 #, c-format msgid "could not identify a comparison function for type %s" msgstr "konnte keine Vergleichsfunktion für Typ %s ermitteln" -#: access/gin/ginvalidate.c:93 -#, c-format -msgid "gin operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "GIN-Operatorfamilie »%s« enthält Support-Prozedur %s mit typübergreifender Registrierung" - -#: access/gin/ginvalidate.c:149 -#, c-format -msgid "gin operator family \"%s\" contains function %s with invalid support number %d" -msgstr "GIN-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" - -#: access/gin/ginvalidate.c:161 -#, c-format -msgid "gin operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "GIN-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" - -#: access/gin/ginvalidate.c:180 -#, c-format -msgid "gin operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "GIN-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" - -#: access/gin/ginvalidate.c:193 -#, c-format -msgid "gin operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "GIN-Operatorfamilie »%s« enthält ungültige ORDER-BY-Angabe für Operator %s" - -#: access/gin/ginvalidate.c:206 -#, c-format -msgid "gin operator family \"%s\" contains operator %s with wrong signature" -msgstr "GIN-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" - -#: access/gin/ginvalidate.c:247 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format -msgid "gin operator class \"%s\" is missing support function %d" -msgstr "in GIN-Operatorklasse »%s« fehlt Support-Funktion %d" +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält Support-Funktion %s mit unterschiedlichen linken und rechten Eingabetypen" #: access/gin/ginvalidate.c:257 #, c-format -msgid "gin operator class \"%s\" is missing support function %d or %d" -msgstr "in GIN-Operatorklasse »%s« fehlt Support-Funktion %d oder %d" +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d oder %d" -#: access/gist/gist.c:706 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:717 access/gist/gistvacuum.c:258 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "Index »%s« enthält ein inneres Tupel, das als ungültig markiert ist" -#: access/gist/gist.c:708 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:719 access/gist/gistvacuum.c:260 #, c-format msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." msgstr "Das kommt von einem unvollständigen Page-Split bei der Crash-Recovery vor dem Upgrade auf PostgreSQL 9.1." -#: access/gist/gist.c:709 access/gist/gistutil.c:739 -#: access/gist/gistutil.c:750 access/gist/gistvacuum.c:261 -#: access/hash/hashutil.c:174 access/hash/hashutil.c:185 -#: access/hash/hashutil.c:197 access/hash/hashutil.c:218 -#: access/nbtree/nbtpage.c:519 access/nbtree/nbtpage.c:530 +#: access/gist/gist.c:720 access/gist/gistutil.c:759 access/gist/gistutil.c:770 +#: access/gist/gistvacuum.c:261 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 +#: access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "Bitte führen Sie REINDEX für den Index aus." -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:252 #, c-format msgid "invalid value for \"buffering\" option" msgstr "ungültiger Wert für Option »buffering«" -#: access/gist/gistbuild.c:251 +#: access/gist/gistbuild.c:253 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "Gültige Werte sind »on«, »off« und »auto«." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:231 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "konnte Block %ld von temporärer Datei nicht schreiben: %m" @@ -690,276 +710,206 @@ msgstr "Picksplit-Methode für Spalte %d von Index »%s« fehlgeschlagen" msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." msgstr "Der Index ist nicht optimal. Um ihn zu optimieren, kontaktieren Sie einen Entwickler oder versuchen Sie, die Spalte als die zweite im CREATE-INDEX-Befehl zu verwenden." -#: access/gist/gistutil.c:736 access/hash/hashutil.c:171 -#: access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "Index »%s« enthält unerwartete Nullseite bei Block %u" -#: access/gist/gistutil.c:747 access/hash/hashutil.c:182 -#: access/hash/hashutil.c:194 access/nbtree/nbtpage.c:527 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "Index »%s« enthält korrupte Seite bei Block %u" -#: access/gist/gistvalidate.c:93 -#, c-format -msgid "gist operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "GiST-Operatorfamilie »%s« enthält Support-Prozedur %s mit typübergreifender Registrierung" - -#: access/gist/gistvalidate.c:146 -#, c-format -msgid "gist operator family \"%s\" contains function %s with invalid support number %d" -msgstr "GiST-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" - -#: access/gist/gistvalidate.c:158 -#, c-format -msgid "gist operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "GiST-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" - -#: access/gist/gistvalidate.c:178 -#, c-format -msgid "gist operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "GiST-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" - #: access/gist/gistvalidate.c:196 #, c-format -msgid "gist operator family \"%s\" contains unsupported ORDER BY specification for operator %s" -msgstr "GiST-Operatorfamilie »%s« enthält nicht unterstützte ORDER-BY-Angabe für Operator %s" +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält nicht unterstützte ORDER-BY-Angabe für Operator %s" #: access/gist/gistvalidate.c:207 #, c-format -msgid "gist operator family \"%s\" contains incorrect ORDER BY opfamily specification for operator %s" -msgstr "GiST-Operatorfamilie »%s« enthält ungültige ORDER-BY-Operatorfamilienangabe für Operator %s" - -#: access/gist/gistvalidate.c:226 -#, c-format -msgid "gist operator family \"%s\" contains operator %s with wrong signature" -msgstr "GiST-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" - -#: access/gist/gistvalidate.c:265 -#, c-format -msgid "gist operator class \"%s\" is missing support function %d" -msgstr "in GiST-Operatorklasse »%s« fehlt Support-Funktion %d" +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "Operatorfamilie »%s« für Zugriffsmethode %s enthält ungültige ORDER-BY-Operatorfamilienangabe für Operator %s" -#: access/hash/hashinsert.c:74 +#: access/hash/hashinsert.c:83 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "Größe der Indexzeile %zu überschreitet Maximum für Hash-Index %zu" -#: access/hash/hashinsert.c:76 access/spgist/spgdoinsert.c:1937 -#: access/spgist/spgutils.c:708 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "Werte, die größer sind als eine Pufferseite, können nicht indiziert werden." -#: access/hash/hashovfl.c:84 -#, fuzzy, c-format -#| msgid "invalid port number: \"%s\"\n" +#: access/hash/hashovfl.c:87 +#, c-format msgid "invalid overflow block number %u" -msgstr "ungültige Portnummer: »%s«\n" +msgstr "ungültige Überlaufblocknummer %u" -#: access/hash/hashovfl.c:273 access/hash/hashpage.c:426 +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "keine Überlaufseiten in Hash-Index »%s« mehr" -#: access/hash/hashsearch.c:248 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "Hash-Indexe unterstützen keine Scans des ganzen Index" -#: access/hash/hashutil.c:210 +#: access/hash/hashutil.c:277 #, c-format msgid "index \"%s\" is not a hash index" msgstr "Index »%s« ist kein Hash-Index" -#: access/hash/hashutil.c:216 +#: access/hash/hashutil.c:283 #, c-format msgid "index \"%s\" has wrong hash version" msgstr "Index »%s« hat falsche Hash-Version" -#: access/hash/hashvalidate.c:99 -#, c-format -msgid "hash operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "Hash-Operatorfamilie »%s« enthält Support-Prozedur %s mit typübergreifender Registrierung" - -#: access/hash/hashvalidate.c:114 -#, c-format -msgid "hash operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "Hash-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" - -#: access/hash/hashvalidate.c:131 -#, c-format -msgid "hash operator family \"%s\" contains function %s with invalid support number %d" -msgstr "Hash-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" - -#: access/hash/hashvalidate.c:152 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "Hash-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" - -#: access/hash/hashvalidate.c:165 -#, c-format -msgid "hash operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "Hash-Operatorfamilie »%s« enthält ungültige ORDER-BY-Angabe für Operator %s" - -#: access/hash/hashvalidate.c:178 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with wrong signature" -msgstr "Hash-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" - -#: access/hash/hashvalidate.c:190 -#, c-format -msgid "hash operator family \"%s\" lacks support function for operator %s" -msgstr "in Hash-Operatorfamilie »%s« fehlt Support-Funktion für Operator %s" - -#: access/hash/hashvalidate.c:218 -#, c-format -msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "in Hash-Operatorfamilie »%s« fehlen Operatoren für Typen %s und %s" - -#: access/hash/hashvalidate.c:232 +#: access/hash/hashvalidate.c:191 #, c-format -msgid "hash operator class \"%s\" is missing operator(s)" -msgstr "in Hash-Operatorklasse »%s« fehlen Operatoren" +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion für Operator %s" -#: access/hash/hashvalidate.c:248 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "hash operator family \"%s\" is missing cross-type operator(s)" -msgstr "in Hash-Operatorfamilie »%s« fehlen typübergreifende Operatoren" +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlen typübergreifende Operatoren" -#: access/heap/heapam.c:1296 access/heap/heapam.c:1324 -#: access/heap/heapam.c:1356 catalog/aclchk.c:1754 +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 +#: access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" msgstr "»%s« ist ein Index" -#: access/heap/heapam.c:1301 access/heap/heapam.c:1329 -#: access/heap/heapam.c:1361 catalog/aclchk.c:1761 commands/tablecmds.c:9558 -#: commands/tablecmds.c:12769 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 +#: access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10837 +#: commands/tablecmds.c:14122 #, c-format msgid "\"%s\" is a composite type" msgstr "»%s« ist ein zusammengesetzter Typ" -#: access/heap/heapam.c:2595 +#: access/heap/heapam.c:2645 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "während einer parallelen Operation können keine Tupel eingefügt werden" +msgid "cannot insert tuples in a parallel worker" +msgstr "in einem parallelen Arbeitsprozess können keine Tupel eingefügt werden" -#: access/heap/heapam.c:3045 +#: access/heap/heapam.c:3092 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "während einer parallelen Operation können keine Tupel gelöscht werden" -#: access/heap/heapam.c:3091 +#: access/heap/heapam.c:3138 #, c-format msgid "attempted to delete invisible tuple" msgstr "Versuch ein unsichtbares Tupel zu löschen" -#: access/heap/heapam.c:3517 access/heap/heapam.c:6268 +#: access/heap/heapam.c:3572 access/heap/heapam.c:6409 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "während einer parallelen Operation können keine Tupel aktualisiert werden" -#: access/heap/heapam.c:3639 +#: access/heap/heapam.c:3720 #, c-format msgid "attempted to update invisible tuple" msgstr "Versuch ein unsichtbares Tupel zu aktualisieren" -#: access/heap/heapam.c:4991 access/heap/heapam.c:5029 -#: access/heap/heapam.c:5281 executor/execMain.c:2461 +#: access/heap/heapam.c:5085 access/heap/heapam.c:5123 +#: access/heap/heapam.c:5375 executor/execMain.c:2662 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "konnte Sperre für Zeile in Relation »%s« nicht setzen" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:664 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:682 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "Zeile ist zu groß: Größe ist %zu, Maximalgröße ist %zu" -#: access/heap/rewriteheap.c:923 +#: access/heap/rewriteheap.c:942 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "konnte nicht in Datei »%s« schreiben, %d von %d geschrieben: %m" -#: access/heap/rewriteheap.c:963 access/heap/rewriteheap.c:1175 -#: access/heap/rewriteheap.c:1272 access/transam/timeline.c:406 -#: access/transam/timeline.c:482 access/transam/xlog.c:3235 -#: access/transam/xlog.c:3397 replication/logical/snapbuild.c:1604 -#: replication/slot.c:1125 replication/slot.c:1210 storage/file/fd.c:631 -#: storage/file/fd.c:3129 storage/smgr/md.c:1043 storage/smgr/md.c:1276 -#: storage/smgr/md.c:1449 utils/misc/guc.c:6951 +#: access/heap/rewriteheap.c:982 access/heap/rewriteheap.c:1203 +#: access/heap/rewriteheap.c:1302 access/transam/timeline.c:411 +#: access/transam/timeline.c:490 access/transam/xlog.c:3307 +#: access/transam/xlog.c:3473 replication/logical/snapbuild.c:1648 +#: replication/slot.c:1313 replication/slot.c:1405 storage/file/fd.c:639 +#: storage/file/fd.c:3533 storage/smgr/md.c:1044 storage/smgr/md.c:1289 +#: storage/smgr/md.c:1463 utils/misc/guc.c:7266 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "konnte Datei »%s« nicht fsyncen: %m" -#: access/heap/rewriteheap.c:1018 access/heap/rewriteheap.c:1138 -#: access/transam/timeline.c:314 access/transam/timeline.c:460 -#: access/transam/xlog.c:3191 access/transam/xlog.c:3340 -#: access/transam/xlog.c:10470 access/transam/xlog.c:10508 -#: access/transam/xlog.c:10881 postmaster/postmaster.c:4410 -#: replication/logical/origin.c:535 replication/slot.c:1082 -#: storage/file/copydir.c:162 storage/smgr/md.c:326 utils/time/snapmgr.c:1275 +#: access/heap/rewriteheap.c:1036 access/heap/rewriteheap.c:1155 +#: access/transam/timeline.c:314 access/transam/timeline.c:465 +#: access/transam/xlog.c:3261 access/transam/xlog.c:3411 +#: access/transam/xlog.c:10692 access/transam/xlog.c:10730 +#: access/transam/xlog.c:11133 postmaster/postmaster.c:4454 +#: replication/logical/origin.c:575 replication/slot.c:1262 +#: storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 #, c-format msgid "could not create file \"%s\": %m" msgstr "konnte Datei »%s« nicht erstellen: %m" -#: access/heap/rewriteheap.c:1147 +#: access/heap/rewriteheap.c:1165 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" -#: access/heap/rewriteheap.c:1154 replication/walsender.c:451 -#: storage/smgr/md.c:1948 +#: access/heap/rewriteheap.c:1173 replication/walsender.c:490 +#: storage/smgr/md.c:1999 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "konnte Positionszeiger nicht ans Ende der Datei »%s« setzen: %m" -#: access/heap/rewriteheap.c:1165 access/transam/timeline.c:366 -#: access/transam/timeline.c:400 access/transam/timeline.c:476 -#: access/transam/xlog.c:3226 access/transam/xlog.c:3390 -#: postmaster/postmaster.c:4420 postmaster/postmaster.c:4430 -#: replication/logical/origin.c:544 replication/logical/origin.c:580 -#: replication/logical/origin.c:596 replication/logical/snapbuild.c:1588 -#: replication/slot.c:1111 storage/file/copydir.c:187 -#: utils/init/miscinit.c:1228 utils/init/miscinit.c:1237 -#: utils/init/miscinit.c:1244 utils/misc/guc.c:6912 utils/misc/guc.c:6943 -#: utils/misc/guc.c:8792 utils/misc/guc.c:8806 utils/time/snapmgr.c:1280 -#: utils/time/snapmgr.c:1287 +#: access/heap/rewriteheap.c:1190 access/transam/timeline.c:369 +#: access/transam/timeline.c:404 access/transam/timeline.c:482 +#: access/transam/xlog.c:3293 access/transam/xlog.c:3464 +#: postmaster/postmaster.c:4464 postmaster/postmaster.c:4474 +#: replication/logical/origin.c:590 replication/logical/origin.c:635 +#: replication/logical/origin.c:657 replication/logical/snapbuild.c:1624 +#: replication/slot.c:1296 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1349 utils/init/miscinit.c:1360 +#: utils/init/miscinit.c:1368 utils/misc/guc.c:7227 utils/misc/guc.c:7258 +#: utils/misc/guc.c:9120 utils/misc/guc.c:9134 utils/time/snapmgr.c:1302 +#: utils/time/snapmgr.c:1309 #, c-format msgid "could not write to file \"%s\": %m" msgstr "konnte nicht in Datei »%s« schreiben: %m" -#: access/heap/rewriteheap.c:1248 access/transam/xlog.c:10719 -#: access/transam/xlogarchive.c:113 access/transam/xlogarchive.c:467 -#: postmaster/postmaster.c:1239 postmaster/syslogger.c:1371 -#: replication/logical/origin.c:522 replication/logical/reorderbuffer.c:2588 -#: replication/logical/reorderbuffer.c:2645 -#: replication/logical/snapbuild.c:1532 replication/logical/snapbuild.c:1907 -#: replication/slot.c:1184 storage/ipc/dsm.c:327 storage/smgr/md.c:425 -#: storage/smgr/md.c:474 storage/smgr/md.c:1396 +#: access/heap/rewriteheap.c:1277 access/transam/xlogarchive.c:112 +#: access/transam/xlogarchive.c:459 postmaster/postmaster.c:1275 +#: postmaster/syslogger.c:1456 replication/logical/origin.c:563 +#: replication/logical/reorderbuffer.c:2810 +#: replication/logical/snapbuild.c:1567 replication/logical/snapbuild.c:1966 +#: replication/slot.c:1375 storage/file/fd.c:690 storage/file/fd.c:3133 +#: storage/file/fd.c:3195 storage/file/reinit.c:255 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1410 +#: utils/time/snapmgr.c:1640 #, c-format msgid "could not remove file \"%s\": %m" msgstr "konnte Datei »%s« nicht löschen: %m" -#: access/heap/rewriteheap.c:1262 access/transam/timeline.c:110 -#: access/transam/timeline.c:235 access/transam/timeline.c:333 -#: access/transam/xlog.c:3167 access/transam/xlog.c:3284 -#: access/transam/xlog.c:3325 access/transam/xlog.c:3598 -#: access/transam/xlog.c:3676 access/transam/xlogutils.c:702 -#: postmaster/syslogger.c:1380 replication/basebackup.c:474 -#: replication/basebackup.c:1218 replication/logical/origin.c:651 -#: replication/logical/reorderbuffer.c:2112 -#: replication/logical/reorderbuffer.c:2358 -#: replication/logical/reorderbuffer.c:3037 -#: replication/logical/snapbuild.c:1581 replication/logical/snapbuild.c:1665 -#: replication/slot.c:1199 replication/walsender.c:444 -#: replication/walsender.c:2055 storage/file/copydir.c:155 -#: storage/file/fd.c:614 storage/file/fd.c:3041 storage/file/fd.c:3108 -#: storage/smgr/md.c:607 utils/error/elog.c:1879 utils/init/miscinit.c:1163 -#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1359 utils/misc/guc.c:7171 -#: utils/misc/guc.c:7204 +#: access/heap/rewriteheap.c:1291 access/transam/timeline.c:111 +#: access/transam/timeline.c:236 access/transam/timeline.c:333 +#: access/transam/xlog.c:3238 access/transam/xlog.c:3356 +#: access/transam/xlog.c:3397 access/transam/xlog.c:3674 +#: access/transam/xlog.c:3752 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1465 replication/basebackup.c:517 +#: replication/basebackup.c:1391 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2304 +#: replication/logical/reorderbuffer.c:2571 +#: replication/logical/reorderbuffer.c:3284 +#: replication/logical/snapbuild.c:1610 replication/logical/snapbuild.c:1710 +#: replication/slot.c:1390 replication/walsender.c:483 +#: replication/walsender.c:2412 storage/file/copydir.c:161 +#: storage/file/fd.c:622 storage/file/fd.c:3428 storage/file/fd.c:3512 +#: storage/smgr/md.c:608 utils/error/elog.c:1872 utils/init/miscinit.c:1273 +#: utils/init/miscinit.c:1408 utils/init/miscinit.c:1485 utils/misc/guc.c:7486 +#: utils/misc/guc.c:7518 #, c-format msgid "could not open file \"%s\": %m" msgstr "konnte Datei »%s« nicht öffnen: %m" @@ -974,34 +924,34 @@ msgstr "Zugriffsmethode »%s« ist nicht vom Typ %s" msgid "index access method \"%s\" does not have a handler" msgstr "Indexzugriffsmethode »%s« hat keinen Handler" -#: access/index/indexam.c:160 catalog/objectaddress.c:1200 -#: commands/indexcmds.c:1811 commands/tablecmds.c:247 -#: commands/tablecmds.c:12760 +#: access/index/indexam.c:160 catalog/objectaddress.c:1223 +#: commands/indexcmds.c:2282 commands/tablecmds.c:249 commands/tablecmds.c:273 +#: commands/tablecmds.c:14113 commands/tablecmds.c:15406 #, c-format msgid "\"%s\" is not an index" msgstr "»%s« ist kein Index" -#: access/nbtree/nbtinsert.c:429 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "doppelter Schlüsselwert verletzt Unique-Constraint »%s«" -#: access/nbtree/nbtinsert.c:431 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." msgstr "Schlüssel »%s« existiert bereits." -#: access/nbtree/nbtinsert.c:498 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "konnte Tupel mit Index »%s« nicht erneut finden" -#: access/nbtree/nbtinsert.c:500 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "Das kann daran liegen, dass der Indexausdruck nicht »immutable« ist." -#: access/nbtree/nbtinsert.c:580 access/nbtree/nbtsort.c:491 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" @@ -1010,122 +960,47 @@ msgstr "" "Werte, die größer sind als 1/3 einer Pufferseite, können nicht indiziert werden.\n" "Erstellen Sie eventuell einen Funktionsindex auf einen MD5-Hash oder verwenden Sie Volltextindizierung." -#: access/nbtree/nbtpage.c:169 access/nbtree/nbtpage.c:372 -#: access/nbtree/nbtpage.c:459 parser/parse_utilcmd.c:1770 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 +#: access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2054 #, c-format msgid "index \"%s\" is not a btree" msgstr "Index »%s« ist kein B-Tree" -#: access/nbtree/nbtpage.c:175 access/nbtree/nbtpage.c:378 -#: access/nbtree/nbtpage.c:465 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 +#: access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "keine Versionsübereinstimmung in Index »%s«: Dateiversion %d, Code-Version %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "keine Versionsübereinstimmung in Index »%s«: Dateiversion %d, aktuelle Version %d, kleinste unterstützte Version %d" -#: access/nbtree/nbtpage.c:1153 +#: access/nbtree/nbtpage.c:1320 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "Index »%s« enthält eine halbtote interne Seite" -#: access/nbtree/nbtpage.c:1155 +#: access/nbtree/nbtpage.c:1322 #, c-format msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." msgstr "Die Ursache kann ein unterbrochenes VACUUM in Version 9.3 oder älter vor dem Upgrade sein. Bitte REINDEX durchführen." -#: access/nbtree/nbtvalidate.c:101 +#: access/nbtree/nbtvalidate.c:236 #, c-format -msgid "btree operator family \"%s\" contains function %s with invalid support number %d" -msgstr "B-Tree-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion für Typen %s und %s" -#: access/nbtree/nbtvalidate.c:113 +#: access/spgist/spgutils.c:136 #, c-format -msgid "btree operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "B-Tree-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" - -#: access/nbtree/nbtvalidate.c:133 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "B-Tree-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" - -#: access/nbtree/nbtvalidate.c:146 -#, c-format -msgid "btree operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "B-Tree-Operatorfamilie »%s« enthält ungültige ORDER-BY-Angabe für Operator %s" - -#: access/nbtree/nbtvalidate.c:159 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with wrong signature" -msgstr "B-Tree-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" - -#: access/nbtree/nbtvalidate.c:201 -#, c-format -msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "in B-Tree-Operatorfamilie »%s« fehlen Operatoren für Typen %s und %s" - -#: access/nbtree/nbtvalidate.c:211 -#, c-format -msgid "btree operator family \"%s\" is missing support function for types %s and %s" -msgstr "in B-Tree-Operatorfamilie »%s« fehlen Support-Funktionen für Typen %s und %s" - -#: access/nbtree/nbtvalidate.c:225 -#, c-format -msgid "btree operator class \"%s\" is missing operator(s)" -msgstr "in B-Tree-Operatorklasse »%s« fehlen Operatoren" - -#: access/nbtree/nbtvalidate.c:242 -#, c-format -msgid "btree operator family \"%s\" is missing cross-type operator(s)" -msgstr "in B-Tree-Operatorfamilie »%s« fehlen typübergreifende Operatoren" +msgid "compress method must be defined when leaf type is different from input type" +msgstr "" -#: access/spgist/spgutils.c:705 +#: access/spgist/spgutils.c:743 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "innere Tupelgröße %zu überschreitet SP-GiST-Maximum %zu" -#: access/spgist/spgvalidate.c:93 -#, c-format -msgid "spgist operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "SPGiST-Operatorfamilie »%s« enthält Support-Prozedur %s mit typübergreifender Registrierung" - -#: access/spgist/spgvalidate.c:116 -#, c-format -msgid "spgist operator family \"%s\" contains function %s with invalid support number %d" -msgstr "SPGiST-Operatorfamilie »%s« enthält Funktion %s mit ungültiger Support-Nummer %d" - -#: access/spgist/spgvalidate.c:128 -#, c-format -msgid "spgist operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "SPGiST-Operatorfamilie »%s« enthält Funktion %s mit falscher Signatur für Support-Nummer %d" - -#: access/spgist/spgvalidate.c:147 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "SPGiST-Operatorfamilie »%s« enthält Operator %s mit ungültiger Strategienummer %d" - -#: access/spgist/spgvalidate.c:160 -#, c-format -msgid "spgist operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "SPGiST-Operatorfamilie »%s« enthält ungültige ORDER-BY-Angabe für Operator %s" - -#: access/spgist/spgvalidate.c:173 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with wrong signature" -msgstr "SPGiST-Operatorfamilie »%s« enthält Operator %s mit falscher Signatur" - -#: access/spgist/spgvalidate.c:201 -#, c-format -msgid "spgist operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "in SPGiST-Operatorfamilie »%s« fehlen Operatoren für Typen %s und %s" - -#: access/spgist/spgvalidate.c:221 -#, c-format -msgid "spgist operator family \"%s\" is missing support function %d for type %s" -msgstr "in SPGiST-Operatorfamilie »%s« fehlt Support-Funktion %d für Typ %s" - -#: access/spgist/spgvalidate.c:234 +#: access/spgist/spgvalidate.c:269 #, c-format -msgid "spgist operator class \"%s\" is missing operator(s)" -msgstr "in SPGiST-Operatorklasse »%s« fehlen Operatoren" +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "in Operatorfamilie »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" #: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 #, c-format @@ -1162,24 +1037,24 @@ msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds erzeugen, um Dat #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Führen Sie ein datenbankweites VACUUM in dieser Datenbank aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." #: access/transam/multixact.c:1007 #, c-format msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" msgstr "Datenbank nimmt keine Befehle an, die neue MultiXactIds erzeugen, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank mit OID %u zu vermeiden" -#: access/transam/multixact.c:1028 access/transam/multixact.c:2314 +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 #, c-format msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" msgstr[0] "Datenbank »%s« muss gevacuumt werden, bevor %u weitere MultiXactId aufgebraucht ist" msgstr[1] "Datenbank »%s« muss gevacuumt werden, bevor %u weitere MultiXactIds aufgebraucht sind" -#: access/transam/multixact.c:1037 access/transam/multixact.c:2323 +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 #, c-format msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" @@ -1225,331 +1100,352 @@ msgstr "MultiXactId %u existiert nicht mehr -- anscheinender Überlauf" msgid "MultiXactId %u has not been created yet -- apparent wraparound" msgstr "MultiXactId %u wurde noch nicht erzeugt -- anscheinender Überlauf" -#: access/transam/multixact.c:2264 +#: access/transam/multixact.c:2268 #, c-format msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "Grenze für MultiXactId-Überlauf ist %u, begrenzt durch Datenbank mit OID %u" -#: access/transam/multixact.c:2319 access/transam/multixact.c:2328 +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 #: access/transam/varsup.c:146 access/transam/varsup.c:153 -#: access/transam/varsup.c:384 access/transam/varsup.c:391 +#: access/transam/varsup.c:405 access/transam/varsup.c:412 #, c-format msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Um ein Abschalten der Datenbank zu vermeiden, führen Sie ein komplettes VACUUM über diese Datenbank aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." -#: access/transam/multixact.c:2598 +#: access/transam/multixact.c:2602 #, c-format msgid "oldest MultiXactId member is at offset %u" msgstr "ältestes MultiXactId-Mitglied ist bei Offset %u" -#: access/transam/multixact.c:2602 +#: access/transam/multixact.c:2606 #, c-format msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" msgstr "MultiXact-Member-Wraparound-Schutz ist deaktiviert, weil die älteste gecheckpointete MultiXact %u nicht auf der Festplatte existiert" -#: access/transam/multixact.c:2624 +#: access/transam/multixact.c:2628 #, c-format msgid "MultiXact member wraparound protections are now enabled" msgstr "MultiXact-Member-Wraparound-Schutz ist jetzt aktiviert" -#: access/transam/multixact.c:2626 +#: access/transam/multixact.c:2631 #, c-format msgid "MultiXact member stop limit is now %u based on MultiXact %u" msgstr "MultiXact-Member-Stopp-Limit ist jetzt %u, basierend auf MultiXact %u" -#: access/transam/multixact.c:3006 +#: access/transam/multixact.c:3011 #, c-format msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" msgstr "älteste MultiXact %u nicht gefunden, älteste ist MultiXact %u, Truncate wird ausgelassen" -#: access/transam/multixact.c:3024 +#: access/transam/multixact.c:3029 #, c-format msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" msgstr "kann nicht bis MultiXact %u trunkieren, weil sie nicht auf der Festplatte existiert, Trunkierung wird ausgelassen" -#: access/transam/multixact.c:3350 +#: access/transam/multixact.c:3355 #, c-format msgid "invalid MultiXactId: %u" msgstr "ungültige MultiXactId: %u" -#: access/transam/parallel.c:592 +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "Initialisierung von parallelem Arbeitsprozess fehlgeschlagen" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "Weitere Einzelheiten sind möglicherweise im Serverlog zu finden." + +#: access/transam/parallel.c:849 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "Postmaster beendete während einer parallelen Transaktion" -#: access/transam/parallel.c:777 +#: access/transam/parallel.c:1036 #, c-format msgid "lost connection to parallel worker" msgstr "Verbindung mit parallelem Arbeitsprozess verloren" -#: access/transam/parallel.c:836 access/transam/parallel.c:838 +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 msgid "parallel worker" msgstr "paralleler Arbeitsprozess" -#: access/transam/parallel.c:977 +#: access/transam/parallel.c:1249 #, c-format msgid "could not map dynamic shared memory segment" msgstr "konnte dynamisches Shared-Memory-Segment nicht mappen" -#: access/transam/parallel.c:982 +#: access/transam/parallel.c:1254 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "ungültige magische Zahl in dynamischem Shared-Memory-Segment" -#: access/transam/slru.c:663 +#: access/transam/slru.c:668 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "Datei »%s« existiert nicht, wird als Nullen eingelesen" -#: access/transam/slru.c:893 access/transam/slru.c:899 -#: access/transam/slru.c:906 access/transam/slru.c:913 -#: access/transam/slru.c:920 access/transam/slru.c:927 +#: access/transam/slru.c:906 access/transam/slru.c:912 +#: access/transam/slru.c:919 access/transam/slru.c:926 +#: access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "konnte auf den Status von Transaktion %u nicht zugreifen" -#: access/transam/slru.c:894 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "Konnte Datei »%s« nicht öffnen: %m." -#: access/transam/slru.c:900 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "Konnte Positionszeiger in Datei »%s« nicht auf %u setzen: %m." -#: access/transam/slru.c:907 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "Konnte nicht aus Datei »%s« bei Position %u lesen: %m." -#: access/transam/slru.c:914 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "Konnte nicht in Datei »%s« bei Position %u schreiben: %m." -#: access/transam/slru.c:921 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "Konnte Datei »%s« nicht fsyncen: %m." -#: access/transam/slru.c:928 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "Konnte Datei »%s« nicht schließen: %m." -#: access/transam/slru.c:1183 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "konnte Verzeichnis »%s« nicht leeren: anscheinender Überlauf" -#: access/transam/slru.c:1238 access/transam/slru.c:1294 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "entferne Datei »%s«" -#: access/transam/timeline.c:147 access/transam/timeline.c:152 +#: access/transam/timeline.c:148 access/transam/timeline.c:153 #, c-format msgid "syntax error in history file: %s" msgstr "Syntaxfehler in History-Datei: %s" -#: access/transam/timeline.c:148 +#: access/transam/timeline.c:149 #, c-format msgid "Expected a numeric timeline ID." msgstr "Eine numerische Zeitleisten-ID wurde erwartet." -#: access/transam/timeline.c:153 +#: access/transam/timeline.c:154 #, c-format -msgid "Expected a transaction log switchpoint location." -msgstr "Eine Transaktionslog-Switchpoint-Position wurde erwartet." +msgid "Expected a write-ahead log switchpoint location." +msgstr "Eine Write-Ahead-Log-Switchpoint-Position wurde erwartet." -#: access/transam/timeline.c:157 +#: access/transam/timeline.c:158 #, c-format msgid "invalid data in history file: %s" msgstr "ungültige Daten in History-Datei: %s" -#: access/transam/timeline.c:158 +#: access/transam/timeline.c:159 #, c-format msgid "Timeline IDs must be in increasing sequence." msgstr "Zeitleisten-IDs müssen in aufsteigender Folge sein." -#: access/transam/timeline.c:178 +#: access/transam/timeline.c:179 #, c-format msgid "invalid data in history file \"%s\"" msgstr "ungültige Daten in History-Datei »%s«" -#: access/transam/timeline.c:179 +#: access/transam/timeline.c:180 #, c-format msgid "Timeline IDs must be less than child timeline's ID." msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein." -#: access/transam/timeline.c:411 access/transam/timeline.c:487 -#: access/transam/xlog.c:3241 access/transam/xlog.c:3402 -#: access/transam/xlogfuncs.c:689 commands/copy.c:1743 -#: storage/file/copydir.c:201 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 +#: access/transam/xlog.c:3314 access/transam/xlog.c:3479 +#: access/transam/xlogfuncs.c:683 commands/copy.c:1760 +#: storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "konnte Datei »%s« nicht schließen: %m" -#: access/transam/timeline.c:569 +#: access/transam/timeline.c:578 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "angeforderte Zeitleiste %u ist nicht in der History dieses Servers" -#: access/transam/twophase.c:362 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "Transaktionsbezeichner »%s« ist zu lang" -#: access/transam/twophase.c:369 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" msgstr "vorbereitete Transaktionen sind abgeschaltet" -#: access/transam/twophase.c:370 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "Setzen Sie max_prepared_transactions auf einen Wert höher als null." -#: access/transam/twophase.c:389 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "Transaktionsbezeichner »%s« wird bereits verwendet" -#: access/transam/twophase.c:398 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "maximale Anzahl vorbereiteter Transaktionen erreicht" -#: access/transam/twophase.c:399 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "Erhöhen Sie max_prepared_transactions (aktuell %d)." -#: access/transam/twophase.c:539 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "vorbereitete Transaktion mit Bezeichner »%s« ist beschäftigt" -#: access/transam/twophase.c:545 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" msgstr "keine Berechtigung, um vorbereitete Transaktion abzuschließen" -#: access/transam/twophase.c:546 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "Sie müssen Superuser oder der Benutzer sein, der die Transaktion vorbereitet hat." -#: access/transam/twophase.c:557 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" msgstr "vorbereitete Transaktion gehört zu einer anderen Datenbank" -#: access/transam/twophase.c:558 +#: access/transam/twophase.c:605 #, c-format msgid "Connect to the database where the transaction was prepared to finish it." msgstr "Verbinden Sie sich mit der Datenbank, wo die Transaktion vorbereitet wurde, um sie zu beenden." -#: access/transam/twophase.c:573 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "vorbereitete Transaktion mit Bezeichner »%s« existiert nicht" -#: access/transam/twophase.c:1042 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "maximale Länge der Zweiphasen-Statusdatei überschritten" -#: access/transam/twophase.c:1160 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "konnte Zweiphasen-Statusdatei »%s« nicht öffnen: %m" -#: access/transam/twophase.c:1177 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" msgstr "konnte »stat« für Zweiphasen-Statusdatei »%s« nicht ausführen: %m" -#: access/transam/twophase.c:1209 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "konnte Zweiphasen-Statusdatei »%s« nicht lesen: %m" -#: access/transam/twophase.c:1262 access/transam/xlog.c:6318 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Fehlgeschlagen beim Anlegen eines WAL-Leseprozessors." -#: access/transam/twophase.c:1268 +#: access/transam/twophase.c:1390 #, c-format msgid "could not read two-phase state from WAL at %X/%X" msgstr "konnte Zweiphasen-Status nicht aus dem WAL bei %X/%X lesen" -#: access/transam/twophase.c:1276 +#: access/transam/twophase.c:1398 #, c-format msgid "expected two-phase state data is not present in WAL at %X/%X" msgstr "erwartete Zweiphasen-Status-Daten sind nicht im WAL bei %X/%X vorhanden" -#: access/transam/twophase.c:1511 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "konnte Zweiphasen-Statusdatei »%s« nicht löschen: %m" -#: access/transam/twophase.c:1541 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "konnte Zweiphasen-Statusdatei »%s« nicht wieder erstellen: %m" -#: access/transam/twophase.c:1550 access/transam/twophase.c:1557 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 #, c-format msgid "could not write two-phase state file: %m" msgstr "konnte Zweiphasen-Statusdatei nicht schreiben: %m" -#: access/transam/twophase.c:1569 +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "konnte Zweiphasen-Statusdatei nicht fsyncen: %m" -#: access/transam/twophase.c:1575 +#: access/transam/twophase.c:1719 #, c-format msgid "could not close two-phase state file: %m" msgstr "konnte Zweiphasen-Statusdatei nicht schließen: %m" -#: access/transam/twophase.c:1648 -#, fuzzy, c-format -#| msgid "%u two-phase state file was written for long-running prepared transactions" -#| msgid_plural "%u two-phase state files were written for long-running prepared transactions" +#: access/transam/twophase.c:1807 +#, c-format msgid "%u two-phase state file was written for a long-running prepared transaction" msgid_plural "%u two-phase state files were written for long-running prepared transactions" -msgstr[0] "%u Zweiphasen-Statusdatei wurde für lange laufende vorbereitete Transaktionen geschrieben" +msgstr[0] "%u Zweiphasen-Statusdatei wurde für eine lange laufende vorbereitete Transaktion geschrieben" msgstr[1] "%u Zweiphasen-Statusdateien wurden für lange laufende vorbereitete Transaktionen geschrieben" -#: access/transam/twophase.c:1712 +#: access/transam/twophase.c:2036 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "Wiederherstellung der vorbereiteten Transaktion %u aus dem Shared Memory" + +#: access/transam/twophase.c:2126 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "entferne abgelaufene Zweiphasen-Statusdatei für Transaktion %u" + +#: access/transam/twophase.c:2133 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "entferne abgelaufenen Zweiphasen-Status aus dem Speicher für Transaktion %u" + +#: access/transam/twophase.c:2146 #, c-format -msgid "removing future two-phase state file \"%s\"" -msgstr "entferne Zweiphasen-Statusdatei aus der Zukunft »%s«" +msgid "removing future two-phase state file for transaction %u" +msgstr "entferne zukünftige Zweiphasen-Statusdatei für Transaktion %u" -#: access/transam/twophase.c:1728 access/transam/twophase.c:1739 -#: access/transam/twophase.c:1859 access/transam/twophase.c:1870 -#: access/transam/twophase.c:1947 +#: access/transam/twophase.c:2153 #, c-format -msgid "removing corrupt two-phase state file \"%s\"" -msgstr "entferne verfälschte Zweiphasen-Statusdatei »%s«" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "entferne zukünftigen Zweiphasen-Status aus dem Speicher für Transaktion %u" -#: access/transam/twophase.c:1848 access/transam/twophase.c:1936 +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 #, c-format -msgid "removing stale two-phase state file \"%s\"" -msgstr "entferne abgelaufene Zweiphasen-Statusdatei »%s«" +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "entferne verfälschte Zweiphasen-Statusdatei für Transaktion %u" -#: access/transam/twophase.c:1954 +#: access/transam/twophase.c:2193 #, c-format -msgid "recovering prepared transaction %u" -msgstr "Wiederherstellung der vorbereiteten Transaktion %u" +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "entferne verfälschten Zweiphasen-Status aus dem Speicher für Transaktion %u" #: access/transam/varsup.c:124 #, c-format @@ -1560,1174 +1456,1194 @@ msgstr "Datenbank nimmt keine Befehle an, um Datenverlust wegen Transaktionsnumm #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Halten Sie den Postmaster an und führen Sie in dieser Datenbank VACUUM im Einzelbenutzermodus aus.\n" -"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen." +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." #: access/transam/varsup.c:131 #, c-format msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" msgstr "Datenbank nimmt keine Befehle an, um Datenverlust wegen Transaktionsnummernüberlauf in Datenbank mit OID %u zu vermeiden" -#: access/transam/varsup.c:143 access/transam/varsup.c:381 +#: access/transam/varsup.c:143 access/transam/varsup.c:402 #, c-format msgid "database \"%s\" must be vacuumed within %u transactions" msgstr "Datenbank »%s« muss innerhalb von %u Transaktionen gevacuumt werden" -#: access/transam/varsup.c:150 access/transam/varsup.c:388 +#: access/transam/varsup.c:150 access/transam/varsup.c:409 #, c-format msgid "database with OID %u must be vacuumed within %u transactions" msgstr "Datenbank mit OID %u muss innerhalb von %u Transaktionen gevacuumt werden" -#: access/transam/varsup.c:346 +#: access/transam/varsup.c:367 #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "Grenze für Transaktionsnummernüberlauf ist %u, begrenzt durch Datenbank mit OID %u" -#: access/transam/xact.c:945 +#: access/transam/xact.c:960 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "kann nicht mehr als 2^32-2 Befehle in einer Transaktion ausführen" -#: access/transam/xact.c:1469 +#: access/transam/xact.c:1485 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "maximale Anzahl committeter Subtransaktionen (%d) überschritten" -#: access/transam/xact.c:2266 +#: access/transam/xact.c:2296 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die temporäre Tabellen bearbeitet hat" -#: access/transam/xact.c:2276 +#: access/transam/xact.c:2308 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die temporäre Objekte bearbeitet hat" + +#: access/transam/xact.c:2318 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die Snapshots exportiert hat" +#: access/transam/xact.c:2327 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "PREPARE kann nicht für eine Transaktion ausgeführt werden, die Arbeitsprozesse für logische Replikation manipuliert hat" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3161 +#: access/transam/xact.c:3212 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s kann nicht in einem Transaktionsblock laufen" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3171 +#: access/transam/xact.c:3222 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s kann nicht in einer Subtransaktion laufen" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3181 +#: access/transam/xact.c:3232 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "%s kann nicht aus einer Funktion oder einer mehrbefehligen Zeichenkette heraus ausgeführt werden" +msgid "%s cannot be executed from a function" +msgstr "%s kann nicht aus einer Funktion ausgerufen werden" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3252 +#: access/transam/xact.c:3301 access/transam/xact.c:3925 +#: access/transam/xact.c:3994 access/transam/xact.c:4105 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s kann nur in Transaktionsblöcken verwendet werden" -#: access/transam/xact.c:3436 +#: access/transam/xact.c:3494 #, c-format msgid "there is already a transaction in progress" msgstr "eine Transaktion ist bereits begonnen" -#: access/transam/xact.c:3604 access/transam/xact.c:3707 +#: access/transam/xact.c:3605 access/transam/xact.c:3675 +#: access/transam/xact.c:3784 #, c-format msgid "there is no transaction in progress" msgstr "keine Transaktion offen" -#: access/transam/xact.c:3615 +#: access/transam/xact.c:3686 #, c-format msgid "cannot commit during a parallel operation" msgstr "während einer parallelen Operation kann nicht committet werden" -#: access/transam/xact.c:3718 +#: access/transam/xact.c:3795 #, c-format msgid "cannot abort during a parallel operation" msgstr "während einer parallelen Operation kann nicht abgebrochen werden" -#: access/transam/xact.c:3760 +#: access/transam/xact.c:3889 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "während einer parallelen Operation können keine Sicherungspunkte definiert werden" -#: access/transam/xact.c:3827 +#: access/transam/xact.c:3976 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "während einer parallelen Operation können keine Sicherungspunkte freigegeben werden" -#: access/transam/xact.c:3838 access/transam/xact.c:3890 -#: access/transam/xact.c:3896 access/transam/xact.c:3952 -#: access/transam/xact.c:4002 access/transam/xact.c:4008 +#: access/transam/xact.c:3986 access/transam/xact.c:4037 +#: access/transam/xact.c:4097 access/transam/xact.c:4146 #, c-format -msgid "no such savepoint" -msgstr "Sicherungspunkt existiert nicht" +msgid "savepoint \"%s\" does not exist" +msgstr "Sicherungspunkt »%s« existiert nicht" + +#: access/transam/xact.c:4043 access/transam/xact.c:4152 +#, fuzzy, c-format +#| msgid "user mapping for \"%s\" does not exist for the server" +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "Benutzerabbildung für »%s« existiert für den Server nicht" -#: access/transam/xact.c:3940 +#: access/transam/xact.c:4085 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "während einer parallelen Operation kann nicht auf einen Sicherungspunkt zurückgerollt werden" -#: access/transam/xact.c:4068 +#: access/transam/xact.c:4213 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "während einer parallelen Operation können keine Subtransaktionen gestartet werden" -#: access/transam/xact.c:4135 +#: access/transam/xact.c:4281 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "während einer parallelen Operation können keine Subtransaktionen committet werden" -#: access/transam/xact.c:4743 +#: access/transam/xact.c:4919 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "kann nicht mehr als 2^32-1 Subtransaktionen in einer Transaktion haben" -#: access/transam/xlog.c:2446 +#: access/transam/xlog.c:2492 #, c-format msgid "could not seek in log file %s to offset %u: %m" msgstr "konnte Positionszeiger in Logdatei %s nicht auf %u setzen: %m" -#: access/transam/xlog.c:2466 +#: access/transam/xlog.c:2514 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "konnte nicht in Logdatei %s bei Position %u, Länge %zu schreiben: %m" -#: access/transam/xlog.c:2730 +#: access/transam/xlog.c:2792 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "minimaler Recovery-Punkt auf %X/%X auf Zeitleiste %u aktualisiert" -#: access/transam/xlog.c:3372 +#: access/transam/xlog.c:3444 #, c-format msgid "not enough data in file \"%s\"" msgstr "nicht genug Daten in Datei »%s«" -#: access/transam/xlog.c:3513 +#: access/transam/xlog.c:3589 #, c-format -msgid "could not open transaction log file \"%s\": %m" -msgstr "konnte Transaktionslogdatei »%s« nicht öffnen: %m" +msgid "could not open write-ahead log file \"%s\": %m" +msgstr "konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %m" -#: access/transam/xlog.c:3702 access/transam/xlog.c:5503 +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 #, c-format msgid "could not close log file %s: %m" msgstr "konnte Logdatei %s nicht schließen: %m" -#: access/transam/xlog.c:3759 access/transam/xlogutils.c:697 -#: replication/walsender.c:2050 +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 +#: replication/walsender.c:2407 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "das angeforderte WAL-Segment %s wurde schon entfernt" -#: access/transam/xlog.c:3819 access/transam/xlog.c:3894 -#: access/transam/xlog.c:4092 -#, c-format -msgid "could not open transaction log directory \"%s\": %m" -msgstr "konnte Transaktionslog-Verzeichnis »%s« nicht öffnen: %m" - -#: access/transam/xlog.c:3975 -#, c-format -msgid "recycled transaction log file \"%s\"" -msgstr "Transaktionslogdatei »%s« wird wiederverwendet" - -#: access/transam/xlog.c:3987 +#: access/transam/xlog.c:4051 #, c-format -msgid "removing transaction log file \"%s\"" -msgstr "entferne Transaktionslogdatei »%s«" +msgid "recycled write-ahead log file \"%s\"" +msgstr "Write-Ahead-Log-Datei »%s« wird wiederverwendet" -#: access/transam/xlog.c:4007 +#: access/transam/xlog.c:4063 #, c-format -msgid "could not rename old transaction log file \"%s\": %m" -msgstr "konnte alte Transaktionslogdatei »%s« nicht umbenennen: %m" +msgid "removing write-ahead log file \"%s\"" +msgstr "entferne Write-Ahead-Log-Datei »%s«" -#: access/transam/xlog.c:4019 +#: access/transam/xlog.c:4083 #, c-format -msgid "could not remove old transaction log file \"%s\": %m" -msgstr "konnte alte Transaktionslogdatei »%s« nicht löschen: %m" +msgid "could not rename old write-ahead log file \"%s\": %m" +msgstr "konnte alte Write-Ahead-Log-Datei »%s« nicht umbenennen: %m" -#: access/transam/xlog.c:4052 access/transam/xlog.c:4062 +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "benötigtes WAL-Verzeichnis »%s« existiert nicht" -#: access/transam/xlog.c:4068 +#: access/transam/xlog.c:4141 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "erzeuge fehlendes WAL-Verzeichnis »%s«" -#: access/transam/xlog.c:4071 +#: access/transam/xlog.c:4144 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "konnte fehlendes Verzeichnis »%s« nicht erzeugen: %m" -#: access/transam/xlog.c:4102 -#, c-format -msgid "removing transaction log backup history file \"%s\"" -msgstr "entferne Transaktionslog-Backup-History-Datei »%s«" - -#: access/transam/xlog.c:4183 +#: access/transam/xlog.c:4252 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "unerwartete Zeitleisten-ID %u in Logsegment %s, Offset %u" -#: access/transam/xlog.c:4305 +#: access/transam/xlog.c:4380 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "neue Zeitleiste %u ist kein Kind der Datenbanksystemzeitleiste %u" -#: access/transam/xlog.c:4319 +#: access/transam/xlog.c:4394 #, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgstr "neue Zeitleiste %u zweigte von der aktuellen Datenbanksystemzeitleiste %u vor dem aktuellen Wiederherstellungspunkt %X/%X ab" -#: access/transam/xlog.c:4338 +#: access/transam/xlog.c:4413 #, c-format msgid "new target timeline is %u" msgstr "neue Zielzeitleiste ist %u" -#: access/transam/xlog.c:4413 +#: access/transam/xlog.c:4493 #, c-format msgid "could not create control file \"%s\": %m" msgstr "konnte Kontrolldatei »%s« nicht erzeugen: %m" -#: access/transam/xlog.c:4424 access/transam/xlog.c:4644 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 #, c-format msgid "could not write to control file: %m" msgstr "konnte nicht in Kontrolldatei schreiben: %m" -#: access/transam/xlog.c:4430 access/transam/xlog.c:4650 +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 #, c-format msgid "could not fsync control file: %m" msgstr "konnte Kontrolldatei nicht fsyncen: %m" -#: access/transam/xlog.c:4435 access/transam/xlog.c:4655 +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 #, c-format msgid "could not close control file: %m" msgstr "konnte Kontrolldatei nicht schließen: %m" -#: access/transam/xlog.c:4453 access/transam/xlog.c:4633 +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 #, c-format msgid "could not open control file \"%s\": %m" msgstr "konnte Kontrolldatei »%s« nicht öffnen: %m" -#: access/transam/xlog.c:4459 +#: access/transam/xlog.c:4548 #, c-format msgid "could not read from control file: %m" msgstr "konnte nicht aus Kontrolldatei lesen: %m" -#: access/transam/xlog.c:4472 access/transam/xlog.c:4481 -#: access/transam/xlog.c:4505 access/transam/xlog.c:4512 -#: access/transam/xlog.c:4519 access/transam/xlog.c:4524 -#: access/transam/xlog.c:4531 access/transam/xlog.c:4538 -#: access/transam/xlog.c:4545 access/transam/xlog.c:4552 -#: access/transam/xlog.c:4559 access/transam/xlog.c:4566 -#: access/transam/xlog.c:4573 access/transam/xlog.c:4582 -#: access/transam/xlog.c:4589 access/transam/xlog.c:4598 -#: access/transam/xlog.c:4605 utils/init/miscinit.c:1380 +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "konnte nicht aus Kontrolldatei lesen: %d Bytes gelesen, %d erwartet" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 +#: access/transam/xlog.c:4599 access/transam/xlog.c:4606 +#: access/transam/xlog.c:4613 access/transam/xlog.c:4618 +#: access/transam/xlog.c:4625 access/transam/xlog.c:4632 +#: access/transam/xlog.c:4639 access/transam/xlog.c:4646 +#: access/transam/xlog.c:4653 access/transam/xlog.c:4660 +#: access/transam/xlog.c:4669 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4685 access/transam/xlog.c:4692 +#: utils/init/miscinit.c:1506 #, c-format msgid "database files are incompatible with server" msgstr "Datenbankdateien sind inkompatibel mit Server" -#: access/transam/xlog.c:4473 +#: access/transam/xlog.c:4567 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d (0x%08x) initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d (0x%08x) kompiliert." -#: access/transam/xlog.c:4477 +#: access/transam/xlog.c:4571 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "Das Problem könnte eine falsche Byte-Reihenfolge sein. Es sieht so aus, dass Sie initdb ausführen müssen." -#: access/transam/xlog.c:4482 +#: access/transam/xlog.c:4576 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "Der Datenbank-Cluster wurde mit PG_CONTROL_VERSION %d initialisiert, aber der Server wurde mit PG_CONTROL_VERSION %d kompiliert." -#: access/transam/xlog.c:4485 access/transam/xlog.c:4509 -#: access/transam/xlog.c:4516 access/transam/xlog.c:4521 +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 +#: access/transam/xlog.c:4610 access/transam/xlog.c:4615 #, c-format msgid "It looks like you need to initdb." msgstr "Es sieht so aus, dass Sie initdb ausführen müssen." -#: access/transam/xlog.c:4496 +#: access/transam/xlog.c:4590 #, c-format msgid "incorrect checksum in control file" msgstr "falsche Prüfsumme in Kontrolldatei" -#: access/transam/xlog.c:4506 +#: access/transam/xlog.c:4600 #, c-format msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." msgstr "Der Datenbank-Cluster wurde mit CATALOG_VERSION_NO %d initialisiert, aber der Server wurde mit CATALOG_VERSION_NO %d kompiliert." -#: access/transam/xlog.c:4513 +#: access/transam/xlog.c:4607 #, c-format msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." msgstr "Der Datenbank-Cluster wurde mit MAXALIGN %d initialisiert, aber der Server wurde mit MAXALIGN %d kompiliert." -#: access/transam/xlog.c:4520 +#: access/transam/xlog.c:4614 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "Der Datenbank-Cluster verwendet anscheinend ein anderes Fließkommazahlenformat als das Serverprogramm." -#: access/transam/xlog.c:4525 +#: access/transam/xlog.c:4619 #, c-format msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "Der Datenbank-Cluster wurde mit BLCKSZ %d initialisiert, aber der Server wurde mit BLCKSZ %d kompiliert." -#: access/transam/xlog.c:4528 access/transam/xlog.c:4535 -#: access/transam/xlog.c:4542 access/transam/xlog.c:4549 -#: access/transam/xlog.c:4556 access/transam/xlog.c:4563 -#: access/transam/xlog.c:4570 access/transam/xlog.c:4577 -#: access/transam/xlog.c:4585 access/transam/xlog.c:4592 -#: access/transam/xlog.c:4601 access/transam/xlog.c:4608 +#: access/transam/xlog.c:4622 access/transam/xlog.c:4629 +#: access/transam/xlog.c:4636 access/transam/xlog.c:4643 +#: access/transam/xlog.c:4650 access/transam/xlog.c:4657 +#: access/transam/xlog.c:4664 access/transam/xlog.c:4672 +#: access/transam/xlog.c:4679 access/transam/xlog.c:4688 +#: access/transam/xlog.c:4695 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "Es sieht so aus, dass Sie neu kompilieren oder initdb ausführen müssen." -#: access/transam/xlog.c:4532 +#: access/transam/xlog.c:4626 #, c-format msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." msgstr "Der Datenbank-Cluster wurde mit RELSEG_SIZE %d initialisiert, aber der Server wurde mit RELSEGSIZE %d kompiliert." -#: access/transam/xlog.c:4539 +#: access/transam/xlog.c:4633 #, c-format msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." msgstr "Der Datenbank-Cluster wurde mit XLOG_BLCKSZ %d initialisiert, aber der Server wurde mit XLOG_BLCKSZ %d kompiliert." -#: access/transam/xlog.c:4546 -#, c-format -msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." -msgstr "Der Datenbank-Cluster wurde mit XLOG_SEG_SIZE %d initialisiert, aber der Server wurde mit XLOG_SEG_SIZE %d kompiliert." - -#: access/transam/xlog.c:4553 +#: access/transam/xlog.c:4640 #, c-format msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." msgstr "Der Datenbank-Cluster wurde mit NAMEDATALEN %d initialisiert, aber der Server wurde mit NAMEDATALEN %d kompiliert." -#: access/transam/xlog.c:4560 +#: access/transam/xlog.c:4647 #, c-format msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." msgstr "Der Datenbank-Cluster wurde mit INDEX_MAX_KEYS %d initialisiert, aber der Server wurde mit INDEX_MAX_KEYS %d kompiliert." -#: access/transam/xlog.c:4567 +#: access/transam/xlog.c:4654 #, c-format msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." msgstr "Der Datenbank-Cluster wurde mit TOAST_MAX_CHUNK_SIZE %d initialisiert, aber der Server wurde mit TOAST_MAX_CHUNK_SIZE %d kompiliert." -#: access/transam/xlog.c:4574 +#: access/transam/xlog.c:4661 #, c-format msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." msgstr "Der Datenbank-Cluster wurde mit LOBLKSIZE %d initialisiert, aber der Server wurde mit LOBLKSIZE %d kompiliert." -#: access/transam/xlog.c:4583 +#: access/transam/xlog.c:4670 #, c-format msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." msgstr "Der Datenbank-Cluster wurde ohne USE_FLOAT4_BYVAL initialisiert, aber der Server wurde mit USE_FLOAT4_BYVAL kompiliert." -#: access/transam/xlog.c:4590 +#: access/transam/xlog.c:4677 #, c-format msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." msgstr "Der Datenbank-Cluster wurde mit USE_FLOAT4_BYVAL initialisiert, aber der Server wurde ohne USE_FLOAT4_BYVAL kompiliert." -#: access/transam/xlog.c:4599 +#: access/transam/xlog.c:4686 #, c-format msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." msgstr "Der Datenbank-Cluster wurde ohne USE_FLOAT8_BYVAL initialisiert, aber der Server wurde mit USE_FLOAT8_BYVAL kompiliert." -#: access/transam/xlog.c:4606 +#: access/transam/xlog.c:4693 #, c-format msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." msgstr "Der Datenbank-Cluster wurde mit USE_FLOAT8_BYVAL initialisiert, aber der Server wurde ohne USE_FLOAT8_BYVAL kompiliert." -#: access/transam/xlog.c:4958 -#, fuzzy, c-format -#| msgid "could not generate random encryption vector" -msgid "could not generation secret authorization token" -msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" +#: access/transam/xlog.c:4702 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Bytes an" -#: access/transam/xlog.c:5046 +#: access/transam/xlog.c:4714 #, c-format -msgid "could not write bootstrap transaction log file: %m" -msgstr "konnte Bootstrap-Transaktionslogdatei nicht schreiben: %m" +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "»min_wal_size« muss mindestens zweimal so groß wie »wal_segment_size« sein" -#: access/transam/xlog.c:5052 +#: access/transam/xlog.c:4718 #, c-format -msgid "could not fsync bootstrap transaction log file: %m" -msgstr "konnte Bootstrap-Transaktionslogdatei nicht fsyncen: %m" +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "»max_wal_size« muss mindestens zweimal so groß wie »wal_segment_size« sein" -#: access/transam/xlog.c:5057 +#: access/transam/xlog.c:5105 #, c-format -msgid "could not close bootstrap transaction log file: %m" -msgstr "konnte Bootstrap-Transaktionslogdatei nicht schließen: %m" +msgid "could not generate secret authorization token" +msgstr "konnte geheimes Autorisierungstoken nicht erzeugen" -#: access/transam/xlog.c:5133 +#: access/transam/xlog.c:5195 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht schreiben: %m" + +#: access/transam/xlog.c:5203 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht fsyncen: %m" + +#: access/transam/xlog.c:5209 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "konnte Bootstrap-Write-Ahead-Log-Datei nicht schließen: %m" + +#: access/transam/xlog.c:5291 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "konnte Recovery-Kommandodatei »%s« nicht öffnen: %m" -#: access/transam/xlog.c:5179 access/transam/xlog.c:5281 +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 #, c-format msgid "invalid value for recovery parameter \"%s\": \"%s\"" msgstr "ungültiger Wert für Recovery-Parameter »%s«: »%s«" -#: access/transam/xlog.c:5182 +#: access/transam/xlog.c:5340 #, c-format msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." msgstr "Gültige Werte sind »pause«, »promote« und »shutdown«." -#: access/transam/xlog.c:5202 +#: access/transam/xlog.c:5360 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" msgstr "recovery_target_timeline ist keine gültige Zahl: »%s«" -#: access/transam/xlog.c:5219 +#: access/transam/xlog.c:5377 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" msgstr "recovery_target_xid ist keine gültige Zahl: »%s«" -#: access/transam/xlog.c:5250 +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_time ist keine gültige Zeitangabe: »%s«" + +#: access/transam/xlog.c:5420 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "recovery_target_name ist zu lang (maximal %d Zeichen)" -#: access/transam/xlog.c:5284 +#: access/transam/xlog.c:5454 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "Der einzige erlaubte Wert ist »immediate«." -#: access/transam/xlog.c:5297 access/transam/xlog.c:5308 -#: commands/extension.c:546 commands/extension.c:554 utils/misc/guc.c:5706 +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 +#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5993 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "Parameter »%s« erfordert einen Boole’schen Wert" -#: access/transam/xlog.c:5343 +#: access/transam/xlog.c:5513 #, c-format msgid "parameter \"%s\" requires a temporal value" msgstr "Parameter »%s« erfordert einen Zeitwert" -#: access/transam/xlog.c:5345 catalog/dependency.c:959 -#: catalog/dependency.c:960 catalog/dependency.c:966 catalog/dependency.c:967 -#: catalog/dependency.c:978 catalog/dependency.c:979 commands/tablecmds.c:946 -#: commands/tablecmds.c:10018 commands/user.c:1052 commands/view.c:505 -#: libpq/auth.c:334 replication/syncrep.c:1118 storage/lmgr/deadlock.c:1139 -#: storage/lmgr/proc.c:1286 utils/adt/acl.c:5248 utils/misc/guc.c:5728 -#: utils/misc/guc.c:5821 utils/misc/guc.c:9773 utils/misc/guc.c:9807 -#: utils/misc/guc.c:9841 utils/misc/guc.c:9875 utils/misc/guc.c:9910 +#: access/transam/xlog.c:5515 catalog/dependency.c:969 catalog/dependency.c:970 +#: catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 +#: catalog/dependency.c:989 commands/tablecmds.c:1072 +#: commands/tablecmds.c:11297 commands/user.c:1064 commands/view.c:509 +#: libpq/auth.c:336 replication/syncrep.c:1162 storage/lmgr/deadlock.c:1139 +#: storage/lmgr/proc.c:1331 utils/adt/acl.c:5344 utils/misc/guc.c:6015 +#: utils/misc/guc.c:6108 utils/misc/guc.c:10098 utils/misc/guc.c:10132 +#: utils/misc/guc.c:10166 utils/misc/guc.c:10200 utils/misc/guc.c:10235 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlog.c:5352 +#: access/transam/xlog.c:5522 #, c-format msgid "unrecognized recovery parameter \"%s\"" msgstr "unbekannter Recovery-Parameter »%s«" -#: access/transam/xlog.c:5363 +#: access/transam/xlog.c:5533 #, c-format msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" msgstr "Recovery-Kommandodatei »%s« hat weder primary_conninfo noch restore_command angegeben" -#: access/transam/xlog.c:5365 +#: access/transam/xlog.c:5535 #, c-format msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." msgstr "Der Datenbankserver prüft das Unterverzeichnis pg_wal regelmäßig auf dort abgelegte Dateien." -#: access/transam/xlog.c:5372 +#: access/transam/xlog.c:5542 #, c-format msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" msgstr "Recovery-Kommandodatei »%s« muss restore_command angeben, wenn der Standby-Modus nicht eingeschaltet ist" -#: access/transam/xlog.c:5393 +#: access/transam/xlog.c:5563 #, c-format msgid "standby mode is not supported by single-user servers" msgstr "Standby-Modus wird von Servern im Einzelbenutzermodus nicht unterstützt" -#: access/transam/xlog.c:5412 +#: access/transam/xlog.c:5582 #, c-format msgid "recovery target timeline %u does not exist" msgstr "recovery_target_timeline %u existiert nicht" -#: access/transam/xlog.c:5533 +#: access/transam/xlog.c:5703 #, c-format msgid "archive recovery complete" msgstr "Wiederherstellung aus Archiv abgeschlossen" -#: access/transam/xlog.c:5592 access/transam/xlog.c:5858 +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 #, c-format msgid "recovery stopping after reaching consistency" msgstr "Wiederherstellung beendet nachdem Konsistenz erreicht wurde" -#: access/transam/xlog.c:5613 +#: access/transam/xlog.c:5783 #, c-format -msgid "recovery stopping before WAL position (LSN) \"%X/%X\"" +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" msgstr "Wiederherstellung beendet vor WAL-Position (LSN) »%X/%X«" -#: access/transam/xlog.c:5699 +#: access/transam/xlog.c:5869 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "Wiederherstellung beendet vor Commit der Transaktion %u, Zeit %s" -#: access/transam/xlog.c:5706 +#: access/transam/xlog.c:5876 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "Wiederherstellung beendet vor Abbruch der Transaktion %u, Zeit %s" -#: access/transam/xlog.c:5752 +#: access/transam/xlog.c:5922 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "Wiederherstellung beendet bei Restore-Punkt »%s«, Zeit %s" -#: access/transam/xlog.c:5770 +#: access/transam/xlog.c:5940 #, c-format -msgid "recovery stopping after WAL position (LSN) \"%X/%X\"" +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" msgstr "Wiederherstellung beendet nach WAL-Position (LSN) »%X/%X«" -#: access/transam/xlog.c:5838 +#: access/transam/xlog.c:6008 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "Wiederherstellung beendet nach Commit der Transaktion %u, Zeit %s" -#: access/transam/xlog.c:5846 +#: access/transam/xlog.c:6016 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "Wiederherstellung beendet nach Abbruch der Transaktion %u, Zeit %s" -#: access/transam/xlog.c:5886 +#: access/transam/xlog.c:6056 #, c-format msgid "recovery has paused" msgstr "Wiederherstellung wurde pausiert" -#: access/transam/xlog.c:5887 +#: access/transam/xlog.c:6057 #, c-format msgid "Execute pg_wal_replay_resume() to continue." msgstr "Führen Sie pg_wal_replay_resume() aus um fortzusetzen." -#: access/transam/xlog.c:6095 +#: access/transam/xlog.c:6265 #, c-format msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" msgstr "Hot Standby ist nicht möglich, weil %s = %d eine niedrigere Einstellung als auf dem Masterserver ist (Wert dort war %d)" -#: access/transam/xlog.c:6121 +#: access/transam/xlog.c:6291 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "WAL wurde mit wal_level=minimal erzeugt, eventuell fehlen Daten" -#: access/transam/xlog.c:6122 +#: access/transam/xlog.c:6292 #, c-format msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." msgstr "Das passiert, wenn vorübergehend wal_level=minimal gesetzt wurde, ohne ein neues Base-Backup zu erzeugen." -#: access/transam/xlog.c:6133 +#: access/transam/xlog.c:6303 #, c-format msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" msgstr "Hot Standby ist nicht möglich, weil wal_level auf dem Masterserver nicht auf »replica« oder höher gesetzt wurde" -#: access/transam/xlog.c:6134 +#: access/transam/xlog.c:6304 #, c-format msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." msgstr "Setzen Sie entweder wal_level auf »replica« auf dem Master oder schalten Sie hot_standby hier aus." -#: access/transam/xlog.c:6191 +#: access/transam/xlog.c:6356 #, c-format msgid "control file contains invalid data" msgstr "Kontrolldatei enthält ungültige Daten" -#: access/transam/xlog.c:6197 +#: access/transam/xlog.c:6362 #, c-format msgid "database system was shut down at %s" msgstr "Datenbanksystem wurde am %s heruntergefahren" -#: access/transam/xlog.c:6202 +#: access/transam/xlog.c:6367 #, c-format msgid "database system was shut down in recovery at %s" msgstr "Datenbanksystem wurde während der Wiederherstellung am %s heruntergefahren" -#: access/transam/xlog.c:6206 +#: access/transam/xlog.c:6371 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "Datenbanksystem wurde beim Herunterfahren unterbrochen; letzte bekannte Aktion am %s" -#: access/transam/xlog.c:6210 +#: access/transam/xlog.c:6375 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "Datenbanksystem wurde während der Wiederherstellung am %s unterbrochen" -#: access/transam/xlog.c:6212 +#: access/transam/xlog.c:6377 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "Das bedeutet wahrscheinlich, dass einige Daten verfälscht sind und Sie die letzte Datensicherung zur Wiederherstellung verwenden müssen." -#: access/transam/xlog.c:6216 +#: access/transam/xlog.c:6381 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "Datenbanksystem wurde während der Wiederherstellung bei Logzeit %s unterbrochen" -#: access/transam/xlog.c:6218 +#: access/transam/xlog.c:6383 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." msgstr "Wenn dies mehr als einmal vorgekommen ist, dann sind einige Daten möglicherweise verfälscht und Sie müssen ein früheres Wiederherstellungsziel wählen." -#: access/transam/xlog.c:6222 +#: access/transam/xlog.c:6387 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "Datenbanksystem wurde unterbrochen; letzte bekannte Aktion am %s" -#: access/transam/xlog.c:6278 +#: access/transam/xlog.c:6443 #, c-format msgid "entering standby mode" msgstr "Standby-Modus eingeschaltet" -#: access/transam/xlog.c:6281 +#: access/transam/xlog.c:6446 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "starte Point-in-Time-Recovery bis XID %u" -#: access/transam/xlog.c:6285 +#: access/transam/xlog.c:6450 #, c-format msgid "starting point-in-time recovery to %s" msgstr "starte Point-in-Time-Recovery bis %s" -#: access/transam/xlog.c:6289 +#: access/transam/xlog.c:6454 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "starte Point-in-Time-Recovery bis »%s«" -#: access/transam/xlog.c:6293 +#: access/transam/xlog.c:6458 #, c-format -msgid "starting point-in-time recovery to WAL position (LSN) \"%X/%X\"" +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" msgstr "starte Point-in-Time-Recovery bis WAL-Position (LSN) »%X/%X«" -#: access/transam/xlog.c:6298 +#: access/transam/xlog.c:6463 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "starte Point-in-Time-Recovery bis zum frühesten konsistenten Punkt" -#: access/transam/xlog.c:6301 +#: access/transam/xlog.c:6466 #, c-format msgid "starting archive recovery" msgstr "starte Wiederherstellung aus Archiv" -#: access/transam/xlog.c:6352 access/transam/xlog.c:6480 +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 #, c-format msgid "checkpoint record is at %X/%X" msgstr "Checkpoint-Eintrag ist bei %X/%X" -#: access/transam/xlog.c:6366 +#: access/transam/xlog.c:6534 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "konnte die vom Checkpoint-Datensatz referenzierte Redo-Position nicht finden" -#: access/transam/xlog.c:6367 access/transam/xlog.c:6374 +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 #, c-format msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." msgstr "Wenn Sie gerade keine Sicherung wiederherstellen, versuchen Sie, die Datei »%s/backup_label« zu löschen." -#: access/transam/xlog.c:6373 +#: access/transam/xlog.c:6541 #, c-format msgid "could not locate required checkpoint record" msgstr "konnte den nötigen Checkpoint-Datensatz nicht finden" -#: access/transam/xlog.c:6399 commands/tablespace.c:639 +#: access/transam/xlog.c:6567 commands/tablespace.c:641 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" -#: access/transam/xlog.c:6431 access/transam/xlog.c:6437 +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "ignoriere Datei »%s«, weil keine Datei »%s« existiert" -#: access/transam/xlog.c:6433 access/transam/xlog.c:11310 +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "Datei »%s« wurde in »%s« umbenannt." -#: access/transam/xlog.c:6439 +#: access/transam/xlog.c:6607 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "Konnte Datei »%s« nicht in »%s« umbenennen: %m." -#: access/transam/xlog.c:6490 access/transam/xlog.c:6505 +#: access/transam/xlog.c:6657 #, c-format msgid "could not locate a valid checkpoint record" msgstr "konnte keinen gültigen Checkpoint-Datensatz finden" -#: access/transam/xlog.c:6499 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "verwende vorherigen Checkpoint-Eintrag bei %X/%X" - -#: access/transam/xlog.c:6543 +#: access/transam/xlog.c:6695 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "angeforderte Zeitleiste %u ist kein Kind der History dieses Servers" -#: access/transam/xlog.c:6545 +#: access/transam/xlog.c:6697 #, c-format msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." msgstr "Neuester Checkpoint ist bei %X/%X auf Zeitleiste %u, aber in der History der angeforderten Zeitleiste zweigte der Server von dieser Zeitleiste bei %X/%X ab." -#: access/transam/xlog.c:6561 +#: access/transam/xlog.c:6713 #, c-format msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" msgstr "angeforderte Zeitleiste %u enthält nicht den minimalen Wiederherstellungspunkt %X/%X auf Zeitleiste %u" -#: access/transam/xlog.c:6592 +#: access/transam/xlog.c:6744 #, c-format msgid "invalid next transaction ID" msgstr "ungültige nächste Transaktions-ID" -#: access/transam/xlog.c:6675 +#: access/transam/xlog.c:6839 #, c-format msgid "invalid redo in checkpoint record" msgstr "ungültiges Redo im Checkpoint-Datensatz" -#: access/transam/xlog.c:6686 +#: access/transam/xlog.c:6850 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "ungültiger Redo-Datensatz im Shutdown-Checkpoint" -#: access/transam/xlog.c:6714 +#: access/transam/xlog.c:6878 #, c-format msgid "database system was not properly shut down; automatic recovery in progress" msgstr "Datenbanksystem wurde nicht richtig heruntergefahren; automatische Wiederherstellung läuft" -#: access/transam/xlog.c:6718 +#: access/transam/xlog.c:6882 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" msgstr "Wiederherstellung nach Absturz beginnt in Zeitleiste %u und hat Zielzeitleiste %u" -#: access/transam/xlog.c:6762 +#: access/transam/xlog.c:6925 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "Daten in backup_label stimmen nicht mit Kontrolldatei überein" -#: access/transam/xlog.c:6763 +#: access/transam/xlog.c:6926 #, c-format msgid "This means that the backup is corrupted and you will have to use another backup for recovery." msgstr "Das bedeutet, dass die Datensicherung verfälscht ist und Sie eine andere Datensicherung zur Wiederherstellung verwenden werden müssen." -#: access/transam/xlog.c:6837 +#: access/transam/xlog.c:7017 #, c-format msgid "initializing for hot standby" msgstr "initialisiere für Hot Standby" -#: access/transam/xlog.c:6969 +#: access/transam/xlog.c:7149 #, c-format msgid "redo starts at %X/%X" msgstr "Redo beginnt bei %X/%X" -#: access/transam/xlog.c:7203 +#: access/transam/xlog.c:7383 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "angeforderter Recovery-Endpunkt ist vor konsistentem Recovery-Punkt" -#: access/transam/xlog.c:7241 +#: access/transam/xlog.c:7421 #, c-format msgid "redo done at %X/%X" msgstr "Redo fertig bei %X/%X" -#: access/transam/xlog.c:7246 access/transam/xlog.c:9244 +#: access/transam/xlog.c:7426 #, c-format msgid "last completed transaction was at log time %s" msgstr "letzte vollständige Transaktion war bei Logzeit %s" -#: access/transam/xlog.c:7255 +#: access/transam/xlog.c:7435 #, c-format msgid "redo is not required" msgstr "Redo nicht nötig" -#: access/transam/xlog.c:7330 access/transam/xlog.c:7334 +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 #, c-format msgid "WAL ends before end of online backup" msgstr "WAL endet vor dem Ende der Online-Sicherung" -#: access/transam/xlog.c:7331 +#: access/transam/xlog.c:7511 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "Der komplette WAL, der während der Online-Sicherung erzeugt wurde, muss bei der Wiederherstellung verfügbar sein." -#: access/transam/xlog.c:7335 +#: access/transam/xlog.c:7515 #, c-format msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." msgstr "Die mit pg_start_backup() begonnene Online-Sicherung muss mit pg_stop_backup() beendet werden und der ganze WAL bis zu diesem Punkt muss bei der Wiederherstellung verfügbar sein." -#: access/transam/xlog.c:7338 +#: access/transam/xlog.c:7518 #, c-format msgid "WAL ends before consistent recovery point" msgstr "WAL endet vor einem konsistenten Wiederherstellungspunkt" -#: access/transam/xlog.c:7365 +#: access/transam/xlog.c:7552 #, c-format msgid "selected new timeline ID: %u" msgstr "gewählte neue Zeitleisten-ID: %u" -#: access/transam/xlog.c:7794 +#: access/transam/xlog.c:7989 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "konsistenter Wiederherstellungszustand erreicht bei %X/%X" -#: access/transam/xlog.c:7986 +#: access/transam/xlog.c:8181 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "ungültige primäre Checkpoint-Verknüpfung in Kontrolldatei" -#: access/transam/xlog.c:7990 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "ungültige sekundäre Checkpoint-Verknüpfung in Kontrolldatei" - -#: access/transam/xlog.c:7994 +#: access/transam/xlog.c:8185 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "ungültige Checkpoint-Verknüpfung in backup_label-Datei" -#: access/transam/xlog.c:8011 +#: access/transam/xlog.c:8202 #, c-format msgid "invalid primary checkpoint record" msgstr "ungültiger primärer Checkpoint-Datensatz" -#: access/transam/xlog.c:8015 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "ungültiger sekundärer Checkpoint-Datensatz" - -#: access/transam/xlog.c:8019 +#: access/transam/xlog.c:8206 #, c-format msgid "invalid checkpoint record" msgstr "ungültiger Checkpoint-Datensatz" -#: access/transam/xlog.c:8030 +#: access/transam/xlog.c:8217 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "ungültige Resource-Manager-ID im primären Checkpoint-Datensatz" -#: access/transam/xlog.c:8034 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "ungültige Resource-Manager-ID im sekundären Checkpoint-Datensatz" - -#: access/transam/xlog.c:8038 +#: access/transam/xlog.c:8221 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "ungültige Resource-Manager-ID im Checkpoint-Datensatz" -#: access/transam/xlog.c:8051 +#: access/transam/xlog.c:8234 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "ungültige xl_info im primären Checkpoint-Datensatz" -#: access/transam/xlog.c:8055 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "ungültige xl_info im sekundären Checkpoint-Datensatz" - -#: access/transam/xlog.c:8059 +#: access/transam/xlog.c:8238 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "ungültige xl_info im Checkpoint-Datensatz" -#: access/transam/xlog.c:8070 +#: access/transam/xlog.c:8249 #, c-format msgid "invalid length of primary checkpoint record" msgstr "ungültige Länge des primären Checkpoint-Datensatzes" -#: access/transam/xlog.c:8074 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "ungültige Länge des sekundären Checkpoint-Datensatzes" - -#: access/transam/xlog.c:8078 +#: access/transam/xlog.c:8253 #, c-format msgid "invalid length of checkpoint record" msgstr "ungültige Länge des Checkpoint-Datensatzes" -#: access/transam/xlog.c:8281 +#: access/transam/xlog.c:8459 #, c-format msgid "shutting down" msgstr "fahre herunter" -#: access/transam/xlog.c:8589 -#, fuzzy, c-format -#| msgid "checkpoint request failed" -msgid "checkpoint skipped due to an idle system" -msgstr "Checkpoint-Anforderung fehlgeschlagen" +#: access/transam/xlog.c:8779 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "Checkpoint übersprungen weil das System inaktiv ist" -#: access/transam/xlog.c:8789 +#: access/transam/xlog.c:8984 #, c-format -msgid "concurrent transaction log activity while database system is shutting down" -msgstr "gleichzeitige Transaktionslog-Aktivität während das Datenbanksystem herunterfährt" +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "gleichzeitige Write-Ahead-Log-Aktivität während das Datenbanksystem herunterfährt" -#: access/transam/xlog.c:9043 +#: access/transam/xlog.c:9241 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "Restart-Punkt übersprungen, Wiederherstellung ist bereits beendet" -#: access/transam/xlog.c:9066 +#: access/transam/xlog.c:9264 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "Restart-Punkt wird übersprungen, schon bei %X/%X erledigt" -#: access/transam/xlog.c:9242 +#: access/transam/xlog.c:9431 #, c-format msgid "recovery restart point at %X/%X" msgstr "Recovery-Restart-Punkt bei %X/%X" -#: access/transam/xlog.c:9378 +#: access/transam/xlog.c:9433 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Die letzte vollständige Transaktion war bei Logzeit %s." + +#: access/transam/xlog.c:9567 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "Restore-Punkt »%s« erzeugt bei %X/%X" -#: access/transam/xlog.c:9508 +#: access/transam/xlog.c:9705 #, c-format msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "unerwartete vorherige Zeitleisten-ID %u (aktuelle Zeitleisten-ID %u) im Checkpoint-Datensatz" -#: access/transam/xlog.c:9517 +#: access/transam/xlog.c:9714 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (nach %u) im Checkpoint-Datensatz" -#: access/transam/xlog.c:9533 +#: access/transam/xlog.c:9730 #, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgstr "unerwartete Zeitleisten-ID %u in Checkpoint-Datensatz, bevor der minimale Wiederherstellungspunkt %X/%X auf Zeitleiste %u erreicht wurde" -#: access/transam/xlog.c:9604 +#: access/transam/xlog.c:9806 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "Online-Sicherung wurde storniert, Wiederherstellung kann nicht fortgesetzt werden" -#: access/transam/xlog.c:9660 access/transam/xlog.c:9707 -#: access/transam/xlog.c:9730 +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 +#: access/transam/xlog.c:9941 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "unerwartete Zeitleisten-ID %u (sollte %u sein) im Checkpoint-Datensatz" -#: access/transam/xlog.c:10005 +#: access/transam/xlog.c:10222 #, c-format msgid "could not fsync log segment %s: %m" msgstr "konnte Logsegment %s nicht fsyncen: %m" -#: access/transam/xlog.c:10029 +#: access/transam/xlog.c:10247 #, c-format msgid "could not fsync log file %s: %m" msgstr "konnte Logdatei %s nicht fsyncen: %m" -#: access/transam/xlog.c:10037 +#: access/transam/xlog.c:10255 #, c-format msgid "could not fsync write-through log file %s: %m" msgstr "konnte Write-Through-Logdatei %s nicht fsyncen: %m" -#: access/transam/xlog.c:10046 +#: access/transam/xlog.c:10264 #, c-format msgid "could not fdatasync log file %s: %m" msgstr "konnte Logdatei %s nicht fdatasyncen: %m" -#: access/transam/xlog.c:10137 access/transam/xlog.c:10641 -#: access/transam/xlogfuncs.c:293 access/transam/xlogfuncs.c:320 -#: access/transam/xlogfuncs.c:359 access/transam/xlogfuncs.c:380 -#: access/transam/xlogfuncs.c:401 +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 +#: access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 +#: access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 +#: access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "Während der Wiederherstellung können keine WAL-Kontrollfunktionen ausgeführt werden." -#: access/transam/xlog.c:10146 access/transam/xlog.c:10650 +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "WAL-Level nicht ausreichend, um Online-Sicherung durchzuführen" -#: access/transam/xlog.c:10147 access/transam/xlog.c:10651 -#: access/transam/xlogfuncs.c:326 +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 +#: access/transam/xlogfuncs.c:320 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "wal_level muss beim Serverstart auf »replica« oder »logical« gesetzt werden." -#: access/transam/xlog.c:10152 +#: access/transam/xlog.c:10370 #, c-format msgid "backup label too long (max %d bytes)" msgstr "Backup-Label zu lang (maximal %d Bytes)" -#: access/transam/xlog.c:10189 access/transam/xlog.c:10461 -#: access/transam/xlog.c:10499 +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 +#: access/transam/xlog.c:10721 #, c-format msgid "a backup is already in progress" msgstr "ein Backup läuft bereits" -#: access/transam/xlog.c:10190 +#: access/transam/xlog.c:10408 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "Führen Sie pg_stop_backup() aus und versuchen Sie es nochmal." -#: access/transam/xlog.c:10285 +#: access/transam/xlog.c:10504 #, c-format msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" msgstr "mit full_page_writes=off erzeugtes WAL wurde seit dem letzten Restart-Punkt zurückgespielt" -#: access/transam/xlog.c:10287 access/transam/xlog.c:10832 +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." msgstr "Das bedeutet, dass die aktuelle Datensicherung auf dem Standby-Server verfälscht ist und nicht verwendet werden sollte. Schalten Sie full_page_writes ein, führen Sie CHECKPOINT aus und versuchen Sie dann die Online-Sicherung erneut." -#: access/transam/xlog.c:10354 replication/basebackup.c:1096 -#: utils/adt/misc.c:497 +#: access/transam/xlog.c:10574 replication/basebackup.c:1232 +#: utils/adt/misc.c:517 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: access/transam/xlog.c:10361 replication/basebackup.c:1101 -#: utils/adt/misc.c:502 +#: access/transam/xlog.c:10581 replication/basebackup.c:1237 +#: utils/adt/misc.c:522 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" -#: access/transam/xlog.c:10414 commands/tablespace.c:389 -#: commands/tablespace.c:551 replication/basebackup.c:1116 -#: utils/adt/misc.c:510 +#: access/transam/xlog.c:10633 commands/tablespace.c:391 +#: commands/tablespace.c:553 replication/basebackup.c:1252 utils/adt/misc.c:530 #, c-format msgid "tablespaces are not supported on this platform" msgstr "Tablespaces werden auf dieser Plattform nicht unterstützt" -#: access/transam/xlog.c:10455 access/transam/xlog.c:10493 -#: access/transam/xlog.c:10689 access/transam/xlogarchive.c:105 -#: access/transam/xlogarchive.c:264 commands/copy.c:1864 commands/copy.c:3038 -#: commands/extension.c:3312 commands/tablespace.c:780 -#: commands/tablespace.c:871 guc-file.l:1001 replication/basebackup.c:480 -#: replication/basebackup.c:548 replication/logical/snapbuild.c:1490 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2903 -#: storage/file/fd.c:2995 utils/adt/dbsize.c:69 utils/adt/dbsize.c:219 -#: utils/adt/dbsize.c:299 utils/adt/genfile.c:114 utils/adt/genfile.c:333 +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 +#: access/transam/xlog.c:10930 access/transam/xlogarchive.c:104 +#: access/transam/xlogarchive.c:264 commands/copy.c:1890 commands/copy.c:3206 +#: commands/extension.c:3326 commands/tablespace.c:782 +#: commands/tablespace.c:873 guc-file.l:1004 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1525 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1733 +#: storage/file/fd.c:3113 storage/file/fd.c:3295 storage/file/fd.c:3380 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:131 utils/adt/genfile.c:382 #, c-format msgid "could not stat file \"%s\": %m" msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" -#: access/transam/xlog.c:10462 access/transam/xlog.c:10500 +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 #, c-format msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." msgstr "Wenn Sie sicher sind, dass noch kein Backup läuft, entfernen Sie die Datei »%s« und versuchen Sie es noch einmal." -#: access/transam/xlog.c:10479 access/transam/xlog.c:10517 -#: access/transam/xlog.c:10893 postmaster/syslogger.c:1391 -#: postmaster/syslogger.c:1404 +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 +#: access/transam/xlog.c:11150 postmaster/syslogger.c:1476 +#: postmaster/syslogger.c:1489 #, c-format msgid "could not write file \"%s\": %m" msgstr "konnte Datei »%s« nicht schreiben: %m" -#: access/transam/xlog.c:10666 +#: access/transam/xlog.c:10907 #, c-format msgid "exclusive backup not in progress" msgstr "es läuft kein exklusives Backup" -#: access/transam/xlog.c:10693 +#: access/transam/xlog.c:10934 #, c-format msgid "a backup is not in progress" msgstr "es läuft kein Backup" -#: access/transam/xlog.c:10767 access/transam/xlog.c:10780 -#: access/transam/xlog.c:11120 access/transam/xlog.c:11126 -#: access/transam/xlog.c:11210 access/transam/xlogfuncs.c:694 +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 +#: access/transam/xlog.c:11394 access/transam/xlog.c:11400 +#: access/transam/xlog.c:11448 access/transam/xlog.c:11521 +#: access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" msgstr "ungültige Daten in Datei »%s«" -#: access/transam/xlog.c:10784 replication/basebackup.c:994 +#: access/transam/xlog.c:11037 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "der Standby-Server wurde während der Online-Sicherung zum Primärserver befördert" -#: access/transam/xlog.c:10785 replication/basebackup.c:995 +#: access/transam/xlog.c:11038 replication/basebackup.c:1090 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "Das bedeutet, dass die aktuelle Online-Sicherung verfälscht ist und nicht verwendet werden sollte. Versuchen Sie, eine neue Online-Sicherung durchzuführen." -#: access/transam/xlog.c:10830 +#: access/transam/xlog.c:11085 #, c-format msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "mit full_page_writes=off erzeugtes WAL wurde während der Online-Sicherung zurückgespielt" -#: access/transam/xlog.c:10942 +#: access/transam/xlog.c:11205 #, c-format msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" msgstr "Aufräumen nach pg_stop_backup beendet, warte bis die benötigten WAL-Segmente archiviert sind" -#: access/transam/xlog.c:10952 +#: access/transam/xlog.c:11215 #, c-format msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "pg_stop_backup wartet immer noch, bis alle benötigten WAL-Segmente archiviert sind (%d Sekunden abgelaufen)" -#: access/transam/xlog.c:10954 +#: access/transam/xlog.c:11217 #, c-format msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." msgstr "Prüfen Sie, ob das archive_command korrekt ausgeführt wird. pg_stop_backup kann gefahrlos abgebrochen werden, aber die Datenbanksicherung wird ohne die fehlenden WAL-Segmente nicht benutzbar sein." -#: access/transam/xlog.c:10961 +#: access/transam/xlog.c:11224 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" msgstr "pg_stop_backup abgeschlossen, alle benötigten WAL-Segmente wurden archiviert" -#: access/transam/xlog.c:10965 +#: access/transam/xlog.c:11228 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "WAL-Archivierung ist nicht eingeschaltet; Sie müssen dafür sorgen, dass alle benötigten WAL-Segmente auf andere Art kopiert werden, um die Sicherung abzuschließen" +#: access/transam/xlog.c:11431 +#, fuzzy, c-format +#| msgid "could not seek in file \"%s\": %m" +msgid "backup time %s in file \"%s\"" +msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" + +#: access/transam/xlog.c:11436 +#, fuzzy, c-format +#| msgid "could not read block %u in file \"%s\": %m" +msgid "backup label %s in file \"%s\"" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %m" + +#: access/transam/xlog.c:11449 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "" + +#: access/transam/xlog.c:11453 +#, fuzzy, c-format +#| msgid "could not write block %u in file \"%s\": %m" +msgid "backup timeline %u in file \"%s\"" +msgstr "konnte Block %u in Datei »%s« nicht schreiben: %m" + #. translator: %s is a WAL record description -#: access/transam/xlog.c:11250 +#: access/transam/xlog.c:11561 #, c-format msgid "WAL redo at %X/%X for %s" msgstr "WAL-Redo bei %X/%X für %s" -#: access/transam/xlog.c:11299 +#: access/transam/xlog.c:11610 #, c-format msgid "online backup mode was not canceled" msgstr "Online-Sicherungsmodus wurde nicht storniert" -#: access/transam/xlog.c:11300 +#: access/transam/xlog.c:11611 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "Konnte Datei »%s« nicht in »%s« umbenennen: %m." -#: access/transam/xlog.c:11309 access/transam/xlog.c:11321 -#: access/transam/xlog.c:11331 +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 +#: access/transam/xlog.c:11642 #, c-format msgid "online backup mode canceled" msgstr "Online-Sicherungsmodus storniert" -#: access/transam/xlog.c:11322 +#: access/transam/xlog.c:11633 #, c-format msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "Dateien »%s« und »%s« wurden in »%s« und »%s« umbenannt." -#: access/transam/xlog.c:11332 +#: access/transam/xlog.c:11643 #, c-format msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." msgstr "Datei »%s« wurde in »%s« umbenannt, aber Datei »%s« konnte nicht in »%s« umbenannt werden: %m." -#: access/transam/xlog.c:11454 access/transam/xlogutils.c:719 -#: replication/walreceiver.c:1005 replication/walsender.c:2067 +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 +#: replication/walreceiver.c:1019 replication/walsender.c:2424 #, c-format msgid "could not seek in log segment %s to offset %u: %m" msgstr "konnte Positionszeiger von Logsegment %s nicht auf %u setzen: %m" -#: access/transam/xlog.c:11466 +#: access/transam/xlog.c:11785 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "konnte nicht aus Logsegment %s, Position %u lesen: %m" -#: access/transam/xlog.c:11940 +#: access/transam/xlog.c:12314 #, c-format msgid "received promote request" msgstr "Anforderung zum Befördern empfangen" -#: access/transam/xlog.c:11953 +#: access/transam/xlog.c:12327 #, c-format msgid "trigger file found: %s" msgstr "Triggerdatei gefunden: %s" -#: access/transam/xlog.c:11962 +#: access/transam/xlog.c:12336 #, c-format msgid "could not stat trigger file \"%s\": %m" msgstr "konnte »stat« für Trigger-Datei »%s« nicht ausführen: %m" @@ -2742,7 +2658,7 @@ msgstr "Archivdatei »%s« hat falsche Größe: %lu statt %lu" msgid "restored log file \"%s\" from archive" msgstr "Logdatei »%s« aus Archiv wiederhergestellt" -#: access/transam/xlogarchive.c:302 +#: access/transam/xlogarchive.c:297 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "konnte Datei »%s« nicht aus Archiv wiederherstellen: %s" @@ -2750,866 +2666,981 @@ msgstr "konnte Datei »%s« nicht aus Archiv wiederherstellen: %s" #. translator: First %s represents a recovery.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:414 +#: access/transam/xlogarchive.c:406 #, c-format msgid "%s \"%s\": %s" msgstr "%s »%s«: %s" -#: access/transam/xlogarchive.c:457 postmaster/syslogger.c:1415 -#: replication/logical/snapbuild.c:1618 replication/slot.c:517 -#: replication/slot.c:1029 replication/slot.c:1137 storage/file/fd.c:642 -#: storage/file/fd.c:700 utils/time/snapmgr.c:1298 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1500 +#: replication/logical/snapbuild.c:1663 replication/slot.c:598 +#: replication/slot.c:1211 replication/slot.c:1326 storage/file/fd.c:650 +#: storage/file/fd.c:745 utils/time/snapmgr.c:1318 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:596 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "konnte Archivstatusdatei »%s« nicht schreiben: %m" -#: access/transam/xlogfuncs.c:57 +#: access/transam/xlogfuncs.c:54 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "Backup wird abgebrochen, weil Backend-Prozess beendete, bevor pg_stop_backup aufgerufen wurde" -#: access/transam/xlogfuncs.c:87 +#: access/transam/xlogfuncs.c:84 #, c-format msgid "a backup is already in progress in this session" msgstr "ein Backup läuft bereits in dieser Sitzung" -#: access/transam/xlogfuncs.c:93 commands/tablespace.c:703 -#: commands/tablespace.c:713 postmaster/postmaster.c:1434 -#: replication/basebackup.c:368 replication/basebackup.c:708 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2369 -#: storage/file/fd.c:2968 storage/ipc/dsm.c:301 utils/adt/genfile.c:439 -#: utils/adt/misc.c:410 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" - -#: access/transam/xlogfuncs.c:154 access/transam/xlogfuncs.c:228 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format msgid "non-exclusive backup in progress" msgstr "es läuft ein nicht-exklusives Backup" -#: access/transam/xlogfuncs.c:155 access/transam/xlogfuncs.c:229 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "Meinten Sie pg_stop_backup('f')?" -#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1450 -#: commands/event_trigger.c:2001 commands/extension.c:1889 -#: commands/extension.c:1998 commands/extension.c:2222 commands/prepare.c:718 -#: executor/execQual.c:1312 executor/functions.c:1024 foreign/foreign.c:488 -#: libpq/hba.c:2414 replication/logical/launcher.c:680 -#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1384 -#: replication/slotfuncs.c:196 replication/walsender.c:2716 -#: utils/adt/jsonfuncs.c:1484 utils/adt/jsonfuncs.c:1614 -#: utils/adt/jsonfuncs.c:1802 utils/adt/jsonfuncs.c:1929 -#: utils/adt/jsonfuncs.c:2695 utils/adt/pgstatfuncs.c:454 -#: utils/adt/pgstatfuncs.c:555 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8501 -#: utils/mmgr/portalmem.c:1053 +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 +#: commands/event_trigger.c:2016 commands/extension.c:1902 +#: commands/extension.c:2011 commands/extension.c:2235 commands/prepare.c:722 +#: executor/execExpr.c:2209 executor/execSRF.c:715 executor/functions.c:1034 +#: foreign/foreign.c:488 libpq/hba.c:2603 replication/logical/launcher.c:1127 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 +#: replication/slotfuncs.c:200 replication/walsender.c:3203 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 +#: utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8829 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "Funktion mit Mengenergebnis in einem Zusammenhang aufgerufen, der keine Mengenergebnisse verarbeiten kann" -#: access/transam/xlogfuncs.c:203 commands/event_trigger.c:1454 -#: commands/event_trigger.c:2005 commands/extension.c:1893 -#: commands/extension.c:2002 commands/extension.c:2226 commands/prepare.c:722 -#: foreign/foreign.c:493 libpq/hba.c:2418 replication/logical/launcher.c:684 -#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1388 -#: replication/slotfuncs.c:200 replication/walsender.c:2720 -#: utils/adt/pgstatfuncs.c:458 utils/adt/pgstatfuncs.c:559 -#: utils/misc/guc.c:8505 utils/misc/pg_config.c:44 utils/mmgr/portalmem.c:1057 +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 +#: commands/event_trigger.c:2020 commands/extension.c:1906 +#: commands/extension.c:2015 commands/extension.c:2239 commands/prepare.c:726 +#: foreign/foreign.c:493 libpq/hba.c:2607 replication/logical/launcher.c:1131 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 +#: replication/slotfuncs.c:204 replication/walsender.c:3207 +#: utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 +#: utils/misc/guc.c:8833 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "Materialisierungsmodus wird benötigt, ist aber in diesem Zusammenhang nicht erlaubt" -#: access/transam/xlogfuncs.c:246 +#: access/transam/xlogfuncs.c:241 #, c-format msgid "non-exclusive backup is not in progress" msgstr "es läuft kein nicht-exklusives Backup" -#: access/transam/xlogfuncs.c:247 +#: access/transam/xlogfuncs.c:242 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "Meinten Sie pg_stop_backup('t')?" -#: access/transam/xlogfuncs.c:325 +#: access/transam/xlogfuncs.c:319 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "WAL-Level nicht ausreichend, um Restore-Punkt anzulegen" -#: access/transam/xlogfuncs.c:333 +#: access/transam/xlogfuncs.c:327 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "Wert zu lang für Restore-Punkt (maximal %d Zeichen)" -#: access/transam/xlogfuncs.c:471 +#: access/transam/xlogfuncs.c:465 #, c-format msgid "pg_walfile_name_offset() cannot be executed during recovery." msgstr "pg_walfile_name_offset() kann nicht während der Wiederherstellung ausgeführt werden." -#: access/transam/xlogfuncs.c:527 +#: access/transam/xlogfuncs.c:521 #, c-format msgid "pg_walfile_name() cannot be executed during recovery." msgstr "pg_walfile_name() kann nicht während der Wiederherstellung ausgeführt werden." -#: access/transam/xlogfuncs.c:547 access/transam/xlogfuncs.c:567 -#: access/transam/xlogfuncs.c:584 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" msgstr "Wiederherstellung läuft nicht" -#: access/transam/xlogfuncs.c:548 access/transam/xlogfuncs.c:568 -#: access/transam/xlogfuncs.c:585 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "Wiederherstellungskontrollfunktionen können nur während der Wiederherstellung ausgeführt werden." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "ungültiger Datensatz-Offset bei %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "Contrecord angefordert von %X/%X" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:625 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "ungültige Datensatzlänge bei %X/%X: %u erwartet, %u erhalten" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:363 #, c-format msgid "record length %u at %X/%X too long" msgstr "Datensatzlänge %u bei %X/%X ist zu lang" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "keine Contrecord-Flag bei %X/%X" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "ungültige Contrecord-Länge %u bei %X/%X" -#: access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:654 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ungültige Resource-Manager-ID %u bei %X/%X" -#: access/transam/xlogreader.c:647 access/transam/xlogreader.c:664 +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "Datensatz mit falschem Prev-Link %X/%X bei %X/%X" -#: access/transam/xlogreader.c:701 +#: access/transam/xlogreader.c:722 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "ungültige Resource-Manager-Datenprüfsumme in Datensatz bei %X/%X" -#: access/transam/xlogreader.c:734 +#: access/transam/xlogreader.c:759 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "ungültige magische Zahl %04X in Logsegment %s, Offset %u" -#: access/transam/xlogreader.c:748 access/transam/xlogreader.c:799 +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "ungültige Info-Bits %04X in Logsegment %s, Offset %u" -#: access/transam/xlogreader.c:774 +#: access/transam/xlogreader.c:799 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Datenbanksystemidentifikator in WAL-Datei ist %s, Datenbanksystemidentifikator in pg_control ist %s" -#: access/transam/xlogreader.c:781 +#: access/transam/xlogreader.c:806 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Falsche XLOG_SEG_SIZE im Seitenkopf" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche Segmentgröße im Seitenkopf" -#: access/transam/xlogreader.c:787 +#: access/transam/xlogreader.c:812 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" -msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Falsche XLOG_BLCKSZ im Seitenkopf" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche XLOG_BLCKSZ im Seitenkopf" -#: access/transam/xlogreader.c:813 +#: access/transam/xlogreader.c:843 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "unerwartete Pageaddr %X/%X in Logsegment %s, Offset %u" -#: access/transam/xlogreader.c:838 +#: access/transam/xlogreader.c:868 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in Logsegment %s, Offset %u" -#: access/transam/xlogreader.c:1083 +#: access/transam/xlogreader.c:1113 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u außer der Reihe bei %X/%X" -#: access/transam/xlogreader.c:1106 +#: access/transam/xlogreader.c:1136 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%X" -#: access/transam/xlogreader.c:1113 +#: access/transam/xlogreader.c:1143 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %u bei %X/%X" -#: access/transam/xlogreader.c:1149 +#: access/transam/xlogreader.c:1179 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %u Länge %u Block-Abbild-Länge %u bei %X/%X" -#: access/transam/xlogreader.c:1165 +#: access/transam/xlogreader.c:1195 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %u Länge %u bei %X/%X" -#: access/transam/xlogreader.c:1180 +#: access/transam/xlogreader.c:1210 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge %u bei %X/%X" -#: access/transam/xlogreader.c:1195 +#: access/transam/xlogreader.c:1225 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %u bei %X/%X" -#: access/transam/xlogreader.c:1211 +#: access/transam/xlogreader.c:1241 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%X" -#: access/transam/xlogreader.c:1223 +#: access/transam/xlogreader.c:1253 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "ungültige block_id %u bei %X/%X" -#: access/transam/xlogreader.c:1291 +#: access/transam/xlogreader.c:1342 #, c-format msgid "record with invalid length at %X/%X" msgstr "Datensatz mit ungültiger Länge bei %X/%X" -#: access/transam/xlogreader.c:1380 +#: access/transam/xlogreader.c:1431 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "ungültiges komprimiertes Abbild bei %X/%X, Block %d" -#: access/transam/xlogutils.c:740 replication/walsender.c:2084 +#: access/transam/xlogutils.c:751 replication/walsender.c:2443 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "konnte nicht aus Logsegment %s bei Position %u, Länge %lu lesen: %m" -#: bootstrap/bootstrap.c:271 postmaster/postmaster.c:801 tcop/postgres.c:3489 +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X benötigt eine Zweierpotenz zwischen 1 MB und 1 GB" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:826 tcop/postgres.c:3581 #, c-format msgid "--%s requires a value" msgstr "--%s benötigt einen Wert" -#: bootstrap/bootstrap.c:276 postmaster/postmaster.c:806 tcop/postgres.c:3494 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:831 tcop/postgres.c:3586 #, c-format msgid "-c %s requires a value" msgstr "-c %s benötigt einen Wert" -#: bootstrap/bootstrap.c:287 postmaster/postmaster.c:818 -#: postmaster/postmaster.c:831 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:843 +#: postmaster/postmaster.c:856 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: bootstrap/bootstrap.c:296 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: ungültige Kommandozeilenargumente\n" -#: catalog/aclchk.c:202 +#: catalog/aclchk.c:203 #, c-format msgid "grant options can only be granted to roles" msgstr "Grant-Optionen können nur Rollen gewährt werden" -#: catalog/aclchk.c:325 +#: catalog/aclchk.c:326 #, c-format msgid "no privileges were granted for column \"%s\" of relation \"%s\"" msgstr "es wurden keine Privilegien für Spalte »%s« von Relation »%s« gewährt" -#: catalog/aclchk.c:330 +#: catalog/aclchk.c:331 #, c-format msgid "no privileges were granted for \"%s\"" msgstr "es wurden keine Privilegien für »%s« gewährt" -#: catalog/aclchk.c:338 +#: catalog/aclchk.c:339 #, c-format msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" msgstr "es wurden nicht alle Priviligien für Spalte »%s« von Relation »%s« gewährt" -#: catalog/aclchk.c:343 +#: catalog/aclchk.c:344 #, c-format msgid "not all privileges were granted for \"%s\"" msgstr "es wurden nicht alle Priviligien für »%s« gewährt" -#: catalog/aclchk.c:354 +#: catalog/aclchk.c:355 #, c-format msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "es konnten keine Privilegien für Spalte »%s« von Relation »%s« entzogen werden" -#: catalog/aclchk.c:359 +#: catalog/aclchk.c:360 #, c-format msgid "no privileges could be revoked for \"%s\"" msgstr "es konnten keine Privilegien für »%s« entzogen werden" -#: catalog/aclchk.c:367 +#: catalog/aclchk.c:368 #, c-format msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "es konnten nicht alle Privilegien für Spalte »%s« von Relation »%s« entzogen werden" -#: catalog/aclchk.c:372 +#: catalog/aclchk.c:373 #, c-format msgid "not all privileges could be revoked for \"%s\"" msgstr "es konnten nicht alle Privilegien für »%s« entzogen werden" -#: catalog/aclchk.c:454 catalog/aclchk.c:947 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" msgstr "ungültiger Privilegtyp %s für Relation" -#: catalog/aclchk.c:458 catalog/aclchk.c:951 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" msgstr "ungültiger Privilegtyp %s für Sequenz" -#: catalog/aclchk.c:462 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "ungültiger Privilegtyp %s für Datenbank" -#: catalog/aclchk.c:466 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "ungültiger Privilegtyp %s für Domäne" -#: catalog/aclchk.c:470 catalog/aclchk.c:955 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" msgstr "ungültiger Privilegtyp %s für Funktion" -#: catalog/aclchk.c:474 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "ungültiger Privilegtyp %s für Sprache" -#: catalog/aclchk.c:478 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "ungültiger Privilegtyp %s für Large Object" -#: catalog/aclchk.c:482 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" msgstr "ungültiger Privilegtyp %s für Schema" -#: catalog/aclchk.c:486 +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "ungültiger Privilegtyp %s für Prozedur" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ungültiger Privilegtyp %s für Routine" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "ungültiger Privilegtyp %s für Tablespace" -#: catalog/aclchk.c:490 catalog/aclchk.c:959 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" msgstr "ungültiger Privilegtyp %s für Typ" -#: catalog/aclchk.c:494 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "ungültiger Privilegtyp %s für Fremddaten-Wrapper" -#: catalog/aclchk.c:498 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "ungültiger Privilegtyp %s für Fremdserver" -#: catalog/aclchk.c:537 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "Spaltenprivilegien sind nur für Relation gültig" -#: catalog/aclchk.c:695 catalog/aclchk.c:3900 catalog/aclchk.c:4682 -#: catalog/objectaddress.c:912 catalog/pg_largeobject.c:111 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 +#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 +#: storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" msgstr "Large Object %u existiert nicht" -#: catalog/aclchk.c:884 catalog/aclchk.c:893 commands/collationcmds.c:92 -#: commands/copy.c:1039 commands/copy.c:1059 commands/copy.c:1068 -#: commands/copy.c:1077 commands/copy.c:1086 commands/copy.c:1095 -#: commands/copy.c:1104 commands/copy.c:1113 commands/copy.c:1122 -#: commands/copy.c:1140 commands/copy.c:1156 commands/copy.c:1176 -#: commands/copy.c:1193 commands/dbcommands.c:155 commands/dbcommands.c:164 +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 +#: commands/copy.c:1063 commands/copy.c:1083 commands/copy.c:1092 +#: commands/copy.c:1101 commands/copy.c:1110 commands/copy.c:1119 +#: commands/copy.c:1128 commands/copy.c:1137 commands/copy.c:1146 +#: commands/copy.c:1164 commands/copy.c:1180 commands/copy.c:1200 +#: commands/copy.c:1217 commands/dbcommands.c:155 commands/dbcommands.c:164 #: commands/dbcommands.c:173 commands/dbcommands.c:182 #: commands/dbcommands.c:191 commands/dbcommands.c:200 #: commands/dbcommands.c:209 commands/dbcommands.c:218 -#: commands/dbcommands.c:227 commands/dbcommands.c:1419 -#: commands/dbcommands.c:1428 commands/dbcommands.c:1437 -#: commands/dbcommands.c:1446 commands/extension.c:1672 -#: commands/extension.c:1682 commands/extension.c:1692 -#: commands/extension.c:1702 commands/extension.c:2942 +#: commands/dbcommands.c:227 commands/dbcommands.c:1427 +#: commands/dbcommands.c:1436 commands/dbcommands.c:1445 +#: commands/dbcommands.c:1454 commands/extension.c:1685 +#: commands/extension.c:1695 commands/extension.c:1705 +#: commands/extension.c:1715 commands/extension.c:2956 #: commands/foreigncmds.c:537 commands/foreigncmds.c:546 -#: commands/functioncmds.c:526 commands/functioncmds.c:643 -#: commands/functioncmds.c:652 commands/functioncmds.c:661 -#: commands/functioncmds.c:670 commands/functioncmds.c:2076 -#: commands/functioncmds.c:2084 commands/publicationcmds.c:89 -#: commands/publicationcmds.c:99 commands/publicationcmds.c:109 -#: commands/publicationcmds.c:119 commands/publicationcmds.c:129 -#: commands/publicationcmds.c:139 commands/sequence.c:1247 -#: commands/sequence.c:1256 commands/sequence.c:1265 commands/sequence.c:1274 -#: commands/sequence.c:1283 commands/sequence.c:1292 commands/sequence.c:1301 -#: commands/sequence.c:1310 commands/sequence.c:1319 -#: commands/subscriptioncmds.c:83 commands/subscriptioncmds.c:92 -#: commands/subscriptioncmds.c:101 commands/subscriptioncmds.c:111 -#: commands/subscriptioncmds.c:121 commands/subscriptioncmds.c:131 -#: commands/subscriptioncmds.c:141 commands/typecmds.c:298 -#: commands/typecmds.c:1375 commands/typecmds.c:1384 commands/typecmds.c:1392 -#: commands/typecmds.c:1400 commands/typecmds.c:1408 commands/user.c:138 -#: commands/user.c:161 commands/user.c:170 commands/user.c:179 -#: commands/user.c:188 commands/user.c:197 commands/user.c:206 -#: commands/user.c:215 commands/user.c:224 commands/user.c:233 -#: commands/user.c:242 commands/user.c:251 commands/user.c:260 -#: commands/user.c:547 commands/user.c:564 commands/user.c:572 -#: commands/user.c:580 commands/user.c:588 commands/user.c:596 -#: commands/user.c:604 commands/user.c:612 commands/user.c:621 -#: commands/user.c:629 commands/user.c:637 replication/pgoutput/pgoutput.c:107 -#: replication/pgoutput/pgoutput.c:128 +#: commands/functioncmds.c:559 commands/functioncmds.c:684 +#: commands/functioncmds.c:693 commands/functioncmds.c:702 +#: commands/functioncmds.c:711 commands/functioncmds.c:2105 +#: commands/functioncmds.c:2113 commands/publicationcmds.c:92 +#: commands/sequence.c:1255 commands/sequence.c:1265 commands/sequence.c:1275 +#: commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 +#: commands/sequence.c:1315 commands/sequence.c:1325 commands/sequence.c:1335 +#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 +#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 +#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 +#: commands/subscriptioncmds.c:179 commands/tablecmds.c:6296 +#: commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 +#: commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 +#: commands/user.c:134 commands/user.c:148 commands/user.c:157 +#: commands/user.c:166 commands/user.c:175 commands/user.c:184 +#: commands/user.c:193 commands/user.c:202 commands/user.c:211 +#: commands/user.c:220 commands/user.c:229 commands/user.c:238 +#: commands/user.c:247 commands/user.c:555 commands/user.c:563 +#: commands/user.c:571 commands/user.c:579 commands/user.c:587 +#: commands/user.c:595 commands/user.c:603 commands/user.c:611 +#: commands/user.c:620 commands/user.c:628 commands/user.c:636 +#: parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 +#: replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "widersprüchliche oder überflüssige Optionen" -#: catalog/aclchk.c:992 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "Vorgabeprivilegien können nicht für Spalten gesetzt werden" -#: catalog/aclchk.c:1503 catalog/objectaddress.c:1367 commands/analyze.c:384 -#: commands/copy.c:4657 commands/sequence.c:1625 commands/tablecmds.c:5533 -#: commands/tablecmds.c:5694 commands/tablecmds.c:5751 -#: commands/tablecmds.c:5865 commands/tablecmds.c:5919 -#: commands/tablecmds.c:6011 commands/tablecmds.c:6167 -#: commands/tablecmds.c:8386 commands/tablecmds.c:8662 -#: commands/tablecmds.c:9079 commands/trigger.c:732 parser/analyze.c:2305 -#: parser/parse_relation.c:2575 parser/parse_relation.c:2637 -#: parser/parse_target.c:1001 parser/parse_type.c:127 utils/adt/acl.c:2823 -#: utils/adt/ruleutils.c:2188 +#: catalog/aclchk.c:1212 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "Klausel IN SCHEMA kann nicht verwendet werden, wenn GRANT/REVOKE ON SCHEMAS verwendet wird" + +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 +#: commands/copy.c:4826 commands/sequence.c:1690 commands/tablecmds.c:5942 +#: commands/tablecmds.c:6090 commands/tablecmds.c:6147 +#: commands/tablecmds.c:6221 commands/tablecmds.c:6315 +#: commands/tablecmds.c:6374 commands/tablecmds.c:6513 +#: commands/tablecmds.c:6595 commands/tablecmds.c:6687 +#: commands/tablecmds.c:6781 commands/tablecmds.c:9510 +#: commands/tablecmds.c:9804 commands/tablecmds.c:10285 commands/trigger.c:904 +#: parser/analyze.c:2343 parser/parse_relation.c:2735 +#: parser/parse_relation.c:2798 parser/parse_target.c:1030 +#: parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2466 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "Spalte »%s« von Relation »%s« existiert nicht" -#: catalog/aclchk.c:1769 catalog/objectaddress.c:1207 commands/sequence.c:1137 -#: commands/tablecmds.c:229 commands/tablecmds.c:12734 utils/adt/acl.c:2059 -#: utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 -#: utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1128 +#: commands/tablecmds.c:231 commands/tablecmds.c:14086 utils/adt/acl.c:2076 +#: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 +#: utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "»%s« ist keine Sequenz" -#: catalog/aclchk.c:1807 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "Sequenz »%s« unterstützt nur die Privilegien USAGE, SELECT und UPDATE" -#: catalog/aclchk.c:1824 +#: catalog/aclchk.c:1898 #, c-format msgid "invalid privilege type %s for table" msgstr "ungültiger Privilegtyp %s für Tabelle" -#: catalog/aclchk.c:1990 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" msgstr "ungültiger Privilegtyp %s für Spalte" -#: catalog/aclchk.c:2003 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "Sequenz »%s« unterstützt nur den Spaltenprivilegientyp SELECT" -#: catalog/aclchk.c:2585 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "Sprache »%s« ist nicht »trusted«" -#: catalog/aclchk.c:2587 +#: catalog/aclchk.c:2661 #, c-format msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." msgstr "GRANT und REVOKE sind für nicht vertrauenswürdige Sprachen nicht erlaubt, weil nur Superuser nicht vertrauenswürdige Sprachen verwenden können." -#: catalog/aclchk.c:3101 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "für Array-Typen können keine Privilegien gesetzt werden" -#: catalog/aclchk.c:3102 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "Setzen Sie stattdessen die Privilegien des Elementtyps." -#: catalog/aclchk.c:3109 catalog/objectaddress.c:1497 commands/typecmds.c:3165 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" msgstr "»%s« ist keine Domäne" -#: catalog/aclchk.c:3229 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "unbekannter Privilegtyp »%s«" -#: catalog/aclchk.c:3278 +#: catalog/aclchk.c:3364 #, c-format -msgid "permission denied for column %s" -msgstr "keine Berechtigung für Spalte %s" +msgid "permission denied for aggregate %s" +msgstr "keine Berechtigung für Aggregatfunktion %s" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for collation %s" +msgstr "keine Berechtigung für Sortierfolge %s" -#: catalog/aclchk.c:3280 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for relation %s" -msgstr "keine Berechtigung für Relation %s" +msgid "permission denied for column %s" +msgstr "keine Berechtigung für Spalte %s" -#: catalog/aclchk.c:3282 commands/sequence.c:599 commands/sequence.c:833 -#: commands/sequence.c:875 commands/sequence.c:916 commands/sequence.c:1671 -#: commands/sequence.c:1735 +#: catalog/aclchk.c:3373 #, c-format -msgid "permission denied for sequence %s" -msgstr "keine Berechtigung für Sequenz %s" +msgid "permission denied for conversion %s" +msgstr "keine Berechtigung für Konversion %s" -#: catalog/aclchk.c:3284 +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" msgstr "keine Berechtigung für Datenbank %s" -#: catalog/aclchk.c:3286 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "keine Berechtigung für Funktion %s" +msgid "permission denied for domain %s" +msgstr "keine Berechtigung für Domäne %s" -#: catalog/aclchk.c:3288 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "keine Berechtigung für Operator %s" +msgid "permission denied for event trigger %s" +msgstr "keine Berechtigung für Ereignistrigger %s" -#: catalog/aclchk.c:3290 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "keine Berechtigung für Typ %s" +msgid "permission denied for extension %s" +msgstr "keine Berechtigung für Erweiterung %s" -#: catalog/aclchk.c:3292 +#: catalog/aclchk.c:3388 #, c-format -msgid "permission denied for language %s" -msgstr "keine Berechtigung für Sprache %s" +msgid "permission denied for foreign-data wrapper %s" +msgstr "keine Berechtigung für Fremddaten-Wrapper %s" -#: catalog/aclchk.c:3294 +#: catalog/aclchk.c:3391 #, c-format -msgid "permission denied for large object %s" -msgstr "keine Berechtigung für Large Object %s" +msgid "permission denied for foreign server %s" +msgstr "keine Berechtigung für Fremdserver %s" -#: catalog/aclchk.c:3296 +#: catalog/aclchk.c:3394 #, c-format -msgid "permission denied for schema %s" -msgstr "keine Berechtigung für Schema %s" +msgid "permission denied for foreign table %s" +msgstr "keine Berechtigung für Fremdtabelle %s" -#: catalog/aclchk.c:3298 +#: catalog/aclchk.c:3397 #, c-format -msgid "permission denied for operator class %s" -msgstr "keine Berechtigung für Operatorklasse %s" +msgid "permission denied for function %s" +msgstr "keine Berechtigung für Funktion %s" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "keine Berechtigung für Index %s" + +#: catalog/aclchk.c:3403 +#, c-format +msgid "permission denied for language %s" +msgstr "keine Berechtigung für Sprache %s" + +#: catalog/aclchk.c:3406 +#, c-format +msgid "permission denied for large object %s" +msgstr "keine Berechtigung für Large Object %s" + +#: catalog/aclchk.c:3409 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "keine Berechtigung für materialisierte Sicht %s" + +#: catalog/aclchk.c:3412 +#, c-format +msgid "permission denied for operator class %s" +msgstr "keine Berechtigung für Operatorklasse %s" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "keine Berechtigung für Operator %s" -#: catalog/aclchk.c:3300 +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" msgstr "keine Berechtigung für Operatorfamilie %s" -#: catalog/aclchk.c:3302 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "keine Berechtigung für Sortierfolge %s" +msgid "permission denied for policy %s" +msgstr "keine Berechtigung für Policy %s" -#: catalog/aclchk.c:3304 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "keine Berechtigung für Konversion %s" +msgid "permission denied for procedure %s" +msgstr "keine Berechtigung für Prozedur %s" + +#: catalog/aclchk.c:3427 +#, c-format +msgid "permission denied for publication %s" +msgstr "keine Berechtigung für Publikation %s" + +#: catalog/aclchk.c:3430 +#, c-format +msgid "permission denied for routine %s" +msgstr "keine Berechtigung für Routine %s" -#: catalog/aclchk.c:3306 +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "keine Berechtigung für Schema %s" + +#: catalog/aclchk.c:3436 commands/sequence.c:598 commands/sequence.c:832 +#: commands/sequence.c:874 commands/sequence.c:915 commands/sequence.c:1788 +#: commands/sequence.c:1852 +#, c-format +msgid "permission denied for sequence %s" +msgstr "keine Berechtigung für Sequenz %s" + +#: catalog/aclchk.c:3439 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "keine Berechtigung für Statistikobjekt %s" + +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "keine Berechtigung für Subskription %s" + +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "keine Berechtigung für Tabelle %s" + +#: catalog/aclchk.c:3448 #, c-format msgid "permission denied for tablespace %s" msgstr "keine Berechtigung für Tablespace %s" -#: catalog/aclchk.c:3308 +#: catalog/aclchk.c:3451 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "keine Berechtigung für Textsuchekonfiguration %s" + +#: catalog/aclchk.c:3454 #, c-format msgid "permission denied for text search dictionary %s" msgstr "keine Berechtigung für Textsuchewörterbuch %s" -#: catalog/aclchk.c:3310 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for text search configuration %s" -msgstr "keine Berechtigung für Textsuchekonfiguration %s" +msgid "permission denied for type %s" +msgstr "keine Berechtigung für Typ %s" -#: catalog/aclchk.c:3312 +#: catalog/aclchk.c:3460 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "keine Berechtigung für Fremddaten-Wrapper %s" +msgid "permission denied for view %s" +msgstr "keine Berechtigung für Sicht %s" -#: catalog/aclchk.c:3314 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for foreign server %s" -msgstr "keine Berechtigung für Fremdserver %s" +msgid "must be owner of aggregate %s" +msgstr "Berechtigung nur für Eigentümer der Aggregatfunktion %s" -#: catalog/aclchk.c:3316 +#: catalog/aclchk.c:3498 #, c-format -msgid "permission denied for event trigger %s" -msgstr "keine Berechtigung für Ereignistrigger %s" +msgid "must be owner of collation %s" +msgstr "Berechtigung nur für Eigentümer der Sortierfolge %s" -#: catalog/aclchk.c:3318 +#: catalog/aclchk.c:3501 #, c-format -msgid "permission denied for extension %s" -msgstr "keine Berechtigung für Erweiterung %s" +msgid "must be owner of conversion %s" +msgstr "Berechtigung nur für Eigentümer der Konversion %s" -#: catalog/aclchk.c:3320 +#: catalog/aclchk.c:3504 #, c-format -msgid "permission denied for publication %s" -msgstr "keine Berechtigung für Publikation %s" +msgid "must be owner of database %s" +msgstr "Berechtigung nur für Eigentümer der Datenbank %s" -#: catalog/aclchk.c:3322 +#: catalog/aclchk.c:3507 #, c-format -msgid "permission denied for subscription %s" -msgstr "keine Berechtigung für Subskription %s" +msgid "must be owner of domain %s" +msgstr "Berechtigung nur für Eigentümer der Domäne %s" -#: catalog/aclchk.c:3328 catalog/aclchk.c:3330 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of relation %s" -msgstr "Berechtigung nur für Eigentümer der Relation %s" +msgid "must be owner of event trigger %s" +msgstr "Berechtigung nur für Eigentümer des Ereignistriggers %s" -#: catalog/aclchk.c:3332 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of sequence %s" -msgstr "Berechtigung nur für Eigentümer der Sequenz %s" +msgid "must be owner of extension %s" +msgstr "Berechtigung nur für Eigentümer der Erweiterung %s" -#: catalog/aclchk.c:3334 +#: catalog/aclchk.c:3516 #, c-format -msgid "must be owner of database %s" -msgstr "Berechtigung nur für Eigentümer der Datenbank %s" +msgid "must be owner of foreign-data wrapper %s" +msgstr "Berechtigung nur für Eigentümer des Fremddaten-Wrappers %s" -#: catalog/aclchk.c:3336 +#: catalog/aclchk.c:3519 #, c-format -msgid "must be owner of function %s" -msgstr "Berechtigung nur für Eigentümer der Funktion %s" +msgid "must be owner of foreign server %s" +msgstr "Berechtigung nur für Eigentümer des Fremdservers %s" -#: catalog/aclchk.c:3338 +#: catalog/aclchk.c:3522 #, c-format -msgid "must be owner of operator %s" -msgstr "Berechtigung nur für Eigentümer des Operators %s" +msgid "must be owner of foreign table %s" +msgstr "Berechtigung nur für Eigentümer der Fremdtabelle %s" -#: catalog/aclchk.c:3340 +#: catalog/aclchk.c:3525 #, c-format -msgid "must be owner of type %s" -msgstr "Berechtigung nur für Eigentümer des Typs %s" +msgid "must be owner of function %s" +msgstr "Berechtigung nur für Eigentümer der Funktion %s" -#: catalog/aclchk.c:3342 +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "Berechtigung nur für Eigentümer des Index %s" + +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" msgstr "Berechtigung nur für Eigentümer der Sprache %s" -#: catalog/aclchk.c:3344 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" msgstr "Berechtigung nur für Eigentümer des Large Object %s" -#: catalog/aclchk.c:3346 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "Berechtigung nur für Eigentümer des Schemas %s" +msgid "must be owner of materialized view %s" +msgstr "Berechtigung nur für Eigentümer der materialisierten Sicht %s" -#: catalog/aclchk.c:3348 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" msgstr "Berechtigung nur für Eigentümer der Operatorklasse %s" -#: catalog/aclchk.c:3350 +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "Berechtigung nur für Eigentümer des Operators %s" + +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" msgstr "Berechtigung nur für Eigentümer der Operatorfamilie %s" -#: catalog/aclchk.c:3352 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "Berechtigung nur für Eigentümer der Sortierfolge %s" +msgid "must be owner of procedure %s" +msgstr "Berechtigung nur für Eigentümer der Prozedur %s" -#: catalog/aclchk.c:3354 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "Berechtigung nur für Eigentümer der Konversion %s" +msgid "must be owner of publication %s" +msgstr "Berechtigung nur für Eigentümer der Publikation %s" -#: catalog/aclchk.c:3356 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of tablespace %s" -msgstr "Berechtigung nur für Eigentümer des Tablespace %s" +msgid "must be owner of routine %s" +msgstr "Berechtigung nur für Eigentümer der Routine %s" -#: catalog/aclchk.c:3358 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "Berechtigung nur für Eigentümer des Textsuchewörterbuches %s" +msgid "must be owner of sequence %s" +msgstr "Berechtigung nur für Eigentümer der Sequenz %s" -#: catalog/aclchk.c:3360 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "Berechtigung nur für Eigentümer der Textsuchekonfiguration %s" +msgid "must be owner of subscription %s" +msgstr "Berechtigung nur für Eigentümer der Subskription %s" -#: catalog/aclchk.c:3362 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "Berechtigung nur für Eigentümer des Fremddaten-Wrappers %s" +msgid "must be owner of table %s" +msgstr "Berechtigung nur für Eigentümer der Tabelle %s" -#: catalog/aclchk.c:3364 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign server %s" -msgstr "Berechtigung nur für Eigentümer des Fremdservers %s" +msgid "must be owner of type %s" +msgstr "Berechtigung nur für Eigentümer des Typs %s" -#: catalog/aclchk.c:3366 +#: catalog/aclchk.c:3570 #, c-format -msgid "must be owner of event trigger %s" -msgstr "Berechtigung nur für Eigentümer des Ereignistriggers %s" +msgid "must be owner of view %s" +msgstr "Berechtigung nur für Eigentümer der Sicht %s" -#: catalog/aclchk.c:3368 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of extension %s" -msgstr "Berechtigung nur für Eigentümer der Erweiterung %s" +msgid "must be owner of schema %s" +msgstr "Berechtigung nur für Eigentümer des Schemas %s" -#: catalog/aclchk.c:3370 +#: catalog/aclchk.c:3576 #, c-format -msgid "must be owner of publication %s" -msgstr "Berechtigung nur für Eigentümer der Publikation %s" +msgid "must be owner of statistics object %s" +msgstr "Berechtigung nur für Eigentümer des Statistikobjekts %s" -#: catalog/aclchk.c:3372 +#: catalog/aclchk.c:3579 #, c-format -msgid "must be owner of subscription %s" -msgstr "Berechtigung nur für Eigentümer der Subskription %s" +msgid "must be owner of tablespace %s" +msgstr "Berechtigung nur für Eigentümer des Tablespace %s" + +#: catalog/aclchk.c:3582 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "Berechtigung nur für Eigentümer der Textsuchekonfiguration %s" -#: catalog/aclchk.c:3414 +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "Berechtigung nur für Eigentümer des Textsuchewörterbuches %s" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "Berechtigung nur für Eigentümer der Relation %s" + +#: catalog/aclchk.c:3643 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "keine Berechtigung für Spalte »%s« von Relation »%s«" -#: catalog/aclchk.c:3533 catalog/aclchk.c:3541 +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "Attribut %d der Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3614 catalog/aclchk.c:4533 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" msgstr "Relation mit OID %u existiert nicht" -#: catalog/aclchk.c:3713 catalog/aclchk.c:4951 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "Datenbank mit OID %u existiert nicht" -#: catalog/aclchk.c:3767 catalog/aclchk.c:4611 tcop/fastpath.c:223 -#: utils/fmgr/fmgr.c:2428 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "Funktion mit OID %u existiert nicht" -#: catalog/aclchk.c:3821 catalog/aclchk.c:4637 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" msgstr "Sprache mit OID %u existiert nicht" -#: catalog/aclchk.c:3985 catalog/aclchk.c:4709 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" msgstr "Schema mit OID %u existiert nicht" -#: catalog/aclchk.c:4039 catalog/aclchk.c:4736 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" msgstr "Tablespace mit OID %u existiert nicht" -#: catalog/aclchk.c:4098 catalog/aclchk.c:4870 commands/foreigncmds.c:324 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "Fremddaten-Wrapper mit OID %u existiert nicht" -#: catalog/aclchk.c:4160 catalog/aclchk.c:4897 commands/foreigncmds.c:459 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" msgstr "Fremdserver mit OID %u existiert nicht" -#: catalog/aclchk.c:4220 catalog/aclchk.c:4559 utils/cache/typcache.c:238 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" msgstr "Typ mit OID %u existiert nicht" -#: catalog/aclchk.c:4585 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" msgstr "Operator mit OID %u existiert nicht" -#: catalog/aclchk.c:4762 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" msgstr "Operatorklasse mit OID %u existiert nicht" -#: catalog/aclchk.c:4789 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" msgstr "Operatorfamilie mit OID %u existiert nicht" -#: catalog/aclchk.c:4816 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "Textsuchewörterbuch mit OID %u existiert nicht" -#: catalog/aclchk.c:4843 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "Textsuchekonfiguration mit OID %u existiert nicht" -#: catalog/aclchk.c:4924 commands/event_trigger.c:587 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format msgid "event trigger with OID %u does not exist" msgstr "Ereignistrigger mit OID %u existiert nicht" -#: catalog/aclchk.c:4977 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" msgstr "Sortierfolge mit OID %u existiert nicht" -#: catalog/aclchk.c:5003 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" msgstr "Konversion mit OID %u existiert nicht" -#: catalog/aclchk.c:5044 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" msgstr "Erweiterung mit OID %u existiert nicht" -#: catalog/aclchk.c:5071 commands/publicationcmds.c:746 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 #, c-format msgid "publication with OID %u does not exist" msgstr "Publikation mit OID %u existiert nicht" -#: catalog/aclchk.c:5097 commands/subscriptioncmds.c:682 +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 #, c-format msgid "subscription with OID %u does not exist" msgstr "Subskription mit OID %u existiert nicht" +#: catalog/aclchk.c:5354 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "Statistikobjekt mit OID %u existiert nicht" + #: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" @@ -3620,27 +3651,27 @@ msgstr "kann %s nicht löschen, wird von %s benötigt" msgid "You can drop %s instead." msgstr "Sie können stattdessen %s löschen." -#: catalog/dependency.c:777 catalog/pg_shdepend.c:573 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "kann %s nicht löschen, wird vom Datenbanksystem benötigt" -#: catalog/dependency.c:895 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" msgstr "Löschvorgang löscht automatisch %s" -#: catalog/dependency.c:907 catalog/dependency.c:916 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" msgstr "%s hängt von %s ab" -#: catalog/dependency.c:928 catalog/dependency.c:937 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" msgstr "Löschvorgang löscht ebenfalls %s" -#: catalog/dependency.c:945 catalog/pg_shdepend.c:684 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -3655,617 +3686,632 @@ msgstr[1] "" "\n" "und %d weitere Objekte (Liste im Serverlog)" -#: catalog/dependency.c:957 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "kann %s nicht löschen, weil andere Objekte davon abhängen" -#: catalog/dependency.c:961 catalog/dependency.c:968 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Verwenden Sie DROP ... CASCADE, um die abhängigen Objekte ebenfalls zu löschen." -#: catalog/dependency.c:965 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "kann gewünschte Objekte nicht löschen, weil andere Objekte davon abhängen" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:974 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "Löschvorgang löscht ebenfalls %d weiteres Objekt" msgstr[1] "Löschvorgang löscht ebenfalls %d weitere Objekte" -#: catalog/dependency.c:1616 -#, fuzzy, c-format -#| msgid "constant of the type \"regrole\" cannot be used here" +#: catalog/dependency.c:1644 +#, c-format msgid "constant of the type %s cannot be used here" -msgstr "Konstante vom Typ »regrole« kann hier nicht verwendet werden" +msgstr "Konstante vom Typ %s kann hier nicht verwendet werden" -#: catalog/heap.c:281 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "keine Berechtigung, um »%s.%s« zu erzeugen" -#: catalog/heap.c:283 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Änderungen an Systemkatalogen sind gegenwärtig nicht erlaubt." -#: catalog/heap.c:418 commands/tablecmds.c:1619 commands/tablecmds.c:2122 -#: commands/tablecmds.c:5144 +#: catalog/heap.c:433 commands/tablecmds.c:1884 commands/tablecmds.c:2417 +#: commands/tablecmds.c:5509 #, c-format msgid "tables can have at most %d columns" msgstr "Tabellen können höchstens %d Spalten haben" -#: catalog/heap.c:435 commands/tablecmds.c:5402 +#: catalog/heap.c:452 commands/tablecmds.c:5805 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "Spaltenname »%s« steht im Konflikt mit dem Namen einer Systemspalte" -#: catalog/heap.c:451 +#: catalog/heap.c:468 #, c-format msgid "column name \"%s\" specified more than once" msgstr "Spaltenname »%s« mehrmals angegeben" -#: catalog/heap.c:504 +#: catalog/heap.c:521 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "Spalte »%s« hat Pseudotyp %s" -#: catalog/heap.c:534 +#: catalog/heap.c:551 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "zusammengesetzter Typ %s kann nicht Teil von sich selbst werden" -#: catalog/heap.c:576 commands/createas.c:201 commands/createas.c:497 +#: catalog/heap.c:593 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "für Spalte »%s« mit sortierbarem Typ %s wurde keine Sortierfolge abgeleitet" -#: catalog/heap.c:578 commands/createas.c:204 commands/createas.c:500 -#: commands/indexcmds.c:1141 commands/tablecmds.c:13000 commands/view.c:103 -#: regex/regc_pg_locale.c:262 utils/adt/formatting.c:1500 -#: utils/adt/formatting.c:1552 utils/adt/formatting.c:1620 -#: utils/adt/formatting.c:1672 utils/adt/formatting.c:1741 -#: utils/adt/formatting.c:1805 utils/adt/like.c:213 utils/adt/selfuncs.c:5332 -#: utils/adt/varlena.c:1422 utils/adt/varlena.c:1827 +#: catalog/heap.c:595 commands/createas.c:204 commands/createas.c:501 +#: commands/indexcmds.c:1588 commands/tablecmds.c:14372 commands/view.c:105 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 +#: utils/adt/selfuncs.c:5807 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "Verwenden Sie die COLLATE-Klausel, um die Sortierfolge explizit zu setzen." -#: catalog/heap.c:1063 catalog/index.c:806 commands/tablecmds.c:2903 +#: catalog/heap.c:1084 catalog/index.c:876 commands/tablecmds.c:3179 #, c-format msgid "relation \"%s\" already exists" msgstr "Relation »%s« existiert bereits" -#: catalog/heap.c:1079 catalog/pg_type.c:410 catalog/pg_type.c:717 -#: commands/typecmds.c:239 commands/typecmds.c:788 commands/typecmds.c:1139 -#: commands/typecmds.c:1350 commands/typecmds.c:2106 +#: catalog/heap.c:1100 catalog/pg_type.c:417 catalog/pg_type.c:732 +#: commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 +#: commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "Typ »%s« existiert bereits" -#: catalog/heap.c:1080 +#: catalog/heap.c:1101 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "Eine Relation hat einen zugehörigen Typ mit dem selben Namen, daher müssen Sie einen Namen wählen, der nicht mit einem bestehenden Typ kollidiert." -#: catalog/heap.c:1109 +#: catalog/heap.c:1130 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "Heap-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/heap.c:2063 -#, fuzzy, c-format -#| msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +#: catalog/heap.c:2333 +#, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" -msgstr "aufschiebbarer Unique-Constraint kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" +msgstr "zur partitionierten Tabelle »%s« kann kein NO-INHERIT-Constraint hinzugefügt werden" -#: catalog/heap.c:2321 +#: catalog/heap.c:2598 #, c-format msgid "check constraint \"%s\" already exists" msgstr "Check-Constraint »%s« existiert bereits" -#: catalog/heap.c:2489 catalog/pg_constraint.c:649 commands/tablecmds.c:6525 +#: catalog/heap.c:2768 catalog/index.c:890 catalog/pg_constraint.c:679 +#: commands/tablecmds.c:7157 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "Constraint »%s« existiert bereits für Relation »%s«" -#: catalog/heap.c:2496 +#: catalog/heap.c:2775 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für Relation »%s«" -#: catalog/heap.c:2507 +#: catalog/heap.c:2786 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit vererbtem Constraint für Relation »%s«" -#: catalog/heap.c:2517 +#: catalog/heap.c:2796 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für Relation »%s«" -#: catalog/heap.c:2522 +#: catalog/heap.c:2801 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "Constraint »%s« wird mit geerbter Definition zusammengeführt" -#: catalog/heap.c:2638 +#: catalog/heap.c:2916 #, c-format msgid "cannot use column references in default expression" msgstr "Spaltenverweise können nicht in Vorgabeausdrücken verwendet werden" -#: catalog/heap.c:2663 rewrite/rewriteHandler.c:1097 +#: catalog/heap.c:2941 rewrite/rewriteHandler.c:1177 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "Spalte »%s« hat Typ %s, aber der Vorgabeausdruck hat Typ %s" -#: catalog/heap.c:2668 commands/prepare.c:384 parser/parse_node.c:428 -#: parser/parse_target.c:589 parser/parse_target.c:839 -#: parser/parse_target.c:849 rewrite/rewriteHandler.c:1102 +#: catalog/heap.c:2946 commands/prepare.c:384 parser/parse_node.c:430 +#: parser/parse_target.c:590 parser/parse_target.c:865 +#: parser/parse_target.c:875 rewrite/rewriteHandler.c:1182 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Sie müssen den Ausdruck umschreiben oder eine Typumwandlung vornehmen." -#: catalog/heap.c:2715 +#: catalog/heap.c:2993 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "nur Verweise auf Tabelle »%s« sind im Check-Constraint zugelassen" -#: catalog/heap.c:2955 +#: catalog/heap.c:3243 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "nicht unterstützte Kombination aus ON COMMIT und Fremdschlüssel" -#: catalog/heap.c:2956 +#: catalog/heap.c:3244 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "Tabelle »%s« verweist auf »%s«, aber sie haben nicht die gleiche ON-COMMIT-Einstellung." -#: catalog/heap.c:2961 +#: catalog/heap.c:3249 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "kann eine Tabelle, die in einen Fremdschlüssel-Constraint eingebunden ist, nicht leeren" -#: catalog/heap.c:2962 +#: catalog/heap.c:3250 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "Tabelle »%s« verweist auf »%s«." -#: catalog/heap.c:2964 +#: catalog/heap.c:3252 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "Leeren Sie die Tabelle »%s« gleichzeitig oder verwenden Sie TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1541 parser/parse_utilcmd.c:1627 +#: catalog/index.c:233 parser/parse_utilcmd.c:1823 parser/parse_utilcmd.c:1910 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "mehrere Primärschlüssel für Tabelle »%s« nicht erlaubt" -#: catalog/index.c:228 +#: catalog/index.c:251 #, c-format msgid "primary keys cannot be expressions" msgstr "Primärschlüssel können keine Ausdrücke sein" -#: catalog/index.c:756 catalog/index.c:1174 +#: catalog/index.c:820 catalog/index.c:1291 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "benutzerdefinierte Indexe für Systemkatalogtabellen werden nicht unterstützt" -#: catalog/index.c:766 +#: catalog/index.c:830 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "nebenläufige Indexerzeugung für Systemkatalogtabellen wird nicht unterstützt" -#: catalog/index.c:784 +#: catalog/index.c:848 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "Cluster-globale Indexe können nicht nach initdb erzeugt werden" -#: catalog/index.c:798 commands/createas.c:249 commands/sequence.c:149 -#: parser/parse_utilcmd.c:197 +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 +#: parser/parse_utilcmd.c:205 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "Relation »%s« existiert bereits, wird übersprungen" -#: catalog/index.c:834 +#: catalog/index.c:918 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "Index-OID-Wert für pg_class ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/index.c:1435 +#: catalog/index.c:1566 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY muss die erste Aktion in einer Transaktion sein" -#: catalog/index.c:2020 -#, c-format -msgid "building index \"%s\" on table \"%s\"" +#: catalog/index.c:2295 +#, fuzzy, c-format +#| msgid "building index \"%s\" on table \"%s\"" +msgid "building index \"%s\" on table \"%s\" serially" msgstr "baue Index »%s« von Tabelle »%s«" -#: catalog/index.c:3338 +#: catalog/index.c:2300 +#, fuzzy, c-format +#| msgid "building index \"%s\" on table \"%s\"" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "baue Index »%s« von Tabelle »%s«" +msgstr[1] "baue Index »%s« von Tabelle »%s«" + +#: catalog/index.c:3689 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht reindizieren" -#: catalog/index.c:3469 +#: catalog/index.c:3820 #, c-format msgid "index \"%s\" was reindexed" msgstr "Index »%s« wurde neu indiziert" -#: catalog/index.c:3471 commands/vacuumlazy.c:1345 commands/vacuumlazy.c:1421 -#: commands/vacuumlazy.c:1610 commands/vacuumlazy.c:1820 +#: catalog/index.c:3891 #, c-format -msgid "%s." -msgstr "%s." +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX von partitionierten Tabellen ist noch nicht implementiert, »%s« wird übersprungen" -#: catalog/namespace.c:234 catalog/namespace.c:432 catalog/namespace.c:526 -#: commands/trigger.c:4782 +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 +#: commands/trigger.c:5405 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "Verweise auf andere Datenbanken sind nicht implementiert: »%s.%s.%s«" -#: catalog/namespace.c:291 +#: catalog/namespace.c:306 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "temporäre Tabellen können keinen Schemanamen angeben" -#: catalog/namespace.c:370 +#: catalog/namespace.c:387 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "konnte Sperre für Relation »%s.%s« nicht setzen" -#: catalog/namespace.c:375 commands/lockcmds.c:145 +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:248 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "konnte Sperre für Relation »%s« nicht setzen" -#: catalog/namespace.c:399 parser/parse_relation.c:1137 +#: catalog/namespace.c:420 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "Relation »%s.%s« existiert nicht" -#: catalog/namespace.c:404 parser/parse_relation.c:1150 -#: parser/parse_relation.c:1158 utils/adt/regproc.c:1036 +#: catalog/namespace.c:425 parser/parse_relation.c:1171 +#: parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "Relation »%s« existiert nicht" -#: catalog/namespace.c:472 catalog/namespace.c:2826 commands/extension.c:1460 -#: commands/extension.c:1466 +#: catalog/namespace.c:491 catalog/namespace.c:3008 commands/extension.c:1466 +#: commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "kein Schema für die Objekterzeugung ausgewählt" -#: catalog/namespace.c:624 catalog/namespace.c:637 +#: catalog/namespace.c:643 catalog/namespace.c:656 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "kann keine Relationen in temporären Schemas anderer Sitzungen erzeugen" -#: catalog/namespace.c:628 +#: catalog/namespace.c:647 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "kann keine temporäre Relation in einem nicht-temporären Schema erzeugen" -#: catalog/namespace.c:643 +#: catalog/namespace.c:662 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "nur temporäre Relationen können in temporären Schemas erzeugt werden" -#: catalog/namespace.c:2139 +#: catalog/namespace.c:2200 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "Statistikobjekt »%s« existiert nicht" + +#: catalog/namespace.c:2323 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "Textsucheparser »%s« existiert nicht" -#: catalog/namespace.c:2265 +#: catalog/namespace.c:2449 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "Textsuchewörterbuch »%s« existiert nicht" -#: catalog/namespace.c:2392 +#: catalog/namespace.c:2576 #, c-format msgid "text search template \"%s\" does not exist" msgstr "Textsuchevorlage »%s« existiert nicht" -#: catalog/namespace.c:2518 commands/tsearchcmds.c:1185 -#: utils/cache/ts_cache.c:612 +#: catalog/namespace.c:2702 commands/tsearchcmds.c:1185 +#: utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "Textsuchekonfiguration »%s« existiert nicht" -#: catalog/namespace.c:2631 parser/parse_expr.c:791 parser/parse_target.c:1191 +#: catalog/namespace.c:2815 parser/parse_expr.c:793 parser/parse_target.c:1220 #, c-format msgid "cross-database references are not implemented: %s" msgstr "Verweise auf andere Datenbanken sind nicht implementiert: %s" -#: catalog/namespace.c:2637 gram.y:14068 gram.y:15487 parser/parse_expr.c:798 -#: parser/parse_target.c:1198 +#: catalog/namespace.c:2821 gram.y:14708 gram.y:16140 parser/parse_expr.c:800 +#: parser/parse_target.c:1227 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "falscher qualifizierter Name (zu viele Namensteile): %s" -#: catalog/namespace.c:2768 +#: catalog/namespace.c:2951 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "Objekte können nicht in oder aus temporären Schemas verschoben werden" -#: catalog/namespace.c:2774 +#: catalog/namespace.c:2957 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "Objekte können nicht in oder aus TOAST-Schemas verschoben werden" -#: catalog/namespace.c:2847 commands/schemacmds.c:255 -#: commands/schemacmds.c:333 commands/tablecmds.c:891 +#: catalog/namespace.c:3029 commands/schemacmds.c:256 commands/schemacmds.c:334 +#: commands/tablecmds.c:1017 #, c-format msgid "schema \"%s\" does not exist" msgstr "Schema »%s« existiert nicht" -#: catalog/namespace.c:2878 +#: catalog/namespace.c:3060 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "falscher Relationsname (zu viele Namensteile): %s" -#: catalog/namespace.c:3388 +#: catalog/namespace.c:3594 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "Sortierfolge »%s« für Kodierung »%s« existiert nicht" -#: catalog/namespace.c:3443 +#: catalog/namespace.c:3649 #, c-format msgid "conversion \"%s\" does not exist" msgstr "Konversion »%s« existiert nicht" -#: catalog/namespace.c:3651 +#: catalog/namespace.c:3889 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "keine Berechtigung, um temporäre Tabellen in Datenbank »%s« zu erzeugen" -#: catalog/namespace.c:3667 +#: catalog/namespace.c:3905 #, c-format msgid "cannot create temporary tables during recovery" msgstr "während der Wiederherstellung können keine temporären Tabellen erzeugt werden" -#: catalog/namespace.c:3673 +#: catalog/namespace.c:3911 #, c-format -msgid "cannot create temporary tables in parallel mode" -msgstr "im Parallelmodus können keine temporären Tabellen erzeugt werden" +msgid "cannot create temporary tables during a parallel operation" +msgstr "während einer parallelen Operation können keine temporären Tabellen erzeugt werden" -#: catalog/namespace.c:3922 commands/tablespace.c:1169 commands/variable.c:64 -#: utils/misc/guc.c:9942 utils/misc/guc.c:10020 +#: catalog/namespace.c:4194 commands/tablespace.c:1171 commands/variable.c:64 +#: utils/misc/guc.c:10267 utils/misc/guc.c:10345 #, c-format msgid "List syntax is invalid." msgstr "Die Listensyntax ist ungültig." -#: catalog/objectaddress.c:1215 catalog/pg_publication.c:57 -#: commands/lockcmds.c:93 commands/policy.c:94 commands/policy.c:391 -#: commands/policy.c:480 commands/tablecmds.c:223 commands/tablecmds.c:265 -#: commands/tablecmds.c:1477 commands/tablecmds.c:4665 -#: commands/tablecmds.c:8502 +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 +#: commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1742 +#: commands/tablecmds.c:5004 commands/tablecmds.c:9628 #, c-format msgid "\"%s\" is not a table" msgstr "»%s« ist keine Tabelle" -#: catalog/objectaddress.c:1222 commands/tablecmds.c:235 -#: commands/tablecmds.c:4695 commands/tablecmds.c:12739 commands/view.c:141 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 +#: commands/tablecmds.c:5034 commands/tablecmds.c:14091 commands/view.c:143 #, c-format msgid "\"%s\" is not a view" msgstr "»%s« ist keine Sicht" -#: catalog/objectaddress.c:1229 commands/matview.c:172 -#: commands/tablecmds.c:241 commands/tablecmds.c:12744 +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 +#: commands/tablecmds.c:14096 #, c-format msgid "\"%s\" is not a materialized view" msgstr "»%s« ist keine materialisierte Sicht" -#: catalog/objectaddress.c:1236 commands/tablecmds.c:259 -#: commands/tablecmds.c:4698 commands/tablecmds.c:12749 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 +#: commands/tablecmds.c:5037 commands/tablecmds.c:14101 #, c-format msgid "\"%s\" is not a foreign table" msgstr "»%s« ist keine Fremdtabelle" -#: catalog/objectaddress.c:1277 -#, fuzzy, c-format -#| msgid "%s must specify unqualified relation names" +#: catalog/objectaddress.c:1300 +#, c-format msgid "must specify relation and object name" -msgstr "%s muss unqualifizierte Relationsnamen angeben" +msgstr "Relations- und Objektname müssen angegeben werden" -#: catalog/objectaddress.c:1353 catalog/objectaddress.c:1406 +#: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 #, c-format msgid "column name must be qualified" msgstr "Spaltenname muss qualifiziert werden" -#: catalog/objectaddress.c:1449 +#: catalog/objectaddress.c:1472 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "Vorgabewert für Spalte »%s« von Relation »%s« existiert nicht" -#: catalog/objectaddress.c:1486 commands/functioncmds.c:128 -#: commands/tablecmds.c:251 commands/typecmds.c:3233 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:794 utils/adt/acl.c:4357 -#: utils/adt/regproc.c:1227 +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 +#: commands/tablecmds.c:253 commands/typecmds.c:3324 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 #, c-format msgid "type \"%s\" does not exist" msgstr "Typ »%s« existiert nicht" -#: catalog/objectaddress.c:1603 +#: catalog/objectaddress.c:1628 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "Operator %d (%s, %s) von %s existiert nicht" -#: catalog/objectaddress.c:1632 +#: catalog/objectaddress.c:1659 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "Funktion %d (%s, %s) von %s existiert nicht" -#: catalog/objectaddress.c:1681 catalog/objectaddress.c:1707 +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "Benutzerabbildung für Benutzer »%s« auf Server »%s« existiert nicht" -#: catalog/objectaddress.c:1696 commands/foreigncmds.c:428 -#: commands/foreigncmds.c:991 commands/foreigncmds.c:1349 +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 +#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 #: foreign/foreign.c:688 #, c-format msgid "server \"%s\" does not exist" msgstr "Server »%s« existiert nicht" -#: catalog/objectaddress.c:1763 +#: catalog/objectaddress.c:1792 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "Publikationsrelation »%s« in Publikation »%s« existiert nicht" -#: catalog/objectaddress.c:1822 +#: catalog/objectaddress.c:1854 #, c-format -msgid "unrecognized default ACL object type %c" -msgstr "unbekannter Standard-ACL-Objekttyp %c" +msgid "unrecognized default ACL object type \"%c\"" +msgstr "unbekannter Standard-ACL-Objekttyp »%c«" -#: catalog/objectaddress.c:1823 +#: catalog/objectaddress.c:1855 #, c-format -msgid "Valid object types are \"r\", \"S\", \"f\", and \"T\"." -msgstr "Gültige Objekttypen sind »r«, »S«, »f« und »T«." +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Gültige Objekttypen sind »%c«, »%c«, »%c«, »%c«, »%c«." -#: catalog/objectaddress.c:1869 +#: catalog/objectaddress.c:1906 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "Standard-ACL für Benutzer »%s« in Schema »%s« für %s existiert nicht" -#: catalog/objectaddress.c:1874 +#: catalog/objectaddress.c:1911 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "Standard-ACL für Benutzer »%s« für %s existiert nicht" -#: catalog/objectaddress.c:1901 catalog/objectaddress.c:1959 -#: catalog/objectaddress.c:2014 +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 +#: catalog/objectaddress.c:2053 #, c-format msgid "name or argument lists may not contain nulls" msgstr "Namens- oder Argumentlisten dürfen keine NULL-Werte enthalten" -#: catalog/objectaddress.c:1935 +#: catalog/objectaddress.c:1972 #, c-format msgid "unsupported object type \"%s\"" msgstr "nicht unterstützter Objekttyp »%s«" -#: catalog/objectaddress.c:1955 catalog/objectaddress.c:1973 -#: catalog/objectaddress.c:2110 +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 +#: catalog/objectaddress.c:2151 #, c-format msgid "name list length must be exactly %d" msgstr "Länge der Namensliste muss genau %d sein" -#: catalog/objectaddress.c:1977 +#: catalog/objectaddress.c:2014 #, c-format msgid "large object OID may not be null" msgstr "Large-Object-OID darf nicht NULL sein" -#: catalog/objectaddress.c:1986 catalog/objectaddress.c:2047 -#: catalog/objectaddress.c:2054 +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:2093 #, c-format msgid "name list length must be at least %d" msgstr "Länge der Namensliste muss mindestens %d sein" -#: catalog/objectaddress.c:2040 catalog/objectaddress.c:2060 +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 #, c-format msgid "argument list length must be exactly %d" msgstr "Länge der Argumentliste muss genau %d sein" -#: catalog/objectaddress.c:2285 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "Berechtigung nur für Eigentümer des Large Object %u" -#: catalog/objectaddress.c:2300 commands/functioncmds.c:1419 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 #, c-format msgid "must be owner of type %s or type %s" msgstr "Berechtigung nur für Eigentümer des Typs %s oder des Typs %s" -#: catalog/objectaddress.c:2350 catalog/objectaddress.c:2367 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" msgstr "Berechtigung nur für Superuser" -#: catalog/objectaddress.c:2357 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "Berechtigung nur mit CREATEROLE-Privileg" -#: catalog/objectaddress.c:2432 +#: catalog/objectaddress.c:2481 #, c-format msgid "unrecognized object type \"%s\"" msgstr "unbekannter Objekttyp »%s«" -#: catalog/objectaddress.c:2627 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " Spalte %s" +msgid "column %s of %s" +msgstr "Spalte %s von %s" -#: catalog/objectaddress.c:2633 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" msgstr "Funktion %s" -#: catalog/objectaddress.c:2638 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" msgstr "Typ %s" -#: catalog/objectaddress.c:2668 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" msgstr "Typumwandlung von %s in %s" -#: catalog/objectaddress.c:2688 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" msgstr "Sortierfolge %s" -#: catalog/objectaddress.c:2712 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" msgstr "Constraint %s für %s" -#: catalog/objectaddress.c:2718 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" msgstr "Constraint %s" -#: catalog/objectaddress.c:2735 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" msgstr "Konversion %s" -#: catalog/objectaddress.c:2772 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" +msgid "default value for %s" msgstr "Vorgabewert für %s" -#: catalog/objectaddress.c:2781 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "Sprache %s" -#: catalog/objectaddress.c:2786 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" msgstr "Large Object %u" -#: catalog/objectaddress.c:2791 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "Operator %s" -#: catalog/objectaddress.c:2823 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "Operatorklasse %s für Zugriffsmethode %s" +#: catalog/objectaddress.c:2939 +#, c-format +msgid "access method %s" +msgstr "Zugriffsmethode %s" + #. translator: %d is the operator strategy (a number), the #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2873 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "Operator %d (%s, %s) von %s: %s" @@ -4274,406 +4320,410 @@ msgstr "Operator %d (%s, %s) von %s: %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2923 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "Funktion %d (%s, %s) von %s: %s" -#: catalog/objectaddress.c:2963 -#, c-format -msgid "rule %s on " -msgstr "Regel %s für " - -#: catalog/objectaddress.c:2985 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "transform for %s language %s" -msgstr "Transformation %s für Sprache %s" +msgid "rule %s on %s" +msgstr "Regel %s für %s" -#: catalog/objectaddress.c:3019 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "Trigger %s für " +msgid "trigger %s on %s" +msgstr "Trigger %s für %s" -#: catalog/objectaddress.c:3036 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" msgstr "Schema %s" -#: catalog/objectaddress.c:3049 +#: catalog/objectaddress.c:3152 +#, c-format +msgid "statistics object %s" +msgstr "Statistikobjekt %s" + +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" msgstr "Textsucheparser %s" -#: catalog/objectaddress.c:3064 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" msgstr "Textsuchewörterbuch %s" -#: catalog/objectaddress.c:3079 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" msgstr "Textsuchevorlage %s" -#: catalog/objectaddress.c:3094 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" msgstr "Textsuchekonfiguration %s" -#: catalog/objectaddress.c:3102 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" msgstr "Rolle %s" -#: catalog/objectaddress.c:3115 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" msgstr "Datenbank %s" -#: catalog/objectaddress.c:3127 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" msgstr "Tablespace %s" -#: catalog/objectaddress.c:3136 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" msgstr "Fremddaten-Wrapper %s" -#: catalog/objectaddress.c:3145 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" msgstr "Server %s" -#: catalog/objectaddress.c:3173 +#: catalog/objectaddress.c:3337 #, c-format msgid "user mapping for %s on server %s" msgstr "Benutzerabbildung für %s auf Server %s" -#: catalog/objectaddress.c:3208 +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "Vorgabeprivilegien für neue Relationen von Rolle %s" -#: catalog/objectaddress.c:3213 +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "Vorgabeprivilegien für neue Sequenzen von Rolle %s" -#: catalog/objectaddress.c:3218 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "Vorgabeprivilegien für neue Funktionen von Rolle %s" -#: catalog/objectaddress.c:3223 +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien für neue Typen von Rolle %s in Schema %s" + +#: catalog/objectaddress.c:3416 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "Vorgabeprivilegien für neue Typen von Rolle %s" -#: catalog/objectaddress.c:3229 +#: catalog/objectaddress.c:3422 #, c-format -msgid "default privileges belonging to role %s" -msgstr "Vorgabeprivilegien von Rolle %s" +msgid "default privileges on new schemas belonging to role %s" +msgstr "Vorgabeprivilegien für neue Schemas von Rolle %s" + +#: catalog/objectaddress.c:3429 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "Vorgabeprivilegien von Rolle %s in Schema %s" -#: catalog/objectaddress.c:3237 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr " in Schema %s" +msgid "default privileges belonging to role %s" +msgstr "Vorgabeprivilegien von Rolle %s" -#: catalog/objectaddress.c:3254 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" msgstr "Erweiterung %s" -#: catalog/objectaddress.c:3267 +#: catalog/objectaddress.c:3464 #, c-format msgid "event trigger %s" msgstr "Ereignistrigger %s" -#: catalog/objectaddress.c:3299 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 #, c-format -msgid "policy %s on " -msgstr "Policy %s für " +msgid "policy %s on %s" +msgstr "Policy %s für %s" -#: catalog/objectaddress.c:3317 -#, c-format -msgid "access method %s" -msgstr "Zugriffsmethode %s" - -#: catalog/objectaddress.c:3325 +#: catalog/objectaddress.c:3510 #, c-format msgid "publication %s" msgstr "Publikation %s" -#: catalog/objectaddress.c:3345 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 #, c-format -msgid "publication table %s in publication %s" -msgstr "Publikationstabelle %s in Publikation %s" +msgid "publication of %s in publication %s" +msgstr "Publikation von %s in Publikation %s" -#: catalog/objectaddress.c:3353 +#: catalog/objectaddress.c:3544 #, c-format msgid "subscription %s" msgstr "Subskription %s" -#: catalog/objectaddress.c:3413 +#: catalog/objectaddress.c:3562 +#, c-format +msgid "transform for %s language %s" +msgstr "Transformation %s für Sprache %s" + +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" msgstr "Tabelle %s" -#: catalog/objectaddress.c:3417 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" msgstr "Index %s" -#: catalog/objectaddress.c:3421 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "Sequenz %s" -#: catalog/objectaddress.c:3425 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "TOAST-Tabelle %s" -#: catalog/objectaddress.c:3429 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "Sicht %s" -#: catalog/objectaddress.c:3433 +#: catalog/objectaddress.c:3646 #, c-format msgid "materialized view %s" msgstr "materialisierte Sicht %s" -#: catalog/objectaddress.c:3437 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "zusammengesetzter Typ %s" -#: catalog/objectaddress.c:3441 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" msgstr "Fremdtabelle %s" -#: catalog/objectaddress.c:3446 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "Relation %s" -#: catalog/objectaddress.c:3483 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" msgstr "Operatorfamilie %s für Zugriffsmethode %s" -#: catalog/objectaddress.c:4854 -#, c-format -msgid "%s in publication %s" -msgstr "%s in Publikation %s" - -#: catalog/partition.c:741 -#, fuzzy, c-format -#| msgid "cannot determine transition data type" -msgid "cannot create range partition with empty range" -msgstr "kann Übergangsdatentyp nicht bestimmen" - -#: catalog/partition.c:835 -#, fuzzy, c-format -#| msgid "relation \"%s\" is not a parent of relation \"%s\"" -msgid "partition \"%s\" would overlap partition \"%s\"" -msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" - -#: catalog/partition.c:939 catalog/partition.c:1088 commands/analyze.c:1438 -#: commands/tablecmds.c:8564 executor/execMain.c:3159 executor/execQual.c:2691 +#: catalog/partition.c:180 commands/analyze.c:1514 commands/indexcmds.c:928 +#: commands/tablecmds.c:944 commands/tablecmds.c:7897 commands/tablecmds.c:9690 +#: commands/tablecmds.c:14985 commands/tablecmds.c:15514 +#: executor/execExprInterp.c:3275 executor/execMain.c:1940 +#: executor/execMain.c:2019 executor/execMain.c:2067 executor/execMain.c:2173 +#: executor/execPartition.c:462 executor/execPartition.c:522 +#: executor/execPartition.c:638 executor/execPartition.c:741 +#: executor/execPartition.c:812 executor/execPartition.c:1010 +#: executor/nodeModifyTable.c:1859 msgid "could not convert row type" msgstr "konnte Zeilentyp nicht umwandeln" -#: catalog/partition.c:1726 -#, c-format -msgid "range partition key of row contains null" -msgstr "" - -#: catalog/pg_aggregate.c:125 +#: catalog/pg_aggregate.c:126 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "Aggregatfunktionen können nicht mehr als %d Argument haben" msgstr[1] "Aggregatfunktionen können nicht mehr als %d Argumente haben" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" msgstr "kann Übergangsdatentyp nicht bestimmen" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." msgstr "Eine Aggregatfunktion mit polymorphischem Übergangstyp muss mindestens ein polymorphisches Argument haben." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:173 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "eine variadische Ordered-Set-Aggregatfunktion muss VARIADIC-Typ ANY verwenden" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:199 #, c-format msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "eine Hypothetical-Set-Aggregatfunktion muss direkte Argumente haben, die mit ihren aggregierten Argumenten übereinstimmen" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "Rückgabetyp der Übergangsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "Anfangswert darf nicht ausgelassen werden, wenn Übergangsfunktion strikt ist und Übergangstyp nicht mit Eingabetyp kompatibel ist" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:335 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "Rückgabetyp der inversen Übergangsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2298 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "Striktheit der vorwärtigen und inversen Übergangsfunktionen einer Aggregatfunktion müssen übereinstimmen" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "Abschlussfunktion mit zusätzlichen Argumenten darf nicht als STRICT deklariert sein" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:427 #, c-format msgid "return type of combine function %s is not %s" msgstr "Rückgabetyp der Kombinierfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:436 +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2947 #, c-format -msgid "combine function with \"%s\" transition type must not be declared STRICT" -msgstr "Kombinierfunktion mit Übergangstyp »%s« darf nicht als STRICT deklariert sein" +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "Kombinierfunktion mit Übergangstyp %s darf nicht als STRICT deklariert sein" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:458 #, c-format msgid "return type of serialization function %s is not %s" msgstr "Rückgabetyp der Serialisierungsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:479 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "Rückgabetyp der Deserialisierungsfunktion %s ist nicht %s" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:243 catalog/pg_proc.c:250 +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "kann Ergebnisdatentyp nicht bestimmen" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:496 #, c-format msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." msgstr "Eine Aggregatfunktion, die einen polymorphischen Typ zurückgibt, muss mindestens ein polymorphisches Argument haben." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:256 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "unsichere Verwendung des Pseudotyps »internal«" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:257 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgstr "Eine Funktion, die »internal« zurückgibt, muss mindestens ein Argument vom Typ »internal« haben." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:562 #, c-format msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "Moving-Aggregat-Implementierung gibt Typ %s zurück, aber die normale Implementierung gibt Typ %s zurück" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "Sortieroperator kann nur für Aggregatfunktionen mit einem Argument angegeben werden" -#: catalog/pg_aggregate.c:810 commands/typecmds.c:1698 -#: commands/typecmds.c:1749 commands/typecmds.c:1780 commands/typecmds.c:1803 -#: commands/typecmds.c:1824 commands/typecmds.c:1851 commands/typecmds.c:1878 -#: commands/typecmds.c:1955 commands/typecmds.c:1997 parser/parse_func.c:365 -#: parser/parse_func.c:394 parser/parse_func.c:419 parser/parse_func.c:433 -#: parser/parse_func.c:508 parser/parse_func.c:519 parser/parse_func.c:1927 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 +#: commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 +#: commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 +#: commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 +#: parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 +#: parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "Funktion %s existiert nicht" -#: catalog/pg_aggregate.c:816 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "Funktion %s gibt eine Ergebnismenge zurück" -#: catalog/pg_aggregate.c:831 +#: catalog/pg_aggregate.c:840 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "Funktion %s muss VARIADIC ANY akzeptieren, um in dieser Aggregatfunktion verwendet zu werden" -#: catalog/pg_aggregate.c:855 +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "Funktion %s erfordert Typumwandlung zur Laufzeit" -#: catalog/pg_collation.c:81 -#, c-format -msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" -msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits, wird übersprungen" - -#: catalog/pg_collation.c:88 -#, c-format -msgid "collation \"%s\" for encoding \"%s\" already exists" -msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits" - -#: catalog/pg_collation.c:106 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format msgid "collation \"%s\" already exists, skipping" msgstr "Sortierfolge »%s« existiert bereits, wird übersprungen" -#: catalog/pg_collation.c:113 +#: catalog/pg_collation.c:94 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits, wird übersprungen" + +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "Sortierfolge »%s« existiert bereits" -#: catalog/pg_constraint.c:658 +#: catalog/pg_collation.c:104 #, c-format -msgid "constraint \"%s\" for domain %s already exists" -msgstr "Constraint »%s« für Domäne %s existiert bereits" +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits" -#: catalog/pg_constraint.c:788 +#: catalog/pg_constraint.c:687 #, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "Tabelle »%s« hat mehrere Constraints namens »%s«" +msgid "constraint \"%s\" for domain %s already exists" +msgstr "Constraint »%s« für Domäne %s existiert bereits" -#: catalog/pg_constraint.c:800 +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "Constraint »%s« für Tabelle »%s« existiert nicht" -#: catalog/pg_constraint.c:846 -#, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "Domäne »%s« hat mehrere Constraints namens »%s«" - -#: catalog/pg_constraint.c:858 +#: catalog/pg_constraint.c:1056 #, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" -msgstr "Constraint »%s« für Domäne »%s« existiert nicht" +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "Constraint »%s« für Domäne %s existiert nicht" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "Konversion »%s« existiert bereits" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "Standardumwandlung von %s nach %s existiert bereits" -#: catalog/pg_depend.c:163 commands/extension.c:3211 +#: catalog/pg_depend.c:163 commands/extension.c:3225 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s ist schon Mitglied der Erweiterung »%s«" @@ -4718,206 +4768,227 @@ msgstr "OID-Wert für pg_enum ist im Binary-Upgrade-Modus nicht gesetzt" msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" msgstr "ALTER TYPE ADD BEFORE/AFTER ist mit Binary Upgrade inkompatibel" -#: catalog/pg_namespace.c:61 commands/schemacmds.c:263 +#: catalog/pg_namespace.c:63 commands/schemacmds.c:264 #, c-format msgid "schema \"%s\" already exists" msgstr "Schema »%s« existiert bereits" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:358 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "»%s« ist kein gültiger Operatorname" -#: catalog/pg_operator.c:367 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" msgstr "nur binäre Operatoren können Kommutatoren haben" -#: catalog/pg_operator.c:371 commands/operatorcmds.c:482 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "nur binäre Operatoren können Join-Selectivity haben" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "nur binäre Operatoren können an einem Merge-Verbund teilnehmen" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "nur binäre Operatoren können eine Hash-Funktion haben" -#: catalog/pg_operator.c:390 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "nur Boole’sche Operatoren können Negatoren haben" -#: catalog/pg_operator.c:394 commands/operatorcmds.c:490 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "nur Boole’sche Operatoren können Restriction-Selectivity haben" -#: catalog/pg_operator.c:398 commands/operatorcmds.c:494 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "nur Boole’sche Operatoren können Join-Selectivity haben" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "nur Boole’sche Operatoren können an einem Merge-Verbund teilnehmen" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "nur Boole’sche Operatoren können eine Hash-Funktion haben" -#: catalog/pg_operator.c:418 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "Operator %s existiert bereits" -#: catalog/pg_operator.c:612 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "Operator kann nicht sein eigener Negator oder Sortierungsoperator sein" -#: catalog/pg_proc.c:131 parser/parse_func.c:1951 parser/parse_func.c:1991 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "Funktionen können nicht mehr als %d Argument haben" msgstr[1] "Funktionen können nicht mehr als %d Argumente haben" -#: catalog/pg_proc.c:244 +#: catalog/pg_proc.c:241 #, c-format msgid "A function returning a polymorphic type must have at least one polymorphic argument." msgstr "Eine Funktion, die einen polymorphischen Typ zurückgibt, muss mindestens ein polymorphisches Argument haben." -#: catalog/pg_proc.c:251 +#: catalog/pg_proc.c:248 #, c-format msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." msgstr "Eine Funktion, die »anyrange« zurückgibt, muss mindestens ein Argument vom Typ »anyrange« haben." -#: catalog/pg_proc.c:269 -#, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "»%s« ist schon ein Attribut von Typ %s" - -#: catalog/pg_proc.c:400 +#: catalog/pg_proc.c:383 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "Funktion »%s« existiert bereits mit den selben Argumenttypen" -#: catalog/pg_proc.c:414 catalog/pg_proc.c:437 +#: catalog/pg_proc.c:393 #, c-format -msgid "cannot change return type of existing function" -msgstr "kann Rückgabetyp einer bestehenden Funktion nicht ändern" +msgid "cannot change routine kind" +msgstr "kann Routinenart nicht ändern" -#: catalog/pg_proc.c:415 catalog/pg_proc.c:439 catalog/pg_proc.c:482 -#: catalog/pg_proc.c:506 catalog/pg_proc.c:532 +#: catalog/pg_proc.c:395 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "Verwenden Sie zuerst DROP FUNCTION %s." +msgid "\"%s\" is an aggregate function." +msgstr "»%s« ist eine Aggregatfunktion." -#: catalog/pg_proc.c:438 +#: catalog/pg_proc.c:397 #, c-format -msgid "Row type defined by OUT parameters is different." -msgstr "Der von OUT-Parametern bestimmte Zeilentyp ist verschieden." +msgid "\"%s\" is a function." +msgstr "»%s« ist eine Funktion." -#: catalog/pg_proc.c:480 +#: catalog/pg_proc.c:399 #, c-format -msgid "cannot change name of input parameter \"%s\"" -msgstr "kann Name des Eingabeparameters »%s« nicht ändern" +msgid "\"%s\" is a procedure." +msgstr "»%s« ist eine Prozedur." -#: catalog/pg_proc.c:505 +#: catalog/pg_proc.c:401 #, c-format -msgid "cannot remove parameter defaults from existing function" -msgstr "kann Parametervorgabewerte einer bestehenden Funktion nicht entfernen" +msgid "\"%s\" is a window function." +msgstr "»%s« ist eine Fensterfunktion." -#: catalog/pg_proc.c:531 +#: catalog/pg_proc.c:419 #, c-format -msgid "cannot change data type of existing parameter default value" -msgstr "kann Datentyp eines bestehenden Parametervorgabewerts nicht ändern" +msgid "cannot change whether a procedure has output parameters" +msgstr "man kann nicht ändern, ob eine Prozedur Ausgabeparameter hat" -#: catalog/pg_proc.c:544 +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 #, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "Funktion »%s« ist eine Aggregatfunktion" +msgid "cannot change return type of existing function" +msgstr "kann Rückgabetyp einer bestehenden Funktion nicht ändern" + +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 +#: catalog/pg_proc.c:520 catalog/pg_proc.c:548 +#, c-format +msgid "Use %s %s first." +msgstr "Verwenden Sie zuerst %s %s." + +#: catalog/pg_proc.c:447 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "Der von OUT-Parametern bestimmte Zeilentyp ist verschieden." -#: catalog/pg_proc.c:549 +#: catalog/pg_proc.c:491 #, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "Funktion »%s« ist keine Aggregatfunktion" +msgid "cannot change name of input parameter \"%s\"" +msgstr "kann Name des Eingabeparameters »%s« nicht ändern" -#: catalog/pg_proc.c:557 +#: catalog/pg_proc.c:518 #, c-format -msgid "function \"%s\" is a window function" -msgstr "Funktion %s ist eine Fensterfunktion" +msgid "cannot remove parameter defaults from existing function" +msgstr "kann Parametervorgabewerte einer bestehenden Funktion nicht entfernen" -#: catalog/pg_proc.c:562 +#: catalog/pg_proc.c:546 #, c-format -msgid "function \"%s\" is not a window function" -msgstr "Funktion »%s« ist keine Fensterfunktion" +msgid "cannot change data type of existing parameter default value" +msgstr "kann Datentyp eines bestehenden Parametervorgabewerts nicht ändern" -#: catalog/pg_proc.c:768 +#: catalog/pg_proc.c:749 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "es gibt keine eingebaute Funktion namens %s" -#: catalog/pg_proc.c:866 +#: catalog/pg_proc.c:847 #, c-format msgid "SQL functions cannot return type %s" msgstr "SQL-Funktionen können keinen Rückgabetyp »%s« haben" -#: catalog/pg_proc.c:881 +#: catalog/pg_proc.c:862 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "SQL-Funktionen können keine Argumente vom Typ »%s« haben" -#: catalog/pg_proc.c:967 executor/functions.c:1424 +#: catalog/pg_proc.c:950 executor/functions.c:1434 #, c-format msgid "SQL function \"%s\"" msgstr "SQL-Funktion »%s«" +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "»%s« ist eine partitionierte Tabelle" + #: catalog/pg_publication.c:59 #, c-format +msgid "Adding partitioned tables to publications is not supported." +msgstr "Partitionierte Tabellen in Publikationen werden nicht unterstützt." + +#: catalog/pg_publication.c:60 +#, c-format +msgid "You can add the table partitions individually." +msgstr "Sie können die Tabellenpartitionen einzeln hinzufügen." + +#: catalog/pg_publication.c:68 +#, c-format msgid "Only tables can be added to publications." msgstr "Nur Tabellen können Teil einer Publikationen sein." -#: catalog/pg_publication.c:65 +#: catalog/pg_publication.c:74 #, c-format msgid "\"%s\" is a system table" msgstr "»%s« ist eine Systemtabelle" -#: catalog/pg_publication.c:67 +#: catalog/pg_publication.c:76 #, c-format msgid "System tables cannot be added to publications." msgstr "Systemtabellen können nicht Teil einer Publikationen sein." -#: catalog/pg_publication.c:73 +#: catalog/pg_publication.c:82 #, c-format msgid "table \"%s\" cannot be replicated" msgstr "Tabelle »%s« kann nicht repliziert werden" -#: catalog/pg_publication.c:75 +#: catalog/pg_publication.c:84 #, c-format msgid "Temporary and unlogged relations cannot be replicated." msgstr "Temporäre und ungeloggte Tabellen können nicht repliziert werden." -#: catalog/pg_publication.c:134 +#: catalog/pg_publication.c:175 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "Relation »%s« ist schon Mitglied der Publikation »%s«" -#: catalog/pg_publication.c:361 catalog/pg_publication.c:382 -#: commands/publicationcmds.c:430 commands/publicationcmds.c:715 +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 +#: commands/publicationcmds.c:415 commands/publicationcmds.c:716 #, c-format msgid "publication \"%s\" does not exist" msgstr "Publikation »%s« existiert nicht" -#: catalog/pg_shdepend.c:691 +#: catalog/pg_shdepend.c:692 #, c-format msgid "" "\n" @@ -4932,98 +5003,98 @@ msgstr[1] "" "\n" "und Objekte in %d anderen Datenbanken (Liste im Serverlog)" -#: catalog/pg_shdepend.c:997 +#: catalog/pg_shdepend.c:998 #, c-format msgid "role %u was concurrently dropped" msgstr "Rolle %u wurde gleichzeitig gelöscht" -#: catalog/pg_shdepend.c:1016 +#: catalog/pg_shdepend.c:1017 #, c-format msgid "tablespace %u was concurrently dropped" msgstr "Tablespace %u wurde gleichzeitig gelöscht" -#: catalog/pg_shdepend.c:1031 +#: catalog/pg_shdepend.c:1032 #, c-format msgid "database %u was concurrently dropped" msgstr "Datenbank %u wurde gleichzeitig gelöscht" -#: catalog/pg_shdepend.c:1076 +#: catalog/pg_shdepend.c:1077 #, c-format msgid "owner of %s" msgstr "Eigentümer von %s" -#: catalog/pg_shdepend.c:1078 +#: catalog/pg_shdepend.c:1079 #, c-format msgid "privileges for %s" msgstr "Privilegien für %s" -#: catalog/pg_shdepend.c:1080 +#: catalog/pg_shdepend.c:1081 #, c-format msgid "target of %s" msgstr "Ziel von %s" #. translator: %s will always be "database %s" -#: catalog/pg_shdepend.c:1088 +#: catalog/pg_shdepend.c:1089 #, c-format msgid "%d object in %s" msgid_plural "%d objects in %s" msgstr[0] "%d Objekt in %s" msgstr[1] "%d Objekte in %s" -#: catalog/pg_shdepend.c:1199 +#: catalog/pg_shdepend.c:1200 #, c-format msgid "cannot drop objects owned by %s because they are required by the database system" msgstr "kann Objekte, die %s gehören, nicht löschen, weil sie vom Datenbanksystem benötigt werden" -#: catalog/pg_shdepend.c:1314 +#: catalog/pg_shdepend.c:1315 #, c-format msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "kann den Eigentümer von den Objekten, die %s gehören, nicht ändern, weil die Objekte vom Datenbanksystem benötigt werden" -#: catalog/pg_subscription.c:158 commands/subscriptioncmds.c:373 -#: commands/subscriptioncmds.c:481 commands/subscriptioncmds.c:651 +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 +#: commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 #, c-format msgid "subscription \"%s\" does not exist" msgstr "Subskription »%s« existiert nicht" -#: catalog/pg_type.c:136 catalog/pg_type.c:452 +#: catalog/pg_type.c:135 catalog/pg_type.c:459 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" -#: catalog/pg_type.c:251 +#: catalog/pg_type.c:241 #, c-format msgid "invalid type internal size %d" msgstr "ungültige interne Typgröße %d" -#: catalog/pg_type.c:267 catalog/pg_type.c:275 catalog/pg_type.c:283 -#: catalog/pg_type.c:292 +#: catalog/pg_type.c:257 catalog/pg_type.c:265 catalog/pg_type.c:273 +#: catalog/pg_type.c:282 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "Ausrichtung »%c« ist ungültig für Typen mit Wertübergabe mit Größe %d" -#: catalog/pg_type.c:299 +#: catalog/pg_type.c:289 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "interne Größe %d ist ungültig für Typen mit Wertübergabe" -#: catalog/pg_type.c:308 catalog/pg_type.c:314 +#: catalog/pg_type.c:298 catalog/pg_type.c:304 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "Ausrichtung »%c« ist ungültig für Typen variabler Länge" -#: catalog/pg_type.c:322 +#: catalog/pg_type.c:312 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "Typen mit fester Größe müssen Storage-Typ PLAIN haben" -#: catalog/pg_type.c:781 +#: catalog/pg_type.c:801 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "konnte keinen Arraytypnamen für Datentyp »%s« erzeugen" -#: catalog/toasting.c:105 commands/indexcmds.c:395 commands/tablecmds.c:4677 -#: commands/tablecmds.c:12627 +#: catalog/toasting.c:105 commands/indexcmds.c:443 commands/tablecmds.c:5016 +#: commands/tablecmds.c:13979 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "»%s« ist keine Tabelle oder materialisierte Sicht" @@ -5033,152 +5104,162 @@ msgstr "»%s« ist keine Tabelle oder materialisierte Sicht" msgid "shared tables cannot be toasted after initdb" msgstr "Cluster-globale Tabellen können nach initdb nicht mehr getoastet werden" -#: commands/aggregatecmds.c:157 +#: commands/aggregatecmds.c:166 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "nur Ordered-Set-Aggregatfunktionen können Hypothetical-Set-Aggregatfunktionen sein" -#: commands/aggregatecmds.c:182 +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "Attribut »%s« für Aggregatfunktion unbekannt" -#: commands/aggregatecmds.c:192 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" msgstr "»stype« für Aggregatfunktion muss angegeben werden" -#: commands/aggregatecmds.c:196 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" msgstr "»sfunc« für Aggregatfunktion muss angegeben werden" -#: commands/aggregatecmds.c:208 +#: commands/aggregatecmds.c:217 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "»msfunc« für Aggregatfunktion muss angegeben werden, wenn »mstype« angegeben ist" -#: commands/aggregatecmds.c:212 +#: commands/aggregatecmds.c:221 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "»minvfunc« für Aggregatfunktion muss angegeben werden, wenn »mstype« angegeben ist" -#: commands/aggregatecmds.c:219 +#: commands/aggregatecmds.c:228 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "»msfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" -#: commands/aggregatecmds.c:223 +#: commands/aggregatecmds.c:232 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "»minvfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" -#: commands/aggregatecmds.c:227 +#: commands/aggregatecmds.c:236 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "»mfinalfunc« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" -#: commands/aggregatecmds.c:231 +#: commands/aggregatecmds.c:240 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "»msspace« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" -#: commands/aggregatecmds.c:235 +#: commands/aggregatecmds.c:244 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "»minitcond« für Aggregatfunktion darf nicht angegeben werden, wenn »mstype« nicht angegeben ist" -#: commands/aggregatecmds.c:255 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" msgstr "Eingabetyp für Aggregatfunktion muss angegeben werden" -#: commands/aggregatecmds.c:285 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "Angabe »basetype« ist überflüssig bei Angabe des Eingabetyps der Aggregatfunktion" -#: commands/aggregatecmds.c:326 commands/aggregatecmds.c:367 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "Übergangsdatentyp von Aggregatfunktion kann nicht %s sein" -#: commands/aggregatecmds.c:338 +#: commands/aggregatecmds.c:356 #, c-format msgid "serialization functions may be specified only when the aggregate transition data type is %s" msgstr "Serialisierungsfunktionen dürfen nur angegeben werden, wenn der Übergangsdatentyp der Aggregatfunktion %s ist" -#: commands/aggregatecmds.c:348 +#: commands/aggregatecmds.c:366 #, c-format msgid "must specify both or neither of serialization and deserialization functions" msgstr "Serialisierungs- und Deserialisierungsfunktionen müssen zusammen angegeben werden" -#: commands/aggregatecmds.c:413 commands/functioncmds.c:564 +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "Parameter »parallel« muss SAFE, RESTRICTED oder UNSAFE sein" -#: commands/alter.c:83 commands/event_trigger.c:233 +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "Parameter »%s« muss READ_ONLY, SHAREABLE oder READ_WRITE sein" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format msgid "event trigger \"%s\" already exists" msgstr "Ereignistrigger »%s« existiert bereits" -#: commands/alter.c:86 commands/foreigncmds.c:595 +#: commands/alter.c:87 commands/foreigncmds.c:595 #, c-format msgid "foreign-data wrapper \"%s\" already exists" msgstr "Fremddaten-Wrapper »%s« existiert bereits" -#: commands/alter.c:89 commands/foreigncmds.c:886 +#: commands/alter.c:90 commands/foreigncmds.c:898 #, c-format msgid "server \"%s\" already exists" msgstr "Server »%s« existiert bereits" -#: commands/alter.c:92 commands/proclang.c:367 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "Sprache »%s« existiert bereits" -#: commands/alter.c:95 commands/publicationcmds.c:189 +#: commands/alter.c:96 commands/publicationcmds.c:176 #, c-format msgid "publication \"%s\" already exists" msgstr "Publikation »%s« existiert bereits" -#: commands/alter.c:98 commands/subscriptioncmds.c:256 +#: commands/alter.c:99 commands/subscriptioncmds.c:358 #, c-format msgid "subscription \"%s\" already exists" msgstr "Subskription »%s« existiert bereits" -#: commands/alter.c:121 +#: commands/alter.c:122 #, c-format msgid "conversion \"%s\" already exists in schema \"%s\"" msgstr "Konversion »%s« existiert bereits in Schema »%s«" -#: commands/alter.c:125 +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "Statistikobjekt »%s« existiert bereits in Schema »%s«" + +#: commands/alter.c:130 #, c-format msgid "text search parser \"%s\" already exists in schema \"%s\"" msgstr "Textsucheparser »%s« existiert bereits in Schema »%s«" -#: commands/alter.c:129 +#: commands/alter.c:134 #, c-format msgid "text search dictionary \"%s\" already exists in schema \"%s\"" msgstr "Textsuchewörterbuch »%s« existiert bereits in Schema »%s«" -#: commands/alter.c:133 +#: commands/alter.c:138 #, c-format msgid "text search template \"%s\" already exists in schema \"%s\"" msgstr "Textsuchevorlage »%s« existiert bereits in Schema »%s«" -#: commands/alter.c:137 +#: commands/alter.c:142 #, c-format msgid "text search configuration \"%s\" already exists in schema \"%s\"" msgstr "Textsuchekonfiguration »%s« existiert bereits in Schema »%s«" -#: commands/alter.c:211 +#: commands/alter.c:216 #, c-format msgid "must be superuser to rename %s" msgstr "nur Superuser können %s umbenennen" -#: commands/alter.c:670 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" msgstr "nur Superuser können Schema von %s setzen" @@ -5203,8 +5284,8 @@ msgstr "Zugriffsmethode »%s« existiert bereits" msgid "must be superuser to drop access methods" msgstr "nur Superuser können Zugriffsmethoden löschen" -#: commands/amcmds.c:174 commands/indexcmds.c:163 commands/indexcmds.c:502 -#: commands/opclasscmds.c:363 commands/opclasscmds.c:777 +#: commands/amcmds.c:174 commands/indexcmds.c:173 commands/indexcmds.c:583 +#: commands/opclasscmds.c:364 commands/opclasscmds.c:778 #, c-format msgid "access method \"%s\" does not exist" msgstr "Zugriffsmethode »%s« existiert nicht" @@ -5214,179 +5295,200 @@ msgstr "Zugriffsmethode »%s« existiert nicht" msgid "handler function is not specified" msgstr "keine Handler-Funktion angegeben" -#: commands/amcmds.c:262 commands/event_trigger.c:242 -#: commands/foreigncmds.c:487 commands/proclang.c:117 commands/proclang.c:289 -#: commands/trigger.c:531 parser/parse_clause.c:961 +#: commands/amcmds.c:262 commands/event_trigger.c:245 +#: commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 +#: commands/trigger.c:696 parser/parse_clause.c:990 #, c-format msgid "function %s must return type %s" msgstr "Function %s muss Rückgabetyp %s haben" -#: commands/analyze.c:145 +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" msgstr "überspringe Analyze von »%s« --- Sperre nicht verfügbar" -#: commands/analyze.c:162 +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "überspringe Analyze von »%s« --- Relation existiert nicht mehr" + +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" msgstr "überspringe »%s« --- nur Superuser kann sie analysieren" -#: commands/analyze.c:166 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" msgstr "überspringe »%s« --- nur Superuser oder Eigentümer der Datenbank kann sie analysieren" -#: commands/analyze.c:170 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" msgstr "überspringe »%s« --- nur Eigentümer der Tabelle oder der Datenbank kann sie analysieren" -#: commands/analyze.c:230 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "überspringe »%s« --- kann diese Fremdtabelle nicht analysieren" -#: commands/analyze.c:247 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "überspringe »%s« --- kann Nicht-Tabellen oder besondere Systemtabellen nicht analysieren" -#: commands/analyze.c:328 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "analysiere Vererbungsbaum von »%s.%s«" -#: commands/analyze.c:333 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "analysiere »%s.%s«" -#: commands/analyze.c:658 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "Spalte »%s« von Relation »%s« erscheint mehrmals" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "automatisches Analysieren von Tabelle »%s.%s.%s« Systembenutzung: %s" -#: commands/analyze.c:1212 +#: commands/analyze.c:1288 #, c-format msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" msgstr "»%s«: %d von %u Seiten gelesen, enthalten %.0f lebende Zeilen und %.0f tote Zeilen; %d Zeilen in Stichprobe, schätzungsweise %.0f Zeilen insgesamt" -#: commands/analyze.c:1292 +#: commands/analyze.c:1368 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" msgstr "überspringe Analysieren des Vererbungsbaums »%s.%s« --- dieser Vererbungsbaum enthält keine abgeleiteten Tabellen" -#: commands/analyze.c:1390 +#: commands/analyze.c:1466 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" msgstr "überspringe Analysieren des Vererbungsbaums »%s.%s« --- dieser Vererbungsbaum enthält keine analysierbaren abgeleiteten Tabellen" -#: commands/async.c:555 +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "Kanalname kann nicht leer sein" -#: commands/async.c:560 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "Kanalname zu lang" -#: commands/async.c:567 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "Payload-Zeichenkette zu lang" -#: commands/async.c:753 +#: commands/async.c:756 #, c-format msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die LISTEN, UNLISTEN oder NOTIFY ausgeführt hat" -#: commands/async.c:856 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "zu viele Benachrichtigungen in NOTIFY-Schlange" -#: commands/async.c:1486 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTIFY-Schlange ist %.0f%% voll" -#: commands/async.c:1488 +#: commands/async.c:1493 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "Der Serverprozess mit PID %d gehört zu denen mit den ältesten Transaktionen." -#: commands/async.c:1491 +#: commands/async.c:1496 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "Die NOTIFY-Schlange kann erst geleert werden, wenn dieser Prozess seine aktuelle Transaktion beendet." -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht clustern" -#: commands/cluster.c:159 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "eine partitionierte Tabelle kann nicht geclustert werden" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "es gibt keinen bereits geclusterten Index für Tabelle »%s«" -#: commands/cluster.c:173 commands/tablecmds.c:9858 commands/tablecmds.c:11721 +#: commands/cluster.c:181 commands/tablecmds.c:11136 commands/tablecmds.c:13041 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "Index »%s« für Tabelle »%s« existiert nicht" -#: commands/cluster.c:353 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "globaler Katalog kann nicht geclustert werden" -#: commands/cluster.c:368 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "temporäre Tabellen anderer Sitzungen können nicht gevacuumt werden" -#: commands/cluster.c:431 commands/tablecmds.c:11731 +#: commands/cluster.c:439 commands/tablecmds.c:13051 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "»%s« ist kein Index für Tabelle »%s«" -#: commands/cluster.c:439 +#: commands/cluster.c:447 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "kann nicht anhand des Index »%s« clustern, weil die Indexmethode Clustern nicht unterstützt" -#: commands/cluster.c:451 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "kann nicht anhand des partiellen Index »%s« clustern" -#: commands/cluster.c:465 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "kann nicht anhand des ungültigen Index »%s« clustern" -#: commands/cluster.c:918 +#: commands/cluster.c:497 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\"" +msgid "cannot mark index clustered in partitioned table" +msgstr "kann keinen Index für partitionierte Tabelle »%s« erzeugen" + +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "clustere »%s.%s« durch Index-Scan von »%s«" -#: commands/cluster.c:924 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "clustere »%s.%s« durch sequenziellen Scan und Sortieren" -#: commands/cluster.c:929 commands/vacuumlazy.c:486 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" -msgstr "vacuume »%s.%s«" +msgstr "Vacuum von »%s.%s«" -#: commands/cluster.c:1084 +#: commands/cluster.c:1106 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "»%s«: %.0f entfernbare, %.0f nicht entfernbare Zeilenversionen in %u Seiten gefunden" -#: commands/cluster.c:1088 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5395,66 +5497,92 @@ msgstr "" "%.0f tote Zeilenversionen können noch nicht entfernt werden.\n" "%s." -#: commands/collationcmds.c:79 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "Attribut »%s« für Sortierfolge unbekannt" -#: commands/collationcmds.c:125 +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "Sortierfolge »default« kann nicht kopiert werden" + +#: commands/collationcmds.c:172 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "unbekannter Sortierfolgen-Provider: %s" + +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "Parameter »lc_collate« muss angegeben werden" -#: commands/collationcmds.c:130 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "Parameter »lc_ctype« muss angegeben werden" -#: commands/collationcmds.c:170 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "Sortierfolge »%s« für Kodierung »%s« existiert bereits in Schema »%s«" -#: commands/collationcmds.c:181 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "Sortierfolge »%s« existiert bereits in Schema »%s«" -#: commands/collationcmds.c:243 +#: commands/collationcmds.c:304 +#, c-format +msgid "changing version from %s to %s" +msgstr "Version wird von %s in %s geändert" + +#: commands/collationcmds.c:319 +#, c-format +msgid "version has not changed" +msgstr "Version hat sich nicht geändert" + +#: commands/collationcmds.c:450 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "konnte Locale-Namen »%s« nicht in Sprach-Tag umwandeln: %s" + +#: commands/collationcmds.c:511 #, c-format msgid "must be superuser to import system collations" msgstr "nur Superuser können Systemsortierfolgen importieren" -#: commands/collationcmds.c:250 commands/copy.c:1827 commands/copy.c:3013 +#: commands/collationcmds.c:534 commands/copy.c:1844 commands/copy.c:3181 +#: libpq/be-secure-common.c:80 #, c-format msgid "could not execute command \"%s\": %m" msgstr "konnte Befehl »%s« nicht ausführen: %m" -#: commands/collationcmds.c:343 +#: commands/collationcmds.c:665 #, c-format msgid "no usable system locales were found" msgstr "keine brauchbaren System-Locales gefunden" -#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:988 -#: commands/dbcommands.c:1092 commands/dbcommands.c:1282 -#: commands/dbcommands.c:1505 commands/dbcommands.c:1619 -#: commands/dbcommands.c:2035 utils/init/postinit.c:841 -#: utils/init/postinit.c:943 utils/init/postinit.c:960 +#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 +#: commands/dbcommands.c:1100 commands/dbcommands.c:1290 +#: commands/dbcommands.c:1513 commands/dbcommands.c:1627 +#: commands/dbcommands.c:2043 utils/init/postinit.c:853 +#: utils/init/postinit.c:958 utils/init/postinit.c:975 #, c-format msgid "database \"%s\" does not exist" msgstr "Datenbank »%s« existiert nicht" -#: commands/comment.c:100 commands/seclabel.c:117 parser/parse_utilcmd.c:824 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, zusammengesetzter Typ noch Fremdtabelle" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2715 +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "Funktion »%s« wurde nicht von Triggermanager aufgerufen" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2724 +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "Funktion »%s« muss AFTER ROW ausgelöst werden" @@ -5464,209 +5592,214 @@ msgstr "Funktion »%s« muss AFTER ROW ausgelöst werden" msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "Funktion »%s« muss von INSERT oder UPDATE ausgelöst werden" -#: commands/conversioncmds.c:66 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "Quellkodierung »%s« existiert nicht" -#: commands/conversioncmds.c:73 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "Zielkodierung »%s« existiert nicht" -#: commands/conversioncmds.c:87 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "Kodierungskonversionsfunktion %s muss Typ %s zurückgeben" -#: commands/copy.c:369 commands/copy.c:403 +#: commands/copy.c:374 commands/copy.c:408 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY mit STDOUT oder STDIN wird nicht unterstützt" -#: commands/copy.c:503 +#: commands/copy.c:508 #, c-format msgid "could not write to COPY program: %m" msgstr "konnte nicht zum COPY-Programm schreiben: %m" -#: commands/copy.c:508 +#: commands/copy.c:513 #, c-format msgid "could not write to COPY file: %m" msgstr "konnte nicht in COPY-Datei schreiben: %m" -#: commands/copy.c:521 +#: commands/copy.c:526 #, c-format msgid "connection lost during COPY to stdout" msgstr "Verbindung während COPY nach STDOUT verloren" -#: commands/copy.c:562 +#: commands/copy.c:570 #, c-format msgid "could not read from COPY file: %m" msgstr "konnte nicht aus COPY-Datei lesen: %m" -#: commands/copy.c:578 commands/copy.c:599 commands/copy.c:603 -#: tcop/postgres.c:341 tcop/postgres.c:377 tcop/postgres.c:404 +#: commands/copy.c:588 commands/copy.c:609 commands/copy.c:613 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "unerwartetes EOF auf Client-Verbindung mit einer offenen Transaktion" -#: commands/copy.c:616 +#: commands/copy.c:626 #, c-format msgid "COPY from stdin failed: %s" msgstr "COPY FROM STDIN fehlgeschlagen: %s" -#: commands/copy.c:632 +#: commands/copy.c:642 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "unerwarteter Messagetyp 0x%02X während COPY FROM STDIN" -#: commands/copy.c:791 +#: commands/copy.c:808 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "nur Superuser können COPY mit externen Programmen verwenden" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "nur Superuser oder Mitglieder von pg_execute_server_program können COPY mit externen Programmen verwenden" -#: commands/copy.c:792 commands/copy.c:798 +#: commands/copy.c:809 commands/copy.c:818 commands/copy.c:825 #, c-format msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "Jeder kann COPY mit STDOUT oder STDIN verwenden. Der Befehl \\copy in psql funktioniert auch für jeden." -#: commands/copy.c:797 +#: commands/copy.c:817 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "nur Superuser oder Mitglieder von pg_read_server_files können mit COPY aus einer Datei lesen" + +#: commands/copy.c:824 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "nur Superuser können COPY mit Dateien verwenden" +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "nur Superuser oder Mitglieder von pg_write_server_files können mit COPY in eine Datei schreiben" -#: commands/copy.c:864 +#: commands/copy.c:887 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "COPY FROM wird nicht unterstützt mit Sicherheit auf Zeilenebene" -#: commands/copy.c:865 +#: commands/copy.c:888 #, c-format msgid "Use INSERT statements instead." msgstr "Verwenden Sie stattdessen INSERT-Anweisungen." -#: commands/copy.c:1051 +#: commands/copy.c:1075 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "COPY-Format »%s« nicht erkannt" -#: commands/copy.c:1131 commands/copy.c:1147 commands/copy.c:1162 -#: commands/copy.c:1184 +#: commands/copy.c:1155 commands/copy.c:1171 commands/copy.c:1186 +#: commands/copy.c:1208 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "Argument von Option »%s« muss eine Liste aus Spaltennamen sein" -#: commands/copy.c:1199 +#: commands/copy.c:1223 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "Argument von Option »%s« muss ein gültiger Kodierungsname sein" -#: commands/copy.c:1206 commands/dbcommands.c:242 commands/dbcommands.c:1453 +#: commands/copy.c:1230 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" msgstr "Option »%s« nicht erkannt" -#: commands/copy.c:1218 +#: commands/copy.c:1242 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "DELIMITER kann nicht im BINARY-Modus angegeben werden" -#: commands/copy.c:1223 +#: commands/copy.c:1247 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "NULL kann nicht im BINARY-Modus angegeben werden" -#: commands/copy.c:1245 +#: commands/copy.c:1269 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "DELIMITER für COPY muss ein einzelnes Ein-Byte-Zeichen sein" -#: commands/copy.c:1252 +#: commands/copy.c:1276 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "COPY-Trennzeichen kann nicht Newline oder Carriage Return sein" -#: commands/copy.c:1258 +#: commands/copy.c:1282 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "COPY NULL-Darstellung kann nicht Newline oder Carriage Return enthalten" -#: commands/copy.c:1275 +#: commands/copy.c:1299 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "DELIMITER für COPY darf nicht »%s« sein" -#: commands/copy.c:1281 +#: commands/copy.c:1305 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "COPY HEADER ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1287 +#: commands/copy.c:1311 #, c-format msgid "COPY quote available only in CSV mode" msgstr "Quote-Zeichen für COPY ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1292 +#: commands/copy.c:1316 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "Quote-Zeichen für COPY muss ein einzelnes Ein-Byte-Zeichen sein" -#: commands/copy.c:1297 +#: commands/copy.c:1321 #, c-format msgid "COPY delimiter and quote must be different" msgstr "DELIMITER und QUOTE für COPY müssen verschieden sein" -#: commands/copy.c:1303 +#: commands/copy.c:1327 #, c-format msgid "COPY escape available only in CSV mode" msgstr "Escape-Zeichen für COPY ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1308 +#: commands/copy.c:1332 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "Escape-Zeichen für COPY muss ein einzelnes Ein-Byte-Zeichen sein" -#: commands/copy.c:1314 +#: commands/copy.c:1338 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "FORCE_QUOTE für COPY ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1318 +#: commands/copy.c:1342 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "FORCE_QUOTE ist nur bei COPY TO verfügbar" -#: commands/copy.c:1324 +#: commands/copy.c:1348 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "FORCE_NOT_NULL für COPY ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1328 +#: commands/copy.c:1352 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "FORCE_NOT_NULL ist nur bei COPY FROM verfügbar" -#: commands/copy.c:1334 +#: commands/copy.c:1358 #, c-format msgid "COPY force null available only in CSV mode" msgstr "FORCE_NULL für COPY ist nur im CSV-Modus verfügbar" -#: commands/copy.c:1339 +#: commands/copy.c:1363 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "FORCE_NULL ist nur bei COPY FROM verfügbar" -#: commands/copy.c:1345 +#: commands/copy.c:1369 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "Trennzeichen für COPY darf nicht in der NULL-Darstellung erscheinen" -#: commands/copy.c:1352 +#: commands/copy.c:1376 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "CSV-Quote-Zeichen darf nicht in der NULL-Darstellung erscheinen" -#: commands/copy.c:1413 +#: commands/copy.c:1437 #, c-format msgid "table \"%s\" does not have OIDs" msgstr "Tabelle »%s« hat keine OIDs" @@ -5676,349 +5809,342 @@ msgstr "Tabelle »%s« hat keine OIDs" msgid "COPY (query) WITH OIDS is not supported" msgstr "COPY (Anfrage) WITH OIDS wird nicht unterstützt" -#: commands/copy.c:1474 +#: commands/copy.c:1475 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "DO INSTEAD NOTHING-Regeln werden für COPY nicht unterstützt" -#: commands/copy.c:1488 +#: commands/copy.c:1489 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "Do INSTEAD-Regeln mit Bedingung werden für COPY nicht unterstützt" -#: commands/copy.c:1492 +#: commands/copy.c:1493 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "DO ALSO-Regeln werden für COPY nicht unterstützt" -#: commands/copy.c:1497 +#: commands/copy.c:1498 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "DO INSTEAD-Regeln mit mehreren Anweisungen werden für COPY nicht unterstützt" -#: commands/copy.c:1507 +#: commands/copy.c:1508 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) wird nicht unterstützt" -#: commands/copy.c:1524 +#: commands/copy.c:1525 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "COPY-Anfrage muss eine RETURNING-Klausel haben" -#: commands/copy.c:1552 +#: commands/copy.c:1553 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "die von der COPY-Anweisung verwendete Relation hat sich geändert" -#: commands/copy.c:1610 +#: commands/copy.c:1612 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "FORCE_QUOTE-Spalte »%s« wird von COPY nicht verwendet" -#: commands/copy.c:1632 +#: commands/copy.c:1635 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "Spalte »%s« mit FORCE_NOT_NULL wird von COPY nicht verwendet" -#: commands/copy.c:1654 +#: commands/copy.c:1658 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "Spalte »%s« mit FORCE_NULL wird von COPY nicht verwendet" -#: commands/copy.c:1719 +#: commands/copy.c:1724 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "konnte Pipe zu externem Programm nicht schließen: %m" -#: commands/copy.c:1723 +#: commands/copy.c:1739 #, c-format msgid "program \"%s\" failed" msgstr "Programm »%s« fehlgeschlagen" -#: commands/copy.c:1773 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from view \"%s\"" msgstr "kann nicht aus Sicht »%s« kopieren" -#: commands/copy.c:1775 commands/copy.c:1781 commands/copy.c:1787 -#: commands/copy.c:1798 +#: commands/copy.c:1792 commands/copy.c:1798 commands/copy.c:1804 +#: commands/copy.c:1815 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Versuchen Sie die Variante COPY (SELECT ...) TO." -#: commands/copy.c:1779 +#: commands/copy.c:1796 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "kann nicht aus materialisierter Sicht »%s« kopieren" -#: commands/copy.c:1785 +#: commands/copy.c:1802 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "kann nicht aus Fremdtabelle »%s« kopieren" -#: commands/copy.c:1791 +#: commands/copy.c:1808 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "kann nicht aus Sequenz »%s« kopieren" -#: commands/copy.c:1796 +#: commands/copy.c:1813 #, c-format msgid "cannot copy from partitioned table \"%s\"" msgstr "kann nicht aus partitionierter Tabelle »%s« kopieren" -#: commands/copy.c:1802 +#: commands/copy.c:1819 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "kann nicht aus Relation »%s«, die keine Tabelle ist, kopieren" -#: commands/copy.c:1842 +#: commands/copy.c:1859 #, c-format msgid "relative path not allowed for COPY to file" msgstr "relativer Pfad bei COPY in Datei nicht erlaubt" -#: commands/copy.c:1854 +#: commands/copy.c:1880 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "konnte Datei »%s« nicht zum Schreiben öffnen: %m" -#: commands/copy.c:1857 +#: commands/copy.c:1883 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." -msgstr "" +msgstr "Mit COPY TO schreibt der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." -#: commands/copy.c:1870 commands/copy.c:3044 +#: commands/copy.c:1896 commands/copy.c:3212 #, c-format msgid "\"%s\" is a directory" msgstr "»%s« ist ein Verzeichnis" -#: commands/copy.c:2193 +#: commands/copy.c:2222 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, Zeile %d, Spalte %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, Zeile %s, Spalte %s" -#: commands/copy.c:2197 commands/copy.c:2244 +#: commands/copy.c:2226 commands/copy.c:2273 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, Zeile %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, Zeile %s" -#: commands/copy.c:2208 +#: commands/copy.c:2237 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, Zeile %d, Spalte %s: »%s«" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, Zeile %s, Spalte %s: »%s«" -#: commands/copy.c:2216 +#: commands/copy.c:2245 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, Zeile %d, Spalte %s: NULL Eingabe" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, Zeile %s, Spalte %s: NULL Eingabe" -#: commands/copy.c:2238 +#: commands/copy.c:2267 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, Zeile %d: »%s«" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, Zeile %s: »%s«" -#: commands/copy.c:2332 +#: commands/copy.c:2363 #, c-format msgid "cannot copy to view \"%s\"" msgstr "kann nicht in Sicht »%s« kopieren" -#: commands/copy.c:2334 -#, fuzzy, c-format -#| msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +#: commands/copy.c:2365 +#, c-format msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." -msgstr "Um Einfügen in die Sicht zu ermöglichen, richten Sie einen INSTEAD OF INSERT Trigger oder eine ON INSERT DO INSTEAD Regel ohne Bedingung ein." +msgstr "Um Kopieren in eine Sicht zu ermöglichen, richten Sie einen INSTEAD OF INSERT Trigger ein." -#: commands/copy.c:2338 +#: commands/copy.c:2369 #, c-format msgid "cannot copy to materialized view \"%s\"" msgstr "kann nicht in materialisierte Sicht »%s« kopieren" -#: commands/copy.c:2343 -#, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "kann nicht in Fremdtabelle »%s« kopieren" - -#: commands/copy.c:2348 +#: commands/copy.c:2374 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "kann nicht in Sequenz »%s« kopieren" -#: commands/copy.c:2353 +#: commands/copy.c:2379 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "kann nicht in Relation »%s« kopieren, die keine Tabelle ist" -#: commands/copy.c:2416 +#: commands/copy.c:2471 +#, c-format +msgid "cannot perform FREEZE on a partitioned table" +msgstr "FREEZE kann nicht in einer partitionierten Tabelle durchgeführt werden" + +#: commands/copy.c:2486 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" msgstr "FREEZE kann nicht durchgeführt werden wegen vorheriger Aktivität in dieser Transaktion" -#: commands/copy.c:2422 +#: commands/copy.c:2492 #, c-format msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" msgstr "FREEZE kann nicht durchgeführt werden, weil die Tabelle nicht in der aktuellen Transaktion erzeugt oder geleert wurde" -#: commands/copy.c:2587 executor/nodeModifyTable.c:311 -#, fuzzy, c-format -#| msgid "cannot insert into foreign table \"%s\"" -msgid "cannot route inserted tuples to a foreign table" -msgstr "kann nicht in Fremdtabelle »%s« einfügen" - -#: commands/copy.c:3031 +#: commands/copy.c:3199 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." -msgstr "" +msgstr "Mit COPY FROM liest der PostgreSQL-Serverprozess eine Datei. Möglicherweise möchten Sie Funktionalität auf Client-Seite verwenden, wie zum Beispiel \\copy in psql." -#: commands/copy.c:3064 +#: commands/copy.c:3232 #, c-format msgid "COPY file signature not recognized" msgstr "COPY-Datei-Signatur nicht erkannt" -#: commands/copy.c:3069 +#: commands/copy.c:3237 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "ungültiger COPY-Dateikopf (Flags fehlen)" -#: commands/copy.c:3075 +#: commands/copy.c:3243 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "unbekannte kritische Flags im COPY-Dateikopf" -#: commands/copy.c:3081 +#: commands/copy.c:3249 #, c-format msgid "invalid COPY file header (missing length)" msgstr "ungültiger COPY-Dateikopf (Länge fehlt)" -#: commands/copy.c:3088 +#: commands/copy.c:3256 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "ungültiger COPY-Dateikopf (falsche Länge)" -#: commands/copy.c:3221 commands/copy.c:3928 commands/copy.c:4158 +#: commands/copy.c:3387 commands/copy.c:4096 commands/copy.c:4326 #, c-format msgid "extra data after last expected column" msgstr "zusätzliche Daten nach letzter erwarteter Spalte" -#: commands/copy.c:3231 +#: commands/copy.c:3397 #, c-format msgid "missing data for OID column" msgstr "fehlende Daten für OID-Spalte" -#: commands/copy.c:3237 +#: commands/copy.c:3403 #, c-format msgid "null OID in COPY data" msgstr "OID ist NULL in COPY-Daten" -#: commands/copy.c:3247 commands/copy.c:3370 +#: commands/copy.c:3413 commands/copy.c:3537 #, c-format msgid "invalid OID in COPY data" msgstr "ungültige OID in COPY-Daten" -#: commands/copy.c:3262 +#: commands/copy.c:3429 #, c-format msgid "missing data for column \"%s\"" msgstr "fehlende Daten für Spalte »%s«" -#: commands/copy.c:3345 +#: commands/copy.c:3512 #, c-format msgid "received copy data after EOF marker" msgstr "COPY-Daten nach EOF-Markierung empfangen" -#: commands/copy.c:3352 +#: commands/copy.c:3519 #, c-format msgid "row field count is %d, expected %d" msgstr "Feldanzahl in Zeile ist %d, erwartet wurden %d" -#: commands/copy.c:3692 commands/copy.c:3709 +#: commands/copy.c:3860 commands/copy.c:3877 #, c-format msgid "literal carriage return found in data" msgstr "Carriage-Return-Zeichen in Daten gefunden" -#: commands/copy.c:3693 commands/copy.c:3710 +#: commands/copy.c:3861 commands/copy.c:3878 #, c-format msgid "unquoted carriage return found in data" msgstr "ungequotetes Carriage-Return-Zeichen in Daten gefunden" -#: commands/copy.c:3695 commands/copy.c:3712 +#: commands/copy.c:3863 commands/copy.c:3880 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "Verwenden Sie »\\r«, um ein Carriage-Return-Zeichen darzustellen." -#: commands/copy.c:3696 commands/copy.c:3713 +#: commands/copy.c:3864 commands/copy.c:3881 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "Verwenden Sie ein gequotetes CSV-Feld, um ein Carriage-Return-Zeichen darzustellen." -#: commands/copy.c:3725 +#: commands/copy.c:3893 #, c-format msgid "literal newline found in data" msgstr "Newline-Zeichen in Daten gefunden" -#: commands/copy.c:3726 +#: commands/copy.c:3894 #, c-format msgid "unquoted newline found in data" msgstr "ungequotetes Newline-Zeichen in Daten gefunden" -#: commands/copy.c:3728 +#: commands/copy.c:3896 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "Verwenden Sie »\\n«, um ein Newline-Zeichen darzustellen." -#: commands/copy.c:3729 +#: commands/copy.c:3897 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "Verwenden Sie ein gequotetes CSV-Feld, um ein Newline-Zeichen darzustellen." -#: commands/copy.c:3775 commands/copy.c:3811 +#: commands/copy.c:3943 commands/copy.c:3979 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "COPY-Ende-Markierung stimmt nicht mit vorherigem Newline-Stil überein" -#: commands/copy.c:3784 commands/copy.c:3800 +#: commands/copy.c:3952 commands/copy.c:3968 #, c-format msgid "end-of-copy marker corrupt" msgstr "COPY-Ende-Markierung verfälscht" -#: commands/copy.c:4242 +#: commands/copy.c:4410 #, c-format msgid "unterminated CSV quoted field" msgstr "Quotes in CSV-Feld nicht abgeschlossen" -#: commands/copy.c:4319 commands/copy.c:4338 +#: commands/copy.c:4487 commands/copy.c:4506 #, c-format msgid "unexpected EOF in COPY data" msgstr "unerwartetes EOF in COPY-Daten" -#: commands/copy.c:4328 +#: commands/copy.c:4496 #, c-format msgid "invalid field size" msgstr "ungültige Feldgröße" -#: commands/copy.c:4351 +#: commands/copy.c:4519 #, c-format msgid "incorrect binary data format" msgstr "falsches Binärdatenformat" -#: commands/copy.c:4662 commands/indexcmds.c:1062 commands/tablecmds.c:1655 -#: commands/tablecmds.c:2150 commands/tablecmds.c:2573 -#: parser/parse_relation.c:3111 parser/parse_relation.c:3131 -#: utils/adt/tsvector_op.c:2561 +#: commands/copy.c:4831 commands/indexcmds.c:1473 commands/statscmds.c:206 +#: commands/tablecmds.c:1910 commands/tablecmds.c:2467 +#: commands/tablecmds.c:2848 parser/parse_relation.c:3288 +#: parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" msgstr "Spalte »%s« existiert nicht" -#: commands/copy.c:4669 commands/tablecmds.c:1681 commands/trigger.c:741 -#: parser/parse_target.c:1017 parser/parse_target.c:1028 +#: commands/copy.c:4838 commands/tablecmds.c:1937 commands/trigger.c:913 +#: parser/parse_target.c:1046 parser/parse_target.c:1057 #, c-format msgid "column \"%s\" specified more than once" msgstr "Spalte »%s« mehrmals angegeben" -#: commands/createas.c:213 commands/createas.c:508 +#: commands/createas.c:213 commands/createas.c:509 #, c-format msgid "too many column names were specified" msgstr "zu viele Spaltennamen wurden angegeben" -#: commands/createas.c:549 +#: commands/createas.c:550 #, c-format msgid "policies not yet implemented for this command" msgstr "Policys sind für diesen Befehl noch nicht implementiert" @@ -6043,8 +6169,8 @@ msgstr "%d ist kein gültiger Kodierungscode" msgid "%s is not a valid encoding name" msgstr "%s ist kein gültiger Kodierungsname" -#: commands/dbcommands.c:292 commands/dbcommands.c:1486 commands/user.c:289 -#: commands/user.c:665 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 +#: commands/user.c:664 #, c-format msgid "invalid connection limit: %d" msgstr "ungültige Verbindungshöchstgrenze: %d" @@ -6104,7 +6230,7 @@ msgstr "neues LC_CTYPE (%s) ist inkompatibel mit dem LC_CTYPE der Template-Daten msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." msgstr "Verwenden Sie das gleiche LC_CTYPE wie die Template-Datenbank oder verwenden Sie template0 als Template." -#: commands/dbcommands.c:432 commands/dbcommands.c:1138 +#: commands/dbcommands.c:432 commands/dbcommands.c:1146 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "pg_global kann nicht als Standard-Tablespace verwendet werden" @@ -6119,7 +6245,7 @@ msgstr "kann neuen Standard-Tablespace »%s« nicht setzen" msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." msgstr "Es gibt einen Konflikt, weil Datenbank »%s« schon einige Tabellen in diesem Tablespace hat." -#: commands/dbcommands.c:480 commands/dbcommands.c:1008 +#: commands/dbcommands.c:480 commands/dbcommands.c:1016 #, c-format msgid "database \"%s\" already exists" msgstr "Datenbank »%s« existiert bereits" @@ -6159,96 +6285,96 @@ msgstr "Template-Datenbank kann nicht gelöscht werden" msgid "cannot drop the currently open database" msgstr "kann aktuell geöffnete Datenbank nicht löschen" -#: commands/dbcommands.c:855 +#: commands/dbcommands.c:858 #, c-format -msgid "database \"%s\" is used by a logical replication slot" -msgstr "Datenbank »%s« wird von einem logischen Replikations-Slot verwendet" +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "Datenbank »%s« wird von einem aktiven logischen Replikations-Slot verwendet" -#: commands/dbcommands.c:857 +#: commands/dbcommands.c:860 #, c-format -msgid "There is %d slot, %d of them active." -msgid_plural "There are %d slots, %d of them active." -msgstr[0] "%d Slot ist vorhanden, %d davon aktiv." -msgstr[1] "%d Slots sind vorhanden, %d davon aktiv." +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d Slot ist vorhanden." +msgstr[1] "%d Slots sind vorhanden." -#: commands/dbcommands.c:871 commands/dbcommands.c:1030 -#: commands/dbcommands.c:1160 +#: commands/dbcommands.c:874 commands/dbcommands.c:1038 +#: commands/dbcommands.c:1168 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "auf Datenbank »%s« wird von anderen Benutzern zugegriffen" -#: commands/dbcommands.c:884 +#: commands/dbcommands.c:887 #, c-format msgid "database \"%s\" is being used by logical replication subscription" msgstr "Datenbank »%s« wird von einer Subskription für logische Replikation verwendet" -#: commands/dbcommands.c:886 +#: commands/dbcommands.c:889 #, c-format msgid "There is %d subscription." msgid_plural "There are %d subscriptions." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d Subskription ist vorhanden." +msgstr[1] "%d Subskriptionen sind vorhanden." -#: commands/dbcommands.c:999 +#: commands/dbcommands.c:1007 #, c-format msgid "permission denied to rename database" msgstr "keine Berechtigung, um Datenbank umzubenennen" -#: commands/dbcommands.c:1019 +#: commands/dbcommands.c:1027 #, c-format msgid "current database cannot be renamed" msgstr "aktuelle Datenbank kann nicht umbenannt werden" -#: commands/dbcommands.c:1116 +#: commands/dbcommands.c:1124 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "kann den Tablespace der aktuell geöffneten Datenbank nicht ändern" -#: commands/dbcommands.c:1219 +#: commands/dbcommands.c:1227 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" msgstr "einige Relationen von Datenbank »%s« ist bereits in Tablespace »%s«" -#: commands/dbcommands.c:1221 +#: commands/dbcommands.c:1229 #, c-format msgid "You must move them back to the database's default tablespace before using this command." msgstr "Sie müssen sie zurück in den Standard-Tablespace der Datenbank verschieben, bevor Sie diesen Befehl verwenden können." -#: commands/dbcommands.c:1347 commands/dbcommands.c:1892 -#: commands/dbcommands.c:2096 commands/dbcommands.c:2144 -#: commands/tablespace.c:604 +#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 +#: commands/dbcommands.c:2104 commands/dbcommands.c:2159 +#: commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "einige nutzlose Dateien wurde möglicherweise im alten Datenbankverzeichnis »%s« zurückgelassen" -#: commands/dbcommands.c:1467 +#: commands/dbcommands.c:1475 #, c-format msgid "option \"%s\" cannot be specified with other options" msgstr "Option »%s« kann nicht mit anderen Optionen angegeben werden" -#: commands/dbcommands.c:1522 +#: commands/dbcommands.c:1530 #, c-format msgid "cannot disallow connections for current database" msgstr "Verbindungen mit der aktuellen Datenbank können nicht verboten werden" -#: commands/dbcommands.c:1659 +#: commands/dbcommands.c:1667 #, c-format msgid "permission denied to change owner of database" msgstr "keine Berechtigung, um Eigentümer der Datenbank zu ändern" -#: commands/dbcommands.c:1979 +#: commands/dbcommands.c:1987 #, c-format msgid "There are %d other session(s) and %d prepared transaction(s) using the database." msgstr "%d andere Sitzung(en) und %d vorbereitete Transaktion(en) verwenden die Datenbank." -#: commands/dbcommands.c:1982 +#: commands/dbcommands.c:1990 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "%d andere Sitzung verwendet die Datenbank." msgstr[1] "%d andere Sitzungen verwenden die Datenbank." -#: commands/dbcommands.c:1987 +#: commands/dbcommands.c:1995 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." @@ -6292,30 +6418,30 @@ msgstr "Argument von %s muss ein Typname sein" msgid "invalid argument for %s: \"%s\"" msgstr "ungültiges Argument für %s: »%s«" -#: commands/dropcmds.c:104 commands/functioncmds.c:1200 -#: utils/adt/ruleutils.c:2284 +#: commands/dropcmds.c:99 commands/functioncmds.c:1212 +#: utils/adt/ruleutils.c:2564 #, c-format msgid "\"%s\" is an aggregate function" msgstr "»%s« ist eine Aggregatfunktion" -#: commands/dropcmds.c:106 +#: commands/dropcmds.c:101 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Verwenden Sie DROP AGGREGATE, um Aggregatfunktionen zu löschen." -#: commands/dropcmds.c:157 commands/sequence.c:430 commands/tablecmds.c:2657 -#: commands/tablecmds.c:2808 commands/tablecmds.c:2851 -#: commands/tablecmds.c:12104 tcop/utility.c:1159 +#: commands/dropcmds.c:157 commands/sequence.c:440 commands/tablecmds.c:2932 +#: commands/tablecmds.c:3090 commands/tablecmds.c:3133 +#: commands/tablecmds.c:13424 tcop/utility.c:1163 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "Relation »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:896 +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1022 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "Schema »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:252 +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "Typ »%s« existiert nicht, wird übersprungen" @@ -6337,167 +6463,182 @@ msgstr "Konversion »%s« existiert nicht, wird übersprungen" #: commands/dropcmds.c:292 #, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "Statistikobjekt »%s« existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:299 +#, c-format msgid "text search parser \"%s\" does not exist, skipping" msgstr "Textsucheparser »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:299 +#: commands/dropcmds.c:306 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" msgstr "Textsuchewörterbuch »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:306 +#: commands/dropcmds.c:313 #, c-format msgid "text search template \"%s\" does not exist, skipping" msgstr "Textsuchevorlage »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:313 +#: commands/dropcmds.c:320 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" msgstr "Textsuchekonfiguration »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:318 +#: commands/dropcmds.c:325 #, c-format msgid "extension \"%s\" does not exist, skipping" msgstr "Erweiterung »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:327 +#: commands/dropcmds.c:335 #, c-format msgid "function %s(%s) does not exist, skipping" msgstr "Funktion %s(%s) existiert nicht, wird übersprungen" -#: commands/dropcmds.c:339 +#: commands/dropcmds.c:348 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "Prozedur %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:361 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "Routine %s(%s) existiert nicht, wird übersprungen" + +#: commands/dropcmds.c:374 #, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "Aggregatfunktion %s(%s) existiert nicht, wird übersprungen" -#: commands/dropcmds.c:351 +#: commands/dropcmds.c:387 #, c-format msgid "operator %s does not exist, skipping" msgstr "Operator %s existiert nicht, wird übersprungen" -#: commands/dropcmds.c:357 +#: commands/dropcmds.c:393 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "Sprache »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:366 +#: commands/dropcmds.c:402 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "Typumwandlung von Typ %s in Typ %s existiert nicht, wird übersprungen" -#: commands/dropcmds.c:375 +#: commands/dropcmds.c:411 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "Transformation für Typ %s Sprache »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:383 +#: commands/dropcmds.c:419 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr "Trigger »%s« für Relation »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:392 +#: commands/dropcmds.c:428 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr "Policy »%s« für Relation »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:399 +#: commands/dropcmds.c:435 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "Ereignistrigger »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:405 +#: commands/dropcmds.c:441 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr "Regel »%s« für Relation »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:412 +#: commands/dropcmds.c:448 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "Fremddaten-Wrapper »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:416 +#: commands/dropcmds.c:452 #, c-format msgid "server \"%s\" does not exist, skipping" msgstr "Server »%s« existiert nicht, wird übersprungen" -#: commands/dropcmds.c:425 +#: commands/dropcmds.c:461 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" msgstr "Operatorklasse »%s« existiert nicht für Zugriffsmethode »%s«, wird übersprungen" -#: commands/dropcmds.c:437 +#: commands/dropcmds.c:473 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" msgstr "Operatorfamilie »%s« existiert nicht für Zugriffsmethode »%s«, wird übersprungen" -#: commands/dropcmds.c:444 +#: commands/dropcmds.c:480 #, c-format msgid "publication \"%s\" does not exist, skipping" msgstr "Publikation »%s« existiert nicht, wird übersprungen" -#: commands/event_trigger.c:184 +#: commands/event_trigger.c:187 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "keine Berechtigung, um Ereignistrigger »%s« zu erzeugen" -#: commands/event_trigger.c:186 +#: commands/event_trigger.c:189 #, c-format msgid "Must be superuser to create an event trigger." msgstr "Nur Superuser können Ereignistrigger anlegen." -#: commands/event_trigger.c:195 +#: commands/event_trigger.c:198 #, c-format msgid "unrecognized event name \"%s\"" msgstr "unbekannter Ereignisname »%s«" -#: commands/event_trigger.c:212 +#: commands/event_trigger.c:215 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "unbekannte Filtervariable »%s«" -#: commands/event_trigger.c:267 +#: commands/event_trigger.c:270 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "Filterwert »%s« nicht erkannt für Filtervariable »%s«" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:273 commands/event_trigger.c:343 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format msgid "event triggers are not supported for %s" msgstr "Ereignistrigger für %s werden nicht unterstützt" -#: commands/event_trigger.c:366 +#: commands/event_trigger.c:369 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "Filtervariable »%s« mehrmals angegeben" -#: commands/event_trigger.c:513 commands/event_trigger.c:556 -#: commands/event_trigger.c:648 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 +#: commands/event_trigger.c:651 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "Ereignistrigger »%s« existiert nicht" -#: commands/event_trigger.c:617 +#: commands/event_trigger.c:620 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "keine Berechtigung, um Eigentümer des Ereignistriggers »%s« zu ändern" -#: commands/event_trigger.c:619 +#: commands/event_trigger.c:622 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "Der Eigentümer eines Ereignistriggers muss ein Superuser sein." -#: commands/event_trigger.c:1443 +#: commands/event_trigger.c:1457 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s kann nur in einer sql_drop-Ereignistriggerfunktion aufgerufen werden" -#: commands/event_trigger.c:1563 commands/event_trigger.c:1584 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s kann nur in einer table_rewrite-Ereignistriggerfunktion aufgerufen werden" -#: commands/event_trigger.c:1994 +#: commands/event_trigger.c:2009 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s kann nur in einer Ereignistriggerfunktion aufgerufen werden" @@ -6522,235 +6663,234 @@ msgstr "EXPLAIN-Option BUFFERS erfordert ANALYZE" msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "EXPLAIN-Option TIMING erfordert ANALYZE" -#: commands/extension.c:167 commands/extension.c:2900 +#: commands/extension.c:168 commands/extension.c:2914 #, c-format msgid "extension \"%s\" does not exist" msgstr "Erweiterung »%s« existiert nicht" -#: commands/extension.c:266 commands/extension.c:275 commands/extension.c:287 -#: commands/extension.c:297 +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 +#: commands/extension.c:298 #, c-format msgid "invalid extension name: \"%s\"" msgstr "ungültiger Erweiterungsname: »%s«" -#: commands/extension.c:267 +#: commands/extension.c:268 #, c-format msgid "Extension names must not be empty." msgstr "Erweiterungsnamen dürfen nicht leer sein." -#: commands/extension.c:276 +#: commands/extension.c:277 #, c-format msgid "Extension names must not contain \"--\"." msgstr "Erweiterungsnamen dürfen nicht »--« enthalten." -#: commands/extension.c:288 +#: commands/extension.c:289 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "Erweiterungsnamen dürfen nicht mit »-« anfangen oder aufhören." -#: commands/extension.c:298 +#: commands/extension.c:299 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "Erweiterungsnamen dürfen keine Verzeichnistrennzeichen enthalten." -#: commands/extension.c:313 commands/extension.c:322 commands/extension.c:331 -#: commands/extension.c:341 +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 +#: commands/extension.c:342 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "ungültiger Erweiterungsversionsname: »%s«" -#: commands/extension.c:314 +#: commands/extension.c:315 #, c-format msgid "Version names must not be empty." msgstr "Versionsnamen dürfen nicht leer sein." -#: commands/extension.c:323 +#: commands/extension.c:324 #, c-format msgid "Version names must not contain \"--\"." msgstr "Versionsnamen dürfen nicht »--« enthalten." -#: commands/extension.c:332 +#: commands/extension.c:333 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "Versionsnamen dürfen nicht mit »-« anfangen oder aufhören." -#: commands/extension.c:342 +#: commands/extension.c:343 #, c-format msgid "Version names must not contain directory separator characters." msgstr "Versionsnamen dürfen keine Verzeichnistrennzeichen enthalten." -#: commands/extension.c:492 +#: commands/extension.c:493 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "konnte Erweiterungskontrolldatei »%s« nicht öffnen: %m" -#: commands/extension.c:514 commands/extension.c:524 +#: commands/extension.c:515 commands/extension.c:525 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "Parameter »%s« kann nicht in einer sekundären Erweitungskontrolldatei gesetzt werden" -#: commands/extension.c:563 +#: commands/extension.c:564 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "»%s« ist kein gültiger Kodierungsname" -#: commands/extension.c:577 +#: commands/extension.c:578 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "Parameter »%s« muss eine Liste von Erweiterungsnamen sein" -#: commands/extension.c:584 +#: commands/extension.c:585 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "unbekannter Parameter »%s« in Datei »%s«" -#: commands/extension.c:593 +#: commands/extension.c:594 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "Parameter »schema« kann nicht angegeben werden, wenn »relocatable« an ist" -#: commands/extension.c:756 +#: commands/extension.c:761 #, c-format msgid "transaction control statements are not allowed within an extension script" msgstr "Transaktionskontrollanweisungen sind nicht in einem Erweiterungsskript erlaubt" -#: commands/extension.c:801 +#: commands/extension.c:807 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "keine Berechtigung, um Erweiterung »%s« zu erzeugen" -#: commands/extension.c:803 +#: commands/extension.c:809 #, c-format msgid "Must be superuser to create this extension." msgstr "Nur Superuser können diese Erweiterung anlegen." -#: commands/extension.c:807 +#: commands/extension.c:813 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "keine Berechtigung, um Erweiterung »%s« zu aktualisieren" -#: commands/extension.c:809 +#: commands/extension.c:815 #, c-format msgid "Must be superuser to update this extension." msgstr "Nur Superuser können diese Erweiterung aktualisieren." -#: commands/extension.c:1091 +#: commands/extension.c:1097 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "Erweiterung »%s« hat keinen Aktualisierungspfad von Version »%s« auf Version »%s«" -#: commands/extension.c:1298 commands/extension.c:2961 +#: commands/extension.c:1304 commands/extension.c:2975 #, c-format msgid "version to install must be specified" msgstr "die zu installierende Version muss angegeben werden" -#: commands/extension.c:1320 +#: commands/extension.c:1326 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "FROM-Version muss verschieden von der zu installierenden Version »%s« sein" -#: commands/extension.c:1385 -#, fuzzy, c-format -#| msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +#: commands/extension.c:1391 +#, c-format msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" -msgstr "Erweiterung »%s« hat keinen Aktualisierungspfad von Version »%s« auf Version »%s«" +msgstr "Erweiterung »%s« hat kein Installationsskript und keinen Aktualisierungspfad für Version »%s«" -#: commands/extension.c:1420 +#: commands/extension.c:1426 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "Erweiterung »%s« muss in Schema »%s« installiert werden" -#: commands/extension.c:1573 +#: commands/extension.c:1586 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "zyklische Abhängigkeit zwischen Erweiterungen »%s« und »%s« entdeckt" -#: commands/extension.c:1578 +#: commands/extension.c:1591 #, c-format msgid "installing required extension \"%s\"" msgstr "installiere benötigte Erweiterung »%s«" -#: commands/extension.c:1602 +#: commands/extension.c:1615 #, c-format msgid "required extension \"%s\" is not installed" msgstr "benötigte Erweiterung »%s« ist nicht installiert" -#: commands/extension.c:1605 +#: commands/extension.c:1618 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "Verwenden Sie CREATE EXTENSION ... CASCADE, um die benötigten Erweiterungen ebenfalls zu installieren." -#: commands/extension.c:1642 +#: commands/extension.c:1655 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "Erweiterung »%s« existiert bereits, wird übersprungen" -#: commands/extension.c:1649 +#: commands/extension.c:1662 #, c-format msgid "extension \"%s\" already exists" msgstr "Erweiterung »%s« existiert bereits" -#: commands/extension.c:1660 +#: commands/extension.c:1673 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "geschachteltes CREATE EXTENSION wird nicht unterstützt" -#: commands/extension.c:1841 +#: commands/extension.c:1854 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "Erweiterung »%s« kann nicht gelöscht werden, weil sie gerade geändert wird" -#: commands/extension.c:2343 +#: commands/extension.c:2356 #, c-format msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" msgstr "pg_extension_config_dump() kann nur von einem SQL-Skript aufgerufen werden, das von CREATE EXTENSION ausgeführt wird" -#: commands/extension.c:2355 +#: commands/extension.c:2368 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u bezieht sich nicht auf eine Tabelle" -#: commands/extension.c:2360 +#: commands/extension.c:2373 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "Tabelle »%s« ist kein Mitglied der anzulegenden Erweiterung" -#: commands/extension.c:2716 +#: commands/extension.c:2729 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "kann Erweiterung »%s« nicht in Schema »%s« verschieben, weil die Erweiterung das Schema enthält" -#: commands/extension.c:2756 commands/extension.c:2819 +#: commands/extension.c:2770 commands/extension.c:2833 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "Erweiterung »%s« unterstützt SET SCHEMA nicht" -#: commands/extension.c:2821 +#: commands/extension.c:2835 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "%s ist nicht im Schema der Erweiterung (»%s«)" -#: commands/extension.c:2880 +#: commands/extension.c:2894 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "geschachteltes ALTER EXTENSION wird nicht unterstützt" -#: commands/extension.c:2972 +#: commands/extension.c:2986 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "Version »%s« von Erweiterung »%s« ist bereits installiert" -#: commands/extension.c:3223 +#: commands/extension.c:3237 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "kann Schema »%s« nicht zu Erweiterung »%s« hinzufügen, weil das Schema die Erweiterung enthält" -#: commands/extension.c:3251 +#: commands/extension.c:3265 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s ist kein Mitglied der Erweiterung »%s«" -#: commands/extension.c:3317 +#: commands/extension.c:3331 #, c-format msgid "file \"%s\" is too large" msgstr "Datei »%s« ist zu groß" @@ -6815,536 +6955,636 @@ msgstr "das Ändern des Handlers des Fremddaten-Wrappers kann das Verhalten von msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" msgstr "durch Ändern des Validators des Fremddaten-Wrappers können die Optionen von abhängigen Objekten ungültig werden" -#: commands/foreigncmds.c:1158 +#: commands/foreigncmds.c:890 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "Server »%s« existiert bereits, wird übersprungen" + +#: commands/foreigncmds.c:1175 +#, c-format +msgid "user mapping for \"%s\" already exists for server %s, skipping" +msgstr "Benutzerabbildung für »%s« existiert bereits für Server %s, wird übersprungen" + +#: commands/foreigncmds.c:1185 #, c-format -msgid "user mapping \"%s\" already exists for server %s" -msgstr "Benutzerabbildung »%s« existiert bereits für Server »%s«" +msgid "user mapping for \"%s\" already exists for server %s" +msgstr "Benutzerabbildung für »%s« existiert bereits für Server %s" -#: commands/foreigncmds.c:1250 commands/foreigncmds.c:1365 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 #, c-format -msgid "user mapping \"%s\" does not exist for the server" -msgstr "Benutzerabbildung »%s« existiert für den Server nicht" +msgid "user mapping for \"%s\" does not exist for the server" +msgstr "Benutzerabbildung für »%s« existiert für den Server nicht" -#: commands/foreigncmds.c:1352 +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" msgstr "Server existiert nicht, wird übersprungen" -#: commands/foreigncmds.c:1370 +#: commands/foreigncmds.c:1402 #, c-format -msgid "user mapping \"%s\" does not exist for the server, skipping" -msgstr "Benutzerabbildung »%s« existiert nicht für den Server, wird übersprungen" +msgid "user mapping for \"%s\" does not exist for the server, skipping" +msgstr "Benutzerabbildung für »%s« existiert für den Server nicht, wird übersprungen" -#: commands/foreigncmds.c:1521 foreign/foreign.c:357 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "Fremddaten-Wrapper »%s« hat keinen Handler" -#: commands/foreigncmds.c:1527 +#: commands/foreigncmds.c:1559 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "Fremddaten-Wrapper »%s« unterstützt IMPORT FOREIGN SCHEMA nicht" -#: commands/foreigncmds.c:1630 +#: commands/foreigncmds.c:1662 #, c-format msgid "importing foreign table \"%s\"" msgstr "importiere Fremdtabelle »%s«" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:104 #, c-format msgid "SQL function cannot return shell type %s" msgstr "SQL-Funktion kann keinen Hüllen-Rückgabetyp %s haben" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:109 #, c-format msgid "return type %s is only a shell" msgstr "Rückgabetyp %s ist nur eine Hülle" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:139 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "Typmodifikator kann für Hüllentyp »%s« nicht angegeben werden" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:145 #, c-format msgid "type \"%s\" is not yet defined" msgstr "Typ »%s« ist noch nicht definiert" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:146 #, c-format msgid "Creating a shell type definition." msgstr "Hüllentypdefinition wird erzeugt." -#: commands/functioncmds.c:233 +#: commands/functioncmds.c:238 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "SQL-Funktion kann keinen Hüllentyp %s annehmen" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:244 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "Aggregatfunktion kann keinen Hüllentyp %s annehmen" -#: commands/functioncmds.c:244 +#: commands/functioncmds.c:249 #, c-format msgid "argument type %s is only a shell" msgstr "Argumenttyp %s ist nur eine Hülle" -#: commands/functioncmds.c:254 +#: commands/functioncmds.c:259 #, c-format msgid "type %s does not exist" msgstr "Typ %s existiert nicht" -#: commands/functioncmds.c:268 +#: commands/functioncmds.c:273 #, c-format msgid "aggregates cannot accept set arguments" msgstr "Aggregatfunktionen können keine SETOF-Argumente haben" -#: commands/functioncmds.c:272 +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "Prozeduren können keine SETOF-Argumente haben" + +#: commands/functioncmds.c:281 #, c-format msgid "functions cannot accept set arguments" msgstr "Funktionen können keine SETOF-Argumente haben" -#: commands/functioncmds.c:282 +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "Prozeduren können keine OUT-Argumente haben" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT-Argumente sind erlaubt." + +#: commands/functioncmds.c:300 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "VARIADIC-Parameter muss der letzte Eingabeparameter sein" -#: commands/functioncmds.c:310 +#: commands/functioncmds.c:330 #, c-format msgid "VARIADIC parameter must be an array" msgstr "VARIADIC-Parameter muss ein Array sein" -#: commands/functioncmds.c:350 +#: commands/functioncmds.c:370 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "Parametername »%s« mehrmals angegeben" -#: commands/functioncmds.c:365 +#: commands/functioncmds.c:385 #, c-format msgid "only input parameters can have default values" msgstr "nur Eingabeparameter können Vorgabewerte haben" -#: commands/functioncmds.c:380 +#: commands/functioncmds.c:400 #, c-format msgid "cannot use table references in parameter default value" msgstr "Tabellenverweise können nicht in Parametervorgabewerten verwendet werden" -#: commands/functioncmds.c:404 +#: commands/functioncmds.c:424 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "Eingabeparameter hinter einem mit Vorgabewert müssen auch einen Vorgabewert haben" -#: commands/functioncmds.c:700 +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "ungültiges Attribut in Prozedurdefinition" + +#: commands/functioncmds.c:747 #, c-format msgid "no function body specified" msgstr "kein Funktionskörper angegeben" -#: commands/functioncmds.c:710 +#: commands/functioncmds.c:757 #, c-format msgid "no language specified" msgstr "keine Sprache angegeben" -#: commands/functioncmds.c:735 commands/functioncmds.c:1241 +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 #, c-format msgid "COST must be positive" msgstr "COST muss positiv sein" -#: commands/functioncmds.c:743 commands/functioncmds.c:1249 +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 #, c-format msgid "ROWS must be positive" msgstr "ROWS muss positiv sein" -#: commands/functioncmds.c:784 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "unbekanntes Funktionsattribut »%s« ignoriert" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:842 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "nur ein AS-Element benötigt für Sprache »%s«" -#: commands/functioncmds.c:930 commands/functioncmds.c:2110 -#: commands/proclang.c:561 +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 +#: commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "Sprache »%s« existiert nicht" -#: commands/functioncmds.c:932 commands/functioncmds.c:2112 +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "Sie müssen CREATE LANGUAGE verwenden, um die Sprache in die Datenbank zu laden." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Verwenden Sie CREATE EXTENSION, um die Sprache in die Datenbank zu laden." -#: commands/functioncmds.c:967 commands/functioncmds.c:1233 +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 #, c-format msgid "only superuser can define a leakproof function" msgstr "nur Superuser können eine »leakproof«-Funktion definieren" -#: commands/functioncmds.c:1009 +#: commands/functioncmds.c:1023 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "Ergebnistyp der Funktion muss %s sein wegen OUT-Parametern" -#: commands/functioncmds.c:1022 +#: commands/functioncmds.c:1036 #, c-format msgid "function result type must be specified" msgstr "Ergebnistyp der Funktion muss angegeben werden" -#: commands/functioncmds.c:1076 commands/functioncmds.c:1253 +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "ROWS ist nicht anwendbar, wenn die Funktion keine Ergebnismenge zurückgibt" -#: commands/functioncmds.c:1405 +#: commands/functioncmds.c:1440 #, c-format msgid "source data type %s is a pseudo-type" msgstr "Quelldatentyp %s ist ein Pseudotyp" -#: commands/functioncmds.c:1411 +#: commands/functioncmds.c:1446 #, c-format msgid "target data type %s is a pseudo-type" msgstr "Zieldatentyp %s ist ein Pseudotyp" -#: commands/functioncmds.c:1435 +#: commands/functioncmds.c:1470 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "Typumwandlung wird ignoriert werden, weil der Quelldatentyp eine Domäne ist" -#: commands/functioncmds.c:1440 +#: commands/functioncmds.c:1475 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "Typumwandlung wird ignoriert werden, weil der Zieldatentyp eine Domäne ist" -#: commands/functioncmds.c:1465 +#: commands/functioncmds.c:1500 #, c-format msgid "cast function must take one to three arguments" msgstr "Typumwandlungsfunktion muss ein bis drei Argumente haben" -#: commands/functioncmds.c:1469 +#: commands/functioncmds.c:1504 #, c-format msgid "argument of cast function must match or be binary-coercible from source data type" msgstr "Argument der Typumwandlungsfunktion muss mit Quelldatentyp übereinstimmen oder in ihn binär-umwandelbar sein" -#: commands/functioncmds.c:1473 +#: commands/functioncmds.c:1508 #, c-format msgid "second argument of cast function must be type %s" msgstr "zweites Argument der Typumwandlungsfunktion muss Typ %s haben" -#: commands/functioncmds.c:1478 +#: commands/functioncmds.c:1513 #, c-format msgid "third argument of cast function must be type %s" msgstr "drittes Argument der Typumwandlungsfunktion muss Typ %s haben" -#: commands/functioncmds.c:1483 +#: commands/functioncmds.c:1518 #, c-format msgid "return data type of cast function must match or be binary-coercible to target data type" msgstr "Rückgabetyp der Typumwandlungsfunktion muss mit Zieldatentyp übereinstimmen oder in ihn binär-umwandelbar sein" -#: commands/functioncmds.c:1494 +#: commands/functioncmds.c:1529 #, c-format msgid "cast function must not be volatile" msgstr "Typumwandlungsfunktion darf nicht VOLATILE sein" -#: commands/functioncmds.c:1499 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "Typumwandlungsfunktion darf keine Aggregatfunktion sein" - -#: commands/functioncmds.c:1503 +#: commands/functioncmds.c:1534 #, c-format -msgid "cast function must not be a window function" -msgstr "Typumwandlungsfunktion darf keine Fensterfunktion sein" +msgid "cast function must be a normal function" +msgstr "Typumwandlungsfunktion muss eine normale Funktion sein" -#: commands/functioncmds.c:1507 +#: commands/functioncmds.c:1538 #, c-format msgid "cast function must not return a set" msgstr "Typumwandlungsfunktion darf keine Ergebnismenge zurückgeben" -#: commands/functioncmds.c:1533 +#: commands/functioncmds.c:1564 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "nur Superuser können Typumwandlungen mit WITHOUT FUNCTION erzeugen" -#: commands/functioncmds.c:1548 +#: commands/functioncmds.c:1579 #, c-format msgid "source and target data types are not physically compatible" msgstr "Quelldatentyp und Zieldatentyp sind nicht physikalisch kompatibel" -#: commands/functioncmds.c:1563 +#: commands/functioncmds.c:1594 #, c-format msgid "composite data types are not binary-compatible" msgstr "zusammengesetzte Datentypen sind nicht binärkompatibel" -#: commands/functioncmds.c:1569 +#: commands/functioncmds.c:1600 #, c-format msgid "enum data types are not binary-compatible" msgstr "Enum-Datentypen sind nicht binärkompatibel" -#: commands/functioncmds.c:1575 +#: commands/functioncmds.c:1606 #, c-format msgid "array data types are not binary-compatible" msgstr "Array-Datentypen sind nicht binärkompatibel" -#: commands/functioncmds.c:1592 +#: commands/functioncmds.c:1623 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "Domänendatentypen dürfen nicht als binärkompatibel markiert werden" -#: commands/functioncmds.c:1602 +#: commands/functioncmds.c:1633 #, c-format msgid "source data type and target data type are the same" msgstr "Quelldatentyp und Zieldatentyp sind der selbe" -#: commands/functioncmds.c:1635 +#: commands/functioncmds.c:1666 #, c-format msgid "cast from type %s to type %s already exists" msgstr "Typumwandlung von Typ %s in Typ %s existiert bereits" -#: commands/functioncmds.c:1708 +#: commands/functioncmds.c:1739 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "Typumwandlung von Typ %s in Typ %s existiert nicht" -#: commands/functioncmds.c:1747 +#: commands/functioncmds.c:1778 #, c-format msgid "transform function must not be volatile" msgstr "Transformationsfunktion darf nicht VOLATILE sein" -#: commands/functioncmds.c:1751 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "Transformationsfunktion darf keine Aggregatfunktion sein" - -#: commands/functioncmds.c:1755 +#: commands/functioncmds.c:1782 #, c-format -msgid "transform function must not be a window function" -msgstr "Transformationsfunktion darf keine Fensterfunktion sein" +msgid "transform function must be a normal function" +msgstr "Transformationsfunktion muss eine normale Funktion sein" -#: commands/functioncmds.c:1759 +#: commands/functioncmds.c:1786 #, c-format msgid "transform function must not return a set" msgstr "Transformationsfunktion darf keine Ergebnismenge zurückgeben" -#: commands/functioncmds.c:1763 +#: commands/functioncmds.c:1790 #, c-format msgid "transform function must take one argument" msgstr "Transformationsfunktion muss ein Argument haben" -#: commands/functioncmds.c:1767 +#: commands/functioncmds.c:1794 #, c-format msgid "first argument of transform function must be type %s" msgstr "erstes Argument der Transformationsfunktion muss Typ %s haben" -#: commands/functioncmds.c:1805 +#: commands/functioncmds.c:1832 #, c-format msgid "data type %s is a pseudo-type" msgstr "Datentyp %s ist ein Pseudotyp" -#: commands/functioncmds.c:1811 +#: commands/functioncmds.c:1838 #, c-format msgid "data type %s is a domain" msgstr "Datentyp %s ist eine Domäne" -#: commands/functioncmds.c:1851 +#: commands/functioncmds.c:1878 #, c-format msgid "return data type of FROM SQL function must be %s" msgstr "Rückgabetyp der FROM-SQL-Funktion muss %s sein" -#: commands/functioncmds.c:1877 +#: commands/functioncmds.c:1904 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "Rückgabetyp der TO-SQL-Funktion muss der zu transformierende Datentyp sein" -#: commands/functioncmds.c:1904 +#: commands/functioncmds.c:1931 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "Transformation für Typ %s Sprache »%s« existiert bereits" -#: commands/functioncmds.c:1993 +#: commands/functioncmds.c:2020 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "Transformation für Typ %s Sprache »%s« existiert nicht" -#: commands/functioncmds.c:2044 +#: commands/functioncmds.c:2071 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "Funktion %s existiert bereits in Schema »%s«" -#: commands/functioncmds.c:2097 +#: commands/functioncmds.c:2126 #, c-format msgid "no inline code specified" msgstr "kein Inline-Code angegeben" -#: commands/functioncmds.c:2142 +#: commands/functioncmds.c:2172 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "Sprache »%s« unterstützt das Ausführen von Inline-Code nicht" -#: commands/indexcmds.c:350 +#: commands/functioncmds.c:2284 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "kann nicht mehr als %d Argument an eine Prozedur übergeben" +msgstr[1] "kann nicht mehr als %d Argumente an eine Prozedur übergeben" + +#: commands/indexcmds.c:393 #, c-format msgid "must specify at least one column" msgstr "mindestens eine Spalte muss angegeben werden" -#: commands/indexcmds.c:354 +#: commands/indexcmds.c:397 #, c-format msgid "cannot use more than %d columns in an index" msgstr "Index kann nicht mehr als %d Spalten enthalten" -#: commands/indexcmds.c:385 +#: commands/indexcmds.c:437 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "kann keinen Index für Fremdtabelle »%s« erzeugen" -#: commands/indexcmds.c:390 -#, c-format -msgid "cannot create index on partitioned table \"%s\"" +#: commands/indexcmds.c:462 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\"" +msgid "cannot create index on partitioned table \"%s\" concurrently" msgstr "kann keinen Index für partitionierte Tabelle »%s« erzeugen" -#: commands/indexcmds.c:405 +#: commands/indexcmds.c:467 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\"" +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "kann keinen Index für partitionierte Tabelle »%s« erzeugen" + +#: commands/indexcmds.c:477 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "kann keine Indexe für temporäre Tabellen anderer Sitzungen erzeugen" -#: commands/indexcmds.c:461 commands/tablecmds.c:579 -#: commands/tablecmds.c:10166 +#: commands/indexcmds.c:542 commands/tablecmds.c:617 commands/tablecmds.c:11445 +#: commands/tablecmds.c:11579 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "nur geteilte Relationen können in den Tablespace »pg_global« gelegt werden" -#: commands/indexcmds.c:494 +#: commands/indexcmds.c:575 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "ersetze Zugriffsmethode »gist« für obsolete Methode »rtree«" -#: commands/indexcmds.c:512 -#, c-format -msgid "hash indexes are not WAL-logged and their use is discouraged" -msgstr "Hash-Indexe werden nicht im WAL geloggt und von ihrer Verwendung wird abgeraten." - -#: commands/indexcmds.c:517 +#: commands/indexcmds.c:593 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "Zugriffsmethode »%s« unterstützt keine Unique Indexe" -#: commands/indexcmds.c:522 +#: commands/indexcmds.c:598 +#, fuzzy, c-format +#| msgid "access method \"%s\" does not support unique indexes" +msgid "access method \"%s\" does not support included columns" +msgstr "Zugriffsmethode »%s« unterstützt keine Unique Indexe" + +#: commands/indexcmds.c:603 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "Zugriffsmethode »%s« unterstützt keine mehrspaltigen Indexe" -#: commands/indexcmds.c:527 +#: commands/indexcmds.c:608 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "Zugriffsmethode »%s« unterstützt keine Exclusion-Constraints" -#: commands/indexcmds.c:599 commands/indexcmds.c:619 +#: commands/indexcmds.c:720 +#, fuzzy, c-format +#| msgid "merging constraint \"%s\" with inherited definition" +msgid "unsupported %s constraint with partition key definition" +msgstr "Constraint »%s« wird mit geerbter Definition zusammengeführt" + +#: commands/indexcmds.c:722 +#, fuzzy, c-format +#| msgid "cannot use subquery in partition key expression" +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "Unteranfragen können nicht in Partitionierungsschlüsselausdrücken verwendet werden" + +#: commands/indexcmds.c:740 +#, fuzzy, c-format +#| msgid "duplicate column name in statistics definition" +msgid "insufficient columns in %s constraint definition" +msgstr "doppelter Spaltenname in Statistikdefinition" + +#: commands/indexcmds.c:742 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "" + +#: commands/indexcmds.c:761 commands/indexcmds.c:781 #, c-format msgid "index creation on system columns is not supported" msgstr "Indexerzeugung für Systemspalten wird nicht unterstützt" -#: commands/indexcmds.c:644 +#: commands/indexcmds.c:806 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s erstellt implizit einen Index »%s« für Tabelle »%s«" -#: commands/indexcmds.c:991 +#: commands/indexcmds.c:1402 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "Funktionen im Indexprädikat müssen als IMMUTABLE markiert sein" -#: commands/indexcmds.c:1057 parser/parse_utilcmd.c:1946 +#: commands/indexcmds.c:1468 parser/parse_utilcmd.c:2237 +#: parser/parse_utilcmd.c:2361 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "Spalte »%s«, die im Schlüssel verwendet wird, existiert nicht" -#: commands/indexcmds.c:1117 +#: commands/indexcmds.c:1492 parser/parse_utilcmd.c:1586 +#, fuzzy, c-format +#| msgid "lossy distance functions are not supported in index-only scans" +msgid "expressions are not supported in included columns" +msgstr "verlustbehaftete Abstandsfunktionen werden in Index-Only-Scans nicht unterstützt" + +#: commands/indexcmds.c:1533 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "Funktionen im Indexausdruck müssen als IMMUTABLE markiert sein" -#: commands/indexcmds.c:1140 +#: commands/indexcmds.c:1548 +#, fuzzy, c-format +#| msgid "identity columns are not supported on partitions" +msgid "including column does not support a collation" +msgstr "Identitätsspalten in partitionierten Tabellen werden nicht unterstützt" + +#: commands/indexcmds.c:1552 +#, fuzzy, c-format +#| msgid "identity columns are not supported on partitions" +msgid "including column does not support an operator class" +msgstr "Identitätsspalten in partitionierten Tabellen werden nicht unterstützt" + +#: commands/indexcmds.c:1556 +#, fuzzy, c-format +#| msgid "access method \"%s\" does not support ASC/DESC options" +msgid "including column does not support ASC/DESC options" +msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" + +#: commands/indexcmds.c:1560 +#, fuzzy, c-format +#| msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" + +#: commands/indexcmds.c:1587 #, c-format msgid "could not determine which collation to use for index expression" msgstr "konnte die für den Indexausdruck zu verwendende Sortierfolge nicht bestimmen" -#: commands/indexcmds.c:1148 commands/tablecmds.c:13007 -#: commands/typecmds.c:831 parser/parse_expr.c:2730 parser/parse_type.c:549 -#: parser/parse_utilcmd.c:2873 utils/adt/misc.c:661 +#: commands/indexcmds.c:1595 commands/tablecmds.c:14379 commands/typecmds.c:833 +#: parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3392 +#: utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "Sortierfolgen werden von Typ %s nicht unterstützt" -#: commands/indexcmds.c:1186 +#: commands/indexcmds.c:1633 #, c-format msgid "operator %s is not commutative" msgstr "Operator %s ist nicht kommutativ" -#: commands/indexcmds.c:1188 +#: commands/indexcmds.c:1635 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "In Exclusion-Constraints können nur kommutative Operatoren verwendet werden." -#: commands/indexcmds.c:1214 +#: commands/indexcmds.c:1661 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "Operator %s ist kein Mitglied der Operatorfamilie »%s«" -#: commands/indexcmds.c:1217 +#: commands/indexcmds.c:1664 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "Der Exklusionsoperator muss in Beziehung zur Indexoperatorklasse des Constraints stehen." -#: commands/indexcmds.c:1252 +#: commands/indexcmds.c:1699 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "Zugriffsmethode »%s« unterstützt die Optionen ASC/DESC nicht" -#: commands/indexcmds.c:1257 +#: commands/indexcmds.c:1704 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "Zugriffsmethode »%s« unterstützt die Optionen NULLS FIRST/LAST nicht" -#: commands/indexcmds.c:1316 commands/typecmds.c:1928 +#: commands/indexcmds.c:1763 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" -#: commands/indexcmds.c:1318 +#: commands/indexcmds.c:1765 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "Sie müssen für den Index eine Operatorklasse angeben oder eine Standardoperatorklasse für den Datentyp definieren." -#: commands/indexcmds.c:1347 commands/indexcmds.c:1355 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1794 commands/indexcmds.c:1802 +#: commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "Operatorklasse »%s« existiert nicht für Zugriffsmethode »%s«" -#: commands/indexcmds.c:1368 commands/typecmds.c:1916 +#: commands/indexcmds.c:1815 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "Operatorklasse »%s« akzeptiert Datentyp %s nicht" -#: commands/indexcmds.c:1458 +#: commands/indexcmds.c:1905 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "es gibt mehrere Standardoperatorklassen für Datentyp %s" -#: commands/indexcmds.c:1849 +#: commands/indexcmds.c:2320 #, c-format msgid "table \"%s\" has no indexes" msgstr "Tabelle »%s« hat keine Indexe" -#: commands/indexcmds.c:1904 +#: commands/indexcmds.c:2375 #, c-format msgid "can only reindex the currently open database" -msgstr "aktuell geöffnete Datenbank kann nicht reindiziert werden" +msgstr "nur die aktuell geöffnete Datenbank kann reindiziert werden" -#: commands/indexcmds.c:2004 +#: commands/indexcmds.c:2493 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "Tabelle »%s.%s« wurde neu indiziert" +#: commands/indexcmds.c:2515 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX ist für partitionierte Indexe noch nicht implementiert" + +#: commands/lockcmds.c:102 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "»%s« ist keine Tabelle oder Sicht" + +#: commands/lockcmds.c:234 rewrite/rewriteHandler.c:1836 +#: rewrite/rewriteHandler.c:3532 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "unendliche Rekursion entdeckt in Regeln für Relation »%s«" + #: commands/matview.c:179 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" @@ -7355,235 +7595,255 @@ msgstr "CONCURRENTLY kann nicht verwendet werden, wenn die materialisierte Sicht msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "Optionen CONCURRENTLY und WITH NO DATA können nicht zusammen verwendet werden" -#: commands/matview.c:255 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "kann materialisierte Sicht »%s« nicht nebenläufig auffrischen" -#: commands/matview.c:258 +#: commands/matview.c:247 #, c-format msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." msgstr "Erzeugen Sie einen Unique Index ohne WHERE-Klausel für eine oder mehrere Spalten der materialisierten Sicht." -#: commands/matview.c:654 +#: commands/matview.c:645 #, c-format msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" msgstr "neue Daten für materialisierte Sicht »%s« enthalten doppelte Zeilen ohne Spalten mit NULL-Werten" -#: commands/matview.c:656 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "Zeile: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "Operatorfamilie »%s« existiert nicht für Zugriffsmethode »%s«" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "Operatorfamilie »%s« für Zugriffsmethode »%s« existiert bereits" -#: commands/opclasscmds.c:402 +#: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" msgstr "nur Superuser können Operatorklassen erzeugen" -#: commands/opclasscmds.c:475 commands/opclasscmds.c:849 -#: commands/opclasscmds.c:973 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 +#: commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "ungültige Operatornummer %d, muss zwischen 1 und %d sein" -#: commands/opclasscmds.c:519 commands/opclasscmds.c:893 -#: commands/opclasscmds.c:988 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 +#: commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "ungültige Prozedurnummer %d, muss zwischen 1 und %d sein" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "ungültige Funktionsnummer %d, muss zwischen 1 und %d sein" -#: commands/opclasscmds.c:548 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "Storage-Typ mehrmals angegeben" -#: commands/opclasscmds.c:575 +#: commands/opclasscmds.c:576 #, c-format msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "Storage-Typ kann nicht vom Datentyp der Zugriffsmethode »%s« verschieden sein" -#: commands/opclasscmds.c:591 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "Operatorklasse »%s« für Zugriffsmethode »%s« existiert bereits" -#: commands/opclasscmds.c:619 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "konnte Operatorklasse »%s« nicht zum Standard für Typ %s machen" -#: commands/opclasscmds.c:622 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "Operatorklasse »%s« ist bereits der Standard." -#: commands/opclasscmds.c:747 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" msgstr "nur Superuser können Operatorfamilien erzeugen" -#: commands/opclasscmds.c:803 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" msgstr "nur Superuser können Operatorfamilien ändern" -#: commands/opclasscmds.c:858 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "Operatorargumenttypen müssen in ALTER OPERATOR FAMILY angegeben werden" -#: commands/opclasscmds.c:921 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "STORAGE kann in ALTER OPERATOR FAMILY nicht angegeben werden" -#: commands/opclasscmds.c:1043 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" msgstr "ein oder zwei Argumenttypen müssen angegeben werden" -#: commands/opclasscmds.c:1069 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "Indexoperatoren müssen binär sein" -#: commands/opclasscmds.c:1088 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "Zugriffsmethode »%s« unterstützt keine Sortieroperatoren" -#: commands/opclasscmds.c:1099 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" msgstr "Indexsuchoperatoren müssen Typ boolean zurückgeben" -#: commands/opclasscmds.c:1141 +#: commands/opclasscmds.c:1144 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree-Vergleichsfunktionen müssen zwei Argumente haben" + +#: commands/opclasscmds.c:1148 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "btree-Vergleichsfunktionen müssen Typ integer zurückgeben" + +#: commands/opclasscmds.c:1165 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "btree-Vergleichsprozeduren müssen zwei Argumente haben" +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btree-Sortierunterstützungsfunktionen müssen Typ »internal« akzeptieren" -#: commands/opclasscmds.c:1145 +#: commands/opclasscmds.c:1169 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "btree-Vergleichsprozeduren müssen Typ integer zurückgeben" +msgid "btree sort support functions must return void" +msgstr "btree-Sortierunterstützungsfunktionen müssen Typ void zurückgeben" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1180 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "btree-Sortierunterstützungsprozeduren müssen Typ »internal« akzeptieren" +msgid "btree in_range functions must have five arguments" +msgstr "btree-in_range-Funktionen müssen fünf Argumente haben" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1184 #, c-format -msgid "btree sort support procedures must return void" -msgstr "btree-Sortierunterstützungsprozeduren müssen Typ void zurückgeben" +msgid "btree in_range functions must return boolean" +msgstr "btree-in_range-Funktionen müssen Typ boolean zurückgeben" -#: commands/opclasscmds.c:1178 +#: commands/opclasscmds.c:1203 #, c-format -msgid "hash procedures must have one argument" -msgstr "Hash-Prozeduren müssen ein Argument haben" +msgid "hash function 1 must have one argument" +msgstr "Hash-Funktion 1 muss ein Argument haben" -#: commands/opclasscmds.c:1182 +#: commands/opclasscmds.c:1207 #, c-format -msgid "hash procedures must return integer" -msgstr "Hash-Prozeduren müssen Typ integer zurückgeben" +msgid "hash function 1 must return integer" +msgstr "Hash-Funktion 1 muss Typ integer zurückgeben" -#: commands/opclasscmds.c:1206 +#: commands/opclasscmds.c:1214 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "zugehörige Datentypen müssen für Indexunterstützungsprozedur angegeben werden" +msgid "hash function 2 must have two arguments" +msgstr "Hash-Funktion 2 muss zwei Argumente haben" -#: commands/opclasscmds.c:1231 +#: commands/opclasscmds.c:1218 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "Prozedurnummer %d für (%s,%s) einscheint mehrmals" +msgid "hash function 2 must return bigint" +msgstr "Hash-Funktion 2 muss Typ bigint zurückgeben" -#: commands/opclasscmds.c:1238 +#: commands/opclasscmds.c:1243 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "zugehörige Datentypen müssen für Indexunterstützungsfunktion angegeben werden" + +#: commands/opclasscmds.c:1268 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "Funktionsnummer %d für (%s,%s) einscheint mehrmals" + +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "Operatornummer %d für (%s,%s) einscheint mehrmals" -#: commands/opclasscmds.c:1287 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "Operator %d(%s,%s) existiert bereits in Operatorfamilie »%s«" -#: commands/opclasscmds.c:1401 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "Funktion %d(%s,%s) existiert bereits in Operatorfamilie »%s«" -#: commands/opclasscmds.c:1489 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "Operator %d(%s,%s) existiert nicht in Operatorfamilie »%s«" -#: commands/opclasscmds.c:1529 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "Funktion %d(%s,%s) existiert nicht in Operatorfamilie »%s«" -#: commands/opclasscmds.c:1659 +#: commands/opclasscmds.c:1696 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "Operatorklasse »%s« für Zugriffsmethode »%s« existiert bereits in Schema »%s«" -#: commands/opclasscmds.c:1682 +#: commands/opclasscmds.c:1719 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "Operatorfamilie »%s« für Zugriffsmethode »%s« existiert bereits in Schema »%s«" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "SETOF-Typ nicht als Operatorargument erlaubt" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:454 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "Operator-Attribut »%s« unbekannt" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "Operatorprozedur muss angegeben werden" +msgid "operator function must be specified" +msgstr "Operatorfunktion muss angegeben werden" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "entweder leftarg oder rightarg (oder beides) muss angegeben werden" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "Restriktionsschätzfunktion %s muss Typ %s zurückgeben" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "Join-Schätzfunktion %s muss Typ %s zurückgeben" -#: commands/operatorcmds.c:448 +#: commands/operatorcmds.c:451 #, c-format msgid "operator attribute \"%s\" cannot be changed" msgstr "Operator-Attribut »%s« kann nicht geändert werden" -#: commands/policy.c:87 commands/policy.c:397 commands/policy.c:486 -#: commands/tablecmds.c:1134 commands/tablecmds.c:1490 -#: commands/tablecmds.c:2467 commands/tablecmds.c:4647 -#: commands/tablecmds.c:6742 commands/tablecmds.c:12660 -#: commands/tablecmds.c:12695 commands/trigger.c:251 commands/trigger.c:1235 -#: commands/trigger.c:1344 rewrite/rewriteDefine.c:272 -#: rewrite/rewriteDefine.c:911 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 +#: commands/tablecmds.c:1278 commands/tablecmds.c:1755 +#: commands/tablecmds.c:2742 commands/tablecmds.c:4986 +#: commands/tablecmds.c:7394 commands/tablecmds.c:14012 +#: commands/tablecmds.c:14047 commands/trigger.c:316 commands/trigger.c:1526 +#: commands/trigger.c:1635 rewrite/rewriteDefine.c:272 +#: rewrite/rewriteDefine.c:924 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "keine Berechtigung: »%s« ist ein Systemkatalog" @@ -7598,44 +7858,43 @@ msgstr "angegebene Rollen außer PUBLIC werden ignoriert" msgid "All roles are members of the PUBLIC role." msgstr "Alle Rollen sind Mitglieder der Rolle PUBLIC." -#: commands/policy.c:510 +#: commands/policy.c:514 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "Rolle »%s« konnte nicht aus Policy »%s« für »%s« entfernt werden" -#: commands/policy.c:716 +#: commands/policy.c:720 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK kann nicht auf SELECT oder DELETE angewendet werden" -#: commands/policy.c:725 commands/policy.c:1023 +#: commands/policy.c:729 commands/policy.c:1027 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "für INSERT sind nur WITH-CHECK-Ausdrücke erlaubt" -#: commands/policy.c:798 commands/policy.c:1243 +#: commands/policy.c:802 commands/policy.c:1247 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "Policy »%s« für Tabelle »%s« existiert bereits" -#: commands/policy.c:995 commands/policy.c:1271 commands/policy.c:1343 +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "Policy »%s« für Tabelle »%s« existiert nicht" -#: commands/policy.c:1013 +#: commands/policy.c:1017 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "für SELECT und DELETE sind nur USING-Ausdrücke erlaubt" -#: commands/portalcmds.c:58 commands/portalcmds.c:182 -#: commands/portalcmds.c:234 +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 #, c-format msgid "invalid cursor name: must not be empty" msgstr "ungültiger Cursorname: darf nicht leer sein" #: commands/portalcmds.c:190 commands/portalcmds.c:244 -#: executor/execCurrent.c:67 utils/adt/xml.c:2460 utils/adt/xml.c:2627 +#: executor/execCurrent.c:69 utils/adt/xml.c:2472 utils/adt/xml.c:2642 #, c-format msgid "cursor \"%s\" does not exist" msgstr "Cursor »%s« existiert nicht" @@ -7645,7 +7904,7 @@ msgstr "Cursor »%s« existiert nicht" msgid "invalid statement name: must not be empty" msgstr "ungültiger Anweisungsname: darf nicht leer sein" -#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1350 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1399 #, c-format msgid "could not determine data type of parameter $%d" msgstr "konnte Datentyp von Parameter $%d nicht ermitteln" @@ -7675,67 +7934,81 @@ msgstr "%d Parameter erwartet aber %d erhalten." msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "Parameter $%d mit Typ %s kann nicht in erwarteten Typ %s umgewandelt werden" -#: commands/prepare.c:474 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "vorbereitete Anweisung »%s« existiert bereits" -#: commands/prepare.c:513 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "vorbereitete Anweisung »%s« existiert nicht" -#: commands/proclang.c:87 +#: commands/proclang.c:86 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "verwende Informationen aus pg_pltemplate statt der CREATE-LANGUAGE-Parameter" -#: commands/proclang.c:97 +#: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "nur Superuser können prozedurale Sprache »%s« erzeugen" -#: commands/proclang.c:252 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "nicht unterstützte Sprache »%s«" -#: commands/proclang.c:254 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "Die unterstützten Sprachen stehen im Systemkatalog pg_pltemplate." -#: commands/proclang.c:262 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" msgstr "nur Superuser können maßgeschneiderte prozedurale Sprachen erzeugen" -#: commands/proclang.c:281 commands/trigger.c:523 commands/typecmds.c:457 -#: commands/typecmds.c:474 +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 +#: commands/typecmds.c:471 #, c-format msgid "changing return type of function %s from %s to %s" msgstr "ändere Rückgabetyp von Funktion %s von %s in %s" -#: commands/publicationcmds.c:179 +#: commands/publicationcmds.c:109 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "ungültige Listensyntax für »publish«-Option" + +#: commands/publicationcmds.c:127 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "unbekannter »publish«-Wert: »%s«" + +#: commands/publicationcmds.c:133 +#, c-format +msgid "unrecognized publication parameter: %s" +msgstr "unbekannter Publikationsparameter: %s" + +#: commands/publicationcmds.c:166 #, c-format msgid "must be superuser to create FOR ALL TABLES publication" msgstr "nur Superuser können eine Publikation FOR ALL TABLES erzeugen" -#: commands/publicationcmds.c:351 +#: commands/publicationcmds.c:335 #, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES" msgstr "Publikation »%s« ist als FOR ALL TABLES definiert" -#: commands/publicationcmds.c:353 +#: commands/publicationcmds.c:337 #, c-format msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." -msgstr "" +msgstr "In einer FOR-ALL-TABLES-Publikation können keine Tabellen hinzugefügt oder entfernt werden." -#: commands/publicationcmds.c:651 -#, fuzzy, c-format -#| msgid "relation \"%s\" is not a parent of relation \"%s\"" +#: commands/publicationcmds.c:638 +#, c-format msgid "relation \"%s\" is not part of the publication" -msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" +msgstr "Relation »%s« ist nicht Teil der Publikation" #: commands/publicationcmds.c:681 #, c-format @@ -7744,15 +8017,15 @@ msgstr "keine Berechtigung, um Eigentümer der Publikation »%s« zu ändern" #: commands/publicationcmds.c:683 #, c-format -msgid "The owner of a publication must be a superuser." -msgstr "Der Eigentümer einer Publikation muss ein Superuser sein." +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "Der Eigentümer einer FOR-ALL-TABLES-Publikation muss ein Superuser sein." -#: commands/schemacmds.c:106 commands/schemacmds.c:279 +#: commands/schemacmds.c:106 commands/schemacmds.c:280 #, c-format msgid "unacceptable schema name \"%s\"" msgstr "inakzeptabler Schemaname »%s«" -#: commands/schemacmds.c:107 commands/schemacmds.c:280 +#: commands/schemacmds.c:107 commands/schemacmds.c:281 #, c-format msgid "The prefix \"pg_\" is reserved for system schemas." msgstr "Der Präfix »pg_« ist für Systemschemas reserviert." @@ -7777,1694 +8050,2057 @@ msgstr "Provider muss angegeben werden, wenn mehrere Security-Label-Provider gel msgid "security label provider \"%s\" is not loaded" msgstr "Security-Label-Provider »%s« ist nicht geladen" -#: commands/sequence.c:135 +#: commands/sequence.c:138 #, c-format msgid "unlogged sequences are not supported" msgstr "ungeloggte Sequenzen werden nicht unterstützt" -#: commands/sequence.c:698 +#: commands/sequence.c:697 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: Maximalwert von Sequenz »%s« erreicht (%s)" -#: commands/sequence.c:721 +#: commands/sequence.c:720 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: Minimalwert von Sequenz »%s« erreicht (%s)" -#: commands/sequence.c:839 +#: commands/sequence.c:838 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "currval von Sequenz »%s« ist in dieser Sitzung noch nicht definiert" -#: commands/sequence.c:858 commands/sequence.c:864 +#: commands/sequence.c:857 commands/sequence.c:863 #, c-format msgid "lastval is not yet defined in this session" msgstr "lastval ist in dieser Sitzung noch nicht definiert" -#: commands/sequence.c:952 +#: commands/sequence.c:951 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: Wert %s ist außerhalb des gültigen Bereichs von Sequenz »%s« (%s..%s)" -#: commands/sequence.c:1344 +#: commands/sequence.c:1348 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "ungültige Sequenzoption SEQUENCE NAME" + +#: commands/sequence.c:1374 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "Typ von Identitätsspalte muss smallint, integer oder bigint sein" + +#: commands/sequence.c:1375 #, c-format msgid "sequence type must be smallint, integer, or bigint" -msgstr "" +msgstr "Sequenztyp muss smallint, integer oder bigint sein" -#: commands/sequence.c:1356 +#: commands/sequence.c:1409 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT darf nicht null sein" -#: commands/sequence.c:1405 -#, fuzzy, c-format -#| msgid "\"%s\" is out of range for type real" +#: commands/sequence.c:1462 +#, c-format msgid "MAXVALUE (%s) is out of range for sequence data type %s" -msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ real" +msgstr "MAXVALUE (%s) ist außerhalb des gültigen Bereichs für Sequenzdatentyp %s" -#: commands/sequence.c:1442 -#, fuzzy, c-format -#| msgid "\"%s\" is out of range for type real" +#: commands/sequence.c:1499 +#, c-format msgid "MINVALUE (%s) is out of range for sequence data type %s" -msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ real" +msgstr "MINVALUE (%s) ist außerhalb des gültigen Bereichs für Sequenzdatentyp %s" -#: commands/sequence.c:1456 +#: commands/sequence.c:1513 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) muss kleiner als MAXVALUE (%s) sein" -#: commands/sequence.c:1481 +#: commands/sequence.c:1540 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "START-Wert (%s) kann nicht kleiner als MINVALUE (%s) sein" -#: commands/sequence.c:1493 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "START-Wert (%s) kann nicht größer als MAXVALUE (%s) sein" -#: commands/sequence.c:1523 +#: commands/sequence.c:1582 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "RESTART-Wert (%s) kann nicht kleiner als MINVALUE (%s) sein" -#: commands/sequence.c:1535 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "RESTART-Wert (%s) kann nicht größer als MAXVALUE (%s) sein" -#: commands/sequence.c:1550 +#: commands/sequence.c:1609 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE (%s) muss größer als null sein" -#: commands/sequence.c:1582 +#: commands/sequence.c:1646 #, c-format msgid "invalid OWNED BY option" msgstr "ungültige OWNED BY Option" -#: commands/sequence.c:1583 +#: commands/sequence.c:1647 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "Geben Sie OWNED BY tabelle.spalte oder OWNED BY NONE an." -#: commands/sequence.c:1607 +#: commands/sequence.c:1672 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle oder Fremdtabelle" -#: commands/sequence.c:1614 +#: commands/sequence.c:1679 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "Sequenz muss selben Eigentümer wie die verknüpfte Tabelle haben" -#: commands/sequence.c:1618 +#: commands/sequence.c:1683 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "Sequenz muss im selben Schema wie die verknüpfte Tabelle sein" -#: commands/subscriptioncmds.c:188 +#: commands/sequence.c:1705 #, c-format -msgid "publication name \"%s\" used more than once" -msgstr "Publikationsname »%s« mehrmals angegeben" +msgid "cannot change ownership of identity sequence" +msgstr "kann Eigentümer einer Identitätssequenz nicht ändern" -#: commands/subscriptioncmds.c:245 +#: commands/sequence.c:1706 commands/tablecmds.c:10827 +#: commands/tablecmds.c:13444 #, c-format -msgid "must be superuser to create subscriptions" -msgstr "nur Superuser können Subskriptionen erzeugen" +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "Sequenz »%s« ist mit Tabelle »%s« verknüpft." -#: commands/subscriptioncmds.c:313 replication/logical/worker.c:1427 -#, fuzzy, c-format -#| msgid "could not connect to the primary server: %s" -msgid "could not connect to the publisher: %s" -msgstr "konnte nicht mit dem Primärserver verbinden: %s" +#: commands/statscmds.c:93 commands/statscmds.c:102 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "in CREATE STATISTICS ist nur eine einzelne Relation erlaubt" -#: commands/subscriptioncmds.c:319 -#, fuzzy, c-format -#| msgid "%s: creating replication slot \"%s\"\n" -msgid "created replication slot \"%s\" on publisher" -msgstr "%s: erzeuge Replikations-Slot »%s«\n" +#: commands/statscmds.c:120 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "Relation »%s« ist keine Tabelle, Fremdtabelle oder materialisierte Sicht" -#: commands/subscriptioncmds.c:485 +#: commands/statscmds.c:163 #, c-format -msgid "subscription \"%s\" does not exist, skipping" -msgstr "Subskription »%s« existiert nicht, wird übersprungen" +msgid "statistics object \"%s\" already exists, skipping" +msgstr "Statistikobjekt »%s« existiert bereits, wird übersprungen" -#: commands/subscriptioncmds.c:564 +#: commands/statscmds.c:171 #, c-format -msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" -msgstr "" +msgid "statistics object \"%s\" already exists" +msgstr "Statistikobjekt »%s« existiert bereits" -#: commands/subscriptioncmds.c:566 commands/subscriptioncmds.c:574 +#: commands/statscmds.c:193 commands/statscmds.c:199 #, c-format -msgid "The error was: %s" -msgstr "Der Fehler war: %s" +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "in CREATE STATISTICS sind nur einfache Spaltenverweise erlaubt" -#: commands/subscriptioncmds.c:572 -#, fuzzy, c-format -#| msgid "%s: could not send replication command \"%s\": %s" -msgid "could not drop the replication slot \"%s\" on publisher" -msgstr "%s: konnte Replikationsbefehl »%s« nicht senden: %s" +#: commands/statscmds.c:214 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "Statistikerzeugung für Systemspalten wird nicht unterstützt" -#: commands/subscriptioncmds.c:577 -#, fuzzy, c-format -#| msgid "%s: dropping replication slot \"%s\"\n" -msgid "dropped replication slot \"%s\" on publisher" -msgstr "%s: lösche Replikations-Slot »%s«\n" +#: commands/statscmds.c:221 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "Spalte »%s« kann nicht in Statistiken verwendet werden, weil ihr Typ %s keine Standardoperatorklasse für btree hat" -#: commands/subscriptioncmds.c:616 +#: commands/statscmds.c:228 #, c-format -msgid "permission denied to change owner of subscription \"%s\"" -msgstr "keine Berechtigung, um Eigentümer der Subskription »%s« zu ändern" +msgid "cannot have more than %d columns in statistics" +msgstr "Statistiken können nicht mehr als %d Spalten enthalten" -#: commands/subscriptioncmds.c:618 +#: commands/statscmds.c:243 #, c-format -msgid "The owner of an subscription must be a superuser." -msgstr "Der Eigentümer einer Subskription muss ein Superuser sein." +msgid "extended statistics require at least 2 columns" +msgstr "erweiterte Statistiken benötigen mindestens 2 Spalten" -#: commands/tablecmds.c:221 commands/tablecmds.c:263 +#: commands/statscmds.c:261 #, c-format -msgid "table \"%s\" does not exist" -msgstr "Tabelle »%s« existiert nicht" +msgid "duplicate column name in statistics definition" +msgstr "doppelter Spaltenname in Statistikdefinition" -#: commands/tablecmds.c:222 commands/tablecmds.c:264 +#: commands/statscmds.c:289 #, c-format -msgid "table \"%s\" does not exist, skipping" -msgstr "Tabelle »%s« existiert nicht, wird übersprungen" +msgid "unrecognized statistics kind \"%s\"" +msgstr "unbekannte Statistikart »%s«" -#: commands/tablecmds.c:224 commands/tablecmds.c:266 -msgid "Use DROP TABLE to remove a table." -msgstr "Verwenden Sie DROP TABLE, um eine Tabelle zu löschen." +#: commands/subscriptioncmds.c:187 +#, c-format +msgid "unrecognized subscription parameter: %s" +msgstr "unbekannter Subskriptionsparameter: %s" -#: commands/tablecmds.c:227 +#: commands/subscriptioncmds.c:200 #, c-format -msgid "sequence \"%s\" does not exist" -msgstr "Sequenz »%s« existiert nicht" +msgid "connect = false and enabled = true are mutually exclusive options" +msgstr "die Optionen connect = false und enabled = true schließen einander aus" -#: commands/tablecmds.c:228 +#: commands/subscriptioncmds.c:205 #, c-format -msgid "sequence \"%s\" does not exist, skipping" -msgstr "Sequenz »%s« existiert nicht, wird übersprungen" +msgid "connect = false and create_slot = true are mutually exclusive options" +msgstr "die Optionen connect = false und create_slot = true schließen einander aus" -#: commands/tablecmds.c:230 -msgid "Use DROP SEQUENCE to remove a sequence." -msgstr "Verwenden Sie DROP SEQUENCE, um eine Sequenz zu löschen." +#: commands/subscriptioncmds.c:210 +#, c-format +msgid "connect = false and copy_data = true are mutually exclusive options" +msgstr "die Optionen connect = false und copy_data = true schließen einander aus" -#: commands/tablecmds.c:233 +#: commands/subscriptioncmds.c:227 #, c-format -msgid "view \"%s\" does not exist" -msgstr "Sicht »%s« existiert nicht" +msgid "slot_name = NONE and enabled = true are mutually exclusive options" +msgstr "die Optionen slot_name = NONE und enabled = true schließen einander aus" -#: commands/tablecmds.c:234 +#: commands/subscriptioncmds.c:232 #, c-format -msgid "view \"%s\" does not exist, skipping" -msgstr "Sicht »%s« existiert nicht, wird übersprungen" +msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +msgstr "die Optionen slot_name = NONE und create_slot = true schließen einander aus" -#: commands/tablecmds.c:236 -msgid "Use DROP VIEW to remove a view." -msgstr "Verwenden Sie DROP VIEW, um eine Sicht zu löschen." +#: commands/subscriptioncmds.c:237 +#, c-format +msgid "subscription with slot_name = NONE must also set enabled = false" +msgstr "Subskription mit slot_name = NONE muss auch enabled = false setzen" -#: commands/tablecmds.c:239 +#: commands/subscriptioncmds.c:242 #, c-format -msgid "materialized view \"%s\" does not exist" +msgid "subscription with slot_name = NONE must also set create_slot = false" +msgstr "Subskription mit slot_name = NONE muss auch create_slot = false setzen" + +#: commands/subscriptioncmds.c:283 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "Publikationsname »%s« mehrmals angegeben" + +#: commands/subscriptioncmds.c:347 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "nur Superuser können Subskriptionen erzeugen" + +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 +#: replication/logical/tablesync.c:856 replication/logical/worker.c:1722 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "konnte nicht mit dem Publikationsserver verbinden: %s" + +#: commands/subscriptioncmds.c:469 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "Replikations-Slot »%s« wurde auf dem Publikationsserver erzeugt" + +#: commands/subscriptioncmds.c:486 +#, c-format +msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" +msgstr "keine Tabellen wurden zur Subskription hinzugefügt; Sie müssen ALTER SUBSCRIPTION ... REFRESH PUBLICATION ausführen, um Tabellen zur Subskription hinzuzufügen" + +#: commands/subscriptioncmds.c:576 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "Tabelle »%s.%s« wurde zur Subskription »%s« hinzugefügt" + +#: commands/subscriptioncmds.c:600 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "Tabelle »%s.%s« wurde aus Subskription »%s« entfernt" + +#: commands/subscriptioncmds.c:669 +#, c-format +msgid "cannot set slot_name = NONE for enabled subscription" +msgstr "für eine aktivierte Subskription kann nicht slot_name = NONE gesetzt werden" + +#: commands/subscriptioncmds.c:703 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "eine Subskription ohne Slot-Name kann nicht aktiviert werden" + +#: commands/subscriptioncmds.c:749 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION mit Refresh ist für deaktivierte Subskriptionen nicht erlaubt" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:768 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH ist für eine deaktivierte Subskription nicht erlaubt" + +#: commands/subscriptioncmds.c:847 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "Subskription »%s« existiert nicht, wird übersprungen" + +#: commands/subscriptioncmds.c:972 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "konnte beim Versuch den Replikations-Slot »%s« zu löschen nicht mit dem Publikationsserver verbinden" + +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 +#: replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 +#, c-format +msgid "The error was: %s" +msgstr "Der Fehler war: %s" + +#: commands/subscriptioncmds.c:975 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." +msgstr "Verwenden Sie ALTER SUBSCRIPTION ... SET (slot_name = NONE), um die Subskription vom Slot zu trennen." + +#: commands/subscriptioncmds.c:986 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "konnte Replikations-Slot »%s« auf dem Publikationsserver nicht löschen" + +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "Replikations-Slot »%s« auf dem Publikationsserver wurde gelöscht" + +#: commands/subscriptioncmds.c:1032 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "keine Berechtigung, um Eigentümer der Subskription »%s« zu ändern" + +#: commands/subscriptioncmds.c:1034 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Der Eigentümer einer Subskription muss ein Superuser sein." + +#: commands/subscriptioncmds.c:1147 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "konnte Liste der replizierten Tabellen nicht vom Publikationsserver empfangen: %s" + +#: commands/tablecmds.c:223 commands/tablecmds.c:265 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "Tabelle »%s« existiert nicht" + +#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "Tabelle »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:226 commands/tablecmds.c:268 +msgid "Use DROP TABLE to remove a table." +msgstr "Verwenden Sie DROP TABLE, um eine Tabelle zu löschen." + +#: commands/tablecmds.c:229 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "Sequenz »%s« existiert nicht" + +#: commands/tablecmds.c:230 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "Sequenz »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:232 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Verwenden Sie DROP SEQUENCE, um eine Sequenz zu löschen." + +#: commands/tablecmds.c:235 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "Sicht »%s« existiert nicht" + +#: commands/tablecmds.c:236 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "Sicht »%s« existiert nicht, wird übersprungen" + +#: commands/tablecmds.c:238 +msgid "Use DROP VIEW to remove a view." +msgstr "Verwenden Sie DROP VIEW, um eine Sicht zu löschen." + +#: commands/tablecmds.c:241 +#, c-format +msgid "materialized view \"%s\" does not exist" msgstr "materialisierte Sicht »%s« existiert nicht" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:242 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "materialisierte Sicht »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Verwenden Sie DROP MATERIALIZED VIEW, um eine materialisierte Sicht zu löschen." -#: commands/tablecmds.c:245 parser/parse_utilcmd.c:1698 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:15449 +#: parser/parse_utilcmd.c:1982 #, c-format msgid "index \"%s\" does not exist" msgstr "Index »%s« existiert nicht" -#: commands/tablecmds.c:246 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "Index »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "Verwenden Sie DROP INDEX, um einen Index zu löschen." -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" msgstr "»%s« ist kein Typ" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "Verwenden Sie DROP TYPE, um einen Typen zu löschen." -#: commands/tablecmds.c:257 commands/tablecmds.c:9065 -#: commands/tablecmds.c:11904 +#: commands/tablecmds.c:259 commands/tablecmds.c:10271 +#: commands/tablecmds.c:13224 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "Fremdtabelle »%s« existiert nicht" -#: commands/tablecmds.c:258 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "Fremdtabelle »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:260 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Verwenden Sie DROP FOREIGN TABLE, um eine Fremdtabelle zu löschen." -#: commands/tablecmds.c:519 +#: commands/tablecmds.c:557 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT kann nur mit temporären Tabellen verwendet werden" -#: commands/tablecmds.c:547 +#: commands/tablecmds.c:585 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "kann temporäre Tabelle nicht in einer sicherheitsbeschränkten Operation erzeugen" -#: commands/tablecmds.c:646 -#, fuzzy, c-format -#| msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#: commands/tablecmds.c:686 +#, c-format msgid "cannot create table with OIDs as partition of table without OIDs" -msgstr "Tabelle »%s« ohne OIDs kann nicht von Tabelle »%s« mit OIDs erben" +msgstr "kann Tabelle mit OIDs nicht als Partition einer Tabelle ohne OIDs erzeugen" -#: commands/tablecmds.c:764 parser/parse_utilcmd.c:3040 -#, fuzzy, c-format -#| msgid "\"%s\" is not an index" +#: commands/tablecmds.c:810 +#, c-format msgid "\"%s\" is not partitioned" -msgstr "»%s« ist kein Index" +msgstr "»%s« ist nicht partitioniert" + +#: commands/tablecmds.c:891 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "Partitionierung kann nicht mehr als %d Spalten verwenden" -#: commands/tablecmds.c:972 +#: commands/tablecmds.c:1098 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY unterstützt das Löschen von mehreren Objekten nicht" -#: commands/tablecmds.c:976 +#: commands/tablecmds.c:1102 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY unterstützt kein CASCADE" -#: commands/tablecmds.c:1224 -#, fuzzy, c-format -#| msgid "column must be added to child tables too" -msgid "must truncate child tables too" -msgstr "Spalte muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" +#: commands/tablecmds.c:1401 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "kann nicht nur eine partitionierte Tabelle leeren" + +#: commands/tablecmds.c:1402 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "Lassen Sie das Schlüsselwort ONLY weg oder wenden Sie TRUNCATE ONLY direkt auf die Partitionen an." -#: commands/tablecmds.c:1252 +#: commands/tablecmds.c:1471 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "Truncate-Vorgang leert ebenfalls Tabelle »%s«" -#: commands/tablecmds.c:1500 +#: commands/tablecmds.c:1765 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht leeren" -#: commands/tablecmds.c:1731 commands/tablecmds.c:10648 -#, fuzzy, c-format -#| msgid "cannot insert into foreign table \"%s\"" +#: commands/tablecmds.c:2006 commands/tablecmds.c:11975 +#, c-format msgid "cannot inherit from partitioned table \"%s\"" -msgstr "kann nicht in Fremdtabelle »%s« einfügen" +msgstr "von partitionierter Tabelle »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:1736 -#, fuzzy, c-format -#| msgid "cannot inherit from temporary relation \"%s\"" +#: commands/tablecmds.c:2011 +#, c-format msgid "cannot inherit from partition \"%s\"" -msgstr "von temporärer Relation »%s« kann nicht geerbt werden" +msgstr "von Partition »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:1744 parser/parse_utilcmd.c:1909 +#: commands/tablecmds.c:2019 parser/parse_utilcmd.c:2199 +#: parser/parse_utilcmd.c:2322 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "geerbte Relation »%s« ist keine Tabelle oder Fremdtabelle" -#: commands/tablecmds.c:1752 commands/tablecmds.c:10627 +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "eine temporäre Relation kann nicht als Partition der permanenten Relation »%s« erzeugt werden" + +#: commands/tablecmds.c:2040 commands/tablecmds.c:11954 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "von temporärer Relation »%s« kann nicht geerbt werden" -#: commands/tablecmds.c:1762 commands/tablecmds.c:10635 +#: commands/tablecmds.c:2050 commands/tablecmds.c:11962 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "von temporärer Relation einer anderen Sitzung kann nicht geerbt werden" -#: commands/tablecmds.c:1779 commands/tablecmds.c:10746 +#: commands/tablecmds.c:2067 commands/tablecmds.c:12086 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "von der Relation »%s« würde mehrmals geerbt werden" -#: commands/tablecmds.c:1827 +#: commands/tablecmds.c:2116 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "geerbte Definitionen von Spalte »%s« werden zusammengeführt" -#: commands/tablecmds.c:1835 +#: commands/tablecmds.c:2124 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "geerbte Spalte »%s« hat Typkonflikt" -#: commands/tablecmds.c:1837 commands/tablecmds.c:1860 -#: commands/tablecmds.c:2065 commands/tablecmds.c:2089 -#: parser/parse_coerce.c:1650 parser/parse_coerce.c:1670 -#: parser/parse_coerce.c:1690 parser/parse_coerce.c:1736 -#: parser/parse_coerce.c:1775 parser/parse_param.c:218 +#: commands/tablecmds.c:2126 commands/tablecmds.c:2149 +#: commands/tablecmds.c:2354 commands/tablecmds.c:2384 +#: parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 +#: parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 +#: parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s gegen %s" -#: commands/tablecmds.c:1846 +#: commands/tablecmds.c:2135 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "geerbte Spalte »%s« hat Sortierfolgenkonflikt" -#: commands/tablecmds.c:1848 commands/tablecmds.c:2077 -#: commands/tablecmds.c:5092 +#: commands/tablecmds.c:2137 commands/tablecmds.c:2366 +#: commands/tablecmds.c:5446 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "»%s« gegen »%s«" -#: commands/tablecmds.c:1858 +#: commands/tablecmds.c:2147 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "geerbte Spalte »%s« hat einen Konflikt bei einem Storage-Parameter" -#: commands/tablecmds.c:1971 commands/tablecmds.c:8573 -#: parser/parse_utilcmd.c:993 parser/parse_utilcmd.c:1343 -#: parser/parse_utilcmd.c:1419 +#: commands/tablecmds.c:2260 commands/tablecmds.c:9699 +#: parser/parse_utilcmd.c:1116 parser/parse_utilcmd.c:1515 +#: parser/parse_utilcmd.c:1622 #, c-format msgid "cannot convert whole-row table reference" msgstr "kann Verweis auf ganze Zeile der Tabelle nicht umwandeln" -#: commands/tablecmds.c:1972 parser/parse_utilcmd.c:994 +#: commands/tablecmds.c:2261 parser/parse_utilcmd.c:1117 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "Constraint »%s« enthält einen Verweis auf die ganze Zeile der Tabelle »%s«." -#: commands/tablecmds.c:2051 +#: commands/tablecmds.c:2340 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "Spalte »%s« wird mit geerbter Definition zusammengeführt" -#: commands/tablecmds.c:2055 +#: commands/tablecmds.c:2344 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "Spalte »%s« wird verschoben und mit geerbter Definition zusammengeführt" -#: commands/tablecmds.c:2056 +#: commands/tablecmds.c:2345 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "Benutzerdefinierte Spalte wurde auf die Position der geerbten Spalte verschoben." -#: commands/tablecmds.c:2063 +#: commands/tablecmds.c:2352 #, c-format msgid "column \"%s\" has a type conflict" msgstr "für Spalte »%s« besteht ein Typkonflikt" -#: commands/tablecmds.c:2075 +#: commands/tablecmds.c:2364 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "für Spalte »%s« besteht ein Sortierfolgenkonflikt" -#: commands/tablecmds.c:2087 +#: commands/tablecmds.c:2382 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "für Spalte »%s« besteht ein Konflikt bei einem Storage-Parameter" -#: commands/tablecmds.c:2189 +#: commands/tablecmds.c:2485 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "Spalte »%s« erbt widersprüchliche Vorgabewerte" -#: commands/tablecmds.c:2191 +#: commands/tablecmds.c:2487 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Um den Konflikt zu lösen, geben Sie einen Vorgabewert ausdrücklich an." -#: commands/tablecmds.c:2238 +#: commands/tablecmds.c:2534 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "Check-Constraint-Name »%s« erscheint mehrmals, aber mit unterschiedlichen Ausdrücken" -#: commands/tablecmds.c:2437 +#: commands/tablecmds.c:2711 #, c-format msgid "cannot rename column of typed table" msgstr "Spalte einer getypten Tabelle kann nicht umbenannt werden" -#: commands/tablecmds.c:2455 +#: commands/tablecmds.c:2730 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, zusammengesetzter Typ, Index noch Fremdtabelle" -#: commands/tablecmds.c:2549 +#: commands/tablecmds.c:2824 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "vererbte Spalte »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" -#: commands/tablecmds.c:2581 +#: commands/tablecmds.c:2856 #, c-format msgid "cannot rename system column \"%s\"" msgstr "Systemspalte »%s« kann nicht umbenannt werden" -#: commands/tablecmds.c:2596 +#: commands/tablecmds.c:2871 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "kann vererbte Spalte »%s« nicht umbenennen" -#: commands/tablecmds.c:2748 +#: commands/tablecmds.c:3023 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "vererbter Constraint »%s« muss ebenso in den abgeleiteten Tabellen umbenannt werden" -#: commands/tablecmds.c:2755 +#: commands/tablecmds.c:3030 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "kann vererbten Constraint »%s« nicht umbenennen" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2979 +#: commands/tablecmds.c:3256 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "%s mit Relation »%s« nicht möglich, weil sie von aktiven Anfragen in dieser Sitzung verwendet wird" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2988 +#: commands/tablecmds.c:3266 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "%s mit Relation »%s« nicht möglich, weil es anstehende Trigger-Ereignisse dafür gibt" -#: commands/tablecmds.c:4087 +#: commands/tablecmds.c:4414 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "Systemrelation »%s« kann nicht neu geschrieben werden" -#: commands/tablecmds.c:4093 +#: commands/tablecmds.c:4420 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "Tabelle »%s«, die als Katalogtabelle verwendet wird, kann nicht neu geschrieben werden" -#: commands/tablecmds.c:4103 +#: commands/tablecmds.c:4430 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "kann temporäre Tabellen anderer Sitzungen nicht neu schreiben" -#: commands/tablecmds.c:4382 +#: commands/tablecmds.c:4707 #, c-format msgid "rewriting table \"%s\"" msgstr "schreibe Tabelle »%s« neu" -#: commands/tablecmds.c:4386 +#: commands/tablecmds.c:4711 #, c-format msgid "verifying table \"%s\"" msgstr "überprüfe Tabelle »%s«" -#: commands/tablecmds.c:4499 +#: commands/tablecmds.c:4827 #, c-format msgid "column \"%s\" contains null values" msgstr "Spalte »%s« enthält NULL-Werte" -#: commands/tablecmds.c:4514 commands/tablecmds.c:7844 +#: commands/tablecmds.c:4843 commands/tablecmds.c:8920 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "Check-Constraint »%s« wird von irgendeiner Zeile verletzt" -#: commands/tablecmds.c:4530 +#: commands/tablecmds.c:4861 #, fuzzy, c-format -#| msgid "check constraint \"%s\" is violated by some row" +#| msgid "partition constraint is violated by some row" +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "Partitions-Constraint wird von irgendeiner Zeile verletzt" + +#: commands/tablecmds.c:4865 +#, c-format msgid "partition constraint is violated by some row" -msgstr "Check-Constraint »%s« wird von irgendeiner Zeile verletzt" +msgstr "Partitions-Constraint wird von irgendeiner Zeile verletzt" -#: commands/tablecmds.c:4668 commands/trigger.c:245 -#: rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:906 +#: commands/tablecmds.c:5007 commands/trigger.c:310 rewrite/rewriteDefine.c:266 +#: rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" msgstr "»%s« ist keine Tabelle oder Sicht" -#: commands/tablecmds.c:4671 commands/trigger.c:1229 commands/trigger.c:1335 +#: commands/tablecmds.c:5010 commands/trigger.c:1520 commands/trigger.c:1626 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "»%s« ist keine Tabelle, Sicht oder Fremdtabelle" -#: commands/tablecmds.c:4674 +#: commands/tablecmds.c:5013 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht noch Index" -#: commands/tablecmds.c:4680 +#: commands/tablecmds.c:5019 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "»%s« ist weder Tabelle, materialisierte Sicht noch Index" -#: commands/tablecmds.c:4683 +#: commands/tablecmds.c:5022 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "»%s« ist weder Tabelle, materialisierte Sicht noch Fremdtabelle" -#: commands/tablecmds.c:4686 +#: commands/tablecmds.c:5025 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "»%s« ist keine Tabelle oder Fremdtabelle" -#: commands/tablecmds.c:4689 +#: commands/tablecmds.c:5028 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "»%s« ist weder Tabelle, Sicht, zusammengesetzter Typ noch Fremdtabelle" -#: commands/tablecmds.c:4692 commands/tablecmds.c:5814 +#: commands/tablecmds.c:5031 commands/tablecmds.c:6449 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "»%s« ist weder Tabelle, materialisierte Sicht, Index noch Fremdtabelle" -#: commands/tablecmds.c:4702 +#: commands/tablecmds.c:5041 #, c-format msgid "\"%s\" is of the wrong type" msgstr "»%s« hat den falschen Typ" -#: commands/tablecmds.c:4856 commands/tablecmds.c:4863 +#: commands/tablecmds.c:5216 commands/tablecmds.c:5223 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "kann Typ »%s« nicht ändern, weil Spalte »%s.%s« ihn verwendet" -#: commands/tablecmds.c:4870 +#: commands/tablecmds.c:5230 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "kann Fremdtabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" -#: commands/tablecmds.c:4877 +#: commands/tablecmds.c:5237 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "kann Tabelle »%s« nicht ändern, weil Spalte »%s.%s« ihren Zeilentyp verwendet" -#: commands/tablecmds.c:4939 +#: commands/tablecmds.c:5291 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "kann Typ »%s« nicht ändern, weil er der Typ einer getypten Tabelle ist" -#: commands/tablecmds.c:4941 +#: commands/tablecmds.c:5293 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "Verwenden Sie ALTER ... CASCADE, um die getypten Tabellen ebenfalls zu ändern." -#: commands/tablecmds.c:4985 +#: commands/tablecmds.c:5339 #, c-format msgid "type %s is not a composite type" msgstr "Typ %s ist kein zusammengesetzter Typ" -#: commands/tablecmds.c:5011 +#: commands/tablecmds.c:5365 #, c-format msgid "cannot add column to typed table" msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" -#: commands/tablecmds.c:5055 -#, fuzzy, c-format -#| msgid "cannot add column to typed table" +#: commands/tablecmds.c:5409 +#, c-format msgid "cannot add column to a partition" -msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" +msgstr "zu einer Partition kann keine Spalte hinzugefügt werden" -#: commands/tablecmds.c:5084 commands/tablecmds.c:10872 +#: commands/tablecmds.c:5438 commands/tablecmds.c:12213 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:5090 commands/tablecmds.c:10879 +#: commands/tablecmds.c:5444 commands/tablecmds.c:12220 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Sortierfolge für Spalte »%s«" -#: commands/tablecmds.c:5100 +#: commands/tablecmds.c:5454 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" msgstr "abgeleitete Tabelle »%s« hat eine widersprüchliche Spalte »%s«" -#: commands/tablecmds.c:5111 +#: commands/tablecmds.c:5465 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "Definition von Spalte »%s« für abgeleitete Tabelle »%s« wird zusammengeführt" -#: commands/tablecmds.c:5335 +#: commands/tablecmds.c:5489 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "eine Identitätsspalte kann nicht rekursiv zu einer Tabelle hinzugefügt werden, die abgeleitete Tabellen hat" + +#: commands/tablecmds.c:5738 #, c-format msgid "column must be added to child tables too" msgstr "Spalte muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" -#: commands/tablecmds.c:5410 +#: commands/tablecmds.c:5813 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "Spalte »%s« von Relation »%s« existiert bereits, wird übersprungen" -#: commands/tablecmds.c:5417 +#: commands/tablecmds.c:5820 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "Spalte »%s« von Relation »%s« existiert bereits" -#: commands/tablecmds.c:5511 commands/tablecmds.c:8246 -#, fuzzy, c-format -#| msgid "constraint must be added to child tables too" -msgid "constraint must be dropped from child tables too" -msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" +#: commands/tablecmds.c:5918 commands/tablecmds.c:9379 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "Constraint kann nicht nur von der partitionierten Tabelle entfernt werden, wenn Partitionen existieren" + +#: commands/tablecmds.c:5919 commands/tablecmds.c:6063 +#: commands/tablecmds.c:6847 commands/tablecmds.c:9380 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "Lassen Sie das Schlüsselwort ONLY weg." -#: commands/tablecmds.c:5542 commands/tablecmds.c:5703 -#: commands/tablecmds.c:5758 commands/tablecmds.c:5873 -#: commands/tablecmds.c:5927 commands/tablecmds.c:6019 -#: commands/tablecmds.c:8395 commands/tablecmds.c:9088 +#: commands/tablecmds.c:5951 commands/tablecmds.c:6099 +#: commands/tablecmds.c:6154 commands/tablecmds.c:6230 +#: commands/tablecmds.c:6324 commands/tablecmds.c:6383 +#: commands/tablecmds.c:6533 commands/tablecmds.c:6603 +#: commands/tablecmds.c:6695 commands/tablecmds.c:9519 +#: commands/tablecmds.c:10294 #, c-format msgid "cannot alter system column \"%s\"" msgstr "Systemspalte »%s« kann nicht geändert werden" -#: commands/tablecmds.c:5578 +#: commands/tablecmds.c:5957 commands/tablecmds.c:6160 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "Spalte »%s« von Relation »%s« ist eine Identitätsspalte" + +#: commands/tablecmds.c:5993 #, c-format msgid "column \"%s\" is in a primary key" msgstr "Spalte »%s« ist in einem Primärschlüssel" -#: commands/tablecmds.c:5600 -#, fuzzy, c-format -#| msgid "column \"%s\" in child table must be marked NOT NULL" +#: commands/tablecmds.c:6015 +#, c-format msgid "column \"%s\" is marked NOT NULL in parent table" -msgstr "Spalte »%s« in abgeleiteter Tabelle muss als NOT NULL markiert sein" +msgstr "Spalte »%s« ist in Elterntabelle als NOT NULL markiert" -#: commands/tablecmds.c:5625 -#, fuzzy, c-format -#| msgid "column \"%s\" is in a primary key" -msgid "column \"%s\" is in range partition key" -msgstr "Spalte »%s« ist in einem Primärschlüssel" +#: commands/tablecmds.c:6062 +#, c-format +msgid "cannot add constraint to only the partitioned table when partitions exist" +msgstr "Constraint kann nicht nur zu der partitionierten Tabelle hinzugefügt werden, wenn Partitionen existieren" -#: commands/tablecmds.c:5672 commands/tablecmds.c:6659 +#: commands/tablecmds.c:6162 #, c-format -msgid "constraint must be added to child tables too" -msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Verwenden Sie stattdessen ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." + +#: commands/tablecmds.c:6241 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "Spalte »%s« von Relation »%s« muss als NOT NULL deklariert werden, bevor Sie Identitätsspalte werden kann" + +#: commands/tablecmds.c:6247 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "Spalte »%s« von Relation »%s« ist bereits eine Identitätsspalte" + +#: commands/tablecmds.c:6253 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "Spalte »%s« von Relation »%s« hat bereits einen Vorgabewert" -#: commands/tablecmds.c:5846 +#: commands/tablecmds.c:6330 commands/tablecmds.c:6391 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte" + +#: commands/tablecmds.c:6396 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "Spalte »%s« von Relation »%s« ist keine Identitätsspalte, wird übersprungen" + +#: commands/tablecmds.c:6461 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "" + +#: commands/tablecmds.c:6492 #, c-format msgid "statistics target %d is too low" msgstr "Statistikziel %d ist zu niedrig" -#: commands/tablecmds.c:5854 +#: commands/tablecmds.c:6500 #, c-format msgid "lowering statistics target to %d" msgstr "setze Statistikziel auf %d herab" -#: commands/tablecmds.c:5999 +#: commands/tablecmds.c:6523 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "Spalte Nummer %d von Relation »%s« existiert nicht" + +#: commands/tablecmds.c:6542 +#, fuzzy, c-format +#| msgid "cannot insert into column \"%s\" of view \"%s\"" +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "kann nicht in Spalte »%s« von Sicht »%s« einfügen" + +#: commands/tablecmds.c:6547 +#, fuzzy, c-format +#| msgid "cannot insert into column \"%s\" of view \"%s\"" +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "kann nicht in Spalte »%s« von Sicht »%s« einfügen" + +#: commands/tablecmds.c:6549 +#, fuzzy, c-format +#| msgid "Collects statistics on database activity." +msgid "Alter statistics on table column instead." +msgstr "Sammelt Statistiken über Datenbankaktivität." + +#: commands/tablecmds.c:6675 #, c-format msgid "invalid storage type \"%s\"" msgstr "ungültiger Storage-Typ »%s«" -#: commands/tablecmds.c:6031 +#: commands/tablecmds.c:6707 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "Spaltendatentyp %s kann nur Storage-Typ PLAIN" -#: commands/tablecmds.c:6066 +#: commands/tablecmds.c:6742 #, c-format msgid "cannot drop column from typed table" msgstr "aus einer getypten Tabelle können keine Spalten gelöscht werden" -#: commands/tablecmds.c:6173 +#: commands/tablecmds.c:6787 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Spalte »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:6186 +#: commands/tablecmds.c:6800 #, c-format msgid "cannot drop system column \"%s\"" msgstr "Systemspalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:6193 +#: commands/tablecmds.c:6807 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "geerbte Spalte »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:6202 -#, fuzzy, c-format -#| msgid "cannot drop column from typed table" +#: commands/tablecmds.c:6818 +#, c-format msgid "cannot drop column named in partition key" -msgstr "aus einer getypten Tabelle können keine Spalten gelöscht werden" +msgstr "eine im Partitionierungsschlüssel verwendete Spalte kann nicht gelöscht werden" -#: commands/tablecmds.c:6206 -#, fuzzy, c-format -#| msgid "cannot use column references in default expression" +#: commands/tablecmds.c:6822 +#, c-format msgid "cannot drop column referenced in partition key expression" -msgstr "Spaltenverweise können nicht in Vorgabeausdrücken verwendet werden" +msgstr "eine im Partitionierungsschlüsselausdruck verwendete Spalte kann nicht gelöscht werden" -#: commands/tablecmds.c:6230 -#, fuzzy, c-format -#| msgid "column must be added to child tables too" -msgid "column must be dropped from child tables too" -msgstr "Spalte muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" +#: commands/tablecmds.c:6846 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "Spalte kann nicht nur aus der partitionierten Tabelle gelöscht werden, wenn Partitionen existieren" + +#: commands/tablecmds.c:7051 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX wird für partitionierte Tabellen nicht unterstützt" -#: commands/tablecmds.c:6446 +#: commands/tablecmds.c:7076 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX benennt Index »%s« um in »%s«" -#: commands/tablecmds.c:6730 -#, fuzzy, c-format -#| msgid "cannot insert into foreign table \"%s\"" +#: commands/tablecmds.c:7292 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "Constraint muss ebenso in den abgeleiteten Tabellen hinzugefügt werden" + +#: commands/tablecmds.c:7365 +#, c-format msgid "cannot reference partitioned table \"%s\"" -msgstr "kann nicht in Fremdtabelle »%s« einfügen" +msgstr "Fremdschlüssel kann nicht auf partitionierte Tabelle »%s« verweisen" + +#: commands/tablecmds.c:7373 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\"" +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "kann keinen Index für partitionierte Tabelle »%s« erzeugen" + +#: commands/tablecmds.c:7379 +#, fuzzy, c-format +#| msgid "cannot rewrite system relation \"%s\"" +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "Systemrelation »%s« kann nicht neu geschrieben werden" + +#: commands/tablecmds.c:7382 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Dieses Feature wird für partitionierte Tabellen noch nicht unterstützt." -#: commands/tablecmds.c:6736 +#: commands/tablecmds.c:7388 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle" -#: commands/tablecmds.c:6759 +#: commands/tablecmds.c:7411 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "Constraints für permanente Tabellen dürfen nur auf permanente Tabellen verweisen" -#: commands/tablecmds.c:6766 +#: commands/tablecmds.c:7418 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "Constraints für ungeloggte Tabellen dürfen nur auf permanente oder ungeloggte Tabellen verweisen" -#: commands/tablecmds.c:6772 +#: commands/tablecmds.c:7424 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "Constraints für temporäre Tabellen dürfen nur auf temporäre Tabellen verweisen" -#: commands/tablecmds.c:6776 +#: commands/tablecmds.c:7428 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "Constraints für temporäre Tabellen müssen temporäre Tabellen dieser Sitzung beinhalten" -#: commands/tablecmds.c:6837 +#: commands/tablecmds.c:7488 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "Anzahl der Quell- und Zielspalten im Fremdschlüssel stimmt nicht überein" -#: commands/tablecmds.c:6944 +#: commands/tablecmds.c:7595 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "Fremdschlüssel-Constraint »%s« kann nicht implementiert werden" -#: commands/tablecmds.c:6947 +#: commands/tablecmds.c:7598 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "Schlüsselspalten »%s« und »%s« haben inkompatible Typen: %s und %s." -#: commands/tablecmds.c:7153 commands/tablecmds.c:7319 -#: commands/tablecmds.c:8225 commands/tablecmds.c:8291 +#: commands/tablecmds.c:8220 commands/tablecmds.c:8385 +#: commands/tablecmds.c:9336 commands/tablecmds.c:9411 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "Constraint »%s« von Relation »%s« existiert nicht" -#: commands/tablecmds.c:7159 +#: commands/tablecmds.c:8227 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel-Constraint" -#: commands/tablecmds.c:7326 +#: commands/tablecmds.c:8393 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "Constraint »%s« von Relation »%s« ist kein Fremdschlüssel- oder Check-Constraint" -#: commands/tablecmds.c:7395 +#: commands/tablecmds.c:8463 #, c-format msgid "constraint must be validated on child tables too" msgstr "Constraint muss ebenso in den abgeleiteten Tabellen validiert werden" -#: commands/tablecmds.c:7463 +#: commands/tablecmds.c:8531 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "Spalte »%s«, die im Fremdschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:7468 +#: commands/tablecmds.c:8536 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "Fremdschlüssel kann nicht mehr als %d Schlüssel haben" -#: commands/tablecmds.c:7533 +#: commands/tablecmds.c:8601 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "aufschiebbarer Primärschlüssel kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:7550 +#: commands/tablecmds.c:8618 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Primärschlüssel" -#: commands/tablecmds.c:7615 +#: commands/tablecmds.c:8683 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "die Liste der Spalten, auf die ein Fremdschlüssel verweist, darf keine doppelten Einträge enthalten" -#: commands/tablecmds.c:7709 +#: commands/tablecmds.c:8777 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "aufschiebbarer Unique-Constraint kann nicht für Tabelle »%s«, auf die verwiesen wird, verwendet werden" -#: commands/tablecmds.c:7714 +#: commands/tablecmds.c:8782 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "in Tabelle »%s«, auf die verwiesen wird, gibt es keinen Unique-Constraint, der auf die angegebenen Schlüssel passt" -#: commands/tablecmds.c:7877 +#: commands/tablecmds.c:8953 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "validiere Fremdschlüssel-Constraint »%s«" -#: commands/tablecmds.c:8179 +#: commands/tablecmds.c:9292 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "geerbter Constraint »%s« von Relation »%s« kann nicht gelöscht werden" -#: commands/tablecmds.c:8231 +#: commands/tablecmds.c:9342 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Constraint »%s« von Relation »%s« existiert nicht, wird übersprungen" -#: commands/tablecmds.c:8379 +#: commands/tablecmds.c:9503 #, c-format msgid "cannot alter column type of typed table" msgstr "Spaltentyp einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:8402 +#: commands/tablecmds.c:9526 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "kann vererbte Spalte »%s« nicht ändern" -#: commands/tablecmds.c:8411 -#, fuzzy, c-format -#| msgid "cannot alter type of a column used in a trigger definition" +#: commands/tablecmds.c:9537 +#, c-format msgid "cannot alter type of column named in partition key" -msgstr "Typ einer Spalte, die in einer Trigger-Definition verwendet wird, kann nicht geändert werden" +msgstr "Typ einer Spalte, die im Partitionierungschlüssel verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:8415 -#, fuzzy, c-format -#| msgid "cannot use column references in default expression" +#: commands/tablecmds.c:9541 +#, c-format msgid "cannot alter type of column referenced in partition key expression" -msgstr "Spaltenverweise können nicht in Vorgabeausdrücken verwendet werden" +msgstr "Typ einer Spalte, die im Partitionierungschlüsselausdruck verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:8465 +#: commands/tablecmds.c:9591 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "Ergebnis der USING-Klausel für Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:8468 +#: commands/tablecmds.c:9594 #, c-format msgid "You might need to add an explicit cast." msgstr "Sie müssen möglicherweise eine ausdrückliche Typumwandlung hinzufügen." -#: commands/tablecmds.c:8472 +#: commands/tablecmds.c:9598 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:8475 +#: commands/tablecmds.c:9601 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Sie müssen möglicherweise »USING %s::%s« angeben." -#: commands/tablecmds.c:8574 +#: commands/tablecmds.c:9700 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "USING-Ausdruck enthält einen Verweis auf die ganze Zeile der Tabelle." -#: commands/tablecmds.c:8585 +#: commands/tablecmds.c:9711 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "Typ der vererbten Spalte »%s« muss ebenso in den abgeleiteten Tabellen geändert werden" -#: commands/tablecmds.c:8672 +#: commands/tablecmds.c:9815 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "Typ der Spalte »%s« kann nicht zweimal geändert werden" -#: commands/tablecmds.c:8708 +#: commands/tablecmds.c:9851 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "Vorgabewert der Spalte »%s« kann nicht automatisch in Typ %s umgewandelt werden" -#: commands/tablecmds.c:8834 +#: commands/tablecmds.c:9957 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "Typ einer Spalte, die von einer Sicht oder Regel verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:8835 commands/tablecmds.c:8854 -#: commands/tablecmds.c:8872 +#: commands/tablecmds.c:9958 commands/tablecmds.c:9977 +#: commands/tablecmds.c:9995 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s hängt von Spalte »%s« ab" -#: commands/tablecmds.c:8853 +#: commands/tablecmds.c:9976 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "Typ einer Spalte, die in einer Trigger-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:8871 +#: commands/tablecmds.c:9994 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "Typ einer Spalte, die in einer Policy-Definition verwendet wird, kann nicht geändert werden" -#: commands/tablecmds.c:9528 +#: commands/tablecmds.c:10797 commands/tablecmds.c:10809 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "kann Eigentümer des Index »%s« nicht ändern" -#: commands/tablecmds.c:9530 +#: commands/tablecmds.c:10799 commands/tablecmds.c:10811 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "Ändern Sie stattdessen den Eigentümer der Tabelle des Index." -#: commands/tablecmds.c:9546 +#: commands/tablecmds.c:10825 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "kann Eigentümer der Sequenz »%s« nicht ändern" -#: commands/tablecmds.c:9548 commands/tablecmds.c:12123 -#, c-format -msgid "Sequence \"%s\" is linked to table \"%s\"." -msgstr "Sequenz »%s« ist mit Tabelle »%s« verknüpft." - -#: commands/tablecmds.c:9560 commands/tablecmds.c:12770 +#: commands/tablecmds.c:10839 commands/tablecmds.c:14123 #, c-format msgid "Use ALTER TYPE instead." msgstr "Verwenden Sie stattdessen ALTER TYPE." -#: commands/tablecmds.c:9569 +#: commands/tablecmds.c:10848 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "»%s« ist keine Tabelle, Sicht, Sequenz oder Fremdtabelle" -#: commands/tablecmds.c:9910 +#: commands/tablecmds.c:11188 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "mehrere SET TABLESPACE Unterbefehle sind ungültig" -#: commands/tablecmds.c:9984 +#: commands/tablecmds.c:11263 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, Index noch TOAST-Tabelle" -#: commands/tablecmds.c:10017 commands/view.c:504 +#: commands/tablecmds.c:11296 commands/view.c:508 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION wird nur für automatisch aktualisierbare Sichten unterstützt" -#: commands/tablecmds.c:10159 +#: commands/tablecmds.c:11438 #, c-format msgid "cannot move system relation \"%s\"" msgstr "Systemrelation »%s« kann nicht verschoben werden" -#: commands/tablecmds.c:10175 +#: commands/tablecmds.c:11454 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "temporäre Tabellen anderer Sitzungen können nicht verschoben werden" -#: commands/tablecmds.c:10311 +#: commands/tablecmds.c:11645 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "nur Tabellen, Indexe und materialisierte Sichten existieren in Tablespaces" -#: commands/tablecmds.c:10323 +#: commands/tablecmds.c:11657 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "Relationen können nicht in den oder aus dem Tablespace »pg_global« verschoben werden" -#: commands/tablecmds.c:10415 +#: commands/tablecmds.c:11750 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "Abbruch weil Sperre für Relation »%s.%s« nicht verfügbar ist" -#: commands/tablecmds.c:10431 +#: commands/tablecmds.c:11766 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "keine passenden Relationen in Tablespace »%s« gefunden" -#: commands/tablecmds.c:10505 storage/buffer/bufmgr.c:915 +#: commands/tablecmds.c:11833 storage/buffer/bufmgr.c:915 #, c-format msgid "invalid page in block %u of relation %s" msgstr "ungültige Seite in Block %u von Relation %s" -#: commands/tablecmds.c:10587 +#: commands/tablecmds.c:11913 #, c-format msgid "cannot change inheritance of typed table" msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:10592 commands/tablecmds.c:11120 -#, fuzzy, c-format -#| msgid "cannot change inheritance of typed table" +#: commands/tablecmds.c:11918 commands/tablecmds.c:12461 +#, c-format msgid "cannot change inheritance of a partition" -msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" +msgstr "Vererbung einer Partition kann nicht geändert werden" -#: commands/tablecmds.c:10597 -#, fuzzy, c-format -#| msgid "cannot change inheritance of typed table" +#: commands/tablecmds.c:11923 +#, c-format msgid "cannot change inheritance of partitioned table" -msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" +msgstr "Vererbung einer partitionierten Tabelle kann nicht geändert werden" -#: commands/tablecmds.c:10642 +#: commands/tablecmds.c:11969 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" -#: commands/tablecmds.c:10655 -#, fuzzy, c-format -#| msgid "cannot inherit from temporary relation \"%s\"" +#: commands/tablecmds.c:11982 +#, c-format msgid "cannot inherit from a partition" -msgstr "von temporärer Relation »%s« kann nicht geerbt werden" +msgstr "von einer Partition kann nicht geerbt werden" -#: commands/tablecmds.c:10677 commands/tablecmds.c:13122 +#: commands/tablecmds.c:12004 commands/tablecmds.c:14707 #, c-format msgid "circular inheritance not allowed" msgstr "zirkuläre Vererbung ist nicht erlaubt" -#: commands/tablecmds.c:10678 commands/tablecmds.c:13123 +#: commands/tablecmds.c:12005 commands/tablecmds.c:14708 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "»%s« ist schon von »%s« abgeleitet." -#: commands/tablecmds.c:10686 +#: commands/tablecmds.c:12013 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" msgstr "Tabelle »%s« ohne OIDs kann nicht von Tabelle »%s« mit OIDs erben" -#: commands/tablecmds.c:10890 +#: commands/tablecmds.c:12026 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "Trigger »%s« verhindert, dass Tabelle »%s« ein Vererbungskind werden kann" + +#: commands/tablecmds.c:12028 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" +msgstr "ROW-Trigger mit Übergangstabellen werden in Vererbungshierarchien nicht unterstützt" + +#: commands/tablecmds.c:12231 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "Spalte »%s« in abgeleiteter Tabelle muss als NOT NULL markiert sein" -#: commands/tablecmds.c:10917 commands/tablecmds.c:10956 +#: commands/tablecmds.c:12258 commands/tablecmds.c:12297 #, c-format msgid "child table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:11044 +#: commands/tablecmds.c:12385 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "abgeleitete Tabelle »%s« hat unterschiedliche Definition für Check-Constraint »%s«" -#: commands/tablecmds.c:11052 +#: commands/tablecmds.c:12393 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit nicht vererbtem Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:11063 +#: commands/tablecmds.c:12404 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "Constraint »%s« kollidiert mit NOT-VALID-Constraint für abgeleitete Tabelle »%s«" -#: commands/tablecmds.c:11098 +#: commands/tablecmds.c:12439 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "Constraint »%s« fehlt in abgeleiteter Tabelle" -#: commands/tablecmds.c:11214 -#, fuzzy, c-format -#| msgid "relation \"%s\" is not a parent of relation \"%s\"" +#: commands/tablecmds.c:12528 +#, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" -msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" +msgstr "Relation »%s« ist keine Partition von Relation »%s«" -#: commands/tablecmds.c:11220 +#: commands/tablecmds.c:12534 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "Relation »%s« ist keine Basisrelation von Relation »%s«" -#: commands/tablecmds.c:11444 +#: commands/tablecmds.c:12760 #, c-format msgid "typed tables cannot inherit" msgstr "getypte Tabellen können nicht erben" -#: commands/tablecmds.c:11475 +#: commands/tablecmds.c:12791 #, c-format msgid "table is missing column \"%s\"" msgstr "Spalte »%s« fehlt in Tabelle" -#: commands/tablecmds.c:11485 +#: commands/tablecmds.c:12802 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "Tabelle hat Spalte »%s«, aber Typ benötigt »%s«" -#: commands/tablecmds.c:11494 +#: commands/tablecmds.c:12811 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "Tabelle »%s« hat unterschiedlichen Typ für Spalte »%s«" -#: commands/tablecmds.c:11507 +#: commands/tablecmds.c:12825 #, c-format msgid "table has extra column \"%s\"" msgstr "Tabelle hat zusätzliche Spalte »%s«" -#: commands/tablecmds.c:11558 +#: commands/tablecmds.c:12877 #, c-format msgid "\"%s\" is not a typed table" msgstr "»%s« ist keine getypte Tabelle" -#: commands/tablecmds.c:11739 +#: commands/tablecmds.c:13059 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "nicht eindeutiger Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:11745 +#: commands/tablecmds.c:13065 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil er nicht IMMEDIATE ist" -#: commands/tablecmds.c:11751 +#: commands/tablecmds.c:13071 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "Ausdrucksindex »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:11757 +#: commands/tablecmds.c:13077 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "partieller Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:11763 +#: commands/tablecmds.c:13083 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "ungültiger Index »%s« kann nicht als Replik-Identität verwendet werden" -#: commands/tablecmds.c:11784 +#: commands/tablecmds.c:13104 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte %d eine Systemspalte ist" -#: commands/tablecmds.c:11791 +#: commands/tablecmds.c:13111 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "Index »%s« kann nicht als Replik-Identität verwendet werden, weil Spalte »%s« NULL-Werte akzeptiert" -#: commands/tablecmds.c:11984 +#: commands/tablecmds.c:13304 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "kann den geloggten Status der Tabelle »%s« nicht ändern, weil sie temporär ist" -#: commands/tablecmds.c:12008 -#, fuzzy, c-format +#: commands/tablecmds.c:13328 +#, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "kann Tabelle »%s« nicht in ungeloggt ändern, weil sie Teil einer Publikation ist" -#: commands/tablecmds.c:12010 +#: commands/tablecmds.c:13330 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Ungeloggte Relationen können nicht repliziert werden." -#: commands/tablecmds.c:12055 +#: commands/tablecmds.c:13375 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in geloggt ändern, weil sie auf die ungeloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:12065 +#: commands/tablecmds.c:13385 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "konnte Tabelle »%s« nicht in ungeloggt ändern, weil sie auf die geloggte Tabelle »%s« verweist" -#: commands/tablecmds.c:12122 +#: commands/tablecmds.c:13443 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "einer Tabelle zugeordnete Sequenz kann nicht in ein anderes Schema verschoben werden" -#: commands/tablecmds.c:12228 +#: commands/tablecmds.c:13549 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "Relation »%s« existiert bereits in Schema »%s«" -#: commands/tablecmds.c:12754 +#: commands/tablecmds.c:14106 #, c-format msgid "\"%s\" is not a composite type" msgstr "»%s« ist kein zusammengesetzter Typ" -#: commands/tablecmds.c:12785 +#: commands/tablecmds.c:14138 #, c-format msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" msgstr "»%s« ist weder Tabelle, Sicht, materialisierte Sicht, Sequenz noch Fremdtabelle" -#: commands/tablecmds.c:12816 -#, fuzzy, c-format -#| msgid "unrecognized privilege type \"%s\"" +#: commands/tablecmds.c:14173 +#, c-format msgid "unrecognized partitioning strategy \"%s\"" -msgstr "unbekannter Privilegtyp »%s«" +msgstr "unbekannte Partitionierungsstrategie »%s«" -#: commands/tablecmds.c:12842 -#, fuzzy, c-format -#| msgid "common column name \"%s\" appears more than once in right table" -msgid "column \"%s\" appears more than once in partition key" -msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der rechten Tabelle" +#: commands/tablecmds.c:14181 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "Partitionierungsstrategie »list« kann nicht mit mehr als einer Spalte verwendet werden" -#: commands/tablecmds.c:12890 -#, fuzzy, c-format -#| msgid "column \"%s\" named in key does not exist" +#: commands/tablecmds.c:14246 +#, c-format msgid "column \"%s\" named in partition key does not exist" -msgstr "Spalte »%s«, die im Schlüssel verwendet wird, existiert nicht" +msgstr "Spalte »%s«, die im Partitionierungsschlüssel verwendet wird, existiert nicht" -#: commands/tablecmds.c:12897 -#, fuzzy, c-format -#| msgid "cannot alter system column \"%s\"" +#: commands/tablecmds.c:14253 +#, c-format msgid "cannot use system column \"%s\" in partition key" -msgstr "Systemspalte »%s« kann nicht geändert werden" +msgstr "Systemspalte »%s« kann nicht im Partitionierungsschlüssel verwendet werden" -#: commands/tablecmds.c:12955 -#, fuzzy, c-format -#| msgid "functions in index expression must be marked IMMUTABLE" +#: commands/tablecmds.c:14316 +#, c-format msgid "functions in partition key expression must be marked IMMUTABLE" -msgstr "Funktionen im Indexausdruck müssen als IMMUTABLE markiert sein" +msgstr "Funktionen im Partitionierungsschlüsselausdruck müssen als IMMUTABLE markiert sein" -#: commands/tablecmds.c:12964 -#, fuzzy, c-format -#| msgid "cannot use expression index \"%s\" as replica identity" -msgid "cannot use constant expression as partition key" -msgstr "Ausdrucksindex »%s« kann nicht als Replik-Identität verwendet werden" - -#: commands/tablecmds.c:12978 -#, fuzzy, c-format -#| msgid "USING expression contains a whole-row table reference." +#: commands/tablecmds.c:14333 +#, c-format msgid "partition key expressions cannot contain whole-row references" -msgstr "USING-Ausdruck enthält einen Verweis auf die ganze Zeile der Tabelle." +msgstr "Partitionierungsschlüsselausdruck kann nicht Verweis auf die ganze Zeile der Tabelle enthalten" -#: commands/tablecmds.c:12999 -#, fuzzy, c-format -#| msgid "could not determine which collation to use for index expression" -msgid "could not determine which collation to use for partition expression" -msgstr "konnte die für den Indexausdruck zu verwendende Sortierfolge nicht bestimmen" +#: commands/tablecmds.c:14340 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "Partitionierungsschlüsselausdruck kann nicht auf Systemspalten verweisen" -#: commands/tablecmds.c:13024 -#, fuzzy, c-format -#| msgid "data type %s has no default operator class for access method \"%s\"" -msgid "data type %s has no default btree operator class" -msgstr "Datentyp %s hat keine Standardoperatorklasse für Zugriffsmethode »%s«" +#: commands/tablecmds.c:14350 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "Partitionierungsschlüssel kann kein konstanter Ausdruck sein" -#: commands/tablecmds.c:13026 -#, fuzzy, c-format -#| msgid "You must specify an operator class for the index or define a default operator class for the data type." +#: commands/tablecmds.c:14371 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "konnte die für den Partitionierungsausdruck zu verwendende Sortierfolge nicht bestimmen" + +#: commands/tablecmds.c:14404 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "Datentyp %s hat keine Standardoperatorklasse für hash" + +#: commands/tablecmds.c:14406 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Sie müssen eine hash-Operatorklasse angeben oder eine hash-Standardoperatorklasse für den Datentyp definieren." + +#: commands/tablecmds.c:14410 +#, c-format +msgid "data type %s has no default btree operator class" +msgstr "Datentyp %s hat keine Standardoperatorklasse für btree" + +#: commands/tablecmds.c:14412 +#, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." -msgstr "Sie müssen für den Index eine Operatorklasse angeben oder eine Standardoperatorklasse für den Datentyp definieren." +msgstr "Sie müssen eine btree-Operatorklasse angeben oder eine btree-Standardoperatorklasse für den Datentyp definieren." -#: commands/tablecmds.c:13073 +#: commands/tablecmds.c:14537 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "Partitions-Constraint für Tabelle »%s« ist schon in bestehenden Constraints inbegriffen" + +#: commands/tablecmds.c:14541 partitioning/partbounds.c:621 +#: partitioning/partbounds.c:666 #, fuzzy, c-format -#| msgid "\"%s\" is already a view" +#| msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "Partitions-Constraint für Tabelle »%s« ist schon in bestehenden Constraints inbegriffen" + +#: commands/tablecmds.c:14647 +#, c-format msgid "\"%s\" is already a partition" -msgstr "»%s« ist bereits eine Sicht" +msgstr "»%s« ist bereits eine Partition" -#: commands/tablecmds.c:13079 -#, fuzzy, c-format -#| msgid "cannot add column to typed table" +#: commands/tablecmds.c:14653 +#, c-format msgid "cannot attach a typed table as partition" -msgstr "zu einer getypten Tabelle kann keine Spalte hinzugefügt werden" +msgstr "eine getypte Tabelle kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:13095 +#: commands/tablecmds.c:14669 #, c-format msgid "cannot attach inheritance child as partition" -msgstr "" +msgstr "ein Vererbungskind kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:13109 -#, fuzzy, c-format -#| msgid "cannot change inheritance of typed table" +#: commands/tablecmds.c:14683 +#, c-format msgid "cannot attach inheritance parent as partition" -msgstr "Vererbung einer getypten Tabelle kann nicht geändert werden" +msgstr "eine Tabelle mit abgeleiteten Tabellen kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:13132 -#, fuzzy, c-format -#| msgid "cannot inherit from temporary relation \"%s\"" +#: commands/tablecmds.c:14717 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "eine temporäre Relation kann nicht als Partition an permanente Relation »%s« angefügt werden" + +#: commands/tablecmds.c:14725 +#, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" -msgstr "von temporärer Relation »%s« kann nicht geerbt werden" +msgstr "eine permanente Relation kann nicht als Partition an temporäre Relation »%s« angefügt werden" -#: commands/tablecmds.c:13140 -#, fuzzy, c-format -#| msgid "cannot inherit to temporary relation of another session" +#: commands/tablecmds.c:14733 +#, c-format msgid "cannot attach as partition of temporary relation of another session" -msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" +msgstr "kann nicht als Partition an temporäre Relation einer anderen Sitzung anfügen" -#: commands/tablecmds.c:13147 -#, fuzzy, c-format -#| msgid "cannot inherit to temporary relation of another session" +#: commands/tablecmds.c:14740 +#, c-format msgid "cannot attach temporary relation of another session as partition" -msgstr "an temporäre Relation einer anderen Sitzung kann nicht vererbt werden" +msgstr "temporäre Relation einer anderen Sitzung kann nicht als Partition angefügt werden" -#: commands/tablecmds.c:13153 -#, fuzzy, c-format -#| msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#: commands/tablecmds.c:14746 +#, c-format msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" -msgstr "Tabelle »%s« ohne OIDs kann nicht von Tabelle »%s« mit OIDs erben" +msgstr "kann Tabelle »%s« ohne OIDs nicht als Partition an Tabelle »%s« mit OIDs anfügen" -#: commands/tablecmds.c:13161 -#, fuzzy, c-format -#| msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#: commands/tablecmds.c:14754 +#, c-format msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" -msgstr "Tabelle »%s« ohne OIDs kann nicht von Tabelle »%s« mit OIDs erben" +msgstr "kann Tabelle »%s« mit OIDs nicht als Partition an Tabelle »%s« ohne OIDs anfügen" -#: commands/tablecmds.c:13183 -#, fuzzy, c-format -#| msgid "column \"%s\" not found in data type %s" +#: commands/tablecmds.c:14776 +#, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" -msgstr "Spalte »%s« nicht gefunden im Datentyp %s" +msgstr "Tabelle »%s« enthält Spalte »%s«, die nicht in der Elterntabelle »%s« gefunden wurde" -#: commands/tablecmds.c:13186 +#: commands/tablecmds.c:14779 #, c-format -msgid "New partition should contain only the columns present in parent." -msgstr "" +msgid "The new partition may contain only the columns present in parent." +msgstr "Die neue Partition darf nur Spalten enthalten, die auch die Elterntabelle hat." -#: commands/tablecmds.c:13358 +#: commands/tablecmds.c:14791 #, c-format -msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "Trigger »%s« verhindert, dass Tabelle »%s« eine Partition werden kann" + +#: commands/tablecmds.c:14793 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "ROW-Trigger mit Übergangstabellen werden für Partitionen nicht unterstützt" + +#: commands/tablecmds.c:15483 commands/tablecmds.c:15502 +#: commands/tablecmds.c:15524 commands/tablecmds.c:15543 +#: commands/tablecmds.c:15599 +#, fuzzy, c-format +#| msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "kann Tabelle »%s« ohne OIDs nicht als Partition an Tabelle »%s« mit OIDs anfügen" + +#: commands/tablecmds.c:15486 +#, fuzzy, c-format +#| msgid "index \"%s\" is already associated with a constraint" +msgid "Index \"%s\" is already attached to another index." +msgstr "Index »%s« gehört bereits zu einem Constraint" + +#: commands/tablecmds.c:15505 +#, fuzzy, c-format +#| msgid "\"%s\" is not an index for table \"%s\"" +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "»%s« ist kein Index für Tabelle »%s«" + +#: commands/tablecmds.c:15527 +#, c-format +msgid "The index definitions do not match." +msgstr "Die Indexdefinitionen stimmen nicht überein." + +#: commands/tablecmds.c:15546 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." msgstr "" -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:623 replication/slot.c:1017 storage/file/copydir.c:47 +#: commands/tablecmds.c:15602 +#, fuzzy, c-format +#| msgid "cannot inherit from partition \"%s\"" +msgid "Another index is already attached for partition \"%s\"." +msgstr "von Partition »%s« kann nicht geerbt werden" + +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:625 replication/slot.c:1199 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: commands/tablespace.c:209 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "konnte »stat« für Verzeichnis »%s« nicht ausführen: %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "»%s« existiert, ist aber kein Verzeichnis" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "keine Berechtigung, um Tablespace »%s« zu erzeugen" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "Nur Superuser können Tablespaces anlegen." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "Tablespace-Pfad darf keine Apostrophe enthalten" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "Tablespace-Pfad muss ein absoluter Pfad sein" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "Tablespace-Pfad »%s« ist zu lang" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "Tablespace-Pfad sollte nicht innerhalb des Datenverzeichnisses sein" -#: commands/tablespace.c:304 commands/tablespace.c:950 +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "inakzeptabler Tablespace-Name »%s«" -#: commands/tablespace.c:306 commands/tablespace.c:951 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "Der Präfix »pg_« ist für System-Tablespaces reserviert." -#: commands/tablespace.c:316 commands/tablespace.c:963 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "Tablespace »%s« existiert bereits" -#: commands/tablespace.c:428 commands/tablespace.c:933 -#: commands/tablespace.c:1013 commands/tablespace.c:1081 -#: commands/tablespace.c:1214 commands/tablespace.c:1414 +#: commands/tablespace.c:430 commands/tablespace.c:935 +#: commands/tablespace.c:1015 commands/tablespace.c:1083 +#: commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "Tablespace »%s« existiert nicht" -#: commands/tablespace.c:434 +#: commands/tablespace.c:436 #, c-format msgid "tablespace \"%s\" does not exist, skipping" msgstr "Tablespace »%s« existiert nicht, wird übersprungen" -#: commands/tablespace.c:510 +#: commands/tablespace.c:512 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "Tablespace »%s« ist nicht leer" -#: commands/tablespace.c:582 +#: commands/tablespace.c:584 #, c-format msgid "directory \"%s\" does not exist" msgstr "Verzeichnis »%s« existiert nicht" -#: commands/tablespace.c:583 +#: commands/tablespace.c:585 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "Erzeugen Sie dieses Verzeichnis für den Tablespace bevor Sie den Server neu starten." -#: commands/tablespace.c:588 +#: commands/tablespace.c:590 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "konnte Zugriffsrechte für Verzeichnis »%s« nicht setzen: %m" -#: commands/tablespace.c:618 +#: commands/tablespace.c:620 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "Verzeichnis »%s« ist bereits als Tablespace in Verwendung" -#: commands/tablespace.c:742 commands/tablespace.c:755 -#: commands/tablespace.c:791 commands/tablespace.c:883 +#: commands/tablespace.c:705 commands/tablespace.c:715 +#: postmaster/postmaster.c:1476 storage/file/fd.c:2695 +#: storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 +#: utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: commands/tablespace.c:744 commands/tablespace.c:757 +#: commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3125 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht löschen: %m" -#: commands/tablespace.c:804 commands/tablespace.c:892 +#: commands/tablespace.c:806 commands/tablespace.c:894 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %m" -#: commands/tablespace.c:814 commands/tablespace.c:901 +#: commands/tablespace.c:816 commands/tablespace.c:903 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "»%s« ist kein Verzeichnis oder symbolische Verknüpfung" -#: commands/tablespace.c:1086 +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "Tablespace »%s« existiert nicht." -#: commands/tablespace.c:1513 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "Verzeichnisse für Tablespace %u konnten nicht entfernt werden" -#: commands/tablespace.c:1515 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "Sie können die Verzeichnisse falls nötig manuell entfernen." -#: commands/trigger.c:187 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" msgstr "»%s« ist eine Tabelle" -#: commands/trigger.c:189 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "Tabellen können keine INSTEAD OF-Trigger haben." -#: commands/trigger.c:194 -#, fuzzy, c-format -#| msgid "\"%s\" is a partial index" -msgid "\"%s\" is a partitioned table" -msgstr "»%s« ist ein partieller Index" +#: commands/trigger.c:237 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "Partitionierte Tabellen können keine BEFORE / FOR EACH ROW-Trigger haben." -#: commands/trigger.c:196 -#, fuzzy, c-format -#| msgid "Foreign tables cannot have TRUNCATE triggers." -msgid "Partitioned tables cannot have ROW triggers." -msgstr "Fremdtabellen können keine TRUNCATE-Trigger haben." +#: commands/trigger.c:255 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Trigger für partitionierte Tabellen können keine Übergangstabellen haben." -#: commands/trigger.c:207 commands/trigger.c:214 +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" msgstr "»%s« ist eine Sicht" -#: commands/trigger.c:209 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "Sichten können keine BEFORE- oder AFTER-Trigger auf Zeilenebene haben." -#: commands/trigger.c:216 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "Sichten können keine TRUNCATE-Trigger haben." -#: commands/trigger.c:224 commands/trigger.c:231 commands/trigger.c:238 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 +#: commands/trigger.c:437 #, c-format msgid "\"%s\" is a foreign table" msgstr "»%s« ist eine Fremdtabelle" -#: commands/trigger.c:226 +#: commands/trigger.c:286 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "Fremdtabellen können keine INSTEAD OF-Trigger haben." -#: commands/trigger.c:233 +#: commands/trigger.c:293 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "Fremdtabellen können keine TRUNCATE-Trigger haben." -#: commands/trigger.c:240 +#: commands/trigger.c:305 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "Fremdtabellen können keine Constraint-Trigger haben." -#: commands/trigger.c:303 +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "TRUNCATE FOR EACH ROW-Trigger werden nicht unterstützt" -#: commands/trigger.c:311 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "INSTEAD OF-Trigger müssen FOR EACH ROW sein" -#: commands/trigger.c:315 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "INSTEAD OF-Trigger können keine WHEN-Bedingungen haben" -#: commands/trigger.c:319 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "INSTEAD OF-Trigger können keine Spaltenlisten haben" -#: commands/trigger.c:348 -#, fuzzy, c-format -#| msgid "using variable \"%s\" in different declare statements is not supported" +#: commands/trigger.c:425 +#, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" -msgstr "Verwendung der Variable »%s« in verschiedenen DECLARE-Anweisungen wird nicht unterstützt" +msgstr "Benennung von ROW-Variablen in der REFERENCING-Klausel wird nicht unterstützt" -#: commands/trigger.c:349 +#: commands/trigger.c:426 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." -msgstr "" +msgstr "Verwenden Sie OLD TABLE und NEW TABLE, um Übergangstabellen zu benennen." -#: commands/trigger.c:360 -#, fuzzy, c-format -#| msgid "%s: transaction log directory location can only be specified in plain mode\n" +#: commands/trigger.c:439 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Trigger für Fremdtabellen können keine Übergangstabellen haben." + +#: commands/trigger.c:446 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Trigger für Sichten können keine Übergangstabellen haben." + +#: commands/trigger.c:466 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "ROW-Trigger mit Übergangstabellen werden für Vererbungskinder nicht unterstützt" + +#: commands/trigger.c:472 +#, c-format msgid "transition table name can only be specified for an AFTER trigger" -msgstr "%s: Transaktionslogverzeichnis kann nur im »plain«-Modus angegeben werden\n" +msgstr "Übergangstabellenname kann nur für einen AFTER-Trigger angegeben werden" + +#: commands/trigger.c:477 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "TRUNCATE-Trigger mit Übergangstabellen werden nicht unterstützt" + +#: commands/trigger.c:494 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "Übergangstabellen können nicht für Trigger mit mehr als einem Ereignis angegeben werden" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "Übergangstabellen können nicht für Trigger mit Spaltenlisten angegeben werden" -#: commands/trigger.c:368 +#: commands/trigger.c:522 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" -msgstr "" +msgstr "NEW TABLE kann nur für INSERT- oder UPDATE-Trigger angegeben werden" -#: commands/trigger.c:373 +#: commands/trigger.c:527 #, c-format msgid "NEW TABLE cannot be specified multiple times" -msgstr "" +msgstr "NEW TABLE kann nicht mehrmals angegeben werden" -#: commands/trigger.c:383 +#: commands/trigger.c:537 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" -msgstr "" +msgstr "OLD TABLE kann nur für DELETE- oder UPDATE-Trigger angegeben werden" -#: commands/trigger.c:388 +#: commands/trigger.c:542 #, c-format msgid "OLD TABLE cannot be specified multiple times" -msgstr "" +msgstr "OLD TABLE kann nicht mehrmals angegeben werden" -#: commands/trigger.c:398 +#: commands/trigger.c:552 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" -msgstr "" +msgstr "Name für OLD TABLE und NEW TABLE kann nicht gleich sein" -#: commands/trigger.c:455 commands/trigger.c:468 +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "WHEN-Bedingung eines Statement-Triggers kann keine Verweise auf Spaltenwerte enthalten" -#: commands/trigger.c:460 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "WHEN-Bedingung eines INSERT-Triggers kann keine Verweise auf OLD-Werte enthalten" -#: commands/trigger.c:473 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "WHEN-Bedingung eines DELETE-Triggers kann keine Verweise auf NEW-Werte enthalten" -#: commands/trigger.c:478 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "WHEN-Bedingung eines BEFORE-Triggers kann keine Verweise auf Systemspalten in NEW enthalten" -#: commands/trigger.c:643 commands/trigger.c:1414 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "Trigger »%s« für Relation »%s« existiert bereits" -#: commands/trigger.c:939 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "UPDATE-Trigger der Zieltabelle wurde gefunden." -#: commands/trigger.c:940 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "DELETE-Trigger der Zieltabelle wurde gefunden." -#: commands/trigger.c:941 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "Trigger der Quelltabelle wurde gefunden." -#: commands/trigger.c:1050 commands/trigger.c:1066 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "unvollständige Triggergruppe für Constraint \"%s\" %s ignoriert" -#: commands/trigger.c:1079 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "Triggergruppe wird in Constraint \"%s\" %s umgewandelt" -#: commands/trigger.c:1300 commands/trigger.c:1459 commands/trigger.c:1574 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "Trigger »%s« für Tabelle »%s« existiert nicht" -#: commands/trigger.c:1542 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "keine Berechtigung: »%s« ist ein Systemtrigger" -#: commands/trigger.c:2097 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "Triggerfunktion %u gab NULL-Wert zurück" -#: commands/trigger.c:2158 commands/trigger.c:2364 commands/trigger.c:2575 -#: commands/trigger.c:2854 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 +#: commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "Trigger für BEFORE STATEMENT kann keinen Wert zurückgeben" -#: commands/trigger.c:2916 executor/nodeModifyTable.c:746 -#: executor/nodeModifyTable.c:1041 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 +#: executor/nodeModifyTable.c:1244 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: commands/trigger.c:2917 executor/nodeModifyTable.c:747 -#: executor/nodeModifyTable.c:1042 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 +#: executor/nodeModifyTable.c:1245 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Verwenden Sie einen AFTER-Trigger anstelle eines BEFORE-Triggers, um Änderungen an andere Zeilen zu propagieren." -#: commands/trigger.c:2931 executor/execMain.c:2526 -#: executor/nodeLockRows.c:216 executor/nodeModifyTable.c:213 -#: executor/nodeModifyTable.c:759 executor/nodeModifyTable.c:1054 -#: executor/nodeModifyTable.c:1220 +#: commands/trigger.c:3320 executor/execMain.c:2727 executor/nodeLockRows.c:220 +#: executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 +#: executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" msgstr "kann Zugriff nicht serialisieren wegen gleichzeitiger Aktualisierung" -#: commands/trigger.c:4834 +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 +#: executor/nodeLockRows.c:224 +#, fuzzy, c-format +#| msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" + +#: commands/trigger.c:5457 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "Constraint »%s« ist nicht aufschiebbar" -#: commands/trigger.c:4857 +#: commands/trigger.c:5480 #, c-format msgid "constraint \"%s\" does not exist" msgstr "Constraint »%s« existiert nicht" @@ -9544,632 +10180,673 @@ msgstr "Optionen PARSER und COPY können nicht beide angegeben werden" msgid "text search parser is required" msgstr "Textsucheparser muss angegeben werden" -#: commands/tsearchcmds.c:1266 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "Tokentyp »%s« existiert nicht" -#: commands/tsearchcmds.c:1487 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "Mapping für Tokentyp »%s« existiert nicht" -#: commands/tsearchcmds.c:1493 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "Mapping für Tokentyp »%s« existiert nicht, wird übersprungen" -#: commands/tsearchcmds.c:1648 commands/tsearchcmds.c:1759 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "ungültiges Parameterlistenformat: »%s«" -#: commands/typecmds.c:183 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" msgstr "nur Superuser können Basistypen anlegen" -#: commands/typecmds.c:290 commands/typecmds.c:1414 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "Typ-Attribut »%s« nicht erkannt" -#: commands/typecmds.c:346 +#: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "ungültige Typenkategorie »%s«: muss einfacher ASCII-Wert sein" -#: commands/typecmds.c:365 +#: commands/typecmds.c:362 #, c-format msgid "array element type cannot be %s" msgstr "Arrayelementtyp kann nicht %s sein" -#: commands/typecmds.c:397 +#: commands/typecmds.c:394 #, c-format msgid "alignment \"%s\" not recognized" msgstr "Ausrichtung »%s« nicht erkannt" -#: commands/typecmds.c:414 +#: commands/typecmds.c:411 #, c-format msgid "storage \"%s\" not recognized" msgstr "Storage-Typ »%s« nicht erkannt" -#: commands/typecmds.c:425 +#: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" msgstr "Typeingabefunktion muss angegeben werden" -#: commands/typecmds.c:429 +#: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" msgstr "Typausgabefunktion muss angegeben werden" -#: commands/typecmds.c:434 +#: commands/typecmds.c:431 #, c-format msgid "type modifier output function is useless without a type modifier input function" msgstr "Typmodifikatorausgabefunktion ist nutzlos ohne Typmodifikatoreingabefunktion" -#: commands/typecmds.c:464 +#: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" msgstr "Typeingabefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:481 +#: commands/typecmds.c:478 #, c-format msgid "type output function %s must return type %s" msgstr "Typausgabefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:490 +#: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" msgstr "Typempfangsfunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:499 +#: commands/typecmds.c:496 #, c-format msgid "type send function %s must return type %s" msgstr "Typsendefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:564 +#: commands/typecmds.c:561 #, c-format msgid "type input function %s should not be volatile" msgstr "Typeingabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:569 +#: commands/typecmds.c:566 #, c-format msgid "type output function %s should not be volatile" msgstr "Typausgabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:574 +#: commands/typecmds.c:571 #, c-format msgid "type receive function %s should not be volatile" msgstr "Typempfangsfunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:579 +#: commands/typecmds.c:576 #, c-format msgid "type send function %s should not be volatile" msgstr "Typsendefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:584 +#: commands/typecmds.c:581 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "Typmodifikatoreingabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:589 +#: commands/typecmds.c:586 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "Typmodifikatorausgabefunktion %s sollte nicht VOLATILE sein" -#: commands/typecmds.c:811 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "»%s« ist kein gültiger Basistyp für eine Domäne" -#: commands/typecmds.c:897 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "mehrere Vorgabeausdrücke" -#: commands/typecmds.c:959 commands/typecmds.c:968 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "wiedersprüchliche NULL/NOT NULL-Constraints" -#: commands/typecmds.c:984 +#: commands/typecmds.c:986 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "Check-Constraints für Domänen können nicht als NO INHERIT markiert werden" -#: commands/typecmds.c:993 commands/typecmds.c:2512 +#: commands/typecmds.c:995 commands/typecmds.c:2585 #, c-format msgid "unique constraints not possible for domains" msgstr "Unique-Constraints sind nicht für Domänen möglich" -#: commands/typecmds.c:999 commands/typecmds.c:2518 +#: commands/typecmds.c:1001 commands/typecmds.c:2591 #, c-format msgid "primary key constraints not possible for domains" msgstr "Primärschlüssel-Constraints sind nicht fürDomänen möglich" -#: commands/typecmds.c:1005 commands/typecmds.c:2524 +#: commands/typecmds.c:1007 commands/typecmds.c:2597 #, c-format msgid "exclusion constraints not possible for domains" msgstr "Exclusion-Constraints sind nicht für Domänen möglich" -#: commands/typecmds.c:1011 commands/typecmds.c:2530 +#: commands/typecmds.c:1013 commands/typecmds.c:2603 #, c-format msgid "foreign key constraints not possible for domains" msgstr "Fremdschlüssel-Constraints sind nicht für Domänen möglich" -#: commands/typecmds.c:1020 commands/typecmds.c:2539 +#: commands/typecmds.c:1022 commands/typecmds.c:2612 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "Setzen des Constraint-Modus wird für Domänen nicht unterstützt" -#: commands/typecmds.c:1284 utils/cache/typcache.c:1636 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" msgstr "»%s« ist kein Enum" -#: commands/typecmds.c:1422 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "Typ-Attribut »subtype« muss angegeben werden" -#: commands/typecmds.c:1427 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "Bereichtsuntertyp kann nicht %s sein" -#: commands/typecmds.c:1446 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "Sortierfolge für Bereichstyp angegeben, aber Untertyp unterstützt keine Sortierfolgen" -#: commands/typecmds.c:1680 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "ändere Argumenttyp von Funktion %s von »opaque« in »cstring«" -#: commands/typecmds.c:1731 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "ändere Argumenttyp von Funktion %s von »opaque« in %s" -#: commands/typecmds.c:1830 +#: commands/typecmds.c:1898 #, c-format msgid "typmod_in function %s must return type %s" msgstr "typmod_in-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:1857 +#: commands/typecmds.c:1925 #, c-format msgid "typmod_out function %s must return type %s" msgstr "typmod_out-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:1884 +#: commands/typecmds.c:1952 #, c-format msgid "type analyze function %s must return type %s" msgstr "Typanalysefunktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:1930 +#: commands/typecmds.c:1998 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "Sie müssen für den Bereichstyp eine Operatorklasse angeben oder eine Standardoperatorklasse für den Untertyp definieren." -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" msgstr "Bereichstyp-Canonical-Funktion %s muss Bereichstyp zurückgeben" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" msgstr "Bereichstyp-Canonical-Funktion %s muss »immutable« sein" -#: commands/typecmds.c:2003 +#: commands/typecmds.c:2071 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss Typ %s zurückgeben" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "Bereichstyp-Untertyp-Diff-Funktion %s muss »immutable« sein" -#: commands/typecmds.c:2037 +#: commands/typecmds.c:2105 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "Array-OID-Wert für pg_type ist im Binary-Upgrade-Modus nicht gesetzt" -#: commands/typecmds.c:2340 +#: commands/typecmds.c:2410 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "Spalte »%s« von Tabelle »%s« enthält NULL-Werte" -#: commands/typecmds.c:2453 commands/typecmds.c:2636 +#: commands/typecmds.c:2524 commands/typecmds.c:2709 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "Constraint »%s« von Domäne »%s« existiert nicht" -#: commands/typecmds.c:2457 +#: commands/typecmds.c:2528 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "Constraint »%s« von Domäne »%s« existiert nicht, wird übersprungen" -#: commands/typecmds.c:2642 +#: commands/typecmds.c:2716 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "Constraint »%s« von Domäne »%s« ist kein Check-Constraint" -#: commands/typecmds.c:2747 +#: commands/typecmds.c:2822 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "Spalte »%s« von Tabelle »%s« enthält Werte, die den neuen Constraint verletzen" -#: commands/typecmds.c:2960 commands/typecmds.c:3247 commands/typecmds.c:3434 +#: commands/typecmds.c:3050 commands/typecmds.c:3256 commands/typecmds.c:3338 +#: commands/typecmds.c:3525 #, c-format msgid "%s is not a domain" msgstr "%s ist keine Domäne" -#: commands/typecmds.c:2994 +#: commands/typecmds.c:3083 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "Constraint »%s« für Domäne »%s« existiert bereits" -#: commands/typecmds.c:3045 +#: commands/typecmds.c:3134 #, c-format msgid "cannot use table references in domain check constraint" msgstr "Tabellenverweise können in Domänen-Check-Constraints nicht verwendet werden" -#: commands/typecmds.c:3177 commands/typecmds.c:3259 commands/typecmds.c:3551 +#: commands/typecmds.c:3268 commands/typecmds.c:3350 commands/typecmds.c:3642 #, c-format msgid "%s is a table's row type" msgstr "%s ist der Zeilentyp einer Tabelle" -#: commands/typecmds.c:3179 commands/typecmds.c:3261 commands/typecmds.c:3553 +#: commands/typecmds.c:3270 commands/typecmds.c:3352 commands/typecmds.c:3644 #, c-format msgid "Use ALTER TABLE instead." msgstr "Verwenden Sie stattdessen ALTER TABLE." -#: commands/typecmds.c:3186 commands/typecmds.c:3268 commands/typecmds.c:3466 +#: commands/typecmds.c:3277 commands/typecmds.c:3359 commands/typecmds.c:3557 #, c-format msgid "cannot alter array type %s" msgstr "Array-Typ %s kann nicht verändert werden" -#: commands/typecmds.c:3188 commands/typecmds.c:3270 commands/typecmds.c:3468 +#: commands/typecmds.c:3279 commands/typecmds.c:3361 commands/typecmds.c:3559 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Sie können den Typ %s ändern, wodurch der Array-Typ ebenfalls geändert wird." -#: commands/typecmds.c:3536 +#: commands/typecmds.c:3627 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "Typ %s existiert bereits in Schema »%s«" -#: commands/user.c:154 +#: commands/user.c:141 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSID kann nicht mehr angegeben werden" -#: commands/user.c:308 +#: commands/user.c:295 #, c-format msgid "must be superuser to create superusers" msgstr "nur Superuser können Superuser anlegen" -#: commands/user.c:315 +#: commands/user.c:302 #, c-format msgid "must be superuser to create replication users" msgstr "nur Superuser können Replikationsbenutzer anlegen" -#: commands/user.c:322 commands/user.c:708 +#: commands/user.c:309 commands/user.c:707 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "nur Superuser können das Attribut »bypassrls« ändern" -#: commands/user.c:329 +#: commands/user.c:316 #, c-format msgid "permission denied to create role" msgstr "keine Berechtigung, um Rolle zu erzeugen" -#: commands/user.c:339 commands/user.c:1183 commands/user.c:1190 gram.y:14233 -#: gram.y:14268 utils/adt/acl.c:5246 utils/adt/acl.c:5252 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 gram.y:14873 +#: gram.y:14911 utils/adt/acl.c:5342 utils/adt/acl.c:5348 #, c-format msgid "role name \"%s\" is reserved" msgstr "Rollenname »%s« ist reserviert" -#: commands/user.c:341 commands/user.c:1185 commands/user.c:1192 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "Rollennamen, die mit »pg_« anfangen, sind reserviert." -#: commands/user.c:353 commands/user.c:1198 +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "Rolle »%s« existiert bereits" -#: commands/user.c:426 +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "leere Zeichenkette ist kein gültiges Passwort, Passwort wird entfernt" + +#: commands/user.c:437 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "OID-Wert für pg_auth ist im Binary-Upgrade-Modus nicht gesetzt" -#: commands/user.c:694 commands/user.c:903 commands/user.c:1437 -#: commands/user.c:1581 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 +#: commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" msgstr "nur Superuser können Superuser ändern" -#: commands/user.c:701 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" msgstr "nur Superuser können Replikationsbenutzer ändern" -#: commands/user.c:724 commands/user.c:911 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "keine Berechtigung" -#: commands/user.c:941 +#: commands/user.c:953 #, c-format msgid "must be superuser to alter settings globally" msgstr "nur Superuser können globale Einstellungen ändern" -#: commands/user.c:963 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "keine Berechtigung, um Rolle zu entfernen" -#: commands/user.c:987 +#: commands/user.c:999 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "in DROP ROLE kann kein Rollenplatzhalter verwendet werden" -#: commands/user.c:997 commands/user.c:1154 commands/variable.c:822 -#: commands/variable.c:894 utils/adt/acl.c:5104 utils/adt/acl.c:5151 -#: utils/adt/acl.c:5179 utils/adt/acl.c:5197 utils/init/miscinit.c:502 +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 +#: commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "Rolle »%s« existiert nicht" -#: commands/user.c:1002 +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "Rolle »%s« existiert nicht, wird übersprungen" -#: commands/user.c:1014 commands/user.c:1018 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "aktueller Benutzer kann nicht entfernt werden" -#: commands/user.c:1022 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "aktueller Sitzungsbenutzer kann nicht entfernt werden" -#: commands/user.c:1033 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" msgstr "nur Superuser können Superuser löschen" -#: commands/user.c:1049 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "kann Rolle »%s« nicht löschen, weil andere Objekte davon abhängen" -#: commands/user.c:1170 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "aktueller Sitzungsbenutzer kann nicht umbenannt werden" -#: commands/user.c:1174 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "aktueller Benutzer kann nicht umbenannt werden" -#: commands/user.c:1208 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" msgstr "nur Superuser können Superuser umbenennen" -#: commands/user.c:1215 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "keine Berechtigung, um Rolle umzubenennen" -#: commands/user.c:1236 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "MD5-Passwort wegen Rollenumbenennung gelöscht" -#: commands/user.c:1296 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "bei GRANT/REVOKE ROLE können keine Spaltennamen angegeben werden" -#: commands/user.c:1334 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" msgstr "keine Berechtigung, um Objekte zu löschen" -#: commands/user.c:1361 commands/user.c:1370 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" msgstr "keine Berechtigung, um Objekte neu zuzuordnen" -#: commands/user.c:1445 commands/user.c:1589 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" msgstr "Admin-Option für Rolle »%s« wird benötigt" -#: commands/user.c:1462 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" msgstr "nur Superuser können Grantor setzen" -#: commands/user.c:1487 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "Rolle »%s« ist ein Mitglied der Rolle »%s«" -#: commands/user.c:1502 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "Rolle »%s« ist schon Mitglied der Rolle »%s«" -#: commands/user.c:1611 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "Rolle »%s« ist kein Mitglied der Rolle »%s«" -#: commands/vacuum.c:186 +#: commands/vacuum.c:111 +#, fuzzy, c-format +#| msgid "aggregate minvfunc must be specified when mstype is specified" +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "»minvfunc« für Aggregatfunktion muss angegeben werden, wenn »mstype« angegeben ist" + +#: commands/vacuum.c:203 #, c-format msgid "%s cannot be executed from VACUUM or ANALYZE" msgstr "%s kann nicht aus VACUUM oder ANALYZE ausgeführt werden" -#: commands/vacuum.c:196 +#: commands/vacuum.c:213 #, c-format msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" msgstr "VACUUM-Option DISABLE_PAGE_SKIPPING kann nicht zusammen mit FULL verwendet werden" -#: commands/vacuum.c:565 +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "älteste xmin ist weit in der Vergangenheit" -#: commands/vacuum.c:566 +#: commands/vacuum.c:658 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." -msgstr "Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Schließen Sie bald alle offenen Transaktionen, um Überlaufprobleme zu vermeiden.\n" +"Eventuell müssen Sie auch alte vorbereitete Transaktionen committen oder zurückrollen oder unbenutzte Replikations-Slots löschen." -#: commands/vacuum.c:605 +#: commands/vacuum.c:698 #, c-format msgid "oldest multixact is far in the past" msgstr "älteste Multixact ist weit in der Vergangenheit" -#: commands/vacuum.c:606 +#: commands/vacuum.c:699 #, c-format msgid "Close open transactions with multixacts soon to avoid wraparound problems." msgstr "Schließen Sie bald alle offenen Transaktionen mit Multixacts, um Überlaufprobleme zu vermeiden." -#: commands/vacuum.c:1176 +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" msgstr "einige Datenbanken sind seit über 2 Milliarden Transaktionen nicht gevacuumt worden" -#: commands/vacuum.c:1177 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "Sie haben möglicherweise bereits Daten wegen Transaktionsnummernüberlauf verloren." -#: commands/vacuum.c:1306 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" msgstr "überspringe Vacuum von »%s« --- Sperre nicht verfügbar" -#: commands/vacuum.c:1332 +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "überspringe Vacuum von »%s« --- Relation existiert nicht mehr" + +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "überspringe »%s« --- nur Superuser kann sie vacuumen" -#: commands/vacuum.c:1336 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "überspringe »%s« --- nur Superuser oder Eigentümer der Datenbank kann sie vacuumen" -#: commands/vacuum.c:1340 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "überspringe »%s« --- nur Eigentümer der Tabelle oder der Datenbank kann sie vacuumen" -#: commands/vacuum.c:1359 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" msgstr "überspringe »%s« --- kann Nicht-Tabellen oder besondere Systemtabellen nicht vacuumen" -#: commands/vacuumlazy.c:372 +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisches aggressives Vacuum der Tabelle »%s.%s.%s«: Index-Scans: %d\n" + +#: commands/vacuumlazy.c:380 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" msgstr "automatisches Vacuum der Tabelle »%s.%s.%s«: Index-Scans: %d\n" -#: commands/vacuumlazy.c:377 +#: commands/vacuumlazy.c:386 #, c-format msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" msgstr "Seiten: %u entfernt, %u verbleiben, %u übersprungen wegen Pins, %u übersprungen weil eingefroren\n" -#: commands/vacuumlazy.c:383 -#, fuzzy, c-format -#| msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" +#: commands/vacuumlazy.c:392 +#, c-format msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" -msgstr "Tupel: %.0f entfernt, %.0f verbleiben, %.0f sind tot aber noch nicht entfernbar\n" +msgstr "Tupel: %.0f entfernt, %.0f verbleiben, %.0f sind tot aber noch nicht entfernbar, ältestes xmin: %u\n" -#: commands/vacuumlazy.c:389 +#: commands/vacuumlazy.c:398 #, c-format msgid "buffer usage: %d hits, %d misses, %d dirtied\n" msgstr "Puffer-Verwendung: %d Treffer, %d Verfehlen, %d geändert\n" -#: commands/vacuumlazy.c:393 +#: commands/vacuumlazy.c:402 #, c-format msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" msgstr "durchschn. Leserate: %.3f MB/s, durchschn. Schreibrate: %.3f MB/s\n" -#: commands/vacuumlazy.c:395 +#: commands/vacuumlazy.c:404 #, c-format msgid "system usage: %s" msgstr "Systembenutzung: %s" -#: commands/vacuumlazy.c:853 +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "aggressives Vacuum von »%s.%s«" + +#: commands/vacuumlazy.c:881 #, c-format msgid "relation \"%s\" page %u is uninitialized --- fixing" msgstr "Seite %2$u in Relation »%1$s« ist nicht initialisiert --- wird repariert" -#: commands/vacuumlazy.c:1323 +#: commands/vacuumlazy.c:1417 #, c-format msgid "\"%s\": removed %.0f row versions in %u pages" msgstr "»%s«: %.0f Zeilenversionen in %u Seiten entfernt" -#: commands/vacuumlazy.c:1333 -#, fuzzy, c-format -#| msgid "%.0f dead row versions cannot be removed yet.\n" +#: commands/vacuumlazy.c:1427 +#, c-format msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" -msgstr "%.0f tote Zeilenversionen können noch nicht entfernt werden.\n" +msgstr "%.0f tote Zeilenversionen können noch nicht entfernt werden, ältestes xmin: %u\n" -#: commands/vacuumlazy.c:1335 +#: commands/vacuumlazy.c:1429 #, c-format msgid "There were %.0f unused item pointers.\n" msgstr "Es gab %.0f unbenutzte Itemzeiger.\n" -#: commands/vacuumlazy.c:1337 +#: commands/vacuumlazy.c:1431 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "%u Seite wegen Buffer-Pins übersprungen, " +msgstr[1] "%u Seiten wegen Buffer-Pins übersprungen, " + +#: commands/vacuumlazy.c:1435 #, c-format -msgid "Skipped %u page due to buffer pins.\n" -msgid_plural "Skipped %u pages due to buffer pins.\n" -msgstr[0] "%u Seite wegen Buffer-Pins übersprungen.\n" -msgstr[1] "%u Seiten wegen Buffer-Pins übersprungen.\n" +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u eingefrorene Seite.\n" +msgstr[1] "%u eingefrorene Seiten.\n" -#: commands/vacuumlazy.c:1341 +#: commands/vacuumlazy.c:1439 #, c-format msgid "%u page is entirely empty.\n" msgid_plural "%u pages are entirely empty.\n" msgstr[0] "%u Seite ist vollkommen leer.\n" msgstr[1] "%u Seiten sind vollkommen leer.\n" -#: commands/vacuumlazy.c:1349 +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" msgstr "»%s«: %.0f entfernbare, %.0f nicht entfernbare Zeilenversionen in %u von %u Seiten gefunden" -#: commands/vacuumlazy.c:1418 +#: commands/vacuumlazy.c:1515 #, c-format msgid "\"%s\": removed %d row versions in %d pages" msgstr "»%s«: %d Zeilenversionen in %d Seiten entfernt" -#: commands/vacuumlazy.c:1607 +#: commands/vacuumlazy.c:1704 #, c-format msgid "scanned index \"%s\" to remove %d row versions" msgstr "Index »%s« gelesen und %d Zeilenversionen entfernt" -#: commands/vacuumlazy.c:1653 +#: commands/vacuumlazy.c:1756 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "Index »%s« enthält %.0f Zeilenversionen in %u Seiten" -#: commands/vacuumlazy.c:1657 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -10180,22 +10857,22 @@ msgstr "" "%u Indexseiten wurden gelöscht, %u sind gegenwärtig wiederverwendbar.\n" "%s." -#: commands/vacuumlazy.c:1752 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" msgstr "»%s«: Truncate wird gestoppt wegen Sperrkonflikt" -#: commands/vacuumlazy.c:1817 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "»%s«: von %u auf %u Seiten verkürzt" -#: commands/vacuumlazy.c:1882 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" msgstr "»%s«: Truncate wird ausgesetzt wegen Sperrkonflikt" -#: commands/variable.c:165 utils/misc/guc.c:9982 utils/misc/guc.c:10044 +#: commands/variable.c:165 utils/misc/guc.c:10307 utils/misc/guc.c:10369 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "Unbekanntes Schlüsselwort: »%s«." @@ -10255,7 +10932,7 @@ msgstr "SET TRANSACTION ISOLATION LEVEL muss vor allen Anfragen aufgerufen werde msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "SET TRANSACTION ISOLATION LEVEL kann nicht in einer Subtransaktion aufgerufen werden" -#: commands/variable.c:571 storage/lmgr/predicate.c:1576 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "kann serialisierbaren Modus nicht in einem Hot Standby verwenden" @@ -10287,8 +10964,8 @@ msgstr "»client_encoding« kann jetzt nicht geändert werden." #: commands/variable.c:776 #, c-format -msgid "cannot change client_encoding in a parallel worker" -msgstr "client_encoding kann nicht in einem parallelen Arbeitsprozess geändert werden" +msgid "cannot change client_encoding during a parallel operation" +msgstr "client_encoding kann nicht während einer parallelen Operation geändert werden" #: commands/variable.c:912 #, c-format @@ -10305,472 +10982,499 @@ msgstr "ungültiger Wert für Option »check_option«" msgid "Valid values are \"local\" and \"cascaded\"." msgstr "Gültige Werte sind »local« und »cascaded«." -#: commands/view.c:101 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "konnte die für die Sichtspalte »%s« zu verwendende Sortierfolge nicht bestimmen" -#: commands/view.c:115 +#: commands/view.c:117 #, c-format msgid "view must have at least one column" msgstr "Sicht muss mindestens eine Spalte haben" -#: commands/view.c:281 commands/view.c:293 +#: commands/view.c:285 commands/view.c:297 #, c-format msgid "cannot drop columns from view" msgstr "aus einer Sicht können keine Spalten gelöscht werden" -#: commands/view.c:298 +#: commands/view.c:302 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "kann Namen der Sichtspalte »%s« nicht in »%s« ändern" -#: commands/view.c:306 +#: commands/view.c:310 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "kann Datentyp der Sichtspalte »%s« nicht von %s in %s ändern" -#: commands/view.c:451 +#: commands/view.c:455 #, c-format msgid "views must not contain SELECT INTO" msgstr "Sichten dürfen kein SELECT INTO enthalten" -#: commands/view.c:463 +#: commands/view.c:467 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "Sichten dürfen keine datenmodifizierenden Anweisungen in WITH enthalten" -#: commands/view.c:533 +#: commands/view.c:537 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "CREATE VIEW gibt mehr Spaltennamen als Spalten an" -#: commands/view.c:541 +#: commands/view.c:545 #, c-format msgid "views cannot be unlogged because they do not have storage" msgstr "Sichten können nicht ungeloggt sein, weil sie keinen Speicherplatz verwenden" -#: commands/view.c:555 +#: commands/view.c:559 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "Sicht »%s« wird eine temporäre Sicht" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:78 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "Cursor »%s« ist keine SELECT-Anfrage" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:84 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "Cursor »%s« wurde aus einer vorherigen Transaktion beibehalten" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:116 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "Cursor »%s« hat mehrere FOR UPDATE/SHARE-Verweise auf Tabelle »%s«" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:125 #, c-format msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "Cursor »%s« hat keinen FOR UPDATE/SHARE-Verweis auf Tabelle »%s«" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:135 executor/execCurrent.c:180 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "Cursor »%s« ist nicht auf eine Zeile positioniert" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:167 executor/execCurrent.c:226 +#: executor/execCurrent.c:238 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "Cursor »%s« ist kein einfach aktualisierbarer Scan der Tabelle »%s«" -#: executor/execCurrent.c:231 executor/execQual.c:1128 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "Typ von Parameter %d (%s) stimmt nicht mit dem überein, als der Plan vorbereitet worden ist (%s)" -#: executor/execCurrent.c:243 executor/execQual.c:1140 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 #, c-format msgid "no value found for parameter %d" msgstr "kein Wert für Parameter %d gefunden" -#: executor/execIndexing.c:545 +#: executor/execExpr.c:856 parser/parse_agg.c:794 +#, c-format +msgid "window function calls cannot be nested" +msgstr "Aufrufe von Fensterfunktionen können nicht geschachtelt werden" + +#: executor/execExpr.c:1314 +#, c-format +msgid "target type is not an array" +msgstr "Zieltyp ist kein Array" + +#: executor/execExpr.c:1647 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW()-Spalte hat Typ %s statt Typ %s" + +#: executor/execExpr.c:2182 executor/execSRF.c:697 parser/parse_func.c:126 +#: parser/parse_func.c:640 parser/parse_func.c:1014 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "kann nicht mehr als %d Argument an eine Funktion übergeben" +msgstr[1] "kann nicht mehr als %d Argumente an eine Funktion übergeben" + +#: executor/execExpr.c:2480 executor/execExpr.c:2486 +#: executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 +#: utils/adt/arrayfuncs.c:5820 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" + +#: executor/execExprInterp.c:1879 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "Attribut %d von Typ %s wurde gelöscht" + +#: executor/execExprInterp.c:1885 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "Attribut %d von Typ %s hat falschen Typ" + +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 +#: executor/execExprInterp.c:2933 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "Tabelle hat Typ %s, aber Anfrage erwartet %s." + +#: executor/execExprInterp.c:2374 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" + +#: executor/execExprInterp.c:2591 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "kann inkompatible Arrays nicht verschmelzen" + +#: executor/execExprInterp.c:2592 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "Arrayelement mit Typ %s kann nicht in ARRAY-Konstrukt mit Elementtyp %s verwendet werden." + +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" + +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 +#, c-format +msgid "attribute %d has wrong type" +msgstr "Attribut %d hat falschen Typ" + +#: executor/execExprInterp.c:3042 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "Arrayindex in Zuweisung darf nicht NULL sein" + +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "Domäne %s erlaubt keine NULL-Werte" + +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "Wert für Domäne %s verletzt Check-Constraint »%s«" + +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 +#: executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 +#: executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 +#: executor/nodeModifyTable.c:142 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "Zeilentyp der Tabelle und der von der Anfrage angegebene Zeilentyp stimmen nicht überein" + +#: executor/execExprInterp.c:3862 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "Tabellenzeile enthält %d Attribut, aber Anfrage erwartet %d." +msgstr[1] "Tabellenzeile enthält %d Attribute, aber Anfrage erwartet %d." + +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "Tabelle hat Typ %s auf Position %d, aber Anfrage erwartet %s." + +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "Physischer Speicher stimmt nicht überein mit gelöschtem Attribut auf Position %d." + +#: executor/execIndexing.c:543 #, c-format msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" msgstr "ON CONFLICT unterstützt keine aufschiebbaren Unique-Constraints/Exclusion-Constraints als Arbiter" -#: executor/execIndexing.c:822 +#: executor/execIndexing.c:818 #, c-format msgid "could not create exclusion constraint \"%s\"" msgstr "konnte Exclusion-Constraint »%s« nicht erzeugen" -#: executor/execIndexing.c:825 +#: executor/execIndexing.c:821 #, c-format msgid "Key %s conflicts with key %s." msgstr "Schlüssel %s kollidiert mit Schlüssel %s." -#: executor/execIndexing.c:827 +#: executor/execIndexing.c:823 #, c-format msgid "Key conflicts exist." msgstr "Es bestehen Schlüsselkonflikte." -#: executor/execIndexing.c:833 +#: executor/execIndexing.c:829 #, c-format msgid "conflicting key value violates exclusion constraint \"%s\"" msgstr "kollidierender Schlüsselwert verletzt Exclusion-Constraint »%s«" -#: executor/execIndexing.c:836 +#: executor/execIndexing.c:832 #, c-format msgid "Key %s conflicts with existing key %s." msgstr "Schlüssel %s kollidiert mit vorhandenem Schlüssel %s." -#: executor/execIndexing.c:838 +#: executor/execIndexing.c:834 #, c-format msgid "Key conflicts with existing key." msgstr "Der Schlüssel kollidiert mit einem vorhandenen Schlüssel." -#: executor/execMain.c:1040 +#: executor/execMain.c:1116 #, c-format msgid "cannot change sequence \"%s\"" msgstr "kann Sequenz »%s« nicht ändern" -#: executor/execMain.c:1046 +#: executor/execMain.c:1122 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "kann TOAST-Relation »%s« nicht ändern" -#: executor/execMain.c:1064 rewrite/rewriteHandler.c:2661 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2773 #, c-format msgid "cannot insert into view \"%s\"" msgstr "kann nicht in Sicht »%s« einfügen" -#: executor/execMain.c:1066 rewrite/rewriteHandler.c:2664 +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2776 #, c-format msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." msgstr "Um Einfügen in die Sicht zu ermöglichen, richten Sie einen INSTEAD OF INSERT Trigger oder eine ON INSERT DO INSTEAD Regel ohne Bedingung ein." -#: executor/execMain.c:1072 rewrite/rewriteHandler.c:2669 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2781 #, c-format msgid "cannot update view \"%s\"" msgstr "kann Sicht »%s« nicht aktualisieren" -#: executor/execMain.c:1074 rewrite/rewriteHandler.c:2672 +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2784 #, c-format msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." msgstr "Um Aktualisieren der Sicht zu ermöglichen, richten Sie einen INSTEAD OF UPDATE Trigger oder eine ON UPDATE DO INSTEAD Regel ohne Bedingung ein." -#: executor/execMain.c:1080 rewrite/rewriteHandler.c:2677 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2789 #, c-format msgid "cannot delete from view \"%s\"" msgstr "kann nicht aus Sicht »%s« löschen" -#: executor/execMain.c:1082 rewrite/rewriteHandler.c:2680 +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2792 #, c-format msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." msgstr "Um Löschen aus der Sicht zu ermöglichen, richten Sie einen INSTEAD OF DELETE Trigger oder eine ON DELETE DO INSTEAD Regel ohne Bedingung ein." -#: executor/execMain.c:1093 +#: executor/execMain.c:1169 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "kann materialisierte Sicht »%s« nicht ändern" -#: executor/execMain.c:1105 +#: executor/execMain.c:1181 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "kann nicht in Fremdtabelle »%s« einfügen" -#: executor/execMain.c:1111 +#: executor/execMain.c:1187 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "Fremdtabelle »%s« erlaubt kein Einfügen" -#: executor/execMain.c:1118 +#: executor/execMain.c:1194 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "kann Fremdtabelle »%s« nicht aktualisieren" -#: executor/execMain.c:1124 +#: executor/execMain.c:1200 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "Fremdtabelle »%s« erlaubt kein Aktualisieren" -#: executor/execMain.c:1131 +#: executor/execMain.c:1207 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "kann nicht aus Fremdtabelle »%s« löschen" -#: executor/execMain.c:1137 +#: executor/execMain.c:1213 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "Fremdtabelle »%s« erlaubt kein Löschen" -#: executor/execMain.c:1148 +#: executor/execMain.c:1224 #, c-format msgid "cannot change relation \"%s\"" msgstr "kann Relation »%s« nicht ändern" -#: executor/execMain.c:1175 +#: executor/execMain.c:1251 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "kann Zeilen in Sequenz »%s« nicht sperren" -#: executor/execMain.c:1182 +#: executor/execMain.c:1258 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "kann Zeilen in TOAST-Relation »%s« nicht sperren" -#: executor/execMain.c:1189 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "kann Zeilen in Sicht »%s« nicht sperren" -#: executor/execMain.c:1197 +#: executor/execMain.c:1273 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "kann Zeilen in materialisierter Sicht »%s« nicht sperren" -#: executor/execMain.c:1206 executor/execMain.c:2760 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1282 executor/execMain.c:2974 +#: executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "kann Zeilen in Fremdtabelle »%s« nicht sperren" -#: executor/execMain.c:1212 +#: executor/execMain.c:1288 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "kann Zeilen in Relation »%s« nicht sperren" -#: executor/execMain.c:1842 +#: executor/execMain.c:1959 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "NULL-Wert in Spalte »%s« verletzt Not-Null-Constraint" +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "neue Zeile für Relation »%s« verletzt Partitions-Constraint" -#: executor/execMain.c:1844 executor/execMain.c:1878 executor/execMain.c:1908 -#: executor/execMain.c:1995 +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 +#: executor/execMain.c:2195 #, c-format msgid "Failing row contains %s." msgstr "Fehlgeschlagene Zeile enthält %s." -#: executor/execMain.c:1876 +#: executor/execMain.c:2039 #, c-format -msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgstr "neue Zeile für Relation »%s« verletzt Check-Constraint »%s«" +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "NULL-Wert in Spalte »%s« verletzt Not-Null-Constraint" -#: executor/execMain.c:1906 -#, fuzzy, c-format -#| msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgid "new row for relation \"%s\" violates partition constraint" +#: executor/execMain.c:2086 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "neue Zeile für Relation »%s« verletzt Check-Constraint »%s«" -#: executor/execMain.c:1993 +#: executor/execMain.c:2193 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "neue Zeile verletzt Check-Option für Sicht »%s«" -#: executor/execMain.c:2003 +#: executor/execMain.c:2203 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« für Tabelle »%s«" -#: executor/execMain.c:2008 +#: executor/execMain.c:2208 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene für Tabelle »%s«" -#: executor/execMain.c:2015 +#: executor/execMain.c:2215 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene »%s« (USING-Ausdruck) für Tabelle »%s«" -#: executor/execMain.c:2020 +#: executor/execMain.c:2220 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "neue Zeile verletzt Policy für Sicherheit auf Zeilenebene (USING-Ausdruck) für Tabelle »%s«" -#: executor/execMain.c:3221 -#, fuzzy, c-format -#| msgid "no matching relations in tablespace \"%s\" found" +#: executor/execPartition.c:337 +#, c-format msgid "no partition of relation \"%s\" found for row" -msgstr "keine passenden Relationen in Tablespace »%s« gefunden" +msgstr "keine Partition von Relation »%s« für die Zeile gefunden" -#: executor/execMain.c:3223 -#, fuzzy, c-format -#| msgid "Failing row contains %s." +#: executor/execPartition.c:339 +#, c-format msgid "Partition key of the failing row contains %s." -msgstr "Fehlgeschlagene Zeile enthält %s." +msgstr "Partitionierungsschlüssel der fehlgeschlagenen Zeile enthält %s." + +#: executor/execReplication.c:197 executor/execReplication.c:356 +#, fuzzy, c-format +#| msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" -#: executor/execQual.c:282 executor/execQual.c:318 executor/execQual.c:2985 -#: utils/adt/array_userfuncs.c:484 utils/adt/arrayfuncs.c:260 -#: utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 -#: utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5241 -#: utils/adt/arrayfuncs.c:5758 +#: executor/execReplication.c:201 executor/execReplication.c:360 #, c-format -msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" +msgid "concurrent update, retrying" +msgstr "gleichzeitige Aktualisierung, versuche erneut" -#: executor/execQual.c:303 executor/execQual.c:338 +#: executor/execReplication.c:257 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 +#: utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 #, c-format -msgid "array subscript in assignment must not be null" -msgstr "Arrayindex in Zuweisung darf nicht NULL sein" +msgid "could not identify an equality operator for type %s" +msgstr "konnte keinen Ist-Gleich-Operator für Typ %s ermitteln" -#: executor/execQual.c:626 executor/execQual.c:3964 +#: executor/execReplication.c:573 #, c-format -msgid "attribute %d has wrong type" -msgstr "Attribut %d hat falschen Typ" +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "Tabelle »%s« kann nicht aktualisiert werden, weil sie keine Replik-Identität hat und Updates publiziert" -#: executor/execQual.c:627 executor/execQual.c:3965 +#: executor/execReplication.c:575 #, c-format -msgid "Table has type %s, but query expects %s." -msgstr "Tabelle hat Typ %s, aber Anfrage erwartet %s." +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Um Aktualisieren der Tabelle zu ermöglichen, setzen Sie REPLICA IDENTITY mit ALTER TABLE." -#: executor/execQual.c:814 executor/execQual.c:831 executor/execQual.c:1027 -#: executor/nodeModifyTable.c:95 executor/nodeModifyTable.c:105 -#: executor/nodeModifyTable.c:122 executor/nodeModifyTable.c:130 +#: executor/execReplication.c:579 #, c-format -msgid "table row type and query-specified row type do not match" -msgstr "Zeilentyp der Tabelle und der von der Anfrage angegebene Zeilentyp stimmen nicht überein" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "aus Tabelle »%s« kann nicht gelöscht werden, weil sie keine Replik-Identität hat und Deletes publiziert" -#: executor/execQual.c:815 +#: executor/execReplication.c:581 #, c-format -msgid "Table row contains %d attribute, but query expects %d." -msgid_plural "Table row contains %d attributes, but query expects %d." -msgstr[0] "Tabellenzeile enthält %d Attribut, aber Anfrage erwartet %d." -msgstr[1] "Tabellenzeile enthält %d Attribute, aber Anfrage erwartet %d." +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Um Löschen in der Tabelle zu ermöglichen, setzen Sie REPLICA IDENTITY mit ALTER TABLE." -#: executor/execQual.c:832 executor/nodeModifyTable.c:106 +#: executor/execReplication.c:600 #, c-format -msgid "Table has type %s at ordinal position %d, but query expects %s." -msgstr "Tabelle hat Typ %s auf Position %d, aber Anfrage erwartet %s." +msgid "logical replication target relation \"%s.%s\" is not a table" +msgstr "Zielrelation für logische Replikation »%s.%s« ist keine Tabelle" -#: executor/execQual.c:1028 executor/execQual.c:1602 +#: executor/execSRF.c:308 #, c-format -msgid "Physical storage mismatch on dropped attribute at ordinal position %d." -msgstr "Physischer Speicher stimmt nicht überein mit gelöschtem Attribut auf Position %d." +msgid "rows returned by function are not all of the same row type" +msgstr "von Funktion zurückgegebene Zeilen haben nicht alle den selben Zeilentyp" -#: executor/execQual.c:1294 parser/parse_func.c:116 parser/parse_func.c:543 -#: parser/parse_func.c:902 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format -msgid "cannot pass more than %d argument to a function" -msgid_plural "cannot pass more than %d arguments to a function" -msgstr[0] "kann nicht mehr als %d Argument an Funktion übergeben" -msgstr[1] "kann nicht mehr als %d Argumente an Funktion übergeben" +msgid "table-function protocol for materialize mode was not followed" +msgstr "Tabellenfunktionsprotokoll für Materialisierungsmodus wurde nicht befolgt" -#: executor/execQual.c:1520 +#: executor/execSRF.c:363 executor/execSRF.c:665 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "unbekannter returnMode von Tabellenfunktion: %d" + +#: executor/execSRF.c:871 #, c-format msgid "function returning setof record called in context that cannot accept type record" msgstr "Funktion mit Ergebnis SETOF RECORD in einem Zusammenhang aufgerufen, der den Typ RECORD nicht verarbeiten kann" -#: executor/execQual.c:1575 executor/execQual.c:1591 executor/execQual.c:1601 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format msgid "function return row and query-specified return row do not match" msgstr "von Funktion zurückgegebene Zeile und von der Anfrage angegebene zurückzugebende Zeile stimmen nicht überein" -#: executor/execQual.c:1576 +#: executor/execSRF.c:927 #, c-format msgid "Returned row contains %d attribute, but query expects %d." msgid_plural "Returned row contains %d attributes, but query expects %d." msgstr[0] "Zurückgegebene Zeile enthält %d Attribut, aber Anfrage erwartet %d." msgstr[1] "Zurückgegebene Zeile enthält %d Attribute, aber Anfrage erwartet %d." -#: executor/execQual.c:1592 +#: executor/execSRF.c:943 #, c-format msgid "Returned type %s at ordinal position %d, but query expects %s." msgstr "Rückgabetyp war %s auf Position %d, aber Anfrage erwartet %s." -#: executor/execQual.c:1790 executor/execQual.c:2153 -#, c-format -msgid "table-function protocol for materialize mode was not followed" -msgstr "Tabellenfunktionsprotokoll für Materialisierungsmodus wurde nicht befolgt" - -#: executor/execQual.c:1808 executor/execQual.c:2160 -#, c-format -msgid "unrecognized table-function returnMode: %d" -msgstr "unbekannter returnMode von Tabellenfunktion: %d" - -#: executor/execQual.c:2105 -#, c-format -msgid "rows returned by function are not all of the same row type" -msgstr "von Funktion zurückgegebene Zeilen haben nicht alle den selben Zeilentyp" - -#: executor/execQual.c:2963 -#, c-format -msgid "cannot merge incompatible arrays" -msgstr "kann inkompatible Arrays nicht verschmelzen" - -#: executor/execQual.c:2964 -#, c-format -msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." -msgstr "Arrayelement mit Typ %s kann nicht in ARRAY-Konstrukt mit Elementtyp %s verwendet werden." - -#: executor/execQual.c:3005 executor/execQual.c:3032 -#, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions" -msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" - -#: executor/execQual.c:3831 utils/adt/domains.c:146 -#, c-format -msgid "domain %s does not allow null values" -msgstr "Domäne %s erlaubt keine NULL-Werte" - -#: executor/execQual.c:3868 utils/adt/domains.c:188 -#, c-format -msgid "value for domain %s violates check constraint \"%s\"" -msgstr "Wert für Domäne %s verletzt Check-Constraint »%s«" - -#: executor/execQual.c:4209 -#, c-format -msgid "WHERE CURRENT OF is not supported for this table type" -msgstr "WHERE CURRENT OF wird für diesen Tabellentyp nicht unterstützt" - -#: executor/execQual.c:4397 parser/parse_agg.c:764 -#, c-format -msgid "window function calls cannot be nested" -msgstr "Aufrufe von Fensterfunktionen können nicht geschachtelt werden" - -#: executor/execQual.c:4614 -#, c-format -msgid "target type is not an array" -msgstr "Zieltyp ist kein Array" - -#: executor/execQual.c:4730 -#, c-format -msgid "ROW() column has type %s instead of type %s" -msgstr "ROW()-Spalte hat Typ %s statt Typ %s" - -#: executor/execReplication.c:195 executor/execReplication.c:342 -#, c-format -msgid "concurrent update, retrying" -msgstr "" - -#: executor/execReplication.c:544 -#, fuzzy, c-format -#| msgid "cannot alter type \"%s\" because it is the type of a typed table" -msgid "cannot update table \"%s\" because it does not have replica identity and publishes updates" -msgstr "kann Typ »%s« nicht ändern, weil er der Typ einer getypten Tabelle ist" - -#: executor/execReplication.c:546 -#, c-format -msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." -msgstr "" - -#: executor/execReplication.c:550 -#, fuzzy, c-format -#| msgid "cannot alter type \"%s\" because it is the type of a typed table" -msgid "cannot delete from table \"%s\" because it does not have replica identity and publishes deletes" -msgstr "kann Typ »%s« nicht ändern, weil er der Typ einer getypten Tabelle ist" - -#: executor/execReplication.c:552 -#, c-format -msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." -msgstr "" - -#: executor/execUtils.c:808 +#: executor/execUtils.c:687 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "materialisierte Sicht »%s« wurde noch nicht befüllt" -#: executor/execUtils.c:810 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Verwenden Sie den Befehl REFRESH MATERIALIZED VIEW." @@ -10780,278 +11484,320 @@ msgstr "Verwenden Sie den Befehl REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "konnte tatsächlichen Typ von Argument mit deklarierten Typ %s nicht bestimmen" -#: executor/functions.c:519 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "COPY vom/zum Client funktioniert in einer SQL-Funktion nicht" #. translator: %s is a SQL statement name -#: executor/functions.c:525 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s ist in SQL-Funktionen nicht erlaubt" #. translator: %s is a SQL statement name -#: executor/functions.c:533 executor/spi.c:1281 executor/spi.c:2052 +#: executor/functions.c:535 executor/spi.c:1422 executor/spi.c:2212 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s ist in als nicht »volatile« markierten Funktionen nicht erlaubt" -#: executor/functions.c:653 +#: executor/functions.c:656 #, c-format msgid "could not determine actual result type for function declared to return type %s" msgstr "konnte tatsächlichen Ergebnistyp von Funktion mit deklarierten Rückgabetyp %s nicht bestimmen" -#: executor/functions.c:1408 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "SQL-Funktion »%s« Anweisung %d" -#: executor/functions.c:1434 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "SQL-Funktion »%s« beim Start" -#: executor/functions.c:1592 executor/functions.c:1629 -#: executor/functions.c:1641 executor/functions.c:1754 -#: executor/functions.c:1787 executor/functions.c:1817 +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "Aufruf von Prozeduren mit Ausgabeargumenten wird in SQL-Funktionen nicht unterstützt" + +#: executor/functions.c:1657 executor/functions.c:1690 +#: executor/functions.c:1702 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "Rückgabetyp von Funktion stimmt nicht überein; deklariert als %s" -#: executor/functions.c:1594 +#: executor/functions.c:1659 #, c-format msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." msgstr "Die letzte Anweisung der Funktion muss ein SELECT oder INSERT/UPDATE/DELETE RETURNING sein." -#: executor/functions.c:1631 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." msgstr "Die letzte Anweisung muss genau eine Spalte zurückgeben." -#: executor/functions.c:1643 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." msgstr "Eigentlicher Rückgabetyp ist %s." -#: executor/functions.c:1756 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "Die letzte Anweisung gibt zu viele Spalten zurück." -#: executor/functions.c:1789 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "Die letzte Anweisung ergibt %s statt %s in Spalte %d." -#: executor/functions.c:1819 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "Die letzte Anweisung gibt zu wenige Spalten zurück." -#: executor/functions.c:1868 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "Rückgabetyp %s wird von SQL-Funktionen nicht unterstützt" -#: executor/nodeAgg.c:3121 +#: executor/nodeAgg.c:2806 parser/parse_agg.c:633 parser/parse_agg.c:663 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "Kombinierfunktion für Aggregatfunktion %u muss als STRICT deklariert sein" +msgid "aggregate function calls cannot be nested" +msgstr "Aufrufe von Aggregatfunktionen können nicht geschachtelt werden" -#: executor/nodeAgg.c:3166 executor/nodeWindowAgg.c:2282 +#: executor/nodeAgg.c:2992 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "Aggregatfunktion %u muss kompatiblen Eingabe- und Übergangstyp haben" -#: executor/nodeAgg.c:3220 parser/parse_agg.c:618 parser/parse_agg.c:648 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "Aufrufe von Aggregatfunktionen können nicht geschachtelt werden" - -#: executor/nodeCustom.c:146 executor/nodeCustom.c:157 +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "Custom-Scan »%s« unterstützt MarkPos nicht" -#: executor/nodeHashjoin.c:768 executor/nodeHashjoin.c:798 +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "konnte Position in temporärer Datei für Hash-Verbund nicht auf Anfang setzen: %m" -#: executor/nodeHashjoin.c:833 executor/nodeHashjoin.c:839 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "konnte nicht in temporäre Datei für Hash-Verbund schreiben: %m" -#: executor/nodeHashjoin.c:880 executor/nodeHashjoin.c:890 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "konnte nicht aus temporärer Datei für Hash-Verbund lesen: %m" -#: executor/nodeIndexonlyscan.c:233 +#: executor/nodeIndexonlyscan.c:236 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "verlustbehaftete Abstandsfunktionen werden in Index-Only-Scans nicht unterstützt" -#: executor/nodeLimit.c:252 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET darf nicht negativ sein" -#: executor/nodeLimit.c:278 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT darf nicht negativ sein" -#: executor/nodeMergejoin.c:1535 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unterstützt" -#: executor/nodeMergejoin.c:1555 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOIN wird nur für Merge-Verbund-fähige Verbundbedingungen unterstützt" -#: executor/nodeModifyTable.c:96 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "Anfrage hat zu viele Spalten." -#: executor/nodeModifyTable.c:123 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "Anfrage liefert einen Wert für eine gelöschte Spalte auf Position %d." -#: executor/nodeModifyTable.c:131 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." msgstr "Anfrage hat zu wenige Spalten." -#: executor/nodeModifyTable.c:1201 +#: executor/nodeModifyTable.c:773 +#, fuzzy, c-format +#| msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" + +#: executor/nodeModifyTable.c:1085 +#, fuzzy, c-format +#| msgid "invalid OWNED BY option" +msgid "invalid ON UPDATE specification" +msgstr "ungültige OWNED BY Option" + +#: executor/nodeModifyTable.c:1086 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "" + +#: executor/nodeModifyTable.c:1261 +#, fuzzy, c-format +#| msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "das zu aktualisierende Tupel wurde schon durch eine vom aktuellen Befehl ausgelöste Operation verändert" + +#: executor/nodeModifyTable.c:1412 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "Befehl in ON CONFLICT DO UPDATE kann eine Zeile nicht ein zweites Mal ändern" -#: executor/nodeModifyTable.c:1202 +#: executor/nodeModifyTable.c:1413 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "Stellen Sie sicher, dass keine im selben Befehl fürs Einfügen vorgesehene Zeilen doppelte Werte haben, die einen Constraint verletzen würden." -#: executor/nodeSamplescan.c:305 +#: executor/nodeSamplescan.c:279 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "Parameter von TABLESAMPLE darf nicht NULL sein" -#: executor/nodeSamplescan.c:317 +#: executor/nodeSamplescan.c:291 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "Parameter von TABLESAMPLE REPEATABLE darf nicht NULL sein" -#: executor/nodeSubplan.c:339 executor/nodeSubplan.c:378 -#: executor/nodeSubplan.c:1028 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1136 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "als Ausdruck verwendete Unteranfrage ergab mehr als eine Zeile" -#: executor/nodeTableFuncscan.c:369 -#, fuzzy, c-format -#| msgid "slot name must not be null" +#: executor/nodeTableFuncscan.c:375 +#, c-format msgid "namespace URI must not be null" -msgstr "Slot-Name darf nicht NULL sein" +msgstr "Namensraum-URI darf nicht NULL sein" -#: executor/nodeTableFuncscan.c:380 -#, fuzzy, c-format -#| msgid "FOREACH expression must not be null" +#: executor/nodeTableFuncscan.c:389 +#, c-format msgid "row filter expression must not be null" -msgstr "FOREACH-Ausdruck darf nicht NULL sein" +msgstr "Zeilenfilterausdruck darf nicht NULL sein" -#: executor/nodeTableFuncscan.c:405 -#, fuzzy, c-format -#| msgid "FOREACH expression must not be null" +#: executor/nodeTableFuncscan.c:415 +#, c-format msgid "column filter expression must not be null" -msgstr "FOREACH-Ausdruck darf nicht NULL sein" +msgstr "Spaltenfilterausdruck darf nicht NULL sein" -#: executor/nodeTableFuncscan.c:406 -#, fuzzy, c-format -#| msgid "missing data for column \"%s\"" +#: executor/nodeTableFuncscan.c:416 +#, c-format msgid "Filter for column \"%s\" is null." -msgstr "fehlende Daten für Spalte »%s«" +msgstr "Filter für Spalte »%s« ist NULL." -#: executor/nodeTableFuncscan.c:485 -#, fuzzy, c-format -#| msgid "cannot alter inherited column \"%s\"" +#: executor/nodeTableFuncscan.c:506 +#, c-format msgid "null is not allowed in column \"%s\"" -msgstr "kann vererbte Spalte »%s« nicht ändern" +msgstr "NULL ist in Spalte »%s« nicht erlaubt" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeWindowAgg.c:355 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "Moving-Aggregat-Übergangsfunktion darf nicht NULL zurückgeben" -#: executor/nodeWindowAgg.c:1621 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "Frame-Start-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:1634 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "Frame-Start-Offset darf nicht negativ sein" -#: executor/nodeWindowAgg.c:1646 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "Frame-Ende-Offset darf nicht NULL sein" -#: executor/nodeWindowAgg.c:1659 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "Frame-Ende-Offset darf nicht negativ sein" -#: executor/spi.c:196 +#: executor/nodeWindowAgg.c:2738 +#, fuzzy, c-format +#| msgid "aggregate function calls cannot contain window function calls" +msgid "aggregate function %s does not support use as a window function" +msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Fensterfunktionen enthalten" + +#: executor/spi.c:233 executor/spi.c:272 +#, fuzzy, c-format +#| msgid "invalid next transaction ID" +msgid "invalid transaction termination" +msgstr "ungültige nächste Transaktions-ID" + +#: executor/spi.c:247 +#, fuzzy, c-format +#| msgid "cannot commit subtransactions during a parallel operation" +msgid "cannot commit while a subtransaction is active" +msgstr "während einer parallelen Operation können keine Subtransaktionen committet werden" + +#: executor/spi.c:278 +#, fuzzy, c-format +#| msgid "%s cannot run inside a subtransaction" +msgid "cannot roll back while a subtransaction is active" +msgstr "%s kann nicht in einer Subtransaktion laufen" + +#: executor/spi.c:317 #, c-format msgid "transaction left non-empty SPI stack" msgstr "Transaktion ließ nicht-leeren SPI-Stack zurück" -#: executor/spi.c:197 executor/spi.c:260 +#: executor/spi.c:318 executor/spi.c:381 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "Prüfen Sie, ob Aufrufe von »SPI_finish« fehlen." -#: executor/spi.c:259 +#: executor/spi.c:380 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "Subtransaktion ließ nicht-leeren SPI-Stack zurück" -#: executor/spi.c:1142 +#: executor/spi.c:1283 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "Plan mit mehreren Anfragen kann nicht als Cursor geöffnet werden" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1147 +#: executor/spi.c:1288 #, c-format msgid "cannot open %s query as cursor" msgstr "%s kann nicht als Cursor geöffnet werden" -#: executor/spi.c:1255 +#: executor/spi.c:1393 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE wird nicht unterstützt" -#: executor/spi.c:1256 parser/analyze.c:2442 +#: executor/spi.c:1394 parser/analyze.c:2480 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Scrollbare Cursor müssen READ ONLY sein." -#: executor/spi.c:2355 +#: executor/spi.c:2534 #, c-format msgid "SQL statement \"%s\"" msgstr "SQL-Anweisung »%s«" -#: executor/tqueue.c:317 +#: executor/tqueue.c:70 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "konnte Tupel nicht an Shared-Memory-Queue senden" @@ -11071,652 +11817,743 @@ msgstr "ungültige Option »%s«" msgid "Valid options in this context are: %s" msgstr "Gültige Optionen in diesem Zusammenhang sind: %s" -#: gram.y:1060 +#: gram.y:1026 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD wird nicht mehr unterstützt" + +#: gram.y:1027 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Lassen Sie UNENCRYPTED weg, um das Passwort stattdessen in verschlüsselter Form zu speichern." + +#: gram.y:1089 #, c-format msgid "unrecognized role option \"%s\"" msgstr "unbekannte Rollenoption »%s«" -#: gram.y:1334 gram.y:1349 +#: gram.y:1336 gram.y:1351 #, c-format msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTS kann keine Schemaelemente enthalten" -#: gram.y:1494 +#: gram.y:1496 #, c-format msgid "current database cannot be changed" msgstr "aktuelle Datenbank kann nicht geändert werden" -#: gram.y:1618 +#: gram.y:1620 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" msgstr "Zeitzonenintervall muss HOUR oder HOUR TO MINUTE sein" -#: gram.y:2769 gram.y:2798 +#: gram.y:2138 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "Spaltennummer muss im Bereich 1 bis %d sein" + +#: gram.y:2677 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "Sequenzoption »%s« wird hier nicht unterstützt" + +#: gram.y:2706 +#, fuzzy, c-format +#| msgid "option \"%s\" provided more than once" +msgid "modulus for hash partition provided more than once" +msgstr "Option »%s« mehrmals angegeben" + +#: gram.y:2715 +#, fuzzy, c-format +#| msgid "option \"%s\" provided more than once" +msgid "remainder for hash partition provided more than once" +msgstr "Option »%s« mehrmals angegeben" + +#: gram.y:2722 +#, fuzzy, c-format +#| msgid "unrecognized exception condition \"%s\"" +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "unbekannte Ausnahmebedingung »%s«" + +#: gram.y:2730 +#, fuzzy, c-format +#| msgid "type output function must be specified" +msgid "modulus for hash partition must be specified" +msgstr "Typausgabefunktion muss angegeben werden" + +#: gram.y:2734 +#, fuzzy, c-format +#| msgid "one or two argument types must be specified" +msgid "remainder for hash partition must be specified" +msgstr "ein oder zwei Argumenttypen müssen angegeben werden" + +#: gram.y:2986 gram.y:3015 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "STDIN/STDOUT sind nicht mit PROGRAM erlaubt" -#: gram.y:3108 gram.y:3115 gram.y:10841 gram.y:10849 +#: gram.y:3325 gram.y:3332 gram.y:11462 gram.y:11470 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "die Verwendung von GLOBAL beim Erzeugen einer temporären Tabelle ist veraltet" -#: gram.y:3592 utils/adt/ri_triggers.c:314 utils/adt/ri_triggers.c:371 -#: utils/adt/ri_triggers.c:790 utils/adt/ri_triggers.c:1013 -#: utils/adt/ri_triggers.c:1169 utils/adt/ri_triggers.c:1350 -#: utils/adt/ri_triggers.c:1515 utils/adt/ri_triggers.c:1691 -#: utils/adt/ri_triggers.c:1871 utils/adt/ri_triggers.c:2062 -#: utils/adt/ri_triggers.c:2120 utils/adt/ri_triggers.c:2225 -#: utils/adt/ri_triggers.c:2402 +#: gram.y:3814 utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 +#: utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 +#: utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 +#: utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 +#: utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MATCH PARTIAL ist noch nicht implementiert" -#: gram.y:4983 -#, fuzzy, c-format -#| msgid "unrecognized role option \"%s\"" +#: gram.y:5296 +#, c-format msgid "unrecognized row security option \"%s\"" -msgstr "unbekannte Rollenoption »%s«" +msgstr "unbekannte Zeilensicherheitsoption »%s«" -#: gram.y:4984 +#: gram.y:5297 #, c-format msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." -msgstr "" +msgstr "Aktuell werden nur PERMISSIVE und RESTRICTIVE unterstützt." -#: gram.y:5092 +#: gram.y:5405 msgid "duplicate trigger events specified" msgstr "mehrere Trigger-Ereignisse angegeben" -#: gram.y:5228 parser/parse_utilcmd.c:2794 parser/parse_utilcmd.c:2820 +#: gram.y:5546 parser/parse_utilcmd.c:3313 parser/parse_utilcmd.c:3339 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "Constraint, der als INITIALLY DEFERRED deklariert wurde, muss DEFERRABLE sein" -#: gram.y:5235 +#: gram.y:5553 #, c-format msgid "conflicting constraint properties" msgstr "widersprüchliche Constraint-Eigentschaften" -#: gram.y:5341 +#: gram.y:5659 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "CREATE ASSERTION ist noch nicht implementiert" -#: gram.y:5356 +#: gram.y:5674 #, c-format msgid "DROP ASSERTION is not yet implemented" msgstr "DROP ASSERTION ist noch nicht implementiert" -#: gram.y:5740 +#: gram.y:6054 #, c-format msgid "RECHECK is no longer required" msgstr "RECHECK wird nicht mehr benötigt" -#: gram.y:5741 +#: gram.y:6055 #, c-format msgid "Update your data type." msgstr "Aktualisieren Sie Ihren Datentyp." -#: gram.y:7350 +#: gram.y:7791 #, c-format msgid "aggregates cannot have output arguments" msgstr "Aggregatfunktionen können keine OUT-Argumente haben" -#: gram.y:7679 utils/adt/regproc.c:776 utils/adt/regproc.c:817 +#: gram.y:8179 utils/adt/regproc.c:691 utils/adt/regproc.c:732 #, c-format msgid "missing argument" msgstr "Argument fehlt" -#: gram.y:7680 utils/adt/regproc.c:777 utils/adt/regproc.c:818 +#: gram.y:8180 utils/adt/regproc.c:692 utils/adt/regproc.c:733 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." msgstr "Verwenden Sie NONE, um das fehlende Argument eines unären Operators anzugeben." -#: gram.y:9125 -#, fuzzy, c-format -#| msgid "unrecognized role option \"%s\"" -msgid "unrecognized option \"%s\"" -msgstr "unbekannte Rollenoption »%s«" - -#: gram.y:9450 gram.y:9468 +#: gram.y:10045 gram.y:10063 #, c-format msgid "WITH CHECK OPTION not supported on recursive views" msgstr "WITH CHECK OPTION wird für rekursive Sichten nicht unterstützt" -#: gram.y:9986 +#: gram.y:10560 #, c-format msgid "unrecognized VACUUM option \"%s\"" msgstr "unbekannte VACUUM-Option »%s«" -#: gram.y:10949 +#: gram.y:11570 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "Syntax LIMIT x,y wird nicht unterstützt" -#: gram.y:10950 +#: gram.y:11571 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "Verwenden Sie die getrennten Klauseln LIMIT und OFFSET." -#: gram.y:11231 gram.y:11256 +#: gram.y:11869 gram.y:11894 #, c-format msgid "VALUES in FROM must have an alias" msgstr "VALUES in FROM muss Aliasnamen erhalten" -#: gram.y:11232 gram.y:11257 +#: gram.y:11870 gram.y:11895 #, c-format msgid "For example, FROM (VALUES ...) [AS] foo." msgstr "Zum Beispiel FROM (VALUES ...) [AS] xyz." -#: gram.y:11237 gram.y:11262 +#: gram.y:11875 gram.y:11900 #, c-format msgid "subquery in FROM must have an alias" msgstr "Unteranfrage in FROM muss Aliasnamen erhalten" -#: gram.y:11238 gram.y:11263 +#: gram.y:11876 gram.y:11901 #, c-format msgid "For example, FROM (SELECT ...) [AS] foo." msgstr "Zum Beispiel FROM (SELECT ...) [AS] xyz." -#: gram.y:11716 +#: gram.y:12354 #, c-format msgid "only one DEFAULT value is allowed" -msgstr "" +msgstr "nur ein DEFAULT-Wert ist erlaubt" -#: gram.y:11725 +#: gram.y:12363 #, c-format msgid "only one PATH value per column is allowed" -msgstr "" +msgstr "nur ein PATH-Wert pro Spalte ist erlaubt" -#: gram.y:11734 -#, fuzzy, c-format -#| msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +#: gram.y:12372 +#, c-format msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" -msgstr "widersprüchliche NULL/NOT NULL-Deklarationen für Spalte »%s« von Tabelle »%s«" +msgstr "widersprüchliche oder überflüssige NULL/NOT NULL-Deklarationen für Spalte »%s«" -#: gram.y:11743 -#, fuzzy, c-format -#| msgid "unrecognized role option \"%s\"" +#: gram.y:12381 +#, c-format msgid "unrecognized column option \"%s\"" -msgstr "unbekannte Rollenoption »%s«" +msgstr "unbekannte Spaltenoption »%s«" -#: gram.y:11997 +#: gram.y:12635 #, c-format msgid "precision for type float must be at least 1 bit" msgstr "Präzision von Typ float muss mindestens 1 Bit sein" -#: gram.y:12006 +#: gram.y:12644 #, c-format msgid "precision for type float must be less than 54 bits" msgstr "Präzision von Typ float muss weniger als 54 Bits sein" -#: gram.y:12497 +#: gram.y:13135 #, c-format msgid "wrong number of parameters on left side of OVERLAPS expression" msgstr "falsche Anzahl Parameter auf linker Seite von OVERLAPS-Ausdruck" -#: gram.y:12502 +#: gram.y:13140 #, c-format msgid "wrong number of parameters on right side of OVERLAPS expression" msgstr "falsche Anzahl Parameter auf rechter Seite von OVERLAPS-Ausdruck" -#: gram.y:12677 +#: gram.y:13315 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "UNIQUE-Prädikat ist noch nicht implementiert" -#: gram.y:13024 +#: gram.y:13662 #, c-format msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" msgstr "in WITHIN GROUP können nicht mehrere ORDER-BY-Klauseln verwendet werden" -#: gram.y:13029 +#: gram.y:13667 #, c-format msgid "cannot use DISTINCT with WITHIN GROUP" msgstr "DISTINCT kann nicht mit WITHIN GROUP verwendet werden" -#: gram.y:13034 +#: gram.y:13672 #, c-format msgid "cannot use VARIADIC with WITHIN GROUP" msgstr "VARIADIC kann nicht mit WITHIN GROUP verwendet werden" -#: gram.y:13460 -#, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING wird nur mit UNBOUNDED unterstützt" - -#: gram.y:13466 -#, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING wird nur mit UNBOUNDED unterstützt" - -#: gram.y:13493 gram.y:13516 +#: gram.y:14125 gram.y:14148 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" msgstr "Frame-Beginn kann nicht UNBOUNDED FOLLOWING sein" -#: gram.y:13498 +#: gram.y:14130 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "Frame der in der folgenden Zeile beginnt kann nicht in der aktuellen Zeile enden" -#: gram.y:13521 +#: gram.y:14153 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" msgstr "Frame-Ende kann nicht UNBOUNDED PRECEDING sein" -#: gram.y:13527 +#: gram.y:14159 #, c-format msgid "frame starting from current row cannot have preceding rows" msgstr "Frame der in der aktuellen Zeile beginnt kann keine vorhergehenden Zeilen haben" -#: gram.y:13534 +#: gram.y:14166 #, c-format msgid "frame starting from following row cannot have preceding rows" msgstr "Frame der in der folgenden Zeile beginnt kann keine vorhergehenden Zeilen haben" -#: gram.y:14169 +#: gram.y:14809 #, c-format msgid "type modifier cannot have parameter name" msgstr "Typmodifikator kann keinen Parameternamen haben" -#: gram.y:14175 +#: gram.y:14815 #, c-format msgid "type modifier cannot have ORDER BY" msgstr "Typmodifikator kann kein ORDER BY haben" -#: gram.y:14239 gram.y:14245 +#: gram.y:14880 gram.y:14887 #, c-format msgid "%s cannot be used as a role name here" msgstr "%s kann hier nicht als Rollenname verwendet werden" -#: gram.y:14905 gram.y:15094 +#: gram.y:15558 gram.y:15747 msgid "improper use of \"*\"" msgstr "unzulässige Verwendung von »*«" -#: gram.y:15057 gram.y:15074 tsearch/spell.c:954 tsearch/spell.c:971 +#: gram.y:15710 gram.y:15727 tsearch/spell.c:954 tsearch/spell.c:971 #: tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 #, c-format msgid "syntax error" msgstr "Syntaxfehler" -#: gram.y:15158 +#: gram.y:15811 #, c-format msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" msgstr "eine Ordered-Set-Aggregatfunktion mit einem direkten VARIADIC-Argument muss ein aggregiertes VARIADIC-Argument des selben Datentyps haben" -#: gram.y:15195 +#: gram.y:15848 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "mehrere ORDER-BY-Klauseln sind nicht erlaubt" -#: gram.y:15206 +#: gram.y:15859 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "mehrere OFFSET-Klauseln sind nicht erlaubt" -#: gram.y:15215 +#: gram.y:15868 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "mehrere LIMIT-Klauseln sind nicht erlaubt" -#: gram.y:15224 +#: gram.y:15877 #, c-format msgid "multiple WITH clauses not allowed" msgstr "mehrere WITH-Klauseln sind nicht erlaubt" -#: gram.y:15428 +#: gram.y:16081 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "OUT- und INOUT-Argumente sind in TABLE-Funktionen nicht erlaubt" -#: gram.y:15529 +#: gram.y:16182 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "mehrere COLLATE-Klauseln sind nicht erlaubt" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15567 gram.y:15580 +#: gram.y:16220 gram.y:16233 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "%s-Constraints können nicht als DEFERRABLE markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15593 +#: gram.y:16246 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "%s-Constraints können nicht als NOT VALID markiert werden" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15606 +#: gram.y:16259 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "%s-Constraints können nicht als NO INHERIT markiert werden" -#: guc-file.l:313 +#: guc-file.l:316 #, c-format msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" msgstr "unbekannter Konfigurationsparameter »%s« in Datei »%s« Zeile %u" -#: guc-file.l:350 utils/misc/guc.c:5962 utils/misc/guc.c:6155 -#: utils/misc/guc.c:6245 utils/misc/guc.c:6335 utils/misc/guc.c:6443 -#: utils/misc/guc.c:6538 +#: guc-file.l:353 utils/misc/guc.c:6249 utils/misc/guc.c:6443 +#: utils/misc/guc.c:6533 utils/misc/guc.c:6623 utils/misc/guc.c:6731 +#: utils/misc/guc.c:6826 #, c-format msgid "parameter \"%s\" cannot be changed without restarting the server" msgstr "Parameter »%s« kann nicht geändert werden, ohne den Server neu zu starten" -#: guc-file.l:386 +#: guc-file.l:389 #, c-format msgid "parameter \"%s\" removed from configuration file, reset to default" msgstr "Parameter »%s« wurde aus Konfigurationsdatei entfernt, wird auf Standardwert zurückgesetzt" -#: guc-file.l:452 +#: guc-file.l:455 #, c-format msgid "parameter \"%s\" changed to \"%s\"" msgstr "Parameter »%s« auf »%s« gesetzt" -#: guc-file.l:494 +#: guc-file.l:497 #, c-format msgid "configuration file \"%s\" contains errors" msgstr "Konfigurationsdatei »%s« enthält Fehler" -#: guc-file.l:499 +#: guc-file.l:502 #, c-format msgid "configuration file \"%s\" contains errors; unaffected changes were applied" msgstr "Konfigurationsdatei »%s« enthält Fehler; nicht betroffene Änderungen wurden durchgeführt" -#: guc-file.l:504 +#: guc-file.l:507 #, c-format msgid "configuration file \"%s\" contains errors; no changes were applied" msgstr "Konfigurationsdatei »%s« enthält Fehler; keine Änderungen wurden durchgeführt" -#: guc-file.l:577 +#: guc-file.l:580 #, c-format msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" msgstr "konnte Konfigurationsdatei »%s« nicht öffnen: maximale Verschachtelungstiefe überschritten" -#: guc-file.l:593 libpq/hba.c:1961 libpq/hba.c:2361 +#: guc-file.l:596 libpq/hba.c:2142 libpq/hba.c:2550 #, c-format msgid "could not open configuration file \"%s\": %m" msgstr "konnte Konfigurationsdatei »%s« nicht öffnen: %m" -#: guc-file.l:604 +#: guc-file.l:607 #, c-format msgid "skipping missing configuration file \"%s\"" msgstr "fehlende Konfigurationsdatei »%s« wird übersprungen" -#: guc-file.l:858 +#: guc-file.l:861 #, c-format msgid "syntax error in file \"%s\" line %u, near end of line" msgstr "Syntaxfehler in Datei »%s«, Zeile %u, am Ende der Zeile" -#: guc-file.l:868 +#: guc-file.l:871 #, c-format msgid "syntax error in file \"%s\" line %u, near token \"%s\"" msgstr "Syntaxfehler in Datei »%s«, Zeile %u, bei »%s«" -#: guc-file.l:888 +#: guc-file.l:891 #, c-format msgid "too many syntax errors found, abandoning file \"%s\"" msgstr "zu viele Syntaxfehler gefunden, Datei »%s« wird aufgegeben" -#: guc-file.l:940 +#: guc-file.l:943 #, c-format msgid "could not open configuration directory \"%s\": %m" msgstr "konnte Konfigurationsverzeichnis »%s« nicht öffnen: %m" -#: lib/stringinfo.c:301 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 +#: utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "konnte nicht auf Datei »%s« zugreifen: %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:715 utils/mmgr/dsa.c:797 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Fehler bei DSA-Anfrage mit Größe %zu." + +#: lib/stringinfo.c:278 #, c-format msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." msgstr "Kann Zeichenkettenpuffer mit %d Bytes nicht um %d Bytes vergrößern." -#: libpq/auth-scram.c:200 -#, fuzzy, c-format -#| msgid "User does not have CONNECT privilege." +#: libpq/auth-scram.c:251 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "Client hat einen ungültigen SASL-Authentifizierungsmechanismums gewählt" + +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "ungültiger SCRAM-Verifier für Benutzer »%s«" + +#: libpq/auth-scram.c:283 +#, c-format msgid "User \"%s\" does not have a valid SCRAM verifier." -msgstr "Benutzer hat das CONNECT-Privileg nicht." +msgstr "Benutzer »%s« hat keinen gültigen SCRAM-Verifier." -#: libpq/auth-scram.c:234 +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 +#: libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 +#: libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 +#: libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 +#: libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 #, c-format -msgid "malformed SCRAM message (empty message)" -msgstr "" +msgid "malformed SCRAM message" +msgstr "fehlerhafte SCRAM-Nachricht" -#: libpq/auth-scram.c:238 +#: libpq/auth-scram.c:362 #, c-format -msgid "malformed SCRAM message (length mismatch)" -msgstr "" +msgid "The message is empty." +msgstr "Die Nachricht ist leer." -#: libpq/auth-scram.c:270 +#: libpq/auth-scram.c:367 #, c-format -msgid "invalid SCRAM response (nonce mismatch)" -msgstr "" +msgid "Message length does not match input length." +msgstr "Länge der Nachricht stimmt nicht mit Länge der Eingabe überein." -#: libpq/auth-scram.c:343 -#, fuzzy, c-format -#| msgid "could not generate random encryption vector" +#: libpq/auth-scram.c:399 +#, c-format +msgid "invalid SCRAM response" +msgstr "ungültige SCRAM-Antwort" + +#: libpq/auth-scram.c:400 +#, c-format +msgid "Nonce does not match." +msgstr "Nonce stimmt nicht überein." + +#: libpq/auth-scram.c:474 +#, c-format msgid "could not generate random salt" -msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" +msgstr "konnte zufälliges Salt nicht erzeugen" -#: libpq/auth-scram.c:483 +#: libpq/auth-scram.c:661 #, c-format -msgid "malformed SCRAM message (attribute '%c' expected, %s found)" -msgstr "" +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Attribut »%c« wurde erwartet, aber »%s« wurde gefunden." -#: libpq/auth-scram.c:490 libpq/auth-scram.c:579 +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 #, c-format -msgid "malformed SCRAM message (expected = in attr %c)" -msgstr "" +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Zeichen »=« für Attribut »%c« wurde erwartet." -#: libpq/auth-scram.c:570 +#: libpq/auth-scram.c:780 #, c-format -msgid "malformed SCRAM message (attribute expected, invalid char %s found)" -msgstr "" +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Attribut wurde erwartet, aber ungültiges Zeichen »%s« wurde gefunden." + +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Der Client hat SCRAM-SHA-256-PLUS gewählt, aber die SCRAM-Nachricht enthielt keine Channel-Binding-Daten." + +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Komma wurde erwartet, aber Zeichen »%s« wurde gefunden." + +#: libpq/auth-scram.c:926 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Fehler bei der Aushandlung von SCRAM-Channel-Binding" + +#: libpq/auth-scram.c:927 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Der Client unterstützt SCRAM-Channel-Binding aber glaubt dass der Server es nicht tut. Dieser Server unterstützt jedoch Channel-Binding." -#: libpq/auth-scram.c:692 +#: libpq/auth-scram.c:949 #, c-format -msgid "client requires SCRAM channel binding, but it is not supported" -msgstr "" +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Der Client hat SCRAM-SHA-256 ohne Channel-Binding gewählt, aber die SCRAM-Nachricht enthält Channel-Binding-Daten." -#: libpq/auth-scram.c:696 +#: libpq/auth-scram.c:960 #, c-format -msgid "malformed SCRAM message (unexpected channel-binding flag %s)" -msgstr "" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "nicht unterstützter SCRAM-Channel-Binding-Typ »%s«" -#: libpq/auth-scram.c:702 +#: libpq/auth-scram.c:967 #, c-format -msgid "malformed SCRAM message (comma expected, got %s)" -msgstr "" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Unerwartetes Channel-Binding-Flag »%s«." -#: libpq/auth-scram.c:712 +#: libpq/auth-scram.c:977 #, c-format msgid "client uses authorization identity, but it is not supported" -msgstr "" +msgstr "Client verwendet Autorisierungsidentität, was nicht unterstützt wird" -#: libpq/auth-scram.c:716 +#: libpq/auth-scram.c:982 #, c-format -msgid "malformed SCRAM message (unexpected attribute %s in client-first-message)" -msgstr "" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Unerwartetes Attribut »%s« in »client-first-message«." -#: libpq/auth-scram.c:732 +#: libpq/auth-scram.c:998 #, c-format -msgid "client requires mandatory SCRAM extension" -msgstr "" +msgid "client requires an unsupported SCRAM extension" +msgstr "Client verlangt eine nicht unterstützte SCRAM-Erweiterung" -#: libpq/auth-scram.c:746 +#: libpq/auth-scram.c:1012 #, c-format msgid "non-printable characters in SCRAM nonce" -msgstr "" +msgstr "nicht druckbare Zeichen in SCRAM-Nonce" -#: libpq/auth-scram.c:863 -#, fuzzy, c-format -#| msgid "could not generate random encryption vector" +#: libpq/auth-scram.c:1129 +#, c-format msgid "could not generate random nonce" -msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" +msgstr "konnte zufällige Nonce nicht erzeugen" -#: libpq/auth-scram.c:931 +#: libpq/auth-scram.c:1233 #, c-format -msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgid "SCRAM channel binding check failed" msgstr "" -#: libpq/auth-scram.c:945 +#: libpq/auth-scram.c:1251 #, c-format -msgid "malformed SCRAM message (malformed proof in client-final-message" -msgstr "" +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "unerwartetes SCRAM-Channel-Binding-Attribut in »client-final-message«" -#: libpq/auth-scram.c:952 +#: libpq/auth-scram.c:1268 #, c-format -msgid "malformed SCRAM message (garbage at end of client-final-message)" -msgstr "" +msgid "Malformed proof in client-final-message." +msgstr "Fehlerhafter Proof in »client-final-message«." + +#: libpq/auth-scram.c:1276 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Müll am Ende der »client-final-message« gefunden." -#: libpq/auth.c:280 +#: libpq/auth.c:282 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: Host abgelehnt" -#: libpq/auth.c:283 +#: libpq/auth.c:285 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "»trust«-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:286 +#: libpq/auth.c:288 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "Ident-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:289 +#: libpq/auth.c:291 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "Peer-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:294 +#: libpq/auth.c:296 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "Passwort-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:299 +#: libpq/auth.c:301 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "GSSAPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:302 +#: libpq/auth.c:304 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "SSPI-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:305 +#: libpq/auth.c:307 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "PAM-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:308 +#: libpq/auth.c:310 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "BSD-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:311 +#: libpq/auth.c:313 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "LDAP-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:314 +#: libpq/auth.c:316 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:317 +#: libpq/auth.c:319 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "RADIUS-Authentifizierung für Benutzer »%s« fehlgeschlagen" -#: libpq/auth.c:320 +#: libpq/auth.c:322 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: ungültige Authentifizierungsmethode" -#: libpq/auth.c:324 +#: libpq/auth.c:326 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "Verbindung stimmte mit pg_hba.conf-Zeile %d überein: »%s«" -#: libpq/auth.c:371 +#: libpq/auth.c:373 #, c-format msgid "client certificates can only be checked if a root certificate store is available" msgstr "Client-Zertifikate können nur überprüft werden, wenn Wurzelzertifikat verfügbar ist" -#: libpq/auth.c:382 +#: libpq/auth.c:384 #, c-format msgid "connection requires a valid client certificate" msgstr "Verbindung erfordert ein gültiges Client-Zertifikat" -#: libpq/auth.c:415 +#: libpq/auth.c:417 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf lehnt Replikationsverbindung ab für Host »%s«, Benutzer »%s«, %s" -#: libpq/auth.c:417 libpq/auth.c:433 libpq/auth.c:491 libpq/auth.c:509 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL off" msgstr "SSL aus" -#: libpq/auth.c:417 libpq/auth.c:433 libpq/auth.c:491 libpq/auth.c:509 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL on" msgstr "SSL an" -#: libpq/auth.c:421 +#: libpq/auth.c:423 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "pg_hba.conf lehnt Replikationsverbindung ab für Host »%s«, Benutzer »%s«" -#: libpq/auth.c:430 +#: libpq/auth.c:432 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf lehnt Verbindung ab für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" -#: libpq/auth.c:437 +#: libpq/auth.c:439 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" msgstr "pg_hba.conf lehnt Verbindung ab für Host »%s«, Benutzer »%s«, Datenbank »%s«" -#: libpq/auth.c:466 +#: libpq/auth.c:468 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt überein." -#: libpq/auth.c:469 +#: libpq/auth.c:471 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung nicht geprüft." -#: libpq/auth.c:472 +#: libpq/auth.c:474 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "Auflösung der Client-IP-Adresse ergab »%s«, Vorwärtsauflösung stimmt nicht überein." -#: libpq/auth.c:475 +#: libpq/auth.c:477 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "Konnte Client-Hostnamen »%s« nicht in IP-Adresse übersetzen: %s." -#: libpq/auth.c:480 +#: libpq/auth.c:482 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "Konnte Client-IP-Adresse nicht in einen Hostnamen auflösen: %s." -#: libpq/auth.c:489 +#: libpq/auth.c:491 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "kein pg_hba.conf-Eintrag für Replikationsverbindung von Host »%s«, Benutzer »%s«, %s" -#: libpq/auth.c:496 +#: libpq/auth.c:498 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" msgstr "kein pg_hba.conf-Eintrag für Replikationsverbindung von Host »%s«, Benutzer »%s«" -#: libpq/auth.c:506 +#: libpq/auth.c:508 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "kein pg_hba.conf-Eintrag für Host »%s«, Benutzer »%s«, Datenbank »%s«, %s" -#: libpq/auth.c:514 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "kein pg_hba.conf-Eintrag für Host »%s«, Benutzer »%s«, Datenbank »%s«" @@ -11731,1100 +12568,1178 @@ msgstr "Passwort-Antwort erwartet, Message-Typ %d empfangen" msgid "invalid password packet size" msgstr "ungültige Größe des Passwortpakets" -#: libpq/auth.c:727 libpq/hba.c:1319 +#: libpq/auth.c:715 +#, c-format +msgid "empty password returned by client" +msgstr "Client gab leeres Passwort zurück" + +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" msgstr "MD5-Authentifizierung wird nicht unterstützt, wenn »db_user_namespace« angeschaltet ist" -#: libpq/auth.c:733 -#, fuzzy, c-format -#| msgid "could not generate random encryption vector" +#: libpq/auth.c:841 +#, c-format msgid "could not generate random MD5 salt" -msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" +msgstr "konnte zufälliges MD5-Salt nicht erzeugen" -#: libpq/auth.c:812 -#, fuzzy, c-format -#| msgid "SSPI is not supported in protocol version 2" +#: libpq/auth.c:887 +#, c-format msgid "SASL authentication is not supported in protocol version 2" -msgstr "SSL wird in Protokollversion 2 nicht unterstützt" +msgstr "SASL-Authentifizierung wird in Protokollversion 2 nicht unterstützt" -#: libpq/auth.c:852 -#, fuzzy, c-format -#| msgid "expected GSS response, got message type %d" +#: libpq/auth.c:920 +#, c-format msgid "expected SASL response, got message type %d" -msgstr "GSS-Antwort erwartet, Message-Typ %d empfangen" +msgstr "SASL-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:989 +#: libpq/auth.c:1112 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "GSSAPI wird in Protokollversion 2 nicht unterstützt" -#: libpq/auth.c:1049 +#: libpq/auth.c:1172 #, c-format msgid "expected GSS response, got message type %d" msgstr "GSS-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:1111 +#: libpq/auth.c:1234 msgid "accepting GSS security context failed" msgstr "Annahme des GSS-Sicherheitskontexts fehlgeschlagen" -#: libpq/auth.c:1137 +#: libpq/auth.c:1260 msgid "retrieving GSS user name failed" msgstr "Abfrage des GSS-Benutzernamens fehlgeschlagen" -#: libpq/auth.c:1256 +#: libpq/auth.c:1385 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "SSL wird in Protokollversion 2 nicht unterstützt" -#: libpq/auth.c:1271 +#: libpq/auth.c:1400 msgid "could not acquire SSPI credentials" msgstr "konnte SSPI-Credentials nicht erhalten" -#: libpq/auth.c:1289 +#: libpq/auth.c:1418 #, c-format msgid "expected SSPI response, got message type %d" msgstr "SSPI-Antwort erwartet, Message-Typ %d empfangen" -#: libpq/auth.c:1362 +#: libpq/auth.c:1491 msgid "could not accept SSPI security context" msgstr "konnte SSPI-Sicherheitskontext nicht akzeptieren" -#: libpq/auth.c:1424 +#: libpq/auth.c:1553 msgid "could not get token from SSPI security context" msgstr "konnte kein Token vom SSPI-Sicherheitskontext erhalten" -#: libpq/auth.c:1543 libpq/auth.c:1562 +#: libpq/auth.c:1672 libpq/auth.c:1691 #, c-format msgid "could not translate name" msgstr "konnte Namen nicht umwandeln" -#: libpq/auth.c:1575 +#: libpq/auth.c:1704 #, c-format msgid "realm name too long" msgstr "Realm-Name zu lang" -#: libpq/auth.c:1590 +#: libpq/auth.c:1719 #, c-format msgid "translated account name too long" msgstr "umgewandelter Account-Name zu lang" -#: libpq/auth.c:1776 +#: libpq/auth.c:1905 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "konnte Socket für Ident-Verbindung nicht erzeugen: %m" -#: libpq/auth.c:1791 +#: libpq/auth.c:1920 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "konnte nicht mit lokaler Adresse »%s« verbinden: %m" -#: libpq/auth.c:1803 +#: libpq/auth.c:1932 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "konnte nicht mit Ident-Server auf Adresse »%s«, Port %s verbinden: %m" -#: libpq/auth.c:1825 +#: libpq/auth.c:1954 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "konnte Anfrage an Ident-Server auf Adresse »%s«, Port %s nicht senden: %m" -#: libpq/auth.c:1842 +#: libpq/auth.c:1971 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "konnte Antwort von Ident-Server auf Adresse »%s«, Port %s nicht empfangen: %m" -#: libpq/auth.c:1852 +#: libpq/auth.c:1981 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "ungültig formatierte Antwort vom Ident-Server: »%s«" -#: libpq/auth.c:1892 +#: libpq/auth.c:2021 #, c-format msgid "peer authentication is not supported on this platform" msgstr "Peer-Authentifizierung wird auf dieser Plattform nicht unterstützt" -#: libpq/auth.c:1896 +#: libpq/auth.c:2025 #, c-format msgid "could not get peer credentials: %m" msgstr "konnte Credentials von Gegenstelle nicht ermitteln: %m" -#: libpq/auth.c:1905 +#: libpq/auth.c:2036 #, c-format msgid "could not look up local user ID %ld: %s" msgstr "konnte lokale Benutzer-ID %ld nicht nachschlagen: %s" -#: libpq/auth.c:1989 libpq/auth.c:2315 libpq/auth.c:2675 -#, c-format -msgid "empty password returned by client" -msgstr "Client gab leeres Passwort zurück" - -#: libpq/auth.c:1999 +#: libpq/auth.c:2124 #, c-format msgid "error from underlying PAM layer: %s" msgstr "Fehler von der unteren PAM-Ebene: %s" -#: libpq/auth.c:2080 +#: libpq/auth.c:2193 #, c-format msgid "could not create PAM authenticator: %s" msgstr "konnte PAM-Authenticator nicht erzeugen: %s" -#: libpq/auth.c:2091 +#: libpq/auth.c:2204 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER) fehlgeschlagen: %s" -#: libpq/auth.c:2102 +#: libpq/auth.c:2236 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST) fehlgeschlagen: %s" -#: libpq/auth.c:2113 +#: libpq/auth.c:2248 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "pam_set_item(PAM_CONV) fehlgeschlagen: %s" -#: libpq/auth.c:2124 +#: libpq/auth.c:2259 #, c-format msgid "pam_authenticate failed: %s" msgstr "pam_authenticate fehlgeschlagen: %s" -#: libpq/auth.c:2135 +#: libpq/auth.c:2270 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmt fehlgeschlagen: %s" -#: libpq/auth.c:2146 +#: libpq/auth.c:2281 #, c-format msgid "could not release PAM authenticator: %s" msgstr "konnte PAM-Authenticator nicht freigeben: %s" -#: libpq/auth.c:2211 -#, c-format -msgid "could not initialize LDAP: %m" -msgstr "konnte LDAP nicht initialisieren: %m" - -#: libpq/auth.c:2214 +#: libpq/auth.c:2357 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "konnte LDAP nicht initialisieren: Fehlercode %d" -#: libpq/auth.c:2224 +#: libpq/auth.c:2406 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "konnte LDAP nicht initialisieren: %s" + +#: libpq/auth.c:2416 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps wird mit dieser LDAP-Bibliothek nicht unterstützt" + +#: libpq/auth.c:2424 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "konnte LDAP nicht initialisieren: %m" + +#: libpq/auth.c:2434 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "konnte LDAP-Protokollversion nicht setzen: %s" -#: libpq/auth.c:2253 +#: libpq/auth.c:2465 #, c-format msgid "could not load wldap32.dll" msgstr "konnte wldap32.dll nicht laden" -#: libpq/auth.c:2261 +#: libpq/auth.c:2473 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "konnte Funktion _ldap_start_tls_sA in wldap32.dll nicht laden" -#: libpq/auth.c:2262 +#: libpq/auth.c:2474 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "LDAP über SSL wird auf dieser Plattform nicht unterstützt." -#: libpq/auth.c:2277 +#: libpq/auth.c:2489 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "konnte LDAP-TLS-Sitzung nicht starten: %s" -#: libpq/auth.c:2299 +#: libpq/auth.c:2552 #, c-format msgid "LDAP server not specified" msgstr "LDAP-Server nicht angegeben" -#: libpq/auth.c:2352 +#: libpq/auth.c:2607 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "ungültiges Zeichen im Benutzernamen für LDAP-Authentifizierung" -#: libpq/auth.c:2367 +#: libpq/auth.c:2624 #, c-format msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "erstes LDAP-Binden für ldapbinddn »%s« auf Server »%s« fehlgeschlagen: %s" -#: libpq/auth.c:2391 +#: libpq/auth.c:2653 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "konnte LDAP nicht mit Filter »%s« auf Server »%s« durchsuchen: %s" -#: libpq/auth.c:2402 +#: libpq/auth.c:2667 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "LDAP-Benutzer »%s« existiert nicht" -#: libpq/auth.c:2403 +#: libpq/auth.c:2668 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "LDAP-Suche nach Filter »%s« auf Server »%s« gab keine Einträge zurück." -#: libpq/auth.c:2407 +#: libpq/auth.c:2672 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "LDAP-Benutzer »%s« ist nicht eindeutig" -#: libpq/auth.c:2408 +#: libpq/auth.c:2673 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Eintrag zurück." msgstr[1] "LDAP-Suche nach Filter »%s« auf Server »%s« gab %d Einträge zurück." -#: libpq/auth.c:2426 +#: libpq/auth.c:2693 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "konnte DN fÅ©r den ersten Treffer für »%s« auf Server »%s« nicht lesen: %s" -#: libpq/auth.c:2446 +#: libpq/auth.c:2714 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "Losbinden fehlgeschlagen nach Suche nach Benutzer »%s« auf Server »%s«: %s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "Losbinden fehlgeschlagen nach Suche nach Benutzer »%s« auf Server »%s«" -#: libpq/auth.c:2476 +#: libpq/auth.c:2745 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "LDAP-Login fehlgeschlagen für Benutzer »%s« auf Server »%s«: %s" -#: libpq/auth.c:2504 +#: libpq/auth.c:2774 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP-Diagnostik: %s" + +#: libpq/auth.c:2799 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "Zertifikatauthentifizierung für Benutzer »%s« fehlgeschlagen: Client-Zertifikat enthält keinen Benutzernamen" -#: libpq/auth.c:2631 +#: libpq/auth.c:2902 #, c-format msgid "RADIUS server not specified" msgstr "RADIUS-Server nicht angegeben" -#: libpq/auth.c:2638 +#: libpq/auth.c:2909 #, c-format msgid "RADIUS secret not specified" msgstr "RADIUS-Geheimnis nicht angegeben" -#: libpq/auth.c:2654 libpq/hba.c:1786 -#, c-format -msgid "could not translate RADIUS server name \"%s\" to address: %s" -msgstr "konnte RADIUS-Servername »%s« nicht in Adresse übersetzen: %s" - -#: libpq/auth.c:2682 +#: libpq/auth.c:2923 #, c-format msgid "RADIUS authentication does not support passwords longer than %d characters" msgstr "RADIUS-Authentifizierung unterstützt keine Passwörter länger als %d Zeichen" -#: libpq/auth.c:2693 +#: libpq/auth.c:3028 libpq/hba.c:1908 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "konnte RADIUS-Servername »%s« nicht in Adresse übersetzen: %s" + +#: libpq/auth.c:3042 #, c-format msgid "could not generate random encryption vector" msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" -#: libpq/auth.c:2726 +#: libpq/auth.c:3076 #, c-format msgid "could not perform MD5 encryption of password" msgstr "konnte MD5-Verschlüsselung des Passworts nicht durchführen" -#: libpq/auth.c:2751 +#: libpq/auth.c:3102 #, c-format msgid "could not create RADIUS socket: %m" msgstr "konnte RADIUS-Socket nicht erstellen: %m" -#: libpq/auth.c:2772 +#: libpq/auth.c:3124 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "konnte lokales RADIUS-Socket nicht binden: %m" -#: libpq/auth.c:2782 +#: libpq/auth.c:3134 #, c-format msgid "could not send RADIUS packet: %m" msgstr "konnte RADIUS-Paket nicht senden: %m" -#: libpq/auth.c:2815 libpq/auth.c:2840 +#: libpq/auth.c:3167 libpq/auth.c:3193 #, c-format -msgid "timeout waiting for RADIUS response" -msgstr "Zeitüberschreitung beim Warten auf RADIUS-Antwort" +msgid "timeout waiting for RADIUS response from %s" +msgstr "Zeitüberschreitung beim Warten auf RADIUS-Antwort von %s" -#: libpq/auth.c:2833 +#: libpq/auth.c:3186 #, c-format msgid "could not check status on RADIUS socket: %m" msgstr "konnte Status des RADIUS-Sockets nicht prüfen: %m" -#: libpq/auth.c:2862 +#: libpq/auth.c:3216 #, c-format msgid "could not read RADIUS response: %m" msgstr "konnte RADIUS-Antwort nicht lesen: %m" -#: libpq/auth.c:2874 libpq/auth.c:2878 +#: libpq/auth.c:3229 libpq/auth.c:3233 #, c-format -msgid "RADIUS response was sent from incorrect port: %d" -msgstr "RADIUS-Antwort wurde von falschem Port gesendet: %d" +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "RADIUS-Antwort von %s wurde von falschem Port gesendet: %d" -#: libpq/auth.c:2887 +#: libpq/auth.c:3242 #, c-format -msgid "RADIUS response too short: %d" -msgstr "RADIUS-Antwort zu kurz: %d" +msgid "RADIUS response from %s too short: %d" +msgstr "RADIUS-Antwort von %s zu kurz: %d" -#: libpq/auth.c:2894 +#: libpq/auth.c:3249 #, c-format -msgid "RADIUS response has corrupt length: %d (actual length %d)" -msgstr "RADIUS-Antwort hat verfälschte Länge: %d (tatsächliche Länge %d)" +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "RADIUS-Antwort von %s hat verfälschte Länge: %d (tatsächliche Länge %d)" -#: libpq/auth.c:2902 +#: libpq/auth.c:3257 #, c-format -msgid "RADIUS response is to a different request: %d (should be %d)" -msgstr "RADIUS-Antwort unterscheidet sich von Anfrage: %d (sollte %d sein)" +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "RADIUS-Antwort von %s unterscheidet sich von Anfrage: %d (sollte %d sein)" -#: libpq/auth.c:2927 +#: libpq/auth.c:3282 #, c-format msgid "could not perform MD5 encryption of received packet" msgstr "konnte MD5-Verschlüsselung des empfangenen Pakets nicht durchführen" -#: libpq/auth.c:2936 +#: libpq/auth.c:3291 #, c-format -msgid "RADIUS response has incorrect MD5 signature" -msgstr "RADIUS-Antwort hat falsche MD5-Signatur" +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "RADIUS-Antwort von %s hat falsche MD5-Signatur" -#: libpq/auth.c:2953 +#: libpq/auth.c:3309 #, c-format -msgid "RADIUS response has invalid code (%d) for user \"%s\"" -msgstr "RADIUS-Antwort hat ungültigen Code (%d) für Benutzer »%s«" +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "RADIUS-Antwort von %s hat ungültigen Code (%d) für Benutzer »%s«" -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 -#: libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 -#: libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format msgid "invalid large-object descriptor: %d" msgstr "ungültiger Large-Object-Deskriptor: %d" -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 -#: libpq/be-fsstubs.c:788 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "keine Berechtigung für Large Object %u" +msgid "large object descriptor %d was not opened for reading" +msgstr "Large-Objekt-Deskriptor %d wurde nicht zum Lesen geöffnet" -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format msgid "large object descriptor %d was not opened for writing" msgstr "Large-Objekt-Deskriptor %d wurde nicht zum Schreiben geöffnet" -#: libpq/be-fsstubs.c:245 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "Ergebnis von lo_lseek ist außerhalb des gültigen Bereichs für Large-Object-Deskriptor %d" -#: libpq/be-fsstubs.c:318 +#: libpq/be-fsstubs.c:285 #, c-format msgid "lo_tell result out of range for large-object descriptor %d" msgstr "Ergebnis von lo_tell ist außerhalb des gültigen Bereichs für Large-Object-Deskriptor: %d" -#: libpq/be-fsstubs.c:455 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "nur Superuser können das serverseitige lo_import() verwenden" - -#: libpq/be-fsstubs.c:456 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "Jeder kann das clientseitige lo_import() von libpq verwenden." - -#: libpq/be-fsstubs.c:469 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "konnte Serverdatei »%s« nicht öffnen: %m" -#: libpq/be-fsstubs.c:491 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "konnte Serverdatei »%s« nicht lesen: %m" -#: libpq/be-fsstubs.c:521 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "nur Superuser können das serverseitige lo_export() verwenden" - -#: libpq/be-fsstubs.c:522 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "Jeder kann das clientseitige lo_export() von libpq verwenden." - -#: libpq/be-fsstubs.c:547 +#: libpq/be-fsstubs.c:511 #, c-format msgid "could not create server file \"%s\": %m" msgstr "konnte Serverdatei »%s« nicht erstellen: %m" -#: libpq/be-fsstubs.c:559 +#: libpq/be-fsstubs.c:523 #, c-format msgid "could not write server file \"%s\": %m" msgstr "konnte Serverdatei »%s« nicht schreiben: %m" -#: libpq/be-fsstubs.c:813 +#: libpq/be-fsstubs.c:752 #, c-format msgid "large object read request is too large" msgstr "Large-Object-Leseaufforderung ist zu groß" -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:211 utils/adt/genfile.c:252 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 +#: utils/adt/genfile.c:306 #, c-format msgid "requested length cannot be negative" msgstr "verlangte Länge darf nicht negativ sein" -#: libpq/be-secure-openssl.c:197 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 +#: storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 +#: storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "could not create SSL context: %s" -msgstr "konnte SSL-Kontext nicht erzeugen: %s" +msgid "permission denied for large object %u" +msgstr "keine Berechtigung für Large Object %u" + +#: libpq/be-secure-common.c:91 +#, fuzzy, c-format +#| msgid "could not read from file \"%s\": %m" +msgid "could not read from command \"%s\": %m" +msgstr "konnte nicht aus Datei »%s« lesen: %m" -#: libpq/be-secure-openssl.c:225 +#: libpq/be-secure-common.c:109 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "konnte Serverzertifikatsdatei »%s« nicht laden: %s" +msgid "command \"%s\" failed" +msgstr "Befehl »%s« fehlgeschlagen" -#: libpq/be-secure-openssl.c:234 +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "konnte auf private Schlüsseldatei »%s« nicht zugreifen: %m" -#: libpq/be-secure-openssl.c:243 +#: libpq/be-secure-common.c:148 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "private Schlüsseldatei »%s« ist keine normale Datei" -#: libpq/be-secure-openssl.c:258 +#: libpq/be-secure-common.c:163 #, c-format msgid "private key file \"%s\" must be owned by the database user or root" msgstr "private Schlüsseldatei »%s« muss als Eigentümer den Datenbankbenutzer oder »root« haben" -#: libpq/be-secure-openssl.c:281 +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" msgstr "private Schlüsseldatei »%s« erlaubt Zugriff von Gruppe oder Welt" -#: libpq/be-secure-openssl.c:283 +#: libpq/be-secure-common.c:188 #, c-format msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." msgstr "Dateirechte müssen u=rw (0600) oder weniger sein, wenn der Eigentümer der Datenbankbenutzer ist, oder u=rw,g=r (0640) oder weniger, wenn der Eigentümer »root« ist." -#: libpq/be-secure-openssl.c:300 -#, fuzzy, c-format -#| msgid "private key file \"%s\" must be owned by the database user or root" +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "konnte SSL-Kontext nicht erzeugen: %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "konnte Serverzertifikatsdatei »%s« nicht laden: %s" + +#: libpq/be-secure-openssl.c:167 +#, c-format msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" -msgstr "private Schlüsseldatei »%s« muss als Eigentümer den Datenbankbenutzer oder »root« haben" +msgstr "private Schlüsseldatei »%s« kann nicht neu geladen werden, weil sie eine Passphrase benötigt" -#: libpq/be-secure-openssl.c:305 +#: libpq/be-secure-openssl.c:172 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:314 +#: libpq/be-secure-openssl.c:181 #, c-format msgid "check of private key failed: %s" msgstr "Überprüfung des privaten Schlüssels fehlgeschlagen: %s" -#: libpq/be-secure-openssl.c:334 +#: libpq/be-secure-openssl.c:208 #, c-format msgid "could not set the cipher list (no valid ciphers available)" -msgstr "" +msgstr "konnte Cipher-Liste nicht setzen (keine gültigen Ciphers verfügbar)" -#: libpq/be-secure-openssl.c:352 +#: libpq/be-secure-openssl.c:226 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "konnte Root-Zertifikat-Datei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:379 +#: libpq/be-secure-openssl.c:253 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "SSL-Certificate-Revocation-List-Datei »%s« ignoriert" -#: libpq/be-secure-openssl.c:381 +#: libpq/be-secure-openssl.c:255 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "SSL-Bibliothek unterstützt keine Certificate-Revocation-Lists." -#: libpq/be-secure-openssl.c:388 +#: libpq/be-secure-openssl.c:262 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "konnte SSL-Certificate-Revocation-List-Datei »%s« nicht laden: %s" -#: libpq/be-secure-openssl.c:469 -#, fuzzy, c-format -#| msgid "could not initialize SSL connection: %s" +#: libpq/be-secure-openssl.c:337 +#, c-format msgid "could not initialize SSL connection: SSL context not set up" -msgstr "konnte SSL-Verbindung nicht initialisieren: %s" +msgstr "konnte SSL-Verbindung nicht initialisieren: SSL-Kontext nicht eingerichtet" -#: libpq/be-secure-openssl.c:477 +#: libpq/be-secure-openssl.c:345 #, c-format msgid "could not initialize SSL connection: %s" msgstr "konnte SSL-Verbindung nicht initialisieren: %s" -#: libpq/be-secure-openssl.c:485 +#: libpq/be-secure-openssl.c:353 #, c-format msgid "could not set SSL socket: %s" msgstr "konnte SSL-Socket nicht setzen: %s" -#: libpq/be-secure-openssl.c:540 +#: libpq/be-secure-openssl.c:408 #, c-format msgid "could not accept SSL connection: %m" msgstr "konnte SSL-Verbindung nicht annehmen: %m" -#: libpq/be-secure-openssl.c:544 libpq/be-secure-openssl.c:555 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "konnte SSL-Verbindung nicht annehmen: EOF entdeckt" -#: libpq/be-secure-openssl.c:549 +#: libpq/be-secure-openssl.c:417 #, c-format msgid "could not accept SSL connection: %s" msgstr "konnte SSL-Verbindung nicht annehmen: %s" -#: libpq/be-secure-openssl.c:560 libpq/be-secure-openssl.c:699 -#: libpq/be-secure-openssl.c:759 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 +#: libpq/be-secure-openssl.c:623 #, c-format msgid "unrecognized SSL error code: %d" msgstr "unbekannter SSL-Fehlercode: %d" -#: libpq/be-secure-openssl.c:602 +#: libpq/be-secure-openssl.c:470 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "Common-Name im SSL-Zertifikat enthält Null-Byte" -#: libpq/be-secure-openssl.c:613 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "SSL-Verbindung von »%s«" - -#: libpq/be-secure-openssl.c:690 libpq/be-secure-openssl.c:750 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format msgid "SSL error: %s" msgstr "SSL-Fehler: %s" -#: libpq/be-secure-openssl.c:1179 +#: libpq/be-secure-openssl.c:788 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "konnte DH-Parameterdatei »%s« nicht öffnen: %m" + +#: libpq/be-secure-openssl.c:800 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "konnte DH-Parameterdatei nicht laden: %s" + +#: libpq/be-secure-openssl.c:810 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "ungültige DH-Parameter: %s" + +#: libpq/be-secure-openssl.c:818 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "ungültige DH-Parameter: p ist keine Primzahl" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "ungültige DH-Parameter: weder geeigneter Generator noch sichere Primzahl" + +#: libpq/be-secure-openssl.c:981 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: konnte DH-Parameter nicht laden" + +#: libpq/be-secure-openssl.c:989 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: konnte DH-Parameter nicht setzen: %s" + +#: libpq/be-secure-openssl.c:1013 #, c-format msgid "ECDH: unrecognized curve name: %s" msgstr "ECDH: unbekannter Kurvenname: %s" -#: libpq/be-secure-openssl.c:1188 +#: libpq/be-secure-openssl.c:1022 #, c-format msgid "ECDH: could not create key" msgstr "ECDH: konnte Schlüssel nicht erzeugen" -#: libpq/be-secure-openssl.c:1216 +#: libpq/be-secure-openssl.c:1050 msgid "no SSL error reported" msgstr "kein SSL-Fehler berichtet" -#: libpq/be-secure-openssl.c:1220 +#: libpq/be-secure-openssl.c:1054 #, c-format msgid "SSL error code %lu" msgstr "SSL-Fehlercode %lu" -#: libpq/be-secure.c:188 libpq/be-secure.c:274 +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "SSL-Verbindung von »%s«" + +#: libpq/be-secure.c:196 libpq/be-secure.c:284 #, c-format msgid "terminating connection due to unexpected postmaster exit" msgstr "Verbindung wird abgebrochen wegen unerwartetem Ende des Postmasters" -#: libpq/crypt.c:58 +#: libpq/crypt.c:51 #, c-format msgid "Role \"%s\" does not exist." msgstr "Rolle »%s« existiert nicht." -#: libpq/crypt.c:68 +#: libpq/crypt.c:61 #, c-format msgid "User \"%s\" has no password assigned." msgstr "Benutzer »%s« hat kein Passwort zugewiesen." -#: libpq/crypt.c:83 -#, c-format -msgid "User \"%s\" has an empty password." -msgstr "Benutzer »%s« hat ein leeres Passwort." - -#: libpq/crypt.c:97 +#: libpq/crypt.c:79 #, c-format msgid "User \"%s\" has an expired password." msgstr "Benutzer »%s« hat ein abgelaufenes Passwort." -#: libpq/crypt.c:254 +#: libpq/crypt.c:173 #, c-format msgid "User \"%s\" has a password that cannot be used with MD5 authentication." -msgstr "" +msgstr "Benutzer »%s« hat ein Passwort, das nicht mit MD5-Authentifizierung verwendet werden kann." -#: libpq/crypt.c:263 libpq/crypt.c:330 +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Passwort stimmt nicht überein für Benutzer »%s«." -#: libpq/crypt.c:321 +#: libpq/crypt.c:281 #, c-format msgid "Password of user \"%s\" is in unrecognized format." -msgstr "" +msgstr "Passwort von Benutzer »%s« hat unbekanntes Format." -#: libpq/hba.c:232 +#: libpq/hba.c:235 #, c-format msgid "authentication file token too long, skipping: \"%s\"" msgstr "Token in Authentifizierungsdatei zu lang, wird übersprungen: »%s«" -#: libpq/hba.c:404 +#: libpq/hba.c:407 #, c-format msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" msgstr "konnte sekundäre Authentifizierungsdatei »@%s« nicht als »%s« öffnen: %m" -#: libpq/hba.c:506 +#: libpq/hba.c:509 #, c-format msgid "authentication file line too long" msgstr "Zeile in Authentifizierungsdatei zu lang" -#: libpq/hba.c:507 libpq/hba.c:861 libpq/hba.c:881 libpq/hba.c:919 -#: libpq/hba.c:969 libpq/hba.c:983 libpq/hba.c:1005 libpq/hba.c:1014 -#: libpq/hba.c:1035 libpq/hba.c:1048 libpq/hba.c:1068 libpq/hba.c:1090 -#: libpq/hba.c:1102 libpq/hba.c:1158 libpq/hba.c:1178 libpq/hba.c:1192 -#: libpq/hba.c:1211 libpq/hba.c:1222 libpq/hba.c:1237 libpq/hba.c:1255 -#: libpq/hba.c:1271 libpq/hba.c:1283 libpq/hba.c:1320 libpq/hba.c:1361 -#: libpq/hba.c:1374 libpq/hba.c:1396 libpq/hba.c:1408 libpq/hba.c:1426 -#: libpq/hba.c:1476 libpq/hba.c:1515 libpq/hba.c:1526 libpq/hba.c:1583 -#: libpq/hba.c:1599 libpq/hba.c:1698 libpq/hba.c:1788 libpq/hba.c:1808 -#: libpq/hba.c:1830 tsearch/ts_locale.c:182 +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 +#: libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 +#: libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 +#: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 +#: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 +#: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 +#: libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 +#: libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 +#: libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 +#: libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 +#: libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "Zeile %d in Konfigurationsdatei »%s«" #. translator: the second %s is a list of auth methods -#: libpq/hba.c:859 +#: libpq/hba.c:865 #, c-format msgid "authentication option \"%s\" is only valid for authentication methods %s" msgstr "Authentifizierungsoption »%s« ist nur gültig für Authentifizierungsmethoden %s" -#: libpq/hba.c:879 +#: libpq/hba.c:885 #, c-format msgid "authentication method \"%s\" requires argument \"%s\" to be set" msgstr "Authentifizierungsmethode »%s« benötigt Argument »%s«" -#: libpq/hba.c:907 +#: libpq/hba.c:913 #, c-format msgid "missing entry in file \"%s\" at end of line %d" msgstr "fehlender Eintrag in Datei »%s« am Ende von Zeile %d" -#: libpq/hba.c:918 +#: libpq/hba.c:924 #, c-format msgid "multiple values in ident field" msgstr "mehrere Werte in Ident-Feld" -#: libpq/hba.c:967 +#: libpq/hba.c:973 #, c-format msgid "multiple values specified for connection type" msgstr "mehrere Werte angegeben für Verbindungstyp" -#: libpq/hba.c:968 +#: libpq/hba.c:974 #, c-format msgid "Specify exactly one connection type per line." msgstr "Geben Sie genau einen Verbindungstyp pro Zeile an." -#: libpq/hba.c:982 +#: libpq/hba.c:988 #, c-format msgid "local connections are not supported by this build" msgstr "lokale Verbindungen werden von dieser Installation nicht unterstützt" -#: libpq/hba.c:1003 +#: libpq/hba.c:1009 #, c-format msgid "hostssl record cannot match because SSL is disabled" -msgstr "" +msgstr "hostssl-Eintrag kann nicht angewendet werden, weil SSL deaktiviert ist" -#: libpq/hba.c:1004 +#: libpq/hba.c:1010 #, c-format msgid "Set ssl = on in postgresql.conf." msgstr "Setzen Sie ssl = on in postgresql.conf." -#: libpq/hba.c:1012 -#, fuzzy, c-format -#| msgid "hostssl is not supported by this build" +#: libpq/hba.c:1018 +#, c-format msgid "hostssl record cannot match because SSL is not supported by this build" -msgstr "hostssl wird von dieser Installation nicht unterstützt" +msgstr "hostssl-Eintrag kann nicht angewendet werden, weil SSL von dieser Installation nicht unterstützt wird" -#: libpq/hba.c:1013 +#: libpq/hba.c:1019 #, c-format msgid "Compile with --with-openssl to use SSL connections." msgstr "Kompilieren Sie mit --with-openssl, um SSL-Verbindungen zu verwenden." -#: libpq/hba.c:1033 +#: libpq/hba.c:1039 #, c-format msgid "invalid connection type \"%s\"" msgstr "ungültiger Verbindungstyp »%s«" -#: libpq/hba.c:1047 +#: libpq/hba.c:1053 #, c-format msgid "end-of-line before database specification" msgstr "Zeilenende vor Datenbankangabe" -#: libpq/hba.c:1067 +#: libpq/hba.c:1073 #, c-format msgid "end-of-line before role specification" msgstr "Zeilenende vor Rollenangabe" -#: libpq/hba.c:1089 +#: libpq/hba.c:1095 #, c-format msgid "end-of-line before IP address specification" msgstr "Zeilenende vor IP-Adressangabe" -#: libpq/hba.c:1100 +#: libpq/hba.c:1106 #, c-format msgid "multiple values specified for host address" msgstr "mehrere Werte für Hostadresse angegeben" -#: libpq/hba.c:1101 +#: libpq/hba.c:1107 #, c-format msgid "Specify one address range per line." msgstr "Geben Sie einen Adressbereich pro Zeile an." -#: libpq/hba.c:1156 +#: libpq/hba.c:1162 #, c-format msgid "invalid IP address \"%s\": %s" msgstr "ungültige IP-Adresse »%s«: %s" -#: libpq/hba.c:1176 +#: libpq/hba.c:1182 #, c-format msgid "specifying both host name and CIDR mask is invalid: \"%s\"" msgstr "Angabe von sowohl Hostname als auch CIDR-Maske ist ungültig: »%s«" -#: libpq/hba.c:1190 +#: libpq/hba.c:1196 #, c-format msgid "invalid CIDR mask in address \"%s\"" msgstr "ungültige CIDR-Maske in Adresse »%s«" -#: libpq/hba.c:1209 +#: libpq/hba.c:1215 #, c-format msgid "end-of-line before netmask specification" msgstr "Zeilenende vor Netzmaskenangabe" -#: libpq/hba.c:1210 +#: libpq/hba.c:1216 #, c-format msgid "Specify an address range in CIDR notation, or provide a separate netmask." msgstr "Geben Sie einen Adressbereich in CIDR-Schreibweise oder eine separate Netzmaske an." -#: libpq/hba.c:1221 +#: libpq/hba.c:1227 #, c-format msgid "multiple values specified for netmask" msgstr "mehrere Werte für Netzmaske angegeben" -#: libpq/hba.c:1235 +#: libpq/hba.c:1241 #, c-format msgid "invalid IP mask \"%s\": %s" msgstr "ungültige IP-Maske »%s«: %s" -#: libpq/hba.c:1254 +#: libpq/hba.c:1260 #, c-format msgid "IP address and mask do not match" msgstr "IP-Adresse und -Maske passen nicht zusammen" -#: libpq/hba.c:1270 +#: libpq/hba.c:1276 #, c-format msgid "end-of-line before authentication method" msgstr "Zeilenende vor Authentifizierungsmethode" -#: libpq/hba.c:1281 +#: libpq/hba.c:1287 #, c-format msgid "multiple values specified for authentication type" msgstr "mehrere Werte für Authentifizierungstyp angegeben" -#: libpq/hba.c:1282 +#: libpq/hba.c:1288 #, c-format msgid "Specify exactly one authentication type per line." msgstr "Geben Sie genau einen Authentifizierungstyp pro Zeile an." -#: libpq/hba.c:1359 +#: libpq/hba.c:1365 #, c-format msgid "invalid authentication method \"%s\"" msgstr "ungültige Authentifizierungsmethode »%s«" -#: libpq/hba.c:1372 +#: libpq/hba.c:1378 #, c-format msgid "invalid authentication method \"%s\": not supported by this build" msgstr "ungültige Authentifizierungsmethode »%s«: von dieser Installation nicht unterstützt" -#: libpq/hba.c:1395 +#: libpq/hba.c:1401 #, c-format msgid "gssapi authentication is not supported on local sockets" msgstr "gssapi-Authentifizierung wird auf lokalen Sockets nicht unterstützt" -#: libpq/hba.c:1407 +#: libpq/hba.c:1413 #, c-format msgid "peer authentication is only supported on local sockets" msgstr "peer-Authentifizierung wird nur auf lokalen Sockets unterstützt" -#: libpq/hba.c:1425 +#: libpq/hba.c:1431 #, c-format msgid "cert authentication is only supported on hostssl connections" msgstr "cert-Authentifizierung wird nur auf »hostssl«-Verbindungen unterstützt" -#: libpq/hba.c:1475 +#: libpq/hba.c:1481 #, c-format msgid "authentication option not in name=value format: %s" msgstr "Authentifizierungsoption nicht im Format name=wert: %s" -#: libpq/hba.c:1514 +#: libpq/hba.c:1522 #, c-format -msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix" -msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute oder ldapurl kann nicht zusammen mit ldapprefix verwendet werden" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter oder ldapurl kann nicht zusammen mit ldapprefix verwendet werden" -#: libpq/hba.c:1525 +#: libpq/hba.c:1533 #, c-format msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "Authentifizierungsmethode »ldap« benötigt Argument »ldapbasedn«, »ldapprefix« oder »ldapsuffix«" -#: libpq/hba.c:1573 +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute kann nicht zusammen mit ldapsearchfilter verwendet werden" + +#: libpq/hba.c:1566 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "List der RADIUS-Server darf nicht leer sein" + +#: libpq/hba.c:1576 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "Liste der RADIUS-Geheimnisse darf nicht leer sein" + +#: libpq/hba.c:1629 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "die Anzahl %s (%d) muss 1 oder gleich der Anzahl %s (%d) sein" + +#: libpq/hba.c:1663 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspi und cert" -#: libpq/hba.c:1582 +#: libpq/hba.c:1672 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "clientcert kann nur für »hostssl«-Zeilen konfiguriert werden" -#: libpq/hba.c:1598 +#: libpq/hba.c:1688 #, c-format msgid "clientcert can not be set to 0 when using \"cert\" authentication" msgstr "clientcert kann nicht auf 0 gesetzt sein, wenn »cert«-Authentifizierung verwendet wird" -#: libpq/hba.c:1635 +#: libpq/hba.c:1725 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "konnte LDAP-URL »%s« nicht interpretieren: %s" -#: libpq/hba.c:1645 +#: libpq/hba.c:1736 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "nicht unterstütztes LDAP-URL-Schema: %s" -#: libpq/hba.c:1663 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "Filter in LDAP-URLs werden nicht unterstützt" - -#: libpq/hba.c:1672 +#: libpq/hba.c:1760 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "LDAP-URLs werden auf dieser Plattform nicht unterstützt" -#: libpq/hba.c:1697 +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "ungültiger ldapscheme-Wert: »%s«" + +#: libpq/hba.c:1796 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "ungültige LDAP-Portnummer: »%s«" -#: libpq/hba.c:1738 libpq/hba.c:1745 +#: libpq/hba.c:1842 libpq/hba.c:1849 msgid "gssapi and sspi" msgstr "gssapi und sspi" -#: libpq/hba.c:1754 libpq/hba.c:1763 +#: libpq/hba.c:1858 libpq/hba.c:1867 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1807 +#: libpq/hba.c:1889 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "konnte RADIUS-Serverliste »%s« nicht parsen" + +#: libpq/hba.c:1937 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "konnte RADIUS-Portliste »%s« nicht parsen" + +#: libpq/hba.c:1951 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "ungültige RADIUS-Portnummer: »%s«" -#: libpq/hba.c:1828 +#: libpq/hba.c:1973 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "konnte RADIUS-Geheimnisliste »%s« nicht parsen" + +#: libpq/hba.c:1995 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "konnte RADIUS-Bezeichnerliste »%s« nicht parsen" + +#: libpq/hba.c:2009 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "unbekannter Authentifizierungsoptionsname: »%s«" -#: libpq/hba.c:2012 +#: libpq/hba.c:2193 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "Konfigurationsdatei »%s« enthält keine Einträge" -#: libpq/hba.c:2517 +#: libpq/hba.c:2706 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "ungültiger regulärer Ausdruck »%s«: %s" -#: libpq/hba.c:2577 +#: libpq/hba.c:2766 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "Suche nach regulärem Ausdruck für »%s« fehlgeschlagen: %s" -#: libpq/hba.c:2596 +#: libpq/hba.c:2785 #, c-format msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" msgstr "regulärer Ausdruck »%s« hat keine Teilausdrücke wie von der Backreference in »%s« verlangt" -#: libpq/hba.c:2693 +#: libpq/hba.c:2882 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "angegebener Benutzername (%s) und authentifizierter Benutzername (%s) stimmen nicht überein" -#: libpq/hba.c:2713 +#: libpq/hba.c:2902 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "kein passender Eintrag in Usermap »%s« für Benutzer »%s«, authentifiziert als »%s«" -#: libpq/hba.c:2746 +#: libpq/hba.c:2935 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "konnte Usermap-Datei »%s« nicht öffnen: %m" -#: libpq/pqcomm.c:201 +#: libpq/pqcomm.c:220 #, c-format msgid "could not set socket to nonblocking mode: %m" msgstr "konnte Socket nicht auf nicht-blockierenden Modus umstellen: %m" -#: libpq/pqcomm.c:355 +#: libpq/pqcomm.c:374 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" msgstr "Unix-Domain-Socket-Pfad »%s« ist zu lang (maximal %d Bytes)" -#: libpq/pqcomm.c:376 +#: libpq/pqcomm.c:395 #, c-format msgid "could not translate host name \"%s\", service \"%s\" to address: %s" msgstr "konnte Hostname »%s«, Dienst »%s« nicht in Adresse übersetzen: %s" -#: libpq/pqcomm.c:380 +#: libpq/pqcomm.c:399 #, c-format msgid "could not translate service \"%s\" to address: %s" msgstr "konnte Dienst »%s« nicht in Adresse übersetzen: %s" -#: libpq/pqcomm.c:407 +#: libpq/pqcomm.c:426 #, c-format msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" msgstr "konnte nicht an alle verlangten Adressen binden: MAXLISTEN (%d) überschritten" -#: libpq/pqcomm.c:416 +#: libpq/pqcomm.c:435 msgid "IPv4" msgstr "IPv4" -#: libpq/pqcomm.c:420 +#: libpq/pqcomm.c:439 msgid "IPv6" msgstr "IPv6" -#: libpq/pqcomm.c:425 +#: libpq/pqcomm.c:444 msgid "Unix" msgstr "Unix" -#: libpq/pqcomm.c:430 +#: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" msgstr "unbekannte Adressfamilie %d" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:456 -#, fuzzy, c-format -#| msgid "could not create listen socket for \"%s\"" +#: libpq/pqcomm.c:475 +#, c-format msgid "could not create %s socket for address \"%s\": %m" -msgstr "konnte Listen-Socket für »%s« nicht erzeugen" +msgstr "konnte %s-Socket für Adresse »%s« nicht erzeugen: %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:482 -#, fuzzy, c-format -#| msgid "setsockopt(SO_REUSEADDR) failed: %m" +#: libpq/pqcomm.c:501 +#, c-format msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" -msgstr "setsockopt(SO_REUSEADDR) fehlgeschlagen: %m" +msgstr "setsockopt(SO_REUSEADDR) für %s-Adresse »%s« fehlgeschlagen: %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:499 -#, fuzzy, c-format -#| msgid "setsockopt(IPV6_V6ONLY) failed: %m" +#: libpq/pqcomm.c:518 +#, c-format msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" -msgstr "setsockopt(IPV6_V6ONLY) fehlgeschlagen: %m" +msgstr "setsockopt(IPV6_V6ONLY) für %s-Adresse »%s« fehlgeschlagen: %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:519 -#, fuzzy, c-format -#| msgid "could not bind to local address \"%s\": %m" +#: libpq/pqcomm.c:538 +#, c-format msgid "could not bind %s address \"%s\": %m" -msgstr "konnte nicht mit lokaler Adresse »%s« verbinden: %m" +msgstr "konnte %s-Adresse »%s« nicht binden: %m" -#: libpq/pqcomm.c:522 +#: libpq/pqcomm.c:541 #, c-format msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." msgstr "Läuft bereits ein anderer Postmaster auf Port %d? Wenn nicht, entfernen Sie die Socketdatei »%s« und versuchen Sie erneut." -#: libpq/pqcomm.c:525 +#: libpq/pqcomm.c:544 #, c-format msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." msgstr "Läuft bereits ein anderer Postmaster auf Port %d? Wenn nicht, warten Sie einige Sekunden und versuchen Sie erneut." #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:558 -#, fuzzy, c-format -#| msgid "could not bind to local address \"%s\": %m" +#: libpq/pqcomm.c:577 +#, c-format msgid "could not listen on %s address \"%s\": %m" -msgstr "konnte nicht mit lokaler Adresse »%s« verbinden: %m" +msgstr "konnte nicht auf %s-Adresse »%s« hören: %m" -#. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:566 -#, fuzzy, c-format -#| msgid "invalid CIDR mask in address \"%s\"" -msgid "listening on %s address \"%s\"" -msgstr "ungültige CIDR-Maske in Adresse »%s«" +#: libpq/pqcomm.c:586 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "erwarte Verbindungen auf Unix-Socket »%s«" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:592 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "erwarte Verbindungen auf %s-Adresse »%s«, Port %d" -#: libpq/pqcomm.c:649 +#: libpq/pqcomm.c:675 #, c-format msgid "group \"%s\" does not exist" msgstr "Gruppe »%s« existiert nicht" -#: libpq/pqcomm.c:659 +#: libpq/pqcomm.c:685 #, c-format msgid "could not set group of file \"%s\": %m" msgstr "konnte Gruppe von Datei »%s« nicht setzen: %m" -#: libpq/pqcomm.c:670 +#: libpq/pqcomm.c:696 #, c-format msgid "could not set permissions of file \"%s\": %m" msgstr "konnte Zugriffsrechte von Datei »%s« nicht setzen: %m" -#: libpq/pqcomm.c:700 +#: libpq/pqcomm.c:726 #, c-format msgid "could not accept new connection: %m" msgstr "konnte neue Verbindung nicht akzeptieren: %m" -#: libpq/pqcomm.c:901 +#: libpq/pqcomm.c:927 #, c-format msgid "there is no client connection" msgstr "es besteht keine Client-Verbindung" -#: libpq/pqcomm.c:952 libpq/pqcomm.c:1048 +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 #, c-format msgid "could not receive data from client: %m" msgstr "konnte Daten vom Client nicht empfangen: %m" -#: libpq/pqcomm.c:1193 tcop/postgres.c:3907 +#: libpq/pqcomm.c:1219 tcop/postgres.c:4020 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "Verbindung wird abgebrochen, weil Protokollsynchronisierung verloren wurde" -#: libpq/pqcomm.c:1259 +#: libpq/pqcomm.c:1285 #, c-format msgid "unexpected EOF within message length word" msgstr "unerwartetes EOF im Message-Längenwort" -#: libpq/pqcomm.c:1270 +#: libpq/pqcomm.c:1296 #, c-format msgid "invalid message length" msgstr "ungültige Message-Länge" -#: libpq/pqcomm.c:1292 libpq/pqcomm.c:1305 +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 #, c-format msgid "incomplete message from client" msgstr "unvollständige Message vom Client" -#: libpq/pqcomm.c:1438 +#: libpq/pqcomm.c:1464 #, c-format msgid "could not send data to client: %m" msgstr "konnte Daten nicht an den Client senden: %m" -#: libpq/pqformat.c:437 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "keine Daten in Message übrig" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 #, c-format msgid "insufficient data left in message" msgstr "nicht genug Daten in Message übrig" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "ungültige Zeichenkette in Message" -#: libpq/pqformat.c:682 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "ungültiges Message-Format" @@ -13129,317 +14044,316 @@ msgstr "erweiterbarer Knotentyp »%s« existiert bereits" msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "ExtensibleNodeMethods »%s« wurde nicht registriert" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1844 -#: parser/parse_coerce.c:1872 parser/parse_coerce.c:1948 -#: parser/parse_expr.c:2089 parser/parse_func.c:598 parser/parse_oper.c:958 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "konnte Arraytyp für Datentyp %s nicht finden" -#: optimizer/path/joinrels.c:802 +#: optimizer/path/joinrels.c:839 #, c-format msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "FULL JOIN wird nur für Merge- oder Hash-Verbund-fähige Verbundbedingungen unterstützt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1200 +#: optimizer/plan/initsplan.c:1212 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s kann nicht auf die nullbare Seite eines äußeren Verbundes angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1480 parser/analyze.c:1619 parser/analyze.c:1816 -#: parser/analyze.c:2610 +#: optimizer/plan/planner.c:1768 parser/analyze.c:1655 parser/analyze.c:1854 +#: parser/analyze.c:2687 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s ist nicht in UNION/INTERSECT/EXCEPT erlaubt" -#: optimizer/plan/planner.c:3854 +#: optimizer/plan/planner.c:2340 optimizer/plan/planner.c:4061 #, c-format msgid "could not implement GROUP BY" msgstr "konnte GROUP BY nicht implementieren" -#: optimizer/plan/planner.c:3855 optimizer/plan/planner.c:4257 -#: optimizer/prep/prepunion.c:928 +#: optimizer/plan/planner.c:2341 optimizer/plan/planner.c:4062 +#: optimizer/plan/planner.c:4805 optimizer/prep/prepunion.c:1080 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "Einige Datentypen unterstützen nur Hashing, während andere nur Sortieren unterstützen." -#: optimizer/plan/planner.c:4256 +#: optimizer/plan/planner.c:4804 #, c-format msgid "could not implement DISTINCT" msgstr "konnte DISTINCT nicht implementieren" -#: optimizer/plan/planner.c:4936 +#: optimizer/plan/planner.c:5487 #, c-format msgid "could not implement window PARTITION BY" msgstr "konnte PARTITION BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:4937 +#: optimizer/plan/planner.c:5488 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Fensterpartitionierungsspalten müssen sortierbare Datentypen haben." -#: optimizer/plan/planner.c:4941 +#: optimizer/plan/planner.c:5492 #, c-format msgid "could not implement window ORDER BY" msgstr "konnte ORDER BY für Fenster nicht implementieren" -#: optimizer/plan/planner.c:4942 +#: optimizer/plan/planner.c:5493 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Fenstersortierspalten müssen sortierbare Datentypen haben." -#: optimizer/plan/setrefs.c:413 +#: optimizer/plan/setrefs.c:414 #, c-format msgid "too many range table entries" msgstr "zu viele Range-Table-Einträge" -#: optimizer/prep/prepunion.c:483 +#: optimizer/prep/prepunion.c:544 #, c-format msgid "could not implement recursive UNION" msgstr "konnte rekursive UNION nicht implementieren" -#: optimizer/prep/prepunion.c:484 +#: optimizer/prep/prepunion.c:545 #, c-format msgid "All column datatypes must be hashable." msgstr "Alle Spaltendatentypen müssen hashbar sein." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:927 +#: optimizer/prep/prepunion.c:1079 #, c-format msgid "could not implement %s" msgstr "konnte %s nicht implementieren" -#: optimizer/util/clauses.c:4634 +#: optimizer/util/clauses.c:4924 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "SQL-Funktion »%s« beim Inlining" -#: optimizer/util/plancat.c:115 +#: optimizer/util/plancat.c:127 #, c-format msgid "cannot access temporary or unlogged relations during recovery" msgstr "während der Wiederherstellung kann nicht auf temporäre oder ungeloggte Tabellen zugegriffen werden" -#: optimizer/util/plancat.c:613 +#: optimizer/util/plancat.c:651 #, c-format msgid "whole row unique index inference specifications are not supported" msgstr "Inferenzangaben mit Unique-Index über die gesamte Zeile werden nicht unterstützt" -#: optimizer/util/plancat.c:630 +#: optimizer/util/plancat.c:668 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "Constraint in der ON-CONFLICT-Klausel hat keinen zugehörigen Index" -#: optimizer/util/plancat.c:681 +#: optimizer/util/plancat.c:719 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" -msgstr "ON CONFLICT DO UDPATE nicht unterstützt mit Exclusion-Constraints" +msgstr "ON CONFLICT DO UPDATE nicht unterstützt mit Exclusion-Constraints" -#: optimizer/util/plancat.c:786 +#: optimizer/util/plancat.c:824 #, c-format msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "es gibt keinen Unique-Constraint oder Exclusion-Constraint, der auf die ON-CONFLICT-Angabe passt" -#: parser/analyze.c:695 parser/analyze.c:1382 +#: parser/analyze.c:711 parser/analyze.c:1418 #, c-format msgid "VALUES lists must all be the same length" msgstr "VALUES-Listen müssen alle die gleiche Länge haben" -#: parser/analyze.c:850 -#, fuzzy, c-format -#| msgid "ON CONFLICT is not supported with system catalog tables" -msgid "ON CONFLICT clause is not supported with partitioned tables" -msgstr "ON CONFLICT wird nicht mit Systemkatalogtabellen unterstützt" - -#: parser/analyze.c:913 +#: parser/analyze.c:921 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT hat mehr Ausdrücke als Zielspalten" -#: parser/analyze.c:931 +#: parser/analyze.c:939 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT hat mehr Zielspalten als Ausdrücke" -#: parser/analyze.c:935 +#: parser/analyze.c:943 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "Der einzufügende Wert ist ein Zeilenausdruck mit der gleichen Anzahl Spalten wie von INSERT erwartet. Haben Sie versehentlich zu viele Klammern gesetzt?" -#: parser/analyze.c:1195 parser/analyze.c:1592 +#: parser/analyze.c:1229 parser/analyze.c:1628 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO ist hier nicht erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1524 parser/analyze.c:2789 +#: parser/analyze.c:1560 parser/analyze.c:2866 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s kann nicht auf VALUES angewendet werden" -#: parser/analyze.c:1743 +#: parser/analyze.c:1779 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "ungültige ORDER-BY-Klausel mit UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:1744 +#: parser/analyze.c:1780 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "Es können nur Ergebnisspaltennamen verwendet werden, keine Ausdrücke oder Funktionen." -#: parser/analyze.c:1745 +#: parser/analyze.c:1781 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Fügen Sie den Ausdrück/die Funktion jedem SELECT hinzu oder verlegen Sie die UNION in eine FROM-Klausel." -#: parser/analyze.c:1806 +#: parser/analyze.c:1844 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO ist nur im ersten SELECT von UNION/INTERSECT/EXCEPT erlaubt" -#: parser/analyze.c:1878 +#: parser/analyze.c:1916 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "Teilanweisung von UNION/INTERSECT/EXCEPT kann nicht auf andere Relationen auf der selben Anfrageebene verweisen" -#: parser/analyze.c:1967 +#: parser/analyze.c:2005 #, c-format msgid "each %s query must have the same number of columns" msgstr "jede %s-Anfrage muss die gleiche Anzahl Spalten haben" -#: parser/analyze.c:2360 +#: parser/analyze.c:2398 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING muss mindestens eine Spalte haben" -#: parser/analyze.c:2401 +#: parser/analyze.c:2439 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "SCROLL und NO SCROLL können nicht beide angegeben werden" -#: parser/analyze.c:2420 +#: parser/analyze.c:2458 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR darf keine datenmodifizierenden Anweisungen in WITH enthalten" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2428 +#: parser/analyze.c:2466 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s wird nicht unterstützt" -#: parser/analyze.c:2431 +#: parser/analyze.c:2469 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "Haltbare Cursor müssen READ ONLY sein." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2439 +#: parser/analyze.c:2477 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s wird nicht unterstützt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2450 +#: parser/analyze.c:2488 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %s wird nicht unterstützt" -#: parser/analyze.c:2453 +#: parser/analyze.c:2491 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "Insensitive Cursor müssen READ ONLY sein." -#: parser/analyze.c:2519 +#: parser/analyze.c:2557 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "materialisierte Sichten dürfen keine datenmodifizierenden Anweisungen in WITH verwenden" -#: parser/analyze.c:2529 +#: parser/analyze.c:2567 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "materialisierte Sichten dürfen keine temporären Tabellen oder Sichten verwenden" -#: parser/analyze.c:2539 +#: parser/analyze.c:2577 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "materialisierte Sichten können nicht unter Verwendung von gebundenen Parametern definiert werden" -#: parser/analyze.c:2551 +#: parser/analyze.c:2589 #, c-format msgid "materialized views cannot be UNLOGGED" msgstr "materialisierte Sichten können nicht UNLOGGED sein" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2617 +#: parser/analyze.c:2694 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s ist nicht mit DISTINCT-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2624 +#: parser/analyze.c:2701 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s ist nicht mit GROUP-BY-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2631 +#: parser/analyze.c:2708 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s ist nicht mit HAVING-Klausel erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2638 +#: parser/analyze.c:2715 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s ist nicht mit Aggregatfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2645 +#: parser/analyze.c:2722 #, c-format msgid "%s is not allowed with window functions" msgstr "%s ist nicht mit Fensterfunktionen erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2652 +#: parser/analyze.c:2729 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s ist nicht mit Funktionen mit Ergebnismenge in der Targetliste erlaubt" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2731 +#: parser/analyze.c:2808 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s muss unqualifizierte Relationsnamen angeben" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2762 +#: parser/analyze.c:2839 #, c-format msgid "%s cannot be applied to a join" msgstr "%s kann nicht auf einen Verbund angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2771 +#: parser/analyze.c:2848 #, c-format msgid "%s cannot be applied to a function" msgstr "%s kann nicht auf eine Funktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2780 -#, fuzzy, c-format -#| msgid "%s cannot be applied to a function" +#: parser/analyze.c:2857 +#, c-format msgid "%s cannot be applied to a table function" -msgstr "%s kann nicht auf eine Funktion angewendet werden" +msgstr "%s kann nicht auf eine Tabellenfunktion angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2798 +#: parser/analyze.c:2875 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s kann nicht auf eine WITH-Anfrage angewendet werden" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2815 +#: parser/analyze.c:2884 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s kann nicht auf einen benannten Tupelstore angewendet werden" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2901 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "Relation »%s« in %s nicht in der FROM-Klausel gefunden" @@ -13507,513 +14421,579 @@ msgstr "Aggregatfunktionen sind in der Fenster-ROWS-Klausel nicht erlaubt" msgid "grouping operations are not allowed in window ROWS" msgstr "Gruppieroperationen sind in der Fenster-ROWS-Klausel nicht erlaubt" -#: parser/parse_agg.c:454 +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "Aggregatfunktionen sind in der Fenster-GROUPS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "Gruppieroperationen sind in der Fenster-GROUPS-Klausel nicht erlaubt" + +#: parser/parse_agg.c:461 msgid "aggregate functions are not allowed in check constraints" msgstr "Aggregatfunktionen sind in Check-Constraints nicht erlaubt" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:463 msgid "grouping operations are not allowed in check constraints" msgstr "Gruppieroperationen sind in Check-Constraints nicht erlaubt" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:470 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "Aggregatfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:472 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "Gruppieroperationen sind in DEFAULT-Ausdrücken nicht erlaubt" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:477 msgid "aggregate functions are not allowed in index expressions" msgstr "Aggregatfunktionen sind in Indexausdrücken nicht erlaubt" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:479 msgid "grouping operations are not allowed in index expressions" msgstr "Gruppieroperationen sind in Indexausdrücken nicht erlaubt" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:484 msgid "aggregate functions are not allowed in index predicates" msgstr "Aggregatfunktionen sind in Indexprädikaten nicht erlaubt" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:486 msgid "grouping operations are not allowed in index predicates" msgstr "Gruppieroperationen sind in Indexprädikaten nicht erlaubt" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:491 msgid "aggregate functions are not allowed in transform expressions" msgstr "Aggregatfunktionen sind in Umwandlungsausdrücken nicht erlaubt" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:493 msgid "grouping operations are not allowed in transform expressions" msgstr "Gruppieroperationen sind in Umwandlungsausdrücken nicht erlaubt" -#: parser/parse_agg.c:491 +#: parser/parse_agg.c:498 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "Aggregatfunktionen sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_agg.c:493 +#: parser/parse_agg.c:500 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "Gruppieroperationen sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_agg.c:498 +#: parser/parse_agg.c:505 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "Aggregatfunktionen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" -#: parser/parse_agg.c:500 +#: parser/parse_agg.c:507 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "Gruppieroperationen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" -#: parser/parse_agg.c:505 -#, fuzzy -#| msgid "aggregate functions are not allowed in index expressions" -msgid "aggregate functions are not allowed in partition key expression" -msgstr "Aggregatfunktionen sind in Indexausdrücken nicht erlaubt" +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "Aggregatfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" -#: parser/parse_agg.c:507 -#, fuzzy -#| msgid "grouping operations are not allowed in index expressions" -msgid "grouping operations are not allowed in partition key expression" -msgstr "Gruppieroperationen sind in Indexausdrücken nicht erlaubt" +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "Gruppieroperationen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "Aggregatfunktionen sind in CALL-Argumenten nicht erlaubt" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "Gruppieroperationen sind in CALL-Argumenten nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:530 parser/parse_clause.c:1767 +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "Aggregatfunktionen sind in %s nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:533 +#: parser/parse_agg.c:548 #, c-format msgid "grouping operations are not allowed in %s" msgstr "Gruppieroperationen sind in %s nicht erlaubt" -#: parser/parse_agg.c:641 +#: parser/parse_agg.c:656 #, c-format msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "Aggregatfunktion auf äußerer Ebene kann keine Variable einer unteren Ebene in ihren direkten Argumenten haben" -#: parser/parse_agg.c:712 +#: parser/parse_agg.c:735 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" + +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 +#: parser/parse_func.c:866 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Sie können möglicherweise die Funktion mit Ergebnismenge in ein LATERAL-FROM-Element verschieben." + +#: parser/parse_agg.c:741 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "Aufrufe von Aggregatfunktionen können keine Aufrufe von Fensterfunktionen enthalten" -#: parser/parse_agg.c:790 +#: parser/parse_agg.c:820 msgid "window functions are not allowed in JOIN conditions" msgstr "Fensterfunktionen sind in JOIN-Bedingungen nicht erlaubt" -#: parser/parse_agg.c:797 +#: parser/parse_agg.c:827 msgid "window functions are not allowed in functions in FROM" msgstr "Fensterfunktionen sind in Funktionen in FROM nicht erlaubt" -#: parser/parse_agg.c:803 +#: parser/parse_agg.c:833 msgid "window functions are not allowed in policy expressions" msgstr "Fensterfunktionen sind in Policy-Ausdrücken nicht erlaubt" -#: parser/parse_agg.c:815 +#: parser/parse_agg.c:846 msgid "window functions are not allowed in window definitions" msgstr "Fensterfunktionen sind in Fensterdefinitionen nicht erlaubt" -#: parser/parse_agg.c:847 +#: parser/parse_agg.c:878 msgid "window functions are not allowed in check constraints" msgstr "Fensterfunktionen sind in Check-Constraints nicht erlaubt" -#: parser/parse_agg.c:851 +#: parser/parse_agg.c:882 msgid "window functions are not allowed in DEFAULT expressions" msgstr "Fensterfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" -#: parser/parse_agg.c:854 +#: parser/parse_agg.c:885 msgid "window functions are not allowed in index expressions" msgstr "Fensterfunktionen sind in Indexausdrücken nicht erlaubt" -#: parser/parse_agg.c:857 +#: parser/parse_agg.c:888 msgid "window functions are not allowed in index predicates" msgstr "Fensterfunktionen sind in Indexprädikaten nicht erlaubt" -#: parser/parse_agg.c:860 +#: parser/parse_agg.c:891 msgid "window functions are not allowed in transform expressions" msgstr "Fensterfunktionen sind in Umwandlungsausdrücken nicht erlaubt" -#: parser/parse_agg.c:863 +#: parser/parse_agg.c:894 msgid "window functions are not allowed in EXECUTE parameters" msgstr "Fensterfunktionen sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_agg.c:866 +#: parser/parse_agg.c:897 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "Fensterfunktionen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" -#: parser/parse_agg.c:869 -#, fuzzy -#| msgid "window functions are not allowed in index expressions" -msgid "window functions are not allowed in partition key expression" -msgstr "Fensterfunktionen sind in Indexausdrücken nicht erlaubt" +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "Fensterfunktionen sind in Partitionierungsschlüsselausdrücken nicht erlaubt" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "Fensterfunktionen sind in CALL-Argumenten nicht erlaubt" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:889 parser/parse_clause.c:1776 +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 #, c-format msgid "window functions are not allowed in %s" msgstr "Fensterfunktionen sind in %s nicht erlaubt" -#: parser/parse_agg.c:923 parser/parse_clause.c:2610 +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 #, c-format msgid "window \"%s\" does not exist" msgstr "Fenster »%s« existiert nicht" -#: parser/parse_agg.c:1008 +#: parser/parse_agg.c:1042 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "zu viele Grouping-Sets vorhanden (maximal 4096)" -#: parser/parse_agg.c:1157 +#: parser/parse_agg.c:1191 #, c-format msgid "aggregate functions are not allowed in a recursive query's recursive term" msgstr "Aggregatfunktionen sind nicht im rekursiven Ausdruck einer rekursiven Anfrage erlaubt" -#: parser/parse_agg.c:1350 +#: parser/parse_agg.c:1384 #, c-format msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" msgstr "Spalte »%s.%s« muss in der GROUP-BY-Klausel erscheinen oder in einer Aggregatfunktion verwendet werden" -#: parser/parse_agg.c:1353 +#: parser/parse_agg.c:1387 #, c-format msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "Direkte Argumente einer Ordered-Set-Aggregatfunktion dürfen nur gruppierte Spalten verwenden." -#: parser/parse_agg.c:1358 +#: parser/parse_agg.c:1392 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "Unteranfrage verwendet nicht gruppierte Spalte »%s.%s« aus äußerer Anfrage" -#: parser/parse_agg.c:1522 +#: parser/parse_agg.c:1556 #, c-format msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "Argumente von GROUPING müssen Gruppierausdrücke der zugehörigen Anfrageebene sein" -#: parser/parse_clause.c:626 +#: parser/parse_clause.c:199 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "Relation »%s« kann nicht das Ziel einer datenverändernden Anweisung sein" + +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "Funktionen mit Ergebnismenge müssen auf oberster Ebene von FROM erscheinen" + +#: parser/parse_clause.c:655 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "mehrere Spaltendefinitionslisten für die selbe Funktion sind nicht erlaubt" -#: parser/parse_clause.c:659 +#: parser/parse_clause.c:688 #, c-format msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "ROWS FROM() mit mehreren Funktionen kann keine Spaltendefinitionsliste haben" -#: parser/parse_clause.c:660 +#: parser/parse_clause.c:689 #, c-format msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "Geben Sie innerhalb von ROWS FROM() jeder Funktion eine eigene Spaltendefinitionsliste." -#: parser/parse_clause.c:666 +#: parser/parse_clause.c:695 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "UNNEST() mit mehreren Argumenten kann keine Spaltendefinitionsliste haben" -#: parser/parse_clause.c:667 +#: parser/parse_clause.c:696 #, c-format msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "Verwenden Sie getrennte UNNEST()-Aufrufe innerhalb von ROWS FROM() und geben Sie jeder eine eigene Spaltendefinitionsliste." -#: parser/parse_clause.c:674 +#: parser/parse_clause.c:703 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY kann nicht mit einer Spaltendefinitionsliste verwendet werden" -#: parser/parse_clause.c:675 +#: parser/parse_clause.c:704 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "Geben Sie die Spaltendefinitionsliste innerhalb von ROWS FROM() an." -#: parser/parse_clause.c:779 +#: parser/parse_clause.c:807 #, c-format msgid "only one FOR ORDINALITY column is allowed" -msgstr "" +msgstr "nur eine FOR-ORDINALITY-Spalte ist erlaubt" -#: parser/parse_clause.c:840 +#: parser/parse_clause.c:868 #, c-format msgid "column name \"%s\" is not unique" msgstr "Spaltenname »%s« ist nicht eindeutig" -#: parser/parse_clause.c:882 -#, fuzzy, c-format -#| msgid "function %s is not unique" +#: parser/parse_clause.c:910 +#, c-format msgid "namespace name \"%s\" is not unique" -msgstr "Funktion %s ist nicht eindeutig" +msgstr "Namensraumname »%s« ist nicht eindeutig" -#: parser/parse_clause.c:892 +#: parser/parse_clause.c:920 #, c-format msgid "only one default namespace is allowed" -msgstr "" +msgstr "nur ein Standardnamensraum ist erlaubt" -#: parser/parse_clause.c:953 +#: parser/parse_clause.c:982 #, c-format msgid "tablesample method %s does not exist" msgstr "Tablesample-Methode %s existiert nicht" -#: parser/parse_clause.c:975 +#: parser/parse_clause.c:1004 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "Tablesample-Methode %s benötigt %d Argument, nicht %d" msgstr[1] "Tablesample-Methode %s benötigt %d Argumente, nicht %d" -#: parser/parse_clause.c:1009 +#: parser/parse_clause.c:1038 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "Tablesample-Methode %s unterstützt REPEATABLE nicht" -#: parser/parse_clause.c:1157 +#: parser/parse_clause.c:1208 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "TABLESAMPLE-Klausel kann nur auf Tabellen und materialisierte Sichten angewendet werden" -#: parser/parse_clause.c:1327 +#: parser/parse_clause.c:1378 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "Spaltenname »%s« erscheint mehrmals in der USING-Klausel" -#: parser/parse_clause.c:1342 +#: parser/parse_clause.c:1393 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der linken Tabelle" -#: parser/parse_clause.c:1351 +#: parser/parse_clause.c:1402 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der linken Tabelle" -#: parser/parse_clause.c:1365 +#: parser/parse_clause.c:1416 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "gemeinsamer Spaltenname »%s« erscheint mehrmals in der rechten Tabelle" -#: parser/parse_clause.c:1374 +#: parser/parse_clause.c:1425 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "Spalte »%s« aus der USING-Klausel existiert nicht in der rechten Tabelle" -#: parser/parse_clause.c:1428 +#: parser/parse_clause.c:1479 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "Spaltenaliasliste für »%s« hat zu viele Einträge" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1737 +#: parser/parse_clause.c:1788 #, c-format msgid "argument of %s must not contain variables" msgstr "Argument von %s darf keine Variablen enthalten" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1902 +#: parser/parse_clause.c:1953 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s »%s« ist nicht eindeutig" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1931 +#: parser/parse_clause.c:1982 #, c-format msgid "non-integer constant in %s" msgstr "Konstante in %s ist keine ganze Zahl" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1953 +#: parser/parse_clause.c:2004 #, c-format msgid "%s position %d is not in select list" msgstr "%s Position %d ist nicht in der Select-Liste" -#: parser/parse_clause.c:2394 +#: parser/parse_clause.c:2445 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE ist auf 12 Elemente begrenzt" -#: parser/parse_clause.c:2598 +#: parser/parse_clause.c:2651 #, c-format msgid "window \"%s\" is already defined" msgstr "Fenster »%s« ist bereits definiert" -#: parser/parse_clause.c:2659 +#: parser/parse_clause.c:2712 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "PARTITION-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:2671 +#: parser/parse_clause.c:2724 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "ORDER-BY-Klausel von Fenster »%s« kann nicht aufgehoben werden" -#: parser/parse_clause.c:2701 parser/parse_clause.c:2707 +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "kann Fenster »%s« nicht kopieren, weil es eine Frame-Klausel hat" -#: parser/parse_clause.c:2709 +#: parser/parse_clause.c:2762 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Lassen Sie die Klammern in dieser OVER-Klausel weg." -#: parser/parse_clause.c:2775 +#: parser/parse_clause.c:2782 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "" + +#: parser/parse_clause.c:2805 +#, fuzzy, c-format +#| msgid "window function %s requires an OVER clause" +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "Fensterfunktion %s erfordert eine OVER-Klausel" + +#: parser/parse_clause.c:2875 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "in einer Aggregatfunktion mit DISTINCT müssen ORDER-BY-Ausdrücke in der Argumentliste erscheinen" -#: parser/parse_clause.c:2776 +#: parser/parse_clause.c:2876 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "bei SELECT DISTINCT müssen ORDER-BY-Ausdrücke in der Select-Liste erscheinen" -#: parser/parse_clause.c:2808 +#: parser/parse_clause.c:2908 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "eine Aggregatfunktion mit DISTINCT muss mindestens ein Argument haben" -#: parser/parse_clause.c:2809 +#: parser/parse_clause.c:2909 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT muss mindestens eine Spalte haben" -#: parser/parse_clause.c:2875 parser/parse_clause.c:2907 +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "Ausdrücke in SELECT DISTINCT ON müssen mit den ersten Ausdrücken in ORDER BY übereinstimmen" -#: parser/parse_clause.c:2985 +#: parser/parse_clause.c:3085 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ASC/DESC ist in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:2991 +#: parser/parse_clause.c:3091 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "NULLS FIRST/LAST ist in der ON-CONFLICT-Klausel nicht erlaubt" -#: parser/parse_clause.c:3071 +#: parser/parse_clause.c:3170 #, c-format msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATE benötigt Inferenzangabe oder Constraint-Namen" -#: parser/parse_clause.c:3072 +#: parser/parse_clause.c:3171 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Zum Bespiel ON CONFLICT (Spaltenname)." -#: parser/parse_clause.c:3083 +#: parser/parse_clause.c:3182 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT wird nicht mit Systemkatalogtabellen unterstützt" -#: parser/parse_clause.c:3091 +#: parser/parse_clause.c:3190 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT wird nicht unterstützt mit Tabelle »%s«, die als Katalogtabelle verwendet wird" -#: parser/parse_clause.c:3217 +#: parser/parse_clause.c:3333 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "Operator %s ist kein gültiger Sortieroperator" + +#: parser/parse_clause.c:3335 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Sortieroperatoren müssen die Mitglieder »<« oder »>« einer »btree«-Operatorfamilie sein." + +#: parser/parse_clause.c:3646 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "" + +#: parser/parse_clause.c:3660 #, c-format -msgid "operator %s is not a valid ordering operator" -msgstr "Operator %s ist kein gültiger Sortieroperator" +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "" -#: parser/parse_clause.c:3219 +#: parser/parse_clause.c:3663 #, c-format -msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." -msgstr "Sortieroperatoren müssen die Mitglieder »<« oder »>« einer »btree«-Operatorfamilie sein." +msgid "Cast the offset value to the exact intended type." +msgstr "" -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2123 parser/parse_expr.c:2699 parser/parse_target.c:935 +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:961 #, c-format msgid "cannot cast type %s to %s" msgstr "kann Typ %s nicht in Typ %s umwandeln" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." msgstr "Eingabe hat zu wenige Spalten." -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "Kann in Spalte %3$d Typ %1$s nicht in Typ %2$s umwandeln." -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." msgstr "Eingabe hat zu viele Spalten." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1128 +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "Argument von %s muss Typ %s haben, nicht Typ %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1091 parser/parse_coerce.c:1140 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "Argument von %s darf keine Ergebnismenge zurückgeben" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1280 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "%s-Typen %s und %s passen nicht zusammen" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1347 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "%s konnte Typ %s nicht in %s umwandeln" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "als »anyelement« deklariert Argumente sind nicht alle gleich" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "als »anyarray« deklarierte Argumente sind nicht alle gleich" -#: parser/parse_coerce.c:1689 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "als »anyrange« deklarierte Argumente sind nicht alle gleich" -#: parser/parse_coerce.c:1718 parser/parse_coerce.c:1933 -#: parser/parse_coerce.c:1967 -#, fuzzy, c-format -#| msgid "argument declared \"anyarray\" is not an array but type %s" +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 +#, c-format msgid "argument declared %s is not an array but type %s" -msgstr "als »anyarray« deklariertes Argument ist kein Array sondern Typ %s" +msgstr "als %s deklariertes Argument ist kein Array sondern Typ %s" -#: parser/parse_coerce.c:1734 parser/parse_coerce.c:1773 -#, fuzzy, c-format -#| msgid "argument declared \"anyarray\" is not consistent with argument declared \"anyelement\"" +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 +#, c-format msgid "argument declared %s is not consistent with argument declared %s" -msgstr "als »anyarray« deklariertes Argument ist nicht mit als »anyelement« deklariertem Argument konsistent" +msgstr "als %s deklariertes Argument ist nicht mit als %s deklariertem Argument konsistent" -#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1980 -#, fuzzy, c-format -#| msgid "argument declared \"anyrange\" is not a range type but type %s" +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 +#, c-format msgid "argument declared %s is not a range type but type %s" -msgstr "als »anyrange« deklariertes Argument ist kein Bereichstyp sondern Typ %s" +msgstr "als %s deklariertes Argument ist kein Bereichstyp sondern Typ %s" -#: parser/parse_coerce.c:1794 -#, fuzzy, c-format -#| msgid "could not determine polymorphic type because input has type \"unknown\"" +#: parser/parse_coerce.c:1865 +#, c-format msgid "could not determine polymorphic type because input has type %s" -msgstr "konnte polymorphischen Typ nicht bestimmen, weil Eingabe Typ »unknown« hat" +msgstr "konnte polymorphischen Typ nicht bestimmen, weil Eingabe Typ %s hat" -#: parser/parse_coerce.c:1805 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "mit »anynonarray« gepaarter Typ ist ein Array-Typ: %s" -#: parser/parse_coerce.c:1815 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "mit »anyenum« gepaarter Typ ist kein Enum-Typ: %s" -#: parser/parse_coerce.c:1855 parser/parse_coerce.c:1885 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "konnte Bereichstyp für Datentyp %s nicht finden" @@ -14135,444 +15115,507 @@ msgstr "FOR UPDATE/SHARE in einer rekursiven Anfrage ist nicht implementiert" msgid "recursive reference to query \"%s\" must not appear more than once" msgstr "rekursiver Verweis auf Anfrage »%s« darf nicht mehrmals erscheinen" -#: parser/parse_expr.c:357 -#, fuzzy, c-format -#| msgid "null array element not allowed in this context" +#: parser/parse_expr.c:350 +#, c-format msgid "DEFAULT is not allowed in this context" -msgstr "NULL-Werte im Array sind in diesem Zusammenhang nicht erlaubt" +msgstr "DEFAULT ist in diesem Zusammenhang nicht erlaubt" -#: parser/parse_expr.c:410 parser/parse_relation.c:3110 -#: parser/parse_relation.c:3130 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 +#: parser/parse_relation.c:3307 #, c-format msgid "column %s.%s does not exist" msgstr "Spalte %s.%s existiert nicht" -#: parser/parse_expr.c:422 +#: parser/parse_expr.c:415 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "Spalte »%s« nicht gefunden im Datentyp %s" -#: parser/parse_expr.c:428 +#: parser/parse_expr.c:421 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "konnte Spalte »%s« im Record-Datentyp nicht identifizieren" -#: parser/parse_expr.c:434 +#: parser/parse_expr.c:427 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "Spaltenschreibweise .%s mit Typ %s verwendet, der kein zusammengesetzter Typ ist" -#: parser/parse_expr.c:464 parser/parse_target.c:721 +#: parser/parse_expr.c:458 parser/parse_target.c:728 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "Zeilenexpansion mit »*« wird hier nicht unterstützt" -#: parser/parse_expr.c:769 parser/parse_relation.c:668 -#: parser/parse_relation.c:768 parser/parse_target.c:1170 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 +#: parser/parse_relation.c:789 parser/parse_target.c:1199 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "Spaltenverweis »%s« ist nicht eindeutig" -#: parser/parse_expr.c:825 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "es gibt keinen Parameter $%d" -#: parser/parse_expr.c:1064 +#: parser/parse_expr.c:1070 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "NULLIF erfordert, dass Operator = boolean ergibt" -#: parser/parse_expr.c:1508 parser/parse_expr.c:1540 +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 +#, c-format +msgid "%s must not return a set" +msgstr "%s darf keine Ergebnismenge zurückgeben" + +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 #, c-format msgid "number of columns does not match number of values" msgstr "Anzahl der Spalten stimmt nicht mit der Anzahl der Werte überein" -#: parser/parse_expr.c:1554 +#: parser/parse_expr.c:1570 #, c-format msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" -msgstr "" +msgstr "die Quelle für ein UPDATE-Element mit mehreren Spalten muss ein Sub-SELECT oder ein ROW()-Ausdruck sein" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "Funktionen mit Ergebnismenge sind in %s nicht erlaubt" -#: parser/parse_expr.c:1798 +#: parser/parse_expr.c:1825 msgid "cannot use subquery in check constraint" msgstr "Unteranfragen können nicht in Check-Constraints verwendet werden" -#: parser/parse_expr.c:1802 +#: parser/parse_expr.c:1829 msgid "cannot use subquery in DEFAULT expression" msgstr "Unteranfragen können nicht in DEFAULT-Ausdrücken verwendet werden" -#: parser/parse_expr.c:1805 +#: parser/parse_expr.c:1832 msgid "cannot use subquery in index expression" msgstr "Unteranfragen können nicht in Indexausdrücken verwendet werden" -#: parser/parse_expr.c:1808 +#: parser/parse_expr.c:1835 msgid "cannot use subquery in index predicate" msgstr "Unteranfragen können nicht im Indexprädikat verwendet werden" -#: parser/parse_expr.c:1811 +#: parser/parse_expr.c:1838 msgid "cannot use subquery in transform expression" msgstr "Unteranfragen können in Umwandlungsausdrücken nicht verwendet werden" -#: parser/parse_expr.c:1814 +#: parser/parse_expr.c:1841 msgid "cannot use subquery in EXECUTE parameter" msgstr "Unteranfragen können nicht in EXECUTE-Parameter verwendet werden" -#: parser/parse_expr.c:1817 +#: parser/parse_expr.c:1844 msgid "cannot use subquery in trigger WHEN condition" msgstr "Unteranfragen können nicht in der WHEN-Bedingung eines Triggers verwendet werden" -#: parser/parse_expr.c:1820 -#, fuzzy -#| msgid "cannot use subquery in index expression" +#: parser/parse_expr.c:1847 msgid "cannot use subquery in partition key expression" -msgstr "Unteranfragen können nicht in Indexausdrücken verwendet werden" +msgstr "Unteranfragen können nicht in Partitionierungsschlüsselausdrücken verwendet werden" + +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "Unteranfragen können nicht in CALL-Argument verwendet werden" -#: parser/parse_expr.c:1873 +#: parser/parse_expr.c:1903 #, c-format msgid "subquery must return only one column" msgstr "Unteranfrage darf nur eine Spalte zurückgeben" -#: parser/parse_expr.c:1957 +#: parser/parse_expr.c:1987 #, c-format msgid "subquery has too many columns" msgstr "Unteranfrage hat zu viele Spalten" -#: parser/parse_expr.c:1962 +#: parser/parse_expr.c:1992 #, c-format msgid "subquery has too few columns" msgstr "Unteranfrage hat zu wenige Spalten" -#: parser/parse_expr.c:2063 +#: parser/parse_expr.c:2093 #, c-format msgid "cannot determine type of empty array" msgstr "kann Typ eines leeren Arrays nicht bestimmen" -#: parser/parse_expr.c:2064 +#: parser/parse_expr.c:2094 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "Wandeln Sie ausdrücklich in den gewünschten Typ um, zum Beispiel ARRAY[]::integer[]." -#: parser/parse_expr.c:2078 +#: parser/parse_expr.c:2108 #, c-format msgid "could not find element type for data type %s" msgstr "konnte Elementtyp für Datentyp %s nicht finden" -#: parser/parse_expr.c:2353 +#: parser/parse_expr.c:2395 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "unbenannter XML-Attributwert muss ein Spaltenverweis sein" -#: parser/parse_expr.c:2354 +#: parser/parse_expr.c:2396 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "unbenannter XML-Elementwert muss ein Spaltenverweis sein" -#: parser/parse_expr.c:2369 +#: parser/parse_expr.c:2411 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "XML-Attributname »%s« einscheint mehrmals" -#: parser/parse_expr.c:2476 +#: parser/parse_expr.c:2518 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "kann das Ergebnis von XMLSERIALIZE nicht in Typ %s umwandeln" -#: parser/parse_expr.c:2772 parser/parse_expr.c:2967 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format msgid "unequal number of entries in row expressions" msgstr "ungleiche Anzahl Einträge in Zeilenausdrücken" -#: parser/parse_expr.c:2782 +#: parser/parse_expr.c:2824 #, c-format msgid "cannot compare rows of zero length" msgstr "kann Zeilen mit Länge null nicht vergleichen" -#: parser/parse_expr.c:2806 +#: parser/parse_expr.c:2849 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "Zeilenvergleichsoperator muss Typ boolean zurückgeben, nicht Typ %s" -#: parser/parse_expr.c:2813 +#: parser/parse_expr.c:2856 #, c-format msgid "row comparison operator must not return a set" msgstr "Zeilenvergleichsoperator darf keine Ergebnismenge zurückgeben" -#: parser/parse_expr.c:2872 parser/parse_expr.c:2913 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "konnte Interpretation des Zeilenvergleichsoperators %s nicht bestimmen" -#: parser/parse_expr.c:2874 +#: parser/parse_expr.c:2917 #, c-format msgid "Row comparison operators must be associated with btree operator families." msgstr "Zeilenvergleichsoperatoren müssen einer »btree«-Operatorfamilie zugeordnet sein." -#: parser/parse_expr.c:2915 +#: parser/parse_expr.c:2958 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "Es gibt mehrere gleichermaßen plausible Kandidaten." -#: parser/parse_expr.c:3007 +#: parser/parse_expr.c:3051 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROM erfordert, dass Operator = boolean ergibt" -#: parser/parse_expr.c:3320 parser/parse_expr.c:3338 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "Änderung der Operatorrangfolge: %s hat jetzt niedrigere Priorität als %s" -#: parser/parse_func.c:175 +#: parser/parse_func.c:185 #, c-format msgid "argument name \"%s\" used more than once" msgstr "Argumentname »%s« mehrmals angegeben" -#: parser/parse_func.c:186 +#: parser/parse_func.c:196 #, c-format msgid "positional argument cannot follow named argument" msgstr "Positionsargument kann nicht hinter benanntem Argument stehen" -#: parser/parse_func.c:271 +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "%s ist keine Prozedur" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Um eine Funktion aufzurufen, verwenden Sie SELECT." + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "%s ist eine Prozedur" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Um eine Prozedur aufzurufen, verwenden Sie CALL." + +#: parser/parse_func.c:306 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "%s(*) angegeben, aber %s ist keine Aggregatfunktion" -#: parser/parse_func.c:278 +#: parser/parse_func.c:313 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "DISTINCT wurde angegeben, aber %s ist keine Aggregatfunktion" -#: parser/parse_func.c:284 +#: parser/parse_func.c:319 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "WITHIN GROUP wurde angegeben, aber %s ist keine Aggregatfunktion" -#: parser/parse_func.c:290 +#: parser/parse_func.c:325 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "ORDER BY angegeben, aber %s ist keine Aggregatfunktion" -#: parser/parse_func.c:296 +#: parser/parse_func.c:331 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "FILTER wurde angegeben, aber %s ist keine Aggregatfunktion" -#: parser/parse_func.c:302 +#: parser/parse_func.c:337 #, c-format msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "OVER angegeben, aber %s ist keine Fensterfunktion oder Aggregatfunktion" -#: parser/parse_func.c:332 +#: parser/parse_func.c:375 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP muss angegeben werden für Ordered-Set-Aggregatfunktion %s" -#: parser/parse_func.c:338 +#: parser/parse_func.c:381 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVER wird für Ordered-Set-Aggregatfunktion %s nicht unterstützt" -#: parser/parse_func.c:369 parser/parse_func.c:398 +#: parser/parse_func.c:412 parser/parse_func.c:441 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt %d direkte Argumente, nicht %d." -#: parser/parse_func.c:423 +#: parser/parse_func.c:466 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "Um die Hypothetical-Set-Aggregatfunktion %s zu verwenden, muss die Anzahl der hypothetischen direkten Argumente (hier %d) mit der Anzahl der Sortierspalten (hier %d) übereinstimmen." -#: parser/parse_func.c:437 +#: parser/parse_func.c:480 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr "Es gibt eine Ordered-Set-Aggregatfunktion %s, aber sie benötigt mindestens %d direkte Argumente." -#: parser/parse_func.c:456 +#: parser/parse_func.c:499 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s ist keine Ordered-Set-Aggregatfunktion und kann deshalb kein WITHIN GROUP haben" -#: parser/parse_func.c:469 +#: parser/parse_func.c:512 #, c-format msgid "window function %s requires an OVER clause" msgstr "Fensterfunktion %s erfordert eine OVER-Klausel" -#: parser/parse_func.c:476 +#: parser/parse_func.c:519 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "Fensterfunktion %s kann kein WITHIN GROUP haben" -#: parser/parse_func.c:497 +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "Prozedur %s ist nicht eindeutig" + +#: parser/parse_func.c:551 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Konnte keine beste Kandidatprozedur auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:557 #, c-format msgid "function %s is not unique" msgstr "Funktion %s ist nicht eindeutig" -#: parser/parse_func.c:500 +#: parser/parse_func.c:560 #, c-format msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "Konnte keine beste Kandidatfunktion auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_func.c:511 +#: parser/parse_func.c:599 #, c-format msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "Keine Aggregatfunktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Mõglicherweise steht ORDER BY an der falschen Stelle; ORDER BY muss hinter allen normalen Argumenten der Aggregatfunktion stehen." -#: parser/parse_func.c:522 +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "Prozedur %s existiert nicht" + +#: parser/parse_func.c:610 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Keine Prozedur stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_func.c:619 #, c-format msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgstr "Keine Funktion stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_func.c:624 +#: parser/parse_func.c:721 #, c-format msgid "VARIADIC argument must be an array" msgstr "VARIADIC-Argument muss ein Array sein" -#: parser/parse_func.c:676 parser/parse_func.c:740 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "beim Aufruf einer parameterlosen Aggregatfunktion muss %s(*) angegeben werden" -#: parser/parse_func.c:683 +#: parser/parse_func.c:780 #, c-format msgid "aggregates cannot return sets" msgstr "Aggregatfunktionen können keine Ergebnismengen zurückgeben" -#: parser/parse_func.c:698 +#: parser/parse_func.c:795 #, c-format msgid "aggregates cannot use named arguments" msgstr "Aggregatfunktionen können keine benannten Argumente verwenden" -#: parser/parse_func.c:730 +#: parser/parse_func.c:827 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "DISTINCT ist für Fensterfunktionen nicht implementiert" -#: parser/parse_func.c:750 +#: parser/parse_func.c:847 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "ORDER BY in Aggregatfunktion ist für Fensterfunktionen nicht implementiert" -#: parser/parse_func.c:759 +#: parser/parse_func.c:856 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER ist für Fensterfunktionen, die keine Aggregatfunktionen sind, nicht implementiert" -#: parser/parse_func.c:765 +#: parser/parse_func.c:865 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "Aufrufe von Fensterfunktionen können keine Aufrufe von Funktionen mit Ergebnismenge enthalten" + +#: parser/parse_func.c:873 #, c-format msgid "window functions cannot return sets" msgstr "Fensterfunktionen können keine Ergebnismengen zurückgeben" -#: parser/parse_func.c:2014 +#: parser/parse_func.c:2059 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "Funktionsname »%s« ist nicht eindeutig" + +#: parser/parse_func.c:2061 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Geben Sie eine Argumentliste an, um die Funktion eindeutig auszuwählen." + +#: parser/parse_func.c:2071 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "konnte keine Funktion namens »%s« finden" + +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s ist keine Funktion" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "konnte keine Prozedur namens »%s« finden" + +#: parser/parse_func.c:2198 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "konnte keine Aggregatfunktion namens »%s« finden" + +#: parser/parse_func.c:2203 #, c-format msgid "aggregate %s(*) does not exist" msgstr "Aggregatfunktion %s(*) existiert nicht" -#: parser/parse_func.c:2019 +#: parser/parse_func.c:2208 #, c-format msgid "aggregate %s does not exist" msgstr "Aggregatfunktion %s existiert nicht" -#: parser/parse_func.c:2038 +#: parser/parse_func.c:2221 #, c-format msgid "function %s is not an aggregate" msgstr "Funktion %s ist keine Aggregatfunktion" -#: parser/parse_func.c:2086 -#, fuzzy -#| msgid "window functions are not allowed in JOIN conditions" +#: parser/parse_func.c:2271 msgid "set-returning functions are not allowed in JOIN conditions" -msgstr "Fensterfunktionen sind in JOIN-Bedingungen nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in JOIN-Bedingungen nicht erlaubt" -#: parser/parse_func.c:2099 -#, fuzzy -#| msgid "window functions are not allowed in policy expressions" +#: parser/parse_func.c:2292 msgid "set-returning functions are not allowed in policy expressions" -msgstr "Fensterfunktionen sind in Policy-Ausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Policy-Ausdrücken nicht erlaubt" -#: parser/parse_func.c:2114 -#, fuzzy -#| msgid "window functions are not allowed in window definitions" +#: parser/parse_func.c:2308 msgid "set-returning functions are not allowed in window definitions" -msgstr "Fensterfunktionen sind in Fensterdefinitionen nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Fensterdefinitionen nicht erlaubt" -#: parser/parse_func.c:2152 -#, fuzzy -#| msgid "window functions are not allowed in check constraints" +#: parser/parse_func.c:2346 msgid "set-returning functions are not allowed in check constraints" -msgstr "Fensterfunktionen sind in Check-Constraints nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Check-Constraints nicht erlaubt" -#: parser/parse_func.c:2156 -#, fuzzy -#| msgid "window functions are not allowed in DEFAULT expressions" +#: parser/parse_func.c:2350 msgid "set-returning functions are not allowed in DEFAULT expressions" -msgstr "Fensterfunktionen sind in DEFAULT-Ausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in DEFAULT-Ausdrücken nicht erlaubt" -#: parser/parse_func.c:2159 -#, fuzzy -#| msgid "window functions are not allowed in index expressions" +#: parser/parse_func.c:2353 msgid "set-returning functions are not allowed in index expressions" -msgstr "Fensterfunktionen sind in Indexausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Indexausdrücken nicht erlaubt" -#: parser/parse_func.c:2162 -#, fuzzy -#| msgid "window functions are not allowed in index predicates" +#: parser/parse_func.c:2356 msgid "set-returning functions are not allowed in index predicates" -msgstr "Fensterfunktionen sind in Indexprädikaten nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Indexprädikaten nicht erlaubt" -#: parser/parse_func.c:2165 -#, fuzzy -#| msgid "window functions are not allowed in transform expressions" +#: parser/parse_func.c:2359 msgid "set-returning functions are not allowed in transform expressions" -msgstr "Fensterfunktionen sind in Umwandlungsausdrücken nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in Umwandlungsausdrücken nicht erlaubt" -#: parser/parse_func.c:2168 -#, fuzzy -#| msgid "window functions are not allowed in EXECUTE parameters" +#: parser/parse_func.c:2362 msgid "set-returning functions are not allowed in EXECUTE parameters" -msgstr "Fensterfunktionen sind in EXECUTE-Parametern nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in EXECUTE-Parametern nicht erlaubt" -#: parser/parse_func.c:2171 -#, fuzzy -#| msgid "window functions are not allowed in trigger WHEN conditions" +#: parser/parse_func.c:2365 msgid "set-returning functions are not allowed in trigger WHEN conditions" -msgstr "Fensterfunktionen sind in der WHEN-Bedingung eines Triggers nicht erlaubt" +msgstr "Funktionen mit Ergebnismenge sind in der WHEN-Bedingung eines Triggers nicht erlaubt" -#: parser/parse_func.c:2174 -#, fuzzy -#| msgid "window functions are not allowed in index expressions" -msgid "set-returning functions are not allowed in partition key expression" -msgstr "Fensterfunktionen sind in Indexausdrücken nicht erlaubt" +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "Funktionen mit Ergebnismenge sind in Partitionierungsschlüsselausdrücken nicht erlaubt" -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_func.c:2194 -#, fuzzy, c-format -#| msgid "window functions are not allowed in %s" -msgid "set-returning functions are not allowed in %s" -msgstr "Fensterfunktionen sind in %s nicht erlaubt" +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "Funktionen mit Ergebnismenge sind in CALL-Argumenten nicht erlaubt" -#: parser/parse_node.c:85 +#: parser/parse_node.c:87 #, c-format msgid "target lists can have at most %d entries" msgstr "Targetlisten können höchstens %d Einträge haben" -#: parser/parse_node.c:254 +#: parser/parse_node.c:256 #, c-format msgid "cannot subscript type %s because it is not an array" msgstr "kann aus Typ %s kein Element auswählen, weil er kein Array ist" -#: parser/parse_node.c:356 parser/parse_node.c:393 +#: parser/parse_node.c:358 parser/parse_node.c:395 #, c-format msgid "array subscript must have type integer" msgstr "Arrayindex muss Typ integer haben" -#: parser/parse_node.c:424 +#: parser/parse_node.c:426 #, c-format msgid "array assignment requires type %s but expression is of type %s" msgstr "Arrayzuweisung erfordert Typ %s, aber Ausdruck hat Typ %s" -#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:585 -#: utils/adt/regproc.c:605 utils/adt/regproc.c:789 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format msgid "operator does not exist: %s" msgstr "Operator existiert nicht: %s" @@ -14582,14 +15625,6 @@ msgstr "Operator existiert nicht: %s" msgid "Use an explicit ordering operator or modify the query." msgstr "Verwenden Sie einen ausdrücklichen Sortieroperator oder ändern Sie die Anfrage." -#: parser/parse_oper.c:228 utils/adt/array_userfuncs.c:794 -#: utils/adt/array_userfuncs.c:933 utils/adt/arrayfuncs.c:3639 -#: utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6039 -#: utils/adt/rowtypes.c:1167 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "konnte keinen Ist-Gleich-Operator für Typ %s ermitteln" - #: parser/parse_oper.c:480 #, c-format msgid "operator requires run-time type coercion: %s" @@ -14605,27 +15640,32 @@ msgstr "Operator ist nicht eindeutig: %s" msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgstr "Konnte keinen besten Kandidatoperator auswählen. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_oper.c:726 +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Kein Operator stimmt mit dem angegebenen Namen und Argumenttyp überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." + +#: parser/parse_oper.c:729 #, c-format -msgid "No operator matches the given name and argument type(s). You might need to add explicit type casts." +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." msgstr "Kein Operator stimmt mit dem angegebenen Namen und den Argumenttypen überein. Sie müssen möglicherweise ausdrückliche Typumwandlungen hinzufügen." -#: parser/parse_oper.c:785 parser/parse_oper.c:903 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "Operator ist nur eine Hülle: %s" -#: parser/parse_oper.c:891 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "op ANY/ALL (array) erfordert Array auf der rechten Seite" -#: parser/parse_oper.c:933 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "op ANY/ALL (array) erfordert, dass Operator boolean ergibt" -#: parser/parse_oper.c:938 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "op ANY/ALL (array) erfordert, dass Operator keine Ergebnismenge zurückgibt" @@ -14635,158 +15675,159 @@ msgstr "op ANY/ALL (array) erfordert, dass Operator keine Ergebnismenge zurückg msgid "inconsistent types deduced for parameter $%d" msgstr "inkonsistente Typen für Parameter $%d ermittelt" -#: parser/parse_relation.c:175 +#: parser/parse_relation.c:176 #, c-format msgid "table reference \"%s\" is ambiguous" msgstr "Tabellenbezug »%s« ist nicht eindeutig" -#: parser/parse_relation.c:219 +#: parser/parse_relation.c:220 #, c-format msgid "table reference %u is ambiguous" msgstr "Tabellenbezug %u ist nicht eindeutig" -#: parser/parse_relation.c:398 +#: parser/parse_relation.c:419 #, c-format msgid "table name \"%s\" specified more than once" msgstr "Tabellenname »%s« mehrmals angegeben" -#: parser/parse_relation.c:425 parser/parse_relation.c:3050 +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "ungültiger Verweis auf FROM-Klausel-Eintrag für Tabelle »%s«" -#: parser/parse_relation.c:428 parser/parse_relation.c:3055 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt einen Eintrag für Tabelle »%s«, aber auf ihn kann aus diesem Teil der Anfrage nicht verwiesen werden." -#: parser/parse_relation.c:430 +#: parser/parse_relation.c:451 #, c-format msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "Der JOIN-Typ für LATERAL muss INNER oder LEFT sein." -#: parser/parse_relation.c:706 +#: parser/parse_relation.c:727 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "Verweis auf Systemspalte »%s« im Check-Constraint ist ungültig" -#: parser/parse_relation.c:1065 parser/parse_relation.c:1345 -#: parser/parse_relation.c:1914 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 +#: parser/parse_relation.c:1936 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "Tabelle »%s« hat %d Spalten, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:1152 +#: parser/parse_relation.c:1173 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt ein WITH-Element namens »%s«, aber darauf kann aus diesem Teil der Anfrage kein Bezug genommen werden." -#: parser/parse_relation.c:1154 +#: parser/parse_relation.c:1175 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "Verwenden Sie WITH RECURSIVE oder sortieren Sie die WITH-Ausdrücke um, um Vorwärtsreferenzen zu entfernen." -#: parser/parse_relation.c:1465 +#: parser/parse_relation.c:1486 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "eine Spaltendefinitionsliste ist nur erlaubt bei Funktionen, die »record« zurückgeben" -#: parser/parse_relation.c:1474 +#: parser/parse_relation.c:1495 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "eine Spaltendefinitionsliste ist erforderlich bei Funktionen, die »record« zurückgeben" -#: parser/parse_relation.c:1553 +#: parser/parse_relation.c:1575 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "Funktion »%s« in FROM hat nicht unterstützten Rückgabetyp %s" -#: parser/parse_relation.c:1742 +#: parser/parse_relation.c:1764 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "VALUES-Liste »%s« hat %d Spalten verfügbar, aber %d Spalten wurden angegeben" -#: parser/parse_relation.c:1797 +#: parser/parse_relation.c:1819 #, c-format msgid "joins can have at most %d columns" msgstr "Verbunde können höchstens %d Spalten haben" -#: parser/parse_relation.c:1887 +#: parser/parse_relation.c:1909 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "WITH-Anfrage »%s« hat keine RETURNING-Klausel" -#: parser/parse_relation.c:2685 parser/parse_relation.c:2834 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 +#: parser/parse_relation.c:3011 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "Spalte %d von Relation »%s« existiert nicht" -#: parser/parse_relation.c:3053 +#: parser/parse_relation.c:3230 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Vielleicht wurde beabsichtigt, auf den Tabellenalias »%s« zu verweisen." -#: parser/parse_relation.c:3061 +#: parser/parse_relation.c:3238 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "fehlender Eintrag in FROM-Klausel für Tabelle »%s«" -#: parser/parse_relation.c:3113 +#: parser/parse_relation.c:3290 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« zu verweisen." -#: parser/parse_relation.c:3115 +#: parser/parse_relation.c:3292 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "Es gibt eine Spalte namens »%s« in Tabelle »%s«, aber auf sie kann aus diesem Teil der Anfrage nicht verwiesen werden." -#: parser/parse_relation.c:3132 +#: parser/parse_relation.c:3309 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "Vielleicht wurde beabsichtigt, auf die Spalte »%s.%s« oder die Spalte »%s.%s« zu verweisen." -#: parser/parse_target.c:482 parser/parse_target.c:774 +#: parser/parse_target.c:483 parser/parse_target.c:790 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "kann Systemspalte »%s« keinen Wert zuweisen" -#: parser/parse_target.c:510 +#: parser/parse_target.c:511 #, c-format msgid "cannot set an array element to DEFAULT" msgstr "kann Arrayelement nicht auf DEFAULT setzen" -#: parser/parse_target.c:515 +#: parser/parse_target.c:516 #, c-format msgid "cannot set a subfield to DEFAULT" msgstr "kann Subfeld nicht auf DEFAULT setzen" -#: parser/parse_target.c:584 +#: parser/parse_target.c:585 #, c-format msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "Spalte »%s« hat Typ %s, aber der Ausdruck hat Typ %s" -#: parser/parse_target.c:758 +#: parser/parse_target.c:774 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" msgstr "kann Feld »%s« in Spalte »%s« nicht setzen, weil ihr Typ %s kein zusammengesetzter Typ ist" -#: parser/parse_target.c:767 +#: parser/parse_target.c:783 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgstr "kann Feld »%s« in Spalte »%s« nicht setzen, weil es keine solche Spalte in Datentyp %s gibt" -#: parser/parse_target.c:834 +#: parser/parse_target.c:860 #, c-format msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "Wertzuweisung für »%s« erfordert Typ %s, aber Ausdruck hat Typ %s" -#: parser/parse_target.c:844 +#: parser/parse_target.c:870 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "Subfeld »%s« hat Typ %s, aber der Ausdruck hat Typ %s" -#: parser/parse_target.c:1260 +#: parser/parse_target.c:1289 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "SELECT * ist nicht gültig, wenn keine Tabellen angegeben sind" @@ -14806,7 +15847,7 @@ msgstr "falscher %%TYPE-Verweis (zu viele Namensteile): %s" msgid "type reference %s converted to %s" msgstr "Typverweis %s in %s umgewandelt" -#: parser/parse_type.c:261 parser/parse_type.c:804 utils/cache/typcache.c:243 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format msgid "type \"%s\" is only a shell" msgstr "Typ »%s« ist nur eine Hülle" @@ -14821,312 +15862,407 @@ msgstr "Typmodifikator ist für Typ »%s« nicht erlaubt" msgid "type modifiers must be simple constants or identifiers" msgstr "Typmodifikatoren müssen einfache Konstanten oder Bezeichner sein" -#: parser/parse_type.c:670 parser/parse_type.c:769 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "ungültiger Typname: »%s«" -#: parser/parse_utilcmd.c:263 -#, fuzzy, c-format -#| msgid "cannot create temporary tables in parallel mode" +#: parser/parse_utilcmd.c:272 +#, c-format msgid "cannot create partitioned table as inheritance child" -msgstr "im Parallelmodus können keine temporären Tabellen erzeugt werden" - -#: parser/parse_utilcmd.c:268 -#, fuzzy, c-format -#| msgid "cannot use more than %d columns in an index" -msgid "cannot partition using more than %d columns" -msgstr "Index kann nicht mehr als %d Spalten enthalten" +msgstr "partitionierte Tabelle kann nicht als Vererbungskind erzeugt werden" -#: parser/parse_utilcmd.c:275 +#: parser/parse_utilcmd.c:448 #, c-format -msgid "cannot list partition using more than one column" -msgstr "" +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s erstellt implizit eine Sequenz »%s« für die »serial«-Spalte »%s.%s«" -#: parser/parse_utilcmd.c:413 +#: parser/parse_utilcmd.c:571 #, c-format msgid "array of serial is not implemented" msgstr "Array aus Typ serial ist nicht implementiert" -#: parser/parse_utilcmd.c:461 -#, c-format -msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" -msgstr "%s erstellt implizit eine Sequenz »%s« für die »serial«-Spalte »%s.%s«" - -#: parser/parse_utilcmd.c:554 parser/parse_utilcmd.c:566 +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 #, c-format msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "widersprüchliche NULL/NOT NULL-Deklarationen für Spalte »%s« von Tabelle »%s«" -#: parser/parse_utilcmd.c:578 +#: parser/parse_utilcmd.c:671 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "mehrere Vorgabewerte angegeben für Spalte »%s« von Tabelle »%s«" -#: parser/parse_utilcmd.c:595 parser/parse_utilcmd.c:704 +#: parser/parse_utilcmd.c:688 #, c-format -msgid "primary key constraints are not supported on foreign tables" -msgstr "Primärschlüssel für Fremdtabellen werden nicht unterstützt" +msgid "identity columns are not supported on typed tables" +msgstr "Identitätsspalten in getypten Tabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:601 parser/parse_utilcmd.c:710 -#, fuzzy, c-format -#| msgid "primary key constraints are not supported on foreign tables" -msgid "primary key constraints are not supported on partitioned tables" +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "Identitätsspalten in partitionierten Tabellen werden nicht unterstützt" + +#: parser/parse_utilcmd.c:701 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "mehrere Identitätsangaben für Spalte »%s« von Tabelle »%s«" + +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 +#, c-format +msgid "primary key constraints are not supported on foreign tables" msgstr "Primärschlüssel für Fremdtabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:610 parser/parse_utilcmd.c:720 +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 #, c-format msgid "unique constraints are not supported on foreign tables" msgstr "Unique-Constraints auf Fremdtabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:616 parser/parse_utilcmd.c:726 -#, fuzzy, c-format -#| msgid "unique constraints are not supported on foreign tables" -msgid "unique constraints are not supported on partitioned tables" -msgstr "Unique-Constraints auf Fremdtabellen werden nicht unterstützt" - -#: parser/parse_utilcmd.c:633 parser/parse_utilcmd.c:756 +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "Fremdschlüssel-Constraints auf Fremdtabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:639 parser/parse_utilcmd.c:762 -#, fuzzy, c-format -#| msgid "foreign key constraints are not supported on foreign tables" -msgid "foreign key constraints are not supported on partitioned tables" -msgstr "Fremdschlüssel-Constraints auf Fremdtabellen werden nicht unterstützt" +#: parser/parse_utilcmd.c:778 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "sowohl Vorgabewert als auch Identität angegeben für Spalte »%s« von Tabelle »%s«" -#: parser/parse_utilcmd.c:736 +#: parser/parse_utilcmd.c:843 #, c-format msgid "exclusion constraints are not supported on foreign tables" msgstr "Exclusion-Constraints auf Fremdtabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:742 -#, fuzzy, c-format -#| msgid "exclusion constraints are not supported on foreign tables" +#: parser/parse_utilcmd.c:849 +#, c-format msgid "exclusion constraints are not supported on partitioned tables" -msgstr "Exclusion-Constraints auf Fremdtabellen werden nicht unterstützt" +msgstr "Exclusion-Constraints auf partitionierten Tabellen werden nicht unterstützt" -#: parser/parse_utilcmd.c:812 +#: parser/parse_utilcmd.c:913 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKE wird für das Erzeugen von Fremdtabellen nicht unterstützt" -#: parser/parse_utilcmd.c:1344 parser/parse_utilcmd.c:1420 +#: parser/parse_utilcmd.c:1516 parser/parse_utilcmd.c:1623 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "Index »%s« enthält einen Verweis auf die ganze Zeile der Tabelle." -#: parser/parse_utilcmd.c:1689 +#: parser/parse_utilcmd.c:1973 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "bestehender Index kann nicht in CREATE TABLE verwendet werden" -#: parser/parse_utilcmd.c:1709 +#: parser/parse_utilcmd.c:1993 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "Index »%s« gehört bereits zu einem Constraint" -#: parser/parse_utilcmd.c:1717 +#: parser/parse_utilcmd.c:2001 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "Index »%s« gehört nicht zu Tabelle »%s«" -#: parser/parse_utilcmd.c:1724 +#: parser/parse_utilcmd.c:2008 #, c-format msgid "index \"%s\" is not valid" msgstr "Index »%s« ist nicht gültig" -#: parser/parse_utilcmd.c:1730 +#: parser/parse_utilcmd.c:2014 #, c-format msgid "\"%s\" is not a unique index" msgstr "»%s« ist kein Unique Index" -#: parser/parse_utilcmd.c:1731 parser/parse_utilcmd.c:1738 -#: parser/parse_utilcmd.c:1745 parser/parse_utilcmd.c:1815 +#: parser/parse_utilcmd.c:2015 parser/parse_utilcmd.c:2022 +#: parser/parse_utilcmd.c:2029 parser/parse_utilcmd.c:2101 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "Ein Primärschlüssel oder Unique-Constraint kann nicht mit einem solchen Index erzeugt werden." -#: parser/parse_utilcmd.c:1737 +#: parser/parse_utilcmd.c:2021 #, c-format msgid "index \"%s\" contains expressions" msgstr "Index »%s« enthält Ausdrücke" -#: parser/parse_utilcmd.c:1744 +#: parser/parse_utilcmd.c:2028 #, c-format msgid "\"%s\" is a partial index" msgstr "»%s« ist ein partieller Index" -#: parser/parse_utilcmd.c:1756 +#: parser/parse_utilcmd.c:2040 #, c-format msgid "\"%s\" is a deferrable index" msgstr "»%s« ist ein aufschiebbarer Index" -#: parser/parse_utilcmd.c:1757 +#: parser/parse_utilcmd.c:2041 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "Ein nicht aufschiebbarer Constraint kann nicht mit einem aufschiebbaren Index erzeugt werden." -#: parser/parse_utilcmd.c:1814 +#: parser/parse_utilcmd.c:2100 #, c-format msgid "index \"%s\" does not have default sorting behavior" msgstr "Index »%s« hat nicht das Standardsortierverhalten" -#: parser/parse_utilcmd.c:1958 +#: parser/parse_utilcmd.c:2249 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "Spalte »%s« erscheint zweimal im Primärschlüssel-Constraint" -#: parser/parse_utilcmd.c:1964 +#: parser/parse_utilcmd.c:2255 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "Spalte »%s« erscheint zweimal im Unique-Constraint" -#: parser/parse_utilcmd.c:2173 +#: parser/parse_utilcmd.c:2578 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "Indexausdrücke und -prädikate können nur auf die zu indizierende Tabelle verweisen" -#: parser/parse_utilcmd.c:2219 +#: parser/parse_utilcmd.c:2624 #, c-format msgid "rules on materialized views are not supported" msgstr "Regeln für materialisierte Sichten werden nicht unterstützt" -#: parser/parse_utilcmd.c:2280 +#: parser/parse_utilcmd.c:2685 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "WHERE-Bedingung einer Regel kann keine Verweise auf andere Relationen enthalten" -#: parser/parse_utilcmd.c:2352 +#: parser/parse_utilcmd.c:2757 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "Regeln mit WHERE-Bedingungen können als Aktion nur SELECT, INSERT, UPDATE oder DELETE haben" -#: parser/parse_utilcmd.c:2370 parser/parse_utilcmd.c:2469 +#: parser/parse_utilcmd.c:2775 parser/parse_utilcmd.c:2874 #: rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "UNION/INTERSECTION/EXCEPT mit Bedingung sind nicht implementiert" -#: parser/parse_utilcmd.c:2388 +#: parser/parse_utilcmd.c:2793 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "ON-SELECT-Regel kann nicht OLD verwenden" -#: parser/parse_utilcmd.c:2392 +#: parser/parse_utilcmd.c:2797 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "ON-SELECT-Regel kann nicht NEW verwenden" -#: parser/parse_utilcmd.c:2401 +#: parser/parse_utilcmd.c:2806 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "ON-INSERT-Regel kann nicht OLD verwenden" -#: parser/parse_utilcmd.c:2407 +#: parser/parse_utilcmd.c:2812 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "ON-DELETE-Regel kann nicht NEW verwenden" -#: parser/parse_utilcmd.c:2435 +#: parser/parse_utilcmd.c:2840 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "in WITH-Anfrage kann nicht auf OLD verweisen werden" -#: parser/parse_utilcmd.c:2442 +#: parser/parse_utilcmd.c:2847 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "in WITH-Anfrage kann nicht auf NEW verwiesen werden" -#: parser/parse_utilcmd.c:2766 +#: parser/parse_utilcmd.c:3285 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "falsch platzierte DEFERRABLE-Klausel" -#: parser/parse_utilcmd.c:2771 parser/parse_utilcmd.c:2786 +#: parser/parse_utilcmd.c:3290 parser/parse_utilcmd.c:3305 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "mehrere DEFERRABLE/NOT DEFERRABLE-Klauseln sind nicht erlaubt" -#: parser/parse_utilcmd.c:2781 +#: parser/parse_utilcmd.c:3300 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "falsch platzierte NOT DEFERRABLE-Klausel" -#: parser/parse_utilcmd.c:2802 +#: parser/parse_utilcmd.c:3321 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "falsch platzierte INITIALLY DEFERRED-Klausel" -#: parser/parse_utilcmd.c:2807 parser/parse_utilcmd.c:2833 +#: parser/parse_utilcmd.c:3326 parser/parse_utilcmd.c:3352 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "mehrere INITIALLY IMMEDIATE/DEFERRED-Klauseln sind nicht erlaubt" -#: parser/parse_utilcmd.c:2828 +#: parser/parse_utilcmd.c:3347 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "falsch platzierte INITIALLY IMMEDIATE-Klausel" -#: parser/parse_utilcmd.c:3019 +#: parser/parse_utilcmd.c:3538 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE gibt ein Schema an (%s) welches nicht gleich dem zu erzeugenden Schema ist (%s)" -#: parser/parse_utilcmd.c:3085 +#: parser/parse_utilcmd.c:3572 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "Tabelle »%s« ist nicht partitioniert" + +#: parser/parse_utilcmd.c:3579 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "Index »%s« ist nicht partitioniert" + +#: parser/parse_utilcmd.c:3613 #, fuzzy, c-format -#| msgid "invalid format specification for an interval value" -msgid "invalid bound specification for a list partition" -msgstr "ungültige Formatangabe für Intervall-Wert" +#| msgid "Partitioned tables cannot have ROW triggers." +msgid "a hash-partitioned table may not have a default partition" +msgstr "Partitionierte Tabellen können keine ROW-Trigger haben." -#: parser/parse_utilcmd.c:3108 parser/parse_utilcmd.c:3208 -#: parser/parse_utilcmd.c:3235 +#: parser/parse_utilcmd.c:3630 #, fuzzy, c-format -#| msgid "cannot alter type of column \"%s\" twice" -msgid "specified value cannot be cast to type \"%s\" of column \"%s\"" -msgstr "Typ der Spalte »%s« kann nicht zweimal geändert werden" +#| msgid "invalid bound specification for a list partition" +msgid "invalid bound specification for a hash partition" +msgstr "ungültige Begrenzungsangabe für eine Listenpartition" -#: parser/parse_utilcmd.c:3147 +#: parser/parse_utilcmd.c:3636 partitioning/partbounds.c:2127 #, fuzzy, c-format -#| msgid "invalid format specification for an interval value" -msgid "invalid bound specification for a range partition" -msgstr "ungültige Formatangabe für Intervall-Wert" +#| msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgid "modulus for hash partition must be a positive integer" +msgstr "%s: Dauer muss eine positive ganze Zahl sein (Dauer ist »%d«)\n" -#: parser/parse_utilcmd.c:3155 +#: parser/parse_utilcmd.c:3643 partitioning/partbounds.c:2135 #, fuzzy, c-format -#| msgid "must specify at least one column" +#| msgid "precision for type float must be less than 54 bits" +msgid "remainder for hash partition must be less than modulus" +msgstr "Präzision von Typ float muss weniger als 54 Bits sein" + +#: parser/parse_utilcmd.c:3655 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "ungültige Begrenzungsangabe für eine Listenpartition" + +#: parser/parse_utilcmd.c:3711 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "ungültige Begrenzungsangabe für eine Bereichspartition" + +#: parser/parse_utilcmd.c:3717 +#, c-format msgid "FROM must specify exactly one value per partitioning column" -msgstr "mindestens eine Spalte muss angegeben werden" +msgstr "FROM muss genau einen Wert pro Partitionierungsspalte angeben" -#: parser/parse_utilcmd.c:3159 -#, fuzzy, c-format -#| msgid "must specify at least one column" +#: parser/parse_utilcmd.c:3721 +#, c-format msgid "TO must specify exactly one value per partitioning column" -msgstr "mindestens eine Spalte muss angegeben werden" +msgstr "TO muss genau einen Wert pro Partitionierungsspalte angeben" -#: parser/parse_utilcmd.c:3197 parser/parse_utilcmd.c:3224 -#, fuzzy, c-format -#| msgid "cannot specify NULL in BINARY mode" +#: parser/parse_utilcmd.c:3768 parser/parse_utilcmd.c:3782 +#, c-format msgid "cannot specify NULL in range bound" -msgstr "NULL kann nicht im BINARY-Modus angegeben werden" +msgstr "NULL kann nicht in der Bereichsgrenze angegeben werden" + +#: parser/parse_utilcmd.c:3829 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "jede Begrenzung, die auf MAXVALUE folgt, muss auch MAXVALUE sein" + +#: parser/parse_utilcmd.c:3836 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "jede Begrenzung, die auf MINVALUE folgt, muss auch MINVALUE sein" + +#: parser/parse_utilcmd.c:3867 parser/parse_utilcmd.c:3879 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "angegebener Wert kann nicht in Typ %s für Spalte »%s« umgewandelt werden" + +#: parser/parse_utilcmd.c:3881 +#, c-format +msgid "The cast requires a non-immutable conversion." +msgstr "Die Typumwandlung ist nicht »immutable«." + +#: parser/parse_utilcmd.c:3882 +#, c-format +msgid "Try putting the literal value in single quotes." +msgstr "Versuchen Sie, den Wert in einfachen Ausführungszeichen zu schreiben." #: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "Bezeichner »%s« wird auf »%s« gekürzt" -#: port/pg_shmem.c:175 port/sysv_shmem.c:175 +#: partitioning/partbounds.c:331 +#, fuzzy, c-format +#| msgid "partition \"%s\" would overlap partition \"%s\"" +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" + +#: partitioning/partbounds.c:390 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "" + +#: partitioning/partbounds.c:486 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "leere Bereichsgrenze angegeben für Partition »%s«" + +#: partitioning/partbounds.c:488 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Angegebene Untergrenze %s ist größer als oder gleich der Obergrenze %s." + +#: partitioning/partbounds.c:585 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "Partition »%s« würde sich mit Partition »%s« überlappen" + +#: partitioning/partbounds.c:685 +#, fuzzy, c-format +#| msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "Relation »%s« ist keine Partition von Relation »%s«" + +#: partitioning/partbounds.c:724 +#, fuzzy, c-format +#| msgid "partition constraint is violated by some row" +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "Partitions-Constraint wird von irgendeiner Zeile verletzt" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "" + +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "»%s« ist keine Hash-partitionierte Tabelle" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, fuzzy, c-format +#| msgid "number of columns does not match number of values" +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "Anzahl der Spalten stimmt nicht mit der Anzahl der Werte überein" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "" + +#: port/pg_shmem.c:196 port/sysv_shmem.c:196 #, c-format msgid "could not create shared memory segment: %m" msgstr "konnte Shared-Memory-Segment nicht erzeugen: %m" -#: port/pg_shmem.c:176 port/sysv_shmem.c:176 +#: port/pg_shmem.c:197 port/sysv_shmem.c:197 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "Fehlgeschlagener Systemaufruf war shmget(Key=%lu, Größe=%zu, 0%o)." -#: port/pg_shmem.c:180 port/sysv_shmem.c:180 +#: port/pg_shmem.c:201 port/sysv_shmem.c:201 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" @@ -15135,7 +16271,7 @@ msgstr "" "Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den Kernel-Parameter SHMMAX überschreitet, oder eventuell, dass es kleiner als der Kernel-Parameter SHMMIN ist.\n" "Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." -#: port/pg_shmem.c:187 port/sysv_shmem.c:187 +#: port/pg_shmem.c:208 port/sysv_shmem.c:208 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" @@ -15144,7 +16280,7 @@ msgstr "" "Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den Kernel-Parameter SHMALL überschreitet. Sie müssen eventuell den Kernel mit einem größeren SHMALL neu konfigurieren.\n" "Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." -#: port/pg_shmem.c:193 port/sysv_shmem.c:193 +#: port/pg_shmem.c:214 port/sysv_shmem.c:214 #, c-format msgid "" "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" @@ -15153,24 +16289,24 @@ msgstr "" "Dieser Fehler bedeutet *nicht*, dass kein Platz mehr auf der Festplatte ist. Er tritt auf, wenn entweder alle verfügbaren Shared-Memory-IDs aufgebraucht sind, dann müssen den Kernelparameter SHMMNI erhöhen, oder weil die Systemhöchstgrenze für Shared Memory insgesamt erreicht wurde.\n" "Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." -#: port/pg_shmem.c:483 port/sysv_shmem.c:483 +#: port/pg_shmem.c:505 port/sysv_shmem.c:505 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "konnte anonymes Shared Memory nicht mappen: %m" -#: port/pg_shmem.c:485 port/sysv_shmem.c:485 +#: port/pg_shmem.c:507 port/sysv_shmem.c:507 #, c-format msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." msgstr "" "Dieser Fehler bedeutet gewöhnlich, dass das von PostgreSQL angeforderte Shared-Memory-Segment den verfügbaren Speicher, Swap-Space oder Huge Pages überschreitet. Um die benötigte Shared-Memory-Größe zu reduzieren (aktuell %zu Bytes), reduzieren Sie den Shared-Memory-Verbrauch von PostgreSQL, beispielsweise indem Sie »shared_buffers« oder »max_connections« reduzieren.\n" "Die PostgreSQL-Dokumentation enthält weitere Informationen über die Konfiguration von Shared Memory." -#: port/pg_shmem.c:551 port/sysv_shmem.c:551 port/win32_shmem.c:134 +#: port/pg_shmem.c:573 port/sysv_shmem.c:573 #, c-format msgid "huge pages not supported on this platform" msgstr "Huge Pages werden auf dieser Plattform nicht unterstützt" -#: port/pg_shmem.c:646 port/sysv_shmem.c:646 +#: port/pg_shmem.c:668 port/sysv_shmem.c:668 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "konnte »stat« für Datenverzeichnis »%s« nicht ausführen: %m" @@ -15259,524 +16395,514 @@ msgstr "konnte Semaphore nicht entsperren: Fehlercode %lu" msgid "could not try-lock semaphore: error code %lu" msgstr "konnte Semaphore nicht versuchsweise sperren: Fehlercode %lu" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:122 port/win32_shmem.c:130 port/win32_shmem.c:142 +#: port/win32_shmem.c:157 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: error code %lu" +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "konnte Shared-Memory-Segment nicht erzeugen: Fehlercode %lu" + +#: port/win32_shmem.c:123 port/win32_shmem.c:131 port/win32_shmem.c:143 +#: port/win32_shmem.c:158 +#, c-format +msgid "Failed system call was %s." +msgstr "Fehlgeschlagener Systemaufruf war %s." + +#: port/win32_shmem.c:153 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not enable Lock Pages in Memory user right" +msgstr "konnte Shared-Memory-Segment nicht erzeugen: %m" + +#: port/win32_shmem.c:154 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "" + +#: port/win32_shmem.c:210 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support tablespaces.\n" +msgid "the processor does not support large pages" +msgstr "Der Server (Version %s) unterstützt keine Tablespaces.\n" + +#: port/win32_shmem.c:212 port/win32_shmem.c:217 +#, fuzzy, c-format +#| msgid "disabling triggers for %s\n" +msgid "disabling huge pages" +msgstr "schalte Trigger für %s aus\n" + +#: port/win32_shmem.c:279 port/win32_shmem.c:315 port/win32_shmem.c:333 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "konnte Shared-Memory-Segment nicht erzeugen: Fehlercode %lu" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:280 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "Fehlgeschlagener Systemaufruf war CreateFileMapping(Größe=%zu, Name=%s)." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:305 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "bereits bestehender Shared-Memory-Block wird noch benutzt" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:306 #, c-format msgid "Check if there are any old server processes still running, and terminate them." msgstr "Prüfen Sie, ob irgendwelche alten Serverprozesse noch laufen und beenden Sie diese." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:316 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "Fehlgeschlagener Systemaufruf war DuplicateHandle." -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:334 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "Fehlgeschlagener Systemaufruf war MapViewOfFileEx." -#: postmaster/autovacuum.c:380 +#: postmaster/autovacuum.c:406 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "konnte Autovacuum-Launcher-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/autovacuum.c:416 +#: postmaster/autovacuum.c:442 #, c-format msgid "autovacuum launcher started" msgstr "Autovacuum-Launcher startet" -#: postmaster/autovacuum.c:780 +#: postmaster/autovacuum.c:832 #, c-format msgid "autovacuum launcher shutting down" msgstr "Autovacuum-Launcher fährt herunter" -#: postmaster/autovacuum.c:1442 +#: postmaster/autovacuum.c:1494 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "konnte Autovacuum-Worker-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/autovacuum.c:1640 +#: postmaster/autovacuum.c:1700 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "Autovacuum: bearbeite Datenbank »%s«" -#: postmaster/autovacuum.c:2214 -#, fuzzy, c-format -#| msgid "autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"" +#: postmaster/autovacuum.c:2269 +#, c-format msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" -msgstr "Autovacuum: lösche verwaiste temporäre Tabelle »%s.%s« in Datenbank »%s«" +msgstr "Autovacuum: lösche verwaiste temporäre Tabelle »%s.%s.%s«" -#: postmaster/autovacuum.c:2420 +#: postmaster/autovacuum.c:2498 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "automatisches Vacuum der Tabelle »%s.%s.%s«" -#: postmaster/autovacuum.c:2423 +#: postmaster/autovacuum.c:2501 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "automatisches Analysieren der Tabelle »%s.%s.%s«" -#: postmaster/autovacuum.c:2972 +#: postmaster/autovacuum.c:2694 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "verarbeite Arbeitseintrag für Relation »%s.%s.%s«" + +#: postmaster/autovacuum.c:3273 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "Autovacuum wegen Fehlkonfiguration nicht gestartet" -#: postmaster/autovacuum.c:2973 +#: postmaster/autovacuum.c:3274 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Schalten Sie die Option »track_counts« ein." -#: postmaster/bgworker.c:375 postmaster/bgworker.c:814 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "registriere Background-Worker »%s«" -#: postmaster/bgworker.c:407 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "deregistriere Background-Worker »%s«" -#: postmaster/bgworker.c:551 +#: postmaster/bgworker.c:592 #, c-format msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" msgstr "Background-Worker »%s«: muss mit Shared Memory verbinden, um eine Datenbankverbindung anzufordern" -#: postmaster/bgworker.c:560 +#: postmaster/bgworker.c:601 #, c-format msgid "background worker \"%s\": cannot request database access if starting at postmaster start" msgstr "Background-Worker »%s«: kann kein Datenbankzugriff anfordern, wenn er nach Postmaster-Start gestartet hat" -#: postmaster/bgworker.c:574 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" msgstr "Background-Worker »%s«: ungültiges Neustart-Intervall" -#: postmaster/bgworker.c:619 +#: postmaster/bgworker.c:630 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "Background-Worker »%s«: parallele Arbeitsprozesse dürfen nicht für Neustart konfiguriert sein" + +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "Background-Worker »%s« wird abgebrochen aufgrund von Anweisung des Administrators" -#: postmaster/bgworker.c:830 +#: postmaster/bgworker.c:863 #, c-format msgid "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "Background-Worker »%s«: muss in shared_preload_libraries registriert sein" -#: postmaster/bgworker.c:842 +#: postmaster/bgworker.c:875 #, c-format msgid "background worker \"%s\": only dynamic background workers can request notification" msgstr "Background-Worker »%s«: nur dynamische Background-Worker können Benachrichtigung verlangen" -#: postmaster/bgworker.c:857 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" msgstr "zu viele Background-Worker" -#: postmaster/bgworker.c:858 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "Up to %d background workers can be registered with the current settings." msgstr[0] "Mit den aktuellen Einstellungen können bis zu %d Background-Worker registriert werden." msgstr[1] "Mit den aktuellen Einstellungen können bis zu %d Background-Worker registriert werden." -#: postmaster/bgworker.c:862 +#: postmaster/bgworker.c:895 #, c-format msgid "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "Erhöhen Sie eventuell den Konfigurationsparameter »max_worker_processes«." -#: postmaster/checkpointer.c:465 +#: postmaster/checkpointer.c:464 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" msgstr[0] "Checkpoints passieren zu oft (alle %d Sekunde)" msgstr[1] "Checkpoints passieren zu oft (alle %d Sekunden)" -#: postmaster/checkpointer.c:469 +#: postmaster/checkpointer.c:468 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "Erhöhen Sie eventuell den Konfigurationsparameter »max_wal_size«." -#: postmaster/checkpointer.c:629 -#, c-format -msgid "transaction log switch forced (archive_timeout=%d)" -msgstr "Umschalten des Transaktionslogs erzwungen (archive_timeout=%d)" - -#: postmaster/checkpointer.c:1088 +#: postmaster/checkpointer.c:1082 #, c-format msgid "checkpoint request failed" msgstr "Checkpoint-Anforderung fehlgeschlagen" -#: postmaster/checkpointer.c:1089 +#: postmaster/checkpointer.c:1083 #, c-format msgid "Consult recent messages in the server log for details." msgstr "Einzelheiten finden Sie in den letzten Meldungen im Serverlog." -#: postmaster/checkpointer.c:1284 +#: postmaster/checkpointer.c:1278 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "fsync-Anfrageschlange von %d Einträgen auf %d Einträge zusammengefasst" -#: postmaster/pgarch.c:149 +#: postmaster/pgarch.c:148 #, c-format msgid "could not fork archiver: %m" msgstr "konnte Archivierer nicht starten (fork-Fehler): %m" -#: postmaster/pgarch.c:457 +#: postmaster/pgarch.c:456 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "archive_mode ist an, aber archive_command ist nicht gesetzt" -#: postmaster/pgarch.c:485 +#: postmaster/pgarch.c:484 #, c-format -msgid "archiving transaction log file \"%s\" failed too many times, will try again later" -msgstr "Archivieren der Transaktionslogdatei »%s« schlug zu oft fehl, wird später erneut versucht" +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "Archivieren der Write-Ahead-Log-Datei »%s« schlug zu oft fehl, wird später erneut versucht" -#: postmaster/pgarch.c:588 +#: postmaster/pgarch.c:585 #, c-format msgid "archive command failed with exit code %d" msgstr "Archivbefehl ist fehlgeschlagen mit Statuscode %d" -#: postmaster/pgarch.c:590 postmaster/pgarch.c:600 postmaster/pgarch.c:607 -#: postmaster/pgarch.c:613 postmaster/pgarch.c:622 +#: postmaster/pgarch.c:587 postmaster/pgarch.c:597 postmaster/pgarch.c:604 +#: postmaster/pgarch.c:610 postmaster/pgarch.c:619 #, c-format msgid "The failed archive command was: %s" msgstr "Der fehlgeschlagene Archivbefehl war: %s" -#: postmaster/pgarch.c:597 +#: postmaster/pgarch.c:594 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "Archivbefehl wurde durch Ausnahme 0x%X beendet" -#: postmaster/pgarch.c:599 postmaster/postmaster.c:3527 +#: postmaster/pgarch.c:596 postmaster/postmaster.c:3567 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "Sehen Sie die Beschreibung des Hexadezimalwerts in der C-Include-Datei »ntstatus.h« nach." -#: postmaster/pgarch.c:604 +#: postmaster/pgarch.c:601 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "Archivbefehl wurde von Signal %d beendet: %s" -#: postmaster/pgarch.c:611 +#: postmaster/pgarch.c:608 #, c-format msgid "archive command was terminated by signal %d" msgstr "Archivbefehl wurde von Signal %d beendet" -#: postmaster/pgarch.c:620 +#: postmaster/pgarch.c:617 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "Archivbefehl hat mit unbekanntem Status %d beendet" -#: postmaster/pgarch.c:632 -#, c-format -msgid "archived transaction log file \"%s\"" -msgstr "archivierte Transaktionslogdatei »%s«" - -#: postmaster/pgarch.c:681 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "konnte Archivstatusverzeichnis »%s« nicht öffnen: %m" - -#: postmaster/pgstat.c:360 +#: postmaster/pgstat.c:395 #, c-format msgid "could not resolve \"localhost\": %s" msgstr "konnte »localhost« nicht auflösen: %s" -#: postmaster/pgstat.c:383 +#: postmaster/pgstat.c:418 #, c-format msgid "trying another address for the statistics collector" msgstr "andere Adresse für Statistiksammelprozess wird versucht" -#: postmaster/pgstat.c:392 +#: postmaster/pgstat.c:427 #, c-format msgid "could not create socket for statistics collector: %m" msgstr "konnte Socket für Statistiksammelprozess nicht erzeugen: %m" -#: postmaster/pgstat.c:404 +#: postmaster/pgstat.c:439 #, c-format msgid "could not bind socket for statistics collector: %m" msgstr "konnte Socket für Statistiksammelprozess nicht binden: %m" -#: postmaster/pgstat.c:415 +#: postmaster/pgstat.c:450 #, c-format msgid "could not get address of socket for statistics collector: %m" msgstr "konnte Adresse für Socket für Statistiksammelprozess nicht ermitteln: %m" -#: postmaster/pgstat.c:431 +#: postmaster/pgstat.c:466 #, c-format msgid "could not connect socket for statistics collector: %m" msgstr "konnte nicht mit Socket für Statistiksammelprozess verbinden: %m" -#: postmaster/pgstat.c:452 +#: postmaster/pgstat.c:487 #, c-format msgid "could not send test message on socket for statistics collector: %m" msgstr "konnte Testnachricht auf Socket für Statistiksammelprozess nicht senden: %m" -#: postmaster/pgstat.c:478 +#: postmaster/pgstat.c:513 #, c-format msgid "select() failed in statistics collector: %m" msgstr "select() im Statistiksammelprozess fehlgeschlagen: %m" -#: postmaster/pgstat.c:493 +#: postmaster/pgstat.c:528 #, c-format msgid "test message did not get through on socket for statistics collector" msgstr "Testnachricht auf Socket für Statistiksammelprozess kam nicht durch" -#: postmaster/pgstat.c:508 +#: postmaster/pgstat.c:543 #, c-format msgid "could not receive test message on socket for statistics collector: %m" msgstr "konnte Testnachricht auf Socket für Statistiksammelprozess nicht empfangen: %m" -#: postmaster/pgstat.c:518 +#: postmaster/pgstat.c:553 #, c-format msgid "incorrect test message transmission on socket for statistics collector" msgstr "fehlerhafte Übertragung der Testnachricht auf Socket für Statistiksammelprozess" -#: postmaster/pgstat.c:541 +#: postmaster/pgstat.c:576 #, c-format msgid "could not set statistics collector socket to nonblocking mode: %m" msgstr "konnte Socket von Statistiksammelprozess nicht auf nicht blockierenden Modus setzen: %m" -#: postmaster/pgstat.c:551 +#: postmaster/pgstat.c:615 #, c-format msgid "disabling statistics collector for lack of working socket" msgstr "Statistiksammelprozess abgeschaltet wegen nicht funkionierender Socket" -#: postmaster/pgstat.c:698 +#: postmaster/pgstat.c:762 #, c-format msgid "could not fork statistics collector: %m" msgstr "konnte Statistiksammelprozess nicht starten (fork-Fehler): %m" -#: postmaster/pgstat.c:1266 +#: postmaster/pgstat.c:1342 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "unbekanntes Reset-Ziel: »%s«" -#: postmaster/pgstat.c:1267 +#: postmaster/pgstat.c:1343 #, c-format msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "Das Reset-Ziel muss »archiver« oder »bgwriter« sein." -#: postmaster/pgstat.c:3816 +#: postmaster/pgstat.c:4362 #, c-format msgid "could not read statistics message: %m" msgstr "konnte Statistiknachricht nicht lesen: %m" -#: postmaster/pgstat.c:4148 postmaster/pgstat.c:4305 +#: postmaster/pgstat.c:4694 postmaster/pgstat.c:4851 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht öffnen: %m" -#: postmaster/pgstat.c:4215 postmaster/pgstat.c:4350 +#: postmaster/pgstat.c:4761 postmaster/pgstat.c:4896 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht schreiben: %m" -#: postmaster/pgstat.c:4224 postmaster/pgstat.c:4359 +#: postmaster/pgstat.c:4770 postmaster/pgstat.c:4905 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht schließen: %m" -#: postmaster/pgstat.c:4232 postmaster/pgstat.c:4367 +#: postmaster/pgstat.c:4778 postmaster/pgstat.c:4913 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "konnte temporäre Statistikdatei »%s« nicht in »%s« umbenennen: %m" -#: postmaster/pgstat.c:4456 postmaster/pgstat.c:4641 postmaster/pgstat.c:4794 +#: postmaster/pgstat.c:5002 postmaster/pgstat.c:5208 postmaster/pgstat.c:5361 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "konnte Statistikdatei »%s« nicht öffnen: %m" -#: postmaster/pgstat.c:4468 postmaster/pgstat.c:4478 postmaster/pgstat.c:4488 -#: postmaster/pgstat.c:4509 postmaster/pgstat.c:4524 postmaster/pgstat.c:4578 -#: postmaster/pgstat.c:4653 postmaster/pgstat.c:4673 postmaster/pgstat.c:4691 -#: postmaster/pgstat.c:4707 postmaster/pgstat.c:4725 postmaster/pgstat.c:4741 -#: postmaster/pgstat.c:4806 postmaster/pgstat.c:4818 postmaster/pgstat.c:4830 -#: postmaster/pgstat.c:4855 postmaster/pgstat.c:4877 +#: postmaster/pgstat.c:5014 postmaster/pgstat.c:5024 postmaster/pgstat.c:5045 +#: postmaster/pgstat.c:5067 postmaster/pgstat.c:5082 postmaster/pgstat.c:5145 +#: postmaster/pgstat.c:5220 postmaster/pgstat.c:5240 postmaster/pgstat.c:5258 +#: postmaster/pgstat.c:5274 postmaster/pgstat.c:5292 postmaster/pgstat.c:5308 +#: postmaster/pgstat.c:5373 postmaster/pgstat.c:5385 postmaster/pgstat.c:5397 +#: postmaster/pgstat.c:5422 postmaster/pgstat.c:5444 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "verfälschte Statistikdatei »%s«" -#: postmaster/pgstat.c:5006 +#: postmaster/pgstat.c:5573 #, c-format msgid "using stale statistics instead of current ones because stats collector is not responding" msgstr "verwende veraltete Statistiken anstatt aktueller, weil der Statistiksammelprozess nicht antwortet" -#: postmaster/pgstat.c:5333 +#: postmaster/pgstat.c:5900 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "Datenbank-Hash-Tabelle beim Aufräumen verfälscht --- Abbruch" -#: postmaster/postmaster.c:692 +#: postmaster/postmaster.c:717 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s: ungültiges Argument für Option -f: »%s«\n" -#: postmaster/postmaster.c:778 +#: postmaster/postmaster.c:803 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s: ungültiges Argument für Option -t: »%s«\n" -#: postmaster/postmaster.c:829 +#: postmaster/postmaster.c:854 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s: ungültiges Argument: »%s«\n" -#: postmaster/postmaster.c:868 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s: superuser_reserved_connections muss kleiner als max_connections sein\n" - -#: postmaster/postmaster.c:873 +#: postmaster/postmaster.c:896 #, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_senders muss kleiner als max_connections sein\n" +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) muss kleiner als max_connections (%d) sein\n" -#: postmaster/postmaster.c:878 +#: postmaster/postmaster.c:903 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "WAL-Archivierung kann nicht eingeschaltet werden, wenn wal_level »minimal« ist" -#: postmaster/postmaster.c:881 +#: postmaster/postmaster.c:906 #, c-format msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" msgstr "WAL-Streaming (max_wal_senders > 0) benötigt wal_level »replica« oder »logical«" -#: postmaster/postmaster.c:889 +#: postmaster/postmaster.c:914 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s: ungültige datetoken-Tabellen, bitte reparieren\n" -#: postmaster/postmaster.c:992 postmaster/postmaster.c:1090 -#: utils/init/miscinit.c:1429 +#: postmaster/postmaster.c:1028 postmaster/postmaster.c:1126 +#: utils/init/miscinit.c:1555 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "ungültige Listensyntax für Parameter »%s«" -#: postmaster/postmaster.c:1023 +#: postmaster/postmaster.c:1059 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "konnte Listen-Socket für »%s« nicht erzeugen" -#: postmaster/postmaster.c:1029 +#: postmaster/postmaster.c:1065 #, c-format msgid "could not create any TCP/IP sockets" msgstr "konnte keine TCP/IP-Sockets erstellen" -#: postmaster/postmaster.c:1112 +#: postmaster/postmaster.c:1148 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "konnte Unix-Domain-Socket in Verzeichnis »%s« nicht erzeugen" -#: postmaster/postmaster.c:1118 +#: postmaster/postmaster.c:1154 #, c-format msgid "could not create any Unix-domain sockets" msgstr "konnte keine Unix-Domain-Sockets erzeugen" -#: postmaster/postmaster.c:1130 +#: postmaster/postmaster.c:1166 #, c-format msgid "no socket created for listening" msgstr "keine Listen-Socket erzeugt" -#: postmaster/postmaster.c:1170 +#: postmaster/postmaster.c:1206 #, c-format msgid "could not create I/O completion port for child queue" msgstr "konnte Ein-/Ausgabe-Completion-Port für Child-Queue nicht erzeugen" -#: postmaster/postmaster.c:1199 +#: postmaster/postmaster.c:1235 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: konnte Rechte der externen PID-Datei »%s« nicht ändern: %s\n" -#: postmaster/postmaster.c:1203 +#: postmaster/postmaster.c:1239 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: konnte externe PID-Datei »%s« nicht schreiben: %s\n" -#: postmaster/postmaster.c:1260 +#: postmaster/postmaster.c:1296 #, c-format msgid "ending log output to stderr" msgstr "Logausgabe nach stderr endet" -#: postmaster/postmaster.c:1261 +#: postmaster/postmaster.c:1297 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "Die weitere Logausgabe geht an Logziel »%s«." -#: postmaster/postmaster.c:1287 utils/init/postinit.c:213 +#: postmaster/postmaster.c:1323 utils/init/postinit.c:214 #, c-format msgid "could not load pg_hba.conf" msgstr "konnte pg_hba.conf nicht laden" -#: postmaster/postmaster.c:1313 +#: postmaster/postmaster.c:1349 #, c-format msgid "postmaster became multithreaded during startup" msgstr "Postmaster ist während des Starts multithreaded geworden" -#: postmaster/postmaster.c:1314 +#: postmaster/postmaster.c:1350 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "Setzen Sie die Umgebungsvariable LC_ALL auf eine gültige Locale." -#: postmaster/postmaster.c:1413 +#: postmaster/postmaster.c:1455 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s: konnte kein passendes Programm »postgres« finden" -#: postmaster/postmaster.c:1436 utils/misc/tzparser.c:341 +#: postmaster/postmaster.c:1478 utils/misc/tzparser.c:341 #, c-format msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." msgstr "Dies kann auf eine unvollständige PostgreSQL-Installation hindeuten, oder darauf, dass die Datei »%s« von ihrer richtigen Stelle verschoben worden ist." -#: postmaster/postmaster.c:1464 -#, c-format -msgid "data directory \"%s\" does not exist" -msgstr "Datenverzeichnis »%s« existiert nicht" - -#: postmaster/postmaster.c:1469 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" - -#: postmaster/postmaster.c:1477 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "angegebenes Datenverzeichnis »%s« ist kein Verzeichnis" - -#: postmaster/postmaster.c:1493 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "Datenverzeichnis »%s« hat falschen Eigentümer" - -#: postmaster/postmaster.c:1495 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "Der Server muss von dem Benutzer gestartet werden, dem das Datenverzeichnis gehört." - -#: postmaster/postmaster.c:1515 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "Datenverzeichnis »%s« erlaubt Zugriff von Gruppe oder Welt" - -#: postmaster/postmaster.c:1517 -#, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "Rechte sollten u=rwx (0700) sein." - -#: postmaster/postmaster.c:1528 +#: postmaster/postmaster.c:1505 #, c-format msgid "" "%s: could not find the database system\n" @@ -15787,716 +16913,784 @@ msgstr "" "Es wurde im Verzeichnis »%s« erwartet,\n" "aber die Datei »%s« konnte nicht geöffnet werden: %s\n" -#: postmaster/postmaster.c:1705 +#: postmaster/postmaster.c:1682 #, c-format msgid "select() failed in postmaster: %m" msgstr "select() fehlgeschlagen im Postmaster: %m" -#: postmaster/postmaster.c:1856 +#: postmaster/postmaster.c:1837 #, c-format msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "führe sofortiges Herunterfahren durch, weil Sperrdatei im Datenverzeichnis ungültig ist" -#: postmaster/postmaster.c:1934 postmaster/postmaster.c:1965 +#: postmaster/postmaster.c:1915 postmaster/postmaster.c:1946 #, c-format msgid "incomplete startup packet" msgstr "unvollständiges Startpaket" -#: postmaster/postmaster.c:1946 +#: postmaster/postmaster.c:1927 #, c-format msgid "invalid length of startup packet" msgstr "ungültige Länge des Startpakets" -#: postmaster/postmaster.c:2004 +#: postmaster/postmaster.c:1985 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "konnte SSL-Verhandlungsantwort nicht senden: %m" -#: postmaster/postmaster.c:2033 +#: postmaster/postmaster.c:2011 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "nicht unterstütztes Frontend-Protokoll %u.%u: Server unterstützt %u.0 bis %u.%u" -#: postmaster/postmaster.c:2096 utils/misc/guc.c:5726 utils/misc/guc.c:5819 -#: utils/misc/guc.c:7117 utils/misc/guc.c:9870 utils/misc/guc.c:9904 +#: postmaster/postmaster.c:2075 utils/misc/guc.c:6013 utils/misc/guc.c:6106 +#: utils/misc/guc.c:7432 utils/misc/guc.c:10195 utils/misc/guc.c:10229 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "ungültiger Wert für Parameter »%s«: »%s«" -#: postmaster/postmaster.c:2099 +#: postmaster/postmaster.c:2078 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "Gültige Werte sind: »false«, 0, »true«, 1, »database«." -#: postmaster/postmaster.c:2119 +#: postmaster/postmaster.c:2108 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "ungültiges Layout des Startpakets: Abschluss als letztes Byte erwartet" -#: postmaster/postmaster.c:2147 +#: postmaster/postmaster.c:2146 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "kein PostgreSQL-Benutzername im Startpaket angegeben" -#: postmaster/postmaster.c:2206 +#: postmaster/postmaster.c:2205 #, c-format msgid "the database system is starting up" msgstr "das Datenbanksystem startet" -#: postmaster/postmaster.c:2211 +#: postmaster/postmaster.c:2210 #, c-format msgid "the database system is shutting down" msgstr "das Datenbanksystem fährt herunter" -#: postmaster/postmaster.c:2216 +#: postmaster/postmaster.c:2215 #, c-format msgid "the database system is in recovery mode" msgstr "das Datenbanksystem ist im Wiederherstellungsmodus" -#: postmaster/postmaster.c:2221 storage/ipc/procarray.c:290 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:338 +#: postmaster/postmaster.c:2220 storage/ipc/procarray.c:292 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:346 #, c-format msgid "sorry, too many clients already" msgstr "tut mir leid, schon zu viele Verbindungen" -#: postmaster/postmaster.c:2283 +#: postmaster/postmaster.c:2310 #, c-format msgid "wrong key in cancel request for process %d" msgstr "falscher Schlüssel in Stornierungsanfrage für Prozess %d" -#: postmaster/postmaster.c:2291 +#: postmaster/postmaster.c:2318 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "PID %d in Stornierungsanfrage stimmte mit keinem Prozess überein" -#: postmaster/postmaster.c:2502 +#: postmaster/postmaster.c:2529 #, c-format msgid "received SIGHUP, reloading configuration files" msgstr "SIGHUP empfangen, Konfigurationsdateien werden neu geladen" -#: postmaster/postmaster.c:2527 -#, fuzzy, c-format -#| msgid "pg_hba.conf not reloaded" +#: postmaster/postmaster.c:2554 +#, c-format msgid "pg_hba.conf was not reloaded" -msgstr "pg_hba.conf nicht neu geladen" +msgstr "pg_hba.conf wurde nicht neu geladen" -#: postmaster/postmaster.c:2531 -#, fuzzy, c-format -#| msgid "pg_ident.conf not reloaded" +#: postmaster/postmaster.c:2558 +#, c-format msgid "pg_ident.conf was not reloaded" -msgstr "pg_ident.conf nicht neu geladen" +msgstr "pg_ident.conf wurde nicht neu geladen" -#: postmaster/postmaster.c:2541 -#, fuzzy, c-format -#| msgid "text search configuration parameter \"%s\" not recognized" +#: postmaster/postmaster.c:2568 +#, c-format msgid "SSL configuration was not reloaded" -msgstr "Textsuchekonfigurationsparameter »%s« nicht erkannt" +msgstr "SSL-Konfiguration wurde nicht neu geladen" -#: postmaster/postmaster.c:2589 +#: postmaster/postmaster.c:2616 #, c-format msgid "received smart shutdown request" msgstr "intelligentes Herunterfahren verlangt" -#: postmaster/postmaster.c:2644 +#: postmaster/postmaster.c:2674 #, c-format msgid "received fast shutdown request" msgstr "schnelles Herunterfahren verlangt" -#: postmaster/postmaster.c:2674 +#: postmaster/postmaster.c:2707 #, c-format msgid "aborting any active transactions" msgstr "etwaige aktive Transaktionen werden abgebrochen" -#: postmaster/postmaster.c:2708 +#: postmaster/postmaster.c:2741 #, c-format msgid "received immediate shutdown request" msgstr "sofortiges Herunterfahren verlangt" -#: postmaster/postmaster.c:2772 +#: postmaster/postmaster.c:2808 #, c-format msgid "shutdown at recovery target" msgstr "Herunterfahren beim Wiederherstellungsziel" -#: postmaster/postmaster.c:2788 postmaster/postmaster.c:2811 +#: postmaster/postmaster.c:2824 postmaster/postmaster.c:2847 msgid "startup process" msgstr "Startprozess" -#: postmaster/postmaster.c:2791 +#: postmaster/postmaster.c:2827 #, c-format msgid "aborting startup due to startup process failure" msgstr "Serverstart abgebrochen wegen Startprozessfehler" -#: postmaster/postmaster.c:2852 +#: postmaster/postmaster.c:2888 #, c-format msgid "database system is ready to accept connections" msgstr "Datenbanksystem ist bereit, um Verbindungen anzunehmen" -#: postmaster/postmaster.c:2871 +#: postmaster/postmaster.c:2909 msgid "background writer process" msgstr "Background-Writer-Prozess" -#: postmaster/postmaster.c:2925 +#: postmaster/postmaster.c:2963 msgid "checkpointer process" msgstr "Checkpointer-Prozess" -#: postmaster/postmaster.c:2941 +#: postmaster/postmaster.c:2979 msgid "WAL writer process" msgstr "WAL-Schreibprozess" -#: postmaster/postmaster.c:2955 +#: postmaster/postmaster.c:2994 msgid "WAL receiver process" msgstr "WAL-Receiver-Prozess" -#: postmaster/postmaster.c:2970 +#: postmaster/postmaster.c:3009 msgid "autovacuum launcher process" msgstr "Autovacuum-Launcher-Prozess" -#: postmaster/postmaster.c:2985 +#: postmaster/postmaster.c:3024 msgid "archiver process" msgstr "Archivierprozess" -#: postmaster/postmaster.c:3001 +#: postmaster/postmaster.c:3040 msgid "statistics collector process" msgstr "Statistiksammelprozess" -#: postmaster/postmaster.c:3015 +#: postmaster/postmaster.c:3054 msgid "system logger process" msgstr "Systemlogger-Prozess" -#: postmaster/postmaster.c:3077 -msgid "worker process" -msgstr "Worker-Prozess" +#: postmaster/postmaster.c:3116 +#, c-format +msgid "background worker \"%s\"" +msgstr "Background-Worker »%s«" -#: postmaster/postmaster.c:3160 postmaster/postmaster.c:3180 -#: postmaster/postmaster.c:3187 postmaster/postmaster.c:3205 +#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 +#: postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 msgid "server process" msgstr "Serverprozess" -#: postmaster/postmaster.c:3259 +#: postmaster/postmaster.c:3299 #, c-format msgid "terminating any other active server processes" msgstr "aktive Serverprozesse werden abgebrochen" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3515 +#: postmaster/postmaster.c:3555 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) beendete mit Status %d" -#: postmaster/postmaster.c:3517 postmaster/postmaster.c:3528 -#: postmaster/postmaster.c:3539 postmaster/postmaster.c:3548 -#: postmaster/postmaster.c:3558 +#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 +#: postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 +#: postmaster/postmaster.c:3598 #, c-format msgid "Failed process was running: %s" msgstr "Der fehlgeschlagene Prozess führte aus: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3525 +#: postmaster/postmaster.c:3565 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) wurde durch Ausnahme 0x%X beendet" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3535 +#: postmaster/postmaster.c:3575 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) wurde von Signal %d beendet: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3546 +#: postmaster/postmaster.c:3586 #, c-format msgid "%s (PID %d) was terminated by signal %d" msgstr "%s (PID %d) wurde von Signal %d beendet" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3556 +#: postmaster/postmaster.c:3596 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" msgstr "%s (PID %d) beendete mit unbekanntem Status %d" -#: postmaster/postmaster.c:3743 +#: postmaster/postmaster.c:3783 #, c-format msgid "abnormal database system shutdown" msgstr "abnormales Herunterfahren des Datenbanksystems" -#: postmaster/postmaster.c:3783 +#: postmaster/postmaster.c:3823 #, c-format msgid "all server processes terminated; reinitializing" msgstr "alle Serverprozesse beendet; initialisiere neu" -#: postmaster/postmaster.c:3949 postmaster/postmaster.c:5343 -#: postmaster/postmaster.c:5649 -#, fuzzy, c-format -#| msgid "could not generate random encryption vector" +#: postmaster/postmaster.c:3993 postmaster/postmaster.c:5418 +#: postmaster/postmaster.c:5782 +#, c-format msgid "could not generate random cancel key" -msgstr "konnte zufälligen Verschlüsselungsvektor nicht erzeugen" +msgstr "konnte zufälligen Stornierungsschlüssel nicht erzeugen" -#: postmaster/postmaster.c:4003 +#: postmaster/postmaster.c:4047 #, c-format msgid "could not fork new process for connection: %m" msgstr "konnte neuen Prozess für Verbindung nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:4045 +#: postmaster/postmaster.c:4089 msgid "could not fork new process for connection: " msgstr "konnte neuen Prozess für Verbindung nicht starten (fork-Fehler): " -#: postmaster/postmaster.c:4159 +#: postmaster/postmaster.c:4203 #, c-format msgid "connection received: host=%s port=%s" msgstr "Verbindung empfangen: Host=%s Port=%s" -#: postmaster/postmaster.c:4164 +#: postmaster/postmaster.c:4208 #, c-format msgid "connection received: host=%s" msgstr "Verbindung empfangen: Host=%s" -#: postmaster/postmaster.c:4449 +#: postmaster/postmaster.c:4493 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "konnte Serverprozess »%s« nicht ausführen: %m" -#: postmaster/postmaster.c:4792 +#: postmaster/postmaster.c:4646 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "Aufgabe nach zu vielen Versuchen, Shared Memory zu reservieren" + +#: postmaster/postmaster.c:4647 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Dies kann durch ASLR oder Antivirus-Software verursacht werden." + +#: postmaster/postmaster.c:4858 #, c-format msgid "SSL configuration could not be loaded in child process" -msgstr "" +msgstr "SSL-Konfiguration konnte im Kindprozess nicht geladen werden" -#: postmaster/postmaster.c:4924 +#: postmaster/postmaster.c:4990 #, c-format msgid "Please report this to ." msgstr "Bitte berichten Sie das an ." -#: postmaster/postmaster.c:5003 +#: postmaster/postmaster.c:5077 #, c-format msgid "database system is ready to accept read only connections" msgstr "Datenbanksystem ist bereit, um lesende Verbindungen anzunehmen" -#: postmaster/postmaster.c:5271 +#: postmaster/postmaster.c:5346 #, c-format msgid "could not fork startup process: %m" msgstr "konnte Startprozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5275 +#: postmaster/postmaster.c:5350 #, c-format msgid "could not fork background writer process: %m" msgstr "konnte Background-Writer-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5279 +#: postmaster/postmaster.c:5354 #, c-format msgid "could not fork checkpointer process: %m" msgstr "konnte Checkpointer-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5283 +#: postmaster/postmaster.c:5358 #, c-format msgid "could not fork WAL writer process: %m" msgstr "konnte WAL-Writer-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5287 +#: postmaster/postmaster.c:5362 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "konnte WAL-Receiver-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5291 +#: postmaster/postmaster.c:5366 #, c-format msgid "could not fork process: %m" msgstr "konnte Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5460 postmaster/postmaster.c:5483 +#: postmaster/postmaster.c:5553 postmaster/postmaster.c:5576 #, c-format msgid "database connection requirement not indicated during registration" msgstr "die Notwendigkeit, Datenbankverbindungen zu erzeugen, wurde bei der Registrierung nicht angezeigt" -#: postmaster/postmaster.c:5467 postmaster/postmaster.c:5490 +#: postmaster/postmaster.c:5560 postmaster/postmaster.c:5583 #, c-format msgid "invalid processing mode in background worker" msgstr "ungültiger Verarbeitungsmodus in Background-Worker" -#: postmaster/postmaster.c:5542 +#: postmaster/postmaster.c:5655 #, c-format msgid "starting background worker process \"%s\"" msgstr "starte Background-Worker-Prozess »%s«" -#: postmaster/postmaster.c:5553 +#: postmaster/postmaster.c:5667 #, c-format msgid "could not fork worker process: %m" msgstr "konnte Worker-Prozess nicht starten (fork-Fehler): %m" -#: postmaster/postmaster.c:5950 +#: postmaster/postmaster.c:6100 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "konnte Socket %d nicht für Verwendung in Backend duplizieren: Fehlercode %d" -#: postmaster/postmaster.c:5982 +#: postmaster/postmaster.c:6132 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "konnte geerbtes Socket nicht erzeugen: Fehlercode %d\n" -#: postmaster/postmaster.c:6011 +#: postmaster/postmaster.c:6161 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "konnte Servervariablendatei »%s« nicht öffnen: %s\n" -#: postmaster/postmaster.c:6018 +#: postmaster/postmaster.c:6168 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "konnte nicht aus Servervariablendatei »%s« lesen: %s\n" -#: postmaster/postmaster.c:6027 +#: postmaster/postmaster.c:6177 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "konnte Datei »%s« nicht löschen: %s\n" -#: postmaster/postmaster.c:6044 +#: postmaster/postmaster.c:6194 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "konnte Sicht der Backend-Variablen nicht mappen: Fehlercode %lu\n" -#: postmaster/postmaster.c:6053 +#: postmaster/postmaster.c:6203 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "konnte Sicht der Backend-Variablen nicht unmappen: Fehlercode %lu\n" -#: postmaster/postmaster.c:6060 +#: postmaster/postmaster.c:6210 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "konnte Handle für Backend-Parametervariablen nicht schließen: Fehlercode %lu\n" -#: postmaster/postmaster.c:6221 +#: postmaster/postmaster.c:6371 #, c-format msgid "could not read exit code for process\n" msgstr "konnte Exitcode des Prozesses nicht lesen\n" -#: postmaster/postmaster.c:6226 +#: postmaster/postmaster.c:6376 #, c-format msgid "could not post child completion status\n" msgstr "konnte Child-Completion-Status nicht versenden\n" -#: postmaster/syslogger.c:452 postmaster/syslogger.c:1053 +#: postmaster/syslogger.c:470 postmaster/syslogger.c:1146 #, c-format msgid "could not read from logger pipe: %m" msgstr "konnte nicht aus Logger-Pipe lesen: %m" -#: postmaster/syslogger.c:502 +#: postmaster/syslogger.c:520 #, c-format msgid "logger shutting down" msgstr "Logger fährt herunter" -#: postmaster/syslogger.c:546 postmaster/syslogger.c:560 +#: postmaster/syslogger.c:564 postmaster/syslogger.c:578 #, c-format msgid "could not create pipe for syslog: %m" msgstr "konnte Pipe für Syslog nicht erzeugen: %m" -#: postmaster/syslogger.c:596 +#: postmaster/syslogger.c:629 #, c-format msgid "could not fork system logger: %m" msgstr "konnte Systemlogger nicht starten (fork-Fehler): %m" -#: postmaster/syslogger.c:632 +#: postmaster/syslogger.c:665 #, c-format msgid "redirecting log output to logging collector process" msgstr "Logausgabe wird an Logsammelprozess umgeleitet" -#: postmaster/syslogger.c:633 +#: postmaster/syslogger.c:666 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "Die weitere Logausgabe wird im Verzeichnis »%s« erscheinen." -#: postmaster/syslogger.c:641 +#: postmaster/syslogger.c:674 #, c-format msgid "could not redirect stdout: %m" msgstr "konnte Standardausgabe nicht umleiten: %m" -#: postmaster/syslogger.c:646 postmaster/syslogger.c:663 +#: postmaster/syslogger.c:679 postmaster/syslogger.c:696 #, c-format msgid "could not redirect stderr: %m" msgstr "konnte Standardfehlerausgabe nicht umleiten: %m" -#: postmaster/syslogger.c:1008 +#: postmaster/syslogger.c:1101 #, c-format msgid "could not write to log file: %s\n" msgstr "konnte nicht in Logdatei schreiben: %s\n" -#: postmaster/syslogger.c:1150 +#: postmaster/syslogger.c:1218 #, c-format msgid "could not open log file \"%s\": %m" msgstr "konnte Logdatei »%s« nicht öffnen: %m" -#: postmaster/syslogger.c:1212 postmaster/syslogger.c:1256 +#: postmaster/syslogger.c:1280 postmaster/syslogger.c:1330 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "automatische Rotation abgeschaltet (SIGHUP zum Wiederanschalten verwenden)" -#: regex/regc_pg_locale.c:261 +#: regex/regc_pg_locale.c:262 #, c-format msgid "could not determine which collation to use for regular expression" msgstr "konnte die für den regulären Ausdruck zu verwendende Sortierfolge nicht bestimmen" -#: repl_gram.y:280 repl_gram.y:317 +#: repl_gram.y:336 repl_gram.y:368 #, c-format msgid "invalid timeline %u" msgstr "ungültige Zeitleiste %u" -#: repl_scanner.l:122 +#: repl_scanner.l:129 msgid "invalid streaming start location" msgstr "ungültige Streaming-Startposition" -#: repl_scanner.l:173 scan.l:670 +#: repl_scanner.l:180 scan.l:683 msgid "unterminated quoted string" msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen" -#: repl_scanner.l:183 -#, c-format -msgid "syntax error: unexpected character \"%s\"" -msgstr "Syntaxfehler: unerwartetes Zeichen »%s«" - -#: replication/basebackup.c:303 +#: replication/basebackup.c:343 #, c-format msgid "could not stat control file \"%s\": %m" msgstr "konnte »stat« für Kontrolldatei »%s« nicht ausführen: %m" -#: replication/basebackup.c:412 +#: replication/basebackup.c:450 #, c-format msgid "could not find any WAL files" msgstr "konnte keine WAL-Dateien finden" -#: replication/basebackup.c:425 replication/basebackup.c:439 -#: replication/basebackup.c:448 +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 #, c-format msgid "could not find WAL file \"%s\"" msgstr "konnte WAL-Datei »%s« nicht finden" -#: replication/basebackup.c:487 replication/basebackup.c:513 +#: replication/basebackup.c:530 replication/basebackup.c:558 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "unerwartete WAL-Dateigröße »%s«" -#: replication/basebackup.c:499 replication/basebackup.c:1228 +#: replication/basebackup.c:544 replication/basebackup.c:1536 #, c-format msgid "base backup could not send data, aborting backup" msgstr "Basissicherung konnte keine Daten senden, Sicherung abgebrochen" -#: replication/basebackup.c:601 replication/basebackup.c:610 -#: replication/basebackup.c:619 replication/basebackup.c:628 -#: replication/basebackup.c:637 replication/basebackup.c:648 -#: replication/basebackup.c:665 +#: replication/basebackup.c:616 +#, fuzzy, c-format +#| msgid " data checksum version\n" +msgid "%s total checksum verification failures" +msgstr " Datenprüfsummenversion\n" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 #, c-format msgid "duplicate option \"%s\"" msgstr "doppelte Option »%s«" -#: replication/basebackup.c:654 utils/misc/guc.c:5736 +#: replication/basebackup.c:717 utils/misc/guc.c:6023 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d ist außerhalb des gültigen Bereichs für Parameter »%s« (%d ... %d)" -#: replication/basebackup.c:928 replication/basebackup.c:1025 +#: replication/basebackup.c:991 replication/basebackup.c:1161 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" -#: replication/basebackup.c:1180 +#: replication/basebackup.c:1316 #, c-format msgid "skipping special file \"%s\"" msgstr "überspringe besondere Datei »%s«" -#: replication/basebackup.c:1293 +#: replication/basebackup.c:1421 +#, fuzzy, c-format +#| msgid "invalid column number %d for table \"%s\"\n" +msgid "invalid segment number %d in file \"%s\"" +msgstr "ungültige Spaltennummer %d in Tabelle »%s«\n" + +#: replication/basebackup.c:1440 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "" + +#: replication/basebackup.c:1484 replication/basebackup.c:1500 +#, fuzzy, c-format +#| msgid "could not seek in file \"%s\": %m" +msgid "could not fseek in file \"%s\": %m" +msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" + +#: replication/basebackup.c:1492 +#, fuzzy, c-format +#| msgid "could not read block %u in file \"%s\": %m" +msgid "could not reread block %d of file \"%s\": %m" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %m" + +#: replication/basebackup.c:1516 +#, fuzzy, c-format +#| msgid "page verification failed, calculated checksum %u but expected %u" +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "Seitenüberprüfung fehlgeschlagen, berechnete Prüfsumme %u, aber erwartet %u" + +#: replication/basebackup.c:1523 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "" + +#: replication/basebackup.c:1581 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "" + +#: replication/basebackup.c:1609 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "Dateiname zu lang für Tar-Format: »%s«" -#: replication/basebackup.c:1298 +#: replication/basebackup.c:1614 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "Ziel der symbolischen Verknüpfung zu lang für Tar-Format: Dateiname »%s«, Ziel »%s«" -#: replication/libpqwalreceiver/libpqwalreceiver.c:221 -#, fuzzy, c-format -#| msgid "invalid connection type: %s" +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 +#, c-format msgid "invalid connection string syntax: %s" -msgstr "ungültiger Verbindungstyp: %s" +msgstr "ungültige Syntax für Verbindungszeichenkette: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:245 +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 #, c-format msgid "could not parse connection string: %s" msgstr "konnte Verbindungsparameter nicht interpretieren: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:295 +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 #, c-format msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "konnte Datenbanksystemidentifikator und Zeitleisten-ID nicht vom Primärserver empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:306 -#: replication/libpqwalreceiver/libpqwalreceiver.c:512 +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 +#: replication/libpqwalreceiver/libpqwalreceiver.c:550 #, c-format msgid "invalid response from primary server" msgstr "ungültige Antwort vom Primärserver" -#: replication/libpqwalreceiver/libpqwalreceiver.c:307 +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 #, c-format msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet." -#: replication/libpqwalreceiver/libpqwalreceiver.c:373 -#: replication/libpqwalreceiver/libpqwalreceiver.c:379 -#: replication/libpqwalreceiver/libpqwalreceiver.c:404 +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 +#: replication/libpqwalreceiver/libpqwalreceiver.c:416 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format msgid "could not start WAL streaming: %s" msgstr "konnte WAL-Streaming nicht starten: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:423 +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "konnte End-of-Streaming-Nachricht nicht an Primärserver senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:447 +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "unerwartete Ergebnismenge nach End-of-Streaming" -#: replication/libpqwalreceiver/libpqwalreceiver.c:467 +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "Fehler beim Beenden des COPY-Datenstroms: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 #, c-format msgid "error reading result of streaming command: %s" msgstr "Fehler beim Lesen des Ergebnisses von Streaming-Befehl: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:475 +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "unerwartetes Ergebnis nach CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:501 +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "konnte Zeitleisten-History-Datei nicht vom Primärserver empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "1 Tupel mit 2 Feldern erwartet, %d Tupel mit %d Feldern erhalten." -#: replication/libpqwalreceiver/libpqwalreceiver.c:660 -#: replication/libpqwalreceiver/libpqwalreceiver.c:687 -#: replication/libpqwalreceiver/libpqwalreceiver.c:693 +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 +#: replication/libpqwalreceiver/libpqwalreceiver.c:756 +#: replication/libpqwalreceiver/libpqwalreceiver.c:762 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:712 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 #, c-format msgid "could not send data to WAL stream: %s" msgstr "konnte keine Daten an den WAL-Stream senden: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:746 -#, fuzzy, c-format -#| msgid "could not create directory \"%s\": %s\n" +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 +#, c-format msgid "could not create replication slot \"%s\": %s" -msgstr "konnte Verzeichnis »%s« nicht erzeugen: %s\n" +msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %s" -#: replication/logical/launcher.c:236 -#, fuzzy, c-format -#| msgid "starting logical decoding for slot \"%s\"" +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 +#, c-format +msgid "invalid query response" +msgstr "ungültige Antwort auf Anfrage" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d Felder erwartet, %d Feldern erhalten." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 +#, c-format +msgid "the query interface requires a database connection" +msgstr "Ausführen von Anfragen benötigt eine Datenbankverbindung" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 +msgid "empty query" +msgstr "leere Anfrage" + +#: replication/logical/launcher.c:310 +#, c-format msgid "starting logical replication worker for subscription \"%s\"" -msgstr "starte logisches Dekodieren für Slot »%s«" +msgstr "starte Arbeitsprozess für logische Replikation für Subskription »%s«" -#: replication/logical/launcher.c:243 -#, fuzzy, c-format -#| msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +#: replication/logical/launcher.c:317 +#, c-format msgid "cannot start logical replication workers when max_replication_slots = 0" -msgstr "Replication-Origin kann nicht abgefragt oder geändert werden, wenn max_replication_slots = 0" +msgstr "Arbeitsprozesse für logische Replikation können nicht gestartet werden, wenn max_replication_slots = 0" -#: replication/logical/launcher.c:267 +#: replication/logical/launcher.c:397 #, c-format -msgid "out of logical replication workers slots" -msgstr "" +msgid "out of logical replication worker slots" +msgstr "alle Slots für Arbeitsprozesse für logische Replikation belegt" -#: replication/logical/launcher.c:268 -#, fuzzy, c-format -#| msgid "You might need to increase max_locks_per_transaction." +#: replication/logical/launcher.c:398 +#, c-format msgid "You might need to increase max_logical_replication_workers." -msgstr "Sie müssen möglicherweise max_locks_per_transaction erhöhen." +msgstr "Sie müssen möglicherweise max_logical_replication_workers erhöhen." -#: replication/logical/launcher.c:296 -#, fuzzy, c-format -#| msgid "too many background workers" -msgid "out of background workers slots" -msgstr "zu viele Background-Worker" +#: replication/logical/launcher.c:453 +#, c-format +msgid "out of background worker slots" +msgstr "alle Slots für Background-Worker belegt" -#: replication/logical/launcher.c:297 -#, fuzzy, c-format -#| msgid "You might need to increase max_locks_per_transaction." +#: replication/logical/launcher.c:454 +#, c-format msgid "You might need to increase max_worker_processes." -msgstr "Sie müssen möglicherweise max_locks_per_transaction erhöhen." +msgstr "Sie müssen möglicherweise max_worker_processes erhöhen." -#: replication/logical/launcher.c:413 +#: replication/logical/launcher.c:661 #, c-format -msgid "logical replication worker slot %d already used by another worker" -msgstr "" +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "Arbeitsprozess-Slot %d für logische Replikation ist leer, kann nicht zugeteilt werden" -#: replication/logical/launcher.c:556 -#, fuzzy, c-format -#| msgid "autovacuum launcher started" -msgid "logical replication launcher started" -msgstr "Autovacuum-Launcher startet" +#: replication/logical/launcher.c:670 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "Arbeitsprozess-Slot %d für logische Replikation wird schon von einem anderen Arbeitsprozess verwendet, kann nicht zugeteilt werden" -#: replication/logical/launcher.c:656 -#, fuzzy, c-format -#| msgid "autovacuum launcher shutting down" -msgid "logical replication launcher shutting down" -msgstr "Autovacuum-Launcher fährt herunter" +#: replication/logical/launcher.c:988 +#, c-format +msgid "logical replication launcher started" +msgstr "Logical-Replication-Launcher startet" -#: replication/logical/logical.c:83 +#: replication/logical/logical.c:90 #, c-format msgid "logical decoding requires wal_level >= logical" msgstr "logische Dekodierung erfordert wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:95 #, c-format msgid "logical decoding requires a database connection" msgstr "logische Dekodierung benötigt eine Datenbankverbindung" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:113 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "logische Dekodierung kann nicht während der Wiederherstellung verwendet werden" -#: replication/logical/logical.c:236 replication/logical/logical.c:348 +#: replication/logical/logical.c:255 replication/logical/logical.c:386 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "physischer Replikations-Slot kann nicht für logisches Dekodieren verwendet werden" -#: replication/logical/logical.c:241 replication/logical/logical.c:353 +#: replication/logical/logical.c:260 replication/logical/logical.c:391 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "Replikations-Slot »%s« wurde nicht in dieser Datenbank erzeugt" -#: replication/logical/logical.c:248 +#: replication/logical/logical.c:267 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "logischer Replikations-Slot kann nicht in einer Transaktion erzeugt werden, die Schreibvorgänge ausgeführt hat" -#: replication/logical/logical.c:390 +#: replication/logical/logical.c:431 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "starte logisches Dekodieren für Slot »%s«" -#: replication/logical/logical.c:392 +#: replication/logical/logical.c:433 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "Streaming beginnt bei Transaktionen, die nach %X/%X committen; lese WAL ab %X/%X" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Streaming beginnt bei Transaktionen, die nach %X/%X committen; lese WAL ab %X/%X." -#: replication/logical/logical.c:527 +#: replication/logical/logical.c:583 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s, zugehörige LSN %X/%X" -#: replication/logical/logical.c:534 +#: replication/logical/logical.c:590 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "Slot »%s«, Ausgabe-Plugin »%s«, im Callback %s" -#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "nur Superuser und Replikationsrollen können Replikations-Slots verwenden" @@ -16521,616 +17715,735 @@ msgstr "Array muss eindimensional sein" msgid "array must not contain nulls" msgstr "Array darf keine NULL-Werte enthalten" -#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2282 -#: utils/adt/jsonb.c:1357 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 +#: utils/adt/jsonb.c:1269 #, c-format msgid "array must have even number of elements" msgstr "Array muss eine gerade Anzahl Elemente haben" -#: replication/logical/logicalfuncs.c:265 +#: replication/logical/logicalfuncs.c:269 #, c-format msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "Ausgabe-Plugin »%s« erzeugt binäre Ausgabe, aber Funktion »%s« erwartet Textdaten" -#: replication/logical/origin.c:180 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "nur Superuser können Replication-Origins abfragen oder ändern" -#: replication/logical/origin.c:185 +#: replication/logical/origin.c:190 #, c-format msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "Replication-Origin kann nicht abgefragt oder geändert werden, wenn max_replication_slots = 0" -#: replication/logical/origin.c:190 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "Replication-Origins können nicht während der Wiederherstellung geändert werden" -#: replication/logical/origin.c:314 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "Replication-Origin »%s« existiert nicht" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "konnte keine freie Replication-Origin-OID finden" -#: replication/logical/origin.c:351 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "konnte Replication-Origin mit OID %d nicht löschen, wird von PID %d verwendet" -#: replication/logical/origin.c:664 +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "Replication-Origin mit OID %u existiert nicht" + +#: replication/logical/origin.c:725 #, c-format msgid "replication checkpoint has wrong magic %u instead of %u" msgstr "Replikations-Checkpoint hat falsche magische Zahl %u statt %u" -#: replication/logical/origin.c:696 +#: replication/logical/origin.c:757 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" -#: replication/logical/origin.c:705 +#: replication/logical/origin.c:766 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "konnte keinen freien Replication-State finden, erhöhen Sie max_replication_slots" -#: replication/logical/origin.c:723 +#: replication/logical/origin.c:784 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "Replikations-Slot-Checkpoint hat falsche Prüfsumme %u, erwartet wurde %u" -#: replication/logical/origin.c:847 +#: replication/logical/origin.c:908 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "Replication-Origin mit OID %d ist bereits aktiv für PID %d" -#: replication/logical/origin.c:858 replication/logical/origin.c:1038 +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 #, c-format msgid "could not find free replication state slot for replication origin with OID %u" msgstr "konnte keinen freien Replication-State-Slot für Replication-Origin mit OID %u finden" -#: replication/logical/origin.c:860 replication/logical/origin.c:1040 -#: replication/slot.c:1336 +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 +#: replication/slot.c:1559 #, c-format msgid "Increase max_replication_slots and try again." msgstr "Erhöhen Sie max_replication_slots und versuchen Sie es erneut." -#: replication/logical/origin.c:997 +#: replication/logical/origin.c:1065 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "kann Replication-Origin nicht einrichten, wenn schon einer eingerichtet ist" -#: replication/logical/origin.c:1026 +#: replication/logical/origin.c:1094 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "Replikationsidentifikator %d ist bereits aktiv für PID %d" -#: replication/logical/origin.c:1072 replication/logical/origin.c:1267 -#: replication/logical/origin.c:1287 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 +#: replication/logical/origin.c:1363 #, c-format msgid "no replication origin is configured" msgstr "kein Replication-Origin konfiguriert" -#: replication/logical/relation.c:265 -#, fuzzy, c-format -#| msgid "replication slot \"%s\" does not exist" +#: replication/logical/relation.c:255 +#, c-format msgid "logical replication target relation \"%s.%s\" does not exist" -msgstr "Replikations-Slot »%s« existiert nicht" - -#: replication/logical/relation.c:276 -#, fuzzy, c-format -#| msgid "referenced relation \"%s\" is not a table" -msgid "logical replication target relation \"%s.%s\" is not a table" -msgstr "Relation »%s«, auf die verwiesen wird, ist keine Tabelle" +msgstr "Zielrelation für logische Replikation »%s.%s« existiert nicht" -#: replication/logical/relation.c:303 +#: replication/logical/relation.c:297 #, c-format msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" -msgstr "" +msgstr "in Zielrelation für logische Replikation »%s.%s« fehlen replizierte Spalten" -#: replication/logical/relation.c:342 +#: replication/logical/relation.c:337 #, c-format msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" -msgstr "" - -#: replication/logical/relation.c:452 -#, fuzzy, c-format -#| msgid "function \"%s\" not found\n" -msgid "builtin type %u not found" -msgstr "Funktion »%s« nicht gefunden\n" - -#: replication/logical/relation.c:453 -#, c-format -msgid "This can be caused by having publisher with higher major version than subscriber" -msgstr "" +msgstr "Zielrelation für logische Replikation »%s.%s« verwendet Systemspalten in REPLICA-IDENTITY-Index" -#: replication/logical/relation.c:485 -#, fuzzy, c-format -#| msgid "database \"%s\" is used by a logical replication slot" -msgid "data type \"%s.%s\" required for logical replication does not exist" -msgstr "Datenbank »%s« wird von einem logischen Replikations-Slot verwendet" - -#: replication/logical/reorderbuffer.c:2286 +#: replication/logical/reorderbuffer.c:2503 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "konnte nicht in Datendatei für XID %u schreiben: %m" -#: replication/logical/reorderbuffer.c:2382 -#: replication/logical/reorderbuffer.c:2402 +#: replication/logical/reorderbuffer.c:2596 +#: replication/logical/reorderbuffer.c:2618 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %m" -#: replication/logical/reorderbuffer.c:2386 -#: replication/logical/reorderbuffer.c:2406 +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "konnte nicht aus Reorder-Buffer-Spill-Datei lesen: %d statt %u Bytes gelesen" -#: replication/logical/reorderbuffer.c:3062 +#: replication/logical/reorderbuffer.c:2845 +#, fuzzy, c-format +#| msgid "could not read file \"%s\", read %d of %d: %m" +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "konnte Datei »%s« nicht lesen, %d von %d gelesen: %m" + +#: replication/logical/reorderbuffer.c:3311 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "konnte nicht aus Datei »%s« lesen: %d statt %d Bytes gelesen" -#: replication/logical/snapbuild.c:597 +#: replication/logical/snapbuild.c:612 +#, c-format +msgid "initial slot snapshot too large" +msgstr "initialer Slot-Snapshot ist zu groß" + +#: replication/logical/snapbuild.c:664 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-ID" msgstr[1] "logischer Dekodierungs-Snapshot exportiert: »%s« mit %u Transaktions-IDs" -#: replication/logical/snapbuild.c:916 replication/logical/snapbuild.c:1281 -#: replication/logical/snapbuild.c:1812 +#: replication/logical/snapbuild.c:1269 replication/logical/snapbuild.c:1362 +#: replication/logical/snapbuild.c:1872 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "logisches Dekodieren fand konsistenten Punkt bei %X/%X" -#: replication/logical/snapbuild.c:918 -#, c-format -msgid "Transaction ID %u finished; no more running transactions." -msgstr "Transaktions-ID %u beendet; keine laufenden Transaktionen mehr." - -#: replication/logical/snapbuild.c:1283 +#: replication/logical/snapbuild.c:1271 #, c-format msgid "There are no running transactions." msgstr "Keine laufenden Transaktionen." -#: replication/logical/snapbuild.c:1345 +#: replication/logical/snapbuild.c:1313 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "logisches Dekodieren fand initialen Startpunkt bei %X/%X" -#: replication/logical/snapbuild.c:1347 +#: replication/logical/snapbuild.c:1315 replication/logical/snapbuild.c:1339 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Warten auf Abschluss der Transaktionen (ungefähr %d), die älter als %u sind." + +#: replication/logical/snapbuild.c:1337 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "logisches Dekodieren fand initialen konsistenten Punkt bei %X/%X" + +#: replication/logical/snapbuild.c:1364 #, c-format -msgid "%u transaction needs to finish." -msgid_plural "%u transactions need to finish." -msgstr[0] "%u Transaktion muss noch abschließen." -msgstr[1] "%u Transaktionen müssen noch abschließen." +msgid "There are no old transactions anymore." +msgstr "Es laufen keine alten Transaktionen mehr." -#: replication/logical/snapbuild.c:1686 replication/logical/snapbuild.c:1712 -#: replication/logical/snapbuild.c:1726 replication/logical/snapbuild.c:1740 +#: replication/logical/snapbuild.c:1736 replication/logical/snapbuild.c:1767 +#: replication/logical/snapbuild.c:1787 replication/logical/snapbuild.c:1806 #, c-format msgid "could not read file \"%s\", read %d of %d: %m" msgstr "konnte Datei »%s« nicht lesen, %d von %d gelesen: %m" -#: replication/logical/snapbuild.c:1692 +#: replication/logical/snapbuild.c:1742 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "Scanbuild-State-Datei »%s« hat falsche magische Zahl %u statt %u" -#: replication/logical/snapbuild.c:1697 +#: replication/logical/snapbuild.c:1747 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "Snapbuild-State-Datei »%s« hat nicht unterstützte Version: %u statt %u" -#: replication/logical/snapbuild.c:1753 +#: replication/logical/snapbuild.c:1819 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "Prüfsummenfehler bei Snapbuild-State-Datei »%s«: ist %u, sollte %u sein" -#: replication/logical/snapbuild.c:1814 +#: replication/logical/snapbuild.c:1874 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "Logische Dekodierung beginnt mit gespeichertem Snapshot." -#: replication/logical/snapbuild.c:1887 +#: replication/logical/snapbuild.c:1946 #, c-format msgid "could not parse file name \"%s\"" msgstr "konnte Dateinamen »%s« nicht parsen" -#: replication/logical/worker.c:256 +#: replication/logical/tablesync.c:138 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat abgeschlossen" + +#: replication/logical/tablesync.c:685 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "konnte Tabelleninformationen für Tabelle »%s.%s« nicht vom Publikationsserver holen: %s" + +#: replication/logical/tablesync.c:691 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "Tabelle »%s.%s« nicht auf dem Publikationsserver gefunden" + +#: replication/logical/tablesync.c:721 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "konnte Tabelleninformationen für Tabelle »%s.%s« nicht holen: %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "konnte Kopieren des Anfangsinhalts für Tabelle »%s.%s« nicht starten: %s" + +#: replication/logical/tablesync.c:904 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht gestartet werden" + +#: replication/logical/tablesync.c:926 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "beim Kopieren der Tabelle konnte die Transaktion auf dem Publikationsserver nicht beenden werden" + +#: replication/logical/worker.c:307 #, c-format msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" -msgstr "" +msgstr "Verarbeiten empfangener Daten für Replikationszielrelation »%s.%s« Spalte »%s«, entfernter Typ %s, lokaler Typ %s" -#: replication/logical/worker.c:448 +#: replication/logical/worker.c:528 #, c-format msgid "ORIGIN message sent out of order" -msgstr "" +msgstr "ORIGIN-Nachricht in falscher Reihenfolge gesendet" -#: replication/logical/worker.c:570 +#: replication/logical/worker.c:661 #, c-format -msgid "publisher does not send replica identity column expected by the logical replication target relation \"%s.%s\"" -msgstr "" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "Publikationsserver hat nicht die Replikidentitätsspalten gesendet, die von Replikationszielrelation »%s.%s« erwartet wurden" -#: replication/logical/worker.c:577 +#: replication/logical/worker.c:668 #, c-format -msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTIY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" -msgstr "" - -#: replication/logical/worker.c:766 -#, fuzzy, c-format -#| msgid "could not find free replication origin OID" -msgid "logical replication could not find row for delete in replication target %s" -msgstr "konnte keine freie Replication-Origin-OID finden" +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "Zielrelation für logische Replikation »%s.%s« hat weder REPLICA-IDENTITY-Index noch Primärschlüssel und die publizierte Relation hat kein REPLICA IDENTITY FULL" -#: replication/logical/worker.c:833 -#, fuzzy, c-format -#| msgid "invalid frontend message type %d" -msgid "invalid logical replication message type %c" -msgstr "ungültiger Frontend-Message-Typ %d" +#: replication/logical/worker.c:1007 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "ungültiger Nachrichtentyp für logische Replikation »%c«" -#: replication/logical/worker.c:972 +#: replication/logical/worker.c:1148 #, c-format msgid "data stream from publisher has ended" -msgstr "" +msgstr "Datenstrom vom Publikationsserver endete" -#: replication/logical/worker.c:1100 -#, fuzzy, c-format -#| msgid "terminating walreceiver due to timeout" +#: replication/logical/worker.c:1307 +#, c-format msgid "terminating logical replication worker due to timeout" -msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung" +msgstr "Arbeitsprozess für logische Replikation wird abgebrochen wegen Zeitüberschreitung" -#: replication/logical/worker.c:1239 +#: replication/logical/worker.c:1455 #, c-format -msgid "logical replication worker for subscription \"%s\" will stop because the subscription was removed" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription entfernt wurde" -#: replication/logical/worker.c:1254 +#: replication/logical/worker.c:1469 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because the connection information was changed" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird anhalten, weil die Subskription deaktiviert wurde" -#: replication/logical/worker.c:1269 +#: replication/logical/worker.c:1483 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because subscription was renamed" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird neu starten, weil die Verbindungsinformationen geändert wurden" -#: replication/logical/worker.c:1284 +#: replication/logical/worker.c:1497 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because subscription's publications were changed" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird neu starten, weil die Subskription umbenannt wurde" -#: replication/logical/worker.c:1300 +#: replication/logical/worker.c:1514 #, c-format -msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird neu starten, weil der Replikations-Slot-Name geändert wurde" -#: replication/logical/worker.c:1393 +#: replication/logical/worker.c:1528 #, c-format -msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" -msgstr "" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird neu starten, weil die Publikationen der Subskription geandert wurden" -#: replication/logical/worker.c:1406 -#, fuzzy, c-format -#| msgid "authentication failed for user \"%s\": host rejected" -msgid "logical replication apply for subscription \"%s\" has started" -msgstr "Authentifizierung für Benutzer »%s« fehlgeschlagen: Host abgelehnt" +#: replication/logical/worker.c:1631 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "Apply-Worker für logische Replikation für Subskription %u« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" -#: replication/pgoutput/pgoutput.c:113 -#, fuzzy, c-format -#| msgid "invalid option \"%s\"" +#: replication/logical/worker.c:1643 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« wird nicht starten, weil die Subskription während des Starts deaktiviert wurde" + +#: replication/logical/worker.c:1661 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "Arbeitsprozess für logische Replikation für Tabellensynchronisation für Subskription »%s«, Tabelle »%s« hat gestartet" + +#: replication/logical/worker.c:1665 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "Apply-Worker für logische Replikation für Subskription »%s« hat gestartet" + +#: replication/logical/worker.c:1705 +#, c-format +msgid "subscription has no replication slot set" +msgstr "für die Subskription ist kein Replikations-Slot gesetzt" + +#: replication/pgoutput/pgoutput.c:117 +#, c-format msgid "invalid proto_version" -msgstr "ungültige Option »%s«" +msgstr "ungültige proto_version" -#: replication/pgoutput/pgoutput.c:118 -#, fuzzy, c-format -#| msgid "numeric time zone \"%s\" out of range" -msgid "proto_verson \"%s\" out of range" -msgstr "numerische Zeitzone »%s« ist außerhalb des gültigen Bereichs" +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version »%s« ist außerhalb des gültigen Bereichs" -#: replication/pgoutput/pgoutput.c:135 -#, fuzzy, c-format -#| msgid "invalid name syntax" +#: replication/pgoutput/pgoutput.c:139 +#, c-format msgid "invalid publication_names syntax" -msgstr "ungültige Namenssyntax" +msgstr "ungültige Syntax für publication_names" -#: replication/pgoutput/pgoutput.c:179 +#: replication/pgoutput/pgoutput.c:181 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or lower" -msgstr "" +msgstr "Client sendete proto_version=%d, aber wir unterstützen nur Protokoll %d oder niedriger" -#: replication/pgoutput/pgoutput.c:185 +#: replication/pgoutput/pgoutput.c:187 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or higher" -msgstr "" +msgstr "Client sendete proto_version=%d, aber wir unterstützen nur Protokoll %d oder höher" -#: replication/pgoutput/pgoutput.c:191 -#, fuzzy, c-format -#| msgid "multiple Dictionary parameters" +#: replication/pgoutput/pgoutput.c:193 +#, c-format msgid "publication_names parameter missing" -msgstr "mehrere »Dictionary«-Parameter" +msgstr "Parameter »publication_names« fehlt" -#: replication/slot.c:180 +#: replication/slot.c:182 #, c-format msgid "replication slot name \"%s\" is too short" msgstr "Replikations-Slot-Name »%s« ist zu kurz" -#: replication/slot.c:189 +#: replication/slot.c:191 #, c-format msgid "replication slot name \"%s\" is too long" msgstr "Replikations-Slot-Name »%s« ist zu lang" -#: replication/slot.c:202 +#: replication/slot.c:204 #, c-format msgid "replication slot name \"%s\" contains invalid character" msgstr "Replikations-Slot-Name »%s« enthält ungültiges Zeichen" -#: replication/slot.c:204 +#: replication/slot.c:206 #, c-format msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." msgstr "Replikations-Slot-Namen dürfen nur Kleinbuchstaben, Zahlen und Unterstriche enthalten." -#: replication/slot.c:251 +#: replication/slot.c:253 #, c-format msgid "replication slot \"%s\" already exists" msgstr "Replikations-Slot »%s« existiert bereits" -#: replication/slot.c:261 +#: replication/slot.c:263 #, c-format msgid "all replication slots are in use" msgstr "alle Replikations-Slots sind in Benutzung" -#: replication/slot.c:262 +#: replication/slot.c:264 #, c-format msgid "Free one or increase max_replication_slots." msgstr "Geben Sie einen frei oder erhöhen Sie max_replication_slots." -#: replication/slot.c:358 +#: replication/slot.c:387 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "Replikations-Slot »%s« existiert nicht" -#: replication/slot.c:362 +#: replication/slot.c:398 replication/slot.c:948 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "Replikations-Slot »%s« ist aktiv für PID %d" -#: replication/slot.c:548 replication/slot.c:960 replication/slot.c:1297 +#: replication/slot.c:632 replication/slot.c:1141 replication/slot.c:1495 #, c-format msgid "could not remove directory \"%s\"" msgstr "konnte Verzeichnis »%s« nicht löschen" -#: replication/slot.c:809 +#: replication/slot.c:983 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "Replikations-Slots können nur verwendet werden, wenn max_replication_slots > 0" -#: replication/slot.c:814 +#: replication/slot.c:988 #, c-format msgid "replication slots can only be used if wal_level >= replica" msgstr "Replikations-Slots können nur verwendet werden, wenn wal_level >= replica" -#: replication/slot.c:1229 replication/slot.c:1267 +#: replication/slot.c:1427 replication/slot.c:1467 #, c-format msgid "could not read file \"%s\", read %d of %u: %m" msgstr "konnte Datei »%s« nicht lesen, %d von %u gelesen: %m" -#: replication/slot.c:1238 +#: replication/slot.c:1436 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "Replikations-Slot-Datei »%s« hat falsche magische Zahl: %u statt %u" -#: replication/slot.c:1245 +#: replication/slot.c:1443 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "Replikations-Slot-Datei »%s« hat nicht unterstützte Version %u" -#: replication/slot.c:1252 +#: replication/slot.c:1450 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "Replikations-Slot-Datei »%s« hat falsche Länge %u" -#: replication/slot.c:1282 +#: replication/slot.c:1482 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "Prüfsummenfehler bei Replikations-Slot-Datei »%s«: ist %u, sollte %u sein" -#: replication/slot.c:1335 +#: replication/slot.c:1516 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "logischer Replikations-Slot »%s« existiert, aber wal_level < logical" + +#: replication/slot.c:1518 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Ändern Sie wal_level in logical oder höher." + +#: replication/slot.c:1522 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "physischer Replikations-Slot »%s« existiert, aber wal_level < replica" + +#: replication/slot.c:1524 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Ändern Sie wal_level in replica oder höher." + +#: replication/slot.c:1558 #, c-format msgid "too many replication slots active before shutdown" msgstr "zu viele aktive Replikations-Slots vor dem Herunterfahren" -#: replication/syncrep.c:244 +#: replication/slotfuncs.c:490 +#, fuzzy, c-format +#| msgid "invalid array flags" +msgid "invalid target wal lsn" +msgstr "ungültige Array-Flags" + +#: replication/slotfuncs.c:512 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "" + +#: replication/slotfuncs.c:528 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" + +#: replication/syncrep.c:246 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "Warten auf synchrone Replikation wird storniert and Verbindung wird abgebrochen, aufgrund von Anweisung des Administrators" -#: replication/syncrep.c:245 replication/syncrep.c:262 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgstr "Die Transaktion wurde lokal bereits committet, aber möglicherweise noch nicht zum Standby repliziert." -#: replication/syncrep.c:261 +#: replication/syncrep.c:263 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "storniere Warten auf synchrone Replikation wegen Benutzeraufforderung" -#: replication/syncrep.c:392 +#: replication/syncrep.c:397 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "Standby »%s« hat jetzt synchrone Standby-Priorität %u" -#: replication/syncrep.c:453 +#: replication/syncrep.c:460 #, c-format msgid "standby \"%s\" is now a synchronous standby with priority %u" msgstr "Standby »%s« ist jetzt ein synchroner Standby mit Priorität %u" -#: replication/syncrep.c:457 -#, fuzzy, c-format -#| msgid "standby \"%s\" is now a synchronous standby with priority %u" +#: replication/syncrep.c:464 +#, c-format msgid "standby \"%s\" is now a candidate for quorum synchronous standby" -msgstr "Standby »%s« ist jetzt ein synchroner Standby mit Priorität %u" +msgstr "Standby »%s« ist jetzt ein Kandidat für synchroner Standby mit Quorum" -#: replication/syncrep.c:1120 +#: replication/syncrep.c:1164 #, c-format msgid "synchronous_standby_names parser failed" msgstr "Parser für synchronous_standby_names fehlgeschlagen" -#: replication/syncrep.c:1126 +#: replication/syncrep.c:1170 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "Anzahl synchroner Standbys (%d) muss größer als null sein" -#: replication/walreceiver.c:167 +#: replication/walreceiver.c:169 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "WAL-Receiver-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" -#: replication/walreceiver.c:300 +#: replication/walreceiver.c:309 #, c-format msgid "could not connect to the primary server: %s" msgstr "konnte nicht mit dem Primärserver verbinden: %s" -#: replication/walreceiver.c:339 +#: replication/walreceiver.c:359 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "Datenbanksystemidentifikator unterscheidet sich zwischen Primär- und Standby-Server" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:360 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "Identifikator des Primärservers ist %s, Identifikator des Standby ist %s." -#: replication/walreceiver.c:351 +#: replication/walreceiver.c:371 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "höchste Zeitleiste %u des primären Servers liegt hinter Wiederherstellungszeitleiste %u zurück" -#: replication/walreceiver.c:387 +#: replication/walreceiver.c:407 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "WAL-Streaming vom Primärserver gestartet bei %X/%X auf Zeitleiste %u" -#: replication/walreceiver.c:392 +#: replication/walreceiver.c:412 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "WAL-Streaming neu gestartet bei %X/%X auf Zeitleiste %u" -#: replication/walreceiver.c:421 +#: replication/walreceiver.c:441 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "kann WAL-Streaming nicht fortsetzen, Wiederherstellung ist bereits beendet" -#: replication/walreceiver.c:458 +#: replication/walreceiver.c:478 #, c-format msgid "replication terminated by primary server" msgstr "Replikation wurde durch Primärserver beendet" -#: replication/walreceiver.c:459 +#: replication/walreceiver.c:479 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "WAL-Ende erreicht auf Zeitleiste %u bei %X/%X." -#: replication/walreceiver.c:554 +#: replication/walreceiver.c:574 #, c-format msgid "terminating walreceiver due to timeout" msgstr "WAL-Receiver-Prozess wird abgebrochen wegen Zeitüberschreitung" -#: replication/walreceiver.c:594 +#: replication/walreceiver.c:614 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "Primärserver enthält kein WAL mehr auf angeforderter Zeitleiste %u" -#: replication/walreceiver.c:609 replication/walreceiver.c:968 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format msgid "could not close log segment %s: %m" msgstr "konnte Logsegment %s nicht schließen: %m" -#: replication/walreceiver.c:734 +#: replication/walreceiver.c:754 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "hole Zeitleisten-History-Datei für Zeitleiste %u vom Primärserver" -#: replication/walreceiver.c:1022 +#: replication/walreceiver.c:1036 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "konnte nicht in Logsegment %s bei Position %u, Länge %lu schreiben: %m" -#: replication/walsender.c:455 +#: replication/walsender.c:494 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "konnte Positionszeiger nicht den Anfang der Datei »%s« setzen: %m" -#: replication/walsender.c:494 +#: replication/walsender.c:535 #, c-format msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" -msgstr "" +msgstr "IDENTIFY_SYSTEM wurde nicht vor START_REPLICATION ausgeführt" -#: replication/walsender.c:511 +#: replication/walsender.c:552 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "logischer Replikations-Slot kann nicht für physische Replikation verwendet werden" -#: replication/walsender.c:574 +#: replication/walsender.c:615 #, c-format msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "angeforderter Startpunkt %X/%X auf Zeitleiste %u ist nicht in der History dieses Servers" -#: replication/walsender.c:578 +#: replication/walsender.c:619 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "Die History dieses Servers zweigte von Zeitleiste %u bei %X/%X ab." -#: replication/walsender.c:623 +#: replication/walsender.c:664 #, c-format msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "angeforderter Startpunkt %X/%X ist vor der WAL-Flush-Position dieses Servers %X/%X" +#: replication/walsender.c:893 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT kann nicht in einer Transaktion aufgerufen werden" + +#: replication/walsender.c:902 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT muss in einer Transaktion aufgerufen werden" + +#: replication/walsender.c:907 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT muss in einer Transaktion im Isolationsmodus REPEATABLE READ aufgerufen werden" + #: replication/walsender.c:912 #, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT muss vor allen Anfragen aufgerufen werden" + +#: replication/walsender.c:917 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT kann nicht in einer Subtransaktion aufgerufen werden" + +#: replication/walsender.c:1063 +#, c-format msgid "terminating walsender process after promotion" msgstr "WAL-Sender-Prozess wird nach Beförderung abgebrochen" -#: replication/walsender.c:1240 +#: replication/walsender.c:1448 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "während der WAL-Sender im Stoppmodus ist können keine neuen Befehle ausgeführt werden" + +#: replication/walsender.c:1481 #, c-format msgid "received replication command: %s" msgstr "Replikationsbefehl empfangen: %s" -#: replication/walsender.c:1348 replication/walsender.c:1364 +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1033 +#: tcop/postgres.c:1357 tcop/postgres.c:1617 tcop/postgres.c:2023 +#: tcop/postgres.c:2396 tcop/postgres.c:2475 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert" + +#: replication/walsender.c:1562 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "im WAL-Sender für physische Replikation können keine SQL-Befehle ausgeführt werden" + +#: replication/walsender.c:1610 replication/walsender.c:1626 #, c-format msgid "unexpected EOF on standby connection" msgstr "unerwartetes EOF auf Standby-Verbindung" -#: replication/walsender.c:1378 +#: replication/walsender.c:1640 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "unerwarteter Standby-Message-Typ »%c«, nach Empfang von CopyDone" -#: replication/walsender.c:1416 +#: replication/walsender.c:1678 #, c-format msgid "invalid standby message type \"%c\"" msgstr "ungültiger Standby-Message-Typ »%c«" -#: replication/walsender.c:1457 +#: replication/walsender.c:1719 #, c-format msgid "unexpected message type \"%c\"" msgstr "unerwarteter Message-Typ »%c«" -#: replication/walsender.c:1741 +#: replication/walsender.c:2097 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "WAL-Sender-Prozess wird abgebrochen wegen Zeitüberschreitung bei der Replikation" -#: replication/walsender.c:1829 +#: replication/walsender.c:2181 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "Standby-Server »%s« hat jetzt den Primärserver eingeholt" +msgid "\"%s\" has now caught up with upstream server" +msgstr "»%s« hat jetzt den Upstream-Server eingeholt" -#: replication/walsender.c:1933 +#: replication/walsender.c:2290 #, c-format msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" msgstr "Anzahl angeforderter Standby-Verbindungen überschreitet max_wal_senders (aktuell %d)" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:967 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "Regel »%s« für Relation »%s« existiert bereits" @@ -17195,133 +18508,143 @@ msgstr "»%s« ist bereits eine Sicht" msgid "view rule for \"%s\" must be named \"%s\"" msgstr "Sicht-Regel für »%s« muss »%s« heißen" -#: rewrite/rewriteDefine.c:430 +#: rewrite/rewriteDefine.c:428 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "kann partitionierte Tabelle »%s« nicht in eine Sicht umwandeln" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "kann Partition »%s« nicht in eine Sicht umwandeln" + +#: rewrite/rewriteDefine.c:442 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie nicht leer ist" -#: rewrite/rewriteDefine.c:438 +#: rewrite/rewriteDefine.c:450 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Trigger hat" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:452 #, c-format msgid "In particular, the table cannot be involved in any foreign key relationships." msgstr "Insbesondere darf die Tabelle nicht in Fremschlüsselverhältnisse eingebunden sein." -#: rewrite/rewriteDefine.c:445 +#: rewrite/rewriteDefine.c:457 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Indexe hat" -#: rewrite/rewriteDefine.c:451 +#: rewrite/rewriteDefine.c:463 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie abgeleitete Tabellen hat" -#: rewrite/rewriteDefine.c:457 +#: rewrite/rewriteDefine.c:469 #, c-format msgid "could not convert table \"%s\" to a view because it has row security enabled" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Sicherheit auf Zeilenebene eingeschaltet hat" -#: rewrite/rewriteDefine.c:463 +#: rewrite/rewriteDefine.c:475 #, c-format msgid "could not convert table \"%s\" to a view because it has row security policies" msgstr "konnte Tabelle »%s« nicht in Sicht umwandeln, weil sie Policys für Sicherheit auf Zeilenebene hat" -#: rewrite/rewriteDefine.c:490 +#: rewrite/rewriteDefine.c:502 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "Regel kann nicht mehrere RETURNING-Listen enthalten" -#: rewrite/rewriteDefine.c:495 +#: rewrite/rewriteDefine.c:507 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "RETURNING-Listen werden in Regeln mit Bedingung nicht unterstützt" -#: rewrite/rewriteDefine.c:499 +#: rewrite/rewriteDefine.c:511 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "RETURNING-Listen werden nur in INSTEAD-Regeln unterstützt" -#: rewrite/rewriteDefine.c:664 +#: rewrite/rewriteDefine.c:675 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "Targetliste von SELECT-Regel hat zu viele Einträge" -#: rewrite/rewriteDefine.c:665 +#: rewrite/rewriteDefine.c:676 #, c-format msgid "RETURNING list has too many entries" msgstr "RETURNING-Liste hat zu viele Einträge" -#: rewrite/rewriteDefine.c:692 +#: rewrite/rewriteDefine.c:703 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "kann Relation mit gelöschten Spalten nicht in Sicht umwandeln" -#: rewrite/rewriteDefine.c:693 +#: rewrite/rewriteDefine.c:704 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "für eine Relation mit gelöschten Spalten kann keine RETURNING-Liste erzeugt werden" -#: rewrite/rewriteDefine.c:699 +#: rewrite/rewriteDefine.c:710 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "Spaltenname in Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:701 +#: rewrite/rewriteDefine.c:712 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "SELECT-Targeteintrag heißt »%s«." -#: rewrite/rewriteDefine.c:710 +#: rewrite/rewriteDefine.c:721 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "Typ von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:712 +#: rewrite/rewriteDefine.c:723 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "Eintrag %d in RETURNING-Liste hat anderen Typ als Spalte »%s«" -#: rewrite/rewriteDefine.c:715 rewrite/rewriteDefine.c:739 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "SELECT-Targeteintrag hat Typ %s, aber Spalte hat Typ %s." -#: rewrite/rewriteDefine.c:718 rewrite/rewriteDefine.c:743 +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "Eintrag in RETURNING-Liste hat Typ %s, aber Spalte hat Typ %s." -#: rewrite/rewriteDefine.c:734 +#: rewrite/rewriteDefine.c:745 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "Größe von Targeteintrag %d von SELECT-Regel unterscheidet sich von Spalte »%s«" -#: rewrite/rewriteDefine.c:736 +#: rewrite/rewriteDefine.c:747 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "Eintrag %d in RETURNING-Liste hat andere Größe als Spalte »%s«" -#: rewrite/rewriteDefine.c:753 +#: rewrite/rewriteDefine.c:764 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "Targetliste von SELECT-Regeln hat zu wenige Einträge" -#: rewrite/rewriteDefine.c:754 +#: rewrite/rewriteDefine.c:765 #, c-format msgid "RETURNING list has too few entries" msgstr "RETURNING-Liste hat zu wenige Einträge" -#: rewrite/rewriteDefine.c:846 rewrite/rewriteDefine.c:958 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 #: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "Regel »%s« für Relation »%s« existiert nicht" -#: rewrite/rewriteDefine.c:977 +#: rewrite/rewriteDefine.c:990 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "Umbenennen einer ON-SELECT-Regel ist nicht erlaubt" @@ -17336,152 +18659,167 @@ msgstr "WITH-Anfragename »%s« erscheint sowohl in der Regelaktion als auch in msgid "cannot have RETURNING lists in multiple rules" msgstr "RETURNING-Listen können nicht in mehreren Regeln auftreten" -#: rewrite/rewriteHandler.c:941 rewrite/rewriteHandler.c:959 +#: rewrite/rewriteHandler.c:823 #, c-format -msgid "multiple assignments to same column \"%s\"" -msgstr "mehrere Zuweisungen zur selben Spalte »%s«" +msgid "cannot insert into column \"%s\"" +msgstr "kann nicht in Spalte »%s« einfügen" -#: rewrite/rewriteHandler.c:1735 rewrite/rewriteHandler.c:3349 +#: rewrite/rewriteHandler.c:824 rewrite/rewriteHandler.c:839 #, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "unendliche Rekursion entdeckt in Regeln für Relation »%s«" +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "Spalte »%s« ist eine Identitätsspalte, die als GENERATED ALWAYS definiert ist." + +#: rewrite/rewriteHandler.c:826 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Verwenden Sie OVERRIDING SYSTEM VALUE, um diese Einschränkung außer Kraft zu setzen." + +#: rewrite/rewriteHandler.c:838 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "Spalte »%s« kann nur auf DEFAULT aktualisiert werden" + +#: rewrite/rewriteHandler.c:1000 rewrite/rewriteHandler.c:1018 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "mehrere Zuweisungen zur selben Spalte »%s«" -#: rewrite/rewriteHandler.c:1820 +#: rewrite/rewriteHandler.c:1921 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "unendliche Rekursion entdeckt in Policys für Relation »%s«" -#: rewrite/rewriteHandler.c:2137 +#: rewrite/rewriteHandler.c:2241 msgid "Junk view columns are not updatable." msgstr "Junk-Sichtspalten sind nicht aktualisierbar." -#: rewrite/rewriteHandler.c:2142 +#: rewrite/rewriteHandler.c:2246 msgid "View columns that are not columns of their base relation are not updatable." msgstr "Sichtspalten, die nicht Spalten ihrer Basisrelation sind, sind nicht aktualisierbar." -#: rewrite/rewriteHandler.c:2145 +#: rewrite/rewriteHandler.c:2249 msgid "View columns that refer to system columns are not updatable." msgstr "Sichtspalten, die auf Systemspalten verweisen, sind nicht aktualisierbar." -#: rewrite/rewriteHandler.c:2148 +#: rewrite/rewriteHandler.c:2252 msgid "View columns that return whole-row references are not updatable." msgstr "Sichtspalten, die Verweise auf ganze Zeilen zurückgeben, sind nicht aktualisierbar." -#: rewrite/rewriteHandler.c:2206 +#: rewrite/rewriteHandler.c:2313 msgid "Views containing DISTINCT are not automatically updatable." msgstr "Sichten, die DISTINCT enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2209 +#: rewrite/rewriteHandler.c:2316 msgid "Views containing GROUP BY are not automatically updatable." msgstr "Sichten, die GROUP BY enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2212 +#: rewrite/rewriteHandler.c:2319 msgid "Views containing HAVING are not automatically updatable." msgstr "Sichten, die HAVING enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2215 +#: rewrite/rewriteHandler.c:2322 msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "Sichten, die UNION, INTERSECT oder EXCEPT enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2218 +#: rewrite/rewriteHandler.c:2325 msgid "Views containing WITH are not automatically updatable." msgstr "Sichten, die WITH enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2221 +#: rewrite/rewriteHandler.c:2328 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "Sichten, die LIMIT oder OFFSET enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2233 +#: rewrite/rewriteHandler.c:2340 msgid "Views that return aggregate functions are not automatically updatable." msgstr "Sichten, die Aggregatfunktionen zurückgeben, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2236 +#: rewrite/rewriteHandler.c:2343 msgid "Views that return window functions are not automatically updatable." msgstr "Sichten, die Fensterfunktionen zurückgeben, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2239 +#: rewrite/rewriteHandler.c:2346 msgid "Views that return set-returning functions are not automatically updatable." msgstr "Sichten, die Funktionen mit Ergebnismenge zurückgeben, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2246 rewrite/rewriteHandler.c:2250 -#: rewrite/rewriteHandler.c:2258 +#: rewrite/rewriteHandler.c:2353 rewrite/rewriteHandler.c:2357 +#: rewrite/rewriteHandler.c:2365 msgid "Views that do not select from a single table or view are not automatically updatable." msgstr "Sichten, die nicht aus einer einzigen Tabelle oder Sicht lesen, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2261 +#: rewrite/rewriteHandler.c:2368 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "Sichten, die TABLESAMPLE enthalten, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2285 +#: rewrite/rewriteHandler.c:2392 msgid "Views that have no updatable columns are not automatically updatable." msgstr "Sichten, die keine aktualisierbaren Spalten haben, sind nicht automatisch aktualisierbar." -#: rewrite/rewriteHandler.c:2737 +#: rewrite/rewriteHandler.c:2849 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "kann nicht in Spalte »%s« von Sicht »%s« einfügen" -#: rewrite/rewriteHandler.c:2745 +#: rewrite/rewriteHandler.c:2857 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "kann Spalte »%s« von Sicht »%s« nicht aktualisieren" -#: rewrite/rewriteHandler.c:3148 +#: rewrite/rewriteHandler.c:3327 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "DO INSTEAD NOTHING-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:3162 +#: rewrite/rewriteHandler.c:3341 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "Do INSTEAD-Regeln mit Bedingung werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:3166 +#: rewrite/rewriteHandler.c:3345 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "DO ALSO-Regeln werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:3171 +#: rewrite/rewriteHandler.c:3350 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "DO INSTEAD-Regeln mit mehreren Anweisungen werden für datenmodifizierende Anweisungen in WITH nicht unterstützt" -#: rewrite/rewriteHandler.c:3386 +#: rewrite/rewriteHandler.c:3569 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "INSERT RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:3388 +#: rewrite/rewriteHandler.c:3571 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON INSERT DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:3393 +#: rewrite/rewriteHandler.c:3576 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "UPDATE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:3395 +#: rewrite/rewriteHandler.c:3578 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON UPDATE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:3400 +#: rewrite/rewriteHandler.c:3583 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "DELETE RETURNING kann in Relation »%s« nicht ausgeführt werden" -#: rewrite/rewriteHandler.c:3402 +#: rewrite/rewriteHandler.c:3585 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "Sie benötigen eine ON DELETE DO INSTEAD Regel ohne Bedingung, mit RETURNING-Klausel." -#: rewrite/rewriteHandler.c:3420 +#: rewrite/rewriteHandler.c:3603 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT mit ON-CONFLICT-Klausel kann nicht mit Tabelle verwendet werden, die INSERT- oder UPDATE-Regeln hat" -#: rewrite/rewriteHandler.c:3477 +#: rewrite/rewriteHandler.c:3660 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH kann nicht in einer Anfrage verwendet werden, die durch Regeln in mehrere Anfragen umgeschrieben wird" @@ -17496,124 +18834,124 @@ msgstr "Utility-Anweisungen mit Bedingung sind nicht implementiert" msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF mit einer Sicht ist nicht implementiert" -#: rewrite/rewriteManip.c:1434 +#: rewrite/rewriteManip.c:1503 #, c-format msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" msgstr "NEW-Variablen in ON UPDATE-Regeln können nicht auf Spalten verweisen, die Teil einer Mehrfachzuweisung in dem UPDATE-Befehl sind" -#: scan.l:432 +#: scan.l:445 msgid "unterminated /* comment" msgstr "/*-Kommentar nicht abgeschlossen" -#: scan.l:461 +#: scan.l:474 msgid "unterminated bit string literal" msgstr "Bitkettenkonstante nicht abgeschlossen" -#: scan.l:482 +#: scan.l:495 msgid "unterminated hexadecimal string literal" msgstr "hexadezimale Zeichenkette nicht abgeschlossen" -#: scan.l:532 +#: scan.l:545 #, c-format msgid "unsafe use of string constant with Unicode escapes" msgstr "unsichere Verwendung von Zeichenkette mit Unicode-Escapes" -#: scan.l:533 +#: scan.l:546 #, c-format msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." msgstr "Zeichenketten mit Unicode-Escapes können nicht verwendet werden, wenn standard_conforming_strings aus ist." -#: scan.l:579 scan.l:778 +#: scan.l:592 scan.l:791 msgid "invalid Unicode escape character" msgstr "ungültiges Unicode-Escape-Zeichen" -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1337 -#: scan.l:1364 scan.l:1368 scan.l:1406 scan.l:1410 scan.l:1432 scan.l:1442 +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 +#: scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 msgid "invalid Unicode surrogate pair" msgstr "ungültiges Unicode-Surrogatpaar" -#: scan.l:627 +#: scan.l:640 #, c-format msgid "invalid Unicode escape" msgstr "ungültiges Unicode-Escape" -#: scan.l:628 +#: scan.l:641 #, c-format msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." msgstr "Unicode-Escapes müssen \\uXXXX oder \\UXXXXXXXX sein." -#: scan.l:639 +#: scan.l:652 #, c-format msgid "unsafe use of \\' in a string literal" msgstr "unsichere Verwendung von \\' in Zeichenkettenkonstante" -#: scan.l:640 +#: scan.l:653 #, c-format msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." msgstr "Verwenden Sie '', um Quotes in Zeichenketten zu schreiben. \\' ist in bestimmten Client-seitigen Kodierungen unsicher." -#: scan.l:715 +#: scan.l:728 msgid "unterminated dollar-quoted string" msgstr "Dollar-Quotes nicht abgeschlossen" -#: scan.l:732 scan.l:758 scan.l:773 +#: scan.l:745 scan.l:771 scan.l:786 msgid "zero-length delimited identifier" msgstr "Bezeichner in Anführungszeichen hat Länge null" -#: scan.l:793 syncrep_scanner.l:87 +#: scan.l:806 syncrep_scanner.l:91 msgid "unterminated quoted identifier" msgstr "Bezeichner in Anführungszeichen nicht abgeschlossen" -#: scan.l:924 +#: scan.l:969 msgid "operator too long" msgstr "Operator zu lang" #. translator: %s is typically the translation of "syntax error" -#: scan.l:1077 +#: scan.l:1125 #, c-format msgid "%s at end of input" msgstr "%s am Ende der Eingabe" #. translator: first %s is typically the translation of "syntax error" -#: scan.l:1085 +#: scan.l:1133 #, c-format msgid "%s at or near \"%s\"" msgstr "%s bei »%s«" -#: scan.l:1251 scan.l:1283 +#: scan.l:1294 scan.l:1326 msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" msgstr "Unicode-Escape-Werte können nicht für Code-Punkt-Werte über 007F verwendet werden, wenn die Serverkodierung nicht UTF8 ist" -#: scan.l:1279 scan.l:1424 +#: scan.l:1322 scan.l:1467 msgid "invalid Unicode escape value" msgstr "ungültiger Unicode-Escape-Wert" -#: scan.l:1488 +#: scan.l:1531 #, c-format msgid "nonstandard use of \\' in a string literal" msgstr "nicht standardkonforme Verwendung von \\' in Zeichenkettenkonstante" -#: scan.l:1489 +#: scan.l:1532 #, c-format msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." msgstr "Verwenden Sie '', um Quotes in Zeichenketten zu schreiben, oder verwenden Sie die Syntax für Escape-Zeichenketten (E'...')." -#: scan.l:1498 +#: scan.l:1541 #, c-format msgid "nonstandard use of \\\\ in a string literal" msgstr "nicht standardkonforme Verwendung von \\\\ in Zeichenkettenkonstante" -#: scan.l:1499 +#: scan.l:1542 #, c-format msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." msgstr "Verwenden Sie die Syntax für Escape-Zeichenketten für Backslashes, z.B. E'\\\\'." -#: scan.l:1513 +#: scan.l:1556 #, c-format msgid "nonstandard use of escape in a string literal" msgstr "nicht standardkonforme Verwendung von Escape in Zeichenkettenkonstante" -#: scan.l:1514 +#: scan.l:1557 #, c-format msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." msgstr "Verwenden Sie die Syntax für Escape-Zeichenketten, z.B. E'\\r\\n'." @@ -17644,6 +18982,47 @@ msgstr "unbekannter Snowball-Parameter: »%s«" msgid "missing Language parameter" msgstr "Parameter »Language« fehlt" +#: statistics/dependencies.c:534 +#, c-format +msgid "invalid zero-length item array in MVDependencies" +msgstr "ungültiges Array mit Länge null in MVDependencies" + +#: statistics/dependencies.c:672 statistics/dependencies.c:725 +#: statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 +#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 +#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 +#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 +#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 +#: utils/adt/pseudotypes.c:393 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: statistics/extended_stats.c:104 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "Statistikobjekt »%s.%s« konnte für Relation »%s.%s« nicht berechnet werden" + +#: statistics/mvdistinct.c:262 +#, c-format +msgid "invalid ndistinct magic %08x (expected %08x)" +msgstr "ungültige ndistinct-Magic %08x (erwartet wurde %08x)" + +#: statistics/mvdistinct.c:267 +#, c-format +msgid "invalid ndistinct type %d (expected %d)" +msgstr "ungültiger ndistinct-Typ %d (erwartet wurde %d)" + +#: statistics/mvdistinct.c:272 +#, c-format +msgid "invalid zero-length item array in MVNDistinct" +msgstr "ungültiges Array mit Länge null in MVNDistinct" + +#: statistics/mvdistinct.c:281 +#, c-format +msgid "invalid MVNDistinct size %zd (expected at least %zd)" +msgstr "ungültige MVNDistinct-Größe %zd (erwartet wurde mindestens %zd)" + #: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 #, c-format msgid "cannot access temporary tables of other sessions" @@ -17664,22 +19043,22 @@ msgstr "Das scheint mit fehlerhaften Kernels vorzukommen; Sie sollten eine Syste msgid "invalid page in block %u of relation %s; zeroing out page" msgstr "ungültige Seite in Block %u von Relation %s; fülle Seite mit Nullen" -#: storage/buffer/bufmgr.c:3996 +#: storage/buffer/bufmgr.c:4013 #, c-format msgid "could not write block %u of %s" msgstr "konnte Block %u von %s nicht schreiben" -#: storage/buffer/bufmgr.c:3998 +#: storage/buffer/bufmgr.c:4015 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "Mehrere Fehlschläge --- Schreibfehler ist möglicherweise dauerhaft." -#: storage/buffer/bufmgr.c:4019 storage/buffer/bufmgr.c:4038 +#: storage/buffer/bufmgr.c:4036 storage/buffer/bufmgr.c:4055 #, c-format msgid "writing block %u of relation %s" msgstr "schreibe Block %u von Relation %s" -#: storage/buffer/bufmgr.c:4339 +#: storage/buffer/bufmgr.c:4358 #, c-format msgid "snapshot too old" msgstr "Snapshot zu alt" @@ -17694,189 +19073,239 @@ msgstr "kein leerer lokaler Puffer verfügbar" msgid "cannot access temporary tables during a parallel operation" msgstr "während einer parallelen Operation kann nicht auf temporäre Tabellen zugegriffen werden" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: storage/file/buffile.c:317 +#, fuzzy, c-format +#| msgid "could not open temporary file \"%s\": %s\n" +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %s\n" + +#: storage/file/buffile.c:814 +#, fuzzy, c-format +#| msgid "could not open temporary file \"%s\": %s\n" +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %s\n" + +#: storage/file/fd.c:451 storage/file/fd.c:523 storage/file/fd.c:559 #, c-format msgid "could not flush dirty data: %m" msgstr "konnte schmutzige Daten nicht flushen: %m" -#: storage/file/fd.c:473 +#: storage/file/fd.c:481 #, c-format msgid "could not determine dirty data size: %m" msgstr "konnte Größe der schmutzigen Daten nicht bestimmen: %m" -#: storage/file/fd.c:525 +#: storage/file/fd.c:533 #, c-format msgid "could not munmap() while flushing data: %m" msgstr "munmap() fehlgeschlagen beim Flushen von Daten: %m" -#: storage/file/fd.c:689 +#: storage/file/fd.c:734 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "konnte Datei »%s« nicht nach »%s« linken: %m" -#: storage/file/fd.c:783 +#: storage/file/fd.c:828 #, c-format msgid "getrlimit failed: %m" msgstr "getrlimit fehlgeschlagen: %m" -#: storage/file/fd.c:873 +#: storage/file/fd.c:918 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "nicht genug Dateideskriptoren verfügbar, um Serverprozess zu starten" -#: storage/file/fd.c:874 +#: storage/file/fd.c:919 #, c-format msgid "System allows %d, we need at least %d." msgstr "System erlaubt %d, wir benötigen mindestens %d." -#: storage/file/fd.c:915 storage/file/fd.c:2078 storage/file/fd.c:2171 -#: storage/file/fd.c:2319 +#: storage/file/fd.c:970 storage/file/fd.c:2379 storage/file/fd.c:2489 +#: storage/file/fd.c:2640 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "keine Dateideskriptoren mehr: %m; freigeben und nochmal versuchen" -#: storage/file/fd.c:1520 +#: storage/file/fd.c:1313 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "temporäre Datei: Pfad »%s«, Größe %lu" -#: storage/file/fd.c:1717 +#: storage/file/fd.c:1445 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "konnte temporäres Verzeichnis »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1452 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "konnte temporäres Unterverzeichnis »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1645 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht erzeugen: %m" + +#: storage/file/fd.c:1680 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %m" + +#: storage/file/fd.c:1721 +#, fuzzy, c-format +#| msgid "could not open temporary file \"%s\": %s\n" +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "konnte temporäre Datei »%s« nicht öffnen: %s\n" + +#: storage/file/fd.c:2010 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "Größe der temporären Datei überschreitet temp_file_limit (%dkB)" -#: storage/file/fd.c:2054 storage/file/fd.c:2104 +#: storage/file/fd.c:2355 storage/file/fd.c:2414 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, die Datei »%s« zu öffnen" -#: storage/file/fd.c:2144 +#: storage/file/fd.c:2459 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, den Befehl »%s« auszuführen" -#: storage/file/fd.c:2295 +#: storage/file/fd.c:2616 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "maxAllocatedDescs (%d) überschritten beim Versuch, das Verzeichnis »%s« zu öffnen" -#: storage/file/fd.c:2381 +#: storage/file/fd.c:2707 #, c-format msgid "could not read directory \"%s\": %m" msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: storage/ipc/dsm.c:364 +#: storage/file/fd.c:3139 +#, fuzzy, c-format +#| msgid "could not locate temporary directory: %s\n" +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "konnte temporäres Verzeichnis nicht finden: %s\n" + +#: storage/file/fd.c:3461 +#, fuzzy, c-format +#| msgid "could not read directory \"%s\": %m" +msgid "could not rmdir directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" + +#: storage/file/sharedfileset.c:93 +#, fuzzy, c-format +#| msgid "could not attach to dynamic shared area" +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "konnte nicht an dynamische Shared Area anbinden" + +#: storage/ipc/dsm.c:351 #, c-format msgid "dynamic shared memory control segment is corrupt" msgstr "Kontrollsegment von dynamischem Shared Memory ist verfälscht" -#: storage/ipc/dsm.c:411 +#: storage/ipc/dsm.c:398 #, c-format msgid "dynamic shared memory is disabled" msgstr "dynamisches Shared-Memory ist abgeschaltet" -#: storage/ipc/dsm.c:412 +#: storage/ipc/dsm.c:399 #, c-format msgid "Set dynamic_shared_memory_type to a value other than \"none\"." msgstr "Setzen Sie dynamic_shared_memory_type auf einen anderen Wert als »none«." -#: storage/ipc/dsm.c:432 +#: storage/ipc/dsm.c:419 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "Kontrollsegment von dynamischem Shared Memory ist ungültig" -#: storage/ipc/dsm.c:521 +#: storage/ipc/dsm.c:515 #, c-format msgid "too many dynamic shared memory segments" msgstr "zu viele dynamische Shared-Memory-Segmente" -#: storage/ipc/dsm_impl.c:260 storage/ipc/dsm_impl.c:360 -#: storage/ipc/dsm_impl.c:532 storage/ipc/dsm_impl.c:647 -#: storage/ipc/dsm_impl.c:818 storage/ipc/dsm_impl.c:960 +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 +#: storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 +#: storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "konnte Shared-Memory-Segment »%s« nicht unmappen: %m" -#: storage/ipc/dsm_impl.c:270 storage/ipc/dsm_impl.c:542 -#: storage/ipc/dsm_impl.c:657 storage/ipc/dsm_impl.c:828 +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 +#: storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "konnte Shared-Memory-Segment »%s« nicht entfernen: %m" -#: storage/ipc/dsm_impl.c:291 storage/ipc/dsm_impl.c:728 -#: storage/ipc/dsm_impl.c:842 +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 +#: storage/ipc/dsm_impl.c:904 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "konnte Shared-Memory-Segment »%s« nicht öffnen: %m" -#: storage/ipc/dsm_impl.c:315 storage/ipc/dsm_impl.c:558 -#: storage/ipc/dsm_impl.c:773 storage/ipc/dsm_impl.c:866 +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 +#: storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "konnte »stat« für Shared-Memory-Segment »%s« nicht ausführen: %m" -#: storage/ipc/dsm_impl.c:334 storage/ipc/dsm_impl.c:885 -#: storage/ipc/dsm_impl.c:933 +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 +#: storage/ipc/dsm_impl.c:997 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "konnte Größe des Shared-Memory-Segments »%s« nicht auf %zu Bytes ändern: %m" -#: storage/ipc/dsm_impl.c:384 storage/ipc/dsm_impl.c:579 -#: storage/ipc/dsm_impl.c:749 storage/ipc/dsm_impl.c:984 +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 +#: storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "konnte Shared-Memory-Segment »%s« nicht mappen: %m" -#: storage/ipc/dsm_impl.c:514 +#: storage/ipc/dsm_impl.c:576 #, c-format msgid "could not get shared memory segment: %m" msgstr "konnte Shared-Memory-Segment nicht finden: %m" -#: storage/ipc/dsm_impl.c:713 +#: storage/ipc/dsm_impl.c:775 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "konnte Shared-Memory-Segment »%s« nicht erzeugen: %m" -#: storage/ipc/dsm_impl.c:1026 storage/ipc/dsm_impl.c:1074 +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 #, c-format msgid "could not duplicate handle for \"%s\": %m" msgstr "konnte Handle für »%s« nicht duplizieren: %m" -#: storage/ipc/latch.c:780 +#: storage/ipc/latch.c:829 #, c-format msgid "epoll_ctl() failed: %m" msgstr "epoll_ctl() fehlgeschlagen: %m" -#: storage/ipc/latch.c:1009 +#: storage/ipc/latch.c:1060 #, c-format msgid "epoll_wait() failed: %m" msgstr "epoll_wait() fehlgeschlagen: %m" -#: storage/ipc/latch.c:1129 +#: storage/ipc/latch.c:1182 #, c-format msgid "poll() failed: %m" msgstr "poll() fehlgeschlagen: %m" -#: storage/ipc/latch.c:1287 -#, c-format -msgid "select() failed: %m" -msgstr "select() fehlgeschlagen: %m" - -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:189 storage/lmgr/lock.c:883 -#: storage/lmgr/lock.c:917 storage/lmgr/lock.c:2679 storage/lmgr/lock.c:4004 -#: storage/lmgr/lock.c:4069 storage/lmgr/lock.c:4361 -#: storage/lmgr/predicate.c:2318 storage/lmgr/predicate.c:2333 -#: storage/lmgr/predicate.c:3725 storage/lmgr/predicate.c:4868 -#: utils/hash/dynahash.c:1043 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 +#: storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 +#: storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 +#: storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 +#: storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "Shared Memory aufgebraucht" #: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 -#, fuzzy, c-format -#| msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +#, c-format msgid "out of shared memory (%zu bytes requested)" -msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zu Bytes angefordert)" +msgstr "Shared Memory aufgebraucht (%zu Bytes angefordert)" #: storage/ipc/shmem.c:421 #, c-format @@ -17898,32 +19327,32 @@ msgstr "nicht genug Shared-Memory für Datenstruktur »%s« (%zu Bytes angeforde msgid "requested shared memory size overflows size_t" msgstr "angeforderte Shared-Memory-Größe übersteigt Kapazität von size_t" -#: storage/ipc/standby.c:531 tcop/postgres.c:2964 +#: storage/ipc/standby.c:558 tcop/postgres.c:3056 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "storniere Anfrage wegen Konflikt mit der Wiederherstellung" -#: storage/ipc/standby.c:532 tcop/postgres.c:2271 +#: storage/ipc/standby.c:559 tcop/postgres.c:2329 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "Benutzertransaktion hat Verklemmung (Deadlock) mit Wiederherstellung verursacht." -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:190 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "pg_largeobject-Eintrag für OID %u, Seite %d hat ungültige Datenfeldgröße %d" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:271 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "ungültige Flags zum Öffnen eines Large Objects: %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:461 #, c-format msgid "invalid whence setting: %d" msgstr "ungültige »whence«-Angabe: %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:633 #, c-format msgid "invalid large object write request size: %d" msgstr "ungültige Größe der Large-Object-Schreibaufforderung: %d" @@ -17948,238 +19377,228 @@ msgstr "Verklemmung (Deadlock) entdeckt" msgid "See server log for query details." msgstr "Einzelheiten zur Anfrage finden Sie im Serverlog." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:767 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "beim Aktualisieren von Tupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:770 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "beim Löschen von Tupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:773 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "beim Sperren von Tupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:776 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "beim Sperren von aktualisierter Version (%u,%u) von Tupel in Relation »%s«" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:779 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "beim Einfügen von Indextupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:782 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "beim Prüfen der Eindeutigkeit von Tupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:785 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "beim erneuten Prüfen des aktualisierten Tupels (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:788 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" msgstr "beim Prüfen eines Exclusion-Constraints für Tupel (%u,%u) in Relation »%s«" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1008 #, c-format msgid "relation %u of database %u" msgstr "Relation %u der Datenbank %u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1014 #, c-format msgid "extension of relation %u of database %u" msgstr "Erweiterung von Relation %u in Datenbank %u" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1020 #, c-format msgid "page %u of relation %u of database %u" msgstr "Seite %u von Relation %u von Datenbank %u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1027 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "Tupel (%u, %u) von Relation %u von Datenbank %u" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1035 #, c-format msgid "transaction %u" msgstr "Transaktion %u" -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1040 #, c-format msgid "virtual transaction %d/%u" msgstr "virtuelle Transaktion %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1046 #, c-format msgid "speculative token %u of transaction %u" msgstr "spekulatives Token %u von Transaktion %u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1052 #, c-format msgid "object %u of class %u of database %u" msgstr "Objekt %u von Klasse %u von Datenbank %u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1060 #, c-format msgid "user lock [%u,%u,%u]" msgstr "Benutzersperre [%u,%u,%u]" -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1067 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "Benutzersperre [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1075 #, c-format msgid "unrecognized locktag type %d" msgstr "unbekannter Locktag-Typ %d" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:740 #, c-format msgid "cannot acquire lock mode %s on database objects while recovery is in progress" msgstr "Sperrmodus %s kann während der Wiederherstellung nicht auf Datenbankobjekte gesetzt werden" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:742 #, c-format msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "Nur Sperren gleich oder unter RowExclusiveLock können während der Wiederherstellung auf Datenbankobjekte gesetzt werden." -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2680 -#: storage/lmgr/lock.c:4005 storage/lmgr/lock.c:4070 storage/lmgr/lock.c:4362 +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 +#: storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "Sie müssen möglicherweise max_locks_per_transaction erhöhen." -#: storage/lmgr/lock.c:3121 storage/lmgr/lock.c:3237 +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 #, c-format msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "PREPARE kann nicht ausgeführt werden, wenn für das selbe Objekt Sperren auf Sitzungsebene und auf Transaktionsebene gehalten werden" -#: storage/lmgr/predicate.c:676 +#: storage/lmgr/predicate.c:682 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "nicht genügend Elemente in RWConflictPool, um einen Lese-/Schreibkonflikt aufzuzeichnen" -#: storage/lmgr/predicate.c:677 storage/lmgr/predicate.c:705 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "Sie müssten entweder weniger Transaktionen auf einmal ausführen oder max_connections erhöhen." -#: storage/lmgr/predicate.c:704 +#: storage/lmgr/predicate.c:710 #, c-format msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "nicht genügend Elemente in RWConflictPool, um einen möglichen Lese-/Schreibkonflikt aufzuzeichnen" -#: storage/lmgr/predicate.c:910 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "Speicher für die Verfolgung von Serialisierungskonflikten ist fast aufgebraucht" - -#: storage/lmgr/predicate.c:911 -#, c-format -msgid "There might be an idle transaction or a forgotten prepared transaction causing this." -msgstr "Möglicherweise gibt es eine stillliegende Transaktion oder eine vergessene vorbereitete Transaktion, die der Grund dafür ist." - -#: storage/lmgr/predicate.c:1538 +#: storage/lmgr/predicate.c:1515 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "aufschiebbarer Snapshot war unsicher; versuche einen neuen" -#: storage/lmgr/predicate.c:1577 +#: storage/lmgr/predicate.c:1604 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "»default_transaction_isolation« ist auf »serializable« gesetzt." -#: storage/lmgr/predicate.c:1578 +#: storage/lmgr/predicate.c:1605 #, c-format msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." msgstr "Mit »SET default_transaction_isolation = 'repeatable read'« können Sie die Voreinstellung ändern." -#: storage/lmgr/predicate.c:1617 +#: storage/lmgr/predicate.c:1645 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "eine Transaktion, die einen Snapshot importiert, must READ ONLY DEFERRABLE sein" -#: storage/lmgr/predicate.c:1695 utils/time/snapmgr.c:617 -#: utils/time/snapmgr.c:623 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 +#: utils/time/snapmgr.c:627 #, c-format msgid "could not import the requested snapshot" msgstr "konnte den angeforderten Snapshot nicht importieren" -#: storage/lmgr/predicate.c:1696 utils/time/snapmgr.c:624 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "Die Quelltransaktion %u läuft nicht mehr." +msgid "The source process with PID %d is not running anymore." +msgstr "Der Ausgangsprozess mit PID %d läuft nicht mehr." -#: storage/lmgr/predicate.c:2319 storage/lmgr/predicate.c:2334 -#: storage/lmgr/predicate.c:3726 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 +#: storage/lmgr/predicate.c:3763 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "Sie müssen möglicherweise max_pred_locks_per_transaction erhöhen." -#: storage/lmgr/predicate.c:3880 storage/lmgr/predicate.c:3969 -#: storage/lmgr/predicate.c:3977 storage/lmgr/predicate.c:4016 -#: storage/lmgr/predicate.c:4255 storage/lmgr/predicate.c:4592 -#: storage/lmgr/predicate.c:4604 storage/lmgr/predicate.c:4646 -#: storage/lmgr/predicate.c:4684 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 +#: storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 +#: storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 +#: storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 +#: storage/lmgr/predicate.c:4721 #, c-format msgid "could not serialize access due to read/write dependencies among transactions" msgstr "konnte Zugriff nicht serialisieren wegen Lese-/Schreib-Abhängigkeiten zwischen Transaktionen" -#: storage/lmgr/predicate.c:3882 storage/lmgr/predicate.c:3971 -#: storage/lmgr/predicate.c:3979 storage/lmgr/predicate.c:4018 -#: storage/lmgr/predicate.c:4257 storage/lmgr/predicate.c:4594 -#: storage/lmgr/predicate.c:4606 storage/lmgr/predicate.c:4648 -#: storage/lmgr/predicate.c:4686 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 +#: storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 +#: storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 +#: storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 +#: storage/lmgr/predicate.c:4723 #, c-format msgid "The transaction might succeed if retried." msgstr "Die Transaktion könnte erfolgreich sein, wenn sie erneut versucht würde." -#: storage/lmgr/proc.c:1273 +#: storage/lmgr/proc.c:1318 #, c-format msgid "Process %d waits for %s on %s." msgstr "Prozess %d wartet auf %s-Sperre auf %s." -#: storage/lmgr/proc.c:1284 +#: storage/lmgr/proc.c:1329 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "sende Stornierung an blockierende Autovacuum-PID %d" -#: storage/lmgr/proc.c:1302 utils/adt/misc.c:269 +#: storage/lmgr/proc.c:1347 utils/adt/misc.c:270 #, c-format msgid "could not send signal to process %d: %m" msgstr "konnte Signal nicht an Prozess %d senden: %m" -#: storage/lmgr/proc.c:1404 +#: storage/lmgr/proc.c:1449 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "Prozess %d vermied Verklemmung wegen %s-Sperre auf %s durch Umordnen der Queue nach %ld,%03d ms" -#: storage/lmgr/proc.c:1419 +#: storage/lmgr/proc.c:1464 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "Prozess %d hat Verklemmung festgestellt beim Warten auf %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1428 +#: storage/lmgr/proc.c:1473 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "Prozess %d wartet immer noch auf %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1435 +#: storage/lmgr/proc.c:1480 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "Prozess %d erlangte %s-Sperre auf %s nach %ld,%03d ms" -#: storage/lmgr/proc.c:1451 +#: storage/lmgr/proc.c:1496 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "Prozess %d konnte %s-Sperre auf %s nach %ld,%03d ms nicht erlangen" @@ -18189,466 +19608,485 @@ msgstr "Prozess %d konnte %s-Sperre auf %s nach %ld,%03d ms nicht erlangen" msgid "page verification failed, calculated checksum %u but expected %u" msgstr "Seitenüberprüfung fehlgeschlagen, berechnete Prüfsumme %u, aber erwartet %u" -#: storage/page/bufpage.c:213 storage/page/bufpage.c:505 -#: storage/page/bufpage.c:748 storage/page/bufpage.c:881 -#: storage/page/bufpage.c:977 storage/page/bufpage.c:1087 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 +#: storage/page/bufpage.c:744 storage/page/bufpage.c:877 +#: storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "verfälschte Seitenzeiger: lower = %u, upper = %u, special = %u" -#: storage/page/bufpage.c:549 +#: storage/page/bufpage.c:529 #, c-format msgid "corrupted item pointer: %u" msgstr "verfälschter Item-Zeiger: %u" -#: storage/page/bufpage.c:560 storage/page/bufpage.c:932 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "verfälschte Item-Längen: gesamt %u, verfügbarer Platz %u" -#: storage/page/bufpage.c:767 storage/page/bufpage.c:905 -#: storage/page/bufpage.c:993 storage/page/bufpage.c:1103 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 +#: storage/page/bufpage.c:1099 #, c-format msgid "corrupted item pointer: offset = %u, size = %u" msgstr "verfälschter Item-Zeiger: offset = %u, size = %u" -#: storage/smgr/md.c:447 storage/smgr/md.c:973 +#: storage/page/bufpage.c:901 +#, c-format +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "verfälschter Item-Zeiger: offset = %u, length = %u" + +#: storage/smgr/md.c:448 storage/smgr/md.c:974 #, c-format msgid "could not truncate file \"%s\": %m" msgstr "kann Datei »%s« nicht kürzen: %m" -#: storage/smgr/md.c:514 +#: storage/smgr/md.c:515 #, c-format msgid "cannot extend file \"%s\" beyond %u blocks" msgstr "kann Datei »%s« nicht auf über %u Blöcke erweitern" # XXX -#: storage/smgr/md.c:536 storage/smgr/md.c:753 storage/smgr/md.c:829 +#: storage/smgr/md.c:537 storage/smgr/md.c:754 storage/smgr/md.c:830 #, c-format msgid "could not seek to block %u in file \"%s\": %m" msgstr "konnte Positionszeiger nicht auf Block %u in Datei »%s« setzen: %m" -#: storage/smgr/md.c:544 +#: storage/smgr/md.c:545 #, c-format msgid "could not extend file \"%s\": %m" msgstr "konnte Datei »%s« nicht erweitern: %m" -#: storage/smgr/md.c:546 storage/smgr/md.c:553 storage/smgr/md.c:856 +#: storage/smgr/md.c:547 storage/smgr/md.c:554 storage/smgr/md.c:857 #, c-format msgid "Check free disk space." msgstr "Prüfen Sie den freien Festplattenplatz." -#: storage/smgr/md.c:550 +#: storage/smgr/md.c:551 #, c-format msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" msgstr "konnte Datei »%s« nicht erweitern: es wurden nur %d von %d Bytes bei Block %u geschrieben" -#: storage/smgr/md.c:771 +#: storage/smgr/md.c:772 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "konnte Block %u in Datei »%s« nicht lesen: %m" -#: storage/smgr/md.c:787 +#: storage/smgr/md.c:788 #, c-format msgid "could not read block %u in file \"%s\": read only %d of %d bytes" msgstr "konnte Block %u in Datei »%s« nicht lesen: es wurden nur %d von %d Bytes gelesen" -#: storage/smgr/md.c:847 +#: storage/smgr/md.c:848 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "konnte Block %u in Datei »%s« nicht schreiben: %m" -#: storage/smgr/md.c:852 +#: storage/smgr/md.c:853 #, c-format msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" msgstr "konnte Block %u in Datei »%s« nicht schreiben: es wurden nur %d von %d Bytes geschrieben" -#: storage/smgr/md.c:944 +#: storage/smgr/md.c:945 #, c-format msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" msgstr "konnte Datei »%s« nicht auf %u Blöcke kürzen: es sind jetzt nur %u Blöcke" -#: storage/smgr/md.c:999 +#: storage/smgr/md.c:1000 #, c-format msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "konnte Datei »%s« nicht auf %u Blöcke kürzen: %m" -#: storage/smgr/md.c:1281 +#: storage/smgr/md.c:1295 #, c-format msgid "could not fsync file \"%s\" but retrying: %m" msgstr "konnte Datei »%s« nicht fsyncen, versuche erneut: %m" -#: storage/smgr/md.c:1444 +#: storage/smgr/md.c:1458 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "konnte fsync-Anfrage nicht weiterleiten, weil Anfrageschlange voll ist" -#: storage/smgr/md.c:1913 +#: storage/smgr/md.c:1964 #, c-format msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" msgstr "konnte Datei »%s« nicht öffnen (Zielblock %u): vorhergehendes Segment hat nur %u Blöcke" -#: storage/smgr/md.c:1927 +#: storage/smgr/md.c:1978 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "konnte Datei »%s« nicht öffnen (Zielblock %u): %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:475 tcop/fastpath.c:605 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" msgstr "ungültige Argumentgröße %d in Funktionsaufruf-Message" -#: tcop/fastpath.c:291 tcop/postgres.c:999 tcop/postgres.c:1308 -#: tcop/postgres.c:1567 tcop/postgres.c:1972 tcop/postgres.c:2339 -#: tcop/postgres.c:2414 -#, c-format -msgid "current transaction is aborted, commands ignored until end of transaction block" -msgstr "aktuelle Transaktion wurde abgebrochen, Befehle werden bis zum Ende der Transaktion ignoriert" - -#: tcop/fastpath.c:319 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "Fastpath-Funktionsaufruf: »%s« (OID %u)" -#: tcop/fastpath.c:401 tcop/postgres.c:1170 tcop/postgres.c:1433 -#: tcop/postgres.c:1813 tcop/postgres.c:2030 +#: tcop/fastpath.c:389 tcop/postgres.c:1218 tcop/postgres.c:1482 +#: tcop/postgres.c:1864 tcop/postgres.c:2085 #, c-format msgid "duration: %s ms" msgstr "Dauer: %s ms" -#: tcop/fastpath.c:405 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "Dauer: %s ms Fastpath-Funktionsaufruf: »%s« (OID %u)" -#: tcop/fastpath.c:443 tcop/fastpath.c:570 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "Funktionsaufruf-Message enthält %d Argumente, aber Funktion benötigt %d" -#: tcop/fastpath.c:451 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "Funktionsaufruf-Message enthält %d Argumentformate aber %d Argumente" -#: tcop/fastpath.c:538 tcop/fastpath.c:621 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "falsches Binärdatenformat in Funktionsargument %d" -#: tcop/postgres.c:352 tcop/postgres.c:388 tcop/postgres.c:415 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "unerwartetes EOF auf Client-Verbindung" -#: tcop/postgres.c:438 tcop/postgres.c:450 tcop/postgres.c:461 -#: tcop/postgres.c:473 tcop/postgres.c:4304 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4408 #, c-format msgid "invalid frontend message type %d" msgstr "ungültiger Frontend-Message-Typ %d" -#: tcop/postgres.c:940 +#: tcop/postgres.c:973 #, c-format msgid "statement: %s" msgstr "Anweisung: %s" -#: tcop/postgres.c:1175 +#: tcop/postgres.c:1223 #, c-format msgid "duration: %s ms statement: %s" msgstr "Dauer: %s ms Anweisung: %s" -#: tcop/postgres.c:1225 +#: tcop/postgres.c:1273 #, c-format msgid "parse %s: %s" msgstr "Parsen %s: %s" -#: tcop/postgres.c:1281 +#: tcop/postgres.c:1330 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "kann nicht mehrere Befehle in vorbereitete Anweisung einfügen" -#: tcop/postgres.c:1438 +#: tcop/postgres.c:1487 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "Dauer: %s ms Parsen %s: %s" -#: tcop/postgres.c:1483 +#: tcop/postgres.c:1532 #, c-format msgid "bind %s to %s" msgstr "Binden %s an %s" -#: tcop/postgres.c:1502 tcop/postgres.c:2320 +#: tcop/postgres.c:1551 tcop/postgres.c:2377 #, c-format msgid "unnamed prepared statement does not exist" msgstr "unbenannte vorbereitete Anweisung existiert nicht" -#: tcop/postgres.c:1544 +#: tcop/postgres.c:1594 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "Binden-Nachricht hat %d Parameterformate aber %d Parameter" -#: tcop/postgres.c:1550 +#: tcop/postgres.c:1600 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "Binden-Nachricht enthält %d Parameter, aber vorbereitete Anweisung »%s« erfordert %d" -#: tcop/postgres.c:1720 +#: tcop/postgres.c:1771 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "falsches Binärdatenformat in Binden-Parameter %d" -#: tcop/postgres.c:1818 +#: tcop/postgres.c:1869 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "Dauer: %s ms Binden %s%s%s: %s" -#: tcop/postgres.c:1866 tcop/postgres.c:2400 +#: tcop/postgres.c:1917 tcop/postgres.c:2461 #, c-format msgid "portal \"%s\" does not exist" msgstr "Portal »%s« existiert nicht" -#: tcop/postgres.c:1951 +#: tcop/postgres.c:2002 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1953 tcop/postgres.c:2038 +#: tcop/postgres.c:2004 tcop/postgres.c:2093 msgid "execute fetch from" msgstr "Ausführen Fetch von" -#: tcop/postgres.c:1954 tcop/postgres.c:2039 +#: tcop/postgres.c:2005 tcop/postgres.c:2094 msgid "execute" msgstr "Ausführen" -#: tcop/postgres.c:2035 +#: tcop/postgres.c:2090 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "Dauer: %s ms %s %s%s%s: %s" -#: tcop/postgres.c:2161 +#: tcop/postgres.c:2216 #, c-format msgid "prepare: %s" msgstr "Vorbereiten: %s" -#: tcop/postgres.c:2224 +#: tcop/postgres.c:2282 #, c-format msgid "parameters: %s" msgstr "Parameter: %s" -#: tcop/postgres.c:2243 +#: tcop/postgres.c:2301 #, c-format msgid "abort reason: recovery conflict" msgstr "Abbruchgrund: Konflikt bei Wiederherstellung" -#: tcop/postgres.c:2259 +#: tcop/postgres.c:2317 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "Benutzer hat Shared-Buffer-Pin zu lange gehalten." -#: tcop/postgres.c:2262 +#: tcop/postgres.c:2320 #, c-format msgid "User was holding a relation lock for too long." msgstr "Benutzer hat Relationssperre zu lange gehalten." -#: tcop/postgres.c:2265 +#: tcop/postgres.c:2323 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "Benutzer hat (möglicherweise) einen Tablespace verwendet, der gelöscht werden muss." -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2326 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "Benutzeranfrage hat möglicherweise Zeilenversionen sehen müssen, die entfernt werden müssen." -#: tcop/postgres.c:2274 +#: tcop/postgres.c:2332 #, c-format msgid "User was connected to a database that must be dropped." msgstr "Benutzer war mit einer Datenbank verbunden, die gelöscht werden muss." -#: tcop/postgres.c:2583 +#: tcop/postgres.c:2657 #, c-format msgid "terminating connection because of crash of another server process" msgstr "Verbindung wird abgebrochen wegen Absturz eines anderen Serverprozesses" -#: tcop/postgres.c:2584 +#: tcop/postgres.c:2658 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "Der Postmaster hat diesen Serverprozess angewiesen, die aktuelle Transaktion zurückzurollen und die Sitzung zu beenden, weil ein anderer Serverprozess abnormal beendet wurde und möglicherweise das Shared Memory verfälscht hat." -#: tcop/postgres.c:2588 tcop/postgres.c:2892 +#: tcop/postgres.c:2662 tcop/postgres.c:2986 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "In einem Moment sollten Sie wieder mit der Datenbank verbinden und Ihren Befehl wiederholen können." -#: tcop/postgres.c:2674 +#: tcop/postgres.c:2744 #, c-format msgid "floating-point exception" msgstr "Fließkommafehler" -#: tcop/postgres.c:2675 +#: tcop/postgres.c:2745 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "Eine ungültige Fließkommaoperation wurde signalisiert. Das bedeutet wahrscheinlich ein Ergebnis außerhalb des gültigen Bereichs oder eine ungültige Operation, zum Beispiel Division durch null." -#: tcop/postgres.c:2837 +#: tcop/postgres.c:2916 #, c-format msgid "canceling authentication due to timeout" msgstr "storniere Authentifizierung wegen Zeitüberschreitung" -#: tcop/postgres.c:2841 +#: tcop/postgres.c:2920 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "Autovacuum-Prozess wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:2847 tcop/postgres.c:2857 tcop/postgres.c:2890 +#: tcop/postgres.c:2924 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "Arbeitsprozess für logische Replikation wird abgebrochen aufgrund von Anweisung des Administrators" + +#: tcop/postgres.c:2928 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "Logical-Replication-Launcher fährt herunter" + +#: tcop/postgres.c:2941 tcop/postgres.c:2951 tcop/postgres.c:2984 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "Verbindung wird abgebrochen wegen Konflikt mit der Wiederherstellung" -#: tcop/postgres.c:2863 +#: tcop/postgres.c:2957 #, c-format msgid "terminating connection due to administrator command" msgstr "Verbindung wird abgebrochen aufgrund von Anweisung des Administrators" -#: tcop/postgres.c:2873 +#: tcop/postgres.c:2967 #, c-format msgid "connection to client lost" msgstr "Verbindung zum Client wurde verloren" -#: tcop/postgres.c:2941 +#: tcop/postgres.c:3033 #, c-format msgid "canceling statement due to lock timeout" msgstr "storniere Anfrage wegen Zeitüberschreitung einer Sperre" -#: tcop/postgres.c:2948 +#: tcop/postgres.c:3040 #, c-format msgid "canceling statement due to statement timeout" msgstr "storniere Anfrage wegen Zeitüberschreitung der Anfrage" -#: tcop/postgres.c:2955 +#: tcop/postgres.c:3047 #, c-format msgid "canceling autovacuum task" msgstr "storniere Autovacuum-Aufgabe" -#: tcop/postgres.c:2978 +#: tcop/postgres.c:3070 #, c-format msgid "canceling statement due to user request" msgstr "storniere Anfrage wegen Benutzeraufforderung" -#: tcop/postgres.c:2988 +#: tcop/postgres.c:3080 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "Verbindung wird abgebrochen wegen Zeitüberschreitung in inaktiver Transaktion" -#: tcop/postgres.c:3102 +#: tcop/postgres.c:3194 #, c-format msgid "stack depth limit exceeded" msgstr "Grenze für Stacktiefe überschritten" -#: tcop/postgres.c:3103 +#: tcop/postgres.c:3195 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "Erhöhen Sie den Konfigurationsparameter »max_stack_depth« (aktuell %dkB), nachdem Sie sichergestellt haben, dass die Stacktiefenbegrenzung Ihrer Plattform ausreichend ist." -#: tcop/postgres.c:3166 +#: tcop/postgres.c:3258 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "»max_stack_depth« darf %ldkB nicht überschreiten." -#: tcop/postgres.c:3168 +#: tcop/postgres.c:3260 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "Erhöhen Sie die Stacktiefenbegrenzung Ihrer Plattform mit »ulimit -s« oder der lokalen Entsprechung." -#: tcop/postgres.c:3528 +#: tcop/postgres.c:3620 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "ungültiges Kommandozeilenargument für Serverprozess: %s" -#: tcop/postgres.c:3529 tcop/postgres.c:3535 +#: tcop/postgres.c:3621 tcop/postgres.c:3627 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Versuchen Sie »%s --help« für weitere Informationen." -#: tcop/postgres.c:3533 +#: tcop/postgres.c:3625 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: ungültiges Kommandozeilenargument: %s" -#: tcop/postgres.c:3595 +#: tcop/postgres.c:3687 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: weder Datenbankname noch Benutzername angegeben" -#: tcop/postgres.c:4212 +#: tcop/postgres.c:4316 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "ungültiger Subtyp %d von CLOSE-Message" -#: tcop/postgres.c:4247 +#: tcop/postgres.c:4351 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "ungültiger Subtyp %d von DESCRIBE-Message" -#: tcop/postgres.c:4325 +#: tcop/postgres.c:4429 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "Fastpath-Funktionsaufrufe werden auf einer Replikationsverbindung nicht unterstützt" -#: tcop/postgres.c:4329 +#: tcop/postgres.c:4433 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "erweitertes Anfrageprotokoll wird nicht auf einer Replikationsverbindung unterstützt" -#: tcop/postgres.c:4499 +#: tcop/postgres.c:4610 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "Verbindungsende: Sitzungszeit: %d:%02d:%02d.%03d Benutzer=%s Datenbank=%s Host=%s%s%s" -#: tcop/pquery.c:638 +#: tcop/pquery.c:645 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "Bind-Message hat %d Ergebnisspalten, aber Anfrage hat %d Spalten" -#: tcop/pquery.c:940 +#: tcop/pquery.c:952 #, c-format msgid "cursor can only scan forward" msgstr "Cursor kann nur vorwärts scannen" -#: tcop/pquery.c:941 +#: tcop/pquery.c:953 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "Deklarieren Sie ihn mit der Option SCROLL, um rückwarts scannen zu können." #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:241 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "%s kann nicht in einer Read-Only-Transaktion ausgeführt werden" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:259 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "%s kann nicht während einer parallelen Operation ausgeführt werden" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:278 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "%s kann nicht während der Wiederherstellung ausgeführt werden" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:296 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "kann %s nicht in einer sicherheitsbeschränkten Operation ausführen" -#: tcop/utility.c:759 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" msgstr "nur Superuser können CHECKPOINT ausführen" +#: tcop/utility.c:1341 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "kann keinen Index für partitionierte Tabelle »%s« erzeugen" + +#: tcop/utility.c:1343 +#, fuzzy, c-format +#| msgid "\"%s\" is not a foreign table" +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "»%s« ist keine Fremdtabelle" + #: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" @@ -18795,17 +20233,17 @@ msgstr "ungültiges Affix-Flag »%s« mit Flag-Wert »long«" msgid "could not open dictionary file \"%s\": %m" msgstr "konnte Wörterbuchdatei »%s« nicht öffnen: %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "ungültiger regulärer Ausdruck: %s" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format msgid "invalid affix alias \"%s\"" msgstr "ungültiges Affixalias »%s«" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "konnte Affixdatei »%s« nicht öffnen: %m" @@ -18820,23 +20258,28 @@ msgstr "Ispell-Wörterbuch unterstützt nur die Flag-Werte »default«, »long« msgid "invalid number of flag vector aliases" msgstr "ungültige Anzahl Flag-Vektor-Aliasse" -#: tsearch/spell.c:1542 +#: tsearch/spell.c:1332 +#, fuzzy, c-format +#| msgid "number of aliases does not match number of columns" +msgid "number of aliases exceeds specified number %d" +msgstr "Anzahl der Aliasnamen stimmt nicht mit der Anzahl der Spalten überein" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "Affixdatei enthält Befehle im alten und im neuen Stil" -#: tsearch/to_tsany.c:170 utils/adt/tsvector.c:271 -#: utils/adt/tsvector_op.c:1134 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "Zeichenkette ist zu lang für tsvector (%d Bytes, maximal %d Bytes)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "Zeile %d in Konfigurationsdatei »%s«: »%s«" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "Umwandlung von wchar_t in Serverkodierung fehlgeschlagen: %m" @@ -18863,458 +20306,463 @@ msgstr "ungültiger Textsuchekonfigurationsdateiname »%s«" msgid "could not open stop-word file \"%s\": %m" msgstr "konnte Stoppwortdatei »%s« nicht öffnen: %m" -#: tsearch/wparser.c:307 +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 #, c-format msgid "text search parser does not support headline creation" msgstr "Textsucheparser unterstützt das Erzeugen von Headlines nicht" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "unbekannter Headline-Parameter: »%s«" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "»MinWords« sollte kleiner als »MaxWords« sein" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "»MinWords« sollte positiv sein" -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "»ShortWord« sollte >= 0 sein" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "»MaxFragments« sollte >= 0 sein" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format msgid "identifier too long" msgstr "Bezeichner zu lang" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format msgid "Identifier must be less than %d characters." msgstr "Bezeichner muss weniger als %d Zeichen haben." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "unbekanntes Schlüsselwort: »%s«" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "ACL-Schlüsselwort muss »group« oder »user« sein." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "Name fehlt" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "Auf das Schlüsselwort »group« oder »user« muss ein Name folgen." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "»=«-Zeichen fehlt" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "ungültiges Moduszeichen: muss eines aus »%s« sein" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "auf das »/«-Zeichen muss ein Name folgen" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "nicht angegebener Grantor wird auf user ID %u gesetzt" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "ACL-Array enthält falschen Datentyp" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "ACL-Arrays müssen eindimensional sein" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "ACL-Array darf keine NULL-Werte enthalten" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "überflüssiger Müll am Ende der ACL-Angabe" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1213 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "Grant-Optionen können nicht an den eigenen Grantor gegeben werden" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1274 #, c-format msgid "dependent privileges exist" msgstr "abhängige Privilegien existieren" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1275 #, c-format msgid "Use CASCADE to revoke them too." msgstr "Verwenden Sie CASCADE, um diese auch zu entziehen." -#: utils/adt/acl.c:1520 +#: utils/adt/acl.c:1537 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert wird nicht mehr unterstützt" -#: utils/adt/acl.c:1530 +#: utils/adt/acl.c:1547 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove wird nicht mehr unterstützt" -#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "unbekannter Privilegtyp: »%s«" -#: utils/adt/acl.c:3410 utils/adt/regproc.c:125 utils/adt/regproc.c:146 -#: utils/adt/regproc.c:321 +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "Funktion »%s« existiert nicht" -#: utils/adt/acl.c:4864 +#: utils/adt/acl.c:4959 #, c-format msgid "must be member of role \"%s\"" msgstr "Berechtigung nur für Mitglied von Rolle »%s«" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5848 -#: utils/adt/arrayfuncs.c:6159 utils/adt/arrayutils.c:93 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 +#: utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 #: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "Arraygröße überschreitet erlaubtes Maximum (%d)" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:541 -#: utils/adt/array_userfuncs.c:621 utils/adt/json.c:1764 utils/adt/json.c:1859 -#: utils/adt/json.c:1897 utils/adt/jsonb.c:1127 utils/adt/jsonb.c:1156 -#: utils/adt/jsonb.c:1592 utils/adt/jsonb.c:1756 utils/adt/jsonb.c:1766 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 +#: utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format msgid "could not determine input data type" msgstr "konnte Eingabedatentypen nicht bestimmen" -#: utils/adt/array_userfuncs.c:84 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "Eingabedatentyp ist kein Array" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 -#: utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:608 -#: utils/adt/int.c:637 utils/adt/int.c:658 utils/adt/int.c:689 -#: utils/adt/int.c:722 utils/adt/int.c:744 utils/adt/int.c:892 -#: utils/adt/int.c:913 utils/adt/int.c:940 utils/adt/int.c:980 -#: utils/adt/int.c:1001 utils/adt/int.c:1028 utils/adt/int.c:1061 -#: utils/adt/int.c:1144 utils/adt/int8.c:1298 utils/adt/numeric.c:2953 -#: utils/adt/numeric.c:2962 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 -#: utils/adt/varlena.c:1056 utils/adt/varlena.c:2808 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1376 utils/adt/float.c:1464 +#: utils/adt/float.c:3765 utils/adt/float.c:3779 utils/adt/int.c:755 +#: utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 +#: utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 +#: utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 +#: utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 +#: utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 +#: utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format msgid "integer out of range" msgstr "integer ist außerhalb des gültigen Bereichs" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "Argument muss entweder leer oder ein eindimensionales Array sein" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 -#: utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 -#: utils/adt/array_userfuncs.c:411 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "inkompatible Arrays können nicht aneinandergehängt werden" -#: utils/adt/array_userfuncs.c:279 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "Arrays mit Elementtypen %s und %s sind nicht kompatibel für Aneinanderhängen." -#: utils/adt/array_userfuncs.c:318 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "Arrays mit %d und %d Dimensionen sind nicht kompatibel für Aneinanderhängen." -#: utils/adt/array_userfuncs.c:355 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "Arrays mit unterschiedlichen Elementdimensionen sind nicht kompatibel für Aneinanderhängen." -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "Arrays mit unterschiedlichen Dimensionen sind nicht kompatibel für Aneinanderhängen." -#: utils/adt/array_userfuncs.c:480 utils/adt/arrayfuncs.c:1284 -#: utils/adt/arrayfuncs.c:3357 utils/adt/arrayfuncs.c:5754 -#, c-format -msgid "invalid number of dimensions: %d" -msgstr "ungültige Anzahl Dimensionen: %d" - -#: utils/adt/array_userfuncs.c:737 utils/adt/array_userfuncs.c:889 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "Suche nach Elementen in mehrdimensionalen Arrays wird nicht unterstützt" -#: utils/adt/array_userfuncs.c:761 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "Startposition darf nicht NULL sein" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" msgstr "fehlerhafte Arraykonstante: »%s«" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "Auf »[« müssen explizit angegebene Array-Dimensionen folgen." -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "Dimensionswert fehlt." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "»%s« fehlt nach Arraydimensionen." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "Obergrenze kann nicht kleiner als Untergrenze sein" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "Arraywert muss mit »{« oder Dimensionsinformationen anfangen." -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." msgstr "Array-Inhalt muss mit {« anfangen." -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "Angegebene Array-Dimensionen stimmen nicht mit dem Array-Inhalt überein." -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2114 utils/adt/rangetypes.c:2122 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 +#: utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format msgid "Unexpected end of input." msgstr "Unerwartetes Ende der Eingabe." -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "Unerwartetes Zeichen »%c«." -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "Unerwartetes Arrayelement." -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "Zeichen »%c« ohne Gegenstück." -#: utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "Mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben." -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "Müll nach schließender rechter geschweifter Klammer." -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5816 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "ungültige Anzahl Dimensionen: %d" + +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" msgstr "ungültige Array-Flags" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "falscher Elementtyp" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2651 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "keine binäre Eingabefunktion verfügbar für Typ %s" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "falsches Binärformat in Arrayelement %d" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2684 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "keine binäre Ausgabefunktion verfügbar für Typ %s" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "Auswählen von Stücken aus Arrays mit fester Länge ist nicht implementiert" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5740 -#: utils/adt/arrayfuncs.c:5766 utils/adt/arrayfuncs.c:5777 -#: utils/adt/json.c:2295 utils/adt/json.c:2370 utils/adt/jsonb.c:1370 -#: utils/adt/jsonb.c:1456 utils/adt/jsonfuncs.c:3465 -#: utils/adt/jsonfuncs.c:3616 utils/adt/jsonfuncs.c:3661 -#: utils/adt/jsonfuncs.c:3708 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 +#: utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 +#: utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 +#: utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "falsche Anzahl Arrayindizes" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "Arrayindex außerhalb des gültigen Bereichs" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "Array mit fester Länge kann keinen NULL-Wert enthalten" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "Aktualisieren von Stücken aus Arrays mit fester Länge ist nicht implementiert" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format msgid "array slice subscript must provide both boundaries" msgstr "Array-Slice-Index muss beide Begrenzungen angeben" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "Wenn ein Slice eines leeren Array-Wertes zugewiesen wird, dann müssen die Slice-Begrenzungen vollständig angegeben werden." -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "Quellarray ist zu klein" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "NULL-Werte im Array sind in diesem Zusammenhang nicht erlaubt" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4124 #, c-format msgid "cannot compare arrays of different element types" msgstr "kann Arrays mit verschiedenen Elementtypen nicht vergleichen" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 +#: utils/adt/rangetypes.c:1317 #, c-format msgid "could not identify a hash function for type %s" msgstr "konnte keine Hash-Funktion für Typ %s ermitteln" -#: utils/adt/arrayfuncs.c:5154 +#: utils/adt/arrayfuncs.c:4040 +#, fuzzy, c-format +#| msgid "could not identify a hash function for type %s" +msgid "could not identify an extended hash function for type %s" +msgstr "konnte keine Hash-Funktion für Typ %s ermitteln" + +#: utils/adt/arrayfuncs.c:5216 #, c-format msgid "data type %s is not an array type" msgstr "Datentyp %s ist kein Array-Typ" -#: utils/adt/arrayfuncs.c:5209 +#: utils/adt/arrayfuncs.c:5271 #, c-format msgid "cannot accumulate null arrays" msgstr "Arrays, die NULL sind, können nicht akkumuliert werden" -#: utils/adt/arrayfuncs.c:5237 +#: utils/adt/arrayfuncs.c:5299 #, c-format msgid "cannot accumulate empty arrays" msgstr "leere Arrays können nicht akkumuliert werden" -#: utils/adt/arrayfuncs.c:5266 utils/adt/arrayfuncs.c:5272 +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "Arrays unterschiedlicher Dimensionalität können nicht akkumuliert werden" -#: utils/adt/arrayfuncs.c:5638 utils/adt/arrayfuncs.c:5678 +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "Dimensions-Array oder Untergrenzen-Array darf nicht NULL sein" -#: utils/adt/arrayfuncs.c:5741 utils/adt/arrayfuncs.c:5767 +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 #, c-format msgid "Dimension array must be one dimensional." msgstr "Dimensions-Array muss eindimensional sein." -#: utils/adt/arrayfuncs.c:5746 utils/adt/arrayfuncs.c:5772 +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 #, c-format msgid "dimension values cannot be null" msgstr "Dimensionswerte dürfen nicht NULL sein" -#: utils/adt/arrayfuncs.c:5778 +#: utils/adt/arrayfuncs.c:5840 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "Untergrenzen-Array hat andere Größe als Dimensions-Array." -#: utils/adt/arrayfuncs.c:6024 +#: utils/adt/arrayfuncs.c:6086 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "Entfernen von Elementen aus mehrdimensionalen Arrays wird nicht unterstützt" -#: utils/adt/arrayfuncs.c:6301 +#: utils/adt/arrayfuncs.c:6363 #, c-format msgid "thresholds must be one-dimensional array" msgstr "Parameter »thresholds« muss ein eindimensionales Array sein" -#: utils/adt/arrayfuncs.c:6306 +#: utils/adt/arrayfuncs.c:6368 #, c-format msgid "thresholds array must not contain NULLs" msgstr "»thresholds«-Array darf keine NULL-Werte enthalten" @@ -19340,42 +20788,43 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "Kodierungsumwandlung zwischen %s und ASCII wird nicht unterstützt" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:153 utils/adt/cash.c:278 utils/adt/datetime.c:3799 -#: utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 -#: utils/adt/float.c:461 utils/adt/float.c:544 utils/adt/float.c:570 -#: utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 utils/adt/geo_ops.c:178 -#: utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 utils/adt/geo_ops.c:265 -#: utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 utils/adt/geo_ops.c:1356 -#: utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3430 utils/adt/geo_ops.c:4563 -#: utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 utils/adt/mac.c:68 -#: utils/adt/nabstime.c:1539 utils/adt/network.c:58 utils/adt/numeric.c:593 -#: utils/adt/numeric.c:620 utils/adt/numeric.c:5488 utils/adt/numeric.c:5512 -#: utils/adt/numeric.c:5536 utils/adt/numeric.c:6338 utils/adt/numeric.c:6364 -#: utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 +#: utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 +#: utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 +#: utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 +#: utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 +#: utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 +#: utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 +#: utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 +#: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 +#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1542 +#: utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 +#: utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 +#: utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 #: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 -#: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:339 +#: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 #: utils/adt/uuid.c:136 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "ungültige Eingabesyntax für Typ %s: »%s«" -#: utils/adt/cash.c:211 utils/adt/cash.c:238 utils/adt/cash.c:249 -#: utils/adt/cash.c:290 utils/adt/int8.c:114 utils/adt/numutils.c:75 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 #: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format msgid "value \"%s\" is out of range for type %s" msgstr "Wert »%s« ist außerhalb des gültigen Bereichs für Typ %s" -#: utils/adt/cash.c:651 utils/adt/cash.c:701 utils/adt/cash.c:752 -#: utils/adt/cash.c:801 utils/adt/cash.c:853 utils/adt/cash.c:903 -#: utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 -#: utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:704 -#: utils/adt/int.c:846 utils/adt/int.c:954 utils/adt/int.c:1043 -#: utils/adt/int.c:1082 utils/adt/int.c:1110 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6902 -#: utils/adt/numeric.c:7191 utils/adt/numeric.c:8204 -#: utils/adt/timestamp.c:3186 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3526 +#: utils/adt/float.c:3589 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 +#: utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 +#: utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 +#: utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 +#: utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3238 #, c-format msgid "division by zero" msgstr "Division durch Null" @@ -19385,162 +20834,172 @@ msgstr "Division durch Null" msgid "\"char\" out of range" msgstr "\"char\" ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:67 utils/adt/timestamp.c:94 utils/adt/varbit.c:53 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 #: utils/adt/varchar.c:46 #, c-format msgid "invalid type modifier" msgstr "ungültige Typmodifikation" -#: utils/adt/date.c:79 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "Präzision von TIME(%d)%s darf nicht negativ sein" -#: utils/adt/date.c:85 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "Präzision von TIME(%d)%s auf erlaubten Höchstwert %d reduziert" -#: utils/adt/date.c:146 utils/adt/datetime.c:1209 utils/adt/datetime.c:2117 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "Datum/Zeitwert »current« wird nicht mehr unterstützt" -#: utils/adt/date.c:172 utils/adt/date.c:180 utils/adt/formatting.c:3523 -#: utils/adt/formatting.c:3532 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 +#: utils/adt/formatting.c:3615 #, c-format msgid "date out of range: \"%s\"" msgstr "date ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/date.c:227 utils/adt/date.c:539 utils/adt/date.c:563 -#: utils/adt/xml.c:2086 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2092 #, c-format msgid "date out of range" msgstr "date ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:273 utils/adt/timestamp.c:563 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "Datum-Feldwert ist außerhalb des gültigen Bereichs: %d-%02d-%02d" -#: utils/adt/date.c:280 utils/adt/date.c:289 utils/adt/timestamp.c:569 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "date ist außerhalb des gültigen Bereichs: %d-%02d-%02d" -#: utils/adt/date.c:327 utils/adt/date.c:350 utils/adt/date.c:376 -#: utils/adt/date.c:1092 utils/adt/date.c:1138 utils/adt/date.c:1672 -#: utils/adt/date.c:1703 utils/adt/date.c:1732 utils/adt/date.c:2469 -#: utils/adt/datetime.c:1690 utils/adt/formatting.c:3398 -#: utils/adt/formatting.c:3430 utils/adt/formatting.c:3498 -#: utils/adt/json.c:1539 utils/adt/json.c:1561 utils/adt/jsonb.c:824 -#: utils/adt/jsonb.c:848 utils/adt/nabstime.c:456 utils/adt/nabstime.c:499 -#: utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 utils/adt/timestamp.c:229 -#: utils/adt/timestamp.c:261 utils/adt/timestamp.c:691 -#: utils/adt/timestamp.c:700 utils/adt/timestamp.c:778 -#: utils/adt/timestamp.c:811 utils/adt/timestamp.c:2765 -#: utils/adt/timestamp.c:2786 utils/adt/timestamp.c:2799 -#: utils/adt/timestamp.c:2808 utils/adt/timestamp.c:2816 -#: utils/adt/timestamp.c:2871 utils/adt/timestamp.c:2894 -#: utils/adt/timestamp.c:2907 utils/adt/timestamp.c:2918 -#: utils/adt/timestamp.c:2926 utils/adt/timestamp.c:3482 -#: utils/adt/timestamp.c:3607 utils/adt/timestamp.c:3648 -#: utils/adt/timestamp.c:3729 utils/adt/timestamp.c:3775 -#: utils/adt/timestamp.c:3878 utils/adt/timestamp.c:4277 -#: utils/adt/timestamp.c:4376 utils/adt/timestamp.c:4386 -#: utils/adt/timestamp.c:4478 utils/adt/timestamp.c:4580 -#: utils/adt/timestamp.c:4590 utils/adt/timestamp.c:4822 -#: utils/adt/timestamp.c:4836 utils/adt/timestamp.c:4841 -#: utils/adt/timestamp.c:4855 utils/adt/timestamp.c:4900 -#: utils/adt/timestamp.c:4932 utils/adt/timestamp.c:4939 -#: utils/adt/timestamp.c:4972 utils/adt/timestamp.c:4976 -#: utils/adt/timestamp.c:5045 utils/adt/timestamp.c:5049 -#: utils/adt/timestamp.c:5063 utils/adt/timestamp.c:5097 utils/adt/xml.c:2108 -#: utils/adt/xml.c:2115 utils/adt/xml.c:2135 utils/adt/xml.c:2142 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 +#: utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 +#: utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 +#: utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:459 +#: utils/adt/nabstime.c:502 utils/adt/nabstime.c:532 utils/adt/nabstime.c:575 +#: utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2817 utils/adt/timestamp.c:2838 +#: utils/adt/timestamp.c:2851 utils/adt/timestamp.c:2860 +#: utils/adt/timestamp.c:2868 utils/adt/timestamp.c:2923 +#: utils/adt/timestamp.c:2946 utils/adt/timestamp.c:2959 +#: utils/adt/timestamp.c:2970 utils/adt/timestamp.c:2978 +#: utils/adt/timestamp.c:3638 utils/adt/timestamp.c:3763 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3894 +#: utils/adt/timestamp.c:3940 utils/adt/timestamp.c:4043 +#: utils/adt/timestamp.c:4450 utils/adt/timestamp.c:4549 +#: utils/adt/timestamp.c:4559 utils/adt/timestamp.c:4651 +#: utils/adt/timestamp.c:4753 utils/adt/timestamp.c:4763 +#: utils/adt/timestamp.c:4995 utils/adt/timestamp.c:5009 +#: utils/adt/timestamp.c:5014 utils/adt/timestamp.c:5028 +#: utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5105 +#: utils/adt/timestamp.c:5112 utils/adt/timestamp.c:5145 +#: utils/adt/timestamp.c:5149 utils/adt/timestamp.c:5218 +#: utils/adt/timestamp.c:5222 utils/adt/timestamp.c:5236 +#: utils/adt/timestamp.c:5270 utils/adt/xml.c:2114 utils/adt/xml.c:2121 +#: utils/adt/xml.c:2141 utils/adt/xml.c:2148 #, c-format msgid "timestamp out of range" msgstr "timestamp ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:514 +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "kann unendliche date-Werte nicht subtrahieren" -#: utils/adt/date.c:592 utils/adt/date.c:623 utils/adt/date.c:641 -#: utils/adt/date.c:2506 utils/adt/date.c:2516 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format msgid "date out of range for timestamp" msgstr "Datum ist außerhalb des gültigen Bereichs für Typ »timestamp«" -#: utils/adt/date.c:1164 +#: utils/adt/date.c:1190 #, c-format msgid "cannot convert reserved abstime value to date" msgstr "kann reservierten »abstime«-Wert nicht in »date« umwandeln" -#: utils/adt/date.c:1182 utils/adt/date.c:1188 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 #, c-format msgid "abstime out of range for date" msgstr "abstime ist außerhalb des gültigen Bereichs für Typ »date«" -#: utils/adt/date.c:1301 utils/adt/date.c:2020 +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format msgid "time out of range" msgstr "time ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:1357 utils/adt/timestamp.c:588 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "Zeit-Feldwert ist außerhalb des gültigen Bereichs: %d:%02d:%02g" -#: utils/adt/date.c:1907 utils/adt/date.c:1920 +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 +#: utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 +#: utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 +#: utils/adt/timestamp.c:3287 utils/adt/timestamp.c:3318 +#: utils/adt/timestamp.c:3349 +#, fuzzy, c-format +#| msgid "window functions are not allowed in window definitions" +msgid "invalid preceding or following size in window function" +msgstr "Fensterfunktionen sind in Fensterdefinitionen nicht erlaubt" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "»time«-Einheit »%s« nicht erkannt" -#: utils/adt/date.c:2028 +#: utils/adt/date.c:2099 #, c-format msgid "time zone displacement out of range" msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs" -#: utils/adt/date.c:2601 utils/adt/date.c:2614 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "»time with time zone«-Einheit »%s« nicht erkannt" -#: utils/adt/date.c:2687 utils/adt/datetime.c:931 utils/adt/datetime.c:1848 -#: utils/adt/datetime.c:4636 utils/adt/timestamp.c:502 -#: utils/adt/timestamp.c:529 utils/adt/timestamp.c:4847 -#: utils/adt/timestamp.c:5055 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 +#: utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 +#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:5020 +#: utils/adt/timestamp.c:5228 #, c-format msgid "time zone \"%s\" not recognized" msgstr "Zeitzone »%s« nicht erkannt" -#: utils/adt/date.c:2719 utils/adt/timestamp.c:4889 utils/adt/timestamp.c:5086 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5062 utils/adt/timestamp.c:5259 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "Intervall-Zeitzone »%s« darf keine Monate oder Tage enthalten" -#: utils/adt/datetime.c:3772 utils/adt/datetime.c:3779 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "Datum/Zeit-Feldwert ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:3781 +#: utils/adt/datetime.c:3770 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "Möglicherweise benötigen Sie eine andere »datestyle«-Einstellung." -#: utils/adt/datetime.c:3786 +#: utils/adt/datetime.c:3775 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "»interval«-Feldwert ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:3792 +#: utils/adt/datetime.c:3781 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "Zeitzonenunterschied ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/datetime.c:4638 +#: utils/adt/datetime.c:4627 #, c-format msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "Dieser Zeitzonenname erscheint in der Konfigurationsdatei für Zeitzonenabkürzung »%s«." @@ -19550,27 +21009,22 @@ msgstr "Dieser Zeitzonenname erscheint in der Konfigurationsdatei für Zeitzonen msgid "invalid Datum pointer" msgstr "ungültiger »Datum«-Zeiger" -#: utils/adt/dbsize.c:109 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "konnte Tablespace-Verzeichnis »%s« nicht öffnen: %m" - -#: utils/adt/dbsize.c:756 utils/adt/dbsize.c:824 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format msgid "invalid size: \"%s\"" msgstr "ungültige Größe: »%s«" -#: utils/adt/dbsize.c:825 +#: utils/adt/dbsize.c:828 #, c-format msgid "Invalid size unit: \"%s\"." msgstr "Ungültige Größeneinheit: »%s«." -#: utils/adt/dbsize.c:826 +#: utils/adt/dbsize.c:829 #, c-format msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "Gültige Einheiten sind »kB«, »MB«, »GB« und »TB«." -#: utils/adt/domains.c:91 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "Typ %s ist keine Domäne" @@ -19610,701 +21064,725 @@ msgstr "ungültige Base64-Endsequenz" msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "Die Eingabedaten haben fehlendes Padding, sind zu kurz oder sind anderweitig verfälscht." -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:785 -#: utils/adt/json.c:825 utils/adt/json.c:841 utils/adt/json.c:853 -#: utils/adt/json.c:863 utils/adt/json.c:914 utils/adt/json.c:946 -#: utils/adt/json.c:965 utils/adt/json.c:977 utils/adt/json.c:989 -#: utils/adt/json.c:1134 utils/adt/json.c:1148 utils/adt/json.c:1159 -#: utils/adt/json.c:1167 utils/adt/json.c:1175 utils/adt/json.c:1183 -#: utils/adt/json.c:1191 utils/adt/json.c:1199 utils/adt/json.c:1207 -#: utils/adt/json.c:1215 utils/adt/json.c:1245 utils/adt/varlena.c:298 -#: utils/adt/varlena.c:339 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 +#: utils/adt/varlena.c:337 #, c-format msgid "invalid input syntax for type %s" msgstr "ungültige Eingabesyntax für Typ %s" -#: utils/adt/enum.c:115 -#, c-format -msgid "unsafe use of new value \"%s\" of enum type %s" -msgstr "" - -#: utils/adt/enum.c:118 -#, c-format -msgid "New enum values must be committed before they can be used." -msgstr "" - -#: utils/adt/enum.c:136 utils/adt/enum.c:146 utils/adt/enum.c:204 -#: utils/adt/enum.c:214 +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 +#: utils/adt/enum.c:123 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "ungültiger Eingabewert für Enum %s: »%s«" -#: utils/adt/enum.c:176 utils/adt/enum.c:242 utils/adt/enum.c:301 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format msgid "invalid internal value for enum: %u" msgstr "ungültiger interner Wert für Enum: %u" -#: utils/adt/enum.c:461 utils/adt/enum.c:490 utils/adt/enum.c:530 -#: utils/adt/enum.c:550 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 +#: utils/adt/enum.c:449 #, c-format msgid "could not determine actual enum type" msgstr "konnte tatsächlichen Enum-Typen nicht bestimmen" -#: utils/adt/enum.c:469 utils/adt/enum.c:498 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format msgid "enum %s contains no values" msgstr "Enum %s enthält keine Werte" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 +#: utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "Typ %s ist kein zusammengesetzter Typ" + +#: utils/adt/float.c:55 #, c-format msgid "value out of range: overflow" msgstr "Wert ist außerhalb des gültigen Bereichs: Überlauf" -#: utils/adt/float.c:63 +#: utils/adt/float.c:60 #, c-format msgid "value out of range: underflow" msgstr "Wert ist außerhalb des gültigen Bereichs: Unterlauf" -#: utils/adt/float.c:312 +#: utils/adt/float.c:309 #, c-format msgid "\"%s\" is out of range for type real" msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ real" -#: utils/adt/float.c:537 +#: utils/adt/float.c:534 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "»%s« ist außerhalb des gültigen Bereichs für Typ double precision" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:334 -#: utils/adt/int.c:760 utils/adt/int.c:789 utils/adt/int.c:810 -#: utils/adt/int.c:830 utils/adt/int.c:864 utils/adt/int.c:1159 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3050 utils/adt/numeric.c:3059 +#: utils/adt/float.c:1408 utils/adt/float.c:1496 utils/adt/int.c:332 +#: utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 +#: utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 +#: utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format msgid "smallint out of range" msgstr "smallint ist außerhalb des gültigen Bereichs" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7624 +#: utils/adt/float.c:1622 utils/adt/numeric.c:7802 #, c-format msgid "cannot take square root of a negative number" msgstr "Quadratwurzel von negativer Zahl kann nicht ermittelt werden" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2853 +#: utils/adt/float.c:1683 utils/adt/numeric.c:3017 #, c-format msgid "zero raised to a negative power is undefined" msgstr "null hoch eine negative Zahl ist undefiniert" -#: utils/adt/float.c:1476 utils/adt/numeric.c:2859 +#: utils/adt/float.c:1687 utils/adt/numeric.c:3023 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "eine negative Zahl hoch eine nicht ganze Zahl ergibt ein komplexes Ergebnis" -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7890 +#: utils/adt/float.c:1753 utils/adt/float.c:1783 utils/adt/numeric.c:8068 #, c-format msgid "cannot take logarithm of zero" msgstr "Logarithmus von null kann nicht ermittelt werden" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7894 +#: utils/adt/float.c:1757 utils/adt/float.c:1787 utils/adt/numeric.c:8072 #, c-format msgid "cannot take logarithm of a negative number" msgstr "Logarithmus negativer Zahlen kann nicht ermittelt werden" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 -#: utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 -#: utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 -#: utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: utils/adt/float.c:1817 utils/adt/float.c:1847 utils/adt/float.c:1939 +#: utils/adt/float.c:1965 utils/adt/float.c:1992 utils/adt/float.c:2018 +#: utils/adt/float.c:2165 utils/adt/float.c:2200 utils/adt/float.c:2364 +#: utils/adt/float.c:2418 utils/adt/float.c:2482 utils/adt/float.c:2537 #, c-format msgid "input is out of range" msgstr "Eingabe ist außerhalb des gültigen Bereichs" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1493 +#: utils/adt/float.c:3743 utils/adt/numeric.c:1504 #, c-format msgid "count must be greater than zero" msgstr "Anzahl muss größer als null sein" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1500 +#: utils/adt/float.c:3748 utils/adt/numeric.c:1511 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "Operand, Untergrenze und Obergrenze dürfen nicht NaN sein" -#: utils/adt/float.c:3543 +#: utils/adt/float.c:3754 #, c-format msgid "lower and upper bounds must be finite" msgstr "Untergrenze und Obergrenze müssen endlich sein" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1513 +#: utils/adt/float.c:3788 utils/adt/numeric.c:1524 #, c-format msgid "lower bound cannot equal upper bound" msgstr "Untergrenze kann nicht gleich der Obergrenze sein" -#: utils/adt/formatting.c:489 +#: utils/adt/formatting.c:488 #, c-format msgid "invalid format specification for an interval value" msgstr "ungültige Formatangabe für Intervall-Wert" -#: utils/adt/formatting.c:490 +#: utils/adt/formatting.c:489 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Intervalle beziehen sich nicht auf bestimmte Kalenderdaten." -#: utils/adt/formatting.c:1056 +#: utils/adt/formatting.c:1059 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "»EEEE« muss das letzte Muster sein" -#: utils/adt/formatting.c:1064 +#: utils/adt/formatting.c:1067 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "»9« muss vor »PR« stehen" -#: utils/adt/formatting.c:1080 +#: utils/adt/formatting.c:1083 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "»0« muss vor »PR« stehen" -#: utils/adt/formatting.c:1107 +#: utils/adt/formatting.c:1110 #, c-format msgid "multiple decimal points" msgstr "mehrere Dezimalpunkte" -#: utils/adt/formatting.c:1111 utils/adt/formatting.c:1194 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "»V« und Dezimalpunkt können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1123 +#: utils/adt/formatting.c:1126 #, c-format msgid "cannot use \"S\" twice" msgstr "»S« kann nicht zweimal verwendet werden" -#: utils/adt/formatting.c:1127 +#: utils/adt/formatting.c:1130 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "»S« und »PL«/»MI«/»SG«/»PR« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1147 +#: utils/adt/formatting.c:1150 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "»S« und »MI« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1157 +#: utils/adt/formatting.c:1160 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "»S« und »PL« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1167 +#: utils/adt/formatting.c:1170 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "»S« und »SG« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1176 +#: utils/adt/formatting.c:1179 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "»PR« und »S«/»PL«/»MI«/»SG« können nicht zusammen verwendet werden" -#: utils/adt/formatting.c:1202 +#: utils/adt/formatting.c:1205 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "»EEEE« kann nicht zweimal verwendet werden" -#: utils/adt/formatting.c:1208 +#: utils/adt/formatting.c:1211 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "»EEEE« ist mit anderen Formaten inkompatibel" -#: utils/adt/formatting.c:1209 +#: utils/adt/formatting.c:1212 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "»EEEE« kann nur zusammen mit Platzhaltern für Ziffern oder Dezimalpunkt verwendet werden." -#: utils/adt/formatting.c:1398 +#: utils/adt/formatting.c:1392 #, c-format msgid "\"%s\" is not a number" msgstr "»%s« ist keine Zahl" -#: utils/adt/formatting.c:1499 utils/adt/formatting.c:1551 +#: utils/adt/formatting.c:1470 +#, c-format +msgid "case conversion failed: %s" +msgstr "Groß/Klein-Umwandlung fehlgeschlagen: %s" + +#: utils/adt/formatting.c:1535 #, c-format msgid "could not determine which collation to use for lower() function" msgstr "konnte die für die Funktion lower() zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/formatting.c:1619 utils/adt/formatting.c:1671 +#: utils/adt/formatting.c:1657 #, c-format msgid "could not determine which collation to use for upper() function" msgstr "konnte die für die Funktion upper() zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/formatting.c:1740 utils/adt/formatting.c:1804 +#: utils/adt/formatting.c:1780 #, c-format msgid "could not determine which collation to use for initcap() function" msgstr "konnte die für die Funktion initcap() zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/formatting.c:2101 +#: utils/adt/formatting.c:2148 #, c-format msgid "invalid combination of date conventions" msgstr "ungültige Kombination von Datumskonventionen" -#: utils/adt/formatting.c:2102 +#: utils/adt/formatting.c:2149 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr "Die Gregorianische und die ISO-Konvention für Wochendaten können nicht einer Formatvorlage gemischt werden." -#: utils/adt/formatting.c:2119 +#: utils/adt/formatting.c:2166 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "widersprüchliche Werte für das Feld »%s« in Formatzeichenkette" -#: utils/adt/formatting.c:2121 +#: utils/adt/formatting.c:2168 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Der Wert widerspricht einer vorherigen Einstellung für den selben Feldtyp." -#: utils/adt/formatting.c:2182 +#: utils/adt/formatting.c:2229 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "Quellzeichenkette zu kurz für Formatfeld »%s»" -#: utils/adt/formatting.c:2184 +#: utils/adt/formatting.c:2231 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "Feld benötigt %d Zeichen, aber nur %d verbleiben." -#: utils/adt/formatting.c:2187 utils/adt/formatting.c:2201 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "Wenn die Quellzeichenkette keine feste Breite hat, versuchen Sie den Modifikator »FM«." -#: utils/adt/formatting.c:2197 utils/adt/formatting.c:2210 -#: utils/adt/formatting.c:2340 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 +#: utils/adt/formatting.c:2387 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "ungültiger Wert »%s« für »%s«" -#: utils/adt/formatting.c:2199 +#: utils/adt/formatting.c:2246 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "Feld benötigt %d Zeichen, aber nur %d konnten geparst werden." -#: utils/adt/formatting.c:2212 +#: utils/adt/formatting.c:2259 #, c-format msgid "Value must be an integer." msgstr "Der Wert muss eine ganze Zahl sein." -#: utils/adt/formatting.c:2217 +#: utils/adt/formatting.c:2264 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "Wert für »%s« in der Eingabezeichenkette ist außerhalb des gültigen Bereichs" -#: utils/adt/formatting.c:2219 +#: utils/adt/formatting.c:2266 #, c-format msgid "Value must be in the range %d to %d." msgstr "Der Wert muss im Bereich %d bis %d sein." -#: utils/adt/formatting.c:2342 +#: utils/adt/formatting.c:2389 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "Der angegebene Wert stimmte mit keinem der für dieses Feld zulässigen Werte überein." -#: utils/adt/formatting.c:2527 utils/adt/formatting.c:2547 -#: utils/adt/formatting.c:2567 utils/adt/formatting.c:2587 -#: utils/adt/formatting.c:2606 utils/adt/formatting.c:2625 -#: utils/adt/formatting.c:2649 utils/adt/formatting.c:2667 -#: utils/adt/formatting.c:2685 utils/adt/formatting.c:2703 -#: utils/adt/formatting.c:2720 utils/adt/formatting.c:2737 +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 +#: utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 +#: utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 +#: utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 +#: utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 +#: utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 #, c-format msgid "localized string format value too long" msgstr "lokalisierter Formatwert ist zu lang" -#: utils/adt/formatting.c:3024 -#, fuzzy, c-format -#| msgid "replication slot file \"%s\" has unsupported version %u" +#: utils/adt/formatting.c:3084 +#, c-format msgid "formatting field \"%s\" is only supported in to_char" -msgstr "Replikations-Slot-Datei »%s« hat nicht unterstützte Version %u" +msgstr "Formatfeld »%s« wird nur in to_char unterstützt" -#: utils/adt/formatting.c:3135 +#: utils/adt/formatting.c:3209 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "ungültige Eingabe für »Y,YYY«" -#: utils/adt/formatting.c:3641 +#: utils/adt/formatting.c:3724 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "Stunde »%d« ist bei einer 12-Stunden-Uhr ungültig" -#: utils/adt/formatting.c:3643 +#: utils/adt/formatting.c:3726 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "Verwenden Sie die 24-Stunden-Uhr oder geben Sie eine Stunde zwischen 1 und 12 an." -#: utils/adt/formatting.c:3749 +#: utils/adt/formatting.c:3832 #, c-format msgid "cannot calculate day of year without year information" msgstr "kann Tag des Jahres nicht berechnen ohne Jahrinformationen" -#: utils/adt/formatting.c:4616 +#: utils/adt/formatting.c:4737 #, c-format msgid "\"EEEE\" not supported for input" msgstr "»E« wird nicht bei der Eingabe unterstützt" -#: utils/adt/formatting.c:4628 +#: utils/adt/formatting.c:4749 #, c-format msgid "\"RN\" not supported for input" msgstr "»RN« wird nicht bei der Eingabe unterstützt" -#: utils/adt/genfile.c:62 +#: utils/adt/genfile.c:79 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "Verweis auf übergeordnetes Verzeichnis (»..«) nicht erlaubt" -#: utils/adt/genfile.c:73 +#: utils/adt/genfile.c:90 #, c-format msgid "absolute path not allowed" msgstr "absoluter Pfad nicht erlaubt" -#: utils/adt/genfile.c:78 +#: utils/adt/genfile.c:95 #, c-format msgid "path must be in or below the current directory" msgstr "Pfad muss in oder unter aktuellem Verzeichnis sein" -#: utils/adt/genfile.c:125 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "verlangte Länge zu groß" -#: utils/adt/genfile.c:142 +#: utils/adt/genfile.c:159 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" -#: utils/adt/genfile.c:200 utils/adt/genfile.c:241 -#, c-format -msgid "must be superuser to read files" +#: utils/adt/genfile.c:219 +#, fuzzy, c-format +#| msgid "must be superuser to read files" +msgid "must be superuser to read files with adminpack 1.0" msgstr "nur Superuser können Dateien lesen" -#: utils/adt/genfile.c:318 -#, c-format -msgid "must be superuser to get file information" -msgstr "nur Superuser können Dateiinformationen lesen" - -#: utils/adt/genfile.c:404 -#, c-format -msgid "must be superuser to get directory listings" -msgstr "nur Superuser können Verzeichnislisten lesen" +#: utils/adt/genfile.c:220 +#, fuzzy, c-format +#| msgid "Consider using tablespaces instead." +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "Verwenden Sie stattdessen Tablespaces." -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:939 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "ungültige »line«-Angabe: A und B können nicht beide null sein" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:947 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "ungültige »line«-Angabe: es müssen zwei verschiedene Punkte angegeben werden" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 -#: utils/adt/geo_ops.c:5181 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 +#: utils/adt/geo_ops.c:5180 #, c-format msgid "too many points requested" msgstr "zu viele Punkte verlangt" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1403 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "ungültige Anzahl Punkte in externem »path«-Wert" -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2554 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "Funktion »dist_lb« ist nicht implementiert" -#: utils/adt/geo_ops.c:3015 +#: utils/adt/geo_ops.c:3014 #, c-format msgid "function \"close_sl\" not implemented" msgstr "Funktion »close_sl« ist nicht implementiert" -#: utils/adt/geo_ops.c:3117 +#: utils/adt/geo_ops.c:3116 #, c-format msgid "function \"close_lb\" not implemented" msgstr "Funktion »close_lb« ist nicht implementiert" -#: utils/adt/geo_ops.c:3406 +#: utils/adt/geo_ops.c:3405 #, c-format msgid "cannot create bounding box for empty polygon" msgstr "kann kein umschließendes Rechteck für leeres Polygon berechnen" -#: utils/adt/geo_ops.c:3487 +#: utils/adt/geo_ops.c:3486 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "ungültige Anzahl Punkte in externem »polygon«-Wert" -#: utils/adt/geo_ops.c:4012 +#: utils/adt/geo_ops.c:4011 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "Funktion »poly_distance« ist nicht implementiert" -#: utils/adt/geo_ops.c:4365 +#: utils/adt/geo_ops.c:4364 #, c-format msgid "function \"path_center\" not implemented" msgstr "Funktion »path_center« ist nicht implementiert" -#: utils/adt/geo_ops.c:4382 +#: utils/adt/geo_ops.c:4381 #, c-format msgid "open path cannot be converted to polygon" msgstr "offener Pfad kann nicht in Polygon umgewandelt werden" -#: utils/adt/geo_ops.c:4631 +#: utils/adt/geo_ops.c:4630 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "ungültiger Radius in externem »circle«-Wert" -#: utils/adt/geo_ops.c:5167 +#: utils/adt/geo_ops.c:5166 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "kann Kreis mit Radius null nicht in Polygon umwandeln" -#: utils/adt/geo_ops.c:5172 +#: utils/adt/geo_ops.c:5171 #, c-format msgid "must request at least 2 points" msgstr "mindestens 2 Punkte müssen angefordert werden" -#: utils/adt/geo_ops.c:5216 +#: utils/adt/geo_ops.c:5215 #, c-format msgid "cannot convert empty polygon to circle" msgstr "kann leeres Polygon nicht in Kreis umwandeln" -#: utils/adt/int.c:162 +#: utils/adt/int.c:160 #, c-format msgid "int2vector has too many elements" msgstr "int2vector-Wert hat zu viele Elemente" -#: utils/adt/int.c:237 +#: utils/adt/int.c:235 #, c-format msgid "invalid int2vector data" msgstr "ungültige int2vector-Daten" -#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "oidvector-Wert hat zu viele Elemente" -#: utils/adt/int.c:1347 utils/adt/int8.c:1460 utils/adt/numeric.c:1401 -#: utils/adt/timestamp.c:5148 utils/adt/timestamp.c:5229 +#: utils/adt/int.c:1379 utils/adt/int8.c:1325 utils/adt/numeric.c:1412 +#: utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5402 #, c-format msgid "step size cannot equal zero" msgstr "Schrittgröße kann nicht gleich null sein" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:105 -#, fuzzy, c-format -#| msgid "invalid input syntax for type %s: \"%s\"" -msgid "invalid input syntax for %s: \"%s\"" -msgstr "ungültige Eingabesyntax für Typ %s: »%s«" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:3005 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 +#: utils/adt/numutils.c:105 +#, c-format +msgid "invalid input syntax for integer: \"%s\"" +msgstr "ungültige Eingabesyntax für ganze Zahl: »%s«" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 +#: utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 +#: utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 +#: utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 +#: utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 +#: utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 +#: utils/adt/int8.c:1227 utils/adt/int8.c:1269 utils/adt/numeric.c:3169 #: utils/adt/varbit.c:1655 #, c-format msgid "bigint out of range" msgstr "bigint ist außerhalb des gültigen Bereichs" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1282 #, c-format msgid "OID out of range" msgstr "OID ist außerhalb des gültigen Bereichs" -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Zeichen mit Wert 0x%02x muss escapt werden." -#: utils/adt/json.c:827 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "Nach »\\u« müssen vier Hexadezimalziffern folgen." -#: utils/adt/json.c:843 +#: utils/adt/json.c:844 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Unicode-High-Surrogate darf nicht auf ein High-Surrogate folgen." -#: utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:916 -#: utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Unicode-Low-Surrogate muss auf ein High-Surrogate folgen." -#: utils/adt/json.c:879 utils/adt/json.c:902 +#: utils/adt/json.c:880 utils/adt/json.c:903 #, c-format msgid "unsupported Unicode escape sequence" msgstr "nicht unterstützte Unicode-Escape-Sequenz" -#: utils/adt/json.c:880 +#: utils/adt/json.c:881 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 kann nicht in »text« umgewandelt werden." -#: utils/adt/json.c:903 +#: utils/adt/json.c:904 #, c-format msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." msgstr "Unicode-Escape-Werte können nicht für Code-Punkt-Werte über 007F verwendet werden, wenn die Serverkodierung nicht UTF8 ist." -#: utils/adt/json.c:948 utils/adt/json.c:966 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "Escape-Sequenz »\\%s« ist nicht gültig." -#: utils/adt/json.c:1135 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "Die Eingabezeichenkette endete unerwartet." -#: utils/adt/json.c:1149 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "Ende der Eingabe erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1160 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "JSON-Wert erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1168 utils/adt/json.c:1216 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "Zeichenkette erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1176 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "Array-Element oder »]« erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "»,« oder »]« erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1192 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "Zeichenkette oder »}« erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1200 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "»:« erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1208 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "»,« oder »}« erwartet, aber »%s« gefunden." -#: utils/adt/json.c:1246 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "Token »%s« ist ungültig." -#: utils/adt/json.c:1318 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "JSON-Daten, Zeile %d: %s%s%s" -#: utils/adt/json.c:1474 utils/adt/jsonb.c:725 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "Schlüsselwert muss skalar sein, nicht Array, zusammengesetzt oder json" -#: utils/adt/json.c:2011 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format -msgid "could not determine data type for argument 1" -msgstr "konnte Datentyp von Argument 1 nicht ermitteln" - -#: utils/adt/json.c:2021 -#, c-format -msgid "could not determine data type for argument 2" -msgstr "konnte Datentyp von Argument 2 nicht ermitteln" +msgid "could not determine data type for argument %d" +msgstr "konnte Datentyp von Argument %d nicht ermitteln" -#: utils/adt/json.c:2045 utils/adt/jsonb.c:1782 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format msgid "field name must not be null" msgstr "Feldname darf nicht NULL sein" -#: utils/adt/json.c:2122 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format msgid "argument list must have even number of elements" msgstr "Argumentliste muss gerade Anzahl Elemente haben" -#: utils/adt/json.c:2123 +#: utils/adt/json.c:2195 #, c-format msgid "The arguments of json_build_object() must consist of alternating keys and values." msgstr "Die Argumente von json_build_object() müssen abwechselnd Schlüssel und Werte sein." -#: utils/adt/json.c:2147 utils/adt/json.c:2168 utils/adt/json.c:2227 -#, c-format -msgid "could not determine data type for argument %d" -msgstr "konnte Datentyp von Argument %d nicht ermitteln" - -#: utils/adt/json.c:2153 +#: utils/adt/json.c:2210 #, c-format msgid "argument %d cannot be null" msgstr "Argument %d darf nicht NULL sein" -#: utils/adt/json.c:2154 +#: utils/adt/json.c:2211 #, c-format msgid "Object keys should be text." msgstr "Objektschlüssel sollten Text sein." -#: utils/adt/json.c:2289 utils/adt/jsonb.c:1364 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format msgid "array must have two columns" msgstr "Array muss zwei Spalten haben" -#: utils/adt/json.c:2313 utils/adt/json.c:2397 utils/adt/jsonb.c:1388 -#: utils/adt/jsonb.c:1483 +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 +#: utils/adt/jsonb.c:1395 #, c-format msgid "null value not allowed for object key" msgstr "NULL-Werte sind nicht als Objektschlüssel erlaubt" -#: utils/adt/json.c:2386 utils/adt/jsonb.c:1472 +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 #, c-format msgid "mismatched array dimensions" msgstr "Array-Dimensionen passen nicht" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:258 #, c-format msgid "string too long to represent as jsonb string" msgstr "Zeichenkette ist zu lang für jsonb" -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:259 #, c-format msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "Aufgrund einer Einschränkung der Implementierung können jsonb-Zeichenketten nicht länger als %d Bytes sein." -#: utils/adt/jsonb.c:1183 +#: utils/adt/jsonb.c:1147 #, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "ungültige Anzahl Argumente: Objekt muss aus Schlüssel-Wert-Paaren bestehen" +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "Die Argumente von jsonb_build_object() müssen abwechselnd Schlüssel und Werte sein." -#: utils/adt/jsonb.c:1196 +#: utils/adt/jsonb.c:1159 #, c-format msgid "argument %d: key must not be null" msgstr "Argument %d: Schlüssel darf nicht NULL sein" -#: utils/adt/jsonb.c:1215 utils/adt/jsonb.c:1238 utils/adt/jsonb.c:1298 -#, c-format -msgid "argument %d: could not determine data type" -msgstr "Argument %d: konnte Datentypen nicht bestimmen" - -#: utils/adt/jsonb.c:1835 +#: utils/adt/jsonb.c:1747 #, c-format msgid "object keys must be strings" msgstr "Objektschlüssel müssen Zeichenketten sein" +#: utils/adt/jsonb.c:1910 +#, fuzzy, c-format +#| msgid "cannot accept a value of type %s" +msgid "cannot cast jsonb null to type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: utils/adt/jsonb.c:1911 +#, fuzzy, c-format +#| msgid "cannot cast type %s to %s" +msgid "cannot cast jsonb string to type %s" +msgstr "kann Typ %s nicht in Typ %s umwandeln" + +#: utils/adt/jsonb.c:1912 +#, fuzzy, c-format +#| msgid "cannot accept a value of type %s" +msgid "cannot cast jsonb numeric to type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: utils/adt/jsonb.c:1913 +#, fuzzy, c-format +#| msgid "cannot accept a value of type %s" +msgid "cannot cast jsonb boolean to type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: utils/adt/jsonb.c:1914 +#, fuzzy, c-format +#| msgid "cannot alter array type %s" +msgid "cannot cast jsonb array to type %s" +msgstr "Array-Typ %s kann nicht verändert werden" + +#: utils/adt/jsonb.c:1915 +#, fuzzy, c-format +#| msgid "cannot accept a value of type %s" +msgid "cannot cast jsonb object to type %s" +msgstr "kann keinen Wert vom Typ %s annehmen" + +#: utils/adt/jsonb.c:1916 +#, fuzzy, c-format +#| msgid "cannot alter array type %s" +msgid "cannot cast jsonb array or object to type %s" +msgstr "Array-Typ %s kann nicht verändert werden" + #: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" @@ -20315,148 +21793,195 @@ msgstr "Anzahl der jsonb-Objekte-Paare überschreitet erlaubtes Maximum (%zu)" msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "Anzahl der jsonb-Arrayelemente überschreitet erlaubtes Maximum (%zu)" -#: utils/adt/jsonb_util.c:1526 utils/adt/jsonb_util.c:1546 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "Gesamtgröße der jsonb-Array-Elemente überschreitet die maximale Größe von %u Bytes" -#: utils/adt/jsonb_util.c:1607 utils/adt/jsonb_util.c:1642 -#: utils/adt/jsonb_util.c:1662 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "Gesamtgröße der jsonb-Objektelemente überschreitet die maximale Größe von %u Bytes" -#: utils/adt/jsonfuncs.c:306 utils/adt/jsonfuncs.c:471 -#: utils/adt/jsonfuncs.c:2058 utils/adt/jsonfuncs.c:2499 -#: utils/adt/jsonfuncs.c:3005 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 #, c-format msgid "cannot call %s on a scalar" msgstr "%s kann nicht mit einem skalaren Wert aufgerufen werden" -#: utils/adt/jsonfuncs.c:311 utils/adt/jsonfuncs.c:458 -#: utils/adt/jsonfuncs.c:2488 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "%s kann nicht mit einem Array aufgerufen werden" -#: utils/adt/jsonfuncs.c:1374 utils/adt/jsonfuncs.c:1409 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "kann nicht die Arraylänge eines skalaren Wertes ermitteln" -#: utils/adt/jsonfuncs.c:1378 utils/adt/jsonfuncs.c:1397 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "kann nicht die Arraylänge eines Nicht-Arrays ermitteln" -#: utils/adt/jsonfuncs.c:1474 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "%s kann nicht mit etwas aufgerufen werden, das kein Objekt ist" -#: utils/adt/jsonfuncs.c:1492 utils/adt/jsonfuncs.c:2171 -#: utils/adt/jsonfuncs.c:2708 +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" -#: utils/adt/jsonfuncs.c:1731 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "kann Array nicht in ein Objekt zerlegen" -#: utils/adt/jsonfuncs.c:1743 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "kann skalaren Wert nicht zerlegen" -#: utils/adt/jsonfuncs.c:1789 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "kann keine Elemente aus einem skalaren Wert auswählen" -#: utils/adt/jsonfuncs.c:1793 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "kann keine Elemente aus einem Objekt auswählen" -#: utils/adt/jsonfuncs.c:2045 utils/adt/jsonfuncs.c:2804 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format msgid "cannot call %s on a non-array" msgstr "%s kann nicht mit etwas aufgerufen werden, das kein Array ist" -#: utils/adt/jsonfuncs.c:2132 utils/adt/jsonfuncs.c:2684 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, c-format +msgid "expected JSON array" +msgstr "JSON-Array wurde erwartet" + +#: utils/adt/jsonfuncs.c:2334 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Prüfen Sie den Wert des Schlüssels »%s«." + +#: utils/adt/jsonfuncs.c:2356 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Prüfen Sie das Arrayelement %s des Schlüssels »%s«." + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "Prüfen Sie das Arrayelement %s." + +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "fehlerhaftes JSON-Array" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "erstes Argument von %s muss ein Zeilentyp sein" -#: utils/adt/jsonfuncs.c:2173 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format msgid "Try calling the function in the FROM clause using a column definition list." msgstr "Versuchen Sie, die Funktion in der FROM-Klausel mit einer Spaltendefinitionsliste aufzurufen." -#: utils/adt/jsonfuncs.c:2820 utils/adt/jsonfuncs.c:2987 +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 #, c-format msgid "argument of %s must be an array of objects" msgstr "Argument von %s muss ein Array von Objekten sein" -#: utils/adt/jsonfuncs.c:2844 +#: utils/adt/jsonfuncs.c:3764 #, c-format msgid "cannot call %s on an object" msgstr "%s kann nicht mit einem Objekt aufgerufen werden" -#: utils/adt/jsonfuncs.c:3411 utils/adt/jsonfuncs.c:3470 -#: utils/adt/jsonfuncs.c:3550 +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 #, c-format msgid "cannot delete from scalar" msgstr "kann nicht aus skalarem Wert löschen" -#: utils/adt/jsonfuncs.c:3555 +#: utils/adt/jsonfuncs.c:4385 #, c-format msgid "cannot delete from object using integer index" msgstr "aus einem Objekt kann nicht per numerischem Index gelöscht werden" -#: utils/adt/jsonfuncs.c:3621 utils/adt/jsonfuncs.c:3713 +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 #, c-format msgid "cannot set path in scalar" msgstr "in einem skalaren Wert kann kein Pfad gesetzt werden" -#: utils/adt/jsonfuncs.c:3666 +#: utils/adt/jsonfuncs.c:4496 #, c-format msgid "cannot delete path in scalar" msgstr "in einem skalaren Wert kann kein Pfad gelöscht werden" -#: utils/adt/jsonfuncs.c:3836 +#: utils/adt/jsonfuncs.c:4666 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "ungültiges Aneinanderhängen von jsonb-Objekten" -#: utils/adt/jsonfuncs.c:3870 +#: utils/adt/jsonfuncs.c:4700 #, c-format msgid "path element at position %d is null" msgstr "Pfadelement auf Position %d ist NULL" -#: utils/adt/jsonfuncs.c:3956 +#: utils/adt/jsonfuncs.c:4786 #, c-format msgid "cannot replace existing key" msgstr "existierender Schlüssel kann nicht ersetzt werden" -#: utils/adt/jsonfuncs.c:3957 +#: utils/adt/jsonfuncs.c:4787 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "Verwenden Sie die Funktion jsonb_set, um den Schlüsselwert zu ersetzen." -#: utils/adt/jsonfuncs.c:4039 +#: utils/adt/jsonfuncs.c:4869 #, c-format msgid "path element at position %d is not an integer: \"%s\"" msgstr "Pfadelement auf Position %d ist keine ganze Zahl: »%s«" +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "" + +#: utils/adt/jsonfuncs.c:4995 +#, fuzzy, c-format +#| msgid "array element type cannot be %s" +msgid "flag array element is not a string" +msgstr "Arrayelementtyp kann nicht %s sein" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "Mögliche Werte sind: »string«, »numeric«, »boolean«, »key« und »all«" + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "" + #: utils/adt/levenshtein.c:133 #, c-format msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "Levenshtein-Argument überschreitet die maximale Länge von %d Zeichen" -#: utils/adt/like.c:212 utils/adt/selfuncs.c:5331 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5806 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "konnte die für ILIKE zu verwendende Sortierfolge nicht bestimmen" @@ -20466,140 +21991,161 @@ msgstr "konnte die für ILIKE zu verwendende Sortierfolge nicht bestimmen" msgid "LIKE pattern must not end with escape character" msgstr "LIKE-Muster darf nicht mit Escape-Zeichen enden" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "ungültige ESCAPE-Zeichenkette" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "ESCAPE-Zeichenkette muss null oder ein Zeichen lang sein." -#: utils/adt/lockfuncs.c:545 +#: utils/adt/lockfuncs.c:664 #, c-format msgid "cannot use advisory locks during a parallel operation" msgstr "während einer parallelen Operation können keine Benutzersperren verwendet werden" -#: utils/adt/mac.c:76 +#: utils/adt/mac.c:102 #, c-format msgid "invalid octet value in \"macaddr\" value: \"%s\"" msgstr "ungültiger Oktettwert in »macaddr«-Wert: »%s«" -#: utils/adt/misc.c:238 +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8-Daten außerhalb des gültigen Bereichs für Umwandlung in macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Nur Adressen, die FF und FE als Werte im 4. und 5. Byte von links haben, zum Beispiel xx:xx:xx:ff:fe:xx:xx:xx, kommen für eine Umwandlung von macaddr8 nach macaddr in Frage." + +#: utils/adt/misc.c:239 #, c-format msgid "PID %d is not a PostgreSQL server process" msgstr "PID %d ist kein PostgreSQL-Serverprozess" -#: utils/adt/misc.c:289 +#: utils/adt/misc.c:290 #, c-format msgid "must be a superuser to cancel superuser query" msgstr "nur Superuser können Anfragen eines Superusers stornieren" -#: utils/adt/misc.c:294 +#: utils/adt/misc.c:295 #, c-format msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" msgstr "muss Mitglied der Rolle sein, deren Anfrage storniert wird, oder Mitglied von pg_signal_backend" -#: utils/adt/misc.c:313 +#: utils/adt/misc.c:314 #, c-format msgid "must be a superuser to terminate superuser process" msgstr "nur Superuser können Prozesse eines Superusers beenden" -#: utils/adt/misc.c:318 +#: utils/adt/misc.c:319 #, c-format msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" msgstr "muss Mitglied der Rolle sein, deren Prozess beendet wird, oder Mitglied von pg_signal_backend" -#: utils/adt/misc.c:335 +#: utils/adt/misc.c:336 #, c-format msgid "failed to send signal to postmaster: %m" msgstr "konnte Signal nicht an Postmaster senden: %m" #: utils/adt/misc.c:355 +#, fuzzy, c-format +#| msgid "Must be superuser to create a tablespace." +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "Nur Superuser können Tablespaces anlegen." + +#: utils/adt/misc.c:356 +#, fuzzy, c-format +#| msgid "Consider using tablespaces instead." +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "Verwenden Sie stattdessen Tablespaces." + +#: utils/adt/misc.c:361 utils/adt/misc.c:381 #, c-format msgid "rotation not possible because log collection not active" msgstr "Rotierung nicht möglich, weil Logsammlung nicht aktiv ist" -#: utils/adt/misc.c:392 +#: utils/adt/misc.c:418 #, c-format msgid "global tablespace never has databases" msgstr "globaler Tablespace hat niemals Datenbanken" -#: utils/adt/misc.c:413 +#: utils/adt/misc.c:439 #, c-format msgid "%u is not a tablespace OID" msgstr "%u ist keine Tablespace-OID" -#: utils/adt/misc.c:606 +#: utils/adt/misc.c:626 msgid "unreserved" msgstr "unreserviert" -#: utils/adt/misc.c:610 +#: utils/adt/misc.c:630 msgid "unreserved (cannot be function or type name)" msgstr "unreserviert (kann nicht Funktions- oder Typname sein)" -#: utils/adt/misc.c:614 +#: utils/adt/misc.c:634 msgid "reserved (can be function or type name)" msgstr "reserviert (kann Funktions- oder Typname sein)" -#: utils/adt/misc.c:618 +#: utils/adt/misc.c:638 msgid "reserved" msgstr "reserviert" -#: utils/adt/misc.c:792 utils/adt/misc.c:806 utils/adt/misc.c:845 -#: utils/adt/misc.c:851 utils/adt/misc.c:857 utils/adt/misc.c:880 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 +#: utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 #, c-format msgid "string is not a valid identifier: \"%s\"" msgstr "Zeichenkette ist kein gültiger Bezeichner: »%s«" -#: utils/adt/misc.c:794 +#: utils/adt/misc.c:814 #, c-format msgid "String has unclosed double quotes." msgstr "Zeichenkette hat nicht geschlossene doppelte Anführungszeichen." -#: utils/adt/misc.c:808 +#: utils/adt/misc.c:828 #, c-format msgid "Quoted identifier must not be empty." msgstr "Bezeichner in Anführungszeichen darf nicht leer sein." -#: utils/adt/misc.c:847 +#: utils/adt/misc.c:867 #, c-format msgid "No valid identifier before \".\"." msgstr "Kein gültiger Bezeichner vor ».«." -#: utils/adt/misc.c:853 +#: utils/adt/misc.c:873 #, c-format msgid "No valid identifier after \".\"." msgstr "Kein gültiger Bezeichner nach ».«." -#: utils/adt/misc.c:914 -#, fuzzy, c-format -#| msgid "interval units \"%s\" not supported" +#: utils/adt/misc.c:934 +#, c-format msgid "log format \"%s\" is not supported" -msgstr "»interval«-Einheit »%s« nicht unterstützt" +msgstr "Logformat »%s« wird nicht unterstützt" -#: utils/adt/misc.c:915 +#: utils/adt/misc.c:935 #, c-format msgid "The supported log formats are \"stderr\" and \"csvlog\"." -msgstr "" +msgstr "Die unterstützten Logformate sind »stderr« und »csvlog«." -#: utils/adt/nabstime.c:137 +#: utils/adt/nabstime.c:140 #, c-format msgid "invalid time zone name: \"%s\"" msgstr "ungültiger Zeitzonenname: »%s«" -#: utils/adt/nabstime.c:482 utils/adt/nabstime.c:555 +#: utils/adt/nabstime.c:485 utils/adt/nabstime.c:558 #, c-format msgid "cannot convert abstime \"invalid\" to timestamp" msgstr "kann »abstime«-Wert »invalid« nicht »timestamp« umwandeln" -#: utils/adt/nabstime.c:782 +#: utils/adt/nabstime.c:785 #, c-format msgid "invalid status in external \"tinterval\" value" msgstr "ungültiger Status in externem »tinterval«-Wert" -#: utils/adt/nabstime.c:852 +#: utils/adt/nabstime.c:855 #, c-format msgid "cannot convert reltime \"invalid\" to interval" msgstr "kann »reltime«-Wert »invalid« nicht in »interval« umwandeln" @@ -20614,8 +22160,8 @@ msgstr "ungültiger cidr-Wert: »%s«" msgid "Value has bits set to right of mask." msgstr "Wert hat gesetzte Bits rechts von der Maske." -#: utils/adt/network.c:111 utils/adt/network.c:582 utils/adt/network.c:607 -#: utils/adt/network.c:632 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 +#: utils/adt/network.c:642 #, c-format msgid "could not format inet value: %m" msgstr "konnte inet-Wert nicht formatieren: %m" @@ -20648,109 +22194,114 @@ msgstr "ungültiger externer »cidr«-Wert" msgid "invalid mask length: %d" msgstr "ungültige Maskenlänge: %d" -#: utils/adt/network.c:650 +#: utils/adt/network.c:660 #, c-format msgid "could not format cidr value: %m" msgstr "konnte cidr-Wert nicht formatieren: %m" -#: utils/adt/network.c:883 +#: utils/adt/network.c:893 #, c-format msgid "cannot merge addresses from different families" msgstr "Adressen verschiedener Familien können nicht zusammengeführt werden" -#: utils/adt/network.c:1292 +#: utils/adt/network.c:1309 #, c-format msgid "cannot AND inet values of different sizes" msgstr "binäres »Und« nicht mit »inet«-Werten unterschiedlicher Größe möglich" -#: utils/adt/network.c:1324 +#: utils/adt/network.c:1341 #, c-format msgid "cannot OR inet values of different sizes" msgstr "binäres »Oder« nicht mit »inet«-Werten unterschiedlicher Größe möglich" -#: utils/adt/network.c:1385 utils/adt/network.c:1461 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format msgid "result is out of range" msgstr "Ergebnis ist außerhalb des gültigen Bereichs" -#: utils/adt/network.c:1426 +#: utils/adt/network.c:1443 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "Subtraktion von »inet«-Werten unterschiedlicher Größe nicht möglich" -#: utils/adt/numeric.c:819 +#: utils/adt/numeric.c:830 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "ungültiges Vorzeichen in externem »numeric«-Wert" -#: utils/adt/numeric.c:825 +#: utils/adt/numeric.c:836 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "ungültige Skala in externem »numeric«-Wert" -#: utils/adt/numeric.c:834 +#: utils/adt/numeric.c:845 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "ungültige Ziffer in externem »numeric«-Wert" -#: utils/adt/numeric.c:1024 utils/adt/numeric.c:1038 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "Präzision von NUMERIC (%d) muss zwischen 1 und %d liegen" -#: utils/adt/numeric.c:1029 +#: utils/adt/numeric.c:1040 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "Skala von NUMERIC (%d) muss zwischen 0 und %d liegen" -#: utils/adt/numeric.c:1047 +#: utils/adt/numeric.c:1058 #, c-format msgid "invalid NUMERIC type modifier" msgstr "ungültiker Modifikator für Typ NUMERIC" -#: utils/adt/numeric.c:1379 +#: utils/adt/numeric.c:1390 #, c-format msgid "start value cannot be NaN" msgstr "Startwert kann nicht NaN sein" -#: utils/adt/numeric.c:1384 +#: utils/adt/numeric.c:1395 #, c-format msgid "stop value cannot be NaN" msgstr "Stoppwert kann nicht NaN sein" -#: utils/adt/numeric.c:1394 +#: utils/adt/numeric.c:1405 #, c-format msgid "step size cannot be NaN" msgstr "Schrittgröße kann nicht NaN sein" -#: utils/adt/numeric.c:2589 utils/adt/numeric.c:5551 utils/adt/numeric.c:5996 -#: utils/adt/numeric.c:7700 utils/adt/numeric.c:8125 utils/adt/numeric.c:8240 -#: utils/adt/numeric.c:8313 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 +#: utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 +#: utils/adt/numeric.c:8490 #, c-format msgid "value overflows numeric format" msgstr "Wert verursacht Überlauf im »numeric«-Format" -#: utils/adt/numeric.c:2931 +#: utils/adt/numeric.c:3095 #, c-format msgid "cannot convert NaN to integer" msgstr "kann NaN nicht in integer umwandeln" -#: utils/adt/numeric.c:2997 +#: utils/adt/numeric.c:3161 #, c-format msgid "cannot convert NaN to bigint" msgstr "kann NaN nicht in bigint umwandeln" -#: utils/adt/numeric.c:3042 +#: utils/adt/numeric.c:3206 #, c-format msgid "cannot convert NaN to smallint" msgstr "kann NaN nicht in smallint umwandeln" -#: utils/adt/numeric.c:6066 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "kann Unendlich nicht in numeric umwandeln" + +#: utils/adt/numeric.c:6240 #, c-format msgid "numeric field overflow" msgstr "Feldüberlauf bei Typ »numeric«" -#: utils/adt/numeric.c:6067 +#: utils/adt/numeric.c:6241 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "Ein Feld mit Präzision %d, Skala %d muss beim Runden einen Betrag von weniger als %s%d ergeben." @@ -20765,86 +22316,132 @@ msgstr "Wert »%s« ist außerhalb des gültigen Bereichs für 8-Bit-Ganzzahl" msgid "invalid oidvector data" msgstr "ungültige oidvector-Daten" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "verlangtes Zeichen zu groß" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "gewünschtes Zeichen ist zu groß für die Kodierung: %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "gewünschtes Zeichen ist nicht gültig für die Kodierung: %d" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "Null-Zeichen ist nicht erlaubt" -#: utils/adt/orderedsetaggs.c:426 utils/adt/orderedsetaggs.c:531 -#: utils/adt/orderedsetaggs.c:670 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "Perzentilwert %g ist nicht zwischen 0 und 1" -#: utils/adt/pg_locale.c:1028 +#: utils/adt/pg_locale.c:1034 #, c-format msgid "Apply system library package updates." msgstr "Aktualisieren Sie die Systembibliotheken." -#: utils/adt/pg_locale.c:1233 +#: utils/adt/pg_locale.c:1249 #, c-format msgid "could not create locale \"%s\": %m" msgstr "konnte Locale »%s« nicht erzeugen: %m" -#: utils/adt/pg_locale.c:1236 +#: utils/adt/pg_locale.c:1252 #, c-format msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "Das Betriebssystem konnte keine Locale-Daten für den Locale-Namen »%s« finden." -#: utils/adt/pg_locale.c:1323 +#: utils/adt/pg_locale.c:1353 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "Sortierfolgen mit unterschiedlichen »collate«- und »ctype«-Werten werden auf dieser Plattform nicht unterstützt" -#: utils/adt/pg_locale.c:1338 +#: utils/adt/pg_locale.c:1362 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "Sortierfolgen-Provider LIBC wird auf dieser Plattform nicht unterstützt" + +#: utils/adt/pg_locale.c:1374 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "Sortierfolgen mit unterschiedlichen »collate«- und »ctype«-Werten werden von ICU nicht unterstützt" + +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "konnte Collator für Locale »%s« nicht öffnen: %s" + +#: utils/adt/pg_locale.c:1391 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU wird in dieser Installation nicht unterstützt" + +#: utils/adt/pg_locale.c:1392 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "Sie müssen PostgreSQL mit --with-icu neu bauen." + +#: utils/adt/pg_locale.c:1412 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "Sortierfolge »%s« hat keine tatsächliche Version, aber eine Version wurde angegeben" + +#: utils/adt/pg_locale.c:1419 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "Version von Sortierfolge »%s« stimmt nicht überein" + +#: utils/adt/pg_locale.c:1421 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Die Sortierfolge in der Datenbank wurde mit Version %s erzeugt, aber das Betriebssystem hat Version %s." + +#: utils/adt/pg_locale.c:1424 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Bauen Sie alle von dieser Sortierfolge beinflussten Objekte neu und führen Sie ALTER COLLATION %s REFRESH VERSION aus, oder bauen Sie PostgreSQL mit der richtigen Bibliotheksversion." + +#: utils/adt/pg_locale.c:1508 #, c-format -msgid "nondefault collations are not supported on this platform" -msgstr "Sortierfolgen außer der Standardsortierfolge werden auf dieser Plattform nicht unterstützt" +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "konnte ICU-Konverter für Kodierung »%s« nicht öffnen: %s" -#: utils/adt/pg_locale.c:1509 +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 +#, c-format +msgid "ucnv_toUChars failed: %s" +msgstr "ucnv_toUChars fehlgeschlagen: %s" + +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 +#, c-format +msgid "ucnv_fromUChars failed: %s" +msgstr "ucnv_fromUChars fehlgeschlagen: %s" + +#: utils/adt/pg_locale.c:1758 #, c-format msgid "invalid multibyte character for locale" msgstr "ungültiges Mehrbytezeichen für Locale" -#: utils/adt/pg_locale.c:1510 +#: utils/adt/pg_locale.c:1759 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "Die LC_CTYPE-Locale des Servers ist wahrscheinlich mit der Kodierung der Datenbank inkompatibel." -#: utils/adt/pg_upgrade_support.c:28 +#: utils/adt/pg_upgrade_support.c:29 #, c-format msgid "function can only be called when server is in binary upgrade mode" msgstr "Funktion kann nur aufgerufen werden, wenn der Server im Binary-Upgrade-Modus ist" -#: utils/adt/pgstatfuncs.c:471 +#: utils/adt/pgstatfuncs.c:474 #, c-format msgid "invalid command name: \"%s\"" msgstr "ungültiger Befehlsname: »%s«" -#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 -#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 -#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 -#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 -#: utils/adt/pseudotypes.c:393 -#, c-format -msgid "cannot accept a value of type %s" -msgstr "kann keinen Wert vom Typ %s annehmen" - #: utils/adt/pseudotypes.c:247 #, c-format msgid "cannot accept a value of a shell type" @@ -20861,10 +22458,9 @@ msgid "cannot output a value of type %s" msgstr "kann keinen Wert vom Typ %s anzeigen" #: utils/adt/pseudotypes.c:403 -#, fuzzy, c-format -#| msgid "cannot display a value of type any" +#, c-format msgid "cannot display a value of type %s" -msgstr "kann keinen Wert vom Typ any anzeigen" +msgstr "kann keinen Wert vom Typ %s anzeigen" #: utils/adt/rangetypes.c:405 #, c-format @@ -20881,215 +22477,217 @@ msgstr "Ergebnis von Bereichsdifferenz würde nicht zusammenhängend sein" msgid "result of range union would not be contiguous" msgstr "Ergebnis von Bereichsvereinigung würde nicht zusammenhängend sein" -#: utils/adt/rangetypes.c:1533 +#: utils/adt/rangetypes.c:1597 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "Bereichsuntergrenze muss kleiner als oder gleich der Bereichsobergrenze sein" -#: utils/adt/rangetypes.c:1916 utils/adt/rangetypes.c:1929 -#: utils/adt/rangetypes.c:1943 +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 +#: utils/adt/rangetypes.c:2007 #, c-format msgid "invalid range bound flags" msgstr "ungültige Markierungen für Bereichsgrenzen" -#: utils/adt/rangetypes.c:1917 utils/adt/rangetypes.c:1930 -#: utils/adt/rangetypes.c:1944 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "Gültige Werte sind »[]«, »[)«, »(]« und »()«." -#: utils/adt/rangetypes.c:2009 utils/adt/rangetypes.c:2026 -#: utils/adt/rangetypes.c:2039 utils/adt/rangetypes.c:2057 -#: utils/adt/rangetypes.c:2068 utils/adt/rangetypes.c:2112 -#: utils/adt/rangetypes.c:2120 +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 +#: utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 +#: utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 +#: utils/adt/rangetypes.c:2184 #, c-format msgid "malformed range literal: \"%s\"" msgstr "fehlerhafte Bereichskonstante: »%s«" -#: utils/adt/rangetypes.c:2011 +#: utils/adt/rangetypes.c:2075 #, c-format msgid "Junk after \"empty\" key word." msgstr "Müll nach Schlüsselwort »empty«." -#: utils/adt/rangetypes.c:2028 +#: utils/adt/rangetypes.c:2092 #, c-format msgid "Missing left parenthesis or bracket." msgstr "Linke runde oder eckige Klammer fehlt." -#: utils/adt/rangetypes.c:2041 +#: utils/adt/rangetypes.c:2105 #, c-format msgid "Missing comma after lower bound." msgstr "Komma fehlt nach Untergrenze." -#: utils/adt/rangetypes.c:2059 +#: utils/adt/rangetypes.c:2123 #, c-format msgid "Too many commas." msgstr "Zu viele Kommas." -#: utils/adt/rangetypes.c:2070 +#: utils/adt/rangetypes.c:2134 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "Müll nach rechter runder oder eckiger Klammer." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1344 utils/adt/varlena.c:3816 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 #, c-format msgid "regular expression failed: %s" msgstr "regulärer Ausdruck fehlgeschlagen: %s" -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 #, c-format msgid "invalid regexp option: \"%c\"" msgstr "ungültige Option für regulären Ausdruck: »%c«" -#: utils/adt/regexp.c:862 -#, fuzzy, c-format -#| msgid "regexp_split does not support the global option" +#: utils/adt/regexp.c:866 +#, c-format msgid "regexp_match does not support the global option" -msgstr "regexp_split unterstützt die »Global«-Option nicht" +msgstr "regexp_match unterstützt die »Global«-Option nicht" -#: utils/adt/regexp.c:863 +#: utils/adt/regexp.c:867 #, c-format msgid "Use the regexp_matches function instead." -msgstr "" +msgstr "Verwenden Sie stattdessen die Funktion regexp_matches." -#: utils/adt/regexp.c:1163 -#, fuzzy, c-format -#| msgid "regexp_split does not support the global option" +#: utils/adt/regexp.c:1049 +#, c-format +msgid "too many regular expression matches" +msgstr "zu viele Treffer für regulären Ausdruck" + +#: utils/adt/regexp.c:1244 +#, c-format msgid "regexp_split_to_table does not support the global option" -msgstr "regexp_split unterstützt die »Global«-Option nicht" +msgstr "regexp_split_to_table unterstützt die »Global«-Option nicht" -#: utils/adt/regexp.c:1219 -#, fuzzy, c-format -#| msgid "regexp_split does not support the global option" +#: utils/adt/regexp.c:1297 +#, c-format msgid "regexp_split_to_array does not support the global option" -msgstr "regexp_split unterstützt die »Global«-Option nicht" +msgstr "regexp_split_to_array unterstützt die »Global«-Option nicht" -#: utils/adt/regproc.c:130 utils/adt/regproc.c:150 +#: utils/adt/regproc.c:106 #, c-format msgid "more than one function named \"%s\"" msgstr "es gibt mehrere Funktionen namens »%s«" -#: utils/adt/regproc.c:589 utils/adt/regproc.c:609 +#: utils/adt/regproc.c:524 #, c-format msgid "more than one operator named %s" msgstr "es gibt mehrere Operatoren namens %s" -#: utils/adt/regproc.c:781 utils/adt/regproc.c:822 utils/adt/regproc.c:2008 -#: utils/adt/ruleutils.c:8718 utils/adt/ruleutils.c:8886 +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9134 utils/adt/ruleutils.c:9302 #, c-format msgid "too many arguments" msgstr "zu viele Argumente" -#: utils/adt/regproc.c:782 utils/adt/regproc.c:823 +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 #, c-format msgid "Provide two argument types for operator." msgstr "Geben Sie zwei Argumente für den Operator an." -#: utils/adt/regproc.c:1596 utils/adt/regproc.c:1620 utils/adt/regproc.c:1717 -#: utils/adt/regproc.c:1741 utils/adt/regproc.c:1843 utils/adt/regproc.c:1848 -#: utils/adt/varlena.c:3071 utils/adt/varlena.c:3076 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 #, c-format msgid "invalid name syntax" msgstr "ungültige Namenssyntax" -#: utils/adt/regproc.c:1906 +#: utils/adt/regproc.c:1763 #, c-format msgid "expected a left parenthesis" msgstr "linke Klammer erwartet" -#: utils/adt/regproc.c:1922 +#: utils/adt/regproc.c:1779 #, c-format msgid "expected a right parenthesis" msgstr "rechte Klammer erwartet" -#: utils/adt/regproc.c:1941 +#: utils/adt/regproc.c:1798 #, c-format msgid "expected a type name" msgstr "Typname erwartet" -#: utils/adt/regproc.c:1973 +#: utils/adt/regproc.c:1830 #, c-format msgid "improper type name" msgstr "falscher Typname" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 -#: utils/adt/ri_triggers.c:3315 +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 +#: utils/adt/ri_triggers.c:2767 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "Einfügen oder Aktualisieren in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s«" -#: utils/adt/ri_triggers.c:346 utils/adt/ri_triggers.c:2493 +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL erlaubt das Mischen von Schlüsseln, die NULL und nicht NULL sind, nicht." -#: utils/adt/ri_triggers.c:2732 +#: utils/adt/ri_triggers.c:2273 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "Funktion »%s« muss von INSERT ausgelöst werden" -#: utils/adt/ri_triggers.c:2738 +#: utils/adt/ri_triggers.c:2279 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "Funktion »%s« muss von UPDATE ausgelöst werden" -#: utils/adt/ri_triggers.c:2744 +#: utils/adt/ri_triggers.c:2285 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "Funktion »%s« muss von DELETE ausgelöst werden" -#: utils/adt/ri_triggers.c:2767 +#: utils/adt/ri_triggers.c:2308 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "kein »pg_constraint«-Eintrag für Trigger »%s« für Tabelle »%s«" -#: utils/adt/ri_triggers.c:2769 +#: utils/adt/ri_triggers.c:2310 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "Entfernen Sie diesen Referentielle-Integritäts-Trigger und seine Partner und führen Sie dann ALTER TABLE ADD CONSTRAINT aus." -#: utils/adt/ri_triggers.c:3225 +#: utils/adt/ri_triggers.c:2614 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "RI-Anfrage in Tabelle »%s« für Constraint »%s« von Tabelle »%s« ergab unerwartetes Ergebnis" -#: utils/adt/ri_triggers.c:3229 +#: utils/adt/ri_triggers.c:2618 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Das liegt höchstwahrscheinlich daran, dass eine Regel die Anfrage umgeschrieben hat." -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/ri_triggers.c:2771 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "Schlüssel (%s)=(%s) ist nicht in Tabelle »%s« vorhanden." -#: utils/adt/ri_triggers.c:3322 +#: utils/adt/ri_triggers.c:2774 #, c-format msgid "Key is not present in table \"%s\"." msgstr "Der Schlüssel ist nicht in Tabelle »%s« vorhanden." -#: utils/adt/ri_triggers.c:3328 +#: utils/adt/ri_triggers.c:2780 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "Aktualisieren oder Löschen in Tabelle »%s« verletzt Fremdschlüssel-Constraint »%s« von Tabelle »%s«" -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/ri_triggers.c:2785 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "Auf Schlüssel (%s)=(%s) wird noch aus Tabelle »%s« verwiesen." -#: utils/adt/ri_triggers.c:3336 +#: utils/adt/ri_triggers.c:2788 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "Auf den Schlüssel wird noch aus Tabelle »%s« verwiesen." -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "Eingabe anonymer zusammengesetzter Typen ist nicht implementiert" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 +#: utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 #, c-format msgid "malformed record literal: \"%s\"" msgstr "fehlerhafte Record-Konstante: »%s«" @@ -21099,193 +22697,193 @@ msgstr "fehlerhafte Record-Konstante: »%s«" msgid "Missing left parenthesis." msgstr "Linke Klammer fehlt." -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:185 #, c-format msgid "Too few columns." msgstr "Zu wenige Spalten." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:268 #, c-format msgid "Too many columns." msgstr "Zu viele Spalten." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:276 #, c-format msgid "Junk after right parenthesis." msgstr "Müll nach rechter Klammer." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:530 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "falsche Anzahl der Spalten: %d, erwartet wurden %d" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:558 #, c-format msgid "wrong data type: %u, expected %u" msgstr "falscher Datentyp: %u, erwartet wurde %u" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:619 #, c-format msgid "improper binary format in record column %d" msgstr "falsches Binärformat in Record-Spalte %d" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 -#: utils/adt/rowtypes.c:1396 utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 +#: utils/adt/rowtypes.c:1657 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "kann unterschiedliche Spaltentyp %s und %s in Record-Spalte %d nicht vergleichen" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 -#: utils/adt/rowtypes.c:1529 utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 +#: utils/adt/rowtypes.c:1731 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "kann Record-Typen mit unterschiedlicher Anzahl Spalten nicht vergleichen" -#: utils/adt/ruleutils.c:4494 +#: utils/adt/ruleutils.c:4825 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "Regel »%s« hat nicht unterstützten Ereignistyp %d" -#: utils/adt/selfuncs.c:5316 +#: utils/adt/selfuncs.c:5791 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "Mustersuche ohne Rücksicht auf Groß-/Kleinschreibung wird für Typ bytea nicht unterstützt" -#: utils/adt/selfuncs.c:5418 +#: utils/adt/selfuncs.c:5893 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "Mustersuche mit regulären Ausdrücken wird für Typ bytea nicht unterstützt" -#: utils/adt/timestamp.c:106 +#: utils/adt/timestamp.c:107 #, c-format msgid "TIMESTAMP(%d)%s precision must not be negative" msgstr "Präzision von TIMESTAMP(%d)%s darf nicht negativ sein" -#: utils/adt/timestamp.c:112 +#: utils/adt/timestamp.c:113 #, c-format msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "Präzision von TIMESTAMP(%d)%s auf erlaubten Höchstwert %d reduziert" -#: utils/adt/timestamp.c:175 utils/adt/timestamp.c:415 +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 #, c-format msgid "timestamp out of range: \"%s\"" msgstr "timestamp ist außerhalb des gültigen Bereichs: »%s«" -#: utils/adt/timestamp.c:193 utils/adt/timestamp.c:433 -#: utils/adt/timestamp.c:940 +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 +#: utils/adt/timestamp.c:941 #, c-format msgid "date/time value \"%s\" is no longer supported" msgstr "Datum/Zeit-Wert »%s« wird nicht mehr unterstützt" -#: utils/adt/timestamp.c:361 +#: utils/adt/timestamp.c:362 #, c-format msgid "timestamp(%d) precision must be between %d and %d" msgstr "Präzision von timestamp(%d) muss zwischen %d und %d sein" -#: utils/adt/timestamp.c:483 +#: utils/adt/timestamp.c:484 #, c-format msgid "invalid input syntax for numeric time zone: \"%s\"" msgstr "ungültige Eingabesyntax für numerische Zeitzone: »%s«" -#: utils/adt/timestamp.c:485 +#: utils/adt/timestamp.c:486 #, c-format msgid "Numeric time zones must have \"-\" or \"+\" as first character." msgstr "Numerische Zeitzonen müssen »-« oder »+« als erstes Zeichen haben." -#: utils/adt/timestamp.c:498 +#: utils/adt/timestamp.c:499 #, c-format msgid "numeric time zone \"%s\" out of range" msgstr "numerische Zeitzone »%s« ist außerhalb des gültigen Bereichs" -#: utils/adt/timestamp.c:600 utils/adt/timestamp.c:610 -#: utils/adt/timestamp.c:618 +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 #, c-format msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" msgstr "timestamp ist außerhalb des gültigen Bereichs: %d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:719 +#: utils/adt/timestamp.c:720 #, c-format msgid "timestamp cannot be NaN" msgstr "timestamp kann nicht NaN sein" -#: utils/adt/timestamp.c:737 utils/adt/timestamp.c:749 +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 #, c-format msgid "timestamp out of range: \"%g\"" msgstr "timestamp ist außerhalb des gültigen Bereichs: »%g«" -#: utils/adt/timestamp.c:934 utils/adt/timestamp.c:1504 -#: utils/adt/timestamp.c:1917 utils/adt/timestamp.c:2964 -#: utils/adt/timestamp.c:2969 utils/adt/timestamp.c:2974 -#: utils/adt/timestamp.c:3024 utils/adt/timestamp.c:3031 -#: utils/adt/timestamp.c:3038 utils/adt/timestamp.c:3058 -#: utils/adt/timestamp.c:3065 utils/adt/timestamp.c:3072 -#: utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3110 -#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3477 -#: utils/adt/timestamp.c:3602 utils/adt/timestamp.c:3970 +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 +#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3016 +#: utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3026 +#: utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3083 +#: utils/adt/timestamp.c:3090 utils/adt/timestamp.c:3110 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3162 +#: utils/adt/timestamp.c:3206 utils/adt/timestamp.c:3633 +#: utils/adt/timestamp.c:3758 utils/adt/timestamp.c:4143 #, c-format msgid "interval out of range" msgstr "interval-Wert ist außerhalb des gültigen Bereichs" -#: utils/adt/timestamp.c:1067 utils/adt/timestamp.c:1100 +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 #, c-format msgid "invalid INTERVAL type modifier" msgstr "ungültiger Modifikator für Typ INTERVAL" -#: utils/adt/timestamp.c:1083 +#: utils/adt/timestamp.c:1084 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "INTERVAL(%d)-Präzision darf nicht negativ sein" -#: utils/adt/timestamp.c:1089 +#: utils/adt/timestamp.c:1090 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "INTERVAL(%d)-Präzision auf erlaubtes Maximum %d reduziert" -#: utils/adt/timestamp.c:1461 +#: utils/adt/timestamp.c:1462 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "Präzision von interval(%d) muss zwischen %d und %d sein" -#: utils/adt/timestamp.c:2565 +#: utils/adt/timestamp.c:2617 #, c-format msgid "cannot subtract infinite timestamps" msgstr "kann unendliche timestamp-Werte nicht subtrahieren" -#: utils/adt/timestamp.c:3721 utils/adt/timestamp.c:4230 -#: utils/adt/timestamp.c:4397 utils/adt/timestamp.c:4418 +#: utils/adt/timestamp.c:3886 utils/adt/timestamp.c:4403 +#: utils/adt/timestamp.c:4570 utils/adt/timestamp.c:4591 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "»timestamp«-Einheit »%s« nicht unterstützt" -#: utils/adt/timestamp.c:3735 utils/adt/timestamp.c:4184 -#: utils/adt/timestamp.c:4428 +#: utils/adt/timestamp.c:3900 utils/adt/timestamp.c:4357 +#: utils/adt/timestamp.c:4601 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "»timestamp«-Einheit »%s« nicht erkannt" -#: utils/adt/timestamp.c:3867 utils/adt/timestamp.c:4225 -#: utils/adt/timestamp.c:4598 utils/adt/timestamp.c:4620 +#: utils/adt/timestamp.c:4032 utils/adt/timestamp.c:4398 +#: utils/adt/timestamp.c:4771 utils/adt/timestamp.c:4793 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "»timestamp with time zone«-Einheit »%s« nicht unterstützt" -#: utils/adt/timestamp.c:3884 utils/adt/timestamp.c:4179 -#: utils/adt/timestamp.c:4629 +#: utils/adt/timestamp.c:4049 utils/adt/timestamp.c:4352 +#: utils/adt/timestamp.c:4802 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "»timestamp with time zone«-Einheit »%s« nicht erkannt" -#: utils/adt/timestamp.c:3957 +#: utils/adt/timestamp.c:4130 #, c-format msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "»interval«-Einheit »%s« wird nicht unterstützt, weil Monate gewöhnlich partielle Wochen haben" -#: utils/adt/timestamp.c:3963 utils/adt/timestamp.c:4723 +#: utils/adt/timestamp.c:4136 utils/adt/timestamp.c:4896 #, c-format msgid "interval units \"%s\" not supported" msgstr "»interval«-Einheit »%s« nicht unterstützt" -#: utils/adt/timestamp.c:3979 utils/adt/timestamp.c:4746 +#: utils/adt/timestamp.c:4152 utils/adt/timestamp.c:4919 #, c-format msgid "interval units \"%s\" not recognized" msgstr "»interval«-Einheit »%s« nicht erkannt" @@ -21315,43 +22913,43 @@ msgstr "suppress_redundant_updates_trigger: muss für jede Zeile aufgerufen werd msgid "gtsvector_in not implemented" msgstr "gtsvector_in ist nicht implementiert" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "Abstand im Phrasenoperator sollte nicht größer als %d sein" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "Syntaxfehler in tsquery: »%s«" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "kein Operand in tsquery: »%s«" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "Wert ist zu groß in tsquery: »%s«" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "Operator ist zu lang in tsquery: »%s«" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "Wort ist zu lang in tsquery: »%s«" -#: utils/adt/tsquery.c:642 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "Textsucheanfrage enthält keine Lexeme: »%s«" -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "tsquery ist zu groß" @@ -21457,69 +23055,74 @@ msgstr "Textsuchekonfigurationsname »%s« muss Schemaqualifikation haben" msgid "column \"%s\" is not of a character type" msgstr "Spalte »%s« hat keinen Zeichentyp" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "Syntaxfehler in tsvector: »%s«" -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "es gibt kein escaptes Zeichen: »%s«" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "falsche Positionsinformationen in tsvector: »%s«" -#: utils/adt/txid.c:555 +#: utils/adt/txid.c:135 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "Transaktions-ID %s ist in der Zukunft" + +#: utils/adt/txid.c:624 #, c-format msgid "invalid external txid_snapshot data" msgstr "ungültige externe txid_snapshot-Daten" -#: utils/adt/varbit.c:58 utils/adt/varchar.c:51 +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 #, c-format msgid "length for type %s must be at least 1" msgstr "Länge von Typ %s muss mindestens 1 sein" -#: utils/adt/varbit.c:63 utils/adt/varchar.c:55 +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 #, c-format msgid "length for type %s cannot exceed %d" msgstr "Länge von Typ %s kann %d nicht überschreiten" -#: utils/adt/varbit.c:164 utils/adt/varbit.c:476 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "Länge der Bitkette überschreitet erlaubtes Maximum (%d)" -#: utils/adt/varbit.c:178 utils/adt/varbit.c:321 utils/adt/varbit.c:378 +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "Länge der Bitkette %d stimmt nicht mit Typ bit(%d) überein" -#: utils/adt/varbit.c:200 utils/adt/varbit.c:512 +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "»%c« ist keine gültige Binärziffer" -#: utils/adt/varbit.c:225 utils/adt/varbit.c:537 +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "»%c« ist keine gültige Hexadezimalziffer" -#: utils/adt/varbit.c:312 utils/adt/varbit.c:628 +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 #, c-format msgid "invalid length in external bit string" msgstr "ungültige Länge in externer Bitkette" -#: utils/adt/varbit.c:490 utils/adt/varbit.c:637 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "Bitkette ist zu lang für Typ bit varying(%d)" -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:843 -#: utils/adt/varlena.c:907 utils/adt/varlena.c:1051 utils/adt/varlena.c:2736 -#: utils/adt/varlena.c:2803 +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 +#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 +#: utils/adt/varlena.c:2979 #, c-format msgid "negative substring length not allowed" msgstr "negative Teilzeichenkettenlänge nicht erlaubt" @@ -21544,7 +23147,7 @@ msgstr "binäres »Exklusiv-Oder« nicht mit Bitketten unterschiedlicher Länge msgid "bit index %d out of valid range (0..%d)" msgstr "Bitindex %d ist außerhalb des gültigen Bereichs (0..%d)" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:2995 +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 #, c-format msgid "new bit must be 0 or 1" msgstr "neues Bit muss 0 oder 1 sein" @@ -21559,68 +23162,78 @@ msgstr "Wert zu lang für Typ character(%d)" msgid "value too long for type character varying(%d)" msgstr "Wert zu lang für Typ character varying(%d)" -#: utils/adt/varlena.c:1421 utils/adt/varlena.c:1826 +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "konnte die für den Zeichenkettenvergleich zu verwendende Sortierfolge nicht bestimmen" -#: utils/adt/varlena.c:1479 utils/adt/varlena.c:1492 +#: utils/adt/varlena.c:1472 utils/adt/varlena.c:1485 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "konnte Zeichenkette nicht in UTF-16 umwandeln: Fehlercode %lu" -#: utils/adt/varlena.c:1507 +#: utils/adt/varlena.c:1500 #, c-format msgid "could not compare Unicode strings: %m" msgstr "konnte Unicode-Zeichenketten nicht vergleichen: %m" -#: utils/adt/varlena.c:2881 utils/adt/varlena.c:2912 utils/adt/varlena.c:2947 -#: utils/adt/varlena.c:2983 +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 +#, c-format +msgid "collation failed: %s" +msgstr "Vergleichung fehlgeschlagen: %s" + +#: utils/adt/varlena.c:2394 +#, c-format +msgid "sort key generation failed: %s" +msgstr "Sortierschlüsselerzeugung fehlgeschlagen: %s" + +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 +#: utils/adt/varlena.c:3158 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "Index %d ist außerhalb des gültigen Bereichs, 0..%d" -#: utils/adt/varlena.c:3912 +#: utils/adt/varlena.c:4201 #, c-format msgid "field position must be greater than zero" msgstr "Feldposition muss größer als null sein" -#: utils/adt/varlena.c:4791 +#: utils/adt/varlena.c:5080 #, c-format msgid "unterminated format() type specifier" msgstr "Typspezifikation in format() nicht abgeschlossen" -#: utils/adt/varlena.c:4792 utils/adt/varlena.c:4926 utils/adt/varlena.c:5047 +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Für ein einzelnes »%%« geben Sie »%%%%« an." -#: utils/adt/varlena.c:4924 utils/adt/varlena.c:5045 +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 #, c-format msgid "unrecognized format() type specifier \"%c\"" msgstr "unbekannte Typspezifikation in format(): »%c«" -#: utils/adt/varlena.c:4937 utils/adt/varlena.c:4994 +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 #, c-format msgid "too few arguments for format()" msgstr "zu wenige Argumente für format()" -#: utils/adt/varlena.c:5089 utils/adt/varlena.c:5272 +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 #, c-format msgid "number is out of range" msgstr "Zahl ist außerhalb des gültigen Bereichs" -#: utils/adt/varlena.c:5153 utils/adt/varlena.c:5181 +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "Format gibt Argument 0 an, aber die Argumente sind von 1 an nummeriert" -#: utils/adt/varlena.c:5174 +#: utils/adt/varlena.c:5463 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "Argumentposition der Breitenangabe muss mit »$« enden" -#: utils/adt/varlena.c:5219 +#: utils/adt/varlena.c:5508 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "NULL-Werte können nicht als SQL-Bezeichner formatiert werden" @@ -21635,251 +23248,247 @@ msgstr "Argument von ntile muss größer als null sein" msgid "argument of nth_value must be greater than zero" msgstr "Argument von nth_value muss größer als null sein" -#: utils/adt/xml.c:217 +#: utils/adt/xml.c:220 #, c-format msgid "unsupported XML feature" msgstr "nicht unterstützte XML-Funktionalität" -#: utils/adt/xml.c:218 +#: utils/adt/xml.c:221 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "Diese Funktionalität verlangt, dass der Server mit Libxml-Unterstützung gebaut wird." -#: utils/adt/xml.c:219 +#: utils/adt/xml.c:222 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "Sie müssen PostgreSQL mit --with-libxml neu bauen." -#: utils/adt/xml.c:238 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:241 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "ungültiger Kodierungsname »%s«" -#: utils/adt/xml.c:481 utils/adt/xml.c:486 +#: utils/adt/xml.c:484 utils/adt/xml.c:489 #, c-format msgid "invalid XML comment" msgstr "ungültiger XML-Kommentar" -#: utils/adt/xml.c:615 +#: utils/adt/xml.c:618 #, c-format msgid "not an XML document" msgstr "kein XML-Dokument" -#: utils/adt/xml.c:774 utils/adt/xml.c:797 +#: utils/adt/xml.c:777 utils/adt/xml.c:800 #, c-format msgid "invalid XML processing instruction" msgstr "ungültige XML-Verarbeitungsanweisung" -#: utils/adt/xml.c:775 +#: utils/adt/xml.c:778 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "Die Zielangabe der XML-Verarbeitungsanweisung darf nicht »%s« sein." -#: utils/adt/xml.c:798 +#: utils/adt/xml.c:801 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "XML-Verarbeitungsanweisung darf nicht »?>« enthalten." -#: utils/adt/xml.c:877 +#: utils/adt/xml.c:880 #, c-format msgid "xmlvalidate is not implemented" msgstr "xmlvalidate ist nicht implementiert" -#: utils/adt/xml.c:956 +#: utils/adt/xml.c:959 #, c-format msgid "could not initialize XML library" msgstr "konnte XML-Bibliothek nicht initialisieren" -#: utils/adt/xml.c:957 +#: utils/adt/xml.c:960 #, c-format msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "libxml2 hat inkompatiblen char-Typ: sizeof(char)=%u, sizeof(xmlChar)=%u." -#: utils/adt/xml.c:1043 +#: utils/adt/xml.c:1046 #, c-format msgid "could not set up XML error handler" msgstr "konnte XML-Fehlerbehandlung nicht einrichten" -#: utils/adt/xml.c:1044 +#: utils/adt/xml.c:1047 #, c-format msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." msgstr "Das deutet wahrscheinlich darauf hin, dass die verwendete Version von libxml2 nicht mit den Header-Dateien der Version, mit der PostgreSQL gebaut wurde, kompatibel ist." -#: utils/adt/xml.c:1794 +#: utils/adt/xml.c:1800 msgid "Invalid character value." msgstr "Ungültiger Zeichenwert." -#: utils/adt/xml.c:1797 +#: utils/adt/xml.c:1803 msgid "Space required." msgstr "Leerzeichen benötigt." -#: utils/adt/xml.c:1800 +#: utils/adt/xml.c:1806 msgid "standalone accepts only 'yes' or 'no'." msgstr "standalone akzeptiert nur »yes« oder »no«." -#: utils/adt/xml.c:1803 +#: utils/adt/xml.c:1809 msgid "Malformed declaration: missing version." msgstr "Fehlerhafte Deklaration: Version fehlt." -#: utils/adt/xml.c:1806 +#: utils/adt/xml.c:1812 msgid "Missing encoding in text declaration." msgstr "Fehlende Kodierung in Textdeklaration." -#: utils/adt/xml.c:1809 +#: utils/adt/xml.c:1815 msgid "Parsing XML declaration: '?>' expected." msgstr "Beim Parsen der XML-Deklaration: »?>« erwartet." -#: utils/adt/xml.c:1812 +#: utils/adt/xml.c:1818 #, c-format msgid "Unrecognized libxml error code: %d." msgstr "Unbekannter Libxml-Fehlercode: %d." -#: utils/adt/xml.c:2087 +#: utils/adt/xml.c:2093 #, c-format msgid "XML does not support infinite date values." msgstr "XML unterstützt keine unendlichen Datumswerte." -#: utils/adt/xml.c:2109 utils/adt/xml.c:2136 +#: utils/adt/xml.c:2115 utils/adt/xml.c:2142 #, c-format msgid "XML does not support infinite timestamp values." msgstr "XML unterstützt keine unendlichen timestamp-Werte." -#: utils/adt/xml.c:2539 +#: utils/adt/xml.c:2554 #, c-format msgid "invalid query" msgstr "ungültige Anfrage" -#: utils/adt/xml.c:3858 +#: utils/adt/xml.c:3877 #, c-format msgid "invalid array for XML namespace mapping" msgstr "ungültiges Array for XML-Namensraumabbildung" -#: utils/adt/xml.c:3859 +#: utils/adt/xml.c:3878 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "Das Array muss zweidimensional sein und die Länge der zweiten Achse muss gleich 2 sein." -#: utils/adt/xml.c:3883 +#: utils/adt/xml.c:3902 #, c-format msgid "empty XPath expression" msgstr "leerer XPath-Ausdruck" -#: utils/adt/xml.c:3927 +#: utils/adt/xml.c:3954 #, c-format msgid "neither namespace name nor URI may be null" msgstr "weder Namensraumname noch URI dürfen NULL sein" -#: utils/adt/xml.c:3934 +#: utils/adt/xml.c:3961 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "konnte XML-Namensraum mit Namen »%s« und URI »%s« nicht registrieren" -#: utils/adt/xml.c:4288 -#, fuzzy, c-format -#| msgid "LIMIT #,# syntax is not supported" +#: utils/adt/xml.c:4312 +#, c-format msgid "DEFAULT namespace is not supported" -msgstr "Syntax LIMIT x,y wird nicht unterstützt" +msgstr "DEFAULT-Namensraum wird nicht unterstützt" -#: utils/adt/xml.c:4317 -#, fuzzy, c-format -#| msgid "Quoted identifier must not be empty." +#: utils/adt/xml.c:4341 +#, c-format msgid "row path filter must not be empty string" -msgstr "Bezeichner in Anführungszeichen darf nicht leer sein." +msgstr "Zeilenpfadfilter darf nicht leer sein" -#: utils/adt/xml.c:4348 -#, fuzzy, c-format -#| msgid "Quoted identifier must not be empty." +#: utils/adt/xml.c:4372 +#, c-format msgid "column path filter must not be empty string" -msgstr "Bezeichner in Anführungszeichen darf nicht leer sein." +msgstr "Spaltenpfadfilter darf nicht leer sein" -#: utils/adt/xml.c:4531 -#, fuzzy, c-format -#| msgid "more than one row returned by a subquery used as an expression" +#: utils/adt/xml.c:4558 +#, c-format msgid "more than one value returned by column XPath expression" -msgstr "als Ausdruck verwendete Unteranfrage ergab mehr als eine Zeile" +msgstr "XPath-Ausdruck für Spalte gab mehr als einen Wert zurück" -#: utils/cache/lsyscache.c:2580 utils/cache/lsyscache.c:2613 -#: utils/cache/lsyscache.c:2646 utils/cache/lsyscache.c:2679 +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "Typ %s ist nur eine Hülle" -#: utils/cache/lsyscache.c:2585 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "keine Eingabefunktion verfügbar für Typ %s" -#: utils/cache/lsyscache.c:2618 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "keine Ausgabefunktion verfügbar für Typ %s" -#: utils/cache/plancache.c:718 +#: utils/cache/partcache.c:202 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "in Operatorklasse »%s« für Zugriffsmethode %s fehlt Support-Funktion %d für Typ %s" + +#: utils/cache/plancache.c:723 #, c-format msgid "cached plan must not change result type" msgstr "gecachter Plan darf den Ergebnistyp nicht ändern" -#: utils/cache/relcache.c:5700 +#: utils/cache/relcache.c:5800 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "konnte Initialisierungsdatei für Relationscache »%s« nicht erzeugen: %m" -#: utils/cache/relcache.c:5702 +#: utils/cache/relcache.c:5802 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Setze trotzdem fort, aber irgendwas stimmt nicht." -#: utils/cache/relcache.c:5976 +#: utils/cache/relcache.c:6156 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "konnte Cache-Datei »%s« nicht löschen: %m" -#: utils/cache/relmapper.c:508 +#: utils/cache/relmapper.c:513 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die das Relation-Mapping geändert hat" -#: utils/cache/relmapper.c:651 utils/cache/relmapper.c:751 +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 #, c-format msgid "could not open relation mapping file \"%s\": %m" msgstr "konnte Relation-Mapping-Datei »%s« nicht öffnen: %m" -#: utils/cache/relmapper.c:664 +#: utils/cache/relmapper.c:669 #, c-format msgid "could not read relation mapping file \"%s\": %m" msgstr "konnte nicht aus Relation-Mapping-Datei »%s« lesen: %m" -#: utils/cache/relmapper.c:674 +#: utils/cache/relmapper.c:680 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "Relation-Mapping-Datei »%s« enthält ungültige Daten" -#: utils/cache/relmapper.c:684 +#: utils/cache/relmapper.c:690 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "Relation-Mapping-Datei »%s« enthält falsche Prüfsumme" -#: utils/cache/relmapper.c:784 +#: utils/cache/relmapper.c:789 #, c-format msgid "could not write to relation mapping file \"%s\": %m" msgstr "konnte nicht in Relation-Mapping-Datei »%s« schreiben: %m" -#: utils/cache/relmapper.c:797 +#: utils/cache/relmapper.c:804 #, c-format msgid "could not fsync relation mapping file \"%s\": %m" msgstr "konnte Relation-Mapping-Datei »%s« nicht fsyncen: %m" -#: utils/cache/relmapper.c:803 -#, c-format -msgid "could not close relation mapping file \"%s\": %m" -msgstr "konnte Relation-Mapping-Datei »%s« nicht schließen: %m" - -#: utils/cache/typcache.c:1211 -#, c-format -msgid "type %s is not composite" -msgstr "Typ %s ist kein zusammengesetzter Typ" +#: utils/cache/relmapper.c:811 +#, c-format +msgid "could not close relation mapping file \"%s\": %m" +msgstr "konnte Relation-Mapping-Datei »%s« nicht schließen: %m" -#: utils/cache/typcache.c:1225 +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 #, c-format msgid "record type has not been registered" msgstr "Record-Typ wurde nicht registriert" @@ -21894,528 +23503,565 @@ msgstr "TRAP: ExceptionalCondition: fehlerhafte Argumente\n" msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" msgstr "TRAP: %s(»%s«, Datei: »%s«, Zeile: %d)\n" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/error/elog.c:322 utils/error/elog.c:1304 #, c-format msgid "error occurred at %s:%d before error message processing is available\n" msgstr "Fehler geschah bei %s:%d bevor Fehlermeldungsverarbeitung bereit war\n" -#: utils/error/elog.c:1889 +#: utils/error/elog.c:1882 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" msgstr "konnte Datei »%s« nicht als stderr neu öffnen: %m" -#: utils/error/elog.c:1902 +#: utils/error/elog.c:1895 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" msgstr "konnte Datei »%s« nicht als stdou neu öffnen: %m" -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 +#: utils/error/elog.c:2387 utils/error/elog.c:2404 utils/error/elog.c:2420 msgid "[unknown]" msgstr "[unbekannt]" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 +#: utils/error/elog.c:2880 utils/error/elog.c:3183 utils/error/elog.c:3291 msgid "missing error text" msgstr "fehlender Fehlertext" -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 -#: utils/error/elog.c:3299 +#: utils/error/elog.c:2883 utils/error/elog.c:2886 utils/error/elog.c:3294 +#: utils/error/elog.c:3297 #, c-format msgid " at character %d" msgstr " bei Zeichen %d" -#: utils/error/elog.c:2898 utils/error/elog.c:2905 +#: utils/error/elog.c:2896 utils/error/elog.c:2903 msgid "DETAIL: " msgstr "DETAIL: " -#: utils/error/elog.c:2912 +#: utils/error/elog.c:2910 msgid "HINT: " msgstr "TIPP: " -#: utils/error/elog.c:2919 +#: utils/error/elog.c:2917 msgid "QUERY: " msgstr "ANFRAGE: " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2924 msgid "CONTEXT: " msgstr "ZUSAMMENHANG: " -#: utils/error/elog.c:2936 +#: utils/error/elog.c:2934 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "ORT: %s, %s:%d\n" -#: utils/error/elog.c:2943 +#: utils/error/elog.c:2941 #, c-format msgid "LOCATION: %s:%d\n" msgstr "ORT: %s:%d\n" -#: utils/error/elog.c:2957 +#: utils/error/elog.c:2955 msgid "STATEMENT: " msgstr "ANWEISUNG: " #. translator: This string will be truncated at 47 #. characters expanded. -#: utils/error/elog.c:3414 +#: utils/error/elog.c:3412 #, c-format msgid "operating system error %d" msgstr "Betriebssystemfehler %d" -#: utils/error/elog.c:3612 +#: utils/error/elog.c:3610 msgid "DEBUG" msgstr "DEBUG" -#: utils/error/elog.c:3616 +#: utils/error/elog.c:3614 msgid "LOG" msgstr "LOG" -#: utils/error/elog.c:3619 +#: utils/error/elog.c:3617 msgid "INFO" msgstr "INFO" -#: utils/error/elog.c:3622 +#: utils/error/elog.c:3620 msgid "NOTICE" msgstr "HINWEIS" -#: utils/error/elog.c:3625 +#: utils/error/elog.c:3623 msgid "WARNING" msgstr "WARNUNG" -#: utils/error/elog.c:3628 +#: utils/error/elog.c:3626 msgid "ERROR" msgstr "FEHLER" -#: utils/error/elog.c:3631 +#: utils/error/elog.c:3629 msgid "FATAL" msgstr "FATAL" -#: utils/error/elog.c:3634 +#: utils/error/elog.c:3632 msgid "PANIC" msgstr "PANIK" -#: utils/fmgr/dfmgr.c:117 +#: utils/fmgr/dfmgr.c:121 #, c-format msgid "could not find function \"%s\" in file \"%s\"" msgstr "konnte Funktion »%s« nicht in Datei »%s« finden" -#: utils/fmgr/dfmgr.c:196 utils/fmgr/dfmgr.c:413 utils/fmgr/dfmgr.c:461 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "konnte nicht auf Datei »%s« zugreifen: %m" - -#: utils/fmgr/dfmgr.c:234 +#: utils/fmgr/dfmgr.c:239 #, c-format msgid "could not load library \"%s\": %s" msgstr "konnte Bibliothek »%s« nicht laden: %s" -#: utils/fmgr/dfmgr.c:266 +#: utils/fmgr/dfmgr.c:271 #, c-format msgid "incompatible library \"%s\": missing magic block" msgstr "inkompatible Bibliothek »%s«: magischer Block fehlt" -#: utils/fmgr/dfmgr.c:268 +#: utils/fmgr/dfmgr.c:273 #, c-format msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." msgstr "Erweiterungsbibliotheken müssen das Makro PG_MODULE_MAGIC verwenden." -#: utils/fmgr/dfmgr.c:314 +#: utils/fmgr/dfmgr.c:319 #, c-format msgid "incompatible library \"%s\": version mismatch" msgstr "inkompatible Bibliothek »%s«: Version stimmt nicht überein" -#: utils/fmgr/dfmgr.c:316 +#: utils/fmgr/dfmgr.c:321 #, c-format msgid "Server is version %d, library is version %s." msgstr "Serverversion ist %d, Bibliotheksversion ist %s." -#: utils/fmgr/dfmgr.c:333 +#: utils/fmgr/dfmgr.c:338 #, c-format msgid "Server has FUNC_MAX_ARGS = %d, library has %d." msgstr "Server hat FUNC_MAX_ARGS = %d, Bibliothek hat %d." -#: utils/fmgr/dfmgr.c:342 +#: utils/fmgr/dfmgr.c:347 #, c-format msgid "Server has INDEX_MAX_KEYS = %d, library has %d." msgstr "Server hat INDEX_MAX_KEYS = %d, Bibliothek hat %d." -#: utils/fmgr/dfmgr.c:351 +#: utils/fmgr/dfmgr.c:356 #, c-format msgid "Server has NAMEDATALEN = %d, library has %d." msgstr "Server hat NAMEDATALEN = %d, Bibliothek hat %d." -#: utils/fmgr/dfmgr.c:360 +#: utils/fmgr/dfmgr.c:365 #, c-format msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." msgstr "Server hat FLOAT4PASSBYVAL = %s, Bibliothek hat %s." -#: utils/fmgr/dfmgr.c:369 +#: utils/fmgr/dfmgr.c:374 #, c-format msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." msgstr "Server hat FLOAT8PASSBYVAL = %s, Bibliothek hat %s." -#: utils/fmgr/dfmgr.c:376 +#: utils/fmgr/dfmgr.c:381 msgid "Magic block has unexpected length or padding difference." msgstr "Magischer Block hat unerwartete Länge oder unterschiedliches Padding." -#: utils/fmgr/dfmgr.c:379 +#: utils/fmgr/dfmgr.c:384 #, c-format msgid "incompatible library \"%s\": magic block mismatch" msgstr "inkompatible Bibliothek »%s«: magischer Block stimmt überein" -#: utils/fmgr/dfmgr.c:543 +#: utils/fmgr/dfmgr.c:548 #, c-format msgid "access to library \"%s\" is not allowed" msgstr "Zugriff auf Bibliothek »%s« ist nicht erlaubt" -#: utils/fmgr/dfmgr.c:569 +#: utils/fmgr/dfmgr.c:574 #, c-format msgid "invalid macro name in dynamic library path: %s" msgstr "ungültiger Makroname in Parameter »dynamic_library_path«: %s" -#: utils/fmgr/dfmgr.c:609 +#: utils/fmgr/dfmgr.c:614 #, c-format msgid "zero-length component in parameter \"dynamic_library_path\"" msgstr "eine Komponente im Parameter »dynamic_library_path« hat Länge null" -#: utils/fmgr/dfmgr.c:628 +#: utils/fmgr/dfmgr.c:633 #, c-format msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "eine Komponente im Parameter »dynamic_library_path« ist kein absoluter Pfad" -#: utils/fmgr/fmgr.c:271 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "interne Funktion »%s« ist nicht in der internen Suchtabelle" -#: utils/fmgr/fmgr.c:478 +#: utils/fmgr/fmgr.c:485 #, c-format -msgid "unrecognized API version %d reported by info function \"%s\"" -msgstr "Info-Funktion »%2$s« berichtete unbekannte API-Version %1$d" +msgid "could not find function information for function \"%s\"" +msgstr "konnte Funktionsinformationen für Funktion »%s« nicht finden" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "Von SQL aufrufbare Funktionen benötigen ein begleitendes PG_FUNCTION_INFO_V1(funkname)." -#: utils/fmgr/fmgr.c:848 utils/fmgr/fmgr.c:2068 +#: utils/fmgr/fmgr.c:505 #, c-format -msgid "function %u has too many arguments (%d, maximum is %d)" -msgstr "Funktion %u hat zu viele Argumente (%d, Maximum ist %d)" +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "Info-Funktion »%2$s« berichtete unbekannte API-Version %1$d" -#: utils/fmgr/fmgr.c:2443 +#: utils/fmgr/fmgr.c:2210 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "Sprachvalidierungsfunktion %u wurde für Sprache %u statt %u aufgerufen" -#: utils/fmgr/funcapi.c:354 +#: utils/fmgr/funcapi.c:358 #, c-format msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "konnte tatsächlichen Ergebnistyp von Funktion »%s« mit deklarierten Rückgabetyp %s nicht bestimmen" -#: utils/fmgr/funcapi.c:1341 utils/fmgr/funcapi.c:1372 +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 #, c-format msgid "number of aliases does not match number of columns" msgstr "Anzahl der Aliasnamen stimmt nicht mit der Anzahl der Spalten überein" -#: utils/fmgr/funcapi.c:1366 +#: utils/fmgr/funcapi.c:1429 #, c-format msgid "no column alias was provided" msgstr "Spaltenalias fehlt" -#: utils/fmgr/funcapi.c:1390 +#: utils/fmgr/funcapi.c:1453 #, c-format msgid "could not determine row description for function returning record" msgstr "konnte Zeilenbeschreibung für Funktion, die »record« zurückgibt, nicht ermitteln" +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "Datenverzeichnis »%s« existiert nicht" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" + #: utils/init/miscinit.c:121 #, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "angegebenes Datenverzeichnis »%s« ist kein Verzeichnis" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "Datenverzeichnis »%s« hat falschen Eigentümer" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Der Server muss von dem Benutzer gestartet werden, dem das Datenverzeichnis gehört." + +#: utils/init/miscinit.c:157 +#, fuzzy, c-format +#| msgid "data directory \"%s\" has wrong ownership" +msgid "data directory \"%s\" has invalid permissions" +msgstr "Datenverzeichnis »%s« hat falschen Eigentümer" + +#: utils/init/miscinit.c:159 +#, fuzzy, c-format +#| msgid "Permissions should be u=rwx (0700)." +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Rechte sollten u=rwx (0700) sein." + +#: utils/init/miscinit.c:218 +#, c-format msgid "could not change directory to \"%s\": %m" msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" -#: utils/init/miscinit.c:449 utils/misc/guc.c:6082 +#: utils/init/miscinit.c:554 utils/misc/guc.c:6370 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "kann Parameter »%s« nicht in einer sicherheitsbeschränkten Operation setzen" -#: utils/init/miscinit.c:510 +#: utils/init/miscinit.c:615 #, c-format msgid "role with OID %u does not exist" msgstr "Rolle mit OID %u existiert nicht" -#: utils/init/miscinit.c:540 +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "Rolle »%s« hat keine Berechtigung zum Einloggen" -#: utils/init/miscinit.c:558 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "zu viele Verbindungen von Rolle »%s«" -#: utils/init/miscinit.c:618 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "keine Berechtigung, um Sitzungsautorisierung zu setzen" -#: utils/init/miscinit.c:701 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "ungültige Rollen-OID: %u" -#: utils/init/miscinit.c:755 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "Datenbanksystem ist heruntergefahren" -#: utils/init/miscinit.c:842 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "konnte Sperrdatei »%s« nicht erstellen: %m" -#: utils/init/miscinit.c:856 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "konnte Sperrdatei »%s« nicht öffnen: %m" -#: utils/init/miscinit.c:862 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "konnte Sperrdatei »%s« nicht lesen: %m" -#: utils/init/miscinit.c:870 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "Sperrdatei »%s« ist leer" -#: utils/init/miscinit.c:871 +#: utils/init/miscinit.c:978 #, c-format msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." msgstr "Entweder startet gerade ein anderer Server oder die Sperrdatei ist von einen Absturz übrig geblieben." -#: utils/init/miscinit.c:918 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "Sperrdatei »%s« existiert bereits" -#: utils/init/miscinit.c:922 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "Läuft bereits ein anderer postgres-Prozess (PID %d) im Datenverzeichnis »%s«?" -#: utils/init/miscinit.c:924 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "Läuft bereits ein anderer postmaster-Prozess (PID %d) im Datenverzeichnis »%s«?" -#: utils/init/miscinit.c:927 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "Verwendet bereits ein anderer postgres-Prozess (PID %d) die Socketdatei »%s«?" -#: utils/init/miscinit.c:929 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "Verwendet bereits ein anderer postmaster-Prozess (PID %d) die Socketdatei »%s«?" -#: utils/init/miscinit.c:965 +#: utils/init/miscinit.c:1069 #, c-format msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" msgstr "bereits bestehender Shared-Memory-Block (Schlüssel %lu, ID %lu) wird noch benutzt" -#: utils/init/miscinit.c:968 +#: utils/init/miscinit.c:1072 #, c-format msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." msgstr "Wenn Sie sich sicher sind, dass kein alter Serverprozess mehr läuft, entfernen Sie den Shared-Memory-Block oder löschen Sie einfach die Datei »%s«." -#: utils/init/miscinit.c:984 +#: utils/init/miscinit.c:1088 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "konnte alte Sperrdatei »%s« nicht löschen: %m" -#: utils/init/miscinit.c:986 +#: utils/init/miscinit.c:1090 #, c-format msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "Die Datei ist anscheinend aus Versehen übrig geblieben, konnte aber nicht gelöscht werden. Bitte entfernen Sie die Datei von Hand und versuchen Sie es erneut." -#: utils/init/miscinit.c:1022 utils/init/miscinit.c:1033 -#: utils/init/miscinit.c:1043 +#: utils/init/miscinit.c:1127 utils/init/miscinit.c:1141 +#: utils/init/miscinit.c:1152 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "konnte Sperrdatei »%s« nicht schreiben: %m" -#: utils/init/miscinit.c:1172 utils/init/miscinit.c:1301 utils/misc/guc.c:8883 +#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1427 utils/misc/guc.c:9211 #, c-format msgid "could not read from file \"%s\": %m" msgstr "konnte nicht aus Datei »%s« lesen: %m" -#: utils/init/miscinit.c:1291 +#: utils/init/miscinit.c:1415 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "konnte Datei »%s« nicht öffnen: %m; setze trotzdem fort" -#: utils/init/miscinit.c:1314 +#: utils/init/miscinit.c:1440 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "Sperrdatei »%s« enthält falsche PID: %ld statt %ld" -#: utils/init/miscinit.c:1353 utils/init/miscinit.c:1369 +#: utils/init/miscinit.c:1479 utils/init/miscinit.c:1495 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "»%s« ist kein gültiges Datenverzeichnis" -#: utils/init/miscinit.c:1355 +#: utils/init/miscinit.c:1481 #, c-format msgid "File \"%s\" is missing." msgstr "Die Datei »%s« fehlt." -#: utils/init/miscinit.c:1371 +#: utils/init/miscinit.c:1497 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "Die Datei »%s« enthält keine gültigen Daten." -#: utils/init/miscinit.c:1373 +#: utils/init/miscinit.c:1499 #, c-format msgid "You might need to initdb." msgstr "Sie müssen möglicherweise initdb ausführen." -#: utils/init/miscinit.c:1381 +#: utils/init/miscinit.c:1507 #, c-format msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." msgstr "Das Datenverzeichnis wurde von PostgreSQL Version %s initialisiert, welche nicht mit dieser Version %s kompatibel ist." -#: utils/init/miscinit.c:1452 +#: utils/init/miscinit.c:1574 #, c-format msgid "loaded library \"%s\"" msgstr "Bibliothek »%s« geladen" -#: utils/init/postinit.c:251 +#: utils/init/postinit.c:252 #, c-format -msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "Replikationsverbindung autorisiert: Benutzer=%s SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Komprimierung=%s)" +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "Replikationsverbindung autorisiert: Benutzer=%s SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Bits=%d, Komprimierung=%s)" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "off" msgstr "aus" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "on" msgstr "an" -#: utils/init/postinit.c:257 +#: utils/init/postinit.c:261 #, c-format msgid "replication connection authorized: user=%s" msgstr "Replikationsverbindung autorisiert: Benutzer=%s" -#: utils/init/postinit.c:265 +#: utils/init/postinit.c:269 #, c-format -msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "Verbindung autorisiert: Benutzer=%s Datenbank=%s SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Komprimierung=%s)" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "Verbindung autorisiert: Benutzer=%s Datenbank=%s SSL an (Protokoll=%s, Verschlüsselungsmethode=%s, Bits=%d, Komprimierung=%s)" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:278 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "Verbindung autorisiert: Benutzer=%s Datenbank=%s" -#: utils/init/postinit.c:303 +#: utils/init/postinit.c:310 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "Datenbank »%s« ist aus pg_database verschwunden" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:312 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "Datenbank-OID %u gehört jetzt anscheinend zu »%s«." -#: utils/init/postinit.c:325 +#: utils/init/postinit.c:332 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "Datenbank »%s« akzeptiert gegenwärtig keine Verbindungen" -#: utils/init/postinit.c:338 +#: utils/init/postinit.c:345 #, c-format msgid "permission denied for database \"%s\"" msgstr "keine Berechtigung für Datenbank »%s«" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:346 #, c-format msgid "User does not have CONNECT privilege." msgstr "Benutzer hat das CONNECT-Privileg nicht." -#: utils/init/postinit.c:356 +#: utils/init/postinit.c:363 #, c-format msgid "too many connections for database \"%s\"" msgstr "zu viele Verbindungen für Datenbank »%s«" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format msgid "database locale is incompatible with operating system" msgstr "Datenbank-Locale ist inkompatibel mit Betriebssystem" -#: utils/init/postinit.c:379 +#: utils/init/postinit.c:386 #, c-format msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." msgstr "Die Datenbank wurde mit LC_COLLATE »%s« initialisiert, was von setlocale() nicht erkannt wird." -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "Erzeugen Sie die Datenbank neu mit einer anderen Locale oder installieren Sie die fehlende Locale." -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:393 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "Die Datenbank wurde mit LC_CTYPE »%s« initialisiert, was von setlocale() nicht erkannt wird." -#: utils/init/postinit.c:714 +#: utils/init/postinit.c:726 #, c-format msgid "no roles are defined in this database system" msgstr "in diesem Datenbanksystem sind keine Rollen definiert" -#: utils/init/postinit.c:715 +#: utils/init/postinit.c:727 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Sie sollten sofort CREATE USER \"%s\" SUPERUSER; ausführen." -#: utils/init/postinit.c:751 +#: utils/init/postinit.c:763 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "während des Herunterfahrens der Datenbank sind keine neuen Replikationsverbindungen erlaubt" -#: utils/init/postinit.c:755 +#: utils/init/postinit.c:767 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "nur Superuser können während des Herunterfahrens der Datenbank verbinden" -#: utils/init/postinit.c:765 +#: utils/init/postinit.c:777 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "nur Superuser können im Binary-Upgrade-Modus verbinden" -#: utils/init/postinit.c:779 +#: utils/init/postinit.c:791 #, c-format msgid "remaining connection slots are reserved for non-replication superuser connections" msgstr "die verbleibenden Verbindungen sind für Superuser auf Nicht-Replikationsverbindungen reserviert" -#: utils/init/postinit.c:789 +#: utils/init/postinit.c:801 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "nur Superuser und Replikationsrollen können WAL-Sender starten" -#: utils/init/postinit.c:858 +#: utils/init/postinit.c:870 #, c-format msgid "database %u does not exist" msgstr "Datenbank %u existiert nicht" -#: utils/init/postinit.c:944 +#: utils/init/postinit.c:959 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Sie wurde anscheinend gerade gelöscht oder umbenannt." -#: utils/init/postinit.c:962 +#: utils/init/postinit.c:977 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "Das Datenbankunterverzeichnis »%s« fehlt." -#: utils/init/postinit.c:967 +#: utils/init/postinit.c:982 #, c-format msgid "could not access directory \"%s\": %m" msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" -#: utils/mb/conv.c:488 utils/mb/conv.c:679 +#: utils/mb/conv.c:488 utils/mb/conv.c:680 #, c-format msgid "invalid encoding number: %d" msgstr "ungültige Kodierungsnummer: %d" @@ -22432,42 +24078,47 @@ msgstr "unerwartete Kodierungs-ID %d für ISO-8859-Zeichensatz" msgid "unexpected encoding ID %d for WIN character sets" msgstr "unerwartete Kodierungs-ID %d für WIN-Zeichensatz" -#: utils/mb/encnames.c:496 +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "Kodierung »%s« wird von ICU nicht unterstützt" + +#: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "Kodierungsname zu lang" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "Umwandlung zwischen %s und %s wird nicht unterstützt" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "Standardumwandlung von Kodierung »%s« nach »%s« existiert nicht" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "Zeichenkette mit %d Bytes ist zu lang für Kodierungsumwandlung." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "ungültiger Quellkodierungsname »%s«" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "ungültiger Zielkodierungsname »%s«" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "ungültiger Byte-Wert für Kodierung »%s«: 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "bind_textdomain_codeset fehlgeschlagen" @@ -22482,1544 +24133,1688 @@ msgstr "ungültige Byte-Sequenz für Kodierung »%s«: %s" msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" msgstr "Zeichen mit Byte-Folge %s in Kodierung »%s« hat keine Entsprechung in Kodierung »%s«" -#: utils/misc/guc.c:573 +#: utils/misc/guc.c:572 msgid "Ungrouped" msgstr "Ungruppiert" -#: utils/misc/guc.c:575 +#: utils/misc/guc.c:574 msgid "File Locations" msgstr "Dateipfade" -#: utils/misc/guc.c:577 +#: utils/misc/guc.c:576 msgid "Connections and Authentication" msgstr "Verbindungen und Authentifizierung" -#: utils/misc/guc.c:579 +#: utils/misc/guc.c:578 msgid "Connections and Authentication / Connection Settings" msgstr "Verbindungen und Authentifizierung / Verbindungseinstellungen" -#: utils/misc/guc.c:581 -msgid "Connections and Authentication / Security and Authentication" -msgstr "Verbindungen und Authentifizierung / Sicherheit und Authentifizierung" +#: utils/misc/guc.c:580 +msgid "Connections and Authentication / Authentication" +msgstr "Verbindungen und Authentifizierung / Authentifizierung" + +#: utils/misc/guc.c:582 +msgid "Connections and Authentication / SSL" +msgstr "Verbindungen und Authentifizierung / SSL" -#: utils/misc/guc.c:583 +#: utils/misc/guc.c:584 msgid "Resource Usage" msgstr "Resourcenbenutzung" -#: utils/misc/guc.c:585 +#: utils/misc/guc.c:586 msgid "Resource Usage / Memory" msgstr "Resourcenbenutzung / Speicher" -#: utils/misc/guc.c:587 +#: utils/misc/guc.c:588 msgid "Resource Usage / Disk" msgstr "Resourcenbenutzung / Festplatte" -#: utils/misc/guc.c:589 +#: utils/misc/guc.c:590 msgid "Resource Usage / Kernel Resources" msgstr "Resourcenbenutzung / Kernelresourcen" -#: utils/misc/guc.c:591 +#: utils/misc/guc.c:592 msgid "Resource Usage / Cost-Based Vacuum Delay" msgstr "Resourcenbenutzung / Kostenbasierte Vacuum-Verzögerung" -#: utils/misc/guc.c:593 +#: utils/misc/guc.c:594 msgid "Resource Usage / Background Writer" msgstr "Resourcenbenutzung / Background-Writer" -#: utils/misc/guc.c:595 +#: utils/misc/guc.c:596 msgid "Resource Usage / Asynchronous Behavior" msgstr "Resourcenbenutzung / Asynchrones Verhalten" -#: utils/misc/guc.c:597 +#: utils/misc/guc.c:598 msgid "Write-Ahead Log" msgstr "Write-Ahead-Log" -#: utils/misc/guc.c:599 +#: utils/misc/guc.c:600 msgid "Write-Ahead Log / Settings" msgstr "Write-Ahead-Log / Einstellungen" -#: utils/misc/guc.c:601 +#: utils/misc/guc.c:602 msgid "Write-Ahead Log / Checkpoints" msgstr "Write-Ahead-Log / Checkpoints" -#: utils/misc/guc.c:603 +#: utils/misc/guc.c:604 msgid "Write-Ahead Log / Archiving" msgstr "Write-Ahead-Log / Archivierung" -#: utils/misc/guc.c:605 +#: utils/misc/guc.c:606 msgid "Replication" msgstr "Replikation" -#: utils/misc/guc.c:607 +#: utils/misc/guc.c:608 msgid "Replication / Sending Servers" msgstr "Replikation / sendende Server" -#: utils/misc/guc.c:609 +#: utils/misc/guc.c:610 msgid "Replication / Master Server" msgstr "Replikation / Master-Server" -#: utils/misc/guc.c:611 +#: utils/misc/guc.c:612 msgid "Replication / Standby Servers" msgstr "Replikation / Standby-Server" -#: utils/misc/guc.c:613 +#: utils/misc/guc.c:614 +msgid "Replication / Subscribers" +msgstr "Replikation / Subskriptionsserver" + +#: utils/misc/guc.c:616 msgid "Query Tuning" msgstr "Anfragetuning" -#: utils/misc/guc.c:615 +#: utils/misc/guc.c:618 msgid "Query Tuning / Planner Method Configuration" msgstr "Anfragetuning / Planermethoden" -#: utils/misc/guc.c:617 +#: utils/misc/guc.c:620 msgid "Query Tuning / Planner Cost Constants" msgstr "Anfragetuning / Planerkosten" -#: utils/misc/guc.c:619 +#: utils/misc/guc.c:622 msgid "Query Tuning / Genetic Query Optimizer" msgstr "Anfragetuning / Genetischer Anfrageoptimierer" -#: utils/misc/guc.c:621 +#: utils/misc/guc.c:624 msgid "Query Tuning / Other Planner Options" msgstr "Anfragetuning / Andere Planeroptionen" -#: utils/misc/guc.c:623 +#: utils/misc/guc.c:626 msgid "Reporting and Logging" msgstr "Berichte und Logging" -#: utils/misc/guc.c:625 +#: utils/misc/guc.c:628 msgid "Reporting and Logging / Where to Log" msgstr "Berichte und Logging / Wohin geloggt wird" -#: utils/misc/guc.c:627 +#: utils/misc/guc.c:630 msgid "Reporting and Logging / When to Log" msgstr "Berichte und Logging / Wann geloggt wird" -#: utils/misc/guc.c:629 +#: utils/misc/guc.c:632 msgid "Reporting and Logging / What to Log" msgstr "Berichte und Logging / Was geloggt wird" -#: utils/misc/guc.c:631 +#: utils/misc/guc.c:634 msgid "Process Title" msgstr "Prozesstitel" -#: utils/misc/guc.c:633 +#: utils/misc/guc.c:636 msgid "Statistics" msgstr "Statistiken" -#: utils/misc/guc.c:635 +#: utils/misc/guc.c:638 msgid "Statistics / Monitoring" msgstr "Statistiken / Überwachung" -#: utils/misc/guc.c:637 +#: utils/misc/guc.c:640 msgid "Statistics / Query and Index Statistics Collector" msgstr "Statistiken / Statistiksammler für Anfragen und Indexe" -#: utils/misc/guc.c:639 +#: utils/misc/guc.c:642 msgid "Autovacuum" msgstr "Autovacuum" -#: utils/misc/guc.c:641 +#: utils/misc/guc.c:644 msgid "Client Connection Defaults" msgstr "Standardeinstellungen für Clientverbindungen" -#: utils/misc/guc.c:643 +#: utils/misc/guc.c:646 msgid "Client Connection Defaults / Statement Behavior" msgstr "Standardeinstellungen für Clientverbindungen / Anweisungsverhalten" -#: utils/misc/guc.c:645 +#: utils/misc/guc.c:648 msgid "Client Connection Defaults / Locale and Formatting" msgstr "Standardeinstellungen für Clientverbindungen / Locale und Formatierung" -#: utils/misc/guc.c:647 +#: utils/misc/guc.c:650 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "Standardeinstellungen für Clientverbindungen / Shared Library Preloading" -#: utils/misc/guc.c:649 +#: utils/misc/guc.c:652 msgid "Client Connection Defaults / Other Defaults" msgstr "Standardeinstellungen für Clientverbindungen / Andere" -#: utils/misc/guc.c:651 +#: utils/misc/guc.c:654 msgid "Lock Management" msgstr "Sperrenverwaltung" -#: utils/misc/guc.c:653 +#: utils/misc/guc.c:656 msgid "Version and Platform Compatibility" msgstr "Versions- und Plattformkompatibilität" -#: utils/misc/guc.c:655 +#: utils/misc/guc.c:658 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "Versions- und Plattformkompatibilität / Frühere PostgreSQL-Versionen" -#: utils/misc/guc.c:657 +#: utils/misc/guc.c:660 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "Versions- und Plattformkompatibilität / Andere Plattformen und Clients" -#: utils/misc/guc.c:659 +#: utils/misc/guc.c:662 msgid "Error Handling" msgstr "Fehlerbehandlung" -#: utils/misc/guc.c:661 +#: utils/misc/guc.c:664 msgid "Preset Options" msgstr "Voreingestellte Optionen" -#: utils/misc/guc.c:663 +#: utils/misc/guc.c:666 msgid "Customized Options" msgstr "Angepasste Optionen" -#: utils/misc/guc.c:665 +#: utils/misc/guc.c:668 msgid "Developer Options" msgstr "Entwickleroptionen" #: utils/misc/guc.c:722 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "Gültige Einheiten für diesen Parameter sind »kB«, »MB«, »GB« und »TB«." +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Gültige Einheiten für diesen Parameter sind »B«, »kB«, »MB«, »GB« und »TB«." -#: utils/misc/guc.c:749 +#: utils/misc/guc.c:764 msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." msgstr "Gültige Einheiten für diesen Parameter sind »ms«, »s«, »min«, »h« und »d«." -#: utils/misc/guc.c:808 +#: utils/misc/guc.c:823 msgid "Enables the planner's use of sequential-scan plans." msgstr "Ermöglicht sequenzielle Scans in Planer." -#: utils/misc/guc.c:817 +#: utils/misc/guc.c:832 msgid "Enables the planner's use of index-scan plans." msgstr "Ermöglicht Index-Scans im Planer." -#: utils/misc/guc.c:826 +#: utils/misc/guc.c:841 msgid "Enables the planner's use of index-only-scan plans." msgstr "Ermöglicht Index-Only-Scans im Planer." -#: utils/misc/guc.c:835 +#: utils/misc/guc.c:850 msgid "Enables the planner's use of bitmap-scan plans." msgstr "Ermöglicht Bitmap-Scans im Planer." -#: utils/misc/guc.c:844 +#: utils/misc/guc.c:859 msgid "Enables the planner's use of TID scan plans." msgstr "Ermöglicht TID-Scans im Planer." -#: utils/misc/guc.c:853 +#: utils/misc/guc.c:868 msgid "Enables the planner's use of explicit sort steps." msgstr "Ermöglicht Sortierschritte im Planer." -#: utils/misc/guc.c:862 +#: utils/misc/guc.c:877 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Ermöglicht Hash-Aggregierung im Planer." -#: utils/misc/guc.c:871 +#: utils/misc/guc.c:886 msgid "Enables the planner's use of materialization." msgstr "Ermöglicht Materialisierung im Planer." -#: utils/misc/guc.c:880 +#: utils/misc/guc.c:895 msgid "Enables the planner's use of nested-loop join plans." msgstr "Ermöglicht Nested-Loop-Verbunde im Planer." -#: utils/misc/guc.c:889 +#: utils/misc/guc.c:904 msgid "Enables the planner's use of merge join plans." msgstr "Ermöglicht Merge-Verbunde im Planer." -#: utils/misc/guc.c:898 +#: utils/misc/guc.c:913 msgid "Enables the planner's use of hash join plans." msgstr "Ermöglicht Hash-Verbunde im Planer." -#: utils/misc/guc.c:907 +#: utils/misc/guc.c:922 +msgid "Enables the planner's use of gather merge plans." +msgstr "Ermöglicht Gather-Merge-Pläne im Planer." + +#: utils/misc/guc.c:931 +msgid "Enables partitionwise join." +msgstr "" + +#: utils/misc/guc.c:940 +msgid "Enables partitionwise aggregation and grouping." +msgstr "" + +#: utils/misc/guc.c:949 #, fuzzy #| msgid "Enables the planner's use of merge join plans." -msgid "Enables the planner's use of gather merge plans." +msgid "Enables the planner's use of parallel append plans." msgstr "Ermöglicht Merge-Verbunde im Planer." -#: utils/misc/guc.c:917 +#: utils/misc/guc.c:958 +#, fuzzy +#| msgid "Enables the planner's use of hash join plans." +msgid "Enables the planner's use of parallel hash plans." +msgstr "Ermöglicht Hash-Verbunde im Planer." + +#: utils/misc/guc.c:967 +msgid "Enable plan-time and run-time partition pruning." +msgstr "" + +#: utils/misc/guc.c:968 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "" + +#: utils/misc/guc.c:978 msgid "Enables genetic query optimization." msgstr "Ermöglicht genetische Anfrageoptimierung." -#: utils/misc/guc.c:918 +#: utils/misc/guc.c:979 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Dieser Algorithmus versucht das Planen ohne erschöpfende Suche durchzuführen." -#: utils/misc/guc.c:928 +#: utils/misc/guc.c:989 msgid "Shows whether the current user is a superuser." msgstr "Zeigt, ob der aktuelle Benutzer ein Superuser ist." -#: utils/misc/guc.c:938 +#: utils/misc/guc.c:999 msgid "Enables advertising the server via Bonjour." msgstr "Ermöglicht die Bekanntgabe des Servers mit Bonjour." -#: utils/misc/guc.c:947 +#: utils/misc/guc.c:1008 msgid "Collects transaction commit time." msgstr "Sammelt Commit-Timestamps von Transaktionen." -#: utils/misc/guc.c:956 +#: utils/misc/guc.c:1017 msgid "Enables SSL connections." msgstr "Ermöglicht SSL-Verbindungen." -#: utils/misc/guc.c:965 +#: utils/misc/guc.c:1026 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "" + +#: utils/misc/guc.c:1035 msgid "Give priority to server ciphersuite order." msgstr "Der Ciphersuite-Reihenfolge des Servers Vorrang geben." -#: utils/misc/guc.c:974 +#: utils/misc/guc.c:1044 msgid "Forces synchronization of updates to disk." msgstr "Erzwingt die Synchronisierung von Aktualisierungen auf Festplatte." -#: utils/misc/guc.c:975 +#: utils/misc/guc.c:1045 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." msgstr "Der Server verwendet den Systemaufruf fsync() an mehreren Stellen, um sicherzustellen, dass Datenänderungen physikalisch auf die Festplatte geschrieben werden. Das stellt sicher, dass der Datenbankcluster nach einem Betriebssystemabsturz oder Hardwarefehler in einem korrekten Zustand wiederhergestellt werden kann." -#: utils/misc/guc.c:986 +#: utils/misc/guc.c:1056 msgid "Continues processing after a checksum failure." msgstr "Setzt die Verarbeitung trotz Prüfsummenfehler fort." -#: utils/misc/guc.c:987 +#: utils/misc/guc.c:1057 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." msgstr "Wenn eine fehlerhafte Prüfsumme entdeckt wird, gibt PostgreSQL normalerweise ein Fehler aus und bricht die aktuelle Transaktion ab. Wenn »ignore_checksum_failure« an ist, dann wird der Fehler ignoriert (aber trotzdem eine Warnung ausgegeben) und die Verarbeitung geht weiter. Dieses Verhalten kann Abstürze und andere ernsthafte Probleme verursachen. Es hat keine Auswirkungen, wenn Prüfsummen nicht eingeschaltet sind." -#: utils/misc/guc.c:1001 +#: utils/misc/guc.c:1071 msgid "Continues processing past damaged page headers." msgstr "Setzt die Verarbeitung trotz kaputter Seitenköpfe fort." -#: utils/misc/guc.c:1002 +#: utils/misc/guc.c:1072 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "Wenn ein kaputter Seitenkopf entdeckt wird, gibt PostgreSQL normalerweise einen Fehler aus und bricht die aktuelle Transaktion ab. Wenn »zero_damaged_pages« an ist, dann wird eine Warnung ausgegeben, die kaputte Seite mit Nullen gefüllt und die Verarbeitung geht weiter. Dieses Verhalten zerstört Daten, nämlich alle Zeilen in der kaputten Seite." -#: utils/misc/guc.c:1015 +#: utils/misc/guc.c:1085 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden." -#: utils/misc/guc.c:1016 +#: utils/misc/guc.c:1086 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." msgstr "Ein Seitenschreibvorgang während eines Betriebssystemabsturzes könnte eventuell nur teilweise geschrieben worden sein. Bei der Wiederherstellung sind die im WAL gespeicherten Zeilenänderungen nicht ausreichend. Diese Option schreibt Seiten, sobald sie nach einem Checkpoint geändert worden sind, damit eine volle Wiederherstellung möglich ist." -#: utils/misc/guc.c:1029 +#: utils/misc/guc.c:1099 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." msgstr "Schreibt volle Seiten in den WAL, sobald sie nach einem Checkpoint geändert werden, auch für nicht kritische Änderungen." -#: utils/misc/guc.c:1039 +#: utils/misc/guc.c:1109 msgid "Compresses full-page writes written in WAL file." msgstr "Komprimiert in WAL-Dateien geschriebene volle Seiten." -#: utils/misc/guc.c:1049 +#: utils/misc/guc.c:1119 msgid "Logs each checkpoint." msgstr "Schreibt jeden Checkpoint in den Log." -#: utils/misc/guc.c:1058 +#: utils/misc/guc.c:1128 msgid "Logs each successful connection." msgstr "Schreibt jede erfolgreiche Verbindung in den Log." -#: utils/misc/guc.c:1067 +#: utils/misc/guc.c:1137 msgid "Logs end of a session, including duration." msgstr "Schreibt jedes Verbindungsende mit Sitzungszeit in den Log." -#: utils/misc/guc.c:1076 +#: utils/misc/guc.c:1146 msgid "Logs each replication command." msgstr "Schreibt jeden Replikationsbefehl in den Log." -#: utils/misc/guc.c:1085 +#: utils/misc/guc.c:1155 msgid "Shows whether the running server has assertion checks enabled." msgstr "Zeigt, ob der laufende Server Assertion-Prüfungen aktiviert hat." -#: utils/misc/guc.c:1100 +#: utils/misc/guc.c:1170 msgid "Terminate session on any error." msgstr "Sitzung bei jedem Fehler abbrechen." -#: utils/misc/guc.c:1109 +#: utils/misc/guc.c:1179 msgid "Reinitialize server after backend crash." msgstr "Server nach Absturz eines Serverprozesses reinitialisieren." -#: utils/misc/guc.c:1119 +#: utils/misc/guc.c:1189 msgid "Logs the duration of each completed SQL statement." msgstr "Loggt die Dauer jeder abgeschlossenen SQL-Anweisung." -#: utils/misc/guc.c:1128 +#: utils/misc/guc.c:1198 msgid "Logs each query's parse tree." msgstr "Scheibt den Parsebaum jeder Anfrage in den Log." -#: utils/misc/guc.c:1137 +#: utils/misc/guc.c:1207 msgid "Logs each query's rewritten parse tree." msgstr "Schreibt den umgeschriebenen Parsebaum jeder Anfrage in den Log." -#: utils/misc/guc.c:1146 +#: utils/misc/guc.c:1216 msgid "Logs each query's execution plan." msgstr "Schreibt den Ausführungsplan jeder Anfrage in den Log." -#: utils/misc/guc.c:1155 +#: utils/misc/guc.c:1225 msgid "Indents parse and plan tree displays." msgstr "Rückt die Anzeige von Parse- und Planbäumen ein." -#: utils/misc/guc.c:1164 +#: utils/misc/guc.c:1234 msgid "Writes parser performance statistics to the server log." msgstr "Schreibt Parser-Leistungsstatistiken in den Serverlog." -#: utils/misc/guc.c:1173 +#: utils/misc/guc.c:1243 msgid "Writes planner performance statistics to the server log." msgstr "Schreibt Planer-Leistungsstatistiken in den Serverlog." -#: utils/misc/guc.c:1182 +#: utils/misc/guc.c:1252 msgid "Writes executor performance statistics to the server log." msgstr "Schreibt Executor-Leistungsstatistiken in den Serverlog." -#: utils/misc/guc.c:1191 +#: utils/misc/guc.c:1261 msgid "Writes cumulative performance statistics to the server log." msgstr "Schreibt Gesamtleistungsstatistiken in den Serverlog." -#: utils/misc/guc.c:1201 +#: utils/misc/guc.c:1271 msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "Loggt Statistiken über Systemressourcen (Speicher und CPU) während diverser B-Baum-Operationen." -#: utils/misc/guc.c:1213 +#: utils/misc/guc.c:1283 msgid "Collects information about executing commands." msgstr "Sammelt Informationen über ausgeführte Befehle." -#: utils/misc/guc.c:1214 +#: utils/misc/guc.c:1284 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "Schaltet die Sammlung von Informationen über den aktuell ausgeführten Befehl jeder Sitzung ein, einschließlich der Zeit, and dem die Befehlsausführung begann." -#: utils/misc/guc.c:1224 +#: utils/misc/guc.c:1294 msgid "Collects statistics on database activity." msgstr "Sammelt Statistiken über Datenbankaktivität." -#: utils/misc/guc.c:1233 +#: utils/misc/guc.c:1303 msgid "Collects timing statistics for database I/O activity." msgstr "Sammelt Zeitmessungsstatistiken über Datenbank-I/O-Aktivität." -#: utils/misc/guc.c:1243 +#: utils/misc/guc.c:1313 msgid "Updates the process title to show the active SQL command." msgstr "Der Prozesstitel wird aktualisiert, um den aktuellen SQL-Befehl anzuzeigen." -#: utils/misc/guc.c:1244 +#: utils/misc/guc.c:1314 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "Ermöglicht das Aktualisieren des Prozesstitels bei jedem von Server empfangenen neuen SQL-Befehl." -#: utils/misc/guc.c:1257 +#: utils/misc/guc.c:1327 msgid "Starts the autovacuum subprocess." msgstr "Startet den Autovacuum-Prozess." -#: utils/misc/guc.c:1267 +#: utils/misc/guc.c:1337 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Erzeugt Debug-Ausgabe für LISTEN und NOTIFY." -#: utils/misc/guc.c:1279 +#: utils/misc/guc.c:1349 msgid "Emits information about lock usage." msgstr "Gibt Informationen über Sperrenverwendung aus." -#: utils/misc/guc.c:1289 +#: utils/misc/guc.c:1359 msgid "Emits information about user lock usage." msgstr "Gibt Informationen über Benutzersperrenverwendung aus." -#: utils/misc/guc.c:1299 +#: utils/misc/guc.c:1369 msgid "Emits information about lightweight lock usage." msgstr "Gibt Informationen über die Verwendung von Lightweight Locks aus." -#: utils/misc/guc.c:1309 +#: utils/misc/guc.c:1379 msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "Gibt Informationen über alle aktuellen Sperren aus, wenn eine Verklemmung auftritt." -#: utils/misc/guc.c:1321 +#: utils/misc/guc.c:1391 msgid "Logs long lock waits." msgstr "Schreibt Meldungen über langes Warten auf Sperren in den Log." -#: utils/misc/guc.c:1331 +#: utils/misc/guc.c:1401 msgid "Logs the host name in the connection logs." msgstr "Schreibt den Hostnamen jeder Verbindung in den Log." -#: utils/misc/guc.c:1332 +#: utils/misc/guc.c:1402 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." msgstr "In der Standardeinstellung zeigen die Verbindungslogs nur die IP-Adresse der Clienthosts. Wenn Sie den Hostnamen auch anzeigen wollen, dann können Sie diese Option anschalten, aber je nachdem, wie Ihr DNS eingerichtet ist, kann das die Leistung nicht unerheblich beeinträchtigen." -#: utils/misc/guc.c:1343 +#: utils/misc/guc.c:1413 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Behandelt »ausdruck=NULL« als »ausdruck IS NULL«." -#: utils/misc/guc.c:1344 +#: utils/misc/guc.c:1414 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "Wenn an, dann werden Ausdrücke der Form ausdruck = NULL (oder NULL = ausdruck) wie ausdruck IS NULL behandelt, das heißt, sie ergeben wahr, wenn das Ergebnis von ausdruck der NULL-Wert ist, und ansonsten falsch. Das korrekte Verhalten von ausdruck = NULL ist immer den NULL-Wert (für unbekannt) zurückzugeben." -#: utils/misc/guc.c:1356 +#: utils/misc/guc.c:1426 msgid "Enables per-database user names." msgstr "Ermöglicht Datenbank-lokale Benutzernamen." -#: utils/misc/guc.c:1365 +#: utils/misc/guc.c:1435 msgid "Sets the default read-only status of new transactions." msgstr "Setzt den Standardwert für die Read-Only-Einstellung einer neuen Transaktion." -#: utils/misc/guc.c:1374 +#: utils/misc/guc.c:1444 msgid "Sets the current transaction's read-only status." msgstr "Setzt die Read-Only-Einstellung der aktuellen Transaktion." -#: utils/misc/guc.c:1384 +#: utils/misc/guc.c:1454 msgid "Sets the default deferrable status of new transactions." msgstr "Setzt den Standardwert für die Deferrable-Einstellung einer neuen Transaktion." -#: utils/misc/guc.c:1393 +#: utils/misc/guc.c:1463 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "Ob eine serialisierbare Read-Only-Transaktion aufgeschoben werden soll, bis sie ohne mögliche Serialisierungsfehler ausgeführt werden kann." -#: utils/misc/guc.c:1403 +#: utils/misc/guc.c:1473 msgid "Enable row security." msgstr "Schaltet Sicherheit auf Zeilenebene ein." -#: utils/misc/guc.c:1404 +#: utils/misc/guc.c:1474 msgid "When enabled, row security will be applied to all users." msgstr "Wenn eingeschaltet, wird Sicherheit auf Zeilenebene auf alle Benutzer angewendet." -#: utils/misc/guc.c:1412 +#: utils/misc/guc.c:1482 msgid "Check function bodies during CREATE FUNCTION." msgstr "Prüft Funktionskörper bei der Ausführung von CREATE FUNCTION." -#: utils/misc/guc.c:1421 +#: utils/misc/guc.c:1491 msgid "Enable input of NULL elements in arrays." msgstr "Ermöglicht die Eingabe von NULL-Elementen in Arrays." -#: utils/misc/guc.c:1422 +#: utils/misc/guc.c:1492 msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." msgstr "Wenn dies eingeschaltet ist, wird ein nicht gequotetes NULL in einem Array-Eingabewert als NULL-Wert interpretiert, ansonsten als Zeichenkette." -#: utils/misc/guc.c:1432 +#: utils/misc/guc.c:1502 msgid "Create new tables with OIDs by default." msgstr "Erzeugt neue Tabellen standardmäßig mit OIDs." -#: utils/misc/guc.c:1441 +#: utils/misc/guc.c:1511 msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "Startet einen Subprozess, um die Stderr-Ausgabe und/oder CSV-Logs in Logdateien auszugeben." -#: utils/misc/guc.c:1450 +#: utils/misc/guc.c:1520 msgid "Truncate existing log files of same name during log rotation." msgstr "Kürzt existierende Logdateien mit dem selben Namen beim Rotieren." -#: utils/misc/guc.c:1461 +#: utils/misc/guc.c:1531 msgid "Emit information about resource usage in sorting." msgstr "Gibt Informationen über die Ressourcenverwendung beim Sortieren aus." -#: utils/misc/guc.c:1475 +#: utils/misc/guc.c:1545 msgid "Generate debugging output for synchronized scanning." msgstr "Erzeugt Debug-Ausgabe für synchronisiertes Scannen." -#: utils/misc/guc.c:1490 +#: utils/misc/guc.c:1560 msgid "Enable bounded sorting using heap sort." msgstr "Ermöglicht Bounded Sorting mittels Heap-Sort." -#: utils/misc/guc.c:1503 +#: utils/misc/guc.c:1573 msgid "Emit WAL-related debugging output." msgstr "Gibt diverse Debug-Meldungen über WAL aus." -#: utils/misc/guc.c:1515 +#: utils/misc/guc.c:1585 msgid "Datetimes are integer based." msgstr "Datum/Zeit verwendet intern ganze Zahlen." -#: utils/misc/guc.c:1526 +#: utils/misc/guc.c:1596 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "Bestimmt, ob Groß-/Kleinschreibung bei Kerberos- und GSSAPI-Benutzernamen ignoriert werden soll." -#: utils/misc/guc.c:1536 +#: utils/misc/guc.c:1606 msgid "Warn about backslash escapes in ordinary string literals." msgstr "Warnt bei Backslash-Escapes in normalen Zeichenkettenkonstanten." -#: utils/misc/guc.c:1546 +#: utils/misc/guc.c:1616 msgid "Causes '...' strings to treat backslashes literally." msgstr "Bewirkt, dass Zeichenketten der Art '...' Backslashes als normales Zeichen behandeln." -#: utils/misc/guc.c:1557 +#: utils/misc/guc.c:1627 msgid "Enable synchronized sequential scans." msgstr "Ermöglicht synchronisierte sequenzielle Scans." -#: utils/misc/guc.c:1567 +#: utils/misc/guc.c:1637 msgid "Allows connections and queries during recovery." msgstr "Erlaubt Verbindungen und Anfragen während der Wiederherstellung." -#: utils/misc/guc.c:1577 +#: utils/misc/guc.c:1647 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "Erlaubt Rückmeldungen von einem Hot Standby an den Primärserver, um Anfragekonflikte zu vermeiden." -#: utils/misc/guc.c:1587 +#: utils/misc/guc.c:1657 msgid "Allows modifications of the structure of system tables." msgstr "Erlaubt Änderungen an der Struktur von Systemtabellen." -#: utils/misc/guc.c:1598 +#: utils/misc/guc.c:1668 msgid "Disables reading from system indexes." msgstr "Schaltet das Lesen aus Systemindexen ab." -#: utils/misc/guc.c:1599 +#: utils/misc/guc.c:1669 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "Das Aktualisieren der Indexe wird nicht verhindert, also ist die Verwendung unbedenklich. Schlimmstenfalls wird alles langsamer." -#: utils/misc/guc.c:1610 +#: utils/misc/guc.c:1680 msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "Schaltet den rückwärtskompatiblen Modus für Privilegienprüfungen bei Large Objects ein." -#: utils/misc/guc.c:1611 +#: utils/misc/guc.c:1681 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." msgstr "Überspringt Privilegienprüfungen beim Lesen oder Ändern von Large Objects, zur Kompatibilität mit PostgreSQL-Versionen vor 9.0." -#: utils/misc/guc.c:1621 +#: utils/misc/guc.c:1691 msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "Warnung ausgeben für Konstrukte, deren Bedeutung sich seit PostgreSQL 9.4 geändert hat." -#: utils/misc/guc.c:1631 +#: utils/misc/guc.c:1701 msgid "When generating SQL fragments, quote all identifiers." msgstr "Wenn SQL-Fragmente erzeugt werden, alle Bezeichner quoten." -#: utils/misc/guc.c:1641 +#: utils/misc/guc.c:1711 msgid "Shows whether data checksums are turned on for this cluster." msgstr "Zeigt, ob Datenprüfsummen in diesem Cluster angeschaltet sind." -#: utils/misc/guc.c:1652 +#: utils/misc/guc.c:1722 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "Syslog-Nachrichten mit Sequenznummern versehen, um Unterdrückung doppelter Nachrichten zu unterbinden." -#: utils/misc/guc.c:1662 +#: utils/misc/guc.c:1732 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "An Syslog gesendete Nachrichten nach Zeilen und in maximal 1024 Bytes aufteilen." -#: utils/misc/guc.c:1681 +#: utils/misc/guc.c:1742 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" + +#: utils/misc/guc.c:1743 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" + +#: utils/misc/guc.c:1752 +msgid "Allow JIT compilation." +msgstr "Erlaubt JIT-Kompilierung." + +#: utils/misc/guc.c:1762 +msgid "Register JIT compiled function with debugger." +msgstr "" + +#: utils/misc/guc.c:1779 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "" + +#: utils/misc/guc.c:1790 +msgid "Allow JIT compilation of expressions." +msgstr "Erlaubt JIT-Kompilierung von Ausdrücken." + +#: utils/misc/guc.c:1801 +msgid "Register JIT compiled function with perf profiler." +msgstr "" + +#: utils/misc/guc.c:1818 +msgid "Allow JIT compilation of tuple deforming." +msgstr "" + +#: utils/misc/guc.c:1829 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Ob nach fehlgeschlagenem Synchronisieren von Datendateien fortgesetzt werden soll." + +#: utils/misc/guc.c:1847 msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." msgstr "Erzwingt das Umschalten zur nächsten WAL-Datei, wenn seit N Sekunden keine neue Datei begonnen worden ist." -#: utils/misc/guc.c:1692 +#: utils/misc/guc.c:1858 msgid "Waits N seconds on connection startup after authentication." msgstr "Wartet beim Starten einer Verbindung N Sekunden nach der Authentifizierung." -#: utils/misc/guc.c:1693 utils/misc/guc.c:2216 +#: utils/misc/guc.c:1859 utils/misc/guc.c:2410 msgid "This allows attaching a debugger to the process." msgstr "Das ermöglicht es, einen Debugger in den Prozess einzuhängen." -#: utils/misc/guc.c:1702 +#: utils/misc/guc.c:1868 msgid "Sets the default statistics target." msgstr "Setzt das voreingestellte Statistikziel." -#: utils/misc/guc.c:1703 +#: utils/misc/guc.c:1869 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "Diese Einstellung gilt für Tabellenspalten, für die kein spaltenspezifisches Ziel mit ALTER TABLE SET STATISTICS gesetzt worden ist." -#: utils/misc/guc.c:1712 +#: utils/misc/guc.c:1878 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "Setzt die Größe der FROM-Liste, ab der Unteranfragen nicht kollabiert werden." -#: utils/misc/guc.c:1714 +#: utils/misc/guc.c:1880 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." msgstr "Der Planer bindet Unteranfragen in die übergeordneten Anfragen ein, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." -#: utils/misc/guc.c:1724 +#: utils/misc/guc.c:1890 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "Setzt die Größe der FROM-Liste, ab der JOIN-Konstrukte nicht aufgelöst werden." -#: utils/misc/guc.c:1726 +#: utils/misc/guc.c:1892 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." msgstr "Der Planer löst ausdrückliche JOIN-Konstrukte in FROM-Listen auf, wenn die daraus resultierende FROM-Liste nicht mehr als so viele Elemente haben würde." -#: utils/misc/guc.c:1736 +#: utils/misc/guc.c:1902 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "Setzt die Anzahl der Elemente in der FROM-Liste, ab der GEQO verwendet wird." -#: utils/misc/guc.c:1745 +#: utils/misc/guc.c:1911 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: wird für die Berechnung der Vorgabewerte anderer GEQO-Parameter verwendet." -#: utils/misc/guc.c:1754 +#: utils/misc/guc.c:1920 msgid "GEQO: number of individuals in the population." msgstr "GEQO: Anzahl der Individien in der Bevölkerung." -#: utils/misc/guc.c:1755 utils/misc/guc.c:1764 +#: utils/misc/guc.c:1921 utils/misc/guc.c:1930 msgid "Zero selects a suitable default value." msgstr "Null wählt einen passenden Vorgabewert." -#: utils/misc/guc.c:1763 +#: utils/misc/guc.c:1929 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: Anzahl der Iterationen im Algorithmus." -#: utils/misc/guc.c:1774 +#: utils/misc/guc.c:1940 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Setzt die Zeit, die gewartet wird, bis auf Verklemmung geprüft wird." -#: utils/misc/guc.c:1785 +#: utils/misc/guc.c:1951 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server archivierte WAL-Daten verarbeitet." -#: utils/misc/guc.c:1796 +#: utils/misc/guc.c:1962 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "Setzt die maximale Verzögerung bevor Anfragen storniert werden, wenn ein Hot-Standby-Server gestreamte WAL-Daten verarbeitet." -#: utils/misc/guc.c:1807 +#: utils/misc/guc.c:1973 msgid "Sets the maximum interval between WAL receiver status reports to the primary." msgstr "Setzt das maximale Intervall zwischen Statusberichten des WAL-Receivers an den Primärserver." -#: utils/misc/guc.c:1818 +#: utils/misc/guc.c:1984 msgid "Sets the maximum wait time to receive data from the primary." msgstr "Setzt die maximale Zeit, um auf den Empfang von Daten vom Primärserver zu warten." -#: utils/misc/guc.c:1829 +#: utils/misc/guc.c:1995 msgid "Sets the maximum number of concurrent connections." msgstr "Setzt die maximale Anzahl gleichzeitiger Verbindungen." -#: utils/misc/guc.c:1839 +#: utils/misc/guc.c:2006 msgid "Sets the number of connection slots reserved for superusers." msgstr "Setzt die Anzahl der für Superuser reservierten Verbindungen." -#: utils/misc/guc.c:1853 +#: utils/misc/guc.c:2020 msgid "Sets the number of shared memory buffers used by the server." msgstr "Setzt die Anzahl der vom Server verwendeten Shared-Memory-Puffer." -#: utils/misc/guc.c:1864 +#: utils/misc/guc.c:2031 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Setzt die maximale Anzahl der von jeder Sitzung verwendeten temporären Puffer." -#: utils/misc/guc.c:1875 +#: utils/misc/guc.c:2042 msgid "Sets the TCP port the server listens on." msgstr "Setzt den TCP-Port, auf dem der Server auf Verbindungen wartet." -#: utils/misc/guc.c:1885 +#: utils/misc/guc.c:2052 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Setzt die Zugriffsrechte für die Unix-Domain-Socket." -#: utils/misc/guc.c:1886 +#: utils/misc/guc.c:2053 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Unix-Domain-Sockets verwenden die üblichen Zugriffsrechte für Unix-Dateisysteme. Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" -#: utils/misc/guc.c:1900 +#: utils/misc/guc.c:2067 msgid "Sets the file permissions for log files." msgstr "Setzt die Dateizugriffsrechte für Logdateien." -#: utils/misc/guc.c:1901 +#: utils/misc/guc.c:2068 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" -#: utils/misc/guc.c:1914 +#: utils/misc/guc.c:2082 +#, fuzzy +#| msgid "Sets the server's data directory." +msgid "Mode of the data directory." +msgstr "Setzt das Datenverzeichnis des Servers." + +#: utils/misc/guc.c:2083 +#, fuzzy +#| msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Der Wert dieser Option muss ein numerischer Wert in der von den Systemaufrufen chmod und umask verwendeten Form sein. (Um das gebräuchliche Oktalformat zu verwenden, muss die Zahl mit 0 (einer Null) anfangen.)" + +#: utils/misc/guc.c:2096 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Setzt die maximale Speichergröße für Anfrage-Arbeitsbereiche." -#: utils/misc/guc.c:1915 +#: utils/misc/guc.c:2097 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "Gibt die Speichermenge an, die für interne Sortiervorgänge und Hashtabellen verwendet werden kann, bevor auf temporäre Dateien umgeschaltet wird." -#: utils/misc/guc.c:1927 +#: utils/misc/guc.c:2109 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Setzt die maximale Speichergröße für Wartungsoperationen." -#: utils/misc/guc.c:1928 +#: utils/misc/guc.c:2110 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "Das schließt Operationen wie VACUUM und CREATE INDEX ein." -#: utils/misc/guc.c:1938 -msgid "Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "Setzt die maximale Anzahl Tupel, die mit Replacement-Selection sortiert werden." - -#: utils/misc/guc.c:1939 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "Wenn mehr Tupel als dieser Wert vorhanden sind, dann wird Quicksort verwendet." - -#: utils/misc/guc.c:1953 +#: utils/misc/guc.c:2125 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Setzt die maximale Stackgröße, in Kilobytes." -#: utils/misc/guc.c:1964 +#: utils/misc/guc.c:2136 msgid "Limits the total size of all temporary files used by each process." msgstr "Beschränkt die Gesamtgröße aller temporären Dateien, die von einem Prozess verwendet werden." -#: utils/misc/guc.c:1965 +#: utils/misc/guc.c:2137 msgid "-1 means no limit." msgstr "-1 bedeutet keine Grenze." -#: utils/misc/guc.c:1975 +#: utils/misc/guc.c:2147 msgid "Vacuum cost for a page found in the buffer cache." msgstr "Vacuum-Kosten für eine im Puffer-Cache gefundene Seite." -#: utils/misc/guc.c:1985 +#: utils/misc/guc.c:2157 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "Vacuum-Kosten für eine nicht im Puffer-Cache gefundene Seite." -#: utils/misc/guc.c:1995 +#: utils/misc/guc.c:2167 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "Vacuum-Kosten für eine durch Vacuum schmutzig gemachte Seite." -#: utils/misc/guc.c:2005 +#: utils/misc/guc.c:2177 msgid "Vacuum cost amount available before napping." msgstr "Verfügbare Vacuum-Kosten vor Nickerchen." -#: utils/misc/guc.c:2015 +#: utils/misc/guc.c:2187 msgid "Vacuum cost delay in milliseconds." msgstr "Vacuum-Kosten-Verzögerung in Millisekunden." -#: utils/misc/guc.c:2026 +#: utils/misc/guc.c:2198 msgid "Vacuum cost delay in milliseconds, for autovacuum." msgstr "Vacuum-Kosten-Verzögerung in Millisekunden, für Autovacuum." -#: utils/misc/guc.c:2037 +#: utils/misc/guc.c:2209 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "Verfügbare Vacuum-Kosten vor Nickerchen, für Autovacuum." -#: utils/misc/guc.c:2047 +#: utils/misc/guc.c:2219 msgid "Sets the maximum number of simultaneously open files for each server process." msgstr "Setzt die maximale Zahl gleichzeitig geöffneter Dateien für jeden Serverprozess." -#: utils/misc/guc.c:2060 +#: utils/misc/guc.c:2232 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Setzt die maximale Anzahl von gleichzeitig vorbereiteten Transaktionen." -#: utils/misc/guc.c:2071 +#: utils/misc/guc.c:2243 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Setzt die minimale Tabellen-OID für das Verfolgen von Sperren." -#: utils/misc/guc.c:2072 +#: utils/misc/guc.c:2244 msgid "Is used to avoid output on system tables." msgstr "Wird verwendet, um Ausgabe für Systemtabellen zu vermeiden." -#: utils/misc/guc.c:2081 +#: utils/misc/guc.c:2253 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Setzt die OID der Tabelle mit bedingungsloser Sperrenverfolgung." -#: utils/misc/guc.c:2093 +#: utils/misc/guc.c:2265 msgid "Sets the maximum allowed duration of any statement." msgstr "Setzt die maximal erlaubte Dauer jeder Anweisung." -#: utils/misc/guc.c:2094 utils/misc/guc.c:2105 utils/misc/guc.c:2116 +#: utils/misc/guc.c:2266 utils/misc/guc.c:2277 utils/misc/guc.c:2288 msgid "A value of 0 turns off the timeout." msgstr "Der Wert 0 schaltet die Zeitprüfung aus." -#: utils/misc/guc.c:2104 +#: utils/misc/guc.c:2276 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Setzt die maximal erlaubte Dauer, um auf eine Sperre zu warten." -#: utils/misc/guc.c:2115 +#: utils/misc/guc.c:2287 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "Setzt die maximal erlaubte Dauer einer inaktiven Transaktion." -#: utils/misc/guc.c:2126 +#: utils/misc/guc.c:2298 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "Mindestalter, bei dem VACUUM eine Tabellenzeile einfrieren soll." -#: utils/misc/guc.c:2136 +#: utils/misc/guc.c:2308 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." -#: utils/misc/guc.c:2146 +#: utils/misc/guc.c:2318 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "Mindestalter, bei dem VACUUM eine MultiXactId in einer Tabellenzeile einfrieren soll." -#: utils/misc/guc.c:2156 +#: utils/misc/guc.c:2328 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "Multixact-Alter, bei dem VACUUM die ganze Tabelle durchsuchen soll, um Zeilen einzufrieren." -#: utils/misc/guc.c:2166 +#: utils/misc/guc.c:2338 msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." msgstr "Anzahl Transaktionen, um die VACUUM- und HOT-Aufräumen aufgeschoben werden soll." -#: utils/misc/guc.c:2179 +#: utils/misc/guc.c:2351 msgid "Sets the maximum number of locks per transaction." msgstr "Setzt die maximale Anzahl Sperren pro Transaktion." -#: utils/misc/guc.c:2180 +#: utils/misc/guc.c:2352 msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "Die globale Sperrentabelle wird mit der Annahme angelegt, das höchstens max_locks_per_transaction * max_connections verschiedene Objekte gleichzeitig gesperrt werden müssen." -#: utils/misc/guc.c:2191 +#: utils/misc/guc.c:2363 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Setzt die maximale Anzahl Prädikatsperren pro Transaktion." -#: utils/misc/guc.c:2192 +#: utils/misc/guc.c:2364 msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "Die globale Prädikatsperrentabelle wird mit der Annahme angelegt, das höchstens max_pred_locks_per_transaction * max_connections verschiedene Objekte gleichzeitig gesperrt werden müssen." -#: utils/misc/guc.c:2203 +#: utils/misc/guc.c:2375 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Setzt die maximale Anzahl Prädikatsperren für Seiten und Tupel pro Relation." + +#: utils/misc/guc.c:2376 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Wenn mehr als diese Gesamtzahl Seiten und Tupel in der selben Relation von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Relationsebene ersetzt." + +#: utils/misc/guc.c:2386 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Setzt die maximale Anzahl Prädikatsperren für Tupel pro Seite." + +#: utils/misc/guc.c:2387 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Wenn mehr als diese Anzahl Tupel auf der selben Seite von einer Verbindung gesperrt sind, werden diese Sperren durch eine Sperre auf Seitenebene ersetzt." + +#: utils/misc/guc.c:2397 msgid "Sets the maximum allowed time to complete client authentication." msgstr "Setzt die maximale Zeit, um die Client-Authentifizierung zu beenden." -#: utils/misc/guc.c:2215 +#: utils/misc/guc.c:2409 msgid "Waits N seconds on connection startup before authentication." msgstr "Wartet beim Starten einer Verbindung N Sekunden vor der Authentifizierung." -#: utils/misc/guc.c:2226 +#: utils/misc/guc.c:2420 msgid "Sets the number of WAL files held for standby servers." msgstr "Setzt die maximale Anzahl der für Standby-Server vorgehaltenen WAL-Dateien." -#: utils/misc/guc.c:2236 +#: utils/misc/guc.c:2430 msgid "Sets the minimum size to shrink the WAL to." msgstr "Setzt die minimale Größe, auf die der WAL geschrumpft wird." -#: utils/misc/guc.c:2247 +#: utils/misc/guc.c:2442 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Setzt die WAL-Größe, die einen Checkpoint auslöst." -#: utils/misc/guc.c:2258 +#: utils/misc/guc.c:2454 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "Setzt die maximale Zeit zwischen automatischen WAL-Checkpoints." -#: utils/misc/guc.c:2269 +#: utils/misc/guc.c:2465 msgid "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "Schreibt eine Logmeldung, wenn Checkpoint-Segmente häufiger als dieser Wert gefüllt werden." -#: utils/misc/guc.c:2271 +#: utils/misc/guc.c:2467 msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." msgstr "Schreibe Meldung in den Serverlog, wenn Checkpoints, die durch Füllen der Checkpoint-Segmente ausgelöst werden, häufiger als dieser Wert in Sekunden passieren. Null schaltet die Warnung ab." -#: utils/misc/guc.c:2283 utils/misc/guc.c:2440 utils/misc/guc.c:2467 +#: utils/misc/guc.c:2479 utils/misc/guc.c:2636 utils/misc/guc.c:2664 msgid "Number of pages after which previously performed writes are flushed to disk." msgstr "Anzahl der Seiten, nach denen getätigte Schreibvorgänge auf die Festplatte zurückgeschrieben werden." -#: utils/misc/guc.c:2294 +#: utils/misc/guc.c:2490 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "Setzt die Anzahl Diskseitenpuffer für WAL im Shared Memory." -#: utils/misc/guc.c:2305 +#: utils/misc/guc.c:2501 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Zeit zwischen WAL-Flush-Operationen im WAL-Writer." -#: utils/misc/guc.c:2316 +#: utils/misc/guc.c:2512 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "Ein Flush wird ausgelöst, wenn diese Menge WAL vom WAL-Writer geschrieben worden ist." -#: utils/misc/guc.c:2328 +#: utils/misc/guc.c:2524 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "Setzt die maximale Anzahl gleichzeitig laufender WAL-Sender-Prozesse." -#: utils/misc/guc.c:2339 +#: utils/misc/guc.c:2535 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Setzt die maximale Anzahl von gleichzeitig definierten Replikations-Slots." -#: utils/misc/guc.c:2349 +#: utils/misc/guc.c:2545 msgid "Sets the maximum time to wait for WAL replication." msgstr "Setzt die maximale Zeit, um auf WAL-Replikation zu warten." -#: utils/misc/guc.c:2360 +#: utils/misc/guc.c:2556 msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." msgstr "Setzt die Verzögerung in Millisekunden zwischen Transaktionsabschluss und dem Schreiben von WAL auf die Festplatte." -#: utils/misc/guc.c:2372 +#: utils/misc/guc.c:2568 msgid "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "Setzt die minimale Anzahl gleichzeitig offener Transaktionen bevor »commit_delay« angewendet wird." -#: utils/misc/guc.c:2383 +#: utils/misc/guc.c:2579 msgid "Sets the number of digits displayed for floating-point values." msgstr "Setzt die Anzahl ausgegebener Ziffern für Fließkommawerte." -#: utils/misc/guc.c:2384 +#: utils/misc/guc.c:2580 msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." msgstr "Diese Einstellung betrifft real, double precision und geometrische Datentypen. Der Parameterwert wird zur Standardziffernanzahl (FLT_DIG bzw. DBL_DIG) hinzuaddiert." -#: utils/misc/guc.c:2395 +#: utils/misc/guc.c:2591 msgid "Sets the minimum execution time above which statements will be logged." msgstr "Setzt die minimale Ausführungszeit, über der Anweisungen geloggt werden." -#: utils/misc/guc.c:2397 +#: utils/misc/guc.c:2593 msgid "Zero prints all queries. -1 turns this feature off." msgstr "Null zeigt alle Anfragen. -1 schaltet dieses Feature aus." -#: utils/misc/guc.c:2407 +#: utils/misc/guc.c:2603 msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgstr "Setzt die minimale Ausführungszeit, über der Autovacuum-Aktionen geloggt werden." -#: utils/misc/guc.c:2409 +#: utils/misc/guc.c:2605 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "Null gibt alls Aktionen aus. -1 schaltet die Log-Aufzeichnung über Autovacuum aus." -#: utils/misc/guc.c:2419 +#: utils/misc/guc.c:2615 msgid "Background writer sleep time between rounds." msgstr "Schlafzeit zwischen Durchläufen des Background-Writers." -#: utils/misc/guc.c:2430 +#: utils/misc/guc.c:2626 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "Maximale Anzahl der vom Background-Writer pro Durchlauf zu flushenden LRU-Seiten." -#: utils/misc/guc.c:2453 +#: utils/misc/guc.c:2649 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "Anzahl simultaner Anfragen, die das Festplattensubsystem effizient bearbeiten kann." -#: utils/misc/guc.c:2454 +#: utils/misc/guc.c:2650 msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." msgstr "Für RAID-Arrays sollte dies ungefähr die Anzahl Spindeln im Array sein." -#: utils/misc/guc.c:2480 +#: utils/misc/guc.c:2677 msgid "Maximum number of concurrent worker processes." msgstr "Maximale Anzahl gleichzeitiger Worker-Prozesse." -#: utils/misc/guc.c:2492 -#, fuzzy -#| msgid "Maximum number of concurrent worker processes." +#: utils/misc/guc.c:2689 msgid "Maximum number of logical replication worker processes." -msgstr "Maximale Anzahl gleichzeitiger Worker-Prozesse." +msgstr "Maximale Anzahl Arbeitsprozesse für logische Replikation." + +#: utils/misc/guc.c:2701 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Maximale Anzahl Arbeitsprozesse für Tabellensynchronisation pro Subskription." -#: utils/misc/guc.c:2502 +#: utils/misc/guc.c:2711 msgid "Automatic log file rotation will occur after N minutes." msgstr "Automatische Rotation der Logdateien geschieht nach N Minuten." -#: utils/misc/guc.c:2513 +#: utils/misc/guc.c:2722 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "Automatische Rotation der Logdateien geschieht nach N Kilobytes." -#: utils/misc/guc.c:2524 +#: utils/misc/guc.c:2733 msgid "Shows the maximum number of function arguments." msgstr "Setzt die maximale Anzahl von Funktionsargumenten." -#: utils/misc/guc.c:2535 +#: utils/misc/guc.c:2744 msgid "Shows the maximum number of index keys." msgstr "Zeigt die maximale Anzahl von Indexschlüsseln." -#: utils/misc/guc.c:2546 +#: utils/misc/guc.c:2755 msgid "Shows the maximum identifier length." msgstr "Zeigt die maximale Länge von Bezeichnern." -#: utils/misc/guc.c:2557 +#: utils/misc/guc.c:2766 msgid "Shows the size of a disk block." msgstr "Zeigt die Größe eines Diskblocks." -#: utils/misc/guc.c:2568 +#: utils/misc/guc.c:2777 msgid "Shows the number of pages per disk file." msgstr "Zeigt die Anzahl Seiten pro Diskdatei." -#: utils/misc/guc.c:2579 +#: utils/misc/guc.c:2788 msgid "Shows the block size in the write ahead log." msgstr "Zeigt die Blockgröße im Write-Ahead-Log." -#: utils/misc/guc.c:2590 +#: utils/misc/guc.c:2799 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "Setzt die Zeit, die gewartet wird, bevor nach einem fehlgeschlagenen Versuch neue WAL-Daten angefordert werden." -#: utils/misc/guc.c:2602 -msgid "Shows the number of pages per write ahead log segment." +#: utils/misc/guc.c:2811 +#, fuzzy +#| msgid "Shows the number of pages per write ahead log segment." +msgid "Shows the size of write ahead log segments." msgstr "Zeit die Anzahl Seiten pro Write-Ahead-Log-Segment." -#: utils/misc/guc.c:2615 +#: utils/misc/guc.c:2824 msgid "Time to sleep between autovacuum runs." msgstr "Wartezeit zwischen Autovacuum-Durchläufen." -#: utils/misc/guc.c:2625 +#: utils/misc/guc.c:2834 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "Mindestanzahl an geänderten oder gelöschten Tupeln vor einem Vacuum." -#: utils/misc/guc.c:2634 +#: utils/misc/guc.c:2843 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "Mindestanzahl an Einfüge-, Änderungs- oder Löschoperationen von einem Analyze." -#: utils/misc/guc.c:2644 +#: utils/misc/guc.c:2853 msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Transaktionsnummernüberlauf zu verhindern." -#: utils/misc/guc.c:2655 +#: utils/misc/guc.c:2864 msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "Multixact-Alter, nach dem eine Tabelle automatisch gevacuumt wird, um Transaktionsnummernüberlauf zu verhindern." -#: utils/misc/guc.c:2665 +#: utils/misc/guc.c:2874 msgid "Sets the maximum number of simultaneously running autovacuum worker processes." msgstr "Setzt die maximale Anzahl gleichzeitig laufender Autovacuum-Worker-Prozesse." -#: utils/misc/guc.c:2675 +#: utils/misc/guc.c:2884 +#, fuzzy +#| msgid "Sets the maximum number of parallel processes per executor node." +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Executor-Knoten." + +#: utils/misc/guc.c:2894 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Setzt die maximale Anzahl paralleler Prozesse pro Executor-Knoten." -#: utils/misc/guc.c:2685 +#: utils/misc/guc.c:2904 #, fuzzy -#| msgid "Sets the maximum number of predicate locks per transaction." -msgid "Sets the maximum number of parallel workers than can be active at one time." -msgstr "Setzt die maximale Anzahl Prädikatsperren pro Transaktion." +#| msgid "Sets the maximum number of parallel workers than can be active at one time." +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Setzt die maximale Anzahl paralleler Arbeitsprozesse, die gleichzeitig aktiv sein können." -#: utils/misc/guc.c:2695 +#: utils/misc/guc.c:2914 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "Setzt die maximale Speichergröße für jeden Autovacuum-Worker-Prozess." -#: utils/misc/guc.c:2706 +#: utils/misc/guc.c:2925 msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." msgstr "Zeit bevor ein Snapshot zu alt ist, um Seiten zu lesen, die geändert wurden, nachdem der Snapshot gemacht wurde." -#: utils/misc/guc.c:2707 +#: utils/misc/guc.c:2926 msgid "A value of -1 disables this feature." msgstr "Der Wert -1 schaltet dieses Feature aus." -#: utils/misc/guc.c:2717 +#: utils/misc/guc.c:2936 msgid "Time between issuing TCP keepalives." msgstr "Zeit zwischen TCP-Keepalive-Sendungen." -#: utils/misc/guc.c:2718 utils/misc/guc.c:2729 +#: utils/misc/guc.c:2937 utils/misc/guc.c:2948 msgid "A value of 0 uses the system default." msgstr "Der Wert 0 verwendet die Systemvoreinstellung." -#: utils/misc/guc.c:2728 +#: utils/misc/guc.c:2947 msgid "Time between TCP keepalive retransmits." msgstr "Zeit zwischen TCP-Keepalive-Neuübertragungen." -#: utils/misc/guc.c:2739 +#: utils/misc/guc.c:2958 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "SSL-Renegotiation wird nicht mehr unterstützt; kann nur auf 0 gesetzt werden." -#: utils/misc/guc.c:2750 +#: utils/misc/guc.c:2969 msgid "Maximum number of TCP keepalive retransmits." msgstr "Maximale Anzahl an TCP-Keepalive-Neuübertragungen." -#: utils/misc/guc.c:2751 +#: utils/misc/guc.c:2970 msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." msgstr "Dies bestimmt die Anzahl von aufeinanderfolgenden Keepalive-Neuübertragungen, die verloren gehen dürfen, bis die Verbindung als tot betrachtet wird. Der Wert 0 verwendet die Betriebssystemvoreinstellung." -#: utils/misc/guc.c:2762 +#: utils/misc/guc.c:2981 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Setzt die maximal erlaubte Anzahl Ergebnisse für eine genaue Suche mit GIN." -#: utils/misc/guc.c:2773 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "Setzt die Annahme des Planers über die Größe des Festplatten-Caches." +#: utils/misc/guc.c:2992 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Setzt die Annahme des Planers über die Gesamtgröße der Daten-Caches." -#: utils/misc/guc.c:2774 -msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." -msgstr "Setzt die Annahme des Planers über die effektive Größe des Diskcaches (das heißt des Teils des Diskcaches vom Kernel, der für die Datendateien von PostgreSQL verwendet wird). Das wird in Diskseiten gemessen, welche normalerweise 8 kB groß sind." +#: utils/misc/guc.c:2993 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Das heißt, die Gesamtgröße der Caches (Kernel-Cache und Shared Buffers), die für Datendateien von PostgreSQL verwendet wird. Das wird in Diskseiten gemessen, welche normalerweise 8 kB groß sind." -#: utils/misc/guc.c:2786 -#, fuzzy -#| msgid "Sets the minimum size of relations to be considered for parallel scan." +#: utils/misc/guc.c:3004 msgid "Sets the minimum amount of table data for a parallel scan." -msgstr "Setzt die minimale Größe einer Relation, um für einen parallelen Scan in Betracht gezogen werden zu können." +msgstr "Setzt die Mindestmenge an Tabellendaten für einen parallelen Scan." -#: utils/misc/guc.c:2787 +#: utils/misc/guc.c:3005 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." -msgstr "" +msgstr "Wenn der Planer schätzt, dass zu wenige Tabellenseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." -#: utils/misc/guc.c:2797 -#, fuzzy -#| msgid "Sets the minimum size of relations to be considered for parallel scan." +#: utils/misc/guc.c:3015 msgid "Sets the minimum amount of index data for a parallel scan." -msgstr "Setzt die minimale Größe einer Relation, um für einen parallelen Scan in Betracht gezogen werden zu können." +msgstr "Setzt die Mindestmenge an Indexdaten für einen parallelen Scan." -#: utils/misc/guc.c:2798 +#: utils/misc/guc.c:3016 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." -msgstr "" +msgstr "Wenn der Planer schätzt, dass zu wenige Indexseiten gelesen werden werden um diesen Wert zu erreichen, dann wird kein paralleler Scan in Erwägung gezogen werden." -#: utils/misc/guc.c:2809 +#: utils/misc/guc.c:3027 msgid "Shows the server version as an integer." msgstr "Zeigt die Serverversion als Zahl." -#: utils/misc/guc.c:2820 +#: utils/misc/guc.c:3038 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "Schreibt Meldungen über die Verwendung von temporären Dateien in den Log, wenn sie größer als diese Anzahl an Kilobytes sind." -#: utils/misc/guc.c:2821 +#: utils/misc/guc.c:3039 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "Null loggt alle Dateien. Die Standardeinstellung ist -1 (wodurch dieses Feature ausgeschaltet wird)." -#: utils/misc/guc.c:2831 +#: utils/misc/guc.c:3049 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Setzt die für pg_stat_activity.query reservierte Größe, in Bytes." -#: utils/misc/guc.c:2846 +#: utils/misc/guc.c:3060 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Setzt die maximale Größe der Pending-Liste eines GIN-Index." -#: utils/misc/guc.c:2866 +#: utils/misc/guc.c:3080 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine sequenzielle Diskseite zu lesen." -#: utils/misc/guc.c:2876 +#: utils/misc/guc.c:3090 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine nichtsequenzielle Diskseite zu lesen." -#: utils/misc/guc.c:2886 +#: utils/misc/guc.c:3100 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung einer Zeile." -#: utils/misc/guc.c:2896 +#: utils/misc/guc.c:3110 msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung eines Indexeintrags während eines Index-Scans." -#: utils/misc/guc.c:2906 +#: utils/misc/guc.c:3120 msgid "Sets the planner's estimate of the cost of processing each operator or function call." msgstr "Setzt den vom Planer geschätzten Aufwand für die Verarbeitung eines Operators oder Funktionsaufrufs." -#: utils/misc/guc.c:2916 +#: utils/misc/guc.c:3130 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." msgstr "Setzt den vom Planer geschätzten Aufwand, um eine Zeile vom Arbeitsprozess and das Master-Backend zu senden." -#: utils/misc/guc.c:2926 +#: utils/misc/guc.c:3140 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "Setzt den vom Planer geschätzten Aufwand für das Starten von Arbeitsprozessen für parallele Anfragen." -#: utils/misc/guc.c:2937 +#: utils/misc/guc.c:3151 +msgid "Perform JIT compilation if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3152 +msgid "-1 disables JIT compilation." +msgstr "" + +#: utils/misc/guc.c:3161 +msgid "Optimize JITed functions if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3162 +#, fuzzy +#| msgid "Enables genetic query optimization." +msgid "-1 disables optimization." +msgstr "Ermöglicht genetische Anfrageoptimierung." + +#: utils/misc/guc.c:3171 +msgid "Perform JIT inlining if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3172 +msgid "-1 disables inlining." +msgstr "" + +#: utils/misc/guc.c:3181 msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." msgstr "Setzt den vom Planer geschätzten Anteil der Cursor-Zeilen, die ausgelesen werden werden." -#: utils/misc/guc.c:2948 +#: utils/misc/guc.c:3192 msgid "GEQO: selective pressure within the population." msgstr "GEQO: selektiver Auswahldruck in der Bevölkerung." -#: utils/misc/guc.c:2958 +#: utils/misc/guc.c:3202 msgid "GEQO: seed for random path selection." msgstr "GEQO: Ausgangswert für die zufällige Pfadauswahl." -#: utils/misc/guc.c:2968 +#: utils/misc/guc.c:3212 msgid "Multiple of the average buffer usage to free per round." msgstr "Vielfaches der durchschnittlichen freizugebenden Pufferverwendung pro Runde." -#: utils/misc/guc.c:2978 +#: utils/misc/guc.c:3222 msgid "Sets the seed for random-number generation." msgstr "Setzt den Ausgangswert für die Zufallszahlenerzeugung." -#: utils/misc/guc.c:2989 +#: utils/misc/guc.c:3233 msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." msgstr "Anzahl geänderter oder gelöschter Tupel vor einem Vacuum, relativ zu reltuples." -#: utils/misc/guc.c:2998 +#: utils/misc/guc.c:3242 msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." msgstr "Anzahl eingefügter, geänderter oder gelöschter Tupel vor einem Analyze, relativ zu reltuples." -#: utils/misc/guc.c:3008 +#: utils/misc/guc.c:3252 msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." msgstr "Zeit, die damit verbracht wird, modifizierte Puffer während eines Checkpoints zurückzuschreiben, als Bruchteil des Checkpoint-Intervalls." -#: utils/misc/guc.c:3027 +#: utils/misc/guc.c:3262 +#, fuzzy +#| msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Anzahl geänderter oder gelöschter Tupel vor einem Vacuum, relativ zu reltuples." + +#: utils/misc/guc.c:3281 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "Setzt den Shell-Befehl, der aufgerufen wird, um eine WAL-Datei zu archivieren." -#: utils/misc/guc.c:3037 +#: utils/misc/guc.c:3291 msgid "Sets the client's character set encoding." msgstr "Setzt die Zeichensatzkodierung des Clients." -#: utils/misc/guc.c:3048 +#: utils/misc/guc.c:3302 msgid "Controls information prefixed to each log line." msgstr "Bestimmt die Informationen, die vor jede Logzeile geschrieben werden." -#: utils/misc/guc.c:3049 +#: utils/misc/guc.c:3303 msgid "If blank, no prefix is used." msgstr "Wenn leer, dann wird kein Präfix verwendet." -#: utils/misc/guc.c:3058 +#: utils/misc/guc.c:3312 msgid "Sets the time zone to use in log messages." msgstr "Setzt die in Logmeldungen verwendete Zeitzone." -#: utils/misc/guc.c:3068 +#: utils/misc/guc.c:3322 msgid "Sets the display format for date and time values." msgstr "Setzt das Ausgabeformat für Datums- und Zeitwerte." -#: utils/misc/guc.c:3069 +#: utils/misc/guc.c:3323 msgid "Also controls interpretation of ambiguous date inputs." msgstr "Kontrolliert auch die Interpretation von zweideutigen Datumseingaben." -#: utils/misc/guc.c:3080 +#: utils/misc/guc.c:3334 msgid "Sets the default tablespace to create tables and indexes in." msgstr "Setzt den Standard-Tablespace für Tabellen und Indexe." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3335 msgid "An empty string selects the database's default tablespace." msgstr "Eine leere Zeichenkette wählt den Standard-Tablespace der Datenbank." -#: utils/misc/guc.c:3091 +#: utils/misc/guc.c:3345 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "Setzt den oder die Tablespaces für temporäre Tabellen und Sortierdateien." -#: utils/misc/guc.c:3102 +#: utils/misc/guc.c:3356 msgid "Sets the path for dynamically loadable modules." msgstr "Setzt den Pfad für ladbare dynamische Bibliotheken." -#: utils/misc/guc.c:3103 +#: utils/misc/guc.c:3357 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "Wenn ein dynamisch ladbares Modul geöffnet werden muss und der angegebene Name keine Verzeichniskomponente hat (das heißt er enthält keinen Schrägstrich), dann sucht das System in diesem Pfad nach der angegebenen Datei." -#: utils/misc/guc.c:3116 +#: utils/misc/guc.c:3370 msgid "Sets the location of the Kerberos server key file." msgstr "Setzt den Ort der Kerberos-Server-Schlüsseldatei." -#: utils/misc/guc.c:3127 +#: utils/misc/guc.c:3381 msgid "Sets the Bonjour service name." msgstr "Setzt den Bonjour-Servicenamen." -#: utils/misc/guc.c:3139 +#: utils/misc/guc.c:3393 msgid "Shows the collation order locale." msgstr "Zeigt die Locale für die Sortierreihenfolge." -#: utils/misc/guc.c:3150 +#: utils/misc/guc.c:3404 msgid "Shows the character classification and case conversion locale." msgstr "Zeigt die Locale für Zeichenklassifizierung und Groß-/Kleinschreibung." -#: utils/misc/guc.c:3161 +#: utils/misc/guc.c:3415 msgid "Sets the language in which messages are displayed." msgstr "Setzt die Sprache, in der Mitteilungen ausgegeben werden." -#: utils/misc/guc.c:3171 +#: utils/misc/guc.c:3425 msgid "Sets the locale for formatting monetary amounts." msgstr "Setzt die Locale für die Formatierung von Geldbeträgen." -#: utils/misc/guc.c:3181 +#: utils/misc/guc.c:3435 msgid "Sets the locale for formatting numbers." msgstr "Setzt die Locale für die Formatierung von Zahlen." -#: utils/misc/guc.c:3191 +#: utils/misc/guc.c:3445 msgid "Sets the locale for formatting date and time values." msgstr "Setzt die Locale für die Formatierung von Datums- und Zeitwerten." -#: utils/misc/guc.c:3201 +#: utils/misc/guc.c:3455 msgid "Lists shared libraries to preload into each backend." msgstr "Listet dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." -#: utils/misc/guc.c:3212 +#: utils/misc/guc.c:3466 msgid "Lists shared libraries to preload into server." msgstr "Listet dynamische Bibliotheken, die vorab in den Server geladen werden." -#: utils/misc/guc.c:3223 +#: utils/misc/guc.c:3477 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "Listet unprivilegierte dynamische Bibliotheken, die vorab in jeden Serverprozess geladen werden." -#: utils/misc/guc.c:3234 +#: utils/misc/guc.c:3488 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "Setzt die Schemasuchreihenfolge für Namen ohne Schemaqualifikation." -#: utils/misc/guc.c:3246 +#: utils/misc/guc.c:3500 msgid "Sets the server (database) character set encoding." msgstr "Setzt die Zeichensatzkodierung des Servers (der Datenbank)." -#: utils/misc/guc.c:3258 +#: utils/misc/guc.c:3512 msgid "Shows the server version." msgstr "Zeigt die Serverversion." -#: utils/misc/guc.c:3270 +#: utils/misc/guc.c:3524 msgid "Sets the current role." msgstr "Setzt die aktuelle Rolle." -#: utils/misc/guc.c:3282 +#: utils/misc/guc.c:3536 msgid "Sets the session user name." msgstr "Setzt den Sitzungsbenutzernamen." -#: utils/misc/guc.c:3293 +#: utils/misc/guc.c:3547 msgid "Sets the destination for server log output." msgstr "Setzt das Ziel für die Serverlogausgabe." -#: utils/misc/guc.c:3294 +#: utils/misc/guc.c:3548 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." msgstr "Gültige Werte sind Kombinationen von »stderr«, »syslog«, »csvlog« und »eventlog«, je nach Plattform." -#: utils/misc/guc.c:3305 +#: utils/misc/guc.c:3559 msgid "Sets the destination directory for log files." msgstr "Bestimmt das Zielverzeichnis für Logdateien." -#: utils/misc/guc.c:3306 +#: utils/misc/guc.c:3560 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "Kann relativ zum Datenverzeichnis oder als absoluter Pfad angegeben werden." -#: utils/misc/guc.c:3316 +#: utils/misc/guc.c:3570 msgid "Sets the file name pattern for log files." msgstr "Bestimmt das Dateinamenmuster für Logdateien." -#: utils/misc/guc.c:3327 +#: utils/misc/guc.c:3581 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Syslog identifiziert werden." -#: utils/misc/guc.c:3338 +#: utils/misc/guc.c:3592 msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "Setzt den Programmnamen, mit dem PostgreSQL-Meldungen im Ereignisprotokoll identifiziert werden." -#: utils/misc/guc.c:3349 +#: utils/misc/guc.c:3603 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "Setzt die Zeitzone, in der Zeitangaben interpretiert und ausgegeben werden." -#: utils/misc/guc.c:3359 +#: utils/misc/guc.c:3613 msgid "Selects a file of time zone abbreviations." msgstr "Wählt eine Datei mit Zeitzonenabkürzungen." -#: utils/misc/guc.c:3369 +#: utils/misc/guc.c:3623 msgid "Sets the current transaction's isolation level." msgstr "Zeigt den Isolationsgrad der aktuellen Transaktion." -#: utils/misc/guc.c:3380 +#: utils/misc/guc.c:3634 msgid "Sets the owning group of the Unix-domain socket." msgstr "Setzt die Eigentümergruppe der Unix-Domain-Socket." -#: utils/misc/guc.c:3381 +#: utils/misc/guc.c:3635 msgid "The owning user of the socket is always the user that starts the server." msgstr "Der Eigentümer ist immer der Benutzer, der den Server startet." -#: utils/misc/guc.c:3391 +#: utils/misc/guc.c:3645 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Setzt die Verzeichnisse, in denen Unix-Domain-Sockets erzeugt werden sollen." -#: utils/misc/guc.c:3406 +#: utils/misc/guc.c:3660 msgid "Sets the host name or IP address(es) to listen to." msgstr "Setzt den Hostnamen oder die IP-Adresse(n), auf der auf Verbindungen gewartet wird." -#: utils/misc/guc.c:3421 +#: utils/misc/guc.c:3675 msgid "Sets the server's data directory." msgstr "Setzt das Datenverzeichnis des Servers." -#: utils/misc/guc.c:3432 +#: utils/misc/guc.c:3686 msgid "Sets the server's main configuration file." msgstr "Setzt die Hauptkonfigurationsdatei des Servers." -#: utils/misc/guc.c:3443 +#: utils/misc/guc.c:3697 msgid "Sets the server's \"hba\" configuration file." msgstr "Setzt die »hba«-Konfigurationsdatei des Servers." -#: utils/misc/guc.c:3454 +#: utils/misc/guc.c:3708 msgid "Sets the server's \"ident\" configuration file." msgstr "Setzt die »ident«-Konfigurationsdatei des Servers." -#: utils/misc/guc.c:3465 +#: utils/misc/guc.c:3719 msgid "Writes the postmaster PID to the specified file." msgstr "Schreibt die Postmaster-PID in die angegebene Datei." -#: utils/misc/guc.c:3476 +#: utils/misc/guc.c:3730 msgid "Location of the SSL server certificate file." msgstr "Ort der SSL-Serverzertifikatsdatei." -#: utils/misc/guc.c:3486 +#: utils/misc/guc.c:3740 msgid "Location of the SSL server private key file." msgstr "Setzt den Ort der Datei mit dem privaten SSL-Server-Schlüssel." -#: utils/misc/guc.c:3496 +#: utils/misc/guc.c:3750 msgid "Location of the SSL certificate authority file." msgstr "Ort der SSL-Certificate-Authority-Datei." -#: utils/misc/guc.c:3506 +#: utils/misc/guc.c:3760 msgid "Location of the SSL certificate revocation list file." msgstr "Ort der SSL-Certificate-Revocation-List-Datei." -#: utils/misc/guc.c:3516 +#: utils/misc/guc.c:3770 msgid "Writes temporary statistics files to the specified directory." msgstr "Schreibt temporäre Statistikdateien in das angegebene Verzeichnis." -#: utils/misc/guc.c:3527 +#: utils/misc/guc.c:3781 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "Anzahl synchroner Standbys und Liste der Namen der möglichen synchronen Standbys." -#: utils/misc/guc.c:3538 +#: utils/misc/guc.c:3792 msgid "Sets default text search configuration." msgstr "Setzt die vorgegebene Textsuchekonfiguration." -#: utils/misc/guc.c:3548 +#: utils/misc/guc.c:3802 msgid "Sets the list of allowed SSL ciphers." msgstr "Setzt die Liste der erlaubten SSL-Verschlüsselungsalgorithmen." -#: utils/misc/guc.c:3563 +#: utils/misc/guc.c:3817 msgid "Sets the curve to use for ECDH." msgstr "Setzt die für ECDH zu verwendende Kurve." -#: utils/misc/guc.c:3578 +#: utils/misc/guc.c:3832 +msgid "Location of the SSL DH parameters file." +msgstr "Setzt den Ort der SSL-DH-Parameter-Datei." + +#: utils/misc/guc.c:3843 +msgid "Command to obtain passphrases for SSL." +msgstr "Befehl zum Einlesen von Passphrasen für SSL." + +#: utils/misc/guc.c:3853 msgid "Sets the application name to be reported in statistics and logs." msgstr "Setzt den Anwendungsnamen, der in Statistiken und Logs verzeichnet wird." -#: utils/misc/guc.c:3589 +#: utils/misc/guc.c:3864 msgid "Sets the name of the cluster, which is included in the process title." msgstr "Setzt den Namen des Clusters, welcher im Prozesstitel angezeigt wird." -#: utils/misc/guc.c:3600 +#: utils/misc/guc.c:3875 msgid "Sets the WAL resource managers for which WAL consistency checks are done." -msgstr "" +msgstr "Setzt die WAL-Resource-Manager, für die WAL-Konsistenzprüfungen durchgeführt werden." -#: utils/misc/guc.c:3601 +#: utils/misc/guc.c:3876 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Volle Seitenabbilder werden für alle Datenblöcke geloggt und gegen die Resultate der WAL-Wiederherstellung geprüft." + +#: utils/misc/guc.c:3886 +msgid "JIT provider to use." msgstr "" -#: utils/misc/guc.c:3620 +#: utils/misc/guc.c:3906 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "Bestimmt, ob »\\'« in Zeichenkettenkonstanten erlaubt ist." -#: utils/misc/guc.c:3630 +#: utils/misc/guc.c:3916 msgid "Sets the output format for bytea." msgstr "Setzt das Ausgabeformat für bytea." -#: utils/misc/guc.c:3640 +#: utils/misc/guc.c:3926 msgid "Sets the message levels that are sent to the client." msgstr "Setzt die Meldungstypen, die an den Client gesendet werden." -#: utils/misc/guc.c:3641 utils/misc/guc.c:3694 utils/misc/guc.c:3705 -#: utils/misc/guc.c:3771 +#: utils/misc/guc.c:3927 utils/misc/guc.c:3980 utils/misc/guc.c:3991 +#: utils/misc/guc.c:4057 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "Jeder Wert schließt alle ihm folgenden Werte mit ein. Je weiter hinten der Wert steht, desto weniger Meldungen werden gesendet werden." -#: utils/misc/guc.c:3651 +#: utils/misc/guc.c:3937 msgid "Enables the planner to use constraints to optimize queries." msgstr "Ermöglicht dem Planer die Verwendung von Constraints, um Anfragen zu optimieren." -#: utils/misc/guc.c:3652 +#: utils/misc/guc.c:3938 msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "Tabellen-Scans werden übersprungen, wenn deren Constraints garantieren, dass keine Zeile mit der Abfrage übereinstimmt." -#: utils/misc/guc.c:3662 +#: utils/misc/guc.c:3948 msgid "Sets the transaction isolation level of each new transaction." msgstr "Setzt den Transaktionsisolationsgrad neuer Transaktionen." -#: utils/misc/guc.c:3672 +#: utils/misc/guc.c:3958 msgid "Sets the display format for interval values." msgstr "Setzt das Ausgabeformat für Intervallwerte." -#: utils/misc/guc.c:3683 +#: utils/misc/guc.c:3969 msgid "Sets the verbosity of logged messages." msgstr "Setzt den Detailgrad von geloggten Meldungen." -#: utils/misc/guc.c:3693 +#: utils/misc/guc.c:3979 msgid "Sets the message levels that are logged." msgstr "Setzt die Meldungstypen, die geloggt werden." -#: utils/misc/guc.c:3704 +#: utils/misc/guc.c:3990 msgid "Causes all statements generating error at or above this level to be logged." msgstr "Schreibt alle Anweisungen, die einen Fehler auf dieser Stufe oder höher verursachen, in den Log." -#: utils/misc/guc.c:3715 +#: utils/misc/guc.c:4001 msgid "Sets the type of statements logged." msgstr "Setzt die Anweisungsarten, die geloggt werden." -#: utils/misc/guc.c:3725 +#: utils/misc/guc.c:4011 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "Setzt die zu verwendende Syslog-»Facility«, wenn Syslog angeschaltet ist." -#: utils/misc/guc.c:3740 +#: utils/misc/guc.c:4026 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "Setzt das Sitzungsverhalten für Trigger und Regeln." -#: utils/misc/guc.c:3750 +#: utils/misc/guc.c:4036 msgid "Sets the current transaction's synchronization level." msgstr "Setzt den Synchronisationsgrad der aktuellen Transaktion." -#: utils/misc/guc.c:3760 +#: utils/misc/guc.c:4046 msgid "Allows archiving of WAL files using archive_command." msgstr "Erlaubt die Archivierung von WAL-Dateien mittels archive_command." -#: utils/misc/guc.c:3770 +#: utils/misc/guc.c:4056 msgid "Enables logging of recovery-related debugging information." msgstr "Ermöglicht das Loggen von Debug-Informationen über die Wiederherstellung." -#: utils/misc/guc.c:3786 +#: utils/misc/guc.c:4072 msgid "Collects function-level statistics on database activity." msgstr "Sammelt Statistiken auf Funktionsebene über Datenbankaktivität." -#: utils/misc/guc.c:3796 +#: utils/misc/guc.c:4082 msgid "Set the level of information written to the WAL." msgstr "Setzt den Umfang der in den WAL geschriebenen Informationen." -#: utils/misc/guc.c:3806 +#: utils/misc/guc.c:4092 msgid "Selects the dynamic shared memory implementation used." msgstr "Wählt die zu verwendende Implementierung von dynamischem Shared Memory." -#: utils/misc/guc.c:3816 +#: utils/misc/guc.c:4102 msgid "Selects the method used for forcing WAL updates to disk." msgstr "Wählt die Methode, um das Schreiben von WAL-Änderungen auf die Festplatte zu erzwingen." -#: utils/misc/guc.c:3826 +#: utils/misc/guc.c:4112 msgid "Sets how binary values are to be encoded in XML." msgstr "Setzt, wie binäre Werte in XML kodiert werden." -#: utils/misc/guc.c:3836 +#: utils/misc/guc.c:4122 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "Setzt, ob XML-Daten in impliziten Parse- und Serialisierungsoperationen als Dokument oder Fragment betrachtet werden sollen." -#: utils/misc/guc.c:3847 -msgid "Use of huge pages on Linux." -msgstr "Huge Pages auf Linux verwenden." +#: utils/misc/guc.c:4133 +msgid "Use of huge pages on Linux or Windows." +msgstr "Huge Pages auf Linux oder Windows verwenden." -#: utils/misc/guc.c:3857 +#: utils/misc/guc.c:4143 msgid "Forces use of parallel query facilities." msgstr "Verwendung der Einrichtungen für parallele Anfragen erzwingen." -#: utils/misc/guc.c:3858 +#: utils/misc/guc.c:4144 msgid "If possible, run query using a parallel worker and with parallel restrictions." msgstr "Wenn möglich werden Anfragen in einem parallelen Arbeitsprozess und mit parallelen Beschränkungen ausgeführt." -#: utils/misc/guc.c:3867 +#: utils/misc/guc.c:4153 msgid "Encrypt passwords." msgstr "Verschlüsselt Passwörter." -#: utils/misc/guc.c:3868 +#: utils/misc/guc.c:4154 msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." msgstr "Wenn in CREATE USER oder ALTER USER ein Passwort ohne ENCRYPTED oder UNENCRYPTED angegeben ist, bestimmt dieser Parameter, ob das Passwort verschlüsselt wird." -#: utils/misc/guc.c:4670 +#: utils/misc/guc.c:4956 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" -#: utils/misc/guc.c:4675 +#: utils/misc/guc.c:4961 #, c-format msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" msgstr "Führen Sie initdb oder pg_basebackup aus, um ein PostgreSQL-Datenverzeichnis zu initialisieren.\n" -#: utils/misc/guc.c:4695 +#: utils/misc/guc.c:4981 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -24029,12 +25824,12 @@ msgstr "" "Sie müssen die Kommandozeilenoption --config-file oder -D angegeben oder\n" "die Umgebungsvariable PGDATA setzen.\n" -#: utils/misc/guc.c:4714 +#: utils/misc/guc.c:5000 #, c-format msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s: konnte nicht auf die Serverkonfigurationsdatei »%s« zugreifen: %s\n" -#: utils/misc/guc.c:4740 +#: utils/misc/guc.c:5026 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -24044,7 +25839,7 @@ msgstr "" "zu finden sind. Sie können dies mit »data_directory« in »%s«, mit der\n" "Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" -#: utils/misc/guc.c:4788 +#: utils/misc/guc.c:5074 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -24054,7 +25849,7 @@ msgstr "" "Sie können dies mit »hba_file« in »%s«, mit der\n" "Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" -#: utils/misc/guc.c:4811 +#: utils/misc/guc.c:5097 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -24064,164 +25859,174 @@ msgstr "" "Sie können dies mit »ident_file« in »%s«, mit der\n" "Kommandozeilenoption -D oder der Umgebungsvariable PGDATA angeben.\n" -#: utils/misc/guc.c:5485 utils/misc/guc.c:5532 +#: utils/misc/guc.c:5772 utils/misc/guc.c:5819 msgid "Value exceeds integer range." msgstr "Wert überschreitet Bereich für ganze Zahlen." -#: utils/misc/guc.c:5755 +#: utils/misc/guc.c:6042 #, c-format msgid "parameter \"%s\" requires a numeric value" msgstr "Parameter »%s« erfordert einen numerischen Wert" -#: utils/misc/guc.c:5764 +#: utils/misc/guc.c:6051 #, c-format msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" msgstr "%g ist außerhalb des gültigen Bereichs für Parameter »%s« (%g ... %g)" -#: utils/misc/guc.c:5917 utils/misc/guc.c:7260 +#: utils/misc/guc.c:6204 utils/misc/guc.c:7574 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "während einer parallelen Operation können keine Parameter gesetzt werden" -#: utils/misc/guc.c:5924 utils/misc/guc.c:6675 utils/misc/guc.c:6727 -#: utils/misc/guc.c:7088 utils/misc/guc.c:7847 utils/misc/guc.c:8015 -#: utils/misc/guc.c:9690 +#: utils/misc/guc.c:6211 utils/misc/guc.c:6963 utils/misc/guc.c:7016 +#: utils/misc/guc.c:7067 utils/misc/guc.c:7403 utils/misc/guc.c:8170 +#: utils/misc/guc.c:8338 utils/misc/guc.c:10015 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "unbekannter Konfigurationsparameter »%s«" -#: utils/misc/guc.c:5939 utils/misc/guc.c:7100 +#: utils/misc/guc.c:6226 utils/misc/guc.c:7415 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "Parameter »%s« kann nicht geändert werden" -#: utils/misc/guc.c:5972 +#: utils/misc/guc.c:6259 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "Parameter »%s« kann jetzt nicht geändert werden" -#: utils/misc/guc.c:5990 utils/misc/guc.c:6036 utils/misc/guc.c:9706 +#: utils/misc/guc.c:6277 utils/misc/guc.c:6324 utils/misc/guc.c:10031 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "keine Berechtigung, um Parameter »%s« zu setzen" -#: utils/misc/guc.c:6026 +#: utils/misc/guc.c:6314 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "Parameter »%s« kann nach Start der Verbindung nicht geändert werden" -#: utils/misc/guc.c:6074 +#: utils/misc/guc.c:6362 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "Parameter »%s« kann nicht in einer Security-Definer-Funktion gesetzt werden" -#: utils/misc/guc.c:6683 utils/misc/guc.c:6731 utils/misc/guc.c:8021 +#: utils/misc/guc.c:6971 utils/misc/guc.c:7021 utils/misc/guc.c:8345 #, c-format -msgid "must be superuser to examine \"%s\"" -msgstr "nur Superuser können »%s« ansehen" +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "nur Superuser oder Mitglieder von pg_read_all_settings können »%s« ansehen" -#: utils/misc/guc.c:6797 +#: utils/misc/guc.c:7112 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s darf nur ein Argument haben" -#: utils/misc/guc.c:7048 +#: utils/misc/guc.c:7363 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" msgstr "nur Superuser können den Befehl ALTER SYSTEM ausführen" -#: utils/misc/guc.c:7133 +#: utils/misc/guc.c:7448 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "Parameterwert für ALTER SYSTEM darf keine Newline enthalten" -#: utils/misc/guc.c:7178 +#: utils/misc/guc.c:7493 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "konnte Inhalt der Datei »%s« nicht parsen" -#: utils/misc/guc.c:7336 +#: utils/misc/guc.c:7650 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT ist nicht implementiert" -#: utils/misc/guc.c:7420 +#: utils/misc/guc.c:7734 #, c-format msgid "SET requires parameter name" msgstr "SET benötigt Parameternamen" -#: utils/misc/guc.c:7544 +#: utils/misc/guc.c:7867 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "Versuch, den Parameter »%s« zu redefinieren" -#: utils/misc/guc.c:9323 +#: utils/misc/guc.c:9648 #, c-format msgid "parameter \"%s\" could not be set" msgstr "Parameter »%s« kann nicht gesetzt werden" -#: utils/misc/guc.c:9410 +#: utils/misc/guc.c:9735 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "konnte Wert von Parameter »%s« nicht lesen" -#: utils/misc/guc.c:9768 utils/misc/guc.c:9802 +#: utils/misc/guc.c:10093 utils/misc/guc.c:10127 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "ungültiger Wert für Parameter »%s«: %d" -#: utils/misc/guc.c:9836 +#: utils/misc/guc.c:10161 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "ungültiger Wert für Parameter »%s«: %g" -#: utils/misc/guc.c:10106 +#: utils/misc/guc.c:10445 #, c-format msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." msgstr "»temp_buffers« kann nicht geändert werden, nachdem in der Sitzung auf temporäre Tabellen zugriffen wurde." -#: utils/misc/guc.c:10118 +#: utils/misc/guc.c:10457 #, c-format msgid "Bonjour is not supported by this build" msgstr "Bonjour wird von dieser Installation nicht unterstützt" -#: utils/misc/guc.c:10131 +#: utils/misc/guc.c:10470 #, c-format msgid "SSL is not supported by this build" msgstr "SSL wird von dieser Installation nicht unterstützt" -#: utils/misc/guc.c:10143 +#: utils/misc/guc.c:10482 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "Kann Parameter nicht einschalten, wenn »log_statement_stats« an ist." -#: utils/misc/guc.c:10155 +#: utils/misc/guc.c:10494 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "Kann »log_statement_stats« nicht einschalten, wenn »log_parser_stats«, »log_planner_stats« oder »log_executor_stats« an ist." +#: utils/misc/guc.c:10710 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgstr "" + #: utils/misc/help_config.c:131 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "interner Fehler: unbekannter Parametertyp\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format msgid "query-specified return tuple and function return type are not compatible" msgstr "in der Anfrage angegebenes Rückgabetupel und Rückgabetyp der Funktion sind nicht kompatibel" -#: utils/misc/pg_controldata.c:58 utils/misc/pg_controldata.c:138 -#: utils/misc/pg_controldata.c:244 utils/misc/pg_controldata.c:311 +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in der Datei überein" -#: utils/misc/rls.c:128 +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: Benutzer: %d,%02d s, System: %d,%02d s, verstrichen: %d,%02d s" + +#: utils/misc/rls.c:127 #, c-format msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "Policy für Sicherheit auf Zeilenebene für Tabelle »%s« würde Auswirkung auf die Anfrage haben" -#: utils/misc/rls.c:130 +#: utils/misc/rls.c:129 #, c-format msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "Um die Policy für den Tabelleneigentümer zu deaktivieren, verwenden Sie ALTER TABLE NO FORCE ROW LEVEL SECURITY." @@ -24296,249 +26101,174 @@ msgstr "Zeile ist zu lang in Zeitzonendatei »%s«, Zeile %d" msgid "@INCLUDE without file name in time zone file \"%s\", line %d" msgstr "@INCLUDE ohne Dateiname in Zeitzonendatei »%s«, Zeile %d" -#: utils/mmgr/aset.c:405 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "Fehler während der Erzeugung des Speicherkontexts »%s«." -#: utils/mmgr/dsa.c:518 -#, fuzzy, c-format -#| msgid "could not set up XML error handler" -msgid "could not attach to dsa_handle" -msgstr "konnte XML-Fehlerbehandlung nicht einrichten" +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1325 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "konnte nicht an dynamische Shared Area anbinden" -#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 #, fuzzy, c-format #| msgid "Failed on request of size %zu." -msgid "Failed on DSA request of size %zu." -msgstr "Fehler bei Anfrage mit Größe %zu." - -#: utils/mmgr/mcxt.c:726 utils/mmgr/mcxt.c:761 utils/mmgr/mcxt.c:798 -#: utils/mmgr/mcxt.c:835 utils/mmgr/mcxt.c:869 utils/mmgr/mcxt.c:898 -#: utils/mmgr/mcxt.c:932 utils/mmgr/mcxt.c:983 utils/mmgr/mcxt.c:1017 -#: utils/mmgr/mcxt.c:1051 -#, c-format -msgid "Failed on request of size %zu." +msgid "Failed on request of size %zu in memory context \"%s\"." msgstr "Fehler bei Anfrage mit Größe %zu." -#: utils/mmgr/portalmem.c:186 +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "Cursor »%s« existiert bereits" -#: utils/mmgr/portalmem.c:190 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "bestehender Cursor »%s« wird geschlossen" -#: utils/mmgr/portalmem.c:394 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "Portal »%s« kann nicht ausgeführt werden" -#: utils/mmgr/portalmem.c:474 +#: utils/mmgr/portalmem.c:476 +#, fuzzy, c-format +#| msgid "cannot drop active portal \"%s\"" +msgid "cannot drop pinned portal \"%s\"" +msgstr "aktives Portal »%s« kann nicht gelöscht werden" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "aktives Portal »%s« kann nicht gelöscht werden" -#: utils/mmgr/portalmem.c:678 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "PREPARE kann nicht in einer Transaktion ausgeführt werden, die einen Cursor mit WITH HOLD erzeugt hat" -#: utils/sort/logtape.c:252 +#: utils/mmgr/portalmem.c:1263 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "konnte Block %ld von temporärer Datei nicht lesen: %m" -#: utils/sort/tuplesort.c:3056 +#: utils/sort/sharedtuplestore.c:208 +#, fuzzy, c-format +#| msgid "could not write to hash-join temporary file: %m" +msgid "could not write to temporary file: %m" +msgstr "konnte nicht in temporäre Datei für Hash-Verbund schreiben: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, fuzzy, c-format +#| msgid "could not read from tuplestore temporary file: %m" +msgid "could not read from shared tuplestore temporary file" +msgstr "konnte nicht aus temporärer Datei für Tuplestore lesen: %m" + +#: utils/sort/sharedtuplestore.c:492 +#, fuzzy, c-format +#| msgid "could not seek in tuplestore temporary file: %m" +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "konnte Positionszeiger in temporärer Datei für Tuplestore nicht setzen: %m" + +#: utils/sort/tuplesort.c:2967 #, c-format msgid "cannot have more than %d runs for an external sort" msgstr "ein externer Sortiervorgang kann nicht mehr als %d Durchgänge haben" -#: utils/sort/tuplesort.c:4125 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "konnte Unique Index »%s« nicht erstellen" -#: utils/sort/tuplesort.c:4127 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "Schlüssel %s ist doppelt vorhanden." -#: utils/sort/tuplesort.c:4128 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "Es existieren doppelte Schlüssel." -#: utils/sort/tuplestore.c:515 utils/sort/tuplestore.c:525 -#: utils/sort/tuplestore.c:852 utils/sort/tuplestore.c:956 -#: utils/sort/tuplestore.c:1020 utils/sort/tuplestore.c:1037 -#: utils/sort/tuplestore.c:1239 utils/sort/tuplestore.c:1304 -#: utils/sort/tuplestore.c:1313 +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 #, c-format msgid "could not seek in tuplestore temporary file: %m" msgstr "konnte Positionszeiger in temporärer Datei für Tuplestore nicht setzen: %m" -#: utils/sort/tuplestore.c:1460 utils/sort/tuplestore.c:1533 -#: utils/sort/tuplestore.c:1539 +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 +#: utils/sort/tuplestore.c:1556 #, c-format msgid "could not read from tuplestore temporary file: %m" msgstr "konnte nicht aus temporärer Datei für Tuplestore lesen: %m" -#: utils/sort/tuplestore.c:1501 utils/sort/tuplestore.c:1506 -#: utils/sort/tuplestore.c:1512 +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 +#: utils/sort/tuplestore.c:1529 #, c-format msgid "could not write to tuplestore temporary file: %m" msgstr "konnte nicht in temporäre Datei für Tuplestore schreiben: %m" -#: utils/time/snapmgr.c:618 +#: utils/time/snapmgr.c:622 #, c-format msgid "The source transaction is not running anymore." msgstr "Die Quelltransaktion läuft nicht mehr." -#: utils/time/snapmgr.c:1190 +#: utils/time/snapmgr.c:1200 #, c-format msgid "cannot export a snapshot from a subtransaction" msgstr "aus einer Subtransaktion kann kein Snapshot exportiert werden" -#: utils/time/snapmgr.c:1339 utils/time/snapmgr.c:1344 -#: utils/time/snapmgr.c:1349 utils/time/snapmgr.c:1364 -#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1374 -#: utils/time/snapmgr.c:1473 utils/time/snapmgr.c:1489 -#: utils/time/snapmgr.c:1514 +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 +#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 +#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 +#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 +#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 #, c-format msgid "invalid snapshot data in file \"%s\"" msgstr "ungültige Snapshot-Daten in Datei »%s«" -#: utils/time/snapmgr.c:1411 +#: utils/time/snapmgr.c:1456 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "SET TRANSACTION SNAPSHOT muss vor allen Anfragen aufgerufen werden" -#: utils/time/snapmgr.c:1420 +#: utils/time/snapmgr.c:1465 #, c-format msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" msgstr "eine Snapshot-importierende Transaktion muss Isolationsgrad SERIALIZABLE oder REPEATABLE READ haben" -#: utils/time/snapmgr.c:1429 utils/time/snapmgr.c:1438 +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 #, c-format msgid "invalid snapshot identifier: \"%s\"" msgstr "ungültiger Snapshot-Bezeichner: »%s«" -#: utils/time/snapmgr.c:1527 +#: utils/time/snapmgr.c:1573 #, c-format msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" msgstr "eine serialisierbare Transaktion kann keinen Snapshot aus einer nicht-serialisierbaren Transaktion importieren" -#: utils/time/snapmgr.c:1531 +#: utils/time/snapmgr.c:1577 #, c-format msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" msgstr "eine serialisierbare Transaktion, die nicht im Read-Only-Modus ist, kann keinen Snapshot aus einer Read-Only-Transaktion importieren" -#: utils/time/snapmgr.c:1546 +#: utils/time/snapmgr.c:1592 #, c-format msgid "cannot import a snapshot from a different database" msgstr "kann keinen Snapshot aus einer anderen Datenbank importieren" - -#~ msgid "" -#~ "WARNING: Calculated CRC checksum does not match value stored in file.\n" -#~ "Either the file is corrupt, or it has a different layout than this program\n" -#~ "is expecting. The results below are untrustworthy.\n" -#~ "\n" -#~ msgstr "" -#~ "WARNUNG: Berechnete CRC-Prüfsumme stimmt nicht mit dem Wert in der Datei\n" -#~ "überein. Entweder ist die Datei kaputt oder sie hat ein anderes Layout\n" -#~ "als von diesem Programm erwartet. Die Ergebnisse unten sind nicht\n" -#~ "verlässlich.\n" -#~ "\n" - -#~ msgid "Proceeding with relation creation anyway." -#~ msgstr "Relation wird trotzdem erzeugt." - -#~ msgid "default expression must not return a set" -#~ msgstr "Vorgabeausdruck kann keine Ergebnismenge zurückgeben" - -#~ msgid "changing return type of function %s from \"opaque\" to \"language_handler\"" -#~ msgstr "ändere Rückgabetyp von Funktion %s von »opaque« in »language_handler«" - -#~ msgid "changing return type of function %s from \"opaque\" to \"trigger\"" -#~ msgstr "ändere Rückgabetyp von Funktion %s von »opaque« in »trigger«" - -#~ msgid "functions and operators can take at most one set argument" -#~ msgstr "Funktionen und Operatoren können höchstens ein Mengenargument haben" - -#~ msgid "IS DISTINCT FROM does not support set arguments" -#~ msgstr "IS DISTINCT FROM unterstützt keine Mengenargumente" - -#~ msgid "op ANY/ALL (array) does not support set arguments" -#~ msgstr "op ANY/ALL (array) unterstützt keine Mengenargumente" - -#~ msgid "NULLIF does not support set arguments" -#~ msgstr "NULLIF unterstützt keine Mengenargumente" - -#~ msgid "hostssl requires SSL to be turned on" -#~ msgstr "für hostssl muss SSL angeschaltet sein" - -#~ msgid "could not create %s socket: %m" -#~ msgstr "konnte %s-Socket nicht erstellen: %m" - -#~ msgid "could not bind %s socket: %m" -#~ msgstr "konnte %s-Socket nicht binden: %m" - -#~ msgid "could not listen on %s socket: %m" -#~ msgstr "konnte nicht auf %s-Socket hören: %m" - -#~ msgid "WHERE CURRENT OF is not supported on a view with no underlying relation" -#~ msgstr "WHERE CURRENT OF wird nicht unterstützt für Sichten ohne zugrundeliegende Relation" - -#~ msgid "WHERE CURRENT OF is not supported on a view with more than one underlying relation" -#~ msgstr "WHERE CURRENT OF wird nicht unterstützt für Sichten mit mehr als einer zugrundeliegenden Relation" - -#~ msgid "WHERE CURRENT OF is not supported on a view with grouping or aggregation" -#~ msgstr "WHERE CURRENT OF wird nicht unterstützt für Sichten mit Gruppierung oder Aggregierung" - -#~ msgid "DEFAULT can only appear in a VALUES list within INSERT" -#~ msgstr "DEFAULT kann nur in VALUES-Liste innerhalb von INSERT auftreten" - -#~ msgid "argument of %s must be type boolean, not type %s" -#~ msgstr "Argument von %s muss Typ boolean haben, nicht Typ %s" - -#~ msgid "argument declared \"anyrange\" is not consistent with argument declared \"anyelement\"" -#~ msgstr "als »anyrange« deklariertes Argument ist nicht mit als »anyelement« deklariertem Argument konsistent" - -#~ msgid "index expression cannot return a set" -#~ msgstr "Indexausdruck kann keine Ergebnismenge zurückgeben" - -#~ msgid "transform expression must not return a set" -#~ msgstr "Umwandlungsausdruck kann keine Ergebnismenge zurückgeben" - -#~ msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" -#~ msgstr "Autovacuum: verwaiste temporäre Tabelle »%s.%s« in Datenbank »%s« gefunden" - -#~ msgid "invalid socket: %s" -#~ msgstr "ungültiges Socket: %s" - -#~ msgid "rule \"%s\" does not exist" -#~ msgstr "Regel »%s« existiert nicht" - -#~ msgid "there are multiple rules named \"%s\"" -#~ msgstr "es gibt mehrere Regeln namens »%s«" - -#~ msgid "Specify a relation name as well as a rule name." -#~ msgstr "Geben Sie einen Relationsnamen und einen Regelnamen an." - -#~ msgid "not enough shared memory for elements of data structure \"%s\" (%zu bytes requested)" -#~ msgstr "nicht genug Shared-Memory für Elemente der Datenstruktur »%s« (%zu Bytes angefordert)" - -#~ msgid "corrupted item pointer: offset = %u, length = %u" -#~ msgstr "verfälschter Item-Zeiger: offset = %u, length = %u" - -#~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" -#~ msgstr "Formatmuster »TZ«/»tz«/»OF« werden in to_date nicht unterstützt" - -#~ msgid "invalid input syntax for integer: \"%s\"" -#~ msgstr "ungültige Eingabesyntax für ganze Zahl: »%s«" - -#~ msgid "Causes subtables to be included by default in various commands." -#~ msgstr "Schließt abgeleitete Tabellen in diverse Befehle automatisch ein." diff --git a/src/backend/po/es.po b/src/backend/po/es.po index e1efe9ca385..cfb5c9614ff 100644 --- a/src/backend/po/es.po +++ b/src/backend/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for PostgreSQL server # -# Copyright (C) 2002-2012 PostgreSQL Global Development Group +# Copyright (c) 2002-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Karim Mribti 2002. @@ -24,11 +24,14 @@ # to lock bloquear # lock (sustantivo) candado # to obtain a lock bloquear un candado +# malformed mal formado # mapping mapeo # operator class clase de operadores # to overflow desbordar # parser analizador sintáctico # to parse interpretar +# partition bound borde de partición +# partition key llave de particionamiento # permission denied permiso denegado # to poll monitorear # privilege privilegio @@ -56,12 +59,12 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL server 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:09+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: PostgreSQL server 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:09+0000\n" +"PO-Revision-Date: 2019-06-12 14:10-0400\n" "Last-Translator: Ãlvaro Herrera \n" -"Language-Team: PgSQL Español \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -76,93 +79,185 @@ msgstr "" msgid "not recorded" msgstr "no registrado" -#: ../common/controldata_utils.c:57 commands/copy.c:3116 -#: commands/extension.c:3330 utils/adt/genfile.c:135 +#: ../common/controldata_utils.c:68 commands/copy.c:3547 +#: commands/extension.c:3341 utils/adt/genfile.c:153 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "no se pudo abrir archivo «%s» para lectura: %m" -#: ../common/controldata_utils.c:61 -#, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: no se pudo abrir el archivo «%s» para lectura: %s\n" - -#: ../common/controldata_utils.c:71 access/transam/timeline.c:348 -#: access/transam/xlog.c:3384 access/transam/xlog.c:10781 -#: access/transam/xlog.c:10794 access/transam/xlog.c:11186 -#: access/transam/xlog.c:11229 access/transam/xlog.c:11268 -#: access/transam/xlog.c:11311 access/transam/xlogfuncs.c:668 -#: access/transam/xlogfuncs.c:687 commands/extension.c:3340 libpq/hba.c:499 -#: replication/logical/origin.c:661 replication/logical/origin.c:691 -#: replication/logical/reorderbuffer.c:3064 replication/walsender.c:506 -#: storage/file/copydir.c:178 utils/adt/genfile.c:152 utils/adt/misc.c:924 +#: ../common/controldata_utils.c:86 access/transam/timeline.c:347 +#: access/transam/twophase.c:1293 access/transam/xlog.c:3456 +#: access/transam/xlog.c:4603 access/transam/xlog.c:10779 +#: access/transam/xlog.c:10792 access/transam/xlog.c:11217 +#: access/transam/xlog.c:11297 access/transam/xlog.c:11336 +#: access/transam/xlog.c:11379 access/transam/xlogfuncs.c:663 +#: access/transam/xlogfuncs.c:682 commands/extension.c:3351 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3308 +#: replication/logical/snapbuild.c:1746 replication/logical/snapbuild.c:1788 +#: replication/logical/snapbuild.c:1816 replication/logical/snapbuild.c:1843 +#: replication/slot.c:1424 replication/slot.c:1465 replication/walsender.c:513 +#: storage/file/copydir.c:195 utils/adt/genfile.c:170 utils/adt/misc.c:753 +#: utils/cache/relmapper.c:741 #, c-format msgid "could not read file \"%s\": %m" msgstr "no se pudo leer el archivo «%s»: %m" -#: ../common/controldata_utils.c:74 +#: ../common/controldata_utils.c:97 access/transam/twophase.c:1296 +#: access/transam/xlog.c:3461 access/transam/xlog.c:4608 +#: replication/logical/origin.c:722 replication/logical/origin.c:761 +#: replication/logical/snapbuild.c:1751 replication/logical/snapbuild.c:1793 +#: replication/logical/snapbuild.c:1821 replication/logical/snapbuild.c:1848 +#: replication/slot.c:1428 replication/slot.c:1469 replication/walsender.c:518 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:256 +#: access/heap/rewriteheap.c:1208 access/heap/rewriteheap.c:1310 +#: access/transam/timeline.c:377 access/transam/timeline.c:421 +#: access/transam/timeline.c:499 access/transam/twophase.c:1305 +#: access/transam/twophase.c:1728 access/transam/xlog.c:3328 +#: access/transam/xlog.c:3496 access/transam/xlog.c:3501 +#: access/transam/xlog.c:3798 access/transam/xlog.c:4573 +#: access/transam/xlog.c:5522 access/transam/xlogfuncs.c:688 +#: commands/copy.c:1815 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:535 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3366 +#: replication/logical/snapbuild.c:1658 replication/logical/snapbuild.c:1856 +#: replication/slot.c:1322 replication/slot.c:1476 replication/walsender.c:528 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:654 +#: storage/file/fd.c:3308 storage/file/fd.c:3411 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: no se pudo leer el archivo «%s»: %s\n" +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" -#: ../common/controldata_utils.c:95 +#: ../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "discordancia en orden de bytes" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:197 access/heap/rewriteheap.c:1293 +#: access/transam/timeline.c:111 access/transam/timeline.c:236 +#: access/transam/timeline.c:333 access/transam/twophase.c:1249 +#: access/transam/xlog.c:3230 access/transam/xlog.c:3370 +#: access/transam/xlog.c:3411 access/transam/xlog.c:3609 +#: access/transam/xlog.c:3694 access/transam/xlog.c:3772 +#: access/transam/xlog.c:4593 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1489 replication/basebackup.c:517 +#: replication/basebackup.c:1394 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2308 +#: replication/logical/reorderbuffer.c:2575 +#: replication/logical/reorderbuffer.c:3288 +#: replication/logical/snapbuild.c:1613 replication/logical/snapbuild.c:1717 +#: replication/slot.c:1396 replication/walsender.c:486 +#: replication/walsender.c:2450 storage/file/copydir.c:161 +#: storage/file/fd.c:629 storage/file/fd.c:3295 storage/file/fd.c:3382 +#: storage/smgr/md.c:462 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1861 +#: utils/init/miscinit.c:1269 utils/init/miscinit.c:1404 +#: utils/init/miscinit.c:1481 utils/misc/guc.c:8060 utils/misc/guc.c:8092 #, c-format -msgid "" -"WARNING: possible byte ordering mismatch\n" -"The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" -msgstr "" -"ATENCIÓN: posible discordancia en orden de bytes\n" -"El orden de bytes usado para almacenar el archivo pg_control puede no\n" -"coincidir con el que usa este programa. En tal caso, los resultados de abajo\n" -"serán incorrectos, y esta instalación de PostgreSQL será incompatible con\n" -"este directorio de datos.\n" +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../common/controldata_utils.c:221 access/transam/twophase.c:1701 +#: access/transam/twophase.c:1710 access/transam/xlog.c:10536 +#: access/transam/xlog.c:10574 access/transam/xlog.c:10987 +#: access/transam/xlogfuncs.c:742 postmaster/syslogger.c:1500 +#: postmaster/syslogger.c:1513 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" -#: ../common/exec.c:127 ../common/exec.c:241 ../common/exec.c:284 +#: ../common/controldata_utils.c:239 access/heap/rewriteheap.c:981 +#: access/heap/rewriteheap.c:1202 access/heap/rewriteheap.c:1304 +#: access/transam/timeline.c:415 access/transam/timeline.c:493 +#: access/transam/twophase.c:1722 access/transam/xlog.c:3321 +#: access/transam/xlog.c:3490 access/transam/xlog.c:4566 +#: access/transam/xlog.c:10054 access/transam/xlog.c:10080 +#: replication/logical/snapbuild.c:1651 replication/slot.c:1312 +#: replication/slot.c:1406 storage/file/fd.c:646 storage/file/fd.c:3403 +#: storage/smgr/md.c:885 storage/smgr/md.c:918 storage/sync/sync.c:395 +#: utils/cache/relmapper.c:885 utils/misc/guc.c:7840 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" + +#: ../common/exec.c:138 ../common/exec.c:255 ../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" -#: ../common/exec.c:146 +#: ../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../common/exec.c:195 +#: ../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../common/exec.c:202 +#: ../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../common/exec.c:257 ../common/exec.c:293 +#: ../common/exec.c:271 ../common/exec.c:310 utils/init/miscinit.c:220 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar el directorio a «%s»: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" -#: ../common/exec.c:272 +#: ../common/exec.c:288 access/transam/xlog.c:10409 +#: replication/basebackup.c:1232 utils/adt/misc.c:324 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../common/exec.c:523 +#: ../common/exec.c:541 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose falló: %m" + +#: ../common/exec.c:670 ../common/exec.c:715 ../common/exec.c:807 +#: ../common/psprintf.c:143 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1394 access/transam/xlog.c:6346 +#: lib/dshash.c:246 lib/stringinfo.c:283 libpq/auth.c:1093 libpq/auth.c:1483 +#: libpq/auth.c:1551 libpq/auth.c:2069 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2454 +#: postmaster/postmaster.c:2476 postmaster/postmaster.c:4068 +#: postmaster/postmaster.c:4757 postmaster/postmaster.c:4832 +#: postmaster/postmaster.c:5509 postmaster/postmaster.c:5856 +#: replication/libpqwalreceiver/libpqwalreceiver.c:257 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:795 storage/file/fd.c:1191 storage/file/fd.c:1352 +#: storage/file/fd.c:2161 storage/ipc/procarray.c:1047 +#: storage/ipc/procarray.c:1542 storage/ipc/procarray.c:1549 +#: storage/ipc/procarray.c:1973 storage/ipc/procarray.c:2600 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1603 utils/adt/formatting.c:1726 +#: utils/adt/formatting.c:1850 utils/adt/pg_locale.c:473 +#: utils/adt/pg_locale.c:637 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4634 utils/misc/guc.c:4650 utils/misc/guc.c:4663 +#: utils/misc/guc.c:7818 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 +#: utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 +#: utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 +#: utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 +#: utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "out of memory" +msgstr "memoria agotada" #: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 -#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 -#: utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 -#: utils/misc/ps_status.c:217 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:145 ../port/path.c:632 +#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:176 +#: utils/misc/ps_status.c:184 utils/misc/ps_status.c:214 +#: utils/misc/ps_status.c:222 #, c-format msgid "out of memory\n" msgstr "memoria agotada\n" @@ -172,139 +267,32 @@ msgstr "memoria agotada\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "no se puede duplicar un puntero nulo (error interno)\n" -#: ../common/file_utils.c:82 ../common/file_utils.c:186 -#, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: no se pudo hacer stat del archivo «%s»: %s\n" - -#: ../common/file_utils.c:162 -#, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: no se pudo abrir el directorio «%s»: %s\n" - -#: ../common/file_utils.c:198 -#, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: no se pudo leer el directorio «%s»: %s\n" - -#: ../common/file_utils.c:231 ../common/file_utils.c:291 -#: ../common/file_utils.c:367 +#: ../common/logging.c:188 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo «%s»: %s\n" +msgid "fatal: " +msgstr "fatal: " -#: ../common/file_utils.c:304 ../common/file_utils.c:376 +#: ../common/logging.c:195 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: no se pudo sincronizar (fsync) el archivo «%s»: %s\n" +msgid "error: " +msgstr "error: " -#: ../common/file_utils.c:387 +#: ../common/logging.c:202 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: no se pudo cambiar el nombre al archivo «%s» a «%s»: %s\n" +msgid "warning: " +msgstr "precaución: " -#: ../common/pgfnames.c:45 -#, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "no se pudo abrir el directorio «%s»: %s\n" - -#: ../common/pgfnames.c:72 -#, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "no se pudo leer el directorio «%s»: %s\n" - -#: ../common/pgfnames.c:84 -#, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "no se pudo cerrar el directorio «%s»: %s\n" - -#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1306 -#: access/transam/xlog.c:6349 lib/stringinfo.c:258 libpq/auth.c:1108 -#: libpq/auth.c:1474 libpq/auth.c:1542 libpq/auth.c:2058 -#: postmaster/bgworker.c:337 postmaster/bgworker.c:908 -#: postmaster/postmaster.c:2391 postmaster/postmaster.c:2413 -#: postmaster/postmaster.c:3975 postmaster/postmaster.c:4675 -#: postmaster/postmaster.c:4750 postmaster/postmaster.c:5428 -#: postmaster/postmaster.c:5765 -#: replication/libpqwalreceiver/libpqwalreceiver.c:251 -#: replication/logical/logical.c:170 storage/buffer/localbuf.c:436 -#: storage/file/fd.c:773 storage/file/fd.c:1201 storage/file/fd.c:1319 -#: storage/file/fd.c:2044 storage/ipc/procarray.c:1057 -#: storage/ipc/procarray.c:1545 storage/ipc/procarray.c:1552 -#: storage/ipc/procarray.c:1969 storage/ipc/procarray.c:2580 -#: utils/adt/formatting.c:1579 utils/adt/formatting.c:1703 -#: utils/adt/formatting.c:1828 utils/adt/pg_locale.c:468 -#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:219 utils/adt/varlena.c:4585 -#: utils/adt/varlena.c:4606 utils/fmgr/dfmgr.c:221 utils/hash/dynahash.c:429 -#: utils/hash/dynahash.c:535 utils/hash/dynahash.c:1047 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3987 utils/misc/guc.c:4003 -#: utils/misc/guc.c:4016 utils/misc/guc.c:6965 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:404 utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 -#: utils/mmgr/mcxt.c:725 utils/mmgr/mcxt.c:760 utils/mmgr/mcxt.c:797 -#: utils/mmgr/mcxt.c:834 utils/mmgr/mcxt.c:868 utils/mmgr/mcxt.c:897 -#: utils/mmgr/mcxt.c:931 utils/mmgr/mcxt.c:982 utils/mmgr/mcxt.c:1016 -#: utils/mmgr/mcxt.c:1050 -#, c-format -msgid "out of memory" -msgstr "memoria agotada" - -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "nombre de «fork» no válido" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "Los nombres de «fork» válidos son «main», «fsm», «vm» e «init»." -#: ../common/restricted_token.c:68 -#, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" - -#: ../common/restricted_token.c:77 -#, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" - -#: ../common/restricted_token.c:90 -#, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" - -#: ../common/restricted_token.c:110 -#, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" - -#: ../common/restricted_token.c:132 -#, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: no se pudo iniciar el proceso para la orden «%s»: código de error %lu\n" - -#: ../common/restricted_token.c:170 -#, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: no se pudo re-ejecutar con el token restringido: código de error %lu\n" - -#: ../common/restricted_token.c:186 -#, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: no se pudo obtener el código de salida del subproceso»: código de error %lu\n" - -#: ../common/rmtree.c:77 -#, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "no se pudo hacer stat al archivo o directorio «%s»: %s\n" - -#: ../common/rmtree.c:104 ../common/rmtree.c:121 -#, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "no se pudo eliminar el directorio «%s»: %s\n" - -#: ../common/saslprep.c:1090 +#: ../common/saslprep.c:1093 #, c-format msgid "password too long" msgstr "la contraseña es demasiado larga" @@ -314,7 +302,7 @@ msgstr "la contraseña es demasiado larga" msgid "could not look up effective user ID %ld: %s" msgstr "no se pudo encontrar el ID de usuario efectivo %ld: %s" -#: ../common/username.c:45 libpq/auth.c:2005 +#: ../common/username.c:45 libpq/auth.c:2016 msgid "user does not exist" msgstr "usuario no existe" @@ -338,25 +326,20 @@ msgstr "orden no encontrada" msgid "child process exited with exit code %d" msgstr "el proceso hijo terminó con código de salida %d" -#: ../common/wait_error.c:61 +#: ../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "el proceso hijo fue terminado por una excepción 0x%X" -#: ../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "el proceso hijo fue terminado por una señal %s" - -#: ../common/wait_error.c:75 +#: ../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "el proceso hijo fue terminado por una señal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" -#: ../common/wait_error.c:80 +#: ../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" -msgstr "el proceso hijo terminó con código no reconocido %d" +msgstr "el proceso hijo terminó con código %d no reconocido" #: ../port/chklocale.c:288 #, c-format @@ -388,25 +371,25 @@ msgstr "no se pudo obtener junction para «%s»: %s" msgid "could not get junction for \"%s\": %s\n" msgstr "no se pudo obtener junction para «%s»: %s\n" -#: ../port/open.c:111 +#: ../port/open.c:128 #, c-format msgid "could not open file \"%s\": %s" msgstr "no se pudo abrir el archivo «%s»: %s" -#: ../port/open.c:112 +#: ../port/open.c:129 msgid "lock violation" msgstr "infracción de bloqueo (locking violation)" -#: ../port/open.c:112 +#: ../port/open.c:129 msgid "sharing violation" msgstr "infracción de uso compartido (sharing violation)" -#: ../port/open.c:113 +#: ../port/open.c:130 #, c-format msgid "Continuing to retry for 30 seconds." msgstr "Reintentando durante 30 segundos." -#: ../port/open.c:114 +#: ../port/open.c:131 #, c-format msgid "You might have antivirus, backup, or similar software interfering with the database system." msgstr "Es posible que tenga antivirus, sistema de respaldos, o software similar interfiriendo con el sistema de bases de datos." @@ -416,10 +399,10 @@ msgstr "Es posible que tenga antivirus, sistema de respaldos, o software similar msgid "could not get current working directory: %s\n" msgstr "no se pudo obtener el directorio de trabajo actual: %s\n" -#: ../port/strerror.c:25 +#: ../port/strerror.c:72 #, c-format -msgid "unrecognized error %d" -msgstr "código de error no reconocido: %d" +msgid "operating system error %d" +msgstr "error %d de sistema operativo" #: ../port/win32security.c:62 #, c-format @@ -432,29 +415,48 @@ msgid "could not get SID for PowerUsers group: error code %lu\n" msgstr "no se pudo obtener el SID del grupo PowerUsers: código de error %lu\n" #: ../port/win32security.c:80 -#, fuzzy, c-format +#, c-format msgid "could not check access token membership: error code %lu\n" -msgstr "no se pudo abrir el token de proceso: código de error %lu\n" +msgstr "no se pudo verificar el token de proceso: código de error %lu\n" + +#: access/brin/brin.c:204 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "petición para sumarización BRIN de rango para el índice «%s» página %u no fue registrada" + +#: access/brin/brin.c:881 access/brin/brin.c:958 access/gin/ginfast.c:1041 +#: access/transam/xlog.c:10189 access/transam/xlog.c:10718 +#: access/transam/xlogfuncs.c:289 access/transam/xlogfuncs.c:316 +#: access/transam/xlogfuncs.c:355 access/transam/xlogfuncs.c:376 +#: access/transam/xlogfuncs.c:397 access/transam/xlogfuncs.c:467 +#: access/transam/xlogfuncs.c:524 +#, c-format +msgid "recovery is in progress" +msgstr "la recuperación está en proceso" + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Las funciones de control de BRIN no pueden ejecutarse durante la recuperación." -#: access/brin/brin.c:867 access/brin/brin.c:938 +#: access/brin/brin.c:890 access/brin/brin.c:967 #, c-format msgid "block number out of range: %s" msgstr "el número de bloque está fuera de rango: %s" -#: access/brin/brin.c:890 access/brin/brin.c:961 +#: access/brin/brin.c:913 access/brin/brin.c:990 #, c-format msgid "\"%s\" is not a BRIN index" msgstr "«%s» no es un índice BRIN" -#: access/brin/brin.c:906 access/brin/brin.c:977 +#: access/brin/brin.c:929 access/brin/brin.c:1006 #, c-format msgid "could not open parent table of index %s" msgstr "no se pudo abrir la tabla padre del índice %s" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:358 -#: access/brin/brin_pageops.c:824 access/gin/ginentrypage.c:110 -#: access/gist/gist.c:1363 access/nbtree/nbtinsert.c:577 -#: access/nbtree/nbtsort.c:488 access/spgist/spgdoinsert.c:1933 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1445 access/spgist/spgdoinsert.c:1957 #, c-format msgid "index row size %zu exceeds maximum %zu for index \"%s\"" msgstr "el tamaño de fila de índice %zu excede el máximo %zu para el índice «%s»" @@ -462,12 +464,12 @@ msgstr "el tamaño de fila de índice %zu excede el máximo %zu para el índice #: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 #, c-format msgid "corrupted BRIN index: inconsistent range map" -msgstr "" +msgstr "índice BRIN corrompido: mapa de rango inconsistente" #: access/brin/brin_revmap.c:404 #, c-format msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" -msgstr "" +msgstr "se detectó una tupla tentativa abandonada en el índice BRIN «%s», eliminando" #: access/brin/brin_revmap.c:601 #, c-format @@ -475,170 +477,166 @@ msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "tipo de página 0x%04X inesperado en el índice BRIN «%s» bloque %u" #: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 -#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:131 -#: access/nbtree/nbtvalidate.c:101 access/spgist/spgvalidate.c:116 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains function %s with invalid support number %d" +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 +#, c-format msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" -msgstr "familia de operadores gin «%s» contiene la función %s con número de soporte %d no válido" +msgstr "familia de operadores «%s» de método de acceso %s contiene la función %s con número de soporte %d no válido" #: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 -#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:114 -#: access/nbtree/nbtvalidate.c:113 access/spgist/spgvalidate.c:128 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains function %s with wrong signature for support number %d" +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 +#, c-format msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" -msgstr "familia de operadores gin «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +msgstr "familia de operadores «%s» de método de acceso %s contiene la función %s con signatura incorrecta para el número de soporte %d" #: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 -#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:152 -#: access/nbtree/nbtvalidate.c:133 access/spgist/spgvalidate.c:147 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains operator %s with invalid strategy number %d" +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:197 +#, c-format msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" -msgstr "familia de operadores gin «%s» contiene el operador %s con número de estrategia %d no válido" +msgstr "familia de operadores «%s» de método de acceso %s contiene el operador %s con número de estrategia %d no válido" #: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 -#: access/hash/hashvalidate.c:165 access/nbtree/nbtvalidate.c:146 -#: access/spgist/spgvalidate.c:160 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains invalid ORDER BY specification for operator %s" +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:213 +#, c-format msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" -msgstr "familia de operadores gin «%s» contiene especificación ORDER BY no válida para el operador %s" +msgstr "familia de operadores «%s» de método de acceso %s contiene especificación ORDER BY no válida para el operador %s" #: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 -#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:178 -#: access/nbtree/nbtvalidate.c:159 access/spgist/spgvalidate.c:173 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains operator %s with wrong signature" +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:229 +#, c-format msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" -msgstr "familia de operadores gin «%s» contiene el operador %s con signatura incorrecta" +msgstr "familia de operadores «%s» de método de acceso %s contiene el operador %s con signatura incorrecta" -#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:218 -#: access/nbtree/nbtvalidate.c:201 access/spgist/spgvalidate.c:201 -#, fuzzy, c-format -#| msgid "brin operator family \"%s\" is missing operator(s) for types %s and %s" +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:256 +#, c-format msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" -msgstr "el/los operador(es) para los tipos %2$s y %3$s faltan de la familia de operadores brin «%1$s»" +msgstr "el/los operador(es) para los tipos %3$s y %4$s faltan de la familia de operadores «%1$s» de método de acceso %2$s" #: access/brin/brin_validate.c:244 -#, fuzzy, c-format -#| msgid "brin operator family \"%s\" is missing support function(s) for types %s and %s" +#, c-format msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" -msgstr "la(s) función/funciones de soporte para los tipos %2$s y %3$s faltan de la familia de operadores brin «%1$s»" +msgstr "la(s) función/funciones de soporte para los tipos %3$s y %4$s faltan de la familia de operadores «%1$s» de método de acceso %2$s" -#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:232 -#: access/nbtree/nbtvalidate.c:225 access/spgist/spgvalidate.c:234 -#, fuzzy, c-format -#| msgid "brin operator class \"%s\" is missing operator(s)" +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:289 +#, c-format msgid "operator class \"%s\" of access method %s is missing operator(s)" -msgstr "faltan operadores de la clase de operadores brin «%s»" +msgstr "faltan operadores de la clase de operadores «%s» del método de acceso %s" #: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 -#: access/gist/gistvalidate.c:265 -#, fuzzy, c-format -#| msgid "gin operator class \"%s\" is missing support function %d" +#: access/gist/gistvalidate.c:266 +#, c-format msgid "operator class \"%s\" of access method %s is missing support function %d" -msgstr "falta la función de soporte %2$d de la clase de operadores gin «%1$s»" +msgstr "falta la función de soporte %3$d de la clase de operadores «%1$s» del método de acceso %2$s" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1405 +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "el número de columnas (%d) excede el límite (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "el número de columnas del índice (%d) excede el límite (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:647 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:691 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "fila de índice requiere %zu bytes, tamaño máximo es %zu" -#: access/common/printtup.c:290 tcop/fastpath.c:182 tcop/fastpath.c:532 -#: tcop/postgres.c:1726 +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1834 #, c-format msgid "unsupported format code: %d" msgstr "código de formato no soportado: %d" -#: access/common/reloptions.c:540 +#: access/common/reloptions.c:582 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "el límite de tipos de parámetros de relación definidos por el usuario ha sido excedido" -#: access/common/reloptions.c:821 +#: access/common/reloptions.c:863 #, c-format msgid "RESET must not include values for parameters" msgstr "RESET no debe incluir valores de parámetros" -#: access/common/reloptions.c:854 +#: access/common/reloptions.c:895 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "espacio de nombre de parámetro «%s» no reconocido" -#: access/common/reloptions.c:1094 parser/parse_clause.c:270 +#: access/common/reloptions.c:932 utils/misc/guc.c:11746 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "las tablas declaradas WITH OIDS no está soportado" + +#: access/common/reloptions.c:1150 #, c-format msgid "unrecognized parameter \"%s\"" -msgstr "parámetro no reconocido «%s»" +msgstr "parámetro «%s» no reconocido" -#: access/common/reloptions.c:1124 +#: access/common/reloptions.c:1180 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "el parámetro «%s» fue especificado más de una vez" -#: access/common/reloptions.c:1140 +#: access/common/reloptions.c:1196 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "valor no válido para la opción booleana «%s»: «%s»" -#: access/common/reloptions.c:1152 +#: access/common/reloptions.c:1208 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "valor no válido para la opción entera «%s»: «%s»" -#: access/common/reloptions.c:1158 access/common/reloptions.c:1178 +#: access/common/reloptions.c:1214 access/common/reloptions.c:1234 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "el valor %s está fuera del rango de la opción «%s»" -#: access/common/reloptions.c:1160 +#: access/common/reloptions.c:1216 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "Los valores aceptables están entre «%d» y «%d»." -#: access/common/reloptions.c:1172 +#: access/common/reloptions.c:1228 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "valor no válido para la opción de coma flotante «%s»: «%s»" -#: access/common/reloptions.c:1180 +#: access/common/reloptions.c:1236 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "Valores aceptables están entre «%f» y «%f»." -#: access/common/tupconvert.c:108 +#: access/common/tupconvert.c:107 #, c-format msgid "Returned type %s does not match expected type %s in column %d." msgstr "El tipo retornado %s no coincide con el tipo de registro esperado %s en la columna %d." -#: access/common/tupconvert.c:136 +#: access/common/tupconvert.c:135 #, c-format msgid "Number of returned columns (%d) does not match expected column count (%d)." msgstr "La cantidad de columnas retornadas (%d) no coincide con la cantidad esperada de columnas (%d)." -#: access/common/tupconvert.c:318 +#: access/common/tupconvert.c:303 #, c-format msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." msgstr "El atributo «%s» de tipo %s no coincide el atributo correspondiente de tipo %s." -#: access/common/tupconvert.c:330 +#: access/common/tupconvert.c:315 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "El atributo «%s» de tipo %s no existe en el tipo %s." -#: access/common/tupdesc.c:728 parser/parse_clause.c:841 -#: parser/parse_relation.c:1544 +#: access/common/tupdesc.c:842 parser/parse_clause.c:779 +#: parser/parse_relation.c:1578 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "la columna «%s» no puede ser declarada SETOF" @@ -653,90 +651,79 @@ msgstr "la «posting list» es demasiado larga" msgid "Reduce maintenance_work_mem." msgstr "Reduzca maintenance_work_mem." -#: access/gin/ginfast.c:991 access/transam/xlog.c:10202 -#: access/transam/xlog.c:10720 access/transam/xlogfuncs.c:296 -#: access/transam/xlogfuncs.c:323 access/transam/xlogfuncs.c:362 -#: access/transam/xlogfuncs.c:383 access/transam/xlogfuncs.c:404 -#: access/transam/xlogfuncs.c:474 access/transam/xlogfuncs.c:530 -#, c-format -msgid "recovery is in progress" -msgstr "la recuperación está en proceso" - -#: access/gin/ginfast.c:992 +#: access/gin/ginfast.c:1042 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "La lista de pendientes GIN no puede limpiarse durante la recuperación." -#: access/gin/ginfast.c:999 +#: access/gin/ginfast.c:1049 #, c-format msgid "\"%s\" is not a GIN index" msgstr "«%s» no es un índice GIN" -#: access/gin/ginfast.c:1010 +#: access/gin/ginfast.c:1060 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "no se pueden acceder índices temporales de otras sesiones" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "los índices GIN antiguos no soportan recorridos del índice completo ni búsquedas de nulos" -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "Para corregir esto, ejecute REINDEX INDEX \"%s\"." -#: access/gin/ginutil.c:134 executor/execExpr.c:1765 -#: utils/adt/arrayfuncs.c:3803 utils/adt/arrayfuncs.c:6323 -#: utils/adt/rowtypes.c:927 +#: access/gin/ginutil.c:139 executor/execExpr.c:1860 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6416 +#: utils/adt/rowtypes.c:936 #, c-format msgid "could not identify a comparison function for type %s" msgstr "no se pudo identificar una función de comparación para el tipo %s" #: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 -#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:93 -#, fuzzy, c-format -#| msgid "gin operator family \"%s\" contains support procedure %s with cross-type registration" -msgid "operator family \"%s\" of access method %s contains support procedure %s with different left and right input types" -msgstr "la familia de operadores gin «%s» contiene el procedimiento de soporte %s registrado entre tipos distintos" +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "la familia de operadores «%s» del método de acceso %s contiene el procedimiento de soporte %s registrado entre tipos distintos" #: access/gin/ginvalidate.c:257 -#, fuzzy, c-format -#| msgid "gin operator class \"%s\" is missing support function %d or %d" +#, c-format msgid "operator class \"%s\" of access method %s is missing support function %d or %d" -msgstr "falta la función de soporte %2$d o %3$d de la clase de operadores gin «%1$s»" +msgstr "falta la función de soporte %3$d o %4$d de la clase de operadores «%1$s» del método de accesso %2$s" -#: access/gist/gist.c:706 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:751 access/gist/gistvacuum.c:424 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "el índice «%s» contiene una tupla interna marcada como no válida" -#: access/gist/gist.c:708 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:753 access/gist/gistvacuum.c:426 #, c-format msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." msgstr "Esto es causado por una división de página incompleta durante una recuperación antes de actualizar a PostgreSQL 9.1." -#: access/gist/gist.c:709 access/gist/gistutil.c:739 -#: access/gist/gistutil.c:750 access/gist/gistvacuum.c:261 -#: access/hash/hashutil.c:241 access/hash/hashutil.c:252 -#: access/hash/hashutil.c:264 access/hash/hashutil.c:285 -#: access/nbtree/nbtpage.c:519 access/nbtree/nbtpage.c:530 +#: access/gist/gist.c:754 access/gist/gistutil.c:787 access/gist/gistutil.c:798 +#: access/gist/gistvacuum.c:427 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:747 +#: access/nbtree/nbtpage.c:758 #, c-format msgid "Please REINDEX it." msgstr "Por favor aplíquele REINDEX." -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:253 #, c-format msgid "invalid value for \"buffering\" option" msgstr "valor no válido para la opción «buffering»" -#: access/gist/gistbuild.c:251 +#: access/gist/gistbuild.c:254 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "Los valores aceptables son «on», «off» y «auto»." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:231 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "no se pudo escribir el bloque %ld del archivo temporal: %m" @@ -751,37 +738,52 @@ msgstr "el método picksplit para la columna %d del índice «%s» falló" msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." msgstr "El índice no es óptimo. Para optimizarlo, contacte un desarrollador o trate de usar la columna en segunda posición en la orden CREATE INDEX." -#: access/gist/gistutil.c:736 access/hash/hashutil.c:238 -#: access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:784 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:744 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "índice «%s» contiene páginas vacías no esperadas en el bloque %u" -#: access/gist/gistutil.c:747 access/hash/hashutil.c:249 -#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:527 +#: access/gist/gistutil.c:795 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:755 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "el índice «%s» contiene una página corrupta en el bloque %u" #: access/gist/gistvalidate.c:196 -#, fuzzy, c-format -#| msgid "gist operator family \"%s\" contains unsupported ORDER BY specification for operator %s" +#, c-format msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" -msgstr "la familia de operadores gist «%s» contiene una especificación ORDER BY no soportada para el operador %s" +msgstr "la familia de operadores «%s» del método de acceso %s contiene una especificación ORDER BY no soportada para el operador %s" #: access/gist/gistvalidate.c:207 -#, fuzzy, c-format -#| msgid "gist operator family \"%s\" contains incorrect ORDER BY opfamily specification for operator %s" +#, c-format msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" -msgstr "la familia de operadores gist «%s» contiene una especificación de familia en ORDER BY incorrecta para el operador %s" +msgstr "la familia de operadores «%s» del método de acceso %s contiene una especificación de familia en ORDER BY incorrecta para el operador %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:992 utils/adt/varchar.c:1052 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "no se pudo determinar qué ordenamiento usar para el hashing de cadenas" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:678 +#: commands/createas.c:207 commands/createas.c:491 commands/indexcmds.c:1697 +#: commands/tablecmds.c:15095 commands/view.c:105 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1571 utils/adt/formatting.c:1694 +#: utils/adt/formatting.c:1818 utils/adt/like.c:194 +#: utils/adt/like_support.c:965 utils/adt/varchar.c:734 utils/adt/varchar.c:993 +#: utils/adt/varchar.c:1053 utils/adt/varlena.c:1456 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Use la cláusula COLLATE para establecer el ordenamiento explícitamente." #: access/hash/hashinsert.c:82 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "el tamaño de fila de índice %zu excede el máximo para hash %zu" -#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1937 -#: access/spgist/spgutils.c:708 +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:752 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "Valores mayores a una página del buffer no pueden ser indexados." @@ -796,7 +798,7 @@ msgstr "número no válido de bloque de «overflow» %u" msgid "out of overflow pages in hash index \"%s\"" msgstr "se agotaron las páginas de desbordamiento en el índice hash «%s»" -#: access/hash/hashsearch.c:250 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "los índices hash no soportan recorridos del índice completo" @@ -811,154 +813,257 @@ msgstr "el índice «%s» no es un índice hash" msgid "index \"%s\" has wrong hash version" msgstr "el índice «%s» tiene una versión de hash incorrecta" -#: access/hash/hashvalidate.c:190 -#, fuzzy, c-format -#| msgid "hash operator family \"%s\" lacks support function for operator %s" -msgid "operator family \"%s\" of access method %s lacks support function for operator %s" -msgstr "la familia de operadores hash «%s» no tiene función de soporte para el operador %s" - -#: access/hash/hashvalidate.c:248 access/nbtree/nbtvalidate.c:242 -#, fuzzy, c-format -#| msgid "hash operator family \"%s\" is missing cross-type operator(s)" -msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" -msgstr "faltan operadores entre tipos en la familia de operadores hash «%s»" - -#: access/heap/heapam.c:1293 access/heap/heapam.c:1321 -#: access/heap/heapam.c:1353 catalog/aclchk.c:1772 +#: access/hash/hashvalidate.c:191 #, c-format -msgid "\"%s\" is an index" -msgstr "«%s» es un índice" +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "la familia de operadores «%s» del método de acceso %s no tiene función de soporte para el operador %s" -#: access/heap/heapam.c:1298 access/heap/heapam.c:1326 -#: access/heap/heapam.c:1358 catalog/aclchk.c:1779 commands/tablecmds.c:9885 -#: commands/tablecmds.c:13115 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "\"%s\" is a composite type" -msgstr "«%s» es un tipo compuesto" +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "faltan operadores entre tipos en la familia de operadores «%s» del método de acceso %s" -#: access/heap/heapam.c:2592 +#: access/heap/heapam.c:2077 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "no se pueden insertar tuplas durante una operación paralela" +msgid "cannot insert tuples in a parallel worker" +msgstr "no se pueden insertar tuplas en un ayudante paralelo" -#: access/heap/heapam.c:3042 +#: access/heap/heapam.c:2487 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "no se pueden eliminar tuplas durante una operación paralela" -#: access/heap/heapam.c:3088 +#: access/heap/heapam.c:2533 #, c-format msgid "attempted to delete invisible tuple" msgstr "se intentó eliminar una tupla invisible" -#: access/heap/heapam.c:3514 access/heap/heapam.c:6214 +#: access/heap/heapam.c:2954 access/heap/heapam.c:5711 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "no se pueden actualizar tuplas durante una operación paralela" -#: access/heap/heapam.c:3662 +#: access/heap/heapam.c:3087 #, c-format msgid "attempted to update invisible tuple" msgstr "se intentó actualizar una tupla invisible" -#: access/heap/heapam.c:4937 access/heap/heapam.c:4975 -#: access/heap/heapam.c:5227 executor/execMain.c:2579 +#: access/heap/heapam.c:4375 access/heap/heapam.c:4413 +#: access/heap/heapam.c:4670 access/heap/heapam_handler.c:454 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "no se pudo bloquear un candado en la fila de la relación «%s»" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:666 +#: access/heap/heapam_handler.c:405 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "el registro a ser bloqueado ya fue movido a otra partición por un update concurrente" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:681 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "fila es demasiado grande: tamaño %zu, tamaño máximo %zu" -#: access/heap/rewriteheap.c:926 +#: access/heap/rewriteheap.c:941 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "no se pudo escribir al archivo «%s», se escribió %d de %d: %m" -#: access/heap/rewriteheap.c:966 access/heap/rewriteheap.c:1183 -#: access/heap/rewriteheap.c:1282 access/transam/timeline.c:412 -#: access/transam/timeline.c:492 access/transam/xlog.c:3249 -#: access/transam/xlog.c:3417 replication/logical/snapbuild.c:1630 -#: replication/slot.c:1230 replication/slot.c:1317 storage/file/fd.c:631 -#: storage/file/fd.c:3180 storage/smgr/md.c:1044 storage/smgr/md.c:1277 -#: storage/smgr/md.c:1450 utils/misc/guc.c:6987 -#, c-format -msgid "could not fsync file \"%s\": %m" -msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" - -#: access/heap/rewriteheap.c:1021 access/heap/rewriteheap.c:1141 -#: access/transam/timeline.c:315 access/transam/timeline.c:467 -#: access/transam/xlog.c:3202 access/transam/xlog.c:3355 -#: access/transam/xlog.c:10537 access/transam/xlog.c:10575 -#: access/transam/xlog.c:10960 postmaster/postmaster.c:4450 -#: replication/logical/origin.c:535 replication/slot.c:1182 -#: storage/file/copydir.c:162 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 +#: access/heap/rewriteheap.c:1035 access/heap/rewriteheap.c:1154 +#: access/transam/timeline.c:314 access/transam/timeline.c:468 +#: access/transam/xlog.c:3253 access/transam/xlog.c:3425 +#: access/transam/xlog.c:4545 access/transam/xlog.c:10527 +#: access/transam/xlog.c:10565 access/transam/xlog.c:10970 +#: access/transam/xlogfuncs.c:736 postmaster/postmaster.c:4524 +#: replication/logical/origin.c:575 replication/slot.c:1261 +#: storage/file/copydir.c:167 storage/smgr/md.c:204 utils/time/snapmgr.c:1299 #, c-format msgid "could not create file \"%s\": %m" msgstr "no se pudo crear archivo «%s»: %m" -#: access/heap/rewriteheap.c:1151 +#: access/heap/rewriteheap.c:1164 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "no se pudo truncar el archivo «%s» a %u: %m" -#: access/heap/rewriteheap.c:1159 replication/walsender.c:486 -#: storage/smgr/md.c:1949 +#: access/heap/rewriteheap.c:1172 replication/walsender.c:493 +#: storage/smgr/md.c:1245 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "no se pudo posicionar (seek) al fin del archivo «%s»: %m" -#: access/heap/rewriteheap.c:1171 access/transam/timeline.c:370 -#: access/transam/timeline.c:405 access/transam/timeline.c:484 -#: access/transam/xlog.c:3238 access/transam/xlog.c:3408 -#: postmaster/postmaster.c:4460 postmaster/postmaster.c:4470 -#: replication/logical/origin.c:544 replication/logical/origin.c:583 -#: replication/logical/origin.c:599 replication/logical/snapbuild.c:1612 -#: replication/slot.c:1213 storage/file/copydir.c:191 -#: utils/init/miscinit.c:1249 utils/init/miscinit.c:1260 -#: utils/init/miscinit.c:1268 utils/misc/guc.c:6948 utils/misc/guc.c:6979 -#: utils/misc/guc.c:8829 utils/misc/guc.c:8843 utils/time/snapmgr.c:1302 -#: utils/time/snapmgr.c:1309 +#: access/heap/rewriteheap.c:1189 access/transam/timeline.c:369 +#: access/transam/timeline.c:408 access/transam/timeline.c:485 +#: access/transam/xlog.c:3309 access/transam/xlog.c:3481 +#: access/transam/xlog.c:4557 postmaster/postmaster.c:4534 +#: postmaster/postmaster.c:4544 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1627 replication/slot.c:1295 +#: storage/file/copydir.c:207 utils/init/miscinit.c:1345 +#: utils/init/miscinit.c:1356 utils/init/miscinit.c:1364 utils/misc/guc.c:7801 +#: utils/misc/guc.c:7832 utils/misc/guc.c:9760 utils/misc/guc.c:9774 +#: utils/time/snapmgr.c:1304 utils/time/snapmgr.c:1311 #, c-format msgid "could not write to file \"%s\": %m" msgstr "no se pudo escribir a archivo «%s»: %m" -#: access/heap/rewriteheap.c:1257 access/transam/xlogarchive.c:113 -#: access/transam/xlogarchive.c:467 postmaster/postmaster.c:1257 -#: postmaster/syslogger.c:1371 replication/logical/origin.c:522 -#: replication/logical/reorderbuffer.c:2595 -#: replication/logical/reorderbuffer.c:2652 -#: replication/logical/snapbuild.c:1560 replication/logical/snapbuild.c:1936 -#: replication/slot.c:1290 storage/file/fd.c:682 storage/ipc/dsm.c:327 -#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1397 +#: access/heap/rewriteheap.c:1279 access/transam/twophase.c:1661 +#: access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:459 +#: postmaster/postmaster.c:1277 postmaster/syslogger.c:1466 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:2814 +#: replication/logical/snapbuild.c:1569 replication/logical/snapbuild.c:2011 +#: replication/slot.c:1381 storage/file/fd.c:704 storage/file/fd.c:3000 +#: storage/file/fd.c:3062 storage/file/reinit.c:255 storage/ipc/dsm.c:307 +#: storage/smgr/md.c:298 storage/smgr/md.c:354 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1644 #, c-format msgid "could not remove file \"%s\": %m" msgstr "no se pudo eliminar el archivo «%s»: %m" -#: access/heap/rewriteheap.c:1271 access/transam/timeline.c:111 -#: access/transam/timeline.c:236 access/transam/timeline.c:334 -#: access/transam/xlog.c:3178 access/transam/xlog.c:3299 -#: access/transam/xlog.c:3340 access/transam/xlog.c:3619 -#: access/transam/xlog.c:3697 access/transam/xlogutils.c:706 -#: postmaster/syslogger.c:1380 replication/basebackup.c:474 -#: replication/basebackup.c:1218 replication/logical/origin.c:654 -#: replication/logical/reorderbuffer.c:2112 -#: replication/logical/reorderbuffer.c:2361 -#: replication/logical/reorderbuffer.c:3044 -#: replication/logical/snapbuild.c:1604 replication/logical/snapbuild.c:1692 -#: replication/slot.c:1305 replication/walsender.c:479 -#: replication/walsender.c:2385 storage/file/copydir.c:155 -#: storage/file/fd.c:614 storage/file/fd.c:3092 storage/file/fd.c:3159 -#: storage/smgr/md.c:608 utils/error/elog.c:1879 utils/init/miscinit.c:1173 -#: utils/init/miscinit.c:1308 utils/init/miscinit.c:1385 utils/misc/guc.c:7207 -#: utils/misc/guc.c:7240 +#: access/heap/vacuumlazy.c:267 #, c-format -msgid "could not open file \"%s\": %m" -msgstr "no se pudo abrir el archivo «%s»: %m" +msgid "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +msgstr "omitiendo vacuum redundante para prevenir wraparound de la tabla «%s.%s.%s»" + +#: access/heap/vacuumlazy.c:405 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum agresivo automático para prevenir wraparound de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:410 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum agresivo automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:412 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" + +#: access/heap/vacuumlazy.c:419 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "páginas: %u eliminadas, %u quedan, %u saltadas debido a «pins», %u congeladas saltadas\n" + +#: access/heap/vacuumlazy.c:425 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "tuplas: %.0f removidas, %.0f permanecen ,%.0f están muertas pero aún no se pueden quitar, el xmin más antiguo: %u\n" + +#: access/heap/vacuumlazy.c:431 +#, c-format +msgid "buffer usage: %d hits, %d misses, %d dirtied\n" +msgstr "uso de búfers: %d aciertos, %d fallas, %d ensuciados\n" + +#: access/heap/vacuumlazy.c:435 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "tasa lectura promedio: %.3f MB/s, tasa escritura promedio: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:437 +#, c-format +msgid "system usage: %s" +msgstr "uso de sistema: %s" + +#: access/heap/vacuumlazy.c:533 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "haciendo vacuum agresivamente a «%s.%s»" + +#: access/heap/vacuumlazy.c:538 commands/cluster.c:910 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "haciendo vacuum a «%s.%s»" + +#: access/heap/vacuumlazy.c:1476 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "«%s»: se eliminaron %.0f versiones de filas en %u páginas" + +#: access/heap/vacuumlazy.c:1486 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f versiones muertas de filas no pueden ser eliminadas aún, xmin máx antiguo: %u\n" + +#: access/heap/vacuumlazy.c:1488 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "Hubo %.0f identificadores de ítem sin usar.\n" + +#: access/heap/vacuumlazy.c:1490 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Omitiendo %u página debido a «pins» de página, " +msgstr[1] "Omitiendo %u páginas debido a «pins» de página, " + +#: access/heap/vacuumlazy.c:1494 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u página marcadas «frozen».\n" +msgstr[1] "%u páginas marcadas «frozen».\n" + +#: access/heap/vacuumlazy.c:1498 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u página está completamente vacía.\n" +msgstr[1] "%u páginas están completamente vacías.\n" + +#: access/heap/vacuumlazy.c:1502 commands/indexcmds.c:3291 +#: commands/indexcmds.c:3309 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1505 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "«%s»: se encontraron %.0f versiones de filas eliminables y %.0f no eliminables en %u de %u páginas" + +#: access/heap/vacuumlazy.c:1574 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "«%s»: se eliminaron %d versiones de filas en %d páginas" + +#: access/heap/vacuumlazy.c:1765 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "se recorrió el índice «%s» para eliminar %d versiones de filas" + +#: access/heap/vacuumlazy.c:1818 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "el índice «%s» ahora contiene %.0f versiones de filas en %u páginas" + +#: access/heap/vacuumlazy.c:1822 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f versiones de filas del índice fueron eliminadas.\n" +"%u páginas de índice han sido eliminadas, %u son reusables.\n" +"%s." + +#: access/heap/vacuumlazy.c:1920 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" -#: access/index/amapi.c:83 commands/amcmds.c:163 +#: access/heap/vacuumlazy.c:1985 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "«%s»: truncadas %u a %u páginas" + +#: access/heap/vacuumlazy.c:2050 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" + +#: access/index/amapi.c:83 commands/amcmds.c:167 #, c-format msgid "access method \"%s\" is not of type %s" msgstr "el método de acceso «%s» no es de tipo %s" @@ -968,102 +1073,152 @@ msgstr "el método de acceso «%s» no es de tipo %s" msgid "index access method \"%s\" does not have a handler" msgstr "el método de acceso «%s» no tiene manejador" -#: access/index/indexam.c:160 catalog/objectaddress.c:1222 -#: commands/indexcmds.c:1819 commands/tablecmds.c:247 -#: commands/tablecmds.c:13106 +#: access/index/indexam.c:136 catalog/objectaddress.c:1259 +#: commands/indexcmds.c:2407 commands/tablecmds.c:248 commands/tablecmds.c:272 +#: commands/tablecmds.c:14802 commands/tablecmds.c:16134 #, c-format msgid "\"%s\" is not an index" msgstr "«%s» no es un índice" -#: access/nbtree/nbtinsert.c:429 +#: access/nbtree/nbtinsert.c:565 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "llave duplicada viola restricción de unicidad «%s»" -#: access/nbtree/nbtinsert.c:431 +#: access/nbtree/nbtinsert.c:567 #, c-format msgid "Key %s already exists." msgstr "Ya existe la llave %s." -#: access/nbtree/nbtinsert.c:498 +#: access/nbtree/nbtinsert.c:638 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "no se pudo volver a encontrar la tupla dentro del índice «%s»" -#: access/nbtree/nbtinsert.c:500 +#: access/nbtree/nbtinsert.c:640 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "Esto puede deberse a una expresión de índice no inmutable." -#: access/nbtree/nbtinsert.c:580 access/nbtree/nbtsort.c:491 -#, c-format -msgid "" -"Values larger than 1/3 of a buffer page cannot be indexed.\n" -"Consider a function index of an MD5 hash of the value, or use full text indexing." -msgstr "" -"Valores mayores a 1/3 de la página del buffer no pueden ser indexados.\n" -"Considere un índice sobre una función que genere un hash MD5 del valor, o utilice un esquema de indexación de texto completo." - -#: access/nbtree/nbtpage.c:169 access/nbtree/nbtpage.c:372 -#: access/nbtree/nbtpage.c:459 parser/parse_utilcmd.c:1899 +#: access/nbtree/nbtpage.c:171 access/nbtree/nbtpage.c:359 +#: access/nbtree/nbtpage.c:572 parser/parse_utilcmd.c:2117 #, c-format msgid "index \"%s\" is not a btree" msgstr "el índice «%s» no es un btree" -#: access/nbtree/nbtpage.c:175 access/nbtree/nbtpage.c:378 -#: access/nbtree/nbtpage.c:465 +#: access/nbtree/nbtpage.c:178 access/nbtree/nbtpage.c:366 +#: access/nbtree/nbtpage.c:579 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "discordancia de versión en índice «%s»: versión de archivo %d, versión de código %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "discordancia de versión en índice «%s»: versión de archivo %d, versión de código %d, mínima versión soportada %d" -#: access/nbtree/nbtpage.c:1153 +#: access/nbtree/nbtpage.c:1388 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "el índice «%s» contiene una página interna parcialmente muerta" -#: access/nbtree/nbtpage.c:1155 +#: access/nbtree/nbtpage.c:1390 #, c-format msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." msgstr "Esto puede ser causado por la interrupción de un VACUUM en la versión 9.3 o anteriores, antes de actualizar. Ejecute REINDEX por favor." -#: access/nbtree/nbtvalidate.c:211 -#, fuzzy, c-format -#| msgid "btree operator family \"%s\" is missing support function for types %s and %s" +#: access/nbtree/nbtutils.c:2563 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "el tamaño de fila de índice %1$zu excede el máximo %3$zu para btree versión %2$u para el índice «%4$s»" + +#: access/nbtree/nbtutils.c:2569 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "La tupla de índice hace referencia a la tupla (%u,%u) en la relación «%s»." + +#: access/nbtree/nbtutils.c:2573 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Valores mayores a 1/3 de la página del buffer no pueden ser indexados.\n" +"Considere un índice sobre una función que genere un hash MD5 del valor, o utilice un esquema de indexación de texto completo." + +#: access/nbtree/nbtvalidate.c:236 +#, c-format msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" -msgstr "faltan funciones de soporte para los tipos %2$s y %3$s en la familia de operadores btree «%1$s»" +msgstr "falta una función de soporte para los tipos %3$s y %4$s en la familia de operadores «%1$s» del método de acceso %2$s" + +#: access/spgist/spgutils.c:142 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "método «compress» debe estar definido cuando el tipo hoja es distinto del tipo de entrada" -#: access/spgist/spgutils.c:705 +#: access/spgist/spgutils.c:749 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "el tamaño de tupla interna SP-GiST %zu excede el máximo %zu" -#: access/spgist/spgvalidate.c:221 -#, fuzzy, c-format -#| msgid "spgist operator family \"%s\" is missing support function %d for type %s" +#: access/spgist/spgvalidate.c:276 +#, c-format msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" -msgstr "falta la función de soporte %2$d para el tipo %3$s de la clase de operadores spgist «%1$s»" +msgstr "falta la función de soporte %3$d para el tipo %4$s de la clase de operadores «%1$s» del método de accesso %2$s" -#: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1832 #, c-format -msgid "sample percentage must be between 0 and 100" -msgstr "el porcentaje de muestreo debe estar entre 0 y 100" +msgid "\"%s\" is an index" +msgstr "«%s» es un índice" -#: access/transam/commit_ts.c:295 +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1839 commands/tablecmds.c:11613 commands/tablecmds.c:14811 #, c-format -msgid "cannot retrieve commit timestamp for transaction %u" -msgstr "no se puede obtener el timestamp de compromiso de la transacción %u" +msgid "\"%s\" is a composite type" +msgstr "«%s» es un tipo compuesto" -#: access/transam/commit_ts.c:393 +#: access/table/tableam.c:236 #, c-format -msgid "could not get commit timestamp data" -msgstr "no se pudo obtener datos de compromiso de transacción" +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "el tid (%u, %u) no es válido para la relación «%s»" -#: access/transam/commit_ts.c:395 +#: access/table/tableamapi.c:109 #, c-format -msgid "Make sure the configuration parameter \"%s\" is set on the master server." -msgstr "Asegúrese que el parámetro de configuración «%s» esté definido en el servidor maestro." +msgid "%s cannot be empty." +msgstr "%s no puede ser vacío." -#: access/transam/commit_ts.c:397 +#: access/table/tableamapi.c:116 utils/misc/guc.c:11648 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s es demasiado largo (máximo %d caracteres)." + +#: access/table/tableamapi.c:138 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "no existe el método de acceso de tabla «%s»" + +#: access/table/tableamapi.c:143 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "No existe el método de acceso de tabla «%s»." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "el porcentaje de muestreo debe estar entre 0 y 100" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "no se puede obtener el timestamp de compromiso de la transacción %u" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "no se pudo obtener datos de compromiso de transacción" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "Asegúrese que el parámetro de configuración «%s» esté definido en el servidor maestro." + +#: access/transam/commit_ts.c:397 #, c-format msgid "Make sure the configuration parameter \"%s\" is set." msgstr "Asegúrese que el parámetro de configuración «%s» esté definido." @@ -1078,10 +1233,10 @@ msgstr "la base de datos no está aceptando órdenes que generen nuevos MultiXac #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"Ejecute VACUUM en esa base de datos.\n" -"Puede que además necesite comprometer o abortar transacciones preparadas antiguas." +"Ejecute VACUUM de la base completa en esa base de datos.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." #: access/transam/multixact.c:1007 #, c-format @@ -1111,8 +1266,8 @@ msgstr "límite de miembros de multixact alcanzado" #, c-format msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Esta orden crearía un multixact con %u miembros, pero el espacio que queda sólo sirve para %u miembro." +msgstr[1] "Esta orden crearía un multixact con %u miembros, pero el espacio que queda sólo sirve para %u miembros." #: access/transam/multixact.c:1104 #, c-format @@ -1147,15 +1302,15 @@ msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "el límite para el reciclaje de MultiXactId es %u, limitado por base de datos con OID %u" #: access/transam/multixact.c:2323 access/transam/multixact.c:2332 -#: access/transam/varsup.c:146 access/transam/varsup.c:153 -#: access/transam/varsup.c:405 access/transam/varsup.c:412 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 #, c-format msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Para evitar que la base de datos se desactive, ejecute VACUUM en esa base de datos.\n" -"Puede que además necesite comprometer o abortar transacciones preparadas antiguas." +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." #: access/transam/multixact.c:2602 #, c-format @@ -1180,90 +1335,100 @@ msgstr "el límite de detención de miembros de multixact es ahora %u basado en #: access/transam/multixact.c:3011 #, c-format msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" -msgstr "multixact más antiguo %u no encontrado, multixact más antiguo es %u, saltando el truncado" +msgstr "multixact más antiguo %u no encontrado, multixact más antiguo es %u, omitiendo el truncado" #: access/transam/multixact.c:3029 #, c-format msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" msgstr "no se puede truncar hasta el MultiXact %u porque no existe en disco, omitiendo el truncado" -#: access/transam/multixact.c:3355 +#: access/transam/multixact.c:3343 #, c-format msgid "invalid MultiXactId: %u" msgstr "el MultiXactId no es válido: %u" -#: access/transam/parallel.c:577 +#: access/transam/parallel.c:673 access/transam/parallel.c:792 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "el ayudante paralelo no pudo iniciar" + +#: access/transam/parallel.c:674 access/transam/parallel.c:793 +#, c-format +msgid "More details may be available in the server log." +msgstr "Puede haber más detalles disponibles en el log del servidor." + +#: access/transam/parallel.c:854 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "postmaster terminó durante una transacción paralela" -#: access/transam/parallel.c:764 +#: access/transam/parallel.c:1041 #, c-format msgid "lost connection to parallel worker" -msgstr "se ha perdido la conexión al proceso trabajador paralelo" +msgstr "se ha perdido la conexión al ayudante paralelo" -#: access/transam/parallel.c:823 access/transam/parallel.c:825 +#: access/transam/parallel.c:1107 access/transam/parallel.c:1109 msgid "parallel worker" -msgstr "proceso trabajador paralelo" +msgstr "ayudante paralelo" -#: access/transam/parallel.c:968 +#: access/transam/parallel.c:1259 #, c-format msgid "could not map dynamic shared memory segment" msgstr "no se pudo mapear el segmento de memoria compartida dinámica" -#: access/transam/parallel.c:973 +#: access/transam/parallel.c:1264 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "número mágico no válido en segmento de memoria compartida dinámica" -#: access/transam/slru.c:664 +#: access/transam/slru.c:674 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "el archivo «%s» no existe, leyendo como ceros" -#: access/transam/slru.c:903 access/transam/slru.c:909 -#: access/transam/slru.c:916 access/transam/slru.c:923 -#: access/transam/slru.c:930 access/transam/slru.c:937 +#: access/transam/slru.c:912 access/transam/slru.c:918 +#: access/transam/slru.c:925 access/transam/slru.c:932 +#: access/transam/slru.c:939 access/transam/slru.c:946 #, c-format msgid "could not access status of transaction %u" msgstr "no se pudo encontrar el estado de la transacción %u" -#: access/transam/slru.c:904 +#: access/transam/slru.c:913 #, c-format msgid "Could not open file \"%s\": %m." msgstr "No se pudo abrir el archivo «%s»: %m." -#: access/transam/slru.c:910 +#: access/transam/slru.c:919 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "No se pudo posicionar (seek) en el archivo «%s» a la posición %u: %m." -#: access/transam/slru.c:917 +#: access/transam/slru.c:926 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "No se pudo leer desde el archivo «%s» en la posición %u: %m." -#: access/transam/slru.c:924 +#: access/transam/slru.c:933 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "No se pudo escribir al archivo «%s» en la posición %u: %m." -#: access/transam/slru.c:931 +#: access/transam/slru.c:940 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "No se pudo sincronizar (fsync) archivo «%s»: %m." -#: access/transam/slru.c:938 +#: access/transam/slru.c:947 #, c-format msgid "Could not close file \"%s\": %m." msgstr "No se pudo cerrar el archivo «%s»: %m." -#: access/transam/slru.c:1195 +#: access/transam/slru.c:1204 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "no se pudo truncar el directorio «%s»: aparente problema por reciclaje de transacciones" -#: access/transam/slru.c:1250 access/transam/slru.c:1306 +#: access/transam/slru.c:1259 access/transam/slru.c:1315 #, c-format msgid "removing file \"%s\"" msgstr "eliminando el archivo «%s»" @@ -1279,7 +1444,7 @@ msgid "Expected a numeric timeline ID." msgstr "Se esperaba un ID numérico de timeline." #: access/transam/timeline.c:154 -#, fuzzy, c-format +#, c-format msgid "Expected a write-ahead log switchpoint location." msgstr "Se esperaba una ubicación de punto de cambio del registro de transacciones." @@ -1303,45 +1468,37 @@ msgstr "datos no válidos en archivo de historia «%s»" msgid "Timeline IDs must be less than child timeline's ID." msgstr "IDs de timeline deben ser menores que el ID de timeline del hijo." -#: access/transam/timeline.c:418 access/transam/timeline.c:498 -#: access/transam/xlog.c:3256 access/transam/xlog.c:3423 -#: access/transam/xlogfuncs.c:693 commands/copy.c:1775 -#: storage/file/copydir.c:206 -#, c-format -msgid "could not close file \"%s\": %m" -msgstr "no se pudo cerrar el archivo «%s»: %m" - #: access/transam/timeline.c:580 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "el timeline %u solicitado no está en la historia de este servidor" -#: access/transam/twophase.c:383 +#: access/transam/twophase.c:382 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "identificador de transacción «%s» es demasiado largo" -#: access/transam/twophase.c:390 +#: access/transam/twophase.c:389 #, c-format msgid "prepared transactions are disabled" msgstr "las transacciones preparadas están deshabilitadas" -#: access/transam/twophase.c:391 +#: access/transam/twophase.c:390 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "Defina max_prepared_transactions a un valor distinto de cero." -#: access/transam/twophase.c:410 +#: access/transam/twophase.c:409 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "identificador de transacción «%s» ya está siendo utilizado" -#: access/transam/twophase.c:419 access/transam/twophase.c:2340 +#: access/transam/twophase.c:418 access/transam/twophase.c:2420 #, c-format msgid "maximum number of prepared transactions reached" msgstr "se alcanzó el número máximo de transacciones preparadas" -#: access/transam/twophase.c:420 access/transam/twophase.c:2341 +#: access/transam/twophase.c:419 access/transam/twophase.c:2421 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "Incremente max_prepared_transactions (actualmente es %d)." @@ -1354,7 +1511,7 @@ msgstr "transacción preparada con identificador «%s» está ocupada" #: access/transam/twophase.c:593 #, c-format msgid "permission denied to finish prepared transaction" -msgstr "permiso denegado para finalizar la transacción preparada" +msgstr "se ha denegado el permiso para finalizar la transacción preparada" #: access/transam/twophase.c:594 #, c-format @@ -1376,758 +1533,674 @@ msgstr "Conéctese a la base de datos donde la transacción fue preparada para t msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "transacción preparada con identificador «%s» no existe" -#: access/transam/twophase.c:1086 +#: access/transam/twophase.c:1115 #, c-format msgid "two-phase state file maximum length exceeded" -msgstr "el largo máximo del archivo de estado de COMMIT en dos fases fue excedido" - -#: access/transam/twophase.c:1204 +msgstr "el largo máximo del archivo de estado de dos fases fue excedido" + +#: access/transam/twophase.c:1261 access/transam/xlog.c:10512 +#: access/transam/xlog.c:10550 access/transam/xlog.c:10767 +#: access/transam/xlogarchive.c:104 access/transam/xlogarchive.c:264 +#: commands/copy.c:1945 commands/copy.c:3557 commands/extension.c:3330 +#: commands/tablespace.c:787 commands/tablespace.c:878 +#: replication/basebackup.c:343 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1527 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1703 +#: storage/file/fd.c:2980 storage/file/fd.c:3162 storage/file/fd.c:3247 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:133 utils/adt/genfile.c:386 guc-file.l:1004 #, c-format -msgid "could not open two-phase state file \"%s\": %m" -msgstr "no se pudo abrir el archivo de estado de COMMIT en dos fases «%s»: %m" +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" -#: access/transam/twophase.c:1221 +#: access/transam/twophase.c:1269 #, c-format -msgid "could not stat two-phase state file \"%s\": %m" -msgstr "no se pudo hacer stat al archivo de estado de COMMIT en dos fases «%s»: %m" +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "tamaño incorrecto de archivo «%s»: %zu byte" +msgstr[1] "tamaño incorrecto de archivo «%s»: %zu bytes" -#: access/transam/twophase.c:1255 +#: access/transam/twophase.c:1278 #, c-format -msgid "could not read two-phase state file \"%s\": %m" -msgstr "no se pudo leer el archivo de estado de COMMIT en dos fases «%s»: %m" - -#: access/transam/twophase.c:1307 access/transam/xlog.c:6350 -#, fuzzy, c-format -msgid "Failed while allocating a WAL reading processor." -msgstr "Falló mientras se emplazaba un procesador de lectura de XLog." +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "alineamiento incorrecto del offset del CRC para el archivo «%s»" -#: access/transam/twophase.c:1313 -#, fuzzy, c-format -msgid "could not read two-phase state from WAL at %X/%X" -msgstr "no se pudo leer el archivo de estado de COMMIT en dos fases desde xlog en %X/%X" +#: access/transam/twophase.c:1311 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "número mágico no válido almacenado en archivo «%s»" -#: access/transam/twophase.c:1321 +#: access/transam/twophase.c:1317 #, c-format -msgid "expected two-phase state data is not present in WAL at %X/%X" -msgstr "" +msgid "invalid size stored in file \"%s\"" +msgstr "tamaño no válido en archivo «%s»" -#: access/transam/twophase.c:1558 +#: access/transam/twophase.c:1329 #, c-format -msgid "could not remove two-phase state file \"%s\": %m" -msgstr "no se pudo eliminar el archivo de estado de COMMIT en dos fases «%s»: %m" +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "la suma de verificación calculada no coincide con el valor almacenado en el archivo «%s»" -#: access/transam/twophase.c:1588 +#: access/transam/twophase.c:1395 access/transam/xlog.c:6347 #, c-format -msgid "could not recreate two-phase state file \"%s\": %m" -msgstr "no se pudo recrear el archivo de estado de COMMIT en dos fases «%s»: %m" +msgid "Failed while allocating a WAL reading processor." +msgstr "Falló mientras se emplazaba un procesador de lectura de WAL." -#: access/transam/twophase.c:1599 access/transam/twophase.c:1607 +#: access/transam/twophase.c:1401 #, c-format -msgid "could not write two-phase state file: %m" -msgstr "no se pudo escribir el archivo de estado de COMMIT en dos fases: %m" +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "no se pudo leer el archivo de estado de dos fases desde WAL en %X/%X" -#: access/transam/twophase.c:1621 +#: access/transam/twophase.c:1409 #, c-format -msgid "could not fsync two-phase state file: %m" -msgstr "no se pudo sincronizar (fsync) el archivo de estado de COMMIT en dos fases: %m" +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "los datos de estado de dos fases esperados no están presentes en WAL en %X/%X" -#: access/transam/twophase.c:1628 +#: access/transam/twophase.c:1689 #, c-format -msgid "could not close two-phase state file: %m" -msgstr "no se pudo cerrar el archivo de estado de COMMIT en dos fases: %m" +msgid "could not recreate file \"%s\": %m" +msgstr "no se pudo recrear archivo «%s»: %m" -#: access/transam/twophase.c:1716 +#: access/transam/twophase.c:1816 #, c-format msgid "%u two-phase state file was written for a long-running prepared transaction" msgid_plural "%u two-phase state files were written for long-running prepared transactions" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%u archivo de estado de dos fases fue escrito para transacción de larga duración" +msgstr[1] "%u archivos de estado de dos fases fueron escritos para transacciones de larga duración" -#: access/transam/twophase.c:1944 -#, fuzzy, c-format +#: access/transam/twophase.c:2050 +#, c-format msgid "recovering prepared transaction %u from shared memory" -msgstr "recuperando transacción preparada %u" +msgstr "recuperando transacción preparada %u desde memoria compartida" -#: access/transam/twophase.c:2034 -#, fuzzy, c-format -msgid "removing stale two-phase state file for \"%u\"" -msgstr "eliminando archivo obsoleto de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2141 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "eliminando archivo obsoleto de estado de dos fases para transacción %u" -#: access/transam/twophase.c:2041 -#, fuzzy, c-format -msgid "removing stale two-phase state from shared memory for \"%u\"" -msgstr "eliminando archivo obsoleto de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2148 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "eliminando de memoria estado de dos fases obsoleto para transacción %u" -#: access/transam/twophase.c:2054 -#, fuzzy, c-format -msgid "removing future two-phase state file for \"%u\"" -msgstr "eliminando archivo futuro de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2161 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "eliminando archivo futuro de estado de dos fases para transacción %u" -#: access/transam/twophase.c:2061 -#, fuzzy, c-format -msgid "removing future two-phase state from memory for \"%u\"" -msgstr "eliminando archivo futuro de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2168 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "eliminando estado de dos fases futuro de memoria para transacción %u" -#: access/transam/twophase.c:2075 access/transam/twophase.c:2094 -#, fuzzy, c-format -msgid "removing corrupt two-phase state file for \"%u\"" -msgstr "eliminando archivo dañado de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2193 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "archivo de estado de dos fases corrupto para transacción %u" -#: access/transam/twophase.c:2101 -#, fuzzy, c-format -msgid "removing corrupt two-phase state from memory for \"%u\"" -msgstr "eliminando archivo dañado de estado de COMMIT en dos fases «%s»" +#: access/transam/twophase.c:2198 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "estado de dos fases en memoria corrupto para transacción %u" -#: access/transam/varsup.c:124 +#: access/transam/varsup.c:127 #, c-format msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" msgstr "la base de datos no está aceptando órdenes para evitar pérdida de datos debido al problema del reciclaje de transacciones en la base de datos «%s»" -#: access/transam/varsup.c:126 access/transam/varsup.c:133 +#: access/transam/varsup.c:129 access/transam/varsup.c:136 #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"Detenga el proceso postmaster y utilice una conexión aislada (standalone) para limpiar (vacuum) esa base de datos.\n" -"Puede que además necesite comprometer o abortar transacciones preparadas antiguas." +"Detenga el postmaster y ejecute VACUUM de la base completa en esa base de datos.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." -#: access/transam/varsup.c:131 +#: access/transam/varsup.c:134 #, c-format msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" msgstr "la base de datos no está aceptando órdenes para evitar pérdida de datos debido al problema del reciclaje de transacciones en la base con OID %u" -#: access/transam/varsup.c:143 access/transam/varsup.c:402 +#: access/transam/varsup.c:146 access/transam/varsup.c:444 #, c-format msgid "database \"%s\" must be vacuumed within %u transactions" msgstr "base de datos «%s» debe ser limpiada dentro de %u transacciones" -#: access/transam/varsup.c:150 access/transam/varsup.c:409 +#: access/transam/varsup.c:153 access/transam/varsup.c:451 #, c-format msgid "database with OID %u must be vacuumed within %u transactions" msgstr "base de datos con OID %u debe ser limpiada dentro de %u transacciones" -#: access/transam/varsup.c:367 +#: access/transam/varsup.c:409 #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "el límite para el reciclaje de ID de transacciones es %u, limitado por base de datos con OID %u" -#: access/transam/xact.c:946 +#: access/transam/xact.c:1027 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "no se pueden tener más de 2^32-2 órdenes en una transacción" -#: access/transam/xact.c:1471 +#: access/transam/xact.c:1552 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "se superó el número máximo de subtransacciones comprometidas (%d)" -#: access/transam/xact.c:2268 +#: access/transam/xact.c:2377 #, c-format -msgid "cannot PREPARE a transaction that has operated on temporary tables" -msgstr "no se puede hacer PREPARE de una transacción que ha operado en tablas temporales" +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "no se puede hacer PREPARE de una transacción que ha operado en objetos temporales" -#: access/transam/xact.c:2278 +#: access/transam/xact.c:2387 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "no se puede hacer PREPARE de una transacción que ha exportado snapshots" +#: access/transam/xact.c:2396 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "no se puede hacer PREPARE de una transacción que ha manipulado procesos ayudantes de replicación lógica" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3164 +#: access/transam/xact.c:3337 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s no puede ser ejecutado dentro de un bloque de transacción" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3174 +#: access/transam/xact.c:3347 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s no puede ser ejecutado dentro de una subtransacción" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3184 +#: access/transam/xact.c:3357 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "la orden %s no puede ser ejecutada desde una función o una línea con múltiples órdenes" +msgid "%s cannot be executed from a function" +msgstr "%s no puede ser ejecutado desde una función" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3255 +#: access/transam/xact.c:3426 access/transam/xact.c:4062 +#: access/transam/xact.c:4131 access/transam/xact.c:4242 #, c-format msgid "%s can only be used in transaction blocks" msgstr "la orden %s sólo puede ser usada en bloques de transacción" -#: access/transam/xact.c:3439 +#: access/transam/xact.c:3619 #, c-format msgid "there is already a transaction in progress" msgstr "ya hay una transacción en curso" -#: access/transam/xact.c:3607 access/transam/xact.c:3710 +#: access/transam/xact.c:3730 access/transam/xact.c:3800 +#: access/transam/xact.c:3916 #, c-format msgid "there is no transaction in progress" msgstr "no hay una transacción en curso" -#: access/transam/xact.c:3618 +#: access/transam/xact.c:3811 #, c-format msgid "cannot commit during a parallel operation" msgstr "no se puede comprometer una transacción durante una operación paralela" -#: access/transam/xact.c:3721 +#: access/transam/xact.c:3927 #, c-format msgid "cannot abort during a parallel operation" msgstr "no se puede abortar durante una operación paralela" -#: access/transam/xact.c:3763 +#: access/transam/xact.c:4026 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "no se pueden definir savepoints durante una operación paralela" -#: access/transam/xact.c:3830 +#: access/transam/xact.c:4113 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "no se pueden liberar savepoints durante una operación paralela" -#: access/transam/xact.c:3841 access/transam/xact.c:3893 -#: access/transam/xact.c:3899 access/transam/xact.c:3955 -#: access/transam/xact.c:4005 access/transam/xact.c:4011 +#: access/transam/xact.c:4123 access/transam/xact.c:4174 +#: access/transam/xact.c:4234 access/transam/xact.c:4283 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "no existe el «savepoint» «%s»" + +#: access/transam/xact.c:4180 access/transam/xact.c:4289 #, c-format -msgid "no such savepoint" -msgstr "no hay un savepoint con ese nombre" +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "el «savepoint» «%s» no existe dentro del nivel de savepoint actual" -#: access/transam/xact.c:3943 +#: access/transam/xact.c:4222 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "no se puede hacer rollback a un savepoint durante una operación paralela" -#: access/transam/xact.c:4071 +#: access/transam/xact.c:4350 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "no se pueden iniciar subtransacciones durante una operación paralela" -#: access/transam/xact.c:4138 +#: access/transam/xact.c:4418 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "no se pueden comprometer subtransacciones durante una operación paralela" -#: access/transam/xact.c:4746 +#: access/transam/xact.c:5056 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "no se pueden tener más de 2^32-1 subtransacciones en una transacción" -#: access/transam/xlog.c:2455 -#, c-format -msgid "could not seek in log file %s to offset %u: %m" -msgstr "no se pudo posicionar (seek) en el archivo «%s» a la posición %u: %m" - -#: access/transam/xlog.c:2477 +#: access/transam/xlog.c:2507 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "no se pudo escribir archivo de registro %s en la posición %u, largo %zu: %m" -#: access/transam/xlog.c:2741 +#: access/transam/xlog.c:2783 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "el punto mínimo de recuperación fue actualizado a %X/%X en el timeline %u" -#: access/transam/xlog.c:3388 -#, c-format -msgid "not enough data in file \"%s\"" -msgstr "los datos del archivo «%s» son insuficientes" - -#: access/transam/xlog.c:3534 -#, fuzzy, c-format -msgid "could not open write-ahead log file \"%s\": %m" -msgstr "no se pudo abrir el archivo de registro «%s»: %m" - -#: access/transam/xlog.c:3723 access/transam/xlog.c:5535 -#, c-format -msgid "could not close log file %s: %m" -msgstr "no se pudo cerrar el archivo de registro %s: %m" - -#: access/transam/xlog.c:3780 access/transam/xlogutils.c:701 -#: replication/walsender.c:2380 +#: access/transam/xlog.c:3864 access/transam/xlogutils.c:703 +#: replication/walsender.c:2445 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "el segmento de WAL solicitado %s ya ha sido eliminado" -#: access/transam/xlog.c:3840 access/transam/xlog.c:3915 -#: access/transam/xlog.c:4110 -#, fuzzy, c-format -msgid "could not open write-ahead log directory \"%s\": %m" -msgstr "no se pudo abrir directorio de registro de transacciones «%s»: %m" - -#: access/transam/xlog.c:3996 -#, fuzzy, c-format +#: access/transam/xlog.c:4106 +#, c-format msgid "recycled write-ahead log file \"%s\"" -msgstr "el archivo de registro de transacciones «%s» ha sido reciclado" +msgstr "reciclado archivo de WAL «%s»" -#: access/transam/xlog.c:4008 -#, fuzzy, c-format +#: access/transam/xlog.c:4118 +#, c-format msgid "removing write-ahead log file \"%s\"" -msgstr "eliminando archivo de registro de transacciones «%s»" +msgstr "eliminando archivo de WAL «%s»" -#: access/transam/xlog.c:4028 -#, fuzzy, c-format -msgid "could not rename old write-ahead log file \"%s\": %m" -msgstr "no se pudo cambiar el nombre del archivo antiguo de registro de transacciones «%s»: %m" +#: access/transam/xlog.c:4138 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "no se pudo renombrar el archivo «%s»: %m" -#: access/transam/xlog.c:4070 access/transam/xlog.c:4080 +#: access/transam/xlog.c:4180 access/transam/xlog.c:4190 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "no existe el directorio WAL «%s»" -#: access/transam/xlog.c:4086 +#: access/transam/xlog.c:4196 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "creando el directorio WAL faltante «%s»" -#: access/transam/xlog.c:4089 +#: access/transam/xlog.c:4199 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "no se pudo crear el directorio faltante «%s»: %m" -#: access/transam/xlog.c:4200 +#: access/transam/xlog.c:4304 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "ID de timeline %u inesperado en archivo %s, posición %u" -#: access/transam/xlog.c:4322 +#: access/transam/xlog.c:4432 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "el nuevo timeline %u especificado no es hijo del timeline de sistema %u" -#: access/transam/xlog.c:4336 +#: access/transam/xlog.c:4446 #, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgstr "el nuevo timeline %u bifurcó del timeline del sistema actual %u antes del punto re recuperación actual %X/%X" -#: access/transam/xlog.c:4355 +#: access/transam/xlog.c:4465 #, c-format msgid "new target timeline is %u" msgstr "el nuevo timeline destino es %u" -#: access/transam/xlog.c:4430 -#, c-format -msgid "could not create control file \"%s\": %m" -msgstr "no se pudo crear archivo de control «%s»: %m" - -#: access/transam/xlog.c:4442 access/transam/xlog.c:4668 -#, c-format -msgid "could not write to control file: %m" -msgstr "no se pudo escribir en el archivo de control: %m" - -#: access/transam/xlog.c:4450 access/transam/xlog.c:4676 -#, c-format -msgid "could not fsync control file: %m" -msgstr "no se pudo sincronizar (fsync) el archivo de control: %m" - -#: access/transam/xlog.c:4456 access/transam/xlog.c:4682 -#, c-format -msgid "could not close control file: %m" -msgstr "no se pudo cerrar el archivo de control: %m" - -#: access/transam/xlog.c:4474 access/transam/xlog.c:4656 -#, c-format -msgid "could not open control file \"%s\": %m" -msgstr "no se pudo abrir el archivo de control «%s»: %m" - -#: access/transam/xlog.c:4481 -#, c-format -msgid "could not read from control file: %m" -msgstr "no se pudo leer desde el archivo de control: %m" - -#: access/transam/xlog.c:4495 access/transam/xlog.c:4504 -#: access/transam/xlog.c:4528 access/transam/xlog.c:4535 -#: access/transam/xlog.c:4542 access/transam/xlog.c:4547 -#: access/transam/xlog.c:4554 access/transam/xlog.c:4561 -#: access/transam/xlog.c:4568 access/transam/xlog.c:4575 -#: access/transam/xlog.c:4582 access/transam/xlog.c:4589 -#: access/transam/xlog.c:4596 access/transam/xlog.c:4605 -#: access/transam/xlog.c:4612 access/transam/xlog.c:4621 -#: access/transam/xlog.c:4628 utils/init/miscinit.c:1406 +#: access/transam/xlog.c:4624 access/transam/xlog.c:4633 +#: access/transam/xlog.c:4657 access/transam/xlog.c:4664 +#: access/transam/xlog.c:4671 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4683 access/transam/xlog.c:4690 +#: access/transam/xlog.c:4697 access/transam/xlog.c:4704 +#: access/transam/xlog.c:4711 access/transam/xlog.c:4718 +#: access/transam/xlog.c:4727 access/transam/xlog.c:4734 +#: access/transam/xlog.c:4743 access/transam/xlog.c:4750 +#: utils/init/miscinit.c:1502 #, c-format msgid "database files are incompatible with server" msgstr "los archivos de base de datos son incompatibles con el servidor" -#: access/transam/xlog.c:4496 +#: access/transam/xlog.c:4625 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "Los archivos de base de datos fueron inicializados con PG_CONTROL_VERSION %d (0x%08x), pero el servidor fue compilado con PG_CONTROL_VERSION %d (0x%08x)." -#: access/transam/xlog.c:4500 +#: access/transam/xlog.c:4629 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "Este puede ser un problema de discordancia en el orden de bytes. Parece que necesitará ejecutar initdb." -#: access/transam/xlog.c:4505 +#: access/transam/xlog.c:4634 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "Los archivos de base de datos fueron inicializados con PG_CONTROL_VERSION %d, pero el servidor fue compilado con PG_CONTROL_VERSION %d." -#: access/transam/xlog.c:4508 access/transam/xlog.c:4532 -#: access/transam/xlog.c:4539 access/transam/xlog.c:4544 +#: access/transam/xlog.c:4637 access/transam/xlog.c:4661 +#: access/transam/xlog.c:4668 access/transam/xlog.c:4673 #, c-format msgid "It looks like you need to initdb." msgstr "Parece que necesita ejecutar initdb." -#: access/transam/xlog.c:4519 +#: access/transam/xlog.c:4648 #, c-format msgid "incorrect checksum in control file" msgstr "la suma de verificación es incorrecta en el archivo de control" -#: access/transam/xlog.c:4529 +#: access/transam/xlog.c:4658 #, c-format msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." msgstr "Los archivos de base de datos fueron inicializados con CATALOG_VERSION_NO %d, pero el servidor fue compilado con CATALOG_VERSION_NO %d." -#: access/transam/xlog.c:4536 +#: access/transam/xlog.c:4665 #, c-format msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." msgstr "Los archivos de la base de datos fueron inicializados con MAXALIGN %d, pero el servidor fue compilado con MAXALIGN %d." -#: access/transam/xlog.c:4543 +#: access/transam/xlog.c:4672 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "Los archivos de la base de datos parecen usar un formato de número de coma flotante distinto al del ejecutable del servidor." -#: access/transam/xlog.c:4548 +#: access/transam/xlog.c:4677 #, c-format msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "Los archivos de base de datos fueron inicializados con BLCKSZ %d, pero el servidor fue compilado con BLCKSZ %d." -#: access/transam/xlog.c:4551 access/transam/xlog.c:4558 -#: access/transam/xlog.c:4565 access/transam/xlog.c:4572 -#: access/transam/xlog.c:4579 access/transam/xlog.c:4586 -#: access/transam/xlog.c:4593 access/transam/xlog.c:4600 -#: access/transam/xlog.c:4608 access/transam/xlog.c:4615 -#: access/transam/xlog.c:4624 access/transam/xlog.c:4631 +#: access/transam/xlog.c:4680 access/transam/xlog.c:4687 +#: access/transam/xlog.c:4694 access/transam/xlog.c:4701 +#: access/transam/xlog.c:4708 access/transam/xlog.c:4715 +#: access/transam/xlog.c:4722 access/transam/xlog.c:4730 +#: access/transam/xlog.c:4737 access/transam/xlog.c:4746 +#: access/transam/xlog.c:4753 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "Parece que necesita recompilar o ejecutar initdb." -#: access/transam/xlog.c:4555 +#: access/transam/xlog.c:4684 #, c-format msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." msgstr "Los archivos de la base de datos fueron inicializados con RELSEG_SIZE %d, pero el servidor fue compilado con RELSEG_SIZE %d." -#: access/transam/xlog.c:4562 +#: access/transam/xlog.c:4691 #, c-format msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." msgstr "Los archivos de base de datos fueron inicializados con XLOG_BLCKSZ %d, pero el servidor fue compilado con XLOG_BLCKSZ %d." -#: access/transam/xlog.c:4569 -#, c-format -msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." -msgstr "Los archivos de la base de datos fueron inicializados con XLOG_SEG_SIZE %d, pero el servidor fue compilado con XLOG_SEG_SIZE %d." - -#: access/transam/xlog.c:4576 +#: access/transam/xlog.c:4698 #, c-format msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." msgstr "Los archivos de la base de datos fueron inicializados con NAMEDATALEN %d, pero el servidor fue compilado con NAMEDATALEN %d." -#: access/transam/xlog.c:4583 +#: access/transam/xlog.c:4705 #, c-format msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." msgstr "Los archivos de la base de datos fueron inicializados con INDEX_MAX_KEYS %d, pero el servidor fue compilado con INDEX_MAX_KEYS %d." -#: access/transam/xlog.c:4590 +#: access/transam/xlog.c:4712 #, c-format msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." msgstr "Los archivos de la base de datos fueron inicializados con TOAST_MAX_CHUNK_SIZE %d, pero el servidor fue compilado con TOAST_MAX_CHUNK_SIZE %d." -#: access/transam/xlog.c:4597 +#: access/transam/xlog.c:4719 #, c-format msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." msgstr "Los archivos de base de datos fueron inicializados con LOBLKSIZE %d, pero el servidor fue compilado con LOBLKSIZE %d." -#: access/transam/xlog.c:4606 +#: access/transam/xlog.c:4728 #, c-format msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." msgstr "Los archivos de base de datos fueron inicializados sin USE_FLOAT4_BYVAL, pero el servidor fue compilado con USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4613 +#: access/transam/xlog.c:4735 #, c-format msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." msgstr "Los archivos de base de datos fueron inicializados con USE_FLOAT4_BYVAL, pero el servidor fue compilado sin USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4622 +#: access/transam/xlog.c:4744 #, c-format msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." msgstr "Los archivos de base de datos fueron inicializados sin USE_FLOAT8_BYVAL, pero el servidor fue compilado con USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4629 +#: access/transam/xlog.c:4751 #, c-format msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." msgstr "Los archivos de base de datos fueron inicializados con USE_FLOAT8_BYVAL, pero el servidor fue compilado sin USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4985 -#, fuzzy, c-format -msgid "could not generate secret authorization token" -msgstr "no se pudo generar un vector aleatorio de encriptación" - -#: access/transam/xlog.c:5075 -#, fuzzy, c-format -msgid "could not write bootstrap write-ahead log file: %m" -msgstr "no se pudo escribir al archivo de registro de transacciones de inicio (bootstrap): %m" - -#: access/transam/xlog.c:5083 -#, fuzzy, c-format -msgid "could not fsync bootstrap write-ahead log file: %m" -msgstr "no se pudo sincronizar (fsync) el archivo de registro de transacciones de inicio (bootstrap): %m" - -#: access/transam/xlog.c:5089 -#, fuzzy, c-format -msgid "could not close bootstrap write-ahead log file: %m" -msgstr "no se pudo cerrar el archivo de registro de transacciones de inicio (bootstrap): %m" - -#: access/transam/xlog.c:5165 -#, c-format -msgid "could not open recovery command file \"%s\": %m" -msgstr "no se pudo abrir el archivo de recuperación «%s»: %m" - -#: access/transam/xlog.c:5211 access/transam/xlog.c:5313 +#: access/transam/xlog.c:4760 #, c-format -msgid "invalid value for recovery parameter \"%s\": \"%s\"" -msgstr "valor no válido para el parámetro de recuperación «%s»: «%s»" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d byte" +msgstr[1] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d bytes" -#: access/transam/xlog.c:5214 +#: access/transam/xlog.c:4772 #, c-format -msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." -msgstr "Los valores aceptables son «pause», «promote» y «shutdown»." +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "«min_wal_size» debe ser al menos el doble de «wal_segment_size»" -#: access/transam/xlog.c:5234 +#: access/transam/xlog.c:4776 #, c-format -msgid "recovery_target_timeline is not a valid number: \"%s\"" -msgstr "recovery_target_timeline no es un número válido: «%s»" +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "«max_wal_size» debe ser al menos el doble de «wal_segment_size»" -#: access/transam/xlog.c:5251 +#: access/transam/xlog.c:5128 #, c-format -msgid "recovery_target_xid is not a valid number: \"%s\"" -msgstr "recovery_target_xid no es un número válido: «%s»" +msgid "could not generate secret authorization token" +msgstr "no se pudo generar un token de autorización secreto" -#: access/transam/xlog.c:5282 +#: access/transam/xlog.c:5218 #, c-format -msgid "recovery_target_name is too long (maximum %d characters)" -msgstr "recovery_target_name es demasiado largo (máximo %d caracteres)" +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "no se pudo escribir el archivo WAL de boostrap: %m" -#: access/transam/xlog.c:5316 +#: access/transam/xlog.c:5226 #, c-format -msgid "The only allowed value is \"immediate\"." -msgstr "El único valor permitido es «immediate»" +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "no se pudo sincronizar (fsync) el archivo de WAL de bootstrap: %m" -#: access/transam/xlog.c:5329 access/transam/xlog.c:5340 -#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5739 +#: access/transam/xlog.c:5232 #, c-format -msgid "parameter \"%s\" requires a Boolean value" -msgstr "el parámetro «%s» requiere un valor lógico (booleano)" +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "no se pudo cerrar el archivo WAL de bootstrap: %m" -#: access/transam/xlog.c:5375 +#: access/transam/xlog.c:5311 #, c-format -msgid "parameter \"%s\" requires a temporal value" -msgstr "el parámetro «%s» requiere un valor de tiempo" +msgid "using recovery command file \"%s\" is not supported" +msgstr "el uso del archivo de configuración de recuperación «%s» no está soportado" -#: access/transam/xlog.c:5377 catalog/dependency.c:961 -#: catalog/dependency.c:962 catalog/dependency.c:968 catalog/dependency.c:969 -#: catalog/dependency.c:980 catalog/dependency.c:981 commands/tablecmds.c:946 -#: commands/tablecmds.c:10345 commands/user.c:1029 commands/view.c:505 -#: libpq/auth.c:328 replication/syncrep.c:1150 storage/lmgr/deadlock.c:1139 -#: storage/lmgr/proc.c:1313 utils/adt/acl.c:5248 utils/misc/guc.c:5761 -#: utils/misc/guc.c:5854 utils/misc/guc.c:9810 utils/misc/guc.c:9844 -#: utils/misc/guc.c:9878 utils/misc/guc.c:9912 utils/misc/guc.c:9947 +#: access/transam/xlog.c:5376 #, c-format -msgid "%s" -msgstr "%s" +msgid "standby mode is not supported by single-user servers" +msgstr "el modo standby no está soportado en el modo mono-usuario" -#: access/transam/xlog.c:5384 +#: access/transam/xlog.c:5393 #, c-format -msgid "unrecognized recovery parameter \"%s\"" -msgstr "parámetro de recuperación no reconocido: «%s»" +msgid "specified neither primary_conninfo nor restore_command" +msgstr "no se especifica primary_conninfo ni restore_command" -#: access/transam/xlog.c:5395 +#: access/transam/xlog.c:5394 #, c-format -msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" -msgstr "el archivo de recuperación «%s» no especifica primary_conninfo ni restore_command" - -#: access/transam/xlog.c:5397 -#, fuzzy, c-format msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." -msgstr "El servidor de bases de datos monitoreará el subdirectorio pg_xlog con regularidad en búsqueda de archivos almacenados ahí." - -#: access/transam/xlog.c:5404 -#, c-format -msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" -msgstr "el archivo de recuperación «%s» debe especificar restore_command cuando el modo standby no está activo" +msgstr "El servidor de bases de datos monitoreará el subdirectorio pg_wal con regularidad en búsqueda de archivos almacenados ahí." -#: access/transam/xlog.c:5425 +#: access/transam/xlog.c:5402 #, c-format -msgid "standby mode is not supported by single-user servers" -msgstr "el modo standby no está soportado en el modo mono-usuario" +msgid "must specify restore_command when standby mode is not enabled" +msgstr "debe especificarse restore_command cuando el modo standby no está activo" -#: access/transam/xlog.c:5444 +#: access/transam/xlog.c:5428 #, c-format msgid "recovery target timeline %u does not exist" msgstr "no existe el timeline %u especificado como destino de recuperación" -#: access/transam/xlog.c:5565 +#: access/transam/xlog.c:5555 #, c-format msgid "archive recovery complete" msgstr "recuperación completa" -#: access/transam/xlog.c:5624 access/transam/xlog.c:5890 +#: access/transam/xlog.c:5614 access/transam/xlog.c:5880 #, c-format msgid "recovery stopping after reaching consistency" msgstr "deteniendo recuperación al alcanzar un estado consistente" -#: access/transam/xlog.c:5645 -#, fuzzy, c-format +#: access/transam/xlog.c:5635 +#, c-format msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" -msgstr "deteniendo recuperación antes de abortar la transacción %u, hora %s" +msgstr "deteniendo recuperación antes de la ubicación (LSN) de WAL «%X/%X»" -#: access/transam/xlog.c:5731 +#: access/transam/xlog.c:5721 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "deteniendo recuperación antes de comprometer la transacción %u, hora %s" -#: access/transam/xlog.c:5738 +#: access/transam/xlog.c:5728 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "deteniendo recuperación antes de abortar la transacción %u, hora %s" -#: access/transam/xlog.c:5784 +#: access/transam/xlog.c:5774 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "deteniendo recuperación en el punto de recuperación «%s», hora %s" -#: access/transam/xlog.c:5802 -#, fuzzy, c-format +#: access/transam/xlog.c:5792 +#, c-format msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" -msgstr "deteniendo recuperación después de abortar la transacción %u, hora %s" +msgstr "deteniendo recuperación después de la ubicación (LSN) de WAL «%X/%X»" -#: access/transam/xlog.c:5870 +#: access/transam/xlog.c:5860 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "deteniendo recuperación de comprometer la transacción %u, hora %s" -#: access/transam/xlog.c:5878 +#: access/transam/xlog.c:5868 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "deteniendo recuperación después de abortar la transacción %u, hora %s" -#: access/transam/xlog.c:5918 +#: access/transam/xlog.c:5908 #, c-format msgid "recovery has paused" msgstr "la recuperación está en pausa" -#: access/transam/xlog.c:5919 -#, fuzzy, c-format +#: access/transam/xlog.c:5909 +#, c-format msgid "Execute pg_wal_replay_resume() to continue." -msgstr "Ejecute pg_xlog_replay_resume() para continuar." +msgstr "Ejecute pg_wal_replay_resume() para continuar." -#: access/transam/xlog.c:6127 +#: access/transam/xlog.c:6117 #, c-format msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" msgstr "hot standby no es posible puesto que %s = %d es una configuración menor que en el servidor maestro (su valor era %d)" -#: access/transam/xlog.c:6153 +#: access/transam/xlog.c:6143 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "WAL fue generado con wal_level=minimal, puede haber datos faltantes" -#: access/transam/xlog.c:6154 +#: access/transam/xlog.c:6144 #, c-format msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." msgstr "Esto sucede si temporalmente define wal_level=minimal sin tomar un nuevo respaldo base." -#: access/transam/xlog.c:6165 +#: access/transam/xlog.c:6155 #, c-format msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" msgstr "hot standby no es posible porque wal_level no estaba configurado como «replica» o superior en el servidor maestro" -#: access/transam/xlog.c:6166 +#: access/transam/xlog.c:6156 #, c-format msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." msgstr "Defina wal_level a «replica» en el maestro, o bien desactive hot_standby en este servidor." -#: access/transam/xlog.c:6223 +#: access/transam/xlog.c:6220 #, c-format msgid "control file contains invalid data" msgstr "el archivo de control contiene datos no válidos" -#: access/transam/xlog.c:6229 +#: access/transam/xlog.c:6226 #, c-format msgid "database system was shut down at %s" msgstr "el sistema de bases de datos fue apagado en %s" -#: access/transam/xlog.c:6234 +#: access/transam/xlog.c:6231 #, c-format msgid "database system was shut down in recovery at %s" msgstr "el sistema de bases de datos fue apagado durante la recuperación en %s" -#: access/transam/xlog.c:6238 +#: access/transam/xlog.c:6235 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "el apagado del sistema de datos fue interrumpido; última vez registrada en funcionamiento en %s" -#: access/transam/xlog.c:6242 +#: access/transam/xlog.c:6239 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "el sistema de bases de datos fue interrumpido durante la recuperación en %s" -#: access/transam/xlog.c:6244 +#: access/transam/xlog.c:6241 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "Esto probablemente significa que algunos datos están corruptos y tendrá que usar el respaldo más reciente para la recuperación." -#: access/transam/xlog.c:6248 +#: access/transam/xlog.c:6245 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "el sistema de bases de datos fue interrumpido durante la recuperación en el instante de registro %s" -#: access/transam/xlog.c:6250 +#: access/transam/xlog.c:6247 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." msgstr "Si esto ha ocurrido más de una vez, algunos datos podrían estar corruptos y podría ser necesario escoger un punto de recuperación anterior." -#: access/transam/xlog.c:6254 +#: access/transam/xlog.c:6251 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "el sistema de bases de datos fue interrumpido; última vez en funcionamiento en %s" -#: access/transam/xlog.c:6310 +#: access/transam/xlog.c:6307 #, c-format msgid "entering standby mode" msgstr "entrando al modo standby" -#: access/transam/xlog.c:6313 +#: access/transam/xlog.c:6310 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "comenzando el proceso de recuperación hasta el XID %u" -#: access/transam/xlog.c:6317 +#: access/transam/xlog.c:6314 #, c-format msgid "starting point-in-time recovery to %s" msgstr "comenzando el proceso de recuperación hasta %s" -#: access/transam/xlog.c:6321 +#: access/transam/xlog.c:6318 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "comenzando el proceso de recuperación hasta «%s»" -#: access/transam/xlog.c:6325 -#, fuzzy, c-format +#: access/transam/xlog.c:6322 +#, c-format msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" -msgstr "comenzando el proceso de recuperación hasta «%s»" +msgstr "comenzando el proceso de recuperación punto-en-el-tiempo a la ubicación (LSN) de WAL «%X/%X»" -#: access/transam/xlog.c:6330 +#: access/transam/xlog.c:6327 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "comenzando recuperación a un punto en el tiempo hasta alcanzar un estado consistente" -#: access/transam/xlog.c:6333 +#: access/transam/xlog.c:6330 #, c-format msgid "starting archive recovery" msgstr "comenzando proceso de recuperación" -#: access/transam/xlog.c:6384 access/transam/xlog.c:6512 +#: access/transam/xlog.c:6384 access/transam/xlog.c:6516 #, c-format msgid "checkpoint record is at %X/%X" msgstr "el registro del punto de control está en %X/%X" @@ -2135,198 +2208,185 @@ msgstr "el registro del punto de control está en %X/%X" #: access/transam/xlog.c:6398 #, c-format msgid "could not find redo location referenced by checkpoint record" -msgstr "no se pudo localizar la ubicación de redo referida por el registro de checkpoint" +msgstr "no se pudo encontrar la ubicación de redo referida por el registro de checkpoint" -#: access/transam/xlog.c:6399 access/transam/xlog.c:6406 +# Purposefully deviate from quoting convention here, since argument is a shell command. +#: access/transam/xlog.c:6399 access/transam/xlog.c:6409 #, c-format -msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." -msgstr "Si no está restaurando un respaldo, intente eliminando «%s/backup_label»." +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Si está restaurando de un respaldo, ejecute «touch \"%s.recovery.signal\"» y agregue las opciones de restauración necesarias.\n" +"Si no está restaurando de un respaldo, intente eliminar el archivo \"%s/backup_label\".\n" +"Tenga cuidado: eliminar \"%s/backup_label\" resultará en un clúster corrupto si está restaurando de un respaldo." -#: access/transam/xlog.c:6405 +#: access/transam/xlog.c:6408 #, c-format msgid "could not locate required checkpoint record" msgstr "no se pudo localizar el registro del punto de control requerido" -#: access/transam/xlog.c:6431 commands/tablespace.c:639 +#: access/transam/xlog.c:6437 commands/tablespace.c:646 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "no se pudo crear el enlace simbólico «%s»: %m" -#: access/transam/xlog.c:6463 access/transam/xlog.c:6469 +#: access/transam/xlog.c:6469 access/transam/xlog.c:6475 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "ignorando el archivo «%s» porque no existe un archivo «%s»" -#: access/transam/xlog.c:6465 access/transam/xlog.c:11390 +#: access/transam/xlog.c:6471 access/transam/xlog.c:11458 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "El archivo «%s» fue renombrado a «%s»." -#: access/transam/xlog.c:6471 +#: access/transam/xlog.c:6477 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "No se pudo renombrar el archivo de «%s» a «%s»: %m." -#: access/transam/xlog.c:6522 access/transam/xlog.c:6537 +#: access/transam/xlog.c:6528 #, c-format msgid "could not locate a valid checkpoint record" msgstr "no se pudo localizar un registro de punto de control válido" -#: access/transam/xlog.c:6531 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "usando el registro del punto de control anterior en %X/%X" - -#: access/transam/xlog.c:6575 +#: access/transam/xlog.c:6566 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "el timeline solicitado %u no es un hijo de la historia de este servidor" -#: access/transam/xlog.c:6577 +#: access/transam/xlog.c:6568 #, c-format msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." msgstr "El punto de control más reciente está en %X/%X en el timeline %u, pero en la historia del timeline solicitado, el servidor se desvió desde ese timeline en %X/%X." -#: access/transam/xlog.c:6593 +#: access/transam/xlog.c:6584 #, c-format msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" msgstr "el timeline solicitado %u no contiene el punto mínimo de recuperación %X/%X en el timeline %u" -#: access/transam/xlog.c:6624 +#: access/transam/xlog.c:6615 #, c-format msgid "invalid next transaction ID" msgstr "el siguiente ID de transacción no es válido" -#: access/transam/xlog.c:6718 +#: access/transam/xlog.c:6709 #, c-format msgid "invalid redo in checkpoint record" msgstr "redo no es válido en el registro de punto de control" -#: access/transam/xlog.c:6729 +#: access/transam/xlog.c:6720 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "registro redo no es válido en el punto de control de apagado" -#: access/transam/xlog.c:6757 +#: access/transam/xlog.c:6748 #, c-format msgid "database system was not properly shut down; automatic recovery in progress" msgstr "el sistema de bases de datos no fue apagado apropiadamente; se está efectuando la recuperación automática" -#: access/transam/xlog.c:6761 +#: access/transam/xlog.c:6752 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" msgstr "la recuperación comienza en el timeline %u y tiene un timeline de destino %u" -#: access/transam/xlog.c:6805 +#: access/transam/xlog.c:6795 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label contiene datos inconsistentes con el archivo de control" -#: access/transam/xlog.c:6806 +#: access/transam/xlog.c:6796 #, c-format msgid "This means that the backup is corrupted and you will have to use another backup for recovery." msgstr "Esto significa que el respaldo está corrupto y deberá usar otro respaldo para la recuperación." -#: access/transam/xlog.c:6880 +#: access/transam/xlog.c:6887 #, c-format msgid "initializing for hot standby" msgstr "inicializando para hot standby" -#: access/transam/xlog.c:7012 +#: access/transam/xlog.c:7019 #, c-format msgid "redo starts at %X/%X" msgstr "redo comienza en %X/%X" -#: access/transam/xlog.c:7246 +#: access/transam/xlog.c:7243 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "el punto de detención de recuperación pedido es antes del punto de recuperación consistente" -#: access/transam/xlog.c:7284 +#: access/transam/xlog.c:7281 #, c-format msgid "redo done at %X/%X" msgstr "redo listo en %X/%X" -#: access/transam/xlog.c:7289 access/transam/xlog.c:9303 +#: access/transam/xlog.c:7286 #, c-format msgid "last completed transaction was at log time %s" msgstr "última transacción completada al tiempo de registro %s" -#: access/transam/xlog.c:7298 +#: access/transam/xlog.c:7295 #, c-format msgid "redo is not required" msgstr "no se requiere redo" -#: access/transam/xlog.c:7373 access/transam/xlog.c:7377 +#: access/transam/xlog.c:7370 access/transam/xlog.c:7374 #, c-format msgid "WAL ends before end of online backup" msgstr "WAL termina antes del fin del respaldo en línea" -#: access/transam/xlog.c:7374 +#: access/transam/xlog.c:7371 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "Todo el WAL generado durante el respaldo en línea debe estar disponible durante la recuperación." -#: access/transam/xlog.c:7378 +#: access/transam/xlog.c:7375 #, c-format msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." msgstr "Un respaldo en línea iniciado con pg_start_backup() debe ser terminado con pg_stop_backup(), y todos los archivos WAL hasta ese punto deben estar disponibles durante la recuperación." -#: access/transam/xlog.c:7381 +#: access/transam/xlog.c:7378 #, c-format msgid "WAL ends before consistent recovery point" msgstr "WAL termina antes del punto de recuperación consistente" -#: access/transam/xlog.c:7408 +#: access/transam/xlog.c:7412 #, c-format msgid "selected new timeline ID: %u" msgstr "seleccionado nuevo ID de timeline: %u" -#: access/transam/xlog.c:7837 +#: access/transam/xlog.c:7849 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "el estado de recuperación consistente fue alcanzado en %X/%X" -#: access/transam/xlog.c:8029 +#: access/transam/xlog.c:8041 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "el enlace de punto de control primario en archivo de control no es válido" -#: access/transam/xlog.c:8033 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "el enlace del punto de control secundario en archivo de control no es válido" - -#: access/transam/xlog.c:8037 +#: access/transam/xlog.c:8045 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "el enlace del punto de control en backup_label no es válido" -#: access/transam/xlog.c:8054 +#: access/transam/xlog.c:8062 #, c-format msgid "invalid primary checkpoint record" msgstr "el registro del punto de control primario no es válido" -#: access/transam/xlog.c:8058 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "el registro del punto de control secundario no es válido" - -#: access/transam/xlog.c:8062 +#: access/transam/xlog.c:8066 #, c-format msgid "invalid checkpoint record" msgstr "el registro del punto de control no es válido" -#: access/transam/xlog.c:8073 +#: access/transam/xlog.c:8077 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "el ID de gestor de recursos en el registro del punto de control primario no es válido" -#: access/transam/xlog.c:8077 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "el ID de gestor de recursos en el registro del punto de control secundario no es válido" - #: access/transam/xlog.c:8081 #, c-format msgid "invalid resource manager ID in checkpoint record" @@ -2339,315 +2399,293 @@ msgstr "xl_info en el registro del punto de control primario no es válido" #: access/transam/xlog.c:8098 #, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "xl_info en el registro del punto de control secundario no es válido" - -#: access/transam/xlog.c:8102 -#, c-format msgid "invalid xl_info in checkpoint record" msgstr "xl_info en el registro del punto de control no es válido" -#: access/transam/xlog.c:8113 +#: access/transam/xlog.c:8109 #, c-format msgid "invalid length of primary checkpoint record" msgstr "la longitud del registro del punto de control primario no es válida" -#: access/transam/xlog.c:8117 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "la longitud del registro del punto de control secundario no es válida" - -#: access/transam/xlog.c:8121 +#: access/transam/xlog.c:8113 #, c-format msgid "invalid length of checkpoint record" msgstr "la longitud del registro de punto de control no es válida" -#: access/transam/xlog.c:8324 +#: access/transam/xlog.c:8293 #, c-format msgid "shutting down" msgstr "apagando" -#: access/transam/xlog.c:8643 -#, fuzzy, c-format -msgid "checkpoint skipped due to an idle system" -msgstr "falló la petición de punto de control" +#: access/transam/xlog.c:8613 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "omitiendo checkpoint porque el sistema está inactivo" -#: access/transam/xlog.c:8848 -#, fuzzy, c-format +#: access/transam/xlog.c:8813 +#, c-format msgid "concurrent write-ahead log activity while database system is shutting down" -msgstr "hay actividad en el registro de transacción mientras el sistema se está apagando" +msgstr "hay actividad de WAL mientras el sistema se está apagando" -#: access/transam/xlog.c:9102 +#: access/transam/xlog.c:9069 #, c-format msgid "skipping restartpoint, recovery has already ended" -msgstr "saltando el punto-de-reinicio; la recuperación ya ha terminado" +msgstr "omitiendo el restartpoint, la recuperación ya ha terminado" -#: access/transam/xlog.c:9125 +#: access/transam/xlog.c:9092 #, c-format msgid "skipping restartpoint, already performed at %X/%X" -msgstr "saltando el punto-de-reinicio; ya fue llevado a cabo en %X/%X" +msgstr "omitiendo el restartpoint, ya fue llevado a cabo en %X/%X" -#: access/transam/xlog.c:9301 +#: access/transam/xlog.c:9259 #, c-format msgid "recovery restart point at %X/%X" -msgstr "punto-de-reinicio de recuperación en %X/%X" +msgstr "restartpoint de recuperación en %X/%X" + +#: access/transam/xlog.c:9261 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Última transacción completada al tiempo de registro %s." -#: access/transam/xlog.c:9437 +#: access/transam/xlog.c:9395 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "punto de recuperación «%s» creado en %X/%X" -#: access/transam/xlog.c:9567 +#: access/transam/xlog.c:9536 #, c-format msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "ID de timeline previo %u inesperado (timeline actual %u) en el registro de punto de control" -#: access/transam/xlog.c:9576 +#: access/transam/xlog.c:9545 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "ID de timeline %u inesperado (después de %u) en el registro de punto de control" -#: access/transam/xlog.c:9592 +#: access/transam/xlog.c:9561 #, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgstr "timeline ID %u inesperado en registro de checkpoint, antes de alcanzar el punto mínimo de recuperación %X/%X en el timeline %u" -#: access/transam/xlog.c:9668 +#: access/transam/xlog.c:9637 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "el respaldo en línea fue cancelado, la recuperación no puede continuar" -#: access/transam/xlog.c:9724 access/transam/xlog.c:9771 -#: access/transam/xlog.c:9794 +#: access/transam/xlog.c:9691 access/transam/xlog.c:9745 +#: access/transam/xlog.c:9768 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "ID de timeline %u inesperado (debería ser %u) en el registro de punto de control" -#: access/transam/xlog.c:10070 -#, c-format -msgid "could not fsync log segment %s: %m" -msgstr "no se pudo sincronizar (fsync) el archivo de registro %s: %m" - -#: access/transam/xlog.c:10095 -#, c-format -msgid "could not fsync log file %s: %m" -msgstr "no se pudo sincronizar (fsync) archivo de registro «%s»: %m" - -#: access/transam/xlog.c:10103 +#: access/transam/xlog.c:10088 #, c-format -msgid "could not fsync write-through log file %s: %m" -msgstr "no se pudo sincronizar (fsync write-through) el archivo de registro %s: %m" +msgid "could not fsync write-through file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync write-through) el archivo «%s»: %m" -#: access/transam/xlog.c:10112 +#: access/transam/xlog.c:10097 #, c-format -msgid "could not fdatasync log file %s: %m" -msgstr "no se pudo sincronizar (fdatasync) el archivo de registro %s: %m" +msgid "could not fdatasync file \"%s\": %m" +msgstr "no se pudo sincronizar (fdatasync) archivo «%s»: %m" -#: access/transam/xlog.c:10203 access/transam/xlog.c:10721 -#: access/transam/xlogfuncs.c:297 access/transam/xlogfuncs.c:324 -#: access/transam/xlogfuncs.c:363 access/transam/xlogfuncs.c:384 -#: access/transam/xlogfuncs.c:405 +#: access/transam/xlog.c:10190 access/transam/xlog.c:10719 +#: access/transam/xlogfuncs.c:290 access/transam/xlogfuncs.c:317 +#: access/transam/xlogfuncs.c:356 access/transam/xlogfuncs.c:377 +#: access/transam/xlogfuncs.c:398 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "Las funciones de control de WAL no pueden ejecutarse durante la recuperación." -#: access/transam/xlog.c:10212 access/transam/xlog.c:10730 +#: access/transam/xlog.c:10199 access/transam/xlog.c:10728 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "el nivel de WAL no es suficiente para hacer un respaldo en línea" -#: access/transam/xlog.c:10213 access/transam/xlog.c:10731 -#: access/transam/xlogfuncs.c:330 +#: access/transam/xlog.c:10200 access/transam/xlog.c:10729 +#: access/transam/xlogfuncs.c:323 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "wal_level debe ser definido a «replica» o «logical» al inicio del servidor." -#: access/transam/xlog.c:10218 +#: access/transam/xlog.c:10205 #, c-format msgid "backup label too long (max %d bytes)" msgstr "la etiqueta de respaldo es demasiado larga (máximo %d bytes)" -#: access/transam/xlog.c:10255 access/transam/xlog.c:10528 -#: access/transam/xlog.c:10566 +#: access/transam/xlog.c:10242 access/transam/xlog.c:10518 +#: access/transam/xlog.c:10556 #, c-format msgid "a backup is already in progress" msgstr "ya hay un respaldo en curso" -#: access/transam/xlog.c:10256 +#: access/transam/xlog.c:10243 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "Ejecute pg_stop_backup() e intente nuevamente." -#: access/transam/xlog.c:10351 +#: access/transam/xlog.c:10339 #, c-format msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" -msgstr "el WAL generado con full_page_writes=off fue restaurado desde el último punto-de-reinicio" +msgstr "el WAL generado con full_page_writes=off fue restaurado desde el último restartpoint" -#: access/transam/xlog.c:10353 access/transam/xlog.c:10911 +#: access/transam/xlog.c:10341 access/transam/xlog.c:10924 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." msgstr "Esto significa que el respaldo que estaba siendo tomado en el standby está corrupto y no debería usarse. Active full_page_writes y ejecute CHECKPOINT en el maestro, luego trate de ejecutar un respaldo en línea nuevamente." -#: access/transam/xlog.c:10420 replication/basebackup.c:1096 -#: utils/adt/misc.c:497 -#, c-format -msgid "could not read symbolic link \"%s\": %m" -msgstr "no se pudo leer el enlace simbólico «%s»: %m" - -#: access/transam/xlog.c:10427 replication/basebackup.c:1101 -#: utils/adt/misc.c:502 +#: access/transam/xlog.c:10416 replication/basebackup.c:1237 +#: utils/adt/misc.c:329 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "la ruta «%s» del enlace simbólico es demasiado larga" -#: access/transam/xlog.c:10480 commands/tablespace.c:389 -#: commands/tablespace.c:551 replication/basebackup.c:1116 -#: utils/adt/misc.c:510 +#: access/transam/xlog.c:10468 commands/tablespace.c:394 +#: commands/tablespace.c:558 replication/basebackup.c:1252 utils/adt/misc.c:337 #, c-format msgid "tablespaces are not supported on this platform" msgstr "tablespaces no están soportados en esta plataforma" -#: access/transam/xlog.c:10522 access/transam/xlog.c:10560 -#: access/transam/xlog.c:10769 access/transam/xlogarchive.c:105 -#: access/transam/xlogarchive.c:264 commands/copy.c:1896 commands/copy.c:3126 -#: commands/extension.c:3319 commands/tablespace.c:780 -#: commands/tablespace.c:871 guc-file.l:1001 replication/basebackup.c:480 -#: replication/basebackup.c:548 replication/logical/snapbuild.c:1518 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2954 -#: storage/file/fd.c:3046 utils/adt/dbsize.c:70 utils/adt/dbsize.c:227 -#: utils/adt/dbsize.c:307 utils/adt/genfile.c:115 utils/adt/genfile.c:334 -#, c-format -msgid "could not stat file \"%s\": %m" -msgstr "no se pudo hacer stat al archivo «%s»: %m" - -#: access/transam/xlog.c:10529 access/transam/xlog.c:10567 +#: access/transam/xlog.c:10519 access/transam/xlog.c:10557 #, c-format msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." msgstr "Si está seguro que no hay un respaldo en curso, elimine el archivo «%s» e intente nuevamente." -#: access/transam/xlog.c:10546 access/transam/xlog.c:10584 -#: access/transam/xlog.c:10972 postmaster/syslogger.c:1391 -#: postmaster/syslogger.c:1404 -#, c-format -msgid "could not write file \"%s\": %m" -msgstr "no se pudo escribir el archivo «%s»: %m" - -#: access/transam/xlog.c:10746 +#: access/transam/xlog.c:10744 #, c-format msgid "exclusive backup not in progress" msgstr "no hay un respaldo exclusivo en curso" -#: access/transam/xlog.c:10773 +#: access/transam/xlog.c:10771 #, c-format msgid "a backup is not in progress" msgstr "no hay un respaldo en curso" -#: access/transam/xlog.c:10846 access/transam/xlog.c:10859 -#: access/transam/xlog.c:11200 access/transam/xlog.c:11206 -#: access/transam/xlog.c:11290 access/transam/xlogfuncs.c:698 +#: access/transam/xlog.c:10857 access/transam/xlog.c:10870 +#: access/transam/xlog.c:11231 access/transam/xlog.c:11237 +#: access/transam/xlog.c:11285 access/transam/xlog.c:11358 +#: access/transam/xlogfuncs.c:693 #, c-format msgid "invalid data in file \"%s\"" msgstr "datos no válidos en archivo «%s»" -#: access/transam/xlog.c:10863 replication/basebackup.c:994 +#: access/transam/xlog.c:10874 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "el standby fue promovido durante el respaldo en línea" -#: access/transam/xlog.c:10864 replication/basebackup.c:995 +#: access/transam/xlog.c:10875 replication/basebackup.c:1090 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "Esto significa que el respaldo que se estaba tomando está corrupto y no debería ser usado. Trate de ejecutar un nuevo respaldo en línea." -#: access/transam/xlog.c:10909 +#: access/transam/xlog.c:10922 #, c-format msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "el WAL generado con full_page_writes=off fue restaurado durante el respaldo en línea" -#: access/transam/xlog.c:11022 +#: access/transam/xlog.c:11042 #, c-format -msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" -msgstr "finalización de pg_stop_backup completa, esperando que se archiven los segmentos WAL requeridos" +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "respaldo base completo, esperando que se archiven los segmentos WAL requeridos" -#: access/transam/xlog.c:11032 +#: access/transam/xlog.c:11052 #, c-format -msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" -msgstr "pg_stop_backup todavía espera que todos los segmentos WAL requeridos sean archivados (han pasado %d segundos)" +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "todavía en espera de que todos los segmentos WAL requeridos sean archivados (han pasado %d segundos)" -#: access/transam/xlog.c:11034 +#: access/transam/xlog.c:11054 #, c-format -msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." -msgstr "Verifique que su archive_command se esté ejecutando con normalidad. pg_stop_backup puede ser abortado confiablemente, pero el respaldo de la base de datos no será utilizable a menos que disponga de todos los segmentos de WAL." +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Verifique que su archive_command se esté ejecutando con normalidad. Puede cancelar este respaldo con confianza, pero el respaldo de la base de datos no será utilizable a menos que disponga de todos los segmentos de WAL." -#: access/transam/xlog.c:11041 +#: access/transam/xlog.c:11061 #, c-format -msgid "pg_stop_backup complete, all required WAL segments have been archived" -msgstr "pg_stop_backup completado, todos los segmentos de WAL requeridos han sido archivados" +msgid "all required WAL segments have been archived" +msgstr "todos los segmentos de WAL requeridos han sido archivados" -#: access/transam/xlog.c:11045 +#: access/transam/xlog.c:11065 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "el archivado de WAL no está activo; debe asegurarse que todos los segmentos WAL requeridos se copian por algún otro mecanismo para completar el respaldo" +#: access/transam/xlog.c:11268 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "tiempo de respaldo %s en archivo «%s»" + +#: access/transam/xlog.c:11273 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "etiqueta de respaldo %s en archivo «%s»" + +#: access/transam/xlog.c:11286 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "El ID de timeline analizado es %u, pero se esperaba %u" + +#: access/transam/xlog.c:11290 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "línea de tiempo %u en archivo «%s»" + #. translator: %s is a WAL record description -#: access/transam/xlog.c:11330 -#, fuzzy, c-format +#: access/transam/xlog.c:11398 +#, c-format msgid "WAL redo at %X/%X for %s" -msgstr "xlog redo en %X/%X para %s" +msgstr "redo WAL en %X/%X para %s" -#: access/transam/xlog.c:11379 +#: access/transam/xlog.c:11447 #, c-format msgid "online backup mode was not canceled" msgstr "el modo de respaldo en línea no fue cancelado" -#: access/transam/xlog.c:11380 +#: access/transam/xlog.c:11448 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "El archivo «%s» no se pudo renombrar a «%s»: %m." -#: access/transam/xlog.c:11389 access/transam/xlog.c:11401 -#: access/transam/xlog.c:11411 +#: access/transam/xlog.c:11457 access/transam/xlog.c:11469 +#: access/transam/xlog.c:11479 #, c-format msgid "online backup mode canceled" msgstr "el modo de respaldo en línea fue cancelado" -#: access/transam/xlog.c:11402 +#: access/transam/xlog.c:11470 #, c-format msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "Los archivos «%s» y «%s» fueron renombrados a «%s» y «%s», respectivamente." -#: access/transam/xlog.c:11412 +#: access/transam/xlog.c:11480 #, c-format msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." msgstr "El archivo «%s» fue renombrado a «%s», pero el archivo «%s» no pudo ser renombrado a «%s»: %m." # XXX why talk about "log segment" instead of "file"? -#: access/transam/xlog.c:11534 access/transam/xlogutils.c:724 -#: replication/walreceiver.c:1005 replication/walsender.c:2397 +#: access/transam/xlog.c:11613 #, c-format -msgid "could not seek in log segment %s to offset %u: %m" -msgstr "no se pudo posicionar (seek) en segmento %s a la posición %u: %m" +msgid "could not read from log segment %s, offset %u: %m" +msgstr "no se pudo leer del archivo de segmento %s, posición %u: %m" # XXX why talk about "log segment" instead of "file"? -#: access/transam/xlog.c:11548 +#: access/transam/xlog.c:11619 replication/walsender.c:2489 #, c-format -msgid "could not read from log segment %s, offset %u: %m" -msgstr "no se pudo leer del archivo de segmento %s, posición %u: %m" +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "no se pudo leer del archivo de segmento %s, posición %u: leídos %d de %zu" -#: access/transam/xlog.c:12037 +#: access/transam/xlog.c:12152 #, c-format msgid "received promote request" msgstr "se recibió petición de promoción" -#: access/transam/xlog.c:12050 +#: access/transam/xlog.c:12165 #, c-format -msgid "trigger file found: %s" -msgstr "se encontró el archivo disparador: %s" +msgid "promote trigger file found: %s" +msgstr "se encontró el archivo disparador de promoción: %s" -#: access/transam/xlog.c:12059 +#: access/transam/xlog.c:12174 #, c-format -msgid "could not stat trigger file \"%s\": %m" -msgstr "no se pudo hacer stat al archivo disparador «%s»: %m" +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo disparador de promoción «%s»: %m" #: access/transam/xlogarchive.c:243 #, c-format @@ -2659,294 +2697,306 @@ msgstr "el archivo «%s» tiene tamaño erróneo: %lu en lugar de %lu" msgid "restored log file \"%s\" from archive" msgstr "se ha restaurado el archivo «%s» desde el área de archivado" -#: access/transam/xlogarchive.c:302 +#: access/transam/xlogarchive.c:297 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "no se pudo recuperar el archivo «%s»: %s" -#. translator: First %s represents a recovery.conf parameter name like +#. translator: First %s represents a postgresql.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:414 +#: access/transam/xlogarchive.c:406 #, c-format msgid "%s \"%s\": %s" msgstr "%s «%s»: %s" -#: access/transam/xlogarchive.c:457 postmaster/syslogger.c:1415 -#: replication/logical/snapbuild.c:1645 replication/slot.c:532 -#: replication/slot.c:1129 replication/slot.c:1243 storage/file/fd.c:642 -#: storage/file/fd.c:737 utils/time/snapmgr.c:1318 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1524 +#: replication/logical/snapbuild.c:1670 replication/slot.c:598 +#: replication/slot.c:1210 replication/slot.c:1332 storage/file/fd.c:664 +#: storage/file/fd.c:759 utils/time/snapmgr.c:1320 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "no se pudo crear el archivo de estado «%s»: %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:596 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "no se pudo escribir el archivo de estado «%s»: %m" -#: access/transam/xlogfuncs.c:55 +#: access/transam/xlogfuncs.c:57 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "abortando el backup porque el proceso servidor terminó antes de que pg_stop_backup fuera invocada" -#: access/transam/xlogfuncs.c:86 +#: access/transam/xlogfuncs.c:87 #, c-format msgid "a backup is already in progress in this session" msgstr "ya hay un respaldo en curso en esta sesión" -#: access/transam/xlogfuncs.c:92 commands/tablespace.c:703 -#: commands/tablespace.c:713 postmaster/postmaster.c:1458 -#: replication/basebackup.c:368 replication/basebackup.c:708 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2420 -#: storage/file/fd.c:3019 storage/ipc/dsm.c:301 utils/adt/genfile.c:440 -#: utils/adt/misc.c:410 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "no se pudo abrir el directorio «%s»: %m" - -#: access/transam/xlogfuncs.c:152 access/transam/xlogfuncs.c:234 +#: access/transam/xlogfuncs.c:145 access/transam/xlogfuncs.c:227 #, c-format msgid "non-exclusive backup in progress" msgstr "respaldo no-exclusivo en curso" -#: access/transam/xlogfuncs.c:153 access/transam/xlogfuncs.c:235 +#: access/transam/xlogfuncs.c:146 access/transam/xlogfuncs.c:228 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "¿Quiso usar pg_stop_backup('f')?" -#: access/transam/xlogfuncs.c:205 commands/event_trigger.c:1471 -#: commands/event_trigger.c:2022 commands/extension.c:1895 -#: commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:721 -#: executor/execExpr.c:2106 executor/execSRF.c:688 executor/functions.c:1029 -#: foreign/foreign.c:488 libpq/hba.c:2563 replication/logical/launcher.c:936 -#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1387 -#: replication/slotfuncs.c:197 replication/walsender.c:3166 -#: utils/adt/jsonfuncs.c:1689 utils/adt/jsonfuncs.c:1819 -#: utils/adt/jsonfuncs.c:2007 utils/adt/jsonfuncs.c:2134 -#: utils/adt/jsonfuncs.c:3489 utils/adt/pgstatfuncs.c:456 -#: utils/adt/pgstatfuncs.c:557 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8538 -#: utils/mmgr/portalmem.c:1053 +#: access/transam/xlogfuncs.c:198 commands/event_trigger.c:1473 +#: commands/event_trigger.c:2025 commands/extension.c:1908 +#: commands/extension.c:2017 commands/extension.c:2241 commands/prepare.c:712 +#: executor/execExpr.c:2201 executor/execSRF.c:720 executor/functions.c:1023 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1112 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1468 +#: replication/slotfuncs.c:236 replication/walsender.c:3245 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:458 +#: utils/adt/pgstatfuncs.c:563 utils/fmgr/funcapi.c:63 utils/misc/guc.c:9460 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "se llamó una función que retorna un conjunto en un contexto que no puede aceptarlo" -#: access/transam/xlogfuncs.c:209 commands/event_trigger.c:1475 -#: commands/event_trigger.c:2026 commands/extension.c:1899 -#: commands/extension.c:2008 commands/extension.c:2232 commands/prepare.c:725 -#: foreign/foreign.c:493 libpq/hba.c:2567 replication/logical/launcher.c:940 -#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1391 -#: replication/slotfuncs.c:201 replication/walsender.c:3170 -#: utils/adt/pgstatfuncs.c:460 utils/adt/pgstatfuncs.c:561 -#: utils/misc/guc.c:8542 utils/misc/pg_config.c:44 utils/mmgr/portalmem.c:1057 +#: access/transam/xlogfuncs.c:202 commands/event_trigger.c:1477 +#: commands/event_trigger.c:2029 commands/extension.c:1912 +#: commands/extension.c:2021 commands/extension.c:2245 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1116 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1472 +#: replication/slotfuncs.c:240 replication/walsender.c:3249 +#: utils/adt/pgstatfuncs.c:462 utils/adt/pgstatfuncs.c:567 +#: utils/misc/guc.c:9464 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "se requiere un nodo «materialize», pero no está permitido en este contexto" -#: access/transam/xlogfuncs.c:251 +#: access/transam/xlogfuncs.c:244 #, c-format msgid "non-exclusive backup is not in progress" msgstr "no hay un respaldo no-exclusivo en progreso" -#: access/transam/xlogfuncs.c:252 +#: access/transam/xlogfuncs.c:245 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "¿Quiso usar pg_stop_backup('t')?" -#: access/transam/xlogfuncs.c:329 +#: access/transam/xlogfuncs.c:322 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "el nivel de WAL no es suficiente para crear un punto de recuperación" -#: access/transam/xlogfuncs.c:337 +#: access/transam/xlogfuncs.c:330 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "el valor es demasiado largo para un punto de recuperación (máximo %d caracteres)" -#: access/transam/xlogfuncs.c:475 -#, fuzzy, c-format -msgid "pg_walfile_name_offset() cannot be executed during recovery." -msgstr "pg_xlogfile_name_offset() no puede ejecutarse durante la recuperación." - -#: access/transam/xlogfuncs.c:531 -#, fuzzy, c-format -msgid "pg_walfile_name() cannot be executed during recovery." -msgstr "pg_xlogfile_name() no puede ejecutarse durante la recuperación." +#: access/transam/xlogfuncs.c:468 access/transam/xlogfuncs.c:525 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "No se puede ejecutar %s durante la recuperación." -#: access/transam/xlogfuncs.c:551 access/transam/xlogfuncs.c:571 -#: access/transam/xlogfuncs.c:588 +#: access/transam/xlogfuncs.c:546 access/transam/xlogfuncs.c:566 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 #, c-format msgid "recovery is not in progress" msgstr "la recuperación no está en proceso" -#: access/transam/xlogfuncs.c:552 access/transam/xlogfuncs.c:572 -#: access/transam/xlogfuncs.c:589 +#: access/transam/xlogfuncs.c:547 access/transam/xlogfuncs.c:567 +#: access/transam/xlogfuncs.c:584 access/transam/xlogfuncs.c:724 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "Las funciones de control de recuperación sólo pueden ejecutarse durante la recuperación." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogfuncs.c:729 +#, c-format +msgid "\"wait_seconds\" cannot be negative or equal zero" +msgstr "«wait_seconds» no puede ser negativo o igual a cero" + +#: access/transam/xlogfuncs.c:749 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "no se pudo enviar señal a postmaster: %m" + +#: access/transam/xlogfuncs.c:776 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "el servidor no promovió en %d segundos" + +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "posición de registro no válida en %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "contrecord solicitado por %X/%X" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:625 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:645 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "largo de registro no válido en %X/%X: se esperaba %u, se obtuvo %u" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:372 #, c-format msgid "record length %u at %X/%X too long" msgstr "largo de registro %u en %X/%X demasiado largo" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "no hay bandera de contrecord en %X/%X" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "largo de contrecord %u no válido en %X/%X" -#: access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:653 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ID de gestor de recursos %u no válido en %X/%X" -#: access/transam/xlogreader.c:647 access/transam/xlogreader.c:664 +#: access/transam/xlogreader.c:667 access/transam/xlogreader.c:684 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "registro con prev-link %X/%X incorrecto en %X/%X" -#: access/transam/xlogreader.c:701 +#: access/transam/xlogreader.c:721 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "suma de verificación de los datos del gestor de recursos incorrecta en el registro en %X/%X" -#: access/transam/xlogreader.c:734 +#: access/transam/xlogreader.c:758 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "número mágico %04X no válido en archivo %s, posición %u" -#: access/transam/xlogreader.c:748 access/transam/xlogreader.c:799 +#: access/transam/xlogreader.c:772 access/transam/xlogreader.c:823 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "info bits %04X no válidos en archivo %s, posición %u" -#: access/transam/xlogreader.c:774 +#: access/transam/xlogreader.c:798 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "archivo WAL es de un sistema de bases de datos distinto: identificador de sistema en archivo WAL es %s, identificador en pg_control es %s" -#: access/transam/xlogreader.c:781 +#: access/transam/xlogreader.c:805 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_SEG_SIZE incorrecto en cabecera de página" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: tamaño de segmento incorrecto en cabecera de paǵina" -#: access/transam/xlogreader.c:787 +#: access/transam/xlogreader.c:811 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_BLCKSZ incorrecto en cabecera de paǵina" -#: access/transam/xlogreader.c:813 +#: access/transam/xlogreader.c:842 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "pageaddr %X/%X inesperado en archivo %s, posición %u" -#: access/transam/xlogreader.c:838 +#: access/transam/xlogreader.c:867 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "ID de timeline %u fuera de secuencia (después de %u) en archivo %s, posición %u" -#: access/transam/xlogreader.c:1083 +#: access/transam/xlogreader.c:1112 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u fuera de orden en %X/%X" -#: access/transam/xlogreader.c:1106 +#: access/transam/xlogreader.c:1135 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA está definido, pero no hay datos en %X/%X" -#: access/transam/xlogreader.c:1113 +#: access/transam/xlogreader.c:1142 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA no está definido, pero el largo de los datos es %u en %X/%X" -#: access/transam/xlogreader.c:1149 +#: access/transam/xlogreader.c:1178 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE está definido, pero posición del agujero es %u largo %u largo de imagen %u en %X/%X" -#: access/transam/xlogreader.c:1165 +#: access/transam/xlogreader.c:1194 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE no está definido, pero posición del agujero es %u largo %u en %X/%X" -#: access/transam/xlogreader.c:1180 +#: access/transam/xlogreader.c:1209 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED definido, pero largo de imagen de bloque es %u en %X/%X" -#: access/transam/xlogreader.c:1195 +#: access/transam/xlogreader.c:1224 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED está definido, pero largo de imagen de bloque es %u en %X/%X" -#: access/transam/xlogreader.c:1211 +#: access/transam/xlogreader.c:1240 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL está definido, pero no hay «rel» anterior en %X/%X " -#: access/transam/xlogreader.c:1223 +#: access/transam/xlogreader.c:1252 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "block_id %u no válido en %X/%X" -#: access/transam/xlogreader.c:1291 +#: access/transam/xlogreader.c:1341 #, c-format msgid "record with invalid length at %X/%X" msgstr "registro con largo no válido en %X/%X" -#: access/transam/xlogreader.c:1380 +#: access/transam/xlogreader.c:1430 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "imagen comprimida no válida en %X/%X, bloque %d" -#: access/transam/xlogutils.c:747 replication/walsender.c:2416 +# XXX why talk about "log segment" instead of "file"? +#: access/transam/xlogutils.c:727 replication/walreceiver.c:959 +#: replication/walsender.c:2462 +#, c-format +msgid "could not seek in log segment %s to offset %u: %m" +msgstr "no se pudo posicionar (seek) en segmento %s a la posición %u: %m" + +#: access/transam/xlogutils.c:751 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "no se pudo leer desde el segmento %s, posición %u, largo %lu: %m" -#: bootstrap/bootstrap.c:272 postmaster/postmaster.c:819 tcop/postgres.c:3510 +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X require un valor potencia de dos entre 1 MB y 1 GB" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:821 tcop/postgres.c:3648 #, c-format msgid "--%s requires a value" msgstr "--%s requiere un valor" -#: bootstrap/bootstrap.c:277 postmaster/postmaster.c:824 tcop/postgres.c:3515 +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:826 tcop/postgres.c:3653 #, c-format msgid "-c %s requires a value" msgstr "-c %s requiere un valor" -#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:836 -#: postmaster/postmaster.c:849 +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:838 +#: postmaster/postmaster.c:851 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Pruebe «%s --help» para mayor información.\n" -#: bootstrap/bootstrap.c:297 +#: bootstrap/bootstrap.c:313 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: argumentos de línea de órdenes no válidos\n" @@ -2996,588 +3046,714 @@ msgstr "no todos los privilegios pudieron ser revocados para la columna «%s» d msgid "not all privileges could be revoked for \"%s\"" msgstr "no todos los privilegios pudieron ser revocados para «%s»" -#: catalog/aclchk.c:455 catalog/aclchk.c:948 +#: catalog/aclchk.c:456 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for relation" msgstr "el tipo de privilegio %s no es válido para una relación" -#: catalog/aclchk.c:459 catalog/aclchk.c:952 +#: catalog/aclchk.c:460 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for sequence" msgstr "el tipo de privilegio %s no es válido para una secuencia" -#: catalog/aclchk.c:463 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "el tipo de privilegio %s no es válido para una base de datos" -#: catalog/aclchk.c:467 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "el tipo de privilegio %s no es válido para un dominio" -#: catalog/aclchk.c:471 catalog/aclchk.c:956 +#: catalog/aclchk.c:472 catalog/aclchk.c:1007 #, c-format msgid "invalid privilege type %s for function" msgstr "el tipo de privilegio %s no es válido para una función" -#: catalog/aclchk.c:475 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "el tipo de privilegio %s no es válido para un lenguaje" -#: catalog/aclchk.c:479 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "el tipo de privilegio %s no es válido para un objeto grande" -#: catalog/aclchk.c:483 catalog/aclchk.c:964 +#: catalog/aclchk.c:484 catalog/aclchk.c:1023 #, c-format msgid "invalid privilege type %s for schema" msgstr "el tipo de privilegio %s no es válido para un esquema" -#: catalog/aclchk.c:487 +#: catalog/aclchk.c:488 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "el tipo de privilegio %s no es válido para un procedimiento" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1015 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "el tipo de privilegio %s no es válido para una rutina" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "el tipo de privilegio %s no es válido para un tablespace" -#: catalog/aclchk.c:491 catalog/aclchk.c:960 +#: catalog/aclchk.c:500 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for type" msgstr "el tipo de privilegio %s no es válido para un tipo" -#: catalog/aclchk.c:495 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "el tipo de privilegio %s no es válido para un conector de datos externos" -#: catalog/aclchk.c:499 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "el tipo de privilegio %s no es válido para un servidor foráneo" -#: catalog/aclchk.c:538 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "los privilegios de columna son sólo válidos para relaciones" -#: catalog/aclchk.c:696 catalog/aclchk.c:3926 catalog/aclchk.c:4708 -#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4135 catalog/aclchk.c:4917 +#: catalog/objectaddress.c:964 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:283 #, c-format msgid "large object %u does not exist" msgstr "no existe el objeto grande %u" -#: catalog/aclchk.c:885 catalog/aclchk.c:894 commands/collationcmds.c:114 -#: commands/copy.c:1042 commands/copy.c:1062 commands/copy.c:1071 -#: commands/copy.c:1080 commands/copy.c:1089 commands/copy.c:1098 -#: commands/copy.c:1107 commands/copy.c:1116 commands/copy.c:1125 -#: commands/copy.c:1143 commands/copy.c:1159 commands/copy.c:1179 -#: commands/copy.c:1196 commands/dbcommands.c:155 commands/dbcommands.c:164 -#: commands/dbcommands.c:173 commands/dbcommands.c:182 -#: commands/dbcommands.c:191 commands/dbcommands.c:200 -#: commands/dbcommands.c:209 commands/dbcommands.c:218 -#: commands/dbcommands.c:227 commands/dbcommands.c:1427 -#: commands/dbcommands.c:1436 commands/dbcommands.c:1445 -#: commands/dbcommands.c:1454 commands/extension.c:1678 -#: commands/extension.c:1688 commands/extension.c:1698 -#: commands/extension.c:1708 commands/extension.c:2949 -#: commands/foreigncmds.c:537 commands/foreigncmds.c:546 -#: commands/functioncmds.c:526 commands/functioncmds.c:643 -#: commands/functioncmds.c:652 commands/functioncmds.c:661 -#: commands/functioncmds.c:670 commands/functioncmds.c:2097 -#: commands/functioncmds.c:2105 commands/publicationcmds.c:90 -#: commands/sequence.c:1265 commands/sequence.c:1275 commands/sequence.c:1285 -#: commands/sequence.c:1295 commands/sequence.c:1305 commands/sequence.c:1315 -#: commands/sequence.c:1325 commands/sequence.c:1335 commands/sequence.c:1345 -#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 -#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 -#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 -#: commands/subscriptioncmds.c:179 commands/tablecmds.c:5960 -#: commands/typecmds.c:298 commands/typecmds.c:1375 commands/typecmds.c:1384 -#: commands/typecmds.c:1392 commands/typecmds.c:1400 commands/typecmds.c:1408 -#: commands/user.c:134 commands/user.c:148 commands/user.c:157 -#: commands/user.c:166 commands/user.c:175 commands/user.c:184 -#: commands/user.c:193 commands/user.c:202 commands/user.c:211 -#: commands/user.c:220 commands/user.c:229 commands/user.c:238 -#: commands/user.c:247 commands/user.c:532 commands/user.c:540 -#: commands/user.c:548 commands/user.c:556 commands/user.c:564 -#: commands/user.c:572 commands/user.c:580 commands/user.c:588 -#: commands/user.c:597 commands/user.c:605 commands/user.c:613 -#: parser/parse_utilcmd.c:394 replication/pgoutput/pgoutput.c:107 -#: replication/pgoutput/pgoutput.c:128 replication/walsender.c:800 -#: replication/walsender.c:811 replication/walsender.c:821 +#: catalog/aclchk.c:936 catalog/aclchk.c:945 commands/collationcmds.c:117 +#: commands/copy.c:1140 commands/copy.c:1160 commands/copy.c:1169 +#: commands/copy.c:1178 commands/copy.c:1187 commands/copy.c:1196 +#: commands/copy.c:1205 commands/copy.c:1214 commands/copy.c:1232 +#: commands/copy.c:1248 commands/copy.c:1268 commands/copy.c:1285 +#: commands/dbcommands.c:156 commands/dbcommands.c:165 +#: commands/dbcommands.c:174 commands/dbcommands.c:183 +#: commands/dbcommands.c:192 commands/dbcommands.c:201 +#: commands/dbcommands.c:210 commands/dbcommands.c:219 +#: commands/dbcommands.c:228 commands/dbcommands.c:1429 +#: commands/dbcommands.c:1438 commands/dbcommands.c:1447 +#: commands/dbcommands.c:1456 commands/extension.c:1688 +#: commands/extension.c:1698 commands/extension.c:1708 +#: commands/extension.c:1718 commands/extension.c:2960 +#: commands/foreigncmds.c:543 commands/foreigncmds.c:552 +#: commands/functioncmds.c:568 commands/functioncmds.c:734 +#: commands/functioncmds.c:743 commands/functioncmds.c:752 +#: commands/functioncmds.c:761 commands/functioncmds.c:2193 +#: commands/functioncmds.c:2201 commands/publicationcmds.c:91 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:111 commands/subscriptioncmds.c:121 +#: commands/subscriptioncmds.c:131 commands/subscriptioncmds.c:141 +#: commands/subscriptioncmds.c:155 commands/subscriptioncmds.c:166 +#: commands/subscriptioncmds.c:180 commands/tablecmds.c:6497 +#: commands/typecmds.c:299 commands/typecmds.c:1428 commands/typecmds.c:1437 +#: commands/typecmds.c:1445 commands/typecmds.c:1453 commands/typecmds.c:1461 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:562 commands/user.c:570 +#: commands/user.c:578 commands/user.c:586 commands/user.c:594 +#: commands/user.c:602 commands/user.c:610 commands/user.c:618 +#: commands/user.c:627 commands/user.c:635 commands/user.c:643 +#: parser/parse_utilcmd.c:385 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:817 +#: replication/walsender.c:828 replication/walsender.c:838 #, c-format msgid "conflicting or redundant options" msgstr "opciones contradictorias o redundantes" -#: catalog/aclchk.c:997 +#: catalog/aclchk.c:1056 #, c-format msgid "default privileges cannot be set for columns" msgstr "los privilegios por omisión no pueden definirse para columnas" -#: catalog/aclchk.c:1157 +#: catalog/aclchk.c:1216 #, c-format msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" -msgstr "" - -#: catalog/aclchk.c:1521 catalog/objectaddress.c:1389 commands/analyze.c:390 -#: commands/copy.c:4745 commands/sequence.c:1700 commands/tablecmds.c:5608 -#: commands/tablecmds.c:5755 commands/tablecmds.c:5812 -#: commands/tablecmds.c:5885 commands/tablecmds.c:5979 -#: commands/tablecmds.c:6038 commands/tablecmds.c:6163 -#: commands/tablecmds.c:6217 commands/tablecmds.c:6309 -#: commands/tablecmds.c:6465 commands/tablecmds.c:8694 -#: commands/tablecmds.c:8970 commands/tablecmds.c:9405 commands/trigger.c:791 -#: parser/analyze.c:2310 parser/parse_relation.c:2699 -#: parser/parse_relation.c:2761 parser/parse_target.c:1002 -#: parser/parse_type.c:127 utils/adt/acl.c:2823 utils/adt/ruleutils.c:2349 +msgstr "No puede utilizar la cláusula IN SCHEMA cuando se utiliza GRANT / REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1584 catalog/catalog.c:519 catalog/objectaddress.c:1426 +#: commands/analyze.c:383 commands/copy.c:5132 commands/sequence.c:1702 +#: commands/tablecmds.c:6039 commands/tablecmds.c:6197 +#: commands/tablecmds.c:6271 commands/tablecmds.c:6341 +#: commands/tablecmds.c:6422 commands/tablecmds.c:6516 +#: commands/tablecmds.c:6575 commands/tablecmds.c:6714 +#: commands/tablecmds.c:6796 commands/tablecmds.c:6888 +#: commands/tablecmds.c:6982 commands/tablecmds.c:10215 +#: commands/tablecmds.c:10530 commands/tablecmds.c:11046 commands/trigger.c:928 +#: parser/analyze.c:2330 parser/parse_relation.c:2788 +#: parser/parse_relation.c:2851 parser/parse_target.c:1031 +#: parser/parse_type.c:127 utils/adt/acl.c:2885 utils/adt/ruleutils.c:2511 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "no existe la columna «%s» en la relación «%s»" -#: catalog/aclchk.c:1787 catalog/objectaddress.c:1229 commands/sequence.c:1138 -#: commands/tablecmds.c:229 commands/tablecmds.c:13080 utils/adt/acl.c:2059 -#: utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 -#: utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#: catalog/aclchk.c:1847 catalog/objectaddress.c:1266 commands/sequence.c:1140 +#: commands/tablecmds.c:230 commands/tablecmds.c:14775 utils/adt/acl.c:2075 +#: utils/adt/acl.c:2105 utils/adt/acl.c:2137 utils/adt/acl.c:2169 +#: utils/adt/acl.c:2197 utils/adt/acl.c:2227 #, c-format msgid "\"%s\" is not a sequence" msgstr "«%s» no es una secuencia" -#: catalog/aclchk.c:1825 +#: catalog/aclchk.c:1885 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "la secuencia «%s» sólo soporta los privilegios USAGE, SELECT, y UPDATE" -#: catalog/aclchk.c:1842 -#, fuzzy, c-format +#: catalog/aclchk.c:1902 +#, c-format msgid "invalid privilege type %s for table" -msgstr "el tipo de privilegio %s no es válido para un tablespace" +msgstr "el tipo de privilegio %s no es válido para una tabla" -#: catalog/aclchk.c:2008 +#: catalog/aclchk.c:2068 #, c-format msgid "invalid privilege type %s for column" msgstr "el tipo de privilegio %s no es válido para una columna" -#: catalog/aclchk.c:2021 +#: catalog/aclchk.c:2081 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "la secuencia «%s» sólo soporta el privilegio SELECT" -#: catalog/aclchk.c:2603 +#: catalog/aclchk.c:2663 #, c-format msgid "language \"%s\" is not trusted" msgstr "el lenguaje «%s» no es confiable (trusted)" -#: catalog/aclchk.c:2605 +#: catalog/aclchk.c:2665 #, c-format msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." msgstr "GRANT y REVOKE no están permitidos en lenguajes no confiables, porque sólo los superusuarios pueden usar lenguajes no confiables." -#: catalog/aclchk.c:3119 +#: catalog/aclchk.c:3179 #, c-format msgid "cannot set privileges of array types" msgstr "no se puede definir privilegios para tipos de array" -#: catalog/aclchk.c:3120 +#: catalog/aclchk.c:3180 #, c-format msgid "Set the privileges of the element type instead." msgstr "Defina los privilegios del tipo elemento en su lugar." -#: catalog/aclchk.c:3127 catalog/objectaddress.c:1519 +#: catalog/aclchk.c:3187 catalog/objectaddress.c:1560 #, c-format msgid "\"%s\" is not a domain" msgstr "«%s» no es un dominio" -#: catalog/aclchk.c:3247 +#: catalog/aclchk.c:3307 #, c-format msgid "unrecognized privilege type \"%s\"" -msgstr "tipo de privilegio no reconocido: «%s»" +msgstr "tipo de privilegio «%s» no reconocido" + +#: catalog/aclchk.c:3368 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "permiso denegado a la función de agregación %s" -#: catalog/aclchk.c:3296 +#: catalog/aclchk.c:3371 #, c-format -msgid "permission denied for column %s" -msgstr "permiso denegado a la columna %s" +msgid "permission denied for collation %s" +msgstr "permiso denegado al ordenamiento (collation) %s" -#: catalog/aclchk.c:3298 +#: catalog/aclchk.c:3374 #, c-format -msgid "permission denied for relation %s" -msgstr "permiso denegado a la relación %s" +msgid "permission denied for column %s" +msgstr "permiso denegado a la columna %s" -#: catalog/aclchk.c:3300 commands/sequence.c:600 commands/sequence.c:834 -#: commands/sequence.c:876 commands/sequence.c:917 commands/sequence.c:1791 -#: commands/sequence.c:1855 +#: catalog/aclchk.c:3377 #, c-format -msgid "permission denied for sequence %s" -msgstr "permiso denegado a la secuencia %s" +msgid "permission denied for conversion %s" +msgstr "permiso denegado a la conversión %s" -#: catalog/aclchk.c:3302 +#: catalog/aclchk.c:3380 #, c-format msgid "permission denied for database %s" msgstr "permiso denegado a la base de datos %s" -#: catalog/aclchk.c:3304 +#: catalog/aclchk.c:3383 #, c-format -msgid "permission denied for function %s" -msgstr "permiso denegado a la función %s" +msgid "permission denied for domain %s" +msgstr "permiso denegado al dominio %s" -#: catalog/aclchk.c:3306 +#: catalog/aclchk.c:3386 #, c-format -msgid "permission denied for operator %s" -msgstr "permiso denegado al operador %s" +msgid "permission denied for event trigger %s" +msgstr "permiso denegado al disparador por eventos %s" -#: catalog/aclchk.c:3308 +#: catalog/aclchk.c:3389 #, c-format -msgid "permission denied for type %s" -msgstr "permiso denegado al tipo %s" +msgid "permission denied for extension %s" +msgstr "permiso denegado a la extensión %s" -#: catalog/aclchk.c:3310 +#: catalog/aclchk.c:3392 #, c-format -msgid "permission denied for language %s" -msgstr "permiso denegado al lenguaje %s" +msgid "permission denied for foreign-data wrapper %s" +msgstr "permiso denegado al conector de datos externos %s" -#: catalog/aclchk.c:3312 +#: catalog/aclchk.c:3395 #, c-format -msgid "permission denied for large object %s" -msgstr "permiso denegado al objeto grande %s" +msgid "permission denied for foreign server %s" +msgstr "permiso denegado al servidor foráneo %s" -#: catalog/aclchk.c:3314 +#: catalog/aclchk.c:3398 #, c-format -msgid "permission denied for schema %s" -msgstr "permiso denegado al esquema %s" +msgid "permission denied for foreign table %s" +msgstr "permiso denegado a la tabla foránea %s" + +#: catalog/aclchk.c:3401 +#, c-format +msgid "permission denied for function %s" +msgstr "permiso denegado a la función %s" + +#: catalog/aclchk.c:3404 +#, c-format +msgid "permission denied for index %s" +msgstr "permiso denegado al índice %s" + +#: catalog/aclchk.c:3407 +#, c-format +msgid "permission denied for language %s" +msgstr "permiso denegado al lenguaje %s" + +#: catalog/aclchk.c:3410 +#, c-format +msgid "permission denied for large object %s" +msgstr "permiso denegado al objeto grande %s" + +#: catalog/aclchk.c:3413 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "permiso denegado a la vista materializada %s" -#: catalog/aclchk.c:3316 +#: catalog/aclchk.c:3416 #, c-format msgid "permission denied for operator class %s" msgstr "permiso denegado a la clase de operadores %s" -#: catalog/aclchk.c:3318 +#: catalog/aclchk.c:3419 +#, c-format +msgid "permission denied for operator %s" +msgstr "permiso denegado al operador %s" + +#: catalog/aclchk.c:3422 #, c-format msgid "permission denied for operator family %s" msgstr "permiso denegado a la familia de operadores %s" -#: catalog/aclchk.c:3320 +#: catalog/aclchk.c:3425 #, c-format -msgid "permission denied for collation %s" -msgstr "permiso denegado al ordenamiento (collation) %s" +msgid "permission denied for policy %s" +msgstr "permiso denegado a la política %s" -#: catalog/aclchk.c:3322 +#: catalog/aclchk.c:3428 #, c-format -msgid "permission denied for conversion %s" -msgstr "permiso denegado a la conversión %s" +msgid "permission denied for procedure %s" +msgstr "permiso denegado al procedimiento %s" + +#: catalog/aclchk.c:3431 +#, c-format +msgid "permission denied for publication %s" +msgstr "permiso denegado a la publicación %s" + +#: catalog/aclchk.c:3434 +#, c-format +msgid "permission denied for routine %s" +msgstr "permiso denegado a la rutina %s" + +#: catalog/aclchk.c:3437 +#, c-format +msgid "permission denied for schema %s" +msgstr "permiso denegado al esquema %s" + +#: catalog/aclchk.c:3440 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "permiso denegado a la secuencia %s" -#: catalog/aclchk.c:3324 -#, fuzzy, c-format +#: catalog/aclchk.c:3443 +#, c-format msgid "permission denied for statistics object %s" -msgstr "permiso denegado al objeto grande %s" +msgstr "permiso denegado al objeto de estadísticas %s" + +#: catalog/aclchk.c:3446 +#, c-format +msgid "permission denied for subscription %s" +msgstr "permiso denegado a la suscripción %s" + +#: catalog/aclchk.c:3449 +#, c-format +msgid "permission denied for table %s" +msgstr "permiso denegado a la tabla %s" -#: catalog/aclchk.c:3326 +#: catalog/aclchk.c:3452 #, c-format msgid "permission denied for tablespace %s" msgstr "permiso denegado al tablespace %s" -#: catalog/aclchk.c:3328 +#: catalog/aclchk.c:3455 #, c-format -msgid "permission denied for text search dictionary %s" +msgid "permission denied for text search configuration %s" msgstr "permiso denegado a la configuración de búsqueda en texto %s" -#: catalog/aclchk.c:3330 +#: catalog/aclchk.c:3458 #, c-format -msgid "permission denied for text search configuration %s" +msgid "permission denied for text search dictionary %s" msgstr "permiso denegado a la configuración de búsqueda en texto %s" -#: catalog/aclchk.c:3332 +#: catalog/aclchk.c:3461 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "permiso denegado al conector de datos externos %s" +msgid "permission denied for type %s" +msgstr "permiso denegado al tipo %s" -#: catalog/aclchk.c:3334 +#: catalog/aclchk.c:3464 #, c-format -msgid "permission denied for foreign server %s" -msgstr "permiso denegado al servidor foráneo %s" +msgid "permission denied for view %s" +msgstr "permiso denegado a la vista %s" -#: catalog/aclchk.c:3336 +#: catalog/aclchk.c:3499 #, c-format -msgid "permission denied for event trigger %s" -msgstr "permiso denegado al disparador por eventos %s" +msgid "must be owner of aggregate %s" +msgstr "debe ser dueño de la función de agregación %s" -#: catalog/aclchk.c:3338 +#: catalog/aclchk.c:3502 #, c-format -msgid "permission denied for extension %s" -msgstr "permiso denegado a la extensión %s" +msgid "must be owner of collation %s" +msgstr "debe ser dueño del ordenamiento (collation) %s" -#: catalog/aclchk.c:3340 -#, fuzzy, c-format -msgid "permission denied for publication %s" -msgstr "permiso denegado a la relación %s" +#: catalog/aclchk.c:3505 +#, c-format +msgid "must be owner of conversion %s" +msgstr "debe ser dueño de la conversión %s" -#: catalog/aclchk.c:3342 -#, fuzzy, c-format -msgid "permission denied for subscription %s" -msgstr "permiso denegado a la función %s" +#: catalog/aclchk.c:3508 +#, c-format +msgid "must be owner of database %s" +msgstr "debe ser dueño de la base de datos %s" -#: catalog/aclchk.c:3348 catalog/aclchk.c:3350 +#: catalog/aclchk.c:3511 #, c-format -msgid "must be owner of relation %s" -msgstr "debe ser dueño de la relación %s" +msgid "must be owner of domain %s" +msgstr "debe ser dueño del dominio %s" -#: catalog/aclchk.c:3352 +#: catalog/aclchk.c:3514 #, c-format -msgid "must be owner of sequence %s" -msgstr "debe ser dueño de la secuencia %s" +msgid "must be owner of event trigger %s" +msgstr "debe ser dueño del disparador por eventos %s" -#: catalog/aclchk.c:3354 +#: catalog/aclchk.c:3517 #, c-format -msgid "must be owner of database %s" -msgstr "debe ser dueño de la base de datos %s" +msgid "must be owner of extension %s" +msgstr "debe ser dueño de la extensión %s" -#: catalog/aclchk.c:3356 +#: catalog/aclchk.c:3520 #, c-format -msgid "must be owner of function %s" -msgstr "debe ser dueño de la función %s" +msgid "must be owner of foreign-data wrapper %s" +msgstr "debe ser dueño del conector de datos externos %s" -#: catalog/aclchk.c:3358 +#: catalog/aclchk.c:3523 #, c-format -msgid "must be owner of operator %s" -msgstr "debe ser dueño del operador %s" +msgid "must be owner of foreign server %s" +msgstr "debe ser dueño del servidor foráneo %s" -#: catalog/aclchk.c:3360 +#: catalog/aclchk.c:3526 #, c-format -msgid "must be owner of type %s" -msgstr "debe ser dueño del tipo %s" +msgid "must be owner of foreign table %s" +msgstr "debe ser dueño de la tabla foránea %s" + +#: catalog/aclchk.c:3529 +#, c-format +msgid "must be owner of function %s" +msgstr "debe ser dueño de la función %s" + +#: catalog/aclchk.c:3532 +#, c-format +msgid "must be owner of index %s" +msgstr "debe ser dueño del índice %s" -#: catalog/aclchk.c:3362 +#: catalog/aclchk.c:3535 #, c-format msgid "must be owner of language %s" msgstr "debe ser dueño del lenguaje %s" -#: catalog/aclchk.c:3364 +#: catalog/aclchk.c:3538 #, c-format msgid "must be owner of large object %s" msgstr "debe ser dueño del objeto grande %s" -#: catalog/aclchk.c:3366 +#: catalog/aclchk.c:3541 #, c-format -msgid "must be owner of schema %s" -msgstr "debe ser dueño del esquema %s" +msgid "must be owner of materialized view %s" +msgstr "debe ser dueño de la vista materializada %s" -#: catalog/aclchk.c:3368 +#: catalog/aclchk.c:3544 #, c-format msgid "must be owner of operator class %s" msgstr "debe ser dueño de la clase de operadores %s" -#: catalog/aclchk.c:3370 +#: catalog/aclchk.c:3547 +#, c-format +msgid "must be owner of operator %s" +msgstr "debe ser dueño del operador %s" + +#: catalog/aclchk.c:3550 #, c-format msgid "must be owner of operator family %s" msgstr "debe ser dueño de la familia de operadores %s" -#: catalog/aclchk.c:3372 +#: catalog/aclchk.c:3553 #, c-format -msgid "must be owner of collation %s" -msgstr "debe ser dueño del ordenamiento (collation) %s" +msgid "must be owner of procedure %s" +msgstr "debe ser dueño del procedimiento %s" -#: catalog/aclchk.c:3374 +#: catalog/aclchk.c:3556 #, c-format -msgid "must be owner of conversion %s" -msgstr "debe ser dueño de la conversión %s" +msgid "must be owner of publication %s" +msgstr "debe ser dueño de la publicación %s" -#: catalog/aclchk.c:3376 -#, fuzzy, c-format -msgid "must be owner of statistics object %s" -msgstr "debe ser dueño del objeto grande %s" +#: catalog/aclchk.c:3559 +#, c-format +msgid "must be owner of routine %s" +msgstr "debe ser dueño de la rutina %s" -#: catalog/aclchk.c:3378 +#: catalog/aclchk.c:3562 #, c-format -msgid "must be owner of tablespace %s" -msgstr "debe ser dueño del tablespace %s" +msgid "must be owner of sequence %s" +msgstr "debe ser dueño de la secuencia %s" -#: catalog/aclchk.c:3380 +#: catalog/aclchk.c:3565 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "debe ser dueño del diccionario de búsqueda en texto %s" +msgid "must be owner of subscription %s" +msgstr "debe ser dueño de la suscripción %s" -#: catalog/aclchk.c:3382 +#: catalog/aclchk.c:3568 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "debe ser dueño de la configuración de búsqueda en texto %s" +msgid "must be owner of table %s" +msgstr "debe ser dueño de la tabla %s" -#: catalog/aclchk.c:3384 +#: catalog/aclchk.c:3571 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "debe ser dueño del conector de datos externos %s" +msgid "must be owner of type %s" +msgstr "debe ser dueño del tipo %s" -#: catalog/aclchk.c:3386 +#: catalog/aclchk.c:3574 #, c-format -msgid "must be owner of foreign server %s" -msgstr "debe ser dueño del servidor foráneo %s" +msgid "must be owner of view %s" +msgstr "debe ser dueño de la vista %s" -#: catalog/aclchk.c:3388 +#: catalog/aclchk.c:3577 #, c-format -msgid "must be owner of event trigger %s" -msgstr "debe ser dueño del disparador por eventos %s" +msgid "must be owner of schema %s" +msgstr "debe ser dueño del esquema %s" -#: catalog/aclchk.c:3390 +#: catalog/aclchk.c:3580 #, c-format -msgid "must be owner of extension %s" -msgstr "debe ser dueño de la extensión %s" +msgid "must be owner of statistics object %s" +msgstr "debe ser dueño del objeto de estadísticas %s" -#: catalog/aclchk.c:3392 -#, fuzzy, c-format -msgid "must be owner of publication %s" -msgstr "debe ser dueño de la relación %s" +#: catalog/aclchk.c:3583 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "debe ser dueño del tablespace %s" -#: catalog/aclchk.c:3394 -#, fuzzy, c-format -msgid "must be owner of subscription %s" -msgstr "debe ser dueño de la función %s" +#: catalog/aclchk.c:3586 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "debe ser dueño de la configuración de búsqueda en texto %s" + +#: catalog/aclchk.c:3589 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "debe ser dueño del diccionario de búsqueda en texto %s" + +#: catalog/aclchk.c:3603 +#, c-format +msgid "must be owner of relation %s" +msgstr "debe ser dueño de la relación %s" -#: catalog/aclchk.c:3436 +#: catalog/aclchk.c:3647 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "permiso denegado a la columna «%s» de la relación «%s»" -#: catalog/aclchk.c:3559 catalog/aclchk.c:3567 +#: catalog/aclchk.c:3768 catalog/aclchk.c:3776 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "no existe el atributo %d de la relación con OID %u" -#: catalog/aclchk.c:3640 catalog/aclchk.c:4559 +#: catalog/aclchk.c:3849 catalog/aclchk.c:4768 #, c-format msgid "relation with OID %u does not exist" msgstr "no existe la relación con OID %u" -#: catalog/aclchk.c:3739 catalog/aclchk.c:4977 +#: catalog/aclchk.c:3948 catalog/aclchk.c:5186 #, c-format msgid "database with OID %u does not exist" msgstr "no existe la base de datos con OID %u" -#: catalog/aclchk.c:3793 catalog/aclchk.c:4637 tcop/fastpath.c:223 -#: utils/fmgr/fmgr.c:2117 +#: catalog/aclchk.c:4002 catalog/aclchk.c:4846 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2017 #, c-format msgid "function with OID %u does not exist" msgstr "no existe la función con OID %u" -#: catalog/aclchk.c:3847 catalog/aclchk.c:4663 +#: catalog/aclchk.c:4056 catalog/aclchk.c:4872 #, c-format msgid "language with OID %u does not exist" msgstr "no existe el lenguaje con OID %u" -#: catalog/aclchk.c:4011 catalog/aclchk.c:4735 +#: catalog/aclchk.c:4220 catalog/aclchk.c:4944 #, c-format msgid "schema with OID %u does not exist" msgstr "no existe el esquema con OID %u" -#: catalog/aclchk.c:4065 catalog/aclchk.c:4762 +#: catalog/aclchk.c:4274 catalog/aclchk.c:4971 utils/adt/genfile.c:637 #, c-format msgid "tablespace with OID %u does not exist" msgstr "no existe el tablespace con OID %u" -#: catalog/aclchk.c:4124 catalog/aclchk.c:4896 commands/foreigncmds.c:324 +#: catalog/aclchk.c:4333 catalog/aclchk.c:5105 commands/foreigncmds.c:328 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "no existe el conector de datos externos con OID %u" -#: catalog/aclchk.c:4186 catalog/aclchk.c:4923 commands/foreigncmds.c:459 +#: catalog/aclchk.c:4395 catalog/aclchk.c:5132 commands/foreigncmds.c:465 #, c-format msgid "foreign server with OID %u does not exist" msgstr "no existe el servidor foráneo con OID %u" -#: catalog/aclchk.c:4246 catalog/aclchk.c:4585 utils/cache/typcache.c:238 +#: catalog/aclchk.c:4455 catalog/aclchk.c:4794 utils/cache/typcache.c:369 #, c-format msgid "type with OID %u does not exist" msgstr "no existe el tipo con OID %u" -#: catalog/aclchk.c:4611 +#: catalog/aclchk.c:4820 #, c-format msgid "operator with OID %u does not exist" msgstr "no existe el operador con OID %u" -#: catalog/aclchk.c:4788 +#: catalog/aclchk.c:4997 #, c-format msgid "operator class with OID %u does not exist" msgstr "no existe la clase de operadores con OID %u" -#: catalog/aclchk.c:4815 +#: catalog/aclchk.c:5024 #, c-format msgid "operator family with OID %u does not exist" msgstr "no existe la familia de operadores con OID %u" -#: catalog/aclchk.c:4842 +#: catalog/aclchk.c:5051 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "no existe el diccionario de búsqueda en texto con OID %u" -#: catalog/aclchk.c:4869 +#: catalog/aclchk.c:5078 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "no existe la configuración de búsqueda en texto con OID %u" -#: catalog/aclchk.c:4950 commands/event_trigger.c:588 +#: catalog/aclchk.c:5159 commands/event_trigger.c:596 #, c-format msgid "event trigger with OID %u does not exist" msgstr "no existe el disparador por eventos con OID %u" -#: catalog/aclchk.c:5003 commands/collationcmds.c:344 +#: catalog/aclchk.c:5212 commands/collationcmds.c:366 #, c-format msgid "collation with OID %u does not exist" msgstr "no existe el ordenamiento (collation) con OID %u" -#: catalog/aclchk.c:5029 +#: catalog/aclchk.c:5238 #, c-format msgid "conversion with OID %u does not exist" msgstr "no existe la conversión con OID %u" -#: catalog/aclchk.c:5070 +#: catalog/aclchk.c:5279 #, c-format msgid "extension with OID %u does not exist" msgstr "no existe la extensión con OID %u" -#: catalog/aclchk.c:5097 commands/publicationcmds.c:733 -#, fuzzy, c-format +#: catalog/aclchk.c:5306 commands/publicationcmds.c:759 +#, c-format msgid "publication with OID %u does not exist" -msgstr "no existe la relación con OID %u" +msgstr "no existe la publicación con OID %u" -#: catalog/aclchk.c:5123 commands/subscriptioncmds.c:1075 -#, fuzzy, c-format +#: catalog/aclchk.c:5332 commands/subscriptioncmds.c:1121 +#, c-format msgid "subscription with OID %u does not exist" -msgstr "no existe la función con OID %u" +msgstr "no existe la suscripción con OID %u" -#: catalog/aclchk.c:5149 -#, fuzzy, c-format +#: catalog/aclchk.c:5358 +#, c-format msgid "statistics object with OID %u does not exist" -msgstr "no existe el tablespace con OID %u" +msgstr "no existe el objeto de estadísticas con OID %u" + +#: catalog/catalog.c:498 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "debe ser superusuario para invocar pg_nextoid()" + +#: catalog/catalog.c:506 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() sólo puede usarse en catálogos de sistema" + +#: catalog/catalog.c:511 parser/parse_utilcmd.c:2064 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "el índice «%s» no pertenece a la tabla «%s»" + +#: catalog/catalog.c:528 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "la columna «%s» no es de tipo oid" + +#: catalog/catalog.c:535 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "«el índice %s» no es el índice para la columna «%s»" -#: catalog/dependency.c:613 +#: catalog/dependency.c:808 catalog/dependency.c:1036 #, c-format msgid "cannot drop %s because %s requires it" msgstr "no se puede eliminar %s porque %s lo requiere" -#: catalog/dependency.c:616 +#: catalog/dependency.c:810 catalog/dependency.c:1038 #, c-format msgid "You can drop %s instead." msgstr "Puede eliminar %s en su lugar." -#: catalog/dependency.c:779 catalog/pg_shdepend.c:574 +#: catalog/dependency.c:908 catalog/pg_shdepend.c:641 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "no se puede eliminar %s porque es requerido por el sistema" -#: catalog/dependency.c:897 +#: catalog/dependency.c:1104 #, c-format msgid "drop auto-cascades to %s" msgstr "eliminando automáticamente %s" -#: catalog/dependency.c:909 catalog/dependency.c:918 +#: catalog/dependency.c:1116 catalog/dependency.c:1125 #, c-format msgid "%s depends on %s" msgstr "%s depende de %s" -#: catalog/dependency.c:930 catalog/dependency.c:939 +#: catalog/dependency.c:1137 catalog/dependency.c:1146 #, c-format msgid "drop cascades to %s" msgstr "eliminando además %s" -#: catalog/dependency.c:947 catalog/pg_shdepend.c:685 +#: catalog/dependency.c:1154 catalog/pg_shdepend.c:770 #, c-format msgid "" "\n" @@ -3592,609 +3768,641 @@ msgstr[1] "" "\n" "y otros %d objetos (vea el registro del servidor para obtener la lista)" -#: catalog/dependency.c:959 +#: catalog/dependency.c:1166 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "no se puede eliminar %s porque otros objetos dependen de él" -#: catalog/dependency.c:963 catalog/dependency.c:970 +#: catalog/dependency.c:1168 catalog/dependency.c:1169 +#: catalog/dependency.c:1175 catalog/dependency.c:1176 +#: catalog/dependency.c:1187 catalog/dependency.c:1188 +#: commands/tablecmds.c:1192 commands/tablecmds.c:12073 commands/user.c:1073 +#: commands/view.c:505 libpq/auth.c:333 replication/syncrep.c:1163 +#: storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1348 utils/adt/acl.c:5344 +#: utils/misc/guc.c:6576 utils/misc/guc.c:6612 utils/misc/guc.c:6682 +#: utils/misc/guc.c:10731 utils/misc/guc.c:10765 utils/misc/guc.c:10799 +#: utils/misc/guc.c:10833 utils/misc/guc.c:10868 utils/misc/guc.c:11613 +#: utils/misc/guc.c:11700 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1170 catalog/dependency.c:1177 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Use DROP ... CASCADE para eliminar además los objetos dependientes." -#: catalog/dependency.c:967 +#: catalog/dependency.c:1174 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "no se puede eliminar el o los objetos deseados porque otros objetos dependen de ellos" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:976 +#: catalog/dependency.c:1183 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "eliminando además %d objeto más" msgstr[1] "eliminando además %d objetos más" -#: catalog/dependency.c:1635 -#, fuzzy, c-format +#: catalog/dependency.c:1845 +#, c-format msgid "constant of the type %s cannot be used here" -msgstr "no se puede usar una constante de tipo «regrole» aquí" +msgstr "no se puede usar una constante de tipo %s aquí" -#: catalog/heap.c:283 +#: catalog/heap.c:332 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "se ha denegado el permiso para crear «%s.%s»" -#: catalog/heap.c:285 +#: catalog/heap.c:334 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Las modificaciones al catálogo del sistema están actualmente deshabilitadas." -#: catalog/heap.c:421 commands/tablecmds.c:1649 commands/tablecmds.c:2159 -#: commands/tablecmds.c:5212 +#: catalog/heap.c:502 commands/tablecmds.c:2043 commands/tablecmds.c:2560 +#: commands/tablecmds.c:5644 #, c-format msgid "tables can have at most %d columns" msgstr "las tablas pueden tener a lo más %d columnas" -#: catalog/heap.c:438 commands/tablecmds.c:5471 +#: catalog/heap.c:520 commands/tablecmds.c:5929 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "el nombre de columna «%s» colisiona con nombre de una columna de sistema" -#: catalog/heap.c:454 +#: catalog/heap.c:536 #, c-format msgid "column name \"%s\" specified more than once" msgstr "el nombre de columna «%s» fue especificado más de una vez" -#: catalog/heap.c:507 +#: catalog/heap.c:604 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "la columna «%s» tiene pseudotipo %s" -#: catalog/heap.c:537 +#: catalog/heap.c:634 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "un tipo compuesto %s no puede ser hecho miembro de sí mismo" -#: catalog/heap.c:579 commands/createas.c:201 commands/createas.c:498 +#: catalog/heap.c:676 commands/createas.c:204 commands/createas.c:488 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "no se derivó ningún ordenamiento (collate) para la columna «%s» con tipo ordenable %s" -#: catalog/heap.c:581 commands/createas.c:204 commands/createas.c:501 -#: commands/indexcmds.c:1149 commands/tablecmds.c:13376 commands/view.c:103 -#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1547 -#: utils/adt/formatting.c:1671 utils/adt/formatting.c:1796 -#: utils/adt/like.c:184 utils/adt/selfuncs.c:5563 utils/adt/varlena.c:1417 -#: utils/adt/varlena.c:1866 -#, c-format -msgid "Use the COLLATE clause to set the collation explicitly." -msgstr "Use la cláusula COLLATE para establecer el ordenamiento explícitamente." - -#: catalog/heap.c:1067 catalog/index.c:807 commands/tablecmds.c:2943 +#: catalog/heap.c:1122 catalog/index.c:819 commands/tablecmds.c:3327 #, c-format msgid "relation \"%s\" already exists" msgstr "la relación «%s» ya existe" -#: catalog/heap.c:1083 catalog/pg_type.c:410 catalog/pg_type.c:732 -#: commands/typecmds.c:239 commands/typecmds.c:788 commands/typecmds.c:1139 -#: commands/typecmds.c:1350 commands/typecmds.c:2106 +#: catalog/heap.c:1138 catalog/pg_type.c:427 catalog/pg_type.c:749 +#: commands/typecmds.c:240 commands/typecmds.c:791 commands/typecmds.c:1191 +#: commands/typecmds.c:1403 commands/typecmds.c:2160 #, c-format msgid "type \"%s\" already exists" msgstr "ya existe un tipo «%s»" -#: catalog/heap.c:1084 +#: catalog/heap.c:1139 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "Una relación tiene un tipo asociado del mismo nombre, de modo que debe usar un nombre que no entre en conflicto con un tipo existente." -#: catalog/heap.c:1113 +#: catalog/heap.c:1168 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "el valor de OID de heap de pg_class no se definió en modo de actualización binaria" -#: catalog/heap.c:2078 -#, fuzzy, c-format +#: catalog/heap.c:2369 +#, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" -msgstr "no se puede usar una restricción unique postergable para la tabla referenciada «%s»" +msgstr "no se puede agregar una restricción NO INHERIT a la tabla particionada «%s»" -#: catalog/heap.c:2336 +#: catalog/heap.c:2639 #, c-format msgid "check constraint \"%s\" already exists" msgstr "la restricción «check» «%s» ya existe" -#: catalog/heap.c:2504 catalog/pg_constraint.c:649 commands/tablecmds.c:6825 +#: catalog/heap.c:2809 catalog/index.c:833 catalog/pg_constraint.c:669 +#: commands/tablecmds.c:7322 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "la restricción «%s» para la relación «%s» ya existe" -#: catalog/heap.c:2511 +#: catalog/heap.c:2816 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "la restricción «%s» está en conflicto con la restricción no heredada de la relación «%s»" -#: catalog/heap.c:2522 +#: catalog/heap.c:2827 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "la restricción «%s» está en conflicto con la restricción heredada de la relación «%s»" -#: catalog/heap.c:2532 +#: catalog/heap.c:2837 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "la restricción «%s» está en conflicto con la restricción NOT VALID de la relación «%s»" -#: catalog/heap.c:2537 +#: catalog/heap.c:2842 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "mezclando la restricción «%s» con la definición heredada" -#: catalog/heap.c:2653 +#: catalog/heap.c:2944 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "no se puede usar la columna generada «%s» en una expresión de generación de columna" + +#: catalog/heap.c:2946 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "Una columna generada no puede hacer referencia a otra columna generada." + +#: catalog/heap.c:2998 #, c-format -msgid "cannot use column references in default expression" -msgstr "no se pueden usar referencias a columnas en una cláusula default" +msgid "generation expression is not immutable" +msgstr "la expresión de generación no es inmutable" -#: catalog/heap.c:2678 rewrite/rewriteHandler.c:1140 +#: catalog/heap.c:3026 rewrite/rewriteHandler.c:1189 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "la columna «%s» es de tipo %s pero la expresión default es de tipo %s" -#: catalog/heap.c:2683 commands/prepare.c:384 parser/parse_node.c:430 -#: parser/parse_target.c:590 parser/parse_target.c:840 -#: parser/parse_target.c:850 rewrite/rewriteHandler.c:1145 +#: catalog/heap.c:3031 commands/prepare.c:384 parser/parse_node.c:435 +#: parser/parse_target.c:591 parser/parse_target.c:866 +#: parser/parse_target.c:876 rewrite/rewriteHandler.c:1194 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Necesitará reescribir la expresión o aplicarle una conversión de tipo." -#: catalog/heap.c:2730 +#: catalog/heap.c:3078 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "sólo la tabla «%s» puede ser referenciada en una restricción «check»" -#: catalog/heap.c:2970 +#: catalog/heap.c:3328 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "combinación de ON COMMIT y llaves foráneas no soportada" -#: catalog/heap.c:2971 +#: catalog/heap.c:3329 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "La tabla «%s» se refiere a «%s», pero no tienen la misma expresión para ON COMMIT." -#: catalog/heap.c:2976 +#: catalog/heap.c:3334 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "no se puede truncar una tabla referida en una llave foránea" -#: catalog/heap.c:2977 +#: catalog/heap.c:3335 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "La tabla «%s» hace referencia a «%s»." -#: catalog/heap.c:2979 +#: catalog/heap.c:3337 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "Trunque la tabla «%s» al mismo tiempo, o utilice TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1670 parser/parse_utilcmd.c:1756 +#: catalog/index.c:219 parser/parse_utilcmd.c:1873 parser/parse_utilcmd.c:1972 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "no se permiten múltiples llaves primarias para la tabla «%s»" -#: catalog/index.c:228 +#: catalog/index.c:237 #, c-format msgid "primary keys cannot be expressions" msgstr "las llaves primarias no pueden ser expresiones" -#: catalog/index.c:757 catalog/index.c:1175 +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "columna de llave primaria «%s» no está marcada NOT NULL" + +#: catalog/index.c:763 catalog/index.c:1709 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "los usuarios no pueden crear índices en tablas del sistema" -#: catalog/index.c:767 +#: catalog/index.c:773 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "no se pueden crear índices de forma concurrente en tablas del sistema" -#: catalog/index.c:785 +#: catalog/index.c:791 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "no se pueden crear índices compartidos después de initdb" -#: catalog/index.c:799 commands/createas.c:250 commands/sequence.c:152 -#: parser/parse_utilcmd.c:200 +#: catalog/index.c:811 commands/createas.c:253 commands/sequence.c:154 +#: parser/parse_utilcmd.c:208 #, c-format msgid "relation \"%s\" already exists, skipping" -msgstr "la relación «%s» ya existe, ignorando" +msgstr "la relación «%s» ya existe, omitiendo" -#: catalog/index.c:835 +#: catalog/index.c:861 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "el valor de OID de índice de pg_class no se definió en modo de actualización binaria" -#: catalog/index.c:1436 +#: catalog/index.c:1985 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY debe ser la primera acción en una transacción" -#: catalog/index.c:2020 +#: catalog/index.c:2682 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "construyendo índice «%s» en la tabla «%s» en forma serial" + +#: catalog/index.c:2687 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "construyendo índice «%s» en la tabla «%s»" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "construyendo índice «%s» en la tabla «%s» solicitando %d ayudante paralelo" +msgstr[1] "construyendo índice «%s» en la tabla «%s» solicitando %d ayudantes paralelos" -#: catalog/index.c:3332 +#: catalog/index.c:3310 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "no se puede hacer reindex de tablas temporales de otras sesiones" -#: catalog/index.c:3463 +#: catalog/index.c:3441 #, c-format msgid "index \"%s\" was reindexed" msgstr "el índice «%s» fue reindexado" -#: catalog/namespace.c:235 catalog/namespace.c:433 catalog/namespace.c:527 -#: commands/trigger.c:4931 +#: catalog/index.c:3514 commands/indexcmds.c:2886 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX de tablas particionadas no está implementado aún, omitiendo «%s»" + +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 +#: commands/trigger.c:5396 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "no están implementadas las referencias entre bases de datos: «%s.%s.%s»" -#: catalog/namespace.c:292 +#: catalog/namespace.c:306 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "las tablas temporales no pueden especificar un nombre de esquema" -#: catalog/namespace.c:371 +#: catalog/namespace.c:387 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "no se pudo bloquear un candado en la relación «%s.%s»" -#: catalog/namespace.c:376 commands/lockcmds.c:145 +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:249 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "no se pudo bloquear un candado en la relación «%s»" -#: catalog/namespace.c:400 parser/parse_relation.c:1158 +#: catalog/namespace.c:420 parser/parse_relation.c:1172 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "no existe la relación «%s.%s»" -#: catalog/namespace.c:405 parser/parse_relation.c:1177 -#: parser/parse_relation.c:1185 +#: catalog/namespace.c:425 parser/parse_relation.c:1185 +#: parser/parse_relation.c:1193 #, c-format msgid "relation \"%s\" does not exist" msgstr "no existe la relación «%s»" -#: catalog/namespace.c:473 catalog/namespace.c:2992 commands/extension.c:1466 -#: commands/extension.c:1472 +#: catalog/namespace.c:491 catalog/namespace.c:3009 commands/extension.c:1469 +#: commands/extension.c:1475 #, c-format msgid "no schema has been selected to create in" msgstr "no se ha seleccionado ningún esquema dentro del cual crear" -#: catalog/namespace.c:625 catalog/namespace.c:638 +#: catalog/namespace.c:643 catalog/namespace.c:656 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "no se pueden crear relaciones en esquemas temporales de otras sesiones" -#: catalog/namespace.c:629 +#: catalog/namespace.c:647 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "no se pueden crear tablas temporales en esquemas no temporales" -#: catalog/namespace.c:644 +#: catalog/namespace.c:662 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "sólo relaciones temporales pueden ser creadas en los esquemas temporales" -#: catalog/namespace.c:2182 -#, fuzzy, c-format +#: catalog/namespace.c:2201 +#, c-format msgid "statistics object \"%s\" does not exist" -msgstr "no existe la tabla «%s»" +msgstr "no existe el objeto de estadísticas «%s»" -#: catalog/namespace.c:2305 +#: catalog/namespace.c:2324 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "no existe el analizador de búsqueda en texto «%s»" -#: catalog/namespace.c:2431 +#: catalog/namespace.c:2450 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "no existe el diccionario de búsqueda en texto «%s»" -#: catalog/namespace.c:2558 +#: catalog/namespace.c:2577 #, c-format msgid "text search template \"%s\" does not exist" msgstr "no existe la plantilla de búsqueda en texto «%s»" -#: catalog/namespace.c:2684 commands/tsearchcmds.c:1185 -#: utils/cache/ts_cache.c:612 +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1197 +#: utils/cache/ts_cache.c:615 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "no existe la configuración de búsqueda en texto «%s»" -#: catalog/namespace.c:2797 parser/parse_expr.c:789 parser/parse_target.c:1192 +#: catalog/namespace.c:2816 parser/parse_expr.c:866 parser/parse_target.c:1221 #, c-format msgid "cross-database references are not implemented: %s" msgstr "no están implementadas las referencias entre bases de datos: %s" -#: catalog/namespace.c:2803 gram.y:14321 gram.y:15742 parser/parse_expr.c:796 -#: parser/parse_target.c:1199 +#: catalog/namespace.c:2822 parser/parse_expr.c:873 parser/parse_target.c:1228 +#: gram.y:14731 gram.y:16165 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "el nombre no es válido (demasiados puntos): %s" -#: catalog/namespace.c:2934 +#: catalog/namespace.c:2952 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "no se puede mover objetos hacia o desde esquemas temporales" -#: catalog/namespace.c:2940 +#: catalog/namespace.c:2958 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "no se puede mover objetos hacia o desde el esquema TOAST" -#: catalog/namespace.c:3013 commands/schemacmds.c:256 -#: commands/schemacmds.c:334 commands/tablecmds.c:891 +#: catalog/namespace.c:3031 commands/schemacmds.c:257 commands/schemacmds.c:337 +#: commands/tablecmds.c:1137 #, c-format msgid "schema \"%s\" does not exist" msgstr "no existe el esquema «%s»" -#: catalog/namespace.c:3044 +#: catalog/namespace.c:3062 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "el nombre de relación no es válido (demasiados puntos): %s" -#: catalog/namespace.c:3538 +#: catalog/namespace.c:3596 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "no existe el ordenamiento (collation) «%s» para la codificación «%s»" -#: catalog/namespace.c:3593 +#: catalog/namespace.c:3651 #, c-format msgid "conversion \"%s\" does not exist" msgstr "no existe la conversión «%s»" -#: catalog/namespace.c:3801 +#: catalog/namespace.c:3891 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "se ha denegado el permiso para crear tablas temporales en la base de datos «%s»" -#: catalog/namespace.c:3817 +#: catalog/namespace.c:3907 #, c-format msgid "cannot create temporary tables during recovery" msgstr "no se pueden crear tablas temporales durante la recuperación" -#: catalog/namespace.c:3823 -#, fuzzy, c-format -#| msgid "cannot access temporary tables during a parallel operation" +#: catalog/namespace.c:3913 +#, c-format msgid "cannot create temporary tables during a parallel operation" -msgstr "no se pueden acceder tablas temporales durante una operación paralela" +msgstr "no se pueden crear tablas temporales durante una operación paralela" -#: catalog/namespace.c:4072 commands/tablespace.c:1169 commands/variable.c:64 -#: utils/misc/guc.c:9979 utils/misc/guc.c:10057 +#: catalog/namespace.c:4196 commands/tablespace.c:1186 commands/variable.c:64 +#: utils/misc/guc.c:10900 utils/misc/guc.c:10978 #, c-format msgid "List syntax is invalid." msgstr "La sintaxis de lista no es válida." -#: catalog/objectaddress.c:1237 catalog/pg_publication.c:66 -#: commands/lockcmds.c:93 commands/policy.c:94 commands/policy.c:391 -#: commands/policy.c:481 commands/tablecmds.c:223 commands/tablecmds.c:265 -#: commands/tablecmds.c:1507 commands/tablecmds.c:4722 -#: commands/tablecmds.c:8810 +#: catalog/objectaddress.c:1274 catalog/pg_publication.c:66 +#: commands/policy.c:95 commands/policy.c:395 commands/policy.c:485 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 commands/tablecmds.c:1899 +#: commands/tablecmds.c:5148 commands/tablecmds.c:10333 #, c-format msgid "\"%s\" is not a table" msgstr "«%s» no es una tabla" -#: catalog/objectaddress.c:1244 commands/tablecmds.c:235 -#: commands/tablecmds.c:4752 commands/tablecmds.c:13085 commands/view.c:141 +#: catalog/objectaddress.c:1281 commands/tablecmds.c:236 +#: commands/tablecmds.c:5178 commands/tablecmds.c:14780 commands/view.c:138 #, c-format msgid "\"%s\" is not a view" msgstr "«%s» no es una vista" -#: catalog/objectaddress.c:1251 commands/matview.c:174 -#: commands/tablecmds.c:241 commands/tablecmds.c:13090 +#: catalog/objectaddress.c:1288 commands/matview.c:175 commands/tablecmds.c:242 +#: commands/tablecmds.c:14785 #, c-format msgid "\"%s\" is not a materialized view" msgstr "«%s» no es una vista materializada" -#: catalog/objectaddress.c:1258 commands/tablecmds.c:259 -#: commands/tablecmds.c:4755 commands/tablecmds.c:13095 +#: catalog/objectaddress.c:1295 commands/tablecmds.c:260 +#: commands/tablecmds.c:5181 commands/tablecmds.c:14790 #, c-format msgid "\"%s\" is not a foreign table" msgstr "«%s» no es una tabla foránea" -#: catalog/objectaddress.c:1299 -#, fuzzy, c-format +#: catalog/objectaddress.c:1336 +#, c-format msgid "must specify relation and object name" -msgstr "%s debe especificar nombres de relaciones sin calificar" +msgstr "debe especificar nombre de relación y nombre de objeto" -#: catalog/objectaddress.c:1375 catalog/objectaddress.c:1428 +#: catalog/objectaddress.c:1412 catalog/objectaddress.c:1465 #, c-format msgid "column name must be qualified" msgstr "el nombre de columna debe ser calificado" -#: catalog/objectaddress.c:1471 +#: catalog/objectaddress.c:1512 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "no existe el valor por omisión para la columna «%s» de la relación «%s»" -#: catalog/objectaddress.c:1508 commands/functioncmds.c:128 -#: commands/tablecmds.c:251 commands/typecmds.c:3233 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:794 utils/adt/acl.c:4357 +#: catalog/objectaddress.c:1549 commands/functioncmds.c:132 +#: commands/tablecmds.c:252 commands/typecmds.c:3321 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4451 #, c-format msgid "type \"%s\" does not exist" msgstr "no existe el tipo «%s»" -#: catalog/objectaddress.c:1625 +#: catalog/objectaddress.c:1668 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "no existe el operador %d (%s, %s) de %s" -#: catalog/objectaddress.c:1656 +#: catalog/objectaddress.c:1699 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "no existe la función %d (%s, %s) de %s" -#: catalog/objectaddress.c:1707 catalog/objectaddress.c:1733 +#: catalog/objectaddress.c:1750 catalog/objectaddress.c:1776 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "no existe el mapeo para el usuario «%s» en el servidor «%s»" -#: catalog/objectaddress.c:1722 commands/foreigncmds.c:428 -#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1377 -#: foreign/foreign.c:688 +#: catalog/objectaddress.c:1765 commands/foreigncmds.c:433 +#: commands/foreigncmds.c:1016 commands/foreigncmds.c:1396 +#: foreign/foreign.c:723 #, c-format msgid "server \"%s\" does not exist" msgstr "no existe el servidor «%s»" -#: catalog/objectaddress.c:1789 -#, fuzzy, c-format +#: catalog/objectaddress.c:1832 +#, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" -msgstr "no existe la restricción «%s» en la relación «%s»" +msgstr "no existe la relación «%s» en la publicación «%s»" -#: catalog/objectaddress.c:1851 -#, fuzzy, c-format -#| msgid "unrecognized default ACL object type %c" +#: catalog/objectaddress.c:1894 +#, c-format msgid "unrecognized default ACL object type \"%c\"" -msgstr "tipo de objeto %c para ACL por omisión no reconocido" +msgstr "tipo de objeto para ACL por omisión «%c» no reconocido" -#: catalog/objectaddress.c:1852 -#, fuzzy, c-format +#: catalog/objectaddress.c:1895 +#, c-format msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." -msgstr "Tipos válidos de objeto son «t», «S», «f» y «T»." +msgstr "Tipos válidos de objeto son «%c», «%c», «%c», «%c» y «%c»." -#: catalog/objectaddress.c:1903 +#: catalog/objectaddress.c:1946 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "no existe el ACL por omisión para el usuario «%s» en el esquema «%s» en %s" -#: catalog/objectaddress.c:1908 +#: catalog/objectaddress.c:1951 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "no existe el ACL por omisión para el usuario «%s» en %s" -#: catalog/objectaddress.c:1935 catalog/objectaddress.c:1993 -#: catalog/objectaddress.c:2048 +#: catalog/objectaddress.c:1978 catalog/objectaddress.c:2036 +#: catalog/objectaddress.c:2093 #, c-format msgid "name or argument lists may not contain nulls" msgstr "las listas de nombres o argumentos no pueden contener nulls" -#: catalog/objectaddress.c:1969 +#: catalog/objectaddress.c:2012 #, c-format msgid "unsupported object type \"%s\"" msgstr "tipo de objeto «%s» no soportado" -#: catalog/objectaddress.c:1989 catalog/objectaddress.c:2007 -#: catalog/objectaddress.c:2145 +#: catalog/objectaddress.c:2032 catalog/objectaddress.c:2050 +#: catalog/objectaddress.c:2191 #, c-format msgid "name list length must be exactly %d" msgstr "el largo de la lista de nombres debe ser exactamente %d" -#: catalog/objectaddress.c:2011 +#: catalog/objectaddress.c:2054 #, c-format msgid "large object OID may not be null" msgstr "el OID de objeto grande no puede ser null" -#: catalog/objectaddress.c:2020 catalog/objectaddress.c:2081 -#: catalog/objectaddress.c:2088 +#: catalog/objectaddress.c:2063 catalog/objectaddress.c:2126 +#: catalog/objectaddress.c:2133 #, c-format msgid "name list length must be at least %d" msgstr "el largo de la lista de nombres debe ser al menos %d" -#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2094 +#: catalog/objectaddress.c:2119 catalog/objectaddress.c:2140 #, c-format msgid "argument list length must be exactly %d" msgstr "el largo de la lista de argumentos debe ser exactamente %d" -#: catalog/objectaddress.c:2320 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2370 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "debe ser dueño del objeto grande %u" -#: catalog/objectaddress.c:2335 commands/functioncmds.c:1440 +#: catalog/objectaddress.c:2385 commands/functioncmds.c:1535 #, c-format msgid "must be owner of type %s or type %s" msgstr "debe ser dueño del tipo %s o el tipo %s" -#: catalog/objectaddress.c:2385 catalog/objectaddress.c:2402 +#: catalog/objectaddress.c:2435 catalog/objectaddress.c:2452 #, c-format msgid "must be superuser" msgstr "debe ser superusuario" -#: catalog/objectaddress.c:2392 +#: catalog/objectaddress.c:2442 #, c-format msgid "must have CREATEROLE privilege" msgstr "debe tener privilegio CREATEROLE" -#: catalog/objectaddress.c:2471 +#: catalog/objectaddress.c:2521 #, c-format msgid "unrecognized object type \"%s\"" msgstr "tipo de objeto «%s» no reconocido" -#: catalog/objectaddress.c:2666 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2742 #, c-format -msgid " column %s" -msgstr " columna %s" +msgid "column %s of %s" +msgstr " columna %s de %s" -#: catalog/objectaddress.c:2672 +#: catalog/objectaddress.c:2752 #, c-format msgid "function %s" msgstr "función %s" -#: catalog/objectaddress.c:2677 +#: catalog/objectaddress.c:2757 #, c-format msgid "type %s" msgstr "tipo %s" -#: catalog/objectaddress.c:2707 +#: catalog/objectaddress.c:2787 #, c-format msgid "cast from %s to %s" msgstr "conversión de %s a %s" -#: catalog/objectaddress.c:2727 +#: catalog/objectaddress.c:2815 #, c-format msgid "collation %s" msgstr "ordenamiento (collation) %s" -#: catalog/objectaddress.c:2751 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2841 #, c-format msgid "constraint %s on %s" msgstr "restricción «%s» en %s" -#: catalog/objectaddress.c:2757 +#: catalog/objectaddress.c:2847 #, c-format msgid "constraint %s" msgstr "restricción %s" -#: catalog/objectaddress.c:2774 +#: catalog/objectaddress.c:2874 #, c-format msgid "conversion %s" msgstr "conversión %s" -#: catalog/objectaddress.c:2811 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2913 #, c-format -msgid "default for %s" +msgid "default value for %s" msgstr "valor por omisión para %s" -#: catalog/objectaddress.c:2820 +#: catalog/objectaddress.c:2922 #, c-format msgid "language %s" msgstr "lenguaje %s" -#: catalog/objectaddress.c:2825 +#: catalog/objectaddress.c:2927 #, c-format msgid "large object %u" msgstr "objeto grande %u" -#: catalog/objectaddress.c:2830 +#: catalog/objectaddress.c:2932 #, c-format msgid "operator %s" msgstr "operador %s" -#: catalog/objectaddress.c:2862 +#: catalog/objectaddress.c:2964 #, c-format msgid "operator class %s for access method %s" msgstr "clase de operadores «%s» para el método de acceso «%s»" -#: catalog/objectaddress.c:2885 +#: catalog/objectaddress.c:2987 #, c-format msgid "access method %s" msgstr "método de acceso %s" @@ -4203,7 +4411,7 @@ msgstr "método de acceso %s" #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2927 +#: catalog/objectaddress.c:3029 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "operador %d (%s, %s) de %s: %s" @@ -4212,361 +4420,401 @@ msgstr "operador %d (%s, %s) de %s: %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2977 +#: catalog/objectaddress.c:3079 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "función %d (%s, %s) de %s: %s" -#: catalog/objectaddress.c:3017 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3123 #, c-format -msgid "rule %s on " -msgstr "regla «%s» en " +msgid "rule %s on %s" +msgstr "regla %s en %s" -#: catalog/objectaddress.c:3052 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3161 #, c-format -msgid "trigger %s on " -msgstr "disparador %s en " +msgid "trigger %s on %s" +msgstr "disparador %s en %s" -#: catalog/objectaddress.c:3069 +#: catalog/objectaddress.c:3177 #, c-format msgid "schema %s" msgstr "esquema %s" -#: catalog/objectaddress.c:3086 -#, fuzzy, c-format +#: catalog/objectaddress.c:3200 +#, c-format msgid "statistics object %s" -msgstr "recolector de estadísticas" +msgstr "object de estadísticas %s" -#: catalog/objectaddress.c:3102 +#: catalog/objectaddress.c:3227 #, c-format msgid "text search parser %s" msgstr "analizador de búsqueda en texto %s" -#: catalog/objectaddress.c:3117 +#: catalog/objectaddress.c:3253 #, c-format msgid "text search dictionary %s" msgstr "diccionario de búsqueda en texto %s" -#: catalog/objectaddress.c:3132 +#: catalog/objectaddress.c:3279 #, c-format msgid "text search template %s" msgstr "plantilla de búsqueda en texto %s" -#: catalog/objectaddress.c:3147 +#: catalog/objectaddress.c:3305 #, c-format msgid "text search configuration %s" msgstr "configuración de búsqueda en texto %s" -#: catalog/objectaddress.c:3155 +#: catalog/objectaddress.c:3314 #, c-format msgid "role %s" msgstr "rol %s" -#: catalog/objectaddress.c:3168 +#: catalog/objectaddress.c:3327 #, c-format msgid "database %s" msgstr "base de datos %s" -#: catalog/objectaddress.c:3180 +#: catalog/objectaddress.c:3339 #, c-format msgid "tablespace %s" msgstr "tablespace %s" -#: catalog/objectaddress.c:3189 +#: catalog/objectaddress.c:3348 #, c-format msgid "foreign-data wrapper %s" msgstr "conector de datos externos %s" -#: catalog/objectaddress.c:3198 +#: catalog/objectaddress.c:3357 #, c-format msgid "server %s" msgstr "servidor %s" -#: catalog/objectaddress.c:3226 +#: catalog/objectaddress.c:3385 #, c-format msgid "user mapping for %s on server %s" msgstr "mapeo para el usuario %s en el servidor %s" -#: catalog/objectaddress.c:3261 +#: catalog/objectaddress.c:3430 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas relaciones pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3434 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "privilegios por omisión en nuevas relaciones pertenecientes al rol %s" -#: catalog/objectaddress.c:3266 +#: catalog/objectaddress.c:3440 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas secuencias pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3444 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "privilegios por omisión en nuevas secuencias pertenecientes al rol %s" -#: catalog/objectaddress.c:3271 +#: catalog/objectaddress.c:3450 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevas funciones pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3454 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "privilegios por omisión en nuevas funciones pertenecientes al rol %s" -#: catalog/objectaddress.c:3276 +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "privilegios por omisión en nuevos tipos pertenecientes al rol %s en el esquema %s" + +#: catalog/objectaddress.c:3464 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "privilegios por omisión en nuevos tipos pertenecientes al rol %s" -#: catalog/objectaddress.c:3281 -#, fuzzy, c-format +#: catalog/objectaddress.c:3470 +#, c-format msgid "default privileges on new schemas belonging to role %s" -msgstr "privilegios por omisión en nuevas secuencias pertenecientes al rol %s" +msgstr "privilegios por omisión en nuevos esquemas pertenecientes al rol %s" -#: catalog/objectaddress.c:3287 +#: catalog/objectaddress.c:3477 #, c-format -msgid "default privileges belonging to role %s" -msgstr "privilegios por omisión pertenecientes al rol %s" +msgid "default privileges belonging to role %s in schema %s" +msgstr "privilegios por omisión pertenecientes al rol %s en el esquema %s" -#: catalog/objectaddress.c:3295 +#: catalog/objectaddress.c:3481 #, c-format -msgid " in schema %s" -msgstr " en esquema %s" +msgid "default privileges belonging to role %s" +msgstr "privilegios por omisión pertenecientes al rol %s" -#: catalog/objectaddress.c:3312 +#: catalog/objectaddress.c:3499 #, c-format msgid "extension %s" msgstr "extensión %s" -#: catalog/objectaddress.c:3325 +#: catalog/objectaddress.c:3512 #, c-format msgid "event trigger %s" msgstr "disparador por eventos %s" -#: catalog/objectaddress.c:3357 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3548 #, c-format -msgid "policy %s on " -msgstr "política «%s» en " +msgid "policy %s on %s" +msgstr "política %s en %s" -#: catalog/objectaddress.c:3368 -#, fuzzy, c-format +#: catalog/objectaddress.c:3558 +#, c-format msgid "publication %s" -msgstr "relación %s" +msgstr "publicación %s" -#: catalog/objectaddress.c:3388 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3584 #, c-format -msgid "publication table %s in publication %s" -msgstr "" +msgid "publication of %s in publication %s" +msgstr "publicación de %s en la publicación %s" -#: catalog/objectaddress.c:3396 -#, fuzzy, c-format +#: catalog/objectaddress.c:3593 +#, c-format msgid "subscription %s" -msgstr "función %s" +msgstr "suscripción %s" -#: catalog/objectaddress.c:3414 +#: catalog/objectaddress.c:3612 #, c-format msgid "transform for %s language %s" msgstr "transformación para %s lenguaje %s" -#: catalog/objectaddress.c:3475 +#: catalog/objectaddress.c:3675 #, c-format msgid "table %s" msgstr "tabla %s" -#: catalog/objectaddress.c:3479 +#: catalog/objectaddress.c:3680 #, c-format msgid "index %s" msgstr "índice %s" -#: catalog/objectaddress.c:3483 +#: catalog/objectaddress.c:3684 #, c-format msgid "sequence %s" msgstr "secuencia %s" -#: catalog/objectaddress.c:3487 +#: catalog/objectaddress.c:3688 #, c-format msgid "toast table %s" msgstr "tabla toast %s" -#: catalog/objectaddress.c:3491 +#: catalog/objectaddress.c:3692 #, c-format msgid "view %s" msgstr "vista %s" -#: catalog/objectaddress.c:3495 +#: catalog/objectaddress.c:3696 #, c-format msgid "materialized view %s" msgstr "vista materializada %s" -#: catalog/objectaddress.c:3499 +#: catalog/objectaddress.c:3700 #, c-format msgid "composite type %s" msgstr "tipo compuesto %s" -#: catalog/objectaddress.c:3503 +#: catalog/objectaddress.c:3704 #, c-format msgid "foreign table %s" msgstr "tabla foránea %s" -#: catalog/objectaddress.c:3508 +#: catalog/objectaddress.c:3709 #, c-format msgid "relation %s" msgstr "relación %s" -#: catalog/objectaddress.c:3545 +#: catalog/objectaddress.c:3746 #, c-format msgid "operator family %s for access method %s" msgstr "familia de operadores %s para el método de acceso %s" -#: catalog/objectaddress.c:4914 -#, c-format -msgid "%s in publication %s" -msgstr "" - -#: catalog/partition.c:742 -#, fuzzy, c-format -msgid "cannot create range partition with empty range" -msgstr "no se pudo determinar el tipo de dato de transición" - -#: catalog/partition.c:836 -#, fuzzy, c-format -msgid "partition \"%s\" would overlap partition \"%s\"" -msgstr "relación «%s» no es un padre de la relación «%s»" - -#: catalog/partition.c:945 catalog/partition.c:1123 commands/analyze.c:1446 -#: commands/copy.c:1466 commands/tablecmds.c:8872 -#: executor/execExprInterp.c:2837 executor/execMain.c:1878 -#: executor/execMain.c:1955 executor/execMain.c:2002 executor/execMain.c:3270 -#: executor/nodeModifyTable.c:1518 +#: catalog/partition.c:214 commands/analyze.c:1353 commands/indexcmds.c:1092 +#: commands/tablecmds.c:1068 commands/tablecmds.c:8120 +#: commands/tablecmds.c:8263 commands/tablecmds.c:8454 +#: commands/tablecmds.c:8591 commands/tablecmds.c:10395 +#: commands/tablecmds.c:15687 commands/tablecmds.c:16242 +#: executor/execExprInterp.c:3303 executor/execMain.c:1865 +#: executor/execMain.c:1951 executor/execMain.c:2001 executor/execMain.c:2109 +#: executor/execPartition.c:590 executor/execPartition.c:650 +#: executor/execPartition.c:794 executor/execPartition.c:908 +#: executor/execPartition.c:941 executor/execPartition.c:1046 +#: executor/nodeModifyTable.c:1963 msgid "could not convert row type" msgstr "no se pudo convertir el tipo de registro" -#: catalog/pg_aggregate.c:125 +#: catalog/pg_aggregate.c:129 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "las funciones de agregación no pueden tener más de %d argumento" msgstr[1] "las funciones de agregación no pueden tener más de %d argumentos" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:152 catalog/pg_aggregate.c:162 #, c-format msgid "cannot determine transition data type" msgstr "no se pudo determinar el tipo de dato de transición" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:153 catalog/pg_aggregate.c:163 #, c-format msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." msgstr "Una función de agregación que use un tipo de dato de transición polimórfico debe tener al menos un argumento de tipo polimórfico." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:176 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "una función de agregación variádica de conjuntos ordenados debe ser de tipo VARIADIC ANY" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:202 #, c-format msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "la función de agregación de conjunto hipotético debe tener argumentos directos que coincidan con los argumentos agregados" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:249 catalog/pg_aggregate.c:293 #, c-format msgid "return type of transition function %s is not %s" msgstr "el tipo de retorno de la función de transición %s no es %s" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:269 catalog/pg_aggregate.c:312 #, c-format msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "no se puede omitir el valor inicial cuando la función de transición es «strict» y el tipo de transición no es compatible con el tipo de entrada" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:338 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "el tipo de retorno de la función inversa de transición %s no es %s" -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2294 +#: catalog/pg_aggregate.c:355 executor/nodeWindowAgg.c:2851 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "la opción «strict» de las funciones de transición directa e inversa deben coincidir exactamente en la función de agregación" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:399 catalog/pg_aggregate.c:552 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "la función final con argumentos extra no debe declararse STRICT" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:430 #, c-format msgid "return type of combine function %s is not %s" msgstr "el tipo de retorno de la función «combine» %s no es %s" -#: catalog/pg_aggregate.c:436 -#, fuzzy, c-format -#| msgid "combine function with \"%s\" transition type must not be declared STRICT" +#: catalog/pg_aggregate.c:442 executor/nodeAgg.c:2973 +#, c-format msgid "combine function with transition type %s must not be declared STRICT" msgstr "la función «combine» con tipo de transición %s no debe declararse STRICT" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:461 #, c-format msgid "return type of serialization function %s is not %s" msgstr "el tipo de retorno de la función de serialización %s no es %s" -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:482 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "el tipo de retorno de la función de deserialización %s no es %s" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:243 catalog/pg_proc.c:250 +#: catalog/pg_aggregate.c:498 catalog/pg_proc.c:243 catalog/pg_proc.c:250 #, c-format msgid "cannot determine result data type" msgstr "no se puede determinar el tipo de dato del resultado" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:499 #, c-format msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." msgstr "Una función de agregación que retorne un tipo de datos polimórfico debe tener al menos un argumento de tipo polimórfico." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:256 +#: catalog/pg_aggregate.c:511 catalog/pg_proc.c:256 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "uso inseguro de pseudotipo «internal»" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:257 +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:257 #, c-format msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgstr "Una función que retorne «internal» debe tener al menos un argumento de tipo «internal»." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:565 #, c-format msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "la implementación de la función de agregación en modo «moving» devuelve tipo de dato %s, pero la implementación normal devuelve tipo de dato %s" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:576 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "el operador de ordenamiento sólo puede ser especificado para funciones de agregación de un solo argumento" -#: catalog/pg_aggregate.c:810 commands/typecmds.c:1698 -#: commands/typecmds.c:1749 commands/typecmds.c:1780 commands/typecmds.c:1803 -#: commands/typecmds.c:1824 commands/typecmds.c:1851 commands/typecmds.c:1878 -#: commands/typecmds.c:1955 commands/typecmds.c:1997 parser/parse_func.c:369 -#: parser/parse_func.c:398 parser/parse_func.c:423 parser/parse_func.c:437 -#: parser/parse_func.c:512 parser/parse_func.c:523 parser/parse_func.c:1977 +#: catalog/pg_aggregate.c:703 catalog/pg_proc.c:396 +#, c-format +msgid "cannot change routine kind" +msgstr "no se puede cambiar el tipo de rutina" + +#: catalog/pg_aggregate.c:705 +#, c-format +msgid "\"%s\" is an ordinary aggregate function." +msgstr "«%s» es una función de agregación corriente." + +#: catalog/pg_aggregate.c:707 +#, c-format +msgid "\"%s\" is an ordered-set aggregate." +msgstr "«%s» es una función de agregación de conjunto ordenado." + +#: catalog/pg_aggregate.c:709 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "«%s» es una agregación de conjunto hipotético." + +#: catalog/pg_aggregate.c:714 +#, c-format +msgid "cannot change number of direct args of an aggregate function" +msgstr "no se puede cambiar cantidad de argumentos directos de una función de agregación" + +#: catalog/pg_aggregate.c:869 commands/functioncmds.c:665 +#: commands/typecmds.c:1751 commands/typecmds.c:1802 commands/typecmds.c:1833 +#: commands/typecmds.c:1856 commands/typecmds.c:1877 commands/typecmds.c:1904 +#: commands/typecmds.c:1931 commands/typecmds.c:2008 commands/typecmds.c:2050 +#: parser/parse_func.c:418 parser/parse_func.c:447 parser/parse_func.c:472 +#: parser/parse_func.c:486 parser/parse_func.c:606 parser/parse_func.c:626 +#: parser/parse_func.c:2139 parser/parse_func.c:2330 #, c-format msgid "function %s does not exist" msgstr "no existe la función %s" -#: catalog/pg_aggregate.c:816 +#: catalog/pg_aggregate.c:875 #, c-format msgid "function %s returns a set" msgstr "la función %s retorna un conjunto" -#: catalog/pg_aggregate.c:831 +#: catalog/pg_aggregate.c:890 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "la función %s debe aceptar VARIADIC ANY para usarse en esta agregación" -#: catalog/pg_aggregate.c:855 +#: catalog/pg_aggregate.c:914 #, c-format msgid "function %s requires run-time type coercion" msgstr "la función %s requiere conversión de tipos en tiempo de ejecución" #: catalog/pg_collation.c:93 catalog/pg_collation.c:140 -#, fuzzy, c-format +#, c-format msgid "collation \"%s\" already exists, skipping" -msgstr "la relación «%s» ya existe, ignorando" +msgstr "el ordenamiento «%s» ya existe, omitiendo" #: catalog/pg_collation.c:95 -#, fuzzy, c-format +#, c-format msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" -msgstr "la codificación «%2$s» ya tiene un ordenamiento llamado «%1$s»" +msgstr "el ordenamiento «%s» para la codificación «%s» ya existe, omitiendo" #: catalog/pg_collation.c:103 catalog/pg_collation.c:147 #, c-format @@ -4578,154 +4826,142 @@ msgstr "el ordenamiento «%s» ya existe" msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "la codificación «%2$s» ya tiene un ordenamiento llamado «%1$s»" -#: catalog/pg_constraint.c:658 +#: catalog/pg_constraint.c:677 #, c-format msgid "constraint \"%s\" for domain %s already exists" msgstr "el dominio %2$s ya contiene una restricción llamada «%1$s»" -#: catalog/pg_constraint.c:788 -#, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "hay múltiples restricciones llamadas «%2$s» en la tabla «%1$s»" - -#: catalog/pg_constraint.c:800 +#: catalog/pg_constraint.c:875 catalog/pg_constraint.c:968 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "no existe la restricción «%s» para la tabla «%s»" -#: catalog/pg_constraint.c:846 -#, fuzzy, c-format -#| msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgid "domain %s has multiple constraints named \"%s\"" -msgstr "hay múltiples restricciones llamadas «%2$s» en el dominio «%1$s»" - -#: catalog/pg_constraint.c:858 -#, fuzzy, c-format -#| msgid "constraint \"%s\" for domain \"%s\" does not exist" +#: catalog/pg_constraint.c:1057 +#, c-format msgid "constraint \"%s\" for domain %s does not exist" -msgstr "no existe la restricción «%s» para el dominio «%s»" +msgstr "no existe la restricción «%s» para el dominio %s" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:67 #, c-format msgid "conversion \"%s\" already exists" msgstr "ya existe la conversión «%s»" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:80 #, c-format msgid "default conversion for %s to %s already exists" msgstr "ya existe una conversión por omisión desde %s a %s" -#: catalog/pg_depend.c:163 commands/extension.c:3218 +#: catalog/pg_depend.c:162 commands/extension.c:3229 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "«%s» ya es un miembro de la extensión «%s»" -#: catalog/pg_depend.c:322 +#: catalog/pg_depend.c:489 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "no se puede eliminar dependencia a %s porque es un objeto requerido por el sistema" -#: catalog/pg_enum.c:115 catalog/pg_enum.c:201 catalog/pg_enum.c:488 +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 #, c-format msgid "invalid enum label \"%s\"" msgstr "la etiqueta enum «%s» no es válida" -#: catalog/pg_enum.c:116 catalog/pg_enum.c:202 catalog/pg_enum.c:489 +#: catalog/pg_enum.c:129 catalog/pg_enum.c:232 catalog/pg_enum.c:527 #, c-format msgid "Labels must be %d characters or less." msgstr "Las etiquetas deben ser de %d caracteres o menos." -#: catalog/pg_enum.c:230 +#: catalog/pg_enum.c:260 #, c-format msgid "enum label \"%s\" already exists, skipping" -msgstr "la etiqueta de enum «%s» ya existe, ignorando" +msgstr "la etiqueta de enum «%s» ya existe, omitiendo" -#: catalog/pg_enum.c:237 catalog/pg_enum.c:532 +#: catalog/pg_enum.c:267 catalog/pg_enum.c:570 #, c-format msgid "enum label \"%s\" already exists" msgstr "la etiqueta de enum «%s» ya existe" -#: catalog/pg_enum.c:292 catalog/pg_enum.c:527 +#: catalog/pg_enum.c:322 catalog/pg_enum.c:565 #, c-format msgid "\"%s\" is not an existing enum label" msgstr "«%s» no es una etiqueta de enum existente" -#: catalog/pg_enum.c:350 +#: catalog/pg_enum.c:380 #, c-format msgid "pg_enum OID value not set when in binary upgrade mode" msgstr "el valor de OID de pg_enum no se definió en modo de actualización binaria" -#: catalog/pg_enum.c:360 +#: catalog/pg_enum.c:390 #, c-format msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" msgstr "ALTER TYPE ADD BEFORE/AFTER es incompatible con la actualización binaria" -#: catalog/pg_namespace.c:63 commands/schemacmds.c:264 +#: catalog/pg_namespace.c:64 commands/schemacmds.c:266 #, c-format msgid "schema \"%s\" already exists" msgstr "ya existe el esquema «%s»" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:358 +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "«%s» no es un nombre válido de operador" -#: catalog/pg_operator.c:367 +#: catalog/pg_operator.c:370 #, c-format msgid "only binary operators can have commutators" msgstr "sólo los operadores binarios pueden tener conmutadores" -#: catalog/pg_operator.c:371 commands/operatorcmds.c:482 +#: catalog/pg_operator.c:374 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "sólo los operadores binarios pueden tener selectividad de join" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can merge join" msgstr "sólo los operadores binarios pueden ser usados en merge join" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:382 #, c-format msgid "only binary operators can hash" msgstr "sólo los operadores binarios pueden ser usados en hash" -#: catalog/pg_operator.c:390 +#: catalog/pg_operator.c:393 #, c-format msgid "only boolean operators can have negators" msgstr "sólo los operadores booleanos pueden tener negadores" -#: catalog/pg_operator.c:394 commands/operatorcmds.c:490 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "sólo los operadores booleanos pueden tener selectividad de restricción" -#: catalog/pg_operator.c:398 commands/operatorcmds.c:494 +#: catalog/pg_operator.c:401 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "sólo los operadores booleanos pueden tener selectividad de join" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can merge join" msgstr "sólo los operadores booleanos pueden ser usados en merge join" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:409 #, c-format msgid "only boolean operators can hash" msgstr "sólo los operadores booleanos pueden ser usados en hash" -#: catalog/pg_operator.c:418 +#: catalog/pg_operator.c:421 #, c-format msgid "operator %s already exists" msgstr "ya existe un operador %s" -#: catalog/pg_operator.c:612 +#: catalog/pg_operator.c:621 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "un operador no puede ser su propio negador u operador de ordenamiento" -#: catalog/pg_proc.c:131 parser/parse_func.c:2001 parser/parse_func.c:2041 +#: catalog/pg_proc.c:131 parser/parse_func.c:2201 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" @@ -4742,139 +4978,143 @@ msgstr "Una función que retorne un tipo polimórfico debe tener al menos un arg msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." msgstr "Una función que retorne «anyrange» debe tener al menos un argumento de tipo «anyrange»." -#: catalog/pg_proc.c:269 +#: catalog/pg_proc.c:386 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "ya existe una función «%s» con los mismos argumentos" + +#: catalog/pg_proc.c:398 #, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "«%s» ya es un atributo de tipo %s" +msgid "\"%s\" is an aggregate function." +msgstr "«%s» es una función de agregación." #: catalog/pg_proc.c:400 #, c-format -msgid "function \"%s\" already exists with same argument types" -msgstr "ya existe una función «%s» con los mismos argumentos" +msgid "\"%s\" is a function." +msgstr "«%s» es una función de agregación." + +#: catalog/pg_proc.c:402 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "«%s» es un índice parcial." + +#: catalog/pg_proc.c:404 +#, c-format +msgid "\"%s\" is a window function." +msgstr "«%s» es una función de ventana deslizante." -#: catalog/pg_proc.c:414 catalog/pg_proc.c:437 +#: catalog/pg_proc.c:424 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "no se puede cambiar que un procedimiento tenga parámetros de salida" + +#: catalog/pg_proc.c:425 catalog/pg_proc.c:455 #, c-format msgid "cannot change return type of existing function" msgstr "no se puede cambiar el tipo de retorno de una función existente" -#: catalog/pg_proc.c:415 catalog/pg_proc.c:439 catalog/pg_proc.c:482 -#: catalog/pg_proc.c:506 catalog/pg_proc.c:532 +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:431 catalog/pg_proc.c:458 catalog/pg_proc.c:503 +#: catalog/pg_proc.c:529 catalog/pg_proc.c:557 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "Use DROP FUNCTION %s primero." +msgid "Use %s %s first." +msgstr "Use %s %s primero." -#: catalog/pg_proc.c:438 +#: catalog/pg_proc.c:456 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "Tipo de registro definido por parámetros OUT es diferente." -#: catalog/pg_proc.c:480 +#: catalog/pg_proc.c:500 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "no se puede cambiar el nombre del parámetro de entrada «%s»" -#: catalog/pg_proc.c:505 +#: catalog/pg_proc.c:527 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "no se puede eliminar el valor por omisión de funciones existentes" -#: catalog/pg_proc.c:531 +#: catalog/pg_proc.c:555 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "no se puede cambiar el tipo de dato del valor por omisión de un parámetro" -#: catalog/pg_proc.c:544 -#, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "la función «%s» es una función de agregación" - -#: catalog/pg_proc.c:549 -#, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "la función «%s» no es una función de agregación" - -#: catalog/pg_proc.c:557 -#, c-format -msgid "function \"%s\" is a window function" -msgstr "la función %s es de tipo window" - -#: catalog/pg_proc.c:562 -#, c-format -msgid "function \"%s\" is not a window function" -msgstr "la función «%s» no es de tipo window" - -#: catalog/pg_proc.c:768 +#: catalog/pg_proc.c:772 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "no hay ninguna función interna llamada «%s»" -#: catalog/pg_proc.c:866 +#: catalog/pg_proc.c:870 #, c-format msgid "SQL functions cannot return type %s" msgstr "las funciones SQL no pueden retornar el tipo %s" -#: catalog/pg_proc.c:881 +#: catalog/pg_proc.c:885 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "las funciones SQL no pueden tener argumentos de tipo %s" -#: catalog/pg_proc.c:968 executor/functions.c:1429 +#: catalog/pg_proc.c:973 executor/functions.c:1423 #, c-format msgid "SQL function \"%s\"" msgstr "función SQL «%s»" -#: catalog/pg_publication.c:57 commands/trigger.c:196 -#, fuzzy, c-format +#: catalog/pg_publication.c:57 commands/trigger.c:238 commands/trigger.c:256 +#, c-format msgid "\"%s\" is a partitioned table" -msgstr "«%s» es un índice parcial" +msgstr "«%s» es una tabla particionada" #: catalog/pg_publication.c:59 -#, fuzzy, c-format +#, c-format msgid "Adding partitioned tables to publications is not supported." -msgstr "la creación de índices en columnas de sistema no está soportada" +msgstr "Agregar tablas particionadas a publicaciones no está soportado." #: catalog/pg_publication.c:60 #, c-format msgid "You can add the table partitions individually." -msgstr "" +msgstr "Puede agregar las particiones de tabla de forma individual." #: catalog/pg_publication.c:68 #, c-format msgid "Only tables can be added to publications." -msgstr "" +msgstr "Sólo se pueden agregar tablas a las publicaciones." #: catalog/pg_publication.c:74 -#, fuzzy, c-format +#, c-format msgid "\"%s\" is a system table" -msgstr "«%s» es una tabla" +msgstr "«%s» es una tabla de sistema" #: catalog/pg_publication.c:76 -#, fuzzy, c-format +#, c-format msgid "System tables cannot be added to publications." -msgstr "%s no puede ser aplicado a una función" +msgstr "Las tablas de sistema no pueden agregarse a publicaciones." #: catalog/pg_publication.c:82 -#, fuzzy, c-format +#, c-format msgid "table \"%s\" cannot be replicated" -msgstr "el portal «%s» no puede ser ejecutado" +msgstr "la tabla «%s» no puede replicarse" #: catalog/pg_publication.c:84 -#, fuzzy, c-format +#, c-format msgid "Temporary and unlogged relations cannot be replicated." -msgstr "no se pueden crear tablas temporales o unlogged durante la recuperación" +msgstr "Las tablas temporales o «unlogged» no pueden replicarse." -#: catalog/pg_publication.c:166 -#, fuzzy, c-format +#: catalog/pg_publication.c:182 +#, c-format msgid "relation \"%s\" is already member of publication \"%s\"" -msgstr "el rol «%s» ya es un miembro del rol «%s»" +msgstr "la relación «%s» ya es un miembro de la publicación «%s»" -#: catalog/pg_publication.c:393 catalog/pg_publication.c:414 -#: commands/publicationcmds.c:401 commands/publicationcmds.c:702 -#, fuzzy, c-format +#: catalog/pg_publication.c:418 catalog/pg_publication.c:440 +#: commands/publicationcmds.c:422 commands/publicationcmds.c:727 +#, c-format msgid "publication \"%s\" does not exist" -msgstr "no existe la relación «%s»" +msgstr "no existe la publicación «%s»" -#: catalog/pg_shdepend.c:692 +#: catalog/pg_shdepend.c:777 #, c-format msgid "" "\n" @@ -4889,467 +5129,461 @@ msgstr[1] "" "\n" "y objetos en otras %d bases de datos (vea el registro del servidor para obtener la lista)" -#: catalog/pg_shdepend.c:998 +#: catalog/pg_shdepend.c:1083 #, c-format msgid "role %u was concurrently dropped" msgstr "el rol %u fue eliminado por una transacción concurrente" -#: catalog/pg_shdepend.c:1017 +#: catalog/pg_shdepend.c:1102 #, c-format msgid "tablespace %u was concurrently dropped" msgstr "el tablespace %u fue eliminado por una transacción concurrente" -#: catalog/pg_shdepend.c:1032 +#: catalog/pg_shdepend.c:1117 #, c-format msgid "database %u was concurrently dropped" msgstr "la base de datos %u fue eliminado por una transacción concurrente" -#: catalog/pg_shdepend.c:1077 +#: catalog/pg_shdepend.c:1162 #, c-format msgid "owner of %s" msgstr "dueño de %s" -#: catalog/pg_shdepend.c:1079 +#: catalog/pg_shdepend.c:1164 #, c-format msgid "privileges for %s" msgstr "privilegios para %s" -#: catalog/pg_shdepend.c:1081 +#: catalog/pg_shdepend.c:1166 #, c-format msgid "target of %s" msgstr "destino de %s" #. translator: %s will always be "database %s" -#: catalog/pg_shdepend.c:1089 +#: catalog/pg_shdepend.c:1174 #, c-format msgid "%d object in %s" msgid_plural "%d objects in %s" msgstr[0] "%d objeto en %s" msgstr[1] "%d objetos en %s" -#: catalog/pg_shdepend.c:1200 +#: catalog/pg_shdepend.c:1285 #, c-format msgid "cannot drop objects owned by %s because they are required by the database system" msgstr "no se puede eliminar objetos de propiedad de %s porque son requeridos por el sistema" -#: catalog/pg_shdepend.c:1315 +#: catalog/pg_shdepend.c:1408 #, c-format msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "no se puede reasignar la propiedad de objetos de %s porque son requeridos por el sistema" -#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:636 -#: commands/subscriptioncmds.c:844 commands/subscriptioncmds.c:1044 -#, fuzzy, c-format +#: catalog/pg_subscription.c:177 commands/subscriptioncmds.c:648 +#: commands/subscriptioncmds.c:862 commands/subscriptioncmds.c:1089 +#, c-format msgid "subscription \"%s\" does not exist" -msgstr "no existe la función «%s»" +msgstr "no existe la suscripción «%s»" -#: catalog/pg_type.c:136 catalog/pg_type.c:452 +#: catalog/pg_type.c:131 catalog/pg_type.c:467 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" -#: catalog/pg_type.c:251 +#: catalog/pg_type.c:249 #, c-format msgid "invalid type internal size %d" msgstr "el tamaño interno de tipo %d no es válido" -#: catalog/pg_type.c:267 catalog/pg_type.c:275 catalog/pg_type.c:283 -#: catalog/pg_type.c:292 +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 +#: catalog/pg_type.c:290 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "el alineamiento «%c» no es válido para un tipo pasado por valor de tamaño %d" -#: catalog/pg_type.c:299 +#: catalog/pg_type.c:297 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "el tamaño interno %d no es válido para un tipo pasado por valor" -#: catalog/pg_type.c:308 catalog/pg_type.c:314 +#: catalog/pg_type.c:306 catalog/pg_type.c:312 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "el alineamiento «%c» no es válido para un tipo de largo variable" -#: catalog/pg_type.c:322 +#: catalog/pg_type.c:320 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "los tipos de tamaño fijo deben tener almacenamiento PLAIN" -#: catalog/pg_type.c:801 +#: catalog/pg_type.c:818 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "no se pudo formar un nombre de tipo de array para el tipo «%s»" -#: catalog/toasting.c:105 commands/indexcmds.c:399 commands/tablecmds.c:4734 -#: commands/tablecmds.c:12973 +#: catalog/storage.c:344 storage/buffer/bufmgr.c:922 #, c-format -msgid "\"%s\" is not a table or materialized view" -msgstr "«%s» no es una tabla o vista materializada" +msgid "invalid page in block %u of relation %s" +msgstr "la página no es válida en el bloque %u de la relación %s" -#: catalog/toasting.c:158 +#: catalog/toasting.c:106 commands/indexcmds.c:585 commands/tablecmds.c:5160 +#: commands/tablecmds.c:14646 #, c-format -msgid "shared tables cannot be toasted after initdb" -msgstr "no se puede crear tablas TOAST a relaciones compartidas después de initdb" +msgid "\"%s\" is not a table or materialized view" +msgstr "«%s» no es una tabla o vista materializada" -#: commands/aggregatecmds.c:157 +#: commands/aggregatecmds.c:171 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "sólo las funciones de agregación de conjuntos ordenados pueden ser hipotéticas" -#: commands/aggregatecmds.c:182 +#: commands/aggregatecmds.c:196 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "el atributo de la función de agregación «%s» no es reconocido" -#: commands/aggregatecmds.c:192 +#: commands/aggregatecmds.c:206 #, c-format msgid "aggregate stype must be specified" msgstr "debe especificarse el tipo de transición (stype) de la función de agregación" -#: commands/aggregatecmds.c:196 +#: commands/aggregatecmds.c:210 #, c-format msgid "aggregate sfunc must be specified" msgstr "debe especificarse la función de transición (sfunc) de la función de agregación" -#: commands/aggregatecmds.c:208 +#: commands/aggregatecmds.c:222 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "debe especificarse la función de transición msfunc cuando se especifica mstype" -#: commands/aggregatecmds.c:212 +#: commands/aggregatecmds.c:226 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "debe especificarse la función de transición minvfunc cuando se especifica mstype" -#: commands/aggregatecmds.c:219 +#: commands/aggregatecmds.c:233 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "no debe especificarse msfunc sin mstype" -#: commands/aggregatecmds.c:223 +#: commands/aggregatecmds.c:237 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "no debe especificarse minvfunc sin mstype" -#: commands/aggregatecmds.c:227 +#: commands/aggregatecmds.c:241 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "no debe especificarse mfinalfunc sin mstype" -#: commands/aggregatecmds.c:231 +#: commands/aggregatecmds.c:245 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "no debe especificarse msspace sin mstype" -#: commands/aggregatecmds.c:235 +#: commands/aggregatecmds.c:249 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "no debe especificarse minitcond sin mstype" -#: commands/aggregatecmds.c:255 +#: commands/aggregatecmds.c:278 #, c-format msgid "aggregate input type must be specified" msgstr "debe especificarse el tipo de entrada de la función de agregación" -#: commands/aggregatecmds.c:285 +#: commands/aggregatecmds.c:308 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "el tipo base es redundante con el tipo de entrada en la función de agregación" -#: commands/aggregatecmds.c:326 commands/aggregatecmds.c:367 +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "el tipo de transición de la función de agregación no puede ser %s" -#: commands/aggregatecmds.c:338 +#: commands/aggregatecmds.c:361 #, c-format msgid "serialization functions may be specified only when the aggregate transition data type is %s" msgstr "las funciones de serialización pueden especificarse sólo cuando el tipo de transición de la función de agregación es %s" -#: commands/aggregatecmds.c:348 +#: commands/aggregatecmds.c:371 #, c-format msgid "must specify both or neither of serialization and deserialization functions" msgstr "debe especificar ambas o ninguna de las funciones de serialización y deserialización" -#: commands/aggregatecmds.c:413 commands/functioncmds.c:564 +#: commands/aggregatecmds.c:436 commands/functioncmds.c:613 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "el parámetro «parallel» debe ser SAFE, RESTRICTED o UNSAFE" -#: commands/alter.c:84 commands/event_trigger.c:234 +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "el parámetro «%s» debe ser READ_ONLY, SHAREABLE o READ_WRITE" + +#: commands/alter.c:85 commands/event_trigger.c:237 #, c-format msgid "event trigger \"%s\" already exists" msgstr "el disparador por eventos «%s» ya existe" -#: commands/alter.c:87 commands/foreigncmds.c:595 +#: commands/alter.c:88 commands/foreigncmds.c:601 #, c-format msgid "foreign-data wrapper \"%s\" already exists" msgstr "el conector de datos externos «%s» ya existe" -#: commands/alter.c:90 commands/foreigncmds.c:898 +#: commands/alter.c:91 commands/foreigncmds.c:907 #, c-format msgid "server \"%s\" already exists" msgstr "el servidor «%s» ya existe" -#: commands/alter.c:93 commands/proclang.c:367 +#: commands/alter.c:94 commands/proclang.c:368 #, c-format msgid "language \"%s\" already exists" msgstr "ya existe el lenguaje «%s»" -#: commands/alter.c:96 commands/publicationcmds.c:170 -#, fuzzy, c-format +#: commands/alter.c:97 commands/publicationcmds.c:176 +#, c-format msgid "publication \"%s\" already exists" -msgstr "la relación «%s» ya existe" +msgstr "la publicación «%s» ya existe" -#: commands/alter.c:99 commands/subscriptioncmds.c:358 -#, fuzzy, c-format +#: commands/alter.c:100 commands/subscriptioncmds.c:369 +#, c-format msgid "subscription \"%s\" already exists" -msgstr "la relación «%s» ya existe" +msgstr "la suscripción «%s» ya existe" -#: commands/alter.c:122 +#: commands/alter.c:123 #, c-format msgid "conversion \"%s\" already exists in schema \"%s\"" msgstr "ya existe una conversión llamada «%s» en el esquema «%s»" -#: commands/alter.c:126 -#, fuzzy, c-format +#: commands/alter.c:127 +#, c-format msgid "statistics object \"%s\" already exists in schema \"%s\"" -msgstr "ya existe una relación llamada «%s» en el esquema «%s»" +msgstr "ya existe un objeto de estadísticas llamado «%s» en el esquema «%s»" -#: commands/alter.c:130 +#: commands/alter.c:131 #, c-format msgid "text search parser \"%s\" already exists in schema \"%s\"" msgstr "el analizador de búsqueda en texto «%s» ya existe en el esquema «%s»" -#: commands/alter.c:134 +#: commands/alter.c:135 #, c-format msgid "text search dictionary \"%s\" already exists in schema \"%s\"" msgstr "el diccionario de búsqueda en texto «%s» ya existe en el esquema «%s»" -#: commands/alter.c:138 +#: commands/alter.c:139 #, c-format msgid "text search template \"%s\" already exists in schema \"%s\"" msgstr "la plantilla de búsqueda en texto «%s» ya existe en el esquema «%s»" -#: commands/alter.c:142 +#: commands/alter.c:143 #, c-format msgid "text search configuration \"%s\" already exists in schema \"%s\"" msgstr "la configuración de búsqueda en texto «%s» ya existe en el esquema «%s»" -#: commands/alter.c:216 +#: commands/alter.c:217 #, c-format msgid "must be superuser to rename %s" msgstr "debe ser superusuario para cambiar el nombre de «%s»" -#: commands/alter.c:709 +#: commands/alter.c:714 #, c-format msgid "must be superuser to set schema of %s" msgstr "debe ser superusuario para definir el esquema de %s" -#: commands/amcmds.c:58 +#: commands/amcmds.c:59 #, c-format msgid "permission denied to create access method \"%s\"" msgstr "se ha denegado el permiso para crear el método de acceso «%s»" -#: commands/amcmds.c:60 +#: commands/amcmds.c:61 #, c-format msgid "Must be superuser to create an access method." msgstr "Debe ser superusuario para crear un método de acceso." -#: commands/amcmds.c:68 +#: commands/amcmds.c:70 #, c-format msgid "access method \"%s\" already exists" msgstr "el método de acceso «%s» ya existe" -#: commands/amcmds.c:123 +#: commands/amcmds.c:127 #, c-format msgid "must be superuser to drop access methods" msgstr "debe ser superusuario para eliminar métodos de acceso" -#: commands/amcmds.c:174 commands/indexcmds.c:163 commands/indexcmds.c:515 -#: commands/opclasscmds.c:363 commands/opclasscmds.c:777 +#: commands/amcmds.c:178 commands/indexcmds.c:187 commands/indexcmds.c:730 +#: commands/opclasscmds.c:372 commands/opclasscmds.c:791 #, c-format msgid "access method \"%s\" does not exist" msgstr "no existe el método de acceso «%s»" -#: commands/amcmds.c:250 +#: commands/amcmds.c:267 #, c-format msgid "handler function is not specified" msgstr "no se ha especificado una función manejadora" -#: commands/amcmds.c:262 commands/event_trigger.c:243 -#: commands/foreigncmds.c:487 commands/proclang.c:117 commands/proclang.c:289 -#: commands/trigger.c:590 parser/parse_clause.c:1011 +#: commands/amcmds.c:288 commands/event_trigger.c:246 +#: commands/foreigncmds.c:493 commands/proclang.c:115 commands/proclang.c:287 +#: commands/trigger.c:719 parser/parse_clause.c:950 #, c-format msgid "function %s must return type %s" msgstr "la función %s debe retornar el tipo %s" -#: commands/analyze.c:151 -#, c-format -msgid "skipping analyze of \"%s\" --- lock not available" -msgstr "omitiendo analyze de «%s»: el candado no está disponible" - -#: commands/analyze.c:168 -#, c-format -msgid "skipping \"%s\" --- only superuser can analyze it" -msgstr "omitiendo «%s»: sólo un superusuario puede analizarla" - -#: commands/analyze.c:172 -#, c-format -msgid "skipping \"%s\" --- only superuser or database owner can analyze it" -msgstr "omitiendo «%s»: sólo un superusuario o el dueño de la base de datos puede analizarla" - -#: commands/analyze.c:176 -#, c-format -msgid "skipping \"%s\" --- only table or database owner can analyze it" -msgstr "omitiendo «%s»: sólo su dueño o el de la base de datos puede analizarla" - -#: commands/analyze.c:236 +#: commands/analyze.c:225 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "omitiendo «%s»: no se puede analizar esta tabla foránea" -#: commands/analyze.c:253 +#: commands/analyze.c:242 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "omitiendo «%s»: no se pueden analizar objetos que no son tablas, ni tablas especiales de sistema" -#: commands/analyze.c:334 +#: commands/analyze.c:323 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "analizando la jerarquía de herencia «%s.%s»" -#: commands/analyze.c:339 +#: commands/analyze.c:328 #, c-format msgid "analyzing \"%s.%s\"" msgstr "analizando «%s.%s»" +#: commands/analyze.c:388 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "la columna «%s» aparece más de una vez en la relación «%s»" + #: commands/analyze.c:668 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "analyze automático de la tabla «%s.%s.%s»: uso del sistema: %s" -#: commands/analyze.c:1220 +#: commands/analyze.c:1127 #, c-format msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" msgstr "«%s»: se procesaron %d de %u páginas, que contenían %.0f filas vigentes y %.0f filas no vigentes; %d filas en la muestra, %.0f total de filas estimadas" -#: commands/analyze.c:1300 +#: commands/analyze.c:1207 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" -msgstr "saltando el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas" +msgstr "omitiendo el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas" -#: commands/analyze.c:1398 +#: commands/analyze.c:1305 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" -msgstr "saltando el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas analizables" +msgstr "omitiendo el análisis del árbol de herencia «%s.%s» --- este árbol no contiene tablas hijas analizables" -#: commands/async.c:555 +#: commands/async.c:557 #, c-format msgid "channel name cannot be empty" msgstr "el nombre de canal no puede ser vacío" -#: commands/async.c:560 +#: commands/async.c:562 #, c-format msgid "channel name too long" msgstr "el nombre de canal es demasiado largo" -#: commands/async.c:567 +#: commands/async.c:569 #, c-format msgid "payload string too long" msgstr "la cadena de carga es demasiado larga" -#: commands/async.c:753 +#: commands/async.c:755 #, c-format msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" msgstr "no se puede hacer PREPARE de una transacción que ha ejecutado LISTEN, UNLISTEN o NOTIFY" -#: commands/async.c:856 +#: commands/async.c:858 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "demasiadas notificaciones en la cola NOTIFY" -#: commands/async.c:1486 +#: commands/async.c:1490 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "la cola NOTIFY está %.0f%% llena" -#: commands/async.c:1488 +#: commands/async.c:1492 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "El proceso servidor con PID %d está entre aquellos con transacciones más antiguas." -#: commands/async.c:1491 +#: commands/async.c:1495 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "La cola NOTIFY no puede vaciarse hasta que ese proceso cierre su transacción actual." -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:126 commands/cluster.c:388 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "no se pueden reordenar tablas temporales de otras sesiones" -#: commands/cluster.c:159 +#: commands/cluster.c:134 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "no se puede hacer «cluster» a una tabla particionada" + +#: commands/cluster.c:164 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "no hay un índice de ordenamiento definido para la tabla «%s»" -#: commands/cluster.c:173 commands/tablecmds.c:10185 -#: commands/tablecmds.c:12066 +#: commands/cluster.c:178 commands/tablecmds.c:11912 commands/tablecmds.c:13714 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "no existe el índice «%s» en la tabla «%s»" -#: commands/cluster.c:353 +#: commands/cluster.c:377 #, c-format msgid "cannot cluster a shared catalog" msgstr "no se puede reordenar un catálogo compartido" -#: commands/cluster.c:368 +#: commands/cluster.c:392 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "no se puede hacer vacuum a tablas temporales de otras sesiones" -#: commands/cluster.c:431 commands/tablecmds.c:12076 +#: commands/cluster.c:458 commands/tablecmds.c:13724 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "«%s» no es un índice de la tabla «%s»" -#: commands/cluster.c:439 +#: commands/cluster.c:466 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "no se puede reordenar en índice «%s» porque el método de acceso no soporta reordenamiento" -#: commands/cluster.c:451 +#: commands/cluster.c:478 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "no se puede reordenar en índice parcial «%s»" -#: commands/cluster.c:465 +#: commands/cluster.c:492 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "no se puede reordenar en el índice no válido «%s»" -#: commands/cluster.c:918 +#: commands/cluster.c:516 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "no se puede marcar un índice «clustered» en una tabla particionada" + +#: commands/cluster.c:899 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "reordenando «%s.%s» usando un recorrido de índice en «%s»" -#: commands/cluster.c:924 +#: commands/cluster.c:905 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "reordenando «%s.%s» usando un recorrido secuencial y ordenamiento" -#: commands/cluster.c:929 commands/vacuumlazy.c:490 -#, c-format -msgid "vacuuming \"%s.%s\"" -msgstr "haciendo vacuum a «%s.%s»" - -#: commands/cluster.c:1084 +#: commands/cluster.c:936 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "«%s»: se encontraron %.0f versiones eliminables de filas y %.0f no eliminables en %u páginas" -#: commands/cluster.c:1088 +#: commands/cluster.c:940 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5358,890 +5592,879 @@ msgstr "" "%.0f versiones muertas de filas no pueden ser eliminadas aún.\n" "%s." -#: commands/collationcmds.c:101 +#: commands/collationcmds.c:104 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "el atributo de ordenamiento (collation) «%s» no es reconocido" -#: commands/collationcmds.c:143 -#, fuzzy, c-format -#| msgid "collation attribute \"%s\" not recognized" +#: commands/collationcmds.c:147 +#, c-format msgid "collation \"default\" cannot be copied" -msgstr "el atributo de ordenamiento (collation) «%s» no es reconocido" +msgstr "el ordenamiento «default» no puede copiarse" -#: commands/collationcmds.c:173 -#, fuzzy, c-format +#: commands/collationcmds.c:180 +#, c-format msgid "unrecognized collation provider: %s" -msgstr "parámetro de configuración no reconocido: «%s»" +msgstr "proveedor de ordenamiento no reconocido: %s" -#: commands/collationcmds.c:182 +#: commands/collationcmds.c:189 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "debe especificarse el parámetro «lc_collate»" -#: commands/collationcmds.c:187 +#: commands/collationcmds.c:194 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "debe especificarse el parámetro «lc_ctype»" -#: commands/collationcmds.c:242 +#: commands/collationcmds.c:204 +#, c-format +msgid "nondeterministic collations not supported with this provider" +msgstr "los ordenamientos no determinísticos no están soportados con este proveedor" + +#: commands/collationcmds.c:264 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "ya existe un ordenamiento (collation) llamado «%s» para la codificación «%s» en el esquema «%s»" -#: commands/collationcmds.c:253 +#: commands/collationcmds.c:275 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "ya existe un ordenamiento llamado «%s» en el esquema «%s»" -#: commands/collationcmds.c:301 -#, fuzzy, c-format +#: commands/collationcmds.c:323 +#, c-format msgid "changing version from %s to %s" -msgstr "cambiando el tipo de retorno de la función %s de %s a %s" +msgstr "cambiando versión de %s a %s" -#: commands/collationcmds.c:316 +#: commands/collationcmds.c:338 #, c-format msgid "version has not changed" -msgstr "" +msgstr "la versión no ha cambiado" -#: commands/collationcmds.c:445 -#, fuzzy, c-format +#: commands/collationcmds.c:469 +#, c-format msgid "could not convert locale name \"%s\" to language tag: %s" -msgstr "no se pudo convertir la tabla «%s» en vista porque tiene índices" +msgstr "no se pudo convertir el nombre de configuración regional «%s» a etiqueta de lenguaje: %s" -#: commands/collationcmds.c:506 -#, fuzzy, c-format +#: commands/collationcmds.c:530 +#, c-format msgid "must be superuser to import system collations" -msgstr "debe ser superusuario obtener información de archivos" +msgstr "debe ser superusuario para importar ordenamientos del sistema" -#: commands/collationcmds.c:529 commands/copy.c:1859 commands/copy.c:3101 +#: commands/collationcmds.c:553 commands/copy.c:1899 commands/copy.c:3532 +#: libpq/be-secure-common.c:80 #, c-format msgid "could not execute command \"%s\": %m" msgstr "no se pudo ejecutar la orden «%s»: %m" -#: commands/collationcmds.c:660 +#: commands/collationcmds.c:684 #, c-format msgid "no usable system locales were found" -msgstr "" - -#: commands/collationcmds.c:724 commands/collationcmds.c:763 -#, fuzzy, c-format -msgid "could not get keyword values for locale \"%s\": %s" -msgstr "no se pudo abrir el archivo de variables de servidor «%s»: %s\n" +msgstr "no se encontraron locales de sistema utilizables" -#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 -#: commands/dbcommands.c:1100 commands/dbcommands.c:1290 -#: commands/dbcommands.c:1513 commands/dbcommands.c:1627 -#: commands/dbcommands.c:2043 utils/init/postinit.c:846 -#: utils/init/postinit.c:951 utils/init/postinit.c:968 +#: commands/comment.c:61 commands/dbcommands.c:810 commands/dbcommands.c:998 +#: commands/dbcommands.c:1102 commands/dbcommands.c:1292 +#: commands/dbcommands.c:1515 commands/dbcommands.c:1629 +#: commands/dbcommands.c:2046 utils/init/postinit.c:890 +#: utils/init/postinit.c:995 utils/init/postinit.c:1012 #, c-format msgid "database \"%s\" does not exist" msgstr "no existe la base de datos «%s»" -#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:930 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:944 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" msgstr "«%s» no es una tabla, vista, vista materializada, tipo compuesto, o tabla foránea" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2712 +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1915 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "la función «%s» no fue ejecutada por el manejador de triggers" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2721 +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1924 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "la función «%s» debe ser ejecutada AFTER ROW" -#: commands/constraint.c:81 +#: commands/constraint.c:84 #, c-format msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "la función «%s» debe ser ejecutada en INSERT o UPDATE" -#: commands/conversioncmds.c:66 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "no existe la codificación fuente «%s»" -#: commands/conversioncmds.c:73 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "no existe la codificación de destino «%s»" -#: commands/conversioncmds.c:87 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "la función de conversión de codificación %s debe retornar tipo %s" -#: commands/copy.c:373 commands/copy.c:407 +#: commands/copy.c:428 commands/copy.c:462 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY no está soportado a la salida estándar o desde la entrada estándar" -#: commands/copy.c:507 +#: commands/copy.c:562 #, c-format msgid "could not write to COPY program: %m" msgstr "no se pudo escribir al programa COPY: %m" -#: commands/copy.c:512 +#: commands/copy.c:567 #, c-format msgid "could not write to COPY file: %m" msgstr "no se pudo escribir archivo COPY: %m" -#: commands/copy.c:525 +#: commands/copy.c:580 #, c-format msgid "connection lost during COPY to stdout" msgstr "se perdió la conexión durante COPY a la salida estándar" -#: commands/copy.c:569 +#: commands/copy.c:624 #, c-format msgid "could not read from COPY file: %m" msgstr "no se pudo leer desde archivo COPY: %m" -#: commands/copy.c:585 commands/copy.c:606 commands/copy.c:610 -#: tcop/postgres.c:335 tcop/postgres.c:371 tcop/postgres.c:398 +#: commands/copy.c:642 commands/copy.c:663 commands/copy.c:667 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "se encontró fin de archivo inesperado en una conexión con una transacción abierta" -#: commands/copy.c:623 +#: commands/copy.c:680 #, c-format msgid "COPY from stdin failed: %s" msgstr "falló COPY desde la entrada estándar: %s" -#: commands/copy.c:639 +#: commands/copy.c:696 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "se recibió un mensaje de tipo 0x%02X inesperado durante COPY desde la entrada estándar" -#: commands/copy.c:800 +#: commands/copy.c:863 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "debe ser superusuario para usar COPY desde o hacia un programa externo" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "debe ser superusuario o miembro del rol pg_execute_server_program para usar COPY desde o hacia un programa externo" -#: commands/copy.c:801 commands/copy.c:807 +#: commands/copy.c:864 commands/copy.c:873 commands/copy.c:880 #, c-format msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "Cualquier usuario puede usar COPY hacia la salida estándar o desde la entrada estándar. La orden \\copy de psql también puede ser utilizado por cualquier usuario." -#: commands/copy.c:806 +#: commands/copy.c:872 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "debe ser superusuario o miembro del rol pg_read_server_files para hacer COPY desde un archivo" + +#: commands/copy.c:879 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "debe ser superusuario para usar COPY desde o hacia un archivo" +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "debe ser superusuario o miembro del rol pg_write_server_files para hacer COPY a un archivo" -#: commands/copy.c:868 +#: commands/copy.c:963 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "COPY FROM no está soportado con seguridad a nivel de registros" -#: commands/copy.c:869 +#: commands/copy.c:964 #, c-format msgid "Use INSERT statements instead." msgstr "Use sentencias INSERT en su lugar." -#: commands/copy.c:1054 +#: commands/copy.c:1152 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "el formato de COPY «%s» no es reconocido" -#: commands/copy.c:1134 commands/copy.c:1150 commands/copy.c:1165 -#: commands/copy.c:1187 +#: commands/copy.c:1223 commands/copy.c:1239 commands/copy.c:1254 +#: commands/copy.c:1276 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "el argumento de la opción «%s» debe ser una lista de nombres de columna" -#: commands/copy.c:1202 +#: commands/copy.c:1291 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "el argumento de la opción «%s» debe ser un nombre válido de codificación" -#: commands/copy.c:1209 commands/dbcommands.c:242 commands/dbcommands.c:1461 +#: commands/copy.c:1298 commands/dbcommands.c:243 commands/dbcommands.c:1463 #, c-format msgid "option \"%s\" not recognized" msgstr "no se reconoce la opción «%s»" -#: commands/copy.c:1221 +#: commands/copy.c:1310 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "no se puede especificar DELIMITER en modo BINARY" -#: commands/copy.c:1226 +#: commands/copy.c:1315 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "no se puede especificar NULL en modo BINARY" -#: commands/copy.c:1248 +#: commands/copy.c:1337 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "el delimitador de COPY debe ser un solo carácter de un byte" -#: commands/copy.c:1255 +#: commands/copy.c:1344 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "el delimitador de COPY no puede ser el carácter de nueva línea ni el de retorno de carro" -#: commands/copy.c:1261 +#: commands/copy.c:1350 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "la representación de null de COPY no puede usar el carácter de nueva línea ni el de retorno de carro" -#: commands/copy.c:1278 +#: commands/copy.c:1367 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "el delimitador de COPY no puede ser «%s»" -#: commands/copy.c:1284 +#: commands/copy.c:1373 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "el «header» de COPY está disponible sólo en modo CSV" -#: commands/copy.c:1290 +#: commands/copy.c:1379 #, c-format msgid "COPY quote available only in CSV mode" msgstr "el «quote» de COPY está disponible sólo en modo CSV" -#: commands/copy.c:1295 +#: commands/copy.c:1384 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "la comilla («quote») de COPY debe ser un solo carácter de un byte" -#: commands/copy.c:1300 +#: commands/copy.c:1389 #, c-format msgid "COPY delimiter and quote must be different" msgstr "el delimitador de COPY y la comilla («quote») deben ser diferentes" -#: commands/copy.c:1306 +#: commands/copy.c:1395 #, c-format msgid "COPY escape available only in CSV mode" msgstr "escape de COPY disponible sólo en modo CSV" -#: commands/copy.c:1311 +#: commands/copy.c:1400 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "el escape de COPY debe ser un sólo carácter de un byte" -#: commands/copy.c:1317 +#: commands/copy.c:1406 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "el forzado de comillas de COPY sólo está disponible en modo CSV" -#: commands/copy.c:1321 +#: commands/copy.c:1410 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "el forzado de comillas de COPY sólo está disponible en COPY TO" -#: commands/copy.c:1327 +#: commands/copy.c:1416 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "el forzado de no nulos en COPY sólo está disponible en modo CSV" -#: commands/copy.c:1331 +#: commands/copy.c:1420 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "el forzado de no nulos en COPY sólo está disponible usando COPY FROM" -#: commands/copy.c:1337 +#: commands/copy.c:1426 #, c-format msgid "COPY force null available only in CSV mode" msgstr "el forzado de nulos en COPY sólo está disponible en modo CSV" -#: commands/copy.c:1342 +#: commands/copy.c:1431 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "el forzado de nulos en COPY sólo está disponible usando COPY FROM" -#: commands/copy.c:1348 +#: commands/copy.c:1437 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "el delimitador de COPY no debe aparecer en la especificación NULL" -#: commands/copy.c:1355 +#: commands/copy.c:1444 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "el carácter de «quote» de CSV no debe aparecer en la especificación NULL" -#: commands/copy.c:1416 -#, c-format -msgid "table \"%s\" does not have OIDs" -msgstr "la tabla «%s» no tiene OIDs" - -#: commands/copy.c:1485 -#, c-format -msgid "COPY (query) WITH OIDS is not supported" -msgstr "COPY (consulta) WITH OIDS no está soportado" - -#: commands/copy.c:1506 +#: commands/copy.c:1530 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "las reglas DO INSTEAD NOTHING no están soportadas para COPY" -#: commands/copy.c:1520 +#: commands/copy.c:1544 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "las reglas DO INSTEAD condicionales no están soportadas para COPY" -#: commands/copy.c:1524 +#: commands/copy.c:1548 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "las reglas DO ALSO no están soportadas para COPY" -#: commands/copy.c:1529 +#: commands/copy.c:1553 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "las reglas DO INSTEAD de múltiples sentencias no están soportadas para COPY" -#: commands/copy.c:1539 +#: commands/copy.c:1563 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) no está soportado" -#: commands/copy.c:1556 +#: commands/copy.c:1580 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "la consulta COPY debe tener una cláusula RETURNING" -#: commands/copy.c:1584 +#: commands/copy.c:1608 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "la relación referenciada por la sentencia COPY ha cambiado" -#: commands/copy.c:1642 +#: commands/copy.c:1667 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "la columna FORCE_QUOTE «%s» no es referenciada en COPY" -#: commands/copy.c:1664 +#: commands/copy.c:1690 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "la columna FORCE_NOT_NULL «%s» no es referenciada en COPY" -#: commands/copy.c:1686 +#: commands/copy.c:1713 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "la columna FORCE_NULL «%s» no es referenciada en COPY" -#: commands/copy.c:1751 +#: commands/copy.c:1779 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "no se pudo cerrar la tubería a la orden externa: %m" -#: commands/copy.c:1755 +#: commands/copy.c:1794 #, c-format msgid "program \"%s\" failed" msgstr "el programa «%s» falló" -#: commands/copy.c:1805 +#: commands/copy.c:1845 #, c-format msgid "cannot copy from view \"%s\"" msgstr "no se puede copiar desde la vista «%s»" -#: commands/copy.c:1807 commands/copy.c:1813 commands/copy.c:1819 -#: commands/copy.c:1830 +#: commands/copy.c:1847 commands/copy.c:1853 commands/copy.c:1859 +#: commands/copy.c:1870 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Intente la forma COPY (SELECT ...) TO." -#: commands/copy.c:1811 +#: commands/copy.c:1851 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "no se puede copiar desde la vista materializada «%s»" -#: commands/copy.c:1817 +#: commands/copy.c:1857 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "no se puede copiar desde la tabla foránea «%s»" -#: commands/copy.c:1823 +#: commands/copy.c:1863 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "no se puede copiar desde la secuencia «%s»" -#: commands/copy.c:1828 -#, fuzzy, c-format +#: commands/copy.c:1868 +#, c-format msgid "cannot copy from partitioned table \"%s\"" -msgstr "no se puede copiar desde la tabla foránea «%s»" +msgstr "no se puede hacer copy de la tabla particionada «%s»" -#: commands/copy.c:1834 +#: commands/copy.c:1874 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "no se puede copiar desde la relación «%s» porque no es una tabla" -#: commands/copy.c:1874 +#: commands/copy.c:1914 #, c-format msgid "relative path not allowed for COPY to file" msgstr "no se permiten rutas relativas para COPY hacia un archivo" -#: commands/copy.c:1886 +#: commands/copy.c:1935 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "no se pudo abrir el archivo «%s» para escritura: %m" -#: commands/copy.c:1889 +#: commands/copy.c:1938 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." -msgstr "" +msgstr "COPY TO indica al proceso servidor PostgreSQL escribir a un archivo. Puede desear usar facilidades del lado del cliente, como \\copy de psql." -#: commands/copy.c:1902 commands/copy.c:3132 +#: commands/copy.c:1951 commands/copy.c:3563 #, c-format msgid "\"%s\" is a directory" msgstr "«%s» es un directorio" -#: commands/copy.c:2225 +#: commands/copy.c:2253 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, línea %d, columna %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, línea %s, columna %s" -#: commands/copy.c:2229 commands/copy.c:2276 +#: commands/copy.c:2257 commands/copy.c:2304 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, línea %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, línea %s" -#: commands/copy.c:2240 +#: commands/copy.c:2268 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, línea %d, columna %s: «%s»" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, línea %s, columna %s: «%s»" -#: commands/copy.c:2248 +#: commands/copy.c:2276 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, línea %d, columna %s: entrada nula" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, línea %s, columna %s: entrada nula" -#: commands/copy.c:2270 +#: commands/copy.c:2298 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, línea %d: «%s»" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, línea %s: «%s»" -#: commands/copy.c:2364 +#: commands/copy.c:2695 #, c-format msgid "cannot copy to view \"%s\"" msgstr "no se puede copiar hacia la vista «%s»" -#: commands/copy.c:2366 -#, fuzzy, c-format +#: commands/copy.c:2697 +#, c-format msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." -msgstr "Para activar las inserciones en la vista, provea un disparador INSTEAD OF INSERT un una regla incodicional ON INSERT DO INSTEAD." +msgstr "Para posibilitar «copy» a una vista, provea un disparador INSTEAD OF INSERT." -#: commands/copy.c:2370 +#: commands/copy.c:2701 #, c-format msgid "cannot copy to materialized view \"%s\"" msgstr "no se puede copiar hacia la vista materializada «%s»" -#: commands/copy.c:2375 -#, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "no se puede copiar hacia la tabla foránea «%s»" - -#: commands/copy.c:2380 +#: commands/copy.c:2706 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "no se puede copiar hacia la secuencia «%s»" -#: commands/copy.c:2385 +#: commands/copy.c:2711 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "no se puede copiar hacia la relación «%s» porque no es una tabla" -#: commands/copy.c:2448 +#: commands/copy.c:2799 #, c-format -msgid "cannot perform FREEZE because of prior transaction activity" -msgstr "no se puede ejecutar FREEZE debido a actividad anterior en la transacción" +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "no se puede hacer COPY FREEZE a una tabla particionada" -#: commands/copy.c:2454 +#: commands/copy.c:2814 #, c-format -msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" -msgstr "no se puede ejecutar FREEZE porque la tabla no fue creada ni truncada en la subtransacción en curso" +msgid "cannot perform COPY FREEZE because of prior transaction activity" +msgstr "no se puede ejecutar COPY FREEZE debido a actividad anterior en la transacción" -#: commands/copy.c:2617 executor/nodeModifyTable.c:311 -#, fuzzy, c-format -msgid "cannot route inserted tuples to a foreign table" -msgstr "no se puede insertar en la tabla foránea «%s»" +#: commands/copy.c:2820 +#, c-format +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "no se puede ejecutar COPY FREEZE porque la tabla no fue creada ni truncada en la subtransacción en curso" -#: commands/copy.c:3119 +#: commands/copy.c:3550 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." -msgstr "" +msgstr "COPY FROM indica al proceso servidor de PostgreSQL leer un archivo. Puede desear usar una facilidad del lado del cliente como \\copy de psql." -#: commands/copy.c:3152 +#: commands/copy.c:3578 #, c-format msgid "COPY file signature not recognized" msgstr "el identificador del archivo COPY no es reconocido" -#: commands/copy.c:3157 +#: commands/copy.c:3583 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "el encabezado del archivo COPY no es válido (faltan campos)" -#: commands/copy.c:3163 +#: commands/copy.c:3587 +#, c-format +msgid "invalid COPY file header (WITH OIDS)" +msgstr "encabezado de archivo COPY no válido (WITH OIDS)" + +#: commands/copy.c:3592 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "valores requeridos no reconocidos en encabezado de COPY" -#: commands/copy.c:3169 +#: commands/copy.c:3598 #, c-format msgid "invalid COPY file header (missing length)" msgstr "el encabezado del archivo COPY no es válido (falta el largo)" -#: commands/copy.c:3176 +#: commands/copy.c:3605 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "el encabezado del archivo COPY no es válido (largo incorrecto)" -#: commands/copy.c:3309 commands/copy.c:4016 commands/copy.c:4246 +#: commands/copy.c:3724 commands/copy.c:4389 commands/copy.c:4619 #, c-format msgid "extra data after last expected column" msgstr "datos extra después de la última columna esperada" -#: commands/copy.c:3319 -#, c-format -msgid "missing data for OID column" -msgstr "faltan datos para la columna OID" - -#: commands/copy.c:3325 -#, c-format -msgid "null OID in COPY data" -msgstr "OID nulo en datos COPY" - -#: commands/copy.c:3335 commands/copy.c:3458 -#, c-format -msgid "invalid OID in COPY data" -msgstr "OID no válido en datos COPY" - -#: commands/copy.c:3350 +#: commands/copy.c:3738 #, c-format msgid "missing data for column \"%s\"" msgstr "faltan datos en la columna «%s»" -#: commands/copy.c:3433 +#: commands/copy.c:3821 #, c-format msgid "received copy data after EOF marker" msgstr "se recibieron datos de copy después del marcador EOF" -#: commands/copy.c:3440 +#: commands/copy.c:3828 #, c-format msgid "row field count is %d, expected %d" msgstr "la cantidad de registros es %d, pero se esperaban %d" -#: commands/copy.c:3780 commands/copy.c:3797 +#: commands/copy.c:4148 commands/copy.c:4165 #, c-format msgid "literal carriage return found in data" msgstr "se encontró un retorno de carro literal en los datos" -#: commands/copy.c:3781 commands/copy.c:3798 +#: commands/copy.c:4149 commands/copy.c:4166 #, c-format msgid "unquoted carriage return found in data" msgstr "se encontró un retorno de carro fuera de comillas en los datos" -#: commands/copy.c:3783 commands/copy.c:3800 +#: commands/copy.c:4151 commands/copy.c:4168 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "Use «\\r» para representar el retorno de carro." -#: commands/copy.c:3784 commands/copy.c:3801 +#: commands/copy.c:4152 commands/copy.c:4169 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "Use un campo CSV entre comillas para representar el retorno de carro." -#: commands/copy.c:3813 +#: commands/copy.c:4181 #, c-format msgid "literal newline found in data" msgstr "se encontró un salto de línea literal en los datos" -#: commands/copy.c:3814 +#: commands/copy.c:4182 #, c-format msgid "unquoted newline found in data" msgstr "se encontró un salto de línea fuera de comillas en los datos" -#: commands/copy.c:3816 +#: commands/copy.c:4184 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "Use «\\n» para representar un salto de línea." -#: commands/copy.c:3817 +#: commands/copy.c:4185 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "Use un campo CSV entre comillas para representar un salto de línea." -#: commands/copy.c:3863 commands/copy.c:3899 +#: commands/copy.c:4231 commands/copy.c:4267 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "el marcador fin-de-copy no coincide con el estilo previo de salto de línea" -#: commands/copy.c:3872 commands/copy.c:3888 +#: commands/copy.c:4240 commands/copy.c:4256 #, c-format msgid "end-of-copy marker corrupt" msgstr "marcador fin-de-copy corrupto" -#: commands/copy.c:4330 +#: commands/copy.c:4703 #, c-format msgid "unterminated CSV quoted field" msgstr "un valor entre comillas está inconcluso" -#: commands/copy.c:4407 commands/copy.c:4426 +#: commands/copy.c:4780 commands/copy.c:4799 #, c-format msgid "unexpected EOF in COPY data" msgstr "EOF inesperado en datos de COPY" -#: commands/copy.c:4416 +#: commands/copy.c:4789 #, c-format msgid "invalid field size" msgstr "el tamaño de campo no es válido" -#: commands/copy.c:4439 +#: commands/copy.c:4812 #, c-format msgid "incorrect binary data format" msgstr "el formato de datos binarios es incorrecto" -#: commands/copy.c:4750 commands/indexcmds.c:1070 commands/tablecmds.c:1685 -#: commands/tablecmds.c:2187 commands/tablecmds.c:2613 -#: parser/parse_relation.c:3249 parser/parse_relation.c:3269 -#: utils/adt/tsvector_op.c:2561 +#: commands/copy.c:5120 +#, c-format +msgid "column \"%s\" is a generated column" +msgstr "la columna «%s» es una columna generada" + +#: commands/copy.c:5122 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "Las columnas generadas no pueden usarse en COPY." + +#: commands/copy.c:5137 commands/indexcmds.c:1582 commands/statscmds.c:210 +#: commands/tablecmds.c:2069 commands/tablecmds.c:2610 +#: commands/tablecmds.c:2989 parser/parse_relation.c:3353 +#: parser/parse_relation.c:3373 utils/adt/tsvector_op.c:2559 #, c-format msgid "column \"%s\" does not exist" msgstr "no existe la columna «%s»" -#: commands/copy.c:4757 commands/tablecmds.c:1711 commands/tablecmds.c:2213 -#: commands/trigger.c:800 parser/parse_target.c:1018 -#: parser/parse_target.c:1029 +#: commands/copy.c:5144 commands/tablecmds.c:2102 commands/trigger.c:937 +#: parser/parse_target.c:1047 parser/parse_target.c:1058 #, c-format msgid "column \"%s\" specified more than once" msgstr "la columna «%s» fue especificada más de una vez" -#: commands/createas.c:213 commands/createas.c:509 +#: commands/createas.c:216 commands/createas.c:499 #, c-format msgid "too many column names were specified" msgstr "se especificaron demasiados nombres de columna" -#: commands/createas.c:550 +#: commands/createas.c:541 #, c-format msgid "policies not yet implemented for this command" msgstr "las políticas no están implementadas para esta orden" -#: commands/dbcommands.c:235 +#: commands/dbcommands.c:236 #, c-format msgid "LOCATION is not supported anymore" msgstr "LOCATION ya no está soportado" -#: commands/dbcommands.c:236 +#: commands/dbcommands.c:237 #, c-format msgid "Consider using tablespaces instead." msgstr "Considere usar tablespaces." -#: commands/dbcommands.c:262 utils/adt/ascii.c:145 +#: commands/dbcommands.c:263 utils/adt/ascii.c:145 #, c-format msgid "%d is not a valid encoding code" msgstr "%d no es un código válido de codificación" -#: commands/dbcommands.c:273 utils/adt/ascii.c:127 +#: commands/dbcommands.c:274 utils/adt/ascii.c:127 #, c-format msgid "%s is not a valid encoding name" msgstr "%s no es un nombre válido de codificación" -#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 -#: commands/user.c:641 +#: commands/dbcommands.c:293 commands/dbcommands.c:1496 commands/user.c:275 +#: commands/user.c:671 #, c-format msgid "invalid connection limit: %d" msgstr "límite de conexión no válido: %d" -#: commands/dbcommands.c:311 +#: commands/dbcommands.c:312 #, c-format msgid "permission denied to create database" msgstr "se ha denegado el permiso para crear la base de datos" -#: commands/dbcommands.c:334 +#: commands/dbcommands.c:335 #, c-format msgid "template database \"%s\" does not exist" msgstr "no existe la base de datos patrón «%s»" -#: commands/dbcommands.c:346 +#: commands/dbcommands.c:347 #, c-format msgid "permission denied to copy database \"%s\"" msgstr "se ha denegado el permiso para copiar la base de datos «%s»" -#: commands/dbcommands.c:362 +#: commands/dbcommands.c:363 #, c-format msgid "invalid server encoding %d" msgstr "la codificación de servidor %d no es válida" -#: commands/dbcommands.c:368 commands/dbcommands.c:373 +#: commands/dbcommands.c:369 commands/dbcommands.c:374 #, c-format msgid "invalid locale name: \"%s\"" msgstr "nombre de configuración regional no válido: «%s»" -#: commands/dbcommands.c:393 +#: commands/dbcommands.c:394 #, c-format msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" msgstr "la nueva codificación (%s) es incompatible con la codificación de la base de datos patrón (%s)" -#: commands/dbcommands.c:396 +#: commands/dbcommands.c:397 #, c-format msgid "Use the same encoding as in the template database, or use template0 as template." msgstr "Use la misma codificación que en la base de datos patrón, o bien use template0 como patrón." -#: commands/dbcommands.c:401 +#: commands/dbcommands.c:402 #, c-format msgid "new collation (%s) is incompatible with the collation of the template database (%s)" msgstr "la nueva «collation» (%s) es incompatible con la «collation» de la base de datos patrón (%s)" -#: commands/dbcommands.c:403 +#: commands/dbcommands.c:404 #, c-format msgid "Use the same collation as in the template database, or use template0 as template." msgstr "Use la misma «collation» que en la base de datos patrón, o bien use template0 como patrón." -#: commands/dbcommands.c:408 +#: commands/dbcommands.c:409 #, c-format msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" msgstr "el nuevo LC_CTYPE (%s) es incompatible con el LC_CTYPE de la base de datos patrón (%s)" -#: commands/dbcommands.c:410 +#: commands/dbcommands.c:411 #, c-format msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." msgstr "Use el mismo LC_CTYPE que en la base de datos patrón, o bien use template0 como patrón." -#: commands/dbcommands.c:432 commands/dbcommands.c:1146 +#: commands/dbcommands.c:433 commands/dbcommands.c:1148 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "no puede usarse pg_global como tablespace por omisión" -#: commands/dbcommands.c:458 +#: commands/dbcommands.c:459 #, c-format msgid "cannot assign new default tablespace \"%s\"" msgstr "no se puede asignar el nuevo tablespace por omisión «%s»" -#: commands/dbcommands.c:460 +#: commands/dbcommands.c:461 #, c-format msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." msgstr "Hay un conflicto puesto que la base de datos «%s» ya tiene algunas tablas en este tablespace." -#: commands/dbcommands.c:480 commands/dbcommands.c:1016 +#: commands/dbcommands.c:481 commands/dbcommands.c:1018 #, c-format msgid "database \"%s\" already exists" msgstr "la base de datos «%s» ya existe" -#: commands/dbcommands.c:494 +#: commands/dbcommands.c:495 #, c-format msgid "source database \"%s\" is being accessed by other users" msgstr "la base de datos de origen «%s» está siendo utilizada por otros usuarios" -#: commands/dbcommands.c:736 commands/dbcommands.c:751 +#: commands/dbcommands.c:738 commands/dbcommands.c:753 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "la codificación «%s» no coincide con la configuración regional «%s»" -#: commands/dbcommands.c:739 +#: commands/dbcommands.c:741 #, c-format msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." msgstr "El parámetro LC_CTYPE escogido requiere la codificación «%s»." -#: commands/dbcommands.c:754 +#: commands/dbcommands.c:756 #, c-format msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." msgstr "El parámetro LC_COLLATE escogido requiere la codificación «%s»." -#: commands/dbcommands.c:815 +#: commands/dbcommands.c:817 #, c-format msgid "database \"%s\" does not exist, skipping" -msgstr "no existe la base de datos «%s», ignorando" +msgstr "no existe la base de datos «%s», omitiendo" -#: commands/dbcommands.c:839 +#: commands/dbcommands.c:841 #, c-format msgid "cannot drop a template database" msgstr "no se puede borrar una base de datos patrón" -#: commands/dbcommands.c:845 +#: commands/dbcommands.c:847 #, c-format msgid "cannot drop the currently open database" msgstr "no se puede eliminar la base de datos activa" -#: commands/dbcommands.c:858 -#, fuzzy, c-format +#: commands/dbcommands.c:860 +#, c-format msgid "database \"%s\" is used by an active logical replication slot" -msgstr "la base de datos «%s» está siendo usada por un slot de replicación lógica" +msgstr "la base de datos «%s» está en uso por un slot de replicación activo" -#: commands/dbcommands.c:860 -#, fuzzy, c-format -msgid "There is %d active slot" -msgid_plural "There are %d active slots" -msgstr[0] "Hay %d slot, %d de ellos activo" -msgstr[1] "Hay %d slots, %d de ellos activos." +#: commands/dbcommands.c:862 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Hay %d slot activo." +msgstr[1] "Hay %d slots activos." -#: commands/dbcommands.c:874 commands/dbcommands.c:1038 -#: commands/dbcommands.c:1168 +#: commands/dbcommands.c:876 commands/dbcommands.c:1040 +#: commands/dbcommands.c:1170 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "la base de datos «%s» está siendo utilizada por otros usuarios" -#: commands/dbcommands.c:887 -#, fuzzy, c-format +#: commands/dbcommands.c:889 +#, c-format msgid "database \"%s\" is being used by logical replication subscription" -msgstr "la base de datos «%s» está siendo usada por un slot de replicación lógica" +msgstr "la base de datos «%s» está siendo utilizada por suscripciones de replicación lógica" -#: commands/dbcommands.c:889 +#: commands/dbcommands.c:891 #, c-format msgid "There is %d subscription." msgid_plural "There are %d subscriptions." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Hay %d suscripción." +msgstr[1] "Hay %d suscripciones." -#: commands/dbcommands.c:1007 +#: commands/dbcommands.c:1009 #, c-format msgid "permission denied to rename database" msgstr "se ha denegado el permiso para cambiar el nombre a la base de datos" -#: commands/dbcommands.c:1027 +#: commands/dbcommands.c:1029 #, c-format msgid "current database cannot be renamed" msgstr "no se puede cambiar el nombre de la base de datos activa" -#: commands/dbcommands.c:1124 +#: commands/dbcommands.c:1126 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "no se puede cambiar el tablespace de la base de datos activa" -#: commands/dbcommands.c:1227 +#: commands/dbcommands.c:1229 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" msgstr "algunas relaciones de la base de datos «%s» ya están en el tablespace «%s»" -#: commands/dbcommands.c:1229 +#: commands/dbcommands.c:1231 #, c-format msgid "You must move them back to the database's default tablespace before using this command." msgstr "Debe moverlas de vuelta al tablespace por omisión de la base de datos antes de ejecutar esta orden." -#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 -#: commands/dbcommands.c:2104 commands/dbcommands.c:2159 -#: commands/tablespace.c:604 +#: commands/dbcommands.c:1356 commands/dbcommands.c:1902 +#: commands/dbcommands.c:2107 commands/dbcommands.c:2162 +#: commands/tablespace.c:611 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "algunos archivos inútiles pueden haber quedado en el directorio \"%s\"" -#: commands/dbcommands.c:1475 +#: commands/dbcommands.c:1477 #, c-format msgid "option \"%s\" cannot be specified with other options" msgstr "la opción «%s» no puede ser especificada con otras opciones" -#: commands/dbcommands.c:1530 +#: commands/dbcommands.c:1533 #, c-format msgid "cannot disallow connections for current database" msgstr "no se pueden prohibir las conexiones para la base de datos actual" -#: commands/dbcommands.c:1667 +#: commands/dbcommands.c:1669 #, c-format msgid "permission denied to change owner of database" msgstr "se ha denegado el permiso para cambiar el dueño de la base de datos" -#: commands/dbcommands.c:1987 +#: commands/dbcommands.c:1990 #, c-format msgid "There are %d other session(s) and %d prepared transaction(s) using the database." msgstr "Hay otras %d sesiones y %d transacciones preparadas usando la base de datos." -#: commands/dbcommands.c:1990 +#: commands/dbcommands.c:1993 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "Hay %d otra sesión usando la base de datos." msgstr[1] "Hay otras %d sesiones usando la base de datos." -#: commands/dbcommands.c:1995 +#: commands/dbcommands.c:1998 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." @@ -6285,1359 +6508,1529 @@ msgstr "el argumento de %s debe ser un nombre de tipo" msgid "invalid argument for %s: \"%s\"" msgstr "argumento no válido para %s: «%s»" -#: commands/dropcmds.c:104 commands/functioncmds.c:1201 -#: utils/adt/ruleutils.c:2445 +#: commands/dropcmds.c:99 commands/functioncmds.c:1272 +#: utils/adt/ruleutils.c:2609 #, c-format msgid "\"%s\" is an aggregate function" msgstr "«%s» es una función de agregación" -#: commands/dropcmds.c:106 +#: commands/dropcmds.c:101 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Use DROP AGGREGATE para eliminar funciones de agregación." -#: commands/dropcmds.c:157 commands/sequence.c:442 commands/tablecmds.c:2697 -#: commands/tablecmds.c:2848 commands/tablecmds.c:2891 -#: commands/tablecmds.c:12449 tcop/utility.c:1168 +#: commands/dropcmds.c:157 commands/sequence.c:447 commands/tablecmds.c:3073 +#: commands/tablecmds.c:3231 commands/tablecmds.c:3276 +#: commands/tablecmds.c:14093 tcop/utility.c:1174 #, c-format msgid "relation \"%s\" does not exist, skipping" -msgstr "no existe la relación «%s», ignorando" +msgstr "no existe la relación «%s», omitiendo" -#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:896 +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1142 #, c-format msgid "schema \"%s\" does not exist, skipping" -msgstr "el esquema «%s» no existe, ignorando" +msgstr "el esquema «%s» no existe, omitiendo" -#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:252 +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:253 #, c-format msgid "type \"%s\" does not exist, skipping" -msgstr "el tipo «%s» no existe, ignorando" +msgstr "el tipo «%s» no existe, omitiendo" #: commands/dropcmds.c:256 #, c-format msgid "access method \"%s\" does not exist, skipping" -msgstr "no existe el método de acceso «%s», ignorando" +msgstr "no existe el método de acceso «%s», omitiendo" #: commands/dropcmds.c:274 #, c-format msgid "collation \"%s\" does not exist, skipping" -msgstr "no existe el ordenamiento (collation) «%s», ignorando" +msgstr "no existe el ordenamiento (collation) «%s», omitiendo" #: commands/dropcmds.c:281 #, c-format msgid "conversion \"%s\" does not exist, skipping" -msgstr "no existe la conversión «%s», ignorando" +msgstr "no existe la conversión «%s», omitiendo" #: commands/dropcmds.c:292 -#, fuzzy, c-format +#, c-format msgid "statistics object \"%s\" does not exist, skipping" -msgstr "la tabla «%s» no existe, ignorando" +msgstr "no existe el objeto de estadísticas «%s», omitiendo" #: commands/dropcmds.c:299 #, c-format msgid "text search parser \"%s\" does not exist, skipping" -msgstr "el analizador de búsqueda en texto «%s» no existe, ignorando" +msgstr "el analizador de búsqueda en texto «%s» no existe, omitiendo" #: commands/dropcmds.c:306 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" -msgstr "el diccionario de búsqueda en texto «%s» no existe, ignorando" +msgstr "el diccionario de búsqueda en texto «%s» no existe, omitiendo" #: commands/dropcmds.c:313 #, c-format msgid "text search template \"%s\" does not exist, skipping" -msgstr "la plantilla de búsqueda en texto «%s» no existe, ignorando" +msgstr "la plantilla de búsqueda en texto «%s» no existe, omitiendo" #: commands/dropcmds.c:320 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" -msgstr "no existe la configuración de búsqueda en texto «%s», ignorando" +msgstr "no existe la configuración de búsqueda en texto «%s», omitiendo" #: commands/dropcmds.c:325 #, c-format msgid "extension \"%s\" does not exist, skipping" -msgstr "no existe la extensión «%s», ignorando" +msgstr "no existe la extensión «%s», omitiendo" #: commands/dropcmds.c:335 #, c-format msgid "function %s(%s) does not exist, skipping" -msgstr "no existe la función %s(%s), ignorando" +msgstr "no existe la función %s(%s), omitiendo" #: commands/dropcmds.c:348 #, c-format -msgid "aggregate %s(%s) does not exist, skipping" -msgstr "la función de agregación %s(%s) no existe, ignorando" +msgid "procedure %s(%s) does not exist, skipping" +msgstr "el procedimiento %s(%s) no existe, omitiendo" #: commands/dropcmds.c:361 #, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "no existe la rutina %s(%s), omitiendo" + +#: commands/dropcmds.c:374 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "la función de agregación %s(%s) no existe, omitiendo" + +#: commands/dropcmds.c:387 +#, c-format msgid "operator %s does not exist, skipping" -msgstr "el operador %s no existe, ignorando" +msgstr "el operador %s no existe, omitiendo" -#: commands/dropcmds.c:367 +#: commands/dropcmds.c:393 #, c-format msgid "language \"%s\" does not exist, skipping" -msgstr "el lenguaje «%s» no existe, ignorando" +msgstr "el lenguaje «%s» no existe, omitiendo" -#: commands/dropcmds.c:376 +#: commands/dropcmds.c:402 #, c-format msgid "cast from type %s to type %s does not exist, skipping" -msgstr "no existe la conversión del tipo %s al tipo %s, ignorando" +msgstr "no existe la conversión del tipo %s al tipo %s, omitiendo" -#: commands/dropcmds.c:385 +#: commands/dropcmds.c:411 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" -msgstr "la transformación para el tipo %s lenguaje «%s» no existe, ignorando" +msgstr "la transformación para el tipo %s lenguaje «%s» no existe, omitiendo" -#: commands/dropcmds.c:393 +#: commands/dropcmds.c:419 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" -msgstr "disparador «%s» para la relación «%s» no existe, ignorando" +msgstr "disparador «%s» para la relación «%s» no existe, omitiendo" -#: commands/dropcmds.c:402 +#: commands/dropcmds.c:428 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" -msgstr "la política «%s» para la relación «%s» no existe, ignorando" +msgstr "la política «%s» para la relación «%s» no existe, omitiendo" -#: commands/dropcmds.c:409 +#: commands/dropcmds.c:435 #, c-format msgid "event trigger \"%s\" does not exist, skipping" -msgstr "el disparador por eventos «%s» no existe, ignorando" +msgstr "el disparador por eventos «%s» no existe, omitiendo" -#: commands/dropcmds.c:415 +#: commands/dropcmds.c:441 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" -msgstr "la regla «%s» para la relación «%s» no existe, ignorando" +msgstr "la regla «%s» para la relación «%s» no existe, omitiendo" -#: commands/dropcmds.c:422 +#: commands/dropcmds.c:448 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" -msgstr "no existe el conector de datos externos «%s», ignorando" +msgstr "no existe el conector de datos externos «%s», omitiendo" -#: commands/dropcmds.c:426 +#: commands/dropcmds.c:452 commands/foreigncmds.c:1400 #, c-format msgid "server \"%s\" does not exist, skipping" -msgstr "el servidor «%s» no existe, ignorando" +msgstr "el servidor «%s» no existe, omitiendo" -#: commands/dropcmds.c:435 +#: commands/dropcmds.c:461 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" -msgstr "no existe la clase de operadores «%s» para el método de acceso «%s», ignorando" +msgstr "no existe la clase de operadores «%s» para el método de acceso «%s», omitiendo" -#: commands/dropcmds.c:447 +#: commands/dropcmds.c:473 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" -msgstr "no existe la familia de operadores «%s» para el método de acceso «%s», ignorando" +msgstr "no existe la familia de operadores «%s» para el método de acceso «%s», omitiendo" -#: commands/dropcmds.c:454 -#, fuzzy, c-format +#: commands/dropcmds.c:480 +#, c-format msgid "publication \"%s\" does not exist, skipping" -msgstr "no existe la relación «%s», ignorando" +msgstr "no existe la publicación «%s», omitiendo" -#: commands/event_trigger.c:185 +#: commands/event_trigger.c:188 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "se ha denegado el permiso para crear el disparador por eventos «%s»" -#: commands/event_trigger.c:187 +#: commands/event_trigger.c:190 #, c-format msgid "Must be superuser to create an event trigger." msgstr "Debe ser superusuario para crear un disparador por eventos." -#: commands/event_trigger.c:196 +#: commands/event_trigger.c:199 #, c-format msgid "unrecognized event name \"%s\"" -msgstr "nomre de evento no reconocido «%s»" +msgstr "nomre de evento «%s» no reconocido" -#: commands/event_trigger.c:213 +#: commands/event_trigger.c:216 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "variable de filtro «%s» no reconocida" -#: commands/event_trigger.c:268 +#: commands/event_trigger.c:271 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "el valor de filtro «%s» no es reconocido por la variable de filtro «%s»" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:274 commands/event_trigger.c:344 +#: commands/event_trigger.c:277 commands/event_trigger.c:347 #, c-format msgid "event triggers are not supported for %s" msgstr "los disparadores por eventos no están soportados para %s" -#: commands/event_trigger.c:367 +#: commands/event_trigger.c:370 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "la variable de filtro «%s» fue especificada más de una vez" -#: commands/event_trigger.c:514 commands/event_trigger.c:557 -#: commands/event_trigger.c:649 +#: commands/event_trigger.c:520 commands/event_trigger.c:564 +#: commands/event_trigger.c:658 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "no existe el disparador por eventos «%s»" -#: commands/event_trigger.c:618 +#: commands/event_trigger.c:626 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "se ha denegado el permiso para cambiar el dueño del disparador por eventos «%s»" -#: commands/event_trigger.c:620 +#: commands/event_trigger.c:628 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "El dueño de un disparador por eventos debe ser un superusuario." -#: commands/event_trigger.c:1464 +#: commands/event_trigger.c:1466 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s sólo puede invocarse en una función de un disparador en el evento sql_drop" -#: commands/event_trigger.c:1584 commands/event_trigger.c:1605 +#: commands/event_trigger.c:1586 commands/event_trigger.c:1607 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s sólo puede invocarse en una función de un disparador en el evento table_rewrite" -#: commands/event_trigger.c:2015 +#: commands/event_trigger.c:2018 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s sólo puede invocarse en una función de un disparador por eventos" -#: commands/explain.c:194 +#: commands/explain.c:193 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "valor no reconocido para la opción de EXPLAIN «%s»: «%s»" -#: commands/explain.c:201 +#: commands/explain.c:200 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" -msgstr "opción de EXPLAIN no reconocida «%s»" +msgstr "opción de EXPLAIN «%s» no reconocida" -#: commands/explain.c:209 +#: commands/explain.c:208 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "la opción BUFFERS de EXPLAIN requiere ANALYZE" -#: commands/explain.c:218 +#: commands/explain.c:217 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "la opción TIMING de EXPLAIN requiere ANALYZE" -#: commands/extension.c:168 commands/extension.c:2907 +#: commands/extension.c:171 commands/extension.c:2918 #, c-format msgid "extension \"%s\" does not exist" msgstr "no existe la extensión «%s»" -#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 -#: commands/extension.c:298 +#: commands/extension.c:270 commands/extension.c:279 commands/extension.c:291 +#: commands/extension.c:301 #, c-format msgid "invalid extension name: \"%s\"" msgstr "nombre de extensión no válido: «%s»" -#: commands/extension.c:268 +#: commands/extension.c:271 #, c-format msgid "Extension names must not be empty." msgstr "Los nombres de extensión no deben ser vacíos." -#: commands/extension.c:277 +#: commands/extension.c:280 #, c-format msgid "Extension names must not contain \"--\"." msgstr "Los nombres de extensión no deben contener «--»." -#: commands/extension.c:289 +#: commands/extension.c:292 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "Los nombres de extensión no deben empezar ni terminar con «-»." -#: commands/extension.c:299 +#: commands/extension.c:302 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "Los nombres de extensión no deben contener caracteres separadores de directorio." -#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 -#: commands/extension.c:342 +#: commands/extension.c:317 commands/extension.c:326 commands/extension.c:335 +#: commands/extension.c:345 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "nombre de versión de extensión no válido: «%s»" -#: commands/extension.c:315 +#: commands/extension.c:318 #, c-format msgid "Version names must not be empty." msgstr "Los nombres de versión no deben ser vacíos." -#: commands/extension.c:324 +#: commands/extension.c:327 #, c-format msgid "Version names must not contain \"--\"." msgstr "Los nombres de versión no deben contener «--»." -#: commands/extension.c:333 +#: commands/extension.c:336 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "Los nombres de versión no deben empezar ni terminar con «-»." -#: commands/extension.c:343 +#: commands/extension.c:346 #, c-format msgid "Version names must not contain directory separator characters." msgstr "Los nombres de versión no deben contener caracteres separadores de directorio." -#: commands/extension.c:493 +#: commands/extension.c:496 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "no se pudo abrir el archivo de control de extensión «%s»: %m" -#: commands/extension.c:515 commands/extension.c:525 +#: commands/extension.c:518 commands/extension.c:528 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "el parámetro «%s» no se puede cambiar en un archivo control secundario de extensión" -#: commands/extension.c:564 +#: commands/extension.c:550 commands/extension.c:558 utils/misc/guc.c:6554 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "el parámetro «%s» requiere un valor lógico (booleano)" + +#: commands/extension.c:567 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "«%s» no es un nombre válido de codificación" -#: commands/extension.c:578 +#: commands/extension.c:581 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "el parámetro «%s» debe ser una lista de nombres de extensión" -#: commands/extension.c:585 +#: commands/extension.c:588 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "parámetro no reconocido «%s» en el archivo «%s»" -#: commands/extension.c:594 +#: commands/extension.c:597 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "el parámetro «schema» no puede ser especificado cuando «relocatable» es verdadero" -#: commands/extension.c:761 +#: commands/extension.c:762 #, c-format msgid "transaction control statements are not allowed within an extension script" msgstr "las sentencias de control de transacción no están permitidos dentro de un guión de transacción" -#: commands/extension.c:807 +#: commands/extension.c:808 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "se ha denegado el permiso para crear la extensión «%s»" -#: commands/extension.c:809 +#: commands/extension.c:810 #, c-format msgid "Must be superuser to create this extension." msgstr "Debe ser superusuario para crear esta extensión." -#: commands/extension.c:813 +#: commands/extension.c:814 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "se ha denegado el permiso para actualizar la extensión «%s»" -#: commands/extension.c:815 +#: commands/extension.c:816 #, c-format msgid "Must be superuser to update this extension." msgstr "Debe ser superusuario para actualizar esta extensión." -#: commands/extension.c:1097 +#: commands/extension.c:1100 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "la extensión «%s» no tiene ruta de actualización desde la versión «%s» hasta la versión «%s»" -#: commands/extension.c:1304 commands/extension.c:2968 +#: commands/extension.c:1307 commands/extension.c:2979 #, c-format msgid "version to install must be specified" msgstr "la versión a instalar debe ser especificada" -#: commands/extension.c:1326 +#: commands/extension.c:1329 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "la versión FROM debe ser diferente de la versión destino de instalación «%s»" -#: commands/extension.c:1391 -#, fuzzy, c-format +#: commands/extension.c:1394 +#, c-format msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" -msgstr "la extensión «%s» no tiene ruta de actualización desde la versión «%s» hasta la versión «%s»" +msgstr "la extensión «%s» no tiene script de instalación ni ruta de actualización para la versión «%s»" -#: commands/extension.c:1426 +#: commands/extension.c:1429 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "la extensión «%s» debe ser instalada en el esquema «%s»" -#: commands/extension.c:1579 +#: commands/extension.c:1589 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "detectada una dependencia cíclica entre las extensiones «%s» y «%s»" -#: commands/extension.c:1584 +#: commands/extension.c:1594 #, c-format msgid "installing required extension \"%s\"" msgstr "instalando la extensión requerida «%s»" -#: commands/extension.c:1608 +#: commands/extension.c:1618 #, c-format msgid "required extension \"%s\" is not installed" msgstr "la extensión requerida «%s» no está instalada" -#: commands/extension.c:1611 +#: commands/extension.c:1621 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "Use CREATE EXTENSION ... CASCADE para instalar además las extensiones requeridas." -#: commands/extension.c:1648 +#: commands/extension.c:1658 #, c-format msgid "extension \"%s\" already exists, skipping" -msgstr "la extensión «%s» ya existe, ignorando" +msgstr "la extensión «%s» ya existe, omitiendo" -#: commands/extension.c:1655 +#: commands/extension.c:1665 #, c-format msgid "extension \"%s\" already exists" msgstr "la extensión «%s» ya existe" -#: commands/extension.c:1666 +#: commands/extension.c:1676 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "los CREATE EXTENSION anidados no están soportados" -#: commands/extension.c:1847 +#: commands/extension.c:1860 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "no se puede eliminar la extensión «%s» porque está siendo modificada" -#: commands/extension.c:2349 +#: commands/extension.c:2362 #, c-format -msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" -msgstr "pg_extension_config_dump() sólo puede ser llamado desde un guión SQL ejecutado por CREATE EXTENSION" +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "%s sólo puede invocarse desde un script SQL ejecutado por CREATE EXTENSION" -#: commands/extension.c:2361 +#: commands/extension.c:2374 #, c-format msgid "OID %u does not refer to a table" msgstr "el OID %u no hace referencia a una tabla" -#: commands/extension.c:2366 +#: commands/extension.c:2379 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "el tabla «%s» no es un miembro de la extensión que se está creando" -#: commands/extension.c:2722 +#: commands/extension.c:2733 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "no se puede mover la extensión «%s» al esquema «%s» porque la extensión contiene al esquema" -#: commands/extension.c:2763 commands/extension.c:2826 +#: commands/extension.c:2774 commands/extension.c:2837 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "la extensión «%s» no soporta SET SCHEMA" -#: commands/extension.c:2828 +#: commands/extension.c:2839 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "%s no está en el esquema de la extensión, «%s»" -#: commands/extension.c:2887 +#: commands/extension.c:2898 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "los ALTER EXTENSION anidados no están soportados" -#: commands/extension.c:2979 +#: commands/extension.c:2990 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "la versión «%s» de la extensión «%s» ya está instalada" -#: commands/extension.c:3230 +#: commands/extension.c:3241 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "no se puede agregar el esquema «%s» a la extensión «%s» porque el esquema contiene la extensión" -#: commands/extension.c:3258 +#: commands/extension.c:3269 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s no es un miembro de la extensión «%s»" -#: commands/extension.c:3324 +#: commands/extension.c:3335 #, c-format msgid "file \"%s\" is too large" msgstr "el archivo «%s» es demasiado grande" -#: commands/foreigncmds.c:150 commands/foreigncmds.c:159 +#: commands/foreigncmds.c:151 commands/foreigncmds.c:160 #, c-format msgid "option \"%s\" not found" msgstr "opción «%s» no encontrada" -#: commands/foreigncmds.c:169 +#: commands/foreigncmds.c:170 #, c-format msgid "option \"%s\" provided more than once" msgstr "la opción «%s» fue especificada más de una vez" -#: commands/foreigncmds.c:223 commands/foreigncmds.c:231 +#: commands/foreigncmds.c:224 commands/foreigncmds.c:232 #, c-format msgid "permission denied to change owner of foreign-data wrapper \"%s\"" msgstr "se ha denegado el permiso para cambiar el dueño del conector de datos externos «%s»" -#: commands/foreigncmds.c:225 +#: commands/foreigncmds.c:226 #, c-format msgid "Must be superuser to change owner of a foreign-data wrapper." msgstr "Debe ser superusuario para cambiar el dueño de un conector de datos externos." -#: commands/foreigncmds.c:233 +#: commands/foreigncmds.c:234 #, c-format msgid "The owner of a foreign-data wrapper must be a superuser." msgstr "El dueño de un conector de datos externos debe ser un superusuario." -#: commands/foreigncmds.c:291 commands/foreigncmds.c:706 foreign/foreign.c:667 +#: commands/foreigncmds.c:294 commands/foreigncmds.c:715 foreign/foreign.c:701 #, c-format msgid "foreign-data wrapper \"%s\" does not exist" msgstr "no existe el conector de datos externos «%s»" -#: commands/foreigncmds.c:582 +#: commands/foreigncmds.c:588 #, c-format msgid "permission denied to create foreign-data wrapper \"%s\"" msgstr "se ha denegado el permiso para crear el conector de datos externos «%s»" -#: commands/foreigncmds.c:584 +#: commands/foreigncmds.c:590 #, c-format msgid "Must be superuser to create a foreign-data wrapper." msgstr "Debe ser superusuario para crear un conector de datos externos." -#: commands/foreigncmds.c:696 +#: commands/foreigncmds.c:705 #, c-format msgid "permission denied to alter foreign-data wrapper \"%s\"" -msgstr "permiso denegado para cambiar el conector de datos externos «%s»" +msgstr "se ha denegado el permiso para cambiar el conector de datos externos «%s»" -#: commands/foreigncmds.c:698 +#: commands/foreigncmds.c:707 #, c-format msgid "Must be superuser to alter a foreign-data wrapper." msgstr "Debe ser superusuario para alterar un conector de datos externos." -#: commands/foreigncmds.c:729 +#: commands/foreigncmds.c:738 #, c-format msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" msgstr "al cambiar el manejador del conector de datos externos, el comportamiento de las tablas foráneas existentes puede cambiar" -#: commands/foreigncmds.c:744 +#: commands/foreigncmds.c:753 #, c-format msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" msgstr "al cambiar el validador del conector de datos externos, las opciones para los objetos dependientes de él pueden volverse no válidas" -#: commands/foreigncmds.c:890 -#, fuzzy, c-format +#: commands/foreigncmds.c:899 +#, c-format msgid "server \"%s\" already exists, skipping" -msgstr "el esquema «%s» ya existe, ignorando" +msgstr "el servidor «%s» ya existe, omitiendo" -#: commands/foreigncmds.c:1175 -#, fuzzy, c-format -msgid "user mapping for \"%s\" already exists for server %s, skipping" -msgstr "el mapeo para el usuario «%s» en el servidor %s ya existe" - -#: commands/foreigncmds.c:1185 -#, fuzzy, c-format -msgid "user mapping for \"%s\" already exists for server %s" -msgstr "el mapeo para el usuario «%s» en el servidor %s ya existe" +#: commands/foreigncmds.c:1187 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "el mapeo de usuario «%s» ya existe para el servidor «%s», omitiendo" -#: commands/foreigncmds.c:1278 commands/foreigncmds.c:1393 -#, fuzzy, c-format -msgid "user mapping for \"%s\" does not exist for the server" -msgstr "no existe el mapeo para el usuario «%s» para el servidor" +#: commands/foreigncmds.c:1197 +#, c-format +msgid "user mapping for \"%s\" already exists for server \"%s\"" +msgstr "el mapeo de usuario «%s» ya existe para el servidor «%s»" -#: commands/foreigncmds.c:1380 +#: commands/foreigncmds.c:1297 commands/foreigncmds.c:1414 #, c-format -msgid "server does not exist, skipping" -msgstr "el servidor no existe, ignorando" +msgid "user mapping for \"%s\" does not exist for server \"%s\"" +msgstr "no existe el mapeo de usuario «%s» para el servidor «%s»" -#: commands/foreigncmds.c:1398 -#, fuzzy, c-format -msgid "user mapping for \"%s\" does not exist for the server, skipping" -msgstr "el mapeo para el usuario «%s» para el servidor no existe, ignorando" +#: commands/foreigncmds.c:1419 +#, c-format +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" +msgstr "no existe el mapeo de usuario «%s» para el servidor «%s», omitiendo" -#: commands/foreigncmds.c:1549 foreign/foreign.c:357 +#: commands/foreigncmds.c:1570 foreign/foreign.c:389 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "el conector de datos externos «%s» no tiene manejador" -#: commands/foreigncmds.c:1555 +#: commands/foreigncmds.c:1576 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "el conector de datos externos «%s» no soporta IMPORT FOREIGN SCHEMA" -#: commands/foreigncmds.c:1658 +#: commands/foreigncmds.c:1679 #, c-format msgid "importing foreign table \"%s\"" msgstr "importando la tabla foránea «%s»" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:103 #, c-format msgid "SQL function cannot return shell type %s" msgstr "una función SQL no puede retornar el tipo inconcluso %s" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:108 #, c-format msgid "return type %s is only a shell" msgstr "el tipo de retorno %s está inconcluso" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:138 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "no se puede especificar un modificador de tipo para el tipo inconcluso «%s»" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:144 #, c-format msgid "type \"%s\" is not yet defined" msgstr "el tipo «%s» no ha sido definido aún" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:145 #, c-format msgid "Creating a shell type definition." msgstr "Creando una definición de tipo inconclusa." -#: commands/functioncmds.c:233 +#: commands/functioncmds.c:237 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "las funciones SQL no pueden aceptar el tipo inconcluso %s" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:243 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "las funciones de agregación no pueden aceptar el tipo inconcluso %s" -#: commands/functioncmds.c:244 +#: commands/functioncmds.c:248 #, c-format msgid "argument type %s is only a shell" msgstr "el tipo de argumento %s está inconcluso" -#: commands/functioncmds.c:254 +#: commands/functioncmds.c:258 #, c-format msgid "type %s does not exist" msgstr "no existe el tipo %s" -#: commands/functioncmds.c:268 +#: commands/functioncmds.c:272 #, c-format msgid "aggregates cannot accept set arguments" -msgstr "las funciones de agregación no pueden aceptar argumentos complejos" +msgstr "las funciones de agregación no pueden aceptar argumentos de conjunto" -#: commands/functioncmds.c:272 +#: commands/functioncmds.c:276 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "los procedimientos no pueden aceptar argumentos de conjunto" + +#: commands/functioncmds.c:280 #, c-format msgid "functions cannot accept set arguments" msgstr "funciones no pueden aceptar argumentos de conjunto" -#: commands/functioncmds.c:282 +#: commands/functioncmds.c:288 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "los procedimientos no pueden tener argumentos OUT" + +#: commands/functioncmds.c:289 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "Argumentos INOUT están permitidos." + +#: commands/functioncmds.c:299 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "el parámetro VARIADIC debe ser el último parámetro de entrada" -#: commands/functioncmds.c:310 +#: commands/functioncmds.c:329 #, c-format msgid "VARIADIC parameter must be an array" msgstr "el parámetro VARIADIC debe ser un array" -#: commands/functioncmds.c:350 +#: commands/functioncmds.c:369 #, c-format msgid "parameter name \"%s\" used more than once" -msgstr "el nombre de parámetro «%s» fue usado más de una vez" +msgstr "nombre de parámetro «%s» usado más de una vez" -#: commands/functioncmds.c:365 +#: commands/functioncmds.c:384 #, c-format msgid "only input parameters can have default values" msgstr "solo los parámetros de entrada pueden tener valores por omisión" -#: commands/functioncmds.c:380 +#: commands/functioncmds.c:399 #, c-format msgid "cannot use table references in parameter default value" msgstr "no se pueden usar referencias a tablas en el valor por omisión de un parámetro" -#: commands/functioncmds.c:404 +#: commands/functioncmds.c:423 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "los parámetros de entrada después de uno que tenga valor por omisión también deben tener valores por omisión" -#: commands/functioncmds.c:700 +#: commands/functioncmds.c:575 commands/functioncmds.c:766 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "atributo no válido en definición de procedimiento" + +#: commands/functioncmds.c:671 +#, c-format +msgid "support function %s must return type %s" +msgstr "la función de soporte %s debe retornar el tipo %s" + +#: commands/functioncmds.c:682 +#, c-format +msgid "must be superuser to specify a support function" +msgstr "debe ser superusuario para especificar una función de soporte" + +#: commands/functioncmds.c:798 #, c-format msgid "no function body specified" msgstr "no se ha especificado un cuerpo para la función" -#: commands/functioncmds.c:710 +#: commands/functioncmds.c:808 #, c-format msgid "no language specified" msgstr "no se ha especificado el lenguaje" -#: commands/functioncmds.c:735 commands/functioncmds.c:1242 +#: commands/functioncmds.c:833 commands/functioncmds.c:1317 #, c-format msgid "COST must be positive" msgstr "COST debe ser positivo" -#: commands/functioncmds.c:743 commands/functioncmds.c:1250 +#: commands/functioncmds.c:841 commands/functioncmds.c:1325 #, c-format msgid "ROWS must be positive" msgstr "ROWS debe ser positivo" -#: commands/functioncmds.c:784 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "se ignoró el atributo de función no reconocido «%s»" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:895 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "sólo se requiere un item AS para el lenguaje «%s»" -#: commands/functioncmds.c:930 commands/functioncmds.c:2131 -#: commands/proclang.c:561 +#: commands/functioncmds.c:993 commands/functioncmds.c:2227 +#: commands/proclang.c:568 #, c-format msgid "language \"%s\" does not exist" msgstr "no existe el lenguaje «%s»" -#: commands/functioncmds.c:932 commands/functioncmds.c:2133 +#: commands/functioncmds.c:995 commands/functioncmds.c:2229 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "Usar CREATE LANGUAGE para instalar el lenguaje en la base de datos." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Use CREATE EXTENSION para cargar el lenguaje en la base de datos." -#: commands/functioncmds.c:967 commands/functioncmds.c:1234 +#: commands/functioncmds.c:1030 commands/functioncmds.c:1309 #, c-format msgid "only superuser can define a leakproof function" msgstr "sólo un superusuario puede definir funciones «leakproof»" -#: commands/functioncmds.c:1010 +#: commands/functioncmds.c:1079 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "tipo de retorno de función debe ser %s debido a los parámetros OUT" -#: commands/functioncmds.c:1023 +#: commands/functioncmds.c:1092 #, c-format msgid "function result type must be specified" msgstr "el tipo de retorno de la función debe ser especificado" -#: commands/functioncmds.c:1077 commands/functioncmds.c:1254 +#: commands/functioncmds.c:1144 commands/functioncmds.c:1329 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "ROWS no es aplicable cuando una función no retorna un conjunto" -#: commands/functioncmds.c:1426 +#: commands/functioncmds.c:1521 #, c-format msgid "source data type %s is a pseudo-type" msgstr "el tipo de origen %s es un pseudotipo" -#: commands/functioncmds.c:1432 +#: commands/functioncmds.c:1527 #, c-format msgid "target data type %s is a pseudo-type" msgstr "el tipo de retorno %s es un pseudotipo" -#: commands/functioncmds.c:1456 +#: commands/functioncmds.c:1551 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "el cast será ignorado porque el tipo de datos de origen es un dominio" -#: commands/functioncmds.c:1461 +#: commands/functioncmds.c:1556 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "el cast será ignorado porque el tipo de datos de destino es un dominio" -#: commands/functioncmds.c:1486 +#: commands/functioncmds.c:1581 #, c-format msgid "cast function must take one to three arguments" msgstr "la función de conversión lleva de uno a tres argumentos" -#: commands/functioncmds.c:1490 +#: commands/functioncmds.c:1585 #, c-format msgid "argument of cast function must match or be binary-coercible from source data type" msgstr "el argumento de la función de conversión debe coincidir o ser binario-convertible con el tipo de origen" -#: commands/functioncmds.c:1494 -#, fuzzy, c-format +#: commands/functioncmds.c:1589 +#, c-format msgid "second argument of cast function must be type %s" -msgstr "el segundo argumento de la función de conversión debe ser entero" +msgstr "el segundo argumento de la función de conversión debe ser de tipo %s" -#: commands/functioncmds.c:1499 -#, fuzzy, c-format +#: commands/functioncmds.c:1594 +#, c-format msgid "third argument of cast function must be type %s" -msgstr "el tercer argumento de la función de conversión debe ser de tipo boolean" +msgstr "el tercer argumento de la función de conversión debe ser de tipo %s" -#: commands/functioncmds.c:1504 +#: commands/functioncmds.c:1599 #, c-format msgid "return data type of cast function must match or be binary-coercible to target data type" msgstr "el tipo de salida de la función de conversión debe coincidir o ser binario-convertible con el tipo de retorno" -#: commands/functioncmds.c:1515 +#: commands/functioncmds.c:1610 #, c-format msgid "cast function must not be volatile" msgstr "la función de conversión no debe ser volatile" -#: commands/functioncmds.c:1520 +#: commands/functioncmds.c:1615 #, c-format -msgid "cast function must not be an aggregate function" -msgstr "la función de conversión no debe ser una función de agregación" +msgid "cast function must be a normal function" +msgstr "la función de conversión debe ser una función normal" -#: commands/functioncmds.c:1524 -#, c-format -msgid "cast function must not be a window function" -msgstr "la función de conversión no debe ser una función de ventana deslizante" - -#: commands/functioncmds.c:1528 +#: commands/functioncmds.c:1619 #, c-format msgid "cast function must not return a set" msgstr "la función de conversión no debe retornar un conjunto" -#: commands/functioncmds.c:1554 +#: commands/functioncmds.c:1645 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "debe ser superusuario para crear una conversión sin especificar función" -#: commands/functioncmds.c:1569 +#: commands/functioncmds.c:1660 #, c-format msgid "source and target data types are not physically compatible" msgstr "los tipos de datos de origen y destino no son físicamente compatibles" -#: commands/functioncmds.c:1584 +#: commands/functioncmds.c:1675 #, c-format msgid "composite data types are not binary-compatible" msgstr "los tipos de datos compuestos no son binario-compatibles" -#: commands/functioncmds.c:1590 +#: commands/functioncmds.c:1681 #, c-format msgid "enum data types are not binary-compatible" msgstr "los tipos de datos enum no son binario-compatibles" -#: commands/functioncmds.c:1596 +#: commands/functioncmds.c:1687 #, c-format msgid "array data types are not binary-compatible" msgstr "los tipos de datos de array no son binario-compatibles" -#: commands/functioncmds.c:1613 +#: commands/functioncmds.c:1704 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "los tipos de dato de dominio no deben ser marcados binario-compatibles" -#: commands/functioncmds.c:1623 +#: commands/functioncmds.c:1714 #, c-format msgid "source data type and target data type are the same" msgstr "el tipo de origen y el tipo de retorno son el mismo" -#: commands/functioncmds.c:1656 +#: commands/functioncmds.c:1747 #, c-format msgid "cast from type %s to type %s already exists" msgstr "ya existe una conversión del tipo %s al tipo %s" -#: commands/functioncmds.c:1729 +#: commands/functioncmds.c:1822 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "no existe la conversión del tipo %s al tipo %s" -#: commands/functioncmds.c:1768 +#: commands/functioncmds.c:1861 #, c-format msgid "transform function must not be volatile" msgstr "la función de transformación no debe ser volatile" -#: commands/functioncmds.c:1772 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "la función de transformación no debe ser una función de agregación" - -#: commands/functioncmds.c:1776 +#: commands/functioncmds.c:1865 #, c-format -msgid "transform function must not be a window function" -msgstr "la función de transformación no debe ser una función de ventana deslizante" +msgid "transform function must be a normal function" +msgstr "la función de transformación debe ser una función normal" -#: commands/functioncmds.c:1780 +#: commands/functioncmds.c:1869 #, c-format msgid "transform function must not return a set" msgstr "la función de transformación no debe retornar un conjunto" -#: commands/functioncmds.c:1784 +#: commands/functioncmds.c:1873 #, c-format msgid "transform function must take one argument" msgstr "la función de transformación debe recibir un argumento" -#: commands/functioncmds.c:1788 -#, fuzzy, c-format +#: commands/functioncmds.c:1877 +#, c-format msgid "first argument of transform function must be type %s" -msgstr "el primer argumento de la función de transformación debe ser «internal»" +msgstr "el primer argumento de la función de transformación debe ser de tipo %s" -#: commands/functioncmds.c:1826 +#: commands/functioncmds.c:1915 #, c-format msgid "data type %s is a pseudo-type" msgstr "el tipo de dato %s es un pseudo-tipo" -#: commands/functioncmds.c:1832 +#: commands/functioncmds.c:1921 #, c-format msgid "data type %s is a domain" msgstr "tipo de dato «%s» es un dominio" -#: commands/functioncmds.c:1872 -#, fuzzy, c-format +#: commands/functioncmds.c:1961 +#, c-format msgid "return data type of FROM SQL function must be %s" -msgstr "el tipo de retorno de la función FROM SQL debe ser «internal»" +msgstr "el tipo de dato de retorno de la función FROM SQL debe ser %s" -#: commands/functioncmds.c:1898 +#: commands/functioncmds.c:1987 #, c-format msgid "return data type of TO SQL function must be the transform data type" -msgstr "el tipo de retorn de la función TO SQL debe ser el tipo de dato de la transformación" +msgstr "el tipo de dato de retorno de la función TO SQL debe ser el tipo de dato de la transformación" -#: commands/functioncmds.c:1925 +#: commands/functioncmds.c:2016 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "la transformación para el tipo %s lenguaje «%s» ya existe" -#: commands/functioncmds.c:2014 +#: commands/functioncmds.c:2108 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "la transformación para el tipo %s lenguaje «%s» no existe" -#: commands/functioncmds.c:2065 +#: commands/functioncmds.c:2159 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "ya existe una función llamada %s en el esquema «%s»" -#: commands/functioncmds.c:2118 +#: commands/functioncmds.c:2214 #, c-format msgid "no inline code specified" msgstr "no se ha especificado código" -#: commands/functioncmds.c:2163 +#: commands/functioncmds.c:2260 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "el lenguaje «%s» no soporta ejecución de código en línea" -#: commands/indexcmds.c:354 +#: commands/functioncmds.c:2372 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "no se pueden pasar más de %d argumento a un procedimiento" +msgstr[1] "no se pueden pasar más de %d argumentos a un procedimiento" + +#: commands/indexcmds.c:536 #, c-format msgid "must specify at least one column" msgstr "debe especificar al menos una columna" -#: commands/indexcmds.c:358 +#: commands/indexcmds.c:540 #, c-format msgid "cannot use more than %d columns in an index" msgstr "no se puede usar más de %d columnas en un índice" -#: commands/indexcmds.c:389 +#: commands/indexcmds.c:579 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "no se puede crear un índice en la tabla foránea «%s»" -#: commands/indexcmds.c:394 -#, fuzzy, c-format -msgid "cannot create index on partitioned table \"%s\"" -msgstr "no se puede crear un índice en la tabla foránea «%s»" +#: commands/indexcmds.c:604 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "no se puede crear un índice en la tabla particionada «%s» concurrentemente" + +#: commands/indexcmds.c:609 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "no se pueden create restricciones de exclusión en la tabla particionada «%s»" -#: commands/indexcmds.c:409 +#: commands/indexcmds.c:619 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "no se pueden crear índices en tablas temporales de otras sesiones" -#: commands/indexcmds.c:474 commands/tablecmds.c:593 -#: commands/tablecmds.c:10493 +#: commands/indexcmds.c:657 commands/tablecmds.c:673 commands/tablespace.c:1155 +#, c-format +msgid "cannot specify default tablespace for partitioned relations" +msgstr "no se puede especificar el tablespace por omisión para las relaciones particionadas" + +#: commands/indexcmds.c:689 commands/tablecmds.c:704 commands/tablecmds.c:12219 +#: commands/tablecmds.c:12331 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "sólo relaciones compartidas pueden ser puestas en el tablespace pg_global" -#: commands/indexcmds.c:507 +#: commands/indexcmds.c:722 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "sustituyendo el método de acceso obsoleto «rtree» por «gist»" -#: commands/indexcmds.c:525 +#: commands/indexcmds.c:743 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "el método de acceso «%s» no soporta índices únicos" -#: commands/indexcmds.c:530 +#: commands/indexcmds.c:748 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "el método de acceso «%s» no soporta columnas incluidas" + +#: commands/indexcmds.c:753 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "el método de acceso «%s» no soporta índices multicolumna" -#: commands/indexcmds.c:535 +#: commands/indexcmds.c:758 #, c-format msgid "access method \"%s\" does not support exclusion constraints" -msgstr "el método de acceso «%s» no soporta restricciones por exclusión" +msgstr "el método de acceso «%s» no soporta restricciones de exclusión" + +#: commands/indexcmds.c:870 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "restricción %s no soportada con definición de llave de particionamiento" + +#: commands/indexcmds.c:872 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "No se pueden usar restricciones %s cuando las llaves de particionamiento incluyen expresiones." + +#: commands/indexcmds.c:890 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "columnas insuficientes en definición de restricción %s" + +#: commands/indexcmds.c:892 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "La restricción %s en la tabla «%s» no incluye la columna «%s» que es parte de la llave de particionamiento." -#: commands/indexcmds.c:607 commands/indexcmds.c:627 +#: commands/indexcmds.c:911 commands/indexcmds.c:930 #, c-format msgid "index creation on system columns is not supported" msgstr "la creación de índices en columnas de sistema no está soportada" -#: commands/indexcmds.c:652 +#: commands/indexcmds.c:955 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s creará el índice implícito «%s» para la tabla «%s»" -#: commands/indexcmds.c:999 +#: commands/indexcmds.c:1511 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "las funciones utilizadas en predicados de índice deben estar marcadas IMMUTABLE" -#: commands/indexcmds.c:1065 parser/parse_utilcmd.c:2075 +#: commands/indexcmds.c:1577 parser/parse_utilcmd.c:2307 +#: parser/parse_utilcmd.c:2441 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "no existe la columna «%s» en la llave" -#: commands/indexcmds.c:1125 +#: commands/indexcmds.c:1601 parser/parse_utilcmd.c:1633 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "las expresiones no están soportadas en columnas incluidas" + +#: commands/indexcmds.c:1642 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "las funciones utilizadas en expresiones de índice deben estar marcadas IMMUTABLE" -#: commands/indexcmds.c:1148 +#: commands/indexcmds.c:1657 +#, c-format +msgid "including column does not support a collation" +msgstr "la columna incluida no permite un ordenamiento (collation)" + +#: commands/indexcmds.c:1661 +#, c-format +msgid "including column does not support an operator class" +msgstr "la columna incluida no permite una clase de operadores" + +#: commands/indexcmds.c:1665 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "la columna incluida no permite las opciones ASC/DESC" + +#: commands/indexcmds.c:1669 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "la columna incluida no permite las opciones NULLS FIRST/LAST" + +#: commands/indexcmds.c:1696 #, c-format msgid "could not determine which collation to use for index expression" msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de índice" -#: commands/indexcmds.c:1156 commands/tablecmds.c:13383 -#: commands/typecmds.c:831 parser/parse_expr.c:2763 parser/parse_type.c:549 -#: parser/parse_utilcmd.c:3111 utils/adt/misc.c:661 +#: commands/indexcmds.c:1704 commands/tablecmds.c:15102 commands/typecmds.c:837 +#: parser/parse_expr.c:2854 parser/parse_type.c:549 parser/parse_utilcmd.c:3514 +#: utils/adt/misc.c:490 #, c-format msgid "collations are not supported by type %s" msgstr "los ordenamientos (collation) no están soportados por el tipo %s" -#: commands/indexcmds.c:1194 +#: commands/indexcmds.c:1742 #, c-format msgid "operator %s is not commutative" msgstr "el operador %s no es conmutativo" -#: commands/indexcmds.c:1196 +#: commands/indexcmds.c:1744 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "Sólo operadores conmutativos pueden ser usados en restricciones de exclusión." -#: commands/indexcmds.c:1222 +#: commands/indexcmds.c:1770 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "el operador %s no es un miembro de la familia de operadores «%s»" -#: commands/indexcmds.c:1225 +#: commands/indexcmds.c:1773 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "El operador de exclusión debe estar relacionado con la clase de operadores del índice para la restricción." -#: commands/indexcmds.c:1260 +#: commands/indexcmds.c:1808 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "el método de acceso «%s» no soporta las opciones ASC/DESC" -#: commands/indexcmds.c:1265 +#: commands/indexcmds.c:1813 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "el método de acceso «%s» no soporta las opciones NULLS FIRST/LAST" -#: commands/indexcmds.c:1324 commands/typecmds.c:1928 +#: commands/indexcmds.c:1873 commands/tablecmds.c:15127 +#: commands/tablecmds.c:15133 commands/typecmds.c:1981 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "el tipo de dato %s no tiene una clase de operadores por omisión para el método de acceso «%s»" -#: commands/indexcmds.c:1326 +#: commands/indexcmds.c:1875 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "Debe especificar una clase de operadores para el índice, o definir una clase de operadores por omisión para el tipo de datos." -#: commands/indexcmds.c:1355 commands/indexcmds.c:1363 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1904 commands/indexcmds.c:1912 +#: commands/opclasscmds.c:208 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "no existe la clase de operadores «%s» para el método de acceso «%s»" -#: commands/indexcmds.c:1376 commands/typecmds.c:1916 +#: commands/indexcmds.c:1926 commands/typecmds.c:1969 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "la clase de operadores «%s» no acepta el tipo de datos %s" -#: commands/indexcmds.c:1466 +#: commands/indexcmds.c:2016 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "hay múltiples clases de operadores por omisión para el tipo de datos %s" -#: commands/indexcmds.c:1857 +#: commands/indexcmds.c:2452 +#, c-format +msgid "table \"%s\" has no indexes that can be reindexed concurrently" +msgstr "la tabla «%s» no tiene índices que puedan ser reindexados concurrentemente" + +#: commands/indexcmds.c:2463 +#, c-format +msgid "table \"%s\" has no indexes to reindex" +msgstr "la tabla «%s» no tiene índices para reindexar" + +#: commands/indexcmds.c:2502 #, c-format -msgid "table \"%s\" has no indexes" -msgstr "la tabla «%s» no tiene índices" +msgid "concurrent reindex of system catalogs is not supported" +msgstr "el reindexado concurrente de los catálogos de sistema no está soportado" -#: commands/indexcmds.c:1912 +#: commands/indexcmds.c:2525 #, c-format msgid "can only reindex the currently open database" msgstr "sólo se puede reindexar la base de datos actualmente abierta" -#: commands/indexcmds.c:2012 +#: commands/indexcmds.c:2616 +#, c-format +msgid "concurrent reindex is not supported for catalog relations, skipping all" +msgstr "el reindexado concurrente no está soportado para relaciones del catálogo, omitiendo todo" + +#: commands/indexcmds.c:2668 commands/indexcmds.c:3307 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "la tabla «%s.%s» fue reindexada" -#: commands/matview.c:181 +#: commands/indexcmds.c:2771 commands/indexcmds.c:2865 +#, c-format +msgid "cannot reindex a system catalog concurrently" +msgstr "no se pueden reindexar un catálogo de sistema concurrentemente" + +#: commands/indexcmds.c:2786 commands/indexcmds.c:2832 +#, c-format +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "no se puede reindexar el índice no válido «%s.%s» concurrentemente, omitiendo" + +#: commands/indexcmds.c:2792 +#, c-format +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "no se puede reindexar el índice de restricción de exclusión «%s.%s» concurrentemente, omitiendo" + +#: commands/indexcmds.c:2893 +#, c-format +msgid "cannot reindex this type of relation concurrently" +msgstr "no se puede reindexar este tipo de relación concurrentemente" + +#: commands/indexcmds.c:3289 commands/indexcmds.c:3300 +#, c-format +msgid "index \"%s.%s\" was reindexed" +msgstr "el índice «%s.%s» fue reindexado" + +#: commands/indexcmds.c:3332 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX no está implementado aún para tablas particionadas" + +#: commands/lockcmds.c:102 commands/tablecmds.c:5151 commands/trigger.c:313 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:928 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "«%s» no es una tabla o vista" + +#: commands/lockcmds.c:235 rewrite/rewriteHandler.c:1974 +#: rewrite/rewriteHandler.c:3707 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "se detectó recursión infinita en las reglas de la relación «%s»" + +#: commands/matview.c:182 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" msgstr "no se puede usar CONCURRENTLY cuando la vista materializada no contiene datos" -#: commands/matview.c:187 +#: commands/matview.c:188 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "las opciones CONCURRENTLY y WITH NO DATA no pueden usarse juntas" -#: commands/matview.c:257 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "no se puede refrescar la vista materializada «%s» concurrentemente" -#: commands/matview.c:260 +#: commands/matview.c:247 #, c-format msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." msgstr "Cree un índice único sin cláusula WHERE en una o más columnas de la vista materializada." -#: commands/matview.c:678 +#: commands/matview.c:645 #, c-format msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" msgstr "nuevos datos para la vista materializada «%s» contiene filas duplicadas sin columnas nulas" -#: commands/matview.c:680 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "Fila: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "no existe la familia de operadores «%s» para el método de acceso «%s»" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:269 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "ya exista una familia de operadores «%s» para el método de acceso «%s»" -#: commands/opclasscmds.c:402 +#: commands/opclasscmds.c:412 #, c-format msgid "must be superuser to create an operator class" msgstr "debe ser superusuario para crear una clase de operadores" -#: commands/opclasscmds.c:475 commands/opclasscmds.c:849 -#: commands/opclasscmds.c:973 +#: commands/opclasscmds.c:485 commands/opclasscmds.c:864 +#: commands/opclasscmds.c:988 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "el número de operador %d es incorrecto, debe estar entre 1 y %d" -#: commands/opclasscmds.c:519 commands/opclasscmds.c:893 -#: commands/opclasscmds.c:988 +#: commands/opclasscmds.c:529 commands/opclasscmds.c:908 +#: commands/opclasscmds.c:1003 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "el número de procedimiento %d no es válido, debe estar entre 1 y %d" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "número de función %d no válido, debe estar entre 1 y %d" -#: commands/opclasscmds.c:548 +#: commands/opclasscmds.c:558 #, c-format msgid "storage type specified more than once" msgstr "el tipo de almacenamiento fue especificado más de una vez" -#: commands/opclasscmds.c:575 +#: commands/opclasscmds.c:585 #, c-format msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "el tipo de almacenamiento no puede ser diferente del tipo de dato para el método de acceso «%s»" -#: commands/opclasscmds.c:591 +#: commands/opclasscmds.c:601 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "ya exista una clase de operadores «%s» para el método de acceso «%s»" -#: commands/opclasscmds.c:619 +#: commands/opclasscmds.c:629 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "no se pudo hacer que «%s» sea la clase de operadores por omisión para el tipo %s" -#: commands/opclasscmds.c:622 +#: commands/opclasscmds.c:632 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "Actualmente, «%s» es la clase de operadores por omisión." -#: commands/opclasscmds.c:747 +#: commands/opclasscmds.c:760 #, c-format msgid "must be superuser to create an operator family" msgstr "debe ser superusuario para crear una familia de operadores" -#: commands/opclasscmds.c:803 +#: commands/opclasscmds.c:818 #, c-format msgid "must be superuser to alter an operator family" msgstr "debe ser superusuario para alterar una familia de operadores" -#: commands/opclasscmds.c:858 +#: commands/opclasscmds.c:873 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "los tipos de los argumentos de operador deben ser especificados en ALTER OPERATOR FAMILY" -#: commands/opclasscmds.c:921 +#: commands/opclasscmds.c:936 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "STORAGE no puede ser especificado en ALTER OPERATOR FAMILY" -#: commands/opclasscmds.c:1043 +#: commands/opclasscmds.c:1058 #, c-format msgid "one or two argument types must be specified" msgstr "uno o dos tipos de argumento debe/n ser especificado" -#: commands/opclasscmds.c:1069 +#: commands/opclasscmds.c:1084 #, c-format msgid "index operators must be binary" msgstr "los operadores de índice deben ser binarios" -#: commands/opclasscmds.c:1088 +#: commands/opclasscmds.c:1103 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "el método de acceso «%s» no soporta operadores de ordenamiento" -#: commands/opclasscmds.c:1099 +#: commands/opclasscmds.c:1114 #, c-format msgid "index search operators must return boolean" msgstr "los operadores de búsqueda en índices deben retornar boolean" -#: commands/opclasscmds.c:1141 +#: commands/opclasscmds.c:1158 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "los procedimientos de comparación btree deben tener dos argumentos" +msgid "btree comparison functions must have two arguments" +msgstr "las funciones de comparación btree deben tener dos argumentos" -#: commands/opclasscmds.c:1145 +#: commands/opclasscmds.c:1162 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "los procedimientos de comparación btree deben retornar integer" +msgid "btree comparison functions must return integer" +msgstr "las funciones de comparación btree deben retornar entero" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1179 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "las funciones btree de soporte de ordenamiento deben aceptar tipo «internal»" + +#: commands/opclasscmds.c:1183 +#, c-format +msgid "btree sort support functions must return void" +msgstr "las funciones btree de soporte de ordenamiento deben retornar void" + +#: commands/opclasscmds.c:1194 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "las funciones btree in_range deben tener cinco argumentos" + +#: commands/opclasscmds.c:1198 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "las funciones btree in_range deben retornar booleano" + +#: commands/opclasscmds.c:1217 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "los procedimientos de «sort support» de btree deben aceptar tipo «internal»" +msgid "hash function 1 must have one argument" +msgstr "la función de hash 1 debe tener un argumento" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1221 #, c-format -msgid "btree sort support procedures must return void" -msgstr "los procedimientos de «sort support» de btree deben retornar «void»" +msgid "hash function 1 must return integer" +msgstr "la función de hash 1 debe retornar integer" -#: commands/opclasscmds.c:1178 +#: commands/opclasscmds.c:1228 #, c-format -msgid "hash procedures must have one argument" -msgstr "los procedimientos de hash deben tener un argumento" +msgid "hash function 2 must have two arguments" +msgstr "la función de hash 2 debe tener dos argumentos" -#: commands/opclasscmds.c:1182 +#: commands/opclasscmds.c:1232 #, c-format -msgid "hash procedures must return integer" -msgstr "los procedimientos de hash deben retornar integer" +msgid "hash function 2 must return bigint" +msgstr "la función de hash 2 debe retornar bigint" -#: commands/opclasscmds.c:1206 +#: commands/opclasscmds.c:1257 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "los tipos de datos asociados deben ser especificados en el procedimiento de soporte de índice" +msgid "associated data types must be specified for index support function" +msgstr "los tipos de datos asociados deben ser especificados para una función de soporte de índice" -#: commands/opclasscmds.c:1231 +#: commands/opclasscmds.c:1282 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "el número de procedimiento %d para (%s,%s) aparece más de una vez" +msgid "function number %d for (%s,%s) appears more than once" +msgstr "la función número %d para (%s,%s) aparece más de una vez" -#: commands/opclasscmds.c:1238 +#: commands/opclasscmds.c:1289 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "el número de operador %d para (%s,%s) aparece más de una vez" -#: commands/opclasscmds.c:1287 +#: commands/opclasscmds.c:1338 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "ya existe un operador %d(%s,%s) en la familia de operadores «%s»" -#: commands/opclasscmds.c:1401 +#: commands/opclasscmds.c:1455 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "ya existe una función %d(%s,%s) en la familia de operador «%s»" -#: commands/opclasscmds.c:1489 +#: commands/opclasscmds.c:1546 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "no existe el operador %d(%s,%s) en la familia de operadores «%s»" -#: commands/opclasscmds.c:1529 +#: commands/opclasscmds.c:1586 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "no existe la función %d(%s,%s) en la familia de operadores «%s»" -#: commands/opclasscmds.c:1659 +#: commands/opclasscmds.c:1716 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "ya existe una clase de operadores «%s» para el método de acceso «%s» en el esquema «%s»" -#: commands/opclasscmds.c:1682 +#: commands/opclasscmds.c:1739 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "ya existe una familia de operadores «%s» para el método de acceso «%s» en el esquema «%s»" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "no se permite un tipo SETOF en los argumentos de un operador" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:454 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "el atributo de operador «%s» no es reconocido" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "debe especificarse un procedimiento de operador" +msgid "operator function must be specified" +msgstr "la función del operador debe especificarse" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "debe especificar al menos uno de los argumentos izquierdo o derecho" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "la función de estimación de restricción %s debe retornar tipo %s" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "la función de estimación de join %s debe retornar tipo %s" -#: commands/operatorcmds.c:448 +#: commands/operatorcmds.c:451 #, c-format msgid "operator attribute \"%s\" cannot be changed" msgstr "el atributo de operador «%s» no puede ser cambiado" -#: commands/policy.c:87 commands/policy.c:397 commands/policy.c:487 -#: commands/tablecmds.c:1150 commands/tablecmds.c:1520 -#: commands/tablecmds.c:2507 commands/tablecmds.c:4704 -#: commands/tablecmds.c:7041 commands/tablecmds.c:13006 -#: commands/tablecmds.c:13041 commands/trigger.c:253 commands/trigger.c:1294 -#: commands/trigger.c:1403 rewrite/rewriteDefine.c:272 -#: rewrite/rewriteDefine.c:925 +#: commands/policy.c:88 commands/policy.c:401 commands/policy.c:491 +#: commands/tablecmds.c:1428 commands/tablecmds.c:1910 +#: commands/tablecmds.c:2883 commands/tablecmds.c:5130 +#: commands/tablecmds.c:7600 commands/tablecmds.c:14701 +#: commands/tablecmds.c:14736 commands/trigger.c:319 commands/trigger.c:1545 +#: commands/trigger.c:1654 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:933 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "permiso denegado: «%s» es un catálogo de sistema" -#: commands/policy.c:170 +#: commands/policy.c:171 #, c-format msgid "ignoring specified roles other than PUBLIC" msgstr "ignorando los roles especificados que no son PUBLIC" -#: commands/policy.c:171 +#: commands/policy.c:172 #, c-format msgid "All roles are members of the PUBLIC role." msgstr "Todos los roles son miembros del rol PUBLIC." -#: commands/policy.c:511 +#: commands/policy.c:515 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "el rol «%s» no pudo ser eliminado de la política «%s» en «%s»" -#: commands/policy.c:717 +#: commands/policy.c:724 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK no puede ser aplicado a SELECT o DELETE" -#: commands/policy.c:726 commands/policy.c:1024 +#: commands/policy.c:733 commands/policy.c:1038 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "sólo se permite una expresión WITH CHECK para INSERT" -#: commands/policy.c:799 commands/policy.c:1244 +#: commands/policy.c:808 commands/policy.c:1260 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "la política «%s» para la tabla «%s» ya existe" -#: commands/policy.c:996 commands/policy.c:1272 commands/policy.c:1344 +#: commands/policy.c:1010 commands/policy.c:1288 commands/policy.c:1359 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "no existe la política «%s» para la tabla «%s»" -#: commands/policy.c:1014 +#: commands/policy.c:1028 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "sólo se permite una expresión USING para SELECT, DELETE" -#: commands/portalcmds.c:58 commands/portalcmds.c:182 -#: commands/portalcmds.c:234 +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 #, c-format msgid "invalid cursor name: must not be empty" msgstr "el nombre de cursor no es válido: no debe ser vacío" #: commands/portalcmds.c:190 commands/portalcmds.c:244 -#: executor/execCurrent.c:67 utils/adt/xml.c:2469 utils/adt/xml.c:2639 +#: executor/execCurrent.c:70 utils/adt/xml.c:2608 utils/adt/xml.c:2778 #, c-format msgid "cursor \"%s\" does not exist" msgstr "no existe el cursor «%s»" @@ -7647,7 +8040,7 @@ msgstr "no existe el cursor «%s»" msgid "invalid statement name: must not be empty" msgstr "el nombre de sentencia no es válido: no debe ser vacío" -#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1349 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1468 #, c-format msgid "could not determine data type of parameter $%d" msgstr "no se pudo determinar el tipo del parámetro $%d" @@ -7677,98 +8070,98 @@ msgstr "Se esperaban %d parámetros pero se obtuvieron %d." msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "el parámetro $%d de tipo %s no puede ser convertido al tipo esperado %s" -#: commands/prepare.c:474 +#: commands/prepare.c:465 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "la sentencia preparada «%s» ya existe" -#: commands/prepare.c:513 +#: commands/prepare.c:504 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "no existe la sentencia preparada «%s»" -#: commands/proclang.c:87 +#: commands/proclang.c:85 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "usando información de pg_pltemplate en vez de los parámetros de CREATE LANGUAGE" -#: commands/proclang.c:97 +#: commands/proclang.c:95 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "debe ser superusuario para crear el lenguaje procedural «%s»" -#: commands/proclang.c:252 +#: commands/proclang.c:250 #, c-format msgid "unsupported language \"%s\"" msgstr "lenguaje no soportado: «%s»" -#: commands/proclang.c:254 +#: commands/proclang.c:252 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "Los lenguajes soportados están listados en el catálogo del sistema pg_pltemplate." -#: commands/proclang.c:262 +#: commands/proclang.c:260 #, c-format msgid "must be superuser to create custom procedural language" msgstr "debe ser superusuario para crear un lenguaje procedural personalizado" -#: commands/proclang.c:281 commands/trigger.c:582 commands/typecmds.c:457 -#: commands/typecmds.c:474 +#: commands/proclang.c:279 commands/trigger.c:711 commands/typecmds.c:458 +#: commands/typecmds.c:475 #, c-format msgid "changing return type of function %s from %s to %s" msgstr "cambiando el tipo de retorno de la función %s de %s a %s" -#: commands/publicationcmds.c:106 -#, fuzzy, c-format -msgid "invalid publish list" -msgstr "el binario «%s» no es válido" +#: commands/publicationcmds.c:108 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "sintaxis de entrada no válida para la opción «publish»" -#: commands/publicationcmds.c:122 -#, fuzzy, c-format +#: commands/publicationcmds.c:126 +#, c-format msgid "unrecognized \"publish\" value: \"%s\"" -msgstr "tipo de privilegio no reconocido: «%s»" +msgstr "valor de «publish» no reconocido: «%s»" -#: commands/publicationcmds.c:128 -#, fuzzy, c-format -msgid "unrecognized publication parameter: %s" -msgstr "parámetro del diccionario simple no reconocido: «%s»" +#: commands/publicationcmds.c:132 +#, c-format +msgid "unrecognized publication parameter: \"%s\"" +msgstr "parámetro de publicación no reconocido: «%s»" -#: commands/publicationcmds.c:160 -#, fuzzy, c-format +#: commands/publicationcmds.c:165 +#, c-format msgid "must be superuser to create FOR ALL TABLES publication" -msgstr "debe ser superusuario para crear usuarios de replicación" +msgstr "debe ser superusuario para crear publicaciones FOR ALL TABLES" -#: commands/publicationcmds.c:321 +#: commands/publicationcmds.c:341 #, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES" -msgstr "" +msgstr "la publicación \"%s\" se define como FOR ALL TABLES" -#: commands/publicationcmds.c:323 +#: commands/publicationcmds.c:343 #, c-format msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." -msgstr "" +msgstr "Las tablas no se pueden agregar ni eliminar de las publicaciones FOR ALL TABLES." -#: commands/publicationcmds.c:624 -#, fuzzy, c-format +#: commands/publicationcmds.c:648 +#, c-format msgid "relation \"%s\" is not part of the publication" -msgstr "relación «%s» no es un padre de la relación «%s»" +msgstr "relación «%s» no es parte de la publicación" -#: commands/publicationcmds.c:667 -#, fuzzy, c-format +#: commands/publicationcmds.c:691 +#, c-format msgid "permission denied to change owner of publication \"%s\"" -msgstr "se ha denegado el permiso para cambiar el dueño de la base de datos" +msgstr "se ha denegado el permiso para cambiar el dueño de la publicación «%s»" -#: commands/publicationcmds.c:669 -#, fuzzy, c-format +#: commands/publicationcmds.c:693 +#, c-format msgid "The owner of a FOR ALL TABLES publication must be a superuser." -msgstr "El dueño de un disparador por eventos debe ser un superusuario." +msgstr "El dueño de una publicación FOR ALL TABLES debe ser un superusuario." -#: commands/schemacmds.c:106 commands/schemacmds.c:280 +#: commands/schemacmds.c:106 commands/schemacmds.c:282 #, c-format msgid "unacceptable schema name \"%s\"" msgstr "el nombre de schema «%s» es inaceptable" -#: commands/schemacmds.c:107 commands/schemacmds.c:281 +#: commands/schemacmds.c:107 commands/schemacmds.c:283 #, c-format msgid "The prefix \"pg_\" is reserved for system schemas." msgstr "El prefijo «pg_» está reservado para esquemas del sistema." @@ -7776,7 +8169,7 @@ msgstr "El prefijo «pg_» está reservado para esquemas del sistema." #: commands/schemacmds.c:121 #, c-format msgid "schema \"%s\" already exists, skipping" -msgstr "el esquema «%s» ya existe, ignorando" +msgstr "el esquema «%s» ya existe, omitiendo" #: commands/seclabel.c:60 #, c-format @@ -7793,1930 +8186,2049 @@ msgstr "debe especificar un proveedor de etiquetas de seguridad cuando más de u msgid "security label provider \"%s\" is not loaded" msgstr "el proveedor de etiquetas de seguridad «%s» no está cargado" -#: commands/sequence.c:138 +#: commands/sequence.c:140 #, c-format msgid "unlogged sequences are not supported" -msgstr "las secuencias unlogged no están soportadas" +msgstr "las secuencias «unlogged» no están soportadas" -#: commands/sequence.c:699 +#: commands/sequence.c:709 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: se alcanzó el valor máximo de la secuencia «%s» (%s)" -#: commands/sequence.c:722 +#: commands/sequence.c:732 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: se alcanzó el valor mínimo de la secuencia «%s» (%s)" -#: commands/sequence.c:840 +#: commands/sequence.c:850 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "currval de la secuencia «%s» no está definido en esta sesión" -#: commands/sequence.c:859 commands/sequence.c:865 +#: commands/sequence.c:869 commands/sequence.c:875 #, c-format msgid "lastval is not yet defined in this session" msgstr "lastval no está definido en esta sesión" -#: commands/sequence.c:953 +#: commands/sequence.c:963 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: el valor %s está fuera del rango de la secuencia «%s» (%s..%s)" -#: commands/sequence.c:1358 +#: commands/sequence.c:1360 #, c-format msgid "invalid sequence option SEQUENCE NAME" -msgstr "" +msgstr "opción de secuencia no válida SEQUENCE NAME" -#: commands/sequence.c:1384 +#: commands/sequence.c:1386 #, c-format msgid "identity column type must be smallint, integer, or bigint" -msgstr "" +msgstr "el tipo de columna de identidad debe ser smallint, integer o bigint" -#: commands/sequence.c:1385 +#: commands/sequence.c:1387 #, c-format msgid "sequence type must be smallint, integer, or bigint" -msgstr "" +msgstr "el tipo de secuencia debe ser smallint, integer o bigint" -#: commands/sequence.c:1419 +#: commands/sequence.c:1421 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT no debe ser cero" -#: commands/sequence.c:1472 -#, fuzzy, c-format +#: commands/sequence.c:1474 +#, c-format msgid "MAXVALUE (%s) is out of range for sequence data type %s" -msgstr "«%s» está fuera de rango para el tipo real" +msgstr "MAXVALUE (%s) está fuera de rango para el tipo de dato de la secuencia %s" -#: commands/sequence.c:1509 -#, fuzzy, c-format +#: commands/sequence.c:1511 +#, c-format msgid "MINVALUE (%s) is out of range for sequence data type %s" -msgstr "«%s» está fuera de rango para el tipo real" +msgstr "MINVALUE (%s) está fuera de rango para el tipo de dato de la secuencia %s" -#: commands/sequence.c:1523 +#: commands/sequence.c:1525 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) debe ser menor que MAXVALUE (%s)" -#: commands/sequence.c:1550 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "el valor START (%s) no puede ser menor que MINVALUE (%s)" -#: commands/sequence.c:1562 +#: commands/sequence.c:1564 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "el valor START (%s) no puede ser mayor que MAXVALUE (%s)" -#: commands/sequence.c:1592 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "el valor RESTART (%s) no puede ser menor que MINVALUE (%s)" -#: commands/sequence.c:1604 +#: commands/sequence.c:1606 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "el valor RESTART (%s) no puede ser mayor que MAXVALUE (%s)" -#: commands/sequence.c:1619 +#: commands/sequence.c:1621 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE (%s) debe ser mayor que cero" -#: commands/sequence.c:1656 +#: commands/sequence.c:1658 #, c-format msgid "invalid OWNED BY option" msgstr "opción OWNED BY no válida" -#: commands/sequence.c:1657 +#: commands/sequence.c:1659 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "Especifique OWNED BY tabla.columna o OWNED BY NONE." -#: commands/sequence.c:1682 +#: commands/sequence.c:1684 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "la relación referida «%s» no es una tabla o tabla foránea" -#: commands/sequence.c:1689 +#: commands/sequence.c:1691 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "la secuencia debe tener el mismo dueño que la tabla a la que está enlazada" -#: commands/sequence.c:1693 +#: commands/sequence.c:1695 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "la secuencia debe estar en el mismo esquema que la tabla a la que está enlazada" -#: commands/sequence.c:1715 -#, fuzzy, c-format +#: commands/sequence.c:1717 +#, c-format msgid "cannot change ownership of identity sequence" -msgstr "no se puede cambiar el dueño de la secuencia «%s»" +msgstr "no se puede cambiar el dueño de la secuencia de identidad" -#: commands/sequence.c:1716 commands/tablecmds.c:9875 -#: commands/tablecmds.c:12469 +#: commands/sequence.c:1718 commands/tablecmds.c:11603 +#: commands/tablecmds.c:14113 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "La secuencia «%s» está enlazada a la tabla «%s»." -#: commands/statscmds.c:93 -#, fuzzy, c-format -msgid "statistics object \"%s\" already exists, skipping" -msgstr "la relación «%s» ya existe, ignorando" - -#: commands/statscmds.c:100 -#, fuzzy, c-format -msgid "statistics object \"%s\" already exists" -msgstr "el tablespace «%s» ya existe" - -#: commands/statscmds.c:112 commands/statscmds.c:121 +#: commands/statscmds.c:97 commands/statscmds.c:106 #, c-format msgid "only a single relation is allowed in CREATE STATISTICS" -msgstr "" +msgstr "sólo se permite una relación en CREATE STATISTICS" -#: commands/statscmds.c:139 -#, fuzzy, c-format +#: commands/statscmds.c:124 +#, c-format msgid "relation \"%s\" is not a table, foreign table, or materialized view" -msgstr "«%s» no es una tabla o vista materializada" +msgstr "la relación «%s» no es una tabla, tabla foránea o vista materializada" -#: commands/statscmds.c:170 commands/statscmds.c:176 +#: commands/statscmds.c:167 #, c-format -msgid "only simple column references are allowed in CREATE STATISTICS" -msgstr "" +msgid "statistics object \"%s\" already exists, skipping" +msgstr "el objeto de estadísticas «%s» ya existe, omitiendo" -#: commands/statscmds.c:183 -#, fuzzy, c-format -msgid "column \"%s\" referenced in statistics does not exist" -msgstr "no existe la columna «%s» referida en la llave foránea" +#: commands/statscmds.c:175 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "el objeto de estadísticas «%s» ya existe" -#: commands/statscmds.c:191 -#, fuzzy, c-format +#: commands/statscmds.c:197 commands/statscmds.c:203 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "sólo se permiten referencias de columnas simples en CREATE STATISTICS" + +#: commands/statscmds.c:218 +#, c-format msgid "statistics creation on system columns is not supported" -msgstr "la creación de índices en columnas de sistema no está soportada" +msgstr "la creación de estadísticas en columnas de sistema no está soportada" -#: commands/statscmds.c:198 +#: commands/statscmds.c:225 #, c-format -msgid "column \"%s\" cannot be used in statistics because its type has no default btree operator class" -msgstr "" +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "la columna «%s» no puede ser usado en estadísticas porque su tipo %s no tiene una clase de operadores por omisión para btree" -#: commands/statscmds.c:205 -#, fuzzy, c-format +#: commands/statscmds.c:232 +#, c-format msgid "cannot have more than %d columns in statistics" -msgstr "no se puede usar más de %d columnas en un índice" - -#: commands/statscmds.c:220 -#, fuzzy, c-format -msgid "extended statistics require at least 2 columns" -msgstr "debe pedir al menos 2 puntos" - -#: commands/statscmds.c:238 -#, fuzzy, c-format -msgid "duplicate column name in statistics definition" -msgstr "no se puede alterar el tipo de una columna usada en una definición de política" - -#: commands/statscmds.c:266 -#, fuzzy, c-format -msgid "unrecognized statistic type \"%s\"" -msgstr "tipo de objeto «%s» no reconocido" +msgstr "no se puede tener más de %d columnas en estadísticas" -#: commands/subscriptioncmds.c:187 -#, fuzzy, c-format -msgid "unrecognized subscription parameter: %s" -msgstr "parámetro del diccionario simple no reconocido: «%s»" - -#: commands/subscriptioncmds.c:200 +#: commands/statscmds.c:247 #, c-format -msgid "connect = false and enabled = true are mutually exclusive options" -msgstr "" +msgid "extended statistics require at least 2 columns" +msgstr "las estadísticas extendidas requieren al menos 2 columnas" -#: commands/subscriptioncmds.c:205 +#: commands/statscmds.c:265 #, c-format -msgid "connect = false and create_slot = true are mutually exclusive options" -msgstr "" +msgid "duplicate column name in statistics definition" +msgstr "nombre de columna duplicado en definición de estadísticas" -#: commands/subscriptioncmds.c:210 +#: commands/statscmds.c:299 #, c-format -msgid "connect = false and copy_data = true are mutually exclusive options" -msgstr "" +msgid "unrecognized statistics kind \"%s\"" +msgstr "tipo de estadísticas «%s» no reconocido" -#: commands/subscriptioncmds.c:227 +#: commands/subscriptioncmds.c:188 #, c-format -msgid "slot_name = NONE and enabled = true are mutually exclusive options" -msgstr "" +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "parámetro de suscripción no reconocido: «%s»" -#: commands/subscriptioncmds.c:232 +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:202 commands/subscriptioncmds.c:208 +#: commands/subscriptioncmds.c:214 commands/subscriptioncmds.c:233 +#: commands/subscriptioncmds.c:239 #, c-format -msgid "slot_name = NONE and create_slot = true are mutually exclusive options" -msgstr "" +msgid "%s and %s are mutually exclusive options" +msgstr "%s y %s son opciones mutuamente excluyentes" -#: commands/subscriptioncmds.c:237 +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:246 commands/subscriptioncmds.c:252 #, c-format -msgid "subscription with slot_name = NONE must also set enabled = false" -msgstr "" +msgid "subscription with %s must also set %s" +msgstr "suscripción con %s también debe activar %s" -#: commands/subscriptioncmds.c:242 +#: commands/subscriptioncmds.c:294 #, c-format -msgid "subscription with slot_name = NONE must also set create_slot = false" -msgstr "" - -#: commands/subscriptioncmds.c:284 -#, fuzzy, c-format msgid "publication name \"%s\" used more than once" -msgstr "el nombre de parámetro «%s» fue usado más de una vez" +msgstr "nombre de publicación «%s» usado más de una vez" -#: commands/subscriptioncmds.c:347 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:358 +#, c-format msgid "must be superuser to create subscriptions" -msgstr "debe ser superusuario para crear superusuarios" +msgstr "debe ser superusuario para crear suscripciones" -#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 -#: replication/logical/tablesync.c:856 replication/logical/worker.c:1616 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:441 commands/subscriptioncmds.c:534 +#: replication/logical/tablesync.c:846 replication/logical/worker.c:1704 +#, c-format msgid "could not connect to the publisher: %s" -msgstr "no se pudo hacer la conexión al servidor primario: %s" +msgstr "no se pudo connectar con el editor (publisher): %s" -#: commands/subscriptioncmds.c:469 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:483 +#, c-format msgid "created replication slot \"%s\" on publisher" -msgstr "no existe el slot de replicación «%s»" +msgstr "se creó el slot de replicación «%s» en el editor (publisher)" -#: commands/subscriptioncmds.c:486 +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:501 #, c-format -msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" -msgstr "" +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "las tablas no se suscribieron, tendrá que ejecutar %s para suscribir las tablas" -#: commands/subscriptioncmds.c:576 +#: commands/subscriptioncmds.c:590 #, c-format -msgid "added subscription for table %s.%s" -msgstr "" +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "tabla «%s.%s» agregada a suscripción «%s»" -#: commands/subscriptioncmds.c:604 +#: commands/subscriptioncmds.c:614 #, c-format -msgid "removed subscription for table %s.%s" -msgstr "" +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "tabla «%s.%s» eliminada de suscripción «%s»" -#: commands/subscriptioncmds.c:672 +#: commands/subscriptioncmds.c:686 #, c-format -msgid "cannot set slot_name = NONE for enabled subscription" -msgstr "" +msgid "cannot set %s for enabled subscription" +msgstr "no se puede establecer %s para la suscripción activada" -#: commands/subscriptioncmds.c:706 +#: commands/subscriptioncmds.c:721 #, c-format msgid "cannot enable subscription that does not have a slot name" -msgstr "" +msgstr "no se puede habilitar la suscripción que no tiene un nombre de slot" -#: commands/subscriptioncmds.c:752 +#: commands/subscriptioncmds.c:767 #, c-format msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" -msgstr "" +msgstr "ALTER SUBSCRIPTION con actualización no está permitido para las suscripciones desactivadas" -#: commands/subscriptioncmds.c:753 +#: commands/subscriptioncmds.c:768 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -msgstr "" +msgstr "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:771 +#: commands/subscriptioncmds.c:786 #, c-format msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" -msgstr "" +msgstr "ALTER SUBSCRIPTION ... REFRESH no está permitido para las suscripciones desactivadas" -#: commands/subscriptioncmds.c:848 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:866 +#, c-format msgid "subscription \"%s\" does not exist, skipping" -msgstr "no existe la relación «%s», ignorando" +msgstr "no existe la suscripción «%s», omitiendo" -#: commands/subscriptioncmds.c:949 +#: commands/subscriptioncmds.c:992 #, c-format msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" -msgstr "" +msgstr "no se pudo conectar con el editor (publisher) al intentar eliminar el slot \"%s\"" -#: commands/subscriptioncmds.c:951 commands/subscriptioncmds.c:965 -#: replication/logical/tablesync.c:906 replication/logical/tablesync.c:926 +#: commands/subscriptioncmds.c:994 commands/subscriptioncmds.c:1009 +#: replication/logical/tablesync.c:895 replication/logical/tablesync.c:917 #, c-format msgid "The error was: %s" msgstr "El error fue: %s" -#: commands/subscriptioncmds.c:952 +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:996 #, c-format -msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." -msgstr "Use ALTER SUBSCRIPTION ... SET (nombre_de_slot = NONE) para disasociar la suscripción del slot." +msgid "Use %s to disassociate the subscription from the slot." +msgstr "Use %s para disociar la suscripción del slot." -#: commands/subscriptioncmds.c:963 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:1007 +#, c-format msgid "could not drop the replication slot \"%s\" on publisher" -msgstr "no se pudo eliminar el origen de replicación con OID %d, en uso por el PID %d" +msgstr "no se pudo eliminar el slot de replicación «%s» en editor (publisher)" -#: commands/subscriptioncmds.c:968 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:1012 +#, c-format msgid "dropped replication slot \"%s\" on publisher" -msgstr "no existe el slot de replicación «%s»" +msgstr "eliminando el slot de replicación «%s» en editor (publisher)" -#: commands/subscriptioncmds.c:1009 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:1053 +#, c-format msgid "permission denied to change owner of subscription \"%s\"" -msgstr "se ha denegado el permiso para cambiar el dueño del disparador por eventos «%s»" +msgstr "se ha denegado el permiso para cambiar el dueño de la suscripción «%s»" -#: commands/subscriptioncmds.c:1011 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:1055 +#, c-format msgid "The owner of a subscription must be a superuser." -msgstr "El dueño de un disparador por eventos debe ser un superusuario." +msgstr "El dueño de una suscripción debe ser un superusuario." -#: commands/subscriptioncmds.c:1124 -#, fuzzy, c-format +#: commands/subscriptioncmds.c:1170 +#, c-format msgid "could not receive list of replicated tables from the publisher: %s" -msgstr "no se pudo recibir el archivo de historia de timeline del servidor primario: %s" +msgstr "no se pudo recibir la lista de tablas replicadas desde el editor (publisher): %s" -#: commands/tablecmds.c:221 commands/tablecmds.c:263 +#: commands/tablecmds.c:222 commands/tablecmds.c:264 #, c-format msgid "table \"%s\" does not exist" msgstr "no existe la tabla «%s»" -#: commands/tablecmds.c:222 commands/tablecmds.c:264 +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist, skipping" -msgstr "la tabla «%s» no existe, ignorando" +msgstr "la tabla «%s» no existe, omitiendo" -#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 msgid "Use DROP TABLE to remove a table." msgstr "Use DROP TABLE para eliminar una tabla." -#: commands/tablecmds.c:227 +#: commands/tablecmds.c:228 #, c-format msgid "sequence \"%s\" does not exist" msgstr "no existe la secuencia «%s»" -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist, skipping" -msgstr "la secuencia «%s» no existe, ignorando" +msgstr "la secuencia «%s» no existe, omitiendo" -#: commands/tablecmds.c:230 +#: commands/tablecmds.c:231 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "Use DROP SEQUENCE para eliminar una secuencia." -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:234 #, c-format msgid "view \"%s\" does not exist" msgstr "no existe la vista «%s»" -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist, skipping" -msgstr "la vista «%s» no existe, ignorando" +msgstr "la vista «%s» no existe, omitiendo" -#: commands/tablecmds.c:236 +#: commands/tablecmds.c:237 msgid "Use DROP VIEW to remove a view." msgstr "Use DROP VIEW para eliminar una vista." -#: commands/tablecmds.c:239 +#: commands/tablecmds.c:240 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "no existe la vista materializada «%s»" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist, skipping" -msgstr "la vista materializada «%s» no existe, ignorando" +msgstr "la vista materializada «%s» no existe, omitiendo" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:243 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Use DROP MATERIALIZED VIEW para eliminar una vista materializada." -#: commands/tablecmds.c:245 parser/parse_utilcmd.c:1827 +#: commands/tablecmds.c:246 commands/tablecmds.c:270 commands/tablecmds.c:16177 +#: parser/parse_utilcmd.c:2045 #, c-format msgid "index \"%s\" does not exist" msgstr "no existe el índice «%s»" -#: commands/tablecmds.c:246 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 #, c-format msgid "index \"%s\" does not exist, skipping" -msgstr "el índice «%s» no existe, ignorando" +msgstr "el índice «%s» no existe, omitiendo" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:249 commands/tablecmds.c:273 msgid "Use DROP INDEX to remove an index." msgstr "Use DROP INDEX para eliminar un índice." -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:254 #, c-format msgid "\"%s\" is not a type" msgstr "«%s» no es un tipo" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:255 msgid "Use DROP TYPE to remove a type." msgstr "Use DROP TYPE para eliminar un tipo." -#: commands/tablecmds.c:257 commands/tablecmds.c:9391 -#: commands/tablecmds.c:12249 +#: commands/tablecmds.c:258 commands/tablecmds.c:11032 +#: commands/tablecmds.c:13893 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "no existe la tabla foránea «%s»" -#: commands/tablecmds.c:258 +#: commands/tablecmds.c:259 #, c-format msgid "foreign table \"%s\" does not exist, skipping" -msgstr "la tabla foránea «%s» no existe, ignorando" +msgstr "la tabla foránea «%s» no existe, omitiendo" -#: commands/tablecmds.c:260 +#: commands/tablecmds.c:261 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Use DROP FOREIGN TABLE para eliminar una tabla foránea." -#: commands/tablecmds.c:533 +#: commands/tablecmds.c:589 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT sólo puede ser usado en tablas temporales" -#: commands/tablecmds.c:561 +#: commands/tablecmds.c:620 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "no se puede crear una tabla temporal dentro una operación restringida por seguridad" -#: commands/tablecmds.c:662 +#: commands/tablecmds.c:656 commands/tablecmds.c:12797 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "se heredaría de la relación «%s» más de una vez" + +#: commands/tablecmds.c:826 #, c-format -msgid "cannot create table with OIDs as partition of table without OIDs" -msgstr "no se puede crear una tabla con OIDs como partición de una tabla sin OIDs" +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "especificar un método de acceso de tablas no está soportado en tablas particionadas." -#: commands/tablecmds.c:783 parser/parse_utilcmd.c:3278 +#: commands/tablecmds.c:922 #, c-format msgid "\"%s\" is not partitioned" msgstr "«%s» no está particionada" -#: commands/tablecmds.c:831 -#, fuzzy, c-format +#: commands/tablecmds.c:1015 +#, c-format msgid "cannot partition using more than %d columns" -msgstr "no se puede usar más de %d columnas en un índice" +msgstr "no se puede particionar usando más de %d columnas" -#: commands/tablecmds.c:972 +#: commands/tablecmds.c:1218 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY no soporta eliminar múltiples objetos" -#: commands/tablecmds.c:976 +#: commands/tablecmds.c:1222 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY no soporta CASCADE" -#: commands/tablecmds.c:1253 +#: commands/tablecmds.c:1564 #, c-format msgid "cannot truncate only a partitioned table" msgstr "no se puede truncar ONLY una tabla particionada" -#: commands/tablecmds.c:1254 +#: commands/tablecmds.c:1565 #, c-format -msgid "Do not specify the ONLY keyword, or use truncate only on the partitions directly." -msgstr "No especifique la opción ONLY, o ejecute el truncado ONLY en las particiones directamente." +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "No especifique la opción ONLY, o ejecute TRUNCATE ONLY en las particiones directamente." -#: commands/tablecmds.c:1282 +#: commands/tablecmds.c:1634 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "truncando además la tabla «%s»" -#: commands/tablecmds.c:1530 +#: commands/tablecmds.c:1929 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "no se pueden truncar tablas temporales de otras sesiones" -#: commands/tablecmds.c:1761 commands/tablecmds.c:10976 +#: commands/tablecmds.c:2155 commands/tablecmds.c:12694 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "no se puede heredar de la tabla particionada «%s»" -#: commands/tablecmds.c:1766 +#: commands/tablecmds.c:2160 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "no se puede heredar de la partición «%s»" -#: commands/tablecmds.c:1774 parser/parse_utilcmd.c:2038 +#: commands/tablecmds.c:2168 parser/parse_utilcmd.c:2269 +#: parser/parse_utilcmd.c:2410 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "la relación heredada «%s» no es una tabla o tabla foránea" -#: commands/tablecmds.c:1782 commands/tablecmds.c:10955 +#: commands/tablecmds.c:2180 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "no se puede crear una relación temporal como partición de la relación permanente «%s»" + +#: commands/tablecmds.c:2189 commands/tablecmds.c:12673 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "no se puede heredar de la tabla temporal «%s»" -#: commands/tablecmds.c:1792 commands/tablecmds.c:10963 +#: commands/tablecmds.c:2199 commands/tablecmds.c:12681 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "no se puede heredar de una tabla temporal de otra sesión" -#: commands/tablecmds.c:1809 commands/tablecmds.c:11087 -#, c-format -msgid "relation \"%s\" would be inherited from more than once" -msgstr "se heredaría de la relación «%s» más de una vez" - -#: commands/tablecmds.c:1857 +#: commands/tablecmds.c:2251 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "mezclando múltiples definiciones heredadas de la columna «%s»" -#: commands/tablecmds.c:1865 +#: commands/tablecmds.c:2259 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "columna heredada «%s» tiene conflicto de tipos" -#: commands/tablecmds.c:1867 commands/tablecmds.c:1890 -#: commands/tablecmds.c:2096 commands/tablecmds.c:2126 -#: parser/parse_coerce.c:1650 parser/parse_coerce.c:1670 -#: parser/parse_coerce.c:1690 parser/parse_coerce.c:1736 -#: parser/parse_coerce.c:1775 parser/parse_param.c:218 +#: commands/tablecmds.c:2261 commands/tablecmds.c:2284 +#: commands/tablecmds.c:2497 commands/tablecmds.c:2527 +#: parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 +#: parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 +#: parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s versus %s" -#: commands/tablecmds.c:1876 +#: commands/tablecmds.c:2270 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "columna heredada «%s» tiene conflicto de ordenamiento (collation)" -#: commands/tablecmds.c:1878 commands/tablecmds.c:2108 -#: commands/tablecmds.c:5149 +#: commands/tablecmds.c:2272 commands/tablecmds.c:2509 +#: commands/tablecmds.c:5592 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "«%s» versus «%s»" -#: commands/tablecmds.c:1888 +#: commands/tablecmds.c:2282 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "columna heredada «%s» tiene conflicto de parámetros de almacenamiento" -#: commands/tablecmds.c:2002 commands/tablecmds.c:8881 -#: parser/parse_utilcmd.c:1121 parser/parse_utilcmd.c:1472 -#: parser/parse_utilcmd.c:1548 +#: commands/tablecmds.c:2298 +#, c-format +msgid "inherited column \"%s\" has a generation conflict" +msgstr "columna heredada «%s» tiene conflicto de generación" + +#: commands/tablecmds.c:2403 commands/tablecmds.c:10404 +#: parser/parse_utilcmd.c:1063 parser/parse_utilcmd.c:1149 +#: parser/parse_utilcmd.c:1562 parser/parse_utilcmd.c:1669 #, c-format msgid "cannot convert whole-row table reference" msgstr "no se puede convertir una referencia a la fila completa (whole-row)" -#: commands/tablecmds.c:2003 parser/parse_utilcmd.c:1122 +#: commands/tablecmds.c:2404 parser/parse_utilcmd.c:1150 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "La restricción «%s» contiene una referencia a la fila completa (whole-row) de la tabla «%s»." -#: commands/tablecmds.c:2082 +#: commands/tablecmds.c:2483 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "mezclando la columna «%s» con la definición heredada" -#: commands/tablecmds.c:2086 +#: commands/tablecmds.c:2487 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "moviendo y mezclando la columna «%s» con la definición heredada" -#: commands/tablecmds.c:2087 +#: commands/tablecmds.c:2488 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "La columna especificada por el usuario fue movida a la posición de la columna heredada." -#: commands/tablecmds.c:2094 +#: commands/tablecmds.c:2495 #, c-format msgid "column \"%s\" has a type conflict" msgstr "la columna «%s» tiene conflicto de tipos" -#: commands/tablecmds.c:2106 +#: commands/tablecmds.c:2507 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "la columna «%s» tiene conflicto de ordenamientos (collation)" -#: commands/tablecmds.c:2124 +#: commands/tablecmds.c:2525 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "la columna «%s» tiene conflicto de parámetros de almacenamiento" -#: commands/tablecmds.c:2235 +#: commands/tablecmds.c:2628 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "la columna «%s» hereda valores por omisión no coincidentes" -#: commands/tablecmds.c:2237 +#: commands/tablecmds.c:2630 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Para resolver el conflicto, indique explícitamente un valor por omisión." -#: commands/tablecmds.c:2284 +#: commands/tablecmds.c:2675 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "la restricción «check» «%s» aparece más de una vez con diferentes expresiones" -#: commands/tablecmds.c:2477 +#: commands/tablecmds.c:2852 #, c-format msgid "cannot rename column of typed table" msgstr "no se puede cambiar el nombre a una columna de una tabla tipada" -#: commands/tablecmds.c:2495 +#: commands/tablecmds.c:2871 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" msgstr "«%s» no es una tabla, vista, vista materializada, tipo compuesto, índice o tabla foránea" -#: commands/tablecmds.c:2589 +#: commands/tablecmds.c:2965 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "debe cambiar el nombre a la columna heredada «%s» en las tablas hijas también" -#: commands/tablecmds.c:2621 +#: commands/tablecmds.c:2997 #, c-format msgid "cannot rename system column \"%s\"" msgstr "no se puede cambiar el nombre a la columna de sistema «%s»" -#: commands/tablecmds.c:2636 +#: commands/tablecmds.c:3012 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "no se puede cambiar el nombre a la columna heredada «%s»" -#: commands/tablecmds.c:2788 +#: commands/tablecmds.c:3164 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "debe cambiar el nombre a la restricción heredada «%s» en las tablas hijas también" -#: commands/tablecmds.c:2795 +#: commands/tablecmds.c:3171 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "no se puede cambiar el nombre a la restricción heredada «%s»" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3019 +#: commands/tablecmds.c:3404 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "no se puede hacer %s en «%s» porque está siendo usada por consultas activas en esta sesión" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3028 +#: commands/tablecmds.c:3414 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "no se puede hacer %s en «%s» porque tiene eventos de disparador pendientes" -#: commands/tablecmds.c:4147 +#: commands/tablecmds.c:4542 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "no se puede reescribir la relación de sistema «%s»" -#: commands/tablecmds.c:4153 +#: commands/tablecmds.c:4548 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "no se puede reescribir la tabla «%s» que es usada como tabla de catálogo" -#: commands/tablecmds.c:4163 +#: commands/tablecmds.c:4558 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "no se puede reescribir tablas temporales de otras sesiones" -#: commands/tablecmds.c:4439 +#: commands/tablecmds.c:4837 #, c-format msgid "rewriting table \"%s\"" msgstr "reescribiendo tabla «%s»" -#: commands/tablecmds.c:4443 +#: commands/tablecmds.c:4841 #, c-format msgid "verifying table \"%s\"" msgstr "verificando tabla «%s»" -#: commands/tablecmds.c:4556 +#: commands/tablecmds.c:4971 #, c-format msgid "column \"%s\" contains null values" msgstr "la columna «%s» contiene valores nulos" -#: commands/tablecmds.c:4571 commands/tablecmds.c:8150 +#: commands/tablecmds.c:4987 commands/tablecmds.c:9641 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "la restricción «check» «%s» es violada por alguna fila" -#: commands/tablecmds.c:4587 -#, fuzzy, c-format -msgid "partition constraint is violated by some row" -msgstr "la restricción «check» «%s» es violada por alguna fila" +#: commands/tablecmds.c:5005 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "la restricción de partición actualizada para la partición «default» sería violada por alguna fila" -#: commands/tablecmds.c:4725 commands/trigger.c:247 -#: rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:920 +#: commands/tablecmds.c:5009 #, c-format -msgid "\"%s\" is not a table or view" -msgstr "«%s» no es una tabla o vista" +msgid "partition constraint is violated by some row" +msgstr "la restricción de partición es violada por alguna fila" -#: commands/tablecmds.c:4728 commands/trigger.c:1288 commands/trigger.c:1394 +#: commands/tablecmds.c:5154 commands/trigger.c:1539 commands/trigger.c:1645 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "«%s» no es una tabla, vista o tabla foránea" -#: commands/tablecmds.c:4731 +#: commands/tablecmds.c:5157 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "«%s» no es una tabla, vista, vista materializada, o índice" -#: commands/tablecmds.c:4737 +#: commands/tablecmds.c:5163 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "«%s» no es una tabla, vista materializada, o índice" -#: commands/tablecmds.c:4740 +#: commands/tablecmds.c:5166 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "«%s» no es una tabla, vista materializada o tabla foránea" -#: commands/tablecmds.c:4743 +#: commands/tablecmds.c:5169 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "«%s» no es una tabla o tabla foránea" -#: commands/tablecmds.c:4746 +#: commands/tablecmds.c:5172 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "«%s» no es una tabla, tipo compuesto, o tabla foránea" -#: commands/tablecmds.c:4749 commands/tablecmds.c:6112 +#: commands/tablecmds.c:5175 commands/tablecmds.c:6650 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "«%s» no es una tabla, vista materializada, índice o tabla foránea" -#: commands/tablecmds.c:4759 +#: commands/tablecmds.c:5185 #, c-format msgid "\"%s\" is of the wrong type" msgstr "«%s» es tipo equivocado" -#: commands/tablecmds.c:4913 commands/tablecmds.c:4920 +#: commands/tablecmds.c:5360 commands/tablecmds.c:5367 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "no se puede alterar el tipo «%s» porque la columna «%s.%s» lo usa" -#: commands/tablecmds.c:4927 +#: commands/tablecmds.c:5374 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "no se puede alterar la tabla foránea «%s» porque la columna «%s.%s» usa su tipo de registro" -#: commands/tablecmds.c:4934 +#: commands/tablecmds.c:5381 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "no se puede alterar la tabla «%s» porque la columna «%s.%s» usa su tipo de registro" -#: commands/tablecmds.c:4996 +#: commands/tablecmds.c:5437 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "no se puede cambiar el tipo «%s» porque es el tipo de una tabla tipada" -#: commands/tablecmds.c:4998 +#: commands/tablecmds.c:5439 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "Use ALTER ... CASCADE para eliminar además las tablas tipadas." -#: commands/tablecmds.c:5042 +#: commands/tablecmds.c:5485 #, c-format msgid "type %s is not a composite type" msgstr "el tipo %s no es un tipo compuesto" -#: commands/tablecmds.c:5068 +#: commands/tablecmds.c:5511 #, c-format msgid "cannot add column to typed table" msgstr "no se puede agregar una columna a una tabla tipada" -#: commands/tablecmds.c:5112 -#, fuzzy, c-format +#: commands/tablecmds.c:5555 +#, c-format msgid "cannot add column to a partition" -msgstr "no se puede agregar una columna a una tabla tipada" +msgstr "no se puede agregar una columna a una partición" -#: commands/tablecmds.c:5141 commands/tablecmds.c:11213 +#: commands/tablecmds.c:5584 commands/tablecmds.c:12924 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "la tabla hija «%s» tiene un tipo diferente para la columna «%s»" -#: commands/tablecmds.c:5147 commands/tablecmds.c:11220 +#: commands/tablecmds.c:5590 commands/tablecmds.c:12931 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "la tabla hija «%s» tiene un ordenamiento (collation) diferente para la columna «%s»" -#: commands/tablecmds.c:5157 -#, c-format -msgid "child table \"%s\" has a conflicting \"%s\" column" -msgstr "tabla hija «%s» tiene una columna «%s» que entra en conflicto" - -#: commands/tablecmds.c:5168 +#: commands/tablecmds.c:5604 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "mezclando la definición de la columna «%s» en la tabla hija «%s»" -#: commands/tablecmds.c:5192 +#: commands/tablecmds.c:5628 #, c-format msgid "cannot recursively add identity column to table that has child tables" msgstr "no se puede agregar una columna de identidad recursivamente a una tabla que tiene tablas hijas" -#: commands/tablecmds.c:5404 +#: commands/tablecmds.c:5862 #, c-format msgid "column must be added to child tables too" msgstr "la columna debe ser agregada a las tablas hijas también" -#: commands/tablecmds.c:5479 +#: commands/tablecmds.c:5937 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" -msgstr "la columna «%s» de la relación «%s» ya existe, ignorando" +msgstr "la columna «%s» de la relación «%s» ya existe, omitiendo" -#: commands/tablecmds.c:5486 +#: commands/tablecmds.c:5944 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "ya existe la columna «%s» en la relación «%s»" -#: commands/tablecmds.c:5584 commands/tablecmds.c:8563 +#: commands/tablecmds.c:6010 commands/tablecmds.c:10084 #, c-format msgid "cannot remove constraint from only the partitioned table when partitions exist" msgstr "no se pueden eliminar restricciones sólo de la tabla particionada cuando existen particiones" -#: commands/tablecmds.c:5585 commands/tablecmds.c:5732 -#: commands/tablecmds.c:6529 commands/tablecmds.c:8564 +#: commands/tablecmds.c:6011 commands/tablecmds.c:6280 +#: commands/tablecmds.c:7048 commands/tablecmds.c:10085 #, c-format msgid "Do not specify the ONLY keyword." msgstr "No especifique la opción ONLY." -#: commands/tablecmds.c:5617 commands/tablecmds.c:5764 -#: commands/tablecmds.c:5819 commands/tablecmds.c:5894 -#: commands/tablecmds.c:5988 commands/tablecmds.c:6047 -#: commands/tablecmds.c:6171 commands/tablecmds.c:6225 -#: commands/tablecmds.c:6317 commands/tablecmds.c:8703 -#: commands/tablecmds.c:9414 +#: commands/tablecmds.c:6048 commands/tablecmds.c:6206 +#: commands/tablecmds.c:6348 commands/tablecmds.c:6431 +#: commands/tablecmds.c:6525 commands/tablecmds.c:6584 +#: commands/tablecmds.c:6734 commands/tablecmds.c:6804 +#: commands/tablecmds.c:6896 commands/tablecmds.c:10224 +#: commands/tablecmds.c:11055 #, c-format msgid "cannot alter system column \"%s\"" msgstr "no se puede alterar columna de sistema «%s»" -#: commands/tablecmds.c:5623 commands/tablecmds.c:5825 +#: commands/tablecmds.c:6054 commands/tablecmds.c:6354 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "la columna «%s» en la relación «%s» es una columna de identidad" -#: commands/tablecmds.c:5659 +#: commands/tablecmds.c:6090 #, c-format msgid "column \"%s\" is in a primary key" msgstr "la columna «%s» está en la llave primaria" -#: commands/tablecmds.c:5681 -#, fuzzy, c-format +#: commands/tablecmds.c:6112 +#, c-format msgid "column \"%s\" is marked NOT NULL in parent table" -msgstr "columna «%s» en tabla hija debe marcarse como NOT NULL" +msgstr "columna «%s» está marcada NOT NULL en la tabla padre" -#: commands/tablecmds.c:5731 +#: commands/tablecmds.c:6277 commands/tablecmds.c:7498 #, c-format -msgid "cannot add constraint to only the partitioned table when partitions exist" -msgstr "" +msgid "constraint must be added to child tables too" +msgstr "la restricción debe ser agregada a las tablas hijas también" + +#: commands/tablecmds.c:6278 +#, c-format +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "La columna «%s» de la relación «%s» no está previamente marcada NOT NULL." + +#: commands/tablecmds.c:6313 +#, c-format +msgid "existing constraints on column \"%s\".\"%s\" are sufficient to prove that it does not contain nulls" +msgstr "las restricciones existentes en la columna «%s.%s» son suficientes para demostrar que no contiene nulos" -#: commands/tablecmds.c:5827 +#: commands/tablecmds.c:6356 #, c-format msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." -msgstr "" +msgstr "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY en su lugar." + +#: commands/tablecmds.c:6361 +#, c-format +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "la columna «%s» en la relación «%s» es una columna generada" -#: commands/tablecmds.c:5905 +#: commands/tablecmds.c:6442 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" -msgstr "" +msgstr "la columna «%s» en la relación «%s» debe ser declarada NOT NULL antes de que una identidad pueda agregarse" -#: commands/tablecmds.c:5911 -#, fuzzy, c-format +#: commands/tablecmds.c:6448 +#, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" -msgstr "ya existe la columna «%s» en la relación «%s»" +msgstr "la columna «%s» en la relación «%s» ya es una columna de identidad" -#: commands/tablecmds.c:5917 -#, fuzzy, c-format +#: commands/tablecmds.c:6454 +#, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" -msgstr "ya existe la columna «%s» en la relación «%s»" +msgstr "la columna «%s» en la relación «%s» ya tiene un valor por omisión" -#: commands/tablecmds.c:5994 commands/tablecmds.c:6055 -#, fuzzy, c-format +#: commands/tablecmds.c:6531 commands/tablecmds.c:6592 +#, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" -msgstr "no existe la columna «%s» en la relación «%s»" +msgstr "la columna «%s» en la relación «%s» no es una columna identidad" -#: commands/tablecmds.c:6060 -#, fuzzy, c-format +#: commands/tablecmds.c:6597 +#, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" -msgstr "no existe la columna «%s» en la relación «%s», ignorando" +msgstr "la columna «%s» de la relación «%s» no es una columna identidad, omitiendo" + +#: commands/tablecmds.c:6662 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "no se puede referir a columnas que no son de índice por número" -#: commands/tablecmds.c:6144 +#: commands/tablecmds.c:6693 #, c-format msgid "statistics target %d is too low" msgstr "el valor de estadísticas %d es demasiado bajo" -#: commands/tablecmds.c:6152 +#: commands/tablecmds.c:6701 #, c-format msgid "lowering statistics target to %d" msgstr "bajando el valor de estadísticas a %d" -#: commands/tablecmds.c:6297 +#: commands/tablecmds.c:6724 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "no existe la columna número %d en la relación «%s»" + +#: commands/tablecmds.c:6743 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "no se puede alterar estadísticas en la columna incluida «%s» del índice «%s»" + +#: commands/tablecmds.c:6748 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "no se puede alterar estadísticas en la columna no-de-expresión «%s» del índice «%s»" + +#: commands/tablecmds.c:6750 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Altere las estadísticas en la columna de la tabla en su lugar." + +#: commands/tablecmds.c:6876 #, c-format msgid "invalid storage type \"%s\"" msgstr "tipo de almacenamiento no válido «%s»" -#: commands/tablecmds.c:6329 +#: commands/tablecmds.c:6908 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "el tipo de datos %s de la columna sólo puede tener almacenamiento PLAIN" -#: commands/tablecmds.c:6364 +#: commands/tablecmds.c:6943 #, c-format msgid "cannot drop column from typed table" msgstr "no se pueden eliminar columnas de una tabla tipada" -#: commands/tablecmds.c:6471 +#: commands/tablecmds.c:6988 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" -msgstr "no existe la columna «%s» en la relación «%s», ignorando" +msgstr "no existe la columna «%s» en la relación «%s», omitiendo" -#: commands/tablecmds.c:6484 +#: commands/tablecmds.c:7001 #, c-format msgid "cannot drop system column \"%s\"" msgstr "no se puede eliminar la columna de sistema «%s»" -#: commands/tablecmds.c:6491 +#: commands/tablecmds.c:7008 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "no se puede eliminar la columna heredada «%s»" -#: commands/tablecmds.c:6500 -#, fuzzy, c-format +#: commands/tablecmds.c:7019 +#, c-format msgid "cannot drop column named in partition key" -msgstr "no se pueden eliminar columnas de una tabla tipada" +msgstr "no se pueden eliminar una columna parte de la llave de particionamiento" -#: commands/tablecmds.c:6504 -#, fuzzy, c-format +#: commands/tablecmds.c:7023 +#, c-format msgid "cannot drop column referenced in partition key expression" -msgstr "no se pueden usar referencias a columnas en una cláusula default" +msgstr "no se pueden eliminar columnas referenciadas en una expresión de la llave de particionamiento" -#: commands/tablecmds.c:6528 -#, fuzzy, c-format +#: commands/tablecmds.c:7047 +#, c-format msgid "cannot drop column from only the partitioned table when partitions exist" -msgstr "no se pueden eliminar columnas de una tabla tipada" +msgstr "no se pueden eliminar columnas sólo de una tabla particionada cuando existe particiones" + +#: commands/tablecmds.c:7219 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX no está soportado en tablas particionadas" -#: commands/tablecmds.c:6746 +#: commands/tablecmds.c:7244 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX renombrará el índice «%s» a «%s»" -#: commands/tablecmds.c:6958 +#: commands/tablecmds.c:7578 #, c-format -msgid "constraint must be added to child tables too" -msgstr "la restricción debe ser agregada a las tablas hijas también" +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "no se puede usar ONLY para una llave foránea en la tabla particionada «%s» haciendo referencia a la relación «%s»" -#: commands/tablecmds.c:7029 -#, fuzzy, c-format -msgid "cannot reference partitioned table \"%s\"" -msgstr "no se puede insertar en la tabla foránea «%s»" +#: commands/tablecmds.c:7584 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "no se puede agregar una llave foránea NOT VALID a la tabla particionada «%s» haciendo referencia a la relación «%s»" -#: commands/tablecmds.c:7035 +#: commands/tablecmds.c:7587 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Esta característica no está aún soportada en tablas particionadas." + +#: commands/tablecmds.c:7594 commands/tablecmds.c:7999 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "la relación referida «%s» no es una tabla" -#: commands/tablecmds.c:7058 +#: commands/tablecmds.c:7617 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "las restricciones en tablas permanentes sólo pueden hacer referencia a tablas permanentes" -#: commands/tablecmds.c:7065 +#: commands/tablecmds.c:7624 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" -msgstr "las restricciones en tablas unlogged sólo pueden hacer referencia a tablas permanentes o unlogged" +msgstr "las restricciones en tablas «unlogged» sólo pueden hacer referencia a tablas permanentes o «unlogged»" -#: commands/tablecmds.c:7071 +#: commands/tablecmds.c:7630 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "las restricciones en tablas temporales sólo pueden hacer referencia a tablas temporales" -#: commands/tablecmds.c:7075 +#: commands/tablecmds.c:7634 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "las restricciones en tablas temporales sólo pueden hacer referencia a tablas temporales de esta sesión" -#: commands/tablecmds.c:7135 +#: commands/tablecmds.c:7700 commands/tablecmds.c:7706 +#, c-format +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "acción %s no válida para restricción de llave foránea que contiene columnas generadas" + +#: commands/tablecmds.c:7722 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "el número de columnas referidas en la llave foránea no coincide con el número de columnas de referencia" -#: commands/tablecmds.c:7242 +#: commands/tablecmds.c:7829 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "la restricción de llave foránea «%s» no puede ser implementada" -#: commands/tablecmds.c:7245 +#: commands/tablecmds.c:7831 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "Las columnas llave «%s» y «%s» son de tipos incompatibles: %s y %s" -#: commands/tablecmds.c:7450 commands/tablecmds.c:7616 -#: commands/tablecmds.c:8531 commands/tablecmds.c:8599 +#: commands/tablecmds.c:8195 commands/tablecmds.c:8583 +#: parser/parse_utilcmd.c:753 parser/parse_utilcmd.c:882 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "las restricciones de llave foránea no están soportadas en tablas foráneas" + +#: commands/tablecmds.c:8950 commands/tablecmds.c:9113 +#: commands/tablecmds.c:10041 commands/tablecmds.c:10116 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "no existe la restricción «%s» en la relación «%s»" -#: commands/tablecmds.c:7456 +#: commands/tablecmds.c:8957 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "la restricción «%s» de la relación «%s» no es una restriccion de llave foránea" -#: commands/tablecmds.c:7623 +#: commands/tablecmds.c:9121 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "la restricción «%s» de la relación «%s» no es una llave foránea o restricción «check»" -#: commands/tablecmds.c:7693 +#: commands/tablecmds.c:9191 #, c-format msgid "constraint must be validated on child tables too" msgstr "la restricción debe ser validada en las tablas hijas también" -#: commands/tablecmds.c:7761 +#: commands/tablecmds.c:9257 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "no existe la columna «%s» referida en la llave foránea" -#: commands/tablecmds.c:7766 +#: commands/tablecmds.c:9262 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "no se puede tener más de %d columnas en una llave foránea" -#: commands/tablecmds.c:7831 +#: commands/tablecmds.c:9327 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "no se puede usar una llave primaria postergable para la tabla referenciada «%s»" -#: commands/tablecmds.c:7848 +#: commands/tablecmds.c:9344 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "no hay llave primaria para la tabla referida «%s»" -#: commands/tablecmds.c:7913 +#: commands/tablecmds.c:9409 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "la lista de columnas referidas en una llave foránea no debe contener duplicados" -#: commands/tablecmds.c:8007 +#: commands/tablecmds.c:9503 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "no se puede usar una restricción unique postergable para la tabla referenciada «%s»" -#: commands/tablecmds.c:8012 +#: commands/tablecmds.c:9508 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "no hay restricción unique que coincida con las columnas dadas en la tabla referida «%s»" -#: commands/tablecmds.c:8183 +#: commands/tablecmds.c:9676 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "validando restricción de llave foránea «%s»" -#: commands/tablecmds.c:8485 +#: commands/tablecmds.c:9997 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "no se puede eliminar la restricción «%s» heredada de la relación «%s»" -#: commands/tablecmds.c:8537 +#: commands/tablecmds.c:10047 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" -msgstr "no existe la restricción «%s» en la relación «%s», ignorando" +msgstr "no existe la restricción «%s» en la relación «%s», omitiendo" -#: commands/tablecmds.c:8687 +#: commands/tablecmds.c:10208 #, c-format msgid "cannot alter column type of typed table" msgstr "no se puede cambiar el tipo de una columna de una tabla tipada" -#: commands/tablecmds.c:8710 +#: commands/tablecmds.c:10231 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "no se puede alterar la columna heredada «%s»" -#: commands/tablecmds.c:8719 -#, fuzzy, c-format +#: commands/tablecmds.c:10242 +#, c-format msgid "cannot alter type of column named in partition key" -msgstr "no se puede alterar el tipo de una columna usada en una definición de trigger" +msgstr "no se puede alterar el tipo de una columna incluida en la llave de particionamiento" -#: commands/tablecmds.c:8723 -#, fuzzy, c-format +#: commands/tablecmds.c:10246 +#, c-format msgid "cannot alter type of column referenced in partition key expression" -msgstr "no se pueden usar referencias a columnas en una cláusula default" +msgstr "no se pueden alterar el tipo de una columna referenciada en expresión de la llave de particionamiento" -#: commands/tablecmds.c:8773 +#: commands/tablecmds.c:10296 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "el resultado de la cláusula USING para la columna «%s» no puede ser convertido automáticamente al tipo %s" -#: commands/tablecmds.c:8776 +#: commands/tablecmds.c:10299 #, c-format msgid "You might need to add an explicit cast." msgstr "Puede ser necesario agregar un cast explícito." -#: commands/tablecmds.c:8780 +#: commands/tablecmds.c:10303 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "la columna «%s» no puede convertirse automáticamente al tipo %s" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:8783 +#: commands/tablecmds.c:10306 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Puede ser necesario especificar «USING %s::%s»." -#: commands/tablecmds.c:8882 +#: commands/tablecmds.c:10405 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "La expresión USING contiene una referencia a la fila completa (whole-row)." -#: commands/tablecmds.c:8893 +#: commands/tablecmds.c:10416 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "debe cambiar el tipo a la columna heredada «%s» en las tablas hijas también" -#: commands/tablecmds.c:8980 +#: commands/tablecmds.c:10541 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "no se puede alterar el tipo de la columna «%s» dos veces" -#: commands/tablecmds.c:9016 +#: commands/tablecmds.c:10579 +#, c-format +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "la expresión de generación para la columna «%s» no puede ser convertido automáticamente al tipo %s" + +#: commands/tablecmds.c:10584 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "el valor por omisión para la columna «%s» no puede ser convertido automáticamente al tipo %s" -#: commands/tablecmds.c:9142 +#: commands/tablecmds.c:10673 +#, c-format +msgid "cannot alter type of a column used by a generated column" +msgstr "no se puede alterar el tipo de una columna usada por una columna generada" + +#: commands/tablecmds.c:10674 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "La columna «%s» es usada por la columna generada «%s»." + +#: commands/tablecmds.c:10706 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "no se puede alterar el tipo de una columna usada en una regla o vista" -#: commands/tablecmds.c:9143 commands/tablecmds.c:9162 -#: commands/tablecmds.c:9180 +#: commands/tablecmds.c:10707 commands/tablecmds.c:10726 +#: commands/tablecmds.c:10744 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s depende de la columna «%s»" -#: commands/tablecmds.c:9161 +#: commands/tablecmds.c:10725 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "no se puede alterar el tipo de una columna usada en una definición de trigger" -#: commands/tablecmds.c:9179 +#: commands/tablecmds.c:10743 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "no se puede alterar el tipo de una columna usada en una definición de política" -#: commands/tablecmds.c:9854 +#: commands/tablecmds.c:11573 commands/tablecmds.c:11585 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "no se puede cambiar el dueño del índice «%s»" -#: commands/tablecmds.c:9856 +#: commands/tablecmds.c:11575 commands/tablecmds.c:11587 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "Considere cambiar el dueño de la tabla en vez de cambiar el dueño del índice." -#: commands/tablecmds.c:9873 +#: commands/tablecmds.c:11601 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "no se puede cambiar el dueño de la secuencia «%s»" -#: commands/tablecmds.c:9887 commands/tablecmds.c:13116 +#: commands/tablecmds.c:11615 commands/tablecmds.c:14812 #, c-format msgid "Use ALTER TYPE instead." msgstr "Considere usar ALTER TYPE." -#: commands/tablecmds.c:9896 +#: commands/tablecmds.c:11624 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "«%s» no es una tabla, vista, secuencia o tabla foránea" -#: commands/tablecmds.c:10237 +#: commands/tablecmds.c:11964 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "no se pueden tener múltiples subórdenes SET TABLESPACE" -#: commands/tablecmds.c:10311 +#: commands/tablecmds.c:12039 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "«%s» no es una tabla, vista, tabla materializada, índice o tabla TOAST" -#: commands/tablecmds.c:10344 commands/view.c:504 +#: commands/tablecmds.c:12072 commands/view.c:504 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION sólo puede usarse en vistas automáticamente actualizables" -#: commands/tablecmds.c:10486 +#: commands/tablecmds.c:12212 #, c-format msgid "cannot move system relation \"%s\"" msgstr "no se puede mover la relación de sistema «%s»" -#: commands/tablecmds.c:10502 +#: commands/tablecmds.c:12228 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "no se pueden mover tablas temporales de otras sesiones" -#: commands/tablecmds.c:10638 +#: commands/tablecmds.c:12396 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "solamente tablas, índices y vistas materializadas existen en tablespaces" -#: commands/tablecmds.c:10650 +#: commands/tablecmds.c:12408 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "no se puede mover objetos hacia o desde el tablespace pg_global" -#: commands/tablecmds.c:10742 +#: commands/tablecmds.c:12500 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "cancelando porque el lock en la relación «%s.%s» no está disponible" -#: commands/tablecmds.c:10758 +#: commands/tablecmds.c:12516 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "no se encontraron relaciones coincidentes en el tablespace «%s»" -#: commands/tablecmds.c:10832 storage/buffer/bufmgr.c:915 -#, c-format -msgid "invalid page in block %u of relation %s" -msgstr "la página no es válida en el bloque %u de la relación %s" - -#: commands/tablecmds.c:10914 +#: commands/tablecmds.c:12632 #, c-format msgid "cannot change inheritance of typed table" msgstr "no se puede cambiar la herencia de una tabla tipada" -#: commands/tablecmds.c:10919 commands/tablecmds.c:11461 -#, fuzzy, c-format +#: commands/tablecmds.c:12637 commands/tablecmds.c:13133 +#, c-format msgid "cannot change inheritance of a partition" -msgstr "no se puede cambiar la herencia de una tabla tipada" +msgstr "no puede cambiar la herencia de una partición" -#: commands/tablecmds.c:10924 -#, fuzzy, c-format +#: commands/tablecmds.c:12642 +#, c-format msgid "cannot change inheritance of partitioned table" -msgstr "no se puede cambiar la herencia de una tabla tipada" +msgstr "no se puede cambiar la herencia de una tabla particionada" -#: commands/tablecmds.c:10970 +#: commands/tablecmds.c:12688 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "no se puede agregar herencia a tablas temporales de otra sesión" -#: commands/tablecmds.c:10983 -#, fuzzy, c-format +#: commands/tablecmds.c:12701 +#, c-format msgid "cannot inherit from a partition" -msgstr "no se puede heredar de la tabla temporal «%s»" +msgstr "no se puede heredar de una partición" -#: commands/tablecmds.c:11005 commands/tablecmds.c:13498 +#: commands/tablecmds.c:12723 commands/tablecmds.c:15448 #, c-format msgid "circular inheritance not allowed" msgstr "la herencia circular no está permitida" -#: commands/tablecmds.c:11006 commands/tablecmds.c:13499 +#: commands/tablecmds.c:12724 commands/tablecmds.c:15449 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "«%s» ya es un hijo de «%s»." -#: commands/tablecmds.c:11014 +#: commands/tablecmds.c:12737 #, c-format -msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" -msgstr "tabla «%s» sin OIDs no puede heredar de tabla «%s» con OIDs" - -#: commands/tablecmds.c:11027 -#, fuzzy, c-format -#| msgid "trigger \"%s\" for table \"%s\" does not exist" msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" -msgstr "no existe el trigger «%s» para la tabla «%s»" +msgstr "el trigger «%s» impide a la tabla «%s» convertirse en hija de herencia" -#: commands/tablecmds.c:11029 -#, fuzzy, c-format -msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" -msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" +#: commands/tablecmds.c:12739 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "Los triggers ROW con tablas de transición no están permitidos en jerarquías de herencia." -#: commands/tablecmds.c:11231 +#: commands/tablecmds.c:12942 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "columna «%s» en tabla hija debe marcarse como NOT NULL" -#: commands/tablecmds.c:11258 commands/tablecmds.c:11297 +#: commands/tablecmds.c:12969 #, c-format msgid "child table is missing column \"%s\"" msgstr "tabla hija no tiene la columna «%s»" -#: commands/tablecmds.c:11385 +#: commands/tablecmds.c:13057 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "la tabla hija «%s» tiene una definición diferente para la restricción «check» «%s»" -#: commands/tablecmds.c:11393 +#: commands/tablecmds.c:13065 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "la restricción «%s» está en conflicto con la restricción no heredada en la tabla hija «%s»" -#: commands/tablecmds.c:11404 +#: commands/tablecmds.c:13076 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "la restricción «%s» está en conflicto con la restricción NOT VALID en la tabla hija «%s»" -#: commands/tablecmds.c:11439 +#: commands/tablecmds.c:13111 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "tabla hija no tiene la restricción «%s»" -#: commands/tablecmds.c:11555 -#, fuzzy, c-format +#: commands/tablecmds.c:13200 +#, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" -msgstr "relación «%s» no es un padre de la relación «%s»" +msgstr "relación «%s» no es una partición de la relación «%s»" -#: commands/tablecmds.c:11561 +#: commands/tablecmds.c:13206 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "relación «%s» no es un padre de la relación «%s»" -#: commands/tablecmds.c:11787 +#: commands/tablecmds.c:13434 #, c-format msgid "typed tables cannot inherit" msgstr "las tablas tipadas no pueden heredar" -#: commands/tablecmds.c:11818 +#: commands/tablecmds.c:13464 #, c-format msgid "table is missing column \"%s\"" msgstr "la tabla no tiene la columna «%s»" -#: commands/tablecmds.c:11828 +#: commands/tablecmds.c:13475 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "la tabla tiene columna «%s» en la posición en que el tipo requiere «%s»." -#: commands/tablecmds.c:11837 +#: commands/tablecmds.c:13484 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "la tabla «%s» tiene un tipo diferente para la columna «%s»" -#: commands/tablecmds.c:11850 +#: commands/tablecmds.c:13498 #, c-format msgid "table has extra column \"%s\"" msgstr "tabla tiene la columna extra «%s»" -#: commands/tablecmds.c:11902 +#: commands/tablecmds.c:13550 #, c-format msgid "\"%s\" is not a typed table" msgstr "«%s» no es una tabla tipada" -#: commands/tablecmds.c:12084 +#: commands/tablecmds.c:13732 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "no se puede usar el índice no-único «%s» como identidad de réplica" -#: commands/tablecmds.c:12090 +#: commands/tablecmds.c:13738 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "no puede usar el índice no-inmediato «%s» como identidad de réplica" -#: commands/tablecmds.c:12096 +#: commands/tablecmds.c:13744 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "no se puede usar el índice funcional «%s» como identidad de réplica" -#: commands/tablecmds.c:12102 +#: commands/tablecmds.c:13750 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "no se puede usar el índice parcial «%s» como identidad de réplica" -#: commands/tablecmds.c:12108 +#: commands/tablecmds.c:13756 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "no se puede usar el índice no válido «%s» como identidad de réplica" -#: commands/tablecmds.c:12129 +#: commands/tablecmds.c:13773 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "el índice «%s» no puede usarse como identidad de réplica porque la column %d es una columna de sistema" -#: commands/tablecmds.c:12136 +#: commands/tablecmds.c:13780 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "el índice «%s» no puede usarse como identidad de réplica porque la column «%s» acepta valores nulos" -#: commands/tablecmds.c:12329 +#: commands/tablecmds.c:13973 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "no se puede cambiar el estado «logged» de la tabla «%s» porque es temporal" -#: commands/tablecmds.c:12353 -#, fuzzy, c-format +#: commands/tablecmds.c:13997 +#, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" -msgstr "no se pudo cambiar la tabla «%s» a «unlogged» porque hace referencia a la tabla «logged» «%s»" +msgstr "no se pudo cambiar la tabla «%s» a «unlogged» porque es parte de una publicación" -#: commands/tablecmds.c:12355 -#, fuzzy, c-format +#: commands/tablecmds.c:13999 +#, c-format msgid "Unlogged relations cannot be replicated." -msgstr "no se pueden anidar llamadas a funciones de agregación" +msgstr "Las tablas «unlogged» no pueden replicarse." -#: commands/tablecmds.c:12400 +#: commands/tablecmds.c:14044 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "no se pudo cambiar la tabla «%s» a «logged» porque hace referencia a la tabla «unlogged» «%s»" -#: commands/tablecmds.c:12410 +#: commands/tablecmds.c:14054 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "no se pudo cambiar la tabla «%s» a «unlogged» porque hace referencia a la tabla «logged» «%s»" -#: commands/tablecmds.c:12468 +#: commands/tablecmds.c:14112 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "no se puede mover una secuencia enlazada a una tabla hacia otro esquema" -#: commands/tablecmds.c:12574 +#: commands/tablecmds.c:14218 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "ya existe una relación llamada «%s» en el esquema «%s»" -#: commands/tablecmds.c:13100 +#: commands/tablecmds.c:14795 #, c-format msgid "\"%s\" is not a composite type" msgstr "«%s» no es un tipo compuesto" -#: commands/tablecmds.c:13131 +#: commands/tablecmds.c:14827 #, c-format msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" msgstr "«%s» no es una tabla, vista, vista materializada, secuencia o tabla foránea" -#: commands/tablecmds.c:13164 -#, fuzzy, c-format +#: commands/tablecmds.c:14862 +#, c-format msgid "unrecognized partitioning strategy \"%s\"" -msgstr "tipo de privilegio no reconocido: «%s»" +msgstr "estrategia de particionamiento «%s» no reconocida" -#: commands/tablecmds.c:13172 -#, fuzzy, c-format +#: commands/tablecmds.c:14870 +#, c-format msgid "cannot use \"list\" partition strategy with more than one column" -msgstr "no se puede usar más de %d columnas en un índice" - -#: commands/tablecmds.c:13197 -#, fuzzy, c-format -msgid "column \"%s\" appears more than once in partition key" -msgstr "la columna común «%s» aparece más de una vez en la tabla derecha" +msgstr "no se puede usar la estrategia de particionamiento «list» con más de una columna" -#: commands/tablecmds.c:13250 -#, fuzzy, c-format +#: commands/tablecmds.c:14936 +#, c-format msgid "column \"%s\" named in partition key does not exist" -msgstr "no existe la columna «%s» en la llave" +msgstr "la columna «%s» nombrada en llave de particionamiento no existe" -#: commands/tablecmds.c:13257 -#, fuzzy, c-format +#: commands/tablecmds.c:14944 +#, c-format msgid "cannot use system column \"%s\" in partition key" -msgstr "no se puede alterar columna de sistema «%s»" +msgstr "no se puede usar la columna de sistema «%s» en llave de particionamiento" + +#: commands/tablecmds.c:14955 commands/tablecmds.c:15060 +#, c-format +msgid "cannot use generated column in partition key" +msgstr "no se puede usar una columna generada en llave de particionamiento" + +#: commands/tablecmds.c:14956 commands/tablecmds.c:15061 commands/trigger.c:659 +#: rewrite/rewriteHandler.c:826 rewrite/rewriteHandler.c:843 +#, c-format +msgid "Column \"%s\" is a generated column." +msgstr "La columna «%s» es una columna generada." -#: commands/tablecmds.c:13320 -#, fuzzy, c-format +#: commands/tablecmds.c:15020 +#, c-format msgid "functions in partition key expression must be marked IMMUTABLE" -msgstr "las funciones utilizadas en expresiones de índice deben estar marcadas IMMUTABLE" +msgstr "las funciones utilizadas en expresiones de la llave de particionamiento deben estar marcadas IMMUTABLE" -#: commands/tablecmds.c:13337 -#, fuzzy, c-format +#: commands/tablecmds.c:15037 +#, c-format msgid "partition key expressions cannot contain whole-row references" -msgstr "La expresión USING contiene una referencia a la fila completa (whole-row)." +msgstr "las expresiones en la llave de particionamiento no pueden incluir referencias a la fila completa (whole-row)" -#: commands/tablecmds.c:13344 -#, fuzzy, c-format +#: commands/tablecmds.c:15044 +#, c-format msgid "partition key expressions cannot contain system column references" -msgstr "La expresión USING contiene una referencia a la fila completa (whole-row)." +msgstr "las expresiones en la llave de particionamiento no pueden contener referencias a columnas de sistema" -#: commands/tablecmds.c:13354 -#, fuzzy, c-format +#: commands/tablecmds.c:15073 +#, c-format msgid "cannot use constant expression as partition key" -msgstr "no se puede usar el índice funcional «%s» como identidad de réplica" +msgstr "no se pueden usar expresiones constantes como llave de particionamiento" -#: commands/tablecmds.c:13375 -#, fuzzy, c-format +#: commands/tablecmds.c:15094 +#, c-format msgid "could not determine which collation to use for partition expression" -msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de índice" +msgstr "no se pudo determinar qué ordenamiento (collation) usar para la expresión de particionamiento" -#: commands/tablecmds.c:13400 -#, fuzzy, c-format -msgid "data type %s has no default btree operator class" -msgstr "el tipo de dato %s no tiene una clase de operadores por omisión para el método de acceso «%s»" +#: commands/tablecmds.c:15129 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Debe especificar una clase de operadores hash, o definir una clase de operadores por omisión para hash para el tipo de datos." -#: commands/tablecmds.c:13402 -#, fuzzy, c-format +#: commands/tablecmds.c:15135 +#, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." -msgstr "Debe especificar una clase de operadores para el índice, o definir una clase de operadores por omisión para el tipo de datos." +msgstr "Debe especificar una clase de operadores btree, o definir una clase de operadores por omisión para btree para el tipo de datos." -#: commands/tablecmds.c:13449 -#, fuzzy, c-format -msgid "\"%s\" is already a partition" -msgstr "«%s» ya es una vista" +#: commands/tablecmds.c:15280 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "la restricción de partición para la tabla \"%s\" está implícita en las restricciones existentes" -#: commands/tablecmds.c:13455 -#, fuzzy, c-format -msgid "cannot attach a typed table as partition" -msgstr "no se puede agregar una columna a una tabla tipada" +#: commands/tablecmds.c:15284 partitioning/partbounds.c:1249 +#: partitioning/partbounds.c:1292 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "la restricción de partición actualizada para la partición por omisión \"%s\" está implícita en las restricciones existentes" + +#: commands/tablecmds.c:15388 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "«%s» ya es una partición" + +#: commands/tablecmds.c:15394 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "no puede adjuntar tabla tipada como partición" -#: commands/tablecmds.c:13471 +#: commands/tablecmds.c:15410 #, c-format msgid "cannot attach inheritance child as partition" -msgstr "" +msgstr "no puede adjuntar hija de herencia como partición" -#: commands/tablecmds.c:13485 -#, fuzzy, c-format +#: commands/tablecmds.c:15424 +#, c-format msgid "cannot attach inheritance parent as partition" -msgstr "no se puede cambiar la herencia de una tabla tipada" +msgstr "no puede adjuntar ancestro de herencia como partición" + +#: commands/tablecmds.c:15458 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "no se puede adjuntar una relación temporal como partición de la relación permanente «%s»" -#: commands/tablecmds.c:13508 -#, fuzzy, c-format +#: commands/tablecmds.c:15466 +#, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" -msgstr "no se puede heredar de la tabla temporal «%s»" +msgstr "no se puede adjuntar una relación permanente como partición de la relación temporal «%s»" -#: commands/tablecmds.c:13516 -#, fuzzy, c-format +#: commands/tablecmds.c:15474 +#, c-format msgid "cannot attach as partition of temporary relation of another session" -msgstr "no se puede agregar herencia a tablas temporales de otra sesión" +msgstr "no se puede adjuntar como partición de una relación temporal de otra sesión" -#: commands/tablecmds.c:13523 -#, fuzzy, c-format +#: commands/tablecmds.c:15481 +#, c-format msgid "cannot attach temporary relation of another session as partition" -msgstr "no se puede agregar herencia a tablas temporales de otra sesión" - -#: commands/tablecmds.c:13529 -#, fuzzy, c-format -msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" -msgstr "tabla «%s» sin OIDs no puede heredar de tabla «%s» con OIDs" +msgstr "no se adjuntar una relación temporal de otra sesión como partición" -#: commands/tablecmds.c:13537 -#, fuzzy, c-format -msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" -msgstr "tabla «%s» sin OIDs no puede heredar de tabla «%s» con OIDs" - -#: commands/tablecmds.c:13559 -#, fuzzy, c-format +#: commands/tablecmds.c:15501 +#, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" -msgstr "la columna «%s» no fue encontrado en el tipo %s" +msgstr "la tabla «%s» contiene la columna «%s» no encontrada en el padre «%s»" -#: commands/tablecmds.c:13562 +#: commands/tablecmds.c:15504 #, c-format -msgid "New partition should contain only the columns present in parent." -msgstr "" +msgid "The new partition may contain only the columns present in parent." +msgstr "La nueva partición sólo puede contener las columnas presentes en el padre." -#: commands/tablecmds.c:13574 -#, fuzzy, c-format -#| msgid "trigger \"%s\" for table \"%s\" does not exist" +#: commands/tablecmds.c:15516 +#, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" -msgstr "no existe el trigger «%s» para la tabla «%s»" +msgstr "el trigger «%s» impide a la tabla «%s» devenir partición" -#: commands/tablecmds.c:13576 commands/trigger.c:387 -#, fuzzy, c-format +#: commands/tablecmds.c:15518 commands/trigger.c:465 +#, c-format msgid "ROW triggers with transition tables are not supported on partitions" -msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" +msgstr "los triggers ROW con tablas de transición no están soportados en particiones" -#: commands/tablecmds.c:13690 +#: commands/tablecmds.c:16211 commands/tablecmds.c:16230 +#: commands/tablecmds.c:16252 commands/tablecmds.c:16271 +#: commands/tablecmds.c:16313 #, c-format -msgid "partition constraint for table \"%s\" is implied by existing constraints" -msgstr "" +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "no se puede adjuntar el índice «%s» como partición del índice «%s»" + +#: commands/tablecmds.c:16214 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "El índice «%s» ya está adjunto a otro índice." -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:623 replication/slot.c:1117 storage/file/copydir.c:47 +#: commands/tablecmds.c:16233 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "El índice «%s» no es un índice en una partición de la tabla «%s»." + +#: commands/tablecmds.c:16255 +#, c-format +msgid "The index definitions do not match." +msgstr "Las definiciones de los índices no coinciden." + +#: commands/tablecmds.c:16274 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "El índice «%s» pertenece a una restricción en la tabla «%s», pero no existe una restricción para el índice «%s»." + +#: commands/tablecmds.c:16316 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "Otro índice ya está adjunto para la partición «%s»." + +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:630 replication/slot.c:1198 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "no se pudo crear el directorio «%s»: %m" -#: commands/tablespace.c:209 utils/adt/genfile.c:538 +#: commands/tablespace.c:210 utils/adt/genfile.c:593 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "no se pudo hacer stat al directorio «%s»: %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "«%s» existe pero no es un directorio" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "se ha denegado el permiso para crear el tablespace «%s»" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "Debe ser superusuario para crear tablespaces." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "la ruta del tablespace no puede contener comillas simples" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "la ubicación del tablespace debe ser una ruta absoluta" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "la ruta «%s» del tablespace es demasiado larga" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "la ubicación del tablespace no debe estar dentro del directorio de datos" -#: commands/tablespace.c:304 commands/tablespace.c:950 +#: commands/tablespace.c:306 commands/tablespace.c:957 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "el nombre de tablespace «%s» es inaceptable" -#: commands/tablespace.c:306 commands/tablespace.c:951 +#: commands/tablespace.c:308 commands/tablespace.c:958 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "El prefijo «pg_» está reservado para tablespaces del sistema." -#: commands/tablespace.c:316 commands/tablespace.c:963 +#: commands/tablespace.c:318 commands/tablespace.c:970 #, c-format msgid "tablespace \"%s\" already exists" msgstr "el tablespace «%s» ya existe" -#: commands/tablespace.c:428 commands/tablespace.c:933 -#: commands/tablespace.c:1013 commands/tablespace.c:1081 -#: commands/tablespace.c:1214 commands/tablespace.c:1414 +#: commands/tablespace.c:434 commands/tablespace.c:940 +#: commands/tablespace.c:1020 commands/tablespace.c:1088 +#: commands/tablespace.c:1231 commands/tablespace.c:1431 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "no existe el tablespace «%s»" -#: commands/tablespace.c:434 +#: commands/tablespace.c:440 #, c-format msgid "tablespace \"%s\" does not exist, skipping" -msgstr "el tablespace «%s» no existe, ignorando" +msgstr "el tablespace «%s» no existe, omitiendo" -#: commands/tablespace.c:510 +#: commands/tablespace.c:517 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "el tablespace «%s» no está vacío" -#: commands/tablespace.c:582 +#: commands/tablespace.c:589 #, c-format msgid "directory \"%s\" does not exist" msgstr "no existe el directorio «%s»" -#: commands/tablespace.c:583 +#: commands/tablespace.c:590 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "Cree este directorio para el tablespace antes de reiniciar el servidor." -#: commands/tablespace.c:588 +#: commands/tablespace.c:595 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "no se pudo definir los permisos del directorio «%s»: %m" -#: commands/tablespace.c:618 +#: commands/tablespace.c:625 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "el directorio «%s» ya está siendo usado como tablespace" -#: commands/tablespace.c:742 commands/tablespace.c:755 -#: commands/tablespace.c:791 commands/tablespace.c:883 +#: commands/tablespace.c:710 commands/tablespace.c:720 +#: postmaster/postmaster.c:1474 storage/file/fd.c:2562 +#: storage/file/reinit.c:122 utils/adt/genfile.c:487 utils/adt/genfile.c:565 +#: utils/adt/misc.c:243 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: commands/tablespace.c:749 commands/tablespace.c:762 +#: commands/tablespace.c:798 commands/tablespace.c:890 storage/file/fd.c:2992 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "no se pudo eliminar el directorio «%s»: %m" -#: commands/tablespace.c:804 commands/tablespace.c:892 +#: commands/tablespace.c:811 commands/tablespace.c:899 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "no se pudo eliminar el enlace simbólico «%s»: %m" -#: commands/tablespace.c:814 commands/tablespace.c:901 +#: commands/tablespace.c:821 commands/tablespace.c:908 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "«%s» no es un directorio o enlace simbólico" -#: commands/tablespace.c:1086 +#: commands/tablespace.c:1093 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "No existe el tablespace «%s»." -#: commands/tablespace.c:1513 +#: commands/tablespace.c:1530 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "algunos directorios para el tablespace %u no pudieron eliminarse" -#: commands/tablespace.c:1515 +#: commands/tablespace.c:1532 #, c-format msgid "You can remove the directories manually if necessary." msgstr "Puede eliminar los directorios manualmente, si es necesario." -#: commands/trigger.c:189 +#: commands/trigger.c:210 commands/trigger.c:221 #, c-format msgid "\"%s\" is a table" msgstr "«%s» es una tabla" -#: commands/trigger.c:191 +#: commands/trigger.c:212 commands/trigger.c:223 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "Las tablas no pueden tener disparadores INSTEAD OF." -#: commands/trigger.c:198 -#, fuzzy, c-format -msgid "Partitioned tables cannot have ROW triggers." -msgstr "Las tablas foráneas no pueden tener disparadores TRUNCATE." +#: commands/trigger.c:240 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "Las tablas particionadas no pueden tener disparadores BEFORE / FOR EACH ROW." + +#: commands/trigger.c:258 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Los triggers en tablas particionadas no pueden tener tablas de transición." -#: commands/trigger.c:209 commands/trigger.c:216 commands/trigger.c:369 +#: commands/trigger.c:270 commands/trigger.c:277 commands/trigger.c:447 #, c-format msgid "\"%s\" is a view" msgstr "«%s» es una vista" -#: commands/trigger.c:211 +#: commands/trigger.c:272 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "Las vistas no pueden tener disparadores BEFORE o AFTER a nivel de fila." -#: commands/trigger.c:218 +#: commands/trigger.c:279 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "Las vistas no pueden tener disparadores TRUNCATE." -#: commands/trigger.c:226 commands/trigger.c:233 commands/trigger.c:240 -#: commands/trigger.c:362 +#: commands/trigger.c:287 commands/trigger.c:294 commands/trigger.c:306 +#: commands/trigger.c:440 #, c-format msgid "\"%s\" is a foreign table" msgstr "«%s» es una tabla foránea" -#: commands/trigger.c:228 +#: commands/trigger.c:289 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "Las tablas foráneas no pueden tener disparadores INSTEAD OF." -#: commands/trigger.c:235 +#: commands/trigger.c:296 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "Las tablas foráneas no pueden tener disparadores TRUNCATE." -#: commands/trigger.c:242 +#: commands/trigger.c:308 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "Las tablas foráneas no pueden tener disparadores de restricción." -#: commands/trigger.c:305 +#: commands/trigger.c:383 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" -#: commands/trigger.c:313 +#: commands/trigger.c:391 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "los disparadores INSTEAD OF deben ser FOR EACH ROW" -#: commands/trigger.c:317 +#: commands/trigger.c:395 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "los disparadores INSTEAD OF no pueden tener condiciones WHEN" -#: commands/trigger.c:321 +#: commands/trigger.c:399 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "los disparadores INSTEAD OF no pueden tener listas de columnas" -#: commands/trigger.c:350 +#: commands/trigger.c:428 #, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" -msgstr "" +msgstr "dar nombre a una variable ROW en la cláusula REFERENCING no está soportado" -#: commands/trigger.c:351 +#: commands/trigger.c:429 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." -msgstr "" +msgstr "utilice OLD TABLE o NEW TABLE para nombrar tablas de transición." -#: commands/trigger.c:364 -#, fuzzy, c-format +#: commands/trigger.c:442 +#, c-format msgid "Triggers on foreign tables cannot have transition tables." -msgstr "Las tablas foráneas no pueden tener disparadores de restricción." +msgstr "Las tablas foráneas no pueden tener tablas de transición." -#: commands/trigger.c:371 -#, fuzzy, c-format +#: commands/trigger.c:449 +#, c-format msgid "Triggers on views cannot have transition tables." -msgstr "Las tablas foráneas no pueden tener disparadores de restricción." +msgstr "Las triggers en vistas no pueden tener tablas de transición." -#: commands/trigger.c:391 -#, fuzzy, c-format +#: commands/trigger.c:469 +#, c-format msgid "ROW triggers with transition tables are not supported on inheritance children" -msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" +msgstr "los triggers ROW con tablas de transición no están soportados con hijas de herencia" -#: commands/trigger.c:397 +#: commands/trigger.c:475 #, c-format msgid "transition table name can only be specified for an AFTER trigger" -msgstr "" +msgstr "el nombre de la tabla de transición solo se puede especificar para un disparador AFTER" -#: commands/trigger.c:402 -#, fuzzy, c-format +#: commands/trigger.c:480 +#, c-format msgid "TRUNCATE triggers with transition tables are not supported" -msgstr "los disparadores TRUNCATE FOR EACH ROW no están soportados" +msgstr "los triggers TRUNCATE con tablas de transición no están soportados" -#: commands/trigger.c:419 -#, fuzzy, c-format -#| msgid "option \"%s\" cannot be specified with other options" -msgid "Transition tables cannot be specified for triggers with more than one event" -msgstr "la opción «%s» no puede ser especificada con otras opciones" +#: commands/trigger.c:497 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "las tablas de transición no pueden especificarse para triggers con más de un evento" -#: commands/trigger.c:427 +#: commands/trigger.c:508 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "las tablas de transición no pueden especificarse para triggers con lista de columnas" + +#: commands/trigger.c:525 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" -msgstr "" +msgstr "NEW TABLE sólo se puede especificar para un disparador INSERT o UPDATE" -#: commands/trigger.c:432 +#: commands/trigger.c:530 #, c-format msgid "NEW TABLE cannot be specified multiple times" -msgstr "" +msgstr "NEW TABLE no se puede especificar varias veces" -#: commands/trigger.c:442 +#: commands/trigger.c:540 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" -msgstr "" +msgstr "OLD TABLE sólo se puede especificar para un disparador DELETE o UPDATE" -#: commands/trigger.c:447 +#: commands/trigger.c:545 #, c-format msgid "OLD TABLE cannot be specified multiple times" -msgstr "" +msgstr "OLD TABLE no se puede especificar varias veces" -#: commands/trigger.c:457 +#: commands/trigger.c:555 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" -msgstr "" +msgstr "el nombre de OLD TABLE y el nombre de NEW TABLE no pueden ser iguales" -#: commands/trigger.c:514 commands/trigger.c:527 +#: commands/trigger.c:619 commands/trigger.c:632 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "la condición WHEN de un disparador por sentencias no pueden referirse a los valores de las columnas" -#: commands/trigger.c:519 +#: commands/trigger.c:624 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "la condición WHEN de un disparador en INSERT no puede referirse a valores OLD" -#: commands/trigger.c:532 +#: commands/trigger.c:637 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "la condición WHEN de un disparador en DELETE no puede referirse a valores NEW" -#: commands/trigger.c:537 +#: commands/trigger.c:642 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "la condición WHEN de un disparador BEFORE no puede referirse a columnas de sistema de NEW" -#: commands/trigger.c:702 commands/trigger.c:1473 +#: commands/trigger.c:650 commands/trigger.c:658 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "la condición WHEN del trigger BEFORE no puede hacer referencia a columnas NEW generadas" + +#: commands/trigger.c:651 +#, c-format +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "Se utiliza una referencia de la tupla completa, y la tabla contiene columnas generadas" + +#: commands/trigger.c:833 commands/trigger.c:1724 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "ya existe un trigger «%s» para la relación «%s»" -#: commands/trigger.c:998 +#: commands/trigger.c:1249 msgid "Found referenced table's UPDATE trigger." msgstr "Se encontró el disparador UPDATE de la tabla referenciada." -#: commands/trigger.c:999 +#: commands/trigger.c:1250 msgid "Found referenced table's DELETE trigger." msgstr "Se encontró el disparador DELETE de la tabla referenciada." -#: commands/trigger.c:1000 +#: commands/trigger.c:1251 msgid "Found referencing table's trigger." msgstr "Se encontró el disparador en la tabla que hace referencia." -#: commands/trigger.c:1109 commands/trigger.c:1125 +#: commands/trigger.c:1360 commands/trigger.c:1376 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "ignorando el grupo de disparadores incompleto para la restricción «%s» %s" -#: commands/trigger.c:1138 +#: commands/trigger.c:1389 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "convirtiendo el grupo de disparadores en la restricción «%s» %s" -#: commands/trigger.c:1359 commands/trigger.c:1518 commands/trigger.c:1633 +#: commands/trigger.c:1610 commands/trigger.c:1771 commands/trigger.c:1907 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "no existe el trigger «%s» para la tabla «%s»" -#: commands/trigger.c:1601 +#: commands/trigger.c:1854 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "permiso denegado: «%s» es un trigger de sistema" -#: commands/trigger.c:2270 +#: commands/trigger.c:2454 #, c-format msgid "trigger function %u returned null value" msgstr "la función de trigger %u ha retornado un valor null" -#: commands/trigger.c:2331 commands/trigger.c:2541 commands/trigger.c:2755 -#: commands/trigger.c:3040 +#: commands/trigger.c:2520 commands/trigger.c:2737 commands/trigger.c:2989 +#: commands/trigger.c:3293 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "un trigger BEFORE STATEMENT no puede retornar un valor" -#: commands/trigger.c:3102 executor/nodeModifyTable.c:795 -#: executor/nodeModifyTable.c:1092 +#: commands/trigger.c:3356 executor/nodeModifyTable.c:1350 +#: executor/nodeModifyTable.c:1421 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "el registro a ser actualizado ya fue modificado por una operación disparada por la orden actual" -#: commands/trigger.c:3103 executor/nodeModifyTable.c:796 -#: executor/nodeModifyTable.c:1093 +#: commands/trigger.c:3357 executor/nodeModifyTable.c:809 +#: executor/nodeModifyTable.c:884 executor/nodeModifyTable.c:1351 +#: executor/nodeModifyTable.c:1422 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Considere usar un disparador AFTER en lugar de un disparador BEFORE para propagar cambios a otros registros." -#: commands/trigger.c:3117 executor/execMain.c:2644 -#: executor/nodeLockRows.c:216 executor/nodeModifyTable.c:214 -#: executor/nodeModifyTable.c:808 executor/nodeModifyTable.c:1105 -#: executor/nodeModifyTable.c:1272 +#: commands/trigger.c:3388 executor/nodeLockRows.c:231 +#: executor/nodeLockRows.c:240 executor/nodeModifyTable.c:220 +#: executor/nodeModifyTable.c:825 executor/nodeModifyTable.c:1367 +#: executor/nodeModifyTable.c:1585 #, c-format msgid "could not serialize access due to concurrent update" msgstr "no se pudo serializar el acceso debido a un update concurrente" -#: commands/trigger.c:4983 +#: commands/trigger.c:3396 executor/nodeModifyTable.c:916 +#: executor/nodeModifyTable.c:1439 executor/nodeModifyTable.c:1609 +#, c-format +msgid "could not serialize access due to concurrent delete" +msgstr "no se pudo serializar el acceso debido a un delete concurrente" + +#: commands/trigger.c:5447 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "la restricción «%s» no es postergable" -#: commands/trigger.c:5006 +#: commands/trigger.c:5470 #, c-format msgid "constraint \"%s\" does not exist" msgstr "no existe la restricción «%s»" -#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:679 +#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:686 #, c-format msgid "function %s should return type %s" msgstr "la función %s debería retornar el tipo %s" @@ -9726,729 +10238,666 @@ msgstr "la función %s debería retornar el tipo %s" msgid "must be superuser to create text search parsers" msgstr "debe ser superusuario para crear analizadores de búsqueda en texto" -#: commands/tsearchcmds.c:240 +#: commands/tsearchcmds.c:245 #, c-format msgid "text search parser parameter \"%s\" not recognized" msgstr "el parámetro de analizador de búsqueda en texto «%s» no es reconocido" -#: commands/tsearchcmds.c:250 +#: commands/tsearchcmds.c:255 #, c-format msgid "text search parser start method is required" msgstr "el método «start» del analizador de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:255 +#: commands/tsearchcmds.c:260 #, c-format msgid "text search parser gettoken method is required" msgstr "el método «gettoken» del analizador de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:260 +#: commands/tsearchcmds.c:265 #, c-format msgid "text search parser end method is required" msgstr "el método «end» del analizador de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:265 +#: commands/tsearchcmds.c:270 #, c-format msgid "text search parser lextypes method is required" msgstr "el método «lextypes» del analizador de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:384 +#: commands/tsearchcmds.c:387 #, c-format msgid "text search template \"%s\" does not accept options" msgstr "la plantilla de búsquede en texto «%s» no acepta opciones" -#: commands/tsearchcmds.c:458 +#: commands/tsearchcmds.c:461 #, c-format msgid "text search template is required" msgstr "la plantilla de búsqueda en texto es obligatoria" -#: commands/tsearchcmds.c:746 +#: commands/tsearchcmds.c:753 #, c-format msgid "must be superuser to create text search templates" msgstr "debe ser superusuario para crear una plantilla de búsqueda en texto" -#: commands/tsearchcmds.c:783 +#: commands/tsearchcmds.c:795 #, c-format msgid "text search template parameter \"%s\" not recognized" msgstr "el parámetro de la plantilla de búsqueda en texto «%s» no es reconocido" -#: commands/tsearchcmds.c:793 +#: commands/tsearchcmds.c:805 #, c-format msgid "text search template lexize method is required" msgstr "el método «lexize» de la plantilla de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:1000 +#: commands/tsearchcmds.c:1009 #, c-format msgid "text search configuration parameter \"%s\" not recognized" msgstr "el parámetro de configuración de búsqueda en texto «%s» no es reconocido" -#: commands/tsearchcmds.c:1007 +#: commands/tsearchcmds.c:1016 #, c-format msgid "cannot specify both PARSER and COPY options" msgstr "no se puede especificar simultáneamente las opciones PARSER y COPY" -#: commands/tsearchcmds.c:1043 +#: commands/tsearchcmds.c:1052 #, c-format msgid "text search parser is required" msgstr "el analizador de búsqueda en texto es obligatorio" -#: commands/tsearchcmds.c:1266 +#: commands/tsearchcmds.c:1276 #, c-format msgid "token type \"%s\" does not exist" msgstr "no existe el tipo de elemento «%s»" -#: commands/tsearchcmds.c:1487 +#: commands/tsearchcmds.c:1503 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "no existe un mapeo para el tipo de elemento «%s»" -#: commands/tsearchcmds.c:1493 +#: commands/tsearchcmds.c:1509 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" -msgstr "el mapeo para el tipo de elemento «%s» no existe, ignorando" +msgstr "el mapeo para el tipo de elemento «%s» no existe, omitiendo" -#: commands/tsearchcmds.c:1648 commands/tsearchcmds.c:1759 +#: commands/tsearchcmds.c:1664 commands/tsearchcmds.c:1775 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "el formato de la lista de parámetros no es válido: «%s»" -#: commands/typecmds.c:183 +#: commands/typecmds.c:184 #, c-format msgid "must be superuser to create a base type" msgstr "debe ser superusuario para crear un tipo base" -#: commands/typecmds.c:290 commands/typecmds.c:1414 +#: commands/typecmds.c:291 commands/typecmds.c:1467 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "el atributo de tipo «%s» no es reconocido" -#: commands/typecmds.c:346 +#: commands/typecmds.c:347 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "la categoría de tipo «%s» no es válida: debe ser ASCII simple" -#: commands/typecmds.c:365 +#: commands/typecmds.c:366 #, c-format msgid "array element type cannot be %s" msgstr "el tipo de elemento de array no puede ser %s" -#: commands/typecmds.c:397 +#: commands/typecmds.c:398 #, c-format msgid "alignment \"%s\" not recognized" msgstr "el alineamiento «%s» no es reconocido" -#: commands/typecmds.c:414 +#: commands/typecmds.c:415 #, c-format msgid "storage \"%s\" not recognized" msgstr "el almacenamiento «%s» no es reconocido" -#: commands/typecmds.c:425 +#: commands/typecmds.c:426 #, c-format msgid "type input function must be specified" msgstr "debe especificarse la función de ingreso del tipo" -#: commands/typecmds.c:429 +#: commands/typecmds.c:430 #, c-format msgid "type output function must be specified" msgstr "debe especificarse la función de salida de tipo" -#: commands/typecmds.c:434 +#: commands/typecmds.c:435 #, c-format msgid "type modifier output function is useless without a type modifier input function" msgstr "la función de salida de modificadores de tipo es inútil sin una función de entrada de modificadores de tipo" -#: commands/typecmds.c:464 +#: commands/typecmds.c:465 #, c-format msgid "type input function %s must return type %s" msgstr "la función de entrada %s del tipo debe retornar %s" -#: commands/typecmds.c:481 +#: commands/typecmds.c:482 #, c-format msgid "type output function %s must return type %s" msgstr "la función de salida %s del tipo debe retornar %s" -#: commands/typecmds.c:490 +#: commands/typecmds.c:491 #, c-format msgid "type receive function %s must return type %s" msgstr "la función de recepción %s del tipo debe retornar %s" -#: commands/typecmds.c:499 +#: commands/typecmds.c:500 #, c-format msgid "type send function %s must return type %s" msgstr "la función «send» %s del tipo debe retornar %s" -#: commands/typecmds.c:564 +#: commands/typecmds.c:565 #, c-format msgid "type input function %s should not be volatile" msgstr "la función de entrada %s no debe ser volatile" -#: commands/typecmds.c:569 +#: commands/typecmds.c:570 #, c-format msgid "type output function %s should not be volatile" msgstr "la función de salida %s no debe ser volatile" -#: commands/typecmds.c:574 +#: commands/typecmds.c:575 #, c-format msgid "type receive function %s should not be volatile" msgstr "la función «receive» %s del tipo no debe ser volatile" -#: commands/typecmds.c:579 +#: commands/typecmds.c:580 #, c-format msgid "type send function %s should not be volatile" msgstr "la función «send» %s no debe ser volatile" -#: commands/typecmds.c:584 +#: commands/typecmds.c:585 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "la función de modificadores de tipo %s no debe ser volatile" -#: commands/typecmds.c:589 +#: commands/typecmds.c:590 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "la función de salida de modificadores de tipo %s no debe ser volatile" -#: commands/typecmds.c:811 +#: commands/typecmds.c:817 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "«%s» no es un tipo de dato base válido para un dominio" -#: commands/typecmds.c:897 +#: commands/typecmds.c:903 #, c-format msgid "multiple default expressions" msgstr "múltiples expresiones default" -#: commands/typecmds.c:959 commands/typecmds.c:968 +#: commands/typecmds.c:966 commands/typecmds.c:975 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "las restricciones NULL/NOT NULL no coinciden" -#: commands/typecmds.c:984 +#: commands/typecmds.c:991 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "las restricciones «check» en dominios no pueden ser marcadas NO INHERIT" -#: commands/typecmds.c:993 commands/typecmds.c:2512 +#: commands/typecmds.c:1000 commands/typecmds.c:2582 #, c-format msgid "unique constraints not possible for domains" msgstr "no se pueden poner restricciones de unicidad a un dominio" -#: commands/typecmds.c:999 commands/typecmds.c:2518 +#: commands/typecmds.c:1006 commands/typecmds.c:2588 #, c-format msgid "primary key constraints not possible for domains" msgstr "no se pueden poner restricciones de llave primaria a un dominio" -#: commands/typecmds.c:1005 commands/typecmds.c:2524 +#: commands/typecmds.c:1012 commands/typecmds.c:2594 #, c-format msgid "exclusion constraints not possible for domains" -msgstr "las restricciones por exclusión no son posibles para los dominios" +msgstr "las restricciones de exclusión no son posibles para los dominios" -#: commands/typecmds.c:1011 commands/typecmds.c:2530 +#: commands/typecmds.c:1018 commands/typecmds.c:2600 #, c-format msgid "foreign key constraints not possible for domains" msgstr "no se pueden poner restricciones de llave foránea a un dominio" -#: commands/typecmds.c:1020 commands/typecmds.c:2539 +#: commands/typecmds.c:1027 commands/typecmds.c:2609 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "no se puede especificar la postergabilidad de las restricciones a un dominio" -#: commands/typecmds.c:1284 utils/cache/typcache.c:1648 +#: commands/typecmds.c:1337 utils/cache/typcache.c:2330 #, c-format msgid "%s is not an enum" msgstr "%s no es un enum" -#: commands/typecmds.c:1422 +#: commands/typecmds.c:1475 #, c-format msgid "type attribute \"subtype\" is required" msgstr "el atributo de tipo «subtype» es obligatorio" -#: commands/typecmds.c:1427 +#: commands/typecmds.c:1480 #, c-format msgid "range subtype cannot be %s" msgstr "el subtipo de rango no puede ser %s" -#: commands/typecmds.c:1446 +#: commands/typecmds.c:1499 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "se especificó un ordenamiento (collation) al rango, pero el subtipo no soporta ordenamiento" -#: commands/typecmds.c:1680 +#: commands/typecmds.c:1733 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "cambiando el tipo de argumento de la función %s de «opaque» a «cstring»" -#: commands/typecmds.c:1731 +#: commands/typecmds.c:1784 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "cambiando el tipo de argumento de la función %s de «opaque» a %s" -#: commands/typecmds.c:1830 +#: commands/typecmds.c:1883 #, c-format msgid "typmod_in function %s must return type %s" msgstr "la función typmod_in %s debe retornar tipo %s" -#: commands/typecmds.c:1857 +#: commands/typecmds.c:1910 #, c-format msgid "typmod_out function %s must return type %s" msgstr "la función typmod_out %s debe retornar tipo %s" -#: commands/typecmds.c:1884 +#: commands/typecmds.c:1937 #, c-format msgid "type analyze function %s must return type %s" msgstr "la función de análisis %s del tipo debe retornar %s" -#: commands/typecmds.c:1930 +#: commands/typecmds.c:1983 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "Debe especificar una clase de operadores para el tipo de rango, o definir una clase de operadores por omisión para el subtipo." -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2014 #, c-format msgid "range canonical function %s must return range type" msgstr "la función canónica %s del rango debe retornar tipo de rango" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2020 #, c-format msgid "range canonical function %s must be immutable" msgstr "la función canónica %s del rango debe ser inmutable" -#: commands/typecmds.c:2003 +#: commands/typecmds.c:2056 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "la función «diff» de subtipo, %s, debe retornar tipo %s" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2063 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "la función «diff» de subtipo, %s, debe ser inmutable" -#: commands/typecmds.c:2037 +#: commands/typecmds.c:2090 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "el valor de OID de pg_type no se definió en modo de actualización binaria" -#: commands/typecmds.c:2340 +#: commands/typecmds.c:2398 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "la columna «%s» de la tabla «%s» contiene valores null" -#: commands/typecmds.c:2453 commands/typecmds.c:2636 +#: commands/typecmds.c:2511 commands/typecmds.c:2713 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "no existe la restricción «%s» en el dominio «%s»" -#: commands/typecmds.c:2457 +#: commands/typecmds.c:2515 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" -msgstr "no existe la restricción «%s» en el dominio «%s», ignorando" +msgstr "no existe la restricción «%s» en el dominio «%s», omitiendo" -#: commands/typecmds.c:2642 +#: commands/typecmds.c:2720 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "la restricción «%s» en el dominio «%s» no es una restricción «check»" -#: commands/typecmds.c:2747 +#: commands/typecmds.c:2826 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "la columna «%s» de la relación «%s» contiene valores que violan la nueva restricción" -#: commands/typecmds.c:2960 commands/typecmds.c:3165 commands/typecmds.c:3247 -#: commands/typecmds.c:3434 +#: commands/typecmds.c:3055 commands/typecmds.c:3253 commands/typecmds.c:3335 +#: commands/typecmds.c:3522 #, c-format msgid "%s is not a domain" msgstr "%s no es un dominio" -#: commands/typecmds.c:2994 +#: commands/typecmds.c:3087 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "el dominio «%2$s» ya contiene una restricción llamada «%1$s»" -#: commands/typecmds.c:3045 +#: commands/typecmds.c:3138 #, c-format msgid "cannot use table references in domain check constraint" msgstr "no se pueden usar referencias a tablas en restricción «check» para un dominio" -#: commands/typecmds.c:3177 commands/typecmds.c:3259 commands/typecmds.c:3551 +#: commands/typecmds.c:3265 commands/typecmds.c:3347 commands/typecmds.c:3639 #, c-format msgid "%s is a table's row type" msgstr "%s es el tipo de registro de una tabla" -#: commands/typecmds.c:3179 commands/typecmds.c:3261 commands/typecmds.c:3553 +#: commands/typecmds.c:3267 commands/typecmds.c:3349 commands/typecmds.c:3641 #, c-format msgid "Use ALTER TABLE instead." msgstr "Considere usar ALTER TABLE." -#: commands/typecmds.c:3186 commands/typecmds.c:3268 commands/typecmds.c:3466 +#: commands/typecmds.c:3274 commands/typecmds.c:3356 commands/typecmds.c:3554 #, c-format msgid "cannot alter array type %s" msgstr "no se puede alterar el tipo de array «%s»" -#: commands/typecmds.c:3188 commands/typecmds.c:3270 commands/typecmds.c:3468 +#: commands/typecmds.c:3276 commands/typecmds.c:3358 commands/typecmds.c:3556 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Puede alterar el tipo %s, lo cual alterará el tipo de array también." -#: commands/typecmds.c:3536 +#: commands/typecmds.c:3624 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "ya existe un tipo llamado «%s» en el esquema «%s»" -#: commands/user.c:141 +#: commands/user.c:140 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSID ya no puede ser especificado" -#: commands/user.c:295 +#: commands/user.c:294 #, c-format msgid "must be superuser to create superusers" msgstr "debe ser superusuario para crear superusuarios" -#: commands/user.c:302 +#: commands/user.c:301 #, c-format msgid "must be superuser to create replication users" msgstr "debe ser superusuario para crear usuarios de replicación" -#: commands/user.c:309 commands/user.c:684 +#: commands/user.c:308 commands/user.c:714 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "debe ser superusuario para cambiar el atributo bypassrls" -#: commands/user.c:316 +#: commands/user.c:315 #, c-format msgid "permission denied to create role" msgstr "se ha denegado el permiso para crear el rol" -#: commands/user.c:326 commands/user.c:1160 commands/user.c:1167 gram.y:14486 -#: gram.y:14521 utils/adt/acl.c:5246 utils/adt/acl.c:5252 +#: commands/user.c:325 commands/user.c:1204 commands/user.c:1211 +#: utils/adt/acl.c:5342 utils/adt/acl.c:5348 gram.y:14896 gram.y:14934 #, c-format msgid "role name \"%s\" is reserved" msgstr "el nombre de rol «%s» está reservado" -#: commands/user.c:328 commands/user.c:1162 commands/user.c:1169 +#: commands/user.c:327 commands/user.c:1206 commands/user.c:1213 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "Los nombres de rol que empiezan con «pg_» están reservados." -#: commands/user.c:340 commands/user.c:1175 +#: commands/user.c:339 commands/user.c:1219 #, c-format msgid "role \"%s\" already exists" msgstr "el rol «%s» ya existe" -#: commands/user.c:414 +#: commands/user.c:405 commands/user.c:823 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "la cadena vacía no es una contraseña válida, limpiando la contraseña" + +#: commands/user.c:434 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "el valor de OID de pg_authid no se definió en modo de actualización binaria" -#: commands/user.c:670 commands/user.c:880 commands/user.c:1414 -#: commands/user.c:1558 +#: commands/user.c:700 commands/user.c:924 commands/user.c:1458 +#: commands/user.c:1602 #, c-format msgid "must be superuser to alter superusers" msgstr "debe ser superusuario para alterar superusuarios" -#: commands/user.c:677 +#: commands/user.c:707 #, c-format msgid "must be superuser to alter replication users" msgstr "debe ser superusuario para alterar usuarios de replicación" -#: commands/user.c:700 commands/user.c:888 +#: commands/user.c:730 commands/user.c:931 #, c-format msgid "permission denied" msgstr "permiso denegado" -#: commands/user.c:918 +#: commands/user.c:961 #, c-format msgid "must be superuser to alter settings globally" msgstr "debe ser superusuario para alterar parámetros globalmente" -#: commands/user.c:940 +#: commands/user.c:983 #, c-format msgid "permission denied to drop role" msgstr "se ha denegado el permiso para eliminar el rol" -#: commands/user.c:964 +#: commands/user.c:1008 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "no se puede usar un especificador especial de rol en DROP ROLE" -#: commands/user.c:974 commands/user.c:1131 commands/variable.c:822 -#: commands/variable.c:894 utils/adt/acl.c:5104 utils/adt/acl.c:5151 -#: utils/adt/acl.c:5179 utils/adt/acl.c:5197 utils/init/miscinit.c:504 +#: commands/user.c:1018 commands/user.c:1175 commands/variable.c:770 +#: commands/variable.c:844 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "no existe el rol «%s»" -#: commands/user.c:979 +#: commands/user.c:1023 #, c-format msgid "role \"%s\" does not exist, skipping" -msgstr "el rol «%s» no existe, ignorando" +msgstr "el rol «%s» no existe, omitiendo" -#: commands/user.c:991 commands/user.c:995 +#: commands/user.c:1036 commands/user.c:1040 #, c-format msgid "current user cannot be dropped" msgstr "el usuario activo no puede ser eliminado" -#: commands/user.c:999 +#: commands/user.c:1044 #, c-format msgid "session user cannot be dropped" msgstr "no se puede eliminar un usuario de la sesión" -#: commands/user.c:1010 +#: commands/user.c:1054 #, c-format msgid "must be superuser to drop superusers" msgstr "debe ser superusuario para eliminar superusuarios" -#: commands/user.c:1026 +#: commands/user.c:1070 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "no se puede eliminar el rol «%s» porque otros objetos dependen de él" -#: commands/user.c:1147 +#: commands/user.c:1191 #, c-format msgid "session user cannot be renamed" msgstr "no se puede cambiar el nombre a un usuario de la sesión" -#: commands/user.c:1151 +#: commands/user.c:1195 #, c-format msgid "current user cannot be renamed" msgstr "no se puede cambiar el nombre al usuario activo" -#: commands/user.c:1185 +#: commands/user.c:1229 #, c-format msgid "must be superuser to rename superusers" msgstr "debe ser superusuario para cambiar el nombre a superusuarios" -#: commands/user.c:1192 +#: commands/user.c:1236 #, c-format msgid "permission denied to rename role" msgstr "se ha denegado el permiso para cambiar el nombre al rol" -#: commands/user.c:1213 +#: commands/user.c:1257 #, c-format msgid "MD5 password cleared because of role rename" msgstr "la contraseña MD5 fue borrada debido al cambio de nombre del rol" -#: commands/user.c:1273 +#: commands/user.c:1317 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "los nombres de columna no pueden ser incluidos en GRANT/REVOKE ROLE" -#: commands/user.c:1311 +#: commands/user.c:1355 #, c-format msgid "permission denied to drop objects" msgstr "se ha denegado el permiso para eliminar objetos" -#: commands/user.c:1338 commands/user.c:1347 +#: commands/user.c:1382 commands/user.c:1391 #, c-format msgid "permission denied to reassign objects" msgstr "se ha denegado el permiso para reasignar objetos" -#: commands/user.c:1422 commands/user.c:1566 +#: commands/user.c:1466 commands/user.c:1610 #, c-format msgid "must have admin option on role \"%s\"" msgstr "debe tener opción de admin en rol «%s»" -#: commands/user.c:1439 +#: commands/user.c:1483 #, c-format msgid "must be superuser to set grantor" msgstr "debe ser superusuario para especificar el cedente (grantor)" -#: commands/user.c:1464 +#: commands/user.c:1508 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "el rol «%s» es un miembro del rol «%s»" -#: commands/user.c:1479 +#: commands/user.c:1523 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "el rol «%s» ya es un miembro del rol «%s»" -#: commands/user.c:1588 +#: commands/user.c:1632 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "el rol «%s» no es un miembro del rol «%s»" -#: commands/vacuum.c:186 -#, c-format -msgid "%s cannot be executed from VACUUM or ANALYZE" -msgstr "%s no puede ejecutarse desde VACUUM o ANALYZE" - -#: commands/vacuum.c:196 -#, c-format -msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" -msgstr "la opción DISABLE_PAGE_SKIPPING de VACUUM no puede usarse con FULL" - -#: commands/vacuum.c:565 -#, c-format -msgid "oldest xmin is far in the past" -msgstr "xmin más antiguo es demasiado antiguo" - -#: commands/vacuum.c:566 -#, c-format -msgid "Close open transactions soon to avoid wraparound problems." -msgstr "Cierre transacciones pronto para prevenir problemas por reciclaje de transacciones." - -#: commands/vacuum.c:605 +#: commands/vacuum.c:116 #, c-format -msgid "oldest multixact is far in the past" -msgstr "multixact más antiguo es demasiado antiguo" +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "opción de ANALYZE «%s» no reconocida" -#: commands/vacuum.c:606 +#: commands/vacuum.c:135 #, c-format -msgid "Close open transactions with multixacts soon to avoid wraparound problems." -msgstr "Cierre transacciones con multixact pronto para prevenir problemas por reciclaje del contador." +msgid "unrecognized VACUUM option \"%s\"" +msgstr "opción de VACUUM «%s» no reconocida" -#: commands/vacuum.c:1176 +#: commands/vacuum.c:169 #, c-format -msgid "some databases have not been vacuumed in over 2 billion transactions" -msgstr "algunas bases de datos no han tenido VACUUM en más de 2 mil millones de transacciones" +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "la opción ANALYZE debe especificarse cuando se provee una lista de columnas" -#: commands/vacuum.c:1177 +#: commands/vacuum.c:259 #, c-format -msgid "You might have already suffered transaction-wraparound data loss." -msgstr "Puede haber sufrido ya problemas de pérdida de datos por reciclaje del contador de transacciones." +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s no puede ejecutarse desde VACUUM o ANALYZE" -#: commands/vacuum.c:1306 +#: commands/vacuum.c:269 #, c-format -msgid "skipping vacuum of \"%s\" --- lock not available" -msgstr "omitiendo el vacuum de «%s»: el candado no está disponible" +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "la opción DISABLE_PAGE_SKIPPING de VACUUM no puede usarse con FULL" -#: commands/vacuum.c:1332 +#: commands/vacuum.c:502 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "omitiendo «%s»: sólo un superusuario puede aplicarle VACUUM" -#: commands/vacuum.c:1336 +#: commands/vacuum.c:506 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "omitiendo «%s»: sólo un superusuario o el dueño de la base de datos puede aplicarle VACUUM" -#: commands/vacuum.c:1340 +#: commands/vacuum.c:510 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "omitiendo «%s»: sólo su dueño o el de la base de datos puede aplicarle VACUUM" -#: commands/vacuum.c:1359 -#, c-format -msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" -msgstr "omitiendo «%s»: no se puede aplicar VACUUM a objetos que no son tablas o a tablas especiales de sistema" - -#: commands/vacuumlazy.c:376 -#, c-format -msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" -msgstr "vacuum automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" - -#: commands/vacuumlazy.c:381 -#, c-format -msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" -msgstr "páginas: %u eliminadas, %u quedan, %u saltadas debido a «pins», %u congeladas saltadas\n" - -#: commands/vacuumlazy.c:387 +#: commands/vacuum.c:525 #, c-format -msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" -msgstr "" - -#: commands/vacuumlazy.c:393 -#, c-format -msgid "buffer usage: %d hits, %d misses, %d dirtied\n" -msgstr "uso de búfers: %d aciertos, %d fallas, %d ensuciados\n" - -#: commands/vacuumlazy.c:397 -#, c-format -msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" -msgstr "tasa lectura promedio: %.3f MB/s, tasa escritura promedio: %.3f MB/s\n" - -#: commands/vacuumlazy.c:399 -#, c-format -msgid "system usage: %s" -msgstr "uso de sistema: %s" - -#: commands/vacuumlazy.c:859 -#, c-format -msgid "relation \"%s\" page %u is uninitialized --- fixing" -msgstr "la página %2$u de la relación «%1$s» no está inicializada --- arreglando" +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "omitiendo «%s»: sólo un superusuario puede analizarla" -#: commands/vacuumlazy.c:1329 +#: commands/vacuum.c:529 #, c-format -msgid "\"%s\": removed %.0f row versions in %u pages" -msgstr "«%s»: se eliminaron %.0f versiones de filas en %u páginas" - -#: commands/vacuumlazy.c:1339 -#, fuzzy, c-format -msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" -msgstr "%.0f versiones muertas de filas no pueden ser eliminadas aún.\n" +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "omitiendo «%s»: sólo un superusuario o el dueño de la base de datos puede analizarla" -#: commands/vacuumlazy.c:1341 +#: commands/vacuum.c:533 #, c-format -msgid "There were %.0f unused item pointers.\n" -msgstr "Hubo %.0f punteros de ítem sin uso.\n" +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "omitiendo «%s»: sólo su dueño o el de la base de datos puede analizarla" -#: commands/vacuumlazy.c:1343 +#: commands/vacuum.c:612 commands/vacuum.c:708 #, c-format -msgid "Skipped %u page due to buffer pins, " -msgid_plural "Skipped %u pages due to buffer pins, " -msgstr[0] "" -msgstr[1] "" +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "omitiendo el vacuum de «%s»: el candado no está disponible" -#: commands/vacuumlazy.c:1347 +#: commands/vacuum.c:617 #, c-format -msgid "%u frozen page.\n" -msgid_plural "%u frozen pages.\n" -msgstr[0] "" -msgstr[1] "" +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "omitiendo el vacuum de «%s» --- la relación ya no existe" -#: commands/vacuumlazy.c:1351 +#: commands/vacuum.c:633 commands/vacuum.c:713 #, c-format -msgid "%u page is entirely empty.\n" -msgid_plural "%u pages are entirely empty.\n" -msgstr[0] "" -msgstr[1] "" +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "omitiendo analyze de «%s»: el candado no está disponible" -#: commands/vacuumlazy.c:1358 +#: commands/vacuum.c:638 #, c-format -msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" -msgstr "«%s»: se encontraron %.0f versiones de filas eliminables y %.0f no eliminables en %u de %u páginas" +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "omitiendo analyze de «%s» --- la relación ya no existe" -#: commands/vacuumlazy.c:1427 +#: commands/vacuum.c:935 #, c-format -msgid "\"%s\": removed %d row versions in %d pages" -msgstr "«%s»: se eliminaron %d versiones de filas en %d páginas" +msgid "oldest xmin is far in the past" +msgstr "xmin más antiguo es demasiado antiguo" -#: commands/vacuumlazy.c:1615 +#: commands/vacuum.c:936 #, c-format -msgid "scanned index \"%s\" to remove %d row versions" -msgstr "se recorrió el índice «%s» para eliminar %d versiones de filas" +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Cierre transaciones abiertas pronto para impedir problemas por reciclaje de contadores.\n" +"Puede que además necesite comprometer o abortar transacciones preparadas antiguas, o eliminar slots de replicación añejos." -#: commands/vacuumlazy.c:1661 +#: commands/vacuum.c:976 #, c-format -msgid "index \"%s\" now contains %.0f row versions in %u pages" -msgstr "el índice «%s» ahora contiene %.0f versiones de filas en %u páginas" +msgid "oldest multixact is far in the past" +msgstr "multixact más antiguo es demasiado antiguo" -#: commands/vacuumlazy.c:1665 +#: commands/vacuum.c:977 #, c-format -msgid "" -"%.0f index row versions were removed.\n" -"%u index pages have been deleted, %u are currently reusable.\n" -"%s." -msgstr "" -"%.0f versiones de filas del índice fueron eliminadas.\n" -"%u páginas de índice han sido eliminadas, %u son reusables.\n" -"%s." +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "Cierre transacciones con multixact pronto para prevenir problemas por reciclaje del contador." -#: commands/vacuumlazy.c:1760 +#: commands/vacuum.c:1548 #, c-format -msgid "\"%s\": stopping truncate due to conflicting lock request" -msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "algunas bases de datos no han tenido VACUUM en más de 2 mil millones de transacciones" -#: commands/vacuumlazy.c:1825 +#: commands/vacuum.c:1549 #, c-format -msgid "\"%s\": truncated %u to %u pages" -msgstr "«%s»: truncadas %u a %u páginas" +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "Puede haber sufrido ya problemas de pérdida de datos por reciclaje del contador de transacciones." -#: commands/vacuumlazy.c:1890 +#: commands/vacuum.c:1707 #, c-format -msgid "\"%s\": suspending truncate due to conflicting lock request" -msgstr "«%s»: suspendiendo el truncado debido a una petición de candado en conflicto" +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "omitiendo «%s»: no se puede aplicar VACUUM a objetos que no son tablas o a tablas especiales de sistema" -#: commands/variable.c:165 utils/misc/guc.c:10019 utils/misc/guc.c:10081 +#: commands/variable.c:165 utils/misc/guc.c:10940 utils/misc/guc.c:11002 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "Palabra clave no reconocida: «%s»." @@ -10498,53 +10947,52 @@ msgstr "el modo de escritura debe ser activado antes de cualquier consulta" msgid "cannot set transaction read-write mode during recovery" msgstr "no se puede poner en modo de escritura durante la recuperación" -#: commands/variable.c:557 +#: commands/variable.c:534 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" msgstr "SET TRANSACTION ISOLATION LEVEL debe ser llamado antes de cualquier consulta" -#: commands/variable.c:564 +#: commands/variable.c:541 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "SET TRANSACTION ISOLATION LEVEL no debe ser llamado en una subtransacción" -#: commands/variable.c:571 storage/lmgr/predicate.c:1634 +#: commands/variable.c:548 storage/lmgr/predicate.c:1626 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "no se puede utilizar el modo serializable en un hot standby" -#: commands/variable.c:572 +#: commands/variable.c:549 #, c-format msgid "You can use REPEATABLE READ instead." msgstr "Puede utilizar REPEATABLE READ en su lugar." -#: commands/variable.c:620 +#: commands/variable.c:567 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" msgstr "SET TRANSACTION [NOT] DEFERRABLE no puede ser llamado en una subtransacción" -#: commands/variable.c:626 +#: commands/variable.c:573 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" msgstr "SET TRANSACTION [NOT] DEFERRABLE debe ser llamado antes de cualquier consulta" -#: commands/variable.c:708 +#: commands/variable.c:655 #, c-format msgid "Conversion between %s and %s is not supported." msgstr "La conversión entre %s y %s no está soportada." -#: commands/variable.c:715 +#: commands/variable.c:662 #, c-format msgid "Cannot change \"client_encoding\" now." msgstr "No se puede cambiar «client_encoding» ahora." -#: commands/variable.c:776 -#, fuzzy, c-format -#| msgid "cannot change client_encoding in a parallel worker" +#: commands/variable.c:723 +#, c-format msgid "cannot change client_encoding during a parallel operation" -msgstr "no se puede cambiar «client_encoding» en un trabajador paralelo" +msgstr "no se puede cambiar «client_encoding» durante una operación paralela" -#: commands/variable.c:912 +#: commands/variable.c:863 #, c-format msgid "permission denied to set role \"%s\"" msgstr "se ha denegado el permiso para definir el rol «%s»" @@ -10559,27 +11007,22 @@ msgstr "valor no válido para la opción «check_option»" msgid "Valid values are \"local\" and \"cascaded\"." msgstr "Los valores aceptables son «local» y «cascaded»." -#: commands/view.c:101 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "no se pudo determinar el ordenamiento (collation) a usar para la columna «%s» de vista" -#: commands/view.c:115 -#, c-format -msgid "view must have at least one column" -msgstr "una vista debe tener al menos una columna" - -#: commands/view.c:281 commands/view.c:293 +#: commands/view.c:280 commands/view.c:291 #, c-format msgid "cannot drop columns from view" msgstr "no se pueden eliminar columnas de una vista" -#: commands/view.c:298 +#: commands/view.c:296 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "no se puede cambiar el nombre de la columna «%s» de la vista a «%s»" -#: commands/view.c:306 +#: commands/view.c:304 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "no se puede cambiar el tipo de dato de la columna «%s» de la vista de %s a %s" @@ -10602,448 +11045,476 @@ msgstr "CREATE VIEW especifica más nombres de columna que columnas" #: commands/view.c:541 #, c-format msgid "views cannot be unlogged because they do not have storage" -msgstr "las vistas no pueden ser unlogged porque no tienen almacenamiento" +msgstr "las vistas no pueden ser «unlogged» porque no tienen almacenamiento" #: commands/view.c:555 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "la vista «%s» será una vista temporal" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:79 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "el cursor «%s» no es una orden SELECT" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:85 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "el cursor «%s» está abierto desde una transacción anterior" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:118 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "el cursor «%s» tiene múltiples referencias FOR UPDATE/SHARE a la tabla «%s»" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:127 #, c-format msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "el cursor «%s» no tiene una referencia FOR UPDATE/SHARE a la tabla «%s»" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:137 executor/execCurrent.c:182 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "el cursor «%s» no está posicionado en una fila" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "el cursor «%s» no es un recorrido simplemente actualizable de la tabla «%s»" -#: executor/execCurrent.c:231 executor/execExprInterp.c:1899 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2312 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "el tipo del parámetro %d (%s) no coincide aquel con que fue preparado el plan (%s)" -#: executor/execCurrent.c:243 executor/execExprInterp.c:1911 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2324 #, c-format msgid "no value found for parameter %d" msgstr "no se encontró un valor para parámetro %d" -#: executor/execExpr.c:780 parser/parse_agg.c:779 +#: executor/execExpr.c:857 parser/parse_agg.c:816 #, c-format msgid "window function calls cannot be nested" msgstr "no se pueden anidar llamadas a funciones de ventana deslizante" -#: executor/execExpr.c:1224 +#: executor/execExpr.c:1316 #, c-format msgid "target type is not an array" msgstr "el tipo de destino no es un array" -#: executor/execExpr.c:1547 +#: executor/execExpr.c:1649 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "la columna de ROW() es de tipo %s en lugar de ser de tipo %s" -#: executor/execExpr.c:2079 executor/execSRF.c:670 parser/parse_func.c:120 -#: parser/parse_func.c:547 parser/parse_func.c:921 +#: executor/execExpr.c:2174 executor/execSRF.c:700 parser/parse_func.c:136 +#: parser/parse_func.c:650 parser/parse_func.c:1024 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" msgstr[0] "no se pueden pasar más de %d argumento a una función" msgstr[1] "no se pueden pasar más de %d argumentos a una función" -#: executor/execExpr.c:2356 executor/execExpr.c:2362 -#: executor/execExprInterp.c:2210 utils/adt/arrayfuncs.c:260 -#: utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 -#: utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5239 -#: utils/adt/arrayfuncs.c:5756 +#: executor/execExpr.c:2570 executor/execExpr.c:2576 +#: executor/execExprInterp.c:2641 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5302 +#: utils/adt/arrayfuncs.c:5819 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "el número de dimensiones del array (%d) excede el máximo permitido (%d)" -#: executor/execExprInterp.c:1571 -#, fuzzy, c-format +#: executor/execExprInterp.c:1862 +#, c-format msgid "attribute %d of type %s has been dropped" -msgstr "El atributo «%s» de tipo %s no existe en el tipo %s." +msgstr "El atributo %d de tipo %s ha sido eliminado" -#: executor/execExprInterp.c:1577 -#, fuzzy, c-format +#: executor/execExprInterp.c:1868 +#, c-format msgid "attribute %d of type %s has wrong type" -msgstr "el atributo %d tiene tipo erróneo" +msgstr "el atributo %d del tipo %s tiene tipo erróneo" -#: executor/execExprInterp.c:1579 executor/execExprInterp.c:2496 +#: executor/execExprInterp.c:1870 executor/execExprInterp.c:2914 +#: executor/execExprInterp.c:2961 #, c-format msgid "Table has type %s, but query expects %s." msgstr "La tabla tiene tipo %s, pero la consulta esperaba %s." -#: executor/execExprInterp.c:1989 +#: executor/execExprInterp.c:2402 #, c-format msgid "WHERE CURRENT OF is not supported for this table type" msgstr "WHERE CURRENT OF no está soportado para este tipo de tabla" -#: executor/execExprInterp.c:2188 +#: executor/execExprInterp.c:2619 #, c-format msgid "cannot merge incompatible arrays" msgstr "no se puede mezclar arrays incompatibles" -#: executor/execExprInterp.c:2189 +#: executor/execExprInterp.c:2620 #, c-format msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." msgstr "El array con tipo de elemento %s no puede ser incluido en una sentencia ARRAY con tipo de elemento %s." -#: executor/execExprInterp.c:2230 executor/execExprInterp.c:2260 +#: executor/execExprInterp.c:2661 executor/execExprInterp.c:2691 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "los arrays multidimensionales deben tener expresiones de arrays con dimensiones coincidentes" -#: executor/execExprInterp.c:2495 +#: executor/execExprInterp.c:2913 executor/execExprInterp.c:2960 #, c-format msgid "attribute %d has wrong type" msgstr "el atributo %d tiene tipo erróneo" -#: executor/execExprInterp.c:2604 +#: executor/execExprInterp.c:3070 #, c-format msgid "array subscript in assignment must not be null" msgstr "subíndice de array en asignación no puede ser nulo" -#: executor/execExprInterp.c:3037 utils/adt/domains.c:148 +#: executor/execExprInterp.c:3503 utils/adt/domains.c:149 #, c-format msgid "domain %s does not allow null values" msgstr "el dominio %s no permite valores null" -#: executor/execExprInterp.c:3052 utils/adt/domains.c:183 +#: executor/execExprInterp.c:3518 utils/adt/domains.c:184 #, c-format msgid "value for domain %s violates check constraint \"%s\"" msgstr "el valor para el dominio %s viola la restricción «check» «%s»" -#: executor/execExprInterp.c:3419 executor/execExprInterp.c:3436 -#: executor/execExprInterp.c:3538 executor/nodeModifyTable.c:96 -#: executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:123 -#: executor/nodeModifyTable.c:131 +#: executor/execExprInterp.c:3889 executor/execExprInterp.c:3906 +#: executor/execExprInterp.c:4008 executor/nodeModifyTable.c:109 +#: executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 +#: executor/nodeModifyTable.c:145 #, c-format msgid "table row type and query-specified row type do not match" msgstr "el tipo de registro de la tabla no coincide con el tipo de registro de la consulta" -#: executor/execExprInterp.c:3420 +#: executor/execExprInterp.c:3890 #, c-format msgid "Table row contains %d attribute, but query expects %d." msgid_plural "Table row contains %d attributes, but query expects %d." msgstr[0] "La fila de la tabla contiene %d atributo, pero la consulta esperaba %d." msgstr[1] "La fila de la tabla contiene %d atributos, pero la consulta esperaba %d." -#: executor/execExprInterp.c:3437 executor/nodeModifyTable.c:107 +#: executor/execExprInterp.c:3907 executor/nodeModifyTable.c:121 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "La tabla tiene tipo %s en posición ordinal %d, pero la consulta esperaba %s." -#: executor/execExprInterp.c:3539 executor/execSRF.c:925 +#: executor/execExprInterp.c:4009 executor/execSRF.c:959 #, c-format msgid "Physical storage mismatch on dropped attribute at ordinal position %d." msgstr "Discordancia de almacenamiento físico en atributo eliminado en la posición %d." -#: executor/execIndexing.c:543 +#: executor/execIndexing.c:550 #, c-format msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" -msgstr "ON CONFLICT no soporta las restricciones únicas/de exclusión postergables como árbitros" +msgstr "ON CONFLICT no soporta las restricciones únicas o de exclusión postergables como árbitros" -#: executor/execIndexing.c:818 +#: executor/execIndexing.c:821 #, c-format msgid "could not create exclusion constraint \"%s\"" -msgstr "no se pudo crear la restricción por exclusión «%s»" +msgstr "no se pudo crear la restricción de exclusión «%s»" -#: executor/execIndexing.c:821 +#: executor/execIndexing.c:824 #, c-format msgid "Key %s conflicts with key %s." msgstr "La llave %s está en conflicto con la llave %s." -#: executor/execIndexing.c:823 +#: executor/execIndexing.c:826 #, c-format msgid "Key conflicts exist." msgstr "Existe un conflicto de llave." -#: executor/execIndexing.c:829 +#: executor/execIndexing.c:832 #, c-format msgid "conflicting key value violates exclusion constraint \"%s\"" -msgstr "llave en conflicto viola restricción por exclusión «%s»" +msgstr "llave en conflicto viola la restricción de exclusión «%s»" -#: executor/execIndexing.c:832 +#: executor/execIndexing.c:835 #, c-format msgid "Key %s conflicts with existing key %s." msgstr "La llave %s está en conflicto con la llave existente %s." -#: executor/execIndexing.c:834 +#: executor/execIndexing.c:837 #, c-format msgid "Key conflicts with existing key." msgstr "La llave está en conflicto con una llave existente." -#: executor/execMain.c:1113 +#: executor/execMain.c:1093 #, c-format msgid "cannot change sequence \"%s\"" msgstr "no se puede cambiar la secuencia «%s»" -#: executor/execMain.c:1119 +#: executor/execMain.c:1099 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "no se puede cambiar la relación TOAST «%s»" -#: executor/execMain.c:1137 rewrite/rewriteHandler.c:2707 +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2911 #, c-format msgid "cannot insert into view \"%s\"" msgstr "no se puede insertar en la vista «%s»" -#: executor/execMain.c:1139 rewrite/rewriteHandler.c:2710 +#: executor/execMain.c:1119 rewrite/rewriteHandler.c:2914 #, c-format msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." -msgstr "Para activar las inserciones en la vista, provea un disparador INSTEAD OF INSERT un una regla incodicional ON INSERT DO INSTEAD." +msgstr "Para posibilitar las inserciones en la vista, provea un disparador INSTEAD OF INSERT o una regla incodicional ON INSERT DO INSTEAD." -#: executor/execMain.c:1145 rewrite/rewriteHandler.c:2715 +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2919 #, c-format msgid "cannot update view \"%s\"" msgstr "no se puede actualizar la vista «%s»" -#: executor/execMain.c:1147 rewrite/rewriteHandler.c:2718 +#: executor/execMain.c:1127 rewrite/rewriteHandler.c:2922 #, c-format msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." -msgstr "Para activar las actualizaciones en la vista, provea un disparador INSTEAD OF UPDATE o una regla incondicional ON UPDATE DO INSTEAD." +msgstr "Para posibilitar las actualizaciones en la vista, provea un disparador INSTEAD OF UPDATE o una regla incondicional ON UPDATE DO INSTEAD." -#: executor/execMain.c:1153 rewrite/rewriteHandler.c:2723 +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2927 #, c-format msgid "cannot delete from view \"%s\"" msgstr "no se puede eliminar de la vista «%s»" -#: executor/execMain.c:1155 rewrite/rewriteHandler.c:2726 +#: executor/execMain.c:1135 rewrite/rewriteHandler.c:2930 #, c-format msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." -msgstr "Para activar las eliminaciones en la vista, provea un disparador INSTEAD OF DELETE o una regla incondicional ON DELETE DO INSTEAD." +msgstr "Para posibilitar las eliminaciones en la vista, provea un disparador INSTEAD OF DELETE o una regla incondicional ON DELETE DO INSTEAD." -#: executor/execMain.c:1166 +#: executor/execMain.c:1146 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "no se puede cambiar la vista materializada «%s»" -#: executor/execMain.c:1178 +#: executor/execMain.c:1158 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "no se puede insertar en la tabla foránea «%s»" -#: executor/execMain.c:1184 +#: executor/execMain.c:1164 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "la tabla foránea «%s» no permite inserciones" -#: executor/execMain.c:1191 +#: executor/execMain.c:1171 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "no se puede actualizar la tabla foránea «%s»" -#: executor/execMain.c:1197 +#: executor/execMain.c:1177 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "la tabla foránea «%s» no permite actualizaciones" -#: executor/execMain.c:1204 +#: executor/execMain.c:1184 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "no se puede eliminar desde la tabla foránea «%s»" -#: executor/execMain.c:1210 +#: executor/execMain.c:1190 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "la tabla foránea «%s» no permite eliminaciones" -#: executor/execMain.c:1221 +#: executor/execMain.c:1201 #, c-format msgid "cannot change relation \"%s\"" msgstr "no se puede cambiar la relación «%s»" -#: executor/execMain.c:1248 +#: executor/execMain.c:1228 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "no se puede bloquear registros de la secuencia «%s»" -#: executor/execMain.c:1255 +#: executor/execMain.c:1235 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "no se puede bloquear registros en la relación TOAST «%s»" -#: executor/execMain.c:1262 +#: executor/execMain.c:1242 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "no se puede bloquear registros en la vista «%s»" -#: executor/execMain.c:1270 +#: executor/execMain.c:1250 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "no se puede bloquear registros en la vista materializada «%s»" -#: executor/execMain.c:1279 executor/execMain.c:2878 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1259 executor/execMain.c:2637 +#: executor/nodeLockRows.c:138 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "no se puede bloquear registros en la tabla foránea «%s»" -#: executor/execMain.c:1285 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "no se puede bloquear registros en la tabla «%s»" -#: executor/execMain.c:1896 -#, fuzzy, c-format +#: executor/execMain.c:1891 +#, c-format msgid "new row for relation \"%s\" violates partition constraint" -msgstr "el nuevo registro para la relación «%s» viola la restricción «check» «%s»" +msgstr "el nuevo registro para la relación «%s» viola la restricción de partición" -#: executor/execMain.c:1898 executor/execMain.c:1976 executor/execMain.c:2022 -#: executor/execMain.c:2113 +#: executor/execMain.c:1893 executor/execMain.c:1975 executor/execMain.c:2024 +#: executor/execMain.c:2133 #, c-format msgid "Failing row contains %s." msgstr "La fila que falla contiene %s." -#: executor/execMain.c:1974 +#: executor/execMain.c:1973 #, c-format msgid "null value in column \"%s\" violates not-null constraint" msgstr "el valor null para la columna «%s» viola la restricción not null" -#: executor/execMain.c:2020 +#: executor/execMain.c:2022 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "el nuevo registro para la relación «%s» viola la restricción «check» «%s»" -#: executor/execMain.c:2111 +#: executor/execMain.c:2131 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "el nuevo registro para la vista «%s» viola la opción check" -#: executor/execMain.c:2121 +#: executor/execMain.c:2141 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "el nuevo registro viola la política de seguridad de registros «%s» para la tabla «%s»" -#: executor/execMain.c:2126 +#: executor/execMain.c:2146 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "el nuevo registro viola la política de seguridad de registros para la tabla «%s»" -#: executor/execMain.c:2133 +#: executor/execMain.c:2153 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "el nuevo registro viola la política de seguridad de registros «%s» (expresión USING) para la tabla «%s»" -#: executor/execMain.c:2138 +#: executor/execMain.c:2158 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "el nuevo registro viola la política de seguridad de registros (expresión USING) para la tabla «%s»" -#: executor/execMain.c:3339 -#, fuzzy, c-format +#: executor/execPartition.c:345 +#, c-format msgid "no partition of relation \"%s\" found for row" -msgstr "no se encontraron relaciones coincidentes en el tablespace «%s»" +msgstr "no se encontró una partición de «%s» para el registro" -#: executor/execMain.c:3341 -#, fuzzy, c-format +#: executor/execPartition.c:348 +#, c-format msgid "Partition key of the failing row contains %s." -msgstr "La fila que falla contiene %s." +msgstr "La llave de particionamiento de la fila que falla contiene %s." + +#: executor/execReplication.c:195 executor/execReplication.c:359 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "el registro a ser bloqueado ya fue movido a otra partición debido a un update concurrente, reintentando" -#: executor/execReplication.c:197 executor/execReplication.c:355 +#: executor/execReplication.c:199 executor/execReplication.c:363 #, c-format msgid "concurrent update, retrying" -msgstr "" +msgstr "actualización simultánea, reintentando" + +#: executor/execReplication.c:205 executor/execReplication.c:369 +#, c-format +msgid "concurrent delete, retrying" +msgstr "eliminacón concurrente, reintentando" -#: executor/execReplication.c:257 parser/parse_oper.c:228 -#: utils/adt/array_userfuncs.c:724 utils/adt/array_userfuncs.c:863 -#: utils/adt/arrayfuncs.c:3639 utils/adt/arrayfuncs.c:4077 -#: utils/adt/arrayfuncs.c:6037 utils/adt/rowtypes.c:1167 +#: executor/execReplication.c:263 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4140 +#: utils/adt/arrayfuncs.c:6130 utils/adt/rowtypes.c:1180 #, c-format msgid "could not identify an equality operator for type %s" msgstr "no se pudo identificar un operador de igualdad para el tipo %s" -#: executor/execReplication.c:563 -#, fuzzy, c-format -msgid "cannot update table \"%s\" because it does not have replica identity and publishes updates" -msgstr "no se puede cambiar el tipo «%s» porque es el tipo de una tabla tipada" +#: executor/execReplication.c:572 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "no se puede actualizar la tabla «%s» porque no tiene identidad de replicación y publica updates" -#: executor/execReplication.c:565 +#: executor/execReplication.c:574 #, c-format msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." -msgstr "" +msgstr "Para habilitar la actualización de la tabla, configure REPLICA IDENTITY utilizando ALTER TABLE." -#: executor/execReplication.c:569 -#, fuzzy, c-format -msgid "cannot delete from table \"%s\" because it does not have replica identity and publishes deletes" -msgstr "no se puede cambiar el tipo «%s» porque es el tipo de una tabla tipada" +#: executor/execReplication.c:578 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "no se puede eliminar de la tabla «%s» porque no tiene una identidad de replicación y publica deletes" -#: executor/execReplication.c:571 +#: executor/execReplication.c:580 #, c-format msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." -msgstr "" +msgstr "para habilitar la eliminación en la tabla, configure REPLICA IDENTITY utilizando ALTER TABLE." -#: executor/execReplication.c:590 -#, fuzzy, c-format -msgid "logical replication target relation \"%s.%s\" is not a table" -msgstr "la relación referida «%s» no es una tabla" +#: executor/execReplication.c:600 executor/execReplication.c:607 +#: executor/execReplication.c:615 +#, c-format +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "no se puede usar la relación «%s.%s» como destino de replicación lógica" -#: executor/execSRF.c:308 +#: executor/execReplication.c:602 +#, c-format +msgid "\"%s.%s\" is a partitioned table." +msgstr "«%s.%s» es un índice particionado." + +#: executor/execReplication.c:609 +#, c-format +msgid "\"%s.%s\" is a foreign table." +msgstr "«%s.%s» es una tabla foránea." + +#: executor/execReplication.c:617 +#, c-format +msgid "\"%s.%s\" is not a table." +msgstr "«%s.%s» no es una tabla." + +#: executor/execSRF.c:310 #, c-format msgid "rows returned by function are not all of the same row type" msgstr "las filas retornadas por la función no tienen todas el mismo tipo de registro" -#: executor/execSRF.c:356 executor/execSRF.c:620 +#: executor/execSRF.c:358 executor/execSRF.c:649 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "no se siguió el protocolo de función tabular para el modo de materialización" -#: executor/execSRF.c:363 executor/execSRF.c:638 +#: executor/execSRF.c:365 executor/execSRF.c:667 #, c-format msgid "unrecognized table-function returnMode: %d" -msgstr "modo de retorno (returnMode) de la función tabular no es reconocido: %d" +msgstr "modo de retorno de la función tabular no es reconocido: %d" -#: executor/execSRF.c:843 +#: executor/execSRF.c:876 #, c-format msgid "function returning setof record called in context that cannot accept type record" msgstr "se llamó una función que retorna «setof record» en un contexto que no puede aceptar el tipo record" -#: executor/execSRF.c:898 executor/execSRF.c:914 executor/execSRF.c:924 +#: executor/execSRF.c:932 executor/execSRF.c:948 executor/execSRF.c:958 #, c-format msgid "function return row and query-specified return row do not match" msgstr "la fila de retorno especificada en la consulta no coincide con fila de retorno de la función" -#: executor/execSRF.c:899 +#: executor/execSRF.c:933 #, c-format msgid "Returned row contains %d attribute, but query expects %d." msgid_plural "Returned row contains %d attributes, but query expects %d." msgstr[0] "Fila retornada contiene %d atributo, pero la consulta esperaba %d." msgstr[1] "Fila retornada contiene %d atributos, pero la consulta esperaba %d." -#: executor/execSRF.c:915 +#: executor/execSRF.c:949 #, c-format msgid "Returned type %s at ordinal position %d, but query expects %s." msgstr "Tipo retornado %s en posición ordinal %d, pero la consulta esperaba %s." -#: executor/execUtils.c:639 +#: executor/execUtils.c:712 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "la vista materializada «%s» no ha sido poblada" -#: executor/execUtils.c:641 +#: executor/execUtils.c:714 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Use la orden REFRESH MATERIALIZED VIEW." @@ -11053,1610 +11524,1388 @@ msgstr "Use la orden REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "no se pudo determinar el tipo de argumento declarado %s" -#: executor/functions.c:520 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "no se puede ejecutar COPY desde/a un cliente en una función SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:526 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s no está permitido en una función SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:534 executor/spi.c:1282 executor/spi.c:2069 +#: executor/functions.c:535 executor/spi.c:1474 executor/spi.c:2262 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s no está permitido en una función no-«volatile»" -#: executor/functions.c:654 +#: executor/functions.c:656 #, c-format msgid "could not determine actual result type for function declared to return type %s" msgstr "no se pudo determinar el tipo de resultado para función declarada retornando tipo %s" -#: executor/functions.c:1413 +#: executor/functions.c:1407 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "función SQL «%s» en la sentencia %d" -#: executor/functions.c:1439 +#: executor/functions.c:1433 #, c-format msgid "SQL function \"%s\" during startup" msgstr "función SQL «%s» durante el inicio" -#: executor/functions.c:1597 executor/functions.c:1634 -#: executor/functions.c:1646 executor/functions.c:1759 -#: executor/functions.c:1792 executor/functions.c:1822 +#: executor/functions.c:1526 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "no está permitido invocar procedimientos con arguments de salida en funciones SQL" + +#: executor/functions.c:1646 executor/functions.c:1679 +#: executor/functions.c:1691 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "el tipo de retorno de función declarada para retornar %s no concuerda" -#: executor/functions.c:1599 +#: executor/functions.c:1648 #, c-format msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." msgstr "La sentencia final de la función debe ser un SELECT o INSERT/UPDATE/DELETE RETURNING." -#: executor/functions.c:1636 +#: executor/functions.c:1681 #, c-format msgid "Final statement must return exactly one column." msgstr "La sentencia final debe retornar exactamente una columna." -#: executor/functions.c:1648 +#: executor/functions.c:1693 #, c-format msgid "Actual return type is %s." msgstr "El verdadero tipo de retorno es %s." -#: executor/functions.c:1761 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "La sentencia final retorna demasiadas columnas." -#: executor/functions.c:1794 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "La sentencia final retorna %s en lugar de %s en la columna %d." -#: executor/functions.c:1824 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "La sentencia final retorna muy pocas columnas." -#: executor/functions.c:1873 +#: executor/functions.c:1945 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "el tipo de retorno %s no es soportado en funciones SQL" -#: executor/nodeAgg.c:3470 +#: executor/nodeAgg.c:2825 parser/parse_agg.c:655 parser/parse_agg.c:685 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "la función «combine» para la función de agregación %u debe declararse STRICT" +msgid "aggregate function calls cannot be nested" +msgstr "no se pueden anidar llamadas a funciones de agregación" -#: executor/nodeAgg.c:3515 executor/nodeWindowAgg.c:2278 +#: executor/nodeAgg.c:3030 executor/nodeWindowAgg.c:2835 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "la función de agregación %u necesita tener tipos de entrada y transición compatibles" -#: executor/nodeAgg.c:3569 parser/parse_agg.c:618 parser/parse_agg.c:648 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "no se pueden anidar llamadas a funciones de agregación" - -#: executor/nodeCustom.c:142 executor/nodeCustom.c:153 +#: executor/nodeCustom.c:146 executor/nodeCustom.c:157 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "el scan personalizado «%s» no soporta MarkPos" -#: executor/nodeHashjoin.c:767 executor/nodeHashjoin.c:797 +#: executor/nodeHashjoin.c:1059 executor/nodeHashjoin.c:1089 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "falló la búsqueda en el archivo temporal de hash-join: %m" -#: executor/nodeHashjoin.c:832 executor/nodeHashjoin.c:838 +#: executor/nodeHashjoin.c:1248 executor/nodeHashjoin.c:1254 #, c-format msgid "could not write to hash-join temporary file: %m" -msgstr "no se pudo escribir el archivo temporal de hash-join: %m" +msgstr "no se pudo escribir al archivo temporal de hash-join: %m" -#: executor/nodeHashjoin.c:879 executor/nodeHashjoin.c:889 +#: executor/nodeHashjoin.c:1295 executor/nodeHashjoin.c:1305 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "no se pudo leer el archivo temporal de hash-join: %m" -#: executor/nodeIndexonlyscan.c:233 +#: executor/nodeIndexonlyscan.c:242 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "no se permiten funciones de ventana deslizante en predicados de índice" -#: executor/nodeLimit.c:252 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET no debe ser negativo" -#: executor/nodeLimit.c:278 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT no debe ser negativo" -#: executor/nodeMergejoin.c:1554 +#: executor/nodeMergejoin.c:1570 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOIN sólo está soportado con condiciones que se pueden usar con merge join" -#: executor/nodeMergejoin.c:1574 +#: executor/nodeMergejoin.c:1588 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOIN sólo está soportado con condiciones que se pueden usar con merge join" -#: executor/nodeModifyTable.c:97 +#: executor/nodeModifyTable.c:110 #, c-format msgid "Query has too many columns." msgstr "La consulta tiene demasiadas columnas." -#: executor/nodeModifyTable.c:124 +#: executor/nodeModifyTable.c:138 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "La consulta entrega un valor para una columna eliminada en la posición %d." -#: executor/nodeModifyTable.c:132 +#: executor/nodeModifyTable.c:146 #, c-format msgid "Query has too few columns." msgstr "La consulta tiene muy pocas columnas." -#: executor/nodeModifyTable.c:1253 +#: executor/nodeModifyTable.c:808 executor/nodeModifyTable.c:883 +#, c-format +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "el registro a ser eliminado ya fue modificado por una operación disparada por la orden actual" + +#: executor/nodeModifyTable.c:1190 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "especificación ON UPDATE no válida" + +#: executor/nodeModifyTable.c:1191 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "La tupla de resultado aparecería en una partición diferente que la tupla original." + +#: executor/nodeModifyTable.c:1564 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "la orden ON CONFLICT DO UPDATE no puede afectar el registro una segunda vez" -#: executor/nodeModifyTable.c:1254 +#: executor/nodeModifyTable.c:1565 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "Asegúrese de que ningún registro propuesto para inserción dentro de la misma orden tenga valores duplicados restringidos." -#: executor/nodeSamplescan.c:298 +#: executor/nodeSamplescan.c:259 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "el parámetro TABLESAMPLE no puede ser null" -#: executor/nodeSamplescan.c:310 +#: executor/nodeSamplescan.c:271 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "el parámetro TABLESAMPLE REPEATABLE no puede ser null" -#: executor/nodeSubplan.c:333 executor/nodeSubplan.c:372 -#: executor/nodeSubplan.c:1004 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1147 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "una subconsulta utilizada como expresión retornó más de un registro" -#: executor/nodeTableFuncscan.c:365 -#, fuzzy, c-format +#: executor/nodeTableFuncscan.c:378 +#, c-format msgid "namespace URI must not be null" -msgstr "el nombre de slot no debe ser null" +msgstr "la URI del espacio de nombres no debe ser null" -#: executor/nodeTableFuncscan.c:376 -#, fuzzy, c-format +#: executor/nodeTableFuncscan.c:392 +#, c-format msgid "row filter expression must not be null" -msgstr "la posición inicial no debe ser null" +msgstr "la expresión filtro de filas no debe ser null" -#: executor/nodeTableFuncscan.c:401 -#, fuzzy, c-format +#: executor/nodeTableFuncscan.c:418 +#, c-format msgid "column filter expression must not be null" -msgstr "la posición inicial no debe ser null" +msgstr "la expresión filtro de columnas no debe ser null" -#: executor/nodeTableFuncscan.c:402 -#, fuzzy, c-format +#: executor/nodeTableFuncscan.c:419 +#, c-format msgid "Filter for column \"%s\" is null." -msgstr "faltan datos en la columna «%s»" +msgstr "El filtro para la columna «%s» es null." -#: executor/nodeTableFuncscan.c:481 -#, fuzzy, c-format +#: executor/nodeTableFuncscan.c:509 +#, c-format msgid "null is not allowed in column \"%s\"" -msgstr "no se puede alterar la columna heredada «%s»" +msgstr "null no está permitido en la columna «%s»" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeWindowAgg.c:354 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "la función de transición de moving-aggregate no debe retornar valor nulo" -#: executor/nodeWindowAgg.c:1621 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "la posición inicial del marco no debe ser null" -#: executor/nodeWindowAgg.c:1634 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "la posición inicial del marco no debe ser negativa" -#: executor/nodeWindowAgg.c:1646 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "la posición final del marco no debe ser null" -#: executor/nodeWindowAgg.c:1659 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "la posición final del marco no debe ser negativa" -#: executor/spi.c:197 +#: executor/nodeWindowAgg.c:2751 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "la función de agregación %s no permite ser usada como función ventana" + +#: executor/spi.c:228 executor/spi.c:297 +#, c-format +msgid "invalid transaction termination" +msgstr "terminación de transacción no válida" + +#: executor/spi.c:242 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "no se puede comprometer mientras hay una subtransacción activa" + +#: executor/spi.c:303 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "no se puede hacer rollback mientras hay una subtransacción activa" + +#: executor/spi.c:372 #, c-format msgid "transaction left non-empty SPI stack" msgstr "transacción dejó un stack SPI no vacío" -#: executor/spi.c:198 executor/spi.c:261 +#: executor/spi.c:373 executor/spi.c:435 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "Revise llamadas a «SPI_finish» faltantes." -#: executor/spi.c:260 +#: executor/spi.c:434 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "subtransacción dejó un stack SPI no vacío" -#: executor/spi.c:1143 +#: executor/spi.c:1335 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "no se puede abrir plan de varias consultas como cursor" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1148 +#: executor/spi.c:1340 #, c-format msgid "cannot open %s query as cursor" msgstr "no se puede abrir consulta %s como cursor" -#: executor/spi.c:1253 +#: executor/spi.c:1445 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE no está soportado" -#: executor/spi.c:1254 parser/analyze.c:2447 +#: executor/spi.c:1446 parser/analyze.c:2493 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Los cursores declarados SCROLL deben ser READ ONLY." -#: executor/spi.c:2374 +#: executor/spi.c:2570 #, c-format msgid "SQL statement \"%s\"" msgstr "sentencia SQL: «%s»" -#: executor/tqueue.c:317 +#: executor/tqueue.c:74 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "no se pudo enviar la tupla a la cola en memoria compartida" -#: foreign/foreign.c:188 +#: foreign/foreign.c:220 #, c-format msgid "user mapping not found for \"%s\"" msgstr "no se encontró un mapeo para el usuario «%s»" -#: foreign/foreign.c:640 +#: foreign/foreign.c:672 #, c-format msgid "invalid option \"%s\"" msgstr "el nombre de opción «%s» no es válido" -#: foreign/foreign.c:641 +#: foreign/foreign.c:673 #, c-format msgid "Valid options in this context are: %s" msgstr "Las opciones válidas en este contexto son: %s" -#: gram.y:1006 -#, fuzzy, c-format -msgid "UNENCRYPTED PASSWORD is no longer supported" -msgstr "aclinsert ya no está soportado" - -#: gram.y:1007 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:426 +#: utils/fmgr/dfmgr.c:474 #, c-format -msgid "Remove UNENCRYPTED to store the password in encrypted form instead." -msgstr "" +msgid "could not access file \"%s\": %m" +msgstr "no se pudo acceder al archivo «%s»: %m" -#: gram.y:1069 +#: jit/llvm/llvmjit.c:601 #, c-format -msgid "unrecognized role option \"%s\"" -msgstr "opción de rol no reconocida «%s»" +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "tiempo en «inline»: %.3fs, opt: %.3fs, emisión: %.3fs" -#: gram.y:1343 gram.y:1358 +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 #, c-format -msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" -msgstr "CREATE SCHEMA IF NOT EXISTS no puede incluir elementos de esquema" +msgid "Failed on DSA request of size %zu." +msgstr "Falla en petición DSA de tamaño %zu." -#: gram.y:1503 +#: lib/stringinfo.c:284 #, c-format -msgid "current database cannot be changed" -msgstr "no se puede cambiar la base de datos activa" +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "No se puede agrandar el búfer de cadena que ya tiene %d bytes en %d bytes adicionales." -#: gram.y:1627 +#: libpq/auth-scram.c:248 #, c-format -msgid "time zone interval must be HOUR or HOUR TO MINUTE" -msgstr "el intervalo de huso horario debe ser HOUR o HOUR TO MINUTE" - -#: gram.y:2643 -#, fuzzy, c-format -msgid "sequence option \"%s\" not supported here" -msgstr "la expansión de filas a través de «*» no está soportado aquí" +msgid "client selected an invalid SASL authentication mechanism" +msgstr "cliente eligió un mecanismo de autentificación SASL no válido" -#: gram.y:2856 gram.y:2885 +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:518 #, c-format -msgid "STDIN/STDOUT not allowed with PROGRAM" -msgstr "STDIN/STDOUT no están permitidos con PROGRAM" +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "verificador SCRAM no válido para el usuario «%s»" -#: gram.y:3195 gram.y:3202 gram.y:11093 gram.y:11101 +#: libpq/auth-scram.c:280 #, c-format -msgid "GLOBAL is deprecated in temporary table creation" -msgstr "GLOBAL está obsoleto para la creación de tablas temporales" +msgid "User \"%s\" does not have a valid SCRAM verifier." +msgstr "Usuario «%s» no tiene un verificador SCRAM válido." -#: gram.y:3677 utils/adt/ri_triggers.c:311 utils/adt/ri_triggers.c:368 -#: utils/adt/ri_triggers.c:787 utils/adt/ri_triggers.c:1010 -#: utils/adt/ri_triggers.c:1166 utils/adt/ri_triggers.c:1347 -#: utils/adt/ri_triggers.c:1512 utils/adt/ri_triggers.c:1688 -#: utils/adt/ri_triggers.c:1868 utils/adt/ri_triggers.c:2059 -#: utils/adt/ri_triggers.c:2117 utils/adt/ri_triggers.c:2222 -#: utils/adt/ri_triggers.c:2399 +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:657 +#: libpq/auth-scram.c:665 libpq/auth-scram.c:776 libpq/auth-scram.c:786 +#: libpq/auth-scram.c:894 libpq/auth-scram.c:901 libpq/auth-scram.c:916 +#: libpq/auth-scram.c:931 libpq/auth-scram.c:945 libpq/auth-scram.c:963 +#: libpq/auth-scram.c:978 libpq/auth-scram.c:1264 libpq/auth-scram.c:1272 #, c-format -msgid "MATCH PARTIAL not yet implemented" -msgstr "MATCH PARTIAL no está implementada" +msgid "malformed SCRAM message" +msgstr "mensaje SCRAM mal formado" -#: gram.y:5139 -#, fuzzy, c-format -msgid "unrecognized row security option \"%s\"" -msgstr "opción de rol no reconocida «%s»" +#: libpq/auth-scram.c:359 +#, c-format +msgid "The message is empty." +msgstr "El mensaje está vacío." -#: gram.y:5140 +#: libpq/auth-scram.c:364 #, c-format -msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." -msgstr "" +msgid "Message length does not match input length." +msgstr "El largo del mensaje no coincide con el largo de entrada." -#: gram.y:5248 -msgid "duplicate trigger events specified" -msgstr "se han especificado eventos de disparador duplicados" +#: libpq/auth-scram.c:396 +#, c-format +msgid "invalid SCRAM response" +msgstr "respuesta SCRAM no válida" -#: gram.y:5384 parser/parse_utilcmd.c:3032 parser/parse_utilcmd.c:3058 +#: libpq/auth-scram.c:397 #, c-format -msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" -msgstr "una restricción declarada INITIALLY DEFERRED debe ser DEFERRABLE" +msgid "Nonce does not match." +msgstr "El «nonce» no coincide." -#: gram.y:5391 +#: libpq/auth-scram.c:471 #, c-format -msgid "conflicting constraint properties" -msgstr "propiedades de restricción contradictorias" +msgid "could not generate random salt" +msgstr "no se pudo generar una sal aleatoria" -#: gram.y:5497 +#: libpq/auth-scram.c:658 #, c-format -msgid "CREATE ASSERTION is not yet implemented" -msgstr "CREATE ASSERTION no está implementado" +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Se esperaba un atributo «%c» pero se encontró «%s»." -#: gram.y:5512 +#: libpq/auth-scram.c:666 libpq/auth-scram.c:787 #, c-format -msgid "DROP ASSERTION is not yet implemented" -msgstr "DROP ASSERTION no está implementado" +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Se esperaba el carácter «=» para el atributo «%c»." -#: gram.y:5892 +#: libpq/auth-scram.c:777 #, c-format -msgid "RECHECK is no longer required" -msgstr "RECHECK ya no es requerido" +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Se esperaba un atributo, se encontró el carácter no válido «%s»." -#: gram.y:5893 +#: libpq/auth-scram.c:895 libpq/auth-scram.c:917 #, c-format -msgid "Update your data type." -msgstr "Actualice su tipo de datos." +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "El cliente seleccionó SCRAM-SHA-256-PLUS, pero el mensaje SCRAM no incluye los datos de enlazado (binding) del canal." -#: gram.y:7536 +#: libpq/auth-scram.c:902 libpq/auth-scram.c:932 #, c-format -msgid "aggregates cannot have output arguments" -msgstr "las funciones de agregación no pueden tener argumentos de salida" +msgid "Comma expected, but found character \"%s\"." +msgstr "Se esperaba una coma, se encontró el carácter «%s»." -#: gram.y:7865 utils/adt/regproc.c:691 utils/adt/regproc.c:732 +#: libpq/auth-scram.c:923 #, c-format -msgid "missing argument" -msgstr "falta un argumento" +msgid "SCRAM channel binding negotiation error" +msgstr "error de negociación de enlazado (binding) de canal SCRAM" -#: gram.y:7866 utils/adt/regproc.c:692 utils/adt/regproc.c:733 +#: libpq/auth-scram.c:924 #, c-format -msgid "Use NONE to denote the missing argument of a unary operator." -msgstr "Use NONE para denotar el argumento faltante de un operador unario." +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "El cliente soporta enlazado (binding) de canal SCRAM, pero piensa que el servidor no. Sin embargo, este servidor sí soporta enlazado de canal." -#: gram.y:9668 gram.y:9686 +#: libpq/auth-scram.c:946 #, c-format -msgid "WITH CHECK OPTION not supported on recursive views" -msgstr "WITH CHECK OPTION no está soportado con vistas recursivas" +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "El cliente seleccionó SCRAM-SHA-256 sin enlazado de canal, pero el mensaje SCRAM incluye datos de enlazado de canal." -#: gram.y:10219 +#: libpq/auth-scram.c:957 #, c-format -msgid "unrecognized VACUUM option \"%s\"" -msgstr "opción de VACUUM «%s» no reconocida" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "tipo de enlazado de canal SCRAM «%s» no soportado" -#: gram.y:11201 +#: libpq/auth-scram.c:964 #, c-format -msgid "LIMIT #,# syntax is not supported" -msgstr "la sintaxis LIMIT #,# no está soportada" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Indicador de enlazado de canal «%s» inesperado." -#: gram.y:11202 +#: libpq/auth-scram.c:974 #, c-format -msgid "Use separate LIMIT and OFFSET clauses." -msgstr "Use cláusulas LIMIT y OFFSET separadas." +msgid "client uses authorization identity, but it is not supported" +msgstr "el cliente usa identidad de autorización, pero no está soportada" -#: gram.y:11483 gram.y:11508 +#: libpq/auth-scram.c:979 #, c-format -msgid "VALUES in FROM must have an alias" -msgstr "VALUES en FROM debe tener un alias" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Atributo inesperado \"%s\" en client-first-message." -#: gram.y:11484 gram.y:11509 +#: libpq/auth-scram.c:995 #, c-format -msgid "For example, FROM (VALUES ...) [AS] foo." -msgstr "Por ejemplo, FROM (VALUES ...) [AS] foo." +msgid "client requires an unsupported SCRAM extension" +msgstr "el cliente requiere una extensión SCRAM no soportada" -#: gram.y:11489 gram.y:11514 +#: libpq/auth-scram.c:1009 #, c-format -msgid "subquery in FROM must have an alias" -msgstr "las subconsultas en FROM deben tener un alias" +msgid "non-printable characters in SCRAM nonce" +msgstr "caracteres no imprimibles en el «nonce» SCRAM" -#: gram.y:11490 gram.y:11515 +#: libpq/auth-scram.c:1126 #, c-format -msgid "For example, FROM (SELECT ...) [AS] foo." -msgstr "Por ejemplo, FROM (SELECT ...) [AS] foo." +msgid "could not generate random nonce" +msgstr "no se pudo generar un «nonce» aleatorio" -#: gram.y:11969 +#: libpq/auth-scram.c:1230 #, c-format -msgid "only one DEFAULT value is allowed" -msgstr "" +msgid "SCRAM channel binding check failed" +msgstr "la verificación de enlazado (binding) de canal SCRAM falló" -#: gram.y:11978 +#: libpq/auth-scram.c:1248 #, c-format -msgid "only one PATH value per column is allowed" -msgstr "" +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "atributo de enlazado de canal SCRAM inesperado en client-final-message" -#: gram.y:11987 -#, fuzzy, c-format -msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" -msgstr "las declaraciones NULL/NOT NULL no son coincidentes para la columna «%s» de la tabla «%s»" +#: libpq/auth-scram.c:1265 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Prueba (proof) mal formada en client-final-message." -#: gram.y:11996 -#, fuzzy, c-format -msgid "unrecognized column option \"%s\"" -msgstr "opción de rol no reconocida «%s»" +#: libpq/auth-scram.c:1273 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Basura encontrada al final de client-final-message." -#: gram.y:12250 +#: libpq/auth.c:279 #, c-format -msgid "precision for type float must be at least 1 bit" -msgstr "la precisión para el tipo float debe ser al menos 1 bit" +msgid "authentication failed for user \"%s\": host rejected" +msgstr "la autentificación falló para el usuario «%s»: anfitrión rechazado" -#: gram.y:12259 +#: libpq/auth.c:282 #, c-format -msgid "precision for type float must be less than 54 bits" -msgstr "la precisión para el tipo float debe ser menor de 54 bits" +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "la autentificación «trust» falló para el usuario «%s»" -#: gram.y:12750 +#: libpq/auth.c:285 #, c-format -msgid "wrong number of parameters on left side of OVERLAPS expression" -msgstr "el número de parámetros es incorrecto al lado izquierdo de la expresión OVERLAPS" +msgid "Ident authentication failed for user \"%s\"" +msgstr "la autentificación Ident falló para el usuario «%s»" -#: gram.y:12755 +#: libpq/auth.c:288 #, c-format -msgid "wrong number of parameters on right side of OVERLAPS expression" -msgstr "el número de parámetros es incorrecto al lado derecho de la expresión OVERLAPS" +msgid "Peer authentication failed for user \"%s\"" +msgstr "la autentificación Peer falló para el usuario «%s»" -#: gram.y:12930 +#: libpq/auth.c:293 #, c-format -msgid "UNIQUE predicate is not yet implemented" -msgstr "el predicado UNIQUE no está implementado" +msgid "password authentication failed for user \"%s\"" +msgstr "la autentificación password falló para el usuario «%s»" -#: gram.y:13277 +#: libpq/auth.c:298 #, c-format -msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" -msgstr "no se permiten múltiples cláusulas ORDER BY con WITHIN GROUP" +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "la autentificación GSSAPI falló para el usuario «%s»" -#: gram.y:13282 +#: libpq/auth.c:301 #, c-format -msgid "cannot use DISTINCT with WITHIN GROUP" -msgstr "no se permite DISTINCT con WITHIN GROUP" +msgid "SSPI authentication failed for user \"%s\"" +msgstr "la autentificación SSPI falló para el usuario «%s»" -#: gram.y:13287 +#: libpq/auth.c:304 #, c-format -msgid "cannot use VARIADIC with WITHIN GROUP" -msgstr "no se permite VARIADIC con WITHIN GROUP" +msgid "PAM authentication failed for user \"%s\"" +msgstr "la autentificación PAM falló para el usuario «%s»" -#: gram.y:13713 +#: libpq/auth.c:307 #, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING sólo está soportado con UNBOUNDED" +msgid "BSD authentication failed for user \"%s\"" +msgstr "la autentificación BSD falló para el usuario «%s»" -#: gram.y:13719 +#: libpq/auth.c:310 #, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING sólo está soportado con UNBOUNDED" +msgid "LDAP authentication failed for user \"%s\"" +msgstr "la autentificación LDAP falló para el usuario «%s»" -#: gram.y:13746 gram.y:13769 +#: libpq/auth.c:313 #, c-format -msgid "frame start cannot be UNBOUNDED FOLLOWING" -msgstr "el inicio de «frame» no puede ser UNBOUNDED FOLLOWING" +msgid "certificate authentication failed for user \"%s\"" +msgstr "la autentificación por certificado falló para el usuario «%s»" -#: gram.y:13751 +#: libpq/auth.c:316 #, c-format -msgid "frame starting from following row cannot end with current row" -msgstr "el «frame» que se inicia desde la siguiente fila no puede terminar en la fila actual" +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "la autentificación RADIUS falló para el usuario «%s»" -#: gram.y:13774 +#: libpq/auth.c:319 #, c-format -msgid "frame end cannot be UNBOUNDED PRECEDING" -msgstr "el fin de «frame» no puede ser UNBOUNDED PRECEDING" +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "la autentificación falló para el usuario «%s»: método de autentificación no válido" -#: gram.y:13780 +#: libpq/auth.c:323 #, c-format -msgid "frame starting from current row cannot have preceding rows" -msgstr "el «frame» que se inicia desde la fila actual no puede tener filas precedentes" +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "La conexión coincidió con la línea %d de pg_hba.conf: «%s»" -#: gram.y:13787 +#: libpq/auth.c:370 #, c-format -msgid "frame starting from following row cannot have preceding rows" -msgstr "el «frame» que se inicia desde la fila siguiente no puede tener filas precedentes" +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "los certificados de cliente sólo pueden verificarse si un almacén de certificado raíz está disponible" -#: gram.y:14422 +#: libpq/auth.c:381 #, c-format -msgid "type modifier cannot have parameter name" -msgstr "el modificador de tipo no puede tener nombre de parámetro" +msgid "connection requires a valid client certificate" +msgstr "la conexión requiere un certificado de cliente válido" -#: gram.y:14428 +#: libpq/auth.c:391 #, c-format -msgid "type modifier cannot have ORDER BY" -msgstr "el modificador de tipo no puede tener ORDER BY" +msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +msgstr "el cifrado GSSAPI sólo puede ser usado con los métodos gss, trust o reject" -#: gram.y:14492 gram.y:14498 +#: libpq/auth.c:425 #, c-format -msgid "%s cannot be used as a role name here" -msgstr "%s no puede ser usado como nombre de rol aquí" +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s», %s" -#: gram.y:15160 gram.y:15349 -msgid "improper use of \"*\"" -msgstr "uso impropio de «*»" +#: libpq/auth.c:427 libpq/auth.c:443 libpq/auth.c:501 libpq/auth.c:519 +msgid "SSL off" +msgstr "SSL inactivo" + +#: libpq/auth.c:427 libpq/auth.c:443 libpq/auth.c:501 libpq/auth.c:519 +msgid "SSL on" +msgstr "SSL activo" -#: gram.y:15312 gram.y:15329 tsearch/spell.c:954 tsearch/spell.c:971 -#: tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 +#: libpq/auth.c:431 #, c-format -msgid "syntax error" -msgstr "error de sintaxis" +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s»" -#: gram.y:15413 +#: libpq/auth.c:440 #, c-format -msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" -msgstr "una agregación de conjunto-ordenado con un argumento directo VARIADIC debe tener al menos un argumento agregado VARIADIC del mismo tipo de datos" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s», %s" -#: gram.y:15450 +#: libpq/auth.c:447 #, c-format -msgid "multiple ORDER BY clauses not allowed" -msgstr "no se permiten múltiples cláusulas ORDER BY" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s»" -#: gram.y:15461 +#: libpq/auth.c:476 #, c-format -msgid "multiple OFFSET clauses not allowed" -msgstr "no se permiten múltiples cláusulas OFFSET" +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado es coincidente." -#: gram.y:15470 +#: libpq/auth.c:479 #, c-format -msgid "multiple LIMIT clauses not allowed" -msgstr "no se permiten múltiples cláusulas LIMIT" +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no fue verificado." -#: gram.y:15479 +#: libpq/auth.c:482 #, c-format -msgid "multiple WITH clauses not allowed" -msgstr "no se permiten múltiples cláusulas WITH" +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no es coincidente." -#: gram.y:15683 +#: libpq/auth.c:485 #, c-format -msgid "OUT and INOUT arguments aren't allowed in TABLE functions" -msgstr "los argumentos OUT e INOUT no están permitidos en funciones TABLE" +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "No se pudo traducir el nombre de host del cliente «%s» a una dirección IP: %s." -#: gram.y:15784 +#: libpq/auth.c:490 #, c-format -msgid "multiple COLLATE clauses not allowed" -msgstr "no se permiten múltiples cláusulas COLLATE" +msgid "Could not resolve client IP address to a host name: %s." +msgstr "No se pudo obtener la dirección IP del cliente a un nombre de host: %s." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15822 gram.y:15835 +#: libpq/auth.c:499 #, c-format -msgid "%s constraints cannot be marked DEFERRABLE" -msgstr "las restricciones %s no pueden ser marcadas DEFERRABLE" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s», %s" -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15848 +#: libpq/auth.c:506 #, c-format -msgid "%s constraints cannot be marked NOT VALID" -msgstr "las restricciones %s no pueden ser marcadas NOT VALID" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s»" -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15861 +#: libpq/auth.c:516 #, c-format -msgid "%s constraints cannot be marked NO INHERIT" -msgstr "las restricciones %s no pueden ser marcadas NO INHERIT" +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s», %s" -#: guc-file.l:313 +#: libpq/auth.c:524 #, c-format -msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" -msgstr "parámetro de configuración «%s» no reconocido en el archivo «%s» línea %u" +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s»" -#: guc-file.l:350 utils/misc/guc.c:5995 utils/misc/guc.c:6188 -#: utils/misc/guc.c:6278 utils/misc/guc.c:6368 utils/misc/guc.c:6476 -#: utils/misc/guc.c:6571 +#: libpq/auth.c:691 #, c-format -msgid "parameter \"%s\" cannot be changed without restarting the server" -msgstr "el parámetro «%s» no se puede cambiar sin reiniciar el servidor" +msgid "expected password response, got message type %d" +msgstr "se esperaba una respuesta de contraseña, se obtuvo mensaje de tipo %d" -#: guc-file.l:386 +#: libpq/auth.c:719 #, c-format -msgid "parameter \"%s\" removed from configuration file, reset to default" -msgstr "parámetro «%s» eliminado del archivo de configuración, volviendo al valor por omisión" +msgid "invalid password packet size" +msgstr "el tamaño del paquete de contraseña no es válido" -#: guc-file.l:452 +#: libpq/auth.c:737 #, c-format -msgid "parameter \"%s\" changed to \"%s\"" -msgstr "el parámetro «%s» fue cambiado a «%s»" +msgid "empty password returned by client" +msgstr "el cliente retornó una contraseña vacía" -#: guc-file.l:494 +#: libpq/auth.c:857 libpq/hba.c:1340 #, c-format -msgid "configuration file \"%s\" contains errors" -msgstr "el archivo de configuración «%s» contiene errores" +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "la autentificación MD5 no está soportada cuando «db_user_namespace» está activo" -#: guc-file.l:499 +#: libpq/auth.c:863 #, c-format -msgid "configuration file \"%s\" contains errors; unaffected changes were applied" -msgstr "el archivo de configuración «%s» contiene errores; los cambios no afectados fueron aplicados" +msgid "could not generate random MD5 salt" +msgstr "no se pudo generar una sal MD5 aleatoria" -#: guc-file.l:504 +#: libpq/auth.c:909 #, c-format -msgid "configuration file \"%s\" contains errors; no changes were applied" -msgstr "el archivo de configuración «%s» contiene errores; no se aplicó ningún cambio" +msgid "SASL authentication is not supported in protocol version 2" +msgstr "autentificación SASL no está soportada en el protocolo versión 2" -#: guc-file.l:577 +#: libpq/auth.c:942 #, c-format -msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" -msgstr "no se pudo abrir el archivo de configuración «%s»: nivel de anidamiento máximo excedido" +msgid "expected SASL response, got message type %d" +msgstr "se esperaba una respuesta SASL, se obtuvo mensaje de tipo %d" -#: guc-file.l:593 libpq/hba.c:2110 libpq/hba.c:2510 +#: libpq/auth.c:1071 #, c-format -msgid "could not open configuration file \"%s\": %m" -msgstr "no se pudo abrir el archivo de configuración «%s»: %m" +msgid "GSSAPI is not supported in protocol version 2" +msgstr "GSSAPI no está soportado por el protocolo versión 2" -#: guc-file.l:604 +#: libpq/auth.c:1131 #, c-format -msgid "skipping missing configuration file \"%s\"" -msgstr "saltando el archivo de configuración faltante «%s»" +msgid "expected GSS response, got message type %d" +msgstr "se esperaba una respuesta GSS, se obtuvo mensaje de tipo %d" -#: guc-file.l:858 -#, c-format -msgid "syntax error in file \"%s\" line %u, near end of line" -msgstr "error de sintaxis en el archivo «%s» línea %u, cerca del fin de línea" +#: libpq/auth.c:1193 +msgid "accepting GSS security context failed" +msgstr "falló la aceptación del contexto de seguridad GSS" -#: guc-file.l:868 -#, c-format -msgid "syntax error in file \"%s\" line %u, near token \"%s\"" -msgstr "error de sintaxis en el archivo «%s» línea %u, cerca de la palabra «%s»" +#: libpq/auth.c:1232 +msgid "retrieving GSS user name failed" +msgstr "falló la obtención del nombre de usuario GSS" -#: guc-file.l:888 +#: libpq/auth.c:1363 #, c-format -msgid "too many syntax errors found, abandoning file \"%s\"" -msgstr "se encontraron demasiados errores de sintaxis, abandonando el archivo «%s»" +msgid "SSPI is not supported in protocol version 2" +msgstr "SSPI no está soportado por el protocolo versión 2" -#: guc-file.l:940 -#, c-format -msgid "could not open configuration directory \"%s\": %m" -msgstr "no se pudo abrir el directorio de configuración «%s»: %m" +#: libpq/auth.c:1378 +msgid "could not acquire SSPI credentials" +msgstr "no se pudo obtener las credenciales SSPI" -#: lib/stringinfo.c:259 +#: libpq/auth.c:1396 #, c-format -msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." -msgstr "No se puede agrandar el búfer de cadena que ya tiene %d bytes en %d bytes adicionales." +msgid "expected SSPI response, got message type %d" +msgstr "se esperaba una respuesta SSPI, se obtuvo mensaje de tipo %d" -#: libpq/auth-scram.c:199 libpq/auth-scram.c:439 libpq/auth-scram.c:448 -#, fuzzy, c-format -#| msgid "invalid RADIUS port number: \"%s\"" -msgid "invalid SCRAM verifier for user \"%s\"" -msgstr "número de puerto RADIUS no válido: «%s»" +#: libpq/auth.c:1469 +msgid "could not accept SSPI security context" +msgstr "no se pudo aceptar un contexto SSPI" -#: libpq/auth-scram.c:210 -#, fuzzy, c-format -msgid "User \"%s\" does not have a valid SCRAM verifier." -msgstr "Usuario no tiene privilegios de conexión." +#: libpq/auth.c:1531 +msgid "could not get token from SSPI security context" +msgstr "no se pudo obtener un testigo (token) desde el contexto de seguridad SSPI" -#: libpq/auth-scram.c:288 libpq/auth-scram.c:293 libpq/auth-scram.c:587 -#: libpq/auth-scram.c:595 libpq/auth-scram.c:676 libpq/auth-scram.c:686 -#: libpq/auth-scram.c:804 libpq/auth-scram.c:811 libpq/auth-scram.c:826 -#: libpq/auth-scram.c:1056 libpq/auth-scram.c:1064 +#: libpq/auth.c:1650 libpq/auth.c:1669 #, c-format -msgid "malformed SCRAM message" -msgstr "" +msgid "could not translate name" +msgstr "no se pudo traducir el nombre" -#: libpq/auth-scram.c:289 -#, fuzzy, c-format -#| msgid "empty message text" -msgid "The message is empty." -msgstr "mensaje de texto vacío" +#: libpq/auth.c:1682 +#, c-format +msgid "realm name too long" +msgstr "nombre de «realm» demasiado largo" -#: libpq/auth-scram.c:294 -#, fuzzy, c-format -#| msgid "bit string length %d does not match type bit(%d)" -msgid "Message length does not match input length." -msgstr "el largo de la cadena de bits %d no coincide con el tipo bit(%d)" +#: libpq/auth.c:1697 +#, c-format +msgid "translated account name too long" +msgstr "nombre de cuenta traducido demasiado largo" -#: libpq/auth-scram.c:326 -#, fuzzy, c-format -msgid "invalid SCRAM response" -msgstr "consulta no válido" +#: libpq/auth.c:1883 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "no se pudo crear un socket para conexión Ident: %m" -#: libpq/auth-scram.c:327 -#, fuzzy, c-format -#| msgid "Role \"%s\" does not exist." -msgid "Nonce does not match." -msgstr "No existe el rol «%s»." +#: libpq/auth.c:1898 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "no se pudo enlazar a la dirección local «%s»: %m" -#: libpq/auth-scram.c:401 -#, fuzzy, c-format -msgid "could not generate random salt" -msgstr "no se pudo generar un vector aleatorio de encriptación" +#: libpq/auth.c:1910 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo conectar al servidor Ident en dirección «%s», port %s: %m" -#: libpq/auth-scram.c:588 -#, fuzzy, c-format -#| msgid "Expected string, but found \"%s\"." -msgid "Expected attribute '%c' but found %s." -msgstr "Se esperaba una cadena, se encontró «%s»." +#: libpq/auth.c:1932 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo enviar consulta Ident al servidor «%s», port %s: %m" -#: libpq/auth-scram.c:596 libpq/auth-scram.c:687 -#, fuzzy, c-format -#| msgid "Expected %d parameters but got %d." -msgid "Expected character = for attribute %c." -msgstr "Se esperaban %d parámetros pero se obtuvieron %d." +#: libpq/auth.c:1949 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "no se pudo recibir respuesta Ident desde el servidor «%s», port %s: %m" -#: libpq/auth-scram.c:677 +#: libpq/auth.c:1959 #, c-format -msgid "Attribute expected, but found invalid character %s." -msgstr "" +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "respuesta del servidor Ident en formato no válido: «%s»" -#: libpq/auth-scram.c:800 +#: libpq/auth.c:1999 #, c-format -msgid "client requires SCRAM channel binding, but it is not supported" -msgstr "" +msgid "peer authentication is not supported on this platform" +msgstr "método de autentificación peer no está soportado en esta plataforma" -#: libpq/auth-scram.c:805 -#, fuzzy, c-format -#| msgid "Unexpected end of input." -msgid "Unexpected channel-binding flag %s." -msgstr "Fin inesperado de la entrada." +#: libpq/auth.c:2003 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "no se pudo recibir credenciales: %m" -#: libpq/auth-scram.c:812 -#, fuzzy, c-format -#| msgid "Expected \":\", but found \"%s\"." -msgid "Comma expected, but found character %s." -msgstr "Se esperaba «:», se encontró «%s»." +#: libpq/auth.c:2014 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "no se pudo encontrar el ID del usuario local %ld: %s" -#: libpq/auth-scram.c:822 +#: libpq/auth.c:2102 #, c-format -msgid "client uses authorization identity, but it is not supported" -msgstr "" +msgid "error from underlying PAM layer: %s" +msgstr "se ha recibido un error de la biblioteca PAM: %s" -#: libpq/auth-scram.c:827 +#: libpq/auth.c:2171 #, c-format -msgid "Unexpected attribute %s in client-first-message." -msgstr "" +msgid "could not create PAM authenticator: %s" +msgstr "no se pudo crear autenticador PAM: %s" -#: libpq/auth-scram.c:843 +#: libpq/auth.c:2182 #, c-format -msgid "client requires an unsupported SCRAM extension" -msgstr "" +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) falló: %s" -#: libpq/auth-scram.c:857 +#: libpq/auth.c:2214 #, c-format -msgid "non-printable characters in SCRAM nonce" -msgstr "" +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) falló: %s" -#: libpq/auth-scram.c:974 -#, fuzzy, c-format -msgid "could not generate random nonce" -msgstr "no se pudo generar un vector aleatorio de encriptación" +#: libpq/auth.c:2226 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) falló: %s" -#: libpq/auth-scram.c:1042 +#: libpq/auth.c:2237 #, c-format -msgid "unexpected SCRAM channel-binding attribute in client-final-message" -msgstr "" +msgid "pam_authenticate failed: %s" +msgstr "pam_authenticate falló: %s" -#: libpq/auth-scram.c:1057 +#: libpq/auth.c:2248 #, c-format -msgid "Malformed proof in client-final-message." -msgstr "" +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt falló: %s" -#: libpq/auth-scram.c:1065 +#: libpq/auth.c:2259 #, c-format -msgid "Garbage found at the end of client-final-message." -msgstr "" +msgid "could not release PAM authenticator: %s" +msgstr "no se pudo liberar autenticador PAM: %s" -#: libpq/auth.c:274 +#: libpq/auth.c:2335 #, c-format -msgid "authentication failed for user \"%s\": host rejected" -msgstr "la autentificación falló para el usuario «%s»: anfitrión rechazado" +msgid "could not initialize LDAP: error code %d" +msgstr "no se pudo inicializar LDAP: código de error %d" -#: libpq/auth.c:277 +#: libpq/auth.c:2372 #, c-format -msgid "\"trust\" authentication failed for user \"%s\"" -msgstr "la autentificación «trust» falló para el usuario «%s»" +msgid "could not extract domain name from ldapbasedn" +msgstr "no se pudo extraer el nombre de dominio de ldapbasedn" -#: libpq/auth.c:280 +#: libpq/auth.c:2380 #, c-format -msgid "Ident authentication failed for user \"%s\"" -msgstr "la autentificación Ident falló para el usuario «%s»" +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "la autentificación LDAP no pudo encontrar registros DNS SRV para «%s»" -#: libpq/auth.c:283 +#: libpq/auth.c:2382 #, c-format -msgid "Peer authentication failed for user \"%s\"" -msgstr "la autentificación Peer falló para el usuario «%s»" +msgid "Set an LDAP server name explicitly." +msgstr "Defina un nombre de servidor LDAP explícitamente." -#: libpq/auth.c:288 +#: libpq/auth.c:2434 #, c-format -msgid "password authentication failed for user \"%s\"" -msgstr "la autentificación password falló para el usuario «%s»" +msgid "could not initialize LDAP: %s" +msgstr "no se pudo inicializar LDAP: %s" -#: libpq/auth.c:293 +#: libpq/auth.c:2444 #, c-format -msgid "GSSAPI authentication failed for user \"%s\"" -msgstr "la autentificación GSSAPI falló para el usuario «%s»" +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps no está soportado con esta biblioteca LDAP" -#: libpq/auth.c:296 +#: libpq/auth.c:2452 #, c-format -msgid "SSPI authentication failed for user \"%s\"" -msgstr "la autentificación SSPI falló para el usuario «%s»" +msgid "could not initialize LDAP: %m" +msgstr "no se pudo inicializar LDAP: %m" -#: libpq/auth.c:299 +#: libpq/auth.c:2462 #, c-format -msgid "PAM authentication failed for user \"%s\"" -msgstr "la autentificación PAM falló para el usuario «%s»" +msgid "could not set LDAP protocol version: %s" +msgstr "no se pudo definir la versión de protocolo LDAP: %s" -#: libpq/auth.c:302 +#: libpq/auth.c:2493 #, c-format -msgid "BSD authentication failed for user \"%s\"" -msgstr "la autentificación BSD falló para el usuario «%s»" +msgid "could not load wldap32.dll" +msgstr "no se pudo cargar wldap32.dll" -#: libpq/auth.c:305 +#: libpq/auth.c:2501 #, c-format -msgid "LDAP authentication failed for user \"%s\"" -msgstr "la autentificación LDAP falló para el usuario «%s»" +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "no se pudo cargar la función _ldap_start_tls_sA en wldap32.dll" -#: libpq/auth.c:308 +#: libpq/auth.c:2502 #, c-format -msgid "certificate authentication failed for user \"%s\"" -msgstr "la autentificación por certificado falló para el usuario «%s»" +msgid "LDAP over SSL is not supported on this platform." +msgstr "LDAP sobre SSL no está soportado en esta plataforma." -#: libpq/auth.c:311 +#: libpq/auth.c:2517 #, c-format -msgid "RADIUS authentication failed for user \"%s\"" -msgstr "la autentificación RADIUS falló para el usuario «%s»" +msgid "could not start LDAP TLS session: %s" +msgstr "no se pudo iniciar sesión de LDAP TLS: %s" -#: libpq/auth.c:314 +#: libpq/auth.c:2588 #, c-format -msgid "authentication failed for user \"%s\": invalid authentication method" -msgstr "la autentificación falló para el usuario «%s»: método de autentificación no válido" +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "servidor LDAP no especificado, y no hay ldapbasedn" -#: libpq/auth.c:318 +#: libpq/auth.c:2595 #, c-format -msgid "Connection matched pg_hba.conf line %d: \"%s\"" -msgstr "La conexión coincidió con la línea %d de pg_hba.conf: «%s»" +msgid "LDAP server not specified" +msgstr "servidor LDAP no especificado" -#: libpq/auth.c:365 +#: libpq/auth.c:2657 #, c-format -msgid "client certificates can only be checked if a root certificate store is available" -msgstr "los certificados de cliente sólo pueden verificarse si un almacén de certificado raíz está disponible" +msgid "invalid character in user name for LDAP authentication" +msgstr "carácter no válido en nombre de usuario para autentificación LDAP" -#: libpq/auth.c:376 +#: libpq/auth.c:2674 #, c-format -msgid "connection requires a valid client certificate" -msgstr "la conexión requiere un certificado de cliente válido" +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "no se pudo hacer el enlace LDAP inicial para el ldapbinddb «%s» en el servidor «%s»: %s" -#: libpq/auth.c:409 +#: libpq/auth.c:2703 #, c-format -msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" -msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s», %s" +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "no se pudo hacer la búsqueda LDAP para el filtro «%s» en el servidor «%s»: %s" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 -msgid "SSL off" -msgstr "SSL inactivo" +#: libpq/auth.c:2717 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "no existe el usuario LDAP «%s»" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 -msgid "SSL on" -msgstr "SSL activo" +#: libpq/auth.c:2718 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "La búsqueda LDAP para el filtro «%s» en el servidor «%s» no retornó elementos." -#: libpq/auth.c:415 +#: libpq/auth.c:2722 #, c-format -msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" -msgstr "pg_hba.conf rechaza la conexión de replicación para el servidor «%s», usuario «%s»" +msgid "LDAP user \"%s\" is not unique" +msgstr "el usuario LDAP «%s» no es única" -#: libpq/auth.c:424 +#: libpq/auth.c:2723 #, c-format -msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" -msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s», %s" +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elemento." +msgstr[1] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elementos." -#: libpq/auth.c:431 +#: libpq/auth.c:2743 #, c-format -msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" -msgstr "pg_hba.conf rechaza la conexión para el servidor «%s», usuario «%s», base de datos «%s»" +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "no se pudo obtener el dn para la primera entrada que coincide con «%s» en el servidor «%s»: %s" -#: libpq/auth.c:460 +#: libpq/auth.c:2764 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup matches." -msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado es coincidente." +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "no se pudo desconectar (unbind) después de buscar al usuario «%s» en el servidor «%s»" -#: libpq/auth.c:463 +#: libpq/auth.c:2795 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup not checked." -msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no fue verificado." +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "falló el inicio de sesión LDAP para el usuario «%s» en el servidor «%s»: %s" -#: libpq/auth.c:466 +#: libpq/auth.c:2824 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup does not match." -msgstr "La dirección IP del cliente fue resuelta a «%s», este resultado no es coincidente." +msgid "LDAP diagnostics: %s" +msgstr "Diagnóstico LDAP: %s" -#: libpq/auth.c:469 +#: libpq/auth.c:2851 #, c-format -msgid "Could not translate client host name \"%s\" to IP address: %s." -msgstr "No se pudo traducir el nombre de host del cliente «%s» a una dirección IP: %s." +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "la autentificación con certificado falló para el usuario «%s»: el certificado de cliente no contiene un nombre de usuario" -#: libpq/auth.c:474 +#: libpq/auth.c:2868 #, c-format -msgid "Could not resolve client IP address to a host name: %s." -msgstr "No se pudo obtener la dirección IP del cliente a un nombre de host: %s." +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": cn mismatch" +msgstr "la validación de certificado (clientcert=verify-full) falló para el usuario «%s»: discordancia de cn" -#: libpq/auth.c:483 +#: libpq/auth.c:2969 #, c-format -msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" -msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s», %s" +msgid "RADIUS server not specified" +msgstr "servidor RADIUS no especificado" -#: libpq/auth.c:490 +#: libpq/auth.c:2976 #, c-format -msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" -msgstr "no hay una línea en pg_hba.conf para la conexión de replicación desde el servidor «%s», usuario «%s»" +msgid "RADIUS secret not specified" +msgstr "secreto RADIUS no especificado" -#: libpq/auth.c:500 +#: libpq/auth.c:2990 #, c-format -msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" -msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s», %s" +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "la autentificación RADIUS no soporta contraseñas más largas de %d caracteres" -#: libpq/auth.c:508 +#: libpq/auth.c:3095 libpq/hba.c:1954 #, c-format -msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" -msgstr "no hay una línea en pg_hba.conf para «%s», usuario «%s», base de datos «%s»" +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "no se pudo traducir el nombre de servidor RADIUS «%s» a dirección: %s" -#: libpq/auth.c:661 +#: libpq/auth.c:3109 #, c-format -msgid "expected password response, got message type %d" -msgstr "se esperaba una respuesta de contraseña, se obtuvo mensaje de tipo %d" +msgid "could not generate random encryption vector" +msgstr "no se pudo generar un vector aleatorio de encriptación" -#: libpq/auth.c:689 +#: libpq/auth.c:3143 #, c-format -msgid "invalid password packet size" -msgstr "el tamaño del paquete de contraseña no es válido" +msgid "could not perform MD5 encryption of password" +msgstr "no se pudo efectuar cifrado MD5 de la contraseña" -#: libpq/auth.c:809 libpq/hba.c:1325 +#: libpq/auth.c:3169 #, c-format -msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" -msgstr "la autentificación MD5 no está soportada cuando «db_user_namespace» está activo" +msgid "could not create RADIUS socket: %m" +msgstr "no se pudo crear el socket RADIUS: %m" -#: libpq/auth.c:815 -#, fuzzy, c-format -msgid "could not generate random MD5 salt" -msgstr "no se pudo generar un vector aleatorio de encriptación" +#: libpq/auth.c:3191 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "no se pudo enlazar el socket RADIUS local: %m" -#: libpq/auth.c:860 -#, fuzzy, c-format -msgid "SASL authentication is not supported in protocol version 2" -msgstr "SSPI no está soportado por el protocolo versión 2" +#: libpq/auth.c:3201 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "no se pudo enviar el paquete RADIUS: %m" -#: libpq/auth.c:902 -#, fuzzy, c-format -msgid "expected SASL response, got message type %d" -msgstr "se esperaba una respuesta GSS, se obtuvo mensaje de tipo %d" +#: libpq/auth.c:3234 libpq/auth.c:3260 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "se agotó el tiempo de espera de la respuesta RADIUS desde %s" -#: libpq/auth.c:939 -#, fuzzy, c-format -msgid "client selected an invalid SASL authentication mechanism" -msgstr "método de autentificación «%s» no válido" +#: libpq/auth.c:3253 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "no se pudo verificar el estado en el socket %m" -#: libpq/auth.c:1086 +#: libpq/auth.c:3283 #, c-format -msgid "GSSAPI is not supported in protocol version 2" -msgstr "GSSAPI no está soportado por el protocolo versión 2" +msgid "could not read RADIUS response: %m" +msgstr "no se pudo leer la respuesta RADIUS: %m" -#: libpq/auth.c:1146 +#: libpq/auth.c:3296 libpq/auth.c:3300 #, c-format -msgid "expected GSS response, got message type %d" -msgstr "se esperaba una respuesta GSS, se obtuvo mensaje de tipo %d" +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "la respuesta RADIUS desde %s fue enviada desde el port incorrecto: %d" -#: libpq/auth.c:1208 -msgid "accepting GSS security context failed" -msgstr "falló la aceptación del contexto de seguridad GSS" +#: libpq/auth.c:3309 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "la respuesta RADIUS desde %s es demasiado corta: %d" -#: libpq/auth.c:1234 -msgid "retrieving GSS user name failed" -msgstr "falló la obtención del nombre de usuario GSS" +#: libpq/auth.c:3316 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "la respuesta RADIUS desde %ss tiene largo corrupto: %d (largo real %d)" -#: libpq/auth.c:1354 +#: libpq/auth.c:3324 #, c-format -msgid "SSPI is not supported in protocol version 2" -msgstr "SSPI no está soportado por el protocolo versión 2" +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "la respuesta RADIUS desde %s es a una petición diferente: %d (debería ser %d)" -#: libpq/auth.c:1369 -msgid "could not acquire SSPI credentials" -msgstr "no se pudo obtener las credenciales SSPI" +#: libpq/auth.c:3349 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "no se pudo realizar cifrado MD5 del paquete recibido" -#: libpq/auth.c:1387 +#: libpq/auth.c:3358 #, c-format -msgid "expected SSPI response, got message type %d" -msgstr "se esperaba una respuesta SSPI, se obtuvo mensaje de tipo %d" +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "la respuesta RADIUS desde %s tiene firma MD5 incorrecta" -#: libpq/auth.c:1460 -msgid "could not accept SSPI security context" -msgstr "no se pudo aceptar un contexto SSPI" +#: libpq/auth.c:3376 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "la respuesta RADIUS desde %s tiene código no válido (%d) para el usuario «%s»" -#: libpq/auth.c:1522 -msgid "could not get token from SSPI security context" -msgstr "no se pudo obtener un testigo (token) desde el contexto de seguridad SSPI" +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:555 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "el descriptor de objeto grande no es válido: %d" -#: libpq/auth.c:1641 libpq/auth.c:1660 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "could not translate name" -msgstr "no se pudo traducir el nombre" +msgid "large object descriptor %d was not opened for reading" +msgstr "el descriptor de objeto grande %d no fue abierto para lectura" -#: libpq/auth.c:1673 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:562 #, c-format -msgid "realm name too long" -msgstr "nombre de «realm» demasiado largo" +msgid "large object descriptor %d was not opened for writing" +msgstr "el descriptor de objeto grande %d no fue abierto para escritura" -#: libpq/auth.c:1688 +#: libpq/be-fsstubs.c:212 #, c-format -msgid "translated account name too long" -msgstr "nombre de cuenta traducido demasiado largo" +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "el resultado de lo_lseek está fuera de rango para el descriptor de objeto grande %d" -#: libpq/auth.c:1874 +#: libpq/be-fsstubs.c:285 #, c-format -msgid "could not create socket for Ident connection: %m" -msgstr "no se pudo crear un socket para conexión Ident: %m" +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "el resultado de lo_tell está fuera de rango para el descriptor de objeto grande %d" -#: libpq/auth.c:1889 +#: libpq/be-fsstubs.c:432 #, c-format -msgid "could not bind to local address \"%s\": %m" -msgstr "no se pudo enlazar a la dirección local «%s»: %m" +msgid "could not open server file \"%s\": %m" +msgstr "no se pudo abrir el archivo de servidor «%s»: %m" -#: libpq/auth.c:1901 +#: libpq/be-fsstubs.c:454 #, c-format -msgid "could not connect to Ident server at address \"%s\", port %s: %m" -msgstr "no se pudo conectar al servidor Ident «%s», port %s: %m" +msgid "could not read server file \"%s\": %m" +msgstr "no se pudo leer el archivo de servidor «%s»: %m" -#: libpq/auth.c:1923 +#: libpq/be-fsstubs.c:516 #, c-format -msgid "could not send query to Ident server at address \"%s\", port %s: %m" -msgstr "no se pudo enviar consulta Ident al servidor «%s», port %s: %m" +msgid "could not create server file \"%s\": %m" +msgstr "no se pudo crear el archivo del servidor «%s»: %m" -#: libpq/auth.c:1940 +#: libpq/be-fsstubs.c:528 #, c-format -msgid "could not receive response from Ident server at address \"%s\", port %s: %m" -msgstr "no se pudo recibir respuesta Ident desde el servidor «%s», port %s: %m" +msgid "could not write server file \"%s\": %m" +msgstr "no se pudo escribir el archivo del servidor «%s»: %m" -#: libpq/auth.c:1950 +#: libpq/be-fsstubs.c:762 #, c-format -msgid "invalidly formatted response from Ident server: \"%s\"" -msgstr "respuesta del servidor Ident en formato no válido: «%s»" +msgid "large object read request is too large" +msgstr "el tamaño de petición de lectura de objeto grande es muy grande" -#: libpq/auth.c:1990 +#: libpq/be-fsstubs.c:804 utils/adt/genfile.c:235 utils/adt/genfile.c:274 +#: utils/adt/genfile.c:310 #, c-format -msgid "peer authentication is not supported on this platform" -msgstr "método de autentificación peer no está soportado en esta plataforma" +msgid "requested length cannot be negative" +msgstr "el tamaño solicitado no puede ser negativo" -#: libpq/auth.c:1994 +#: libpq/be-fsstubs.c:857 storage/large_object/inv_api.c:295 +#: storage/large_object/inv_api.c:307 storage/large_object/inv_api.c:511 +#: storage/large_object/inv_api.c:622 storage/large_object/inv_api.c:812 #, c-format -msgid "could not get peer credentials: %m" -msgstr "no se pudo recibir credenciales: %m" +msgid "permission denied for large object %u" +msgstr "permiso denegado al objeto grande %u" -#: libpq/auth.c:2003 +#: libpq/be-secure-common.c:91 #, c-format -msgid "could not look up local user ID %ld: %s" -msgstr "no se pudo encontrar el ID del usuario local %ld: %s" +msgid "could not read from command \"%s\": %m" +msgstr "no se pudo leer desde la orden «%s»: %m" -#: libpq/auth.c:2087 libpq/auth.c:2413 libpq/auth.c:2726 +#: libpq/be-secure-common.c:109 #, c-format -msgid "empty password returned by client" -msgstr "el cliente retornó una contraseña vacía" +msgid "command \"%s\" failed" +msgstr "la orden «%s» falló" -#: libpq/auth.c:2097 +#: libpq/be-secure-common.c:139 #, c-format -msgid "error from underlying PAM layer: %s" -msgstr "se ha recibido un error de la biblioteca PAM: %s" +msgid "could not access private key file \"%s\": %m" +msgstr "no se pudo acceder al archivo de la llave privada «%s»: %m" -#: libpq/auth.c:2178 +#: libpq/be-secure-common.c:148 #, c-format -msgid "could not create PAM authenticator: %s" -msgstr "no se pudo crear autenticador PAM: %s" +msgid "private key file \"%s\" is not a regular file" +msgstr "el archivo de llave privada «%s» no es un archivo regular" -#: libpq/auth.c:2189 +#: libpq/be-secure-common.c:163 #, c-format -msgid "pam_set_item(PAM_USER) failed: %s" -msgstr "pam_set_item(PAM_USER) falló: %s" +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "el archivo de llave privada «%s» debe ser de propiedad del usuario de base de datos o root" -#: libpq/auth.c:2200 +#: libpq/be-secure-common.c:186 #, c-format -msgid "pam_set_item(PAM_RHOST) failed: %s" -msgstr "pam_set_item(PAM_RHOST) falló: %s" +msgid "private key file \"%s\" has group or world access" +msgstr "el archivo de la llave privada «%s» tiene acceso para el grupo u otros" -#: libpq/auth.c:2211 +#: libpq/be-secure-common.c:188 #, c-format -msgid "pam_set_item(PAM_CONV) failed: %s" -msgstr "pam_set_item(PAM_CONV) falló: %s" +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "El archivo debe tener permisos u=rw (0600) o menos si es de propiedad del usuario de base deatos, o permisos u=rw,g=r (0640) o menos si es de root." -#: libpq/auth.c:2222 +#: libpq/be-secure-gssapi.c:178 +msgid "GSSAPI wrap error" +msgstr "error de «wrap» de GSSAPI" + +#: libpq/be-secure-gssapi.c:182 libpq/be-secure-gssapi.c:349 #, c-format -msgid "pam_authenticate failed: %s" -msgstr "pam_authenticate falló: %s" +msgid "GSSAPI did not provide confidentiality" +msgstr "GSSAPI no proveyó confidencialidad" -#: libpq/auth.c:2233 +#: libpq/be-secure-gssapi.c:186 libpq/be-secure-gssapi.c:549 #, c-format -msgid "pam_acct_mgmt failed: %s" -msgstr "pam_acct_mgmt falló: %s" +msgid "server tried to send oversize GSSAPI packet: %zu bytes" +msgstr "el servidor intentó enviar un paquete GSSAPI demasiado grande: %zu bytes" -#: libpq/auth.c:2244 +#: libpq/be-secure-gssapi.c:303 libpq/be-secure-gssapi.c:501 #, c-format -msgid "could not release PAM authenticator: %s" -msgstr "no se pudo liberar autenticador PAM: %s" +msgid "oversize GSSAPI packet sent by the client: %zu bytes" +msgstr "paquete GSSAPI demasiado grande enviado por el cliente: %zu bytes" + +#: libpq/be-secure-gssapi.c:344 +msgid "GSSAPI unwrap error" +msgstr "error de «unwrap» de GSSAPI" -#: libpq/auth.c:2309 +#: libpq/be-secure-gssapi.c:522 +msgid "GSSAPI context error" +msgstr "error de contexto de GSSAPI" + +#: libpq/be-secure-gssapi.c:594 +msgid "GSSAPI size check error" +msgstr "error de verificación de tamaño GSSAPI" + +#: libpq/be-secure-openssl.c:111 #, c-format -msgid "could not initialize LDAP: %m" -msgstr "no se pudo inicializar LDAP: %m" +msgid "could not create SSL context: %s" +msgstr "no se pudo crear un contexto SSL: %s" -#: libpq/auth.c:2312 +#: libpq/be-secure-openssl.c:154 #, c-format -msgid "could not initialize LDAP: error code %d" -msgstr "no se pudo inicializar LDAP: código de error %d" +msgid "could not load server certificate file \"%s\": %s" +msgstr "no se pudo cargar el archivo de certificado de servidor «%s»: %s" -#: libpq/auth.c:2322 +#: libpq/be-secure-openssl.c:174 #, c-format -msgid "could not set LDAP protocol version: %s" -msgstr "no se pudo definir la versión de protocolo LDAP: %s" +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "el archivo de clave privada \"%s\" no se puede volver a cargar porque requiere una contraseña" -#: libpq/auth.c:2351 +#: libpq/be-secure-openssl.c:179 #, c-format -msgid "could not load wldap32.dll" -msgstr "no se pudo cargar wldap32.dll" +msgid "could not load private key file \"%s\": %s" +msgstr "no se pudo cargar el archivo de la llave privada «%s»: %s" -#: libpq/auth.c:2359 +#: libpq/be-secure-openssl.c:188 #, c-format -msgid "could not load function _ldap_start_tls_sA in wldap32.dll" -msgstr "no se pudo cargar la función _ldap_start_tls_sA en wldap32.dll" +msgid "check of private key failed: %s" +msgstr "falló la revisión de la llave privada: %s" -#: libpq/auth.c:2360 +#: libpq/be-secure-openssl.c:234 #, c-format -msgid "LDAP over SSL is not supported on this platform." -msgstr "LDAP sobre SSL no está soportado en esta plataforma." +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "no se pudo establecer la lista de cifrado (no hay cifradores disponibles)" -#: libpq/auth.c:2375 +#: libpq/be-secure-openssl.c:252 #, c-format -msgid "could not start LDAP TLS session: %s" -msgstr "no se pudo iniciar sesión de LDAP TLS: %s" +msgid "could not load root certificate file \"%s\": %s" +msgstr "no se pudo cargar el archivo del certificado raíz «%s»: %s" -#: libpq/auth.c:2397 +#: libpq/be-secure-openssl.c:279 #, c-format -msgid "LDAP server not specified" -msgstr "servidor LDAP no especificado" +msgid "SSL certificate revocation list file \"%s\" ignored" +msgstr "ignorando lista de revocación de certificados SSL «%s»" -#: libpq/auth.c:2450 +#: libpq/be-secure-openssl.c:281 #, c-format -msgid "invalid character in user name for LDAP authentication" -msgstr "carácter no válido en nombre de usuario para autentificación LDAP" +msgid "SSL library does not support certificate revocation lists." +msgstr "La libreria SSL no soporta listas de revocación de certificados." -#: libpq/auth.c:2465 +#: libpq/be-secure-openssl.c:288 #, c-format -msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" -msgstr "no se pudo hacer el enlace LDAP inicial para el ldapbinddb «%s» en el servidor «%s»: %s" +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "no se pudo cargar el archivo de lista de revocación de certificados SSL «%s»: %s" -#: libpq/auth.c:2489 +#: libpq/be-secure-openssl.c:363 #, c-format -msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" -msgstr "no se pudo hacer la búsqueda LDAP para el filtro «%s» en el servidor «%s»: %s" +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "no se pudo inicializar la conexión SSL: el contexto SSL no está instalado" -#: libpq/auth.c:2500 +#: libpq/be-secure-openssl.c:371 #, c-format -msgid "LDAP user \"%s\" does not exist" -msgstr "no existe el usuario LDAP «%s»" +msgid "could not initialize SSL connection: %s" +msgstr "no se pudo inicializar la conexión SSL: %s" -#: libpq/auth.c:2501 +#: libpq/be-secure-openssl.c:379 #, c-format -msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." -msgstr "La búsqueda LDAP para el filtro «%s» en el servidor «%s» no retornó elementos." +msgid "could not set SSL socket: %s" +msgstr "no se definir un socket SSL: %s" -#: libpq/auth.c:2505 +#: libpq/be-secure-openssl.c:434 #, c-format -msgid "LDAP user \"%s\" is not unique" -msgstr "el usuario LDAP «%s» no es única" +msgid "could not accept SSL connection: %m" +msgstr "no se pudo aceptar una conexión SSL: %m" -#: libpq/auth.c:2506 +#: libpq/be-secure-openssl.c:438 libpq/be-secure-openssl.c:449 #, c-format -msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." -msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." -msgstr[0] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elemento." -msgstr[1] "La búsqueda LDAP para el filtro «%s» en el servidor «%s» retornó %d elementos." +msgid "could not accept SSL connection: EOF detected" +msgstr "no se pudo aceptar una conexión SSL: se detectó EOF" -#: libpq/auth.c:2524 +#: libpq/be-secure-openssl.c:443 #, c-format -msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" -msgstr "no se pudo obtener el dn para la primera entrada que coincide con «%s» en el servidor «%s»: %s" +msgid "could not accept SSL connection: %s" +msgstr "no se pudo aceptar una conexión SSL: %s" -#: libpq/auth.c:2544 +#: libpq/be-secure-openssl.c:454 libpq/be-secure-openssl.c:585 +#: libpq/be-secure-openssl.c:649 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "no se pudo desconectar después de buscar al usuario «%s» en el servidor «%s»: %s" +msgid "unrecognized SSL error code: %d" +msgstr "código de error SSL no reconocido: %d" -#: libpq/auth.c:2574 +#: libpq/be-secure-openssl.c:496 #, c-format -msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" -msgstr "falló el inicio de sesión LDAP para el usuario «%s» en el servidor «%s»: %s" +msgid "SSL certificate's common name contains embedded null" +msgstr "el «common name» del certificado SSL contiene un carácter null" -#: libpq/auth.c:2602 +#: libpq/be-secure-openssl.c:574 libpq/be-secure-openssl.c:633 #, c-format -msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" -msgstr "la autentificación con certificado falló para el usuario «%s»: el certificado de cliente no contiene un nombre de usuario" +msgid "SSL error: %s" +msgstr "error de SSL: %s" -#: libpq/auth.c:2705 +#: libpq/be-secure-openssl.c:814 #, c-format -msgid "RADIUS server not specified" -msgstr "servidor RADIUS no especificado" +msgid "could not open DH parameters file \"%s\": %m" +msgstr "no se pudo abrir el archivo de parámetros DH «%s»: %m" -#: libpq/auth.c:2712 +#: libpq/be-secure-openssl.c:826 #, c-format -msgid "RADIUS secret not specified" -msgstr "secreto RADIUS no especificado" +msgid "could not load DH parameters file: %s" +msgstr "no se pudo cargar el archivo de parámetros DH: %s" -#: libpq/auth.c:2733 +#: libpq/be-secure-openssl.c:836 #, c-format -msgid "RADIUS authentication does not support passwords longer than %d characters" -msgstr "la autentificación RADIUS no soporta contraseñas más largas de %d caracteres" +msgid "invalid DH parameters: %s" +msgstr "parámetros DH no válidos: %s" -#: libpq/auth.c:2830 libpq/hba.c:1876 +#: libpq/be-secure-openssl.c:844 #, c-format -msgid "could not translate RADIUS server name \"%s\" to address: %s" -msgstr "no se pudo traducir el nombre de servidor RADIUS «%s» a dirección: %s" +msgid "invalid DH parameters: p is not prime" +msgstr "parámetros DH no válidos: p no es primo" -#: libpq/auth.c:2844 +#: libpq/be-secure-openssl.c:852 #, c-format -msgid "could not generate random encryption vector" -msgstr "no se pudo generar un vector aleatorio de encriptación" +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "parámetros DH no válidos: no hay generador apropiado o primo seguro" -#: libpq/auth.c:2878 +#: libpq/be-secure-openssl.c:1007 #, c-format -msgid "could not perform MD5 encryption of password" -msgstr "no se pudo efectuar cifrado MD5 de la contraseña" +msgid "DH: could not load DH parameters" +msgstr "DH: no se pudo cargar los parámetros DH" -#: libpq/auth.c:2904 +#: libpq/be-secure-openssl.c:1015 #, c-format -msgid "could not create RADIUS socket: %m" -msgstr "no se pudo crear el socket RADIUS: %m" +msgid "DH: could not set DH parameters: %s" +msgstr "DH: no se pudo definir los parámetros DH: %s" -#: libpq/auth.c:2926 +#: libpq/be-secure-openssl.c:1039 #, c-format -msgid "could not bind local RADIUS socket: %m" -msgstr "no se pudo enlazar el socket RADIUS local: %m" +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: nombre de curva no reconocida: %s" -#: libpq/auth.c:2936 +#: libpq/be-secure-openssl.c:1048 #, c-format -msgid "could not send RADIUS packet: %m" -msgstr "no se pudo enviar el paquete RADIUS: %m" +msgid "ECDH: could not create key" +msgstr "ECDH: no se pudo crear la llave" -#: libpq/auth.c:2969 libpq/auth.c:2995 -#, fuzzy, c-format -msgid "timeout waiting for RADIUS response from %s" -msgstr "se agotó el tiempo de espera de la respuesta RADIUS" +#: libpq/be-secure-openssl.c:1076 +msgid "no SSL error reported" +msgstr "código de error SSL no reportado" -#: libpq/auth.c:2988 +#: libpq/be-secure-openssl.c:1080 #, c-format -msgid "could not check status on RADIUS socket: %m" -msgstr "no se pudo verificar el estado en el socket %m" +msgid "SSL error code %lu" +msgstr "código de error SSL %lu" -#: libpq/auth.c:3018 +#: libpq/be-secure-openssl.c:1310 #, c-format -msgid "could not read RADIUS response: %m" -msgstr "no se pudo leer la respuesta RADIUS: %m" - -#: libpq/auth.c:3031 libpq/auth.c:3035 -#, fuzzy, c-format -msgid "RADIUS response from %s was sent from incorrect port: %d" -msgstr "la respuesta RADIUS fue enviada desde el port incorrecto: %d" +msgid "%s setting %s not supported by this build" +msgstr "el valor de %s %s no está soportado en esta instalación" -#: libpq/auth.c:3044 -#, fuzzy, c-format -msgid "RADIUS response from %s too short: %d" -msgstr "la respuesta RADIUS es demasiado corta: %d" +#: libpq/be-secure.c:123 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "conexión SSL desde «%s»" -#: libpq/auth.c:3051 -#, fuzzy, c-format -msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" -msgstr "la respuesta RADIUS tiene largo corrupto: %d (largo real %d)" +#: libpq/be-secure.c:208 libpq/be-secure.c:304 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "terminando la conexión debido al término inesperado de postmaster" -#: libpq/auth.c:3059 -#, fuzzy, c-format -msgid "RADIUS response from %s is to a different request: %d (should be %d)" -msgstr "la respuesta RADIUS es a una petición diferente: %d (debería ser %d)" +#: libpq/crypt.c:52 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "No existe el rol «%s»." -#: libpq/auth.c:3084 -#, c-format -msgid "could not perform MD5 encryption of received packet" -msgstr "no se pudo realizar cifrado MD5 del paquete recibido" - -#: libpq/auth.c:3093 -#, fuzzy, c-format -msgid "RADIUS response from %s has incorrect MD5 signature" -msgstr "la respuesta RADIUS tiene firma MD5 incorrecta" - -#: libpq/auth.c:3111 -#, fuzzy, c-format -msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" -msgstr "la respuesta RADIUS tiene código no válido (%d) para el usuario «%s»" - -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 -#: libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 -#: libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 -#, c-format -msgid "invalid large-object descriptor: %d" -msgstr "el descriptor de objeto grande no es válido: %d" - -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 -#: libpq/be-fsstubs.c:788 -#, c-format -msgid "permission denied for large object %u" -msgstr "permiso denegado al objeto grande %u" - -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 -#, c-format -msgid "large object descriptor %d was not opened for writing" -msgstr "el descriptor de objeto grande %d no fue abierto para escritura" - -#: libpq/be-fsstubs.c:245 -#, c-format -msgid "lo_lseek result out of range for large-object descriptor %d" -msgstr "el resultado de lo_lseek está fuera de rango para el descriptor de objeto grande %d" - -#: libpq/be-fsstubs.c:318 -#, c-format -msgid "lo_tell result out of range for large-object descriptor %d" -msgstr "el resultado de lo_tell está fuera de rango para el descriptor de objeto grande %d" - -#: libpq/be-fsstubs.c:455 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "debe ser superusuario para utilizar lo_import() en el extremo del servidor" - -#: libpq/be-fsstubs.c:456 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "Todos los usuarios pueden utilizar lo_import() de cliente proporcionada por libpq." - -#: libpq/be-fsstubs.c:469 -#, c-format -msgid "could not open server file \"%s\": %m" -msgstr "no se pudo abrir el archivo de servidor «%s»: %m" - -#: libpq/be-fsstubs.c:491 -#, c-format -msgid "could not read server file \"%s\": %m" -msgstr "no se pudo leer el archivo de servidor «%s»: %m" - -#: libpq/be-fsstubs.c:521 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "debe ser superusuario para utilizar lo_export() en el extremo del servidor" - -#: libpq/be-fsstubs.c:522 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "Todos los usuarios pueden utilizar lo_export() de cliente proporcionada por libpq." - -#: libpq/be-fsstubs.c:547 -#, c-format -msgid "could not create server file \"%s\": %m" -msgstr "no se pudo crear el archivo del servidor «%s»: %m" - -#: libpq/be-fsstubs.c:559 -#, c-format -msgid "could not write server file \"%s\": %m" -msgstr "no se pudo escribir el archivo del servidor «%s»: %m" - -#: libpq/be-fsstubs.c:813 -#, c-format -msgid "large object read request is too large" -msgstr "el tamaño de petición de lectura de objeto grande es muy grande" - -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:212 utils/adt/genfile.c:253 -#, c-format -msgid "requested length cannot be negative" -msgstr "el tamaño solicitado no puede ser negativo" - -#: libpq/be-secure-openssl.c:197 -#, c-format -msgid "could not create SSL context: %s" -msgstr "no se pudo crear un contexto SSL: %s" - -#: libpq/be-secure-openssl.c:225 -#, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "no se pudo cargar el archivo de certificado de servidor «%s»: %s" - -#: libpq/be-secure-openssl.c:234 -#, c-format -msgid "could not access private key file \"%s\": %m" -msgstr "no se pudo acceder al archivo de la llave privada «%s»: %m" - -#: libpq/be-secure-openssl.c:243 -#, c-format -msgid "private key file \"%s\" is not a regular file" -msgstr "el archivo de llave privada «%s» no es un archivo regular" - -#: libpq/be-secure-openssl.c:258 -#, c-format -msgid "private key file \"%s\" must be owned by the database user or root" -msgstr "el archivo de llave privada «%s» debe ser de propiedad del usuario de base de datos o root" - -#: libpq/be-secure-openssl.c:281 -#, c-format -msgid "private key file \"%s\" has group or world access" -msgstr "el archivo de la llave privada «%s» tiene acceso para el grupo u otros" - -#: libpq/be-secure-openssl.c:283 -#, c-format -msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." -msgstr "El archivo debe tener permisos u=rw (0600) o menos si es de propiedad del usuario de base deatos, o permisos u=rw,g=r (0640) o menos si es de root." - -#: libpq/be-secure-openssl.c:300 -#, c-format -msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" -msgstr "" - -#: libpq/be-secure-openssl.c:305 -#, c-format -msgid "could not load private key file \"%s\": %s" -msgstr "no se pudo cargar el archivo de la llave privada «%s»: %s" - -#: libpq/be-secure-openssl.c:314 -#, c-format -msgid "check of private key failed: %s" -msgstr "falló la revisión de la llave privada: %s" - -#: libpq/be-secure-openssl.c:334 -#, c-format -msgid "could not set the cipher list (no valid ciphers available)" -msgstr "" - -#: libpq/be-secure-openssl.c:352 -#, c-format -msgid "could not load root certificate file \"%s\": %s" -msgstr "no se pudo cargar el archivo del certificado raíz «%s»: %s" - -#: libpq/be-secure-openssl.c:379 -#, c-format -msgid "SSL certificate revocation list file \"%s\" ignored" -msgstr "ignorando lista de revocación de certificados SSL «%s»" - -#: libpq/be-secure-openssl.c:381 -#, c-format -msgid "SSL library does not support certificate revocation lists." -msgstr "La libreria SSL no soporta listas de revocación de certificados." - -#: libpq/be-secure-openssl.c:388 -#, c-format -msgid "could not load SSL certificate revocation list file \"%s\": %s" -msgstr "no se pudo cargar el archivo de lista de revocación de certificados SSL «%s»: %s" - -#: libpq/be-secure-openssl.c:469 -#, fuzzy, c-format -msgid "could not initialize SSL connection: SSL context not set up" -msgstr "no se pudo inicializar la conexión SSL: %s" - -#: libpq/be-secure-openssl.c:477 -#, c-format -msgid "could not initialize SSL connection: %s" -msgstr "no se pudo inicializar la conexión SSL: %s" - -#: libpq/be-secure-openssl.c:485 -#, c-format -msgid "could not set SSL socket: %s" -msgstr "no se definir un socket SSL: %s" - -#: libpq/be-secure-openssl.c:540 -#, c-format -msgid "could not accept SSL connection: %m" -msgstr "no se pudo aceptar una conexión SSL: %m" - -#: libpq/be-secure-openssl.c:544 libpq/be-secure-openssl.c:555 -#, c-format -msgid "could not accept SSL connection: EOF detected" -msgstr "no se pudo aceptar una conexión SSL: se detectó EOF" - -#: libpq/be-secure-openssl.c:549 -#, c-format -msgid "could not accept SSL connection: %s" -msgstr "no se pudo aceptar una conexión SSL: %s" - -#: libpq/be-secure-openssl.c:560 libpq/be-secure-openssl.c:701 -#: libpq/be-secure-openssl.c:767 -#, c-format -msgid "unrecognized SSL error code: %d" -msgstr "código de error SSL no reconocido: %d" - -#: libpq/be-secure-openssl.c:602 -#, c-format -msgid "SSL certificate's common name contains embedded null" -msgstr "el «common name» del certificado SSL contiene un carácter null" - -#: libpq/be-secure-openssl.c:613 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "conexión SSL desde «%s»" - -#: libpq/be-secure-openssl.c:690 libpq/be-secure-openssl.c:752 -#, c-format -msgid "SSL error: %s" -msgstr "error de SSL: %s" - -#: libpq/be-secure-openssl.c:1187 -#, c-format -msgid "ECDH: unrecognized curve name: %s" -msgstr "ECDH: nombre de curva no reconocida: %s" - -#: libpq/be-secure-openssl.c:1196 -#, c-format -msgid "ECDH: could not create key" -msgstr "ECDH: no se pudo crear la llave" - -#: libpq/be-secure-openssl.c:1224 -msgid "no SSL error reported" -msgstr "código de error SSL no reportado" - -#: libpq/be-secure-openssl.c:1228 -#, c-format -msgid "SSL error code %lu" -msgstr "código de error SSL %lu" - -#: libpq/be-secure.c:188 libpq/be-secure.c:274 -#, c-format -msgid "terminating connection due to unexpected postmaster exit" -msgstr "terminando la conexión debido al término inesperado de postmaster" - -#: libpq/crypt.c:51 -#, c-format -msgid "Role \"%s\" does not exist." -msgstr "No existe el rol «%s»." - -#: libpq/crypt.c:61 +#: libpq/crypt.c:62 #, c-format msgid "User \"%s\" has no password assigned." msgstr "El usuario «%s» no tiene una contraseña asignada." -#: libpq/crypt.c:76 -#, c-format -msgid "User \"%s\" has an empty password." -msgstr "El usuario «%s» tiene contraseña vacía." - -#: libpq/crypt.c:87 +#: libpq/crypt.c:80 #, c-format msgid "User \"%s\" has an expired password." msgstr "El usuario «%s» tiene contraseña expirada." -#: libpq/crypt.c:181 +#: libpq/crypt.c:182 #, c-format msgid "User \"%s\" has a password that cannot be used with MD5 authentication." -msgstr "" +msgstr "El usuario \"%s\" tiene una contraseña que no se puede usar con la autentificación MD5." -#: libpq/crypt.c:205 libpq/crypt.c:246 libpq/crypt.c:270 +#: libpq/crypt.c:206 libpq/crypt.c:247 libpq/crypt.c:271 #, c-format msgid "Password does not match for user \"%s\"." msgstr "La contraseña no coincide para el usuario «%s»." -#: libpq/crypt.c:289 +#: libpq/crypt.c:290 #, c-format msgid "Password of user \"%s\" is in unrecognized format." -msgstr "" +msgstr "La contraseña del usuario \"%s\" está en un formato no reconocido." #: libpq/hba.c:235 #, c-format msgid "authentication file token too long, skipping: \"%s\"" -msgstr "una palabra en el archivo de autentificación es demasiado larga, ignorando: «%s»" +msgstr "una palabra en el archivo de autentificación es demasiado larga, omitiendo: «%s»" #: libpq/hba.c:407 #, c-format @@ -12669,17 +12918,18 @@ msgid "authentication file line too long" msgstr "línea en el archivo de autentificación demasiado larga" #: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 -#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 -#: libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 -#: libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 -#: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 -#: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 -#: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 -#: libpq/hba.c:1482 libpq/hba.c:1521 libpq/hba.c:1532 libpq/hba.c:1549 -#: libpq/hba.c:1559 libpq/hba.c:1617 libpq/hba.c:1655 libpq/hba.c:1671 -#: libpq/hba.c:1770 libpq/hba.c:1859 libpq/hba.c:1878 libpq/hba.c:1907 -#: libpq/hba.c:1920 libpq/hba.c:1943 libpq/hba.c:1965 libpq/hba.c:1979 -#: tsearch/ts_locale.c:182 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 +#: libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 +#: libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 +#: libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 libpq/hba.c:1430 +#: libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 +#: libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 +#: libpq/hba.c:1666 libpq/hba.c:1704 libpq/hba.c:1726 libpq/hba.c:1738 +#: libpq/hba.c:1825 libpq/hba.c:1843 libpq/hba.c:1937 libpq/hba.c:1956 +#: libpq/hba.c:1985 libpq/hba.c:1998 libpq/hba.c:2021 libpq/hba.c:2043 +#: libpq/hba.c:2057 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "línea %d del archivo de configuración «%s»" @@ -12720,274 +12970,304 @@ msgstr "Especifique exactamente un tipo de conexión por línea." msgid "local connections are not supported by this build" msgstr "las conexiones locales no están soportadas en este servidor" -#: libpq/hba.c:1009 +#: libpq/hba.c:1011 #, c-format msgid "hostssl record cannot match because SSL is disabled" -msgstr "" +msgstr "el registro hostssl no puede coincidir porque SSL está deshabilitado" -#: libpq/hba.c:1010 +#: libpq/hba.c:1012 #, c-format msgid "Set ssl = on in postgresql.conf." msgstr "Defina «ssl = on» en postgresql.conf." -#: libpq/hba.c:1018 -#, fuzzy, c-format +#: libpq/hba.c:1020 +#, c-format msgid "hostssl record cannot match because SSL is not supported by this build" -msgstr "hostssl no está soportado en este servidor" +msgstr "el registro hostssl no puede coincidir porque SSL no está soportado en esta instalación" -#: libpq/hba.c:1019 +#: libpq/hba.c:1021 #, c-format msgid "Compile with --with-openssl to use SSL connections." msgstr "Compile con --with-openssl para usar conexiones SSL." -#: libpq/hba.c:1039 +#: libpq/hba.c:1033 +#, c-format +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "el registro hostgssenc no puede coincidir porque GSSAPI no está soportado en esta instalación" + +#: libpq/hba.c:1034 +#, c-format +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "Compile con --with-gssapi para usar conexiones GSSAPI." + +#: libpq/hba.c:1054 #, c-format msgid "invalid connection type \"%s\"" msgstr "tipo de conexión «%s» no válido" -#: libpq/hba.c:1053 +#: libpq/hba.c:1068 #, c-format msgid "end-of-line before database specification" msgstr "fin de línea antes de especificación de base de datos" -#: libpq/hba.c:1073 +#: libpq/hba.c:1088 #, c-format msgid "end-of-line before role specification" msgstr "fin de línea antes de especificación de rol" -#: libpq/hba.c:1095 +#: libpq/hba.c:1110 #, c-format msgid "end-of-line before IP address specification" msgstr "fin de línea antes de especificación de dirección IP" -#: libpq/hba.c:1106 +#: libpq/hba.c:1121 #, c-format msgid "multiple values specified for host address" msgstr "múltiples valores especificados para la dirección de anfitrión" -#: libpq/hba.c:1107 +#: libpq/hba.c:1122 #, c-format msgid "Specify one address range per line." msgstr "Especifique un rango de direcciones por línea." -#: libpq/hba.c:1162 +#: libpq/hba.c:1177 #, c-format msgid "invalid IP address \"%s\": %s" msgstr "dirección IP «%s» no válida: %s" -#: libpq/hba.c:1182 +#: libpq/hba.c:1197 #, c-format msgid "specifying both host name and CIDR mask is invalid: \"%s\"" msgstr "especificar tanto el nombre de host como la máscara CIDR no es válido: «%s»" -#: libpq/hba.c:1196 +#: libpq/hba.c:1211 #, c-format msgid "invalid CIDR mask in address \"%s\"" msgstr "máscara CIDR no válida en dirección «%s»" -#: libpq/hba.c:1215 +#: libpq/hba.c:1230 #, c-format msgid "end-of-line before netmask specification" msgstr "fin de línea antes de especificación de máscara de red" -#: libpq/hba.c:1216 +#: libpq/hba.c:1231 #, c-format msgid "Specify an address range in CIDR notation, or provide a separate netmask." msgstr "Especifique un rango de direcciones en notación CIDR, o provea una netmask separadamente." -#: libpq/hba.c:1227 +#: libpq/hba.c:1242 #, c-format msgid "multiple values specified for netmask" msgstr "múltiples valores especificados para la máscara de red" -#: libpq/hba.c:1241 +#: libpq/hba.c:1256 #, c-format msgid "invalid IP mask \"%s\": %s" msgstr "máscara IP «%s» no válida: %s" -#: libpq/hba.c:1260 +#: libpq/hba.c:1275 #, c-format msgid "IP address and mask do not match" msgstr "La dirección y máscara IP no coinciden" -#: libpq/hba.c:1276 +#: libpq/hba.c:1291 #, c-format msgid "end-of-line before authentication method" msgstr "fin de línea antes de especificación de método de autentificación" -#: libpq/hba.c:1287 +#: libpq/hba.c:1302 #, c-format msgid "multiple values specified for authentication type" msgstr "múltiples valores especificados para el tipo de autentificación" -#: libpq/hba.c:1288 +#: libpq/hba.c:1303 #, c-format msgid "Specify exactly one authentication type per line." msgstr "Especifique exactamente un tipo de autentificación por línea." -#: libpq/hba.c:1365 +#: libpq/hba.c:1380 #, c-format msgid "invalid authentication method \"%s\"" msgstr "método de autentificación «%s» no válido" -#: libpq/hba.c:1378 +#: libpq/hba.c:1393 #, c-format msgid "invalid authentication method \"%s\": not supported by this build" msgstr "método de autentificación «%s» no válido: este servidor no lo soporta" -#: libpq/hba.c:1401 +#: libpq/hba.c:1416 #, c-format msgid "gssapi authentication is not supported on local sockets" msgstr "la autentificación gssapi no está soportada en conexiones locales" -#: libpq/hba.c:1413 +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "El cifrado GSSAPI sólo soporta autentificación gss, trust o reject" + +#: libpq/hba.c:1441 #, c-format msgid "peer authentication is only supported on local sockets" msgstr "la autentificación peer sólo está soportada en conexiones locales" -#: libpq/hba.c:1431 +#: libpq/hba.c:1459 #, c-format msgid "cert authentication is only supported on hostssl connections" msgstr "la autentificación cert sólo está soportada en conexiones hostssl" -#: libpq/hba.c:1481 +#: libpq/hba.c:1509 #, c-format msgid "authentication option not in name=value format: %s" msgstr "opción de autentificación en formato nombre=valor: %s" -#: libpq/hba.c:1520 +#: libpq/hba.c:1553 #, c-format -msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix" -msgstr "no se puede usar ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute o ldapurl junto con ldapprefix" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "no se puede usar ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter o ldapurl junto con ldapprefix" -#: libpq/hba.c:1531 +#: libpq/hba.c:1564 #, c-format msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "el método de autentificación «ldap» requiere que los argumento «ldapbasedn», «ldapprefix» o «ldapsuffix» estén definidos" -#: libpq/hba.c:1548 -#, fuzzy, c-format +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "no se puede usar ldapsearchattribute junto con ldapsearchfilter" + +#: libpq/hba.c:1597 +#, c-format msgid "list of RADIUS servers cannot be empty" -msgstr "servidor RADIUS no especificado" +msgstr "la lista de servidores RADIUS no puede ser vacía" -#: libpq/hba.c:1558 -#, fuzzy, c-format +#: libpq/hba.c:1607 +#, c-format msgid "list of RADIUS secrets cannot be empty" -msgstr "secreto RADIUS no especificado" +msgstr "la lista de secretos RADIUS no puede ser vacía" -#: libpq/hba.c:1611 +#: libpq/hba.c:1660 #, c-format -msgid "the number of %s (%i) must be 1 or the same as the number of %s (%i)" -msgstr "" +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "el número de %s (%d) debe ser 1 o igual al número de %s (%d)" -#: libpq/hba.c:1645 +#: libpq/hba.c:1694 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspi y cert" -#: libpq/hba.c:1654 +#: libpq/hba.c:1703 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "clientcert sólo puede ser configurado en líneas «hostssl»" -#: libpq/hba.c:1670 +#: libpq/hba.c:1725 #, c-format -msgid "clientcert can not be set to 0 when using \"cert\" authentication" -msgstr "clientcert no puede establecerse en 0 cuando se emplea autentificación «cert»" +msgid "clientcert can not be set to \"no-verify\" when using \"cert\" authentication" +msgstr "clientcert no puede establecerse a «no-verify» cuando se emplea autentificación «cert»" -#: libpq/hba.c:1707 +#: libpq/hba.c:1737 +#, c-format +msgid "invalid value for clientcert: \"%s\"" +msgstr "valor no válido para el parámetro clientcert: «%s»" + +#: libpq/hba.c:1771 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "no se pudo interpretar la URL LDAP «%s»: %s" -#: libpq/hba.c:1717 +#: libpq/hba.c:1782 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "esquema de URL LDAP no soportado: %s" -#: libpq/hba.c:1735 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "los filtros no están soportados en URLs LDAP" - -#: libpq/hba.c:1744 +#: libpq/hba.c:1806 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "las URLs LDAP no está soportado en esta plataforma" -#: libpq/hba.c:1769 +#: libpq/hba.c:1824 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "valor ldapscheme no válido: «%s»" + +#: libpq/hba.c:1842 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "número de puerto LDAP no válido: «%s»" -#: libpq/hba.c:1810 libpq/hba.c:1817 +#: libpq/hba.c:1888 libpq/hba.c:1895 msgid "gssapi and sspi" msgstr "gssapi y sspi" -#: libpq/hba.c:1826 libpq/hba.c:1835 +#: libpq/hba.c:1904 libpq/hba.c:1913 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1857 -#, fuzzy, c-format +#: libpq/hba.c:1935 +#, c-format msgid "could not parse RADIUS server list \"%s\"" -msgstr "no se pudo abrir el archivo de servidor «%s»: %m" +msgstr "no se pudo interpretar la lista de servidores RADIUS «%s»" -#: libpq/hba.c:1905 -#, fuzzy, c-format +#: libpq/hba.c:1983 +#, c-format msgid "could not parse RADIUS port list \"%s\"" -msgstr "no se pudo leer la respuesta RADIUS: %m" +msgstr "no se pudo interpretar la lista de port RADIUS «%s»" -#: libpq/hba.c:1919 +#: libpq/hba.c:1997 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "número de puerto RADIUS no válido: «%s»" -#: libpq/hba.c:1941 -#, fuzzy, c-format +#: libpq/hba.c:2019 +#, c-format msgid "could not parse RADIUS secret list \"%s\"" -msgstr "no se pudo crear el socket RADIUS: %m" +msgstr "no se pudo interpretar la lista de secretos RADIUS «%s»" -#: libpq/hba.c:1963 -#, fuzzy, c-format +#: libpq/hba.c:2041 +#, c-format msgid "could not parse RADIUS identifiers list \"%s\"" -msgstr "no se pudo interpretar el nombre de archivo «%s»" +msgstr "no se pudo interpretar la lista de identificadoes RADIUS «%s»" -#: libpq/hba.c:1977 +#: libpq/hba.c:2055 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "nombre de opción de autentificación desconocido: «%s»" -#: libpq/hba.c:2161 +#: libpq/hba.c:2199 libpq/hba.c:2613 guc-file.l:596 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "no se pudo abrir el archivo de configuración «%s»: %m" + +#: libpq/hba.c:2250 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "el archivo de configuración «%s» no contiene líneas" -#: libpq/hba.c:2666 +#: libpq/hba.c:2769 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "la expresión regular «%s» no es válida: %s" -#: libpq/hba.c:2726 +#: libpq/hba.c:2829 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "la coincidencia de expresión regular para «%s» falló: %s" -#: libpq/hba.c:2745 +#: libpq/hba.c:2848 #, c-format msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" msgstr "la expresión regular «%s» no tiene subexpresiones según lo requiere la referencia hacia atrás en «%s»" -#: libpq/hba.c:2842 +#: libpq/hba.c:2945 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "el nombre de usuario entregado (%s) y el nombre de usuario autentificado (%s) no coinciden" -#: libpq/hba.c:2862 +#: libpq/hba.c:2965 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "no hay coincidencia en el mapa «%s» para el usuario «%s» autentificado como «%s»" -#: libpq/hba.c:2895 +#: libpq/hba.c:2998 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "no se pudo abrir el archivo de mapa de usuarios «%s»: %m" @@ -13032,31 +13312,31 @@ msgstr "Unix" #: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" -msgstr "la familia de direcciones %d no es reconocida" +msgstr "la familia de direcciones %d no reconocida" #. translator: first %s is IPv4, IPv6, or Unix #: libpq/pqcomm.c:475 -#, fuzzy, c-format +#, c-format msgid "could not create %s socket for address \"%s\": %m" -msgstr "no se pudo crear el socket de escucha para «%s»" +msgstr "no se pudo crear el socket %s de escucha para la dirección «%s»: %m" #. translator: first %s is IPv4, IPv6, or Unix #: libpq/pqcomm.c:501 -#, fuzzy, c-format +#, c-format msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" -msgstr "setsockopt(SO_REUSEADDR) falló: %m" +msgstr "setsockopt(SO_REUSEADDR) falló para la dirección %s «%s»: %m" #. translator: first %s is IPv4, IPv6, or Unix #: libpq/pqcomm.c:518 -#, fuzzy, c-format +#, c-format msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" -msgstr "setsockopt(IPV6_V6ONLY) falló: %m" +msgstr "setsockopt(IPV6_V6ONLY) falló para la dirección %s «%s»: %m" #. translator: first %s is IPv4, IPv6, or Unix #: libpq/pqcomm.c:538 -#, fuzzy, c-format +#, c-format msgid "could not bind %s address \"%s\": %m" -msgstr "no se pudo enlazar a la dirección local «%s»: %m" +msgstr "no se pudo enlazar a la dirección %s «%s»: %m" #: libpq/pqcomm.c:541 #, c-format @@ -13070,20 +13350,20 @@ msgstr "¿Hay otro postmaster corriendo en el puerto %d? Si no, aguarde unos seg #. translator: first %s is IPv4, IPv6, or Unix #: libpq/pqcomm.c:577 -#, fuzzy, c-format +#, c-format msgid "could not listen on %s address \"%s\": %m" -msgstr "no se pudo enlazar a la dirección local «%s»: %m" +msgstr "no se pudo escuchar en la dirección %s «%s»: %m" #: libpq/pqcomm.c:586 -#, fuzzy, c-format +#, c-format msgid "listening on Unix socket \"%s\"" -msgstr "no se pudo escuchar en el socket %s: %m" +msgstr "escuchando en el socket Unix «%s»" #. translator: first %s is IPv4 or IPv6 #: libpq/pqcomm.c:592 -#, fuzzy, c-format +#, c-format msgid "listening on %s address \"%s\", port %d" -msgstr "no se pudo conectar al servidor Ident «%s», port %s: %m" +msgstr "escuchando en la dirección %s «%s», port %d" #: libpq/pqcomm.c:675 #, c-format @@ -13105,58 +13385,58 @@ msgstr "no se pudo definir los permisos del archivo «%s»: %m" msgid "could not accept new connection: %m" msgstr "no se pudo aceptar una nueva conexión: %m" -#: libpq/pqcomm.c:927 +#: libpq/pqcomm.c:928 #, c-format msgid "there is no client connection" msgstr "no hay conexión de cliente" -#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 +#: libpq/pqcomm.c:979 libpq/pqcomm.c:1075 #, c-format msgid "could not receive data from client: %m" msgstr "no se pudo recibir datos del cliente: %m" -#: libpq/pqcomm.c:1219 tcop/postgres.c:3928 +#: libpq/pqcomm.c:1220 tcop/postgres.c:4087 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "terminando la conexión por pérdida de sincronía del protocolo" -#: libpq/pqcomm.c:1285 +#: libpq/pqcomm.c:1286 #, c-format msgid "unexpected EOF within message length word" msgstr "EOF inesperado dentro de la palabra de tamaño del mensaje" -#: libpq/pqcomm.c:1296 +#: libpq/pqcomm.c:1297 #, c-format msgid "invalid message length" msgstr "el largo de mensaje no es válido" -#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 +#: libpq/pqcomm.c:1319 libpq/pqcomm.c:1332 #, c-format msgid "incomplete message from client" msgstr "mensaje incompleto del cliente" -#: libpq/pqcomm.c:1464 +#: libpq/pqcomm.c:1465 #, c-format msgid "could not send data to client: %m" msgstr "no se pudo enviar datos al cliente: %m" -#: libpq/pqformat.c:437 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "no hay datos restantes en el mensaje" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:567 #, c-format msgid "insufficient data left in message" msgstr "los datos restantes del mensaje son insuficientes" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "cadena inválida en el mensaje" -#: libpq/pqformat.c:682 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "formato de mensaje no válido" @@ -13410,14 +13690,14 @@ msgid "" "configuration settings and how to set them on the command line or in\n" "the configuration file.\n" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" "Por favor lea la documentación para obtener la lista completa de\n" "parámetros de configuración y cómo definirlos en la línea de órdenes\n" "y en el archivo de configuración.\n" "\n" -"Reporte errores a \n" +"Reporte errores a \n" #: main/main.c:391 #, c-format @@ -13463,911 +13743,991 @@ msgstr "el tipo de nodo extensible «%s» ya existe" msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "ExtensibleNodeMethods «%s» no fue registrado" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1844 -#: parser/parse_coerce.c:1872 parser/parse_coerce.c:1948 -#: parser/parse_expr.c:2110 parser/parse_func.c:602 parser/parse_oper.c:964 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2201 parser/parse_func.c:705 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "no se pudo encontrar un tipo de array para el tipo de dato %s" -#: optimizer/path/joinrels.c:826 +#: optimizer/path/joinrels.c:833 #, c-format msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "FULL JOIN sólo está soportado con condiciones que se pueden usar con merge join o hash join" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1200 +#: optimizer/plan/initsplan.c:1195 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s no puede ser aplicado al lado nulable de un outer join" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1544 parser/analyze.c:1624 parser/analyze.c:1821 -#: parser/analyze.c:2615 +#: optimizer/plan/planner.c:1912 parser/analyze.c:1644 parser/analyze.c:1842 +#: parser/analyze.c:2700 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s no está permitido con UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:2144 optimizer/plan/planner.c:4102 +#: optimizer/plan/planner.c:2498 optimizer/plan/planner.c:4152 #, c-format msgid "could not implement GROUP BY" msgstr "no se pudo implementar GROUP BY" -#: optimizer/plan/planner.c:2145 optimizer/plan/planner.c:4103 -#: optimizer/plan/planner.c:4843 optimizer/prep/prepunion.c:938 +#: optimizer/plan/planner.c:2499 optimizer/plan/planner.c:4153 +#: optimizer/plan/planner.c:4891 optimizer/prep/prepunion.c:1042 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "Algunos de los tipos sólo soportan hashing, mientras que otros sólo soportan ordenamiento." -#: optimizer/plan/planner.c:4842 +#: optimizer/plan/planner.c:4890 #, c-format msgid "could not implement DISTINCT" msgstr "no se pudo implementar DISTINCT" -#: optimizer/plan/planner.c:5522 +#: optimizer/plan/planner.c:5625 #, c-format msgid "could not implement window PARTITION BY" msgstr "No se pudo implementar PARTITION BY de ventana" -#: optimizer/plan/planner.c:5523 +#: optimizer/plan/planner.c:5626 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Las columnas de particionamiento de ventana deben de tipos que se puedan ordenar." -#: optimizer/plan/planner.c:5527 +#: optimizer/plan/planner.c:5630 #, c-format msgid "could not implement window ORDER BY" msgstr "no se pudo implementar ORDER BY de ventana" -#: optimizer/plan/planner.c:5528 +#: optimizer/plan/planner.c:5631 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Las columnas de ordenamiento de ventana debe ser de tipos que se puedan ordenar." -#: optimizer/plan/setrefs.c:413 +#: optimizer/plan/setrefs.c:424 #, c-format msgid "too many range table entries" msgstr "demasiadas «range table entries»" -#: optimizer/prep/prepunion.c:493 +#: optimizer/prep/prepunion.c:505 #, c-format msgid "could not implement recursive UNION" msgstr "no se pudo implementar UNION recursivo" -#: optimizer/prep/prepunion.c:494 +#: optimizer/prep/prepunion.c:506 #, c-format msgid "All column datatypes must be hashable." msgstr "Todos los tipos de dato de las columnas deben ser tipos de los que se puedan hacer un hash." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:937 +#: optimizer/prep/prepunion.c:1041 #, c-format msgid "could not implement %s" msgstr "no se pudo implementar %s" -#: optimizer/util/clauses.c:4668 +#: optimizer/util/clauses.c:4781 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "función SQL «%s», durante expansión en línea" -#: optimizer/util/plancat.c:120 +#: optimizer/util/plancat.c:130 #, c-format msgid "cannot access temporary or unlogged relations during recovery" -msgstr "no se pueden crear tablas temporales o unlogged durante la recuperación" +msgstr "no se puede acceder a tablas temporales o «unlogged» durante la recuperación" -#: optimizer/util/plancat.c:620 +#: optimizer/util/plancat.c:650 #, c-format msgid "whole row unique index inference specifications are not supported" msgstr "no están soportadas las especificaciones de inferencia de índice único de registro completo" -#: optimizer/util/plancat.c:637 +#: optimizer/util/plancat.c:667 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "la restricción en la cláusula ON CONFLICT no tiene un índice asociado" -#: optimizer/util/plancat.c:688 +#: optimizer/util/plancat.c:717 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" msgstr "ON CONFLICT DO UPDATE no está soportado con restricciones de exclusión" -#: optimizer/util/plancat.c:793 +#: optimizer/util/plancat.c:822 #, c-format msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "no hay restricción única o de exclusión que coincida con la especificación ON CONFLICT" -#: parser/analyze.c:700 parser/analyze.c:1387 +#: parser/analyze.c:711 parser/analyze.c:1407 #, c-format msgid "VALUES lists must all be the same length" msgstr "las listas VALUES deben ser todas de la misma longitud" -#: parser/analyze.c:855 -#, fuzzy, c-format -msgid "ON CONFLICT clause is not supported with partitioned tables" -msgstr "ON CONFLICT no está soportado con tablas que son catálogos de sistema" - -#: parser/analyze.c:918 +#: parser/analyze.c:914 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT tiene más expresiones que columnas de destino" -#: parser/analyze.c:936 +#: parser/analyze.c:932 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT tiene más columnas de destino que expresiones" -#: parser/analyze.c:940 +#: parser/analyze.c:936 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "La fuente de inserción es una expresión de fila que contiene la misma cantidad de columnas que esperaba el INSERT. ¿Usó accidentalmente paréntesis extra?" -#: parser/analyze.c:1200 parser/analyze.c:1597 +#: parser/analyze.c:1218 parser/analyze.c:1617 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO no está permitido aquí" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1529 parser/analyze.c:2794 +#: parser/analyze.c:1549 parser/analyze.c:2879 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s no puede ser aplicado a VALUES" -#: parser/analyze.c:1748 +#: parser/analyze.c:1767 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "cláusula UNION/INTERSECT/EXCEPT ORDER BY no válida" -#: parser/analyze.c:1749 +#: parser/analyze.c:1768 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "Sólo nombres de columna del resultado pueden usarse, no expresiones o funciones." -#: parser/analyze.c:1750 +#: parser/analyze.c:1769 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Agregue la función o expresión a todos los SELECT, o mueva el UNION dentro de una cláusula FROM." -#: parser/analyze.c:1811 +#: parser/analyze.c:1832 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "sólo se permite INTO en el primer SELECT de UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:1883 +#: parser/analyze.c:1904 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "una sentencia miembro de UNION/INSERT/EXCEPT no puede referirse a otras relaciones del mismo nivel de la consulta" -#: parser/analyze.c:1972 +#: parser/analyze.c:1993 #, c-format msgid "each %s query must have the same number of columns" msgstr "cada consulta %s debe tener el mismo número de columnas" -#: parser/analyze.c:2365 +#: parser/analyze.c:2411 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING debe tener al menos una columna" -#: parser/analyze.c:2406 +#: parser/analyze.c:2452 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "no se puede especificar SCROLL y NO SCROLL" -#: parser/analyze.c:2425 +#: parser/analyze.c:2471 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR no debe contener sentencias que modifiquen datos en WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2433 +#: parser/analyze.c:2479 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s no está soportado" -#: parser/analyze.c:2436 +#: parser/analyze.c:2482 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "Los cursores declarados HOLD deben ser READ ONLY." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2444 +#: parser/analyze.c:2490 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s no está soportado" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2455 +#: parser/analyze.c:2501 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %s no está soportado" -#: parser/analyze.c:2458 +#: parser/analyze.c:2504 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "Los cursores insensitivos deben ser READ ONLY." -#: parser/analyze.c:2524 +#: parser/analyze.c:2570 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "las vistas materializadas no deben usar sentencias que modifiquen datos en WITH" -#: parser/analyze.c:2534 +#: parser/analyze.c:2580 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "las vistas materializadas no deben usar tablas temporales o vistas" -#: parser/analyze.c:2544 +#: parser/analyze.c:2590 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "las vistas materializadas no pueden definirse usando parámetros enlazados" -#: parser/analyze.c:2556 +#: parser/analyze.c:2602 #, c-format -msgid "materialized views cannot be UNLOGGED" -msgstr "las vistas materializadas no pueden ser UNLOGGED" +msgid "materialized views cannot be unlogged" +msgstr "las vistas materializadas no pueden ser «unlogged»" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2622 +#: parser/analyze.c:2707 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s no está permitido con cláusulas DISTINCT" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2629 +#: parser/analyze.c:2714 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s no está permitido con cláusulas GROUP BY" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2636 +#: parser/analyze.c:2721 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s no está permitido con cláusulas HAVING" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2643 +#: parser/analyze.c:2728 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s no está permitido con funciones de agregación" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2650 +#: parser/analyze.c:2735 #, c-format msgid "%s is not allowed with window functions" msgstr "%s no está permitido con funciones de ventana deslizante" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2657 +#: parser/analyze.c:2742 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s no está permitido con funciones que retornan conjuntos en la lista de resultados" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2736 +#: parser/analyze.c:2821 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s debe especificar nombres de relaciones sin calificar" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2767 +#: parser/analyze.c:2852 #, c-format msgid "%s cannot be applied to a join" msgstr "%s no puede ser aplicado a un join" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2776 +#: parser/analyze.c:2861 #, c-format msgid "%s cannot be applied to a function" msgstr "%s no puede ser aplicado a una función" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2785 -#, fuzzy, c-format +#: parser/analyze.c:2870 +#, c-format msgid "%s cannot be applied to a table function" -msgstr "%s no puede ser aplicado a una función" +msgstr "%s no puede ser aplicado a una función de tabla" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2803 +#: parser/analyze.c:2888 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s no puede ser aplicado a una consulta WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2812 -#, fuzzy, c-format +#: parser/analyze.c:2897 +#, c-format msgid "%s cannot be applied to a named tuplestore" -msgstr "%s no puede ser aplicado a una consulta WITH" +msgstr "%s no puede ser aplicado a un «tuplestore» con nombre" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2829 +#: parser/analyze.c:2917 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "la relación «%s» en la cláusula %s no fue encontrada en la cláusula FROM" -#: parser/parse_agg.c:221 parser/parse_oper.c:222 +#: parser/parse_agg.c:220 parser/parse_oper.c:222 #, c-format msgid "could not identify an ordering operator for type %s" msgstr "no se pudo identificar un operador de ordenamiento para el tipo %s" -#: parser/parse_agg.c:223 +#: parser/parse_agg.c:222 #, c-format msgid "Aggregates with DISTINCT must be able to sort their inputs." msgstr "Las funciones de agregación con DISTINCT deben ser capaces de ordenar sus valores de entrada." -#: parser/parse_agg.c:258 +#: parser/parse_agg.c:257 #, c-format msgid "GROUPING must have fewer than 32 arguments" msgstr "GROUPING debe tener menos de 32 argumentos" -#: parser/parse_agg.c:361 +#: parser/parse_agg.c:360 msgid "aggregate functions are not allowed in JOIN conditions" msgstr "no se permiten funciones de agregación en las condiciones de JOIN" -#: parser/parse_agg.c:363 +#: parser/parse_agg.c:362 msgid "grouping operations are not allowed in JOIN conditions" msgstr "no se permiten las operaciones «grouping» en condiciones JOIN" -#: parser/parse_agg.c:375 +#: parser/parse_agg.c:374 msgid "aggregate functions are not allowed in FROM clause of their own query level" msgstr "las funciones de agregación no están permitidas en la cláusula FROM de su mismo nivel de consulta" -#: parser/parse_agg.c:377 +#: parser/parse_agg.c:376 msgid "grouping operations are not allowed in FROM clause of their own query level" msgstr "las operaciones «grouping» no están permitidas en la cláusula FROM de su mismo nivel de consulta" -#: parser/parse_agg.c:382 +#: parser/parse_agg.c:381 msgid "aggregate functions are not allowed in functions in FROM" msgstr "no se permiten funciones de agregación en una función en FROM" -#: parser/parse_agg.c:384 +#: parser/parse_agg.c:383 msgid "grouping operations are not allowed in functions in FROM" msgstr "no se permiten operaciones «grouping» en funciones en FROM" -#: parser/parse_agg.c:392 +#: parser/parse_agg.c:391 msgid "aggregate functions are not allowed in policy expressions" msgstr "no se permiten funciones de agregación en expresiones de políticas" -#: parser/parse_agg.c:394 +#: parser/parse_agg.c:393 msgid "grouping operations are not allowed in policy expressions" msgstr "no se permiten operaciones «grouping» en expresiones de políticas" -#: parser/parse_agg.c:411 +#: parser/parse_agg.c:410 msgid "aggregate functions are not allowed in window RANGE" msgstr "no se permiten funciones de agregación en RANGE de ventana deslizante" -#: parser/parse_agg.c:413 +#: parser/parse_agg.c:412 msgid "grouping operations are not allowed in window RANGE" msgstr "no se permiten operaciones «grouping» en RANGE de ventana deslizante" -#: parser/parse_agg.c:418 +#: parser/parse_agg.c:417 msgid "aggregate functions are not allowed in window ROWS" msgstr "no se permiten funciones de agregación en ROWS de ventana deslizante" -#: parser/parse_agg.c:420 +#: parser/parse_agg.c:419 msgid "grouping operations are not allowed in window ROWS" msgstr "no se permiten operaciones «grouping» en ROWS de ventana deslizante" -#: parser/parse_agg.c:454 +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "no se permiten funciones de agregación en GROUPS de ventana deslizante" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "no se permiten operaciones «grouping» en GROUPS de ventana deslizante" + +#: parser/parse_agg.c:460 msgid "aggregate functions are not allowed in check constraints" msgstr "no se permiten funciones de agregación en restricciones «check»" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:462 msgid "grouping operations are not allowed in check constraints" msgstr "no se permiten operaciones «grouping» en restricciones «check»" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:469 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "no se permiten funciones de agregación en expresiones DEFAULT" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:471 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "no se permiten operaciones «grouping» en expresiones DEFAULT" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:476 msgid "aggregate functions are not allowed in index expressions" msgstr "no se permiten funciones de agregación en una expresión de índice" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:478 msgid "grouping operations are not allowed in index expressions" msgstr "no se permiten operaciones «grouping» en expresiones de índice" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:483 msgid "aggregate functions are not allowed in index predicates" msgstr "no se permiten funciones de agregación en predicados de índice" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:485 msgid "grouping operations are not allowed in index predicates" msgstr "no se permiten operaciones «grouping» en predicados de índice" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:490 msgid "aggregate functions are not allowed in transform expressions" msgstr "no se permiten funciones de agregación en una expresión de transformación" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:492 msgid "grouping operations are not allowed in transform expressions" msgstr "no se permiten operaciones «grouping» en expresiones de transformación" -#: parser/parse_agg.c:491 +#: parser/parse_agg.c:497 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "no se permiten funciones de agregación en un parámetro a EXECUTE" -#: parser/parse_agg.c:493 +#: parser/parse_agg.c:499 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "no se permiten operaciones «grouping» en parámetros a EXECUTE" -#: parser/parse_agg.c:498 +#: parser/parse_agg.c:504 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "no se permiten funciones de agregación en condición WHEN de un disparador" -#: parser/parse_agg.c:500 +#: parser/parse_agg.c:506 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "no se permiten operaciones «grouping» en condiciones WHEN de un disparador" -#: parser/parse_agg.c:505 -#, fuzzy -msgid "aggregate functions are not allowed in partition key expression" -msgstr "no se permiten funciones de agregación en una expresión de índice" +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "no se permiten funciones de agregación en borde de partición" -#: parser/parse_agg.c:507 -#, fuzzy -msgid "grouping operations are not allowed in partition key expression" -msgstr "no se permiten operaciones «grouping» en expresiones de índice" +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "no se permiten operaciones «grouping» en borde de partición" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "no se permiten funciones de agregación en una expresión de llave de particionaiento" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de llave de particionamiento" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "no se permiten funciones de agregación en expresiones de generación de columna" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "no se permiten operaciones «grouping» en expresiones de generación de columna" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "no se permiten funciones de agregación en argumentos de CALL" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "no se permiten operaciones «grouping» en argumentos de CALL" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones de agregación en las condiciones WHERE de COPY FROM" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten las operaciones «grouping» en condiciones WHERE de COPY FROM" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:530 parser/parse_clause.c:1830 +#: parser/parse_agg.c:567 parser/parse_clause.c:1778 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "no se permiten funciones de agregación en %s" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:533 +#: parser/parse_agg.c:570 #, c-format msgid "grouping operations are not allowed in %s" msgstr "no se permiten operaciones «grouping» en %s" -#: parser/parse_agg.c:641 +#: parser/parse_agg.c:678 #, c-format msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "una función de agregación de nivel exterior no puede contener una variable de nivel inferior en sus argumentos directos" -#: parser/parse_agg.c:720 -#, fuzzy, c-format -#| msgid "aggregate function calls cannot contain window function calls" +#: parser/parse_agg.c:757 +#, c-format msgid "aggregate function calls cannot contain set-returning function calls" -msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones de ventana deslizante" +msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones que retornan conjuntos" -#: parser/parse_agg.c:721 parser/parse_expr.c:1761 parser/parse_expr.c:2237 -#: parser/parse_func.c:773 -#, fuzzy, c-format -#| msgid "%s is not allowed with set-returning functions in the target list" +#: parser/parse_agg.c:758 parser/parse_expr.c:1839 parser/parse_expr.c:2328 +#: parser/parse_func.c:876 +#, c-format msgid "You might be able to move the set-returning function into a LATERAL FROM item." -msgstr "%s no está permitido con funciones que retornan conjuntos en la lista de resultados" +msgstr "Puede intentar mover la funci[on que retorna conjuntos a un elemento LATERAL FROM." -#: parser/parse_agg.c:726 +#: parser/parse_agg.c:763 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones de ventana deslizante" -#: parser/parse_agg.c:805 +#: parser/parse_agg.c:842 msgid "window functions are not allowed in JOIN conditions" msgstr "no se permiten funciones de ventana deslizante en condiciones JOIN" -#: parser/parse_agg.c:812 +#: parser/parse_agg.c:849 msgid "window functions are not allowed in functions in FROM" msgstr "no se permiten funciones de ventana deslizante en funciones en FROM" -#: parser/parse_agg.c:818 +#: parser/parse_agg.c:855 msgid "window functions are not allowed in policy expressions" msgstr "no se permiten funciones de ventana deslizante en expresiones de políticas" -#: parser/parse_agg.c:830 +#: parser/parse_agg.c:868 msgid "window functions are not allowed in window definitions" msgstr "no se permiten funciones de ventana deslizante en definiciones de ventana deslizante" -#: parser/parse_agg.c:862 +#: parser/parse_agg.c:900 msgid "window functions are not allowed in check constraints" msgstr "no se permiten funciones de ventana deslizante en restricciones «check»" -#: parser/parse_agg.c:866 +#: parser/parse_agg.c:904 msgid "window functions are not allowed in DEFAULT expressions" msgstr "no se permiten funciones de ventana deslizante en expresiones DEFAULT" -#: parser/parse_agg.c:869 +#: parser/parse_agg.c:907 msgid "window functions are not allowed in index expressions" msgstr "no se permiten funciones de ventana deslizante en expresiones de índice" -#: parser/parse_agg.c:872 +#: parser/parse_agg.c:910 msgid "window functions are not allowed in index predicates" msgstr "no se permiten funciones de ventana deslizante en predicados de índice" -#: parser/parse_agg.c:875 +#: parser/parse_agg.c:913 msgid "window functions are not allowed in transform expressions" msgstr "no se permiten funciones de ventana deslizante en expresiones de transformación" -#: parser/parse_agg.c:878 +#: parser/parse_agg.c:916 msgid "window functions are not allowed in EXECUTE parameters" msgstr "no se permiten funciones de ventana deslizante en parámetros a EXECUTE" -#: parser/parse_agg.c:881 +#: parser/parse_agg.c:919 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "no se permiten funciones de ventana deslizante en condiciones WHEN de un disparador" -#: parser/parse_agg.c:884 -#, fuzzy -msgid "window functions are not allowed in partition key expression" -msgstr "no se permiten funciones de ventana deslizante en expresiones de índice" +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "no se permiten funciones de ventana deslizante en borde de partición" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de llave de particionamiento" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "no se permiten funciones de ventana deslizante en argumentos de CALL" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones de ventana deslizante en las condiciones WHERE de COPY FROM" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "no se permiten funciones de ventana deslizante en expresiones de generación de columna" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:904 parser/parse_clause.c:1839 +#: parser/parse_agg.c:954 parser/parse_clause.c:1787 #, c-format msgid "window functions are not allowed in %s" msgstr "no se permiten funciones de ventana deslizante en %s" -#: parser/parse_agg.c:938 parser/parse_clause.c:2673 +#: parser/parse_agg.c:988 parser/parse_clause.c:2623 #, c-format msgid "window \"%s\" does not exist" msgstr "la ventana «%s» no existe" -#: parser/parse_agg.c:1023 +#: parser/parse_agg.c:1072 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "demasiados conjuntos «grouping» presentes (máximo 4096)" -#: parser/parse_agg.c:1172 +#: parser/parse_agg.c:1212 #, c-format msgid "aggregate functions are not allowed in a recursive query's recursive term" msgstr "no se permiten funciones de agregación en el término recursivo de una consulta recursiva" -#: parser/parse_agg.c:1365 +#: parser/parse_agg.c:1405 #, c-format msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" msgstr "la columna «%s.%s» debe aparecer en la cláusula GROUP BY o ser usada en una función de agregación" -#: parser/parse_agg.c:1368 +#: parser/parse_agg.c:1408 #, c-format msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "Argumentos directos de una función de agregación de conjuntos ordenados debe usar sólo columnas agrupadas." -#: parser/parse_agg.c:1373 +#: parser/parse_agg.c:1413 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "la subconsulta usa la columna «%s.%s» no agrupada de una consulta exterior" -#: parser/parse_agg.c:1537 +#: parser/parse_agg.c:1577 #, c-format msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "los argumentos de GROUPING deben ser expresiones agrupantes del nivel de consulta asociado" -#: parser/parse_clause.c:192 -#, fuzzy, c-format +#: parser/parse_clause.c:198 +#, c-format msgid "relation \"%s\" cannot be the target of a modifying statement" -msgstr "relación «%s» no es un padre de la relación «%s»" +msgstr "relación «%s» no puede ser destino de una sentencia modificadora" -#: parser/parse_clause.c:637 parser/parse_clause.c:665 -#: parser/parse_func.c:2153 -#, fuzzy, c-format +#: parser/parse_clause.c:575 parser/parse_clause.c:603 parser/parse_func.c:2434 +#, c-format msgid "set-returning functions must appear at top level of FROM" -msgstr "no se permiten funciones de ventana deslizante en %s" +msgstr "las funciones que retornan conjuntos deben aparecer en el nivel más externo del FROM" -#: parser/parse_clause.c:677 +#: parser/parse_clause.c:615 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "no se permiten múltiples definiciones de columnas para la misma función" -#: parser/parse_clause.c:710 +#: parser/parse_clause.c:648 #, c-format msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "ROWS FROM() con varias funciones no puede tener una lista de definición de columnas" -#: parser/parse_clause.c:711 +#: parser/parse_clause.c:649 #, c-format msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "Ponga una lista de columnas separada para cada función dentro de ROWS FROM()." -#: parser/parse_clause.c:717 +#: parser/parse_clause.c:655 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "UNNEST() con varios argumentos no puede tener una lista de definición de columnas" -#: parser/parse_clause.c:718 +#: parser/parse_clause.c:656 #, c-format msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "Use llamadas a UNNEST() separadas dentro de ROWS FROM() y adjunte una lista de columnas a cada una." -#: parser/parse_clause.c:725 +#: parser/parse_clause.c:663 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY no puede usarse con una lista de definición de columnas" -#: parser/parse_clause.c:726 +#: parser/parse_clause.c:664 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "Ponga una lista de columnas dentro de ROWS FROM()." -#: parser/parse_clause.c:829 +#: parser/parse_clause.c:767 #, c-format msgid "only one FOR ORDINALITY column is allowed" -msgstr "" +msgstr "sólo se permite una columna FOR ORDINALITY" -#: parser/parse_clause.c:890 -#, fuzzy, c-format +#: parser/parse_clause.c:828 +#, c-format msgid "column name \"%s\" is not unique" -msgstr "la función %s no es única" +msgstr "el nombre de columna «%s» no es único" -#: parser/parse_clause.c:932 -#, fuzzy, c-format +#: parser/parse_clause.c:870 +#, c-format msgid "namespace name \"%s\" is not unique" -msgstr "la función %s no es única" +msgstr "el espacio de nombres «%s» no es único" -#: parser/parse_clause.c:942 +#: parser/parse_clause.c:880 #, c-format msgid "only one default namespace is allowed" -msgstr "" +msgstr "sólo se permite un espacio de nombres predeterminado" -#: parser/parse_clause.c:1003 +#: parser/parse_clause.c:942 #, c-format msgid "tablesample method %s does not exist" msgstr "no existe el método de tablesample «%s»" -#: parser/parse_clause.c:1025 +#: parser/parse_clause.c:964 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "el método de tablesample «%s» requiere %d argumento, no %d" msgstr[1] "el método de tablesample «%s» requiere %d argumentos, no %d" -#: parser/parse_clause.c:1059 +#: parser/parse_clause.c:998 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "el método de tablesample «%s» no soporta la opción REPEATABLE" -#: parser/parse_clause.c:1220 +#: parser/parse_clause.c:1168 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "la cláusula TABLESAMPLE sólo puede aplicarse a tablas y vistas materializadas" -#: parser/parse_clause.c:1390 +#: parser/parse_clause.c:1338 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "la columna «%s» aparece más de una vez en la cláusula USING" -#: parser/parse_clause.c:1405 +#: parser/parse_clause.c:1353 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "la columna común «%s» aparece más de una vez en la tabla izquierda" -#: parser/parse_clause.c:1414 +#: parser/parse_clause.c:1362 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "la columna «%s» especificada en la cláusula USING no existe en la tabla izquierda" -#: parser/parse_clause.c:1428 +#: parser/parse_clause.c:1376 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "la columna común «%s» aparece más de una vez en la tabla derecha" -#: parser/parse_clause.c:1437 +#: parser/parse_clause.c:1385 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "la columna «%s» especificada en la cláusula USING no existe en la tabla derecha" -#: parser/parse_clause.c:1491 +#: parser/parse_clause.c:1439 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "la lista de alias de columnas para «%s» tiene demasiadas entradas" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1800 +#: parser/parse_clause.c:1748 #, c-format msgid "argument of %s must not contain variables" msgstr "el argumento de %s no puede contener variables" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1965 +#: parser/parse_clause.c:1913 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s «%s» es ambiguo" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1994 +#: parser/parse_clause.c:1942 #, c-format msgid "non-integer constant in %s" msgstr "constante no entera en %s" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2016 +#: parser/parse_clause.c:1964 #, c-format msgid "%s position %d is not in select list" msgstr "la posición %2$d de %1$s no está en la lista de resultados" -#: parser/parse_clause.c:2457 +#: parser/parse_clause.c:2405 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE está limitado a 12 elementos" -#: parser/parse_clause.c:2661 +#: parser/parse_clause.c:2611 #, c-format msgid "window \"%s\" is already defined" msgstr "la ventana «%s» ya está definida" -#: parser/parse_clause.c:2722 +#: parser/parse_clause.c:2672 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "no se puede pasar a llevar la cláusula PARTITION BY de la ventana «%s»" -#: parser/parse_clause.c:2734 +#: parser/parse_clause.c:2684 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "no se puede pasar a llevar la cláusula ORDER BY de la ventana «%s»" -#: parser/parse_clause.c:2764 parser/parse_clause.c:2770 +#: parser/parse_clause.c:2714 parser/parse_clause.c:2720 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "no se puede copiar la ventana «%s» porque tiene una cláusula «frame»" -#: parser/parse_clause.c:2772 +#: parser/parse_clause.c:2722 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Omita el uso de paréntesis en esta cláusula OVER." -#: parser/parse_clause.c:2838 +#: parser/parse_clause.c:2742 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING requiere exactamente una columna ORDER BY" + +#: parser/parse_clause.c:2765 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "el modo GROUPS requiere una cláusula ORDER BY" + +#: parser/parse_clause.c:2835 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "en una agregación con DISTINCT, las expresiones en ORDER BY deben aparecer en la lista de argumentos" -#: parser/parse_clause.c:2839 +#: parser/parse_clause.c:2836 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "para SELECT DISTINCT, las expresiones en ORDER BY deben aparecer en la lista de resultados" -#: parser/parse_clause.c:2871 +#: parser/parse_clause.c:2868 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "una función de agregación con DISTINCT debe tener al menos un argumento" -#: parser/parse_clause.c:2872 +#: parser/parse_clause.c:2869 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT debe tener al menos una columna" -#: parser/parse_clause.c:2938 parser/parse_clause.c:2970 +#: parser/parse_clause.c:2935 parser/parse_clause.c:2967 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "las expresiones de SELECT DISTINCT ON deben coincidir con las expresiones iniciales de ORDER BY" -#: parser/parse_clause.c:3048 +#: parser/parse_clause.c:3045 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ASC/DESC no están permitidos en cláusulas ON CONFLICT" -#: parser/parse_clause.c:3054 +#: parser/parse_clause.c:3051 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "NULLS FIRST/LAST no están permitidos en cláusulas ON CONFLICT" -#: parser/parse_clause.c:3134 +#: parser/parse_clause.c:3130 #, c-format msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATE requiere una especificación de inferencia o nombre de restricción" -#: parser/parse_clause.c:3135 +#: parser/parse_clause.c:3131 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Por ejemplo, ON CONFLICT (nombre_de_columna)." -#: parser/parse_clause.c:3146 +#: parser/parse_clause.c:3142 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT no está soportado con tablas que son catálogos de sistema" -#: parser/parse_clause.c:3154 +#: parser/parse_clause.c:3150 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT no está soportado en la tabla «%s» usada como catálogo de sistema" -#: parser/parse_clause.c:3280 +#: parser/parse_clause.c:3293 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "el operador «%s» no es un operador válido de ordenamiento" -#: parser/parse_clause.c:3282 +#: parser/parse_clause.c:3295 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "Los operadores de ordenamiento deben ser miembros «<» o «>» de una familia de operadores btree." -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2144 parser/parse_expr.c:2732 parser/parse_target.c:936 +#: parser/parse_clause.c:3606 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING no está soportado para la columna de tipo %s" + +#: parser/parse_clause.c:3612 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING no está soportado para la columna de tipo %s y tipo de desplazamiento %s" + +#: parser/parse_clause.c:3615 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Convierta el valor de desplazamiento a un tipo apropiado." + +#: parser/parse_clause.c:3620 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE con desplazamiento PRECEDING/FOLLOWING tiene múltiples interpretaciones para la columna de tipo %s y tipo de desplazamiento %s" + +#: parser/parse_clause.c:3623 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Convierta el valor de desplazamiento al tipo deseado exacto." + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2235 parser/parse_expr.c:2823 parser/parse_target.c:962 #, c-format msgid "cannot cast type %s to %s" msgstr "no se puede convertir el tipo %s a %s" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." msgstr "La entrada tiene muy pocas columnas." -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "No se puede convertir el tipo %s a %s en la columna %d." -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." msgstr "La entrada tiene demasiadas columnas." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1128 +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "el argumento de %s debe ser de tipo %s, no tipo %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1091 parser/parse_coerce.c:1140 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "el argumento de %s no debe retornar un conjunto" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1280 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "los tipos %2$s y %3$s no son coincidentes en %1$s" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1347 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "%s no pudo convertir el tipo %s a %s" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "los argumentos declarados «anyelement» no son de tipos compatibles" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "los argumentos declarados «anyarray» no son de tipos compatibles" -#: parser/parse_coerce.c:1689 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "los argumentos declarados «anyrange» no son de tipos compatibles" -#: parser/parse_coerce.c:1718 parser/parse_coerce.c:1933 -#: parser/parse_coerce.c:1967 -#, fuzzy, c-format +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 +#, c-format msgid "argument declared %s is not an array but type %s" -msgstr "el argumento declarado «anyarray» no es un array sino de tipo %s" +msgstr "el argumento declarado %s no es un array sino de tipo %s" -#: parser/parse_coerce.c:1734 parser/parse_coerce.c:1773 -#, fuzzy, c-format +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 +#, c-format msgid "argument declared %s is not consistent with argument declared %s" -msgstr "el argumento declarado «anyrange» no es consistente con el argumento declarado «anyelement»" +msgstr "el argumento declarado %s no es consistente con el argumento declarado %s" -#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1980 -#, fuzzy, c-format +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 +#, c-format msgid "argument declared %s is not a range type but type %s" -msgstr "el argumento declarado «anyrange» no es un tipo de rango sino tipo %s" +msgstr "el argumento declarado %s no es un tipo de rango sino tipo %s" -#: parser/parse_coerce.c:1794 -#, fuzzy, c-format +#: parser/parse_coerce.c:1865 +#, c-format msgid "could not determine polymorphic type because input has type %s" -msgstr "no se pudo determinar el tipo polimórfico porque el tipo de entrada es «unknown»" +msgstr "no se pudo determinar el tipo polimórfico porque la entrada es de tipo %s" -#: parser/parse_coerce.c:1805 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "el argumento coincidente con anynonarray es un array: %s" -#: parser/parse_coerce.c:1815 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "el tipo coincidente con anyenum no es un tipo enum: %s" -#: parser/parse_coerce.c:1855 parser/parse_coerce.c:1885 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "no se pudo encontrar un tipo de rango para el tipo de dato %s" @@ -14489,452 +14849,570 @@ msgstr "FOR UPDATE/SHARE no está implementado en una consulta recursiva" msgid "recursive reference to query \"%s\" must not appear more than once" msgstr "la referencia recursiva a la consulta «%s» no debe aparecer más de una vez" -#: parser/parse_expr.c:350 -#, fuzzy, c-format +#: parser/parse_expr.c:349 +#, c-format msgid "DEFAULT is not allowed in this context" -msgstr "los arrays con elementos null no son permitidos en este contexto" +msgstr "DEFAULT no está permitido en este contexto" -#: parser/parse_expr.c:403 parser/parse_relation.c:3248 -#: parser/parse_relation.c:3268 +#: parser/parse_expr.c:402 parser/parse_relation.c:3352 +#: parser/parse_relation.c:3372 #, c-format msgid "column %s.%s does not exist" msgstr "no existe la columna %s.%s" -#: parser/parse_expr.c:415 +#: parser/parse_expr.c:414 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "la columna «%s» no fue encontrado en el tipo %s" -#: parser/parse_expr.c:421 +#: parser/parse_expr.c:420 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "no se pudo identificar la columna «%s» en el tipo de dato record" -#: parser/parse_expr.c:427 +#: parser/parse_expr.c:426 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "la notación de columna .%s fue aplicada al tipo %s, que no es un tipo compuesto" -#: parser/parse_expr.c:458 parser/parse_target.c:722 +#: parser/parse_expr.c:457 parser/parse_target.c:729 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "la expansión de filas a través de «*» no está soportado aquí" -#: parser/parse_expr.c:767 parser/parse_relation.c:689 -#: parser/parse_relation.c:789 parser/parse_target.c:1171 +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "no se pueden usar referencias a columnas en una cláusula DEFAULT" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "no se pueden usar referencias a columnas en expresión de borde de partición" + +#: parser/parse_expr.c:844 parser/parse_relation.c:692 +#: parser/parse_relation.c:803 parser/parse_target.c:1200 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "la referencia a la columna «%s» es ambigua" -#: parser/parse_expr.c:823 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:900 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "no hay parámetro $%d" -#: parser/parse_expr.c:1066 +#: parser/parse_expr.c:1143 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "NULLIF requiere que el operador = retorne boolean" #. translator: %s is name of a SQL construct, eg NULLIF -#: parser/parse_expr.c:1072 parser/parse_expr.c:3048 -#, fuzzy, c-format -#| msgid "argument of %s must not return a set" +#: parser/parse_expr.c:1149 parser/parse_expr.c:3139 +#, c-format msgid "%s must not return a set" -msgstr "el argumento de %s no debe retornar un conjunto" +msgstr "%s no debe retornar un conjunto" -#: parser/parse_expr.c:1519 parser/parse_expr.c:1551 +#: parser/parse_expr.c:1597 parser/parse_expr.c:1629 #, c-format msgid "number of columns does not match number of values" msgstr "el número de columnas no coincide con el número de valores" -#: parser/parse_expr.c:1565 +#: parser/parse_expr.c:1643 #, c-format msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" -msgstr "" +msgstr "el origen para un UPDATE de varias columnas debe ser una expresión sub-SELECT o ROW ()" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_expr.c:1759 parser/parse_expr.c:2235 parser/parse_func.c:2256 -#, fuzzy, c-format +#: parser/parse_expr.c:1837 parser/parse_expr.c:2326 parser/parse_func.c:2550 +#, c-format msgid "set-returning functions are not allowed in %s" -msgstr "no se permiten funciones de ventana deslizante en %s" +msgstr "no se permiten funciones que retornan conjuntos en %s" -#: parser/parse_expr.c:1819 +#: parser/parse_expr.c:1898 msgid "cannot use subquery in check constraint" msgstr "no se pueden usar subconsultas en una restricción «check»" -#: parser/parse_expr.c:1823 +#: parser/parse_expr.c:1902 msgid "cannot use subquery in DEFAULT expression" msgstr "no se puede usar una subconsulta en una expresión DEFAULT" -#: parser/parse_expr.c:1826 +#: parser/parse_expr.c:1905 msgid "cannot use subquery in index expression" msgstr "no se puede usar una subconsulta en una expresión de índice" -#: parser/parse_expr.c:1829 +#: parser/parse_expr.c:1908 msgid "cannot use subquery in index predicate" msgstr "no se puede usar una subconsulta en un predicado de índice" -#: parser/parse_expr.c:1832 +#: parser/parse_expr.c:1911 msgid "cannot use subquery in transform expression" msgstr "no se puede usar una subconsulta en una expresión de transformación" -#: parser/parse_expr.c:1835 +#: parser/parse_expr.c:1914 msgid "cannot use subquery in EXECUTE parameter" msgstr "no se puede usar una subconsulta en un parámetro a EXECUTE" -#: parser/parse_expr.c:1838 +#: parser/parse_expr.c:1917 msgid "cannot use subquery in trigger WHEN condition" msgstr "no se puede usar una subconsulta en la condición WHEN de un disparador" -#: parser/parse_expr.c:1841 -#, fuzzy +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in partition bound" +msgstr "no se puede usar una subconsulta en un borde de partición" + +#: parser/parse_expr.c:1923 msgid "cannot use subquery in partition key expression" -msgstr "no se puede usar una subconsulta en una expresión de índice" +msgstr "no se puede usar una subconsulta en una expresión de llave de partición" -#: parser/parse_expr.c:1894 +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in CALL argument" +msgstr "no se puede usar una subconsulta en un argumento a CALL" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "no se puede usar una subconsulta en la condición WHERE de COPY FROM" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in column generation expression" +msgstr "no se puede usar una subconsulta en una expresión de generación de columna" + +#: parser/parse_expr.c:1985 #, c-format msgid "subquery must return only one column" msgstr "la subconsulta debe retornar sólo una columna" -#: parser/parse_expr.c:1978 +#: parser/parse_expr.c:2069 #, c-format msgid "subquery has too many columns" msgstr "la subconsulta tiene demasiadas columnas" -#: parser/parse_expr.c:1983 +#: parser/parse_expr.c:2074 #, c-format msgid "subquery has too few columns" msgstr "la subconsulta tiene muy pocas columnas" -#: parser/parse_expr.c:2084 +#: parser/parse_expr.c:2175 #, c-format msgid "cannot determine type of empty array" msgstr "no se puede determinar el tipo de un array vacío" -#: parser/parse_expr.c:2085 +#: parser/parse_expr.c:2176 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "Agregue una conversión de tipo explícita al tipo deseado, por ejemplo ARRAY[]::integer[]." -#: parser/parse_expr.c:2099 +#: parser/parse_expr.c:2190 #, c-format msgid "could not find element type for data type %s" msgstr "no se pudo encontrar el tipo de dato de elemento para el tipo de dato %s" -#: parser/parse_expr.c:2386 +#: parser/parse_expr.c:2477 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "el valor del atributo XML sin nombre debe ser una referencia a una columna" -#: parser/parse_expr.c:2387 +#: parser/parse_expr.c:2478 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "el valor del elemento XML sin nombre debe ser una referencia a una columna" -#: parser/parse_expr.c:2402 +#: parser/parse_expr.c:2493 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "el nombre de atributo XML «%s» aparece más de una vez" -#: parser/parse_expr.c:2509 +#: parser/parse_expr.c:2600 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "no se puede convertir el resultado de XMLSERIALIZE a %s" -#: parser/parse_expr.c:2805 parser/parse_expr.c:3001 +#: parser/parse_expr.c:2896 parser/parse_expr.c:3092 #, c-format msgid "unequal number of entries in row expressions" msgstr "número desigual de entradas en expresiones de registro" -#: parser/parse_expr.c:2815 +#: parser/parse_expr.c:2906 #, c-format msgid "cannot compare rows of zero length" msgstr "no se pueden comparar registros de largo cero" -#: parser/parse_expr.c:2840 +#: parser/parse_expr.c:2931 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "el operador de comparación de registros debe retornar tipo boolean, no tipo %s" -#: parser/parse_expr.c:2847 +#: parser/parse_expr.c:2938 #, c-format msgid "row comparison operator must not return a set" msgstr "el operador de comparación de registros no puede retornar un conjunto" -#: parser/parse_expr.c:2906 parser/parse_expr.c:2947 +#: parser/parse_expr.c:2997 parser/parse_expr.c:3038 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "no se pudo determinar la interpretación del operador de comparación de registros %s" -#: parser/parse_expr.c:2908 +#: parser/parse_expr.c:2999 #, c-format msgid "Row comparison operators must be associated with btree operator families." msgstr "Los operadores de comparación de registros deben estar asociados a una familia de operadores btree." -#: parser/parse_expr.c:2949 +#: parser/parse_expr.c:3040 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "Hay múltiples candidatos igualmente plausibles." -#: parser/parse_expr.c:3042 +#: parser/parse_expr.c:3133 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROM requiere que el operador = retorne boolean" -#: parser/parse_expr.c:3361 parser/parse_expr.c:3379 +#: parser/parse_expr.c:3452 parser/parse_expr.c:3470 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "cambio de precedencia de operadores: %s es ahora de menor precedencia que %s" -#: parser/parse_func.c:179 +#: parser/parse_func.c:195 #, c-format msgid "argument name \"%s\" used more than once" -msgstr "el nombre de argumento «%s» fue especificado más de una vez" +msgstr "nombre de argumento «%s» especificado más de una vez" -#: parser/parse_func.c:190 +#: parser/parse_func.c:206 #, c-format msgid "positional argument cannot follow named argument" msgstr "un argumento posicional no puede seguir a un argumento con nombre" -#: parser/parse_func.c:275 +#: parser/parse_func.c:288 parser/parse_func.c:2253 +#, c-format +msgid "%s is not a procedure" +msgstr "%s no es un procedimiento" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Para invocar a una función, use SELECT." + +#: parser/parse_func.c:298 +#, c-format +msgid "%s is a procedure" +msgstr "%s es un procedimiento" + +#: parser/parse_func.c:302 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Para invocar a un procedimiento, use CALL." + +#: parser/parse_func.c:316 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "se especificó %s(*), pero %s no es una función de agregación" -#: parser/parse_func.c:282 +#: parser/parse_func.c:323 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "se especificó DISTINCT, pero %s no es una función de agregación" -#: parser/parse_func.c:288 +#: parser/parse_func.c:329 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "se especificó WITHIN GROUP, pero %s no es una función de agregación" -#: parser/parse_func.c:294 +#: parser/parse_func.c:335 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "se especificó ORDER BY, pero %s no es una función de agregación" -#: parser/parse_func.c:300 +#: parser/parse_func.c:341 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "se especificó FILTER, pero %s no es una función de agregación" -#: parser/parse_func.c:306 +#: parser/parse_func.c:347 #, c-format msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "se especificó OVER, pero %s no es una función de ventana deslizante ni una función de agregación" -#: parser/parse_func.c:336 +#: parser/parse_func.c:385 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP es obligatorio para la función de agregación de conjuntos ordenados %s" -#: parser/parse_func.c:342 +#: parser/parse_func.c:391 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVER no está soportado para la función de agregación de conjuntos ordenados %s" -#: parser/parse_func.c:373 parser/parse_func.c:402 +#: parser/parse_func.c:422 parser/parse_func.c:451 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr "Hay una función de agregación de conjuntos ordenados %s, pero requiere %d argumentos directos, no %d." -#: parser/parse_func.c:427 +#: parser/parse_func.c:476 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "Para usar la función de agregación de conjunto hipotética %s, el número de argumentos hipotéticos directos (acá %d) debe coincidir con el número de columnas del ordenamiento (acá %d)." -#: parser/parse_func.c:441 +#: parser/parse_func.c:490 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr "Hay una función de agregación de conjuntos ordenados %s, pero requiere al menos %d argumentos directos" -#: parser/parse_func.c:460 +#: parser/parse_func.c:509 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s no es una función de agregación de conjunto ordenado, por lo que no puede tener WITHIN GROUP" -#: parser/parse_func.c:473 +#: parser/parse_func.c:522 #, c-format msgid "window function %s requires an OVER clause" msgstr "la función de ventana deslizante %s requiere una cláusula OVER" -#: parser/parse_func.c:480 +#: parser/parse_func.c:529 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "la función de ventana deslizante %s no puede tener WITHIN GROUP" -#: parser/parse_func.c:501 +#: parser/parse_func.c:558 +#, c-format +msgid "procedure %s is not unique" +msgstr "la procedimiento %s no es único" + +#: parser/parse_func.c:561 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "No se pudo escoger el procedimiento más adecuado. Puede ser necesario agregar conversiones explícitas de tipos." + +#: parser/parse_func.c:567 #, c-format msgid "function %s is not unique" msgstr "la función %s no es única" -#: parser/parse_func.c:504 +#: parser/parse_func.c:570 #, c-format msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "No se pudo escoger la función más adecuada. Puede ser necesario agregar conversiones explícitas de tipos." -#: parser/parse_func.c:515 +#: parser/parse_func.c:609 #, c-format msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "Ninguna función coincide en el nombre y tipos de argumentos. Quizás puso ORDER BY en una mala posición; ORDER BY debe aparecer después de todos los argumentos normales de la función de agregación." -#: parser/parse_func.c:526 +#: parser/parse_func.c:617 parser/parse_func.c:2296 +#, c-format +msgid "procedure %s does not exist" +msgstr "no existe el procedimiento «%s»" + +#: parser/parse_func.c:620 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ningún procedimiento coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_func.c:629 #, c-format msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgstr "Ninguna función coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." -#: parser/parse_func.c:628 +#: parser/parse_func.c:731 #, c-format msgid "VARIADIC argument must be an array" msgstr "el parámetro VARIADIC debe ser un array" -#: parser/parse_func.c:680 parser/parse_func.c:744 +#: parser/parse_func.c:783 parser/parse_func.c:847 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*) debe ser usado para invocar una función de agregación sin parámetros" -#: parser/parse_func.c:687 +#: parser/parse_func.c:790 #, c-format msgid "aggregates cannot return sets" msgstr "las funciones de agregación no pueden retornar conjuntos" -#: parser/parse_func.c:702 +#: parser/parse_func.c:805 #, c-format msgid "aggregates cannot use named arguments" msgstr "las funciones de agregación no pueden usar argumentos con nombre" -#: parser/parse_func.c:734 +#: parser/parse_func.c:837 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "DISTINCT no está implementado para funciones de ventana deslizante" -#: parser/parse_func.c:754 +#: parser/parse_func.c:857 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "el ORDER BY de funciones de agregación no está implementado para funciones de ventana deslizante" -#: parser/parse_func.c:763 +#: parser/parse_func.c:866 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER no está implementado para funciones de ventana deslizante" -#: parser/parse_func.c:772 -#, fuzzy, c-format -#| msgid "aggregate function calls cannot contain window function calls" +#: parser/parse_func.c:875 +#, c-format msgid "window function calls cannot contain set-returning function calls" -msgstr "las llamadas a funciones de agregación no pueden contener llamadas a funciones de ventana deslizante" +msgstr "las llamadas a funciones de ventana no pueden contener llamadas a funciones que retornan conjuntos" -#: parser/parse_func.c:780 +#: parser/parse_func.c:883 #, c-format msgid "window functions cannot return sets" msgstr "las funciones de ventana deslizante no pueden retornar conjuntos" -#: parser/parse_func.c:1950 -#, fuzzy, c-format +#: parser/parse_func.c:2134 parser/parse_func.c:2325 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "no se pudo encontrar una función llamada «%s»" + +#: parser/parse_func.c:2148 parser/parse_func.c:2343 +#, c-format msgid "function name \"%s\" is not unique" -msgstr "la función %s no es única" +msgstr "el nombre de función «%s» no es único" -#: parser/parse_func.c:1952 +#: parser/parse_func.c:2150 parser/parse_func.c:2345 #, c-format msgid "Specify the argument list to select the function unambiguously." -msgstr "" +msgstr "Especifique la lista de argumentos para seleccionar la función sin ambigüedad." -#: parser/parse_func.c:1962 -#, fuzzy, c-format -msgid "could not find a function named \"%s\"" -msgstr "no se encuentra la función «%s» en el archivo «%s»" +#: parser/parse_func.c:2194 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "los procedimientos no pueden tener más de %d argumento" +msgstr[1] "los procedimientos no pueden tener más de %d argumentos" + +#: parser/parse_func.c:2243 +#, c-format +msgid "%s is not a function" +msgstr "«%s» no es una función" + +#: parser/parse_func.c:2263 +#, c-format +msgid "function %s is not an aggregate" +msgstr "la función %s no es una función de agregación" + +#: parser/parse_func.c:2291 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "no se pudo encontrar un procedimiento llamado «%s»" + +#: parser/parse_func.c:2305 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "no se pudo encontrar una función de agregación llamada «%s»" -#: parser/parse_func.c:2064 +#: parser/parse_func.c:2310 #, c-format msgid "aggregate %s(*) does not exist" msgstr "no existe la función de agregación %s(*)" -#: parser/parse_func.c:2069 +#: parser/parse_func.c:2315 #, c-format msgid "aggregate %s does not exist" msgstr "no existe la función de agregación %s" -#: parser/parse_func.c:2088 +#: parser/parse_func.c:2350 #, c-format -msgid "function %s is not an aggregate" -msgstr "la función %s no es una función de agregación" +msgid "procedure name \"%s\" is not unique" +msgstr "el nombre de procedimiento «%s» no es única" + +#: parser/parse_func.c:2352 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar el procedimiento sin ambigüedad." + +#: parser/parse_func.c:2357 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "el atributo de la función de agregación «%s» no es único" + +#: parser/parse_func.c:2359 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar la función de agregación sin ambigüedad." + +#: parser/parse_func.c:2364 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "el nombre de rutina «%s» no es único" + +#: parser/parse_func.c:2366 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Especifique la lista de argumentos para seleccionar la rutina sin ambigüedad." -#: parser/parse_func.c:2140 -#, fuzzy +#: parser/parse_func.c:2421 msgid "set-returning functions are not allowed in JOIN conditions" -msgstr "no se permiten funciones de ventana deslizante en condiciones JOIN" +msgstr "no se permiten funciones que retornan conjuntos en condiciones JOIN" -#: parser/parse_func.c:2161 -#, fuzzy +#: parser/parse_func.c:2442 msgid "set-returning functions are not allowed in policy expressions" -msgstr "no se permiten funciones de ventana deslizante en expresiones de políticas" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de política" -#: parser/parse_func.c:2176 -#, fuzzy +#: parser/parse_func.c:2458 msgid "set-returning functions are not allowed in window definitions" -msgstr "no se permiten funciones de ventana deslizante en definiciones de ventana deslizante" +msgstr "no se permiten funciones que retornan conjuntos definiciones de ventana deslizante" -#: parser/parse_func.c:2214 -#, fuzzy +#: parser/parse_func.c:2496 msgid "set-returning functions are not allowed in check constraints" -msgstr "no se permiten funciones de ventana deslizante en restricciones «check»" +msgstr "no se permiten funciones de que retornan conjuntos en restricciones «check»" -#: parser/parse_func.c:2218 -#, fuzzy +#: parser/parse_func.c:2500 msgid "set-returning functions are not allowed in DEFAULT expressions" -msgstr "no se permiten funciones de ventana deslizante en expresiones DEFAULT" +msgstr "no se permiten funciones que retornan conjuntos en expresiones DEFAULT" -#: parser/parse_func.c:2221 -#, fuzzy +#: parser/parse_func.c:2503 msgid "set-returning functions are not allowed in index expressions" -msgstr "no se permiten funciones de ventana deslizante en expresiones de índice" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de índice" -#: parser/parse_func.c:2224 -#, fuzzy +#: parser/parse_func.c:2506 msgid "set-returning functions are not allowed in index predicates" -msgstr "no se permiten funciones de ventana deslizante en predicados de índice" +msgstr "no se permiten funciones que retornan conjuntos en predicados de índice" -#: parser/parse_func.c:2227 -#, fuzzy +#: parser/parse_func.c:2509 msgid "set-returning functions are not allowed in transform expressions" -msgstr "no se permiten funciones de ventana deslizante en expresiones de transformación" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de transformación" -#: parser/parse_func.c:2230 -#, fuzzy +#: parser/parse_func.c:2512 msgid "set-returning functions are not allowed in EXECUTE parameters" -msgstr "no se permiten funciones de ventana deslizante en parámetros a EXECUTE" +msgstr "no se permiten funciones que retornan conjuntos en parámetros a EXECUTE" -#: parser/parse_func.c:2233 -#, fuzzy +#: parser/parse_func.c:2515 msgid "set-returning functions are not allowed in trigger WHEN conditions" -msgstr "no se permiten funciones de ventana deslizante en condiciones WHEN de un disparador" +msgstr "no se permiten funciones que retornan conjuntos en condiciones WHEN de un disparador" + +#: parser/parse_func.c:2518 +msgid "set-returning functions are not allowed in partition bound" +msgstr "no se permiten funciones que retornan conjuntos en bordes de partición" -#: parser/parse_func.c:2236 -#, fuzzy +#: parser/parse_func.c:2521 msgid "set-returning functions are not allowed in partition key expressions" -msgstr "no se permiten funciones de ventana deslizante en expresiones de índice" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de llave de particionamiento" + +#: parser/parse_func.c:2524 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "no se permiten funciones que retornan conjuntos en argumentos de CALL" + +#: parser/parse_func.c:2527 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "no se permiten funciones que retornan conjuntos en las condiciones WHERE de COPY FROM" + +#: parser/parse_func.c:2530 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "no se permiten funciones que retornan conjuntos en expresiones de generación de columna" #: parser/parse_node.c:87 #, c-format msgid "target lists can have at most %d entries" msgstr "las listas de resultados pueden tener a lo más %d entradas" -#: parser/parse_node.c:256 +#: parser/parse_node.c:257 #, c-format msgid "cannot subscript type %s because it is not an array" msgstr "no se puede poner subíndices al tipo %s porque no es un array" -#: parser/parse_node.c:358 parser/parse_node.c:395 +#: parser/parse_node.c:363 parser/parse_node.c:400 #, c-format msgid "array subscript must have type integer" msgstr "los subíndices de arrays deben tener tipo entero" -#: parser/parse_node.c:426 +#: parser/parse_node.c:431 #, c-format msgid "array assignment requires type %s but expression is of type %s" msgstr "la asignación de array debe tener tipo %s pero la expresión es de tipo %s" @@ -14965,27 +15443,32 @@ msgstr "el operador no es único: %s" msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgstr "No se pudo escoger el operador más adecuado. Puede ser necesario agregar conversiones explícitas de tipos." -#: parser/parse_oper.c:726 +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Ningún operador coincide en el nombre y tipo de argumento. Puede ser necesario agregar conversión explícita de tipos." + +#: parser/parse_oper.c:729 #, c-format -msgid "No operator matches the given name and argument type(s). You might need to add explicit type casts." -msgstr "Ningún operador coincide con el nombre y el tipo de los argumentos. Puede ser necesario agregar conversiones explícitas de tipos." +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ningún operador coincide en el nombre y tipos de argumentos. Puede ser necesario agregar conversión explícita de tipos." -#: parser/parse_oper.c:787 parser/parse_oper.c:909 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "el operador está inconcluso: %s" -#: parser/parse_oper.c:897 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "op ANY/ALL (array) requiere un array al lado derecho" -#: parser/parse_oper.c:939 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "op ANY/ALL (array) requiere un operador que entregue boolean" -#: parser/parse_oper.c:944 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "op ANY/ALL (array) requiere un operador que no retorne un conjunto" @@ -14995,158 +15478,165 @@ msgstr "op ANY/ALL (array) requiere un operador que no retorne un conjunto" msgid "inconsistent types deduced for parameter $%d" msgstr "para el parámetro $%d se dedujeron tipos de dato inconsistentes" -#: parser/parse_relation.c:176 +#: parser/parse_relation.c:179 #, c-format msgid "table reference \"%s\" is ambiguous" msgstr "la referencia a la tabla «%s» es ambigua" -#: parser/parse_relation.c:220 +#: parser/parse_relation.c:223 #, c-format msgid "table reference %u is ambiguous" msgstr "la referencia a la tabla %u es ambigua" -#: parser/parse_relation.c:419 +#: parser/parse_relation.c:422 #, c-format msgid "table name \"%s\" specified more than once" msgstr "el nombre de tabla «%s» fue especificado más de una vez" -#: parser/parse_relation.c:446 parser/parse_relation.c:3188 +#: parser/parse_relation.c:449 parser/parse_relation.c:3292 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "referencia a la entrada de la cláusula FROM para la tabla «%s» no válida" -#: parser/parse_relation.c:449 parser/parse_relation.c:3193 +#: parser/parse_relation.c:452 parser/parse_relation.c:3297 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "Hay una entrada para la tabla «%s», pero no puede ser referenciada desde esta parte de la consulta." -#: parser/parse_relation.c:451 +#: parser/parse_relation.c:454 #, c-format msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "El tipo de JOIN debe ser INNER o LEFT para una referencia LATERAL." -#: parser/parse_relation.c:727 +#: parser/parse_relation.c:730 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "la referencia a columna a sistema «%s» en una restricción check no es válida" -#: parser/parse_relation.c:1086 parser/parse_relation.c:1372 -#: parser/parse_relation.c:1941 +#: parser/parse_relation.c:741 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "no se puede usar la columna de sistema «%s» en una expresión de generación de columna" + +#: parser/parse_relation.c:1100 parser/parse_relation.c:1404 +#: parser/parse_relation.c:1985 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "la tabla «%s» tiene %d columnas pero se especificaron %d" -#: parser/parse_relation.c:1179 +#: parser/parse_relation.c:1187 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "Hay un elemento WITH llamado «%s», pero no puede ser referenciada desde esta parte de la consulta." -#: parser/parse_relation.c:1181 +#: parser/parse_relation.c:1189 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "Use WITH RECURSIVE, o reordene los elementos de WITH para eliminar referencias hacia adelante." -#: parser/parse_relation.c:1492 +#: parser/parse_relation.c:1525 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "sólo se permite una lista de definición de columnas en funciones que retornan «record»" -#: parser/parse_relation.c:1501 +#: parser/parse_relation.c:1534 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "la lista de definición de columnas es obligatoria para funciones que retornan «record»" -#: parser/parse_relation.c:1580 +#: parser/parse_relation.c:1620 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "la función «%s» en FROM tiene el tipo de retorno no soportado %s" -#: parser/parse_relation.c:1769 +#: parser/parse_relation.c:1811 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "la lista VALUES «%s» tiene %d columnas disponibles pero se especificaron %d" -#: parser/parse_relation.c:1824 +#: parser/parse_relation.c:1867 #, c-format msgid "joins can have at most %d columns" msgstr "los joins pueden tener a lo más %d columnas" -#: parser/parse_relation.c:1914 +#: parser/parse_relation.c:1958 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "la consulta WITH «%s» no tiene una cláusula RETURNING" -#: parser/parse_relation.c:2809 parser/parse_relation.c:2972 +#: parser/parse_relation.c:2899 parser/parse_relation.c:2937 +#: parser/parse_relation.c:2946 parser/parse_relation.c:3072 +#: parser/parse_relation.c:3082 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "no existe la columna %d en la relación «%s»" -#: parser/parse_relation.c:3191 +#: parser/parse_relation.c:3295 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Probablemente quiera hacer referencia al alias de la tabla «%s»." -#: parser/parse_relation.c:3199 +#: parser/parse_relation.c:3303 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "falta una entrada para la tabla «%s» en la cláusula FROM" -#: parser/parse_relation.c:3251 +#: parser/parse_relation.c:3355 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Probablemente quiera hacer referencia a la columna «%s.%s»." -#: parser/parse_relation.c:3253 +#: parser/parse_relation.c:3357 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "Hay una columna llamada «%s» en la tabla «%s», pero no puede ser referenciada desde esta parte de la consulta." -#: parser/parse_relation.c:3270 +#: parser/parse_relation.c:3374 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "Probablemente quiera hacer referencia a la columna «%s.%s» o la columna «%s.%s»." -#: parser/parse_target.c:483 parser/parse_target.c:775 +#: parser/parse_target.c:484 parser/parse_target.c:791 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "no se puede asignar a la columna de sistema «%s»" -#: parser/parse_target.c:511 +#: parser/parse_target.c:512 #, c-format msgid "cannot set an array element to DEFAULT" msgstr "no se puede definir un elemento de array a DEFAULT" -#: parser/parse_target.c:516 +#: parser/parse_target.c:517 #, c-format msgid "cannot set a subfield to DEFAULT" msgstr "no se puede definir un subcampo a DEFAULT" -#: parser/parse_target.c:585 +#: parser/parse_target.c:586 #, c-format msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "la columna «%s» es de tipo %s pero la expresión es de tipo %s" -#: parser/parse_target.c:759 +#: parser/parse_target.c:775 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" msgstr "no se puede asignar al campo «%s» de la columna «%s» porque su tipo %s no es un tipo compuesto" -#: parser/parse_target.c:768 +#: parser/parse_target.c:784 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgstr "no se puede asignar al campo «%s» de la columna «%s» porque no existe esa columna en el tipo de dato %s" -#: parser/parse_target.c:835 +#: parser/parse_target.c:861 #, c-format msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "la asignación de array a «%s» requiere tipo %s pero la expresión es de tipo %s" -#: parser/parse_target.c:845 +#: parser/parse_target.c:871 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "el subcampo «%s» es de tipo %s pero la expresión es de tipo %s" -#: parser/parse_target.c:1261 +#: parser/parse_target.c:1290 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "SELECT * sin especificar tablas no es válido" @@ -15166,7 +15656,7 @@ msgstr "la referencia a %%TYPE es inapropiada (demasiados nombres con punto): %s msgid "type reference %s converted to %s" msgstr "la referencia al tipo %s convertida a %s" -#: parser/parse_type.c:261 parser/parse_type.c:804 utils/cache/typcache.c:243 +#: parser/parse_type.c:261 parser/parse_type.c:840 utils/cache/typcache.c:374 #, c-format msgid "type \"%s\" is only a shell" msgstr "el tipo «%s» está inconcluso" @@ -15181,315 +15671,419 @@ msgstr "un modificador de tipo no está permitido para el tipo «%s»" msgid "type modifiers must be simple constants or identifiers" msgstr "los modificadores de tipo deben ser constantes simples o identificadores" -#: parser/parse_type.c:670 parser/parse_type.c:769 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "el nombre de tipo «%s» no es válido" -#: parser/parse_utilcmd.c:264 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:263 +#, c-format msgid "cannot create partitioned table as inheritance child" -msgstr "no se pueden crear tablas temporales en modo paralelo" +msgstr "no se puede crear una tabla particionada como hija de herencia" -#: parser/parse_utilcmd.c:434 +#: parser/parse_utilcmd.c:426 #, c-format msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" msgstr "%s creará una secuencia implícita «%s» para la columna serial «%s.%s»" -#: parser/parse_utilcmd.c:549 +#: parser/parse_utilcmd.c:550 #, c-format msgid "array of serial is not implemented" msgstr "array de serial no está implementado" -#: parser/parse_utilcmd.c:625 parser/parse_utilcmd.c:637 +#: parser/parse_utilcmd.c:627 parser/parse_utilcmd.c:639 #, c-format msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "las declaraciones NULL/NOT NULL no son coincidentes para la columna «%s» de la tabla «%s»" -#: parser/parse_utilcmd.c:649 +#: parser/parse_utilcmd.c:651 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "múltiples valores default especificados para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:670 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:668 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "las columnas identidad no está soportadas en tablas tipadas" + +#: parser/parse_utilcmd.c:672 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "las columnas identidad no están soportadas en particiones" + +#: parser/parse_utilcmd.c:681 +#, c-format msgid "multiple identity specifications for column \"%s\" of table \"%s\"" -msgstr "múltiples valores default especificados para columna «%s» de tabla «%s»" +msgstr "múltiples especificaciones de identidad para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:693 parser/parse_utilcmd.c:810 +#: parser/parse_utilcmd.c:700 #, c-format -msgid "primary key constraints are not supported on foreign tables" -msgstr "las restricciones de llave primaria no están soportadas en tablas foráneas" +msgid "generated columns are not supported on typed tables" +msgstr "las columnas generadas no están soportadas en tablas tipadas" + +#: parser/parse_utilcmd.c:704 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "las columnas generadas no están soportadas en particiones" + +#: parser/parse_utilcmd.c:709 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "múltiples cláusulas de generación especificadas para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:699 parser/parse_utilcmd.c:816 -#, fuzzy, c-format -msgid "primary key constraints are not supported on partitioned tables" +#: parser/parse_utilcmd.c:727 parser/parse_utilcmd.c:842 +#, c-format +msgid "primary key constraints are not supported on foreign tables" msgstr "las restricciones de llave primaria no están soportadas en tablas foráneas" -#: parser/parse_utilcmd.c:708 parser/parse_utilcmd.c:826 +#: parser/parse_utilcmd.c:736 parser/parse_utilcmd.c:852 #, c-format msgid "unique constraints are not supported on foreign tables" msgstr "las restricciones unique no están soportadas en tablas foráneas" -#: parser/parse_utilcmd.c:714 parser/parse_utilcmd.c:832 -#, fuzzy, c-format -msgid "unique constraints are not supported on partitioned tables" -msgstr "las restricciones unique no están soportadas en tablas foráneas" - -#: parser/parse_utilcmd.c:731 parser/parse_utilcmd.c:862 +#: parser/parse_utilcmd.c:781 #, c-format -msgid "foreign key constraints are not supported on foreign tables" -msgstr "las restricciones de llave foránea no están soportadas en tablas foráneas" +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "tanto el valor por omisión como identidad especificados para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:737 parser/parse_utilcmd.c:868 -#, fuzzy, c-format -msgid "foreign key constraints are not supported on partitioned tables" -msgstr "las restricciones de llave foránea no están soportadas en tablas foráneas" +#: parser/parse_utilcmd.c:789 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "tanto el valor por omisión como expresión de generación especificados para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:765 -#, fuzzy, c-format -msgid "both default and identity specified for column \"%s\" of table \"%s\"" -msgstr "múltiples valores default especificados para columna «%s» de tabla «%s»" +#: parser/parse_utilcmd.c:797 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "tanto identidad como expresión de generación especificados para columna «%s» de tabla «%s»" -#: parser/parse_utilcmd.c:842 +#: parser/parse_utilcmd.c:862 #, c-format msgid "exclusion constraints are not supported on foreign tables" -msgstr "las restricciones exclusion no están soportadas en tablas foráneas" +msgstr "las restricciones de exclusión no están soportadas en tablas foráneas" -#: parser/parse_utilcmd.c:848 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:868 +#, c-format msgid "exclusion constraints are not supported on partitioned tables" -msgstr "las restricciones exclusion no están soportadas en tablas foráneas" +msgstr "las restricciones de exclusión no están soportadas en tablas particionadas" -#: parser/parse_utilcmd.c:918 +#: parser/parse_utilcmd.c:932 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKE no está soportado para la creación de tablas foráneas" -#: parser/parse_utilcmd.c:1473 parser/parse_utilcmd.c:1549 +#: parser/parse_utilcmd.c:1064 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "La expresión de generación para la columna «%s» contiene una referencia a la fila completa (whole-row) de la tabla «%s»." + +#: parser/parse_utilcmd.c:1563 parser/parse_utilcmd.c:1670 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "El índice «%s» contiene una referencia a la fila completa (whole-row)." -#: parser/parse_utilcmd.c:1818 +#: parser/parse_utilcmd.c:2036 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "no se puede usar un índice existente en CREATE TABLE" -#: parser/parse_utilcmd.c:1838 +#: parser/parse_utilcmd.c:2056 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "el índice «%s» ya está asociado a una restricción" -#: parser/parse_utilcmd.c:1846 -#, c-format -msgid "index \"%s\" does not belong to table \"%s\"" -msgstr "el índice «%s» no pertenece a la tabla «%s»" - -#: parser/parse_utilcmd.c:1853 +#: parser/parse_utilcmd.c:2071 #, c-format msgid "index \"%s\" is not valid" msgstr "el índice «%s» no es válido" -#: parser/parse_utilcmd.c:1859 +#: parser/parse_utilcmd.c:2077 #, c-format msgid "\"%s\" is not a unique index" msgstr "«%s» no es un índice único" -#: parser/parse_utilcmd.c:1860 parser/parse_utilcmd.c:1867 -#: parser/parse_utilcmd.c:1874 parser/parse_utilcmd.c:1944 +#: parser/parse_utilcmd.c:2078 parser/parse_utilcmd.c:2085 +#: parser/parse_utilcmd.c:2092 parser/parse_utilcmd.c:2163 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "No se puede crear una restricción de llave primaria o única usando un índice así." -#: parser/parse_utilcmd.c:1866 +#: parser/parse_utilcmd.c:2084 #, c-format msgid "index \"%s\" contains expressions" msgstr "el índice «%s» contiene expresiones" -#: parser/parse_utilcmd.c:1873 +#: parser/parse_utilcmd.c:2091 #, c-format msgid "\"%s\" is a partial index" msgstr "«%s» es un índice parcial" -#: parser/parse_utilcmd.c:1885 +#: parser/parse_utilcmd.c:2103 #, c-format msgid "\"%s\" is a deferrable index" msgstr "«%s» no es un índice postergable (deferrable)" -#: parser/parse_utilcmd.c:1886 +#: parser/parse_utilcmd.c:2104 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "No se puede crear una restricción no postergable usando un índice postergable." -#: parser/parse_utilcmd.c:1943 +#: parser/parse_utilcmd.c:2162 #, c-format -msgid "index \"%s\" does not have default sorting behavior" -msgstr "el índice «%s» no tiene el comportamiento de ordenamiento por omisión" +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "el índice «%s» columna número %d no tiene comportamiento de ordenamiento por omisión" -#: parser/parse_utilcmd.c:2087 +#: parser/parse_utilcmd.c:2319 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "la columna «%s» aparece dos veces en llave primaria" -#: parser/parse_utilcmd.c:2093 +#: parser/parse_utilcmd.c:2325 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "la columna «%s» aparece dos veces en restricción unique" -#: parser/parse_utilcmd.c:2302 +#: parser/parse_utilcmd.c:2676 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "las expresiones y predicados de índice sólo pueden referirse a la tabla en indexación" -#: parser/parse_utilcmd.c:2348 +#: parser/parse_utilcmd.c:2722 #, c-format msgid "rules on materialized views are not supported" msgstr "las reglas en vistas materializadas no están soportadas" -#: parser/parse_utilcmd.c:2409 +#: parser/parse_utilcmd.c:2785 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "la condición WHERE de la regla no puede contener referencias a otras relaciones" -#: parser/parse_utilcmd.c:2481 +#: parser/parse_utilcmd.c:2859 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "las reglas con condiciones WHERE sólo pueden tener acciones SELECT, INSERT, UPDATE o DELETE" -#: parser/parse_utilcmd.c:2499 parser/parse_utilcmd.c:2598 -#: rewrite/rewriteHandler.c:500 rewrite/rewriteManip.c:1015 +#: parser/parse_utilcmd.c:2877 parser/parse_utilcmd.c:2976 +#: rewrite/rewriteHandler.c:501 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "las sentencias UNION/INTERSECT/EXCEPT condicionales no están implementadas" -#: parser/parse_utilcmd.c:2517 +#: parser/parse_utilcmd.c:2895 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "una regla ON SELECT no puede usar OLD" -#: parser/parse_utilcmd.c:2521 +#: parser/parse_utilcmd.c:2899 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "una regla ON SELECT no puede usar NEW" -#: parser/parse_utilcmd.c:2530 +#: parser/parse_utilcmd.c:2908 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "una regla ON INSERT no puede usar OLD" -#: parser/parse_utilcmd.c:2536 +#: parser/parse_utilcmd.c:2914 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "una regla ON DELETE no puede usar NEW" -#: parser/parse_utilcmd.c:2564 +#: parser/parse_utilcmd.c:2942 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "no se puede hacer referencia a OLD dentro de una consulta WITH" -#: parser/parse_utilcmd.c:2571 +#: parser/parse_utilcmd.c:2949 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "no se puede hacer referencia a NEW dentro de una consulta WITH" -#: parser/parse_utilcmd.c:3004 +#: parser/parse_utilcmd.c:3407 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "cláusula DEFERRABLE mal puesta" -#: parser/parse_utilcmd.c:3009 parser/parse_utilcmd.c:3024 +#: parser/parse_utilcmd.c:3412 parser/parse_utilcmd.c:3427 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "no se permiten múltiples cláusulas DEFERRABLE/NOT DEFERRABLE" -#: parser/parse_utilcmd.c:3019 +#: parser/parse_utilcmd.c:3422 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "la cláusula NOT DEFERRABLE está mal puesta" -#: parser/parse_utilcmd.c:3040 +#: parser/parse_utilcmd.c:3435 parser/parse_utilcmd.c:3461 gram.y:5529 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "una restricción declarada INITIALLY DEFERRED debe ser DEFERRABLE" + +#: parser/parse_utilcmd.c:3443 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "la cláusula INITIALLY DEFERRED está mal puesta" -#: parser/parse_utilcmd.c:3045 parser/parse_utilcmd.c:3071 +#: parser/parse_utilcmd.c:3448 parser/parse_utilcmd.c:3474 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "no se permiten múltiples cláusulas INITIALLY IMMEDIATE/DEFERRED" -#: parser/parse_utilcmd.c:3066 +#: parser/parse_utilcmd.c:3469 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "la cláusula INITIALLY IMMEDIATE está mal puesta" -#: parser/parse_utilcmd.c:3257 +#: parser/parse_utilcmd.c:3660 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE especifica un esquema (%s) diferente del que se está creando (%s)" -#: parser/parse_utilcmd.c:3316 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:3694 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "«la tabla %s» no está particionada" + +#: parser/parse_utilcmd.c:3701 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "el índice «%s» no está particionado" + +#: parser/parse_utilcmd.c:3735 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "una tabla particionada por hash no puede tener una partición default" + +#: parser/parse_utilcmd.c:3752 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "especificación de borde no válida para partición de hash" + +#: parser/parse_utilcmd.c:3758 partitioning/partbounds.c:2802 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "el módulo para una partición hash debe ser un entero positivo" + +#: parser/parse_utilcmd.c:3765 partitioning/partbounds.c:2810 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "remanente en partición hash debe ser menor que el módulo" + +#: parser/parse_utilcmd.c:3778 +#, c-format msgid "invalid bound specification for a list partition" -msgstr "especificación de formato no válida para un valor de interval" +msgstr "especificación de borde no válida para partición de lista" -#: parser/parse_utilcmd.c:3373 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:3831 +#, c-format msgid "invalid bound specification for a range partition" -msgstr "especificación de formato no válida para un valor de interval" +msgstr "especificación de borde no válida para partición de rango" -#: parser/parse_utilcmd.c:3379 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:3837 +#, c-format msgid "FROM must specify exactly one value per partitioning column" -msgstr "debe especificar al menos una columna" +msgstr "FROM debe especificar exactamente un valor por cada columna de particionado" -#: parser/parse_utilcmd.c:3383 -#, fuzzy, c-format +#: parser/parse_utilcmd.c:3841 +#, c-format msgid "TO must specify exactly one value per partitioning column" -msgstr "debe especificar al menos una columna" +msgstr "TO debe especificar exactamente un valor por cada columna de particionado" -#: parser/parse_utilcmd.c:3400 parser/parse_utilcmd.c:3414 +#: parser/parse_utilcmd.c:3955 #, c-format -msgid "cannot specify finite value after UNBOUNDED" -msgstr "" - -#: parser/parse_utilcmd.c:3456 parser/parse_utilcmd.c:3470 -#, fuzzy, c-format msgid "cannot specify NULL in range bound" -msgstr "no se puede especificar NULL en modo BINARY" +msgstr "no se puede especificar NULL en borde de rango" -#: parser/parse_utilcmd.c:3513 parser/parse_utilcmd.c:3525 -#, fuzzy, c-format -msgid "specified value cannot be cast to type %s for column \"%s\"" -msgstr "no se puede alterar el tipo de la columna «%s» dos veces" +#: parser/parse_utilcmd.c:4004 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "cada borde que sigue a un MAXVALUE debe ser también MAXVALUE" -#: parser/parse_utilcmd.c:3527 -#, fuzzy, c-format -#| msgid "This may be because of a non-immutable index expression." -msgid "The cast requires a non-immutable conversion." -msgstr "Esto puede deberse a una expresión de índice no inmutable." +#: parser/parse_utilcmd.c:4011 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "cada borde que siga a un MINVALUE debe ser también MINVALUE" -#: parser/parse_utilcmd.c:3528 +#: parser/parse_utilcmd.c:4046 #, c-format -msgid "Try putting the literal value in single quotes." -msgstr "" +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "el ordenamiento (collation) del valor de borde de partición para la columna «%s» no coincide con el ordenamiento de la llave de particionamiento «%s»" + +#: parser/parse_utilcmd.c:4063 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "el valor especificado no puede ser convertido al tipo %s para la columna «%s»" #: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "el identificador «%s» se truncará a «%s»" -#: port/pg_shmem.c:196 port/sysv_shmem.c:196 +#: partitioning/partbounds.c:959 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "la partición «%s» está en conflicto con la partición default «%s» existente" + +#: partitioning/partbounds.c:1018 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "cada módulo de partición hash debe ser un factor del próximo mayor módulo" + +#: partitioning/partbounds.c:1114 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "borde de rango vació especificado para la partición «%s»" + +#: partitioning/partbounds.c:1116 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "El límite inferior %s especificado es mayor o igual al límite superior %s." + +#: partitioning/partbounds.c:1213 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "la partición «%s» traslaparía con la partición «%s»" + +#: partitioning/partbounds.c:1311 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "se omitió recorrer la tabla foránea «%s» que es una partición de la partición default «%s»" + +#: partitioning/partbounds.c:1348 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "la restricción de partición actualizada para la partición default «%s» sería violada por alguna fila" + +#: partitioning/partbounds.c:2806 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "remanente en partición hash debe ser un entero no negativo" + +#: partitioning/partbounds.c:2833 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "«%s» es una tabla particionada por hash" + +#: partitioning/partbounds.c:2844 partitioning/partbounds.c:2961 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "el número de columnas de particionamiento (%d) no coincide con el número de llaves de particionamiento provistas (%d)" + +#: partitioning/partbounds.c:2866 partitioning/partbounds.c:2898 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "la columna %d de la llave de particionamiento tiene tipo «%s», pero el valor dado es de tipo «%s»" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 #, c-format msgid "could not create shared memory segment: %m" msgstr "no se pudo crear el segmento de memoria compartida: %m" -#: port/pg_shmem.c:197 port/sysv_shmem.c:197 +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "La llamada a sistema fallida fue shmget(key=%lu, size=%zu, 0%o)." -#: port/pg_shmem.c:201 port/sysv_shmem.c:201 +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" @@ -15498,7 +16092,7 @@ msgstr "" "Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedió el parámetro SHMMAX del kernel, o posiblemente que es menor que el parámetro SHMMIN del kernel.\n" "La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." -#: port/pg_shmem.c:208 port/sysv_shmem.c:208 +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" @@ -15507,7 +16101,7 @@ msgstr "" "Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedió el parámetro SHMALL del kernel. Puede ser necesario reconfigurar el kernel con un SHMALL mayor.\n" "La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." -#: port/pg_shmem.c:214 port/sysv_shmem.c:214 +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 #, c-format msgid "" "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" @@ -15516,22 +16110,32 @@ msgstr "" "Este error *no* significa que se haya quedado sin espacio en disco. Ocurre cuando se han usado todos los IDs de memoria compartida disponibles, en cuyo caso puede incrementar el parámetro SHMMNI del kernel, o bien porque se ha alcanzado el límite total de memoria compartida.\n" "La documentación de PostgreSQL contiene más información acerca de la configuración de memoria compartida." -#: port/pg_shmem.c:505 port/sysv_shmem.c:505 +#: port/pg_shmem.c:577 port/sysv_shmem.c:577 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "no se pudo mapear memoria compartida anónima: %m" -#: port/pg_shmem.c:507 port/sysv_shmem.c:507 +#: port/pg_shmem.c:579 port/sysv_shmem.c:579 #, c-format msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." msgstr "Este error normalmente significa que la petición de un segmento de memoria compartida de PostgreSQL excedía la memoria disponible, el espacio de intercambio (swap), o las huge pages. Para reducir el tamaño de la petición (actualmente %zu bytes), reduzca el uso de memoria compartida de PostgreSQL, quizás reduciendo el parámetro shared_buffers o el parámetro max_connections." -#: port/pg_shmem.c:573 port/sysv_shmem.c:573 port/win32_shmem.c:134 +#: port/pg_shmem.c:639 port/sysv_shmem.c:639 #, c-format msgid "huge pages not supported on this platform" msgstr "las huge pages no están soportados en esta plataforma" -#: port/pg_shmem.c:668 port/sysv_shmem.c:668 +#: port/pg_shmem.c:700 port/sysv_shmem.c:700 utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "el bloque de memoria compartida preexistente (clave %lu, ID %lu) aún está en uso" + +#: port/pg_shmem.c:703 port/sysv_shmem.c:703 utils/init/miscinit.c:1071 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Termine cualquier proceso de servidor asociado al directorio de datos «%s»." + +#: port/pg_shmem.c:754 port/sysv_shmem.c:754 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "no se pudo hacer stat al directorio de datos «%s»: %m" @@ -15586,17 +16190,17 @@ msgstr "se escribió el volcado de caída en el archivo «%s».\n" msgid "could not write crash dump to file \"%s\": error code %lu\n" msgstr "no se pudo escribir el volcado de caída al archivo «%s»: código de error %lu\n" -#: port/win32/signal.c:194 +#: port/win32/signal.c:196 #, c-format msgid "could not create signal listener pipe for PID %d: error code %lu" msgstr "no se pudo crear tubería para escuchar señales para el PID %d: código de error %lu" -#: port/win32/signal.c:274 port/win32/signal.c:306 +#: port/win32/signal.c:277 port/win32/signal.c:309 #, c-format msgid "could not create signal listener pipe: error code %lu; retrying\n" msgstr "no se pudo crear tubería para escuchar señales: código de error %lu; reintentando\n" -#: port/win32/signal.c:317 +#: port/win32/signal.c:320 #, c-format msgid "could not create signal dispatch thread: error code %lu\n" msgstr "no se pudo crear thread de despacho de señales: código de error %lu\n" @@ -15621,155 +16225,187 @@ msgstr "no se pudo desbloquear semáforo: código de error %lu" msgid "could not try-lock semaphore: error code %lu" msgstr "no se pudo intentar-bloquear (try-lock) el semáforo: código de error %lu" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "no se pudo activar el privilegio «Bloquear páginas en la memoria»: código de error %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "La llamada a sistema fallida fue %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "no se pudo activar el privilegio «Bloquear páginas en la memoria»" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Asigne el privilegio «Bloquear páginas en la memoria» a la cuenta de usuario de Windows que ejecuta PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "el procesador no soporta páginas grandes" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "desactivando «huge pages»" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "no se pudo crear el segmento de memoria compartida: código de error %lu" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:303 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "La llamada a sistema fallida fue CreateFileMapping(size=%zu, name=%s)." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:328 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "el bloque de memoria compartida preexistente aún está en uso" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:329 #, c-format msgid "Check if there are any old server processes still running, and terminate them." msgstr "Verifique si hay procesos de servidor antiguos aún en funcionamiento, y termínelos." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:339 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "La llamada a sistema fallida fue DuplicateHandle." -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:357 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "La llamada a sistema fallida fue MapViewOfFileEx." -#: postmaster/autovacuum.c:416 +#: postmaster/autovacuum.c:405 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "no se pudo iniciar el lanzador autovacuum: %m" -#: postmaster/autovacuum.c:452 +#: postmaster/autovacuum.c:441 #, c-format msgid "autovacuum launcher started" msgstr "lanzador de autovacuum iniciado" -#: postmaster/autovacuum.c:839 +#: postmaster/autovacuum.c:819 #, c-format msgid "autovacuum launcher shutting down" -msgstr "apagando lanzador de autovacuum" +msgstr "lanzador de autovacuum apagándose" -#: postmaster/autovacuum.c:1501 +#: postmaster/autovacuum.c:1481 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "no se pudo lanzar el proceso «autovacuum worker»: %m" -#: postmaster/autovacuum.c:1707 +#: postmaster/autovacuum.c:1687 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "autovacuum: procesando la base de datos «%s»" -#: postmaster/autovacuum.c:2281 -#, fuzzy, c-format +#: postmaster/autovacuum.c:2256 +#, c-format msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" -msgstr "autovacuum: eliminando la tabla temporal huérfana «%s».«%s» en la base de datos «%s»" +msgstr "autovacuum: eliminando tabla temporal huérfana «%s.%s.%s»" -#: postmaster/autovacuum.c:2487 +#: postmaster/autovacuum.c:2485 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "vacuum automático de la tabla «%s.%s.%s»" -#: postmaster/autovacuum.c:2490 +#: postmaster/autovacuum.c:2488 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "análisis automático de la tabla «%s.%s.%s»" -#: postmaster/autovacuum.c:2701 -#, fuzzy, c-format +#: postmaster/autovacuum.c:2681 +#, c-format msgid "processing work entry for relation \"%s.%s.%s\"" -msgstr "permiso denegado a la relación %s" +msgstr "procesando elemento de tarea de la tabla «%s.%s.%s»" -#: postmaster/autovacuum.c:3345 +#: postmaster/autovacuum.c:3262 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "autovacuum no fue iniciado debido a un error de configuración" -#: postmaster/autovacuum.c:3346 +#: postmaster/autovacuum.c:3263 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Active la opción «track_counts»." -#: postmaster/bgworker.c:393 postmaster/bgworker.c:856 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" -msgstr "registrando el «background worker» «%s»" +msgstr "registrando el proceso ayudante «%s»" -#: postmaster/bgworker.c:425 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" -msgstr "des-registrando el «background worker» «%s»" +msgstr "des-registrando el proceso ayudante «%s»" -#: postmaster/bgworker.c:590 +#: postmaster/bgworker.c:592 #, c-format msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" -msgstr "«background worker» «%s»: debe acoplarse a memoria compartida para poder solicitar una conexión a base de datos" +msgstr "proceso ayudante «%s»: debe acoplarse a memoria compartida para poder solicitar una conexión a base de datos" -#: postmaster/bgworker.c:599 +#: postmaster/bgworker.c:601 #, c-format msgid "background worker \"%s\": cannot request database access if starting at postmaster start" -msgstr "«background worker» «%s»: no se puede solicitar una conexión a base de datos si está iniciando en el momento de inicio de postmaster" +msgstr "proceso ayudante «%s»: no se puede solicitar una conexión a base de datos si está iniciando en el momento de inicio de postmaster" -#: postmaster/bgworker.c:613 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" -msgstr "«background worker» «%s»: intervalo de reinicio no válido" +msgstr "proceso ayudante «%s»: intervalo de reinicio no válido" -#: postmaster/bgworker.c:628 -#, fuzzy, c-format +#: postmaster/bgworker.c:630 +#, c-format msgid "background worker \"%s\": parallel workers may not be configured for restart" -msgstr "«background worker» «%s»: intervalo de reinicio no válido" +msgstr "proceso ayudante «%s»: los ayudantes paralelos no pueden ser configurados «restart»" -#: postmaster/bgworker.c:673 +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" -msgstr "terminando el «background worker» «%s» debido a una orden del administrador" +msgstr "terminando el proceso ayudante «%s» debido a una orden del administrador" -#: postmaster/bgworker.c:864 +#: postmaster/bgworker.c:863 #, c-format msgid "background worker \"%s\": must be registered in shared_preload_libraries" -msgstr "«background worker» «%s»: debe ser registrado en shared_preload_libraries" +msgstr "proceso ayudante «%s»: debe ser registrado en shared_preload_libraries" -#: postmaster/bgworker.c:876 +#: postmaster/bgworker.c:875 #, c-format msgid "background worker \"%s\": only dynamic background workers can request notification" -msgstr "«background worker» «%s»: sólo los «background worker» dinámicos pueden pedir notificaciones" +msgstr "proceso ayudante «%s»: sólo los ayudantes dinámicos pueden pedir notificaciones" -#: postmaster/bgworker.c:891 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" -msgstr "demasiados «background workers»" +msgstr "demasiados procesos ayudantes" -#: postmaster/bgworker.c:892 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "Up to %d background workers can be registered with the current settings." -msgstr[0] "Hasta %d «background worker» puede registrarse con la configuración actual." -msgstr[1] "Hasta %d «background workers» pueden registrarse con la configuración actual." +msgstr[0] "Hasta %d proceso ayudante puede registrarse con la configuración actual." +msgstr[1] "Hasta %d procesos ayudantes pueden registrarse con la configuración actual." # FIXME a %s would be nice here -#: postmaster/bgworker.c:896 +#: postmaster/bgworker.c:895 #, c-format msgid "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "Considere incrementar el parámetro de configuración «max_worker_processes»." -#: postmaster/checkpointer.c:464 +#: postmaster/checkpointer.c:458 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" @@ -15777,814 +16413,784 @@ msgstr[0] "los puntos de control están ocurriendo con demasiada frecuencia (cad msgstr[1] "los puntos de control están ocurriendo con demasiada frecuencia (cada %d segundos)" # FIXME a %s would be nice here -#: postmaster/checkpointer.c:468 +#: postmaster/checkpointer.c:462 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "Considere incrementar el parámetro de configuración «max_wal_size»." -#: postmaster/checkpointer.c:1087 +#: postmaster/checkpointer.c:1081 #, c-format msgid "checkpoint request failed" msgstr "falló la petición de punto de control" -#: postmaster/checkpointer.c:1088 +#: postmaster/checkpointer.c:1082 #, c-format msgid "Consult recent messages in the server log for details." msgstr "Vea los mensajes recientes en el registro del servidor para obtener más detalles." -#: postmaster/checkpointer.c:1283 +#: postmaster/checkpointer.c:1267 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "la cola de peticiones de fsync fue compactada de %d a %d elementos" -#: postmaster/pgarch.c:148 +#: postmaster/pgarch.c:159 #, c-format msgid "could not fork archiver: %m" msgstr "no se pudo lanzar el proceso archivador: %m" -#: postmaster/pgarch.c:456 +#: postmaster/pgarch.c:470 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "archive_mode activado, pero archive_command no está definido" -#: postmaster/pgarch.c:484 -#, fuzzy, c-format +#: postmaster/pgarch.c:492 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "eliminando archivo de estado huérfano «%s»" + +#: postmaster/pgarch.c:502 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "la eliminación del archivo de estado huérfano «%s» falló demasiadas veces, se tratará de nuevo después" + +#: postmaster/pgarch.c:538 +#, c-format msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" -msgstr "el archivado del archivo de transacción «%s» falló demasiadas veces, se reintentará nuevamente más tarde" +msgstr "el archivado del archivo de WAL «%s» falló demasiadas veces, se tratará de nuevo más tarde" -#: postmaster/pgarch.c:587 +#: postmaster/pgarch.c:639 #, c-format msgid "archive command failed with exit code %d" msgstr "la orden de archivado falló con código de retorno %d" -#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 -#: postmaster/pgarch.c:612 postmaster/pgarch.c:621 +#: postmaster/pgarch.c:641 postmaster/pgarch.c:651 postmaster/pgarch.c:657 +#: postmaster/pgarch.c:666 #, c-format msgid "The failed archive command was: %s" msgstr "La orden fallida era: «%s»" -#: postmaster/pgarch.c:596 +#: postmaster/pgarch.c:648 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "la orden de archivado fue terminada por una excepción 0x%X" -#: postmaster/pgarch.c:598 postmaster/postmaster.c:3567 +#: postmaster/pgarch.c:650 postmaster/postmaster.c:3669 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "Vea el archivo «ntstatus.h» para una descripción del valor hexadecimal." -#: postmaster/pgarch.c:603 +#: postmaster/pgarch.c:655 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "la orden de archivado fue terminada por una señal %d: %s" -#: postmaster/pgarch.c:610 -#, c-format -msgid "archive command was terminated by signal %d" -msgstr "la orden de archivado fue terminada por una señal %d" - -#: postmaster/pgarch.c:619 +#: postmaster/pgarch.c:664 #, c-format msgid "archive command exited with unrecognized status %d" -msgstr "la orden de archivado fue terminada con código no reconocido %d" - -#: postmaster/pgarch.c:679 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "no se pudo abrir el directorio de estado de archivado «%s»: %m" +msgstr "la orden de archivado fue terminada con código %d no reconocido" -#: postmaster/pgstat.c:395 +#: postmaster/pgstat.c:396 #, c-format msgid "could not resolve \"localhost\": %s" msgstr "no se pudo resolver «localhost»: %s" -#: postmaster/pgstat.c:418 +#: postmaster/pgstat.c:419 #, c-format msgid "trying another address for the statistics collector" msgstr "intentando otra dirección para el recolector de estadísticas" -#: postmaster/pgstat.c:427 +#: postmaster/pgstat.c:428 #, c-format msgid "could not create socket for statistics collector: %m" msgstr "no se pudo crear el socket para el recolector de estadísticas: %m" -#: postmaster/pgstat.c:439 +#: postmaster/pgstat.c:440 #, c-format msgid "could not bind socket for statistics collector: %m" msgstr "no se pudo enlazar (bind) el socket para el recolector de estadísticas: %m" -#: postmaster/pgstat.c:450 +#: postmaster/pgstat.c:451 #, c-format msgid "could not get address of socket for statistics collector: %m" msgstr "no se pudo obtener la dirección del socket de estadísticas: %m" -#: postmaster/pgstat.c:466 +#: postmaster/pgstat.c:467 #, c-format msgid "could not connect socket for statistics collector: %m" msgstr "no se pudo conectar el socket para el recolector de estadísticas: %m" -#: postmaster/pgstat.c:487 +#: postmaster/pgstat.c:488 #, c-format msgid "could not send test message on socket for statistics collector: %m" msgstr "no se pudo enviar el mensaje de prueba al recolector de estadísticas: %m" -#: postmaster/pgstat.c:513 +#: postmaster/pgstat.c:514 #, c-format msgid "select() failed in statistics collector: %m" msgstr "select() falló en el recolector de estadísticas: %m" -#: postmaster/pgstat.c:528 +#: postmaster/pgstat.c:529 #, c-format msgid "test message did not get through on socket for statistics collector" msgstr "el mensaje de prueba al recolector de estadísticas no ha sido recibido en el socket" -#: postmaster/pgstat.c:543 +#: postmaster/pgstat.c:544 #, c-format msgid "could not receive test message on socket for statistics collector: %m" msgstr "no se pudo recibir el mensaje de prueba en el socket del recolector de estadísticas: %m" -#: postmaster/pgstat.c:553 +#: postmaster/pgstat.c:554 #, c-format msgid "incorrect test message transmission on socket for statistics collector" msgstr "transmisión del mensaje de prueba incorrecta en el socket del recolector de estadísticas" -#: postmaster/pgstat.c:576 +#: postmaster/pgstat.c:577 #, c-format msgid "could not set statistics collector socket to nonblocking mode: %m" msgstr "no se pudo poner el socket de estadísticas en modo no bloqueante: %m" -#: postmaster/pgstat.c:615 +#: postmaster/pgstat.c:616 #, c-format msgid "disabling statistics collector for lack of working socket" msgstr "desactivando el recolector de estadísticas por falla del socket" -#: postmaster/pgstat.c:762 +#: postmaster/pgstat.c:763 #, c-format msgid "could not fork statistics collector: %m" msgstr "no se pudo crear el proceso para el recolector de estadísticas: %m" -#: postmaster/pgstat.c:1342 +#: postmaster/pgstat.c:1347 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "destino de reset no reconocido: «%s»" -#: postmaster/pgstat.c:1343 +#: postmaster/pgstat.c:1348 #, c-format msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "El destino debe ser «archiver» o «bgwriter»." -#: postmaster/pgstat.c:4287 +#: postmaster/pgstat.c:4534 #, c-format msgid "could not read statistics message: %m" msgstr "no se pudo leer un mensaje de estadísticas: %m" -#: postmaster/pgstat.c:4619 postmaster/pgstat.c:4776 +#: postmaster/pgstat.c:4875 postmaster/pgstat.c:5032 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "no se pudo abrir el archivo temporal de estadísticas «%s»: %m" -#: postmaster/pgstat.c:4686 postmaster/pgstat.c:4821 +#: postmaster/pgstat.c:4942 postmaster/pgstat.c:5077 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "no se pudo escribir el archivo temporal de estadísticas «%s»: %m" -#: postmaster/pgstat.c:4695 postmaster/pgstat.c:4830 +#: postmaster/pgstat.c:4951 postmaster/pgstat.c:5086 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "no se pudo cerrar el archivo temporal de estadísticas «%s»: %m" -#: postmaster/pgstat.c:4703 postmaster/pgstat.c:4838 +#: postmaster/pgstat.c:4959 postmaster/pgstat.c:5094 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "no se pudo cambiar el nombre al archivo temporal de estadísticas de «%s» a «%s»: %m" -#: postmaster/pgstat.c:4927 postmaster/pgstat.c:5133 postmaster/pgstat.c:5286 +#: postmaster/pgstat.c:5183 postmaster/pgstat.c:5389 postmaster/pgstat.c:5542 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "no se pudo abrir el archivo de estadísticas «%s»: %m" -#: postmaster/pgstat.c:4939 postmaster/pgstat.c:4949 postmaster/pgstat.c:4970 -#: postmaster/pgstat.c:4992 postmaster/pgstat.c:5007 postmaster/pgstat.c:5070 -#: postmaster/pgstat.c:5145 postmaster/pgstat.c:5165 postmaster/pgstat.c:5183 -#: postmaster/pgstat.c:5199 postmaster/pgstat.c:5217 postmaster/pgstat.c:5233 -#: postmaster/pgstat.c:5298 postmaster/pgstat.c:5310 postmaster/pgstat.c:5322 -#: postmaster/pgstat.c:5347 postmaster/pgstat.c:5369 +#: postmaster/pgstat.c:5195 postmaster/pgstat.c:5205 postmaster/pgstat.c:5226 +#: postmaster/pgstat.c:5248 postmaster/pgstat.c:5263 postmaster/pgstat.c:5326 +#: postmaster/pgstat.c:5401 postmaster/pgstat.c:5421 postmaster/pgstat.c:5439 +#: postmaster/pgstat.c:5455 postmaster/pgstat.c:5473 postmaster/pgstat.c:5489 +#: postmaster/pgstat.c:5554 postmaster/pgstat.c:5566 postmaster/pgstat.c:5578 +#: postmaster/pgstat.c:5603 postmaster/pgstat.c:5625 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "el archivo de estadísticas «%s» está corrupto" -#: postmaster/pgstat.c:5498 +#: postmaster/pgstat.c:5754 #, c-format msgid "using stale statistics instead of current ones because stats collector is not responding" msgstr "usando estadísticas añejas en vez de actualizadas porque el recolector de estadísticas no está respondiendo" -#: postmaster/pgstat.c:5825 +#: postmaster/pgstat.c:6081 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "el hash de bases de datos se corrompió durante la finalización; abortando" -#: postmaster/postmaster.c:710 +#: postmaster/postmaster.c:712 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s: argumento no válido para la opción -f: «%s»\n" -#: postmaster/postmaster.c:796 +#: postmaster/postmaster.c:798 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s: argumento no válido para la opción -t: «%s»\n" -#: postmaster/postmaster.c:847 +#: postmaster/postmaster.c:849 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s: argumento no válido: «%s»\n" -#: postmaster/postmaster.c:886 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s: superuser_reserved_connections debe ser menor que max_connections\n" - #: postmaster/postmaster.c:891 #, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_senders debe ser menor que max_connections\n" +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) debe ser menor que max_connections (%d)\n" -#: postmaster/postmaster.c:896 +#: postmaster/postmaster.c:898 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "el archivador de WAL no puede activarse cuando wal_level es «minimal»" -#: postmaster/postmaster.c:899 +#: postmaster/postmaster.c:901 #, c-format msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" msgstr "el flujo de WAL (max_wal_senders > 0) requiere wal_level «replica» o «logical»" -#: postmaster/postmaster.c:907 +#: postmaster/postmaster.c:909 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s: las tablas de palabras clave de fecha no son válidas, arréglelas\n" -#: postmaster/postmaster.c:1010 postmaster/postmaster.c:1108 -#: utils/init/miscinit.c:1455 +#: postmaster/postmaster.c:998 +#, c-format +msgid "starting %s" +msgstr "iniciando %s" + +#: postmaster/postmaster.c:1027 postmaster/postmaster.c:1125 +#: utils/init/miscinit.c:1551 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "la sintaxis de lista no es válida para el parámetro «%s»" -#: postmaster/postmaster.c:1041 +#: postmaster/postmaster.c:1058 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "no se pudo crear el socket de escucha para «%s»" -#: postmaster/postmaster.c:1047 +#: postmaster/postmaster.c:1064 #, c-format msgid "could not create any TCP/IP sockets" msgstr "no se pudo crear ningún socket TCP/IP" -#: postmaster/postmaster.c:1130 +#: postmaster/postmaster.c:1147 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "no se pudo crear el socket de dominio Unix en el directorio «%s»" -#: postmaster/postmaster.c:1136 +#: postmaster/postmaster.c:1153 #, c-format msgid "could not create any Unix-domain sockets" msgstr "no se pudo crear ningún socket de dominio Unix" -#: postmaster/postmaster.c:1148 +#: postmaster/postmaster.c:1165 #, c-format msgid "no socket created for listening" msgstr "no se creó el socket de atención" -#: postmaster/postmaster.c:1188 +#: postmaster/postmaster.c:1205 #, c-format msgid "could not create I/O completion port for child queue" msgstr "no se pudo crear el port E/S de reporte de completitud para la cola de procesos hijos" -#: postmaster/postmaster.c:1217 +#: postmaster/postmaster.c:1234 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: no se pudo cambiar los permisos del archivo de PID externo «%s»: %s\n" -#: postmaster/postmaster.c:1221 +#: postmaster/postmaster.c:1238 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: no pudo escribir en el archivo externo de PID «%s»: %s\n" -#: postmaster/postmaster.c:1278 +#: postmaster/postmaster.c:1298 #, c-format msgid "ending log output to stderr" msgstr "terminando la salida de registro a stderr" -#: postmaster/postmaster.c:1279 +#: postmaster/postmaster.c:1299 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "La salida futura del registro será enviada al destino de log «%s»." -#: postmaster/postmaster.c:1305 utils/init/postinit.c:213 +#: postmaster/postmaster.c:1325 utils/init/postinit.c:216 #, c-format msgid "could not load pg_hba.conf" msgstr "no se pudo cargar pg_hba.conf" -#: postmaster/postmaster.c:1331 +#: postmaster/postmaster.c:1351 #, c-format msgid "postmaster became multithreaded during startup" msgstr "postmaster se volvió multi-hilo durante la partida" -#: postmaster/postmaster.c:1332 +#: postmaster/postmaster.c:1352 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "Defina la variable de ambiente LC_ALL a un valor válido." -#: postmaster/postmaster.c:1437 +#: postmaster/postmaster.c:1453 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s: no se pudo localizar el ejecutable postgres correspondiente" -#: postmaster/postmaster.c:1460 utils/misc/tzparser.c:341 +#: postmaster/postmaster.c:1476 utils/misc/tzparser.c:341 #, c-format msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." msgstr "Esto puede indicar una instalación de PostgreSQL incompleta, o que el archivo «%s» ha sido movido de la ubicación adecuada." -#: postmaster/postmaster.c:1488 +#: postmaster/postmaster.c:1503 #, c-format -msgid "data directory \"%s\" does not exist" -msgstr "no existe el directorio de datos «%s»" +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: no se pudo encontrar el sistema de base de datos\n" +"Se esperaba encontrar en el directorio PGDATA «%s»,\n" +"pero no se pudo abrir el archivo «%s»: %s\n" -#: postmaster/postmaster.c:1493 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "no se pudo obtener los permisos del directorio «%s»: %m" - -#: postmaster/postmaster.c:1501 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "el directorio de datos especificado «%s» no es un directorio" - -#: postmaster/postmaster.c:1517 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "el directorio de datos «%s» tiene dueño equivocado" - -#: postmaster/postmaster.c:1519 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "El servidor debe ser iniciado por el usuario dueño del directorio de datos." - -#: postmaster/postmaster.c:1539 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "el directorio de datos «%s» tiene acceso para el grupo u otros" - -#: postmaster/postmaster.c:1541 -#, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "Los permisos deberían ser u=rwx (0700)." - -#: postmaster/postmaster.c:1552 -#, c-format -msgid "" -"%s: could not find the database system\n" -"Expected to find it in the directory \"%s\",\n" -"but could not open file \"%s\": %s\n" -msgstr "" -"%s: no se pudo encontrar el sistema de base de datos.\n" -"Se esperaba encontrar en el directorio PGDATA «%s»,\n" -"pero no se pudo abrir el archivo «%s»: %s\n" - -#: postmaster/postmaster.c:1729 +#: postmaster/postmaster.c:1680 #, c-format msgid "select() failed in postmaster: %m" msgstr "select() falló en postmaster: %m" -#: postmaster/postmaster.c:1884 +#: postmaster/postmaster.c:1835 #, c-format msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "ejecutando un apagado inmediato porque el archivo de bloqueo del directorio de datos no es válido" -#: postmaster/postmaster.c:1962 postmaster/postmaster.c:1993 +#: postmaster/postmaster.c:1934 postmaster/postmaster.c:1965 #, c-format msgid "incomplete startup packet" msgstr "el paquete de inicio está incompleto" -#: postmaster/postmaster.c:1974 +#: postmaster/postmaster.c:1946 #, c-format msgid "invalid length of startup packet" msgstr "el de paquete de inicio tiene largo incorrecto" -#: postmaster/postmaster.c:2032 +#: postmaster/postmaster.c:2004 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "no se pudo enviar la respuesta de negociación SSL: %m" -#: postmaster/postmaster.c:2061 +#: postmaster/postmaster.c:2031 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "no se pudo enviar la respuesta de negociación GSSAPI: %m" + +#: postmaster/postmaster.c:2056 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "el protocolo %u.%u no está soportado: servidor soporta %u.0 hasta %u.%u" -#: postmaster/postmaster.c:2124 utils/misc/guc.c:5759 utils/misc/guc.c:5852 -#: utils/misc/guc.c:7153 utils/misc/guc.c:9907 utils/misc/guc.c:9941 +#: postmaster/postmaster.c:2120 utils/misc/guc.c:6574 utils/misc/guc.c:6610 +#: utils/misc/guc.c:6680 utils/misc/guc.c:8006 utils/misc/guc.c:10828 +#: utils/misc/guc.c:10862 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "valor no válido para el parámetro «%s»: «%s»" -#: postmaster/postmaster.c:2127 +#: postmaster/postmaster.c:2123 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "Los valores válidos son: «false», 0, «true», 1, «database»." -#: postmaster/postmaster.c:2147 +#: postmaster/postmaster.c:2168 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "el paquete de inicio no es válido: se esperaba un terminador en el último byte" -#: postmaster/postmaster.c:2175 +#: postmaster/postmaster.c:2206 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "no se especifica un nombre de usuario en el paquete de inicio" -#: postmaster/postmaster.c:2234 +#: postmaster/postmaster.c:2265 #, c-format msgid "the database system is starting up" msgstr "el sistema de base de datos está iniciándose" -#: postmaster/postmaster.c:2239 +#: postmaster/postmaster.c:2270 #, c-format msgid "the database system is shutting down" msgstr "el sistema de base de datos está apagándose" -#: postmaster/postmaster.c:2244 +#: postmaster/postmaster.c:2275 #, c-format msgid "the database system is in recovery mode" msgstr "el sistema de base de datos está en modo de recuperación" -#: postmaster/postmaster.c:2249 storage/ipc/procarray.c:291 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:338 +#: postmaster/postmaster.c:2280 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:363 #, c-format msgid "sorry, too many clients already" msgstr "lo siento, ya tenemos demasiados clientes" -#: postmaster/postmaster.c:2311 +#: postmaster/postmaster.c:2370 #, c-format msgid "wrong key in cancel request for process %d" msgstr "llave incorrecta en la petición de cancelación para el proceso %d" -#: postmaster/postmaster.c:2319 +#: postmaster/postmaster.c:2382 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "el PID %d en la petición de cancelación no coincidió con ningún proceso" -#: postmaster/postmaster.c:2530 +#: postmaster/postmaster.c:2629 #, c-format msgid "received SIGHUP, reloading configuration files" -msgstr "se recibió SIGHUP, releyendo el archivo de configuración" +msgstr "se recibió SIGHUP, volviendo a cargar archivos de configuración" -#: postmaster/postmaster.c:2555 -#, fuzzy, c-format -msgid "pg_hba.conf was not reloaded" -msgstr "pg_hba.conf no ha sido recargado" - -#: postmaster/postmaster.c:2559 -#, fuzzy, c-format -msgid "pg_ident.conf was not reloaded" -msgstr "pg_ident.conf no ha sido recargado" +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2655 postmaster/postmaster.c:2659 +#, c-format +msgid "%s was not reloaded" +msgstr "%s no fue vuelto a cargar" -#: postmaster/postmaster.c:2569 -#, fuzzy, c-format +#: postmaster/postmaster.c:2669 +#, c-format msgid "SSL configuration was not reloaded" -msgstr "el parámetro de configuración de búsqueda en texto «%s» no es reconocido" +msgstr "la configuración SSL no fue vuelta a cargar" -#: postmaster/postmaster.c:2617 +#: postmaster/postmaster.c:2717 #, c-format msgid "received smart shutdown request" msgstr "se recibió petición de apagado inteligente" -#: postmaster/postmaster.c:2675 +#: postmaster/postmaster.c:2775 #, c-format msgid "received fast shutdown request" msgstr "se recibió petición de apagado rápido" -#: postmaster/postmaster.c:2708 +#: postmaster/postmaster.c:2808 #, c-format msgid "aborting any active transactions" msgstr "abortando transacciones activas" -#: postmaster/postmaster.c:2742 +#: postmaster/postmaster.c:2842 #, c-format msgid "received immediate shutdown request" msgstr "se recibió petición de apagado inmediato" -#: postmaster/postmaster.c:2809 +#: postmaster/postmaster.c:2909 #, c-format msgid "shutdown at recovery target" msgstr "apagándose al alcanzar el destino de recuperación" -#: postmaster/postmaster.c:2825 postmaster/postmaster.c:2848 +#: postmaster/postmaster.c:2925 postmaster/postmaster.c:2948 msgid "startup process" msgstr "proceso de inicio" -#: postmaster/postmaster.c:2828 +#: postmaster/postmaster.c:2928 #, c-format msgid "aborting startup due to startup process failure" msgstr "abortando el inicio debido a una falla en el procesamiento de inicio" -#: postmaster/postmaster.c:2889 +#: postmaster/postmaster.c:2989 #, c-format msgid "database system is ready to accept connections" msgstr "el sistema de bases de datos está listo para aceptar conexiones" -#: postmaster/postmaster.c:2910 +#: postmaster/postmaster.c:3010 msgid "background writer process" msgstr "proceso background writer" -#: postmaster/postmaster.c:2964 +#: postmaster/postmaster.c:3064 msgid "checkpointer process" msgstr "proceso checkpointer" -#: postmaster/postmaster.c:2980 +#: postmaster/postmaster.c:3080 msgid "WAL writer process" msgstr "proceso escritor de WAL" -#: postmaster/postmaster.c:2995 +#: postmaster/postmaster.c:3095 msgid "WAL receiver process" msgstr "proceso receptor de WAL" -#: postmaster/postmaster.c:3010 +#: postmaster/postmaster.c:3110 msgid "autovacuum launcher process" msgstr "proceso lanzador de autovacuum" -#: postmaster/postmaster.c:3025 +#: postmaster/postmaster.c:3125 msgid "archiver process" msgstr "proceso de archivado" -#: postmaster/postmaster.c:3041 +#: postmaster/postmaster.c:3141 msgid "statistics collector process" msgstr "recolector de estadísticas" -#: postmaster/postmaster.c:3055 +#: postmaster/postmaster.c:3155 msgid "system logger process" msgstr "proceso de log" -#: postmaster/postmaster.c:3117 -msgid "worker process" -msgstr "proceso «background worker»" +#: postmaster/postmaster.c:3217 +#, c-format +msgid "background worker \"%s\"" +msgstr "proceso ayudante «%s»" -#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 -#: postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 +#: postmaster/postmaster.c:3301 postmaster/postmaster.c:3321 +#: postmaster/postmaster.c:3328 postmaster/postmaster.c:3346 msgid "server process" msgstr "proceso de servidor" -#: postmaster/postmaster.c:3299 +#: postmaster/postmaster.c:3400 #, c-format msgid "terminating any other active server processes" msgstr "terminando todos los otros procesos de servidor activos" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3555 +#: postmaster/postmaster.c:3656 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) terminó con código de salida %d" -#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 -#: postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 -#: postmaster/postmaster.c:3598 +#: postmaster/postmaster.c:3658 postmaster/postmaster.c:3670 +#: postmaster/postmaster.c:3680 postmaster/postmaster.c:3691 #, c-format msgid "Failed process was running: %s" msgstr "El proceso que falló estaba ejecutando: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3565 +#: postmaster/postmaster.c:3667 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) fue terminado por una excepción 0x%X" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3575 +#: postmaster/postmaster.c:3677 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) fue terminado por una señal %d: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3586 -#, c-format -msgid "%s (PID %d) was terminated by signal %d" -msgstr "%s (PID %d) fue terminado por una señal %d" - -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3596 +#: postmaster/postmaster.c:3689 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" -msgstr "%s (PID %d) terminó con código no reconocido %d" +msgstr "%s (PID %d) terminó con código %d no reconocido" -#: postmaster/postmaster.c:3783 +#: postmaster/postmaster.c:3872 #, c-format msgid "abnormal database system shutdown" msgstr "apagado anormal del sistema de bases de datos" -#: postmaster/postmaster.c:3823 +#: postmaster/postmaster.c:3912 #, c-format msgid "all server processes terminated; reinitializing" msgstr "todos los procesos fueron terminados; reinicializando" -#: postmaster/postmaster.c:3989 postmaster/postmaster.c:5392 -#: postmaster/postmaster.c:5756 -#, fuzzy, c-format +#: postmaster/postmaster.c:4082 postmaster/postmaster.c:5473 +#: postmaster/postmaster.c:5847 +#, c-format msgid "could not generate random cancel key" -msgstr "no se pudo generar un vector aleatorio de encriptación" +msgstr "no se pudo generar una llave de cancelación aleatoria" -#: postmaster/postmaster.c:4043 +#: postmaster/postmaster.c:4136 #, c-format msgid "could not fork new process for connection: %m" msgstr "no se pudo lanzar el nuevo proceso para la conexión: %m" -#: postmaster/postmaster.c:4085 +#: postmaster/postmaster.c:4178 msgid "could not fork new process for connection: " msgstr "no se pudo lanzar el nuevo proceso para la conexión: " -#: postmaster/postmaster.c:4199 +#: postmaster/postmaster.c:4288 #, c-format msgid "connection received: host=%s port=%s" msgstr "conexión recibida: host=%s port=%s" -#: postmaster/postmaster.c:4204 +#: postmaster/postmaster.c:4293 #, c-format msgid "connection received: host=%s" msgstr "conexión recibida: host=%s" -#: postmaster/postmaster.c:4489 +#: postmaster/postmaster.c:4563 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "no se pudo lanzar el proceso servidor «%s»: %m" -#: postmaster/postmaster.c:4832 +#: postmaster/postmaster.c:4716 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "renunciar después de demasiados intentos de reservar memoria compartida" + +#: postmaster/postmaster.c:4717 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Esto podría deberse a ASLR o un software antivirus." + +#: postmaster/postmaster.c:4928 #, c-format msgid "SSL configuration could not be loaded in child process" -msgstr "" +msgstr "No se pudo cargar la configuración SSL en proceso secundario" -#: postmaster/postmaster.c:4964 +#: postmaster/postmaster.c:5060 #, c-format -msgid "Please report this to ." -msgstr "Por favor reporte esto a ." +msgid "Please report this to ." +msgstr "Por favor, reporte esto a ." -#: postmaster/postmaster.c:5051 +#: postmaster/postmaster.c:5147 #, c-format msgid "database system is ready to accept read only connections" msgstr "el sistema de bases de datos está listo para aceptar conexiones de sólo lectura" -#: postmaster/postmaster.c:5320 +#: postmaster/postmaster.c:5401 #, c-format msgid "could not fork startup process: %m" msgstr "no se pudo lanzar el proceso de inicio: %m" -#: postmaster/postmaster.c:5324 +#: postmaster/postmaster.c:5405 #, c-format msgid "could not fork background writer process: %m" msgstr "no se pudo lanzar el background writer: %m" -#: postmaster/postmaster.c:5328 +#: postmaster/postmaster.c:5409 #, c-format msgid "could not fork checkpointer process: %m" msgstr "no se pudo lanzar el checkpointer: %m" -#: postmaster/postmaster.c:5332 +#: postmaster/postmaster.c:5413 #, c-format msgid "could not fork WAL writer process: %m" msgstr "no se pudo lanzar el proceso escritor de WAL: %m" -#: postmaster/postmaster.c:5336 +#: postmaster/postmaster.c:5417 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "no se pudo lanzar el proceso receptor de WAL: %m" -#: postmaster/postmaster.c:5340 +#: postmaster/postmaster.c:5421 #, c-format msgid "could not fork process: %m" msgstr "no se pudo lanzar el proceso: %m" -#: postmaster/postmaster.c:5527 postmaster/postmaster.c:5550 +#: postmaster/postmaster.c:5618 postmaster/postmaster.c:5641 #, c-format msgid "database connection requirement not indicated during registration" msgstr "el requerimiento de conexión a base de datos no fue indicado durante el registro" -#: postmaster/postmaster.c:5534 postmaster/postmaster.c:5557 +#: postmaster/postmaster.c:5625 postmaster/postmaster.c:5648 #, c-format msgid "invalid processing mode in background worker" -msgstr "modo de procesamiento no válido en «background worker»" +msgstr "modo de procesamiento no válido en proceso ayudante" -#: postmaster/postmaster.c:5629 +#: postmaster/postmaster.c:5720 #, c-format msgid "starting background worker process \"%s\"" -msgstr "iniciando el proceso «background worker» «%s»" +msgstr "iniciando el proceso ayudante «%s»" -#: postmaster/postmaster.c:5641 +#: postmaster/postmaster.c:5732 #, c-format msgid "could not fork worker process: %m" -msgstr "no se pudo lanzar el proceso «background worker»: %m" +msgstr "no se pudo lanzar el proceso ayudante: %m" -#: postmaster/postmaster.c:6065 +#: postmaster/postmaster.c:6168 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "no se pudo duplicar el socket %d para su empleo en el backend: código de error %d" -#: postmaster/postmaster.c:6097 +#: postmaster/postmaster.c:6200 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "no se pudo crear el socket heradado: código de error %d\n" -#: postmaster/postmaster.c:6126 +#: postmaster/postmaster.c:6229 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "no se pudo abrir el archivo de variables de servidor «%s»: %s\n" -#: postmaster/postmaster.c:6133 +#: postmaster/postmaster.c:6236 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "no se pudo leer el archivo de variables de servidor «%s»: %s\n" -#: postmaster/postmaster.c:6142 +#: postmaster/postmaster.c:6245 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "no se pudo eliminar el archivo «%s»: %s\n" -#: postmaster/postmaster.c:6159 +#: postmaster/postmaster.c:6262 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "no se pudo mapear la vista del archivo de variables: código de error %lu\n" -#: postmaster/postmaster.c:6168 +#: postmaster/postmaster.c:6271 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "no se pudo desmapear la vista del archivo de variables: código de error %lu\n" -#: postmaster/postmaster.c:6175 +#: postmaster/postmaster.c:6278 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "no se pudo cerrar el archivo de variables de servidor: código de error %lu\n" -#: postmaster/postmaster.c:6336 +#: postmaster/postmaster.c:6442 #, c-format msgid "could not read exit code for process\n" msgstr "no se pudo leer el código de salida del proceso\n" -#: postmaster/postmaster.c:6341 +#: postmaster/postmaster.c:6447 #, c-format msgid "could not post child completion status\n" msgstr "no se pudo publicar el estado de completitud del proceso hijo\n" -#: postmaster/syslogger.c:452 postmaster/syslogger.c:1053 +#: postmaster/syslogger.c:480 postmaster/syslogger.c:1154 #, c-format msgid "could not read from logger pipe: %m" msgstr "no se pudo leer desde la tubería de log: %m" -#: postmaster/syslogger.c:502 +#: postmaster/syslogger.c:528 #, c-format msgid "logger shutting down" -msgstr "apagando proceso de log" +msgstr "proceso logger apagándose" -#: postmaster/syslogger.c:546 postmaster/syslogger.c:560 +#: postmaster/syslogger.c:572 postmaster/syslogger.c:586 #, c-format msgid "could not create pipe for syslog: %m" msgstr "no se pudo crear la tubería para syslog: %m" -#: postmaster/syslogger.c:596 +#: postmaster/syslogger.c:637 #, c-format msgid "could not fork system logger: %m" msgstr "no se pudo crear el proceso de log: %m" -#: postmaster/syslogger.c:632 +#: postmaster/syslogger.c:673 #, c-format msgid "redirecting log output to logging collector process" msgstr "redirigiendo la salida del registro al proceso recolector de registro" -#: postmaster/syslogger.c:633 +#: postmaster/syslogger.c:674 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "La salida futura del registro aparecerá en el directorio «%s»." -#: postmaster/syslogger.c:641 +#: postmaster/syslogger.c:682 #, c-format msgid "could not redirect stdout: %m" msgstr "no se pudo redirigir stdout: %m" -#: postmaster/syslogger.c:646 postmaster/syslogger.c:663 +#: postmaster/syslogger.c:687 postmaster/syslogger.c:704 #, c-format msgid "could not redirect stderr: %m" msgstr "no se pudo redirigir stderr: %m" -#: postmaster/syslogger.c:1008 +#: postmaster/syslogger.c:1109 #, c-format msgid "could not write to log file: %s\n" msgstr "no se pudo escribir al archivo de log: %s\n" -#: postmaster/syslogger.c:1150 +#: postmaster/syslogger.c:1226 #, c-format msgid "could not open log file \"%s\": %m" msgstr "no se pudo abrir el archivo de registro «%s»: %m" -#: postmaster/syslogger.c:1212 postmaster/syslogger.c:1256 +#: postmaster/syslogger.c:1288 postmaster/syslogger.c:1338 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "desactivando rotación automática (use SIGHUP para reactivarla)" @@ -16594,282 +17200,313 @@ msgstr "desactivando rotación automática (use SIGHUP para reactivarla)" msgid "could not determine which collation to use for regular expression" msgstr "no se pudo determinar qué ordenamiento usar para la expresión regular" -#: repl_gram.y:320 repl_gram.y:352 -#, c-format -msgid "invalid timeline %u" -msgstr "timeline %u no válido" - -#: repl_scanner.l:125 -msgid "invalid streaming start location" -msgstr "posición de inicio de flujo de WAL no válida" - -#: repl_scanner.l:176 scan.l:670 -msgid "unterminated quoted string" -msgstr "una cadena de caracteres entre comillas está inconclusa" - -#: replication/basebackup.c:303 +#: regex/regc_pg_locale.c:269 #, c-format -msgid "could not stat control file \"%s\": %m" -msgstr "no se pudo hacer stat al archivo de control «%s»: %m" +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "los ordenamientos no determinísticos no están soportados para expresiones regulares" -#: replication/basebackup.c:412 +#: replication/basebackup.c:450 #, c-format msgid "could not find any WAL files" msgstr "no se pudo encontrar ningún archivo de WAL" -#: replication/basebackup.c:425 replication/basebackup.c:439 -#: replication/basebackup.c:448 +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 #, c-format msgid "could not find WAL file \"%s\"" msgstr "no se pudo encontrar archivo de WAL «%s»" -#: replication/basebackup.c:487 replication/basebackup.c:513 +#: replication/basebackup.c:530 replication/basebackup.c:558 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "tamaño del archivo WAL «%s» inesperado" -#: replication/basebackup.c:499 replication/basebackup.c:1228 +#: replication/basebackup.c:544 replication/basebackup.c:1539 #, c-format msgid "base backup could not send data, aborting backup" msgstr "el respaldo base no pudo enviar datos, abortando el respaldo" -#: replication/basebackup.c:601 replication/basebackup.c:610 -#: replication/basebackup.c:619 replication/basebackup.c:628 -#: replication/basebackup.c:637 replication/basebackup.c:648 -#: replication/basebackup.c:665 +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "%s fallas de verificación de checksums en total" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "falla en verificación de checksums durante respaldo base" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 #, c-format msgid "duplicate option \"%s\"" msgstr "nombre de opción «%s» duplicada" -#: replication/basebackup.c:654 utils/misc/guc.c:5769 +#: replication/basebackup.c:717 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d está fuera del rango aceptable para el parámetro «%s» (%d .. %d)" -#: replication/basebackup.c:928 replication/basebackup.c:1025 +#: replication/basebackup.c:991 replication/basebackup.c:1161 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "no se pudo hacer stat al archivo o directorio «%s»: %m" -#: replication/basebackup.c:1180 +#: replication/basebackup.c:1316 #, c-format msgid "skipping special file \"%s\"" -msgstr "ignorando el archivo especial «%s»" +msgstr "omitiendo el archivo especial «%s»" -#: replication/basebackup.c:1293 +#: replication/basebackup.c:1424 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "número de segmento %d no válido en archivo «%s»" + +#: replication/basebackup.c:1443 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "no se puede verificar el checksum en el archivo «%s», bloque %d: el tamaño leído %d y el tamaño de página %d difieren" + +#: replication/basebackup.c:1487 replication/basebackup.c:1503 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "no se pudo posicionar (fseek) el archivo «%s»: %m" + +#: replication/basebackup.c:1495 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "no se pudo leer el bloque %d del archivo «%s»: %m" + +#: replication/basebackup.c:1519 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "verificación de checksums falló en archivo «%s», bloque %d: calculado %X pero se esperaba %X" + +#: replication/basebackup.c:1526 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "subsiguientes fallas de verificación de checksums en el archivo «%s» no se reportarán" + +#: replication/basebackup.c:1584 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "el archivo «%s» tiene un total de %d fallas de verificación de checksums" + +#: replication/basebackup.c:1615 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "nombre de archivo demasiado largo para el formato tar: «%s»" -#: replication/basebackup.c:1298 +#: replication/basebackup.c:1620 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "destino de enlace simbólico demasiado largo para el formato tar: nombre de archivo «%s», destino «%s»" -#: replication/libpqwalreceiver/libpqwalreceiver.c:226 -#, fuzzy, c-format +#: replication/libpqwalreceiver/libpqwalreceiver.c:232 +#, c-format msgid "invalid connection string syntax: %s" -msgstr "límite de conexión no válido: %d" +msgstr "sintaxis de cadena de conexión no válida: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:250 +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 #, c-format msgid "could not parse connection string: %s" msgstr "no se pudo interpretar la cadena de conexión: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:300 +#: replication/libpqwalreceiver/libpqwalreceiver.c:328 #, c-format msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "no se pudo recibir el identificador de sistema y el ID de timeline del servidor primario: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:311 -#: replication/libpqwalreceiver/libpqwalreceiver.c:518 +#: replication/libpqwalreceiver/libpqwalreceiver.c:339 +#: replication/libpqwalreceiver/libpqwalreceiver.c:557 #, c-format msgid "invalid response from primary server" msgstr "respuesta no válida del servidor primario" -#: replication/libpqwalreceiver/libpqwalreceiver.c:312 +#: replication/libpqwalreceiver/libpqwalreceiver.c:340 #, c-format msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "No se pudo identificar el sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos." -#: replication/libpqwalreceiver/libpqwalreceiver.c:378 -#: replication/libpqwalreceiver/libpqwalreceiver.c:384 -#: replication/libpqwalreceiver/libpqwalreceiver.c:409 +#: replication/libpqwalreceiver/libpqwalreceiver.c:413 +#: replication/libpqwalreceiver/libpqwalreceiver.c:419 +#: replication/libpqwalreceiver/libpqwalreceiver.c:444 #, c-format msgid "could not start WAL streaming: %s" msgstr "no se pudo iniciar el flujo de WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:428 +#: replication/libpqwalreceiver/libpqwalreceiver.c:467 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "no se pudo enviar el mensaje fin-de-flujo al primario: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 +#: replication/libpqwalreceiver/libpqwalreceiver.c:489 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "conjunto de resultados inesperado después del fin-de-flujo" -#: replication/libpqwalreceiver/libpqwalreceiver.c:464 -#, fuzzy, c-format -#| msgid "error reading result of streaming command: %s" +#: replication/libpqwalreceiver/libpqwalreceiver.c:503 +#, c-format msgid "error while shutting down streaming COPY: %s" -msgstr "ocurrió un error mientras se leía la orden de flujo: %s" +msgstr "ocurrió un error mientras se apagaba el flujo COPY: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:473 +#: replication/libpqwalreceiver/libpqwalreceiver.c:512 #, c-format msgid "error reading result of streaming command: %s" msgstr "ocurrió un error mientras se leía la orden de flujo: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:481 -#: replication/libpqwalreceiver/libpqwalreceiver.c:709 +#: replication/libpqwalreceiver/libpqwalreceiver.c:520 +#: replication/libpqwalreceiver/libpqwalreceiver.c:754 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "resultado inesperado después de CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:507 +#: replication/libpqwalreceiver/libpqwalreceiver.c:546 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "no se pudo recibir el archivo de historia de timeline del servidor primario: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:519 +#: replication/libpqwalreceiver/libpqwalreceiver.c:558 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "Se esperaba 1 tupla con 2 campos, se obtuvieron %d tuplas con %d campos." -#: replication/libpqwalreceiver/libpqwalreceiver.c:673 -#: replication/libpqwalreceiver/libpqwalreceiver.c:724 -#: replication/libpqwalreceiver/libpqwalreceiver.c:730 +#: replication/libpqwalreceiver/libpqwalreceiver.c:718 +#: replication/libpqwalreceiver/libpqwalreceiver.c:769 +#: replication/libpqwalreceiver/libpqwalreceiver.c:775 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "no se pudo recibir datos desde el flujo de WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:749 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 #, c-format msgid "could not send data to WAL stream: %s" msgstr "no se pudo enviar datos al flujo de WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:798 -#, fuzzy, c-format +#: replication/libpqwalreceiver/libpqwalreceiver.c:843 +#, c-format msgid "could not create replication slot \"%s\": %s" -msgstr "no se pudo crear la configuración regional «%s»: %m" +msgstr "no se pudo create el slot de replicación «%s»: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:832 -#, fuzzy, c-format +#: replication/libpqwalreceiver/libpqwalreceiver.c:877 +#, c-format msgid "invalid query response" -msgstr "consulta no válido" +msgstr "respuesta no válida a consulta" -#: replication/libpqwalreceiver/libpqwalreceiver.c:833 -#, fuzzy, c-format +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#, c-format msgid "Expected %d fields, got %d fields." -msgstr "Se esperaba 1 tupla con 2 campos, se obtuvieron %d tuplas con %d campos." +msgstr "Se esperaban %d campos, se obtuvieron %d campos." -#: replication/libpqwalreceiver/libpqwalreceiver.c:902 -#, fuzzy, c-format +#: replication/libpqwalreceiver/libpqwalreceiver.c:947 +#, c-format msgid "the query interface requires a database connection" -msgstr "decodificación lógica requiere una conexión a una base de datos" +msgstr "la interfaz de consulta requiere una conexión a base de datos" -#: replication/libpqwalreceiver/libpqwalreceiver.c:933 +#: replication/libpqwalreceiver/libpqwalreceiver.c:978 msgid "empty query" -msgstr "" +msgstr "consulta vacía" -#: replication/logical/launcher.c:268 -#, fuzzy, c-format +#: replication/logical/launcher.c:307 +#, c-format msgid "starting logical replication worker for subscription \"%s\"" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "iniciando el proceso ayudante de replicación lógica para la suscripción «%s»" -#: replication/logical/launcher.c:275 -#, fuzzy, c-format +#: replication/logical/launcher.c:314 +#, c-format msgid "cannot start logical replication workers when max_replication_slots = 0" -msgstr "no se puede consultar o manipular orígenes de replicación cuando max_replication_slots = 0" +msgstr "no se pueden iniciar procesos ayudantes de replicación cuando max_replication_slots = 0" -#: replication/logical/launcher.c:355 -#, fuzzy, c-format +#: replication/logical/launcher.c:394 +#, c-format msgid "out of logical replication worker slots" -msgstr "la base de datos «%s» está siendo usada por un slot de replicación lógica" +msgstr "se agotaron los slots de procesos ayudantes de replicación" -#: replication/logical/launcher.c:356 -#, fuzzy, c-format +#: replication/logical/launcher.c:395 +#, c-format msgid "You might need to increase max_logical_replication_workers." -msgstr "Puede ser necesario incrementar max_locks_per_transaction." +msgstr "Puede ser necesario incrementar max_logical_replication_workers." -#: replication/logical/launcher.c:401 -#, fuzzy, c-format +#: replication/logical/launcher.c:450 +#, c-format msgid "out of background worker slots" -msgstr "demasiados «background workers»" +msgstr "se acabaron los slots de procesos ayudante" -#: replication/logical/launcher.c:402 -#, fuzzy, c-format +#: replication/logical/launcher.c:451 +#, c-format msgid "You might need to increase max_worker_processes." -msgstr "Puede ser necesario incrementar max_locks_per_transaction." +msgstr "Puede ser necesario incrementar max_worker_processes." -#: replication/logical/launcher.c:564 +#: replication/logical/launcher.c:650 #, c-format msgid "logical replication worker slot %d is empty, cannot attach" -msgstr "" +msgstr "el slot del worker de replicación lógica %d está vacío, no se puede adjuntar" -#: replication/logical/launcher.c:573 +#: replication/logical/launcher.c:659 #, c-format msgid "logical replication worker slot %d is already used by another worker, cannot attach" -msgstr "" +msgstr "el slot de replicación lógica %d ya está siendo utilizado por otro worker, no se puede adjuntar" -#: replication/logical/launcher.c:798 -#, fuzzy, c-format +#: replication/logical/launcher.c:977 +#, c-format msgid "logical replication launcher started" -msgstr "lanzador de autovacuum iniciado" +msgstr "lanzador de replicación lógica iniciado" # FIXME see slot.c:779. See also postmaster.c:835 -#: replication/logical/logical.c:83 +#: replication/logical/logical.c:90 #, c-format msgid "logical decoding requires wal_level >= logical" msgstr "la decodificación lógica requiere wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:95 #, c-format msgid "logical decoding requires a database connection" msgstr "decodificación lógica requiere una conexión a una base de datos" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:113 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "la decodificación lógica no puede ejecutarse durante la recuperación" -#: replication/logical/logical.c:243 replication/logical/logical.c:365 +#: replication/logical/logical.c:258 replication/logical/logical.c:396 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "no se puede usar un slot de replicación física para decodificación lógica" -#: replication/logical/logical.c:248 replication/logical/logical.c:370 +#: replication/logical/logical.c:263 replication/logical/logical.c:401 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "el slot de replicación «%s» no fue creado en esta base de datos" -#: replication/logical/logical.c:255 +#: replication/logical/logical.c:270 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "no se puede crear un slot de replicación lógica en una transacción que ha efectuado escrituras" -#: replication/logical/logical.c:408 +#: replication/logical/logical.c:441 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "iniciando la decodificación lógica para el slot «%s»" -#: replication/logical/logical.c:410 +#: replication/logical/logical.c:443 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "enviando flujo de transacciones comprometidas después de %X/%X, leyendo WAL de %X/%X" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Transacciones en flujo comprometiendo después de %X/%X, leyendo WAL desde %X/%X." -#: replication/logical/logical.c:557 +#: replication/logical/logical.c:593 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "slot «%s», plugin de salida «%s», en el callback %s, LSN asociado %X/%X" # FIXME must quote callback name? Need a translator: comment? -#: replication/logical/logical.c:564 +#: replication/logical/logical.c:600 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "slot «%s», plugin de salida «%s», en el callback %s" -#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:34 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "debe ser superusuario o rol de replicación para usar slots de replicación" @@ -16894,470 +17531,516 @@ msgstr "el array debe ser unidimensional" msgid "array must not contain nulls" msgstr "el array no debe contener nulls" -#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2282 -#: utils/adt/jsonb.c:1357 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2312 +#: utils/adt/jsonb.c:1282 #, c-format msgid "array must have even number of elements" msgstr "el array debe tener un número par de elementos" -#: replication/logical/logicalfuncs.c:268 +#: replication/logical/logicalfuncs.c:269 #, c-format msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "el plugin de salida de decodificación lógica «%s» produce salida binaria, pero «%s» espera datos textuales" -#: replication/logical/origin.c:180 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "debe ser superusuario para consultar o manipular orígenes de replicación" -#: replication/logical/origin.c:185 +#: replication/logical/origin.c:190 #, c-format msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "no se puede consultar o manipular orígenes de replicación cuando max_replication_slots = 0" -#: replication/logical/origin.c:190 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "no se puede manipular orígenes de replicación durante la recuperación" -#: replication/logical/origin.c:314 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "no existe el origen de replicación «%s»" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "no se pudo encontrar un OID de origen de replicación libre" -#: replication/logical/origin.c:351 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "no se pudo eliminar el origen de replicación con OID %d, en uso por el PID %d" -#: replication/logical/origin.c:667 +#: replication/logical/origin.c:461 #, c-format -msgid "replication checkpoint has wrong magic %u instead of %u" -msgstr "el checkpoint de replicación tiene número mágico erróneo %u en lugar de %u" +msgid "replication origin with OID %u does not exist" +msgstr "el origen de replicación con OID %u no existe" -#: replication/logical/origin.c:699 +#: replication/logical/origin.c:729 #, c-format -msgid "could not read file \"%s\": read %d of %zu" -msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "el checkpoint de replicación tiene número mágico erróneo %u en lugar de %u" -#: replication/logical/origin.c:708 +#: replication/logical/origin.c:770 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "no se pudo encontrar una estructura de replicación libre, incremente max_replication_slots" -#: replication/logical/origin.c:726 +#: replication/logical/origin.c:788 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "el checkpoint del slot de replicación tiene suma de verificación errónea %u, se esperaba %u" -#: replication/logical/origin.c:850 +#: replication/logical/origin.c:916 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "el origen de replicación con OID %d ya está activo para el PID %d" -#: replication/logical/origin.c:861 replication/logical/origin.c:1041 +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 #, c-format msgid "could not find free replication state slot for replication origin with OID %u" msgstr "no se pudo encontrar un slot libre para el estado del origen de replicación con OID %u" -#: replication/logical/origin.c:863 replication/logical/origin.c:1043 -#: replication/slot.c:1448 +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1564 #, c-format msgid "Increase max_replication_slots and try again." msgstr "Aumente max_replication_slots y reintente." -#: replication/logical/origin.c:1000 +#: replication/logical/origin.c:1073 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "no se puede establecer un destino de replicación cuando ya hay uno definido" -#: replication/logical/origin.c:1029 +#: replication/logical/origin.c:1102 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "el identificador de replicación %d ya está activo para el PID %d" -#: replication/logical/origin.c:1075 replication/logical/origin.c:1270 -#: replication/logical/origin.c:1290 +#: replication/logical/origin.c:1153 replication/logical/origin.c:1351 +#: replication/logical/origin.c:1371 #, c-format msgid "no replication origin is configured" msgstr "no hay un destino de replicación configurado" -#: replication/logical/relation.c:259 -#, fuzzy, c-format +#: replication/logical/relation.c:255 +#, c-format msgid "logical replication target relation \"%s.%s\" does not exist" -msgstr "no existe el slot de replicación «%s»" +msgstr "la relación destino de replicación lógica «%s.%s» no existe" #: replication/logical/relation.c:297 #, c-format msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" -msgstr "" +msgstr "a la relación destino de replicación lógica «%s.%s» le faltan algunas columnas replicadas" #: replication/logical/relation.c:337 #, c-format msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" -msgstr "" - -#: replication/logical/relation.c:453 -#, fuzzy, c-format -msgid "builtin type %u not found" -msgstr "opción «%s» no encontrada" - -#: replication/logical/relation.c:454 -#, c-format -msgid "This can be caused by having publisher with higher major version than subscriber" -msgstr "" +msgstr "la relación de destino de replicación lógica «%s.%s» usa columnas de sistemas en el índice REPLICA IDENTITY" -#: replication/logical/relation.c:486 -#, fuzzy, c-format -msgid "data type \"%s.%s\" required for logical replication does not exist" -msgstr "la base de datos «%s» está siendo usada por un slot de replicación lógica" - -#: replication/logical/reorderbuffer.c:2288 +#: replication/logical/reorderbuffer.c:2507 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "no se pudo escribir al archivo de datos para el XID %u: %m" -#: replication/logical/reorderbuffer.c:2387 -#: replication/logical/reorderbuffer.c:2409 +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "no se pudo leer desde el archivo de desborde de reorderbuffer: %m" -#: replication/logical/reorderbuffer.c:2391 -#: replication/logical/reorderbuffer.c:2413 +#: replication/logical/reorderbuffer.c:2604 +#: replication/logical/reorderbuffer.c:2626 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "no se pudo leer desde el archivo de desborde de reorderbuffer: se leyeron sólo %d en ve de %u bytes" +#: replication/logical/reorderbuffer.c:2849 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "no se pudo borrar el archivo «%s» durante la eliminación de pg_replslot/%s/xid*: %m" + # FIXME almost duplicated again!? -#: replication/logical/reorderbuffer.c:3071 +#: replication/logical/reorderbuffer.c:3315 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "no se pudo leer del archivo «%s»: se leyeron %d en lugar de %d bytes" -#: replication/logical/snapbuild.c:612 -#, fuzzy, c-format +#: replication/logical/snapbuild.c:611 +#, c-format msgid "initial slot snapshot too large" -msgstr "el archivo «%s» es demasiado grande" +msgstr "el snapshot inicial del slot es demasiado grande" # FIXME: snapshot? instantánea? -#: replication/logical/snapbuild.c:664 +#: replication/logical/snapbuild.c:665 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "se exportó un snapshot de decodificación lógica: «%s» con %u ID de transacción" msgstr[1] "se exportó un snapshot de decodificación lógica: «%s» con %u IDs de transacción" -#: replication/logical/snapbuild.c:1262 replication/logical/snapbuild.c:1355 -#: replication/logical/snapbuild.c:1842 +#: replication/logical/snapbuild.c:1270 replication/logical/snapbuild.c:1363 +#: replication/logical/snapbuild.c:1917 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "la decodificación lógica encontró un punto consistente en %X/%X" -#: replication/logical/snapbuild.c:1264 +#: replication/logical/snapbuild.c:1272 #, c-format msgid "There are no running transactions." msgstr "No hay transacciones en ejecución." -#: replication/logical/snapbuild.c:1306 +#: replication/logical/snapbuild.c:1314 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "decodificación lógica encontró punto de inicio en %X/%X" -#: replication/logical/snapbuild.c:1308 replication/logical/snapbuild.c:1332 +#: replication/logical/snapbuild.c:1316 replication/logical/snapbuild.c:1340 #, c-format msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "Esperando que las (aproximadamente %d) transacciones más antiguas que %u terminen." -#: replication/logical/snapbuild.c:1330 +#: replication/logical/snapbuild.c:1338 #, c-format msgid "logical decoding found initial consistent point at %X/%X" msgstr "la decodificación lógica encontró un punto consistente inicial en %X/%X" -#: replication/logical/snapbuild.c:1357 +#: replication/logical/snapbuild.c:1365 #, c-format msgid "There are no old transactions anymore." msgstr "Ya no hay transacciones antiguas en ejecución." -# FIXME almost duplicated string -#: replication/logical/snapbuild.c:1715 replication/logical/snapbuild.c:1743 -#: replication/logical/snapbuild.c:1760 replication/logical/snapbuild.c:1776 -#, c-format -msgid "could not read file \"%s\", read %d of %d: %m" -msgstr "no se pudo leer el archivo «%s», leídos %d de %d: %m" - # FIXME "snapbuild"? -#: replication/logical/snapbuild.c:1721 +#: replication/logical/snapbuild.c:1759 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "el archivo de estado de snapbuild «%s» tiene número mágico erróneo: %u en lugar de %u" -#: replication/logical/snapbuild.c:1726 +#: replication/logical/snapbuild.c:1765 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "el archivo de estado de snapbuild «%s» tiene versión no soportada: %u en vez de %u" -#: replication/logical/snapbuild.c:1789 +#: replication/logical/snapbuild.c:1864 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "suma de verificación no coincidente para el archivo de estado de snapbuild «%s»: es %u, debería ser %u" -#: replication/logical/snapbuild.c:1844 +#: replication/logical/snapbuild.c:1919 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "La decodificación lógica comenzará usando el snapshot guardado." -#: replication/logical/snapbuild.c:1916 +#: replication/logical/snapbuild.c:1991 #, c-format msgid "could not parse file name \"%s\"" msgstr "no se pudo interpretar el nombre de archivo «%s»" -#: replication/logical/tablesync.c:138 -#, fuzzy, c-format +#: replication/logical/tablesync.c:139 +#, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante de sincronización de tabla de replicación lógica para la suscripción «%s», tabla «%s» ha terminado" -#: replication/logical/tablesync.c:685 -#, fuzzy, c-format +#: replication/logical/tablesync.c:672 +#, c-format msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" -msgstr "no se pudo recuperar el archivo «%s»: %s" +msgstr "no se pudo obtener información de la tabla «%s.%s» del editor (publisher): %s" -#: replication/logical/tablesync.c:691 +#: replication/logical/tablesync.c:678 #, c-format msgid "table \"%s.%s\" not found on publisher" -msgstr "" +msgstr "la tabla \"%s.%s\" no fue encontrada en el editor (publisher)" -#: replication/logical/tablesync.c:721 -#, fuzzy, c-format +#: replication/logical/tablesync.c:710 +#, c-format msgid "could not fetch table info for table \"%s.%s\": %s" -msgstr "no se pudo definir un junction para «%s»: %s" +msgstr "no se pudo obtener información de la tabla «%s.%s»: %s" -#: replication/logical/tablesync.c:791 -#, fuzzy, c-format +#: replication/logical/tablesync.c:780 +#, c-format msgid "could not start initial contents copy for table \"%s.%s\": %s" -msgstr "no se pudo hacer stat al archivo de control «%s»: %m" +msgstr "no se pudo iniciar la copia de contenido inicial para de la tabla «%s.%s»: %s" -#: replication/logical/tablesync.c:905 -#, fuzzy, c-format +#: replication/logical/tablesync.c:894 +#, c-format msgid "table copy could not start transaction on publisher" -msgstr "no se pudo encontrar el estado de la transacción %u" +msgstr "la copia de la tabla no pudo iniciar una transacción en el editor (publisher)" -#: replication/logical/tablesync.c:925 +#: replication/logical/tablesync.c:916 #, c-format msgid "table copy could not finish transaction on publisher" -msgstr "" +msgstr "la copia de tabla no pudo terminar la transacción en el editor (publisher)" -#: replication/logical/worker.c:291 +#: replication/logical/worker.c:290 #, c-format msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" -msgstr "" +msgstr "Procesamiento de datos remotos para la relación de destino de replicación \"%s.%s\" columna \"%s\", tipo remoto %s, tipo local %s" -#: replication/logical/worker.c:500 +#: replication/logical/worker.c:511 #, c-format msgid "ORIGIN message sent out of order" -msgstr "" +msgstr "mensaje ORIGIN enviado fuera de orden" -#: replication/logical/worker.c:631 +#: replication/logical/worker.c:645 #, c-format -msgid "publisher does not send replica identity column expected by the logical replication target relation \"%s.%s\"" -msgstr "" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "el editor (publisher) no envía la columna identidad de réplica esperada por la relación de destino de replicación lógica «%s.%s»" -#: replication/logical/worker.c:638 +#: replication/logical/worker.c:652 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" -msgstr "" +msgstr "la relación destino de replicación lógica «%s.%s» no tiene índice REPLICA IDENTITY ni PRIMARY KEY y la relación publicada no tiene REPLICA IDENTITY FULL" -#: replication/logical/worker.c:845 -#, fuzzy, c-format -msgid "logical replication could not find row for delete in replication target %s" -msgstr "no se pudo encontrar un OID de origen de replicación libre" - -#: replication/logical/worker.c:912 -#, fuzzy, c-format -msgid "invalid logical replication message type %c" -msgstr "el tipo de mensaje de frontend %d no es válido" +#: replication/logical/worker.c:993 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "tipo de mensaje de replicación lógica «%c» no válido" -#: replication/logical/worker.c:1053 +#: replication/logical/worker.c:1134 #, c-format msgid "data stream from publisher has ended" -msgstr "" +msgstr "el flujo de datos del publisher ha terminado" -#: replication/logical/worker.c:1212 -#, fuzzy, c-format +#: replication/logical/worker.c:1289 +#, c-format msgid "terminating logical replication worker due to timeout" -msgstr "terminando el proceso walreceiver debido a que se agotó el tiempo de espera" +msgstr "terminando el proceso de replicación lógica debido a que se agotó el tiempo de espera" -#: replication/logical/worker.c:1360 -#, fuzzy, c-format +#: replication/logical/worker.c:1437 +#, c-format msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se detendrá porque la suscripción fue eliminada" -#: replication/logical/worker.c:1374 -#, fuzzy, c-format +#: replication/logical/worker.c:1451 +#, c-format msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se detendrá porque la suscripción fue inhabilitada" -#: replication/logical/worker.c:1388 +#: replication/logical/worker.c:1465 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" -msgstr "" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque la información de conexión fue cambiada" -#: replication/logical/worker.c:1402 -#, fuzzy, c-format +#: replication/logical/worker.c:1479 +#, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque a la suscripción se le cambió el nombre" -#: replication/logical/worker.c:1419 +#: replication/logical/worker.c:1496 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" -msgstr "" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque el nombre del slot de replicación fue cambiado" -#: replication/logical/worker.c:1433 +#: replication/logical/worker.c:1510 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" -msgstr "" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» se reiniciará porque las publicaciones de la suscripción fueron cambiadas" -#: replication/logical/worker.c:1541 +#: replication/logical/worker.c:1614 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "el ayudante «apply» de replicación lógica para la suscripción %u no se iniciará porque la suscripción fue eliminada durante el inicio" + +#: replication/logical/worker.c:1626 #, c-format msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" -msgstr "" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» no se iniciará porque la suscripción fue inhabilitada durante el inicio" -#: replication/logical/worker.c:1555 -#, fuzzy, c-format +#: replication/logical/worker.c:1644 +#, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante de sincronización de tabla de replicación lógica para la suscripción «%s», tabla «%s» ha iniciado" -#: replication/logical/worker.c:1559 -#, fuzzy, c-format +#: replication/logical/worker.c:1648 +#, c-format msgid "logical replication apply worker for subscription \"%s\" has started" -msgstr "iniciando la decodificación lógica para el slot «%s»" +msgstr "el ayudante «apply» de replicación lógica para la suscripción «%s» ha iniciado" -#: replication/logical/worker.c:1599 +#: replication/logical/worker.c:1687 #, c-format msgid "subscription has no replication slot set" -msgstr "" +msgstr "la suscripción no tiene un slot de replicación establecido" -#: replication/pgoutput/pgoutput.c:113 -#, fuzzy, c-format +#: replication/pgoutput/pgoutput.c:117 +#, c-format msgid "invalid proto_version" -msgstr "el nombre de opción «%s» no es válido" +msgstr "proto_version no válido" -#: replication/pgoutput/pgoutput.c:118 -#, fuzzy, c-format -msgid "proto_verson \"%s\" out of range" -msgstr "el huso horario numérico «%s» está fuera de rango" +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version «%s» está fuera de rango" -#: replication/pgoutput/pgoutput.c:135 -#, fuzzy, c-format +#: replication/pgoutput/pgoutput.c:139 +#, c-format msgid "invalid publication_names syntax" -msgstr "la sintaxis de nombre no es válida" +msgstr "sintaxis de publication_names no válida" -#: replication/pgoutput/pgoutput.c:179 +#: replication/pgoutput/pgoutput.c:181 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or lower" -msgstr "" +msgstr "el cliente envió proto_version=%d pero sólo soportamos el protocolo %d o inferior" -#: replication/pgoutput/pgoutput.c:185 +#: replication/pgoutput/pgoutput.c:187 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or higher" -msgstr "" +msgstr "el cliente envió proto_version=%d pero sólo soportamos el protocolo %d o superior" -#: replication/pgoutput/pgoutput.c:191 -#, fuzzy, c-format +#: replication/pgoutput/pgoutput.c:193 +#, c-format msgid "publication_names parameter missing" -msgstr "parámetro Dictionary duplicado" +msgstr "parámetro publication_names faltante" -#: replication/slot.c:181 +#: replication/slot.c:182 #, c-format msgid "replication slot name \"%s\" is too short" msgstr "el nombre de slot de replicación «%s» es demasiado corto" -#: replication/slot.c:190 +#: replication/slot.c:191 #, c-format msgid "replication slot name \"%s\" is too long" msgstr "el nombre de slot de replicación «%s» es demasiado largo" -#: replication/slot.c:203 +#: replication/slot.c:204 #, c-format msgid "replication slot name \"%s\" contains invalid character" msgstr "el nombre de slot de replicación «%s» contiene caracteres no válidos" -#: replication/slot.c:205 +#: replication/slot.c:206 #, c-format msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." msgstr "Los nombres de slots de replicación sólo pueden contener letras minúsculas, números y el carácter «_»." -#: replication/slot.c:252 +#: replication/slot.c:253 #, c-format msgid "replication slot \"%s\" already exists" msgstr "el slot de replicación «%s» ya existe" -#: replication/slot.c:262 +#: replication/slot.c:263 #, c-format msgid "all replication slots are in use" msgstr "todos los slots de replicación están en uso" -#: replication/slot.c:263 +#: replication/slot.c:264 #, c-format msgid "Free one or increase max_replication_slots." msgstr "Libere uno o incremente max_replication_slots." -#: replication/slot.c:357 +#: replication/slot.c:387 replication/slotfuncs.c:663 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "no existe el slot de replicación «%s»" -#: replication/slot.c:361 replication/slot.c:879 +#: replication/slot.c:398 replication/slot.c:947 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "el slot de replicación «%s» está activo para el PID %d" -#: replication/slot.c:563 replication/slot.c:1060 replication/slot.c:1409 +#: replication/slot.c:631 replication/slot.c:1139 replication/slot.c:1499 #, c-format msgid "could not remove directory \"%s\"" msgstr "no se pudo eliminar el directorio «%s»" -#: replication/slot.c:909 +#: replication/slot.c:982 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "los slots de replicación sólo pueden usarse si max_replication_slots > 0" # FIXME see logical.c:81 -#: replication/slot.c:914 +#: replication/slot.c:987 #, c-format msgid "replication slots can only be used if wal_level >= replica" msgstr "los slots de replicación sólo pueden usarse si wal_level >= replica" -#: replication/slot.c:1339 replication/slot.c:1379 -#, c-format -msgid "could not read file \"%s\", read %d of %u: %m" -msgstr "no se pudo leer el archivo «%s», leídos %d de %u: %m" - -#: replication/slot.c:1348 +#: replication/slot.c:1437 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "el archivo de slot de replicación «%s» tiene número mágico erróneo: %u en lugar de %u" -#: replication/slot.c:1355 +#: replication/slot.c:1444 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "el archivo de slot de replicación «%s» tiene versión no soportada %u" -#: replication/slot.c:1362 +#: replication/slot.c:1451 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "el archivo de slot de replicación «%s» tiene largo corrupto %u" -#: replication/slot.c:1394 +#: replication/slot.c:1487 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "suma de verificación no coincidenete en archivo de slot de replicación «%s»: es %u, debería ser %u" -#: replication/slot.c:1447 +# FIXME see slot.c:779. See also postmaster.c:835 +#: replication/slot.c:1521 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "existe el slot de replicación lógica «%s», pero wal_level < logical" + +#: replication/slot.c:1523 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Cambie wal_level a logical o superior." + +# FIXME see slot.c:779. See also postmaster.c:835 +#: replication/slot.c:1527 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "existe el slot de replicación lógica «%s», pero wal_level < logical" + +# <> hello vim +#: replication/slot.c:1529 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Cambie wal_level a replica o superior." + +#: replication/slot.c:1563 #, c-format msgid "too many replication slots active before shutdown" msgstr "demasiados slots de replicacion activos antes del apagado" +#: replication/slotfuncs.c:526 +#, c-format +msgid "invalid target wal lsn" +msgstr "el lsn de wal de destino no es válido" + +#: replication/slotfuncs.c:548 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "no puede avanzar un slot de replicación que no ha reservado WAL previamente" + +#: replication/slotfuncs.c:564 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "no puede avanzar un slot de replicación a %X/%X, el mínimo es %X/%X" + +#: replication/slotfuncs.c:670 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "no se puede copiar el slot de replicación física «%s» como slot de replicación lógica" + +#: replication/slotfuncs.c:672 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "no se puede copiar el slot de replicación lógica «%s» como slot de replicación física" + +#: replication/slotfuncs.c:681 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "no puede copiar un slot de replicación que no ha reservado WAL" + +#: replication/slotfuncs.c:746 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "no se pudo copiar el slot de replicación «%s»" + +#: replication/slotfuncs.c:748 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "El slot de replicación de origen fue modificado incompatiblemente durante la operación de copia." + #: replication/syncrep.c:248 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" @@ -17373,606 +18056,606 @@ msgstr "La transacción ya fue comprometida localmente, pero pudo no haber sido msgid "canceling wait for synchronous replication due to user request" msgstr "cancelando espera para la replicación sincrónica debido a una petición del usuario" -#: replication/syncrep.c:396 +#: replication/syncrep.c:398 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "el standby «%s» ahora tiene prioridad sincrónica %u" -#: replication/syncrep.c:457 +#: replication/syncrep.c:461 #, c-format msgid "standby \"%s\" is now a synchronous standby with priority %u" msgstr "el standby «%s» es ahora un standby sincrónico con prioridad %u" -#: replication/syncrep.c:461 -#, fuzzy, c-format +#: replication/syncrep.c:465 +#, c-format msgid "standby \"%s\" is now a candidate for quorum synchronous standby" -msgstr "el standby «%s» es ahora un standby sincrónico con prioridad %u" +msgstr "el standby «%s» es ahora un candidato para standby sincrónico de quórum" -#: replication/syncrep.c:1152 +#: replication/syncrep.c:1165 #, c-format msgid "synchronous_standby_names parser failed" -msgstr "falló la interpretación de «synchronous_standby_names»" +msgstr "falló la interpretación de synchronous_standby_names" -#: replication/syncrep.c:1158 +#: replication/syncrep.c:1171 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "el argumento de standby sincrónicos (%d) debe ser mayor que cero" -#: replication/walreceiver.c:168 +#: replication/walreceiver.c:160 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "terminando el proceso walreceiver debido a una orden del administrador" -#: replication/walreceiver.c:300 +#: replication/walreceiver.c:276 #, c-format msgid "could not connect to the primary server: %s" -msgstr "no se pudo hacer la conexión al servidor primario: %s" +msgstr "no se pudo conectar al servidor primario: %s" -#: replication/walreceiver.c:339 +#: replication/walreceiver.c:322 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "el identificador de sistema difiere entre el primario y el standby" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:323 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "El identificador del primario es %s, el identificador del standby es %s." -#: replication/walreceiver.c:351 +#: replication/walreceiver.c:333 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "el timeline más alto del primario, %u, está más atrás que el timeline de recuperación %u" -#: replication/walreceiver.c:387 +#: replication/walreceiver.c:369 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "iniciando el flujo de WAL desde el primario en %X/%X en el timeline %u" -#: replication/walreceiver.c:392 +#: replication/walreceiver.c:374 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "reiniciando el flujo de WAL en %X/%X en el timeline %u" -#: replication/walreceiver.c:421 +#: replication/walreceiver.c:403 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "no se puede continuar el flujo de WAL; la recuperación ya ha terminado" -#: replication/walreceiver.c:458 +#: replication/walreceiver.c:440 #, c-format msgid "replication terminated by primary server" msgstr "replicación terminada por el servidor primario" -#: replication/walreceiver.c:459 +#: replication/walreceiver.c:441 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "Se alcanzó el fin de WAL en el timeline %u en la posición %X/%X." -#: replication/walreceiver.c:554 +#: replication/walreceiver.c:529 #, c-format msgid "terminating walreceiver due to timeout" msgstr "terminando el proceso walreceiver debido a que se agotó el tiempo de espera" -#: replication/walreceiver.c:594 +#: replication/walreceiver.c:567 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "el servidor primario no contiene más WAL en el timeline %u solicitado" -#: replication/walreceiver.c:609 replication/walreceiver.c:968 +#: replication/walreceiver.c:582 replication/walreceiver.c:922 #, c-format msgid "could not close log segment %s: %m" msgstr "no se pudo cerrar archivo de segmento %s: %m" -#: replication/walreceiver.c:734 +#: replication/walreceiver.c:700 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "trayendo el archivo de historia del timeline para el timeline %u desde el servidor primario" -#: replication/walreceiver.c:1022 +#: replication/walreceiver.c:976 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "no se pudo escribir al segmento de log %s en la posición %u, largo %lu: %m" -#: replication/walsender.c:490 +#: replication/walsender.c:497 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "no se pudo posicionar (seek) al comienzo del archivo «%s»: %m" -#: replication/walsender.c:531 +#: replication/walsender.c:548 #, c-format msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" -msgstr "" +msgstr "IDENTIFY_SYSTEM no se ha ejecutado antes de START_REPLICATION" -#: replication/walsender.c:548 +#: replication/walsender.c:565 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "no se puede usar un slot de replicación lógica para replicación física" -#: replication/walsender.c:611 +#: replication/walsender.c:628 #, c-format msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "el punto de inicio solicitado %X/%X del timeline %u no está en la historia de este servidor" -#: replication/walsender.c:615 +#: replication/walsender.c:632 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "La historia de este servidor bifurcó desde el timeline %u en %X/%X." -#: replication/walsender.c:660 +#: replication/walsender.c:677 #, c-format msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "el punto de inicio solicitado %X/%X está más adelante que la posición de sincronización (flush) de WAL de este servidor %X/%X" -#: replication/walsender.c:889 -#, fuzzy, c-format -msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" -msgstr "SET TRANSACTION ISOLATION LEVEL no debe ser llamado en una subtransacción" +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:907 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s no debe ser ejecutado dentro de una transacción" -#: replication/walsender.c:898 -#, fuzzy, c-format -msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" -msgstr "SET TRANSACTION ISOLATION LEVEL no debe ser llamado en una subtransacción" +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:917 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s no debe ser ejecutado dentro de una transacción" -#: replication/walsender.c:903 +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:923 #, c-format -msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" -msgstr "" +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s debe llamarse en una transacción de modo de aislamiento REPEATABLE READ" -#: replication/walsender.c:908 -#, fuzzy, c-format -msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" -msgstr "SET TRANSACTION SNAPSHOT debe ser llamado antes de cualquier consulta" +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:929 +#, c-format +msgid "%s must be called before any query" +msgstr "%s debe ser llamado antes de cualquier consulta" -#: replication/walsender.c:913 -#, fuzzy, c-format -msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" -msgstr "SET TRANSACTION ISOLATION LEVEL no debe ser llamado en una subtransacción" +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:935 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s no está permitido en una subtransacción" -#: replication/walsender.c:1059 +#: replication/walsender.c:1082 #, c-format msgid "terminating walsender process after promotion" msgstr "terminando el proceso walsender luego de la promoción" -#: replication/walsender.c:1437 +#: replication/walsender.c:1453 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" -msgstr "" +msgstr "no puede ejecutar nuevas órdenes mientras el «WAL sender» está en modo de apagarse" -#: replication/walsender.c:1470 +#: replication/walsender.c:1486 #, c-format msgid "received replication command: %s" msgstr "se recibió orden de replicación: %s" -#: replication/walsender.c:1486 tcop/fastpath.c:281 tcop/postgres.c:997 -#: tcop/postgres.c:1307 tcop/postgres.c:1566 tcop/postgres.c:1971 -#: tcop/postgres.c:2339 tcop/postgres.c:2414 +#: replication/walsender.c:1502 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1426 tcop/postgres.c:1684 tcop/postgres.c:2077 +#: tcop/postgres.c:2463 tcop/postgres.c:2542 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "transacción abortada, las órdenes serán ignoradas hasta el fin de bloque de transacción" -#: replication/walsender.c:1548 -#, fuzzy, c-format -msgid "not connected to database" -msgstr "demasiadas conexiones para la base de datos «%s»" +#: replication/walsender.c:1570 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "no puede ejecutar órdenes SQL en el «WAL sender» para replicación física" -#: replication/walsender.c:1588 replication/walsender.c:1604 +#: replication/walsender.c:1618 replication/walsender.c:1634 #, c-format msgid "unexpected EOF on standby connection" msgstr "se encontró fin de archivo inesperado en la conexión standby" -#: replication/walsender.c:1618 +#: replication/walsender.c:1648 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "mensaje de standby de tipo «%c» inesperado, después de recibir CopyDone" -#: replication/walsender.c:1656 +#: replication/walsender.c:1686 #, c-format msgid "invalid standby message type \"%c\"" msgstr "el tipo «%c» de mensaje del standby no es válido" -#: replication/walsender.c:1697 +#: replication/walsender.c:1727 #, c-format msgid "unexpected message type \"%c\"" msgstr "mensaje de tipo «%c» inesperado" -#: replication/walsender.c:2067 +#: replication/walsender.c:2145 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "terminando el proceso walsender debido a que se agotó el tiempo de espera de replicación" -#: replication/walsender.c:2156 +#: replication/walsender.c:2222 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "el standby «%s» ahora está actualizado respecto del primario" +msgid "\"%s\" has now caught up with upstream server" +msgstr "«%s» ha alcanzado al servidor de origen" -#: replication/walsender.c:2263 +#: replication/walsender.c:2481 #, c-format -msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" -msgstr "la cantidad de conexiones standby pedidas excede max_wal_senders (actualmente %d)" +msgid "could not read from log segment %s, offset %u, length %zu: %m" +msgstr "no se pudo leer desde el segmento %s, posición %u, largo %zu: %m" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:981 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "ya existe una regla llamada «%s» para la relación «%s»" -#: rewrite/rewriteDefine.c:296 +#: rewrite/rewriteDefine.c:301 #, c-format msgid "rule actions on OLD are not implemented" msgstr "las acciones de regla en OLD no están implementadas" -#: rewrite/rewriteDefine.c:297 +#: rewrite/rewriteDefine.c:302 #, c-format msgid "Use views or triggers instead." msgstr "Use vistas o triggers en su lugar." -#: rewrite/rewriteDefine.c:301 +#: rewrite/rewriteDefine.c:306 #, c-format msgid "rule actions on NEW are not implemented" msgstr "las acciones de regla en NEW no están implementadas" -#: rewrite/rewriteDefine.c:302 +#: rewrite/rewriteDefine.c:307 #, c-format msgid "Use triggers instead." msgstr "Use triggers en su lugar." -#: rewrite/rewriteDefine.c:315 +#: rewrite/rewriteDefine.c:320 #, c-format msgid "INSTEAD NOTHING rules on SELECT are not implemented" msgstr "las reglas INSTEAD NOTHING en SELECT no están implementadas" -#: rewrite/rewriteDefine.c:316 +#: rewrite/rewriteDefine.c:321 #, c-format msgid "Use views instead." msgstr "Use vistas en su lugar." -#: rewrite/rewriteDefine.c:324 +#: rewrite/rewriteDefine.c:329 #, c-format msgid "multiple actions for rules on SELECT are not implemented" msgstr "las reglas de múltiples acciones en SELECT no están implementadas" -#: rewrite/rewriteDefine.c:334 +#: rewrite/rewriteDefine.c:339 #, c-format msgid "rules on SELECT must have action INSTEAD SELECT" msgstr "las reglas en SELECT deben tener una acción INSTEAD SELECT" -#: rewrite/rewriteDefine.c:342 +#: rewrite/rewriteDefine.c:347 #, c-format msgid "rules on SELECT must not contain data-modifying statements in WITH" msgstr "las reglas en SELECT no deben contener sentencias que modifiquen datos en WITH" -#: rewrite/rewriteDefine.c:350 +#: rewrite/rewriteDefine.c:355 #, c-format msgid "event qualifications are not implemented for rules on SELECT" msgstr "las calificaciones de eventos no están implementadas para las reglas en SELECT" -#: rewrite/rewriteDefine.c:377 +#: rewrite/rewriteDefine.c:382 #, c-format msgid "\"%s\" is already a view" msgstr "«%s» ya es una vista" -#: rewrite/rewriteDefine.c:401 +#: rewrite/rewriteDefine.c:406 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "la regla de vista para «%s» debe llamarse «%s»" -#: rewrite/rewriteDefine.c:428 -#, fuzzy, c-format -msgid "could not convert partitioned table \"%s\" to a view" -msgstr "no se pudo convertir la tabla «%s» en vista porque tiene índices" - #: rewrite/rewriteDefine.c:434 -#, fuzzy, c-format -msgid "could not convert partition \"%s\" to a view" -msgstr "no se pudo convertir la tabla «%s» en vista porque tiene índices" +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "no se puede convertir la tabla particionada «%s» en vista" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "no se puede convertir la partición «%s» en vista" -#: rewrite/rewriteDefine.c:442 +#: rewrite/rewriteDefine.c:449 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" msgstr "no se pudo convertir la tabla «%s» en vista porque no está vacía" -#: rewrite/rewriteDefine.c:450 +#: rewrite/rewriteDefine.c:458 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" msgstr "no se pudo convertir la tabla «%s» en vista porque tiene triggers" -#: rewrite/rewriteDefine.c:452 +#: rewrite/rewriteDefine.c:460 #, c-format msgid "In particular, the table cannot be involved in any foreign key relationships." msgstr "En particular, la tabla no puede estar involucrada en relaciones de llave foránea." -#: rewrite/rewriteDefine.c:457 +#: rewrite/rewriteDefine.c:465 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "no se pudo convertir la tabla «%s» en vista porque tiene índices" -#: rewrite/rewriteDefine.c:463 +#: rewrite/rewriteDefine.c:471 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "no se pudo convertir la tabla «%s» en vista porque tiene tablas hijas" -#: rewrite/rewriteDefine.c:469 +#: rewrite/rewriteDefine.c:477 #, c-format msgid "could not convert table \"%s\" to a view because it has row security enabled" msgstr "no se pudo convertir la tabla «%s» en vista porque tiene seguridad de registros activada" -#: rewrite/rewriteDefine.c:475 +#: rewrite/rewriteDefine.c:483 #, c-format msgid "could not convert table \"%s\" to a view because it has row security policies" msgstr "no se pudo convertir la tabla «%s» en vista porque tiene políticas de seguridad de registros" -#: rewrite/rewriteDefine.c:502 +#: rewrite/rewriteDefine.c:510 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "no se pueden tener múltiples listas RETURNING en una regla" -#: rewrite/rewriteDefine.c:507 +#: rewrite/rewriteDefine.c:515 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "listas de RETURNING no están soportadas en reglas condicionales" -#: rewrite/rewriteDefine.c:511 +#: rewrite/rewriteDefine.c:519 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "listas de RETURNING no están soportadas en reglas que no estén marcadas INSTEAD" -#: rewrite/rewriteDefine.c:676 +#: rewrite/rewriteDefine.c:683 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "la lista de destinos en la regla de SELECT tiene demasiadas entradas" -#: rewrite/rewriteDefine.c:677 +#: rewrite/rewriteDefine.c:684 #, c-format msgid "RETURNING list has too many entries" msgstr "la lista de RETURNING tiene demasiadas entradas" -#: rewrite/rewriteDefine.c:704 +#: rewrite/rewriteDefine.c:711 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "no se puede convertir en vista una relación que contiene columnas eliminadas" -#: rewrite/rewriteDefine.c:705 +#: rewrite/rewriteDefine.c:712 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "no se puede crear una lista RETURNING para una relación que contiene columnas eliminadas" -#: rewrite/rewriteDefine.c:711 +#: rewrite/rewriteDefine.c:718 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "la entrada de destino %d de la regla de SELECT tiene un nombre de columna diferente de «%s»" -#: rewrite/rewriteDefine.c:713 +#: rewrite/rewriteDefine.c:720 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "La entrada de destino de SELECT tiene nombre «%s»." -#: rewrite/rewriteDefine.c:722 +#: rewrite/rewriteDefine.c:729 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "el destino %d de la regla de SELECT tiene un tipo diferente de la columna «%s»" -#: rewrite/rewriteDefine.c:724 +#: rewrite/rewriteDefine.c:731 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "el destino %d de la lista de RETURNING tiene un tipo diferente de la columna «%s»" -#: rewrite/rewriteDefine.c:727 rewrite/rewriteDefine.c:751 +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "La entrada de destino de SELECT tiene un tipo «%s», pero la columna tiene tipo «%s»." -#: rewrite/rewriteDefine.c:730 rewrite/rewriteDefine.c:755 +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "una entrada de la lista RETURNING tiene tipo %s, pero la columna tiene tipo %s." -#: rewrite/rewriteDefine.c:746 +#: rewrite/rewriteDefine.c:753 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "el destino %d de la regla de SELECT tiene un tamaño diferente de la columna «%s»" -#: rewrite/rewriteDefine.c:748 +#: rewrite/rewriteDefine.c:755 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "el destino %d de la lista RETURNING tiene un tamaño diferente de la columna «%s»" -#: rewrite/rewriteDefine.c:765 +#: rewrite/rewriteDefine.c:772 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "la lista de destinos de regla de SELECT tiene muy pocas entradas" -#: rewrite/rewriteDefine.c:766 +#: rewrite/rewriteDefine.c:773 #, c-format msgid "RETURNING list has too few entries" msgstr "la lista de RETURNING tiene muy pocas entradas" -#: rewrite/rewriteDefine.c:858 rewrite/rewriteDefine.c:972 +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 #: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "no existe la regla «%s» para la relación «%s»" -#: rewrite/rewriteDefine.c:991 +#: rewrite/rewriteDefine.c:999 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "no se permite cambiar el nombre de una regla ON SELECT" -#: rewrite/rewriteHandler.c:543 +#: rewrite/rewriteHandler.c:544 #, c-format msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" msgstr "el nombre de consulta WITH «%s» aparece tanto en una acción de regla y en la consulta que está siendo reescrita" -#: rewrite/rewriteHandler.c:603 +#: rewrite/rewriteHandler.c:604 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "no se puede usar RETURNING en múltiples reglas" -#: rewrite/rewriteHandler.c:818 -#, fuzzy, c-format +#: rewrite/rewriteHandler.c:813 rewrite/rewriteHandler.c:825 +#, c-format msgid "cannot insert into column \"%s\"" -msgstr "no se puede insertar en la vista «%s»" +msgstr "no se puede insertar en la columna «%s»" -#: rewrite/rewriteHandler.c:819 rewrite/rewriteHandler.c:834 +#: rewrite/rewriteHandler.c:814 rewrite/rewriteHandler.c:836 #, c-format msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." -msgstr "" +msgstr "La columna \"% s\" es una columna de identidad definida como GENERATED ALWAYS." -#: rewrite/rewriteHandler.c:821 +#: rewrite/rewriteHandler.c:816 #, c-format msgid "Use OVERRIDING SYSTEM VALUE to override." -msgstr "" +msgstr "Use OVERRIDING SYSTEM VALUE para controlar manualmente." -#: rewrite/rewriteHandler.c:833 -#, fuzzy, c-format +#: rewrite/rewriteHandler.c:835 rewrite/rewriteHandler.c:842 +#, c-format msgid "column \"%s\" can only be updated to DEFAULT" -msgstr "la columna «%s» no puede ser declarada SETOF" +msgstr "la columna «%s» sólo puede actualizarse a DEFAULT" -#: rewrite/rewriteHandler.c:984 rewrite/rewriteHandler.c:1002 +#: rewrite/rewriteHandler.c:1011 rewrite/rewriteHandler.c:1029 #, c-format msgid "multiple assignments to same column \"%s\"" msgstr "hay múltiples asignaciones a la misma columna «%s»" -#: rewrite/rewriteHandler.c:1778 rewrite/rewriteHandler.c:3400 -#, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "se detectó recursión infinita en las reglas de la relación «%s»" - -#: rewrite/rewriteHandler.c:1864 +#: rewrite/rewriteHandler.c:2059 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "se detectó recursión infinita en la política para la relación «%s»" -#: rewrite/rewriteHandler.c:2181 +#: rewrite/rewriteHandler.c:2379 msgid "Junk view columns are not updatable." msgstr "Las columnas «basura» de vistas no son actualizables." -#: rewrite/rewriteHandler.c:2186 +#: rewrite/rewriteHandler.c:2384 msgid "View columns that are not columns of their base relation are not updatable." msgstr "Las columnas de vistas que no son columnas de su relación base no son actualizables." -#: rewrite/rewriteHandler.c:2189 +#: rewrite/rewriteHandler.c:2387 msgid "View columns that refer to system columns are not updatable." msgstr "Las columnas de vistas que se refieren a columnas de sistema no son actualizables." -#: rewrite/rewriteHandler.c:2192 +#: rewrite/rewriteHandler.c:2390 msgid "View columns that return whole-row references are not updatable." msgstr "Las columnas de vistas que retornan referencias a la fila completa no son actualizables." # XXX a %s here would be nice ... -#: rewrite/rewriteHandler.c:2250 +#: rewrite/rewriteHandler.c:2451 msgid "Views containing DISTINCT are not automatically updatable." msgstr "Las vistas que contienen DISTINCT no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2253 +#: rewrite/rewriteHandler.c:2454 msgid "Views containing GROUP BY are not automatically updatable." msgstr "Las vistas que contienen GROUP BY no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2256 +#: rewrite/rewriteHandler.c:2457 msgid "Views containing HAVING are not automatically updatable." msgstr "Las vistas que contienen HAVING no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2259 +#: rewrite/rewriteHandler.c:2460 msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "Las vistas que contienen UNION, INTERSECT o EXCEPT no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2262 +#: rewrite/rewriteHandler.c:2463 msgid "Views containing WITH are not automatically updatable." msgstr "Las vistas que contienen WITH no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2265 +#: rewrite/rewriteHandler.c:2466 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "Las vistas que contienen LIMIT u OFFSET no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2277 +#: rewrite/rewriteHandler.c:2478 msgid "Views that return aggregate functions are not automatically updatable." msgstr "Las vistas que retornan funciones de agregación no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2280 +#: rewrite/rewriteHandler.c:2481 msgid "Views that return window functions are not automatically updatable." msgstr "Las vistas que retornan funciones ventana no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2283 +#: rewrite/rewriteHandler.c:2484 msgid "Views that return set-returning functions are not automatically updatable." msgstr "Las vistas que retornan funciones-que-retornan-conjuntos no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2290 rewrite/rewriteHandler.c:2294 -#: rewrite/rewriteHandler.c:2302 +#: rewrite/rewriteHandler.c:2491 rewrite/rewriteHandler.c:2495 +#: rewrite/rewriteHandler.c:2503 msgid "Views that do not select from a single table or view are not automatically updatable." msgstr "Las vistas que no extraen desde una única tabla o vista no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2305 +#: rewrite/rewriteHandler.c:2506 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "Las vistas que contienen TABLESAMPLE no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2329 +#: rewrite/rewriteHandler.c:2530 msgid "Views that have no updatable columns are not automatically updatable." msgstr "Las vistas que no tienen columnas actualizables no son automáticamente actualizables." -#: rewrite/rewriteHandler.c:2783 +#: rewrite/rewriteHandler.c:2987 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "no se puede insertar en la columna «%s» de la vista «%s»" -#: rewrite/rewriteHandler.c:2791 +#: rewrite/rewriteHandler.c:2995 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "no se puede actualizar la columna «%s» vista «%s»" -#: rewrite/rewriteHandler.c:3194 +#: rewrite/rewriteHandler.c:3471 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "las reglas DO INSTEAD NOTHING no están soportadas para sentencias que modifiquen datos en WITH" -#: rewrite/rewriteHandler.c:3208 +#: rewrite/rewriteHandler.c:3485 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "las reglas DO INSTEAD condicionales no están soportadas para sentencias que modifiquen datos en WITH" -#: rewrite/rewriteHandler.c:3212 +#: rewrite/rewriteHandler.c:3489 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "las reglas DO ALSO no están soportadas para sentencias que modifiquen datos en WITH" -#: rewrite/rewriteHandler.c:3217 +#: rewrite/rewriteHandler.c:3494 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "las reglas DO INSTEAD de múltiples sentencias no están soportadas para sentencias que modifiquen datos en WITH" -#: rewrite/rewriteHandler.c:3437 +#: rewrite/rewriteHandler.c:3744 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "no se puede hacer INSERT RETURNING a la relación «%s»" -#: rewrite/rewriteHandler.c:3439 +#: rewrite/rewriteHandler.c:3746 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "Necesita un regla incondicional ON INSERT DO INSTEAD con una cláusula RETURNING." -#: rewrite/rewriteHandler.c:3444 +#: rewrite/rewriteHandler.c:3751 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "no se puede hacer UPDATE RETURNING a la relación «%s»" -#: rewrite/rewriteHandler.c:3446 +#: rewrite/rewriteHandler.c:3753 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "Necesita un regla incondicional ON UPDATE DO INSTEAD con una cláusula RETURNING." -#: rewrite/rewriteHandler.c:3451 +#: rewrite/rewriteHandler.c:3758 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "no se puede hacer DELETE RETURNING a la relación «%s»" -#: rewrite/rewriteHandler.c:3453 +#: rewrite/rewriteHandler.c:3760 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "Necesita un regla incondicional ON DELETE DO INSTEAD con una clásula RETURNING." -#: rewrite/rewriteHandler.c:3471 +#: rewrite/rewriteHandler.c:3778 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT con una cláusula ON CONFLICT no puede usarse con una tabla que tiene reglas INSERT o UPDATE" -#: rewrite/rewriteHandler.c:3528 +#: rewrite/rewriteHandler.c:3835 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH no puede ser usado en una consulta que está siendo convertida en múltiples consultas a través de reglas" @@ -17987,231 +18670,95 @@ msgstr "las sentencias condicionales de utilidad no están implementadas" msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF no está implementado en una vista" -#: rewrite/rewriteManip.c:1434 +#: rewrite/rewriteManip.c:1503 #, c-format msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" msgstr "las variables NEW en reglas ON UPDATE no pueden referenciar columnas que son parte de una asignación múltiple en la orden UPDATE" -#: scan.l:432 -msgid "unterminated /* comment" -msgstr "un comentario /* está inconcluso" - -#: scan.l:461 -msgid "unterminated bit string literal" -msgstr "una cadena de bits está inconclusa" - -#: scan.l:482 -msgid "unterminated hexadecimal string literal" -msgstr "una cadena hexadecimal está inconclusa" - -#: scan.l:532 -#, c-format -msgid "unsafe use of string constant with Unicode escapes" -msgstr "uso inseguro de literal de cadena con escapes Unicode" - -#: scan.l:533 -#, c-format -msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." -msgstr "Los literales de cadena con escapes Unicode no pueden usarse cuando standard_conforming_strings está desactivado." - -#: scan.l:579 scan.l:778 -msgid "invalid Unicode escape character" -msgstr "carácter de escape Unicode no válido" - -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1337 -#: scan.l:1364 scan.l:1368 scan.l:1406 scan.l:1410 scan.l:1432 scan.l:1442 -msgid "invalid Unicode surrogate pair" -msgstr "par sustituto (surrogate) Unicode no válido" - -#: scan.l:627 -#, c-format -msgid "invalid Unicode escape" -msgstr "valor de escape Unicode no válido" - -#: scan.l:628 -#, c-format -msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." -msgstr "Los escapes Unicode deben ser \\uXXXX o \\UXXXXXXXX." - -#: scan.l:639 -#, c-format -msgid "unsafe use of \\' in a string literal" -msgstr "uso inseguro de \\' en un literal de cadena" - -#: scan.l:640 -#, c-format -msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." -msgstr "Use '' para escribir comillas en cadenas. \\' es inseguro en codificaciones de sólo cliente." - -#: scan.l:715 -msgid "unterminated dollar-quoted string" -msgstr "una cadena separada por $ está inconclusa" - -#: scan.l:732 scan.l:758 scan.l:773 -msgid "zero-length delimited identifier" -msgstr "un identificador delimitado tiene largo cero" - -#: scan.l:793 syncrep_scanner.l:89 -msgid "unterminated quoted identifier" -msgstr "un identificador entre comillas está inconcluso" - -#: scan.l:924 -msgid "operator too long" -msgstr "el operador es demasiado largo" - -#. translator: %s is typically the translation of "syntax error" -#: scan.l:1077 -#, c-format -msgid "%s at end of input" -msgstr "%s al final de la entrada" - -#. translator: first %s is typically the translation of "syntax error" -#: scan.l:1085 -#, c-format -msgid "%s at or near \"%s\"" -msgstr "%s en o cerca de «%s»" - -#: scan.l:1251 scan.l:1283 -msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" -msgstr "Los valores de escape Unicode no puede ser usados para valores de «code point» sobre 007F cuando la codificación de servidor no es UTF8" - -#: scan.l:1279 scan.l:1424 -msgid "invalid Unicode escape value" -msgstr "valor de escape Unicode no válido" - -#: scan.l:1488 -#, c-format -msgid "nonstandard use of \\' in a string literal" -msgstr "uso no estandar de \\' en un literal de cadena" - -#: scan.l:1489 -#, c-format -msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." -msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'...')." - -#: scan.l:1498 -#, c-format -msgid "nonstandard use of \\\\ in a string literal" -msgstr "uso no estandar de \\\\ en un literal de cadena" - -#: scan.l:1499 -#, c-format -msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." -msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'\\\\')." - -#: scan.l:1513 -#, c-format -msgid "nonstandard use of escape in a string literal" -msgstr "uso no estandar de escape en un literal de cadena" - -#: scan.l:1514 -#, c-format -msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." -msgstr "Use la sintaxis de escape para cadenas, por ej. E'\\r\\n'." - -#: snowball/dict_snowball.c:177 +#: snowball/dict_snowball.c:197 #, c-format msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" msgstr "no se encontró un analizador Snowball para el lenguaje «%s» y la codificación «%s»" -#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:74 +#: snowball/dict_snowball.c:220 tsearch/dict_ispell.c:74 #: tsearch/dict_simple.c:49 #, c-format msgid "multiple StopWords parameters" msgstr "parámetro StopWords duplicado" -#: snowball/dict_snowball.c:209 +#: snowball/dict_snowball.c:229 #, c-format msgid "multiple Language parameters" msgstr "parámetro Language duplicado" -#: snowball/dict_snowball.c:216 +#: snowball/dict_snowball.c:236 #, c-format msgid "unrecognized Snowball parameter: \"%s\"" msgstr "parámetro Snowball no reconocido: «%s»" -#: snowball/dict_snowball.c:224 +#: snowball/dict_snowball.c:244 #, c-format msgid "missing Language parameter" msgstr "falta un parámetro Language" -#: statistics/dependencies.c:542 -#, c-format -msgid "invalid zero-length item array in MVDependencies" -msgstr "" - #: statistics/dependencies.c:673 statistics/dependencies.c:726 -#: statistics/mvdistinct.c:338 statistics/mvdistinct.c:391 -#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 -#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 -#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 -#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 -#: utils/adt/pseudotypes.c:393 +#: statistics/mcv.c:1310 statistics/mcv.c:1341 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:94 +#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 +#: utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 +#: utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 +#: utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 #, c-format msgid "cannot accept a value of type %s" msgstr "no se puede aceptar un valor de tipo %s" -#: statistics/extended_stats.c:102 -#, fuzzy, c-format -msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" -msgstr "el rol «%s» no pudo ser eliminado de la política «%s» en «%s»" - -#: statistics/mvdistinct.c:259 +#: statistics/extended_stats.c:119 #, c-format -msgid "invalid ndistinct magic %08x (expected %08x)" -msgstr "" - -#: statistics/mvdistinct.c:264 -#, fuzzy, c-format -msgid "invalid ndistinct type %d (expected %d)" -msgstr "tipo de dato erróneo: %u, se esperaba %u" - -#: statistics/mvdistinct.c:269 -#, fuzzy, c-format -msgid "invalid zero-length item array in MVNDistinct" -msgstr "el largo largo no es válido en cadena de bits externa" +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "el objeto de estadísticas «%s.%s» no pudo ser calculado para la relación «%s.%s»" -#: statistics/mvdistinct.c:278 +#: statistics/mcv.c:1166 utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 #, c-format -msgid "invalid MVNDistinct size %zd (expected at least %zd)" -msgstr "" +msgid "function returning record called in context that cannot accept type record" +msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" -#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 +#: storage/buffer/bufmgr.c:545 storage/buffer/bufmgr.c:658 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "no se pueden acceder tablas temporales de otras sesiones" -#: storage/buffer/bufmgr.c:807 +#: storage/buffer/bufmgr.c:814 #, c-format msgid "unexpected data beyond EOF in block %u of relation %s" msgstr "datos inesperados más allá del EOF en el bloque %u de relación %s" -#: storage/buffer/bufmgr.c:809 +#: storage/buffer/bufmgr.c:816 #, c-format msgid "This has been seen to occur with buggy kernels; consider updating your system." msgstr "Esto parece ocurrir sólo con kernels defectuosos; considere actualizar su sistema." -#: storage/buffer/bufmgr.c:907 +#: storage/buffer/bufmgr.c:914 #, c-format msgid "invalid page in block %u of relation %s; zeroing out page" msgstr "la página no es válida en el bloque %u de la relación «%s»; reinicializando la página" -#: storage/buffer/bufmgr.c:4013 +#: storage/buffer/bufmgr.c:4056 #, c-format msgid "could not write block %u of %s" msgstr "no se pudo escribir el bloque %u de %s" -#: storage/buffer/bufmgr.c:4015 +#: storage/buffer/bufmgr.c:4058 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "Múltiples fallas --- el error de escritura puede ser permanente." -#: storage/buffer/bufmgr.c:4036 storage/buffer/bufmgr.c:4055 +#: storage/buffer/bufmgr.c:4079 storage/buffer/bufmgr.c:4098 #, c-format msgid "writing block %u of relation %s" msgstr "escribiendo el bloque %u de la relación %s" -#: storage/buffer/bufmgr.c:4356 +#: storage/buffer/bufmgr.c:4401 #, c-format msgid "snapshot too old" msgstr "snapshot demasiado antiguo" @@ -18226,183 +18773,217 @@ msgstr "no hay ningún búfer local disponible" msgid "cannot access temporary tables during a parallel operation" msgstr "no se pueden acceder tablas temporales durante una operación paralela" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "no se pudo abrir archivo temporal «%s» del BufFile «%s»: %m" + +#: storage/file/buffile.c:796 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "no se pudo determinar el tamaño del archivo temporal «%s» del BufFile «%s»: %m" + +#: storage/file/fd.c:458 storage/file/fd.c:530 storage/file/fd.c:566 #, c-format msgid "could not flush dirty data: %m" msgstr "no se pudo sincronizar (flush) datos «sucios»: %m" -#: storage/file/fd.c:473 +#: storage/file/fd.c:488 #, c-format msgid "could not determine dirty data size: %m" msgstr "no se pudo determinar el tamaño de los datos «sucios»: %m" -#: storage/file/fd.c:525 +#: storage/file/fd.c:540 #, c-format msgid "could not munmap() while flushing data: %m" msgstr "no se pudo ejecutar munmap() mientras se sincronizaban (flush) datos: %m" -#: storage/file/fd.c:726 +#: storage/file/fd.c:748 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "no se pudo enlazar (link) el archivo «%s» a «%s»: %m" -#: storage/file/fd.c:820 +#: storage/file/fd.c:842 #, c-format msgid "getrlimit failed: %m" msgstr "getrlimit falló: %m" -#: storage/file/fd.c:910 +#: storage/file/fd.c:932 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "los descriptores de archivo disponibles son insuficientes para iniciar un proceso servidor" -#: storage/file/fd.c:911 +#: storage/file/fd.c:933 #, c-format msgid "System allows %d, we need at least %d." msgstr "El sistema permite %d, se requieren al menos %d." -#: storage/file/fd.c:952 storage/file/fd.c:2129 storage/file/fd.c:2222 -#: storage/file/fd.c:2370 +#: storage/file/fd.c:984 storage/file/fd.c:2246 storage/file/fd.c:2356 +#: storage/file/fd.c:2507 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "se agotaron los descriptores de archivo: %m; libere e intente nuevamente" -#: storage/file/fd.c:1557 +#: storage/file/fd.c:1284 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "archivo temporal: ruta «%s», tamaño %lu" -#: storage/file/fd.c:1760 +#: storage/file/fd.c:1415 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "no se pudo crear el directorio temporal «%s»: %m" + +#: storage/file/fd.c:1422 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "no se pudo crear el subdirectorio temporal «%s»: %m" + +#: storage/file/fd.c:1615 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "no se pudo crear el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1650 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "no se pudo abrir el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1691 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "no se pudo eliminar (unlink) el archivo temporal «%s»: %m" + +#: storage/file/fd.c:1955 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "el tamaño del archivo temporal excede temp_file_limit permitido (%dkB)" -#: storage/file/fd.c:2105 storage/file/fd.c:2155 +#: storage/file/fd.c:2222 storage/file/fd.c:2281 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de abrir el archivo «%s»" -#: storage/file/fd.c:2195 +#: storage/file/fd.c:2326 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de ejecutar la orden «%s»" -#: storage/file/fd.c:2346 +#: storage/file/fd.c:2483 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "se excedió maxAllocatedDescs (%d) mientras se trataba de abrir el directorio «%s»" -#: storage/file/fd.c:2432 utils/adt/genfile.c:511 +#: storage/file/fd.c:2574 #, c-format msgid "could not read directory \"%s\": %m" msgstr "no se pudo leer el directorio «%s»: %m" -#: storage/ipc/dsm.c:364 +#: storage/file/fd.c:3006 #, c-format -msgid "dynamic shared memory control segment is corrupt" -msgstr "el segmento de control de memoria compartida dinámica está corrupto" +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "archivo inesperado en directorio de archivos temporales: «%s»" + +#: storage/file/fd.c:3331 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "no se pudo eliminar (rmdir) el directorio «%s»: %m" -#: storage/ipc/dsm.c:411 +#: storage/file/sharedfileset.c:95 #, c-format -msgid "dynamic shared memory is disabled" -msgstr "la memoria compartida dinámica está deshabilitada" +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "no se puede adjuntar a un SharedFileSet que ya está destruido" -#: storage/ipc/dsm.c:412 +#: storage/ipc/dsm.c:343 #, c-format -msgid "Set dynamic_shared_memory_type to a value other than \"none\"." -msgstr "Defina dynamic_shared_memory_type a un valor distinto de «none»." +msgid "dynamic shared memory control segment is corrupt" +msgstr "el segmento de control de memoria compartida dinámica está corrupto" -#: storage/ipc/dsm.c:432 +#: storage/ipc/dsm.c:404 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "el segmento de control de memoria compartida dinámica no es válido" -#: storage/ipc/dsm.c:528 +#: storage/ipc/dsm.c:500 #, c-format msgid "too many dynamic shared memory segments" msgstr "demasiados segmentos de memoria compartida dinámica" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 -#: storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 -#: storage/ipc/dsm_impl.c:819 storage/ipc/dsm_impl.c:963 +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:517 +#: storage/ipc/dsm_impl.c:621 storage/ipc/dsm_impl.c:792 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "no se pudo desmapear el segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 -#: storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:829 +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:527 +#: storage/ipc/dsm_impl.c:631 storage/ipc/dsm_impl.c:802 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "no se pudo eliminar el segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:729 -#: storage/ipc/dsm_impl.c:843 +#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:702 +#: storage/ipc/dsm_impl.c:816 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "no se pudo abrir el segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 -#: storage/ipc/dsm_impl.c:774 storage/ipc/dsm_impl.c:867 +#: storage/ipc/dsm_impl.c:285 storage/ipc/dsm_impl.c:543 +#: storage/ipc/dsm_impl.c:747 storage/ipc/dsm_impl.c:840 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "no se pudo hacer stat del segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:886 -#: storage/ipc/dsm_impl.c:936 +#: storage/ipc/dsm_impl.c:311 storage/ipc/dsm_impl.c:891 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "no se pudo redimensionar el segmento de memoria compartida «%s» a %zu bytes: %m" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 -#: storage/ipc/dsm_impl.c:750 storage/ipc/dsm_impl.c:987 +#: storage/ipc/dsm_impl.c:332 storage/ipc/dsm_impl.c:564 +#: storage/ipc/dsm_impl.c:723 storage/ipc/dsm_impl.c:913 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "no se pudo mapear el segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:515 +#: storage/ipc/dsm_impl.c:499 #, c-format msgid "could not get shared memory segment: %m" msgstr "no se pudo obtener el segmento de memoria compartida: %m" -#: storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:687 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "no se pudo crear el segmento de memoria compartida «%s»: %m" -#: storage/ipc/dsm_impl.c:1029 storage/ipc/dsm_impl.c:1077 -#, c-format -msgid "could not duplicate handle for \"%s\": %m" -msgstr "no se pudo duplicar el «handle» para «%s»: %m" - -#: storage/ipc/latch.c:828 +#: storage/ipc/dsm_impl.c:924 #, c-format -msgid "epoll_ctl() failed: %m" -msgstr "epoll_ctl() fallida: %m" +msgid "could not close shared memory segment \"%s\": %m" +msgstr "no se pudo cerrar el segmento de memoria compartida «%s»: %m" -#: storage/ipc/latch.c:1057 +#: storage/ipc/dsm_impl.c:963 storage/ipc/dsm_impl.c:1011 #, c-format -msgid "epoll_wait() failed: %m" -msgstr "epoll_wait() fallida: %m" +msgid "could not duplicate handle for \"%s\": %m" +msgstr "no se pudo duplicar el «handle» para «%s»: %m" -#: storage/ipc/latch.c:1179 +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:860 storage/ipc/latch.c:1093 storage/ipc/latch.c:1219 #, c-format -msgid "poll() failed: %m" -msgstr "poll() fallida: %m" +msgid "%s failed: %m" +msgstr "%s falló: %m" -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:190 storage/lmgr/lock.c:883 -#: storage/lmgr/lock.c:917 storage/lmgr/lock.c:2679 storage/lmgr/lock.c:4004 -#: storage/lmgr/lock.c:4069 storage/lmgr/lock.c:4361 -#: storage/lmgr/predicate.c:2386 storage/lmgr/predicate.c:2401 -#: storage/lmgr/predicate.c:3793 storage/lmgr/predicate.c:4936 -#: utils/hash/dynahash.c:1043 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:929 +#: storage/lmgr/lock.c:967 storage/lmgr/lock.c:2754 storage/lmgr/lock.c:4084 +#: storage/lmgr/lock.c:4149 storage/lmgr/lock.c:4441 +#: storage/lmgr/predicate.c:2404 storage/lmgr/predicate.c:2419 +#: storage/lmgr/predicate.c:3918 storage/lmgr/predicate.c:5075 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "memoria compartida agotada" #: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 -#, fuzzy, c-format +#, c-format msgid "out of shared memory (%zu bytes requested)" -msgstr "el espacio de memoria compartida es insuficiente para la estructura «%s» (%zu bytes solicitados" +msgstr "memoria compartida agotada (%zu bytes solicitados)" #: storage/ipc/shmem.c:421 #, c-format @@ -18417,39 +18998,85 @@ msgstr "el tamaño de la entrada ShmemIndex es incorrecto para la estructura «% #: storage/ipc/shmem.c:453 #, c-format msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" -msgstr "el espacio de memoria compartida es insuficiente para la estructura «%s» (%zu bytes solicitados" +msgstr "el espacio de memoria compartida es insuficiente para la estructura «%s» (%zu bytes solicitados)" #: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 #, c-format msgid "requested shared memory size overflows size_t" msgstr "la petición de tamaño de memoria compartida desborda size_t" -#: storage/ipc/standby.c:531 tcop/postgres.c:2985 +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d no es un proceso servidor de PostgreSQL" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1364 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "no se pudo enviar la señal al proceso %d: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "debe ser superusuario para cancelar una consulta de superusuario" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "debe ser miembro del rol cuya consulta se está cancelando o ser miembro de pg_signal_backend" + +#: storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "debe ser superusuario para terminar proceso de superusuario" + +#: storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "debe ser miembro del rol cuyo proceso se está terminando o ser miembro de pg_signal_backend" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "bebe ser superusuario para rotar archivos de log con adminpack 1.0" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:223 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Considere usar %s, que es parte del servidor, en su lugar." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "la rotación no es posible porque la recoleccion de log no está activa" + +#: storage/ipc/standby.c:558 tcop/postgres.c:3123 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "cancelando la sentencia debido a un conflicto con la recuperación" -#: storage/ipc/standby.c:532 tcop/postgres.c:2271 +#: storage/ipc/standby.c:559 tcop/postgres.c:2397 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "La transacción del usuario causó un «deadlock» con la recuperación." -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:189 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "la entrada pg_largeobject para el OID %u, página %d tiene tamaño de campo %d no válido" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:270 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "opciones no válidas para abrir un objeto grande: %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:460 #, c-format msgid "invalid whence setting: %d" msgstr "parámetro «whence» no válido: %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:632 #, c-format msgid "invalid large object write request size: %d" msgstr "tamaño de petición de escritura de objeto grande no válido: %d" @@ -18474,718 +19101,705 @@ msgstr "se ha detectado un deadlock" msgid "See server log for query details." msgstr "Vea el registro del servidor para obtener detalles de las consultas." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:815 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "mientras se actualizaba la tupla (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:818 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "mientras se borraba la tupla (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:821 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "mientras se bloqueaba la tupla (%u,%u) de la relación «%s»" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:824 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "mientras se bloqueaba la versión actualizada (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:827 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "mientras se insertaba la tupla de índice (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:830 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "mientras se verificaba la unicidad de la tupla (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:833 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "mientras se verificaba la tupla actualizada (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:836 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" -msgstr "mientras se verificaba una restricción por exclusión en la tupla (%u,%u) en la relación «%s»" +msgstr "mientras se verificaba una restricción de exclusión en la tupla (%u,%u) en la relación «%s»" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1093 #, c-format msgid "relation %u of database %u" msgstr "relación %u de la base de datos %u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1099 #, c-format msgid "extension of relation %u of database %u" msgstr "extensión de la relación %u de la base de datos %u" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1105 #, c-format msgid "page %u of relation %u of database %u" msgstr "página %u de la relación %u de la base de datos %u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1112 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "tupla (%u,%u) de la relación %u de la base de datos %u" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1120 #, c-format msgid "transaction %u" msgstr "transacción %u" -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1125 #, c-format msgid "virtual transaction %d/%u" msgstr "transacción virtual %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1131 #, c-format msgid "speculative token %u of transaction %u" msgstr "token especulativo %u de la transacción %u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1137 #, c-format msgid "object %u of class %u of database %u" msgstr "objeto %u de clase %u de la base de datos %u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1145 #, c-format msgid "user lock [%u,%u,%u]" msgstr "candado de usuario [%u,%u,%u]" # XXX is this a good translation? -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1152 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "candado consultivo [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1160 #, c-format msgid "unrecognized locktag type %d" msgstr "tipo de locktag %d no reconocido" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:764 #, c-format msgid "cannot acquire lock mode %s on database objects while recovery is in progress" msgstr "no se puede adquirir candado en modo %s en objetos de la base de datos mientras la recuperación está en proceso" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:766 #, c-format msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "Sólo candados RowExclusiveLock o menor pueden ser adquiridos en objetos de la base de datos durante la recuperación." -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2680 -#: storage/lmgr/lock.c:4005 storage/lmgr/lock.c:4070 storage/lmgr/lock.c:4362 +#: storage/lmgr/lock.c:930 storage/lmgr/lock.c:968 storage/lmgr/lock.c:2755 +#: storage/lmgr/lock.c:4085 storage/lmgr/lock.c:4150 storage/lmgr/lock.c:4442 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "Puede ser necesario incrementar max_locks_per_transaction." -#: storage/lmgr/lock.c:3121 storage/lmgr/lock.c:3237 +#: storage/lmgr/lock.c:3201 storage/lmgr/lock.c:3317 #, c-format msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "no se puede hacer PREPARE mientras se mantienen candados a nivel de sesión y transacción simultáneamente sobre el mismo objeto" -#: storage/lmgr/predicate.c:684 +#: storage/lmgr/predicate.c:703 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "no hay suficientes elementos en RWConflictPool para registrar un conflicto read/write" -#: storage/lmgr/predicate.c:685 storage/lmgr/predicate.c:713 +#: storage/lmgr/predicate.c:704 storage/lmgr/predicate.c:732 #, c-format msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "Puede ser necesario ejecutar menos transacciones al mismo tiempo, o incrementar max_connections." -#: storage/lmgr/predicate.c:712 +#: storage/lmgr/predicate.c:731 #, c-format msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "no hay suficientes elementos en RWConflictPool para registrar un potencial conflicto read/write" -#: storage/lmgr/predicate.c:918 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "la memoria para el seguimiento de conflictos de serialización está casi agotada" - -#: storage/lmgr/predicate.c:919 -#, c-format -msgid "There might be an idle transaction or a forgotten prepared transaction causing this." -msgstr "Puede haber una transacción inactiva o una transacción preparada olvidada que esté causando este problema." - -#: storage/lmgr/predicate.c:1546 +#: storage/lmgr/predicate.c:1538 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "la instantánea postergada era insegura; intentando con una nueva" -#: storage/lmgr/predicate.c:1635 +#: storage/lmgr/predicate.c:1627 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "«default_transaction_isolation» está definido a «serializable»." -#: storage/lmgr/predicate.c:1636 +#: storage/lmgr/predicate.c:1628 #, c-format msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." msgstr "Puede usar «SET default_transaction_isolation = 'repeatable read'» para cambiar el valor por omisión." -#: storage/lmgr/predicate.c:1676 +#: storage/lmgr/predicate.c:1679 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "una transacción que importa un snapshot no debe ser READ ONLY DEFERRABLE" -#: storage/lmgr/predicate.c:1756 utils/time/snapmgr.c:621 -#: utils/time/snapmgr.c:627 +#: storage/lmgr/predicate.c:1758 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 #, c-format msgid "could not import the requested snapshot" msgstr "no se pudo importar el snapshot solicitado" -#: storage/lmgr/predicate.c:1757 utils/time/snapmgr.c:628 -#, fuzzy, c-format -#| msgid "The source transaction %u is not running anymore." -msgid "The source process with pid %d is not running anymore." -msgstr "La transacción de origen %u ya no está en ejecución." +#: storage/lmgr/predicate.c:1759 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "El proceso de origen con PID %d ya no está en ejecución." -#: storage/lmgr/predicate.c:2387 storage/lmgr/predicate.c:2402 -#: storage/lmgr/predicate.c:3794 +#: storage/lmgr/predicate.c:2405 storage/lmgr/predicate.c:2420 +#: storage/lmgr/predicate.c:3919 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "Puede ser necesario incrementar max_pred_locks_per_transaction." -#: storage/lmgr/predicate.c:3948 storage/lmgr/predicate.c:4037 -#: storage/lmgr/predicate.c:4045 storage/lmgr/predicate.c:4084 -#: storage/lmgr/predicate.c:4323 storage/lmgr/predicate.c:4660 -#: storage/lmgr/predicate.c:4672 storage/lmgr/predicate.c:4714 -#: storage/lmgr/predicate.c:4752 +#: storage/lmgr/predicate.c:4075 storage/lmgr/predicate.c:4164 +#: storage/lmgr/predicate.c:4172 storage/lmgr/predicate.c:4211 +#: storage/lmgr/predicate.c:4454 storage/lmgr/predicate.c:4791 +#: storage/lmgr/predicate.c:4803 storage/lmgr/predicate.c:4846 +#: storage/lmgr/predicate.c:4884 #, c-format msgid "could not serialize access due to read/write dependencies among transactions" msgstr "no se pudo serializar el acceso debido a dependencias read/write entre transacciones" -#: storage/lmgr/predicate.c:3950 storage/lmgr/predicate.c:4039 -#: storage/lmgr/predicate.c:4047 storage/lmgr/predicate.c:4086 -#: storage/lmgr/predicate.c:4325 storage/lmgr/predicate.c:4662 -#: storage/lmgr/predicate.c:4674 storage/lmgr/predicate.c:4716 -#: storage/lmgr/predicate.c:4754 +#: storage/lmgr/predicate.c:4077 storage/lmgr/predicate.c:4166 +#: storage/lmgr/predicate.c:4174 storage/lmgr/predicate.c:4213 +#: storage/lmgr/predicate.c:4456 storage/lmgr/predicate.c:4793 +#: storage/lmgr/predicate.c:4805 storage/lmgr/predicate.c:4848 +#: storage/lmgr/predicate.c:4886 #, c-format msgid "The transaction might succeed if retried." msgstr "La transacción podría tener éxito si es reintentada." -#: storage/lmgr/proc.c:1300 +#: storage/lmgr/proc.c:359 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "la cantidad de conexiones standby pedidas excede max_wal_senders (actualmente %d)" + +#: storage/lmgr/proc.c:1335 #, c-format msgid "Process %d waits for %s on %s." msgstr "El proceso %d espera %s en %s." -#: storage/lmgr/proc.c:1311 +#: storage/lmgr/proc.c:1346 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "enviando señal de cancelación a la tarea autovacuum bloqueante con PID %d" -#: storage/lmgr/proc.c:1329 utils/adt/misc.c:269 -#, c-format -msgid "could not send signal to process %d: %m" -msgstr "no se pudo enviar la señal al proceso %d: %m" - -#: storage/lmgr/proc.c:1431 +#: storage/lmgr/proc.c:1466 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "el proceso %d evitó un deadlock para %s en %s reordenando la cola después de %ld.%03d ms" -#: storage/lmgr/proc.c:1446 +#: storage/lmgr/proc.c:1481 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "el proceso %d detectó un deadlock mientras esperaba %s en %s después de %ld.%03d ms" -#: storage/lmgr/proc.c:1455 +#: storage/lmgr/proc.c:1490 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "el proceso %d aún espera %s en %s después de %ld.%03d ms" -#: storage/lmgr/proc.c:1462 +#: storage/lmgr/proc.c:1497 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "el proceso %d adquirió %s en %s después de %ld.%03d ms" -#: storage/lmgr/proc.c:1478 +#: storage/lmgr/proc.c:1513 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "el proceso %d no pudo adquirir %s en %s después de %ld.%03d ms" -#: storage/page/bufpage.c:151 +#: storage/page/bufpage.c:152 #, c-format msgid "page verification failed, calculated checksum %u but expected %u" msgstr "la suma de verificación falló, se calculó %u pero se esperaba %u" -#: storage/page/bufpage.c:213 storage/page/bufpage.c:505 -#: storage/page/bufpage.c:748 storage/page/bufpage.c:881 -#: storage/page/bufpage.c:977 storage/page/bufpage.c:1087 +#: storage/page/bufpage.c:216 storage/page/bufpage.c:510 +#: storage/page/bufpage.c:747 storage/page/bufpage.c:880 +#: storage/page/bufpage.c:976 storage/page/bufpage.c:1086 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "los punteros de página están corruptos: inferior = %u, superior = %u, especial = %u" -#: storage/page/bufpage.c:549 +#: storage/page/bufpage.c:532 #, c-format -msgid "corrupted item pointer: %u" -msgstr "el puntero de item está corrupto: %u" +msgid "corrupted line pointer: %u" +msgstr "puntero de ítem corrupto: %u" -#: storage/page/bufpage.c:560 storage/page/bufpage.c:932 +#: storage/page/bufpage.c:559 storage/page/bufpage.c:931 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "los largos de ítem están corruptos: total %u, espacio disponible %u" -#: storage/page/bufpage.c:767 storage/page/bufpage.c:993 -#: storage/page/bufpage.c:1103 +#: storage/page/bufpage.c:766 storage/page/bufpage.c:904 +#: storage/page/bufpage.c:992 storage/page/bufpage.c:1102 #, c-format -msgid "corrupted item pointer: offset = %u, size = %u" -msgstr "el puntero de ítem está corrupto: posición = %u, tamaño = %u" +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "puntero de ítem corrupto: desplazamiento = %u, tamaño = %u" -#: storage/page/bufpage.c:905 -#, fuzzy, c-format -#| msgid "corrupted item pointer: offset = %u, size = %u" -msgid "corrupted item pointer: offset = %u, length = %u" -msgstr "el puntero de ítem está corrupto: posición = %u, tamaño = %u" - -#: storage/smgr/md.c:448 storage/smgr/md.c:974 +#: storage/smgr/md.c:320 storage/smgr/md.c:815 #, c-format msgid "could not truncate file \"%s\": %m" msgstr "no se pudo truncar el archivo «%s»: %m" -#: storage/smgr/md.c:515 +#: storage/smgr/md.c:394 #, c-format msgid "cannot extend file \"%s\" beyond %u blocks" msgstr "no se pudo extender el archivo «%s» más allá de %u bloques" -#: storage/smgr/md.c:537 storage/smgr/md.c:754 storage/smgr/md.c:830 -#, c-format -msgid "could not seek to block %u in file \"%s\": %m" -msgstr "no se pudo posicionar (seek) al bloque %u en el archivo «%s»: %m" - -#: storage/smgr/md.c:545 +#: storage/smgr/md.c:409 #, c-format msgid "could not extend file \"%s\": %m" msgstr "no se pudo extender el archivo «%s»: %m" -#: storage/smgr/md.c:547 storage/smgr/md.c:554 storage/smgr/md.c:857 +#: storage/smgr/md.c:411 storage/smgr/md.c:418 storage/smgr/md.c:698 #, c-format msgid "Check free disk space." msgstr "Verifique el espacio libre en disco." -#: storage/smgr/md.c:551 +#: storage/smgr/md.c:415 #, c-format msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" msgstr "no se pudo extender el archivo «%s»: sólo se escribieron %d de %d bytes en el bloque %u" -#: storage/smgr/md.c:772 +#: storage/smgr/md.c:619 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "no se pudo leer el bloque %u del archivo «%s»: %m" -#: storage/smgr/md.c:788 +#: storage/smgr/md.c:635 #, c-format msgid "could not read block %u in file \"%s\": read only %d of %d bytes" msgstr "no se pudo leer el bloque %u del archivo «%s»: se leyeron sólo %d de %d bytes" -#: storage/smgr/md.c:848 +#: storage/smgr/md.c:689 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "no se pudo escribir el bloque %u en el archivo «%s»: %m" -#: storage/smgr/md.c:853 +#: storage/smgr/md.c:694 #, c-format msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" msgstr "no se pudo escribir el bloque %u en el archivo «%s»: se escribieron sólo %d de %d bytes" -#: storage/smgr/md.c:945 +#: storage/smgr/md.c:786 #, c-format msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" msgstr "no se pudo truncar el archivo «%s» a %u bloques: es de sólo %u bloques ahora" -#: storage/smgr/md.c:1000 +#: storage/smgr/md.c:841 #, c-format msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "no se pudo truncar el archivo «%s» a %u bloques: %m" -#: storage/smgr/md.c:1282 -#, c-format -msgid "could not fsync file \"%s\" but retrying: %m" -msgstr "no se pudo sincronizar (fsync) archivo «%s» pero reintentando: %m" - -#: storage/smgr/md.c:1445 +#: storage/smgr/md.c:913 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "no se pudo enviar una petición fsync porque la cola de peticiones está llena" -#: storage/smgr/md.c:1914 +#: storage/smgr/md.c:1210 #, c-format msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" msgstr "no se pudo abrir el archivo «%s» (bloque buscado %u): el segmento previo sólo tiene %u bloques" -#: storage/smgr/md.c:1928 +#: storage/smgr/md.c:1224 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "no se pudo abrir el archivo «%s» (bloque buscado %u): %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:463 tcop/fastpath.c:593 +#: storage/sync/sync.c:400 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s» pero reintentando: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" msgstr "el tamaño de argumento %d no es válido en el mensaje de llamada a función" -#: tcop/fastpath.c:309 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "llamada a función fastpath: «%s» (OID %u)" -#: tcop/fastpath.c:391 tcop/postgres.c:1169 tcop/postgres.c:1432 -#: tcop/postgres.c:1812 tcop/postgres.c:2030 +#: tcop/fastpath.c:389 tcop/postgres.c:1288 tcop/postgres.c:1551 +#: tcop/postgres.c:1918 tcop/postgres.c:2139 #, c-format msgid "duration: %s ms" msgstr "duración: %s ms" -#: tcop/fastpath.c:395 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "duración: %s ms llamada a función fastpath: «%s» (OID %u)" -#: tcop/fastpath.c:431 tcop/fastpath.c:558 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "el mensaje de llamada a función contiene %d argumentos pero la función requiere %d" -#: tcop/fastpath.c:439 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "el mensaje de llamada a función contiene %d formatos de argumento pero %d argumentos" -#: tcop/fastpath.c:526 tcop/fastpath.c:609 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "el formato de datos binarios es incorrecto en argumento %d a función" -#: tcop/postgres.c:346 tcop/postgres.c:382 tcop/postgres.c:409 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "se encontró fin de archivo inesperado en la conexión del cliente" -#: tcop/postgres.c:432 tcop/postgres.c:444 tcop/postgres.c:455 -#: tcop/postgres.c:467 tcop/postgres.c:4316 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4473 #, c-format msgid "invalid frontend message type %d" msgstr "el tipo de mensaje de frontend %d no es válido" -#: tcop/postgres.c:938 +#: tcop/postgres.c:1043 #, c-format msgid "statement: %s" msgstr "sentencia: %s" -#: tcop/postgres.c:1174 +#: tcop/postgres.c:1293 #, c-format msgid "duration: %s ms statement: %s" msgstr "duración: %s ms sentencia: %s" -#: tcop/postgres.c:1224 +#: tcop/postgres.c:1343 #, c-format msgid "parse %s: %s" msgstr "parse %s: %s" -#: tcop/postgres.c:1280 +#: tcop/postgres.c:1400 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "no se pueden insertar múltiples órdenes en una sentencia preparada" -#: tcop/postgres.c:1437 +#: tcop/postgres.c:1556 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "duración: %s ms parse: %s: %s" -#: tcop/postgres.c:1482 +#: tcop/postgres.c:1601 #, c-format msgid "bind %s to %s" msgstr "bind %s a %s" -#: tcop/postgres.c:1501 tcop/postgres.c:2320 +#: tcop/postgres.c:1620 tcop/postgres.c:2444 #, c-format msgid "unnamed prepared statement does not exist" msgstr "no existe una sentencia preparada sin nombre" -#: tcop/postgres.c:1543 +#: tcop/postgres.c:1661 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "el mensaje de enlace (bind) tiene %d formatos de parámetro pero %d parámetros" -#: tcop/postgres.c:1549 +#: tcop/postgres.c:1667 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "el mensaje de enlace (bind) entrega %d parámetros, pero la sentencia preparada «%s» requiere %d" -#: tcop/postgres.c:1719 +#: tcop/postgres.c:1827 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "el formato de datos binarios es incorrecto en el parámetro de enlace %d" -#: tcop/postgres.c:1817 +#: tcop/postgres.c:1923 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "duración: %s ms bind %s%s%s: %s" -#: tcop/postgres.c:1865 tcop/postgres.c:2400 +#: tcop/postgres.c:1971 tcop/postgres.c:2528 #, c-format msgid "portal \"%s\" does not exist" msgstr "no existe el portal «%s»" -#: tcop/postgres.c:1950 +#: tcop/postgres.c:2056 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1952 tcop/postgres.c:2038 +#: tcop/postgres.c:2058 tcop/postgres.c:2147 msgid "execute fetch from" msgstr "ejecutar fetch desde" -#: tcop/postgres.c:1953 tcop/postgres.c:2039 +#: tcop/postgres.c:2059 tcop/postgres.c:2148 msgid "execute" msgstr "ejecutar" -#: tcop/postgres.c:2035 +#: tcop/postgres.c:2144 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "duración: %s ms %s %s%s%s: %s" -#: tcop/postgres.c:2161 +#: tcop/postgres.c:2285 #, c-format msgid "prepare: %s" msgstr "prepare: %s" -#: tcop/postgres.c:2224 +#: tcop/postgres.c:2350 #, c-format msgid "parameters: %s" msgstr "parámetros: %s" -#: tcop/postgres.c:2243 +#: tcop/postgres.c:2369 #, c-format msgid "abort reason: recovery conflict" msgstr "razón para abortar: conflicto en la recuperación" -#: tcop/postgres.c:2259 +#: tcop/postgres.c:2385 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "El usuario mantuvo el búfer compartido «clavado» por demasiado tiempo." -#: tcop/postgres.c:2262 +#: tcop/postgres.c:2388 #, c-format msgid "User was holding a relation lock for too long." msgstr "El usuario mantuvo una relación bloqueada por demasiado tiempo." -#: tcop/postgres.c:2265 +#: tcop/postgres.c:2391 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "El usuario estaba o pudo haber estado usando un tablespace que debía ser eliminado." -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2394 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "La consulta del usuario pudo haber necesitado examinar versiones de tuplas que debían eliminarse." -#: tcop/postgres.c:2274 +#: tcop/postgres.c:2400 #, c-format msgid "User was connected to a database that must be dropped." msgstr "El usuario estaba conectado a una base de datos que debía ser eliminada." -#: tcop/postgres.c:2583 +#: tcop/postgres.c:2724 #, c-format msgid "terminating connection because of crash of another server process" msgstr "terminando la conexión debido a una falla en otro proceso servidor" -#: tcop/postgres.c:2584 +#: tcop/postgres.c:2725 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "Postmaster ha ordenado que este proceso servidor cancele la transacción en curso y finalice la conexión, porque otro proceso servidor ha terminado anormalmente y podría haber corrompido la memoria compartida." -#: tcop/postgres.c:2588 tcop/postgres.c:2913 +#: tcop/postgres.c:2729 tcop/postgres.c:3053 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "Dentro de un momento debería poder reconectarse y repetir la consulta." -#: tcop/postgres.c:2674 +#: tcop/postgres.c:2811 #, c-format msgid "floating-point exception" msgstr "excepción de coma flotante" -#: tcop/postgres.c:2675 +#: tcop/postgres.c:2812 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "Se ha recibido una señal de una operación de coma flotante no válida. Esto puede significar un resultado fuera de rango o una operación no válida, como una división por cero." -#: tcop/postgres.c:2843 +#: tcop/postgres.c:2983 #, c-format msgid "canceling authentication due to timeout" msgstr "cancelando la autentificación debido a que se agotó el tiempo de espera" -#: tcop/postgres.c:2847 +#: tcop/postgres.c:2987 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "terminando el proceso autovacuum debido a una orden del administrador" -#: tcop/postgres.c:2851 -#, fuzzy, c-format -#| msgid "terminating connection due to administrator command" +#: tcop/postgres.c:2991 +#, c-format msgid "terminating logical replication worker due to administrator command" -msgstr "terminando la conexión debido a una orden del administrador" +msgstr "terminando el proceso de replicación lógica debido a una orden del administrador" -#: tcop/postgres.c:2855 -#, fuzzy, c-format +#: tcop/postgres.c:2995 +#, c-format msgid "logical replication launcher shutting down" -msgstr "apagando lanzador de autovacuum" +msgstr "lanzador de replicación lógica apagándose" -#: tcop/postgres.c:2868 tcop/postgres.c:2878 tcop/postgres.c:2911 +#: tcop/postgres.c:3008 tcop/postgres.c:3018 tcop/postgres.c:3051 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "terminando la conexión debido a un conflicto con la recuperación" -#: tcop/postgres.c:2884 +#: tcop/postgres.c:3024 #, c-format msgid "terminating connection due to administrator command" msgstr "terminando la conexión debido a una orden del administrador" -#: tcop/postgres.c:2894 +#: tcop/postgres.c:3034 #, c-format msgid "connection to client lost" msgstr "se ha perdido la conexión al cliente" -#: tcop/postgres.c:2962 +#: tcop/postgres.c:3100 #, c-format msgid "canceling statement due to lock timeout" msgstr "cancelando la sentencia debido a que se agotó el tiempo de espera de candados (locks)" -#: tcop/postgres.c:2969 +#: tcop/postgres.c:3107 #, c-format msgid "canceling statement due to statement timeout" msgstr "cancelando la sentencia debido a que se agotó el tiempo de espera de sentencias" -#: tcop/postgres.c:2976 +#: tcop/postgres.c:3114 #, c-format msgid "canceling autovacuum task" msgstr "cancelando tarea de autovacuum" -#: tcop/postgres.c:2999 +#: tcop/postgres.c:3137 #, c-format msgid "canceling statement due to user request" msgstr "cancelando la sentencia debido a una petición del usuario" -#: tcop/postgres.c:3009 +#: tcop/postgres.c:3147 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "terminando la conexión debido a que se agotó el tiempo de espera para transacciones abiertas inactivas" -#: tcop/postgres.c:3123 +#: tcop/postgres.c:3261 #, c-format msgid "stack depth limit exceeded" msgstr "límite de profundidad de stack alcanzado" -#: tcop/postgres.c:3124 +#: tcop/postgres.c:3262 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "Incremente el parámetro de configuración «max_stack_depth» (actualmente %dkB), después de asegurarse que el límite de profundidad de stack de la plataforma es adecuado." -#: tcop/postgres.c:3187 +#: tcop/postgres.c:3325 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "«max_stack_depth» no debe exceder %ldkB." -#: tcop/postgres.c:3189 +#: tcop/postgres.c:3327 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "Incremente el límite de profundidad del stack del sistema usando «ulimit -s» o el equivalente de su sistema." -#: tcop/postgres.c:3549 +#: tcop/postgres.c:3687 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "argumentos de línea de órdenes no válidos para proceso servidor: %s" -#: tcop/postgres.c:3550 tcop/postgres.c:3556 +#: tcop/postgres.c:3688 tcop/postgres.c:3694 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Pruebe «%s --help» para mayor información." -#: tcop/postgres.c:3554 +#: tcop/postgres.c:3692 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: argumento de línea de órdenes no válido: %s" -#: tcop/postgres.c:3616 +#: tcop/postgres.c:3754 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: no se ha especificado base de datos ni usuario" -#: tcop/postgres.c:4224 +#: tcop/postgres.c:4381 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "subtipo %d de mensaje CLOSE no válido" -#: tcop/postgres.c:4259 +#: tcop/postgres.c:4416 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "subtipo %d de mensaje DESCRIBE no válido" -#: tcop/postgres.c:4337 +#: tcop/postgres.c:4494 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "la invocación «fastpath» de funciones no está soportada en conexiones de replicación" -#: tcop/postgres.c:4341 +#: tcop/postgres.c:4498 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "el protocolo extendido de consultas no está soportado en conexiones de replicación" -#: tcop/postgres.c:4511 +#: tcop/postgres.c:4675 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "desconexión: duración de sesión: %d:%02d:%02d.%03d usuario=%s base=%s host=%s%s%s" -#: tcop/pquery.c:645 +#: tcop/pquery.c:642 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "el mensaje de enlace (bind) tiene %d formatos de resultado pero la consulta tiene %d columnas" -#: tcop/pquery.c:952 +#: tcop/pquery.c:949 #, c-format msgid "cursor can only scan forward" msgstr "el cursor sólo se puede desplazar hacia adelante" -#: tcop/pquery.c:953 +#: tcop/pquery.c:950 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "Declárelo con SCROLL para permitirle desplazar hacia atrás." #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:242 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "no se puede ejecutar %s en una transacción de sólo lectura" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:260 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "no se puede ejecutar %s durante una operación paralela" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:279 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "no se puede ejecutar %s durante la recuperación" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:297 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "no se puede ejecutar %s durante una operación restringida por seguridad" -#: tcop/utility.c:765 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" msgstr "debe ser superusuario para ejecutar CHECKPOINT" +#: tcop/utility.c:1353 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "no se puede crear un índice en la tabla particionada «%s»" + +#: tcop/utility.c:1355 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "La tabla «%s» contiene particiones que son tablas foráneas." + #: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" @@ -19335,17 +19949,23 @@ msgstr "marca de afijo «%s» no válida con el valor de marca «long»" msgid "could not open dictionary file \"%s\": %m" msgstr "no se pudo abrir el archivo de diccionario «%s»: %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "la expresión regular no es válida: %s" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 +#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15735 gram.y:15752 +#, c-format +msgid "syntax error" +msgstr "error de sintaxis" + +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format msgid "invalid affix alias \"%s\"" msgstr "alias de afijo «%s» no válido" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "no se pudo abrir el archivo de afijos «%s»: %m" @@ -19360,23 +19980,27 @@ msgstr "el diccionario Ispell sólo permite los valores «default», «long» y msgid "invalid number of flag vector aliases" msgstr "número no válido de alias de opciones" -#: tsearch/spell.c:1542 +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "el número de aliases excede el número especificado %d" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "el archivo de «affix» contiene órdenes en estilos antiguo y nuevo" -#: tsearch/to_tsany.c:179 utils/adt/tsvector.c:271 -#: utils/adt/tsvector_op.c:1134 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1132 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "la cadena es demasiado larga para tsvector (%d bytes, máximo %d bytes)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "línea %d del archivo de configuración «%s»: «%s»" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "conversión desde un wchar_t a la codificación del servidor falló: %m" @@ -19408,452 +20032,457 @@ msgstr "no se pudo abrir el archivo de stopwords «%s»: %m" msgid "text search parser does not support headline creation" msgstr "el analizador de búsqueda en texto no soporta creación de encabezados (headline)" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "parámetro de encabezado (headline) no reconocido: «%s»" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "MinWords debería ser menor que MaxWords" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "MinWords debería ser positivo" -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "ShortWord debería ser >= 0" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "MaxFragments debería ser >= 0" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:93 #, c-format msgid "identifier too long" msgstr "el identificador es demasiado largo" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:94 #, c-format msgid "Identifier must be less than %d characters." msgstr "El identificador debe ser menor a %d caracteres." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "palabra clave no reconocida: «%s»" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "Palabra clave de ACL debe ser «group» o «user»." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "falta un nombre" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "Debe venir un nombre después de una palabra clave «group» o «user»." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "falta un signo «=»" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "carácter de modo no válido: debe ser uno de «%s»" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "debe venir un nombre después del signo «/»" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "usando el cedente por omisión con ID %u" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "el array ACL contiene tipo de datos incorrecto" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "los array de ACL debe ser unidimensional" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "los arrays de ACL no pueden contener valores nulos" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "basura extra al final de la especificación de la ACL" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1212 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "la opción de grant no puede ser otorgada de vuelta a quien la otorgó" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1273 #, c-format msgid "dependent privileges exist" msgstr "existen privilegios dependientes" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1274 #, c-format msgid "Use CASCADE to revoke them too." msgstr "Use CASCADE para revocarlos también." -#: utils/adt/acl.c:1520 +#: utils/adt/acl.c:1536 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert ya no está soportado" -#: utils/adt/acl.c:1530 +#: utils/adt/acl.c:1546 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove ya no está soportado" -#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#: utils/adt/acl.c:1632 utils/adt/acl.c:1686 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "tipo de privilegio no reconocido: «%s»" -#: utils/adt/acl.c:3410 utils/adt/regproc.c:102 utils/adt/regproc.c:277 +#: utils/adt/acl.c:3486 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "no existe la función «%s»" -#: utils/adt/acl.c:4864 +#: utils/adt/acl.c:4958 #, c-format msgid "must be member of role \"%s\"" msgstr "debe ser miembro del rol «%s»" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5846 -#: utils/adt/arrayfuncs.c:6157 utils/adt/arrayutils.c:93 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5909 +#: utils/adt/arrayfuncs.c:6250 utils/adt/arrayutils.c:93 #: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "el tamaño del array excede el máximo permitido (%d)" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:471 -#: utils/adt/array_userfuncs.c:551 utils/adt/json.c:1764 utils/adt/json.c:1859 -#: utils/adt/json.c:1897 utils/adt/jsonb.c:1127 utils/adt/jsonb.c:1156 -#: utils/adt/jsonb.c:1592 utils/adt/jsonb.c:1756 utils/adt/jsonb.c:1766 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1094 utils/adt/jsonb.c:1123 +#: utils/adt/jsonb.c:1517 utils/adt/jsonb.c:1681 utils/adt/jsonb.c:1691 #, c-format msgid "could not determine input data type" msgstr "no se pudo determinar el tipo de dato de entrada" -#: utils/adt/array_userfuncs.c:84 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "el tipo de entrada no es un array" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 -#: utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:608 -#: utils/adt/int.c:637 utils/adt/int.c:658 utils/adt/int.c:689 -#: utils/adt/int.c:722 utils/adt/int.c:744 utils/adt/int.c:892 -#: utils/adt/int.c:913 utils/adt/int.c:940 utils/adt/int.c:980 -#: utils/adt/int.c:1001 utils/adt/int.c:1028 utils/adt/int.c:1061 -#: utils/adt/int.c:1144 utils/adt/int8.c:1298 utils/adt/numeric.c:2953 -#: utils/adt/numeric.c:2962 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 -#: utils/adt/varlena.c:1054 utils/adt/varlena.c:2953 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1220 utils/adt/float.c:1308 +#: utils/adt/float.c:3883 utils/adt/float.c:3897 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int8.c:1167 utils/adt/numeric.c:1565 +#: utils/adt/numeric.c:3240 utils/adt/varbit.c:1183 utils/adt/varbit.c:1585 +#: utils/adt/varlena.c:1075 utils/adt/varlena.c:3362 #, c-format msgid "integer out of range" msgstr "el entero está fuera de rango" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "el argumento debe ser vacío o un array unidimensional" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 -#: utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 -#: utils/adt/array_userfuncs.c:411 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "no se pueden concatenar arrays incompatibles" -#: utils/adt/array_userfuncs.c:279 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "Los arrays con elementos de tipo %s y %s son incompatibles para la concatenación." -#: utils/adt/array_userfuncs.c:318 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "Los arrays de dimesiones %d y %d son incompatibles para la concatenación." -#: utils/adt/array_userfuncs.c:355 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "Los arrays con elementos de diferentes dimensiones son incompatibles para la concatenación." -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "Los arrays con diferentes dimensiones son incompatibles para la concatenación." -#: utils/adt/array_userfuncs.c:667 utils/adt/array_userfuncs.c:819 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "no está soportada la búsqueda de elementos en arrays multidimensionales" -#: utils/adt/array_userfuncs.c:691 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "la posición inicial no debe ser null" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" -msgstr "literal de array no es válido: «%s»" +msgstr "literal de array mal formado: «%s»" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "Un «[» debe introducir dimensiones de array especificadas explícitamente." -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "Falta un valor de dimensión de array." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "Falta «%s» luego de las dimensiones de array." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "el límite superior no puede ser menor que el límite inferior" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "El valor de array debe comenzar con «{» o información de dimensión." -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." msgstr "El contenido del array debe empezar con «{»." -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "Las dimensiones del array especificadas no coinciden con el contenido del array." -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2114 utils/adt/rangetypes.c:2122 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2179 utils/adt/rangetypes.c:2187 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 #, c-format msgid "Unexpected end of input." msgstr "Fin inesperado de la entrada." -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "Carácter «%c» inesperado." -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "Elemento de array inesperado." -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "Carácter «%c» sin pareja" -#: utils/adt/arrayfuncs.c:597 utils/adt/jsonfuncs.c:2381 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "Los arrays multidimensionales deben tener sub-arrays con dimensiones coincidentes." -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "Basura después de la llave derecha de cierre." -#: utils/adt/arrayfuncs.c:1284 utils/adt/arrayfuncs.c:3357 -#: utils/adt/arrayfuncs.c:5752 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5815 #, c-format msgid "invalid number of dimensions: %d" msgstr "número incorrecto de dimensiones: %d" -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" msgstr "opciones de array no válidas" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "el tipo de elemento es erróneo" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2683 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "no hay una función binaria de entrada para el tipo %s" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "el formato binario no es válido en elemento %d de array" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2716 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "no hay una función binaria de salida para el tipo %s" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "no está implementada la obtención de segmentos de arrays de largo fijo" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5738 -#: utils/adt/arrayfuncs.c:5764 utils/adt/arrayfuncs.c:5775 -#: utils/adt/json.c:2295 utils/adt/json.c:2370 utils/adt/jsonb.c:1370 -#: utils/adt/jsonb.c:1456 utils/adt/jsonfuncs.c:4141 -#: utils/adt/jsonfuncs.c:4292 utils/adt/jsonfuncs.c:4337 -#: utils/adt/jsonfuncs.c:4384 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5801 +#: utils/adt/arrayfuncs.c:5827 utils/adt/arrayfuncs.c:5838 +#: utils/adt/json.c:2325 utils/adt/json.c:2400 utils/adt/jsonb.c:1295 +#: utils/adt/jsonb.c:1381 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "número incorrecto de subíndices del array" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" -msgstr "los subíndices de arrays están fuera de rango" +msgstr "subíndice de array fuera de rango" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "no se puede asignar un valor nulo a un elemento de un array de longitud fija" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "no están implementadas las actualizaciones en segmentos de arrays de largo fija" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format msgid "array slice subscript must provide both boundaries" msgstr "los subíndices del segmento de array deben especificar ambos bordes" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "Cuando se asigna a un segmento de un array vacío, los bordes del segmento deben ser especificados completamente." -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "el array de origen es demasiado pequeño" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "los arrays con elementos null no son permitidos en este contexto" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4123 #, c-format msgid "cannot compare arrays of different element types" msgstr "no se pueden comparar arrays con elementos de distintos tipos" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 #, c-format msgid "could not identify a hash function for type %s" msgstr "no se pudo identificar una función de hash para el tipo %s" -#: utils/adt/arrayfuncs.c:5152 +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "no se pudo identificar una función de hash extendida para el tipo %s" + +#: utils/adt/arrayfuncs.c:5215 #, c-format msgid "data type %s is not an array type" msgstr "el tipo %s no es un array" -#: utils/adt/arrayfuncs.c:5207 +#: utils/adt/arrayfuncs.c:5270 #, c-format msgid "cannot accumulate null arrays" msgstr "no se pueden acumular arrays nulos" -#: utils/adt/arrayfuncs.c:5235 +#: utils/adt/arrayfuncs.c:5298 #, c-format msgid "cannot accumulate empty arrays" msgstr "no se pueden acumular arrays vacíos" -#: utils/adt/arrayfuncs.c:5264 utils/adt/arrayfuncs.c:5270 +#: utils/adt/arrayfuncs.c:5327 utils/adt/arrayfuncs.c:5333 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "no se pueden acumular arrays de distinta dimensionalidad" -#: utils/adt/arrayfuncs.c:5636 utils/adt/arrayfuncs.c:5676 +#: utils/adt/arrayfuncs.c:5699 utils/adt/arrayfuncs.c:5739 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "el array de dimensiones o el array de límites inferiores debe ser no nulo" -#: utils/adt/arrayfuncs.c:5739 utils/adt/arrayfuncs.c:5765 +#: utils/adt/arrayfuncs.c:5802 utils/adt/arrayfuncs.c:5828 #, c-format msgid "Dimension array must be one dimensional." msgstr "El array de dimensiones debe ser unidimensional." -#: utils/adt/arrayfuncs.c:5744 utils/adt/arrayfuncs.c:5770 +#: utils/adt/arrayfuncs.c:5807 utils/adt/arrayfuncs.c:5833 #, c-format msgid "dimension values cannot be null" msgstr "los valores de dimensión no pueden ser null" -#: utils/adt/arrayfuncs.c:5776 +#: utils/adt/arrayfuncs.c:5839 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "El array de límites inferiores tiene tamaño diferente que el array de dimensiones." -#: utils/adt/arrayfuncs.c:6022 +#: utils/adt/arrayfuncs.c:6115 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "la eliminación de elementos desde arrays multidimensionales no está soportada" -#: utils/adt/arrayfuncs.c:6299 +#: utils/adt/arrayfuncs.c:6392 #, c-format msgid "thresholds must be one-dimensional array" msgstr "los umbrales deben ser un array unidimensional" -#: utils/adt/arrayfuncs.c:6304 +#: utils/adt/arrayfuncs.c:6397 #, c-format msgid "thresholds array must not contain NULLs" msgstr "el array de umbrales no debe contener nulos" @@ -19879,44 +20508,45 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "la conversión de codificación de %s a ASCII no está soportada" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:153 utils/adt/cash.c:278 utils/adt/datetime.c:3799 -#: utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 -#: utils/adt/float.c:461 utils/adt/float.c:544 utils/adt/float.c:570 -#: utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 utils/adt/geo_ops.c:178 -#: utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 utils/adt/geo_ops.c:265 -#: utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 utils/adt/geo_ops.c:1356 -#: utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3430 utils/adt/geo_ops.c:4563 -#: utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 utils/adt/mac.c:94 -#: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 -#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1539 -#: utils/adt/network.c:58 utils/adt/numeric.c:593 utils/adt/numeric.c:620 -#: utils/adt/numeric.c:5488 utils/adt/numeric.c:5512 utils/adt/numeric.c:5536 -#: utils/adt/numeric.c:6338 utils/adt/numeric.c:6364 utils/adt/oid.c:44 +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3787 +#: utils/adt/float.c:168 utils/adt/float.c:252 utils/adt/float.c:276 +#: utils/adt/float.c:390 utils/adt/float.c:474 utils/adt/float.c:501 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3360 utils/adt/geo_ops.c:4526 +#: utils/adt/geo_ops.c:4541 utils/adt/geo_ops.c:4548 utils/adt/int8.c:128 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:74 utils/adt/numeric.c:607 +#: utils/adt/numeric.c:634 utils/adt/numeric.c:5806 utils/adt/numeric.c:5830 +#: utils/adt/numeric.c:5854 utils/adt/numeric.c:6684 utils/adt/numeric.c:6710 +#: utils/adt/numutils.c:52 utils/adt/numutils.c:62 utils/adt/numutils.c:106 +#: utils/adt/numutils.c:182 utils/adt/numutils.c:258 utils/adt/oid.c:44 #: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 -#: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 -#: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 -#: utils/adt/uuid.c:136 +#: utils/adt/pg_lsn.c:43 utils/adt/pg_lsn.c:49 utils/adt/tid.c:73 +#: utils/adt/tid.c:81 utils/adt/tid.c:89 utils/adt/timestamp.c:495 +#: utils/adt/txid.c:410 utils/adt/uuid.c:136 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "la sintaxis de entrada no es válida para tipo %s: «%s»" -#: utils/adt/cash.c:211 utils/adt/cash.c:238 utils/adt/cash.c:249 -#: utils/adt/cash.c:292 utils/adt/int8.c:114 utils/adt/numutils.c:75 -#: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 -#, fuzzy, c-format +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:120 utils/adt/numutils.c:76 +#: utils/adt/numutils.c:83 utils/adt/numutils.c:176 utils/adt/numutils.c:252 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format msgid "value \"%s\" is out of range for type %s" -msgstr "el valor «%s» está fuera de rango para el tipo oid" - -#: utils/adt/cash.c:653 utils/adt/cash.c:703 utils/adt/cash.c:754 -#: utils/adt/cash.c:803 utils/adt/cash.c:855 utils/adt/cash.c:905 -#: utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 -#: utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:704 -#: utils/adt/int.c:846 utils/adt/int.c:954 utils/adt/int.c:1043 -#: utils/adt/int.c:1082 utils/adt/int.c:1110 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6902 -#: utils/adt/numeric.c:7191 utils/adt/numeric.c:8203 -#: utils/adt/timestamp.c:3216 +msgstr "el valor «%s» está fuera de rango para el tipo %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/int.c:824 utils/adt/int.c:940 utils/adt/int.c:1020 +#: utils/adt/int.c:1082 utils/adt/int.c:1120 utils/adt/int.c:1148 +#: utils/adt/int8.c:595 utils/adt/int8.c:653 utils/adt/int8.c:853 +#: utils/adt/int8.c:933 utils/adt/int8.c:995 utils/adt/int8.c:1075 +#: utils/adt/numeric.c:7248 utils/adt/numeric.c:7537 utils/adt/numeric.c:8549 +#: utils/adt/timestamp.c:3279 #, c-format msgid "division by zero" msgstr "división por cero" @@ -19926,192 +20556,184 @@ msgstr "división por cero" msgid "\"char\" out of range" msgstr "«char» está fuera de rango" -#: utils/adt/date.c:67 utils/adt/timestamp.c:95 utils/adt/varbit.c:53 -#: utils/adt/varchar.c:46 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:55 +#: utils/adt/varchar.c:49 #, c-format msgid "invalid type modifier" msgstr "el modificador de tipo no es válido" -#: utils/adt/date.c:79 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "la precisión de TIME(%d)%s no debe ser negativa" -#: utils/adt/date.c:85 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "la precisión de TIME(%d)%s fue reducida al máximo permitido, %d" -#: utils/adt/date.c:146 utils/adt/datetime.c:1209 utils/adt/datetime.c:2117 +#: utils/adt/date.c:144 utils/adt/datetime.c:1192 utils/adt/datetime.c:2103 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "valor de hora/fecha «current» ya no está soportado" -#: utils/adt/date.c:172 utils/adt/date.c:180 utils/adt/formatting.c:3585 -#: utils/adt/formatting.c:3594 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3733 +#: utils/adt/formatting.c:3742 #, c-format msgid "date out of range: \"%s\"" msgstr "fecha fuera de rango: «%s»" -#: utils/adt/date.c:227 utils/adt/date.c:539 utils/adt/date.c:563 -#: utils/adt/xml.c:2089 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2228 #, c-format msgid "date out of range" msgstr "la fecha fuera de rango" -#: utils/adt/date.c:273 utils/adt/timestamp.c:564 +#: utils/adt/date.c:271 utils/adt/timestamp.c:575 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "un valor en el campo de fecha está fuera de rango: %d-%02d-%02d" -#: utils/adt/date.c:280 utils/adt/date.c:289 utils/adt/timestamp.c:570 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:581 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "fecha fuera de rango: %d-%02d-%02d" -#: utils/adt/date.c:327 utils/adt/date.c:350 utils/adt/date.c:376 -#: utils/adt/date.c:1092 utils/adt/date.c:1138 utils/adt/date.c:1672 -#: utils/adt/date.c:1703 utils/adt/date.c:1732 utils/adt/date.c:2469 -#: utils/adt/datetime.c:1690 utils/adt/formatting.c:3460 -#: utils/adt/formatting.c:3492 utils/adt/formatting.c:3560 -#: utils/adt/json.c:1539 utils/adt/json.c:1561 utils/adt/jsonb.c:824 -#: utils/adt/jsonb.c:848 utils/adt/nabstime.c:456 utils/adt/nabstime.c:499 -#: utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 utils/adt/timestamp.c:230 -#: utils/adt/timestamp.c:262 utils/adt/timestamp.c:692 -#: utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 -#: utils/adt/timestamp.c:812 utils/adt/timestamp.c:2795 -#: utils/adt/timestamp.c:2816 utils/adt/timestamp.c:2829 -#: utils/adt/timestamp.c:2838 utils/adt/timestamp.c:2846 -#: utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2924 -#: utils/adt/timestamp.c:2937 utils/adt/timestamp.c:2948 -#: utils/adt/timestamp.c:2956 utils/adt/timestamp.c:3512 -#: utils/adt/timestamp.c:3637 utils/adt/timestamp.c:3678 -#: utils/adt/timestamp.c:3759 utils/adt/timestamp.c:3805 -#: utils/adt/timestamp.c:3908 utils/adt/timestamp.c:4307 -#: utils/adt/timestamp.c:4406 utils/adt/timestamp.c:4416 -#: utils/adt/timestamp.c:4508 utils/adt/timestamp.c:4610 -#: utils/adt/timestamp.c:4620 utils/adt/timestamp.c:4852 -#: utils/adt/timestamp.c:4866 utils/adt/timestamp.c:4871 -#: utils/adt/timestamp.c:4885 utils/adt/timestamp.c:4930 -#: utils/adt/timestamp.c:4962 utils/adt/timestamp.c:4969 -#: utils/adt/timestamp.c:5002 utils/adt/timestamp.c:5006 -#: utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5079 -#: utils/adt/timestamp.c:5093 utils/adt/timestamp.c:5127 utils/adt/xml.c:2111 -#: utils/adt/xml.c:2118 utils/adt/xml.c:2138 utils/adt/xml.c:2145 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1665 +#: utils/adt/date.c:1696 utils/adt/date.c:1725 utils/adt/date.c:2557 +#: utils/adt/datetime.c:1676 utils/adt/formatting.c:3599 +#: utils/adt/formatting.c:3631 utils/adt/formatting.c:3708 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/timestamp.c:230 +#: utils/adt/timestamp.c:262 utils/adt/timestamp.c:703 +#: utils/adt/timestamp.c:712 utils/adt/timestamp.c:790 +#: utils/adt/timestamp.c:823 utils/adt/timestamp.c:2858 +#: utils/adt/timestamp.c:2879 utils/adt/timestamp.c:2892 +#: utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2909 +#: utils/adt/timestamp.c:2964 utils/adt/timestamp.c:2987 +#: utils/adt/timestamp.c:3000 utils/adt/timestamp.c:3011 +#: utils/adt/timestamp.c:3019 utils/adt/timestamp.c:3679 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3845 +#: utils/adt/timestamp.c:3935 utils/adt/timestamp.c:3979 +#: utils/adt/timestamp.c:4082 utils/adt/timestamp.c:4566 +#: utils/adt/timestamp.c:4665 utils/adt/timestamp.c:4675 +#: utils/adt/timestamp.c:4767 utils/adt/timestamp.c:4869 +#: utils/adt/timestamp.c:4879 utils/adt/timestamp.c:5099 +#: utils/adt/timestamp.c:5113 utils/adt/timestamp.c:5118 +#: utils/adt/timestamp.c:5132 utils/adt/timestamp.c:5165 +#: utils/adt/timestamp.c:5214 utils/adt/timestamp.c:5221 +#: utils/adt/timestamp.c:5254 utils/adt/timestamp.c:5258 +#: utils/adt/timestamp.c:5327 utils/adt/timestamp.c:5331 +#: utils/adt/timestamp.c:5345 utils/adt/timestamp.c:5379 utils/adt/xml.c:2250 +#: utils/adt/xml.c:2257 utils/adt/xml.c:2277 utils/adt/xml.c:2284 #, c-format msgid "timestamp out of range" msgstr "el timestamp está fuera de rango" -#: utils/adt/date.c:514 +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "no se pueden restar fechas infinitas" -#: utils/adt/date.c:592 utils/adt/date.c:623 utils/adt/date.c:641 -#: utils/adt/date.c:2506 utils/adt/date.c:2516 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2594 utils/adt/date.c:2604 #, c-format msgid "date out of range for timestamp" msgstr "fecha fuera de rango para timestamp" -#: utils/adt/date.c:1164 -#, c-format -msgid "cannot convert reserved abstime value to date" -msgstr "no se puede convertir un valor reservado de abstime a date" - -#: utils/adt/date.c:1182 utils/adt/date.c:1188 -#, c-format -msgid "abstime out of range for date" -msgstr "abstime fuera de rango para date" - -#: utils/adt/date.c:1301 utils/adt/date.c:2020 +#: utils/adt/date.c:1278 utils/adt/date.c:2052 #, c-format msgid "time out of range" msgstr "hora fuera de rango" -#: utils/adt/date.c:1357 utils/adt/timestamp.c:589 +#: utils/adt/date.c:1334 utils/adt/timestamp.c:600 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "un valor en el campo de hora está fuera de rango: %d:%02d:%02g" -#: utils/adt/date.c:1907 utils/adt/date.c:1920 +#: utils/adt/date.c:1854 utils/adt/date.c:2356 utils/adt/float.c:1046 +#: utils/adt/float.c:1115 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:494 utils/adt/numeric.c:2203 +#: utils/adt/timestamp.c:3328 utils/adt/timestamp.c:3359 +#: utils/adt/timestamp.c:3390 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "tamaño «preceding» o «following» no válido en ventana deslizante" + +#: utils/adt/date.c:1939 utils/adt/date.c:1952 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "las unidades de «time» «%s» no son reconocidas" -#: utils/adt/date.c:2028 +#: utils/adt/date.c:2060 #, c-format msgid "time zone displacement out of range" msgstr "desplazamiento de huso horario fuera de rango" -#: utils/adt/date.c:2601 utils/adt/date.c:2614 +#: utils/adt/date.c:2689 utils/adt/date.c:2702 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "las unidades de «timestamp with time zone» «%s» no son reconocidas" -#: utils/adt/date.c:2687 utils/adt/datetime.c:931 utils/adt/datetime.c:1848 -#: utils/adt/datetime.c:4636 utils/adt/timestamp.c:503 -#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:4877 -#: utils/adt/timestamp.c:5085 +#: utils/adt/date.c:2775 utils/adt/datetime.c:914 utils/adt/datetime.c:1834 +#: utils/adt/datetime.c:4631 utils/adt/timestamp.c:514 +#: utils/adt/timestamp.c:541 utils/adt/timestamp.c:4165 +#: utils/adt/timestamp.c:5124 utils/adt/timestamp.c:5337 #, c-format msgid "time zone \"%s\" not recognized" msgstr "el huso horario «%s» no es reconocido" -#: utils/adt/date.c:2719 utils/adt/timestamp.c:4919 utils/adt/timestamp.c:5116 +#: utils/adt/date.c:2807 utils/adt/timestamp.c:5154 utils/adt/timestamp.c:5368 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "el intervalo de huso horario «%s» no debe especificar meses o días" -#: utils/adt/datetime.c:3772 utils/adt/datetime.c:3779 +#: utils/adt/datetime.c:3760 utils/adt/datetime.c:3767 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "el valor de hora/fecha está fuera de rango: «%s»" -#: utils/adt/datetime.c:3781 +#: utils/adt/datetime.c:3769 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "Quizás necesite una configuración diferente de «datestyle»." -#: utils/adt/datetime.c:3786 +#: utils/adt/datetime.c:3774 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "el valor de interval está fuera de rango: «%s»" -#: utils/adt/datetime.c:3792 +#: utils/adt/datetime.c:3780 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "el desplazamiento de huso horario está fuera de rango: «%s»" -#: utils/adt/datetime.c:4638 +#: utils/adt/datetime.c:4633 #, c-format msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "Este nombre de huso horario aparece en el archivo de configuración para abreviaciones de husos horarios «%s»." -#: utils/adt/datum.c:86 utils/adt/datum.c:98 +#: utils/adt/datum.c:88 utils/adt/datum.c:100 #, c-format msgid "invalid Datum pointer" msgstr "puntero a Datum no válido" -#: utils/adt/dbsize.c:116 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "no se pudo abrir el directorio de tablespace «%s»: %m" - -#: utils/adt/dbsize.c:764 utils/adt/dbsize.c:832 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format msgid "invalid size: \"%s\"" msgstr "tamaño no válido: «%s»" -#: utils/adt/dbsize.c:833 +#: utils/adt/dbsize.c:828 #, c-format msgid "Invalid size unit: \"%s\"." msgstr "Nombre de unidad de tamaño no válido: «%s»." -#: utils/adt/dbsize.c:834 +#: utils/adt/dbsize.c:829 #, c-format msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "Unidades válidas son «bytes«, «kB», «MB», «GB» y «TB»." -#: utils/adt/domains.c:91 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "tipo «%s» no es un dominio" @@ -20151,691 +20773,696 @@ msgstr "secuencia de término base64 no válida" msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "A los datos de entrada les falta relleno, o están truncados, o están corruptos de alguna otra forma." -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:785 -#: utils/adt/json.c:825 utils/adt/json.c:841 utils/adt/json.c:853 -#: utils/adt/json.c:863 utils/adt/json.c:914 utils/adt/json.c:946 -#: utils/adt/json.c:965 utils/adt/json.c:977 utils/adt/json.c:989 -#: utils/adt/json.c:1134 utils/adt/json.c:1148 utils/adt/json.c:1159 -#: utils/adt/json.c:1167 utils/adt/json.c:1175 utils/adt/json.c:1183 -#: utils/adt/json.c:1191 utils/adt/json.c:1199 utils/adt/json.c:1207 -#: utils/adt/json.c:1215 utils/adt/json.c:1245 utils/adt/varlena.c:296 -#: utils/adt/varlena.c:337 -#, fuzzy, c-format +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:318 +#: utils/adt/varlena.c:359 jsonpath_gram.y:516 jsonpath_scan.l:543 +#: jsonpath_scan.l:559 jsonpath_scan.l:570 jsonpath_scan.l:580 +#: jsonpath_scan.l:622 +#, c-format msgid "invalid input syntax for type %s" -msgstr "sintaxis de entrada no válida para tipo json" +msgstr "sintaxis de entrada no válida para tipo %s" -#: utils/adt/enum.c:115 +#: utils/adt/enum.c:100 #, c-format msgid "unsafe use of new value \"%s\" of enum type %s" -msgstr "" +msgstr "uso inseguro del nuevo valor «%s» del tipo enum %s" -#: utils/adt/enum.c:118 +#: utils/adt/enum.c:103 #, c-format msgid "New enum values must be committed before they can be used." -msgstr "" +msgstr "Los nuevos valores de enum deben estar comprometidos (committed) antes de que puedan usarse." -#: utils/adt/enum.c:136 utils/adt/enum.c:146 utils/adt/enum.c:204 -#: utils/adt/enum.c:214 +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "la sintaxis de entrada no es válida para el enum %s: «%s»" -#: utils/adt/enum.c:176 utils/adt/enum.c:242 utils/adt/enum.c:301 +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 #, c-format msgid "invalid internal value for enum: %u" msgstr "el valor interno no es válido para enum: %u" -#: utils/adt/enum.c:461 utils/adt/enum.c:490 utils/adt/enum.c:530 -#: utils/adt/enum.c:550 +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 #, c-format msgid "could not determine actual enum type" msgstr "no se pudo determinar el tipo enum efectivo" -#: utils/adt/enum.c:469 utils/adt/enum.c:498 +#: utils/adt/enum.c:454 utils/adt/enum.c:483 #, c-format msgid "enum %s contains no values" msgstr "el enum %s no contiene valores" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1574 utils/cache/typcache.c:1730 +#: utils/cache/typcache.c:1860 utils/fmgr/funcapi.c:415 #, c-format -msgid "value out of range: overflow" -msgstr "valor fuera de rango: desbordamiento" - -#: utils/adt/float.c:63 -#, c-format -msgid "value out of range: underflow" -msgstr "valor fuera de rango: desbordamiento por abajo" +msgid "type %s is not composite" +msgstr "el tipo %s no es compuesto" -#: utils/adt/float.c:312 +#: utils/adt/float.c:246 #, c-format msgid "\"%s\" is out of range for type real" msgstr "«%s» está fuera de rango para el tipo real" -#: utils/adt/float.c:537 +#: utils/adt/float.c:466 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "«%s» está fuera de rango para el tipo double precision" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:334 -#: utils/adt/int.c:760 utils/adt/int.c:789 utils/adt/int.c:810 -#: utils/adt/int.c:830 utils/adt/int.c:864 utils/adt/int.c:1159 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3050 utils/adt/numeric.c:3059 +#: utils/adt/float.c:1252 utils/adt/float.c:1340 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1188 utils/adt/numeric.c:3358 utils/adt/numeric.c:3367 #, c-format msgid "smallint out of range" msgstr "smallint está fuera de rango" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7624 +#: utils/adt/float.c:1466 utils/adt/numeric.c:7970 #, c-format msgid "cannot take square root of a negative number" msgstr "no se puede calcular la raíz cuadrada un de número negativo" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2853 +#: utils/adt/float.c:1527 utils/adt/numeric.c:3138 #, c-format msgid "zero raised to a negative power is undefined" msgstr "cero elevado a una potencia negativa es indefinido" -#: utils/adt/float.c:1476 utils/adt/numeric.c:2859 +#: utils/adt/float.c:1531 utils/adt/numeric.c:3144 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "un número negativo elevado a una potencia no positiva entrega un resultado complejo" -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7890 +#: utils/adt/float.c:1597 utils/adt/float.c:1627 utils/adt/numeric.c:8236 #, c-format msgid "cannot take logarithm of zero" msgstr "no se puede calcular logaritmo de cero" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7894 +#: utils/adt/float.c:1601 utils/adt/float.c:1631 utils/adt/numeric.c:8240 #, c-format msgid "cannot take logarithm of a negative number" msgstr "no se puede calcular logaritmo de un número negativo" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 -#: utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 -#: utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 -#: utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: utils/adt/float.c:1661 utils/adt/float.c:1691 utils/adt/float.c:1783 +#: utils/adt/float.c:1809 utils/adt/float.c:1836 utils/adt/float.c:1862 +#: utils/adt/float.c:2009 utils/adt/float.c:2044 utils/adt/float.c:2208 +#: utils/adt/float.c:2262 utils/adt/float.c:2326 utils/adt/float.c:2381 +#: utils/adt/float.c:2569 utils/adt/float.c:2594 #, c-format msgid "input is out of range" msgstr "la entrada está fuera de rango" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1493 +#: utils/adt/float.c:2662 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "parámetro setseed %g fuera del rango permitido [-1,1]" + +#: utils/adt/float.c:2880 utils/adt/float.c:2956 utils/adt/float.c:3179 +#, c-format +msgid "value out of range: overflow" +msgstr "valor fuera de rango: desbordamiento" + +#: utils/adt/float.c:3861 utils/adt/numeric.c:1515 #, c-format msgid "count must be greater than zero" msgstr "count debe ser mayor que cero" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1500 +#: utils/adt/float.c:3866 utils/adt/numeric.c:1522 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "el operando, límite inferior y límite superior no pueden ser NaN" -#: utils/adt/float.c:3543 +#: utils/adt/float.c:3872 #, c-format msgid "lower and upper bounds must be finite" msgstr "los límites inferior y superior deben ser finitos" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1513 +#: utils/adt/float.c:3906 utils/adt/numeric.c:1535 #, c-format msgid "lower bound cannot equal upper bound" msgstr "el límite superior no puede ser igual al límite inferior" -#: utils/adt/formatting.c:493 +#: utils/adt/formatting.c:504 #, c-format msgid "invalid format specification for an interval value" msgstr "especificación de formato no válida para un valor de interval" -#: utils/adt/formatting.c:494 +#: utils/adt/formatting.c:505 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Los Interval no están ... a valores determinados de fechas de calendario." -#: utils/adt/formatting.c:1060 +#: utils/adt/formatting.c:1086 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "«EEEE» debe ser el último patrón usado" -#: utils/adt/formatting.c:1068 +#: utils/adt/formatting.c:1094 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "«9» debe ir antes de «PR»" -#: utils/adt/formatting.c:1084 +#: utils/adt/formatting.c:1110 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "«0» debe ir antes de «PR»" -#: utils/adt/formatting.c:1111 +#: utils/adt/formatting.c:1137 #, c-format msgid "multiple decimal points" msgstr "hay múltiples puntos decimales" -#: utils/adt/formatting.c:1115 utils/adt/formatting.c:1198 +#: utils/adt/formatting.c:1141 utils/adt/formatting.c:1224 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "no se puede usar «V» y un punto decimal simultáneamente" -#: utils/adt/formatting.c:1127 +#: utils/adt/formatting.c:1153 #, c-format msgid "cannot use \"S\" twice" msgstr "no se puede usar «S» dos veces" -#: utils/adt/formatting.c:1131 +#: utils/adt/formatting.c:1157 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "no se puede usar «S» y «PL»/«MI»/«SG»/«PR» simultáneamente" -#: utils/adt/formatting.c:1151 +#: utils/adt/formatting.c:1177 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "no se puede usar «S» y «MI» simultáneamente" -#: utils/adt/formatting.c:1161 +#: utils/adt/formatting.c:1187 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "no se puede usar «S» y «PL» simultáneamente" -#: utils/adt/formatting.c:1171 +#: utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "no se puede usar «S» y «SG» simultáneamente" -#: utils/adt/formatting.c:1180 +#: utils/adt/formatting.c:1206 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "no se puede usar «PR» y «S»/«PL»/«MI»/«SG» simultáneamente" -#: utils/adt/formatting.c:1206 +#: utils/adt/formatting.c:1232 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "no se puede usar «EEEE» dos veces" -#: utils/adt/formatting.c:1212 +#: utils/adt/formatting.c:1238 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "«EEEE» es incompatible con otros formatos" -#: utils/adt/formatting.c:1213 +#: utils/adt/formatting.c:1239 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "«EEEE» sólo puede ser usado en conjunción con patrones de dígitos y puntos decimales." -#: utils/adt/formatting.c:1402 +#: utils/adt/formatting.c:1426 #, c-format msgid "\"%s\" is not a number" msgstr "«%s» no es un número" -#: utils/adt/formatting.c:1480 -#, fuzzy, c-format -msgid "case conversion failed: %s" -msgstr "la expresión regular falló: %s" - -#: utils/adt/formatting.c:1546 -#, c-format -msgid "could not determine which collation to use for lower() function" -msgstr "no se pudo determinar qué ordenamiento (collation) usar para la función lower()" - -#: utils/adt/formatting.c:1670 +#: utils/adt/formatting.c:1504 #, c-format -msgid "could not determine which collation to use for upper() function" -msgstr "no se pudo determinar qué ordenamiento (collation) usar para la función upper()" +msgid "case conversion failed: %s" +msgstr "falló la conversión de mayúsculas: %s" -#: utils/adt/formatting.c:1795 +#: utils/adt/formatting.c:1569 utils/adt/formatting.c:1692 +#: utils/adt/formatting.c:1816 #, c-format -msgid "could not determine which collation to use for initcap() function" -msgstr "no se pudo determinar qué ordenamiento (collation) usar para la función initcap()" +msgid "could not determine which collation to use for %s function" +msgstr "no se pudo determinar qué ordenamiento usar para la función %s" -#: utils/adt/formatting.c:2163 +#: utils/adt/formatting.c:2185 #, c-format msgid "invalid combination of date conventions" msgstr "combinacion invalida de convenciones de fecha" -#: utils/adt/formatting.c:2164 +#: utils/adt/formatting.c:2186 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr " No mezclar convenciones de semana Gregorianas e ISO en una plantilla formateada" -#: utils/adt/formatting.c:2181 +#: utils/adt/formatting.c:2203 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "valores en conflicto para le campo \"%s\" en cadena de formato" -#: utils/adt/formatting.c:2183 +#: utils/adt/formatting.c:2205 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Este valor se contradice con un seteo previo para el mismo tipo de campo" -#: utils/adt/formatting.c:2244 +#: utils/adt/formatting.c:2266 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "cadena de texto fuente muy corta para campo formateado \"%s\" " -#: utils/adt/formatting.c:2246 +#: utils/adt/formatting.c:2268 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "El campo requiere %d caractéres, pero solo quedan %d." -#: utils/adt/formatting.c:2249 utils/adt/formatting.c:2263 +#: utils/adt/formatting.c:2271 utils/adt/formatting.c:2285 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "Si su cadena de texto no es de ancho modificado, trate de usar el modificador \"FM\" " -#: utils/adt/formatting.c:2259 utils/adt/formatting.c:2272 -#: utils/adt/formatting.c:2402 +#: utils/adt/formatting.c:2281 utils/adt/formatting.c:2294 +#: utils/adt/formatting.c:2424 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "el valor «%s» no es válido para «%s»" -#: utils/adt/formatting.c:2261 +#: utils/adt/formatting.c:2283 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "El campo requiere %d caracteres, pero sólo %d pudieron ser analizados." -#: utils/adt/formatting.c:2274 +#: utils/adt/formatting.c:2296 #, c-format msgid "Value must be an integer." msgstr "El valor debe ser un entero." -#: utils/adt/formatting.c:2279 +#: utils/adt/formatting.c:2301 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "el valor para «%s» en la cadena de origen está fuera de rango" -#: utils/adt/formatting.c:2281 +#: utils/adt/formatting.c:2303 #, c-format msgid "Value must be in the range %d to %d." msgstr "El valor debe estar en el rango de %d a %d." -#: utils/adt/formatting.c:2404 +#: utils/adt/formatting.c:2426 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "El valor dado no concuerda con ninguno de los valores permitidos para este campo." -#: utils/adt/formatting.c:2589 utils/adt/formatting.c:2609 -#: utils/adt/formatting.c:2629 utils/adt/formatting.c:2649 -#: utils/adt/formatting.c:2668 utils/adt/formatting.c:2687 -#: utils/adt/formatting.c:2711 utils/adt/formatting.c:2729 -#: utils/adt/formatting.c:2747 utils/adt/formatting.c:2765 -#: utils/adt/formatting.c:2782 utils/adt/formatting.c:2799 +#: utils/adt/formatting.c:2624 utils/adt/formatting.c:2644 +#: utils/adt/formatting.c:2664 utils/adt/formatting.c:2684 +#: utils/adt/formatting.c:2703 utils/adt/formatting.c:2722 +#: utils/adt/formatting.c:2746 utils/adt/formatting.c:2764 +#: utils/adt/formatting.c:2782 utils/adt/formatting.c:2800 +#: utils/adt/formatting.c:2817 utils/adt/formatting.c:2834 #, c-format msgid "localized string format value too long" msgstr "cadena traducida en cadena de formato es demasiado larga" -#: utils/adt/formatting.c:3086 -#, fuzzy, c-format +#: utils/adt/formatting.c:3176 +#, c-format msgid "formatting field \"%s\" is only supported in to_char" -msgstr "el archivo de slot de replicación «%s» tiene versión no soportada %u" +msgstr "el campo de formato «%s» sólo está soportado en to_char" -#: utils/adt/formatting.c:3197 +#: utils/adt/formatting.c:3317 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "cadena de entrada no válida para «Y,YYY»" -#: utils/adt/formatting.c:3703 +#: utils/adt/formatting.c:3851 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "la hora «%d» no es válida para el reloj de 12 horas" -#: utils/adt/formatting.c:3705 +#: utils/adt/formatting.c:3853 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "Use el reloj de 24 horas, o entregue una hora entre 1 y 12." -#: utils/adt/formatting.c:3811 +#: utils/adt/formatting.c:3959 #, c-format msgid "cannot calculate day of year without year information" msgstr "no se puede calcular el día del año sin conocer el año" -#: utils/adt/formatting.c:4678 +#: utils/adt/formatting.c:4866 #, c-format msgid "\"EEEE\" not supported for input" msgstr "«EEEE» no está soportado en la entrada" -#: utils/adt/formatting.c:4690 +#: utils/adt/formatting.c:4878 #, c-format msgid "\"RN\" not supported for input" msgstr "«RN» no está soportado en la entrada" -#: utils/adt/genfile.c:63 +#: utils/adt/genfile.c:81 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "no se permiten referencias a directorios padre («..»)" -#: utils/adt/genfile.c:74 +#: utils/adt/genfile.c:92 #, c-format msgid "absolute path not allowed" msgstr "no se permiten rutas absolutas" -#: utils/adt/genfile.c:79 +#: utils/adt/genfile.c:97 #, c-format msgid "path must be in or below the current directory" msgstr "la ruta debe estar en o debajo del directorio actual" -#: utils/adt/genfile.c:126 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:144 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "el tamaño solicitado es demasiado grande" -#: utils/adt/genfile.c:143 +#: utils/adt/genfile.c:161 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "no se pudo posicionar (seek) el archivo «%s»: %m" -#: utils/adt/genfile.c:201 utils/adt/genfile.c:242 -#, c-format -msgid "must be superuser to read files" -msgstr "debe ser superusuario para leer archivos" - -#: utils/adt/genfile.c:319 +#: utils/adt/genfile.c:221 #, c-format -msgid "must be superuser to get file information" -msgstr "debe ser superusuario obtener información de archivos" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "Debe ser superusuario leer archivos con adminpack 1.0." -#: utils/adt/genfile.c:405 -#, c-format -msgid "must be superuser to get directory listings" -msgstr "debe ser superusuario para obtener listados de directorio" - -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "especificación de línea no válida: A y B no pueden ser ambos cero" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "especificación de línea no válida: deben ser dos puntos distintos" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 -#: utils/adt/geo_ops.c:5181 +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3370 utils/adt/geo_ops.c:4238 +#: utils/adt/geo_ops.c:5129 #, c-format msgid "too many points requested" msgstr "se pidieron demasiados puntos" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1461 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "el número de puntos no es válido en el valor «path» externo" -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2459 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "la función «dist_lb» no está implementada" -#: utils/adt/geo_ops.c:3015 +#: utils/adt/geo_ops.c:2859 #, c-format msgid "function \"close_sl\" not implemented" msgstr "la función «close_sl» no está implementada" -#: utils/adt/geo_ops.c:3117 +#: utils/adt/geo_ops.c:3006 #, c-format msgid "function \"close_lb\" not implemented" msgstr "la función «close_lb» no está implementada" -#: utils/adt/geo_ops.c:3406 -#, c-format -msgid "cannot create bounding box for empty polygon" -msgstr "no se puede crear una caja de contorno para un polígono vacío" - -#: utils/adt/geo_ops.c:3487 +#: utils/adt/geo_ops.c:3417 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "el número de puntos no es válido en «polygon» externo" -#: utils/adt/geo_ops.c:4012 +#: utils/adt/geo_ops.c:3953 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "la función «poly_distance» no está implementada" -#: utils/adt/geo_ops.c:4365 +#: utils/adt/geo_ops.c:4330 #, c-format msgid "function \"path_center\" not implemented" msgstr "la función «path_center» no está implementada" -#: utils/adt/geo_ops.c:4382 +#: utils/adt/geo_ops.c:4347 #, c-format msgid "open path cannot be converted to polygon" msgstr "no se puede convertir un camino abierto en polygon" -#: utils/adt/geo_ops.c:4631 +#: utils/adt/geo_ops.c:4594 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "el radio no es válido en el valor «circle» externo" -#: utils/adt/geo_ops.c:5167 +#: utils/adt/geo_ops.c:5115 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "no se puede convertir un círculo de radio cero a polygon" -#: utils/adt/geo_ops.c:5172 +#: utils/adt/geo_ops.c:5120 #, c-format msgid "must request at least 2 points" msgstr "debe pedir al menos 2 puntos" -#: utils/adt/geo_ops.c:5216 -#, c-format -msgid "cannot convert empty polygon to circle" -msgstr "no se puede convertir polígono vacío a circle" - -#: utils/adt/int.c:162 +#: utils/adt/int.c:164 #, c-format msgid "int2vector has too many elements" msgstr "int2vector tiene demasiados elementos" -#: utils/adt/int.c:237 +#: utils/adt/int.c:239 #, c-format msgid "invalid int2vector data" msgstr "datos de int2vector no válidos" -#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "el oidvector tiene demasiados elementos" -#: utils/adt/int.c:1347 utils/adt/int8.c:1460 utils/adt/numeric.c:1401 -#: utils/adt/timestamp.c:5178 utils/adt/timestamp.c:5259 +#: utils/adt/int.c:1383 utils/adt/int8.c:1328 utils/adt/numeric.c:1423 +#: utils/adt/timestamp.c:5430 utils/adt/timestamp.c:5511 #, c-format msgid "step size cannot equal zero" msgstr "el tamaño de paso no puede ser cero" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:105 -#, fuzzy, c-format -msgid "invalid input syntax for %s: \"%s\"" -msgstr "la sintaxis de entrada no es válida para tipo %s: «%s»" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:3005 -#: utils/adt/varbit.c:1655 +#: utils/adt/int8.c:529 utils/adt/int8.c:552 utils/adt/int8.c:566 +#: utils/adt/int8.c:580 utils/adt/int8.c:611 utils/adt/int8.c:635 +#: utils/adt/int8.c:690 utils/adt/int8.c:704 utils/adt/int8.c:728 +#: utils/adt/int8.c:741 utils/adt/int8.c:810 utils/adt/int8.c:824 +#: utils/adt/int8.c:838 utils/adt/int8.c:869 utils/adt/int8.c:891 +#: utils/adt/int8.c:905 utils/adt/int8.c:919 utils/adt/int8.c:952 +#: utils/adt/int8.c:966 utils/adt/int8.c:980 utils/adt/int8.c:1011 +#: utils/adt/int8.c:1033 utils/adt/int8.c:1047 utils/adt/int8.c:1061 +#: utils/adt/int8.c:1230 utils/adt/int8.c:1272 utils/adt/numeric.c:3313 +#: utils/adt/varbit.c:1665 #, c-format msgid "bigint out of range" msgstr "bigint está fuera de rango" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1285 #, c-format msgid "OID out of range" msgstr "OID está fuera de rango" -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Los caracteres con valor 0x%02x deben ser escapados" -#: utils/adt/json.c:827 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "«\\u» debe ser seguido por cuatro dígitos hexadecimales." -#: utils/adt/json.c:843 +#: utils/adt/json.c:844 jsonpath_scan.l:560 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Un «high-surrogate» Unicode no puede venir después de un «high-surrogate»." -#: utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:916 -#: utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 jsonpath_scan.l:571 +#: jsonpath_scan.l:581 jsonpath_scan.l:623 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Un «low-surrogate» Unicode debe seguir a un «high-surrogate»." -#: utils/adt/json.c:879 utils/adt/json.c:902 +#: utils/adt/json.c:880 utils/adt/json.c:903 jsonpath_scan.l:518 #, c-format msgid "unsupported Unicode escape sequence" msgstr "secuencia de escape Unicode no soportado" -#: utils/adt/json.c:880 +#: utils/adt/json.c:881 jsonpath_scan.l:519 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 no puede ser convertido a text." -#: utils/adt/json.c:903 +#: utils/adt/json.c:904 jsonpath_scan.l:544 #, c-format msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." msgstr "Los valores de escape Unicode no pueden ser usados para valores de «code point» sobre 007F cuando la codificación de servidor no es UTF8." -#: utils/adt/json.c:948 utils/adt/json.c:966 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "La secuencia de escape «%s» no es válida." -#: utils/adt/json.c:1135 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "La cadena de entrada terminó inesperadamente." -#: utils/adt/json.c:1149 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "Se esperaba el fin de la entrada, se encontró «%s»." -#: utils/adt/json.c:1160 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "Se esperaba un valor JSON, se encontró «%s»." -#: utils/adt/json.c:1168 utils/adt/json.c:1216 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "Se esperaba una cadena, se encontró «%s»." -#: utils/adt/json.c:1176 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "Se esperaba un elemento de array o «]», se encontró «%s»." -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "Se esperaba «,» o «]», se encontró «%s»." -#: utils/adt/json.c:1192 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "Se esperaba una cadena o «}», se encontró «%s»." -#: utils/adt/json.c:1200 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "Se esperaba «:», se encontró «%s»." -#: utils/adt/json.c:1208 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "Se esperaba «,» o «}», se encontró «%s»." -#: utils/adt/json.c:1246 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "El elemento «%s» no es válido." -#: utils/adt/json.c:1318 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "Datos JSON, línea %d: %s%s%s" -#: utils/adt/json.c:1474 utils/adt/jsonb.c:725 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:739 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "el valor de llave debe ser escalar, no array, composite o json" -#: utils/adt/json.c:2011 utils/adt/json.c:2021 utils/adt/json.c:2147 -#: utils/adt/json.c:2168 utils/adt/json.c:2227 utils/adt/jsonb.c:1215 -#: utils/adt/jsonb.c:1238 utils/adt/jsonb.c:1298 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1549 #, c-format msgid "could not determine data type for argument %d" msgstr "no se pudo determinar el tipo de dato para el argumento %d" -#: utils/adt/json.c:2045 utils/adt/jsonb.c:1782 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1707 #, c-format msgid "field name must not be null" msgstr "el nombre de campo no debe ser null" -#: utils/adt/json.c:2122 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1157 #, c-format msgid "argument list must have even number of elements" msgstr "la lista de argumentos debe tener un número par de elementos" -#: utils/adt/json.c:2123 +#. translator: %s is a SQL function name +#: utils/adt/json.c:2196 utils/adt/jsonb.c:1159 #, c-format -msgid "The arguments of json_build_object() must consist of alternating keys and values." -msgstr "Los argumentos de json_build_object() deben consistir de llaves y valores alternados." +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "El argumento de %s debe consistir de llaves y valores alternados." -#: utils/adt/json.c:2153 +#: utils/adt/json.c:2212 #, c-format msgid "argument %d cannot be null" msgstr "el argumento %d no puede ser null" -#: utils/adt/json.c:2154 +#: utils/adt/json.c:2213 #, c-format msgid "Object keys should be text." msgstr "Las llaves de un objeto deben ser de texto." -#: utils/adt/json.c:2289 utils/adt/jsonb.c:1364 +#: utils/adt/json.c:2319 utils/adt/jsonb.c:1289 #, c-format msgid "array must have two columns" msgstr "un array debe tener dos columnas" -#: utils/adt/json.c:2313 utils/adt/json.c:2397 utils/adt/jsonb.c:1388 -#: utils/adt/jsonb.c:1483 +#: utils/adt/json.c:2343 utils/adt/json.c:2427 utils/adt/jsonb.c:1313 +#: utils/adt/jsonb.c:1408 #, c-format msgid "null value not allowed for object key" msgstr "no se permite el valor nulo como llave en un objeto" -#: utils/adt/json.c:2386 utils/adt/jsonb.c:1472 +#: utils/adt/json.c:2416 utils/adt/jsonb.c:1397 #, c-format msgid "mismatched array dimensions" msgstr "las dimensiones de array no coinciden" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:269 #, c-format msgid "string too long to represent as jsonb string" msgstr "la cadena es demasiado larga para representarla como cadena jsonb." -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:270 #, c-format msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "Debido a una restricción de la implementación, las cadenas en jsonb no pueden exceder los %d bytes." -#: utils/adt/jsonb.c:1183 -#, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "número no válido de argumentos: los objetos deben formar pares llave/valor" - -#: utils/adt/jsonb.c:1196 +#: utils/adt/jsonb.c:1172 #, c-format msgid "argument %d: key must not be null" msgstr "argumento %d: la llave no puede ser null" -#: utils/adt/jsonb.c:1835 +#: utils/adt/jsonb.c:1760 #, c-format msgid "object keys must be strings" msgstr "las llaves de un objeto deben ser cadenas" +#: utils/adt/jsonb.c:1923 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "no se puede convertir un null jsonb a tipo %s" + +#: utils/adt/jsonb.c:1924 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "no se puede convertir un string jsonb a tipo %s" + +#: utils/adt/jsonb.c:1925 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "no se puede convertir un numérico jsonb a tipo %s" + +#: utils/adt/jsonb.c:1926 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "no se puede convertir un booleano jsonb a tipo %s" + +#: utils/adt/jsonb.c:1927 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "no se puede convertir un array jsonb a tipo %s" + +#: utils/adt/jsonb.c:1928 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "no se puede convertir un objeto jsonb a tipo %s" + +#: utils/adt/jsonb.c:1929 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "no se puede convertir un array u objeto jsonb a tipo %s" + #: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" @@ -20846,193 +21473,333 @@ msgstr "el número de pares en objeto jsonb excede el máximo permitido (%zu)" msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "el número de elementos del array jsonb excede el máximo permitido (%zu)" -#: utils/adt/jsonb_util.c:1526 utils/adt/jsonb_util.c:1546 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "el tamaño total de los elementos del array jsonb excede el máximo de %u bytes" -#: utils/adt/jsonb_util.c:1607 utils/adt/jsonb_util.c:1642 -#: utils/adt/jsonb_util.c:1662 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "el tamaño total de los elementos del objeto jsonb excede el máximo de %u bytes" -#: utils/adt/jsonfuncs.c:511 utils/adt/jsonfuncs.c:676 -#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:2699 -#: utils/adt/jsonfuncs.c:3393 utils/adt/jsonfuncs.c:3677 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 #, c-format msgid "cannot call %s on a scalar" msgstr "no se puede invocar %s en un escalar" -#: utils/adt/jsonfuncs.c:516 utils/adt/jsonfuncs.c:663 -#: utils/adt/jsonfuncs.c:2701 utils/adt/jsonfuncs.c:3382 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "no se puede invocar %s en un array" -#: utils/adt/jsonfuncs.c:1579 utils/adt/jsonfuncs.c:1614 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "no se puede obtener el largo de array de un escalar" -#: utils/adt/jsonfuncs.c:1583 utils/adt/jsonfuncs.c:1602 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "no se puede obtener el largo de array de un no-array" -#: utils/adt/jsonfuncs.c:1679 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "no se puede invocar %s en un no-objeto" -#: utils/adt/jsonfuncs.c:1697 utils/adt/jsonfuncs.c:3208 -#: utils/adt/jsonfuncs.c:3502 -#, c-format -msgid "function returning record called in context that cannot accept type record" -msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" - -#: utils/adt/jsonfuncs.c:1936 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "no se puede desconstruir un array como un objeto" -#: utils/adt/jsonfuncs.c:1948 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "no se puede desconstruir un escalar" -#: utils/adt/jsonfuncs.c:1994 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "no se pueden extraer elementos de un escalar" -#: utils/adt/jsonfuncs.c:1998 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "no se pudo extraer elementos de un objeto" -#: utils/adt/jsonfuncs.c:2250 utils/adt/jsonfuncs.c:3566 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format msgid "cannot call %s on a non-array" msgstr "no se puede invocar %s en un no-array" -#: utils/adt/jsonfuncs.c:2316 utils/adt/jsonfuncs.c:2321 -#: utils/adt/jsonfuncs.c:2338 utils/adt/jsonfuncs.c:2344 -#, fuzzy, c-format -msgid "expected json array" -msgstr "Elemento de array inesperado." +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, c-format +msgid "expected JSON array" +msgstr "se esperaba un array JSON" -#: utils/adt/jsonfuncs.c:2317 -#, fuzzy, c-format -msgid "see the value of key \"%s\"" -msgstr "el valor de hora/fecha está fuera de rango: «%s»" +#: utils/adt/jsonfuncs.c:2334 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Vea el valor de la llave «%s»." -#: utils/adt/jsonfuncs.c:2339 -#, fuzzy, c-format -msgid "see the array element %s of key \"%s\"" -msgstr "el tipo de elemento de array no puede ser %s" +#: utils/adt/jsonfuncs.c:2356 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Vea el elemento %s de la llave «%s»." -#: utils/adt/jsonfuncs.c:2345 -#, fuzzy, c-format -msgid "see the array element %s" -msgstr "Elemento de array inesperado." +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "Veo el elemento de array %s." -#: utils/adt/jsonfuncs.c:2380 -#, fuzzy, c-format -msgid "malformed json array" -msgstr "literal de array no es válido: «%s»" +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "array JSON mal formado" -#: utils/adt/jsonfuncs.c:3168 utils/adt/jsonfuncs.c:3478 +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "el primer argumento de %s debe ser un tipo de registro" -#: utils/adt/jsonfuncs.c:3210 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format msgid "Try calling the function in the FROM clause using a column definition list." msgstr "Intente invocar la función desde la cláusula FROM usando una lista de definición de columnas" -#: utils/adt/jsonfuncs.c:3583 utils/adt/jsonfuncs.c:3659 +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 #, c-format msgid "argument of %s must be an array of objects" msgstr "el argumento de %s debe ser un array de objetos" -#: utils/adt/jsonfuncs.c:3611 +#: utils/adt/jsonfuncs.c:3764 #, c-format msgid "cannot call %s on an object" msgstr "no se puede invocar %s en un objeto" -#: utils/adt/jsonfuncs.c:4087 utils/adt/jsonfuncs.c:4146 -#: utils/adt/jsonfuncs.c:4226 +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 #, c-format msgid "cannot delete from scalar" msgstr "no se puede eliminar de un escalar" -#: utils/adt/jsonfuncs.c:4231 +#: utils/adt/jsonfuncs.c:4385 #, c-format msgid "cannot delete from object using integer index" msgstr "no se puede eliminar de un objeto usando un índice numérico" -#: utils/adt/jsonfuncs.c:4297 utils/adt/jsonfuncs.c:4389 +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 #, c-format msgid "cannot set path in scalar" msgstr "no se puede definir una ruta en un escalar" -#: utils/adt/jsonfuncs.c:4342 +#: utils/adt/jsonfuncs.c:4496 #, c-format msgid "cannot delete path in scalar" msgstr "no se puede eliminar una ruta en un escalar" -#: utils/adt/jsonfuncs.c:4512 +#: utils/adt/jsonfuncs.c:4666 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "concatenación no válida de objetos jsonb" -#: utils/adt/jsonfuncs.c:4546 +#: utils/adt/jsonfuncs.c:4700 #, c-format msgid "path element at position %d is null" msgstr "el elemento en la posición %d de la ruta es null" -#: utils/adt/jsonfuncs.c:4632 +#: utils/adt/jsonfuncs.c:4786 #, c-format msgid "cannot replace existing key" msgstr "no se puede reemplazar una llave existente" -#: utils/adt/jsonfuncs.c:4633 +#: utils/adt/jsonfuncs.c:4787 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "Intente usar la función jsonb_set para reemplazar el valor de la llave." -#: utils/adt/jsonfuncs.c:4715 +#: utils/adt/jsonfuncs.c:4869 #, c-format msgid "path element at position %d is not an integer: \"%s\"" msgstr "el elemento de ruta en la posición %d no es un entero: «%s»" +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "indicador de tipo errónea, sólo se permiten arrays y tipos escalares" + +#: utils/adt/jsonfuncs.c:4995 +#, c-format +msgid "flag array element is not a string" +msgstr "elemento del array de opciones no es un string" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Los valores posibles son: «string», «numeric», «boolean», «key» y «all»." + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "indicador erróneo en array de indicadores: «%s»" + +#: utils/adt/jsonpath.c:360 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ no es permitido en expresiones raíz" + +#: utils/adt/jsonpath.c:366 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST sólo está permitido en subíndices de array" + +#: utils/adt/jsonpath_exec.c:342 +#, c-format +msgid "single boolean result is expected" +msgstr "se esperaba un único resultado booleano" + +#: utils/adt/jsonpath_exec.c:490 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "el argumento «vars» no es un objeto" + +#: utils/adt/jsonpath_exec.c:491 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Los parámetros jsonpath deben codificarse como pares llave-valor del objeto «vars»." + +#: utils/adt/jsonpath_exec.c:607 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "el objeto JSON no contiene la llave «%s»" + +#: utils/adt/jsonpath_exec.c:619 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "el método de acceso a un miembro jsonpath sólo puede aplicarse a un objeto" + +#: utils/adt/jsonpath_exec.c:648 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "el método de acceso comodín de array jsonpath sólo puede aplicarse a un array" + +#: utils/adt/jsonpath_exec.c:696 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "subíndice de array jsonpath fuera de los bordes" + +#: utils/adt/jsonpath_exec.c:753 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "el método de acceso de array jsonpath sólo puede aplicarse a un array" + +#: utils/adt/jsonpath_exec.c:807 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "el método de acesso comodín de objeto jsonpath sólo puede aplicarse a un objeto" + +#: utils/adt/jsonpath_exec.c:937 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicase a un array" + +#: utils/adt/jsonpath_exec.c:991 utils/adt/jsonpath_exec.c:1012 +#: utils/adt/jsonpath_exec.c:1695 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicarse a un valor numérico" + +#: utils/adt/jsonpath_exec.c:1025 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "el método de ítem jsonpath .%s() sólo puede aplicarse a un valor numérico o de cadena" + +#: utils/adt/jsonpath_exec.c:1509 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "el operando izquiero del operador jsonpath %s no es un valor numérico escalar" + +#: utils/adt/jsonpath_exec.c:1516 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "el operando derecho del operador jsonpath %s no es un valor numérico escalar" + +#: utils/adt/jsonpath_exec.c:1584 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "el operando del operador jsonpath unario %s no es un valor numérico" + +#: utils/adt/jsonpath_exec.c:1754 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "el método de ítem jsonpath .%s() sólo puede ser aplicado a un objeto" + +#: utils/adt/jsonpath_exec.c:1937 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "no se pudo encontrar la variable jsonpath «%s»" + +#: utils/adt/jsonpath_exec.c:2097 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "el subíndice de array jsonpath no es un único valor numérico" + +#: utils/adt/jsonpath_exec.c:2109 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "subíndice de array jsonpath fuera del rango entero" + #: utils/adt/levenshtein.c:133 #, c-format msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "el argumento levenshtein excede el largo máximo de %d caracteres" -#: utils/adt/like.c:183 utils/adt/selfuncs.c:5562 +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "los ordenamientos no determinísticos no están soportados para LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:964 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "no se pudo determinar qué ordenamiento (collation) usar para ILIKE" +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "los ordenamientos no determinísticos no están soportados para ILIKE" + #: utils/adt/like_match.c:107 utils/adt/like_match.c:167 #, c-format msgid "LIKE pattern must not end with escape character" msgstr "el patrón de LIKE debe no terminar con un carácter de escape" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "cadena de escape no válida" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "La cadena de escape debe ser vacía o un carácter." +#: utils/adt/like_support.c:949 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "no está soportada la comparación insensible a mayúsculas en bytea" + +#: utils/adt/like_support.c:1051 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "no está soportada la comparación con expresiones regulares en bytea" + #: utils/adt/lockfuncs.c:664 #, c-format msgid "cannot use advisory locks during a parallel operation" @@ -21043,285 +21810,235 @@ msgstr "no se pueden usar locks consultivos durante una operación paralela" msgid "invalid octet value in \"macaddr\" value: \"%s\"" msgstr "valor de octeto no válido en valor «macaddr»: «%s»" -#: utils/adt/mac8.c:554 +#: utils/adt/mac8.c:563 #, c-format msgid "macaddr8 data out of range to convert to macaddr" -msgstr "" - -#: utils/adt/mac8.c:555 -#, c-format -msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes, from the left, for example: XX-XX-XX-FF-FE-XX-XX-XX, are eligible to be converted from macaddr8 to macaddr." -msgstr "" - -#: utils/adt/misc.c:238 -#, c-format -msgid "PID %d is not a PostgreSQL server process" -msgstr "PID %d no es un proceso servidor de PostgreSQL" - -#: utils/adt/misc.c:289 -#, c-format -msgid "must be a superuser to cancel superuser query" -msgstr "debe ser superusuario para cancelar una consulta de superusuario" - -#: utils/adt/misc.c:294 -#, c-format -msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" -msgstr "debe ser miembro del rol cuya consulta se está cancelando o ser miembro de pg_signal_backend" - -#: utils/adt/misc.c:313 -#, c-format -msgid "must be a superuser to terminate superuser process" -msgstr "debe ser superusuario para terminar proceso de superusuario" - -#: utils/adt/misc.c:318 -#, c-format -msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" -msgstr "debe ser miembro del rol cuyo proceso se está terminando o ser miembro de pg_signal_backend" - -#: utils/adt/misc.c:335 -#, c-format -msgid "failed to send signal to postmaster: %m" -msgstr "no se pudo enviar señal a postmaster: %m" +msgstr "datos macaddr8 fuera de rango para convertir a macaddr" -#: utils/adt/misc.c:355 +#: utils/adt/mac8.c:564 #, c-format -msgid "rotation not possible because log collection not active" -msgstr "la rotación no es posible porque la recoleccion de log no está activa" +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Sólo las direcciones que tienen FF y FF como valores en el cuarto y quinto bytes desde la izquierda, por ejemplo xx:xx:xx:ff:fe:xx:xx:xx se pueden convertir de macaddr8 a macaddr." -#: utils/adt/misc.c:392 +#: utils/adt/misc.c:225 #, c-format msgid "global tablespace never has databases" msgstr "el tablespace global nunca tiene bases de datos" -#: utils/adt/misc.c:413 +#: utils/adt/misc.c:246 #, c-format msgid "%u is not a tablespace OID" msgstr "%u no es un OID de tablespace" -#: utils/adt/misc.c:606 +#: utils/adt/misc.c:435 msgid "unreserved" msgstr "no reservado" -#: utils/adt/misc.c:610 +#: utils/adt/misc.c:439 msgid "unreserved (cannot be function or type name)" msgstr "no reservado (no puede ser nombre de función o de tipo)" -#: utils/adt/misc.c:614 +#: utils/adt/misc.c:443 msgid "reserved (can be function or type name)" msgstr "reservado (puede ser nombre de función o de tipo)" -#: utils/adt/misc.c:618 +#: utils/adt/misc.c:447 msgid "reserved" msgstr "reservado" -#: utils/adt/misc.c:792 utils/adt/misc.c:806 utils/adt/misc.c:845 -#: utils/adt/misc.c:851 utils/adt/misc.c:857 utils/adt/misc.c:880 +#: utils/adt/misc.c:621 utils/adt/misc.c:635 utils/adt/misc.c:674 +#: utils/adt/misc.c:680 utils/adt/misc.c:686 utils/adt/misc.c:709 #, c-format msgid "string is not a valid identifier: \"%s\"" msgstr "la cadena no es un identificador válido: «%s»" -#: utils/adt/misc.c:794 +#: utils/adt/misc.c:623 #, c-format msgid "String has unclosed double quotes." msgstr "La cadena tiene comillas dobles sin cerrar." -#: utils/adt/misc.c:808 +#: utils/adt/misc.c:637 #, c-format msgid "Quoted identifier must not be empty." msgstr "El identificador en comillas no debe ser vacío." -#: utils/adt/misc.c:847 +#: utils/adt/misc.c:676 #, c-format msgid "No valid identifier before \".\"." msgstr "No hay un identificador válido antes de «.»." -#: utils/adt/misc.c:853 +#: utils/adt/misc.c:682 #, c-format msgid "No valid identifier after \".\"." msgstr "No hay un identificador válido después de «.»." -#: utils/adt/misc.c:914 -#, fuzzy, c-format +#: utils/adt/misc.c:743 +#, c-format msgid "log format \"%s\" is not supported" -msgstr "las unidades de interval «%s» no están soportadas" +msgstr "el formato de log «%s» no está soportado" -#: utils/adt/misc.c:915 +#: utils/adt/misc.c:744 #, c-format msgid "The supported log formats are \"stderr\" and \"csvlog\"." -msgstr "" - -#: utils/adt/nabstime.c:137 -#, c-format -msgid "invalid time zone name: \"%s\"" -msgstr "nombre de huso horario no válido: «%s»" - -#: utils/adt/nabstime.c:482 utils/adt/nabstime.c:555 -#, c-format -msgid "cannot convert abstime \"invalid\" to timestamp" -msgstr "no se puede convertir el valor reservado de abstime «invalid» a timestamp" +msgstr "Los formatos de registro admitidos son \"stderr\" y \"csvlog\"." -#: utils/adt/nabstime.c:782 -#, c-format -msgid "invalid status in external \"tinterval\" value" -msgstr "estatus no válido en valor «tinterval» externo" - -#: utils/adt/nabstime.c:852 -#, c-format -msgid "cannot convert reltime \"invalid\" to interval" -msgstr "no se puede convertir el reltime «invalid» a interval" - -#: utils/adt/network.c:69 +#: utils/adt/network.c:85 #, c-format msgid "invalid cidr value: \"%s\"" msgstr "valor cidr no válido: «%s»" -#: utils/adt/network.c:70 utils/adt/network.c:200 +#: utils/adt/network.c:86 utils/adt/network.c:216 #, c-format msgid "Value has bits set to right of mask." msgstr "El valor tiene bits definidos a la derecha de la máscara" -#: utils/adt/network.c:111 utils/adt/network.c:582 utils/adt/network.c:607 -#: utils/adt/network.c:632 +#: utils/adt/network.c:127 utils/adt/network.c:800 utils/adt/network.c:825 +#: utils/adt/network.c:850 #, c-format msgid "could not format inet value: %m" msgstr "no se pudo dar formato al valor inet: %m" #. translator: %s is inet or cidr -#: utils/adt/network.c:168 +#: utils/adt/network.c:184 #, c-format msgid "invalid address family in external \"%s\" value" msgstr "familia de dirección no válida en valor «%s» externo" #. translator: %s is inet or cidr -#: utils/adt/network.c:175 +#: utils/adt/network.c:191 #, c-format msgid "invalid bits in external \"%s\" value" msgstr "bits no válidos en valor «%s» externo" #. translator: %s is inet or cidr -#: utils/adt/network.c:184 +#: utils/adt/network.c:200 #, c-format msgid "invalid length in external \"%s\" value" msgstr "largo no válido en valor «%s» externo" -#: utils/adt/network.c:199 +#: utils/adt/network.c:215 #, c-format msgid "invalid external \"cidr\" value" msgstr "valor externo «cidr» no válido" -#: utils/adt/network.c:295 utils/adt/network.c:318 +#: utils/adt/network.c:311 utils/adt/network.c:334 #, c-format msgid "invalid mask length: %d" msgstr "largo de máscara no válido: %d" -#: utils/adt/network.c:650 +#: utils/adt/network.c:868 #, c-format msgid "could not format cidr value: %m" msgstr "no se pudo dar formato al valor cidr: %m" -#: utils/adt/network.c:883 +#: utils/adt/network.c:1101 #, c-format msgid "cannot merge addresses from different families" msgstr "no se pueden mezclar direcciones de familias diferentes" -#: utils/adt/network.c:1302 +#: utils/adt/network.c:1517 #, c-format msgid "cannot AND inet values of different sizes" msgstr "no se puede hacer AND entre valores inet de distintos tamaños" -#: utils/adt/network.c:1334 +#: utils/adt/network.c:1549 #, c-format msgid "cannot OR inet values of different sizes" msgstr "no se puede hacer OR entre valores inet de distintos tamaños" -#: utils/adt/network.c:1395 utils/adt/network.c:1471 +#: utils/adt/network.c:1610 utils/adt/network.c:1686 #, c-format msgid "result is out of range" msgstr "resultado fuera de rango" -#: utils/adt/network.c:1436 +#: utils/adt/network.c:1651 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "no se puede sustraer valores inet de distintos tamaños" -#: utils/adt/numeric.c:819 +#: utils/adt/numeric.c:833 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "el signo no es válido en el valor «numeric» externo" -#: utils/adt/numeric.c:825 +#: utils/adt/numeric.c:839 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "la escala no es válida en el valor «numeric» externo" -#: utils/adt/numeric.c:834 +#: utils/adt/numeric.c:848 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "hay un dígito no válido en el valor «numeric» externo" -#: utils/adt/numeric.c:1024 utils/adt/numeric.c:1038 +#: utils/adt/numeric.c:1046 utils/adt/numeric.c:1060 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "la precisión %d de NUMERIC debe estar entre 1 y %d" -#: utils/adt/numeric.c:1029 +#: utils/adt/numeric.c:1051 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "la escala de NUMERIC, %d, debe estar entre 0 y la precisión %d" -#: utils/adt/numeric.c:1047 +#: utils/adt/numeric.c:1069 #, c-format msgid "invalid NUMERIC type modifier" msgstr "modificador de tipo NUMERIC no es válido" -#: utils/adt/numeric.c:1379 +#: utils/adt/numeric.c:1401 #, c-format msgid "start value cannot be NaN" msgstr "el valor de inicio no puede ser NaN" -#: utils/adt/numeric.c:1384 +#: utils/adt/numeric.c:1406 #, c-format msgid "stop value cannot be NaN" msgstr "el valor de término no puede ser NaN" -#: utils/adt/numeric.c:1394 +#: utils/adt/numeric.c:1416 #, c-format msgid "step size cannot be NaN" msgstr "el tamaño de paso no puede ser NaN" -#: utils/adt/numeric.c:2589 utils/adt/numeric.c:5551 utils/adt/numeric.c:5996 -#: utils/adt/numeric.c:7700 utils/adt/numeric.c:8125 utils/adt/numeric.c:8239 -#: utils/adt/numeric.c:8312 +#: utils/adt/numeric.c:2857 utils/adt/numeric.c:5869 utils/adt/numeric.c:6324 +#: utils/adt/numeric.c:8046 utils/adt/numeric.c:8471 utils/adt/numeric.c:8585 +#: utils/adt/numeric.c:8658 #, c-format msgid "value overflows numeric format" msgstr "el valor excede el formato numeric" -#: utils/adt/numeric.c:2931 +#: utils/adt/numeric.c:3222 #, c-format msgid "cannot convert NaN to integer" msgstr "no se puede convertir NaN a entero" -#: utils/adt/numeric.c:2997 +#: utils/adt/numeric.c:3305 #, c-format msgid "cannot convert NaN to bigint" msgstr "no se puede convertir NaN a bigint" -#: utils/adt/numeric.c:3042 +#: utils/adt/numeric.c:3350 #, c-format msgid "cannot convert NaN to smallint" msgstr "no se puede convertir NaN a smallint" -#: utils/adt/numeric.c:6066 +#: utils/adt/numeric.c:3387 utils/adt/numeric.c:3458 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "no se puede convertir infinito a numeric" + +#: utils/adt/numeric.c:6408 #, c-format msgid "numeric field overflow" msgstr "desbordamiento de campo numeric" -#: utils/adt/numeric.c:6067 +#: utils/adt/numeric.c:6409 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "Un campo con precisión %d, escala %d debe redondear a un valor absoluto menor que %s%d." -#: utils/adt/numutils.c:89 +#: utils/adt/numutils.c:90 #, c-format msgid "value \"%s\" is out of range for 8-bit integer" msgstr "el valor «%s» está fuera de rango para un entero de 8 bits" @@ -21331,129 +22048,125 @@ msgstr "el valor «%s» está fuera de rango para un entero de 8 bits" msgid "invalid oidvector data" msgstr "datos de oidvector no válidos" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "el carácter solicitado es demasiado grande" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "el carácter pedido es demasiado largo para el encoding: %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "el carácter pedido no es válido para el encoding: %d" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "el carácter nulo no está permitido" -#: utils/adt/orderedsetaggs.c:426 utils/adt/orderedsetaggs.c:531 -#: utils/adt/orderedsetaggs.c:670 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "el valor de percentil %g no está entre 0 y 1" -#: utils/adt/pg_locale.c:1034 +#: utils/adt/pg_locale.c:1097 #, c-format msgid "Apply system library package updates." msgstr "Aplique actualizaciones de paquetes de bibliotecas del sistema." -#: utils/adt/pg_locale.c:1239 +#: utils/adt/pg_locale.c:1312 #, c-format msgid "could not create locale \"%s\": %m" msgstr "no se pudo crear la configuración regional «%s»: %m" -#: utils/adt/pg_locale.c:1242 +#: utils/adt/pg_locale.c:1315 #, c-format msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "El sistema operativo no pudo encontrar datos de configuración regional para la configuración «%s»." -#: utils/adt/pg_locale.c:1339 +#: utils/adt/pg_locale.c:1417 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "los ordenamientos (collation) con valores collate y ctype diferentes no están soportados en esta plataforma" -#: utils/adt/pg_locale.c:1348 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1426 +#, c-format msgid "collation provider LIBC is not supported on this platform" -msgstr "LDAP sobre SSL no está soportado en esta plataforma." +msgstr "el proveedor de ordenamientos LIBC no está soportado en esta plataforma" -#: utils/adt/pg_locale.c:1360 -#, fuzzy, c-format -#| msgid "collations with different collate and ctype values are not supported on this platform" +#: utils/adt/pg_locale.c:1438 +#, c-format msgid "collations with different collate and ctype values are not supported by ICU" -msgstr "los ordenamientos (collation) con valores collate y ctype diferentes no están soportados en esta plataforma" +msgstr "los ordenamientos (collation) con valores collate y ctype diferentes no están soportados por ICU" -#: utils/adt/pg_locale.c:1366 utils/adt/pg_locale.c:1448 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1444 utils/adt/pg_locale.c:1535 +#: utils/adt/pg_locale.c:1753 +#, c-format msgid "could not open collator for locale \"%s\": %s" -msgstr "no se pudo abrir el archivo de control «%s»: %m" +msgstr "no se pudo abrir el «collator» para la configuración regional «%s»: %s" -#: utils/adt/pg_locale.c:1375 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1458 +#, c-format msgid "ICU is not supported in this build" -msgstr "SSL no está soportado en este servidor" +msgstr "ICU no está soportado en este servidor" -#: utils/adt/pg_locale.c:1376 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1459 +#, c-format msgid "You need to rebuild PostgreSQL using --with-icu." -msgstr "Necesita reconstruir PostgreSQL usando --with-libxml." +msgstr "Necesita reconstruir PostgreSQL usando --with-icu." -#: utils/adt/pg_locale.c:1396 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1479 +#, c-format msgid "collation \"%s\" has no actual version, but a version was specified" -msgstr "la extensión «%s» no tiene ruta de actualización desde la versión «%s» hasta la versión «%s»" +msgstr "la extensión «%s» no tiene versión actual, pero se especificó una versión" -#: utils/adt/pg_locale.c:1403 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1486 +#, c-format msgid "collation \"%s\" has version mismatch" -msgstr "biblioteca «%s» incompatible: versión no coincide" +msgstr "el ordenamiento (collation) «%s» tiene una discordancia de versión" -#: utils/adt/pg_locale.c:1405 +#: utils/adt/pg_locale.c:1488 #, c-format msgid "The collation in the database was created using version %s, but the operating system provides version %s." -msgstr "" +msgstr "El ordenamiento en la base de datos fue creado usando la versión %s, pero el sistema operativo provee la versión %s." -#: utils/adt/pg_locale.c:1408 +#: utils/adt/pg_locale.c:1491 #, c-format msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." -msgstr "" +msgstr "Reconstruya todos los objetos afectados por este ordenamiento y ejecute ALTER COLLATION %s REFRESH VERSION, o construya PostgreSQL con la versión correcta de la biblioteca." -#: utils/adt/pg_locale.c:1488 -#, fuzzy, c-format +#: utils/adt/pg_locale.c:1575 +#, c-format msgid "could not open ICU converter for encoding \"%s\": %s" -msgstr "no se pudo abrir el archivo de control «%s»: %m" +msgstr "no se pudo abrir el conversor ICU para la codificación «%s»: %s" -#: utils/adt/pg_locale.c:1519 utils/adt/pg_locale.c:1528 -#, fuzzy, c-format -msgid "ucnv_toUChars failed: %s" -msgstr "pclose falló: %s" - -#: utils/adt/pg_locale.c:1557 utils/adt/pg_locale.c:1566 -#, fuzzy, c-format -msgid "ucnv_fromUChars failed: %s" -msgstr "pclose falló: %s" +#: utils/adt/pg_locale.c:1606 utils/adt/pg_locale.c:1615 +#: utils/adt/pg_locale.c:1644 utils/adt/pg_locale.c:1654 +#, c-format +msgid "%s failed: %s" +msgstr "%s falló: %s" -#: utils/adt/pg_locale.c:1739 +#: utils/adt/pg_locale.c:1926 #, c-format msgid "invalid multibyte character for locale" msgstr "el carácter multibyte no es válido para esta configuración regional" -#: utils/adt/pg_locale.c:1740 +#: utils/adt/pg_locale.c:1927 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "La configuración regional LC_CTYPE del servidor es probablemente incompatible con la codificación de la base de datos." -#: utils/adt/pg_upgrade_support.c:28 +#: utils/adt/pg_upgrade_support.c:29 #, c-format msgid "function can only be called when server is in binary upgrade mode" msgstr "la función sólo puede invocarse cuando el servidor está en modo de actualización binaria" -#: utils/adt/pgstatfuncs.c:473 +#: utils/adt/pgstatfuncs.c:479 #, c-format msgid "invalid command name: \"%s\"" msgstr "nombre de orden no válido: «%s»" @@ -21474,104 +22187,105 @@ msgid "cannot output a value of type %s" msgstr "no se puede desplegar un valor de tipo %s" #: utils/adt/pseudotypes.c:403 -#, fuzzy, c-format +#, c-format msgid "cannot display a value of type %s" -msgstr "no se puede desplegar un valor de tipo any" +msgstr "no se puede desplegar un valor de tipo %s" -#: utils/adt/rangetypes.c:405 +#: utils/adt/rangetypes.c:406 #, c-format msgid "range constructor flags argument must not be null" msgstr "el argumento de opciones del constructor de rango no debe ser null" -#: utils/adt/rangetypes.c:992 +#: utils/adt/rangetypes.c:993 #, c-format msgid "result of range difference would not be contiguous" msgstr "el resultado de la diferencia de rangos no sería contiguo" -#: utils/adt/rangetypes.c:1053 +#: utils/adt/rangetypes.c:1054 #, c-format msgid "result of range union would not be contiguous" msgstr "el resultado de la unión de rangos no sería contiguo" -#: utils/adt/rangetypes.c:1533 +#: utils/adt/rangetypes.c:1598 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "el límite inferior del rango debe ser menor o igual al límite superior del rango" -#: utils/adt/rangetypes.c:1916 utils/adt/rangetypes.c:1929 -#: utils/adt/rangetypes.c:1943 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "invalid range bound flags" msgstr "opciones de bordes de rango no válidas" -#: utils/adt/rangetypes.c:1917 utils/adt/rangetypes.c:1930 -#: utils/adt/rangetypes.c:1944 +#: utils/adt/rangetypes.c:1982 utils/adt/rangetypes.c:1995 +#: utils/adt/rangetypes.c:2009 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "Los valores aceptables son «[]», «[)», «(]» y «()»." -#: utils/adt/rangetypes.c:2009 utils/adt/rangetypes.c:2026 -#: utils/adt/rangetypes.c:2039 utils/adt/rangetypes.c:2057 -#: utils/adt/rangetypes.c:2068 utils/adt/rangetypes.c:2112 -#: utils/adt/rangetypes.c:2120 +#: utils/adt/rangetypes.c:2074 utils/adt/rangetypes.c:2091 +#: utils/adt/rangetypes.c:2104 utils/adt/rangetypes.c:2122 +#: utils/adt/rangetypes.c:2133 utils/adt/rangetypes.c:2177 +#: utils/adt/rangetypes.c:2185 #, c-format msgid "malformed range literal: \"%s\"" msgstr "literal de rango mal formado: «%s»" -#: utils/adt/rangetypes.c:2011 +#: utils/adt/rangetypes.c:2076 #, c-format msgid "Junk after \"empty\" key word." msgstr "Basura a continuación de la palabra «empty»." -#: utils/adt/rangetypes.c:2028 +#: utils/adt/rangetypes.c:2093 #, c-format msgid "Missing left parenthesis or bracket." msgstr "Falta paréntesis o corchete izquierdo." -#: utils/adt/rangetypes.c:2041 +#: utils/adt/rangetypes.c:2106 #, c-format msgid "Missing comma after lower bound." msgstr "Coma faltante después del límite inferior." -#: utils/adt/rangetypes.c:2059 +#: utils/adt/rangetypes.c:2124 #, c-format msgid "Too many commas." msgstr "Demasiadas comas." -#: utils/adt/rangetypes.c:2070 +#: utils/adt/rangetypes.c:2135 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "Basura después del paréntesis o corchete derecho." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1344 utils/adt/varlena.c:3963 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1490 utils/adt/varlena.c:4476 #, c-format msgid "regular expression failed: %s" msgstr "la expresión regular falló: %s" -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 #, c-format -msgid "invalid regexp option: \"%c\"" -msgstr "la opción de expresión regular no es válida: «%c»" +msgid "invalid regular expression option: \"%c\"" +msgstr "opción de expresión regular no válida: «%c»" -#: utils/adt/regexp.c:862 -#, fuzzy, c-format -msgid "regexp_match does not support the global option" -msgstr "regex_split no soporta la opción «global»" +#: utils/adt/regexp.c:838 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "la expresión regular SQL no puede contener más de dos separadores escape-comilla doble" -#: utils/adt/regexp.c:863 +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:924 utils/adt/regexp.c:1307 utils/adt/regexp.c:1362 #, c-format -msgid "Use the regexp_matches function instead." -msgstr "" +msgid "%s does not support the \"global\" option" +msgstr "%s no soporta la opción «global»" -#: utils/adt/regexp.c:1163 -#, fuzzy, c-format -msgid "regexp_split_to_table does not support the global option" -msgstr "regex_split no soporta la opción «global»" +#: utils/adt/regexp.c:926 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "En su lugar, utilice la función regexp_matches." -#: utils/adt/regexp.c:1219 -#, fuzzy, c-format -msgid "regexp_split_to_array does not support the global option" -msgstr "regex_split no soporta la opción «global»" +#: utils/adt/regexp.c:1108 +#, c-format +msgid "too many regular expression matches" +msgstr "demasiadas coincidencias de la expresión regular" #: utils/adt/regproc.c:106 #, c-format @@ -21583,8 +22297,18 @@ msgstr "existe más de una función llamada «%s»" msgid "more than one operator named %s" msgstr "existe más de un operador llamado %s" +#: utils/adt/regproc.c:691 utils/adt/regproc.c:732 gram.y:8145 +#, c-format +msgid "missing argument" +msgstr "falta un argumento" + +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8146 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Use NONE para denotar el argumento faltante de un operador unario." + #: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 -#: utils/adt/ruleutils.c:8884 utils/adt/ruleutils.c:9052 +#: utils/adt/ruleutils.c:9210 utils/adt/ruleutils.c:9378 #, c-format msgid "too many arguments" msgstr "demasiados argumentos" @@ -21596,7 +22320,7 @@ msgstr "Provea dos tipos de argumento para un operador." #: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 #: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 -#: utils/adt/varlena.c:3216 utils/adt/varlena.c:3221 +#: utils/adt/varlena.c:3625 utils/adt/varlena.c:3630 #, c-format msgid "invalid name syntax" msgstr "la sintaxis de nombre no es válida" @@ -21621,150 +22345,155 @@ msgstr "se esperaba un nombre de tipo" msgid "improper type name" msgstr "el nombre de tipo no es válido" -#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2487 -#: utils/adt/ri_triggers.c:3312 +#: utils/adt/ri_triggers.c:298 utils/adt/ri_triggers.c:1534 +#: utils/adt/ri_triggers.c:2465 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "inserción o actualización en la tabla «%s» viola la llave foránea «%s»" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 +#: utils/adt/ri_triggers.c:301 utils/adt/ri_triggers.c:1537 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL no permite la mezcla de valores de clave nulos y no nulos." -#: utils/adt/ri_triggers.c:2729 +#: utils/adt/ri_triggers.c:1932 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "la función «%s» debe ser ejecutada en INSERT" -#: utils/adt/ri_triggers.c:2735 +#: utils/adt/ri_triggers.c:1938 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "la función «%s» debe ser ejecutada en UPDATE" -#: utils/adt/ri_triggers.c:2741 +#: utils/adt/ri_triggers.c:1944 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "la función «%s» debe ser ejecutada en DELETE" -#: utils/adt/ri_triggers.c:2764 +#: utils/adt/ri_triggers.c:1967 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "no hay una entrada en pg_constraint para el trigger «%s» en tabla «%s»" -#: utils/adt/ri_triggers.c:2766 +#: utils/adt/ri_triggers.c:1969 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "Elimine este trigger de integridad referencial y sus pares, y utilice ALTER TABLE ADD CONSTRAINT." -#: utils/adt/ri_triggers.c:3222 +#: utils/adt/ri_triggers.c:1999 gram.y:3784 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL no está implementada" + +#: utils/adt/ri_triggers.c:2291 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "la consulta de integridad referencial en «%s» de la restricción «%s» en «%s» entregó un resultado inesperado" -#: utils/adt/ri_triggers.c:3226 +#: utils/adt/ri_triggers.c:2295 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Esto probablemente es causado por una regla que reescribió la consulta." -#: utils/adt/ri_triggers.c:3316 +#: utils/adt/ri_triggers.c:2456 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "eliminar la partición «%s» viola la llave foránea «%s»" + +#: utils/adt/ri_triggers.c:2459 +#, c-format +msgid "Key (%s)=(%s) still referenced from table \"%s\"." +msgstr "La llave (%s)=(%s) todavía es referida desde la tabla «%s»." + +#: utils/adt/ri_triggers.c:2469 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "La llave (%s)=(%s) no está presente en la tabla «%s»." -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/ri_triggers.c:2472 #, c-format msgid "Key is not present in table \"%s\"." msgstr "La llave no está presente en la tabla «%s»." -#: utils/adt/ri_triggers.c:3325 +#: utils/adt/ri_triggers.c:2478 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "update o delete en «%s» viola la llave foránea «%s» en la tabla «%s»" -#: utils/adt/ri_triggers.c:3330 +#: utils/adt/ri_triggers.c:2483 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "La llave (%s)=(%s) todavía es referida desde la tabla «%s»." -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/ri_triggers.c:2486 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "La llave todavía es referida desde la tabla «%s»." -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "el ingreso de tipos compuestos anónimos no está implementado" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 #, c-format msgid "malformed record literal: \"%s\"" -msgstr "literal de record no es válido: «%s»" +msgstr "literal de record mal formado: «%s»" -#: utils/adt/rowtypes.c:156 +#: utils/adt/rowtypes.c:157 #, c-format msgid "Missing left parenthesis." msgstr "Falta paréntesis izquierdo." -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:186 #, c-format msgid "Too few columns." msgstr "Muy pocas columnas." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:269 #, c-format msgid "Too many columns." msgstr "Demasiadas columnas." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:277 #, c-format msgid "Junk after right parenthesis." msgstr "Basura después del paréntesis derecho." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:531 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "número de columnas erróneo: %d, se esperaban %d" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:559 #, c-format msgid "wrong data type: %u, expected %u" msgstr "tipo de dato erróneo: %u, se esperaba %u" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:620 #, c-format msgid "improper binary format in record column %d" msgstr "formato binario incorrecto en la columna record %d" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 -#: utils/adt/rowtypes.c:1396 utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1155 utils/adt/rowtypes.c:1414 +#: utils/adt/rowtypes.c:1658 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "no se pueden comparar los tipos de columnas disímiles %s y %s en la columna %d" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 -#: utils/adt/rowtypes.c:1529 utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:1000 utils/adt/rowtypes.c:1226 +#: utils/adt/rowtypes.c:1509 utils/adt/rowtypes.c:1694 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "no se pueden comparar registros con cantidad distinta de columnas" -#: utils/adt/ruleutils.c:4655 +#: utils/adt/ruleutils.c:4885 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "la regla «%s» tiene el tipo de evento no soportado %d" -#: utils/adt/selfuncs.c:5547 -#, c-format -msgid "case insensitive matching not supported on type bytea" -msgstr "no está soportada la comparación insensible a mayúsculas en bytea" - -#: utils/adt/selfuncs.c:5649 -#, c-format -msgid "regular-expression matching not supported on type bytea" -msgstr "no está soportada la comparación con expresiones regulares en bytea" - #: utils/adt/timestamp.c:107 #, c-format msgid "TIMESTAMP(%d)%s precision must not be negative" @@ -21775,126 +22504,121 @@ msgstr "la precisión de TIMESTAMP(%d)%s no debe ser negativa" msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "la precisión de TIMESTAMP(%d)%s fue reducida al máximo permitido, %d" -#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:427 #, c-format msgid "timestamp out of range: \"%s\"" msgstr "timestamp fuera de rango: «%s»" -#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 -#: utils/adt/timestamp.c:941 +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:445 +#: utils/adt/timestamp.c:952 #, c-format msgid "date/time value \"%s\" is no longer supported" msgstr "el valor de date/time «%s» ya no está soportado" -#: utils/adt/timestamp.c:362 +#: utils/adt/timestamp.c:373 #, c-format msgid "timestamp(%d) precision must be between %d and %d" msgstr "la precisión de timestamp(%d) debe estar entre %d y %d" -#: utils/adt/timestamp.c:484 -#, c-format -msgid "invalid input syntax for numeric time zone: \"%s\"" -msgstr "la sintaxis de entrada no es válida para el huso horario numérico: «%s»" - -#: utils/adt/timestamp.c:486 +#: utils/adt/timestamp.c:497 #, c-format msgid "Numeric time zones must have \"-\" or \"+\" as first character." msgstr "Los husos horarios numéricos deben tener «-» o «+» como su primer carácter." -#: utils/adt/timestamp.c:499 +#: utils/adt/timestamp.c:510 #, c-format msgid "numeric time zone \"%s\" out of range" msgstr "el huso horario numérico «%s» está fuera de rango" -#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 -#: utils/adt/timestamp.c:619 +#: utils/adt/timestamp.c:612 utils/adt/timestamp.c:622 +#: utils/adt/timestamp.c:630 #, c-format msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" msgstr "timestamp fuera de rango: %d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:720 +#: utils/adt/timestamp.c:731 #, c-format msgid "timestamp cannot be NaN" msgstr "el timestamp no puede ser NaN" -#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#: utils/adt/timestamp.c:749 utils/adt/timestamp.c:761 #, c-format msgid "timestamp out of range: \"%g\"" msgstr "timestamp fuera de rango: «%g»" -#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 -#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:2994 -#: utils/adt/timestamp.c:2999 utils/adt/timestamp.c:3004 -#: utils/adt/timestamp.c:3054 utils/adt/timestamp.c:3061 -#: utils/adt/timestamp.c:3068 utils/adt/timestamp.c:3088 -#: utils/adt/timestamp.c:3095 utils/adt/timestamp.c:3102 -#: utils/adt/timestamp.c:3132 utils/adt/timestamp.c:3140 -#: utils/adt/timestamp.c:3184 utils/adt/timestamp.c:3507 -#: utils/adt/timestamp.c:3632 utils/adt/timestamp.c:4000 +#: utils/adt/timestamp.c:946 utils/adt/timestamp.c:1526 +#: utils/adt/timestamp.c:1959 utils/adt/timestamp.c:3057 +#: utils/adt/timestamp.c:3062 utils/adt/timestamp.c:3067 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3131 utils/adt/timestamp.c:3151 +#: utils/adt/timestamp.c:3158 utils/adt/timestamp.c:3165 +#: utils/adt/timestamp.c:3195 utils/adt/timestamp.c:3203 +#: utils/adt/timestamp.c:3247 utils/adt/timestamp.c:3674 +#: utils/adt/timestamp.c:3799 utils/adt/timestamp.c:4259 #, c-format msgid "interval out of range" msgstr "interval fuera de rango" -#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#: utils/adt/timestamp.c:1079 utils/adt/timestamp.c:1112 #, c-format msgid "invalid INTERVAL type modifier" msgstr "modificador de tipo INTERVAL no válido" -#: utils/adt/timestamp.c:1084 +#: utils/adt/timestamp.c:1095 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "la precisión de INTERVAL(%d) no debe ser negativa" -#: utils/adt/timestamp.c:1090 +#: utils/adt/timestamp.c:1101 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "la precisión de INTERVAL(%d) fue reducida al máximo permitido, %d" -#: utils/adt/timestamp.c:1462 +#: utils/adt/timestamp.c:1483 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "la precisión de interval(%d) debe estar entre %d y %d" -#: utils/adt/timestamp.c:2595 +#: utils/adt/timestamp.c:2658 #, c-format msgid "cannot subtract infinite timestamps" msgstr "no se pueden restar timestamps infinitos" -#: utils/adt/timestamp.c:3751 utils/adt/timestamp.c:4260 -#: utils/adt/timestamp.c:4427 utils/adt/timestamp.c:4448 +#: utils/adt/timestamp.c:3927 utils/adt/timestamp.c:4519 +#: utils/adt/timestamp.c:4686 utils/adt/timestamp.c:4707 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "las unidades de timestamp «%s» no están soportadas" -#: utils/adt/timestamp.c:3765 utils/adt/timestamp.c:4214 -#: utils/adt/timestamp.c:4458 +#: utils/adt/timestamp.c:3941 utils/adt/timestamp.c:4473 +#: utils/adt/timestamp.c:4717 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "las unidades de timestamp «%s» no son reconocidas" -#: utils/adt/timestamp.c:3897 utils/adt/timestamp.c:4255 -#: utils/adt/timestamp.c:4628 utils/adt/timestamp.c:4650 +#: utils/adt/timestamp.c:4071 utils/adt/timestamp.c:4514 +#: utils/adt/timestamp.c:4887 utils/adt/timestamp.c:4909 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "las unidades de timestamp with time zone «%s» no están soportadas" -#: utils/adt/timestamp.c:3914 utils/adt/timestamp.c:4209 -#: utils/adt/timestamp.c:4659 +#: utils/adt/timestamp.c:4088 utils/adt/timestamp.c:4468 +#: utils/adt/timestamp.c:4918 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "las unidades de timestamp with time zone «%s» no son reconocidas" -#: utils/adt/timestamp.c:3987 +#: utils/adt/timestamp.c:4246 #, c-format msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "las unidades de intervalo «%s» no están soportadas porque los meses normalmente tienen semanas fraccionales" -#: utils/adt/timestamp.c:3993 utils/adt/timestamp.c:4753 +#: utils/adt/timestamp.c:4252 utils/adt/timestamp.c:5012 #, c-format msgid "interval units \"%s\" not supported" msgstr "las unidades de interval «%s» no están soportadas" -#: utils/adt/timestamp.c:4009 utils/adt/timestamp.c:4776 +#: utils/adt/timestamp.c:4268 utils/adt/timestamp.c:5035 #, c-format msgid "interval units \"%s\" not recognized" msgstr "las unidades de interval «%s» no son reconocidas" @@ -21919,48 +22643,48 @@ msgstr "suppress_redundant_updates_trigger: debe ser invocado «BEFORE UPDATE»" msgid "suppress_redundant_updates_trigger: must be called for each row" msgstr "suppress_redundant_updates_trigger: debe ser invocado «FOR EACH ROW»" -#: utils/adt/tsgistidx.c:100 +#: utils/adt/tsgistidx.c:81 #, c-format msgid "gtsvector_in not implemented" msgstr "gtsvector_in no está implementado" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "distancia en operador de frases no debe ser mayor que %d" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "error de sintaxis en tsquery: «%s»" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "no hay operando en tsquery: «%s»" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "el valor es demasiado grande en tsquery: «%s»" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "el operando es muy largo en tsquery: «%s»" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "palabra demasiado larga en tsquery: «%s»" -#: utils/adt/tsquery.c:642 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "la consulta de búsqueda en texto no contiene lexemas: «%s»" -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "el tsquery es demasiado grande" @@ -22010,254 +22734,252 @@ msgstr "la palabra es demasiado larga (%ld, máximo %ld bytes)" msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "la cadena es demasiado larga para tsvector (%ld bytes, máximo %ld bytes)" -#: utils/adt/tsvector_op.c:323 utils/adt/tsvector_op.c:610 -#: utils/adt/tsvector_op.c:778 +#: utils/adt/tsvector_op.c:321 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:776 #, c-format msgid "lexeme array may not contain nulls" msgstr "el array de lexemas no debe contener nulls" -#: utils/adt/tsvector_op.c:853 +#: utils/adt/tsvector_op.c:851 #, c-format msgid "weight array may not contain nulls" msgstr "el array de pesos no debe contener nulls" -#: utils/adt/tsvector_op.c:877 +#: utils/adt/tsvector_op.c:875 #, c-format msgid "unrecognized weight: \"%c\"" msgstr "no se reconoce el peso: «%c»" -#: utils/adt/tsvector_op.c:2314 +#: utils/adt/tsvector_op.c:2312 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "la consulta ts_stat debe retornar una columna tsvector" -#: utils/adt/tsvector_op.c:2496 +#: utils/adt/tsvector_op.c:2494 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "la columna tsvector «%s» no existe" -#: utils/adt/tsvector_op.c:2503 +#: utils/adt/tsvector_op.c:2501 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "la columna «%s» no es de tipo tsvector" -#: utils/adt/tsvector_op.c:2515 +#: utils/adt/tsvector_op.c:2513 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "la columna de configuración «%s» no existe" -#: utils/adt/tsvector_op.c:2521 +#: utils/adt/tsvector_op.c:2519 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "la columna «%s» no es de tipo regconfig" -#: utils/adt/tsvector_op.c:2528 +#: utils/adt/tsvector_op.c:2526 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "la columna de configuración «%s» no debe ser nula" -#: utils/adt/tsvector_op.c:2541 +#: utils/adt/tsvector_op.c:2539 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "el nombre de la configuración de búsqueda «%s» debe ser calificada con esquema" -#: utils/adt/tsvector_op.c:2566 +#: utils/adt/tsvector_op.c:2564 #, c-format msgid "column \"%s\" is not of a character type" msgstr "la columna «%s» no es de un tipo textual" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "error de sintaxis en tsvector: «%s»" -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "no hay carácter escapado: «%s»" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "información posicional incorrecta en tsvector: «%s»" -#: utils/adt/txid.c:135 -#, fuzzy, c-format -msgid "transaction ID " -msgstr "transacción %u" +#: utils/adt/txid.c:140 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "el ID de transacción %s está en el futuro" -#: utils/adt/txid.c:624 +#: utils/adt/txid.c:629 #, c-format msgid "invalid external txid_snapshot data" msgstr "valor externo txid_snapshot no válido" -#: utils/adt/txid.c:758 utils/adt/txid.c:779 -#, fuzzy -msgid "in progress" -msgstr "la recuperación está en proceso" - -#: utils/adt/txid.c:760 -msgid "committed" -msgstr "" - -#: utils/adt/txid.c:762 utils/adt/txid.c:777 -msgid "aborted" -msgstr "" - -#: utils/adt/varbit.c:58 utils/adt/varchar.c:51 +#: utils/adt/varbit.c:60 utils/adt/varchar.c:54 #, c-format msgid "length for type %s must be at least 1" msgstr "el largo para el tipo %s debe ser al menos 1" -#: utils/adt/varbit.c:63 utils/adt/varchar.c:55 +#: utils/adt/varbit.c:65 utils/adt/varchar.c:58 #, c-format msgid "length for type %s cannot exceed %d" msgstr "el largo del tipo %s no puede exceder %d" -#: utils/adt/varbit.c:164 utils/adt/varbit.c:476 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:166 utils/adt/varbit.c:478 utils/adt/varbit.c:984 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "el tamaño de la cadena de bits excede el máximo permitido (%d)" -#: utils/adt/varbit.c:178 utils/adt/varbit.c:321 utils/adt/varbit.c:378 +#: utils/adt/varbit.c:180 utils/adt/varbit.c:323 utils/adt/varbit.c:380 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "el largo de la cadena de bits %d no coincide con el tipo bit(%d)" -#: utils/adt/varbit.c:200 utils/adt/varbit.c:512 +#: utils/adt/varbit.c:202 utils/adt/varbit.c:514 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "«%c» no es un dígito binario válido" -#: utils/adt/varbit.c:225 utils/adt/varbit.c:537 +#: utils/adt/varbit.c:227 utils/adt/varbit.c:539 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "«%c» no es un dígito hexadecimal válido" -#: utils/adt/varbit.c:312 utils/adt/varbit.c:628 +#: utils/adt/varbit.c:314 utils/adt/varbit.c:630 #, c-format msgid "invalid length in external bit string" -msgstr "el largo largo no es válido en cadena de bits externa" +msgstr "el largo no es válido en cadena de bits externa" -#: utils/adt/varbit.c:490 utils/adt/varbit.c:637 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:492 utils/adt/varbit.c:639 utils/adt/varbit.c:742 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "la cadena de bits es demasiado larga para el tipo bit varying(%d)" -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:841 -#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2881 -#: utils/adt/varlena.c:2948 +#: utils/adt/varbit.c:1077 utils/adt/varbit.c:1179 utils/adt/varlena.c:863 +#: utils/adt/varlena.c:927 utils/adt/varlena.c:1071 utils/adt/varlena.c:3291 +#: utils/adt/varlena.c:3358 #, c-format msgid "negative substring length not allowed" msgstr "no se permite un largo negativo de subcadena" -#: utils/adt/varbit.c:1226 +#: utils/adt/varbit.c:1236 #, c-format msgid "cannot AND bit strings of different sizes" msgstr "no se puede hacer AND entre cadenas de bits de distintos tamaños" -#: utils/adt/varbit.c:1268 +#: utils/adt/varbit.c:1278 #, c-format msgid "cannot OR bit strings of different sizes" msgstr "no se puede hacer OR entre cadenas de bits de distintos tamaños" -#: utils/adt/varbit.c:1315 +#: utils/adt/varbit.c:1325 #, c-format msgid "cannot XOR bit strings of different sizes" msgstr "no se puede hacer XOR entre cadenas de bits de distintos tamaños" -#: utils/adt/varbit.c:1803 utils/adt/varbit.c:1861 +#: utils/adt/varbit.c:1813 utils/adt/varbit.c:1871 #, c-format msgid "bit index %d out of valid range (0..%d)" msgstr "el índice de bit %d está fuera del rango válido (0..%d)" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3140 +#: utils/adt/varbit.c:1822 utils/adt/varlena.c:3549 #, c-format msgid "new bit must be 0 or 1" msgstr "el nuevo bit debe ser 0 o 1" -#: utils/adt/varchar.c:155 utils/adt/varchar.c:308 +#: utils/adt/varchar.c:158 utils/adt/varchar.c:311 #, c-format msgid "value too long for type character(%d)" msgstr "el valor es demasiado largo para el tipo character(%d)" -#: utils/adt/varchar.c:470 utils/adt/varchar.c:623 +#: utils/adt/varchar.c:473 utils/adt/varchar.c:635 #, c-format msgid "value too long for type character varying(%d)" msgstr "el valor es demasiado largo para el tipo character varying(%d)" -#: utils/adt/varlena.c:1416 utils/adt/varlena.c:1865 +#: utils/adt/varchar.c:733 utils/adt/varlena.c:1455 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "no se pudo determinar qué ordenamiento usar para la comparación de cadenas" -#: utils/adt/varlena.c:1473 utils/adt/varlena.c:1486 +#: utils/adt/varchar.c:1122 utils/adt/varchar.c:1232 utils/adt/varlena.c:3024 +#: utils/adt/varlena.c:3134 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "los ordenamientos no determinísticos no están soportados para la clase de operadores «%s»" + +#: utils/adt/varlena.c:1165 utils/adt/varlena.c:1889 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "los ordenamientos no determinísticos no están soportados para búsquedas de sub-cadenas" + +#: utils/adt/varlena.c:1548 utils/adt/varlena.c:1561 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "no se pudo convertir la cadena a UTF-16: código de error %lu" -#: utils/adt/varlena.c:1501 +#: utils/adt/varlena.c:1576 #, c-format msgid "could not compare Unicode strings: %m" msgstr "no se pudieron comparar las cadenas Unicode: %m" -#: utils/adt/varlena.c:1556 utils/adt/varlena.c:2145 -#, fuzzy, c-format +#: utils/adt/varlena.c:1627 utils/adt/varlena.c:2341 +#, c-format msgid "collation failed: %s" -msgstr "pclose falló: %s" +msgstr "el ordenamiento falló: %s" -#: utils/adt/varlena.c:2363 -#, fuzzy, c-format +#: utils/adt/varlena.c:2549 +#, c-format msgid "sort key generation failed: %s" -msgstr "la expresión regular falló: %s" +msgstr "la generación de la llave de ordenamiento falló: %s" -#: utils/adt/varlena.c:3026 utils/adt/varlena.c:3057 utils/adt/varlena.c:3092 -#: utils/adt/varlena.c:3128 +#: utils/adt/varlena.c:3435 utils/adt/varlena.c:3466 utils/adt/varlena.c:3501 +#: utils/adt/varlena.c:3537 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "el índice %d está fuera de rango [0..%d]" -#: utils/adt/varlena.c:4059 +#: utils/adt/varlena.c:4573 #, c-format msgid "field position must be greater than zero" msgstr "la posición del campo debe ser mayor que cero" -#: utils/adt/varlena.c:4949 +#: utils/adt/varlena.c:5439 #, c-format msgid "unterminated format() type specifier" msgstr "especificador de tipo inconcluso en format()" -#: utils/adt/varlena.c:4950 utils/adt/varlena.c:5084 utils/adt/varlena.c:5205 +#: utils/adt/varlena.c:5440 utils/adt/varlena.c:5574 utils/adt/varlena.c:5695 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Para un «%%» solo, use «%%%%»." -#: utils/adt/varlena.c:5082 utils/adt/varlena.c:5203 +#: utils/adt/varlena.c:5572 utils/adt/varlena.c:5693 #, c-format msgid "unrecognized format() type specifier \"%c\"" msgstr "especificador de tipo no reconocido «%c» en format()" -#: utils/adt/varlena.c:5095 utils/adt/varlena.c:5152 +#: utils/adt/varlena.c:5585 utils/adt/varlena.c:5642 #, c-format msgid "too few arguments for format()" msgstr "muy pocos argumentos para format()" -#: utils/adt/varlena.c:5247 utils/adt/varlena.c:5430 +#: utils/adt/varlena.c:5738 utils/adt/varlena.c:5920 #, c-format msgid "number is out of range" msgstr "el número está fuera de rango" -#: utils/adt/varlena.c:5311 utils/adt/varlena.c:5339 +#: utils/adt/varlena.c:5801 utils/adt/varlena.c:5829 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "la conversión especifica el argumento 0, pero los argumentos se numeran desde 1" -#: utils/adt/varlena.c:5332 +#: utils/adt/varlena.c:5822 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "la posición del argumento de anchura debe terminar con «$»" -#: utils/adt/varlena.c:5377 +#: utils/adt/varlena.c:5867 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "los valores nulos no pueden ser formateados como un identificador SQL" @@ -22272,247 +22994,222 @@ msgstr "el argumento de ntile debe ser mayor que cero" msgid "argument of nth_value must be greater than zero" msgstr "el argumento de nth_value debe ser mayor que cero" -#: utils/adt/xml.c:220 +#: utils/adt/xml.c:222 #, c-format msgid "unsupported XML feature" msgstr "característica XML no soportada" -#: utils/adt/xml.c:221 +#: utils/adt/xml.c:223 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "Esta funcionalidad requiere que el servidor haya sido construido con soporte libxml." -#: utils/adt/xml.c:222 +#: utils/adt/xml.c:224 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "Necesita reconstruir PostgreSQL usando --with-libxml." -#: utils/adt/xml.c:241 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:243 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "nombre de codificación «%s» no válido" -#: utils/adt/xml.c:484 utils/adt/xml.c:489 +#: utils/adt/xml.c:486 utils/adt/xml.c:491 #, c-format msgid "invalid XML comment" msgstr "comentario XML no válido" -#: utils/adt/xml.c:618 +#: utils/adt/xml.c:620 #, c-format msgid "not an XML document" msgstr "no es un documento XML" -#: utils/adt/xml.c:777 utils/adt/xml.c:800 +#: utils/adt/xml.c:779 utils/adt/xml.c:802 #, c-format msgid "invalid XML processing instruction" msgstr "instrucción de procesamiento XML no válida" -#: utils/adt/xml.c:778 +#: utils/adt/xml.c:780 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "el nombre de destino de la instrucción de procesamiento XML no puede ser «%s»." -#: utils/adt/xml.c:801 +#: utils/adt/xml.c:803 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "la instrucción de procesamiento XML no puede contener «?>»." -#: utils/adt/xml.c:880 +#: utils/adt/xml.c:882 #, c-format msgid "xmlvalidate is not implemented" msgstr "xmlvalidate no está implementado" -#: utils/adt/xml.c:959 +#: utils/adt/xml.c:961 #, c-format msgid "could not initialize XML library" msgstr "no se pudo inicializar la biblioteca XML" -#: utils/adt/xml.c:960 +#: utils/adt/xml.c:962 #, c-format msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "libxml2 tiene tipo char incompatible: sizeof(char)=%u, sizeof(xmlChar)=%u." -#: utils/adt/xml.c:1046 +#: utils/adt/xml.c:1048 #, c-format msgid "could not set up XML error handler" msgstr "no se pudo instalar un gestor de errores XML" -#: utils/adt/xml.c:1047 +#: utils/adt/xml.c:1049 #, c-format msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." msgstr "Esto probablemente indica que la versión de libxml2 en uso no es compatible con los archivos de cabecera libxml2 con los que PostgreSQL fue construido." -#: utils/adt/xml.c:1797 +#: utils/adt/xml.c:1936 msgid "Invalid character value." msgstr "Valor de carácter no válido." -#: utils/adt/xml.c:1800 +#: utils/adt/xml.c:1939 msgid "Space required." msgstr "Se requiere un espacio." -#: utils/adt/xml.c:1803 +#: utils/adt/xml.c:1942 msgid "standalone accepts only 'yes' or 'no'." msgstr "standalone acepta sólo 'yes' y 'no'." -#: utils/adt/xml.c:1806 +#: utils/adt/xml.c:1945 msgid "Malformed declaration: missing version." msgstr "Declaración mal formada: falta la versión." -#: utils/adt/xml.c:1809 +#: utils/adt/xml.c:1948 msgid "Missing encoding in text declaration." msgstr "Falta especificación de codificación en declaración de texto." -#: utils/adt/xml.c:1812 +#: utils/adt/xml.c:1951 msgid "Parsing XML declaration: '?>' expected." msgstr "Procesando declaración XML: se esperaba '?>'." -#: utils/adt/xml.c:1815 +#: utils/adt/xml.c:1954 #, c-format msgid "Unrecognized libxml error code: %d." msgstr "Código de error libxml no reconocido: %d." -#: utils/adt/xml.c:2090 +#: utils/adt/xml.c:2229 #, c-format msgid "XML does not support infinite date values." msgstr "XML no soporta valores infinitos de fecha." -#: utils/adt/xml.c:2112 utils/adt/xml.c:2139 +#: utils/adt/xml.c:2251 utils/adt/xml.c:2278 #, c-format msgid "XML does not support infinite timestamp values." msgstr "XML no soporta valores infinitos de timestamp." -#: utils/adt/xml.c:2551 +#: utils/adt/xml.c:2690 #, c-format msgid "invalid query" msgstr "consulta no válido" -#: utils/adt/xml.c:3870 +#: utils/adt/xml.c:4037 #, c-format msgid "invalid array for XML namespace mapping" msgstr "array no válido para mapeo de espacio de nombres XML" -#: utils/adt/xml.c:3871 +#: utils/adt/xml.c:4038 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "El array debe ser bidimensional y el largo del segundo eje igual a 2." -#: utils/adt/xml.c:3895 +#: utils/adt/xml.c:4062 #, c-format msgid "empty XPath expression" msgstr "expresion XPath vacía" -#: utils/adt/xml.c:3939 +#: utils/adt/xml.c:4114 #, c-format msgid "neither namespace name nor URI may be null" msgstr "ni el espacio de nombres ni la URI pueden ser vacíos" -#: utils/adt/xml.c:3946 +#: utils/adt/xml.c:4121 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "no se pudo registrar un espacio de nombres XML llamado «%s» con URI «%s»" -#: utils/adt/xml.c:4300 -#, fuzzy, c-format +#: utils/adt/xml.c:4472 +#, c-format msgid "DEFAULT namespace is not supported" -msgstr "la sintaxis LIMIT #,# no está soportada" +msgstr "el espacio de nombres DEFAULT no está soportado" -#: utils/adt/xml.c:4329 -#, fuzzy, c-format +#: utils/adt/xml.c:4501 +#, c-format msgid "row path filter must not be empty string" -msgstr "El identificador en comillas no debe ser vacío." +msgstr "el «path» de filtro de registros no debe ser la cadena vacía" -#: utils/adt/xml.c:4360 -#, fuzzy, c-format +#: utils/adt/xml.c:4532 +#, c-format msgid "column path filter must not be empty string" -msgstr "El identificador en comillas no debe ser vacío." +msgstr "el «path» de filtro de columna no debe ser la cadena vacía" -#: utils/adt/xml.c:4542 -#, fuzzy, c-format +#: utils/adt/xml.c:4682 +#, c-format msgid "more than one value returned by column XPath expression" -msgstr "una subconsulta utilizada como expresión retornó más de un registro" +msgstr "la expresión XPath de columna retornó más de un valor" -#: utils/cache/lsyscache.c:2612 utils/cache/lsyscache.c:2645 -#: utils/cache/lsyscache.c:2678 utils/cache/lsyscache.c:2711 +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "el tipo %s está inconcluso" -#: utils/cache/lsyscache.c:2617 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "no hay una función de entrada para el tipo %s" -#: utils/cache/lsyscache.c:2650 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "no hay una función de salida para el tipo %s" -#: utils/cache/plancache.c:722 +#: utils/cache/partcache.c:195 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "falta la función de soporte %3$d para el tipo %4$s de la clase de operadores «%1$s» del método de acceso %2$s" + +#: utils/cache/plancache.c:718 #, c-format msgid "cached plan must not change result type" msgstr "el plan almacenado no debe cambiar el tipo de resultado" -#: utils/cache/relcache.c:5791 +#: utils/cache/relcache.c:5751 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "no se pudo crear el archivo de cache de catálogos de sistema «%s»: %m" -#: utils/cache/relcache.c:5793 +#: utils/cache/relcache.c:5753 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Prosiguiendo de todas maneras, pero hay algo mal." -#: utils/cache/relcache.c:6063 +#: utils/cache/relcache.c:6107 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "no se pudo eliminar el archivo de cache «%s»: %m" -#: utils/cache/relmapper.c:509 +#: utils/cache/relmapper.c:531 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "no se puede hacer PREPARE de una transacción que ha modificado el mapeo de relaciones" -#: utils/cache/relmapper.c:652 utils/cache/relmapper.c:754 -#, c-format -msgid "could not open relation mapping file \"%s\": %m" -msgstr "no se pudo abrir el archivo de mapeo de relaciones «%s»: %m" - -#: utils/cache/relmapper.c:666 -#, c-format -msgid "could not read relation mapping file \"%s\": %m" -msgstr "no se pudo leer el archivo de mapeo de relaciones «%s»: %m" - -#: utils/cache/relmapper.c:677 +#: utils/cache/relmapper.c:761 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "el archivo de mapeo de relaciones «%s» contiene datos no válidos" -#: utils/cache/relmapper.c:687 +#: utils/cache/relmapper.c:771 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "el archivo de mapeo de relaciones «%s» tiene una suma de verificación incorrecta" -#: utils/cache/relmapper.c:788 -#, c-format -msgid "could not write to relation mapping file \"%s\": %m" -msgstr "no se pudo escribir el archivo de mapeo de relaciones «%s»: %m" - -#: utils/cache/relmapper.c:803 -#, c-format -msgid "could not fsync relation mapping file \"%s\": %m" -msgstr "no se pudo sincronizar (fsync) el archivo de mapeo de relaciones «%s»: %m" - -#: utils/cache/relmapper.c:810 -#, c-format -msgid "could not close relation mapping file \"%s\": %m" -msgstr "no se pudo cerrar el archivo de mapeo de relaciones «%s»: %m" - -#: utils/cache/typcache.c:1223 -#, c-format -msgid "type %s is not composite" -msgstr "el tipo %s no es compuesto" - -#: utils/cache/typcache.c:1237 +#: utils/cache/typcache.c:1634 utils/fmgr/funcapi.c:420 #, c-format msgid "record type has not been registered" msgstr "el tipo record no ha sido registrado" @@ -22527,528 +23224,558 @@ msgstr "TRAP: ExceptionalConditions: argumentos erróneos\n" msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" msgstr "TRAP: %s(«%s», Archivo: «%s», Línea: %d)\n" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/error/elog.c:319 utils/error/elog.c:1293 #, c-format msgid "error occurred at %s:%d before error message processing is available\n" msgstr "ocurrió un error en %s:%d antes de que el procesamiento de mensajes de error esté disponible\n" -#: utils/error/elog.c:1889 +#: utils/error/elog.c:1871 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" msgstr "no se pudo reabrir «%s» para error estándar: %m" -#: utils/error/elog.c:1902 +#: utils/error/elog.c:1884 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" msgstr "no se pudo reabrir «%s» para usar como salida estándar: %m" -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 +#: utils/error/elog.c:2376 utils/error/elog.c:2393 utils/error/elog.c:2409 msgid "[unknown]" msgstr "[desconocido]" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 +#: utils/error/elog.c:2869 utils/error/elog.c:3172 utils/error/elog.c:3280 msgid "missing error text" msgstr "falta un texto de mensaje de error" -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 -#: utils/error/elog.c:3299 +#: utils/error/elog.c:2872 utils/error/elog.c:2875 utils/error/elog.c:3283 +#: utils/error/elog.c:3286 #, c-format msgid " at character %d" msgstr " en carácter %d" -#: utils/error/elog.c:2898 utils/error/elog.c:2905 +#: utils/error/elog.c:2885 utils/error/elog.c:2892 msgid "DETAIL: " msgstr "DETALLE: " -#: utils/error/elog.c:2912 +#: utils/error/elog.c:2899 msgid "HINT: " msgstr "HINT: " -#: utils/error/elog.c:2919 +#: utils/error/elog.c:2906 msgid "QUERY: " msgstr "CONSULTA: " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2913 msgid "CONTEXT: " msgstr "CONTEXTO: " -#: utils/error/elog.c:2936 +#: utils/error/elog.c:2923 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "UBICACIÓN: %s, %s:%d\n" -#: utils/error/elog.c:2943 +#: utils/error/elog.c:2930 #, c-format msgid "LOCATION: %s:%d\n" msgstr "UBICACIÓN: %s:%d\n" -#: utils/error/elog.c:2957 +#: utils/error/elog.c:2944 msgid "STATEMENT: " msgstr "SENTENCIA: " -#. translator: This string will be truncated at 47 -#. characters expanded. -#: utils/error/elog.c:3414 -#, c-format -msgid "operating system error %d" -msgstr "error %d de sistema operativo" - -#: utils/error/elog.c:3612 +#: utils/error/elog.c:3333 msgid "DEBUG" msgstr "DEBUG" -#: utils/error/elog.c:3616 +#: utils/error/elog.c:3337 msgid "LOG" msgstr "LOG" -#: utils/error/elog.c:3619 +#: utils/error/elog.c:3340 msgid "INFO" msgstr "INFO" -#: utils/error/elog.c:3622 +#: utils/error/elog.c:3343 msgid "NOTICE" msgstr "NOTICE" -#: utils/error/elog.c:3625 +#: utils/error/elog.c:3346 msgid "WARNING" msgstr "WARNING" -#: utils/error/elog.c:3628 +#: utils/error/elog.c:3349 msgid "ERROR" msgstr "ERROR" -#: utils/error/elog.c:3631 +#: utils/error/elog.c:3352 msgid "FATAL" msgstr "FATAL" -#: utils/error/elog.c:3634 +#: utils/error/elog.c:3355 msgid "PANIC" msgstr "PANIC" -#: utils/fmgr/dfmgr.c:121 +#: utils/fmgr/dfmgr.c:130 #, c-format msgid "could not find function \"%s\" in file \"%s\"" -msgstr "no se encuentra la función «%s» en el archivo «%s»" - -#: utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 utils/fmgr/dfmgr.c:466 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "no se pudo acceder al archivo «%s»: %m" +msgstr "no se pudo encontrar la función «%s» en el archivo «%s»" -#: utils/fmgr/dfmgr.c:239 +#: utils/fmgr/dfmgr.c:247 #, c-format msgid "could not load library \"%s\": %s" msgstr "no se pudo cargar la biblioteca «%s»: %s" -#: utils/fmgr/dfmgr.c:271 +#: utils/fmgr/dfmgr.c:279 #, c-format msgid "incompatible library \"%s\": missing magic block" msgstr "biblioteca «%s» incompatible: no se encuentra el bloque mágico" -#: utils/fmgr/dfmgr.c:273 +#: utils/fmgr/dfmgr.c:281 #, c-format msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." msgstr "Se requiere que las bibliotecas de extensión usen la macro PG_MODULE_MAGIC." -#: utils/fmgr/dfmgr.c:319 +#: utils/fmgr/dfmgr.c:327 #, c-format msgid "incompatible library \"%s\": version mismatch" msgstr "biblioteca «%s» incompatible: versión no coincide" -#: utils/fmgr/dfmgr.c:321 -#, fuzzy, c-format +#: utils/fmgr/dfmgr.c:329 +#, c-format msgid "Server is version %d, library is version %s." -msgstr "Servidor tiene versión %d.%d, biblioteca es versión %d.%d." +msgstr "Versión del servidor %d, versión de biblioteca %s." -#: utils/fmgr/dfmgr.c:338 +#: utils/fmgr/dfmgr.c:346 #, c-format msgid "Server has FUNC_MAX_ARGS = %d, library has %d." msgstr "El servidor tiene FUNC_MAX_ARGS = %d, la librería tiene %d" -#: utils/fmgr/dfmgr.c:347 +#: utils/fmgr/dfmgr.c:355 #, c-format msgid "Server has INDEX_MAX_KEYS = %d, library has %d." msgstr "El servidor tiene INDEX_MAX_KEYS = %d, la librería tiene %d" -#: utils/fmgr/dfmgr.c:356 +#: utils/fmgr/dfmgr.c:364 #, c-format msgid "Server has NAMEDATALEN = %d, library has %d." msgstr "El servidor tiene NAMEDATALEN = %d, la librería tiene %d" -#: utils/fmgr/dfmgr.c:365 +#: utils/fmgr/dfmgr.c:373 #, c-format msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." msgstr "El servidor tiene FLOAT4PASSBYVAL = %s, la librería tiene %s" -#: utils/fmgr/dfmgr.c:374 +#: utils/fmgr/dfmgr.c:382 #, c-format msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." msgstr "El servidor tiene FLOAT8PASSBYVAL = %s, la librería tiene %s" -#: utils/fmgr/dfmgr.c:381 +#: utils/fmgr/dfmgr.c:389 msgid "Magic block has unexpected length or padding difference." msgstr "El bloque mágico tiene un largo inesperado, o una diferencia de relleno." -#: utils/fmgr/dfmgr.c:384 +#: utils/fmgr/dfmgr.c:392 #, c-format msgid "incompatible library \"%s\": magic block mismatch" msgstr "biblioteca «%s» incompatible: bloque mágico no coincide" -#: utils/fmgr/dfmgr.c:548 +#: utils/fmgr/dfmgr.c:556 #, c-format msgid "access to library \"%s\" is not allowed" msgstr "no está permitido el acceso a la biblioteca «%s»" -#: utils/fmgr/dfmgr.c:574 +#: utils/fmgr/dfmgr.c:582 #, c-format msgid "invalid macro name in dynamic library path: %s" msgstr "el nombre de macro no es válido en la ruta a biblioteca dinámica: %s" -#: utils/fmgr/dfmgr.c:614 +#: utils/fmgr/dfmgr.c:622 #, c-format msgid "zero-length component in parameter \"dynamic_library_path\"" msgstr "se encontró componente de largo cero en el parámetro «dynamic_library_path»" -#: utils/fmgr/dfmgr.c:633 +#: utils/fmgr/dfmgr.c:641 #, c-format msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "un componente en el parámetro «dynamic_library_path» no es una ruta absoluta" -#: utils/fmgr/fmgr.c:239 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "la función interna «%s» no está en la tabla interna de búsqueda" -#: utils/fmgr/fmgr.c:399 -#, fuzzy, c-format +#: utils/fmgr/fmgr.c:485 +#, c-format msgid "could not find function information for function \"%s\"" -msgstr "no se encuentra la función «%s» en el archivo «%s»" +msgstr "no se pudo encontrar información de función para la función «%s»" -#: utils/fmgr/fmgr.c:401 +#: utils/fmgr/fmgr.c:487 #, c-format msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." -msgstr "" +msgstr "Funciones invocables desde SQL necesitan PG_FUNCTION_INFO_V1(función) que los acompañe." -#: utils/fmgr/fmgr.c:419 +#: utils/fmgr/fmgr.c:505 #, c-format msgid "unrecognized API version %d reported by info function \"%s\"" msgstr "la versión de API %d no reconocida fue reportada por la función «%s»" -#: utils/fmgr/fmgr.c:2132 +#: utils/fmgr/fmgr.c:2032 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "función de validación de lenguaje %u invocada para el lenguaje %u en lugar de %u" -#: utils/fmgr/funcapi.c:354 +#: utils/fmgr/funcapi.c:343 #, c-format msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "no se pudo determinar el tipo verdadero de resultado para la función «%s» declarada retornando tipo %s" -#: utils/fmgr/funcapi.c:1341 utils/fmgr/funcapi.c:1372 +#: utils/fmgr/funcapi.c:1388 utils/fmgr/funcapi.c:1420 #, c-format msgid "number of aliases does not match number of columns" -msgstr "el número de aliases no calza con el número de columnas" +msgstr "el número de aliases no coincide con el número de columnas" -#: utils/fmgr/funcapi.c:1366 +#: utils/fmgr/funcapi.c:1414 #, c-format msgid "no column alias was provided" msgstr "no se entregó alias de columna" -#: utils/fmgr/funcapi.c:1390 +#: utils/fmgr/funcapi.c:1438 #, c-format msgid "could not determine row description for function returning record" msgstr "no se pudo encontrar descripción de registro de función que retorna record" -#: utils/init/miscinit.c:123 +#: utils/init/miscinit.c:110 #, c-format -msgid "could not change directory to \"%s\": %m" -msgstr "no se pudo cambiar al directorio «%s»: %m" +msgid "data directory \"%s\" does not exist" +msgstr "no existe el directorio de datos «%s»" -#: utils/init/miscinit.c:451 utils/misc/guc.c:6115 +#: utils/init/miscinit.c:115 #, c-format -msgid "cannot set parameter \"%s\" within security-restricted operation" -msgstr "no se puede definir el parámetro «%s» dentro de una operación restringida por seguridad" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" -#: utils/init/miscinit.c:512 +#: utils/init/miscinit.c:123 #, c-format -msgid "role with OID %u does not exist" -msgstr "no existe el rol con OID %u" - -#: utils/init/miscinit.c:542 +msgid "specified data directory \"%s\" is not a directory" +msgstr "el directorio de datos especificado «%s» no es un directorio" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "el directorio de datos «%s» tiene dueño equivocado" + +#: utils/init/miscinit.c:141 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "El servidor debe ser iniciado por el usuario dueño del directorio de datos." + +#: utils/init/miscinit.c:159 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "el directorio de datos «%s» tiene permisos no válidos" + +#: utils/init/miscinit.c:161 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Los permisos deberían ser u=rwx (0700) o u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:547 utils/misc/guc.c:6944 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "no se puede definir el parámetro «%s» dentro de una operación restringida por seguridad" + +#: utils/init/miscinit.c:615 +#, c-format +msgid "role with OID %u does not exist" +msgstr "no existe el rol con OID %u" + +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "al rol «%s» no se le permite conectarse" -#: utils/init/miscinit.c:560 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "demasiadas conexiones para el rol «%s»" -#: utils/init/miscinit.c:620 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "se ha denegado el permiso para cambiar el usuario actual" -#: utils/init/miscinit.c:703 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "el OID de rol no es válido: %u" -#: utils/init/miscinit.c:757 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "el sistema de bases de datos está apagado" -#: utils/init/miscinit.c:844 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "no se pudo crear el archivo de bloqueo «%s»: %m" -#: utils/init/miscinit.c:858 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "no se pudo abrir el archivo de bloqueo «%s»: %m" -#: utils/init/miscinit.c:865 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "no se pudo leer el archivo de bloqueo «%s»: %m" -#: utils/init/miscinit.c:874 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "el archivo de bloqueo «%s» está vacío" -#: utils/init/miscinit.c:875 +#: utils/init/miscinit.c:978 #, c-format msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." msgstr "Otro proceso servidor está iniciándose, o el archivo de bloqueo es remanente de una caída durante un inicio anterior." -#: utils/init/miscinit.c:922 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "el archivo de bloqueo «%s» ya existe" -#: utils/init/miscinit.c:926 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "¿Hay otro postgres (PID %d) corriendo en el directorio de datos «%s»?" -#: utils/init/miscinit.c:928 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "¿Hay otro postmaster (PID %d) corriendo en el directorio de datos «%s»?" -#: utils/init/miscinit.c:931 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "¿Hay otro postgres (PID %d) usando el socket «%s»?" -#: utils/init/miscinit.c:933 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "¿Hay otro postmaster (PID %d) usando el socket «%s»?" -#: utils/init/miscinit.c:969 -#, c-format -msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" -msgstr "el bloque de memoria compartida preexistente (clave %lu, ID %lu) aún está en uso" - -#: utils/init/miscinit.c:972 -#, c-format -msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." -msgstr "Si está seguro que no hay procesos de servidor antiguos aún en ejecución, elimine el bloque de memoria compartida, o simplemente borre el archivo «%s»." - -#: utils/init/miscinit.c:988 +#: utils/init/miscinit.c:1084 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "no se pudo eliminar el archivo de bloqueo antiguo «%s»: %m" -#: utils/init/miscinit.c:990 +#: utils/init/miscinit.c:1086 #, c-format msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "El archivo parece accidentalmente abandonado, pero no pudo ser eliminado. Por favor elimine el archivo manualmente e intente nuevamente." -#: utils/init/miscinit.c:1027 utils/init/miscinit.c:1041 -#: utils/init/miscinit.c:1052 +#: utils/init/miscinit.c:1123 utils/init/miscinit.c:1137 +#: utils/init/miscinit.c:1148 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "no se pudo escribir el archivo de bloqueo «%s»: %m" -#: utils/init/miscinit.c:1184 utils/init/miscinit.c:1327 utils/misc/guc.c:8920 +#: utils/init/miscinit.c:1280 utils/init/miscinit.c:1423 utils/misc/guc.c:9851 #, c-format msgid "could not read from file \"%s\": %m" msgstr "no se pudo leer el archivo «%s»: %m" -#: utils/init/miscinit.c:1315 +#: utils/init/miscinit.c:1411 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "no se pudo abrir el archivo «%s»: %m; continuando de todas formas" -#: utils/init/miscinit.c:1340 +#: utils/init/miscinit.c:1436 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "el archivo de bloqueo «%s» tiene un PID erróneo: %ld en lugar de %ld" -#: utils/init/miscinit.c:1379 utils/init/miscinit.c:1395 +#: utils/init/miscinit.c:1475 utils/init/miscinit.c:1491 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "«%s» no es un directorio de datos válido" -#: utils/init/miscinit.c:1381 +#: utils/init/miscinit.c:1477 #, c-format msgid "File \"%s\" is missing." msgstr "Falta el archivo «%s»." -#: utils/init/miscinit.c:1397 +#: utils/init/miscinit.c:1493 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "El archivo «%s» no contiene datos válidos." -#: utils/init/miscinit.c:1399 +#: utils/init/miscinit.c:1495 #, c-format msgid "You might need to initdb." msgstr "Puede ser necesario ejecutar initdb." -#: utils/init/miscinit.c:1407 -#, fuzzy, c-format +#: utils/init/miscinit.c:1503 +#, c-format msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." -msgstr "El directorio de datos fue inicializado por PostgreSQL versión %ld.%ld, que no es compatible con esta versión %s." +msgstr "El directorio de datos fue inicializado por PostgreSQL versión %s, que no es compatible con esta versión %s." -#: utils/init/miscinit.c:1474 +#: utils/init/miscinit.c:1570 #, c-format msgid "loaded library \"%s\"" msgstr "biblioteca «%s» cargada" -#: utils/init/postinit.c:251 +#: utils/init/postinit.c:255 #, c-format -msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "conexión de replicación autorizada: usuario=%s SSL activo (protocolo=%s, cifrado=%s, compresión=%s)" +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "conexión de replicación autorizada: usuario=%s application_name=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 msgid "off" msgstr "desactivado" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 msgid "on" msgstr "activado" -#: utils/init/postinit.c:257 +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "conexión de replicación autorizada: usuario=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "conexión de replicación autorizada: usuario=%s application_name=%s" + +#: utils/init/postinit.c:275 #, c-format msgid "replication connection authorized: user=%s" msgstr "conexión de replicación autorizada: usuario=%s" -#: utils/init/postinit.c:265 +#: utils/init/postinit.c:284 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "conexión autorizada: usuario=%s base_de_datos=%s application_name=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s)" + +#: utils/init/postinit.c:290 #, c-format -msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "conexión autorizada: usuario=%s database=%s SSL activo (protocolo=%s, cifrado=%s, compresión=%s)" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "conexión autorizada: usuario=%s base de datos=%s SSL activo (protocolo=%s, cifrado=%s, bits=%d, compresión=%s" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "conexión autorizada: usuario=%s base de datos=%s application_name=%s" + +#: utils/init/postinit.c:302 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "conexión autorizada: usuario=%s database=%s" -#: utils/init/postinit.c:303 +#: utils/init/postinit.c:334 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "la base de datos «%s» ha desaparecido de pg_database" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:336 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "Base de datos con OID %u ahora parece pertenecer a «%s»." -#: utils/init/postinit.c:325 +#: utils/init/postinit.c:356 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "la base de datos «%s» no acepta conexiones" -#: utils/init/postinit.c:338 +#: utils/init/postinit.c:369 #, c-format msgid "permission denied for database \"%s\"" msgstr "permiso denegado a la base de datos «%s»" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:370 #, c-format msgid "User does not have CONNECT privilege." msgstr "Usuario no tiene privilegios de conexión." -#: utils/init/postinit.c:356 +#: utils/init/postinit.c:387 #, c-format msgid "too many connections for database \"%s\"" msgstr "demasiadas conexiones para la base de datos «%s»" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#: utils/init/postinit.c:409 utils/init/postinit.c:416 #, c-format msgid "database locale is incompatible with operating system" msgstr "la configuración regional es incompatible con el sistema operativo" -#: utils/init/postinit.c:379 +#: utils/init/postinit.c:410 #, c-format msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." msgstr "La base de datos fue inicializada con LC_COLLATE «%s», el cual no es reconocido por setlocale()." -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#: utils/init/postinit.c:412 utils/init/postinit.c:419 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "Recree la base de datos con otra configuración regional, o instale la configuración regional faltante." -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:417 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "La base de datos fueron inicializada con LC_CTYPE «%s», el cual no es reconocido por setlocale()." -#: utils/init/postinit.c:719 +#: utils/init/postinit.c:764 #, c-format msgid "no roles are defined in this database system" msgstr "no hay roles definidos en esta base de datos" -#: utils/init/postinit.c:720 +#: utils/init/postinit.c:765 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Debería ejecutar imediatamente CREATE USER \"%s\" SUPERUSER;." -#: utils/init/postinit.c:756 +#: utils/init/postinit.c:801 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "nuevas conexiones de replicación no son permitidas durante el apagado de la base de datos" -#: utils/init/postinit.c:760 +#: utils/init/postinit.c:805 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "debe ser superusuario para conectarse durante el apagado de la base de datos" -#: utils/init/postinit.c:770 +#: utils/init/postinit.c:815 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "debe ser superusuario para conectarse en modo de actualización binaria" -#: utils/init/postinit.c:784 +#: utils/init/postinit.c:828 #, c-format msgid "remaining connection slots are reserved for non-replication superuser connections" msgstr "las conexiones restantes están reservadas a superusuarios y no de replicación" -#: utils/init/postinit.c:794 +#: utils/init/postinit.c:838 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "debe ser superusuario o rol de replicación para iniciar el walsender" -#: utils/init/postinit.c:863 +#: utils/init/postinit.c:907 #, c-format msgid "database %u does not exist" msgstr "no existe la base de datos %u" -#: utils/init/postinit.c:952 +#: utils/init/postinit.c:996 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Parece haber sido eliminada o renombrada." -#: utils/init/postinit.c:970 +#: utils/init/postinit.c:1014 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "Falta el subdirectorio de base de datos «%s»." -#: utils/init/postinit.c:975 +#: utils/init/postinit.c:1019 #, c-format msgid "could not access directory \"%s\": %m" msgstr "no se pudo acceder al directorio «%s»: %m" @@ -23071,1622 +23798,1848 @@ msgid "unexpected encoding ID %d for WIN character sets" msgstr "ID de codificación %d inesperado para juegos de caracteres WIN" #: utils/mb/encnames.c:473 -#, fuzzy, c-format +#, c-format msgid "encoding \"%s\" not supported by ICU" -msgstr "las unidades de interval «%s» no están soportadas" +msgstr "la codificación «%s» no estæ soportada por ICU" #: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "el nombre de codificación es demasiado largo" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "la conversión entre %s y %s no está soportada" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "no existe el procedimiento por omisión de conversión desde la codificación «%s» a «%s»" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "La cadena de %d bytes es demasiado larga para la recodificación." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "la codificación de origen «%s» no es válida" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "la codificación de destino «%s» no es válida" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "byte no válido para codificación «%s»: 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "bind_textdomain_codeset falló" -#: utils/mb/wchar.c:2015 +#: utils/mb/wchar.c:2033 #, c-format msgid "invalid byte sequence for encoding \"%s\": %s" msgstr "secuencia de bytes no válida para codificación «%s»: %s" -#: utils/mb/wchar.c:2048 +#: utils/mb/wchar.c:2066 #, c-format msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" msgstr "carácter con secuencia de bytes %s en codificación «%s» no tiene equivalente en la codificación «%s»" -#: utils/misc/guc.c:570 +#: utils/misc/guc.c:636 msgid "Ungrouped" msgstr "Sin Grupo" -#: utils/misc/guc.c:572 +#: utils/misc/guc.c:638 msgid "File Locations" msgstr "Ubicaciones de Archivos" -#: utils/misc/guc.c:574 +#: utils/misc/guc.c:640 msgid "Connections and Authentication" msgstr "Conexiones y Autentificación" -#: utils/misc/guc.c:576 +#: utils/misc/guc.c:642 msgid "Connections and Authentication / Connection Settings" msgstr "Conexiones y Autentificación / Parámetros de Conexión" -#: utils/misc/guc.c:578 -msgid "Connections and Authentication / Security and Authentication" -msgstr "Conexiones y Autentificación / Seguridad y Autentificación" +#: utils/misc/guc.c:644 +msgid "Connections and Authentication / Authentication" +msgstr "Conexiones y Autentificación / Autentificación" + +#: utils/misc/guc.c:646 +msgid "Connections and Authentication / SSL" +msgstr "Conexiones y Autentificación / SSL" -#: utils/misc/guc.c:580 +#: utils/misc/guc.c:648 msgid "Resource Usage" msgstr "Uso de Recursos" -#: utils/misc/guc.c:582 +#: utils/misc/guc.c:650 msgid "Resource Usage / Memory" msgstr "Uso de Recursos / Memoria" -#: utils/misc/guc.c:584 +#: utils/misc/guc.c:652 msgid "Resource Usage / Disk" msgstr "Uso de Recursos / Disco" -#: utils/misc/guc.c:586 +#: utils/misc/guc.c:654 msgid "Resource Usage / Kernel Resources" msgstr "Uso de Recursos / Recursos del Kernel" -#: utils/misc/guc.c:588 +#: utils/misc/guc.c:656 msgid "Resource Usage / Cost-Based Vacuum Delay" msgstr "Uso de Recursos / Retardo de Vacuum por Costos" -#: utils/misc/guc.c:590 +#: utils/misc/guc.c:658 msgid "Resource Usage / Background Writer" msgstr "Uso de Recursos / Escritor en Segundo Plano" -#: utils/misc/guc.c:592 +#: utils/misc/guc.c:660 msgid "Resource Usage / Asynchronous Behavior" msgstr "Uso de Recursos / Comportamiento Asíncrono" -#: utils/misc/guc.c:594 +#: utils/misc/guc.c:662 msgid "Write-Ahead Log" msgstr "Write-Ahead Log" -#: utils/misc/guc.c:596 +#: utils/misc/guc.c:664 msgid "Write-Ahead Log / Settings" msgstr "Write-Ahead Log / Configuraciones" -#: utils/misc/guc.c:598 +#: utils/misc/guc.c:666 msgid "Write-Ahead Log / Checkpoints" msgstr "Write-Ahead Log / Puntos de Control (Checkpoints)" -#: utils/misc/guc.c:600 +#: utils/misc/guc.c:668 msgid "Write-Ahead Log / Archiving" msgstr "Write-Ahead Log / Archivado" -#: utils/misc/guc.c:602 +#: utils/misc/guc.c:670 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead Log / Recuperación desde Archivo" + +#: utils/misc/guc.c:672 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead Log / Destino de Recuperación" + +#: utils/misc/guc.c:674 msgid "Replication" msgstr "Replicación" -#: utils/misc/guc.c:604 +#: utils/misc/guc.c:676 msgid "Replication / Sending Servers" msgstr "Replicación / Servidores de Envío" -#: utils/misc/guc.c:606 +#: utils/misc/guc.c:678 msgid "Replication / Master Server" msgstr "Replicación / Servidor Maestro" -#: utils/misc/guc.c:608 +#: utils/misc/guc.c:680 msgid "Replication / Standby Servers" msgstr "Replicación / Servidores Standby" -#: utils/misc/guc.c:610 -#, fuzzy +#: utils/misc/guc.c:682 msgid "Replication / Subscribers" -msgstr "Replicación / Servidores Standby" +msgstr "Replicación / Suscriptores" -#: utils/misc/guc.c:612 +#: utils/misc/guc.c:684 msgid "Query Tuning" msgstr "Afinamiento de Consultas" -#: utils/misc/guc.c:614 +#: utils/misc/guc.c:686 msgid "Query Tuning / Planner Method Configuration" msgstr "Afinamiento de Consultas / Configuración de Métodos del Planner" -#: utils/misc/guc.c:616 +#: utils/misc/guc.c:688 msgid "Query Tuning / Planner Cost Constants" msgstr "Afinamiento de Consultas / Constantes de Costo del Planner" -#: utils/misc/guc.c:618 +#: utils/misc/guc.c:690 msgid "Query Tuning / Genetic Query Optimizer" msgstr "Afinamiento de Consultas / Optimizador Genético de Consultas" -#: utils/misc/guc.c:620 +#: utils/misc/guc.c:692 msgid "Query Tuning / Other Planner Options" msgstr "Afinamiento de Consultas / Otras Opciones del Planner" -#: utils/misc/guc.c:622 +#: utils/misc/guc.c:694 msgid "Reporting and Logging" msgstr "Reporte y Registro" -#: utils/misc/guc.c:624 +#: utils/misc/guc.c:696 msgid "Reporting and Logging / Where to Log" msgstr "Reporte y Registro / Cuándo Registrar" -#: utils/misc/guc.c:626 +#: utils/misc/guc.c:698 msgid "Reporting and Logging / When to Log" msgstr "Reporte y Registro / Cuándo Registrar" -#: utils/misc/guc.c:628 +#: utils/misc/guc.c:700 msgid "Reporting and Logging / What to Log" msgstr "Reporte y Registro / Qué Registrar" -#: utils/misc/guc.c:630 +#: utils/misc/guc.c:702 msgid "Process Title" msgstr "Título de Proceso" -#: utils/misc/guc.c:632 +#: utils/misc/guc.c:704 msgid "Statistics" msgstr "Estadísticas" -#: utils/misc/guc.c:634 +#: utils/misc/guc.c:706 msgid "Statistics / Monitoring" msgstr "Estadísticas / Monitoreo" -#: utils/misc/guc.c:636 +#: utils/misc/guc.c:708 msgid "Statistics / Query and Index Statistics Collector" msgstr "Estadísticas / Recolector de Estadísticas de Consultas e Ãndices" -#: utils/misc/guc.c:638 +#: utils/misc/guc.c:710 msgid "Autovacuum" msgstr "Autovacuum" -#: utils/misc/guc.c:640 +#: utils/misc/guc.c:712 msgid "Client Connection Defaults" msgstr "Valores por Omisión de Conexiones" -#: utils/misc/guc.c:642 +#: utils/misc/guc.c:714 msgid "Client Connection Defaults / Statement Behavior" msgstr "Valores por Omisión de Conexiones / Comportamiento de Sentencias" -#: utils/misc/guc.c:644 +#: utils/misc/guc.c:716 msgid "Client Connection Defaults / Locale and Formatting" msgstr "Valores por Omisión de Conexiones / Configuraciones Regionales y Formateo" -#: utils/misc/guc.c:646 +#: utils/misc/guc.c:718 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "Valores por Omisión de Conexiones / Precargado de Bibliotecas Compartidas" -#: utils/misc/guc.c:648 +#: utils/misc/guc.c:720 msgid "Client Connection Defaults / Other Defaults" msgstr "Valores por Omisión de Conexiones / Otros Valores" -#: utils/misc/guc.c:650 +#: utils/misc/guc.c:722 msgid "Lock Management" msgstr "Manejo de Bloqueos" -#: utils/misc/guc.c:652 +#: utils/misc/guc.c:724 msgid "Version and Platform Compatibility" msgstr "Compatibilidad de Versión y Plataforma" -#: utils/misc/guc.c:654 +#: utils/misc/guc.c:726 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "Compatibilidad de Versión y Plataforma / Versiones Anteriores de PostgreSQL" -#: utils/misc/guc.c:656 +#: utils/misc/guc.c:728 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "Compatibilidad de Versión y Plataforma / Otras Plataformas y Clientes" -#: utils/misc/guc.c:658 +#: utils/misc/guc.c:730 msgid "Error Handling" msgstr "Gestión de Errores" -#: utils/misc/guc.c:660 +#: utils/misc/guc.c:732 msgid "Preset Options" msgstr "Opciones Predefinidas" -#: utils/misc/guc.c:662 +#: utils/misc/guc.c:734 msgid "Customized Options" msgstr "Opciones Personalizadas" -#: utils/misc/guc.c:664 +#: utils/misc/guc.c:736 msgid "Developer Options" msgstr "Opciones de Desarrollador" -#: utils/misc/guc.c:721 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "Unidades válidas para este parámetro son «kB», «MB», «GB» y «TB»." +#: utils/misc/guc.c:788 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Unidades válidas para este parámetro son «B», «kB», «MB», «GB» y «TB»." -#: utils/misc/guc.c:748 -msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." -msgstr "Unidades válidas para este parámetro son «ms», «s», «min», «h» y «d»." +#: utils/misc/guc.c:825 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Unidades válidas son para este parámetro son «us», «ms», «s», «min», «h» y «d»." -#: utils/misc/guc.c:807 +#: utils/misc/guc.c:887 msgid "Enables the planner's use of sequential-scan plans." msgstr "Permitir el uso de planes de recorrido secuencial." -#: utils/misc/guc.c:816 +#: utils/misc/guc.c:897 msgid "Enables the planner's use of index-scan plans." msgstr "Permitir el uso de planes de recorrido de índice." -#: utils/misc/guc.c:825 +#: utils/misc/guc.c:907 msgid "Enables the planner's use of index-only-scan plans." msgstr "Permitir el uso de planes de recorrido de sólo-índice." -#: utils/misc/guc.c:834 +#: utils/misc/guc.c:917 msgid "Enables the planner's use of bitmap-scan plans." msgstr "Permitir el uso de planes de recorrido de índice por mapas de bits." -#: utils/misc/guc.c:843 +#: utils/misc/guc.c:927 msgid "Enables the planner's use of TID scan plans." msgstr "Permitir el uso de planes de recorrido por TID." -#: utils/misc/guc.c:852 +#: utils/misc/guc.c:937 msgid "Enables the planner's use of explicit sort steps." msgstr "Permitir el uso de pasos explícitos de ordenamiento." -#: utils/misc/guc.c:861 +#: utils/misc/guc.c:947 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Permitir el uso de planes de agregación a través de hash." -#: utils/misc/guc.c:870 +#: utils/misc/guc.c:957 msgid "Enables the planner's use of materialization." msgstr "Permitir el uso de materialización de planes." -#: utils/misc/guc.c:879 +#: utils/misc/guc.c:967 msgid "Enables the planner's use of nested-loop join plans." msgstr "Permitir el uso de planes «nested-loop join»." -#: utils/misc/guc.c:888 +#: utils/misc/guc.c:977 msgid "Enables the planner's use of merge join plans." msgstr "Permitir el uso de planes «merge join»." -#: utils/misc/guc.c:897 +#: utils/misc/guc.c:987 msgid "Enables the planner's use of hash join plans." msgstr "Permitir el uso de planes «hash join»." -#: utils/misc/guc.c:906 -#, fuzzy +#: utils/misc/guc.c:997 msgid "Enables the planner's use of gather merge plans." -msgstr "Permitir el uso de planes «merge join»." +msgstr "Permitir el uso de planes «gather merge»." + +#: utils/misc/guc.c:1007 +msgid "Enables partitionwise join." +msgstr "Permitir el uso de joins por particiones." + +#: utils/misc/guc.c:1017 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Permitir el uso de agregación y agrupamiento por particiones." + +#: utils/misc/guc.c:1027 +msgid "Enables the planner's use of parallel append plans." +msgstr "Permitir el uso de planes «append» paralelos." + +#: utils/misc/guc.c:1037 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Permitir el uso de planes «hash join» paralelos." -#: utils/misc/guc.c:916 +#: utils/misc/guc.c:1047 +msgid "Enable plan-time and run-time partition pruning." +msgstr "Permitir el uso de poda de particiones en tiempo de plan y ejecución." + +#: utils/misc/guc.c:1048 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Permite al optimizador de consultas y al ejecutor a comparar bordes de particiones a condiciones en las consultas para determinar qué particiones deben recorrerse." + +#: utils/misc/guc.c:1059 msgid "Enables genetic query optimization." msgstr "Permitir el uso del optimizador genético de consultas." -#: utils/misc/guc.c:917 +#: utils/misc/guc.c:1060 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Este algoritmo intenta planear las consultas sin hacer búsqueda exhaustiva." -#: utils/misc/guc.c:927 +#: utils/misc/guc.c:1071 msgid "Shows whether the current user is a superuser." msgstr "Indica si el usuario actual es superusuario." -#: utils/misc/guc.c:937 +#: utils/misc/guc.c:1081 msgid "Enables advertising the server via Bonjour." msgstr "Permitir la publicación del servidor vía Bonjour." -#: utils/misc/guc.c:946 +#: utils/misc/guc.c:1090 msgid "Collects transaction commit time." msgstr "Recolectar tiempo de compromiso de transacciones." -#: utils/misc/guc.c:955 +#: utils/misc/guc.c:1099 msgid "Enables SSL connections." msgstr "Permitir conexiones SSL." -#: utils/misc/guc.c:964 +#: utils/misc/guc.c:1108 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "También usar ssl_passphrase_command durante la recarga del servidor." + +#: utils/misc/guc.c:1117 msgid "Give priority to server ciphersuite order." msgstr "Da prioridad al orden de algoritmos de cifrado especificado por el servidor." -#: utils/misc/guc.c:973 +#: utils/misc/guc.c:1126 msgid "Forces synchronization of updates to disk." msgstr "Forzar la sincronización de escrituras a disco." -#: utils/misc/guc.c:974 +#: utils/misc/guc.c:1127 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." msgstr "El servidor usará la llamada a sistema fsync() en varios lugares para asegurarse que las actualizaciones son escritas físicamente a disco. Esto asegura que las bases de datos se recuperarán a un estado consistente después de una caída de hardware o sistema operativo." -#: utils/misc/guc.c:985 +#: utils/misc/guc.c:1138 msgid "Continues processing after a checksum failure." msgstr "Continuar procesando después de una falla de suma de verificación." -#: utils/misc/guc.c:986 +#: utils/misc/guc.c:1139 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." msgstr "La detección de una suma de verificación que no coincide normalmente hace que PostgreSQL reporte un error, abortando la transacción en curso. Definiendo ignore_checksum_failure a true hace que el sistema ignore la falla (pero aún así reporta un mensaje de warning), y continúe el procesamiento. Este comportamiento podría causar caídas del sistema u otros problemas serios. Sólo tiene efecto si las sumas de verificación están activadas." -#: utils/misc/guc.c:1000 +#: utils/misc/guc.c:1153 msgid "Continues processing past damaged page headers." msgstr "Continuar procesando después de detectar encabezados de página dañados." -#: utils/misc/guc.c:1001 +#: utils/misc/guc.c:1154 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "La detección de un encabezado de página dañado normalmente hace que PostgreSQL reporte un error, abortando la transacción en curso. Definiendo zero_damaged_pages a true hace que el sistema reporte un mensaje de warning, escriba ceros en toda la página, y continúe el procesamiento. Este comportamiento destruirá datos; en particular, todas las tuplas en la página dañada." -#: utils/misc/guc.c:1014 +#: utils/misc/guc.c:1167 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "Escribe páginas completas a WAL cuando son modificadas después de un punto de control." -#: utils/misc/guc.c:1015 +#: utils/misc/guc.c:1168 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." msgstr "Una escritura de página que está siendo procesada durante una caída del sistema operativo puede ser completada sólo parcialmente. Durante la recuperación, los cambios de registros (tuplas) almacenados en WAL no son suficientes para la recuperación. Esta opción activa la escritura de las páginas a WAL cuando son modificadas por primera vez después de un punto de control, de manera que una recuperación total es posible." -#: utils/misc/guc.c:1028 +#: utils/misc/guc.c:1181 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." msgstr "Escribir páginas completas a WAL cuando son modificadas después de un punto de control, incluso para modificaciones no críticas." -#: utils/misc/guc.c:1038 +#: utils/misc/guc.c:1191 msgid "Compresses full-page writes written in WAL file." msgstr "Comprimir las imágenes de páginas completas al escribirlas a WAL." -#: utils/misc/guc.c:1048 +#: utils/misc/guc.c:1201 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Escribir ceros a nuevos archivos WAL antes del primer uso." + +#: utils/misc/guc.c:1211 +msgid "Recycles WAL files by renaming them." +msgstr "Reciclar archivos de WAL cambiándoles de nombre." + +#: utils/misc/guc.c:1221 msgid "Logs each checkpoint." msgstr "Registrar cada punto de control." -#: utils/misc/guc.c:1057 +#: utils/misc/guc.c:1230 msgid "Logs each successful connection." msgstr "Registrar cada conexión exitosa." -#: utils/misc/guc.c:1066 +#: utils/misc/guc.c:1239 msgid "Logs end of a session, including duration." msgstr "Registrar el fin de una sesión, incluyendo su duración." -#: utils/misc/guc.c:1075 +#: utils/misc/guc.c:1248 msgid "Logs each replication command." msgstr "Registrar cada orden de replicación." -#: utils/misc/guc.c:1084 +#: utils/misc/guc.c:1257 msgid "Shows whether the running server has assertion checks enabled." msgstr "Indica si el servidor actual tiene activas las aseveraciones (asserts) activas." -#: utils/misc/guc.c:1099 +#: utils/misc/guc.c:1272 msgid "Terminate session on any error." msgstr "Terminar sesión ante cualquier error." -#: utils/misc/guc.c:1108 +#: utils/misc/guc.c:1281 msgid "Reinitialize server after backend crash." msgstr "Reinicializar el servidor después de una caída de un proceso servidor." -#: utils/misc/guc.c:1118 +#: utils/misc/guc.c:1291 msgid "Logs the duration of each completed SQL statement." msgstr "Registrar la duración de cada sentencia SQL ejecutada." -#: utils/misc/guc.c:1127 +#: utils/misc/guc.c:1300 msgid "Logs each query's parse tree." msgstr "Registrar cada arbol analizado de consulta " -#: utils/misc/guc.c:1136 +#: utils/misc/guc.c:1309 msgid "Logs each query's rewritten parse tree." msgstr "Registrar cada reescritura del arból analizado de consulta" -#: utils/misc/guc.c:1145 +#: utils/misc/guc.c:1318 msgid "Logs each query's execution plan." msgstr "Registrar el plan de ejecución de cada consulta." -#: utils/misc/guc.c:1154 +#: utils/misc/guc.c:1327 msgid "Indents parse and plan tree displays." msgstr "Indentar los árboles de parse y plan." -#: utils/misc/guc.c:1163 +#: utils/misc/guc.c:1336 msgid "Writes parser performance statistics to the server log." msgstr "Escribir estadísticas de parser al registro del servidor." -#: utils/misc/guc.c:1172 +#: utils/misc/guc.c:1345 msgid "Writes planner performance statistics to the server log." msgstr "Escribir estadísticas de planner al registro del servidor." -#: utils/misc/guc.c:1181 +#: utils/misc/guc.c:1354 msgid "Writes executor performance statistics to the server log." msgstr "Escribir estadísticas del executor al registro del servidor." -#: utils/misc/guc.c:1190 +#: utils/misc/guc.c:1363 msgid "Writes cumulative performance statistics to the server log." msgstr "Escribir estadísticas acumulativas al registro del servidor." -#: utils/misc/guc.c:1200 +#: utils/misc/guc.c:1373 msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "Registrar uso de recursos de sistema (memoria y CPU) en varias operaciones B-tree." -#: utils/misc/guc.c:1212 +#: utils/misc/guc.c:1385 msgid "Collects information about executing commands." msgstr "Recolectar estadísticas sobre órdenes en ejecución." -#: utils/misc/guc.c:1213 +#: utils/misc/guc.c:1386 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "Activa la recolección de información sobre la orden actualmente en ejecución en cada sesión, junto con el momento en el cual esa orden comenzó la ejecución." -#: utils/misc/guc.c:1223 +#: utils/misc/guc.c:1396 msgid "Collects statistics on database activity." msgstr "Recolectar estadísticas de actividad de la base de datos." -#: utils/misc/guc.c:1232 +#: utils/misc/guc.c:1405 msgid "Collects timing statistics for database I/O activity." msgstr "Recolectar estadísticas de tiempos en las operaciones de I/O de la base de datos." -#: utils/misc/guc.c:1242 +#: utils/misc/guc.c:1415 msgid "Updates the process title to show the active SQL command." msgstr "Actualiza el título del proceso para mostrar la orden SQL activo." -#: utils/misc/guc.c:1243 +#: utils/misc/guc.c:1416 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "Habilita que se actualice el título del proceso cada vez que una orden SQL es recibido por el servidor." -#: utils/misc/guc.c:1256 +#: utils/misc/guc.c:1429 msgid "Starts the autovacuum subprocess." msgstr "Iniciar el subproceso de autovacuum." -#: utils/misc/guc.c:1266 +#: utils/misc/guc.c:1439 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Generar salida de depuración para LISTEN y NOTIFY." -#: utils/misc/guc.c:1278 +#: utils/misc/guc.c:1451 msgid "Emits information about lock usage." msgstr "Emitir información acerca del uso de locks." -#: utils/misc/guc.c:1288 +#: utils/misc/guc.c:1461 msgid "Emits information about user lock usage." msgstr "Emitir información acerca del uso de locks de usuario." -#: utils/misc/guc.c:1298 +#: utils/misc/guc.c:1471 msgid "Emits information about lightweight lock usage." msgstr "Emitir información acerca del uso de «lightweight locks»." -#: utils/misc/guc.c:1308 +#: utils/misc/guc.c:1481 msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "Volcar información acerca de los locks existentes cuando se agota el tiempo de deadlock." -#: utils/misc/guc.c:1320 +#: utils/misc/guc.c:1493 msgid "Logs long lock waits." msgstr "Registrar esperas largas de bloqueos." -#: utils/misc/guc.c:1330 +#: utils/misc/guc.c:1503 msgid "Logs the host name in the connection logs." msgstr "Registrar el nombre del host en la conexión." -#: utils/misc/guc.c:1331 +#: utils/misc/guc.c:1504 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." msgstr "Por omisión, los registros de conexión sólo muestran la dirección IP del host que establece la conexión. Si desea que se despliegue el nombre del host puede activar esta opción, pero dependiendo de su configuración de resolución de nombres esto puede imponer una penalización de rendimiento no despreciable." -#: utils/misc/guc.c:1342 +#: utils/misc/guc.c:1515 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Tratar expr=NULL como expr IS NULL." -#: utils/misc/guc.c:1343 +#: utils/misc/guc.c:1516 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "Cuando está activado, expresiones de la forma expr = NULL (o NULL = expr) son tratadas como expr IS NULL, esto es, retornarán verdadero si expr es evaluada al valor nulo, y falso en caso contrario. El comportamiento correcto de expr = NULL es retornar siempre null (desconocido)." -#: utils/misc/guc.c:1355 +#: utils/misc/guc.c:1528 msgid "Enables per-database user names." msgstr "Activar el uso de nombre de usuario locales a cada base de datos." -#: utils/misc/guc.c:1364 +#: utils/misc/guc.c:1537 msgid "Sets the default read-only status of new transactions." msgstr "Estado por omisión de sólo lectura de nuevas transacciones." -#: utils/misc/guc.c:1373 +#: utils/misc/guc.c:1546 msgid "Sets the current transaction's read-only status." msgstr "Activa el estado de sólo lectura de la transacción en curso." -#: utils/misc/guc.c:1383 +#: utils/misc/guc.c:1556 msgid "Sets the default deferrable status of new transactions." msgstr "Estado por omisión de postergable de nuevas transacciones." -#: utils/misc/guc.c:1392 +#: utils/misc/guc.c:1565 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "Si está activo, las transacciones serializables de sólo lectura serán pausadas hasta que puedan ejecutarse sin posibles fallas de serialización." -#: utils/misc/guc.c:1402 +#: utils/misc/guc.c:1575 msgid "Enable row security." msgstr "Activar seguridad de registros." -#: utils/misc/guc.c:1403 +#: utils/misc/guc.c:1576 msgid "When enabled, row security will be applied to all users." msgstr "Cuando está activada, la seguridad de registros se aplicará a todos los usuarios." -#: utils/misc/guc.c:1411 +#: utils/misc/guc.c:1584 msgid "Check function bodies during CREATE FUNCTION." msgstr "Verificar definición de funciones durante CREATE FUNCTION." -#: utils/misc/guc.c:1420 +#: utils/misc/guc.c:1593 msgid "Enable input of NULL elements in arrays." msgstr "Habilita el ingreso de elementos nulos en arrays." -#: utils/misc/guc.c:1421 +#: utils/misc/guc.c:1594 msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." msgstr "Cuando está activo, un valor NULL sin comillas en la entrada de un array significa un valor nulo; en caso contrario es tomado literalmente." -#: utils/misc/guc.c:1431 -msgid "Create new tables with OIDs by default." -msgstr "Crea nuevas tablas con OIDs por omisión." +#: utils/misc/guc.c:1610 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS ya no está soportado; esto sólo puede ser false." -#: utils/misc/guc.c:1440 +#: utils/misc/guc.c:1620 msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "Lanzar un subproceso para capturar stderr y/o logs CSV en archivos de log." -#: utils/misc/guc.c:1449 +#: utils/misc/guc.c:1629 msgid "Truncate existing log files of same name during log rotation." msgstr "Truncar archivos de log del mismo nombre durante la rotación." -#: utils/misc/guc.c:1460 +#: utils/misc/guc.c:1640 msgid "Emit information about resource usage in sorting." msgstr "Emitir información acerca de uso de recursos durante los ordenamientos." -#: utils/misc/guc.c:1474 +#: utils/misc/guc.c:1654 msgid "Generate debugging output for synchronized scanning." msgstr "Generar salida de depuración para recorrido sincronizado." -#: utils/misc/guc.c:1489 +#: utils/misc/guc.c:1669 msgid "Enable bounded sorting using heap sort." msgstr "Activar ordenamiento acotado usando «heap sort»." -#: utils/misc/guc.c:1502 +#: utils/misc/guc.c:1682 msgid "Emit WAL-related debugging output." msgstr "Activar salida de depuración de WAL." -#: utils/misc/guc.c:1514 +#: utils/misc/guc.c:1694 msgid "Datetimes are integer based." msgstr "Las fechas y horas se basan en tipos enteros." -#: utils/misc/guc.c:1525 +#: utils/misc/guc.c:1705 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "Define que los nombres de usuario Kerberos y GSSAPI deberían ser tratados sin distinción de mayúsculas." -#: utils/misc/guc.c:1535 +#: utils/misc/guc.c:1715 msgid "Warn about backslash escapes in ordinary string literals." msgstr "Avisa acerca de escapes de backslash en literales de cadena corrientes." -#: utils/misc/guc.c:1545 +#: utils/misc/guc.c:1725 msgid "Causes '...' strings to treat backslashes literally." msgstr "Provoca que las cadenas '...' traten las barras inclinadas inversas (\\) en forma literal." -#: utils/misc/guc.c:1556 +#: utils/misc/guc.c:1736 msgid "Enable synchronized sequential scans." msgstr "Permitir la sincronización de recorridos secuenciales." -#: utils/misc/guc.c:1566 +#: utils/misc/guc.c:1746 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Define si incluir o excluir la transacción con el destino de recuperación." + +#: utils/misc/guc.c:1756 msgid "Allows connections and queries during recovery." msgstr "Permite conexiones y consultas durante la recuperación." -#: utils/misc/guc.c:1576 +#: utils/misc/guc.c:1766 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "Permite retroalimentación desde un hot standby hacia el primario que evitará conflictos en consultas." -#: utils/misc/guc.c:1586 +#: utils/misc/guc.c:1776 msgid "Allows modifications of the structure of system tables." msgstr "Permite modificaciones de la estructura de las tablas del sistema." -#: utils/misc/guc.c:1597 +#: utils/misc/guc.c:1787 msgid "Disables reading from system indexes." msgstr "Deshabilita lectura de índices del sistema." -#: utils/misc/guc.c:1598 +#: utils/misc/guc.c:1788 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "No evita la actualización de índices, así que es seguro. Lo peor que puede ocurrir es lentitud del sistema." -#: utils/misc/guc.c:1609 +#: utils/misc/guc.c:1799 msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "Activa el modo de compatibilidad con versiones anteriores de las comprobaciones de privilegios de objetos grandes." -#: utils/misc/guc.c:1610 +#: utils/misc/guc.c:1800 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." msgstr "Omite las comprobaciones de privilegios cuando se leen o modifican los objetos grandes, para compatibilidad con versiones de PostgreSQL anteriores a 9.0." -#: utils/misc/guc.c:1620 +#: utils/misc/guc.c:1810 msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "Emitir una advertencia en constructos que cambiaron significado desde PostgreSQL 9.4." -#: utils/misc/guc.c:1630 +#: utils/misc/guc.c:1820 msgid "When generating SQL fragments, quote all identifiers." msgstr "Al generar fragmentos SQL, entrecomillar todos los identificadores." -#: utils/misc/guc.c:1640 +#: utils/misc/guc.c:1830 msgid "Shows whether data checksums are turned on for this cluster." msgstr "Indica si las sumas de verificación están activas en este cluster." -#: utils/misc/guc.c:1651 +#: utils/misc/guc.c:1841 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "Agregar número de secuencia a mensajes syslog para evitar supresión de duplicados." -#: utils/misc/guc.c:1661 +#: utils/misc/guc.c:1851 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "Dividir mensajes enviados a syslog en líneas y que quepan en 1024 bytes." -#: utils/misc/guc.c:1680 -#, fuzzy +#: utils/misc/guc.c:1861 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Controla si los Gather y Gather Merge también ejecutan subplanes." + +#: utils/misc/guc.c:1862 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "¿Deben los nodos de recolección ejecutar subplanes, o sólo recolectar tuplas?" + +#: utils/misc/guc.c:1872 +msgid "Allow JIT compilation." +msgstr "Permitir compilación JIT." + +#: utils/misc/guc.c:1883 +msgid "Register JIT compiled function with debugger." +msgstr "Registra la función JIT compilada con el depurador." + +#: utils/misc/guc.c:1900 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Escribe el bitcode LLVM para facilitar depuración de JIT." + +#: utils/misc/guc.c:1911 +msgid "Allow JIT compilation of expressions." +msgstr "Permitir compilación JIT de expresiones." + +#: utils/misc/guc.c:1922 +msgid "Register JIT compiled function with perf profiler." +msgstr "Registrar funciones JIT-compiladas con el analizador «perf»." + +#: utils/misc/guc.c:1939 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Permitir compilación JIT de deformación de tuplas." + +#: utils/misc/guc.c:1950 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Si continuar ejecutando después de una falla al sincronizar archivos de datos." + +#: utils/misc/guc.c:1968 msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." -msgstr "Obliga al cambio al siguiente archivo xlog si un nuevo archivo no ha sido iniciado dentro de N segundos." +msgstr "Fuerza a que utilizar el siguiente archivo de WAL si no se ha comenzado un nuevo archivo de WAL dentro de N segundos." -#: utils/misc/guc.c:1691 +#: utils/misc/guc.c:1979 msgid "Waits N seconds on connection startup after authentication." msgstr "Espera N segundos al inicio de la conexión después de la autentificación." -#: utils/misc/guc.c:1692 utils/misc/guc.c:2237 +#: utils/misc/guc.c:1980 utils/misc/guc.c:2526 msgid "This allows attaching a debugger to the process." msgstr "Esto permite adjuntar un depurador al proceso." -#: utils/misc/guc.c:1701 +#: utils/misc/guc.c:1989 msgid "Sets the default statistics target." msgstr "Definir el valor por omisión de toma de estadísticas." -#: utils/misc/guc.c:1702 +#: utils/misc/guc.c:1990 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "Esto se aplica a columnas de tablas que no tienen un valor definido a través de ALTER TABLE SET STATISTICS." -#: utils/misc/guc.c:1711 +#: utils/misc/guc.c:1999 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "Tamaño de lista de FROM a partir del cual subconsultas no serán colapsadas." -#: utils/misc/guc.c:1713 +#: utils/misc/guc.c:2001 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." msgstr "El planner mezclará subconsultas en consultas de nivel superior si la lista FROM resultante es menor que esta cantidad de ítems." -#: utils/misc/guc.c:1723 +#: utils/misc/guc.c:2012 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "Tamaño de lista de FROM a partir del cual constructos JOIN no serán aplanados." -#: utils/misc/guc.c:1725 +#: utils/misc/guc.c:2014 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." msgstr "El planner aplanará constructos JOIN explícitos en listas de ítems FROM siempre que la lista resultante no tenga más que esta cantidad de ítems." -#: utils/misc/guc.c:1735 +#: utils/misc/guc.c:2025 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "Umbral de ítems en FROM a partir del cual se usará GEQO." -#: utils/misc/guc.c:1744 +#: utils/misc/guc.c:2035 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: effort se usa para determinar los valores por defecto para otros parámetros." -#: utils/misc/guc.c:1753 +#: utils/misc/guc.c:2045 msgid "GEQO: number of individuals in the population." msgstr "GEQO: número de individuos en una población." -#: utils/misc/guc.c:1754 utils/misc/guc.c:1763 +#: utils/misc/guc.c:2046 utils/misc/guc.c:2056 msgid "Zero selects a suitable default value." msgstr "Cero selecciona un valor por omisión razonable." -#: utils/misc/guc.c:1762 +#: utils/misc/guc.c:2055 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: número de iteraciones del algoritmo." -#: utils/misc/guc.c:1773 +#: utils/misc/guc.c:2067 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Define el tiempo a esperar un lock antes de buscar un deadlock." -#: utils/misc/guc.c:1784 +#: utils/misc/guc.c:2078 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "Define el máximo retardo antes de cancelar consultas cuando un servidor hot standby está procesando datos de WAL archivado." -#: utils/misc/guc.c:1795 +#: utils/misc/guc.c:2089 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "Define el máximo retardo antes de cancelar consultas cuando un servidor hot standby está procesando datos de WAL en flujo." -#: utils/misc/guc.c:1806 -msgid "Sets the maximum interval between WAL receiver status reports to the primary." -msgstr "Define el intervalo máximo entre reportes de estado desde un proceso receptor de WAL hacia el primario." +#: utils/misc/guc.c:2100 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Define el retraso mínimo para aplicar cambios durante la recuperación." + +#: utils/misc/guc.c:2111 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Define el intervalo máximo entre reportes de estado que el receptor WAL envía al servidor origen." -#: utils/misc/guc.c:1817 -msgid "Sets the maximum wait time to receive data from the primary." -msgstr "Define el máximo tiempo a esperar entre recepciones de datos desde el primario." +#: utils/misc/guc.c:2122 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Define el máximo tiempo de espera para recibir datos desde el servidor origen." -#: utils/misc/guc.c:1828 +#: utils/misc/guc.c:2133 msgid "Sets the maximum number of concurrent connections." msgstr "Número máximo de conexiones concurrentes." -#: utils/misc/guc.c:1838 +#: utils/misc/guc.c:2144 msgid "Sets the number of connection slots reserved for superusers." msgstr "Número de conexiones reservadas para superusuarios." -#: utils/misc/guc.c:1852 +#: utils/misc/guc.c:2158 msgid "Sets the number of shared memory buffers used by the server." msgstr "Número de búfers de memoria compartida usados por el servidor." -#: utils/misc/guc.c:1863 +#: utils/misc/guc.c:2169 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Número de búfers de memoria temporal usados por cada sesión." -#: utils/misc/guc.c:1874 +#: utils/misc/guc.c:2180 msgid "Sets the TCP port the server listens on." msgstr "Puerto TCP en el cual escuchará el servidor." -#: utils/misc/guc.c:1884 +#: utils/misc/guc.c:2190 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Privilegios de acceso al socket Unix." -#: utils/misc/guc.c:1885 +#: utils/misc/guc.c:2191 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Los sockets de dominio Unix usan la funcionalidad de permisos de archivos estándar de Unix. Se espera que el valor de esta opción sea una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. Para usar el modo octal acostumbrado, comience el número con un 0 (cero)." -#: utils/misc/guc.c:1899 +#: utils/misc/guc.c:2205 msgid "Sets the file permissions for log files." msgstr "Define los privilegios para los archivos del registro del servidor." -#: utils/misc/guc.c:1900 +#: utils/misc/guc.c:2206 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Se espera que el valor de esta opción sea una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. Para usar el modo octal acostumbrado, comience el número con un 0 (cero)." -#: utils/misc/guc.c:1913 +#: utils/misc/guc.c:2220 +msgid "Mode of the data directory." +msgstr "Modo del directorio de datos." + +#: utils/misc/guc.c:2221 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "El valor del parámetro es una especificación numérica de modo, en la forma aceptada por las llamadas a sistema chmod y umask. (Para usar el modo octal acostumbrado, comience el número con un 0 (cero).)" + +#: utils/misc/guc.c:2234 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Establece el límite de memoria que se usará para espacios de trabajo de consultas." -#: utils/misc/guc.c:1914 +#: utils/misc/guc.c:2235 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "Esta es la cantidad máxima de memoria que se usará para operaciones internas de ordenamiento y tablas de hashing, antes de comenzar a usar archivos temporales en disco." -#: utils/misc/guc.c:1926 +#: utils/misc/guc.c:2247 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Establece el límite de memoria que se usará para operaciones de mantención." -#: utils/misc/guc.c:1927 +#: utils/misc/guc.c:2248 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "Esto incluye operaciones como VACUUM y CREATE INDEX." -#: utils/misc/guc.c:1937 -msgid "Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "Define el máximo número de tuplas que se ordenarán usando selección con reemplazo." - -#: utils/misc/guc.c:1938 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "Cuando más tuplas que esta cantidad esté presente, se usará quicksort." - -#: utils/misc/guc.c:1952 +#: utils/misc/guc.c:2263 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Establece el tamaño máximo del stack, en kilobytes." -#: utils/misc/guc.c:1963 +#: utils/misc/guc.c:2274 msgid "Limits the total size of all temporary files used by each process." msgstr "Limita el tamaño total de todos los archivos temporales usados en cada proceso." -#: utils/misc/guc.c:1964 +#: utils/misc/guc.c:2275 msgid "-1 means no limit." msgstr "-1 significa sin límite." -#: utils/misc/guc.c:1974 +#: utils/misc/guc.c:2285 msgid "Vacuum cost for a page found in the buffer cache." msgstr "Costo de Vacuum de una página encontrada en el buffer." -#: utils/misc/guc.c:1984 +#: utils/misc/guc.c:2295 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "Costo de Vacuum de una página no encontrada en el cache." -#: utils/misc/guc.c:1994 +#: utils/misc/guc.c:2305 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "Costo de Vacuum de una página ensuciada por vacuum." -#: utils/misc/guc.c:2004 +#: utils/misc/guc.c:2315 msgid "Vacuum cost amount available before napping." msgstr "Costo de Vacuum disponible antes de descansar." -#: utils/misc/guc.c:2014 -msgid "Vacuum cost delay in milliseconds." -msgstr "Tiempo de descanso de vacuum en milisegundos." - -#: utils/misc/guc.c:2025 -msgid "Vacuum cost delay in milliseconds, for autovacuum." -msgstr "Tiempo de descanso de vacuum en milisegundos, para autovacuum." - -#: utils/misc/guc.c:2036 +#: utils/misc/guc.c:2325 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "Costo de Vacuum disponible antes de descansar, para autovacuum." -#: utils/misc/guc.c:2046 +#: utils/misc/guc.c:2335 msgid "Sets the maximum number of simultaneously open files for each server process." msgstr "Define la cantidad máxima de archivos abiertos por cada subproceso." -#: utils/misc/guc.c:2059 +#: utils/misc/guc.c:2348 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Define la cantidad máxima de transacciones preparadas simultáneas." -#: utils/misc/guc.c:2070 +#: utils/misc/guc.c:2359 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Define el OID mínimo para hacer seguimiento de locks." -#: utils/misc/guc.c:2071 +#: utils/misc/guc.c:2360 msgid "Is used to avoid output on system tables." msgstr "Se usa para evitar salida excesiva por tablas de sistema." -#: utils/misc/guc.c:2080 +#: utils/misc/guc.c:2369 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Define el OID de una tabla con trazado incondicional de locks." -#: utils/misc/guc.c:2092 +#: utils/misc/guc.c:2381 msgid "Sets the maximum allowed duration of any statement." msgstr "Define la duración máxima permitida de sentencias." -#: utils/misc/guc.c:2093 utils/misc/guc.c:2104 utils/misc/guc.c:2115 +#: utils/misc/guc.c:2382 utils/misc/guc.c:2393 utils/misc/guc.c:2404 msgid "A value of 0 turns off the timeout." msgstr "Un valor de 0 desactiva el máximo." -#: utils/misc/guc.c:2103 +#: utils/misc/guc.c:2392 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Define la duración máxima permitida de cualquier espera por un lock." -#: utils/misc/guc.c:2114 +#: utils/misc/guc.c:2403 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "Define la duración máxima permitida de transacciones inactivas." -#: utils/misc/guc.c:2125 +#: utils/misc/guc.c:2414 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "Mínima edad a la cual VACUUM debería congelar (freeze) una fila de una tabla." -#: utils/misc/guc.c:2135 +#: utils/misc/guc.c:2424 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "Edad a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." -#: utils/misc/guc.c:2145 +#: utils/misc/guc.c:2434 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "Mínima edad a la cual VACUUM debería congelar (freeze) el multixact en una fila." -#: utils/misc/guc.c:2155 +#: utils/misc/guc.c:2444 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "Edad de multixact a la cual VACUUM debería recorrer una tabla completa para congelar (freeze) las filas." -#: utils/misc/guc.c:2165 +#: utils/misc/guc.c:2454 msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." msgstr "Número de transacciones por las cuales VACUUM y la limpieza HOT deberían postergarse." -#: utils/misc/guc.c:2178 +#: utils/misc/guc.c:2467 msgid "Sets the maximum number of locks per transaction." msgstr "Cantidad máxima de candados (locks) por transacción." -#: utils/misc/guc.c:2179 +#: utils/misc/guc.c:2468 msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "El tamaño de la tabla compartida de candados se calcula usando la suposición de que a lo más max_locks_per_transaction * max_connections objetos necesitarán ser bloqueados simultáneamente." -#: utils/misc/guc.c:2190 +#: utils/misc/guc.c:2479 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Cantidad máxima de candados (locks) de predicado por transacción." -#: utils/misc/guc.c:2191 +#: utils/misc/guc.c:2480 msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "El tamaño de la tabla compartida de candados se calcula usando la suposición de que a lo más max_pred_locks_per_transaction * max_connections objetos necesitarán ser bloqueados simultáneamente." -#: utils/misc/guc.c:2202 -#, fuzzy +#: utils/misc/guc.c:2491 msgid "Sets the maximum number of predicate-locked pages and tuples per relation." -msgstr "Cantidad máxima de candados (locks) de predicado por transacción." +msgstr "Cantidad máxima de páginas y tuplas bloqueadas por predicado." -#: utils/misc/guc.c:2203 -msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation level lock." -msgstr "" +#: utils/misc/guc.c:2492 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Si más que este total de páginas y tuplas en la misma relación están bloqueadas por una conexión, esos locks son reemplazados por un lock a nivel de relación." -#: utils/misc/guc.c:2213 -#, fuzzy +#: utils/misc/guc.c:2502 msgid "Sets the maximum number of predicate-locked tuples per page." -msgstr "Cantidad máxima de candados (locks) de predicado por transacción." +msgstr "Cantidad máxima de locks de predicado por página." -#: utils/misc/guc.c:2214 -msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page level lock." -msgstr "" +#: utils/misc/guc.c:2503 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Si más que este número de tuplas de la misma página están bloqueadas por una conexión, esos locks son reemplazados por un lock a nivel de página." -#: utils/misc/guc.c:2224 +#: utils/misc/guc.c:2513 msgid "Sets the maximum allowed time to complete client authentication." msgstr "Define el tiempo máximo para completar proceso de autentificación." -#: utils/misc/guc.c:2236 +#: utils/misc/guc.c:2525 msgid "Waits N seconds on connection startup before authentication." msgstr "Espera N segundos al inicio de la conexión antes de la autentificación." -#: utils/misc/guc.c:2247 +#: utils/misc/guc.c:2536 msgid "Sets the number of WAL files held for standby servers." msgstr "Número de archivos WAL conservados para servidores standby." -#: utils/misc/guc.c:2257 +#: utils/misc/guc.c:2546 msgid "Sets the minimum size to shrink the WAL to." msgstr "Define el tamaño mínimo al cual reducir el WAL." -#: utils/misc/guc.c:2268 +#: utils/misc/guc.c:2558 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Define el tamaño de WAL que desencadena un checkpoint." -#: utils/misc/guc.c:2279 +#: utils/misc/guc.c:2570 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "Define el tiempo máximo entre puntos de control de WAL automáticos." -#: utils/misc/guc.c:2290 +#: utils/misc/guc.c:2581 msgid "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "Registrar si el llenado de segmentos de WAL es más frecuente que esto." -#: utils/misc/guc.c:2292 +#: utils/misc/guc.c:2583 msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." msgstr "Envía un mensaje a los registros del servidor si los punto de control causados por el llenado de archivos de segmento sucede con más frecuencia que este número de segundos. Un valor de 0 (cero) desactiva la opción." -#: utils/misc/guc.c:2304 utils/misc/guc.c:2461 utils/misc/guc.c:2488 +#: utils/misc/guc.c:2595 utils/misc/guc.c:2753 utils/misc/guc.c:2782 msgid "Number of pages after which previously performed writes are flushed to disk." msgstr "Número de páginas después del cual las escrituras previamente ejecutadas se sincronizan a disco." -#: utils/misc/guc.c:2315 +#: utils/misc/guc.c:2606 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "Búfers en memoria compartida para páginas de WAL." -#: utils/misc/guc.c:2326 +#: utils/misc/guc.c:2617 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Tiempo entre sincronizaciones de WAL ejecutadas por el proceso escritor de WAL." -#: utils/misc/guc.c:2337 +#: utils/misc/guc.c:2628 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "Cantidad de WAL escrito por el proceso escritor de WAL que desencadena una sincronización (flush)." -#: utils/misc/guc.c:2349 +#: utils/misc/guc.c:2639 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "Define la cantidad máxima de procesos «WAL sender» simultáneos." -#: utils/misc/guc.c:2360 +#: utils/misc/guc.c:2650 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Define la cantidad máxima de slots de replicación definidos simultáneamente." -#: utils/misc/guc.c:2370 +#: utils/misc/guc.c:2660 msgid "Sets the maximum time to wait for WAL replication." msgstr "Define el tiempo máximo a esperar la replicación de WAL." -#: utils/misc/guc.c:2381 +#: utils/misc/guc.c:2671 msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." msgstr "Retardo en microsegundos entre completar una transacción y escribir WAL a disco." -#: utils/misc/guc.c:2393 +#: utils/misc/guc.c:2683 msgid "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "Mínimo de transacciones concurrentes para esperar commit_delay." -#: utils/misc/guc.c:2404 +#: utils/misc/guc.c:2694 msgid "Sets the number of digits displayed for floating-point values." msgstr "Ajustar el número de dígitos mostrados para valores de coma flotante." -#: utils/misc/guc.c:2405 -msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." -msgstr "Afecta los tipos real, double precision y geométricos. El valor del parámetro se agrega al número estándar de dígitos (FLT_DIG o DBL_DIG según corresponda)" +#: utils/misc/guc.c:2695 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Esto afecta los tipos real, de doble precisión, y geométricos. Un valor del parámetro cero o negativo se agrega a la cantidad estándar de dígitos (FLT_DIG o DBL_DIG, según sea apropiado). Cualquier valor mayor que cero selecciona el modo de salida preciso." -#: utils/misc/guc.c:2416 +#: utils/misc/guc.c:2707 msgid "Sets the minimum execution time above which statements will be logged." msgstr "Tiempo mínimo de ejecución a partir del cual se registran las consultas." -#: utils/misc/guc.c:2418 -msgid "Zero prints all queries. -1 turns this feature off." -msgstr "Cero registra todas las consultas. -1 desactiva esta característica." +#: utils/misc/guc.c:2709 +msgid "Zero prints all queries, subject to log_statement_sample_rate. -1 turns this feature off." +msgstr "Cero imprime todas las consultas, sujeto a log_statement_sample_rate. -1 desactiva esta funcionalidad." -#: utils/misc/guc.c:2428 +#: utils/misc/guc.c:2720 msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgstr "Tiempo mínimo de ejecución a partir del cual se registran las acciones de autovacuum." -#: utils/misc/guc.c:2430 +#: utils/misc/guc.c:2722 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "Cero registra todas las acciones. -1 desactiva el registro de autovacuum." -#: utils/misc/guc.c:2440 +#: utils/misc/guc.c:2732 msgid "Background writer sleep time between rounds." msgstr "Tiempo de descanso entre rondas del background writer" -#: utils/misc/guc.c:2451 +#: utils/misc/guc.c:2743 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "Número máximo de páginas LRU a escribir en cada ronda del background writer" -#: utils/misc/guc.c:2474 +#: utils/misc/guc.c:2766 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "Cantidad máxima de peticiones simultáneas que pueden ser manejadas eficientemente por el sistema de disco." -#: utils/misc/guc.c:2475 +#: utils/misc/guc.c:2767 msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." msgstr "Para arrays RAID, esto debería ser aproximadamente la cantidad de discos en el array." -#: utils/misc/guc.c:2501 +#: utils/misc/guc.c:2795 msgid "Maximum number of concurrent worker processes." -msgstr "Número máximo de procesos trabajadores concurrentes." +msgstr "Número máximo de procesos ayudantes concurrentes." -#: utils/misc/guc.c:2513 -#, fuzzy +#: utils/misc/guc.c:2807 msgid "Maximum number of logical replication worker processes." -msgstr "Número máximo de procesos trabajadores concurrentes." +msgstr "Número máximo de procesos ayudantes de replicación lógica." -#: utils/misc/guc.c:2525 -#, fuzzy +#: utils/misc/guc.c:2819 msgid "Maximum number of table synchronization workers per subscription." -msgstr "Número máximo de procesos trabajadores concurrentes." +msgstr "Número máximo de procesos ayudantes de sincronización por suscripción." -#: utils/misc/guc.c:2535 +#: utils/misc/guc.c:2829 msgid "Automatic log file rotation will occur after N minutes." msgstr "La rotación automática de archivos de log se efectuará después de N minutos." -#: utils/misc/guc.c:2546 +#: utils/misc/guc.c:2840 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "La rotación automática de archivos de log se efectuará después de N kilobytes." -#: utils/misc/guc.c:2557 +#: utils/misc/guc.c:2851 msgid "Shows the maximum number of function arguments." msgstr "Muestra la cantidad máxima de argumentos de funciones." -#: utils/misc/guc.c:2568 +#: utils/misc/guc.c:2862 msgid "Shows the maximum number of index keys." msgstr "Muestra la cantidad máxima de claves de índices." -#: utils/misc/guc.c:2579 +#: utils/misc/guc.c:2873 msgid "Shows the maximum identifier length." msgstr "Muestra el largo máximo de identificadores." -#: utils/misc/guc.c:2590 +#: utils/misc/guc.c:2884 msgid "Shows the size of a disk block." msgstr "Muestra el tamaño de un bloque de disco." -#: utils/misc/guc.c:2601 +#: utils/misc/guc.c:2895 msgid "Shows the number of pages per disk file." msgstr "Muestra el número de páginas por archivo en disco." -#: utils/misc/guc.c:2612 +#: utils/misc/guc.c:2906 msgid "Shows the block size in the write ahead log." msgstr "Muestra el tamaño de bloque en el write-ahead log." -#: utils/misc/guc.c:2623 +#: utils/misc/guc.c:2917 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "Define el tiempo a esperar antes de reintentar obtener WAL después de un intento fallido." -#: utils/misc/guc.c:2635 -msgid "Shows the number of pages per write ahead log segment." -msgstr "Muestra el número de páginas por cada segmento de write-ahead log." +#: utils/misc/guc.c:2929 +msgid "Shows the size of write ahead log segments." +msgstr "Muestra el tamaño de los segmentos de WAL." -#: utils/misc/guc.c:2648 +#: utils/misc/guc.c:2942 msgid "Time to sleep between autovacuum runs." msgstr "Tiempo de descanso entre ejecuciones de autovacuum." -#: utils/misc/guc.c:2658 +#: utils/misc/guc.c:2952 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "Número mínimo de updates o deletes antes de ejecutar vacuum." -#: utils/misc/guc.c:2667 +#: utils/misc/guc.c:2961 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "Número mínimo de inserciones, actualizaciones y eliminaciones de tuplas antes de ejecutar analyze." -#: utils/misc/guc.c:2677 +#: utils/misc/guc.c:2971 msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "Edad a la cual aplicar VACUUM automáticamente a una tabla para prevenir problemas por reciclaje de ID de transacción." -#: utils/misc/guc.c:2688 +#: utils/misc/guc.c:2982 msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "Edad de multixact a la cual aplicar VACUUM automáticamente a una tabla para prevenir problemas por reciclaje de ID de multixacts." -#: utils/misc/guc.c:2698 +#: utils/misc/guc.c:2992 msgid "Sets the maximum number of simultaneously running autovacuum worker processes." msgstr "Define la cantidad máxima de procesos «autovacuum worker» simultáneos." -#: utils/misc/guc.c:2708 +#: utils/misc/guc.c:3002 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Cantidad máxima de procesos ayudantes paralelos por operación de mantención." + +#: utils/misc/guc.c:3012 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Cantidad máxima de locks de predicado por nodo de ejecución." -#: utils/misc/guc.c:2718 -#, fuzzy -msgid "Sets the maximum number of parallel workers than can be active at one time." -msgstr "Cantidad máxima de candados (locks) de predicado por transacción." +#: utils/misc/guc.c:3023 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Define la cantidad máxima de procesos ayudantes que pueden estar activos en un momento dado." -#: utils/misc/guc.c:2728 +#: utils/misc/guc.c:3034 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "Establece el límite de memoria que cada proceso «autovacuum worker» usará." -#: utils/misc/guc.c:2739 +#: utils/misc/guc.c:3045 msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." msgstr "Tiempo antes de que un snapshot sea demasiado antiguo para leer páginas después de que el snapshot fue tomado." -#: utils/misc/guc.c:2740 +#: utils/misc/guc.c:3046 msgid "A value of -1 disables this feature." msgstr "El valor -1 desactiva esta característica." -#: utils/misc/guc.c:2750 +#: utils/misc/guc.c:3056 msgid "Time between issuing TCP keepalives." msgstr "Tiempo entre cada emisión de TCP keepalive." -#: utils/misc/guc.c:2751 utils/misc/guc.c:2762 +#: utils/misc/guc.c:3057 utils/misc/guc.c:3068 utils/misc/guc.c:3192 msgid "A value of 0 uses the system default." msgstr "Un valor 0 usa el valor por omisión del sistema." -#: utils/misc/guc.c:2761 +#: utils/misc/guc.c:3067 msgid "Time between TCP keepalive retransmits." msgstr "Tiempo entre retransmisiones TCP keepalive." -#: utils/misc/guc.c:2772 +#: utils/misc/guc.c:3078 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "La renegociación SSL ya no está soportada; esto sólo puede ser 0." -#: utils/misc/guc.c:2783 +#: utils/misc/guc.c:3089 msgid "Maximum number of TCP keepalive retransmits." msgstr "Cantidad máxima de retransmisiones TCP keepalive." -#: utils/misc/guc.c:2784 +#: utils/misc/guc.c:3090 msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." msgstr "Esto controla el número de retransmisiones consecutivas de keepalive que pueden ser perdidas antes que la conexión sea considerada muerta. Un valor 0 usa el valor por omisión del sistema." -#: utils/misc/guc.c:2795 +#: utils/misc/guc.c:3101 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Define el máximo de resultados permitidos por búsquedas exactas con GIN." -#: utils/misc/guc.c:2806 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "Define la suposición del tamaño del cache de disco." +#: utils/misc/guc.c:3112 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Define la suposición del optimizador sobre el tamaño total de los caches de datos." -#: utils/misc/guc.c:2807 -msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." -msgstr "Esto es, la porción del cache de disco que será usado para archivos de datos de PostgreSQL. Esto se mide en cantidad de páginas, que normalmente son de 8 kB cada una." +#: utils/misc/guc.c:3113 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Esto es, el tamaño total de caches (cache del kernel y búfers compartidos) usados por archivos de datos de PostgreSQL. Esto se mide en páginas de disco, que normalmente son de 8 kB cada una." -#: utils/misc/guc.c:2819 -#, fuzzy +#: utils/misc/guc.c:3124 msgid "Sets the minimum amount of table data for a parallel scan." -msgstr "Tamaño mínimo de relaciones para considerarlas en recorridos en paralelo." +msgstr "Define la cantidad mínima de datos en una tabla para un recorrido paralelo." -#: utils/misc/guc.c:2820 +#: utils/misc/guc.c:3125 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." -msgstr "" +msgstr "Si el planificador estima que leerá un número de páginas de tabla demasiado pequeñas para alcanzar este límite, no se considerará una búsqueda paralela." -#: utils/misc/guc.c:2830 -#, fuzzy +#: utils/misc/guc.c:3135 msgid "Sets the minimum amount of index data for a parallel scan." -msgstr "Tamaño mínimo de relaciones para considerarlas en recorridos en paralelo." +msgstr "Define la cantidad mínima de datos en un índice para un recorrido paralelo." -#: utils/misc/guc.c:2831 +#: utils/misc/guc.c:3136 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." -msgstr "" +msgstr "Si el planificador estima que leerá un número de páginas de índice demasiado pequeñas para alcanzar este límite, no se considerará una búsqueda paralela." -#: utils/misc/guc.c:2842 +#: utils/misc/guc.c:3147 msgid "Shows the server version as an integer." msgstr "Muestra la versión del servidor como un número entero." -#: utils/misc/guc.c:2853 +#: utils/misc/guc.c:3158 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "Registra el uso de archivos temporales que crezcan más allá de este número de kilobytes." -#: utils/misc/guc.c:2854 +#: utils/misc/guc.c:3159 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "Cero registra todos los archivos. El valor por omisión es -1 (lo cual desactiva el registro)." -#: utils/misc/guc.c:2864 +#: utils/misc/guc.c:3169 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Tamaño reservado para pg_stat_activity.query, en bytes." -#: utils/misc/guc.c:2879 +#: utils/misc/guc.c:3180 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Define el tamaño máximo de la lista de pendientes de un índice GIN." -#: utils/misc/guc.c:2899 +#: utils/misc/guc.c:3191 +msgid "TCP user timeout." +msgstr "Tiempo de expiración de TCP." + +#: utils/misc/guc.c:3211 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "Estimación del costo de una página leída secuencialmente." -#: utils/misc/guc.c:2909 +#: utils/misc/guc.c:3222 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "Estimación del costo de una página leída no secuencialmente." -#: utils/misc/guc.c:2919 +#: utils/misc/guc.c:3233 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "Estimación del costo de procesar cada tupla (fila)." -#: utils/misc/guc.c:2929 +#: utils/misc/guc.c:3244 msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." msgstr "Estimación del costo de procesar cada fila de índice durante un recorrido de índice." -#: utils/misc/guc.c:2939 +#: utils/misc/guc.c:3255 msgid "Sets the planner's estimate of the cost of processing each operator or function call." msgstr "Estimación del costo de procesar cada operador o llamada a función." -#: utils/misc/guc.c:2949 +#: utils/misc/guc.c:3266 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." -msgstr "Estimación del costo de pasar cada tupla (fila) desde un proceso trabajador al proceso servidor principal." +msgstr "Estimación del costo de pasar cada tupla (fila) desde un proceso ayudante al proceso servidor principal." -#: utils/misc/guc.c:2959 +#: utils/misc/guc.c:3277 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." -msgstr "Estimación del costo de lanzar procesos trabajadores para consultas en paralelo." +msgstr "Estimación del costo de lanzar procesos ayudantes para consultas en paralelo." + +#: utils/misc/guc.c:3289 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Ejecutar compilación JIT si la consulta es más cara." + +#: utils/misc/guc.c:3290 +msgid "-1 disables JIT compilation." +msgstr "-1 inhabilita compilación JIT." + +#: utils/misc/guc.c:3300 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Optimizar funciones JIT-compiladas si la consulta es más cara." -#: utils/misc/guc.c:2970 +#: utils/misc/guc.c:3301 +msgid "-1 disables optimization." +msgstr "-1 inhabilita la optimización." + +#: utils/misc/guc.c:3311 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Ejecutar «inlining» JIT si la consulta es más cara." + +#: utils/misc/guc.c:3312 +msgid "-1 disables inlining." +msgstr "-1 inhabilita el «inlining»." + +#: utils/misc/guc.c:3322 msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." msgstr "Estimación de la fracción de filas de un cursor que serán extraídas." -#: utils/misc/guc.c:2981 +#: utils/misc/guc.c:3334 msgid "GEQO: selective pressure within the population." msgstr "GEQO: presión selectiva dentro de la población." -#: utils/misc/guc.c:2991 +#: utils/misc/guc.c:3345 msgid "GEQO: seed for random path selection." msgstr "GEQO: semilla para la selección aleatoria de caminos." -#: utils/misc/guc.c:3001 +#: utils/misc/guc.c:3356 msgid "Multiple of the average buffer usage to free per round." msgstr "Múltiplo del uso promedio de búfers que liberar en cada ronda." -#: utils/misc/guc.c:3011 +#: utils/misc/guc.c:3366 msgid "Sets the seed for random-number generation." msgstr "Semilla para la generación de números aleatorios." -#: utils/misc/guc.c:3022 +#: utils/misc/guc.c:3377 +msgid "Vacuum cost delay in milliseconds." +msgstr "Tiempo de descanso de vacuum en milisegundos." + +#: utils/misc/guc.c:3388 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Tiempo de descanso de vacuum en milisegundos, para autovacuum." + +#: utils/misc/guc.c:3399 msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." msgstr "Número de updates o deletes de tuplas antes de ejecutar un vacuum, como fracción de reltuples." -#: utils/misc/guc.c:3031 +#: utils/misc/guc.c:3408 msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." msgstr "Número mínimo de inserciones, actualizaciones y eliminaciones de tuplas antes de ejecutar analyze, como fracción de reltuples." -#: utils/misc/guc.c:3041 +#: utils/misc/guc.c:3418 msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." msgstr "Tiempo utilizado en escribir páginas «sucias» durante los puntos de control, medido como fracción del intervalo del punto de control." -#: utils/misc/guc.c:3060 +#: utils/misc/guc.c:3428 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Número de inserts de tuplas antes de ejecutar una limpieza de índice, como fracción de reltuples." + +#: utils/misc/guc.c:3438 +msgid "Fraction of statements exceeding log_min_duration_statement to be logged." +msgstr "Fracción de sentencias que excedan log_min_duration_statement que serán registradas." + +#: utils/misc/guc.c:3439 +msgid "If you only want a sample, use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Si sólo quiere una muestra, use un valor entre 0.0 (nunca registrar) y 1.0 (siempre registrar)." + +#: utils/misc/guc.c:3449 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "Define la fracción de transacciones que registrar en el log, para nuevas transacciones." + +#: utils/misc/guc.c:3450 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Registra todas las sentencias de una fracción de transacciones. Use un valor entre 0.0 (nunca registrar) y 1.0 (registrar todas las sentencias de todas las transacciones)." + +#: utils/misc/guc.c:3470 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "Orden de shell que se invocará para archivar un archivo WAL." -#: utils/misc/guc.c:3070 +#: utils/misc/guc.c:3480 +msgid "Sets the shell command that will retrieve an archived WAL file." +msgstr "Orden de shell que se invocará para obtener un archivo WAL archivado." + +#: utils/misc/guc.c:3490 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Orden de shell que se invocará en cada «restart point»." + +#: utils/misc/guc.c:3500 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Orden de shell que se invocará una vez al terminar la recuperación." + +#: utils/misc/guc.c:3510 +msgid "Specifies the timeline to recovery into." +msgstr "Especifica la línea de tiempo a la cual recuperar." + +#: utils/misc/guc.c:3520 +msgid "Set to 'immediate' to end recovery as soon as a consistent state is reached." +msgstr "Defina a 'immediate' para terminar la recuperación en cuando se alcance el estado consistente." + +#: utils/misc/guc.c:3529 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Define el ID de transacción hasta el cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3538 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Define la marca de tiempo hasta la cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3547 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Define el nombre del punto de restauración hasta el cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3556 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Define el LSN de la ubicación de WAL hasta la cual se ejecutará la recuperación." + +#: utils/misc/guc.c:3566 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Especifica un nombre de archivo cuya presencia termina la recuperación en el standby." + +#: utils/misc/guc.c:3576 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Define la cadena de conexión que se usará para conectarse al servidor de origen." + +#: utils/misc/guc.c:3587 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Define el nombre del slot de replicación a utilizar en el servidor de origen." + +#: utils/misc/guc.c:3597 msgid "Sets the client's character set encoding." msgstr "Codificación del juego de caracteres del cliente." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3608 msgid "Controls information prefixed to each log line." msgstr "Controla el prefijo que antecede cada línea registrada." -#: utils/misc/guc.c:3082 +#: utils/misc/guc.c:3609 msgid "If blank, no prefix is used." msgstr "si está en blanco, no se usa prefijo." -#: utils/misc/guc.c:3091 +#: utils/misc/guc.c:3618 msgid "Sets the time zone to use in log messages." msgstr "Define el huso horario usando en los mensajes registrados." -#: utils/misc/guc.c:3101 +#: utils/misc/guc.c:3628 msgid "Sets the display format for date and time values." msgstr "Formato de salida para valores de horas y fechas." -#: utils/misc/guc.c:3102 +#: utils/misc/guc.c:3629 msgid "Also controls interpretation of ambiguous date inputs." msgstr "También controla la interpretación de entradas ambiguas de fechas" -#: utils/misc/guc.c:3113 +#: utils/misc/guc.c:3640 +msgid "Sets the default table access method for new tables." +msgstr "Define el método de acceso a tablas por omisión para nuevas tablas." + +#: utils/misc/guc.c:3651 msgid "Sets the default tablespace to create tables and indexes in." msgstr "Define el tablespace en el cual crear tablas e índices." -#: utils/misc/guc.c:3114 +#: utils/misc/guc.c:3652 msgid "An empty string selects the database's default tablespace." msgstr "Una cadena vacía especifica el tablespace por omisión de la base de datos." -#: utils/misc/guc.c:3124 +#: utils/misc/guc.c:3662 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "Define el/los tablespace/s en el cual crear tablas temporales y archivos de ordenamiento." -#: utils/misc/guc.c:3135 +#: utils/misc/guc.c:3673 msgid "Sets the path for dynamically loadable modules." msgstr "Ruta para módulos dinámicos." -#: utils/misc/guc.c:3136 +#: utils/misc/guc.c:3674 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "Si se necesita abrir un módulo dinámico y el nombre especificado no tiene un componente de directorio (es decir, no contiene un slash), el sistema buscará el archivo especificado en esta ruta." -#: utils/misc/guc.c:3149 +#: utils/misc/guc.c:3687 msgid "Sets the location of the Kerberos server key file." msgstr "Ubicación del archivo de llave del servidor Kerberos." -#: utils/misc/guc.c:3160 +#: utils/misc/guc.c:3698 msgid "Sets the Bonjour service name." msgstr "Nombre del servicio Bonjour." -#: utils/misc/guc.c:3172 +#: utils/misc/guc.c:3710 msgid "Shows the collation order locale." msgstr "Configuración regional de ordenamiento de cadenas (collation)." -#: utils/misc/guc.c:3183 +#: utils/misc/guc.c:3721 msgid "Shows the character classification and case conversion locale." msgstr "Configuración regional de clasificación de caracteres y conversión de mayúsculas." -#: utils/misc/guc.c:3194 +#: utils/misc/guc.c:3732 msgid "Sets the language in which messages are displayed." msgstr "Idioma en el que se despliegan los mensajes." -#: utils/misc/guc.c:3204 +#: utils/misc/guc.c:3742 msgid "Sets the locale for formatting monetary amounts." msgstr "Configuración regional para formatos de moneda." -#: utils/misc/guc.c:3214 +#: utils/misc/guc.c:3752 msgid "Sets the locale for formatting numbers." msgstr "Configuración regional para formatos de números." -#: utils/misc/guc.c:3224 +#: utils/misc/guc.c:3762 msgid "Sets the locale for formatting date and time values." msgstr "Configuración regional para formatos de horas y fechas." -#: utils/misc/guc.c:3234 +#: utils/misc/guc.c:3772 msgid "Lists shared libraries to preload into each backend." msgstr "Bibliotecas compartidas a precargar en cada proceso." -#: utils/misc/guc.c:3245 +#: utils/misc/guc.c:3783 msgid "Lists shared libraries to preload into server." msgstr "Bibliotecas compartidas a precargar en el servidor." -#: utils/misc/guc.c:3256 +#: utils/misc/guc.c:3794 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "Bibliotecas compartidas no privilegiadas a precargar en cada proceso." -#: utils/misc/guc.c:3267 +#: utils/misc/guc.c:3805 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "Orden de búsqueda en schemas para nombres que no especifican schema." -#: utils/misc/guc.c:3279 +#: utils/misc/guc.c:3817 msgid "Sets the server (database) character set encoding." msgstr "Codificación de caracteres del servidor (bases de datos)." -#: utils/misc/guc.c:3291 +#: utils/misc/guc.c:3829 msgid "Shows the server version." msgstr "Versión del servidor." -#: utils/misc/guc.c:3303 +#: utils/misc/guc.c:3841 msgid "Sets the current role." msgstr "Define el rol actual." -#: utils/misc/guc.c:3315 +#: utils/misc/guc.c:3853 msgid "Sets the session user name." msgstr "Define el nombre del usuario de sesión." -#: utils/misc/guc.c:3326 +#: utils/misc/guc.c:3864 msgid "Sets the destination for server log output." msgstr "Define el destino de la salida del registro del servidor." -#: utils/misc/guc.c:3327 +#: utils/misc/guc.c:3865 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." msgstr "Los valores aceptables son combinaciones de «stderr», «syslog», «csvlog» y «eventlog», dependiendo de la plataforma." -#: utils/misc/guc.c:3338 +#: utils/misc/guc.c:3876 msgid "Sets the destination directory for log files." msgstr "Define el directorio de destino de los archivos del registro del servidor." -#: utils/misc/guc.c:3339 +#: utils/misc/guc.c:3877 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "Puede ser una ruta relativa al directorio de datos o una ruta absoluta." -#: utils/misc/guc.c:3349 +#: utils/misc/guc.c:3887 msgid "Sets the file name pattern for log files." msgstr "Define el patrón para los nombres de archivo del registro del servidor." -#: utils/misc/guc.c:3360 +#: utils/misc/guc.c:3898 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "Nombre de programa para identificar PostgreSQL en mensajes de syslog." -#: utils/misc/guc.c:3371 +#: utils/misc/guc.c:3909 msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "Nombre de programa para identificar PostgreSQL en mensajes del log de eventos." -#: utils/misc/guc.c:3382 +#: utils/misc/guc.c:3920 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "Huso horario para desplegar e interpretar valores de tiempo." -#: utils/misc/guc.c:3392 +#: utils/misc/guc.c:3930 msgid "Selects a file of time zone abbreviations." msgstr "Selecciona un archivo de abreviaciones de huso horario." -#: utils/misc/guc.c:3402 -msgid "Sets the current transaction's isolation level." -msgstr "Define el nivel de aislación de la transacción en curso." - -#: utils/misc/guc.c:3413 +#: utils/misc/guc.c:3940 msgid "Sets the owning group of the Unix-domain socket." msgstr "Grupo dueño del socket de dominio Unix." -#: utils/misc/guc.c:3414 +#: utils/misc/guc.c:3941 msgid "The owning user of the socket is always the user that starts the server." msgstr "El usuario dueño del socket siempre es el usuario que inicia el servidor." -#: utils/misc/guc.c:3424 +#: utils/misc/guc.c:3951 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Directorios donde se crearán los sockets de dominio Unix." -#: utils/misc/guc.c:3439 +#: utils/misc/guc.c:3966 msgid "Sets the host name or IP address(es) to listen to." msgstr "Define el nombre de anfitrión o dirección IP en la cual escuchar." -#: utils/misc/guc.c:3454 +#: utils/misc/guc.c:3981 msgid "Sets the server's data directory." msgstr "Define la ubicación del directorio de datos." -#: utils/misc/guc.c:3465 +#: utils/misc/guc.c:3992 msgid "Sets the server's main configuration file." msgstr "Define la ubicación del archivo principal de configuración del servidor." -#: utils/misc/guc.c:3476 +#: utils/misc/guc.c:4003 msgid "Sets the server's \"hba\" configuration file." msgstr "Define la ubicación del archivo de configuración «hba» del servidor." -#: utils/misc/guc.c:3487 +#: utils/misc/guc.c:4014 msgid "Sets the server's \"ident\" configuration file." msgstr "Define la ubicación del archivo de configuración «ident» del servidor." -#: utils/misc/guc.c:3498 +#: utils/misc/guc.c:4025 msgid "Writes the postmaster PID to the specified file." msgstr "Registra el PID de postmaster en el archivo especificado." -#: utils/misc/guc.c:3509 +#: utils/misc/guc.c:4036 +msgid "Name of the SSL library." +msgstr "Nombre de la biblioteca SSL." + +#: utils/misc/guc.c:4051 msgid "Location of the SSL server certificate file." msgstr "Ubicación del archivo de certificado SSL del servidor." -#: utils/misc/guc.c:3519 +#: utils/misc/guc.c:4061 msgid "Location of the SSL server private key file." msgstr "Ubicación del archivo de la llave SSL privada del servidor." -#: utils/misc/guc.c:3529 +#: utils/misc/guc.c:4071 msgid "Location of the SSL certificate authority file." msgstr "Ubicación del archivo de autoridad certificadora SSL." -#: utils/misc/guc.c:3539 +#: utils/misc/guc.c:4081 msgid "Location of the SSL certificate revocation list file." msgstr "Ubicación del archivo de lista de revocación de certificados SSL" -#: utils/misc/guc.c:3549 +#: utils/misc/guc.c:4091 msgid "Writes temporary statistics files to the specified directory." msgstr "Escribe los archivos temporales de estadísticas al directorio especificado." -#: utils/misc/guc.c:3560 +#: utils/misc/guc.c:4102 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "Número de standbys sincrónicos y lista de nombres de los potenciales sincrónicos." -#: utils/misc/guc.c:3571 +#: utils/misc/guc.c:4113 msgid "Sets default text search configuration." msgstr "Define la configuración de búsqueda en texto por omisión." -#: utils/misc/guc.c:3581 +#: utils/misc/guc.c:4123 msgid "Sets the list of allowed SSL ciphers." msgstr "Define la lista de cifrados SSL permitidos." -#: utils/misc/guc.c:3596 +#: utils/misc/guc.c:4138 msgid "Sets the curve to use for ECDH." msgstr "Define la curva a usar para ECDH." -#: utils/misc/guc.c:3611 +#: utils/misc/guc.c:4153 +msgid "Location of the SSL DH parameters file." +msgstr "Ubicación del archivo de parámetros DH para SSL." + +#: utils/misc/guc.c:4164 +msgid "Command to obtain passphrases for SSL." +msgstr "Orden para obtener frases clave para SSL." + +#: utils/misc/guc.c:4174 msgid "Sets the application name to be reported in statistics and logs." msgstr "Define el nombre de aplicación a reportarse en estadísticas y logs." -#: utils/misc/guc.c:3622 +#: utils/misc/guc.c:4185 msgid "Sets the name of the cluster, which is included in the process title." msgstr "Define el nombre del clúster, el cual se incluye en el título de proceso." -#: utils/misc/guc.c:3633 +#: utils/misc/guc.c:4196 msgid "Sets the WAL resource managers for which WAL consistency checks are done." -msgstr "" +msgstr "Define los gestores de recursos WAL para los cuales hacer verificaciones de consistencia WAL." -#: utils/misc/guc.c:3634 +#: utils/misc/guc.c:4197 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." -msgstr "" +msgstr "Se registrarán imágenes de página completa para todos los bloques de datos, y comparados con los resultados de la aplicación de WAL." + +#: utils/misc/guc.c:4207 +msgid "JIT provider to use." +msgstr "Proveedor JIT a usar." -#: utils/misc/guc.c:3653 +#: utils/misc/guc.c:4227 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "Define si «\\'» está permitido en literales de cadena." -#: utils/misc/guc.c:3663 +#: utils/misc/guc.c:4237 msgid "Sets the output format for bytea." msgstr "Formato de salida para bytea." -#: utils/misc/guc.c:3673 +#: utils/misc/guc.c:4247 msgid "Sets the message levels that are sent to the client." msgstr "Nivel de mensajes enviados al cliente." -#: utils/misc/guc.c:3674 utils/misc/guc.c:3727 utils/misc/guc.c:3738 -#: utils/misc/guc.c:3804 +#: utils/misc/guc.c:4248 utils/misc/guc.c:4313 utils/misc/guc.c:4324 +#: utils/misc/guc.c:4400 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "Cada nivel incluye todos los niveles que lo siguen. Mientras más posterior el nivel, menos mensajes se enviarán." -#: utils/misc/guc.c:3684 +#: utils/misc/guc.c:4258 msgid "Enables the planner to use constraints to optimize queries." msgstr "Permitir el uso de restricciones para limitar los accesos a tablas." -#: utils/misc/guc.c:3685 +#: utils/misc/guc.c:4259 msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "Las tablas no serán recorridas si sus restricciones garantizan que ninguna fila coincidirá con la consulta." -#: utils/misc/guc.c:3695 +#: utils/misc/guc.c:4270 msgid "Sets the transaction isolation level of each new transaction." msgstr "Nivel de aislación (isolation level) de transacciones nuevas." -#: utils/misc/guc.c:3705 +#: utils/misc/guc.c:4280 +msgid "Sets the current transaction's isolation level." +msgstr "Define el nivel de aislación de la transacción en curso." + +#: utils/misc/guc.c:4291 msgid "Sets the display format for interval values." msgstr "Formato de salida para valores de intervalos." -#: utils/misc/guc.c:3716 +#: utils/misc/guc.c:4302 msgid "Sets the verbosity of logged messages." msgstr "Verbosidad de los mensajes registrados." -#: utils/misc/guc.c:3726 +#: utils/misc/guc.c:4312 msgid "Sets the message levels that are logged." msgstr "Nivel de mensajes registrados." -#: utils/misc/guc.c:3737 +#: utils/misc/guc.c:4323 msgid "Causes all statements generating error at or above this level to be logged." msgstr "Registrar sentencias que generan error de nivel superior o igual a éste." -#: utils/misc/guc.c:3748 +#: utils/misc/guc.c:4334 msgid "Sets the type of statements logged." msgstr "Define el tipo de sentencias que se registran." -#: utils/misc/guc.c:3758 +#: utils/misc/guc.c:4344 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "«Facility» de syslog que se usará cuando syslog esté habilitado." -#: utils/misc/guc.c:3773 +#: utils/misc/guc.c:4359 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "Define el comportamiento de la sesión con respecto a disparadores y reglas de reescritura." -#: utils/misc/guc.c:3783 +#: utils/misc/guc.c:4369 msgid "Sets the current transaction's synchronization level." msgstr "Define el nivel de sincronización de la transacción en curso." -#: utils/misc/guc.c:3793 +#: utils/misc/guc.c:4379 msgid "Allows archiving of WAL files using archive_command." msgstr "Permite el archivado de WAL usando archive_command." -#: utils/misc/guc.c:3803 +#: utils/misc/guc.c:4389 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Acción a ejecutar al alcanzar el destino de recuperación." + +#: utils/misc/guc.c:4399 msgid "Enables logging of recovery-related debugging information." msgstr "Recolectar información de depuración relacionada con la recuperación." -#: utils/misc/guc.c:3819 +#: utils/misc/guc.c:4415 msgid "Collects function-level statistics on database activity." msgstr "Recolectar estadísticas de actividad de funciones en la base de datos." -#: utils/misc/guc.c:3829 +#: utils/misc/guc.c:4425 msgid "Set the level of information written to the WAL." msgstr "Nivel de información escrita a WAL." -#: utils/misc/guc.c:3839 +#: utils/misc/guc.c:4435 msgid "Selects the dynamic shared memory implementation used." msgstr "Escoge la implementación de memoria compartida dinámica que se usará." -#: utils/misc/guc.c:3849 +#: utils/misc/guc.c:4445 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Escoge la implementación de memoria compartida dinámica que se usará para la región principal de memoria compartida." + +#: utils/misc/guc.c:4455 msgid "Selects the method used for forcing WAL updates to disk." msgstr "Selecciona el método usado para forzar escritura de WAL a disco." -#: utils/misc/guc.c:3859 +#: utils/misc/guc.c:4465 msgid "Sets how binary values are to be encoded in XML." msgstr "Define cómo se codificarán los valores binarios en XML." -#: utils/misc/guc.c:3869 +#: utils/misc/guc.c:4475 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "Define si los datos XML implícitos en operaciones de análisis y serialización serán considerados documentos o fragmentos de contenido." -#: utils/misc/guc.c:3880 -msgid "Use of huge pages on Linux." -msgstr "Uso de «huge pages» en Linux." +#: utils/misc/guc.c:4486 +msgid "Use of huge pages on Linux or Windows." +msgstr "Usar páginas grandes (huge) en Linux o Windows." -#: utils/misc/guc.c:3890 +#: utils/misc/guc.c:4496 msgid "Forces use of parallel query facilities." msgstr "Obliga al uso de la funcionalidad de consultas paralelas." -#: utils/misc/guc.c:3891 +#: utils/misc/guc.c:4497 msgid "If possible, run query using a parallel worker and with parallel restrictions." -msgstr "Si es posible, ejecuta cada consulta en un proceso trabajador paralelo y con restricciones de paralelismo." +msgstr "Si es posible, ejecuta cada consulta en un ayudante paralelo y con restricciones de paralelismo." -#: utils/misc/guc.c:3900 +#: utils/misc/guc.c:4507 msgid "Encrypt passwords." msgstr "Cifrar contraseñas." -#: utils/misc/guc.c:3901 +#: utils/misc/guc.c:4508 msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." msgstr "Cuando se entrega una contraseña en CREATE USER o ALTER USER sin especificar ENCRYPTED ni UNENCRYPTED, esta opción determina si la password deberá ser encriptada." -#: utils/misc/guc.c:4703 +#: utils/misc/guc.c:4519 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Controla la selección del optimizador de planes genéricos o «custom»." + +#: utils/misc/guc.c:4520 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Las sentencias preparadas pueden tener planes genéricos y «custom», y el optimizador intentará escoger cuál es mejor. Esto puede usarse para controlar manualmente el comportamiento." + +#: utils/misc/guc.c:4532 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Define la versión mínima del protocolo SSL/TLS a usar." + +#: utils/misc/guc.c:4544 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Define la versión máxima del protocolo SSL/TLS a usar." + +#: utils/misc/guc.c:5367 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" -#: utils/misc/guc.c:4708 +#: utils/misc/guc.c:5372 #, c-format msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" msgstr "Ejecute initdb o pg_basebackup para inicializar un directorio de datos de PostgreSQL.\n" -#: utils/misc/guc.c:4728 +#: utils/misc/guc.c:5392 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -24695,12 +25648,12 @@ msgstr "" "%s no sabe dónde encontrar el archivo de configuración del servidor.\n" "Debe especificar la opción --config-file o -D o definir la variable de ambiente PGDATA.\n" -#: utils/misc/guc.c:4747 +#: utils/misc/guc.c:5411 #, c-format msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s: no se pudo acceder al archivo de configuración «%s»: %s\n" -#: utils/misc/guc.c:4773 +#: utils/misc/guc.c:5437 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -24709,7 +25662,7 @@ msgstr "" "%s no sabe dónde encontrar los archivos de sistema de la base de datos.\n" "Esto puede especificarse como «data_directory» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" -#: utils/misc/guc.c:4821 +#: utils/misc/guc.c:5485 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -24718,7 +25671,7 @@ msgstr "" "%s no sabe dónde encontrar el archivo de configuración «hba».\n" "Esto puede especificarse como «hba_file» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" -#: utils/misc/guc.c:4844 +#: utils/misc/guc.c:5508 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -24727,154 +25680,186 @@ msgstr "" "%s no sabe dónde encontrar el archivo de configuración «ident».\n" "Esto puede especificarse como «ident_file» en «%s», o usando la opción -D, o a través de la variable de ambiente PGDATA.\n" -#: utils/misc/guc.c:5518 utils/misc/guc.c:5565 +#: utils/misc/guc.c:6350 msgid "Value exceeds integer range." msgstr "El valor excede el rango para enteros." -#: utils/misc/guc.c:5788 +#: utils/misc/guc.c:6586 #, c-format -msgid "parameter \"%s\" requires a numeric value" -msgstr "el parámetro «%s» requiere un valor numérico" +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s está fuera del rango aceptable para el parámetro «%s» (%d .. %d)" -#: utils/misc/guc.c:5797 +#: utils/misc/guc.c:6622 #, c-format -msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" -msgstr "%g está fuera del rango aceptable para el parámetro «%s» (%g .. %g)" +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s está fuera del rango aceptable para el parámetro «%s» (%g .. %g)" -#: utils/misc/guc.c:5950 utils/misc/guc.c:7296 +#: utils/misc/guc.c:6778 utils/misc/guc.c:8148 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "no se puede definir parámetros durante una operación paralela" -#: utils/misc/guc.c:5957 utils/misc/guc.c:6708 utils/misc/guc.c:6761 -#: utils/misc/guc.c:7124 utils/misc/guc.c:7883 utils/misc/guc.c:8051 -#: utils/misc/guc.c:9727 +#: utils/misc/guc.c:6785 utils/misc/guc.c:7537 utils/misc/guc.c:7590 +#: utils/misc/guc.c:7641 utils/misc/guc.c:7977 utils/misc/guc.c:8744 +#: utils/misc/guc.c:9010 utils/misc/guc.c:10648 #, c-format msgid "unrecognized configuration parameter \"%s\"" -msgstr "parámetro de configuración no reconocido: «%s»" +msgstr "parámetro de configuración «%s» no reconocido" -#: utils/misc/guc.c:5972 utils/misc/guc.c:7136 +#: utils/misc/guc.c:6800 utils/misc/guc.c:7989 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "no se puede cambiar el parámetro «%s»" -#: utils/misc/guc.c:6005 +#: utils/misc/guc.c:6823 utils/misc/guc.c:7017 utils/misc/guc.c:7107 +#: utils/misc/guc.c:7197 utils/misc/guc.c:7305 utils/misc/guc.c:7400 +#: guc-file.l:353 #, c-format -msgid "parameter \"%s\" cannot be changed now" -msgstr "el parámetro «%s» no se puede cambiar en este momento" +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "el parámetro «%s» no se puede cambiar sin reiniciar el servidor" -#: utils/misc/guc.c:6023 utils/misc/guc.c:6069 utils/misc/guc.c:9743 +#: utils/misc/guc.c:6833 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "el parámetro «%s» no se puede cambiar en este momento" + +#: utils/misc/guc.c:6851 utils/misc/guc.c:6898 utils/misc/guc.c:10664 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "se ha denegado el permiso para cambiar la opción «%s»" -#: utils/misc/guc.c:6059 +#: utils/misc/guc.c:6888 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "el parámetro «%s» no se puede cambiar después de efectuar la conexión" -#: utils/misc/guc.c:6107 +#: utils/misc/guc.c:6936 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "no se puede definir el parámetro «%s» dentro una función security-definer" -#: utils/misc/guc.c:6716 utils/misc/guc.c:6766 utils/misc/guc.c:8058 -#, fuzzy, c-format +#: utils/misc/guc.c:7545 utils/misc/guc.c:7595 utils/misc/guc.c:9017 +#, c-format msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" -msgstr "debe ser superusuario para examinar «%s»" +msgstr "debe ser superusuario o miembro del rol pg_read_all settings para examinar «%s»" -#: utils/misc/guc.c:6833 +#: utils/misc/guc.c:7686 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s lleva sólo un argumento" -#: utils/misc/guc.c:7084 +#: utils/misc/guc.c:7937 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" -msgstr "debe ser superusuario ejecutar la orden ALTER SYSTEM" +msgstr "debe ser superusuario para ejecutar la orden ALTER SYSTEM" -#: utils/misc/guc.c:7169 +#: utils/misc/guc.c:8022 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "los valores de parámetros para ALTER SYSTEM no deben contener saltos de línea" -#: utils/misc/guc.c:7214 +#: utils/misc/guc.c:8067 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "no se pudo interpretar el contenido del archivo «%s»" -#: utils/misc/guc.c:7372 +#: utils/misc/guc.c:8224 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT no está implementado" -#: utils/misc/guc.c:7456 +#: utils/misc/guc.c:8308 #, c-format msgid "SET requires parameter name" msgstr "SET requiere el nombre de un parámetro" -#: utils/misc/guc.c:7580 +#: utils/misc/guc.c:8441 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "intento de cambiar la opción «%s»" -#: utils/misc/guc.c:9360 +#: utils/misc/guc.c:10281 #, c-format msgid "parameter \"%s\" could not be set" msgstr "no se pudo cambiar el parámetro «%s»" -#: utils/misc/guc.c:9447 +#: utils/misc/guc.c:10368 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "no se pudo interpretar el valor de para el parámetro «%s»" -#: utils/misc/guc.c:9805 utils/misc/guc.c:9839 +#: utils/misc/guc.c:10726 utils/misc/guc.c:10760 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "valor no válido para el parámetro «%s»: %d" -#: utils/misc/guc.c:9873 +#: utils/misc/guc.c:10794 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "valor no válido para el parámetro «%s»: %g" -#: utils/misc/guc.c:10143 +#: utils/misc/guc.c:11064 #, c-format msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." msgstr "«temp_buffers» no puede ser cambiado después de que cualquier tabla temporal haya sido accedida en la sesión." -#: utils/misc/guc.c:10155 +#: utils/misc/guc.c:11076 #, c-format msgid "Bonjour is not supported by this build" msgstr "Bonjour no está soportado en este servidor" -#: utils/misc/guc.c:10168 +#: utils/misc/guc.c:11089 #, c-format msgid "SSL is not supported by this build" msgstr "SSL no está soportado en este servidor" -#: utils/misc/guc.c:10180 +#: utils/misc/guc.c:11101 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "No se puede activar el parámetro cuando «log_statement_stats» está activo." -#: utils/misc/guc.c:10192 +#: utils/misc/guc.c:11113 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "No se puede activar «log_statement_stats» cuando «log_parser_stats», «log_planner_stats» o «log_executor_stats» están activos." -#: utils/misc/help_config.c:131 +#: utils/misc/guc.c:11357 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency debe ser 0 en plataformas que no tienen posix_fadvise()." + +#: utils/misc/guc.c:11471 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline no es un número válido." + +#: utils/misc/guc.c:11511 +#, c-format +msgid "multiple recovery targets specified" +msgstr "múltiples valores de destino de recuperación especificados" + +#: utils/misc/guc.c:11512 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "A lo más uno de recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid puede estar definido." + +#: utils/misc/guc.c:11520 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "El único valor permitido es «immediate»." + +#: utils/misc/help_config.c:130 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "error interno: tipo parámetro no reconocido\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format msgid "query-specified return tuple and function return type are not compatible" msgstr "tupla de retorno especificada por la consulta y el tipo retornado por la función no son compatibles" -#: utils/misc/pg_controldata.c:58 utils/misc/pg_controldata.c:138 -#: utils/misc/pg_controldata.c:244 utils/misc/pg_controldata.c:311 +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:242 utils/misc/pg_controldata.c:309 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "la suma de verificación calculada no coincide con el valor almacenado en el archivo" @@ -24882,14 +25867,14 @@ msgstr "la suma de verificación calculada no coincide con el valor almacenado e #: utils/misc/pg_rusage.c:64 #, c-format msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" -msgstr "" +msgstr "CPU: usuario: %d.%02d s, sistema: %d.%02d s, transcurrido: %d.%02d s" -#: utils/misc/rls.c:128 +#: utils/misc/rls.c:127 #, c-format msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "la consulta sería afectada por la política de seguridad de registros para la tabla «%s»" -#: utils/misc/rls.c:130 +#: utils/misc/rls.c:129 #, c-format msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "Para desactivar la política para el dueño de la tabla, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." @@ -24964,75 +25949,98 @@ msgstr "línea demasiado larga en archivo de huso horario «%s», línea %d" msgid "@INCLUDE without file name in time zone file \"%s\", line %d" msgstr "@INCLUDE sin nombre de archivo en archivo de huso horario «%s», línea %d" -#: utils/mmgr/aset.c:405 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "Falla al crear el contexto de memoria «%s»." -#: utils/mmgr/dsa.c:518 utils/mmgr/dsa.c:1323 -#, fuzzy, c-format +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format msgid "could not attach to dynamic shared area" -msgstr "no se pudo mapear el segmento de memoria compartida dinámica" +msgstr "no se pudo adjuntar al segmento de memoria compartida dinámica" -#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 -#, fuzzy, c-format -msgid "Failed on DSA request of size %zu." -msgstr "Falla en petición de tamaño %zu." - -#: utils/mmgr/mcxt.c:726 utils/mmgr/mcxt.c:761 utils/mmgr/mcxt.c:798 -#: utils/mmgr/mcxt.c:835 utils/mmgr/mcxt.c:869 utils/mmgr/mcxt.c:898 -#: utils/mmgr/mcxt.c:932 utils/mmgr/mcxt.c:983 utils/mmgr/mcxt.c:1017 -#: utils/mmgr/mcxt.c:1051 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 #, c-format -msgid "Failed on request of size %zu." -msgstr "Falla en petición de tamaño %zu." +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Falló una petición de tamaño %zu en el contexto de memoria «%s»." -#: utils/mmgr/portalmem.c:186 +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "el cursor «%s» ya existe" -#: utils/mmgr/portalmem.c:190 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "cerrando el cursor «%s» preexistente" -#: utils/mmgr/portalmem.c:394 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "el portal «%s» no puede ser ejecutado" -#: utils/mmgr/portalmem.c:474 +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "no se puede eliminar el portal «pinned» «%s»" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "no se puede eliminar el portal activo «%s»" -#: utils/mmgr/portalmem.c:678 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "no se puede hacer PREPARE de una transacción que ha creado un cursor WITH HOLD" -#: utils/sort/logtape.c:252 +#: utils/mmgr/portalmem.c:1269 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "no se pueden ejecutar órdenes de transacción dentro de un bucle de cursor que no es de sólo lectura" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "no se pudo leer el bloque %ld del archivo temporal: %m" -#: utils/sort/tuplesort.c:3072 +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "no se pudo escribir al archivo temporal: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "no se pudo leer desde el archivo temporal del tuplestore compartido" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "trozo inesperado en archivo temporal del tuplestore compartido" + +#: utils/sort/tuplesort.c:2967 #, c-format msgid "cannot have more than %d runs for an external sort" msgstr "no se pueden tener más de %d pasadas para un ordenamiento externo" -#: utils/sort/tuplesort.c:4141 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "no se pudo crear el índice único «%s»" -#: utils/sort/tuplesort.c:4143 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "La llave %s está duplicada." -#: utils/sort/tuplesort.c:4144 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "Existe una llave duplicada." @@ -25056,739 +26064,577 @@ msgstr "no se pudo leer el archivo temporal de tuplestore: %m" #: utils/sort/tuplestore.c:1529 #, c-format msgid "could not write to tuplestore temporary file: %m" -msgstr "no se pudo escribir el archivo temporal de tuplestore: %m" +msgstr "no se pudo escribir al archivo temporal de tuplestore: %m" -#: utils/time/snapmgr.c:622 +#: utils/time/snapmgr.c:624 #, c-format msgid "The source transaction is not running anymore." msgstr "La transacción de origen ya no está en ejecución." -#: utils/time/snapmgr.c:1200 +#: utils/time/snapmgr.c:1202 #, c-format msgid "cannot export a snapshot from a subtransaction" msgstr "no se puede exportar snapshots desde una subtransacción" -#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 -#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 -#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 -#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 -#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 -#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 +#: utils/time/snapmgr.c:1361 utils/time/snapmgr.c:1366 +#: utils/time/snapmgr.c:1371 utils/time/snapmgr.c:1386 +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1411 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1523 +#: utils/time/snapmgr.c:1539 utils/time/snapmgr.c:1564 #, c-format msgid "invalid snapshot data in file \"%s\"" msgstr "datos no válidos en archivo de snapshot «%s»" -#: utils/time/snapmgr.c:1456 +#: utils/time/snapmgr.c:1458 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "SET TRANSACTION SNAPSHOT debe ser llamado antes de cualquier consulta" -#: utils/time/snapmgr.c:1465 +#: utils/time/snapmgr.c:1467 #, c-format msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" msgstr "una transacción que importa un snapshot no debe tener nivel de aislación SERIALIZABLE o REPEATABLE READ" -#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 +#: utils/time/snapmgr.c:1476 utils/time/snapmgr.c:1485 #, c-format msgid "invalid snapshot identifier: \"%s\"" msgstr "identificador de snapshot no válido: «%s»" -#: utils/time/snapmgr.c:1573 +#: utils/time/snapmgr.c:1577 #, c-format msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" msgstr "una transacción serializable no puede importar un snapshot desde una transacción no serializable" -#: utils/time/snapmgr.c:1577 +#: utils/time/snapmgr.c:1581 #, c-format msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" msgstr "una transacción serializable que no es de sólo lectura no puede importar un snapshot de una transacción de sólo lectura" -#: utils/time/snapmgr.c:1592 +#: utils/time/snapmgr.c:1596 #, c-format msgid "cannot import a snapshot from a different database" msgstr "no se puede importar un snapshot desde una base de datos diferente" -#~ msgid "" -#~ "WARNING: Calculated CRC checksum does not match value stored in file.\n" -#~ "Either the file is corrupt, or it has a different layout than this program\n" -#~ "is expecting. The results below are untrustworthy.\n" -#~ "\n" -#~ msgstr "" -#~ "ATENCIÓN: La suma de verificación calculada no coincide con el valor\n" -#~ "almacenado en el archivo. Puede ser que el archivo esté corrupto, o\n" -#~ "bien tiene una estructura diferente de la que este programa está\n" -#~ "esperando. Los resultados presentados a continuación no son confiables.\n" -#~ "\n" - -#~ msgid "could not open transaction log file \"%s\": %m" -#~ msgstr "no se pudo abrir el archivo de registro de transacciones «%s»: %m" - -#~ msgid "could not remove old transaction log file \"%s\": %m" -#~ msgstr "no se pudo eliminar el archivo antiguo de registro de transacciones «%s»: %m" - -#~ msgid "removing transaction log backup history file \"%s\"" -#~ msgstr "eliminando el archivo de historia del respaldo de registro de transacciones «%s»" - -#~ msgid "The database cluster was initialized without HAVE_INT64_TIMESTAMP but the server was compiled with HAVE_INT64_TIMESTAMP." -#~ msgstr "Los archivos de la base de datos fueron inicializados sin HAVE_INT64_TIMESTAMP, pero el servidor fue compilado con HAVE_INT64_TIMESTAMP." - -#~ msgid "The database cluster was initialized with HAVE_INT64_TIMESTAMP but the server was compiled without HAVE_INT64_TIMESTAMP." -#~ msgstr "Los archivos de la base de datos fueron inicializados con HAVE_INT64_TIMESTAMP, pero el servidor fue compilado sin HAVE_INT64_TIMESTAMP." - -#~ msgid "invalid privilege type USAGE for table" -#~ msgstr "el tipo de privilegio USAGE no es válido para tablas" - -#~ msgid "column \"%s\" has type \"unknown\"" -#~ msgstr "la columna «%s» tiene tipo «unknown» (desconocido)" - -#~ msgid "Proceeding with relation creation anyway." -#~ msgstr "Continuando con la creación de la relación de todas maneras." - -#~ msgid "default expression must not return a set" -#~ msgstr "expresiones default no pueden retornar conjuntos" - -#~ msgid "database name cannot be qualified" -#~ msgstr "un nombre de base de datos no puede ser calificado" - -#~ msgid "extension name cannot be qualified" -#~ msgstr "un nombre de extensión no puede ser calificado" - -#~ msgid "tablespace name cannot be qualified" -#~ msgstr "un nombre de tablespace no puede ser calificado" - -#~ msgid "role name cannot be qualified" -#~ msgstr "un nombre de rol no puede ser calificado" - -#~ msgid "schema name cannot be qualified" -#~ msgstr "un nombre de esquema no puede ser calificado" - -#~ msgid "language name cannot be qualified" -#~ msgstr "un nombre de lenguaje no puede ser calificado" - -#~ msgid "foreign-data wrapper name cannot be qualified" -#~ msgstr "un nombre de conector de datos externos no puede ser calificado" - -#~ msgid "server name cannot be qualified" -#~ msgstr "un nombre de servidor no puede ser calificado" - -#~ msgid "event trigger name cannot be qualified" -#~ msgstr "un nombre de disparador por eventos no puede ser calificado" - -#~ msgid "changing return type of function %s from \"opaque\" to \"language_handler\"" -#~ msgstr "cambiando el tipo de retorno de la función %s de «opaque» a «language_handler»" - -#~ msgid "changing return type of function %s from \"opaque\" to \"trigger\"" -#~ msgstr "cambiando el tipo de retorno de la función %s de «opaque» a «trigger»" - -#~ msgid "functions and operators can take at most one set argument" -#~ msgstr "las funciones y operadores pueden tomar a lo más un argumento que sea un conjunto" - -#~ msgid "IS DISTINCT FROM does not support set arguments" -#~ msgstr "IS DISTINCT FROM no soporta argumentos que sean conjuntos" - -#~ msgid "op ANY/ALL (array) does not support set arguments" -#~ msgstr "op ANY/ALL (array) no soporta argumentos que sean conjuntos" - -#~ msgid "NULLIF does not support set arguments" -#~ msgstr "NULLIF no soporta argumentos que sean conjuntos" - -#~ msgid "hostssl requires SSL to be turned on" -#~ msgstr "hostssl requiere que SSL esté activado" - -#~ msgid "could not create %s socket: %m" -#~ msgstr "no se pudo crear el socket %s: %m" - -#~ msgid "could not bind %s socket: %m" -#~ msgstr "no se pudo enlazar al socket %s: %m" - -#~ msgid "DEFAULT can only appear in a VALUES list within INSERT" -#~ msgstr "DEFAULT sólo puede aparecer en listas VALUES dentro de un INSERT" - -#~ msgid "argument of %s must be type boolean, not type %s" -#~ msgstr "el argumento de %s debe ser de tipo boolean, no tipo %s" - -#~ msgid "index expression cannot return a set" -#~ msgstr "las expresiones de índice no pueden retornar conjuntos" - -#~ msgid "transform expression must not return a set" -#~ msgstr "la expresión de transformación no puede retornar conjuntos" - -#~ msgid "huge TLB pages not supported on this platform" -#~ msgstr "las «huge TLB pages» no están soportadas en esta plataforma" - -#~ msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" -#~ msgstr "autovacuum: se encontró una tabla temporal huérfana «%s».«%s» en la base de datos «%s»" - -#~ msgid "transaction log switch forced (archive_timeout=%d)" -#~ msgstr "cambio forzado de registro de transacción (archive_timeout=%d)" - -#~ msgid "archived transaction log file \"%s\"" -#~ msgstr "el archivo de registro «%s» ha sido archivado" - -#~ msgid "syntax error: unexpected character \"%s\"" -#~ msgstr "error de sintaxis: carácter «%s» inesperado" - -#~ msgid "select() failed: %m" -#~ msgstr "select() fallida: %m" - -#~ msgid "Transaction ID %u finished; no more running transactions." -#~ msgstr "La transacción de ID %u terminó: no hay más transacciones en ejecución." - -#~ msgid "%u transaction needs to finish." -#~ msgid_plural "%u transactions need to finish." -#~ msgstr[0] "%u transacción debe terminar." -#~ msgstr[1] "%u transacciones deben terminar." - -#~ msgid "rule \"%s\" does not exist" -#~ msgstr "no existe la regla «%s»" - -#~ msgid "there are multiple rules named \"%s\"" -#~ msgstr "hay múltiples reglas llamadas «%s»" - -#~ msgid "Specify a relation name as well as a rule name." -#~ msgstr "Especifique un nombre de relación además del nombre de regla." - -#~ msgid "not enough shared memory for elements of data structure \"%s\" (%zu bytes requested)" -#~ msgstr "el espacio de memoria compartida es insuficiente para los elementos de la estructura «%s» (%zu bytes solicitados)" - -#~ msgid "wrong range of array subscripts" -#~ msgstr "rango incorrecto en los subíndices del array" - -#~ msgid "Lower bound of dimension array must be one." -#~ msgstr "El límite inferior del array de dimensiones debe ser uno." - -#~ msgid "invalid input syntax for type boolean: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo boolean: «%s»" - -#~ msgid "invalid input syntax for type money: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo money: «%s»" - -#~ msgid "invalid input syntax for type bytea" -#~ msgstr "sintaxis de entrada no válida para tipo bytea" - -#~ msgid "invalid input syntax for type real: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo real: «%s»" - -#~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" -#~ msgstr "los patrones de formato «TZ»/«tz»/«OF» no están soportados en to_date" - -#~ msgid "invalid input syntax for integer: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para integer: «%s»" - -#~ msgid "value \"%s\" is out of range for type bigint" -#~ msgstr "el valor «%s» está fuera de rango para el tipo bigint" - -#~ msgid "invalid input syntax for type macaddr: \"%s\"" -#~ msgstr "sintaxis de entrada no válida para tipo macaddr: «%s»" - -#~ msgid "invalid input syntax for type tinterval: \"%s\"" -#~ msgstr "sintaxis de entrada no válida para el tipo tinterval: «%s»" - -#~ msgid "invalid input syntax for type numeric: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para el tipo numeric: «%s»" - -#~ msgid "invalid input syntax for type double precision: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo double precision: «%s»" - -#~ msgid "value \"%s\" is out of range for type integer" -#~ msgstr "el valor «%s» está fuera de rango para el tipo integer" - -#~ msgid "value \"%s\" is out of range for type smallint" -#~ msgstr "el valor «%s» está fuera de rango para el tipo smallint" - -#~ msgid "invalid input syntax for type oid: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para el tipo oid: «%s»" - -#~ msgid "nondefault collations are not supported on this platform" -#~ msgstr "los ordenamientos (collation) distintos del ordenamiento por omisión no están soportados en esta plataforma" - -#~ msgid "invalid input syntax for type pg_lsn: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo pg_lsn: «%s»" - -#~ msgid "cannot accept a value of type any" -#~ msgstr "no se puede aceptar un valor de tipo any" - -#~ msgid "cannot accept a value of type anyarray" -#~ msgstr "no se puede aceptar un valor de tipo anyarray" - -#~ msgid "cannot accept a value of type anyenum" -#~ msgstr "no se puede aceptar un valor de tipo anyenum" - -#~ msgid "cannot accept a value of type anyrange" -#~ msgstr "no se puede aceptar un valor de tipo anyrange" - -#~ msgid "cannot accept a value of type trigger" -#~ msgstr "no se puede aceptar un valor de tipo trigger" - -#~ msgid "cannot display a value of type trigger" -#~ msgstr "no se puede desplegar un valor de tipo trigger" - -#~ msgid "cannot accept a value of type event_trigger" -#~ msgstr "no se puede aceptar un valor de tipo event_trigger" - -#~ msgid "cannot display a value of type event_trigger" -#~ msgstr "no se puede desplegar un valor de tipo event_trigger" - -#~ msgid "cannot accept a value of type language_handler" -#~ msgstr "no se puede aceptar un valor de tipo language_handler" - -#~ msgid "cannot display a value of type language_handler" -#~ msgstr "no se puede desplegar un valor de tipo language_handler" - -#~ msgid "cannot accept a value of type fdw_handler" -#~ msgstr "no se puede aceptar un valor de tipo fdw_handler" - -#~ msgid "cannot display a value of type fdw_handler" -#~ msgstr "no se puede desplegar un valor de tipo fdw_handler" - -#~ msgid "cannot accept a value of type internal" -#~ msgstr "no se puede aceptar un valor de tipo internal" - -#~ msgid "cannot display a value of type internal" -#~ msgstr "no se puede desplegar un valor de tipo internal" - -#~ msgid "cannot accept a value of type opaque" -#~ msgstr "no se puede aceptar un valor de tipo opaque" - -#~ msgid "cannot display a value of type opaque" -#~ msgstr "no se puede desplegar un valor de tipo opaque" - -#~ msgid "cannot accept a value of type anyelement" -#~ msgstr "no se puede aceptar un valor de tipo anyelement" - -#~ msgid "cannot display a value of type anyelement" -#~ msgstr "no se puede desplegar un valor de tipo anyelement" - -#~ msgid "cannot accept a value of type anynonarray" -#~ msgstr "no se puede aceptar un valor de tipo anynonarray" - -#~ msgid "cannot display a value of type anynonarray" -#~ msgstr "no se puede desplegar un valor de tipo anynonarray" - -#~ msgid "invalid input syntax for type tid: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo tid: «%s»" - -#~ msgid "invalid input syntax for uuid: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para el tipo uuid: «%s»" - -#~ msgid "function %u has too many arguments (%d, maximum is %d)" -#~ msgstr "la función %u tiene demasiados argumentos (%d, el máximo es %d)" - -#~ msgid "Causes subtables to be included by default in various commands." -#~ msgstr "Incluir, por omisión, subtablas en varias órdenes." - -#~ msgid "mapped win32 error code %lu to %d" -#~ msgstr "código de error win32 %lu mapeado a %d" - -#~ msgid "unrecognized win32 error code: %lu" -#~ msgstr "código de error win32 no reconocido: %lu" - -#~ msgid "could not create two-phase state file \"%s\": %m" -#~ msgstr "no se pudo crear el archivo de estado de COMMIT en dos fases «%s»: %m" - -#~ msgid "could not seek in two-phase state file: %m" -#~ msgstr "no se pudo posicionar (seek) en el archivo de estado de COMMIT en dos fases: %m" - -#~ msgid "two-phase state file for transaction %u is corrupt" -#~ msgstr "el archivo de estado de COMMIT en dos fases para la transacción %u está dañado" - -#~ msgid "could not fsync two-phase state file \"%s\": %m" -#~ msgstr "no se pudo sincronizar (fsync) el archivo de estado de COMMIT en dos fases «%s»: %m" - -#~ msgid "could not close two-phase state file \"%s\": %m" -#~ msgstr "no se pudo cerrar el archivo de estado de COMMIT en dos fases «%s»: %m" - -#~ msgid "could not link file \"%s\" to \"%s\" (initialization of log file): %m" -#~ msgstr "no se pudo enlazar (link) el archivo «%s» a «%s» (inicialización de archivo de registro): %m" - -#~ msgid "could not rename file \"%s\" to \"%s\" (initialization of log file): %m" -#~ msgstr "no se pudo renombrar archivo de «%s» a «%s» (inicialización de archivo de registro): %m" - -#~ msgid "invalid value for recovery parameter \"recovery_target\"" -#~ msgstr "valor no válido para el parámetro de recuperación «recovery_target»" - -#~ msgid "redo record is at %X/%X; shutdown %s" -#~ msgstr "registro de redo en %X/%X; apagado %s" - -#~ msgid "next transaction ID: %u/%u; next OID: %u" -#~ msgstr "siguiente ID de transacción: %u/%u; siguiente OID: %u" - -#~ msgid "next MultiXactId: %u; next MultiXactOffset: %u" -#~ msgstr "siguiente MultiXactId: %u; siguiente MultiXactOffset: %u" - -#~ msgid "oldest unfrozen transaction ID: %u, in database %u" -#~ msgstr "ID de transacción más antigua sin congelar: %u, en base de datos %u" - -#~ msgid "oldest MultiXactId: %u, in database %u" -#~ msgstr "MultiXactId más antiguo: %u, en base de datos %u" - -#~ msgid "must be superuser or replication role to run a backup" -#~ msgstr "debe ser superusuario o el rol de replicación para ejecutar un respaldo" - -#~ msgid "must be superuser to switch transaction log files" -#~ msgstr "debe ser superusuario para cambiar a un nuevo archivo de registro" - -#~ msgid "must be superuser to create a restore point" -#~ msgstr "debe ser superusuario para crear un punto de recuperación" - -#~ msgid "must be superuser to control recovery" -#~ msgstr "debe ser superusuario para controlar la recuperación" - -#~ msgid "%s is already in schema \"%s\"" -#~ msgstr "%s ya está en el esquema «%s»" - -#~ msgid "function \"%s\" must return type \"event_trigger\"" -#~ msgstr "la función «%s» debe retornar tipo «event_trigger»" - -#~ msgid "function %s must return type \"fdw_handler\"" -#~ msgstr "la función %s debe retornar tipo «fdw_handler»" - -#~ msgid "could not reposition held cursor" -#~ msgstr "no se pudo reposicionar cursor abierto" - -#~ msgid "function %s must return type \"language_handler\"" -#~ msgstr "la función %s debe retornar tipo «language_handler»" - -#~ msgid "\"%s\" is not a table, materialized view, composite type, or foreign table" -#~ msgstr "«%s» no es una tabla, vista materializada, tipo compuesto, o tabla foránea" - -#~ msgid "function %s must return type \"trigger\"" -#~ msgstr "la función %s debe retornar tipo «trigger»" +#: gram.y:1030 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD ya no está soportado" -#~ msgid "changing return type of function %s from \"opaque\" to \"cstring\"" -#~ msgstr "cambiando el tipo de retorno de la función %s de «opaque» a «cstring»" +#: gram.y:1031 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Quite UNENCRYPTED para almacenar la contraseña en su lugar en forma cifrada." -#~ msgid "type output function %s must return type \"cstring\"" -#~ msgstr "la función de salida %s del tipo debe retornar «cstring»" +#: gram.y:1093 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "opción de rol «%s» no reconocida" -#~ msgid "type send function %s must return type \"bytea\"" -#~ msgstr "la función de envío %s del tipo debe retornar «bytea»" +#: gram.y:1340 gram.y:1355 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS no puede incluir elementos de esquema" -#~ msgid "typmod_in function %s must return type \"integer\"" -#~ msgstr "la función typmod_in %s debe retornar tipo «integer»" +#: gram.y:1501 +#, c-format +msgid "current database cannot be changed" +msgstr "no se puede cambiar la base de datos activa" -#~ msgid "received password packet" -#~ msgstr "se recibió un paquete de clave" +#: gram.y:1625 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "el intervalo de huso horario debe ser HOUR o HOUR TO MINUTE" -#~ msgid "Permissions should be u=rw (0600) or less." -#~ msgstr "Los permisos deberían ser u=rw (0500) o menos." +#: gram.y:2143 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "el número de columna debe estar en el rango de 1 a %d" -#~ msgid "must be superuser to reset statistics counters" -#~ msgstr "debe ser superusuario para reinicializar los contadores de estadísticas" +#: gram.y:2675 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "la opción de secuencia «%s» no está soportado aquí" -#~ msgid "invalid value for parameter \"replication\"" -#~ msgstr "valor no válido para la opción «replication»" +#: gram.y:2704 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "el módulo para partición de hash fue especificado más de una vez" -#~ msgid "archive member \"%s\" too large for tar format" -#~ msgstr "el miembro de archivador «%s» es demasiado grande para el formato tar" +#: gram.y:2713 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "el remanentde para partición de hash fue especificado más de una vez" -#~ msgid "socket not open" -#~ msgstr "el socket no está abierto" +#: gram.y:2720 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "especificación de borde de partición hash «%s» no reconocida" -#~ msgid "multibyte flag character is not allowed" -#~ msgstr "los caracteres bandera multibyte no están permitidos" +#: gram.y:2728 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "el módulo para una partición hash debe ser especificado" -#~ msgid "could not format \"path\" value" -#~ msgstr "no se pudo dar formato a «path»" +#: gram.y:2732 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "remanente en partición hash debe ser especificado" -#~ msgid "invalid input syntax for type box: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo box: «%s»" +#: gram.y:2933 gram.y:2966 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT no están permitidos con PROGRAM" -#~ msgid "invalid input syntax for type line: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo line: «%s»" +#: gram.y:2939 +#, c-format +msgid "WHERE clause not allowed with COPY TO" +msgstr "la cláusula WHERE no está permitida con COPY TO" -#~ msgid "invalid input syntax for type path: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo «path»: «%s»" +#: gram.y:3271 gram.y:3278 gram.y:11480 gram.y:11488 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL está obsoleto para la creación de tablas temporales" -#~ msgid "invalid input syntax for type point: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo point: «%s»" +#: gram.y:3518 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "para una columna generada, GENERATED ALWAYS debe ser especificado" -#~ msgid "invalid input syntax for type lseg: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo lseg: «%s»" +#: gram.y:5274 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "opción de seguridad de registro «%s» no reconocida" -#~ msgid "invalid input syntax for type polygon: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para tipo polygon: «%s»" +#: gram.y:5275 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "sólo se admiten actualmente políticas PERMISSIVE o RESTRICTIVE." -#~ msgid "invalid input syntax for type circle: \"%s\"" -#~ msgstr "la sintaxis de entrada no es válida para el tipo circle: «%s»" +#: gram.y:5388 +msgid "duplicate trigger events specified" +msgstr "se han especificado eventos de disparador duplicados" -#~ msgid "could not format \"circle\" value" -#~ msgstr "no se pudo dar formato al valor «circle»" +#: gram.y:5536 +#, c-format +msgid "conflicting constraint properties" +msgstr "propiedades de restricción contradictorias" -#~ msgid "must be superuser to signal the postmaster" -#~ msgstr "debe ser superusuario para enviar señales a postmaster" +#: gram.y:5632 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION no está implementado" -#~ msgid "must be superuser to rotate log files" -#~ msgstr "debe ser superusuario para rotar archivos de log" +#: gram.y:6015 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK ya no es requerido" -#~ msgid "argument for function \"exp\" too big" -#~ msgstr "el argumento a la función «exp» es demasiado grande" +#: gram.y:6016 +#, c-format +msgid "Update your data type." +msgstr "Actualice su tipo de datos." -#~ msgid "could not convert to time zone \"%s\"" -#~ msgstr "no se pudo convertir al huso horario «%s»" +#: gram.y:7753 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "las funciones de agregación no pueden tener argumentos de salida" -#~ msgid "WAL writer sleep time between WAL flushes." -#~ msgstr "Tiempo de descanso del escritor de WAL entre escrituras de WAL consecutivas." +#: gram.y:10025 gram.y:10043 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION no está soportado con vistas recursivas" -#~ msgid "=> is deprecated as an operator name" -#~ msgstr "=> es un nombre obsoleto de operador" +#: gram.y:11588 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "la sintaxis LIMIT #,# no está soportada" -#~ msgid "This name may be disallowed altogether in future versions of PostgreSQL." -#~ msgstr "Este nombre puede prohibirse por completo en futuras versiones de PostgreSQL." +#: gram.y:11589 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Use cláusulas LIMIT y OFFSET separadas." -#~ msgid "Specify a USING expression to perform the conversion." -#~ msgstr "Especifique una expresión USING para llevar a cabo la conversión." +#: gram.y:11887 gram.y:11912 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "VALUES en FROM debe tener un alias" -#~ msgid "" -#~ "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" -#~ "pages: %d removed, %d remain\n" -#~ "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" -#~ "buffer usage: %d hits, %d misses, %d dirtied\n" -#~ "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" -#~ "system usage: %s" -#~ msgstr "" -#~ "vacuum automático de la tabla «%s.%s.%s»: recorridos de índice: %d\n" -#~ "páginas: eliminadas %d, remanentes %d\n" -#~ "tuplas: eliminadas %.0f, remanentes %.0f, muertas pero sin eliminar aún %.0f\n" -#~ "uso de búfers: %d aciertos, %d fallas, %d ensuciados\n" -#~ "tasas promedio: de lectura: %.3f MB/s, de escritura %.3f MB/s\n" -#~ "uso del sistema: %s" +#: gram.y:11888 gram.y:11913 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Por ejemplo, FROM (VALUES ...) [AS] foo." -#~ msgid "" -#~ "%.0f dead row versions cannot be removed yet.\n" -#~ "There were %.0f unused item pointers.\n" -#~ "%u pages are entirely empty.\n" -#~ "%s." -#~ msgstr "" -#~ "%.0f versiones muertas de filas no pueden ser eliminadas aún.\n" -#~ "Hubo %.0f punteros de ítem sin uso.\n" -#~ "%u páginas están completamente vacías.\n" -#~ "%s." +#: gram.y:11893 gram.y:11918 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "las subconsultas en FROM deben tener un alias" -#~ msgid "SSL failure during renegotiation start" -#~ msgstr "fallo SSL durante el inicio de renegociación" +#: gram.y:11894 gram.y:11919 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Por ejemplo, FROM (SELECT ...) [AS] foo." -#~ msgid "SSL handshake failure on renegotiation, retrying" -#~ msgstr "fallo en el «handshake» durante la renegociación SSL, intentando de nuevo" +#: gram.y:12372 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "Sólo se permite un valor DEFAULT" -#~ msgid "could not complete SSL handshake on renegotiation, too many failures" -#~ msgstr "no se pudo completar el «handshake» durante la renegociación SSL, demasiados fallos" +#: gram.y:12381 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "sólo se permite un valor de PATH por columna" -#~ msgid "SSL failed to renegotiate connection before limit expired" -#~ msgstr "SSL no pudo renegociar conexión antes de la expiración del límite" +#: gram.y:12390 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "declaraciones NULL/NOT NULL en conflicto o redundantes para la columna «%s»" -#~ msgid "could not set socket to blocking mode: %m" -#~ msgstr "no se pudo poner el socket en modo bloqueante: %m" +#: gram.y:12399 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "opción de columna «%s» no reconocida" -#~ msgid "%s: setsysinfo failed: %s\n" -#~ msgstr "%s: setsysinfo falló: %s\n" +#: gram.y:12653 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "la precisión para el tipo float debe ser al menos 1 bit" -#~ msgid " -A 1|0 enable/disable run-time assert checking\n" -#~ msgstr " -A 1|0 activar/desactivar el uso de aseveraciones (asserts)\n" +#: gram.y:12662 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "la precisión para el tipo float debe ser menor de 54 bits" -#~ msgid "subquery must return a column" -#~ msgstr "la subconsulta debe retornar una columna" +#: gram.y:13153 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "el número de parámetros es incorrecto al lado izquierdo de la expresión OVERLAPS" -#~ msgid "Consider increasing the configuration parameter \"checkpoint_segments\"." -#~ msgstr "Considere incrementar el parámetro de configuración «checkpoint_segments»." +#: gram.y:13158 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "el número de parámetros es incorrecto al lado derecho de la expresión OVERLAPS" -#~ msgid "WAL archival (archive_mode=on) requires wal_level \"archive\", \"hot_standby\", or \"logical\"" -#~ msgstr "el archivado de WAL (archive_mode=on) requiere wal_level «archive» o «hot_standby» o «logical»" +#: gram.y:13333 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "el predicado UNIQUE no está implementado" -#~ msgid "could not determine input data types" -#~ msgstr "no se pudo determinar el tipo de datos de entrada" +#: gram.y:13680 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "no se permiten múltiples cláusulas ORDER BY con WITHIN GROUP" -#~ msgid "neither input type is an array" -#~ msgstr "ninguno de los tipos de entrada es un array" +#: gram.y:13685 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "no se permite DISTINCT con WITHIN GROUP" -#~ msgid "unexpected \"=\"" -#~ msgstr "«=» inesperado" +#: gram.y:13690 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "no se permite VARIADIC con WITHIN GROUP" -#~ msgid "invalid symbol" -#~ msgstr "símbolo no válido" +#: gram.y:14148 gram.y:14171 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "el inicio de «frame» no puede ser UNBOUNDED FOLLOWING" -#~ msgid "JSON does not support infinite date values." -#~ msgstr "JSON no soporta valores infinitos de fecha." +#: gram.y:14153 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "el «frame» que se inicia desde la siguiente fila no puede terminar en la fila actual" -#~ msgid "JSON does not support infinite timestamp values." -#~ msgstr "JSON no soporta valores infinitos de timestamp." +#: gram.y:14176 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "el fin de «frame» no puede ser UNBOUNDED PRECEDING" -#~ msgid "cannot accept a value of type pg_node_tree" -#~ msgstr "no se puede aceptar un valor de tipo pg_node_tree" +#: gram.y:14182 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "el «frame» que se inicia desde la fila actual no puede tener filas precedentes" -#~ msgid "Turns on various assertion checks." -#~ msgstr "Activar varios chequeos de integridad (assertion checks)." +#: gram.y:14189 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "el «frame» que se inicia desde la fila siguiente no puede tener filas precedentes" -#~ msgid "This is a debugging aid." -#~ msgstr "Esto es una ayuda para la depuración." +#: gram.y:14832 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "el modificador de tipo no puede tener nombre de parámetro" -#~ msgid "This parameter doesn't do anything." -#~ msgstr "Este parámetro no hace nada." +#: gram.y:14838 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "el modificador de tipo no puede tener ORDER BY" -#~ msgid "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients." -#~ msgstr "Está aquí sólo para poder aceptar SET AUTOCOMMIT TO ON desde clientes de la línea 7.3." +#: gram.y:14903 gram.y:14910 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s no puede ser usado como nombre de rol aquí" -#~ msgid "Sets the maximum distance in log segments between automatic WAL checkpoints." -#~ msgstr "Define la distancia máxima, en cantidad de segmentos, entre puntos de control de WAL automáticos." +#: gram.y:15583 gram.y:15772 +msgid "improper use of \"*\"" +msgstr "uso impropio de «*»" -#~ msgid "Set the amount of traffic to send and receive before renegotiating the encryption keys." -#~ msgstr "Define la cantidad de tráfico a enviar y recibir antes de renegociar las llaves de cifrado." +#: gram.y:15836 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "una agregación de conjunto-ordenado con un argumento directo VARIADIC debe tener al menos un argumento agregado VARIADIC del mismo tipo de datos" -#~ msgid "assertion checking is not supported by this build" -#~ msgstr "la revisión de aseveraciones (asserts) no está soportada en este servidor" +#: gram.y:15873 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "no se permiten múltiples cláusulas ORDER BY" -#~ msgid "interval precision specified twice" -#~ msgstr "la precisión de interval fue especificada dos veces" +#: gram.y:15884 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "no se permiten múltiples cláusulas OFFSET" -#~ msgid "too few arguments for format" -#~ msgstr "muy pocos argumentos para el formato" +#: gram.y:15893 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "no se permiten múltiples cláusulas LIMIT" -#~ msgid "invalid length in external \"numeric\" value" -#~ msgstr "el largo no es válido en el valor «numeric» externo" +#: gram.y:15902 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "no se permiten múltiples cláusulas WITH" -#~ msgid "time zone abbreviation \"%s\" is not used in time zone \"%s\"" -#~ msgstr "abreviación de huso horario «%s» no se usa en el huso horario «%s»" +#: gram.y:16106 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "los argumentos OUT e INOUT no están permitidos en funciones TABLE" -#~ msgid "function returning set of rows cannot return null value" -#~ msgstr "una función que retorna un conjunto de registros no puede devolver un valor null" +#: gram.y:16207 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "no se permiten múltiples cláusulas COLLATE" -#~ msgid "Only superusers can use untrusted languages." -#~ msgstr "Sólo los superusuarios pueden usar lenguajes no confiables." +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16245 gram.y:16258 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "las restricciones %s no pueden ser marcadas DEFERRABLE" -#~ msgid "argument %d: could not determine data type" -#~ msgstr "argumento %d: no se pudo determinar el tipo de dato" +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16271 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "las restricciones %s no pueden ser marcadas NOT VALID" -#~ msgid "could not determine data type for argument 2" -#~ msgstr "no se pudo determinar el tipo de dato para el argumento 2" +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16284 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "las restricciones %s no pueden ser marcadas NO INHERIT" -#~ msgid "could not determine data type for argument 1" -#~ msgstr "no se pudo determinar el tipo de dato para el argumento 1" +#: guc-file.l:316 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "parámetro de configuración «%s» no reconocido en el archivo «%s» línea %u" -#, fuzzy -#~ msgid "Triggers on partitioned tables cannot have transition tables." -#~ msgstr "Las tablas foráneas no pueden tener disparadores de restricción." +#: guc-file.l:389 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "parámetro «%s» eliminado del archivo de configuración, volviendo al valor por omisión" -#, fuzzy -#~ msgid "synchronized table states" -#~ msgstr "Permitir la sincronización de recorridos secuenciales." +#: guc-file.l:455 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "el parámetro «%s» fue cambiado a «%s»" -#, fuzzy -#~ msgid "could get display name for locale \"%s\": %s" -#~ msgstr "no se pudo crear la configuración regional «%s»: %m" +#: guc-file.l:497 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "el archivo de configuración «%s» contiene errores" -#~ msgid "cannot create temporary tables in parallel mode" -#~ msgstr "no se pueden crear tablas temporales en modo paralelo" +#: guc-file.l:502 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "el archivo de configuración «%s» contiene errores; los cambios no afectados fueron aplicados" -#~ msgid "%s." -#~ msgstr "%s." +#: guc-file.l:507 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "el archivo de configuración «%s» contiene errores; no se aplicó ningún cambio" -#~ msgid "spgist operator class \"%s\" is missing operator(s)" -#~ msgstr "faltan operadores en la clase de de operadores spgist «%s»" +#: guc-file.l:580 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "no se pudo abrir el archivo de configuración «%s»: nivel de anidamiento máximo excedido" -#~ msgid "spgist operator family \"%s\" is missing operator(s) for types %s and %s" -#~ msgstr "faltan operadores para los tipos %2$s y %3$s en la familia de operadores spgist «%1$s»" +#: guc-file.l:607 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "omitiendo el archivo de configuración faltante «%s»" -#~ msgid "spgist operator family \"%s\" contains operator %s with wrong signature" -#~ msgstr "la familia de operadores spgist «%s» contiene al operador %s con signatura incorrecta" +#: guc-file.l:861 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "error de sintaxis en el archivo «%s» línea %u, cerca del fin de línea" -#~ msgid "spgist operator family \"%s\" contains invalid ORDER BY specification for operator %s" -#~ msgstr "la familia de operadores spgist «%s» contiene una especificación ORDER BY no válida para el operador %s" +#: guc-file.l:871 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "error de sintaxis en el archivo «%s» línea %u, cerca de la palabra «%s»" -#~ msgid "spgist operator family \"%s\" contains operator %s with invalid strategy number %d" -#~ msgstr "la familia de operadores spgist «%s» contiene operador %s con número de estrategia %d no válido" +#: guc-file.l:891 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "se encontraron demasiados errores de sintaxis, abandonando el archivo «%s»" -#~ msgid "spgist operator family \"%s\" contains function %s with wrong signature for support number %d" -#~ msgstr "la familia de operadores spgist «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +#: guc-file.l:943 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "no se pudo abrir el directorio de configuración «%s»: %m" -#~ msgid "spgist operator family \"%s\" contains function %s with invalid support number %d" -#~ msgstr "la familia de operadores spgist «%s» contiene la función %s con número de soporte no válido %d" +#: jsonpath_gram.y:517 +#, c-format +msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgstr "parámetro no reconocido «%c» en predicado LIKE_REGEX" -#~ msgid "spgist operator family \"%s\" contains support procedure %s with cross-type registration" -#~ msgstr "la familia de operadores spgist «%s» contiene el procedimiento de soporte %s registrado entre tipos distintos" +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:300 +#, c-format +msgid "%s at end of jsonpath input" +msgstr "%s al final de la entrada jsonpath" -#~ msgid "btree operator family \"%s\" is missing cross-type operator(s)" -#~ msgstr "faltan operadores entre tipos en la familia de operadores btree «%s»" +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:307 +#, c-format +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s en o cerca de «%s» de la entrada jsonpath" -#~ msgid "btree operator class \"%s\" is missing operator(s)" -#~ msgstr "faltan operadores en la clase de operadores btree «%s»" +#: repl_gram.y:336 repl_gram.y:368 +#, c-format +msgid "invalid timeline %u" +msgstr "timeline %u no válido" -#~ msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" -#~ msgstr "faltan operadores para los tipos %2$s y %3$s en la familia de operadores btree «%1$s»" +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "posición de inicio de flujo de WAL no válida" -#~ msgid "btree operator family \"%s\" contains operator %s with wrong signature" -#~ msgstr "la familia de operadores btree «%s» contiene al operador %s con signatura incorrecta" +#: repl_scanner.l:180 scan.l:703 +msgid "unterminated quoted string" +msgstr "una cadena de caracteres entre comillas está inconclusa" -#~ msgid "btree operator family \"%s\" contains invalid ORDER BY specification for operator %s" -#~ msgstr "la familia de operadores btree «%s» contiene una especificación ORDER BY no válida para el operador %s" +#: scan.l:463 +msgid "unterminated /* comment" +msgstr "un comentario /* está inconcluso" -#~ msgid "btree operator family \"%s\" contains operator %s with invalid strategy number %d" -#~ msgstr "la familia de operadores btree «%s» contiene operador %s con número de estrategia %d no válido" +#: scan.l:494 +msgid "unterminated bit string literal" +msgstr "una cadena de bits está inconclusa" -#~ msgid "btree operator family \"%s\" contains function %s with wrong signature for support number %d" -#~ msgstr "la familia de operadores btree «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +#: scan.l:515 +msgid "unterminated hexadecimal string literal" +msgstr "una cadena hexadecimal está inconclusa" -#~ msgid "btree operator family \"%s\" contains function %s with invalid support number %d" -#~ msgstr "la familia de operadores btree «%s» contiene la función %s con número de soporte no válido %d" +#: scan.l:565 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "uso inseguro de literal de cadena con escapes Unicode" -#~ msgid "hash operator class \"%s\" is missing operator(s)" -#~ msgstr "faltan operadores en la clase de de operadores hash «%s»" +#: scan.l:566 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Los literales de cadena con escapes Unicode no pueden usarse cuando standard_conforming_strings está desactivado." -#~ msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" -#~ msgstr "faltan operadores para los tipos %2$s y %3$s en la familia de operadores hash «%1$s»" +#: scan.l:612 scan.l:811 +msgid "invalid Unicode escape character" +msgstr "carácter de escape Unicode no válido" -#~ msgid "hash operator family \"%s\" contains operator %s with wrong signature" -#~ msgstr "la familia de operadores hash «%s» contiene la función %s con signatura incorrecta" +#: scan.l:638 scan.l:646 scan.l:654 scan.l:655 scan.l:656 scan.l:1400 +#: scan.l:1427 scan.l:1431 scan.l:1469 scan.l:1473 scan.l:1495 scan.l:1505 +msgid "invalid Unicode surrogate pair" +msgstr "par sustituto (surrogate) Unicode no válido" -#~ msgid "hash operator family \"%s\" contains invalid ORDER BY specification for operator %s" -#~ msgstr "la familia de operadores hash «%s» contiene una especificación no válida de ORDER BY para el operador %s" +#: scan.l:660 +#, c-format +msgid "invalid Unicode escape" +msgstr "valor de escape Unicode no válido" -#~ msgid "hash operator family \"%s\" contains operator %s with invalid strategy number %d" -#~ msgstr "la familia de operadores hash «%s» contiene el operador %s con número de estrategia %d no válido" +#: scan.l:661 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Los escapes Unicode deben ser \\uXXXX o \\UXXXXXXXX." -#~ msgid "hash operator family \"%s\" contains function %s with invalid support number %d" -#~ msgstr "la familia de operadores hash «%s» contiene la función %s con número de soporte %d no válido" +#: scan.l:672 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "uso inseguro de \\' en un literal de cadena" -#~ msgid "hash operator family \"%s\" contains function %s with wrong signature for support number %d" -#~ msgstr "la familia de operadores hash «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +#: scan.l:673 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Use '' para escribir comillas en cadenas. \\' es inseguro en codificaciones de sólo cliente." -#~ msgid "hash operator family \"%s\" contains support procedure %s with cross-type registration" -#~ msgstr "la familia de operadores hash «%s» contiene el procedimiento de soporte %s registrado entre tipos distintos" +#: scan.l:748 +msgid "unterminated dollar-quoted string" +msgstr "una cadena separada por $ está inconclusa" -#~ msgid "gist operator class \"%s\" is missing support function %d" -#~ msgstr "falta la función de soporte %2$d de la clase de operadores gist «%1$s»" +#: scan.l:765 scan.l:791 scan.l:806 +msgid "zero-length delimited identifier" +msgstr "un identificador delimitado tiene largo cero" -#~ msgid "gist operator family \"%s\" contains operator %s with wrong signature" -#~ msgstr "la familia de operadores gist «%s» contiene un operador %s con la signatura incorrecta" +#: scan.l:826 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "un identificador entre comillas está inconcluso" -#~ msgid "gist operator family \"%s\" contains operator %s with invalid strategy number %d" -#~ msgstr "la familia de operadores gist «%s» contiene el operador %s con número de estrategia %d no válido" +#: scan.l:989 +msgid "operator too long" +msgstr "el operador es demasiado largo" -#~ msgid "gist operator family \"%s\" contains function %s with wrong signature for support number %d" -#~ msgstr "la familia de operadores gist «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1141 +#, c-format +msgid "%s at end of input" +msgstr "%s al final de la entrada" -#~ msgid "gist operator family \"%s\" contains function %s with invalid support number %d" -#~ msgstr "la familia de operadores gist «%s» contiene la función %s con número de soporte %d no válido" +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1149 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s en o cerca de «%s»" -#~ msgid "gist operator family \"%s\" contains support procedure %s with cross-type registration" -#~ msgstr "la familia de operadores gist «%s» contiene el procedimiento de soporte %s registrado entre distintos tipos" +#: scan.l:1314 scan.l:1346 +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +msgstr "Los valores de escape Unicode no puede ser usados para valores de «code point» sobre 007F cuando la codificación de servidor no es UTF8" -#~ msgid "brin operator class \"%s\" is missing support function %d" -#~ msgstr "falta la función de soporte %2$d de la clase de operadores brin «%1$s»" +#: scan.l:1342 scan.l:1487 +msgid "invalid Unicode escape value" +msgstr "valor de escape Unicode no válido" -#~ msgid "brin operator family \"%s\" contains operator %s with wrong signature" -#~ msgstr "familia de operadores brin «%s» contiene el operador %s con signatura incorrecta" +#: scan.l:1551 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "uso no estandar de \\' en un literal de cadena" -#~ msgid "brin operator family \"%s\" contains invalid ORDER BY specification for operator %s" -#~ msgstr "familia de operadores brin «%s» contiene especificación ORDER BY no válida para el operador %s" +#: scan.l:1552 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'...')." -#~ msgid "brin operator family \"%s\" contains operator %s with invalid strategy number %d" -#~ msgstr "familia de operadores brin «%s» contiene el operador %s con número de estrategia %d no válido" +#: scan.l:1561 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "uso no estandar de \\\\ en un literal de cadena" -#~ msgid "brin operator family \"%s\" contains function %s with wrong signature for support number %d" -#~ msgstr "familia de operadores brin «%s» contiene la función %s con signatura incorrecta para el número de soporte %d" +#: scan.l:1562 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Use '' para escribir comillas en cadenas, o use la sintaxis de escape de cadenas (E'\\\\')." -#~ msgid "brin operator family \"%s\" contains function %s with invalid support number %d" -#~ msgstr "familia de operadores brin «%s» contiene la función %s con número de soporte %d no válido" +#: scan.l:1576 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "uso no estandar de escape en un literal de cadena" -#~ msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -#~ msgstr "el tamaño de fila de índice %lu excede el máximo %lu para el índice «%s»" +#: scan.l:1577 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Use la sintaxis de escape para cadenas, por ej. E'\\r\\n'." diff --git a/src/backend/po/fr.po b/src/backend/po/fr.po index a375bc57cb4..749147746da 100644 --- a/src/backend/po/fr.po +++ b/src/backend/po/fr.po @@ -8,47 +8,57 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 02:39+0000\n" -"PO-Revision-Date: 2017-08-04 20:59+0200\n" -"Last-Translator: Guillaume Lelarge \n" +"POT-Creation-Date: 2019-04-16 01:39+0000\n" +"PO-Revision-Date: 2019-04-17 21:38+0200\n" +"Last-Translator: Julien Rouhaud \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.2.1\n" #: ../common/config_info.c:130 ../common/config_info.c:138 ../common/config_info.c:146 ../common/config_info.c:154 ../common/config_info.c:162 ../common/config_info.c:170 ../common/config_info.c:178 ../common/config_info.c:186 ../common/config_info.c:194 msgid "not recorded" msgstr "non enregistré" -#: ../common/controldata_utils.c:57 commands/copy.c:3117 commands/extension.c:3330 utils/adt/genfile.c:135 +#: ../common/controldata_utils.c:58 commands/copy.c:3196 commands/extension.c:3337 utils/adt/genfile.c:151 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" -#: ../common/controldata_utils.c:61 +#: ../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" -#: ../common/controldata_utils.c:71 access/transam/timeline.c:348 access/transam/xlog.c:3384 access/transam/xlog.c:10787 access/transam/xlog.c:10800 access/transam/xlog.c:11192 access/transam/xlog.c:11235 access/transam/xlog.c:11274 access/transam/xlog.c:11317 access/transam/xlogfuncs.c:668 access/transam/xlogfuncs.c:687 commands/extension.c:3340 libpq/hba.c:499 replication/logical/origin.c:661 replication/logical/origin.c:691 -#: replication/logical/reorderbuffer.c:3064 replication/walsender.c:506 storage/file/copydir.c:178 utils/adt/genfile.c:152 utils/adt/misc.c:924 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 access/transam/xlog.c:3440 access/transam/xlog.c:10942 access/transam/xlog.c:10955 access/transam/xlog.c:11380 access/transam/xlog.c:11460 access/transam/xlog.c:11499 access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 access/transam/xlogfuncs.c:677 commands/extension.c:3347 libpq/hba.c:499 replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3308 replication/walsender.c:510 storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format msgid "could not read file \"%s\": %m" msgstr "n'a pas pu lire le fichier « %s » : %m" -#: ../common/controldata_utils.c:74 +#: ../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s : n'a pas pu lire le fichier « %s » : %s\n" -#: ../common/controldata_utils.c:95 +#: ../common/controldata_utils.c:86 +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %d" + +#: ../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s : n'a pas pu lire le fichier « %s » : a lu %d sur %d\n" + +#: ../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "différence de l'ordre des octets" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -97,7 +107,7 @@ msgstr "n'a pas pu lire le lien symbolique « %s »" msgid "pclose failed: %s" msgstr "échec de pclose : %s" -#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 utils/misc/ps_status.c:217 +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 ../common/fe_memutils.c:98 ../common/psprintf.c:182 ../port/path.c:632 ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 utils/misc/ps_status.c:217 #, c-format msgid "out of memory\n" msgstr "mémoire épuisée\n" @@ -152,20 +162,20 @@ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" msgid "could not close directory \"%s\": %s\n" msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" -#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1306 access/transam/xlog.c:6355 lib/stringinfo.c:258 libpq/auth.c:1108 libpq/auth.c:1474 libpq/auth.c:1542 libpq/auth.c:2058 postmaster/bgworker.c:337 postmaster/bgworker.c:908 postmaster/postmaster.c:2391 postmaster/postmaster.c:2413 postmaster/postmaster.c:3975 postmaster/postmaster.c:4683 postmaster/postmaster.c:4758 -#: postmaster/postmaster.c:5436 postmaster/postmaster.c:5773 replication/libpqwalreceiver/libpqwalreceiver.c:251 replication/logical/logical.c:170 storage/buffer/localbuf.c:436 storage/file/fd.c:773 storage/file/fd.c:1201 storage/file/fd.c:1319 storage/file/fd.c:2044 storage/ipc/procarray.c:1057 storage/ipc/procarray.c:1545 storage/ipc/procarray.c:1552 storage/ipc/procarray.c:1969 storage/ipc/procarray.c:2580 utils/adt/formatting.c:1579 -#: utils/adt/formatting.c:1703 utils/adt/formatting.c:1828 utils/adt/pg_locale.c:468 utils/adt/pg_locale.c:652 utils/adt/regexp.c:219 utils/adt/varlena.c:4585 utils/adt/varlena.c:4606 utils/fmgr/dfmgr.c:221 utils/hash/dynahash.c:444 utils/hash/dynahash.c:553 utils/hash/dynahash.c:1065 utils/mb/mbutils.c:376 utils/mb/mbutils.c:709 utils/misc/guc.c:3998 utils/misc/guc.c:4014 utils/misc/guc.c:4027 utils/misc/guc.c:6976 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:404 utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 utils/mmgr/mcxt.c:725 utils/mmgr/mcxt.c:760 utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:834 utils/mmgr/mcxt.c:868 utils/mmgr/mcxt.c:897 utils/mmgr/mcxt.c:931 utils/mmgr/mcxt.c:982 utils/mmgr/mcxt.c:1016 utils/mmgr/mcxt.c:1050 +#: ../common/psprintf.c:180 ../port/path.c:630 ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6482 lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 postmaster/bgworker.c:907 postmaster/postmaster.c:2391 postmaster/postmaster.c:2413 postmaster/postmaster.c:3980 postmaster/postmaster.c:4688 +#: postmaster/postmaster.c:4763 postmaster/postmaster.c:5455 postmaster/postmaster.c:5792 replication/libpqwalreceiver/libpqwalreceiver.c:260 replication/logical/logical.c:179 storage/buffer/localbuf.c:436 storage/file/fd.c:800 storage/file/fd.c:1239 storage/file/fd.c:1400 storage/file/fd.c:2313 storage/ipc/procarray.c:1066 storage/ipc/procarray.c:1554 storage/ipc/procarray.c:1561 storage/ipc/procarray.c:1982 storage/ipc/procarray.c:2606 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 utils/misc/guc.c:4240 utils/misc/guc.c:4256 utils/misc/guc.c:4269 +#: utils/misc/guc.c:7248 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format msgid "out of memory" msgstr "mémoire épuisée" -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "nom du fork invalide" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "Les noms de fork valides sont « main », « fsm », « vm » et « init »." @@ -173,7 +183,7 @@ msgstr "Les noms de fork valides sont « main », « fsm », « vm » et « init #: ../common/restricted_token.c:68 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s : ATTENTION : ne peut pas crér les jetons restreints sur cette plateforme\n" +msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" #: ../common/restricted_token.c:77 #, c-format @@ -217,7 +227,7 @@ msgstr "" msgid "could not remove file or directory \"%s\": %s\n" msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %s\n" -#: ../common/saslprep.c:1090 +#: ../common/saslprep.c:1093 #, c-format msgid "password too long" msgstr "mot de passe trop long" @@ -227,7 +237,7 @@ msgstr "mot de passe trop long" msgid "could not look up effective user ID %ld: %s" msgstr "n'a pas pu trouver l'identifiant réel %ld de l'utilisateur : %s" -#: ../common/username.c:45 libpq/auth.c:2005 +#: ../common/username.c:45 libpq/auth.c:2038 msgid "user does not exist" msgstr "l'utilisateur n'existe pas" @@ -353,22 +363,37 @@ msgstr "" msgid "could not check access token membership: error code %lu\n" msgstr "n'a pas pu vérifier l'appartenance du jeton d'accès : code d'erreur %lu\n" -#: access/brin/brin.c:867 access/brin/brin.c:938 +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "requête de résumé d'intervalle BRIN pour la page « %s » de l'index « %u » n'a pas été enregistrée" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 access/transam/xlog.c:10354 access/transam/xlog.c:10881 access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "restauration en cours" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Les fonctions de controle BRIN ne peuvent pas être exécutées pendant la restauration" + +#: access/brin/brin.c:886 access/brin/brin.c:963 #, c-format msgid "block number out of range: %s" msgstr "numéro de bloc en dehors des limites : %s" -#: access/brin/brin.c:890 access/brin/brin.c:961 +#: access/brin/brin.c:909 access/brin/brin.c:986 #, c-format msgid "\"%s\" is not a BRIN index" msgstr "« %s » n'est pas un index BRIN" -#: access/brin/brin.c:906 access/brin/brin.c:977 +#: access/brin/brin.c:925 access/brin/brin.c:1002 #, c-format msgid "could not open parent table of index %s" msgstr "n'a pas pu ouvrir la table parent de l'index %s" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:358 access/brin/brin_pageops.c:824 access/gin/ginentrypage.c:110 access/gist/gist.c:1363 access/nbtree/nbtinsert.c:577 access/nbtree/nbtsort.c:488 access/spgist/spgdoinsert.c:1933 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 access/gist/gist.c:1381 access/nbtree/nbtinsert.c:678 access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 #, c-format msgid "index row size %zu exceeds maximum %zu for index \"%s\"" msgstr "la taille de la ligne index, %zu, dépasse le maximum, %zu, pour l'index « %s »" @@ -381,47 +406,47 @@ msgstr "index BRIN corrompu : carte d'intervalle incohérente" #: access/brin/brin_revmap.c:404 #, c-format msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" -msgstr "" +msgstr "reste d'espace de ligne réservé dans l'index BRIN « %s », suppression" #: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "type de page 0x%04X dans l'index BRIN « %s », bloc %u" -#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:131 access/nbtree/nbtvalidate.c:101 access/spgist/spgvalidate.c:116 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction %s avec\n" "le numéro de support invalide %d" -#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:114 access/nbtree/nbtvalidate.c:113 access/spgist/spgvalidate.c:128 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction %s avec une mauvaise\n" "signature pour le numéro de support %d" -#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:152 access/nbtree/nbtvalidate.c:133 access/spgist/spgvalidate.c:147 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 #, c-format msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s contient l'opérateur %s avec le numéro\n" "de stratégie invalide %d" -#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 access/hash/hashvalidate.c:165 access/nbtree/nbtvalidate.c:146 access/spgist/spgvalidate.c:160 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 access/spgist/spgvalidate.c:209 #, c-format msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s contient la spécification ORDER BY\n" "invalide pour l'opérateur %s" -#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:178 access/nbtree/nbtvalidate.c:159 access/spgist/spgvalidate.c:173 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 #, c-format msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" msgstr "la famille d'opérateur « %s » de la méthode d'accès %s contient l'opérateur %s avec une mauvaise signature" -#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:218 access/nbtree/nbtvalidate.c:201 access/spgist/spgvalidate.c:201 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 #, c-format msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" msgstr "" @@ -435,87 +460,87 @@ msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s nécessite des fonctions de support\n" "manquantes pour les types %s et %s" -#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:232 access/nbtree/nbtvalidate.c:225 access/spgist/spgvalidate.c:234 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format msgid "operator class \"%s\" of access method %s is missing operator(s)" msgstr "il manque un ou des opérateurs à la classe d'opérateur « %s » de la méthode d'accès %s" -#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 access/gist/gistvalidate.c:265 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 access/gist/gistvalidate.c:266 #, c-format msgid "operator class \"%s\" of access method %s is missing support function %d" msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1405 +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "le nombre de colonnes (%d) dépasse la limite (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "le nombre de colonnes indexées (%d) dépasse la limite (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:647 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "la ligne index requiert %zu octets, la taille maximum est %zu" -#: access/common/printtup.c:290 tcop/fastpath.c:182 tcop/fastpath.c:532 tcop/postgres.c:1726 +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 tcop/postgres.c:1778 #, c-format msgid "unsupported format code: %d" msgstr "code de format non supporté : %d" -#: access/common/reloptions.c:540 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "limite dépassée des types de paramètres de la relation définie par l'utilisateur" -#: access/common/reloptions.c:821 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "RESET ne doit pas inclure de valeurs pour les paramètres" -#: access/common/reloptions.c:854 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "espace de nom du paramètre « %s » non reconnu" -#: access/common/reloptions.c:1094 parser/parse_clause.c:270 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "paramètre « %s » non reconnu" -#: access/common/reloptions.c:1124 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "le paramètre « %s » est spécifié plus d'une fois" -#: access/common/reloptions.c:1140 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "valeur invalide pour l'option booléenne « %s » : %s" -#: access/common/reloptions.c:1152 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "valeur invalide pour l'option de type integer « %s » : %s" -#: access/common/reloptions.c:1158 access/common/reloptions.c:1178 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "valeur %s en dehors des limites pour l'option « %s »" -#: access/common/reloptions.c:1160 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "Les valeurs valides sont entre « %d » et « %d »." -#: access/common/reloptions.c:1172 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "valeur invalide pour l'option de type float « %s » : %s" -#: access/common/reloptions.c:1180 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "Les valeurs valides sont entre « %f » et « %f »." @@ -532,17 +557,17 @@ msgstr "" "Le nombre de colonnes renvoyées (%d) ne correspond pas au nombre de colonnes\n" "attendues (%d)." -#: access/common/tupconvert.c:318 +#: access/common/tupconvert.c:329 #, c-format msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." msgstr "L'attribut « %s » du type %s ne correspond pas à l'attribut correspondant de type %s." -#: access/common/tupconvert.c:330 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "L'attribut « %s » du type %s n'existe pas dans le type %s." -#: access/common/tupdesc.c:728 parser/parse_clause.c:841 parser/parse_relation.c:1544 +#: access/common/tupdesc.c:837 parser/parse_clause.c:819 parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "la colonne « %s » ne peut pas être déclarée SETOF" @@ -557,48 +582,43 @@ msgstr "la posting list est trop longue" msgid "Reduce maintenance_work_mem." msgstr "Réduisez le maintenance_work_mem." -#: access/gin/ginfast.c:991 access/transam/xlog.c:10208 access/transam/xlog.c:10726 access/transam/xlogfuncs.c:296 access/transam/xlogfuncs.c:323 access/transam/xlogfuncs.c:362 access/transam/xlogfuncs.c:383 access/transam/xlogfuncs.c:404 access/transam/xlogfuncs.c:474 access/transam/xlogfuncs.c:530 -#, c-format -msgid "recovery is in progress" -msgstr "restauration en cours" - -#: access/gin/ginfast.c:992 +#: access/gin/ginfast.c:1019 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "la pending list GIN ne peut pas être nettoyée lors de la restauration" -#: access/gin/ginfast.c:999 +#: access/gin/ginfast.c:1026 #, c-format msgid "\"%s\" is not a GIN index" msgstr "« %s » n'est pas un index GIN" -#: access/gin/ginfast.c:1010 +#: access/gin/ginfast.c:1037 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "ne peut pas accéder aux index temporaires d'autres sessions" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "" "les anciens index GIN ne supportent pas les parcours complets d'index et les\n" "recherches de valeurs NULL" -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "Pour corriger ceci, faites un REINDEX INDEX « %s »." -#: access/gin/ginutil.c:134 executor/execExpr.c:1780 utils/adt/arrayfuncs.c:3803 utils/adt/arrayfuncs.c:6323 utils/adt/rowtypes.c:927 +#: access/gin/ginutil.c:138 executor/execExpr.c:1868 utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 utils/adt/rowtypes.c:935 #, c-format msgid "could not identify a comparison function for type %s" msgstr "n'a pas pu identifier une fonction de comparaison pour le type %s" -#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:93 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format -msgid "operator family \"%s\" of access method %s contains support procedure %s with different left and right input types" +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" msgstr "" -"la famille d'opérateur « %s » de la méthode d'accès %s contient la procédure de support\n" +"la famille d'opérateur « %s » de la méthode d'accès %s contient la fonction de support\n" "%s avec des types en entrée gauche et droite différents" #: access/gin/ginvalidate.c:257 @@ -606,34 +626,34 @@ msgstr "" msgid "operator class \"%s\" of access method %s is missing support function %d or %d" msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d ou %d" -#: access/gist/gist.c:706 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:717 access/gist/gistvacuum.c:258 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "l'index « %s » contient une ligne interne marquée comme invalide" -#: access/gist/gist.c:708 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:719 access/gist/gistvacuum.c:260 #, c-format msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." msgstr "" "Ceci est dû à la division d'une page incomplète à la restauration suite à un\n" "crash avant la mise à jour en 9.1." -#: access/gist/gist.c:709 access/gist/gistutil.c:739 access/gist/gistutil.c:750 access/gist/gistvacuum.c:261 access/hash/hashutil.c:241 access/hash/hashutil.c:252 access/hash/hashutil.c:264 access/hash/hashutil.c:285 access/nbtree/nbtpage.c:519 access/nbtree/nbtpage.c:530 +#: access/gist/gist.c:720 access/gist/gistutil.c:759 access/gist/gistutil.c:770 access/gist/gistvacuum.c:261 access/hash/hashutil.c:241 access/hash/hashutil.c:252 access/hash/hashutil.c:264 access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "Merci d'exécuter REINDEX sur cet objet." -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:252 #, c-format msgid "invalid value for \"buffering\" option" msgstr "valeur invalide pour l'option « buffering »" -#: access/gist/gistbuild.c:251 +#: access/gist/gistbuild.c:253 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "Les valeurs valides sont entre « on », « off » et « auto »." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:231 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "n'a pas pu écrire le bloc %ld du fichier temporaire : %m" @@ -651,12 +671,12 @@ msgstr "" "ou essayez d'utiliser la colonne comme second dans la commande\n" "CREATE INDEX." -#: access/gist/gistutil.c:736 access/hash/hashutil.c:238 access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "l'index « %s » contient une page zéro inattendue au bloc %u" -#: access/gist/gistutil.c:747 access/hash/hashutil.c:249 access/hash/hashutil.c:261 access/nbtree/nbtpage.c:527 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "l'index « %s » contient une page corrompue au bloc %u" @@ -675,12 +695,12 @@ msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s contient la spécification opfamily ORDER BY\n" "incorrecte pour l'opérateur %s" -#: access/hash/hashinsert.c:82 +#: access/hash/hashinsert.c:83 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "la taille de la ligne index, %zu, dépasse le hachage maximum, %zu" -#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1937 access/spgist/spgutils.c:708 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "Les valeurs plus larges qu'une page de tampon ne peuvent pas être indexées." @@ -690,12 +710,12 @@ msgstr "Les valeurs plus larges qu'une page de tampon ne peuvent pas être index msgid "invalid overflow block number %u" msgstr "numéro de bloc de surcharge invalide %u" -#: access/hash/hashovfl.c:283 access/hash/hashpage.c:462 +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "en dehors des pages surchargées dans l'index haché « %s »" -#: access/hash/hashsearch.c:250 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "les index hâchés ne supportent pas les parcours complets d'index" @@ -710,103 +730,103 @@ msgstr "l'index « %s » n'est pas un index haché" msgid "index \"%s\" has wrong hash version" msgstr "l'index « %s » a la mauvaise version de hachage" -#: access/hash/hashvalidate.c:190 +#: access/hash/hashvalidate.c:191 #, c-format msgid "operator family \"%s\" of access method %s lacks support function for operator %s" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s requiert la fonction de support\n" "pour l'opérateur %s" -#: access/hash/hashvalidate.c:248 access/nbtree/nbtvalidate.c:242 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" msgstr "il manque un opérateur inter-type pour la famille d'opérateur « %s » de la méthode d'accès %s" -#: access/heap/heapam.c:1293 access/heap/heapam.c:1321 access/heap/heapam.c:1353 catalog/aclchk.c:1772 +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" msgstr "« %s » est un index" -#: access/heap/heapam.c:1298 access/heap/heapam.c:1326 access/heap/heapam.c:1358 catalog/aclchk.c:1779 commands/tablecmds.c:9885 commands/tablecmds.c:13115 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10846 commands/tablecmds.c:14131 #, c-format msgid "\"%s\" is a composite type" msgstr "« %s » est un type composite" -#: access/heap/heapam.c:2592 +#: access/heap/heapam.c:2645 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "ne peut pas insérer les lignes lors d'une opération parallèle" +msgid "cannot insert tuples in a parallel worker" +msgstr "ne peut pas insérer de lignes dans un processus parallèle" -#: access/heap/heapam.c:3042 +#: access/heap/heapam.c:3092 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "ne peut pas supprimer les lignes lors d'une opération parallèle" -#: access/heap/heapam.c:3088 +#: access/heap/heapam.c:3138 #, c-format msgid "attempted to delete invisible tuple" msgstr "a tenté de supprimer la ligne invisible" -#: access/heap/heapam.c:3514 access/heap/heapam.c:6247 +#: access/heap/heapam.c:3572 access/heap/heapam.c:6409 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "ne peut pas mettre à jour les lignes lors d'une opération parallèle" -#: access/heap/heapam.c:3662 +#: access/heap/heapam.c:3720 #, c-format msgid "attempted to update invisible tuple" msgstr "a tenté de mettre à jour la ligne invisible" -#: access/heap/heapam.c:4937 access/heap/heapam.c:4975 access/heap/heapam.c:5227 executor/execMain.c:2602 +#: access/heap/heapam.c:5085 access/heap/heapam.c:5123 access/heap/heapam.c:5375 executor/execMain.c:2662 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "n'a pas pu obtenir un verrou sur la relation « %s »" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:666 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:682 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "la ligne est trop grande : taille %zu, taille maximale %zu" -#: access/heap/rewriteheap.c:926 +#: access/heap/rewriteheap.c:942 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "n'a pas pu écrire le fichier « %s », a écrit %d de %d : %m" -#: access/heap/rewriteheap.c:966 access/heap/rewriteheap.c:1183 access/heap/rewriteheap.c:1282 access/transam/timeline.c:412 access/transam/timeline.c:492 access/transam/xlog.c:3249 access/transam/xlog.c:3417 replication/logical/snapbuild.c:1630 replication/slot.c:1290 replication/slot.c:1377 storage/file/fd.c:631 storage/file/fd.c:3180 storage/smgr/md.c:1044 storage/smgr/md.c:1277 storage/smgr/md.c:1450 utils/misc/guc.c:6998 +#: access/heap/rewriteheap.c:982 access/heap/rewriteheap.c:1203 access/heap/rewriteheap.c:1302 access/transam/timeline.c:411 access/transam/timeline.c:490 access/transam/xlog.c:3307 access/transam/xlog.c:3473 replication/logical/snapbuild.c:1652 replication/slot.c:1313 replication/slot.c:1405 storage/file/fd.c:658 storage/file/fd.c:3552 storage/smgr/md.c:1044 storage/smgr/md.c:1289 storage/smgr/md.c:1463 utils/misc/guc.c:7270 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" -#: access/heap/rewriteheap.c:1021 access/heap/rewriteheap.c:1141 access/transam/timeline.c:315 access/transam/timeline.c:467 access/transam/xlog.c:3202 access/transam/xlog.c:3355 access/transam/xlog.c:10543 access/transam/xlog.c:10581 access/transam/xlog.c:10966 postmaster/postmaster.c:4450 replication/logical/origin.c:535 replication/slot.c:1242 storage/file/copydir.c:162 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 +#: access/heap/rewriteheap.c:1036 access/heap/rewriteheap.c:1155 access/transam/timeline.c:314 access/transam/timeline.c:465 access/transam/xlog.c:3261 access/transam/xlog.c:3411 access/transam/xlog.c:10692 access/transam/xlog.c:10730 access/transam/xlog.c:11133 postmaster/postmaster.c:4455 replication/logical/origin.c:575 replication/slot.c:1262 storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 #, c-format msgid "could not create file \"%s\": %m" msgstr "n'a pas pu créer le fichier « %s » : %m" -#: access/heap/rewriteheap.c:1151 +#: access/heap/rewriteheap.c:1165 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "n'a pas pu tronquer le fichier « %s » en %u : %m" -#: access/heap/rewriteheap.c:1159 replication/walsender.c:486 storage/smgr/md.c:1949 +#: access/heap/rewriteheap.c:1173 replication/walsender.c:490 storage/smgr/md.c:1993 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "n'a pas pu trouver la fin du fichier « %s » : %m" -#: access/heap/rewriteheap.c:1171 access/transam/timeline.c:370 access/transam/timeline.c:405 access/transam/timeline.c:484 access/transam/xlog.c:3238 access/transam/xlog.c:3408 postmaster/postmaster.c:4460 postmaster/postmaster.c:4470 replication/logical/origin.c:544 replication/logical/origin.c:583 replication/logical/origin.c:599 replication/logical/snapbuild.c:1612 replication/slot.c:1273 storage/file/copydir.c:191 -#: utils/init/miscinit.c:1249 utils/init/miscinit.c:1260 utils/init/miscinit.c:1268 utils/misc/guc.c:6959 utils/misc/guc.c:6990 utils/misc/guc.c:8840 utils/misc/guc.c:8854 utils/time/snapmgr.c:1302 utils/time/snapmgr.c:1309 +#: access/heap/rewriteheap.c:1190 access/transam/timeline.c:369 access/transam/timeline.c:404 access/transam/timeline.c:482 access/transam/xlog.c:3293 access/transam/xlog.c:3464 postmaster/postmaster.c:4465 postmaster/postmaster.c:4475 replication/logical/origin.c:590 replication/logical/origin.c:635 replication/logical/origin.c:657 replication/logical/snapbuild.c:1628 replication/slot.c:1296 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1345 utils/init/miscinit.c:1356 utils/init/miscinit.c:1364 utils/misc/guc.c:7231 utils/misc/guc.c:7262 utils/misc/guc.c:9124 utils/misc/guc.c:9138 utils/time/snapmgr.c:1302 utils/time/snapmgr.c:1309 #, c-format msgid "could not write to file \"%s\": %m" msgstr "n'a pas pu écrire dans le fichier « %s » : %m" -#: access/heap/rewriteheap.c:1257 access/transam/xlogarchive.c:113 access/transam/xlogarchive.c:467 postmaster/postmaster.c:1257 postmaster/syslogger.c:1371 replication/logical/origin.c:522 replication/logical/reorderbuffer.c:2595 replication/logical/reorderbuffer.c:2652 replication/logical/snapbuild.c:1560 replication/logical/snapbuild.c:1936 replication/slot.c:1350 storage/file/fd.c:682 storage/ipc/dsm.c:327 storage/smgr/md.c:426 -#: storage/smgr/md.c:475 storage/smgr/md.c:1397 +#: access/heap/rewriteheap.c:1277 access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:459 postmaster/postmaster.c:1276 postmaster/syslogger.c:1459 replication/logical/origin.c:563 replication/logical/reorderbuffer.c:2814 replication/logical/snapbuild.c:1570 replication/logical/snapbuild.c:1972 replication/slot.c:1375 storage/file/fd.c:709 storage/file/fd.c:3152 storage/file/fd.c:3214 storage/file/reinit.c:255 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1410 utils/time/snapmgr.c:1640 #, c-format msgid "could not remove file \"%s\": %m" msgstr "n'a pas pu supprimer le fichier « %s » : %m" -#: access/heap/rewriteheap.c:1271 access/transam/timeline.c:111 access/transam/timeline.c:236 access/transam/timeline.c:334 access/transam/xlog.c:3178 access/transam/xlog.c:3299 access/transam/xlog.c:3340 access/transam/xlog.c:3619 access/transam/xlog.c:3697 access/transam/xlogutils.c:706 postmaster/syslogger.c:1380 replication/basebackup.c:474 replication/basebackup.c:1218 replication/logical/origin.c:654 -#: replication/logical/reorderbuffer.c:2112 replication/logical/reorderbuffer.c:2361 replication/logical/reorderbuffer.c:3044 replication/logical/snapbuild.c:1604 replication/logical/snapbuild.c:1692 replication/slot.c:1365 replication/walsender.c:479 replication/walsender.c:2385 storage/file/copydir.c:155 storage/file/fd.c:614 storage/file/fd.c:3092 storage/file/fd.c:3159 storage/smgr/md.c:608 utils/error/elog.c:1879 -#: utils/init/miscinit.c:1173 utils/init/miscinit.c:1308 utils/init/miscinit.c:1385 utils/misc/guc.c:7218 utils/misc/guc.c:7251 +#: access/heap/rewriteheap.c:1291 access/transam/timeline.c:111 access/transam/timeline.c:236 access/transam/timeline.c:333 access/transam/xlog.c:3238 access/transam/xlog.c:3356 access/transam/xlog.c:3397 access/transam/xlog.c:3674 access/transam/xlog.c:3752 access/transam/xlogutils.c:708 postmaster/syslogger.c:1482 replication/basebackup.c:517 replication/basebackup.c:1391 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2308 replication/logical/reorderbuffer.c:2575 replication/logical/reorderbuffer.c:3288 replication/logical/snapbuild.c:1614 replication/logical/snapbuild.c:1714 replication/slot.c:1390 replication/walsender.c:483 replication/walsender.c:2415 storage/file/copydir.c:161 storage/file/fd.c:641 storage/file/fd.c:3447 storage/file/fd.c:3531 storage/smgr/md.c:608 utils/error/elog.c:1872 +#: utils/init/miscinit.c:1269 utils/init/miscinit.c:1404 utils/init/miscinit.c:1481 utils/misc/guc.c:7490 utils/misc/guc.c:7522 #, c-format msgid "could not open file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier « %s » : %m" @@ -821,32 +841,32 @@ msgstr "la méthode d'accès « %s » n'est pas de type %s" msgid "index access method \"%s\" does not have a handler" msgstr "la méthode d'accès « %s » n'a pas de handler" -#: access/index/indexam.c:160 catalog/objectaddress.c:1222 commands/indexcmds.c:1819 commands/tablecmds.c:247 commands/tablecmds.c:13106 +#: access/index/indexam.c:160 catalog/objectaddress.c:1223 commands/indexcmds.c:2281 commands/tablecmds.c:249 commands/tablecmds.c:273 commands/tablecmds.c:14122 commands/tablecmds.c:15415 #, c-format msgid "\"%s\" is not an index" msgstr "« %s » n'est pas un index" -#: access/nbtree/nbtinsert.c:429 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "la valeur d'une clé dupliquée rompt la contrainte unique « %s »" -#: access/nbtree/nbtinsert.c:431 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." msgstr "La clé « %s » existe déjà." -#: access/nbtree/nbtinsert.c:498 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "échec pour retrouver la ligne dans l'index « %s »" -#: access/nbtree/nbtinsert.c:500 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "Ceci peut être dû à une expression d'index immutable." -#: access/nbtree/nbtinsert.c:580 access/nbtree/nbtsort.c:491 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" @@ -857,39 +877,44 @@ msgstr "" "Utilisez un index sur le hachage MD5 de la valeur ou passez à l'indexation\n" "de la recherche plein texte." -#: access/nbtree/nbtpage.c:169 access/nbtree/nbtpage.c:372 access/nbtree/nbtpage.c:459 parser/parse_utilcmd.c:1900 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2054 #, c-format msgid "index \"%s\" is not a btree" msgstr "l'index « %s » n'est pas un btree" -#: access/nbtree/nbtpage.c:175 access/nbtree/nbtpage.c:378 access/nbtree/nbtpage.c:465 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "la version ne correspond pas dans l'index « %s » : version du fichier %d, version du code %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "la version ne correspond pas dans l'index « %s » : version du fichier %d, version courante %d, version minimale supportée %d" -#: access/nbtree/nbtpage.c:1153 +#: access/nbtree/nbtpage.c:1320 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "l'index « %s » contient une page interne à moitié morte" -#: access/nbtree/nbtpage.c:1155 +#: access/nbtree/nbtpage.c:1322 #, c-format msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." msgstr "Ceci peut être dû à un VACUUM interrompu en version 9.3 ou antérieure, avant la mise à jour. Merci d'utiliser REINDEX." -#: access/nbtree/nbtvalidate.c:211 +#: access/nbtree/nbtvalidate.c:236 #, c-format msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès %s nécessite une fonction de support\n" "manquante pour les types %s et %s" -#: access/spgist/spgutils.c:705 +#: access/spgist/spgutils.c:136 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "la méthode de compression doit être définie quand le type feuille est différent du type d'entrée" + +#: access/spgist/spgutils.c:743 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "la taille de la ligne interne SP-GiST, %zu, dépasse le maximum, %zu" -#: access/spgist/spgvalidate.c:221 +#: access/spgist/spgvalidate.c:269 #, c-format msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" msgstr "" @@ -930,10 +955,10 @@ msgstr "la base de données n'accepte pas de commandes qui génèrent de nouveau #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Exécutez un VACUUM sur toute cette base.\n" -"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées." +"Vous pourriez avoir besoin de valider ou d'annuler les anciennes transactions préparées, ou de supprimer les slots de réplication trop anciens" #: access/transam/multixact.c:1007 #, c-format @@ -993,7 +1018,7 @@ msgstr "le MultiXactId %u n'existe plus - wraparound apparent" #: access/transam/multixact.c:1285 #, c-format msgid "MultiXactId %u has not been created yet -- apparent wraparound" -msgstr "le MultiXactId %u n'a pas encore été créer : wraparound apparent" +msgstr "le MultiXactId %u n'a pas encore été créé : wraparound apparent" #: access/transam/multixact.c:2268 #, c-format @@ -1004,11 +1029,11 @@ msgstr "La limite de réinitialisation MultiXactId est %u, limité par la base d #, c-format msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Pour éviter un arrêt de la base de données, exécutez un VACUUM sur toute cette\n" -"base. Vous pouvez avoir besoin d'enregistrer ou d'annuler les anciennes\n" -"transactions préparées." +"base. Vous pourriez avoir besoin d'enregistrer ou d'annuler les slots de réplication\n" +"trop anciens." #: access/transam/multixact.c:2602 #, c-format @@ -1028,7 +1053,7 @@ msgstr "Les protections sur la réutilisation d'un membre MultiXact sont mainten #: access/transam/multixact.c:2631 #, c-format msgid "MultiXact member stop limit is now %u based on MultiXact %u" -msgstr "La limite d'arrêt d'un membre MultiXact est maintenant %x, base sur le MultiXact %u" +msgstr "La limite d'arrêt d'un membre MultiXact est maintenant %u, basée sur le MultiXact %u" #: access/transam/multixact.c:3011 #, c-format @@ -1045,26 +1070,36 @@ msgstr "ne peut pas tronquer jusqu'au MutiXact %u car il n'existe pas sur disque msgid "invalid MultiXactId: %u" msgstr "MultiXactId invalide : %u" -#: access/transam/parallel.c:577 +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "échec de l'initialisation du worker parallèle" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "Plus de détails sont disponibles dans les traces du serveur." + +#: access/transam/parallel.c:849 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "postmaster a quitté pendant une transaction parallèle" -#: access/transam/parallel.c:764 +#: access/transam/parallel.c:1036 #, c-format msgid "lost connection to parallel worker" msgstr "perte de la connexion au processus parallèle" -#: access/transam/parallel.c:823 access/transam/parallel.c:825 +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 msgid "parallel worker" msgstr "processus parallèle" -#: access/transam/parallel.c:968 +#: access/transam/parallel.c:1249 #, c-format msgid "could not map dynamic shared memory segment" msgstr "n'a pas pu mapper le segment de mémoire partagée dynamique" -#: access/transam/parallel.c:973 +#: access/transam/parallel.c:1254 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "numéro magique invalide dans le segment de mémoire partagée dynamique" @@ -1074,47 +1109,47 @@ msgstr "numéro magique invalide dans le segment de mémoire partagée dynamique msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "le fichier « %s » n'existe pas, contenu lu comme des zéros" -#: access/transam/slru.c:907 access/transam/slru.c:913 access/transam/slru.c:920 access/transam/slru.c:927 access/transam/slru.c:934 access/transam/slru.c:941 +#: access/transam/slru.c:906 access/transam/slru.c:912 access/transam/slru.c:919 access/transam/slru.c:926 access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "n'a pas pu accéder au statut de la transaction %u" -#: access/transam/slru.c:908 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "N'a pas pu ouvrir le fichier « %s » : %m." -#: access/transam/slru.c:914 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "N'a pas pu se déplacer dans le fichier « %s » au décalage %u : %m." -#: access/transam/slru.c:921 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "N'a pas pu lire le fichier « %s » au décalage %u : %m." -#: access/transam/slru.c:928 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "N'a pas pu écrire le fichier « %s » au décalage %u : %m." -#: access/transam/slru.c:935 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "N'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m." -#: access/transam/slru.c:942 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "N'a pas pu fermer le fichier « %s » : %m." -#: access/transam/slru.c:1199 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "n'a pas pu tronquer le répertoire « %s » : contournement apparent" -#: access/transam/slru.c:1254 access/transam/slru.c:1310 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "suppression du fichier « %s »" @@ -1156,197 +1191,197 @@ msgstr "" "Les identifiants timeline doivent être plus petits que les enfants des\n" "identifiants timeline." -#: access/transam/timeline.c:418 access/transam/timeline.c:498 access/transam/xlog.c:3256 access/transam/xlog.c:3423 access/transam/xlogfuncs.c:693 commands/copy.c:1776 storage/file/copydir.c:206 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 access/transam/xlog.c:3314 access/transam/xlog.c:3479 access/transam/xlogfuncs.c:683 commands/copy.c:1760 storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "n'a pas pu fermer le fichier « %s » : %m" -#: access/transam/timeline.c:580 +#: access/transam/timeline.c:578 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "la timeline %u requise n'est pas dans l'historique de ce serveur" -#: access/transam/twophase.c:383 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "l'identifiant de la transaction « %s » est trop long" -#: access/transam/twophase.c:390 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" msgstr "les transactions préparées sont désactivées" -#: access/transam/twophase.c:391 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "Configure max_prepared_transactions à une valeur différente de zéro." -#: access/transam/twophase.c:410 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "l'identifiant de la transaction « %s » est déjà utilisé" -#: access/transam/twophase.c:419 access/transam/twophase.c:2340 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "nombre maximum de transactions préparées obtenu" -#: access/transam/twophase.c:420 access/transam/twophase.c:2341 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "Augmentez max_prepared_transactions (actuellement %d)." -#: access/transam/twophase.c:587 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "la transaction préparée d'identifiant « %s » est occupée" -#: access/transam/twophase.c:593 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" msgstr "droit refusé pour terminer la transaction préparée" -#: access/transam/twophase.c:594 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "Doit être super-utilisateur ou l'utilisateur qui a préparé la transaction." -#: access/transam/twophase.c:605 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" msgstr "la transaction préparée appartient à une autre base de données" -#: access/transam/twophase.c:606 +#: access/transam/twophase.c:605 #, c-format msgid "Connect to the database where the transaction was prepared to finish it." msgstr "" "Connectez-vous à la base de données où la transaction a été préparée pour\n" "la terminer." -#: access/transam/twophase.c:621 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "la transaction préparée d'identifiant « %s » n'existe pas" -#: access/transam/twophase.c:1086 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "" "longueur maximale dépassée pour le fichier de statut de la validation en\n" "deux phase" -#: access/transam/twophase.c:1204 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "" "n'a pas pu ouvrir le fichier d'état de la validation en deux phases nommé\n" "« %s » : %m" -#: access/transam/twophase.c:1221 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" msgstr "" "n'a pas pu récupérer des informations sur le fichier d'état de la validation\n" "en deux phases nommé « %s » : %m" -#: access/transam/twophase.c:1255 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "" "n'a pas pu lire le fichier d'état de la validation en deux phases nommé\n" "« %s » : %m" -#: access/transam/twophase.c:1307 access/transam/xlog.c:6356 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Échec lors de l'allocation d'un processeur de lecture de journaux de transactions." -#: access/transam/twophase.c:1313 +#: access/transam/twophase.c:1390 #, c-format msgid "could not read two-phase state from WAL at %X/%X" msgstr "n'a pas pu lire le fichier d'état de la validation en deux phases depuis les journaux de transactions à %X/%X" -#: access/transam/twophase.c:1321 +#: access/transam/twophase.c:1398 #, c-format msgid "expected two-phase state data is not present in WAL at %X/%X" msgstr "" "le fichier d'état de la validation en deux phases attendu n'est pas présent\n" "dans les journaux de transaction à %X/%X" -#: access/transam/twophase.c:1558 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "" "n'a pas pu supprimer le fichier d'état de la validation en deux phases\n" "« %s » : %m" -#: access/transam/twophase.c:1588 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "" "n'a pas pu re-créer le fichier d'état de la validation en deux phases nommé\n" "« %s » : %m" -#: access/transam/twophase.c:1599 access/transam/twophase.c:1607 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 #, c-format msgid "could not write two-phase state file: %m" msgstr "n'a pas pu écrire dans le fichier d'état de la validation en deux phases : %m" -#: access/transam/twophase.c:1621 +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "" "n'a pas pu synchroniser sur disque (fsync) le fichier d'état de la\n" "validation en deux phases : %m" -#: access/transam/twophase.c:1628 +#: access/transam/twophase.c:1719 #, c-format msgid "could not close two-phase state file: %m" msgstr "n'a pas pu fermer le fichier d'état de la validation en deux phases : %m" -#: access/transam/twophase.c:1716 +#: access/transam/twophase.c:1807 #, c-format msgid "%u two-phase state file was written for a long-running prepared transaction" msgid_plural "%u two-phase state files were written for long-running prepared transactions" msgstr[0] "le fichier d'état de la validation en deux phases %u a été écrit pour une transaction préparée de longue durée" msgstr[1] "les fichiers d'état de la validation en deux phases %u a été écrit pour des transactions préparées de longue durée" -#: access/transam/twophase.c:1944 +#: access/transam/twophase.c:2036 #, c-format msgid "recovering prepared transaction %u from shared memory" msgstr "récupération de la transaction préparée %u à partir de la mémoire partagée" -#: access/transam/twophase.c:2034 +#: access/transam/twophase.c:2126 #, c-format -msgid "removing stale two-phase state file for \"%u\"" -msgstr "suppression du vieux fichier d'état de la validation en deux phases pour %u" +msgid "removing stale two-phase state file for transaction %u" +msgstr "suppression du vieux fichier d'état de la validation en deux phases pour la transaction %u" -#: access/transam/twophase.c:2041 +#: access/transam/twophase.c:2133 #, c-format -msgid "removing stale two-phase state from shared memory for \"%u\"" -msgstr "suppression du vieux fichier d'état de la validation en deux phases nommé à partir de la mémoire partagée pour « %u »" +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "suppression du vieux fichier d'état de la validation en deux phases de la mémoire pour la transaction %u" -#: access/transam/twophase.c:2054 +#: access/transam/twophase.c:2146 #, c-format -msgid "removing future two-phase state file for \"%u\"" -msgstr "suppression du futur fichier d'état de la validation en deux phases pour « %u »" +msgid "removing future two-phase state file for transaction %u" +msgstr "suppression du futur fichier d'état de la validation en deux phases pour la transaction %u" -#: access/transam/twophase.c:2061 +#: access/transam/twophase.c:2153 #, c-format -msgid "removing future two-phase state from memory for \"%u\"" -msgstr "suppression du futur fichier d'état de la validation en deux phases en mémoire pour « %u »" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "suppression du futur fichier d'état de la validation en deux phases en mémoire pour la transaction %u" -#: access/transam/twophase.c:2075 access/transam/twophase.c:2094 +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 #, c-format -msgid "removing corrupt two-phase state file for \"%u\"" -msgstr "suppression du fichier d'état corrompu de la validation en deux phases pour « %u »" +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "suppression du fichier d'état corrompu de la validation en deux phases pour la transaction %u" -#: access/transam/twophase.c:2101 +#: access/transam/twophase.c:2193 #, c-format -msgid "removing corrupt two-phase state from memory for \"%u\"" +msgid "removing corrupt two-phase state from memory for transaction %u" msgstr "" "suppression du fichier d'état corrompu de la validation en deux phases en mémoire\n" -"pour « %u »" +"pour la transaction %u" #: access/transam/varsup.c:124 #, c-format @@ -1360,11 +1395,12 @@ msgstr "" #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Arrêtez le postmaster et utilisez un moteur autonome pour exécuter VACUUM\n" "sur cette base de données.\n" -"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées." +"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées,\n" +"ou de supprimer les slots de réplication trop anciens." #: access/transam/varsup.c:131 #, c-format @@ -1395,240 +1431,257 @@ msgstr "" "la limite de réinitialisation de l'identifiant de transaction est %u,\n" "limité par la base de données d'OID %u" -#: access/transam/xact.c:946 +#: access/transam/xact.c:960 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "ne peux pas avoir plus de 2^32-2 commandes dans une transaction" -#: access/transam/xact.c:1471 +#: access/transam/xact.c:1485 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "nombre maximum de sous-transactions validées (%d) dépassé" -#: access/transam/xact.c:2268 +#: access/transam/xact.c:2296 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" msgstr "" "ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" "tables temporaires" -#: access/transam/xact.c:2278 +#: access/transam/xact.c:2308 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "" +"ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" +"objets temporaires" + +#: access/transam/xact.c:2318 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "ne peut pas préparer (PREPARE) une transaction qui a exporté des snapshots" +#: access/transam/xact.c:2327 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "" +"ne peut pas préparer (PREPARE) une transaction qui a travaillé sur des\n" +"workers de réplication logique" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3164 +#: access/transam/xact.c:3212 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s ne peut pas être exécuté dans un bloc de transaction" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3174 +#: access/transam/xact.c:3222 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s ne peut pas être exécuté dans un sous-bloc de transaction" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3184 +#: access/transam/xact.c:3232 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "" -"%s ne peut pas être exécuté à partir d'une fonction ou d'une chaîne\n" -"contenant plusieurs commandes" +msgid "%s cannot be executed from a function" +msgstr "%s ne peut pas être exécuté à partir d'une fonction" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3255 +#: access/transam/xact.c:3301 access/transam/xact.c:3925 access/transam/xact.c:3994 access/transam/xact.c:4105 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s peut seulement être utilisé dans des blocs de transaction" -#: access/transam/xact.c:3439 +#: access/transam/xact.c:3494 #, c-format msgid "there is already a transaction in progress" msgstr "une transaction est déjà en cours" -#: access/transam/xact.c:3607 access/transam/xact.c:3710 +#: access/transam/xact.c:3605 access/transam/xact.c:3675 access/transam/xact.c:3784 #, c-format msgid "there is no transaction in progress" msgstr "aucune transaction en cours" -#: access/transam/xact.c:3618 +#: access/transam/xact.c:3686 #, c-format msgid "cannot commit during a parallel operation" msgstr "ne peut pas valider pendant une opération parallèle" -#: access/transam/xact.c:3721 +#: access/transam/xact.c:3795 #, c-format msgid "cannot abort during a parallel operation" msgstr "ne peut pas annuler pendant une opération en parallèle" -#: access/transam/xact.c:3763 +#: access/transam/xact.c:3889 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "ne peut pas définir de points de sauvegarde lors d'une opération parallèle" -#: access/transam/xact.c:3830 +#: access/transam/xact.c:3976 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "ne peut pas relâcher de points de sauvegarde pendant une opération parallèle" -#: access/transam/xact.c:3841 access/transam/xact.c:3893 access/transam/xact.c:3899 access/transam/xact.c:3955 access/transam/xact.c:4005 access/transam/xact.c:4011 +#: access/transam/xact.c:3986 access/transam/xact.c:4037 access/transam/xact.c:4097 access/transam/xact.c:4146 #, c-format -msgid "no such savepoint" -msgstr "aucun point de sauvegarde" +msgid "savepoint \"%s\" does not exist" +msgstr "le point de sauvegarde « %s » n'existe pas" -#: access/transam/xact.c:3943 +#: access/transam/xact.c:4043 access/transam/xact.c:4152 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "le point de sauvegarde « %s » n'existe pas dans le niveau de point de sauvegarde actuel" + +#: access/transam/xact.c:4085 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "ne peut pas retourner à un point de sauvegarde pendant un opération parallèle" -#: access/transam/xact.c:4071 +#: access/transam/xact.c:4213 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "ne peut pas lancer de sous-transactions pendant une opération parallèle" -#: access/transam/xact.c:4138 +#: access/transam/xact.c:4281 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "ne peut pas valider de sous-transactions pendant une opération parallèle" -#: access/transam/xact.c:4746 +#: access/transam/xact.c:4919 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "ne peut pas avoir plus de 2^32-1 sous-transactions dans une transaction" -#: access/transam/xlog.c:2455 +#: access/transam/xlog.c:2492 #, c-format msgid "could not seek in log file %s to offset %u: %m" msgstr "n'a pas pu se déplacer dans le fichier de transactions « %s » au décalage %u : %m" -#: access/transam/xlog.c:2477 +#: access/transam/xlog.c:2514 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "n'a pas pu écrire le fichier de transactions %s au décalage %u, longueur %zu : %m" -#: access/transam/xlog.c:2741 +#: access/transam/xlog.c:2792 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "mise à jour du point minimum de restauration sur %X/%X pour la timeline %u" -#: access/transam/xlog.c:3388 +#: access/transam/xlog.c:3444 #, c-format msgid "not enough data in file \"%s\"" msgstr "données insuffisantes dans le fichier « %s »" -#: access/transam/xlog.c:3534 +#: access/transam/xlog.c:3589 #, c-format msgid "could not open write-ahead log file \"%s\": %m" msgstr "n'a pas pu écrire dans le journal de transactions « %s » : %m" -#: access/transam/xlog.c:3723 access/transam/xlog.c:5541 +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 #, c-format msgid "could not close log file %s: %m" msgstr "n'a pas pu fermer le fichier de transactions « %s » : %m" -#: access/transam/xlog.c:3780 access/transam/xlogutils.c:701 replication/walsender.c:2380 +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 replication/walsender.c:2410 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "le segment demandé du journal de transaction, %s, a déjà été supprimé" -#: access/transam/xlog.c:3840 access/transam/xlog.c:3915 access/transam/xlog.c:4110 -#, c-format -msgid "could not open write-ahead log directory \"%s\": %m" -msgstr "n'a pas pu ouvrir le répertoire des journaux de transactions « %s » : %m" - -#: access/transam/xlog.c:3996 +#: access/transam/xlog.c:4051 #, c-format msgid "recycled write-ahead log file \"%s\"" msgstr "recyclage du journal de transactions « %s »" -#: access/transam/xlog.c:4008 +#: access/transam/xlog.c:4063 #, c-format msgid "removing write-ahead log file \"%s\"" msgstr "suppression du journal de transactions « %s »" -#: access/transam/xlog.c:4028 +#: access/transam/xlog.c:4083 #, c-format msgid "could not rename old write-ahead log file \"%s\": %m" msgstr "n'a pas pu renommer l'ancien journal de transactions « %s » : %m" -#: access/transam/xlog.c:4070 access/transam/xlog.c:4080 +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "le répertoire « %s » requis pour les journaux de transactions n'existe pas" -#: access/transam/xlog.c:4086 +#: access/transam/xlog.c:4141 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "création du répertoire manquant « %s » pour les journaux de transactions" -#: access/transam/xlog.c:4089 +#: access/transam/xlog.c:4144 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "n'a pas pu créer le répertoire « %s » manquant : %m" -#: access/transam/xlog.c:4200 +#: access/transam/xlog.c:4252 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "identifiant timeline %u inattendu dans le journal de transactions %s, décalage %u" -#: access/transam/xlog.c:4322 +#: access/transam/xlog.c:4380 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "" "le nouveau timeline %u n'est pas un fils du timeline %u du système de bases\n" "de données" -#: access/transam/xlog.c:4336 +#: access/transam/xlog.c:4394 #, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgstr "" "la nouvelle timeline %u a été créée à partir de la timeline de la base de données système %u\n" "avant le point de restauration courant %X/%X" -#: access/transam/xlog.c:4355 +#: access/transam/xlog.c:4413 #, c-format msgid "new target timeline is %u" msgstr "la nouvelle timeline cible est %u" -#: access/transam/xlog.c:4436 +#: access/transam/xlog.c:4493 #, c-format msgid "could not create control file \"%s\": %m" msgstr "n'a pas pu créer le fichier de contrôle « %s » : %m" -#: access/transam/xlog.c:4448 access/transam/xlog.c:4674 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 #, c-format msgid "could not write to control file: %m" msgstr "n'a pas pu écrire le fichier de contrôle : %m" -#: access/transam/xlog.c:4456 access/transam/xlog.c:4682 +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 #, c-format msgid "could not fsync control file: %m" msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier de contrôle : %m" -#: access/transam/xlog.c:4462 access/transam/xlog.c:4688 +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 #, c-format msgid "could not close control file: %m" msgstr "n'a pas pu fermer le fichier de contrôle : %m" -#: access/transam/xlog.c:4480 access/transam/xlog.c:4662 +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 #, c-format msgid "could not open control file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de contrôle « %s » : %m" -#: access/transam/xlog.c:4487 +#: access/transam/xlog.c:4548 #, c-format msgid "could not read from control file: %m" msgstr "n'a pas pu lire le fichier de contrôle : %m" -#: access/transam/xlog.c:4501 access/transam/xlog.c:4510 access/transam/xlog.c:4534 access/transam/xlog.c:4541 access/transam/xlog.c:4548 access/transam/xlog.c:4553 access/transam/xlog.c:4560 access/transam/xlog.c:4567 access/transam/xlog.c:4574 access/transam/xlog.c:4581 access/transam/xlog.c:4588 access/transam/xlog.c:4595 access/transam/xlog.c:4602 access/transam/xlog.c:4611 access/transam/xlog.c:4618 access/transam/xlog.c:4627 -#: access/transam/xlog.c:4634 utils/init/miscinit.c:1406 +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "n'a pas pu lire le fichier de contrôle : lu %d octets, %d attendus" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 access/transam/xlog.c:4599 access/transam/xlog.c:4606 access/transam/xlog.c:4613 access/transam/xlog.c:4618 access/transam/xlog.c:4625 access/transam/xlog.c:4632 access/transam/xlog.c:4639 access/transam/xlog.c:4646 access/transam/xlog.c:4653 access/transam/xlog.c:4660 access/transam/xlog.c:4669 access/transam/xlog.c:4676 access/transam/xlog.c:4685 access/transam/xlog.c:4692 +#: utils/init/miscinit.c:1502 #, c-format msgid "database files are incompatible with server" msgstr "les fichiers de la base de données sont incompatibles avec le serveur" -#: access/transam/xlog.c:4502 +#: access/transam/xlog.c:4567 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "" @@ -1636,303 +1689,318 @@ msgstr "" "%d (0x%08x) alors que le serveur a été compilé avec un PG_CONTROL_VERSION à\n" "%d (0x%08x)." -#: access/transam/xlog.c:4506 +#: access/transam/xlog.c:4571 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "" "Ceci peut être un problème d'incohérence dans l'ordre des octets.\n" "Il se peut que vous ayez besoin d'initdb." -#: access/transam/xlog.c:4511 +#: access/transam/xlog.c:4576 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "" "Le cluster de base de données a été initialisé avec un PG_CONTROL_VERSION à\n" "%d alors que le serveur a été compilé avec un PG_CONTROL_VERSION à %d." -#: access/transam/xlog.c:4514 access/transam/xlog.c:4538 access/transam/xlog.c:4545 access/transam/xlog.c:4550 +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 access/transam/xlog.c:4610 access/transam/xlog.c:4615 #, c-format msgid "It looks like you need to initdb." msgstr "Il semble que vous avez besoin d'initdb." -#: access/transam/xlog.c:4525 +#: access/transam/xlog.c:4590 #, c-format msgid "incorrect checksum in control file" msgstr "somme de contrôle incorrecte dans le fichier de contrôle" -#: access/transam/xlog.c:4535 +#: access/transam/xlog.c:4600 #, c-format msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." msgstr "" "Le cluster de base de données a été initialisé avec un CATALOG_VERSION_NO à\n" "%d alors que le serveur a été compilé avec un CATALOG_VERSION_NO à %d." -#: access/transam/xlog.c:4542 +#: access/transam/xlog.c:4607 #, c-format msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." msgstr "" "Le cluster de bases de données a été initialisé avec un MAXALIGN à %d alors\n" "que le serveur a été compilé avec un MAXALIGN à %d." -#: access/transam/xlog.c:4549 +#: access/transam/xlog.c:4614 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "" "Le cluster de bases de données semble utiliser un format différent pour les\n" "nombres à virgule flottante de celui de l'exécutable serveur." -#: access/transam/xlog.c:4554 +#: access/transam/xlog.c:4619 #, c-format msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "" "Le cluster de base de données a été initialisé avec un BLCKSZ à %d alors que\n" "le serveur a été compilé avec un BLCKSZ à %d." -#: access/transam/xlog.c:4557 access/transam/xlog.c:4564 access/transam/xlog.c:4571 access/transam/xlog.c:4578 access/transam/xlog.c:4585 access/transam/xlog.c:4592 access/transam/xlog.c:4599 access/transam/xlog.c:4606 access/transam/xlog.c:4614 access/transam/xlog.c:4621 access/transam/xlog.c:4630 access/transam/xlog.c:4637 +#: access/transam/xlog.c:4622 access/transam/xlog.c:4629 access/transam/xlog.c:4636 access/transam/xlog.c:4643 access/transam/xlog.c:4650 access/transam/xlog.c:4657 access/transam/xlog.c:4664 access/transam/xlog.c:4672 access/transam/xlog.c:4679 access/transam/xlog.c:4688 access/transam/xlog.c:4695 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "Il semble que vous avez besoin de recompiler ou de relancer initdb." -#: access/transam/xlog.c:4561 +#: access/transam/xlog.c:4626 #, c-format msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." msgstr "" "Le cluster de bases de données a été initialisé avec un RELSEG_SIZE à %d\n" "alors que le serveur a été compilé avec un RELSEG_SIZE à %d." -#: access/transam/xlog.c:4568 +#: access/transam/xlog.c:4633 #, c-format msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." msgstr "" "Le cluster de base de données a été initialisé avec un XLOG_BLCKSZ à %d\n" "alors que le serveur a été compilé avec un XLOG_BLCKSZ à %d." -#: access/transam/xlog.c:4575 -#, c-format -msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." -msgstr "" -"Le cluster de bases de données a été initialisé avec un XLOG_SEG_SIZE à %d\n" -"alors que le serveur a été compilé avec un XLOG_SEG_SIZE à %d." - -#: access/transam/xlog.c:4582 +#: access/transam/xlog.c:4640 #, c-format msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." msgstr "" "Le cluster de bases de données a été initialisé avec un NAMEDATALEN à %d\n" "alors que le serveur a été compilé avec un NAMEDATALEN à %d." -#: access/transam/xlog.c:4589 +#: access/transam/xlog.c:4647 #, c-format msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." msgstr "" "Le groupe de bases de données a été initialisé avec un INDEX_MAX_KEYS à %d\n" "alors que le serveur a été compilé avec un INDEX_MAX_KEYS à %d." -#: access/transam/xlog.c:4596 +#: access/transam/xlog.c:4654 #, c-format msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." msgstr "" "Le cluster de bases de données a été initialisé avec un TOAST_MAX_CHUNK_SIZE\n" "à %d alors que le serveur a été compilé avec un TOAST_MAX_CHUNK_SIZE à %d." -#: access/transam/xlog.c:4603 +#: access/transam/xlog.c:4661 #, c-format msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." msgstr "" "Le cluster de base de données a été initialisé avec un LOBLKSIZE à %d alors que\n" "le serveur a été compilé avec un LOBLKSIZE à %d." -#: access/transam/xlog.c:4612 +#: access/transam/xlog.c:4670 #, c-format msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." msgstr "" "Le cluster de base de données a été initialisé sans USE_FLOAT4_BYVAL\n" "alors que le serveur a été compilé avec USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4619 +#: access/transam/xlog.c:4677 #, c-format msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." msgstr "" "Le cluster de base de données a été initialisé avec USE_FLOAT4_BYVAL\n" "alors que le serveur a été compilé sans USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4628 +#: access/transam/xlog.c:4686 #, c-format msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." msgstr "" "Le cluster de base de données a été initialisé sans USE_FLOAT8_BYVAL\n" "alors que le serveur a été compilé avec USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4635 +#: access/transam/xlog.c:4693 #, c-format msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." msgstr "" "Le cluster de base de données a été initialisé avec USE_FLOAT8_BYVAL\n" "alors que le serveur a été compilé sans USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4991 +#: access/transam/xlog.c:4702 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octet" +msgstr[1] "La taille du segment WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go, mais le fichier de contrôle indique %d octets" + +#: access/transam/xlog.c:4714 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "« min_wal_size » doit être au moins le double de « wal_segment_size »" + +#: access/transam/xlog.c:4718 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "« max_wal_size » doit être au moins le double de « wal_segment_size »" + +#: access/transam/xlog.c:5105 #, c-format msgid "could not generate secret authorization token" msgstr "n'a pas pu générer le jeton secret d'autorisation" -#: access/transam/xlog.c:5081 +#: access/transam/xlog.c:5195 #, c-format msgid "could not write bootstrap write-ahead log file: %m" msgstr "n'a pas pu écrire le « bootstrap » du journal des transactions : %m" -#: access/transam/xlog.c:5089 +#: access/transam/xlog.c:5203 #, c-format msgid "could not fsync bootstrap write-ahead log file: %m" msgstr "" "n'a pas pu synchroniser sur disque (fsync) le « bootstrap » du journal des\n" "transactions : %m" -#: access/transam/xlog.c:5095 +#: access/transam/xlog.c:5209 #, c-format msgid "could not close bootstrap write-ahead log file: %m" msgstr "n'a pas pu fermer le « bootstrap » du journal des transactions : %m" -#: access/transam/xlog.c:5171 +#: access/transam/xlog.c:5291 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de restauration « %s » : %m" -#: access/transam/xlog.c:5217 access/transam/xlog.c:5319 +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 #, c-format msgid "invalid value for recovery parameter \"%s\": \"%s\"" msgstr "valeur invalide pour le paramètre de restauration « %s » : « %s »" -#: access/transam/xlog.c:5220 +#: access/transam/xlog.c:5340 #, c-format msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." msgstr "Les valeurs valides sont « pause », « promote » et « shutdown »." -#: access/transam/xlog.c:5240 +#: access/transam/xlog.c:5360 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" msgstr "recovery_target_timeline n'est pas un nombre valide : « %s »" -#: access/transam/xlog.c:5257 +#: access/transam/xlog.c:5377 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" msgstr "recovery_target_xid n'est pas un nombre valide : « %s »" -#: access/transam/xlog.c:5288 +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_timeline n'est pas un horodatage valide : « %s »" + +#: access/transam/xlog.c:5420 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "recovery_target_name est trop long (%d caractères maximum)" -#: access/transam/xlog.c:5322 +#: access/transam/xlog.c:5454 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "La seule valeur autorisée est « immediate »." -#: access/transam/xlog.c:5335 access/transam/xlog.c:5346 commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5750 +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5997 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "le paramètre « %s » requiert une valeur booléenne" -#: access/transam/xlog.c:5381 +#: access/transam/xlog.c:5513 #, c-format msgid "parameter \"%s\" requires a temporal value" msgstr "le paramètre « %s » requiert une valeur temporelle" -#: access/transam/xlog.c:5383 catalog/dependency.c:961 catalog/dependency.c:962 catalog/dependency.c:968 catalog/dependency.c:969 catalog/dependency.c:980 catalog/dependency.c:981 commands/tablecmds.c:946 commands/tablecmds.c:10345 commands/user.c:1029 commands/view.c:505 libpq/auth.c:328 replication/syncrep.c:1160 storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1313 utils/adt/acl.c:5248 utils/misc/guc.c:5772 utils/misc/guc.c:5865 -#: utils/misc/guc.c:9821 utils/misc/guc.c:9855 utils/misc/guc.c:9889 utils/misc/guc.c:9923 utils/misc/guc.c:9958 +#: access/transam/xlog.c:5515 catalog/dependency.c:969 catalog/dependency.c:970 catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 catalog/dependency.c:989 commands/tablecmds.c:1072 commands/tablecmds.c:11306 commands/user.c:1064 commands/view.c:504 libpq/auth.c:336 replication/syncrep.c:1162 storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1331 utils/adt/acl.c:5344 utils/misc/guc.c:6019 utils/misc/guc.c:6112 +#: utils/misc/guc.c:10102 utils/misc/guc.c:10136 utils/misc/guc.c:10170 utils/misc/guc.c:10204 utils/misc/guc.c:10239 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlog.c:5390 +#: access/transam/xlog.c:5522 #, c-format msgid "unrecognized recovery parameter \"%s\"" msgstr "paramètre de restauration « %s » non reconnu" -#: access/transam/xlog.c:5401 +#: access/transam/xlog.c:5533 #, c-format msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" msgstr "le fichier de restauration « %s » n'a spécifié ni primary_conninfo ni restore_command" -#: access/transam/xlog.c:5403 +#: access/transam/xlog.c:5535 #, c-format msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." msgstr "" "Le serveur de la base de données va régulièrement interroger le sous-répertoire\n" "pg_wal pour vérifier les fichiers placés ici." -#: access/transam/xlog.c:5410 +#: access/transam/xlog.c:5542 #, c-format msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" msgstr "" "le fichier de restauration « %s » doit spécifier restore_command quand le mode\n" "de restauration n'est pas activé" -#: access/transam/xlog.c:5431 +#: access/transam/xlog.c:5563 #, c-format msgid "standby mode is not supported by single-user servers" msgstr "le mode de restauration n'est pas supporté pour les serveurs mono-utilisateur" -#: access/transam/xlog.c:5450 +#: access/transam/xlog.c:5582 #, c-format msgid "recovery target timeline %u does not exist" msgstr "le timeline cible, %u, de la restauration n'existe pas" -#: access/transam/xlog.c:5571 +#: access/transam/xlog.c:5703 #, c-format msgid "archive recovery complete" msgstr "restauration terminée de l'archive" -#: access/transam/xlog.c:5630 access/transam/xlog.c:5896 +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 #, c-format msgid "recovery stopping after reaching consistency" msgstr "arrêt de la restauration après avoir atteint le point de cohérence" -#: access/transam/xlog.c:5651 +#: access/transam/xlog.c:5783 #, c-format msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" msgstr "arrêt de la restauration avant l'emplacement WAL (LSN) « %X/%X »" -#: access/transam/xlog.c:5737 +#: access/transam/xlog.c:5869 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "arrêt de la restauration avant validation de la transaction %u, %s" -#: access/transam/xlog.c:5744 +#: access/transam/xlog.c:5876 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "arrêt de la restauration avant annulation de la transaction %u, %s" -#: access/transam/xlog.c:5790 +#: access/transam/xlog.c:5922 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "restauration en arrêt au point de restauration « %s », heure %s" -#: access/transam/xlog.c:5808 +#: access/transam/xlog.c:5940 #, c-format msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" msgstr "arrêt de la restauration après l'emplacement WAL (LSN) « %X/%X »" -#: access/transam/xlog.c:5876 +#: access/transam/xlog.c:6008 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "arrêt de la restauration après validation de la transaction %u, %s" -#: access/transam/xlog.c:5884 +#: access/transam/xlog.c:6016 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "arrêt de la restauration après annulation de la transaction %u, %s" -#: access/transam/xlog.c:5924 +#: access/transam/xlog.c:6056 #, c-format msgid "recovery has paused" msgstr "restauration en pause" -#: access/transam/xlog.c:5925 +#: access/transam/xlog.c:6057 #, c-format msgid "Execute pg_wal_replay_resume() to continue." msgstr "Exécuter pg_wal_replay_resume() pour continuer." -#: access/transam/xlog.c:6133 +#: access/transam/xlog.c:6265 #, c-format msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" msgstr "" @@ -1940,271 +2008,266 @@ msgstr "" "paramètrage plus bas que celui du serveur maître des journaux de transactions\n" "(la valeur était %d)" -#: access/transam/xlog.c:6159 +#: access/transam/xlog.c:6291 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "" "le journal de transactions a été généré avec le paramètre wal_level configuré\n" "à « minimal », des données pourraient manquer" -#: access/transam/xlog.c:6160 +#: access/transam/xlog.c:6292 #, c-format msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." msgstr "" "Ceci peut arriver si vous configurez temporairement wal_level à minimal sans avoir\n" "pris une nouvelle sauvegarde de base." -#: access/transam/xlog.c:6171 +#: access/transam/xlog.c:6303 #, c-format msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" msgstr "" "les connexions en lecture seules ne sont pas possibles parce que le paramètre wal_level\n" "n'a pas été positionné à « replica » ou plus sur le serveur maître" -#: access/transam/xlog.c:6172 +#: access/transam/xlog.c:6304 #, c-format msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." msgstr "" "Vous devez soit positionner le paramètre wal_level à « replica » sur le maître,\n" "soit désactiver le hot_standby ici." -#: access/transam/xlog.c:6229 +#: access/transam/xlog.c:6356 #, c-format msgid "control file contains invalid data" msgstr "le fichier de contrôle contient des données invalides" -#: access/transam/xlog.c:6235 +#: access/transam/xlog.c:6362 #, c-format msgid "database system was shut down at %s" msgstr "le système de bases de données a été arrêté à %s" -#: access/transam/xlog.c:6240 +#: access/transam/xlog.c:6367 #, c-format msgid "database system was shut down in recovery at %s" msgstr "le système de bases de données a été arrêté pendant la restauration à %s" -#: access/transam/xlog.c:6244 +#: access/transam/xlog.c:6371 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "le système de bases de données a été interrompu ; dernier lancement connu à %s" -#: access/transam/xlog.c:6248 +#: access/transam/xlog.c:6375 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "le système de bases de données a été interrompu lors d'une restauration à %s" -#: access/transam/xlog.c:6250 +#: access/transam/xlog.c:6377 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "" "Ceci signifie probablement que des données ont été corrompues et que vous\n" "devrez utiliser la dernière sauvegarde pour la restauration." -#: access/transam/xlog.c:6254 +#: access/transam/xlog.c:6381 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "" "le système de bases de données a été interrompu lors d'une récupération à %s\n" "(moment de la journalisation)" -#: access/transam/xlog.c:6256 +#: access/transam/xlog.c:6383 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." msgstr "" "Si c'est arrivé plus d'une fois, des données ont pu être corrompues et vous\n" "pourriez avoir besoin de choisir une cible de récupération antérieure." -#: access/transam/xlog.c:6260 +#: access/transam/xlog.c:6387 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "le système de bases de données a été interrompu ; dernier lancement connu à %s" -#: access/transam/xlog.c:6316 +#: access/transam/xlog.c:6443 #, c-format msgid "entering standby mode" msgstr "entre en mode standby" -#: access/transam/xlog.c:6319 +#: access/transam/xlog.c:6446 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "début de la restauration de l'archive au XID %u" -#: access/transam/xlog.c:6323 +#: access/transam/xlog.c:6450 #, c-format msgid "starting point-in-time recovery to %s" msgstr "début de la restauration de l'archive à %s" -#: access/transam/xlog.c:6327 +#: access/transam/xlog.c:6454 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "début de la restauration PITR à « %s »" -#: access/transam/xlog.c:6331 +#: access/transam/xlog.c:6458 #, c-format msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" msgstr "début de la restauration PITR à l'emplacement WAL (LSN) « %X/%X »" -#: access/transam/xlog.c:6336 +#: access/transam/xlog.c:6463 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "début de la restauration de l'archive jusqu'au point de cohérence le plus proche" -#: access/transam/xlog.c:6339 +#: access/transam/xlog.c:6466 #, c-format msgid "starting archive recovery" msgstr "début de la restauration de l'archive" -#: access/transam/xlog.c:6390 access/transam/xlog.c:6518 +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 #, c-format msgid "checkpoint record is at %X/%X" msgstr "l'enregistrement du point de vérification est à %X/%X" -#: access/transam/xlog.c:6404 +#: access/transam/xlog.c:6534 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "n'a pas pu localiser l'enregistrement redo référencé par le point de vérification" -#: access/transam/xlog.c:6405 access/transam/xlog.c:6412 +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 #, c-format msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." msgstr "" "Si vous n'avez pas pu restaurer une sauvegarde, essayez de supprimer le\n" "fichier « %s/backup_label »." -#: access/transam/xlog.c:6411 +#: access/transam/xlog.c:6541 #, c-format msgid "could not locate required checkpoint record" msgstr "n'a pas pu localiser l'enregistrement d'un point de vérification requis" -#: access/transam/xlog.c:6437 commands/tablespace.c:639 +#: access/transam/xlog.c:6567 commands/tablespace.c:641 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "n'a pas pu créer le lien symbolique « %s » : %m" -#: access/transam/xlog.c:6469 access/transam/xlog.c:6475 +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "ignore le fichier « %s » car le fichier « %s » n'existe pas" -#: access/transam/xlog.c:6471 access/transam/xlog.c:11396 +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "Le fichier « %s » a été renommé en « %s »." -#: access/transam/xlog.c:6477 +#: access/transam/xlog.c:6607 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "N'a pas pu renommer le fichier « %s » en « %s » : %m" -#: access/transam/xlog.c:6528 access/transam/xlog.c:6543 +#: access/transam/xlog.c:6657 #, c-format msgid "could not locate a valid checkpoint record" msgstr "n'a pas pu localiser un enregistrement d'un point de vérification valide" -#: access/transam/xlog.c:6537 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "utilisation du précédent enregistrement d'un point de vérification à %X/%X" - -#: access/transam/xlog.c:6581 +#: access/transam/xlog.c:6695 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "la timeline requise %u n'est pas un fils de l'historique de ce serveur" -#: access/transam/xlog.c:6583 +#: access/transam/xlog.c:6697 #, c-format msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." msgstr "Le dernier checkpoint est à %X/%X sur la timeline %u, mais dans l'historique de la timeline demandée, le serveur est sorti de cette timeline à %X/%X." -#: access/transam/xlog.c:6599 +#: access/transam/xlog.c:6713 #, c-format msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" msgstr "la timeline requise, %u, ne contient pas le point de restauration minimum (%X/%X) sur la timeline %u" -#: access/transam/xlog.c:6630 +#: access/transam/xlog.c:6744 #, c-format msgid "invalid next transaction ID" msgstr "prochain ID de transaction invalide" -#: access/transam/xlog.c:6724 +#: access/transam/xlog.c:6839 #, c-format msgid "invalid redo in checkpoint record" msgstr "ré-exécution invalide dans l'enregistrement du point de vérification" -#: access/transam/xlog.c:6735 +#: access/transam/xlog.c:6850 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "enregistrement de ré-exécution invalide dans le point de vérification d'arrêt" -#: access/transam/xlog.c:6763 +#: access/transam/xlog.c:6878 #, c-format msgid "database system was not properly shut down; automatic recovery in progress" msgstr "" "le système de bases de données n'a pas été arrêté proprement ; restauration\n" "automatique en cours" -#: access/transam/xlog.c:6767 +#: access/transam/xlog.c:6882 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" -msgstr "la restauration après crash commence avec la timeline %u et a la timeline %u en cible" +msgstr "la restauration après crash commence par la timeline %u et a la timeline %u en cible" -#: access/transam/xlog.c:6811 +#: access/transam/xlog.c:6925 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label contient des données incohérentes avec le fichier de contrôle" -#: access/transam/xlog.c:6812 +#: access/transam/xlog.c:6926 #, c-format msgid "This means that the backup is corrupted and you will have to use another backup for recovery." msgstr "" "Ceci signifie que la sauvegarde a été corrompue et que vous devrez utiliser\n" "la dernière sauvegarde pour la restauration." -#: access/transam/xlog.c:6886 +#: access/transam/xlog.c:7017 #, c-format msgid "initializing for hot standby" msgstr "initialisation pour « Hot Standby »" -#: access/transam/xlog.c:7018 +#: access/transam/xlog.c:7149 #, c-format msgid "redo starts at %X/%X" msgstr "la ré-exécution commence à %X/%X" -#: access/transam/xlog.c:7252 +#: access/transam/xlog.c:7383 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "" "le point d'arrêt de la restauration demandée se trouve avant le point\n" "cohérent de restauration" -#: access/transam/xlog.c:7290 +#: access/transam/xlog.c:7421 #, c-format msgid "redo done at %X/%X" msgstr "ré-exécution faite à %X/%X" -#: access/transam/xlog.c:7295 access/transam/xlog.c:9309 +#: access/transam/xlog.c:7426 #, c-format msgid "last completed transaction was at log time %s" msgstr "la dernière transaction a eu lieu à %s (moment de la journalisation)" -#: access/transam/xlog.c:7304 +#: access/transam/xlog.c:7435 #, c-format msgid "redo is not required" msgstr "la ré-exécution n'est pas nécessaire" -#: access/transam/xlog.c:7379 access/transam/xlog.c:7383 +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 #, c-format msgid "WAL ends before end of online backup" msgstr "le journal de transactions se termine avant la fin de la sauvegarde de base" -#: access/transam/xlog.c:7380 +#: access/transam/xlog.c:7511 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "" "Tous les journaux de transactions générés pendant la sauvegarde en ligne\n" "doivent être disponibles pour la restauration." -#: access/transam/xlog.c:7384 +#: access/transam/xlog.c:7515 #, c-format msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." msgstr "" @@ -2212,225 +2275,204 @@ msgstr "" "pg_stop_backup() et tous les journaux de transactions générés entre les deux\n" "doivent être disponibles pour la restauration." -#: access/transam/xlog.c:7387 +#: access/transam/xlog.c:7518 #, c-format msgid "WAL ends before consistent recovery point" msgstr "Le journal de transaction se termine avant un point de restauration cohérent" -#: access/transam/xlog.c:7414 +#: access/transam/xlog.c:7552 #, c-format msgid "selected new timeline ID: %u" msgstr "identifiant d'un timeline nouvellement sélectionné : %u" -#: access/transam/xlog.c:7843 +#: access/transam/xlog.c:7989 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "état de restauration cohérent atteint à %X/%X" -#: access/transam/xlog.c:8035 +#: access/transam/xlog.c:8181 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "lien du point de vérification primaire invalide dans le fichier de contrôle" -#: access/transam/xlog.c:8039 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "lien du point de vérification secondaire invalide dans le fichier de contrôle" - -#: access/transam/xlog.c:8043 +#: access/transam/xlog.c:8185 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "lien du point de vérification invalide dans le fichier backup_label" -#: access/transam/xlog.c:8060 +#: access/transam/xlog.c:8202 #, c-format msgid "invalid primary checkpoint record" msgstr "enregistrement du point de vérification primaire invalide" -#: access/transam/xlog.c:8064 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "enregistrement du point de vérification secondaire invalide" - -#: access/transam/xlog.c:8068 +#: access/transam/xlog.c:8206 #, c-format msgid "invalid checkpoint record" msgstr "enregistrement du point de vérification invalide" -#: access/transam/xlog.c:8079 +#: access/transam/xlog.c:8217 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement primaire du point de vérification" -#: access/transam/xlog.c:8083 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement secondaire du point de vérification" - -#: access/transam/xlog.c:8087 +#: access/transam/xlog.c:8221 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement du point de vérification" -#: access/transam/xlog.c:8100 +#: access/transam/xlog.c:8234 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "xl_info invalide dans l'enregistrement du point de vérification primaire" -#: access/transam/xlog.c:8104 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "xl_info invalide dans l'enregistrement du point de vérification secondaire" - -#: access/transam/xlog.c:8108 +#: access/transam/xlog.c:8238 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "xl_info invalide dans l'enregistrement du point de vérification" -#: access/transam/xlog.c:8119 +#: access/transam/xlog.c:8249 #, c-format msgid "invalid length of primary checkpoint record" msgstr "longueur invalide de l'enregistrement primaire du point de vérification" -#: access/transam/xlog.c:8123 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "longueur invalide de l'enregistrement secondaire du point de vérification" - -#: access/transam/xlog.c:8127 +#: access/transam/xlog.c:8253 #, c-format msgid "invalid length of checkpoint record" msgstr "longueur invalide de l'enregistrement du point de vérification" -#: access/transam/xlog.c:8330 +#: access/transam/xlog.c:8459 #, c-format msgid "shutting down" msgstr "arrêt en cours" -#: access/transam/xlog.c:8649 +#: access/transam/xlog.c:8779 #, c-format -msgid "checkpoint skipped due to an idle system" -msgstr "checkpoint ignoré, le système étant en attente" +msgid "checkpoint skipped because system is idle" +msgstr "checkpoint ignoré car le système est inactif" -#: access/transam/xlog.c:8854 -#, fuzzy, c-format -#| msgid "concurrent transaction log activity while database system is shutting down" +#: access/transam/xlog.c:8984 +#, c-format msgid "concurrent write-ahead log activity while database system is shutting down" msgstr "" "activité en cours du journal de transactions alors que le système de bases\n" "de données est en cours d'arrêt" -#: access/transam/xlog.c:9108 +#: access/transam/xlog.c:9241 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "restartpoint ignoré, la récupération est déjà terminée" -#: access/transam/xlog.c:9131 +#: access/transam/xlog.c:9264 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "ignore le point de redémarrage, déjà réalisé à %X/%X" -#: access/transam/xlog.c:9307 +#: access/transam/xlog.c:9431 #, c-format msgid "recovery restart point at %X/%X" msgstr "la ré-exécution en restauration commence à %X/%X" -#: access/transam/xlog.c:9443 +#: access/transam/xlog.c:9433 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "la dernière transaction a eu lieu à %s (moment de la journalisation)." + +#: access/transam/xlog.c:9567 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "point de restauration « %s » créé à %X/%X" -#: access/transam/xlog.c:9573 +#: access/transam/xlog.c:9705 #, c-format msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "identifiant de timeline précédent %u inattendu (identifiant de la timeline courante %u) dans l'enregistrement du point de vérification" -#: access/transam/xlog.c:9582 +#: access/transam/xlog.c:9714 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "" "identifiant timeline %u inattendu (après %u) dans l'enregistrement du point\n" "de vérification" -#: access/transam/xlog.c:9598 +#: access/transam/xlog.c:9730 #, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgstr "identifiant timeline %u inattendu dans l'enregistrement du checkpoint, avant d'atteindre le point de restauration minimum %X/%X sur la timeline %u" -#: access/transam/xlog.c:9674 +#: access/transam/xlog.c:9806 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "la sauvegarde en ligne a été annulée, la restauration ne peut pas continuer" -#: access/transam/xlog.c:9730 access/transam/xlog.c:9777 access/transam/xlog.c:9800 +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 access/transam/xlog.c:9941 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "" "identifiant timeline %u inattendu (devrait être %u) dans l'enregistrement du\n" "point de vérification" -#: access/transam/xlog.c:10076 +#: access/transam/xlog.c:10222 #, c-format msgid "could not fsync log segment %s: %m" msgstr "n'a pas pu synchroniser sur disque (fsync) le segment du journal des transactions %s : %m" -#: access/transam/xlog.c:10101 +#: access/transam/xlog.c:10247 #, c-format msgid "could not fsync log file %s: %m" msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier de transactions « %s » : %m" -#: access/transam/xlog.c:10109 +#: access/transam/xlog.c:10255 #, c-format msgid "could not fsync write-through log file %s: %m" msgstr "n'a pas pu synchroniser sur disque (fsync) le journal des transactions %s : %m" -#: access/transam/xlog.c:10118 +#: access/transam/xlog.c:10264 #, c-format msgid "could not fdatasync log file %s: %m" msgstr "n'a pas pu synchroniser sur disque (fdatasync) le journal de transactions %s : %m" -#: access/transam/xlog.c:10209 access/transam/xlog.c:10727 access/transam/xlogfuncs.c:297 access/transam/xlogfuncs.c:324 access/transam/xlogfuncs.c:363 access/transam/xlogfuncs.c:384 access/transam/xlogfuncs.c:405 +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "" "les fonctions de contrôle des journaux de transactions ne peuvent pas\n" "être exécutées lors de la restauration." -#: access/transam/xlog.c:10218 access/transam/xlog.c:10736 +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "" "Le niveau de journalisation (configuré par wal_level) n'est pas suffisant pour\n" "faire une sauvegarde en ligne." -#: access/transam/xlog.c:10219 access/transam/xlog.c:10737 access/transam/xlogfuncs.c:330 +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 access/transam/xlogfuncs.c:320 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "" "wal_level doit être configuré à « replica » ou « logical »\n" "au démarrage du serveur." -#: access/transam/xlog.c:10224 +#: access/transam/xlog.c:10370 #, c-format msgid "backup label too long (max %d bytes)" msgstr "label de sauvegarde trop long (%d octets maximum)" -#: access/transam/xlog.c:10261 access/transam/xlog.c:10534 access/transam/xlog.c:10572 +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 access/transam/xlog.c:10721 #, c-format msgid "a backup is already in progress" msgstr "une sauvegarde est déjà en cours" -#: access/transam/xlog.c:10262 +#: access/transam/xlog.c:10408 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "Exécutez pg_stop_backup() et tentez de nouveau." -#: access/transam/xlog.c:10357 +#: access/transam/xlog.c:10504 #, c-format msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" msgstr "Les journaux générés avec full_page_writes=off ont été rejoués depuis le dernier restartpoint." -#: access/transam/xlog.c:10359 access/transam/xlog.c:10917 +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." msgstr "" @@ -2438,86 +2480,86 @@ msgstr "" "corrompue et ne doit pas être utilisée. Activez full_page_writes et lancez\n" "CHECKPOINT sur le maître, puis recommencez la sauvegarde." -#: access/transam/xlog.c:10426 replication/basebackup.c:1096 utils/adt/misc.c:497 +#: access/transam/xlog.c:10574 replication/basebackup.c:1232 utils/adt/misc.c:517 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "n'a pas pu lire le lien symbolique « %s » : %m" -#: access/transam/xlog.c:10433 replication/basebackup.c:1101 utils/adt/misc.c:502 +#: access/transam/xlog.c:10581 replication/basebackup.c:1237 utils/adt/misc.c:522 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "la cible du lien symbolique « %s » est trop long" -#: access/transam/xlog.c:10486 commands/tablespace.c:389 commands/tablespace.c:551 replication/basebackup.c:1116 utils/adt/misc.c:510 +#: access/transam/xlog.c:10633 commands/tablespace.c:391 commands/tablespace.c:553 replication/basebackup.c:1252 utils/adt/misc.c:530 #, c-format msgid "tablespaces are not supported on this platform" msgstr "les tablespaces ne sont pas supportés sur cette plateforme" -#: access/transam/xlog.c:10528 access/transam/xlog.c:10566 access/transam/xlog.c:10775 access/transam/xlogarchive.c:105 access/transam/xlogarchive.c:264 commands/copy.c:1897 commands/copy.c:3127 commands/extension.c:3319 commands/tablespace.c:780 commands/tablespace.c:871 guc-file.l:1001 replication/basebackup.c:480 replication/basebackup.c:548 replication/logical/snapbuild.c:1518 storage/file/copydir.c:72 storage/file/copydir.c:115 -#: storage/file/fd.c:2954 storage/file/fd.c:3046 utils/adt/dbsize.c:70 utils/adt/dbsize.c:227 utils/adt/dbsize.c:307 utils/adt/genfile.c:115 utils/adt/genfile.c:334 +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 access/transam/xlog.c:10930 access/transam/xlogarchive.c:104 access/transam/xlogarchive.c:264 commands/copy.c:1890 commands/copy.c:3206 commands/extension.c:3326 commands/tablespace.c:782 commands/tablespace.c:873 guc-file.l:1004 replication/basebackup.c:523 replication/basebackup.c:593 replication/logical/snapbuild.c:1528 storage/file/copydir.c:68 storage/file/copydir.c:107 +#: storage/file/fd.c:1752 storage/file/fd.c:3132 storage/file/fd.c:3314 storage/file/fd.c:3399 utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:131 utils/adt/genfile.c:382 #, c-format msgid "could not stat file \"%s\": %m" msgstr "n'a pas pu tester le fichier « %s » : %m" -#: access/transam/xlog.c:10535 access/transam/xlog.c:10573 +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 #, c-format msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." msgstr "" "Si vous êtes certain qu'aucune sauvegarde n'est en cours, supprimez le\n" "fichier « %s » et recommencez de nouveau." -#: access/transam/xlog.c:10552 access/transam/xlog.c:10590 access/transam/xlog.c:10978 postmaster/syslogger.c:1391 postmaster/syslogger.c:1404 +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 access/transam/xlog.c:11150 postmaster/syslogger.c:1493 postmaster/syslogger.c:1506 #, c-format msgid "could not write file \"%s\": %m" msgstr "impossible d'écrire le fichier « %s » : %m" -#: access/transam/xlog.c:10752 +#: access/transam/xlog.c:10907 #, c-format msgid "exclusive backup not in progress" msgstr "une sauvegarde exclusive n'est pas en cours" -#: access/transam/xlog.c:10779 +#: access/transam/xlog.c:10934 #, c-format msgid "a backup is not in progress" msgstr "une sauvegarde n'est pas en cours" -#: access/transam/xlog.c:10852 access/transam/xlog.c:10865 access/transam/xlog.c:11206 access/transam/xlog.c:11212 access/transam/xlog.c:11296 access/transam/xlogfuncs.c:698 +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 access/transam/xlog.c:11394 access/transam/xlog.c:11400 access/transam/xlog.c:11448 access/transam/xlog.c:11521 access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" msgstr "données invalides dans le fichier « %s »" -#: access/transam/xlog.c:10869 replication/basebackup.c:994 +#: access/transam/xlog.c:11037 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "le standby a été promu lors de la sauvegarde en ligne" -#: access/transam/xlog.c:10870 replication/basebackup.c:995 +#: access/transam/xlog.c:11038 replication/basebackup.c:1090 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "" "Cela signifie que la sauvegarde en cours de réalisation est corrompue et ne\n" "doit pas être utilisée. Recommencez la sauvegarde." -#: access/transam/xlog.c:10915 +#: access/transam/xlog.c:11085 #, c-format msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "" "le journal de transactions généré avec full_page_writes=off a été rejoué lors\n" "de la sauvegarde en ligne" -#: access/transam/xlog.c:11028 +#: access/transam/xlog.c:11205 #, c-format msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" msgstr "nettoyage de pg_stop_backup terminé, en attente des journaux de transactions requis à archiver" -#: access/transam/xlog.c:11038 +#: access/transam/xlog.c:11215 #, c-format msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "" "pg_stop_backup toujours en attente de la fin de l'archivage des segments de\n" "journaux de transactions requis (%d secondes passées)" -#: access/transam/xlog.c:11040 +#: access/transam/xlog.c:11217 #, c-format msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." msgstr "" @@ -2525,12 +2567,12 @@ msgstr "" "peut être annulé avec sûreté mais la sauvegarde de la base ne sera pas\n" "utilisable sans tous les segments WAL." -#: access/transam/xlog.c:11047 +#: access/transam/xlog.c:11224 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" msgstr "pg_stop_backup terminé, tous les journaux de transactions requis ont été archivés" -#: access/transam/xlog.c:11051 +#: access/transam/xlog.c:11228 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "" @@ -2538,58 +2580,78 @@ msgstr "" "vous devez vous assurer que tous les fichiers requis des journaux de\n" "transactions sont copiés par d'autre moyens pour terminer la sauvegarde." +#: access/transam/xlog.c:11431 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "heure de sauvegarde %s dans le fichier « %s »" + +#: access/transam/xlog.c:11436 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "label de sauvegarde %s dans le fichier « %s" + +#: access/transam/xlog.c:11449 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "L'identifiant de timeline parsé est %u, mais %u était attendu" + +#: access/transam/xlog.c:11453 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "timeline de sauvegarde %u dans le fichier « %s" + #. translator: %s is a WAL record description -#: access/transam/xlog.c:11336 +#: access/transam/xlog.c:11561 #, c-format msgid "WAL redo at %X/%X for %s" msgstr "rejeu des WAL à %X/%X pour %s" -#: access/transam/xlog.c:11385 +#: access/transam/xlog.c:11610 #, c-format msgid "online backup mode was not canceled" msgstr "le mode de sauvegarde en ligne n'a pas été annulé" -#: access/transam/xlog.c:11386 +#: access/transam/xlog.c:11611 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "Le fichier « %s » n'a pas pu être renommé en « %s » : %m" -#: access/transam/xlog.c:11395 access/transam/xlog.c:11407 access/transam/xlog.c:11417 +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 access/transam/xlog.c:11642 #, c-format msgid "online backup mode canceled" msgstr "mode de sauvegarde en ligne annulé" -#: access/transam/xlog.c:11408 +#: access/transam/xlog.c:11633 #, c-format msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "Les fichiers « %s » et « %s » sont renommés respectivement « %s » et « %s »." -#: access/transam/xlog.c:11418 +#: access/transam/xlog.c:11643 #, c-format msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." msgstr "Le fichier « %s » a été renommé en « %s », mais le fichier « %s » n'a pas pu être renommé en « %s » : %m" -#: access/transam/xlog.c:11540 access/transam/xlogutils.c:724 replication/walreceiver.c:1005 replication/walsender.c:2397 +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 replication/walreceiver.c:1019 replication/walsender.c:2427 #, c-format msgid "could not seek in log segment %s to offset %u: %m" msgstr "n'a pas pu se déplacer dans le journal de transactions %s au décalage %u : %m" -#: access/transam/xlog.c:11554 +#: access/transam/xlog.c:11785 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "n'a pas pu lire le journal de transactions %s, décalage %u : %m" -#: access/transam/xlog.c:12043 +#: access/transam/xlog.c:12314 #, c-format msgid "received promote request" msgstr "a reçu une demande de promotion" -#: access/transam/xlog.c:12056 +#: access/transam/xlog.c:12327 #, c-format msgid "trigger file found: %s" msgstr "fichier trigger trouvé : %s" -#: access/transam/xlog.c:12065 +#: access/transam/xlog.c:12336 #, c-format msgid "could not stat trigger file \"%s\": %m" msgstr "n'a pas pu tester le fichier trigger « %s » : %m" @@ -2604,7 +2666,7 @@ msgstr "le fichier d'archive « %s » a la mauvaise taille : %lu au lieu de %lu" msgid "restored log file \"%s\" from archive" msgstr "restauration du journal de transactions « %s » à partir de l'archive" -#: access/transam/xlogarchive.c:302 +#: access/transam/xlogarchive.c:297 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "n'a pas pu restaurer le fichier « %s » à partir de l'archive : %s" @@ -2612,267 +2674,267 @@ msgstr "n'a pas pu restaurer le fichier « %s » à partir de l'archive : %s" #. translator: First %s represents a recovery.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:414 +#: access/transam/xlogarchive.c:406 #, c-format msgid "%s \"%s\": %s" msgstr "%s « %s »: %s" -#: access/transam/xlogarchive.c:457 postmaster/syslogger.c:1415 replication/logical/snapbuild.c:1645 replication/slot.c:589 replication/slot.c:1189 replication/slot.c:1303 storage/file/fd.c:642 storage/file/fd.c:737 utils/time/snapmgr.c:1318 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1517 replication/logical/snapbuild.c:1667 replication/slot.c:598 replication/slot.c:1211 replication/slot.c:1326 storage/file/fd.c:669 storage/file/fd.c:764 utils/time/snapmgr.c:1318 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "n'a pas pu créer le fichier de statut d'archivage « %s » : %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:596 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "n'a pas pu écrire le fichier de statut d'archivage « %s » : %m" -#: access/transam/xlogfuncs.c:55 +#: access/transam/xlogfuncs.c:54 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "annulation de la sauvegarde due à la déconnexion du processus serveur avant que pg_stop_backup ne soit appelé" -#: access/transam/xlogfuncs.c:86 +#: access/transam/xlogfuncs.c:84 #, c-format msgid "a backup is already in progress in this session" msgstr "une sauvegarde est déjà en cours dans cette session" -#: access/transam/xlogfuncs.c:92 commands/tablespace.c:703 commands/tablespace.c:713 postmaster/postmaster.c:1458 replication/basebackup.c:368 replication/basebackup.c:708 storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2420 storage/file/fd.c:3019 storage/ipc/dsm.c:301 utils/adt/genfile.c:440 utils/adt/misc.c:410 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" - -#: access/transam/xlogfuncs.c:152 access/transam/xlogfuncs.c:234 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format msgid "non-exclusive backup in progress" msgstr "une sauvegarde non exclusive est en cours" -#: access/transam/xlogfuncs.c:153 access/transam/xlogfuncs.c:235 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "Souhaitiez-vous utiliser pg_stop_backup('f') ?" -#: access/transam/xlogfuncs.c:205 commands/event_trigger.c:1471 commands/event_trigger.c:2022 commands/extension.c:1895 commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:721 executor/execExpr.c:2121 executor/execSRF.c:688 executor/functions.c:1029 foreign/foreign.c:488 libpq/hba.c:2563 replication/logical/launcher.c:936 replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1387 replication/slotfuncs.c:197 -#: replication/walsender.c:3166 utils/adt/jsonfuncs.c:1689 utils/adt/jsonfuncs.c:1819 utils/adt/jsonfuncs.c:2007 utils/adt/jsonfuncs.c:2134 utils/adt/jsonfuncs.c:3489 utils/adt/pgstatfuncs.c:456 utils/adt/pgstatfuncs.c:557 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8549 utils/mmgr/portalmem.c:1053 +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 commands/event_trigger.c:2016 commands/extension.c:1902 commands/extension.c:2011 commands/extension.c:2235 commands/prepare.c:722 executor/execExpr.c:2209 executor/execSRF.c:715 executor/functions.c:1034 foreign/foreign.c:488 libpq/hba.c:2603 replication/logical/launcher.c:1127 replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 replication/slotfuncs.c:200 +#: replication/walsender.c:3206 utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8833 utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "la fonction avec set-value a été appelé dans un contexte qui n'accepte pas\n" "un ensemble" -#: access/transam/xlogfuncs.c:209 commands/event_trigger.c:1475 commands/event_trigger.c:2026 commands/extension.c:1899 commands/extension.c:2008 commands/extension.c:2232 commands/prepare.c:725 foreign/foreign.c:493 libpq/hba.c:2567 replication/logical/launcher.c:940 replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1391 replication/slotfuncs.c:201 replication/walsender.c:3170 utils/adt/pgstatfuncs.c:460 -#: utils/adt/pgstatfuncs.c:561 utils/misc/guc.c:8553 utils/misc/pg_config.c:44 utils/mmgr/portalmem.c:1057 +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 commands/event_trigger.c:2020 commands/extension.c:1906 commands/extension.c:2015 commands/extension.c:2239 commands/prepare.c:726 foreign/foreign.c:493 libpq/hba.c:2607 replication/logical/launcher.c:1131 replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 replication/slotfuncs.c:204 replication/walsender.c:3210 utils/adt/pgstatfuncs.c:461 +#: utils/adt/pgstatfuncs.c:562 utils/misc/guc.c:8837 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "mode matérialisé requis mais interdit dans ce contexte" -#: access/transam/xlogfuncs.c:251 +#: access/transam/xlogfuncs.c:241 #, c-format msgid "non-exclusive backup is not in progress" msgstr "une sauvegarde non exclusive n'est pas en cours" -#: access/transam/xlogfuncs.c:252 +#: access/transam/xlogfuncs.c:242 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "Souhaitiez-vous utiliser pg_stop_backup('t') ?" -#: access/transam/xlogfuncs.c:329 +#: access/transam/xlogfuncs.c:319 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "" "le niveau de journalisation (configuré par wal_level) n'est pas suffisant pour\n" "créer un point de restauration" -#: access/transam/xlogfuncs.c:337 +#: access/transam/xlogfuncs.c:327 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "valeur trop longue pour le point de restauration (%d caractères maximum)" -#: access/transam/xlogfuncs.c:475 +#: access/transam/xlogfuncs.c:465 #, c-format msgid "pg_walfile_name_offset() cannot be executed during recovery." msgstr "pg_walfile_name_offset() ne peut pas être exécuté lors de la restauration." -#: access/transam/xlogfuncs.c:531 +#: access/transam/xlogfuncs.c:521 #, c-format msgid "pg_walfile_name() cannot be executed during recovery." msgstr "pg_walfile_name() ne peut pas être exécuté lors de la restauration." -#: access/transam/xlogfuncs.c:551 access/transam/xlogfuncs.c:571 access/transam/xlogfuncs.c:588 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" msgstr "la restauration n'est pas en cours" -#: access/transam/xlogfuncs.c:552 access/transam/xlogfuncs.c:572 access/transam/xlogfuncs.c:589 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "" "Les fonctions de contrôle de la restauration peuvent seulement être exécutées\n" "lors de la restauration." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "décalage invalide de l'enregistrement %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "« contrecord » est requis par %X/%X" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:625 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "longueur invalide de l'enregistrement à %X/%X : voulait %u, a eu %u" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:363 #, c-format msgid "record length %u at %X/%X too long" msgstr "longueur trop importante de l'enregistrement %u à %X/%X" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "il n'existe pas de drapeau contrecord à %X/%X" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "longueur %u invalide du contrecord à %X/%X" -#: access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:654 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "identifiant du gestionnaire de ressources invalide %u à %X/%X" -#: access/transam/xlogreader.c:647 access/transam/xlogreader.c:664 +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "enregistrement avec prev-link %X/%X incorrect à %X/%X" -#: access/transam/xlogreader.c:701 +#: access/transam/xlogreader.c:722 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "" "somme de contrôle des données du gestionnaire de ressources incorrecte à\n" "l'enregistrement %X/%X" -#: access/transam/xlogreader.c:734 +#: access/transam/xlogreader.c:759 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "numéro magique invalide %04X dans le segment %s, décalage %u" -#: access/transam/xlogreader.c:748 access/transam/xlogreader.c:799 +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "bits d'information %04X invalides dans le segment %s, décalage %u" -#: access/transam/xlogreader.c:774 +#: access/transam/xlogreader.c:799 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "le fichier WAL provient d'un système différent : l'identifiant système de la base dans le fichier WAL est %s, alors que l'identifiant système de la base dans pg_control est %s" -#: access/transam/xlogreader.c:781 +#: access/transam/xlogreader.c:806 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "le fichier WAL provient d'un système différent : XLOG_SEG_SIZE invalide dans l'en-tête de page" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "Le fichier WAL provient d'un système différent : taille invalide du segment dans l'en-tête de page" -#: access/transam/xlogreader.c:787 +#: access/transam/xlogreader.c:812 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "le fichier WAL provient d'un système différent : XLOG_BLCKSZ invalide dans l'en-tête de page" -#: access/transam/xlogreader.c:813 +#: access/transam/xlogreader.c:843 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "pageaddr %X/%X inattendue dans le journal de transactions %s, segment %u" -#: access/transam/xlogreader.c:838 +#: access/transam/xlogreader.c:868 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "identifiant timeline %u hors de la séquence (après %u) dans le segment %s, décalage %u" -#: access/transam/xlogreader.c:1083 +#: access/transam/xlogreader.c:1113 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u désordonné à %X/%X" -#: access/transam/xlogreader.c:1106 +#: access/transam/xlogreader.c:1136 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA configuré, mais aucune donnée inclus à %X/%X" -#: access/transam/xlogreader.c:1113 +#: access/transam/xlogreader.c:1143 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA non configuré, mais la longueur des données est %u à %X/%X" -#: access/transam/xlogreader.c:1149 +#: access/transam/xlogreader.c:1179 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE initialisé, mais décalage du trou %u longueur %u longueur de l'image du bloc %u à %X/%X" -#: access/transam/xlogreader.c:1165 +#: access/transam/xlogreader.c:1195 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE non initialisé, mais décalage du trou %u longueur %u à %X/%X" -#: access/transam/xlogreader.c:1180 +#: access/transam/xlogreader.c:1210 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" -#: access/transam/xlogreader.c:1195 +#: access/transam/xlogreader.c:1225 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED configuré, mais la longueur de l'image du bloc est %u à %X/%X" -#: access/transam/xlogreader.c:1211 +#: access/transam/xlogreader.c:1241 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL configuré, mais pas de relation précédente à %X/%X" -#: access/transam/xlogreader.c:1223 +#: access/transam/xlogreader.c:1253 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "block_id %u invalide à %X/%X" -#: access/transam/xlogreader.c:1291 +#: access/transam/xlogreader.c:1342 #, c-format msgid "record with invalid length at %X/%X" msgstr "enregistrement de longueur invalide à %X/%X" -#: access/transam/xlogreader.c:1380 +#: access/transam/xlogreader.c:1431 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "image compressée invalide à %X/%X, bloc %d" -#: access/transam/xlogutils.c:747 replication/walsender.c:2416 +#: access/transam/xlogutils.c:751 replication/walsender.c:2446 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "n'a pas pu lire le journal de transactions %s, décalage %u, longueur %lu : %m" -#: bootstrap/bootstrap.c:272 postmaster/postmaster.c:819 tcop/postgres.c:3510 +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X nécessaite une puisse de deux entre 1 MB et 1 GB" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:827 tcop/postgres.c:3581 #, c-format msgid "--%s requires a value" msgstr "--%s requiert une valeur" -#: bootstrap/bootstrap.c:277 postmaster/postmaster.c:824 tcop/postgres.c:3515 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:832 tcop/postgres.c:3586 #, c-format msgid "-c %s requires a value" msgstr "-c %s requiert une valeur" -#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:836 postmaster/postmaster.c:849 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:844 postmaster/postmaster.c:857 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: bootstrap/bootstrap.c:297 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s : arguments invalides en ligne de commande\n" @@ -2922,538 +2984,638 @@ msgstr "certains droits n'ont pu être révoqué pour la colonne « %s » de la msgid "not all privileges could be revoked for \"%s\"" msgstr "certains droits n'ont pu être révoqué pour « %s »" -#: catalog/aclchk.c:455 catalog/aclchk.c:948 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" msgstr "droit %s invalide pour la relation" -#: catalog/aclchk.c:459 catalog/aclchk.c:952 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" msgstr "droit %s invalide pour la séquence" -#: catalog/aclchk.c:463 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "droit %s invalide pour la base de données" -#: catalog/aclchk.c:467 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "type de droit %s invalide pour le domaine" -#: catalog/aclchk.c:471 catalog/aclchk.c:956 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" msgstr "droit %s invalide pour la fonction" -#: catalog/aclchk.c:475 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "droit %s invalide pour le langage" -#: catalog/aclchk.c:479 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "type de droit invalide, %s, pour le Large Object" -#: catalog/aclchk.c:483 catalog/aclchk.c:964 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" msgstr "droit %s invalide pour le schéma" -#: catalog/aclchk.c:487 +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "type de droit %s invalide pour la procedure " + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "droit %s invalide pour la routine" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "droit %s invalide pour le tablespace" -#: catalog/aclchk.c:491 catalog/aclchk.c:960 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" msgstr "type de droit %s invalide pour le type" -#: catalog/aclchk.c:495 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "type de droit %s invalide pour le wrapper de données distantes" -#: catalog/aclchk.c:499 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "type de droit %s invalide pour le serveur distant" -#: catalog/aclchk.c:538 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "les droits sur la colonne sont seulement valides pour les relations" -#: catalog/aclchk.c:696 catalog/aclchk.c:3926 catalog/aclchk.c:4708 catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" msgstr "le « Large Object » %u n'existe pas" -#: catalog/aclchk.c:885 catalog/aclchk.c:894 commands/collationcmds.c:114 commands/copy.c:1042 commands/copy.c:1062 commands/copy.c:1071 commands/copy.c:1080 commands/copy.c:1089 commands/copy.c:1098 commands/copy.c:1107 commands/copy.c:1116 commands/copy.c:1125 commands/copy.c:1143 commands/copy.c:1159 commands/copy.c:1179 commands/copy.c:1196 commands/dbcommands.c:155 commands/dbcommands.c:164 commands/dbcommands.c:173 -#: commands/dbcommands.c:182 commands/dbcommands.c:191 commands/dbcommands.c:200 commands/dbcommands.c:209 commands/dbcommands.c:218 commands/dbcommands.c:227 commands/dbcommands.c:1427 commands/dbcommands.c:1436 commands/dbcommands.c:1445 commands/dbcommands.c:1454 commands/extension.c:1678 commands/extension.c:1688 commands/extension.c:1698 commands/extension.c:1708 commands/extension.c:2949 commands/foreigncmds.c:537 -#: commands/foreigncmds.c:546 commands/functioncmds.c:526 commands/functioncmds.c:643 commands/functioncmds.c:652 commands/functioncmds.c:661 commands/functioncmds.c:670 commands/functioncmds.c:2097 commands/functioncmds.c:2105 commands/publicationcmds.c:90 commands/sequence.c:1265 commands/sequence.c:1275 commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 commands/sequence.c:1315 commands/sequence.c:1325 -#: commands/sequence.c:1335 commands/sequence.c:1345 commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 commands/subscriptioncmds.c:179 commands/tablecmds.c:5960 commands/typecmds.c:298 commands/typecmds.c:1375 commands/typecmds.c:1384 commands/typecmds.c:1392 commands/typecmds.c:1400 -#: commands/typecmds.c:1408 commands/user.c:134 commands/user.c:148 commands/user.c:157 commands/user.c:166 commands/user.c:175 commands/user.c:184 commands/user.c:193 commands/user.c:202 commands/user.c:211 commands/user.c:220 commands/user.c:229 commands/user.c:238 commands/user.c:247 commands/user.c:532 commands/user.c:540 commands/user.c:548 commands/user.c:556 commands/user.c:564 commands/user.c:572 commands/user.c:580 -#: commands/user.c:588 commands/user.c:597 commands/user.c:605 commands/user.c:613 parser/parse_utilcmd.c:395 replication/pgoutput/pgoutput.c:107 replication/pgoutput/pgoutput.c:128 replication/walsender.c:800 replication/walsender.c:811 replication/walsender.c:821 +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 commands/copy.c:1063 commands/copy.c:1083 commands/copy.c:1092 commands/copy.c:1101 commands/copy.c:1110 commands/copy.c:1119 commands/copy.c:1128 commands/copy.c:1137 commands/copy.c:1146 commands/copy.c:1164 commands/copy.c:1180 commands/copy.c:1200 commands/copy.c:1217 commands/dbcommands.c:155 commands/dbcommands.c:164 commands/dbcommands.c:173 +#: commands/dbcommands.c:182 commands/dbcommands.c:191 commands/dbcommands.c:200 commands/dbcommands.c:209 commands/dbcommands.c:218 commands/dbcommands.c:227 commands/dbcommands.c:1427 commands/dbcommands.c:1436 commands/dbcommands.c:1445 commands/dbcommands.c:1454 commands/extension.c:1685 commands/extension.c:1695 commands/extension.c:1705 commands/extension.c:1715 commands/extension.c:2956 commands/foreigncmds.c:537 +#: commands/foreigncmds.c:546 commands/functioncmds.c:559 commands/functioncmds.c:684 commands/functioncmds.c:693 commands/functioncmds.c:702 commands/functioncmds.c:711 commands/functioncmds.c:2105 commands/functioncmds.c:2113 commands/publicationcmds.c:92 commands/sequence.c:1255 commands/sequence.c:1265 commands/sequence.c:1275 commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 commands/sequence.c:1315 +#: commands/sequence.c:1325 commands/sequence.c:1335 commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 commands/subscriptioncmds.c:179 commands/tablecmds.c:6305 commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 commands/typecmds.c:1461 commands/typecmds.c:1469 +#: commands/typecmds.c:1477 commands/user.c:134 commands/user.c:148 commands/user.c:157 commands/user.c:166 commands/user.c:175 commands/user.c:184 commands/user.c:193 commands/user.c:202 commands/user.c:211 commands/user.c:220 commands/user.c:229 commands/user.c:238 commands/user.c:247 commands/user.c:555 commands/user.c:563 commands/user.c:571 commands/user.c:579 commands/user.c:587 commands/user.c:595 commands/user.c:603 +#: commands/user.c:611 commands/user.c:620 commands/user.c:628 commands/user.c:636 parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "options en conflit ou redondantes" -#: catalog/aclchk.c:997 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "les droits par défaut ne peuvent pas être configurés pour les colonnes" -#: catalog/aclchk.c:1157 +#: catalog/aclchk.c:1212 #, c-format msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" msgstr "ne peut pas utiliser la clause IN SCHEMA lors de l'utilisation de GRANT/REVOKE ON SCHEMAS" -#: catalog/aclchk.c:1521 catalog/objectaddress.c:1389 commands/analyze.c:390 commands/copy.c:4746 commands/sequence.c:1700 commands/tablecmds.c:5608 commands/tablecmds.c:5755 commands/tablecmds.c:5812 commands/tablecmds.c:5885 commands/tablecmds.c:5979 commands/tablecmds.c:6038 commands/tablecmds.c:6163 commands/tablecmds.c:6217 commands/tablecmds.c:6309 commands/tablecmds.c:6465 commands/tablecmds.c:8694 commands/tablecmds.c:8970 -#: commands/tablecmds.c:9405 commands/trigger.c:791 parser/analyze.c:2310 parser/parse_relation.c:2699 parser/parse_relation.c:2761 parser/parse_target.c:1002 parser/parse_type.c:127 utils/adt/acl.c:2823 utils/adt/ruleutils.c:2356 +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 commands/copy.c:4826 commands/sequence.c:1690 commands/tablecmds.c:5951 commands/tablecmds.c:6099 commands/tablecmds.c:6156 commands/tablecmds.c:6230 commands/tablecmds.c:6324 commands/tablecmds.c:6383 commands/tablecmds.c:6522 commands/tablecmds.c:6604 commands/tablecmds.c:6696 commands/tablecmds.c:6790 commands/tablecmds.c:9519 commands/tablecmds.c:9813 +#: commands/tablecmds.c:10294 commands/trigger.c:904 parser/analyze.c:2343 parser/parse_relation.c:2735 parser/parse_relation.c:2798 parser/parse_target.c:1030 parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2465 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "la colonne « %s » de la relation « %s » n'existe pas" -#: catalog/aclchk.c:1787 catalog/objectaddress.c:1229 commands/sequence.c:1138 commands/tablecmds.c:229 commands/tablecmds.c:13080 utils/adt/acl.c:2059 utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1128 commands/tablecmds.c:231 commands/tablecmds.c:14095 utils/adt/acl.c:2076 utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "« %s » n'est pas une séquence" -#: catalog/aclchk.c:1825 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "la séquence « %s » accepte seulement les droits USAGE, SELECT et UPDATE" -#: catalog/aclchk.c:1842 +#: catalog/aclchk.c:1898 #, c-format msgid "invalid privilege type %s for table" msgstr "type de droit %s invalide pour la table" -#: catalog/aclchk.c:2008 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" msgstr "type de droit %s invalide pour la colonne" -#: catalog/aclchk.c:2021 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "la séquence « %s » accepte seulement le droit SELECT pour les colonnes" -#: catalog/aclchk.c:2603 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "le langage « %s » n'est pas de confiance" -#: catalog/aclchk.c:2605 +#: catalog/aclchk.c:2661 #, c-format msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." msgstr "GRANT et REVOKE ne sont pas autorisés sur des langages qui ne sont pas de confiance car seuls les super-utilisateurs peuvent utiliser ces langages" -#: catalog/aclchk.c:3119 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "ne peut pas configurer les droits des types tableau" -#: catalog/aclchk.c:3120 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "Configurez les droits du type élément à la place." -#: catalog/aclchk.c:3127 catalog/objectaddress.c:1519 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" msgstr "« %s » n'est pas un domaine" -#: catalog/aclchk.c:3247 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "droit « %s » non reconnu" -#: catalog/aclchk.c:3296 +#: catalog/aclchk.c:3364 #, c-format -msgid "permission denied for column %s" -msgstr "droit refusé pour la colonne %s" +msgid "permission denied for aggregate %s" +msgstr "droit refusé pour l'aggrégat %s" -#: catalog/aclchk.c:3298 +#: catalog/aclchk.c:3367 #, c-format -msgid "permission denied for relation %s" -msgstr "droit refusé pour la relation %s" +msgid "permission denied for collation %s" +msgstr "droit refusé pour le collationnement %s" -#: catalog/aclchk.c:3300 commands/sequence.c:600 commands/sequence.c:834 commands/sequence.c:876 commands/sequence.c:917 commands/sequence.c:1791 commands/sequence.c:1855 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for sequence %s" -msgstr "droit refusé pour la séquence %s" +msgid "permission denied for column %s" +msgstr "droit refusé pour la colonne %s" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for conversion %s" +msgstr "droit refusé pour la conversion %s" -#: catalog/aclchk.c:3302 +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" msgstr "droit refusé pour la base de données %s" -#: catalog/aclchk.c:3304 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "droit refusé pour la fonction %s" +msgid "permission denied for domain %s" +msgstr "droit refusé pour le domaine %s" -#: catalog/aclchk.c:3306 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "droit refusé pour l'opérateur %s" +msgid "permission denied for event trigger %s" +msgstr "droit refusé pour le trigger sur événement %s" -#: catalog/aclchk.c:3308 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "droit refusé pour le type %s" +msgid "permission denied for extension %s" +msgstr "droit refusé pour l'extension %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "droit refusé pour le wrapper de données distantes %s" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "droit refusé pour le serveur distant %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "droit refusé pour la table distante %s" -#: catalog/aclchk.c:3310 +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "droit refusé pour la fonction %s" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "droit refusé pour l'index %s" + +#: catalog/aclchk.c:3403 #, c-format msgid "permission denied for language %s" msgstr "droit refusé pour le langage %s" -#: catalog/aclchk.c:3312 +#: catalog/aclchk.c:3406 #, c-format msgid "permission denied for large object %s" msgstr "droit refusé pour le Large Object %s" -#: catalog/aclchk.c:3314 +#: catalog/aclchk.c:3409 #, c-format -msgid "permission denied for schema %s" -msgstr "droit refusé pour le schéma %s" +msgid "permission denied for materialized view %s" +msgstr "droit refusé pour la vue matérialisée %s" -#: catalog/aclchk.c:3316 +#: catalog/aclchk.c:3412 #, c-format msgid "permission denied for operator class %s" msgstr "droit refusé pour la classe d'opérateur %s" -#: catalog/aclchk.c:3318 +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "droit refusé pour l'opérateur %s" + +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" msgstr "droit refusé pour la famille d'opérateur %s" -#: catalog/aclchk.c:3320 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "droit refusé pour le collationnement %s" +msgid "permission denied for policy %s" +msgstr "droit refusé pour la politique %s" -#: catalog/aclchk.c:3322 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "droit refusé pour la conversion %s" +msgid "permission denied for procedure %s" +msgstr "droit refusé pour la procédure %s" -#: catalog/aclchk.c:3324 +#: catalog/aclchk.c:3427 +#, c-format +msgid "permission denied for publication %s" +msgstr "droit refusé pour la publication %s" + +#: catalog/aclchk.c:3430 +#, c-format +msgid "permission denied for routine %s" +msgstr "droit refusé pour la routine %s" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "droit refusé pour le schéma %s" + +#: catalog/aclchk.c:3436 commands/sequence.c:598 commands/sequence.c:832 commands/sequence.c:874 commands/sequence.c:915 commands/sequence.c:1788 commands/sequence.c:1852 +#, c-format +msgid "permission denied for sequence %s" +msgstr "droit refusé pour la séquence %s" + +#: catalog/aclchk.c:3439 #, c-format msgid "permission denied for statistics object %s" msgstr "droit refusé pour l'objet statistique %s" -#: catalog/aclchk.c:3326 +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "droit refusé pour la souscription %s" + +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "droit refusé pour la table %s" + +#: catalog/aclchk.c:3448 #, c-format msgid "permission denied for tablespace %s" msgstr "droit refusé pour le tablespace %s" -#: catalog/aclchk.c:3328 +#: catalog/aclchk.c:3451 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "droit refusé pour la configuration de recherche plein texte %s" + +#: catalog/aclchk.c:3454 #, c-format msgid "permission denied for text search dictionary %s" msgstr "droit refusé pour le dictionnaire de recherche plein texte %s" -#: catalog/aclchk.c:3330 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for text search configuration %s" -msgstr "droit refusé pour la configuration de recherche plein texte %s" +msgid "permission denied for type %s" +msgstr "droit refusé pour le type %s" -#: catalog/aclchk.c:3332 +#: catalog/aclchk.c:3460 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "droit refusé pour le wrapper de données distantes %s" +msgid "permission denied for view %s" +msgstr "droit refusé pour la vue %s" -#: catalog/aclchk.c:3334 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for foreign server %s" -msgstr "droit refusé pour le serveur distant %s" +msgid "must be owner of aggregate %s" +msgstr "doit être le propriétaire de l'aggrégat %s" -#: catalog/aclchk.c:3336 +#: catalog/aclchk.c:3498 #, c-format -msgid "permission denied for event trigger %s" -msgstr "droit refusé pour le trigger sur événement %s" +msgid "must be owner of collation %s" +msgstr "doit être le propriétaire du collationnement %s" -#: catalog/aclchk.c:3338 +#: catalog/aclchk.c:3501 #, c-format -msgid "permission denied for extension %s" -msgstr "droit refusé pour l'extension %s" +msgid "must be owner of conversion %s" +msgstr "doit être le propriétaire de la conversion %s" -#: catalog/aclchk.c:3340 +#: catalog/aclchk.c:3504 #, c-format -msgid "permission denied for publication %s" -msgstr "droit refusé pour la publication %s" +msgid "must be owner of database %s" +msgstr "doit être le propriétaire de la base de données %s" -#: catalog/aclchk.c:3342 +#: catalog/aclchk.c:3507 #, c-format -msgid "permission denied for subscription %s" -msgstr "droit refusé pour la souscription %s" +msgid "must be owner of domain %s" +msgstr "doit être le propriétaire du domaine %s" -#: catalog/aclchk.c:3348 catalog/aclchk.c:3350 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of relation %s" -msgstr "doit être le propriétaire de la relation %s" +msgid "must be owner of event trigger %s" +msgstr "doit être le propriétaire du trigger sur événement %s" -#: catalog/aclchk.c:3352 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of sequence %s" -msgstr "doit être le propriétaire de la séquence %s" +msgid "must be owner of extension %s" +msgstr "doit être le propriétaire de l'extension %s" -#: catalog/aclchk.c:3354 +#: catalog/aclchk.c:3516 #, c-format -msgid "must be owner of database %s" -msgstr "doit être le propriétaire de la base de données %s" +msgid "must be owner of foreign-data wrapper %s" +msgstr "doit être le propriétaire du wrapper de données distantes %s" -#: catalog/aclchk.c:3356 +#: catalog/aclchk.c:3519 #, c-format -msgid "must be owner of function %s" -msgstr "doit être le propriétaire de la fonction %s" +msgid "must be owner of foreign server %s" +msgstr "doit être le propriétaire de serveur distant %s" -#: catalog/aclchk.c:3358 +#: catalog/aclchk.c:3522 #, c-format -msgid "must be owner of operator %s" -msgstr "doit être le prorpriétaire de l'opérateur %s" +msgid "must be owner of foreign table %s" +msgstr "doit être le propriétaire de la table distante %s" -#: catalog/aclchk.c:3360 +#: catalog/aclchk.c:3525 #, c-format -msgid "must be owner of type %s" -msgstr "doit être le propriétaire du type %s" +msgid "must be owner of function %s" +msgstr "doit être le propriétaire de la fonction %s" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "doit être le propriétaire de l'index %s" -#: catalog/aclchk.c:3362 +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" msgstr "doit être le propriétaire du langage %s" -#: catalog/aclchk.c:3364 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" msgstr "doit être le propriétaire du Large Object %s" -#: catalog/aclchk.c:3366 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "doit être le propriétaire du schéma %s" +msgid "must be owner of materialized view %s" +msgstr "doit être le propriétaire de la vue matérialisée %s" -#: catalog/aclchk.c:3368 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" msgstr "doit être le propriétaire de la classe d'opérateur %s" -#: catalog/aclchk.c:3370 +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "doit être le prorpriétaire de l'opérateur %s" + +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" msgstr "doit être le prorpriétaire de la famille d'opérateur %s" -#: catalog/aclchk.c:3372 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "doit être le propriétaire du collationnement %s" +msgid "must be owner of procedure %s" +msgstr "doit être le prorpriétaire de la procédure %s" -#: catalog/aclchk.c:3374 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "doit être le propriétaire de la conversion %s" +msgid "must be owner of publication %s" +msgstr "doit être le propriétaire de la publication %s" -#: catalog/aclchk.c:3376 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of statistics object %s" -msgstr "doit être le propriétaire de l'objet statistique %s" +msgid "must be owner of routine %s" +msgstr "doit être le propriétaire de la routine %s" -#: catalog/aclchk.c:3378 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of tablespace %s" -msgstr "doit être le propriétaire du tablespace %s" +msgid "must be owner of sequence %s" +msgstr "doit être le propriétaire de la séquence %s" -#: catalog/aclchk.c:3380 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "doit être le propriétaire du dictionnaire de recherche plein texte %s" +msgid "must be owner of subscription %s" +msgstr "doit être le propriétaire de la souscription %s" -#: catalog/aclchk.c:3382 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "doit être le propriétaire de la configuration de recherche plein texte %s" +msgid "must be owner of table %s" +msgstr "doit être le propriétaire de la table %s" -#: catalog/aclchk.c:3384 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "doit être le propriétaire du wrapper de données distantes %s" +msgid "must be owner of type %s" +msgstr "doit être le propriétaire du type %s" -#: catalog/aclchk.c:3386 +#: catalog/aclchk.c:3570 #, c-format -msgid "must be owner of foreign server %s" -msgstr "doit être le propriétaire de serveur distant %s" +msgid "must be owner of view %s" +msgstr "doit être le propriétaire de la vue %s" -#: catalog/aclchk.c:3388 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of event trigger %s" -msgstr "doit être le propriétaire du trigger sur événement %s" +msgid "must be owner of schema %s" +msgstr "doit être le propriétaire du schéma %s" -#: catalog/aclchk.c:3390 +#: catalog/aclchk.c:3576 #, c-format -msgid "must be owner of extension %s" -msgstr "doit être le propriétaire de l'extension %s" +msgid "must be owner of statistics object %s" +msgstr "doit être le propriétaire de l'objet statistique %s" -#: catalog/aclchk.c:3392 +#: catalog/aclchk.c:3579 #, c-format -msgid "must be owner of publication %s" -msgstr "doit être le propriétaire de la publication %s" +msgid "must be owner of tablespace %s" +msgstr "doit être le propriétaire du tablespace %s" -#: catalog/aclchk.c:3394 +#: catalog/aclchk.c:3582 #, c-format -msgid "must be owner of subscription %s" -msgstr "doit être le propriétaire de la souscription %s" +msgid "must be owner of text search configuration %s" +msgstr "doit être le propriétaire de la configuration de recherche plein texte %s" -#: catalog/aclchk.c:3436 +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "doit être le propriétaire du dictionnaire de recherche plein texte %s" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "doit être le propriétaire de la relation %s" + +#: catalog/aclchk.c:3643 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "droit refusé pour la colonne « %s » de la relation « %s »" -#: catalog/aclchk.c:3559 catalog/aclchk.c:3567 +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "l'attribut %d de la relation d'OID %u n'existe pas" -#: catalog/aclchk.c:3640 catalog/aclchk.c:4559 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" msgstr "la relation d'OID %u n'existe pas" -#: catalog/aclchk.c:3739 catalog/aclchk.c:4977 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "la base de données d'OID %u n'existe pas" -#: catalog/aclchk.c:3793 catalog/aclchk.c:4637 tcop/fastpath.c:223 utils/fmgr/fmgr.c:2117 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "la fonction d'OID %u n'existe pas" -#: catalog/aclchk.c:3847 catalog/aclchk.c:4663 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" msgstr "le langage d'OID %u n'existe pas" -#: catalog/aclchk.c:4011 catalog/aclchk.c:4735 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" msgstr "le schéma d'OID %u n'existe pas" -#: catalog/aclchk.c:4065 catalog/aclchk.c:4762 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" msgstr "le tablespace d'OID %u n'existe pas" -#: catalog/aclchk.c:4124 catalog/aclchk.c:4896 commands/foreigncmds.c:324 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "le wrapper de données distantes d'OID %u n'existe pas" -#: catalog/aclchk.c:4186 catalog/aclchk.c:4923 commands/foreigncmds.c:459 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" msgstr "le serveur distant d'OID %u n'existe pas" -#: catalog/aclchk.c:4246 catalog/aclchk.c:4585 utils/cache/typcache.c:238 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" msgstr "le type d'OID %u n'existe pas" -#: catalog/aclchk.c:4611 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" msgstr "l'opérateur d'OID %u n'existe pas" -#: catalog/aclchk.c:4788 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" msgstr "la classe d'opérateur d'OID %u n'existe pas" -#: catalog/aclchk.c:4815 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" msgstr "la famille d'opérateur d'OID %u n'existe pas" -#: catalog/aclchk.c:4842 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "le dictionnaire de recherche plein texte d'OID %u n'existe pas" -#: catalog/aclchk.c:4869 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "la configuration de recherche plein texte d'OID %u n'existe pas" -#: catalog/aclchk.c:4950 commands/event_trigger.c:588 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format msgid "event trigger with OID %u does not exist" msgstr "le trigger sur événement d'OID %u n'existe pas" -#: catalog/aclchk.c:5003 commands/collationcmds.c:348 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" msgstr "le collationnement d'OID %u n'existe pas" -#: catalog/aclchk.c:5029 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" msgstr "la conversion d'OID %u n'existe pas" -#: catalog/aclchk.c:5070 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" msgstr "l'extension d'OID %u n'existe pas" -#: catalog/aclchk.c:5097 commands/publicationcmds.c:733 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 #, c-format msgid "publication with OID %u does not exist" msgstr "la publication d'OID %u n'existe pas" -#: catalog/aclchk.c:5123 commands/subscriptioncmds.c:1075 +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 #, c-format msgid "subscription with OID %u does not exist" msgstr "la souscription d'OID %u n'existe pas" -#: catalog/aclchk.c:5149 +#: catalog/aclchk.c:5354 #, c-format msgid "statistics object with OID %u does not exist" msgstr "l'objet statistique d'OID %u n'existe pas" -#: catalog/dependency.c:613 +#: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" msgstr "n'a pas pu supprimer %s car il est requis par %s" -#: catalog/dependency.c:616 +#: catalog/dependency.c:614 #, c-format msgid "You can drop %s instead." msgstr "Vous pouvez supprimer %s à la place." -#: catalog/dependency.c:779 catalog/pg_shdepend.c:574 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "n'a pas pu supprimer %s car il est requis par le système de bases de données" -#: catalog/dependency.c:897 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" msgstr "DROP cascade automatiquement sur %s" -#: catalog/dependency.c:909 catalog/dependency.c:918 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" msgstr "%s dépend de %s" -#: catalog/dependency.c:930 catalog/dependency.c:939 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" msgstr "DROP cascade sur %s" -#: catalog/dependency.c:947 catalog/pg_shdepend.c:685 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -3468,581 +3630,596 @@ msgstr[1] "" "\n" "et %d autres objets (voir le journal applicatif du serveur pour une liste)" -#: catalog/dependency.c:959 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "n'a pas pu supprimer %s car d'autres objets en dépendent" -#: catalog/dependency.c:963 catalog/dependency.c:970 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Utilisez DROP ... CASCADE pour supprimer aussi les objets dépendants." -#: catalog/dependency.c:967 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "ne peut pas supprimer les objets désirés car d'autres objets en dépendent" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:976 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "DROP cascade sur %d autre objet" msgstr[1] "DROP cascade sur %d autres objets" -#: catalog/dependency.c:1635 +#: catalog/dependency.c:1644 #, c-format msgid "constant of the type %s cannot be used here" msgstr "la constante de type %s ne peut pas être utilisée ici" -#: catalog/heap.c:283 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "droit refusé pour créer « %s.%s »" -#: catalog/heap.c:285 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Les modifications du catalogue système sont actuellement interdites." -#: catalog/heap.c:421 commands/tablecmds.c:1649 commands/tablecmds.c:2159 commands/tablecmds.c:5212 +#: catalog/heap.c:433 commands/tablecmds.c:1884 commands/tablecmds.c:2417 commands/tablecmds.c:5518 #, c-format msgid "tables can have at most %d columns" msgstr "les tables peuvent avoir au plus %d colonnes" -#: catalog/heap.c:438 commands/tablecmds.c:5471 +#: catalog/heap.c:452 commands/tablecmds.c:5814 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "le nom de la colonne « %s » entre en conflit avec le nom d'une colonne système" -#: catalog/heap.c:454 +#: catalog/heap.c:468 #, c-format msgid "column name \"%s\" specified more than once" msgstr "colonne « %s » spécifiée plus d'une fois" -#: catalog/heap.c:507 +#: catalog/heap.c:521 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "la colonne « %s » a le pseudo type %s" -#: catalog/heap.c:537 +#: catalog/heap.c:551 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "le type composite %s ne peut pas être membre de lui-même" -#: catalog/heap.c:579 commands/createas.c:201 commands/createas.c:498 +#: catalog/heap.c:593 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "aucun collationnement n'a été dérivé pour la colonne « %s » de type collationnable %s" -#: catalog/heap.c:581 commands/createas.c:204 commands/createas.c:501 commands/indexcmds.c:1149 commands/tablecmds.c:13376 commands/view.c:103 regex/regc_pg_locale.c:263 utils/adt/formatting.c:1547 utils/adt/formatting.c:1671 utils/adt/formatting.c:1796 utils/adt/like.c:184 utils/adt/selfuncs.c:5563 utils/adt/varlena.c:1417 utils/adt/varlena.c:1866 +#: catalog/heap.c:595 commands/createas.c:204 commands/createas.c:501 commands/indexcmds.c:1587 commands/tablecmds.c:14381 commands/view.c:105 regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 utils/adt/selfuncs.c:5812 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "Utilisez la clause COLLARE pour configurer explicitement le collationnement." -#: catalog/heap.c:1067 catalog/index.c:807 commands/tablecmds.c:2943 +#: catalog/heap.c:1084 catalog/index.c:876 commands/tablecmds.c:3179 #, c-format msgid "relation \"%s\" already exists" msgstr "la relation « %s » existe déjà" -#: catalog/heap.c:1083 catalog/pg_type.c:410 catalog/pg_type.c:732 commands/typecmds.c:239 commands/typecmds.c:788 commands/typecmds.c:1139 commands/typecmds.c:1350 commands/typecmds.c:2106 +#: catalog/heap.c:1100 catalog/pg_type.c:417 catalog/pg_type.c:732 commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "le type « %s » existe déjà" -#: catalog/heap.c:1084 +#: catalog/heap.c:1101 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "" "Une relation a un type associé du même nom, donc vous devez utiliser un nom\n" "qui n'entre pas en conflit avec un type existant." -#: catalog/heap.c:1113 +#: catalog/heap.c:1130 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "OID du heap de pg_class non configuré en mode de mise à jour binaire" -#: catalog/heap.c:2078 +#: catalog/heap.c:2333 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "ne peut pas ajouter une contrainte NO INHERIT pour la table partitionnée « %s »" -#: catalog/heap.c:2336 +#: catalog/heap.c:2598 #, c-format msgid "check constraint \"%s\" already exists" msgstr "la contrainte de vérification « %s » existe déjà" -#: catalog/heap.c:2504 catalog/pg_constraint.c:649 commands/tablecmds.c:6825 +#: catalog/heap.c:2768 catalog/index.c:890 catalog/pg_constraint.c:679 commands/tablecmds.c:7166 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "la contrainte « %s » de la relation « %s » existe déjà" -#: catalog/heap.c:2511 +#: catalog/heap.c:2775 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "la contrainte « %s » entre en conflit avec la constrainte non héritée sur la relation « %s »" -#: catalog/heap.c:2522 +#: catalog/heap.c:2786 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "la contrainte « %s » entre en conflit avec une contrainte héritée sur la relation « %s »" -#: catalog/heap.c:2532 +#: catalog/heap.c:2796 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "la contrainte « %s » entre en conflit avec une contrainte NOT VALID sur la relation « %s »" -#: catalog/heap.c:2537 +#: catalog/heap.c:2801 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "assemblage de la contrainte « %s » avec une définition héritée" -#: catalog/heap.c:2653 +#: catalog/heap.c:2916 #, c-format msgid "cannot use column references in default expression" msgstr "ne peut pas utiliser les références de colonnes dans l'expression par défaut" -#: catalog/heap.c:2678 rewrite/rewriteHandler.c:1171 +#: catalog/heap.c:2941 rewrite/rewriteHandler.c:1163 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "la colonne « %s » est de type %s alors que l'expression par défaut est de type %s" -#: catalog/heap.c:2683 commands/prepare.c:384 parser/parse_node.c:430 parser/parse_target.c:590 parser/parse_target.c:840 parser/parse_target.c:850 rewrite/rewriteHandler.c:1176 +#: catalog/heap.c:2946 commands/prepare.c:384 parser/parse_node.c:430 parser/parse_target.c:590 parser/parse_target.c:865 parser/parse_target.c:875 rewrite/rewriteHandler.c:1168 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Vous devez réécrire l'expression ou lui appliquer une transformation de type." -#: catalog/heap.c:2730 +#: catalog/heap.c:2993 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "seule la table « %s » peut être référencée dans la contrainte de vérification" -#: catalog/heap.c:2970 +#: catalog/heap.c:3243 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "combinaison ON COMMIT et clé étrangère non supportée" -#: catalog/heap.c:2971 +#: catalog/heap.c:3244 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "" "La table « %s » référence « %s » mais elles n'ont pas la même valeur pour le\n" "paramètre ON COMMIT." -#: catalog/heap.c:2976 +#: catalog/heap.c:3249 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "ne peut pas tronquer une table référencée dans une contrainte de clé étrangère" -#: catalog/heap.c:2977 +#: catalog/heap.c:3250 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "La table « %s » référence « %s »." -#: catalog/heap.c:2979 +#: catalog/heap.c:3252 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "Tronquez la table « %s » en même temps, ou utilisez TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1671 parser/parse_utilcmd.c:1757 +#: catalog/index.c:233 parser/parse_utilcmd.c:1823 parser/parse_utilcmd.c:1910 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "les clés primaires multiples ne sont pas autorisées pour la table « %s »" -#: catalog/index.c:228 +#: catalog/index.c:251 #, c-format msgid "primary keys cannot be expressions" msgstr "les clés primaires ne peuvent pas être des expressions" -#: catalog/index.c:757 catalog/index.c:1175 +#: catalog/index.c:820 catalog/index.c:1291 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "les index définis par l'utilisateur sur les tables du catalogue système ne sont pas supportés" -#: catalog/index.c:767 +#: catalog/index.c:830 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "" "la création en parallèle d'un index sur les tables du catalogue système\n" "n'est pas supportée" -#: catalog/index.c:785 +#: catalog/index.c:848 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "les index partagés ne peuvent pas être créés après initdb" -#: catalog/index.c:799 commands/createas.c:250 commands/sequence.c:152 parser/parse_utilcmd.c:201 +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 parser/parse_utilcmd.c:205 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "la relation « %s » existe déjà, poursuite du traitement" -#: catalog/index.c:835 +#: catalog/index.c:918 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "OID de l'index de pg_class non configuré en mode de mise à jour binaire" -#: catalog/index.c:1436 +#: catalog/index.c:1566 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY doit être la première action dans une transaction" -#: catalog/index.c:2024 +#: catalog/index.c:2294 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "construction de l'index « %s » séquentiellement sur la table « %s »" + +#: catalog/index.c:2299 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "construction de l'index « %s » sur la table « %s »" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "construction de l'index « %s » sur la table « %s » avec une demande de %d processus parallèle" +msgstr[1] "construction de l'index « %s » sur la table « %s » avec une demande de %d processus parallèles" -#: catalog/index.c:3336 +#: catalog/index.c:3688 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "ne peut pas ré-indexer les tables temporaires des autres sessions" -#: catalog/index.c:3467 +#: catalog/index.c:3819 #, c-format msgid "index \"%s\" was reindexed" msgstr "l'index « %s » a été réindexée" -#: catalog/namespace.c:235 catalog/namespace.c:433 catalog/namespace.c:527 commands/trigger.c:4931 +#: catalog/index.c:3890 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX sur des tables partitionnées n'est pas encore impémenté, « %s » ignoré" + +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 commands/trigger.c:5405 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "les références entre bases de données ne sont pas implémentées : « %s.%s.%s »" -#: catalog/namespace.c:292 +#: catalog/namespace.c:306 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "les tables temporaires ne peuvent pas spécifier un nom de schéma" -#: catalog/namespace.c:371 +#: catalog/namespace.c:387 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "n'a pas pu obtenir un verrou sur la relation « %s.%s »" -#: catalog/namespace.c:376 commands/lockcmds.c:145 +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:248 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "n'a pas pu obtenir un verrou sur la relation « %s »" -#: catalog/namespace.c:400 parser/parse_relation.c:1158 +#: catalog/namespace.c:420 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "la relation « %s.%s » n'existe pas" -#: catalog/namespace.c:405 parser/parse_relation.c:1177 parser/parse_relation.c:1185 +#: catalog/namespace.c:425 parser/parse_relation.c:1171 parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "la relation « %s » n'existe pas" -#: catalog/namespace.c:473 catalog/namespace.c:2992 commands/extension.c:1466 commands/extension.c:1472 +#: catalog/namespace.c:491 catalog/namespace.c:3008 commands/extension.c:1466 commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "aucun schéma n'a été sélectionné pour cette création" -#: catalog/namespace.c:625 catalog/namespace.c:638 +#: catalog/namespace.c:643 catalog/namespace.c:656 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "ne peut pas créer les relations dans les schémas temporaires d'autres sessions" -#: catalog/namespace.c:629 +#: catalog/namespace.c:647 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "ne peut pas créer une relation temporaire dans un schéma non temporaire" -#: catalog/namespace.c:644 +#: catalog/namespace.c:662 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "seules les relations temporaires peuvent être créées dans des schémas temporaires" -#: catalog/namespace.c:2182 +#: catalog/namespace.c:2200 #, c-format msgid "statistics object \"%s\" does not exist" msgstr "l'objet statistique « %s » n'existe pas" -#: catalog/namespace.c:2305 +#: catalog/namespace.c:2323 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "l'analyseur de recherche plein texte « %s » n'existe pas" -#: catalog/namespace.c:2431 +#: catalog/namespace.c:2449 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "le dictionnaire de recherche plein texte « %s » n'existe pas" -#: catalog/namespace.c:2558 +#: catalog/namespace.c:2576 #, c-format msgid "text search template \"%s\" does not exist" msgstr "le modèle de recherche plein texte « %s » n'existe pas" -#: catalog/namespace.c:2684 commands/tsearchcmds.c:1185 utils/cache/ts_cache.c:612 +#: catalog/namespace.c:2702 commands/tsearchcmds.c:1185 utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "la configuration de recherche plein texte « %s » n'existe pas" -#: catalog/namespace.c:2797 parser/parse_expr.c:789 parser/parse_target.c:1192 +#: catalog/namespace.c:2815 parser/parse_expr.c:793 parser/parse_target.c:1220 #, c-format msgid "cross-database references are not implemented: %s" msgstr "les références entre bases de données ne sont pas implémentées : %s" -#: catalog/namespace.c:2803 gram.y:14300 gram.y:15721 parser/parse_expr.c:796 parser/parse_target.c:1199 +#: catalog/namespace.c:2821 gram.y:14728 gram.y:16160 parser/parse_expr.c:800 parser/parse_target.c:1227 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "mauvaise qualification du nom (trop de points entre les noms) : %s" -#: catalog/namespace.c:2934 +#: catalog/namespace.c:2951 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "ne peut pas déplacer les objets dans ou à partir des schémas temporaires" -#: catalog/namespace.c:2940 +#: catalog/namespace.c:2957 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "ne peut pas déplacer les objets dans ou à partir des schémas TOAST" -#: catalog/namespace.c:3013 commands/schemacmds.c:256 commands/schemacmds.c:334 commands/tablecmds.c:891 +#: catalog/namespace.c:3029 commands/schemacmds.c:256 commands/schemacmds.c:334 commands/tablecmds.c:1017 #, c-format msgid "schema \"%s\" does not exist" msgstr "le schéma « %s » n'existe pas" -#: catalog/namespace.c:3044 +#: catalog/namespace.c:3060 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "nom de relation incorrecte (trop de points entre les noms) : %s" -#: catalog/namespace.c:3538 +#: catalog/namespace.c:3594 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "le collationnement « %s » pour l'encodage « %s » n'existe pas" -#: catalog/namespace.c:3593 +#: catalog/namespace.c:3649 #, c-format msgid "conversion \"%s\" does not exist" msgstr "la conversion « %s » n'existe pas" -#: catalog/namespace.c:3801 +#: catalog/namespace.c:3889 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "droit refusé pour la création de tables temporaires dans la base de données « %s »" -#: catalog/namespace.c:3817 +#: catalog/namespace.c:3905 #, c-format msgid "cannot create temporary tables during recovery" msgstr "ne peut pas créer des tables temporaires lors de la restauration" -#: catalog/namespace.c:3823 +#: catalog/namespace.c:3911 #, c-format msgid "cannot create temporary tables during a parallel operation" msgstr "ne peut pas créer de tables temporaires pendant une opération parallèle" -#: catalog/namespace.c:4072 commands/tablespace.c:1169 commands/variable.c:64 utils/misc/guc.c:9990 utils/misc/guc.c:10068 +#: catalog/namespace.c:4194 commands/tablespace.c:1171 commands/variable.c:64 utils/misc/guc.c:10271 utils/misc/guc.c:10349 #, c-format msgid "List syntax is invalid." msgstr "La syntaxe de la liste est invalide." -#: catalog/objectaddress.c:1237 catalog/pg_publication.c:66 commands/lockcmds.c:93 commands/policy.c:94 commands/policy.c:391 commands/policy.c:481 commands/tablecmds.c:223 commands/tablecmds.c:265 commands/tablecmds.c:1507 commands/tablecmds.c:4722 commands/tablecmds.c:8810 +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1742 commands/tablecmds.c:5013 commands/tablecmds.c:9637 #, c-format msgid "\"%s\" is not a table" msgstr "« %s » n'est pas une table" -#: catalog/objectaddress.c:1244 commands/tablecmds.c:235 commands/tablecmds.c:4752 commands/tablecmds.c:13085 commands/view.c:141 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 commands/tablecmds.c:5043 commands/tablecmds.c:14100 commands/view.c:138 #, c-format msgid "\"%s\" is not a view" msgstr "« %s » n'est pas une vue" -#: catalog/objectaddress.c:1251 commands/matview.c:174 commands/tablecmds.c:241 commands/tablecmds.c:13090 +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 commands/tablecmds.c:14105 #, c-format msgid "\"%s\" is not a materialized view" msgstr "« %s » n'est pas une vue matérialisée" -#: catalog/objectaddress.c:1258 commands/tablecmds.c:259 commands/tablecmds.c:4755 commands/tablecmds.c:13095 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 commands/tablecmds.c:5046 commands/tablecmds.c:14110 #, c-format msgid "\"%s\" is not a foreign table" msgstr "« %s » n'est pas une table distante" -#: catalog/objectaddress.c:1299 +#: catalog/objectaddress.c:1300 #, c-format msgid "must specify relation and object name" msgstr "doit indiquer les noms de relation et d'objet" -#: catalog/objectaddress.c:1375 catalog/objectaddress.c:1428 +#: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 #, c-format msgid "column name must be qualified" msgstr "le nom de la colonne doit être qualifié" -#: catalog/objectaddress.c:1471 +#: catalog/objectaddress.c:1472 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "la valeur par défaut de la colonne « %s » de la relation « %s » n'existe pas" -#: catalog/objectaddress.c:1508 commands/functioncmds.c:128 commands/tablecmds.c:251 commands/typecmds.c:3233 parser/parse_type.c:226 parser/parse_type.c:255 parser/parse_type.c:794 utils/adt/acl.c:4357 +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 commands/tablecmds.c:253 commands/typecmds.c:3324 parser/parse_type.c:226 parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 #, c-format msgid "type \"%s\" does not exist" msgstr "le type « %s » n'existe pas" -#: catalog/objectaddress.c:1625 +#: catalog/objectaddress.c:1628 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "l'opérateur %d (%s, %s) de %s n'existe pas" -#: catalog/objectaddress.c:1656 +#: catalog/objectaddress.c:1659 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "la fonction %d (%s, %s) de %s n'existe pas" -#: catalog/objectaddress.c:1707 catalog/objectaddress.c:1733 +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "la correspondance pour l'utilisateur « %s » sur le serveur « %s » n'existe pas" -#: catalog/objectaddress.c:1722 commands/foreigncmds.c:428 commands/foreigncmds.c:1004 commands/foreigncmds.c:1377 foreign/foreign.c:688 +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 foreign/foreign.c:688 #, c-format msgid "server \"%s\" does not exist" msgstr "le serveur « %s » n'existe pas" -#: catalog/objectaddress.c:1789 +#: catalog/objectaddress.c:1792 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "la relation de publication « %s » dans la publication « %s » n'existe pas" -#: catalog/objectaddress.c:1851 +#: catalog/objectaddress.c:1854 #, c-format msgid "unrecognized default ACL object type \"%c\"" msgstr "type d'objet de droits par défaut non reconnu « %c »" -#: catalog/objectaddress.c:1852 +#: catalog/objectaddress.c:1855 #, c-format msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." msgstr "Les types d'objet valides sont « %c », « %c », « %c », « %c », « %c »." -#: catalog/objectaddress.c:1903 +#: catalog/objectaddress.c:1906 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" -msgstr "le droit par défaut pour l'utilisateur « % s» dans le schéma « %s » de %s n'existe pas" +msgstr "le droit par défaut pour l'utilisateur « %s » dans le schéma « %s » de %s n'existe pas" -#: catalog/objectaddress.c:1908 +#: catalog/objectaddress.c:1911 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "le droit par défaut pour l'utilisateur « %s » sur %s n'existe pas" -#: catalog/objectaddress.c:1935 catalog/objectaddress.c:1993 catalog/objectaddress.c:2048 +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 catalog/objectaddress.c:2053 #, c-format msgid "name or argument lists may not contain nulls" msgstr "le nom ou les listes d'arguments ne peuvent pas contenir de valeurs NULL" -#: catalog/objectaddress.c:1969 +#: catalog/objectaddress.c:1972 #, c-format msgid "unsupported object type \"%s\"" msgstr "type d'objet « %s » non supporté" -#: catalog/objectaddress.c:1989 catalog/objectaddress.c:2007 catalog/objectaddress.c:2145 +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 catalog/objectaddress.c:2151 #, c-format msgid "name list length must be exactly %d" msgstr "la liste de nom doit être exactement de longueur %d" -#: catalog/objectaddress.c:2011 +#: catalog/objectaddress.c:2014 #, c-format msgid "large object OID may not be null" msgstr "l'OID du Large Object peut ne pas être NULL" -#: catalog/objectaddress.c:2020 catalog/objectaddress.c:2081 catalog/objectaddress.c:2088 +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 catalog/objectaddress.c:2093 #, c-format msgid "name list length must be at least %d" msgstr "la longueur de la liste de nom doit au moins être %d" -#: catalog/objectaddress.c:2074 catalog/objectaddress.c:2094 +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 #, c-format msgid "argument list length must be exactly %d" msgstr "la longueur de la liste d'arguments doit être %d exactement" -#: catalog/objectaddress.c:2320 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "doit être le propriétaire du Large Object %u" -#: catalog/objectaddress.c:2335 commands/functioncmds.c:1440 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 #, c-format msgid "must be owner of type %s or type %s" msgstr "doit être le propriétaire du type %s ou du type %s" -#: catalog/objectaddress.c:2385 catalog/objectaddress.c:2402 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" msgstr "doit être super-utilisateur" -#: catalog/objectaddress.c:2392 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "doit avoir l'attribut CREATEROLE" -#: catalog/objectaddress.c:2471 +#: catalog/objectaddress.c:2481 #, c-format msgid "unrecognized object type \"%s\"" msgstr "type d'objet non reconnu « %s »" -#: catalog/objectaddress.c:2666 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " colonne %s" +msgid "column %s of %s" +msgstr " colonne %s de %s" -#: catalog/objectaddress.c:2672 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" msgstr "fonction %s" -#: catalog/objectaddress.c:2677 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" msgstr "type %s" -#: catalog/objectaddress.c:2707 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" msgstr "conversion de %s en %s" -#: catalog/objectaddress.c:2727 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" msgstr "collationnement %s" -#: catalog/objectaddress.c:2751 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" msgstr "contrainte %s sur %s" -#: catalog/objectaddress.c:2757 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" msgstr "contrainte %s" -#: catalog/objectaddress.c:2774 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" msgstr "conversion %s" -#: catalog/objectaddress.c:2811 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" +msgid "default value for %s" msgstr "valeur par défaut pour %s" -#: catalog/objectaddress.c:2820 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "langage %s" -#: catalog/objectaddress.c:2825 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" msgstr "« Large Object » %u" -#: catalog/objectaddress.c:2830 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "opérateur %s" -#: catalog/objectaddress.c:2862 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "classe d'opérateur %s pour la méthode d'accès %s" -#: catalog/objectaddress.c:2885 +#: catalog/objectaddress.c:2939 #, c-format msgid "access method %s" msgstr "méthode d'accès %s" @@ -4051,7 +4228,7 @@ msgstr "méthode d'accès %s" #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2927 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "opérateur %d (%s, %s) de %s : %s" @@ -4060,255 +4237,265 @@ msgstr "opérateur %d (%s, %s) de %s : %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2977 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "fonction %d (%s, %s) de %s : %s" -#: catalog/objectaddress.c:3017 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "rule %s on " -msgstr "règle %s active " +msgid "rule %s on %s" +msgstr "règle %s sur %s" -#: catalog/objectaddress.c:3052 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "trigger %s actif " +msgid "trigger %s on %s" +msgstr "trigger %s sur %s" -#: catalog/objectaddress.c:3069 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" msgstr "schéma %s" -#: catalog/objectaddress.c:3086 +#: catalog/objectaddress.c:3152 #, c-format msgid "statistics object %s" msgstr "objet statistique %s" -#: catalog/objectaddress.c:3102 +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" msgstr "analyseur %s de la recherche plein texte" -#: catalog/objectaddress.c:3117 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" msgstr "dictionnaire %s de la recherche plein texte" -#: catalog/objectaddress.c:3132 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" msgstr "modèle %s de la recherche plein texte" -#: catalog/objectaddress.c:3147 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" msgstr "configuration %s de recherche plein texte" -#: catalog/objectaddress.c:3155 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" msgstr "rôle %s" -#: catalog/objectaddress.c:3168 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" msgstr "base de données %s" -#: catalog/objectaddress.c:3180 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" msgstr "tablespace %s" -#: catalog/objectaddress.c:3189 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" msgstr "wrapper de données distantes %s" -#: catalog/objectaddress.c:3198 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" msgstr "serveur %s" -#: catalog/objectaddress.c:3226 +#: catalog/objectaddress.c:3337 #, c-format msgid "user mapping for %s on server %s" msgstr "correspondance utilisateur pour %s sur le serveur %s" -#: catalog/objectaddress.c:3261 +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles relations appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "droits par défaut pour les nouvelles relations appartenant au rôle %s" -#: catalog/objectaddress.c:3266 +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles séquences appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "droits par défaut pour les nouvelles séquences appartenant au rôle %s" -#: catalog/objectaddress.c:3271 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouvelles fonctions appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "droits par défaut pour les nouvelles fonctions appartenant au rôle %s" -#: catalog/objectaddress.c:3276 +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "droits par défaut pour les nouveaux types appartenant au rôle %s dans le schéma %s" + +#: catalog/objectaddress.c:3416 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "droits par défaut pour les nouveaux types appartenant au rôle %s" -#: catalog/objectaddress.c:3281 +#: catalog/objectaddress.c:3422 #, c-format msgid "default privileges on new schemas belonging to role %s" msgstr "droits par défaut pour les nouveaux schémas appartenant au rôle %s" -#: catalog/objectaddress.c:3287 +#: catalog/objectaddress.c:3429 #, c-format -msgid "default privileges belonging to role %s" -msgstr "droits par défaut appartenant au rôle %s" +msgid "default privileges belonging to role %s in schema %s" +msgstr "droits par défaut appartenant au rôle %s dans le schéma %s" -#: catalog/objectaddress.c:3295 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr " dans le schéma %s" +msgid "default privileges belonging to role %s" +msgstr "droits par défaut appartenant au rôle %s" -#: catalog/objectaddress.c:3312 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" msgstr "extension %s" -#: catalog/objectaddress.c:3325 +#: catalog/objectaddress.c:3464 #, c-format msgid "event trigger %s" msgstr "trigger sur événement %s" -#: catalog/objectaddress.c:3357 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 #, c-format -msgid "policy %s on " -msgstr "politique %s sur " +msgid "policy %s on %s" +msgstr "politique %s sur %s" -#: catalog/objectaddress.c:3368 +#: catalog/objectaddress.c:3510 #, c-format msgid "publication %s" msgstr "publication %s" -#: catalog/objectaddress.c:3388 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 #, c-format -msgid "publication table %s in publication %s" -msgstr "table de publication %s dans la publication %s" +msgid "publication of %s in publication %s" +msgstr "publication de %s dans la publication %s" -#: catalog/objectaddress.c:3396 +#: catalog/objectaddress.c:3544 #, c-format msgid "subscription %s" msgstr "souscription %s" -#: catalog/objectaddress.c:3414 +#: catalog/objectaddress.c:3562 #, c-format msgid "transform for %s language %s" msgstr "transformation pour %s langage %s" -#: catalog/objectaddress.c:3475 +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" msgstr "table %s" -#: catalog/objectaddress.c:3479 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" msgstr "index %s" -#: catalog/objectaddress.c:3483 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "séquence %s" -#: catalog/objectaddress.c:3487 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "table TOAST %s" -#: catalog/objectaddress.c:3491 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "vue %s" -#: catalog/objectaddress.c:3495 +#: catalog/objectaddress.c:3646 #, c-format msgid "materialized view %s" msgstr "vue matérialisée %s" -#: catalog/objectaddress.c:3499 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "type composite %s" -#: catalog/objectaddress.c:3503 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" msgstr "table distante %s" -#: catalog/objectaddress.c:3508 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "relation %s" -#: catalog/objectaddress.c:3545 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" msgstr "famille d'opérateur %s pour la méthode d'accès %s" -#: catalog/objectaddress.c:4914 -#, c-format -msgid "%s in publication %s" -msgstr "%s dans la publication %s" - -#: catalog/partition.c:727 -#, c-format -msgid "cannot create range partition with empty range" -msgstr "ne peut pas créer une partition par intervalle avec un intervalle vide" - -#: catalog/partition.c:808 -#, c-format -msgid "partition \"%s\" would overlap partition \"%s\"" -msgstr "la partition « %s » surchargerait la partition « %s »" - -#: catalog/partition.c:921 catalog/partition.c:1099 commands/analyze.c:1446 commands/copy.c:1467 commands/tablecmds.c:8872 executor/execExprInterp.c:2853 executor/execMain.c:1878 executor/execMain.c:1956 executor/execMain.c:2004 executor/execMain.c:2114 executor/execMain.c:3294 executor/nodeModifyTable.c:1518 +#: catalog/partition.c:180 commands/analyze.c:1514 commands/indexcmds.c:928 commands/tablecmds.c:944 commands/tablecmds.c:7906 commands/tablecmds.c:9699 commands/tablecmds.c:14994 commands/tablecmds.c:15523 executor/execExprInterp.c:3275 executor/execMain.c:1940 executor/execMain.c:2019 executor/execMain.c:2067 executor/execMain.c:2173 executor/execPartition.c:471 executor/execPartition.c:531 executor/execPartition.c:647 +#: executor/execPartition.c:750 executor/execPartition.c:821 executor/execPartition.c:1019 executor/nodeModifyTable.c:1859 msgid "could not convert row type" msgstr "n'a pas pu convertir le type de ligne" -#: catalog/pg_aggregate.c:125 +#: catalog/pg_aggregate.c:126 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "les agrégats ne peuvent avoir plus de %d argument" msgstr[1] "les agrégats ne peuvent avoir plus de %d arguments" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" msgstr "n'a pas pu déterminer le type de données de transition" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." msgstr "" "Un agrégat utilisant un type de transition polymorphique doit avoir au moins\n" "un argument polymorphique." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:173 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "un agrégat à ensemble trié variadique doit être VARIADIC sur le type ANY" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:199 #, c-format msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "un agrégat à ensemble hypothétique doit avoir des arguments directs correspondant aux arguments agrégés" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "le type de retour de la fonction de transition %s n'est pas %s" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "" @@ -4316,152 +4503,141 @@ msgstr "" "stricte et que le type de transition n'est pas compatible avec le type en\n" "entrée" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:335 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "le type de retour de la fonction de transition inverse %s n'est pas %s" -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2298 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "la fonction de transition d'agrégat en déplacement ne doit pas renvoyer null" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "la fonction finale avec des arguments supplémentaires ne doit pas être déclarée avec la clause STRICT" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:427 #, c-format msgid "return type of combine function %s is not %s" msgstr "le type de retour de la fonction de d'unification %s n'est pas %s" -#: catalog/pg_aggregate.c:436 -#, fuzzy, c-format -#| msgid "combine function with \"%s\" transition type must not be declared STRICT" +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2947 +#, c-format msgid "combine function with transition type %s must not be declared STRICT" -msgstr "la fonction d'unification avec le type de transaction «%s » ne doit pas être déclaré STRICT" +msgstr "la fonction d'unification avec le type de transaction %s ne doit pas être déclaré STRICT" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:458 #, c-format msgid "return type of serialization function %s is not %s" msgstr "le type de retour de la fonction de sérialisation %s n'est pas %s" -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:479 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "le type de retour de la fonction de désérialisation %s n'est pas %s" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:243 catalog/pg_proc.c:250 +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "n'a pas pu déterminer le type de données en résultat" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:496 #, c-format msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." msgstr "" "Un agrégat renvoyant un type polymorphique doit avoir au moins un argument\n" "de type polymorphique." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:256 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "utilisation non sûre des pseudo-types « INTERNAL »" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:257 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgstr "" "Une fonction renvoyant « internal » doit avoir au moins un argument du type\n" "« internal »." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:562 #, c-format msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "l'impémentation d'aggrégat glissant retourne le type %s, mais l'implémentation standard retourne le type %s" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "l'opérateur de tri peut seulement être indiqué pour des agrégats à un seul argument" -#: catalog/pg_aggregate.c:810 commands/typecmds.c:1698 commands/typecmds.c:1749 commands/typecmds.c:1780 commands/typecmds.c:1803 commands/typecmds.c:1824 commands/typecmds.c:1851 commands/typecmds.c:1878 commands/typecmds.c:1955 commands/typecmds.c:1997 parser/parse_func.c:369 parser/parse_func.c:398 parser/parse_func.c:423 parser/parse_func.c:437 parser/parse_func.c:512 parser/parse_func.c:523 parser/parse_func.c:1977 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "la fonction %s n'existe pas" -#: catalog/pg_aggregate.c:816 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "la fonction %s renvoie un ensemble" -#: catalog/pg_aggregate.c:831 +#: catalog/pg_aggregate.c:840 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "la fonction %s doit accepter VARIADIC ANY pour être utilisé dans cet agrégat" -#: catalog/pg_aggregate.c:855 +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "la fonction %s requiert une coercion sur le type à l'exécution" -#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format msgid "collation \"%s\" already exists, skipping" msgstr "le collationnement « %s » existe déjà, poursuite du traitement" -#: catalog/pg_collation.c:95 +#: catalog/pg_collation.c:94 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" msgstr "le collationnement « %s » pour l'encodage « %s » existe déjà, poursuite du traitement" -#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "le collationnement « %s » existe déjà" -#: catalog/pg_collation.c:105 +#: catalog/pg_collation.c:104 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "le collationnement « %s » pour l'encodage « %s » existe déjà" -#: catalog/pg_constraint.c:658 +#: catalog/pg_constraint.c:687 #, c-format msgid "constraint \"%s\" for domain %s already exists" msgstr "la contrainte « %s » du domaine %s existe déjà" -#: catalog/pg_constraint.c:788 -#, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "la table « %s » a de nombreuses contraintes nommées « %s »" - -#: catalog/pg_constraint.c:800 +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "la contrainte « %s » de la table « %s » n'existe pas" -#: catalog/pg_constraint.c:846 -#, c-format -msgid "domain %s has multiple constraints named \"%s\"" -msgstr "le domaine %s a plusieurs contraintes nommées « %s »" - -#: catalog/pg_constraint.c:858 +#: catalog/pg_constraint.c:1056 #, c-format msgid "constraint \"%s\" for domain %s does not exist" msgstr "la contrainte « %s » du domaine %s n'existe pas" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "la conversion « %s » existe déjà" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "la conversion par défaut de %s vers %s existe déjà" -#: catalog/pg_depend.c:163 commands/extension.c:3218 +#: catalog/pg_depend.c:163 commands/extension.c:3225 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s est déjà un membre de l'extension « %s »" @@ -4511,170 +4687,176 @@ msgstr "ALTER TYPE ADD BEFORE/AFTER est incompatible avec la mise à jour binair msgid "schema \"%s\" already exists" msgstr "le schéma « %s » existe déjà" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:358 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "« %s » n'est pas un nom d'opérateur valide" -#: catalog/pg_operator.c:367 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" msgstr "seuls les opérateurs binaires peuvent avoir des commutateurs" -#: catalog/pg_operator.c:371 commands/operatorcmds.c:482 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "seuls les opérateurs binaires peuvent avoir une sélectivité des jointures" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "seuls les opérateurs binaires peuvent exécuter des jointures MERGE" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "seuls les opérateurs binaires ont du hachage" -#: catalog/pg_operator.c:390 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "seuls les opérateurs booléens peuvent avoir des négations" -#: catalog/pg_operator.c:394 commands/operatorcmds.c:490 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "seuls les opérateurs booléens peuvent avoir une sélectivité des restrictions" -#: catalog/pg_operator.c:398 commands/operatorcmds.c:494 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "seuls les opérateurs booléens peuvent avoir une sélectivité des jointures" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "seuls les opérateurs booléens peuvent exécuter des jointures MERGE" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "seuls les opérateurs booléens peuvent hacher" -#: catalog/pg_operator.c:418 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "l'opérateur %s existe déjà" -#: catalog/pg_operator.c:612 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "l'opérateur ne peut pas être son propre opérateur de négation ou de tri" -#: catalog/pg_proc.c:131 parser/parse_func.c:2001 parser/parse_func.c:2041 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "les fonctions ne peuvent avoir plus de %d argument" msgstr[1] "les fonctions ne peuvent avoir plus de %d arguments" -#: catalog/pg_proc.c:244 +#: catalog/pg_proc.c:241 #, c-format msgid "A function returning a polymorphic type must have at least one polymorphic argument." msgstr "" "Une fonction renvoyant un type polymorphique doit avoir au moins un argument\n" "de type polymorphique." -#: catalog/pg_proc.c:251 +#: catalog/pg_proc.c:248 #, c-format msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." msgstr "Une fonction renvoyant « anyrange » doit avoir au moins un argument du type « anyrange »." -#: catalog/pg_proc.c:269 -#, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "« %s » est déjà un attribut du type %s" - -#: catalog/pg_proc.c:400 +#: catalog/pg_proc.c:383 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "la fonction « %s » existe déjà avec des types d'arguments identiques" -#: catalog/pg_proc.c:414 catalog/pg_proc.c:437 +#: catalog/pg_proc.c:393 +#, c-format +msgid "cannot change routine kind" +msgstr "ne peut pas modifier le type de routine" + +#: catalog/pg_proc.c:395 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "« %s » est une fonction d'agrégat." + +#: catalog/pg_proc.c:397 +#, c-format +msgid "\"%s\" is a function." +msgstr "« %s » est une fonction." + +#: catalog/pg_proc.c:399 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "« %s » est une procédure." + +#: catalog/pg_proc.c:401 +#, c-format +msgid "\"%s\" is a window function." +msgstr "la fonction « %s » est une fonction window." + +#: catalog/pg_proc.c:419 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "ne peut pas changer le fait qu'une procédure ait des paramètres en sortie ou non" + +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 #, c-format msgid "cannot change return type of existing function" msgstr "ne peut pas modifier le type de retour d'une fonction existante" -#: catalog/pg_proc.c:415 catalog/pg_proc.c:439 catalog/pg_proc.c:482 catalog/pg_proc.c:506 catalog/pg_proc.c:532 +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 catalog/pg_proc.c:520 catalog/pg_proc.c:548 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "Utilisez tout d'abord DROP FUNCTION %s." +msgid "Use %s %s first." +msgstr "Utilisez tout d'abord %s %s." -#: catalog/pg_proc.c:438 +#: catalog/pg_proc.c:447 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "Le type de ligne défini par les paramètres OUT est différent." -#: catalog/pg_proc.c:480 +#: catalog/pg_proc.c:491 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "ne peut pas modifier le nom du paramètre en entrée « %s »" -#: catalog/pg_proc.c:505 +#: catalog/pg_proc.c:518 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "" "ne peut pas supprimer les valeurs par défaut des paramètres de la\n" "fonction existante" -#: catalog/pg_proc.c:531 +#: catalog/pg_proc.c:546 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "" "ne peut pas modifier le type de données d'un paramètre avec une valeur\n" "par défaut" -#: catalog/pg_proc.c:544 -#, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "la fonction « %s » est une fonction d'agrégat" - -#: catalog/pg_proc.c:549 -#, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "la fonction « %s » n'est pas une fonction d'agrégat" - -#: catalog/pg_proc.c:557 -#, c-format -msgid "function \"%s\" is a window function" -msgstr "la fonction « %s » est une fonction window" - -#: catalog/pg_proc.c:562 -#, c-format -msgid "function \"%s\" is not a window function" -msgstr "la fonction « %s » n'est pas une fonction window" - -#: catalog/pg_proc.c:768 +#: catalog/pg_proc.c:749 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "il n'existe pas de fonction intégrée nommée « %s »" -#: catalog/pg_proc.c:866 +#: catalog/pg_proc.c:847 #, c-format msgid "SQL functions cannot return type %s" msgstr "les fonctions SQL ne peuvent pas renvoyer un type %s" -#: catalog/pg_proc.c:881 +#: catalog/pg_proc.c:862 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "les fonctions SQL ne peuvent avoir d'arguments du type %s" -#: catalog/pg_proc.c:968 executor/functions.c:1429 +#: catalog/pg_proc.c:950 executor/functions.c:1434 #, c-format msgid "SQL function \"%s\"" msgstr "Fonction SQL « %s »" -#: catalog/pg_publication.c:57 commands/trigger.c:196 +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 #, c-format msgid "\"%s\" is a partitioned table" msgstr "« %s » est une table partitionnée" @@ -4714,12 +4896,12 @@ msgstr "la table « %s » ne peut pas être répliquée" msgid "Temporary and unlogged relations cannot be replicated." msgstr "Les tables tremporaires et les tables non journalisées ne peuvent pas être répliquées." -#: catalog/pg_publication.c:166 +#: catalog/pg_publication.c:175 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "la relation « %s » est déjà un membre de la publication « %s »" -#: catalog/pg_publication.c:393 catalog/pg_publication.c:414 commands/publicationcmds.c:401 commands/publicationcmds.c:702 +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 commands/publicationcmds.c:415 commands/publicationcmds.c:716 #, c-format msgid "publication \"%s\" does not exist" msgstr "la publication « %s » n'existe pas" @@ -4793,37 +4975,37 @@ msgstr "" "ne peut pas réaffecter les objets appartenant à %s car ils sont nécessaires au\n" "système de bases de données" -#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:636 commands/subscriptioncmds.c:844 commands/subscriptioncmds.c:1044 +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 #, c-format msgid "subscription \"%s\" does not exist" msgstr "la souscription « %s » n'existe pas" -#: catalog/pg_type.c:136 catalog/pg_type.c:452 +#: catalog/pg_type.c:135 catalog/pg_type.c:459 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "OID de pg_type non configuré en mode de mise à jour binaire" -#: catalog/pg_type.c:251 +#: catalog/pg_type.c:241 #, c-format msgid "invalid type internal size %d" msgstr "taille interne de type invalide %d" -#: catalog/pg_type.c:267 catalog/pg_type.c:275 catalog/pg_type.c:283 catalog/pg_type.c:292 +#: catalog/pg_type.c:257 catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:282 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "l'alignement « %c » est invalide pour le type passé par valeur de taille %d" -#: catalog/pg_type.c:299 +#: catalog/pg_type.c:289 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "la taille interne %d est invalide pour le type passé par valeur" -#: catalog/pg_type.c:308 catalog/pg_type.c:314 +#: catalog/pg_type.c:298 catalog/pg_type.c:304 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "l'alignement « %c » est invalide pour le type de longueur variable" -#: catalog/pg_type.c:322 +#: catalog/pg_type.c:312 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "les types de taille fixe doivent avoir un stockage de base" @@ -4833,7 +5015,7 @@ msgstr "les types de taille fixe doivent avoir un stockage de base" msgid "could not form array type name for type \"%s\"" msgstr "n'a pas pu former le nom du type array pour le type de données %s" -#: catalog/toasting.c:105 commands/indexcmds.c:399 commands/tablecmds.c:4734 commands/tablecmds.c:12973 +#: catalog/toasting.c:105 commands/indexcmds.c:443 commands/tablecmds.c:5025 commands/tablecmds.c:13988 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "« %s » n'est pas une table ou une vue matérialisée" @@ -4845,92 +5027,97 @@ msgstr "" "les tables partagées ne peuvent pas avoir une table TOAST après la commande\n" "initdb" -#: commands/aggregatecmds.c:157 +#: commands/aggregatecmds.c:166 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "seuls les agrégats à ensemble ordonné peuvent être hypothétiques" -#: commands/aggregatecmds.c:182 +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "l'attribut de l'agrégat « %s » n'est pas reconnu" -#: commands/aggregatecmds.c:192 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" msgstr "le type source de l'agrégat doit être spécifié" -#: commands/aggregatecmds.c:196 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" msgstr "la fonction source de l'agrégat doit être spécifiée" -#: commands/aggregatecmds.c:208 +#: commands/aggregatecmds.c:217 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "la fonction msfunc de l'agrégat doit être spécifiée quand mstype est spécifié" -#: commands/aggregatecmds.c:212 +#: commands/aggregatecmds.c:221 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "la fonction minvfunc de l'agrégat doit être spécifiée quand mstype est spécifié" -#: commands/aggregatecmds.c:219 +#: commands/aggregatecmds.c:228 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "la fonction msfunc de l'agrégat ne doit pas être spécifiée sans mstype" -#: commands/aggregatecmds.c:223 +#: commands/aggregatecmds.c:232 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "la fonction minvfunc de l'agrégat ne doit pas être spécifiée sans mstype" -#: commands/aggregatecmds.c:227 +#: commands/aggregatecmds.c:236 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "la fonction mfinalfunc de l'agrégat ne doit pas être spécifiée sans mstype" -#: commands/aggregatecmds.c:231 +#: commands/aggregatecmds.c:240 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "la fonction msspace de l'agrégat ne doit pas être spécifiée sans mstype" -#: commands/aggregatecmds.c:235 +#: commands/aggregatecmds.c:244 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "la fonction minitcond de l'agrégat ne doit pas être spécifiée sans mstype" -#: commands/aggregatecmds.c:255 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" msgstr "le type de saisie de l'agrégat doit être précisé" -#: commands/aggregatecmds.c:285 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "le type de base est redondant avec la spécification du type en entrée de l'agrégat" -#: commands/aggregatecmds.c:326 commands/aggregatecmds.c:367 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "Le type de données de transition de l'agrégat ne peut pas être %s" -#: commands/aggregatecmds.c:338 +#: commands/aggregatecmds.c:356 #, c-format msgid "serialization functions may be specified only when the aggregate transition data type is %s" msgstr "les fonctions de sérialisation ne peuvent être spécifiées que quand le type de données des transitions d'aggrégat est %s" -#: commands/aggregatecmds.c:348 +#: commands/aggregatecmds.c:366 #, c-format msgid "must specify both or neither of serialization and deserialization functions" msgstr "doit spécifier soit toutes soit aucunes des fonctions de sérialisation et désérialisation" -#: commands/aggregatecmds.c:413 commands/functioncmds.c:564 +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "le paramètre « parallel » doit être SAFE, RESTRICTED ou UNSAFE" -#: commands/alter.c:84 commands/event_trigger.c:234 +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "le paramètre « %s » doit être READ_ONLY, SHAREABLE, ou READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format msgid "event trigger \"%s\" already exists" msgstr "le trigger sur événement « %s » existe déjà" @@ -4945,12 +5132,12 @@ msgstr "le wrapper de données distantes « %s » existe déjà" msgid "server \"%s\" already exists" msgstr "le serveur « %s » existe déjà" -#: commands/alter.c:93 commands/proclang.c:367 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "le langage « %s » existe déjà" -#: commands/alter.c:96 commands/publicationcmds.c:170 +#: commands/alter.c:96 commands/publicationcmds.c:176 #, c-format msgid "publication \"%s\" already exists" msgstr "la publication « %s » existe déjà" @@ -4995,7 +5182,7 @@ msgstr "la configuration de recherche plein texte « %s » existe déjà dans le msgid "must be superuser to rename %s" msgstr "doit être super-utilisateur pour renommer « %s »" -#: commands/alter.c:709 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" msgstr "doit être super-utilisateur pour configurer le schéma de %s" @@ -5020,7 +5207,7 @@ msgstr "la méthode d'accès « %s » existe déjà" msgid "must be superuser to drop access methods" msgstr "doit être super-utilisateur pour supprimer des méthodes d'accès" -#: commands/amcmds.c:174 commands/indexcmds.c:163 commands/indexcmds.c:515 commands/opclasscmds.c:363 commands/opclasscmds.c:777 +#: commands/amcmds.c:174 commands/indexcmds.c:173 commands/indexcmds.c:583 commands/opclasscmds.c:364 commands/opclasscmds.c:778 #, c-format msgid "access method \"%s\" does not exist" msgstr "la méthode d'accès « %s » n'existe pas" @@ -5030,61 +5217,71 @@ msgstr "la méthode d'accès « %s » n'existe pas" msgid "handler function is not specified" msgstr "la fonction handler n'est pas spécifiée" -#: commands/amcmds.c:262 commands/event_trigger.c:243 commands/foreigncmds.c:487 commands/proclang.c:117 commands/proclang.c:289 commands/trigger.c:590 parser/parse_clause.c:1011 +#: commands/amcmds.c:262 commands/event_trigger.c:245 commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 commands/trigger.c:696 parser/parse_clause.c:990 #, c-format msgid "function %s must return type %s" msgstr "la fonction %s doit renvoyer le type %s" -#: commands/analyze.c:151 +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" msgstr "ignore l'analyse de « %s » --- verrou non disponible" -#: commands/analyze.c:168 +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "ignore l'analyse de « %s » --- la relation n'existe plus" + +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" msgstr "ignore « %s » --- seul le super-utilisateur peut l'analyser" -#: commands/analyze.c:172 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" msgstr "" "ignore « %s » --- seul le super-utilisateur ou le propriétaire de la base de\n" "données peut l'analyser" -#: commands/analyze.c:176 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" msgstr "" "ignore « %s » --- seul le propriétaire de la table ou de la base de données\n" "peut l'analyser" -#: commands/analyze.c:236 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "ignore « %s » --- ne peut pas analyser cette table distante" -#: commands/analyze.c:253 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "ignore « %s » --- ne peut pas analyser les objets autres que les tables et les tables système" -#: commands/analyze.c:334 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "analyse l'arbre d'héritage « %s.%s »" -#: commands/analyze.c:339 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "analyse « %s.%s »" -#: commands/analyze.c:668 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "la colonne « %s » de la relation « %s » apparait plus d'une fois" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "ANALYZE automatique de la table « %s.%s.%s » ; utilisation système : %s" -#: commands/analyze.c:1220 +#: commands/analyze.c:1288 #, c-format msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" msgstr "" @@ -5093,130 +5290,140 @@ msgstr "" " %d lignes dans l'échantillon,\n" " %.0f lignes totales estimées" -#: commands/analyze.c:1300 +#: commands/analyze.c:1368 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" msgstr "ignore l'analyse de l'arbre d'héritage « %s.%s » --- cet arbre d'héritage ne contient pas de tables enfants" -#: commands/analyze.c:1398 +#: commands/analyze.c:1466 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" msgstr "ignore l'analyse de l'arbre d'héritage « %s.%s » --- cet arbre d'héritage ne contient pas de tables enfants analysables" -#: commands/async.c:555 +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "le nom du canal ne peut pas être vide" -#: commands/async.c:560 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "nom du canal trop long" -#: commands/async.c:567 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "chaîne de charge trop longue" -#: commands/async.c:753 +#: commands/async.c:756 #, c-format msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" msgstr "" "ne peut pas exécuter PREPARE sur une transaction qui a exécuté LISTEN,\n" "UNLISTEN ou NOTIFY" -#: commands/async.c:856 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "trop de notifications dans la queue NOTIFY" -#: commands/async.c:1486 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "la queue NOTIFY est pleine à %.0f%%" -#: commands/async.c:1488 +#: commands/async.c:1493 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "Le processus serveur de PID %d est parmi ceux qui ont les transactions les plus anciennes." -#: commands/async.c:1491 +#: commands/async.c:1496 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "" "La queue NOTIFY ne peut pas être vidée jusqu'à ce que le processus finisse\n" "sa transaction en cours." -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "ne peut pas exécuter CLUSTER sur les tables temporaires des autres sessions" -#: commands/cluster.c:159 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "ne peut pas exécuter CLUSTER sur une table partitionnée" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "Il n'existe pas d'index CLUSTER pour la table « %s »" -#: commands/cluster.c:173 commands/tablecmds.c:10185 commands/tablecmds.c:12066 +#: commands/cluster.c:181 commands/tablecmds.c:11145 commands/tablecmds.c:13050 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "l'index « %s » pour la table « %s » n'existe pas" -#: commands/cluster.c:353 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "ne peut pas exécuter CLUSTER sur un catalogue partagé" -#: commands/cluster.c:368 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "ne peut pas exécuter VACUUM sur les tables temporaires des autres sessions" -#: commands/cluster.c:431 commands/tablecmds.c:12076 +#: commands/cluster.c:439 commands/tablecmds.c:13060 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "« %s » n'est pas un index de la table « %s »" -#: commands/cluster.c:439 +#: commands/cluster.c:447 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "" "ne peut pas exécuter CLUSTER sur l'index « %s » car la méthode d'accès de\n" "l'index ne gère pas cette commande" -#: commands/cluster.c:451 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "ne peut pas exécuter CLUSTER sur l'index partiel « %s »" -#: commands/cluster.c:465 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "ne peut pas exécuter la commande CLUSTER sur l'index invalide « %s »" -#: commands/cluster.c:918 +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "ne peut pas marquer un index comme CLUSTER sur une table partitionnée" + +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "cluster sur « %s.%s » en utilisant un parcours d'index sur « %s »" -#: commands/cluster.c:924 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "cluster sur « %s.%s » en utilisant un parcours séquentiel puis un tri" -#: commands/cluster.c:929 commands/vacuumlazy.c:490 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" msgstr "exécution du VACUUM sur « %s.%s »" -#: commands/cluster.c:1084 +#: commands/cluster.c:1106 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "" "« %s » : %.0f versions de ligne supprimables, %.0f non supprimables\n" "parmi %u pages" -#: commands/cluster.c:1088 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5225,92 +5432,87 @@ msgstr "" "%.0f versions de lignes ne peuvent pas encore être supprimées.\n" "%s." -#: commands/collationcmds.c:101 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "attribut de collationnement « %s » non reconnu" -#: commands/collationcmds.c:143 +#: commands/collationcmds.c:142 #, c-format msgid "collation \"default\" cannot be copied" msgstr "le collationnement « default » ne peut pas être copié" -#: commands/collationcmds.c:173 +#: commands/collationcmds.c:172 #, c-format msgid "unrecognized collation provider: %s" msgstr "fournisseur de collationnement non reconnu : %s" -#: commands/collationcmds.c:182 +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "le paramètre « lc_collate » doit être spécifié" -#: commands/collationcmds.c:187 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "le paramètre « lc_ctype » doit être spécifié" -#: commands/collationcmds.c:246 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "le collationnament « %s » pour l'encodage « %s » existe déjà dans le schéma « %s »" -#: commands/collationcmds.c:257 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "le collationnement « %s » existe déjà dans le schéma « %s »" -#: commands/collationcmds.c:305 +#: commands/collationcmds.c:304 #, c-format msgid "changing version from %s to %s" msgstr "changement de version de %s à %s" -#: commands/collationcmds.c:320 +#: commands/collationcmds.c:319 #, c-format msgid "version has not changed" msgstr "la version n'a pas changé" -#: commands/collationcmds.c:451 +#: commands/collationcmds.c:450 #, c-format msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "n'a pas pu convertir le nom de locale « %s » en balise de langage : %s" -#: commands/collationcmds.c:512 +#: commands/collationcmds.c:511 #, c-format msgid "must be superuser to import system collations" msgstr "doit être super-utilisateur pour importer les collationnements systèmes" -#: commands/collationcmds.c:535 commands/copy.c:1860 commands/copy.c:3102 +#: commands/collationcmds.c:534 commands/copy.c:1844 commands/copy.c:3181 libpq/be-secure-common.c:80 #, c-format msgid "could not execute command \"%s\": %m" msgstr "n'a pas pu exécuter la commande « %s » : %m" -#: commands/collationcmds.c:666 +#: commands/collationcmds.c:665 #, c-format msgid "no usable system locales were found" msgstr "aucune locale système utilisable n'a été trouvée" -#: commands/collationcmds.c:730 commands/collationcmds.c:769 -#, c-format -msgid "could not get keyword values for locale \"%s\": %s" -msgstr "n'a pas pu obtenir les valeurs des mots clés pour la locale « %s » : %s" - -#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 commands/dbcommands.c:1100 commands/dbcommands.c:1290 commands/dbcommands.c:1513 commands/dbcommands.c:1627 commands/dbcommands.c:2043 utils/init/postinit.c:846 utils/init/postinit.c:951 utils/init/postinit.c:968 +#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 commands/dbcommands.c:1100 commands/dbcommands.c:1290 commands/dbcommands.c:1513 commands/dbcommands.c:1627 commands/dbcommands.c:2043 utils/init/postinit.c:855 utils/init/postinit.c:960 utils/init/postinit.c:977 #, c-format msgid "database \"%s\" does not exist" msgstr "la base de données « %s » n'existe pas" -#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:931 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni un type composite, ni une table distante" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2712 +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "la fonction « %s » n'a pas été appelée par le gestionnaire de triggers" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2721 +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "la fonction « %s » doit être exécutée pour l'instruction AFTER ROW" @@ -5320,548 +5522,548 @@ msgstr "la fonction « %s » doit être exécutée pour l'instruction AFTER ROW" msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "la fonction « %s » doit être exécutée pour les instructions INSERT ou UPDATE" -#: commands/conversioncmds.c:66 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "le codage source « %s » n'existe pas" -#: commands/conversioncmds.c:73 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "l'encodage de destination « %s » n'existe pas" -#: commands/conversioncmds.c:87 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "la fonction de conversion d'encodage %s doit renvoyer le type %s" -#: commands/copy.c:373 commands/copy.c:407 +#: commands/copy.c:374 commands/copy.c:408 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY n'est pas supporté vers stdout ou à partir de stdin" -#: commands/copy.c:507 +#: commands/copy.c:508 #, c-format msgid "could not write to COPY program: %m" msgstr "n'a pas pu écrire vers le programme COPY : %m" -#: commands/copy.c:512 +#: commands/copy.c:513 #, c-format msgid "could not write to COPY file: %m" msgstr "n'a pas pu écrire dans le fichier COPY : %m" -#: commands/copy.c:525 +#: commands/copy.c:526 #, c-format msgid "connection lost during COPY to stdout" msgstr "connexion perdue lors de l'opération COPY vers stdout" -#: commands/copy.c:569 +#: commands/copy.c:570 #, c-format msgid "could not read from COPY file: %m" msgstr "n'a pas pu lire le fichier COPY : %m" -#: commands/copy.c:585 commands/copy.c:606 commands/copy.c:610 tcop/postgres.c:335 tcop/postgres.c:371 tcop/postgres.c:398 +#: commands/copy.c:588 commands/copy.c:609 commands/copy.c:613 tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "" "fin de fichier (EOF) inattendue de la connexion du client avec une\n" "transaction ouverte" -#: commands/copy.c:623 +#: commands/copy.c:626 #, c-format msgid "COPY from stdin failed: %s" msgstr "échec de la commande COPY à partir de stdin : %s" -#: commands/copy.c:639 +#: commands/copy.c:642 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "type 0x%02X du message, inattendu, lors d'une opération COPY à partir de stdin" -#: commands/copy.c:800 +#: commands/copy.c:808 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "doit être super-utilisateur pour utiliser COPY avec un programme externe" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "doit être super-utilisateur ou membre du rôle pg_execute_server_program pour utiliser COPY avec un programme externe" -#: commands/copy.c:801 commands/copy.c:807 +#: commands/copy.c:809 commands/copy.c:818 commands/copy.c:825 #, c-format msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "" "Tout le monde peut utiliser COPY vers stdout ou à partir de stdin.\n" "La commande \\copy de psql fonctionne aussi pour tout le monde." -#: commands/copy.c:806 +#: commands/copy.c:817 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "doit être super-utilisateur pour utiliser COPY à partir ou vers un fichier" +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "doit être super-utilisateur ou membre du rôle pg_read_all_settings pour utiliser COPY depuis un fichier" -#: commands/copy.c:868 +#: commands/copy.c:824 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "doit être super-utilisateur ou membre de pg_read_all_settings pour utiliser COPY vers un fichier" + +#: commands/copy.c:887 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "COPY FROM non supporté avec la sécurité niveau ligne" -#: commands/copy.c:869 +#: commands/copy.c:888 #, c-format msgid "Use INSERT statements instead." msgstr "Utilisez des instructions INSERT à la place." -#: commands/copy.c:1054 +#: commands/copy.c:1075 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "format COPY « %s » non reconnu" -#: commands/copy.c:1134 commands/copy.c:1150 commands/copy.c:1165 commands/copy.c:1187 +#: commands/copy.c:1155 commands/copy.c:1171 commands/copy.c:1186 commands/copy.c:1208 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "l'argument de l'option « %s » doit être une liste de noms de colonnes" -#: commands/copy.c:1202 +#: commands/copy.c:1223 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "l'argument de l'option « %s » doit être un nom d'encodage valide" -#: commands/copy.c:1209 commands/dbcommands.c:242 commands/dbcommands.c:1461 +#: commands/copy.c:1230 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" msgstr "option « %s » non reconnu" -#: commands/copy.c:1221 +#: commands/copy.c:1242 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "ne peut pas spécifier le délimiteur (DELIMITER) en mode binaire (BINARY)" -#: commands/copy.c:1226 +#: commands/copy.c:1247 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "ne peut pas spécifier NULL en mode binaire (BINARY)" -#: commands/copy.c:1248 +#: commands/copy.c:1269 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "le délimiteur COPY doit être sur un seul caractère sur un octet" -#: commands/copy.c:1255 +#: commands/copy.c:1276 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "le délimiteur de COPY ne peut pas être un retour à la ligne ou un retour chariot" -#: commands/copy.c:1261 +#: commands/copy.c:1282 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "" "la représentation du NULL dans COPY ne peut pas utiliser le caractère du\n" "retour à la ligne ou du retour chariot" -#: commands/copy.c:1278 +#: commands/copy.c:1299 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "le délimiteur de COPY ne peut pas être « %s »" -#: commands/copy.c:1284 +#: commands/copy.c:1305 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "COPY HEADER disponible uniquement en mode CSV" -#: commands/copy.c:1290 +#: commands/copy.c:1311 #, c-format msgid "COPY quote available only in CSV mode" msgstr "le guillemet COPY n'est disponible que dans le mode CSV" -#: commands/copy.c:1295 +#: commands/copy.c:1316 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "le guillemet COPY doit être sur un seul caractère sur un octet" -#: commands/copy.c:1300 +#: commands/copy.c:1321 #, c-format msgid "COPY delimiter and quote must be different" msgstr "le délimiteur de COPY ne doit pas être un guillemet" -#: commands/copy.c:1306 +#: commands/copy.c:1327 #, c-format msgid "COPY escape available only in CSV mode" msgstr "le caractère d'échappement COPY n'est disponible que dans le mode CSV" -#: commands/copy.c:1311 +#: commands/copy.c:1332 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "le caractère d'échappement COPY doit être sur un seul caractère sur un octet" -#: commands/copy.c:1317 +#: commands/copy.c:1338 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "le guillemet forcé COPY n'est disponible que dans le mode CSV" -#: commands/copy.c:1321 +#: commands/copy.c:1342 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "le guillemet forcé COPY n'est disponible qu'en utilisant COPY TO" -#: commands/copy.c:1327 +#: commands/copy.c:1348 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "« COPY force not null » n'est disponible que dans la version CSV" -#: commands/copy.c:1331 +#: commands/copy.c:1352 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "« COPY force not null » n'est disponible qu'en utilisant COPY FROM" -#: commands/copy.c:1337 +#: commands/copy.c:1358 #, c-format msgid "COPY force null available only in CSV mode" msgstr "« COPY force null » n'est disponible que dans le mode CSV" -#: commands/copy.c:1342 +#: commands/copy.c:1363 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "« COPY force null » n'est disponible qu'en utilisant COPY FROM" -#: commands/copy.c:1348 +#: commands/copy.c:1369 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "le délimiteur COPY ne doit pas apparaître dans la spécification de NULL" -#: commands/copy.c:1355 +#: commands/copy.c:1376 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "le caractère guillemet de CSV ne doit pas apparaître dans la spécification de NULL" -#: commands/copy.c:1416 +#: commands/copy.c:1437 #, c-format msgid "table \"%s\" does not have OIDs" msgstr "la table « %s » n'a pas d'OID" -#: commands/copy.c:1486 +#: commands/copy.c:1454 #, c-format msgid "COPY (query) WITH OIDS is not supported" msgstr "COPY (requête) WITH OIDS n'est pas supporté" -#: commands/copy.c:1507 +#: commands/copy.c:1475 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "les règles DO INSTEAD NOTHING ne sont pas supportées par l'instruction COPY" -#: commands/copy.c:1521 +#: commands/copy.c:1489 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "les règles DO INSTEAD conditionnelles ne sont pas supportées par l'instruction COPY" -#: commands/copy.c:1525 +#: commands/copy.c:1493 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "les règles DO ALSO ne sont pas supportées par l'instruction COPY" -#: commands/copy.c:1530 +#: commands/copy.c:1498 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "les règles DO INSTEAD multi-instructions ne sont pas supportées par l'instruction COPY" -#: commands/copy.c:1540 +#: commands/copy.c:1508 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) n'est pas supporté" -#: commands/copy.c:1557 +#: commands/copy.c:1525 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "La requête COPY doit avoir une clause RETURNING" -#: commands/copy.c:1585 +#: commands/copy.c:1553 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "la relation référencée par l'instruction COPY a changé" -#: commands/copy.c:1643 +#: commands/copy.c:1612 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "la colonne « %s » FORCE_QUOTE n'est pas référencée par COPY" -#: commands/copy.c:1665 +#: commands/copy.c:1635 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "la colonne « %s » FORCE_NOT_NULL n'est pas référencée par COPY" -#: commands/copy.c:1687 +#: commands/copy.c:1658 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "colonne « %s » FORCE_NULL non référencée par COPY" -#: commands/copy.c:1752 +#: commands/copy.c:1724 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "n'a pas pu fermer le fichier pipe vers la commande externe : %m" -#: commands/copy.c:1756 +#: commands/copy.c:1739 #, c-format msgid "program \"%s\" failed" msgstr "le programme « %s » a échoué" -#: commands/copy.c:1806 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from view \"%s\"" msgstr "ne peut pas copier à partir de la vue « %s »" -#: commands/copy.c:1808 commands/copy.c:1814 commands/copy.c:1820 commands/copy.c:1831 +#: commands/copy.c:1792 commands/copy.c:1798 commands/copy.c:1804 commands/copy.c:1815 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Tentez la variante COPY (SELECT ...) TO." -#: commands/copy.c:1812 +#: commands/copy.c:1796 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "ne peut pas copier à partir de la vue matérialisée « %s »" -#: commands/copy.c:1818 +#: commands/copy.c:1802 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "ne peut pas copier à partir de la table distante « %s »" -#: commands/copy.c:1824 +#: commands/copy.c:1808 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "ne peut pas copier à partir de la séquence « %s »" -#: commands/copy.c:1829 +#: commands/copy.c:1813 #, c-format msgid "cannot copy from partitioned table \"%s\"" msgstr "ne peut pas copier à partir de la table partitionnée « %s »" -#: commands/copy.c:1835 +#: commands/copy.c:1819 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "ne peut pas copier à partir de la relation « %s », qui n'est pas une table" -#: commands/copy.c:1875 +#: commands/copy.c:1859 #, c-format msgid "relative path not allowed for COPY to file" msgstr "un chemin relatif n'est pas autorisé à utiliser COPY vers un fichier" -#: commands/copy.c:1887 +#: commands/copy.c:1880 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "n'a pas pu ouvrir le fichier « %s » en écriture : %m" -#: commands/copy.c:1890 +#: commands/copy.c:1883 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY TO indique au serveur PostgreSQL d'écrire un fichier. Vous pourriez vouloir utiliser la fonctionnalité \\copy de psql pour écrire en local." -#: commands/copy.c:1903 commands/copy.c:3133 +#: commands/copy.c:1896 commands/copy.c:3212 #, c-format msgid "\"%s\" is a directory" msgstr "« %s » est un répertoire" -#: commands/copy.c:2226 +#: commands/copy.c:2222 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, ligne %d, colonne %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, ligne %s, colonne %s" -#: commands/copy.c:2230 commands/copy.c:2277 +#: commands/copy.c:2226 commands/copy.c:2273 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, ligne %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, ligne %s" -#: commands/copy.c:2241 +#: commands/copy.c:2237 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, ligne %d, colonne %s : « %s »" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, ligne %s, colonne %s : « %s »" -#: commands/copy.c:2249 +#: commands/copy.c:2245 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, ligne %d, colonne %s : NULL en entrée" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, ligne %s, colonne %s : NULL en entrée" -#: commands/copy.c:2271 +#: commands/copy.c:2267 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, ligne %d : « %s »" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, ligne %s : « %s »" -#: commands/copy.c:2365 +#: commands/copy.c:2363 #, c-format msgid "cannot copy to view \"%s\"" msgstr "ne peut pas copier vers la vue « %s »" -#: commands/copy.c:2367 +#: commands/copy.c:2365 #, c-format msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." msgstr "Pour activer la copie d'une vue, fournissez un trigger INSTEAD OF INSERT." -#: commands/copy.c:2371 +#: commands/copy.c:2369 #, c-format msgid "cannot copy to materialized view \"%s\"" msgstr "ne peut pas copier vers la vue matérialisée « %s »" -#: commands/copy.c:2376 -#, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "ne peut pas copier vers la table distante « %s »" - -#: commands/copy.c:2381 +#: commands/copy.c:2374 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "ne peut pas copier vers la séquence « %s »" -#: commands/copy.c:2386 +#: commands/copy.c:2379 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "ne peut pas copier vers une relation « %s » qui n'est pas une table" -#: commands/copy.c:2449 +#: commands/copy.c:2471 +#, c-format +msgid "cannot perform FREEZE on a partitioned table" +msgstr "ne peut pas exécuter FREEZE sur une table partitionnée" + +#: commands/copy.c:2486 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" msgstr "n'a pas pu exécuter un FREEZE à cause d'une activité transactionnelle précédente" -#: commands/copy.c:2455 +#: commands/copy.c:2492 #, c-format msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" msgstr "n'a pas pu exécuter un FREEZE parce que la table n'était pas créée ou tronquée dans la transaction en cours" -#: commands/copy.c:2618 executor/nodeModifyTable.c:311 -#, c-format -msgid "cannot route inserted tuples to a foreign table" -msgstr "ne peut pas envoyer les lignes insérées dans une table distante" - -#: commands/copy.c:3120 +#: commands/copy.c:3199 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY TO indique au serveur PostgreSQL de lire un fichier. Vous pourriez vouloir utiliser la fonctionnalité \\copy de psql pour lire en local." -#: commands/copy.c:3153 +#: commands/copy.c:3232 #, c-format msgid "COPY file signature not recognized" msgstr "la signature du fichier COPY n'est pas reconnue" -#: commands/copy.c:3158 +#: commands/copy.c:3237 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "en-tête du fichier COPY invalide (options manquantes)" -#: commands/copy.c:3164 +#: commands/copy.c:3243 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "options critiques non reconnues dans l'en-tête du fichier COPY" -#: commands/copy.c:3170 +#: commands/copy.c:3249 #, c-format msgid "invalid COPY file header (missing length)" msgstr "en-tête du fichier COPY invalide (longueur manquante)" -#: commands/copy.c:3177 +#: commands/copy.c:3256 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "en-tête du fichier COPY invalide (mauvaise longueur)" -#: commands/copy.c:3310 commands/copy.c:4017 commands/copy.c:4247 +#: commands/copy.c:3387 commands/copy.c:4096 commands/copy.c:4326 #, c-format msgid "extra data after last expected column" msgstr "données supplémentaires après la dernière colonne attendue" -#: commands/copy.c:3320 +#: commands/copy.c:3397 #, c-format msgid "missing data for OID column" msgstr "données manquantes pour la colonne OID" -#: commands/copy.c:3326 +#: commands/copy.c:3403 #, c-format msgid "null OID in COPY data" msgstr "OID NULL dans les données du COPY" -#: commands/copy.c:3336 commands/copy.c:3459 +#: commands/copy.c:3413 commands/copy.c:3537 #, c-format msgid "invalid OID in COPY data" msgstr "OID invalide dans les données du COPY" -#: commands/copy.c:3351 +#: commands/copy.c:3429 #, c-format msgid "missing data for column \"%s\"" msgstr "données manquantes pour la colonne « %s »" -#: commands/copy.c:3434 +#: commands/copy.c:3512 #, c-format msgid "received copy data after EOF marker" msgstr "a reçu des données de COPY après le marqueur de fin" -#: commands/copy.c:3441 +#: commands/copy.c:3519 #, c-format msgid "row field count is %d, expected %d" msgstr "le nombre de champs de la ligne est %d, %d attendus" -#: commands/copy.c:3781 commands/copy.c:3798 +#: commands/copy.c:3860 commands/copy.c:3877 #, c-format msgid "literal carriage return found in data" msgstr "retour chariot trouvé dans les données" -#: commands/copy.c:3782 commands/copy.c:3799 +#: commands/copy.c:3861 commands/copy.c:3878 #, c-format msgid "unquoted carriage return found in data" msgstr "retour chariot sans guillemet trouvé dans les données" -#: commands/copy.c:3784 commands/copy.c:3801 +#: commands/copy.c:3863 commands/copy.c:3880 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "Utilisez « \\r » pour représenter un retour chariot." -#: commands/copy.c:3785 commands/copy.c:3802 +#: commands/copy.c:3864 commands/copy.c:3881 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "Utiliser le champ CSV entre guillemets pour représenter un retour chariot." -#: commands/copy.c:3814 +#: commands/copy.c:3893 #, c-format msgid "literal newline found in data" msgstr "retour à la ligne trouvé dans les données" -#: commands/copy.c:3815 +#: commands/copy.c:3894 #, c-format msgid "unquoted newline found in data" msgstr "retour à la ligne trouvé dans les données" -#: commands/copy.c:3817 +#: commands/copy.c:3896 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "Utilisez « \\n » pour représenter un retour à la ligne." -#: commands/copy.c:3818 +#: commands/copy.c:3897 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "Utiliser un champ CSV entre guillemets pour représenter un retour à la ligne." -#: commands/copy.c:3864 commands/copy.c:3900 +#: commands/copy.c:3943 commands/copy.c:3979 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "le marqueur fin-de-copie ne correspond pas à un précédent style de fin de ligne" -#: commands/copy.c:3873 commands/copy.c:3889 +#: commands/copy.c:3952 commands/copy.c:3968 #, c-format msgid "end-of-copy marker corrupt" msgstr "marqueur fin-de-copie corrompu" -#: commands/copy.c:4331 +#: commands/copy.c:4410 #, c-format msgid "unterminated CSV quoted field" msgstr "champ CSV entre guillemets non terminé" -#: commands/copy.c:4408 commands/copy.c:4427 +#: commands/copy.c:4487 commands/copy.c:4506 #, c-format msgid "unexpected EOF in COPY data" msgstr "fin de fichier (EOF) inattendu dans les données du COPY" -#: commands/copy.c:4417 +#: commands/copy.c:4496 #, c-format msgid "invalid field size" msgstr "taille du champ invalide" -#: commands/copy.c:4440 +#: commands/copy.c:4519 #, c-format msgid "incorrect binary data format" msgstr "format de données binaires incorrect" -#: commands/copy.c:4751 commands/indexcmds.c:1070 commands/tablecmds.c:1685 commands/tablecmds.c:2187 commands/tablecmds.c:2613 parser/parse_relation.c:3249 parser/parse_relation.c:3269 utils/adt/tsvector_op.c:2561 +#: commands/copy.c:4831 commands/indexcmds.c:1472 commands/statscmds.c:206 commands/tablecmds.c:1910 commands/tablecmds.c:2467 commands/tablecmds.c:2848 parser/parse_relation.c:3288 parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" msgstr "la colonne « %s » n'existe pas" -#: commands/copy.c:4758 commands/tablecmds.c:1711 commands/tablecmds.c:2213 commands/trigger.c:800 parser/parse_target.c:1018 parser/parse_target.c:1029 +#: commands/copy.c:4838 commands/tablecmds.c:1937 commands/trigger.c:913 parser/parse_target.c:1046 parser/parse_target.c:1057 #, c-format msgid "column \"%s\" specified more than once" msgstr "la colonne « %s » est spécifiée plus d'une fois" @@ -5896,7 +6098,7 @@ msgstr "%d n'est pas un code d'encodage valide" msgid "%s is not a valid encoding name" msgstr "%s n'est pas un nom d'encodage valide" -#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 commands/user.c:641 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 commands/user.c:664 #, c-format msgid "invalid connection limit: %d" msgstr "limite de connexion invalide : %d" @@ -6032,10 +6234,10 @@ msgstr "la base de données « %s » est utilisée par un slot de réplication l #: commands/dbcommands.c:860 #, c-format -msgid "There is %d active slot" -msgid_plural "There are %d active slots" -msgstr[0] "Il existe %d slot actif" -msgstr[1] "Il existe %d slots actifs" +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "Il existe %d slot actif." +msgstr[1] "Il existe %d slots actifs." #: commands/dbcommands.c:874 commands/dbcommands.c:1038 commands/dbcommands.c:1168 #, c-format @@ -6083,7 +6285,7 @@ msgstr "" "Vous devez d'abord les déplacer dans le tablespace par défaut de la base\n" "de données avant d'utiliser cette commande." -#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 commands/dbcommands.c:2104 commands/dbcommands.c:2159 commands/tablespace.c:604 +#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 commands/dbcommands.c:2104 commands/dbcommands.c:2159 commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "" @@ -6159,27 +6361,27 @@ msgstr "l'argument de %s doit être un nom de type" msgid "invalid argument for %s: \"%s\"" msgstr "argument invalide pour %s : « %s »" -#: commands/dropcmds.c:104 commands/functioncmds.c:1201 utils/adt/ruleutils.c:2452 +#: commands/dropcmds.c:99 commands/functioncmds.c:1212 utils/adt/ruleutils.c:2563 #, c-format msgid "\"%s\" is an aggregate function" msgstr "« %s » est une fonction d'agrégat" -#: commands/dropcmds.c:106 +#: commands/dropcmds.c:101 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Utiliser DROP AGGREGATE pour supprimer les fonctions d'agrégat." -#: commands/dropcmds.c:157 commands/sequence.c:442 commands/tablecmds.c:2697 commands/tablecmds.c:2848 commands/tablecmds.c:2891 commands/tablecmds.c:12449 tcop/utility.c:1168 +#: commands/dropcmds.c:157 commands/sequence.c:440 commands/tablecmds.c:2932 commands/tablecmds.c:3090 commands/tablecmds.c:3133 commands/tablecmds.c:13433 tcop/utility.c:1163 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "la relation « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:896 +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1022 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "le schéma « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:252 +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "le type « %s » n'existe pas, poursuite du traitement" @@ -6242,161 +6444,171 @@ msgstr "la fonction %s(%s) n'existe pas, poursuite du traitement" #: commands/dropcmds.c:348 #, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "La procédure %s(%s) n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:361 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "la routine %s(%s) n'existe pas, poursuite du traitement" + +#: commands/dropcmds.c:374 +#, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "L'agrégat %s(%s) n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:361 +#: commands/dropcmds.c:387 #, c-format msgid "operator %s does not exist, skipping" msgstr "l'opérateur %s n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:367 +#: commands/dropcmds.c:393 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "le langage « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:376 +#: commands/dropcmds.c:402 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "la conversion du type %s vers le type %s n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:385 +#: commands/dropcmds.c:411 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "la transformation pour le type %s et le langage « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:393 +#: commands/dropcmds.c:419 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr "le trigger « %s » de la relation « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:402 +#: commands/dropcmds.c:428 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr "la politique « %s » de la relation « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:409 +#: commands/dropcmds.c:435 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "le trigger sur événement « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:415 +#: commands/dropcmds.c:441 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr "la règle « %s » de la relation « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:422 +#: commands/dropcmds.c:448 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "le wrapper de données distantes « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:426 +#: commands/dropcmds.c:452 #, c-format msgid "server \"%s\" does not exist, skipping" msgstr "le serveur « %s » n'existe pas, poursuite du traitement" -#: commands/dropcmds.c:435 +#: commands/dropcmds.c:461 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" msgstr "la classe d'opérateur « %s » n'existe pas pour la méthode d'accès « %s », ignoré" -#: commands/dropcmds.c:447 +#: commands/dropcmds.c:473 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" msgstr "la famille d'opérateur « %s » n'existe pas pour la méthode d'accès « %s », ignoré" -#: commands/dropcmds.c:454 +#: commands/dropcmds.c:480 #, c-format msgid "publication \"%s\" does not exist, skipping" msgstr "la publication « %s » n'existe pas, poursuite du traitement" -#: commands/event_trigger.c:185 +#: commands/event_trigger.c:187 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "droit refusé pour créer le trigger sur événement « %s »" -#: commands/event_trigger.c:187 +#: commands/event_trigger.c:189 #, c-format msgid "Must be superuser to create an event trigger." msgstr "Doit être super-utilisateur pour créer un trigger sur événement." -#: commands/event_trigger.c:196 +#: commands/event_trigger.c:198 #, c-format msgid "unrecognized event name \"%s\"" msgstr "nom d'événement non reconnu : « %s »" -#: commands/event_trigger.c:213 +#: commands/event_trigger.c:215 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "variable « %s » du filtre non reconnu" -#: commands/event_trigger.c:268 +#: commands/event_trigger.c:270 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "valeur de filtre « %s » non reconnu pour la variable de filtre « %s »" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:274 commands/event_trigger.c:344 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format msgid "event triggers are not supported for %s" msgstr "les triggers sur événemenr ne sont pas supportés pour %s" -#: commands/event_trigger.c:367 +#: commands/event_trigger.c:369 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "variable « %s » du filtre spécifiée plus d'une fois" -#: commands/event_trigger.c:514 commands/event_trigger.c:557 commands/event_trigger.c:649 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 commands/event_trigger.c:651 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "le trigger sur événement « %s » n'existe pas" -#: commands/event_trigger.c:618 +#: commands/event_trigger.c:620 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "droit refusé pour modifier le propriétaire du trigger sur événement « %s »" -#: commands/event_trigger.c:620 +#: commands/event_trigger.c:622 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "Le propriétaire du trigger sur événement doit être un super-utilisateur." -#: commands/event_trigger.c:1464 +#: commands/event_trigger.c:1457 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement sql_drop" -#: commands/event_trigger.c:1584 commands/event_trigger.c:1605 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement table_rewrite" -#: commands/event_trigger.c:2015 +#: commands/event_trigger.c:2009 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s peut seulement être appelé dans une fonction de trigger sur événement" -#: commands/explain.c:194 +#: commands/explain.c:192 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "valeur non reconnue pour l'option EXPLAIN « %s » : %s" -#: commands/explain.c:201 +#: commands/explain.c:199 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "option EXPLAIN « %s » non reconnu" -#: commands/explain.c:209 +#: commands/explain.c:207 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "l'option BUFFERS d'EXPLAIN nécessite ANALYZE" -#: commands/explain.c:218 +#: commands/explain.c:216 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "l'option TIMING d'EXPLAIN nécessite ANALYZE" -#: commands/extension.c:168 commands/extension.c:2907 +#: commands/extension.c:168 commands/extension.c:2914 #, c-format msgid "extension \"%s\" does not exist" msgstr "l'extension « %s » n'existe pas" @@ -6517,7 +6729,7 @@ msgstr "Doit être super-utilisateur pour mettre à jour cette extension." msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "l'extension « %s » n'a pas de chemin de mise à jour pour aller de la version « %s » à la version « %s »" -#: commands/extension.c:1304 commands/extension.c:2968 +#: commands/extension.c:1304 commands/extension.c:2975 #, c-format msgid "version to install must be specified" msgstr "la version à installer doit être précisée" @@ -6537,103 +6749,103 @@ msgstr "l'extension « %s » n'a pas de script d'installation ou de chemin de de msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "l'extension « %s » doit être installée dans le schéma « %s »" -#: commands/extension.c:1579 +#: commands/extension.c:1586 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "dépendance cyclique détectée entre les extensions « %s » et « %s »" -#: commands/extension.c:1584 +#: commands/extension.c:1591 #, c-format msgid "installing required extension \"%s\"" msgstr "installation de l'extension requise « %s »" -#: commands/extension.c:1608 +#: commands/extension.c:1615 #, c-format msgid "required extension \"%s\" is not installed" msgstr "l'extension « %s » requise n'est pas installée" -#: commands/extension.c:1611 +#: commands/extension.c:1618 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "Utilisez CREATE EXTENSION ... CASCADE pour installer également les extensions requises." -#: commands/extension.c:1648 +#: commands/extension.c:1655 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "l'extension « %s » existe déjà, poursuite du traitement" -#: commands/extension.c:1655 +#: commands/extension.c:1662 #, c-format msgid "extension \"%s\" already exists" msgstr "l'extension « %s » existe déjà" -#: commands/extension.c:1666 +#: commands/extension.c:1673 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "CREATE EXTENSION imbriqué n'est pas supporté" -#: commands/extension.c:1847 +#: commands/extension.c:1854 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "ne peut pas supprimer l'extension « %s » car il est en cours de modification" -#: commands/extension.c:2349 +#: commands/extension.c:2356 #, c-format msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" msgstr "" "pg_extension_config_dump() peut seulement être appelé à partir d'un script SQL\n" "exécuté par CREATE EXTENSION" -#: commands/extension.c:2361 +#: commands/extension.c:2368 #, c-format msgid "OID %u does not refer to a table" msgstr "l'OID %u ne fait pas référence à une table" -#: commands/extension.c:2366 +#: commands/extension.c:2373 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "la table « %s » n'est pas un membre de l'extension en cours de création" -#: commands/extension.c:2722 +#: commands/extension.c:2729 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "" "ne peut pas déplacer l'extension « %s » dans le schéma « %s » car l'extension\n" "contient le schéma" -#: commands/extension.c:2763 commands/extension.c:2826 +#: commands/extension.c:2770 commands/extension.c:2833 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "l'extension « %s » ne supporte pas SET SCHEMA" -#: commands/extension.c:2828 +#: commands/extension.c:2835 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "%s n'est pas dans le schéma « %s » de l'extension" -#: commands/extension.c:2887 +#: commands/extension.c:2894 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "un ALTER EXTENSION imbriqué n'est pas supporté" -#: commands/extension.c:2979 +#: commands/extension.c:2986 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "la version « %s » de l'extension « %s » est déjà installée" -#: commands/extension.c:3230 +#: commands/extension.c:3237 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "" "ne peut pas ajouter le schéma « %s » à l'extension « %s » car le schéma\n" "contient l'extension" -#: commands/extension.c:3258 +#: commands/extension.c:3265 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s n'est pas un membre de l'extension « %s »" -#: commands/extension.c:3324 +#: commands/extension.c:3331 #, c-format msgid "file \"%s\" is too large" msgstr "le fichier « %s » est trop gros" @@ -6719,784 +6931,886 @@ msgstr "la correspondance utilisateur « %s » existe déjà pour le serveur « msgid "user mapping for \"%s\" already exists for server %s" msgstr "la correspondance utilisateur « %s » existe déjà pour le serveur « %s »" -#: commands/foreigncmds.c:1278 commands/foreigncmds.c:1393 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 #, c-format msgid "user mapping for \"%s\" does not exist for the server" msgstr "la correspondance utilisateur « %s » n'existe pas pour le serveur" -#: commands/foreigncmds.c:1380 +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" msgstr "le serveur n'existe pas, poursuite du traitement" -#: commands/foreigncmds.c:1398 +#: commands/foreigncmds.c:1402 #, c-format msgid "user mapping for \"%s\" does not exist for the server, skipping" msgstr "" "la correspondance utilisateur « %s » n'existe pas pour le serveur, poursuite\n" "du traitement" -#: commands/foreigncmds.c:1549 foreign/foreign.c:357 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "le wrapper de données distantes « %s » n'a pas de gestionnaire" -#: commands/foreigncmds.c:1555 +#: commands/foreigncmds.c:1559 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "le wrapper de données distantes « %s » ne supporte pas IMPORT FOREIGN SCHEMA" -#: commands/foreigncmds.c:1658 +#: commands/foreigncmds.c:1662 #, c-format msgid "importing foreign table \"%s\"" msgstr "import de la table distante « %s »" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:104 #, c-format msgid "SQL function cannot return shell type %s" msgstr "la fonction SQL ne peut pas retourner le type shell %s" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:109 #, c-format msgid "return type %s is only a shell" msgstr "le type de retour %s est seulement un shell" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:139 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "le modificateur de type ne peut pas être précisé pour le type shell « %s »" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:145 #, c-format msgid "type \"%s\" is not yet defined" msgstr "le type « %s » n'est pas encore défini" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:146 #, c-format msgid "Creating a shell type definition." msgstr "Création d'une définition d'un type shell." -#: commands/functioncmds.c:233 +#: commands/functioncmds.c:238 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "la fonction SQL ne peut pas accepter le type shell %s" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:244 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "l'agrégat ne peut pas accepter le type shell %s" -#: commands/functioncmds.c:244 +#: commands/functioncmds.c:249 #, c-format msgid "argument type %s is only a shell" msgstr "le type d'argument %s est seulement un shell" -#: commands/functioncmds.c:254 +#: commands/functioncmds.c:259 #, c-format msgid "type %s does not exist" msgstr "le type %s n'existe pas" -#: commands/functioncmds.c:268 +#: commands/functioncmds.c:273 #, c-format msgid "aggregates cannot accept set arguments" msgstr "les agrégats ne peuvent pas utiliser des arguments d'ensemble" -#: commands/functioncmds.c:272 +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "les procédures ne peuvent pas utiliser des arguments d'ensemble" + +#: commands/functioncmds.c:281 #, c-format msgid "functions cannot accept set arguments" msgstr "les fonctions ne peuvent pas accepter des arguments d'ensemble" -#: commands/functioncmds.c:282 +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "les procédures ne peuvent pas avoir d'argument OUT" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "les arguments INOUT ne sont pas autorisés." + +#: commands/functioncmds.c:300 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "le paramètre VARIADIC doit être le dernier paramètre en entrée" -#: commands/functioncmds.c:310 +#: commands/functioncmds.c:330 #, c-format msgid "VARIADIC parameter must be an array" msgstr "le paramètre VARIADIC doit être un tableau" -#: commands/functioncmds.c:350 +#: commands/functioncmds.c:370 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "le nom du paramètre « %s » est utilisé plus d'une fois" -#: commands/functioncmds.c:365 +#: commands/functioncmds.c:385 #, c-format msgid "only input parameters can have default values" msgstr "seuls les paramètres en entrée peuvent avoir des valeurs par défaut" -#: commands/functioncmds.c:380 +#: commands/functioncmds.c:400 #, c-format msgid "cannot use table references in parameter default value" msgstr "" "ne peut pas utiliser les références de tables dans la valeur par défaut des\n" "paramètres" -#: commands/functioncmds.c:404 +#: commands/functioncmds.c:424 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "les paramètres en entrée suivant un paramètre avec valeur par défaut doivent aussi avoir des valeurs par défaut" -#: commands/functioncmds.c:700 +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "attribute invalide dans la définition de la procédure" + +#: commands/functioncmds.c:747 #, c-format msgid "no function body specified" msgstr "aucun corps de fonction spécifié" -#: commands/functioncmds.c:710 +#: commands/functioncmds.c:757 #, c-format msgid "no language specified" msgstr "aucun langage spécifié" -#: commands/functioncmds.c:735 commands/functioncmds.c:1242 +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 #, c-format msgid "COST must be positive" msgstr "COST doit être positif" -#: commands/functioncmds.c:743 commands/functioncmds.c:1250 +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 #, c-format msgid "ROWS must be positive" msgstr "ROWS doit être positif" -#: commands/functioncmds.c:784 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "l'attribut « %s » non reconnu de la fonction a été ignoré" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:842 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "seul un élément AS est nécessaire pour le langage « %s »" -#: commands/functioncmds.c:930 commands/functioncmds.c:2131 commands/proclang.c:561 +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "le langage « %s » n'existe pas" -#: commands/functioncmds.c:932 commands/functioncmds.c:2133 +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "Utiliser CREATE LANGUAGE pour charger le langage dans la base de données." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Utiliser CREATE EXTENSION pour charger le langage dans la base de données." -#: commands/functioncmds.c:967 commands/functioncmds.c:1234 +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 #, c-format msgid "only superuser can define a leakproof function" msgstr "seul un superutilisateur peut définir une fonction leakproof" -#: commands/functioncmds.c:1010 +#: commands/functioncmds.c:1023 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "le type de résultat de la fonction doit être %s à cause des paramètres OUT" -#: commands/functioncmds.c:1023 +#: commands/functioncmds.c:1036 #, c-format msgid "function result type must be specified" msgstr "le type de résultat de la fonction doit être spécifié" -#: commands/functioncmds.c:1077 commands/functioncmds.c:1254 +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "ROWS n'est pas applicable quand la fonction ne renvoie pas un ensemble" -#: commands/functioncmds.c:1426 +#: commands/functioncmds.c:1440 #, c-format msgid "source data type %s is a pseudo-type" msgstr "le type de données source %s est un pseudo-type" -#: commands/functioncmds.c:1432 +#: commands/functioncmds.c:1446 #, c-format msgid "target data type %s is a pseudo-type" msgstr "le type de données cible %s est un pseudo-type" -#: commands/functioncmds.c:1456 +#: commands/functioncmds.c:1470 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "la conversion sera ignorée car le type de données source est un domaine" -#: commands/functioncmds.c:1461 +#: commands/functioncmds.c:1475 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "la conversion sera ignorée car le type de données cible est un domaine" -#: commands/functioncmds.c:1486 +#: commands/functioncmds.c:1500 #, c-format msgid "cast function must take one to three arguments" msgstr "la fonction de conversion doit prendre de un à trois arguments" -#: commands/functioncmds.c:1490 +#: commands/functioncmds.c:1504 #, c-format msgid "argument of cast function must match or be binary-coercible from source data type" msgstr "" "l'argument de la fonction de conversion doit correspondre ou être binary-coercible\n" "à partir du type de la donnée source" -#: commands/functioncmds.c:1494 +#: commands/functioncmds.c:1508 #, c-format msgid "second argument of cast function must be type %s" msgstr "le second argument de la fonction de conversion doit être de type %s" -#: commands/functioncmds.c:1499 +#: commands/functioncmds.c:1513 #, c-format msgid "third argument of cast function must be type %s" msgstr "le troisième argument de la fonction de conversion doit être de type %s" -#: commands/functioncmds.c:1504 +#: commands/functioncmds.c:1518 #, c-format msgid "return data type of cast function must match or be binary-coercible to target data type" msgstr "" "le type de donnée en retour de la fonction de conversion doit correspondre\n" "ou être coercible binairement au type de données cible" -#: commands/functioncmds.c:1515 +#: commands/functioncmds.c:1529 #, c-format msgid "cast function must not be volatile" msgstr "la fonction de conversion ne doit pas être volatile" -#: commands/functioncmds.c:1520 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "la fonction de conversion ne doit pas être une fonction d'agrégat" - -#: commands/functioncmds.c:1524 +#: commands/functioncmds.c:1534 #, c-format -msgid "cast function must not be a window function" -msgstr "la fonction de conversion ne doit pas être une fonction window" +msgid "cast function must be a normal function" +msgstr "la fonction de conversion doit être une fonction normale" -#: commands/functioncmds.c:1528 +#: commands/functioncmds.c:1538 #, c-format msgid "cast function must not return a set" msgstr "la fonction de conversion ne doit pas renvoyer un ensemble" -#: commands/functioncmds.c:1554 +#: commands/functioncmds.c:1564 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "doit être super-utilisateur pour créer une fonction de conversion SANS FONCTION" -#: commands/functioncmds.c:1569 +#: commands/functioncmds.c:1579 #, c-format msgid "source and target data types are not physically compatible" msgstr "les types de données source et cible ne sont pas physiquement compatibles" -#: commands/functioncmds.c:1584 +#: commands/functioncmds.c:1594 #, c-format msgid "composite data types are not binary-compatible" msgstr "les types de données composites ne sont pas compatibles binairement" -#: commands/functioncmds.c:1590 +#: commands/functioncmds.c:1600 #, c-format msgid "enum data types are not binary-compatible" msgstr "les types de données enum ne sont pas compatibles binairement" -#: commands/functioncmds.c:1596 +#: commands/functioncmds.c:1606 #, c-format msgid "array data types are not binary-compatible" msgstr "les types de données tableau ne sont pas compatibles binairement" -#: commands/functioncmds.c:1613 +#: commands/functioncmds.c:1623 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "les types de données domaines ne sont pas compatibles binairement" -#: commands/functioncmds.c:1623 +#: commands/functioncmds.c:1633 #, c-format msgid "source data type and target data type are the same" msgstr "les types de données source et cible sont identiques" -#: commands/functioncmds.c:1656 +#: commands/functioncmds.c:1666 #, c-format msgid "cast from type %s to type %s already exists" msgstr "la conversion du type %s vers le type %s existe déjà" -#: commands/functioncmds.c:1729 +#: commands/functioncmds.c:1739 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "la conversion du type %s vers le type %s n'existe pas" -#: commands/functioncmds.c:1768 +#: commands/functioncmds.c:1778 #, c-format msgid "transform function must not be volatile" msgstr "la fonction de transformation ne doit pas être volatile" -#: commands/functioncmds.c:1772 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "la fonction de transformation ne doit pas être une fonction d'agrégat" - -#: commands/functioncmds.c:1776 +#: commands/functioncmds.c:1782 #, c-format -msgid "transform function must not be a window function" -msgstr "la fonction de transformation ne doit pas être une fonction window" +msgid "transform function must be a normal function" +msgstr "la fonction de transformation doit être une fonction normale" -#: commands/functioncmds.c:1780 +#: commands/functioncmds.c:1786 #, c-format msgid "transform function must not return a set" msgstr "la fonction de transformation ne doit pas renvoyer un ensemble" -#: commands/functioncmds.c:1784 +#: commands/functioncmds.c:1790 #, c-format msgid "transform function must take one argument" msgstr "la fonction de transformation doit prendre de un argument" -#: commands/functioncmds.c:1788 +#: commands/functioncmds.c:1794 #, c-format msgid "first argument of transform function must be type %s" msgstr "le premier argument de la fonction de transformation doit être de type %s" -#: commands/functioncmds.c:1826 +#: commands/functioncmds.c:1832 #, c-format msgid "data type %s is a pseudo-type" msgstr "le type de données %s est un pseudo-type" -#: commands/functioncmds.c:1832 +#: commands/functioncmds.c:1838 #, c-format msgid "data type %s is a domain" msgstr "le type de données %s est un domaine" -#: commands/functioncmds.c:1872 +#: commands/functioncmds.c:1878 #, c-format msgid "return data type of FROM SQL function must be %s" msgstr "le type de donnée en retour de la fonction FROM SQL doit être %s" -#: commands/functioncmds.c:1898 +#: commands/functioncmds.c:1904 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "le type de donnée en retour de la fonction TO SQL doit être du type de données de la transformation" -#: commands/functioncmds.c:1925 +#: commands/functioncmds.c:1931 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "la transformation pour le type %s et le langage « %s » existe déjà" -#: commands/functioncmds.c:2014 +#: commands/functioncmds.c:2020 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "la transformation pour le type %s et le langage « %s » n'existe pas" -#: commands/functioncmds.c:2065 +#: commands/functioncmds.c:2071 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "la fonction %s existe déjà dans le schéma « %s »" -#: commands/functioncmds.c:2118 +#: commands/functioncmds.c:2126 #, c-format msgid "no inline code specified" msgstr "aucun code en ligne spécifié" -#: commands/functioncmds.c:2163 +#: commands/functioncmds.c:2172 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "le langage « %s » ne supporte pas l'exécution de code en ligne" -#: commands/indexcmds.c:354 +#: commands/functioncmds.c:2284 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "ne peut pas passer plus de %d argument à une procédure" +msgstr[1] "ne peut pas passer plus de %d arguments à une procédure" + +#: commands/indexcmds.c:393 #, c-format msgid "must specify at least one column" msgstr "doit spécifier au moins une colonne" -#: commands/indexcmds.c:358 +#: commands/indexcmds.c:397 #, c-format msgid "cannot use more than %d columns in an index" msgstr "ne peut pas utiliser plus de %d colonnes dans un index" -#: commands/indexcmds.c:389 +#: commands/indexcmds.c:437 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "ne peut pas créer un index sur la table distante « %s »" -#: commands/indexcmds.c:394 +#: commands/indexcmds.c:462 #, c-format -msgid "cannot create index on partitioned table \"%s\"" -msgstr "ne peut pas créer un index sur la table partitionnée « %s »" +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "ne peut pas créer un index sur la table partitionnée « %s » de manière concurrente" + +#: commands/indexcmds.c:467 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "ne peut pas créer de contraintes d'exclusion sur la table partitionnée « %s »" -#: commands/indexcmds.c:409 +#: commands/indexcmds.c:477 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "ne peut pas créer les index sur les tables temporaires des autres sessions" -#: commands/indexcmds.c:474 commands/tablecmds.c:593 commands/tablecmds.c:10493 +#: commands/indexcmds.c:542 commands/tablecmds.c:617 commands/tablecmds.c:11454 commands/tablecmds.c:11588 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "seules les relations partagées peuvent être placées dans le tablespace pg_global" -#: commands/indexcmds.c:507 +#: commands/indexcmds.c:575 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "substitution de la méthode d'accès obsolète « rtree » par « gist » " -#: commands/indexcmds.c:525 +#: commands/indexcmds.c:593 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "la méthode d'accès « %s » ne supporte pas les index uniques" -#: commands/indexcmds.c:530 +#: commands/indexcmds.c:598 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "la méthode d'accès « %s » ne supporte pas les colonnes incluses" + +#: commands/indexcmds.c:603 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "la méthode d'accès « %s » ne supporte pas les index multi-colonnes" -#: commands/indexcmds.c:535 +#: commands/indexcmds.c:608 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "la méthode d'accès « %s » ne supporte pas les contraintes d'exclusion" -#: commands/indexcmds.c:607 commands/indexcmds.c:627 +#: commands/indexcmds.c:720 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "contrainte %s non supporée avec la définition de clé de partitionnement" + +#: commands/indexcmds.c:722 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "les contraints %s ne peuvent pas être utilisées les clés de partitionnement incluent des expression." + +#: commands/indexcmds.c:740 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "colonnes infuffisantes dans la définition de contrainte de %s" + +#: commands/indexcmds.c:742 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "la contrainte %s sur la table « %s » ne contient pas la colonne « %s » qui fait partie de la clé de partitionnement." + +#: commands/indexcmds.c:761 commands/indexcmds.c:781 #, c-format msgid "index creation on system columns is not supported" msgstr "la création d'un index sur les tables du catalogue système n'est pas supportée" -#: commands/indexcmds.c:652 +#: commands/indexcmds.c:806 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s créera un index implicite « %s » pour la table « %s »" -#: commands/indexcmds.c:999 +#: commands/indexcmds.c:1401 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "les fonctions dans un prédicat d'index doivent être marquées comme IMMUTABLE" -#: commands/indexcmds.c:1065 parser/parse_utilcmd.c:2076 +#: commands/indexcmds.c:1467 parser/parse_utilcmd.c:2237 parser/parse_utilcmd.c:2361 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "la colonne « %s » nommée dans la clé n'existe pas" -#: commands/indexcmds.c:1125 +#: commands/indexcmds.c:1491 parser/parse_utilcmd.c:1586 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "les expressions ne sont pas supportées dans les colonnes incluses" + +#: commands/indexcmds.c:1532 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "" "les fonctions dans l'expression de l'index doivent être marquées comme\n" "IMMUTABLE" -#: commands/indexcmds.c:1148 +#: commands/indexcmds.c:1547 +#, c-format +msgid "including column does not support a collation" +msgstr "une colonne incluse ne supporte pas de collationnement" + +#: commands/indexcmds.c:1551 +#, c-format +msgid "including column does not support an operator class" +msgstr "une colonne incluse ne supporte pas de classe d'opérateur" + +#: commands/indexcmds.c:1555 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "une colonne incluse ne supporte pas d'options ASC/DESC" + +#: commands/indexcmds.c:1559 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "une colonne incluse ne supporte pas d'options NULLS FIRST/LAST" + +#: commands/indexcmds.c:1586 #, c-format msgid "could not determine which collation to use for index expression" msgstr "n'a pas pu déterminer le collationnement à utiliser pour l'expression d'index" -#: commands/indexcmds.c:1156 commands/tablecmds.c:13383 commands/typecmds.c:831 parser/parse_expr.c:2763 parser/parse_type.c:549 parser/parse_utilcmd.c:3112 utils/adt/misc.c:661 +#: commands/indexcmds.c:1594 commands/tablecmds.c:14388 commands/typecmds.c:833 parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3392 utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "les collationnements ne sont pas supportés par le type %s" -#: commands/indexcmds.c:1194 +#: commands/indexcmds.c:1632 #, c-format msgid "operator %s is not commutative" msgstr "l'opérateur %s n'est pas commutatif" -#: commands/indexcmds.c:1196 +#: commands/indexcmds.c:1634 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "Seuls les opérateurs commutatifs peuvent être utilisés dans les contraintes d'exclusion." -#: commands/indexcmds.c:1222 +#: commands/indexcmds.c:1660 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "l'opérateur %s n'est pas un membre de la famille d'opérateur « %s »" -#: commands/indexcmds.c:1225 +#: commands/indexcmds.c:1663 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "" "L'opérateur d'exclusion doit être en relation avec la classe d'opérateur de\n" "l'index pour la contrainte." -#: commands/indexcmds.c:1260 +#: commands/indexcmds.c:1698 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "la méthode d'accès « %s » ne supporte pas les options ASC/DESC" -#: commands/indexcmds.c:1265 +#: commands/indexcmds.c:1703 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "la méthode d'accès « %s » ne supporte pas les options NULLS FIRST/LAST" -#: commands/indexcmds.c:1324 commands/typecmds.c:1928 +#: commands/indexcmds.c:1762 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "" "le type de données %s n'a pas de classe d'opérateurs par défaut pour la\n" "méthode d'accès « %s »" -#: commands/indexcmds.c:1326 +#: commands/indexcmds.c:1764 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "" "Vous devez spécifier une classe d'opérateur pour l'index ou définir une\n" "classe d'opérateur par défaut pour le type de données." -#: commands/indexcmds.c:1355 commands/indexcmds.c:1363 commands/opclasscmds.c:205 +#: commands/indexcmds.c:1793 commands/indexcmds.c:1801 commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "la classe d'opérateur « %s » n'existe pas pour la méthode d'accès « %s »" -#: commands/indexcmds.c:1376 commands/typecmds.c:1916 +#: commands/indexcmds.c:1814 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "la classe d'opérateur « %s » n'accepte pas le type de données %s" -#: commands/indexcmds.c:1466 +#: commands/indexcmds.c:1904 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "" "il existe de nombreuses classes d'opérateur par défaut pour le type de\n" "données %s" -#: commands/indexcmds.c:1857 +#: commands/indexcmds.c:2319 #, c-format msgid "table \"%s\" has no indexes" msgstr "la table « %s » n'a pas d'index" -#: commands/indexcmds.c:1912 +#: commands/indexcmds.c:2374 #, c-format msgid "can only reindex the currently open database" msgstr "peut seulement réindexer la base de données en cours" -#: commands/indexcmds.c:2012 +#: commands/indexcmds.c:2492 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "la table « %s.%s » a été réindexée" -#: commands/matview.c:181 +#: commands/indexcmds.c:2514 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX n'est pas implémenté pour des index partitionnés" + +#: commands/lockcmds.c:102 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "« %s » n'est pas une table ou une vue" + +#: commands/lockcmds.c:234 rewrite/rewriteHandler.c:1942 rewrite/rewriteHandler.c:3669 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "récursion infinie détectée dans les règles de la relation « %s »" + +#: commands/matview.c:179 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" msgstr "CONCURRENTLY ne peut pas être utilisé quand la vue matérialisée n'est pas peuplée" -#: commands/matview.c:187 +#: commands/matview.c:185 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "Les options CONCURRENTLY et WITH NO DATA ne peuvent pas être utilisées ensemble" -#: commands/matview.c:257 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "ne peut pas rafraichir en parallèle la vue matérialisée « %s »" -#: commands/matview.c:260 +#: commands/matview.c:247 #, c-format msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." msgstr "Crée un index unique sans clause WHERE sur une ou plusieurs colonnes de la vue matérialisée." -#: commands/matview.c:678 +#: commands/matview.c:645 #, c-format msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" msgstr "les nouvelles données pour la vue matérialisée « %s » contiennent des lignes dupliquées sans colonnes NULL" -#: commands/matview.c:680 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "Ligne : %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "la famille d'opérateur « %s » n'existe pas pour la méthode d'accès « %s »" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "la famille d'opérateur « %s » existe déjà pour la méthode d'accès « %s »" -#: commands/opclasscmds.c:402 +#: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" msgstr "doit être super-utilisateur pour créer une classe d'opérateur" -#: commands/opclasscmds.c:475 commands/opclasscmds.c:849 commands/opclasscmds.c:973 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "numéro d'opérateur %d invalide, doit être compris entre 1 et %d" -#: commands/opclasscmds.c:519 commands/opclasscmds.c:893 commands/opclasscmds.c:988 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "numéro de procédure %d invalide, doit être compris entre 1 et %d" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "numéro de fonction %d invalide, doit être compris entre 1 et %d" -#: commands/opclasscmds.c:548 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "type de stockage spécifié plus d'une fois" -#: commands/opclasscmds.c:575 +#: commands/opclasscmds.c:576 #, c-format msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "" "le type de stockage ne peut pas être différent du type de données pour la\n" "méthode d'accès « %s »" -#: commands/opclasscmds.c:591 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "la classe d'opérateur « %s » existe déjà pour la méthode d'accès « %s »" -#: commands/opclasscmds.c:619 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "n'a pas pu rendre la classe d'opérateur « %s » par défaut pour le type %s" -#: commands/opclasscmds.c:622 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "La classe d'opérateur « %s » est déjà la classe par défaut." -#: commands/opclasscmds.c:747 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" msgstr "doit être super-utilisateur pour créer une famille d'opérateur" -#: commands/opclasscmds.c:803 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" msgstr "doit être super-utilisateur pour modifier une famille d'opérateur" -#: commands/opclasscmds.c:858 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "" "les types d'argument de l'opérateur doivent être indiqués dans ALTER\n" "OPERATOR FAMILY" -#: commands/opclasscmds.c:921 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "STORAGE ne peut pas être spécifié dans ALTER OPERATOR FAMILY" -#: commands/opclasscmds.c:1043 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" msgstr "un ou deux types d'argument doit être spécifié" -#: commands/opclasscmds.c:1069 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "les opérateurs d'index doivent être binaires" -#: commands/opclasscmds.c:1088 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "la méthode d'accès « %s » ne supporte pas les opérateurs de tri" -#: commands/opclasscmds.c:1099 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" msgstr "les opérateurs de recherche d'index doivent renvoyer un booléen" -#: commands/opclasscmds.c:1141 +#: commands/opclasscmds.c:1144 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "les fonctions de comparaison btree doivent avoir deux arguments" + +#: commands/opclasscmds.c:1148 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "les fonctions de comparaison btree doivent renvoyer un entier" + +#: commands/opclasscmds.c:1165 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "les fonctions de support de tri btree doivent accepter le type « internal »" + +#: commands/opclasscmds.c:1169 +#, c-format +msgid "btree sort support functions must return void" +msgstr "les fonctions de support de tri btree doivent renvoyer void" + +#: commands/opclasscmds.c:1180 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "les procédures de comparaison btree doivent avoir deux arguments" +msgid "btree in_range functions must have five arguments" +msgstr "les fonctions in_range btree doivent avoir cinq arguments" -#: commands/opclasscmds.c:1145 +#: commands/opclasscmds.c:1184 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "les procédures de comparaison btree doivent renvoyer un entier" +msgid "btree in_range functions must return boolean" +msgstr "les fonctions in_range btree doivent doivent retourner un booléen" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1203 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "les procédures de support de tri btree doivent accepter le type « internal »" +msgid "hash function 1 must have one argument" +msgstr "la fonctions de hashage 1 doit avoir un argument" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1207 #, c-format -msgid "btree sort support procedures must return void" -msgstr "les procédures de support de tri btree doivent renvoyer void" +msgid "hash function 1 must return integer" +msgstr "la fonctions de hashage 1 doit retourner un integer" -#: commands/opclasscmds.c:1178 +#: commands/opclasscmds.c:1214 #, c-format -msgid "hash procedures must have one argument" -msgstr "les procédures de hachage doivent avoir un argument" +msgid "hash function 2 must have two arguments" +msgstr "la fonctions de hashage 1 doit avoir deux argument" -#: commands/opclasscmds.c:1182 +#: commands/opclasscmds.c:1218 #, c-format -msgid "hash procedures must return integer" -msgstr "les procédures de hachage doivent renvoyer un entier" +msgid "hash function 2 must return bigint" +msgstr "la fonctions de hashage 2 doit retourner un bigint" -#: commands/opclasscmds.c:1206 +#: commands/opclasscmds.c:1243 #, c-format -msgid "associated data types must be specified for index support procedure" +msgid "associated data types must be specified for index support function" msgstr "" -"les types de données associés doivent être indiqués pour la procédure de\n" +"les types de données associés doivent être indiqués pour la fonction de\n" "support de l'index" -#: commands/opclasscmds.c:1231 +#: commands/opclasscmds.c:1268 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "le numéro de procédure %d pour (%s, %s) apparaît plus d'une fois" +msgid "function number %d for (%s,%s) appears more than once" +msgstr "le numéro de fonction %d pour (%s, %s) apparaît plus d'une fois" -#: commands/opclasscmds.c:1238 +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "le numéro d'opérateur %d pour (%s, %s) apparaît plus d'une fois" -#: commands/opclasscmds.c:1287 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "l'opérateur %d(%s, %s) existe déjà dans la famille d'opérateur « %s »" -#: commands/opclasscmds.c:1401 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "la fonction %d(%s, %s) existe déjà dans la famille d'opérateur « %s »" -#: commands/opclasscmds.c:1489 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "l'opérateur %d(%s, %s) n'existe pas dans la famille d'opérateur « %s »" -#: commands/opclasscmds.c:1529 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "la fonction %d(%s, %s) n'existe pas dans la famille d'opérateur « %s »" -#: commands/opclasscmds.c:1659 +#: commands/opclasscmds.c:1696 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "" "la classe d'opérateur « %s » de la méthode d'accès « %s » existe déjà dans\n" "le schéma « %s »" -#: commands/opclasscmds.c:1682 +#: commands/opclasscmds.c:1719 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "" "la famille d'opérateur « %s » de la méthode d'accès « %s » existe déjà dans\n" "le schéma « %s »" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "type SETOF non autorisé pour l'argument de l'opérateur" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:454 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "l'attribut « %s » de l'opérateur n'est pas reconnu" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "la procédure de l'opérateur doit être spécifiée" +msgid "operator function must be specified" +msgstr "la fonction d'opérateur doit être spécifiée" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "au moins un des arguments (le gauche ou le droit) doit être spécifié" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "" "la fonction d'estimation de la restriction, de nom %s, doit renvoyer le type\n" "%s" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "" "la fonction d'estimation de la jointure, de nom %s, doit renvoyer le type\n" "%s" -#: commands/operatorcmds.c:448 +#: commands/operatorcmds.c:451 #, c-format msgid "operator attribute \"%s\" cannot be changed" msgstr "l'attribut « %s » de l'opérateur ne peut pas être changé" -#: commands/policy.c:87 commands/policy.c:397 commands/policy.c:487 commands/tablecmds.c:1150 commands/tablecmds.c:1520 commands/tablecmds.c:2507 commands/tablecmds.c:4704 commands/tablecmds.c:7041 commands/tablecmds.c:13006 commands/tablecmds.c:13041 commands/trigger.c:253 commands/trigger.c:1294 commands/trigger.c:1403 rewrite/rewriteDefine.c:272 rewrite/rewriteDefine.c:925 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 commands/tablecmds.c:1278 commands/tablecmds.c:1755 commands/tablecmds.c:2742 commands/tablecmds.c:4995 commands/tablecmds.c:7403 commands/tablecmds.c:14021 commands/tablecmds.c:14056 commands/trigger.c:316 commands/trigger.c:1526 commands/trigger.c:1635 rewrite/rewriteDefine.c:272 rewrite/rewriteDefine.c:924 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "droit refusé : « %s » est un catalogue système" @@ -7511,32 +7825,32 @@ msgstr "ingore les rôles spécifiés autre que PUBLIC" msgid "All roles are members of the PUBLIC role." msgstr "Tous les rôles sont membres du rôle PUBLIC." -#: commands/policy.c:511 +#: commands/policy.c:514 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "le rôle « %s » n'a pas pu être supprimé de la politique « %s » sur « %s »" -#: commands/policy.c:717 +#: commands/policy.c:720 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK ne peut pas être appliqué à SELECT et DELETE" -#: commands/policy.c:726 commands/policy.c:1024 +#: commands/policy.c:729 commands/policy.c:1027 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "seule une expression WITH CHECK est autorisée pour INSERT" -#: commands/policy.c:799 commands/policy.c:1244 +#: commands/policy.c:802 commands/policy.c:1247 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "la politique « %s » pour la table « %s » existe déjà" -#: commands/policy.c:996 commands/policy.c:1272 commands/policy.c:1344 +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "la politique « %s » pour la table « %s » n'existe pas" -#: commands/policy.c:1014 +#: commands/policy.c:1017 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "seule une expression USING est autorisée pour SELECT, DELETE" @@ -7546,7 +7860,7 @@ msgstr "seule une expression USING est autorisée pour SELECT, DELETE" msgid "invalid cursor name: must not be empty" msgstr "nom de curseur invalide : il ne doit pas être vide" -#: commands/portalcmds.c:190 commands/portalcmds.c:244 executor/execCurrent.c:67 utils/adt/xml.c:2469 utils/adt/xml.c:2639 +#: commands/portalcmds.c:190 commands/portalcmds.c:244 executor/execCurrent.c:69 utils/adt/xml.c:2577 utils/adt/xml.c:2747 #, c-format msgid "cursor \"%s\" does not exist" msgstr "le curseur « %s » n'existe pas" @@ -7556,7 +7870,7 @@ msgstr "le curseur « %s » n'existe pas" msgid "invalid statement name: must not be empty" msgstr "nom de l'instruction invalide : ne doit pas être vide" -#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1349 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1399 #, c-format msgid "could not determine data type of parameter $%d" msgstr "n'a pas pu déterminer le type de données du paramètre $%d" @@ -7588,89 +7902,89 @@ msgstr "" "le paramètre $%d de type %s ne peut être utilisé dans la coercion à cause du\n" "type %s attendu" -#: commands/prepare.c:474 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "l'instruction préparée « %s » existe déjà" -#: commands/prepare.c:513 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "l'instruction préparée « %s » n'existe pas" -#: commands/proclang.c:87 +#: commands/proclang.c:86 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "" "utilisation des informations de pg_pltemplate au lieu des paramètres de\n" "CREATE LANGUAGE" -#: commands/proclang.c:97 +#: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "doit être super-utilisateur pour créer le langage de procédures « %s »" -#: commands/proclang.c:252 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "langage non supporté « %s »" -#: commands/proclang.c:254 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "Les langages supportés sont listés dans le catalogue système pg_pltemplate." -#: commands/proclang.c:262 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" msgstr "doit être super-utilisateur pour créer un langage de procédures personnalisé" -#: commands/proclang.c:281 commands/trigger.c:582 commands/typecmds.c:457 commands/typecmds.c:474 +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 commands/typecmds.c:471 #, c-format msgid "changing return type of function %s from %s to %s" msgstr "changement du type de retour de la fonction %s de %s vers %s" -#: commands/publicationcmds.c:106 +#: commands/publicationcmds.c:109 #, c-format -msgid "invalid publish list" -msgstr "liste de publication invalide" +msgid "invalid list syntax for \"publish\" option" +msgstr "syntaxe de liste invalide pour l'option « publish »" -#: commands/publicationcmds.c:122 +#: commands/publicationcmds.c:127 #, c-format msgid "unrecognized \"publish\" value: \"%s\"" msgstr "type « publish » non reconnu : « %s »" -#: commands/publicationcmds.c:128 +#: commands/publicationcmds.c:133 #, c-format msgid "unrecognized publication parameter: %s" msgstr "paramètre de publication non reconnu : %s" -#: commands/publicationcmds.c:160 +#: commands/publicationcmds.c:166 #, c-format msgid "must be superuser to create FOR ALL TABLES publication" msgstr "doit être super-utilisateur pour créer une publication « FOR ALL TABLES »" -#: commands/publicationcmds.c:321 +#: commands/publicationcmds.c:335 #, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES" msgstr "la publication « %s » est définie avec FOR ALL TABLES" -#: commands/publicationcmds.c:323 +#: commands/publicationcmds.c:337 #, c-format msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." msgstr "Les tables ne peuvent pas être ajoutées ou supprimées à des publications FOR ALL TABLES." -#: commands/publicationcmds.c:624 +#: commands/publicationcmds.c:638 #, c-format msgid "relation \"%s\" is not part of the publication" msgstr "la relation « %s » ne fait pas partie de la publication" -#: commands/publicationcmds.c:667 +#: commands/publicationcmds.c:681 #, c-format msgid "permission denied to change owner of publication \"%s\"" msgstr "droit refusé pour modifier le propriétaire de la publication « %s »" -#: commands/publicationcmds.c:669 +#: commands/publicationcmds.c:683 #, c-format msgid "The owner of a FOR ALL TABLES publication must be a superuser." msgstr "Le propriétaire d'une publication FOR ALL TABLES doit être un super-utilisateur." @@ -7710,186 +8024,181 @@ msgstr "le fournisseur « %s » de label de sécurité n'est pas chargé" msgid "unlogged sequences are not supported" msgstr "les séquences non tracées ne sont pas supportées" -#: commands/sequence.c:699 +#: commands/sequence.c:697 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval : valeur maximale de la séquence « %s » (%s) atteinte" -#: commands/sequence.c:722 +#: commands/sequence.c:720 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval : valeur minimale de la séquence « %s » (%s) atteinte" -#: commands/sequence.c:840 +#: commands/sequence.c:838 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "" "la valeur courante (currval) de la séquence « %s » n'est pas encore définie\n" "dans cette session" -#: commands/sequence.c:859 commands/sequence.c:865 +#: commands/sequence.c:857 commands/sequence.c:863 #, c-format msgid "lastval is not yet defined in this session" msgstr "la dernière valeur (lastval) n'est pas encore définie dans cette session" -#: commands/sequence.c:953 +#: commands/sequence.c:951 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval : la valeur %s est en dehors des limites de la séquence « %s » (%s..%s)" -#: commands/sequence.c:1358 +#: commands/sequence.c:1348 #, c-format msgid "invalid sequence option SEQUENCE NAME" msgstr "option SEQUENCE NAME invalide" -#: commands/sequence.c:1384 +#: commands/sequence.c:1374 #, c-format msgid "identity column type must be smallint, integer, or bigint" msgstr "le type de colonne identité doit être smallint, integer ou bigint" -#: commands/sequence.c:1385 +#: commands/sequence.c:1375 #, c-format msgid "sequence type must be smallint, integer, or bigint" msgstr "le type de séquence doit être smallint, integer ou bigint" -#: commands/sequence.c:1419 +#: commands/sequence.c:1409 #, c-format msgid "INCREMENT must not be zero" msgstr "la valeur INCREMENT ne doit pas être zéro" -#: commands/sequence.c:1472 +#: commands/sequence.c:1462 #, c-format msgid "MAXVALUE (%s) is out of range for sequence data type %s" msgstr "MAXVALUE (%s) est hors des limites pour le type de données séquence %s" -#: commands/sequence.c:1509 +#: commands/sequence.c:1499 #, c-format msgid "MINVALUE (%s) is out of range for sequence data type %s" msgstr "MINVALUE (%s) est hors des limites pour le type de données séquence %s" -#: commands/sequence.c:1523 +#: commands/sequence.c:1513 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "la valeur MINVALUE (%s) doit être moindre que la valeur MAXVALUE (%s)" -#: commands/sequence.c:1550 +#: commands/sequence.c:1540 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "la valeur START (%s) ne peut pas être plus petite que celle de MINVALUE (%s)" -#: commands/sequence.c:1562 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "la valeur START (%s) ne peut pas être plus grande que celle de MAXVALUE (%s)" -#: commands/sequence.c:1592 +#: commands/sequence.c:1582 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "la valeur RESTART (%s) ne peut pas être plus petite que celle de MINVALUE (%s)" -#: commands/sequence.c:1604 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "la valeur RESTART (%s) ne peut pas être plus grande que celle de MAXVALUE (%s)" -#: commands/sequence.c:1619 +#: commands/sequence.c:1609 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "la valeur CACHE (%s) doit être plus grande que zéro" -#: commands/sequence.c:1656 +#: commands/sequence.c:1646 #, c-format msgid "invalid OWNED BY option" msgstr "option OWNED BY invalide" -#: commands/sequence.c:1657 +#: commands/sequence.c:1647 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "Indiquer OWNED BY table.colonne ou OWNED BY NONE." -#: commands/sequence.c:1682 +#: commands/sequence.c:1672 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "la relation référencée « %s » n'est ni une table ni une table distante" -#: commands/sequence.c:1689 +#: commands/sequence.c:1679 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "la séquence doit avoir le même propriétaire que la table avec laquelle elle est liée" -#: commands/sequence.c:1693 +#: commands/sequence.c:1683 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "la séquence doit être dans le même schéma que la table avec laquelle elle est liée" -#: commands/sequence.c:1715 +#: commands/sequence.c:1705 #, c-format msgid "cannot change ownership of identity sequence" msgstr "ne peut pas modifier le propriétaire de la séquence d'identité" -#: commands/sequence.c:1716 commands/tablecmds.c:9875 commands/tablecmds.c:12469 +#: commands/sequence.c:1706 commands/tablecmds.c:10836 commands/tablecmds.c:13453 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "La séquence « %s » est liée à la table « %s »." -#: commands/statscmds.c:93 -#, c-format -msgid "statistics object \"%s\" already exists, skipping" -msgstr "l'objet statistique « %s » existe déjà, poursuite du traitement" - -#: commands/statscmds.c:100 -#, c-format -msgid "statistics object \"%s\" already exists" -msgstr "l'objet statistique « %s » existe déjà" - -#: commands/statscmds.c:112 commands/statscmds.c:121 +#: commands/statscmds.c:93 commands/statscmds.c:102 #, c-format msgid "only a single relation is allowed in CREATE STATISTICS" msgstr "seule une relation seule est acceptée dans CREATE STATISTICS" -#: commands/statscmds.c:139 +#: commands/statscmds.c:120 #, c-format msgid "relation \"%s\" is not a table, foreign table, or materialized view" msgstr "la relation « %s » n'est pas une table, une table distante ou une vue matérialisée" -#: commands/statscmds.c:170 commands/statscmds.c:176 +#: commands/statscmds.c:163 #, c-format -msgid "only simple column references are allowed in CREATE STATISTICS" -msgstr "seules des références à une seule colonne sont acceptées dans CREATE STATISTICS" +msgid "statistics object \"%s\" already exists, skipping" +msgstr "l'objet statistique « %s » existe déjà, poursuite du traitement" -#: commands/statscmds.c:183 +#: commands/statscmds.c:171 #, c-format -msgid "column \"%s\" referenced in statistics does not exist" -msgstr "la colonne « %s » référencée dans les statistiques n'existe pas" +msgid "statistics object \"%s\" already exists" +msgstr "l'objet statistique « %s » existe déjà" -#: commands/statscmds.c:191 +#: commands/statscmds.c:193 commands/statscmds.c:199 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "seules des références à une seule colonne sont acceptées dans CREATE STATISTICS" + +#: commands/statscmds.c:214 #, c-format msgid "statistics creation on system columns is not supported" msgstr "la création de statistiques sur les colonnes systèmes n'est pas supportée" -#: commands/statscmds.c:198 +#: commands/statscmds.c:221 #, c-format -msgid "column \"%s\" cannot be used in statistics because its type has no default btree operator class" -msgstr "la colonne « %s » ne peut pas être utilisé dans des statistiques parce que son type n'a pas de classe d'opérateur btree par défaut" +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "la colonne « %s » ne peut pas être utilisé dans des statistiques parce que son type %s n'a pas de classe d'opérateur btree par défaut" -#: commands/statscmds.c:205 +#: commands/statscmds.c:228 #, c-format msgid "cannot have more than %d columns in statistics" msgstr "ne peut pas avoir plus de %d colonnes dans des statistiques" -#: commands/statscmds.c:220 +#: commands/statscmds.c:243 #, c-format msgid "extended statistics require at least 2 columns" msgstr "les statistiques étendues requièrent au moins 2 colonnes" -#: commands/statscmds.c:238 +#: commands/statscmds.c:261 #, c-format msgid "duplicate column name in statistics definition" msgstr "nom de colonne dupliqué dans la définition des statistiques" -#: commands/statscmds.c:266 +#: commands/statscmds.c:289 #, c-format -msgid "unrecognized statistic type \"%s\"" +msgid "unrecognized statistics kind \"%s\"" msgstr "type de statistique « %s » non reconnu" #: commands/subscriptioncmds.c:187 @@ -7932,7 +8241,7 @@ msgstr "la souscription avec slot_name = NONE doit aussi être configurée avec msgid "subscription with slot_name = NONE must also set create_slot = false" msgstr "la souscription avec slot_name = NONE doit aussi être configurée avec create_slot = false" -#: commands/subscriptioncmds.c:284 +#: commands/subscriptioncmds.c:283 #, c-format msgid "publication name \"%s\" used more than once" msgstr "nom de publication « %s » utilisé plus d'une fois" @@ -7942,7 +8251,7 @@ msgstr "nom de publication « %s » utilisé plus d'une fois" msgid "must be superuser to create subscriptions" msgstr "doit être super-utilisateur pour créer des souscriptions" -#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 replication/logical/tablesync.c:856 replication/logical/worker.c:1616 +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 replication/logical/tablesync.c:856 replication/logical/worker.c:1722 #, c-format msgid "could not connect to the publisher: %s" msgstr "n'a pas pu se connecter au publieur : %s" @@ -7959,388 +8268,393 @@ msgstr "les tables n'étaient pas souscrites, vous devrez exécuter ALTER SUBSCR #: commands/subscriptioncmds.c:576 #, c-format -msgid "added subscription for table %s.%s" -msgstr "souscription ajoutée pour la table %s.%s" +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "table « %s.%s » ajoutée à la souscription « %s »" -#: commands/subscriptioncmds.c:604 +#: commands/subscriptioncmds.c:600 #, c-format -msgid "removed subscription for table %s.%s" -msgstr "a supprimé une souscription pour la table %s.%s" +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "table « %s.%s » supprimée de la souscription « %s »" -#: commands/subscriptioncmds.c:672 +#: commands/subscriptioncmds.c:669 #, c-format msgid "cannot set slot_name = NONE for enabled subscription" msgstr "ne peut pas configurer slot_name = NONE pour la souscription activée" -#: commands/subscriptioncmds.c:706 +#: commands/subscriptioncmds.c:703 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "ne peut pas activer une souscription qui n'a pas de nom de slot" -#: commands/subscriptioncmds.c:752 +#: commands/subscriptioncmds.c:749 #, c-format msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION avec rafraichissement n'est pas autorisé pour les souscriptions désactivées" -#: commands/subscriptioncmds.c:753 +#: commands/subscriptioncmds.c:750 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." msgstr "Utilisez ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:771 +#: commands/subscriptioncmds.c:768 #, c-format msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION ... REFRESH n'est pas autorisé pour les souscriptions désactivées" -#: commands/subscriptioncmds.c:848 +#: commands/subscriptioncmds.c:847 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "la souscription « %s » n'existe pas, poursuite du traitement" -#: commands/subscriptioncmds.c:949 +#: commands/subscriptioncmds.c:972 #, c-format msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" msgstr "n'a pas pu se connecter au publieur pour supprimer le slot de réplication « %s »" -#: commands/subscriptioncmds.c:951 commands/subscriptioncmds.c:965 replication/logical/tablesync.c:906 replication/logical/tablesync.c:928 +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 #, c-format msgid "The error was: %s" msgstr "L'erreur était : %s" -#: commands/subscriptioncmds.c:952 +#: commands/subscriptioncmds.c:975 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." msgstr "Utilisez ALTER SUBSCRIPTION ... SET (slot_name = NONE) pour dissocier la souscription du slot." -#: commands/subscriptioncmds.c:963 +#: commands/subscriptioncmds.c:986 #, c-format msgid "could not drop the replication slot \"%s\" on publisher" msgstr "n'a pas pu supprimer le slot de réplication « %s » sur le publieur" -#: commands/subscriptioncmds.c:968 +#: commands/subscriptioncmds.c:991 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "slot de réplication « %s » supprimé sur le publieur" -#: commands/subscriptioncmds.c:1009 +#: commands/subscriptioncmds.c:1032 #, c-format msgid "permission denied to change owner of subscription \"%s\"" msgstr "droit refusé pour modifier le propriétaire de la souscription « %s »" -#: commands/subscriptioncmds.c:1011 +#: commands/subscriptioncmds.c:1034 #, c-format msgid "The owner of a subscription must be a superuser." msgstr "Le propriétaire d'une souscription doit être un super-utilisateur." -#: commands/subscriptioncmds.c:1124 +#: commands/subscriptioncmds.c:1147 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "n'a pas pu recevoir la liste des tables répliquées à partir du publieur : %s" -#: commands/tablecmds.c:221 commands/tablecmds.c:263 +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist" msgstr "la table « %s » n'existe pas" -#: commands/tablecmds.c:222 commands/tablecmds.c:264 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 #, c-format msgid "table \"%s\" does not exist, skipping" msgstr "la table « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#: commands/tablecmds.c:226 commands/tablecmds.c:268 msgid "Use DROP TABLE to remove a table." msgstr "Utilisez DROP TABLE pour supprimer une table." -#: commands/tablecmds.c:227 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist" msgstr "la séquence « %s » n'existe pas" -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:230 #, c-format msgid "sequence \"%s\" does not exist, skipping" msgstr "la séquence « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:230 +#: commands/tablecmds.c:232 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "Utilisez DROP SEQUENCE pour supprimer une séquence." -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist" msgstr "la vue « %s » n'existe pas" -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:236 #, c-format msgid "view \"%s\" does not exist, skipping" msgstr "la vue « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:236 +#: commands/tablecmds.c:238 msgid "Use DROP VIEW to remove a view." msgstr "Utilisez DROP VIEW pour supprimer une vue." -#: commands/tablecmds.c:239 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "la vue matérialisée « %s » n'existe pas" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:242 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "la vue matérialisée « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Utilisez DROP MATERIALIZED VIEW pour supprimer une vue matérialisée." -#: commands/tablecmds.c:245 parser/parse_utilcmd.c:1828 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:15458 parser/parse_utilcmd.c:1982 #, c-format msgid "index \"%s\" does not exist" msgstr "l'index « %s » n'existe pas" -#: commands/tablecmds.c:246 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "l'index « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "Utilisez DROP INDEX pour supprimer un index." -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" msgstr "« %s » n'est pas un type" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "Utilisez DROP TYPE pour supprimer un type." -#: commands/tablecmds.c:257 commands/tablecmds.c:9391 commands/tablecmds.c:12249 +#: commands/tablecmds.c:259 commands/tablecmds.c:10280 commands/tablecmds.c:13233 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "la table distante « %s » n'existe pas" -#: commands/tablecmds.c:258 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "la table distante « %s » n'existe pas, poursuite du traitement" -#: commands/tablecmds.c:260 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Utilisez DROP FOREIGN TABLE pour supprimer une table distante." -#: commands/tablecmds.c:533 +#: commands/tablecmds.c:557 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT peut seulement être utilisé sur des tables temporaires" -#: commands/tablecmds.c:561 +#: commands/tablecmds.c:585 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "" "ne peut pas créer une table temporaire à l'intérieur d'une fonction\n" "restreinte pour sécurité" -#: commands/tablecmds.c:662 +#: commands/tablecmds.c:686 #, c-format msgid "cannot create table with OIDs as partition of table without OIDs" msgstr "ne peut pas créer une table avec OID comme partition d'une table sans OID" -#: commands/tablecmds.c:783 parser/parse_utilcmd.c:3279 +#: commands/tablecmds.c:810 #, c-format msgid "\"%s\" is not partitioned" msgstr "« %s » n'est pas partitionné" -#: commands/tablecmds.c:831 +#: commands/tablecmds.c:891 #, c-format msgid "cannot partition using more than %d columns" msgstr "ne peut pas partitionner en utilisant plus de %d colonnes" -#: commands/tablecmds.c:972 +#: commands/tablecmds.c:1098 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY ne permet pas de supprimer plusieurs objets" -#: commands/tablecmds.c:976 +#: commands/tablecmds.c:1102 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY ne permet pas la CASCADE" -#: commands/tablecmds.c:1253 +#: commands/tablecmds.c:1401 #, c-format msgid "cannot truncate only a partitioned table" msgstr "ne peut pas seulement tronquer une table partitionnée" -#: commands/tablecmds.c:1254 +#: commands/tablecmds.c:1402 #, c-format -msgid "Do not specify the ONLY keyword, or use truncate only on the partitions directly." +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." msgstr "Ne spécifiez pas le mot clé ONLY ou utilisez TRUNCATE ONLY directement sur les partitions." -#: commands/tablecmds.c:1282 +#: commands/tablecmds.c:1471 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "TRUNCATE cascade sur la table « %s »" -#: commands/tablecmds.c:1530 +#: commands/tablecmds.c:1765 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "ne peut pas tronquer les tables temporaires des autres sessions" -#: commands/tablecmds.c:1761 commands/tablecmds.c:10976 +#: commands/tablecmds.c:2006 commands/tablecmds.c:11984 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "ne peut pas hériter de la table partitionnée « %s »" -#: commands/tablecmds.c:1766 +#: commands/tablecmds.c:2011 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "ne peut pas hériter de la partition « %s »" -#: commands/tablecmds.c:1774 parser/parse_utilcmd.c:2039 +#: commands/tablecmds.c:2019 parser/parse_utilcmd.c:2199 parser/parse_utilcmd.c:2322 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "la relation héritée « %s » n'est ni une table ni une table distante" -#: commands/tablecmds.c:1782 commands/tablecmds.c:10955 +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "ne peut pas créer une relation temporaire comme partition de la relation permanente « %s »" + +#: commands/tablecmds.c:2040 commands/tablecmds.c:11963 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "ine peut pas hériter à partir d'une relation temporaire « %s »" -#: commands/tablecmds.c:1792 commands/tablecmds.c:10963 +#: commands/tablecmds.c:2050 commands/tablecmds.c:11971 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "ne peut pas hériter de la table temporaire d'une autre session" -#: commands/tablecmds.c:1809 commands/tablecmds.c:11087 +#: commands/tablecmds.c:2067 commands/tablecmds.c:12095 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "la relation « %s » serait héritée plus d'une fois" -#: commands/tablecmds.c:1857 +#: commands/tablecmds.c:2116 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "assemblage de plusieurs définitions d'héritage pour la colonne « %s »" -#: commands/tablecmds.c:1865 +#: commands/tablecmds.c:2124 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "la colonne héritée « %s » a un conflit de type" -#: commands/tablecmds.c:1867 commands/tablecmds.c:1890 commands/tablecmds.c:2096 commands/tablecmds.c:2126 parser/parse_coerce.c:1650 parser/parse_coerce.c:1670 parser/parse_coerce.c:1690 parser/parse_coerce.c:1736 parser/parse_coerce.c:1775 parser/parse_param.c:218 +#: commands/tablecmds.c:2126 commands/tablecmds.c:2149 commands/tablecmds.c:2354 commands/tablecmds.c:2384 parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s versus %s" -#: commands/tablecmds.c:1876 +#: commands/tablecmds.c:2135 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "la colonne héritée « %s » a un conflit sur le collationnement" -#: commands/tablecmds.c:1878 commands/tablecmds.c:2108 commands/tablecmds.c:5149 +#: commands/tablecmds.c:2137 commands/tablecmds.c:2366 commands/tablecmds.c:5455 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "« %s » versus « %s »" -#: commands/tablecmds.c:1888 +#: commands/tablecmds.c:2147 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "la colonne héritée « %s » a un conflit de paramètre de stockage" -#: commands/tablecmds.c:2002 commands/tablecmds.c:8881 parser/parse_utilcmd.c:1122 parser/parse_utilcmd.c:1473 parser/parse_utilcmd.c:1549 +#: commands/tablecmds.c:2260 commands/tablecmds.c:9708 parser/parse_utilcmd.c:1116 parser/parse_utilcmd.c:1515 parser/parse_utilcmd.c:1622 #, c-format msgid "cannot convert whole-row table reference" msgstr "ne peut pas convertir une référence de ligne complète de table" -#: commands/tablecmds.c:2003 parser/parse_utilcmd.c:1123 +#: commands/tablecmds.c:2261 parser/parse_utilcmd.c:1117 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "La constrainte « %s » contient une référence de ligne complète vers la table « %s »." -#: commands/tablecmds.c:2082 +#: commands/tablecmds.c:2340 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "assemblage de la colonne « %s » avec une définition héritée" -#: commands/tablecmds.c:2086 +#: commands/tablecmds.c:2344 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "déplacement et assemblage de la colonne « %s » avec une définition héritée" -#: commands/tablecmds.c:2087 +#: commands/tablecmds.c:2345 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "Colonne utilisateur déplacée à la position de la colonne héritée." -#: commands/tablecmds.c:2094 +#: commands/tablecmds.c:2352 #, c-format msgid "column \"%s\" has a type conflict" msgstr "la colonne « %s » a un conflit de type" -#: commands/tablecmds.c:2106 +#: commands/tablecmds.c:2364 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "la colonne « %s » a un conflit sur le collationnement" -#: commands/tablecmds.c:2124 +#: commands/tablecmds.c:2382 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "la colonne « %s » a un conflit de paramètre de stockage" -#: commands/tablecmds.c:2235 +#: commands/tablecmds.c:2485 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "la colonne « %s » hérite de valeurs par défaut conflictuelles" -#: commands/tablecmds.c:2237 +#: commands/tablecmds.c:2487 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Pour résoudre le conflit, spécifiez explicitement une valeur par défaut." -#: commands/tablecmds.c:2284 +#: commands/tablecmds.c:2534 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "" "le nom de la contrainte de vérification, « %s », apparaît plusieurs fois\n" "mais avec des expressions différentes" -#: commands/tablecmds.c:2477 +#: commands/tablecmds.c:2711 #, c-format msgid "cannot rename column of typed table" msgstr "ne peut pas renommer une colonne d'une table typée" -#: commands/tablecmds.c:2495 +#: commands/tablecmds.c:2730 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" msgstr "« %s » n'est ni une table, ni une vue, ni une vue matérialisée, ni un type composite, ni un index, ni une table distante" -#: commands/tablecmds.c:2589 +#: commands/tablecmds.c:2824 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "la colonne héritée « %s » doit aussi être renommée pour les tables filles" -#: commands/tablecmds.c:2621 +#: commands/tablecmds.c:2856 #, c-format msgid "cannot rename system column \"%s\"" msgstr "ne peut pas renommer la colonne système « %s »" -#: commands/tablecmds.c:2636 +#: commands/tablecmds.c:2871 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "ne peut pas renommer la colonne héritée « %s »" -#: commands/tablecmds.c:2788 +#: commands/tablecmds.c:3023 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "la contrainte héritée « %s » doit aussi être renommée pour les tables enfants" -#: commands/tablecmds.c:2795 +#: commands/tablecmds.c:3030 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "ne peut pas renommer la colonne héritée « %s »" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3019 +#: commands/tablecmds.c:3256 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "" @@ -8348,1277 +8662,1394 @@ msgstr "" "des requêtes actives dans cette session" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3028 +#: commands/tablecmds.c:3266 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "ne peut pas exécuter %s « %s » car il reste des événements sur les triggers" -#: commands/tablecmds.c:4147 +#: commands/tablecmds.c:4414 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "ne peut pas ré-écrire la relation système « %s »" -#: commands/tablecmds.c:4153 +#: commands/tablecmds.c:4420 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "ne peut pas réécrire la table « %s » utilisée comme une table catalogue" -#: commands/tablecmds.c:4163 +#: commands/tablecmds.c:4430 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "ne peut pas ré-écrire les tables temporaires des autres sessions" -#: commands/tablecmds.c:4439 +#: commands/tablecmds.c:4716 #, c-format msgid "rewriting table \"%s\"" msgstr "ré-écriture de la table « %s »" -#: commands/tablecmds.c:4443 +#: commands/tablecmds.c:4720 #, c-format msgid "verifying table \"%s\"" msgstr "vérification de la table « %s »" -#: commands/tablecmds.c:4556 +#: commands/tablecmds.c:4836 #, c-format msgid "column \"%s\" contains null values" msgstr "la colonne « %s » contient des valeurs NULL" -#: commands/tablecmds.c:4571 commands/tablecmds.c:8150 +#: commands/tablecmds.c:4852 commands/tablecmds.c:8929 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "la contrainte de vérification « %s » est rompue par une ligne" -#: commands/tablecmds.c:4587 +#: commands/tablecmds.c:4870 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "la contrainte de partition mise à jour pour la partition par défaut serait transgressée par des lignes" + +#: commands/tablecmds.c:4874 #, c-format msgid "partition constraint is violated by some row" msgstr "la contrainte de partition est violée par une ligne" -#: commands/tablecmds.c:4725 commands/trigger.c:247 rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:920 +#: commands/tablecmds.c:5016 commands/trigger.c:310 rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" msgstr "« %s » n'est pas une table ou une vue" -#: commands/tablecmds.c:4728 commands/trigger.c:1288 commands/trigger.c:1394 +#: commands/tablecmds.c:5019 commands/trigger.c:1520 commands/trigger.c:1626 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "« %s » n'est pas une table, une vue ou une table distante" -#: commands/tablecmds.c:4731 +#: commands/tablecmds.c:5022 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "« %s » n'est pas une table, une vue, une vue matérialisée, une séquence ou une table distante" -#: commands/tablecmds.c:4737 +#: commands/tablecmds.c:5028 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "« %s » n'est pas une table, une vue matérialisée ou un index" -#: commands/tablecmds.c:4740 +#: commands/tablecmds.c:5031 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "« %s » n'est pas une table, une vue matérialisée ou une table distante" -#: commands/tablecmds.c:4743 +#: commands/tablecmds.c:5034 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "« %s » n'est pas une table ou une table distante" -#: commands/tablecmds.c:4746 +#: commands/tablecmds.c:5037 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "« %s » n'est ni une table, ni un type composite, ni une table distante" -#: commands/tablecmds.c:4749 commands/tablecmds.c:6112 +#: commands/tablecmds.c:5040 commands/tablecmds.c:6458 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "« %s » n'est pas une table, une vue matérialisée, un index ou une table distante" -#: commands/tablecmds.c:4759 +#: commands/tablecmds.c:5050 #, c-format msgid "\"%s\" is of the wrong type" msgstr "« %s » est du mauvais type" -#: commands/tablecmds.c:4913 commands/tablecmds.c:4920 +#: commands/tablecmds.c:5225 commands/tablecmds.c:5232 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "ne peux pas modifier le type « %s » car la colonne « %s.%s » l'utilise" -#: commands/tablecmds.c:4927 +#: commands/tablecmds.c:5239 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "" "ne peut pas modifier la table distante « %s » car la colonne « %s.%s » utilise\n" "son type de ligne" -#: commands/tablecmds.c:4934 +#: commands/tablecmds.c:5246 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "" "ne peut pas modifier la table « %s » car la colonne « %s.%s » utilise\n" "son type de ligne" -#: commands/tablecmds.c:4996 +#: commands/tablecmds.c:5300 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "ne peut pas modifier le type « %s » car il s'agit du type d'une table de type" -#: commands/tablecmds.c:4998 +#: commands/tablecmds.c:5302 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "Utilisez ALTER ... CASCADE pour modifier aussi les tables de type." -#: commands/tablecmds.c:5042 +#: commands/tablecmds.c:5348 #, c-format msgid "type %s is not a composite type" msgstr "le type %s n'est pas un type composite" -#: commands/tablecmds.c:5068 +#: commands/tablecmds.c:5374 #, c-format msgid "cannot add column to typed table" msgstr "ne peut pas ajouter une colonne à une table typée" -#: commands/tablecmds.c:5112 +#: commands/tablecmds.c:5418 #, c-format msgid "cannot add column to a partition" msgstr "ne peut pas ajouter une colonne à une partition" -#: commands/tablecmds.c:5141 commands/tablecmds.c:11213 +#: commands/tablecmds.c:5447 commands/tablecmds.c:12222 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "la table fille « %s » a un type différent pour la colonne « %s »" -#: commands/tablecmds.c:5147 commands/tablecmds.c:11220 +#: commands/tablecmds.c:5453 commands/tablecmds.c:12229 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "la table fille « %s » a un collationnement différent pour la colonne « %s »" -#: commands/tablecmds.c:5157 +#: commands/tablecmds.c:5463 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" msgstr "la table fille « %s » a une colonne conflictuelle, « %s »" -#: commands/tablecmds.c:5168 +#: commands/tablecmds.c:5474 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "assemblage de la définition de la colonne « %s » pour le fils « %s »" -#: commands/tablecmds.c:5192 +#: commands/tablecmds.c:5498 #, c-format msgid "cannot recursively add identity column to table that has child tables" msgstr "ne peut pas ajouter récursivement la colonne identité à une table qui a des tables filles" -#: commands/tablecmds.c:5404 +#: commands/tablecmds.c:5747 #, c-format msgid "column must be added to child tables too" msgstr "la colonne doit aussi être ajoutée aux tables filles" -#: commands/tablecmds.c:5479 +#: commands/tablecmds.c:5822 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "la colonne « %s » de la relation « %s » existe déjà, poursuite du traitement" -#: commands/tablecmds.c:5486 +#: commands/tablecmds.c:5829 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "la colonne « %s » de la relation « %s » existe déjà" -#: commands/tablecmds.c:5584 commands/tablecmds.c:8563 +#: commands/tablecmds.c:5927 commands/tablecmds.c:9388 #, c-format msgid "cannot remove constraint from only the partitioned table when partitions exist" msgstr "ne peut pas supprimer une contrainte uniquement d'une table partitionnée quand des partitions existent" -#: commands/tablecmds.c:5585 commands/tablecmds.c:5732 commands/tablecmds.c:6529 commands/tablecmds.c:8564 +#: commands/tablecmds.c:5928 commands/tablecmds.c:6072 commands/tablecmds.c:6856 commands/tablecmds.c:9389 #, c-format msgid "Do not specify the ONLY keyword." msgstr "Ne spécifiez pas le mot clé ONLY." -#: commands/tablecmds.c:5617 commands/tablecmds.c:5764 commands/tablecmds.c:5819 commands/tablecmds.c:5894 commands/tablecmds.c:5988 commands/tablecmds.c:6047 commands/tablecmds.c:6171 commands/tablecmds.c:6225 commands/tablecmds.c:6317 commands/tablecmds.c:8703 commands/tablecmds.c:9414 +#: commands/tablecmds.c:5960 commands/tablecmds.c:6108 commands/tablecmds.c:6163 commands/tablecmds.c:6239 commands/tablecmds.c:6333 commands/tablecmds.c:6392 commands/tablecmds.c:6542 commands/tablecmds.c:6612 commands/tablecmds.c:6704 commands/tablecmds.c:9528 commands/tablecmds.c:10303 #, c-format msgid "cannot alter system column \"%s\"" msgstr "n'a pas pu modifier la colonne système « %s »" -#: commands/tablecmds.c:5623 commands/tablecmds.c:5825 +#: commands/tablecmds.c:5966 commands/tablecmds.c:6169 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité" -#: commands/tablecmds.c:5659 +#: commands/tablecmds.c:6002 #, c-format msgid "column \"%s\" is in a primary key" msgstr "la colonne « %s » est dans une clé primaire" -#: commands/tablecmds.c:5681 +#: commands/tablecmds.c:6024 #, c-format msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "la colonne « %s » est marquée NOT NULL dans la table parent" -#: commands/tablecmds.c:5731 +#: commands/tablecmds.c:6071 #, c-format msgid "cannot add constraint to only the partitioned table when partitions exist" msgstr "ne peut pas ajouter la contrainte à la seule table partitionnée quand plusieurs partitions existent" -#: commands/tablecmds.c:5827 +#: commands/tablecmds.c:6171 #, c-format msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." msgstr "Utilisez à la place ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." -#: commands/tablecmds.c:5905 +#: commands/tablecmds.c:6250 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" msgstr "la colonne « %s » de la relation « %s » doit être déclarée NOT NULL avant que la colonne identité puisse être ajoutée" -#: commands/tablecmds.c:5911 +#: commands/tablecmds.c:6256 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "la colonne « %s » de la relation « %s » est déjà une colonne d'identité" -#: commands/tablecmds.c:5917 +#: commands/tablecmds.c:6262 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "la colonne « %s » de la relation « %s » a déjà une valeur par défaut" -#: commands/tablecmds.c:5994 commands/tablecmds.c:6055 +#: commands/tablecmds.c:6339 commands/tablecmds.c:6400 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité" -#: commands/tablecmds.c:6060 +#: commands/tablecmds.c:6405 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "la colonne « %s » de la relation « %s » n'est pas une colonne d'identité, poursuite du traitement" -#: commands/tablecmds.c:6144 +#: commands/tablecmds.c:6470 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "impossible de référence une colonne non liée à une table par un nombre" + +#: commands/tablecmds.c:6501 #, c-format msgid "statistics target %d is too low" msgstr "la cible statistique %d est trop basse" -#: commands/tablecmds.c:6152 +#: commands/tablecmds.c:6509 #, c-format msgid "lowering statistics target to %d" msgstr "abaissement de la cible statistique à %d" -#: commands/tablecmds.c:6297 +#: commands/tablecmds.c:6532 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "la colonne numéro %d de la relation « %s » n'existe pas" + +#: commands/tablecmds.c:6551 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "ne peut modifier les statistiques sur la colonne incluse « %s » de l'index « %s »" + +#: commands/tablecmds.c:6556 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "ne peut modifier les statistiques sur la colonne « %s » de l'index « %s » qui n'est pas une expression" + +#: commands/tablecmds.c:6558 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Modifier les statistiques sur la colonne de la table à la place." + +#: commands/tablecmds.c:6684 #, c-format msgid "invalid storage type \"%s\"" msgstr "type « %s » de stockage invalide" -#: commands/tablecmds.c:6329 +#: commands/tablecmds.c:6716 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "le type de données %s de la colonne peut seulement avoir un stockage PLAIN" -#: commands/tablecmds.c:6364 +#: commands/tablecmds.c:6751 #, c-format msgid "cannot drop column from typed table" msgstr "ne peut pas supprimer une colonne à une table typée" -#: commands/tablecmds.c:6471 +#: commands/tablecmds.c:6796 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "la colonne « %s » de la relation « %s » n'existe pas, ignore" -#: commands/tablecmds.c:6484 +#: commands/tablecmds.c:6809 #, c-format msgid "cannot drop system column \"%s\"" msgstr "ne peut pas supprimer la colonne système « %s »" -#: commands/tablecmds.c:6491 +#: commands/tablecmds.c:6816 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "ne peut pas supprimer la colonne héritée « %s »" -#: commands/tablecmds.c:6500 +#: commands/tablecmds.c:6827 #, c-format msgid "cannot drop column named in partition key" msgstr "ne peut pas supprimer une colonne nommée dans une clé de partitionnement" -#: commands/tablecmds.c:6504 +#: commands/tablecmds.c:6831 #, c-format msgid "cannot drop column referenced in partition key expression" msgstr "ne peut pas supprimer une colonne référencée dans l'expression d'une clé de partitionnement" -#: commands/tablecmds.c:6528 +#: commands/tablecmds.c:6855 #, c-format msgid "cannot drop column from only the partitioned table when partitions exist" msgstr "ne peut pas supprimer une colonne sur une seule partition quand plusieurs partitions existent" -#: commands/tablecmds.c:6746 +#: commands/tablecmds.c:7060 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX n'est pas supporté sur les tables partitionnées" + +#: commands/tablecmds.c:7085 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX renommera l'index « %s » en « %s »" -#: commands/tablecmds.c:6958 +#: commands/tablecmds.c:7301 #, c-format msgid "constraint must be added to child tables too" msgstr "la contrainte doit aussi être ajoutée aux tables filles" -#: commands/tablecmds.c:7029 +#: commands/tablecmds.c:7374 #, c-format msgid "cannot reference partitioned table \"%s\"" msgstr "ne peut pas référencer la table partitionnée « %s »" -#: commands/tablecmds.c:7035 +#: commands/tablecmds.c:7382 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ne peut pas utiliser ONLY pour une clé étrangère sur la table partitionnée « %s » référençant la relation « %s »" + +#: commands/tablecmds.c:7388 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ne peut pas ajouter de clé étrangère NOT VALID sur la table partitionnée « %s » référençant la relation « %s »" + +#: commands/tablecmds.c:7391 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Cette fonctionnalité n'est pas encore implémentée sur les tables partitionnées." + +#: commands/tablecmds.c:7397 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "la relation référencée « %s » n'est pas une table" -#: commands/tablecmds.c:7058 +#: commands/tablecmds.c:7420 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "les contraintes sur les tables permanentes peuvent seulement référencer des tables permanentes" -#: commands/tablecmds.c:7065 +#: commands/tablecmds.c:7427 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "les contraintes sur les tables non tracées peuvent seulement référencer des tables permanentes ou non tracées" -#: commands/tablecmds.c:7071 +#: commands/tablecmds.c:7433 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "" "les constraintes sur des tables temporaires ne peuvent référencer que des\n" "tables temporaires" -#: commands/tablecmds.c:7075 +#: commands/tablecmds.c:7437 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "" "les contraintes sur des tables temporaires doivent référencer les tables\n" "temporaires de cette session" -#: commands/tablecmds.c:7135 +#: commands/tablecmds.c:7497 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "nombre de colonnes de référence et référencées pour la clé étrangère en désaccord" -#: commands/tablecmds.c:7242 +#: commands/tablecmds.c:7604 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "la contrainte de clé étrangère « %s » ne peut pas être implémentée" -#: commands/tablecmds.c:7245 +#: commands/tablecmds.c:7607 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "Les colonnes clés « %s » et « %s » sont de types incompatibles : %s et %s." -#: commands/tablecmds.c:7450 commands/tablecmds.c:7616 commands/tablecmds.c:8531 commands/tablecmds.c:8599 +#: commands/tablecmds.c:8229 commands/tablecmds.c:8394 commands/tablecmds.c:9345 commands/tablecmds.c:9420 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "la contrainte « %s » de la relation « %s » n'existe pas" -#: commands/tablecmds.c:7456 +#: commands/tablecmds.c:8236 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "la contrainte « %s » de la relation « %s » n'est pas une clé étrangère" -#: commands/tablecmds.c:7623 +#: commands/tablecmds.c:8402 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "la contrainte « %s » de la relation « %s » n'est pas une clé étrangère ou une contrainte de vérification" -#: commands/tablecmds.c:7693 +#: commands/tablecmds.c:8472 #, c-format msgid "constraint must be validated on child tables too" msgstr "la contrainte doit aussi être validées sur les tables enfants" -#: commands/tablecmds.c:7761 +#: commands/tablecmds.c:8540 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "la colonne « %s » référencée dans la contrainte de clé étrangère n'existe pas" -#: commands/tablecmds.c:7766 +#: commands/tablecmds.c:8545 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "ne peut pas avoir plus de %d clés dans une clé étrangère" -#: commands/tablecmds.c:7831 +#: commands/tablecmds.c:8610 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "ne peut pas utiliser une clé primaire déferrable pour la table « %s » référencée" -#: commands/tablecmds.c:7848 +#: commands/tablecmds.c:8627 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "il n'existe pas de clé étrangère pour la table « %s » référencée" -#: commands/tablecmds.c:7913 +#: commands/tablecmds.c:8692 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "la liste de colonnes référencées dans la clé étrangère ne doit pas contenir de duplicats" -#: commands/tablecmds.c:8007 +#: commands/tablecmds.c:8786 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "" "ne peut pas utiliser une contrainte unique déferrable pour la table\n" "référencée « %s »" -#: commands/tablecmds.c:8012 +#: commands/tablecmds.c:8791 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "" "il n'existe aucune contrainte unique correspondant aux clés données pour la\n" "table « %s » référencée" -#: commands/tablecmds.c:8183 +#: commands/tablecmds.c:8962 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "validation de la contraintes de clé étrangère « %s »" -#: commands/tablecmds.c:8485 +#: commands/tablecmds.c:9301 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "ne peut pas supprimer la contrainte héritée « %s » de la relation « %s »" -#: commands/tablecmds.c:8537 +#: commands/tablecmds.c:9351 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "la contrainte « %s » de la relation « %s » n'existe pas, ignore" -#: commands/tablecmds.c:8687 +#: commands/tablecmds.c:9512 #, c-format msgid "cannot alter column type of typed table" msgstr "ne peut pas modifier le type d'une colonne appartenant à une table typée" -#: commands/tablecmds.c:8710 +#: commands/tablecmds.c:9535 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "ne peut pas modifier la colonne héritée « %s »" -#: commands/tablecmds.c:8719 +#: commands/tablecmds.c:9546 #, c-format msgid "cannot alter type of column named in partition key" msgstr "ne peut pas modifier le type d'une colonne nommée dans une clé de partitionnement" -#: commands/tablecmds.c:8723 +#: commands/tablecmds.c:9550 #, c-format msgid "cannot alter type of column referenced in partition key expression" msgstr "ne peut pas utiliser le type d'une colonne référencée dans l'expression d'une clé de partitionnement" -#: commands/tablecmds.c:8773 +#: commands/tablecmds.c:9600 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "le résultat de la clause USING pour la colonne « %s » ne peut pas être converti automatiquement vers le type %s" -#: commands/tablecmds.c:8776 +#: commands/tablecmds.c:9603 #, c-format msgid "You might need to add an explicit cast." msgstr "Vous pouvez avoir besoin d'ajouter une conversion explicite." -#: commands/tablecmds.c:8780 +#: commands/tablecmds.c:9607 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "la colonne « %s » ne peut pas être convertie vers le type %s" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:8783 +#: commands/tablecmds.c:9610 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Vous pouvez avoir besoin de spécifier \"USING %s::%s\"." -#: commands/tablecmds.c:8882 +#: commands/tablecmds.c:9709 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "l'expression USING contient une référence de table de ligne complète" -#: commands/tablecmds.c:8893 +#: commands/tablecmds.c:9720 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "le type de colonne héritée « %s » doit aussi être renommée pour les tables filles" -#: commands/tablecmds.c:8980 +#: commands/tablecmds.c:9824 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "ne peut pas modifier la colonne « %s » deux fois" -#: commands/tablecmds.c:9016 +#: commands/tablecmds.c:9860 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "" "la valeur par défaut de la colonne « %s » ne peut pas être convertie vers le\n" "type %s automatiquement" -#: commands/tablecmds.c:9142 +#: commands/tablecmds.c:9966 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "ne peut pas modifier le type d'une colonne utilisée dans une vue ou une règle" -#: commands/tablecmds.c:9143 commands/tablecmds.c:9162 commands/tablecmds.c:9180 +#: commands/tablecmds.c:9967 commands/tablecmds.c:9986 commands/tablecmds.c:10004 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s dépend de la colonne « %s »" -#: commands/tablecmds.c:9161 +#: commands/tablecmds.c:9985 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "ne peut pas modifier le type d'une colonne utilisée dans la définition d'un trigger" -#: commands/tablecmds.c:9179 +#: commands/tablecmds.c:10003 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "ne peut pas modifier le type d'une colonne utilisée dans la définition d'une politique" -#: commands/tablecmds.c:9854 +#: commands/tablecmds.c:10806 commands/tablecmds.c:10818 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "ne peut pas modifier le propriétaire de l'index « %s »" -#: commands/tablecmds.c:9856 +#: commands/tablecmds.c:10808 commands/tablecmds.c:10820 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "Modifier à la place le propriétaire de la table concernée par l'index." -#: commands/tablecmds.c:9873 +#: commands/tablecmds.c:10834 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "ne peut pas modifier le propriétaire de la séquence « %s »" -#: commands/tablecmds.c:9887 commands/tablecmds.c:13116 +#: commands/tablecmds.c:10848 commands/tablecmds.c:14132 #, c-format msgid "Use ALTER TYPE instead." msgstr "Utilisez ALTER TYPE à la place." -#: commands/tablecmds.c:9896 +#: commands/tablecmds.c:10857 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "« %s » n'est pas une table, une vue, une séquence ou une table distante" -#: commands/tablecmds.c:10237 +#: commands/tablecmds.c:11197 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "ne peut pas avoir de nombreuses sous-commandes SET TABLESPACE" -#: commands/tablecmds.c:10311 +#: commands/tablecmds.c:11272 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "« %s » n'est pas une table, une vue, une vue matérialisée, un index ou une table TOAST" -#: commands/tablecmds.c:10344 commands/view.c:504 +#: commands/tablecmds.c:11305 commands/view.c:503 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION est uniquement accepté pour les vues dont la mise à jour est automatique" -#: commands/tablecmds.c:10486 +#: commands/tablecmds.c:11447 #, c-format msgid "cannot move system relation \"%s\"" msgstr "ne peut pas déplacer la colonne système « %s »" -#: commands/tablecmds.c:10502 +#: commands/tablecmds.c:11463 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "ne peut pas déplacer les tables temporaires d'autres sessions" -#: commands/tablecmds.c:10638 +#: commands/tablecmds.c:11654 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "seuls les tables, index et vues matérialisées existent dans les tablespaces" -#: commands/tablecmds.c:10650 +#: commands/tablecmds.c:11666 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "ne peut pas déplacer les relations dans ou à partir du tablespace pg_global" -#: commands/tablecmds.c:10742 +#: commands/tablecmds.c:11759 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "annulation car le verrou sur la relation « %s.%s » n'est pas disponible" -#: commands/tablecmds.c:10758 +#: commands/tablecmds.c:11775 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "aucune relation correspondante trouvée dans le tablespace « %s »" -#: commands/tablecmds.c:10832 storage/buffer/bufmgr.c:915 +#: commands/tablecmds.c:11842 storage/buffer/bufmgr.c:915 #, c-format msgid "invalid page in block %u of relation %s" msgstr "page invalide dans le bloc %u de la relation %s" -#: commands/tablecmds.c:10914 +#: commands/tablecmds.c:11922 #, c-format msgid "cannot change inheritance of typed table" msgstr "ne peut pas modifier l'héritage d'une table typée" -#: commands/tablecmds.c:10919 commands/tablecmds.c:11461 +#: commands/tablecmds.c:11927 commands/tablecmds.c:12470 #, c-format msgid "cannot change inheritance of a partition" msgstr "ne peut pas modifier l'héritage d'une partition" -#: commands/tablecmds.c:10924 +#: commands/tablecmds.c:11932 #, c-format msgid "cannot change inheritance of partitioned table" msgstr "ne peut pas modifier l'héritage d'une table partitionnée" -#: commands/tablecmds.c:10970 +#: commands/tablecmds.c:11978 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "ne peut pas hériter à partir d'une relation temporaire d'une autre session" -#: commands/tablecmds.c:10983 +#: commands/tablecmds.c:11991 #, c-format msgid "cannot inherit from a partition" msgstr "ne peut pas hériter d'une partition" -#: commands/tablecmds.c:11005 commands/tablecmds.c:13509 +#: commands/tablecmds.c:12013 commands/tablecmds.c:14716 #, c-format msgid "circular inheritance not allowed" msgstr "héritage circulaire interdit" -#: commands/tablecmds.c:11006 commands/tablecmds.c:13510 +#: commands/tablecmds.c:12014 commands/tablecmds.c:14717 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "« %s » est déjà un enfant de « %s »." -#: commands/tablecmds.c:11014 +#: commands/tablecmds.c:12022 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" msgstr "la table « %s » qui n'a pas d'OID ne peut pas hériter de la table « %s » qui en a" -#: commands/tablecmds.c:11027 +#: commands/tablecmds.c:12035 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" msgstr "le trigger « %s » empêche la table « %s » de devenir une fille dans l'héritage" -#: commands/tablecmds.c:11029 +#: commands/tablecmds.c:12037 #, c-format msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" msgstr "les triggers ROW avec des tables de transition ne sont pas supportés dans les hiérarchies d'héritage" -#: commands/tablecmds.c:11231 +#: commands/tablecmds.c:12240 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "la colonne « %s » de la table enfant doit être marquée comme NOT NULL" -#: commands/tablecmds.c:11258 commands/tablecmds.c:11297 +#: commands/tablecmds.c:12267 commands/tablecmds.c:12306 #, c-format msgid "child table is missing column \"%s\"" msgstr "la colonne « %s » manque à la table enfant" -#: commands/tablecmds.c:11385 +#: commands/tablecmds.c:12394 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "la table fille « %s » a un type différent pour la contrainte de vérification « %s »" -#: commands/tablecmds.c:11393 +#: commands/tablecmds.c:12402 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "la contrainte « %s » entre en conflit avec une contrainte non héritée sur la table fille « %s »" -#: commands/tablecmds.c:11404 +#: commands/tablecmds.c:12413 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "la contrainte « %s » entre en conflit avec une contrainte NOT VALID sur la table fille « %s »" -#: commands/tablecmds.c:11439 +#: commands/tablecmds.c:12448 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "la contrainte « %s » manque à la table enfant" -#: commands/tablecmds.c:11555 +#: commands/tablecmds.c:12537 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "la relation « %s » n'est pas une partition de la relation « %s »" -#: commands/tablecmds.c:11561 +#: commands/tablecmds.c:12543 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "la relation « %s » n'est pas un parent de la relation « %s »" -#: commands/tablecmds.c:11787 +#: commands/tablecmds.c:12769 #, c-format msgid "typed tables cannot inherit" msgstr "les tables avec type ne peuvent pas hériter d'autres tables" -#: commands/tablecmds.c:11818 +#: commands/tablecmds.c:12800 #, c-format msgid "table is missing column \"%s\"" msgstr "la colonne « %s » manque à la table" -#: commands/tablecmds.c:11828 +#: commands/tablecmds.c:12811 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "la table a une colonne « %s » alors que le type impose « %s »." -#: commands/tablecmds.c:11837 +#: commands/tablecmds.c:12820 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "la table « %s » a un type différent pour la colonne « %s »" -#: commands/tablecmds.c:11850 +#: commands/tablecmds.c:12834 #, c-format msgid "table has extra column \"%s\"" msgstr "la table a une colonne supplémentaire « %s »" -#: commands/tablecmds.c:11902 +#: commands/tablecmds.c:12886 #, c-format msgid "\"%s\" is not a typed table" msgstr "« %s » n'est pas une table typée" -#: commands/tablecmds.c:12084 +#: commands/tablecmds.c:13068 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "ne peut pas utiliser l'index non unique « %s » comme identité de réplicat" -#: commands/tablecmds.c:12090 +#: commands/tablecmds.c:13074 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "ne peut pas utiliser l'index « %s » immédiat comme identité de réplicat" -#: commands/tablecmds.c:12096 +#: commands/tablecmds.c:13080 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "ne peut pas utiliser un index par expression « %s » comme identité de réplicat" -#: commands/tablecmds.c:12102 +#: commands/tablecmds.c:13086 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "ne peut pas utiliser l'index partiel « %s » comme identité de réplicat" -#: commands/tablecmds.c:12108 +#: commands/tablecmds.c:13092 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "ne peut pas utiliser l'index invalide « %s » comme identité de réplicat" -#: commands/tablecmds.c:12129 +#: commands/tablecmds.c:13113 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "l'index « %s » ne peut pas être utilisé comme identité de réplicat car la colonne %d est une colonne système" -#: commands/tablecmds.c:12136 +#: commands/tablecmds.c:13120 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "l'index « %s » ne peut pas être utilisé comme identité de réplicat car la colonne « %s » peut être NULL" -#: commands/tablecmds.c:12329 +#: commands/tablecmds.c:13313 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "ne peut pas modifier le statut de journalisation de la table « %s » parce qu'elle est temporaire" -#: commands/tablecmds.c:12353 +#: commands/tablecmds.c:13337 #, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "ne peut pas modifier la table « %s » en non journalisée car elle fait partie d'une publication" -#: commands/tablecmds.c:12355 +#: commands/tablecmds.c:13339 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Les relations non journalisées ne peuvent pas être répliquées." -#: commands/tablecmds.c:12400 +#: commands/tablecmds.c:13384 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "n'a pas pu passer la table « %s » en journalisé car elle référence la table non journalisée « %s »" -#: commands/tablecmds.c:12410 +#: commands/tablecmds.c:13394 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "n'a pas pu passer la table « %s » en non journalisé car elle référence la table journalisée « %s »" -#: commands/tablecmds.c:12468 +#: commands/tablecmds.c:13452 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "ne peut pas déplacer une séquence OWNED BY dans un autre schéma" -#: commands/tablecmds.c:12574 +#: commands/tablecmds.c:13558 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "la relation « %s » existe déjà dans le schéma « %s »" -#: commands/tablecmds.c:13100 +#: commands/tablecmds.c:14115 #, c-format msgid "\"%s\" is not a composite type" msgstr "« %s » n'est pas un type composite" -#: commands/tablecmds.c:13131 +#: commands/tablecmds.c:14147 #, c-format msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" msgstr "« %s » n'est pas une table, une vue, une vue matérialisée, une séquence ou une table distante" -#: commands/tablecmds.c:13164 +#: commands/tablecmds.c:14182 #, c-format msgid "unrecognized partitioning strategy \"%s\"" msgstr "stratégie de partitionnement « %s » non reconnue" -#: commands/tablecmds.c:13172 +#: commands/tablecmds.c:14190 #, c-format msgid "cannot use \"list\" partition strategy with more than one column" msgstr "ne peut pas utiliser la stratégie de partitionnement « list » avec plus d'une colonne" -#: commands/tablecmds.c:13197 -#, c-format -msgid "column \"%s\" appears more than once in partition key" -msgstr "la colonne « %s » apparaît plus d'une fois dans la clé de partitionnement" - -#: commands/tablecmds.c:13250 +#: commands/tablecmds.c:14255 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "la colonne « %s » nommée dans la clé de partitionnement n'existe pas" -#: commands/tablecmds.c:13257 +#: commands/tablecmds.c:14262 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "ne peut pas utiliser la colonne système « %s » comme clé de partitionnement" -#: commands/tablecmds.c:13320 +#: commands/tablecmds.c:14325 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "" "les fonctions dans une expression de clé de partitionnement doivent être marquées comme\n" "IMMUTABLE" -#: commands/tablecmds.c:13337 +#: commands/tablecmds.c:14342 #, c-format msgid "partition key expressions cannot contain whole-row references" msgstr "les expressions de clé de partitionnement ne peuvent pas contenir des références à des lignes complètes" -#: commands/tablecmds.c:13344 +#: commands/tablecmds.c:14349 #, c-format msgid "partition key expressions cannot contain system column references" msgstr "les expressions de la clé de partitionnement ne peuvent pas contenir des références aux colonnes systèmes" -#: commands/tablecmds.c:13354 +#: commands/tablecmds.c:14359 #, c-format msgid "cannot use constant expression as partition key" msgstr "ne peut pas utiliser une expression constante comme clé de partitionnement" -#: commands/tablecmds.c:13375 +#: commands/tablecmds.c:14380 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "n'a pas pu déterminer le collationnement à utiliser pour l'expression de partitionnement" -#: commands/tablecmds.c:13400 +#: commands/tablecmds.c:14413 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "le type de données %s n'a pas de classe d'opérateurs hash par défaut" + +#: commands/tablecmds.c:14415 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "" +"Vous devez spécifier une classe d'opérateur hash ou définir une\n" +"classe d'opérateur hash par défaut pour le type de données." + +#: commands/tablecmds.c:14419 #, c-format msgid "data type %s has no default btree operator class" msgstr "le type de données %s n'a pas de classe d'opérateurs btree par défaut" -#: commands/tablecmds.c:13402 +#: commands/tablecmds.c:14421 #, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." msgstr "" "Vous devez spécifier une classe d'opérateur btree ou définir une\n" "classe d'opérateur btree par défaut pour le type de données." -#: commands/tablecmds.c:13449 +#: commands/tablecmds.c:14546 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "la contrainte de partitionnement pour la table « %s » provient des contraintes existantes" + +#: commands/tablecmds.c:14550 partitioning/partbounds.c:621 partitioning/partbounds.c:666 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "la contrainte de partitionnement pour la partition par défaut « %s » est implicite du fait de contraintes existantes" + +#: commands/tablecmds.c:14656 #, c-format msgid "\"%s\" is already a partition" msgstr "« %s » est déjà une partition" -#: commands/tablecmds.c:13455 +#: commands/tablecmds.c:14662 #, c-format msgid "cannot attach a typed table as partition" msgstr "ne peut pas attacher une table typée à une partition" -#: commands/tablecmds.c:13471 +#: commands/tablecmds.c:14678 #, c-format msgid "cannot attach inheritance child as partition" msgstr "ne peut pas ajouter la table en héritage comme une partition" -#: commands/tablecmds.c:13485 +#: commands/tablecmds.c:14692 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "ne peut pas attacher le parent d'héritage comme partition" -#: commands/tablecmds.c:13519 +#: commands/tablecmds.c:14726 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "ne peut pas attacher une relation temporaire comme partition de la relation permanente « %s »" + +#: commands/tablecmds.c:14734 #, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "ne peut pas attacher une relation permanente comme partition de la relation temporaire « %s »" -#: commands/tablecmds.c:13527 +#: commands/tablecmds.c:14742 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "ne peut pas attacher comme partition d'une relation temporaire d'une autre session" -#: commands/tablecmds.c:13534 +#: commands/tablecmds.c:14749 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "ne peut pas attacher une relation temporaire d'une autre session comme partition" -#: commands/tablecmds.c:13540 +#: commands/tablecmds.c:14755 #, c-format msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" msgstr "ne peut pas attacher la table « %s » sans OID comme partition de la table « %s » avec OID" -#: commands/tablecmds.c:13548 +#: commands/tablecmds.c:14763 #, c-format msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" msgstr "ne peut pas attacher la table « %s » avec OID comme partition de la table « %s » sans OID" -#: commands/tablecmds.c:13570 +#: commands/tablecmds.c:14785 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "la table « %s » contient la colonne « %s » introuvable dans le parent « %s »" -#: commands/tablecmds.c:13573 +#: commands/tablecmds.c:14788 #, c-format -msgid "New partition should contain only the columns present in parent." -msgstr "La nouvelle partition devrait seulement contenir les colonnes présentes dans le parent." +msgid "The new partition may contain only the columns present in parent." +msgstr "La nouvelle partition pourrait seulement contenir les colonnes présentes dans le parent." -#: commands/tablecmds.c:13585 +#: commands/tablecmds.c:14800 #, c-format msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" msgstr "le trigger « %s » empêche la table « %s » de devenir une partition" -#: commands/tablecmds.c:13587 commands/trigger.c:387 +#: commands/tablecmds.c:14802 commands/trigger.c:462 #, c-format msgid "ROW triggers with transition tables are not supported on partitions" msgstr "les triggers ROW avec des tables de transition ne sont pas supportés sur les partitions" -#: commands/tablecmds.c:13702 +#: commands/tablecmds.c:15492 commands/tablecmds.c:15511 commands/tablecmds.c:15533 commands/tablecmds.c:15552 commands/tablecmds.c:15608 #, c-format -msgid "partition constraint for table \"%s\" is implied by existing constraints" -msgstr "la contrainte de partitionnement pour la table « %s » provient des contraintes existantes" +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "ne peut pas attacher l'index « %s » comme une partition de l'index « %s »" -#: commands/tablespace.c:162 commands/tablespace.c:179 commands/tablespace.c:190 commands/tablespace.c:198 commands/tablespace.c:623 replication/slot.c:1177 storage/file/copydir.c:47 +#: commands/tablecmds.c:15495 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "l'index « %s » est déjà attaché à un autre index" + +#: commands/tablecmds.c:15514 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "L'index « %s » n'est pas un index sur aucune des partitions de la table « %s »" + +#: commands/tablecmds.c:15536 +#, c-format +msgid "The index definitions do not match." +msgstr "La définition de l'index correspond pas." + +#: commands/tablecmds.c:15555 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "L'index « %s » appartient à une contrainte dans la table « %s » mais aucune contrainte n'existe pour l'index « %s »." + +#: commands/tablecmds.c:15611 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "Un autre index est déjà attaché pour la partition « %s »." + +#: commands/tablespace.c:163 commands/tablespace.c:180 commands/tablespace.c:191 commands/tablespace.c:199 commands/tablespace.c:625 replication/slot.c:1199 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "n'a pas pu créer le répertoire « %s » : %m" -#: commands/tablespace.c:209 utils/adt/genfile.c:538 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "n'a pas pu lire les informations sur le répertoire « %s » : %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "« %s » existe mais n'est pas un répertoire" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "droit refusé pour créer le tablespace « %s »" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "Doit être super-utilisateur pour créer un tablespace." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "le chemin du tablespace ne peut pas contenir de guillemets simples" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "le chemin du tablespace doit être un chemin absolu" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "le chemin du tablespace « %s » est trop long" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "l'emplacement du tablespace ne doit pas être dans le répertoire de données" -#: commands/tablespace.c:304 commands/tablespace.c:950 +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "nom inacceptable pour le tablespace « %s »" -#: commands/tablespace.c:306 commands/tablespace.c:951 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "Le préfixe « pg_ » est réservé pour les tablespaces système." -#: commands/tablespace.c:316 commands/tablespace.c:963 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "le tablespace « %s » existe déjà" -#: commands/tablespace.c:428 commands/tablespace.c:933 commands/tablespace.c:1013 commands/tablespace.c:1081 commands/tablespace.c:1214 commands/tablespace.c:1414 +#: commands/tablespace.c:430 commands/tablespace.c:935 commands/tablespace.c:1015 commands/tablespace.c:1083 commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "le tablespace « %s » n'existe pas" -#: commands/tablespace.c:434 +#: commands/tablespace.c:436 #, c-format msgid "tablespace \"%s\" does not exist, skipping" msgstr "le tablespace « %s » n'existe pas, poursuite du traitement" -#: commands/tablespace.c:510 +#: commands/tablespace.c:512 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "le tablespace « %s » n'est pas vide" -#: commands/tablespace.c:582 +#: commands/tablespace.c:584 #, c-format msgid "directory \"%s\" does not exist" msgstr "le répertoire « %s » n'existe pas" -#: commands/tablespace.c:583 +#: commands/tablespace.c:585 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "Créer le répertoire pour ce tablespace avant de redémarrer le serveur." -#: commands/tablespace.c:588 +#: commands/tablespace.c:590 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "n'a pas pu configurer les droits du répertoire « %s » : %m" -#: commands/tablespace.c:618 +#: commands/tablespace.c:620 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "répertoire « %s » déjà utilisé comme tablespace" -#: commands/tablespace.c:742 commands/tablespace.c:755 commands/tablespace.c:791 commands/tablespace.c:883 +#: commands/tablespace.c:705 commands/tablespace.c:715 postmaster/postmaster.c:1477 storage/file/fd.c:2714 storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" + +#: commands/tablespace.c:744 commands/tablespace.c:757 commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3144 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "n'a pas pu supprimer le répertoire « %s » : %m" -#: commands/tablespace.c:804 commands/tablespace.c:892 +#: commands/tablespace.c:806 commands/tablespace.c:894 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "n'a pas pu supprimer le lien symbolique « %s » : %m" -#: commands/tablespace.c:814 commands/tablespace.c:901 +#: commands/tablespace.c:816 commands/tablespace.c:903 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "« %s » n'est pas un répertoire ou un lien symbolique" -#: commands/tablespace.c:1086 +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "Le tablespace « %s » n'existe pas." -#: commands/tablespace.c:1513 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "les répertoires du tablespace %u n'ont pas pu être supprimés" -#: commands/tablespace.c:1515 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "Vous pouvez supprimer les répertoires manuellement si nécessaire." -#: commands/trigger.c:189 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" msgstr "« %s » est une table" -#: commands/trigger.c:191 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "Les tables ne peuvent pas avoir de triggers INSTEAD OF." -#: commands/trigger.c:198 +#: commands/trigger.c:237 #, c-format -msgid "Partitioned tables cannot have ROW triggers." -msgstr "Les tables partitionnées ne peuvent pas avoir de triggers ROW." +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "Les tables partitionnées ne peuvent pas avoir de triggers BEFORE / FOR EACH ROW." -#: commands/trigger.c:209 commands/trigger.c:216 commands/trigger.c:369 +#: commands/trigger.c:255 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Les triggers sur les tables partitionnées ne peuvent pas avoir de tables de transition." + +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" msgstr "« %s » est une vue" -#: commands/trigger.c:211 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "Les vues ne peuvent pas avoir de trigger BEFORE ou AFTER au niveau ligne." -#: commands/trigger.c:218 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "Les vues ne peuvent pas avoir de triggers TRUNCATE." -#: commands/trigger.c:226 commands/trigger.c:233 commands/trigger.c:240 commands/trigger.c:362 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 commands/trigger.c:437 #, c-format msgid "\"%s\" is a foreign table" msgstr "« %s » est une table distante" -#: commands/trigger.c:228 +#: commands/trigger.c:286 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "Les tables distantes ne peuvent pas avoir de triggers INSTEAD OF." -#: commands/trigger.c:235 +#: commands/trigger.c:293 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "Les tables distantes ne peuvent pas avoir de triggers TRUNCATE." -#: commands/trigger.c:242 +#: commands/trigger.c:305 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "Les tables distantes ne peuvent pas avoir de triggers de contrainte." -#: commands/trigger.c:305 +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "les triggers TRUNCATE FOR EACH ROW ne sont pas supportés" -#: commands/trigger.c:313 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "les triggers INSTEAD OF doivent être FOR EACH ROW" -#: commands/trigger.c:317 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "les triggers INSTEAD OF ne peuvent pas avoir de conditions WHEN" -#: commands/trigger.c:321 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "les triggers INSTEAD OF ne peuvent pas avoir de liste de colonnes" -#: commands/trigger.c:350 +#: commands/trigger.c:425 #, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" msgstr "le nommage de variable ROW dans la clause REFERENCING n'est pas supportée" -#: commands/trigger.c:351 +#: commands/trigger.c:426 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." msgstr "Utilisez OLD TABLE ou NEW TABLE pour nommer les tables de transition." -#: commands/trigger.c:364 +#: commands/trigger.c:439 #, c-format msgid "Triggers on foreign tables cannot have transition tables." msgstr "Les triggers sur les tables distantes ne peuvent pas avoir de tables de transition." -#: commands/trigger.c:371 +#: commands/trigger.c:446 #, c-format msgid "Triggers on views cannot have transition tables." msgstr "Les triggers sur les vues ne peuvent pas avoir de tables de transition." -#: commands/trigger.c:391 +#: commands/trigger.c:466 #, c-format msgid "ROW triggers with transition tables are not supported on inheritance children" msgstr "les triggers ROW avec des tables de transition ne sont pas supportés sur les filles en héritage" -#: commands/trigger.c:397 +#: commands/trigger.c:472 #, c-format msgid "transition table name can only be specified for an AFTER trigger" msgstr "le nom de la table de transition peut seulement être spécifié pour un trigger AFTER" -#: commands/trigger.c:402 +#: commands/trigger.c:477 #, c-format msgid "TRUNCATE triggers with transition tables are not supported" msgstr "les triggers TRUNCATE avec des tables de transition ne sont pas supportés" -#: commands/trigger.c:419 +#: commands/trigger.c:494 #, c-format -msgid "Transition tables cannot be specified for triggers with more than one event" -msgstr "Les tables de transition ne peuvent pas être spécifiées pour les triggers avec plus d'un événement" +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "les tables de transition ne peuvent pas être spécifiées pour les triggers avec plus d'un événement" -#: commands/trigger.c:427 +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "les tables de transition ne peuvent pas être spécifiées pour les triggers avec des listes de colonnes" + +#: commands/trigger.c:522 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" msgstr "OLD TABLE peut seulement être spécifié pour un trigger INSERT ou UPDATE" -#: commands/trigger.c:432 +#: commands/trigger.c:527 #, c-format msgid "NEW TABLE cannot be specified multiple times" msgstr "NEW TABLE ne peut pas être spécifié plusieurs fois" -#: commands/trigger.c:442 +#: commands/trigger.c:537 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" msgstr "OLD TABLE peut seulement être spécifié pour un trigger DELETE ou UPDATE" -#: commands/trigger.c:447 +#: commands/trigger.c:542 #, c-format msgid "OLD TABLE cannot be specified multiple times" msgstr "OLD TABLE ne peut pas être spécifié plusieurs fois" -#: commands/trigger.c:457 +#: commands/trigger.c:552 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" msgstr "les noms de OLD TABLE et NEW TABLE ne peuvent pas être identiques" -#: commands/trigger.c:514 commands/trigger.c:527 +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "" "la condition WHEN de l'instruction du trigger ne peut pas référencer les valeurs\n" "des colonnes" -#: commands/trigger.c:519 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "la condition WHEN du trigger INSERT ne peut pas référencer les valeurs OLD" -#: commands/trigger.c:532 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "la condition WHEN du trigger DELETE ne peut pas référencer les valeurs NEW" -#: commands/trigger.c:537 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "" "la condition WHEN d'un trigger BEFORE ne doit pas référencer les colonnes\n" "système avec NEW" -#: commands/trigger.c:702 commands/trigger.c:1473 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "le trigger « %s » de la relation « %s » existe déjà" -#: commands/trigger.c:998 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "Trigger UPDATE de la table référencée trouvé." -#: commands/trigger.c:999 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "Trigger DELETE de la table référencée trouvé." -#: commands/trigger.c:1000 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "Trigger de la table référencée trouvé." -#: commands/trigger.c:1109 commands/trigger.c:1125 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "ignore le groupe de trigger incomplet pour la contrainte « %s » %s" -#: commands/trigger.c:1138 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "conversion du groupe de trigger en une contrainte « %s » %s" -#: commands/trigger.c:1359 commands/trigger.c:1518 commands/trigger.c:1633 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "le trigger « %s » de la table « %s » n'existe pas" -#: commands/trigger.c:1601 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "droit refusé : « %s » est un trigger système" -#: commands/trigger.c:2270 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "la fonction trigger %u a renvoyé la valeur NULL" -#: commands/trigger.c:2331 commands/trigger.c:2541 commands/trigger.c:2755 commands/trigger.c:3040 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "le trigger BEFORE STATEMENT ne peut pas renvoyer une valeur" -#: commands/trigger.c:3102 executor/nodeModifyTable.c:795 executor/nodeModifyTable.c:1092 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 executor/nodeModifyTable.c:1244 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "la ligne à mettre à jour était déjà modifiée par une opération déclenchée par la commande courante" -#: commands/trigger.c:3103 executor/nodeModifyTable.c:796 executor/nodeModifyTable.c:1093 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 executor/nodeModifyTable.c:1245 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Considérez l'utilisation d'un trigger AFTER au lieu d'un trigger BEFORE pour propager les changements sur les autres lignes." -#: commands/trigger.c:3117 executor/execMain.c:2667 executor/nodeLockRows.c:220 executor/nodeModifyTable.c:214 executor/nodeModifyTable.c:808 executor/nodeModifyTable.c:1105 executor/nodeModifyTable.c:1272 +#: commands/trigger.c:3320 executor/execMain.c:2727 executor/nodeLockRows.c:220 executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" msgstr "n'a pas pu sérialiser un accès à cause d'une mise à jour en parallèle" -#: commands/trigger.c:4983 +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 executor/nodeLockRows.c:224 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "la ligne à verrouillée était déjà déplacée dans une autre partition du fait d'une mise à jour concurrente" + +#: commands/trigger.c:5457 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "la contrainte « %s » n'est pas DEFERRABLE" -#: commands/trigger.c:5006 +#: commands/trigger.c:5480 #, c-format msgid "constraint \"%s\" does not exist" msgstr "la contrainte « %s » n'existe pas" @@ -9698,316 +10129,316 @@ msgstr "ne peut pas spécifier à la fois PARSER et COPY" msgid "text search parser is required" msgstr "l'analyseur de la recherche plein texte est requis" -#: commands/tsearchcmds.c:1266 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "le type de jeton « %s » n'existe pas" -#: commands/tsearchcmds.c:1487 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "la correspondance pour le type de jeton « %s » n'existe pas" -#: commands/tsearchcmds.c:1493 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "" "la correspondance pour le type de jeton « %s » n'existe pas, poursuite du\n" "traitement" -#: commands/tsearchcmds.c:1648 commands/tsearchcmds.c:1759 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "format de liste de paramètres invalide : « %s »" -#: commands/typecmds.c:183 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" msgstr "doit être super-utilisateur pour créer un type de base" -#: commands/typecmds.c:290 commands/typecmds.c:1414 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "attribut du type « %s » non reconnu" -#: commands/typecmds.c:346 +#: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "catégorie de type « %s » invalide : doit être de l'ASCII pur" -#: commands/typecmds.c:365 +#: commands/typecmds.c:362 #, c-format msgid "array element type cannot be %s" msgstr "le type d'élément tableau ne peut pas être %s" -#: commands/typecmds.c:397 +#: commands/typecmds.c:394 #, c-format msgid "alignment \"%s\" not recognized" msgstr "alignement « %s » non reconnu" -#: commands/typecmds.c:414 +#: commands/typecmds.c:411 #, c-format msgid "storage \"%s\" not recognized" msgstr "stockage « %s » non reconnu" -#: commands/typecmds.c:425 +#: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" msgstr "le type d'entrée de la fonction doit être spécifié" -#: commands/typecmds.c:429 +#: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" msgstr "le type de sortie de la fonction doit être spécifié" -#: commands/typecmds.c:434 +#: commands/typecmds.c:431 #, c-format msgid "type modifier output function is useless without a type modifier input function" msgstr "" "la fonction en sortie du modificateur de type est inutile sans une fonction\n" "en entrée du modificateur de type" -#: commands/typecmds.c:464 +#: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" msgstr "le type d'entrée de la fonction %s doit être %s" -#: commands/typecmds.c:481 +#: commands/typecmds.c:478 #, c-format msgid "type output function %s must return type %s" msgstr "le type de sortie de la fonction %s doit être %s" -#: commands/typecmds.c:490 +#: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" msgstr "la fonction receive du type %s doit renvoyer le type %s" -#: commands/typecmds.c:499 +#: commands/typecmds.c:496 #, c-format msgid "type send function %s must return type %s" msgstr "le type de sortie de la fonction d'envoi %s doit être %s" -#: commands/typecmds.c:564 +#: commands/typecmds.c:561 #, c-format msgid "type input function %s should not be volatile" msgstr "la fonction en entrée du type %s ne doit pas être volatile" -#: commands/typecmds.c:569 +#: commands/typecmds.c:566 #, c-format msgid "type output function %s should not be volatile" msgstr "la fonction en entrée du type %s ne doit pas être volatile" -#: commands/typecmds.c:574 +#: commands/typecmds.c:571 #, c-format msgid "type receive function %s should not be volatile" msgstr "la fonction receive du type %s ne doit pas être volatile" -#: commands/typecmds.c:579 +#: commands/typecmds.c:576 #, c-format msgid "type send function %s should not be volatile" msgstr "la fonction send du type %s ne doit pas être volatile" -#: commands/typecmds.c:584 +#: commands/typecmds.c:581 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "la fonction en entrée du modificateur de type %s ne devrait pas être volatile" -#: commands/typecmds.c:589 +#: commands/typecmds.c:586 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "la fonction en sortie du modificateur de type %s ne devrait pas être volatile" -#: commands/typecmds.c:811 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "« %s » n'est pas un type de base valide pour un domaine" -#: commands/typecmds.c:897 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "multiples expressions par défaut" -#: commands/typecmds.c:959 commands/typecmds.c:968 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "contraintes NULL/NOT NULL en conflit" -#: commands/typecmds.c:984 +#: commands/typecmds.c:986 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "les contraintes CHECK pour les domaines ne peuvent pas être marquées NO INHERIT" -#: commands/typecmds.c:993 commands/typecmds.c:2512 +#: commands/typecmds.c:995 commands/typecmds.c:2585 #, c-format msgid "unique constraints not possible for domains" msgstr "contraintes uniques impossible pour les domaines" -#: commands/typecmds.c:999 commands/typecmds.c:2518 +#: commands/typecmds.c:1001 commands/typecmds.c:2591 #, c-format msgid "primary key constraints not possible for domains" msgstr "contraintes de clé primaire impossible pour les domaines" -#: commands/typecmds.c:1005 commands/typecmds.c:2524 +#: commands/typecmds.c:1007 commands/typecmds.c:2597 #, c-format msgid "exclusion constraints not possible for domains" msgstr "contraintes d'exclusion impossible pour les domaines" -#: commands/typecmds.c:1011 commands/typecmds.c:2530 +#: commands/typecmds.c:1013 commands/typecmds.c:2603 #, c-format msgid "foreign key constraints not possible for domains" msgstr "contraintes de clé étrangère impossible pour les domaines" -#: commands/typecmds.c:1020 commands/typecmds.c:2539 +#: commands/typecmds.c:1022 commands/typecmds.c:2612 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "spécifier des contraintes déferrantes n'est pas supporté par les domaines" -#: commands/typecmds.c:1284 utils/cache/typcache.c:1648 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" msgstr "%s n'est pas un enum" -#: commands/typecmds.c:1422 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "l'attribut du sous-type est requis" -#: commands/typecmds.c:1427 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "le sous-type de l'intervalle ne peut pas être %s" -#: commands/typecmds.c:1446 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "collationnement spécifié pour l'intervalle mais le sous-type ne supporte pas les collationnements" -#: commands/typecmds.c:1680 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "changement du type d'argument de la fonction %s d'« opaque » à « cstring »" -#: commands/typecmds.c:1731 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "changement du type d'argument de la fonction %s d'« opaque » à %s" -#: commands/typecmds.c:1830 +#: commands/typecmds.c:1898 #, c-format msgid "typmod_in function %s must return type %s" msgstr "le type de sortie de la fonction typmod_in %s doit être %s" -#: commands/typecmds.c:1857 +#: commands/typecmds.c:1925 #, c-format msgid "typmod_out function %s must return type %s" msgstr "le type de sortie de la fonction typmod_out %s doit être %s" -#: commands/typecmds.c:1884 +#: commands/typecmds.c:1952 #, c-format msgid "type analyze function %s must return type %s" msgstr "la fonction analyze du type %s doit renvoyer le type %s" -#: commands/typecmds.c:1930 +#: commands/typecmds.c:1998 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "" "Vous devez spécifier une classe d'opérateur pour le type range ou définir une\n" "classe d'opérateur par défaut pour le sous-type." -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" msgstr "la fonction canonical %s du range doit renvoyer le type range" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" msgstr "la fonction canonical %s du range doit être immutable" -#: commands/typecmds.c:2003 +#: commands/typecmds.c:2071 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "" "la fonction %s de calcul de différence pour le sous-type d'un intervalle de\n" "valeur doit renvoyer le type %s" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "" "la fonction %s de calcul de différence pour le sous-type d'un intervalle de\n" "valeur doit être immutable" -#: commands/typecmds.c:2037 +#: commands/typecmds.c:2105 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "les valeurs d'OID du tableau pgtype ne sont pas positionnées en mode de mise à jour binaire" -#: commands/typecmds.c:2340 +#: commands/typecmds.c:2410 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "la colonne « %s » de la table « %s » contient des valeurs NULL" -#: commands/typecmds.c:2453 commands/typecmds.c:2636 +#: commands/typecmds.c:2524 commands/typecmds.c:2709 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "la contrainte « %s » du domaine « %s » n'existe pas" -#: commands/typecmds.c:2457 +#: commands/typecmds.c:2528 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "la contrainte « %s » du domaine « %s » n'existe pas, ignore" -#: commands/typecmds.c:2642 +#: commands/typecmds.c:2716 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "la contrainte « %s » du domaine « %s » n'est pas une contrainte de vérification" -#: commands/typecmds.c:2747 +#: commands/typecmds.c:2822 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "" "la colonne « %s » de la table « %s » contient des valeurs violant la\n" "nouvelle contrainte" -#: commands/typecmds.c:2960 commands/typecmds.c:3165 commands/typecmds.c:3247 commands/typecmds.c:3434 +#: commands/typecmds.c:3050 commands/typecmds.c:3256 commands/typecmds.c:3338 commands/typecmds.c:3525 #, c-format msgid "%s is not a domain" msgstr "%s n'est pas un domaine" -#: commands/typecmds.c:2994 +#: commands/typecmds.c:3083 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "la contrainte « %s » du domaine « %s » existe déjà" -#: commands/typecmds.c:3045 +#: commands/typecmds.c:3134 #, c-format msgid "cannot use table references in domain check constraint" msgstr "" "ne peut pas utiliser les références de table dans la contrainte de\n" "vérification du domaine" -#: commands/typecmds.c:3177 commands/typecmds.c:3259 commands/typecmds.c:3551 +#: commands/typecmds.c:3268 commands/typecmds.c:3350 commands/typecmds.c:3642 #, c-format msgid "%s is a table's row type" msgstr "« %s » est du type ligne de table" -#: commands/typecmds.c:3179 commands/typecmds.c:3261 commands/typecmds.c:3553 +#: commands/typecmds.c:3270 commands/typecmds.c:3352 commands/typecmds.c:3644 #, c-format msgid "Use ALTER TABLE instead." msgstr "Utilisez ALTER TABLE à la place." -#: commands/typecmds.c:3186 commands/typecmds.c:3268 commands/typecmds.c:3466 +#: commands/typecmds.c:3277 commands/typecmds.c:3359 commands/typecmds.c:3557 #, c-format msgid "cannot alter array type %s" msgstr "ne peut pas modifier le type array %s" -#: commands/typecmds.c:3188 commands/typecmds.c:3270 commands/typecmds.c:3468 +#: commands/typecmds.c:3279 commands/typecmds.c:3361 commands/typecmds.c:3559 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Vous pouvez modifier le type %s, ce qui va modifier aussi le type tableau." -#: commands/typecmds.c:3536 +#: commands/typecmds.c:3627 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "le type « %s » existe déjà dans le schéma « %s »" @@ -10027,7 +10458,7 @@ msgstr "doit être super-utilisateur pour créer des super-utilisateurs" msgid "must be superuser to create replication users" msgstr "doit être super-utilisateur pour créer des utilisateurs avec l'attribut réplication" -#: commands/user.c:309 commands/user.c:684 +#: commands/user.c:309 commands/user.c:707 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "doit être super-utilisateur pour modifier l'attribut bypassrls" @@ -10037,326 +10468,358 @@ msgstr "doit être super-utilisateur pour modifier l'attribut bypassrls" msgid "permission denied to create role" msgstr "droit refusé pour créer un rôle" -#: commands/user.c:326 commands/user.c:1160 commands/user.c:1167 gram.y:14465 gram.y:14500 utils/adt/acl.c:5246 utils/adt/acl.c:5252 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 gram.y:14893 gram.y:14931 utils/adt/acl.c:5342 utils/adt/acl.c:5348 #, c-format msgid "role name \"%s\" is reserved" msgstr "le nom du rôle « %s » est réservé" -#: commands/user.c:328 commands/user.c:1162 commands/user.c:1169 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "Les noms de rôle commençant par « pg_ » sont réservés." -#: commands/user.c:340 commands/user.c:1175 +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "le rôle « %s » existe déjà" -#: commands/user.c:414 +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "une chaîne vide n'est pas un mot de passe valide, effacement du mot de passe" + +#: commands/user.c:437 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "la valeur d'OID de pg_authid n'est pas positionnée en mode de mise à jour binaire" -#: commands/user.c:670 commands/user.c:880 commands/user.c:1414 commands/user.c:1558 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" msgstr "doit être super-utilisateur pour modifier des super-utilisateurs" -#: commands/user.c:677 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" msgstr "doit être super-utilisateur pour modifier des utilisateurs ayant l'attribut réplication" -#: commands/user.c:700 commands/user.c:888 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "droit refusé" -#: commands/user.c:918 +#: commands/user.c:953 #, c-format msgid "must be superuser to alter settings globally" msgstr "doit être super-utilisateur pour modifier globalement les configurations" -#: commands/user.c:940 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "droit refusé pour supprimer le rôle" -#: commands/user.c:964 +#: commands/user.c:999 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "ne peut pas être le spécificateur de rôle spécial dans DROP ROLE" -#: commands/user.c:974 commands/user.c:1131 commands/variable.c:822 commands/variable.c:894 utils/adt/acl.c:5104 utils/adt/acl.c:5151 utils/adt/acl.c:5179 utils/adt/acl.c:5197 utils/init/miscinit.c:504 +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "le rôle « %s » n'existe pas" -#: commands/user.c:979 +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "le rôle « %s » n'existe pas, poursuite du traitement" -#: commands/user.c:991 commands/user.c:995 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "l'utilisateur actuel ne peut pas être supprimé" -#: commands/user.c:999 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "l'utilisateur de la session ne peut pas être supprimé" -#: commands/user.c:1010 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" msgstr "doit être super-utilisateur pour supprimer des super-utilisateurs" -#: commands/user.c:1026 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "le rôle « %s » ne peut pas être supprimé car d'autres objets en dépendent" -#: commands/user.c:1147 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "l'utilisateur de la session ne peut pas être renommé" -#: commands/user.c:1151 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "l'utilisateur courant ne peut pas être renommé" -#: commands/user.c:1185 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" msgstr "doit être super-utilisateur pour renommer les super-utilisateurs" -#: commands/user.c:1192 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "droit refusé pour renommer le rôle" -#: commands/user.c:1213 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "mot de passe MD5 effacé à cause du renommage du rôle" -#: commands/user.c:1273 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "les noms de colonne ne peuvent pas être inclus dans GRANT/REVOKE ROLE" -#: commands/user.c:1311 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" msgstr "droit refusé pour supprimer les objets" -#: commands/user.c:1338 commands/user.c:1347 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" msgstr "droit refusé pour ré-affecter les objets" -#: commands/user.c:1422 commands/user.c:1566 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" msgstr "doit avoir l'option admin sur le rôle « %s »" -#: commands/user.c:1439 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" msgstr "doit être super-utilisateur pour configurer le « donneur de droits »" -#: commands/user.c:1464 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "le rôle « %s » est un membre du rôle « %s »" -#: commands/user.c:1479 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "le rôle « %s » est déjà un membre du rôle « %s »" -#: commands/user.c:1588 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "le rôle « %s » n'est pas un membre du rôle « %s »" -#: commands/vacuum.c:186 +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "l'option ANALYZE doit être spécifiée quand une liste de colonne est fournie" + +#: commands/vacuum.c:203 #, c-format msgid "%s cannot be executed from VACUUM or ANALYZE" msgstr "%s ne peut pas être exécuté dans un VACUUM ou un ANALYZE" -#: commands/vacuum.c:196 +#: commands/vacuum.c:213 #, c-format msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" msgstr "" "l'option DISABLE_PAGE_SKIPPING de la commande VACUUM ne pas pas être utilisée\n" "en même temps que l'option FULL" -#: commands/vacuum.c:565 +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "le plus ancien xmin est loin dans le passé" -#: commands/vacuum.c:566 +#: commands/vacuum.c:658 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"Fermez les transactions ouvertes rapidement pour éviter des problèmes de\n" -"réinitialisation." +"Fermer les transactions dès que possible pour éviter des problèmes de rebouclage d'identifiants de transaction.\n" +"Vous pouvez avoir besoin de valider ou d'annuler les anciennes transactions préparées, ou de supprimer les slots de réplication trop anciens." -#: commands/vacuum.c:605 +#: commands/vacuum.c:698 #, c-format msgid "oldest multixact is far in the past" msgstr "le plus ancien multixact est loin dans le passé" -#: commands/vacuum.c:606 +#: commands/vacuum.c:699 #, c-format msgid "Close open transactions with multixacts soon to avoid wraparound problems." msgstr "" "Fermez les transactions ouvertes avec multixacts rapidement pour éviter des problèmes de\n" "réinitialisation." -#: commands/vacuum.c:1176 +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" msgstr "" "certaines bases de données n'ont pas eu droit à l'opération de maintenance\n" "VACUUM depuis plus de 2 milliards de transactions" -#: commands/vacuum.c:1177 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "" "Vous pouvez avoir déjà souffert de pertes de données suite à une\n" "réinitialisation de l'identifiant des transactions." -#: commands/vacuum.c:1306 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" msgstr "ignore le vacuum de « %s » --- verrou non disponible" -#: commands/vacuum.c:1332 +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "ignore le vacuum de « %s » --- la relation n'existe plus" + +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "ignore « %s » --- seul le super-utilisateur peut exécuter un VACUUM" -#: commands/vacuum.c:1336 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "" "ignore « %s » --- seul le super-utilisateur ou le propriétaire de la base de données\n" "peuvent exécuter un VACUUM" -#: commands/vacuum.c:1340 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "" "ignore « %s » --- seul le propriétaire de la table ou de la base de données\n" "peut exécuter un VACUUM" -#: commands/vacuum.c:1359 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" msgstr "" "ignore « %s » --- n'a pas pu exécuter un VACUUM sur les objets autres que\n" "des tables et les tables systèmes" -#: commands/vacuumlazy.c:376 +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "VACUUM aggressif automatique de la table « %s.%s.%s » : %d parcours d'index\n" + +#: commands/vacuumlazy.c:380 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" msgstr "VACUUM automatique de la table « %s.%s.%s » : %d parcours d'index\n" -#: commands/vacuumlazy.c:381 +#: commands/vacuumlazy.c:386 #, c-format msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" msgstr "pages : %u supprimées, %u restants, %u ignorées à cause de verrous; %u ignorées car gelées\n" -#: commands/vacuumlazy.c:387 +#: commands/vacuumlazy.c:392 #, c-format msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" msgstr "lignes : %.0f supprimées, %.0f restantes, %.0f sont mortes mais pas encore supprimables, plus ancien xmin : %u\n" -#: commands/vacuumlazy.c:393 +#: commands/vacuumlazy.c:398 #, c-format msgid "buffer usage: %d hits, %d misses, %d dirtied\n" msgstr "utilisation du tampon : %d récupérées, %d ratées, %d modifiées\n" -#: commands/vacuumlazy.c:397 +#: commands/vacuumlazy.c:402 #, c-format msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" msgstr "taux moyen de lecture : %.3f Mo/s, taux moyen d'écriture : %.3f Mo/s\n" -#: commands/vacuumlazy.c:399 +#: commands/vacuumlazy.c:404 #, c-format msgid "system usage: %s" msgstr "utilisation du système : %s" -#: commands/vacuumlazy.c:858 +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "exécution d'un VACUUM aggressif sur « %s.%s »" + +#: commands/vacuumlazy.c:881 #, c-format msgid "relation \"%s\" page %u is uninitialized --- fixing" msgstr "relation « %s » : la page %u n'est pas initialisée --- correction en cours" -#: commands/vacuumlazy.c:1328 +#: commands/vacuumlazy.c:1417 #, c-format msgid "\"%s\": removed %.0f row versions in %u pages" msgstr "« %s » : %.0f versions de ligne supprimées parmi %u pages" -#: commands/vacuumlazy.c:1338 +#: commands/vacuumlazy.c:1427 #, c-format msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" msgstr "%.0f versions de lignes mortes ne peuvent pas encore être supprimées, plus ancien xmin : %u\n" -#: commands/vacuumlazy.c:1340 +#: commands/vacuumlazy.c:1429 #, c-format msgid "There were %.0f unused item pointers.\n" msgstr "Il y avait %.0f pointeurs d'éléments inutilisés.\n" -#: commands/vacuumlazy.c:1342 +#: commands/vacuumlazy.c:1431 #, c-format msgid "Skipped %u page due to buffer pins, " msgid_plural "Skipped %u pages due to buffer pins, " msgstr[0] "Ignore %u page à cause des verrous de blocs, " msgstr[1] "Ignore %u pages à cause des verrous de blocs, " -#: commands/vacuumlazy.c:1346 +#: commands/vacuumlazy.c:1435 #, c-format msgid "%u frozen page.\n" msgid_plural "%u frozen pages.\n" msgstr[0] "%u page gelée.\n" msgstr[1] "%u pages gelées.\n" -#: commands/vacuumlazy.c:1350 +#: commands/vacuumlazy.c:1439 #, c-format msgid "%u page is entirely empty.\n" msgid_plural "%u pages are entirely empty.\n" msgstr[0] "%u page est entièrement vide.\n" msgstr[1] "%u pages sont entièrement vides.\n" -#: commands/vacuumlazy.c:1357 +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" msgstr "" "« %s » : %.0f versions de ligne supprimables, %.0f non supprimables\n" "parmi %u pages sur %u" -#: commands/vacuumlazy.c:1426 +#: commands/vacuumlazy.c:1515 #, c-format msgid "\"%s\": removed %d row versions in %d pages" msgstr "« %s »: %d versions de ligne supprimée parmi %d pages" -#: commands/vacuumlazy.c:1614 +#: commands/vacuumlazy.c:1704 #, c-format msgid "scanned index \"%s\" to remove %d row versions" msgstr "a parcouru l'index « %s » pour supprimer %d versions de lignes" -#: commands/vacuumlazy.c:1660 +#: commands/vacuumlazy.c:1756 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "l'index « %s » contient maintenant %.0f versions de ligne dans %u pages" -#: commands/vacuumlazy.c:1664 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -10367,22 +10830,22 @@ msgstr "" "%u pages d'index ont été supprimées, %u sont actuellement réutilisables.\n" "%s." -#: commands/vacuumlazy.c:1759 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" msgstr "« %s » : mis en suspens du tronquage à cause d'un conflit dans la demande de verrou" -#: commands/vacuumlazy.c:1824 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "« %s » : %u pages tronqués en %u" -#: commands/vacuumlazy.c:1889 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" msgstr "« %s » : mis en suspens du tronquage à cause d'un conflit dans la demande de verrou" -#: commands/variable.c:165 utils/misc/guc.c:10030 utils/misc/guc.c:10092 +#: commands/variable.c:165 utils/misc/guc.c:10311 utils/misc/guc.c:10373 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "Mot clé non reconnu : « %s »" @@ -10450,7 +10913,7 @@ msgstr "" "SET TRANSACTION ISOLATION LEVEL ne doit pas être appelé dans une\n" "sous-transaction" -#: commands/variable.c:571 storage/lmgr/predicate.c:1647 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "ne peut pas utiliser le mode sérialisable sur un serveur en « Hot Standby »" @@ -10502,200 +10965,195 @@ msgstr "valeur invalide pour l'option « check_option »" msgid "Valid values are \"local\" and \"cascaded\"." msgstr "Les valeurs valides sont entre « local » et « cascaded »." -#: commands/view.c:101 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "" "n'a pas pu déterminer le collationnement à utiliser pour la colonne « %s »\n" "de la vue" -#: commands/view.c:115 -#, c-format -msgid "view must have at least one column" -msgstr "la vue doit avoir au moins une colonne" - -#: commands/view.c:281 commands/view.c:293 +#: commands/view.c:280 commands/view.c:292 #, c-format msgid "cannot drop columns from view" msgstr "ne peut pas supprimer les colonnes d'une vue" -#: commands/view.c:298 +#: commands/view.c:297 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "ne peut pas modifier le nom de la colonne « %s » de la vue en « %s »" -#: commands/view.c:306 +#: commands/view.c:305 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "ne peut pas modifier le type de données de la colonne « %s » de la vue de %s à %s" -#: commands/view.c:451 +#: commands/view.c:450 #, c-format msgid "views must not contain SELECT INTO" msgstr "les vues ne peuvent pas contenir SELECT INTO" -#: commands/view.c:463 +#: commands/view.c:462 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "les vues ne peuvent pas contenir d'instructions de modifications de données avec WITH" -#: commands/view.c:533 +#: commands/view.c:532 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "CREATE VIEW spécifie plus de noms de colonnes que de colonnes" -#: commands/view.c:541 +#: commands/view.c:540 #, c-format msgid "views cannot be unlogged because they do not have storage" msgstr "les vues ne peuvent pas être non tracées car elles n'ont pas de stockage" -#: commands/view.c:555 +#: commands/view.c:554 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "la vue « %s » sera une vue temporaire" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:78 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "le curseur « %s » n'est pas une requête SELECT" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:84 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "le curseur « %s » est détenu par une transaction précédente" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:116 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "le curseur « %s » a plusieurs références FOR UPDATE/SHARE pour la table « %s »" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:125 #, c-format msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "le curseur « %s » n'a pas de référence FOR UPDATE/SHARE pour la table « %s »" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:135 executor/execCurrent.c:180 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "le curseur « %s » n'est pas positionné sur une ligne" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:167 executor/execCurrent.c:226 executor/execCurrent.c:238 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "le curseur « %s » n'est pas un parcours modifiable de la table « %s »" -#: executor/execCurrent.c:231 executor/execExprInterp.c:1889 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "le type de paramètre %d (%s) ne correspond pas à ce qui est préparé dans le plan (%s)" -#: executor/execCurrent.c:243 executor/execExprInterp.c:1901 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 #, c-format msgid "no value found for parameter %d" msgstr "aucune valeur trouvée pour le paramètre %d" -#: executor/execExpr.c:780 parser/parse_agg.c:779 +#: executor/execExpr.c:856 parser/parse_agg.c:794 #, c-format msgid "window function calls cannot be nested" msgstr "les appels à la fonction window ne peuvent pas être imbriqués" -#: executor/execExpr.c:1236 +#: executor/execExpr.c:1314 #, c-format msgid "target type is not an array" msgstr "le type cible n'est pas un tableau" -#: executor/execExpr.c:1559 +#: executor/execExpr.c:1647 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "une colonne ROW() a le type %s au lieu du type %s" -#: executor/execExpr.c:2094 executor/execSRF.c:670 parser/parse_func.c:120 parser/parse_func.c:547 parser/parse_func.c:921 +#: executor/execExpr.c:2182 executor/execSRF.c:697 parser/parse_func.c:126 parser/parse_func.c:640 parser/parse_func.c:1014 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" msgstr[0] "ne peut pas passer plus de %d argument à une fonction" msgstr[1] "ne peut pas passer plus de %d arguments à une fonction" -#: executor/execExpr.c:2371 executor/execExpr.c:2377 executor/execExprInterp.c:2226 utils/adt/arrayfuncs.c:260 utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5239 utils/adt/arrayfuncs.c:5756 +#: executor/execExpr.c:2480 executor/execExpr.c:2486 executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 utils/adt/arrayfuncs.c:5820 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "le nombre de dimensions du tableau (%d) dépasse le maximum autorisé (%d)" -#: executor/execExprInterp.c:1561 +#: executor/execExprInterp.c:1879 #, c-format msgid "attribute %d of type %s has been dropped" msgstr "l'attribut %d du type %s a été supprimé" -#: executor/execExprInterp.c:1567 +#: executor/execExprInterp.c:1885 #, c-format msgid "attribute %d of type %s has wrong type" msgstr "l'attribut %d de type %s a un mauvais type" -#: executor/execExprInterp.c:1569 executor/execExprInterp.c:2512 +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 executor/execExprInterp.c:2933 #, c-format msgid "Table has type %s, but query expects %s." msgstr "La table a le type %s alors que la requête attend %s." -#: executor/execExprInterp.c:1979 +#: executor/execExprInterp.c:2374 #, c-format msgid "WHERE CURRENT OF is not supported for this table type" msgstr "WHERE CURRENT OF n'est pas supporté pour ce type de table" -#: executor/execExprInterp.c:2204 +#: executor/execExprInterp.c:2591 #, c-format msgid "cannot merge incompatible arrays" msgstr "ne peut pas fusionner les tableaux incompatibles" -#: executor/execExprInterp.c:2205 +#: executor/execExprInterp.c:2592 #, c-format msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." msgstr "Le tableau avec le type d'élément %s ne peut pas être inclus dans la construction ARRAY avec le type d'élément %s." -#: executor/execExprInterp.c:2246 executor/execExprInterp.c:2276 +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "" "les tableaux multidimensionnels doivent avoir des expressions de tableaux\n" "avec les dimensions correspondantes" -#: executor/execExprInterp.c:2511 +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 #, c-format msgid "attribute %d has wrong type" msgstr "l'attribut %d a un type invalide" -#: executor/execExprInterp.c:2620 +#: executor/execExprInterp.c:3042 #, c-format msgid "array subscript in assignment must not be null" msgstr "l'indice du tableau dans l'affectation ne doit pas être NULL" -#: executor/execExprInterp.c:3053 utils/adt/domains.c:148 +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 #, c-format msgid "domain %s does not allow null values" msgstr "le domaine %s n'autorise pas les valeurs NULL" -#: executor/execExprInterp.c:3068 utils/adt/domains.c:183 +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 #, c-format msgid "value for domain %s violates check constraint \"%s\"" msgstr "la valeur pour le domaine %s viole la contrainte de vérification « %s »" -#: executor/execExprInterp.c:3435 executor/execExprInterp.c:3452 executor/execExprInterp.c:3554 executor/nodeModifyTable.c:96 executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:123 executor/nodeModifyTable.c:131 +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 executor/nodeModifyTable.c:142 #, c-format msgid "table row type and query-specified row type do not match" msgstr "Le type de ligne de la table et celui spécifié par la requête ne correspondent pas" -#: executor/execExprInterp.c:3436 +#: executor/execExprInterp.c:3862 #, c-format msgid "Table row contains %d attribute, but query expects %d." msgid_plural "Table row contains %d attributes, but query expects %d." msgstr[0] "La ligne de la table contient %d attribut alors que la requête en attend %d." msgstr[1] "La ligne de la table contient %d attributs alors que la requête en attend %d." -#: executor/execExprInterp.c:3453 executor/nodeModifyTable.c:107 +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "La table a le type %s à la position ordinale %d alors que la requête attend %s." -#: executor/execExprInterp.c:3555 executor/execSRF.c:925 +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 #, c-format msgid "Physical storage mismatch on dropped attribute at ordinal position %d." msgstr "" @@ -10737,202 +11195,207 @@ msgstr "La clé %s est en conflit avec la clé existante %s." msgid "Key conflicts with existing key." msgstr "La clé est en conflit avec une clé existante." -#: executor/execMain.c:1113 +#: executor/execMain.c:1116 #, c-format msgid "cannot change sequence \"%s\"" msgstr "ne peut pas modifier la séquence « %s »" -#: executor/execMain.c:1119 +#: executor/execMain.c:1122 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "ne peut pas modifier la relation TOAST « %s »" -#: executor/execMain.c:1137 rewrite/rewriteHandler.c:2738 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2879 #, c-format msgid "cannot insert into view \"%s\"" msgstr "ne peut pas insérer dans la vue « %s »" -#: executor/execMain.c:1139 rewrite/rewriteHandler.c:2741 +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2882 #, c-format msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." msgstr "Pour activer l'insertion dans la vue, fournissez un trigger INSTEAD OF INSERT ou une règle ON INSERT DO INSTEAD sans condition." -#: executor/execMain.c:1145 rewrite/rewriteHandler.c:2746 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2887 #, c-format msgid "cannot update view \"%s\"" msgstr "ne peut pas mettre à jour la vue « %s »" -#: executor/execMain.c:1147 rewrite/rewriteHandler.c:2749 +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2890 #, c-format msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." msgstr "Pour activer la mise à jour dans la vue, fournissez un trigger INSTEAD OF UPDATE ou une règle ON UPDATE DO INSTEAD sans condition." -#: executor/execMain.c:1153 rewrite/rewriteHandler.c:2754 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2895 #, c-format msgid "cannot delete from view \"%s\"" msgstr "ne peut pas supprimer à partir de la vue « %s »" -#: executor/execMain.c:1155 rewrite/rewriteHandler.c:2757 +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2898 #, c-format msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." msgstr "Pour activer la suppression dans la vue, fournissez un trigger INSTEAD OF DELETE ou une règle ON DELETE DO INSTEAD sans condition." -#: executor/execMain.c:1166 +#: executor/execMain.c:1169 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "ne peut pas modifier la vue matérialisée « %s »" -#: executor/execMain.c:1178 +#: executor/execMain.c:1181 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "ne peut pas insérer dans la table distante « %s »" -#: executor/execMain.c:1184 +#: executor/execMain.c:1187 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "la table distante « %s » n'autorise pas les insertions" -#: executor/execMain.c:1191 +#: executor/execMain.c:1194 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "ne peut pas modifier la table distante « %s »" -#: executor/execMain.c:1197 +#: executor/execMain.c:1200 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "la table distante « %s » n'autorise pas les modifications" -#: executor/execMain.c:1204 +#: executor/execMain.c:1207 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "ne peut pas supprimer à partir de la table distante « %s »" -#: executor/execMain.c:1210 +#: executor/execMain.c:1213 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "la table distante « %s » n'autorise pas les suppressions" -#: executor/execMain.c:1221 +#: executor/execMain.c:1224 #, c-format msgid "cannot change relation \"%s\"" msgstr "ne peut pas modifier la relation « %s »" -#: executor/execMain.c:1248 +#: executor/execMain.c:1251 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "ne peut pas verrouiller les lignes dans la séquence « %s »" -#: executor/execMain.c:1255 +#: executor/execMain.c:1258 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "ne peut pas verrouiller les lignes dans la relation TOAST « %s »" -#: executor/execMain.c:1262 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "ne peut pas verrouiller les lignes dans la vue « %s »" -#: executor/execMain.c:1270 +#: executor/execMain.c:1273 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "ne peut pas verrouiller les lignes dans la vue matérialisée « %s »" -#: executor/execMain.c:1279 executor/execMain.c:2901 executor/nodeLockRows.c:136 +#: executor/execMain.c:1282 executor/execMain.c:2974 executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "ne peut pas verrouiller la table distante « %s »" -#: executor/execMain.c:1285 +#: executor/execMain.c:1288 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "n'a pas pu verrouiller les lignes dans la relation « %s »" -#: executor/execMain.c:1897 +#: executor/execMain.c:1959 #, c-format msgid "new row for relation \"%s\" violates partition constraint" msgstr "la nouvelle ligne de la relation « %s » viole la contrainte de partitionnement" -#: executor/execMain.c:1899 executor/execMain.c:1978 executor/execMain.c:2025 executor/execMain.c:2136 +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 executor/execMain.c:2195 #, c-format msgid "Failing row contains %s." msgstr "La ligne en échec contient %s" -#: executor/execMain.c:1976 +#: executor/execMain.c:2039 #, c-format msgid "null value in column \"%s\" violates not-null constraint" msgstr "une valeur NULL viole la contrainte NOT NULL de la colonne « %s »" -#: executor/execMain.c:2023 +#: executor/execMain.c:2086 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgstr "la nouvelle ligne viole la contrainte de vérification « %s » de la relation « %s »" +msgstr "la nouvelle ligne de la relation « %s » viole la contrainte de vérification « %s »" -#: executor/execMain.c:2134 +#: executor/execMain.c:2193 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "la nouvelle ligne viole la contrainte de vérification pour la vue « %s »" -#: executor/execMain.c:2144 +#: executor/execMain.c:2203 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne « %s » pour la table « %s »" -#: executor/execMain.c:2149 +#: executor/execMain.c:2208 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne pour la table « %s »" -#: executor/execMain.c:2156 +#: executor/execMain.c:2215 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne « %s » (expression USING) pour la table « %s »" -#: executor/execMain.c:2161 +#: executor/execMain.c:2220 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "la nouvelle ligne viole la politique de sécurité au niveau ligne (expression USING) pour la table « %s »" -#: executor/execMain.c:3363 +#: executor/execPartition.c:346 #, c-format msgid "no partition of relation \"%s\" found for row" msgstr "aucune partition de la relation « %s » trouvée pour la ligne" -#: executor/execMain.c:3365 +#: executor/execPartition.c:348 #, c-format msgid "Partition key of the failing row contains %s." msgstr "La clé de partitionnement de la ligne en échec contient %s." -#: executor/execReplication.c:196 executor/execReplication.c:354 +#: executor/execReplication.c:197 executor/execReplication.c:356 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "la ligne à verrouiller était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente, nouvelle tentative" + +#: executor/execReplication.c:201 executor/execReplication.c:360 #, c-format msgid "concurrent update, retrying" msgstr "mise à jour concurrente, nouvelle tentative" -#: executor/execReplication.c:256 parser/parse_oper.c:228 utils/adt/array_userfuncs.c:724 utils/adt/array_userfuncs.c:863 utils/adt/arrayfuncs.c:3639 utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6037 utils/adt/rowtypes.c:1167 +#: executor/execReplication.c:257 parser/parse_oper.c:228 utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 #, c-format msgid "could not identify an equality operator for type %s" msgstr "n'a pas pu identifier un opérateur d'égalité pour le type %s" -#: executor/execReplication.c:562 +#: executor/execReplication.c:573 #, c-format -msgid "cannot update table \"%s\" because it does not have replica identity and publishes updates" +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" msgstr "ne peut pas mettre à jour la table « %s » car elle n'a pas d'identité de réplicat et publie des mises à jour" -#: executor/execReplication.c:564 +#: executor/execReplication.c:575 #, c-format msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." msgstr "Pour activer les mises à jour sur la table, configurez REPLICA IDENTITY en utilisant ALTER TABLE" -#: executor/execReplication.c:568 +#: executor/execReplication.c:579 #, c-format -msgid "cannot delete from table \"%s\" because it does not have replica identity and publishes deletes" -msgstr "ne peut pas supprimer à partir de la table « %s » car elle n'a pas d'identité de réplicat et publie des mises à jour" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "ne peut pas supprimer à partir de la table « %s » car elle n'a pas d'identité de réplicat et publie des suppressions" -#: executor/execReplication.c:570 +#: executor/execReplication.c:581 #, c-format msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." msgstr "Pour activer les suppressions sur la table, configurez REPLICA IDENTITY en utilisant ALTER TABLE" -#: executor/execReplication.c:589 +#: executor/execReplication.c:600 #, c-format msgid "logical replication target relation \"%s.%s\" is not a table" msgstr "la relation cible de la réplication logique « %s.%s » n'est pas une table" @@ -10942,46 +11405,46 @@ msgstr "la relation cible de la réplication logique « %s.%s » n'est pas une t msgid "rows returned by function are not all of the same row type" msgstr "les lignes renvoyées par la fonction ne sont pas toutes du même type ligne" -#: executor/execSRF.c:356 executor/execSRF.c:620 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "le protocole de la fonction table pour le mode matérialisé n'a pas été respecté" -#: executor/execSRF.c:363 executor/execSRF.c:638 +#: executor/execSRF.c:363 executor/execSRF.c:665 #, c-format msgid "unrecognized table-function returnMode: %d" msgstr "returnMode de la fonction table non reconnu : %d" -#: executor/execSRF.c:843 +#: executor/execSRF.c:871 #, c-format msgid "function returning setof record called in context that cannot accept type record" msgstr "" "la fonction renvoyant des lignes a été appelée dans un contexte qui\n" "n'accepte pas un ensemble" -#: executor/execSRF.c:898 executor/execSRF.c:914 executor/execSRF.c:924 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format msgid "function return row and query-specified return row do not match" msgstr "la ligne de retour spécifiée par la requête et la ligne de retour de la fonction ne correspondent pas" -#: executor/execSRF.c:899 +#: executor/execSRF.c:927 #, c-format msgid "Returned row contains %d attribute, but query expects %d." msgid_plural "Returned row contains %d attributes, but query expects %d." msgstr[0] "La ligne renvoyée contient %d attribut mais la requête en attend %d." msgstr[1] "La ligne renvoyée contient %d attributs mais la requête en attend %d." -#: executor/execSRF.c:915 +#: executor/execSRF.c:943 #, c-format msgid "Returned type %s at ordinal position %d, but query expects %s." msgstr "A renvoyé le type %s à la position ordinale %d, mais la requête attend %s." -#: executor/execUtils.c:639 +#: executor/execUtils.c:687 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "la vue matérialisée « %s » n'a pas été peuplée" -#: executor/execUtils.c:641 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Utilisez la commande REFRESH MATERIALIZED VIEW." @@ -10991,115 +11454,115 @@ msgstr "Utilisez la commande REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "n'a pas pu déterminer le type actuel de l'argument déclaré %s" -#: executor/functions.c:520 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "ne peut pas utiliser COPY TO/FROM dans une fonction SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:526 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s n'est pas autorisé dans une fonction SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:534 executor/spi.c:1282 executor/spi.c:2069 +#: executor/functions.c:535 executor/spi.c:1422 executor/spi.c:2212 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s n'est pas autorisé dans une fonction non volatile" -#: executor/functions.c:654 +#: executor/functions.c:656 #, c-format msgid "could not determine actual result type for function declared to return type %s" msgstr "" "n'a pas pu déterminer le type du résultat actuel pour la fonction déclarant\n" "renvoyer le type %s" -#: executor/functions.c:1413 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "fonction SQL « %s », instruction %d" -#: executor/functions.c:1439 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "fonction SQL « %s » lors du lancement" -#: executor/functions.c:1597 executor/functions.c:1634 executor/functions.c:1646 executor/functions.c:1759 executor/functions.c:1792 executor/functions.c:1822 +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "l'appel à des procédures avec des arguments en sortie n'est pas supporté dans les fonctions SQL" + +#: executor/functions.c:1657 executor/functions.c:1690 executor/functions.c:1702 executor/functions.c:1826 executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "le type de retour ne correspond pas à la fonction déclarant renvoyer %s" -#: executor/functions.c:1599 +#: executor/functions.c:1659 #, c-format msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." msgstr "" "L'instruction finale de la fonction doit être un SELECT ou un\n" "INSERT/UPDATE/DELETE RETURNING." -#: executor/functions.c:1636 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." msgstr "L'instruction finale doit renvoyer exactement une colonne." -#: executor/functions.c:1648 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." msgstr "Le code de retour réel est %s." -#: executor/functions.c:1761 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "L'instruction finale renvoie beaucoup trop de colonnes." -#: executor/functions.c:1794 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "L'instruction finale renvoie %s au lieu de %s pour la colonne %d." -#: executor/functions.c:1824 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "L'instruction finale renvoie trop peu de colonnes." -#: executor/functions.c:1873 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "le type de retour %s n'est pas supporté pour les fonctions SQL" -#: executor/nodeAgg.c:3480 +#: executor/nodeAgg.c:2806 parser/parse_agg.c:633 parser/parse_agg.c:663 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "la fonction d'unification pour l'aggrégat %u doit être déclarée comme STRICT" +msgid "aggregate function calls cannot be nested" +msgstr "les appels à la fonction d'agrégat ne peuvent pas être imbriqués" -#: executor/nodeAgg.c:3525 executor/nodeWindowAgg.c:2282 +#: executor/nodeAgg.c:2992 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "" "L'agrégat %u a besoin d'avoir un type en entrée compatible avec le type en\n" "transition" -#: executor/nodeAgg.c:3579 parser/parse_agg.c:618 parser/parse_agg.c:648 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "les appels à la fonction d'agrégat ne peuvent pas être imbriqués" - -#: executor/nodeCustom.c:152 executor/nodeCustom.c:163 +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "le parcours personnalisé « %s » ne supporte pas MarkPos" -#: executor/nodeHashjoin.c:770 executor/nodeHashjoin.c:800 +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "n'a pas pu revenir au début du fichier temporaire de la jointure hâchée : %m" -#: executor/nodeHashjoin.c:835 executor/nodeHashjoin.c:841 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "n'a pas pu écrire le fichier temporaire de la jointure hâchée : %m" -#: executor/nodeHashjoin.c:882 executor/nodeHashjoin.c:892 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "n'a pas pu lire le fichier temporaire contenant la jointure hâchée : %m" @@ -11109,160 +11572,200 @@ msgstr "n'a pas pu lire le fichier temporaire contenant la jointure hâchée : % msgid "lossy distance functions are not supported in index-only scans" msgstr "les fonctions de distance à perte ne sont pas supportés dans les parcours d'index seul" -#: executor/nodeLimit.c:256 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET ne doit pas être négatif" -#: executor/nodeLimit.c:282 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT ne doit pas être négative" -#: executor/nodeMergejoin.c:1559 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOIN est supporté seulement avec les conditions de jointures MERGE" -#: executor/nodeMergejoin.c:1579 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOIN est supporté seulement avec les conditions de jointures MERGE" -#: executor/nodeModifyTable.c:97 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "La requête a trop de colonnes." -#: executor/nodeModifyTable.c:124 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "" "La requête fournit une valeur pour une colonne supprimée à la position\n" "ordinale %d." -#: executor/nodeModifyTable.c:132 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." msgstr "La requête n'a pas assez de colonnes." -#: executor/nodeModifyTable.c:1253 +#: executor/nodeModifyTable.c:773 +#, c-format +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "la ligne à supprimer était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente" + +#: executor/nodeModifyTable.c:1085 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "spécification ON UPDATE invalide" + +#: executor/nodeModifyTable.c:1086 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "La ligne résultante apparaîtrait dans une partition différente de la ligne originale." + +#: executor/nodeModifyTable.c:1261 +#, c-format +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "la ligne à mettre à jour était déjà déplacée vers une autre partition du fait d'une mise à jour concurrente, nouvelle tentative" + +#: executor/nodeModifyTable.c:1412 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "la commande ON CONFLICT DO UPDATE ne peut pas affecter une ligne la deuxième fois" -#: executor/nodeModifyTable.c:1254 +#: executor/nodeModifyTable.c:1413 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "S'assure qu'aucune ligne proposée à l'insertion dans la même commande n'a de valeurs contraintes dupliquées." -#: executor/nodeSamplescan.c:301 +#: executor/nodeSamplescan.c:279 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "le paramètre de TABLESAMPLE ne peut pas être NULL" -#: executor/nodeSamplescan.c:313 +#: executor/nodeSamplescan.c:291 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "le paramètre TABLESAMPLE REPEATABLE ne peut pas être NULL" -#: executor/nodeSubplan.c:336 executor/nodeSubplan.c:375 executor/nodeSubplan.c:1009 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 executor/nodeSubplan.c:1136 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "plus d'une ligne renvoyée par une sous-requête utilisée comme une expression" -#: executor/nodeTableFuncscan.c:368 +#: executor/nodeTableFuncscan.c:375 #, c-format msgid "namespace URI must not be null" msgstr "l'URI de l'espace de nom ne doit pas être NULL" -#: executor/nodeTableFuncscan.c:379 +#: executor/nodeTableFuncscan.c:389 #, c-format msgid "row filter expression must not be null" msgstr "l'expression de filtre de lignes ne doit pas être NULL" -#: executor/nodeTableFuncscan.c:404 +#: executor/nodeTableFuncscan.c:415 #, c-format msgid "column filter expression must not be null" msgstr "l'expression de filtre de colonnes ne doit pas être NULL" -#: executor/nodeTableFuncscan.c:405 +#: executor/nodeTableFuncscan.c:416 #, c-format msgid "Filter for column \"%s\" is null." msgstr "Le filtre pour la colonne « %s » est NULL." -#: executor/nodeTableFuncscan.c:486 +#: executor/nodeTableFuncscan.c:506 #, c-format msgid "null is not allowed in column \"%s\"" msgstr "NULL n'est pas autorisé dans la colonne « %s »" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeWindowAgg.c:355 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "la fonction de conversion de l'agrégat en déplacement ne doit pas renvoyer null" -#: executor/nodeWindowAgg.c:1624 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "l'offset de début de frame ne doit pas être NULL" -#: executor/nodeWindowAgg.c:1637 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "l'offset de début de frame ne doit pas être négatif" -#: executor/nodeWindowAgg.c:1649 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "l'offset de fin de frame ne doit pas être NULL" -#: executor/nodeWindowAgg.c:1662 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "l'offset de fin de frame ne doit pas être négatif" -#: executor/spi.c:197 +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "la fonction d'aggrégat %s ne supporte pas l'utilisation en tant que fonction window" + +#: executor/spi.c:233 executor/spi.c:272 +#, c-format +msgid "invalid transaction termination" +msgstr "arrêt de transaction invalide" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "ne peut pas valider la transaction pendant qu'une sous-transaction est active" + +#: executor/spi.c:278 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "ne peut pas annuler la transaction pendant qu'une sous-transaction est active" + +#: executor/spi.c:317 #, c-format msgid "transaction left non-empty SPI stack" msgstr "transaction gauche non vide dans la pile SPI" -#: executor/spi.c:198 executor/spi.c:261 +#: executor/spi.c:318 executor/spi.c:381 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "Vérifiez les appels manquants à « SPI_finish »." -#: executor/spi.c:260 +#: executor/spi.c:380 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "sous-transaction gauche non vide dans la pile SPI" -#: executor/spi.c:1143 +#: executor/spi.c:1283 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "ne peut pas ouvrir le plan à plusieurs requêtes comme curseur" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1148 +#: executor/spi.c:1288 #, c-format msgid "cannot open %s query as cursor" msgstr "ne peut pas ouvrir la requête %s comme curseur" -#: executor/spi.c:1253 +#: executor/spi.c:1393 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE n'est pas supporté" -#: executor/spi.c:1254 parser/analyze.c:2447 +#: executor/spi.c:1394 parser/analyze.c:2480 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Les curseurs déplaçables doivent être en lecture seule (READ ONLY)." -#: executor/spi.c:2374 +#: executor/spi.c:2534 #, c-format msgid "SQL statement \"%s\"" msgstr "instruction SQL « %s »" -#: executor/tqueue.c:317 +#: executor/tqueue.c:70 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "n'a pas pu envoyer la ligne dans la queue en mémoire partagée" @@ -11282,1332 +11785,1400 @@ msgstr "option « %s » invalide" msgid "Valid options in this context are: %s" msgstr "Les options valides dans ce contexte sont %s" -#: gram.y:1002 +#: gram.y:1026 #, c-format msgid "UNENCRYPTED PASSWORD is no longer supported" msgstr "UNENCRYPTED PASSWORD n'est plus supporté" -#: gram.y:1003 +#: gram.y:1027 #, c-format msgid "Remove UNENCRYPTED to store the password in encrypted form instead." msgstr "Supprimez UNENCRYPTED pour enregistrer le mot de passe dans sa forme chiffrée à la place." -#: gram.y:1065 +#: gram.y:1089 #, c-format msgid "unrecognized role option \"%s\"" msgstr "option « %s » du rôle non reconnu" -#: gram.y:1312 gram.y:1327 +#: gram.y:1336 gram.y:1351 #, c-format msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTS n'inclut pas les éléments du schéma" -#: gram.y:1472 +#: gram.y:1497 #, c-format msgid "current database cannot be changed" msgstr "la base de données actuelle ne peut pas être changée" -#: gram.y:1596 +#: gram.y:1621 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" msgstr "l'intervalle de fuseau horaire doit être HOUR ou HOUR TO MINUTE" -#: gram.y:2612 +#: gram.y:2139 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "le numéro de colonne doit être dans l'intervalle entre 1 et %d" + +#: gram.y:2678 #, c-format msgid "sequence option \"%s\" not supported here" msgstr "option de séquence « %s » non supportée ici" -#: gram.y:2835 gram.y:2864 +#: gram.y:2707 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "le modulus pour la partition hash est spécifié plus d'une fois" + +#: gram.y:2716 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "le reste pour la partition hash est spécifié plus d'une fois" + +#: gram.y:2723 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "spécification de limite de partition hash non reconnue « %s »" + +#: gram.y:2731 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "le modulus pour les partition hash doit être spécifié" + +#: gram.y:2735 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "le reste pour les partition hash doit être spécifié" + +#: gram.y:2987 gram.y:3016 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "STDIN/STDOUT non autorisé dans PROGRAM" -#: gram.y:3174 gram.y:3181 gram.y:11072 gram.y:11080 +#: gram.y:3326 gram.y:3333 gram.y:11482 gram.y:11490 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "GLOBAL est obsolète dans la création de la table temporaire" -#: gram.y:3656 utils/adt/ri_triggers.c:311 utils/adt/ri_triggers.c:368 utils/adt/ri_triggers.c:787 utils/adt/ri_triggers.c:1010 utils/adt/ri_triggers.c:1166 utils/adt/ri_triggers.c:1347 utils/adt/ri_triggers.c:1512 utils/adt/ri_triggers.c:1688 utils/adt/ri_triggers.c:1868 utils/adt/ri_triggers.c:2059 utils/adt/ri_triggers.c:2117 utils/adt/ri_triggers.c:2222 utils/adt/ri_triggers.c:2399 +#: gram.y:3815 utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MATCH PARTIAL non implémenté" -#: gram.y:5118 +#: gram.y:5297 #, c-format msgid "unrecognized row security option \"%s\"" msgstr "option « %s » de sécurité de ligne non reconnue" -#: gram.y:5119 +#: gram.y:5298 #, c-format msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." msgstr "Seules les politiques PERMISSIVE et RESTRICTIVE sont supportées actuellement." -#: gram.y:5227 +#: gram.y:5406 msgid "duplicate trigger events specified" msgstr "événements de trigger dupliqués spécifiés" -#: gram.y:5363 parser/parse_utilcmd.c:3033 parser/parse_utilcmd.c:3059 +#: gram.y:5547 parser/parse_utilcmd.c:3313 parser/parse_utilcmd.c:3339 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "la contrainte déclarée INITIALLY DEFERRED doit être DEFERRABLE" -#: gram.y:5370 +#: gram.y:5554 #, c-format msgid "conflicting constraint properties" msgstr "propriétés de contrainte en conflit" -#: gram.y:5476 +#: gram.y:5660 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "CREATE ASSERTION n'est pas encore implémenté" -#: gram.y:5491 +#: gram.y:5675 #, c-format msgid "DROP ASSERTION is not yet implemented" msgstr "DROP ASSERTION n'est pas encore implémenté" -#: gram.y:5871 +#: gram.y:6055 #, c-format msgid "RECHECK is no longer required" msgstr "RECHECK n'est plus nécessaire" -#: gram.y:5872 +#: gram.y:6056 #, c-format msgid "Update your data type." msgstr "Mettez à jour votre type de données." -#: gram.y:7515 +#: gram.y:7793 #, c-format msgid "aggregates cannot have output arguments" msgstr "les agrégats ne peuvent pas avoir d'arguments en sortie" -#: gram.y:7844 utils/adt/regproc.c:691 utils/adt/regproc.c:732 +#: gram.y:8181 utils/adt/regproc.c:691 utils/adt/regproc.c:732 #, c-format msgid "missing argument" msgstr "argument manquant" -#: gram.y:7845 utils/adt/regproc.c:692 utils/adt/regproc.c:733 +#: gram.y:8182 utils/adt/regproc.c:692 utils/adt/regproc.c:733 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." msgstr "Utilisez NONE pour dénoter l'argument manquant d'un opérateur unitaire." -#: gram.y:9647 gram.y:9665 +#: gram.y:10047 gram.y:10065 #, c-format msgid "WITH CHECK OPTION not supported on recursive views" msgstr "WITH CHECK OPTION non supporté sur les vues récursives" -#: gram.y:10198 +#: gram.y:10562 #, c-format msgid "unrecognized VACUUM option \"%s\"" msgstr "option « %s » de la commande VACUUM non reconnue" -#: gram.y:11180 +#: gram.y:11590 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "la syntaxe LIMIT #,# n'est pas supportée" -#: gram.y:11181 +#: gram.y:11591 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "Utilisez les clauses séparées LIMIT et OFFSET." -#: gram.y:11462 gram.y:11487 +#: gram.y:11889 gram.y:11914 #, c-format msgid "VALUES in FROM must have an alias" msgstr "VALUES dans FROM doit avoir un alias" -#: gram.y:11463 gram.y:11488 +#: gram.y:11890 gram.y:11915 #, c-format msgid "For example, FROM (VALUES ...) [AS] foo." msgstr "Par exemple, FROM (VALUES ...) [AS] quelquechose." -#: gram.y:11468 gram.y:11493 +#: gram.y:11895 gram.y:11920 #, c-format msgid "subquery in FROM must have an alias" msgstr "la sous-requête du FROM doit avoir un alias" -#: gram.y:11469 gram.y:11494 +#: gram.y:11896 gram.y:11921 #, c-format msgid "For example, FROM (SELECT ...) [AS] foo." msgstr "Par exemple, FROM (SELECT...) [AS] quelquechose." -#: gram.y:11948 +#: gram.y:12374 #, c-format msgid "only one DEFAULT value is allowed" msgstr "seule une valeur DEFAULT est autorisée" -#: gram.y:11957 +#: gram.y:12383 #, c-format msgid "only one PATH value per column is allowed" msgstr "seule une valeur PATH par colonne est autorisée" -#: gram.y:11966 -#, fuzzy, c-format -#| msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +#: gram.y:12392 +#, c-format msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" -msgstr "déclarations NULL/NOT NULL en conflit pour la colonne « %s » de la table « %s »" +msgstr "déclarations NULL/NOT NULL en conflit ou redondantes pour la colonne « %s »" -#: gram.y:11975 +#: gram.y:12401 #, c-format msgid "unrecognized column option \"%s\"" msgstr "option « %s » de colonne non reconnue" -#: gram.y:12229 +#: gram.y:12655 #, c-format msgid "precision for type float must be at least 1 bit" msgstr "la précision du type float doit être d'au moins un bit" -#: gram.y:12238 +#: gram.y:12664 #, c-format msgid "precision for type float must be less than 54 bits" msgstr "la précision du type float doit être inférieur à 54 bits" -#: gram.y:12729 +#: gram.y:13155 #, c-format msgid "wrong number of parameters on left side of OVERLAPS expression" msgstr "mauvais nombre de paramètres sur le côté gauche de l'expression OVERLAPS" -#: gram.y:12734 +#: gram.y:13160 #, c-format msgid "wrong number of parameters on right side of OVERLAPS expression" msgstr "mauvais nombre de paramètres sur le côté droit de l'expression OVERLAPS" -#: gram.y:12909 +#: gram.y:13335 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "prédicat UNIQUE non implémenté" -#: gram.y:13256 +#: gram.y:13682 #, c-format msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" msgstr "ne peut pas utiliser des clauses ORDER BY multiples dans WITHIN GROUP" -#: gram.y:13261 +#: gram.y:13687 #, c-format msgid "cannot use DISTINCT with WITHIN GROUP" msgstr "ne peut pas utiliser DISTINCT avec WITHIN GROUP" -#: gram.y:13266 +#: gram.y:13692 #, c-format msgid "cannot use VARIADIC with WITHIN GROUP" msgstr "ne peut pas utiliser VARIADIC avec WITHIN GROUP" -#: gram.y:13692 -#, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING est seulement supporté avec UNBOUNDED" - -#: gram.y:13698 -#, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING est seulement supporté avec UNBOUNDED" - -#: gram.y:13725 gram.y:13748 +#: gram.y:14145 gram.y:14168 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" msgstr "la fin du frame ne peut pas être UNBOUNDED FOLLOWING" -#: gram.y:13730 +#: gram.y:14150 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "la frame commençant après la ligne suivante ne peut pas se terminer avec la ligne actuelle" -#: gram.y:13753 +#: gram.y:14173 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" msgstr "la fin du frame ne peut pas être UNBOUNDED PRECEDING" -#: gram.y:13759 +#: gram.y:14179 #, c-format msgid "frame starting from current row cannot have preceding rows" msgstr "la frame commençant à la ligne courante ne peut pas avoir des lignes précédentes" -#: gram.y:13766 +#: gram.y:14186 #, c-format msgid "frame starting from following row cannot have preceding rows" msgstr "la frame commençant à la ligne suivante ne peut pas avoir des lignes précédentes" -#: gram.y:14401 +#: gram.y:14829 #, c-format msgid "type modifier cannot have parameter name" msgstr "le modificateur de type ne peut pas avoir de nom de paramètre" -#: gram.y:14407 +#: gram.y:14835 #, c-format msgid "type modifier cannot have ORDER BY" msgstr "le modificateur de type ne peut pas avoir de clause ORDER BY" -#: gram.y:14471 gram.y:14477 +#: gram.y:14900 gram.y:14907 #, c-format msgid "%s cannot be used as a role name here" msgstr "%s ne peut pas être utilisé comme nom de rôle ici" -#: gram.y:15139 gram.y:15328 +#: gram.y:15578 gram.y:15767 msgid "improper use of \"*\"" msgstr "mauvaise utilisation de « * »" -#: gram.y:15291 gram.y:15308 tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 +#: gram.y:15730 gram.y:15747 tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 #, c-format msgid "syntax error" msgstr "erreur de syntaxe" -#: gram.y:15392 +#: gram.y:15831 #, c-format msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" msgstr "un agrégat par ensemble ordonné avec un argument VARIADIC direct doit avoir un argument VARIADIC agrégé du même type de données" -#: gram.y:15429 +#: gram.y:15868 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "clauses ORDER BY multiples non autorisées" -#: gram.y:15440 +#: gram.y:15879 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "clauses OFFSET multiples non autorisées" -#: gram.y:15449 +#: gram.y:15888 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "clauses LIMIT multiples non autorisées" -#: gram.y:15458 +#: gram.y:15897 #, c-format msgid "multiple WITH clauses not allowed" msgstr "clauses WITH multiples non autorisées" -#: gram.y:15662 +#: gram.y:16101 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "les arguments OUT et INOUT ne sont pas autorisés dans des fonctions TABLE" -#: gram.y:15763 +#: gram.y:16202 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "clauses COLLATE multiples non autorisées" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15801 gram.y:15814 +#: gram.y:16240 gram.y:16253 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "les contraintes %s ne peuvent pas être marquées comme DEFERRABLE" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15827 +#: gram.y:16266 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "les contraintes %s ne peuvent pas être marquées comme NOT VALID" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15840 +#: gram.y:16279 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "les contraintes %s ne peuvent pas être marquées NO INHERIT" -#: guc-file.l:313 +#: guc-file.l:316 #, c-format msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" msgstr "paramètre de configuration « %s » non reconnu dans le fichier « %s », ligne %u" -#: guc-file.l:350 utils/misc/guc.c:6006 utils/misc/guc.c:6199 utils/misc/guc.c:6289 utils/misc/guc.c:6379 utils/misc/guc.c:6487 utils/misc/guc.c:6582 +#: guc-file.l:353 utils/misc/guc.c:6253 utils/misc/guc.c:6447 utils/misc/guc.c:6537 utils/misc/guc.c:6627 utils/misc/guc.c:6735 utils/misc/guc.c:6830 #, c-format msgid "parameter \"%s\" cannot be changed without restarting the server" msgstr "le paramètre « %s » ne peut pas être modifié sans redémarrer le serveur" -#: guc-file.l:386 +#: guc-file.l:389 #, c-format msgid "parameter \"%s\" removed from configuration file, reset to default" msgstr "" "paramètre « %s » supprimé du fichier de configuration ;\n" "réinitialisation à la valeur par défaut" -#: guc-file.l:452 +#: guc-file.l:455 #, c-format msgid "parameter \"%s\" changed to \"%s\"" msgstr "paramètre « %s » modifié par « %s »" -#: guc-file.l:494 +#: guc-file.l:497 #, c-format msgid "configuration file \"%s\" contains errors" msgstr "le fichier de configuration « %s » contient des erreurs" -#: guc-file.l:499 +#: guc-file.l:502 #, c-format msgid "configuration file \"%s\" contains errors; unaffected changes were applied" msgstr "le fichier de configuration « %s » contient des erreurs ; les modifications non affectées ont été appliquées" -#: guc-file.l:504 +#: guc-file.l:507 #, c-format msgid "configuration file \"%s\" contains errors; no changes were applied" msgstr "le fichier de configuration « %s » contient des erreurs ; aucune modification n'a été appliquée" -#: guc-file.l:577 +#: guc-file.l:580 #, c-format msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" msgstr "" "n'a pas pu ouvrir le fichier de configuration « %s » : profondeur\n" "d'imbrication dépassé" -#: guc-file.l:593 libpq/hba.c:2110 libpq/hba.c:2510 +#: guc-file.l:596 libpq/hba.c:2142 libpq/hba.c:2550 #, c-format msgid "could not open configuration file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de configuration « %s » : %m" -#: guc-file.l:604 +#: guc-file.l:607 #, c-format msgid "skipping missing configuration file \"%s\"" msgstr "ignore le fichier de configuration « %s » manquant" -#: guc-file.l:858 +#: guc-file.l:861 #, c-format msgid "syntax error in file \"%s\" line %u, near end of line" msgstr "erreur de syntaxe dans le fichier « %s », ligne %u, près de la fin de ligne" -#: guc-file.l:868 +#: guc-file.l:871 #, c-format msgid "syntax error in file \"%s\" line %u, near token \"%s\"" msgstr "erreur de syntaxe dans le fichier « %s », ligne %u, près du mot clé « %s »" -#: guc-file.l:888 +#: guc-file.l:891 #, c-format msgid "too many syntax errors found, abandoning file \"%s\"" msgstr "trop d'erreurs de syntaxe trouvées, abandon du fichier « %s »" -#: guc-file.l:940 +#: guc-file.l:943 #, c-format msgid "could not open configuration directory \"%s\": %m" msgstr "n'a pas pu ouvrir le répertoire de configuration « %s » : %m" -#: lib/stringinfo.c:259 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "n'a pas pu accéder au fichier « %s » : %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "temps pour inliner: %.3fs, opt: %.3fs, emit: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Échec d'une requête DSA de taille %zu." + +#: lib/stringinfo.c:278 #, c-format msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." msgstr "Ne peut pas agrandir de %d octets le tampon de chaîne contenant déjà %d octets" -#: libpq/auth-scram.c:199 libpq/auth-scram.c:439 libpq/auth-scram.c:448 +#: libpq/auth-scram.c:251 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "le client a sélectionné un mécanisme d'authentification SASL invalide" + +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 #, c-format msgid "invalid SCRAM verifier for user \"%s\"" msgstr "vérificateur SCRAM invalide pour l'utilisateur « %s »" -#: libpq/auth-scram.c:210 +#: libpq/auth-scram.c:283 #, c-format msgid "User \"%s\" does not have a valid SCRAM verifier." msgstr "L'utilisateur « %s » n'a pas de vérificateur SCRAM valide." -#: libpq/auth-scram.c:288 libpq/auth-scram.c:293 libpq/auth-scram.c:587 libpq/auth-scram.c:595 libpq/auth-scram.c:676 libpq/auth-scram.c:686 libpq/auth-scram.c:804 libpq/auth-scram.c:811 libpq/auth-scram.c:826 libpq/auth-scram.c:1056 libpq/auth-scram.c:1064 +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 #, c-format msgid "malformed SCRAM message" msgstr "message SCRAM malformé" -#: libpq/auth-scram.c:289 +#: libpq/auth-scram.c:362 #, c-format msgid "The message is empty." msgstr "Le message est vide." -#: libpq/auth-scram.c:294 +#: libpq/auth-scram.c:367 #, c-format msgid "Message length does not match input length." msgstr "La longueur du message ne correspond pas à la longueur en entrée." -#: libpq/auth-scram.c:326 +#: libpq/auth-scram.c:399 #, c-format msgid "invalid SCRAM response" msgstr "réponse SCRAM invalide" -#: libpq/auth-scram.c:327 +#: libpq/auth-scram.c:400 #, c-format msgid "Nonce does not match." msgstr "Le nonce ne correspond pas." -#: libpq/auth-scram.c:401 +#: libpq/auth-scram.c:474 #, c-format msgid "could not generate random salt" msgstr "n'a pas pu générer le sel aléatoire" -#: libpq/auth-scram.c:588 +#: libpq/auth-scram.c:661 #, c-format -msgid "Expected attribute '%c' but found %s." -msgstr "Attribut attendu '%c', mais « %s » trouvé." +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Attribut attendu « %c », mais « %s » trouvé." -#: libpq/auth-scram.c:596 libpq/auth-scram.c:687 +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 #, c-format -msgid "Expected character = for attribute %c." -msgstr "Caractère = attendu pour l'attribut %c." +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Caractère « = » attendu pour l'attribut « %c »." -#: libpq/auth-scram.c:677 +#: libpq/auth-scram.c:780 #, c-format -msgid "Attribute expected, but found invalid character %s." -msgstr "Attribut attendu, mais a trouvé le caractère invalide %s." +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Attribut attendu, mais a trouvé le caractère invalide « %s »." -#: libpq/auth-scram.c:800 +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 #, c-format -msgid "client requires SCRAM channel binding, but it is not supported" -msgstr "" +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Le client a sélectionné SCRAM-SHA-256-PLUS, mais le message SCRAM n'inclut pas de données de channel-binding." -#: libpq/auth-scram.c:805 -#, fuzzy, c-format -#| msgid "Unexpected end of input." -msgid "Unexpected channel-binding flag %s." -msgstr "Fin de l'entrée inattendue." +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Virgule attendue, mais caractère « %s » trouvé." + +#: libpq/auth-scram.c:926 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Erreur de négociation de channel-binding SCRAM" + +#: libpq/auth-scram.c:927 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Le client supporte le channel binding SCRAM mais pense que le serveur ne le supporte pas. Cependant, ce serveur supporte vraiment le channel-binding." + +#: libpq/auth-scram.c:949 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Le client a sélectionné SCRAM-SHA-256 sans channel binding, mais le message SCRAM inclue des données de channel-binding." + +#: libpq/auth-scram.c:960 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "type de channel-binding SCRAM « %s » non supporté" -#: libpq/auth-scram.c:812 +#: libpq/auth-scram.c:967 #, c-format -msgid "Comma expected, but found character %s." -msgstr "Virgule attendue, mais « %s » trouvé." +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Drapeau du channel-binding inattendu « %s »." -#: libpq/auth-scram.c:822 +#: libpq/auth-scram.c:977 #, c-format msgid "client uses authorization identity, but it is not supported" msgstr "le client utilise une identité d'autorisation, mais elle n'est pas supportée" -#: libpq/auth-scram.c:827 +#: libpq/auth-scram.c:982 #, c-format -msgid "Unexpected attribute %s in client-first-message." -msgstr "Attribut %s inattendu dans client-first-message." +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Attribut « %s » inattendu dans client-first-message." -#: libpq/auth-scram.c:843 +#: libpq/auth-scram.c:998 #, c-format msgid "client requires an unsupported SCRAM extension" msgstr "le client requiert une extension SCRAM non supportée" -#: libpq/auth-scram.c:857 +#: libpq/auth-scram.c:1012 #, c-format msgid "non-printable characters in SCRAM nonce" -msgstr "" +msgstr "caractères non affichables dans le nonce SCRAM" -#: libpq/auth-scram.c:974 +#: libpq/auth-scram.c:1129 #, c-format msgid "could not generate random nonce" msgstr "n'a pas pu générer le nonce aléatoire" -#: libpq/auth-scram.c:1042 +#: libpq/auth-scram.c:1233 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "la vérification du channel-binding SCRAM a échoué" + +#: libpq/auth-scram.c:1251 #, c-format msgid "unexpected SCRAM channel-binding attribute in client-final-message" -msgstr "" +msgstr "attribut du lien de canal SCRAM inattendu dans client-final-message" -#: libpq/auth-scram.c:1057 +#: libpq/auth-scram.c:1268 #, c-format msgid "Malformed proof in client-final-message." -msgstr "" +msgstr "Preuve malformée dans le client-final-message." -#: libpq/auth-scram.c:1065 +#: libpq/auth-scram.c:1276 #, c-format msgid "Garbage found at the end of client-final-message." msgstr "Problème trouvé à la fin de client-final-message." -#: libpq/auth.c:274 +#: libpq/auth.c:282 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "authentification échouée pour l'utilisateur « %s » : hôte rejeté" -#: libpq/auth.c:277 +#: libpq/auth.c:285 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "authentification « trust » échouée pour l'utilisateur « %s »" -#: libpq/auth.c:280 +#: libpq/auth.c:288 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "authentification Ident échouée pour l'utilisateur « %s »" -#: libpq/auth.c:283 +#: libpq/auth.c:291 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "authentification peer échouée pour l'utilisateur « %s »" -#: libpq/auth.c:288 +#: libpq/auth.c:296 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "authentification par mot de passe échouée pour l'utilisateur « %s »" -#: libpq/auth.c:293 +#: libpq/auth.c:301 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "authentification GSSAPI échouée pour l'utilisateur « %s »" -#: libpq/auth.c:296 +#: libpq/auth.c:304 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "authentification SSPI échouée pour l'utilisateur « %s »" -#: libpq/auth.c:299 +#: libpq/auth.c:307 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "authentification PAM échouée pour l'utilisateur « %s »" -#: libpq/auth.c:302 +#: libpq/auth.c:310 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "authentification BSD échouée pour l'utilisateur « %s »" -#: libpq/auth.c:305 +#: libpq/auth.c:313 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "authentification LDAP échouée pour l'utilisateur « %s »" -#: libpq/auth.c:308 +#: libpq/auth.c:316 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "authentification par le certificat échouée pour l'utilisateur « %s »" -#: libpq/auth.c:311 +#: libpq/auth.c:319 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "authentification RADIUS échouée pour l'utilisateur « %s »" -#: libpq/auth.c:314 +#: libpq/auth.c:322 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "" "authentification échouée pour l'utilisateur « %s » :\n" "méthode d'authentification invalide" -#: libpq/auth.c:318 +#: libpq/auth.c:326 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "La connexion correspond à la ligne %d du pg_hba.conf : « %s »" -#: libpq/auth.c:365 +#: libpq/auth.c:373 #, c-format msgid "client certificates can only be checked if a root certificate store is available" msgstr "" "les certificats cert peuvent seulement être vérifiés si un emplacement de\n" "certificat racine est disponible" -#: libpq/auth.c:376 +#: libpq/auth.c:384 #, c-format msgid "connection requires a valid client certificate" msgstr "la connexion requiert un certificat client valide" -#: libpq/auth.c:409 +#: libpq/auth.c:417 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "" "pg_hba.conf rejette la connexion de la réplication pour l'hôte « %s »,\n" "utilisateur « %s », %s" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL off" msgstr "SSL inactif" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL on" msgstr "SSL actif" -#: libpq/auth.c:415 +#: libpq/auth.c:423 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "" "pg_hba.conf rejette la connexion de la réplication pour l'hôte « %s »,\n" "utilisateur « %s »" -#: libpq/auth.c:424 +#: libpq/auth.c:432 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "" "pg_hba.conf rejette la connexion pour l'hôte « %s », utilisateur « %s », base\n" "de données « %s », %s" -#: libpq/auth.c:431 +#: libpq/auth.c:439 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" msgstr "" "pg_hba.conf rejette la connexion pour l'hôte « %s », utilisateur « %s », base\n" "de données « %s »" -#: libpq/auth.c:460 +#: libpq/auth.c:468 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "Adresse IP du client résolue en « %s », la recherche inverse correspond bien." -#: libpq/auth.c:463 +#: libpq/auth.c:471 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "Adresse IP du client résolue en « %s », la recherche inverse n'est pas vérifiée." -#: libpq/auth.c:466 +#: libpq/auth.c:474 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "Adresse IP du client résolue en « %s », la recherche inverse ne correspond pas." -#: libpq/auth.c:469 +#: libpq/auth.c:477 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "N'a pas pu traduire le nom d'hôte « %s » du client en adresse IP : %s." -#: libpq/auth.c:474 +#: libpq/auth.c:482 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "N'a pas pu résoudre l'adresse IP du client à partir du nom d'hôte : %s." -#: libpq/auth.c:483 +#: libpq/auth.c:491 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "" "aucune entrée dans pg_hba.conf pour la connexion de la réplication à partir de\n" "l'hôte « %s », utilisateur « %s », %s" -#: libpq/auth.c:490 +#: libpq/auth.c:498 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" msgstr "" "aucune entrée dans pg_hba.conf pour la connexion de la réplication à partir de\n" "l'hôte « %s », utilisateur « %s »" -#: libpq/auth.c:500 +#: libpq/auth.c:508 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "" "aucune entrée dans pg_hba.conf pour l'hôte « %s », utilisateur « %s »,\n" "base de données « %s », %s" -#: libpq/auth.c:508 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "" "aucune entrée dans pg_hba.conf pour l'hôte « %s », utilisateur « %s »,\n" "base de données « %s »" -#: libpq/auth.c:661 +#: libpq/auth.c:669 #, c-format msgid "expected password response, got message type %d" msgstr "en attente du mot de passe, a reçu un type de message %d" -#: libpq/auth.c:689 +#: libpq/auth.c:697 #, c-format msgid "invalid password packet size" msgstr "taille du paquet du mot de passe invalide" -#: libpq/auth.c:809 libpq/hba.c:1325 +#: libpq/auth.c:715 +#, c-format +msgid "empty password returned by client" +msgstr "mot de passe vide renvoyé par le client" + +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" msgstr "l'authentification MD5 n'est pas supportée quand « db_user_namespace » est activé" -#: libpq/auth.c:815 +#: libpq/auth.c:841 #, c-format msgid "could not generate random MD5 salt" msgstr "n'a pas pu générer le sel MD5 aléatoire" -#: libpq/auth.c:860 +#: libpq/auth.c:887 #, c-format msgid "SASL authentication is not supported in protocol version 2" msgstr "l'authentification SASL n'est pas supportée dans le protocole de version 2" -#: libpq/auth.c:902 +#: libpq/auth.c:920 #, c-format msgid "expected SASL response, got message type %d" msgstr "attendait une réponse SASL, a reçu le type de message %d" -#: libpq/auth.c:939 -#, c-format -msgid "client selected an invalid SASL authentication mechanism" -msgstr "le client a sélectionné un mécanisme d'authentification SASL invalide" - -#: libpq/auth.c:1086 +#: libpq/auth.c:1112 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "GSSAPI n'est pas supporté dans le protocole de version 2" -#: libpq/auth.c:1146 +#: libpq/auth.c:1172 #, c-format msgid "expected GSS response, got message type %d" msgstr "en attente d'une réponse GSS, a reçu un message de type %d" -#: libpq/auth.c:1208 +#: libpq/auth.c:1234 msgid "accepting GSS security context failed" msgstr "échec de l'acceptation du contexte de sécurité GSS" -#: libpq/auth.c:1234 +#: libpq/auth.c:1260 msgid "retrieving GSS user name failed" msgstr "échec lors de la récupération du nom de l'utilisateur avec GSS" -#: libpq/auth.c:1354 +#: libpq/auth.c:1385 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "SSPI n'est pas supporté dans le protocole de version 2" -#: libpq/auth.c:1369 +#: libpq/auth.c:1400 msgid "could not acquire SSPI credentials" msgstr "n'a pas pu obtenir les pièces d'identité SSPI" -#: libpq/auth.c:1387 +#: libpq/auth.c:1418 #, c-format msgid "expected SSPI response, got message type %d" msgstr "en attente d'une réponse SSPI, a reçu un message de type %d" -#: libpq/auth.c:1460 +#: libpq/auth.c:1491 msgid "could not accept SSPI security context" msgstr "n'a pas pu accepter le contexte de sécurité SSPI" -#: libpq/auth.c:1522 +#: libpq/auth.c:1553 msgid "could not get token from SSPI security context" msgstr "n'a pas pu obtenir le jeton du contexte de sécurité SSPI" -#: libpq/auth.c:1641 libpq/auth.c:1660 +#: libpq/auth.c:1672 libpq/auth.c:1691 #, c-format msgid "could not translate name" msgstr "n'a pas pu traduit le nom" -#: libpq/auth.c:1673 +#: libpq/auth.c:1704 #, c-format msgid "realm name too long" msgstr "nom du royaume trop long" -#: libpq/auth.c:1688 +#: libpq/auth.c:1719 #, c-format msgid "translated account name too long" msgstr "traduction du nom de compte trop longue" -#: libpq/auth.c:1874 +#: libpq/auth.c:1905 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "n'a pas pu créer le socket pour la connexion Ident : %m" -#: libpq/auth.c:1889 +#: libpq/auth.c:1920 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "n'a pas pu se lier à l'adresse locale « %s » : %m" -#: libpq/auth.c:1901 +#: libpq/auth.c:1932 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "n'a pas pu se connecter au serveur Ident à l'adresse « %s », port %s : %m" -#: libpq/auth.c:1923 +#: libpq/auth.c:1954 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "n'a pas pu envoyer la requête au serveur Ident à l'adresse « %s », port %s : %m" -#: libpq/auth.c:1940 +#: libpq/auth.c:1971 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "" "n'a pas pu recevoir la réponse du serveur Ident à l'adresse « %s », port %s :\n" "%m" -#: libpq/auth.c:1950 +#: libpq/auth.c:1981 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "réponse mal formatée du serveur Ident : « %s »" -#: libpq/auth.c:1990 +#: libpq/auth.c:2021 #, c-format msgid "peer authentication is not supported on this platform" msgstr "la méthode d'authentification «peer n'est pas supportée sur cette plateforme" -#: libpq/auth.c:1994 +#: libpq/auth.c:2025 #, c-format msgid "could not get peer credentials: %m" msgstr "n'a pas pu obtenir l'authentification de l'autre : %m" -#: libpq/auth.c:2003 +#: libpq/auth.c:2036 #, c-format msgid "could not look up local user ID %ld: %s" msgstr "n'a pas pu rechercher l'identifiant %ld de l'utilisateur local : %s" -#: libpq/auth.c:2087 libpq/auth.c:2413 libpq/auth.c:2726 -#, c-format -msgid "empty password returned by client" -msgstr "mot de passe vide renvoyé par le client" - -#: libpq/auth.c:2097 +#: libpq/auth.c:2124 #, c-format msgid "error from underlying PAM layer: %s" msgstr "erreur provenant de la couche PAM : %s" -#: libpq/auth.c:2178 +#: libpq/auth.c:2193 #, c-format msgid "could not create PAM authenticator: %s" msgstr "n'a pas pu créer l'authenticateur PAM : %s" -#: libpq/auth.c:2189 +#: libpq/auth.c:2204 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER) a échoué : %s" -#: libpq/auth.c:2200 +#: libpq/auth.c:2236 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST) a échoué : %s" -#: libpq/auth.c:2211 +#: libpq/auth.c:2248 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "pam_set_item(PAM_CONV) a échoué : %s" -#: libpq/auth.c:2222 +#: libpq/auth.c:2259 #, c-format msgid "pam_authenticate failed: %s" msgstr "pam_authenticate a échoué : %s" -#: libpq/auth.c:2233 +#: libpq/auth.c:2270 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmt a échoué : %s" -#: libpq/auth.c:2244 +#: libpq/auth.c:2281 #, c-format msgid "could not release PAM authenticator: %s" msgstr "n'a pas pu fermer l'authenticateur PAM : %s" -#: libpq/auth.c:2309 -#, c-format -msgid "could not initialize LDAP: %m" -msgstr "n'a pas pu initialiser LDAP : %m" - -#: libpq/auth.c:2312 +#: libpq/auth.c:2357 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "n'a pas pu initialiser LDAP : code d'erreur %d" -#: libpq/auth.c:2322 +#: libpq/auth.c:2406 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "n'a pas pu initialiser LDAP : %s" + +#: libpq/auth.c:2416 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps non supporté avec cette bibliothèque LDAP" + +#: libpq/auth.c:2424 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "n'a pas pu initialiser LDAP : %m" + +#: libpq/auth.c:2434 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "n'a pas pu initialiser la version du protocole LDAP : %s" -#: libpq/auth.c:2351 +#: libpq/auth.c:2465 #, c-format msgid "could not load wldap32.dll" msgstr "n'a pas pu charger wldap32.dll" -#: libpq/auth.c:2359 +#: libpq/auth.c:2473 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "n'a pas pu charger la fonction _ldap_start_tls_sA de wldap32.dll" -#: libpq/auth.c:2360 +#: libpq/auth.c:2474 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "LDAP via SSL n'est pas supporté sur cette plateforme." -#: libpq/auth.c:2375 +#: libpq/auth.c:2489 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "n'a pas pu démarrer la session TLS LDAP : %s" -#: libpq/auth.c:2397 +#: libpq/auth.c:2552 #, c-format msgid "LDAP server not specified" msgstr "serveur LDAP non précisé" -#: libpq/auth.c:2450 +#: libpq/auth.c:2607 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "caractère invalide dans le nom de l'utilisateur pour l'authentification LDAP" -#: libpq/auth.c:2465 +#: libpq/auth.c:2624 #, c-format msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "n'a pas pu réaliser le lien LDAP initiale pour ldapbinddn « %s » sur le serveur « %s » : %s" -#: libpq/auth.c:2489 +#: libpq/auth.c:2653 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "n'a pas pu rechercher dans LDAP pour filtrer « %s » sur le serveur « %s » : %s" -#: libpq/auth.c:2500 +#: libpq/auth.c:2667 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "l'utilisateur LDAP « %s » n'existe pas" -#: libpq/auth.c:2501 +#: libpq/auth.c:2668 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "la recherche LDAP pour le filtre « %s » sur le serveur « %s » n'a renvoyé aucun enregistrement." -#: libpq/auth.c:2505 +#: libpq/auth.c:2672 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "l'utilisateur LDAP « %s » n'est pas unique" -#: libpq/auth.c:2506 +#: libpq/auth.c:2673 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "la recherche LDAP pour le filtre « %s » sur le serveur « %s » a renvoyé %d enregistrement." msgstr[1] "la recherche LDAP pour le filtre « %s » sur le serveur « %s » a renvoyé %d enregistrements." -#: libpq/auth.c:2524 +#: libpq/auth.c:2693 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "" "n'a pas pu obtenir le dn pour la première entrée correspondante « %s » sur\n" "le serveur « %s » : %s" -#: libpq/auth.c:2544 +#: libpq/auth.c:2714 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" msgstr "" "n'a pas pu exécuter le unbind après la recherche de l'utilisateur « %s »\n" -"sur le serveur « %s » : %s" +"sur le serveur « %s »" -#: libpq/auth.c:2574 +#: libpq/auth.c:2745 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "échec de connexion LDAP pour l'utilisateur « %s » sur le serveur « %s » : %s" -#: libpq/auth.c:2602 +#: libpq/auth.c:2774 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "diagnostique LDAP: %s" + +#: libpq/auth.c:2799 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "" "l'authentification par le certificat a échoué pour l'utilisateur « %s » :\n" "le certificat du client ne contient aucun nom d'utilisateur" -#: libpq/auth.c:2705 +#: libpq/auth.c:2902 #, c-format msgid "RADIUS server not specified" msgstr "serveur RADIUS non précisé" -#: libpq/auth.c:2712 +#: libpq/auth.c:2909 #, c-format msgid "RADIUS secret not specified" msgstr "secret RADIUS non précisé" -#: libpq/auth.c:2733 +#: libpq/auth.c:2923 #, c-format msgid "RADIUS authentication does not support passwords longer than %d characters" msgstr "" "l'authentification RADIUS ne supporte pas les mots de passe de plus de %d\n" "caractères" -#: libpq/auth.c:2830 libpq/hba.c:1876 +#: libpq/auth.c:3028 libpq/hba.c:1908 #, c-format msgid "could not translate RADIUS server name \"%s\" to address: %s" msgstr "n'a pas pu traduire le nom du serveur RADIUS « %s » en une adresse : %s" -#: libpq/auth.c:2844 +#: libpq/auth.c:3042 #, c-format msgid "could not generate random encryption vector" msgstr "n'a pas pu générer le vecteur de chiffrement aléatoire" -#: libpq/auth.c:2878 +#: libpq/auth.c:3076 #, c-format msgid "could not perform MD5 encryption of password" msgstr "n'a pas pu réaliser le chiffrement MD5 du mot de passe" -#: libpq/auth.c:2904 +#: libpq/auth.c:3102 #, c-format msgid "could not create RADIUS socket: %m" msgstr "n'a pas pu créer le socket RADIUS : %m" -#: libpq/auth.c:2926 +#: libpq/auth.c:3124 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "n'a pas pu se lier à la socket RADIUS : %m" -#: libpq/auth.c:2936 +#: libpq/auth.c:3134 #, c-format msgid "could not send RADIUS packet: %m" msgstr "n'a pas pu transmettre le paquet RADIUS : %m" -#: libpq/auth.c:2969 libpq/auth.c:2995 +#: libpq/auth.c:3167 libpq/auth.c:3193 #, c-format msgid "timeout waiting for RADIUS response from %s" msgstr "dépassement du délai pour la réponse du RADIUS à partir de %s" -#: libpq/auth.c:2988 +#: libpq/auth.c:3186 #, c-format msgid "could not check status on RADIUS socket: %m" msgstr "n'a pas pu vérifier le statut sur la socket RADIUS : %m" -#: libpq/auth.c:3018 +#: libpq/auth.c:3216 #, c-format msgid "could not read RADIUS response: %m" msgstr "n'a pas pu lire la réponse RADIUS : %m" -#: libpq/auth.c:3031 libpq/auth.c:3035 +#: libpq/auth.c:3229 libpq/auth.c:3233 #, c-format msgid "RADIUS response from %s was sent from incorrect port: %d" msgstr "la réponse RADIUS de %s a été envoyée à partir d'un mauvais port : %d" -#: libpq/auth.c:3044 +#: libpq/auth.c:3242 #, c-format msgid "RADIUS response from %s too short: %d" msgstr "réponse RADIUS de %s trop courte : %d" -#: libpq/auth.c:3051 +#: libpq/auth.c:3249 #, c-format msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" msgstr "la réponse RADIUS de %s a une longueur corrompue : %d (longueur actuelle %d)" -#: libpq/auth.c:3059 +#: libpq/auth.c:3257 #, c-format msgid "RADIUS response from %s is to a different request: %d (should be %d)" msgstr "la réponse RADIUS à partir de %s correspond à une demande différente : %d (devrait être %d)" -#: libpq/auth.c:3084 +#: libpq/auth.c:3282 #, c-format msgid "could not perform MD5 encryption of received packet" msgstr "n'a pas pu réaliser le chiffrement MD5 du paquet reçu" -#: libpq/auth.c:3093 +#: libpq/auth.c:3291 #, c-format msgid "RADIUS response from %s has incorrect MD5 signature" msgstr "la réponse RADIUS à partir de %s a une signature MD5 invalide" -#: libpq/auth.c:3111 +#: libpq/auth.c:3309 #, c-format msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" msgstr "la réponse RADIUS à partir de %s a un code invalide (%d) pour l'utilisateur « %s »" -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format msgid "invalid large-object descriptor: %d" msgstr "descripteur invalide de « Large Object » : %d" -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 libpq/be-fsstubs.c:788 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "droit refusé pour le Large Object %u" +msgid "large object descriptor %d was not opened for reading" +msgstr "le descripteur %d du « Large Object » n'a pas été ouvert pour la lecture" -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format msgid "large object descriptor %d was not opened for writing" msgstr "le descripteur %d du « Large Object » n'a pas été ouvert pour l'écriture" -#: libpq/be-fsstubs.c:245 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "résultat de lo_lseek en dehors de l'intervalle pour le descripteur de Large Object %d" -#: libpq/be-fsstubs.c:318 +#: libpq/be-fsstubs.c:285 #, c-format msgid "lo_tell result out of range for large-object descriptor %d" msgstr "résultat de lo_tell en dehors de l'intervalle pour le descripteur de Large Object %d" -#: libpq/be-fsstubs.c:455 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "doit être super-utilisateur pour utiliser lo_import() du côté serveur" - -#: libpq/be-fsstubs.c:456 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "Tout le monde peut utiliser lo_import(), fourni par libpq, du côté client." - -#: libpq/be-fsstubs.c:469 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier serveur « %s » : %m" -#: libpq/be-fsstubs.c:491 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "n'a pas pu lire le fichier serveur « %s » : %m" -#: libpq/be-fsstubs.c:521 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "doit être super-utilisateur pour utiliser lo_export() du côté serveur" - -#: libpq/be-fsstubs.c:522 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "Tout le monde peut utiliser lo_export(), fournie par libpq, du côté client." - -#: libpq/be-fsstubs.c:547 +#: libpq/be-fsstubs.c:511 #, c-format msgid "could not create server file \"%s\": %m" msgstr "n'a pas pu créer le fichier serveur « %s » : %m" -#: libpq/be-fsstubs.c:559 +#: libpq/be-fsstubs.c:523 #, c-format msgid "could not write server file \"%s\": %m" msgstr "n'a pas pu écrire le fichier serveur « %s » : %m" -#: libpq/be-fsstubs.c:813 +#: libpq/be-fsstubs.c:752 #, c-format msgid "large object read request is too large" msgstr "la demande de lecture du Large Object est trop grande" -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:212 utils/adt/genfile.c:253 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 utils/adt/genfile.c:306 #, c-format msgid "requested length cannot be negative" msgstr "la longueur demandée ne peut pas être négative" -#: libpq/be-secure-openssl.c:166 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "could not create SSL context: %s" -msgstr "n'a pas pu créer le contexte SSL : %s" +msgid "permission denied for large object %u" +msgstr "droit refusé pour le Large Object %u" -#: libpq/be-secure-openssl.c:194 +#: libpq/be-secure-common.c:91 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "n'a pas pu charger le fichier du certificat serveur « %s » : %s" +msgid "could not read from command \"%s\": %m" +msgstr "n'a pas pu lire à partir de la commande « %s » : %m" -#: libpq/be-secure-openssl.c:203 +#: libpq/be-secure-common.c:109 +#, c-format +msgid "command \"%s\" failed" +msgstr "la commande « %s » a échoué" + +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "n'a pas pu accéder au fichier de la clé privée « %s » : %m" -#: libpq/be-secure-openssl.c:212 +#: libpq/be-secure-common.c:148 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "le fichier de clé privée « %s » n'est pas un fichier" -#: libpq/be-secure-openssl.c:227 +#: libpq/be-secure-common.c:163 #, c-format msgid "private key file \"%s\" must be owned by the database user or root" msgstr "le fichier de clé privée « %s » doit avoir le même propriétaire que la base de donnée ou root" -#: libpq/be-secure-openssl.c:250 +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" msgstr "" "le fichier de clé privé « %s » est accessible par le groupe et/ou par les\n" "autres" -#: libpq/be-secure-openssl.c:252 +#: libpq/be-secure-common.c:188 #, c-format msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." msgstr "" "Le fichier doit avoir les permissions u=rw (0600) ou moins si le propriétaire est le même que la base de données,\n" "ou les permissions u=rw,g=r (0640) ou moins si le propriétaire est root." -#: libpq/be-secure-openssl.c:269 +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "n'a pas pu créer le contexte SSL : %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "n'a pas pu charger le fichier du certificat serveur « %s » : %s" + +#: libpq/be-secure-openssl.c:167 #, c-format msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" msgstr "le fichier de clé privée « %s » ne peut pas être rechargé car il nécessaire une phrase de passe" -#: libpq/be-secure-openssl.c:274 +#: libpq/be-secure-openssl.c:172 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "n'a pas pu charger le fichier de clé privée « %s » : %s" -#: libpq/be-secure-openssl.c:283 +#: libpq/be-secure-openssl.c:181 #, c-format msgid "check of private key failed: %s" msgstr "échec de la vérification de la clé privée : %s" -#: libpq/be-secure-openssl.c:302 +#: libpq/be-secure-openssl.c:208 #, c-format msgid "could not set the cipher list (no valid ciphers available)" msgstr "n'a pas pu configurer la liste des algorithmes de chiffrement (pas d'algorithmes valides disponibles)" -#: libpq/be-secure-openssl.c:320 +#: libpq/be-secure-openssl.c:226 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "n'a pas pu charger le fichier du certificat racine « %s » : %s" -#: libpq/be-secure-openssl.c:347 +#: libpq/be-secure-openssl.c:253 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "liste de révocation des certificats SSL « %s » ignorée" -#: libpq/be-secure-openssl.c:349 +#: libpq/be-secure-openssl.c:255 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "La bibliothèque SSL ne supporte pas les listes de révocation des certificats." -#: libpq/be-secure-openssl.c:356 +#: libpq/be-secure-openssl.c:262 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "n'a pas pu charger le fichier de liste de révocation des certificats SSL (« %s ») : %s" -#: libpq/be-secure-openssl.c:437 +#: libpq/be-secure-openssl.c:337 #, c-format msgid "could not initialize SSL connection: SSL context not set up" msgstr "n'a pas pu initialiser la connexion SSL : contexte SSL non configuré" -#: libpq/be-secure-openssl.c:445 +#: libpq/be-secure-openssl.c:345 #, c-format msgid "could not initialize SSL connection: %s" msgstr "n'a pas pu initialiser la connexion SSL : %s" -#: libpq/be-secure-openssl.c:453 +#: libpq/be-secure-openssl.c:353 #, c-format msgid "could not set SSL socket: %s" msgstr "n'a pas pu créer le socket SSL : %s" -#: libpq/be-secure-openssl.c:508 +#: libpq/be-secure-openssl.c:408 #, c-format msgid "could not accept SSL connection: %m" msgstr "n'a pas pu accepter la connexion SSL : %m" -#: libpq/be-secure-openssl.c:512 libpq/be-secure-openssl.c:523 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "n'a pas pu accepter la connexion SSL : fin de fichier détecté" -#: libpq/be-secure-openssl.c:517 +#: libpq/be-secure-openssl.c:417 #, c-format msgid "could not accept SSL connection: %s" msgstr "n'a pas pu accepter la connexion SSL : %s" -#: libpq/be-secure-openssl.c:528 libpq/be-secure-openssl.c:669 libpq/be-secure-openssl.c:735 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 libpq/be-secure-openssl.c:623 #, c-format msgid "unrecognized SSL error code: %d" msgstr "code d'erreur SSL inconnu : %d" -#: libpq/be-secure-openssl.c:570 +#: libpq/be-secure-openssl.c:470 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "le nom commun du certificat SSL contient des NULL" -#: libpq/be-secure-openssl.c:581 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "connexion SSL de « %s »" - -#: libpq/be-secure-openssl.c:658 libpq/be-secure-openssl.c:720 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format msgid "SSL error: %s" msgstr "erreur SSL : %s" -#: libpq/be-secure-openssl.c:900 +#: libpq/be-secure-openssl.c:788 #, c-format msgid "could not open DH parameters file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de paramètres DH « %s » : %m" -#: libpq/be-secure-openssl.c:912 +#: libpq/be-secure-openssl.c:800 #, c-format msgid "could not load DH parameters file: %s" msgstr "n'a pas pu charger le fichier de paramètres DH : %s" -#: libpq/be-secure-openssl.c:922 +#: libpq/be-secure-openssl.c:810 #, c-format msgid "invalid DH parameters: %s" msgstr "paramètres DH invalides : %s" -#: libpq/be-secure-openssl.c:930 +#: libpq/be-secure-openssl.c:818 #, c-format msgid "invalid DH parameters: p is not prime" msgstr "paramètres DH invalides : p n'est pas premier" -#: libpq/be-secure-openssl.c:938 +#: libpq/be-secure-openssl.c:826 #, c-format msgid "invalid DH parameters: neither suitable generator or safe prime" -msgstr "" +msgstr "paramètres DH invalides : pas de générateur convenable ou de premier sûr" -#: libpq/be-secure-openssl.c:1079 +#: libpq/be-secure-openssl.c:981 #, c-format msgid "DH: could not load DH parameters" msgstr "DH : n'a pas pu charger les paramètres DH" -#: libpq/be-secure-openssl.c:1087 +#: libpq/be-secure-openssl.c:989 #, c-format msgid "DH: could not set DH parameters: %s" msgstr "DH : n'a pas pu configurer les paramètres DH : %s" -#: libpq/be-secure-openssl.c:1111 +#: libpq/be-secure-openssl.c:1013 #, c-format msgid "ECDH: unrecognized curve name: %s" msgstr "ECDH : nome de courbe non reconnu : %s" -#: libpq/be-secure-openssl.c:1120 +#: libpq/be-secure-openssl.c:1022 #, c-format msgid "ECDH: could not create key" msgstr "ECDH : n'a pas pu créer la clé" -#: libpq/be-secure-openssl.c:1148 +#: libpq/be-secure-openssl.c:1050 msgid "no SSL error reported" msgstr "aucune erreur SSL reportée" -#: libpq/be-secure-openssl.c:1152 +#: libpq/be-secure-openssl.c:1054 #, c-format msgid "SSL error code %lu" msgstr "erreur SSL %lu" -#: libpq/be-secure.c:189 libpq/be-secure.c:275 +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "connexion SSL de « %s »" + +#: libpq/be-secure.c:196 libpq/be-secure.c:284 #, c-format msgid "terminating connection due to unexpected postmaster exit" msgstr "arrêt des connexions suite à un arrêt inatendu du postmaster" @@ -12622,27 +13193,22 @@ msgstr "Le rôle « %s » n'existe pas" msgid "User \"%s\" has no password assigned." msgstr "L'utilisateur « %s » n'a pas de mot de passe affecté." -#: libpq/crypt.c:76 -#, c-format -msgid "User \"%s\" has an empty password." -msgstr "L'utilisateur « %s » a un mot de passe vide." - -#: libpq/crypt.c:87 +#: libpq/crypt.c:79 #, c-format msgid "User \"%s\" has an expired password." msgstr "L'utilisateur « %s » a un mot de passe expiré." -#: libpq/crypt.c:181 +#: libpq/crypt.c:173 #, c-format msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "L'utilisateur « %s » a un mot de passe qui ne peut pas être utilisé avec une authentification MD5." -#: libpq/crypt.c:205 libpq/crypt.c:246 libpq/crypt.c:270 +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Mot de passe ne correspond pas pour l'utilisateur %s : " -#: libpq/crypt.c:289 +#: libpq/crypt.c:281 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "Le mot de passe de l'utilisateur « %s » est dans un format non reconnu." @@ -12665,7 +13231,7 @@ msgid "authentication file line too long" msgstr "ligne du fichier d'authentification trop longue" #: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 libpq/hba.c:1380 libpq/hba.c:1402 -#: libpq/hba.c:1414 libpq/hba.c:1432 libpq/hba.c:1482 libpq/hba.c:1521 libpq/hba.c:1532 libpq/hba.c:1549 libpq/hba.c:1559 libpq/hba.c:1617 libpq/hba.c:1655 libpq/hba.c:1671 libpq/hba.c:1770 libpq/hba.c:1859 libpq/hba.c:1878 libpq/hba.c:1907 libpq/hba.c:1920 libpq/hba.c:1943 libpq/hba.c:1965 libpq/hba.c:1979 tsearch/ts_locale.c:182 +#: libpq/hba.c:1414 libpq/hba.c:1432 libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "ligne %d du fichier de configuration « %s »" @@ -12849,147 +13415,152 @@ msgstr "l'authentification cert est seulement supportée sur les connexions host msgid "authentication option not in name=value format: %s" msgstr "l'option d'authentification n'est pas dans le format nom=valeur : %s" -#: libpq/hba.c:1520 +#: libpq/hba.c:1522 #, c-format -msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix" -msgstr "ne peut pas utiliser ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ou ldapurl avec ldapprefix" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ne peut pas utiliser ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchattribute ou ldapurl avec ldapprefix" -#: libpq/hba.c:1531 +#: libpq/hba.c:1533 #, c-format msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "" "la méthode d'authentification « ldap » requiert un argument « ldapbasedn »,\n" "« ldapprefix » ou « ldapsuffix » pour être mise en place" -#: libpq/hba.c:1548 +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ne peut pas utiliser ldapsearchattribute avec ldapsearchfilter" + +#: libpq/hba.c:1566 #, c-format msgid "list of RADIUS servers cannot be empty" msgstr "la liste de serveurs RADIUS ne peut pas être vide" -#: libpq/hba.c:1558 +#: libpq/hba.c:1576 #, c-format msgid "list of RADIUS secrets cannot be empty" msgstr "la liste des secrets RADIUS ne peut pas être vide" -#: libpq/hba.c:1611 +#: libpq/hba.c:1629 #, c-format -msgid "the number of %s (%i) must be 1 or the same as the number of %s (%i)" -msgstr "le nombre de %s (%i) doit valoir 1 ou être identique au nombre de %s (%i)" +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "le nombre de %s (%d) doit valoir 1 ou être identique au nombre de %s (%d)" -#: libpq/hba.c:1645 +#: libpq/hba.c:1663 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspi et cert" -#: libpq/hba.c:1654 +#: libpq/hba.c:1672 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "clientcert peut seulement être configuré pour les lignes « hostssl »" -#: libpq/hba.c:1670 +#: libpq/hba.c:1688 #, c-format msgid "clientcert can not be set to 0 when using \"cert\" authentication" msgstr "clientcert ne peut pas être initialisé à 0 si vous utilisez l'authentification « cert »" -#: libpq/hba.c:1707 +#: libpq/hba.c:1725 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "n'a pas pu analyser l'URL LDAP « %s » : %s" -#: libpq/hba.c:1717 +#: libpq/hba.c:1736 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "méthode URL LDAP non supporté : %s" -#: libpq/hba.c:1735 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "filtres non supportés dans les URL LDAP" - -#: libpq/hba.c:1744 +#: libpq/hba.c:1760 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "URL LDAP non supportés sur cette plateforme." -#: libpq/hba.c:1769 +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "valeur ldapscheme invalide : « %s »" + +#: libpq/hba.c:1796 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "numéro de port LDAP invalide : « %s »" -#: libpq/hba.c:1810 libpq/hba.c:1817 +#: libpq/hba.c:1842 libpq/hba.c:1849 msgid "gssapi and sspi" msgstr "gssapi et sspi" -#: libpq/hba.c:1826 libpq/hba.c:1835 +#: libpq/hba.c:1858 libpq/hba.c:1867 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1857 +#: libpq/hba.c:1889 #, c-format msgid "could not parse RADIUS server list \"%s\"" msgstr "n'a pas pu analyser la liste de serveurs RADIUS « %s »" -#: libpq/hba.c:1905 +#: libpq/hba.c:1937 #, c-format msgid "could not parse RADIUS port list \"%s\"" msgstr "n'a pas pu analyser la liste de ports RADIUS « %s »" -#: libpq/hba.c:1919 +#: libpq/hba.c:1951 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "numéro de port RADIUS invalide : « %s »" -#: libpq/hba.c:1941 +#: libpq/hba.c:1973 #, c-format msgid "could not parse RADIUS secret list \"%s\"" msgstr "n'a pas pu analyser la liste de secrets RADIUS « %s »" -#: libpq/hba.c:1963 +#: libpq/hba.c:1995 #, c-format msgid "could not parse RADIUS identifiers list \"%s\"" msgstr "n'a pas pu analyser la liste des identifieurs RADIUS « %s »" -#: libpq/hba.c:1977 +#: libpq/hba.c:2009 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "nom d'option de l'authentification inconnu : « %s »" -#: libpq/hba.c:2161 +#: libpq/hba.c:2193 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "le fichier de configuration « %s » ne contient aucun enregistrement" -#: libpq/hba.c:2666 +#: libpq/hba.c:2706 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "expression rationnelle invalide « %s » : %s" -#: libpq/hba.c:2726 +#: libpq/hba.c:2766 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "la correspondance de l'expression rationnelle pour « %s » a échoué : %s" -#: libpq/hba.c:2745 +#: libpq/hba.c:2785 #, c-format msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" msgstr "" "l'expression rationnelle « %s » n'a pas de sous-expressions comme celle\n" "demandée par la référence dans « %s »" -#: libpq/hba.c:2842 +#: libpq/hba.c:2882 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "" "le nom d'utilisateur (%s) et le nom d'utilisateur authentifié (%s) fournis ne\n" "correspondent pas" -#: libpq/hba.c:2862 +#: libpq/hba.c:2902 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "" "pas de correspondance dans la usermap « %s » pour l'utilisateur « %s »\n" "authentifié en tant que « %s »" -#: libpq/hba.c:2895 +#: libpq/hba.c:2935 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier usermap « %s » : %m" @@ -13119,7 +13690,7 @@ msgstr "il n'y a pas de connexion client" msgid "could not receive data from client: %m" msgstr "n'a pas pu recevoir les données du client : %m" -#: libpq/pqcomm.c:1219 tcop/postgres.c:3928 +#: libpq/pqcomm.c:1219 tcop/postgres.c:4020 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "arrêt de la connexion à cause d'une perte de synchronisation du protocole" @@ -13144,22 +13715,22 @@ msgstr "message incomplet du client" msgid "could not send data to client: %m" msgstr "n'a pas pu envoyer les données au client : %m" -#: libpq/pqformat.c:437 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "pas de données dans le message" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 #, c-format msgid "insufficient data left in message" msgstr "données insuffisantes laissées dans le message" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "chaîne invalide dans le message" -#: libpq/pqformat.c:682 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "format du message invalide" @@ -13479,12 +14050,12 @@ msgstr "le type de nœud extensible « %s » existe déjà" msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "ExtensibleNodeMethods \"%s\" n'a pas été enregistré" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1844 parser/parse_coerce.c:1872 parser/parse_coerce.c:1948 parser/parse_expr.c:2110 parser/parse_func.c:602 parser/parse_oper.c:964 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "n'a pas pu trouver de type tableau pour le type de données %s" -#: optimizer/path/joinrels.c:826 +#: optimizer/path/joinrels.c:831 #, c-format msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "" @@ -13492,128 +14063,123 @@ msgstr "" "jointures HASH JOIN" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1200 +#: optimizer/plan/initsplan.c:1212 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s ne peut être appliqué sur le côté possiblement NULL d'une jointure externe" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1544 parser/analyze.c:1624 parser/analyze.c:1821 parser/analyze.c:2615 +#: optimizer/plan/planner.c:1801 parser/analyze.c:1655 parser/analyze.c:1854 parser/analyze.c:2687 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s n'est pas autorisé avec UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:2144 optimizer/plan/planner.c:4102 +#: optimizer/plan/planner.c:2373 optimizer/plan/planner.c:4092 #, c-format msgid "could not implement GROUP BY" -msgstr "n'a pas pu implanté GROUP BY" +msgstr "n'a pas pu implanter GROUP BY" -#: optimizer/plan/planner.c:2145 optimizer/plan/planner.c:4103 optimizer/plan/planner.c:4843 optimizer/prep/prepunion.c:938 +#: optimizer/plan/planner.c:2374 optimizer/plan/planner.c:4093 optimizer/plan/planner.c:4836 optimizer/prep/prepunion.c:1080 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "" "Certains des types de données supportent seulement le hachage,\n" "alors que les autres supportent seulement le tri." -#: optimizer/plan/planner.c:4842 +#: optimizer/plan/planner.c:4835 #, c-format msgid "could not implement DISTINCT" -msgstr "n'a pas pu implanté DISTINCT" +msgstr "n'a pas pu implanter DISTINCT" -#: optimizer/plan/planner.c:5522 +#: optimizer/plan/planner.c:5518 #, c-format msgid "could not implement window PARTITION BY" msgstr "n'a pas pu implanter PARTITION BY de window" -#: optimizer/plan/planner.c:5523 +#: optimizer/plan/planner.c:5519 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "" "Les colonnes de partitionnement de window doivent être d'un type de données\n" "triables." -#: optimizer/plan/planner.c:5527 +#: optimizer/plan/planner.c:5523 #, c-format msgid "could not implement window ORDER BY" msgstr "n'a pas pu implanter ORDER BY dans le window" -#: optimizer/plan/planner.c:5528 +#: optimizer/plan/planner.c:5524 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Les colonnes de tri de la window doivent être d'un type de données triable." -#: optimizer/plan/setrefs.c:413 +#: optimizer/plan/setrefs.c:414 #, c-format msgid "too many range table entries" msgstr "trop d'enregistrements dans la table range" -#: optimizer/prep/prepunion.c:493 +#: optimizer/prep/prepunion.c:544 #, c-format msgid "could not implement recursive UNION" -msgstr "n'a pas pu implanté le UNION récursif" +msgstr "n'a pas pu implanter le UNION récursif" -#: optimizer/prep/prepunion.c:494 +#: optimizer/prep/prepunion.c:545 #, c-format msgid "All column datatypes must be hashable." msgstr "Tous les types de données colonnes doivent être hachables." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:937 +#: optimizer/prep/prepunion.c:1079 #, c-format msgid "could not implement %s" -msgstr "n'a pas pu implanté %s" +msgstr "n'a pas pu implanter %s" -#: optimizer/util/clauses.c:4689 +#: optimizer/util/clauses.c:4923 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "fonction SQL « %s » durant « inlining »" -#: optimizer/util/plancat.c:120 +#: optimizer/util/plancat.c:127 #, c-format msgid "cannot access temporary or unlogged relations during recovery" msgstr "ne peut pas accéder à des tables temporaires et non tracées lors de la restauration" -#: optimizer/util/plancat.c:620 +#: optimizer/util/plancat.c:651 #, c-format msgid "whole row unique index inference specifications are not supported" msgstr "les spécifications d'inférence d'index unique pour une ligne entière ne sont pas supportées" -#: optimizer/util/plancat.c:637 +#: optimizer/util/plancat.c:668 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "la contrainte de la clause ON CONFLICT n'a pas d'index associé" -#: optimizer/util/plancat.c:688 +#: optimizer/util/plancat.c:719 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" msgstr "ON CONFLICT DO UPDATE non supporté avec les contraintes d'exclusion" -#: optimizer/util/plancat.c:793 +#: optimizer/util/plancat.c:824 #, c-format msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "il n'existe aucune contrainte unique ou contrainte d'exclusion correspondant à la spécification ON CONFLICT" -#: parser/analyze.c:700 parser/analyze.c:1387 +#: parser/analyze.c:711 parser/analyze.c:1418 #, c-format msgid "VALUES lists must all be the same length" -msgstr "les listes VALUES doivent toutes être de la même longueur" - -#: parser/analyze.c:855 -#, c-format -msgid "ON CONFLICT clause is not supported with partitioned tables" -msgstr "la clause ON CONFLICT n'est pas supporté avec les tables partitionnées" +msgstr "les listes VALUES doivent toutes être de la même longueur" -#: parser/analyze.c:918 +#: parser/analyze.c:921 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT a plus d'expressions que les colonnes cibles" -#: parser/analyze.c:936 +#: parser/analyze.c:939 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT a plus de colonnes cibles que d'expressions" -#: parser/analyze.c:940 +#: parser/analyze.c:943 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "" @@ -13621,188 +14187,188 @@ msgstr "" "de colonnes que celui attendu par INSERT. Auriez-vous utilisé des parenthèses\n" "supplémentaires ?" -#: parser/analyze.c:1200 parser/analyze.c:1597 +#: parser/analyze.c:1229 parser/analyze.c:1628 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO n'est pas autorisé ici" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1529 parser/analyze.c:2794 +#: parser/analyze.c:1560 parser/analyze.c:2866 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s ne peut pas être appliqué à VALUES" -#: parser/analyze.c:1748 +#: parser/analyze.c:1779 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "clause UNION/INTERSECT/EXCEPT ORDER BY invalide" -#: parser/analyze.c:1749 +#: parser/analyze.c:1780 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "" "Seuls les noms de colonnes résultats peuvent être utilisés, pas les\n" "expressions et les fonctions." -#: parser/analyze.c:1750 +#: parser/analyze.c:1781 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Ajouter l'expression/fonction à chaque SELECT, ou déplacer l'UNION dans une clause FROM." -#: parser/analyze.c:1811 +#: parser/analyze.c:1844 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO est autorisé uniquement sur le premier SELECT d'un UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:1883 +#: parser/analyze.c:1916 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "" "L'instruction membre UNION/INTERSECT/EXCEPT ne peut pas faire référence à\n" "d'autres relations que celles de la requête de même niveau" -#: parser/analyze.c:1972 +#: parser/analyze.c:2005 #, c-format msgid "each %s query must have the same number of columns" msgstr "chaque requête %s doit avoir le même nombre de colonnes" -#: parser/analyze.c:2365 +#: parser/analyze.c:2398 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING doit avoir au moins une colonne" -#: parser/analyze.c:2406 +#: parser/analyze.c:2439 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "ne peut pas spécifier à la fois SCROLL et NO SCROLL" -#: parser/analyze.c:2425 +#: parser/analyze.c:2458 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR ne doit pas contenir des instructions de modification de données dans WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2433 +#: parser/analyze.c:2466 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s n'est pas supporté" -#: parser/analyze.c:2436 +#: parser/analyze.c:2469 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "Les curseurs détenables doivent être en lecture seule (READ ONLY)." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2444 +#: parser/analyze.c:2477 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s n'est pas supporté" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2455 +#: parser/analyze.c:2488 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %s n'est pas supporté" -#: parser/analyze.c:2458 +#: parser/analyze.c:2491 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "Les curseurs insensibles doivent être en lecture seule (READ ONLY)." -#: parser/analyze.c:2524 +#: parser/analyze.c:2557 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "les vues matérialisées ne peuvent pas contenir d'instructions de modifications de données avec WITH" -#: parser/analyze.c:2534 +#: parser/analyze.c:2567 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "les vues matérialisées ne doivent pas utiliser de tables temporaires ou de vues" -#: parser/analyze.c:2544 +#: parser/analyze.c:2577 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "les vues matérialisées ne peuvent pas être définies en utilisant des paramètres liés" -#: parser/analyze.c:2556 +#: parser/analyze.c:2589 #, c-format msgid "materialized views cannot be UNLOGGED" msgstr "les vues matérialisées ne peuvent pas être UNLOGGED" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2622 +#: parser/analyze.c:2694 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s n'est pas autorisé avec la clause DISTINCT" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2629 +#: parser/analyze.c:2701 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s n'est pas autorisé avec la clause GROUP BY" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2636 +#: parser/analyze.c:2708 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s n'est pas autorisé avec la clause HAVING" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2643 +#: parser/analyze.c:2715 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s n'est pas autorisé avec les fonctions d'agrégat" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2650 +#: parser/analyze.c:2722 #, c-format msgid "%s is not allowed with window functions" msgstr "%s n'est pas autorisé avec les fonctions de fenêtrage" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2657 +#: parser/analyze.c:2729 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s n'est pas autorisé avec les fonctions renvoyant plusieurs lignes dans la liste cible" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2736 +#: parser/analyze.c:2808 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s doit indiquer les noms de relation non qualifiés" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2767 +#: parser/analyze.c:2839 #, c-format msgid "%s cannot be applied to a join" msgstr "%s ne peut pas être appliqué à une jointure" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2776 +#: parser/analyze.c:2848 #, c-format msgid "%s cannot be applied to a function" msgstr "%s ne peut pas être appliqué à une fonction" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2785 +#: parser/analyze.c:2857 #, c-format msgid "%s cannot be applied to a table function" msgstr "%s ne peut pas être appliqué à une fonction de table" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2803 +#: parser/analyze.c:2875 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s ne peut pas être appliqué à une requête WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2812 +#: parser/analyze.c:2884 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%s ne peut pas être appliqué à une tuplestore nommé" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2829 +#: parser/analyze.c:2901 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "relation « %s » dans une clause %s introuvable dans la clause FROM" @@ -13870,543 +14436,598 @@ msgstr "les fonctions d'agrégats ne sont pas autorisés dans le ROWS de fenêtr msgid "grouping operations are not allowed in window ROWS" msgstr "les fonctions de regroupement ne sont pas autorisés dans le ROWS de fenêtrage" -#: parser/parse_agg.c:454 +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "les fonctions d'agrégats ne sont pas autorisés dans le GROUPS de fenêtrage" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "les fonctions de regroupement ne sont pas autorisés dans le GROUPS de fenêtrage" + +#: parser/parse_agg.c:461 msgid "aggregate functions are not allowed in check constraints" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les contraintes CHECK" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:463 msgid "grouping operations are not allowed in check constraints" msgstr "les fonctions de regroupement ne sont pas autorisés dans les contraintes CHECK" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:470 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les expressions par défaut" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:472 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions par défaut" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:477 msgid "aggregate functions are not allowed in index expressions" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les expressions d'index" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:479 msgid "grouping operations are not allowed in index expressions" msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions d'index" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:484 msgid "aggregate functions are not allowed in index predicates" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les prédicats d'index" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:486 msgid "grouping operations are not allowed in index predicates" msgstr "les fonctions de regroupement ne sont pas autorisés dans les prédicats d'index" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:491 msgid "aggregate functions are not allowed in transform expressions" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les expressions de transformation" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:493 msgid "grouping operations are not allowed in transform expressions" msgstr "les fonctions de regroupement ne sont pas autorisés dans les expressions de transformation" -#: parser/parse_agg.c:491 +#: parser/parse_agg.c:498 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les paramètres d'EXECUTE" -#: parser/parse_agg.c:493 +#: parser/parse_agg.c:500 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "les fonctions de regroupement ne sont pas autorisés dans les paramètres d'EXECUTE" -#: parser/parse_agg.c:498 +#: parser/parse_agg.c:505 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "les fonctions d'agrégats ne sont pas autorisés dans les conditions WHEN des triggers" -#: parser/parse_agg.c:500 +#: parser/parse_agg.c:507 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "les fonctions de regroupement ne sont pas autorisés dans les conditions WHEN des triggers" -#: parser/parse_agg.c:505 -msgid "aggregate functions are not allowed in partition key expression" +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" msgstr "les fonctions d'agrégats ne sont pas autorisées dans les expressions de clé de partitionnement" -#: parser/parse_agg.c:507 -msgid "grouping operations are not allowed in partition key expression" +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" msgstr "les opérations de regroupement ne sont pas autorisées dans les expressions de clé de partitionnement" +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "les fonctions d'agrégats ne sont pas autorisés dans les arguments de CALL" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "les fonctions de regroupement ne sont pas autorisés dans les arguments de CALL" + #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:530 parser/parse_clause.c:1830 +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "les fonctions d'agrégats ne sont pas autorisés dans %s" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:533 +#: parser/parse_agg.c:548 #, c-format msgid "grouping operations are not allowed in %s" msgstr "les fonctions de regroupement ne sont pas autorisés dans %s" -#: parser/parse_agg.c:641 +#: parser/parse_agg.c:656 #, c-format msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "un aggrégat de niveau externe ne peut pas contenir de variable de niveau inférieur dans ses arguments directs" -#: parser/parse_agg.c:720 +#: parser/parse_agg.c:735 #, c-format msgid "aggregate function calls cannot contain set-returning function calls" msgstr "" "les appels à la fonction d'agrégat ne peuvent pas contenir des appels à des\n" "fonction SETOF" -#: parser/parse_agg.c:721 parser/parse_expr.c:1761 parser/parse_expr.c:2237 parser/parse_func.c:773 +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 parser/parse_func.c:866 #, c-format msgid "You might be able to move the set-returning function into a LATERAL FROM item." msgstr "Vous devriez être capable de déplacer la fonction SETOF dans un élément LATERAL FROM." -#: parser/parse_agg.c:726 +#: parser/parse_agg.c:741 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "" "les appels à la fonction d'agrégat ne peuvent pas contenir des appels à la\n" "fonction window" -#: parser/parse_agg.c:805 +#: parser/parse_agg.c:820 msgid "window functions are not allowed in JOIN conditions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les conditions de jointure" -#: parser/parse_agg.c:812 +#: parser/parse_agg.c:827 msgid "window functions are not allowed in functions in FROM" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les fonctions contenues dans la clause FROM" -#: parser/parse_agg.c:818 +#: parser/parse_agg.c:833 msgid "window functions are not allowed in policy expressions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de politique" -#: parser/parse_agg.c:830 +#: parser/parse_agg.c:846 msgid "window functions are not allowed in window definitions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les définitions de fenêtres" -#: parser/parse_agg.c:862 +#: parser/parse_agg.c:878 msgid "window functions are not allowed in check constraints" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les contraintes CHECK" -#: parser/parse_agg.c:866 +#: parser/parse_agg.c:882 msgid "window functions are not allowed in DEFAULT expressions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions par défaut" -#: parser/parse_agg.c:869 +#: parser/parse_agg.c:885 msgid "window functions are not allowed in index expressions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions d'index" -#: parser/parse_agg.c:872 +#: parser/parse_agg.c:888 msgid "window functions are not allowed in index predicates" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les prédicats d'index" -#: parser/parse_agg.c:875 +#: parser/parse_agg.c:891 msgid "window functions are not allowed in transform expressions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de transformation" -#: parser/parse_agg.c:878 +#: parser/parse_agg.c:894 msgid "window functions are not allowed in EXECUTE parameters" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les paramètres d'EXECUTE" -#: parser/parse_agg.c:881 +#: parser/parse_agg.c:897 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les conditions WHEN des triggers" -#: parser/parse_agg.c:884 -msgid "window functions are not allowed in partition key expression" +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les expressions de clé de partitionnement" +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "les fonctions de fenêtrage ne sont pas autorisés dans les arguments de CALL" + #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:904 parser/parse_clause.c:1839 +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 #, c-format msgid "window functions are not allowed in %s" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans %s" -#: parser/parse_agg.c:938 parser/parse_clause.c:2673 +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 #, c-format msgid "window \"%s\" does not exist" msgstr "le window « %s » n'existe pas" -#: parser/parse_agg.c:1023 +#: parser/parse_agg.c:1042 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "trop d'ensembles de regroupement présents (4096 maximum)" -#: parser/parse_agg.c:1172 +#: parser/parse_agg.c:1191 #, c-format msgid "aggregate functions are not allowed in a recursive query's recursive term" msgstr "les fonctions de fenêtrage ne sont pas autorisés dans le terme récursif d'une requête récursive" -#: parser/parse_agg.c:1365 +#: parser/parse_agg.c:1384 #, c-format msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" msgstr "la colonne « %s.%s » doit apparaître dans la clause GROUP BY ou doit être utilisé dans une fonction d'agrégat" -#: parser/parse_agg.c:1368 +#: parser/parse_agg.c:1387 #, c-format msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "Les arguments directs d'un agégat par ensemble ordonné doivent seulement utiliser des colonnes groupées." -#: parser/parse_agg.c:1373 +#: parser/parse_agg.c:1392 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "" "la sous-requête utilise une colonne « %s.%s » non groupée dans la requête\n" "externe" -#: parser/parse_agg.c:1537 +#: parser/parse_agg.c:1556 #, c-format msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "les arguments de la clause GROUPING doivent être des expressions de regroupement du niveau de la requête associée" -#: parser/parse_clause.c:192 +#: parser/parse_clause.c:199 #, c-format msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "la relation « %s » ne peut pas être la cible d'une instruction modifiée" -#: parser/parse_clause.c:637 parser/parse_clause.c:665 parser/parse_func.c:2153 +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 #, c-format msgid "set-returning functions must appear at top level of FROM" msgstr "les fonctions renvoyant des ensembles doivent apparaître au niveau haut d'un FROM" -#: parser/parse_clause.c:677 +#: parser/parse_clause.c:655 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "plusieurs listes de définition de colonnes ne sont pas autorisées pour la même fonction" -#: parser/parse_clause.c:710 +#: parser/parse_clause.c:688 #, c-format msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "ROWS FROM() avec plusieurs fonctions ne peut pas avoir une liste de définitions de colonnes" -#: parser/parse_clause.c:711 +#: parser/parse_clause.c:689 #, c-format msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "Placer une liste de définitions de colonnes séparée pour chaque fonction à l'intérieur de ROWS FROM()." -#: parser/parse_clause.c:717 +#: parser/parse_clause.c:695 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "UNNEST() avec plusieurs arguments ne peut pas avoir de liste de définition de colonnes" -#: parser/parse_clause.c:718 +#: parser/parse_clause.c:696 #, c-format msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "Utiliser des appels séparés UNNEST() à l'intérieur de ROWS FROM(), et attacher une liste de définition des colonnes pour chaque." -#: parser/parse_clause.c:725 +#: parser/parse_clause.c:703 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY ne peut pas être utilisé avec une liste de définitions de colonnes" -#: parser/parse_clause.c:726 +#: parser/parse_clause.c:704 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "Placez la liste de définitions des colonnes dans ROWS FROM()." -#: parser/parse_clause.c:829 +#: parser/parse_clause.c:807 #, c-format msgid "only one FOR ORDINALITY column is allowed" msgstr "seule une colonne FOR ORDINALITY est autorisée" -#: parser/parse_clause.c:890 +#: parser/parse_clause.c:868 #, c-format msgid "column name \"%s\" is not unique" msgstr "le nom de colonne « %s » n'est pas unique" -#: parser/parse_clause.c:932 +#: parser/parse_clause.c:910 #, c-format msgid "namespace name \"%s\" is not unique" msgstr "l'espace de nom « %s » n'est pas unique" -#: parser/parse_clause.c:942 +#: parser/parse_clause.c:920 #, c-format msgid "only one default namespace is allowed" msgstr "seul un espace de nom par défaut est autorisé" -#: parser/parse_clause.c:1003 +#: parser/parse_clause.c:982 #, c-format msgid "tablesample method %s does not exist" msgstr "la méthode d'échantillonage %s n'existe pas" -#: parser/parse_clause.c:1025 +#: parser/parse_clause.c:1004 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "la méthode d'échantillonage %s requiert %d argument, et non pas %d" msgstr[1] "la méthode d'échantillonage %s requiert %d arguments, et non pas %d" -#: parser/parse_clause.c:1059 +#: parser/parse_clause.c:1038 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "la méthode d'échantillonage %s ne supporte pas REPEATABLE" -#: parser/parse_clause.c:1220 +#: parser/parse_clause.c:1208 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "la clause TABLESAMPLE est uniquement applicable pour les tables et les vues matérialisées" -#: parser/parse_clause.c:1390 +#: parser/parse_clause.c:1378 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "le nom de la colonne « %s » apparaît plus d'une fois dans la clause USING" -#: parser/parse_clause.c:1405 +#: parser/parse_clause.c:1393 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "" "le nom commun de la colonne « %s » apparaît plus d'une fois dans la table de\n" "gauche" -#: parser/parse_clause.c:1414 +#: parser/parse_clause.c:1402 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "" "la colonne « %s » spécifiée dans la clause USING n'existe pas dans la table\n" "de gauche" -#: parser/parse_clause.c:1428 +#: parser/parse_clause.c:1416 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "" "le nom commun de la colonne « %s » apparaît plus d'une fois dans la table de\n" " droite" -#: parser/parse_clause.c:1437 +#: parser/parse_clause.c:1425 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "" "la colonne « %s » spécifiée dans la clause USING n'existe pas dans la table\n" "de droite" -#: parser/parse_clause.c:1491 +#: parser/parse_clause.c:1479 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "la liste d'alias de colonnes pour « %s » a beaucoup trop d'entrées" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1800 +#: parser/parse_clause.c:1788 #, c-format msgid "argument of %s must not contain variables" msgstr "l'argument de « %s » ne doit pas contenir de variables" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1965 +#: parser/parse_clause.c:1953 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s « %s » est ambigu" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1994 +#: parser/parse_clause.c:1982 #, c-format msgid "non-integer constant in %s" msgstr "constante non entière dans %s" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:2016 +#: parser/parse_clause.c:2004 #, c-format msgid "%s position %d is not in select list" msgstr "%s, à la position %d, n'est pas dans la liste SELECT" -#: parser/parse_clause.c:2457 +#: parser/parse_clause.c:2445 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE est limité à 12 éléments" -#: parser/parse_clause.c:2661 +#: parser/parse_clause.c:2651 #, c-format msgid "window \"%s\" is already defined" msgstr "le window « %s » est déjà définie" -#: parser/parse_clause.c:2722 +#: parser/parse_clause.c:2712 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "n'a pas pu surcharger la clause PARTITION BY de window « %s »" -#: parser/parse_clause.c:2734 +#: parser/parse_clause.c:2724 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "n'a pas pu surcharger la clause ORDER BY de window « %s »" -#: parser/parse_clause.c:2764 parser/parse_clause.c:2770 +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "ne peut pas copier la fenêtre « %s » car il dispose d'une clause de portée" -#: parser/parse_clause.c:2772 +#: parser/parse_clause.c:2762 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Omettre les parenthèses dans cette clause OVER." -#: parser/parse_clause.c:2838 +#: parser/parse_clause.c:2782 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE avec offset PRECEDING/FOLLOWING nécessite exactement une colonne ORDER BY" + +#: parser/parse_clause.c:2805 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "le mode GROUPS nécessite une clause ORDER BY" + +#: parser/parse_clause.c:2875 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "" "dans un agrégat avec DISTINCT, les expressions ORDER BY doivent apparaître\n" "dans la liste d'argument" -#: parser/parse_clause.c:2839 +#: parser/parse_clause.c:2876 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "" "pour SELECT DISTINCT, ORDER BY, les expressions doivent apparaître dans la\n" "liste SELECT" -#: parser/parse_clause.c:2871 +#: parser/parse_clause.c:2908 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "un agrégat avec DISTINCT doit avoir au moins un argument" -#: parser/parse_clause.c:2872 +#: parser/parse_clause.c:2909 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT doit avoir au moins une colonne" -#: parser/parse_clause.c:2938 parser/parse_clause.c:2970 +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "" "les expressions SELECT DISTINCT ON doivent correspondre aux expressions\n" "ORDER BY initiales" -#: parser/parse_clause.c:3048 +#: parser/parse_clause.c:3085 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ASC/DESC n'est pas autorisé avec la clause ON CONFLICT" -#: parser/parse_clause.c:3054 +#: parser/parse_clause.c:3091 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "NULLS FIRST/LAST n'est pas autorisé avec la clause ON CONFLICT" -#: parser/parse_clause.c:3134 +#: parser/parse_clause.c:3170 #, c-format msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATE requiert une spécification d'inférence ou un nom de contrainte" -#: parser/parse_clause.c:3135 +#: parser/parse_clause.c:3171 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Par exemple, ON CONFLICT (nom_colonne)" -#: parser/parse_clause.c:3146 +#: parser/parse_clause.c:3182 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT n'est pas supporté avec les catalogues systèmes" -#: parser/parse_clause.c:3154 +#: parser/parse_clause.c:3190 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT n'est pas supporté sur la table « %s » utilisée comme une table catalogue" -#: parser/parse_clause.c:3280 +#: parser/parse_clause.c:3333 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "l'opérateur %s n'est pas un opérateur de tri valide" -#: parser/parse_clause.c:3282 +#: parser/parse_clause.c:3335 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "" "Les opérateurs de tri doivent être les membres « < » ou « > » des familles\n" "d'opérateurs btree." -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 parser/parse_expr.c:2144 parser/parse_expr.c:2732 parser/parse_target.c:936 +#: parser/parse_clause.c:3646 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING n'est pas supporté pour le type de collone %s" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING n'est pas supporté pour le type de colonne %s et le type d'ossfet %s" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Transtypez la valeur d'offset vers un type approprié." + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE avec offset PRECEDING/FOLLOWING a de multiples interprétations pour le type de colonne %s et le type d'offset %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Transtypez la valeur d'offset vers exactement le type attendu." + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:961 #, c-format msgid "cannot cast type %s to %s" msgstr "ne peut pas convertir le type %s en %s" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." msgstr "L'entrée n'a pas assez de colonnes." -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "ne peut pas convertir le type %s en %s dans la colonne %d" -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." msgstr "L'entrée a trop de colonnes." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1128 +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "l'argument de %s doit être de type %s, et non du type %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1091 parser/parse_coerce.c:1140 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "l'argument de %s ne doit pas renvoyer un ensemble" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1280 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "les %s types %s et %s ne peuvent pas correspondre" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1347 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "%s n'a pas pu convertir le type %s en %s" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "les arguments déclarés « anyelement » ne sont pas tous identiques" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "les arguments déclarés « anyarray » ne sont pas tous identiques" -#: parser/parse_coerce.c:1689 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "les arguments déclarés « anyrange » ne sont pas tous identiques" -#: parser/parse_coerce.c:1718 parser/parse_coerce.c:1933 parser/parse_coerce.c:1967 +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 parser/parse_coerce.c:2038 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "l'argument déclaré %s n'est pas un tableau mais est du type %s" -#: parser/parse_coerce.c:1734 parser/parse_coerce.c:1773 +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "l'argument déclaré %s n'est pas cohérent avec l'argument déclaré %s" -#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1980 +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "l'argument déclaré %s n'est pas un type d'intervalle mais est du type %s" -#: parser/parse_coerce.c:1794 +#: parser/parse_coerce.c:1865 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "" "n'a pas pu déterminer le type polymorphique car l'entrée dispose\n" "du type %s" -#: parser/parse_coerce.c:1805 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "le type déclaré anynonarray est un type tableau : %s" -#: parser/parse_coerce.c:1815 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "le type déclaré anyenum n'est pas un type enum : %s" -#: parser/parse_coerce.c:1855 parser/parse_coerce.c:1885 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "n'a pas pu trouver le type range pour le type de données %s" @@ -14547,7 +15168,7 @@ msgstr "la référence récursive à la requête « %s » ne doit pas apparaîtr msgid "DEFAULT is not allowed in this context" msgstr "DEFAULT interdit dans ce contexte" -#: parser/parse_expr.c:403 parser/parse_relation.c:3248 parser/parse_relation.c:3268 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 parser/parse_relation.c:3307 #, c-format msgid "column %s.%s does not exist" msgstr "la colonne %s.%s n'existe pas" @@ -14567,272 +15188,308 @@ msgstr "n'a pas pu identifier la colonne « %s » dans le type de données de l' msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "notation d'attribut .%s appliqué au type %s, qui n'est pas un type composé" -#: parser/parse_expr.c:458 parser/parse_target.c:722 +#: parser/parse_expr.c:458 parser/parse_target.c:728 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "l'expansion de ligne via « * » n'est pas supporté ici" -#: parser/parse_expr.c:767 parser/parse_relation.c:689 parser/parse_relation.c:789 parser/parse_target.c:1171 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 parser/parse_relation.c:789 parser/parse_target.c:1199 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "la référence à la colonne « %s » est ambigu" -#: parser/parse_expr.c:823 parser/parse_param.c:110 parser/parse_param.c:142 parser/parse_param.c:199 parser/parse_param.c:298 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "Il n'existe pas de paramètres $%d" -#: parser/parse_expr.c:1066 +#: parser/parse_expr.c:1070 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "NULLIF requiert l'opérateur = pour comparer des booleéns" #. translator: %s is name of a SQL construct, eg NULLIF -#: parser/parse_expr.c:1072 parser/parse_expr.c:3048 +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 #, c-format msgid "%s must not return a set" msgstr "%s ne doit pas renvoyer un ensemble" -#: parser/parse_expr.c:1519 parser/parse_expr.c:1551 +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 #, c-format msgid "number of columns does not match number of values" msgstr "le nombre de colonnes ne correspond pas au nombre de valeurs" -#: parser/parse_expr.c:1565 +#: parser/parse_expr.c:1570 #, c-format msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" msgstr "la source d'un élément UPDATE multi-colonnes doit être un sous-SELECT ou une expression ROW()" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_expr.c:1759 parser/parse_expr.c:2235 parser/parse_func.c:2256 +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 #, c-format msgid "set-returning functions are not allowed in %s" msgstr "les fonctions renvoyant un ensemble ne sont pas autorisés dans %s" -#: parser/parse_expr.c:1819 +#: parser/parse_expr.c:1825 msgid "cannot use subquery in check constraint" msgstr "ne peut pas utiliser une sous-requête dans la contrainte de vérification" -#: parser/parse_expr.c:1823 +#: parser/parse_expr.c:1829 msgid "cannot use subquery in DEFAULT expression" msgstr "ne peut pas utiliser de sous-requête dans une expression DEFAULT" -#: parser/parse_expr.c:1826 +#: parser/parse_expr.c:1832 msgid "cannot use subquery in index expression" msgstr "ne peut pas utiliser la sous-requête dans l'expression de l'index" -#: parser/parse_expr.c:1829 +#: parser/parse_expr.c:1835 msgid "cannot use subquery in index predicate" msgstr "ne peut pas utiliser une sous-requête dans un prédicat d'index" -#: parser/parse_expr.c:1832 +#: parser/parse_expr.c:1838 msgid "cannot use subquery in transform expression" msgstr "ne peut pas utiliser une sous-requête dans l'expression de transformation" -#: parser/parse_expr.c:1835 +#: parser/parse_expr.c:1841 msgid "cannot use subquery in EXECUTE parameter" msgstr "ne peut pas utiliser les sous-requêtes dans le paramètre EXECUTE" -#: parser/parse_expr.c:1838 +#: parser/parse_expr.c:1844 msgid "cannot use subquery in trigger WHEN condition" msgstr "ne peut pas utiliser une sous-requête dans la condition WHEN d'un trigger" -#: parser/parse_expr.c:1841 +#: parser/parse_expr.c:1847 msgid "cannot use subquery in partition key expression" msgstr "ne peut pas utiliser de sous-requête dans l'expression de clé de partitionnement" -#: parser/parse_expr.c:1894 +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "ne peut pas utiliser de sous-requête dans l'argument CALL" + +#: parser/parse_expr.c:1903 #, c-format msgid "subquery must return only one column" msgstr "la sous-requête doit renvoyer une seule colonne" -#: parser/parse_expr.c:1978 +#: parser/parse_expr.c:1987 #, c-format msgid "subquery has too many columns" msgstr "la sous-requête a trop de colonnes" -#: parser/parse_expr.c:1983 +#: parser/parse_expr.c:1992 #, c-format msgid "subquery has too few columns" msgstr "la sous-requête n'a pas assez de colonnes" -#: parser/parse_expr.c:2084 +#: parser/parse_expr.c:2093 #, c-format msgid "cannot determine type of empty array" msgstr "ne peut pas déterminer le type d'un tableau vide" -#: parser/parse_expr.c:2085 +#: parser/parse_expr.c:2094 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "Convertit explicitement vers le type désiré, par exemple ARRAY[]::integer[]." -#: parser/parse_expr.c:2099 +#: parser/parse_expr.c:2108 #, c-format msgid "could not find element type for data type %s" msgstr "n'a pas pu trouver le type d'élément pour le type de données %s" -#: parser/parse_expr.c:2386 +#: parser/parse_expr.c:2395 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "la valeur d'un attribut XML sans nom doit être une référence de colonne" -#: parser/parse_expr.c:2387 +#: parser/parse_expr.c:2396 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "la valeur d'un élément XML sans nom doit être une référence de colonne" -#: parser/parse_expr.c:2402 +#: parser/parse_expr.c:2411 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "le nom de l'attribut XML « %s » apparaît plus d'une fois" -#: parser/parse_expr.c:2509 +#: parser/parse_expr.c:2518 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "ne peut pas convertir le résultat XMLSERIALIZE en %s" -#: parser/parse_expr.c:2805 parser/parse_expr.c:3001 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format msgid "unequal number of entries in row expressions" msgstr "nombre différent d'entrées dans les expressions de ligne" -#: parser/parse_expr.c:2815 +#: parser/parse_expr.c:2824 #, c-format msgid "cannot compare rows of zero length" msgstr "n'a pas pu comparer des lignes de taille zéro" -#: parser/parse_expr.c:2840 +#: parser/parse_expr.c:2849 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "" "l'opérateur de comparaison de ligne doit renvoyer le type booléen, et non le\n" "type %s" -#: parser/parse_expr.c:2847 +#: parser/parse_expr.c:2856 #, c-format msgid "row comparison operator must not return a set" msgstr "l'opérateur de comparaison de ligne ne doit pas renvoyer un ensemble" -#: parser/parse_expr.c:2906 parser/parse_expr.c:2947 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "n'a pas pu déterminer l'interprétation de l'opérateur de comparaison de ligne %s" -#: parser/parse_expr.c:2908 +#: parser/parse_expr.c:2917 #, c-format msgid "Row comparison operators must be associated with btree operator families." msgstr "" "Les opérateurs de comparaison de lignes doivent être associés à des familles\n" "d'opérateurs btree." -#: parser/parse_expr.c:2949 +#: parser/parse_expr.c:2958 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "Il existe de nombreus candidats également plausibles." -#: parser/parse_expr.c:3042 +#: parser/parse_expr.c:3051 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROM requiert l'opérateur = pour comparer des booléens" -#: parser/parse_expr.c:3361 parser/parse_expr.c:3379 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "la précédence d'opérateur change : %s a maintenant une précédence inférieure à %s" -#: parser/parse_func.c:179 +#: parser/parse_func.c:185 #, c-format msgid "argument name \"%s\" used more than once" msgstr "nom « %s » de l'argument spécifié plus d'une fois" -#: parser/parse_func.c:190 +#: parser/parse_func.c:196 #, c-format msgid "positional argument cannot follow named argument" msgstr "l'argument positionné ne doit pas suivre l'argument nommé" -#: parser/parse_func.c:275 +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "%s n'est pas une procédure" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Pour appeler une fonction, utilisez SELECT." + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "%s est une procédure" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Pour appeler une procédure, utilisez CALL." + +#: parser/parse_func.c:306 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "%s(*) spécifié, mais %s n'est pas une fonction d'agrégat" -#: parser/parse_func.c:282 +#: parser/parse_func.c:313 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "DISTINCT spécifié mais %s n'est pas une fonction d'agrégat" -#: parser/parse_func.c:288 +#: parser/parse_func.c:319 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "WITHIN GROUP spécifié, mais %s n'est pas une fonction d'agrégat" -#: parser/parse_func.c:294 +#: parser/parse_func.c:325 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "ORDER BY spécifié, mais %s n'est pas une fonction d'agrégat" -#: parser/parse_func.c:300 +#: parser/parse_func.c:331 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "FILTER spécifié mais %s n'est pas une fonction d'agrégat" -#: parser/parse_func.c:306 +#: parser/parse_func.c:337 #, c-format msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "OVER spécifié, mais %s n'est pas une fonction window ou une fonction d'agrégat" -#: parser/parse_func.c:336 +#: parser/parse_func.c:375 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP est requis pour l'agrégat à ensemble ordonné %s" -#: parser/parse_func.c:342 +#: parser/parse_func.c:381 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVER n'est pas supporté pour l'agrégat %s à ensemble trié" -#: parser/parse_func.c:373 parser/parse_func.c:402 +#: parser/parse_func.c:412 parser/parse_func.c:441 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr "Il existe un agrégat par ensemble trié nommé %s, mais il requiert au moins %d arguments directs, pas %d." -#: parser/parse_func.c:427 +#: parser/parse_func.c:466 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "Pour utiliser l'agrégat à ensemble hypothétique %s, le nombre d'arguments directs hypothétiques (ici %d) doit correspondre au nombre de colonnes de tri (ici %d)." -#: parser/parse_func.c:441 +#: parser/parse_func.c:480 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr "Il existe un agrégat par ensemble trié nommé %s, mais il requiert au moins %d arguments directs." -#: parser/parse_func.c:460 +#: parser/parse_func.c:499 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s n'est pas un agrégat par ensemble trié, donc il ne peut pas avoir WITHIN GROUP" -#: parser/parse_func.c:473 +#: parser/parse_func.c:512 #, c-format msgid "window function %s requires an OVER clause" msgstr "la fonction de fenêtrage %s nécessite une clause OVER" -#: parser/parse_func.c:480 +#: parser/parse_func.c:519 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "la fonction de fenêtrage %s ne peut avoir WITHIN GROUP" -#: parser/parse_func.c:501 +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "la procédure %s n'est pas unique" + +#: parser/parse_func.c:551 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "" +"N'a pas pu choisir un meilleur candidat pour la procédure. Vous pourriez avoir besoin\n" +"d'ajouter une conversion de type explicite." + +#: parser/parse_func.c:557 #, c-format msgid "function %s is not unique" msgstr "la fonction %s n'est pas unique" -#: parser/parse_func.c:504 +#: parser/parse_func.c:560 #, c-format msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "" "N'a pas pu choisir un meilleur candidat dans les fonctions. Vous pourriez\n" "avoir besoin d'ajouter des conversions explicites de type." -#: parser/parse_func.c:515 +#: parser/parse_func.c:599 #, c-format msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "" @@ -14840,134 +15497,165 @@ msgstr "" "Peut-être avez-vous mal placé la clause ORDER BY.\n" "Cette dernière doit apparaître après tous les arguments standards de l'agrégat." -#: parser/parse_func.c:526 +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "la procédure %s n'existe pas" + +#: parser/parse_func.c:610 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "" +"Aucune procédure ne correspond au nom donné et aux types d'arguments.\n" +"Vous pourriez avoir avoir besoin d'ajouter des conversions de type explicites." + +#: parser/parse_func.c:619 #, c-format msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgstr "" "Aucune fonction ne correspond au nom donné et aux types d'arguments.\n" "Vous devez ajouter des conversions explicites de type." -#: parser/parse_func.c:628 +#: parser/parse_func.c:721 #, c-format msgid "VARIADIC argument must be an array" msgstr "l'argument VARIADIC doit être un tableau" -#: parser/parse_func.c:680 parser/parse_func.c:744 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*) doit être utilisé pour appeler une fonction d'agrégat sans paramètre" -#: parser/parse_func.c:687 +#: parser/parse_func.c:780 #, c-format msgid "aggregates cannot return sets" msgstr "les agrégats ne peuvent pas renvoyer des ensembles" -#: parser/parse_func.c:702 +#: parser/parse_func.c:795 #, c-format msgid "aggregates cannot use named arguments" msgstr "les agrégats ne peuvent pas utiliser des aguments nommés" -#: parser/parse_func.c:734 +#: parser/parse_func.c:827 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "DISTINCT n'est pas implémenté pour des fonctions window" -#: parser/parse_func.c:754 +#: parser/parse_func.c:847 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "l'agrégat ORDER BY n'est pas implémenté pour des fonctions window" -#: parser/parse_func.c:763 +#: parser/parse_func.c:856 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER n'est pas implémenté pour des fonctions de fenêtrage non agrégats" -#: parser/parse_func.c:772 +#: parser/parse_func.c:865 #, c-format msgid "window function calls cannot contain set-returning function calls" msgstr "" "les appels à la fonction de fenêtrage ne peuvent pas contenir des appels à des\n" "fonctions renvoyant des ensembles de lignes" -#: parser/parse_func.c:780 +#: parser/parse_func.c:873 #, c-format msgid "window functions cannot return sets" msgstr "les fonctions window ne peuvent pas renvoyer des ensembles" -#: parser/parse_func.c:1950 +#: parser/parse_func.c:2059 #, c-format msgid "function name \"%s\" is not unique" msgstr "le nom de la fonction « %s » n'est pas unique" -#: parser/parse_func.c:1952 +#: parser/parse_func.c:2061 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "Indiquez la liste d'arguments pour sélectionner la fonction sans ambiguïté." -#: parser/parse_func.c:1962 +#: parser/parse_func.c:2071 #, c-format msgid "could not find a function named \"%s\"" msgstr "n'a pas pu trouver une fonction nommée « %s »" -#: parser/parse_func.c:2064 +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s n'est pas une fonction" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "n'a pas pu trouver une procédure nommée « %s »" + +#: parser/parse_func.c:2198 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "n'a pas pu trouver un aggrégat nommé « %s »" + +#: parser/parse_func.c:2203 #, c-format msgid "aggregate %s(*) does not exist" msgstr "l'agrégat %s(*) n'existe pas" -#: parser/parse_func.c:2069 +#: parser/parse_func.c:2208 #, c-format msgid "aggregate %s does not exist" msgstr "l'agrégat %s n'existe pas" -#: parser/parse_func.c:2088 +#: parser/parse_func.c:2221 #, c-format msgid "function %s is not an aggregate" msgstr "la fonction %s n'est pas un agrégat" -#: parser/parse_func.c:2140 +#: parser/parse_func.c:2271 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "les fonctions renvoyant un ensemble de lignes ne sont pas autorisées dans les conditions JOIN" -#: parser/parse_func.c:2161 +#: parser/parse_func.c:2292 msgid "set-returning functions are not allowed in policy expressions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de politique" -#: parser/parse_func.c:2176 +#: parser/parse_func.c:2308 msgid "set-returning functions are not allowed in window definitions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les définitions de fenêtres" -#: parser/parse_func.c:2214 +#: parser/parse_func.c:2346 msgid "set-returning functions are not allowed in check constraints" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les contraintes CHECK" -#: parser/parse_func.c:2218 +#: parser/parse_func.c:2350 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions par défaut" -#: parser/parse_func.c:2221 +#: parser/parse_func.c:2353 msgid "set-returning functions are not allowed in index expressions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions d'index" -#: parser/parse_func.c:2224 +#: parser/parse_func.c:2356 msgid "set-returning functions are not allowed in index predicates" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les prédicats d'index" -#: parser/parse_func.c:2227 +#: parser/parse_func.c:2359 msgid "set-returning functions are not allowed in transform expressions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de transformation" -#: parser/parse_func.c:2230 +#: parser/parse_func.c:2362 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les paramètres d'EXECUTE" -#: parser/parse_func.c:2233 +#: parser/parse_func.c:2365 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les conditions WHEN des triggers" -#: parser/parse_func.c:2236 +#: parser/parse_func.c:2368 msgid "set-returning functions are not allowed in partition key expressions" msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les expressions de clé de partitionnement" +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "les fonctions renvoyant plusieurs lignes ne sont pas autorisées dans les arguments de CALL" + #: parser/parse_node.c:87 #, c-format msgid "target lists can have at most %d entries" @@ -15015,29 +15703,36 @@ msgstr "" "N'a pas pu choisir un meilleur candidat pour l'opérateur. Vous devez ajouter une\n" "conversion explicite de type." -#: parser/parse_oper.c:726 +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "" +"Aucun opérateur ne correspond au nom donné et au type d'argument.\n" +"Vous devez ajouter des conversions explicites de type." + +#: parser/parse_oper.c:729 #, c-format -msgid "No operator matches the given name and argument type(s). You might need to add explicit type casts." +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." msgstr "" "Aucun opérateur ne correspond au nom donné et aux types d'arguments.\n" "Vous devez ajouter des conversions explicites de type." -#: parser/parse_oper.c:787 parser/parse_oper.c:909 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "l'opérateur est seulement un shell : %s" -#: parser/parse_oper.c:897 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "op ANY/ALL (tableau) requiert un tableau sur le côté droit" -#: parser/parse_oper.c:939 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "op ANY/ALL (tableau) requiert un opérateur pour comparer des booléens" -#: parser/parse_oper.c:944 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "op ANY/ALL (tableau) requiert que l'opérateur ne renvoie pas un ensemble" @@ -15062,12 +15757,12 @@ msgstr "la référence à la table %u est ambigu" msgid "table name \"%s\" specified more than once" msgstr "le nom de la table « %s » est spécifié plus d'une fois" -#: parser/parse_relation.c:446 parser/parse_relation.c:3188 +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "référence invalide d'une entrée de la clause FROM pour la table « %s »" -#: parser/parse_relation.c:449 parser/parse_relation.c:3193 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "" @@ -15084,92 +15779,92 @@ msgstr "Le type JOIN combiné doit être INNER ou LEFT pour une référence LATE msgid "system column \"%s\" reference in check constraint is invalid" msgstr "la référence de la colonne système « %s » dans la contrainte CHECK est invalide" -#: parser/parse_relation.c:1086 parser/parse_relation.c:1372 parser/parse_relation.c:1941 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 parser/parse_relation.c:1936 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "la table « %s » a %d colonnes disponibles mais %d colonnes spécifiées" -#: parser/parse_relation.c:1179 +#: parser/parse_relation.c:1173 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "" "Il existe un élément WITH nommé « %s » mais il ne peut pas être\n" "référencée de cette partie de la requête." -#: parser/parse_relation.c:1181 +#: parser/parse_relation.c:1175 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "" "Utilisez WITH RECURSIVE ou ré-ordonnez les éléments WITH pour supprimer\n" "les références en avant." -#: parser/parse_relation.c:1492 +#: parser/parse_relation.c:1486 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "" "une liste de définition de colonnes est uniquement autorisée pour les fonctions\n" "renvoyant un « record »" -#: parser/parse_relation.c:1501 +#: parser/parse_relation.c:1495 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "" "une liste de définition de colonnes est requise pour les fonctions renvoyant\n" "un « record »" -#: parser/parse_relation.c:1580 +#: parser/parse_relation.c:1575 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "la fonction « %s » dans la clause FROM a un type de retour %s non supporté" -#: parser/parse_relation.c:1769 +#: parser/parse_relation.c:1764 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "" "les listes « %s » de VALUES ont %d colonnes disponibles mais %d colonnes\n" "spécifiées" -#: parser/parse_relation.c:1824 +#: parser/parse_relation.c:1819 #, c-format msgid "joins can have at most %d columns" msgstr "les jointures peuvent avoir au plus %d colonnes" -#: parser/parse_relation.c:1914 +#: parser/parse_relation.c:1909 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "La requête WITH « %s » n'a pas de clause RETURNING" -#: parser/parse_relation.c:2809 parser/parse_relation.c:2972 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 parser/parse_relation.c:3011 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "la colonne %d de la relation « %s » n'existe pas" -#: parser/parse_relation.c:3191 +#: parser/parse_relation.c:3230 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Peut-être que vous souhaitiez référencer l'alias de la table « %s »." -#: parser/parse_relation.c:3199 +#: parser/parse_relation.c:3238 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "entrée manquante de la clause FROM pour la table « %s »" -#: parser/parse_relation.c:3251 +#: parser/parse_relation.c:3290 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Peut-être que vous souhaitiez référencer la colonne « %s.%s »." -#: parser/parse_relation.c:3253 +#: parser/parse_relation.c:3292 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "Il existe une colonne nommée « %s » pour la table « %s » mais elle ne peut pas être référencée dans cette partie de la requête." -#: parser/parse_relation.c:3270 +#: parser/parse_relation.c:3309 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "Peut-être que vous souhaitiez référencer la colonne « %s.%s » ou la colonne « %s.%s »." -#: parser/parse_target.c:483 parser/parse_target.c:775 +#: parser/parse_target.c:483 parser/parse_target.c:790 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "ne peut pas affecter à une colonne système « %s »" @@ -15189,33 +15884,33 @@ msgstr "ne peut pas initialiser un sous-champ avec DEFAULT" msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "la colonne « %s » est de type %s mais l'expression est de type %s" -#: parser/parse_target.c:759 +#: parser/parse_target.c:774 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" msgstr "" "ne peut pas l'affecter au champ « %s » de la colonne « %s » parce que son\n" "type %s n'est pas un type composé" -#: parser/parse_target.c:768 +#: parser/parse_target.c:783 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgstr "" "ne peut pas l'affecter au champ « %s » de la colonne « %s » parce qu'il n'existe\n" "pas une telle colonne dans le type de données %s" -#: parser/parse_target.c:835 +#: parser/parse_target.c:860 #, c-format msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "" "l'affectation d'un tableau avec « %s » requiert le type %s mais l'expression est\n" "de type %s" -#: parser/parse_target.c:845 +#: parser/parse_target.c:870 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "le sous-champ « %s » est de type %s mais l'expression est de type %s" -#: parser/parse_target.c:1261 +#: parser/parse_target.c:1289 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "Un SELECT * sans table spécifiée n'est pas valide" @@ -15235,7 +15930,7 @@ msgstr "référence %%TYPE invalide (trop de points entre les noms) : %s" msgid "type reference %s converted to %s" msgstr "référence de type %s convertie en %s" -#: parser/parse_type.c:261 parser/parse_type.c:804 utils/cache/typcache.c:243 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format msgid "type \"%s\" is only a shell" msgstr "le type « %s » est seulement un shell" @@ -15250,74 +15945,69 @@ msgstr "le modificateur de type n'est pas autorisé pour le type « %s »" msgid "type modifiers must be simple constants or identifiers" msgstr "les modificateurs de type doivent être des constantes ou des identifiants" -#: parser/parse_type.c:670 parser/parse_type.c:769 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "nom de type « %s » invalide" -#: parser/parse_utilcmd.c:265 +#: parser/parse_utilcmd.c:272 #, c-format msgid "cannot create partitioned table as inheritance child" msgstr "ne peut pas créer une table partitionnée comme la fille d'un héritage" -#: parser/parse_utilcmd.c:435 +#: parser/parse_utilcmd.c:448 #, c-format msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" msgstr "%s créera des séquences implicites « %s » pour la colonne serial « %s.%s »" -#: parser/parse_utilcmd.c:550 +#: parser/parse_utilcmd.c:571 #, c-format msgid "array of serial is not implemented" msgstr "le tableau de type serial n'est pas implanté" -#: parser/parse_utilcmd.c:626 parser/parse_utilcmd.c:638 +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 #, c-format msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "déclarations NULL/NOT NULL en conflit pour la colonne « %s » de la table « %s »" -#: parser/parse_utilcmd.c:650 +#: parser/parse_utilcmd.c:671 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "" "plusieurs valeurs par défaut sont spécifiées pour la colonne « %s » de la table\n" "« %s »" -#: parser/parse_utilcmd.c:671 +#: parser/parse_utilcmd.c:688 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "les colonnes d'identité uniques ne sont pas supportées sur les tables typées" + +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "les colonnes d'identité ne sont pas supportées sur les partitions" + +#: parser/parse_utilcmd.c:701 #, c-format msgid "multiple identity specifications for column \"%s\" of table \"%s\"" msgstr "plusieurs spécifications d'identité pour la colonne « %s » de la table « %s »" -#: parser/parse_utilcmd.c:694 parser/parse_utilcmd.c:811 +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 #, c-format msgid "primary key constraints are not supported on foreign tables" msgstr "les clés primaires ne sont pas supportées par les tables distantes" -#: parser/parse_utilcmd.c:700 parser/parse_utilcmd.c:817 -#, c-format -msgid "primary key constraints are not supported on partitioned tables" -msgstr "les clés primaires ne sont pas supportées sur les tables partitionnées" - -#: parser/parse_utilcmd.c:709 parser/parse_utilcmd.c:827 +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 #, c-format msgid "unique constraints are not supported on foreign tables" msgstr "les contraintes uniques ne sont pas supportées par les tables distantes" -#: parser/parse_utilcmd.c:715 parser/parse_utilcmd.c:833 -#, c-format -msgid "unique constraints are not supported on partitioned tables" -msgstr "les contraintes uniques ne sont pas supportées sur les tables partitionnées" - -#: parser/parse_utilcmd.c:732 parser/parse_utilcmd.c:863 +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "les clés étrangères ne sont pas supportées par les tables distantes" -#: parser/parse_utilcmd.c:738 parser/parse_utilcmd.c:869 -#, c-format -msgid "foreign key constraints are not supported on partitioned tables" -msgstr "les clés étrangères ne sont pas supportées sur les tables partitionnées" - -#: parser/parse_utilcmd.c:766 +#: parser/parse_utilcmd.c:778 #, c-format msgid "both default and identity specified for column \"%s\" of table \"%s\"" msgstr "une valeur par défaut et une identité ont été spécifiées pour la colonne « %s » de la table « %s »" @@ -15332,213 +16022,253 @@ msgstr "les contraintes d'exclusion ne sont pas supportées par les tables dista msgid "exclusion constraints are not supported on partitioned tables" msgstr "les contraintes d'exclusion ne sont pas supportées sur les tables partitionnées" -#: parser/parse_utilcmd.c:919 +#: parser/parse_utilcmd.c:913 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKE n'est pas supporté pour la création de tables distantes" -#: parser/parse_utilcmd.c:1474 parser/parse_utilcmd.c:1550 +#: parser/parse_utilcmd.c:1516 parser/parse_utilcmd.c:1623 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "l'index « %s » contient une référence de table de ligne complète" -#: parser/parse_utilcmd.c:1819 +#: parser/parse_utilcmd.c:1973 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "ne peut pas utiliser un index existant dans CREATE TABLE" -#: parser/parse_utilcmd.c:1839 +#: parser/parse_utilcmd.c:1993 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "l'index « %s » est déjà associé à une contrainte" -#: parser/parse_utilcmd.c:1847 +#: parser/parse_utilcmd.c:2001 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "l'index « %s » n'appartient pas à la table « %s »" -#: parser/parse_utilcmd.c:1854 +#: parser/parse_utilcmd.c:2008 #, c-format msgid "index \"%s\" is not valid" msgstr "l'index « %s » n'est pas valide" -#: parser/parse_utilcmd.c:1860 +#: parser/parse_utilcmd.c:2014 #, c-format msgid "\"%s\" is not a unique index" msgstr "« %s » n'est pas un index unique" -#: parser/parse_utilcmd.c:1861 parser/parse_utilcmd.c:1868 parser/parse_utilcmd.c:1875 parser/parse_utilcmd.c:1945 +#: parser/parse_utilcmd.c:2015 parser/parse_utilcmd.c:2022 parser/parse_utilcmd.c:2029 parser/parse_utilcmd.c:2101 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "Ne peut pas créer une clé primaire ou une contrainte unique avec cet index." -#: parser/parse_utilcmd.c:1867 +#: parser/parse_utilcmd.c:2021 #, c-format msgid "index \"%s\" contains expressions" msgstr "l'index « %s » contient des expressions" -#: parser/parse_utilcmd.c:1874 +#: parser/parse_utilcmd.c:2028 #, c-format msgid "\"%s\" is a partial index" msgstr "« %s » est un index partiel" -#: parser/parse_utilcmd.c:1886 +#: parser/parse_utilcmd.c:2040 #, c-format msgid "\"%s\" is a deferrable index" msgstr "« %s » est un index déferrable" -#: parser/parse_utilcmd.c:1887 +#: parser/parse_utilcmd.c:2041 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "Ne peut pas créer une contrainte non-déferrable utilisant un index déferrable." -#: parser/parse_utilcmd.c:1944 +#: parser/parse_utilcmd.c:2100 #, c-format msgid "index \"%s\" does not have default sorting behavior" msgstr "l'index « %s » n'a pas de comportement de tri par défaut" -#: parser/parse_utilcmd.c:2088 +#: parser/parse_utilcmd.c:2249 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "la colonne « %s » apparaît deux fois dans la contrainte de la clé primaire" -#: parser/parse_utilcmd.c:2094 +#: parser/parse_utilcmd.c:2255 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "la colonne « %s » apparaît deux fois sur une contrainte unique" -#: parser/parse_utilcmd.c:2303 +#: parser/parse_utilcmd.c:2578 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "les expressions et prédicats d'index peuvent seulement faire référence à la table en cours d'indexage" -#: parser/parse_utilcmd.c:2349 +#: parser/parse_utilcmd.c:2624 #, c-format msgid "rules on materialized views are not supported" msgstr "les règles ne sont pas supportés sur les vues matérialisées" -#: parser/parse_utilcmd.c:2410 +#: parser/parse_utilcmd.c:2685 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "" "la condition WHERE d'une règle ne devrait pas contenir de références à d'autres\n" "relations" -#: parser/parse_utilcmd.c:2482 +#: parser/parse_utilcmd.c:2757 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "" "les règles avec des conditions WHERE ne peuvent contenir que des actions\n" "SELECT, INSERT, UPDATE ou DELETE " -#: parser/parse_utilcmd.c:2500 parser/parse_utilcmd.c:2599 rewrite/rewriteHandler.c:500 rewrite/rewriteManip.c:1015 +#: parser/parse_utilcmd.c:2775 parser/parse_utilcmd.c:2874 rewrite/rewriteHandler.c:497 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "" "les instructions conditionnelles UNION/INTERSECT/EXCEPT ne sont pas\n" "implémentées" -#: parser/parse_utilcmd.c:2518 +#: parser/parse_utilcmd.c:2793 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "la règle ON SELECT ne peut pas utiliser OLD" -#: parser/parse_utilcmd.c:2522 +#: parser/parse_utilcmd.c:2797 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "la règle ON SELECT ne peut pas utiliser NEW" -#: parser/parse_utilcmd.c:2531 +#: parser/parse_utilcmd.c:2806 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "la règle ON INSERT ne peut pas utiliser OLD" -#: parser/parse_utilcmd.c:2537 +#: parser/parse_utilcmd.c:2812 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "la règle ON INSERT ne peut pas utiliser NEW" -#: parser/parse_utilcmd.c:2565 +#: parser/parse_utilcmd.c:2840 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "ne peut référencer OLD dans une requête WITH" -#: parser/parse_utilcmd.c:2572 +#: parser/parse_utilcmd.c:2847 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "ne peut référencer NEW dans une requête WITH" -#: parser/parse_utilcmd.c:3005 +#: parser/parse_utilcmd.c:3285 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "clause DEFERRABLE mal placée" -#: parser/parse_utilcmd.c:3010 parser/parse_utilcmd.c:3025 +#: parser/parse_utilcmd.c:3290 parser/parse_utilcmd.c:3305 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "clauses DEFERRABLE/NOT DEFERRABLE multiples non autorisées" -#: parser/parse_utilcmd.c:3020 +#: parser/parse_utilcmd.c:3300 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "clause NOT DEFERRABLE mal placée" -#: parser/parse_utilcmd.c:3041 +#: parser/parse_utilcmd.c:3321 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "clause INITIALLY DEFERRED mal placée" -#: parser/parse_utilcmd.c:3046 parser/parse_utilcmd.c:3072 +#: parser/parse_utilcmd.c:3326 parser/parse_utilcmd.c:3352 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "clauses INITIALLY IMMEDIATE/DEFERRED multiples non autorisées" -#: parser/parse_utilcmd.c:3067 +#: parser/parse_utilcmd.c:3347 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "clause INITIALLY IMMEDIATE mal placée" -#: parser/parse_utilcmd.c:3258 +#: parser/parse_utilcmd.c:3538 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE spécifie un schéma (%s) différent de celui tout juste créé (%s)" -#: parser/parse_utilcmd.c:3317 +#: parser/parse_utilcmd.c:3572 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "la table « %s » n'est pas partitionné" + +#: parser/parse_utilcmd.c:3579 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "l'index « %s » n'est pas partitionné" + +#: parser/parse_utilcmd.c:3613 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "une table partitionnées par hash ne peut pas avoir de partition par défaut" + +#: parser/parse_utilcmd.c:3630 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "spécification de limite invalide pour une partition par hash" + +#: parser/parse_utilcmd.c:3636 partitioning/partbounds.c:2127 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "le modulus pour une partition par hash doit être un entier positif" + +#: parser/parse_utilcmd.c:3643 partitioning/partbounds.c:2135 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "le modulus pour une partition par hash doit être inférieur au modulus" + +#: parser/parse_utilcmd.c:3655 #, c-format msgid "invalid bound specification for a list partition" msgstr "spécification de limite invalide pour une partition par liste" -#: parser/parse_utilcmd.c:3373 +#: parser/parse_utilcmd.c:3711 #, c-format msgid "invalid bound specification for a range partition" msgstr "spécification de limite invalide pour une partition par intervalle" -#: parser/parse_utilcmd.c:3379 +#: parser/parse_utilcmd.c:3717 #, c-format msgid "FROM must specify exactly one value per partitioning column" msgstr "FROM doit spécifier exactement une valeur par colonne de partitionnement" -#: parser/parse_utilcmd.c:3383 +#: parser/parse_utilcmd.c:3721 #, c-format msgid "TO must specify exactly one value per partitioning column" msgstr "TO doit spécifier exactement une valeur par colonne de partitionnement" -#: parser/parse_utilcmd.c:3423 parser/parse_utilcmd.c:3437 +#: parser/parse_utilcmd.c:3768 parser/parse_utilcmd.c:3782 #, c-format msgid "cannot specify NULL in range bound" msgstr "ne peut pas spécifier NULL dans la limite de l'intervalle" -#: parser/parse_utilcmd.c:3480 parser/parse_utilcmd.c:3492 +#: parser/parse_utilcmd.c:3829 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "chaque limite suivant MAXVALUE doit aussi être MAXVALUE" + +#: parser/parse_utilcmd.c:3836 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "chaque limite suivant MINVALUE doit aussi être MINVALUE" + +#: parser/parse_utilcmd.c:3867 parser/parse_utilcmd.c:3879 #, c-format msgid "specified value cannot be cast to type %s for column \"%s\"" msgstr "la valeur spécifiée ne peut pas être convertie vers le type %s pour la colonne « %s »" -#: parser/parse_utilcmd.c:3494 +#: parser/parse_utilcmd.c:3881 #, c-format msgid "The cast requires a non-immutable conversion." msgstr "Cette conversion requiert une conversion non immutable." -#: parser/parse_utilcmd.c:3495 +#: parser/parse_utilcmd.c:3882 #, c-format msgid "Try putting the literal value in single quotes." msgstr "Placer la valeur littérale en guillemets simples." @@ -15548,17 +16278,74 @@ msgstr "Placer la valeur littérale en guillemets simples." msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "l'identifiant « %s » sera tronqué en « %s »" -#: port/pg_shmem.c:196 port/sysv_shmem.c:196 +#: partitioning/partbounds.c:331 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "la partition « %s » est en conflit avec la partition par défaut existante « %s »" + +#: partitioning/partbounds.c:390 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "chaque modulo de partition hash doit être un facteur du prochain plus gros modulo" + +#: partitioning/partbounds.c:486 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "limite d'intervalle vide indiquée pour la parttion « %s »" + +#: partitioning/partbounds.c:488 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "" +"la limite inférieure spécifiée %s est supérieure ou égale\n" +"à la limite supérieure %s." + +#: partitioning/partbounds.c:585 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "la partition « %s » surchargerait la partition « %s »" + +#: partitioning/partbounds.c:685 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "parcours ignoré pour la table distante « %s » qui n'est pas une partition ou partition par défaut « %s »" + +#: partitioning/partbounds.c:724 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "la contrainte de partition mise à jour pour la partition par défaut « %s » serait transgressée par des lignes" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "le reste pour une partition hash doit être un entier non négatif" + +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "« %s » n'est pas une table partitionnée par hash" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "le nombre de colonnes de partitionnement (%d) ne correspond pas au nombre de clés de partitionnement fourni (%d)" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "la colonne %d de la clé de partitionnement a pour type « %s », mais la valeur fournie a pour type « %s »" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 #, c-format msgid "could not create shared memory segment: %m" msgstr "n'a pas pu créer le segment de mémoire partagée : %m" -#: port/pg_shmem.c:197 port/sysv_shmem.c:197 +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "L'appel système qui a échoué était shmget(clé=%lu, taille=%zu, 0%o)." -#: port/pg_shmem.c:201 port/sysv_shmem.c:201 +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" @@ -15567,7 +16354,7 @@ msgstr "" "Cette erreur signifie habituellement que la demande de PostgreSQL pour un segment de mémoire partagée dépasse la valeur du paramètre SHMMAX du noyau, ou est plus petite\n" "que votre paramètre SHMMIN du noyau. La documentation PostgreSQL contient plus d'information sur la configuration de la mémoire partagée." -#: port/pg_shmem.c:208 port/sysv_shmem.c:208 +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" @@ -15576,7 +16363,7 @@ msgstr "" "Cette erreur signifie habituellement que la demande de PostgreSQL pour un segment de mémoire partagée dépasse le paramètre SHMALL du noyau. Vous pourriez avoir besoin de reconfigurer\n" "le noyau avec un SHMALL plus important. La documentation PostgreSQL contient plus d'information sur la configuration de la mémoire partagée." -#: port/pg_shmem.c:214 port/sysv_shmem.c:214 +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 #, c-format msgid "" "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" @@ -15585,12 +16372,12 @@ msgstr "" "Cette erreur ne signifie *pas* que vous manquez d'espace disque. Elle survient si tous les identifiants de mémoire partagé disponibles ont été pris, auquel cas vous devez augmenter le paramètre SHMMNI de votre noyau, ou parce que la limite maximum de la mémoire partagée\n" "de votre système a été atteinte. La documentation de PostgreSQL contient plus d'informations sur la configuration de la mémoire partagée." -#: port/pg_shmem.c:505 port/sysv_shmem.c:505 +#: port/pg_shmem.c:553 port/sysv_shmem.c:553 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "n'a pas pu créer le segment de mémoire partagée anonyme : %m" -#: port/pg_shmem.c:507 port/sysv_shmem.c:507 +#: port/pg_shmem.c:555 port/sysv_shmem.c:555 #, c-format msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." msgstr "" @@ -15601,12 +16388,24 @@ msgstr "" "valeur du paramètre shared_buffers de PostgreSQL ou le paramètre\n" "max_connections." -#: port/pg_shmem.c:573 port/sysv_shmem.c:573 port/win32_shmem.c:134 +#: port/pg_shmem.c:617 port/sysv_shmem.c:617 #, c-format msgid "huge pages not supported on this platform" msgstr "Huge Pages non supporté sur cette plateforme" -#: port/pg_shmem.c:668 port/sysv_shmem.c:668 +#: port/pg_shmem.c:680 port/sysv_shmem.c:680 utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "" +"le bloc de mémoire partagé pré-existant (clé %lu, ID %lu) est en cours\n" +"d'utilisation" + +#: port/pg_shmem.c:683 port/sysv_shmem.c:683 utils/init/miscinit.c:1071 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Termine les anciens processus serveurs associés avec le répertoire de données « %s »." + +#: port/pg_shmem.c:734 port/sysv_shmem.c:734 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "n'a pas pu lire les informations sur le répertoire des données « %s » : %m" @@ -15705,156 +16504,186 @@ msgstr "n'a pas pu déverrouiller la sémaphore : code d'erreur %lu" msgid "could not try-lock semaphore: error code %lu" msgstr "n'a pas pu tenter le verrouillage de la sémaphore : code d'erreur %lu" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "n'a pas pu activer le Lock Pages in Memory user right : code d'erreur %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "L'appel système qui a échoué était %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "n'a pas pu activer le Lock Pages in Memory user right" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Assignez le droit d'utilisateur Lock Pages in Memory au compte d'utilisateur Windows qui fait tourner PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "le processeur ne supporte pas les Large Pages" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "désactivation des Huge Pages" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "n'a pas pu créer le segment de mémoire partagée : code d'erreur %lu" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:303 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "L'appel système qui a échoué était CreateFileMapping(taille=%zu, nom=%s)." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:328 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "le bloc de mémoire partagé pré-existant est toujours en cours d'utilisation" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:329 #, c-format msgid "Check if there are any old server processes still running, and terminate them." msgstr "" "Vérifier s'il n'y a pas de vieux processus serveur en cours d'exécution. Si c'est le\n" "cas, fermez-les." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:339 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "L'appel système qui a échoué était DuplicateHandle." -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:357 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "L'appel système qui a échoué était MapViewOfFileEx." -#: postmaster/autovacuum.c:416 +#: postmaster/autovacuum.c:406 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "n'a pas pu exécuter le processus autovacuum maître : %m" -#: postmaster/autovacuum.c:452 +#: postmaster/autovacuum.c:442 #, c-format msgid "autovacuum launcher started" msgstr "lancement du processus autovacuum" -#: postmaster/autovacuum.c:839 +#: postmaster/autovacuum.c:832 #, c-format msgid "autovacuum launcher shutting down" msgstr "arrêt du processus autovacuum" -#: postmaster/autovacuum.c:1501 +#: postmaster/autovacuum.c:1494 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "n'a pas pu exécuter le processus autovacuum worker : %m" -#: postmaster/autovacuum.c:1707 +#: postmaster/autovacuum.c:1700 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "autovacuum : traitement de la base de données « %s »" -#: postmaster/autovacuum.c:2281 +#: postmaster/autovacuum.c:2269 #, c-format msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" msgstr "autovacuum : suppression de la table temporaire orpheline « %s.%s.%s »" -#: postmaster/autovacuum.c:2487 +#: postmaster/autovacuum.c:2498 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "VACUUM automatique de la table « %s.%s.%s »" -#: postmaster/autovacuum.c:2490 +#: postmaster/autovacuum.c:2501 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "ANALYZE automatique de la table « %s.%s.%s »" -#: postmaster/autovacuum.c:2701 +#: postmaster/autovacuum.c:2694 #, c-format msgid "processing work entry for relation \"%s.%s.%s\"" msgstr "traitement de l'enregistrement de travail pour la relation « %s.%s.%s »" -#: postmaster/autovacuum.c:3345 +#: postmaster/autovacuum.c:3273 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "autovacuum non exécuté à cause d'une mauvaise configuration" -#: postmaster/autovacuum.c:3346 +#: postmaster/autovacuum.c:3274 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Activez l'option « track_counts »." -#: postmaster/bgworker.c:393 postmaster/bgworker.c:856 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "enregistrement du processus en tâche de fond « %s »" -#: postmaster/bgworker.c:425 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "désenregistrement du processus en tâche de fond « %s »" -#: postmaster/bgworker.c:590 +#: postmaster/bgworker.c:592 #, c-format msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" msgstr "processus en tâche de fond « %s » : doit se lier à la mémoire partagée pour être capable de demander une connexion à une base" -#: postmaster/bgworker.c:599 +#: postmaster/bgworker.c:601 #, c-format msgid "background worker \"%s\": cannot request database access if starting at postmaster start" msgstr "processus en tâche de fond « %s » : ne peut pas réclamer un accès à la base s'il s'exécute au lancement de postmaster" -#: postmaster/bgworker.c:613 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" msgstr "processus en tâche de fond « %s »: intervalle de redémarrage invalide" -#: postmaster/bgworker.c:628 +#: postmaster/bgworker.c:630 #, c-format msgid "background worker \"%s\": parallel workers may not be configured for restart" msgstr "processus en tâche de fond « %s »: les processus parallélisés pourraient ne pas être configurés pour redémarrer" -#: postmaster/bgworker.c:673 +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "arrêt du processus en tâche de fond « %s » suite à la demande de l'administrateur" -#: postmaster/bgworker.c:864 +#: postmaster/bgworker.c:863 #, c-format msgid "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "processus en tâche de fond « %s » : doit être enregistré dans shared_preload_libraries" -#: postmaster/bgworker.c:876 +#: postmaster/bgworker.c:875 #, c-format msgid "background worker \"%s\": only dynamic background workers can request notification" msgstr "processus en tâche de fond « %s » : seuls les processus utilisateurs en tâche de fond dynamiques peuvent réclamer des notifications" -#: postmaster/bgworker.c:891 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" msgstr "trop de processus en tâche de fond" -#: postmaster/bgworker.c:892 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "Up to %d background workers can be registered with the current settings." msgstr[0] "Un maximum de %d processus en tâche de fond peut être enregistré avec la configuration actuelle" msgstr[1] "Un maximum de %d processus en tâche de fond peut être enregistré avec la configuration actuelle" -#: postmaster/bgworker.c:896 +#: postmaster/bgworker.c:895 #, c-format msgid "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "Considérez l'augmentation du paramètre « max_worker_processes »." -#: postmaster/checkpointer.c:464 +#: postmaster/checkpointer.c:468 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" @@ -15865,24 +16694,24 @@ msgstr[1] "" "les points de vérification (checkpoints) arrivent trop fréquemment\n" "(toutes les %d secondes)" -#: postmaster/checkpointer.c:468 +#: postmaster/checkpointer.c:472 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "Considérez l'augmentation du paramètre « max_wal_size »." -#: postmaster/checkpointer.c:1087 +#: postmaster/checkpointer.c:1090 #, c-format msgid "checkpoint request failed" msgstr "échec de la demande de point de vérification" -#: postmaster/checkpointer.c:1088 +#: postmaster/checkpointer.c:1091 #, c-format msgid "Consult recent messages in the server log for details." msgstr "" "Consultez les messages récents du serveur dans les journaux applicatifs pour\n" "plus de détails." -#: postmaster/checkpointer.c:1283 +#: postmaster/checkpointer.c:1286 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "a compacté la queue de requêtes fsync de %d entrées à %d" @@ -15902,48 +16731,43 @@ msgstr "archive_mode activé, cependant archive_command n'est pas configuré" msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" msgstr "l'archivage du journal de transactions « %s » a échoué trop de fois, nouvelle tentative repoussée" -#: postmaster/pgarch.c:587 +#: postmaster/pgarch.c:585 #, c-format msgid "archive command failed with exit code %d" msgstr "échec de la commande d'archivage avec un code de retour %d" -#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 postmaster/pgarch.c:612 postmaster/pgarch.c:621 +#: postmaster/pgarch.c:587 postmaster/pgarch.c:597 postmaster/pgarch.c:604 postmaster/pgarch.c:610 postmaster/pgarch.c:619 #, c-format msgid "The failed archive command was: %s" msgstr "La commande d'archivage qui a échoué était : %s" -#: postmaster/pgarch.c:596 +#: postmaster/pgarch.c:594 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "la commande d'archivage a été terminée par l'exception 0x%X" -#: postmaster/pgarch.c:598 postmaster/postmaster.c:3567 +#: postmaster/pgarch.c:596 postmaster/postmaster.c:3568 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "" "Voir le fichier d'en-tête C « ntstatus.h » pour une description de la valeur\n" "hexadécimale." -#: postmaster/pgarch.c:603 +#: postmaster/pgarch.c:601 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "la commande d'archivage a été terminée par le signal %d : %s" -#: postmaster/pgarch.c:610 +#: postmaster/pgarch.c:608 #, c-format msgid "archive command was terminated by signal %d" msgstr "la commande d'archivage a été terminée par le signal %d" -#: postmaster/pgarch.c:619 +#: postmaster/pgarch.c:617 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "la commande d'archivage a quitté avec le statut non reconnu %d" -#: postmaster/pgarch.c:679 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "n'a pas pu accéder au répertoire du statut des archives « %s » : %m" - #: postmaster/pgstat.c:395 #, c-format msgid "could not resolve \"localhost\": %s" @@ -16038,219 +16862,175 @@ msgstr "cible reset non reconnu : « %s »" msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "La cible doit être « archiver » ou « bgwriter »." -#: postmaster/pgstat.c:4287 +#: postmaster/pgstat.c:4366 #, c-format msgid "could not read statistics message: %m" msgstr "n'a pas pu lire le message des statistiques : %m" -#: postmaster/pgstat.c:4619 postmaster/pgstat.c:4776 +#: postmaster/pgstat.c:4698 postmaster/pgstat.c:4855 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier temporaire des statistiques « %s » : %m" -#: postmaster/pgstat.c:4686 postmaster/pgstat.c:4821 +#: postmaster/pgstat.c:4765 postmaster/pgstat.c:4900 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "n'a pas pu écrire le fichier temporaire des statistiques « %s » : %m" -#: postmaster/pgstat.c:4695 postmaster/pgstat.c:4830 +#: postmaster/pgstat.c:4774 postmaster/pgstat.c:4909 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "n'a pas pu fermer le fichier temporaire des statistiques « %s » : %m" -#: postmaster/pgstat.c:4703 postmaster/pgstat.c:4838 +#: postmaster/pgstat.c:4782 postmaster/pgstat.c:4917 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "" "n'a pas pu renommer le fichier temporaire des statistiques « %s » en\n" "« %s » : %m" -#: postmaster/pgstat.c:4927 postmaster/pgstat.c:5133 postmaster/pgstat.c:5286 +#: postmaster/pgstat.c:5006 postmaster/pgstat.c:5212 postmaster/pgstat.c:5365 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de statistiques « %s » : %m" -#: postmaster/pgstat.c:4939 postmaster/pgstat.c:4949 postmaster/pgstat.c:4970 postmaster/pgstat.c:4992 postmaster/pgstat.c:5007 postmaster/pgstat.c:5070 postmaster/pgstat.c:5145 postmaster/pgstat.c:5165 postmaster/pgstat.c:5183 postmaster/pgstat.c:5199 postmaster/pgstat.c:5217 postmaster/pgstat.c:5233 postmaster/pgstat.c:5298 postmaster/pgstat.c:5310 postmaster/pgstat.c:5322 postmaster/pgstat.c:5347 postmaster/pgstat.c:5369 +#: postmaster/pgstat.c:5018 postmaster/pgstat.c:5028 postmaster/pgstat.c:5049 postmaster/pgstat.c:5071 postmaster/pgstat.c:5086 postmaster/pgstat.c:5149 postmaster/pgstat.c:5224 postmaster/pgstat.c:5244 postmaster/pgstat.c:5262 postmaster/pgstat.c:5278 postmaster/pgstat.c:5296 postmaster/pgstat.c:5312 postmaster/pgstat.c:5377 postmaster/pgstat.c:5389 postmaster/pgstat.c:5401 postmaster/pgstat.c:5426 postmaster/pgstat.c:5448 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "fichier de statistiques « %s » corrompu" -#: postmaster/pgstat.c:5498 +#: postmaster/pgstat.c:5577 #, c-format msgid "using stale statistics instead of current ones because stats collector is not responding" msgstr "" "utilise de vieilles statistiques à la place des actuelles car le collecteur de\n" "statistiques ne répond pas" -#: postmaster/pgstat.c:5825 +#: postmaster/pgstat.c:5904 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "" "corruption de la table hachée de la base de données lors du lancement\n" "--- annulation" -#: postmaster/postmaster.c:710 +#: postmaster/postmaster.c:718 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s : argument invalide pour l'option -f : « %s »\n" -#: postmaster/postmaster.c:796 +#: postmaster/postmaster.c:804 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s : argument invalide pour l'option -t : « %s »\n" -#: postmaster/postmaster.c:847 +#: postmaster/postmaster.c:855 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s : argument invalide : « %s »\n" -#: postmaster/postmaster.c:886 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s : superuser_reserved_connections doit être inférieur à max_connections\n" - -#: postmaster/postmaster.c:891 +#: postmaster/postmaster.c:897 #, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s : max_wal_senders doit être inférieur à max_connections\n" +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s : superuser_reserved_connections (%d) plus max_wal_senders (%d) doit être inférieur à max_connections (%d)\n" -#: postmaster/postmaster.c:896 +#: postmaster/postmaster.c:904 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "L'archivage des journaux de transactions ne peut pas être activé quand wal_level vaut « minimal »" -#: postmaster/postmaster.c:899 +#: postmaster/postmaster.c:907 #, c-format msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" msgstr "" "l'envoi d'un flux de transactions (max_wal_senders > 0) nécessite que\n" "le paramètre wal_level soit initialisé avec « replica » ou « logical »" -#: postmaster/postmaster.c:907 +#: postmaster/postmaster.c:915 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s : tables datetoken invalide, merci de corriger\n" -#: postmaster/postmaster.c:1010 postmaster/postmaster.c:1108 utils/init/miscinit.c:1455 +#: postmaster/postmaster.c:1029 postmaster/postmaster.c:1127 utils/init/miscinit.c:1551 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "syntaxe de liste invalide pour le paramètre « %s »" -#: postmaster/postmaster.c:1041 +#: postmaster/postmaster.c:1060 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "n'a pas pu créer le socket d'écoute pour « %s »" -#: postmaster/postmaster.c:1047 +#: postmaster/postmaster.c:1066 #, c-format msgid "could not create any TCP/IP sockets" msgstr "n'a pas pu créer de socket TCP/IP" -#: postmaster/postmaster.c:1130 +#: postmaster/postmaster.c:1149 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "n'a pas pu créer la socket de domaine Unix dans le répertoire « %s »" -#: postmaster/postmaster.c:1136 +#: postmaster/postmaster.c:1155 #, c-format msgid "could not create any Unix-domain sockets" msgstr "n'a pas pu créer les sockets de domaine Unix" -#: postmaster/postmaster.c:1148 +#: postmaster/postmaster.c:1167 #, c-format msgid "no socket created for listening" msgstr "pas de socket créé pour l'écoute" -#: postmaster/postmaster.c:1188 +#: postmaster/postmaster.c:1207 #, c-format msgid "could not create I/O completion port for child queue" msgstr "n'a pas pu créer un port de terminaison I/O pour la queue" -#: postmaster/postmaster.c:1217 +#: postmaster/postmaster.c:1236 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s : n'a pas pu modifier les droits du fichier PID externe « %s » : %s\n" -#: postmaster/postmaster.c:1221 +#: postmaster/postmaster.c:1240 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s : n'a pas pu écrire le fichier PID externe « %s » : %s\n" -#: postmaster/postmaster.c:1278 +#: postmaster/postmaster.c:1297 #, c-format msgid "ending log output to stderr" msgstr "arrêt des traces sur stderr" -#: postmaster/postmaster.c:1279 +#: postmaster/postmaster.c:1298 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "Les traces suivantes iront sur « %s »." -#: postmaster/postmaster.c:1305 utils/init/postinit.c:213 +#: postmaster/postmaster.c:1324 utils/init/postinit.c:214 #, c-format msgid "could not load pg_hba.conf" msgstr "n'a pas pu charger pg_hba.conf" -#: postmaster/postmaster.c:1331 +#: postmaster/postmaster.c:1350 #, c-format msgid "postmaster became multithreaded during startup" msgstr "le postmaster est devenu multithreadé lors du démarrage" -#: postmaster/postmaster.c:1332 +#: postmaster/postmaster.c:1351 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "Configurez la variable d'environnement LC_ALL avec une locale valide." -#: postmaster/postmaster.c:1437 +#: postmaster/postmaster.c:1456 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s : n'a pas pu localiser l'exécutable postgres correspondant" -#: postmaster/postmaster.c:1460 utils/misc/tzparser.c:341 +#: postmaster/postmaster.c:1479 utils/misc/tzparser.c:341 #, c-format msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." msgstr "Ceci peut indiquer une installation PostgreSQL incomplète, ou que le fichier « %s » a été déplacé." -#: postmaster/postmaster.c:1488 -#, c-format -msgid "data directory \"%s\" does not exist" -msgstr "le répertoire des données « %s » n'existe pas" - -#: postmaster/postmaster.c:1493 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "n'a pas pu lire les droits du répertoire « %s » : %m" - -#: postmaster/postmaster.c:1501 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "le répertoire des données « %s » n'est pas un répertoire" - -#: postmaster/postmaster.c:1517 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "le répertoire des données « %s » a un mauvais propriétaire" - -#: postmaster/postmaster.c:1519 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "" -"Le serveur doit être en cours d'exécution par l'utilisateur qui possède le\n" -"répertoire des données." - -#: postmaster/postmaster.c:1539 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "" -"le répertoire des données « %s » est accessible par le groupe et/ou par les\n" -"autres" - -#: postmaster/postmaster.c:1541 -#, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "Les droits devraient être u=rwx (0700)." - -#: postmaster/postmaster.c:1552 +#: postmaster/postmaster.c:1506 #, c-format msgid "" "%s: could not find the database system\n" @@ -16261,76 +17041,76 @@ msgstr "" "S'attendait à le trouver dans le répertoire « %s »,\n" "mais n'a pas réussi à ouvrir le fichier « %s »: %s\n" -#: postmaster/postmaster.c:1729 +#: postmaster/postmaster.c:1683 #, c-format msgid "select() failed in postmaster: %m" msgstr "échec de select() dans postmaster : %m" -#: postmaster/postmaster.c:1884 +#: postmaster/postmaster.c:1838 #, c-format msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "forçage d'un arrêt immédiat car le fichier de verrou du répertoire de données est invalide" -#: postmaster/postmaster.c:1962 postmaster/postmaster.c:1993 +#: postmaster/postmaster.c:1916 postmaster/postmaster.c:1947 #, c-format msgid "incomplete startup packet" msgstr "paquet de démarrage incomplet" -#: postmaster/postmaster.c:1974 +#: postmaster/postmaster.c:1928 #, c-format msgid "invalid length of startup packet" msgstr "longueur invalide du paquet de démarrage" -#: postmaster/postmaster.c:2032 +#: postmaster/postmaster.c:1986 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "échec lors de l'envoi de la réponse de négotiation SSL : %m" -#: postmaster/postmaster.c:2061 +#: postmaster/postmaster.c:2012 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "" "Protocole non supportée de l'interface %u.%u : le serveur supporte de %u.0 à\n" "%u.%u" -#: postmaster/postmaster.c:2124 utils/misc/guc.c:5770 utils/misc/guc.c:5863 utils/misc/guc.c:7164 utils/misc/guc.c:9918 utils/misc/guc.c:9952 +#: postmaster/postmaster.c:2076 utils/misc/guc.c:6017 utils/misc/guc.c:6110 utils/misc/guc.c:7436 utils/misc/guc.c:10199 utils/misc/guc.c:10233 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "valeur invalide pour le paramètre « %s » : « %s »" -#: postmaster/postmaster.c:2127 +#: postmaster/postmaster.c:2079 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "Les valeurs valides sont : « false », « 0 », « true », « 1 », « database »." -#: postmaster/postmaster.c:2147 +#: postmaster/postmaster.c:2109 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "" "configuration invalide du paquet de démarrage : terminaison attendue comme\n" "dernier octet" -#: postmaster/postmaster.c:2175 +#: postmaster/postmaster.c:2147 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "aucun nom d'utilisateur PostgreSQL n'a été spécifié dans le paquet de démarrage" -#: postmaster/postmaster.c:2234 +#: postmaster/postmaster.c:2206 #, c-format msgid "the database system is starting up" msgstr "le système de bases de données se lance" -#: postmaster/postmaster.c:2239 +#: postmaster/postmaster.c:2211 #, c-format msgid "the database system is shutting down" msgstr "le système de base de données s'arrête" -#: postmaster/postmaster.c:2244 +#: postmaster/postmaster.c:2216 #, c-format msgid "the database system is in recovery mode" msgstr "le système de bases de données est en cours de restauration" -#: postmaster/postmaster.c:2249 storage/ipc/procarray.c:291 storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:338 +#: postmaster/postmaster.c:2221 storage/ipc/procarray.c:292 storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:346 #, c-format msgid "sorry, too many clients already" msgstr "désolé, trop de clients sont déjà connectés" @@ -16437,285 +17217,286 @@ msgid "system logger process" msgstr "processus des journaux applicatifs" #: postmaster/postmaster.c:3117 -msgid "worker process" -msgstr "processus de travail" +#, c-format +msgid "background worker \"%s\"" +msgstr "processus en tâche de fond « %s »" -#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 +#: postmaster/postmaster.c:3201 postmaster/postmaster.c:3221 postmaster/postmaster.c:3228 postmaster/postmaster.c:3246 msgid "server process" msgstr "processus serveur" -#: postmaster/postmaster.c:3299 +#: postmaster/postmaster.c:3300 #, c-format msgid "terminating any other active server processes" msgstr "arrêt des autres processus serveur actifs" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3555 +#: postmaster/postmaster.c:3556 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) quitte avec le code de sortie %d" -#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 postmaster/postmaster.c:3598 +#: postmaster/postmaster.c:3558 postmaster/postmaster.c:3569 postmaster/postmaster.c:3580 postmaster/postmaster.c:3589 postmaster/postmaster.c:3599 #, c-format msgid "Failed process was running: %s" msgstr "Le processus qui a échoué exécutait : %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3565 +#: postmaster/postmaster.c:3566 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) a été arrêté par l'exception 0x%X" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3575 +#: postmaster/postmaster.c:3576 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) a été arrêté par le signal %d : %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3586 +#: postmaster/postmaster.c:3587 #, c-format msgid "%s (PID %d) was terminated by signal %d" msgstr "%s (PID %d) a été arrêté par le signal %d" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3596 +#: postmaster/postmaster.c:3597 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" msgstr "%s (PID %d) a quitté avec le statut inattendu %d" -#: postmaster/postmaster.c:3783 +#: postmaster/postmaster.c:3784 #, c-format msgid "abnormal database system shutdown" msgstr "le système de base de données a été arrêté anormalement" -#: postmaster/postmaster.c:3823 +#: postmaster/postmaster.c:3824 #, c-format msgid "all server processes terminated; reinitializing" msgstr "tous les processus serveur se sont arrêtés, réinitialisation" -#: postmaster/postmaster.c:3989 postmaster/postmaster.c:5400 postmaster/postmaster.c:5764 +#: postmaster/postmaster.c:3994 postmaster/postmaster.c:5419 postmaster/postmaster.c:5783 #, c-format msgid "could not generate random cancel key" msgstr "n'a pas pu générer la clé d'annulation aléatoire" -#: postmaster/postmaster.c:4043 +#: postmaster/postmaster.c:4048 #, c-format msgid "could not fork new process for connection: %m" msgstr "n'a pas pu lancer le nouveau processus fils pour la connexion : %m" -#: postmaster/postmaster.c:4085 +#: postmaster/postmaster.c:4090 msgid "could not fork new process for connection: " msgstr "n'a pas pu lancer le nouveau processus fils pour la connexion : " -#: postmaster/postmaster.c:4199 +#: postmaster/postmaster.c:4204 #, c-format msgid "connection received: host=%s port=%s" msgstr "connexion reçue : hôte=%s port=%s" -#: postmaster/postmaster.c:4204 +#: postmaster/postmaster.c:4209 #, c-format msgid "connection received: host=%s" msgstr "connexion reçue : hôte=%s" -#: postmaster/postmaster.c:4489 +#: postmaster/postmaster.c:4494 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "n'a pas pu exécuter le processus serveur « %s » : %m" -#: postmaster/postmaster.c:4642 +#: postmaster/postmaster.c:4647 #, c-format msgid "giving up after too many tries to reserve shared memory" msgstr "abandon après trop de tentatives pour réserver la mémoire partagée" -#: postmaster/postmaster.c:4643 +#: postmaster/postmaster.c:4648 #, c-format msgid "This might be caused by ASLR or antivirus software." msgstr "Ceci pourrait être causé par un logiciel ASLR ou un antivirus." -#: postmaster/postmaster.c:4840 +#: postmaster/postmaster.c:4859 #, c-format msgid "SSL configuration could not be loaded in child process" msgstr "la configuration SSL n'a pas pu être chargé sur le processus fils" -#: postmaster/postmaster.c:4972 +#: postmaster/postmaster.c:4991 #, c-format msgid "Please report this to ." msgstr "Veuillez rapporter ceci à ." -#: postmaster/postmaster.c:5059 +#: postmaster/postmaster.c:5078 #, c-format msgid "database system is ready to accept read only connections" msgstr "le système de bases de données est prêt pour accepter les connexions en lecture seule" -#: postmaster/postmaster.c:5328 +#: postmaster/postmaster.c:5347 #, c-format msgid "could not fork startup process: %m" msgstr "n'a pas pu lancer le processus fils de démarrage : %m" -#: postmaster/postmaster.c:5332 +#: postmaster/postmaster.c:5351 #, c-format msgid "could not fork background writer process: %m" msgstr "" "n'a pas pu créer un processus fils du processus d'écriture en tâche de\n" "fond : %m" -#: postmaster/postmaster.c:5336 +#: postmaster/postmaster.c:5355 #, c-format msgid "could not fork checkpointer process: %m" msgstr "n'a pas pu créer le processus checkpointer : %m" -#: postmaster/postmaster.c:5340 +#: postmaster/postmaster.c:5359 #, c-format msgid "could not fork WAL writer process: %m" msgstr "" "n'a pas pu créer un processus fils du processus d'écriture des journaux de\n" "transaction : %m" -#: postmaster/postmaster.c:5344 +#: postmaster/postmaster.c:5363 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "" "n'a pas pu créer un processus fils de réception des journaux de\n" "transactions : %m" -#: postmaster/postmaster.c:5348 +#: postmaster/postmaster.c:5367 #, c-format msgid "could not fork process: %m" msgstr "n'a pas pu lancer le processus fils : %m" -#: postmaster/postmaster.c:5535 postmaster/postmaster.c:5558 +#: postmaster/postmaster.c:5554 postmaster/postmaster.c:5577 #, c-format msgid "database connection requirement not indicated during registration" msgstr "pré-requis de la connexion à la base non indiqué lors de l'enregistrement" -#: postmaster/postmaster.c:5542 postmaster/postmaster.c:5565 +#: postmaster/postmaster.c:5561 postmaster/postmaster.c:5584 #, c-format msgid "invalid processing mode in background worker" msgstr "mode de traitement invalide dans le processus en tâche de fond" -#: postmaster/postmaster.c:5637 +#: postmaster/postmaster.c:5656 #, c-format msgid "starting background worker process \"%s\"" msgstr "démarrage du processus d'écriture en tâche de fond « %s »" -#: postmaster/postmaster.c:5649 +#: postmaster/postmaster.c:5668 #, c-format msgid "could not fork worker process: %m" msgstr "n'a pas pu créer un processus fils du processus en tâche de fond : %m" -#: postmaster/postmaster.c:6073 +#: postmaster/postmaster.c:6104 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "n'a pas pu dupliquer la socket %d pour le serveur : code d'erreur %d" -#: postmaster/postmaster.c:6105 +#: postmaster/postmaster.c:6136 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "n'a pas pu créer la socket héritée : code d'erreur %d\n" -#: postmaster/postmaster.c:6134 +#: postmaster/postmaster.c:6165 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier des variables moteurs « %s » : %s\n" -#: postmaster/postmaster.c:6141 +#: postmaster/postmaster.c:6172 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "n'a pas pu lire le fichier de configuration serveur « %s » : %s\n" -#: postmaster/postmaster.c:6150 +#: postmaster/postmaster.c:6181 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "n'a pas pu supprimer le fichier « %s » : %s\n" -#: postmaster/postmaster.c:6167 +#: postmaster/postmaster.c:6198 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "" "n'a pas pu exécuter \"map\" la vue des variables serveurs : code\n" "d'erreur %lu\n" -#: postmaster/postmaster.c:6176 +#: postmaster/postmaster.c:6207 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "" "n'a pas pu exécuter \"unmap\" sur la vue des variables serveurs : code\n" "d'erreur %lu\n" -#: postmaster/postmaster.c:6183 +#: postmaster/postmaster.c:6214 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "" "n'a pas pu fermer le lien vers les variables des paramètres du serveur :\n" "code d'erreur %lu\n" -#: postmaster/postmaster.c:6344 +#: postmaster/postmaster.c:6378 #, c-format msgid "could not read exit code for process\n" msgstr "n'a pas pu lire le code de sortie du processus\n" -#: postmaster/postmaster.c:6349 +#: postmaster/postmaster.c:6383 #, c-format msgid "could not post child completion status\n" msgstr "n'a pas pu poster le statut de fin de l'enfant\n" -#: postmaster/syslogger.c:452 postmaster/syslogger.c:1053 +#: postmaster/syslogger.c:471 postmaster/syslogger.c:1147 #, c-format msgid "could not read from logger pipe: %m" msgstr "n'a pas pu lire à partir du tube des journaux applicatifs : %m" -#: postmaster/syslogger.c:502 +#: postmaster/syslogger.c:521 #, c-format msgid "logger shutting down" msgstr "arrêt en cours des journaux applicatifs" -#: postmaster/syslogger.c:546 postmaster/syslogger.c:560 +#: postmaster/syslogger.c:565 postmaster/syslogger.c:579 #, c-format msgid "could not create pipe for syslog: %m" msgstr "n'a pas pu créer un tube pour syslog : %m" -#: postmaster/syslogger.c:596 +#: postmaster/syslogger.c:630 #, c-format msgid "could not fork system logger: %m" msgstr "n'a pas pu lancer le processus des journaux applicatifs : %m" -#: postmaster/syslogger.c:632 +#: postmaster/syslogger.c:666 #, c-format msgid "redirecting log output to logging collector process" msgstr "redirection des traces vers le processus de récupération des traces" -#: postmaster/syslogger.c:633 +#: postmaster/syslogger.c:667 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "Les prochaines traces apparaîtront dans le répertoire « %s »." -#: postmaster/syslogger.c:641 +#: postmaster/syslogger.c:675 #, c-format msgid "could not redirect stdout: %m" msgstr "n'a pas pu rediriger la sortie (stdout) : %m" -#: postmaster/syslogger.c:646 postmaster/syslogger.c:663 +#: postmaster/syslogger.c:680 postmaster/syslogger.c:697 #, c-format msgid "could not redirect stderr: %m" msgstr "n'a pas pu rediriger la sortie des erreurs (stderr) : %m" -#: postmaster/syslogger.c:1008 +#: postmaster/syslogger.c:1102 #, c-format msgid "could not write to log file: %s\n" msgstr "n'a pas pu écrire dans le journal applicatif : %s\n" -#: postmaster/syslogger.c:1150 +#: postmaster/syslogger.c:1219 #, c-format msgid "could not open log file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier applicatif « %s » : %m" -#: postmaster/syslogger.c:1212 postmaster/syslogger.c:1256 +#: postmaster/syslogger.c:1281 postmaster/syslogger.c:1331 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "désactivation de la rotation automatique (utilisez SIGHUP pour la réactiver)" @@ -16725,276 +17506,320 @@ msgstr "désactivation de la rotation automatique (utilisez SIGHUP pour la réac msgid "could not determine which collation to use for regular expression" msgstr "n'a pas pu déterminer le collationnement à utiliser pour une expression rationnelle" -#: repl_gram.y:320 repl_gram.y:352 +#: repl_gram.y:336 repl_gram.y:368 #, c-format msgid "invalid timeline %u" msgstr "timeline %u invalide" -#: repl_scanner.l:125 +#: repl_scanner.l:129 msgid "invalid streaming start location" msgstr "emplacement de démarrage du flux de réplication invalide" -#: repl_scanner.l:176 scan.l:670 +#: repl_scanner.l:180 scan.l:683 msgid "unterminated quoted string" msgstr "chaîne entre guillemets non terminée" -#: replication/basebackup.c:303 +#: replication/basebackup.c:343 #, c-format msgid "could not stat control file \"%s\": %m" msgstr "n'a pas pu récupérer des informations sur le fichier de contrôle « %s » : %m" -#: replication/basebackup.c:412 +#: replication/basebackup.c:450 #, c-format msgid "could not find any WAL files" msgstr "n'a pas pu trouver un seul fichier WAL" -#: replication/basebackup.c:425 replication/basebackup.c:439 replication/basebackup.c:448 +#: replication/basebackup.c:464 replication/basebackup.c:479 replication/basebackup.c:488 #, c-format msgid "could not find WAL file \"%s\"" msgstr "n'a pas pu trouver le fichier WAL « %s »" -#: replication/basebackup.c:487 replication/basebackup.c:513 +#: replication/basebackup.c:530 replication/basebackup.c:558 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "taille du fichier WAL « %s » inattendue" -#: replication/basebackup.c:499 replication/basebackup.c:1228 +#: replication/basebackup.c:544 replication/basebackup.c:1536 #, c-format msgid "base backup could not send data, aborting backup" msgstr "la sauvegarde de base n'a pas pu envoyer les données, annulation de la sauvegarde" -#: replication/basebackup.c:601 replication/basebackup.c:610 replication/basebackup.c:619 replication/basebackup.c:628 replication/basebackup.c:637 replication/basebackup.c:648 replication/basebackup.c:665 +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "%s erreurs de vérifications des sommes de contrôle" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "échec de la véffication de somme de controle durant la sauvegarde de base" + +#: replication/basebackup.c:664 replication/basebackup.c:673 replication/basebackup.c:682 replication/basebackup.c:691 replication/basebackup.c:700 replication/basebackup.c:711 replication/basebackup.c:728 replication/basebackup.c:737 #, c-format msgid "duplicate option \"%s\"" msgstr "option « %s » dupliquée" -#: replication/basebackup.c:654 utils/misc/guc.c:5780 +#: replication/basebackup.c:717 utils/misc/guc.c:6027 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d est en dehors des limites valides pour le paramètre « %s » (%d .. %d)" -#: replication/basebackup.c:928 replication/basebackup.c:1025 +#: replication/basebackup.c:991 replication/basebackup.c:1161 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "" "n'a pas pu récupérer les informations sur le fichier ou répertoire\n" "« %s » : %m" -#: replication/basebackup.c:1180 +#: replication/basebackup.c:1316 #, c-format msgid "skipping special file \"%s\"" msgstr "ignore le fichier spécial « %s »" -#: replication/basebackup.c:1293 +#: replication/basebackup.c:1421 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "numéro de segment %d invalide dans le fichier « %s »" + +#: replication/basebackup.c:1440 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "impossible de vérifier la somme de contrôle dans le fichier « %s », block %d : la taille de tampon de lecture %d et la taille de page %d diffèrent" + +#: replication/basebackup.c:1484 replication/basebackup.c:1500 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "n'a pas pu effectuer de fseek dans le fichier « %s » : %m" + +#: replication/basebackup.c:1492 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "n'a pas pu relire le bloc %d dans le fichier « %s » : %m" + +#: replication/basebackup.c:1516 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "échec de la vérification de la somme de contrôle dans le fichier « %s », bloc %d : calculé %X, alors que le bloc contient %X" + +#: replication/basebackup.c:1523 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "les prochains échec de vérification de somme de contrôle dans le fichier « %s » ne seront pas reportés" + +#: replication/basebackup.c:1581 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "le fichier « %s » a un total de %d échecs de vérification de somme de contrôle" + +#: replication/basebackup.c:1609 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "nom du fichier trop long pour le format tar : « %s »" -#: replication/basebackup.c:1298 +#: replication/basebackup.c:1614 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "cible du lien symbolique trop long pour le format tar : nom de fichier « %s », cible « %s »" -#: replication/libpqwalreceiver/libpqwalreceiver.c:226 +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 #, c-format msgid "invalid connection string syntax: %s" msgstr "syntaxe de la chaîne de connexion invalide : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:250 +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 #, c-format msgid "could not parse connection string: %s" msgstr "n'a pas pu analyser la chaîne de connexion « %s »" -#: replication/libpqwalreceiver/libpqwalreceiver.c:300 +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 #, c-format msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "" "n'a pas pu recevoir l'identifiant du système de bases de données et\n" "l'identifiant de la timeline à partir du serveur principal : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:311 replication/libpqwalreceiver/libpqwalreceiver.c:518 +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 replication/libpqwalreceiver/libpqwalreceiver.c:550 #, c-format msgid "invalid response from primary server" msgstr "réponse invalide du serveur principal" -#: replication/libpqwalreceiver/libpqwalreceiver.c:312 +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 #, c-format msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "" "N'a pas pu identifier le système : a récupéré %d lignes et %d champs,\n" "attendait %d lignes et %d champs (ou plus)." -#: replication/libpqwalreceiver/libpqwalreceiver.c:378 replication/libpqwalreceiver/libpqwalreceiver.c:384 replication/libpqwalreceiver/libpqwalreceiver.c:409 +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 replication/libpqwalreceiver/libpqwalreceiver.c:416 replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format msgid "could not start WAL streaming: %s" msgstr "n'a pas pu démarrer l'envoi des WAL : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:428 +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "n'a pas pu transmettre le message de fin d'envoi de flux au primaire : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "ensemble de résultats inattendu après la fin du flux de réplication" -#: replication/libpqwalreceiver/libpqwalreceiver.c:464 -#, fuzzy, c-format -#| msgid "error reading result of streaming command: %s" +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format msgid "error while shutting down streaming COPY: %s" -msgstr "erreur lors de la lecture de la commande de flux : %s" +msgstr "erreur lors de l'arrêt de la copie en flux : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:473 +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 #, c-format msgid "error reading result of streaming command: %s" msgstr "erreur lors de la lecture de la commande de flux : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:481 replication/libpqwalreceiver/libpqwalreceiver.c:709 +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 replication/libpqwalreceiver/libpqwalreceiver.c:741 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "résultat inattendu après CommandComplete : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:507 +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "n'a pas pu recevoir le fichier historique à partir du serveur principal : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:519 +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "Attendait 1 ligne avec 2 champs, a obtenu %d lignes avec %d champs." -#: replication/libpqwalreceiver/libpqwalreceiver.c:673 replication/libpqwalreceiver/libpqwalreceiver.c:724 replication/libpqwalreceiver/libpqwalreceiver.c:730 +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 replication/libpqwalreceiver/libpqwalreceiver.c:756 replication/libpqwalreceiver/libpqwalreceiver.c:762 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "n'a pas pu recevoir des données du flux de WAL : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:749 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 #, c-format msgid "could not send data to WAL stream: %s" msgstr "n'a pas pu transmettre les données au flux WAL : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:798 +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "n'a pas pu créer le slot de réplication « %s » : %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:832 +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 #, c-format msgid "invalid query response" msgstr "réponse à la requête invalide" -#: replication/libpqwalreceiver/libpqwalreceiver.c:833 +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 #, c-format msgid "Expected %d fields, got %d fields." msgstr "Attendait %d champs, a obtenu %d champs." -#: replication/libpqwalreceiver/libpqwalreceiver.c:902 +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 #, c-format msgid "the query interface requires a database connection" msgstr "l'interface de la requête requiert une connexion à une base" -#: replication/libpqwalreceiver/libpqwalreceiver.c:933 +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 msgid "empty query" msgstr "requête vide" -#: replication/logical/launcher.c:268 +#: replication/logical/launcher.c:310 #, c-format msgid "starting logical replication worker for subscription \"%s\"" msgstr "lancement du processus worker de réplication logique pour la souscription « %s »" -#: replication/logical/launcher.c:275 +#: replication/logical/launcher.c:317 #, c-format msgid "cannot start logical replication workers when max_replication_slots = 0" msgstr "ne peut pas démarrer les processus worker de la réplication logique quand max_replication_slots = 0" -#: replication/logical/launcher.c:355 +#: replication/logical/launcher.c:397 #, c-format msgid "out of logical replication worker slots" msgstr "plus de slots de processus worker pour la réplication logique" -#: replication/logical/launcher.c:356 +#: replication/logical/launcher.c:398 #, c-format msgid "You might need to increase max_logical_replication_workers." msgstr "Vous pourriez avoir besoin d'augmenter max_logical_replication_workers." -#: replication/logical/launcher.c:401 +#: replication/logical/launcher.c:453 #, c-format msgid "out of background worker slots" msgstr "plus de slots de processus en tâche de fond" -#: replication/logical/launcher.c:402 +#: replication/logical/launcher.c:454 #, c-format msgid "You might need to increase max_worker_processes." msgstr "Vous pourriez avoir besoin d'augmenter max_worker_processes." -#: replication/logical/launcher.c:564 +#: replication/logical/launcher.c:661 #, c-format msgid "logical replication worker slot %d is empty, cannot attach" msgstr "le slot %d du processus de réplication logique est vide, ne peut pas s'y attacher" -#: replication/logical/launcher.c:573 +#: replication/logical/launcher.c:670 #, c-format msgid "logical replication worker slot %d is already used by another worker, cannot attach" msgstr "le slot %d du processus de réplication logique est déjà utilisé par un autre processus, ne peut pas s'attacher" -#: replication/logical/launcher.c:798 +#: replication/logical/launcher.c:988 #, c-format msgid "logical replication launcher started" msgstr "lancement du processus de lancement de la réplication logique" -#: replication/logical/logical.c:83 +#: replication/logical/logical.c:90 #, c-format msgid "logical decoding requires wal_level >= logical" msgstr "le décodage logique requiert wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:95 #, c-format msgid "logical decoding requires a database connection" msgstr "le décodage logique requiert une connexion à une base" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:113 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "le décodage logique ne peut pas être utilisé lors de la restauration" -#: replication/logical/logical.c:243 replication/logical/logical.c:365 +#: replication/logical/logical.c:255 replication/logical/logical.c:386 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "ne peut pas utiliser un slot de réplication physique pour le décodage logique" -#: replication/logical/logical.c:248 replication/logical/logical.c:370 +#: replication/logical/logical.c:260 replication/logical/logical.c:391 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "le slot de réplication « %s » n'a pas été créé dans cette base de données" -#: replication/logical/logical.c:255 +#: replication/logical/logical.c:267 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "ne peut pas créer un slot de réplication logique dans une transaction qui a fait des écritures" -#: replication/logical/logical.c:408 +#: replication/logical/logical.c:431 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "début du décodage logique pour le slot « %s »" -#: replication/logical/logical.c:410 +#: replication/logical/logical.c:433 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "envoi des transactions validées après %X/%X, lecture des journaux à partir de %X/%X" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "envoi des transactions validées après %X/%X, lecture des journaux à partir de %X/%X." -#: replication/logical/logical.c:557 +#: replication/logical/logical.c:583 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "slot « %s », plugin de sortie « %s », dans la fonction d'appel %s, associé au LSN %X/%X" -#: replication/logical/logical.c:564 +#: replication/logical/logical.c:590 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "slot « %s », plugin de sortie « %s », dans la fonction d'appel %s" -#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "" @@ -17021,92 +17846,102 @@ msgstr "le tableau doit avoir une dimension" msgid "array must not contain nulls" msgstr "le tableau ne doit pas contenir de valeurs NULL" -#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2282 utils/adt/jsonb.c:1357 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 utils/adt/jsonb.c:1269 #, c-format msgid "array must have even number of elements" msgstr "le tableau doit avoir un nombre pair d'éléments" -#: replication/logical/logicalfuncs.c:268 +#: replication/logical/logicalfuncs.c:269 #, c-format msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "le plugin de sortie « %s » pour le décodage logique produit une sortie binaire, mais la fonction « %s » attend des données texte" -#: replication/logical/origin.c:180 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "seuls les super-utilisateurs peuvent lire ou manipuler les origines de réplication" -#: replication/logical/origin.c:185 +#: replication/logical/origin.c:190 #, c-format msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "ne peut pas lire ou manipuler une originie de réplication logique quand max_replication_slots = 0" -#: replication/logical/origin.c:190 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "ne peut pas manipuler les origines de réplication lors d'une restauration" -#: replication/logical/origin.c:314 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "l'origine de réplication « %s » n'existe pas" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "n'a pas pu trouver d'OID d'origine de réplication libre" -#: replication/logical/origin.c:351 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "ne peut pas supprimer l'origine de réplication d'OID %d, utilisée par le PID %d" -#: replication/logical/origin.c:667 +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "l'origine de réplication d'OID %u n'existe pas" + +#: replication/logical/origin.c:725 #, c-format msgid "replication checkpoint has wrong magic %u instead of %u" msgstr "le checkpoint de réplication a le mauvais nombre magique (%u au lieu de %u)" -#: replication/logical/origin.c:699 +#: replication/logical/origin.c:757 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" -#: replication/logical/origin.c:708 +#: replication/logical/origin.c:766 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "n'a pas pu trouver d'état de réplication libre, augmentez max_replication_slots" -#: replication/logical/origin.c:726 +#: replication/logical/origin.c:784 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "le point de contrôle du slot de réplication à la mauvaise somme de contrôle %u, %u attendu" -#: replication/logical/origin.c:850 +#: replication/logical/origin.c:908 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "l'origine de réplication d'OID %d est déjà active pour le PID %d" -#: replication/logical/origin.c:861 replication/logical/origin.c:1041 +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 #, c-format msgid "could not find free replication state slot for replication origin with OID %u" msgstr "n'a pas pu trouver de slot d'état de réplication libre pour l'origine de réplication d'OID %u" -#: replication/logical/origin.c:863 replication/logical/origin.c:1043 replication/slot.c:1508 +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 replication/slot.c:1559 #, c-format msgid "Increase max_replication_slots and try again." msgstr "Augmentez max_replication_slots et recommencez." -#: replication/logical/origin.c:1000 +#: replication/logical/origin.c:1065 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "ne peut pas configurer l'origine de réplication si une origine existe déjà" -#: replication/logical/origin.c:1029 +#: replication/logical/origin.c:1094 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "l'identificateur de réplication %d est déjà actif pour le PID %d" -#: replication/logical/origin.c:1075 replication/logical/origin.c:1270 replication/logical/origin.c:1290 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 replication/logical/origin.c:1363 #, c-format msgid "no replication origin is configured" msgstr "aucune origine de réplication n'est configurée" -#: replication/logical/relation.c:259 +#: replication/logical/relation.c:255 #, c-format msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "la relation cible de la réplication logique « %s.%s » n'existe pas" @@ -17114,46 +17949,36 @@ msgstr "la relation cible de la réplication logique « %s.%s » n'existe pas" #: replication/logical/relation.c:297 #, c-format msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" -msgstr "il manque des colonnes répliquées dans la relation cible « %s.%s » de réplication logique" - -#: replication/logical/relation.c:337 -#, c-format -msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" -msgstr "la relation cible « %s.%s » de réplication logique utilise des colonnes systèmes dans l'index REPLICA IDENTITY" - -#: replication/logical/relation.c:453 -#, c-format -msgid "builtin type %u not found" -msgstr "type interne %u non trouvé" - -#: replication/logical/relation.c:454 -#, c-format -msgid "This can be caused by having publisher with higher major version than subscriber" -msgstr "Ceci peut avoir pour cause un publieur ayant une version majeure supérieur à l'abonné" +msgstr "il manque des colonnes répliquées dans la relation cible « %s.%s » de réplication logique" -#: replication/logical/relation.c:486 +#: replication/logical/relation.c:337 #, c-format -msgid "data type \"%s.%s\" required for logical replication does not exist" -msgstr "le type de données « %s/%s » requis par la réplication logique n'existe pas" +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "la relation cible « %s.%s » de réplication logique utilise des colonnes systèmes dans l'index REPLICA IDENTITY" -#: replication/logical/reorderbuffer.c:2288 +#: replication/logical/reorderbuffer.c:2507 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "n'a pas pu écrire dans le fichier pour le XID %u : %m" -#: replication/logical/reorderbuffer.c:2387 replication/logical/reorderbuffer.c:2409 +#: replication/logical/reorderbuffer.c:2600 replication/logical/reorderbuffer.c:2622 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "n'a pas pu lire le fichier « reorderbuffer spill » : %m" -#: replication/logical/reorderbuffer.c:2391 replication/logical/reorderbuffer.c:2413 +#: replication/logical/reorderbuffer.c:2604 replication/logical/reorderbuffer.c:2626 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "" "n'a pas pu lire à partir du fichier « reorderbuffer spill » : a lu seulement %d octets\n" "sur %u" -#: replication/logical/reorderbuffer.c:3071 +#: replication/logical/reorderbuffer.c:2849 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "n'a pas pu supprimer le fichier « %s » pendant la suppression de pg_replslot/%s/*.xid: %m" + +#: replication/logical/reorderbuffer.c:3315 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "n'a pas pu lire à partir du fichier « %s » : lu %d octets au lieu de %d octets" @@ -17163,71 +17988,71 @@ msgstr "n'a pas pu lire à partir du fichier « %s » : lu %d octets au lieu de msgid "initial slot snapshot too large" msgstr "snapshot du slot initial trop gros" -#: replication/logical/snapbuild.c:664 +#: replication/logical/snapbuild.c:666 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "snapshot exporté pour le décodage logique : « %s » avec %u identifiant de transaction" msgstr[1] "snapshot exporté pour le décodage logique : « %s » avec %u identifiants de transaction" -#: replication/logical/snapbuild.c:1262 replication/logical/snapbuild.c:1355 replication/logical/snapbuild.c:1842 +#: replication/logical/snapbuild.c:1271 replication/logical/snapbuild.c:1364 replication/logical/snapbuild.c:1878 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "le décodage logique a trouvé le point de cohérence à %X/%X" -#: replication/logical/snapbuild.c:1264 +#: replication/logical/snapbuild.c:1273 #, c-format msgid "There are no running transactions." msgstr "Il n'existe pas de transactions en cours." -#: replication/logical/snapbuild.c:1306 +#: replication/logical/snapbuild.c:1315 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "le décodage logique a trouvé le point de démarrage à %X/%X" -#: replication/logical/snapbuild.c:1308 replication/logical/snapbuild.c:1332 +#: replication/logical/snapbuild.c:1317 replication/logical/snapbuild.c:1341 #, c-format msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "En attente de transactions (approximativement %d) plus anciennes que %u pour terminer." -#: replication/logical/snapbuild.c:1330 +#: replication/logical/snapbuild.c:1339 #, c-format msgid "logical decoding found initial consistent point at %X/%X" msgstr "le décodage logique a trouvé le point de cohérence initial à %X/%X" -#: replication/logical/snapbuild.c:1357 +#: replication/logical/snapbuild.c:1366 #, c-format msgid "There are no old transactions anymore." msgstr "Il n'existe plus d'anciennes transactions." -#: replication/logical/snapbuild.c:1715 replication/logical/snapbuild.c:1743 replication/logical/snapbuild.c:1760 replication/logical/snapbuild.c:1776 +#: replication/logical/snapbuild.c:1740 replication/logical/snapbuild.c:1773 replication/logical/snapbuild.c:1793 replication/logical/snapbuild.c:1812 #, c-format msgid "could not read file \"%s\", read %d of %d: %m" msgstr "n'a pas pu lire le fichier « %s », lu %d sur %d : %m" -#: replication/logical/snapbuild.c:1721 +#: replication/logical/snapbuild.c:1747 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "le fichier d'état snapbuild « %s » a le nombre magique: %u au lieu de %u" -#: replication/logical/snapbuild.c:1726 +#: replication/logical/snapbuild.c:1753 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "le fichier d'état snapbuild « %s » a une version non supportée : %u au lieu de %u" -#: replication/logical/snapbuild.c:1789 +#: replication/logical/snapbuild.c:1825 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "" "différence de somme de contrôle pour lefichier d'état snapbuild %s :\n" "est %u, devrait être %u" -#: replication/logical/snapbuild.c:1844 +#: replication/logical/snapbuild.c:1880 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "Le décodage logique commencera en utilisant un snapshot sauvegardé." -#: replication/logical/snapbuild.c:1916 +#: replication/logical/snapbuild.c:1952 #, c-format msgid "could not parse file name \"%s\"" msgstr "n'a pas pu analyser le mode du fichier « %s »" @@ -17235,7 +18060,7 @@ msgstr "n'a pas pu analyser le mode du fichier « %s »" #: replication/logical/tablesync.c:138 #, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" -msgstr "" +msgstr "le worker de synchronisation de table en réplication logique pour la souscription « %s », table « %s », a terminé" #: replication/logical/tablesync.c:685 #, c-format @@ -17257,132 +18082,132 @@ msgstr "n'a pas pu récupérer les informations sur la table « %s.%s » : %s" msgid "could not start initial contents copy for table \"%s.%s\": %s" msgstr "n'a pas pu lancer la copie initiale du contenu de la table « %s.%s » : %s" -#: replication/logical/tablesync.c:905 +#: replication/logical/tablesync.c:904 #, c-format msgid "table copy could not start transaction on publisher" msgstr "la copie de table n'a pas pu démarrer la transaction sur le publieur" -#: replication/logical/tablesync.c:927 +#: replication/logical/tablesync.c:926 #, c-format msgid "table copy could not finish transaction on publisher" msgstr "la copie de table n'a pas pu finir la transaction sur le publieur" -#: replication/logical/worker.c:291 +#: replication/logical/worker.c:307 #, c-format msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" msgstr "traitement des données distantes pour la relation cible « %s.%s » de réplication logique, colonne « %s », type distant %s, type local %s" -#: replication/logical/worker.c:500 +#: replication/logical/worker.c:528 #, c-format msgid "ORIGIN message sent out of order" msgstr "message ORIGIN en désordre" -#: replication/logical/worker.c:631 +#: replication/logical/worker.c:661 #, c-format -msgid "publisher does not send replica identity column expected by the logical replication target relation \"%s.%s\"" -msgstr "le publieur n'envoie pas la colonne d'identité du réplicat attendue par la relation cible « %s.%s » de réplication logique" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "le publieur n'a pas envoyé la colonne d'identité du réplicat attendue par la relation cible « %s.%s » de réplication logique" -#: replication/logical/worker.c:638 +#: replication/logical/worker.c:668 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" msgstr "la relation cible « %s.%s » de réplication logique n'a ni un index REPLICA IDENTITY ni une clé primaire, et la relation publiée n'a pas REPLICA IDENTITY FULL" -#: replication/logical/worker.c:845 -#, c-format -msgid "logical replication could not find row for delete in replication target %s" -msgstr "la réplication logique n'a pas pu trouver la ligne à supprimer dans la cible de réplication %s" - -#: replication/logical/worker.c:912 +#: replication/logical/worker.c:1007 #, c-format -msgid "invalid logical replication message type %c" -msgstr "type %c du message de la réplication logique invalide" +msgid "invalid logical replication message type \"%c\"" +msgstr "type « %c » du message de la réplication logique invalide" -#: replication/logical/worker.c:1053 +#: replication/logical/worker.c:1148 #, c-format msgid "data stream from publisher has ended" msgstr "le flux de données provenant du publieur s'est terminé" -#: replication/logical/worker.c:1212 +#: replication/logical/worker.c:1307 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "arrêt du processus worker de la réplication logique suite à l'expiration du délai de réplication" -#: replication/logical/worker.c:1360 +#: replication/logical/worker.c:1455 #, c-format msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" msgstr "le processus apply de réplication logique pour la souscription « %s » s'arrêtera car la souscription a été supprimée" -#: replication/logical/worker.c:1374 +#: replication/logical/worker.c:1469 #, c-format msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" msgstr "le processus apply de réplication logique pour la souscription « %s » s'arrêtera car la souscription a été désactivée" -#: replication/logical/worker.c:1388 +#: replication/logical/worker.c:1483 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car la souscription a été modifiée" -#: replication/logical/worker.c:1402 +#: replication/logical/worker.c:1497 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car la souscription a été renommée" -#: replication/logical/worker.c:1419 +#: replication/logical/worker.c:1514 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car le nom du slot de réplication a été modifiée" -#: replication/logical/worker.c:1433 +#: replication/logical/worker.c:1528 #, c-format msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" msgstr "le processus apply de réplication logique pour la souscription « %s » redémarrera car les publications ont été modifiées" -#: replication/logical/worker.c:1541 +#: replication/logical/worker.c:1631 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "le processus apply de réplication logique pour la souscription %u ne démarrera pas car la souscription a été désactivée au démarrage" + +#: replication/logical/worker.c:1643 #, c-format msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgstr "le processus apply de réplication logique pour la souscription « %s » ne démarrera pas car la souscription a été désactivée au démarrage" -#: replication/logical/worker.c:1555 +#: replication/logical/worker.c:1661 #, c-format msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" msgstr "le processus de synchronisation des tables en réplication logique pour la souscription « %s », table « %s » a démarré" -#: replication/logical/worker.c:1559 +#: replication/logical/worker.c:1665 #, c-format msgid "logical replication apply worker for subscription \"%s\" has started" msgstr "le processus apply de réplication logique pour la souscription « %s » a démarré" -#: replication/logical/worker.c:1599 +#: replication/logical/worker.c:1705 #, c-format msgid "subscription has no replication slot set" msgstr "la souscription n'a aucun ensemble de slot de réplication" -#: replication/pgoutput/pgoutput.c:113 +#: replication/pgoutput/pgoutput.c:117 #, c-format msgid "invalid proto_version" msgstr "proto_version invalide" -#: replication/pgoutput/pgoutput.c:118 +#: replication/pgoutput/pgoutput.c:122 #, c-format -msgid "proto_verson \"%s\" out of range" -msgstr "proto_version « %s » est en dehors des limites" +msgid "proto_version \"%s\" out of range" +msgstr "proto_version « %s » en dehors des limites" -#: replication/pgoutput/pgoutput.c:135 +#: replication/pgoutput/pgoutput.c:139 #, c-format msgid "invalid publication_names syntax" msgstr "syntaxe publication_names invalide" -#: replication/pgoutput/pgoutput.c:179 +#: replication/pgoutput/pgoutput.c:181 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or lower" msgstr "le client a envoyé proto_version=%d mais nous supportons seulement le protocole %d et les protocoles antérieurs" -#: replication/pgoutput/pgoutput.c:185 +#: replication/pgoutput/pgoutput.c:187 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or higher" msgstr "le client a envoyé proto_version=%d mais nous supportons seulement le protocole %d et les protocoles supérieurs" -#: replication/pgoutput/pgoutput.c:191 +#: replication/pgoutput/pgoutput.c:193 #, c-format msgid "publication_names parameter missing" msgstr "paramètre publication_names manquant" @@ -17422,81 +18247,116 @@ msgstr "tous les slots de réplication sont utilisés" msgid "Free one or increase max_replication_slots." msgstr "Libérez un slot ou augmentez max_replication_slots." -#: replication/slot.c:379 +#: replication/slot.c:387 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "le slot de réplication « %s » n'existe pas" -#: replication/slot.c:390 replication/slot.c:939 +#: replication/slot.c:398 replication/slot.c:948 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "le slot de réplication « %s » est actif pour le PID %d" -#: replication/slot.c:623 replication/slot.c:1120 replication/slot.c:1469 +#: replication/slot.c:632 replication/slot.c:1141 replication/slot.c:1495 #, c-format msgid "could not remove directory \"%s\"" msgstr "n'a pas pu supprimer le répertoire « %s »" -#: replication/slot.c:969 +#: replication/slot.c:983 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "les slots de réplications peuvent seulement être utilisés si max_replication_slots > 0" -#: replication/slot.c:974 +#: replication/slot.c:988 #, c-format msgid "replication slots can only be used if wal_level >= replica" msgstr "les slots de réplication peuvent seulement être utilisés si wal_level >= replica" -#: replication/slot.c:1399 replication/slot.c:1439 +#: replication/slot.c:1427 replication/slot.c:1467 #, c-format msgid "could not read file \"%s\", read %d of %u: %m" msgstr "n'a pas pu lire le fichier « %s », a lu %d sur %u : %m" -#: replication/slot.c:1408 +#: replication/slot.c:1436 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "le fichier « %s » du slot de réplication a le nombre magique %u au lieu de %u" -#: replication/slot.c:1415 +#: replication/slot.c:1443 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "le fichier « %s » du slot de réplication a une version %u non supportée" -#: replication/slot.c:1422 +#: replication/slot.c:1450 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "le slot de réplication « %s » a une taille %u corrompue" -#: replication/slot.c:1454 +#: replication/slot.c:1482 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "différence de somme de contrôle pour le fichier de slot de réplication « %s » : est %u, devrait être %u" -#: replication/slot.c:1507 +#: replication/slot.c:1516 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "le slot de réplication logique « %s » existe mais, wal_level < logical" + +#: replication/slot.c:1518 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Modifiez wal_level pour valoir logical ou supérieur." + +#: replication/slot.c:1522 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "le slot de réplication physique « %s » existe mais, wal_level < replica" + +#: replication/slot.c:1524 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Modifiez wal_level pour valoir replica ou supérieur." + +#: replication/slot.c:1558 #, c-format msgid "too many replication slots active before shutdown" msgstr "trop de slots de réplication actifs avant l'arrêt" -#: replication/syncrep.c:248 +#: replication/slotfuncs.c:490 +#, c-format +msgid "invalid target wal lsn" +msgstr "wal lsn de destination invalide" + +#: replication/slotfuncs.c:512 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "impossible d'avancer un slot de réplication qui n'a pas auparavant réservé de WAL" + +#: replication/slotfuncs.c:528 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "impossible d'avancer le slot de réplication vers %X/%X, le minimum est %X/%X" + +#: replication/syncrep.c:246 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "" "annulation de l'attente pour la réplication synchrone et arrêt des connexions\n" "suite à la demande de l'administrateur" -#: replication/syncrep.c:249 replication/syncrep.c:266 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgstr "" "La transaction a déjà enregistré les données localement, mais il se peut que\n" "cela n'ait pas été répliqué sur le serveur en standby." -#: replication/syncrep.c:265 +#: replication/syncrep.c:263 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "annulation de l'attente pour la réplication synchrone à la demande de l'utilisateur" -#: replication/syncrep.c:399 +#: replication/syncrep.c:397 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "" @@ -17513,215 +18373,215 @@ msgstr "le serveur « %s » en standby est maintenant un serveur standby synchro msgid "standby \"%s\" is now a candidate for quorum synchronous standby" msgstr "le serveur standby « %s » est maintenant un candidat dans le quorum des standbys synchrones" -#: replication/syncrep.c:1162 +#: replication/syncrep.c:1164 #, c-format msgid "synchronous_standby_names parser failed" msgstr "l'analyseur du paramètre synchronous_standby_names a échoué" -#: replication/syncrep.c:1168 +#: replication/syncrep.c:1170 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "le nombre de standbys synchrones (%d) doit être supérieur à zéro" -#: replication/walreceiver.c:168 +#: replication/walreceiver.c:169 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "arrêt du processus walreceiver suite à la demande de l'administrateur" -#: replication/walreceiver.c:300 +#: replication/walreceiver.c:309 #, c-format msgid "could not connect to the primary server: %s" msgstr "n'a pas pu se connecter au serveur principal : %s" -#: replication/walreceiver.c:339 +#: replication/walreceiver.c:359 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "" "l'identifiant du système de bases de données diffère entre le serveur principal\n" "et le serveur en attente" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:360 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "" "L'identifiant du serveur principal est %s, l'identifiant du serveur en attente\n" "est %s." -#: replication/walreceiver.c:351 +#: replication/walreceiver.c:371 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "la plus grande timeline %u du serveur principal est derrière la timeline de restauration %u" -#: replication/walreceiver.c:387 +#: replication/walreceiver.c:407 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "Commence le flux des journaux depuis le principal à %X/%X sur la timeline %u" -#: replication/walreceiver.c:392 +#: replication/walreceiver.c:412 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "recommence le flux WAL à %X/%X sur la timeline %u" -#: replication/walreceiver.c:421 +#: replication/walreceiver.c:441 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "ne peut pas continuer le flux de journaux de transactions, la récupération est déjà terminée" -#: replication/walreceiver.c:458 +#: replication/walreceiver.c:478 #, c-format msgid "replication terminated by primary server" msgstr "réplication terminée par le serveur primaire" -#: replication/walreceiver.c:459 +#: replication/walreceiver.c:479 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "Fin du WAL atteint sur la timeline %u à %X/%X" -#: replication/walreceiver.c:554 +#: replication/walreceiver.c:574 #, c-format msgid "terminating walreceiver due to timeout" msgstr "arrêt du processus walreceiver suite à l'expiration du délai de réplication" -#: replication/walreceiver.c:594 +#: replication/walreceiver.c:614 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "le serveur principal ne contient plus de WAL sur la timeline %u demandée" -#: replication/walreceiver.c:609 replication/walreceiver.c:968 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format msgid "could not close log segment %s: %m" msgstr "n'a pas pu fermer le journal de transactions %s : %m" -#: replication/walreceiver.c:734 +#: replication/walreceiver.c:754 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "récupération du fichier historique pour la timeline %u à partir du serveur principal" -#: replication/walreceiver.c:1022 +#: replication/walreceiver.c:1036 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "n'a pas pu écrire le journal de transactions %s au décalage %u, longueur %lu : %m" -#: replication/walsender.c:490 +#: replication/walsender.c:494 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "n'a pas pu se déplacer au début du fichier « %s » : %m" -#: replication/walsender.c:531 +#: replication/walsender.c:535 #, c-format msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" msgstr "IDENTIFY_SYSTEM n'a pas été exécuté avant START_REPLICATION" -#: replication/walsender.c:548 +#: replication/walsender.c:552 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "ne peut pas utiliser un slot de réplication logique pour une réplication physique" -#: replication/walsender.c:611 +#: replication/walsender.c:615 #, c-format msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "le point de reprise %X/%X de la timeline %u n'est pas dans l'historique du serveur" -#: replication/walsender.c:615 +#: replication/walsender.c:619 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "L'historique du serveur a changé à partir de la timeline %u à %X/%X." -#: replication/walsender.c:660 +#: replication/walsender.c:664 #, c-format msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "le point de reprise requis %X/%X est devant la position de vidage des WAL de ce serveur %X/%X" -#: replication/walsender.c:889 +#: replication/walsender.c:893 #, c-format msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT ne doit pas être appelé dans une sous-transaction" -#: replication/walsender.c:898 +#: replication/walsender.c:902 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT doit être appelé dans une transaction" -#: replication/walsender.c:903 +#: replication/walsender.c:907 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT doit être appelé dans le niveau d'isolation REPEATABLE READ" -#: replication/walsender.c:908 +#: replication/walsender.c:912 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT doit être appelé avant toute requête" -#: replication/walsender.c:913 +#: replication/walsender.c:917 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT ne doit pas être appelé dans une sous-transaction" -#: replication/walsender.c:1059 +#: replication/walsender.c:1063 #, c-format msgid "terminating walsender process after promotion" msgstr "arrêt du processus walreceiver suite promotion" -#: replication/walsender.c:1437 +#: replication/walsender.c:1448 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "ne peut pas exécuter de nouvelles commandes alors que le walsender est en mode d'arrêt" -#: replication/walsender.c:1470 +#: replication/walsender.c:1481 #, c-format msgid "received replication command: %s" msgstr "commande de réplication reçu : %s" -#: replication/walsender.c:1486 tcop/fastpath.c:281 tcop/postgres.c:997 tcop/postgres.c:1307 tcop/postgres.c:1566 tcop/postgres.c:1971 tcop/postgres.c:2339 tcop/postgres.c:2414 +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1033 tcop/postgres.c:1357 tcop/postgres.c:1617 tcop/postgres.c:2023 tcop/postgres.c:2396 tcop/postgres.c:2475 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "" "la transaction est annulée, les commandes sont ignorées jusqu'à la fin du bloc\n" "de la transaction" -#: replication/walsender.c:1548 +#: replication/walsender.c:1565 #, c-format -msgid "not connected to database" -msgstr "non connecté à une base de données" +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "ne peut pas exécuter des commandes SQL dans le walsender pour la réplication physique" -#: replication/walsender.c:1588 replication/walsender.c:1604 +#: replication/walsender.c:1613 replication/walsender.c:1629 #, c-format msgid "unexpected EOF on standby connection" msgstr "fin de fichier (EOF) inattendue de la connexion du serveur en attente" -#: replication/walsender.c:1618 +#: replication/walsender.c:1643 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "type de message standby « %c » inattendu, après avoir reçu CopyDone" -#: replication/walsender.c:1656 +#: replication/walsender.c:1681 #, c-format msgid "invalid standby message type \"%c\"" msgstr "type de message « %c » invalide pour le serveur en standby" -#: replication/walsender.c:1697 +#: replication/walsender.c:1722 #, c-format msgid "unexpected message type \"%c\"" msgstr "type de message « %c » inattendu" -#: replication/walsender.c:2067 +#: replication/walsender.c:2100 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "arrêt du processus walreceiver suite à l'expiration du délai de réplication" -#: replication/walsender.c:2156 +#: replication/walsender.c:2184 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "le serveur standby « %s » a maintenant rattrapé le serveur primaire" +msgid "\"%s\" has now caught up with upstream server" +msgstr "« %s » a maintenant rattrapé le serveur en amont" -#: replication/walsender.c:2263 +#: replication/walsender.c:2293 #, c-format msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" msgstr "" "le nombre de connexions demandées par le serveur en attente dépasse\n" "max_wal_senders (actuellement %d)" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:981 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "la règle « %s » existe déjà pour la relation « %s »" @@ -17792,13 +18652,13 @@ msgstr "la règle de la vue pour « %s » doit être nommée « %s »" #: rewrite/rewriteDefine.c:428 #, c-format -msgid "could not convert partitioned table \"%s\" to a view" -msgstr "n'a pas pu convertir la table partitionnée « %s » en une vue" +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "ne peut pas convertir la table partitionnée « %s » en une vue" #: rewrite/rewriteDefine.c:434 #, c-format -msgid "could not convert partition \"%s\" to a view" -msgstr "n'a pas pu convertir la partition « %s » en une vue" +msgid "cannot convert partition \"%s\" to a view" +msgstr "ne peut pas convertir la partition « %s » en une vue" #: rewrite/rewriteDefine.c:442 #, c-format @@ -17852,277 +18712,272 @@ msgstr "les listes RETURNING ne sont pas supportés dans des règles conditionne msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "les listes RETURNING ne sont pas supportés dans des règles autres que INSTEAD" -#: rewrite/rewriteDefine.c:676 +#: rewrite/rewriteDefine.c:675 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "la liste cible de la règle SELECT a trop d'entrées" -#: rewrite/rewriteDefine.c:677 +#: rewrite/rewriteDefine.c:676 #, c-format msgid "RETURNING list has too many entries" msgstr "la liste RETURNING a trop d'entrées" -#: rewrite/rewriteDefine.c:704 +#: rewrite/rewriteDefine.c:703 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "ne peut pas convertir la relation contenant les colonnes supprimées de la vue" -#: rewrite/rewriteDefine.c:705 +#: rewrite/rewriteDefine.c:704 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "ne peut pas créer une liste RETURNING pour une relation contenant des colonnes supprimées" -#: rewrite/rewriteDefine.c:711 +#: rewrite/rewriteDefine.c:710 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "l'entrée cible de la règle SELECT %d a un nom de colonne différent pour la colonne « %s »" -#: rewrite/rewriteDefine.c:713 +#: rewrite/rewriteDefine.c:712 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "l'entrée cible de la règle SELECT est nommé « %s »." -#: rewrite/rewriteDefine.c:722 +#: rewrite/rewriteDefine.c:721 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "l'entrée cible de la règle SELECT %d a plusieurs types pour la colonne « %s »" -#: rewrite/rewriteDefine.c:724 +#: rewrite/rewriteDefine.c:723 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "l'entrée %d de la liste RETURNING a un type différent de la colonne « %s »" -#: rewrite/rewriteDefine.c:727 rewrite/rewriteDefine.c:751 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "l'entrée de la liste SELECT a le type %s alors que la colonne a le type %s." -#: rewrite/rewriteDefine.c:730 rewrite/rewriteDefine.c:755 +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "l'entrée de la liste RETURNING a le type %s alors que la colonne a le type %s." -#: rewrite/rewriteDefine.c:746 +#: rewrite/rewriteDefine.c:745 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "l'entrée cible de la règle SELECT %d a plusieurs tailles pour la colonne « %s »" -#: rewrite/rewriteDefine.c:748 +#: rewrite/rewriteDefine.c:747 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "l'entrée %d de la liste RETURNING a plusieurs tailles pour la colonne « %s »" -#: rewrite/rewriteDefine.c:765 +#: rewrite/rewriteDefine.c:764 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "l'entrée cible de la règle SELECT n'a pas assez d'entrées" -#: rewrite/rewriteDefine.c:766 +#: rewrite/rewriteDefine.c:765 #, c-format msgid "RETURNING list has too few entries" msgstr "la liste RETURNING n'a pas assez d'entrées" -#: rewrite/rewriteDefine.c:858 rewrite/rewriteDefine.c:972 rewrite/rewriteSupport.c:109 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "la règle « %s » de la relation « %s » n'existe pas" -#: rewrite/rewriteDefine.c:991 +#: rewrite/rewriteDefine.c:990 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "le renommage d'une règle ON SELECT n'est pas autorisé" -#: rewrite/rewriteHandler.c:543 +#: rewrite/rewriteHandler.c:540 #, c-format msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" msgstr "" "Le nom de la requête WITH «%s » apparaît à la fois dans l'action d'une règle\n" "et la requête en cours de ré-écriture." -#: rewrite/rewriteHandler.c:603 +#: rewrite/rewriteHandler.c:600 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "ne peut pas avoir des listes RETURNING dans plusieurs règles" -#: rewrite/rewriteHandler.c:818 +#: rewrite/rewriteHandler.c:809 #, c-format msgid "cannot insert into column \"%s\"" msgstr "ne peut pas insérer dans la colonne « %s »" -#: rewrite/rewriteHandler.c:819 rewrite/rewriteHandler.c:834 +#: rewrite/rewriteHandler.c:810 rewrite/rewriteHandler.c:825 #, c-format msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." msgstr "La colonne « %s » est une colonne d'identité définie comme GENERATED ALWAYS." -#: rewrite/rewriteHandler.c:821 +#: rewrite/rewriteHandler.c:812 #, c-format msgid "Use OVERRIDING SYSTEM VALUE to override." msgstr "Utilisez OVERRIDING SYSTEM VALUE pour surcharger." -#: rewrite/rewriteHandler.c:833 +#: rewrite/rewriteHandler.c:824 #, c-format msgid "column \"%s\" can only be updated to DEFAULT" msgstr "la colonne « %s » peut seulement être mise à jour en DEFAULT" -#: rewrite/rewriteHandler.c:1005 rewrite/rewriteHandler.c:1023 +#: rewrite/rewriteHandler.c:986 rewrite/rewriteHandler.c:1004 #, c-format msgid "multiple assignments to same column \"%s\"" msgstr "affectations multiples pour la même colonne « %s »" -#: rewrite/rewriteHandler.c:1809 rewrite/rewriteHandler.c:3431 -#, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "récursion infinie détectée dans les règles de la relation « %s »" - -#: rewrite/rewriteHandler.c:1895 +#: rewrite/rewriteHandler.c:2027 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "récursion infinie détectée dans la politique pour la relation « %s »" -#: rewrite/rewriteHandler.c:2212 +#: rewrite/rewriteHandler.c:2347 msgid "Junk view columns are not updatable." msgstr "Les colonnes « junk » des vues ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2217 +#: rewrite/rewriteHandler.c:2352 msgid "View columns that are not columns of their base relation are not updatable." msgstr "Les colonnes des vues qui ne font pas référence à des colonnes de la relation de base ne sont pas automatiquement modifiables." -#: rewrite/rewriteHandler.c:2220 +#: rewrite/rewriteHandler.c:2355 msgid "View columns that refer to system columns are not updatable." msgstr "Les colonnes des vues qui font référence à des colonnes systèmes ne sont pas automatiquement modifiables." -#: rewrite/rewriteHandler.c:2223 +#: rewrite/rewriteHandler.c:2358 msgid "View columns that return whole-row references are not updatable." msgstr "Les colonnes de vue qui font références à des lignes complètes ne sont pas automatiquement modifiables." -#: rewrite/rewriteHandler.c:2281 +#: rewrite/rewriteHandler.c:2419 msgid "Views containing DISTINCT are not automatically updatable." msgstr "Les vues contenant DISTINCT ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2284 +#: rewrite/rewriteHandler.c:2422 msgid "Views containing GROUP BY are not automatically updatable." msgstr "Les vues contenant GROUP BY ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2287 +#: rewrite/rewriteHandler.c:2425 msgid "Views containing HAVING are not automatically updatable." msgstr "Les vues contenant HAVING ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2290 +#: rewrite/rewriteHandler.c:2428 msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "Les vues contenant UNION, INTERSECT ou EXCEPT ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2293 +#: rewrite/rewriteHandler.c:2431 msgid "Views containing WITH are not automatically updatable." msgstr "Les vues contenant WITH ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2296 +#: rewrite/rewriteHandler.c:2434 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "Les vues contenant LIMIT ou OFFSET ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2308 +#: rewrite/rewriteHandler.c:2446 msgid "Views that return aggregate functions are not automatically updatable." msgstr "Les vues qui renvoient des fonctions d'agrégat ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2311 +#: rewrite/rewriteHandler.c:2449 msgid "Views that return window functions are not automatically updatable." msgstr "Les vues qui renvoient des fonctions de fenêtrage ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2314 +#: rewrite/rewriteHandler.c:2452 msgid "Views that return set-returning functions are not automatically updatable." msgstr "Les vues qui renvoient des fonctions à plusieurs lignes ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2321 rewrite/rewriteHandler.c:2325 rewrite/rewriteHandler.c:2333 +#: rewrite/rewriteHandler.c:2459 rewrite/rewriteHandler.c:2463 rewrite/rewriteHandler.c:2471 msgid "Views that do not select from a single table or view are not automatically updatable." msgstr "Les vues qui lisent plusieurs tables ou vues ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2336 +#: rewrite/rewriteHandler.c:2474 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "Les vues contenant TABLESAMPLE ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2360 +#: rewrite/rewriteHandler.c:2498 msgid "Views that have no updatable columns are not automatically updatable." msgstr "Les vues qui possèdent des colonnes non modifiables ne sont pas automatiquement disponibles en écriture." -#: rewrite/rewriteHandler.c:2814 +#: rewrite/rewriteHandler.c:2955 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "ne peut pas insérer dans la colonne « %s » de la vue « %s »" -#: rewrite/rewriteHandler.c:2822 +#: rewrite/rewriteHandler.c:2963 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "ne peut pas mettre à jour la colonne « %s » de la vue « %s »" -#: rewrite/rewriteHandler.c:3225 +#: rewrite/rewriteHandler.c:3433 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "" "les règles DO INSTEAD NOTHING ne sont pas supportées par les instructions\n" "de modification de données dans WITH" -#: rewrite/rewriteHandler.c:3239 +#: rewrite/rewriteHandler.c:3447 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "" "les règles DO INSTEAD conditionnelles ne sont pas supportées par les\n" "instructions de modification de données dans WITH" -#: rewrite/rewriteHandler.c:3243 +#: rewrite/rewriteHandler.c:3451 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "" "les règles DO ALSO ne sont pas supportées par les instructions de modification\n" "de données dans WITH" -#: rewrite/rewriteHandler.c:3248 +#: rewrite/rewriteHandler.c:3456 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "" "les règles DO INSTEAD multi-instructions ne sont pas supportées pour les\n" "instructions de modification de données dans WITH" -#: rewrite/rewriteHandler.c:3468 +#: rewrite/rewriteHandler.c:3706 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "ne peut pas exécuter INSERT RETURNING sur la relation « %s »" -#: rewrite/rewriteHandler.c:3470 +#: rewrite/rewriteHandler.c:3708 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "" "Vous avez besoin d'une règle ON INSERT DO INSTEAD sans condition avec une\n" "clause RETURNING." -#: rewrite/rewriteHandler.c:3475 +#: rewrite/rewriteHandler.c:3713 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "ne peut pas exécuter UPDATE RETURNING sur la relation « %s »" -#: rewrite/rewriteHandler.c:3477 +#: rewrite/rewriteHandler.c:3715 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "" "Vous avez besoin d'une règle ON UPDATE DO INSTEAD sans condition avec une\n" "clause RETURNING." -#: rewrite/rewriteHandler.c:3482 +#: rewrite/rewriteHandler.c:3720 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "ne peut pas exécuter DELETE RETURNING sur la relation « %s »" -#: rewrite/rewriteHandler.c:3484 +#: rewrite/rewriteHandler.c:3722 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "" "Vous avez besoin d'une règle ON DELETE DO INSTEAD sans condition avec une\n" "clause RETURNING." -#: rewrite/rewriteHandler.c:3502 +#: rewrite/rewriteHandler.c:3740 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT avec une clause ON CONFLICT ne peut pas être utilisée avec une table qui a des règles pour INSERT ou UPDATE" -#: rewrite/rewriteHandler.c:3559 +#: rewrite/rewriteHandler.c:3797 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH ne peut pas être utilisé dans une requête réécrite par des règles en plusieurs requêtes" @@ -18137,132 +18992,132 @@ msgstr "les instructions conditionnelles ne sont pas implémentées" msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF n'est pas implémenté sur une vue" -#: rewrite/rewriteManip.c:1463 +#: rewrite/rewriteManip.c:1503 #, c-format msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" msgstr "les variables NEW des règles ON UPDATE ne peuvent pas référencer des colonnes faisant partie d'une affectation multiple dans une commande UPDATE" -#: scan.l:432 +#: scan.l:445 msgid "unterminated /* comment" msgstr "commentaire /* non terminé" -#: scan.l:461 +#: scan.l:474 msgid "unterminated bit string literal" msgstr "chaîne littérale bit non terminée" -#: scan.l:482 +#: scan.l:495 msgid "unterminated hexadecimal string literal" msgstr "chaîne littérale hexadécimale non terminée" -#: scan.l:532 +#: scan.l:545 #, c-format msgid "unsafe use of string constant with Unicode escapes" msgstr "utilisation non sûre de la constante de chaîne avec des échappements Unicode" -#: scan.l:533 +#: scan.l:546 #, c-format msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." msgstr "" "Les constantes de chaîne avec des échappements Unicode ne peuvent pas être\n" "utilisées quand standard_conforming_strings est désactivé." -#: scan.l:579 scan.l:778 +#: scan.l:592 scan.l:791 msgid "invalid Unicode escape character" msgstr "chaîne d'échappement Unicode invalide" -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1337 scan.l:1364 scan.l:1368 scan.l:1406 scan.l:1410 scan.l:1432 scan.l:1442 +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 msgid "invalid Unicode surrogate pair" msgstr "paire surrogate Unicode invalide" -#: scan.l:627 +#: scan.l:640 #, c-format msgid "invalid Unicode escape" msgstr "échappement Unicode invalide" -#: scan.l:628 +#: scan.l:641 #, c-format msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." msgstr "Les échappements Unicode doivent être de la forme \\uXXXX ou \\UXXXXXXXX." -#: scan.l:639 +#: scan.l:652 #, c-format msgid "unsafe use of \\' in a string literal" msgstr "utilisation non sûre de \\' dans une chaîne littérale" -#: scan.l:640 +#: scan.l:653 #, c-format msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." msgstr "" "Utilisez '' pour écrire des guillemets dans une chaîne. \\' n'est pas sécurisé\n" "pour les encodages clients." -#: scan.l:715 +#: scan.l:728 msgid "unterminated dollar-quoted string" msgstr "chaîne entre guillemets dollars non terminée" -#: scan.l:732 scan.l:758 scan.l:773 +#: scan.l:745 scan.l:771 scan.l:786 msgid "zero-length delimited identifier" msgstr "identifiant délimité de longueur nulle" -#: scan.l:793 syncrep_scanner.l:89 +#: scan.l:806 syncrep_scanner.l:91 msgid "unterminated quoted identifier" msgstr "identifiant entre guillemets non terminé" -#: scan.l:924 +#: scan.l:969 msgid "operator too long" msgstr "opérateur trop long" #. translator: %s is typically the translation of "syntax error" -#: scan.l:1077 +#: scan.l:1125 #, c-format msgid "%s at end of input" msgstr "%s à la fin de l'entrée" #. translator: first %s is typically the translation of "syntax error" -#: scan.l:1085 +#: scan.l:1133 #, c-format msgid "%s at or near \"%s\"" msgstr "%s sur ou près de « %s »" -#: scan.l:1251 scan.l:1283 +#: scan.l:1294 scan.l:1326 msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" msgstr "" "Les valeurs d'échappement unicode ne peuvent pas être utilisées pour les\n" "valeurs de point de code au-dessus de 007F quand l'encodage serveur n'est\n" "pas UTF8" -#: scan.l:1279 scan.l:1424 +#: scan.l:1322 scan.l:1467 msgid "invalid Unicode escape value" msgstr "valeur d'échappement Unicode invalide" -#: scan.l:1488 +#: scan.l:1531 #, c-format msgid "nonstandard use of \\' in a string literal" msgstr "utilisation non standard de \\' dans une chaîne littérale" -#: scan.l:1489 +#: scan.l:1532 #, c-format msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." msgstr "" "Utilisez '' pour écrire des guillemets dans une chaîne ou utilisez la syntaxe de\n" "chaîne d'échappement (E'...')." -#: scan.l:1498 +#: scan.l:1541 #, c-format msgid "nonstandard use of \\\\ in a string literal" msgstr "utilisation non standard de \\\\ dans une chaîne littérale" -#: scan.l:1499 +#: scan.l:1542 #, c-format msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." msgstr "Utilisez la syntaxe de chaîne d'échappement pour les antislashs, c'est-à-dire E'\\\\'." -#: scan.l:1513 +#: scan.l:1556 #, c-format msgid "nonstandard use of escape in a string literal" msgstr "utilisation non standard d'un échappement dans une chaîne littérale" -#: scan.l:1514 +#: scan.l:1557 #, c-format msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." msgstr "" @@ -18299,35 +19154,35 @@ msgstr "paramètre Language manquant" msgid "invalid zero-length item array in MVDependencies" msgstr "tableau d'éléments de longueur zéro invalide dans MVDependencies" -#: statistics/dependencies.c:665 statistics/dependencies.c:718 statistics/mvdistinct.c:338 statistics/mvdistinct.c:391 utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 +#: statistics/dependencies.c:672 statistics/dependencies.c:725 statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 #, c-format msgid "cannot accept a value of type %s" msgstr "ne peut pas accepter une valeur de type %s" -#: statistics/extended_stats.c:102 +#: statistics/extended_stats.c:104 #, c-format msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgstr "l'objet de statistiques « %s.%s » n'a pas pu être calculé pour la relation « %s.%s »" -#: statistics/mvdistinct.c:259 +#: statistics/mvdistinct.c:262 #, c-format msgid "invalid ndistinct magic %08x (expected %08x)" -msgstr "" +msgstr "nombre magique ndistinct invalide %08x (attendu %08x)" -#: statistics/mvdistinct.c:264 +#: statistics/mvdistinct.c:267 #, c-format msgid "invalid ndistinct type %d (expected %d)" msgstr "type ndistinct invalide %d (%d attendu)" -#: statistics/mvdistinct.c:269 +#: statistics/mvdistinct.c:272 #, c-format msgid "invalid zero-length item array in MVNDistinct" msgstr "tableau d'élément de longueur zéro invalide dans MVNDistinct" -#: statistics/mvdistinct.c:278 +#: statistics/mvdistinct.c:281 #, c-format msgid "invalid MVNDistinct size %zd (expected at least %zd)" -msgstr "" +msgstr "taille MVNDistinct %zd invalide (attendue au moins %zd)" #: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 #, c-format @@ -18368,7 +19223,7 @@ msgstr "Échecs multiples --- l'erreur d'écriture pourrait être permanent." msgid "writing block %u of relation %s" msgstr "écriture du bloc %u de la relation %s" -#: storage/buffer/bufmgr.c:4356 +#: storage/buffer/bufmgr.c:4358 #, c-format msgid "snapshot too old" msgstr "snapshot trop ancien" @@ -18383,162 +19238,212 @@ msgstr "aucun tampon local vide disponible" msgid "cannot access temporary tables during a parallel operation" msgstr "ne peut pas accéder à des tables temporaires pendant une opération parallèle" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: storage/file/buffile.c:317 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire « %s » à partir de BufFile « %s » : %m" + +#: storage/file/buffile.c:814 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "n'a pas pu déterminer la taille du fichier temporaire « %s » à partir de BufFile « %s » : %m" + +#: storage/file/fd.c:470 storage/file/fd.c:542 storage/file/fd.c:578 #, c-format msgid "could not flush dirty data: %m" msgstr "n'a pas pu vider les données modifiées : %m" -#: storage/file/fd.c:473 +#: storage/file/fd.c:500 #, c-format msgid "could not determine dirty data size: %m" msgstr "n'a pas pu déterminer la taille des données modifiées : %m" -#: storage/file/fd.c:525 +#: storage/file/fd.c:552 #, c-format msgid "could not munmap() while flushing data: %m" msgstr "n'a pas exécuter munmap() durant la synchronisation des données : %m" -#: storage/file/fd.c:726 +#: storage/file/fd.c:753 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "n'a pas pu lier le fichier « %s » à « %s » : %m" -#: storage/file/fd.c:820 +#: storage/file/fd.c:847 #, c-format msgid "getrlimit failed: %m" msgstr "échec de getrlimit : %m" -#: storage/file/fd.c:910 +#: storage/file/fd.c:937 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "nombre de descripteurs de fichier insuffisants pour lancer le processus serveur" -#: storage/file/fd.c:911 +#: storage/file/fd.c:938 #, c-format msgid "System allows %d, we need at least %d." msgstr "Le système autorise %d, nous avons besoin d'au moins %d." -#: storage/file/fd.c:952 storage/file/fd.c:2129 storage/file/fd.c:2222 storage/file/fd.c:2370 +#: storage/file/fd.c:989 storage/file/fd.c:2398 storage/file/fd.c:2508 storage/file/fd.c:2659 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "plus de descripteurs de fichiers : %m; quittez et ré-essayez" -#: storage/file/fd.c:1557 +#: storage/file/fd.c:1332 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "fichier temporaire : chemin « %s », taille %lu" -#: storage/file/fd.c:1760 +#: storage/file/fd.c:1464 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "ne peut pas créer le répertoire temporaire « %s » : %m" + +#: storage/file/fd.c:1471 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "ne peut pas créer le sous-répertoire temporaire « %s » : %m" + +#: storage/file/fd.c:1664 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "n'a pas pu créer le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:1699 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:1740 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier temporaire « %s » : %m" + +#: storage/file/fd.c:2029 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "la taille du fichier temporaire dépasse temp_file_limit (%d Ko)" -#: storage/file/fd.c:2105 storage/file/fd.c:2155 +#: storage/file/fd.c:2374 storage/file/fd.c:2433 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'ouverture du fichier « %s »" -#: storage/file/fd.c:2195 +#: storage/file/fd.c:2478 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'exécution de la commande « %s »" -#: storage/file/fd.c:2346 +#: storage/file/fd.c:2635 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "dépassement de maxAllocatedDescs (%d) lors de la tentative d'ouverture du répertoire « %s »" -#: storage/file/fd.c:2432 utils/adt/genfile.c:511 +#: storage/file/fd.c:2726 #, c-format msgid "could not read directory \"%s\": %m" msgstr "n'a pas pu lire le répertoire « %s » : %m" -#: storage/ipc/dsm.c:364 +#: storage/file/fd.c:3158 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "fichier non attendu dans le répertoire des fichiers temporaires : « %s »" + +#: storage/file/fd.c:3480 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "n'a pas pu supprimer le répertoire « %s » : %m" + +#: storage/file/sharedfileset.c:93 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "n'a pas pu s'attacher a un SharedFileSet qui est déjà détruit" + +#: storage/ipc/dsm.c:351 #, c-format msgid "dynamic shared memory control segment is corrupt" msgstr "le segment contrôle de mémoire partagée dynamique est corrompu" -#: storage/ipc/dsm.c:411 +#: storage/ipc/dsm.c:398 #, c-format msgid "dynamic shared memory is disabled" msgstr "la mémoire partagée dynamique est désactivée" -#: storage/ipc/dsm.c:412 +#: storage/ipc/dsm.c:399 #, c-format msgid "Set dynamic_shared_memory_type to a value other than \"none\"." msgstr "Configurez dynamic_shared_memory_type à une valeur autre que « none »." -#: storage/ipc/dsm.c:432 +#: storage/ipc/dsm.c:419 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "le segment contrôle de mémoire partagée dynamique n'est pas valide" -#: storage/ipc/dsm.c:528 +#: storage/ipc/dsm.c:515 #, c-format msgid "too many dynamic shared memory segments" msgstr "trop de segments de mémoire partagée dynamique" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 storage/ipc/dsm_impl.c:819 storage/ipc/dsm_impl.c:963 +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "n'a pas pu annuler le mappage du segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:829 +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "n'a pas pu supprimer le segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:729 storage/ipc/dsm_impl.c:843 +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 storage/ipc/dsm_impl.c:904 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "n'a pas pu ouvrir le segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 storage/ipc/dsm_impl.c:774 storage/ipc/dsm_impl.c:867 +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "n'a pas pu obtenir des informations sur le segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:886 storage/ipc/dsm_impl.c:936 +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 storage/ipc/dsm_impl.c:997 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "n'a pas pu retailler le segment de mémoire partagée « %s » en %zu octets : %m" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 storage/ipc/dsm_impl.c:750 storage/ipc/dsm_impl.c:987 +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "n'a pas pu mapper le segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:515 +#: storage/ipc/dsm_impl.c:576 #, c-format msgid "could not get shared memory segment: %m" msgstr "n'a pas pu obtenir le segment de mémoire partagée : %m" -#: storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:775 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "n'a pas pu créer le segment de mémoire partagée « %s » : %m" -#: storage/ipc/dsm_impl.c:1029 storage/ipc/dsm_impl.c:1077 +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 #, c-format msgid "could not duplicate handle for \"%s\": %m" msgstr "n'a pas pu dupliquer le lien pour « %s » : %m" -#: storage/ipc/latch.c:828 +#: storage/ipc/latch.c:829 #, c-format msgid "epoll_ctl() failed: %m" msgstr "échec de epoll_ctl() : %m" -#: storage/ipc/latch.c:1057 +#: storage/ipc/latch.c:1060 #, c-format msgid "epoll_wait() failed: %m" msgstr "échec de epoll_wait() : %m" -#: storage/ipc/latch.c:1179 +#: storage/ipc/latch.c:1182 #, c-format msgid "poll() failed: %m" msgstr "échec de poll() : %m" -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:190 storage/lmgr/lock.c:883 storage/lmgr/lock.c:917 storage/lmgr/lock.c:2679 storage/lmgr/lock.c:4004 storage/lmgr/lock.c:4069 storage/lmgr/lock.c:4361 storage/lmgr/predicate.c:2399 storage/lmgr/predicate.c:2414 storage/lmgr/predicate.c:3806 storage/lmgr/predicate.c:4949 utils/hash/dynahash.c:1061 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "mémoire partagée épuisée" @@ -18568,32 +19473,32 @@ msgstr "pas assez de mémoire partagée pour la structure de données « %s » ( msgid "requested shared memory size overflows size_t" msgstr "la taille de la mémoire partagée demandée dépasse size_t" -#: storage/ipc/standby.c:531 tcop/postgres.c:2985 +#: storage/ipc/standby.c:558 tcop/postgres.c:3056 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "annulation de la requête à cause d'un conflit avec la restauration" -#: storage/ipc/standby.c:532 tcop/postgres.c:2271 +#: storage/ipc/standby.c:559 tcop/postgres.c:2329 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "La transaction de l'utilisateur causait un verrou mortel lors de la restauration." -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:190 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "l'entrée du Large Object d'OID %u, en page %d, a une taille de champ de données invalide, %d" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:271 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "drapeaux invalides pour l'ouverture d'un « Large Object » : %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:461 #, c-format msgid "invalid whence setting: %d" msgstr "paramètrage de « whence » invalide : %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:633 #, c-format msgid "invalid large object write request size: %d" msgstr "taille de la requête d'écriture du « Large Object » invalide : %d" @@ -18618,243 +19523,231 @@ msgstr "Bloquage mortel détecté" msgid "See server log for query details." msgstr "Voir les journaux applicatifs du serveur pour les détails sur la requête." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:767 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "lors de la mise à jour de la ligne (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:770 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "lors de la suppression de la ligne (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:773 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "lors du verrouillage de la ligne (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:776 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "lors du verrou de la version mise à jour (%u, %u) de la ligne de la relation « %s »" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:779 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "lors de l'insertion de l'enregistrement (%u, %u) de l'index dans la relation « %s »" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:782 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "lors de la vérification de l'unicité de l'enregistrement (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:785 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "lors de la re-vérification de l'enregistrement mis à jour (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:788 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" msgstr "lors de la vérification de la contrainte d'exclusion sur l'enregistrement (%u,%u) dans la relation « %s »" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1008 #, c-format msgid "relation %u of database %u" msgstr "relation %u de la base de données %u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1014 #, c-format msgid "extension of relation %u of database %u" msgstr "extension de la relation %u de la base de données %u" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1020 #, c-format msgid "page %u of relation %u of database %u" msgstr "page %u de la relation %u de la base de données %u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1027 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "ligne (%u,%u) de la relation %u de la base de données %u" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1035 #, c-format msgid "transaction %u" msgstr "transaction %u" -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1040 #, c-format msgid "virtual transaction %d/%u" msgstr "transaction virtuelle %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1046 #, c-format msgid "speculative token %u of transaction %u" msgstr "jeton spéculatif %u de la transaction %u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1052 #, c-format msgid "object %u of class %u of database %u" msgstr "objet %u de la classe %u de la base de données %u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1060 #, c-format msgid "user lock [%u,%u,%u]" msgstr "verrou utilisateur [%u,%u,%u]" -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1067 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "verrou informatif [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1075 #, c-format msgid "unrecognized locktag type %d" msgstr "type locktag non reconnu %d" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:740 #, c-format msgid "cannot acquire lock mode %s on database objects while recovery is in progress" msgstr "" "ne peut pas acquérir le mode de verrou %s sur les objets de base de données\n" "alors que la restauration est en cours" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:742 #, c-format msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "" "Seuls RowExclusiveLock et les verrous inférieurs peuvent être acquis sur les\n" "objets d'une base pendant une restauration." -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2680 storage/lmgr/lock.c:4005 storage/lmgr/lock.c:4070 storage/lmgr/lock.c:4362 +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "Vous pourriez avoir besoin d'augmenter max_locks_per_transaction." -#: storage/lmgr/lock.c:3121 storage/lmgr/lock.c:3237 +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 #, c-format msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "ne peut pas utiliser PREPARE lorsque des verrous de niveau session et deniveau transaction sont détenus sur le même objet" -#: storage/lmgr/predicate.c:684 +#: storage/lmgr/predicate.c:682 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "pas assez d'éléments dans RWConflictPool pour enregistrer un conflit en lecture/écriture" -#: storage/lmgr/predicate.c:685 storage/lmgr/predicate.c:713 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "" "Il est possible que vous ayez à exécuter moins de transactions à la fois\n" "ou d'augmenter max_connections." -#: storage/lmgr/predicate.c:712 +#: storage/lmgr/predicate.c:710 #, c-format msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "pas assez d'éléments dans RWConflictPool pour enregistrer un conflit en lecture/écriture potentiel" -#: storage/lmgr/predicate.c:919 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "la mémoire pour tracer les conflits sérialisables est pratiquement pleine" - -#: storage/lmgr/predicate.c:920 -#, c-format -msgid "There might be an idle transaction or a forgotten prepared transaction causing this." -msgstr "" -"Il pourait y avoir une transaction en attente ou une transaction préparée\n" -"oubliée causant cela." - -#: storage/lmgr/predicate.c:1559 +#: storage/lmgr/predicate.c:1515 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "l'image déferrable est non sûre ; tentative avec une nouvelle image" -#: storage/lmgr/predicate.c:1648 +#: storage/lmgr/predicate.c:1604 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "« default_transaction_isolation » est configuré à « serializable »." -#: storage/lmgr/predicate.c:1649 +#: storage/lmgr/predicate.c:1605 #, c-format msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." msgstr "" "Vous pouvez utiliser « SET default_transaction_isolation = 'repeatable read' »\n" "pour modifier la valeur par défaut." -#: storage/lmgr/predicate.c:1689 +#: storage/lmgr/predicate.c:1645 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "une transaction important un snapshot ne doit pas être READ ONLY DEFERRABLE" -#: storage/lmgr/predicate.c:1769 utils/time/snapmgr.c:621 utils/time/snapmgr.c:627 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 utils/time/snapmgr.c:627 #, c-format msgid "could not import the requested snapshot" msgstr "n'a pas pu importer le snapshot demandé" -#: storage/lmgr/predicate.c:1770 utils/time/snapmgr.c:628 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The source process with pid %d is not running anymore." +msgid "The source process with PID %d is not running anymore." msgstr "Le processus source de PID %d n'est plus en cours d'exécution." -#: storage/lmgr/predicate.c:2400 storage/lmgr/predicate.c:2415 storage/lmgr/predicate.c:3807 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 storage/lmgr/predicate.c:3763 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "Vous pourriez avoir besoin d'augmenter max_pred_locks_per_transaction." -#: storage/lmgr/predicate.c:3961 storage/lmgr/predicate.c:4050 storage/lmgr/predicate.c:4058 storage/lmgr/predicate.c:4097 storage/lmgr/predicate.c:4336 storage/lmgr/predicate.c:4673 storage/lmgr/predicate.c:4685 storage/lmgr/predicate.c:4727 storage/lmgr/predicate.c:4765 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 storage/lmgr/predicate.c:4721 #, c-format msgid "could not serialize access due to read/write dependencies among transactions" msgstr "" "n'a pas pu sérialiser un accès à cause des dépendances de lecture/écriture\n" "parmi les transactions" -#: storage/lmgr/predicate.c:3963 storage/lmgr/predicate.c:4052 storage/lmgr/predicate.c:4060 storage/lmgr/predicate.c:4099 storage/lmgr/predicate.c:4338 storage/lmgr/predicate.c:4675 storage/lmgr/predicate.c:4687 storage/lmgr/predicate.c:4729 storage/lmgr/predicate.c:4767 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 storage/lmgr/predicate.c:4723 #, c-format msgid "The transaction might succeed if retried." msgstr "La transaction pourrait réussir après une nouvelle tentative." -#: storage/lmgr/proc.c:1300 +#: storage/lmgr/proc.c:1318 #, c-format msgid "Process %d waits for %s on %s." msgstr "Le processus %d attend %s sur %s." -#: storage/lmgr/proc.c:1311 +#: storage/lmgr/proc.c:1329 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "envoi de l'annulation pour bloquer le PID %d de l'autovacuum" -#: storage/lmgr/proc.c:1329 utils/adt/misc.c:269 +#: storage/lmgr/proc.c:1347 utils/adt/misc.c:270 #, c-format msgid "could not send signal to process %d: %m" msgstr "n'a pas pu envoyer le signal au processus %d : %m" -#: storage/lmgr/proc.c:1431 +#: storage/lmgr/proc.c:1449 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "" "le processus %d a évité un verrou mortel pour %s sur %s en modifiant l'ordre\n" "de la queue après %ld.%03d ms" -#: storage/lmgr/proc.c:1446 +#: storage/lmgr/proc.c:1464 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "" "le processus %d a détecté un verrou mortel alors qu'il était en attente de\n" "%s sur %s après %ld.%03d ms" -#: storage/lmgr/proc.c:1455 +#: storage/lmgr/proc.c:1473 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "le processus %d est toujours en attente de %s sur %s après %ld.%03d ms" -#: storage/lmgr/proc.c:1462 +#: storage/lmgr/proc.c:1480 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "le processus %d a acquis %s sur %s après %ld.%03d ms" -#: storage/lmgr/proc.c:1478 +#: storage/lmgr/proc.c:1496 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "le processus %d a échoué pour l'acquisition de %s sur %s après %ld.%03d ms" @@ -18864,27 +19757,27 @@ msgstr "le processus %d a échoué pour l'acquisition de %s sur %s après %ld.%0 msgid "page verification failed, calculated checksum %u but expected %u" msgstr "échec de la vérification de la page, somme de contrôle calculé %u, mais attendait %u" -#: storage/page/bufpage.c:213 storage/page/bufpage.c:505 storage/page/bufpage.c:748 storage/page/bufpage.c:881 storage/page/bufpage.c:977 storage/page/bufpage.c:1087 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 storage/page/bufpage.c:744 storage/page/bufpage.c:877 storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "pointeurs de page corrompus : le plus bas = %u, le plus haut = %u, spécial = %u" -#: storage/page/bufpage.c:549 +#: storage/page/bufpage.c:529 #, c-format msgid "corrupted item pointer: %u" msgstr "pointeur d'élément corrompu : %u" -#: storage/page/bufpage.c:560 storage/page/bufpage.c:932 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "longueurs d'élément corrompus : total %u, espace disponible %u" -#: storage/page/bufpage.c:767 storage/page/bufpage.c:993 storage/page/bufpage.c:1103 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 storage/page/bufpage.c:1099 #, c-format msgid "corrupted item pointer: offset = %u, size = %u" msgstr "pointeur d'élément corrompu : décalage = %u, taille = %u" -#: storage/page/bufpage.c:905 +#: storage/page/bufpage.c:901 #, c-format msgid "corrupted item pointer: offset = %u, length = %u" msgstr "pointeur d'élément corrompu : décalage = %u, longueur = %u" @@ -18955,205 +19848,205 @@ msgstr "n'a pas pu tronquer le fichier « %s » en %u blocs : il y a seulement % msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "n'a pas pu tronquer le fichier « %s » en %u blocs : %m" -#: storage/smgr/md.c:1282 +#: storage/smgr/md.c:1295 #, c-format msgid "could not fsync file \"%s\" but retrying: %m" msgstr "" "n'a pas pu synchroniser sur disque (fsync) le fichier « %s », nouvelle\n" "tentative : %m" -#: storage/smgr/md.c:1445 +#: storage/smgr/md.c:1458 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "n'a pas pu envoyer la requête fsync car la queue des requêtes est pleine" -#: storage/smgr/md.c:1914 +#: storage/smgr/md.c:1958 #, c-format msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" msgstr "n'a pas pu ouvrir le fichier « %s » (bloc cible %u) : le segment précédent ne fait que %u blocs" -#: storage/smgr/md.c:1928 +#: storage/smgr/md.c:1972 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "n'a pas pu ouvrir le fichier « %s » (bloc cible %u) : %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:463 tcop/fastpath.c:593 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" msgstr "taille de l'argument %d invalide dans le message d'appel de la fonction" -#: tcop/fastpath.c:309 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "appel de fonction fastpath : « %s » (OID %u)" -#: tcop/fastpath.c:391 tcop/postgres.c:1169 tcop/postgres.c:1432 tcop/postgres.c:1812 tcop/postgres.c:2030 +#: tcop/fastpath.c:389 tcop/postgres.c:1218 tcop/postgres.c:1482 tcop/postgres.c:1864 tcop/postgres.c:2085 #, c-format msgid "duration: %s ms" msgstr "durée : %s ms" -#: tcop/fastpath.c:395 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "durée : %s ms, appel de fonction fastpath : « %s » (OID %u)" -#: tcop/fastpath.c:431 tcop/fastpath.c:558 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "" "le message d'appel de la fonction contient %d arguments mais la fonction en\n" "requiert %d" -#: tcop/fastpath.c:439 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "" "le message d'appel de la fonction contient %d formats d'argument mais %d\n" " arguments" -#: tcop/fastpath.c:526 tcop/fastpath.c:609 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "format des données binaires incorrect dans l'argument de la fonction %d" -#: tcop/postgres.c:346 tcop/postgres.c:382 tcop/postgres.c:409 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "fin de fichier (EOF) inattendue de la connexion du client" -#: tcop/postgres.c:432 tcop/postgres.c:444 tcop/postgres.c:455 tcop/postgres.c:467 tcop/postgres.c:4316 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 tcop/postgres.c:480 tcop/postgres.c:4408 #, c-format msgid "invalid frontend message type %d" msgstr "type %d du message de l'interface invalide" -#: tcop/postgres.c:938 +#: tcop/postgres.c:973 #, c-format msgid "statement: %s" msgstr "instruction : %s" -#: tcop/postgres.c:1174 +#: tcop/postgres.c:1223 #, c-format msgid "duration: %s ms statement: %s" msgstr "durée : %s ms, instruction : %s" -#: tcop/postgres.c:1224 +#: tcop/postgres.c:1273 #, c-format msgid "parse %s: %s" msgstr "analyse %s : %s" -#: tcop/postgres.c:1280 +#: tcop/postgres.c:1330 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "ne peut pas insérer les commandes multiples dans une instruction préparée" -#: tcop/postgres.c:1437 +#: tcop/postgres.c:1487 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "durée : %s ms, analyse %s : %s" -#: tcop/postgres.c:1482 +#: tcop/postgres.c:1532 #, c-format msgid "bind %s to %s" msgstr "lie %s à %s" -#: tcop/postgres.c:1501 tcop/postgres.c:2320 +#: tcop/postgres.c:1551 tcop/postgres.c:2377 #, c-format msgid "unnamed prepared statement does not exist" msgstr "l'instruction préparée non nommée n'existe pas" -#: tcop/postgres.c:1543 +#: tcop/postgres.c:1594 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "le message bind a %d formats de paramètres mais %d paramètres" -#: tcop/postgres.c:1549 +#: tcop/postgres.c:1600 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "" "le message bind fournit %d paramètres, mais l'instruction préparée « %s » en\n" "requiert %d" -#: tcop/postgres.c:1719 +#: tcop/postgres.c:1771 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "format des données binaires incorrect dans le paramètre bind %d" -#: tcop/postgres.c:1817 +#: tcop/postgres.c:1869 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "durée : %s ms, lien %s%s%s : %s" -#: tcop/postgres.c:1865 tcop/postgres.c:2400 +#: tcop/postgres.c:1917 tcop/postgres.c:2461 #, c-format msgid "portal \"%s\" does not exist" msgstr "le portail « %s » n'existe pas" -#: tcop/postgres.c:1950 +#: tcop/postgres.c:2002 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1952 tcop/postgres.c:2038 +#: tcop/postgres.c:2004 tcop/postgres.c:2093 msgid "execute fetch from" msgstr "exécute fetch à partir de" -#: tcop/postgres.c:1953 tcop/postgres.c:2039 +#: tcop/postgres.c:2005 tcop/postgres.c:2094 msgid "execute" msgstr "exécute" -#: tcop/postgres.c:2035 +#: tcop/postgres.c:2090 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "durée : %s ms %s %s%s%s: %s" -#: tcop/postgres.c:2161 +#: tcop/postgres.c:2216 #, c-format msgid "prepare: %s" msgstr "préparation : %s" -#: tcop/postgres.c:2224 +#: tcop/postgres.c:2282 #, c-format msgid "parameters: %s" msgstr "paramètres : %s" -#: tcop/postgres.c:2243 +#: tcop/postgres.c:2301 #, c-format msgid "abort reason: recovery conflict" msgstr "raison de l'annulation : conflit de restauration" -#: tcop/postgres.c:2259 +#: tcop/postgres.c:2317 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "L'utilisateur conservait des blocs disques en mémoire partagée depuis trop longtemps." -#: tcop/postgres.c:2262 +#: tcop/postgres.c:2320 #, c-format msgid "User was holding a relation lock for too long." msgstr "L'utilisateur conservait un verrou sur une relation depuis trop longtemps." -#: tcop/postgres.c:2265 +#: tcop/postgres.c:2323 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "L'utilisateur utilisait ou pouvait utiliser un tablespace qui doit être supprimé." -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2326 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "" "La requête de l'utilisateur pourrait avoir eu besoin de voir des versions de\n" "lignes qui doivent être supprimées." -#: tcop/postgres.c:2274 +#: tcop/postgres.c:2332 #, c-format msgid "User was connected to a database that must be dropped." msgstr "L'utilisateur était connecté à une base de donnée qui doit être supprimé." -#: tcop/postgres.c:2583 +#: tcop/postgres.c:2657 #, c-format msgid "terminating connection because of crash of another server process" msgstr "arrêt de la connexion à cause de l'arrêt brutal d'un autre processus serveur" -#: tcop/postgres.c:2584 +#: tcop/postgres.c:2658 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "" @@ -19161,19 +20054,19 @@ msgstr "" "courante et de quitter car un autre processus serveur a quitté anormalement\n" "et qu'il existe probablement de la mémoire partagée corrompue." -#: tcop/postgres.c:2588 tcop/postgres.c:2913 +#: tcop/postgres.c:2662 tcop/postgres.c:2986 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "" "Dans un moment, vous devriez être capable de vous reconnecter à la base de\n" "données et de relancer votre commande." -#: tcop/postgres.c:2674 +#: tcop/postgres.c:2744 #, c-format msgid "floating-point exception" msgstr "exception dû à une virgule flottante" -#: tcop/postgres.c:2675 +#: tcop/postgres.c:2745 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "" @@ -19181,73 +20074,72 @@ msgstr "" "Ceci signifie probablement un résultat en dehors de l'échelle ou une\n" "opération invalide telle qu'une division par zéro." -#: tcop/postgres.c:2843 +#: tcop/postgres.c:2916 #, c-format msgid "canceling authentication due to timeout" msgstr "annulation de l'authentification à cause du délai écoulé" -#: tcop/postgres.c:2847 +#: tcop/postgres.c:2920 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "arrêt du processus autovacuum suite à la demande de l'administrateur" -#: tcop/postgres.c:2851 -#, fuzzy, c-format -#| msgid "terminating connection due to administrator command" +#: tcop/postgres.c:2924 +#, c-format msgid "terminating logical replication worker due to administrator command" -msgstr "arrêt des connexions suite à la demande de l'administrateur" +msgstr "arrêt des processus workers de réplication logique suite à la demande de l'administrateur" -#: tcop/postgres.c:2855 +#: tcop/postgres.c:2928 #, c-format msgid "logical replication launcher shutting down" msgstr "arrêt du processus de lancement de la réplication logique" -#: tcop/postgres.c:2868 tcop/postgres.c:2878 tcop/postgres.c:2911 +#: tcop/postgres.c:2941 tcop/postgres.c:2951 tcop/postgres.c:2984 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "arrêt de la connexion à cause d'un conflit avec la restauration" -#: tcop/postgres.c:2884 +#: tcop/postgres.c:2957 #, c-format msgid "terminating connection due to administrator command" msgstr "arrêt des connexions suite à la demande de l'administrateur" -#: tcop/postgres.c:2894 +#: tcop/postgres.c:2967 #, c-format msgid "connection to client lost" msgstr "connexion au client perdue" -#: tcop/postgres.c:2962 +#: tcop/postgres.c:3033 #, c-format msgid "canceling statement due to lock timeout" msgstr "annulation de la requête à cause du délai écoulé pour l'obtention des verrous" -#: tcop/postgres.c:2969 +#: tcop/postgres.c:3040 #, c-format msgid "canceling statement due to statement timeout" msgstr "annulation de la requête à cause du délai écoulé pour l'exécution de l'instruction" -#: tcop/postgres.c:2976 +#: tcop/postgres.c:3047 #, c-format msgid "canceling autovacuum task" msgstr "annulation de la tâche d'autovacuum" -#: tcop/postgres.c:2999 +#: tcop/postgres.c:3070 #, c-format msgid "canceling statement due to user request" msgstr "annulation de la requête à la demande de l'utilisateur" -#: tcop/postgres.c:3009 +#: tcop/postgres.c:3080 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "arrêt des connexions suite à l'expiration du délai d'inactivité en transaction" -#: tcop/postgres.c:3123 +#: tcop/postgres.c:3194 #, c-format msgid "stack depth limit exceeded" msgstr "dépassement de limite (en profondeur) de la pile" -#: tcop/postgres.c:3124 +#: tcop/postgres.c:3195 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "" @@ -19255,59 +20147,59 @@ msgstr "" "être assuré que la limite de profondeur de la pile de la plateforme est\n" "adéquate." -#: tcop/postgres.c:3187 +#: tcop/postgres.c:3258 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "« max_stack_depth » ne doit pas dépasser %ld Ko." -#: tcop/postgres.c:3189 +#: tcop/postgres.c:3260 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "" "Augmenter la limite de profondeur de la pile sur votre plateforme via\n" "« ulimit -s » ou l'équivalent local." -#: tcop/postgres.c:3549 +#: tcop/postgres.c:3620 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "argument invalide en ligne de commande pour le processus serveur : %s" -#: tcop/postgres.c:3550 tcop/postgres.c:3556 +#: tcop/postgres.c:3621 tcop/postgres.c:3627 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Essayez « %s --help » pour plus d'informations." -#: tcop/postgres.c:3554 +#: tcop/postgres.c:3625 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s : argument invalide en ligne de commande : %s" -#: tcop/postgres.c:3616 +#: tcop/postgres.c:3687 #, c-format msgid "%s: no database nor user name specified" msgstr "%s : aucune base de données et aucun utilisateur spécifiés" -#: tcop/postgres.c:4224 +#: tcop/postgres.c:4316 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "sous-type %d du message CLOSE invalide" -#: tcop/postgres.c:4259 +#: tcop/postgres.c:4351 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "sous-type %d du message DESCRIBE invalide" -#: tcop/postgres.c:4337 +#: tcop/postgres.c:4429 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "appels à la fonction fastpath non supportés dans une connexion de réplication" -#: tcop/postgres.c:4341 +#: tcop/postgres.c:4433 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "protocole étendu de requêtes non supporté dans une connexion de réplication" -#: tcop/postgres.c:4511 +#: tcop/postgres.c:4610 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "" @@ -19330,36 +20222,46 @@ msgid "Declare it with SCROLL option to enable backward scan." msgstr "Déclarez-le avec l'option SCROLL pour activer le parcours inverse." #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:242 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "ne peut pas exécuter %s dans une transaction en lecture seule" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:260 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "ne peut pas exécuté %s lors d'une opération parallèle" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:279 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "ne peut pas exécuté %s lors de la restauration" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:297 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "" "ne peut pas exécuter %s à l'intérieur d'une fonction restreinte\n" "pour sécurité" -#: tcop/utility.c:765 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" msgstr "doit être super-utilisateur pour exécuter un point de vérification (CHECKPOINT)" +#: tcop/utility.c:1341 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "ne peut pas créer un index sur la table partitionnée « %s »" + +#: tcop/utility.c:1343 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "La table « %s » contient des partitionso qui ne sont pas des tables distantes." + #: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" @@ -19509,17 +20411,17 @@ msgstr "drapeau d'affixe invalide « %s » avec la valeur de drapeau « long »" msgid "could not open dictionary file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier dictionnaire « %s » : %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "expression rationnelle invalide : %s" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format msgid "invalid affix alias \"%s\"" msgstr "alias d'affixe invalide « %s »" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier affixe « %s » : %m" @@ -19534,7 +20436,12 @@ msgstr "le dictionnaire Ispell supporte seulement les valeurs de drapeau « defa msgid "invalid number of flag vector aliases" msgstr "nombre d'alias de vecteur de drapeau invalide" -#: tsearch/spell.c:1542 +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "le nombre d'alias excède le nombre %d spécifié" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "le fichier d'affixes contient des commandes ancien et nouveau style" @@ -19544,12 +20451,12 @@ msgstr "le fichier d'affixes contient des commandes ancien et nouveau style" msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "la chaîne est trop longue (%d octets, max %d octets)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "ligne %d du fichier de configuration « %s » : « %s »" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "échec de l'encodage de wchar_t vers l'encodage du serveur : %m" @@ -19579,423 +20486,428 @@ msgstr "n'a pas pu ouvrir le fichier des termes courants « %s » : %m" msgid "text search parser does not support headline creation" msgstr "l'analyseur de recherche plein texte ne supporte pas headline" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "paramètre headline « %s » non reconnu" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "MinWords doit avoir une valeur plus petite que celle de MaxWords" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "MinWords doit être positif" -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "ShortWord devrait être positif ou nul" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "MaxFragments devrait être positif ou nul" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format msgid "identifier too long" msgstr "identifiant trop long" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format msgid "Identifier must be less than %d characters." msgstr "L'identifiant doit faire moins de %d caractères." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "mot clé non reconnu : « %s »" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "le mot clé ACL doit être soit « group » soit « user »." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "nom manquant" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "Un nom doit suivre le mot clé « group » ou « user »." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "signe « = » manquant" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "mode caractère invalide : doit faire partie de « %s »" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "un nom doit suivre le signe « / »" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "par défaut, le « donneur de droits » devient l'utilisateur d'identifiant %u" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "le tableau ACL contient un type de données incorrect" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "les tableaux d'ACL doivent avoir une dimension" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "les tableaux d'ACL ne doivent pas contenir de valeurs NULL" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "données superflues à la fin de la spécification de l'ACL" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1213 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "les options grant ne peuvent pas être rendues à votre propre donateur" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1274 #, c-format msgid "dependent privileges exist" msgstr "des privilèges dépendants existent" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1275 #, c-format msgid "Use CASCADE to revoke them too." msgstr "Utilisez CASCADE pour les révoquer aussi." -#: utils/adt/acl.c:1520 +#: utils/adt/acl.c:1537 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert n'est plus supporté" -#: utils/adt/acl.c:1530 +#: utils/adt/acl.c:1547 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove n'est plus supporté" -#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "type de droit non reconnu : « %s »" -#: utils/adt/acl.c:3410 utils/adt/regproc.c:102 utils/adt/regproc.c:277 +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "la fonction « %s » n'existe pas" -#: utils/adt/acl.c:4864 +#: utils/adt/acl.c:4959 #, c-format msgid "must be member of role \"%s\"" msgstr "doit être un membre du rôle « %s »" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5846 utils/adt/arrayfuncs.c:6157 utils/adt/arrayutils.c:93 utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "la taille du tableau dépasse le maximum permis (%d)" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:471 utils/adt/array_userfuncs.c:551 utils/adt/json.c:1764 utils/adt/json.c:1859 utils/adt/json.c:1897 utils/adt/jsonb.c:1127 utils/adt/jsonb.c:1156 utils/adt/jsonb.c:1592 utils/adt/jsonb.c:1756 utils/adt/jsonb.c:1766 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format msgid "could not determine input data type" msgstr "n'a pas pu déterminer le type de données date en entrée" -#: utils/adt/array_userfuncs.c:84 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "le type de données en entrée n'est pas un tableau" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:608 utils/adt/int.c:637 utils/adt/int.c:658 utils/adt/int.c:689 utils/adt/int.c:722 utils/adt/int.c:744 utils/adt/int.c:892 utils/adt/int.c:913 utils/adt/int.c:940 utils/adt/int.c:980 utils/adt/int.c:1001 utils/adt/int.c:1028 -#: utils/adt/int.c:1061 utils/adt/int.c:1144 utils/adt/int8.c:1298 utils/adt/numeric.c:2953 utils/adt/numeric.c:2962 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 utils/adt/varlena.c:1054 utils/adt/varlena.c:2953 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1376 utils/adt/float.c:1464 utils/adt/float.c:3765 utils/adt/float.c:3779 utils/adt/int.c:755 utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 utils/adt/int.c:1049 utils/adt/int.c:1063 +#: utils/adt/int.c:1094 utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format msgid "integer out of range" msgstr "entier en dehors des limites" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "l'argument doit être vide ou doit être un tableau à une dimension" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 utils/adt/array_userfuncs.c:411 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "ne peut pas concaténer des tableaux non compatibles" -#: utils/adt/array_userfuncs.c:279 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "" "Les tableaux avec les types d'élément %s et %s ne sont pas compatibles\n" "pour la concaténation." -#: utils/adt/array_userfuncs.c:318 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "" "Les tableaux de dimensions %d et %d ne sont pas compatiblee pour la\n" "concaténation." -#: utils/adt/array_userfuncs.c:355 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "" "Les tableaux de dimensions différentes ne sont pas compatibles pour\n" "une concaténation." -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "" "Les tableaux de dimensions différentes ne sont pas compatibles pour\n" "une concaténation." -#: utils/adt/array_userfuncs.c:667 utils/adt/array_userfuncs.c:819 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "la recherche d'éléments dans des tableaux multidimensionnels n'est pas supportée" -#: utils/adt/array_userfuncs.c:691 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "la position initiale ne doit pas être NULL" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" msgstr "tableau litéral mal formé : « %s »" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "« [ » doit introduire les dimensions explicites du tableau" -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "Valeur manquante de la dimension du tableau." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "« %s » manquant après les dimensions du tableau." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "la limite supérieure ne peut pas être plus petite que la limite inférieure" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "" -"La valeur du tableau doit commencer avec « { » ou avec l'information de la\n" +"La valeur du tableau doit commencer par « { » ou avec l'information de la\n" "dimension." -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." -msgstr "Le contenu du tableau doit commencer avec « { »." +msgstr "Le contenu du tableau doit commencer par « { »." -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "Les dimensions spécifiées du tableau ne correspondent pas au contenu du tableau." -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 utils/adt/rangetypes.c:2114 utils/adt/rangetypes.c:2122 utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format msgid "Unexpected end of input." msgstr "Fin de l'entrée inattendue." -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "Caractère « %c » inattendu." -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "Élément de tableau inattendu." -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "Caractère « %c » sans correspondance." -#: utils/adt/arrayfuncs.c:597 utils/adt/jsonfuncs.c:2381 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "" "Les tableaux multidimensionnels doivent avoir des sous-tableaux\n" "avec les dimensions correspondantes" -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "Problème après la parenthèse droite fermante." -#: utils/adt/arrayfuncs.c:1284 utils/adt/arrayfuncs.c:3357 utils/adt/arrayfuncs.c:5752 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 utils/adt/arrayfuncs.c:5816 #, c-format msgid "invalid number of dimensions: %d" msgstr "nombre de dimensions invalides : %d" -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" msgstr "drapeaux de tableau invalides" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "mauvais type d'élément" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 utils/cache/lsyscache.c:2683 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "aucune fonction d'entrée binaire disponible pour le type %s" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "format binaire mal conçu dans l'élément du tableau %d" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 utils/cache/lsyscache.c:2716 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "aucune fonction de sortie binaire disponible pour le type %s" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "les morceaux des tableaux à longueur fixe ne sont pas implémentés" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5738 utils/adt/arrayfuncs.c:5764 utils/adt/arrayfuncs.c:5775 utils/adt/json.c:2295 utils/adt/json.c:2370 utils/adt/jsonb.c:1370 utils/adt/jsonb.c:1456 utils/adt/jsonfuncs.c:4141 utils/adt/jsonfuncs.c:4292 utils/adt/jsonfuncs.c:4337 utils/adt/jsonfuncs.c:4384 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "mauvais nombre d'indices du tableau" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "indice du tableau en dehors de l'échelle" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "ne peut pas affecter une valeur NULL à un élément d'un tableau à longueur fixe" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "" "les mises à jour de morceaux des tableaux à longueur fixe ne sont pas\n" "implémentées" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format msgid "array slice subscript must provide both boundaries" msgstr "la tranche d'indice de tableau doit être fournir les deux limites" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "Les limites de tranches doivent être entièrement spécifiées lors de l'assignation d'une valeur d'un tableau vide à une tranche" -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "tableau source trop petit" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "élément NULL de tableau interdit dans ce contexte" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 utils/adt/arrayfuncs.c:4124 #, c-format msgid "cannot compare arrays of different element types" msgstr "ne peut pas comparer des tableaux ayant des types d'éléments différents" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 utils/adt/rangetypes.c:1317 #, c-format msgid "could not identify a hash function for type %s" msgstr "n'a pas pu identifier une fonction de hachage pour le type %s" -#: utils/adt/arrayfuncs.c:5152 +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "n'a pas pu identifier une fonction de hachage étendue pour le type %s" + +#: utils/adt/arrayfuncs.c:5216 #, c-format msgid "data type %s is not an array type" msgstr "le type de données %s n'est pas un type tableau" -#: utils/adt/arrayfuncs.c:5207 +#: utils/adt/arrayfuncs.c:5271 #, c-format msgid "cannot accumulate null arrays" msgstr "ne peut pas accumuler des tableaux NULL" -#: utils/adt/arrayfuncs.c:5235 +#: utils/adt/arrayfuncs.c:5299 #, c-format msgid "cannot accumulate empty arrays" msgstr "ne peut pas concaténer des tableaux vides" -#: utils/adt/arrayfuncs.c:5264 utils/adt/arrayfuncs.c:5270 +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "ne peut pas accumuler des tableaux de dimensions différentes" -#: utils/adt/arrayfuncs.c:5636 utils/adt/arrayfuncs.c:5676 +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "la dimension ou la limite basse du tableau ne peut pas être NULL" -#: utils/adt/arrayfuncs.c:5739 utils/adt/arrayfuncs.c:5765 +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 #, c-format msgid "Dimension array must be one dimensional." msgstr "le tableau doit avoir une seule dimension" -#: utils/adt/arrayfuncs.c:5744 utils/adt/arrayfuncs.c:5770 +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 #, c-format msgid "dimension values cannot be null" msgstr "les valeurs de dimension ne peuvent pas être NULL" -#: utils/adt/arrayfuncs.c:5776 +#: utils/adt/arrayfuncs.c:5840 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "La limite basse du tableau a une taille différentes des dimensions du tableau." -#: utils/adt/arrayfuncs.c:6022 +#: utils/adt/arrayfuncs.c:6086 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "la suppression d'éléments de tableaux multidimensionnels n'est pas supportée" -#: utils/adt/arrayfuncs.c:6299 +#: utils/adt/arrayfuncs.c:6363 #, c-format msgid "thresholds must be one-dimensional array" msgstr "les limites doivent être un tableau à une dimension" -#: utils/adt/arrayfuncs.c:6304 +#: utils/adt/arrayfuncs.c:6368 #, c-format msgid "thresholds array must not contain NULLs" msgstr "le tableau de limites ne doit pas contenir de valeurs NULL" @@ -20021,20 +20933,20 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "la conversion de l'encodage de %s vers l'ASCII n'est pas supportée" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:153 utils/adt/cash.c:278 utils/adt/datetime.c:3799 utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 utils/adt/float.c:461 utils/adt/float.c:544 utils/adt/float.c:570 utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 utils/adt/geo_ops.c:178 utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 utils/adt/geo_ops.c:265 utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 utils/adt/geo_ops.c:1356 utils/adt/geo_ops.c:1364 -#: utils/adt/geo_ops.c:3430 utils/adt/geo_ops.c:4563 utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 utils/adt/mac.c:94 utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1539 utils/adt/network.c:58 utils/adt/numeric.c:593 utils/adt/numeric.c:620 utils/adt/numeric.c:5488 utils/adt/numeric.c:5512 utils/adt/numeric.c:5536 utils/adt/numeric.c:6338 -#: utils/adt/numeric.c:6364 utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 utils/adt/uuid.c:136 +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 utils/adt/geo_ops.c:1363 +#: utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1542 utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 utils/adt/numeric.c:6516 +#: utils/adt/numeric.c:6542 utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 utils/adt/uuid.c:136 #, c-format msgid "invalid input syntax for type %s: \"%s\"" msgstr "syntaxe en entrée invalide pour le type %s : « %s »" -#: utils/adt/cash.c:211 utils/adt/cash.c:238 utils/adt/cash.c:249 utils/adt/cash.c:292 utils/adt/int8.c:114 utils/adt/numutils.c:75 utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format msgid "value \"%s\" is out of range for type %s" msgstr "la valeur « %s » est en dehors des limites pour le type %s" -#: utils/adt/cash.c:653 utils/adt/cash.c:703 utils/adt/cash.c:754 utils/adt/cash.c:803 utils/adt/cash.c:855 utils/adt/cash.c:905 utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:704 utils/adt/int.c:846 utils/adt/int.c:954 utils/adt/int.c:1043 utils/adt/int.c:1082 utils/adt/int.c:1110 utils/adt/int8.c:597 utils/adt/int8.c:657 utils/adt/int8.c:897 -#: utils/adt/int8.c:1005 utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6902 utils/adt/numeric.c:7191 utils/adt/numeric.c:8203 utils/adt/timestamp.c:3216 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3526 utils/adt/float.c:3589 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 utils/adt/int8.c:650 utils/adt/int8.c:850 +#: utils/adt/int8.c:930 utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3238 #, c-format msgid "division by zero" msgstr "division par zéro" @@ -20044,130 +20956,135 @@ msgstr "division par zéro" msgid "\"char\" out of range" msgstr "« char » hors des limites" -#: utils/adt/date.c:67 utils/adt/timestamp.c:95 utils/adt/varbit.c:53 utils/adt/varchar.c:46 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 utils/adt/varchar.c:46 #, c-format msgid "invalid type modifier" msgstr "modifieur de type invalide" -#: utils/adt/date.c:79 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "la précision de TIME(%d)%s ne doit pas être négative" -#: utils/adt/date.c:85 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "la précision de TIME(%d)%s a été réduit au maximum autorisée, %d" -#: utils/adt/date.c:146 utils/adt/datetime.c:1209 utils/adt/datetime.c:2117 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "la valeur « current » pour la date et heure n'est plus supportée" -#: utils/adt/date.c:172 utils/adt/date.c:180 utils/adt/formatting.c:3585 utils/adt/formatting.c:3594 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 utils/adt/formatting.c:3615 #, c-format msgid "date out of range: \"%s\"" msgstr "date en dehors des limites : « %s »" -#: utils/adt/date.c:227 utils/adt/date.c:539 utils/adt/date.c:563 utils/adt/xml.c:2089 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 utils/adt/xml.c:2197 #, c-format msgid "date out of range" msgstr "date en dehors des limites" -#: utils/adt/date.c:273 utils/adt/timestamp.c:564 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "valeur du champ date en dehors des limites : %d-%02d-%02d" -#: utils/adt/date.c:280 utils/adt/date.c:289 utils/adt/timestamp.c:570 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "date en dehors des limites : %d-%02d-%02d" -#: utils/adt/date.c:327 utils/adt/date.c:350 utils/adt/date.c:376 utils/adt/date.c:1092 utils/adt/date.c:1138 utils/adt/date.c:1672 utils/adt/date.c:1703 utils/adt/date.c:1732 utils/adt/date.c:2469 utils/adt/datetime.c:1690 utils/adt/formatting.c:3460 utils/adt/formatting.c:3492 utils/adt/formatting.c:3560 utils/adt/json.c:1539 utils/adt/json.c:1561 utils/adt/jsonb.c:824 utils/adt/jsonb.c:848 utils/adt/nabstime.c:456 utils/adt/nabstime.c:499 -#: utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 utils/adt/timestamp.c:2795 utils/adt/timestamp.c:2816 utils/adt/timestamp.c:2829 utils/adt/timestamp.c:2838 utils/adt/timestamp.c:2846 utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2924 utils/adt/timestamp.c:2937 -#: utils/adt/timestamp.c:2948 utils/adt/timestamp.c:2956 utils/adt/timestamp.c:3512 utils/adt/timestamp.c:3637 utils/adt/timestamp.c:3678 utils/adt/timestamp.c:3759 utils/adt/timestamp.c:3805 utils/adt/timestamp.c:3908 utils/adt/timestamp.c:4307 utils/adt/timestamp.c:4406 utils/adt/timestamp.c:4416 utils/adt/timestamp.c:4508 utils/adt/timestamp.c:4610 utils/adt/timestamp.c:4620 utils/adt/timestamp.c:4852 utils/adt/timestamp.c:4866 -#: utils/adt/timestamp.c:4871 utils/adt/timestamp.c:4885 utils/adt/timestamp.c:4930 utils/adt/timestamp.c:4962 utils/adt/timestamp.c:4969 utils/adt/timestamp.c:5002 utils/adt/timestamp.c:5006 utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5079 utils/adt/timestamp.c:5093 utils/adt/timestamp.c:5127 utils/adt/xml.c:2111 utils/adt/xml.c:2118 utils/adt/xml.c:2138 utils/adt/xml.c:2145 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:459 utils/adt/nabstime.c:502 utils/adt/nabstime.c:532 +#: utils/adt/nabstime.c:575 utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 utils/adt/timestamp.c:2817 utils/adt/timestamp.c:2838 utils/adt/timestamp.c:2851 utils/adt/timestamp.c:2860 utils/adt/timestamp.c:2868 utils/adt/timestamp.c:2923 utils/adt/timestamp.c:2946 utils/adt/timestamp.c:2959 utils/adt/timestamp.c:2970 +#: utils/adt/timestamp.c:2978 utils/adt/timestamp.c:3638 utils/adt/timestamp.c:3763 utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3894 utils/adt/timestamp.c:3940 utils/adt/timestamp.c:4043 utils/adt/timestamp.c:4450 utils/adt/timestamp.c:4549 utils/adt/timestamp.c:4559 utils/adt/timestamp.c:4651 utils/adt/timestamp.c:4753 utils/adt/timestamp.c:4763 utils/adt/timestamp.c:4995 utils/adt/timestamp.c:5009 utils/adt/timestamp.c:5014 +#: utils/adt/timestamp.c:5028 utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5105 utils/adt/timestamp.c:5112 utils/adt/timestamp.c:5145 utils/adt/timestamp.c:5149 utils/adt/timestamp.c:5218 utils/adt/timestamp.c:5222 utils/adt/timestamp.c:5236 utils/adt/timestamp.c:5270 utils/adt/xml.c:2219 utils/adt/xml.c:2226 utils/adt/xml.c:2246 utils/adt/xml.c:2253 #, c-format msgid "timestamp out of range" msgstr "timestamp en dehors des limites" -#: utils/adt/date.c:514 +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "ne peut pas soustraire les valeurs dates infinies" -#: utils/adt/date.c:592 utils/adt/date.c:623 utils/adt/date.c:641 utils/adt/date.c:2506 utils/adt/date.c:2516 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format msgid "date out of range for timestamp" msgstr "date en dehors des limites pour un timestamp" -#: utils/adt/date.c:1164 +#: utils/adt/date.c:1190 #, c-format msgid "cannot convert reserved abstime value to date" msgstr "ne peut pas convertir la valeur réservée abstime en date" -#: utils/adt/date.c:1182 utils/adt/date.c:1188 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 #, c-format msgid "abstime out of range for date" msgstr "abstime en dehors des limites pour une date" -#: utils/adt/date.c:1301 utils/adt/date.c:2020 +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format msgid "time out of range" msgstr "heure en dehors des limites" -#: utils/adt/date.c:1357 utils/adt/timestamp.c:589 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "valeur du champ time en dehors des limites : %d:%02d:%02g" -#: utils/adt/date.c:1907 utils/adt/date.c:1920 +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 utils/adt/timestamp.c:3287 utils/adt/timestamp.c:3318 utils/adt/timestamp.c:3349 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "taille précédente ou suivante invalide dans la fonction de fenêtrage" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "l'unité « %s » n'est pas reconnu pour le type « time »" -#: utils/adt/date.c:2028 +#: utils/adt/date.c:2099 #, c-format msgid "time zone displacement out of range" msgstr "déplacement du fuseau horaire en dehors des limites" -#: utils/adt/date.c:2601 utils/adt/date.c:2614 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "L'unité « %s » n'est pas reconnu pour le type « time with time zone »" -#: utils/adt/date.c:2687 utils/adt/datetime.c:931 utils/adt/datetime.c:1848 utils/adt/datetime.c:4636 utils/adt/timestamp.c:503 utils/adt/timestamp.c:530 utils/adt/timestamp.c:4877 utils/adt/timestamp.c:5085 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 utils/adt/timestamp.c:530 utils/adt/timestamp.c:5020 utils/adt/timestamp.c:5228 #, c-format msgid "time zone \"%s\" not recognized" msgstr "le fuseau horaire « %s » n'est pas reconnu" -#: utils/adt/date.c:2719 utils/adt/timestamp.c:4919 utils/adt/timestamp.c:5116 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5062 utils/adt/timestamp.c:5259 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "l'intervalle de fuseau horaire « %s » ne doit pas spécifier de mois ou de jours" -#: utils/adt/datetime.c:3772 utils/adt/datetime.c:3779 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "valeur du champ date/time en dehors des limites : « %s »" -#: utils/adt/datetime.c:3781 +#: utils/adt/datetime.c:3770 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "Peut-être avez-vous besoin d'un paramètrage « datestyle » différent." -#: utils/adt/datetime.c:3786 +#: utils/adt/datetime.c:3775 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "valeur du champ interval en dehors des limites : « %s »" -#: utils/adt/datetime.c:3792 +#: utils/adt/datetime.c:3781 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "déplacement du fuseau horaire en dehors des limites : « %s »" -#: utils/adt/datetime.c:4638 +#: utils/adt/datetime.c:4627 #, c-format msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "Ce nom du fuseau horaire apparaît dans le fichier de configuration des abréviations de fuseaux horaires « %s »." @@ -20177,27 +21094,22 @@ msgstr "Ce nom du fuseau horaire apparaît dans le fichier de configuration des msgid "invalid Datum pointer" msgstr "pointeur Datum invalide" -#: utils/adt/dbsize.c:116 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "n'a pas pu ouvrir le répertoire du tablespace « %s » : %m" - -#: utils/adt/dbsize.c:764 utils/adt/dbsize.c:832 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format msgid "invalid size: \"%s\"" msgstr "taille invalide : « %s »" -#: utils/adt/dbsize.c:833 +#: utils/adt/dbsize.c:828 #, c-format msgid "Invalid size unit: \"%s\"." msgstr "Unité invalide pour une taille : « %s »." -#: utils/adt/dbsize.c:834 +#: utils/adt/dbsize.c:829 #, c-format msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "Les unités valides pour ce paramètre sont « bytes », « kB », « MB », « GB » et « TB »." -#: utils/adt/domains.c:91 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "le type %s n'est pas un domaine" @@ -20237,659 +21149,684 @@ msgstr "séquence base64 de fin invalide" msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "Les données en entrée manquent un alignement, sont tronquées ou ont une corruption autre." -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:785 utils/adt/json.c:825 utils/adt/json.c:841 utils/adt/json.c:853 utils/adt/json.c:863 utils/adt/json.c:914 utils/adt/json.c:946 utils/adt/json.c:965 utils/adt/json.c:977 utils/adt/json.c:989 utils/adt/json.c:1134 utils/adt/json.c:1148 utils/adt/json.c:1159 utils/adt/json.c:1167 utils/adt/json.c:1175 utils/adt/json.c:1183 utils/adt/json.c:1191 utils/adt/json.c:1199 -#: utils/adt/json.c:1207 utils/adt/json.c:1215 utils/adt/json.c:1245 utils/adt/varlena.c:296 utils/adt/varlena.c:337 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 utils/adt/json.c:1192 utils/adt/json.c:1200 +#: utils/adt/json.c:1208 utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 utils/adt/varlena.c:337 #, c-format msgid "invalid input syntax for type %s" msgstr "syntaxe en entrée invalide pour le type %s" -#: utils/adt/enum.c:115 -#, c-format -msgid "unsafe use of new value \"%s\" of enum type %s" -msgstr "" - -#: utils/adt/enum.c:118 -#, c-format -msgid "New enum values must be committed before they can be used." -msgstr "Les nouvelles valeurs enum doivent être validées (COMMIT) avant de pouvoir être utilisées." - -#: utils/adt/enum.c:136 utils/adt/enum.c:146 utils/adt/enum.c:204 utils/adt/enum.c:214 +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 utils/adt/enum.c:123 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "valeur en entrée invalide pour le enum %s : « %s »" -#: utils/adt/enum.c:176 utils/adt/enum.c:242 utils/adt/enum.c:301 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format msgid "invalid internal value for enum: %u" msgstr "valeur interne invalide pour le enum : %u" -#: utils/adt/enum.c:461 utils/adt/enum.c:490 utils/adt/enum.c:530 utils/adt/enum.c:550 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 utils/adt/enum.c:449 #, c-format msgid "could not determine actual enum type" msgstr "n'a pas pu déterminer le type enum actuel" -#: utils/adt/enum.c:469 utils/adt/enum.c:498 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format msgid "enum %s contains no values" msgstr "l'énumération « %s » ne contient aucune valeur" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "le type %s n'est pas un type composite" + +#: utils/adt/float.c:55 #, c-format msgid "value out of range: overflow" msgstr "valeur en dehors des limites : dépassement" -#: utils/adt/float.c:63 +#: utils/adt/float.c:60 #, c-format msgid "value out of range: underflow" msgstr "valeur en dehors des limites : trop petit" -#: utils/adt/float.c:312 +#: utils/adt/float.c:309 #, c-format msgid "\"%s\" is out of range for type real" msgstr "« %s » est hors des limites du type real" -#: utils/adt/float.c:537 +#: utils/adt/float.c:534 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "« %s » est en dehors des limites du type double precision" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:334 utils/adt/int.c:760 utils/adt/int.c:789 utils/adt/int.c:810 utils/adt/int.c:830 utils/adt/int.c:864 utils/adt/int.c:1159 utils/adt/int8.c:1323 utils/adt/numeric.c:3050 utils/adt/numeric.c:3059 +#: utils/adt/float.c:1408 utils/adt/float.c:1496 utils/adt/int.c:332 utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format msgid "smallint out of range" msgstr "smallint en dehors des limites" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7624 +#: utils/adt/float.c:1622 utils/adt/numeric.c:7802 #, c-format msgid "cannot take square root of a negative number" msgstr "ne peut pas calculer la racine carré d'un nombre négatif" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2853 +#: utils/adt/float.c:1683 utils/adt/numeric.c:3017 #, c-format msgid "zero raised to a negative power is undefined" msgstr "zéro à une puissance négative est indéfini" -#: utils/adt/float.c:1476 utils/adt/numeric.c:2859 +#: utils/adt/float.c:1687 utils/adt/numeric.c:3023 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "un nombre négatif élevé à une puissance non entière donne un résultat complexe" -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7890 +#: utils/adt/float.c:1753 utils/adt/float.c:1783 utils/adt/numeric.c:8068 #, c-format msgid "cannot take logarithm of zero" msgstr "ne peut pas calculer le logarithme de zéro" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7894 +#: utils/adt/float.c:1757 utils/adt/float.c:1787 utils/adt/numeric.c:8072 #, c-format msgid "cannot take logarithm of a negative number" msgstr "ne peut pas calculer le logarithme sur un nombre négatif" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: utils/adt/float.c:1817 utils/adt/float.c:1847 utils/adt/float.c:1939 utils/adt/float.c:1965 utils/adt/float.c:1992 utils/adt/float.c:2018 utils/adt/float.c:2165 utils/adt/float.c:2200 utils/adt/float.c:2364 utils/adt/float.c:2418 utils/adt/float.c:2482 utils/adt/float.c:2537 #, c-format msgid "input is out of range" msgstr "l'entrée est en dehors des limites" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1493 +#: utils/adt/float.c:3743 utils/adt/numeric.c:1504 #, c-format msgid "count must be greater than zero" msgstr "le total doit être supérieur à zéro" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1500 +#: utils/adt/float.c:3748 utils/adt/numeric.c:1511 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "la limite inférieure et supérieure de l'opérande ne peuvent pas être NaN" -#: utils/adt/float.c:3543 +#: utils/adt/float.c:3754 #, c-format msgid "lower and upper bounds must be finite" msgstr "les limites basse et haute doivent être finies" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1513 +#: utils/adt/float.c:3788 utils/adt/numeric.c:1524 #, c-format msgid "lower bound cannot equal upper bound" msgstr "la limite inférieure ne peut pas être plus égale à la limite supérieure" -#: utils/adt/formatting.c:493 +#: utils/adt/formatting.c:488 #, c-format msgid "invalid format specification for an interval value" msgstr "format de spécification invalide pour une valeur intervalle" -#: utils/adt/formatting.c:494 +#: utils/adt/formatting.c:489 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Les intervalles ne sont pas liés aux dates de calendriers spécifiques." -#: utils/adt/formatting.c:1060 +#: utils/adt/formatting.c:1059 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "« EEEE » doit être le dernier motif utilisé" -#: utils/adt/formatting.c:1068 +#: utils/adt/formatting.c:1067 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "« 9 » doit être avant « PR »" -#: utils/adt/formatting.c:1084 +#: utils/adt/formatting.c:1083 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "« 0 » doit être avant « PR »" -#: utils/adt/formatting.c:1111 +#: utils/adt/formatting.c:1110 #, c-format msgid "multiple decimal points" msgstr "multiples points décimaux" -#: utils/adt/formatting.c:1115 utils/adt/formatting.c:1198 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "ne peut pas utiliser « V » et le point décimal ensemble" -#: utils/adt/formatting.c:1127 +#: utils/adt/formatting.c:1126 #, c-format msgid "cannot use \"S\" twice" msgstr "ne peut pas utiliser « S » deux fois" -#: utils/adt/formatting.c:1131 +#: utils/adt/formatting.c:1130 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "ne peut pas utiliser « S » et « PL »/« MI »/« SG »/« PR » ensemble" -#: utils/adt/formatting.c:1151 +#: utils/adt/formatting.c:1150 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "ne peut pas utiliser « S » et « MI » ensemble" -#: utils/adt/formatting.c:1161 +#: utils/adt/formatting.c:1160 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "ne peut pas utiliser « S » et « PL » ensemble" -#: utils/adt/formatting.c:1171 +#: utils/adt/formatting.c:1170 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "ne peut pas utiliser « S » et « SG » ensemble" -#: utils/adt/formatting.c:1180 +#: utils/adt/formatting.c:1179 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "ne peut pas utiliser « PR » et « S »/« PL »/« MI »/« SG » ensemble" -#: utils/adt/formatting.c:1206 +#: utils/adt/formatting.c:1205 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "ne peut pas utiliser « EEEE » deux fois" -#: utils/adt/formatting.c:1212 +#: utils/adt/formatting.c:1211 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "« EEEE » est incompatible avec les autres formats" -#: utils/adt/formatting.c:1213 +#: utils/adt/formatting.c:1212 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "« EEEE » peut seulement être utilisé avec les motifs de chiffres et de points décimaux." -#: utils/adt/formatting.c:1402 +#: utils/adt/formatting.c:1392 #, c-format msgid "\"%s\" is not a number" msgstr "« %s » n'est pas un nombre" -#: utils/adt/formatting.c:1480 +#: utils/adt/formatting.c:1470 #, c-format msgid "case conversion failed: %s" msgstr "échec de la conversion de casse : %s" -#: utils/adt/formatting.c:1546 +#: utils/adt/formatting.c:1535 #, c-format msgid "could not determine which collation to use for lower() function" msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction lower()" -#: utils/adt/formatting.c:1670 +#: utils/adt/formatting.c:1657 #, c-format msgid "could not determine which collation to use for upper() function" msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction upper()" -#: utils/adt/formatting.c:1795 +#: utils/adt/formatting.c:1780 #, c-format msgid "could not determine which collation to use for initcap() function" msgstr "n'a pas pu déterminer le collationnement à utiliser pour la fonction initcap()" -#: utils/adt/formatting.c:2163 +#: utils/adt/formatting.c:2148 #, c-format msgid "invalid combination of date conventions" msgstr "combinaison invalide des conventions de date" -#: utils/adt/formatting.c:2164 +#: utils/adt/formatting.c:2149 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr "" "Ne pas mixer les conventions de jour de semaine grégorien et ISO dans un\n" "modèle de formatage." -#: utils/adt/formatting.c:2181 +#: utils/adt/formatting.c:2166 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "valeur conflictuelle pour le champ « %s » dans la chaîne de formatage" -#: utils/adt/formatting.c:2183 +#: utils/adt/formatting.c:2168 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Cette valeur contredit une configuration précédente pour le même type de champ." -#: utils/adt/formatting.c:2244 +#: utils/adt/formatting.c:2229 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "chaîne source trop petite pour le champ de formatage « %s »" -#: utils/adt/formatting.c:2246 +#: utils/adt/formatting.c:2231 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "Le champ requiert %d caractères, mais seuls %d restent." -#: utils/adt/formatting.c:2249 utils/adt/formatting.c:2263 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "" "Si votre chaîne source n'a pas une taille fixe, essayez d'utiliser le\n" "modifieur « FM »." -#: utils/adt/formatting.c:2259 utils/adt/formatting.c:2272 utils/adt/formatting.c:2402 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 utils/adt/formatting.c:2387 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "valeur « %s » invalide pour « %s »" -#: utils/adt/formatting.c:2261 +#: utils/adt/formatting.c:2246 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "Le champ nécessite %d caractères, mais seulement %d ont pu être analysés." -#: utils/adt/formatting.c:2274 +#: utils/adt/formatting.c:2259 #, c-format msgid "Value must be an integer." msgstr "La valeur doit être un entier" -#: utils/adt/formatting.c:2279 +#: utils/adt/formatting.c:2264 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "la valeur pour « %s » dans la chaîne source est en dehors des limites" -#: utils/adt/formatting.c:2281 +#: utils/adt/formatting.c:2266 #, c-format msgid "Value must be in the range %d to %d." msgstr "La valeur doit être compris entre %d et %d" -#: utils/adt/formatting.c:2404 +#: utils/adt/formatting.c:2389 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "La valeur donnée ne correspond pas aux valeurs autorisées pour ce champ." -#: utils/adt/formatting.c:2589 utils/adt/formatting.c:2609 utils/adt/formatting.c:2629 utils/adt/formatting.c:2649 utils/adt/formatting.c:2668 utils/adt/formatting.c:2687 utils/adt/formatting.c:2711 utils/adt/formatting.c:2729 utils/adt/formatting.c:2747 utils/adt/formatting.c:2765 utils/adt/formatting.c:2782 utils/adt/formatting.c:2799 +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 #, c-format msgid "localized string format value too long" msgstr "chaîne localisée trop longue" -#: utils/adt/formatting.c:3086 +#: utils/adt/formatting.c:3084 #, c-format msgid "formatting field \"%s\" is only supported in to_char" msgstr "le formatage du champ « %s » est seulement supporté dans to_char" -#: utils/adt/formatting.c:3197 +#: utils/adt/formatting.c:3209 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "chaîne invalide en entrée pour « Y,YYY »" -#: utils/adt/formatting.c:3703 +#: utils/adt/formatting.c:3724 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "l'heure « %d » est invalide pour une horloge sur 12 heures" -#: utils/adt/formatting.c:3705 +#: utils/adt/formatting.c:3726 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "Utilisez une horloge sur 24 heures ou donnez une heure entre 1 et 12." -#: utils/adt/formatting.c:3811 +#: utils/adt/formatting.c:3832 #, c-format msgid "cannot calculate day of year without year information" msgstr "ne peut pas calculer le jour de l'année sans information sur l'année" -#: utils/adt/formatting.c:4678 +#: utils/adt/formatting.c:4737 #, c-format msgid "\"EEEE\" not supported for input" msgstr "« EEEE » non supporté en entrée" -#: utils/adt/formatting.c:4690 +#: utils/adt/formatting.c:4749 #, c-format msgid "\"RN\" not supported for input" msgstr "« RN » non supporté en entrée" -#: utils/adt/genfile.c:63 +#: utils/adt/genfile.c:79 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "référence non autorisée au répertoire parent (« .. »)" -#: utils/adt/genfile.c:74 +#: utils/adt/genfile.c:90 #, c-format msgid "absolute path not allowed" msgstr "chemin absolu non autorisé" -#: utils/adt/genfile.c:79 +#: utils/adt/genfile.c:95 #, c-format msgid "path must be in or below the current directory" msgstr "le chemin doit être dans ou en-dessous du répertoire courant" -#: utils/adt/genfile.c:126 utils/adt/oracle_compat.c:184 utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "longueur demandée trop importante" -#: utils/adt/genfile.c:143 +#: utils/adt/genfile.c:159 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "n'a pas pu parcourir le fichier « %s » : %m" -#: utils/adt/genfile.c:201 utils/adt/genfile.c:242 -#, c-format -msgid "must be superuser to read files" -msgstr "doit être super-utilisateur pour lire des fichiers" - -#: utils/adt/genfile.c:319 +#: utils/adt/genfile.c:219 #, c-format -msgid "must be superuser to get file information" -msgstr "doit être super-utilisateur pour obtenir des informations sur le fichier" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "doit être super-utilisateur pour lire des fichiers avec adminpack 1.0" -#: utils/adt/genfile.c:405 +#: utils/adt/genfile.c:220 #, c-format -msgid "must be superuser to get directory listings" -msgstr "doit être super-utilisateur pour obtenir le contenu du répertoire" +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "Considérer l'utilisation de pg_file_read(), qui est présent par défaut, à la place." -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:939 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "spécification invalide de ligne : A et B ne peuvent pas être à zéro tous les deux" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:947 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "spécification de ligne invalide : doit être deux points distincts" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 utils/adt/geo_ops.c:5181 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 utils/adt/geo_ops.c:5180 #, c-format msgid "too many points requested" msgstr "trop de points demandé" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1403 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "nombre de points invalide dans la valeur externe de « path »" -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2554 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "la fonction « dist_lb » n'est pas implémentée" -#: utils/adt/geo_ops.c:3015 +#: utils/adt/geo_ops.c:3014 #, c-format msgid "function \"close_sl\" not implemented" msgstr "la fonction « close_sl » n'est pas implémentée" -#: utils/adt/geo_ops.c:3117 +#: utils/adt/geo_ops.c:3116 #, c-format msgid "function \"close_lb\" not implemented" msgstr "la fonction « close_lb » n'est pas implémentée" -#: utils/adt/geo_ops.c:3406 +#: utils/adt/geo_ops.c:3405 #, c-format msgid "cannot create bounding box for empty polygon" msgstr "ne peut pas créer une boîte entourée pour un polygône vide" -#: utils/adt/geo_ops.c:3487 +#: utils/adt/geo_ops.c:3486 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "nombre de points invalide dans la valeur externe de « polygon »" -#: utils/adt/geo_ops.c:4012 +#: utils/adt/geo_ops.c:4011 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "la fonction « poly_distance » n'est pas implémentée" -#: utils/adt/geo_ops.c:4365 +#: utils/adt/geo_ops.c:4364 #, c-format msgid "function \"path_center\" not implemented" msgstr "la fonction « path_center » n'est pas implémentée" -#: utils/adt/geo_ops.c:4382 +#: utils/adt/geo_ops.c:4381 #, c-format msgid "open path cannot be converted to polygon" msgstr "le chemin ouvert ne peut être converti en polygône" -#: utils/adt/geo_ops.c:4631 +#: utils/adt/geo_ops.c:4630 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "diamètre invalide pour la valeur externe de « circle »" -#: utils/adt/geo_ops.c:5167 +#: utils/adt/geo_ops.c:5166 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "ne peut pas convertir le cercle avec un diamètre zéro en un polygône" -#: utils/adt/geo_ops.c:5172 +#: utils/adt/geo_ops.c:5171 #, c-format msgid "must request at least 2 points" msgstr "doit demander au moins deux points" -#: utils/adt/geo_ops.c:5216 +#: utils/adt/geo_ops.c:5215 #, c-format msgid "cannot convert empty polygon to circle" msgstr "ne peut pas convertir un polygône vide en cercle" -#: utils/adt/int.c:162 +#: utils/adt/int.c:160 #, c-format msgid "int2vector has too many elements" msgstr "int2vector a trop d'éléments" -#: utils/adt/int.c:237 +#: utils/adt/int.c:235 #, c-format msgid "invalid int2vector data" msgstr "données int2vector invalide" -#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "oidvector a trop d'éléments" -#: utils/adt/int.c:1347 utils/adt/int8.c:1460 utils/adt/numeric.c:1401 utils/adt/timestamp.c:5178 utils/adt/timestamp.c:5259 +#: utils/adt/int.c:1379 utils/adt/int8.c:1325 utils/adt/numeric.c:1412 utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5402 #, c-format msgid "step size cannot equal zero" msgstr "la taille du pas ne peut pas valoir zéro" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 utils/adt/numutils.c:61 utils/adt/numutils.c:105 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 utils/adt/numutils.c:105 #, c-format -msgid "invalid input syntax for %s: \"%s\"" -msgstr "syntaxe en entrée invalide pour le type %s : « %s »" +msgid "invalid input syntax for integer: \"%s\"" +msgstr "syntaxe en entrée invalide pour l'entier : « %s »" -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 utils/adt/int8.c:1052 utils/adt/int8.c:1079 -#: utils/adt/int8.c:1112 utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:3005 utils/adt/varbit.c:1655 +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 utils/adt/int8.c:1227 utils/adt/int8.c:1269 utils/adt/numeric.c:3169 utils/adt/varbit.c:1655 #, c-format msgid "bigint out of range" msgstr "bigint en dehors des limites" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1282 #, c-format msgid "OID out of range" msgstr "OID en dehors des limites" -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Le caractère de valeur 0x%02x doit être échappé." -#: utils/adt/json.c:827 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "« \\u » doit être suivi par quatre chiffres hexadécimaux." -#: utils/adt/json.c:843 +#: utils/adt/json.c:844 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Une substitution unicode haute ne doit pas suivre une substitution haute." -#: utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:916 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 utils/adt/json.c:979 utils/adt/json.c:991 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Une substitution unicode basse ne doit pas suivre une substitution haute." -#: utils/adt/json.c:879 utils/adt/json.c:902 +#: utils/adt/json.c:880 utils/adt/json.c:903 #, c-format msgid "unsupported Unicode escape sequence" msgstr "séquence d'échappement Unicode non supportée" -#: utils/adt/json.c:880 +#: utils/adt/json.c:881 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 ne peut pas être converti en texte." -#: utils/adt/json.c:903 +#: utils/adt/json.c:904 #, c-format msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." msgstr "" "Les valeurs d'échappement unicode ne peuvent pas être utilisées pour les valeurs de point de code\n" "au-dessus de 007F quand l'encodage serveur n'est pas UTF8." -#: utils/adt/json.c:948 utils/adt/json.c:966 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "La séquence d'échappement « \\%s » est invalide." -#: utils/adt/json.c:1135 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "La chaîne en entrée se ferme de manière inattendue." -#: utils/adt/json.c:1149 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." -msgstr "Attendait une fin de l'entrée, mais ait trouvé « %s »." +msgstr "Attendait une fin de l'entrée, mais a trouvé « %s »." -#: utils/adt/json.c:1160 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "Valeur JSON attendue, mais « %s » trouvé." -#: utils/adt/json.c:1168 utils/adt/json.c:1216 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "Chaîne attendue, mais « %s » trouvé." -#: utils/adt/json.c:1176 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "Élément de tableau ou « ] » attendu, mais « %s » trouvé" -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "« , » ou « ] » attendu, mais « %s » trouvé" -#: utils/adt/json.c:1192 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "Chaîne ou « } » attendu, mais « %s » trouvé" -#: utils/adt/json.c:1200 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "« : » attendu, mais « %s » trouvé" -#: utils/adt/json.c:1208 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "« , » ou « } » attendu, mais « %s » trouvé" -#: utils/adt/json.c:1246 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "le jeton « %s » n'est pas valide" -#: utils/adt/json.c:1318 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "données JSON, ligne %d : %s%s%s" -#: utils/adt/json.c:1474 utils/adt/jsonb.c:725 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "la valeur clé doit être scalaire, et non pas un tableau ou une valeur composite ou un json" -#: utils/adt/json.c:2011 utils/adt/json.c:2021 utils/adt/json.c:2147 utils/adt/json.c:2168 utils/adt/json.c:2227 utils/adt/jsonb.c:1215 utils/adt/jsonb.c:1238 utils/adt/jsonb.c:1298 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format msgid "could not determine data type for argument %d" msgstr "n'a pas pu déterminer le type de données pour l'argument %d" -#: utils/adt/json.c:2045 utils/adt/jsonb.c:1782 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format msgid "field name must not be null" msgstr "le nom du champ ne doit pas être NULL" -#: utils/adt/json.c:2122 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format msgid "argument list must have even number of elements" msgstr "la liste d'arguments doit avoir un nombre pair d'éléments" -#: utils/adt/json.c:2123 +#: utils/adt/json.c:2195 #, c-format msgid "The arguments of json_build_object() must consist of alternating keys and values." msgstr "Les arguments de json_build_object() doivent consister en des clés et valeurs alternées" -#: utils/adt/json.c:2153 +#: utils/adt/json.c:2210 #, c-format msgid "argument %d cannot be null" msgstr "l'argument %d ne peut pas être NULL" -#: utils/adt/json.c:2154 +#: utils/adt/json.c:2211 #, c-format msgid "Object keys should be text." msgstr "Les clés de l'objet doivent être du texte." -#: utils/adt/json.c:2289 utils/adt/jsonb.c:1364 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format msgid "array must have two columns" msgstr "le tableau doit avoir deux colonnes" -#: utils/adt/json.c:2313 utils/adt/json.c:2397 utils/adt/jsonb.c:1388 utils/adt/jsonb.c:1483 +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 utils/adt/jsonb.c:1395 #, c-format msgid "null value not allowed for object key" msgstr "valeur NULL non autorisée pour une clé d'objet" -#: utils/adt/json.c:2386 utils/adt/jsonb.c:1472 +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 #, c-format msgid "mismatched array dimensions" msgstr "dimensions du tableau non correspondantes" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:258 #, c-format msgid "string too long to represent as jsonb string" msgstr "chaîne trop longue pour être représentée en tant que chaîne jsonb" -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:259 #, c-format msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "Dû à l'implémentation, les chaînes jsonb ne peuvent excéder %d octets." -#: utils/adt/jsonb.c:1183 +#: utils/adt/jsonb.c:1147 #, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "nombre d'arguments invalide : l'objet doit correspond aux paires clé/valeur" +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "Les arguments de jsonb_build_object() doivent consister en des clés et valeurs alternées" -#: utils/adt/jsonb.c:1196 +#: utils/adt/jsonb.c:1159 #, c-format msgid "argument %d: key must not be null" msgstr "argument %d : la clé ne doit pas être NULL" -#: utils/adt/jsonb.c:1835 +#: utils/adt/jsonb.c:1747 #, c-format msgid "object keys must be strings" msgstr "les clés de l'objet doivent être du texte" +#: utils/adt/jsonb.c:1910 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "ne peut pas convertir un jsonb NULL vers le type %s" + +#: utils/adt/jsonb.c:1911 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "ne peut pas convertir la chaîne jsonb vers le type %s" + +#: utils/adt/jsonb.c:1912 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "ne peut pas convertir le numeric jsonb vers le type %s" + +#: utils/adt/jsonb.c:1913 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "ne peut pas convertir le booléen jsonb vers le type %s" + +#: utils/adt/jsonb.c:1914 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "ne peut pas convertir le tableau jsonb vers le type %s" + +#: utils/adt/jsonb.c:1915 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "ne peut pas convertir l'objet jsonb vers le type %s" + +#: utils/adt/jsonb.c:1916 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "ne peut pas convertir le tableau ou l'objet jsonb vers le type %s" + #: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" @@ -20900,169 +21837,189 @@ msgstr "le nombre de paires d'objets jsonb dépasse le maximum autorisé (%zu)" msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "le nombre d'éléments du tableau jsonb dépasse le maximum autorisé (%zu)" -#: utils/adt/jsonb_util.c:1526 utils/adt/jsonb_util.c:1546 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "la taille totale des éléments du tableau jsonb dépasse le maximum de %u octets" -#: utils/adt/jsonb_util.c:1607 utils/adt/jsonb_util.c:1642 utils/adt/jsonb_util.c:1662 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "la taille totale des éléments de l'objet JSON dépasse le maximum de %u octets" -#: utils/adt/jsonfuncs.c:511 utils/adt/jsonfuncs.c:676 utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:2699 utils/adt/jsonfuncs.c:3393 utils/adt/jsonfuncs.c:3677 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 #, c-format msgid "cannot call %s on a scalar" msgstr "ne peut pas appeler %s sur un scalaire" -#: utils/adt/jsonfuncs.c:516 utils/adt/jsonfuncs.c:663 utils/adt/jsonfuncs.c:2701 utils/adt/jsonfuncs.c:3382 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "ne peut pas appeler %s sur un tableau" -#: utils/adt/jsonfuncs.c:1579 utils/adt/jsonfuncs.c:1614 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "ne peut pas obtenir la longueur d'un scalaire" -#: utils/adt/jsonfuncs.c:1583 utils/adt/jsonfuncs.c:1602 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "ne peut pas obtenir la longueur du tableau d'un objet qui n'est pas un tableau" -#: utils/adt/jsonfuncs.c:1679 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "ne peut pas appeler %s sur un non objet" -#: utils/adt/jsonfuncs.c:1697 utils/adt/jsonfuncs.c:3208 utils/adt/jsonfuncs.c:3502 +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 utils/adt/jsonfuncs.c:3621 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "" "fonction renvoyant le type record appelée dans un contexte qui ne peut pas\n" "accepter le type record" -#: utils/adt/jsonfuncs.c:1936 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "ne peut pas déconstruire un tableau sous la forme d'un objet" -#: utils/adt/jsonfuncs.c:1948 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "ne peut pas décomposer un scalaire" -#: utils/adt/jsonfuncs.c:1994 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "ne peut pas extraire des éléments d'un scalaire" -#: utils/adt/jsonfuncs.c:1998 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "ne peut pas extraire des éléments d'un objet" -#: utils/adt/jsonfuncs.c:2250 utils/adt/jsonfuncs.c:3566 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format msgid "cannot call %s on a non-array" msgstr "ne peut pas appeler %s sur un type non tableau" -#: utils/adt/jsonfuncs.c:2316 utils/adt/jsonfuncs.c:2321 utils/adt/jsonfuncs.c:2338 utils/adt/jsonfuncs.c:2344 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 #, c-format -msgid "expected json array" -msgstr "attendait un tableau json" +msgid "expected JSON array" +msgstr "attendait un tableau JSON" -#: utils/adt/jsonfuncs.c:2317 +#: utils/adt/jsonfuncs.c:2334 #, c-format -msgid "see the value of key \"%s\"" -msgstr "voir la valeur de la clé « %s »" +msgid "See the value of key \"%s\"." +msgstr "Voir la valeur de la clé « %s »." -#: utils/adt/jsonfuncs.c:2339 +#: utils/adt/jsonfuncs.c:2356 #, c-format -msgid "see the array element %s of key \"%s\"" -msgstr "voir l'élément de tableau %s de la clé « %s »" +msgid "See the array element %s of key \"%s\"." +msgstr "Voir l'élément de tableau %s de la clé « %s »." -#: utils/adt/jsonfuncs.c:2345 +#: utils/adt/jsonfuncs.c:2362 #, c-format -msgid "see the array element %s" -msgstr "voir l'élément de tableau %s" +msgid "See the array element %s." +msgstr "voir l'élément de tableau %s." -#: utils/adt/jsonfuncs.c:2380 +#: utils/adt/jsonfuncs.c:2397 #, c-format -msgid "malformed json array" -msgstr "tableau json mal formé" +msgid "malformed JSON array" +msgstr "tableau JSON mal formé" -#: utils/adt/jsonfuncs.c:3168 utils/adt/jsonfuncs.c:3478 +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "le premier argument de %s doit être un type row" -#: utils/adt/jsonfuncs.c:3210 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format msgid "Try calling the function in the FROM clause using a column definition list." msgstr "Essayez d'appeler la fonction dans la clause FROM en utilisant une liste de définition de colonnes." -#: utils/adt/jsonfuncs.c:3583 utils/adt/jsonfuncs.c:3659 +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 #, c-format msgid "argument of %s must be an array of objects" msgstr "l'argument de %s doit être un tableau d'objets" -#: utils/adt/jsonfuncs.c:3611 +#: utils/adt/jsonfuncs.c:3764 #, c-format msgid "cannot call %s on an object" msgstr "ne peut pas appeler %s sur un objet" -#: utils/adt/jsonfuncs.c:4087 utils/adt/jsonfuncs.c:4146 utils/adt/jsonfuncs.c:4226 +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 utils/adt/jsonfuncs.c:4380 #, c-format msgid "cannot delete from scalar" msgstr "ne peut pas supprimer à partir du scalaire" -#: utils/adt/jsonfuncs.c:4231 +#: utils/adt/jsonfuncs.c:4385 #, c-format msgid "cannot delete from object using integer index" msgstr "ne peut pas supprimer à partir de l'objet en utilisant l'index de l'entier" -#: utils/adt/jsonfuncs.c:4297 utils/adt/jsonfuncs.c:4389 +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 #, c-format msgid "cannot set path in scalar" msgstr "ne peut pas initialiser le chemin dans le scalaire" -#: utils/adt/jsonfuncs.c:4342 +#: utils/adt/jsonfuncs.c:4496 #, c-format msgid "cannot delete path in scalar" msgstr "ne peut pas supprimer un chemin dans le scalaire" -#: utils/adt/jsonfuncs.c:4512 +#: utils/adt/jsonfuncs.c:4666 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "concaténation invalide d'objets jsonb" -#: utils/adt/jsonfuncs.c:4546 +#: utils/adt/jsonfuncs.c:4700 #, c-format msgid "path element at position %d is null" msgstr "l'élément de chemin à la position %d est nul" -#: utils/adt/jsonfuncs.c:4632 +#: utils/adt/jsonfuncs.c:4786 #, c-format msgid "cannot replace existing key" msgstr "ne peut pas remplacer une clé existante" -#: utils/adt/jsonfuncs.c:4633 +#: utils/adt/jsonfuncs.c:4787 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "Essayez d'utiliser la fonction jsonb_set pour remplacer la valeur de la clé." -#: utils/adt/jsonfuncs.c:4715 +#: utils/adt/jsonfuncs.c:4869 #, c-format msgid "path element at position %d is not an integer: \"%s\"" msgstr "l'élément du chemin à la position %d n'est pas un entier : « %s »" +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "mauvais type de drapeau, seuls les tableaux et scalaires sont autorisés" + +#: utils/adt/jsonfuncs.c:4995 +#, c-format +msgid "flag array element is not a string" +msgstr "le drapeau d'élément de tableau n'est pas une chaîne" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "Les valeurs possibles sont : « string », « numeric », « boolean », « key » et « all »" + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "mauvais drapeau dans le drapeau de tableau : « %s »" + #: utils/adt/levenshtein.c:133 #, c-format msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "l'argument levenshtein dépasse la longueur maximale de %d caractères" -#: utils/adt/like.c:183 utils/adt/selfuncs.c:5562 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5811 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "n'a pas pu déterminer le collationnement à utiliser pour ILIKE" @@ -21072,12 +22029,12 @@ msgstr "n'a pas pu déterminer le collationnement à utiliser pour ILIKE" msgid "LIKE pattern must not end with escape character" msgstr "le motif LIKE ne se termine pas de caractères d'échappement" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "chaîne d'échappement invalide" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "La chaîne d'échappement doit être vide ou ne contenir qu'un caractère." @@ -21092,128 +22049,138 @@ msgstr "ne peut pas utiliser les verrous informatifs lors d'une opération paral msgid "invalid octet value in \"macaddr\" value: \"%s\"" msgstr "valeur d'un octet invalide dans la valeur de « macaddr » : « %s »" -#: utils/adt/mac8.c:554 +#: utils/adt/mac8.c:563 #, c-format msgid "macaddr8 data out of range to convert to macaddr" -msgstr "" +msgstr "donnée macaddr8 hors de l'échelle pour être convertie en macaddr" -#: utils/adt/mac8.c:555 +#: utils/adt/mac8.c:564 #, c-format -msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes, from the left, for example: XX-XX-XX-FF-FE-XX-XX-XX, are eligible to be converted from macaddr8 to macaddr." -msgstr "" +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Seules les adresses qui ont FF ou FE comme valeurs dans les 4è et 5è octets à partir de la gauche, par exemple xx:xx:xx:ff:fe:xx:xx:xx, , sont éligibles à être converties de macaddr8 à macaddr." -#: utils/adt/misc.c:238 +#: utils/adt/misc.c:239 #, c-format msgid "PID %d is not a PostgreSQL server process" msgstr "le PID %d n'est pas un processus du serveur PostgreSQL" -#: utils/adt/misc.c:289 +#: utils/adt/misc.c:290 #, c-format msgid "must be a superuser to cancel superuser query" msgstr "doit être super-utilisateur pour annuler la requête d'un super-utilisateur" -#: utils/adt/misc.c:294 +#: utils/adt/misc.c:295 #, c-format msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" msgstr "doit être un membre du rôle dont la requête est en cours d'annulation ou membre de pg_signal_backend" -#: utils/adt/misc.c:313 +#: utils/adt/misc.c:314 #, c-format msgid "must be a superuser to terminate superuser process" msgstr "doit être super-utilisateur pour terminer le processus d'un super-utilisateur" -#: utils/adt/misc.c:318 +#: utils/adt/misc.c:319 #, c-format msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" msgstr "doit être un membre du rôle dont le processus est en cours d'arrêt ou membre de pg_signal_backend" -#: utils/adt/misc.c:335 +#: utils/adt/misc.c:336 #, c-format msgid "failed to send signal to postmaster: %m" msgstr "n'a pas pu envoyer le signal au postmaster : %m" #: utils/adt/misc.c:355 #, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "doit être super-utilisateur pour exécuter la rotation des journaux applicatifs avec adminpack 1.0" + +#: utils/adt/misc.c:356 +#, c-format +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "Considérer l'utilisation de pg_logfile_rotate(), qui est présent par défaut, à la place." + +#: utils/adt/misc.c:361 utils/adt/misc.c:381 +#, c-format msgid "rotation not possible because log collection not active" msgstr "rotation impossible car la récupération des journaux applicatifs n'est pas activée" -#: utils/adt/misc.c:392 +#: utils/adt/misc.c:418 #, c-format msgid "global tablespace never has databases" msgstr "le tablespace global n'a jamais de bases de données" -#: utils/adt/misc.c:413 +#: utils/adt/misc.c:439 #, c-format msgid "%u is not a tablespace OID" msgstr "%u n'est pas un OID de tablespace" -#: utils/adt/misc.c:606 +#: utils/adt/misc.c:626 msgid "unreserved" msgstr "non réservé" -#: utils/adt/misc.c:610 +#: utils/adt/misc.c:630 msgid "unreserved (cannot be function or type name)" msgstr "non réservé (ne peut pas être un nom de fonction ou de type)" -#: utils/adt/misc.c:614 +#: utils/adt/misc.c:634 msgid "reserved (can be function or type name)" msgstr "réservé (peut être un nom de fonction ou de type)" -#: utils/adt/misc.c:618 +#: utils/adt/misc.c:638 msgid "reserved" msgstr "réservé" -#: utils/adt/misc.c:792 utils/adt/misc.c:806 utils/adt/misc.c:845 utils/adt/misc.c:851 utils/adt/misc.c:857 utils/adt/misc.c:880 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 #, c-format msgid "string is not a valid identifier: \"%s\"" msgstr "la chaîne n'est pas un identifiant valide : « %s »" -#: utils/adt/misc.c:794 +#: utils/adt/misc.c:814 #, c-format msgid "String has unclosed double quotes." msgstr "La chaîne des des guillements doubles non fermés." -#: utils/adt/misc.c:808 +#: utils/adt/misc.c:828 #, c-format msgid "Quoted identifier must not be empty." msgstr "L'identifiant entre guillemets ne doit pas être vide." -#: utils/adt/misc.c:847 +#: utils/adt/misc.c:867 #, c-format msgid "No valid identifier before \".\"." msgstr "Pas d'identifiant valide avant « . »." -#: utils/adt/misc.c:853 +#: utils/adt/misc.c:873 #, c-format msgid "No valid identifier after \".\"." msgstr "Pas d'identifiant valide après « . »." -#: utils/adt/misc.c:914 +#: utils/adt/misc.c:934 #, c-format msgid "log format \"%s\" is not supported" msgstr "le format de trace « %s » n'est pas supporté" -#: utils/adt/misc.c:915 +#: utils/adt/misc.c:935 #, c-format msgid "The supported log formats are \"stderr\" and \"csvlog\"." msgstr "Les formats de traces supportés sont « stderr » et « csvlog »." -#: utils/adt/nabstime.c:137 +#: utils/adt/nabstime.c:140 #, c-format msgid "invalid time zone name: \"%s\"" msgstr "nom du fuseau horaire invalide : « %s »" -#: utils/adt/nabstime.c:482 utils/adt/nabstime.c:555 +#: utils/adt/nabstime.c:485 utils/adt/nabstime.c:558 #, c-format msgid "cannot convert abstime \"invalid\" to timestamp" msgstr "ne peut pas convertir un abstime « invalid » en timestamp" -#: utils/adt/nabstime.c:782 +#: utils/adt/nabstime.c:785 #, c-format msgid "invalid status in external \"tinterval\" value" msgstr "statut invalide dans la valeur externe « tinterval »" -#: utils/adt/nabstime.c:852 +#: utils/adt/nabstime.c:855 #, c-format msgid "cannot convert reltime \"invalid\" to interval" msgstr "ne peut pas convertir reltime « invalid » en interval" @@ -21228,7 +22195,7 @@ msgstr "valeur cidr invalide : « %s »" msgid "Value has bits set to right of mask." msgstr "La valeur a des bits positionnés à la droite du masque." -#: utils/adt/network.c:111 utils/adt/network.c:582 utils/adt/network.c:607 utils/adt/network.c:632 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 utils/adt/network.c:642 #, c-format msgid "could not format inet value: %m" msgstr "n'a pas pu formater la valeur inet : %m" @@ -21261,111 +22228,116 @@ msgstr "valeur externe « cidr » invalide" msgid "invalid mask length: %d" msgstr "longueur du masque invalide : %d" -#: utils/adt/network.c:650 +#: utils/adt/network.c:660 #, c-format msgid "could not format cidr value: %m" msgstr "n'a pas pu formater la valeur cidr : %m" -#: utils/adt/network.c:883 +#: utils/adt/network.c:893 #, c-format msgid "cannot merge addresses from different families" msgstr "ne peut pas assembler les adresses de familles différentes" -#: utils/adt/network.c:1302 +#: utils/adt/network.c:1309 #, c-format msgid "cannot AND inet values of different sizes" msgstr "" "ne peut pas utiliser l'opérateur AND sur des champs de type inet de tailles\n" "différentes" -#: utils/adt/network.c:1334 +#: utils/adt/network.c:1341 #, c-format msgid "cannot OR inet values of different sizes" msgstr "" "ne peut pas utiliser l'opérateur OR sur des champs de type inet de tailles\n" "différentes" -#: utils/adt/network.c:1395 utils/adt/network.c:1471 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format msgid "result is out of range" msgstr "le résultat est en dehors des limites" -#: utils/adt/network.c:1436 +#: utils/adt/network.c:1443 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "ne peut pas soustraire des valeurs inet de tailles différentes" -#: utils/adt/numeric.c:819 +#: utils/adt/numeric.c:830 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "signe invalide dans la valeur externe « numeric »" -#: utils/adt/numeric.c:825 +#: utils/adt/numeric.c:836 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "échelle invalide dans la valeur externe « numeric »" -#: utils/adt/numeric.c:834 +#: utils/adt/numeric.c:845 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "chiffre invalide dans la valeur externe « numeric »" -#: utils/adt/numeric.c:1024 utils/adt/numeric.c:1038 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "la précision NUMERIC %d doit être comprise entre 1 et %d" -#: utils/adt/numeric.c:1029 +#: utils/adt/numeric.c:1040 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "l'échelle NUMERIC %d doit être comprise entre 0 et %d" -#: utils/adt/numeric.c:1047 +#: utils/adt/numeric.c:1058 #, c-format msgid "invalid NUMERIC type modifier" msgstr "modificateur de type NUMERIC invalide" -#: utils/adt/numeric.c:1379 +#: utils/adt/numeric.c:1390 #, c-format msgid "start value cannot be NaN" msgstr "la valeur de démarrage ne peut pas être NaN" -#: utils/adt/numeric.c:1384 +#: utils/adt/numeric.c:1395 #, c-format msgid "stop value cannot be NaN" msgstr "la valeur d'arrêt ne peut pas être NaN" -#: utils/adt/numeric.c:1394 +#: utils/adt/numeric.c:1405 #, c-format msgid "step size cannot be NaN" msgstr "la taille du pas ne peut pas être NaN" -#: utils/adt/numeric.c:2589 utils/adt/numeric.c:5551 utils/adt/numeric.c:5996 utils/adt/numeric.c:7700 utils/adt/numeric.c:8125 utils/adt/numeric.c:8239 utils/adt/numeric.c:8312 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 utils/adt/numeric.c:8490 #, c-format msgid "value overflows numeric format" msgstr "la valeur dépasse le format numeric" -#: utils/adt/numeric.c:2931 +#: utils/adt/numeric.c:3095 #, c-format msgid "cannot convert NaN to integer" msgstr "ne peut pas convertir NaN en un entier" -#: utils/adt/numeric.c:2997 +#: utils/adt/numeric.c:3161 #, c-format msgid "cannot convert NaN to bigint" msgstr "ne peut pas convertir NaN en un entier de type bigint" -#: utils/adt/numeric.c:3042 +#: utils/adt/numeric.c:3206 #, c-format msgid "cannot convert NaN to smallint" msgstr "ne peut pas convertir NaN en un entier de type smallint" -#: utils/adt/numeric.c:6066 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "ne peut pas convertir infinity en un type numeric" + +#: utils/adt/numeric.c:6240 #, c-format msgid "numeric field overflow" msgstr "champ numérique en dehors des limites" -#: utils/adt/numeric.c:6067 +#: utils/adt/numeric.c:6241 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "" @@ -21382,27 +22354,27 @@ msgstr "la valeur « %s » est en dehors des limites des entiers sur 8 bits" msgid "invalid oidvector data" msgstr "donnée oidvector invalide" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "caractère demandé trop long" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "caractère demandé trop long pour l'encodage : %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "caractère demandé invalide pour l'encodage : %d" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "caractère nul interdit" -#: utils/adt/orderedsetaggs.c:426 utils/adt/orderedsetaggs.c:531 utils/adt/orderedsetaggs.c:670 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "la valeur centile %g n'est pas entre 0 et 1" @@ -21422,95 +22394,91 @@ msgstr "n'a pas pu créer la locale « %s » : %m" msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "Le système d'exploitation n'a pas pu trouver des données de locale pour la locale « %s »." -#: utils/adt/pg_locale.c:1352 +#: utils/adt/pg_locale.c:1353 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "" "les collationnements avec des valeurs différents pour le tri et le jeu de\n" "caractères ne sont pas supportés sur cette plateforme" -#: utils/adt/pg_locale.c:1361 +#: utils/adt/pg_locale.c:1362 #, c-format msgid "collation provider LIBC is not supported on this platform" msgstr "le fournisseur du collationnement, LIBC, n'est pas supporté sur cette plateforme" -#: utils/adt/pg_locale.c:1373 -#, fuzzy, c-format -#| msgid "collations with different collate and ctype values are not supported on this platform" +#: utils/adt/pg_locale.c:1374 +#, c-format msgid "collations with different collate and ctype values are not supported by ICU" -msgstr "" -"les collationnements avec des valeurs différents pour le tri et le jeu de\n" -"caractères ne sont pas supportés sur cette plateforme" +msgstr "les collationnements avec des valeurs différentes pour le tri (collate) et le jeu de caractères (ctype) ne sont pas supportés par ICU" -#: utils/adt/pg_locale.c:1379 utils/adt/pg_locale.c:1461 -#, fuzzy, c-format -#| msgid "could not open control file \"%s\": %m" +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 +#, c-format msgid "could not open collator for locale \"%s\": %s" -msgstr "n'a pas pu ouvrir le fichier de contrôle « %s » : %m" +msgstr "n'a pas pu ouvrir le collationneur pour la locale « %s » : %s" -#: utils/adt/pg_locale.c:1388 +#: utils/adt/pg_locale.c:1391 #, c-format msgid "ICU is not supported in this build" msgstr "ICU n'est pas supporté dans cette installation" -#: utils/adt/pg_locale.c:1389 +#: utils/adt/pg_locale.c:1392 #, c-format msgid "You need to rebuild PostgreSQL using --with-icu." msgstr "Vous devez recompiler PostgreSQL en utilisant --with-icu." -#: utils/adt/pg_locale.c:1409 +#: utils/adt/pg_locale.c:1412 #, c-format msgid "collation \"%s\" has no actual version, but a version was specified" msgstr "le collationnement « %s » n'a pas de version réelle mais une version était indiquée" -#: utils/adt/pg_locale.c:1416 +#: utils/adt/pg_locale.c:1419 #, c-format msgid "collation \"%s\" has version mismatch" msgstr "le collationnement « %s » a des versions différentes" -#: utils/adt/pg_locale.c:1418 +#: utils/adt/pg_locale.c:1421 #, c-format msgid "The collation in the database was created using version %s, but the operating system provides version %s." msgstr "Le collationnement dans la base de données a été créé en utilisant la version %s mais le système d'exploitation fournit la version %s." -#: utils/adt/pg_locale.c:1421 +#: utils/adt/pg_locale.c:1424 #, c-format msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." msgstr "Reconstruisez tous les objets affectés par ce collationnement, et lancez ALTER COLLATION %s REFRESH VERSION, ou construisez PostgreSQL avec la bonne version de bibliothèque." -#: utils/adt/pg_locale.c:1501 +#: utils/adt/pg_locale.c:1508 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "n'a pas pu ouvrir le convertisseur ICU pour l'encodage « %s » : %s" -#: utils/adt/pg_locale.c:1532 utils/adt/pg_locale.c:1541 +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 #, c-format msgid "ucnv_toUChars failed: %s" msgstr "échec de ucnv_toUChars : %s" -#: utils/adt/pg_locale.c:1570 utils/adt/pg_locale.c:1579 +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 #, c-format msgid "ucnv_fromUChars failed: %s" msgstr "échec de ucnv_fromUChars : %s" -#: utils/adt/pg_locale.c:1752 +#: utils/adt/pg_locale.c:1758 #, c-format msgid "invalid multibyte character for locale" msgstr "caractère multi-octets invalide pour la locale" -#: utils/adt/pg_locale.c:1753 +#: utils/adt/pg_locale.c:1759 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "" "La locale LC_CTYPE du serveur est probablement incompatible avec l'encodage\n" "de la base de données." -#: utils/adt/pg_upgrade_support.c:28 +#: utils/adt/pg_upgrade_support.c:29 #, c-format msgid "function can only be called when server is in binary upgrade mode" msgstr "la fonction peut seulement être appelée quand le serveur est en mode de mise à jour binaire" -#: utils/adt/pgstatfuncs.c:473 +#: utils/adt/pgstatfuncs.c:474 #, c-format msgid "invalid command name: \"%s\"" msgstr "nom de commande invalide : « %s »" @@ -21550,79 +22518,84 @@ msgstr "le résultat de la différence d'intervalle de valeur ne sera pas contig msgid "result of range union would not be contiguous" msgstr "le résultat de l'union d'intervalle pourrait ne pas être contigü" -#: utils/adt/rangetypes.c:1533 +#: utils/adt/rangetypes.c:1597 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "" "la limite inférieure de l'intervalle de valeurs doit être inférieure ou égale\n" "à la limite supérieure de l'intervalle de valeurs" -#: utils/adt/rangetypes.c:1916 utils/adt/rangetypes.c:1929 utils/adt/rangetypes.c:1943 +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 utils/adt/rangetypes.c:2007 #, c-format msgid "invalid range bound flags" msgstr "drapeaux de limite de l'intervalle invalides" -#: utils/adt/rangetypes.c:1917 utils/adt/rangetypes.c:1930 utils/adt/rangetypes.c:1944 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 utils/adt/rangetypes.c:2008 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "Les valeurs valides sont entre « [] », « [) », « (] » et « () »." -#: utils/adt/rangetypes.c:2009 utils/adt/rangetypes.c:2026 utils/adt/rangetypes.c:2039 utils/adt/rangetypes.c:2057 utils/adt/rangetypes.c:2068 utils/adt/rangetypes.c:2112 utils/adt/rangetypes.c:2120 +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 utils/adt/rangetypes.c:2184 #, c-format msgid "malformed range literal: \"%s\"" msgstr "intervalle litéral mal formé : « %s »" -#: utils/adt/rangetypes.c:2011 +#: utils/adt/rangetypes.c:2075 #, c-format msgid "Junk after \"empty\" key word." msgstr "Cochonnerie après le mot clé « empty »" -#: utils/adt/rangetypes.c:2028 +#: utils/adt/rangetypes.c:2092 #, c-format msgid "Missing left parenthesis or bracket." msgstr "Parenthèse gauche ou crochet manquant" -#: utils/adt/rangetypes.c:2041 +#: utils/adt/rangetypes.c:2105 #, c-format msgid "Missing comma after lower bound." msgstr "Virgule manquante après une limite basse." -#: utils/adt/rangetypes.c:2059 +#: utils/adt/rangetypes.c:2123 #, c-format msgid "Too many commas." msgstr "Trop de virgules." -#: utils/adt/rangetypes.c:2070 +#: utils/adt/rangetypes.c:2134 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "Problème après la parenthèse droite ou le crochet droit." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1344 utils/adt/varlena.c:3963 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 #, c-format msgid "regular expression failed: %s" msgstr "l'expression rationnelle a échoué : %s" -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 #, c-format msgid "invalid regexp option: \"%c\"" msgstr "option invalide de l'expression rationnelle : « %c »" -#: utils/adt/regexp.c:862 +#: utils/adt/regexp.c:866 #, c-format msgid "regexp_match does not support the global option" msgstr "regexp_match ne supporte pas l'option globale" -#: utils/adt/regexp.c:863 +#: utils/adt/regexp.c:867 #, c-format msgid "Use the regexp_matches function instead." msgstr "Utilisez la foncction regexp_matches à la place." -#: utils/adt/regexp.c:1163 +#: utils/adt/regexp.c:1049 +#, c-format +msgid "too many regular expression matches" +msgstr "trop de correspondances pour l'expression rationnelle" + +#: utils/adt/regexp.c:1244 #, c-format msgid "regexp_split_to_table does not support the global option" msgstr "regexp_split_to_table ne supporte pas l'option globale" -#: utils/adt/regexp.c:1219 +#: utils/adt/regexp.c:1297 #, c-format msgid "regexp_split_to_array does not support the global option" msgstr "regexp_split_to_array ne supporte pas l'option globale" @@ -21637,7 +22610,7 @@ msgstr "il existe plus d'une fonction nommée « %s »" msgid "more than one operator named %s" msgstr "il existe plus d'un opérateur nommé%s" -#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 utils/adt/ruleutils.c:8996 utils/adt/ruleutils.c:9164 +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 utils/adt/ruleutils.c:9133 utils/adt/ruleutils.c:9301 #, c-format msgid "too many arguments" msgstr "trop d'arguments" @@ -21647,7 +22620,7 @@ msgstr "trop d'arguments" msgid "Provide two argument types for operator." msgstr "Fournit deux types d'argument pour l'opérateur." -#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 utils/adt/varlena.c:3216 utils/adt/varlena.c:3221 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 #, c-format msgid "invalid name syntax" msgstr "syntaxe du nom invalide" @@ -21672,90 +22645,90 @@ msgstr "attendait un nom de type" msgid "improper type name" msgstr "nom du type invalide" -#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2487 utils/adt/ri_triggers.c:3312 +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 utils/adt/ri_triggers.c:2774 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "" "une instruction insert ou update sur la table « %s » viole la contrainte de clé\n" "étrangère « %s »" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL n'autorise pas le mixage de valeurs clés NULL et non NULL." -#: utils/adt/ri_triggers.c:2729 +#: utils/adt/ri_triggers.c:2273 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "la fonction « %s » doit être exécutée pour l'instruction INSERT" -#: utils/adt/ri_triggers.c:2735 +#: utils/adt/ri_triggers.c:2279 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "la fonction « %s » doit être exécutée pour l'instruction UPDATE" -#: utils/adt/ri_triggers.c:2741 +#: utils/adt/ri_triggers.c:2285 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "la fonction « %s » doit être exécutée pour l'instruction DELETE" -#: utils/adt/ri_triggers.c:2764 +#: utils/adt/ri_triggers.c:2308 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "aucune entrée pg_constraint pour le trigger « %s » sur la table « %s »" -#: utils/adt/ri_triggers.c:2766 +#: utils/adt/ri_triggers.c:2310 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "" "Supprimez ce trigger sur une intégrité référentielle et ses enfants,\n" "puis faites un ALTER TABLE ADD CONSTRAINT." -#: utils/adt/ri_triggers.c:3222 +#: utils/adt/ri_triggers.c:2621 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "" "la requête d'intégrité référentielle sur « %s » à partir de la contrainte « %s »\n" "sur « %s » donne des résultats inattendus" -#: utils/adt/ri_triggers.c:3226 +#: utils/adt/ri_triggers.c:2625 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Ceci est certainement dû à une règle qui a ré-écrit la requête." -#: utils/adt/ri_triggers.c:3316 +#: utils/adt/ri_triggers.c:2778 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "La clé (%s)=(%s) n'est pas présente dans la table « %s »." -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/ri_triggers.c:2781 #, c-format msgid "Key is not present in table \"%s\"." msgstr "La clé n'est pas présente dans la table « %s »." -#: utils/adt/ri_triggers.c:3325 +#: utils/adt/ri_triggers.c:2787 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "" "UPDATE ou DELETE sur la table « %s » viole la contrainte de clé étrangère\n" "« %s » de la table « %s »" -#: utils/adt/ri_triggers.c:3330 +#: utils/adt/ri_triggers.c:2792 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "La clé (%s)=(%s) est toujours référencée à partir de la table « %s »." -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/ri_triggers.c:2795 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "La clé est toujours référencée à partir de la table « %s »." -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "l'ajout de colonnes ayant un type composé n'est pas implémenté" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 #, c-format msgid "malformed record literal: \"%s\"" msgstr "enregistrement litéral invalide : « %s »" @@ -21765,61 +22738,61 @@ msgstr "enregistrement litéral invalide : « %s »" msgid "Missing left parenthesis." msgstr "Parenthèse gauche manquante" -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:185 #, c-format msgid "Too few columns." msgstr "Pas assez de colonnes." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:268 #, c-format msgid "Too many columns." msgstr "Trop de colonnes." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:276 #, c-format msgid "Junk after right parenthesis." msgstr "Problème après la parenthèse droite." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:530 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "mauvais nombre de colonnes : %d, alors que %d attendu" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:558 #, c-format msgid "wrong data type: %u, expected %u" msgstr "mauvais type de données : %u, alors que %u attendu" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:619 #, c-format msgid "improper binary format in record column %d" msgstr "format binaire invalide dans l'enregistrement de la colonne %d" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 utils/adt/rowtypes.c:1396 utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 utils/adt/rowtypes.c:1657 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "" "ne peut pas comparer les types de colonnes non similaires %s et %s pour la\n" "colonne %d de l'enregistrement" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 utils/adt/rowtypes.c:1529 utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 utils/adt/rowtypes.c:1731 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "" "ne peut pas comparer les types d'enregistrement avec des numéros différents\n" "des colonnes" -#: utils/adt/ruleutils.c:4667 +#: utils/adt/ruleutils.c:4824 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "la règle « %s » a un type d'événement %d non supporté" -#: utils/adt/selfuncs.c:5547 +#: utils/adt/selfuncs.c:5796 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "la recherche insensible à la casse n'est pas supportée avec le type bytea" -#: utils/adt/selfuncs.c:5649 +#: utils/adt/selfuncs.c:5898 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "la recherche par expression rationnelle n'est pas supportée sur le type bytea" @@ -21879,8 +22852,8 @@ msgstr "timestamp ne peut pas valoir NaN" msgid "timestamp out of range: \"%g\"" msgstr "timestamp en dehors de limites : « %g »" -#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 utils/adt/timestamp.c:1918 utils/adt/timestamp.c:2994 utils/adt/timestamp.c:2999 utils/adt/timestamp.c:3004 utils/adt/timestamp.c:3054 utils/adt/timestamp.c:3061 utils/adt/timestamp.c:3068 utils/adt/timestamp.c:3088 utils/adt/timestamp.c:3095 utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3132 utils/adt/timestamp.c:3140 utils/adt/timestamp.c:3184 utils/adt/timestamp.c:3507 -#: utils/adt/timestamp.c:3632 utils/adt/timestamp.c:4000 +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3016 utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3026 utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3083 utils/adt/timestamp.c:3090 utils/adt/timestamp.c:3110 utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3162 utils/adt/timestamp.c:3206 utils/adt/timestamp.c:3633 +#: utils/adt/timestamp.c:3758 utils/adt/timestamp.c:4143 #, c-format msgid "interval out of range" msgstr "intervalle en dehors des limites" @@ -21905,46 +22878,46 @@ msgstr "La précision de l'intervalle INTERVAL(%d) doit être réduit au maximum msgid "interval(%d) precision must be between %d and %d" msgstr "La précision de interval(%d) doit être comprise entre %d et %d" -#: utils/adt/timestamp.c:2595 +#: utils/adt/timestamp.c:2617 #, c-format msgid "cannot subtract infinite timestamps" msgstr "ne peut pas soustraire les valeurs timestamps infinies" -#: utils/adt/timestamp.c:3751 utils/adt/timestamp.c:4260 utils/adt/timestamp.c:4427 utils/adt/timestamp.c:4448 +#: utils/adt/timestamp.c:3886 utils/adt/timestamp.c:4403 utils/adt/timestamp.c:4570 utils/adt/timestamp.c:4591 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "les unités timestamp « %s » ne sont pas supportées" -#: utils/adt/timestamp.c:3765 utils/adt/timestamp.c:4214 utils/adt/timestamp.c:4458 +#: utils/adt/timestamp.c:3900 utils/adt/timestamp.c:4357 utils/adt/timestamp.c:4601 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "les unité « %s » ne sont pas reconnues pour le type timestamp" -#: utils/adt/timestamp.c:3897 utils/adt/timestamp.c:4255 utils/adt/timestamp.c:4628 utils/adt/timestamp.c:4650 +#: utils/adt/timestamp.c:4032 utils/adt/timestamp.c:4398 utils/adt/timestamp.c:4771 utils/adt/timestamp.c:4793 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "" "les unités « %s » ne sont pas supportées pour le type « timestamp with time\n" "zone »" -#: utils/adt/timestamp.c:3914 utils/adt/timestamp.c:4209 utils/adt/timestamp.c:4659 +#: utils/adt/timestamp.c:4049 utils/adt/timestamp.c:4352 utils/adt/timestamp.c:4802 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "" "Les unités « %s » ne sont pas reconnues pour le type « timestamp with time\n" "zone »" -#: utils/adt/timestamp.c:3987 +#: utils/adt/timestamp.c:4130 #, c-format msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "unités d'intervalle « %s » non supporté car les mois ont généralement des semaines fractionnaires" -#: utils/adt/timestamp.c:3993 utils/adt/timestamp.c:4753 +#: utils/adt/timestamp.c:4136 utils/adt/timestamp.c:4896 #, c-format msgid "interval units \"%s\" not supported" msgstr "Les unités « %s » ne sont pas supportées pour le type interval" -#: utils/adt/timestamp.c:4009 utils/adt/timestamp.c:4776 +#: utils/adt/timestamp.c:4152 utils/adt/timestamp.c:4919 #, c-format msgid "interval units \"%s\" not recognized" msgstr "Les unités « %s » ne sont pas reconnues pour le type interval" @@ -21974,42 +22947,42 @@ msgstr "suppress_redundant_updates_trigger : doit être appelé pour chaque lign msgid "gtsvector_in not implemented" msgstr "gtsvector_in n'est pas encore implémenté" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "la distance dans l'opérateur de phrase ne devrait pas être plus que %d" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "erreur de syntaxe dans tsquery : « %s »" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "aucun opérande dans tsquery : « %s »" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "valeur trop importante dans tsquery : « %s »" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "l'opérande est trop long dans tsquery : « %s »" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "le mot est trop long dans tsquery : « %s »" -#: utils/adt/tsquery.c:642 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "la requête de recherche plein texte ne contient pas de lexemes : « %s »" -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "le champ tsquery est trop gros" @@ -22118,84 +23091,72 @@ msgstr "" msgid "column \"%s\" is not of a character type" msgstr "la colonne « %s » n'est pas de type caractère" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "erreur de syntaxe dans tsvector : « %s »" -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "il n'existe pas de caractères d'échappement : « %s »" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "mauvaise information de position dans tsvector : « %s »" #: utils/adt/txid.c:135 #, c-format -msgid "transaction ID " -msgstr "ID de transaction " +msgid "transaction ID %s is in the future" +msgstr "l'identifiant de transaction %s est dans le futur" #: utils/adt/txid.c:624 #, c-format msgid "invalid external txid_snapshot data" msgstr "valeur externe « txid_snapshot » invalide" -#: utils/adt/txid.c:758 utils/adt/txid.c:779 -msgid "in progress" -msgstr "en cours" - -#: utils/adt/txid.c:760 -msgid "committed" -msgstr "validé" - -#: utils/adt/txid.c:762 utils/adt/txid.c:777 -msgid "aborted" -msgstr "annulé" - -#: utils/adt/varbit.c:58 utils/adt/varchar.c:51 +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 #, c-format msgid "length for type %s must be at least 1" msgstr "la longueur du type %s doit être d'au moins 1" -#: utils/adt/varbit.c:63 utils/adt/varchar.c:55 +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 #, c-format msgid "length for type %s cannot exceed %d" msgstr "la longueur du type %s ne peut pas excéder %d" -#: utils/adt/varbit.c:164 utils/adt/varbit.c:476 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "la taille du tableau de bits dépasse le maximum permis (%d)" -#: utils/adt/varbit.c:178 utils/adt/varbit.c:321 utils/adt/varbit.c:378 +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "la longueur (en bits) de la chaîne %d ne doit pas correspondre au type bit(%d)" -#: utils/adt/varbit.c:200 utils/adt/varbit.c:512 +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "« %c » n'est pas un chiffre binaire valide" -#: utils/adt/varbit.c:225 utils/adt/varbit.c:537 +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "« %c » n'est pas un chiffre hexadécimal valide" -#: utils/adt/varbit.c:312 utils/adt/varbit.c:628 +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 #, c-format msgid "invalid length in external bit string" msgstr "longueur invalide dans la chaîne bit externe" -#: utils/adt/varbit.c:490 utils/adt/varbit.c:637 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "la chaîne bit est trop longue pour le type bit varying(%d)" -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:841 utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2881 utils/adt/varlena.c:2948 +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 utils/adt/varlena.c:2979 #, c-format msgid "negative substring length not allowed" msgstr "longueur de sous-chaîne négative non autorisée" @@ -22220,7 +23181,7 @@ msgstr "ne peut pas utiliser l'opérateur XOR sur des chaînes bit de tailles di msgid "bit index %d out of valid range (0..%d)" msgstr "index de bit %d en dehors des limites valides (0..%d)" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3140 +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 #, c-format msgid "new bit must be 0 or 1" msgstr "le nouveau bit doit valoir soit 0 soit 1" @@ -22235,77 +23196,77 @@ msgstr "valeur trop longue pour le type character(%d)" msgid "value too long for type character varying(%d)" msgstr "valeur trop longue pour le type character varying(%d)" -#: utils/adt/varlena.c:1416 utils/adt/varlena.c:1865 +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "n'a pas pu déterminer le collationnement à utiliser pour la comparaison de chaîne" -#: utils/adt/varlena.c:1473 utils/adt/varlena.c:1486 +#: utils/adt/varlena.c:1472 utils/adt/varlena.c:1485 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "n'a pas pu convertir la chaîne en UTF-16 : erreur %lu" -#: utils/adt/varlena.c:1501 +#: utils/adt/varlena.c:1500 #, c-format msgid "could not compare Unicode strings: %m" msgstr "n'a pas pu comparer les chaînes unicode : %m" -#: utils/adt/varlena.c:1556 utils/adt/varlena.c:2145 +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 #, c-format msgid "collation failed: %s" msgstr "échec du collationnement : %s" -#: utils/adt/varlena.c:2363 +#: utils/adt/varlena.c:2394 #, c-format msgid "sort key generation failed: %s" msgstr "échec de génération de la clé de tri : %s" -#: utils/adt/varlena.c:3026 utils/adt/varlena.c:3057 utils/adt/varlena.c:3092 utils/adt/varlena.c:3128 +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 utils/adt/varlena.c:3158 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "index %d en dehors des limites valides, 0..%d" -#: utils/adt/varlena.c:4059 +#: utils/adt/varlena.c:4201 #, c-format msgid "field position must be greater than zero" msgstr "la position du champ doit être plus grand que zéro" -#: utils/adt/varlena.c:4949 +#: utils/adt/varlena.c:5080 #, c-format msgid "unterminated format() type specifier" msgstr "spécificateur de type pour format() non terminé" -#: utils/adt/varlena.c:4950 utils/adt/varlena.c:5084 utils/adt/varlena.c:5205 +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Pour un unique \"%%\" utilisez \"%%%%\"." -#: utils/adt/varlena.c:5082 utils/adt/varlena.c:5203 +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 #, c-format msgid "unrecognized format() type specifier \"%c\"" msgstr "spécificateur de type « %c » pour format() non reconnu" -#: utils/adt/varlena.c:5095 utils/adt/varlena.c:5152 +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 #, c-format msgid "too few arguments for format()" msgstr "trop peu d'arguments pour format()" -#: utils/adt/varlena.c:5247 utils/adt/varlena.c:5430 +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 #, c-format msgid "number is out of range" msgstr "le nombre est en dehors des limites" -#: utils/adt/varlena.c:5311 utils/adt/varlena.c:5339 +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "le format indique l'argument 0 mais les arguments sont numérotés à partir de 1" -#: utils/adt/varlena.c:5332 +#: utils/adt/varlena.c:5463 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "la position de l'argument width doit se terminer par « $ »" -#: utils/adt/varlena.c:5377 +#: utils/adt/varlena.c:5508 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "les valeurs NULL ne peuvent pas être formatés comme un identifiant SQL" @@ -22320,74 +23281,74 @@ msgstr "l'argument de ntile doit être supérieur à zéro" msgid "argument of nth_value must be greater than zero" msgstr "l'argument de nth_value doit être supérieur à zéro" -#: utils/adt/xml.c:220 +#: utils/adt/xml.c:221 #, c-format msgid "unsupported XML feature" msgstr "fonctionnalité XML non supportée" -#: utils/adt/xml.c:221 +#: utils/adt/xml.c:222 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "Cette fonctionnalité nécessite que le serveur dispose du support de libxml." -#: utils/adt/xml.c:222 +#: utils/adt/xml.c:223 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "Vous devez recompiler PostgreSQL en utilisant --with-libxml." -#: utils/adt/xml.c:241 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:242 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "nom d'encodage « %s » invalide" -#: utils/adt/xml.c:484 utils/adt/xml.c:489 +#: utils/adt/xml.c:485 utils/adt/xml.c:490 #, c-format msgid "invalid XML comment" msgstr "commentaire XML invalide" -#: utils/adt/xml.c:618 +#: utils/adt/xml.c:619 #, c-format msgid "not an XML document" msgstr "pas un document XML" -#: utils/adt/xml.c:777 utils/adt/xml.c:800 +#: utils/adt/xml.c:778 utils/adt/xml.c:801 #, c-format msgid "invalid XML processing instruction" msgstr "instruction de traitement XML invalide" -#: utils/adt/xml.c:778 +#: utils/adt/xml.c:779 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "le nom de cible de l'instruction de traitement XML ne peut pas être « %s »." -#: utils/adt/xml.c:801 +#: utils/adt/xml.c:802 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "l'instruction de traitement XML ne peut pas contenir « ?> »." -#: utils/adt/xml.c:880 +#: utils/adt/xml.c:881 #, c-format msgid "xmlvalidate is not implemented" msgstr "xmlvalidate n'est pas implémenté" -#: utils/adt/xml.c:959 +#: utils/adt/xml.c:960 #, c-format msgid "could not initialize XML library" msgstr "n'a pas pu initialiser la bibliothèque XML" -#: utils/adt/xml.c:960 +#: utils/adt/xml.c:961 #, c-format msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "" "libxml2 a un type de caractère incompatible : sizeof(char)=%u,\n" "sizeof(xmlChar)=%u." -#: utils/adt/xml.c:1046 +#: utils/adt/xml.c:1047 #, c-format msgid "could not set up XML error handler" msgstr "n'a pas pu configurer le gestionnaire d'erreurs XML" -#: utils/adt/xml.c:1047 +#: utils/adt/xml.c:1048 #, c-format msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." msgstr "" @@ -22395,182 +23356,182 @@ msgstr "" "n'est pas compatible avec les fichiers d'en-tête de libxml2 avec lesquels\n" "PostgreSQL a été construit." -#: utils/adt/xml.c:1797 +#: utils/adt/xml.c:1905 msgid "Invalid character value." msgstr "Valeur invalide pour le caractère." -#: utils/adt/xml.c:1800 +#: utils/adt/xml.c:1908 msgid "Space required." msgstr "Espace requis." -#: utils/adt/xml.c:1803 +#: utils/adt/xml.c:1911 msgid "standalone accepts only 'yes' or 'no'." msgstr "la version autonome accepte seulement 'yes' et 'no'." -#: utils/adt/xml.c:1806 +#: utils/adt/xml.c:1914 msgid "Malformed declaration: missing version." msgstr "Déclaration mal formée : version manquante." -#: utils/adt/xml.c:1809 +#: utils/adt/xml.c:1917 msgid "Missing encoding in text declaration." msgstr "Encodage manquant dans la déclaration du texte." -#: utils/adt/xml.c:1812 +#: utils/adt/xml.c:1920 msgid "Parsing XML declaration: '?>' expected." msgstr "Analyse de la déclaration XML : « ?> » attendu." -#: utils/adt/xml.c:1815 +#: utils/adt/xml.c:1923 #, c-format msgid "Unrecognized libxml error code: %d." msgstr "code d'erreur libxml inconnu : %d" -#: utils/adt/xml.c:2090 +#: utils/adt/xml.c:2198 #, c-format msgid "XML does not support infinite date values." msgstr "XML ne supporte pas les valeurs infinies de date." -#: utils/adt/xml.c:2112 utils/adt/xml.c:2139 +#: utils/adt/xml.c:2220 utils/adt/xml.c:2247 #, c-format msgid "XML does not support infinite timestamp values." msgstr "XML ne supporte pas les valeurs infinies de timestamp." -#: utils/adt/xml.c:2551 +#: utils/adt/xml.c:2659 #, c-format msgid "invalid query" msgstr "requête invalide" -#: utils/adt/xml.c:3870 +#: utils/adt/xml.c:3982 #, c-format msgid "invalid array for XML namespace mapping" msgstr "tableau invalide pour la correspondance de l'espace de nom XML" -#: utils/adt/xml.c:3871 +#: utils/adt/xml.c:3983 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "" "Le tableau doit avoir deux dimensions avec une longueur de 2 pour le\n" "deuxième axe." -#: utils/adt/xml.c:3895 +#: utils/adt/xml.c:4007 #, c-format msgid "empty XPath expression" msgstr "expression XPath vide" -#: utils/adt/xml.c:3939 +#: utils/adt/xml.c:4059 #, c-format msgid "neither namespace name nor URI may be null" msgstr "ni le nom de l'espace de noms ni l'URI ne peuvent être NULL" -#: utils/adt/xml.c:3946 +#: utils/adt/xml.c:4066 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "n'a pas pu enregistrer l'espace de noms XML de nom « %s » et d'URI « %s »" -#: utils/adt/xml.c:4300 +#: utils/adt/xml.c:4417 #, c-format msgid "DEFAULT namespace is not supported" msgstr "l'espace de nom DEFAULT n'est pas supporté" -#: utils/adt/xml.c:4329 +#: utils/adt/xml.c:4446 #, c-format msgid "row path filter must not be empty string" msgstr "le filtre du chemin de ligne ne doit pas être une chaîne vide" -#: utils/adt/xml.c:4360 +#: utils/adt/xml.c:4477 #, c-format msgid "column path filter must not be empty string" msgstr "le filtre du chemin de colonne ne doit pas être une chaîne vide" -#: utils/adt/xml.c:4542 +#: utils/adt/xml.c:4663 #, c-format msgid "more than one value returned by column XPath expression" msgstr "plus d'une valeur renvoyée par l'expression XPath de colonne" -#: utils/cache/lsyscache.c:2612 utils/cache/lsyscache.c:2645 utils/cache/lsyscache.c:2678 utils/cache/lsyscache.c:2711 +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "le type %s est seulement un shell" -#: utils/cache/lsyscache.c:2617 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "aucune fonction en entrée disponible pour le type %s" -#: utils/cache/lsyscache.c:2650 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "aucune fonction en sortie disponible pour le type %s" -#: utils/cache/plancache.c:722 +#: utils/cache/partcache.c:201 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "la classe d'opérateur « %s » de la méthode d'accès %s nécessite la fonction de support manquante %d pour le type %s" + +#: utils/cache/plancache.c:723 #, c-format msgid "cached plan must not change result type" msgstr "le plan en cache ne doit pas modifier le type en résultat" -#: utils/cache/relcache.c:5795 +#: utils/cache/relcache.c:5806 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "n'a pas pu créer le fichier d'initialisation relation-cache « %s » : %m" -#: utils/cache/relcache.c:5797 +#: utils/cache/relcache.c:5808 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Continue malgré tout, mais quelque chose s'est mal passé." -#: utils/cache/relcache.c:6067 +#: utils/cache/relcache.c:6162 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "n'a pas pu supprimer le fichier cache « %s » : %m" -#: utils/cache/relmapper.c:509 +#: utils/cache/relmapper.c:513 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "" "ne peut pas préparer (PREPARE) une transaction qui a modifié la correspondance\n" "de relation" -#: utils/cache/relmapper.c:652 utils/cache/relmapper.c:754 +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 #, c-format msgid "could not open relation mapping file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier de correspondance des relations « %s » : %m" -#: utils/cache/relmapper.c:666 +#: utils/cache/relmapper.c:669 #, c-format msgid "could not read relation mapping file \"%s\": %m" msgstr "n'a pas pu lire le fichier de correspondance des relations « %s » : %m" -#: utils/cache/relmapper.c:677 +#: utils/cache/relmapper.c:680 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "le fichier de correspondance des relations « %s » contient des données invalides" -#: utils/cache/relmapper.c:687 +#: utils/cache/relmapper.c:690 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "" "le fichier de correspondance des relations « %s » contient une somme de\n" "contrôle incorrecte" -#: utils/cache/relmapper.c:788 +#: utils/cache/relmapper.c:789 #, c-format msgid "could not write to relation mapping file \"%s\": %m" msgstr "n'a pas pu écrire le fichier de correspondance des relations « %s » : %m" -#: utils/cache/relmapper.c:803 +#: utils/cache/relmapper.c:804 #, c-format msgid "could not fsync relation mapping file \"%s\": %m" msgstr "n'a pas pu synchroniser (fsync) le fichier de correspondance des relations « %s » : %m" -#: utils/cache/relmapper.c:810 +#: utils/cache/relmapper.c:811 #, c-format msgid "could not close relation mapping file \"%s\": %m" msgstr "n'a pas pu fermer le fichier de correspondance des relations « %s » : %m" -#: utils/cache/typcache.c:1223 -#, c-format -msgid "type %s is not composite" -msgstr "le type %s n'est pas un type composite" - -#: utils/cache/typcache.c:1237 +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 #, c-format msgid "record type has not been registered" msgstr "le type d'enregistrement n'a pas été enregistré" @@ -22585,102 +23546,102 @@ msgstr "TRAP : ExceptionalCondition : mauvais arguments\n" msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" msgstr "TRAP : %s(« %s », fichier : « %s », ligne : %d)\n" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/error/elog.c:322 utils/error/elog.c:1304 #, c-format msgid "error occurred at %s:%d before error message processing is available\n" msgstr "" "erreur survenue à %s:%d avant que le traitement des messages d'erreurs ne\n" "soit disponible\n" -#: utils/error/elog.c:1889 +#: utils/error/elog.c:1882 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" msgstr "n'a pas pu ré-ouvrir le fichier « %s » comme stderr : %m" -#: utils/error/elog.c:1902 +#: utils/error/elog.c:1895 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" msgstr "n'a pas pu ré-ouvrir le fichier « %s » comme stdout : %m" -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 +#: utils/error/elog.c:2387 utils/error/elog.c:2404 utils/error/elog.c:2420 msgid "[unknown]" msgstr "[inconnu]" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 +#: utils/error/elog.c:2880 utils/error/elog.c:3183 utils/error/elog.c:3291 msgid "missing error text" msgstr "texte d'erreur manquant" -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 utils/error/elog.c:3299 +#: utils/error/elog.c:2883 utils/error/elog.c:2886 utils/error/elog.c:3294 utils/error/elog.c:3297 #, c-format msgid " at character %d" msgstr " au caractère %d" -#: utils/error/elog.c:2898 utils/error/elog.c:2905 +#: utils/error/elog.c:2896 utils/error/elog.c:2903 msgid "DETAIL: " msgstr "DÉTAIL: " -#: utils/error/elog.c:2912 +#: utils/error/elog.c:2910 msgid "HINT: " msgstr "ASTUCE : " -#: utils/error/elog.c:2919 +#: utils/error/elog.c:2917 msgid "QUERY: " msgstr "REQUÊTE : " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2924 msgid "CONTEXT: " msgstr "CONTEXTE : " -#: utils/error/elog.c:2936 +#: utils/error/elog.c:2934 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "EMPLACEMENT : %s, %s:%d\n" -#: utils/error/elog.c:2943 +#: utils/error/elog.c:2941 #, c-format msgid "LOCATION: %s:%d\n" msgstr "EMPLACEMENT : %s:%d\n" -#: utils/error/elog.c:2957 +#: utils/error/elog.c:2955 msgid "STATEMENT: " msgstr "INSTRUCTION : " #. translator: This string will be truncated at 47 #. characters expanded. -#: utils/error/elog.c:3414 +#: utils/error/elog.c:3412 #, c-format msgid "operating system error %d" msgstr "erreur %d du système d'exploitation" -#: utils/error/elog.c:3612 +#: utils/error/elog.c:3610 msgid "DEBUG" msgstr "DEBUG" -#: utils/error/elog.c:3616 +#: utils/error/elog.c:3614 msgid "LOG" msgstr "LOG" -#: utils/error/elog.c:3619 +#: utils/error/elog.c:3617 msgid "INFO" msgstr "INFO" -#: utils/error/elog.c:3622 +#: utils/error/elog.c:3620 msgid "NOTICE" msgstr "NOTICE" -#: utils/error/elog.c:3625 +#: utils/error/elog.c:3623 msgid "WARNING" msgstr "ATTENTION" -#: utils/error/elog.c:3628 +#: utils/error/elog.c:3626 msgid "ERROR" msgstr "ERREUR" -#: utils/error/elog.c:3631 +#: utils/error/elog.c:3629 msgid "FATAL" msgstr "FATAL" -#: utils/error/elog.c:3634 +#: utils/error/elog.c:3632 msgid "PANIC" msgstr "PANIC" @@ -22689,11 +23650,6 @@ msgstr "PANIC" msgid "could not find function \"%s\" in file \"%s\"" msgstr "n'a pas pu trouver la fonction « %s » dans le fichier « %s »" -#: utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 utils/fmgr/dfmgr.c:466 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "n'a pas pu accéder au fichier « %s » : %m" - #: utils/fmgr/dfmgr.c:239 #, c-format msgid "could not load library \"%s\": %s" @@ -22775,373 +23731,395 @@ msgstr "composant de longueur zéro dans le paramètre « dynamic_library_path msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "Un composant du paramètre « dynamic_library_path » n'est pas un chemin absolu" -#: utils/fmgr/fmgr.c:239 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "la fonction interne « %s » n'est pas dans une table de recherche interne" -#: utils/fmgr/fmgr.c:399 +#: utils/fmgr/fmgr.c:485 #, c-format msgid "could not find function information for function \"%s\"" msgstr "n'a pas pu trouver d'informations sur la fonction « %s »" -#: utils/fmgr/fmgr.c:401 +#: utils/fmgr/fmgr.c:487 #, c-format msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." msgstr "Les fonctions appelables en SQL ont besoin d'un PG_FUNCTION_INFO_V1(nom_fonction)." -#: utils/fmgr/fmgr.c:419 +#: utils/fmgr/fmgr.c:505 #, c-format msgid "unrecognized API version %d reported by info function \"%s\"" msgstr "version API %d non reconnue mais rapportée par la fonction info « %s »" -#: utils/fmgr/fmgr.c:2132 +#: utils/fmgr/fmgr.c:2210 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "fonction %u de validation du langage appelée pour le langage %u au lieu de %u" -#: utils/fmgr/funcapi.c:354 +#: utils/fmgr/funcapi.c:358 #, c-format msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "" "n'a pas pu déterminer le type du résultat actuel pour la fonction « %s »\n" "déclarant retourner le type %s" -#: utils/fmgr/funcapi.c:1341 utils/fmgr/funcapi.c:1372 +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 #, c-format msgid "number of aliases does not match number of columns" msgstr "le nombre d'alias ne correspond pas au nombre de colonnes" -#: utils/fmgr/funcapi.c:1366 +#: utils/fmgr/funcapi.c:1429 #, c-format msgid "no column alias was provided" msgstr "aucun alias de colonne n'a été fourni" -#: utils/fmgr/funcapi.c:1390 +#: utils/fmgr/funcapi.c:1453 #, c-format msgid "could not determine row description for function returning record" msgstr "" "n'a pas pu déterminer la description de la ligne pour la fonction renvoyant\n" "l'enregistrement" -#: utils/init/miscinit.c:123 +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "le répertoire des données « %s » n'existe pas" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "n'a pas pu lire les droits du répertoire « %s » : %m" + +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "le répertoire des données « %s » n'est pas un répertoire" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "le répertoire des données « %s » a un mauvais propriétaire" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "" +"Le serveur doit être en cours d'exécution par l'utilisateur qui possède le\n" +"répertoire des données." + +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "le répertoire des données « %s » a des permissions non valides" + +#: utils/init/miscinit.c:159 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Les droits devraient être u=rwx (0700) ou u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:218 #, c-format msgid "could not change directory to \"%s\": %m" msgstr "n'a pas pu modifier le répertoire par « %s » : %m" -#: utils/init/miscinit.c:451 utils/misc/guc.c:6126 +#: utils/init/miscinit.c:554 utils/misc/guc.c:6374 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "" "ne peut pas configurer le paramètre « %s » à l'intérieur d'une fonction\n" "restreinte pour sécurité" -#: utils/init/miscinit.c:512 +#: utils/init/miscinit.c:615 #, c-format msgid "role with OID %u does not exist" msgstr "le rôle d'OID %u n'existe pas" -#: utils/init/miscinit.c:542 +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "le rôle « %s » n'est pas autorisé à se connecter" -#: utils/init/miscinit.c:560 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "trop de connexions pour le rôle « %s »" -#: utils/init/miscinit.c:620 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "droit refusé pour initialiser une autorisation de session" -#: utils/init/miscinit.c:703 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "OID du rôle invalide : %u" -#: utils/init/miscinit.c:757 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "le système de base de données est arrêté" -#: utils/init/miscinit.c:844 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "n'a pas pu créer le fichier verrou « %s » : %m" -#: utils/init/miscinit.c:858 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "n'a pas pu ouvrir le fichier verrou « %s » : %m" -#: utils/init/miscinit.c:865 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "n'a pas pu lire le fichier verrou « %s » : %m" -#: utils/init/miscinit.c:874 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "le fichier verrou « %s » est vide" -#: utils/init/miscinit.c:875 +#: utils/init/miscinit.c:978 #, c-format msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." msgstr "Soit un autre serveur est en cours de démarrage, soit le fichier verrou est un reste d'un précédent crash au démarrage du serveur" -#: utils/init/miscinit.c:922 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "le fichier verrou « %s » existe déjà" -#: utils/init/miscinit.c:926 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "" "Un autre postgres (de PID %d) est-il déjà lancé avec comme répertoire de\n" "données « %s » ?" -#: utils/init/miscinit.c:928 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "" "Un autre postmaster (de PID %d) est-il déjà lancé avec comme répertoire de\n" "données « %s » ?" -#: utils/init/miscinit.c:931 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "Un autre postgres (de PID %d) est-il déjà lancé en utilisant la socket « %s » ?" -#: utils/init/miscinit.c:933 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "Un autre postmaster (de PID %d) est-il déjà lancé en utilisant la socket « %s » ?" -#: utils/init/miscinit.c:969 -#, c-format -msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" -msgstr "" -"le bloc de mémoire partagé pré-existant (clé %lu, ID %lu) est en cours\n" -"d'utilisation" - -#: utils/init/miscinit.c:972 -#, c-format -msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." -msgstr "" -"Si vous êtes sûr qu'aucun processus serveur n'est toujours en cours\n" -"d'exécution, supprimez le bloc de mémoire partagée\n" -"ou supprimez simplement le fichier « %s »." - -#: utils/init/miscinit.c:988 +#: utils/init/miscinit.c:1084 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "n'a pas pu supprimer le vieux fichier verrou « %s » : %m" -#: utils/init/miscinit.c:990 +#: utils/init/miscinit.c:1086 #, c-format msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "" "Le fichier semble avoir été oublié accidentellement mais il ne peut pas être\n" "supprimé. Merci de supprimer ce fichier manuellement et de ré-essayer." -#: utils/init/miscinit.c:1027 utils/init/miscinit.c:1041 utils/init/miscinit.c:1052 +#: utils/init/miscinit.c:1123 utils/init/miscinit.c:1137 utils/init/miscinit.c:1148 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "n'a pas pu écrire le fichier verrou « %s » : %m" -#: utils/init/miscinit.c:1184 utils/init/miscinit.c:1327 utils/misc/guc.c:8931 +#: utils/init/miscinit.c:1280 utils/init/miscinit.c:1423 utils/misc/guc.c:9215 #, c-format msgid "could not read from file \"%s\": %m" msgstr "n'a pas pu lire à partir du fichier « %s » : %m" -#: utils/init/miscinit.c:1315 +#: utils/init/miscinit.c:1411 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "n'a pas pu ouvrir le fichier « %s » : %m ; poursuite du traitement" -#: utils/init/miscinit.c:1340 +#: utils/init/miscinit.c:1436 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "le fichier de verrou « %s » contient le mauvais PID : %ld au lieu de %ld" -#: utils/init/miscinit.c:1379 utils/init/miscinit.c:1395 +#: utils/init/miscinit.c:1475 utils/init/miscinit.c:1491 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "« %s » n'est pas un répertoire de données valide" -#: utils/init/miscinit.c:1381 +#: utils/init/miscinit.c:1477 #, c-format msgid "File \"%s\" is missing." msgstr "le fichier « %s » est manquant." -#: utils/init/miscinit.c:1397 +#: utils/init/miscinit.c:1493 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "le fichier « %s » ne contient aucune données valides." -#: utils/init/miscinit.c:1399 +#: utils/init/miscinit.c:1495 #, c-format msgid "You might need to initdb." msgstr "Vous pouvez avoir besoin d'exécuter initdb." -#: utils/init/miscinit.c:1407 +#: utils/init/miscinit.c:1503 #, c-format msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." msgstr "" "Le répertoire des données a été initialisé avec PostgreSQL version %s,\n" "qui est non compatible avec cette version %s." -#: utils/init/miscinit.c:1474 +#: utils/init/miscinit.c:1570 #, c-format msgid "loaded library \"%s\"" msgstr "bibliothèque « %s » chargée" -#: utils/init/postinit.c:251 +#: utils/init/postinit.c:252 #, c-format -msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "connexion autorisée : utilisateur=%s, SSL activé (protocole=%s, chiffrement=%s, compression=%s)" +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "connexion autorisée : utilisateur=%s, SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "off" msgstr "désactivé" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "on" msgstr "activé" -#: utils/init/postinit.c:257 +#: utils/init/postinit.c:261 #, c-format msgid "replication connection authorized: user=%s" msgstr "connexion de réplication autorisée : utilisateur=%s" -#: utils/init/postinit.c:265 +#: utils/init/postinit.c:269 #, c-format -msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "connexion autorisée : utilisateur=%s, base de données=%s, SSL activé (protocole=%s, chiffrement=%s, compression=%s)" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "connexion autorisée : utilisateur=%s, base de données=%s, SSL activé (protocole=%s, chiffrement=%s, bits=%d, compression=%s)" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:278 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "connexion autorisée : utilisateur=%s, base de données=%s" -#: utils/init/postinit.c:303 +#: utils/init/postinit.c:310 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "la base de données « %s » a disparu de pg_database" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:312 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "La base de données d'OID %u semble maintenant appartenir à « %s »." -#: utils/init/postinit.c:325 +#: utils/init/postinit.c:332 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "la base de données « %s » n'accepte plus les connexions" -#: utils/init/postinit.c:338 +#: utils/init/postinit.c:345 #, c-format msgid "permission denied for database \"%s\"" msgstr "droit refusé pour la base de données « %s »" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:346 #, c-format msgid "User does not have CONNECT privilege." msgstr "L'utilisateur n'a pas le droit CONNECT." -#: utils/init/postinit.c:356 +#: utils/init/postinit.c:363 #, c-format msgid "too many connections for database \"%s\"" msgstr "trop de connexions pour la base de données « %s »" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format msgid "database locale is incompatible with operating system" msgstr "la locale de la base de données est incompatible avec le système d'exploitation" -#: utils/init/postinit.c:379 +#: utils/init/postinit.c:386 #, c-format msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." msgstr "" "La base de données a été initialisée avec un LC_COLLATE à « %s »,\n" "qui n'est pas reconnu par setlocale()." -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "" "Recréez la base de données avec une autre locale ou installez la locale\n" "manquante." -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:393 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "" "La base de données a été initialisée avec un LC_CTYPE à « %s »,\n" "qui n'est pas reconnu par setlocale()." -#: utils/init/postinit.c:719 +#: utils/init/postinit.c:728 #, c-format msgid "no roles are defined in this database system" msgstr "aucun rôle n'est défini dans le système de bases de données" -#: utils/init/postinit.c:720 +#: utils/init/postinit.c:729 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Vous devez immédiatement exécuter « CREATE USER \"%s\" CREATEUSER; »." -#: utils/init/postinit.c:756 +#: utils/init/postinit.c:765 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "" "les nouvelles connexions pour la réplication ne sont pas autorisées pendant\n" "l'arrêt du serveur de base de données" -#: utils/init/postinit.c:760 +#: utils/init/postinit.c:769 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "" "doit être super-utilisateur pour se connecter pendant un arrêt de la base de\n" "données" -#: utils/init/postinit.c:770 +#: utils/init/postinit.c:779 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "doit être super-utilisateur pour se connecter en mode de mise à jour binaire" -#: utils/init/postinit.c:784 +#: utils/init/postinit.c:793 #, c-format msgid "remaining connection slots are reserved for non-replication superuser connections" msgstr "" "les emplacements de connexions restants sont réservés pour les connexions\n" "superutilisateur non relatif à la réplication" -#: utils/init/postinit.c:794 +#: utils/init/postinit.c:803 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "" "doit être un superutilisateur ou un rôle ayant l'attribut de réplication\n" "pour exécuter walsender" -#: utils/init/postinit.c:863 +#: utils/init/postinit.c:872 #, c-format msgid "database %u does not exist" msgstr "la base de données « %u » n'existe pas" -#: utils/init/postinit.c:952 +#: utils/init/postinit.c:961 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Cet objet semble avoir été tout juste supprimé ou renommé." -#: utils/init/postinit.c:970 +#: utils/init/postinit.c:979 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "Le sous-répertoire de la base de données « %s » est manquant." -#: utils/init/postinit.c:975 +#: utils/init/postinit.c:984 #, c-format msgid "could not access directory \"%s\": %m" msgstr "n'a pas pu accéder au répertoire « %s » : %m" @@ -23171,39 +24149,39 @@ msgstr "encodage « %s » non supporté par ICU" msgid "encoding name too long" msgstr "nom d'encodage trop long" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "la conversion entre %s et %s n'est pas supportée" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "" "la fonction de conversion par défaut pour l'encodage de « %s » en « %s »\n" "n'existe pas" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "Une chaîne de %d octets est trop longue pour la conversion d'encodage." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "nom de l'encodage source « %s » invalide" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "nom de l'encodage destination « %s » invalide" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "valeur d'octet invalide pour l'encodage « %s » : 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "échec de bind_textdomain_codeset" @@ -23220,289 +24198,321 @@ msgstr "" "le caractère dont la séquence d'octets est %s dans l'encodage « %s » n'a pas\n" "d'équivalent dans l'encodage « %s »" -#: utils/misc/guc.c:570 +#: utils/misc/guc.c:572 msgid "Ungrouped" msgstr "Dégroupé" -#: utils/misc/guc.c:572 +#: utils/misc/guc.c:574 msgid "File Locations" msgstr "Emplacement des fichiers" -#: utils/misc/guc.c:574 +#: utils/misc/guc.c:576 msgid "Connections and Authentication" msgstr "Connexions et authentification" -#: utils/misc/guc.c:576 +#: utils/misc/guc.c:578 msgid "Connections and Authentication / Connection Settings" msgstr "Connexions et authentification / Paramètrages de connexion" -#: utils/misc/guc.c:578 -msgid "Connections and Authentication / Security and Authentication" -msgstr "Connexions et authentification / Sécurité et authentification" - #: utils/misc/guc.c:580 +msgid "Connections and Authentication / Authentication" +msgstr "Connexions et authentification / Authentification" + +#: utils/misc/guc.c:582 +msgid "Connections and Authentication / SSL" +msgstr "Connexions et authentification / SSL" + +#: utils/misc/guc.c:584 msgid "Resource Usage" msgstr "Utilisation des ressources" -#: utils/misc/guc.c:582 +#: utils/misc/guc.c:586 msgid "Resource Usage / Memory" msgstr "Utilisation des ressources / Mémoire" -#: utils/misc/guc.c:584 +#: utils/misc/guc.c:588 msgid "Resource Usage / Disk" msgstr "Utilisation des ressources / Disques" -#: utils/misc/guc.c:586 +#: utils/misc/guc.c:590 msgid "Resource Usage / Kernel Resources" msgstr "Utilisation des ressources / Ressources noyau" -#: utils/misc/guc.c:588 +#: utils/misc/guc.c:592 msgid "Resource Usage / Cost-Based Vacuum Delay" msgstr "Utilisation des ressources / Délai du VACUUM basé sur le coût" -#: utils/misc/guc.c:590 +#: utils/misc/guc.c:594 msgid "Resource Usage / Background Writer" msgstr "Utilisation des ressources / Processus d'écriture en tâche de fond" -#: utils/misc/guc.c:592 +#: utils/misc/guc.c:596 msgid "Resource Usage / Asynchronous Behavior" msgstr "Utilisation des ressources / Comportement asynchrone" -#: utils/misc/guc.c:594 +#: utils/misc/guc.c:598 msgid "Write-Ahead Log" msgstr "Write-Ahead Log" -#: utils/misc/guc.c:596 +#: utils/misc/guc.c:600 msgid "Write-Ahead Log / Settings" msgstr "Write-Ahead Log / Paramètrages" -#: utils/misc/guc.c:598 +#: utils/misc/guc.c:602 msgid "Write-Ahead Log / Checkpoints" msgstr "Write-Ahead Log / Points de vérification (Checkpoints)" -#: utils/misc/guc.c:600 +#: utils/misc/guc.c:604 msgid "Write-Ahead Log / Archiving" msgstr "Write-Ahead Log / Archivage" -#: utils/misc/guc.c:602 +#: utils/misc/guc.c:606 msgid "Replication" msgstr "Réplication" -#: utils/misc/guc.c:604 +#: utils/misc/guc.c:608 msgid "Replication / Sending Servers" msgstr "Réplication / Serveurs d'envoi" -#: utils/misc/guc.c:606 +#: utils/misc/guc.c:610 msgid "Replication / Master Server" msgstr "Réplication / Serveur maître" -#: utils/misc/guc.c:608 +#: utils/misc/guc.c:612 msgid "Replication / Standby Servers" msgstr "Réplication / Serveurs en attente" -#: utils/misc/guc.c:610 +#: utils/misc/guc.c:614 msgid "Replication / Subscribers" msgstr "Réplication / Abonnés" -#: utils/misc/guc.c:612 +#: utils/misc/guc.c:616 msgid "Query Tuning" msgstr "Optimisation des requêtes" -#: utils/misc/guc.c:614 +#: utils/misc/guc.c:618 msgid "Query Tuning / Planner Method Configuration" msgstr "Optimisation des requêtes / Configuration de la méthode du planificateur" -#: utils/misc/guc.c:616 +#: utils/misc/guc.c:620 msgid "Query Tuning / Planner Cost Constants" msgstr "Optimisation des requêtes / Constantes des coûts du planificateur" -#: utils/misc/guc.c:618 +#: utils/misc/guc.c:622 msgid "Query Tuning / Genetic Query Optimizer" msgstr "Optimisation des requêtes / Optimiseur génétique de requêtes" -#: utils/misc/guc.c:620 +#: utils/misc/guc.c:624 msgid "Query Tuning / Other Planner Options" msgstr "Optimisation des requêtes / Autres options du planificateur" -#: utils/misc/guc.c:622 +#: utils/misc/guc.c:626 msgid "Reporting and Logging" msgstr "Rapports et traces" -#: utils/misc/guc.c:624 +#: utils/misc/guc.c:628 msgid "Reporting and Logging / Where to Log" msgstr "Rapports et traces / Où tracer" -#: utils/misc/guc.c:626 +#: utils/misc/guc.c:630 msgid "Reporting and Logging / When to Log" msgstr "Rapports et traces / Quand tracer" -#: utils/misc/guc.c:628 +#: utils/misc/guc.c:632 msgid "Reporting and Logging / What to Log" msgstr "Rapports et traces / Que tracer" -#: utils/misc/guc.c:630 +#: utils/misc/guc.c:634 msgid "Process Title" msgstr "Titre du processus" -#: utils/misc/guc.c:632 +#: utils/misc/guc.c:636 msgid "Statistics" msgstr "Statistiques" -#: utils/misc/guc.c:634 +#: utils/misc/guc.c:638 msgid "Statistics / Monitoring" msgstr "Statistiques / Surveillance" -#: utils/misc/guc.c:636 +#: utils/misc/guc.c:640 msgid "Statistics / Query and Index Statistics Collector" msgstr "Statistiques / Récupérateur des statistiques sur les requêtes et sur les index" -#: utils/misc/guc.c:638 +#: utils/misc/guc.c:642 msgid "Autovacuum" msgstr "Autovacuum" -#: utils/misc/guc.c:640 +#: utils/misc/guc.c:644 msgid "Client Connection Defaults" msgstr "Valeurs par défaut pour les connexions client" -#: utils/misc/guc.c:642 +#: utils/misc/guc.c:646 msgid "Client Connection Defaults / Statement Behavior" msgstr "Valeurs par défaut pour les connexions client / Comportement des instructions" -#: utils/misc/guc.c:644 +#: utils/misc/guc.c:648 msgid "Client Connection Defaults / Locale and Formatting" msgstr "Valeurs par défaut pour les connexions client / Locale et formattage" -#: utils/misc/guc.c:646 +#: utils/misc/guc.c:650 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "Valeurs par défaut pour les connexions des clients / Préchargement des bibliothèques partagées" -#: utils/misc/guc.c:648 +#: utils/misc/guc.c:652 msgid "Client Connection Defaults / Other Defaults" msgstr "Valeurs par défaut pour les connexions client / Autres valeurs par défaut" -#: utils/misc/guc.c:650 +#: utils/misc/guc.c:654 msgid "Lock Management" msgstr "Gestion des verrous" -#: utils/misc/guc.c:652 +#: utils/misc/guc.c:656 msgid "Version and Platform Compatibility" msgstr "Compatibilité des versions et des plateformes" -#: utils/misc/guc.c:654 +#: utils/misc/guc.c:658 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "Compatibilité des versions et des plateformes / Anciennes versions de PostgreSQL" -#: utils/misc/guc.c:656 +#: utils/misc/guc.c:660 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "Compatibilité des versions et des plateformes / Anciennes plateformes et anciens clients" -#: utils/misc/guc.c:658 +#: utils/misc/guc.c:662 msgid "Error Handling" msgstr "Gestion des erreurs" -#: utils/misc/guc.c:660 +#: utils/misc/guc.c:664 msgid "Preset Options" msgstr "Options pré-configurées" -#: utils/misc/guc.c:662 +#: utils/misc/guc.c:666 msgid "Customized Options" msgstr "Options personnalisées" -#: utils/misc/guc.c:664 +#: utils/misc/guc.c:668 msgid "Developer Options" msgstr "Options pour le développeur" -#: utils/misc/guc.c:721 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "Les unités valides pour ce paramètre sont « kB », « MB », « GB » et « TB »." +#: utils/misc/guc.c:722 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Les unités valides pour ce paramètre sont « B », « kB », « MB », « GB » et « TB »." -#: utils/misc/guc.c:748 +#: utils/misc/guc.c:764 msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." msgstr "" "Les unités valides pour ce paramètre sont « ms », « s », « min », « h » et\n" "« d »." -#: utils/misc/guc.c:807 +#: utils/misc/guc.c:823 msgid "Enables the planner's use of sequential-scan plans." msgstr "Active l'utilisation des parcours séquentiels par le planificateur." -#: utils/misc/guc.c:816 +#: utils/misc/guc.c:832 msgid "Enables the planner's use of index-scan plans." msgstr "Active l'utilisation des parcours d'index par le planificateur." -#: utils/misc/guc.c:825 +#: utils/misc/guc.c:841 msgid "Enables the planner's use of index-only-scan plans." msgstr "Active l'utilisation des parcours d'index seul par le planificateur." -#: utils/misc/guc.c:834 +#: utils/misc/guc.c:850 msgid "Enables the planner's use of bitmap-scan plans." msgstr "Active l'utilisation des parcours de bitmap par le planificateur." -#: utils/misc/guc.c:843 +#: utils/misc/guc.c:859 msgid "Enables the planner's use of TID scan plans." msgstr "Active l'utilisation de plans de parcours TID par le planificateur." -#: utils/misc/guc.c:852 +#: utils/misc/guc.c:868 msgid "Enables the planner's use of explicit sort steps." msgstr "Active l'utilisation des étapes de tris explicites par le planificateur." -#: utils/misc/guc.c:861 +#: utils/misc/guc.c:877 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Active l'utilisation de plans d'agrégats hâchés par le planificateur." -#: utils/misc/guc.c:870 +#: utils/misc/guc.c:886 msgid "Enables the planner's use of materialization." msgstr "Active l'utilisation de la matérialisation par le planificateur." -#: utils/misc/guc.c:879 +#: utils/misc/guc.c:895 msgid "Enables the planner's use of nested-loop join plans." msgstr "Active l'utilisation de plans avec des jointures imbriquées par le planificateur." -#: utils/misc/guc.c:888 +#: utils/misc/guc.c:904 msgid "Enables the planner's use of merge join plans." msgstr "Active l'utilisation de plans de jointures MERGE par le planificateur." -#: utils/misc/guc.c:897 +#: utils/misc/guc.c:913 msgid "Enables the planner's use of hash join plans." msgstr "Active l'utilisation de plans de jointures hâchées par le planificateur." -#: utils/misc/guc.c:906 +#: utils/misc/guc.c:922 msgid "Enables the planner's use of gather merge plans." msgstr "Active l'utilisation de plans GATHER MERGE par le planificateur." -#: utils/misc/guc.c:916 +#: utils/misc/guc.c:931 +msgid "Enables partitionwise join." +msgstr "Active l'utilisation de jointures à la partition" + +#: utils/misc/guc.c:940 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Active l'utilisation d'aggrégations et regroupements à la partition" + +#: utils/misc/guc.c:949 +msgid "Enables the planner's use of parallel append plans." +msgstr "Active l'utilisation de plans Append parallèles par le planificateur." + +#: utils/misc/guc.c:958 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Active l'utilisation de plans de jointures hâchées parallèles par le planificateur." + +#: utils/misc/guc.c:967 +msgid "Enable plan-time and run-time partition pruning." +msgstr "Active l'élagage de partition durant la planification et l'exécution" + +#: utils/misc/guc.c:968 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Autorise le planificateur de requête et l'exécuteur à comparer les limites de partition avec les conditions dans les requêtes pour déterminer quelles sont les partitions qui doivent être parcourues." + +#: utils/misc/guc.c:978 msgid "Enables genetic query optimization." msgstr "Active l'optimisation génétique des requêtes." -#: utils/misc/guc.c:917 +#: utils/misc/guc.c:979 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Cet algorithme essaie de faire une planification sans recherche exhaustive." -#: utils/misc/guc.c:927 +#: utils/misc/guc.c:989 msgid "Shows whether the current user is a superuser." msgstr "Affiche si l'utilisateur actuel est un super-utilisateur." -#: utils/misc/guc.c:937 +#: utils/misc/guc.c:999 msgid "Enables advertising the server via Bonjour." msgstr "Active la publication du serveur via Bonjour." -#: utils/misc/guc.c:946 +#: utils/misc/guc.c:1008 msgid "Collects transaction commit time." msgstr "Récupère l'horodatage de la validation de la transaction." -#: utils/misc/guc.c:955 +#: utils/misc/guc.c:1017 msgid "Enables SSL connections." msgstr "Active les connexions SSL." -#: utils/misc/guc.c:964 +#: utils/misc/guc.c:1026 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Utiliser également ssl_passphrase_command durant le rechargement du serveur." + +#: utils/misc/guc.c:1035 msgid "Give priority to server ciphersuite order." msgstr "Donne la priorité à l'ordre des chiffrements du serveur." -#: utils/misc/guc.c:973 +#: utils/misc/guc.c:1044 msgid "Forces synchronization of updates to disk." msgstr "Force la synchronisation des mises à jour sur le disque." -#: utils/misc/guc.c:974 +#: utils/misc/guc.c:1045 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." msgstr "" "Le serveur utilisera l'appel système fsync() à différents endroits pour\n" @@ -23510,19 +24520,19 @@ msgstr "" "nous assure qu'un groupe de bases de données se retrouvera dans un état\n" "cohérent après un arrêt brutal dû au système d'exploitation ou au matériel." -#: utils/misc/guc.c:985 +#: utils/misc/guc.c:1056 msgid "Continues processing after a checksum failure." msgstr "Continue le traitement après un échec de la somme de contrôle." -#: utils/misc/guc.c:986 +#: utils/misc/guc.c:1057 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." -msgstr "La détection d'une erreur de somme de contrôle a normalement pour effet de rapporter une erreur, annulant la transaction en cours. Régler ignore_checksum_failure à true permet au système d'ignorer cette erreur (mais rapporte toujours un avertissement), et continue le traitement. Ce comportement pourrait causer un arrêt brutal ou d'autres problèmes sérieux. Cela a un effet seulement si les sommes de contrôles (checksums) sont activés." +msgstr "La détection d'une erreur de somme de contrôle a normalement pour effet de rapporter une erreur, annulant la transaction en cours. Régler ignore_checksum_failure à true permet au système d'ignorer cette erreur (mais rapporte toujours un avertissement), et continue le traitement. Ce comportement pourrait causer un arrêt brutal ou d'autres problèmes sérieux. Cela a un effet seulement si les sommes de contrôle (checksums) sont activés." -#: utils/misc/guc.c:1000 +#: utils/misc/guc.c:1071 msgid "Continues processing past damaged page headers." msgstr "Continue le travail après les en-têtes de page endommagés." -#: utils/misc/guc.c:1001 +#: utils/misc/guc.c:1072 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "" "La détection d'une en-tête de page endommagée cause normalement le rapport\n" @@ -23531,13 +24541,13 @@ msgstr "" "message d'attention et continue à travailler. Ce comportement détruira des\n" "données, notamment toutes les lignes de la page endommagée." -#: utils/misc/guc.c:1014 +#: utils/misc/guc.c:1085 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "" "Écrit des pages complètes dans les WAL lors d'une première modification après\n" "un point de vérification." -#: utils/misc/guc.c:1015 +#: utils/misc/guc.c:1086 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." msgstr "" "Une page écrite au moment d'un arrêt brutal du système d'exploitation\n" @@ -23548,155 +24558,155 @@ msgstr "" "vérification des journaux de transaction pour que la récupération complète\n" "soit possible." -#: utils/misc/guc.c:1028 +#: utils/misc/guc.c:1099 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." msgstr "" "Écrit des pages complètes dans les WAL lors d'une première modification après\n" "un point de vérification, y compris pour des modifications non critiques." -#: utils/misc/guc.c:1038 +#: utils/misc/guc.c:1109 msgid "Compresses full-page writes written in WAL file." msgstr "Compresse les blocs complets écrits dans les journaux de transactions." -#: utils/misc/guc.c:1048 +#: utils/misc/guc.c:1119 msgid "Logs each checkpoint." msgstr "Trace tous les points de vérification." -#: utils/misc/guc.c:1057 +#: utils/misc/guc.c:1128 msgid "Logs each successful connection." msgstr "Trace toutes les connexions réussies." -#: utils/misc/guc.c:1066 +#: utils/misc/guc.c:1137 msgid "Logs end of a session, including duration." msgstr "Trace la fin d'une session, avec sa durée." -#: utils/misc/guc.c:1075 +#: utils/misc/guc.c:1146 msgid "Logs each replication command." msgstr "Trace chaque commande de réplication." -#: utils/misc/guc.c:1084 +#: utils/misc/guc.c:1155 msgid "Shows whether the running server has assertion checks enabled." msgstr "Affiche si le serveur en cours d'exécution a les vérifications d'assertion activées." -#: utils/misc/guc.c:1099 +#: utils/misc/guc.c:1170 msgid "Terminate session on any error." msgstr "Termine la session sans erreur." -#: utils/misc/guc.c:1108 +#: utils/misc/guc.c:1179 msgid "Reinitialize server after backend crash." msgstr "Réinitialisation du serveur après un arrêt brutal d'un processus serveur." -#: utils/misc/guc.c:1118 +#: utils/misc/guc.c:1189 msgid "Logs the duration of each completed SQL statement." msgstr "Trace la durée de chaque instruction SQL terminée." -#: utils/misc/guc.c:1127 +#: utils/misc/guc.c:1198 msgid "Logs each query's parse tree." msgstr "Trace l'arbre d'analyse de chaque requête." -#: utils/misc/guc.c:1136 +#: utils/misc/guc.c:1207 msgid "Logs each query's rewritten parse tree." msgstr "Trace l'arbre d'analyse réécrit de chaque requête." -#: utils/misc/guc.c:1145 +#: utils/misc/guc.c:1216 msgid "Logs each query's execution plan." msgstr "Trace le plan d'exécution de chaque requête." -#: utils/misc/guc.c:1154 +#: utils/misc/guc.c:1225 msgid "Indents parse and plan tree displays." msgstr "Indente l'affichage des arbres d'analyse et de planification." -#: utils/misc/guc.c:1163 +#: utils/misc/guc.c:1234 msgid "Writes parser performance statistics to the server log." msgstr "" "Écrit les statistiques de performance de l'analyseur dans les journaux applicatifs\n" "du serveur." -#: utils/misc/guc.c:1172 +#: utils/misc/guc.c:1243 msgid "Writes planner performance statistics to the server log." msgstr "" "Écrit les statistiques de performance de planification dans les journaux\n" "applicatifs du serveur." -#: utils/misc/guc.c:1181 +#: utils/misc/guc.c:1252 msgid "Writes executor performance statistics to the server log." msgstr "" "Écrit les statistiques de performance de l'exécuteur dans les journaux applicatifs\n" "du serveur." -#: utils/misc/guc.c:1190 +#: utils/misc/guc.c:1261 msgid "Writes cumulative performance statistics to the server log." msgstr "" "Écrit les statistiques de performance cumulatives dans les journaux applicatifs\n" "du serveur." -#: utils/misc/guc.c:1200 +#: utils/misc/guc.c:1271 msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "Trace les statistiques d'utilisation des ressources systèmes (mémoire et CPU) sur les différentes opérations B-tree." -#: utils/misc/guc.c:1212 +#: utils/misc/guc.c:1283 msgid "Collects information about executing commands." msgstr "Récupère les statistiques sur les commandes en exécution." -#: utils/misc/guc.c:1213 +#: utils/misc/guc.c:1284 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "" "Active la récupération d'informations sur la commande en cours d'exécution\n" "pour chaque session, avec l'heure de début de l'exécution de la commande." -#: utils/misc/guc.c:1223 +#: utils/misc/guc.c:1294 msgid "Collects statistics on database activity." msgstr "Récupère les statistiques sur l'activité de la base de données." -#: utils/misc/guc.c:1232 +#: utils/misc/guc.c:1303 msgid "Collects timing statistics for database I/O activity." msgstr "Récupère les statistiques d'horodatage sur l'activité en entrées/sorties de la base de données." -#: utils/misc/guc.c:1242 +#: utils/misc/guc.c:1313 msgid "Updates the process title to show the active SQL command." msgstr "" "Met à jour le titre du processus pour indiquer la commande SQL en cours\n" "d'exécution." -#: utils/misc/guc.c:1243 +#: utils/misc/guc.c:1314 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "" "Active la mise à jour du titre du processus chaque fois qu'une nouvelle\n" "commande SQL est reçue par le serveur." -#: utils/misc/guc.c:1256 +#: utils/misc/guc.c:1327 msgid "Starts the autovacuum subprocess." msgstr "Exécute le sous-processus de l'autovacuum." -#: utils/misc/guc.c:1266 +#: utils/misc/guc.c:1337 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Génère une sortie de débogage pour LISTEN et NOTIFY." -#: utils/misc/guc.c:1278 +#: utils/misc/guc.c:1349 msgid "Emits information about lock usage." msgstr "Émet des informations sur l'utilisation des verrous." -#: utils/misc/guc.c:1288 +#: utils/misc/guc.c:1359 msgid "Emits information about user lock usage." msgstr "Émet des informations sur l'utilisation des verrous utilisateurs." -#: utils/misc/guc.c:1298 +#: utils/misc/guc.c:1369 msgid "Emits information about lightweight lock usage." msgstr "Émet des informations sur l'utilisation des verrous légers." -#: utils/misc/guc.c:1308 +#: utils/misc/guc.c:1379 msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "Trace les informations sur les verrous actuels lorsqu'un délai sur le deadlock est dépassé." -#: utils/misc/guc.c:1320 +#: utils/misc/guc.c:1391 msgid "Logs long lock waits." msgstr "Trace les attentes longues de verrou." -#: utils/misc/guc.c:1330 +#: utils/misc/guc.c:1401 msgid "Logs the host name in the connection logs." msgstr "Trace le nom d'hôte dans les traces de connexion." -#: utils/misc/guc.c:1331 +#: utils/misc/guc.c:1402 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." msgstr "" "Par défaut, les traces de connexion n'affichent que l'adresse IP de l'hôte\n" @@ -23705,11 +24715,11 @@ msgstr "" "pour votre hôte, cela pourrait imposer des dégradations de performances non\n" "négligeables." -#: utils/misc/guc.c:1342 +#: utils/misc/guc.c:1413 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Traite « expr=NULL » comme « expr IS NULL »." -#: utils/misc/guc.c:1343 +#: utils/misc/guc.c:1414 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "" "Une fois activé, les expressions de la forme expr = NULL (ou NULL = expr)\n" @@ -23717,504 +24727,539 @@ msgstr "" "l'expression est évaluée comme étant NULL et false sinon. Le comportement\n" "correct de expr = NULL est de toujours renvoyer NULL (inconnu)." -#: utils/misc/guc.c:1355 +#: utils/misc/guc.c:1426 msgid "Enables per-database user names." msgstr "Active les noms d'utilisateur par base de données." -#: utils/misc/guc.c:1364 +#: utils/misc/guc.c:1435 msgid "Sets the default read-only status of new transactions." msgstr "Initialise le statut de lecture seule par défaut des nouvelles transactions." -#: utils/misc/guc.c:1373 +#: utils/misc/guc.c:1444 msgid "Sets the current transaction's read-only status." msgstr "Affiche le statut de lecture seule de la transaction actuelle." -#: utils/misc/guc.c:1383 +#: utils/misc/guc.c:1454 msgid "Sets the default deferrable status of new transactions." msgstr "Initialise le statut déferrable par défaut des nouvelles transactions." -#: utils/misc/guc.c:1392 +#: utils/misc/guc.c:1463 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "" "S'il faut repousser une transaction sérialisable en lecture seule jusqu'à ce qu'elle\n" "puisse être exécutée sans échecs possibles de sérialisation." -#: utils/misc/guc.c:1402 +#: utils/misc/guc.c:1473 msgid "Enable row security." msgstr "Active la sécurité niveau ligne." -#: utils/misc/guc.c:1403 +#: utils/misc/guc.c:1474 msgid "When enabled, row security will be applied to all users." msgstr "Lorsqu'il est activé, le mode de sécurité niveau ligne sera appliqué à tous les utilisateurs." -#: utils/misc/guc.c:1411 +#: utils/misc/guc.c:1482 msgid "Check function bodies during CREATE FUNCTION." msgstr "Vérifie les corps de fonction lors du CREATE FUNCTION." -#: utils/misc/guc.c:1420 +#: utils/misc/guc.c:1491 msgid "Enable input of NULL elements in arrays." msgstr "Active la saisie d'éléments NULL dans les tableaux." -#: utils/misc/guc.c:1421 +#: utils/misc/guc.c:1492 msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." msgstr "" "Si activé, un NULL sans guillemets en tant que valeur d'entrée dans un\n" "tableau signifie une valeur NULL ; sinon, il sera pris littéralement." -#: utils/misc/guc.c:1431 +#: utils/misc/guc.c:1502 msgid "Create new tables with OIDs by default." msgstr "Crée des nouvelles tables avec des OID par défaut." -#: utils/misc/guc.c:1440 +#: utils/misc/guc.c:1511 msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "" "Lance un sous-processus pour capturer la sortie d'erreurs (stderr) et/ou\n" "csvlogs dans des journaux applicatifs." -#: utils/misc/guc.c:1449 +#: utils/misc/guc.c:1520 msgid "Truncate existing log files of same name during log rotation." msgstr "" "Tronque les journaux applicatifs existants du même nom lors de la rotation\n" "des journaux applicatifs." -#: utils/misc/guc.c:1460 +#: utils/misc/guc.c:1531 msgid "Emit information about resource usage in sorting." msgstr "Émet des informations sur l'utilisation des ressources lors d'un tri." -#: utils/misc/guc.c:1474 +#: utils/misc/guc.c:1545 msgid "Generate debugging output for synchronized scanning." msgstr "Génère une sortie de débogage pour les parcours synchronisés." -#: utils/misc/guc.c:1489 +#: utils/misc/guc.c:1560 msgid "Enable bounded sorting using heap sort." msgstr "Active le tri limité en utilisant le tri de heap." -#: utils/misc/guc.c:1502 +#: utils/misc/guc.c:1573 msgid "Emit WAL-related debugging output." msgstr "Émet une sortie de débogage concernant les journaux de transactions." -#: utils/misc/guc.c:1514 +#: utils/misc/guc.c:1585 msgid "Datetimes are integer based." msgstr "Les types datetime sont basés sur des entiers" -#: utils/misc/guc.c:1525 +#: utils/misc/guc.c:1596 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "" "Indique si les noms d'utilisateurs Kerberos et GSSAPI devraient être traités\n" "sans se soucier de la casse." -#: utils/misc/guc.c:1535 +#: utils/misc/guc.c:1606 msgid "Warn about backslash escapes in ordinary string literals." msgstr "Avertie sur les échappements par antislash dans les chaînes ordinaires." -#: utils/misc/guc.c:1545 +#: utils/misc/guc.c:1616 msgid "Causes '...' strings to treat backslashes literally." msgstr "Fait que les chaînes '...' traitent les antislashs littéralement." -#: utils/misc/guc.c:1556 +#: utils/misc/guc.c:1627 msgid "Enable synchronized sequential scans." msgstr "Active l'utilisation des parcours séquentiels synchronisés." -#: utils/misc/guc.c:1566 +#: utils/misc/guc.c:1637 msgid "Allows connections and queries during recovery." msgstr "Autorise les connexions et les requêtes pendant la restauration." -#: utils/misc/guc.c:1576 +#: utils/misc/guc.c:1647 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "" "Permet l'envoi d'informations d'un serveur Hot Standby vers le serveur\n" "principal pour éviter les conflits de requêtes." -#: utils/misc/guc.c:1586 +#: utils/misc/guc.c:1657 msgid "Allows modifications of the structure of system tables." msgstr "Permet les modifications de la structure des tables systèmes." -#: utils/misc/guc.c:1597 +#: utils/misc/guc.c:1668 msgid "Disables reading from system indexes." msgstr "Désactive la lecture des index système." -#: utils/misc/guc.c:1598 +#: utils/misc/guc.c:1669 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "" "Cela n'empêche pas la mise à jour des index, donc vous pouvez l'utiliser en\n" "toute sécurité. La pire conséquence est la lenteur." -#: utils/misc/guc.c:1609 +#: utils/misc/guc.c:1680 msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "" "Active la compatibilité ascendante pour la vérification des droits sur les\n" "Large Objects." -#: utils/misc/guc.c:1610 +#: utils/misc/guc.c:1681 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." msgstr "" "Ignore la vérification des droits lors de la lecture et de la modification\n" "des Larges Objects, pour la compatibilité avec les versions antérieures à la\n" "9.0." -#: utils/misc/guc.c:1620 +#: utils/misc/guc.c:1691 msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "Émet un avertissement pour les constructions dont la signification a changé depuis PostgreSQL 9.4." -#: utils/misc/guc.c:1630 +#: utils/misc/guc.c:1701 msgid "When generating SQL fragments, quote all identifiers." msgstr "Lors de la génération des rragments SQL, mettre entre guillemets tous les identifiants." -#: utils/misc/guc.c:1640 +#: utils/misc/guc.c:1711 msgid "Shows whether data checksums are turned on for this cluster." msgstr "Affiche si les sommes de contrôle sont activées sur les données pour cette instance." -#: utils/misc/guc.c:1651 +#: utils/misc/guc.c:1722 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "Ajoute un numéro de séquence aux messages syslog pour éviter des suppressions de doublons." -#: utils/misc/guc.c:1661 +#: utils/misc/guc.c:1732 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "Sépare les messages envoyés à syslog par lignes afin de les faire tenir dans 1024 octets." -#: utils/misc/guc.c:1680 +#: utils/misc/guc.c:1742 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Controle si les nœuds Gather et Gather Merge doivent également exécuter des sous-plans." + +#: utils/misc/guc.c:1743 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Est-ce que les nœuds Gather devrait également exécuter des sous-plans, ou juste receuiller des lignes ?" + +#: utils/misc/guc.c:1752 +msgid "Allow JIT compilation." +msgstr "Autoriser la compilation JIT." + +#: utils/misc/guc.c:1762 +msgid "Register JIT compiled function with debugger." +msgstr "Enregister la fonction JIT compilée avec debugueur." + +#: utils/misc/guc.c:1779 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Écrire le bitcode LLVM pour faciliter de débugage JIT." + +#: utils/misc/guc.c:1790 +msgid "Allow JIT compilation of expressions." +msgstr "Autoriser la compilation JIT des expressions." + +#: utils/misc/guc.c:1801 +msgid "Register JIT compiled function with perf profiler." +msgstr "Enregistrer la fonction compilée JIT avec le profiler perf." + +#: utils/misc/guc.c:1818 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Autoriser la compilation JIT des expressions." + +#: utils/misc/guc.c:1829 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Soit de continuer à s'exécuter après un échec lors de la synchronisation des fichiers de données." + +#: utils/misc/guc.c:1847 msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." msgstr "" "Force un changement du journal de transaction si un nouveau fichier n'a pas\n" "été créé depuis N secondes." -#: utils/misc/guc.c:1691 +#: utils/misc/guc.c:1858 msgid "Waits N seconds on connection startup after authentication." msgstr "Attends N secondes après l'authentification." -#: utils/misc/guc.c:1692 utils/misc/guc.c:2237 +#: utils/misc/guc.c:1859 utils/misc/guc.c:2410 msgid "This allows attaching a debugger to the process." msgstr "Ceci permet d'attacher un débogueur au processus." -#: utils/misc/guc.c:1701 +#: utils/misc/guc.c:1868 msgid "Sets the default statistics target." msgstr "Initialise la cible par défaut des statistiques." -#: utils/misc/guc.c:1702 +#: utils/misc/guc.c:1869 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "" "Ceci s'applique aux colonnes de tables qui n'ont pas de cible spécifique\n" "pour la colonne initialisée via ALTER TABLE SET STATISTICS." -#: utils/misc/guc.c:1711 +#: utils/misc/guc.c:1878 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "" "Initialise la taille de la liste FROM en dehors de laquelle les\n" "sous-requêtes ne sont pas rassemblées." -#: utils/misc/guc.c:1713 +#: utils/misc/guc.c:1880 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." msgstr "" "Le planificateur fusionne les sous-requêtes dans des requêtes supérieures\n" "si la liste FROM résultante n'a pas plus de ce nombre d'éléments." -#: utils/misc/guc.c:1723 +#: utils/misc/guc.c:1890 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "" "Initialise la taille de la liste FROM en dehors de laquelle les contructions\n" "JOIN ne sont pas aplanies." -#: utils/misc/guc.c:1725 +#: utils/misc/guc.c:1892 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." msgstr "" "La planificateur applanira les constructions JOIN explicites dans des listes\n" "d'éléments FROM lorsqu'une liste d'au plus ce nombre d'éléments en\n" "résulterait." -#: utils/misc/guc.c:1735 +#: utils/misc/guc.c:1902 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "Initialise la limite des éléments FROM en dehors de laquelle GEQO est utilisé." -#: utils/misc/guc.c:1744 +#: utils/misc/guc.c:1911 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "" "GEQO : l'effort est utilisé pour initialiser une valeur par défaut pour les\n" "autres paramètres GEQO." -#: utils/misc/guc.c:1753 +#: utils/misc/guc.c:1920 msgid "GEQO: number of individuals in the population." msgstr "GEQO : nombre d'individus dans une population." -#: utils/misc/guc.c:1754 utils/misc/guc.c:1763 +#: utils/misc/guc.c:1921 utils/misc/guc.c:1930 msgid "Zero selects a suitable default value." msgstr "Zéro sélectionne une valeur par défaut convenable." -#: utils/misc/guc.c:1762 +#: utils/misc/guc.c:1929 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO : nombre d'itérations dans l'algorithme." -#: utils/misc/guc.c:1773 +#: utils/misc/guc.c:1940 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Temps d'attente du verrou avant de vérifier les verrous bloqués." -#: utils/misc/guc.c:1784 +#: utils/misc/guc.c:1951 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "" "Initialise le délai maximum avant d'annuler les requêtes lorsqu'un serveur en\n" "hotstandby traite les données des journaux de transactions archivés" -#: utils/misc/guc.c:1795 +#: utils/misc/guc.c:1962 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "" "Initialise le délai maximum avant d'annuler les requêtes lorsqu'un serveur en\n" "hotstandby traite les données des journaux de transactions envoyés en flux." -#: utils/misc/guc.c:1806 +#: utils/misc/guc.c:1973 msgid "Sets the maximum interval between WAL receiver status reports to the primary." msgstr "Configure l'intervalle maximum entre chaque envoi d'un rapport de statut du walreceiver vers le serveur maître." -#: utils/misc/guc.c:1817 +#: utils/misc/guc.c:1984 msgid "Sets the maximum wait time to receive data from the primary." msgstr "Configure la durée maximale de l'attente de la réception de données depuis le serveur maître." -#: utils/misc/guc.c:1828 +#: utils/misc/guc.c:1995 msgid "Sets the maximum number of concurrent connections." msgstr "Nombre maximum de connexions simultanées." -#: utils/misc/guc.c:1838 +#: utils/misc/guc.c:2006 msgid "Sets the number of connection slots reserved for superusers." msgstr "Nombre de connexions réservées aux super-utilisateurs." -#: utils/misc/guc.c:1852 +#: utils/misc/guc.c:2020 msgid "Sets the number of shared memory buffers used by the server." msgstr "Nombre de tampons en mémoire partagée utilisé par le serveur." -#: utils/misc/guc.c:1863 +#: utils/misc/guc.c:2031 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Nombre maximum de tampons en mémoire partagée utilisés par chaque session." -#: utils/misc/guc.c:1874 +#: utils/misc/guc.c:2042 msgid "Sets the TCP port the server listens on." msgstr "Port TCP sur lequel le serveur écoutera." -#: utils/misc/guc.c:1884 +#: utils/misc/guc.c:2052 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Droits d'accès au socket domaine Unix." -#: utils/misc/guc.c:1885 +#: utils/misc/guc.c:2053 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "" "Les sockets de domaine Unix utilise l'ensemble des droits habituels du système\n" "de fichiers Unix. La valeur de ce paramètre doit être une spécification en\n" "mode numérique de la forme acceptée par les appels système chmod et umask\n" -"(pour utiliser le format octal, le nombre doit commencer avec un zéro)." +"(pour utiliser le format octal, le nombre doit commencer par un zéro)." -#: utils/misc/guc.c:1899 +#: utils/misc/guc.c:2067 msgid "Sets the file permissions for log files." msgstr "Initialise les droits des fichiers de trace." -#: utils/misc/guc.c:1900 +#: utils/misc/guc.c:2068 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "" "La valeur du paramètre est attendue dans le format numérique du mode accepté\n" "par les appels système chmod et umask (pour utiliser le format octal\n" -"personnalisé, le numéro doit commencer avec un zéro)." +"personnalisé, le numéro doit commencer par un zéro)." + +#: utils/misc/guc.c:2082 +msgid "Mode of the data directory." +msgstr "Mode du répertoire des données du serveur." + +#: utils/misc/guc.c:2083 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "" +"La valeur du paramètre est une spécification numérique de mode dans la forme acceptée\n" +"par les appels système chmod et umask (pour utiliser le format octal\n" +"personnalisé, le numéro doit commencer par un 0 (zéro).)" -#: utils/misc/guc.c:1913 +#: utils/misc/guc.c:2096 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Initialise la mémoire maximum utilisée pour les espaces de travail des requêtes." -#: utils/misc/guc.c:1914 +#: utils/misc/guc.c:2097 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "" "Spécifie la mémoire à utiliser par les opérations de tris internes et par\n" "les tables de hachage avant de passer sur des fichiers temporaires sur disque." -#: utils/misc/guc.c:1926 +#: utils/misc/guc.c:2109 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Initialise la mémoire maximum utilisée pour les opérations de maintenance." -#: utils/misc/guc.c:1927 +#: utils/misc/guc.c:2110 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "Ceci inclut les opérations comme VACUUM et CREATE INDEX." -#: utils/misc/guc.c:1937 -msgid "Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "Configure le nombre maximum de lignes à trier en utilisant la sélection de remplacement." - -#: utils/misc/guc.c:1938 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "Quand plus de lignes que ça sont présentes, quicksort sera utilisé." - -#: utils/misc/guc.c:1952 +#: utils/misc/guc.c:2125 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Initialise la profondeur maximale de la pile, en Ko." -#: utils/misc/guc.c:1963 +#: utils/misc/guc.c:2136 msgid "Limits the total size of all temporary files used by each process." msgstr "Limite la taille totale de tous les fichiers temporaires utilisés par chaque processus." -#: utils/misc/guc.c:1964 +#: utils/misc/guc.c:2137 msgid "-1 means no limit." msgstr "-1 signifie sans limite." -#: utils/misc/guc.c:1974 +#: utils/misc/guc.c:2147 msgid "Vacuum cost for a page found in the buffer cache." msgstr "Coût d'un VACUUM pour une page trouvée dans le cache du tampon." -#: utils/misc/guc.c:1984 +#: utils/misc/guc.c:2157 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "Coût d'un VACUUM pour une page introuvable dans le cache du tampon." -#: utils/misc/guc.c:1994 +#: utils/misc/guc.c:2167 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "Coût d'un VACUUM pour une page modifiée par VACUUM." -#: utils/misc/guc.c:2004 +#: utils/misc/guc.c:2177 msgid "Vacuum cost amount available before napping." msgstr "Coût du VACUUM disponible avant un repos." -#: utils/misc/guc.c:2014 +#: utils/misc/guc.c:2187 msgid "Vacuum cost delay in milliseconds." msgstr "Délai d'un coût de VACUUM en millisecondes." -#: utils/misc/guc.c:2025 +#: utils/misc/guc.c:2198 msgid "Vacuum cost delay in milliseconds, for autovacuum." msgstr "Délai d'un coût de VACUUM en millisecondes, pour autovacuum." -#: utils/misc/guc.c:2036 +#: utils/misc/guc.c:2209 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "Coût du VACUUM disponible avant un repos, pour autovacuum." -#: utils/misc/guc.c:2046 +#: utils/misc/guc.c:2219 msgid "Sets the maximum number of simultaneously open files for each server process." msgstr "" "Initialise le nombre maximum de fichiers ouverts simultanément pour chaque\n" "processus serveur." -#: utils/misc/guc.c:2059 +#: utils/misc/guc.c:2232 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Initialise le nombre maximum de transactions préparées simultanément." -#: utils/misc/guc.c:2070 +#: utils/misc/guc.c:2243 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Initialise l'OID minimum des tables pour tracer les verrous." -#: utils/misc/guc.c:2071 +#: utils/misc/guc.c:2244 msgid "Is used to avoid output on system tables." msgstr "Est utilisé pour éviter la sortie sur des tables systèmes." -#: utils/misc/guc.c:2080 +#: utils/misc/guc.c:2253 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Configure l'OID de la table avec une trace des verrous sans condition." -#: utils/misc/guc.c:2092 +#: utils/misc/guc.c:2265 msgid "Sets the maximum allowed duration of any statement." msgstr "Initialise la durée maximum permise pour toute instruction." -#: utils/misc/guc.c:2093 utils/misc/guc.c:2104 utils/misc/guc.c:2115 +#: utils/misc/guc.c:2266 utils/misc/guc.c:2277 utils/misc/guc.c:2288 msgid "A value of 0 turns off the timeout." msgstr "Une valeur de 0 désactive le timeout." -#: utils/misc/guc.c:2103 +#: utils/misc/guc.c:2276 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Initialise la durée maximum permise pour toute attente d'un verrou." -#: utils/misc/guc.c:2114 +#: utils/misc/guc.c:2287 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "Initialise la durée maximale autorisée pour toute transaction en attente." -#: utils/misc/guc.c:2125 +#: utils/misc/guc.c:2298 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "Âge minimum à partir duquel VACUUM devra geler une ligne de table." -#: utils/misc/guc.c:2135 +#: utils/misc/guc.c:2308 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "" "Âge à partir duquel VACUUM devra parcourir une table complète pour geler les\n" "lignes." -#: utils/misc/guc.c:2145 +#: utils/misc/guc.c:2318 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "Âge minimum à partir duquel VACUUM devra geler un MultiXactId dans une ligne de table." -#: utils/misc/guc.c:2155 +#: utils/misc/guc.c:2328 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "" "Âge Multixact à partir duquel VACUUM devra parcourir une table complète pour geler les\n" "lignes." -#: utils/misc/guc.c:2165 +#: utils/misc/guc.c:2338 msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." msgstr "Nombre de transactions à partir duquel les nettoyages VACUUM et HOT doivent être déferrés." -#: utils/misc/guc.c:2178 +#: utils/misc/guc.c:2351 msgid "Sets the maximum number of locks per transaction." msgstr "Initialise le nombre maximum de verrous par transaction." -#: utils/misc/guc.c:2179 +#: utils/misc/guc.c:2352 msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "" "La table des verrous partagés est dimensionnée sur l'idée qu'au plus\n" "max_locks_per_transaction * max_connections objets distincts auront besoin\n" "d'être verrouillés à tout moment." -#: utils/misc/guc.c:2190 +#: utils/misc/guc.c:2363 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Initialise le nombre maximum de verrous prédicats par transaction." -#: utils/misc/guc.c:2191 +#: utils/misc/guc.c:2364 msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "" "La table des verrous de prédicat partagés est dimensionnée sur l'idée qu'au plus\n" "max_pred_locks_per_transaction * max_connections objets distincts auront besoin\n" "d'être verrouillés à tout moment." -#: utils/misc/guc.c:2202 -#, fuzzy -#| msgid "Sets the maximum number of predicate locks per transaction." +#: utils/misc/guc.c:2375 msgid "Sets the maximum number of predicate-locked pages and tuples per relation." -msgstr "Initialise le nombre maximum de verrous prédicats par transaction." +msgstr "Initialise le nombre maximum de pages et lignes verrouillées avec prédicats par transaction." -#: utils/misc/guc.c:2203 -msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation level lock." -msgstr "" +#: utils/misc/guc.c:2376 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Si plus que ce nombre de pages et lignes dans la même relation sont verrouillées par une connexion, ces verrous sont remplacés par un verrou de niveau relation." -#: utils/misc/guc.c:2213 -#, fuzzy -#| msgid "Sets the maximum number of predicate locks per transaction." +#: utils/misc/guc.c:2386 msgid "Sets the maximum number of predicate-locked tuples per page." -msgstr "Initialise le nombre maximum de verrous prédicats par transaction." +msgstr "Initialise le nombre maximum de lignes verrouillées avec prédicat par transaction." -#: utils/misc/guc.c:2214 -msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page level lock." +#: utils/misc/guc.c:2387 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." msgstr "Si plus que ce nombre de lignes sur la même page sont verrouillées par une connexion, ces verrous sont remplacés par un verrou de niveau de page." -#: utils/misc/guc.c:2224 +#: utils/misc/guc.c:2397 msgid "Sets the maximum allowed time to complete client authentication." msgstr "" "Initialise le temps maximum en secondes pour terminer l'authentification du\n" "client." -#: utils/misc/guc.c:2236 +#: utils/misc/guc.c:2409 msgid "Waits N seconds on connection startup before authentication." msgstr "Attends N secondes au lancement de la connexion avant l'authentification." -#: utils/misc/guc.c:2247 +#: utils/misc/guc.c:2420 msgid "Sets the number of WAL files held for standby servers." msgstr "Initialise le nombre de journaux de transactions conservés tenus par les seveurs en attente." -#: utils/misc/guc.c:2257 +#: utils/misc/guc.c:2430 msgid "Sets the minimum size to shrink the WAL to." msgstr "Initialise la taille minimale à laquelle réduire l'espace des journaux de transaction." -#: utils/misc/guc.c:2268 +#: utils/misc/guc.c:2442 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Initialise la volumétrie de journaux de transaction qui déclenche un checkpoint." -#: utils/misc/guc.c:2279 +#: utils/misc/guc.c:2454 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "" "Initialise le temps maximum entre des points de vérification (checkpoints)\n" "pour les journaux de transactions." -#: utils/misc/guc.c:2290 +#: utils/misc/guc.c:2465 msgid "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "" "Active des messages d'avertissement si les segments des points de\n" "vérifications se remplissent plus fréquemment que cette durée." -#: utils/misc/guc.c:2292 +#: utils/misc/guc.c:2467 msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." msgstr "" "Écrit un message dans les journaux applicatifs du serveur si les points de\n" @@ -24222,761 +25267,803 @@ msgstr "" "des points de vérification qui arrivent plus fréquemment que ce nombre de\n" "secondes. Une valeur 0 désactive l'avertissement." -#: utils/misc/guc.c:2304 utils/misc/guc.c:2461 utils/misc/guc.c:2488 +#: utils/misc/guc.c:2479 utils/misc/guc.c:2636 utils/misc/guc.c:2664 msgid "Number of pages after which previously performed writes are flushed to disk." msgstr "Nombre de pages après lequel les précédentes écritures seront synchronisées sur disque." -#: utils/misc/guc.c:2315 +#: utils/misc/guc.c:2490 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "" "Initialise le nombre de tampons de pages disque dans la mémoire partagée\n" "pour les journaux de transactions." -#: utils/misc/guc.c:2326 +#: utils/misc/guc.c:2501 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Temps entre les synchronisations des WAL sur disques effectuées par le processus d'écriture des journaux de transaction" -#: utils/misc/guc.c:2337 +#: utils/misc/guc.c:2512 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "Quantité de WAL écrits par le processus d'écriture des journaux de transaction devant déclencher une synchronisation sur disque." -#: utils/misc/guc.c:2349 +#: utils/misc/guc.c:2524 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "" "Initialise le nombre maximum de processus d'envoi des journaux de transactions\n" "exécutés simultanément." -#: utils/misc/guc.c:2360 +#: utils/misc/guc.c:2535 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Initialise le nombre maximum de slots de réplication définis simultanément." -#: utils/misc/guc.c:2370 +#: utils/misc/guc.c:2545 msgid "Sets the maximum time to wait for WAL replication." msgstr "Initialise le temps maximum à attendre pour la réplication des WAL." -#: utils/misc/guc.c:2381 +#: utils/misc/guc.c:2556 msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." msgstr "" "Initialise le délai en microsecondes entre l'acceptation de la transaction\n" "et le vidage du journal de transaction sur disque." -#: utils/misc/guc.c:2393 +#: utils/misc/guc.c:2568 msgid "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "" "Initialise le nombre minimum de transactions ouvertes simultanément avant le\n" "commit_delay." -#: utils/misc/guc.c:2404 +#: utils/misc/guc.c:2579 msgid "Sets the number of digits displayed for floating-point values." msgstr "Initialise le nombre de chiffres affichés pour les valeurs à virgule flottante." -#: utils/misc/guc.c:2405 +#: utils/misc/guc.c:2580 msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." msgstr "" "Ceci affecte les types de données real, double precision et géométriques.\n" "La valeur du paramètre est ajoutée au nombre standard de chiffres (FLT_DIG\n" "ou DBL_DIG comme approprié)." -#: utils/misc/guc.c:2416 +#: utils/misc/guc.c:2591 msgid "Sets the minimum execution time above which statements will be logged." msgstr "" "Initialise le temps d'exécution minimum au-dessus de lequel les instructions\n" "seront tracées." -#: utils/misc/guc.c:2418 +#: utils/misc/guc.c:2593 msgid "Zero prints all queries. -1 turns this feature off." msgstr "Zéro affiche toutes les requêtes. -1 désactive cette fonctionnalité." -#: utils/misc/guc.c:2428 +#: utils/misc/guc.c:2603 msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgstr "" "Initialise le temps d'exécution minimum au-dessus duquel les actions\n" "autovacuum seront tracées." -#: utils/misc/guc.c:2430 +#: utils/misc/guc.c:2605 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "Zéro affiche toutes les requêtes. -1 désactive cette fonctionnalité." -#: utils/misc/guc.c:2440 +#: utils/misc/guc.c:2615 msgid "Background writer sleep time between rounds." msgstr "" "Temps d'endormissement du processus d'écriture en tâche de fond en\n" "millisecondes." -#: utils/misc/guc.c:2451 +#: utils/misc/guc.c:2626 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "" "Nombre de pages LRU maximum à nettoyer par le processus d'écriture en\n" "tâche de fond." -#: utils/misc/guc.c:2474 +#: utils/misc/guc.c:2649 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "Nombre de requêtes simultanées pouvant être gérées efficacement par le sous-système disque." -#: utils/misc/guc.c:2475 +#: utils/misc/guc.c:2650 msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." msgstr "" "Pour les systèmes RAID, cela devrait être approximativement le nombre de\n" "têtes de lecture du système." -#: utils/misc/guc.c:2501 +#: utils/misc/guc.c:2677 msgid "Maximum number of concurrent worker processes." msgstr "Nombre maximum de background workers simultanés." -#: utils/misc/guc.c:2513 +#: utils/misc/guc.c:2689 msgid "Maximum number of logical replication worker processes." msgstr "Nombre maximum de processus workers de réplication logique." -#: utils/misc/guc.c:2525 +#: utils/misc/guc.c:2701 msgid "Maximum number of table synchronization workers per subscription." msgstr "Nombre maximum de workers de synchronisation par souscription." -#: utils/misc/guc.c:2535 +#: utils/misc/guc.c:2711 msgid "Automatic log file rotation will occur after N minutes." msgstr "" "La rotation automatique des journaux applicatifs s'effectue toutes les N\n" "minutes." -#: utils/misc/guc.c:2546 +#: utils/misc/guc.c:2722 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "La rotation automatique des journaux applicatifs s'effectue après N Ko." -#: utils/misc/guc.c:2557 +#: utils/misc/guc.c:2733 msgid "Shows the maximum number of function arguments." msgstr "Affiche le nombre maximum d'arguments de fonction." -#: utils/misc/guc.c:2568 +#: utils/misc/guc.c:2744 msgid "Shows the maximum number of index keys." msgstr "Affiche le nombre maximum de clés d'index." -#: utils/misc/guc.c:2579 +#: utils/misc/guc.c:2755 msgid "Shows the maximum identifier length." msgstr "Affiche la longueur maximum d'un identifiant" -#: utils/misc/guc.c:2590 +#: utils/misc/guc.c:2766 msgid "Shows the size of a disk block." msgstr "Affiche la taille d'un bloc de disque." -#: utils/misc/guc.c:2601 +#: utils/misc/guc.c:2777 msgid "Shows the number of pages per disk file." msgstr "Affiche le nombre de pages par fichier." -#: utils/misc/guc.c:2612 +#: utils/misc/guc.c:2788 msgid "Shows the block size in the write ahead log." msgstr "Affiche la taille du bloc dans les journaux de transactions." -#: utils/misc/guc.c:2623 +#: utils/misc/guc.c:2799 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "Initalise le temps à attendre avant de retenter de récupérer un WAL après une tentative infructueuse." -#: utils/misc/guc.c:2635 -msgid "Shows the number of pages per write ahead log segment." -msgstr "Affiche le nombre de pages par journal de transactions." +#: utils/misc/guc.c:2811 +msgid "Shows the size of write ahead log segments." +msgstr "Affiche la taille des journaux de transactions." -#: utils/misc/guc.c:2648 +#: utils/misc/guc.c:2824 msgid "Time to sleep between autovacuum runs." msgstr "Durée d'endormissement entre deux exécutions d'autovacuum." -#: utils/misc/guc.c:2658 +#: utils/misc/guc.c:2834 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "Nombre minimum de lignes mises à jour ou supprimées avant le VACUUM." -#: utils/misc/guc.c:2667 +#: utils/misc/guc.c:2843 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "Nombre minimum de lignes insérées, mises à jour ou supprimées avant un ANALYZE." -#: utils/misc/guc.c:2677 +#: utils/misc/guc.c:2853 msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "" "Âge à partir duquel l'autovacuum se déclenche sur une table pour empêcher la\n" "réinitialisation de l'identifiant de transaction" -#: utils/misc/guc.c:2688 +#: utils/misc/guc.c:2864 msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "" "Âge multixact à partir duquel l'autovacuum se déclenche sur une table pour empêcher la\n" "réinitialisation du multixact" -#: utils/misc/guc.c:2698 +#: utils/misc/guc.c:2874 msgid "Sets the maximum number of simultaneously running autovacuum worker processes." msgstr "Initialise le nombre maximum de processus autovacuum exécutés simultanément." -#: utils/misc/guc.c:2708 +#: utils/misc/guc.c:2884 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Initialise le nombre maximum de processus parallèles par opération de maintenance." + +#: utils/misc/guc.c:2894 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Initialise le nombre maximum de processus parallèles par nœud d'exécution." -#: utils/misc/guc.c:2718 -msgid "Sets the maximum number of parallel workers than can be active at one time." +#: utils/misc/guc.c:2904 +msgid "Sets the maximum number of parallel workers that can be active at one time." msgstr "Configure le nombre maximum de processus parallélisés pouvant être actifs en même temps." -#: utils/misc/guc.c:2728 +#: utils/misc/guc.c:2914 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "Initialise la mémoire maximum utilisée par chaque processus autovacuum worker." -#: utils/misc/guc.c:2739 +#: utils/misc/guc.c:2925 msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." msgstr "Temps à partir duquel un snapshot est trop ancien pour lire des pages ayant changées après que le snapshot ait été effectué." -#: utils/misc/guc.c:2740 +#: utils/misc/guc.c:2926 msgid "A value of -1 disables this feature." msgstr "Une valeur de -1 désactive cette fonctionnalité." -#: utils/misc/guc.c:2750 +#: utils/misc/guc.c:2936 msgid "Time between issuing TCP keepalives." msgstr "Secondes entre l'exécution de « TCP keepalives »." -#: utils/misc/guc.c:2751 utils/misc/guc.c:2762 +#: utils/misc/guc.c:2937 utils/misc/guc.c:2948 msgid "A value of 0 uses the system default." msgstr "Une valeur de 0 désactive la valeur système par défaut." -#: utils/misc/guc.c:2761 +#: utils/misc/guc.c:2947 msgid "Time between TCP keepalive retransmits." msgstr "Secondes entre les retransmissions de « TCP keepalive »." -#: utils/misc/guc.c:2772 +#: utils/misc/guc.c:2958 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "La renégociation SSL n'est plus supportée; ce paramètre ne peut être positionné qu'à 0." -#: utils/misc/guc.c:2783 +#: utils/misc/guc.c:2969 msgid "Maximum number of TCP keepalive retransmits." msgstr "Nombre maximum de retransmissions de « TCP keepalive »." -#: utils/misc/guc.c:2784 +#: utils/misc/guc.c:2970 msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." msgstr "" "Ceci contrôle le nombre de retransmissions keepalive consécutives qui\n" "peuvent être perdues avant qu'une connexion ne soit considérée morte. Une\n" "valeur de 0 utilise la valeur par défaut du système." -#: utils/misc/guc.c:2795 +#: utils/misc/guc.c:2981 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Configure le nombre maximum de résultats lors d'une recherche par GIN." -#: utils/misc/guc.c:2806 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "Initialise le sentiment du planificateur sur la taille du cache disque." +#: utils/misc/guc.c:2992 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Initialise le sentiment du planificateur sur la taille des caches disques." -#: utils/misc/guc.c:2807 -msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +#: utils/misc/guc.c:2993 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." msgstr "" -"C'est-à-dire, la portion du cache disque du noyau qui sera utilisé pour les\n" +"C'est-à-dire, la portion des caches disques (noyau et PostgreSQL) qui sera utilisé pour les\n" "fichiers de données de PostgreSQL. C'est mesuré en pages disque, qui font\n" "normalement 8 Ko chaque." -#: utils/misc/guc.c:2819 +#: utils/misc/guc.c:3004 msgid "Sets the minimum amount of table data for a parallel scan." msgstr "Configure la quantité minimale de données de table pour un parcours parallèle." -#: utils/misc/guc.c:2820 +#: utils/misc/guc.c:3005 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." msgstr "Si le planificateur estime qu'il lira un nombre de blocs de table trop petit pour atteindre cette limite, un parcours parallèle ne sera pas considéré." -#: utils/misc/guc.c:2830 +#: utils/misc/guc.c:3015 msgid "Sets the minimum amount of index data for a parallel scan." msgstr "Configure la quantité minimale de données d'index pour un parcours parallèle." -#: utils/misc/guc.c:2831 +#: utils/misc/guc.c:3016 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." msgstr "Si le planificateur estime qu'il lira un nombre de blocs d'index trop petit pour atteindre cette limite, un parcours parallèle ne sera pas considéré." -#: utils/misc/guc.c:2842 +#: utils/misc/guc.c:3027 msgid "Shows the server version as an integer." msgstr "Affiche la version du serveur sous la forme d'un entier." -#: utils/misc/guc.c:2853 +#: utils/misc/guc.c:3038 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "" "Trace l'utilisation de fichiers temporaires plus gros que ce nombre de\n" "kilooctets." -#: utils/misc/guc.c:2854 +#: utils/misc/guc.c:3039 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "" "Zéro trace toutes les requêtes. La valeur par défaut est -1 (désactivant\n" "cette fonctionnalité)." -#: utils/misc/guc.c:2864 +#: utils/misc/guc.c:3049 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Configure la taille réservée pour pg_stat_activity.query, en octets." -#: utils/misc/guc.c:2879 +#: utils/misc/guc.c:3060 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Configure la taille maximale de la pending list d'un index GIN" -#: utils/misc/guc.c:2899 +#: utils/misc/guc.c:3080 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "" "Initialise l'estimation du planificateur pour le coût d'une page disque\n" "récupérée séquentiellement." -#: utils/misc/guc.c:2909 +#: utils/misc/guc.c:3090 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "" "Initialise l'estimation du plnnificateur pour le coût d'une page disque\n" "récupérée non séquentiellement." -#: utils/misc/guc.c:2919 +#: utils/misc/guc.c:3100 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "" "Initialise l'estimation du planificateur pour le coût d'exécution sur chaque\n" "ligne." -#: utils/misc/guc.c:2929 +#: utils/misc/guc.c:3110 msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." msgstr "" "Initialise l'estimation du planificateur pour le coût de traitement de\n" "chaque ligne indexée lors d'un parcours d'index." -#: utils/misc/guc.c:2939 +#: utils/misc/guc.c:3120 msgid "Sets the planner's estimate of the cost of processing each operator or function call." msgstr "" "Initialise l'estimation du planificateur pour le coût de traitement de\n" "chaque opérateur ou appel de fonction." -#: utils/misc/guc.c:2949 +#: utils/misc/guc.c:3130 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." msgstr "Initialise l'estimation du planificateur pour le coût de passage de chaque ligne d'un processus fils vers le processus maître." -#: utils/misc/guc.c:2959 +#: utils/misc/guc.c:3140 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "Initialise l'estimation du planificateur pour le coût de démarrage des processus d'exécution de requêtes parallèles." -#: utils/misc/guc.c:2970 +#: utils/misc/guc.c:3151 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Effectuer une compilation JIT si la requête est plus coûteuse." + +#: utils/misc/guc.c:3152 +msgid "-1 disables JIT compilation." +msgstr "-1 désactive la compilation JIT." + +#: utils/misc/guc.c:3161 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Optimise les fonctions JITées si la requête est plus coûteuse" + +#: utils/misc/guc.c:3162 +msgid "-1 disables optimization." +msgstr "-1 désactive l'optimisation." + +#: utils/misc/guc.c:3171 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Effectuer un inlining JIT si la requête est plus coûteuse." + +#: utils/misc/guc.c:3172 +msgid "-1 disables inlining." +msgstr "-1 désactive l'inlining." + +#: utils/misc/guc.c:3181 msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." msgstr "Initialise l'estimation du planificateur de la fraction des lignes d'un curseur à récupérer." -#: utils/misc/guc.c:2981 +#: utils/misc/guc.c:3192 msgid "GEQO: selective pressure within the population." msgstr "GEQO : pression sélective dans la population." -#: utils/misc/guc.c:2991 +#: utils/misc/guc.c:3202 msgid "GEQO: seed for random path selection." msgstr "GEQO : graine pour la sélection du chemin aléatoire." -#: utils/misc/guc.c:3001 +#: utils/misc/guc.c:3212 msgid "Multiple of the average buffer usage to free per round." msgstr "Multiplede l'utilisation moyenne des tampons à libérer à chaque tour." -#: utils/misc/guc.c:3011 +#: utils/misc/guc.c:3222 msgid "Sets the seed for random-number generation." msgstr "Initialise la clé pour la génération de nombres aléatoires." -#: utils/misc/guc.c:3022 +#: utils/misc/guc.c:3233 msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." msgstr "" "Nombre de lignes modifiées ou supprimées avant d'exécuter un VACUUM\n" "(fraction de reltuples)." -#: utils/misc/guc.c:3031 +#: utils/misc/guc.c:3242 msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." msgstr "" "Nombre de lignes insérées, mises à jour ou supprimées avant d'analyser\n" "une fraction de reltuples." -#: utils/misc/guc.c:3041 +#: utils/misc/guc.c:3252 msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." msgstr "" "Temps passé à vider les tampons lors du point de vérification, en tant que\n" "fraction de l'intervalle du point de vérification." -#: utils/misc/guc.c:3060 +#: utils/misc/guc.c:3262 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "" +"Nombre de lignes insérées avant d'effectuer un nettoyage des index\n" +"(fraction de reltuples)." + +#: utils/misc/guc.c:3281 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "La commande shell qui sera appelée pour archiver un journal de transaction." -#: utils/misc/guc.c:3070 +#: utils/misc/guc.c:3291 msgid "Sets the client's character set encoding." msgstr "Initialise l'encodage du client." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3302 msgid "Controls information prefixed to each log line." msgstr "Contrôle l'information préfixée sur chaque ligne de trace." -#: utils/misc/guc.c:3082 +#: utils/misc/guc.c:3303 msgid "If blank, no prefix is used." msgstr "Si vide, aucun préfixe n'est utilisé." -#: utils/misc/guc.c:3091 +#: utils/misc/guc.c:3312 msgid "Sets the time zone to use in log messages." msgstr "Initialise le fuseau horaire à utiliser pour les journaux applicatifs." -#: utils/misc/guc.c:3101 +#: utils/misc/guc.c:3322 msgid "Sets the display format for date and time values." msgstr "Initialise le format d'affichage des valeurs date et time." -#: utils/misc/guc.c:3102 +#: utils/misc/guc.c:3323 msgid "Also controls interpretation of ambiguous date inputs." msgstr "Contrôle aussi l'interprétation des dates ambigues en entrée." -#: utils/misc/guc.c:3113 +#: utils/misc/guc.c:3334 msgid "Sets the default tablespace to create tables and indexes in." msgstr "Initialise le tablespace par défaut pour créer les tables et index." -#: utils/misc/guc.c:3114 +#: utils/misc/guc.c:3335 msgid "An empty string selects the database's default tablespace." msgstr "Une chaîne vide sélectionne le tablespace par défaut de la base de données." -#: utils/misc/guc.c:3124 +#: utils/misc/guc.c:3345 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "" "Initialise le(s) tablespace(s) à utiliser pour les tables temporaires et les\n" "fichiers de tri." -#: utils/misc/guc.c:3135 +#: utils/misc/guc.c:3356 msgid "Sets the path for dynamically loadable modules." msgstr "Initialise le chemin des modules chargeables dynamiquement." -#: utils/misc/guc.c:3136 +#: utils/misc/guc.c:3357 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "" "Si un module chargeable dynamiquement a besoin d'être ouvert et que le nom\n" "spécifié n'a pas une composante répertoire (c'est-à-dire que le nom ne\n" "contient pas un '/'), le système cherche le fichier spécifié sur ce chemin." -#: utils/misc/guc.c:3149 +#: utils/misc/guc.c:3370 msgid "Sets the location of the Kerberos server key file." msgstr "Initalise l'emplacement du fichier de la clé serveur pour Kerberos." -#: utils/misc/guc.c:3160 +#: utils/misc/guc.c:3381 msgid "Sets the Bonjour service name." msgstr "Initialise le nom du service Bonjour." -#: utils/misc/guc.c:3172 +#: utils/misc/guc.c:3393 msgid "Shows the collation order locale." msgstr "Affiche la locale de tri et de groupement." -#: utils/misc/guc.c:3183 +#: utils/misc/guc.c:3404 msgid "Shows the character classification and case conversion locale." msgstr "Affiche la classification des caractères et la locale de conversions." -#: utils/misc/guc.c:3194 +#: utils/misc/guc.c:3415 msgid "Sets the language in which messages are displayed." msgstr "Initialise le langage dans lequel les messages sont affichés." -#: utils/misc/guc.c:3204 +#: utils/misc/guc.c:3425 msgid "Sets the locale for formatting monetary amounts." msgstr "Initialise la locale pour le formattage des montants monétaires." -#: utils/misc/guc.c:3214 +#: utils/misc/guc.c:3435 msgid "Sets the locale for formatting numbers." msgstr "Initialise la locale pour formater les nombres." -#: utils/misc/guc.c:3224 +#: utils/misc/guc.c:3445 msgid "Sets the locale for formatting date and time values." msgstr "Initialise la locale pour formater les valeurs date et time." -#: utils/misc/guc.c:3234 +#: utils/misc/guc.c:3455 msgid "Lists shared libraries to preload into each backend." msgstr "Liste les bibliothèques partagées à précharger dans chaque processus serveur." -#: utils/misc/guc.c:3245 +#: utils/misc/guc.c:3466 msgid "Lists shared libraries to preload into server." msgstr "Liste les bibliothèques partagées à précharger dans le serveur." -#: utils/misc/guc.c:3256 +#: utils/misc/guc.c:3477 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "Liste les bibliothèques partagées non privilégiées à précharger dans chaque processus serveur." -#: utils/misc/guc.c:3267 +#: utils/misc/guc.c:3488 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "" "Initialise l'ordre de recherche des schémas pour les noms qui ne précisent\n" "pas le schéma." -#: utils/misc/guc.c:3279 +#: utils/misc/guc.c:3500 msgid "Sets the server (database) character set encoding." msgstr "Initialise le codage des caractères pour le serveur (base de données)." -#: utils/misc/guc.c:3291 +#: utils/misc/guc.c:3512 msgid "Shows the server version." msgstr "Affiche la version du serveur." -#: utils/misc/guc.c:3303 +#: utils/misc/guc.c:3524 msgid "Sets the current role." msgstr "Initialise le rôle courant." -#: utils/misc/guc.c:3315 +#: utils/misc/guc.c:3536 msgid "Sets the session user name." msgstr "Initialise le nom de l'utilisateur de la session." -#: utils/misc/guc.c:3326 +#: utils/misc/guc.c:3547 msgid "Sets the destination for server log output." msgstr "Initialise la destination des journaux applicatifs du serveur." -#: utils/misc/guc.c:3327 +#: utils/misc/guc.c:3548 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." msgstr "" "Les valeurs valides sont une combinaison de « stderr », « syslog »,\n" "« csvlog » et « eventlog », suivant la plateforme." -#: utils/misc/guc.c:3338 +#: utils/misc/guc.c:3559 msgid "Sets the destination directory for log files." msgstr "Initialise le répertoire de destination pour les journaux applicatifs." -#: utils/misc/guc.c:3339 +#: utils/misc/guc.c:3560 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "Accepte un chemin relatif ou absolu pour le répertoire des données." -#: utils/misc/guc.c:3349 +#: utils/misc/guc.c:3570 msgid "Sets the file name pattern for log files." msgstr "Initialise le modèle de nom de fichiers pour les journaux applicatifs." -#: utils/misc/guc.c:3360 +#: utils/misc/guc.c:3581 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "" "Initialise le nom du programme utilisé pour identifier les messages de\n" "PostgreSQL dans syslog." -#: utils/misc/guc.c:3371 +#: utils/misc/guc.c:3592 msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "" "Initialise le nom de l'application, utilisé pour identifier les messages de\n" "PostgreSQL dans eventlog." -#: utils/misc/guc.c:3382 +#: utils/misc/guc.c:3603 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "Initialise la zone horaire pour afficher et interpréter les dates/heures." -#: utils/misc/guc.c:3392 +#: utils/misc/guc.c:3613 msgid "Selects a file of time zone abbreviations." msgstr "Sélectionne un fichier contenant les abréviations des fuseaux horaires." -#: utils/misc/guc.c:3402 +#: utils/misc/guc.c:3623 msgid "Sets the current transaction's isolation level." msgstr "Initialise le niveau d'isolation de la transaction courante." -#: utils/misc/guc.c:3413 +#: utils/misc/guc.c:3634 msgid "Sets the owning group of the Unix-domain socket." msgstr "Initialise le groupe d'appartenance du socket domaine Unix." -#: utils/misc/guc.c:3414 +#: utils/misc/guc.c:3635 msgid "The owning user of the socket is always the user that starts the server." msgstr "Le propriétaire du socket est toujours l'utilisateur qui a lancé le serveur." -#: utils/misc/guc.c:3424 +#: utils/misc/guc.c:3645 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Initialise les répertoires où les sockets de domaine Unix seront créés." -#: utils/misc/guc.c:3439 +#: utils/misc/guc.c:3660 msgid "Sets the host name or IP address(es) to listen to." msgstr "Initialise le nom de l'hôte ou l'adresse IP à écouter." -#: utils/misc/guc.c:3454 +#: utils/misc/guc.c:3675 msgid "Sets the server's data directory." msgstr "Initialise le répertoire des données du serveur." -#: utils/misc/guc.c:3465 +#: utils/misc/guc.c:3686 msgid "Sets the server's main configuration file." msgstr "Voir le fichier de configuration principal du serveur." -#: utils/misc/guc.c:3476 +#: utils/misc/guc.c:3697 msgid "Sets the server's \"hba\" configuration file." msgstr "Initialise le fichier de configuration « hba » du serveur." -#: utils/misc/guc.c:3487 +#: utils/misc/guc.c:3708 msgid "Sets the server's \"ident\" configuration file." msgstr "Initialise le fichier de configuration « ident » du serveur." -#: utils/misc/guc.c:3498 +#: utils/misc/guc.c:3719 msgid "Writes the postmaster PID to the specified file." msgstr "Écrit le PID du postmaster PID dans le fichier spécifié." -#: utils/misc/guc.c:3509 +#: utils/misc/guc.c:3730 msgid "Location of the SSL server certificate file." msgstr "Emplacement du fichier du certificat serveur SSL." -#: utils/misc/guc.c:3519 +#: utils/misc/guc.c:3740 msgid "Location of the SSL server private key file." msgstr "Emplacement du fichier de la clé privée SSL du serveur." -#: utils/misc/guc.c:3529 +#: utils/misc/guc.c:3750 msgid "Location of the SSL certificate authority file." msgstr "Emplacement du fichier du certificat autorité SSL." -#: utils/misc/guc.c:3539 +#: utils/misc/guc.c:3760 msgid "Location of the SSL certificate revocation list file." msgstr "Emplacement du fichier de liste de révocation des certificats SSL." -#: utils/misc/guc.c:3549 +#: utils/misc/guc.c:3770 msgid "Writes temporary statistics files to the specified directory." msgstr "Écrit les fichiers statistiques temporaires dans le répertoire indiqué." -#: utils/misc/guc.c:3560 +#: utils/misc/guc.c:3781 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "Nombre de standbys synchrones et liste des noms des synchrones potentiels." -#: utils/misc/guc.c:3571 +#: utils/misc/guc.c:3792 msgid "Sets default text search configuration." msgstr "Initialise le configuration par défaut de la recherche plein texte" -#: utils/misc/guc.c:3581 +#: utils/misc/guc.c:3802 msgid "Sets the list of allowed SSL ciphers." msgstr "Initialise la liste des chiffrements SSL autorisés." -#: utils/misc/guc.c:3596 +#: utils/misc/guc.c:3817 msgid "Sets the curve to use for ECDH." msgstr "Initialise la courbe à utiliser pour ECDH." -#: utils/misc/guc.c:3611 -msgid "Location of the SSL DH params file." +#: utils/misc/guc.c:3832 +msgid "Location of the SSL DH parameters file." msgstr "Emplacement du fichier des paramètres DH SSL." -#: utils/misc/guc.c:3622 +#: utils/misc/guc.c:3843 +msgid "Command to obtain passphrases for SSL." +msgstr "Commande pour obtenir la phrase de passe pour SSL." + +#: utils/misc/guc.c:3853 msgid "Sets the application name to be reported in statistics and logs." msgstr "Configure le nom de l'application à indiquer dans les statistiques et les journaux." -#: utils/misc/guc.c:3633 +#: utils/misc/guc.c:3864 msgid "Sets the name of the cluster, which is included in the process title." msgstr "Configure le nom du cluster, qui est inclus dans le titre du processus." -#: utils/misc/guc.c:3644 +#: utils/misc/guc.c:3875 msgid "Sets the WAL resource managers for which WAL consistency checks are done." msgstr "Configure les gestionnaires de ressource des WAL pour lesquels des vérifications de cohérence sont effectuées." -#: utils/misc/guc.c:3645 +#: utils/misc/guc.c:3876 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." msgstr "Des images complètes de bloc seront tracées pour tous les blocs de données et vérifiées avec le résultat du rejeu des journaux de transactions." -#: utils/misc/guc.c:3664 +#: utils/misc/guc.c:3886 +msgid "JIT provider to use." +msgstr "Fournisseur JIT à utiliser." + +#: utils/misc/guc.c:3906 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "Indique si « \\' » est autorisé dans une constante de chaîne." -#: utils/misc/guc.c:3674 +#: utils/misc/guc.c:3916 msgid "Sets the output format for bytea." msgstr "Initialise le format de sortie pour bytea." -#: utils/misc/guc.c:3684 +#: utils/misc/guc.c:3926 msgid "Sets the message levels that are sent to the client." msgstr "Initialise les niveaux de message envoyés au client." -#: utils/misc/guc.c:3685 utils/misc/guc.c:3738 utils/misc/guc.c:3749 utils/misc/guc.c:3815 +#: utils/misc/guc.c:3927 utils/misc/guc.c:3980 utils/misc/guc.c:3991 utils/misc/guc.c:4057 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "" "Chaque niveau inclut les niveaux qui suivent. Plus loin sera le niveau,\n" "moindre sera le nombre de messages envoyés." -#: utils/misc/guc.c:3695 +#: utils/misc/guc.c:3937 msgid "Enables the planner to use constraints to optimize queries." msgstr "Active l'utilisation des contraintes par le planificateur pour optimiser les requêtes." -#: utils/misc/guc.c:3696 +#: utils/misc/guc.c:3938 msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "" "Les parcours de tables seront ignorés si leur contraintes garantissent\n" "qu'aucune ligne ne correspond à la requête." -#: utils/misc/guc.c:3706 +#: utils/misc/guc.c:3948 msgid "Sets the transaction isolation level of each new transaction." msgstr "Initialise le niveau d'isolation des transactions pour chaque nouvelle transaction." -#: utils/misc/guc.c:3716 +#: utils/misc/guc.c:3958 msgid "Sets the display format for interval values." msgstr "Initialise le format d'affichage des valeurs interval." -#: utils/misc/guc.c:3727 +#: utils/misc/guc.c:3969 msgid "Sets the verbosity of logged messages." msgstr "Initialise la verbosité des messages tracés." -#: utils/misc/guc.c:3737 +#: utils/misc/guc.c:3979 msgid "Sets the message levels that are logged." msgstr "Initialise les niveaux de messages tracés." -#: utils/misc/guc.c:3748 +#: utils/misc/guc.c:3990 msgid "Causes all statements generating error at or above this level to be logged." msgstr "" "Génère une trace pour toutes les instructions qui produisent une erreur de\n" "ce niveau ou de niveaux plus importants." -#: utils/misc/guc.c:3759 +#: utils/misc/guc.c:4001 msgid "Sets the type of statements logged." msgstr "Initialise le type d'instructions tracées." -#: utils/misc/guc.c:3769 +#: utils/misc/guc.c:4011 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "" "Initialise le niveau (« facility ») de syslog à utilisé lors de l'activation\n" "de syslog." -#: utils/misc/guc.c:3784 +#: utils/misc/guc.c:4026 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "" "Configure le comportement des sessions pour les triggers et les règles de\n" "ré-écriture." -#: utils/misc/guc.c:3794 +#: utils/misc/guc.c:4036 msgid "Sets the current transaction's synchronization level." msgstr "Initialise le niveau d'isolation de la transaction courante." -#: utils/misc/guc.c:3804 +#: utils/misc/guc.c:4046 msgid "Allows archiving of WAL files using archive_command." msgstr "Autorise l'archivage des journaux de transactions en utilisant archive_command." -#: utils/misc/guc.c:3814 +#: utils/misc/guc.c:4056 msgid "Enables logging of recovery-related debugging information." msgstr "Active les traces sur les informations de débogage relatives à la restauration." -#: utils/misc/guc.c:3830 +#: utils/misc/guc.c:4072 msgid "Collects function-level statistics on database activity." msgstr "Récupère les statistiques niveau fonction sur l'activité de la base de données." -#: utils/misc/guc.c:3840 +#: utils/misc/guc.c:4082 msgid "Set the level of information written to the WAL." msgstr "Configure le niveau des informations écrites dans les journaux de transactions." -#: utils/misc/guc.c:3850 +#: utils/misc/guc.c:4092 msgid "Selects the dynamic shared memory implementation used." msgstr "Sélectionne l'implémentation de la mémoire partagée dynamique." -#: utils/misc/guc.c:3860 +#: utils/misc/guc.c:4102 msgid "Selects the method used for forcing WAL updates to disk." msgstr "" "Sélectionne la méthode utilisée pour forcer la mise à jour des journaux de\n" "transactions sur le disque." -#: utils/misc/guc.c:3870 +#: utils/misc/guc.c:4112 msgid "Sets how binary values are to be encoded in XML." msgstr "Configure comment les valeurs binaires seront codées en XML." -#: utils/misc/guc.c:3880 +#: utils/misc/guc.c:4122 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "" "Configure si les données XML dans des opérations d'analyse et de\n" "sérialisation implicite doivent être considérées comme des documents\n" "ou des fragments de contenu." -#: utils/misc/guc.c:3891 -msgid "Use of huge pages on Linux." -msgstr "Utilisation des HugePages sur Linux." +#: utils/misc/guc.c:4133 +msgid "Use of huge pages on Linux or Windows." +msgstr "Utilisation des HugePages sur Linux ou Windows." -#: utils/misc/guc.c:3901 +#: utils/misc/guc.c:4143 msgid "Forces use of parallel query facilities." msgstr "Force l'utilisation des fonctionnalités de requête parallèle." -#: utils/misc/guc.c:3902 +#: utils/misc/guc.c:4144 msgid "If possible, run query using a parallel worker and with parallel restrictions." msgstr "Si possible, exécute des requêtes utilisant des processus parallèles et avec les restrictions parallèles." -#: utils/misc/guc.c:3911 +#: utils/misc/guc.c:4153 msgid "Encrypt passwords." msgstr "Chiffre les mots de passe." -#: utils/misc/guc.c:3912 +#: utils/misc/guc.c:4154 msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." msgstr "" "Lorsqu'un mot de passe est spécifié dans CREATE USER ou ALTER USER sans\n" "indiquer ENCRYPTED ou UNENCRYPTED, ce paramètre détermine si le mot de passe\n" "doit être chiffré." -#: utils/misc/guc.c:4714 +#: utils/misc/guc.c:4956 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" -#: utils/misc/guc.c:4719 +#: utils/misc/guc.c:4961 #, c-format msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" msgstr "Lancer initdb ou pg_basebackup pour initialiser un répertoire de données PostgreSQL.\n" -#: utils/misc/guc.c:4739 +#: utils/misc/guc.c:4981 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -24986,12 +26073,12 @@ msgstr "" "Vous devez soit spécifier l'option --config-file soit spécifier l'option -D\n" "soit initialiser la variable d'environnement.\n" -#: utils/misc/guc.c:4758 +#: utils/misc/guc.c:5000 #, c-format msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s : n'a pas pu accéder au fichier de configuration « %s » : %s\n" -#: utils/misc/guc.c:4784 +#: utils/misc/guc.c:5026 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -25001,7 +26088,7 @@ msgstr "" "Il est configurable avec « data_directory » dans « %s » ou avec l'option -D\n" "ou encore avec la variable d'environnement PGDATA.\n" -#: utils/misc/guc.c:4832 +#: utils/misc/guc.c:5074 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -25011,7 +26098,7 @@ msgstr "" "Il est configurable avec « hba_file » dans « %s » ou avec l'option -D ou\n" "encore avec la variable d'environnement PGDATA.\n" -#: utils/misc/guc.c:4855 +#: utils/misc/guc.c:5097 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -25021,155 +26108,160 @@ msgstr "" "Il est configurable avec « ident_file » dans « %s » ou avec l'option -D ou\n" "encore avec la variable d'environnement PGDATA.\n" -#: utils/misc/guc.c:5529 utils/misc/guc.c:5576 +#: utils/misc/guc.c:5772 utils/misc/guc.c:5819 msgid "Value exceeds integer range." msgstr "La valeur dépasse l'échelle des entiers." -#: utils/misc/guc.c:5799 +#: utils/misc/guc.c:6046 #, c-format msgid "parameter \"%s\" requires a numeric value" msgstr "le paramètre « %s » requiert une valeur numérique" -#: utils/misc/guc.c:5808 +#: utils/misc/guc.c:6055 #, c-format msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" msgstr "%g est en dehors des limites valides pour le paramètre « %s » (%g .. %g)" -#: utils/misc/guc.c:5961 utils/misc/guc.c:7307 +#: utils/misc/guc.c:6208 utils/misc/guc.c:7578 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "ne peut pas configurer les paramètres lors d'une opération parallèle" -#: utils/misc/guc.c:5968 utils/misc/guc.c:6719 utils/misc/guc.c:6772 utils/misc/guc.c:7135 utils/misc/guc.c:7894 utils/misc/guc.c:8062 utils/misc/guc.c:9738 +#: utils/misc/guc.c:6215 utils/misc/guc.c:6967 utils/misc/guc.c:7020 utils/misc/guc.c:7071 utils/misc/guc.c:7407 utils/misc/guc.c:8174 utils/misc/guc.c:8342 utils/misc/guc.c:10019 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "paramètre de configuration « %s » non reconnu" -#: utils/misc/guc.c:5983 utils/misc/guc.c:7147 +#: utils/misc/guc.c:6230 utils/misc/guc.c:7419 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "le paramètre « %s » ne peut pas être changé" -#: utils/misc/guc.c:6016 +#: utils/misc/guc.c:6263 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "le paramètre « %s » ne peut pas être modifié maintenant" -#: utils/misc/guc.c:6034 utils/misc/guc.c:6080 utils/misc/guc.c:9754 +#: utils/misc/guc.c:6281 utils/misc/guc.c:6328 utils/misc/guc.c:10035 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "droit refusé pour initialiser le paramètre « %s »" -#: utils/misc/guc.c:6070 +#: utils/misc/guc.c:6318 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "le paramètre « %s » ne peut pas être initialisé après le lancement du serveur" -#: utils/misc/guc.c:6118 +#: utils/misc/guc.c:6366 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "" "ne peut pas configurer le paramètre « %s » à l'intérieur d'une fonction\n" "SECURITY DEFINER" -#: utils/misc/guc.c:6727 utils/misc/guc.c:6777 utils/misc/guc.c:8069 +#: utils/misc/guc.c:6975 utils/misc/guc.c:7025 utils/misc/guc.c:8349 #, c-format msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" msgstr "doit être super-utilisateur ou membre de pg_read_all_settings pour examiner « %s »" -#: utils/misc/guc.c:6844 +#: utils/misc/guc.c:7116 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s prend un seul argument" -#: utils/misc/guc.c:7095 +#: utils/misc/guc.c:7367 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" msgstr "doit être super-utilisateur pour exécuter la commande ALTER SYSTEM" -#: utils/misc/guc.c:7180 +#: utils/misc/guc.c:7452 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "la valeur du paramètre pour ALTER SYSTEM ne doit pas contenir de caractère de retour à la ligne" -#: utils/misc/guc.c:7225 +#: utils/misc/guc.c:7497 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "n'a pas pu analyser le contenu du fichier « %s »" -#: utils/misc/guc.c:7383 +#: utils/misc/guc.c:7654 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT n'est pas implémenté" -#: utils/misc/guc.c:7467 +#: utils/misc/guc.c:7738 #, c-format msgid "SET requires parameter name" msgstr "SET requiert le nom du paramètre" -#: utils/misc/guc.c:7591 +#: utils/misc/guc.c:7871 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "tentative de redéfinition du paramètre « %s »" -#: utils/misc/guc.c:9371 +#: utils/misc/guc.c:9652 #, c-format msgid "parameter \"%s\" could not be set" msgstr "le paramètre « %s » n'a pas pu être configuré" -#: utils/misc/guc.c:9458 +#: utils/misc/guc.c:9739 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "n'a pas pu analyser la configuration du paramètre « %s »" -#: utils/misc/guc.c:9816 utils/misc/guc.c:9850 +#: utils/misc/guc.c:10097 utils/misc/guc.c:10131 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "valeur invalide pour le paramètre « %s » : %d" -#: utils/misc/guc.c:9884 +#: utils/misc/guc.c:10165 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "valeur invalide pour le paramètre « %s » : %g" -#: utils/misc/guc.c:10154 +#: utils/misc/guc.c:10449 #, c-format msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." msgstr "« temp_buffers » ne peut pas être modifié après que des tables temporaires aient été utilisées dans la session." -#: utils/misc/guc.c:10166 +#: utils/misc/guc.c:10461 #, c-format msgid "Bonjour is not supported by this build" msgstr "Bonjour n'est pas supporté dans cette installation" -#: utils/misc/guc.c:10179 +#: utils/misc/guc.c:10474 #, c-format msgid "SSL is not supported by this build" msgstr "SSL n'est pas supporté dans cette installation" -#: utils/misc/guc.c:10191 +#: utils/misc/guc.c:10486 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "Ne peut pas activer le paramètre avec « log_statement_stats » à true." -#: utils/misc/guc.c:10203 +#: utils/misc/guc.c:10498 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "" "Ne peut pas activer « log_statement_stats » lorsque « log_parser_stats »,\n" "« log_planner_stats » ou « log_executor_stats » est true." +#: utils/misc/guc.c:10714 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgstr "effective_io_concurrency doit être positionnéà 0 sur les plateformes qui n'ont pas posix_fadvise()" + #: utils/misc/help_config.c:131 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "erreur interne : type de paramètre d'exécution non reconnu\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format msgid "query-specified return tuple and function return type are not compatible" msgstr "une ligne de sortie spécifiée à la requête et un type de sortie de fonction ne sont pas compatibles" -#: utils/misc/pg_controldata.c:58 utils/misc/pg_controldata.c:138 utils/misc/pg_controldata.c:244 utils/misc/pg_controldata.c:311 +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "la somme de contrôle CRC calculée ne correspond par à la valeur enregistrée dans le fichier" @@ -25179,12 +26271,12 @@ msgstr "la somme de contrôle CRC calculée ne correspond par à la valeur enreg msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" msgstr "CPU : utilisateur : %d.%02d s, système : %d.%02d s, temps passé : %d.%02d s" -#: utils/misc/rls.c:128 +#: utils/misc/rls.c:127 #, c-format msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "la requête pourrait être affectée par une politique de sécurité au niveau ligne pour la table « %s »" -#: utils/misc/rls.c:130 +#: utils/misc/rls.c:129 #, c-format msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "Pour désactiver la politique pour le propriétaire de la table, utilisez ALTER TABLE NO FORCE ROW LEVEL SECURITY." @@ -25273,72 +26365,92 @@ msgstr "" "@INCLUDE sans nom de fichier dans le fichier des fuseaux horaires « %s »,\n" "ligne %d" -#: utils/mmgr/aset.c:405 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "Échec lors de la création du contexte mémoire « %s »." -#: utils/mmgr/dsa.c:518 utils/mmgr/dsa.c:1323 +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 #, c-format msgid "could not attach to dynamic shared area" msgstr "n'a pas pu attacher le segment de mémoire partagée dynamique" -#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 -#, c-format -msgid "Failed on DSA request of size %zu." -msgstr "Échec d'une requête DSA de taille %zu." - -#: utils/mmgr/mcxt.c:726 utils/mmgr/mcxt.c:761 utils/mmgr/mcxt.c:798 utils/mmgr/mcxt.c:835 utils/mmgr/mcxt.c:869 utils/mmgr/mcxt.c:898 utils/mmgr/mcxt.c:932 utils/mmgr/mcxt.c:983 utils/mmgr/mcxt.c:1017 utils/mmgr/mcxt.c:1051 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 utils/mmgr/mcxt.c:1134 #, c-format -msgid "Failed on request of size %zu." -msgstr "Échec d'une requête de taille %zu." +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Échec d'une requête de taille %zu dans le contexte mémoire « %s »." -#: utils/mmgr/portalmem.c:186 +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "le curseur « %s » existe déjà" -#: utils/mmgr/portalmem.c:190 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "fermeture du curseur existant « %s »" -#: utils/mmgr/portalmem.c:394 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "le portail « %s » ne peut pas être exécuté de nouveau" -#: utils/mmgr/portalmem.c:474 +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "ne peut pas supprimer le portail épinglé « %s »" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "ne peut pas supprimer le portail actif « %s »" -#: utils/mmgr/portalmem.c:678 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "ne peut pas préparer une transaction qui a créé un curseur WITH HOLD" -#: utils/sort/logtape.c:252 +#: utils/mmgr/portalmem.c:1263 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "ne peut pas effectuer de commandes de transaction dans une boucle de curseur qui n'est pas en lecture seule" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "n'a pas pu lire le bloc %ld du fichier temporaire : %m" -#: utils/sort/tuplesort.c:3072 +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "n'a pas pu écrire dans le fichier temporaire : %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "n'a pas pu lire le fichier temporaire tuplestore partagé : %m" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "tronçon non attendu dans le fichier temporaire tuplestore partagé" + +#: utils/sort/tuplesort.c:2967 #, c-format msgid "cannot have more than %d runs for an external sort" msgstr "ne peut pas avoir plus de %d exécutions pour un tri externe" -#: utils/sort/tuplesort.c:4146 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "n'a pas pu créer l'index unique « %s »" -#: utils/sort/tuplesort.c:4148 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "La clé %s est dupliquée." -#: utils/sort/tuplesort.c:4149 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "Des clés dupliquées existent." @@ -25405,6 +26517,226 @@ msgstr "" msgid "cannot import a snapshot from a different database" msgstr "ne peut pas importer un snapshot à partir d'une base de données différente" +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "n'a pas pu ouvrir le BufFile « %s »" + +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "" +#~ "%s ne peut pas être exécuté à partir d'une fonction ou d'une chaîne\n" +#~ "contenant plusieurs commandes" + +#~ msgid "no such savepoint" +#~ msgstr "aucun point de sauvegarde" + +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le répertoire des journaux de transactions « %s » : %m" + +#~ msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "" +#~ "Le cluster de bases de données a été initialisé avec un XLOG_SEG_SIZE à %d\n" +#~ "alors que le serveur a été compilé avec un XLOG_SEG_SIZE à %d." + +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "utilisation du précédent enregistrement d'un point de vérification à %X/%X" + +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "lien du point de vérification secondaire invalide dans le fichier de contrôle" + +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "enregistrement du point de vérification secondaire invalide" + +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "identifiant du gestionnaire de ressource invalide dans l'enregistrement secondaire du point de vérification" + +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "xl_info invalide dans l'enregistrement du point de vérification secondaire" + +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "longueur invalide de l'enregistrement secondaire du point de vérification" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "le fichier WAL provient d'un système différent : XLOG_SEG_SIZE invalide dans l'en-tête de page" + +#~ msgid " in schema %s" +#~ msgstr " dans le schéma %s" + +#~ msgid "%s in publication %s" +#~ msgstr "%s dans la publication %s" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "la table « %s » a de nombreuses contraintes nommées « %s »" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "le domaine %s a plusieurs contraintes nommées « %s »" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "« %s » est déjà un attribut du type %s" + +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "la fonction « %s » est une fonction d'agrégat" + +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "la fonction « %s » n'est pas une fonction d'agrégat" + +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "la fonction « %s » n'est pas une fonction window" + +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "doit être super-utilisateur pour utiliser COPY à partir ou vers un fichier" + +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "ne peut pas copier vers la table distante « %s »" + +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "ne peut pas envoyer les lignes insérées dans une table distante" + +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "l'attribut « %s » non reconnu de la fonction a été ignoré" + +#~ msgid "cast function must not be an aggregate function" +#~ msgstr "la fonction de conversion ne doit pas être une fonction d'agrégat" + +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "la fonction de transformation ne doit pas être une fonction d'agrégat" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "numéro de procédure %d invalide, doit être compris entre 1 et %d" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "le numéro de procédure %d pour (%s, %s) apparaît plus d'une fois" + +#~ msgid "operator procedure must be specified" +#~ msgstr "la procédure de l'opérateur doit être spécifiée" + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "la colonne « %s » apparaît plus d'une fois dans la clé de partitionnement" + +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "" +#~ "Fermez les transactions ouvertes rapidement pour éviter des problèmes de\n" +#~ "réinitialisation." + +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "la fonction d'unification pour l'aggrégat %u doit être déclarée comme STRICT" + +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING est seulement supporté avec UNBOUNDED" + +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING est seulement supporté avec UNBOUNDED" + +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "le client requiert le lien de canal SCRAM mais ceci n'est pas supporté" + +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "doit être super-utilisateur pour utiliser lo_import() du côté serveur" + +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "Tout le monde peut utiliser lo_import(), fourni par libpq, du côté client." + +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "doit être super-utilisateur pour utiliser lo_export() du côté serveur" + +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "Tout le monde peut utiliser lo_export(), fournie par libpq, du côté client." + +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "la clause ON CONFLICT n'est pas supporté avec les tables partitionnées" + +#~ msgid "primary key constraints are not supported on partitioned tables" +#~ msgstr "les clés primaires ne sont pas supportées sur les tables partitionnées" + +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "les clés étrangères ne sont pas supportées sur les tables partitionnées" + +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "n'a pas pu accéder au répertoire du statut des archives « %s » : %m" + +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s : max_wal_senders doit être inférieur à max_connections\n" + +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "" +#~ "le répertoire des données « %s » est accessible par le groupe et/ou par les\n" +#~ "autres" + +#~ msgid "worker process" +#~ msgstr "processus de travail" + +#~ msgid "built-in type %u not found" +#~ msgstr "type interne %u non trouvé" + +#~ msgid "This can be caused by having a publisher with a higher PostgreSQL major version than the subscriber." +#~ msgstr "Ceci peut avoir pour cause un publieur ayant une version majeure de PostgreSQL supérieure à l'abonné" + +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "le type de données « %s/%s » requis par la réplication logique n'existe pas" + +#~ msgid "logical replication could not find row for delete in replication target relation \"%s\"" +#~ msgstr "la réplication logique n'a pas pu trouver la ligne à supprimer dans la relation cible de réplication %s" + +#~ msgid "memory for serializable conflict tracking is nearly exhausted" +#~ msgstr "la mémoire pour tracer les conflits sérialisables est pratiquement pleine" + +#~ msgid "There might be an idle transaction or a forgotten prepared transaction causing this." +#~ msgstr "" +#~ "Il pourait y avoir une transaction en attente ou une transaction préparée\n" +#~ "oubliée causant cela." + +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "n'a pas pu ouvrir le répertoire du tablespace « %s » : %m" + +#~ msgid "must be superuser to get file information" +#~ msgstr "doit être super-utilisateur pour obtenir des informations sur le fichier" + +#~ msgid "must be superuser to get directory listings" +#~ msgstr "doit être super-utilisateur pour obtenir le contenu du répertoire" + +#~ msgid "Sets the maximum number of tuples to be sorted using replacement selection." +#~ msgstr "Configure le nombre maximum de lignes à trier en utilisant la sélection de remplacement." + +#~ msgid "When more tuples than this are present, quicksort will be used." +#~ msgstr "Quand plus de lignes que ça sont présentes, quicksort sera utilisé." + +#~ msgid "cannot create range partition with empty range" +#~ msgstr "ne peut pas créer une partition par intervalle avec un intervalle vide" + +#~ msgid "could not get keyword values for locale \"%s\": %s" +#~ msgstr "n'a pas pu obtenir les valeurs des mots clés pour la locale « %s » : %s" + +#~ msgid "invalid publish list" +#~ msgstr "liste de publication invalide" + +#~ msgid "column \"%s\" referenced in statistics does not exist" +#~ msgstr "la colonne « %s » référencée dans les statistiques n'existe pas" + +#~ msgid "added subscription for table %s.%s" +#~ msgstr "souscription ajoutée pour la table %s.%s" + +#~ msgid "removed subscription for table %s.%s" +#~ msgstr "a supprimé une souscription pour la table %s.%s" + +#~ msgid "User \"%s\" has an empty password." +#~ msgstr "L'utilisateur « %s » a un mot de passe vide." + +#~ msgid "not connected to database" +#~ msgstr "non connecté à une base de données" + +#~ msgid "invalid input syntax for %s: \"%s\"" +#~ msgstr "syntaxe en entrée invalide pour le type %s : « %s »" + +#~ msgid "transaction ID " +#~ msgstr "ID de transaction " + +#~ msgid "in progress" +#~ msgstr "en cours" + +#~ msgid "committed" +#~ msgstr "validé" + +#~ msgid "aborted" +#~ msgstr "annulé" + #~ msgid "wrong range of array subscripts" #~ msgstr "mauvais échelle des indices du tableau" @@ -25678,9 +27010,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "%s: could not determine user name (GetUserName failed)\n" #~ msgstr "%s : n'a pas pu déterminer le nom de l'utilisateur (GetUserName a échoué)\n" -#~ msgid "too many column aliases specified for function %s" -#~ msgstr "trop d'alias de colonnes spécifiées pour la fonction %s" - #~ msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." #~ msgstr "Attendait 1 ligne avec 3 champs, a obtenu %d lignes avec %d champs." @@ -25699,9 +27028,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "cannot call json_object_keys on an array" #~ msgstr "ne peut pas appeler json_object_keys sur un tableau" -#~ msgid "cannot call json_object_keys on a scalar" -#~ msgstr "ne peut pas appeler json_object_keys sur un scalaire" - #~ msgid "cannot call function with null path elements" #~ msgstr "ne peut pas appeler une fonction avec des éléments chemins NULL" @@ -26172,9 +27498,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "not unique \"S\"" #~ msgstr "« S » non unique" -#~ msgid "invalid argument for power function" -#~ msgstr "argument invalide pour la fonction puissance (power)" - #~ msgid "Valid values are DOCUMENT and CONTENT." #~ msgstr "Les valeurs valides sont DOCUMENT et CONTENT." @@ -26388,9 +27711,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "invalid LC_CTYPE setting" #~ msgstr "paramètre LC_CTYPE invalide" -#~ msgid "invalid LC_COLLATE setting" -#~ msgstr "paramètre LC_COLLATE invalide" - #~ msgid "GIN index does not support search with void query" #~ msgstr "les index GIN ne supportent pas la recherche avec des requêtes vides" @@ -26963,9 +28283,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "invalid list syntax for \"unix_socket_directories\"" #~ msgstr "syntaxe de liste invalide pour le paramètre « unix_socket_directories »" -#~ msgid "invalid list syntax for \"listen_addresses\"" -#~ msgstr "syntaxe de liste invalide pour le paramètre « listen_addresses »" - #~ msgid "window functions cannot use named arguments" #~ msgstr "les fonctions window ne peuvent pas renvoyer des arguments nommés" @@ -26986,9 +28303,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "argument for function \"exp\" too big" #~ msgstr "l'argument de la fonction « exp » est trop gros" -#~ msgid "must be superuser to rotate log files" -#~ msgstr "doit être super-utilisateur pour exécuter la rotation des journaux applicatifs" - #~ msgid "must be superuser to signal the postmaster" #~ msgstr "doit être super-utilisateur pour envoyer un signal au postmaster" @@ -27241,9 +28555,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "value \"%s\" is out of range for type bigint" #~ msgstr "la valeur « %s » est en dehors des limites du type bigint" -#~ msgid "invalid input syntax for integer: \"%s\"" -#~ msgstr "syntaxe en entrée invalide pour l'entier : « %s »" - #~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" #~ msgstr "les motifs de format « TZ »/« tz »/« OF » ne sont pas supportés dans to_date" @@ -27391,9 +28702,6 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ msgid "access method name cannot be qualified" #~ msgstr "le nom de la méthode d'accès ne peut pas être qualifiée" -#~ msgid "%s." -#~ msgstr "%s." - #~ msgid "default expression must not return a set" #~ msgstr "l'expression par défaut ne doit pas renvoyer un ensemble" @@ -27599,3 +28907,26 @@ msgstr "ne peut pas importer un snapshot à partir d'une base de données diffé #~ "attendue par le programme.\n" #~ "Les résultats ci-dessous ne sont pas dignes de confiance.\n" #~ "\n" + +#~ msgid "invalid number of arguments: object must be matched key value pairs" +#~ msgstr "nombre d'arguments invalide : l'objet doit correspond aux paires clé/valeur" + +#~ msgid "New enum values must be committed before they can be used." +#~ msgstr "Les nouvelles valeurs enum doivent être validées (COMMIT) avant de pouvoir être utilisées." + +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "la clé étrangère référençant la table partitionnée « %s » ne doit pas être ONLY" + +#~ msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." +#~ msgstr "" +#~ "Si vous êtes sûr qu'aucun processus serveur n'est toujours en cours\n" +#~ "d'exécution, supprimez le bloc de mémoire partagée\n" +#~ "ou supprimez simplement le fichier « %s »." + +#~ msgid "view must have at least one column" +#~ msgstr "la vue doit avoir au moins une colonne" + +#~ msgid "cannot PREPARE a transaction that has operated on temporary namespace" +#~ msgstr "" +#~ "ne peut pas préparer (PREPARE) une transaction qui a travaillé sur un\n" +#~ "schéma temporaire" diff --git a/src/backend/po/it.po b/src/backend/po/it.po index 5f42bb4940e..139d84b6ff5 100644 --- a/src/backend/po/it.po +++ b/src/backend/po/it.po @@ -1,75 +1,86 @@ # -# Translation of postgres to Italian -# PostgreSQL Project +# postgres.po +# Italian message translation file for postgres # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Vincenzo Romano +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# Daniele Varrazzo , 2012-2017. +# Vincenzo Romano +# +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: postgres (PostgreSQL) 10\n" +"Project-Id-Version: postgres (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:38+0000\n" -"PO-Revision-Date: 2017-06-03 01:29+0100\n" +"POT-Creation-Date: 2018-10-08 14:08+0000\n" +"PO-Revision-Date: 2018-10-16 02:25+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" -#: ../common/config_info.c:131 ../common/config_info.c:139 -#: ../common/config_info.c:147 ../common/config_info.c:155 -#: ../common/config_info.c:163 ../common/config_info.c:171 -#: ../common/config_info.c:179 ../common/config_info.c:187 -#: ../common/config_info.c:195 +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 msgid "not recorded" msgstr "non registrato" -#: ../common/controldata_utils.c:57 commands/copy.c:3041 -#: commands/extension.c:3328 utils/adt/genfile.c:135 +#: ../common/controldata_utils.c:58 commands/copy.c:3146 +#: commands/extension.c:3330 utils/adt/genfile.c:151 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "apertura del file \"%s\" in lettura fallita: %m" -#: ../common/controldata_utils.c:61 +#: ../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: apertura del file \"%s\" in lettura fallita: %s\n" -#: ../common/controldata_utils.c:71 access/transam/timeline.c:348 -#: access/transam/xlog.c:3385 access/transam/xlog.c:10777 -#: access/transam/xlog.c:10790 access/transam/xlog.c:11182 -#: access/transam/xlog.c:11225 access/transam/xlog.c:11264 -#: access/transam/xlog.c:11307 access/transam/xlogfuncs.c:668 -#: access/transam/xlogfuncs.c:687 commands/extension.c:3338 libpq/hba.c:499 -#: replication/logical/origin.c:661 replication/logical/origin.c:691 -#: replication/logical/reorderbuffer.c:3064 replication/walsender.c:508 -#: storage/file/copydir.c:178 utils/adt/genfile.c:152 utils/adt/misc.c:924 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 +#: access/transam/xlog.c:3440 access/transam/xlog.c:10942 +#: access/transam/xlog.c:10955 access/transam/xlog.c:11380 +#: access/transam/xlog.c:11460 access/transam/xlog.c:11499 +#: access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 +#: access/transam/xlogfuncs.c:677 commands/extension.c:3340 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3294 replication/walsender.c:510 +#: storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format msgid "could not read file \"%s\": %m" -msgstr "lettura de file \"%s\" fallita: %m" +msgstr "lettura del file \"%s\" fallita: %m" -#: ../common/controldata_utils.c:74 +#: ../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: lettura del file \"%s\" fallita: %s\n" -#: ../common/controldata_utils.c:95 +#: ../common/controldata_utils.c:86 +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "lettura del file \"%s\" fallita: letti %d di %d" + +#: ../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: lettura del file \"%s\" fallita: letti %d di %d\n" + +#: ../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "l'ordine dei byte non combacia" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -179,41 +190,42 @@ msgid "could not close directory \"%s\": %s\n" msgstr "chiusura della directory \"%s\" fallita: %s\n" #: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1306 access/transam/xlog.c:6350 -#: lib/stringinfo.c:258 libpq/auth.c:1107 libpq/auth.c:1472 libpq/auth.c:1540 -#: libpq/auth.c:2056 postmaster/bgworker.c:337 postmaster/bgworker.c:908 -#: postmaster/postmaster.c:2377 postmaster/postmaster.c:2399 -#: postmaster/postmaster.c:3952 postmaster/postmaster.c:4652 -#: postmaster/postmaster.c:4727 postmaster/postmaster.c:5397 -#: postmaster/postmaster.c:5716 -#: replication/libpqwalreceiver/libpqwalreceiver.c:251 -#: replication/logical/logical.c:170 storage/buffer/localbuf.c:436 -#: storage/file/fd.c:773 storage/file/fd.c:1201 storage/file/fd.c:1319 -#: storage/file/fd.c:2044 storage/ipc/procarray.c:1057 -#: storage/ipc/procarray.c:1545 storage/ipc/procarray.c:1552 -#: storage/ipc/procarray.c:1966 storage/ipc/procarray.c:2577 -#: utils/adt/formatting.c:1578 utils/adt/formatting.c:1701 -#: utils/adt/formatting.c:1825 utils/adt/pg_locale.c:468 -#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:219 utils/adt/varlena.c:4570 -#: utils/adt/varlena.c:4591 utils/fmgr/dfmgr.c:221 utils/hash/dynahash.c:429 -#: utils/hash/dynahash.c:535 utils/hash/dynahash.c:1047 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3987 utils/misc/guc.c:4003 -#: utils/misc/guc.c:4016 utils/misc/guc.c:6965 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:404 utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 -#: utils/mmgr/mcxt.c:725 utils/mmgr/mcxt.c:760 utils/mmgr/mcxt.c:797 -#: utils/mmgr/mcxt.c:834 utils/mmgr/mcxt.c:868 utils/mmgr/mcxt.c:897 -#: utils/mmgr/mcxt.c:931 utils/mmgr/mcxt.c:982 utils/mmgr/mcxt.c:1016 -#: utils/mmgr/mcxt.c:1050 +#: ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6482 +#: lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 +#: libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2390 +#: postmaster/postmaster.c:2412 postmaster/postmaster.c:3979 +#: postmaster/postmaster.c:4687 postmaster/postmaster.c:4762 +#: postmaster/postmaster.c:5454 postmaster/postmaster.c:5791 +#: replication/libpqwalreceiver/libpqwalreceiver.c:260 +#: replication/logical/logical.c:174 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:781 storage/file/fd.c:1219 storage/file/fd.c:1380 +#: storage/file/fd.c:2286 storage/ipc/procarray.c:1055 +#: storage/ipc/procarray.c:1543 storage/ipc/procarray.c:1550 +#: storage/ipc/procarray.c:1965 storage/ipc/procarray.c:2589 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 +#: utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 +#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4231 utils/misc/guc.c:4247 utils/misc/guc.c:4260 +#: utils/misc/guc.c:7235 utils/misc/tzparser.c:468 utils/mmgr/aset.c:482 +#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 utils/mmgr/generation.c:249 +#: utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 +#: utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 utils/mmgr/mcxt.c:975 +#: utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 +#: utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format msgid "out of memory" msgstr "memoria esaurita" -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "Nome del fork non valido" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "Nomi di fork validi sono \"main\", \"fsm\", \"vm\" e \"init\"." @@ -263,7 +275,7 @@ msgstr "non è stato possibile ottenere informazioni sul file o directory \"%s\" msgid "could not remove file or directory \"%s\": %s\n" msgstr "rimozione del file o directory \"%s\" fallita: %s\n" -#: ../common/saslprep.c:1090 +#: ../common/saslprep.c:1093 #, c-format msgid "password too long" msgstr "password troppo lunga" @@ -273,7 +285,7 @@ msgstr "password troppo lunga" msgid "could not look up effective user ID %ld: %s" msgstr "ID utente effettivo %ld non trovato: %s" -#: ../common/username.c:45 libpq/auth.c:2003 +#: ../common/username.c:45 libpq/auth.c:2038 msgid "user does not exist" msgstr "l'utente non esiste" @@ -395,159 +407,194 @@ msgstr "lettura del SID del gruppo PowerUsers fallita: codice di errore %lu\n" msgid "could not check access token membership: error code %lu\n" msgstr "errore nel controllo del token di appartenenza: codice di errore %lu\n" -#: access/brin/brin.c:866 access/brin/brin.c:937 +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "la richiesta di riassunzione dell'intervallo BRIN per l'indice \"%s\" pagina %u non è stata registrata" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 +#: access/transam/xlog.c:10354 access/transam/xlog.c:10881 +#: access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 +#: access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 +#: access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 +#: access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "il ripristino è in corso" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "le funzioni di controllo BRIN non possono essere eseguite durante il recupero." + +#: access/brin/brin.c:886 access/brin/brin.c:963 #, c-format msgid "block number out of range: %s" msgstr "numero di blocco fuori dall'intervallo consentito: %s" -#: access/brin/brin.c:889 access/brin/brin.c:960 +#: access/brin/brin.c:909 access/brin/brin.c:986 #, c-format msgid "\"%s\" is not a BRIN index" msgstr "\"%s\" non è un indice BRIN" -#: access/brin/brin.c:905 access/brin/brin.c:976 +#: access/brin/brin.c:925 access/brin/brin.c:1002 #, c-format msgid "could not open parent table of index %s" msgstr "apertura della tabella dell'indice %s non riuscita" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:360 -#: access/brin/brin_pageops.c:828 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1376 access/nbtree/nbtinsert.c:678 +#: access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -msgstr "la dimensione %lu della riga dell'indice supera il massimo %lu per l'indice \"%s\"" +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "la dimensione %zu della riga dell'indice supera il massimo %zu per l'indice \"%s\"" -#: access/brin/brin_revmap.c:379 access/brin/brin_revmap.c:385 +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 #, c-format msgid "corrupted BRIN index: inconsistent range map" msgstr "indice BRIN corrotto: mappa di dominio inconsistente" -#: access/brin/brin_revmap.c:401 +#: access/brin/brin_revmap.c:404 #, c-format msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" msgstr "trovata tupla segnaposto avanzata nell'indice BRIN \"%s\", verrà cancellata" -#: access/brin/brin_revmap.c:598 +#: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "tipo di pagina inaspettato 0x%04X nell'indice BRIN \"%s\" blocco %u" -#: access/brin/brin_validate.c:116 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format -msgid "brin operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori brin \"%s\" contiene la funzione %s con numero di supporto non valido %d" +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene la funzione %s con numero di supporto non valido %d" -#: access/brin/brin_validate.c:132 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format -msgid "brin operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori brin \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene la funzione %s con signature errata per il numero di supporto %d" -#: access/brin/brin_validate.c:154 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 #, c-format -msgid "brin operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori brin \"%s\" contiene la funzione %s con numero di strategia non valido %d" +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene l'operatore %s con numero di strategia %d non valido" -#: access/brin/brin_validate.c:183 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:209 #, c-format -msgid "brin operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "la famiglia di operatori brin \"%s\" contiene una specifica ORDER BY non valida per l'operatore %s" +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene una specifica ORDER BY non valida per l'operatore %s" -#: access/brin/brin_validate.c:196 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 #, c-format -msgid "brin operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori brin \"%s\" contiene l'operatore %s con signature non valida" +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene l'operatore %s con signature non valida" -#: access/brin/brin_validate.c:234 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 #, c-format -msgid "brin operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "alla famiglia di operatori brin \"%s\" mancano operatori per i tipi %s e %s" +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s mancano operatori per i tipi %s e %s" #: access/brin/brin_validate.c:244 #, c-format -msgid "brin operator family \"%s\" is missing support function(s) for types %s and %s" -msgstr "alla famiglia di operatori brin \"%s\" mancano funzioni di supporto per i tipi %s e %s" +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s mancano funzioni di supporto per i tipi %s e %s" -#: access/brin/brin_validate.c:257 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format -msgid "brin operator class \"%s\" is missing operator(s)" -msgstr "alla classe di operatori brin \"%s\" mancano operatori" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s mancano operatori" -#: access/brin/brin_validate.c:268 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -msgid "brin operator class \"%s\" is missing support function %d" -msgstr "alla classe di operatori brin \"%s\" manca la funzione di supporto %d" +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s manca la funzione di supporto %d" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1405 +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "il numero di colonne (%d) eccede il limite (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "il numero delle colonne dell'indice (%d) eccede il limite (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:647 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "la riga dell'indice richiede %zu byte, la dimensione massima è %zu" -#: access/common/printtup.c:290 tcop/fastpath.c:182 tcop/fastpath.c:532 -#: tcop/postgres.c:1732 +#: access/common/printtup.c:365 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1755 #, c-format msgid "unsupported format code: %d" msgstr "codice di formato non supportato: %d" -#: access/common/reloptions.c:540 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "è stato superato il limite per i tipi di parametro per la relazione definita dall'utente" -#: access/common/reloptions.c:821 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "RESET non deve contenere valori per i parametri" -#: access/common/reloptions.c:854 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "parametro del namespace \"%s\" sconosciuto" -#: access/common/reloptions.c:1094 parser/parse_clause.c:270 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "parametro \"%s\" non identificato" -#: access/common/reloptions.c:1124 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "parametro \"%s\" specificato più di una volta" -#: access/common/reloptions.c:1140 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "valore non valido per l'opzione booleana \"%s\": %s" -#: access/common/reloptions.c:1152 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "valore non valido per l'opzione intera \"%s\": %s" -#: access/common/reloptions.c:1158 access/common/reloptions.c:1178 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "il valore %s non rientra nei limiti previsti per l'opzione \"%s\"" -#: access/common/reloptions.c:1160 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "I valori validi sono quelli compresi fra \"%d\" e \"%d\"." -#: access/common/reloptions.c:1172 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "valore non valido per l'opzione in virgola mobile \"%s\": %s" -#: access/common/reloptions.c:1180 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "I valori validi sono quelli compresi fra \"%f\" e \"%f\"." @@ -562,18 +609,18 @@ msgstr "Il tipo restituito %s non corrisponde al tipo attesto %s nella colonna % msgid "Number of returned columns (%d) does not match expected column count (%d)." msgstr "il numero di colonne restituito (%d) non coincide col numero di colonne atteso (%d)" -#: access/common/tupconvert.c:318 +#: access/common/tupconvert.c:329 #, c-format msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." msgstr "L'attributo \"%s\" di tipo %s non combacia con l'attributo corrispondente di tipo %s." -#: access/common/tupconvert.c:330 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "L'attributo \"%s\" di tipo %s non esiste nel tipo %s." -#: access/common/tupdesc.c:728 parser/parse_clause.c:815 -#: parser/parse_relation.c:1544 +#: access/common/tupdesc.c:834 parser/parse_clause.c:819 +#: parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "la colonna \"%s\" non può essere dichiarata SETOF" @@ -588,109 +635,64 @@ msgstr "la lista di posting è troppo lunga" msgid "Reduce maintenance_work_mem." msgstr "Riduci maintenance_work_mem." -#: access/gin/ginentrypage.c:110 access/gist/gist.c:1363 -#: access/nbtree/nbtinsert.c:577 access/nbtree/nbtsort.c:488 -#: access/spgist/spgdoinsert.c:1933 -#, c-format -msgid "index row size %zu exceeds maximum %zu for index \"%s\"" -msgstr "la dimensione %zu della riga dell'indice supera il massimo %zu per l'indice \"%s\"" - -#: access/gin/ginfast.c:991 access/transam/xlog.c:10198 -#: access/transam/xlog.c:10716 access/transam/xlogfuncs.c:296 -#: access/transam/xlogfuncs.c:323 access/transam/xlogfuncs.c:362 -#: access/transam/xlogfuncs.c:383 access/transam/xlogfuncs.c:404 -#: access/transam/xlogfuncs.c:474 access/transam/xlogfuncs.c:530 -#, c-format -msgid "recovery is in progress" -msgstr "il ripristino è in corso" - -#: access/gin/ginfast.c:992 +#: access/gin/ginfast.c:1019 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "La lista GIN in attesa non può essere completata durante il recupero." -#: access/gin/ginfast.c:999 +#: access/gin/ginfast.c:1026 #, c-format msgid "\"%s\" is not a GIN index" msgstr "\"%s\" non è un indice GIN" -#: access/gin/ginfast.c:1010 +#: access/gin/ginfast.c:1037 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "non è possibile accedere ad indici temporanei di altre sessioni" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "i vecchi indici GIN non supportano le scansioni sull'intero indice né le ricerche di null" -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "Per correggere questo problema esegui REINDEX INDEX \"%s\"." -#: access/gin/ginutil.c:134 executor/execExpr.c:1765 -#: utils/adt/arrayfuncs.c:3803 utils/adt/arrayfuncs.c:6325 -#: utils/adt/rowtypes.c:927 +#: access/gin/ginutil.c:138 executor/execExpr.c:1867 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 +#: utils/adt/rowtypes.c:935 #, c-format msgid "could not identify a comparison function for type %s" msgstr "non è stato possibile trovare un operatore di confronto per il tipo %s" -#: access/gin/ginvalidate.c:93 -#, c-format -msgid "gin operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "la famiglia di operatori gin \"%s\" contiene la procedura di supporto %s con tipi misti" - -#: access/gin/ginvalidate.c:149 -#, c-format -msgid "gin operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori gin \"%s\" contiene la funzione %s con numero di supporto non valido %d" - -#: access/gin/ginvalidate.c:161 -#, c-format -msgid "gin operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori gin \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" - -#: access/gin/ginvalidate.c:180 -#, c-format -msgid "gin operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori gin \"%s\" contiene l'operatore %s con numero di strategia non valido %d" - -#: access/gin/ginvalidate.c:193 -#, c-format -msgid "gin operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "la famiglia di operatori gin \"%s\" contiene una specifica ORDER BY non valida per l'operatore %s" - -#: access/gin/ginvalidate.c:206 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format -msgid "gin operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori gin \"%s\" contiene l'operatore %s con signature non valida" - -#: access/gin/ginvalidate.c:247 -#, c-format -msgid "gin operator class \"%s\" is missing support function %d" -msgstr "alla classe di operatori gin \"%s\" manca la funzione di supporto %d" +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene la funzione di supporto %s con tipi di input sinistro e destro diversi" #: access/gin/ginvalidate.c:257 #, c-format -msgid "gin operator class \"%s\" is missing support function %d or %d" -msgstr "alla classe di operatori gin \"%s\" mancano le funzioni di supporto %d o %d" +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "alla classe di operatori \"%s\" del metodo di accesso %s manca la funzione di supporto %d o %d" -#: access/gist/gist.c:706 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:713 access/gist/gistvacuum.c:257 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "l'indice \"%s\" contiene una tupla interna marcata come invalida" -#: access/gist/gist.c:708 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:715 access/gist/gistvacuum.c:259 #, c-format msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." msgstr "Ciò è causato da una separazione di pagina incompleta al ripristino del crash prima dell'aggiornamento a PostgreSQL 9.1." -#: access/gist/gist.c:709 access/gist/gistutil.c:739 access/gist/gistutil.c:750 -#: access/gist/gistvacuum.c:261 access/hash/hashutil.c:241 +#: access/gist/gist.c:716 access/gist/gistutil.c:759 access/gist/gistutil.c:770 +#: access/gist/gistvacuum.c:260 access/hash/hashutil.c:241 #: access/hash/hashutil.c:252 access/hash/hashutil.c:264 -#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:519 -#: access/nbtree/nbtpage.c:530 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 +#: access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "Si richiede l'esecuzione di REINDEX." @@ -705,7 +707,7 @@ msgstr "valore non valido per l'opzione \"buffering\"" msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "I valori validi sono \"on\", \"off\" ed \"auto\"." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:231 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "scrittura del blocco %ld del file temporaneo fallita: %m" @@ -720,65 +722,35 @@ msgstr "il metodo picksplit per la colonna %d dell'indice \"%s\" è fallito" msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." msgstr "L'indice non è ottimale. Per ottimizzarlo si contatti uno sviluppatore o si usi la colonna ponendola in seconda posizione nel comando CREATE INDEX." -#: access/gist/gistutil.c:736 access/hash/hashutil.c:238 -#: access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "l'indice \"%s\" contiene una pagina inaspettata completamente a zero al blocco %u" -#: access/gist/gistutil.c:747 access/hash/hashutil.c:249 -#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:527 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "l'indice \"%s\" contiene una pagina corrotta al blocco %u" -#: access/gist/gistvalidate.c:93 -#, c-format -msgid "gist operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "la famiglia di operatori gist \"%s\" contiene la procedura di supporto %s con tipi misti" - -#: access/gist/gistvalidate.c:146 -#, c-format -msgid "gist operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori gist \"%s\" contiene la funzione %s con numero di supporto non valido %d" - -#: access/gist/gistvalidate.c:158 -#, c-format -msgid "gist operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori gist \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" - -#: access/gist/gistvalidate.c:178 -#, c-format -msgid "gist operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori gist \"%s\" contiene l'operatore %s con numero di strategia non valido %d" - #: access/gist/gistvalidate.c:196 #, c-format -msgid "gist operator family \"%s\" contains unsupported ORDER BY specification for operator %s" -msgstr "la famiglia di operatori gist \"%s\" contiene una specifica ORDER BY non supportata per l'operatore %s" +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene una specifica ORDER BY non supportata per l'operatore %s" #: access/gist/gistvalidate.c:207 #, c-format -msgid "gist operator family \"%s\" contains incorrect ORDER BY opfamily specification for operator %s" -msgstr "la famiglia di operatori gist \"%s\" contiene una specifica ORDER BY non corretta per l'operatore %s" - -#: access/gist/gistvalidate.c:226 -#, c-format -msgid "gist operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori gist \"%s\" contiene l'operatore %s con signature non valida" - -#: access/gist/gistvalidate.c:265 -#, c-format -msgid "gist operator class \"%s\" is missing support function %d" -msgstr "-alla classe di operatori gist \"%s\" manca la funzione di supporto %d" +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "la famiglia di operatori \"%s\" del metodo di accesso %s contiene una specifica opfamily ORDER BY non corretta per l'operatore %s" -#: access/hash/hashinsert.c:82 +#: access/hash/hashinsert.c:83 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "la dimensione %zu della riga dell'indice supera il massimo dell'hash %zu" -#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1937 -#: access/spgist/spgutils.c:708 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "Non si possono indicizzare valori più grandi di una pagina di buffer." @@ -788,12 +760,12 @@ msgstr "Non si possono indicizzare valori più grandi di una pagina di buffer." msgid "invalid overflow block number %u" msgstr "numero di blocco di overflow %u non valido" -#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "pagine di overflow esaurite per l'indice hash \"%s\"" -#: access/hash/hashsearch.c:250 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "gli indici hash non supportano scansioni sull'intero indice" @@ -808,187 +780,148 @@ msgstr "l'indice \"%s\" non è un indice hash" msgid "index \"%s\" has wrong hash version" msgstr "l'indice \"%s\" ha una versione errata dell'hash" -#: access/hash/hashvalidate.c:99 +#: access/hash/hashvalidate.c:191 #, c-format -msgid "hash operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "la famiglia di operatori hash \"%s\" contiene la procedura di supporto %s con tipi misti" +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s manca la funzione di supporto per l'operatore %s" -#: access/hash/hashvalidate.c:114 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "hash operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori hash \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s mancano operatori tra tipi diversi" -#: access/hash/hashvalidate.c:131 -#, c-format -msgid "hash operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori hash \"%s\" contiene la funzione %s con numero di supporto non valido %d" - -#: access/hash/hashvalidate.c:152 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori hash \"%s\" contiene l'operatore %s con numero di strategia non valido %d" - -#: access/hash/hashvalidate.c:165 -#, c-format -msgid "hash operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "la famiglia di operatori hash \"%s\" contiene una specifica ORDER BY non valida per l'operatore %s" - -#: access/hash/hashvalidate.c:178 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori hash \"%s\" contiene l'operatore %s con signature non valida" - -#: access/hash/hashvalidate.c:190 -#, c-format -msgid "hash operator family \"%s\" lacks support function for operator %s" -msgstr "alla famiglia di operatori hash \"%s\" manca la funzione di supporto per l'operatore %s" - -#: access/hash/hashvalidate.c:218 -#, c-format -msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "alla famiglia di operatori hash \"%s\" mancano operatori per i tipi %s e %s" - -#: access/hash/hashvalidate.c:232 -#, c-format -msgid "hash operator class \"%s\" is missing operator(s)" -msgstr "alla classe di operatori hash \"%s\" mancano operatori" - -#: access/hash/hashvalidate.c:248 -#, c-format -msgid "hash operator family \"%s\" is missing cross-type operator(s)" -msgstr "alla famiglia di operatori hash \"%s\" mancano operatori tra tipi diversi" - -#: access/heap/heapam.c:1293 access/heap/heapam.c:1321 -#: access/heap/heapam.c:1353 catalog/aclchk.c:1772 +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 +#: access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" msgstr "\"%s\" è un indice" -#: access/heap/heapam.c:1298 access/heap/heapam.c:1326 -#: access/heap/heapam.c:1358 catalog/aclchk.c:1779 commands/tablecmds.c:9876 -#: commands/tablecmds.c:13088 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 +#: access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10329 +#: commands/tablecmds.c:13528 #, c-format msgid "\"%s\" is a composite type" msgstr "\"%s\" è un tipo composito" -#: access/heap/heapam.c:2592 +#: access/heap/heapam.c:2639 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "non è possibile inserire tuple durante un'operazione parallela" +msgid "cannot insert tuples in a parallel worker" +msgstr "non è possibile inserire tuple in un lavoratore parallelo" -#: access/heap/heapam.c:3042 +#: access/heap/heapam.c:3083 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "non è possibile eliminare tuple durante un'operazione parallela" -#: access/heap/heapam.c:3088 +#: access/heap/heapam.c:3129 #, c-format msgid "attempted to delete invisible tuple" msgstr "tentativo di eliminare tuple invisibili" -#: access/heap/heapam.c:3514 access/heap/heapam.c:6214 +#: access/heap/heapam.c:3564 access/heap/heapam.c:6401 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "non è possibile aggiornare tuple durante un'operazione parallela" -#: access/heap/heapam.c:3662 +#: access/heap/heapam.c:3712 #, c-format msgid "attempted to update invisible tuple" msgstr "tentativo di aggiornare tuple invisibili" -#: access/heap/heapam.c:4937 access/heap/heapam.c:4975 -#: access/heap/heapam.c:5227 executor/execMain.c:2588 +#: access/heap/heapam.c:5077 access/heap/heapam.c:5115 +#: access/heap/heapam.c:5367 executor/execMain.c:2662 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "lock di riga nella relazione \"%s\" fallito" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:666 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:670 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "la riga è troppo grande: la dimensione %zu supera il massimo %zu" -#: access/heap/rewriteheap.c:926 +#: access/heap/rewriteheap.c:930 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "scrittura nel file \"%s\" fallita, scritti %d di %d: %m" -#: access/heap/rewriteheap.c:966 access/heap/rewriteheap.c:1183 -#: access/heap/rewriteheap.c:1282 access/transam/timeline.c:412 -#: access/transam/timeline.c:492 access/transam/xlog.c:3250 -#: access/transam/xlog.c:3418 replication/logical/snapbuild.c:1630 -#: replication/slot.c:1232 replication/slot.c:1319 storage/file/fd.c:631 -#: storage/file/fd.c:3180 storage/smgr/md.c:1044 storage/smgr/md.c:1277 -#: storage/smgr/md.c:1450 utils/misc/guc.c:6987 +#: access/heap/rewriteheap.c:970 access/heap/rewriteheap.c:1191 +#: access/heap/rewriteheap.c:1290 access/transam/timeline.c:411 +#: access/transam/timeline.c:490 access/transam/xlog.c:3307 +#: access/transam/xlog.c:3473 replication/logical/snapbuild.c:1645 +#: replication/slot.c:1308 replication/slot.c:1400 storage/file/fd.c:639 +#: storage/file/fd.c:3515 storage/smgr/md.c:1044 storage/smgr/md.c:1277 +#: storage/smgr/md.c:1450 utils/misc/guc.c:7257 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "fsync del file \"%s\" fallito: %m" -#: access/heap/rewriteheap.c:1021 access/heap/rewriteheap.c:1141 -#: access/transam/timeline.c:315 access/transam/timeline.c:467 -#: access/transam/xlog.c:3203 access/transam/xlog.c:3356 -#: access/transam/xlog.c:10533 access/transam/xlog.c:10571 -#: access/transam/xlog.c:10956 postmaster/postmaster.c:4427 -#: replication/logical/origin.c:535 replication/slot.c:1184 -#: storage/file/copydir.c:162 storage/smgr/md.c:327 utils/time/snapmgr.c:1283 +#: access/heap/rewriteheap.c:1024 access/heap/rewriteheap.c:1143 +#: access/transam/timeline.c:314 access/transam/timeline.c:465 +#: access/transam/xlog.c:3261 access/transam/xlog.c:3411 +#: access/transam/xlog.c:10692 access/transam/xlog.c:10730 +#: access/transam/xlog.c:11133 postmaster/postmaster.c:4454 +#: replication/logical/origin.c:575 replication/slot.c:1257 +#: storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 #, c-format msgid "could not create file \"%s\": %m" msgstr "creazione del file \"%s\" fallita: %m" -#: access/heap/rewriteheap.c:1151 +#: access/heap/rewriteheap.c:1153 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "troncamento del file \"%s\" a %u fallito: %m" -#: access/heap/rewriteheap.c:1159 replication/walsender.c:488 -#: storage/smgr/md.c:1949 +#: access/heap/rewriteheap.c:1161 replication/walsender.c:490 +#: storage/smgr/md.c:1986 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "non è stato possibile spostarsi alla fine del file \"%s\": %m" -#: access/heap/rewriteheap.c:1171 access/transam/timeline.c:370 -#: access/transam/timeline.c:405 access/transam/timeline.c:484 -#: access/transam/xlog.c:3239 access/transam/xlog.c:3409 -#: postmaster/postmaster.c:4437 postmaster/postmaster.c:4447 -#: replication/logical/origin.c:544 replication/logical/origin.c:583 -#: replication/logical/origin.c:599 replication/logical/snapbuild.c:1612 -#: replication/slot.c:1215 storage/file/copydir.c:191 -#: utils/init/miscinit.c:1240 utils/init/miscinit.c:1251 -#: utils/init/miscinit.c:1259 utils/misc/guc.c:6948 utils/misc/guc.c:6979 -#: utils/misc/guc.c:8829 utils/misc/guc.c:8843 utils/time/snapmgr.c:1288 -#: utils/time/snapmgr.c:1295 +#: access/heap/rewriteheap.c:1178 access/transam/timeline.c:369 +#: access/transam/timeline.c:404 access/transam/timeline.c:482 +#: access/transam/xlog.c:3293 access/transam/xlog.c:3464 +#: postmaster/postmaster.c:4464 postmaster/postmaster.c:4474 +#: replication/logical/origin.c:590 replication/logical/origin.c:635 +#: replication/logical/origin.c:657 replication/logical/snapbuild.c:1624 +#: replication/slot.c:1291 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1349 utils/init/miscinit.c:1360 +#: utils/init/miscinit.c:1368 utils/misc/guc.c:7218 utils/misc/guc.c:7249 +#: utils/misc/guc.c:9111 utils/misc/guc.c:9125 utils/time/snapmgr.c:1302 +#: utils/time/snapmgr.c:1309 #, c-format msgid "could not write to file \"%s\": %m" msgstr "scrittura nel file \"%s\" fallita: %m" -#: access/heap/rewriteheap.c:1257 access/transam/xlogarchive.c:113 -#: access/transam/xlogarchive.c:467 postmaster/postmaster.c:1253 -#: postmaster/syslogger.c:1371 replication/logical/origin.c:522 -#: replication/logical/reorderbuffer.c:2595 -#: replication/logical/reorderbuffer.c:2652 -#: replication/logical/snapbuild.c:1560 replication/logical/snapbuild.c:1936 -#: replication/slot.c:1292 storage/file/fd.c:682 storage/ipc/dsm.c:327 +#: access/heap/rewriteheap.c:1265 access/transam/xlogarchive.c:113 +#: access/transam/xlogarchive.c:469 postmaster/postmaster.c:1275 +#: postmaster/syslogger.c:1456 replication/logical/origin.c:563 +#: replication/logical/reorderbuffer.c:2800 +#: replication/logical/snapbuild.c:1567 replication/logical/snapbuild.c:1963 +#: replication/slot.c:1370 storage/file/fd.c:690 storage/file/fd.c:3118 +#: storage/file/fd.c:3180 storage/file/reinit.c:255 storage/ipc/dsm.c:315 #: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1397 +#: utils/time/snapmgr.c:1640 #, c-format msgid "could not remove file \"%s\": %m" msgstr "rimozione del file \"%s\" fallita: %m" -#: access/heap/rewriteheap.c:1271 access/transam/timeline.c:111 -#: access/transam/timeline.c:236 access/transam/timeline.c:334 -#: access/transam/xlog.c:3179 access/transam/xlog.c:3300 -#: access/transam/xlog.c:3341 access/transam/xlog.c:3620 -#: access/transam/xlog.c:3698 access/transam/xlogutils.c:706 -#: postmaster/syslogger.c:1380 replication/basebackup.c:474 -#: replication/basebackup.c:1218 replication/logical/origin.c:654 -#: replication/logical/reorderbuffer.c:2113 -#: replication/logical/reorderbuffer.c:2361 -#: replication/logical/reorderbuffer.c:3044 -#: replication/logical/snapbuild.c:1604 replication/logical/snapbuild.c:1692 -#: replication/slot.c:1307 replication/walsender.c:481 -#: replication/walsender.c:2388 storage/file/copydir.c:155 -#: storage/file/fd.c:614 storage/file/fd.c:3092 storage/file/fd.c:3159 -#: storage/smgr/md.c:608 utils/error/elog.c:1879 utils/init/miscinit.c:1171 -#: utils/init/miscinit.c:1299 utils/init/miscinit.c:1376 utils/misc/guc.c:7207 -#: utils/misc/guc.c:7240 +#: access/heap/rewriteheap.c:1279 access/transam/timeline.c:111 +#: access/transam/timeline.c:236 access/transam/timeline.c:333 +#: access/transam/xlog.c:3238 access/transam/xlog.c:3356 +#: access/transam/xlog.c:3397 access/transam/xlog.c:3674 +#: access/transam/xlog.c:3752 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1465 replication/basebackup.c:510 +#: replication/basebackup.c:1384 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2294 +#: replication/logical/reorderbuffer.c:2561 +#: replication/logical/reorderbuffer.c:3274 +#: replication/logical/snapbuild.c:1610 replication/logical/snapbuild.c:1707 +#: replication/slot.c:1385 replication/walsender.c:483 +#: replication/walsender.c:2412 storage/file/copydir.c:161 +#: storage/file/fd.c:622 storage/file/fd.c:3410 storage/file/fd.c:3494 +#: storage/smgr/md.c:608 utils/error/elog.c:1879 utils/init/miscinit.c:1273 +#: utils/init/miscinit.c:1408 utils/init/miscinit.c:1485 utils/misc/guc.c:7477 +#: utils/misc/guc.c:7509 #, c-format msgid "could not open file \"%s\": %m" msgstr "apertura del file \"%s\" fallita: %m" @@ -1004,33 +937,33 @@ msgid "index access method \"%s\" does not have a handler" msgstr "il metodo di accesso dell'indice \"%s\" non ha un handler" #: access/index/indexam.c:160 catalog/objectaddress.c:1223 -#: commands/indexcmds.c:1806 commands/tablecmds.c:247 -#: commands/tablecmds.c:13079 +#: commands/indexcmds.c:2272 commands/tablecmds.c:249 commands/tablecmds.c:273 +#: commands/tablecmds.c:13519 commands/tablecmds.c:14750 #, c-format msgid "\"%s\" is not an index" msgstr "\"%s\" non è un indice" -#: access/nbtree/nbtinsert.c:429 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "un valore chiave duplicato viola il vincolo univoco \"%s\"" -#: access/nbtree/nbtinsert.c:431 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." msgstr "La chiave %s esiste già." -#: access/nbtree/nbtinsert.c:498 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "non ho ritrovato la tupla nell'indice \"%s\"" -#: access/nbtree/nbtinsert.c:500 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "Ciò potrebbe essere causato da un'espressione dell'indice non immutabile." -#: access/nbtree/nbtinsert.c:580 access/nbtree/nbtsort.c:491 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" @@ -1039,122 +972,47 @@ msgstr "" "Non si possono indicizzare valori più grandi di 1/3 di pagina di buffer.\n" "Si consiglia un indice funzionale su un hash MD5 del valore o l'uso del full text indexing." -#: access/nbtree/nbtpage.c:169 access/nbtree/nbtpage.c:372 -#: access/nbtree/nbtpage.c:459 parser/parse_utilcmd.c:1891 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 +#: access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2056 #, c-format msgid "index \"%s\" is not a btree" msgstr "l'indice \"%s\" non è un btree" -#: access/nbtree/nbtpage.c:175 access/nbtree/nbtpage.c:378 -#: access/nbtree/nbtpage.c:465 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 +#: access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "le versioni non corrispondono per l'indice \"%s\": la versione sul file è %d, quella del codice %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "le versioni non corrispondono per l'indice \"%s\": la versione sul file è %d, quella corrente %d, quella minima supportata %d" -#: access/nbtree/nbtpage.c:1153 +#: access/nbtree/nbtpage.c:1320 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "l'indice \"%s\" contiene una pagina interna mezza morta" -#: access/nbtree/nbtpage.c:1155 +#: access/nbtree/nbtpage.c:1322 #, c-format msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." msgstr "Ciò può essere causato da un VACUUM interrotto in una versione 9.3 o precedente, prima dell'aggiornamento. Si consiglia un REINDEX." -#: access/nbtree/nbtvalidate.c:101 -#, c-format -msgid "btree operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori btree \"%s\" contiene la funzione %s con numero di supporto non valido %d" - -#: access/nbtree/nbtvalidate.c:113 -#, c-format -msgid "btree operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori btree \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" - -#: access/nbtree/nbtvalidate.c:133 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori btree \"%s\" contiene l'operatore %s con numero di strategia non valido %d" - -#: access/nbtree/nbtvalidate.c:146 -#, c-format -msgid "btree operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "la famiglia di operatori btree \"%s\" contiene una specifica ORDER BY non valida per l'operatore %s" - -#: access/nbtree/nbtvalidate.c:159 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori btree \"%s\" contiene l'operatore %s con signature non valida" - -#: access/nbtree/nbtvalidate.c:201 -#, c-format -msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "alla famiglia di operatori btree \"%s\" mancano operatori per i tipi %s e %s" - -#: access/nbtree/nbtvalidate.c:211 +#: access/nbtree/nbtvalidate.c:236 #, c-format -msgid "btree operator family \"%s\" is missing support function for types %s and %s" -msgstr "alla famiglia di operatori btree \"%s\" mancano funzioni di supporto per i tipi %s e %s" +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s manca la funzione di supporto per i tipi %s e %s" -#: access/nbtree/nbtvalidate.c:225 +#: access/spgist/spgutils.c:136 #, c-format -msgid "btree operator class \"%s\" is missing operator(s)" -msgstr "alla classe di operatori btree \"%s\" mancano operatori" +msgid "compress method must be defined when leaf type is different from input type" +msgstr "il metodo di compressione dev'essere definito quando il tipo foglia è diverso dal tipo di input" -#: access/nbtree/nbtvalidate.c:242 -#, c-format -msgid "btree operator family \"%s\" is missing cross-type operator(s)" -msgstr "alla famiglia di operatori btree \"%s\" mancano operatori tra tipi diversi" - -#: access/spgist/spgutils.c:705 +#: access/spgist/spgutils.c:743 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "La dimensione %zu della tupla interna SP-GiST supera il massimo %zu" -#: access/spgist/spgvalidate.c:93 -#, c-format -msgid "spgist operator family \"%s\" contains support procedure %s with cross-type registration" -msgstr "la famiglia di operatori spgist \"%s\" contiene la procedura di supporto %s con tipi misti" - -#: access/spgist/spgvalidate.c:116 +#: access/spgist/spgvalidate.c:269 #, c-format -msgid "spgist operator family \"%s\" contains function %s with invalid support number %d" -msgstr "la famiglia di operatori spgist \"%s\" contiene la funzione %s con numero di supporto non valido %d" - -#: access/spgist/spgvalidate.c:128 -#, c-format -msgid "spgist operator family \"%s\" contains function %s with wrong signature for support number %d" -msgstr "la famiglia di operatori spgist \"%s\" contiene la funzione %s con signature non valida per il numero di supporto %d" - -#: access/spgist/spgvalidate.c:147 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with invalid strategy number %d" -msgstr "la famiglia di operatori spgist \"%s\" contiene l'operatore %s con numero di strategia non valido %d" - -#: access/spgist/spgvalidate.c:160 -#, c-format -msgid "spgist operator family \"%s\" contains invalid ORDER BY specification for operator %s" -msgstr "la famiglia di operatori spgist \"%s\" contiene una specifica ORDER BY non valida per l'operatore %s" - -#: access/spgist/spgvalidate.c:173 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with wrong signature" -msgstr "la famiglia di operatori spgist \"%s\" contiene l'operatore %s con signature non valida" - -#: access/spgist/spgvalidate.c:201 -#, c-format -msgid "spgist operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "alla famiglia di operatori spgist \"%s\" mancano operatori per i tipi %s e %s" - -#: access/spgist/spgvalidate.c:221 -#, c-format -msgid "spgist operator family \"%s\" is missing support function %d for type %s" -msgstr "alla famiglia di operatori spgist \"%s\" manca la funzione di supporto %d per il tipo %s" - -#: access/spgist/spgvalidate.c:234 -#, c-format -msgid "spgist operator class \"%s\" is missing operator(s)" -msgstr "alla classe di operatori spgist \"%s\" mancano operatori" +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "alla famiglia di operatori \"%s\" del metodo di accesso %s manca la funzione di supporto %d per il tipo %s" #: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 #, c-format @@ -1191,10 +1049,10 @@ msgstr "il database non sta accettando comandi che generano nuovi MultiXactIds p #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Esegui un VACUUM sull'intero database.\n" -"Potresti anche dover eseguire il commit o il rollback di vecchie transazioni preparate." +"Potresti anche dover eseguire il commit o il rollback di vecchie transazioni preparate, o eliminare vecchi slot di replica." #: access/transam/multixact.c:1007 #, c-format @@ -1265,10 +1123,10 @@ msgstr "il limite di wrap di MultiXactId è %u, limitato dal database con OID %u #, c-format msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "Per evitare lo spegnimento del database, si deve eseguire un VACUUM su tutto il database.\n" -"Potrebbe essere necessario inoltre effettuare il COMMIT o il ROLLBACK di vecchie transazioni preparate." +"Potrebbe essere necessario inoltre effettuare il COMMIT o il ROLLBACK di vecchie transazioni preparate, o eliminare vecchi slot di replica." #: access/transam/multixact.c:2602 #, c-format @@ -1305,78 +1163,88 @@ msgstr "impossibile troncare fino al MultiXact %u perché non esiste su disco, t msgid "invalid MultiXactId: %u" msgstr "MultiXactId non valido: %u" -#: access/transam/parallel.c:577 +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "errore nell'avvio del worker parallelo" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "Potrebbero esserci più dettagli disponibili nel log del server." + +#: access/transam/parallel.c:849 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "il postmaster è terminato durante una transazione parallela" -#: access/transam/parallel.c:764 +#: access/transam/parallel.c:1036 #, c-format msgid "lost connection to parallel worker" msgstr "connessione al worker parallelo perduta" -#: access/transam/parallel.c:823 access/transam/parallel.c:825 +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 msgid "parallel worker" msgstr "worker parallelo" -#: access/transam/parallel.c:968 +#: access/transam/parallel.c:1249 #, c-format msgid "could not map dynamic shared memory segment" msgstr "mappatura del segmento di memoria dinamica condivisa non riuscito" -#: access/transam/parallel.c:973 +#: access/transam/parallel.c:1254 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "numero magico non valido nel segmento di memoria dinamica condivisa" -#: access/transam/slru.c:664 +#: access/transam/slru.c:668 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "il file \"%s\" non esiste, interpretato come zeri" -#: access/transam/slru.c:903 access/transam/slru.c:909 -#: access/transam/slru.c:916 access/transam/slru.c:923 -#: access/transam/slru.c:930 access/transam/slru.c:937 +#: access/transam/slru.c:906 access/transam/slru.c:912 +#: access/transam/slru.c:919 access/transam/slru.c:926 +#: access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "non è stato possibile accedere allo stato della transazione %u" -#: access/transam/slru.c:904 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "Apertura del file \"%s\" fallita: %m." -#: access/transam/slru.c:910 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "Spostamento nel file \"%s\" all'offset %u fallito: %m." -#: access/transam/slru.c:917 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "Lettura dal file \"%s\" all'offset %u fallita: %m." -#: access/transam/slru.c:924 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "Scrittura nel file \"%s\" all'offset %u fallita: %m." -#: access/transam/slru.c:931 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "fsync del file \"%s\" fallito: %m." -#: access/transam/slru.c:938 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "Chiusura del file \"%s\" fallita: %m." -#: access/transam/slru.c:1195 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "troncamento della directory \"%s\" fallito: probabile wraparound" -#: access/transam/slru.c:1250 access/transam/slru.c:1306 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "cancellazione del file \"%s\"" @@ -1416,180 +1284,180 @@ msgstr "dati non validi nel file dello storico \"%s\"" msgid "Timeline IDs must be less than child timeline's ID." msgstr "Gli ID della timeline devono avere valori inferiori degli ID della timeline figlia" -#: access/transam/timeline.c:418 access/transam/timeline.c:498 -#: access/transam/xlog.c:3257 access/transam/xlog.c:3424 -#: access/transam/xlogfuncs.c:693 commands/copy.c:1745 -#: storage/file/copydir.c:206 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 +#: access/transam/xlog.c:3314 access/transam/xlog.c:3479 +#: access/transam/xlogfuncs.c:683 commands/copy.c:1742 +#: storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "chiusura del file \"%s\" fallita: %m" -#: access/transam/timeline.c:580 +#: access/transam/timeline.c:578 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "la timeline richiesta %u non è nella storia di questo server" -#: access/transam/twophase.c:385 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "l'identificativo di transazione \"%s\" è troppo lungo" -#: access/transam/twophase.c:392 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" msgstr "le transazione preparate sono disabilitate" -#: access/transam/twophase.c:393 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "Imposta max_prepared_transactions ad un valore non nullo." -#: access/transam/twophase.c:412 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "l'identificativo di transazione \"%s\" è già in uso" -#: access/transam/twophase.c:421 access/transam/twophase.c:2332 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "è stato raggiunto il numero massimo di transazioni preparate" -#: access/transam/twophase.c:422 access/transam/twophase.c:2333 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "Incrementa il valore di max_prepared_transactions (il valore attuale è %d)" -#: access/transam/twophase.c:583 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "la transazione preparata con identificativo \"%s\" è in uso" -#: access/transam/twophase.c:589 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" msgstr "non è consentito portare a termine la transazione preparata" -#: access/transam/twophase.c:590 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "È consentito solo a un superutente o all'utente che ha preparato la transazione." -#: access/transam/twophase.c:601 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" msgstr "la transazione preparata appartiene ad un altro database" -#: access/transam/twophase.c:602 +#: access/transam/twophase.c:605 #, c-format msgid "Connect to the database where the transaction was prepared to finish it." msgstr "Connettersi al database in cui la transazione è stata preparata per portarla a termine." -#: access/transam/twophase.c:617 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "la transazione preparata con identificativo \"%s\" non esiste" -#: access/transam/twophase.c:1086 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "è stata superata la lunghezza massima del file dello stato a due fasi" -#: access/transam/twophase.c:1204 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "apertura del file dello stato a due fasi \"%s\" fallita: %m" -#: access/transam/twophase.c:1221 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sul file dello stato a due fasi \"%s\": %m" -#: access/transam/twophase.c:1255 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "lettura del file dello stato a due fasi \"%s\" fallita: %m" -#: access/transam/twophase.c:1307 access/transam/xlog.c:6351 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Errore nell'allocazione di un processore di lettura del WAL." -#: access/transam/twophase.c:1313 +#: access/transam/twophase.c:1390 #, c-format msgid "could not read two-phase state from WAL at %X/%X" msgstr "lettura dello stato a due fasi dal WAL a %X/%X fallita" -#: access/transam/twophase.c:1321 +#: access/transam/twophase.c:1398 #, c-format msgid "expected two-phase state data is not present in WAL at %X/%X" msgstr "i dati attesi sullo stato a due fasi non sono presenti nel WAL a %X/%X" -#: access/transam/twophase.c:1556 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "rimozione del file dello stato a due fasi \"%s\" fallita: %m" -#: access/transam/twophase.c:1586 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "ricreazione del file dello stato a due fasi \"%s\" fallita: %m" -#: access/transam/twophase.c:1597 access/transam/twophase.c:1605 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 #, c-format msgid "could not write two-phase state file: %m" msgstr "scrittura nel file dello stato a due fasi fallito: %m" -#: access/transam/twophase.c:1619 +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "fsync del file dello stato a due fasi: %m" -#: access/transam/twophase.c:1626 +#: access/transam/twophase.c:1719 #, c-format msgid "could not close two-phase state file: %m" msgstr "chiusura del file dello stato a due fasi fallita: %m" -#: access/transam/twophase.c:1714 +#: access/transam/twophase.c:1807 #, c-format msgid "%u two-phase state file was written for a long-running prepared transaction" msgid_plural "%u two-phase state files were written for long-running prepared transactions" msgstr[0] "%u file di stato a due fasi scritto per una transazione preparata di lunga durata" msgstr[1] "%u file di stato a due fasi scritti per transazioni preparate di lunga durata" -#: access/transam/twophase.c:1941 +#: access/transam/twophase.c:2036 #, c-format msgid "recovering prepared transaction %u from shared memory" msgstr "recupero di %u transazioni preparate dalla memoria condivisa" -#: access/transam/twophase.c:2026 +#: access/transam/twophase.c:2126 #, c-format -msgid "removing stale two-phase state file for \"%u\"" -msgstr "vecchio file di stato a due fasi per \"%u\" rimosso" +msgid "removing stale two-phase state file for transaction %u" +msgstr "vecchio file di stato a due fasi per la transazione %u rimosso" -#: access/transam/twophase.c:2033 +#: access/transam/twophase.c:2133 #, c-format -msgid "removing stale two-phase state from shared memory for \"%u\"" -msgstr "rimozione del vecchio stato a due fasi dalla memoria condivisa per \"%u\"" +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "rimozione del vecchio stato a due fasi dalla memoria condivisa per la transazione %u" -#: access/transam/twophase.c:2046 +#: access/transam/twophase.c:2146 #, c-format -msgid "removing future two-phase state file for \"%u\"" -msgstr "rimozione del file di stato a due fasi future per \"%u\"" +msgid "removing future two-phase state file for transaction %u" +msgstr "rimozione del file di stato a due fasi future per la transazione %u" -#: access/transam/twophase.c:2053 +#: access/transam/twophase.c:2153 #, c-format -msgid "removing future two-phase state from memory for \"%u\"" -msgstr "rimozione dello stato a due fasi dalla memoria per \"%u\"" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "rimozione dello stato a due fasi dalla memoria per la transazione %u" -#: access/transam/twophase.c:2067 access/transam/twophase.c:2086 +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 #, c-format -msgid "removing corrupt two-phase state file for \"%u\"" -msgstr "rimozione del file di stato a due fasi corrotto per \"%u\"" +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "rimozione del file di stato a due fasi corrotto per la transazione %u" -#: access/transam/twophase.c:2093 +#: access/transam/twophase.c:2193 #, c-format -msgid "removing corrupt two-phase state from memory for \"%u\"" -msgstr "rimozione dello stato a due fasi corrotto dalla memoria per \"%u\"" +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "rimozione dello stato a due fasi corrotto dalla memoria per la transazione %u" #: access/transam/varsup.c:124 #, c-format @@ -1600,10 +1468,10 @@ msgstr "il database non accetta comandi per evitare perdita di dati per wraparou #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"Arresta il processo postmaster ed effettua un VACUUM su quel database in modalità a singolo utente.\n" -"Potrebbe essere necessario inoltre effettuare il COMMIT o il ROLLBACK di vecchie transazioni preparate." +"Arresta il processo postmaster ed effettua un VACUUM su quel database in modalità a utente singolo.\n" +"Potrebbe essere necessario inoltre effettuare il COMMIT o il ROLLBACK di vecchie transazioni preparate, o eliminare vecchi slot di replica." #: access/transam/varsup.c:131 #, c-format @@ -1625,1156 +1493,1179 @@ msgstr "è necessario eseguire il VACUUM sul database con OID %u entro %u transa msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "il limite di sovrascrittura degli ID di transazione è %u, definito dal database con OID %u" -#: access/transam/xact.c:946 +#: access/transam/xact.c:960 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "non è possibile effettuare più di 2^32-2 comandi in una transazione" -#: access/transam/xact.c:1471 +#: access/transam/xact.c:1485 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "il numero massimo di sottotransazioni committed (%d) è stato superato" -#: access/transam/xact.c:2268 +#: access/transam/xact.c:2286 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" msgstr "non è possibile eseguire PREPARE in una transazione che ha operato su tabelle temporanee" -#: access/transam/xact.c:2278 +#: access/transam/xact.c:2296 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "non è possibile eseguire PREPARE in una transazione che ha esportato snapshot" +#: access/transam/xact.c:2305 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "non è possibile eseguire PREPARE in una transazione che ha manipolato i worker di replica logica" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3165 +#: access/transam/xact.c:3190 #, c-format msgid "%s cannot run inside a transaction block" msgstr "non è possibile eseguire %s all'interno di un blocco di transazione" # translator: %s represents an SQL statement name #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3175 +#: access/transam/xact.c:3200 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "non è possibile eseguire %s all'interno di una sottotransazione" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3185 +#: access/transam/xact.c:3210 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "una funzione o una stringa multi-comando non può eseguire %s" +msgid "%s cannot be executed from a function" +msgstr "%s non può essere eseguito da una funzione" # translator: %s represents an SQL statement name #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3256 +#: access/transam/xact.c:3279 access/transam/xact.c:3903 +#: access/transam/xact.c:3972 access/transam/xact.c:4083 #, c-format msgid "%s can only be used in transaction blocks" msgstr "si può usare %s solo entro blocchi di transazione" -#: access/transam/xact.c:3440 +#: access/transam/xact.c:3472 #, c-format msgid "there is already a transaction in progress" msgstr "c'è già una transazione in corso" -#: access/transam/xact.c:3608 access/transam/xact.c:3711 +#: access/transam/xact.c:3583 access/transam/xact.c:3653 +#: access/transam/xact.c:3762 #, c-format msgid "there is no transaction in progress" msgstr "non c'è alcuna transazione in corso" -#: access/transam/xact.c:3619 +#: access/transam/xact.c:3664 #, c-format msgid "cannot commit during a parallel operation" msgstr "non è possibile effettuare un commit durante un'operazione parallela" -#: access/transam/xact.c:3722 +#: access/transam/xact.c:3773 #, c-format msgid "cannot abort during a parallel operation" msgstr "non è possibile interrompere durante un'operazione parallela" -#: access/transam/xact.c:3764 +#: access/transam/xact.c:3867 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "non è possibile definire un punto di salvataggio durante un'operazione parallela" -#: access/transam/xact.c:3831 +#: access/transam/xact.c:3954 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "non è possibile rilasciare un punto di salvataggio durante un'operazione parallela" -#: access/transam/xact.c:3842 access/transam/xact.c:3894 -#: access/transam/xact.c:3900 access/transam/xact.c:3956 -#: access/transam/xact.c:4006 access/transam/xact.c:4012 +#: access/transam/xact.c:3964 access/transam/xact.c:4015 +#: access/transam/xact.c:4075 access/transam/xact.c:4124 #, c-format -msgid "no such savepoint" -msgstr "punto di salvataggio inesistente" +msgid "savepoint \"%s\" does not exist" +msgstr "il punto di salvataggio \"%s\" non esiste" -#: access/transam/xact.c:3944 +#: access/transam/xact.c:4021 access/transam/xact.c:4130 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "il punto di salvataggio \"%s\" non esiste al livello di punti di salvataggio corrente" + +#: access/transam/xact.c:4063 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "non è possibile effettuare un rollback durante un'operazione parallela" -#: access/transam/xact.c:4072 +#: access/transam/xact.c:4191 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "non è possibile iniziare una sub-transazione durante un'operazione parallela" -#: access/transam/xact.c:4139 +#: access/transam/xact.c:4259 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "non è possibile effettuare il commit di una sub-transazione durante un'operazione parallela" -#: access/transam/xact.c:4747 +#: access/transam/xact.c:4897 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "non è possibile avere più di 2^32-1 comandi in una sottotransazione" -#: access/transam/xlog.c:2456 +#: access/transam/xlog.c:2492 #, c-format msgid "could not seek in log file %s to offset %u: %m" msgstr "spostamento nel file di log %s alla posizione %u fallito: %m" -#: access/transam/xlog.c:2478 +#: access/transam/xlog.c:2514 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "scrittura nel file di log %s in posizione %u, lunghezza %zu fallita: %m" -#: access/transam/xlog.c:2742 +#: access/transam/xlog.c:2792 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "punto di recupero minimo aggiornato a %X/%X sulla timeline %u" -#: access/transam/xlog.c:3389 +#: access/transam/xlog.c:3444 #, c-format msgid "not enough data in file \"%s\"" msgstr "il file \"%s\" non contiene abbastanza dati" -#: access/transam/xlog.c:3535 +#: access/transam/xlog.c:3589 #, c-format msgid "could not open write-ahead log file \"%s\": %m" msgstr "apertura del file di log write-ahead \"%s\" fallita: %m" -#: access/transam/xlog.c:3724 access/transam/xlog.c:5536 +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 #, c-format msgid "could not close log file %s: %m" msgstr "chiusura del file di log %s fallita: %m" -#: access/transam/xlog.c:3781 access/transam/xlogutils.c:701 -#: replication/walsender.c:2383 +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 +#: replication/walsender.c:2407 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "il segmento WAL richiesto %s è stato già rimosso" -#: access/transam/xlog.c:3841 access/transam/xlog.c:3916 -#: access/transam/xlog.c:4111 -#, c-format -msgid "could not open write-ahead log directory \"%s\": %m" -msgstr "apertura della directory del log write-ahead \"%s\" fallita: %m" - -#: access/transam/xlog.c:3997 +#: access/transam/xlog.c:4051 #, c-format msgid "recycled write-ahead log file \"%s\"" msgstr "riciclaggio del file di log write-ahead \"%s\"" -#: access/transam/xlog.c:4009 +#: access/transam/xlog.c:4063 #, c-format msgid "removing write-ahead log file \"%s\"" msgstr "rimozione del file di log write-ahead \"%s\"" -#: access/transam/xlog.c:4029 +#: access/transam/xlog.c:4083 #, c-format msgid "could not rename old write-ahead log file \"%s\": %m" msgstr "rinominazione del vecchio file di log write-ahead \"%s\" fallita: %m" -#: access/transam/xlog.c:4071 access/transam/xlog.c:4081 +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "la directory dei file WAL \"%s\" necessaria non esiste" -#: access/transam/xlog.c:4087 +#: access/transam/xlog.c:4141 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "creazione della directory dei file WAL mancante \"%s\"" -#: access/transam/xlog.c:4090 +#: access/transam/xlog.c:4144 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "creazione della directory mancante \"%s\" fallita: %m" -#: access/transam/xlog.c:4201 +#: access/transam/xlog.c:4252 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "ID di timeline %u inatteso nel segmento di log %s, offset %u" -#: access/transam/xlog.c:4323 +#: access/transam/xlog.c:4380 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "la nuova timeline %u non è figlia della timeline %u del database" -#: access/transam/xlog.c:4337 +#: access/transam/xlog.c:4394 #, c-format msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgstr "la nuova timeline %u si è staccata dalla timeline attuale %u prima del punto di recupero corrente %X/%X" -#: access/transam/xlog.c:4356 +#: access/transam/xlog.c:4413 #, c-format msgid "new target timeline is %u" msgstr "la nuova timeline di destinazione %u" -#: access/transam/xlog.c:4431 +#: access/transam/xlog.c:4493 #, c-format msgid "could not create control file \"%s\": %m" msgstr "creazione del file di controllo \"%s\" fallita: %m" -#: access/transam/xlog.c:4443 access/transam/xlog.c:4669 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 #, c-format msgid "could not write to control file: %m" msgstr "scrittura nel file di controllo fallita: %m" -#: access/transam/xlog.c:4451 access/transam/xlog.c:4677 +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 #, c-format msgid "could not fsync control file: %m" msgstr "fsync del file di controllo fallito: %m" -#: access/transam/xlog.c:4457 access/transam/xlog.c:4683 +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 #, c-format msgid "could not close control file: %m" msgstr "chiusura del file di controllo fallita: %m" -#: access/transam/xlog.c:4475 access/transam/xlog.c:4657 +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 #, c-format msgid "could not open control file \"%s\": %m" msgstr "apertura del file di controllo \"%s\" fallita: %m" -#: access/transam/xlog.c:4482 +#: access/transam/xlog.c:4548 #, c-format msgid "could not read from control file: %m" msgstr "lettura dal file di controllo fallita: %m" -#: access/transam/xlog.c:4496 access/transam/xlog.c:4505 -#: access/transam/xlog.c:4529 access/transam/xlog.c:4536 -#: access/transam/xlog.c:4543 access/transam/xlog.c:4548 -#: access/transam/xlog.c:4555 access/transam/xlog.c:4562 -#: access/transam/xlog.c:4569 access/transam/xlog.c:4576 -#: access/transam/xlog.c:4583 access/transam/xlog.c:4590 -#: access/transam/xlog.c:4597 access/transam/xlog.c:4606 -#: access/transam/xlog.c:4613 access/transam/xlog.c:4622 -#: access/transam/xlog.c:4629 utils/init/miscinit.c:1397 +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "errore nella lettura del file di controllo: %d byte letti, %d attesi" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 +#: access/transam/xlog.c:4599 access/transam/xlog.c:4606 +#: access/transam/xlog.c:4613 access/transam/xlog.c:4618 +#: access/transam/xlog.c:4625 access/transam/xlog.c:4632 +#: access/transam/xlog.c:4639 access/transam/xlog.c:4646 +#: access/transam/xlog.c:4653 access/transam/xlog.c:4660 +#: access/transam/xlog.c:4669 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4685 access/transam/xlog.c:4692 +#: utils/init/miscinit.c:1506 #, c-format msgid "database files are incompatible with server" msgstr "i file del database sono incompatibili col server" -#: access/transam/xlog.c:4497 +#: access/transam/xlog.c:4567 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "Il cluster di database è stato inizializzato con PG_CONTROL_VERSION %d (0x%08x), ma il server è stato compilato con PG_CONTROL_VERSION %d (0x%08x)." -#: access/transam/xlog.c:4501 +#: access/transam/xlog.c:4571 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "Questo potrebbe essere un problema di ordinamento di byte che non combacia. Sembra sia necessario eseguire initdb." -#: access/transam/xlog.c:4506 +#: access/transam/xlog.c:4576 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "Il cluster di database è stato inizializzato con PG_CONTROL_VERSION %d, ma il server è stato compilato con PG_CONTROL_VERSION %d." -#: access/transam/xlog.c:4509 access/transam/xlog.c:4533 -#: access/transam/xlog.c:4540 access/transam/xlog.c:4545 +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 +#: access/transam/xlog.c:4610 access/transam/xlog.c:4615 #, c-format msgid "It looks like you need to initdb." msgstr "Sembra sia necessario eseguire initdb." -#: access/transam/xlog.c:4520 +#: access/transam/xlog.c:4590 #, c-format msgid "incorrect checksum in control file" msgstr "il checksum nel file di controllo non è corretto" -#: access/transam/xlog.c:4530 +#: access/transam/xlog.c:4600 #, c-format msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." msgstr "Il cluster di database è stato inizializzato con CATALOG_VERSION_NO %d, ma il server è stato compilato con CATALOG_VERSION_NO %d." -#: access/transam/xlog.c:4537 +#: access/transam/xlog.c:4607 #, c-format msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." msgstr "Il cluster di database è stato inizializzato con MAXALIGN %d, ma il server è stato compilato con MAXALIGN %d." -#: access/transam/xlog.c:4544 +#: access/transam/xlog.c:4614 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "Il cluster di database sta usando un formato per i numeri in virgola mobile diverso da quello usato dall'eseguibile del server." -#: access/transam/xlog.c:4549 +#: access/transam/xlog.c:4619 #, c-format msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "Il cluster di database è stato inizializzato con BLCKSZ %d, ma il server è stato compilato con BLCKSZ %d." -#: access/transam/xlog.c:4552 access/transam/xlog.c:4559 -#: access/transam/xlog.c:4566 access/transam/xlog.c:4573 -#: access/transam/xlog.c:4580 access/transam/xlog.c:4587 -#: access/transam/xlog.c:4594 access/transam/xlog.c:4601 -#: access/transam/xlog.c:4609 access/transam/xlog.c:4616 -#: access/transam/xlog.c:4625 access/transam/xlog.c:4632 +#: access/transam/xlog.c:4622 access/transam/xlog.c:4629 +#: access/transam/xlog.c:4636 access/transam/xlog.c:4643 +#: access/transam/xlog.c:4650 access/transam/xlog.c:4657 +#: access/transam/xlog.c:4664 access/transam/xlog.c:4672 +#: access/transam/xlog.c:4679 access/transam/xlog.c:4688 +#: access/transam/xlog.c:4695 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "Si consiglia di ricompilare il sistema o di eseguire initdb." -#: access/transam/xlog.c:4556 +#: access/transam/xlog.c:4626 #, c-format msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." msgstr "Il cluster di database è stato inizializzato con RELSEG_SIZE %d, ma il server è stato compilato con RELSEG_SIZE %d." -#: access/transam/xlog.c:4563 +#: access/transam/xlog.c:4633 #, c-format msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." msgstr "Il cluster di database è stato inizializzato con XLOG_BLOCKSZ %d, ma il server è stato compilato con XLOG_BLOCKSZ %d." -#: access/transam/xlog.c:4570 -#, c-format -msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." -msgstr "Il cluster di database è stato inizializzato con XLOG_SEG_SIZE %d, ma il server è stato compilato con XLOG_SEG_SIZE %d." - -#: access/transam/xlog.c:4577 +#: access/transam/xlog.c:4640 #, c-format msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." msgstr "Il cluster di database è stato inizializzato con NAMEDATALEN %d, ma il server è stato compilato con NAMEDATALEN %d." -#: access/transam/xlog.c:4584 +#: access/transam/xlog.c:4647 #, c-format msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." msgstr "Il cluster di database è stato inizializzato con INDEX_MAX_KEYS %d, ma il server è stato compilato con INDEX_MAX_KEYS %d." -#: access/transam/xlog.c:4591 +#: access/transam/xlog.c:4654 #, c-format msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." msgstr "Il cluster di database è stato inizializzato con TOAST_MAX_CHUNK_SIZE %d, ma il server è stato compilato con TOAST_MAX_CHUNK_SIZE %d." -#: access/transam/xlog.c:4598 +#: access/transam/xlog.c:4661 #, c-format msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." msgstr "Il cluster di database è stato inizializzato con LOBLKSIZE %d, ma il server è stato compilato con LOBLKSIZE %d." -#: access/transam/xlog.c:4607 +#: access/transam/xlog.c:4670 #, c-format msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." msgstr "Il cluster di database è stato inizializzato senza USE_FLOAT4_BYVAL, ma il server è stato compilato con USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4614 +#: access/transam/xlog.c:4677 #, c-format msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." msgstr "Il cluster di database è stato inizializzato con USE_FLOAT4_BYVAL, ma il server è stato compilato senza USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4623 +#: access/transam/xlog.c:4686 #, c-format msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." msgstr "Il cluster di database è stato inizializzato senza USE_FLOAT8_BYVAL, ma il server è stato compilato con USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4630 +#: access/transam/xlog.c:4693 #, c-format msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." msgstr "Il cluster di database è stato inizializzato con USE_FLOAT8_BYVAL, ma il server è stato compilato senza USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4986 +#: access/transam/xlog.c:4702 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "la dimensione del segmento WAL dev'essere una potenza di due tra 1 MB e 1 GB, ma il file di controllo specifica %d byte" +msgstr[1] "la dimensione del segmento WAL dev'essere una potenza di due tra 1 MB e 1 GB, ma il file di controllo specifica %d byte" + +#: access/transam/xlog.c:4714 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" dev'essere almeno il doppio di \"wal_segment_size\"" + +#: access/transam/xlog.c:4718 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" dev'essere almeno il doppio di \"wal_segment_size\"" + +#: access/transam/xlog.c:5105 #, c-format msgid "could not generate secret authorization token" msgstr "generazione del token segreto di autenticazione fallita" -#: access/transam/xlog.c:5076 +#: access/transam/xlog.c:5195 #, c-format msgid "could not write bootstrap write-ahead log file: %m" msgstr "scrittura del file di bootstrap del log write-ahead fallita: %m" -#: access/transam/xlog.c:5084 +#: access/transam/xlog.c:5203 #, c-format msgid "could not fsync bootstrap write-ahead log file: %m" msgstr "sincronizzazione del file di bootstrap del log write-ahead fallita: %m" -#: access/transam/xlog.c:5090 +#: access/transam/xlog.c:5209 #, c-format msgid "could not close bootstrap write-ahead log file: %m" msgstr "chiusura del file di bootstrap del log write-ahead fallita: %m" -#: access/transam/xlog.c:5166 +#: access/transam/xlog.c:5291 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "apertura del file di ripristino \"%s\" fallita: %m" -#: access/transam/xlog.c:5212 access/transam/xlog.c:5314 +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 #, c-format msgid "invalid value for recovery parameter \"%s\": \"%s\"" msgstr "valore non valido per il parametro di ripristino \"%s\": \"%s\"" -#: access/transam/xlog.c:5215 +#: access/transam/xlog.c:5340 #, c-format msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." msgstr "I valori validi sono \"pause\", \"promote\" e \"shutdown\"." # da non tradurre # DV: perché (già tradotto peraltro) -#: access/transam/xlog.c:5235 +#: access/transam/xlog.c:5360 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" msgstr "recovery_target_timeline non ha un valore numerico valido: \"%s\"" -#: access/transam/xlog.c:5252 +#: access/transam/xlog.c:5377 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" msgstr "recovery_target_xid non ha un valore numerico valido: \"%s\"" -#: access/transam/xlog.c:5283 +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_time non è un timestamp valido: \"%s\"" + +#: access/transam/xlog.c:5420 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "il recovery_target_name è troppo lungo (massimo %d caratteri)" -#: access/transam/xlog.c:5317 +#: access/transam/xlog.c:5454 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "Il solo valore permesso è \"immediate\"." -#: access/transam/xlog.c:5330 access/transam/xlog.c:5341 -#: commands/extension.c:546 commands/extension.c:554 utils/misc/guc.c:5739 +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 +#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5984 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "il parametro \"%s\" richiede un valore booleano" -#: access/transam/xlog.c:5376 +#: access/transam/xlog.c:5513 #, c-format msgid "parameter \"%s\" requires a temporal value" msgstr "il parametro \"%s\" richiede un valore temporale" -#: access/transam/xlog.c:5378 catalog/dependency.c:961 catalog/dependency.c:962 -#: catalog/dependency.c:968 catalog/dependency.c:969 catalog/dependency.c:980 -#: catalog/dependency.c:981 commands/tablecmds.c:927 commands/tablecmds.c:10336 -#: commands/user.c:1030 commands/view.c:505 libpq/auth.c:328 -#: replication/syncrep.c:1130 storage/lmgr/deadlock.c:1139 -#: storage/lmgr/proc.c:1313 utils/adt/acl.c:5248 utils/misc/guc.c:5761 -#: utils/misc/guc.c:5854 utils/misc/guc.c:9810 utils/misc/guc.c:9844 -#: utils/misc/guc.c:9878 utils/misc/guc.c:9912 utils/misc/guc.c:9947 +#: access/transam/xlog.c:5515 catalog/dependency.c:969 catalog/dependency.c:970 +#: catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 +#: catalog/dependency.c:989 commands/tablecmds.c:1069 +#: commands/tablecmds.c:10789 commands/user.c:1064 commands/view.c:509 +#: libpq/auth.c:336 replication/syncrep.c:1158 storage/lmgr/deadlock.c:1139 +#: storage/lmgr/proc.c:1324 utils/adt/acl.c:5344 utils/misc/guc.c:6006 +#: utils/misc/guc.c:6099 utils/misc/guc.c:10089 utils/misc/guc.c:10123 +#: utils/misc/guc.c:10157 utils/misc/guc.c:10191 utils/misc/guc.c:10226 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlog.c:5385 +#: access/transam/xlog.c:5522 #, c-format msgid "unrecognized recovery parameter \"%s\"" msgstr "parametro di ripristino \"%s\" sconosciuto" -#: access/transam/xlog.c:5396 +#: access/transam/xlog.c:5533 #, c-format msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" msgstr "il file dei comandi di ripristino \"%s\" non specifica né primary_conninfo né restore_command" -#: access/transam/xlog.c:5398 +#: access/transam/xlog.c:5535 #, c-format msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." msgstr "Il server database ispezionerà regolarmente la sottodirectory pg_wal per controllare se vi vengono aggiunti dei file.\"" -#: access/transam/xlog.c:5405 +#: access/transam/xlog.c:5542 #, c-format msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" msgstr "il file dei comandi di ripristino \"%s\" deve specificare restore_command quando la modalità standby non è abilitata" -#: access/transam/xlog.c:5426 +#: access/transam/xlog.c:5563 #, c-format msgid "standby mode is not supported by single-user servers" msgstr "la modalità di standby non è supportata per i server a utente singolo" -#: access/transam/xlog.c:5445 +#: access/transam/xlog.c:5582 #, c-format msgid "recovery target timeline %u does not exist" msgstr "la timeline destinazione di recupero %u non esiste" -#: access/transam/xlog.c:5566 +#: access/transam/xlog.c:5703 #, c-format msgid "archive recovery complete" msgstr "il ripristino dell'archivio è stato completato" -#: access/transam/xlog.c:5625 access/transam/xlog.c:5891 +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 #, c-format msgid "recovery stopping after reaching consistency" msgstr "il ripristino è stato interrotto dopo aver raggiunto la consistenza" -#: access/transam/xlog.c:5646 +#: access/transam/xlog.c:5783 #, c-format msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" msgstr "il ripristino è stato interrotto prima della locazione WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:5732 +#: access/transam/xlog.c:5869 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "il ripristino è stato interrotto prima del commit della transazione %u, orario %s" -#: access/transam/xlog.c:5739 +#: access/transam/xlog.c:5876 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "il ripristino è stato interrotto prima dell'abort della transazione %u alle %s" -#: access/transam/xlog.c:5785 +#: access/transam/xlog.c:5922 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "il ripristino è stato interrotto al punto di ripristino \"%s\" alle %s" -#: access/transam/xlog.c:5803 +#: access/transam/xlog.c:5940 #, c-format msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" msgstr "il ripristino è stato interrotto dopo la locazione WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:5871 +#: access/transam/xlog.c:6008 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "il ripristino è stato interrotto dopo il commit della transazione %u alle %s" -#: access/transam/xlog.c:5879 +#: access/transam/xlog.c:6016 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "il ripristino è stato interrotto dopo l'abort della transazione %u alle %s" -#: access/transam/xlog.c:5919 +#: access/transam/xlog.c:6056 #, c-format msgid "recovery has paused" msgstr "ripristino in pausa" -#: access/transam/xlog.c:5920 +#: access/transam/xlog.c:6057 #, c-format msgid "Execute pg_wal_replay_resume() to continue." msgstr "Esegui pg_wal_replay_resume() per continuare." -#: access/transam/xlog.c:6128 +#: access/transam/xlog.c:6265 #, c-format msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" msgstr "l'hot standby non è possibile perché %s = %d è un'impostazione inferiore a quella del server master (il cui valore era %d)" -#: access/transam/xlog.c:6154 +#: access/transam/xlog.c:6291 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "il WAL è stato generato con wal_level=minimal, alcuni dati potrebbero mancare" -#: access/transam/xlog.c:6155 +#: access/transam/xlog.c:6292 #, c-format msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." msgstr "Questo avviene se imposti temporaneamente wal_level=minimal senza effettuare un nuovo backup di base." -#: access/transam/xlog.c:6166 +#: access/transam/xlog.c:6303 #, c-format msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" msgstr "l'hot standby non è possibile perché il wal_level non è impostato a \"replica\" o superiore nel server master" -#: access/transam/xlog.c:6167 +#: access/transam/xlog.c:6304 #, c-format msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." msgstr "Imposta il wal_level a \"replica\" sul master oppure disattiva hot_standby qui." -#: access/transam/xlog.c:6224 +#: access/transam/xlog.c:6356 #, c-format msgid "control file contains invalid data" msgstr "il file di controllo contiene dati non validi" -#: access/transam/xlog.c:6230 +#: access/transam/xlog.c:6362 #, c-format msgid "database system was shut down at %s" msgstr "il database è stato arrestato alle %s" -#: access/transam/xlog.c:6235 +#: access/transam/xlog.c:6367 #, c-format msgid "database system was shut down in recovery at %s" msgstr "il database è stato arrestato durante il ripristino alle %s" -#: access/transam/xlog.c:6239 +#: access/transam/xlog.c:6371 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "l'arresto del database è stato interrotto; l'ultimo segno di vita risale alle %s" -#: access/transam/xlog.c:6243 +#: access/transam/xlog.c:6375 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "il database è stato interrotto alle %s mentre era in fase di ripristino" -#: access/transam/xlog.c:6245 +#: access/transam/xlog.c:6377 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "Questo probabilmente significa che alcuni dati sono corrotti e dovrai usare il backup più recente per il ripristino." -#: access/transam/xlog.c:6249 +#: access/transam/xlog.c:6381 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "il database è stato interrotto all'orario di log %s mentre era in fase di ripristino" -#: access/transam/xlog.c:6251 +#: access/transam/xlog.c:6383 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." msgstr "Se ciò è avvenuto più di una volta, alcuni dati potrebbero essere corrotti e potresti dover scegliere una destinazione di ripristino precedente." -#: access/transam/xlog.c:6255 +#: access/transam/xlog.c:6387 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "il database è stato interrotto; l'ultimo segno di vita risale alle %s" -#: access/transam/xlog.c:6311 +#: access/transam/xlog.c:6443 #, c-format msgid "entering standby mode" msgstr "inizio modalità standby" -#: access/transam/xlog.c:6314 +#: access/transam/xlog.c:6446 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "avvio del ripristino point-in-time allo XID %u" -#: access/transam/xlog.c:6318 +#: access/transam/xlog.c:6450 #, c-format msgid "starting point-in-time recovery to %s" msgstr "avvio del ripristino point-in-time alle %s" -#: access/transam/xlog.c:6322 +#: access/transam/xlog.c:6454 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "avvio del ripristino point-in-time a \"%s\"" -#: access/transam/xlog.c:6326 +#: access/transam/xlog.c:6458 #, c-format msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" msgstr "avvio del ripristino point-in-time alla locazione WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:6331 +#: access/transam/xlog.c:6463 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "avvio del ripristino point-in-time al precedente punto consistente" -#: access/transam/xlog.c:6334 +#: access/transam/xlog.c:6466 #, c-format msgid "starting archive recovery" msgstr "avvio del ripristino dell'archivio" -#: access/transam/xlog.c:6385 access/transam/xlog.c:6513 +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 #, c-format msgid "checkpoint record is at %X/%X" msgstr "il record di checkpoint si trova in %X/%X" -#: access/transam/xlog.c:6399 +#: access/transam/xlog.c:6534 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "localizzazione della posizione di redo referenziata dal record di checkpoint fallita" -#: access/transam/xlog.c:6400 access/transam/xlog.c:6407 +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 #, c-format msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." msgstr "Se non si sta effettuando il ripristino da backup, prova a rimuovere il file \"%s/backup_label\"." -#: access/transam/xlog.c:6406 +#: access/transam/xlog.c:6541 #, c-format msgid "could not locate required checkpoint record" msgstr "localizzazione del record di checkpoint richiesto fallita" -#: access/transam/xlog.c:6432 commands/tablespace.c:639 +#: access/transam/xlog.c:6567 commands/tablespace.c:641 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "creazione del link simbolico \"%s\" fallita: %m" -#: access/transam/xlog.c:6464 access/transam/xlog.c:6470 +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "il file \"%s\" verrà ignorato perché il file \"%s\" non esiste" -#: access/transam/xlog.c:6466 access/transam/xlog.c:11386 +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "Il file \"%s\" è stato rinominato in \"%s\"." -#: access/transam/xlog.c:6472 +#: access/transam/xlog.c:6607 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "Cambio del nome del file da \"%s\" a \"%s\" fallito: %m." -#: access/transam/xlog.c:6523 access/transam/xlog.c:6538 +#: access/transam/xlog.c:6657 #, c-format msgid "could not locate a valid checkpoint record" msgstr "localizzazione di un record di checkpoint valido fallita" -#: access/transam/xlog.c:6532 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "si sta usando il precedente record di checkpoint in %X/%X" - -#: access/transam/xlog.c:6576 +#: access/transam/xlog.c:6695 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "la timeline richiesta %u non è figlia della storia di questo server" -#: access/transam/xlog.c:6578 +#: access/transam/xlog.c:6697 #, c-format msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." msgstr "L'ultimo checkpoint è a %X/%X sulla timeline %u, ma nella storia della timeline richiesta, il server si è separato da quella timeline a %X/%X." -#: access/transam/xlog.c:6594 +#: access/transam/xlog.c:6713 #, c-format msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" msgstr "la timeline richiesta %u non contiene il punto di recupero minimo %X/%X sulla timeline %u" -#: access/transam/xlog.c:6625 +#: access/transam/xlog.c:6744 #, c-format msgid "invalid next transaction ID" msgstr "l'ID della prossima transazione non è valido" -#: access/transam/xlog.c:6719 +#: access/transam/xlog.c:6839 #, c-format msgid "invalid redo in checkpoint record" msgstr "il redo nel record di checkpoint non è valido" -#: access/transam/xlog.c:6730 +#: access/transam/xlog.c:6850 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "record di redo non valido nel checkpoint di arresto" -#: access/transam/xlog.c:6758 +#: access/transam/xlog.c:6878 #, c-format msgid "database system was not properly shut down; automatic recovery in progress" msgstr "il database non è stato arrestato correttamente; ripristino automatico in corso" -#: access/transam/xlog.c:6762 +#: access/transam/xlog.c:6882 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" msgstr "il recupero dal crash comincia nella timeline %u e si conclude nella timeline %u" -#: access/transam/xlog.c:6806 +#: access/transam/xlog.c:6925 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label contiene dati non consistenti col file di controllo" -#: access/transam/xlog.c:6807 +#: access/transam/xlog.c:6926 #, c-format msgid "This means that the backup is corrupted and you will have to use another backup for recovery." msgstr "Questo vuol dire che il backup è corrotto e sarà necessario usare un altro backup per il ripristino." -#: access/transam/xlog.c:6881 +#: access/transam/xlog.c:7017 #, c-format msgid "initializing for hot standby" msgstr "inizializzazione per l'hot standby" -#: access/transam/xlog.c:7013 +#: access/transam/xlog.c:7149 #, c-format msgid "redo starts at %X/%X" msgstr "il redo inizia in %X/%X" -#: access/transam/xlog.c:7247 +#: access/transam/xlog.c:7383 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "lo stop point di ripristino è posto prima di un punto di ripristino consistente" -#: access/transam/xlog.c:7285 +#: access/transam/xlog.c:7421 #, c-format msgid "redo done at %X/%X" msgstr "redo concluso in %X/%X" -#: access/transam/xlog.c:7290 access/transam/xlog.c:9299 +#: access/transam/xlog.c:7426 #, c-format msgid "last completed transaction was at log time %s" msgstr "l'ultima transazione è stata completata all'orario di log %s" -#: access/transam/xlog.c:7299 +#: access/transam/xlog.c:7435 #, c-format msgid "redo is not required" msgstr "redo non richiesto" -#: access/transam/xlog.c:7374 access/transam/xlog.c:7378 +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 #, c-format msgid "WAL ends before end of online backup" msgstr "il WAL termina prima della fine del backup online" -#: access/transam/xlog.c:7375 +#: access/transam/xlog.c:7511 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "Tutti i file WAL generati mentre il backup online veniva effettuato devono essere disponibili al momento del ripristino." -#: access/transam/xlog.c:7379 +#: access/transam/xlog.c:7515 #, c-format msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." msgstr "Un backup online iniziato con pg_start_backup() deve essere terminato con pg_stop_backup(), e tutti i file WAL fino a quel punto devono essere disponibili per il ripristino." -#: access/transam/xlog.c:7382 +#: access/transam/xlog.c:7518 #, c-format msgid "WAL ends before consistent recovery point" msgstr "il WAL termina prima di un punto di ripristino consistente" -#: access/transam/xlog.c:7409 +#: access/transam/xlog.c:7552 #, c-format msgid "selected new timeline ID: %u" msgstr "l'ID della nuova timeline selezionata è %u" -#: access/transam/xlog.c:7838 +#: access/transam/xlog.c:7989 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "è stato raggiunto uno stato di ripristino consistente a %X/%X" -#: access/transam/xlog.c:8030 +#: access/transam/xlog.c:8181 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "il link nel file di controllo al checkpoint primario non è valido" -#: access/transam/xlog.c:8034 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "il link nel file di controllo al checkpoint secondario non è valido" - -#: access/transam/xlog.c:8038 +#: access/transam/xlog.c:8185 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "il link al checkpoint nel file backup_label non è valido" -#: access/transam/xlog.c:8055 +#: access/transam/xlog.c:8202 #, c-format msgid "invalid primary checkpoint record" msgstr "il record del checkpoint primario non è valido" -#: access/transam/xlog.c:8059 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "il record del checkpoint secondario non è valido" - -#: access/transam/xlog.c:8063 +#: access/transam/xlog.c:8206 #, c-format msgid "invalid checkpoint record" msgstr "il record del checkpoint non è valido" -#: access/transam/xlog.c:8074 +#: access/transam/xlog.c:8217 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "l'ID del resource manager nel record del checkpoint primario non è valido" -#: access/transam/xlog.c:8078 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "l'ID del resource manager nel record del checkpoint secondario non è valido" - -#: access/transam/xlog.c:8082 +#: access/transam/xlog.c:8221 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "l'ID del resource manager nel record del checkpoint non è valido" -#: access/transam/xlog.c:8095 +#: access/transam/xlog.c:8234 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "l'xl_info nel record del checkpoint primario non è valido" -#: access/transam/xlog.c:8099 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "l'xl_info nel record del checkpoint secondario non è valido" - -#: access/transam/xlog.c:8103 +#: access/transam/xlog.c:8238 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "l'xl_info nel record del checkpoint non è valido" -#: access/transam/xlog.c:8114 +#: access/transam/xlog.c:8249 #, c-format msgid "invalid length of primary checkpoint record" msgstr "la lunghezza del record del checkpoint primario non è valida" -#: access/transam/xlog.c:8118 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "la lunghezza del record del checkpoint secondario non è valida" - -#: access/transam/xlog.c:8122 +#: access/transam/xlog.c:8253 #, c-format msgid "invalid length of checkpoint record" msgstr "la lunghezza del record del checkpoint non è valida" -#: access/transam/xlog.c:8325 +#: access/transam/xlog.c:8459 #, c-format msgid "shutting down" msgstr "arresto in corso" -#: access/transam/xlog.c:8639 +#: access/transam/xlog.c:8779 #, c-format -msgid "checkpoint skipped due to an idle system" -msgstr "checkpoint saltato per un sistema inattivo" +msgid "checkpoint skipped because system is idle" +msgstr "checkpoint saltato perché il sistema è inattivo" -#: access/transam/xlog.c:8844 +#: access/transam/xlog.c:8984 #, c-format msgid "concurrent write-ahead log activity while database system is shutting down" msgstr "attività concorrente del log write-ahead mentre il database è in fase di arresto" -#: access/transam/xlog.c:9098 +#: access/transam/xlog.c:9241 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "si tralascia il restartpoint, il ripristino è ormai terminato" -#: access/transam/xlog.c:9121 +#: access/transam/xlog.c:9264 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "si tralascia il restartpoint, già eseguito in %X/%X" -#: access/transam/xlog.c:9297 +#: access/transam/xlog.c:9431 #, c-format msgid "recovery restart point at %X/%X" msgstr "punto di avvio del ripristino in %X/%X" #: access/transam/xlog.c:9433 #, c-format +msgid "Last completed transaction was at log time %s." +msgstr "L'ultima transazione completata è stata registrata all'ora %s." + +#: access/transam/xlog.c:9567 +#, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "punto di ripristino \"%s\" creato in %X/%X" -#: access/transam/xlog.c:9563 +#: access/transam/xlog.c:9705 #, c-format msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "timeline precedente con ID %u non prevista (l'ID della timeline corrente è %u) nel record di checkpoint" -#: access/transam/xlog.c:9572 +#: access/transam/xlog.c:9714 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "timeline ID %u imprevista (dopo %u) nel record di checkpoint" -#: access/transam/xlog.c:9588 +#: access/transam/xlog.c:9730 #, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgstr "timeline ID %u imprevista nel record di checkpoint, prima di raggiungere il punto di recupero minimo %X/%X sulla timeline %u" -#: access/transam/xlog.c:9664 +#: access/transam/xlog.c:9806 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "il backup online è stato annullato, il ripristino non può continuare" -#: access/transam/xlog.c:9720 access/transam/xlog.c:9767 -#: access/transam/xlog.c:9790 +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 +#: access/transam/xlog.c:9941 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "l'ID della timeline %u (che dovrebbe essere %u) non era prevista nel record di checkpoint" -#: access/transam/xlog.c:10066 +#: access/transam/xlog.c:10222 #, c-format msgid "could not fsync log segment %s: %m" msgstr "fsync del segmento di log %s fallito: %m" -#: access/transam/xlog.c:10091 +#: access/transam/xlog.c:10247 #, c-format msgid "could not fsync log file %s: %m" msgstr "fsync del file di log %s fallito: %m" -#: access/transam/xlog.c:10099 +#: access/transam/xlog.c:10255 #, c-format msgid "could not fsync write-through log file %s: %m" msgstr "fsync write-through del file di log %s fallito: %m" -#: access/transam/xlog.c:10108 +#: access/transam/xlog.c:10264 #, c-format msgid "could not fdatasync log file %s: %m" msgstr "fdatasync del file di log %s fallito: %m" -#: access/transam/xlog.c:10199 access/transam/xlog.c:10717 -#: access/transam/xlogfuncs.c:297 access/transam/xlogfuncs.c:324 -#: access/transam/xlogfuncs.c:363 access/transam/xlogfuncs.c:384 -#: access/transam/xlogfuncs.c:405 +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 +#: access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 +#: access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 +#: access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "le funzioni di controllo WAL non possono essere eseguite durante il ripristino." -#: access/transam/xlog.c:10208 access/transam/xlog.c:10726 +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "livello WAL non sufficiente per creare un backup online" -#: access/transam/xlog.c:10209 access/transam/xlog.c:10727 -#: access/transam/xlogfuncs.c:330 +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 +#: access/transam/xlogfuncs.c:320 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "Il wal_level deve essere impostato a \"replica\" o \"logical\" all'avvio del server." -#: access/transam/xlog.c:10214 +#: access/transam/xlog.c:10370 #, c-format msgid "backup label too long (max %d bytes)" msgstr "etichetta di backup troppo lunga (massimo %d byte)" -#: access/transam/xlog.c:10251 access/transam/xlog.c:10524 -#: access/transam/xlog.c:10562 +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 +#: access/transam/xlog.c:10721 #, c-format msgid "a backup is already in progress" msgstr "c'è già un backup in corso" -#: access/transam/xlog.c:10252 +#: access/transam/xlog.c:10408 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "Esegui pg_stop_backup() e prova di nuovo." -#: access/transam/xlog.c:10347 +#: access/transam/xlog.c:10504 #, c-format msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" msgstr "un WAL generato con full_page_writes=off è stato riprodotto dopo l'ultimo restartpoint" -#: access/transam/xlog.c:10349 access/transam/xlog.c:10907 +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 #, c-format msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." msgstr "Ciò vuol dire che il backup che sta venendo preso sullo standby è corrotto e non dovrebbe essere usato. Abilita full_page_writes ed esegui CHECKPOINT sul master, poi prova ad effettuare nuovamente un backup online.\"" -#: access/transam/xlog.c:10416 replication/basebackup.c:1096 -#: utils/adt/misc.c:497 +#: access/transam/xlog.c:10574 replication/basebackup.c:1225 +#: utils/adt/misc.c:517 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "lettura del link simbolico \"%s\" fallita: %m" -#: access/transam/xlog.c:10423 replication/basebackup.c:1101 -#: utils/adt/misc.c:502 +#: access/transam/xlog.c:10581 replication/basebackup.c:1230 +#: utils/adt/misc.c:522 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "la destinazione del link simbolico \"%s\" è troppo lunga" -#: access/transam/xlog.c:10476 commands/tablespace.c:389 -#: commands/tablespace.c:551 replication/basebackup.c:1116 utils/adt/misc.c:510 +#: access/transam/xlog.c:10633 commands/tablespace.c:391 +#: commands/tablespace.c:553 replication/basebackup.c:1245 utils/adt/misc.c:530 #, c-format msgid "tablespaces are not supported on this platform" msgstr "i tablespace non sono supportati su questa piattaforma" -#: access/transam/xlog.c:10518 access/transam/xlog.c:10556 -#: access/transam/xlog.c:10765 access/transam/xlogarchive.c:105 -#: access/transam/xlogarchive.c:264 commands/copy.c:1866 commands/copy.c:3051 -#: commands/extension.c:3317 commands/tablespace.c:780 -#: commands/tablespace.c:871 replication/basebackup.c:480 -#: replication/basebackup.c:548 replication/logical/snapbuild.c:1518 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2954 -#: storage/file/fd.c:3046 utils/adt/dbsize.c:70 utils/adt/dbsize.c:227 -#: utils/adt/dbsize.c:307 utils/adt/genfile.c:115 utils/adt/genfile.c:334 -#: guc-file.l:1001 +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 +#: access/transam/xlog.c:10930 access/transam/xlogarchive.c:105 +#: access/transam/xlogarchive.c:265 commands/copy.c:1872 commands/copy.c:3156 +#: commands/extension.c:3319 commands/tablespace.c:782 +#: commands/tablespace.c:873 replication/basebackup.c:516 +#: replication/basebackup.c:586 replication/logical/snapbuild.c:1525 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1732 +#: storage/file/fd.c:3098 storage/file/fd.c:3277 storage/file/fd.c:3362 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:131 utils/adt/genfile.c:382 guc-file.l:1004 #, c-format msgid "could not stat file \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sul file \"%s\": %m" -#: access/transam/xlog.c:10525 access/transam/xlog.c:10563 +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 #, c-format msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." msgstr "Se si è certi che non ci sono backup in corso, rimuovi il file \"%s\" e prova di nuovo." -#: access/transam/xlog.c:10542 access/transam/xlog.c:10580 -#: access/transam/xlog.c:10968 postmaster/syslogger.c:1391 -#: postmaster/syslogger.c:1404 +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 +#: access/transam/xlog.c:11150 postmaster/syslogger.c:1476 +#: postmaster/syslogger.c:1489 #, c-format msgid "could not write file \"%s\": %m" msgstr "scrittura nel file \"%s\" fallita: %m" -#: access/transam/xlog.c:10742 +#: access/transam/xlog.c:10907 #, c-format msgid "exclusive backup not in progress" msgstr "non c'è un backup esclusivo in corso" -#: access/transam/xlog.c:10769 +#: access/transam/xlog.c:10934 #, c-format msgid "a backup is not in progress" msgstr "non c'è un backup in esecuzione" -#: access/transam/xlog.c:10842 access/transam/xlog.c:10855 -#: access/transam/xlog.c:11196 access/transam/xlog.c:11202 -#: access/transam/xlog.c:11286 access/transam/xlogfuncs.c:698 +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 +#: access/transam/xlog.c:11394 access/transam/xlog.c:11400 +#: access/transam/xlog.c:11448 access/transam/xlog.c:11521 +#: access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" msgstr "i dati nel file \"%s\" non sono validi" -#: access/transam/xlog.c:10859 replication/basebackup.c:994 +#: access/transam/xlog.c:11037 replication/basebackup.c:1082 #, c-format msgid "the standby was promoted during online backup" msgstr "lo standby è stato promosso durante il backup online" -#: access/transam/xlog.c:10860 replication/basebackup.c:995 +#: access/transam/xlog.c:11038 replication/basebackup.c:1083 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "Ciò vuol dire che il backup che stava venendo salvato è corrotto e non dovrebbe essere usato. Prova ad effettuare un altro backup online." -#: access/transam/xlog.c:10905 +#: access/transam/xlog.c:11085 #, c-format msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "un WAL generato con full_page_writes=off è stato riprodotto durante il backup online" -#: access/transam/xlog.c:11018 +#: access/transam/xlog.c:11205 #, c-format msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" msgstr "pulizia di pg_stop_backup effettuata, in attesa che i segmenti WAL richiesti vengano archiviati" -#: access/transam/xlog.c:11028 +#: access/transam/xlog.c:11215 #, c-format msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "pg_stop_backup è ancora in attesa che tutti i segmenti WAL richiesti siano stati archiviati (sono passati %d secondi)" -#: access/transam/xlog.c:11030 +#: access/transam/xlog.c:11217 #, c-format msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." msgstr "Controlla che il tuo archive_command venga eseguito correttamente. pg_stop_backup può essere interrotto in sicurezza ma il backup del database non sarà utilizzabile senza tutti i segmenti WAL." -#: access/transam/xlog.c:11037 +#: access/transam/xlog.c:11224 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" msgstr "pg_stop_backup completo, tutti i segmenti WAL richiesti sono stati archiviati" -#: access/transam/xlog.c:11041 +#: access/transam/xlog.c:11228 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" msgstr "l'archiviazione WAL non è abilitata; devi verificare che tutti i segmenti WAL richiesti vengano copiati in qualche altro modo per completare il backup" +#: access/transam/xlog.c:11431 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "ora del backup %s nel file \"%s\"" + +#: access/transam/xlog.c:11436 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "etichetta del backup %s nel file \"%s\"" + +#: access/transam/xlog.c:11449 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "L'ID della timeline letta è %u, ma era atteso %u" + +#: access/transam/xlog.c:11453 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "timeline del backup %u nel file \"%s\"" + #. translator: %s is a WAL record description -#: access/transam/xlog.c:11326 +#: access/transam/xlog.c:11561 #, c-format msgid "WAL redo at %X/%X for %s" msgstr "Ripristino WAL a %X/%X per %s" -#: access/transam/xlog.c:11375 +#: access/transam/xlog.c:11610 #, c-format msgid "online backup mode was not canceled" msgstr "la modalità di backup online non è stata annullata" -#: access/transam/xlog.c:11376 +#: access/transam/xlog.c:11611 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "Non è stato possibile rinominare il file \"%s\" in \"%s\": %m." -#: access/transam/xlog.c:11385 access/transam/xlog.c:11397 -#: access/transam/xlog.c:11407 +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 +#: access/transam/xlog.c:11642 #, c-format msgid "online backup mode canceled" msgstr "modalità backup online annullata" -#: access/transam/xlog.c:11398 +#: access/transam/xlog.c:11633 #, c-format msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "File \"%s\" e \"%s\" rinominati rispettivamente in \"%s\" e \"%s\"." -#: access/transam/xlog.c:11408 +#: access/transam/xlog.c:11643 #, c-format msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." msgstr "File \"%s\" rinominato in \"%s\", ma non è stato possibile rinominare il file \"%s\" in \"%s\": %m." -#: access/transam/xlog.c:11530 access/transam/xlogutils.c:724 -#: replication/walreceiver.c:1006 replication/walsender.c:2400 +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 +#: replication/walreceiver.c:1019 replication/walsender.c:2424 #, c-format msgid "could not seek in log segment %s to offset %u: %m" msgstr "spostamento nel segmento di log %s alla posizione %u fallito: %m" -#: access/transam/xlog.c:11544 +#: access/transam/xlog.c:11785 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "lettura del segmento di log %s, posizione %u fallita: %m" -#: access/transam/xlog.c:12033 +#: access/transam/xlog.c:12314 #, c-format msgid "received promote request" msgstr "richiesta di promozione ricevuta" -#: access/transam/xlog.c:12046 +#: access/transam/xlog.c:12327 #, c-format msgid "trigger file found: %s" msgstr "trovato il file trigger: %s" -#: access/transam/xlog.c:12055 +#: access/transam/xlog.c:12336 #, c-format msgid "could not stat trigger file \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sul file trigger \"%s\": %m" -#: access/transam/xlogarchive.c:243 +#: access/transam/xlogarchive.c:244 #, c-format msgid "archive file \"%s\" has wrong size: %lu instead of %lu" msgstr "il file archivio \"%s\" è di dimensione errata: %lu invece di %lu" -#: access/transam/xlogarchive.c:252 +#: access/transam/xlogarchive.c:253 #, c-format msgid "restored log file \"%s\" from archive" msgstr "file di log \"%s\" ripristinato dall'archivio" -#: access/transam/xlogarchive.c:302 +#: access/transam/xlogarchive.c:303 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "non è stato possibile ripristinare il file \"%s\" dall'archivio: %s" @@ -2782,286 +2673,281 @@ msgstr "non è stato possibile ripristinare il file \"%s\" dall'archivio: %s" #. translator: First %s represents a recovery.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:414 +#: access/transam/xlogarchive.c:416 #, c-format msgid "%s \"%s\": %s" msgstr "%s \"%s\": %s" -#: access/transam/xlogarchive.c:457 postmaster/syslogger.c:1415 -#: replication/logical/snapbuild.c:1645 replication/slot.c:534 -#: replication/slot.c:1131 replication/slot.c:1245 storage/file/fd.c:642 -#: storage/file/fd.c:737 utils/time/snapmgr.c:1306 +#: access/transam/xlogarchive.c:459 postmaster/syslogger.c:1500 +#: replication/logical/snapbuild.c:1660 replication/slot.c:598 +#: replication/slot.c:1206 replication/slot.c:1321 storage/file/fd.c:650 +#: storage/file/fd.c:745 utils/time/snapmgr.c:1318 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "non è stato possibile rinominare il file \"%s\" in \"%s\": %m" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#: access/transam/xlogarchive.c:526 access/transam/xlogarchive.c:590 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "creazione del file di stato dell'archivio \"%s\" fallita: %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:596 +#: access/transam/xlogarchive.c:534 access/transam/xlogarchive.c:598 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "scrittura del file di stato dell'archivio \"%s\" fallita: %m" -#: access/transam/xlogfuncs.c:55 +#: access/transam/xlogfuncs.c:54 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "interruzione del backup perché il backend è terminato prima della chiamata di pg_stop_backup" -#: access/transam/xlogfuncs.c:86 +#: access/transam/xlogfuncs.c:84 #, c-format msgid "a backup is already in progress in this session" msgstr "c'è già un backup in corso in questa sessione" -#: access/transam/xlogfuncs.c:92 commands/tablespace.c:703 -#: commands/tablespace.c:713 postmaster/postmaster.c:1448 -#: replication/basebackup.c:368 replication/basebackup.c:708 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2420 -#: storage/file/fd.c:3019 storage/ipc/dsm.c:301 utils/adt/genfile.c:440 -#: utils/adt/misc.c:410 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "apertura della directory \"%s\" fallita: %m" - -#: access/transam/xlogfuncs.c:152 access/transam/xlogfuncs.c:234 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format msgid "non-exclusive backup in progress" msgstr "il backup in corso non è esclusivo" -#: access/transam/xlogfuncs.c:153 access/transam/xlogfuncs.c:235 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "Forse intendevi usare pg_stop_backup('f')?" -#: access/transam/xlogfuncs.c:205 commands/event_trigger.c:1471 -#: commands/event_trigger.c:2022 commands/extension.c:1894 -#: commands/extension.c:2003 commands/extension.c:2227 commands/prepare.c:721 -#: executor/execExpr.c:2106 executor/execSRF.c:688 executor/functions.c:1028 -#: foreign/foreign.c:488 libpq/hba.c:2563 replication/logical/launcher.c:923 -#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1387 -#: replication/slotfuncs.c:197 replication/walsender.c:3154 -#: utils/adt/jsonfuncs.c:1688 utils/adt/jsonfuncs.c:1818 -#: utils/adt/jsonfuncs.c:2006 utils/adt/jsonfuncs.c:2133 -#: utils/adt/jsonfuncs.c:3473 utils/adt/pgstatfuncs.c:456 -#: utils/adt/pgstatfuncs.c:557 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8538 -#: utils/mmgr/portalmem.c:1053 +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 +#: commands/event_trigger.c:2016 commands/extension.c:1895 +#: commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:722 +#: executor/execExpr.c:2208 executor/execSRF.c:715 executor/functions.c:1034 +#: foreign/foreign.c:488 libpq/hba.c:2600 replication/logical/launcher.c:1127 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 +#: replication/slotfuncs.c:200 replication/walsender.c:3203 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 +#: utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8820 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "la funzione che restituisce insiemi è chiamata in un contesto che non può accettare un insieme" -#: access/transam/xlogfuncs.c:209 commands/event_trigger.c:1475 -#: commands/event_trigger.c:2026 commands/extension.c:1898 -#: commands/extension.c:2007 commands/extension.c:2231 commands/prepare.c:725 -#: foreign/foreign.c:493 libpq/hba.c:2567 replication/logical/launcher.c:927 -#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1391 -#: replication/slotfuncs.c:201 replication/walsender.c:3158 -#: utils/adt/pgstatfuncs.c:460 utils/adt/pgstatfuncs.c:561 -#: utils/misc/guc.c:8542 utils/misc/pg_config.c:44 utils/mmgr/portalmem.c:1057 +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 +#: commands/event_trigger.c:2020 commands/extension.c:1899 +#: commands/extension.c:2008 commands/extension.c:2232 commands/prepare.c:726 +#: foreign/foreign.c:493 libpq/hba.c:2604 replication/logical/launcher.c:1131 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 +#: replication/slotfuncs.c:204 replication/walsender.c:3207 +#: utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 +#: utils/misc/guc.c:8824 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "necessaria modalità materializzata, ma non ammessa in questo contesto" -#: access/transam/xlogfuncs.c:251 +#: access/transam/xlogfuncs.c:241 #, c-format msgid "non-exclusive backup is not in progress" msgstr "non c'è un backup non esclusivo in corso" -#: access/transam/xlogfuncs.c:252 +#: access/transam/xlogfuncs.c:242 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "Forse intendevi usare pg_stop_backup('t')?" -#: access/transam/xlogfuncs.c:329 +#: access/transam/xlogfuncs.c:319 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "livello WAL non sufficiente per creare un punto di ripristino" -#: access/transam/xlogfuncs.c:337 +#: access/transam/xlogfuncs.c:327 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "il valore è troppo lungo per un punto di ripristino (massimo %d caratteri)" -#: access/transam/xlogfuncs.c:475 +#: access/transam/xlogfuncs.c:465 #, c-format msgid "pg_walfile_name_offset() cannot be executed during recovery." msgstr "pg_walfile_name_offset() non può essere eseguita in fase di recupero." -#: access/transam/xlogfuncs.c:531 +#: access/transam/xlogfuncs.c:521 #, c-format msgid "pg_walfile_name() cannot be executed during recovery." msgstr "pg_walfile_name() non può essere eseguita in fase di recupero." -#: access/transam/xlogfuncs.c:551 access/transam/xlogfuncs.c:571 -#: access/transam/xlogfuncs.c:588 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" msgstr "il recupero non è in corso" -#: access/transam/xlogfuncs.c:552 access/transam/xlogfuncs.c:572 -#: access/transam/xlogfuncs.c:589 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "Le funzioni di controllo del recupero possono essere eseguite solo durante un recupero." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "offset del record non valido a %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "contrecord richiesto da %X/%X" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:625 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "lunghezza del record a %X/%X non valida: atteso %u, ricevuto %u" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:363 #, c-format msgid "record length %u at %X/%X too long" msgstr "lunghezza del record %u a %X/%X eccessiva" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "non c'è un flag di contrecord a %X/%X" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "lunghezza di contrecord %u non valida a %X/%X" -#: access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:654 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ID di gestione risorse %u non valido a %X/%X" -#: access/transam/xlogreader.c:647 access/transam/xlogreader.c:664 +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "record con link-precedente %X/%X non corretto a %X/%X" -#: access/transam/xlogreader.c:701 +#: access/transam/xlogreader.c:722 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "checksum dei dati del manager di risorse non corretto nel record a %X/%X" -#: access/transam/xlogreader.c:734 +#: access/transam/xlogreader.c:759 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "numero magico %04X non valido nel segmento di log %s, offset %u" -#: access/transam/xlogreader.c:748 access/transam/xlogreader.c:799 +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "bit di info %04X non validi nel segmento di log %s, offset %u" -#: access/transam/xlogreader.c:774 +#: access/transam/xlogreader.c:799 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "il file di WAL è di un database diverso: l'identificativo del file di WAL del database è %s, l'identificativo di pg_control del database è %s" -#: access/transam/xlogreader.c:781 +#: access/transam/xlogreader.c:806 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "il file di WAL è di un database diverso: XLOG_SEG_SIZE non corretto nell'header di pagina" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "il file di WAL è di un diverso database: dimensione del segmento sbagliata nell'header di pagina" -#: access/transam/xlogreader.c:787 +#: access/transam/xlogreader.c:812 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "il file di WAL è di un database diverso: XLOG_BLCKSZ non corretto nell'header di pagina" -#: access/transam/xlogreader.c:813 +#: access/transam/xlogreader.c:843 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "pageaddr inaspettato %X/%X nel segmento di log %s, offset %u" -#: access/transam/xlogreader.c:838 +#: access/transam/xlogreader.c:868 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "ID della timeline %u (dopo %u) fuori sequenza nel segmento di log %s, offset %u" -#: access/transam/xlogreader.c:1083 +#: access/transam/xlogreader.c:1113 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id fuori sequenza %u a %X/%X" -#: access/transam/xlogreader.c:1106 +#: access/transam/xlogreader.c:1136 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA impostato, ma dati non inclusi a %X/%X" -#: access/transam/xlogreader.c:1113 +#: access/transam/xlogreader.c:1143 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA non impostato, ma la lunghezza dei dati è %u a %X/%X" -#: access/transam/xlogreader.c:1149 +#: access/transam/xlogreader.c:1179 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE impostato, ma offset buco %u lunghezza %u lunghezza dell'immagine del blocco %u a %X/%X" -#: access/transam/xlogreader.c:1165 +#: access/transam/xlogreader.c:1195 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE non impostato, ma offset buco %u lunghezza %u a %X/%X" -#: access/transam/xlogreader.c:1180 +#: access/transam/xlogreader.c:1210 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED impostato, ma la lunghezza dell'immagine del blocco è %u a %X/%X" -#: access/transam/xlogreader.c:1195 +#: access/transam/xlogreader.c:1225 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "né BKPIMAGE_HAS_HOLE né BKPIMAGE_IS_COMPRESSED impostati, ma la lunghezza dell'immagine del blocco è %u a %X/%X" -#: access/transam/xlogreader.c:1211 +#: access/transam/xlogreader.c:1241 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL impostato ma non c'è un rel precedente a %X/%X" -#: access/transam/xlogreader.c:1223 +#: access/transam/xlogreader.c:1253 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "block_id %u non valido a %X/%X" -#: access/transam/xlogreader.c:1291 +#: access/transam/xlogreader.c:1342 #, c-format msgid "record with invalid length at %X/%X" msgstr "record con lunghezza non valida a %X/%X" -#: access/transam/xlogreader.c:1380 +#: access/transam/xlogreader.c:1431 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "immagine compressa non valida a %X/%X, blocco %d" -#: access/transam/xlogutils.c:747 replication/walsender.c:2419 +#: access/transam/xlogutils.c:751 replication/walsender.c:2443 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "lettura del segmento di log %s, posizione %u, lunghezza %lu fallita: %m" -#: bootstrap/bootstrap.c:272 postmaster/postmaster.c:815 tcop/postgres.c:3495 +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X richiede una potenza di due tra 1 MB e 1 GB" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:826 tcop/postgres.c:3558 #, c-format msgid "--%s requires a value" msgstr "--%s richiede un valore" -#: bootstrap/bootstrap.c:277 postmaster/postmaster.c:820 tcop/postgres.c:3500 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:831 tcop/postgres.c:3563 #, c-format msgid "-c %s requires a value" msgstr "-c %s richiede un valore" -#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:832 -#: postmaster/postmaster.c:845 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:843 +#: postmaster/postmaster.c:856 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: bootstrap/bootstrap.c:297 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: parametri della riga di comando non validi\n" @@ -3111,588 +2997,688 @@ msgstr "non è stato possibile revocare tutti i privilegi per la colonna \"%s\" msgid "not all privileges could be revoked for \"%s\"" msgstr "non è stato possibile revocare tutti i privilegi per \"%s\"" -#: catalog/aclchk.c:455 catalog/aclchk.c:948 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" msgstr "tipo di privilegio %s non valido per la relazione" -#: catalog/aclchk.c:459 catalog/aclchk.c:952 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" msgstr "tipo di privilegio %s non valido per la sequenza" -#: catalog/aclchk.c:463 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "tipo di privilegio %s non valido per il database" -#: catalog/aclchk.c:467 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "tipo di privilegio %s non valido per il dominio" -#: catalog/aclchk.c:471 catalog/aclchk.c:956 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" msgstr "tipo di privilegio %s non valido per la funzione" -#: catalog/aclchk.c:475 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "tipo di privilegio %s non valido per il linguaggio" -#: catalog/aclchk.c:479 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "tipo di privilegio %s non valido per il large object" -#: catalog/aclchk.c:483 catalog/aclchk.c:964 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" msgstr "tipo di privilegio %s non valido per lo schema" -#: catalog/aclchk.c:487 +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "tipo di privilegio %s non valido per la procedura" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "tipo di privilegio %s non valido per la routine" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "tipo di privilegio %s non valido per il tablespace" -#: catalog/aclchk.c:491 catalog/aclchk.c:960 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" msgstr "tipo di privilegio %s non valido per il tipo" -#: catalog/aclchk.c:495 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "tipo di privilegio %s non valido per il wrapper di dati esterni" -#: catalog/aclchk.c:499 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "tipo di privilegio %s non valido per il server esterno" -#: catalog/aclchk.c:538 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "i privilegi della colonna sono validi solo per le relazioni" -#: catalog/aclchk.c:696 catalog/aclchk.c:3926 catalog/aclchk.c:4708 -#: catalog/objectaddress.c:929 catalog/pg_largeobject.c:111 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 +#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 +#: storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" msgstr "il large object %u non esiste" -#: catalog/aclchk.c:885 catalog/aclchk.c:894 commands/collationcmds.c:106 -#: commands/copy.c:1040 commands/copy.c:1060 commands/copy.c:1069 -#: commands/copy.c:1078 commands/copy.c:1087 commands/copy.c:1096 -#: commands/copy.c:1105 commands/copy.c:1114 commands/copy.c:1123 -#: commands/copy.c:1141 commands/copy.c:1157 commands/copy.c:1177 -#: commands/copy.c:1194 commands/dbcommands.c:155 commands/dbcommands.c:164 +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 +#: commands/copy.c:1057 commands/copy.c:1077 commands/copy.c:1086 +#: commands/copy.c:1095 commands/copy.c:1104 commands/copy.c:1113 +#: commands/copy.c:1122 commands/copy.c:1131 commands/copy.c:1140 +#: commands/copy.c:1158 commands/copy.c:1174 commands/copy.c:1194 +#: commands/copy.c:1211 commands/dbcommands.c:155 commands/dbcommands.c:164 #: commands/dbcommands.c:173 commands/dbcommands.c:182 #: commands/dbcommands.c:191 commands/dbcommands.c:200 #: commands/dbcommands.c:209 commands/dbcommands.c:218 #: commands/dbcommands.c:227 commands/dbcommands.c:1427 #: commands/dbcommands.c:1436 commands/dbcommands.c:1445 -#: commands/dbcommands.c:1454 commands/extension.c:1677 -#: commands/extension.c:1687 commands/extension.c:1697 -#: commands/extension.c:1707 commands/extension.c:2947 +#: commands/dbcommands.c:1454 commands/extension.c:1678 +#: commands/extension.c:1688 commands/extension.c:1698 +#: commands/extension.c:1708 commands/extension.c:2949 #: commands/foreigncmds.c:537 commands/foreigncmds.c:546 -#: commands/functioncmds.c:526 commands/functioncmds.c:643 -#: commands/functioncmds.c:652 commands/functioncmds.c:661 -#: commands/functioncmds.c:670 commands/functioncmds.c:2077 -#: commands/functioncmds.c:2085 commands/publicationcmds.c:90 -#: commands/sequence.c:1288 commands/sequence.c:1297 commands/sequence.c:1306 -#: commands/sequence.c:1315 commands/sequence.c:1324 commands/sequence.c:1333 -#: commands/sequence.c:1342 commands/sequence.c:1351 commands/sequence.c:1360 -#: commands/subscriptioncmds.c:106 commands/subscriptioncmds.c:116 -#: commands/subscriptioncmds.c:126 commands/subscriptioncmds.c:136 -#: commands/subscriptioncmds.c:150 commands/subscriptioncmds.c:161 -#: commands/tablecmds.c:5951 commands/typecmds.c:298 commands/typecmds.c:1375 -#: commands/typecmds.c:1384 commands/typecmds.c:1392 commands/typecmds.c:1400 -#: commands/typecmds.c:1408 commands/user.c:135 commands/user.c:149 -#: commands/user.c:158 commands/user.c:167 commands/user.c:176 -#: commands/user.c:185 commands/user.c:194 commands/user.c:203 -#: commands/user.c:212 commands/user.c:221 commands/user.c:230 -#: commands/user.c:239 commands/user.c:248 commands/user.c:533 -#: commands/user.c:541 commands/user.c:549 commands/user.c:557 -#: commands/user.c:565 commands/user.c:573 commands/user.c:581 -#: commands/user.c:589 commands/user.c:598 commands/user.c:606 -#: commands/user.c:614 parser/parse_utilcmd.c:398 -#: replication/pgoutput/pgoutput.c:107 replication/pgoutput/pgoutput.c:128 -#: replication/walsender.c:807 replication/walsender.c:818 -#: replication/walsender.c:828 +#: commands/functioncmds.c:559 commands/functioncmds.c:684 +#: commands/functioncmds.c:693 commands/functioncmds.c:702 +#: commands/functioncmds.c:711 commands/functioncmds.c:2105 +#: commands/functioncmds.c:2113 commands/publicationcmds.c:92 +#: commands/sequence.c:1256 commands/sequence.c:1266 commands/sequence.c:1276 +#: commands/sequence.c:1286 commands/sequence.c:1296 commands/sequence.c:1306 +#: commands/sequence.c:1316 commands/sequence.c:1326 commands/sequence.c:1336 +#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 +#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 +#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 +#: commands/subscriptioncmds.c:179 commands/tablecmds.c:6261 +#: commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 +#: commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 +#: commands/user.c:134 commands/user.c:148 commands/user.c:157 +#: commands/user.c:166 commands/user.c:175 commands/user.c:184 +#: commands/user.c:193 commands/user.c:202 commands/user.c:211 +#: commands/user.c:220 commands/user.c:229 commands/user.c:238 +#: commands/user.c:247 commands/user.c:555 commands/user.c:563 +#: commands/user.c:571 commands/user.c:579 commands/user.c:587 +#: commands/user.c:595 commands/user.c:603 commands/user.c:611 +#: commands/user.c:620 commands/user.c:628 commands/user.c:636 +#: parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 +#: replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "opzioni contraddittorie o ridondanti" -#: catalog/aclchk.c:997 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "i privilegi predefiniti non possono essere impostati sulle colonne" -#: catalog/aclchk.c:1157 +#: catalog/aclchk.c:1212 #, c-format msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" msgstr "non è possibile usare la clausola IN SCHEMA usando GRANT/REVOKE ON SCHEMAS" -#: catalog/aclchk.c:1521 catalog/objectaddress.c:1390 commands/analyze.c:390 -#: commands/copy.c:4670 commands/sequence.c:1731 commands/tablecmds.c:5599 -#: commands/tablecmds.c:5746 commands/tablecmds.c:5803 -#: commands/tablecmds.c:5876 commands/tablecmds.c:5970 -#: commands/tablecmds.c:6029 commands/tablecmds.c:6154 -#: commands/tablecmds.c:6208 commands/tablecmds.c:6300 -#: commands/tablecmds.c:6456 commands/tablecmds.c:8685 -#: commands/tablecmds.c:8961 commands/tablecmds.c:9396 commands/trigger.c:758 -#: parser/analyze.c:2310 parser/parse_relation.c:2699 -#: parser/parse_relation.c:2761 parser/parse_target.c:1002 -#: parser/parse_type.c:127 utils/adt/acl.c:2823 utils/adt/ruleutils.c:2349 +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 +#: commands/copy.c:4776 commands/sequence.c:1691 commands/tablecmds.c:5907 +#: commands/tablecmds.c:6055 commands/tablecmds.c:6112 +#: commands/tablecmds.c:6186 commands/tablecmds.c:6280 +#: commands/tablecmds.c:6339 commands/tablecmds.c:6478 +#: commands/tablecmds.c:6560 commands/tablecmds.c:6652 +#: commands/tablecmds.c:6746 commands/tablecmds.c:9082 +#: commands/tablecmds.c:9361 commands/tablecmds.c:9777 commands/trigger.c:904 +#: parser/analyze.c:2337 parser/parse_relation.c:2735 +#: parser/parse_relation.c:2798 parser/parse_target.c:1024 +#: parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2464 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "la colonna \"%s\" della relazione \"%s\" non esiste" -#: catalog/aclchk.c:1787 catalog/objectaddress.c:1230 commands/sequence.c:1146 -#: commands/tablecmds.c:229 commands/tablecmds.c:13053 utils/adt/acl.c:2059 -#: utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 -#: utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1129 +#: commands/tablecmds.c:231 commands/tablecmds.c:13492 utils/adt/acl.c:2076 +#: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 +#: utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\" non è una sequenza" -#: catalog/aclchk.c:1825 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "la sequenza \"%s\" supporta solo i privilegi USAGE, SELECT e UPDATE" -#: catalog/aclchk.c:1842 +#: catalog/aclchk.c:1898 #, c-format msgid "invalid privilege type %s for table" msgstr "tipo di privilegio %s non valido per la tabella" -#: catalog/aclchk.c:2008 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" msgstr "tipo di privilegio %s non valido per la colonna" -#: catalog/aclchk.c:2021 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "la sequenza \"%s\" supporta solo i privilegi di SELECT sulla colonna" -#: catalog/aclchk.c:2603 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "il linguaggio \"%s\" non è fidato" -#: catalog/aclchk.c:2605 +#: catalog/aclchk.c:2661 #, c-format msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." msgstr "GRANT e REVOKE non sono ammessi sui linguaggi non fidati, perché i linguaggi non fidati possono essere usati solo da superutenti." -#: catalog/aclchk.c:3119 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "non è possibile impostare privilegi su tipi array" -#: catalog/aclchk.c:3120 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "Puoi impostare i privilegi del tipo dell'elemento." -#: catalog/aclchk.c:3127 catalog/objectaddress.c:1520 commands/typecmds.c:3165 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" msgstr "\"%s\" non è un dominio" -#: catalog/aclchk.c:3247 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "tipo di privilegio \"%s\" sconosciuto" -#: catalog/aclchk.c:3296 +#: catalog/aclchk.c:3364 #, c-format -msgid "permission denied for column %s" -msgstr "permesso negato per la colonna %s" +msgid "permission denied for aggregate %s" +msgstr "permesso negato per l'aggregato %s" -#: catalog/aclchk.c:3298 +#: catalog/aclchk.c:3367 #, c-format -msgid "permission denied for relation %s" -msgstr "permesso negato per la relazione %s" +msgid "permission denied for collation %s" +msgstr "permesso negato per l'ordinamento %s" -#: catalog/aclchk.c:3300 commands/sequence.c:608 commands/sequence.c:842 -#: commands/sequence.c:884 commands/sequence.c:925 commands/sequence.c:1822 -#: commands/sequence.c:1886 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for sequence %s" -msgstr "permesso negato per la sequenza %s" +msgid "permission denied for column %s" +msgstr "permesso negato per la colonna %s" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for conversion %s" +msgstr "permesso negato per la conversione %s" -#: catalog/aclchk.c:3302 +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" msgstr "permesso negato per il database %s" -#: catalog/aclchk.c:3304 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "permesso negato per la funzione %s" +msgid "permission denied for domain %s" +msgstr "permesso negato per il dominio %s" -#: catalog/aclchk.c:3306 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "permesso negato per l'operatore %s" +msgid "permission denied for event trigger %s" +msgstr "permesso negato per il trigger di evento %s" -#: catalog/aclchk.c:3308 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "permesso negato per il tipo %s" +msgid "permission denied for extension %s" +msgstr "permesso negato per l'estensione %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "permesso negato per il wrapper di dati esterni %s" -#: catalog/aclchk.c:3310 +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "permesso negato per il server esterno %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "permesso negato per la tabella esterna %s" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "permesso negato per la funzione %s" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "permesso negato per l'indice %s" + +#: catalog/aclchk.c:3403 #, c-format msgid "permission denied for language %s" msgstr "permesso negato per il linguaggio %s" -#: catalog/aclchk.c:3312 +#: catalog/aclchk.c:3406 #, c-format msgid "permission denied for large object %s" msgstr "permesso negato per large object %s" -#: catalog/aclchk.c:3314 +#: catalog/aclchk.c:3409 #, c-format -msgid "permission denied for schema %s" -msgstr "permesso negato per lo schema %s" +msgid "permission denied for materialized view %s" +msgstr "permesso negato per la vista materializzata %s" -#: catalog/aclchk.c:3316 +#: catalog/aclchk.c:3412 #, c-format msgid "permission denied for operator class %s" msgstr "permesso negato per la classe di operatori %s" -#: catalog/aclchk.c:3318 +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "permesso negato per l'operatore %s" + +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" msgstr "permesso negato per la famiglia di operatori %s" -#: catalog/aclchk.c:3320 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "permesso negato per l'ordinamento %s" +msgid "permission denied for policy %s" +msgstr "permesso negato per la regola di sicurezza %s" -#: catalog/aclchk.c:3322 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "permesso negato per la conversione %s" +msgid "permission denied for procedure %s" +msgstr "permesso negato per la procedura %s" + +#: catalog/aclchk.c:3427 +#, c-format +msgid "permission denied for publication %s" +msgstr "permesso negato per la pubblicazione %s" + +#: catalog/aclchk.c:3430 +#, c-format +msgid "permission denied for routine %s" +msgstr "permesso negato per la routine %s" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "permesso negato per lo schema %s" -#: catalog/aclchk.c:3324 +#: catalog/aclchk.c:3436 commands/sequence.c:599 commands/sequence.c:833 +#: commands/sequence.c:875 commands/sequence.c:916 commands/sequence.c:1789 +#: commands/sequence.c:1853 +#, c-format +msgid "permission denied for sequence %s" +msgstr "permesso negato per la sequenza %s" + +#: catalog/aclchk.c:3439 #, c-format msgid "permission denied for statistics object %s" msgstr "permesso negato per la statistica %s" -#: catalog/aclchk.c:3326 +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "permesso negato per la sottoscrizione %s" + +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "permesso negato per la tabella %s" + +#: catalog/aclchk.c:3448 #, c-format msgid "permission denied for tablespace %s" msgstr "permesso negato per il tablespace %s" -#: catalog/aclchk.c:3328 +#: catalog/aclchk.c:3451 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "permesso negato per la configurazione di ricerca di testo %s" + +#: catalog/aclchk.c:3454 #, c-format msgid "permission denied for text search dictionary %s" msgstr "permesso negato per il dizionario di ricerca di testo %s" -#: catalog/aclchk.c:3330 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for text search configuration %s" -msgstr "permesso negato per la configurazione di ricerca di testo %s" +msgid "permission denied for type %s" +msgstr "permesso negato per il tipo %s" -#: catalog/aclchk.c:3332 +#: catalog/aclchk.c:3460 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "permesso negato per il wrapper di dati esterni %s" +msgid "permission denied for view %s" +msgstr "permesso negato per la vista %s" -#: catalog/aclchk.c:3334 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for foreign server %s" -msgstr "permesso negato per il server esterno %s" +msgid "must be owner of aggregate %s" +msgstr "bisogna essere proprietari dell'aggregato %s" -#: catalog/aclchk.c:3336 +#: catalog/aclchk.c:3498 #, c-format -msgid "permission denied for event trigger %s" -msgstr "permesso negato per il trigger di evento %s" +msgid "must be owner of collation %s" +msgstr "bisogna essere proprietari dell'ordinamento %s" -#: catalog/aclchk.c:3338 +#: catalog/aclchk.c:3501 #, c-format -msgid "permission denied for extension %s" -msgstr "permesso negato per l'estensione %s" +msgid "must be owner of conversion %s" +msgstr "bisogna essere proprietari della conversione %s" -#: catalog/aclchk.c:3340 +#: catalog/aclchk.c:3504 #, c-format -msgid "permission denied for publication %s" -msgstr "permesso negato per la pubblicazione %s" +msgid "must be owner of database %s" +msgstr "bisogna essere proprietari del database %s" -#: catalog/aclchk.c:3342 +#: catalog/aclchk.c:3507 #, c-format -msgid "permission denied for subscription %s" -msgstr "permesso negato per la sottoscrizione %s" +msgid "must be owner of domain %s" +msgstr "bisogna essere proprietari del dominio %s" -#: catalog/aclchk.c:3348 catalog/aclchk.c:3350 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of relation %s" -msgstr "bisogna essere proprietari della relazione %s" +msgid "must be owner of event trigger %s" +msgstr "bisogna essere proprietari del trigger di evento %s" -#: catalog/aclchk.c:3352 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of sequence %s" -msgstr "bisogna essere proprietari della sequenza %s" +msgid "must be owner of extension %s" +msgstr "bisogna essere proprietari dell'estensione %s" -#: catalog/aclchk.c:3354 +#: catalog/aclchk.c:3516 #, c-format -msgid "must be owner of database %s" -msgstr "bisogna essere proprietari del database %s" +msgid "must be owner of foreign-data wrapper %s" +msgstr "bisogna essere proprietari del wrapper di dati esterni %s" -#: catalog/aclchk.c:3356 +#: catalog/aclchk.c:3519 #, c-format -msgid "must be owner of function %s" -msgstr "bisogna essere proprietari della funzione %s" +msgid "must be owner of foreign server %s" +msgstr "bisogna essere proprietari del server esterno %s" -#: catalog/aclchk.c:3358 +#: catalog/aclchk.c:3522 #, c-format -msgid "must be owner of operator %s" -msgstr "bisogna essere proprietari dell'operatore %s" +msgid "must be owner of foreign table %s" +msgstr "bisogna essere proprietari della tabella esterna %s" -#: catalog/aclchk.c:3360 +#: catalog/aclchk.c:3525 #, c-format -msgid "must be owner of type %s" -msgstr "bisogna essere proprietari del tipo %s" +msgid "must be owner of function %s" +msgstr "bisogna essere proprietari della funzione %s" -#: catalog/aclchk.c:3362 +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "bisogna essere proprietari dell'indice %s" + +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" msgstr "bisogna essere proprietari del linguaggio %s" -#: catalog/aclchk.c:3364 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" msgstr "bisogna essere proprietari del large object %s" -#: catalog/aclchk.c:3366 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "bisogna essere proprietari dello schema %s" +msgid "must be owner of materialized view %s" +msgstr "bisogna essere proprietari della vista materializzata %s" -#: catalog/aclchk.c:3368 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" msgstr "bisogna essere proprietari della classe di operatore %s" -#: catalog/aclchk.c:3370 +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "bisogna essere proprietari dell'operatore %s" + +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" msgstr "bisogna essere proprietari della famiglia di operatori %s" -#: catalog/aclchk.c:3372 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "bisogna essere proprietari dell'ordinamento %s" +msgid "must be owner of procedure %s" +msgstr "bisogna essere proprietari della procedura %s" -#: catalog/aclchk.c:3374 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "bisogna essere proprietari della conversione %s" +msgid "must be owner of publication %s" +msgstr "bisogna essere proprietari della pubblicazione %s" -#: catalog/aclchk.c:3376 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of statistics object %s" -msgstr "bisogna essere proprietari della statistica %s" +msgid "must be owner of routine %s" +msgstr "bisogna essere proprietari della routine %s" -#: catalog/aclchk.c:3378 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of tablespace %s" -msgstr "bisogna essere proprietari del tablespace %s" +msgid "must be owner of sequence %s" +msgstr "bisogna essere proprietari della sequenza %s" -#: catalog/aclchk.c:3380 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "bisogna essere proprietari del dizionario di ricerca di testo %s" +msgid "must be owner of subscription %s" +msgstr "bisogna essere proprietari della sottoscrizione %s" -#: catalog/aclchk.c:3382 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "bisogna essere proprietari della configurazione di ricerca di testo %s" +msgid "must be owner of table %s" +msgstr "bisogna essere proprietari della tabella %s" -#: catalog/aclchk.c:3384 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "bisogna essere proprietari del wrapper di dati esterni %s" +msgid "must be owner of type %s" +msgstr "bisogna essere proprietari del tipo %s" -#: catalog/aclchk.c:3386 +#: catalog/aclchk.c:3570 #, c-format -msgid "must be owner of foreign server %s" -msgstr "bisogna essere proprietari del server esterno %s" +msgid "must be owner of view %s" +msgstr "bisogna essere proprietari della vista %s" -#: catalog/aclchk.c:3388 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of event trigger %s" -msgstr "bisogna essere proprietari del trigger di evento %s" +msgid "must be owner of schema %s" +msgstr "bisogna essere proprietari dello schema %s" -#: catalog/aclchk.c:3390 +#: catalog/aclchk.c:3576 #, c-format -msgid "must be owner of extension %s" -msgstr "bisogna essere proprietari dell'estensione %s" +msgid "must be owner of statistics object %s" +msgstr "bisogna essere proprietari della statistica %s" -#: catalog/aclchk.c:3392 +#: catalog/aclchk.c:3579 #, c-format -msgid "must be owner of publication %s" -msgstr "bisogna essere proprietari della pubblicazione %s" +msgid "must be owner of tablespace %s" +msgstr "bisogna essere proprietari del tablespace %s" -#: catalog/aclchk.c:3394 +#: catalog/aclchk.c:3582 #, c-format -msgid "must be owner of subscription %s" -msgstr "bisogna essere proprietari della sottoscrizione %s" +msgid "must be owner of text search configuration %s" +msgstr "bisogna essere proprietari della configurazione di ricerca di testo %s" + +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "bisogna essere proprietari del dizionario di ricerca di testo %s" -#: catalog/aclchk.c:3436 +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "bisogna essere proprietari della relazione %s" + +#: catalog/aclchk.c:3643 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "permesso negato per la colonna \"%s\" della relazione \"%s\"" -#: catalog/aclchk.c:3559 catalog/aclchk.c:3567 +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "l'attributo %d della relazione con OID %u non esiste" -#: catalog/aclchk.c:3640 catalog/aclchk.c:4559 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" msgstr "la relazione con OID %u non esiste" -#: catalog/aclchk.c:3739 catalog/aclchk.c:4977 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "il database con OID %u non esiste" -#: catalog/aclchk.c:3793 catalog/aclchk.c:4637 tcop/fastpath.c:223 -#: utils/fmgr/fmgr.c:2117 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "la funzione con OID %u non esiste" -#: catalog/aclchk.c:3847 catalog/aclchk.c:4663 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" msgstr "il linguaggio con OID %u non esiste" -#: catalog/aclchk.c:4011 catalog/aclchk.c:4735 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" msgstr "lo schema con OID %u non esiste" -#: catalog/aclchk.c:4065 catalog/aclchk.c:4762 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" msgstr "il tablespace con l'OID %u non esiste" -#: catalog/aclchk.c:4124 catalog/aclchk.c:4896 commands/foreigncmds.c:324 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "il wrapper di dati esterni con OID %u non esiste" -#: catalog/aclchk.c:4186 catalog/aclchk.c:4923 commands/foreigncmds.c:459 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" msgstr "il server esterno con OID %u non esiste" -#: catalog/aclchk.c:4246 catalog/aclchk.c:4585 utils/cache/typcache.c:238 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" msgstr "il tipo con OID %u non esiste" -#: catalog/aclchk.c:4611 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" msgstr "l'operatore con OID %u non esiste" -#: catalog/aclchk.c:4788 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" msgstr "la classe di operatori con OID %u non esiste" -#: catalog/aclchk.c:4815 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" msgstr "la famiglia di operatori con OID %u non esiste" -#: catalog/aclchk.c:4842 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "il dizionario di ricerca di testo con OID %u non esiste" -#: catalog/aclchk.c:4869 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "la configurazione di ricerca di testo con OID %u non esiste" -#: catalog/aclchk.c:4950 commands/event_trigger.c:588 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format msgid "event trigger with OID %u does not exist" msgstr "il trigger di evento con OID %u non esiste" -#: catalog/aclchk.c:5003 commands/collationcmds.c:319 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" msgstr "l'ordinamento con OID %u non esiste" -#: catalog/aclchk.c:5029 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" msgstr "la conversione con OID %u non esiste" -#: catalog/aclchk.c:5070 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" msgstr "l'estensione con OID %u non esiste" -#: catalog/aclchk.c:5097 commands/publicationcmds.c:733 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 #, c-format msgid "publication with OID %u does not exist" msgstr "la pubblicazione con OID %u non esiste" -#: catalog/aclchk.c:5123 commands/subscriptioncmds.c:1057 +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 #, c-format msgid "subscription with OID %u does not exist" msgstr "la sottoscrizione con OID %u non esiste" -#: catalog/aclchk.c:5149 +#: catalog/aclchk.c:5354 #, c-format msgid "statistics object with OID %u does not exist" msgstr "la statistica con OID %u non esiste" -#: catalog/dependency.c:613 +#: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" msgstr "non è possibile eliminare %s perché %s lo richiede" -#: catalog/dependency.c:616 +#: catalog/dependency.c:614 #, c-format msgid "You can drop %s instead." msgstr "È invece possibile eliminare %s." -#: catalog/dependency.c:779 catalog/pg_shdepend.c:574 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "non è possibile eliminare %s perché richiesto dal sistema database" -#: catalog/dependency.c:897 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" msgstr "l'eliminazione elimina anche %s in cascata automatica" -#: catalog/dependency.c:909 catalog/dependency.c:918 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" msgstr "%s dipende da %s" -#: catalog/dependency.c:930 catalog/dependency.c:939 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" msgstr "l'eliminazione elimina anche %s in cascata" -#: catalog/dependency.c:947 catalog/pg_shdepend.c:685 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -3707,415 +3693,421 @@ msgstr[1] "" "\n" "e %d altri oggetti (vedere il log del server per la lista)" -#: catalog/dependency.c:959 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "non è possibile eliminare %s perché altri oggetti dipendono da esso" -#: catalog/dependency.c:963 catalog/dependency.c:970 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Usa DROP ... CASCADE per eliminare anche gli oggetti dipendenti." -#: catalog/dependency.c:967 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "non è possibile eliminare gli oggetti desiderati perché altri oggetti dipendono da essi" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:976 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "l'eliminazione elimina in cascata %d altro oggetto" msgstr[1] "l'eliminazione elimina in cascata %d altri oggetti" -#: catalog/dependency.c:1635 +#: catalog/dependency.c:1644 #, c-format msgid "constant of the type %s cannot be used here" msgstr "un vincolo di tipo %s non può essere usato qui" -#: catalog/heap.c:283 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "permesso di creare \"%s.%s\" negato" -#: catalog/heap.c:285 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Le modifiche al catalogo di sistema non sono attualmente consentite." -#: catalog/heap.c:421 commands/tablecmds.c:1630 commands/tablecmds.c:2140 -#: commands/tablecmds.c:5203 +#: catalog/heap.c:425 commands/tablecmds.c:1861 commands/tablecmds.c:2385 +#: commands/tablecmds.c:5474 #, c-format msgid "tables can have at most %d columns" msgstr "le tabelle possono avere al massimo %d colonne" -#: catalog/heap.c:438 commands/tablecmds.c:5462 +#: catalog/heap.c:444 commands/tablecmds.c:5770 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "il nome della colonna \"%s\" è in conflitto con il nome di una colonna di sistema" -#: catalog/heap.c:454 +#: catalog/heap.c:460 #, c-format msgid "column name \"%s\" specified more than once" msgstr "nome di colonna \"%s\" specificato più di una volta" -#: catalog/heap.c:507 +#: catalog/heap.c:513 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "la colonna \"%s\" ha pseudo-tipo %s" -#: catalog/heap.c:537 +#: catalog/heap.c:543 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "il tipo composito %s non può essere fatto membro di sé stesso" -#: catalog/heap.c:579 commands/createas.c:201 commands/createas.c:498 +#: catalog/heap.c:585 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "nessun ordinamento è stato derivato per la colonna \"%s\" con tipo ordinabile %s" -#: catalog/heap.c:581 commands/createas.c:204 commands/createas.c:501 -#: commands/indexcmds.c:1136 commands/tablecmds.c:13319 commands/view.c:103 -#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1547 -#: utils/adt/formatting.c:1670 utils/adt/formatting.c:1794 utils/adt/like.c:184 -#: utils/adt/selfuncs.c:5526 utils/adt/varlena.c:1417 utils/adt/varlena.c:1862 +#: catalog/heap.c:587 commands/createas.c:204 commands/createas.c:501 +#: commands/indexcmds.c:1578 commands/tablecmds.c:13778 commands/view.c:105 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 +#: utils/adt/selfuncs.c:5807 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "Usa la clausola COLLATE per impostare esplicitamente l'ordinamento." -#: catalog/heap.c:1067 catalog/index.c:807 commands/tablecmds.c:2930 +#: catalog/heap.c:1076 catalog/index.c:876 commands/tablecmds.c:3148 #, c-format msgid "relation \"%s\" already exists" msgstr "la relazione \"%s\" esiste già" -#: catalog/heap.c:1083 catalog/pg_type.c:410 catalog/pg_type.c:717 -#: commands/typecmds.c:239 commands/typecmds.c:788 commands/typecmds.c:1139 -#: commands/typecmds.c:1350 commands/typecmds.c:2106 +#: catalog/heap.c:1092 catalog/pg_type.c:409 catalog/pg_type.c:731 +#: commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 +#: commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "il tipo \"%s\" esiste già" -#: catalog/heap.c:1084 +#: catalog/heap.c:1093 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." msgstr "Una relazione ha un tipo associato con lo stesso nome, quindi devi usare nomi che non siano in conflitto con alcun tipo esistente." -#: catalog/heap.c:1113 +#: catalog/heap.c:1122 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "valore OID heap pg_class non impostato in modalità di aggiornamento binaria" -#: catalog/heap.c:2078 +#: catalog/heap.c:2334 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "non si può aggiungere un vincolo NO INHERIT alla tabella partizionata \"%s\"" -#: catalog/heap.c:2336 +#: catalog/heap.c:2599 #, c-format msgid "check constraint \"%s\" already exists" msgstr "il vincolo di controllo \"%s\" esiste già" -#: catalog/heap.c:2504 catalog/pg_constraint.c:649 commands/tablecmds.c:6815 +#: catalog/heap.c:2769 catalog/index.c:890 catalog/pg_constraint.c:917 +#: commands/tablecmds.c:7122 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "il vincolo \"%s\" per la relazione \"%s\" esiste già" -#: catalog/heap.c:2511 +#: catalog/heap.c:2776 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "il vincolo \"%s\" è in conflitto con un vincolo non ereditato sulla relazione \"%s\"" -#: catalog/heap.c:2522 +#: catalog/heap.c:2787 #, c-format msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "il vincolo \"%s\" è in conflitto con un vincolo ereditato sulla relazione \"%s\"" -#: catalog/heap.c:2532 +#: catalog/heap.c:2797 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" msgstr "il vincolo \"%s\" è in conflitto con un vincolo non valido sulla relazione \"%s\"" -#: catalog/heap.c:2537 +#: catalog/heap.c:2802 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "unione del vincolo \"%s\" con una definizione ereditata" -#: catalog/heap.c:2653 +#: catalog/heap.c:2917 #, c-format msgid "cannot use column references in default expression" msgstr "non si possono usare riferimenti a colonne nell'espressione predefinita" -#: catalog/heap.c:2678 rewrite/rewriteHandler.c:1140 +#: catalog/heap.c:2942 rewrite/rewriteHandler.c:1177 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "la colonna \"%s\" è di tipo %s ma l'espressione predefinita è di tipo %s" -#: catalog/heap.c:2683 commands/prepare.c:384 parser/parse_node.c:430 -#: parser/parse_target.c:590 parser/parse_target.c:840 -#: parser/parse_target.c:850 rewrite/rewriteHandler.c:1145 +#: catalog/heap.c:2947 commands/prepare.c:384 parser/parse_node.c:430 +#: parser/parse_target.c:590 parser/parse_target.c:859 +#: parser/parse_target.c:869 rewrite/rewriteHandler.c:1182 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Devi riscrivere o convertire il tipo dell'espressione" -#: catalog/heap.c:2730 +#: catalog/heap.c:2994 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "solo la tabella \"%s\" può essere referenziata nel vincolo di controllo" -#: catalog/heap.c:2970 +#: catalog/heap.c:3237 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "la combinazione di COMMIT con una chiave esterna non è supportata" -#: catalog/heap.c:2971 +#: catalog/heap.c:3238 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "La tabella \"%s\" referenzia \"%s\", ma non hanno la stessa impostazione ON COMMIT." -#: catalog/heap.c:2976 +#: catalog/heap.c:3243 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "non è possibile troncare una tabella referenziata da un vincolo di chiave esterna" -#: catalog/heap.c:2977 +#: catalog/heap.c:3244 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "La tabella \"%s\" referenzia \"%s\"." -#: catalog/heap.c:2979 +#: catalog/heap.c:3246 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "Troncare la tabella \"%s\" nello stesso tempo o usare TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1662 parser/parse_utilcmd.c:1748 +#: catalog/index.c:233 parser/parse_utilcmd.c:1825 parser/parse_utilcmd.c:1912 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "non è possibile avere più di una chiave primaria per la tabella \"%s\"" -#: catalog/index.c:228 +#: catalog/index.c:251 #, c-format msgid "primary keys cannot be expressions" msgstr "le chiavi primarie non possono essere delle espressioni" -#: catalog/index.c:757 catalog/index.c:1175 +#: catalog/index.c:820 catalog/index.c:1291 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "non sono supportati indici definiti dall'utente sulle tabelle del catalogo di sistema" -#: catalog/index.c:767 +#: catalog/index.c:830 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "la creazione concorrente di indici sulle tabelle del catalogo di sistema non è supportata" -#: catalog/index.c:785 +#: catalog/index.c:848 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "indici condivisi non possono essere creati dopo initdb" -#: catalog/index.c:799 commands/createas.c:250 commands/sequence.c:152 -#: parser/parse_utilcmd.c:198 +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 +#: parser/parse_utilcmd.c:205 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "la relazione \"%s\" esiste già, saltata" -#: catalog/index.c:835 +#: catalog/index.c:918 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "valore OID indice pg_class non impostato in modalità di aggiornamento binaria" -#: catalog/index.c:1436 +#: catalog/index.c:1566 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY deve essere la prima azione della transazione" -#: catalog/index.c:2020 +#: catalog/index.c:2295 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "creazione seriale dell'indice \"%s\" sulla tabella \"%s\"" + +#: catalog/index.c:2300 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "creazione dell'indice \"%s\" sulla tabella \"%s\"" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "creazione dell'indice \"%s\" sulla tabella \"%s\" con richiesta di %d lavoratori paralleli" +msgstr[1] "creazione dell'indice \"%s\" sulla tabella \"%s\" con richiesta di %d lavoratori paralleli" -#: catalog/index.c:3332 +#: catalog/index.c:3689 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "non è possibile reindicizzare le tabelle temporanee di altre sessioni" -#: catalog/index.c:3463 +#: catalog/index.c:3820 #, c-format msgid "index \"%s\" was reindexed" msgstr "l'indice \"%s\" è stato reindicizzato" -#: catalog/index.c:3465 commands/vacuumlazy.c:1356 commands/vacuumlazy.c:1432 -#: commands/vacuumlazy.c:1621 commands/vacuumlazy.c:1831 +#: catalog/index.c:3891 #, c-format -msgid "%s." -msgstr "%s." +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX di una tabella partizionata non ancora implementato, \"%s\" saltato" -#: catalog/namespace.c:235 catalog/namespace.c:433 catalog/namespace.c:527 -#: commands/trigger.c:4800 +#: catalog/namespace.c:248 catalog/namespace.c:452 catalog/namespace.c:546 +#: commands/trigger.c:5400 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "i riferimenti tra database diversi non sono implementati: \"%s.%s.%s\"" -#: catalog/namespace.c:292 +#: catalog/namespace.c:305 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "Le tabelle temporanee non possono specificare un nome di schema" -#: catalog/namespace.c:371 +#: catalog/namespace.c:386 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "lock della relazione \"%s.%s\" fallito" -#: catalog/namespace.c:376 commands/lockcmds.c:145 +#: catalog/namespace.c:391 commands/lockcmds.c:152 commands/lockcmds.c:238 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "lock della relazione \"%s\" fallito" -#: catalog/namespace.c:400 parser/parse_relation.c:1158 +#: catalog/namespace.c:419 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "la relazione \"%s.%s\" non esiste" -#: catalog/namespace.c:405 parser/parse_relation.c:1177 -#: parser/parse_relation.c:1185 +#: catalog/namespace.c:424 parser/parse_relation.c:1171 +#: parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "la relazione \"%s\" non esiste" -#: catalog/namespace.c:473 catalog/namespace.c:2949 commands/extension.c:1465 -#: commands/extension.c:1471 +#: catalog/namespace.c:492 catalog/namespace.c:3011 commands/extension.c:1466 +#: commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "nessuna schema selezionato per crearci dentro" -#: catalog/namespace.c:625 catalog/namespace.c:638 +#: catalog/namespace.c:644 catalog/namespace.c:657 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "non si possono creare relazioni in schemi temporanei di altre sessioni" -#: catalog/namespace.c:629 +#: catalog/namespace.c:648 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "non si possono creare relazioni temporanee in schemi non temporanei" -#: catalog/namespace.c:644 +#: catalog/namespace.c:663 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "solo relazioni temporanee possono essere create in schemi temporanei" -#: catalog/namespace.c:2139 +#: catalog/namespace.c:2201 #, c-format msgid "statistics object \"%s\" does not exist" msgstr "la statistica \"%s\" non esiste" -#: catalog/namespace.c:2262 +#: catalog/namespace.c:2324 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "l'analizzatore di ricerca di testo \"%s\" non esiste" -#: catalog/namespace.c:2388 +#: catalog/namespace.c:2450 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "il dizionario di ricerca di testo \"%s\" non esiste" -#: catalog/namespace.c:2515 +#: catalog/namespace.c:2577 #, c-format msgid "text search template \"%s\" does not exist" msgstr "il modello di ricerca di testo \"%s\" non esiste" -#: catalog/namespace.c:2641 commands/tsearchcmds.c:1185 -#: utils/cache/ts_cache.c:612 +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1185 +#: utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "la configurazione di ricerca di testo \"%s\" non esiste" -#: catalog/namespace.c:2754 parser/parse_expr.c:791 parser/parse_target.c:1192 +#: catalog/namespace.c:2816 parser/parse_expr.c:793 parser/parse_target.c:1214 #, c-format msgid "cross-database references are not implemented: %s" msgstr "i riferimenti tra database diversi non sono implementati: %s" -#: catalog/namespace.c:2760 parser/parse_expr.c:798 parser/parse_target.c:1199 -#: gram.y:14320 gram.y:15741 +#: catalog/namespace.c:2822 parser/parse_expr.c:800 parser/parse_target.c:1221 +#: gram.y:14712 gram.y:16144 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "nome qualificato improprio (troppi nomi puntati): %s" -#: catalog/namespace.c:2891 +#: catalog/namespace.c:2953 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "non posso spostare oggetti dentro o fuori gli schemi temporanei" -#: catalog/namespace.c:2897 +#: catalog/namespace.c:2959 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "non posso spostare oggetti dentro o fuori lo schema TOAST" -#: catalog/namespace.c:2970 commands/schemacmds.c:256 commands/schemacmds.c:334 -#: commands/tablecmds.c:872 +#: catalog/namespace.c:3032 commands/schemacmds.c:256 commands/schemacmds.c:334 +#: commands/tablecmds.c:1014 #, c-format msgid "schema \"%s\" does not exist" msgstr "lo schema \"%s\" non esiste" -#: catalog/namespace.c:3001 +#: catalog/namespace.c:3063 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "nome di relazione improprio (troppi nomi puntati): %s" -#: catalog/namespace.c:3511 +#: catalog/namespace.c:3597 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "l'ordinamento \"%s\" per la codifica \"%s\" non esiste" -#: catalog/namespace.c:3566 +#: catalog/namespace.c:3652 #, c-format msgid "conversion \"%s\" does not exist" msgstr "la conversione \"%s\" non esiste" -#: catalog/namespace.c:3774 +#: catalog/namespace.c:3860 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "permesso di creare tabelle temporanee nel database \"%s\" negato" -#: catalog/namespace.c:3790 +#: catalog/namespace.c:3876 #, c-format msgid "cannot create temporary tables during recovery" msgstr "non è possibile creare tabelle temporanee durante il recupero" -#: catalog/namespace.c:3796 +#: catalog/namespace.c:3882 #, c-format -msgid "cannot create temporary tables in parallel mode" -msgstr "non è possibile creare tabelle temporanee in modalità parallela" +msgid "cannot create temporary tables during a parallel operation" +msgstr "non è possibile creare tabelle temporanee durante un'operazione parallela" -#: catalog/namespace.c:4045 commands/tablespace.c:1169 commands/variable.c:64 -#: utils/misc/guc.c:9979 utils/misc/guc.c:10057 +#: catalog/namespace.c:4165 commands/tablespace.c:1171 commands/variable.c:64 +#: utils/misc/guc.c:10258 utils/misc/guc.c:10336 #, c-format msgid "List syntax is invalid." msgstr "La sintassi della lista non è valida." #: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 -#: commands/lockcmds.c:93 commands/policy.c:94 commands/policy.c:391 -#: commands/policy.c:480 commands/tablecmds.c:223 commands/tablecmds.c:265 -#: commands/tablecmds.c:1488 commands/tablecmds.c:4713 -#: commands/tablecmds.c:8801 +#: commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1719 +#: commands/tablecmds.c:4969 commands/tablecmds.c:9200 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\" non è una tabella" -#: catalog/objectaddress.c:1245 commands/tablecmds.c:235 -#: commands/tablecmds.c:4743 commands/tablecmds.c:13058 commands/view.c:141 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 +#: commands/tablecmds.c:4999 commands/tablecmds.c:13497 commands/view.c:143 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\" non è una vista" -#: catalog/objectaddress.c:1252 commands/matview.c:174 commands/tablecmds.c:241 -#: commands/tablecmds.c:13063 +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 +#: commands/tablecmds.c:13502 #, c-format msgid "\"%s\" is not a materialized view" msgstr "\"%s\" non è una vista materializzata" -#: catalog/objectaddress.c:1259 commands/tablecmds.c:259 -#: commands/tablecmds.c:4746 commands/tablecmds.c:13068 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 +#: commands/tablecmds.c:5002 commands/tablecmds.c:13507 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\" non è una tabella esterna" @@ -4135,184 +4127,187 @@ msgstr "il nome della colonna deve essere qualificato" msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "il valore di default per la colonna \"%s\" della relazione \"%s\" non esiste" -#: catalog/objectaddress.c:1509 commands/functioncmds.c:128 -#: commands/tablecmds.c:251 commands/typecmds.c:3233 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:794 utils/adt/acl.c:4357 +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 +#: commands/tablecmds.c:253 commands/typecmds.c:3323 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 #, c-format msgid "type \"%s\" does not exist" msgstr "il tipo \"%s\" non esiste" -#: catalog/objectaddress.c:1626 +#: catalog/objectaddress.c:1628 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "l'operatore %d (%s, %s) di %s non esiste" -#: catalog/objectaddress.c:1657 +#: catalog/objectaddress.c:1659 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "la funzione %d (%s, %s) di %s non esiste" -#: catalog/objectaddress.c:1708 catalog/objectaddress.c:1734 +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "la mappatura per l'utente \"%s\" sul server \"%s\" non esiste" -#: catalog/objectaddress.c:1723 commands/foreigncmds.c:428 -#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1377 +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 +#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 #: foreign/foreign.c:688 #, c-format msgid "server \"%s\" does not exist" msgstr "il server \"%s\" non esiste" -#: catalog/objectaddress.c:1790 +#: catalog/objectaddress.c:1792 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "la tabella \"%s\" nella pubblicazione \"%s\" non esiste" -#: catalog/objectaddress.c:1852 +#: catalog/objectaddress.c:1854 #, c-format -msgid "unrecognized default ACL object type %c" -msgstr "tipo di oggetto ACL di default %c non riconosciuto" +msgid "unrecognized default ACL object type \"%c\"" +msgstr "tipo di oggetto ACL di default \"%c\" non riconosciuto" -#: catalog/objectaddress.c:1853 +#: catalog/objectaddress.c:1855 #, c-format -msgid "Valid object types are \"r\", \"S\", \"f\", \"T\" and \"s\"." -msgstr "I tipi di oggetti validi sono \"r\", \"S\", \"f\", \"T\" e \"s\"." +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Gli oggetti validi sono \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." -#: catalog/objectaddress.c:1899 +#: catalog/objectaddress.c:1906 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "l'ACL di default per l'utente \"%s\" nello schema \"%s\" su %s non esiste" -#: catalog/objectaddress.c:1904 +#: catalog/objectaddress.c:1911 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "l'ACL di default per l'utente \"%s\" su %s non esiste" -#: catalog/objectaddress.c:1931 catalog/objectaddress.c:1989 -#: catalog/objectaddress.c:2044 +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 +#: catalog/objectaddress.c:2053 #, c-format msgid "name or argument lists may not contain nulls" msgstr "il nome o la lista di argomenti non può contenere valori nulli" -#: catalog/objectaddress.c:1965 +#: catalog/objectaddress.c:1972 #, c-format msgid "unsupported object type \"%s\"" msgstr "tipo di oggetto \"%s\" non supportato" -#: catalog/objectaddress.c:1985 catalog/objectaddress.c:2003 -#: catalog/objectaddress.c:2141 +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 +#: catalog/objectaddress.c:2151 #, c-format msgid "name list length must be exactly %d" msgstr "la lunghezza della lista dei nomi dev'essere %d" -#: catalog/objectaddress.c:2007 +#: catalog/objectaddress.c:2014 #, c-format msgid "large object OID may not be null" msgstr "l'OID di large object non può essere nullo" -#: catalog/objectaddress.c:2016 catalog/objectaddress.c:2077 -#: catalog/objectaddress.c:2084 +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:2093 #, c-format msgid "name list length must be at least %d" msgstr "la lunghezza della lista dei nomi deve essere almeno %d" -#: catalog/objectaddress.c:2070 catalog/objectaddress.c:2090 +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 #, c-format msgid "argument list length must be exactly %d" msgstr "la lunghezza della lista degli argomenti deve essere %d" -#: catalog/objectaddress.c:2316 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "occorre essere proprietari del large object %u" -#: catalog/objectaddress.c:2331 commands/functioncmds.c:1420 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 #, c-format msgid "must be owner of type %s or type %s" msgstr "occorre essere proprietari del tipo %s o del tipo %s" -#: catalog/objectaddress.c:2381 catalog/objectaddress.c:2398 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" msgstr "occorre essere superutenti" -#: catalog/objectaddress.c:2388 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "occorre avere privilegio CREATEROLE" -#: catalog/objectaddress.c:2467 +#: catalog/objectaddress.c:2481 #, c-format msgid "unrecognized object type \"%s\"" msgstr "tipo di oggetto \"%s\" non riconosciuto" -#: catalog/objectaddress.c:2662 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " colonna %s" +msgid "column %s of %s" +msgstr "colonna %s di %s" -#: catalog/objectaddress.c:2668 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" msgstr "funzione %s" -#: catalog/objectaddress.c:2673 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" msgstr "tipo %s" -#: catalog/objectaddress.c:2703 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" msgstr "conversione da %s a %s" -#: catalog/objectaddress.c:2723 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" msgstr "ordinamento %s" -#: catalog/objectaddress.c:2747 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" msgstr "vincolo %s su %s" -#: catalog/objectaddress.c:2753 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" msgstr "vincolo %s" -#: catalog/objectaddress.c:2770 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" msgstr "conversione %s" -#: catalog/objectaddress.c:2807 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" -msgstr "predefinito per %s" +msgid "default value for %s" +msgstr "valore di default per %s" -#: catalog/objectaddress.c:2816 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "linguaggio %s" -#: catalog/objectaddress.c:2821 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" msgstr "large object %u" -#: catalog/objectaddress.c:2826 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "operatore %s" -#: catalog/objectaddress.c:2858 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "classe di operatori %s per il metodo di accesso %s" -#: catalog/objectaddress.c:2881 +#: catalog/objectaddress.c:2939 #, c-format msgid "access method %s" msgstr "metodo di accesso %s" @@ -4321,7 +4316,7 @@ msgstr "metodo di accesso %s" #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2923 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "operatore %d (%s, %s) della %s: %s" @@ -4330,406 +4325,410 @@ msgstr "operatore %d (%s, %s) della %s: %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2973 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "funzione %d (%s, %s) della %s: %s" -#: catalog/objectaddress.c:3013 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "rule %s on " -msgstr "regola %s on " +msgid "rule %s on %s" +msgstr "regola %s su %s" -#: catalog/objectaddress.c:3048 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "trigger %s su " +msgid "trigger %s on %s" +msgstr "trigger %s su %s" -#: catalog/objectaddress.c:3065 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" msgstr "schema %s" -#: catalog/objectaddress.c:3082 +#: catalog/objectaddress.c:3152 #, c-format msgid "statistics object %s" msgstr "statistiche %s" -#: catalog/objectaddress.c:3098 +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" msgstr "analizzatore di ricerca di testo %s" -#: catalog/objectaddress.c:3113 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" msgstr "dizionario di ricerca di testo %s" -#: catalog/objectaddress.c:3128 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" msgstr "modello di ricerca di testo %s" -#: catalog/objectaddress.c:3143 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" msgstr "configurazione di ricerca di testo %s" -#: catalog/objectaddress.c:3151 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" msgstr "regola %s" -#: catalog/objectaddress.c:3164 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" msgstr "database %s" -#: catalog/objectaddress.c:3176 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" msgstr "tablespace %s" -#: catalog/objectaddress.c:3185 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" msgstr "wrapper di dati esterni %s" -#: catalog/objectaddress.c:3194 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" msgstr "server %s" -#: catalog/objectaddress.c:3222 +#: catalog/objectaddress.c:3337 #, c-format msgid "user mapping for %s on server %s" msgstr "mappatura utenti per %s sul server %s" -#: catalog/objectaddress.c:3257 +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "privilegi predefiniti sulle nuove relazioni appartenenti al ruolo %s nello schema %s" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "privilegi predefiniti sulle nuove relazioni appartenenti al ruolo %s" -#: catalog/objectaddress.c:3262 +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "privilegi predefiniti sulle nuove sequenze appartenenti al ruolo %s nello schema %s" + +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "privilegi predefiniti sulle nuove sequenze appartenenti al ruolo %s" -#: catalog/objectaddress.c:3267 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "privilegi predefiniti sulle nuove funzioni appartenenti al ruolo %s nello schema %s" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "privilegi predefiniti sulle nuove funzioni appartenenti al ruolo %s" -#: catalog/objectaddress.c:3272 +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "privilegi predefiniti sui nuovi tipi appartenenti al ruolo %s nello schema %s" + +#: catalog/objectaddress.c:3416 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "privilegi predefiniti sui nuovi tipi appartenenti al ruolo %s" -#: catalog/objectaddress.c:3277 +#: catalog/objectaddress.c:3422 #, c-format msgid "default privileges on new schemas belonging to role %s" msgstr "privilegi predefiniti sui nuovi schemi appartenenti al ruolo %s" -#: catalog/objectaddress.c:3283 +#: catalog/objectaddress.c:3429 #, c-format -msgid "default privileges belonging to role %s" -msgstr "privilegi predefiniti appartenenti al ruolo %s" +msgid "default privileges belonging to role %s in schema %s" +msgstr "privilegi predefiniti appartenenti al ruolo %s nello schema %s" -#: catalog/objectaddress.c:3291 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr " nello schema %s" +msgid "default privileges belonging to role %s" +msgstr "privilegi predefiniti appartenenti al ruolo %s" -#: catalog/objectaddress.c:3308 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" msgstr "estensione %s" -#: catalog/objectaddress.c:3321 +#: catalog/objectaddress.c:3464 #, c-format msgid "event trigger %s" msgstr "trigger di evento %s" -#: catalog/objectaddress.c:3353 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 #, c-format -msgid "policy %s on " -msgstr "regola di sicurezza %s su " +msgid "policy %s on %s" +msgstr "regola di sicurezza %s su %s" -#: catalog/objectaddress.c:3364 +#: catalog/objectaddress.c:3510 #, c-format msgid "publication %s" msgstr "pubblicazione %s" -#: catalog/objectaddress.c:3384 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 #, c-format -msgid "publication table %s in publication %s" -msgstr "tabella %s nella pubblicazione %s" +msgid "publication of %s in publication %s" +msgstr "pubblicazione di %s nella pubblicazione %s" -#: catalog/objectaddress.c:3392 +#: catalog/objectaddress.c:3544 #, c-format msgid "subscription %s" msgstr "sottoscrizione %s" -#: catalog/objectaddress.c:3410 +#: catalog/objectaddress.c:3562 #, c-format msgid "transform for %s language %s" msgstr "trasformazione per %s linguaggio %s" -#: catalog/objectaddress.c:3471 +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" msgstr "tabella %s" -#: catalog/objectaddress.c:3475 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" msgstr "indice %s" -#: catalog/objectaddress.c:3479 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "sequenza %s" -#: catalog/objectaddress.c:3483 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "tabella toast %s" -#: catalog/objectaddress.c:3487 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "vista %s" -#: catalog/objectaddress.c:3491 +#: catalog/objectaddress.c:3646 #, c-format msgid "materialized view %s" msgstr "vista materializzata %s" -#: catalog/objectaddress.c:3495 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "tipo composito %s" -#: catalog/objectaddress.c:3499 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" msgstr "tabella esterna %s" -#: catalog/objectaddress.c:3504 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "relazione %s" -#: catalog/objectaddress.c:3541 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" msgstr "famiglia di operatori %s per il metodo d'accesso %s" -#: catalog/objectaddress.c:4910 -#, c-format -msgid "%s in publication %s" -msgstr "%s nella pubblicazione %s" - -#: catalog/partition.c:741 -#, c-format -msgid "cannot create range partition with empty range" -msgstr "non è possibile creare una partizione su un intervallo vuoto" - -#: catalog/partition.c:835 -#, c-format -msgid "partition \"%s\" would overlap partition \"%s\"" -msgstr "la partizione \"%s\" si sovrapporrebbe a \"%s\"" - -#: catalog/partition.c:943 catalog/partition.c:1121 commands/analyze.c:1446 -#: commands/tablecmds.c:8863 executor/execExprInterp.c:2837 -#: executor/execMain.c:1928 executor/execMain.c:1975 executor/execMain.c:2017 -#: executor/execMain.c:3279 +#: catalog/partition.c:180 catalog/pg_constraint.c:420 commands/analyze.c:1499 +#: commands/indexcmds.c:918 commands/tablecmds.c:941 commands/tablecmds.c:9262 +#: commands/tablecmds.c:14386 commands/tablecmds.c:14858 +#: executor/execExprInterp.c:3275 executor/execMain.c:1940 +#: executor/execMain.c:2019 executor/execMain.c:2067 executor/execMain.c:2173 +#: executor/execPartition.c:462 executor/execPartition.c:522 +#: executor/execPartition.c:638 executor/execPartition.c:741 +#: executor/execPartition.c:812 executor/execPartition.c:1010 +#: executor/nodeModifyTable.c:1859 msgid "could not convert row type" msgstr "conversione del tipo riga fallita" -#: catalog/pg_aggregate.c:125 +#: catalog/pg_aggregate.c:126 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "gli aggregati non possono avere più di %d argomento" msgstr[1] "gli aggregati non possono avere più di %d argomenti" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" msgstr "non è possibile determinare il tipo di dati della transizione" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." msgstr "Un aggregato che usa un tipo di transizione polimorfico deve avere almeno un argomento polimorfico." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:173 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "un aggregato variadico su insieme ordinato deve usare il tipo VARIADIC ANY" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:199 #, c-format msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "gli argomenti diretti di un aggregato su insieme ipotetico devono combaciare con gli argomenti aggregati" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "il tipo restituito dalla funzione di transizione %s non è %s" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "non si può omettere initval quando la funzione di transizione è strict e il tipo di transizione non è compatibile col tipo in input" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:335 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "il tipo restituito dalla funzione di transizione inversa %s non è %s" -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2294 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 #, c-format msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "le ristrettezze della trasformazione diretta ed inversa di un aggregato devono combaciare" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "la funzione finale con argomenti aggiuntivi non deve essere dichiarata STRICT" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:427 #, c-format msgid "return type of combine function %s is not %s" msgstr "il tipo restituito dalla funzione di combinazione %s non è %s" -#: catalog/pg_aggregate.c:436 +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2943 #, c-format -msgid "combine function with \"%s\" transition type must not be declared STRICT" -msgstr "una funzione di combinazione con \"%s\" tipi di transizione non può essere dichiarata STRICT" +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "la funzione di combinazione con il tipo di transizione %s non deve essere dichiarata STRICT" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:458 #, c-format msgid "return type of serialization function %s is not %s" msgstr "il tipo restituito dalla funzione di serializzazione %s non è %s" -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:479 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "il tipo restituito dalla funzione di deserializzazione %s non è %s" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:243 catalog/pg_proc.c:250 +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "non è possibile determinare il tipo di dati del risultato" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:496 #, c-format msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." msgstr "Una funzione di aggregazione che restituisce un tipo polimorfico deve avere almeno un argomento polimorfico." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:256 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "uso dello pseudo-tipo \"internal\" non sicuro" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:257 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgstr "Una funzione che restituisce \"internal\" deve avere almeno un argomento \"internal\"." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:562 #, c-format msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "l'implementazione dell'aggregazione mobile restituisce il tipo %s ma l'implementazione semplice resituisce il tipo %s" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "l'operatore di ordinamento può essere specificato sono per aggregati con un solo argomento" -#: catalog/pg_aggregate.c:810 commands/typecmds.c:1698 commands/typecmds.c:1749 -#: commands/typecmds.c:1780 commands/typecmds.c:1803 commands/typecmds.c:1824 -#: commands/typecmds.c:1851 commands/typecmds.c:1878 commands/typecmds.c:1955 -#: commands/typecmds.c:1997 parser/parse_func.c:365 parser/parse_func.c:394 -#: parser/parse_func.c:419 parser/parse_func.c:433 parser/parse_func.c:508 -#: parser/parse_func.c:519 parser/parse_func.c:1958 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 +#: commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 +#: commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 +#: commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 +#: parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 +#: parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "la funzione %s non esiste" -#: catalog/pg_aggregate.c:816 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "la funzione %s restituisce un insieme" -#: catalog/pg_aggregate.c:831 +#: catalog/pg_aggregate.c:840 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "la funzione %s deve accettare VARIADIC ANY per essere usata in questo aggregato" -#: catalog/pg_aggregate.c:855 +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "la funzione %s richiede una coercizione di tipo a run-time" -#: catalog/pg_collation.c:85 catalog/pg_collation.c:127 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format msgid "collation \"%s\" already exists, skipping" msgstr "l'ordinamento \"%s\" esiste già, saltato" -#: catalog/pg_collation.c:87 +#: catalog/pg_collation.c:94 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" msgstr "l'ordinamento \"%s\" per l'encoding \"%s\" esiste già, saltato" -#: catalog/pg_collation.c:95 catalog/pg_collation.c:134 +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "l'ordinamento \"%s\" esiste già" -#: catalog/pg_collation.c:97 +#: catalog/pg_collation.c:104 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "l'ordinamento \"%s\" per la codifica \"%s\" esiste già" -#: catalog/pg_constraint.c:658 +#: catalog/pg_constraint.c:925 #, c-format msgid "constraint \"%s\" for domain %s already exists" msgstr "il vincolo \"%s\" per il dominio %s esiste già" -#: catalog/pg_constraint.c:788 -#, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "la tabella \"%s\" ha più di un vincolo di nome \"%s\"" - -#: catalog/pg_constraint.c:800 +#: catalog/pg_constraint.c:1088 catalog/pg_constraint.c:1181 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "il vincolo \"%s\" per la tabella \"%s\" non esiste" -#: catalog/pg_constraint.c:846 +#: catalog/pg_constraint.c:1270 #, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "il dominio \"%s\" ha più di un vincolo di nome \"%s\"" +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "il vincolo \"%s\" per il dominio %s non esiste" -#: catalog/pg_constraint.c:858 -#, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" -msgstr "il vincolo \"%s\" per la il dominio \"%s\" non esiste" - -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "la conversione \"%s\" esiste già" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "la conversione predefinita da %s a %s esiste già" -#: catalog/pg_depend.c:163 commands/extension.c:3216 +#: catalog/pg_depend.c:163 commands/extension.c:3218 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s fa già parte dell'estensione \"%s\"" @@ -4779,165 +4778,171 @@ msgstr "ALTER TYPE ADD BEFORE/AFTER non è compatibile con gli aggiornamenti bin msgid "schema \"%s\" already exists" msgstr "lo schema \"%s\" esiste già" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:358 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "\"%s\" non è un nome di operatore valido" -#: catalog/pg_operator.c:367 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" msgstr "solo gli operatori binari possono avere commutatori" -#: catalog/pg_operator.c:371 commands/operatorcmds.c:482 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "solo gli operatori binari possono avere selettività di unione" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "solo gli operatori binari possono fare dei merge-join" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "solo gli operatori binari possono supportare l'hash" -#: catalog/pg_operator.c:390 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "solo gli operatori booleani possono avere un negatore" -#: catalog/pg_operator.c:394 commands/operatorcmds.c:490 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "solo gli operatori booleani possono avere restrizione di selettività" -#: catalog/pg_operator.c:398 commands/operatorcmds.c:494 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "solo gli operatori booleani possono avere selettività di unione" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "solo gli operatori booleani possono fare dei merge-join" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "solo gli operatori booleani possono supportare l'hash" -#: catalog/pg_operator.c:418 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "l'operatore %s esiste già " -#: catalog/pg_operator.c:612 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "l'operatore non può negare o ordinare se stesso" -#: catalog/pg_proc.c:131 parser/parse_func.c:1982 parser/parse_func.c:2022 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "le funzioni non possono avere più di %d argomento" msgstr[1] "le funzioni non possono avere più di %d argomenti" -#: catalog/pg_proc.c:244 +#: catalog/pg_proc.c:241 #, c-format msgid "A function returning a polymorphic type must have at least one polymorphic argument." msgstr "Una funzione che restituisce un tipo polimorfico deve avere almeno un argomento polimorfico." -#: catalog/pg_proc.c:251 +#: catalog/pg_proc.c:248 #, c-format msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." msgstr "Una funzione che restituisce \"anyrange\" deve avere almeno un argomento \"anyrange\"." -#: catalog/pg_proc.c:269 -#, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "\"%s\" è già un attributo del tipo %s" - -#: catalog/pg_proc.c:400 +#: catalog/pg_proc.c:383 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "la funzione \"%s\" esiste già, con gli stessi tipi di argomenti" -#: catalog/pg_proc.c:414 catalog/pg_proc.c:437 +#: catalog/pg_proc.c:393 +#, c-format +msgid "cannot change routine kind" +msgstr "non è possibile cambiare il tipo di routine" + +#: catalog/pg_proc.c:395 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" è una funzione di aggregazione." + +#: catalog/pg_proc.c:397 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" è una funzione." + +#: catalog/pg_proc.c:399 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" è una procedura." + +#: catalog/pg_proc.c:401 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\" è una funzione finestra." + +#: catalog/pg_proc.c:419 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "non è possibile cambiare se una funzione ha parametri di output o no" + +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 #, c-format msgid "cannot change return type of existing function" msgstr "non è possibile cambiare il tipo restituito da una funzione esistente" -#: catalog/pg_proc.c:415 catalog/pg_proc.c:439 catalog/pg_proc.c:482 -#: catalog/pg_proc.c:506 catalog/pg_proc.c:532 +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 +#: catalog/pg_proc.c:520 catalog/pg_proc.c:548 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "Usa prima DROP FUNCTION %s." +msgid "Use %s %s first." +msgstr "Usa %s %s prima." -#: catalog/pg_proc.c:438 +#: catalog/pg_proc.c:447 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "Il tipo della riga definito dai parametri di OUT è diverso." -#: catalog/pg_proc.c:480 +#: catalog/pg_proc.c:491 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "non è possibile cambiare nome del parametro di ingresso \"%s\"" -#: catalog/pg_proc.c:505 +#: catalog/pg_proc.c:518 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "non è possibile rimuovere i valori predefiniti dei parametri da funzioni esistenti" -#: catalog/pg_proc.c:531 +#: catalog/pg_proc.c:546 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "non è possibile cambiare tipo di dati dei valori predefiniti di parametri esistenti" -#: catalog/pg_proc.c:544 -#, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "la funzione \"%s\" è una funzione di aggregazione" - -#: catalog/pg_proc.c:549 -#, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "la funzione \"%s\" non è una funzione di aggregazione" - -#: catalog/pg_proc.c:557 -#, c-format -msgid "function \"%s\" is a window function" -msgstr "la funzione \"%s\" è una funzione finestra" - -#: catalog/pg_proc.c:562 -#, c-format -msgid "function \"%s\" is not a window function" -msgstr "la funzione \"%s\" non è una funzione finestra" - -#: catalog/pg_proc.c:768 +#: catalog/pg_proc.c:757 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "non c'è nessuna funzione predefinita chiamata \"%s\"" -#: catalog/pg_proc.c:866 +#: catalog/pg_proc.c:855 #, c-format msgid "SQL functions cannot return type %s" msgstr "Le funzioni SQL non possono restituire il tipo %s" -#: catalog/pg_proc.c:881 +#: catalog/pg_proc.c:870 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "le funzioni SQL non possono avere argomenti di tipo %s" -#: catalog/pg_proc.c:968 executor/functions.c:1428 +#: catalog/pg_proc.c:958 executor/functions.c:1434 #, c-format msgid "SQL function \"%s\"" msgstr "funzione SQL \"%s\"" -#: catalog/pg_publication.c:57 commands/trigger.c:194 commands/trigger.c:360 +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 #, c-format msgid "\"%s\" is a partitioned table" msgstr "\"%s\" è una tabella partizionata" @@ -4977,13 +4982,13 @@ msgstr "la tabella \"%s\" non può essere replicata" msgid "Temporary and unlogged relations cannot be replicated." msgstr "Le relazioni temporanee e non loggate non possono essere replicate." -#: catalog/pg_publication.c:142 +#: catalog/pg_publication.c:175 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "la relazione \"%s\" è già membra della pubblicazione \"%s\"" -#: catalog/pg_publication.c:369 catalog/pg_publication.c:390 -#: commands/publicationcmds.c:401 commands/publicationcmds.c:702 +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 +#: commands/publicationcmds.c:415 commands/publicationcmds.c:716 #, c-format msgid "publication \"%s\" does not exist" msgstr "la pubblicazione \"%s\" non esiste" @@ -5051,50 +5056,50 @@ msgstr "non è possibile eliminare oggetti di proprietà di %s perché richiesti msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "non è possibile modificare il proprietario degli oggetti di proprietà di %s perché richiesti dal database" -#: catalog/pg_subscription.c:174 commands/subscriptioncmds.c:622 -#: commands/subscriptioncmds.c:826 commands/subscriptioncmds.c:1026 +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 +#: commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 #, c-format msgid "subscription \"%s\" does not exist" msgstr "la sottoscrizione \"%s\" non esiste" -#: catalog/pg_type.c:136 catalog/pg_type.c:452 +#: catalog/pg_type.c:135 catalog/pg_type.c:451 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "valore di OID di pg_type non impostato in modalità di aggiornamento binaria" -#: catalog/pg_type.c:251 +#: catalog/pg_type.c:250 #, c-format msgid "invalid type internal size %d" msgstr "dimensione interna del tipo %d non valida" -#: catalog/pg_type.c:267 catalog/pg_type.c:275 catalog/pg_type.c:283 -#: catalog/pg_type.c:292 +#: catalog/pg_type.c:266 catalog/pg_type.c:274 catalog/pg_type.c:282 +#: catalog/pg_type.c:291 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "l'allineamento \"%c\" non è valido per tipi passati per valore di grandezza %d" -#: catalog/pg_type.c:299 +#: catalog/pg_type.c:298 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "la dimensione interna %d non è valida per tipi passati per valore" -#: catalog/pg_type.c:308 catalog/pg_type.c:314 +#: catalog/pg_type.c:307 catalog/pg_type.c:313 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "l'allineamento \"%c\" non è valido per il tipi a lunghezza variabile" -#: catalog/pg_type.c:322 +#: catalog/pg_type.c:321 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "i tipi a dimensione fissa devono avere immagazzinamento PLAIN" -#: catalog/pg_type.c:781 +#: catalog/pg_type.c:800 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "creazione del nome per il tipo array del tipo \"%s\" fallita" -#: catalog/toasting.c:105 commands/indexcmds.c:395 commands/tablecmds.c:4725 -#: commands/tablecmds.c:12946 +#: catalog/toasting.c:105 commands/indexcmds.c:443 commands/tablecmds.c:4981 +#: commands/tablecmds.c:13385 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "\"%s\" non è una tabella né una vista materializzata" @@ -5104,92 +5109,97 @@ msgstr "\"%s\" non è una tabella né una vista materializzata" msgid "shared tables cannot be toasted after initdb" msgstr "le tabelle condivise non possono essere trasformate in toast dopo initdb" -#: commands/aggregatecmds.c:157 +#: commands/aggregatecmds.c:166 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "solo gli aggregati su insiemi ordinati possono essere ipotetici" -#: commands/aggregatecmds.c:182 +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "attributo dell'aggregato \"%s\" non riconosciuto" -#: commands/aggregatecmds.c:192 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" msgstr "l'attributo stype dell'aggregato deve essere specificato" -#: commands/aggregatecmds.c:196 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" msgstr "l'attributo sfunc dell'aggregato deve essere specificato" -#: commands/aggregatecmds.c:208 +#: commands/aggregatecmds.c:217 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "l'attributo msfunc dell'aggregato deve essere specificato quando mstype lo è" -#: commands/aggregatecmds.c:212 +#: commands/aggregatecmds.c:221 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "l'attributo minvfunc dell'aggregato deve essere specificato quando mstype lo è" -#: commands/aggregatecmds.c:219 +#: commands/aggregatecmds.c:228 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "l'attributo msfunc dell'aggregato non deve essere specificato se mstype non lo è" -#: commands/aggregatecmds.c:223 +#: commands/aggregatecmds.c:232 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "l'attributo minvfunc dell'aggregato non deve essere specificato se mstype non lo è" -#: commands/aggregatecmds.c:227 +#: commands/aggregatecmds.c:236 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "l'attributo mfinalfunc dell'aggregato non deve essere specificato se mstype non lo è" -#: commands/aggregatecmds.c:231 +#: commands/aggregatecmds.c:240 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "l'attributo msspace dell'aggregato non deve essere specificato se mstype non lo è" -#: commands/aggregatecmds.c:235 +#: commands/aggregatecmds.c:244 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "l'attributo minitcond dell'aggregato non deve essere specificato se mstype non lo è" -#: commands/aggregatecmds.c:255 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" msgstr "il tipo di input dell'aggregato deve essere specificato" -#: commands/aggregatecmds.c:285 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "il basetype è ridondante se il tipo di input è specificato per un aggregato" -#: commands/aggregatecmds.c:326 commands/aggregatecmds.c:367 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "il tipo di dato della transizione dell'aggregato non può essere %s" -#: commands/aggregatecmds.c:338 +#: commands/aggregatecmds.c:356 #, c-format msgid "serialization functions may be specified only when the aggregate transition data type is %s" msgstr "le funzioni di serializzazione possono essere specificate solo quando il tipo di dato di transizione dell'aggregato è %s" -#: commands/aggregatecmds.c:348 +#: commands/aggregatecmds.c:366 #, c-format msgid "must specify both or neither of serialization and deserialization functions" msgstr "occorre specificare o entrambe le funzioni di serializzazione e deserializzazione o nessuna" -#: commands/aggregatecmds.c:413 commands/functioncmds.c:564 +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "il parametro \"parallel\" deve essere SAFE, RESTRICTED o UNSAFE" -#: commands/alter.c:84 commands/event_trigger.c:234 +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "il parametro \"%s\" deve essere READ_ONLY, SHAREABLE o READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format msgid "event trigger \"%s\" already exists" msgstr "il trigger di evento \"%s\" esiste già" @@ -5204,17 +5214,17 @@ msgstr "il wrapper di dati esterni \"%s\" esiste già" msgid "server \"%s\" already exists" msgstr "il server \"%s\" esiste già" -#: commands/alter.c:93 commands/proclang.c:367 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "il linguaggio \"%s\" esiste già" -#: commands/alter.c:96 commands/publicationcmds.c:170 +#: commands/alter.c:96 commands/publicationcmds.c:176 #, c-format msgid "publication \"%s\" already exists" msgstr "la pubblicazione \"%s\" esiste già" -#: commands/alter.c:99 commands/subscriptioncmds.c:343 +#: commands/alter.c:99 commands/subscriptioncmds.c:358 #, c-format msgid "subscription \"%s\" already exists" msgstr "la sottoscrizione \"%s\" esiste già" @@ -5254,7 +5264,7 @@ msgstr "la configurazione di ricerca di testo \"%s\" esiste già nello schema \" msgid "must be superuser to rename %s" msgstr "occorre essere un superutente per rinominare %s" -#: commands/alter.c:709 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" msgstr "occorre essere un superutente per impostare lo schema di %s" @@ -5279,8 +5289,8 @@ msgstr "il metodo di accesso \"%s\" esiste già" msgid "must be superuser to drop access methods" msgstr "occorre essere un superutente per eliminare un metodo di accesso" -#: commands/amcmds.c:174 commands/indexcmds.c:163 commands/indexcmds.c:502 -#: commands/opclasscmds.c:363 commands/opclasscmds.c:777 +#: commands/amcmds.c:174 commands/indexcmds.c:173 commands/indexcmds.c:583 +#: commands/opclasscmds.c:364 commands/opclasscmds.c:778 #, c-format msgid "access method \"%s\" does not exist" msgstr "Il metodo di accesso \"%s\" non esiste" @@ -5290,179 +5300,199 @@ msgstr "Il metodo di accesso \"%s\" non esiste" msgid "handler function is not specified" msgstr "funzione handler non specificata" -#: commands/amcmds.c:262 commands/event_trigger.c:243 -#: commands/foreigncmds.c:487 commands/proclang.c:117 commands/proclang.c:289 -#: commands/trigger.c:557 parser/parse_clause.c:985 +#: commands/amcmds.c:262 commands/event_trigger.c:245 +#: commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 +#: commands/trigger.c:696 parser/parse_clause.c:990 #, c-format msgid "function %s must return type %s" msgstr "la funzione %s deve restituire il tipo %s" -#: commands/analyze.c:151 +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" msgstr "analisi di \"%s\" saltata --- lock non disponibile" -#: commands/analyze.c:168 +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "analisi di \"%s\" saltata --- la relazione non esiste più" + +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" msgstr "\"%s\" saltato --- solo un superutente può analizzarlo" -#: commands/analyze.c:172 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" msgstr "\"%s\" saltato --- solo un superutente o il proprietario del database possono analizzarlo." -#: commands/analyze.c:176 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" msgstr "\"%s\" saltato --- solo il proprietario del database o della tabella possono analizzarlo" -#: commands/analyze.c:236 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "\"%s\" saltato --- non è possibile analizzare questa tabella esterna" -#: commands/analyze.c:253 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "\"%s\" saltato --- non è possibile analizzare non-tabelle o le tabelle speciali di sistema" -#: commands/analyze.c:334 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "analisi dell'albero di ereditarietà di \"%s.%s\"" -#: commands/analyze.c:339 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "analisi di \"%s.%s\"" -#: commands/analyze.c:668 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "la colonna \"%s\" della relazione \"%s\" è specificata più di una volta" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "analisi automatica della tabella \"%s.%s.%s\" uso del sistema: %s" -#: commands/analyze.c:1220 +#: commands/analyze.c:1273 #, c-format msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" msgstr "\"%s\": esaminate %d pagine su %u, contenenti %.0f righe vive e %.0f righe morte; %d righe nel campione, %.0f righe totali stimate" -#: commands/analyze.c:1300 +#: commands/analyze.c:1353 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" msgstr "analyze dell'albero di ereditarietà \"%s.%s\" saltato --- questo albero non ha tabelle figlie" -#: commands/analyze.c:1398 +#: commands/analyze.c:1451 #, c-format msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" msgstr "analyze dell'albero di ereditarietà \"%s.%s\" saltato --- questo albero non ha tabelle figlie analizzabili" -#: commands/async.c:555 +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "Il nome del canale non può essere vuoto" -#: commands/async.c:560 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "il nome del canale è troppo lungo" -#: commands/async.c:567 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "la stringa del carico è troppo lunga" -#: commands/async.c:753 +#: commands/async.c:756 #, c-format msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" msgstr "non è possibile eseguire PREPARE in una transazione che ha eseguito LISTEN, UNLISTEN o NOTIFY" -#: commands/async.c:856 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "troppe notifiche nella coda di NOTIFY" -#: commands/async.c:1486 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "la coda di NOTIFY è piena al %.0f%%" -#: commands/async.c:1488 +#: commands/async.c:1493 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." msgstr "Il processo server con PID %d è tra quelli con le transazioni più vecchie." -#: commands/async.c:1491 +#: commands/async.c:1496 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "La coda di NOTIFY non può essere svuotata finché quel processo non avrà terminato la sua transazione corrente." -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "non è possibile raggruppare tabelle temporanee di altre sessioni" -#: commands/cluster.c:159 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "non è possibile eseguire CLUSTER su una tabella partizionata" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "non esiste un indice già raggruppato per la tabella \"%s\"" -#: commands/cluster.c:173 commands/tablecmds.c:10176 commands/tablecmds.c:12039 +#: commands/cluster.c:181 commands/tablecmds.c:10628 commands/tablecmds.c:12478 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "l'indice \"%s\" per la tabella \"%s\" non esiste" -#: commands/cluster.c:353 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "non è possibile raggruppare un catalogo condiviso" -#: commands/cluster.c:368 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "non è possibile ripulire tabelle temporanee di altre sessioni" -#: commands/cluster.c:431 commands/tablecmds.c:12049 +#: commands/cluster.c:439 commands/tablecmds.c:12488 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "\"%s\" non è un indice per la tabella \"%s\"" -#: commands/cluster.c:439 +#: commands/cluster.c:447 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "non è possibile raggruppare sull'indice \"%s\" perché il metodo di accesso non supporta il raggruppamento" -#: commands/cluster.c:451 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "non è possibile raggruppare sull'indice parziale \"%s\"" -#: commands/cluster.c:465 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "non è possibile raggruppare sull'indice non valido \"%s\"" -#: commands/cluster.c:918 +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "non è possibile marcare un indice come raggruppato in una tabella partizionata" + +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "raggruppamento di \"%s.%s\" usando una scansione sull'indice \"%s\"" -#: commands/cluster.c:924 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "raggruppamento di \"%s.%s\" usando una scansione sequenziale e ordinamento" -#: commands/cluster.c:929 commands/vacuumlazy.c:491 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" msgstr "pulizia di \"%s.%s\"" -#: commands/cluster.c:1084 +#: commands/cluster.c:1106 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" msgstr "\"%s\": trovate %.0f versioni di riga removibili, %.0f non removibili in %u pagine" -#: commands/cluster.c:1088 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5471,101 +5501,92 @@ msgstr "" "%.0f versioni di riga morte non possono ancora essere rimosse.\n" "%s." -#: commands/collationcmds.c:93 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "attributo dell'ordinamento \"%s\" non riconosciuto" -#: commands/collationcmds.c:152 +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "l'ordinamento \"default\" non può essere copiato" + +#: commands/collationcmds.c:172 #, c-format msgid "unrecognized collation provider: %s" msgstr "fornitore di ordinamenti non riconosciuto: %s" -#: commands/collationcmds.c:161 +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "il parametro \"lc_collate\" deve essere specificato" -#: commands/collationcmds.c:166 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "il parametro \"lc_ctype\" deve essere specificato" -#: commands/collationcmds.c:217 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "l'ordinamento \"%s\" per la codifica \"%s\" già esiste nello schema \"%s\"" -#: commands/collationcmds.c:228 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "l'ordinamento \"%s\" già esiste nello schema \"%s\"" -#: commands/collationcmds.c:276 +#: commands/collationcmds.c:304 #, c-format msgid "changing version from %s to %s" msgstr "cambio della versione da %s a %s" -#: commands/collationcmds.c:291 +#: commands/collationcmds.c:319 #, c-format msgid "version has not changed" msgstr "la versione non è cambiata" -#: commands/collationcmds.c:382 +#: commands/collationcmds.c:450 #, c-format msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "conversione del nome di locale \"%s\" in tag di linguaggio fallita: %s" -#: commands/collationcmds.c:401 -#, c-format -msgid "could get display name for locale \"%s\": %s" -msgstr "lettura del nome da mostrare per il locale \"%s\" fallita: %s" - -#: commands/collationcmds.c:432 +#: commands/collationcmds.c:511 #, c-format msgid "must be superuser to import system collations" msgstr "solo un superutente può importare gli ordinamenti di sistema" -#: commands/collationcmds.c:439 commands/copy.c:1829 commands/copy.c:3026 +#: commands/collationcmds.c:534 commands/copy.c:1826 commands/copy.c:3131 +#: libpq/be-secure-common.c:80 #, c-format msgid "could not execute command \"%s\": %m" msgstr "esecuzione del comando \"%s\" fallita: %m" -#: commands/collationcmds.c:536 +#: commands/collationcmds.c:665 #, c-format msgid "no usable system locales were found" msgstr "non è stato trovato nessun locale di sistema utilizzabile" -#: commands/collationcmds.c:544 utils/mb/encnames.c:473 -#, c-format -msgid "encoding \"%s\" not supported by ICU" -msgstr "codifica \"%s\" non supportata da ICU" - -#: commands/collationcmds.c:588 commands/collationcmds.c:609 -#, c-format -msgid "could not get keyword values for locale \"%s\": %s" -msgstr "errore nella lettura dei valori chiave per il locale \"%s\": %s" - #: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 #: commands/dbcommands.c:1100 commands/dbcommands.c:1290 #: commands/dbcommands.c:1513 commands/dbcommands.c:1627 -#: commands/dbcommands.c:2043 utils/init/postinit.c:846 -#: utils/init/postinit.c:951 utils/init/postinit.c:968 +#: commands/dbcommands.c:2043 utils/init/postinit.c:853 +#: utils/init/postinit.c:958 utils/init/postinit.c:975 #, c-format msgid "database \"%s\" does not exist" msgstr "il database \"%s\" non esiste" -#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:922 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" msgstr "\"%s\" non è una tabella, vista, vista materializzata, tipo composito né una tabella esterna" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2715 +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "la funzione \"%s\" non è stata invocata dal trigger manager" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2724 +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "la funzione \"%s\" deve essere eseguita AFTER ROW" @@ -5575,549 +5596,544 @@ msgstr "la funzione \"%s\" deve essere eseguita AFTER ROW" msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "la funzione \"%s\" deve essere eseguita per un INSERT o un UPDATE" -#: commands/conversioncmds.c:66 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "la codifica di partenza \"%s\" non esiste" -#: commands/conversioncmds.c:73 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "la codifica di destinazione \"%s\" non esiste" -#: commands/conversioncmds.c:87 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "la funzione di conversione della codifica %s deve restituire il tipo %s" -#: commands/copy.c:371 commands/copy.c:405 +#: commands/copy.c:372 commands/copy.c:406 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY non è supportato verso stdout o da stdin" -#: commands/copy.c:505 +#: commands/copy.c:506 #, c-format msgid "could not write to COPY program: %m" msgstr "scrittura nel programma COPY fallita: %m" -#: commands/copy.c:510 +#: commands/copy.c:511 #, c-format msgid "could not write to COPY file: %m" msgstr "scrittura nel file COPY fallita: %m" -#: commands/copy.c:523 +#: commands/copy.c:524 #, c-format msgid "connection lost during COPY to stdout" msgstr "connessione persa durante COPY verso stdout" -#: commands/copy.c:567 +#: commands/copy.c:568 #, c-format msgid "could not read from COPY file: %m" msgstr "lettura dal file COPY fallita: %m" -#: commands/copy.c:583 commands/copy.c:604 commands/copy.c:608 -#: tcop/postgres.c:341 tcop/postgres.c:377 tcop/postgres.c:404 +#: commands/copy.c:584 commands/copy.c:605 commands/copy.c:609 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "fine-file inaspettato sulla connessione del client con una transazione aperta" -#: commands/copy.c:621 +#: commands/copy.c:622 #, c-format msgid "COPY from stdin failed: %s" msgstr "COPY da stdin fallita: %s" -#: commands/copy.c:637 +#: commands/copy.c:638 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "messaggio del tipo inaspettato 0x%02X durante COPY da stdin" -#: commands/copy.c:798 +#: commands/copy.c:804 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "occorre essere un superutente per effettuare COPY da o verso un programma esterno" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "occorre essere un superutente o membro del ruolo pg_execute_server_program per effettuare COPY da o verso un programma esterno" -#: commands/copy.c:799 commands/copy.c:805 +#: commands/copy.c:805 commands/copy.c:814 commands/copy.c:821 #, c-format msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "Chiunque può eseguire COPY verso stdout e da stdin. Anche il comando \\copy di psql funziona per chiunque." -#: commands/copy.c:804 +#: commands/copy.c:813 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "bisogna essere un superutente per eseguire un COPY da o verso un file" +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "bisogna essere un superutente o membro del ruolo pg_read_server_files per eseguire COPY da un file" -#: commands/copy.c:866 +#: commands/copy.c:820 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "bisogna essere un superutente o membro del ruolo pg_write_server_files per eseguire COPY in un file" + +#: commands/copy.c:883 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "COPY FROM non supportato con il livello di sicurezza di righe" -#: commands/copy.c:867 +#: commands/copy.c:884 #, c-format msgid "Use INSERT statements instead." msgstr "Usa istruzioni INSERT invece." -#: commands/copy.c:1052 +#: commands/copy.c:1069 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "Formato di COPY \"%s\" non riconosciuto" -#: commands/copy.c:1132 commands/copy.c:1148 commands/copy.c:1163 -#: commands/copy.c:1185 +#: commands/copy.c:1149 commands/copy.c:1165 commands/copy.c:1180 +#: commands/copy.c:1202 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "l'argomento dell'opzione \"%s\" dev'essere una lista di nomi di colonne" -#: commands/copy.c:1200 +#: commands/copy.c:1217 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "l'argomento dell'opzione \"%s\" dev'essere un nome di codifica valido" -#: commands/copy.c:1207 commands/dbcommands.c:242 commands/dbcommands.c:1461 +#: commands/copy.c:1224 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" msgstr "opzione \"%s\" non riconosciuta" -#: commands/copy.c:1219 +#: commands/copy.c:1236 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "non è possibile specificare DELIMITER in BINARY mode" -#: commands/copy.c:1224 +#: commands/copy.c:1241 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "non è possibile specificare NULL in BINARY mode" -#: commands/copy.c:1246 +#: commands/copy.c:1263 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "il delimitatore di COPY deve essere un solo carattere di un solo byte" -#: commands/copy.c:1253 +#: commands/copy.c:1270 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "Il delimitatore di COPY non può essere una \"nuova riga\" o un \"ritorno carrello\"" -#: commands/copy.c:1259 +#: commands/copy.c:1276 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "la rappresentazione dei null in COPY non può usare \"nuova riga\" o \"ritorno carrello\"" -#: commands/copy.c:1276 +#: commands/copy.c:1293 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "il delimitatore di COPY non può essere \"%s\"" -#: commands/copy.c:1282 +#: commands/copy.c:1299 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "l'HEADER di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1288 +#: commands/copy.c:1305 #, c-format msgid "COPY quote available only in CSV mode" msgstr "il quoting di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1293 +#: commands/copy.c:1310 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "il quote di COPY dev'essere un solo carattere di un byte" -#: commands/copy.c:1298 +#: commands/copy.c:1315 #, c-format msgid "COPY delimiter and quote must be different" msgstr "il delimitatore e il quote di COPY devono essere diversi" -#: commands/copy.c:1304 +#: commands/copy.c:1321 #, c-format msgid "COPY escape available only in CSV mode" msgstr "l'escape di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1309 +#: commands/copy.c:1326 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "l'escape di COPY deve essere un solo carattere di un byte" -#: commands/copy.c:1315 +#: commands/copy.c:1332 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "il \"force quote\" di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1319 +#: commands/copy.c:1336 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "il \"force quote\" di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1325 +#: commands/copy.c:1342 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "il \"force not null\" di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1329 +#: commands/copy.c:1346 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "il \"force not null\" di COPY è disponibile solo in COPY FROM" -#: commands/copy.c:1335 +#: commands/copy.c:1352 #, c-format msgid "COPY force null available only in CSV mode" msgstr "il \"force null\" di COPY è disponibile solo in modalità CSV" -#: commands/copy.c:1340 +#: commands/copy.c:1357 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "il \"force null\" di COPY è disponibile solo usando COPY FROM" -#: commands/copy.c:1346 +#: commands/copy.c:1363 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "il delimitatore di COPY non deve apparire nella specificazione di NULL" -#: commands/copy.c:1353 +#: commands/copy.c:1370 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "Il carattere quote del CSV non deve apparire nella specificazione di NULL" -#: commands/copy.c:1414 +#: commands/copy.c:1431 #, c-format msgid "table \"%s\" does not have OIDs" msgstr "la tabella \"%s\" non ha OID" -#: commands/copy.c:1455 +#: commands/copy.c:1448 #, c-format msgid "COPY (query) WITH OIDS is not supported" msgstr "COPY (query) WITH OIDS non è supportata" -#: commands/copy.c:1476 +#: commands/copy.c:1469 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "le regole DO INSTEAD NOTHING non sono supportate per COPY" -#: commands/copy.c:1490 +#: commands/copy.c:1483 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "le regole DO INSTEAD condizionali non sono supportate per COPY" -#: commands/copy.c:1494 +#: commands/copy.c:1487 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "le regole DO ALSO non sono supportate per COPY" -#: commands/copy.c:1499 +#: commands/copy.c:1492 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "le regole DO INSTEAD con più istruzioni non sono supportate per COPY" -#: commands/copy.c:1509 +#: commands/copy.c:1502 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) non è supportata" -#: commands/copy.c:1526 +#: commands/copy.c:1519 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "la query COPY deve avere una clausola RETURNING" -#: commands/copy.c:1554 +#: commands/copy.c:1547 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "la relazione referenziata dall'istruzione COPY è cambiata" -#: commands/copy.c:1612 +#: commands/copy.c:1606 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "la colonna FORCE_QUOTE \"%s\" non è referenziata da COPY" -#: commands/copy.c:1634 +#: commands/copy.c:1629 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "la colonna FORCE_NOT_NULL \"%s\" non è referenziata da COPY" -#: commands/copy.c:1656 +#: commands/copy.c:1652 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "la colonna FORCE_NULL \"%s\" non è referenziata da COPY" -#: commands/copy.c:1721 +#: commands/copy.c:1718 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "chiusura della pipe per verso il comando esterno fallita: %m" -#: commands/copy.c:1725 +#: commands/copy.c:1722 #, c-format msgid "program \"%s\" failed" msgstr "programma \"%s\" fallito" -#: commands/copy.c:1775 +#: commands/copy.c:1772 #, c-format msgid "cannot copy from view \"%s\"" msgstr "non è possibile copiare dalla vista \"%s\"" -#: commands/copy.c:1777 commands/copy.c:1783 commands/copy.c:1789 -#: commands/copy.c:1800 +#: commands/copy.c:1774 commands/copy.c:1780 commands/copy.c:1786 +#: commands/copy.c:1797 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Prova la variante COPY (SELECT ...) TO." -#: commands/copy.c:1781 +#: commands/copy.c:1778 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "non è possibile copiare dalla vista materializzata \"%s\"" -#: commands/copy.c:1787 +#: commands/copy.c:1784 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "non è possibile copiare dalla tabella esterna \"%s\"" -#: commands/copy.c:1793 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "non è possibile copiare dalla sequenza \"%s\"" -#: commands/copy.c:1798 +#: commands/copy.c:1795 #, c-format msgid "cannot copy from partitioned table \"%s\"" msgstr "non è possibile copiare dalla tabella partizionata \"%s\"" -#: commands/copy.c:1804 +#: commands/copy.c:1801 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "non è possibile copiare dalla relazione \"%s\" perché non è una tabella" -#: commands/copy.c:1844 +#: commands/copy.c:1841 #, c-format msgid "relative path not allowed for COPY to file" msgstr "i percorsi relativi non sono consentiti per il COPY verso un file" -#: commands/copy.c:1856 +#: commands/copy.c:1862 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "apertura del file \"%s\" in scrittura fallita: %m" -#: commands/copy.c:1859 +#: commands/copy.c:1865 #, c-format msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY TO fa scrivere un file al processo server PostgreSQL. Probabilmente ti serve un sistema lato client, per esempio il comando \\copy di psql." -#: commands/copy.c:1872 commands/copy.c:3057 +#: commands/copy.c:1878 commands/copy.c:3162 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\" è una directory" -#: commands/copy.c:2195 +#: commands/copy.c:2204 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, riga %d, colonna %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, linea %s, colonna %s" -#: commands/copy.c:2199 commands/copy.c:2246 +#: commands/copy.c:2208 commands/copy.c:2255 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, riga %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, linea %s" -#: commands/copy.c:2210 +#: commands/copy.c:2219 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, riga %d, colonna %s: \"%s\"" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, linea %s, colonna %s: \"%s\"" -#: commands/copy.c:2218 +#: commands/copy.c:2227 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, riga %d, colonna %s: input nullo" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, linea %s, colonna %s: input null" -#: commands/copy.c:2240 +#: commands/copy.c:2249 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, riga %d: \"%s\"" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, linea %s, \"%s\"" -#: commands/copy.c:2334 +#: commands/copy.c:2345 #, c-format msgid "cannot copy to view \"%s\"" msgstr "non è possibile copiare verso la vista \"%s\"" -#: commands/copy.c:2336 +#: commands/copy.c:2347 #, c-format msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." msgstr "Per consentire la copia in una vista occorre fornire un trigger INSTEAD OF INSERT." -#: commands/copy.c:2340 +#: commands/copy.c:2351 #, c-format msgid "cannot copy to materialized view \"%s\"" msgstr "non è possibile copiare verso la vista materializzata \"%s\"" -#: commands/copy.c:2345 -#, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "non è possibile copiare verso la tabella esterna \"%s\"" - -#: commands/copy.c:2350 +#: commands/copy.c:2356 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "non è possibile copiare verso sequenza \"%s\"" -#: commands/copy.c:2355 +#: commands/copy.c:2361 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "non è possibile copiare verso la relazione \"%s\" perché non è una tabella" -#: commands/copy.c:2418 +#: commands/copy.c:2436 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" msgstr "non è possibile eseguire FREEZE a causa di precedente attività della transazione" -#: commands/copy.c:2424 +#: commands/copy.c:2442 #, c-format msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" msgstr "non è possibile eseguire FREEZE perché la tabella non è stata creata o troncata nella sottotransazione corrente" -#: commands/copy.c:2587 executor/nodeModifyTable.c:311 -#, c-format -msgid "cannot route inserted tuples to a foreign table" -msgstr "non è possibile instradare le tuple inserite in una tabella esterna" - -#: commands/copy.c:3044 +#: commands/copy.c:3149 #, c-format msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." msgstr "COPY TO fa leggere un file dal processo server PostgreSQL. Probabilmente ti serve un sistema lato client, per esempio il comando \\copy di psql." -#: commands/copy.c:3077 +#: commands/copy.c:3182 #, c-format msgid "COPY file signature not recognized" msgstr "formato del file COPY non riconosciuto" -#: commands/copy.c:3082 +#: commands/copy.c:3187 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "intestazione del file COPY non valida (flag mancanti)" -#: commands/copy.c:3088 +#: commands/copy.c:3193 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "alcune flag critici non sono stati riconosciuti nell'intestazione del file COPY" -#: commands/copy.c:3094 +#: commands/copy.c:3199 #, c-format msgid "invalid COPY file header (missing length)" msgstr "intestazione del file COPY non valida (manca la lunghezza)" -#: commands/copy.c:3101 +#: commands/copy.c:3206 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "intestazione del file COPY non valida (lunghezza errata)" -#: commands/copy.c:3234 commands/copy.c:3941 commands/copy.c:4171 +#: commands/copy.c:3337 commands/copy.c:4046 commands/copy.c:4276 #, c-format msgid "extra data after last expected column" msgstr "ci sono dati in eccesso dopo l'ultima colonna attesa" -#: commands/copy.c:3244 +#: commands/copy.c:3347 #, c-format msgid "missing data for OID column" msgstr "dati per la colonna OID mancanti" -#: commands/copy.c:3250 +#: commands/copy.c:3353 #, c-format msgid "null OID in COPY data" msgstr "OID nullo nei dati da COPY" -#: commands/copy.c:3260 commands/copy.c:3383 +#: commands/copy.c:3363 commands/copy.c:3487 #, c-format msgid "invalid OID in COPY data" msgstr "OID non valido nei dati da COPY" -#: commands/copy.c:3275 +#: commands/copy.c:3379 #, c-format msgid "missing data for column \"%s\"" msgstr "dati mancanti per la colonna \"%s\"" -#: commands/copy.c:3358 +#: commands/copy.c:3462 #, c-format msgid "received copy data after EOF marker" msgstr "dati da copiare ricevuti dopo il segnalatore di fine file" -#: commands/copy.c:3365 +#: commands/copy.c:3469 #, c-format msgid "row field count is %d, expected %d" msgstr "il numero di campi è %d, ne erano attesi %d" -#: commands/copy.c:3705 commands/copy.c:3722 +#: commands/copy.c:3810 commands/copy.c:3827 #, c-format msgid "literal carriage return found in data" msgstr "\"ritorno carrello\" trovato nei dati" -#: commands/copy.c:3706 commands/copy.c:3723 +#: commands/copy.c:3811 commands/copy.c:3828 #, c-format msgid "unquoted carriage return found in data" msgstr "\"ritorno carrello\" non quotato trovato nei dati" -#: commands/copy.c:3708 commands/copy.c:3725 +#: commands/copy.c:3813 commands/copy.c:3830 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "Usa \"\\r\" per rappresentare i caratteri \"ritorno carrello\"." -#: commands/copy.c:3709 commands/copy.c:3726 +#: commands/copy.c:3814 commands/copy.c:3831 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "Usa un campo CSV quotato per rappresentare i caratteri \"ritorno carrello\"." -#: commands/copy.c:3738 +#: commands/copy.c:3843 #, c-format msgid "literal newline found in data" msgstr "\"nuova riga\" letterale trovato nei dati" -#: commands/copy.c:3739 +#: commands/copy.c:3844 #, c-format msgid "unquoted newline found in data" msgstr "\"nuova riga\" non quotato trovato nei dati" -#: commands/copy.c:3741 +#: commands/copy.c:3846 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "Usa \"\\n\" per rappresentare i caratteri \"nuova riga\"." -#: commands/copy.c:3742 +#: commands/copy.c:3847 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "Usa un campo CSV quotato per rappresentare i caratteri \"nuova riga\"." -#: commands/copy.c:3788 commands/copy.c:3824 +#: commands/copy.c:3893 commands/copy.c:3929 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "il marcatore di fine copia non combacia con il precedente stile \"nuova riga\"" -#: commands/copy.c:3797 commands/copy.c:3813 +#: commands/copy.c:3902 commands/copy.c:3918 #, c-format msgid "end-of-copy marker corrupt" msgstr "il marcatore di fine copia è corrotto" -#: commands/copy.c:4255 +#: commands/copy.c:4360 #, c-format msgid "unterminated CSV quoted field" msgstr "campo CSV tra virgolette non terminato" -#: commands/copy.c:4332 commands/copy.c:4351 +#: commands/copy.c:4437 commands/copy.c:4456 #, c-format msgid "unexpected EOF in COPY data" msgstr "fine file inattesa dei dati da COPY" -#: commands/copy.c:4341 +#: commands/copy.c:4446 #, c-format msgid "invalid field size" msgstr "dimensione del campo non valida" -#: commands/copy.c:4364 +#: commands/copy.c:4469 #, c-format msgid "incorrect binary data format" msgstr "formato di dati binari non corretto" -#: commands/copy.c:4675 commands/indexcmds.c:1057 commands/tablecmds.c:1666 -#: commands/tablecmds.c:2168 commands/tablecmds.c:2600 -#: parser/parse_relation.c:3249 parser/parse_relation.c:3269 -#: utils/adt/tsvector_op.c:2561 +#: commands/copy.c:4781 commands/indexcmds.c:1463 commands/statscmds.c:206 +#: commands/tablecmds.c:1897 commands/tablecmds.c:2413 +#: commands/tablecmds.c:2824 parser/parse_relation.c:3288 +#: parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" msgstr "la colonna \"%s\" non esiste" -#: commands/copy.c:4682 commands/tablecmds.c:1692 commands/tablecmds.c:2194 -#: commands/trigger.c:767 parser/parse_target.c:1018 parser/parse_target.c:1029 +#: commands/copy.c:4788 commands/tablecmds.c:1923 commands/tablecmds.c:2439 +#: commands/trigger.c:913 parser/parse_target.c:1040 parser/parse_target.c:1051 #, c-format msgid "column \"%s\" specified more than once" msgstr "la colonna \"%s\" è stata specificata più di una volta" @@ -6152,8 +6168,8 @@ msgstr "%d non è un codice di codifica valido" msgid "%s is not a valid encoding name" msgstr "%s non è un nome di codifica valido" -#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:277 -#: commands/user.c:642 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 +#: commands/user.c:664 #, c-format msgid "invalid connection limit: %d" msgstr "limite di connessioni non valido: %d" @@ -6275,10 +6291,10 @@ msgstr "il database \"%s\" è usato da uno slot di replica attivo" #: commands/dbcommands.c:860 #, c-format -msgid "There is %d active slot" -msgid_plural "There are %d active slots" -msgstr[0] "Ci sono %d slot attivi" -msgstr[1] "Ci sono %d slot attivi" +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "C'è %d slot attivo." +msgstr[1] "Ci sono %d slot attivi." #: commands/dbcommands.c:874 commands/dbcommands.c:1038 #: commands/dbcommands.c:1168 @@ -6325,7 +6341,7 @@ msgstr "Occorre spostarle di nuovo nel tablespace di default del database prima #: commands/dbcommands.c:1355 commands/dbcommands.c:1900 #: commands/dbcommands.c:2104 commands/dbcommands.c:2159 -#: commands/tablespace.c:604 +#: commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "alcuni file inutili possono essere stati lasciati nella vecchia directory del database \"%s\"" @@ -6401,469 +6417,479 @@ msgstr "l'argomento di %s deve essere il nome di un tipo" msgid "invalid argument for %s: \"%s\"" msgstr "argomento non valido per %s: \"%s\"" -#: commands/dropcmds.c:104 commands/functioncmds.c:1201 -#: utils/adt/ruleutils.c:2445 +#: commands/dropcmds.c:98 commands/functioncmds.c:1212 +#: utils/adt/ruleutils.c:2562 #, c-format msgid "\"%s\" is an aggregate function" msgstr "\"%s\" è una funzione di aggregazione" -#: commands/dropcmds.c:106 +#: commands/dropcmds.c:100 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "Usa DROP AGGREGATE per rimuovere le funzioni di aggregazione." -#: commands/dropcmds.c:157 commands/sequence.c:437 commands/tablecmds.c:2684 -#: commands/tablecmds.c:2835 commands/tablecmds.c:2878 -#: commands/tablecmds.c:12422 tcop/utility.c:1168 +#: commands/dropcmds.c:149 commands/sequence.c:441 commands/tablecmds.c:2908 +#: commands/tablecmds.c:3059 commands/tablecmds.c:3102 +#: commands/tablecmds.c:12861 tcop/utility.c:1160 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "la relazione \"%s\" non esiste, saltata" -#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:877 +#: commands/dropcmds.c:179 commands/dropcmds.c:278 commands/tablecmds.c:1019 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "lo schema \"%s\" non esiste, saltato" -#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:252 +#: commands/dropcmds.c:219 commands/dropcmds.c:258 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "il tipo \"%s\" non esiste, saltato" -#: commands/dropcmds.c:256 +#: commands/dropcmds.c:248 #, c-format msgid "access method \"%s\" does not exist, skipping" msgstr "il metodo di accesso \"%s\" non esiste, saltato" -#: commands/dropcmds.c:274 +#: commands/dropcmds.c:266 #, c-format msgid "collation \"%s\" does not exist, skipping" msgstr "l'ordinamento \"%s\" non esiste, saltato" -#: commands/dropcmds.c:281 +#: commands/dropcmds.c:273 #, c-format msgid "conversion \"%s\" does not exist, skipping" msgstr "la conversione \"%s\" non esiste, saltata" -#: commands/dropcmds.c:292 +#: commands/dropcmds.c:284 #, c-format msgid "statistics object \"%s\" does not exist, skipping" msgstr "la statistica \"%s\" non esiste, saltata" -#: commands/dropcmds.c:299 +#: commands/dropcmds.c:291 #, c-format msgid "text search parser \"%s\" does not exist, skipping" msgstr "l'analizzatore di ricerca di testo \"%s\" non esiste, saltato" -#: commands/dropcmds.c:306 +#: commands/dropcmds.c:298 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" msgstr "il dizionario di ricerca di testo \"%s\" non esiste, saltato" -#: commands/dropcmds.c:313 +#: commands/dropcmds.c:305 #, c-format msgid "text search template \"%s\" does not exist, skipping" msgstr "il modello di ricerca di testo \"%s\" non esiste, saltato" -#: commands/dropcmds.c:320 +#: commands/dropcmds.c:312 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" msgstr "la combinazione di ricerca di testo \"%s\" non esiste, saltato" -#: commands/dropcmds.c:325 +#: commands/dropcmds.c:317 #, c-format msgid "extension \"%s\" does not exist, skipping" msgstr "l'estensione \"%s\" non esiste, saltata" -#: commands/dropcmds.c:335 +#: commands/dropcmds.c:327 #, c-format msgid "function %s(%s) does not exist, skipping" msgstr "la funzione %s(%s) non esiste, saltata" -#: commands/dropcmds.c:348 +#: commands/dropcmds.c:340 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "la procedura %s(%s) non esiste, saltata" + +#: commands/dropcmds.c:353 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "la routine %s(%s) non esiste, saltata" + +#: commands/dropcmds.c:366 #, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "la funzione di aggregazione %s(%s) non esiste, saltato" -#: commands/dropcmds.c:361 +#: commands/dropcmds.c:379 #, c-format msgid "operator %s does not exist, skipping" msgstr "l'operatore %s non esiste, saltato" -#: commands/dropcmds.c:367 +#: commands/dropcmds.c:385 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "il linguaggio \"%s\" non esiste, saltato" -#: commands/dropcmds.c:376 +#: commands/dropcmds.c:394 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "la conversione dal tipo %s al tipo %s non esiste, saltata" -#: commands/dropcmds.c:385 +#: commands/dropcmds.c:403 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "la trasformazione per il tipo %s linguaggio \"%s\" non esiste, saltata" -#: commands/dropcmds.c:393 +#: commands/dropcmds.c:411 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr "il trigger \"%s\" per la relazione \"%s\" non esiste, saltato" -#: commands/dropcmds.c:402 +#: commands/dropcmds.c:420 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr "la regola di sicurezza \"%s\" per la relazione \"%s\" non esiste, saltata" -#: commands/dropcmds.c:409 +#: commands/dropcmds.c:427 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "il trigger di evento \"%s\" non esiste, saltato" -#: commands/dropcmds.c:415 +#: commands/dropcmds.c:433 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr "la regola \"%s\" per la relazione \"%s\" non esiste, saltata" -#: commands/dropcmds.c:422 +#: commands/dropcmds.c:440 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "il wrapper di dati remoti \"%s\" non esiste, saltato" -#: commands/dropcmds.c:426 +#: commands/dropcmds.c:444 #, c-format msgid "server \"%s\" does not exist, skipping" msgstr "il server \"%s\" non esiste, saltato" -#: commands/dropcmds.c:435 +#: commands/dropcmds.c:453 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" msgstr "la classe di operatori \"%s\" non esiste per il metodo di accesso \"%s\", saltata" -#: commands/dropcmds.c:447 +#: commands/dropcmds.c:465 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" msgstr "la famiglia di operatori \"%s\" non esiste per il metodo di accesso \"%s\", saltata" -#: commands/dropcmds.c:454 +#: commands/dropcmds.c:472 #, c-format msgid "publication \"%s\" does not exist, skipping" msgstr "la pubblicazione \"%s\" non esiste, saltata" -#: commands/event_trigger.c:185 +#: commands/event_trigger.c:187 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "permesso di creare il trigger di evento \"%s\" negato" -#: commands/event_trigger.c:187 +#: commands/event_trigger.c:189 #, c-format msgid "Must be superuser to create an event trigger." msgstr "Solo un superutente può creare un trigger di evento." -#: commands/event_trigger.c:196 +#: commands/event_trigger.c:198 #, c-format msgid "unrecognized event name \"%s\"" msgstr "nome dell'evento \"%s\" sconosciuto" -#: commands/event_trigger.c:213 +#: commands/event_trigger.c:215 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "variabile filtro \"%s\" sconosciuta" -#: commands/event_trigger.c:268 +#: commands/event_trigger.c:270 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "valore del filtro \"%s\" sconosciuto per la variabile filtro \"%s\"" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:274 commands/event_trigger.c:344 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format msgid "event triggers are not supported for %s" msgstr "trigger di eventi non supportati per %s" -#: commands/event_trigger.c:367 +#: commands/event_trigger.c:369 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "la variabile filtro \"%s\" è specificata più di una volta" -#: commands/event_trigger.c:514 commands/event_trigger.c:557 -#: commands/event_trigger.c:649 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 +#: commands/event_trigger.c:651 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "il trigger di evento \"%s\" non esiste" -#: commands/event_trigger.c:618 +#: commands/event_trigger.c:620 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "permesso di cambiare il proprietario del trigger di evento \"%s\" negato" -#: commands/event_trigger.c:620 +#: commands/event_trigger.c:622 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "Il proprietario di un trigger di evento deve essere un superutente." -#: commands/event_trigger.c:1464 +#: commands/event_trigger.c:1457 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s può essere chiamata solo in una funzione trigger di evento sql_drop" -#: commands/event_trigger.c:1584 commands/event_trigger.c:1605 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s può essere chiamata solo in una funzione trigger di evento table_rewrite" -#: commands/event_trigger.c:2015 +#: commands/event_trigger.c:2009 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s può essere chiamata solo in una funzione trigger di evento" -#: commands/explain.c:194 +#: commands/explain.c:192 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "valore sconosciuto per l'opzione di EXPLAIN \"%s\": \"%s\"" -#: commands/explain.c:201 +#: commands/explain.c:199 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "opzione di EXPLAIN non riconosciuta \"%s\"" -#: commands/explain.c:209 +#: commands/explain.c:207 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "l'opzione BUFFERS di EXPLAIN richiede ANALYZE" -#: commands/explain.c:218 +#: commands/explain.c:216 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "l'opzione TIMING di EXPLAIN richiede ANALYZE" -#: commands/extension.c:167 commands/extension.c:2905 +#: commands/extension.c:168 commands/extension.c:2907 #, c-format msgid "extension \"%s\" does not exist" msgstr "l'estensione \"%s\" non esiste" -#: commands/extension.c:266 commands/extension.c:275 commands/extension.c:287 -#: commands/extension.c:297 +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 +#: commands/extension.c:298 #, c-format msgid "invalid extension name: \"%s\"" msgstr "nome di estensione non valido: \"%s\"" -#: commands/extension.c:267 +#: commands/extension.c:268 #, c-format msgid "Extension names must not be empty." msgstr "I nomi delle estensioni non possono essere vuoti." -#: commands/extension.c:276 +#: commands/extension.c:277 #, c-format msgid "Extension names must not contain \"--\"." msgstr "I nomi delle estensioni non possono contenere \"--\"." -#: commands/extension.c:288 +#: commands/extension.c:289 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "I nomi delle estensioni non possono iniziare o finire con \"-\"." -#: commands/extension.c:298 +#: commands/extension.c:299 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "I nomi delle estensioni non possono contenere caratteri separatore directory." -#: commands/extension.c:313 commands/extension.c:322 commands/extension.c:331 -#: commands/extension.c:341 +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 +#: commands/extension.c:342 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "nome di versione dell'estensione non valido: \"%s\"" -#: commands/extension.c:314 +#: commands/extension.c:315 #, c-format msgid "Version names must not be empty." msgstr "I nomi di versione non possono essere vuoti." -#: commands/extension.c:323 +#: commands/extension.c:324 #, c-format msgid "Version names must not contain \"--\"." msgstr "I nomi di versione non possono contenere \"--\"." -#: commands/extension.c:332 +#: commands/extension.c:333 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "I nomi di versione non possono iniziare o finire con \"-\"." -#: commands/extension.c:342 +#: commands/extension.c:343 #, c-format msgid "Version names must not contain directory separator characters." msgstr "I nomi di versione non possono contenere caratteri separatore directory." -#: commands/extension.c:492 +#: commands/extension.c:493 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "apertura del file di controllo dell'estensione \"%s\" fallita: %m" -#: commands/extension.c:514 commands/extension.c:524 +#: commands/extension.c:515 commands/extension.c:525 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "il parametro \"%s\" non può essere impostato in un file di controllo secondario di estensione" -#: commands/extension.c:563 +#: commands/extension.c:564 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "\"%s\" non è un nome di codifica valido" -#: commands/extension.c:577 +#: commands/extension.c:578 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "il parametro \"%s\" dev'essere una lista di nomi di estensioni" -#: commands/extension.c:584 +#: commands/extension.c:585 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "parametro sconosciuto \"%s\" nel file \"%s\"" -#: commands/extension.c:593 +#: commands/extension.c:594 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "il parametro \"schema\" non può essere specificato quando \"relocatable\" è abilitato" -#: commands/extension.c:760 +#: commands/extension.c:761 #, c-format msgid "transaction control statements are not allowed within an extension script" msgstr "le istruzioni di controllo di transazione non sono valide in uno script di estensione" -#: commands/extension.c:806 +#: commands/extension.c:807 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "permesso di creare l'estensione \"%s\" negato" -#: commands/extension.c:808 +#: commands/extension.c:809 #, c-format msgid "Must be superuser to create this extension." msgstr "Solo un superutente può creare questa estensione." -#: commands/extension.c:812 +#: commands/extension.c:813 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "permesso di modificare l'estensione \"%s\" negato" -#: commands/extension.c:814 +#: commands/extension.c:815 #, c-format msgid "Must be superuser to update this extension." msgstr "Solo un superutente può modificare questa estensione." -#: commands/extension.c:1096 +#: commands/extension.c:1097 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "l'estensione \"%s\" non ha un percorso di aggiornamento dalla versione \"%s\" alla versione \"%s\"" -#: commands/extension.c:1303 commands/extension.c:2966 +#: commands/extension.c:1304 commands/extension.c:2968 #, c-format msgid "version to install must be specified" msgstr "il nome di versione da installare deve essere specificato" -#: commands/extension.c:1325 +#: commands/extension.c:1326 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "la versione FROM dev'essere diversa dalla versione \"%s\" oggetto dell'installazione" -#: commands/extension.c:1390 +#: commands/extension.c:1391 #, c-format msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" msgstr "l'estensione \"%s\" non ha uno script di installazione o un percorso di update per la versione \"%s\"" -#: commands/extension.c:1425 +#: commands/extension.c:1426 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "l'estensione \"%s\" dev'essere installata nello schema \"%s\"" -#: commands/extension.c:1578 +#: commands/extension.c:1579 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "individuata una dipendenza ciclica tra le estensioni \"%s\" e \"%s\"" -#: commands/extension.c:1583 +#: commands/extension.c:1584 #, c-format msgid "installing required extension \"%s\"" msgstr "installazione dell'estensione richiesta \"%s\"" -#: commands/extension.c:1607 +#: commands/extension.c:1608 #, c-format msgid "required extension \"%s\" is not installed" msgstr "l'estensione richiesta \"%s\" non è installata" -#: commands/extension.c:1610 +#: commands/extension.c:1611 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "Usa CREATE EXTENSION ... CASCADE per installare anche le estensioni richieste." -#: commands/extension.c:1647 +#: commands/extension.c:1648 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "l'estensione \"%s\" esiste già, saltata" -#: commands/extension.c:1654 +#: commands/extension.c:1655 #, c-format msgid "extension \"%s\" already exists" msgstr "l'estensione \"%s\" esiste già" -#: commands/extension.c:1665 +#: commands/extension.c:1666 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "CREATE EXTENSION annidati non sono supportati" -#: commands/extension.c:1846 +#: commands/extension.c:1847 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "non è possibile eliminare l'estensione \"%s\" perché sta venendo modificata" -#: commands/extension.c:2348 +#: commands/extension.c:2349 #, c-format msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" msgstr "pg_extension_config_dump() può essere richiamata solo da uno script SQL eseguito da CREATE EXTENSION" -#: commands/extension.c:2360 +#: commands/extension.c:2361 #, c-format msgid "OID %u does not refer to a table" msgstr "l'OID %u non si riferisce ad una tabella" -#: commands/extension.c:2365 +#: commands/extension.c:2366 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "la tabella \"%s\" non è membra dell'estensione in fase di creazione" -#: commands/extension.c:2721 +#: commands/extension.c:2722 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "non è possibile spostare l'estensione \"%s\" nello schema \"%s\" perché l'estensione contiene lo schema" -#: commands/extension.c:2761 commands/extension.c:2824 +#: commands/extension.c:2763 commands/extension.c:2826 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "l'estensione \"%s\" non supporta SET SCHEMA" -#: commands/extension.c:2826 +#: commands/extension.c:2828 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "%s non è nello schema dell'estensione \"%s\"" -#: commands/extension.c:2885 +#: commands/extension.c:2887 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "ALTER EXTENSION annidati non sono supportati" -#: commands/extension.c:2977 +#: commands/extension.c:2979 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "la versione \"%s\" dell'estensione \"%s\" è già installata" -#: commands/extension.c:3228 +#: commands/extension.c:3230 #, c-format msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "non è possibile aggiungere lo schema \"%s\" all'estensione \"%s\" perché lo schema contiene l'estensione" -#: commands/extension.c:3256 +#: commands/extension.c:3258 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s non fa parte dell'estensione \"%s\"" -#: commands/extension.c:3322 +#: commands/extension.c:3324 #, c-format msgid "file \"%s\" is too large" msgstr "il file \"%s\" è troppo grande" @@ -6943,764 +6969,868 @@ msgstr "la mappatura utenti per \"%s\" esiste già per il server %s, saltata" msgid "user mapping for \"%s\" already exists for server %s" msgstr "la mappatura utenti per \"%s\" esiste già per il server %s" -#: commands/foreigncmds.c:1278 commands/foreigncmds.c:1393 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 #, c-format msgid "user mapping for \"%s\" does not exist for the server" msgstr "la mappatura utenti per \"%s\" non esiste per il server" -#: commands/foreigncmds.c:1380 +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" msgstr "il server non esiste, saltato" -#: commands/foreigncmds.c:1398 +#: commands/foreigncmds.c:1402 #, c-format msgid "user mapping for \"%s\" does not exist for the server, skipping" msgstr "la mappatura utenti per \"%s\" non esiste per il server, saltata" -#: commands/foreigncmds.c:1549 foreign/foreign.c:357 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "il wrapper di dati remoti \"%s\" non ha un handler" -#: commands/foreigncmds.c:1555 +#: commands/foreigncmds.c:1559 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "il wrapper di dati remoti \"%s\" non supporta IMPORT FOREIGN SCHEMA" -#: commands/foreigncmds.c:1658 +#: commands/foreigncmds.c:1662 #, c-format msgid "importing foreign table \"%s\"" msgstr "importazione della tabella remota \"%s\"" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:104 #, c-format msgid "SQL function cannot return shell type %s" msgstr "la funzione SQL non può restituire il tipo non completamente definito %s" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:109 #, c-format msgid "return type %s is only a shell" msgstr "il tipo restituito %s non è completamente definito" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:139 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "il modificatore di tipo non può essere specificato per il tipo non completamente definito \"%s\"" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:145 #, c-format msgid "type \"%s\" is not yet defined" msgstr "il tipo \"%s\" non è ancora definito" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:146 #, c-format msgid "Creating a shell type definition." msgstr "Creazione di un tipo non completamente definito." -#: commands/functioncmds.c:233 +#: commands/functioncmds.c:238 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "la funzione SQL non può accettare il tipo non completamente definito %s" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:244 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "l'aggregato non può accettare il tipo non completamente definito %s" -#: commands/functioncmds.c:244 +#: commands/functioncmds.c:249 #, c-format msgid "argument type %s is only a shell" msgstr "il tipo %s dell'argomento non è completamente definito" -#: commands/functioncmds.c:254 +#: commands/functioncmds.c:259 #, c-format msgid "type %s does not exist" msgstr "il tipo %s non esiste" -#: commands/functioncmds.c:268 +#: commands/functioncmds.c:273 #, c-format msgid "aggregates cannot accept set arguments" msgstr "gli aggregati non accettano insiemi come argomenti" -#: commands/functioncmds.c:272 +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "le procedure non accettano insiemi come argomenti" + +#: commands/functioncmds.c:281 #, c-format msgid "functions cannot accept set arguments" msgstr "le funzioni non accettano insiemi come argomenti" -#: commands/functioncmds.c:282 +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "le procedure non possono avere argomenti OUT" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "Argomenti INOUT sono permessi." + +#: commands/functioncmds.c:300 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "il parametro VARIADIC deve essere l'ultimo dei parametri di input" -#: commands/functioncmds.c:310 +#: commands/functioncmds.c:330 #, c-format msgid "VARIADIC parameter must be an array" msgstr "il parametro VARIADIC dev'essere un array" -#: commands/functioncmds.c:350 +#: commands/functioncmds.c:370 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "il nome di parametro \"%s\" è usato più di una volta" -#: commands/functioncmds.c:365 +#: commands/functioncmds.c:385 #, c-format msgid "only input parameters can have default values" msgstr "solo i parametri di input possono avere un valore di default" -#: commands/functioncmds.c:380 +#: commands/functioncmds.c:400 #, c-format msgid "cannot use table references in parameter default value" msgstr "non si possono usare riferimenti a tabelle nel valore predefinito dei parametri" -#: commands/functioncmds.c:404 +#: commands/functioncmds.c:424 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "i parametri di input che seguono uno con valore predefinito devono avere anch'essi un valore predefinito" -#: commands/functioncmds.c:700 +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "attributo non valido nella definizione della procedura" + +#: commands/functioncmds.c:747 #, c-format msgid "no function body specified" msgstr "non è stato specificato alcun corpo della funzione" -#: commands/functioncmds.c:710 +#: commands/functioncmds.c:757 #, c-format msgid "no language specified" msgstr "nessun linguaggio specificato" -#: commands/functioncmds.c:735 commands/functioncmds.c:1242 +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 #, c-format msgid "COST must be positive" msgstr "COST dev'essere positivo" -#: commands/functioncmds.c:743 commands/functioncmds.c:1250 +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 #, c-format msgid "ROWS must be positive" msgstr "ROWS dev'essere positivo" -#: commands/functioncmds.c:784 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "attributo di funzione sconosciuto \"%s\" ignorato" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:842 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "solo un elemento AS è necessario per il linguaggio \"%s\"" -#: commands/functioncmds.c:930 commands/functioncmds.c:2111 -#: commands/proclang.c:561 +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 +#: commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "il linguaggio \"%s\" non esiste" -#: commands/functioncmds.c:932 commands/functioncmds.c:2113 +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "Usa CREATE LANGUAGE per caricare il linguaggio nel database." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Usa CREATE EXTENSION per caricare il linguaggio nel database." -#: commands/functioncmds.c:967 commands/functioncmds.c:1234 +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 #, c-format msgid "only superuser can define a leakproof function" msgstr "solo un superutente può definire una funzione stagna" -#: commands/functioncmds.c:1010 +#: commands/functioncmds.c:1023 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "il risultato della funzione deve essere %s per i parametri OUT" -#: commands/functioncmds.c:1023 +#: commands/functioncmds.c:1036 #, c-format msgid "function result type must be specified" msgstr "il tipo di risultato della funzione dev'essere specificato" -#: commands/functioncmds.c:1077 commands/functioncmds.c:1254 +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "ROWS è non applicabile quando la funzione non restituisce un insieme" -#: commands/functioncmds.c:1406 +#: commands/functioncmds.c:1440 #, c-format msgid "source data type %s is a pseudo-type" msgstr "il tipo di dati di origine %s è uno pseudo-tipo" -#: commands/functioncmds.c:1412 +#: commands/functioncmds.c:1446 #, c-format msgid "target data type %s is a pseudo-type" msgstr "il tipo di dati di destinazione %s è uno pseudo-tipo" -#: commands/functioncmds.c:1436 +#: commands/functioncmds.c:1470 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "la conversione verrà ignorata perché il tipo di dato di origine è un dominio" -#: commands/functioncmds.c:1441 +#: commands/functioncmds.c:1475 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "la conversione verrà ignorata perché il tipo di dato di destinazione è un dominio" -#: commands/functioncmds.c:1466 +#: commands/functioncmds.c:1500 #, c-format msgid "cast function must take one to three arguments" msgstr "la funzione di conversione deve prendere da uno a tre argomenti" -#: commands/functioncmds.c:1470 +#: commands/functioncmds.c:1504 #, c-format msgid "argument of cast function must match or be binary-coercible from source data type" msgstr "l'argomento della funzione di conversione deve combaciare o essere convertibile a livello binario dal tipo di dato di origine" -#: commands/functioncmds.c:1474 +#: commands/functioncmds.c:1508 #, c-format msgid "second argument of cast function must be type %s" msgstr "il secondo argomento della funzione di conversione deve essere di tipo %s" -#: commands/functioncmds.c:1479 +#: commands/functioncmds.c:1513 #, c-format msgid "third argument of cast function must be type %s" msgstr "il terzo argomento della funzione di conversione deve essere di tipo %s" -#: commands/functioncmds.c:1484 +#: commands/functioncmds.c:1518 #, c-format msgid "return data type of cast function must match or be binary-coercible to target data type" msgstr "il tipo di dato restituito dalla funzione di conversione deve combaciare o essere convertibile a livello binario nel tipo di dato di destinazione" -#: commands/functioncmds.c:1495 +#: commands/functioncmds.c:1529 #, c-format msgid "cast function must not be volatile" msgstr "la funzione di conversione non può essere volatile" -#: commands/functioncmds.c:1500 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "la funzione di conversione non può essere una funzione di aggregazione" - -#: commands/functioncmds.c:1504 +#: commands/functioncmds.c:1534 #, c-format -msgid "cast function must not be a window function" -msgstr "la funzione di conversione non può essere una funzione finestra" +msgid "cast function must be a normal function" +msgstr "la funzione di conversione dev'essere una funzione normale" -#: commands/functioncmds.c:1508 +#: commands/functioncmds.c:1538 #, c-format msgid "cast function must not return a set" msgstr "la funzione di conversione non può restituire un insieme" -#: commands/functioncmds.c:1534 +#: commands/functioncmds.c:1564 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "occorre essere un superutente per creare un cast WITHOUT FUNCTION" -#: commands/functioncmds.c:1549 +#: commands/functioncmds.c:1579 #, c-format msgid "source and target data types are not physically compatible" msgstr "i tipi di dati di origine e di destinazione non sono fisicamente compatibili" -#: commands/functioncmds.c:1564 +#: commands/functioncmds.c:1594 #, c-format msgid "composite data types are not binary-compatible" msgstr "i tipi di dati compositi non sono compatibili a livello binario" -#: commands/functioncmds.c:1570 +#: commands/functioncmds.c:1600 #, c-format msgid "enum data types are not binary-compatible" msgstr "le enumerazioni non sono compatibili a livello binario" -#: commands/functioncmds.c:1576 +#: commands/functioncmds.c:1606 #, c-format msgid "array data types are not binary-compatible" msgstr "i tipi di dati array non sono compatibili a livello binario" -#: commands/functioncmds.c:1593 +#: commands/functioncmds.c:1623 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "i tipi di dominio non devono essere marcati come compatibili a livello binario" -#: commands/functioncmds.c:1603 +#: commands/functioncmds.c:1633 #, c-format msgid "source data type and target data type are the same" msgstr "i tipi di dati di origine e di destinazione sono gli stessi" -#: commands/functioncmds.c:1636 +#: commands/functioncmds.c:1666 #, c-format msgid "cast from type %s to type %s already exists" msgstr "la conversione dal tipo %s al tipo %s esiste già" -#: commands/functioncmds.c:1709 +#: commands/functioncmds.c:1739 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "la conversione dal tipo %s al tipo %s non esiste" -#: commands/functioncmds.c:1748 +#: commands/functioncmds.c:1778 #, c-format msgid "transform function must not be volatile" msgstr "la funzione di trasformazione non può essere volatile" -#: commands/functioncmds.c:1752 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "la funzione di trasformazione non può essere una funzione aggregata" - -#: commands/functioncmds.c:1756 +#: commands/functioncmds.c:1782 #, c-format -msgid "transform function must not be a window function" -msgstr "la funzione di trasformazione non può essere una funzione finestra" +msgid "transform function must be a normal function" +msgstr "la funzione di trasformazione dev'essere una funzione normale" -#: commands/functioncmds.c:1760 +#: commands/functioncmds.c:1786 #, c-format msgid "transform function must not return a set" msgstr "la funzione di trasformazione non può restituire un insieme" -#: commands/functioncmds.c:1764 +#: commands/functioncmds.c:1790 #, c-format msgid "transform function must take one argument" msgstr "la funzione di trasformazione deve poter ricevere un solo argomento" -#: commands/functioncmds.c:1768 +#: commands/functioncmds.c:1794 #, c-format msgid "first argument of transform function must be type %s" msgstr "il primo argomento della funzione di trasformazione deve essere di tipo %s" -#: commands/functioncmds.c:1806 +#: commands/functioncmds.c:1832 #, c-format msgid "data type %s is a pseudo-type" msgstr "il tipo di dato %s è uno pseudo-tipo" -#: commands/functioncmds.c:1812 +#: commands/functioncmds.c:1838 #, c-format msgid "data type %s is a domain" msgstr "il tipo di dato %s è un dominio" -#: commands/functioncmds.c:1852 +#: commands/functioncmds.c:1878 #, c-format msgid "return data type of FROM SQL function must be %s" msgstr "il tipo di dati restituito dalla funzione FROM SQL deve essere %s" -#: commands/functioncmds.c:1878 +#: commands/functioncmds.c:1904 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "il tipo di dati restituito da una funzione TO SQL dev'essere il tipo di dato della trasformazione" -#: commands/functioncmds.c:1905 +#: commands/functioncmds.c:1931 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "la trasformazione per il tipo %s linguaggio \"%s\" esiste già" -#: commands/functioncmds.c:1994 +#: commands/functioncmds.c:2020 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "la trasformazione per il tipo %s linguaggio \"%s\" non esiste" -#: commands/functioncmds.c:2045 +#: commands/functioncmds.c:2071 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "la funzione %s esiste già nello schema \"%s\"" -#: commands/functioncmds.c:2098 +#: commands/functioncmds.c:2126 #, c-format msgid "no inline code specified" msgstr "nessun codice inline specificato" -#: commands/functioncmds.c:2143 +#: commands/functioncmds.c:2172 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "il linguaggio \"%s\" non supporta l'esecuzione di codice inline" -#: commands/indexcmds.c:350 +#: commands/functioncmds.c:2271 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "non è possibile passare più di %d argomenti ad una procedura" +msgstr[1] "non è possibile passare più di %d argomenti ad una procedura" + +#: commands/indexcmds.c:393 #, c-format msgid "must specify at least one column" msgstr "occorre specificare almeno una colonna" -#: commands/indexcmds.c:354 +#: commands/indexcmds.c:397 #, c-format msgid "cannot use more than %d columns in an index" msgstr "non è possibile usare più di %d colonne in un indice" -#: commands/indexcmds.c:385 +#: commands/indexcmds.c:437 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "non è possibile creare indici sulla tabella esterna \"%s\"" -#: commands/indexcmds.c:390 +#: commands/indexcmds.c:462 #, c-format -msgid "cannot create index on partitioned table \"%s\"" -msgstr "non è possibile creare indici sulla tabella partizionata \"%s\"" +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "non è possibile creare indici sulla tabella partizionata \"%s\" concorrentemente" + +#: commands/indexcmds.c:467 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "non è possibile creare vincoli di esclusione sulla tabella partizionata \"%s\"" -#: commands/indexcmds.c:405 +#: commands/indexcmds.c:477 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "non è possibile creare indici su tabelle temporanee di altre sessioni" -#: commands/indexcmds.c:461 commands/tablecmds.c:584 commands/tablecmds.c:10484 +#: commands/indexcmds.c:542 commands/tablecmds.c:614 commands/tablecmds.c:10937 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "solo le relazioni condivise possono essere poste nel tablespace pg_global" -#: commands/indexcmds.c:494 +#: commands/indexcmds.c:575 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "sostituzione del metodo di accesso \"gist\" per il metodo obsoleto \"rtree\"" -#: commands/indexcmds.c:512 +#: commands/indexcmds.c:593 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "il metodo di accesso \"%s\" non supporta gli indici univoci" -#: commands/indexcmds.c:517 +#: commands/indexcmds.c:598 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "il metodo di accesso \"%s\" non supporta colonne incluse" + +#: commands/indexcmds.c:603 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "il metodo di accesso \"%s\" non supporta gli indici multicolonna" -#: commands/indexcmds.c:522 +#: commands/indexcmds.c:608 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "il metodo di accesso \"%s\" non supporta i vincoli di esclusione" -#: commands/indexcmds.c:594 commands/indexcmds.c:614 +#: commands/indexcmds.c:720 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "vincolo %s non supportato con una definizione di chiave di partizione" + +#: commands/indexcmds.c:722 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "I vincoli %s non possono essere usati quando le chiavi di partizioni includono espressioni." + +#: commands/indexcmds.c:740 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "colonne non sufficienti nella definizione del vincolo %s" + +#: commands/indexcmds.c:742 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "il vincolo %s sulla tabella \"%s\" non ha la colonna \"%s\" che è parte della chiave di partizione." + +#: commands/indexcmds.c:761 commands/indexcmds.c:781 #, c-format msgid "index creation on system columns is not supported" msgstr "la creazione di indici su colonne di sistema non è supportata" -#: commands/indexcmds.c:639 +#: commands/indexcmds.c:806 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s creerà un indice implicito \"%s\" per la tabella \"%s\"" -#: commands/indexcmds.c:986 +#: commands/indexcmds.c:1392 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "le funzioni nel predicato dell'indice devono essere marcate IMMUTABLE" -#: commands/indexcmds.c:1052 parser/parse_utilcmd.c:2067 +#: commands/indexcmds.c:1458 parser/parse_utilcmd.c:2239 +#: parser/parse_utilcmd.c:2363 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "la colonna \"%s\" nominata nella chiave non esiste" -#: commands/indexcmds.c:1112 +#: commands/indexcmds.c:1482 parser/parse_utilcmd.c:1588 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "le colonne incluse non supportano espressioni" + +#: commands/indexcmds.c:1523 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "le funzioni nell'espressione dell'indice devono essere marcate IMMUTABLE" -#: commands/indexcmds.c:1135 +#: commands/indexcmds.c:1538 +#, c-format +msgid "including column does not support a collation" +msgstr "le colonne incluse non supportano ordinamenti" + +#: commands/indexcmds.c:1542 +#, c-format +msgid "including column does not support an operator class" +msgstr "le colonne incluse non supportano classi di operatori" + +#: commands/indexcmds.c:1546 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "le colonne incluse non supportano opzioni ASC/DESC" + +#: commands/indexcmds.c:1550 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "le colonne incluse non supportano opzioni NULLS FIRST/LAST" + +#: commands/indexcmds.c:1577 #, c-format msgid "could not determine which collation to use for index expression" msgstr "non è stato possibile determinare quale ordinamento usare per l'espressione dell'indice" -#: commands/indexcmds.c:1143 commands/tablecmds.c:13326 commands/typecmds.c:831 -#: parser/parse_expr.c:2730 parser/parse_type.c:549 parser/parse_utilcmd.c:3103 -#: utils/adt/misc.c:661 +#: commands/indexcmds.c:1585 commands/tablecmds.c:13785 commands/typecmds.c:833 +#: parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3394 +#: utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "gli ordinamenti non sono supportati dal tipo %s" -#: commands/indexcmds.c:1181 +#: commands/indexcmds.c:1623 #, c-format msgid "operator %s is not commutative" msgstr "l'operatore %s non è commutativo" -#: commands/indexcmds.c:1183 +#: commands/indexcmds.c:1625 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "Solo operatori commutativi possono essere usati nei vincoli di esclusione." -#: commands/indexcmds.c:1209 +#: commands/indexcmds.c:1651 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "l'operatore %s non è membro della famiglia di operatori \"%s\"" -#: commands/indexcmds.c:1212 +#: commands/indexcmds.c:1654 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "L'operatore di esclusione dev'essere correlato alla classe di operatori dell'indice per il vincolo." -#: commands/indexcmds.c:1247 +#: commands/indexcmds.c:1689 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "il metodo di accesso \"%s\" non supporta le opzioni ASC/DESC" -#: commands/indexcmds.c:1252 +#: commands/indexcmds.c:1694 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "il metodo di accesso \"%s\" non supporta le opzioni NULLS FIRST/LAST" -#: commands/indexcmds.c:1311 commands/typecmds.c:1928 +#: commands/indexcmds.c:1753 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "il tipo di dati %s non ha una classe di operatori predefinita per il metodo di accesso \"%s\"" -#: commands/indexcmds.c:1313 +#: commands/indexcmds.c:1755 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "Devi specificare una classe di operatori per l'indice o definire una classe di operatori predefinita per il tipo di dati" -#: commands/indexcmds.c:1342 commands/indexcmds.c:1350 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1784 commands/indexcmds.c:1792 +#: commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "la classe di operatori \"%s\" non esiste per il metodo di accesso \"%s\"" -#: commands/indexcmds.c:1363 commands/typecmds.c:1916 +#: commands/indexcmds.c:1805 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "la classe di operatori \"%s\" non accetta il tipo di dati %s" -#: commands/indexcmds.c:1453 +#: commands/indexcmds.c:1895 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "il tipo di dati %s ha più di una classe di operatori predefinita" -#: commands/indexcmds.c:1844 +#: commands/indexcmds.c:2310 #, c-format msgid "table \"%s\" has no indexes" msgstr "la tabella \"%s\" non ha indici" -#: commands/indexcmds.c:1899 +#: commands/indexcmds.c:2365 #, c-format msgid "can only reindex the currently open database" msgstr "è possibile reindicizzare solo il database corrente" -#: commands/indexcmds.c:1999 +#: commands/indexcmds.c:2483 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "la tabella \"%s.%s\" è stata reindicizzata" -#: commands/matview.c:181 +#: commands/indexcmds.c:2505 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX non ancora implementato per tabelle partizionate" + +#: commands/lockcmds.c:100 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "\"%s\" non è una tabella o una vista" + +#: commands/lockcmds.c:224 rewrite/rewriteHandler.c:1836 +#: rewrite/rewriteHandler.c:3532 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "ricorsione infinita individuata nelle regole per la relazione \"%s\"" + +#: commands/matview.c:179 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" msgstr "non si può usare CONCURRENTLY quando la vista materializzata non è popolata" -#: commands/matview.c:187 +#: commands/matview.c:185 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "le opzioni CONCURRENTLY e WITH NO DATA non possono essere usate insieme" -#: commands/matview.c:257 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "non è possibile aggiornare la vista materializzata \"%s\" concorrentemente" -#: commands/matview.c:260 +#: commands/matview.c:247 #, c-format msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." msgstr "Crea un indice unico senza clausola WHERE su una o più colonna della vista materializzata." -#: commands/matview.c:678 +#: commands/matview.c:645 #, c-format msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" msgstr "i nuovi dati per la vista materializzata \"%s\" contengono righe duplicate senza alcuna colonna null" -#: commands/matview.c:680 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "Riga: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "la famiglia di operatori \"%s\" non esiste per il metodo di accesso \"%s\"" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "la famiglia di operatori \"%s\" per il metodo di accesso \"%s\" esiste già " -#: commands/opclasscmds.c:402 +#: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" msgstr "devi essere un superutente per creare una classe di operatori" -#: commands/opclasscmds.c:475 commands/opclasscmds.c:849 -#: commands/opclasscmds.c:973 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 +#: commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "numero di operatore %d non valido, deve essere tra 1 e %d" -#: commands/opclasscmds.c:519 commands/opclasscmds.c:893 -#: commands/opclasscmds.c:988 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 +#: commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "numero di procedura %d non valido, deve essere tra 1 e %d" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "numero di funzione %d non valido, deve essere tra 1 e %d" -#: commands/opclasscmds.c:548 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "tipo di immagazzinamento specificato più di una volta" -#: commands/opclasscmds.c:575 +#: commands/opclasscmds.c:576 #, c-format msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "il tipo di immagazzinamento non deve essere diverso dal tipo di dato per il metodo di accesso \"%s\"" -#: commands/opclasscmds.c:591 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "la classe di operatori \"%s\" per il metodo di accesso \"%s\" esiste già" -#: commands/opclasscmds.c:619 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "non è stato possibile rendere la classe di operatori \"%s\" predefinita per il tipo %s" -#: commands/opclasscmds.c:622 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "La classe di operatori \"%s\" è già predefinita." -#: commands/opclasscmds.c:747 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" msgstr "solo un superutente può creare una famiglia di operatori" -#: commands/opclasscmds.c:803 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" msgstr "solo un superutente può modificare una famiglia di operatori" -#: commands/opclasscmds.c:858 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "i tipi degli argomenti dell'operatore devono essere specificati in ALTER OPERATOR FAMILY" -#: commands/opclasscmds.c:921 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "STORAGE non può essere specificato in ALTER OPERATOR FAMILY" -#: commands/opclasscmds.c:1043 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" msgstr "devono essere specificati uno due argomenti" -#: commands/opclasscmds.c:1069 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "gli operatori dell'indice devono essere binari" -#: commands/opclasscmds.c:1088 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "il metodo di accesso \"%s\" non supporta operatori di ordinamento" -#: commands/opclasscmds.c:1099 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" msgstr "gli operatori di ricerca degli indici devono restituire un booleano" -#: commands/opclasscmds.c:1141 +#: commands/opclasscmds.c:1144 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "le funzioni di comparazioni btree devono avere due argomenti" + +#: commands/opclasscmds.c:1148 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "le funzioni di comparazioni btree devono restituire un intero" + +#: commands/opclasscmds.c:1165 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "le funzioni di supporto btree devono accettare il tipo \"internal\"" + +#: commands/opclasscmds.c:1169 +#, c-format +msgid "btree sort support functions must return void" +msgstr "le funzioni di supporto btree devono restituire void" + +#: commands/opclasscmds.c:1180 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "le procedure di comparazione btree devono avere due argomenti" +msgid "btree in_range functions must have five arguments" +msgstr "le funzioni in_range btree devono avere cinque argomenti" -#: commands/opclasscmds.c:1145 +#: commands/opclasscmds.c:1184 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "le procedure di comparazione btree devono restituire un intero" +msgid "btree in_range functions must return boolean" +msgstr "le funzioni in_range btree devono restituire un booleano" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1203 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "le procedure di supporto all'ordinamento btree devono accettare il tipo \"internal\"" +msgid "hash function 1 must have one argument" +msgstr "la funzione di hash 1 deve avere un solo argomento" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1207 #, c-format -msgid "btree sort support procedures must return void" -msgstr "le procedure di supporto all'ordinamento btree devono restituire \"void\"" +msgid "hash function 1 must return integer" +msgstr "la funzione di hash 1 deve restituire un intero" -#: commands/opclasscmds.c:1178 +#: commands/opclasscmds.c:1214 #, c-format -msgid "hash procedures must have one argument" -msgstr "la procedura di hash deve avere un argomento." +msgid "hash function 2 must have two arguments" +msgstr "la funzione di hash 2 deve avere due argomenti" -#: commands/opclasscmds.c:1182 +#: commands/opclasscmds.c:1218 #, c-format -msgid "hash procedures must return integer" -msgstr "la procedura di hash deve restituire un intero" +msgid "hash function 2 must return bigint" +msgstr "la funzione di hash 2 deve restituire un btree" -#: commands/opclasscmds.c:1206 +#: commands/opclasscmds.c:1243 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "i tipi di dati associati devono essere specificati per la procedura di supporto dell'indice" +msgid "associated data types must be specified for index support function" +msgstr "occorre specificare tipi di dati associati per le funzioni di supporto dell'indice" -#: commands/opclasscmds.c:1231 +#: commands/opclasscmds.c:1268 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "la procedura numero %d per (%s,%s) compare più di una volta" +msgid "function number %d for (%s,%s) appears more than once" +msgstr "la funzione numero %d per (%s,%s) compare più di una volta" -#: commands/opclasscmds.c:1238 +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "l'operatore numero %d per (%s,%s) compare più di una volta" -#: commands/opclasscmds.c:1287 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "l'operatore %d(%s,%s) esiste già nella famiglia di operatori \"%s\"" -#: commands/opclasscmds.c:1401 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "la funzione %d(%s,%s) esiste già nella famiglia di operatori \"%s\"" -#: commands/opclasscmds.c:1489 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "l'operatore %d(%s,%s) non esiste nella famiglia di operatori \"%s\"" -#: commands/opclasscmds.c:1529 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "la funzione %d(%s,%s) non esiste nella famiglia di operatori \"%s\"" -#: commands/opclasscmds.c:1659 +#: commands/opclasscmds.c:1696 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "la classe di operatori \"%s\" per il metodo di accesso \"%s\" esiste già nello schema \"%s\"" -#: commands/opclasscmds.c:1682 +#: commands/opclasscmds.c:1719 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "la famiglia di operatori \"%s\" per il metodo di accesso \"%s\" esiste già nello schema \"%s\"" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "il tipo SETOF non è permesso come argomento dell'operatore." -#: commands/operatorcmds.c:152 commands/operatorcmds.c:454 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "attributo dell'operatore \"%s\" non riconosciuto" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "la procedura dell'operatore deve essere specificata" +msgid "operator function must be specified" +msgstr "la funzione dell'operatore deve essere specificata" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "almeno uno tra leftarg e rightarg deve essere specificato" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "la funzione di stima di restrizione %s deve restituire il tipo %s" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "la funzione di stima del join %s deve restituire il tipo %s" -#: commands/operatorcmds.c:448 +#: commands/operatorcmds.c:451 #, c-format msgid "operator attribute \"%s\" cannot be changed" msgstr "l'attributo dell'operatore \"%s\" non può essere cambiato" -#: commands/policy.c:87 commands/policy.c:397 commands/policy.c:486 -#: commands/tablecmds.c:1131 commands/tablecmds.c:1501 -#: commands/tablecmds.c:2494 commands/tablecmds.c:4695 -#: commands/tablecmds.c:7031 commands/tablecmds.c:12979 -#: commands/tablecmds.c:13014 commands/trigger.c:251 commands/trigger.c:1261 -#: commands/trigger.c:1370 rewrite/rewriteDefine.c:272 -#: rewrite/rewriteDefine.c:919 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 +#: commands/tablecmds.c:1275 commands/tablecmds.c:1732 +#: commands/tablecmds.c:2718 commands/tablecmds.c:4951 +#: commands/tablecmds.c:7358 commands/tablecmds.c:13418 +#: commands/tablecmds.c:13453 commands/trigger.c:316 commands/trigger.c:1526 +#: commands/trigger.c:1635 rewrite/rewriteDefine.c:272 +#: rewrite/rewriteDefine.c:924 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "permesso negato: \"%s\" è un catalogo di sistema" @@ -7715,32 +7845,32 @@ msgstr "i ruoli specificati a parte PUBLIC verranno ignorati" msgid "All roles are members of the PUBLIC role." msgstr "TuttiTutti i ruoli sono membri del ruolo PUBLIC." -#: commands/policy.c:510 +#: commands/policy.c:514 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "non è stato possibile rimuovere il ruolo \"%s\" dalla regola di sicurezza \"%s\" su \"%s\"" -#: commands/policy.c:716 +#: commands/policy.c:720 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK non può essere applicato a SELECT o a DELETE" -#: commands/policy.c:725 commands/policy.c:1023 +#: commands/policy.c:729 commands/policy.c:1027 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "solo le espressioni WITH CHECK sono consentite per INSERT" -#: commands/policy.c:798 commands/policy.c:1243 +#: commands/policy.c:802 commands/policy.c:1247 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "la regola di sicurezza \"%s\" per la tabella \"%s\" esiste già" -#: commands/policy.c:995 commands/policy.c:1271 commands/policy.c:1343 +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "la regola di sicurezza \"%s\" per la tabella \"%s\" non esiste" -#: commands/policy.c:1013 +#: commands/policy.c:1017 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "solo le espressioni USING sono permesse per SELECT e DELETE" @@ -7751,7 +7881,7 @@ msgid "invalid cursor name: must not be empty" msgstr "nome di cursore non valido: non deve essere vuoto" #: commands/portalcmds.c:190 commands/portalcmds.c:244 -#: executor/execCurrent.c:67 utils/adt/xml.c:2469 utils/adt/xml.c:2639 +#: executor/execCurrent.c:69 utils/adt/xml.c:2469 utils/adt/xml.c:2639 #, c-format msgid "cursor \"%s\" does not exist" msgstr "il cursore \"%s\" non esiste" @@ -7761,7 +7891,7 @@ msgstr "il cursore \"%s\" non esiste" msgid "invalid statement name: must not be empty" msgstr "nome di istruzione non valido: non deve essere vuoto" -#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1355 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1376 #, c-format msgid "could not determine data type of parameter $%d" msgstr "non è stato possibile determinare il tipo di dato del parametro $%d" @@ -7791,88 +7921,88 @@ msgstr "Erano attesi %d parametri ma ottenuti %d." msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "il parametro $%d di tipo %s non può essere forzato al tipo previsto %s" -#: commands/prepare.c:474 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "l'istruzione preparata \"%s\" esiste già" -#: commands/prepare.c:513 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "l'istruzione preparata \"%s\" non esiste" -#: commands/proclang.c:87 +#: commands/proclang.c:86 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "vengono usate le informazioni di pg_pltemplate invece dei parametri di CREATE LANGUAGE" -#: commands/proclang.c:97 +#: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "solo i superutenti possono creare il linguaggio procedurale \"%s\"" -#: commands/proclang.c:252 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "linguaggio non supportato \"%s\"" -#: commands/proclang.c:254 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "I linguaggi supportati sono elencate nel catalogo di sistema pg_pltemplate" -#: commands/proclang.c:262 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" msgstr "solo i superutenti possono creare un linguaggio procedurale personalizzato" -#: commands/proclang.c:281 commands/trigger.c:549 commands/typecmds.c:457 -#: commands/typecmds.c:474 +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 +#: commands/typecmds.c:471 #, c-format msgid "changing return type of function %s from %s to %s" msgstr "modifica del tipo restituito dalla funzione %s da %s a %s" -#: commands/publicationcmds.c:106 +#: commands/publicationcmds.c:109 #, c-format -msgid "invalid publish list" -msgstr "lista di pubblicazione non valida" +msgid "invalid list syntax for \"publish\" option" +msgstr "sintassi di lista errata per l'opzione \"publish\"" -#: commands/publicationcmds.c:122 +#: commands/publicationcmds.c:127 #, c-format msgid "unrecognized \"publish\" value: \"%s\"" msgstr "valore \"publish\" non valido: \"%s\"" -#: commands/publicationcmds.c:128 +#: commands/publicationcmds.c:133 #, c-format msgid "unrecognized publication parameter: %s" msgstr "parametro di pubblicazione non valido: %s" -#: commands/publicationcmds.c:160 +#: commands/publicationcmds.c:166 #, c-format msgid "must be superuser to create FOR ALL TABLES publication" msgstr "solo un superutente può creare una pubblicazione FOR ALL TABLES" -#: commands/publicationcmds.c:321 +#: commands/publicationcmds.c:335 #, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES" msgstr "la pubblicazione \"%s\" è definita come FOR ALL TABLES" -#: commands/publicationcmds.c:323 +#: commands/publicationcmds.c:337 #, c-format msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." msgstr "Non è possibile aggiungere o rimuovere tabelle da pubblicazioni FOR ALL TABLES." -#: commands/publicationcmds.c:624 +#: commands/publicationcmds.c:638 #, c-format msgid "relation \"%s\" is not part of the publication" msgstr "la relazione \"%s\" non è parte di una pubblicazione" -#: commands/publicationcmds.c:667 +#: commands/publicationcmds.c:681 #, c-format msgid "permission denied to change owner of publication \"%s\"" msgstr "permesso negato per cambiare proprietario della pubblicazione \"%s\"" -#: commands/publicationcmds.c:669 +#: commands/publicationcmds.c:683 #, c-format msgid "The owner of a FOR ALL TABLES publication must be a superuser." msgstr "Il proprietario di una pubblicazione FOR ALL TABLES deve essere un superutente." @@ -7912,1871 +8042,2040 @@ msgstr "il fornitore di etichette di sicurezza \"%s\" non è stato caricato" msgid "unlogged sequences are not supported" msgstr "le sequenze non loggate non sono supportate" -#: commands/sequence.c:707 +#: commands/sequence.c:698 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: è stato raggiunto il valore massimo della sequenza \"%s\" (%s)" -#: commands/sequence.c:730 +#: commands/sequence.c:721 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: è stato raggiunto il valore minimo della sequenza \"%s\" (%s)" -#: commands/sequence.c:848 +#: commands/sequence.c:839 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "il valore corrente della sequenza \"%s\" non è stato ancora definito in questa sessione" -#: commands/sequence.c:867 commands/sequence.c:873 +#: commands/sequence.c:858 commands/sequence.c:864 #, c-format msgid "lastval is not yet defined in this session" msgstr "lastval non è stato ancora definito in questa sessione" -#: commands/sequence.c:961 +#: commands/sequence.c:952 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: il valore %s non rientra nei margini della sequenza \"%s\" (%s..%s)" -#: commands/sequence.c:1373 +#: commands/sequence.c:1349 #, c-format msgid "invalid sequence option SEQUENCE NAME" msgstr "opzione di sequenza SEQUENCE NAME non valido" -#: commands/sequence.c:1401 +#: commands/sequence.c:1375 #, c-format msgid "identity column type must be smallint, integer, or bigint" msgstr "il tipo della colonna identità deve essere smallint, integer o bigint" -#: commands/sequence.c:1402 +#: commands/sequence.c:1376 #, c-format msgid "sequence type must be smallint, integer, or bigint" msgstr "il tipo della sequenza deve essere smallint, integer o bigint" -#: commands/sequence.c:1439 +#: commands/sequence.c:1410 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT non può essere zero" -#: commands/sequence.c:1497 +#: commands/sequence.c:1463 #, c-format msgid "MAXVALUE (%s) is out of range for sequence data type %s" msgstr "MAXVALUE (%s) è al di fuori dell'intervallo consentito per il tipo di dati della sequenza %s" -#: commands/sequence.c:1536 +#: commands/sequence.c:1500 #, c-format msgid "MINVALUE (%s) is out of range for sequence data type %s" msgstr "MINVALUE (%s) è al di fuori dell'intervallo consentito per il tipo di dati della sequenza %s" -#: commands/sequence.c:1550 +#: commands/sequence.c:1514 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) deve essere minore del MAXVALUE (%s)" -#: commands/sequence.c:1579 +#: commands/sequence.c:1541 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "il valore di START (%s) non può essere inferiore a quello di MINVALUE (%s)" -#: commands/sequence.c:1591 +#: commands/sequence.c:1553 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "il valore di START (%s) non può essere superiore a quello di MAXVALUE (%s)" -#: commands/sequence.c:1621 +#: commands/sequence.c:1583 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "il valore di RESTART (%s) non può essere inferiore a quello di MINVALUE (%s)" -#: commands/sequence.c:1633 +#: commands/sequence.c:1595 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "il valore di RESTART (%s) non può essere superiore a quello di MAXVALUE (%s)" -#: commands/sequence.c:1649 +#: commands/sequence.c:1610 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE (%s) dev'essere maggiore di zero" -#: commands/sequence.c:1687 +#: commands/sequence.c:1647 #, c-format msgid "invalid OWNED BY option" msgstr "opzione OWNED BY non valida" -#: commands/sequence.c:1688 +#: commands/sequence.c:1648 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "Specifica OWNED BY tabella.colonna oppure OWNED BY NONE." -#: commands/sequence.c:1713 +#: commands/sequence.c:1673 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "la relazione referenziata \"%s\" non è una tabella né una tabella esterna" -#: commands/sequence.c:1720 +#: commands/sequence.c:1680 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "la sequenza deve avere lo stesso proprietario della tabella a cui è collegata" -#: commands/sequence.c:1724 +#: commands/sequence.c:1684 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "la sequenza deve essere nello stesso schema della tabella a cui è collegata" -#: commands/sequence.c:1746 +#: commands/sequence.c:1706 #, c-format msgid "cannot change ownership of identity sequence" msgstr "non è possibile cambiare proprietario di una sequenza identità" -#: commands/sequence.c:1747 commands/tablecmds.c:9866 -#: commands/tablecmds.c:12442 +#: commands/sequence.c:1707 commands/tablecmds.c:10319 +#: commands/tablecmds.c:12881 #, c-format msgid "Sequence \"%s\" is linked to table \"%s\"." msgstr "La sequenza \"%s\" è collegata alla tabella \"%s\"." -#: commands/statscmds.c:93 -#, c-format -msgid "statistics object \"%s\" already exists, skipping" -msgstr "la statistica \"%s\" esiste già, saltata" - -#: commands/statscmds.c:100 -#, c-format -msgid "statistics object \"%s\" already exists" -msgstr "la statistica \"%s\" esiste già" - -#: commands/statscmds.c:112 commands/statscmds.c:121 +#: commands/statscmds.c:93 commands/statscmds.c:102 #, c-format msgid "only a single relation is allowed in CREATE STATISTICS" msgstr "solo una relazione singola è permessa in CREATE STATISTICS" -#: commands/statscmds.c:139 +#: commands/statscmds.c:120 #, c-format msgid "relation \"%s\" is not a table, foreign table, or materialized view" msgstr "la relazione \"%s\" non è una tabella, una tabella esterna o una vista materializzata" -#: commands/statscmds.c:170 commands/statscmds.c:176 +#: commands/statscmds.c:163 #, c-format -msgid "only simple column references are allowed in CREATE STATISTICS" -msgstr "solo riferimenti a colonne semplici sono consentiti in CREATE STATISTICS" +msgid "statistics object \"%s\" already exists, skipping" +msgstr "la statistica \"%s\" esiste già, saltata" + +#: commands/statscmds.c:171 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "la statistica \"%s\" esiste già" -#: commands/statscmds.c:183 +#: commands/statscmds.c:193 commands/statscmds.c:199 #, c-format -msgid "column \"%s\" referenced in statistics does not exist" -msgstr "la colonna \"%s\" nominata nella statistica non esiste" +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "solo riferimenti a colonne semplici sono consentiti in CREATE STATISTICS" -#: commands/statscmds.c:191 +#: commands/statscmds.c:214 #, c-format msgid "statistics creation on system columns is not supported" msgstr "la creazione di statistiche su colonne di sistema non è supportata" -#: commands/statscmds.c:198 +#: commands/statscmds.c:221 #, c-format -msgid "column \"%s\" cannot be used in statistics because its type has no default btree operator class" -msgstr "la colonna \"%s\" non può essere usata in una statistica perché il suo tipo non ha una classe di operatori btree definita" +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "la colonna \"%s\" non può essere usata in una statistica perché il suo tipo %s non ha una classe di operatori btree definita" -#: commands/statscmds.c:205 +#: commands/statscmds.c:228 #, c-format msgid "cannot have more than %d columns in statistics" msgstr "non è possibile avere più di %d colonne in una statistica" -#: commands/statscmds.c:220 +#: commands/statscmds.c:243 #, c-format msgid "extended statistics require at least 2 columns" msgstr "una statistica estesa richiede almeno due colonne" -#: commands/statscmds.c:238 +#: commands/statscmds.c:261 #, c-format msgid "duplicate column name in statistics definition" msgstr "nome di colonna duplicato nella definizione della statistica" -#: commands/statscmds.c:266 +#: commands/statscmds.c:289 #, c-format -msgid "unrecognized statistic type \"%s\"" +msgid "unrecognized statistics kind \"%s\"" msgstr "tipo di statistica \"%s\" sconosciuto" -#: commands/subscriptioncmds.c:173 +#: commands/subscriptioncmds.c:187 #, c-format msgid "unrecognized subscription parameter: %s" msgstr "parametro di sottoscrizione sconosciuto: %s" -#: commands/subscriptioncmds.c:186 +#: commands/subscriptioncmds.c:200 #, c-format msgid "connect = false and enabled = true are mutually exclusive options" msgstr "connect = false ed enabled = true sono opzioni mutuamente esclusive" -#: commands/subscriptioncmds.c:191 +#: commands/subscriptioncmds.c:205 #, c-format msgid "connect = false and create_slot = true are mutually exclusive options" msgstr "connect = false e create_slot = true sono opzioni mutuamente esclusive" -#: commands/subscriptioncmds.c:196 +#: commands/subscriptioncmds.c:210 #, c-format msgid "connect = false and copy_data = true are mutually exclusive options" msgstr "connect = false e copy_data = true sono opzioni mutuamente esclusive" -#: commands/subscriptioncmds.c:213 +#: commands/subscriptioncmds.c:227 #, c-format msgid "slot_name = NONE and enabled = true are mutually exclusive options" msgstr "slot_name = NONE ed enabled = true sono opzioni mutuamente esclusive" -#: commands/subscriptioncmds.c:218 +#: commands/subscriptioncmds.c:232 #, c-format msgid "slot_name = NONE and create_slot = true are mutually exclusive options" msgstr "slot_name = NONE e create_slot = true sono opzioni mutuamente esclusive" -#: commands/subscriptioncmds.c:223 +#: commands/subscriptioncmds.c:237 #, c-format msgid "subscription with slot_name = NONE must also set enabled = false" msgstr "una sottoscrizione con slot_name = NONE deve avere anche enabled = false" -#: commands/subscriptioncmds.c:228 +#: commands/subscriptioncmds.c:242 #, c-format msgid "subscription with slot_name = NONE must also set create_slot = false" msgstr "una sottoscrizione con slot_name = NONE deve avere anche create_slot = false" -#: commands/subscriptioncmds.c:270 +#: commands/subscriptioncmds.c:283 #, c-format msgid "publication name \"%s\" used more than once" msgstr "nome di pubblicazione \"%s\" usato più di una volta" -#: commands/subscriptioncmds.c:332 +#: commands/subscriptioncmds.c:347 #, c-format msgid "must be superuser to create subscriptions" msgstr "occorre essere un superutente per creare sottoscrizioni" -#: commands/subscriptioncmds.c:412 commands/subscriptioncmds.c:508 -#: replication/logical/tablesync.c:798 replication/logical/worker.c:1579 +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 +#: replication/logical/tablesync.c:856 replication/logical/worker.c:1722 #, c-format msgid "could not connect to the publisher: %s" msgstr "connessione alla pubblicazione fallita: %s" -#: commands/subscriptioncmds.c:443 -#, c-format -msgid "synchronized table states" -msgstr "sincronizzazione degli stati della tabella" - -#: commands/subscriptioncmds.c:457 +#: commands/subscriptioncmds.c:469 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "creazione dello slot di replica \"%s\" sulla pubblicazione" -#: commands/subscriptioncmds.c:474 +#: commands/subscriptioncmds.c:486 #, c-format msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" msgstr "le tabelle non sono state sottoscritte, è necessario eseguire ALTER SUBSCRIPTION ... REFRESH PUBLICATION per sottoscrivere le tabelle" -#: commands/subscriptioncmds.c:564 +#: commands/subscriptioncmds.c:576 #, c-format -msgid "added subscription for table %s.%s" -msgstr "aggiunta sottoscrizione per la tabella %s.%s" +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "tabella \"%s.%s\" aggiunta alla sottoscrizione \"%s\"" -#: commands/subscriptioncmds.c:590 +#: commands/subscriptioncmds.c:600 #, c-format -msgid "removed subscription for table %s.%s" -msgstr "rimossa sottoscrizione per la tabella %s.%s" +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "tabella \"%s.%s\" rimossa dalla sottoscrizione \"%s\"" -#: commands/subscriptioncmds.c:655 +#: commands/subscriptioncmds.c:669 #, c-format msgid "cannot set slot_name = NONE for enabled subscription" msgstr "non è possibile impostare slot_name = NONE per le sottoscrizioni attive" -#: commands/subscriptioncmds.c:689 +#: commands/subscriptioncmds.c:703 #, c-format msgid "cannot enable subscription that does not have a slot name" msgstr "non è possibile abilitare una sottoscrizione che non ha un nome di slot" -#: commands/subscriptioncmds.c:735 commands/subscriptioncmds.c:753 +#: commands/subscriptioncmds.c:749 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION con refresh non consentito per sottoscrizioni disabilitate" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "Usa ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:768 #, c-format msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" msgstr "ALTER SUBSCRIPTION ... REFRESH non è consentito per sottoscrizioni disabilitate" -#: commands/subscriptioncmds.c:830 +#: commands/subscriptioncmds.c:847 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "la sottoscrizione \"%s\" non esiste, saltata" -#: commands/subscriptioncmds.c:931 +#: commands/subscriptioncmds.c:972 #, c-format msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" msgstr "non è possibile connettersi alla pubblicazione mentre si sta eliminando lo slot di replica \"%s\"" -#: commands/subscriptioncmds.c:933 commands/subscriptioncmds.c:947 -#: replication/logical/tablesync.c:847 replication/logical/tablesync.c:867 +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 +#: replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 #, c-format msgid "The error was: %s" msgstr "L'errore è stato: %s" -#: commands/subscriptioncmds.c:934 +#: commands/subscriptioncmds.c:975 #, c-format msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." msgstr "Usa ALTER SUBSCRIPTION ... SET (slot_name = NONE) per disassociare la sottoscrizione dallo slot." -#: commands/subscriptioncmds.c:945 +#: commands/subscriptioncmds.c:986 #, c-format msgid "could not drop the replication slot \"%s\" on publisher" msgstr "eliminazione dello slot di replica \"%s\" sulla pubblicazione fallita" -#: commands/subscriptioncmds.c:950 +#: commands/subscriptioncmds.c:991 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "eliminazione dello slot di replica \"%s\" sulla pubblicazione" -#: commands/subscriptioncmds.c:991 +#: commands/subscriptioncmds.c:1032 #, c-format msgid "permission denied to change owner of subscription \"%s\"" msgstr "permesso negato nel cambiare il proprietario della sottoscrizione \"%s\"" -#: commands/subscriptioncmds.c:993 +#: commands/subscriptioncmds.c:1034 #, c-format msgid "The owner of a subscription must be a superuser." msgstr "Il proprietario della sottoscrizione deve essere un superutente." -#: commands/subscriptioncmds.c:1106 +#: commands/subscriptioncmds.c:1147 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "errore nell'ottenere la lista delle tabelle replicate dalla pubblicazione: %s" -#: commands/tablecmds.c:221 commands/tablecmds.c:263 +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist" msgstr "la tabella \"%s\" non esiste" -#: commands/tablecmds.c:222 commands/tablecmds.c:264 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 #, c-format msgid "table \"%s\" does not exist, skipping" msgstr "la tabella \"%s\" non esiste, saltata" -#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#: commands/tablecmds.c:226 commands/tablecmds.c:268 msgid "Use DROP TABLE to remove a table." msgstr "Usa DROP TABLE per eliminare una tabella." -#: commands/tablecmds.c:227 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist" msgstr "la sequenza \"%s\" non esiste" -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:230 #, c-format msgid "sequence \"%s\" does not exist, skipping" msgstr "la sequenza \"%s\" non esiste, saltata" -#: commands/tablecmds.c:230 +#: commands/tablecmds.c:232 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "Usa DROP SEQUENCE per eliminare una sequenza." -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist" msgstr "la vista \"%s\" non esiste" -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:236 #, c-format msgid "view \"%s\" does not exist, skipping" msgstr "la vista \"%s\" non esiste, saltata" -#: commands/tablecmds.c:236 +#: commands/tablecmds.c:238 msgid "Use DROP VIEW to remove a view." msgstr "Usa DROP VIEW per eliminare una vista." -#: commands/tablecmds.c:239 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "la vista materializzata \"%s\" non esiste" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:242 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "la vista materializzata \"%s\" non esiste, saltata" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "Usa DROP MATERIALIZED VIEW per rimuovere una vista materializzata." -#: commands/tablecmds.c:245 parser/parse_utilcmd.c:1819 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:14793 +#: parser/parse_utilcmd.c:1984 #, c-format msgid "index \"%s\" does not exist" msgstr "l'indice \"%s\" non esiste" -#: commands/tablecmds.c:246 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "l'indice \"%s\" non esiste, saltato" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "Usa DROP INDEX per eliminare un indice." -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" msgstr "\"%s\" non è un tipo" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "Usa DROP TYPE per eliminare un tipo." -#: commands/tablecmds.c:257 commands/tablecmds.c:9382 -#: commands/tablecmds.c:12222 +#: commands/tablecmds.c:259 commands/tablecmds.c:9763 +#: commands/tablecmds.c:12661 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "la tabella esterna \"%s\" non esiste" -#: commands/tablecmds.c:258 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "la tabella esterna \"%s\" non esiste, saltata" -#: commands/tablecmds.c:260 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Usa DROP FOREIGN TABLE per eliminare una tabella esterna." -#: commands/tablecmds.c:524 +#: commands/tablecmds.c:554 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT può essere usato solo con le tabelle temporanee" -#: commands/tablecmds.c:552 +#: commands/tablecmds.c:582 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "non è possibile creare la tabella temporanea nell'ambito di operazioni a sicurezza ristretta" -#: commands/tablecmds.c:653 +#: commands/tablecmds.c:683 #, c-format msgid "cannot create table with OIDs as partition of table without OIDs" msgstr "non è possibile creare una tabella con OID come partizione di una tabella senza OID" -#: commands/tablecmds.c:774 parser/parse_utilcmd.c:3270 +#: commands/tablecmds.c:807 #, c-format msgid "\"%s\" is not partitioned" msgstr "\"%s\" non è partizionata" -#: commands/tablecmds.c:953 +#: commands/tablecmds.c:888 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "non è possibile partizionare usando più di %d colonne" + +#: commands/tablecmds.c:1095 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY non supporta l'eliminazione di più di un oggetto" -#: commands/tablecmds.c:957 +#: commands/tablecmds.c:1099 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY non supporta CASCADE" -#: commands/tablecmds.c:1234 +#: commands/tablecmds.c:1381 #, c-format msgid "cannot truncate only a partitioned table" msgstr "non è possibile troncare solo una tabella partizionata" -#: commands/tablecmds.c:1235 +#: commands/tablecmds.c:1382 #, c-format -msgid "Do not specify the ONLY keyword, or use truncate only on the partitions directly." +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." msgstr "Non specificare la parola chiave ONLY, oppure usa TRUNCATE ONLY sulle partizioni direttamente." -#: commands/tablecmds.c:1263 +#: commands/tablecmds.c:1451 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "truncate si propaga in cascata alla tabella \"%s\"" -#: commands/tablecmds.c:1511 +#: commands/tablecmds.c:1742 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "non è possibile troncare tabelle temporanee di altre sessioni" -#: commands/tablecmds.c:1742 commands/tablecmds.c:10966 +#: commands/tablecmds.c:1973 commands/tablecmds.c:11412 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "non è possibile ereditare dalla tabella partizionata \"%s\"" -#: commands/tablecmds.c:1747 +#: commands/tablecmds.c:1978 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "non è possibile ereditare dalla partizione \"%s\"" -#: commands/tablecmds.c:1755 parser/parse_utilcmd.c:2030 +#: commands/tablecmds.c:1986 parser/parse_utilcmd.c:2201 +#: parser/parse_utilcmd.c:2324 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "la relazione ereditata \"%s\" non è una tabella o tabella esterna" -#: commands/tablecmds.c:1763 commands/tablecmds.c:10945 +#: commands/tablecmds.c:1998 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "non è possibile creare una relazione temporanea come partizione della relazione permanente \"%s\"" + +#: commands/tablecmds.c:2007 commands/tablecmds.c:11391 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "non è possibile ereditare dalla relazione temporanea \"%s\"" -#: commands/tablecmds.c:1773 commands/tablecmds.c:10953 +#: commands/tablecmds.c:2017 commands/tablecmds.c:11399 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "non è possibile ereditare da una relazione temporanea di un'altra sessione" -#: commands/tablecmds.c:1790 commands/tablecmds.c:11064 +#: commands/tablecmds.c:2034 commands/tablecmds.c:11523 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "la relazione \"%s\" sarebbe ereditata più di una volta" -#: commands/tablecmds.c:1838 +#: commands/tablecmds.c:2083 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "unione delle definizioni multiple ereditate della colonna \"%s\"" -#: commands/tablecmds.c:1846 +#: commands/tablecmds.c:2091 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "la colonna ereditata \"%s\" ha un conflitto di tipo" -#: commands/tablecmds.c:1848 commands/tablecmds.c:1871 -#: commands/tablecmds.c:2077 commands/tablecmds.c:2107 -#: parser/parse_coerce.c:1650 parser/parse_coerce.c:1670 -#: parser/parse_coerce.c:1690 parser/parse_coerce.c:1736 -#: parser/parse_coerce.c:1775 parser/parse_param.c:218 +#: commands/tablecmds.c:2093 commands/tablecmds.c:2116 +#: commands/tablecmds.c:2322 commands/tablecmds.c:2352 +#: parser/parse_coerce.c:1716 parser/parse_coerce.c:1736 +#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1802 +#: parser/parse_coerce.c:1841 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "tra %s e %s" -#: commands/tablecmds.c:1857 +#: commands/tablecmds.c:2102 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "la colonna ereditata \"%s\" ha un conflitto di ordinamento" -#: commands/tablecmds.c:1859 commands/tablecmds.c:2089 -#: commands/tablecmds.c:5140 +#: commands/tablecmds.c:2104 commands/tablecmds.c:2334 +#: commands/tablecmds.c:5411 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "tra \"%s\" e \"%s\"" -#: commands/tablecmds.c:1869 +#: commands/tablecmds.c:2114 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "la colonna ereditata \"%s\" ha un conflitto di parametro di memorizzazione" -#: commands/tablecmds.c:1983 commands/tablecmds.c:8872 -#: parser/parse_utilcmd.c:1113 parser/parse_utilcmd.c:1464 -#: parser/parse_utilcmd.c:1540 +#: commands/tablecmds.c:2228 commands/tablecmds.c:9271 +#: parser/parse_utilcmd.c:1117 parser/parse_utilcmd.c:1517 +#: parser/parse_utilcmd.c:1624 #, c-format msgid "cannot convert whole-row table reference" msgstr "non è possibile convertire riferimenti ad una riga intera di tabella" -#: commands/tablecmds.c:1984 parser/parse_utilcmd.c:1114 +#: commands/tablecmds.c:2229 parser/parse_utilcmd.c:1118 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "Il vincolo \"%s\" contiene un riferimento alla riga intera alla tabella \"%s\"." -#: commands/tablecmds.c:2063 +#: commands/tablecmds.c:2308 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "unione della colonna \"%s\" con la definizione ereditata" -#: commands/tablecmds.c:2067 +#: commands/tablecmds.c:2312 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "spostamento e unione della colonna \"%s\" con la definizione ereditata" -#: commands/tablecmds.c:2068 +#: commands/tablecmds.c:2313 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "Colonna specificata dall'utente spostata nella posizione della colonna ereditata." -#: commands/tablecmds.c:2075 +#: commands/tablecmds.c:2320 #, c-format msgid "column \"%s\" has a type conflict" msgstr "la colonna \"%s\" ha un conflitto di tipi" -#: commands/tablecmds.c:2087 +#: commands/tablecmds.c:2332 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "la colonna \"%s\" ha un conflitto di ordinamento" -#: commands/tablecmds.c:2105 +#: commands/tablecmds.c:2350 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "la colonna \"%s\" ha un conflitto di parametri di memorizzazione" -#: commands/tablecmds.c:2216 +#: commands/tablecmds.c:2461 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "la colonna \"%s\" eredita valori predefiniti in conflitto tra loro" -#: commands/tablecmds.c:2218 +#: commands/tablecmds.c:2463 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Per risolvere il conflitto, specificare esplicitamente un valore predefinito." -#: commands/tablecmds.c:2265 +#: commands/tablecmds.c:2510 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "il nome del vincolo di controllo \"%s\" compare più di una volta ma con espressioni diverse" -#: commands/tablecmds.c:2464 +#: commands/tablecmds.c:2687 #, c-format msgid "cannot rename column of typed table" msgstr "non è possibile rinominare la colonna di una tabella con tipo" -#: commands/tablecmds.c:2482 +#: commands/tablecmds.c:2706 #, c-format msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" msgstr "\"%s\" non è una tabella, vista, vista materializzata, tipo composito, indice né una tabella esterna" -#: commands/tablecmds.c:2576 +#: commands/tablecmds.c:2800 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "la colonna ereditata \"%s\" dev'essere rinominata anche nelle tabelle figlie" -#: commands/tablecmds.c:2608 +#: commands/tablecmds.c:2832 #, c-format msgid "cannot rename system column \"%s\"" msgstr "non è possibile rinominare la colonna di sistema \"%s\"" -#: commands/tablecmds.c:2623 +#: commands/tablecmds.c:2847 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "non è possibile rinominare la colonna ereditata \"%s\"" -#: commands/tablecmds.c:2775 +#: commands/tablecmds.c:2999 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "i vincoli ereditati \"%s\" devono essere rinominati anche nelle tabelle figlie" -#: commands/tablecmds.c:2782 +#: commands/tablecmds.c:3006 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "non è possibile rinominare il vincolo ereditato \"%s\"" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3006 +#: commands/tablecmds.c:3225 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "non è possibile effettuare %s \"%s\" perché è in uso da query attive in questa sessione" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:3015 +#: commands/tablecmds.c:3235 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "non è possibile effettuare %s \"%s\" perché ha eventi trigger in sospeso" -#: commands/tablecmds.c:4138 +#: commands/tablecmds.c:4379 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "non è possibile riscrivere la relazione di sistema \"%s\"" -#: commands/tablecmds.c:4144 +#: commands/tablecmds.c:4385 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "non è possibile riscrivere la tabella \"%s\" usata come tabella di catalogo" -#: commands/tablecmds.c:4154 +#: commands/tablecmds.c:4395 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "non è possibile riscrivere tabelle temporanee di altre sessioni" -#: commands/tablecmds.c:4430 +#: commands/tablecmds.c:4672 #, c-format msgid "rewriting table \"%s\"" msgstr "riscrittura della tabella \"%s\"" -#: commands/tablecmds.c:4434 +#: commands/tablecmds.c:4676 #, c-format msgid "verifying table \"%s\"" msgstr "verifica della tabella \"%s\"" -#: commands/tablecmds.c:4547 +#: commands/tablecmds.c:4792 #, c-format msgid "column \"%s\" contains null values" msgstr "la colonna \"%s\" contiene valori null" -#: commands/tablecmds.c:4562 commands/tablecmds.c:8141 +#: commands/tablecmds.c:4808 commands/tablecmds.c:8505 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "il vincolo di controllo \"%s\" è violato da alcune righe" -#: commands/tablecmds.c:4578 +#: commands/tablecmds.c:4826 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "il nuovo vincolo di partizione per la partizione di default verrebbe violato da alcune righe" + +#: commands/tablecmds.c:4830 #, c-format msgid "partition constraint is violated by some row" msgstr "il vincolo di partizione è violato da qualche riga" -#: commands/tablecmds.c:4716 commands/trigger.c:245 rewrite/rewriteDefine.c:266 -#: rewrite/rewriteDefine.c:914 +#: commands/tablecmds.c:4972 commands/trigger.c:310 rewrite/rewriteDefine.c:266 +#: rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" msgstr "\"%s\" non è una tabella né una vista" -#: commands/tablecmds.c:4719 commands/trigger.c:1255 commands/trigger.c:1361 +#: commands/tablecmds.c:4975 commands/trigger.c:1520 commands/trigger.c:1626 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "\"%s\" non è una tabella, una vista né una tabella esterna" -#: commands/tablecmds.c:4722 +#: commands/tablecmds.c:4978 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "\"%s\" non è una tabella, una vista, una vista materializzata né un indice" -#: commands/tablecmds.c:4728 +#: commands/tablecmds.c:4984 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "\"%s\" non è una tabella, una vista materializzata né un indice" -#: commands/tablecmds.c:4731 +#: commands/tablecmds.c:4987 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "\"%s\" non è una tabella, una vista materializzata né una tabella esterna" -#: commands/tablecmds.c:4734 +#: commands/tablecmds.c:4990 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "\"%s\" non è una tabella né una tabella esterna" -#: commands/tablecmds.c:4737 +#: commands/tablecmds.c:4993 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "\"%s\" non è una tabella, un tipo composito né una tabella esterna" -#: commands/tablecmds.c:4740 commands/tablecmds.c:6103 +#: commands/tablecmds.c:4996 commands/tablecmds.c:6414 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "\"%s\" non è una tabella, una vista materializzata, un indice né una tabella esterna" -#: commands/tablecmds.c:4750 +#: commands/tablecmds.c:5006 #, c-format msgid "\"%s\" is of the wrong type" msgstr "\"%s\" è del tipo sbagliato" -#: commands/tablecmds.c:4904 commands/tablecmds.c:4911 +#: commands/tablecmds.c:5181 commands/tablecmds.c:5188 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "non è possibile modificare il tipo \"%s\" perché la colonna \"%s.%s\" lo usa" -#: commands/tablecmds.c:4918 +#: commands/tablecmds.c:5195 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "non è possibile modificare la tabella esterna \"%s\" perché la colonna \"%s.%s\" usa il suo tipo di riga" -#: commands/tablecmds.c:4925 +#: commands/tablecmds.c:5202 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "non è possibile modificare la tabella \"%s\" perché la colonna \"%s.%s\" usa il suo tipo di riga" -#: commands/tablecmds.c:4987 +#: commands/tablecmds.c:5256 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "non è possibile modificare il tipo \"%s\" perché è il tipo di una tabella con tipo" -#: commands/tablecmds.c:4989 +#: commands/tablecmds.c:5258 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "Usa DROP ... CASCADE per eliminare anche le tabelle con tipo." -#: commands/tablecmds.c:5033 +#: commands/tablecmds.c:5304 #, c-format msgid "type %s is not a composite type" msgstr "il tipo %s non è un tipo composito" -#: commands/tablecmds.c:5059 +#: commands/tablecmds.c:5330 #, c-format msgid "cannot add column to typed table" msgstr "non è possibile aggiungere una colonna ad una tabella con tipo" -#: commands/tablecmds.c:5103 +#: commands/tablecmds.c:5374 #, c-format msgid "cannot add column to a partition" msgstr "non è possibile aggiungere una colonna ad una partizione" -#: commands/tablecmds.c:5132 commands/tablecmds.c:11190 +#: commands/tablecmds.c:5403 commands/tablecmds.c:11650 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "la tabella figlia \"%s\" ha tipo diverso per la colonna \"%s\"" -#: commands/tablecmds.c:5138 commands/tablecmds.c:11197 +#: commands/tablecmds.c:5409 commands/tablecmds.c:11657 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "la tabella figlia \"%s\" ha ordinamento diverso per la colonna \"%s\"" -#: commands/tablecmds.c:5148 +#: commands/tablecmds.c:5419 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" msgstr "la tabella figlia \"%s\" ha la colonna \"%s\" in conflitto" -#: commands/tablecmds.c:5159 +#: commands/tablecmds.c:5430 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "unione delle definizioni della colonna \"%s\" per la tabella figlia \"%s\"" -#: commands/tablecmds.c:5183 +#: commands/tablecmds.c:5454 #, c-format msgid "cannot recursively add identity column to table that has child tables" msgstr "non è possibile aggiungere ricorsivamente una colonna identità ad una tabella che ha tabelle figlie" -#: commands/tablecmds.c:5395 +#: commands/tablecmds.c:5703 #, c-format msgid "column must be added to child tables too" msgstr "la colonna deve essere aggiunta anche alle tabelle figlie" -#: commands/tablecmds.c:5470 +#: commands/tablecmds.c:5778 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "la colonna \"%s\" della relazione \"%s\" esiste già, saltata" -#: commands/tablecmds.c:5477 +#: commands/tablecmds.c:5785 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "la colonna \"%s\" della relazione \"%s\" esiste già" -#: commands/tablecmds.c:5575 commands/tablecmds.c:8554 +#: commands/tablecmds.c:5883 commands/tablecmds.c:8951 #, c-format msgid "cannot remove constraint from only the partitioned table when partitions exist" msgstr "non è possibile rimuovere un vincolo solo da una tabella partizionata se ci sono partizioni esistenti" -#: commands/tablecmds.c:5576 commands/tablecmds.c:5723 -#: commands/tablecmds.c:6520 commands/tablecmds.c:8555 +#: commands/tablecmds.c:5884 commands/tablecmds.c:6028 +#: commands/tablecmds.c:6812 commands/tablecmds.c:8952 #, c-format msgid "Do not specify the ONLY keyword." msgstr "Non specificare la parola chiave ONLY." -#: commands/tablecmds.c:5608 commands/tablecmds.c:5755 -#: commands/tablecmds.c:5810 commands/tablecmds.c:5885 -#: commands/tablecmds.c:5979 commands/tablecmds.c:6038 -#: commands/tablecmds.c:6162 commands/tablecmds.c:6216 -#: commands/tablecmds.c:6308 commands/tablecmds.c:8694 -#: commands/tablecmds.c:9405 +#: commands/tablecmds.c:5916 commands/tablecmds.c:6064 +#: commands/tablecmds.c:6119 commands/tablecmds.c:6195 +#: commands/tablecmds.c:6289 commands/tablecmds.c:6348 +#: commands/tablecmds.c:6498 commands/tablecmds.c:6568 +#: commands/tablecmds.c:6660 commands/tablecmds.c:9091 +#: commands/tablecmds.c:9786 #, c-format msgid "cannot alter system column \"%s\"" msgstr "non è possibile modificare la colonna di sistema \"%s\"" -#: commands/tablecmds.c:5614 commands/tablecmds.c:5816 +#: commands/tablecmds.c:5922 commands/tablecmds.c:6125 #, c-format msgid "column \"%s\" of relation \"%s\" is an identity column" msgstr "la colonna \"%s\" della relazione \"%s\" è una colonna identità" -#: commands/tablecmds.c:5650 +#: commands/tablecmds.c:5958 #, c-format msgid "column \"%s\" is in a primary key" msgstr "la colonna \"%s\" è in una chiave primaria" -#: commands/tablecmds.c:5672 +#: commands/tablecmds.c:5980 #, c-format msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "la colonna \"%s\" è specificata NOT NULL nella tabella padre" -#: commands/tablecmds.c:5722 +#: commands/tablecmds.c:6027 #, c-format msgid "cannot add constraint to only the partitioned table when partitions exist" msgstr "non è possibile aggiungere un vincolo solo alla tabella partizionata se esistono partizioni" -#: commands/tablecmds.c:5818 +#: commands/tablecmds.c:6127 #, c-format msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." msgstr "Usa invece ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." -#: commands/tablecmds.c:5896 +#: commands/tablecmds.c:6206 #, c-format msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" msgstr "la colonna \"%s\" della relazione \"%s\" deve essere dichiarata NOT NULL prima che possa essere aggiunta l'identità" -#: commands/tablecmds.c:5902 +#: commands/tablecmds.c:6212 #, c-format msgid "column \"%s\" of relation \"%s\" is already an identity column" msgstr "la colonna \"%s\" della relazione \"%s\" è già una colonna identità" -#: commands/tablecmds.c:5908 +#: commands/tablecmds.c:6218 #, c-format msgid "column \"%s\" of relation \"%s\" already has a default value" msgstr "la colonna \"%s\" della relazione \"%s\" ha già un valore predefinito" -#: commands/tablecmds.c:5985 commands/tablecmds.c:6046 +#: commands/tablecmds.c:6295 commands/tablecmds.c:6356 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column" msgstr "la colonna \"%s\" della relazione \"%s\" non è una colonna identità" -#: commands/tablecmds.c:6051 +#: commands/tablecmds.c:6361 #, c-format msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" msgstr "la colonna \"%s\" della relazione \"%s\" non è una colonna identità, saltata" -#: commands/tablecmds.c:6135 +#: commands/tablecmds.c:6426 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "non è possibile riferirsi a colonne non-indice per numero" + +#: commands/tablecmds.c:6457 #, c-format msgid "statistics target %d is too low" msgstr "il target delle statistiche %d è troppo basso" -#: commands/tablecmds.c:6143 +#: commands/tablecmds.c:6465 #, c-format msgid "lowering statistics target to %d" msgstr "target delle statistiche abbassato a %d" -#: commands/tablecmds.c:6288 +#: commands/tablecmds.c:6488 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "la colonna numero %d della relazione \"%s\" non esiste" + +#: commands/tablecmds.c:6507 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "non è possibile cambiare statistiche sulla colonna inclusa \"%s\" dell'indice \"%s\"" + +#: commands/tablecmds.c:6512 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "non è possibile cambiare statistiche sulla colonna non di espressione \"%s\" dell'indice \"%s\"" + +#: commands/tablecmds.c:6514 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Cambia le statistiche sulla colonna della tabella invece." + +#: commands/tablecmds.c:6640 #, c-format msgid "invalid storage type \"%s\"" msgstr "tipo di immagazzinamento non valido \"%s\"" -#: commands/tablecmds.c:6320 +#: commands/tablecmds.c:6672 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "il tipo di dato della colonna %s può avere solo immagazzinamento PLAIN" -#: commands/tablecmds.c:6355 +#: commands/tablecmds.c:6707 #, c-format msgid "cannot drop column from typed table" msgstr "non è possibile eliminare la colonna da una tabella con tipo" -#: commands/tablecmds.c:6462 +#: commands/tablecmds.c:6752 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "la colonna \"%s\" della relazione \"%s\" non esiste, saltato" -#: commands/tablecmds.c:6475 +#: commands/tablecmds.c:6765 #, c-format msgid "cannot drop system column \"%s\"" msgstr "non è possibile eliminare la colonna di sistema \"%s\"" -#: commands/tablecmds.c:6482 +#: commands/tablecmds.c:6772 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "non è possibile eliminare la colonna ereditata \"%s\"" -#: commands/tablecmds.c:6491 +#: commands/tablecmds.c:6783 #, c-format msgid "cannot drop column named in partition key" msgstr "non è possibile eliminare una colonna nominata come chiave di partizione" -#: commands/tablecmds.c:6495 +#: commands/tablecmds.c:6787 #, c-format msgid "cannot drop column referenced in partition key expression" msgstr "non è possibile eliminare una colonna referenziata in un'espressione di partizione" -#: commands/tablecmds.c:6519 +#: commands/tablecmds.c:6811 #, c-format msgid "cannot drop column from only the partitioned table when partitions exist" msgstr "non è possibile eliminare una colonna solo dalla tabella partizionata se esistono delle partizioni" -#: commands/tablecmds.c:6736 +#: commands/tablecmds.c:7016 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX non è supportato su tabelle partizionate" + +#: commands/tablecmds.c:7041 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX rinominerà l'indice \"%s\" in \"%s\"" -#: commands/tablecmds.c:6948 +#: commands/tablecmds.c:7257 #, c-format msgid "constraint must be added to child tables too" msgstr "il vincolo deve essere aggiunto anche alle tabelle figlie" -#: commands/tablecmds.c:7019 +#: commands/tablecmds.c:7329 #, c-format msgid "cannot reference partitioned table \"%s\"" msgstr "non è possibile referenziare la tabella partizionata \"%s\"" -#: commands/tablecmds.c:7025 +#: commands/tablecmds.c:7337 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "non è possibile usare ONLY per la chiave esterna sulla tabella partizionata \"%s\" riferita alla relazione \"%s\"" + +#: commands/tablecmds.c:7343 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "non è possibile aggiungere la chiave esterna NON VALID sulla tabella partizionata \"%s\" riferita alla relazione \"%s\"" + +#: commands/tablecmds.c:7346 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Questa caratteristica non è ancora supportata sulle tabelle partizionate." + +#: commands/tablecmds.c:7352 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "la relazione referenziata \"%s\" non è una tabella" -#: commands/tablecmds.c:7048 +#: commands/tablecmds.c:7375 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "i vincoli su tabelle permanenti possono referenziare solo tabelle permanenti" -#: commands/tablecmds.c:7055 +#: commands/tablecmds.c:7382 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "i vincoli su tabelle non loggate possono referenziare solo tabelle permanenti o non loggate" -#: commands/tablecmds.c:7061 +#: commands/tablecmds.c:7388 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "i vincoli su tabelle temporanee possono referenziare solo tabelle temporanee" -#: commands/tablecmds.c:7065 +#: commands/tablecmds.c:7392 #, c-format msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "i vincoli su tabelle temporanee devono riferirsi a tabelle temporanee di questa sessione" -#: commands/tablecmds.c:7125 +#: commands/tablecmds.c:7452 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "i numeri di colonne referenzianti e referenziate per la chiave esterna non combaciano" -#: commands/tablecmds.c:7232 +#: commands/tablecmds.c:7559 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "non è possibile implementare il vincolo di chiave esterna \"%s\"" -#: commands/tablecmds.c:7235 +#: commands/tablecmds.c:7562 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "Le colonne chiave \"%s\" e \"%s\" hanno tipi incompatibili: %s e %s." -#: commands/tablecmds.c:7441 commands/tablecmds.c:7607 -#: commands/tablecmds.c:8522 commands/tablecmds.c:8590 +#: commands/tablecmds.c:7805 commands/tablecmds.c:7970 +#: commands/tablecmds.c:8919 commands/tablecmds.c:8983 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "il vincolo \"%s\" della relazione \"%s\" non esiste" -#: commands/tablecmds.c:7447 +#: commands/tablecmds.c:7812 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "il vincolo \"%s\" della relazione \"%s\" non è una chiave esterna" -#: commands/tablecmds.c:7614 +#: commands/tablecmds.c:7978 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "il vincolo \"%s\" della relazione \"%s\" non è una chiave esterna o un vincolo di controllo" -#: commands/tablecmds.c:7684 +#: commands/tablecmds.c:8048 #, c-format msgid "constraint must be validated on child tables too" msgstr "i vincoli devono essere validati anche sulle tabelle figlie" -#: commands/tablecmds.c:7752 +#: commands/tablecmds.c:8116 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "la colonna \"%s\" referenziata dal vincolo di chiave esterna non esiste" -#: commands/tablecmds.c:7757 +#: commands/tablecmds.c:8121 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "non possono esserci più di %d chiavi in una chiave esterna" -#: commands/tablecmds.c:7822 +#: commands/tablecmds.c:8186 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "non è possibile usare una chiave primaria deferita per la tabella referenziata \"%s\"" -#: commands/tablecmds.c:7839 +#: commands/tablecmds.c:8203 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "la tabella referenziata \"%s\" non ha una chiave primaria" -#: commands/tablecmds.c:7904 +#: commands/tablecmds.c:8268 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "la lista di colonne referenziate dalla chiave esterna non deve contenere duplicati" -#: commands/tablecmds.c:7998 +#: commands/tablecmds.c:8362 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "non è possibile usare un vincolo univoco deferito per la tabella referenziata \"%s\"" -#: commands/tablecmds.c:8003 +#: commands/tablecmds.c:8367 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "non c'è alcun vincolo univoco che corrisponda alle chiavi indicate per la tabella referenziata \"%s\"" -#: commands/tablecmds.c:8174 +#: commands/tablecmds.c:8538 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "validazione del vincolo di chiave esterna \"%s\"" -#: commands/tablecmds.c:8476 +#: commands/tablecmds.c:8876 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "non è possibile eliminare il vincolo ereditato \"%s\" della relazione \"%s\"" -#: commands/tablecmds.c:8528 +#: commands/tablecmds.c:8925 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "il vincolo \"%s\" della relazione \"%s\" non esiste, saltato" -#: commands/tablecmds.c:8678 +#: commands/tablecmds.c:9075 #, c-format msgid "cannot alter column type of typed table" msgstr "non è possibile modificare il tipo di colonna di una tabella con tipo" -#: commands/tablecmds.c:8701 +#: commands/tablecmds.c:9098 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "non è possibile modificare la colonna ereditata \"%s\"" -#: commands/tablecmds.c:8710 +#: commands/tablecmds.c:9109 #, c-format msgid "cannot alter type of column named in partition key" msgstr "non è possibile cambiare il tipo di una colonna in una chiave di partizione" -#: commands/tablecmds.c:8714 +#: commands/tablecmds.c:9113 #, c-format msgid "cannot alter type of column referenced in partition key expression" msgstr "non è possibile cambiare il tipo di una colonna referenziata in una espressione di partizione" -#: commands/tablecmds.c:8764 +#: commands/tablecmds.c:9163 #, c-format msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "il risultato della clausola USING per la colonna \"%s\" non può essere convertito automaticamente al tipo %s" -#: commands/tablecmds.c:8767 +#: commands/tablecmds.c:9166 #, c-format msgid "You might need to add an explicit cast." msgstr "Potresti dover aggiungere una conversione esplicita." -#: commands/tablecmds.c:8771 +#: commands/tablecmds.c:9170 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "la colonna \"%s\" non può essere convertita automaticamente al tipo %s" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:8774 +#: commands/tablecmds.c:9173 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Potresti dover specificare \"USING %s::%s\"." -#: commands/tablecmds.c:8873 +#: commands/tablecmds.c:9272 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "L'espressione USING contiene un riferimento alla riga completa della tabella." -#: commands/tablecmds.c:8884 +#: commands/tablecmds.c:9283 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "il tipo della colonna ereditata \"%s\" deve essere cambiato anche nelle tabelle figlie" -#: commands/tablecmds.c:8971 +#: commands/tablecmds.c:9372 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "non è possibile cambiare il tipo della colonna \"%s\" due volte" -#: commands/tablecmds.c:9007 +#: commands/tablecmds.c:9408 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "il valore predefinito della colonna \"%s\" non può essere convertito automaticamente al tipo %s" -#: commands/tablecmds.c:9133 +#: commands/tablecmds.c:9514 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "non è possibile cambiare il tipo di una colonna usata in una vista o una regola" -#: commands/tablecmds.c:9134 commands/tablecmds.c:9153 -#: commands/tablecmds.c:9171 +#: commands/tablecmds.c:9515 commands/tablecmds.c:9534 +#: commands/tablecmds.c:9552 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s dipende dalla colonna \"%s\"" -#: commands/tablecmds.c:9152 +#: commands/tablecmds.c:9533 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "non è possibile cambiare il tipo di una colonna usata nella definizione di un trigger" -#: commands/tablecmds.c:9170 +#: commands/tablecmds.c:9551 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "non è possibile cambiare il tipo di una colonna usata nella definizione di una regola di sicurezza" -#: commands/tablecmds.c:9845 +#: commands/tablecmds.c:10289 commands/tablecmds.c:10301 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "non è possibile cambiare il proprietario dell'indice \"%s\"" -#: commands/tablecmds.c:9847 +#: commands/tablecmds.c:10291 commands/tablecmds.c:10303 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "Cambia il proprietario della tabella dell'indice invece." -#: commands/tablecmds.c:9864 +#: commands/tablecmds.c:10317 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "non è possibile cambiare il proprietario della sequenza \"%s\"" -#: commands/tablecmds.c:9878 commands/tablecmds.c:13089 +#: commands/tablecmds.c:10331 commands/tablecmds.c:13529 #, c-format msgid "Use ALTER TYPE instead." msgstr "È possibile usare ALTER TYPE invece." -#: commands/tablecmds.c:9887 +#: commands/tablecmds.c:10340 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "\"%s\" non è una tabella, una vista, una sequenza né una tabella esterna" -#: commands/tablecmds.c:10228 +#: commands/tablecmds.c:10680 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "non è possibile avere più di un sottocomando SET TABLESPACE" -#: commands/tablecmds.c:10302 +#: commands/tablecmds.c:10755 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "\"%s\" non è una tabella, una vista, una vista materializzata né una tabella TOAST" -#: commands/tablecmds.c:10335 commands/view.c:504 +#: commands/tablecmds.c:10788 commands/view.c:508 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTION è supportato solo su viste aggiornabili automaticamente" -#: commands/tablecmds.c:10477 +#: commands/tablecmds.c:10930 #, c-format msgid "cannot move system relation \"%s\"" msgstr "non è possibile spostare la relazione \"%s\"" -#: commands/tablecmds.c:10493 +#: commands/tablecmds.c:10946 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "non è possibile spostare tabelle temporanee di altre sessioni" -#: commands/tablecmds.c:10629 +#: commands/tablecmds.c:11082 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "solo tabelle, indici e viste materializzate esistono nei tablespace" -#: commands/tablecmds.c:10641 +#: commands/tablecmds.c:11094 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "non è possibile spostare relazioni dentro o fuori il tablespace pg_global" -#: commands/tablecmds.c:10733 +#: commands/tablecmds.c:11187 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "interruzione perché non c'è un lock disponibile sulla relazione \"%s.%s\"" -#: commands/tablecmds.c:10749 +#: commands/tablecmds.c:11203 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "nessuna relazione corrispondente trovata nel tablespace \"%s\"" -#: commands/tablecmds.c:10823 storage/buffer/bufmgr.c:915 +#: commands/tablecmds.c:11270 storage/buffer/bufmgr.c:915 #, c-format msgid "invalid page in block %u of relation %s" msgstr "pagina non valida nel blocco %u della relazione %s" -#: commands/tablecmds.c:10905 +#: commands/tablecmds.c:11350 #, c-format msgid "cannot change inheritance of typed table" msgstr "non è possibile cambiare ereditarietà di tabelle con tipo" -#: commands/tablecmds.c:10910 commands/tablecmds.c:11438 +#: commands/tablecmds.c:11355 commands/tablecmds.c:11898 #, c-format msgid "cannot change inheritance of a partition" msgstr "non è possibile cambiare ereditarietà di una partizione" -#: commands/tablecmds.c:10915 +#: commands/tablecmds.c:11360 #, c-format msgid "cannot change inheritance of partitioned table" msgstr "non è possibile cambiare ereditarietà di una tabella partizionata" -#: commands/tablecmds.c:10960 +#: commands/tablecmds.c:11406 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "non è possibile ereditare tabelle temporanee di un'altra sessione" -#: commands/tablecmds.c:10973 +#: commands/tablecmds.c:11419 #, c-format msgid "cannot inherit from a partition" msgstr "non è possibile ereditare da una partizione" -#: commands/tablecmds.c:10995 commands/tablecmds.c:13441 +#: commands/tablecmds.c:11441 commands/tablecmds.c:14108 #, c-format msgid "circular inheritance not allowed" msgstr "l'ereditarietà circolare non è consentita" -#: commands/tablecmds.c:10996 commands/tablecmds.c:13442 +#: commands/tablecmds.c:11442 commands/tablecmds.c:14109 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\" è già figlia di \"%s\"." -#: commands/tablecmds.c:11004 +#: commands/tablecmds.c:11450 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" msgstr "la tabella \"%s\" senza OID non può ereditare dalla tabella \"%s\" con OID" -#: commands/tablecmds.c:11208 +#: commands/tablecmds.c:11463 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "il trigger \"%s\" impedisce alla tabella \"%s\" di diventare figlia di ereditarietà" + +#: commands/tablecmds.c:11465 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" +msgstr "i trigger ROW con tabelle di transizioni non sono supportati nelle gerarchie ereditarie" + +#: commands/tablecmds.c:11668 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "la colonna \"%s\" nella tabella figlia dev'essere marcata NOT NULL" -#: commands/tablecmds.c:11235 commands/tablecmds.c:11274 +#: commands/tablecmds.c:11695 commands/tablecmds.c:11734 #, c-format msgid "child table is missing column \"%s\"" msgstr "la tabella figlia non ha la colonna \"%s\"" -#: commands/tablecmds.c:11362 +#: commands/tablecmds.c:11822 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "la tabella figlia \"%s\" ha una definizione diversa del vincolo di controllo \"%s\"" -#: commands/tablecmds.c:11370 +#: commands/tablecmds.c:11830 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "il vincolo \"%s\" è in conflitto con un vincolo non ereditato nella tabella figlia \"%s\"" -#: commands/tablecmds.c:11381 +#: commands/tablecmds.c:11841 #, c-format msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" msgstr "il vincolo \"%s\" è in conflitto con un vincolo non valido nella tabella figlia \"%s\"" -#: commands/tablecmds.c:11416 +#: commands/tablecmds.c:11876 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "la tabella figlia non ha il vincolo \"%s\"" -#: commands/tablecmds.c:11532 +#: commands/tablecmds.c:11965 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "la relazione \"%s\" non è una partizione della relazione \"%s\"" -#: commands/tablecmds.c:11538 +#: commands/tablecmds.c:11971 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "la relazione \"%s\" non è genitore della relazione \"%s\"" -#: commands/tablecmds.c:11762 +#: commands/tablecmds.c:12197 #, c-format msgid "typed tables cannot inherit" msgstr "le tabelle con tipo non possono essere ereditate" -#: commands/tablecmds.c:11793 +#: commands/tablecmds.c:12228 #, c-format msgid "table is missing column \"%s\"" msgstr "la tabella non ha la colonna \"%s\"" -#: commands/tablecmds.c:11803 +#: commands/tablecmds.c:12239 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "la tabella ha la colonna \"%s\" laddove il tipo richiede \"%s\"" -#: commands/tablecmds.c:11812 +#: commands/tablecmds.c:12248 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "la tabella \"%s\" ha tipo diverso per la colonna \"%s\"" -#: commands/tablecmds.c:11825 +#: commands/tablecmds.c:12262 #, c-format msgid "table has extra column \"%s\"" msgstr "la tabella ha la colonna \"%s\" in eccesso" -#: commands/tablecmds.c:11876 +#: commands/tablecmds.c:12314 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\" non è una tabella con tipo" -#: commands/tablecmds.c:12057 +#: commands/tablecmds.c:12496 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "non è possibile usare l'indice non univoco \"%s\" come identità di replica" -#: commands/tablecmds.c:12063 +#: commands/tablecmds.c:12502 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "non è possibile usare l'indice non immediato \"%s\" come identità di replica" -#: commands/tablecmds.c:12069 +#: commands/tablecmds.c:12508 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "non è possibile usare l'indice su espressione \"%s\" come identità di replica" -#: commands/tablecmds.c:12075 +#: commands/tablecmds.c:12514 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "non è possibile usare l'indice parziale \"%s\" come identità di replica" -#: commands/tablecmds.c:12081 +#: commands/tablecmds.c:12520 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "non è possibile usare l'indice non valido \"%s\" come identità di replica" -#: commands/tablecmds.c:12102 +#: commands/tablecmds.c:12541 #, c-format msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "l'indice \"%s\" non può essere usato come identità di replica perché la colonna %d è una colonna di sistema" -#: commands/tablecmds.c:12109 +#: commands/tablecmds.c:12548 #, c-format msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "l'indice \"%s\" non può essere usato come identità di replica perché la colonna \"%s\" può essere NULL" -#: commands/tablecmds.c:12302 +#: commands/tablecmds.c:12741 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "non è possibile cambiare lo stato di log della tabella \"%s\" perché è temporanea" -#: commands/tablecmds.c:12326 +#: commands/tablecmds.c:12765 #, c-format msgid "cannot change table \"%s\" to unlogged because it is part of a publication" msgstr "non è possibile rendere la tabella \"%s\" non loggata perché è parte di una pubblicazione" -#: commands/tablecmds.c:12328 +#: commands/tablecmds.c:12767 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Le tabelle non loggate non possono essere replicate." -#: commands/tablecmds.c:12373 +#: commands/tablecmds.c:12812 #, c-format msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "non è possibile cambiare lo stato della tabella \"%s\" a loggata perché referenzia la tabella non loggata \"%s\"" -#: commands/tablecmds.c:12383 +#: commands/tablecmds.c:12822 #, c-format msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "non è possibile cambiare lo stato della tabella \"%s\" a non loggata perché referenzia la tabella loggata \"%s\"" -#: commands/tablecmds.c:12441 +#: commands/tablecmds.c:12880 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "non è possibile spostare una sequenza con proprietario in uno schema diverso" -#: commands/tablecmds.c:12547 +#: commands/tablecmds.c:12986 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "la relazione \"%s\" esiste già nello schema \"%s\"" -#: commands/tablecmds.c:13073 +#: commands/tablecmds.c:13512 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\" non è un tipo composito" -#: commands/tablecmds.c:13104 +#: commands/tablecmds.c:13544 #, c-format msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" msgstr "\"%s\" non è una tabella, una vista, una vista materializzata, una sequenza né una tabella esterna" -#: commands/tablecmds.c:13135 +#: commands/tablecmds.c:13579 #, c-format msgid "unrecognized partitioning strategy \"%s\"" msgstr "strategia di partizionamento \"%s\" sconosciuta" -#: commands/tablecmds.c:13161 +#: commands/tablecmds.c:13587 #, c-format -msgid "column \"%s\" appears more than once in partition key" -msgstr "la colonna \"%s\" appare più di una volta nella chiave di partizione" +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "non è possibile usare la strategia di partizionamento \"list\" con più di una colonna" -#: commands/tablecmds.c:13209 +#: commands/tablecmds.c:13652 #, c-format msgid "column \"%s\" named in partition key does not exist" msgstr "la colonna \"%s\" nominata nella chiave di partizione non esiste" -#: commands/tablecmds.c:13216 +#: commands/tablecmds.c:13659 #, c-format msgid "cannot use system column \"%s\" in partition key" msgstr "non è possibile usare la colonna di sistema \"%s\" nella chiave di partizione" -#: commands/tablecmds.c:13274 +#: commands/tablecmds.c:13722 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" msgstr "le funzioni nelle espressioni di partizione devono essere IMMUTABLE" -#: commands/tablecmds.c:13283 -#, c-format -msgid "cannot use constant expression as partition key" -msgstr "non è possibile usare un'espressione costante come chiave di partizione" - -#: commands/tablecmds.c:13297 +#: commands/tablecmds.c:13739 #, c-format msgid "partition key expressions cannot contain whole-row references" msgstr "l'espressione di partizione non può contenere riferimenti alla riga intera" -#: commands/tablecmds.c:13318 +#: commands/tablecmds.c:13746 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "l'espressione di partizione non può contenere riferimenti a colonne di sistema" + +#: commands/tablecmds.c:13756 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "non è possibile usare un'espressione costante come chiave di partizione" + +#: commands/tablecmds.c:13777 #, c-format msgid "could not determine which collation to use for partition expression" msgstr "non è possibile determinare quale ordinamento usare per l'espressione di partizione" -#: commands/tablecmds.c:13343 +#: commands/tablecmds.c:13810 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "il tipo di dati %s non ha una classe di operatori hash di default" + +#: commands/tablecmds.c:13812 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Devi specificare una classe di operatori hash o definire una classe di operatori hash di default per il tipo di dato." + +#: commands/tablecmds.c:13816 #, c-format msgid "data type %s has no default btree operator class" msgstr "il tipo di dati %s non ha una classe di operatori btree predefinita" -#: commands/tablecmds.c:13345 +#: commands/tablecmds.c:13818 #, c-format msgid "You must specify a btree operator class or define a default btree operator class for the data type." msgstr "Devi specificare una classe di operatori btree o definire una classe di operatori btree predefinita per il tipo di dati." -#: commands/tablecmds.c:13392 +#: commands/tablecmds.c:13943 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "il vincolo di partizione per la tabella \"%s\" è implicito dai vincoli esistenti" + +#: commands/tablecmds.c:13947 partitioning/partbounds.c:621 +#: partitioning/partbounds.c:666 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "il nuovo vincolo di partizione per la partizione di default \"%s\" è implicito grazie ai vincoli esistenti" + +#: commands/tablecmds.c:14048 #, c-format msgid "\"%s\" is already a partition" msgstr "\"%s\" è già una partizione" -#: commands/tablecmds.c:13398 +#: commands/tablecmds.c:14054 #, c-format msgid "cannot attach a typed table as partition" msgstr "non è possibile agganciare una tabella con tipo come partizione" -#: commands/tablecmds.c:13414 +#: commands/tablecmds.c:14070 #, c-format msgid "cannot attach inheritance child as partition" msgstr "non è possibile agganciare una tabella figlia di ereditarietà come partizione" -#: commands/tablecmds.c:13428 +#: commands/tablecmds.c:14084 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "non è possibile agganciare una tabella padre di ereditarietà come partizione" -#: commands/tablecmds.c:13451 +#: commands/tablecmds.c:14118 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "non è possibile agganciare una relazione temporanea come partizione della relazione permanente \"%s\"" + +#: commands/tablecmds.c:14126 #, c-format msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "non è possibile agganciare una relazione permanente come partizione della relazione temporanea \"%s\"" -#: commands/tablecmds.c:13459 +#: commands/tablecmds.c:14134 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "non è possibile agganciare una partizione di relazione temporanea di un'altra sessione" -#: commands/tablecmds.c:13466 +#: commands/tablecmds.c:14141 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "non è possibile agganciare una relazione temporanea di un'altra sessione come partizione" -#: commands/tablecmds.c:13472 +#: commands/tablecmds.c:14147 #, c-format msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" msgstr "non è possibile agganciare la tabella \"%s\" senza OID come partizione della tabella \"%s\" con OID" -#: commands/tablecmds.c:13480 +#: commands/tablecmds.c:14155 #, c-format msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" msgstr "non è possibile agganciare la tabella \"%s\" con OID come partizione della tabella \"%s\" senza OID" -#: commands/tablecmds.c:13502 +#: commands/tablecmds.c:14177 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "la tabella \"%s\" contiene la colonna \"%s\" che non è presente nel padre \"%s\"" -#: commands/tablecmds.c:13505 +#: commands/tablecmds.c:14180 #, c-format -msgid "New partition should contain only the columns present in parent." -msgstr "La partizione dovrebbe contenere solo le colonne presenti nella tabella padre." +msgid "The new partition may contain only the columns present in parent." +msgstr "La partizione può contenere solo le colonne presenti nella tabella padre." -#: commands/tablecmds.c:13677 +#: commands/tablecmds.c:14192 #, c-format -msgid "partition constraint for table \"%s\" is implied by existing constraints" -msgstr "il vincolo di partizione per la tabella \"%s\" è implicito dai vincoli esistenti" +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "il trigger \"%s\" impedisce alla tabella \"%s\" di diventare una partizione" + +#: commands/tablecmds.c:14194 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "i trigger ROW con tabelle di transizioni non sono supportati sulle partizioni" + +#: commands/tablecmds.c:14827 commands/tablecmds.c:14846 +#: commands/tablecmds.c:14868 commands/tablecmds.c:14887 +#: commands/tablecmds.c:14943 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "non è possibile agganciare l'indice \"%s\" come partizione dell'indice \"%s\"" + +#: commands/tablecmds.c:14830 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "L'indice \"%s\" è già agganciato ad un altro indice." + +#: commands/tablecmds.c:14849 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "L'Indice \"%s\" non è un indice di alcuna partizione della tabella \"%s\"." + +#: commands/tablecmds.c:14871 +#, c-format +msgid "The index definitions do not match." +msgstr "Le definizioni degli indici non corrispondono." + +#: commands/tablecmds.c:14890 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "L'indice \"%s\" appartiene ad un vincolo nella tabella \"%s\" ma non c'è alcun vincolo per l'indice \"%s\"." + +#: commands/tablecmds.c:14946 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "C'è già un altro indice agganciato per la partizione \"%s\"." -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:623 replication/slot.c:1119 storage/file/copydir.c:47 +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:625 replication/slot.c:1194 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "creazione della directory \"%s\" fallita: %m" -#: commands/tablespace.c:209 utils/adt/genfile.c:538 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sulla directory \"%s\": %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "\"%s\" esiste ma non è una directory" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "permesso di creare il tablespace \"%s\" negato" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "Solo un superutente può incrementare questo valore." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "la posizione del tablespace non può contenere apici" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "la posizione del tablespace dev'essere un percorso assoluto" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "la posizione del tablespace \"%s\" è troppo lunga" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "la locazione del tablespace non dev'essere all'interno della directory dei dati" -#: commands/tablespace.c:304 commands/tablespace.c:950 +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "il nome del tablespace \"%s\" non è accettabile" -#: commands/tablespace.c:306 commands/tablespace.c:951 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "Il prefisso \"pg_\" è riservato per i tablespace di sistema." -#: commands/tablespace.c:316 commands/tablespace.c:963 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "il tablespace \"%s\" esiste già" -#: commands/tablespace.c:428 commands/tablespace.c:933 -#: commands/tablespace.c:1013 commands/tablespace.c:1081 -#: commands/tablespace.c:1214 commands/tablespace.c:1414 +#: commands/tablespace.c:430 commands/tablespace.c:935 +#: commands/tablespace.c:1015 commands/tablespace.c:1083 +#: commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "il tablespace \"%s\" non esiste" -#: commands/tablespace.c:434 +#: commands/tablespace.c:436 #, c-format msgid "tablespace \"%s\" does not exist, skipping" msgstr "il tablespace \"%s\" non esiste, saltato" -#: commands/tablespace.c:510 +#: commands/tablespace.c:512 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "il tablespace \"%s\" non è vuoto" -#: commands/tablespace.c:582 +#: commands/tablespace.c:584 #, c-format msgid "directory \"%s\" does not exist" msgstr "la directory \"%s\" non esiste" -#: commands/tablespace.c:583 +#: commands/tablespace.c:585 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "Crea questa directory per il tablespace prima di riavviare il server." -#: commands/tablespace.c:588 +#: commands/tablespace.c:590 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "impostazione dei permessi sulla directory \"%s\" fallita: %m" -#: commands/tablespace.c:618 +#: commands/tablespace.c:620 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "la directory \"%s\" già è in uso come tablespace" -#: commands/tablespace.c:742 commands/tablespace.c:755 -#: commands/tablespace.c:791 commands/tablespace.c:883 +#: commands/tablespace.c:705 commands/tablespace.c:715 +#: postmaster/postmaster.c:1476 storage/file/fd.c:2680 +#: storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 +#: utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "apertura della directory \"%s\" fallita: %m" + +#: commands/tablespace.c:744 commands/tablespace.c:757 +#: commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3110 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "rimozione della directory \"%s\" fallita: %m" -#: commands/tablespace.c:804 commands/tablespace.c:892 +#: commands/tablespace.c:806 commands/tablespace.c:894 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "rimozione del link simbolico \"%s\" fallita: %m" -#: commands/tablespace.c:814 commands/tablespace.c:901 +#: commands/tablespace.c:816 commands/tablespace.c:903 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "\"%s\" non è una directory o un link simbolico" -#: commands/tablespace.c:1086 +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "Il tablespace \"%s\" non esiste." -#: commands/tablespace.c:1513 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "rimozioni delle directory per il tablespace %u fallita" -#: commands/tablespace.c:1515 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "Puoi rimuovere le directory manualmente se necessario." -#: commands/trigger.c:187 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" msgstr "\"%s\" non è una tabella" -#: commands/trigger.c:189 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "Le tabelle non possono avere trigger INSTEAD OF." -#: commands/trigger.c:196 +#: commands/trigger.c:237 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "Le tabelle partizionate non possono avere trigger BEFORE / FOR EACH ROW." + +#: commands/trigger.c:255 #, c-format -msgid "Partitioned tables cannot have ROW triggers." -msgstr "Le tabelle partizionate non possono avere trigger ROW." +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "I trigger su tabelle partizionate non possono avere tabelle di transizione." -#: commands/trigger.c:207 commands/trigger.c:214 commands/trigger.c:374 +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" msgstr "\"%s\" è una vista" -#: commands/trigger.c:209 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "Le viste non possono avere trigger di riga BEFORE o AFTER." -#: commands/trigger.c:216 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "Le viste non possono avere trigger TRUNCATE." -#: commands/trigger.c:224 commands/trigger.c:231 commands/trigger.c:238 -#: commands/trigger.c:367 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 +#: commands/trigger.c:437 #, c-format msgid "\"%s\" is a foreign table" msgstr "\"%s\" è una tabella esterna" -#: commands/trigger.c:226 +#: commands/trigger.c:286 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "Le tabelle esterne non possono avere trigger INSTEAD OF." -#: commands/trigger.c:233 +#: commands/trigger.c:293 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "Le tabelle esterne non possono avere trigger TRUNCATE." -#: commands/trigger.c:240 +#: commands/trigger.c:305 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "Le tabelle esterne non possono avere trigger di vincolo." -#: commands/trigger.c:303 +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "i trigger TRUNCATE FOR EACH ROW non sono supportati" -#: commands/trigger.c:311 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "i trigger INSTEAD OF devono essere FOR EACH ROW" -#: commands/trigger.c:315 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "i trigger INSTEAD OF non possono avere condizioni WHEN" -#: commands/trigger.c:319 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "i trigger INSTEAD OF non possono avere liste di colonne" -#: commands/trigger.c:348 +#: commands/trigger.c:425 #, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" msgstr "non è possibile nominare la variabile ROW nella clausola REFERENCING" -#: commands/trigger.c:349 +#: commands/trigger.c:426 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." msgstr "Usa OLD TABLE o NEW TABLE per nominare le tabelle di transizione." -#: commands/trigger.c:362 -#, c-format -msgid "Triggers on partitioned tables cannot have transition tables." -msgstr "I trigger sulle tabelle partizionate non possono avere tabelle di transizione." - -#: commands/trigger.c:369 +#: commands/trigger.c:439 #, c-format msgid "Triggers on foreign tables cannot have transition tables." msgstr "I trigger sulle tabelle esterne non possono avere tabelle di transizione." -#: commands/trigger.c:376 +#: commands/trigger.c:446 #, c-format msgid "Triggers on views cannot have transition tables." msgstr "I trigger sulle viste non possono avere tabelle di transizione." -#: commands/trigger.c:381 +#: commands/trigger.c:466 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "i trigger ROW con tabelle di transizioni non sono supportati nei figli eredirari" + +#: commands/trigger.c:472 #, c-format msgid "transition table name can only be specified for an AFTER trigger" msgstr "il nome di una tabella di transizione può essere specificato solo per i trigger AFTER" -#: commands/trigger.c:386 +#: commands/trigger.c:477 #, c-format msgid "TRUNCATE triggers with transition tables are not supported" msgstr "trigger TRUNCATE con tabelle di transizione non sono supportati" -#: commands/trigger.c:394 +#: commands/trigger.c:494 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "non si può specificare una tabella di transizione per trigger con più di un evento" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "non si può specificare una tabella di transizione per trigger con una lista di colonne" + +#: commands/trigger.c:522 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" msgstr "NEW TABLE può essere specificato solo per i trigger INSERT o UPDATE" -#: commands/trigger.c:399 +#: commands/trigger.c:527 #, c-format msgid "NEW TABLE cannot be specified multiple times" msgstr "NEW TABLE non può essere specificato più volte" -#: commands/trigger.c:409 +#: commands/trigger.c:537 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" msgstr "OLD TABLE può essere specificato solo per i trigger DELETE o UPDATE" -#: commands/trigger.c:414 +#: commands/trigger.c:542 #, c-format msgid "OLD TABLE cannot be specified multiple times" msgstr "OLD TABLE non può essere specificato più volte" -#: commands/trigger.c:424 +#: commands/trigger.c:552 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" msgstr "OLD TABLE e NEW TABLE non possono avere lo stesso nome" -#: commands/trigger.c:481 commands/trigger.c:494 +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "la condizione WHEN del trigger di istruzione non può riferirsi a valori di colonna" -#: commands/trigger.c:486 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "la condizione WHEN dei trigger INSERT non può usare OLD" -#: commands/trigger.c:499 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "la condizione WHEN del trigger DELETE non può usare NEW" -#: commands/trigger.c:504 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "la condizione WHEN del trigger BEFORE non può usare le colonne di sistema NEW" -#: commands/trigger.c:669 commands/trigger.c:1440 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "il trigger \"%s\" per la relazione \"%s\" esiste già" -#: commands/trigger.c:965 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "Trovato trigger UPDATE della tabella referenziata." -#: commands/trigger.c:966 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "Trovato trigger DELETE della tabella referenziata." -#: commands/trigger.c:967 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "Trovato trigger della tabella referenziante." -#: commands/trigger.c:1076 commands/trigger.c:1092 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "ignorato gruppo di trigger incompleto per il vincolo \"%s\" %s" -#: commands/trigger.c:1105 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "conversione del gruppo di trigger nel vincolo \"%s\" %s" -#: commands/trigger.c:1326 commands/trigger.c:1485 commands/trigger.c:1600 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "il trigger \"%s\" per la tabella \"%s\" non esiste" -#: commands/trigger.c:1568 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "permesso negato: \"%s\" è un trigger di sistema" -#: commands/trigger.c:2123 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "la funzione trigger %u ha restituito un valore null" -#: commands/trigger.c:2184 commands/trigger.c:2390 commands/trigger.c:2601 -#: commands/trigger.c:2880 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 +#: commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "il trigger BEFORE STATEMENT non può restituire un valore" -#: commands/trigger.c:2942 executor/nodeModifyTable.c:746 -#: executor/nodeModifyTable.c:1041 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 +#: executor/nodeModifyTable.c:1244 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "la tupla da aggiornare era stata già modificata da un'operazione fatta eseguire da un comando corrente" -#: commands/trigger.c:2943 executor/nodeModifyTable.c:747 -#: executor/nodeModifyTable.c:1042 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 +#: executor/nodeModifyTable.c:1245 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "Considera l'utilizzo di un trigger AFTER invece di un trigger BEFORE per propagare i cambiamenti ad altre righe." -#: commands/trigger.c:2957 executor/execMain.c:2653 executor/nodeLockRows.c:216 -#: executor/nodeModifyTable.c:214 executor/nodeModifyTable.c:759 -#: executor/nodeModifyTable.c:1054 executor/nodeModifyTable.c:1220 +#: commands/trigger.c:3320 executor/execMain.c:2727 executor/nodeLockRows.c:220 +#: executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 +#: executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" msgstr "serializzazione dell'accesso fallita a causa di modifiche concorrenti" -#: commands/trigger.c:4852 +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 +#: executor/nodeLockRows.c:224 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "la tupla da lockare era stata già mossa in un'altra partizione a causa di una modifica concorrente" + +#: commands/trigger.c:5452 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "il vincolo \"%s\" non è deferibile" -#: commands/trigger.c:4875 +#: commands/trigger.c:5475 #, c-format msgid "constraint \"%s\" does not exist" msgstr "il vincolo \"%s\" non esiste" @@ -9856,637 +10155,672 @@ msgstr "non è possibile specificare sia l'opzione PARSER che COPY" msgid "text search parser is required" msgstr "l'analizzatore per la ricerca di testo è richiesto" -#: commands/tsearchcmds.c:1266 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "il tipo di token \"%s\" non esiste" -#: commands/tsearchcmds.c:1487 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "la mappatura per il token \"%s\" non esiste" -#: commands/tsearchcmds.c:1493 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "la mappatura per il token \"%s\" non esiste, saltato" -#: commands/tsearchcmds.c:1648 commands/tsearchcmds.c:1759 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "formato di lista di parametri non valido: \"%s\"" -#: commands/typecmds.c:183 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" msgstr "solo un superutente può creare un tipo di base" -#: commands/typecmds.c:290 commands/typecmds.c:1414 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "attributo del tipo \"%s\" non riconosciuto" -#: commands/typecmds.c:346 +#: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "categoria non valida \"%s\": dev'essere semplice ASCII" -#: commands/typecmds.c:365 +#: commands/typecmds.c:362 #, c-format msgid "array element type cannot be %s" msgstr "il tipo di elemento dell'array non può essere %s" -#: commands/typecmds.c:397 +#: commands/typecmds.c:394 #, c-format msgid "alignment \"%s\" not recognized" msgstr "allineamento \"%s\" non riconosciuto" -#: commands/typecmds.c:414 +#: commands/typecmds.c:411 #, c-format msgid "storage \"%s\" not recognized" msgstr "immagazzinamento \"%s\" non riconosciuto" -#: commands/typecmds.c:425 +#: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" msgstr "la funzione di input del tipo deve essere specificata" -#: commands/typecmds.c:429 +#: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" msgstr "la funzione di output del tipo deve essere specificata" -#: commands/typecmds.c:434 +#: commands/typecmds.c:431 #, c-format msgid "type modifier output function is useless without a type modifier input function" msgstr "la funzione di output del modificatore di tipo è inutile senza una funzione di input" -#: commands/typecmds.c:464 +#: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" msgstr "la funzione %s di input di tipo deve restituire il tipo %s" -#: commands/typecmds.c:481 +#: commands/typecmds.c:478 #, c-format msgid "type output function %s must return type %s" msgstr "la funzione %s di output di tipo deve restituire il tipo %s" -#: commands/typecmds.c:490 +#: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" msgstr "la funzione receive %s del tipo deve restituire il tipo %s" -#: commands/typecmds.c:499 +#: commands/typecmds.c:496 #, c-format msgid "type send function %s must return type %s" msgstr "la funzione send %s del tipo deve restituire il tipo %s" -#: commands/typecmds.c:564 +#: commands/typecmds.c:561 #, c-format msgid "type input function %s should not be volatile" msgstr "la funzione di input %s del tipo non può essere volatile" -#: commands/typecmds.c:569 +#: commands/typecmds.c:566 #, c-format msgid "type output function %s should not be volatile" msgstr "la funzione di output %s del tipo non può essere volatile" -#: commands/typecmds.c:574 +#: commands/typecmds.c:571 #, c-format msgid "type receive function %s should not be volatile" msgstr "la funzione receive %s del tipo non può essere volatile" -#: commands/typecmds.c:579 +#: commands/typecmds.c:576 #, c-format msgid "type send function %s should not be volatile" msgstr "la funzione send %s del tipo non può essere volatile" -#: commands/typecmds.c:584 +#: commands/typecmds.c:581 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "la funzione di input del modificatore %s del tipo non può essere volatile" -#: commands/typecmds.c:589 +#: commands/typecmds.c:586 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "la funzione di output del modificatore %s del tipo non può essere volatile" -#: commands/typecmds.c:811 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "\"%s\" non è un tipo di base valido per un dominio" -#: commands/typecmds.c:897 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "più di una espressione di default" -#: commands/typecmds.c:959 commands/typecmds.c:968 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "vincoli NULL/NOT NULL in conflitto" -#: commands/typecmds.c:984 +#: commands/typecmds.c:986 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "i vincoli di controllo per i domini non possono essere NO INHERIT" -#: commands/typecmds.c:993 commands/typecmds.c:2512 +#: commands/typecmds.c:995 commands/typecmds.c:2584 #, c-format msgid "unique constraints not possible for domains" msgstr "i vincoli univoci non sono ammessi per i domini" -#: commands/typecmds.c:999 commands/typecmds.c:2518 +#: commands/typecmds.c:1001 commands/typecmds.c:2590 #, c-format msgid "primary key constraints not possible for domains" msgstr "i vincoli di chiave primaria non sono ammessi per i domini" -#: commands/typecmds.c:1005 commands/typecmds.c:2524 +#: commands/typecmds.c:1007 commands/typecmds.c:2596 #, c-format msgid "exclusion constraints not possible for domains" msgstr "i vincoli di esclusione non sono ammessi per i domini" -#: commands/typecmds.c:1011 commands/typecmds.c:2530 +#: commands/typecmds.c:1013 commands/typecmds.c:2602 #, c-format msgid "foreign key constraints not possible for domains" msgstr "i vincoli di chiave esterna non sono ammessi per i domini" -#: commands/typecmds.c:1020 commands/typecmds.c:2539 +#: commands/typecmds.c:1022 commands/typecmds.c:2611 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "specificare la deferibilità dei vincoli non è ammesso per i domini" -#: commands/typecmds.c:1284 utils/cache/typcache.c:1648 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" msgstr "%s non è una enumerazione" -#: commands/typecmds.c:1422 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "l'attributo \"subtype\" del tipo è richiesto" -#: commands/typecmds.c:1427 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "il sottotipo dell'intervallo non può essere %s" -#: commands/typecmds.c:1446 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "è stato specificato un ordinamento per gli intervalli ma il sottotipo non supporta ordinamenti" -#: commands/typecmds.c:1680 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "modifica del tipo di argomento della funzione %s da \"opaque\" a \"cstring\"" -#: commands/typecmds.c:1731 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "modifica del tipo di argomento della funzione %s da \"opaque\" a %s" -#: commands/typecmds.c:1830 +#: commands/typecmds.c:1898 #, c-format msgid "typmod_in function %s must return type %s" msgstr "la funzione %s typmod_in deve restituire il tipo %s" -#: commands/typecmds.c:1857 +#: commands/typecmds.c:1925 #, c-format msgid "typmod_out function %s must return type %s" msgstr "la funzione %s typmod_out deve restituire il tipo %s" -#: commands/typecmds.c:1884 +#: commands/typecmds.c:1952 #, c-format msgid "type analyze function %s must return type %s" msgstr "la funzione %s analyze deve restituire il tipo %s" -#: commands/typecmds.c:1930 +#: commands/typecmds.c:1998 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "Occorre specificare una classe di operatori per l'intervallo o definire una classe di operatori predefinita per il sottotipo." -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" msgstr "la funzione canonica %s dell'intervallo deve restituire un intervallo" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" msgstr "la funzione canonica %s dell'intervallo deve essere immutabile" -#: commands/typecmds.c:2003 +#: commands/typecmds.c:2071 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "la funzione %s di differenza sottotipo range deve restituire il tipo %s" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "la funzione di differenza sottotipo %s deve essere immutabile" -#: commands/typecmds.c:2037 +#: commands/typecmds.c:2105 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "valore di OID array di pg_type non impostato in modalità di aggiornamento binaria" -#: commands/typecmds.c:2340 +#: commands/typecmds.c:2409 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "la colonna \"%s\" della tabella \"%s\" contiene valori null" -#: commands/typecmds.c:2453 commands/typecmds.c:2636 +#: commands/typecmds.c:2523 commands/typecmds.c:2708 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "il vincolo \"%s\" del dominio \"%s\" non esiste" -#: commands/typecmds.c:2457 +#: commands/typecmds.c:2527 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "il vincolo \"%s\" del dominio \"%s\" non esiste, saltato" -#: commands/typecmds.c:2642 +#: commands/typecmds.c:2715 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "il vincolo \"%s\" del dominio \"%s\" non è un vincolo di controllo" -#: commands/typecmds.c:2747 +#: commands/typecmds.c:2821 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "la colonna \"%s\" della tabella \"%s\" contiene valori che violano il nuovo vincolo" -#: commands/typecmds.c:2960 commands/typecmds.c:3247 commands/typecmds.c:3434 +#: commands/typecmds.c:3049 commands/typecmds.c:3255 commands/typecmds.c:3337 +#: commands/typecmds.c:3524 #, c-format msgid "%s is not a domain" msgstr "%s non è un dominio" -#: commands/typecmds.c:2994 +#: commands/typecmds.c:3082 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "il vincolo \"%s\" del dominio \"%s\" esiste già" -#: commands/typecmds.c:3045 +#: commands/typecmds.c:3133 #, c-format msgid "cannot use table references in domain check constraint" msgstr "non è possibile usare riferimenti a tabelle nel vincolo di controllo del dominio" -#: commands/typecmds.c:3177 commands/typecmds.c:3259 commands/typecmds.c:3551 +#: commands/typecmds.c:3267 commands/typecmds.c:3349 commands/typecmds.c:3641 #, c-format msgid "%s is a table's row type" msgstr "%s è il tipo della riga di una tabella" -#: commands/typecmds.c:3179 commands/typecmds.c:3261 commands/typecmds.c:3553 +#: commands/typecmds.c:3269 commands/typecmds.c:3351 commands/typecmds.c:3643 #, c-format msgid "Use ALTER TABLE instead." msgstr "Usa ALTER TABLE invece." -#: commands/typecmds.c:3186 commands/typecmds.c:3268 commands/typecmds.c:3466 +#: commands/typecmds.c:3276 commands/typecmds.c:3358 commands/typecmds.c:3556 #, c-format msgid "cannot alter array type %s" msgstr "non è possibile modificare il tipo di array %s" -#: commands/typecmds.c:3188 commands/typecmds.c:3270 commands/typecmds.c:3468 +#: commands/typecmds.c:3278 commands/typecmds.c:3360 commands/typecmds.c:3558 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "puoi modificare il tipo %s, il che modificherà il tipo dell'array come conseguenza." -#: commands/typecmds.c:3536 +#: commands/typecmds.c:3626 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "il tipo \"%s\" esiste già nello schema \"%s\"" -#: commands/user.c:142 +#: commands/user.c:141 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSID non può più essere specificato" -#: commands/user.c:296 +#: commands/user.c:295 #, c-format msgid "must be superuser to create superusers" msgstr "solo i superutenti possono creare superutenti" -#: commands/user.c:303 +#: commands/user.c:302 #, c-format msgid "must be superuser to create replication users" msgstr "solo i superutenti possono creare utenti di replica" -#: commands/user.c:310 commands/user.c:685 +#: commands/user.c:309 commands/user.c:707 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "solo i superutenti possono cambiare l'attributo bypassrls" -#: commands/user.c:317 +#: commands/user.c:316 #, c-format msgid "permission denied to create role" msgstr "permesso di creare il ruolo negato" -#: commands/user.c:327 commands/user.c:1161 commands/user.c:1168 -#: utils/adt/acl.c:5246 utils/adt/acl.c:5252 gram.y:14485 gram.y:14520 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 +#: utils/adt/acl.c:5342 utils/adt/acl.c:5348 gram.y:14877 gram.y:14915 #, c-format msgid "role name \"%s\" is reserved" msgstr "il nome di ruolo \"%s\" è riservato" -#: commands/user.c:329 commands/user.c:1163 commands/user.c:1170 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "I nomi di ruoli che iniziano con \"pg_\" sono riservati." -#: commands/user.c:341 commands/user.c:1176 +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "il ruolo \"%s\" esiste già" -#: commands/user.c:415 +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "la stringa vuota non è una password valida, password rimossa" + +#: commands/user.c:437 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "valore di OID di pg_authid non impostato in modalità di aggiornamento binaria" -#: commands/user.c:671 commands/user.c:881 commands/user.c:1415 -#: commands/user.c:1559 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 +#: commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" msgstr "solo i superutenti possono modificare superutenti" -#: commands/user.c:678 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" msgstr "solo i superutenti possono modificare utenti di replica" -#: commands/user.c:701 commands/user.c:889 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "permesso negato" -#: commands/user.c:919 +#: commands/user.c:953 #, c-format msgid "must be superuser to alter settings globally" msgstr "solo i superutenti possono alterare impostazioni globalmente" -#: commands/user.c:941 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "permesso di eliminare il ruolo negato" -#: commands/user.c:965 +#: commands/user.c:999 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "non è possibile usare lo specificatore di ruolo speciale in DROP ROLE" -#: commands/user.c:975 commands/user.c:1132 commands/variable.c:822 -#: commands/variable.c:894 utils/adt/acl.c:5104 utils/adt/acl.c:5151 -#: utils/adt/acl.c:5179 utils/adt/acl.c:5197 utils/init/miscinit.c:503 +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 +#: commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "il ruolo \"%s\" non esiste" -#: commands/user.c:980 +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "il ruolo \"%s\" non esiste, saltato" -#: commands/user.c:992 commands/user.c:996 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "l'utente corrente non può essere eliminato" -#: commands/user.c:1000 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "l'utente della sessione non può essere eliminato" -#: commands/user.c:1011 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" msgstr "solo i superutenti possono eliminare superutenti" -#: commands/user.c:1027 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "il ruolo \"%s\" non può essere eliminato perché alcuni oggetti ne dipendono" -#: commands/user.c:1148 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "l'utente della sessione non può essere rinominato" -#: commands/user.c:1152 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "l'utente corrente non può essere eliminato" -#: commands/user.c:1186 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" msgstr "solo i superutenti possono rinominare superutenti" -#: commands/user.c:1193 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "permesso di rinominare il ruolo negato" -#: commands/user.c:1214 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "L'MD5 della password è stato cancellato perché il ruolo è stato rinominato" -#: commands/user.c:1274 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "la colonna dei nomi non può essere inclusa in GRANT/REVOKE ROLE" -#: commands/user.c:1312 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" msgstr "permesso di eliminare gli oggetti negato" -#: commands/user.c:1339 commands/user.c:1348 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" msgstr "permesso di riassegnare gli oggetti negato" -#: commands/user.c:1423 commands/user.c:1567 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" msgstr "occorre avere l'opzione admin sul ruolo \"%s\"" -#: commands/user.c:1440 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" msgstr "solo i superutenti possono impostare chi ha concesso il privilegio" -#: commands/user.c:1465 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "il ruolo \"%s\" è membro del ruolo \"%s\"" -#: commands/user.c:1480 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "il ruolo \"%s\" è già membro del ruolo \"%s\"" -#: commands/user.c:1589 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "il ruolo \"%s\" non è membro del ruolo \"%s\"" -#: commands/vacuum.c:186 +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "occorre specificare l'opzione ANALYZE quando è fornita una lista di colonne" + +#: commands/vacuum.c:203 #, c-format msgid "%s cannot be executed from VACUUM or ANALYZE" msgstr "%s non può essere eseguito da VACUUM o ANALYZE" -#: commands/vacuum.c:196 +#: commands/vacuum.c:213 #, c-format msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" msgstr "l'opzione DISABLE_PAGE_SKIPPING di VACUUM non può essere usata con FULL" -#: commands/vacuum.c:565 +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "il più vecchio xmin è molto lontano nel tempo" -#: commands/vacuum.c:566 +#: commands/vacuum.c:658 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." -msgstr "Chiudi presto le transazioni per evitare problemi di wraparound." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Chiudi presto le transazioni per evitare problemi di wraparound.\n" +"Potrebbe essere necessario inoltre effettuare il COMMIT o il ROLLBACK di vecchie transazioni preparate, o eliminare vecchi slot di replica." -#: commands/vacuum.c:605 +#: commands/vacuum.c:698 #, c-format msgid "oldest multixact is far in the past" msgstr "il multixact più vecchio è remoto" -#: commands/vacuum.c:606 +#: commands/vacuum.c:699 #, c-format msgid "Close open transactions with multixacts soon to avoid wraparound problems." msgstr "Chiudi presto le transazioni con multixact per evitare problemi di wraparound." -#: commands/vacuum.c:1176 +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" msgstr "alcuni database non sono stati ripuliti per più di 2 miliardi di transazioni" -#: commands/vacuum.c:1177 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "Potresti aver già subito perdita di dati dovuta al wraparound delle transazioni." -#: commands/vacuum.c:1306 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" msgstr "pulizia di \"%s\" saltata --- lock non disponibile" -#: commands/vacuum.c:1332 +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "pulizia di \"%s\" saltata --- la relazione non esiste più" + +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "\"%s\" saltato --- solo i superutenti possono pulirla" -#: commands/vacuum.c:1336 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "\"%s\" saltato --- solo i superutenti o il proprietario del database possono pulirla" -#: commands/vacuum.c:1340 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "\"%s\" saltato --- solo il proprietario del database o della tabella possono pulirla" -#: commands/vacuum.c:1359 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" msgstr "\"%s\" saltato --- non è possibile ripulire non-tabelle o tabelle speciali di sistema" -#: commands/vacuumlazy.c:377 +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "vacuum automatico aggressivo della tabella \"%s.%s.%s\": scansioni di indici: %d\n" + +#: commands/vacuumlazy.c:380 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" msgstr "vacuum automatico della tabella \"%s.%s.%s\": scan di indici: %d\n" -#: commands/vacuumlazy.c:382 +#: commands/vacuumlazy.c:386 #, c-format msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" msgstr "pagine: %u rimosse, %u restanti, %u saltate perché bloccate, %u congelate saltate\n" -#: commands/vacuumlazy.c:388 +#: commands/vacuumlazy.c:392 #, c-format msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" msgstr "tuple: %.0f rimosse, %.0f restanti, %.0f sono morte ma non possono essere ancora rimosse, xmin più vecchio: %u\n" -#: commands/vacuumlazy.c:394 +#: commands/vacuumlazy.c:398 #, c-format msgid "buffer usage: %d hits, %d misses, %d dirtied\n" msgstr "uso dei buffer: %d colpiti, %d mancati, %d sporcati\n" -#: commands/vacuumlazy.c:398 +#: commands/vacuumlazy.c:402 #, c-format msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" msgstr "velocità di lettura media: %.3f MB/s, velocità di scrittura media: %.3f MB/s\n" -#: commands/vacuumlazy.c:400 +#: commands/vacuumlazy.c:404 #, c-format msgid "system usage: %s" msgstr "utilizzo di sistema: %s" -#: commands/vacuumlazy.c:860 +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "vacuum aggressivo di \"%s.%s\"" + +#: commands/vacuumlazy.c:881 #, c-format msgid "relation \"%s\" page %u is uninitialized --- fixing" msgstr "la relazione \"%s\" pagina %u non è inizializzata --- in correzione" -#: commands/vacuumlazy.c:1330 +#: commands/vacuumlazy.c:1417 #, c-format msgid "\"%s\": removed %.0f row versions in %u pages" msgstr "\"%s\": %.0f versioni di riga rimosse in %u pagine" -#: commands/vacuumlazy.c:1340 +#: commands/vacuumlazy.c:1427 #, c-format msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" msgstr "%.0f versioni di righe morte non possono essere ancora rimosse, xmin più vecchio: %u\n" -#: commands/vacuumlazy.c:1342 +#: commands/vacuumlazy.c:1429 #, c-format msgid "There were %.0f unused item pointers.\n" msgstr "C'erano %.0f puntatori ad elementi non usati.\n" -#: commands/vacuumlazy.c:1344 +#: commands/vacuumlazy.c:1431 #, c-format msgid "Skipped %u page due to buffer pins, " msgid_plural "Skipped %u pages due to buffer pins, " msgstr[0] "%u pagine saltate a causa di buffer pin, " msgstr[1] "%u pagine saltate a causa di buffer pin, " -#: commands/vacuumlazy.c:1348 +#: commands/vacuumlazy.c:1435 #, c-format msgid "%u frozen page.\n" msgid_plural "%u frozen pages.\n" msgstr[0] "%u pagine congelate.\n" msgstr[1] "%u pagine congelate.\n" -#: commands/vacuumlazy.c:1352 +#: commands/vacuumlazy.c:1439 #, c-format msgid "%u page is entirely empty.\n" msgid_plural "%u pages are entirely empty.\n" msgstr[0] "%u pagina è completamente vuota.\n" msgstr[1] "%u pagina sono completamente vuote.\n" -#: commands/vacuumlazy.c:1360 +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" msgstr "\"%s\": trovate %.0f versioni di riga removibili, %.0f non removibili in %u pagine su %u" -#: commands/vacuumlazy.c:1429 +#: commands/vacuumlazy.c:1515 #, c-format msgid "\"%s\": removed %d row versions in %d pages" msgstr "\"%s\": %d versioni di riga rimosse in %d pagine" -#: commands/vacuumlazy.c:1618 +#: commands/vacuumlazy.c:1704 #, c-format msgid "scanned index \"%s\" to remove %d row versions" msgstr "effettuata la scansione dell'indice \"%s\" per rimuovere %d versioni di riga" -#: commands/vacuumlazy.c:1664 +#: commands/vacuumlazy.c:1756 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "l'indice \"%s\" ora contiene %.0f versioni di riga in %u pagine" -#: commands/vacuumlazy.c:1668 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -10497,22 +10831,22 @@ msgstr "" "%u pagine dell'indice sono state cancellate, %u sono attualmente riusabili.\n" "%s." -#: commands/vacuumlazy.c:1763 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" msgstr "\"%s\": truncate interrotto a causa di una richiesta di lock in conflitto" -#: commands/vacuumlazy.c:1828 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "\"%s\": %u pagine ridotte a %u" -#: commands/vacuumlazy.c:1893 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" msgstr "\"%s\": annullamento del troncamento a causa di richieste di lock in conflitto" -#: commands/variable.c:165 utils/misc/guc.c:10019 utils/misc/guc.c:10081 +#: commands/variable.c:165 utils/misc/guc.c:10298 utils/misc/guc.c:10360 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "Parola chiave non riconosciuta: \"%s\"." @@ -10572,7 +10906,7 @@ msgstr "SET TRANSACTION ISOLATION LEVEL dev'essere invocato prima di qualsiasi q msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "SET TRANSACTION ISOLATION LEVEL non può essere invocato in una sotto-transazione" -#: commands/variable.c:571 storage/lmgr/predicate.c:1633 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "non è possibile usare la modalità SERIALIZABLE in un hot standby" @@ -10604,8 +10938,8 @@ msgstr "Non è possibile cambiare \"client_encoding\" ora." #: commands/variable.c:776 #, c-format -msgid "cannot change client_encoding in a parallel worker" -msgstr "non è possibile cambiare client_encoding in un worker parallelo" +msgid "cannot change client_encoding during a parallel operation" +msgstr "non è possibile cambiare client_encoding durante un'operazione parallela" #: commands/variable.c:912 #, c-format @@ -10622,204 +10956,206 @@ msgstr "valore non valido per l'opzione \"check_option\"" msgid "Valid values are \"local\" and \"cascaded\"." msgstr "Valori validi sono \"local\" e \"cascaded\"." -#: commands/view.c:101 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "non è stato possibile determinare quale ordinamento usare per la colonna \"%s\"" -#: commands/view.c:115 +#: commands/view.c:117 #, c-format msgid "view must have at least one column" msgstr "la vista deve avere almeno una colonna" -#: commands/view.c:281 commands/view.c:293 +#: commands/view.c:285 commands/view.c:297 #, c-format msgid "cannot drop columns from view" msgstr "non è possibile eliminare colonne da una vista" -#: commands/view.c:298 +#: commands/view.c:302 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "non è possibile cambiare nome della colonna di vista \"%s\" in \"%s\"" -#: commands/view.c:306 +#: commands/view.c:310 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "non è possibile cambiare tipo di dato della colonna di vista \"%s\" da %s a %s" -#: commands/view.c:451 +#: commands/view.c:455 #, c-format msgid "views must not contain SELECT INTO" msgstr "le viste non possono contenere SELECT INTO" -#: commands/view.c:463 +#: commands/view.c:467 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "una vista non può contenere istruzioni di modifica dei dati in un WITH" -#: commands/view.c:533 +#: commands/view.c:537 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "CREATE VIEW specifica più nomi di colonne che colonne" -#: commands/view.c:541 +#: commands/view.c:545 #, c-format msgid "views cannot be unlogged because they do not have storage" msgstr "le viste non possono essere non loggate perché non sono immagazzinate" -#: commands/view.c:555 +#: commands/view.c:559 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "la vista \"%s\" sarà una vista temporanea" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:78 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "il cursore \"%s\" non è una query SELECT" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:84 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "il cursore \"%s\" è trattenuto da una precedente transazione" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:116 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "il cursore \"%s\" ha più di un riferimento FOR UPDATE/SHARE alla tabella \"%s\"" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:125 #, c-format msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "il cursore \"%s\" non ha alcun riferimento FOR UPDATE/SHARE alla tabella \"%s\"" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:135 executor/execCurrent.c:180 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "il cursore \"%s\" non è posizionato su una riga" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:167 executor/execCurrent.c:226 +#: executor/execCurrent.c:238 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "il cursore \"%s\" non è una scansione semplice aggiornabile della tabella \"%s\"" -#: executor/execCurrent.c:231 executor/execExprInterp.c:1899 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "il tipo del parametro %d (%s) non combacia con quello usato alla preparazione del piano (%s)" -#: executor/execCurrent.c:243 executor/execExprInterp.c:1911 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 #, c-format msgid "no value found for parameter %d" msgstr "nessun valore trovato per il parametro %d" -#: executor/execExpr.c:780 parser/parse_agg.c:764 +#: executor/execExpr.c:856 parser/parse_agg.c:794 #, c-format msgid "window function calls cannot be nested" msgstr "le chiamate a funzioni finestra non possono essere annidate" -#: executor/execExpr.c:1224 +#: executor/execExpr.c:1314 #, c-format msgid "target type is not an array" msgstr "il tipo di destinazione non è un array" -#: executor/execExpr.c:1547 +#: executor/execExpr.c:1646 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "la colonna ROW() è di tipo %s invece di %s" -#: executor/execExpr.c:2079 executor/execSRF.c:670 parser/parse_func.c:116 -#: parser/parse_func.c:543 parser/parse_func.c:902 +#: executor/execExpr.c:2181 executor/execSRF.c:697 parser/parse_func.c:126 +#: parser/parse_func.c:640 parser/parse_func.c:1014 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" msgstr[0] "non è possibile passare più di %d argomento ad una funzione" msgstr[1] "non è possibile passare più di %d argomenti ad una funzione" -#: executor/execExpr.c:2356 executor/execExpr.c:2362 -#: executor/execExprInterp.c:2210 utils/adt/arrayfuncs.c:260 -#: utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 -#: utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5241 -#: utils/adt/arrayfuncs.c:5758 +#: executor/execExpr.c:2479 executor/execExpr.c:2485 +#: executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 +#: utils/adt/arrayfuncs.c:5820 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "il numero di dimensioni dell'array (%d) eccede il massimo consentito (%d)" -#: executor/execExprInterp.c:1571 +#: executor/execExprInterp.c:1879 #, c-format msgid "attribute %d of type %s has been dropped" msgstr "l'attributo %d del tipo %s è stato rimosso" -#: executor/execExprInterp.c:1577 +#: executor/execExprInterp.c:1885 #, c-format msgid "attribute %d of type %s has wrong type" msgstr "l'attributo %d del tipo %s ha il tipo sbagliato" -#: executor/execExprInterp.c:1579 executor/execExprInterp.c:2496 +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 +#: executor/execExprInterp.c:2933 #, c-format msgid "Table has type %s, but query expects %s." msgstr "La tabella ha il tipo %s, ma la query prevede %s." -#: executor/execExprInterp.c:1989 +#: executor/execExprInterp.c:2374 #, c-format msgid "WHERE CURRENT OF is not supported for this table type" msgstr "WHERE CURRENT OF non è supportato per questo tipo di tabella" -#: executor/execExprInterp.c:2188 +#: executor/execExprInterp.c:2591 #, c-format msgid "cannot merge incompatible arrays" msgstr "non è possibile unire array non compatibili" -#: executor/execExprInterp.c:2189 +#: executor/execExprInterp.c:2592 #, c-format msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." msgstr "Un array con tipo di elementi %s non può essere incluso nel costrutto ARRAY con elementi di tipo %s." -#: executor/execExprInterp.c:2230 executor/execExprInterp.c:2260 +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "gli array multidimensionali devono avere espressioni array di dimensioni corrispondenti" -#: executor/execExprInterp.c:2495 +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 #, c-format msgid "attribute %d has wrong type" msgstr "l'attributo %d è di tipo errato" -#: executor/execExprInterp.c:2604 +#: executor/execExprInterp.c:3042 #, c-format msgid "array subscript in assignment must not be null" msgstr "l'indice di un array nell'assegnamento non può essere nullo" -#: executor/execExprInterp.c:3037 utils/adt/domains.c:148 +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 #, c-format msgid "domain %s does not allow null values" msgstr "il DOMAIN %s non consente valori nulli" -#: executor/execExprInterp.c:3052 utils/adt/domains.c:183 +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 #, c-format msgid "value for domain %s violates check constraint \"%s\"" msgstr "il valore per il DOMAIN %s viola il vincolo di controllo \"%s\"" -#: executor/execExprInterp.c:3419 executor/execExprInterp.c:3436 -#: executor/execExprInterp.c:3538 executor/nodeModifyTable.c:96 -#: executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:123 -#: executor/nodeModifyTable.c:131 +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 +#: executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 +#: executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 +#: executor/nodeModifyTable.c:142 #, c-format msgid "table row type and query-specified row type do not match" msgstr "il tipo della riga della tabella e il tipo di riga specificato dalla query non corrispondono" -#: executor/execExprInterp.c:3420 +#: executor/execExprInterp.c:3862 #, c-format msgid "Table row contains %d attribute, but query expects %d." msgid_plural "Table row contains %d attributes, but query expects %d." msgstr[0] "La riga della tabella contiene %d attributo, ma la query ne prevede %d." msgstr[1] "La riga della tabella contiene %d attributi, ma la query ne prevede %d." -#: executor/execExprInterp.c:3437 executor/nodeModifyTable.c:107 +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "La tabella ha il tipo %s in posizione %d, ma la query prevede %s." -#: executor/execExprInterp.c:3539 executor/execSRF.c:925 +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 #, c-format msgid "Physical storage mismatch on dropped attribute at ordinal position %d." msgstr "Il tipo di immagazzinamento fisico non corrisponde per l'attributo eliminato in posizione %d." @@ -10859,199 +11195,212 @@ msgstr "La chiave %s è in conflitto con la chiave esistente %s." msgid "Key conflicts with existing key." msgstr "Conflitti di chiave con chiave esistente." -#: executor/execMain.c:1111 +#: executor/execMain.c:1116 #, c-format msgid "cannot change sequence \"%s\"" msgstr "non è possibile modificare la sequenza \"%s\"" -#: executor/execMain.c:1117 +#: executor/execMain.c:1122 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "non è possibile modificare la relazione TOAST \"%s\"" -#: executor/execMain.c:1135 rewrite/rewriteHandler.c:2704 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2773 #, c-format msgid "cannot insert into view \"%s\"" msgstr "non è possibile inserire nella vista \"%s\"" -#: executor/execMain.c:1137 rewrite/rewriteHandler.c:2707 +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2776 #, c-format msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." msgstr "Per consentire inserimenti nella vista occorre fornire un trigger INSTEAD OF INSERT oppure una regola ON INSERT DO INSTEAD senza condizioni." -#: executor/execMain.c:1143 rewrite/rewriteHandler.c:2712 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2781 #, c-format msgid "cannot update view \"%s\"" msgstr "non è possibile modificare la vista \"%s\"" -#: executor/execMain.c:1145 rewrite/rewriteHandler.c:2715 +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2784 #, c-format msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." msgstr "Per consentire modifiche alla vista occorre fornire un trigger INSTEAD OF UPDATE oppure una regola ON UPDATE DO INSTEAD senza condizioni." -#: executor/execMain.c:1151 rewrite/rewriteHandler.c:2720 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2789 #, c-format msgid "cannot delete from view \"%s\"" msgstr "non è possibile cancellare dalla vista \"%s\"" -#: executor/execMain.c:1153 rewrite/rewriteHandler.c:2723 +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2792 #, c-format msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." msgstr "Per consentire eliminazioni dalla vista occorre fornire un trigger INSTEAD OF DELETE oppure una regola ON DELETE DO INSTEAD senza condizioni." -#: executor/execMain.c:1164 +#: executor/execMain.c:1169 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "non è possibile modificare la vista materializzata \"%s\"" -#: executor/execMain.c:1176 +#: executor/execMain.c:1181 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "non è possibile inserire nella tabella esterna \"%s\"" -#: executor/execMain.c:1182 +#: executor/execMain.c:1187 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "la tabella esterna \"%s\" non consente inserimenti" -#: executor/execMain.c:1189 +#: executor/execMain.c:1194 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "non è possibile modificare la tabella esterna \"%s\"" -#: executor/execMain.c:1195 +#: executor/execMain.c:1200 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "la tabella esterna \"%s\" non consente modifiche" -#: executor/execMain.c:1202 +#: executor/execMain.c:1207 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "non è possibile eliminare dalla tabella esterna \"%s\"" -#: executor/execMain.c:1208 +#: executor/execMain.c:1213 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "la tabella esterna \"%s\" non consente cancellazioni" -#: executor/execMain.c:1219 +#: executor/execMain.c:1224 #, c-format msgid "cannot change relation \"%s\"" msgstr "non è possibile modificare la relazione \"%s\"" -#: executor/execMain.c:1246 +#: executor/execMain.c:1251 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "non è possibile bloccare righe nella sequenza \"%s\"" -#: executor/execMain.c:1253 +#: executor/execMain.c:1258 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "non è possibile bloccare righe nella relazione TOAST \"%s\"" -#: executor/execMain.c:1260 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "non è possibile bloccare righe vista \"%s\"" -#: executor/execMain.c:1268 +#: executor/execMain.c:1273 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "non è possibile bloccare righe nella vista materializzata \"%s\"" -#: executor/execMain.c:1277 executor/execMain.c:2887 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1282 executor/execMain.c:2974 +#: executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "non è possibile bloccare righe nella tabella esterna \"%s\"" -#: executor/execMain.c:1283 +#: executor/execMain.c:1288 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "non è possibile bloccare righe nella relazione \"%s\"" -#: executor/execMain.c:1947 +#: executor/execMain.c:1959 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "valori null nella colonna \"%s\" violano il vincolo non-null" +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "la nuova riga per la partizione \"%s\" viola il vincolo di partizione" -#: executor/execMain.c:1949 executor/execMain.c:1995 executor/execMain.c:2037 -#: executor/execMain.c:2122 +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 +#: executor/execMain.c:2195 #, c-format msgid "Failing row contains %s." msgstr "La riga in errore contiene %s." -#: executor/execMain.c:1993 +#: executor/execMain.c:2039 #, c-format -msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgstr "la nuova riga per la relazione \"%s\" viola il vincolo di controllo \"%s\"" +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "valori null nella colonna \"%s\" violano il vincolo non-null" -#: executor/execMain.c:2035 +#: executor/execMain.c:2086 #, c-format -msgid "new row for relation \"%s\" violates partition constraint" -msgstr "la nuova riga per la partizione \"%s\" viola il vincolo di partizione" +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "la nuova riga per la relazione \"%s\" viola il vincolo di controllo \"%s\"" -#: executor/execMain.c:2120 +#: executor/execMain.c:2193 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "la nuova riga viola l'opzione di controllo della vista \"%s\"" -#: executor/execMain.c:2130 +#: executor/execMain.c:2203 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "la nuova riga viola la regola di sicurezza per riga \"%s\" per la tabella \"%s\"" -#: executor/execMain.c:2135 +#: executor/execMain.c:2208 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "la nuova riga viola la regola di sicurezza per riga per la tabella \"%s\"" -#: executor/execMain.c:2142 +#: executor/execMain.c:2215 #, c-format msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "la nuova riga viola la regola di sicurezza per riga \"%s\" (espressione USING) per la tabella \"%s\"" -#: executor/execMain.c:2147 +#: executor/execMain.c:2220 #, c-format msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "la nuova riga viola la regola di sicurezza per riga (espressione USING) per la tabella \"%s\"" -#: executor/execMain.c:3341 +#: executor/execPartition.c:337 #, c-format msgid "no partition of relation \"%s\" found for row" msgstr "nessuna partizione della relazione \"%s\" trovata per la riga" -#: executor/execMain.c:3343 +#: executor/execPartition.c:339 #, c-format msgid "Partition key of the failing row contains %s." msgstr "La chiave di partizione della riga sbagliata contiene %s." -#: executor/execReplication.c:195 executor/execReplication.c:342 +#: executor/execReplication.c:197 executor/execReplication.c:361 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "la tupla da lockare era stata già mossa in un'altra partizione a causa di una modifica concorrente, sto riprovando" + +#: executor/execReplication.c:201 executor/execReplication.c:365 #, c-format msgid "concurrent update, retrying" msgstr "modifica concorrente, sto riprovando" -#: executor/execReplication.c:544 +#: executor/execReplication.c:262 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 +#: utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "operatore di uguaglianza per il tipo %s non trovato" + +#: executor/execReplication.c:578 #, c-format -msgid "cannot update table \"%s\" because it does not have replica identity and publishes updates" -msgstr "non è possibile modificare la tabella \"%s\" perché non ha una replica di identità ma pubblica le righe modificate" +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "non è possibile modificare la tabella \"%s\" perché non ha una identità di replica ma pubblica le righe modificate" -#: executor/execReplication.c:546 +#: executor/execReplication.c:580 #, c-format msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." msgstr "Per abilitare le modifiche della tabella imposta REPLICA IDENTITY tramite ALTER TABLE." -#: executor/execReplication.c:550 +#: executor/execReplication.c:584 #, c-format -msgid "cannot delete from table \"%s\" because it does not have replica identity and publishes deletes" -msgstr "non è possibile cancellare dalla tabella \"%s\" perché non ha una replica di identità ma pubblica le righe cancellate" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "non è possibile cancellare dalla tabella \"%s\" perché non ha una identità di replica ma pubblica le righe cancellate" -#: executor/execReplication.c:552 +#: executor/execReplication.c:586 #, c-format msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." msgstr "Per abilitare le cancellazioni sulla tabella imposta REPLICA IDENTITY tramite ALTER TABLE." -#: executor/execReplication.c:571 +#: executor/execReplication.c:605 #, c-format msgid "logical replication target relation \"%s.%s\" is not a table" msgstr "la relazione di destinazione per la replica logica \"%s.%s\" non è una tabella" @@ -11061,44 +11410,44 @@ msgstr "la relazione di destinazione per la replica logica \"%s.%s\" non è una msgid "rows returned by function are not all of the same row type" msgstr "le righe restituite dalla funzione non sono tutte dello stesso tipo" -#: executor/execSRF.c:356 executor/execSRF.c:620 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "il protocollo tabella-funzione del modo di materializzazione non è stato seguito" -#: executor/execSRF.c:363 executor/execSRF.c:638 +#: executor/execSRF.c:363 executor/execSRF.c:665 #, c-format msgid "unrecognized table-function returnMode: %d" msgstr "returnMode tabella-funzione sconosciuto: %d" -#: executor/execSRF.c:843 +#: executor/execSRF.c:871 #, c-format msgid "function returning setof record called in context that cannot accept type record" msgstr "funzione che restituisce un insieme di record invocata in un contesto che non accetta il tipo record" -#: executor/execSRF.c:898 executor/execSRF.c:914 executor/execSRF.c:924 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format msgid "function return row and query-specified return row do not match" msgstr "il tipo di riga restituito dalla funzione e il valore specificato dalla query non combaciano" -#: executor/execSRF.c:899 +#: executor/execSRF.c:927 #, c-format msgid "Returned row contains %d attribute, but query expects %d." msgid_plural "Returned row contains %d attributes, but query expects %d." msgstr[0] "La riga restituita contiene %d attributo, ma la query ne prevede %d." msgstr[1] "La riga restituita contiene %d attributi, ma la query ne prevede %d." -#: executor/execSRF.c:915 +#: executor/execSRF.c:943 #, c-format msgid "Returned type %s at ordinal position %d, but query expects %s." msgstr "Tipo %s restituito in posizione %d, ma la query prevede %s." -#: executor/execUtils.c:639 +#: executor/execUtils.c:687 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "la vista materializzata \"%s\" non è stata popolata" -#: executor/execUtils.c:641 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Usa il comando REFRESH MATERIALIZED VIEW." @@ -11108,273 +11457,313 @@ msgstr "Usa il comando REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "non è stato possibile determinare il tipo reale dell'argomento dichiarato %s" -#: executor/functions.c:519 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "non è possibile usare COPY da o verso il client in una funzione SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:525 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s non è consentito in una funzione SQL" #. translator: %s is a SQL statement name -#: executor/functions.c:533 executor/spi.c:1282 executor/spi.c:2069 +#: executor/functions.c:535 executor/spi.c:1409 executor/spi.c:2199 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s non è consentito in una funzione non volatile" -#: executor/functions.c:653 +#: executor/functions.c:656 #, c-format msgid "could not determine actual result type for function declared to return type %s" msgstr "non è stato possibile determinare il tipo reale restituito dalla funzione dichiarata con tipo restituito %s" -#: executor/functions.c:1412 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "funzione SQL \"%s\" istruzione %d" -#: executor/functions.c:1438 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "funzione SQL \"%s\" durante l'avvio" -#: executor/functions.c:1596 executor/functions.c:1633 -#: executor/functions.c:1645 executor/functions.c:1758 -#: executor/functions.c:1791 executor/functions.c:1821 +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "l'esecuzione di procedure con argomenti di output non è supportata in funzioni SQL" + +#: executor/functions.c:1657 executor/functions.c:1690 +#: executor/functions.c:1702 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "il tipo restituito non combacia nella funzione dichiarata con tipo restituito %s" -#: executor/functions.c:1598 +#: executor/functions.c:1659 #, c-format msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." msgstr "L'istruzione finale della funzione deve essere SELECT oppure INSERT/UPDATE/DELETE RETURNING." -#: executor/functions.c:1635 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." msgstr "L'istruzione finale deve restituire esattamente una colonna." -#: executor/functions.c:1647 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." msgstr "Il tipo restituito realmente è %s." -#: executor/functions.c:1760 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "L'istruzione finale restituisce troppe colonne." -#: executor/functions.c:1793 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "L'istruzione finale restituisce %s invece di %s alla colonna %d." -#: executor/functions.c:1823 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "L'istruzione finale restituisce troppe poche colonne." -#: executor/functions.c:1872 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "il tipo di risultato %s non è supportato per le funzioni SQL" -#: executor/nodeAgg.c:3471 +#: executor/nodeAgg.c:2802 parser/parse_agg.c:633 parser/parse_agg.c:663 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "la funzione di combinazione per l'aggregato %u deve essere dichiarata STRICT" +msgid "aggregate function calls cannot be nested" +msgstr "le chiamate a funzioni di aggregazione non possono essere annidate" -#: executor/nodeAgg.c:3516 executor/nodeWindowAgg.c:2278 +#: executor/nodeAgg.c:2988 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "l'aggregato %u deve avere tipi di input e transizione compatibili" -#: executor/nodeAgg.c:3570 parser/parse_agg.c:618 parser/parse_agg.c:648 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "le chiamate a funzioni di aggregazione non possono essere annidate" - -#: executor/nodeCustom.c:142 executor/nodeCustom.c:153 +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "-lo scan personalizzato \"%s\" non supporta MarkPos" -#: executor/nodeHashjoin.c:767 executor/nodeHashjoin.c:797 +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "riavvolgimento del file temporaneo per l'hash-join fallito: %m" -#: executor/nodeHashjoin.c:832 executor/nodeHashjoin.c:838 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "scrittura nel file temporaneo per l'hash-join fallita: %m" -#: executor/nodeHashjoin.c:879 executor/nodeHashjoin.c:889 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "lettura dal file temporaneo per l'hash-join fallita: %m" -#: executor/nodeIndexonlyscan.c:233 +#: executor/nodeIndexonlyscan.c:236 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "le funzioni di distanza lossy non sono supportate nelle scansioni dei soli indici" -#: executor/nodeLimit.c:252 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET non può essere negativo" -#: executor/nodeLimit.c:278 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT non può essere negativo" -#: executor/nodeMergejoin.c:1554 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOIN è supportato solo con condizioni di join che supportano merge" -#: executor/nodeMergejoin.c:1574 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOIN è supportato solo con condizioni di join che supportano merge" -#: executor/nodeModifyTable.c:97 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "La query ha troppe colonne." -#: executor/nodeModifyTable.c:124 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "La query produce un valore per una colonna eliminata in posizione %d." -#: executor/nodeModifyTable.c:132 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." msgstr "La query ha troppe poche colonne." -#: executor/nodeModifyTable.c:1201 +#: executor/nodeModifyTable.c:773 +#, c-format +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "la tupla da cancellare era stata già mossa in un'altra partizione a causa di una modifica concorrente" + +#: executor/nodeModifyTable.c:1085 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "specifica ON UPDATE non valida" + +#: executor/nodeModifyTable.c:1086 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "La tupla risultato apparterrebbe ad una partizione diversa della tupla originale." + +#: executor/nodeModifyTable.c:1261 +#, c-format +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "la tupla da modificare era stata già mossa in un'altra partizione a causa di una modifica concorrente" + +#: executor/nodeModifyTable.c:1412 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "il comando ON CONFLICT DO UPDATE non può toccare le righe una seconda volta" -#: executor/nodeModifyTable.c:1202 +#: executor/nodeModifyTable.c:1413 #, c-format msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "Assicurati che non ci siano righe proposte per l'inserimento nello stesso comando che abbiano valori vincolati uguali." -#: executor/nodeSamplescan.c:298 +#: executor/nodeSamplescan.c:279 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "il parametro TABLESAMPLE non può essere null" -#: executor/nodeSamplescan.c:310 +#: executor/nodeSamplescan.c:291 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "il parametro TABLESAMPLE REPEATABLE non può essere null" -#: executor/nodeSubplan.c:333 executor/nodeSubplan.c:372 -#: executor/nodeSubplan.c:1004 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1127 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "più di una riga restituita da una sottoquery usata come espressione" -#: executor/nodeTableFuncscan.c:365 +#: executor/nodeTableFuncscan.c:375 #, c-format msgid "namespace URI must not be null" msgstr "l'URI del namespace non può essere nullo" -#: executor/nodeTableFuncscan.c:376 +#: executor/nodeTableFuncscan.c:389 #, c-format msgid "row filter expression must not be null" msgstr "l'espressione di filtro della riga non può essere null" -#: executor/nodeTableFuncscan.c:401 +#: executor/nodeTableFuncscan.c:415 #, c-format msgid "column filter expression must not be null" msgstr "l'espressione del filtro di colonna non può essere null" -#: executor/nodeTableFuncscan.c:402 +#: executor/nodeTableFuncscan.c:416 #, c-format msgid "Filter for column \"%s\" is null." msgstr "Il filtro per la colonna \"%s\" è null." -#: executor/nodeTableFuncscan.c:481 +#: executor/nodeTableFuncscan.c:506 #, c-format msgid "null is not allowed in column \"%s\"" msgstr "null non ammessi nella colonna \"%s\"" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeWindowAgg.c:355 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "le funzioni di transizione per aggregati mobili non possono restituire null" -#: executor/nodeWindowAgg.c:1621 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "l'offset di inizio della finestra dev'essere non nullo" -#: executor/nodeWindowAgg.c:1634 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "l'offset di inizio della finestra non può essere negativo" -#: executor/nodeWindowAgg.c:1646 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "l'offset di fine della finestra dev'essere non nullo" -#: executor/nodeWindowAgg.c:1659 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "l'offset di fine della finestra non può essere negativo" -#: executor/spi.c:197 +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "la funzione di aggregazione %s non consente l'uso come funzione finestra" + +#: executor/spi.c:233 executor/spi.c:272 +#, c-format +msgid "invalid transaction termination" +msgstr "terminazione di transazione non valida" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "non è possibile effettuare un COMMIT mentre è attiva una sotto-transazione" + +#: executor/spi.c:278 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "non è possibile effettuare un ROLLBACK mentre è attiva una sotto-transazione" + +#: executor/spi.c:317 #, c-format msgid "transaction left non-empty SPI stack" msgstr "la transazione ha lasciato lo stack SPI non vuoto" -#: executor/spi.c:198 executor/spi.c:261 +#: executor/spi.c:318 executor/spi.c:381 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "Verifica che non ci siano chiamate \"SPI_finish\" mancanti." -#: executor/spi.c:260 +#: executor/spi.c:380 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "la sottotransazione ha lasciato lo stack SPI non vuoto" -#: executor/spi.c:1143 +#: executor/spi.c:1270 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "non è possibile aprire un piano multi-query come cursore" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1148 +#: executor/spi.c:1275 #, c-format msgid "cannot open %s query as cursor" msgstr "non è possibile aprire una query %s come cursore" -#: executor/spi.c:1253 +#: executor/spi.c:1380 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE non è supportato" -#: executor/spi.c:1254 parser/analyze.c:2447 +#: executor/spi.c:1381 parser/analyze.c:2474 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Un cursore scorribile dev'essere READ ONLY." -#: executor/spi.c:2374 +#: executor/spi.c:2521 #, c-format msgid "SQL statement \"%s\"" msgstr "istruzione SQL \"%s\"" -#: executor/tqueue.c:317 +#: executor/tqueue.c:70 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "invio delle tuple alla coda in memoria condivisa fallito" @@ -11394,855 +11783,962 @@ msgstr "opzione \"%s\" non valida" msgid "Valid options in this context are: %s" msgstr "Le opzioni valide in questo contesto sono: %s" -#: lib/stringinfo.c:259 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 +#: utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "accesso al file \"%s\" fallito: %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "tempo per l'inline: %.3fs, ottimizzazione: %.3fs, emissione: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:715 utils/mmgr/dsa.c:797 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Errore su richiesta DSA di dimensione %zu." + +#: lib/stringinfo.c:278 #, c-format msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." msgstr "Non è possibile aumentare il buffer della stringa contenente %d byte di altri %d byte." -#: libpq/auth-scram.c:208 +#: libpq/auth-scram.c:251 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "il client a selezionato un meccanismo di autenticazione SASL non valido" + +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "verifica SCRAM non valido per l'utente \"%s\"" + +#: libpq/auth-scram.c:283 #, c-format msgid "User \"%s\" does not have a valid SCRAM verifier." msgstr "L'utente \"%s\" non ha una verifica SCRAM valida." -#: libpq/auth-scram.c:286 +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 +#: libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 +#: libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 +#: libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 +#: libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 +#, c-format +msgid "malformed SCRAM message" +msgstr "messaggio SCRAM malformato" + +#: libpq/auth-scram.c:362 +#, c-format +msgid "The message is empty." +msgstr "Il messaggio è vuoto." + +#: libpq/auth-scram.c:367 #, c-format -msgid "malformed SCRAM message (empty message)" -msgstr "messaggio SCRAM malformato (messaggio vuoto)" +msgid "Message length does not match input length." +msgstr "La lunghezza del messaggio non combacia con la lunghezza dell'input." -#: libpq/auth-scram.c:290 +#: libpq/auth-scram.c:399 #, c-format -msgid "malformed SCRAM message (length mismatch)" -msgstr "messaggio SCRAM malformato (la lunghezza non combacia)" +msgid "invalid SCRAM response" +msgstr "risposta SCRAM non valida" -#: libpq/auth-scram.c:322 +#: libpq/auth-scram.c:400 #, c-format -msgid "invalid SCRAM response (nonce mismatch)" -msgstr "risposta SCRAM non valida (il nonce non combacia)" +msgid "Nonce does not match." +msgstr "Il nonce non combacia." -#: libpq/auth-scram.c:397 +#: libpq/auth-scram.c:474 #, c-format msgid "could not generate random salt" msgstr "errore nella generazione del sale casuale" -#: libpq/auth-scram.c:585 +#: libpq/auth-scram.c:661 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "Atteso attributo \"%c\" ma trovato \"%s\"." + +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "Atteso carattere \"=\" per l'attributo \"%c\"." + +#: libpq/auth-scram.c:780 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Atteso attributo, ma trovato carattere non valido \"%s\"." + +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "Il client ha scelto SCRAM-SHA-256-PLUS, ma il messaggio di SCRAM non include dati di binding del canale." + +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 #, c-format -msgid "malformed SCRAM message (attribute '%c' expected, %s found)" -msgstr "messaggio SCRAM non valido (previsto attributo '%c', trovato %s)" +msgid "Comma expected, but found character \"%s\"." +msgstr "Attesa virgola, ma trovato carattere \"%s\"." -#: libpq/auth-scram.c:592 libpq/auth-scram.c:681 +#: libpq/auth-scram.c:926 #, c-format -msgid "malformed SCRAM message (expected = in attr %c)" -msgstr "messaggio SCRAM non valido (previsto = in attributo '%c')" +msgid "SCRAM channel binding negotiation error" +msgstr "errore di negoziazione del binding del canale SCRAM" -#: libpq/auth-scram.c:672 +#: libpq/auth-scram.c:927 #, c-format -msgid "malformed SCRAM message (attribute expected, invalid char %s found)" -msgstr "messaggio SCRAM non valido (previsto attributo, trovato carattere non valido %s)" +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "Il client supporta il binding del canale SCRAM ma pensa che il server non lo supporti. Invece, questo server supporta il binding del canale." -#: libpq/auth-scram.c:794 +#: libpq/auth-scram.c:949 #, c-format -msgid "client requires SCRAM channel binding, but it is not supported" -msgstr "il client richiede il binding del canale SCRAM, ma non è supportato" +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "Il client ha scelto SCRAM-SHA-256 senza binding del canale, ma il messaggio SCRAM include dati di binding del canale." -#: libpq/auth-scram.c:798 +#: libpq/auth-scram.c:960 #, c-format -msgid "malformed SCRAM message (unexpected channel-binding flag %s)" -msgstr "messaggio SCRAM non valido (flag di channel-binding %s non previsto)" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "tipo di binding di canale SCRAM \"%s\" non supportato" -#: libpq/auth-scram.c:804 +#: libpq/auth-scram.c:967 #, c-format -msgid "malformed SCRAM message (comma expected, got %s)" -msgstr "messaggio SCRAM non valido (prevista virgola, ricevuto %s)" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Flag channel-binding \"%s\" non previsto." -#: libpq/auth-scram.c:814 +#: libpq/auth-scram.c:977 #, c-format msgid "client uses authorization identity, but it is not supported" msgstr "il client usa l'autorizzazione identità, ma non è supportata" -#: libpq/auth-scram.c:818 +#: libpq/auth-scram.c:982 #, c-format -msgid "malformed SCRAM message (unexpected attribute %s in client-first-message)" -msgstr "messaggio SCRAM non valido (attributo '%s' non previsto nel primo messaggio client)" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Attributo \"%s\" non atteso nel client-first-message." -#: libpq/auth-scram.c:834 +#: libpq/auth-scram.c:998 #, c-format -msgid "client requires mandatory SCRAM extension" -msgstr "il client richiede l'estensione SCRAM obbligatoria" +msgid "client requires an unsupported SCRAM extension" +msgstr "il client richiede un'estensione SCRAM non supportata" -#: libpq/auth-scram.c:848 +#: libpq/auth-scram.c:1012 #, c-format msgid "non-printable characters in SCRAM nonce" msgstr "caratteri non stampabili nel nonce SCRAM" -#: libpq/auth-scram.c:965 +#: libpq/auth-scram.c:1129 #, c-format msgid "could not generate random nonce" msgstr "errore nella generazione del nonce SCRAM" -#: libpq/auth-scram.c:1033 +#: libpq/auth-scram.c:1233 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "controllo di binding del canale SCRAM fallito" + +#: libpq/auth-scram.c:1251 #, c-format msgid "unexpected SCRAM channel-binding attribute in client-final-message" msgstr "attributo channel-binding SCRAM non previsto nel messaggio finale del client" -#: libpq/auth-scram.c:1047 +#: libpq/auth-scram.c:1268 #, c-format -msgid "malformed SCRAM message (malformed proof in client-final-message" -msgstr "messaggio SCRAM non valido (prova errata nel messaggio finale del client)" +msgid "Malformed proof in client-final-message." +msgstr "Verifica malformata in client-final-message." -#: libpq/auth-scram.c:1054 +#: libpq/auth-scram.c:1276 #, c-format -msgid "malformed SCRAM message (garbage at end of client-final-message)" -msgstr "messaggio SCRAM non valido (dati in eccesso alla fine del messaggio finale del client)" +msgid "Garbage found at the end of client-final-message." +msgstr "Dati spuri alla fine del client-final-message." -#: libpq/auth.c:274 +#: libpq/auth.c:282 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "autenticazione fallita per l'utente \"%s\": host rifiutato" -#: libpq/auth.c:277 +#: libpq/auth.c:285 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "autenticazione \"trust\" fallita per l'utente \"%s\"" -#: libpq/auth.c:280 +#: libpq/auth.c:288 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "autenticazione Ident fallita per l'utente \"%s\"" -#: libpq/auth.c:283 +#: libpq/auth.c:291 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "autenticazione Peer fallita per l'utente \"%s\"" -#: libpq/auth.c:288 +#: libpq/auth.c:296 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "autenticazione con password fallita per l'utente \"%s\"" -#: libpq/auth.c:293 +#: libpq/auth.c:301 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "autenticazione GSSAPI fallita per l'utente \"%s\"" -#: libpq/auth.c:296 +#: libpq/auth.c:304 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "autenticazione SSPI fallita per l'utente \"%s\"" -#: libpq/auth.c:299 +#: libpq/auth.c:307 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "autenticazione PAM fallita per l'utente \"%s\"" -#: libpq/auth.c:302 +#: libpq/auth.c:310 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "autenticazione BSD fallita per l'utente \"%s\"" -#: libpq/auth.c:305 +#: libpq/auth.c:313 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "autenticazione LDAP fallita per l'utente \"%s\"" -#: libpq/auth.c:308 +#: libpq/auth.c:316 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "autenticazione con certificato fallita per l'utente \"%s\"" -#: libpq/auth.c:311 +#: libpq/auth.c:319 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "autenticazione RADIUS fallita per l'utente \"%s\"" -#: libpq/auth.c:314 +#: libpq/auth.c:322 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "autenticazione fallita per l'utente \"%s\": metodo di autenticazione non valido" -#: libpq/auth.c:318 +#: libpq/auth.c:326 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "La connessione si abbina con la riga %d di pg_hba.log: \"%s\"" -#: libpq/auth.c:365 +#: libpq/auth.c:373 #, c-format msgid "client certificates can only be checked if a root certificate store is available" msgstr "il certificato del client può essere controllato solo se un root certificate store è disponibile" -#: libpq/auth.c:376 +#: libpq/auth.c:384 #, c-format msgid "connection requires a valid client certificate" msgstr "la connessione richiede un certificato valido per il client" -#: libpq/auth.c:409 +#: libpq/auth.c:417 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf rifiuta connessioni di replica per l'host \"%s\", utente \"%s\", %s" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL off" msgstr "SSL non abilitato" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL on" msgstr "SSL abilitato" -#: libpq/auth.c:415 +#: libpq/auth.c:423 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "pg_hba.conf rifiuta connessioni di replica per l'host \"%s\", utente \"%s\"" -#: libpq/auth.c:424 +#: libpq/auth.c:432 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf rifiuta connessioni per l'host \"%s\", utente \"%s\", database \"%s\", %s" -#: libpq/auth.c:431 +#: libpq/auth.c:439 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" msgstr "pg_hba.conf rifiuta connessioni per l'host \"%s\", user \"%s\", database \"%s\"" -#: libpq/auth.c:460 +#: libpq/auth.c:468 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "Indirizzo IP del client risolto in \"%s\", il forward lookup combacia." -#: libpq/auth.c:463 +#: libpq/auth.c:471 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "Indirizzo IP del client risolto in \"%s\", forward lookup non controllato." -#: libpq/auth.c:466 +#: libpq/auth.c:474 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "Indirizzo IP del client risolto in \"%s\", il forward lookup non combacia." -#: libpq/auth.c:469 +#: libpq/auth.c:477 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "Conversione del nome host \"%s\" in indirizzo IP non riuscita: %s." -#: libpq/auth.c:474 +#: libpq/auth.c:482 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "Risoluzione dell'indirizzo IP del client in nome host non riuscita: %s." -#: libpq/auth.c:483 +#: libpq/auth.c:491 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "nessuna voce in pg_hba.conf per connessioni di replica da host \"%s\", utente \"%s\", database \"%s\"" -#: libpq/auth.c:490 +#: libpq/auth.c:498 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" msgstr "nessuna voce in pg_hba.conf per connessioni di replica da host \"%s\", user \"%s\"" -#: libpq/auth.c:500 +#: libpq/auth.c:508 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "nessuna voce in pg_hba.conf per l'host \"%s\", utente \"%s\", database \"%s\", %s" -#: libpq/auth.c:508 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "nessuna voce in pg_hba.conf per l'host \"%s\", utente \"%s\", database \"%s\"" -#: libpq/auth.c:661 +#: libpq/auth.c:669 #, c-format msgid "expected password response, got message type %d" msgstr "era attesa una risposta password, ricevuto messaggio di tipo %d" -#: libpq/auth.c:689 +#: libpq/auth.c:697 #, c-format msgid "invalid password packet size" msgstr "dimensione del pacchetto password non valida" -#: libpq/auth.c:809 libpq/hba.c:1325 +#: libpq/auth.c:715 +#, c-format +msgid "empty password returned by client" +msgstr "il client ha restituito una password vuota" + +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" msgstr "l'autenticazione MD5 non è supportata quando \"db_user_namespace\" è abilitato" -#: libpq/auth.c:815 +#: libpq/auth.c:841 #, c-format msgid "could not generate random MD5 salt" msgstr "errore nella generazione del sale casuale MD5" -#: libpq/auth.c:860 +#: libpq/auth.c:887 #, c-format msgid "SASL authentication is not supported in protocol version 2" msgstr "l'autenticazione SASL non è supportata nella versione 2 del protocollo" -#: libpq/auth.c:902 +#: libpq/auth.c:920 #, c-format msgid "expected SASL response, got message type %d" msgstr "attesa risposta SASL, ricevuto messaggio di tipo %d" -#: libpq/auth.c:939 -#, c-format -msgid "client selected an invalid SASL authentication mechanism" -msgstr "il client a selezionato un meccanismo di autenticazione SASL non valido" - -#: libpq/auth.c:1085 +#: libpq/auth.c:1112 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "GSSAPI non è supportato con la versione 2 del protocollo" -#: libpq/auth.c:1145 +#: libpq/auth.c:1172 #, c-format msgid "expected GSS response, got message type %d" msgstr "era attesa una risposta GSS, ricevuto messaggio di tipo %d" -#: libpq/auth.c:1207 +#: libpq/auth.c:1234 msgid "accepting GSS security context failed" msgstr "contesto di sicurezza accettazione GSS fallito" -#: libpq/auth.c:1233 +#: libpq/auth.c:1260 msgid "retrieving GSS user name failed" msgstr "la richiesta del GSS user name è fallita" -#: libpq/auth.c:1352 +#: libpq/auth.c:1385 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "SSPI non è supportato con la versione 2 del protocollo" -#: libpq/auth.c:1367 +#: libpq/auth.c:1400 msgid "could not acquire SSPI credentials" msgstr "non è stato possibile ottenere le credenziali SSPI" -#: libpq/auth.c:1385 +#: libpq/auth.c:1418 #, c-format msgid "expected SSPI response, got message type %d" msgstr "era attesa una risposta SSPI, ricevuto messaggio di tipo %d" -#: libpq/auth.c:1458 +#: libpq/auth.c:1491 msgid "could not accept SSPI security context" msgstr "non è stato possibile accettare il contesto di sicurezza SSPI" -#: libpq/auth.c:1520 +#: libpq/auth.c:1553 msgid "could not get token from SSPI security context" msgstr "non è stato possibile ottenere il token dal contesto di sicurezza SSPI" -#: libpq/auth.c:1639 libpq/auth.c:1658 +#: libpq/auth.c:1672 libpq/auth.c:1691 #, c-format msgid "could not translate name" msgstr "non è stato possibile tradurre il nome" -#: libpq/auth.c:1671 +#: libpq/auth.c:1704 #, c-format msgid "realm name too long" msgstr "nome di realm troppo lungo" -#: libpq/auth.c:1686 +#: libpq/auth.c:1719 #, c-format msgid "translated account name too long" msgstr "nome di account tradotto troppo lungo" -#: libpq/auth.c:1872 +#: libpq/auth.c:1905 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "creazione del socket per la connessione Ident fallita: %m" -#: libpq/auth.c:1887 +#: libpq/auth.c:1920 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "bind sull'indirizzo locale \"%s\" fallito: %m" -#: libpq/auth.c:1899 +#: libpq/auth.c:1932 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "connessione al server Ident all'indirizzo \"%s\", porta %s fallita: %m" -#: libpq/auth.c:1921 +#: libpq/auth.c:1954 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "invio della query al server Ident all'indirizzo \"%s\", porta %s fallito: %m" -#: libpq/auth.c:1938 +#: libpq/auth.c:1971 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "ricezione della risposta dal server Ident all'indirizzo \"%s\", porta %s fallita: %m" -#: libpq/auth.c:1948 +#: libpq/auth.c:1981 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "risposta dal server Ident formattata in maniera non corretta: \"%s\"" -#: libpq/auth.c:1988 +#: libpq/auth.c:2021 #, c-format msgid "peer authentication is not supported on this platform" msgstr "il metodo di autenticazione peer non è supportato su questa piattaforma" -#: libpq/auth.c:1992 +#: libpq/auth.c:2025 #, c-format msgid "could not get peer credentials: %m" msgstr "non è stato possibile recuperare le credenziali del peer: %m" -#: libpq/auth.c:2001 +#: libpq/auth.c:2036 #, c-format msgid "could not look up local user ID %ld: %s" msgstr "ricerca dell'ID utente locale %ld fallita: %s" -#: libpq/auth.c:2085 libpq/auth.c:2411 libpq/auth.c:2724 -#, c-format -msgid "empty password returned by client" -msgstr "il client ha restituito una password vuota" - -#: libpq/auth.c:2095 +#: libpq/auth.c:2124 #, c-format msgid "error from underlying PAM layer: %s" msgstr "errore dal livello PAM sottostante: %s" -#: libpq/auth.c:2176 +#: libpq/auth.c:2205 #, c-format msgid "could not create PAM authenticator: %s" msgstr "creazione dell'autenticatore PAM fallita: %s" -#: libpq/auth.c:2187 +#: libpq/auth.c:2216 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER) fallita: %s" -#: libpq/auth.c:2198 +#: libpq/auth.c:2227 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST) fallita: %s" -#: libpq/auth.c:2209 +#: libpq/auth.c:2238 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "pam_set_item(PAM_CONV) fallita: %s" -#: libpq/auth.c:2220 +#: libpq/auth.c:2249 #, c-format msgid "pam_authenticate failed: %s" msgstr "pam_authenticate fallita: %s" -#: libpq/auth.c:2231 +#: libpq/auth.c:2260 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmt fallita: %s" -#: libpq/auth.c:2242 +#: libpq/auth.c:2271 #, c-format msgid "could not release PAM authenticator: %s" msgstr "rilascio dell'autenticatore PAM fallito: %s" -#: libpq/auth.c:2307 -#, c-format -msgid "could not initialize LDAP: %m" -msgstr "inizializzazione LDAP fallita: %m" - -#: libpq/auth.c:2310 +#: libpq/auth.c:2347 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "inizializzazione LDAP fallita: codice errore %d" -#: libpq/auth.c:2320 +#: libpq/auth.c:2364 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "inizializzazione LDAP fallita: %s" + +#: libpq/auth.c:2374 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ldaps non supportato con questa libreria LDAP" + +#: libpq/auth.c:2382 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "inizializzazione LDAP fallita: %m" + +#: libpq/auth.c:2392 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "impostazione della versione del protocollo LDAP fallita: %s" -#: libpq/auth.c:2349 +#: libpq/auth.c:2423 #, c-format msgid "could not load wldap32.dll" msgstr "caricamento wldap32.dll fallito" -#: libpq/auth.c:2357 +#: libpq/auth.c:2431 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "caricamento della funzione _ldap_start_tls_sA in wldap32.dll fallito" -#: libpq/auth.c:2358 +#: libpq/auth.c:2432 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "LDAP su SSL non è supportato su questa piattaforma." -#: libpq/auth.c:2373 +#: libpq/auth.c:2447 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "avvio della sessione TLS LDAP fallito: %s" -#: libpq/auth.c:2395 +#: libpq/auth.c:2510 #, c-format msgid "LDAP server not specified" msgstr "server LDAP non specificato" -#: libpq/auth.c:2448 +#: libpq/auth.c:2565 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "carattere non valido nel nome utente per l'autenticazione LDAP" -#: libpq/auth.c:2463 +#: libpq/auth.c:2582 #, c-format msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "bind iniziale LDAP fallito per ldapbinddn \"%s\" sul server \"%s\": %s" -#: libpq/auth.c:2487 +#: libpq/auth.c:2611 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "ricerca in LDAP del filtro \"%s\" sul server \"%s\" fallita: %s" -#: libpq/auth.c:2498 +#: libpq/auth.c:2625 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "l'utente LDAP \"%s\" non esiste" -#: libpq/auth.c:2499 +#: libpq/auth.c:2626 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "La ricerca LDAP del filtro \"%s\" sul server \"%s\" non ha restituito risultati." -#: libpq/auth.c:2503 +#: libpq/auth.c:2630 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "L'utente LDAP \"%s\" non è unico" -#: libpq/auth.c:2504 +#: libpq/auth.c:2631 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "La ricerca LDAP del filtro \"%s\" sul server \"%s\" ha restituito %d risultato." msgstr[1] "La ricerca LDAP del filtro \"%s\" sul server \"%s\" ha restituito %d risultati." -#: libpq/auth.c:2522 +#: libpq/auth.c:2651 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "dn per il primo risultato di \"%s\" non trovato sul server \"%s\": %s" -#: libpq/auth.c:2542 +#: libpq/auth.c:2672 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "unbind fallito dopo aver cercato l'utente \"%s\" sul server \"%s\": %s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "unbinding fallito dopo aver cercato l'utente \"%s\" sul server \"%s\"" -#: libpq/auth.c:2572 +#: libpq/auth.c:2703 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "login LDAP fallito per l'utente \"%s\" sul server \"%s\": %s" -#: libpq/auth.c:2600 +#: libpq/auth.c:2732 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "diagnostica LDAP: %s" + +#: libpq/auth.c:2757 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "autenticazione con certificato fallita per l'utente \"%s\": il certificato del client non contiene alcun nome utente" -#: libpq/auth.c:2703 +#: libpq/auth.c:2860 #, c-format msgid "RADIUS server not specified" msgstr "server RADIUS non specificato" -#: libpq/auth.c:2710 +#: libpq/auth.c:2867 #, c-format msgid "RADIUS secret not specified" msgstr "segreto RADIUS non specificato" -#: libpq/auth.c:2731 +#: libpq/auth.c:2881 #, c-format msgid "RADIUS authentication does not support passwords longer than %d characters" msgstr "l'autenticazione RADIUS non supporta password più lunghe di %d caratteri" -#: libpq/auth.c:2828 libpq/hba.c:1876 +#: libpq/auth.c:2986 libpq/hba.c:1908 #, c-format msgid "could not translate RADIUS server name \"%s\" to address: %s" msgstr "conversione del nome del server RADIUS \"%s\" in indirizzo fallita: %s" -#: libpq/auth.c:2842 +#: libpq/auth.c:3000 #, c-format msgid "could not generate random encryption vector" msgstr "generazione del vettore di criptaggio casuale fallita" -#: libpq/auth.c:2876 +#: libpq/auth.c:3034 #, c-format msgid "could not perform MD5 encryption of password" msgstr "criptaggio MD5 della password fallito" -#: libpq/auth.c:2902 +#: libpq/auth.c:3060 #, c-format msgid "could not create RADIUS socket: %m" msgstr "creazione del socket RADIUS fallita: %m" -#: libpq/auth.c:2924 +#: libpq/auth.c:3082 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "bind del socket RADIUS fallito: %m" -#: libpq/auth.c:2934 +#: libpq/auth.c:3092 #, c-format msgid "could not send RADIUS packet: %m" msgstr "invio del pacchetto RADIUS fallito: %m" -#: libpq/auth.c:2967 libpq/auth.c:2993 +#: libpq/auth.c:3125 libpq/auth.c:3151 #, c-format msgid "timeout waiting for RADIUS response from %s" msgstr "timeout in attesa della risposta RADIUS da %s" -#: libpq/auth.c:2986 +#: libpq/auth.c:3144 #, c-format msgid "could not check status on RADIUS socket: %m" msgstr "controllo dello stato sul socket RADIUS fallito: %m" -#: libpq/auth.c:3016 +#: libpq/auth.c:3174 #, c-format msgid "could not read RADIUS response: %m" msgstr "lettura della risposta RADIUS fallita: %m" -#: libpq/auth.c:3029 libpq/auth.c:3033 +#: libpq/auth.c:3187 libpq/auth.c:3191 #, c-format msgid "RADIUS response from %s was sent from incorrect port: %d" msgstr "la risposta RADIUS da %s è stata inviata da una porta non valida: %d" -#: libpq/auth.c:3042 +#: libpq/auth.c:3200 #, c-format msgid "RADIUS response from %s too short: %d" msgstr "risposta RADIUS da %s troppo breve: %d" -#: libpq/auth.c:3049 +#: libpq/auth.c:3207 #, c-format msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" msgstr "la risposta RADIUS da %s ha una lunghezza non valida: %d (la lunghezza reale è %d)" -#: libpq/auth.c:3057 +#: libpq/auth.c:3215 #, c-format msgid "RADIUS response from %s is to a different request: %d (should be %d)" msgstr "la risposta RADIUS da %s è di una richiesta diversa: %d (dovrebbe essere %d)" -#: libpq/auth.c:3082 +#: libpq/auth.c:3240 #, c-format msgid "could not perform MD5 encryption of received packet" msgstr "criptaggio MD5 dei pacchetti ricevuti fallito" -#: libpq/auth.c:3091 +#: libpq/auth.c:3249 #, c-format msgid "RADIUS response from %s has incorrect MD5 signature" msgstr "la risposta RADIUS da %s ha una firma MD5 non valida" -#: libpq/auth.c:3109 +#: libpq/auth.c:3267 #, c-format msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" msgstr "La risposta RADIUS da %s ha un codice non valido (%d) per l'utente \"%s\"" -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 -#: libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 -#: libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format msgid "invalid large-object descriptor: %d" msgstr "descrittore di large object non valido: %d" -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 -#: libpq/be-fsstubs.c:788 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "permesso per il large object %u negato" +msgid "large object descriptor %d was not opened for reading" +msgstr "il descrittore per il large object %d non era aperto in lettura" -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format msgid "large object descriptor %d was not opened for writing" msgstr "il descrittore per il large object %d non era aperto in scrittura" -#: libpq/be-fsstubs.c:245 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "il risultato di lo_lseek è fuori dall'intervallo consentito per il descrittore di large object %d" -#: libpq/be-fsstubs.c:318 +#: libpq/be-fsstubs.c:285 #, c-format msgid "lo_tell result out of range for large-object descriptor %d" msgstr "il risultato di lo_tell è fuori dall'intervallo consentito per il descrittore di large object %d" -#: libpq/be-fsstubs.c:455 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "solo un superutente può usare lo_import() lato server" - -#: libpq/be-fsstubs.c:456 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "Chiunque può invece usare lo_import() lato client fornito da libpq." - -#: libpq/be-fsstubs.c:469 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "apertura del file del server \"%s\" fallita: %m" -#: libpq/be-fsstubs.c:491 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "lettura dal file del server \"%s\" fallita: %m" -#: libpq/be-fsstubs.c:521 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "solo un superutente può usare lo_export() lato server" - -#: libpq/be-fsstubs.c:522 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "Chiunque può invece usare lo_export() lato client fornito da libpq." - -#: libpq/be-fsstubs.c:547 +#: libpq/be-fsstubs.c:511 #, c-format msgid "could not create server file \"%s\": %m" msgstr "creazione del file del server \"%s\" fallita: %m" -#: libpq/be-fsstubs.c:559 +#: libpq/be-fsstubs.c:523 #, c-format msgid "could not write server file \"%s\": %m" msgstr "scrittura del file del server \"%s\" fallita: %m" -#: libpq/be-fsstubs.c:813 +#: libpq/be-fsstubs.c:752 #, c-format msgid "large object read request is too large" msgstr "la richiesta di lettura per il large object è troppo grande" -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:212 utils/adt/genfile.c:253 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 +#: utils/adt/genfile.c:306 #, c-format msgid "requested length cannot be negative" msgstr "la lunghezza richiesta non può essere negativa" -#: libpq/be-secure-openssl.c:197 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 +#: storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 +#: storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "could not create SSL context: %s" -msgstr "creazione del contesto SSL fallita: %s" +msgid "permission denied for large object %u" +msgstr "permesso per il large object %u negato" -#: libpq/be-secure-openssl.c:225 +#: libpq/be-secure-common.c:91 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "caricamento del file di certificato del server \"%s\" fallito: %s" +msgid "could not read from command \"%s\": %m" +msgstr "lettura fallita dal comando \"%s\": %m" + +#: libpq/be-secure-common.c:109 +#, c-format +msgid "command \"%s\" failed" +msgstr "comando \"%s\" fallito" -#: libpq/be-secure-openssl.c:234 +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "accesso fallito al file della chiave privata \"%s\": %m" -#: libpq/be-secure-openssl.c:243 +#: libpq/be-secure-common.c:148 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "il file di chiave privata \"%s\" non è un file regolare" -#: libpq/be-secure-openssl.c:258 +#: libpq/be-secure-common.c:163 #, c-format msgid "private key file \"%s\" must be owned by the database user or root" msgstr "il file di chiave privata \"%s\" deve essere di proprietà dell'utente del database o di root" -#: libpq/be-secure-openssl.c:281 +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" msgstr "il file della chiave privata \"%s\" ha accesso al gruppo o a chiunque" -#: libpq/be-secure-openssl.c:283 +#: libpq/be-secure-common.c:188 #, c-format msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." msgstr "Il file deve avere permesso u=rw (0600) o inferiore se di proprietà dell'utente database, o permesso u=rw,g=r (0640) o inferiore se di proprietà di root." -#: libpq/be-secure-openssl.c:300 +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "creazione del contesto SSL fallita: %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "caricamento del file di certificato del server \"%s\" fallito: %s" + +#: libpq/be-secure-openssl.c:167 #, c-format msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" msgstr "il file della chiave privata \"%s\" non può essere ricaricato perché richiede una passphrase" -#: libpq/be-secure-openssl.c:305 +#: libpq/be-secure-openssl.c:172 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "caricamento del file della chiave privata \"%s\" fallito: %s" -#: libpq/be-secure-openssl.c:314 +#: libpq/be-secure-openssl.c:181 #, c-format msgid "check of private key failed: %s" msgstr "controllo della chiave privata fallito: %s" -#: libpq/be-secure-openssl.c:334 +#: libpq/be-secure-openssl.c:208 #, c-format msgid "could not set the cipher list (no valid ciphers available)" msgstr "impostazione della lista dei cifrari fallita (nessun cifrario valido disponibile)" -#: libpq/be-secure-openssl.c:352 +#: libpq/be-secure-openssl.c:226 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "caricamento del file del certificato radice \"%s\" fallito: %s" -#: libpq/be-secure-openssl.c:379 +#: libpq/be-secure-openssl.c:253 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "il file di lista di revoche di certificati SSL \"%s\" è stato ignorato" -#: libpq/be-secure-openssl.c:381 +#: libpq/be-secure-openssl.c:255 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "La libreria SSL non supporta le liste di revoca dei certificati." -#: libpq/be-secure-openssl.c:388 +#: libpq/be-secure-openssl.c:262 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "caricamento del file di lista di revoche di certificati SSL \"%s\" fallito: %s" -#: libpq/be-secure-openssl.c:469 +#: libpq/be-secure-openssl.c:337 #, c-format msgid "could not initialize SSL connection: SSL context not set up" msgstr "inizializzazione della connessione SSL fallita: contesto SSL non impostato" -#: libpq/be-secure-openssl.c:477 +#: libpq/be-secure-openssl.c:345 #, c-format msgid "could not initialize SSL connection: %s" msgstr "inizializzazione della connessione SSL fallita: %s" -#: libpq/be-secure-openssl.c:485 +#: libpq/be-secure-openssl.c:353 #, c-format msgid "could not set SSL socket: %s" msgstr "impostazione del socket SSL fallita: %s" -#: libpq/be-secure-openssl.c:540 +#: libpq/be-secure-openssl.c:408 #, c-format msgid "could not accept SSL connection: %m" msgstr "accettazione della connessione SSL fallita: %m" -#: libpq/be-secure-openssl.c:544 libpq/be-secure-openssl.c:555 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "accettazione della connessione SSL fallita: fine file individuata" -#: libpq/be-secure-openssl.c:549 +#: libpq/be-secure-openssl.c:417 #, c-format msgid "could not accept SSL connection: %s" msgstr "accettazione della connessione SSL fallita: %s" -#: libpq/be-secure-openssl.c:560 libpq/be-secure-openssl.c:699 -#: libpq/be-secure-openssl.c:759 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 +#: libpq/be-secure-openssl.c:623 #, c-format msgid "unrecognized SSL error code: %d" msgstr "codice di errore SSL sconosciuto: %d" -#: libpq/be-secure-openssl.c:602 +#: libpq/be-secure-openssl.c:470 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "Il nome comune del certificato SSL contiene un null" -#: libpq/be-secure-openssl.c:613 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "connessione SSL da \"%s\"" - -#: libpq/be-secure-openssl.c:690 libpq/be-secure-openssl.c:750 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format msgid "SSL error: %s" msgstr "errore SSL: %s" -#: libpq/be-secure-openssl.c:1179 +#: libpq/be-secure-openssl.c:788 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "errore nell'apertura del file di parametri DH \"%s\": %m" + +#: libpq/be-secure-openssl.c:800 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "errore nell'apertura del file di parametri DH: %s" + +#: libpq/be-secure-openssl.c:810 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "parametri DH non validi: %s" + +#: libpq/be-secure-openssl.c:818 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "parametri DH non validi: p non è primo" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "parametri DH non validi: né un generatore adatto o un primo sicuro" + +#: libpq/be-secure-openssl.c:981 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: errore nel caricamento dei parametri DH" + +#: libpq/be-secure-openssl.c:989 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: errore nell'impostazione dei parametri DH: %s" + +#: libpq/be-secure-openssl.c:1013 #, c-format msgid "ECDH: unrecognized curve name: %s" msgstr "ECDH: nome della curva non riconosciuto: %s" -#: libpq/be-secure-openssl.c:1188 +#: libpq/be-secure-openssl.c:1022 #, c-format msgid "ECDH: could not create key" msgstr "ECDH: chiave non creata" -#: libpq/be-secure-openssl.c:1216 +#: libpq/be-secure-openssl.c:1050 msgid "no SSL error reported" msgstr "nessun errore SSL riportato" -#: libpq/be-secure-openssl.c:1220 +#: libpq/be-secure-openssl.c:1054 #, c-format msgid "SSL error code %lu" msgstr "codice di errore SSL: %lu" -#: libpq/be-secure.c:188 libpq/be-secure.c:274 +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "connessione SSL da \"%s\"" + +#: libpq/be-secure.c:193 libpq/be-secure.c:279 #, c-format msgid "terminating connection due to unexpected postmaster exit" msgstr "la connessione è stata terminata a causa di un'uscita inattesa di postmaster" @@ -12257,27 +12753,22 @@ msgstr "Il ruolo \"%s\" non esiste." msgid "User \"%s\" has no password assigned." msgstr "L'utente \"%s\" non ha una password assegnata." -#: libpq/crypt.c:76 -#, c-format -msgid "User \"%s\" has an empty password." -msgstr "Il ruolo \"%s\" ha una password vuota." - -#: libpq/crypt.c:87 +#: libpq/crypt.c:79 #, c-format msgid "User \"%s\" has an expired password." msgstr "L'utente \"%s\" ha la password scaduta." -#: libpq/crypt.c:181 +#: libpq/crypt.c:173 #, c-format msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "L'utente \"%s\" ha una password che non può essere usata con l'autenticazione MD5." -#: libpq/crypt.c:205 libpq/crypt.c:246 libpq/crypt.c:270 +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Le password non combaciano per l'utente \"%s\"." -#: libpq/crypt.c:289 +#: libpq/crypt.c:281 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "La password dell'utente \"%s\" è in un formato non riconosciuto." @@ -12304,11 +12795,11 @@ msgstr "riga del file di autenticazione troppo lunga" #: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 #: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 #: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 -#: libpq/hba.c:1482 libpq/hba.c:1521 libpq/hba.c:1532 libpq/hba.c:1549 -#: libpq/hba.c:1559 libpq/hba.c:1617 libpq/hba.c:1655 libpq/hba.c:1671 -#: libpq/hba.c:1770 libpq/hba.c:1859 libpq/hba.c:1878 libpq/hba.c:1907 -#: libpq/hba.c:1920 libpq/hba.c:1943 libpq/hba.c:1965 libpq/hba.c:1979 -#: tsearch/ts_locale.c:182 +#: libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 +#: libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 +#: libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 +#: libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 +#: libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:179 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "riga %d del file di configurazione \"%s\"" @@ -12484,313 +12975,318 @@ msgstr "l'autenticazione cert è supportata solo su connessioni hostssl" msgid "authentication option not in name=value format: %s" msgstr "opzione di autenticazione non in formato nome=valore: %s" -#: libpq/hba.c:1520 +#: libpq/hba.c:1522 #, c-format -msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix" -msgstr "non si possono usare ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute né ldapurl insieme a ldapprefix" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "non è possibile usare ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter o ldapurl insieme a ldapprefix" -#: libpq/hba.c:1531 +#: libpq/hba.c:1533 #, c-format msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "il metodo di autenticazione \"ldap\" richiede che gli argomenti \"ldapbasedn\", \"ldapprefix\" o \"ldapsuffix\" siano impostati" -#: libpq/hba.c:1548 +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "non è possibile usare ldapsearchattribute insieme a ldapsearchfilter" + +#: libpq/hba.c:1566 #, c-format msgid "list of RADIUS servers cannot be empty" msgstr "la lista di server RADIUS non può essere vuota" -#: libpq/hba.c:1558 +#: libpq/hba.c:1576 #, c-format msgid "list of RADIUS secrets cannot be empty" msgstr "la lista di segreti RADIUS non può essere vuota" -#: libpq/hba.c:1611 +#: libpq/hba.c:1629 #, c-format -msgid "the number of %s (%i) must be 1 or the same as the number of %s (%i)" -msgstr "il numero di %s (%i) deve essere 1 oppure lo stesso numero di %s (%i)" +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "il numero di %s (%d) deve essere 1 oppure lo stesso numero di %s (%d)" -#: libpq/hba.c:1645 +#: libpq/hba.c:1663 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspi e cert" -#: libpq/hba.c:1654 +#: libpq/hba.c:1672 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "il clientcert può essere configurato solo per le righe \"hostssl\"" -#: libpq/hba.c:1670 +#: libpq/hba.c:1688 #, c-format msgid "clientcert can not be set to 0 when using \"cert\" authentication" msgstr "clientcert non può essere impostato a 0 quando si usa l'autenticazione \"cert\"" -#: libpq/hba.c:1707 +#: libpq/hba.c:1725 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "impossibile interpretare la URL LDAP \"%s\": %s" -#: libpq/hba.c:1717 +#: libpq/hba.c:1736 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "schema di URL LDAP non supportato: %s" -#: libpq/hba.c:1735 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "i filtri non sono supportati nelle URL LDAP" - -#: libpq/hba.c:1744 +#: libpq/hba.c:1760 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "URL LDAP non supportate su questa piattaforma" -#: libpq/hba.c:1769 +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "valore ldapscheme non valido: \"%s\"" + +#: libpq/hba.c:1796 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "numero di porta LDAP non valido: \"%s\"" -#: libpq/hba.c:1810 libpq/hba.c:1817 +#: libpq/hba.c:1842 libpq/hba.c:1849 msgid "gssapi and sspi" msgstr "gssapi e sspi" -#: libpq/hba.c:1826 libpq/hba.c:1835 +#: libpq/hba.c:1858 libpq/hba.c:1867 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1857 +#: libpq/hba.c:1889 #, c-format msgid "could not parse RADIUS server list \"%s\"" msgstr "errore nell'interpretazione della lista di server RADIUS \"%s\"" -#: libpq/hba.c:1905 +#: libpq/hba.c:1937 #, c-format msgid "could not parse RADIUS port list \"%s\"" msgstr "errore nell'interpretazione della lista di porte RADIUS \"%s\"" -#: libpq/hba.c:1919 +#: libpq/hba.c:1951 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "numero di porta RADIUS non valido: \"%s\"" -#: libpq/hba.c:1941 +#: libpq/hba.c:1973 #, c-format msgid "could not parse RADIUS secret list \"%s\"" msgstr "errore nell'interpretazione della lista di segreti RADIUS \"%s\"" -#: libpq/hba.c:1963 +#: libpq/hba.c:1995 #, c-format msgid "could not parse RADIUS identifiers list \"%s\"" msgstr "errore nell'interpretazione della lista di identificatori RADIUS \"%s\"" -#: libpq/hba.c:1977 +#: libpq/hba.c:2009 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "nome di opzione di autenticazione sconosciuto: \"%s\"" -#: libpq/hba.c:2110 libpq/hba.c:2510 guc-file.l:593 +#: libpq/hba.c:2142 libpq/hba.c:2547 guc-file.l:596 #, c-format msgid "could not open configuration file \"%s\": %m" msgstr "apertura del file di configurazione \"%s\" fallita: %m" -#: libpq/hba.c:2161 +#: libpq/hba.c:2193 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "il file di configurazione \"%s\" non contiene alcuna voce" -#: libpq/hba.c:2666 +#: libpq/hba.c:2703 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "espressione regolare non valida \"%s\": %s" -#: libpq/hba.c:2726 +#: libpq/hba.c:2763 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "corrispondenza dell'espressione regolare \"%s\" fallita: %s" -#: libpq/hba.c:2745 +#: libpq/hba.c:2782 #, c-format msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" msgstr "l'espressione regolare \"%s\" non ha la sottoespressione richiesta dal riferimento in \"%s\"" -#: libpq/hba.c:2842 +#: libpq/hba.c:2879 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "il nome utente fornito (%s) e il nome utente autenticato (%s) non combaciano" -#: libpq/hba.c:2862 +#: libpq/hba.c:2899 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "nessuna corrispondenza nella mappa utenti \"%s\" per l'utente \"%s\" autenticato come \"%s\"" -#: libpq/hba.c:2895 +#: libpq/hba.c:2932 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "apertura del file usermap \"%s\" fallita: %m" -#: libpq/pqcomm.c:201 +#: libpq/pqcomm.c:220 #, c-format msgid "could not set socket to nonblocking mode: %m" msgstr "impossibile impostare il socket in modalità non bloccante: %m" -#: libpq/pqcomm.c:355 +#: libpq/pqcomm.c:374 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" msgstr "Il percorso del socket di dominio unix \"%s\" è troppo lungo (massimo %d byte)" -#: libpq/pqcomm.c:376 +#: libpq/pqcomm.c:395 #, c-format msgid "could not translate host name \"%s\", service \"%s\" to address: %s" msgstr "conversione del nome host \"%s\", servizio \"%s\" in indirizzo fallita: %s" -#: libpq/pqcomm.c:380 +#: libpq/pqcomm.c:399 #, c-format msgid "could not translate service \"%s\" to address: %s" msgstr "conversione del servizio \"%s\" in indirizzo fallita: %s" -#: libpq/pqcomm.c:407 +#: libpq/pqcomm.c:426 #, c-format msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" msgstr "bind a tutti gli indirizzi richiesti fallito: MAXLISTEN (%d) superato" -#: libpq/pqcomm.c:416 +#: libpq/pqcomm.c:435 msgid "IPv4" msgstr "IPv4" -#: libpq/pqcomm.c:420 +#: libpq/pqcomm.c:439 msgid "IPv6" msgstr "IPv6" -#: libpq/pqcomm.c:425 +#: libpq/pqcomm.c:444 msgid "Unix" msgstr "Unix" -#: libpq/pqcomm.c:430 +#: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" msgstr "famiglia di indirizzi %d sconosciuto" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:456 +#: libpq/pqcomm.c:475 #, c-format msgid "could not create %s socket for address \"%s\": %m" msgstr "creazione del socket %s per l'indirizzo \"%s\" fallita: %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:482 +#: libpq/pqcomm.c:501 #, c-format msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" msgstr "setsockopt(SO_REUSEADDR) fallita per l'indirizzo %s \"%s\": %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:499 +#: libpq/pqcomm.c:518 #, c-format msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" msgstr "setsockopt(IPV6_V6ONLY) fallita per l'indirizzo %s \"%s\": %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:519 +#: libpq/pqcomm.c:538 #, c-format msgid "could not bind %s address \"%s\": %m" msgstr "bind dell'indirizzo %s \"%s\" fallito: %m" -#: libpq/pqcomm.c:522 +#: libpq/pqcomm.c:541 #, c-format msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." msgstr "C'è già un altro postmaster in funzione sulla porta %d? Se non c'è, rimuovi il file socket \"%s\" e riprova." -#: libpq/pqcomm.c:525 +#: libpq/pqcomm.c:544 #, c-format msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." msgstr "C'è già un altro postmaster in funzione sulla porta %d? Se non c'è, aspetta alcuni secondi e riprova." #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:558 +#: libpq/pqcomm.c:577 #, c-format msgid "could not listen on %s address \"%s\": %m" msgstr "listen sull'indirizzo %s \"%s\" fallito: %m" -#: libpq/pqcomm.c:567 +#: libpq/pqcomm.c:586 #, c-format msgid "listening on Unix socket \"%s\"" msgstr "in ascolto sul socket Unix \"%s\"" #. translator: first %s is IPv4 or IPv6 -#: libpq/pqcomm.c:573 +#: libpq/pqcomm.c:592 #, c-format msgid "listening on %s address \"%s\", port %d" msgstr "in ascolto sull'indirizzo %s \"%s\", porta %d" -#: libpq/pqcomm.c:656 +#: libpq/pqcomm.c:675 #, c-format msgid "group \"%s\" does not exist" msgstr "il gruppo \"%s\" non esiste" -#: libpq/pqcomm.c:666 +#: libpq/pqcomm.c:685 #, c-format msgid "could not set group of file \"%s\": %m" msgstr "impostazione del gruppo del file \"%s\" fallita: %m" -#: libpq/pqcomm.c:677 +#: libpq/pqcomm.c:696 #, c-format msgid "could not set permissions of file \"%s\": %m" msgstr "impostazione dei permessi del file \"%s\" fallita: %m" -#: libpq/pqcomm.c:707 +#: libpq/pqcomm.c:726 #, c-format msgid "could not accept new connection: %m" msgstr "impossibile accettare la nuova connessione: %m" -#: libpq/pqcomm.c:908 +#: libpq/pqcomm.c:927 #, c-format msgid "there is no client connection" msgstr "c'è alcuna connessione client" -#: libpq/pqcomm.c:959 libpq/pqcomm.c:1055 +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 #, c-format msgid "could not receive data from client: %m" msgstr "ricezione dati dal client fallita: %m" -#: libpq/pqcomm.c:1200 tcop/postgres.c:3913 +#: libpq/pqcomm.c:1219 tcop/postgres.c:3997 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "la connessione verrà terminata perché la sincronizzazione del protocollo è stata persa" -#: libpq/pqcomm.c:1266 +#: libpq/pqcomm.c:1285 #, c-format msgid "unexpected EOF within message length word" msgstr "fine file inattesa nella word della lunghezza del messaggio" -#: libpq/pqcomm.c:1277 +#: libpq/pqcomm.c:1296 #, c-format msgid "invalid message length" msgstr "lunghezza del messaggio non valida" -#: libpq/pqcomm.c:1299 libpq/pqcomm.c:1312 +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 #, c-format msgid "incomplete message from client" msgstr "messaggio incompleto dal client" -#: libpq/pqcomm.c:1445 +#: libpq/pqcomm.c:1464 #, c-format msgid "could not send data to client: %m" msgstr "invio dati al client fallito: %m" -#: libpq/pqformat.c:437 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "nessun dato rimasto nel messaggio" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 #, c-format msgid "insufficient data left in message" msgstr "i dati rimasti nel messaggio non sono sufficienti" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "stringa non valida nel messaggio" -#: libpq/pqformat.c:682 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "formato del messaggio non valido" @@ -12984,7 +13480,7 @@ msgid "" "Options for single-user mode:\n" msgstr "" "\n" -"Opzione per la modalità a singolo utente:\n" +"Opzione per la modalità a utente singolo:\n" #: main/main.c:364 #, c-format @@ -13108,321 +13604,316 @@ msgstr "il tipo di nodo estendibile \"%s\" esiste già" msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "ExtensibleNodeMethods \"%s\" non è stato registrato" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1844 -#: parser/parse_coerce.c:1872 parser/parse_coerce.c:1948 -#: parser/parse_expr.c:2089 parser/parse_func.c:598 parser/parse_oper.c:958 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1910 +#: parser/parse_coerce.c:1938 parser/parse_coerce.c:2014 +#: parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "non è stato possibile trovare il tipo di array per il tipo di dati %s" -#: optimizer/path/joinrels.c:826 +#: optimizer/path/joinrels.c:837 #, c-format msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "FULL JOIN è supportato solo con condizioni di join realizzabili con merge o hash" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1200 +#: optimizer/plan/initsplan.c:1221 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s non può essere applicato sul lato che può essere nullo di un join esterno" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1544 parser/analyze.c:1624 parser/analyze.c:1821 -#: parser/analyze.c:2615 +#: optimizer/plan/planner.c:1767 parser/analyze.c:1651 parser/analyze.c:1848 +#: parser/analyze.c:2679 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s non è consentito con UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:2144 optimizer/plan/planner.c:4102 +#: optimizer/plan/planner.c:2339 optimizer/plan/planner.c:4060 #, c-format msgid "could not implement GROUP BY" msgstr "non è stato possibile implementare GROUP BY" -#: optimizer/plan/planner.c:2145 optimizer/plan/planner.c:4103 -#: optimizer/plan/planner.c:4843 optimizer/prep/prepunion.c:938 +#: optimizer/plan/planner.c:2340 optimizer/plan/planner.c:4061 +#: optimizer/plan/planner.c:4804 optimizer/prep/prepunion.c:1080 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "Alcuni dei tipi di dati supportano solo l'hashing, mentre altri supportano solo l'ordinamento." -#: optimizer/plan/planner.c:4842 +#: optimizer/plan/planner.c:4803 #, c-format msgid "could not implement DISTINCT" msgstr "non è stato possibile implementare DISTINCT" -#: optimizer/plan/planner.c:5522 +#: optimizer/plan/planner.c:5486 #, c-format msgid "could not implement window PARTITION BY" msgstr "non è stato possibile implementare PARTITION BY della finestra" -#: optimizer/plan/planner.c:5523 +#: optimizer/plan/planner.c:5487 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "La colonna di partizionamento della finestra dev'essere un tipo di dato ordinabile." -#: optimizer/plan/planner.c:5527 +#: optimizer/plan/planner.c:5491 #, c-format msgid "could not implement window ORDER BY" msgstr "non è stato possibile implementare ORDER BY della finestra" -#: optimizer/plan/planner.c:5528 +#: optimizer/plan/planner.c:5492 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "La colonna di ordinamento della finestra dev'essere un tipo di dato ordinabile." -#: optimizer/plan/setrefs.c:413 +#: optimizer/plan/setrefs.c:414 #, c-format msgid "too many range table entries" msgstr "troppi intervalli di tabella" -#: optimizer/prep/prepunion.c:493 +#: optimizer/prep/prepunion.c:544 #, c-format msgid "could not implement recursive UNION" msgstr "non è stato possibile implementare la UNION ricorsiva" -#: optimizer/prep/prepunion.c:494 +#: optimizer/prep/prepunion.c:545 #, c-format msgid "All column datatypes must be hashable." msgstr "Tutti i tipi di dati devono supportare l'hash." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:937 +#: optimizer/prep/prepunion.c:1079 #, c-format msgid "could not implement %s" msgstr "non è stato possibile implementare %s" -#: optimizer/util/clauses.c:4668 +#: optimizer/util/clauses.c:4854 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "funzione SQL \"%s\" durante l'inlining" -#: optimizer/util/plancat.c:120 +#: optimizer/util/plancat.c:127 #, c-format msgid "cannot access temporary or unlogged relations during recovery" msgstr "non è possibile accedere a relazioni temporanee o non loggate durante il ripristino" -#: optimizer/util/plancat.c:620 +#: optimizer/util/plancat.c:651 #, c-format msgid "whole row unique index inference specifications are not supported" msgstr "le specifiche di inferenza di indici unici per l'intera riga non sono supportate" -#: optimizer/util/plancat.c:637 +#: optimizer/util/plancat.c:668 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "il vincolo nella clausola ON CONFLICT non ha indici associati" -#: optimizer/util/plancat.c:688 +#: optimizer/util/plancat.c:719 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" msgstr "ON CONFLICT DO UPDATE non supportato con vincoli di esclusione" -#: optimizer/util/plancat.c:793 +#: optimizer/util/plancat.c:824 #, c-format msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "non c'è alcun vincolo di unicità o esclusione che combaci con la specifica ON CONFLICT" -#: parser/analyze.c:700 parser/analyze.c:1387 +#: parser/analyze.c:709 parser/analyze.c:1414 #, c-format msgid "VALUES lists must all be the same length" msgstr "le liste VALUES devono essere tutte della stessa lunghezza" -#: parser/analyze.c:855 -#, c-format -msgid "ON CONFLICT clause is not supported with partitioned tables" -msgstr "la clausola ON CONFLICT non è supportata con tabelle partizionate" - -#: parser/analyze.c:918 +#: parser/analyze.c:919 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT ha più espressioni che colonne di destinazione" -#: parser/analyze.c:936 +#: parser/analyze.c:937 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT ha più colonne di destinazione che espressioni" -#: parser/analyze.c:940 +#: parser/analyze.c:941 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "L'origine dell'inserimento è un'espressione riga con lo stesso numero di colonne attese da INSERT. Forse hai usato accidentalmente parentesi in eccesso?" -#: parser/analyze.c:1200 parser/analyze.c:1597 +#: parser/analyze.c:1227 parser/analyze.c:1624 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO non è permesso qui" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1529 parser/analyze.c:2794 +#: parser/analyze.c:1556 parser/analyze.c:2858 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s non è consentito con VALUES" -#: parser/analyze.c:1748 +#: parser/analyze.c:1775 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "clausola UNION/INTERSECT/EXCEPT ORDER BY non valida" -#: parser/analyze.c:1749 +#: parser/analyze.c:1776 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "Possono essere usati solo nomi di colonne risultanti, non espressioni o funzioni." -#: parser/analyze.c:1750 +#: parser/analyze.c:1777 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "Aggiungi l'espressione/funzione ad ogni SELECT, oppure sposta la UNION in una clausola FROM." -#: parser/analyze.c:1811 +#: parser/analyze.c:1838 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO è permesso solo nella prima SELECT di UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:1883 +#: parser/analyze.c:1910 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "l'istruzione membro di UNION/INTERSECT/EXCEPT non può riferirsi al altre relazione allo stesso livello della query" -#: parser/analyze.c:1972 +#: parser/analyze.c:1999 #, c-format msgid "each %s query must have the same number of columns" msgstr "ogni query in %s deve avere lo stesso numero di colonne" -#: parser/analyze.c:2365 +#: parser/analyze.c:2392 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING deve avere almeno una colonna" -#: parser/analyze.c:2406 +#: parser/analyze.c:2433 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "non è possibile specificare sia SCROLL che NO SCROLL" -#: parser/analyze.c:2425 +#: parser/analyze.c:2452 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR non può contenere istruzioni di modifica dei dati nel WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2433 +#: parser/analyze.c:2460 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s non è supportato" -#: parser/analyze.c:2436 +#: parser/analyze.c:2463 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "I cursori trattenibili devono essere READ ONLY." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2444 +#: parser/analyze.c:2471 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s non è supportato" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2455 +#: parser/analyze.c:2482 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %s non è supportato" -#: parser/analyze.c:2458 +#: parser/analyze.c:2485 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "I cursori Insensitive devono essere READ ONLY." -#: parser/analyze.c:2524 +#: parser/analyze.c:2551 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "le viste materializzate non possono usare istruzioni di modifica dei dati nel WITH" -#: parser/analyze.c:2534 +#: parser/analyze.c:2561 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "le viste materializzate non possono usare tabelle temporanee o viste" -#: parser/analyze.c:2544 +#: parser/analyze.c:2571 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "le viste materializzate non possono essere definite con parametri impostati" -#: parser/analyze.c:2556 +#: parser/analyze.c:2583 #, c-format msgid "materialized views cannot be UNLOGGED" msgstr "le viste materializzate non possono essere UNLOGGED" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2622 +#: parser/analyze.c:2686 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s non è consentito con la clausola DISTINCT" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2629 +#: parser/analyze.c:2693 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s non è consentito con la clausola GROUP BY" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2636 +#: parser/analyze.c:2700 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s non è consentito con la clausola HAVING" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2643 +#: parser/analyze.c:2707 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s non è consentito con funzioni di aggregazione" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2650 +#: parser/analyze.c:2714 #, c-format msgid "%s is not allowed with window functions" msgstr "%s non è consentito con funzioni finestra" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2657 +#: parser/analyze.c:2721 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%s non è consentito con la le funzioni che restituiscono insiemi nella lista di destinazione" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2736 +#: parser/analyze.c:2800 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s deve specificare nomi di tabelle non qualificati" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2767 +#: parser/analyze.c:2831 #, c-format msgid "%s cannot be applied to a join" msgstr "%s non può essere applicato ad un join" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2776 +#: parser/analyze.c:2840 #, c-format msgid "%s cannot be applied to a function" msgstr "%s non può essere applicato ad una funzione" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2785 +#: parser/analyze.c:2849 #, c-format msgid "%s cannot be applied to a table function" msgstr "%s non può essere applicato ad una funzione tabella" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2803 +#: parser/analyze.c:2867 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s non può essere applicato ad una query WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2812 +#: parser/analyze.c:2876 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%s non può essere applicato a un tuplestore con nome" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2829 +#: parser/analyze.c:2893 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "la relazione \"%s\" nella clausola %s non è stata trovata nella clausola FROM" @@ -13490,508 +13981,579 @@ msgstr "le funzioni di aggregazione non sono ammesse nel ROWS della finestra" msgid "grouping operations are not allowed in window ROWS" msgstr "le operazioni di raggruppamento non sono ammesse nel ROWS della finestra" -#: parser/parse_agg.c:454 +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "le funzioni di aggregazione non sono ammesse nel GROUPS della finestra" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "le operazioni di raggruppamento non sono ammesse nel GROUPS della finestra" + +#: parser/parse_agg.c:461 msgid "aggregate functions are not allowed in check constraints" msgstr "le funzioni di aggregazione non sono ammesse nei vincoli di controllo" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:463 msgid "grouping operations are not allowed in check constraints" msgstr "le operazioni di raggruppamento non sono ammesse nei vincoli di controllo" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:470 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "le funzioni di aggregazione non sono ammesse nelle espressioni DEFAULT" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:472 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "le operazioni di raggruppamento non sono ammesse nelle espressioni DEFAULT" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:477 msgid "aggregate functions are not allowed in index expressions" msgstr "le funzioni di aggregazione non sono ammesse nelle espressioni degli indici" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:479 msgid "grouping operations are not allowed in index expressions" msgstr "le operazioni di raggruppamento non sono ammesse nelle espressioni degli indici" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:484 msgid "aggregate functions are not allowed in index predicates" msgstr "le funzioni di aggregazione non sono ammesse nei predicati degli indici" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:486 msgid "grouping operations are not allowed in index predicates" msgstr "le operazioni di raggruppamento non sono ammesse nei predicati degli indici" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:491 msgid "aggregate functions are not allowed in transform expressions" msgstr "le funzioni di aggregazione non sono ammesse nelle espressioni di trasformazione" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:493 msgid "grouping operations are not allowed in transform expressions" msgstr "le operazioni di raggruppamento non sono ammesse nelle espressioni di trasformazione" -#: parser/parse_agg.c:491 +#: parser/parse_agg.c:498 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "le funzioni di aggregazione non sono ammesse nei parametri di EXECUTE" -#: parser/parse_agg.c:493 +#: parser/parse_agg.c:500 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "le operazioni di raggruppamento non sono ammesse nei parametri di EXECUTE" -#: parser/parse_agg.c:498 +#: parser/parse_agg.c:505 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "le funzioni di aggregazione non sono ammesse nelle condizioni WHEN dei trigger" -#: parser/parse_agg.c:500 +#: parser/parse_agg.c:507 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "le operazioni di raggruppamento non sono ammesse nelle condizioni WHEN dei trigger" -#: parser/parse_agg.c:505 -msgid "aggregate functions are not allowed in partition key expression" -msgstr "le funzioni aggregazione non sono supportate nelle espressioni di partizione" +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "le funzioni di aggregazione non sono ammesse nelle espressioni di partizione" -#: parser/parse_agg.c:507 -msgid "grouping operations are not allowed in partition key expression" -msgstr "le funzioni raggruppamento non sono supportate nelle espressioni di partizione" +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "le operazioni di raggruppamento non sono ammesse nelle espressioni di partizione" + +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "le funzioni di aggregazione non sono ammesse in argomenti CALL" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "le operazioni di raggruppamento non sono ammesse in argomenti CALL" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:530 parser/parse_clause.c:1804 +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "le funzioni di aggregazione non sono ammesse in %s" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:533 +#: parser/parse_agg.c:548 #, c-format msgid "grouping operations are not allowed in %s" msgstr "le operazioni di raggruppamento non sono ammesse in %s" -#: parser/parse_agg.c:641 +#: parser/parse_agg.c:656 #, c-format msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "gli aggregati di livello esterno non possono contenere una variabile di livello inferiore tra gli argomenti diretti" -#: parser/parse_agg.c:712 +#: parser/parse_agg.c:735 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "le chiamate a funzioni di aggregazione non possono contenere chiamate a funzioni che restituiscono insiemi" + +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 +#: parser/parse_func.c:866 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Potresti riuscire a spostare la funzione che restituisce insiemi in un costrutto LATERAL FORM." + +#: parser/parse_agg.c:741 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "le chiamate a funzioni di aggregazione non possono contenere chiamate a funzioni finestra" -#: parser/parse_agg.c:790 +#: parser/parse_agg.c:820 msgid "window functions are not allowed in JOIN conditions" msgstr "le funzioni finestra non sono ammesse nelle condizioni JOIN" -#: parser/parse_agg.c:797 +#: parser/parse_agg.c:827 msgid "window functions are not allowed in functions in FROM" msgstr "le funzioni finestra non sono ammesse nelle funzioni in FROM" -#: parser/parse_agg.c:803 +#: parser/parse_agg.c:833 msgid "window functions are not allowed in policy expressions" msgstr "le funzioni finestra non sono ammesse nell'espressione di una regola di sicurezza" -#: parser/parse_agg.c:815 +#: parser/parse_agg.c:846 msgid "window functions are not allowed in window definitions" msgstr "le funzioni finestra non sono ammesse nelle definizioni di finestre" -#: parser/parse_agg.c:847 +#: parser/parse_agg.c:878 msgid "window functions are not allowed in check constraints" msgstr "le funzioni finestra non sono ammesse nei vincoli di controllo" -#: parser/parse_agg.c:851 +#: parser/parse_agg.c:882 msgid "window functions are not allowed in DEFAULT expressions" msgstr "le funzioni finestra non sono ammesse nelle espressioni DEFAULT" -#: parser/parse_agg.c:854 +#: parser/parse_agg.c:885 msgid "window functions are not allowed in index expressions" msgstr "le funzioni finestra non sono ammesse nelle espressioni degli indici" -#: parser/parse_agg.c:857 +#: parser/parse_agg.c:888 msgid "window functions are not allowed in index predicates" msgstr "le funzioni finestra non sono ammesse nei predicati degli indici" -#: parser/parse_agg.c:860 +#: parser/parse_agg.c:891 msgid "window functions are not allowed in transform expressions" msgstr "le funzioni finestra non sono ammesse nelle espressioni di trasformazione" -#: parser/parse_agg.c:863 +#: parser/parse_agg.c:894 msgid "window functions are not allowed in EXECUTE parameters" msgstr "le funzioni finestra non sono ammesse nei parametri di EXECUTE" -#: parser/parse_agg.c:866 +#: parser/parse_agg.c:897 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "le funzioni finestra non sono ammesse nelle condizioni WHEN dei trigger" -#: parser/parse_agg.c:869 -msgid "window functions are not allowed in partition key expression" -msgstr "le funzioni finestra non sono supportate nelle espressioni di partizione" +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "le funzioni finestra non sono ammesse nelle espressioni di partizione" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "le funzioni finestra non sono ammesse in argomenti CALL" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:889 parser/parse_clause.c:1813 +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 #, c-format msgid "window functions are not allowed in %s" msgstr "le funzioni finestra non sono ammesse in %s" -#: parser/parse_agg.c:923 parser/parse_clause.c:2647 +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 #, c-format msgid "window \"%s\" does not exist" msgstr "la finestra \"%s\" non esiste" -#: parser/parse_agg.c:1008 +#: parser/parse_agg.c:1042 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "troppi insiemi di raggruppamento presenti (il massimo è 4096)" -#: parser/parse_agg.c:1157 +#: parser/parse_agg.c:1191 #, c-format msgid "aggregate functions are not allowed in a recursive query's recursive term" msgstr "le funzioni di aggregazione non sono ammesse nel termine ricorsivo di una query ricorsiva" -#: parser/parse_agg.c:1350 +#: parser/parse_agg.c:1384 #, c-format msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" msgstr "la colonna \"%s.%s\" deve comparire nella clausola GROUP BY o essere usata in una funzione di aggregazione" -#: parser/parse_agg.c:1353 +#: parser/parse_agg.c:1387 #, c-format msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "Gli argomenti diretti di un aggregato su insieme ordinato devono usare solo colonne raggruppate." -#: parser/parse_agg.c:1358 +#: parser/parse_agg.c:1392 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "la sottoquery usa la colonna non raggruppata \"%s.%s\" dalla query esterna" -#: parser/parse_agg.c:1522 +#: parser/parse_agg.c:1556 #, c-format msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "gli argomenti di GROUPING devono essere espressioni di raggruppamento del livello della query associato" -#: parser/parse_clause.c:192 +#: parser/parse_clause.c:199 #, c-format msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "la relazione \"%s\" non può essere obiettivo di un comando di modifica" -#: parser/parse_clause.c:651 +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "le funzioni che restituiscono insiemi devono comparire al livello superiore del FROM" + +#: parser/parse_clause.c:655 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "non è consentita più di una lista di definizione di colonne multiple per la stessa funzione" -#: parser/parse_clause.c:684 +#: parser/parse_clause.c:688 #, c-format msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "ROWS FROM() con più di una funzione non può avere una lista di definizioni di colonne" -#: parser/parse_clause.c:685 +#: parser/parse_clause.c:689 #, c-format msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "Specifica una lista di definizioni colonna separata per ogni funzione dentro ROWS FROM()" -#: parser/parse_clause.c:691 +#: parser/parse_clause.c:695 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "UNNEST() con più di un argomento non può avere una lista di definizioni di colonne" -#: parser/parse_clause.c:692 +#: parser/parse_clause.c:696 #, c-format msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "Usa una invocazione di UNNEST() separata in ROWS FROM() e collega una lista di definizioni di colonne ad ognuna di esse." -#: parser/parse_clause.c:699 +#: parser/parse_clause.c:703 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY non può essere usata con una lista di definizioni di colonne" -#: parser/parse_clause.c:700 +#: parser/parse_clause.c:704 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "Specifica la lista di definizioni di colonne dentro ROWS FROM()." -#: parser/parse_clause.c:803 +#: parser/parse_clause.c:807 #, c-format msgid "only one FOR ORDINALITY column is allowed" msgstr "solo una colonna FOR ORDINALITY consentita" -#: parser/parse_clause.c:864 +#: parser/parse_clause.c:868 #, c-format msgid "column name \"%s\" is not unique" msgstr "il nome della colonna \"%s\" non è unico" -#: parser/parse_clause.c:906 +#: parser/parse_clause.c:910 #, c-format msgid "namespace name \"%s\" is not unique" msgstr "il nome di namespace \"%s\" non è unico" -#: parser/parse_clause.c:916 +#: parser/parse_clause.c:920 #, c-format msgid "only one default namespace is allowed" msgstr "solo un nome predefinito di namespace consentito" -#: parser/parse_clause.c:977 +#: parser/parse_clause.c:982 #, c-format msgid "tablesample method %s does not exist" msgstr "il metodo di campionamento tabella %s non esiste" -#: parser/parse_clause.c:999 +#: parser/parse_clause.c:1004 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "il metodo di campionamento %s richiede %d argumenti, not %d" msgstr[1] "il metodo di campionamento %s richiede %d argumenti, not %d" -#: parser/parse_clause.c:1033 +#: parser/parse_clause.c:1038 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "il metodo di campionamento %s non supporta REPEATABLE" -#: parser/parse_clause.c:1194 +#: parser/parse_clause.c:1208 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "la clausola TABLESAMPLE può essere applicata solo a tabelle e viste materializzate" -#: parser/parse_clause.c:1364 +#: parser/parse_clause.c:1378 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "il nome della colonna \"%s\" compare più di una volta nella clausola USING" -#: parser/parse_clause.c:1379 +#: parser/parse_clause.c:1393 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "il nome comune della colonna \"%s\" compare più di una volta nella tabella di sinistra" -#: parser/parse_clause.c:1388 +#: parser/parse_clause.c:1402 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "la colonna \"%s\" specificata nella clausola USING non esiste nella tabella di sinistra" -#: parser/parse_clause.c:1402 +#: parser/parse_clause.c:1416 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "il nome comune della colonna \"%s\" compare più di una volta nella tabella di destra" -#: parser/parse_clause.c:1411 +#: parser/parse_clause.c:1425 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "la colonna \"%s\" specificata nella clausola USING non esiste nella tabella di destra" -#: parser/parse_clause.c:1465 +#: parser/parse_clause.c:1479 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "la lista di alias delle colonne per \"%s\" ha troppi elementi" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1774 +#: parser/parse_clause.c:1788 #, c-format msgid "argument of %s must not contain variables" msgstr "l'argomento di %s non può contenere variabili" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1939 +#: parser/parse_clause.c:1953 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s \"%s\" è ambiguo" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1968 +#: parser/parse_clause.c:1982 #, c-format msgid "non-integer constant in %s" msgstr "costante non intera in %s" # translator: %s is name of a SQL construct, eg ORDER BY #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1990 +#: parser/parse_clause.c:2004 #, c-format msgid "%s position %d is not in select list" msgstr "%s in posizione %d non è nella lista SELECT" -#: parser/parse_clause.c:2431 +#: parser/parse_clause.c:2445 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE è limitato a 12 elementi" -#: parser/parse_clause.c:2635 +#: parser/parse_clause.c:2651 #, c-format msgid "window \"%s\" is already defined" msgstr "la finestra \"%s\" è già definita" -#: parser/parse_clause.c:2696 +#: parser/parse_clause.c:2712 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "non è possibile scavalcare la clausola PARTITION BY della finestra \"%s\"" -#: parser/parse_clause.c:2708 +#: parser/parse_clause.c:2724 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "non è possibile scavalcare la clausola ORDER BY della finestra \"%s\"" -#: parser/parse_clause.c:2738 parser/parse_clause.c:2744 +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "non è possibile copiare la finestra \"%s\" perché ha una clausola frame" -#: parser/parse_clause.c:2746 +#: parser/parse_clause.c:2762 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Omettere le parentesi in questa clausola OVER." -#: parser/parse_clause.c:2812 +#: parser/parse_clause.c:2782 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE con offset PRECEDING/FOLLOWING richiede esattamente una colonna ORDER BY" + +#: parser/parse_clause.c:2805 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "la modalità GROUPS richiede una clausola ORDER BY" + +#: parser/parse_clause.c:2875 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "in un aggregato con DISTINCT, le espressioni ORDER BY devono figurare nella lista di argomenti" -#: parser/parse_clause.c:2813 +#: parser/parse_clause.c:2876 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "per SELECT DISTINCT, le espressioni ORDER BY devono figurare nella lista di argomenti" -#: parser/parse_clause.c:2845 +#: parser/parse_clause.c:2908 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "un aggregato con DISTINCT deve avere almeno un argomento" -#: parser/parse_clause.c:2846 +#: parser/parse_clause.c:2909 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT deve avere almeno una colonna" -#: parser/parse_clause.c:2912 parser/parse_clause.c:2944 +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "le espressioni SELECT DISTINCT ON devono coincidere con l'espressione ORDER BY iniziale" -#: parser/parse_clause.c:3022 +#: parser/parse_clause.c:3085 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ASC/DESC non è permesso nelle clausole ON CONFLICT" -#: parser/parse_clause.c:3028 +#: parser/parse_clause.c:3091 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "NULLS FIRST/LAST non è permesso nelle clausole ON CONFLICT" -#: parser/parse_clause.c:3108 +#: parser/parse_clause.c:3170 #, c-format msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATE richiede una specifica di inferenza o il nome di un vincolo" -#: parser/parse_clause.c:3109 +#: parser/parse_clause.c:3171 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Per esempio, ON CONFLICT (nome_colonna)." -#: parser/parse_clause.c:3120 +#: parser/parse_clause.c:3182 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT non è supportato sulle tabelle del catalogo di sistema" -#: parser/parse_clause.c:3128 +#: parser/parse_clause.c:3190 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "ON CONFLICT non è supportato sulla tabella \"%s\" usata da una tabella di catalogo" -#: parser/parse_clause.c:3254 +#: parser/parse_clause.c:3333 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "l'operatore %s non è un operatore di ordinamento valido" -#: parser/parse_clause.c:3256 +#: parser/parse_clause.c:3335 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "Gli operatori di ordinamento devono essere i membri \"<\" oppure \">\" di una famiglia di operatori btree." -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2123 parser/parse_expr.c:2699 parser/parse_target.c:936 +#: parser/parse_clause.c:3646 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE con offset PRECEDING/FOLLOWING non supportato per il tipo di colonna %s" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE con offset PRECEDING/FOLLOWING non supportato per il tipo di colonna %s e tipo di offset %s" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Converti il valore di offset in un tipo appropriato." + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE con offset PRECEDING/FOLLOWING ha interpretazioni multiple per il tipo di colonna %s e tipo di offset %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Converti il valore di offset nel tipo esatto desiderato." + +#: parser/parse_coerce.c:1017 parser/parse_coerce.c:1055 +#: parser/parse_coerce.c:1073 parser/parse_coerce.c:1088 +#: parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:955 #, c-format msgid "cannot cast type %s to %s" msgstr "non è possibile convertire il tipo %s in %s" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1058 #, c-format msgid "Input has too few columns." msgstr "L'input ha troppe poche colonne." -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1076 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "Non è possibile convertire il tipo %s in %s nella colonna %d." -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1091 #, c-format msgid "Input has too many columns." msgstr "L'input ha troppe colonne." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1128 +#: parser/parse_coerce.c:1146 parser/parse_coerce.c:1194 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "l'argomento di %s deve essere di tipo %s, non %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1091 parser/parse_coerce.c:1140 +#: parser/parse_coerce.c:1157 parser/parse_coerce.c:1206 #, c-format msgid "argument of %s must not return a set" msgstr "l'argomento di %s non deve restituire un set" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1280 +#: parser/parse_coerce.c:1346 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "in %s i tipi %s e %s non combaciano" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1347 +#: parser/parse_coerce.c:1413 #, c-format msgid "%s could not convert type %s to %s" msgstr "in %s conversione del tipo %s in %s fallita" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1715 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "gli argomenti dichiarati \"anyelement\" non sono tutti simili" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1735 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "gli argomenti dichiarati \"anyarray\" non sono tutti simili" -#: parser/parse_coerce.c:1689 +#: parser/parse_coerce.c:1755 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "gli argomenti dichiarati \"anyrange\" non sono tutti simili" -#: parser/parse_coerce.c:1718 parser/parse_coerce.c:1933 -#: parser/parse_coerce.c:1967 +#: parser/parse_coerce.c:1784 parser/parse_coerce.c:1999 +#: parser/parse_coerce.c:2033 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "l'argomento dichiarato %s non è un array ma di tipo %s" -#: parser/parse_coerce.c:1734 parser/parse_coerce.c:1773 +#: parser/parse_coerce.c:1800 parser/parse_coerce.c:1839 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "l'argomento dichiarato %s non è consistente con l'argomento dichiarato %s" -#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1980 +#: parser/parse_coerce.c:1822 parser/parse_coerce.c:2046 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "l'argomento dichiarato %s non è un intervallo ma di tipo %s" -#: parser/parse_coerce.c:1794 +#: parser/parse_coerce.c:1860 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "errore nel determinare il tipo polimorfico perché l'input è di tipo %s" -#: parser/parse_coerce.c:1805 +#: parser/parse_coerce.c:1871 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "il tipo associato ad anynonarray è di tipo array: %s" -#: parser/parse_coerce.c:1815 +#: parser/parse_coerce.c:1881 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "il tipo associato ad anyenum non è una enumerazione: %s" -#: parser/parse_coerce.c:1855 parser/parse_coerce.c:1885 +#: parser/parse_coerce.c:1921 parser/parse_coerce.c:1951 #, c-format msgid "could not find range type for data type %s" msgstr "tipo dell'intervallo non trovato per il tipo di dato %s" @@ -14113,410 +14675,484 @@ msgstr "FOR UPDATE/SHARE non è implementato in una query ricorsiva" msgid "recursive reference to query \"%s\" must not appear more than once" msgstr "il riferimento ricorsivo alla query \"%s\" non può apparire più di una volta" -#: parser/parse_expr.c:357 +#: parser/parse_expr.c:350 #, c-format msgid "DEFAULT is not allowed in this context" msgstr "DEFAULT non ammesso in questo contesto" -#: parser/parse_expr.c:410 parser/parse_relation.c:3248 -#: parser/parse_relation.c:3268 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 +#: parser/parse_relation.c:3307 #, c-format msgid "column %s.%s does not exist" msgstr "la colonna %s.%s non esiste" -#: parser/parse_expr.c:422 +#: parser/parse_expr.c:415 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "la colonna \"%s\" non è stata trovata nel tipo di dato %s" -#: parser/parse_expr.c:428 +#: parser/parse_expr.c:421 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "la colonna \"%s\" non identificata nel tipo di dato record" -#: parser/parse_expr.c:434 +#: parser/parse_expr.c:427 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "la notazione della colonna .%s sembra essere di tipo %s, che non è un tipo composito" -#: parser/parse_expr.c:464 parser/parse_target.c:722 +#: parser/parse_expr.c:458 parser/parse_target.c:722 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "l'espansione della riga tramite \"*\" non è supportata qui" -#: parser/parse_expr.c:769 parser/parse_relation.c:689 -#: parser/parse_relation.c:789 parser/parse_target.c:1171 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 +#: parser/parse_relation.c:789 parser/parse_target.c:1193 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "il riferimento alla colonna \"%s\" è ambiguo" -#: parser/parse_expr.c:825 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "parametro $%d non presente" -#: parser/parse_expr.c:1064 +#: parser/parse_expr.c:1070 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "NULLIF richiede che l'operatore = restituisca un valore booleano" -#: parser/parse_expr.c:1508 parser/parse_expr.c:1540 +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 +#, c-format +msgid "%s must not return a set" +msgstr "%s non può restituire un insieme" + +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 #, c-format msgid "number of columns does not match number of values" msgstr "il numero di colonne non corrisponde al numero di valori" -#: parser/parse_expr.c:1554 +#: parser/parse_expr.c:1570 #, c-format msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" msgstr "l'origine per un UPDATE multi-colonna deve essere una sub-SELECT o espressione ROW()" -#: parser/parse_expr.c:1798 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "non si possono usare funzioni che restituiscono insiemi in %s" + +#: parser/parse_expr.c:1825 msgid "cannot use subquery in check constraint" msgstr "non si può usare una sottoquery nel vincolo di controllo" -#: parser/parse_expr.c:1802 +#: parser/parse_expr.c:1829 msgid "cannot use subquery in DEFAULT expression" msgstr "non si può usare una sottoquery in un'espressione DEFAULT" -#: parser/parse_expr.c:1805 +#: parser/parse_expr.c:1832 msgid "cannot use subquery in index expression" msgstr "non si possono usare sottoquery nell'espressione dell'indice" -#: parser/parse_expr.c:1808 +#: parser/parse_expr.c:1835 msgid "cannot use subquery in index predicate" msgstr "non è possibile usare sottoquery nel predicato dell'indice" -#: parser/parse_expr.c:1811 +#: parser/parse_expr.c:1838 msgid "cannot use subquery in transform expression" msgstr "non è possibile usare sottoquery in un'espressione di trasformazione" -#: parser/parse_expr.c:1814 +#: parser/parse_expr.c:1841 msgid "cannot use subquery in EXECUTE parameter" msgstr "non si possono usare sottoquery nel parametro EXECUTE" -#: parser/parse_expr.c:1817 +#: parser/parse_expr.c:1844 msgid "cannot use subquery in trigger WHEN condition" msgstr "non è possibile usare sottoquery nella condizione WHEN del trigger" -#: parser/parse_expr.c:1820 +#: parser/parse_expr.c:1847 msgid "cannot use subquery in partition key expression" -msgstr "non è possibile usare sottowquery in un'espressione di partizione" +msgstr "non è possibile usare sottoquery in un'espressione di partizione" + +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "non è possibile usare sottoquery in argomenti CALL" -#: parser/parse_expr.c:1873 +#: parser/parse_expr.c:1903 #, c-format msgid "subquery must return only one column" msgstr "la sottoquery deve restituire solo una colonna" -#: parser/parse_expr.c:1957 +#: parser/parse_expr.c:1987 #, c-format msgid "subquery has too many columns" msgstr "la sottoquery ha troppe colonne" -#: parser/parse_expr.c:1962 +#: parser/parse_expr.c:1992 #, c-format msgid "subquery has too few columns" msgstr "la sottoquery ha troppe poche colonne" -#: parser/parse_expr.c:2063 +#: parser/parse_expr.c:2093 #, c-format msgid "cannot determine type of empty array" msgstr "non è possibile determinare il tipo di un array vuoto" -#: parser/parse_expr.c:2064 +#: parser/parse_expr.c:2094 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "Effettua una conversione esplicita al tipo desiderato, ad esempio ARRAY[]::integer[]." -#: parser/parse_expr.c:2078 +#: parser/parse_expr.c:2108 #, c-format msgid "could not find element type for data type %s" msgstr "tipo dell'elemento non trovato per il tipo di dato %s" -#: parser/parse_expr.c:2353 +#: parser/parse_expr.c:2395 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "il valore dell'attributo XML senza nome dev'essere un riferimento ad una colonna" -#: parser/parse_expr.c:2354 +#: parser/parse_expr.c:2396 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "il valore dell'elemento XML senza nome dev'essere un riferimento ad una colonna" -#: parser/parse_expr.c:2369 +#: parser/parse_expr.c:2411 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "l'attributo XML di nome \"%s\" compare più di una volta" -#: parser/parse_expr.c:2476 +#: parser/parse_expr.c:2518 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "non è possibile convertire il risultato di XMLSERIALIZE a %s" -#: parser/parse_expr.c:2772 parser/parse_expr.c:2967 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format msgid "unequal number of entries in row expressions" msgstr "numero di elementi differente nelle espressioni di riga" -#: parser/parse_expr.c:2782 +#: parser/parse_expr.c:2824 #, c-format msgid "cannot compare rows of zero length" msgstr "non possono comparire righe di lunghezza zero" -#: parser/parse_expr.c:2806 +#: parser/parse_expr.c:2849 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "l'operatore di comparazione tra righe deve restituire il tipo booleano, non il tipo %s" -#: parser/parse_expr.c:2813 +#: parser/parse_expr.c:2856 #, c-format msgid "row comparison operator must not return a set" msgstr "l'operatore di comparazione tra righe non può restituire un insieme" -#: parser/parse_expr.c:2872 parser/parse_expr.c:2913 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "non è stato possibile determinare un'interpretazione dell'operatore di comparazione tra righe %s" -#: parser/parse_expr.c:2874 +#: parser/parse_expr.c:2917 #, c-format msgid "Row comparison operators must be associated with btree operator families." msgstr "Gli operatori di comparazione tra righe devono essere associati a famiglie di operatori btree." -#: parser/parse_expr.c:2915 +#: parser/parse_expr.c:2958 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "C'è più di un candidato egualmente plausibile." -#: parser/parse_expr.c:3007 +#: parser/parse_expr.c:3051 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROM richiede che l'operatore = restituisca un valore booleano" -#: parser/parse_expr.c:3320 parser/parse_expr.c:3338 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "cambio di precedenza di operatori: %s ora ha precedenza inferiore di %s" -#: parser/parse_func.c:175 +#: parser/parse_func.c:185 #, c-format msgid "argument name \"%s\" used more than once" msgstr "il nome dell'argomento \"%s\" è usato più di una volta" -#: parser/parse_func.c:186 +#: parser/parse_func.c:196 #, c-format msgid "positional argument cannot follow named argument" msgstr "gli argomenti posizionali non possono seguire gli argomenti con nome" -#: parser/parse_func.c:271 +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "%s non è una procedura" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Per eseguire una funzione, usa SELECT." + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "%s è una procedura" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Per eseguire una procedura, usa CALL." + +#: parser/parse_func.c:306 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "%s(*) specificato, ma %s non è una funzione di aggregazione" -#: parser/parse_func.c:278 +#: parser/parse_func.c:313 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "DISTINCT specificato, ma %s non è una funzione di aggregazione" -#: parser/parse_func.c:284 +#: parser/parse_func.c:319 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "WITHIN GROUP specificato, ma %s non è una funzione di aggregazione" -#: parser/parse_func.c:290 +#: parser/parse_func.c:325 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "ORDER BY specificato, ma %s non è una funzione di aggregazione" -#: parser/parse_func.c:296 +#: parser/parse_func.c:331 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "FILTER specificato, ma %s non è una funzione di aggregazione" -#: parser/parse_func.c:302 +#: parser/parse_func.c:337 #, c-format msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "OVER specificato, ma %s non è una funzione finestra né una funzione di aggregazione" -#: parser/parse_func.c:332 +#: parser/parse_func.c:375 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP è richiesto per l'aggregato su insieme ordinato %s" -#: parser/parse_func.c:338 +#: parser/parse_func.c:381 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVER non è supportato per l'aggregato su insieme ordinato %s" -#: parser/parse_func.c:369 parser/parse_func.c:398 +#: parser/parse_func.c:412 parser/parse_func.c:441 #, c-format msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr "Esiste un aggregato su insieme ordinato %s, ma richiede %d argomenti diretti, non %d." -#: parser/parse_func.c:423 +#: parser/parse_func.c:466 #, c-format msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "Per usare l'aggregato su insieme ipotetico %s il numero di argomenti ipotetici diretti (qui %d) deve combaciare con quello di colonne di ordinamento (qui %d)." -#: parser/parse_func.c:437 +#: parser/parse_func.c:480 #, c-format msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr "Esiste un aggregato su insieme ordinato %s, ma richiede almeno %d argomenti diretti." -#: parser/parse_func.c:456 +#: parser/parse_func.c:499 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s non è un aggregato su insieme ordinato, per cui non può avere WITHIN GROUP" -#: parser/parse_func.c:469 +#: parser/parse_func.c:512 #, c-format msgid "window function %s requires an OVER clause" msgstr "la funzione finestra %s richiede una clausola OVER" -#: parser/parse_func.c:476 +#: parser/parse_func.c:519 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "la funzione di aggregazione %s non può avere WITHIN GROUP" -#: parser/parse_func.c:497 +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "la procedura %s non è unica" + +#: parser/parse_func.c:551 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Non è stato possibile scegliere la procedura migliore. Potrebbe essere necessario convertire i tipi esplicitamente." + +#: parser/parse_func.c:557 #, c-format msgid "function %s is not unique" msgstr "la funzione %s non è unica" -#: parser/parse_func.c:500 +#: parser/parse_func.c:560 #, c-format msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "Non è stato possibile scegliere la funzione migliore. Potrebbe essere necessario convertire i tipi esplicitamente." -#: parser/parse_func.c:511 +#: parser/parse_func.c:599 #, c-format msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." msgstr "Nessuna funzione di aggregazione trovata con nome e tipi di argomenti forniti. Forse hai posizionato ORDER BY male: ORDER BY deve apparire dopo tutti gli argomenti regolari della funzione di aggregazione." -#: parser/parse_func.c:522 +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "la procedura %s non esiste" + +#: parser/parse_func.c:610 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Nessuna procedura trovata con nome e tipi di argomenti forniti. Potrebbe essere necessario convertire i tipi esplicitamente." + +#: parser/parse_func.c:619 #, c-format msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgstr "Nessuna funzione trovata con nome e tipi di argomenti forniti. Potrebbe essere necessario convertire i tipi esplicitamente." -#: parser/parse_func.c:624 +#: parser/parse_func.c:721 #, c-format msgid "VARIADIC argument must be an array" msgstr "l'argomento VARIADIC deve essere un array" -#: parser/parse_func.c:676 parser/parse_func.c:740 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*) dev'essere usato per richiamare una funzione di aggregazione senza parametri" -#: parser/parse_func.c:683 +#: parser/parse_func.c:780 #, c-format msgid "aggregates cannot return sets" msgstr "le funzioni di aggregazione non possono restituire insiemi" -#: parser/parse_func.c:698 +#: parser/parse_func.c:795 #, c-format msgid "aggregates cannot use named arguments" msgstr "le funzioni di aggregazione non possono usare argomenti con nome" -#: parser/parse_func.c:730 +#: parser/parse_func.c:827 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "DISTINCT non è implementato per funzioni finestra" -#: parser/parse_func.c:750 +#: parser/parse_func.c:847 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "ORDER BY delle funzioni di aggregazione non è implementato per funzioni finestra" -#: parser/parse_func.c:759 +#: parser/parse_func.c:856 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER non è implementato per funzioni finestra non aggregate" -#: parser/parse_func.c:765 +#: parser/parse_func.c:865 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "le funzioni finestra non possono contenere richiami a funzioni che restituiscono insiemi" + +#: parser/parse_func.c:873 #, c-format msgid "window functions cannot return sets" msgstr "le funzioni finestra non possono restituire insiemi" -#: parser/parse_func.c:1931 +#: parser/parse_func.c:2059 #, c-format msgid "function name \"%s\" is not unique" msgstr "il nome della funzione \"%s\" non è univoco" -#: parser/parse_func.c:1933 +#: parser/parse_func.c:2061 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "Specifica l'elenco degli argomenti per selezionare la funzione senza ambiguità." -#: parser/parse_func.c:1943 +#: parser/parse_func.c:2071 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "funzione \"%s\" non trovata" + +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s non è una funzione" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "procedura \"%s\" non trovata" + +#: parser/parse_func.c:2198 #, c-format -msgid "could not find a function named \"%s\"" -msgstr "funzione \"%s\" non trovata" +msgid "could not find an aggregate named \"%s\"" +msgstr "funzione di aggregazione \"%s\" non trovata" -#: parser/parse_func.c:2045 +#: parser/parse_func.c:2203 #, c-format msgid "aggregate %s(*) does not exist" msgstr "la funzione di aggregazione %s(*) non esiste" -#: parser/parse_func.c:2050 +#: parser/parse_func.c:2208 #, c-format msgid "aggregate %s does not exist" msgstr "la funzione di aggregazione %s non esiste" -#: parser/parse_func.c:2069 +#: parser/parse_func.c:2221 #, c-format msgid "function %s is not an aggregate" msgstr "la funzione %s non è una funzione di aggregazione" -#: parser/parse_func.c:2117 +#: parser/parse_func.c:2271 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "non si possono usare funzioni che restituiscono insiemi in condizioni JOIN" -#: parser/parse_func.c:2130 +#: parser/parse_func.c:2292 msgid "set-returning functions are not allowed in policy expressions" msgstr "non si possono usare funzioni che restituiscono insiemi nelle regole di sicurezza" -#: parser/parse_func.c:2145 +#: parser/parse_func.c:2308 msgid "set-returning functions are not allowed in window definitions" msgstr "non si possono usare funzioni che restituiscono insiemi nelle definizioni di finestre" -#: parser/parse_func.c:2183 +#: parser/parse_func.c:2346 msgid "set-returning functions are not allowed in check constraints" msgstr "non si possono usare funzioni che restituiscono insiemi nei vincoli di controllo" -#: parser/parse_func.c:2187 +#: parser/parse_func.c:2350 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "non si possono usare funzioni che restituiscono insiemi nelle espressioni DEFAULT" -#: parser/parse_func.c:2190 +#: parser/parse_func.c:2353 msgid "set-returning functions are not allowed in index expressions" msgstr "non si possono usare funzioni che restituiscono insiemi nelle espressioni degli indici" -#: parser/parse_func.c:2193 +#: parser/parse_func.c:2356 msgid "set-returning functions are not allowed in index predicates" msgstr "non si possono usare funzioni che restituiscono insiemi nei predicati degli indici" -#: parser/parse_func.c:2196 +#: parser/parse_func.c:2359 msgid "set-returning functions are not allowed in transform expressions" msgstr "non si possono usare funzioni che restituiscono insiemi in espressioni di trasformazione" -#: parser/parse_func.c:2199 +#: parser/parse_func.c:2362 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "non si possono usare funzioni che restituiscono insiemi in parametri EXECUTE" -#: parser/parse_func.c:2202 +#: parser/parse_func.c:2365 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "non si possono usare funzioni che restituiscono insiemi nelle condizioni WHEN dei trigger" -#: parser/parse_func.c:2205 -msgid "set-returning functions are not allowed in partition key expression" -msgstr "non si possono usare funzioni che restituiscono insiemi in espressioni di partizione" +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "non si possono usare funzioni che restituiscono insiemi come espressione di partizione " -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_func.c:2225 -#, c-format -msgid "set-returning functions are not allowed in %s" -msgstr "non si possono usare funzioni che restituiscono insiemi in %s" +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "non si possono usare funzioni che restituiscono insiemi in argomenti CALL" #: parser/parse_node.c:87 #, c-format @@ -14538,8 +15174,8 @@ msgstr "l'indice di un array dev'essere di tipo intero" msgid "array assignment requires type %s but expression is of type %s" msgstr "l'assegnamento all'array richiede il tipo %s ma l'espressione è di tipo %s" -#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:519 -#: utils/adt/regproc.c:703 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format msgid "operator does not exist: %s" msgstr "l'operatore non esiste: %s" @@ -14549,14 +15185,6 @@ msgstr "l'operatore non esiste: %s" msgid "Use an explicit ordering operator or modify the query." msgstr "Usa un operatore di ordinamento esplicito, oppure modifica la query." -#: parser/parse_oper.c:228 utils/adt/array_userfuncs.c:724 -#: utils/adt/array_userfuncs.c:863 utils/adt/arrayfuncs.c:3639 -#: utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6039 -#: utils/adt/rowtypes.c:1167 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "operatore di uguaglianza per il tipo %s non trovato" - #: parser/parse_oper.c:480 #, c-format msgid "operator requires run-time type coercion: %s" @@ -14572,27 +15200,32 @@ msgstr "l'operatore non è unico: %s" msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgstr "Non è stato possibile scegliere l'operatore migliore. Potrebbe essere necessario convertire i tipi esplicitamente." -#: parser/parse_oper.c:726 +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Nessun operatore trovato con nome e tipo di argomento fornito. Potrebbe essere necessario convertire il tipo esplicitamente." + +#: parser/parse_oper.c:729 #, c-format -msgid "No operator matches the given name and argument type(s). You might need to add explicit type casts." +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." msgstr "Nessun operatore trovato con nome e tipi di argomenti forniti. Potrebbe essere necessario convertire i tipi esplicitamente." -#: parser/parse_oper.c:785 parser/parse_oper.c:903 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "l'operatore non è completamente definito: %s" -#: parser/parse_oper.c:891 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "op ANY/ALL (array) richiede un array sul lato destro" -#: parser/parse_oper.c:933 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "op ANY/ALL (array) richiede che l'operatore restituisca un valore booleano" -#: parser/parse_oper.c:938 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "op ANY/ALL (array) richiede che l'operatore non restituisca un insieme" @@ -14617,12 +15250,12 @@ msgstr "il riferimento alla tabella %u è ambiguo" msgid "table name \"%s\" specified more than once" msgstr "la tabella di nome \"%s\" è stata specificata più di una volta" -#: parser/parse_relation.c:446 parser/parse_relation.c:3188 +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "riferimento non valido all'elemento della clausola FROM per la tabella \"%s\"" -#: parser/parse_relation.c:449 parser/parse_relation.c:3193 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "C'è un elemento per la tabella \"%s\", ma non può essere referenziato da questa parte della query." @@ -14637,83 +15270,84 @@ msgstr "Il tipo del JOIN deve essere INNER oppure LEFT per un riferimento LATERA msgid "system column \"%s\" reference in check constraint is invalid" msgstr "la colonna di sistema \"%s\" referenziata nel vincolo di controllo non è valida" -#: parser/parse_relation.c:1086 parser/parse_relation.c:1372 -#: parser/parse_relation.c:1941 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 +#: parser/parse_relation.c:1936 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "la tabella \"%s\" ha %d colonne disponibili ma %d colonne specificate" -#: parser/parse_relation.c:1179 +#: parser/parse_relation.c:1173 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "C'è un elemento di WITH di nome \"%s\", ma non può essere referenziato da questa parte della query." -#: parser/parse_relation.c:1181 +#: parser/parse_relation.c:1175 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "Usa WITH RECURSIVE, oppure riordina gli elementi di WITH per rimuovere i riferimenti in avanti." -#: parser/parse_relation.c:1492 +#: parser/parse_relation.c:1486 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "la lista di definizione di colonne è consentita solo per funzioni che restituiscono \"record\"" -#: parser/parse_relation.c:1501 +#: parser/parse_relation.c:1495 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "la lista di definizione di colonne è necessaria per funzioni che restituiscono \"record\"" -#: parser/parse_relation.c:1580 +#: parser/parse_relation.c:1575 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "la funzione \"%s\" in FROM restituisce il tipo non supportato %s" -#: parser/parse_relation.c:1769 +#: parser/parse_relation.c:1764 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "le liste VALUES \"%s\" hanno %d colonne disponibili ma %d colonne specificate" -#: parser/parse_relation.c:1824 +#: parser/parse_relation.c:1819 #, c-format msgid "joins can have at most %d columns" msgstr "i join possono avere al più %d colonne" -#: parser/parse_relation.c:1914 +#: parser/parse_relation.c:1909 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "la query WITH \"%s\" non ha una clausola RETURNING" -#: parser/parse_relation.c:2809 parser/parse_relation.c:2972 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 +#: parser/parse_relation.c:3011 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "la colonna %d della relazione \"%s\" non esiste" -#: parser/parse_relation.c:3191 +#: parser/parse_relation.c:3230 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Forse intendevi utilizzare l'alias \"%s\" della tabella." -#: parser/parse_relation.c:3199 +#: parser/parse_relation.c:3238 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "elemento FROM per la tabella \"%s\" mancante" -#: parser/parse_relation.c:3251 +#: parser/parse_relation.c:3290 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Forse intendevi referenziare la colonna \"%s.%s\"." -#: parser/parse_relation.c:3253 +#: parser/parse_relation.c:3292 #, c-format msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "Esiste una colonna di nome \"%s\" nella tabella \"%s\", ma non può essere referenziata da questa parte della query." -#: parser/parse_relation.c:3270 +#: parser/parse_relation.c:3309 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "Forse intendevi referenziare la colonna \"%s.%s\" o la colonna \"%s.%s\"." -#: parser/parse_target.c:483 parser/parse_target.c:775 +#: parser/parse_target.c:483 parser/parse_target.c:784 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "non è possibile assegnare alla colonna di sistema \"%s\"" @@ -14733,27 +15367,27 @@ msgstr "non è possibile impostare un sottocampo a DEFAULT" msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "la colonna \"%s\" è di tipo %s ma l'espressione è di tipo %s" -#: parser/parse_target.c:759 +#: parser/parse_target.c:768 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" msgstr "non è possibile assegnare al campo \"%s\" della colonna \"%s\" perché il suo tipo %s non è un tipo composito" -#: parser/parse_target.c:768 +#: parser/parse_target.c:777 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgstr "non è possibile assegnare al campo \"%s\" della colonna \"%s\" perché non questa colonna non compare nel tipo di dato %s" -#: parser/parse_target.c:835 +#: parser/parse_target.c:854 #, c-format msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "l'assegnamento array a \"%s\" richiede il tipo %s ma l'espressione è di tipo %s" -#: parser/parse_target.c:845 +#: parser/parse_target.c:864 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "il sottocampo \"%s\" è di tipo %s ma l'espressione è di tipo %s" -#: parser/parse_target.c:1261 +#: parser/parse_target.c:1283 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "SELECT * senza tabelle specificate non è consentito" @@ -14773,7 +15407,7 @@ msgstr "riferimento %%TYPE improprio (troppi nomi puntati): %s" msgid "type reference %s converted to %s" msgstr "riferimento al tipo %s convertito in %s" -#: parser/parse_type.c:261 parser/parse_type.c:804 utils/cache/typcache.c:243 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format msgid "type \"%s\" is only a shell" msgstr "il tipo \"%s\" non è completamente definito" @@ -14788,320 +15422,404 @@ msgstr "modificatore di tipo non ammesso per il tipo \"%s\"" msgid "type modifiers must be simple constants or identifiers" msgstr "i modificatori di tipo devono essere costanti o identificatori semplici" -#: parser/parse_type.c:670 parser/parse_type.c:769 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "nome di tipo \"%s\" non valido" -#: parser/parse_utilcmd.c:264 +#: parser/parse_utilcmd.c:272 #, c-format msgid "cannot create partitioned table as inheritance child" msgstr "non è possibile creare tabelle partizionate come figli di ereditarietà" -#: parser/parse_utilcmd.c:269 -#, c-format -msgid "cannot partition using more than %d columns" -msgstr "non è possibile partizionare usando più di %d colonne" - -#: parser/parse_utilcmd.c:276 -#, c-format -msgid "cannot list partition using more than one column" -msgstr "non è possibile elencare partizioni che usano più di una colonna" - -#: parser/parse_utilcmd.c:428 +#: parser/parse_utilcmd.c:448 #, c-format msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" msgstr "%s creerà la sequenza implicita \"%s\" per la colonna serial \"%s.%s\"" -#: parser/parse_utilcmd.c:541 +#: parser/parse_utilcmd.c:571 #, c-format msgid "array of serial is not implemented" msgstr "gli array di serial non sono implementati" -#: parser/parse_utilcmd.c:617 parser/parse_utilcmd.c:629 +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 #, c-format msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "dichiarazioni NULL/NOT NULL in conflitto per la colonna \"%s\" della tabella \"%s\"" -#: parser/parse_utilcmd.c:641 +#: parser/parse_utilcmd.c:671 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "più di un valore predefinito specificato per la colonna \"%s\" della tabella \"%s\"" -#: parser/parse_utilcmd.c:662 +#: parser/parse_utilcmd.c:688 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "le colonne identità non sono supportate in tabelle con tipo" + +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "le colonne identità non sono supportate nelle partizioni" + +#: parser/parse_utilcmd.c:701 #, c-format msgid "multiple identity specifications for column \"%s\" of table \"%s\"" msgstr "specifica di identità multipla per la colonna \"%s\" della tabella \"%s\"" -#: parser/parse_utilcmd.c:685 parser/parse_utilcmd.c:802 +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 #, c-format msgid "primary key constraints are not supported on foreign tables" msgstr "i vincoli di chiave primaria non sono supportati sulle tabelle esterne" -#: parser/parse_utilcmd.c:691 parser/parse_utilcmd.c:808 -#, c-format -msgid "primary key constraints are not supported on partitioned tables" -msgstr "i vincoli di chiave primaria non sono supportati sulle tabelle partizionate" - -#: parser/parse_utilcmd.c:700 parser/parse_utilcmd.c:818 +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 #, c-format msgid "unique constraints are not supported on foreign tables" msgstr "i vincoli di unicità non sono supportati sulle tabelle esterne" -#: parser/parse_utilcmd.c:706 parser/parse_utilcmd.c:824 -#, c-format -msgid "unique constraints are not supported on partitioned tables" -msgstr "i vincoli di unicità non sono supportati sulle tabelle partizionate" - -#: parser/parse_utilcmd.c:723 parser/parse_utilcmd.c:854 +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "i vincoli di chiave esterna non sono supportati sulle tabelle esterne" -#: parser/parse_utilcmd.c:729 parser/parse_utilcmd.c:860 -#, c-format -msgid "foreign key constraints are not supported on partitioned tables" -msgstr "i vincoli di chiave esterna non sono supportati sulle tabelle partizionate" - -#: parser/parse_utilcmd.c:757 +#: parser/parse_utilcmd.c:778 #, c-format msgid "both default and identity specified for column \"%s\" of table \"%s\"" msgstr "specificati sia il default che l'identità per la colonna \"%s\" della tabella \"%s\"" -#: parser/parse_utilcmd.c:834 +#: parser/parse_utilcmd.c:843 #, c-format msgid "exclusion constraints are not supported on foreign tables" msgstr "i vincoli esclusione non sono supportati sulle tabelle esterne" -#: parser/parse_utilcmd.c:840 +#: parser/parse_utilcmd.c:849 #, c-format msgid "exclusion constraints are not supported on partitioned tables" msgstr "i vincoli esclusione non sono supportati sulle tabelle partizionate" -#: parser/parse_utilcmd.c:910 +#: parser/parse_utilcmd.c:913 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKE non è supportato nella creazione di tabelle esterne" -#: parser/parse_utilcmd.c:1465 parser/parse_utilcmd.c:1541 +#: parser/parse_utilcmd.c:1518 parser/parse_utilcmd.c:1625 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "L'indice \"%s\" contiene un riferimento all'intera riga della tabella." -#: parser/parse_utilcmd.c:1810 +#: parser/parse_utilcmd.c:1975 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "non è possibile usare un indice preesistente in CREATE TABLE" -#: parser/parse_utilcmd.c:1830 +#: parser/parse_utilcmd.c:1995 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "l'indice \"%s\" è già associato ad un vincolo" -#: parser/parse_utilcmd.c:1838 +#: parser/parse_utilcmd.c:2003 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "l'indice \"%s\" non appartiene alla tabella \"%s\"" -#: parser/parse_utilcmd.c:1845 +#: parser/parse_utilcmd.c:2010 #, c-format msgid "index \"%s\" is not valid" msgstr "l'indice \"%s\" non è valido" -#: parser/parse_utilcmd.c:1851 +#: parser/parse_utilcmd.c:2016 #, c-format msgid "\"%s\" is not a unique index" msgstr "\"%s\" non è un indice univoco" -#: parser/parse_utilcmd.c:1852 parser/parse_utilcmd.c:1859 -#: parser/parse_utilcmd.c:1866 parser/parse_utilcmd.c:1936 +#: parser/parse_utilcmd.c:2017 parser/parse_utilcmd.c:2024 +#: parser/parse_utilcmd.c:2031 parser/parse_utilcmd.c:2103 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "Non è possibile creare una chiave primaria o un vincolo univoco usando tale indice." -#: parser/parse_utilcmd.c:1858 +#: parser/parse_utilcmd.c:2023 #, c-format msgid "index \"%s\" contains expressions" msgstr "l'indice \"%s\" contiene espressioni" -#: parser/parse_utilcmd.c:1865 +#: parser/parse_utilcmd.c:2030 #, c-format msgid "\"%s\" is a partial index" msgstr "\"%s\" è un indice parziale" -#: parser/parse_utilcmd.c:1877 +#: parser/parse_utilcmd.c:2042 #, c-format msgid "\"%s\" is a deferrable index" msgstr "\"%s\" è un indice deferibile" -#: parser/parse_utilcmd.c:1878 +#: parser/parse_utilcmd.c:2043 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "Non è possibile creare un vincolo non deferibile usando un indice deferibile." -#: parser/parse_utilcmd.c:1935 +#: parser/parse_utilcmd.c:2102 #, c-format msgid "index \"%s\" does not have default sorting behavior" msgstr "l'indice \"%s\" non ha un ordinamento predefinito" -#: parser/parse_utilcmd.c:2079 +#: parser/parse_utilcmd.c:2251 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "la colonna \"%s\" appare due volte nel vincolo di chiave primaria" -#: parser/parse_utilcmd.c:2085 +#: parser/parse_utilcmd.c:2257 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "la colonna \"%s\" appare due volte nel vincolo univoco" -#: parser/parse_utilcmd.c:2294 +#: parser/parse_utilcmd.c:2580 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" msgstr "le espressioni e i predicati dell'indice possono riferirsi solo alla tabella indicizzata" -#: parser/parse_utilcmd.c:2340 +#: parser/parse_utilcmd.c:2626 #, c-format msgid "rules on materialized views are not supported" msgstr "le regole sulle viste materializzate non sono supportate" -#: parser/parse_utilcmd.c:2401 +#: parser/parse_utilcmd.c:2687 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "le condizioni WHERE delle regole non possono avere riferimenti ad altre relazioni" -#: parser/parse_utilcmd.c:2473 +#: parser/parse_utilcmd.c:2759 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "le regole con una condizione WHERE possono avere solo azione SELECT, INSERT, UPDATE o DELETE" -#: parser/parse_utilcmd.c:2491 parser/parse_utilcmd.c:2590 -#: rewrite/rewriteHandler.c:500 rewrite/rewriteManip.c:1015 +#: parser/parse_utilcmd.c:2777 parser/parse_utilcmd.c:2876 +#: rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "le istruzioni UNION/INTERSECT/EXCEPT condizionali non sono implementate" -#: parser/parse_utilcmd.c:2509 +#: parser/parse_utilcmd.c:2795 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "la regola ON SELECT non può usare OLD" -#: parser/parse_utilcmd.c:2513 +#: parser/parse_utilcmd.c:2799 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "la regola ON SELECT non può usare NEW" -#: parser/parse_utilcmd.c:2522 +#: parser/parse_utilcmd.c:2808 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "la regola ON INSERT non può usare OLD" -#: parser/parse_utilcmd.c:2528 +#: parser/parse_utilcmd.c:2814 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "La regola ON DELETE non può usare NEW" -#: parser/parse_utilcmd.c:2556 +#: parser/parse_utilcmd.c:2842 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "non ci si può riferire ad OLD nella query WITH" -#: parser/parse_utilcmd.c:2563 +#: parser/parse_utilcmd.c:2849 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "non ci si può riferire a NEW nella query WITH" -#: parser/parse_utilcmd.c:2996 +#: parser/parse_utilcmd.c:3287 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "clausola DEFERRABLE mal posizionata" -#: parser/parse_utilcmd.c:3001 parser/parse_utilcmd.c:3016 +#: parser/parse_utilcmd.c:3292 parser/parse_utilcmd.c:3307 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "clausole DEFERRABLE/NOT DEFERRABLE multiple non consentite" -#: parser/parse_utilcmd.c:3011 +#: parser/parse_utilcmd.c:3302 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "clausola NOT DEFERRABLE mal posizionata" -#: parser/parse_utilcmd.c:3024 parser/parse_utilcmd.c:3050 gram.y:5373 +#: parser/parse_utilcmd.c:3315 parser/parse_utilcmd.c:3341 gram.y:5549 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "un vincolo dichiarato INITIALLY DEFERRED dev'essere DEFERRABLE" -#: parser/parse_utilcmd.c:3032 +#: parser/parse_utilcmd.c:3323 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "clausola INITIALLY DEFERRED mal posizionata" -#: parser/parse_utilcmd.c:3037 parser/parse_utilcmd.c:3063 +#: parser/parse_utilcmd.c:3328 parser/parse_utilcmd.c:3354 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "clausole INITIALLY IMMEDIATE/DEFERRED multiple non sono consentite" -#: parser/parse_utilcmd.c:3058 +#: parser/parse_utilcmd.c:3349 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "clausola INITIALLY IMMEDIATE mal posizionata" -#: parser/parse_utilcmd.c:3249 +#: parser/parse_utilcmd.c:3540 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE specifica uno schema (%s) differente da quello che sta venendo creato (%s)" -#: parser/parse_utilcmd.c:3315 +#: parser/parse_utilcmd.c:3574 #, c-format -msgid "invalid bound specification for a list partition" -msgstr "specifica di estremità non valida per una partizione su lista" +msgid "table \"%s\" is not partitioned" +msgstr "la tabella \"%s\" non è partizionata" + +#: parser/parse_utilcmd.c:3581 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "l'indice \"%s\" non è partizionato" + +#: parser/parse_utilcmd.c:3615 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "una tabella partizionata con un hash non può avere una partizione di default" + +#: parser/parse_utilcmd.c:3632 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "specifica di estremità non valida per una partizione su hash" + +#: parser/parse_utilcmd.c:3638 partitioning/partbounds.c:2127 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "il modulo per la partizione hash deve essere un intero positivo" + +#: parser/parse_utilcmd.c:3645 partitioning/partbounds.c:2135 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "il resto per la partizione hash deve essere inferiore al modulo" -#: parser/parse_utilcmd.c:3338 parser/parse_utilcmd.c:3472 -#: parser/parse_utilcmd.c:3499 +#: parser/parse_utilcmd.c:3657 #, c-format -msgid "specified value cannot be cast to type \"%s\" of column \"%s\"" -msgstr "il valore specificato non può essere convertito al tipo \"%s\" della colonna \"%s\"" +msgid "invalid bound specification for a list partition" +msgstr "specifica di estremità non valida per una partizione su lista" -#: parser/parse_utilcmd.c:3378 +#: parser/parse_utilcmd.c:3713 #, c-format msgid "invalid bound specification for a range partition" msgstr "specifica di estremità non valida per una partizione su intervallo" -#: parser/parse_utilcmd.c:3386 +#: parser/parse_utilcmd.c:3719 #, c-format msgid "FROM must specify exactly one value per partitioning column" msgstr "FROM deve specificare esattamente un valore per colonna di partizionamento" -#: parser/parse_utilcmd.c:3390 +#: parser/parse_utilcmd.c:3723 #, c-format msgid "TO must specify exactly one value per partitioning column" msgstr "TO deve specificare esattamente un valore per colonna di partizionamento" -#: parser/parse_utilcmd.c:3407 parser/parse_utilcmd.c:3421 -#, c-format -msgid "cannot specify finite value after UNBOUNDED" -msgstr "non si può specificare un valore finito dopo UNBOUNDED" - -#: parser/parse_utilcmd.c:3461 parser/parse_utilcmd.c:3488 +#: parser/parse_utilcmd.c:3770 parser/parse_utilcmd.c:3784 #, c-format msgid "cannot specify NULL in range bound" msgstr "non si può specificare NULL nel limite di un margine" +#: parser/parse_utilcmd.c:3831 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "ogni limite che segue MAXVALUE dev'essere anch'esso MAXVALUE" + +#: parser/parse_utilcmd.c:3838 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "ogni limite che segue MINVALUE dev'essere anch'esso MINVALUE" + +#: parser/parse_utilcmd.c:3869 parser/parse_utilcmd.c:3881 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "il valore specificato non può essere trasformato nel tipo %s per la colonna \"%s\"" + +#: parser/parse_utilcmd.c:3883 +#, c-format +msgid "The cast requires a non-immutable conversion." +msgstr "Il cast richiede una conversione non immutabile." + +#: parser/parse_utilcmd.c:3884 +#, c-format +msgid "Try putting the literal value in single quotes." +msgstr "Prova a mettere il valore letterale tra apici." + #: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "l'identificativo \"%s\" sarà troncato a \"%s\"" -#: port/pg_shmem.c:195 port/sysv_shmem.c:195 +#: partitioning/partbounds.c:331 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "la partizione \"%s\" è in conflitto con la partizione di default esistente \"%s\"" + +#: partitioning/partbounds.c:390 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "ogni modulo di partizione hash deve essere un fattore del successivo modulo più grande" + +#: partitioning/partbounds.c:486 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "intervallo vuoto specificato come limite per la partizione \"%s\"" + +#: partitioning/partbounds.c:488 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Il limite inferiore specificato %s è maggiore o uguale al limite superiore %s." + +#: partitioning/partbounds.c:585 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "la partizione \"%s\" si sovrapporrebbe a \"%s\"" + +#: partitioning/partbounds.c:685 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "scansione della tabella esterna \"%s\", che è una partizione della partizione di default \"%s\", saltata" + +#: partitioning/partbounds.c:724 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "il nuovo vincolo di partizione per la partizione di default \"%s\" verrebbe violato da alcune righe" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "il resto per la partizione hash deve essere un intero non negativo" + +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" non è una tabella partizionata con un hash" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "il numero di colonne di partizionamento (%d) non combacia con il numero di chiavi di partizioni fornito (%d)" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "la colonna %d della chiave di partizione ha tipo \"%s\", ma il valore fornito è di tipo \"%s\"" + +#: port/pg_shmem.c:196 port/sysv_shmem.c:196 #, c-format msgid "could not create shared memory segment: %m" msgstr "creazione del segmento di memoria condivisa fallita: %m" -#: port/pg_shmem.c:196 port/sysv_shmem.c:196 +#: port/pg_shmem.c:197 port/sysv_shmem.c:197 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "La chiamata di sistema fallita era shmget(key=%lu, size=%zu, 0%o)." -#: port/pg_shmem.c:200 port/sysv_shmem.c:200 +#: port/pg_shmem.c:201 port/sysv_shmem.c:201 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" @@ -15110,7 +15828,7 @@ msgstr "" "Questo errore di solito vuol dire che la richiesta di PostgreSQL di un segmento di memoria condivisa eccede il valore del parametro SHMMAX del tuo kernel, o anche che sia inferiore del parametro SHMMIN.\n" "La documentazione di PostgreSQL contiene ulteriori informazioni sulla configurazione della memoria condivisa." -#: port/pg_shmem.c:207 port/sysv_shmem.c:207 +#: port/pg_shmem.c:208 port/sysv_shmem.c:208 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" @@ -15119,7 +15837,7 @@ msgstr "" "Questo errore di solito vuol dire che la richiesta di PostgreSQL di un segmento di memoria condivisa eccede il valore del parametro SHMALL del tuo kernel. Potresti dover riconfigurare il kernel con uno SHMALL più grande.\n" "La documentazione di PostgreSQL contiene ulteriori informazioni sulla configurazione della memoria condivisa." -#: port/pg_shmem.c:213 port/sysv_shmem.c:213 +#: port/pg_shmem.c:214 port/sysv_shmem.c:214 #, c-format msgid "" "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" @@ -15128,22 +15846,22 @@ msgstr "" "Questo errore *non* significa che è finito lo spazio su disco. Può succedere se tutti gli ID di memoria condivisa sono stati presi, nel cui caso è necessario aumentare il parametro SHMMNI del tuo kernel, oppure perché il limite globale la memoria condivisa di sistema è stato raggiunto.\n" "La documentazione di PostgreSQL contiene ulteriori informazioni sulla configurazione della memoria condivisa." -#: port/pg_shmem.c:504 port/sysv_shmem.c:504 +#: port/pg_shmem.c:505 port/sysv_shmem.c:505 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "mappatura della memoria condivisa anonima fallita: %m" -#: port/pg_shmem.c:506 port/sysv_shmem.c:506 +#: port/pg_shmem.c:507 port/sysv_shmem.c:507 #, c-format msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." msgstr "Questo errore di solito vuol dire che la richiesta di PostgreSQL di un segmento di memoria condivisa supera la memoria disponibile, lo spazio di swap o le pagine huge. Per ridurre la dimensione richiesta (attualmente %zu byte), riduci l'utilizzo di memoria condivisa di PostgreSQL, ad esempio riducendo shared_buffers o max_connections." -#: port/pg_shmem.c:572 port/sysv_shmem.c:572 port/win32_shmem.c:134 +#: port/pg_shmem.c:573 port/sysv_shmem.c:573 #, c-format msgid "huge pages not supported on this platform" msgstr "pagine huge non supportate su questa piattaforma" -#: port/pg_shmem.c:667 port/sysv_shmem.c:667 +#: port/pg_shmem.c:668 port/sysv_shmem.c:668 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sulla directory dati \"%s\": %m" @@ -15232,236 +15950,263 @@ msgstr "unlock del semaforo fallito: codice errore %lu" msgid "could not try-lock semaphore: error code %lu" msgstr "try-lock del semaforo fallito: codice errore %lu" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:122 port/win32_shmem.c:130 port/win32_shmem.c:142 +#: port/win32_shmem.c:157 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "abilitazione del privilegio Lock Pages fallito: codice di errore %lu" + +#: port/win32_shmem.c:123 port/win32_shmem.c:131 port/win32_shmem.c:143 +#: port/win32_shmem.c:158 +#, c-format +msgid "Failed system call was %s." +msgstr "La chiamata di sistema fallita è %s." + +#: port/win32_shmem.c:153 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "abilitazione del privilegio Lock Pages fallito" + +#: port/win32_shmem.c:154 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Assegna il privilegio Lock Pages in Memory all'utente Window che esegue PostgreSQL." + +#: port/win32_shmem.c:210 +#, c-format +msgid "the processor does not support large pages" +msgstr "il processore non supporta large pages" + +#: port/win32_shmem.c:212 port/win32_shmem.c:217 +#, c-format +msgid "disabling huge pages" +msgstr "huge page disabilitate" + +#: port/win32_shmem.c:279 port/win32_shmem.c:315 port/win32_shmem.c:333 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "creazione del segmento di memoria condivisa fallito: codice errore %lu" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:280 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "La funzione di sistema fallita era CreateFileMapping(size=%zu, name=%s)." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:305 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "blocco di memoria condivisa preesistente ancora in uso" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:306 #, c-format msgid "Check if there are any old server processes still running, and terminate them." msgstr "Controlla se ci sono vecchi processi server ancora in esecuzione ed interrompili." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:316 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "La chiamata di sistema fallita era DuplicateHandle." -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:334 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "La chiamata di sistema fallita era MapViewOfFileEx." -#: postmaster/autovacuum.c:416 +#: postmaster/autovacuum.c:406 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "fork del processo di esecuzione di autovacuum fallito: %m" -#: postmaster/autovacuum.c:452 +#: postmaster/autovacuum.c:442 #, c-format msgid "autovacuum launcher started" msgstr "esecutore di autovacuum avviato" -#: postmaster/autovacuum.c:838 +#: postmaster/autovacuum.c:832 #, c-format msgid "autovacuum launcher shutting down" msgstr "arresto dell'esecutore di autovacuum" -#: postmaster/autovacuum.c:1500 +#: postmaster/autovacuum.c:1494 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "fork del processo di lavoro di autovacuum fallito: %m" -#: postmaster/autovacuum.c:1706 +#: postmaster/autovacuum.c:1700 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "autovacuum: elaborazione del database \"%s\"" -#: postmaster/autovacuum.c:2280 +#: postmaster/autovacuum.c:2269 #, c-format msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" msgstr "autovacuum: eliminazione della tabella temporanea orfana \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2486 +#: postmaster/autovacuum.c:2498 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "pulizia automatica della tabella \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2489 +#: postmaster/autovacuum.c:2501 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "analisi automatica della tabella \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2700 +#: postmaster/autovacuum.c:2694 #, c-format msgid "processing work entry for relation \"%s.%s.%s\"" msgstr "processo a lavoro sulla relazione \"%s.%s.%s\"" -#: postmaster/autovacuum.c:3344 +#: postmaster/autovacuum.c:3273 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "autovacuum non avviato a causa di configurazione errata" -#: postmaster/autovacuum.c:3345 +#: postmaster/autovacuum.c:3274 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Abilita l'opzione \"track_counts\"." -#: postmaster/bgworker.c:393 postmaster/bgworker.c:856 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "registrazione del processo di lavoro in background \"%s\"" -#: postmaster/bgworker.c:425 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "annullamento registrazione del processo di lavoro in background \"%s\"" -#: postmaster/bgworker.c:590 +#: postmaster/bgworker.c:592 #, c-format msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" msgstr "processo di lavoro in background \"%s\": occorre collegarsi al segmento di memoria per richiedere una connessione al database" -#: postmaster/bgworker.c:599 +#: postmaster/bgworker.c:601 #, c-format msgid "background worker \"%s\": cannot request database access if starting at postmaster start" msgstr "processo di lavoro in background \"%s\": non è possibile richiedere accesso al database se avviato all'avvio di postmaster" -#: postmaster/bgworker.c:613 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" msgstr "processo di lavoro in background \"%s\": intervallo di riavvio non valido" -#: postmaster/bgworker.c:628 +#: postmaster/bgworker.c:630 #, c-format msgid "background worker \"%s\": parallel workers may not be configured for restart" msgstr "processo di lavoro in background \"%s\": i worker paralleli non possono essere configurati per il riavvio" -#: postmaster/bgworker.c:673 +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "interruzione del processo di lavoro in background \"%s\" a causa di comando amministrativo" -#: postmaster/bgworker.c:864 +#: postmaster/bgworker.c:863 #, c-format msgid "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "processo di lavoro in background \"%s\": deve essere registrato in shared_preload_libraries" -#: postmaster/bgworker.c:876 +#: postmaster/bgworker.c:875 #, c-format msgid "background worker \"%s\": only dynamic background workers can request notification" msgstr "processo di lavoro in background \"%s\": solo i processi dinamici possono richiedere notifiche" -#: postmaster/bgworker.c:891 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" msgstr "troppi processi di lavoro in background" -#: postmaster/bgworker.c:892 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "Up to %d background workers can be registered with the current settings." msgstr[0] "Le impostazioni correnti consentono la registrazione di un massimo di %d processi di lavoro in background." msgstr[1] "Le impostazioni correnti consentono la registrazione di un massimo di %d processi di lavoro in background." -#: postmaster/bgworker.c:896 +#: postmaster/bgworker.c:895 #, c-format msgid "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "Considera di incrementare il parametro di configurazione \"max_worker_processes\"." -#: postmaster/checkpointer.c:465 +#: postmaster/checkpointer.c:464 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" msgstr[0] "i checkpoint stanno avvenendo troppo frequentemente (a distanza di %d secondo)" msgstr[1] "i checkpoint stanno avvenendo troppo frequentemente (a distanza di %d secondi)" -#: postmaster/checkpointer.c:469 +#: postmaster/checkpointer.c:468 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "Considera di incrementare il parametro di configurazione \"max_wal_size\"." -#: postmaster/checkpointer.c:1088 +#: postmaster/checkpointer.c:1082 #, c-format msgid "checkpoint request failed" msgstr "richiesta di checkpoint fallita" -#: postmaster/checkpointer.c:1089 +#: postmaster/checkpointer.c:1083 #, c-format msgid "Consult recent messages in the server log for details." msgstr "Consulta i messaggi recenti nel log del server per i dettagli." -#: postmaster/checkpointer.c:1284 +#: postmaster/checkpointer.c:1278 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "coda di richieste di fsync ridotta da %d a %d elementi" -#: postmaster/pgarch.c:149 +#: postmaster/pgarch.c:148 #, c-format msgid "could not fork archiver: %m" msgstr "non è possibile fare un fork dell'archiver: %m" -#: postmaster/pgarch.c:457 +#: postmaster/pgarch.c:456 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "archive_mode abilitato, ma archive_command non è impostato" -#: postmaster/pgarch.c:485 +#: postmaster/pgarch.c:484 #, c-format msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" msgstr "archiviazione del file di log write-ahead \"%s\" fallita troppe volte, verrà riprovato più tardi" -#: postmaster/pgarch.c:588 +#: postmaster/pgarch.c:587 #, c-format msgid "archive command failed with exit code %d" msgstr "comando di archiviazione fallito con codice di uscita %d" -#: postmaster/pgarch.c:590 postmaster/pgarch.c:600 postmaster/pgarch.c:607 -#: postmaster/pgarch.c:613 postmaster/pgarch.c:622 +#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 +#: postmaster/pgarch.c:612 postmaster/pgarch.c:621 #, c-format msgid "The failed archive command was: %s" msgstr "Il comando di archiviazione fallito era: %s" -#: postmaster/pgarch.c:597 +#: postmaster/pgarch.c:596 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "comando di archiviazione terminato da eccezione 0x%X" -#: postmaster/pgarch.c:599 postmaster/postmaster.c:3541 +#: postmaster/pgarch.c:598 postmaster/postmaster.c:3567 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "Consulta il file include C \"ntstatus.h\" per una spiegazione del valore esadecimale." -#: postmaster/pgarch.c:604 +#: postmaster/pgarch.c:603 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "comando di archiviazione terminato dal segnale %d: %s" -#: postmaster/pgarch.c:611 +#: postmaster/pgarch.c:610 #, c-format msgid "archive command was terminated by signal %d" msgstr "comando di archiviazione terminato dal segnale %d" -#: postmaster/pgarch.c:620 +#: postmaster/pgarch.c:619 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "processo di archiviazione uscito con stato sconosciuto %d" -#: postmaster/pgarch.c:680 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "apertura della directory dello stato dell'archivio \"%s\" fallita: %m" - #: postmaster/pgstat.c:395 #, c-format msgid "could not resolve \"localhost\": %s" @@ -15542,213 +16287,173 @@ msgstr "destinazione di reset sconosciuta: \"%s\"" msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "La destinazione deve essere \"archiver\" o \"bgwriter\"." -#: postmaster/pgstat.c:4287 +#: postmaster/pgstat.c:4362 #, c-format msgid "could not read statistics message: %m" msgstr "lettura del messaggio delle statistiche fallito: %m" -#: postmaster/pgstat.c:4619 postmaster/pgstat.c:4776 +#: postmaster/pgstat.c:4694 postmaster/pgstat.c:4851 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "apertura del file temporaneo delle statistiche \"%s\" fallita: %m" -#: postmaster/pgstat.c:4686 postmaster/pgstat.c:4821 +#: postmaster/pgstat.c:4761 postmaster/pgstat.c:4896 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "scrittura del file temporaneo delle statistiche \"%s\" fallita: %m" -#: postmaster/pgstat.c:4695 postmaster/pgstat.c:4830 +#: postmaster/pgstat.c:4770 postmaster/pgstat.c:4905 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "chiusura del file temporaneo delle statistiche \"%s\" fallita: %m" -#: postmaster/pgstat.c:4703 postmaster/pgstat.c:4838 +#: postmaster/pgstat.c:4778 postmaster/pgstat.c:4913 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "non è stato possibile rinominare il file temporaneo delle statistiche \"%s\" in \"%s\": %m" -#: postmaster/pgstat.c:4927 postmaster/pgstat.c:5112 postmaster/pgstat.c:5265 +#: postmaster/pgstat.c:5002 postmaster/pgstat.c:5208 postmaster/pgstat.c:5361 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "apertura del file delle statistiche \"%s\" fallita: %m" -#: postmaster/pgstat.c:4939 postmaster/pgstat.c:4949 postmaster/pgstat.c:4959 -#: postmaster/pgstat.c:4980 postmaster/pgstat.c:4995 postmaster/pgstat.c:5049 -#: postmaster/pgstat.c:5124 postmaster/pgstat.c:5144 postmaster/pgstat.c:5162 -#: postmaster/pgstat.c:5178 postmaster/pgstat.c:5196 postmaster/pgstat.c:5212 -#: postmaster/pgstat.c:5277 postmaster/pgstat.c:5289 postmaster/pgstat.c:5301 -#: postmaster/pgstat.c:5326 postmaster/pgstat.c:5348 +#: postmaster/pgstat.c:5014 postmaster/pgstat.c:5024 postmaster/pgstat.c:5045 +#: postmaster/pgstat.c:5067 postmaster/pgstat.c:5082 postmaster/pgstat.c:5145 +#: postmaster/pgstat.c:5220 postmaster/pgstat.c:5240 postmaster/pgstat.c:5258 +#: postmaster/pgstat.c:5274 postmaster/pgstat.c:5292 postmaster/pgstat.c:5308 +#: postmaster/pgstat.c:5373 postmaster/pgstat.c:5385 postmaster/pgstat.c:5397 +#: postmaster/pgstat.c:5422 postmaster/pgstat.c:5444 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "file delle statistiche corrotto \"%s\"" -#: postmaster/pgstat.c:5477 +#: postmaster/pgstat.c:5573 #, c-format msgid "using stale statistics instead of current ones because stats collector is not responding" msgstr "verranno utilizzate statistiche vecchie invece di quelle correnti perché il processo di raccolta statistiche non risponde" -#: postmaster/pgstat.c:5804 +#: postmaster/pgstat.c:5900 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "tabella hash del database corrotta durante la pulizia --- interruzione" -#: postmaster/postmaster.c:706 +#: postmaster/postmaster.c:717 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s: argomento non valido per l'opzione -f: \"%s\"\n" -#: postmaster/postmaster.c:792 +#: postmaster/postmaster.c:803 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s: argomento non valido per l'opzione -t: \"%s\"\n" -#: postmaster/postmaster.c:843 +#: postmaster/postmaster.c:854 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s: argomento non valido: \"%s\"\n" -#: postmaster/postmaster.c:882 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s: superuser_reserved_connections dev'essere minore di max_connections\n" - -#: postmaster/postmaster.c:887 +#: postmaster/postmaster.c:896 #, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_senders dev'essere minore di max_connections\n" +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) più max_wal_senders (%d) dev'essere meno di max_connections (%d)\n" -#: postmaster/postmaster.c:892 +#: postmaster/postmaster.c:903 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "l'archiviazione dei WAL non può essere attivata quando wal_level è \"minimal\"" -#: postmaster/postmaster.c:895 +#: postmaster/postmaster.c:906 #, c-format msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" msgstr "lo streaming WAL (max_wal_senders > 0) richiede wal_level \"replica\" oppure \"logical\"" -#: postmaster/postmaster.c:903 +#: postmaster/postmaster.c:914 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s: datetoken tables non valido, per favore correggilo\n" -#: postmaster/postmaster.c:1006 postmaster/postmaster.c:1104 -#: utils/init/miscinit.c:1446 +#: postmaster/postmaster.c:1028 postmaster/postmaster.c:1126 +#: utils/init/miscinit.c:1555 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "sintassi di lista non valida nel parametro \"%s\"" -#: postmaster/postmaster.c:1037 +#: postmaster/postmaster.c:1059 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "creazione del socket di ascolto per \"%s\" fallita" -#: postmaster/postmaster.c:1043 +#: postmaster/postmaster.c:1065 #, c-format msgid "could not create any TCP/IP sockets" msgstr "non è stato possibile creare alcun socket TCP/IP" -#: postmaster/postmaster.c:1126 +#: postmaster/postmaster.c:1148 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "creazione del socket di dominio Unix fallita nella directory \"%s\"" -#: postmaster/postmaster.c:1132 +#: postmaster/postmaster.c:1154 #, c-format msgid "could not create any Unix-domain sockets" msgstr "creazione del socket di dominio Unix fallita" -#: postmaster/postmaster.c:1144 +#: postmaster/postmaster.c:1166 #, c-format msgid "no socket created for listening" msgstr "nessun socket per l'ascolto è stato creato" -#: postmaster/postmaster.c:1184 +#: postmaster/postmaster.c:1206 #, c-format msgid "could not create I/O completion port for child queue" msgstr "creazione della porta di completamento I/O per la coda dei figli fallita" -#: postmaster/postmaster.c:1213 +#: postmaster/postmaster.c:1235 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: modifica dei permessi del file PID esterno \"%s\" fallita: %s\n" -#: postmaster/postmaster.c:1217 +#: postmaster/postmaster.c:1239 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: scrittura del file PID esterno \"%s\" fallita: %s\n" -#: postmaster/postmaster.c:1274 +#: postmaster/postmaster.c:1296 #, c-format msgid "ending log output to stderr" msgstr "terminazione dell'output del log su stderr" -#: postmaster/postmaster.c:1275 +#: postmaster/postmaster.c:1297 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "L'output dei prossimi log andrà su \"%s\"." -#: postmaster/postmaster.c:1301 utils/init/postinit.c:213 +#: postmaster/postmaster.c:1323 utils/init/postinit.c:214 #, c-format msgid "could not load pg_hba.conf" msgstr "caricamento di pg_hba.conf fallito" -#: postmaster/postmaster.c:1327 +#: postmaster/postmaster.c:1349 #, c-format msgid "postmaster became multithreaded during startup" msgstr "il postmaster è diventato multithread durante l'avvio" -#: postmaster/postmaster.c:1328 +#: postmaster/postmaster.c:1350 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "Imposta la variabile d'ambiente LC_ALL non corrisponde ad un locale valido." -#: postmaster/postmaster.c:1427 +#: postmaster/postmaster.c:1455 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s: eseguibile postgres corrispondente non trovato" -#: postmaster/postmaster.c:1450 utils/misc/tzparser.c:341 +#: postmaster/postmaster.c:1478 utils/misc/tzparser.c:341 #, c-format msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." msgstr "Questo potrebbe indicare una installazione di PostgreSQL incompleta, o che il file \"%s\" sia stato spostato dalla sua posizione corretta." -#: postmaster/postmaster.c:1478 -#, c-format -msgid "data directory \"%s\" does not exist" -msgstr "la directory dei dati \"%s\" non esiste" - -#: postmaster/postmaster.c:1483 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "lettura dei permessi della directory \"%s\" fallita: %m" - -#: postmaster/postmaster.c:1491 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "la directory dei dati specificata \"%s\" non è una directory" - -#: postmaster/postmaster.c:1507 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "la directory dei dati \"%s\" ha il proprietario errato" - -#: postmaster/postmaster.c:1509 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "Il server deve essere avviato dall'utente che possiede la directory dei dati." - -#: postmaster/postmaster.c:1529 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "la directory dei dati \"%s\" è accessibile dal gruppo o da tutti" - -#: postmaster/postmaster.c:1531 -#, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "I permessi dovrebbero essere u=rwx (0700)." - -#: postmaster/postmaster.c:1542 +#: postmaster/postmaster.c:1505 #, c-format msgid "" "%s: could not find the database system\n" @@ -15759,441 +16464,452 @@ msgstr "" "Sarebbe dovuto essere nella directory \"%s\",\n" "ma l'apertura del file \"%s\" è fallita: %s\n" -#: postmaster/postmaster.c:1719 +#: postmaster/postmaster.c:1682 #, c-format msgid "select() failed in postmaster: %m" msgstr "select() fallita in postmaster: %m" -#: postmaster/postmaster.c:1870 +#: postmaster/postmaster.c:1837 #, c-format msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "arresto immediato perché il file di lock della directory dati non è valido" -#: postmaster/postmaster.c:1948 postmaster/postmaster.c:1979 +#: postmaster/postmaster.c:1915 postmaster/postmaster.c:1946 #, c-format msgid "incomplete startup packet" msgstr "pacchetto di avvio incompleto" -#: postmaster/postmaster.c:1960 +#: postmaster/postmaster.c:1927 #, c-format msgid "invalid length of startup packet" msgstr "dimensione del pacchetto di avvio non valida" -#: postmaster/postmaster.c:2018 +#: postmaster/postmaster.c:1985 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "invio della risposta di negoziazione SSL fallito: %m" -#: postmaster/postmaster.c:2047 +#: postmaster/postmaster.c:2011 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "protocollo frontend non supportato %u.%u: il server supporta da %u.0 a %u.%u" -#: postmaster/postmaster.c:2110 utils/misc/guc.c:5759 utils/misc/guc.c:5852 -#: utils/misc/guc.c:7153 utils/misc/guc.c:9907 utils/misc/guc.c:9941 +#: postmaster/postmaster.c:2075 utils/misc/guc.c:6004 utils/misc/guc.c:6097 +#: utils/misc/guc.c:7423 utils/misc/guc.c:10186 utils/misc/guc.c:10220 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "valore non valido per il parametro \"%s\": \"%s\"" -#: postmaster/postmaster.c:2113 +#: postmaster/postmaster.c:2078 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "I valori validi sono: \"false\", 0, \"true\", 1, \"database\"." -#: postmaster/postmaster.c:2133 +#: postmaster/postmaster.c:2108 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "formato del pacchetto di avvio non valido: atteso il terminatore all'ultimo byte" -#: postmaster/postmaster.c:2161 +#: postmaster/postmaster.c:2146 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "nessun utente PostgreSQL specificato nel pacchetto di avvio" -#: postmaster/postmaster.c:2220 +#: postmaster/postmaster.c:2205 #, c-format msgid "the database system is starting up" msgstr "il database si sta avviando" -#: postmaster/postmaster.c:2225 +#: postmaster/postmaster.c:2210 #, c-format msgid "the database system is shutting down" msgstr "il database si sta spegnendo" -#: postmaster/postmaster.c:2230 +#: postmaster/postmaster.c:2215 #, c-format msgid "the database system is in recovery mode" msgstr "il database è in modalità di ripristino" -#: postmaster/postmaster.c:2235 storage/ipc/procarray.c:291 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:338 +#: postmaster/postmaster.c:2220 storage/ipc/procarray.c:292 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:339 #, c-format msgid "sorry, too many clients already" msgstr "spiacente, troppi client già connessi" -#: postmaster/postmaster.c:2297 +#: postmaster/postmaster.c:2310 #, c-format msgid "wrong key in cancel request for process %d" msgstr "chiave sbagliata nella richiesta di annullamento per il processo %d" -#: postmaster/postmaster.c:2305 +#: postmaster/postmaster.c:2318 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "il PID %d nella richiesta di annullamento non corrisponde ad alcun processo" -#: postmaster/postmaster.c:2516 +#: postmaster/postmaster.c:2529 #, c-format msgid "received SIGHUP, reloading configuration files" msgstr "SIGHUP ricevuto, sto ricaricando i file di configurazione" -#: postmaster/postmaster.c:2541 +#: postmaster/postmaster.c:2554 #, c-format msgid "pg_hba.conf was not reloaded" msgstr "pg_hba.conf non è stato ricaricato" -#: postmaster/postmaster.c:2545 +#: postmaster/postmaster.c:2558 #, c-format msgid "pg_ident.conf was not reloaded" msgstr "pg_ident.conf non è stato ricaricato" -#: postmaster/postmaster.c:2555 +#: postmaster/postmaster.c:2568 #, c-format msgid "SSL configuration was not reloaded" msgstr "la configurazione SSL non è stata ricaricata" -#: postmaster/postmaster.c:2603 +#: postmaster/postmaster.c:2616 #, c-format msgid "received smart shutdown request" msgstr "richiesta di arresto smart ricevuta" -#: postmaster/postmaster.c:2658 +#: postmaster/postmaster.c:2674 #, c-format msgid "received fast shutdown request" msgstr "richiesta di arresto fast ricevuta" -#: postmaster/postmaster.c:2688 +#: postmaster/postmaster.c:2707 #, c-format msgid "aborting any active transactions" msgstr "interruzione di tutte le transazioni attive" -#: postmaster/postmaster.c:2722 +#: postmaster/postmaster.c:2741 #, c-format msgid "received immediate shutdown request" msgstr "richiesta di arresto immediate ricevuta" -#: postmaster/postmaster.c:2786 +#: postmaster/postmaster.c:2808 #, c-format msgid "shutdown at recovery target" msgstr "arresto alla destinazione di recupero" -#: postmaster/postmaster.c:2802 postmaster/postmaster.c:2825 +#: postmaster/postmaster.c:2824 postmaster/postmaster.c:2847 msgid "startup process" msgstr "avvio del processo" -#: postmaster/postmaster.c:2805 +#: postmaster/postmaster.c:2827 #, c-format msgid "aborting startup due to startup process failure" msgstr "avvio interrotto a causa del fallimento del processo di avvio" -#: postmaster/postmaster.c:2866 +#: postmaster/postmaster.c:2888 #, c-format msgid "database system is ready to accept connections" msgstr "il database è pronto ad accettare connessioni" -#: postmaster/postmaster.c:2885 +#: postmaster/postmaster.c:2909 msgid "background writer process" msgstr "processo di scrittura in background" -#: postmaster/postmaster.c:2939 +#: postmaster/postmaster.c:2963 msgid "checkpointer process" msgstr "processo di creazione checkpoint" -#: postmaster/postmaster.c:2955 +#: postmaster/postmaster.c:2979 msgid "WAL writer process" msgstr "processo di scrittura WAL" -#: postmaster/postmaster.c:2969 +#: postmaster/postmaster.c:2994 msgid "WAL receiver process" msgstr "processo di ricezione WAL" -#: postmaster/postmaster.c:2984 +#: postmaster/postmaster.c:3009 msgid "autovacuum launcher process" msgstr "processo del lanciatore di autovacuum" -#: postmaster/postmaster.c:2999 +#: postmaster/postmaster.c:3024 msgid "archiver process" msgstr "processo di archiviazione" -#: postmaster/postmaster.c:3015 +#: postmaster/postmaster.c:3040 msgid "statistics collector process" msgstr "processo del raccoglitore di statistiche" -#: postmaster/postmaster.c:3029 +#: postmaster/postmaster.c:3054 msgid "system logger process" msgstr "processo del logger di sistema" -#: postmaster/postmaster.c:3091 -msgid "worker process" -msgstr "processo di lavoro" +#: postmaster/postmaster.c:3116 +#, c-format +msgid "background worker \"%s\"" +msgstr "processo di lavoro in background \"%s\"" -#: postmaster/postmaster.c:3174 postmaster/postmaster.c:3194 -#: postmaster/postmaster.c:3201 postmaster/postmaster.c:3219 +#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 +#: postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 msgid "server process" msgstr "processo del server" -#: postmaster/postmaster.c:3273 +#: postmaster/postmaster.c:3299 #, c-format msgid "terminating any other active server processes" msgstr "interruzione di tutti gli altri processi attivi del server" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3529 +#: postmaster/postmaster.c:3555 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) è uscito con codice di uscita %d" -#: postmaster/postmaster.c:3531 postmaster/postmaster.c:3542 -#: postmaster/postmaster.c:3553 postmaster/postmaster.c:3562 -#: postmaster/postmaster.c:3572 +#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 +#: postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 +#: postmaster/postmaster.c:3598 #, c-format msgid "Failed process was running: %s" msgstr "Il processo fallito stava eseguendo: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3539 +#: postmaster/postmaster.c:3565 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) è stato terminato dall'eccezione 0x%X" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3549 +#: postmaster/postmaster.c:3575 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) è stato terminato dal segnale %d: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3560 +#: postmaster/postmaster.c:3586 #, c-format msgid "%s (PID %d) was terminated by signal %d" msgstr "%s (PID %d) è stato terminato dal segnale %d" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3570 +#: postmaster/postmaster.c:3596 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" msgstr "%s (PID %d) uscito con stato sconosciuto %d" -#: postmaster/postmaster.c:3760 +#: postmaster/postmaster.c:3783 #, c-format msgid "abnormal database system shutdown" msgstr "spegnimento anormale del database" -#: postmaster/postmaster.c:3800 +#: postmaster/postmaster.c:3823 #, c-format msgid "all server processes terminated; reinitializing" msgstr "tutti i processi server sono terminati; re-inizializzazione" -#: postmaster/postmaster.c:3966 postmaster/postmaster.c:5361 -#: postmaster/postmaster.c:5707 +#: postmaster/postmaster.c:3993 postmaster/postmaster.c:5418 +#: postmaster/postmaster.c:5782 #, c-format msgid "could not generate random cancel key" msgstr "generazione della chiave di annullamento casuale fallita" -#: postmaster/postmaster.c:4020 +#: postmaster/postmaster.c:4047 #, c-format msgid "could not fork new process for connection: %m" msgstr "fork del nuovo processo per la connessione fallito: %m" -#: postmaster/postmaster.c:4062 +#: postmaster/postmaster.c:4089 msgid "could not fork new process for connection: " msgstr "fork del nuovo processo per la connessione fallito: " -#: postmaster/postmaster.c:4176 +#: postmaster/postmaster.c:4203 #, c-format msgid "connection received: host=%s port=%s" msgstr "connessione ricevuta: host=%s porta=%s" -#: postmaster/postmaster.c:4181 +#: postmaster/postmaster.c:4208 #, c-format msgid "connection received: host=%s" msgstr "connessione ricevuta: host=%s" -#: postmaster/postmaster.c:4466 +#: postmaster/postmaster.c:4493 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "esecuzione del processo del server \"%s\" fallita: %m" -#: postmaster/postmaster.c:4809 +#: postmaster/postmaster.c:4646 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "mi sono arreso dopo troppi tentativi di riservare memoria condivisa" + +#: postmaster/postmaster.c:4647 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Ciò potrebbe essere causato da ASLR o software antivirus." + +#: postmaster/postmaster.c:4858 #, c-format msgid "SSL configuration could not be loaded in child process" msgstr "errore nel caricamento della configurazione SSL nel processo figlio" -#: postmaster/postmaster.c:4941 +#: postmaster/postmaster.c:4990 #, c-format msgid "Please report this to ." msgstr "Per favore segnala questo problema a ." -#: postmaster/postmaster.c:5020 +#: postmaster/postmaster.c:5077 #, c-format msgid "database system is ready to accept read only connections" msgstr "il database è pronto ad accettare connessioni in sola lettura" -#: postmaster/postmaster.c:5289 +#: postmaster/postmaster.c:5346 #, c-format msgid "could not fork startup process: %m" msgstr "fork del processo di avvio fallito: %m" -#: postmaster/postmaster.c:5293 +#: postmaster/postmaster.c:5350 #, c-format msgid "could not fork background writer process: %m" msgstr "fork del processo di scrittura in background fallito: %m" -#: postmaster/postmaster.c:5297 +#: postmaster/postmaster.c:5354 #, c-format msgid "could not fork checkpointer process: %m" msgstr "fork del processo di creazione dei checkpoint fallito: %m" -#: postmaster/postmaster.c:5301 +#: postmaster/postmaster.c:5358 #, c-format msgid "could not fork WAL writer process: %m" msgstr "fork del processo di scrittura dei WAL fallito: %m" -#: postmaster/postmaster.c:5305 +#: postmaster/postmaster.c:5362 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "fork del processo di ricezione dei WAL fallito: %m" -#: postmaster/postmaster.c:5309 +#: postmaster/postmaster.c:5366 #, c-format msgid "could not fork process: %m" msgstr "fork del processo fallito: %m" -#: postmaster/postmaster.c:5478 postmaster/postmaster.c:5501 +#: postmaster/postmaster.c:5553 postmaster/postmaster.c:5576 #, c-format msgid "database connection requirement not indicated during registration" msgstr "requisiti di connessione a database non indicati durante la registrazione" -#: postmaster/postmaster.c:5485 postmaster/postmaster.c:5508 +#: postmaster/postmaster.c:5560 postmaster/postmaster.c:5583 #, c-format msgid "invalid processing mode in background worker" msgstr "modalità di processo non valida nel processo di lavoro in background" -#: postmaster/postmaster.c:5580 +#: postmaster/postmaster.c:5655 #, c-format msgid "starting background worker process \"%s\"" msgstr "avvio del processo di lavoro in background \"%s\"" -#: postmaster/postmaster.c:5592 +#: postmaster/postmaster.c:5667 #, c-format msgid "could not fork worker process: %m" msgstr "fork del processo di lavoro in background fallito: %m" -#: postmaster/postmaster.c:6016 +#: postmaster/postmaster.c:6100 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "duplicazione del socket %d da usare nel backend fallita: codice errore %d" -#: postmaster/postmaster.c:6048 +#: postmaster/postmaster.c:6132 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "creazione del socket ereditato fallita: codice errore %d\n" -#: postmaster/postmaster.c:6077 +#: postmaster/postmaster.c:6161 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "apertura del file delle variabili del backend \"%s\" fallita: %s\n" -#: postmaster/postmaster.c:6084 +#: postmaster/postmaster.c:6168 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "lettura dal file delle variabili del backend \"%s\" fallita: %s\n" -#: postmaster/postmaster.c:6093 +#: postmaster/postmaster.c:6177 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "rimozione del file \"%s\" fallita: %s\n" -#: postmaster/postmaster.c:6110 +#: postmaster/postmaster.c:6194 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "non è stato possibile mappare la vista delle variabili del backend: codice errore %lu\n" -#: postmaster/postmaster.c:6119 +#: postmaster/postmaster.c:6203 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "non è stato possibile rimuovere la mappa della vista delle variabili del backend: codice errore %lu\n" -#: postmaster/postmaster.c:6126 +#: postmaster/postmaster.c:6210 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "chiusura dell'handle dei parametri variabili del backend fallita: codice errore %lu\n" -#: postmaster/postmaster.c:6287 +#: postmaster/postmaster.c:6371 #, c-format msgid "could not read exit code for process\n" msgstr "lettura del codice di uscita del processo fallita\n" -#: postmaster/postmaster.c:6292 +#: postmaster/postmaster.c:6376 #, c-format msgid "could not post child completion status\n" msgstr "invio dello stato di completamento del figlio fallito\n" -#: postmaster/syslogger.c:452 postmaster/syslogger.c:1053 +#: postmaster/syslogger.c:470 postmaster/syslogger.c:1146 #, c-format msgid "could not read from logger pipe: %m" msgstr "lettura dalla pipe del logger fallita: %m" -#: postmaster/syslogger.c:502 +#: postmaster/syslogger.c:520 #, c-format msgid "logger shutting down" msgstr "spegnimento del logger" -#: postmaster/syslogger.c:546 postmaster/syslogger.c:560 +#: postmaster/syslogger.c:564 postmaster/syslogger.c:578 #, c-format msgid "could not create pipe for syslog: %m" msgstr "creazione della pipe per il syslog fallita: %m" -#: postmaster/syslogger.c:596 +#: postmaster/syslogger.c:629 #, c-format msgid "could not fork system logger: %m" msgstr "fork del logger di sistema fallito: %m" -#: postmaster/syslogger.c:632 +#: postmaster/syslogger.c:665 #, c-format msgid "redirecting log output to logging collector process" msgstr "redirezione dell'output ti log al processo di raccolta dei log" -#: postmaster/syslogger.c:633 +#: postmaster/syslogger.c:666 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "I prossimi output di log appariranno nella directory \"%s\"." -#: postmaster/syslogger.c:641 +#: postmaster/syslogger.c:674 #, c-format msgid "could not redirect stdout: %m" msgstr "redirezione di stdout fallita: %m" -#: postmaster/syslogger.c:646 postmaster/syslogger.c:663 +#: postmaster/syslogger.c:679 postmaster/syslogger.c:696 #, c-format msgid "could not redirect stderr: %m" msgstr "redirezione di stderr fallita: %m" -#: postmaster/syslogger.c:1008 +#: postmaster/syslogger.c:1101 #, c-format msgid "could not write to log file: %s\n" msgstr "scrittura nel file di log fallita: %s\n" -#: postmaster/syslogger.c:1150 +#: postmaster/syslogger.c:1218 #, c-format msgid "could not open log file \"%s\": %m" msgstr "apertura del file di log \"%s\" fallita: %m" -#: postmaster/syslogger.c:1212 postmaster/syslogger.c:1256 +#: postmaster/syslogger.c:1280 postmaster/syslogger.c:1330 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "rotazione automatica disabilitata (usa SIGHUP per abilitarla di nuovo)" @@ -16203,266 +16919,311 @@ msgstr "rotazione automatica disabilitata (usa SIGHUP per abilitarla di nuovo)" msgid "could not determine which collation to use for regular expression" msgstr "non è stato possibile determinare quale ordinamento usare per le espressioni regolari" -#: replication/basebackup.c:303 +#: replication/basebackup.c:336 #, c-format msgid "could not stat control file \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sul file di controllo \"%s\": %m" -#: replication/basebackup.c:412 +#: replication/basebackup.c:443 #, c-format msgid "could not find any WAL files" msgstr "nessun file WAL trovato" -#: replication/basebackup.c:425 replication/basebackup.c:439 -#: replication/basebackup.c:448 +#: replication/basebackup.c:457 replication/basebackup.c:472 +#: replication/basebackup.c:481 #, c-format msgid "could not find WAL file \"%s\"" msgstr "file WAL \"%s\" non trovato" -#: replication/basebackup.c:487 replication/basebackup.c:513 +#: replication/basebackup.c:523 replication/basebackup.c:551 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "dimensione inaspettata del file WAL \"%s\"" -#: replication/basebackup.c:499 replication/basebackup.c:1228 +#: replication/basebackup.c:537 replication/basebackup.c:1529 #, c-format msgid "base backup could not send data, aborting backup" msgstr "invio dati da parte del backup di base fallito, backup interrotto" -#: replication/basebackup.c:601 replication/basebackup.c:610 -#: replication/basebackup.c:619 replication/basebackup.c:628 -#: replication/basebackup.c:637 replication/basebackup.c:648 -#: replication/basebackup.c:665 +#: replication/basebackup.c:609 +#, c-format +msgid "%s total checksum verification failures" +msgstr "%s fallimenti di verifica checksum totale" + +#: replication/basebackup.c:613 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "fallimento verifica checksum durante il backup di base" + +#: replication/basebackup.c:657 replication/basebackup.c:666 +#: replication/basebackup.c:675 replication/basebackup.c:684 +#: replication/basebackup.c:693 replication/basebackup.c:704 +#: replication/basebackup.c:721 replication/basebackup.c:730 #, c-format msgid "duplicate option \"%s\"" msgstr "opzione duplicata \"%s\"" -#: replication/basebackup.c:654 utils/misc/guc.c:5769 +#: replication/basebackup.c:710 utils/misc/guc.c:6014 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d non è compreso nell'intervallo di validità del il parametro \"%s\" (%d .. %d)" -#: replication/basebackup.c:928 replication/basebackup.c:1025 +#: replication/basebackup.c:984 replication/basebackup.c:1154 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "non è stato possibile ottenere informazioni sul file o directory \"%s\": %m" -#: replication/basebackup.c:1180 +#: replication/basebackup.c:1309 #, c-format msgid "skipping special file \"%s\"" msgstr "file speciale \"%s\" saltato" -#: replication/basebackup.c:1293 +#: replication/basebackup.c:1414 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "segmento numero %d non valido nel file \"%s\"" + +#: replication/basebackup.c:1433 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "impossibile verificare il checksum nel file \"%s\", blocco %d: la dimensione del buffer di lettura %d e la dimensione della pagina %d sono diverse" + +#: replication/basebackup.c:1477 replication/basebackup.c:1493 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "errore nell'fseek nel file \"%s\": %m" + +#: replication/basebackup.c:1485 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "errore nella rilettura del blocco %d del file \"%s\": %m" + +#: replication/basebackup.c:1509 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "checksum di verifica fallito nel file \"%s\", blocco %d: calcolato %X ma atteso %X" + +#: replication/basebackup.c:1516 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "ulteriori fallimenti del checksum di verifica nel file \"%s\" non verranno riportati" + +#: replication/basebackup.c:1574 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "il file \"%s\" ha un totale di %d fallimenti di verifiche checksum" + +#: replication/basebackup.c:1602 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "nome del file troppo lungo per il formato tar: \"%s\"" -#: replication/basebackup.c:1298 +#: replication/basebackup.c:1607 #, c-format msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "destinazione del link simbolico troppo lunga per il formato tar: nome del file \"%s\", destinazione \"%s\"" -#: replication/libpqwalreceiver/libpqwalreceiver.c:226 +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 #, c-format msgid "invalid connection string syntax: %s" msgstr "sintassi della stringa di connessione errata: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:250 +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 #, c-format msgid "could not parse connection string: %s" msgstr "interpretazione della stringa di connessione fallita: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:300 +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 #, c-format msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "ricezione fallita dell'identificativo del database e l'ID della timeline dal server primario: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:311 -#: replication/libpqwalreceiver/libpqwalreceiver.c:515 +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 +#: replication/libpqwalreceiver/libpqwalreceiver.c:550 #, c-format msgid "invalid response from primary server" msgstr "risposta non valida dal server primario" -#: replication/libpqwalreceiver/libpqwalreceiver.c:312 +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 #, c-format msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "Identificazione del sistema non riuscita: ricevute %d righe and %d campi, attese %d righe e %d o più campi." -#: replication/libpqwalreceiver/libpqwalreceiver.c:378 -#: replication/libpqwalreceiver/libpqwalreceiver.c:384 -#: replication/libpqwalreceiver/libpqwalreceiver.c:409 +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 +#: replication/libpqwalreceiver/libpqwalreceiver.c:416 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format msgid "could not start WAL streaming: %s" msgstr "avvio dello streaming dei WAL fallito: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:428 +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "invio del messaggio di fine stream al primario fallito: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "risultato imprevisto dopo la fine stream" -#: replication/libpqwalreceiver/libpqwalreceiver.c:470 +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "errore nel terminare il down streaming di COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 #, c-format msgid "error reading result of streaming command: %s" msgstr "errore nella lettura del risultato del comando di streaming: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:478 -#: replication/libpqwalreceiver/libpqwalreceiver.c:688 +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "risultato imprevisto dopo CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:504 +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "errore nella ricezione del file di storia della timeline dal server primario: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:516 +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "Attesa una tupla con 2 campi, ricevute %d tuple con %d campi." -#: replication/libpqwalreceiver/libpqwalreceiver.c:663 -#: replication/libpqwalreceiver/libpqwalreceiver.c:701 -#: replication/libpqwalreceiver/libpqwalreceiver.c:707 +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 +#: replication/libpqwalreceiver/libpqwalreceiver.c:756 +#: replication/libpqwalreceiver/libpqwalreceiver.c:762 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "ricezione dati dallo stream WAL fallita: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:726 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 #, c-format msgid "could not send data to WAL stream: %s" msgstr "invio dati allo stream WAL fallito: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:775 +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "creazione dello slot di replica \"%s\" fallita: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:809 +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 #, c-format -msgid "invalid query responser" -msgstr "risposta della query non valida" +msgid "invalid query response" +msgstr "risposta query non valida" -#: replication/libpqwalreceiver/libpqwalreceiver.c:810 +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 #, c-format msgid "Expected %d fields, got %d fields." msgstr "Attesi %d campi, ricevuti %d campi." -#: replication/libpqwalreceiver/libpqwalreceiver.c:880 +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 #, c-format msgid "the query interface requires a database connection" msgstr "l'interfaccia per le query richiede una connessione ad un database" -#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 msgid "empty query" msgstr "query vuota" -#: replication/logical/launcher.c:264 +#: replication/logical/launcher.c:310 #, c-format msgid "starting logical replication worker for subscription \"%s\"" msgstr "avvio del worker di replica logica per la sottoscrizione \"%s\"" -#: replication/logical/launcher.c:271 +#: replication/logical/launcher.c:317 #, c-format msgid "cannot start logical replication workers when max_replication_slots = 0" msgstr "non è possibile avviare worker di replica logica se max_replication_slots = 0" -#: replication/logical/launcher.c:351 +#: replication/logical/launcher.c:397 #, c-format msgid "out of logical replication worker slots" msgstr "worker di replica logica esauriti" -#: replication/logical/launcher.c:352 +#: replication/logical/launcher.c:398 #, c-format msgid "You might need to increase max_logical_replication_workers." msgstr "Potresti dover aumentare max_logical_replication_workers." -#: replication/logical/launcher.c:397 +#: replication/logical/launcher.c:453 #, c-format msgid "out of background worker slots" msgstr "worker di lavoro in background esauriti" -#: replication/logical/launcher.c:398 +#: replication/logical/launcher.c:454 #, c-format msgid "You might need to increase max_worker_processes." msgstr "Potresti dover aumentare max_worker_processes." -#: replication/logical/launcher.c:549 +#: replication/logical/launcher.c:661 #, c-format msgid "logical replication worker slot %d is empty, cannot attach" msgstr "lo slot del worker di replica logica %d è vuoto, non è possibile agganciarsi" -#: replication/logical/launcher.c:558 +#: replication/logical/launcher.c:670 #, c-format msgid "logical replication worker slot %d is already used by another worker, cannot attach" msgstr "lo slot del worker di replica logica %d è già in uso da un altro processo, non è possibile agganciarsi" -#: replication/logical/launcher.c:791 +#: replication/logical/launcher.c:988 #, c-format msgid "logical replication launcher started" msgstr "lanciatore di replica logica avviato" -#: replication/logical/launcher.c:899 -#, c-format -msgid "logical replication launcher shutting down" -msgstr "lanciatore di replica logica in arresto" - -#: replication/logical/logical.c:83 +#: replication/logical/logical.c:85 #, c-format msgid "logical decoding requires wal_level >= logical" msgstr "la decodifica logica richiede wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:90 #, c-format msgid "logical decoding requires a database connection" msgstr "la decodifica logica richiede una connessione al database" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:108 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "la decodifica logica non può essere usata in modalità di recupero" -#: replication/logical/logical.c:243 replication/logical/logical.c:365 +#: replication/logical/logical.c:250 replication/logical/logical.c:381 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "non si possono usare slot di replica fisica per la decodifica logica" -#: replication/logical/logical.c:248 replication/logical/logical.c:370 +#: replication/logical/logical.c:255 replication/logical/logical.c:386 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "lo slot di replica \"%s\" non è stato creato in questo database" -#: replication/logical/logical.c:255 +#: replication/logical/logical.c:262 #, c-format msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "non si possono creare slot di replica logica in transazioni che hanno effettuato scritture" -#: replication/logical/logical.c:408 +#: replication/logical/logical.c:426 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "avvio della decodifica logica per lo slot \"%s\"" -#: replication/logical/logical.c:410 +#: replication/logical/logical.c:428 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "commit dello streaming delle transazioni dopo %X/%X, lettura del wal a partire da %X/%X" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Commit delle transazioni streaming dopo %X/%X, lettura del WAL dopo %X/%X." -#: replication/logical/logical.c:557 +#: replication/logical/logical.c:578 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "slot \"%s\", plugin di output \"%s\", nel callback %s, LSN associato %X/%X" -#: replication/logical/logical.c:564 +#: replication/logical/logical.c:585 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "slot \"%s\", plugin di output \"%s\", nel callback %s" -#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "solo un superutente o il ruolo di replica può usare uno slot di replica" @@ -16487,142 +17248,142 @@ msgstr "l'array deve essere monodimensionale" msgid "array must not contain nulls" msgstr "l'array non deve contenere NULL" -#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2282 -#: utils/adt/jsonb.c:1357 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 +#: utils/adt/jsonb.c:1269 #, c-format msgid "array must have even number of elements" msgstr "l'array deve avere un numero pari di elementi" -#: replication/logical/logicalfuncs.c:268 +#: replication/logical/logicalfuncs.c:269 #, c-format msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "il plugin di output di decodifica logica \"%s\" produce dati binari, ma la funzione \"%s\" si aspetta dati testuali" -#: replication/logical/origin.c:180 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "solo i superutenti possono interrogare o replicare le origini di replica" -#: replication/logical/origin.c:185 +#: replication/logical/origin.c:190 #, c-format msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "non è possibile interrogare o manipolare le origini di replica quando max_replication_slots = 0" -#: replication/logical/origin.c:190 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "non è possibile manipolare le origini di replica durante il recupero" -#: replication/logical/origin.c:314 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "l'origine di replica \"%s\" non esiste" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "non è stato trovato alcun OID di origine di replica libero" -#: replication/logical/origin.c:351 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "impossibile eliminare l'origine di replica con OID %d, in uso dal pid %d" -#: replication/logical/origin.c:667 +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "l'origine di replica con OID %u non esiste" + +#: replication/logical/origin.c:725 #, c-format msgid "replication checkpoint has wrong magic %u instead of %u" msgstr "il checkpoint di replica ha numero magico sbagliato %u invece di %u" -#: replication/logical/origin.c:699 +#: replication/logical/origin.c:757 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "lettura del file \"%s\" fallita: letti %d di %zu" -#: replication/logical/origin.c:708 +#: replication/logical/origin.c:766 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "nessuno stato di replica libero trovato, incrementa \"max_replication_slots\"" -#: replication/logical/origin.c:726 +#: replication/logical/origin.c:784 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "il checkpoint dello slot di replica ha il checksum sbagliato %u, atteso %u" -#: replication/logical/origin.c:850 +#: replication/logical/origin.c:908 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "l'origine di replica con OID %d è già attiva per il PID %d" -#: replication/logical/origin.c:861 replication/logical/origin.c:1041 +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 #, c-format msgid "could not find free replication state slot for replication origin with OID %u" msgstr "nessuno slot di stato di replica trovato per l'origine di replica con OID %u" -#: replication/logical/origin.c:863 replication/logical/origin.c:1043 -#: replication/slot.c:1450 +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 +#: replication/slot.c:1529 #, c-format msgid "Increase max_replication_slots and try again." msgstr "Incrementa max_replication_slots e prova di nuovo." -#: replication/logical/origin.c:1000 +#: replication/logical/origin.c:1065 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "non è possibile impostare l'origine di replica quando una è già impostata" -#: replication/logical/origin.c:1029 +#: replication/logical/origin.c:1094 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "l'identificativo di replica %d è già attivo per il PID %d" -#: replication/logical/origin.c:1075 replication/logical/origin.c:1270 -#: replication/logical/origin.c:1290 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 +#: replication/logical/origin.c:1363 #, c-format msgid "no replication origin is configured" msgstr "nessuna origine di replica configurata" -#: replication/logical/relation.c:259 +#: replication/logical/relation.c:255 #, c-format msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "la relazione di destinazione di replica logica \"%s.%s\" non esiste" -#: replication/logical/relation.c:292 +#: replication/logical/relation.c:297 #, c-format msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" msgstr "la relazione di destinazione di replica logica \"%s.%s\" ha alcune colonne replicate mancanti" -#: replication/logical/relation.c:332 +#: replication/logical/relation.c:337 #, c-format msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" msgstr "la relazione di destinazione di replica logica \"%s.%s\" usa colonne di sistema nell'indice REPLICA IDENTITY" -#: replication/logical/relation.c:448 -#, c-format -msgid "builtin type %u not found" -msgstr "tipo predefinito %u non trovato" - -#: replication/logical/relation.c:449 -#, c-format -msgid "This can be caused by having publisher with higher major version than subscriber" -msgstr "Ciò può essere causato da un database di pubblicazione di versione maggiore di quello di sottoscrizione" - -#: replication/logical/relation.c:481 -#, c-format -msgid "data type \"%s.%s\" required for logical replication does not exist" -msgstr "il tipo di dato \"%s.%s\" richiesto per la replica logica non esiste" - -#: replication/logical/reorderbuffer.c:2288 +#: replication/logical/reorderbuffer.c:2493 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "scrittura nel file di dati per lo XID %u non riuscita: %m" -#: replication/logical/reorderbuffer.c:2387 -#: replication/logical/reorderbuffer.c:2409 +#: replication/logical/reorderbuffer.c:2586 +#: replication/logical/reorderbuffer.c:2608 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "lettura dal file spill reorderbuffer non riuscita: %m" -#: replication/logical/reorderbuffer.c:2391 -#: replication/logical/reorderbuffer.c:2413 +#: replication/logical/reorderbuffer.c:2590 +#: replication/logical/reorderbuffer.c:2612 #, c-format msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "lettura dal file spill reorderbuffer non riuscita: letti %d byte invece di %u" -#: replication/logical/reorderbuffer.c:3071 +#: replication/logical/reorderbuffer.c:2835 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "errore nella rimozione del file \"%s\" durante la rimozione di pg_replslot/%s/*.xid: %m" + +#: replication/logical/reorderbuffer.c:3301 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "lettura dal file \"%s\" non riuscita: letti %d byte invece di %d" @@ -16639,536 +17400,561 @@ msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs msgstr[0] "snapshot di decidifica logica esportati: \"%s\" con %u ID di transazione" msgstr[1] "snapshot di decidifica logica esportati: \"%s\" con %u ID di transazione" -#: replication/logical/snapbuild.c:1262 replication/logical/snapbuild.c:1355 -#: replication/logical/snapbuild.c:1842 +#: replication/logical/snapbuild.c:1269 replication/logical/snapbuild.c:1362 +#: replication/logical/snapbuild.c:1869 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "la decodifica logica ha trovato un punto consistente a %X/%X" -#: replication/logical/snapbuild.c:1264 +#: replication/logical/snapbuild.c:1271 #, c-format msgid "There are no running transactions." msgstr "Non ci sono transazioni in corso." -#: replication/logical/snapbuild.c:1306 +#: replication/logical/snapbuild.c:1313 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "la decodifica logica ha trovato un punto di avvio iniziale a %X/%X" -#: replication/logical/snapbuild.c:1308 replication/logical/snapbuild.c:1332 +#: replication/logical/snapbuild.c:1315 replication/logical/snapbuild.c:1339 #, c-format msgid "Waiting for transactions (approximately %d) older than %u to end." msgstr "In attesa che alcune transazioni (circa %d) più vecchie di %u finiscano." -#: replication/logical/snapbuild.c:1330 +#: replication/logical/snapbuild.c:1337 #, c-format msgid "logical decoding found initial consistent point at %X/%X" msgstr "la decodifica logica ha trovato il punto iniziale consistente a %X/%X" -#: replication/logical/snapbuild.c:1357 +#: replication/logical/snapbuild.c:1364 #, c-format msgid "There are no old transactions anymore." msgstr "Non ci sono più vecchie transazioni." -#: replication/logical/snapbuild.c:1715 replication/logical/snapbuild.c:1743 -#: replication/logical/snapbuild.c:1760 replication/logical/snapbuild.c:1776 +#: replication/logical/snapbuild.c:1733 replication/logical/snapbuild.c:1764 +#: replication/logical/snapbuild.c:1784 replication/logical/snapbuild.c:1803 #, c-format msgid "could not read file \"%s\", read %d of %d: %m" msgstr "lettura del file \"%s\" non riuscita, letti %d su %d: %m" -#: replication/logical/snapbuild.c:1721 +#: replication/logical/snapbuild.c:1739 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "il file di stato snapbuild \"%s\" ha il numero magico sbagliato: %u invece di %u" -#: replication/logical/snapbuild.c:1726 +#: replication/logical/snapbuild.c:1744 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "il file di stato snapbuild \"%s\" ha una versione non supportata: %u invece di %u" -#: replication/logical/snapbuild.c:1789 +#: replication/logical/snapbuild.c:1816 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "il checksum del file di stato snapbuild \"%s\" non combacia: è %u, sarebbe dovuto essere %u" -#: replication/logical/snapbuild.c:1844 +#: replication/logical/snapbuild.c:1871 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "La decodifica logica inizierà usando uno snapshot salvato." -#: replication/logical/snapbuild.c:1916 +#: replication/logical/snapbuild.c:1943 #, c-format msgid "could not parse file name \"%s\"" msgstr "interpretazione del nome di file \"%s\" fallita" -#: replication/logical/tablesync.c:137 +#: replication/logical/tablesync.c:138 #, c-format -msgid "logical replication synchronization worker finished processing" -msgstr "il worked di sincronizzazione della replica logica ha terminato il lavoro" +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "worker di replica logica di sincronizzazione tabelle per la sottoscrizione \"%s\", la tabella \"%s\" è completata" -#: replication/logical/tablesync.c:632 +#: replication/logical/tablesync.c:685 #, c-format msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" msgstr "errore nella lettura delle informazioni sulla tabella \"%s.%s\" per la pubblicazione: %s" -#: replication/logical/tablesync.c:638 +#: replication/logical/tablesync.c:691 #, c-format msgid "table \"%s.%s\" not found on publisher" msgstr "tabella \"%s.%s\" non trovata sul database di pubblicazione" -#: replication/logical/tablesync.c:668 +#: replication/logical/tablesync.c:721 #, c-format msgid "could not fetch table info for table \"%s.%s\": %s" msgstr "errore nella lettura delle informazioni sulla tabella \"%s.%s\": %s" -#: replication/logical/tablesync.c:738 +#: replication/logical/tablesync.c:791 #, c-format msgid "could not start initial contents copy for table \"%s.%s\": %s" msgstr "errore nell'avvio della copia iniziale dei contenuti per la tabella \"%s.%s\": %s" -#: replication/logical/tablesync.c:846 +#: replication/logical/tablesync.c:904 #, c-format msgid "table copy could not start transaction on publisher" msgstr "inizio della transazione non riuscito per la copia della tabella sul database di pubblicazione" -#: replication/logical/tablesync.c:866 +#: replication/logical/tablesync.c:926 #, c-format msgid "table copy could not finish transaction on publisher" msgstr "completamento della transazione non riuscito per la copia della tabella sul database di pubblicazione" -#: replication/logical/worker.c:283 +#: replication/logical/worker.c:307 #, c-format msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" msgstr "processo dei dati remoti per la replica della tabella di destinazione \"%s.%s\" colonna \"%s\", tipo remoto %s, tipo locale %s" -#: replication/logical/worker.c:486 +#: replication/logical/worker.c:528 #, c-format msgid "ORIGIN message sent out of order" msgstr "messaggi ORIGIN inviati in ordine sbagliato" -#: replication/logical/worker.c:617 +#: replication/logical/worker.c:661 #, c-format -msgid "publisher does not send replica identity column expected by the logical replication target relation \"%s.%s\"" -msgstr "il database di pubblicazione non invia le colonne di identità di replica attese dalla relazione di destinazione di replica logica \"%s.%s\"" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "il database di pubblicazione non ha inviato le colonne di identità di replica attese dalla relazione di destinazione di replica logica \"%s.%s\"" -#: replication/logical/worker.c:624 +#: replication/logical/worker.c:668 #, c-format msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" msgstr "la relazione di destinazione di replica logica \"%s.%s\" non ha né un indice REPLICA IDENTITY né una PRIMARY KEY e la relazione pubblicata non ha REPLICA IDENTITY FULL" -#: replication/logical/worker.c:831 +#: replication/logical/worker.c:1007 #, c-format -msgid "logical replication could not find row for delete in replication target %s" -msgstr "la replica logica non ha trovato la riga da cancellare nella destinazione %s" +msgid "invalid logical replication message type \"%c\"" +msgstr "messaggio di replica logica tipo \"%c\" non valido" -#: replication/logical/worker.c:898 -#, c-format -msgid "invalid logical replication message type %c" -msgstr "messaggio di replica logica tipo %c non valido" - -#: replication/logical/worker.c:1036 +#: replication/logical/worker.c:1148 #, c-format msgid "data stream from publisher has ended" msgstr "stream di dati dal database di pubblicazione terminato" -#: replication/logical/worker.c:1181 +#: replication/logical/worker.c:1307 #, c-format msgid "terminating logical replication worker due to timeout" msgstr "arresto del worker di replica logica per timeout" -#: replication/logical/worker.c:1328 +#: replication/logical/worker.c:1455 #, c-format -msgid "logical replication worker for subscription \"%s\" will stop because the subscription was removed" -msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà terminato perché la sottoscrizione è stata rimossa" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà fermato perché la sottoscrizione è stata rimossa" -#: replication/logical/worker.c:1343 +#: replication/logical/worker.c:1469 #, c-format -msgid "logical replication worker for subscription \"%s\" will stop because the subscription was disabled" -msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà terminato perché la sottoscrizione è stata disabilitata" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà fermato perché la sottoscrizione è stata disabilitata" -#: replication/logical/worker.c:1358 +#: replication/logical/worker.c:1483 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because the connection information was changed" -msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato perché le informazioni di connessione sono cambiate" +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato perché l'informazione di connessione è cambiata" -#: replication/logical/worker.c:1373 +#: replication/logical/worker.c:1497 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because subscription was renamed" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato perché la sottoscrizione è stata rinominata" -#: replication/logical/worker.c:1391 +#: replication/logical/worker.c:1514 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because the replication slot name was changed" +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato perché il nome dello slot di replica è cambiato" -#: replication/logical/worker.c:1406 +#: replication/logical/worker.c:1528 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato le pubblicazioni della sottoscrizione sono cambiate" + +#: replication/logical/worker.c:1631 #, c-format -msgid "logical replication worker for subscription \"%s\" will restart because subscription's publications were changed" -msgstr "il worker di replica logica per la sottoscrizione \"%s\" verrà riavviato perché le pubblicazioni della sottoscrizione sono cambiate" +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "il worker di replica logica per la sottoscrizione %u non verrà avviato perché la sottoscrizione è stata rimossa durante l'avvio" -#: replication/logical/worker.c:1506 +#: replication/logical/worker.c:1643 #, c-format -msgid "logical replication worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" msgstr "il worker di replica logica per la sottoscrizione \"%s\" non verrà avviato perché la sottoscrizione è stata disabilitata all'avvio" -#: replication/logical/worker.c:1562 +#: replication/logical/worker.c:1661 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "il worker di replica logica di sincronizzazione tabelle per la sottoscrizione \"%s\", la tabella \"%s\" è stata avviata" + +#: replication/logical/worker.c:1665 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "il worker di replica logica per la sottoscrizione \"%s\" è partito" + +#: replication/logical/worker.c:1705 #, c-format msgid "subscription has no replication slot set" msgstr "la sottoscrizione non ha uno slot di replica impostato" -#: replication/pgoutput/pgoutput.c:113 +#: replication/pgoutput/pgoutput.c:117 #, c-format msgid "invalid proto_version" msgstr "proto_version non valido" -#: replication/pgoutput/pgoutput.c:118 +#: replication/pgoutput/pgoutput.c:122 #, c-format -msgid "proto_verson \"%s\" out of range" +msgid "proto_version \"%s\" out of range" msgstr "proto_version \"%s\" fuori dall'intervallo consentito" -#: replication/pgoutput/pgoutput.c:135 +#: replication/pgoutput/pgoutput.c:139 #, c-format msgid "invalid publication_names syntax" msgstr "sintassi di publication_names non valida" -#: replication/pgoutput/pgoutput.c:179 +#: replication/pgoutput/pgoutput.c:181 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or lower" msgstr "il cliente ha inviato proto_version=%d ma solo il protocollo %d o inferiore è supportato" -#: replication/pgoutput/pgoutput.c:185 +#: replication/pgoutput/pgoutput.c:187 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or higher" msgstr "il cliente ha inviato proto_version=%d ma solo il protocollo %d o superiore è supportato" -#: replication/pgoutput/pgoutput.c:191 +#: replication/pgoutput/pgoutput.c:193 #, c-format msgid "publication_names parameter missing" msgstr "parametro publication_names mancante" -#: replication/slot.c:181 +#: replication/slot.c:182 #, c-format msgid "replication slot name \"%s\" is too short" msgstr "il nome dello slot di replica \"%s\" è troppo corto" -#: replication/slot.c:190 +#: replication/slot.c:191 #, c-format msgid "replication slot name \"%s\" is too long" msgstr "il nome dello slot di replica \"%s\" è troppo lungo" -#: replication/slot.c:203 +#: replication/slot.c:204 #, c-format msgid "replication slot name \"%s\" contains invalid character" msgstr "il nome dello slot di replica \"%s\" contiene caratteri non validi" -#: replication/slot.c:205 +#: replication/slot.c:206 #, c-format msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." msgstr "I nomi degli slot di replica possono contenere solo lettere minuscole, numeri e il carattere underscore." -#: replication/slot.c:252 +#: replication/slot.c:253 #, c-format msgid "replication slot \"%s\" already exists" msgstr "lo slot di replica \"%s\" esiste già" -#: replication/slot.c:262 +#: replication/slot.c:263 #, c-format msgid "all replication slots are in use" msgstr "tutti gli slot di replica sono in uso" -#: replication/slot.c:263 +#: replication/slot.c:264 #, c-format msgid "Free one or increase max_replication_slots." msgstr "Liberane uno o incrementa max_replication_slots." -#: replication/slot.c:359 +#: replication/slot.c:387 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "lo slot di replica \"%s\" non esiste" -#: replication/slot.c:363 replication/slot.c:881 +#: replication/slot.c:398 replication/slot.c:948 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "lo slot di replica \"%s\" è attivo per il PID %d" -#: replication/slot.c:565 replication/slot.c:1062 replication/slot.c:1411 +#: replication/slot.c:632 replication/slot.c:1136 replication/slot.c:1490 #, c-format msgid "could not remove directory \"%s\"" msgstr "eliminazione della directory \"%s\" fallita" -#: replication/slot.c:911 +#: replication/slot.c:978 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "gli slot di replica possono essere usati solo se max_replication_slots > 0" -#: replication/slot.c:916 +#: replication/slot.c:983 #, c-format msgid "replication slots can only be used if wal_level >= replica" msgstr "gli slot di replica possono essere usati solo se wal_level >= replica" -#: replication/slot.c:1341 replication/slot.c:1381 +#: replication/slot.c:1422 replication/slot.c:1462 #, c-format msgid "could not read file \"%s\", read %d of %u: %m" msgstr "lettura del file \"%s\" fallita, letti %d su %u: %m" -#: replication/slot.c:1350 +#: replication/slot.c:1431 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "il file dello slot di replica \"%s\" ha il numero magico sbagliato: %u invece di %u" -#: replication/slot.c:1357 +#: replication/slot.c:1438 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "il file dello slot di replica \"%s\" ha la versione non supportata %u" -#: replication/slot.c:1364 +#: replication/slot.c:1445 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "il file dello slot di replica \"%s\" ha la lunghezza corrotta %u" -#: replication/slot.c:1396 +#: replication/slot.c:1477 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "il checksum del file dello slot di replica \"%s\" non combacia: è %u, sarebbe dovuto essere %u" -#: replication/slot.c:1449 +#: replication/slot.c:1528 #, c-format msgid "too many replication slots active before shutdown" msgstr "troppi slot di replica attivi prima dell'arresto" -#: replication/syncrep.c:248 +#: replication/slotfuncs.c:490 +#, c-format +msgid "invalid target wal lsn" +msgstr "wal lsn di destinazione non valida" + +#: replication/slotfuncs.c:512 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "non è possibile avanzare uno slot di replica che non ha precedentemente riservato WAL" + +#: replication/slotfuncs.c:528 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "non è possibile avanzare lo slot di replica a %X/%X, il minimo è %X/%X" + +#: replication/syncrep.c:246 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "annullamento dell'attesa di replica sincrona ed interruzione della connessione su comando dell'amministratore" -#: replication/syncrep.c:249 replication/syncrep.c:266 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgstr "La transazione ha già effettuato il commit localmente, ma potrebbe non essere stata replicata agli standby." -#: replication/syncrep.c:265 +#: replication/syncrep.c:263 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "annullamento dell'attesa di replica sincrona su richiesta utente" -#: replication/syncrep.c:396 +#: replication/syncrep.c:397 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "lo standby \"%s\" ha ora priorità di standby sincrono %u" -#: replication/syncrep.c:457 +#: replication/syncrep.c:458 #, c-format msgid "standby \"%s\" is now a synchronous standby with priority %u" msgstr "lo standby \"%s\" è ora uno standby sincrono con priorità %u" -#: replication/syncrep.c:461 +#: replication/syncrep.c:462 #, c-format msgid "standby \"%s\" is now a candidate for quorum synchronous standby" msgstr "lo standby \"%s\" è ora un candidato al quorum di standby sincroni" -#: replication/syncrep.c:1132 +#: replication/syncrep.c:1160 #, c-format msgid "synchronous_standby_names parser failed" msgstr "interpretazione di synchronous_standby_names non riuscita" -#: replication/syncrep.c:1138 +#: replication/syncrep.c:1166 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "il numero di standby sincroni (%d) deve essere maggiore di zero" -#: replication/walreceiver.c:168 +#: replication/walreceiver.c:169 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "interruzione del processo walreceiver su comando dell'amministratore" -#: replication/walreceiver.c:301 +#: replication/walreceiver.c:309 #, c-format msgid "could not connect to the primary server: %s" msgstr "connessione al server primario fallita: %s" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:359 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "l'identificativo del database è diverso tra il primario e lo standby" -#: replication/walreceiver.c:341 +#: replication/walreceiver.c:360 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "L'identificativo del primario è %s, quello dello standby è %s." -#: replication/walreceiver.c:352 +#: replication/walreceiver.c:371 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "la timeline massima %u del primario è dietro la timeline di recupero %u" -#: replication/walreceiver.c:388 +#: replication/walreceiver.c:407 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "streaming WAL avviato dal primario a %X/%X sulla timeline %u" -#: replication/walreceiver.c:393 +#: replication/walreceiver.c:412 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "streaming WAL riavviato sulla timeline %X/%X sulla timeline %u" -#: replication/walreceiver.c:422 +#: replication/walreceiver.c:441 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "non è possibile continuare lo streaming dei WAL, il recupero è già terminato" -#: replication/walreceiver.c:459 +#: replication/walreceiver.c:478 #, c-format msgid "replication terminated by primary server" msgstr "replica terminata dal server primario" -#: replication/walreceiver.c:460 +#: replication/walreceiver.c:479 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "Fine del WAL raggiunta sulla timeline %u a %X/%X." -#: replication/walreceiver.c:555 +#: replication/walreceiver.c:574 #, c-format msgid "terminating walreceiver due to timeout" msgstr "walreceiver terminato a causa di timeout" -#: replication/walreceiver.c:595 +#: replication/walreceiver.c:614 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "il server primario non contiene più alcun WAL sulla timeline richiesta %u" -#: replication/walreceiver.c:610 replication/walreceiver.c:969 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format msgid "could not close log segment %s: %m" msgstr "chiusura del segmento di log %s fallita: %m" -#: replication/walreceiver.c:735 +#: replication/walreceiver.c:754 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "recupero del file di storia della timeline %u dal server primario" -#: replication/walreceiver.c:1023 +#: replication/walreceiver.c:1036 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "scrittura nel segmento di log %s in posizione %u, lunghezza %lu fallita: %m" -#: replication/walsender.c:492 +#: replication/walsender.c:494 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "spostamento all'inizio del file \"%s\" fallito: %m" -#: replication/walsender.c:533 +#: replication/walsender.c:535 #, c-format msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" msgstr "IDENTIFY_SYSTEM non eseguito prima di START_REPLICATION" -#: replication/walsender.c:550 +#: replication/walsender.c:552 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "non si può usare una slot di replica logico per la replica fisica" -#: replication/walsender.c:613 +#: replication/walsender.c:615 #, c-format msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "il punto di avvio richiesto %X/%X sulla timeline %u non è nella storia di questo server" -#: replication/walsender.c:617 +#: replication/walsender.c:619 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "La storia di questo server si è separata dalla timeline %u a %X/%X." -#: replication/walsender.c:662 +#: replication/walsender.c:664 #, c-format msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "il punto di avvio richiesto %X/%X è più avanti della posizione di flush del WAL %X/%X di questo server" -#: replication/walsender.c:896 +#: replication/walsender.c:893 #, c-format msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT non può essere eseguito in una transazione" -#: replication/walsender.c:905 +#: replication/walsender.c:902 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT deve essere eseguito in una transazione" -#: replication/walsender.c:910 +#: replication/walsender.c:907 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT deve essere eseguito in una transazione in modalità REPEATABLE READ" -#: replication/walsender.c:915 +#: replication/walsender.c:912 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT deve essere eseguito prima di qualunque query" -#: replication/walsender.c:920 +#: replication/walsender.c:917 #, c-format msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT non può essere eseguito in una sottotransazione" -#: replication/walsender.c:1066 +#: replication/walsender.c:1063 #, c-format msgid "terminating walsender process after promotion" msgstr "interruzione del processo walsender dopo la promozione" -#: replication/walsender.c:1434 +#: replication/walsender.c:1448 #, c-format msgid "cannot execute new commands while WAL sender is in stopping mode" msgstr "non è possibile eseguire nuovi comandi mentre WAL sender è in modalità di arresto" -#: replication/walsender.c:1467 +#: replication/walsender.c:1481 #, c-format msgid "received replication command: %s" msgstr "ricevuto comando di replica: %s" -#: replication/walsender.c:1483 tcop/fastpath.c:281 tcop/postgres.c:1003 -#: tcop/postgres.c:1313 tcop/postgres.c:1572 tcop/postgres.c:1977 -#: tcop/postgres.c:2345 tcop/postgres.c:2420 +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1010 +#: tcop/postgres.c:1334 tcop/postgres.c:1594 tcop/postgres.c:2000 +#: tcop/postgres.c:2373 tcop/postgres.c:2452 #, c-format msgid "current transaction is aborted, commands ignored until end of transaction block" msgstr "la transazione corrente è interrotta, i comandi saranno ignorati fino alla fine del blocco della transazione" -#: replication/walsender.c:1545 +#: replication/walsender.c:1562 #, c-format -msgid "not connected to database" -msgstr "non connesso ad un database" +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "non è possibile eseguire comandi SQL nel WAL sender di replica fisica" -#: replication/walsender.c:1585 replication/walsender.c:1601 +#: replication/walsender.c:1610 replication/walsender.c:1626 #, c-format msgid "unexpected EOF on standby connection" msgstr "fine del file inaspettato sulla connessione di standby" -#: replication/walsender.c:1615 +#: replication/walsender.c:1640 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "tipo di messaggio di standby \"%c\" imprevisto, dopo la ricezione di CopyDone" -#: replication/walsender.c:1653 +#: replication/walsender.c:1678 #, c-format msgid "invalid standby message type \"%c\"" msgstr "tipo di messaggio \"%c\" di standby non valido" -#: replication/walsender.c:1694 +#: replication/walsender.c:1719 #, c-format msgid "unexpected message type \"%c\"" msgstr "tipo di messaggio \"%c\" inatteso" -#: replication/walsender.c:2064 +#: replication/walsender.c:2097 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "interruzione del processo walsender a causa di timeout di replica" -#: replication/walsender.c:2152 +#: replication/walsender.c:2181 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "lo standby \"%s\" ha ora raggiunto il primario" +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" ora è allineato al server di origine" -#: replication/walsender.c:2266 +#: replication/walsender.c:2290 #, c-format msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" msgstr "il numero di richieste di connessioni di standby supera max_wal_senders (attualmente %d)" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:975 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "la regola \"%s\" per la relazione \"%s\" esiste già" @@ -17235,316 +18021,316 @@ msgstr "la regola della vista \"%s\" deve essere chiamata \"%s\"" #: rewrite/rewriteDefine.c:428 #, c-format -msgid "could not convert partitioned table \"%s\" to a view" -msgstr "conversione della tabella partizionata \"%s\" in vista fallita" +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "non è possibile convertire la tabella partizionata \"%s\" in una vista" -#: rewrite/rewriteDefine.c:436 +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "non è possibile convertire la partizione \"%s\" in una vista" + +#: rewrite/rewriteDefine.c:442 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" msgstr "conversione della tabella \"%s\" in vista fallita perché non è vuota" -#: rewrite/rewriteDefine.c:444 +#: rewrite/rewriteDefine.c:450 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" msgstr "conversione della tabella \"%s\" in vista fallita perché ha dei trigger" -#: rewrite/rewriteDefine.c:446 +#: rewrite/rewriteDefine.c:452 #, c-format msgid "In particular, the table cannot be involved in any foreign key relationships." msgstr "In particolare, la tabella non può prendere parte in alcuna relazione di chiave esterna." -#: rewrite/rewriteDefine.c:451 +#: rewrite/rewriteDefine.c:457 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "conversione della tabella \"%s\" in vista fallita perché ha indici" -#: rewrite/rewriteDefine.c:457 +#: rewrite/rewriteDefine.c:463 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "conversione della tabella \"%s\" in vista fallita perché ha tabelle figlie" -#: rewrite/rewriteDefine.c:463 +#: rewrite/rewriteDefine.c:469 #, c-format msgid "could not convert table \"%s\" to a view because it has row security enabled" msgstr "conversione della tabella \"%s\" in vista fallita perché ha la sicurezza delle righe abilitata" -#: rewrite/rewriteDefine.c:469 +#: rewrite/rewriteDefine.c:475 #, c-format msgid "could not convert table \"%s\" to a view because it has row security policies" msgstr "conversione della tabella \"%s\" in vista fallita perché ha regole di sicurezza per riga" -#: rewrite/rewriteDefine.c:496 +#: rewrite/rewriteDefine.c:502 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "non è possibile avere più di una lista RETURNING in una regola" -#: rewrite/rewriteDefine.c:501 +#: rewrite/rewriteDefine.c:507 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "le liste RETURNING non sono supportate in regole condizionali" -#: rewrite/rewriteDefine.c:505 +#: rewrite/rewriteDefine.c:511 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "le liste RETURNING non sono supportate in regole che non siano INSTEAD" -#: rewrite/rewriteDefine.c:670 +#: rewrite/rewriteDefine.c:675 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "la lista di destinazione della regola SELECT ha troppi elementi" -#: rewrite/rewriteDefine.c:671 +#: rewrite/rewriteDefine.c:676 #, c-format msgid "RETURNING list has too many entries" msgstr "la lista RETURNING ha troppi elementi" -#: rewrite/rewriteDefine.c:698 +#: rewrite/rewriteDefine.c:703 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "non è possibile convertire una relazione contenente colonne eliminate in una vista" -#: rewrite/rewriteDefine.c:699 +#: rewrite/rewriteDefine.c:704 #, c-format msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "non è possibile creare una lista RETURNING per una relazione che contiene colonne eliminate" -#: rewrite/rewriteDefine.c:705 +#: rewrite/rewriteDefine.c:710 #, c-format msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "elemento di destinazione %d della regola SELECT ha nome di colonna diverso dalla colonna \"%s\"" -#: rewrite/rewriteDefine.c:707 +#: rewrite/rewriteDefine.c:712 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "L'elemento di destinazione di SELECT si chiama \"%s\"." -#: rewrite/rewriteDefine.c:716 +#: rewrite/rewriteDefine.c:721 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "l'elemento %d di destinazione della regola SELECT è di tipo diverso dalla colonna \"%s\"" -#: rewrite/rewriteDefine.c:718 +#: rewrite/rewriteDefine.c:723 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "l'elemento %d della lista RETURNING è di tipo diverso dalla colonna \"%s\"" -#: rewrite/rewriteDefine.c:721 rewrite/rewriteDefine.c:745 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "L'elemento di destinazione di SELECT è di tipo %s, ma la colonna è di tipo %s." -#: rewrite/rewriteDefine.c:724 rewrite/rewriteDefine.c:749 +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "la lista di elementi di RETURNING è di tipo %s, ma la colonna è di tipo %s." -#: rewrite/rewriteDefine.c:740 +#: rewrite/rewriteDefine.c:745 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "l'elemento %d di destinazione della regola SELECT ha dimensione diversa dalla colonna \"%s\"" -#: rewrite/rewriteDefine.c:742 +#: rewrite/rewriteDefine.c:747 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "l'elemento %d della lista RETURNING ha dimensione diversa dalla colonna \"%s\"" -#: rewrite/rewriteDefine.c:759 +#: rewrite/rewriteDefine.c:764 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "la lista di destinazione della regola SELECT ha troppi pochi elementi" -#: rewrite/rewriteDefine.c:760 +#: rewrite/rewriteDefine.c:765 #, c-format msgid "RETURNING list has too few entries" msgstr "la lista RETURNING ha troppi pochi elementi" -#: rewrite/rewriteDefine.c:852 rewrite/rewriteDefine.c:966 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 #: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "la regola \"%s\" per la relazione \"%s\" non esiste" -#: rewrite/rewriteDefine.c:985 +#: rewrite/rewriteDefine.c:990 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "non è consentire rinominare una regola ON SELECT" -#: rewrite/rewriteHandler.c:543 +#: rewrite/rewriteHandler.c:541 #, c-format msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" msgstr "la query WITH \"%s\" appare sia in una regola di azione che nella query che deve essere riscritta" -#: rewrite/rewriteHandler.c:603 +#: rewrite/rewriteHandler.c:601 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "non è possibile avere liste RETURNING in più di una regola" -#: rewrite/rewriteHandler.c:818 +#: rewrite/rewriteHandler.c:823 #, c-format msgid "cannot insert into column \"%s\"" msgstr "non è possibile inserire nella colonna \"%s\"" -#: rewrite/rewriteHandler.c:819 rewrite/rewriteHandler.c:834 +#: rewrite/rewriteHandler.c:824 rewrite/rewriteHandler.c:839 #, c-format msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." msgstr "La colonna \"%s\" è una colonna identità definita come GENERATED ALWAYS." -#: rewrite/rewriteHandler.c:821 +#: rewrite/rewriteHandler.c:826 #, c-format msgid "Use OVERRIDING SYSTEM VALUE to override." msgstr "Usa OVERRIDING SYSTEM VALUE per sovrascrivere." -#: rewrite/rewriteHandler.c:833 +#: rewrite/rewriteHandler.c:838 #, c-format msgid "column \"%s\" can only be updated to DEFAULT" msgstr "la colonna \"%s\" può essere modificata solo a DEFAULT" -#: rewrite/rewriteHandler.c:984 rewrite/rewriteHandler.c:1002 +#: rewrite/rewriteHandler.c:1000 rewrite/rewriteHandler.c:1018 #, c-format msgid "multiple assignments to same column \"%s\"" msgstr "più di un assegnamento alla stessa colonna \"%s\"" -#: rewrite/rewriteHandler.c:1778 rewrite/rewriteHandler.c:3397 -#, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "ricorsione infinita individuata nelle regole per la relazione \"%s\"" - -#: rewrite/rewriteHandler.c:1863 +#: rewrite/rewriteHandler.c:1921 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "ricorsione infinita individuata nella regola di sicurezza per la relazione \"%s\"" -#: rewrite/rewriteHandler.c:2180 +#: rewrite/rewriteHandler.c:2241 msgid "Junk view columns are not updatable." msgstr "Le colonne junk di una vista non sono aggiornabili." -#: rewrite/rewriteHandler.c:2185 +#: rewrite/rewriteHandler.c:2246 msgid "View columns that are not columns of their base relation are not updatable." msgstr "Le colonne di vista che non sono colonne della loro relazione di base non sono aggiornabili." -#: rewrite/rewriteHandler.c:2188 +#: rewrite/rewriteHandler.c:2249 msgid "View columns that refer to system columns are not updatable." msgstr "Le colonne di vista che si riferiscono a colonne di sistema non sono aggiornabili." -#: rewrite/rewriteHandler.c:2191 +#: rewrite/rewriteHandler.c:2252 msgid "View columns that return whole-row references are not updatable." msgstr "Le colonne di vista che restituiscono riferimenti a righe intere non sono aggiornabili." -#: rewrite/rewriteHandler.c:2249 +#: rewrite/rewriteHandler.c:2313 msgid "Views containing DISTINCT are not automatically updatable." msgstr "Le viste contenenti DISTINCT non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2252 +#: rewrite/rewriteHandler.c:2316 msgid "Views containing GROUP BY are not automatically updatable." msgstr "Le viste contenenti GROUP BY non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2255 +#: rewrite/rewriteHandler.c:2319 msgid "Views containing HAVING are not automatically updatable." msgstr "Le viste contenenti HAVING non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2258 +#: rewrite/rewriteHandler.c:2322 msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "Le viste che contengono UNION, INTERSECT o EXCEPT non sono automaticamente aggiornabili." -#: rewrite/rewriteHandler.c:2261 +#: rewrite/rewriteHandler.c:2325 msgid "Views containing WITH are not automatically updatable." msgstr "Le viste contenenti WITH non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2264 +#: rewrite/rewriteHandler.c:2328 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "Le viste contenenti LIMIT o OFFSET non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2276 +#: rewrite/rewriteHandler.c:2340 msgid "Views that return aggregate functions are not automatically updatable." msgstr "Le viste che restituiscono funzioni di aggregazione non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2279 +#: rewrite/rewriteHandler.c:2343 msgid "Views that return window functions are not automatically updatable." msgstr "Le viste che restituiscono funzioni finestra non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2282 +#: rewrite/rewriteHandler.c:2346 msgid "Views that return set-returning functions are not automatically updatable." msgstr "Le viste che restituiscono funzioni insieme non sono aggiornabili automaticamente" -#: rewrite/rewriteHandler.c:2289 rewrite/rewriteHandler.c:2293 -#: rewrite/rewriteHandler.c:2301 +#: rewrite/rewriteHandler.c:2353 rewrite/rewriteHandler.c:2357 +#: rewrite/rewriteHandler.c:2365 msgid "Views that do not select from a single table or view are not automatically updatable." msgstr "Le viste che non leggono da una singola tabella o vista non sono aggiornabili automaticamente." -#: rewrite/rewriteHandler.c:2304 +#: rewrite/rewriteHandler.c:2368 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "Le viste che contengono TABLESAMPLE non sono automaticamente aggiornabili." -#: rewrite/rewriteHandler.c:2328 +#: rewrite/rewriteHandler.c:2392 msgid "Views that have no updatable columns are not automatically updatable." msgstr "Le viste che non hanno colonne aggiornabili non sono automaticamente aggiornabili." -#: rewrite/rewriteHandler.c:2780 +#: rewrite/rewriteHandler.c:2849 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "non si può inserire nella colonna \"%s\" della vista \"%s\"" -#: rewrite/rewriteHandler.c:2788 +#: rewrite/rewriteHandler.c:2857 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "non si può modificare la colonna \"%s\" della vista \"%s\"" -#: rewrite/rewriteHandler.c:3191 +#: rewrite/rewriteHandler.c:3327 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "le regole DO INSTEAD NOTHING non sono supportate per istruzioni di modifica dei dati nel WITH" -#: rewrite/rewriteHandler.c:3205 +#: rewrite/rewriteHandler.c:3341 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "le regole DO INSTEAD NOTHING condizionali non sono supportate per istruzioni di modifica dei dati nel WITH" -#: rewrite/rewriteHandler.c:3209 +#: rewrite/rewriteHandler.c:3345 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "le regole DO ALSO non sono supportate per istruzioni di modifica dei dati nel WITH" -#: rewrite/rewriteHandler.c:3214 +#: rewrite/rewriteHandler.c:3350 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "le regole DO INSTEAD multi-istruzione non sono supportate per istruzioni di modifica dei dati nel WITH" -#: rewrite/rewriteHandler.c:3434 +#: rewrite/rewriteHandler.c:3569 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "non è possibile eseguire INSERT RETURNING sulla relazione \"%s\"" -#: rewrite/rewriteHandler.c:3436 +#: rewrite/rewriteHandler.c:3571 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "È necessaria una regola ON INSERT DO INSTEAD non condizionale con una clausola RETURNING." -#: rewrite/rewriteHandler.c:3441 +#: rewrite/rewriteHandler.c:3576 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "non è possibile eseguire UPDATE RETURNING sulla relazione \"%s\"" -#: rewrite/rewriteHandler.c:3443 +#: rewrite/rewriteHandler.c:3578 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "È necessaria una regola ON UPDATE DO INSTEAD non condizionale con una clausola RETURNING." -#: rewrite/rewriteHandler.c:3448 +#: rewrite/rewriteHandler.c:3583 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "non è possibile eseguire DELETE RETURNING sulla relazione \"%s\"" -#: rewrite/rewriteHandler.c:3450 +#: rewrite/rewriteHandler.c:3585 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "È necessaria una regola ON DELETE DO INSTEAD non condizionale con una clausola RETURNING." -#: rewrite/rewriteHandler.c:3468 +#: rewrite/rewriteHandler.c:3603 #, c-format msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "INSERT con clausola ON CONFLICT non può essere usato in tabelle con una regola su INSERT o UPDATE" -#: rewrite/rewriteHandler.c:3525 +#: rewrite/rewriteHandler.c:3660 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH non può essere usato in una query che viene riscritta da regole in più di una query" @@ -17559,7 +18345,7 @@ msgstr "i comandi di utilità condizionali non sono implementati" msgid "WHERE CURRENT OF on a view is not implemented" msgstr "WHERE CURRENT OF su una vista non è implementato" -#: rewrite/rewriteManip.c:1434 +#: rewrite/rewriteManip.c:1503 #, c-format msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" msgstr "la variabile NEW nelle regole ON UPDATE non può riferirsi a colonne che fanno parte di un assegnamento multiplo nel comando UPDATE soggetto" @@ -17590,13 +18376,13 @@ msgstr "parametro Snowball sconosciuto: \"%s\"" msgid "missing Language parameter" msgstr "parametro Language mancante" -#: statistics/dependencies.c:542 +#: statistics/dependencies.c:534 #, c-format msgid "invalid zero-length item array in MVDependencies" msgstr "elemento array a lunghezza zero non valido in MVDependencies" -#: statistics/dependencies.c:673 statistics/dependencies.c:726 -#: statistics/mvdistinct.c:338 statistics/mvdistinct.c:391 +#: statistics/dependencies.c:672 statistics/dependencies.c:725 +#: statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 #: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 #: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 #: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 @@ -17606,27 +18392,27 @@ msgstr "elemento array a lunghezza zero non valido in MVDependencies" msgid "cannot accept a value of type %s" msgstr "non è possibile accettare un valore del tipo %s" -#: statistics/extended_stats.c:102 +#: statistics/extended_stats.c:104 #, c-format msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" msgstr "calcolo della statistica \"%s.%s\" fallito per la relazione \"%s.%s\"" -#: statistics/mvdistinct.c:259 +#: statistics/mvdistinct.c:262 #, c-format msgid "invalid ndistinct magic %08x (expected %08x)" msgstr "valore magico ndistinct %08x non valido (atteso %08x)" -#: statistics/mvdistinct.c:264 +#: statistics/mvdistinct.c:267 #, c-format msgid "invalid ndistinct type %d (expected %d)" msgstr "tipo ndistinct %d non valido (atteso %d)" -#: statistics/mvdistinct.c:269 +#: statistics/mvdistinct.c:272 #, c-format msgid "invalid zero-length item array in MVNDistinct" msgstr "elemento array a lunghezza zero non valido in MVDistinct" -#: statistics/mvdistinct.c:278 +#: statistics/mvdistinct.c:281 #, c-format msgid "invalid MVNDistinct size %zd (expected at least %zd)" msgstr "dimensione MVDistinct %zd non valida (attesa almeno %zd)" @@ -17666,7 +18452,7 @@ msgstr "Più di un fallimento --- l'errore in scrittura potrebbe essere permanen msgid "writing block %u of relation %s" msgstr "scrittura del blocco %u della relazione %s" -#: storage/buffer/bufmgr.c:4356 +#: storage/buffer/bufmgr.c:4358 #, c-format msgid "snapshot too old" msgstr "snapshot troppo vecchio" @@ -17681,175 +18467,220 @@ msgstr "nessun buffer locale vuoto disponibile" msgid "cannot access temporary tables during a parallel operation" msgstr "non è possibile accedere alle tabelle temporanee durante un'operazione parallela" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: storage/file/buffile.c:317 +#, c-format +msgid "could not open BufFile \"%s\"" +msgstr "errore nell'apertura del BufFile \"%s\"" + +#: storage/file/fd.c:451 storage/file/fd.c:523 storage/file/fd.c:559 #, c-format msgid "could not flush dirty data: %m" msgstr "non è stato possibile scaricare i dati sporchi: %m" -#: storage/file/fd.c:473 +#: storage/file/fd.c:481 #, c-format msgid "could not determine dirty data size: %m" msgstr "non è stato possibile determinare la dimensione dei dati sporchi: %m" -#: storage/file/fd.c:525 +#: storage/file/fd.c:533 #, c-format msgid "could not munmap() while flushing data: %m" msgstr "non è possibile effettuare munmap() mentre si stanno scaricando i dati sporchi: %m" -#: storage/file/fd.c:726 +#: storage/file/fd.c:734 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "creazione del collegamento il file \"%s\" a \"%s\" fallita: %m" -#: storage/file/fd.c:820 +#: storage/file/fd.c:828 #, c-format msgid "getrlimit failed: %m" msgstr "getrlimit fallito: %m" -#: storage/file/fd.c:910 +#: storage/file/fd.c:918 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "descrittori di file non sufficienti per avviare il processo server" -#: storage/file/fd.c:911 +#: storage/file/fd.c:919 #, c-format msgid "System allows %d, we need at least %d." msgstr "Il sistema ne consente %d, ne occorrono almeno %d." -#: storage/file/fd.c:952 storage/file/fd.c:2129 storage/file/fd.c:2222 -#: storage/file/fd.c:2370 +#: storage/file/fd.c:970 storage/file/fd.c:2371 storage/file/fd.c:2473 +#: storage/file/fd.c:2625 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "descrittori di file esauriti: %m; sto rilasciando e riprovando" -#: storage/file/fd.c:1557 +#: storage/file/fd.c:1312 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "file temporaneo: percorso \"%s\", dimensione %lu" -#: storage/file/fd.c:1760 +#: storage/file/fd.c:1444 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "errore nella creazione della directory temporanea \"%s\": %m" + +#: storage/file/fd.c:1451 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "errore nella creazione della sottodirectory temporanea \"%s\": %m" + +#: storage/file/fd.c:1644 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "errore nella creazione del file temporaneo \"%s\": %m" + +#: storage/file/fd.c:1679 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "errore nell'apertura del file temporaneo \"%s\": %m" + +#: storage/file/fd.c:1720 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "errore nell'unlink del file temporaneo \"%s\": %m" + +#: storage/file/fd.c:2002 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "la dimensione del file temporaneo supera temp_file_limit (%dkB)" -#: storage/file/fd.c:2105 storage/file/fd.c:2155 +#: storage/file/fd.c:2347 storage/file/fd.c:2406 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "maxAllocatedDescs (%d) superato tentando di aprire il file \"%s\"" -#: storage/file/fd.c:2195 +#: storage/file/fd.c:2446 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "maxAllocatedDescs (%d) superato tentando di eseguire il comando \"%s\"" -#: storage/file/fd.c:2346 +#: storage/file/fd.c:2601 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "maxAllocatedDescs (%d) superato tentando di aprire la directory \"%s\"" -#: storage/file/fd.c:2432 utils/adt/genfile.c:511 +#: storage/file/fd.c:2692 #, c-format msgid "could not read directory \"%s\": %m" msgstr "lettura della directory \"%s\" fallita: %m" -#: storage/ipc/dsm.c:364 +#: storage/file/fd.c:3124 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "trovato file non previsto nella directory dei file temporanei: \"%s\"" + +#: storage/file/fd.c:3443 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "errore nella rimozione della directory \"%s\": %m" + +#: storage/file/sharedfileset.c:93 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "errore collegandosi ad uno SharedFileSet che è stato già distrutto" + +#: storage/ipc/dsm.c:351 #, c-format msgid "dynamic shared memory control segment is corrupt" msgstr "il segmento di controllo della memoria dinamica condivisa è corrotto" -#: storage/ipc/dsm.c:411 +#: storage/ipc/dsm.c:398 #, c-format msgid "dynamic shared memory is disabled" msgstr "la memoria dinamica condivisa è disabilitata" -#: storage/ipc/dsm.c:412 +#: storage/ipc/dsm.c:399 #, c-format msgid "Set dynamic_shared_memory_type to a value other than \"none\"." msgstr "Imposta dynamic_shared_memory_type ad un valore diverso da \"none\"." -#: storage/ipc/dsm.c:432 +#: storage/ipc/dsm.c:419 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "il segmento di controllo della memoria dinamica condivisa non è valido" -#: storage/ipc/dsm.c:528 +#: storage/ipc/dsm.c:515 #, c-format msgid "too many dynamic shared memory segments" msgstr "troppi segmenti di memoria dinamica condivisa" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 -#: storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 -#: storage/ipc/dsm_impl.c:819 storage/ipc/dsm_impl.c:963 +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 +#: storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 +#: storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "unmap del segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 -#: storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:829 +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 +#: storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "rimozione del segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:729 -#: storage/ipc/dsm_impl.c:843 +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 +#: storage/ipc/dsm_impl.c:904 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "apertura del segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 -#: storage/ipc/dsm_impl.c:774 storage/ipc/dsm_impl.c:867 +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 +#: storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "lettura informazioni sul segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:886 -#: storage/ipc/dsm_impl.c:936 +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 +#: storage/ipc/dsm_impl.c:997 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "ridimensionamento del segmento di memoria condivisa \"%s\" a %zu byte fallito: %m" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 -#: storage/ipc/dsm_impl.c:750 storage/ipc/dsm_impl.c:987 +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 +#: storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "map del segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:515 +#: storage/ipc/dsm_impl.c:576 #, c-format msgid "could not get shared memory segment: %m" msgstr "impossibile ottenere un segmento di memoria condivisa: %m" -#: storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:775 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "creazione del segmento di memoria condivisa \"%s\" fallito: %m" -#: storage/ipc/dsm_impl.c:1029 storage/ipc/dsm_impl.c:1077 +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 #, c-format msgid "could not duplicate handle for \"%s\": %m" msgstr "duplicazione dell'handle per \"%s\" fallita: %m" -#: storage/ipc/latch.c:828 +#: storage/ipc/latch.c:829 #, c-format msgid "epoll_ctl() failed: %m" msgstr "epoll_ctl() fallita: %m" -#: storage/ipc/latch.c:1057 +#: storage/ipc/latch.c:1060 #, c-format msgid "epoll_wait() failed: %m" msgstr "epoll_wait() fallita: %m" -#: storage/ipc/latch.c:1179 +#: storage/ipc/latch.c:1182 #, c-format msgid "poll() failed: %m" msgstr "poll() fallito: %m" -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:189 storage/lmgr/lock.c:883 -#: storage/lmgr/lock.c:917 storage/lmgr/lock.c:2679 storage/lmgr/lock.c:4004 -#: storage/lmgr/lock.c:4069 storage/lmgr/lock.c:4361 -#: storage/lmgr/predicate.c:2382 storage/lmgr/predicate.c:2397 -#: storage/lmgr/predicate.c:3789 storage/lmgr/predicate.c:4932 -#: utils/hash/dynahash.c:1043 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 +#: storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 +#: storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 +#: storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 +#: storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "memoria condivisa esaurita" @@ -17879,32 +18710,32 @@ msgstr "memoria condivisa per la struttura di dati \"%s\" insufficiente (richies msgid "requested shared memory size overflows size_t" msgstr "la dimensione richiesta di memoria condivisa supera size_t" -#: storage/ipc/standby.c:531 tcop/postgres.c:2970 +#: storage/ipc/standby.c:558 tcop/postgres.c:3033 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "annullamento dell'istruzione a causa di un conflitto con il ripristino" -#: storage/ipc/standby.c:532 tcop/postgres.c:2277 +#: storage/ipc/standby.c:559 tcop/postgres.c:2306 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "La transazione utente ha causato un deadlock del buffer con il ripristino." -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:190 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "elemento pg_largeobject per OID %u, pagina %d ha la dimensione del campo dati errata %d" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:271 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "flag non validi per l'apertura di un large object: %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:461 #, c-format msgid "invalid whence setting: %d" msgstr "impostazione \"da dove\" non valida: %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:633 #, c-format msgid "invalid large object write request size: %d" msgstr "dimensione della richiesta di scrittura large object non valida: %d" @@ -17929,238 +18760,228 @@ msgstr "rilevato deadlock" msgid "See server log for query details." msgstr "Vedi i log del server per i dettagli della query." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:767 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "durante la modifica della tupla (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:770 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "durante l'eliminazione della tupla (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:773 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "durante il blocco della tupla (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:776 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "durante il blocco della versione modificata (%u,%u) della tupla nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:779 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "durante l'inserimento della tupla di indice (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:782 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "durante il controllo di univocità della tupla (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:785 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "durante il ricontrollo della tupla modificata (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:788 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" msgstr "durante il controllo del vincolo di esclusione sulla tupla (%u,%u) nella relazione \"%s\"" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1008 #, c-format msgid "relation %u of database %u" msgstr "la relazione %u del database %u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1014 #, c-format msgid "extension of relation %u of database %u" msgstr "l'estensione della relazione %u del database %u" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1020 #, c-format msgid "page %u of relation %u of database %u" msgstr "la pagina %u della relazione %u del database %u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1027 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "la tupla (%u,%u) della relazione %u del database %u" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1035 #, c-format msgid "transaction %u" msgstr "la transazione %u" -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1040 #, c-format msgid "virtual transaction %d/%u" msgstr "la transazione virtuale %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1046 #, c-format msgid "speculative token %u of transaction %u" msgstr "token speculativo %u della transazione %u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1052 #, c-format msgid "object %u of class %u of database %u" msgstr "l'oggetto %u di classe %u del database %u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1060 #, c-format msgid "user lock [%u,%u,%u]" msgstr "il lock utente [%u,%u,%u]" -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1067 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "l'advisory lock [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1075 #, c-format msgid "unrecognized locktag type %d" msgstr "tipo di locktag %d sconosciuto" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:740 #, c-format msgid "cannot acquire lock mode %s on database objects while recovery is in progress" msgstr "non è possibile acquisire lock in modo %s sugli oggetti del database mentre è in corso il ripristino" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:742 #, c-format msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "Solo RowExclusiveLock o inferiore può essere acquisito sugli oggetti database durante il ripristino." -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2680 -#: storage/lmgr/lock.c:4005 storage/lmgr/lock.c:4070 storage/lmgr/lock.c:4362 +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 +#: storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "Potrebbe essere necessario incrementare max_locks_per_transaction." -#: storage/lmgr/lock.c:3121 storage/lmgr/lock.c:3237 +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 #, c-format msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "non è possibile eseguire PREPARE tenendo sia lock a livello di sessione che di transazione sullo stesso oggetto" -#: storage/lmgr/predicate.c:683 +#: storage/lmgr/predicate.c:682 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "elementi non sufficienti in RWConflictPool per registrare un conflitto di lettura/scrittura" -#: storage/lmgr/predicate.c:684 storage/lmgr/predicate.c:712 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "Potrebbe essere necessario eseguire meno transazioni per volta oppure incrementare max_connections." -#: storage/lmgr/predicate.c:711 +#: storage/lmgr/predicate.c:710 #, c-format msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "elementi non sufficienti in RWConflictPool per registrare un potenziale conflitto di lettura/scrittura" -#: storage/lmgr/predicate.c:917 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "la memoria per il tracciamento dei conflitti di serializzazione è quasi esaurita" - -#: storage/lmgr/predicate.c:918 -#, c-format -msgid "There might be an idle transaction or a forgotten prepared transaction causing this." -msgstr "Ciò potrebbe essere causato da una transazione inattiva o una transazione preparata dimenticata." - -#: storage/lmgr/predicate.c:1545 +#: storage/lmgr/predicate.c:1515 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "lo snapshot deferibile era insicuro; ne sto provando uno nuovo" -#: storage/lmgr/predicate.c:1634 +#: storage/lmgr/predicate.c:1604 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "\"default_transaction_isolation\" è impostato a \"serializable\"." -#: storage/lmgr/predicate.c:1635 +#: storage/lmgr/predicate.c:1605 #, c-format msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." msgstr "Puoi usare \"SET default_transaction_isolation = 'repeatable read'\" per cambiare il valore predefinito." -#: storage/lmgr/predicate.c:1674 +#: storage/lmgr/predicate.c:1645 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "una transazione che importa uno snapshot non può essere READ ONLY DEFERRABLE" -#: storage/lmgr/predicate.c:1752 utils/time/snapmgr.c:617 -#: utils/time/snapmgr.c:623 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 +#: utils/time/snapmgr.c:627 #, c-format msgid "could not import the requested snapshot" msgstr "non è stato possibile importare lo snapshot richiesto" -#: storage/lmgr/predicate.c:1753 utils/time/snapmgr.c:624 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "La transazione di origine %u non è più in esecuzione." +msgid "The source process with PID %d is not running anymore." +msgstr "Il processo di origine con PID %d non è più in esecuzione." -#: storage/lmgr/predicate.c:2383 storage/lmgr/predicate.c:2398 -#: storage/lmgr/predicate.c:3790 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 +#: storage/lmgr/predicate.c:3763 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "Potrebbe essere necessario incrementare max_pred_locks_per_transaction." -#: storage/lmgr/predicate.c:3944 storage/lmgr/predicate.c:4033 -#: storage/lmgr/predicate.c:4041 storage/lmgr/predicate.c:4080 -#: storage/lmgr/predicate.c:4319 storage/lmgr/predicate.c:4656 -#: storage/lmgr/predicate.c:4668 storage/lmgr/predicate.c:4710 -#: storage/lmgr/predicate.c:4748 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 +#: storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 +#: storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 +#: storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 +#: storage/lmgr/predicate.c:4721 #, c-format msgid "could not serialize access due to read/write dependencies among transactions" msgstr "serializzazione dell'accesso fallita a causa di dipendenze di lettura/scrittura tra le transazioni" -#: storage/lmgr/predicate.c:3946 storage/lmgr/predicate.c:4035 -#: storage/lmgr/predicate.c:4043 storage/lmgr/predicate.c:4082 -#: storage/lmgr/predicate.c:4321 storage/lmgr/predicate.c:4658 -#: storage/lmgr/predicate.c:4670 storage/lmgr/predicate.c:4712 -#: storage/lmgr/predicate.c:4750 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 +#: storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 +#: storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 +#: storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 +#: storage/lmgr/predicate.c:4723 #, c-format msgid "The transaction might succeed if retried." msgstr "La transazione potrebbe riuscire se ritentata." -#: storage/lmgr/proc.c:1300 +#: storage/lmgr/proc.c:1311 #, c-format msgid "Process %d waits for %s on %s." msgstr "Processo %d in attesa di %s su %s." -#: storage/lmgr/proc.c:1311 +#: storage/lmgr/proc.c:1322 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "invio di annullamento per bloccare l'autovacuum con PID %d" -#: storage/lmgr/proc.c:1329 utils/adt/misc.c:269 +#: storage/lmgr/proc.c:1340 utils/adt/misc.c:270 #, c-format msgid "could not send signal to process %d: %m" msgstr "invio del segnale al processo %d fallito: %m" -#: storage/lmgr/proc.c:1431 +#: storage/lmgr/proc.c:1442 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "il processo %d ha evitato un deadlock per %s su %s modificando l'ordine della coda dopo %ld.%03d ms" -#: storage/lmgr/proc.c:1446 +#: storage/lmgr/proc.c:1457 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "il processo %d ha individuato un deadlock mentre era in attesa di %s su %s dopo %ld.%03d ms" -#: storage/lmgr/proc.c:1455 +#: storage/lmgr/proc.c:1466 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "il processo %d è ancora un attesa di %s su %s dopo %ld.%03d ms" -#: storage/lmgr/proc.c:1462 +#: storage/lmgr/proc.c:1473 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "il processo %d ha acquisito %s su %s dopo %ld.%03d ms" -#: storage/lmgr/proc.c:1478 +#: storage/lmgr/proc.c:1489 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "il processo %d ha fallito l'acquisizione di %s su %s dopo %ld.%03d ms" @@ -18170,29 +18991,34 @@ msgstr "il processo %d ha fallito l'acquisizione di %s su %s dopo %ld.%03d ms" msgid "page verification failed, calculated checksum %u but expected %u" msgstr "verifica della pagina fallita, somma di controllo calcolata %u ma era attesa %u" -#: storage/page/bufpage.c:213 storage/page/bufpage.c:505 -#: storage/page/bufpage.c:748 storage/page/bufpage.c:881 -#: storage/page/bufpage.c:977 storage/page/bufpage.c:1087 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 +#: storage/page/bufpage.c:744 storage/page/bufpage.c:877 +#: storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "puntatore di pagina corrotto: lower = %u, upper = %u, special = %u" -#: storage/page/bufpage.c:549 +#: storage/page/bufpage.c:529 #, c-format msgid "corrupted item pointer: %u" msgstr "puntatore di elemento corrotto: %u" -#: storage/page/bufpage.c:560 storage/page/bufpage.c:932 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "lunghezza dell'elemento corrotta: totale %u, spazio disponibile %u" -#: storage/page/bufpage.c:767 storage/page/bufpage.c:905 -#: storage/page/bufpage.c:993 storage/page/bufpage.c:1103 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 +#: storage/page/bufpage.c:1099 #, c-format msgid "corrupted item pointer: offset = %u, size = %u" msgstr "puntatore di elemento corrotto: offset = %u, size = %u" +#: storage/page/bufpage.c:901 +#, c-format +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "puntatore di elemeno corrotto: offset = %u, lunghezza = %u" + #: storage/smgr/md.c:448 storage/smgr/md.c:974 #, c-format msgid "could not truncate file \"%s\": %m" @@ -18263,364 +19089,384 @@ msgstr "fsync del file \"%s\" fallito ma sto ritentando: %m" msgid "could not forward fsync request because request queue is full" msgstr "inoltro della richiesta di fsync fallito perché la coda di richieste è piena" -#: storage/smgr/md.c:1914 +#: storage/smgr/md.c:1951 #, c-format msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" msgstr "apertura del file \"%s\" fallita (blocco di destinazione %u): il segmento precedente è di soli %u blocchi" -#: storage/smgr/md.c:1928 +#: storage/smgr/md.c:1965 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "apertura del file \"%s\" fallita (blocco di destinazione %u): %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:463 tcop/fastpath.c:593 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" msgstr "La dimensione dell'argomento %d non è valida nel messaggi di chiamata di funzione" -#: tcop/fastpath.c:309 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "chiamata funzione fastpath: \"%s\" (OID %u)" -#: tcop/fastpath.c:391 tcop/postgres.c:1175 tcop/postgres.c:1438 -#: tcop/postgres.c:1818 tcop/postgres.c:2036 +#: tcop/fastpath.c:389 tcop/postgres.c:1195 tcop/postgres.c:1459 +#: tcop/postgres.c:1841 tcop/postgres.c:2062 #, c-format msgid "duration: %s ms" msgstr "durata: %s ms" -#: tcop/fastpath.c:395 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "durata: %s ms chiamata funzione fastpath: \"%s\" (OID %u)" -#: tcop/fastpath.c:431 tcop/fastpath.c:558 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "la chiamata alla funzione contiene %d parametri ma la funzione ne richiede %d" -#: tcop/fastpath.c:439 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "la chiamata alla funzione contiene %d formati di parametri ma %d parametri" -#: tcop/fastpath.c:526 tcop/fastpath.c:609 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "formato dei dati binari non corretto nell'argomento %d della funzione" -#: tcop/postgres.c:352 tcop/postgres.c:388 tcop/postgres.c:415 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "fine file inaspettata nella connessione al client" -#: tcop/postgres.c:438 tcop/postgres.c:450 tcop/postgres.c:461 -#: tcop/postgres.c:473 tcop/postgres.c:4301 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4385 #, c-format msgid "invalid frontend message type %d" msgstr "messaggio frontend di tipo %d non valido" -#: tcop/postgres.c:944 +#: tcop/postgres.c:950 #, c-format msgid "statement: %s" msgstr "istruzione: %s" -#: tcop/postgres.c:1180 +#: tcop/postgres.c:1200 #, c-format msgid "duration: %s ms statement: %s" msgstr "durata: %s ms istruzione: %s" -#: tcop/postgres.c:1230 +#: tcop/postgres.c:1250 #, c-format msgid "parse %s: %s" msgstr "analisi di %s: %s" -#: tcop/postgres.c:1286 +#: tcop/postgres.c:1307 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "non è possibile inserire comandi multipli in una istruzione preparata" -#: tcop/postgres.c:1443 +#: tcop/postgres.c:1464 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "durata: %s ms analisi di %s: %s" -#: tcop/postgres.c:1488 +#: tcop/postgres.c:1509 #, c-format msgid "bind %s to %s" msgstr "bind di %s a %s" -#: tcop/postgres.c:1507 tcop/postgres.c:2326 +#: tcop/postgres.c:1528 tcop/postgres.c:2354 #, c-format msgid "unnamed prepared statement does not exist" msgstr "l'istruzione preparata senza nome non esiste" -#: tcop/postgres.c:1549 +#: tcop/postgres.c:1571 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "il messaggio di bind ha %d formati di parametri ma %d parametri" -#: tcop/postgres.c:1555 +#: tcop/postgres.c:1577 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" -msgstr "il messaggio di bind fornisce %d paramatri, ma l'istruzione preparata \"%s\" ne richiede %d" +msgstr "il messaggio di bind fornisce %d parametri, ma l'istruzione preparata \"%s\" ne richiede %d" -#: tcop/postgres.c:1725 +#: tcop/postgres.c:1748 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "formato del dato binario errato nel parametro di bind %d" -#: tcop/postgres.c:1823 +#: tcop/postgres.c:1846 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "durata: %s ms bind %s%s%s: %s" -#: tcop/postgres.c:1871 tcop/postgres.c:2406 +#: tcop/postgres.c:1894 tcop/postgres.c:2438 #, c-format msgid "portal \"%s\" does not exist" msgstr "il portale \"%s\" non esiste" -#: tcop/postgres.c:1956 +#: tcop/postgres.c:1979 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1958 tcop/postgres.c:2044 +#: tcop/postgres.c:1981 tcop/postgres.c:2070 msgid "execute fetch from" msgstr "esecuzione di fetch da" -#: tcop/postgres.c:1959 tcop/postgres.c:2045 +#: tcop/postgres.c:1982 tcop/postgres.c:2071 msgid "execute" msgstr "esecuzione di" -#: tcop/postgres.c:2041 +#: tcop/postgres.c:2067 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "durata: %s ms %s %s%s%s: %s" -#: tcop/postgres.c:2167 +#: tcop/postgres.c:2193 #, c-format msgid "prepare: %s" msgstr "preparazione: %s" -#: tcop/postgres.c:2230 +#: tcop/postgres.c:2259 #, c-format msgid "parameters: %s" msgstr "parametri: %s" -#: tcop/postgres.c:2249 +#: tcop/postgres.c:2278 #, c-format msgid "abort reason: recovery conflict" msgstr "motivo dell'interruzione: conflitto di recupero" -#: tcop/postgres.c:2265 +#: tcop/postgres.c:2294 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "L'utente stava trattenendo un pin di shared buffer troppo a lungo." -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2297 #, c-format msgid "User was holding a relation lock for too long." msgstr "L'utente stava trattenendo un lock di relazione troppo a lungo." -#: tcop/postgres.c:2271 +#: tcop/postgres.c:2300 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "L'utente stava usando o potrebbe aver usato un tablespace che deve essere eliminato." -#: tcop/postgres.c:2274 +#: tcop/postgres.c:2303 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "L'utente potrebbe aver avuto bisogno di vedere versioni di righe che devono essere rimosse." -#: tcop/postgres.c:2280 +#: tcop/postgres.c:2309 #, c-format msgid "User was connected to a database that must be dropped." msgstr "L'utente era connesso ad un database che deve essere eliminato." -#: tcop/postgres.c:2589 +#: tcop/postgres.c:2634 #, c-format msgid "terminating connection because of crash of another server process" msgstr "la connessione è stata terminata a causa del crash di un altro processo del server" -#: tcop/postgres.c:2590 +#: tcop/postgres.c:2635 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "Il postmaster ha obbligato questo processo del server di attuare il roll back della transazione corrente e di uscire, perché un altro processo del server è terminato anormalmente e con possibile corruzione della memoria condivisa." -#: tcop/postgres.c:2594 tcop/postgres.c:2898 +#: tcop/postgres.c:2639 tcop/postgres.c:2963 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "In un momento sarai in grado di riconnetterti al database e di ripetere il comando." -#: tcop/postgres.c:2680 +#: tcop/postgres.c:2721 #, c-format msgid "floating-point exception" msgstr "eccezione floating-point" -#: tcop/postgres.c:2681 +#: tcop/postgres.c:2722 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "Un'operazione in floating-point non valida è stata segnalata. Questo probabilmente sta a significare che il risultato è un valore fuori limite o l'operazione non è valida, ad esempio una divisione per zero." -#: tcop/postgres.c:2843 +#: tcop/postgres.c:2893 #, c-format msgid "canceling authentication due to timeout" msgstr "annullamento dell'autenticazione a causa di timeout" -#: tcop/postgres.c:2847 +#: tcop/postgres.c:2897 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "interruzione del processo autovacuum su comando dell'amministratore" -#: tcop/postgres.c:2853 tcop/postgres.c:2863 tcop/postgres.c:2896 +#: tcop/postgres.c:2901 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "interruzione del worker di replica logica su comando dell'amministratore" + +#: tcop/postgres.c:2905 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "lanciatore di replica logica in arresto" + +#: tcop/postgres.c:2918 tcop/postgres.c:2928 tcop/postgres.c:2961 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "interruzione della connessione a causa di conflitto con il ripristino" -#: tcop/postgres.c:2869 +#: tcop/postgres.c:2934 #, c-format msgid "terminating connection due to administrator command" msgstr "interruzione della connessione su comando dell'amministratore" -#: tcop/postgres.c:2879 +#: tcop/postgres.c:2944 #, c-format msgid "connection to client lost" msgstr "connessione al client persa" -#: tcop/postgres.c:2947 +#: tcop/postgres.c:3010 #, c-format msgid "canceling statement due to lock timeout" msgstr "annullamento dell'istruzione a causa di timeout di lock" -#: tcop/postgres.c:2954 +#: tcop/postgres.c:3017 #, c-format msgid "canceling statement due to statement timeout" msgstr "annullamento dell'istruzione a causa di timeout" -#: tcop/postgres.c:2961 +#: tcop/postgres.c:3024 #, c-format msgid "canceling autovacuum task" msgstr "annullamento del task di autovacuum" -#: tcop/postgres.c:2984 +#: tcop/postgres.c:3047 #, c-format msgid "canceling statement due to user request" msgstr "annullamento dell'istruzione su richiesta dell'utente" -#: tcop/postgres.c:2994 +#: tcop/postgres.c:3057 #, c-format msgid "terminating connection due to idle-in-transaction timeout" msgstr "la connessione è stata terminata a causa di timeout di inattività durante una transazione" -#: tcop/postgres.c:3108 +#: tcop/postgres.c:3171 #, c-format msgid "stack depth limit exceeded" msgstr "limite di profondità dello stack superato" -#: tcop/postgres.c:3109 +#: tcop/postgres.c:3172 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "Incrementa il parametro di configurazione \"max_stack_depth\" (attualmente %dkB), dopo esserti assicurato che il limite dello stack della piattaforma sia adeguato." -#: tcop/postgres.c:3172 +#: tcop/postgres.c:3235 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "\"max_stack_depth\" non deve superare %ldkB" -#: tcop/postgres.c:3174 +#: tcop/postgres.c:3237 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "Incrementa il limite dello stack della piattaforma usando \"ulimit -s\" on un comando equivalente." -#: tcop/postgres.c:3534 +#: tcop/postgres.c:3597 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "argomento della riga di comando non valido per il processo server: %s" -#: tcop/postgres.c:3535 tcop/postgres.c:3541 +#: tcop/postgres.c:3598 tcop/postgres.c:3604 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Prova \"%s --help\" per maggiori informazioni." -#: tcop/postgres.c:3539 +#: tcop/postgres.c:3602 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: argomento della riga di comando non valido: %s" -#: tcop/postgres.c:3601 +#: tcop/postgres.c:3664 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: nessun database né nome utente specificato" -#: tcop/postgres.c:4209 +#: tcop/postgres.c:4293 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "sottotipo %d del messaggio CLOSE non valido" -#: tcop/postgres.c:4244 +#: tcop/postgres.c:4328 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "sottotipo %d del messaggio DESCRIBE non valido" -#: tcop/postgres.c:4322 +#: tcop/postgres.c:4406 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "le chiamate di funzione fastpath non sono supportate in una connessione di replica" -#: tcop/postgres.c:4326 +#: tcop/postgres.c:4410 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "il protocollo di query esteso non è supportato in una connessione di replica" -#: tcop/postgres.c:4496 +#: tcop/postgres.c:4587 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "disconnessione: tempo della sessione: %d:%02d:%02d.%03d utente=%s database=%s host=%s%s%s" -#: tcop/pquery.c:646 +#: tcop/pquery.c:645 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "il messaggio di bind ha %d formati di risultato ma la query ha %d colonne" -#: tcop/pquery.c:953 +#: tcop/pquery.c:952 #, c-format msgid "cursor can only scan forward" msgstr "il cursore effettuare solo scansioni in avanti" -#: tcop/pquery.c:954 +#: tcop/pquery.c:953 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "Dichiaralo con l'opzione SCROLL per abilitare le scansioni all'indietro." #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:242 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "non è possibile eseguire %s in una transazione a sola lettura" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:260 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "non è possibile eseguire %s durante un'operazione parallela" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:279 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "non è possibile eseguire %s durante il recupero" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:297 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "non è possibile eseguire %s nell'ambito di operazioni a sicurezza ristretta" -#: tcop/utility.c:765 +#: tcop/utility.c:757 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "solo un superutente può eseguire CHECKPOINT" + +#: tcop/utility.c:1338 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "non è possibile creare indici sulla tabella partizionata \"%s\"" + +#: tcop/utility.c:1340 #, c-format -msgid "must be superuser to do CHECKPOINT" -msgstr "solo un superutente può eseguire CHECKPOINT" +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "La tabella \"%s\" contiene partizioni che sono tabelle esterne." #: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format @@ -18768,23 +19614,23 @@ msgstr "flag di affix \"%s\" con valore di flag \"long\" non valido" msgid "could not open dictionary file \"%s\": %m" msgstr "apertura del file dictionary \"%s\" fallita: %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "espressione regolare non valida: %s" #: tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 -#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15311 gram.y:15328 +#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15714 gram.y:15731 #, c-format msgid "syntax error" msgstr "errore di sintassi" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format msgid "invalid affix alias \"%s\"" msgstr "alias di affix \"%s\" non valido" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "apertura del file affix \"%s\" fallita: %m" @@ -18799,22 +19645,27 @@ msgstr "il dizionario Ispell supporta solo valori di flag \"default\", \"long\" msgid "invalid number of flag vector aliases" msgstr "numero di alias nel vettore di flag non valido" -#: tsearch/spell.c:1542 +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "il numero di alias è maggiore del numero specificato %d" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "il file affix contiene comandi sia vecchio stile che nuovo stile" -#: tsearch/to_tsany.c:179 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "la stringa è troppo lunga per tsvector (%d byte, massimo %d byte)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:174 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "riga %d del file di configurazione \"%s\": \"%s\"" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:291 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "conversione da wchar_t a codifica server fallita: %m" @@ -18846,451 +19697,457 @@ msgstr "apertura del file delle stop word \"%s\" fallita: %m" msgid "text search parser does not support headline creation" msgstr "l'analizzatore di ricerca di testo non supporta la creazione di intestazioni" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "parametro di intestazione sconosciuto: \"%s\"" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "MinWords dovrebbe essere minore di MaxWords" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "MinWords dovrebbe essere positivo" -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "ShortWord dovrebbe essere >= 0" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "MaxFragments dovrebbe essere >= 0" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format msgid "identifier too long" msgstr "l'identificativo è troppo lungo" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format msgid "Identifier must be less than %d characters." msgstr "Gli identificatori devono essere più corti di %d caratteri." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "parola chiave sconosciuta: \"%s\"" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "la parola chiave ACL deve essere \"group\" o \"user\"." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "manca il nome" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "le parole chiave \"group\" o \"user\" devono essere seguite da un nome." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "manca il simbolo \"=\"" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "il carattere di modo non è valido: deve essere uno fra \"%s\"" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "il simbolo \"/\" deve essere seguito da un nome" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "l'user ID %u è ora chi concede i ruoli in maniera predefinita" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "l'array di ACL array contiene tipi di dati errati" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "gli array di ACL devono avere una sola dimensione" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "gli array di ACL non possono contenere valori nulli" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "ci sono caratteri spuri al termine della specifica dell'ACL" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1213 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "le opzioni di concessione non possono essere concesse a chi le ha concesse a te" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1274 #, c-format msgid "dependent privileges exist" msgstr "esistono privilegi dipendenti" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1275 #, c-format msgid "Use CASCADE to revoke them too." msgstr "Usa CASCADE per revocare anch'essi." -#: utils/adt/acl.c:1520 +#: utils/adt/acl.c:1537 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert non è più supportato" -#: utils/adt/acl.c:1530 +#: utils/adt/acl.c:1547 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove non è più supportato" -#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "tipo di privilegio sconosciuto: \"%s\"" -#: utils/adt/acl.c:3410 utils/adt/regproc.c:101 utils/adt/regproc.c:276 +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "la funzione \"%s\" non esiste" -#: utils/adt/acl.c:4864 +#: utils/adt/acl.c:4959 #, c-format msgid "must be member of role \"%s\"" msgstr "occorre far parte del ruolo \"%s\"" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5848 -#: utils/adt/arrayfuncs.c:6159 utils/adt/arrayutils.c:93 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 +#: utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 #: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "la dimensione dell'array supera il massimo consentito (%d)" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:471 -#: utils/adt/array_userfuncs.c:551 utils/adt/json.c:1764 utils/adt/json.c:1859 -#: utils/adt/json.c:1897 utils/adt/jsonb.c:1127 utils/adt/jsonb.c:1156 -#: utils/adt/jsonb.c:1592 utils/adt/jsonb.c:1756 utils/adt/jsonb.c:1766 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 +#: utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format msgid "could not determine input data type" msgstr "non è stato possibile determinare il tipo di dato di input" -#: utils/adt/array_userfuncs.c:84 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "il tipo di dati in input non è un array" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 -#: utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:608 -#: utils/adt/int.c:637 utils/adt/int.c:658 utils/adt/int.c:689 -#: utils/adt/int.c:722 utils/adt/int.c:744 utils/adt/int.c:892 -#: utils/adt/int.c:913 utils/adt/int.c:940 utils/adt/int.c:980 -#: utils/adt/int.c:1001 utils/adt/int.c:1028 utils/adt/int.c:1061 -#: utils/adt/int.c:1144 utils/adt/int8.c:1298 utils/adt/numeric.c:2953 -#: utils/adt/numeric.c:2962 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 -#: utils/adt/varlena.c:1054 utils/adt/varlena.c:2940 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1363 utils/adt/float.c:1422 +#: utils/adt/float.c:3708 utils/adt/float.c:3722 utils/adt/int.c:755 +#: utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 +#: utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 +#: utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 +#: utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 +#: utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 +#: utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format msgid "integer out of range" msgstr "intero fuori dall'intervallo" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "l'argomento deve essere vuoto o un array con una sola dimensione" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 -#: utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 -#: utils/adt/array_userfuncs.c:411 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "non è possibile concatenare array non compatibili" -#: utils/adt/array_userfuncs.c:279 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "Array con elementi di tipi %s e %s non sono compatibili per il concatenamento." -#: utils/adt/array_userfuncs.c:318 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "Array con dimensioni %d e %d non sono compatibili per il concatenamento." -#: utils/adt/array_userfuncs.c:355 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "Array con elementi dalle dimensioni diverse non sono compatibili per il concatenamento." -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "Array con dimensioni diverse non sono compatibili per il concatenamento." -#: utils/adt/array_userfuncs.c:667 utils/adt/array_userfuncs.c:819 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "la ricerca di elementi in array multidimensionali non è supportata" -#: utils/adt/array_userfuncs.c:691 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "la posizione iniziale non può essere nulla" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" msgstr "il letterale array non è definito in modo corretto: \"%s\"" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "\"[\" deve introdurre un array con dimensioni specificate esplicitamente." -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "Valore delle dimensioni dell'array mancante." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "Manca \"%s\" dopo le dimensioni dell'array." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "il limite massimo non può essere minore del limite minimo" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "L'array deve iniziare con \"{\" oppure con le informazioni di dimensione." -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." msgstr "Il contenuto dell'array deve cominciare con \"{\"." -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "Le dimensioni specificate per l'array non combaciano con il contenuto." -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2114 utils/adt/rangetypes.c:2122 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 +#: utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format msgid "Unexpected end of input." msgstr "L'input è terminato in modo inatteso." -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "Carattere \"%c\" inatteso." -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "Elemento dell'array inatteso." -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "Il carattere \"%c\" non combacia." -#: utils/adt/arrayfuncs.c:597 utils/adt/jsonfuncs.c:2380 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "Gli array multidimensionali devono avere sotto-array con dimensioni corrispondenti." -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "Caratteri spuri dopo la parentesi chiusa." -#: utils/adt/arrayfuncs.c:1284 utils/adt/arrayfuncs.c:3357 -#: utils/adt/arrayfuncs.c:5754 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5816 #, c-format msgid "invalid number of dimensions: %d" msgstr "numero di dimensioni non valido: %d" -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" msgstr "i flag dell'array non sono validi" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "il tipo di elemento è errato" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2683 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "non esiste una funzione di input binario per il tipo %s" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "il formato binario nell'elemento dell'array %d non è corretto" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2716 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "non esiste una funzione di output binario per il tipo %s" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "le sezioni di array a lunghezza fissa non sono implementate" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5740 -#: utils/adt/arrayfuncs.c:5766 utils/adt/arrayfuncs.c:5777 -#: utils/adt/json.c:2295 utils/adt/json.c:2370 utils/adt/jsonb.c:1370 -#: utils/adt/jsonb.c:1456 utils/adt/jsonfuncs.c:4125 utils/adt/jsonfuncs.c:4276 -#: utils/adt/jsonfuncs.c:4321 utils/adt/jsonfuncs.c:4368 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 +#: utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 +#: utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 +#: utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4289 utils/adt/jsonfuncs.c:4440 +#: utils/adt/jsonfuncs.c:4485 utils/adt/jsonfuncs.c:4532 #, c-format msgid "wrong number of array subscripts" msgstr "il numero di indici di array è errato" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "indice dell'array fuori dall'intervallo" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "non è possibile assegnare un valore nullo a un elemento di un array a dimensione fissa" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "la modifica di sezioni di array a lunghezza fissa non è implementate" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format msgid "array slice subscript must provide both boundaries" msgstr "l'indice della sezione dell'array deve fornire entrambi i limiti" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "Quando si assegna ad una sezione di un array vuoto, i limiti della sezione devono essere specificati interamente." -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "l'array di origine è troppo piccolo" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "in questo contesto non è consentito un elemento di array nullo" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4124 #, c-format msgid "cannot compare arrays of different element types" msgstr "non è possibile confrontare array con elementi di tipo diverso" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 +#: utils/adt/rangetypes.c:1317 #, c-format msgid "could not identify a hash function for type %s" msgstr "non è stato possibile trovare una funzione di hash per il tipo %s" -#: utils/adt/arrayfuncs.c:5154 +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "non è stato possibile trovare una funzione di hash estesa per il tipo %s" + +#: utils/adt/arrayfuncs.c:5216 #, c-format msgid "data type %s is not an array type" msgstr "il tipo di dati %s non è un tipo array" -#: utils/adt/arrayfuncs.c:5209 +#: utils/adt/arrayfuncs.c:5271 #, c-format msgid "cannot accumulate null arrays" msgstr "non è possibile accumulare array nulli" -#: utils/adt/arrayfuncs.c:5237 +#: utils/adt/arrayfuncs.c:5299 #, c-format msgid "cannot accumulate empty arrays" msgstr "non è possibile accumulare array vuoti" -#: utils/adt/arrayfuncs.c:5266 utils/adt/arrayfuncs.c:5272 +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "non è possibile accumulare array di dimensioni diverse" -#: utils/adt/arrayfuncs.c:5638 utils/adt/arrayfuncs.c:5678 +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "la dimensione dell'array o il suo limite inferiore non possono essere nulli" -#: utils/adt/arrayfuncs.c:5741 utils/adt/arrayfuncs.c:5767 +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 #, c-format msgid "Dimension array must be one dimensional." msgstr "L'array delle dimensioni deve avere una sola dimensione." -#: utils/adt/arrayfuncs.c:5746 utils/adt/arrayfuncs.c:5772 +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 #, c-format msgid "dimension values cannot be null" msgstr "i valori di dimensione non possono essere nulli" -#: utils/adt/arrayfuncs.c:5778 +#: utils/adt/arrayfuncs.c:5840 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "L'array dei valori inferiori ha dimensione differente dal numero di dimensioni dell'array." -#: utils/adt/arrayfuncs.c:6024 +#: utils/adt/arrayfuncs.c:6086 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "la rimozione di elementi da array multidimensionali non è supportata" -#: utils/adt/arrayfuncs.c:6301 +#: utils/adt/arrayfuncs.c:6363 #, c-format msgid "thresholds must be one-dimensional array" msgstr "la soglia dev'essere un array monodimensionale" -#: utils/adt/arrayfuncs.c:6306 +#: utils/adt/arrayfuncs.c:6368 #, c-format msgid "thresholds array must not contain NULLs" msgstr "l'array delle soglie non può contenere NULL" @@ -19316,19 +20173,19 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "la conversione di codifica da %s a ASCII non è supportata" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:153 utils/adt/cash.c:278 utils/adt/datetime.c:3799 -#: utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 -#: utils/adt/float.c:461 utils/adt/float.c:544 utils/adt/float.c:570 -#: utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 utils/adt/geo_ops.c:178 -#: utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 utils/adt/geo_ops.c:265 -#: utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 utils/adt/geo_ops.c:1356 -#: utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3430 utils/adt/geo_ops.c:4563 -#: utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 utils/adt/mac.c:94 +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 +#: utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 +#: utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 +#: utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 +#: utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 +#: utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 +#: utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 +#: utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 #: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 #: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1539 -#: utils/adt/network.c:58 utils/adt/numeric.c:593 utils/adt/numeric.c:620 -#: utils/adt/numeric.c:5488 utils/adt/numeric.c:5512 utils/adt/numeric.c:5536 -#: utils/adt/numeric.c:6338 utils/adt/numeric.c:6364 utils/adt/oid.c:44 +#: utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 +#: utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 +#: utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 #: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 #: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 #: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 @@ -19337,22 +20194,22 @@ msgstr "la conversione di codifica da %s a ASCII non è supportata" msgid "invalid input syntax for type %s: \"%s\"" msgstr "sintassi di input non valida per il tipo %s: \"%s\"" -#: utils/adt/cash.c:211 utils/adt/cash.c:238 utils/adt/cash.c:249 -#: utils/adt/cash.c:292 utils/adt/int8.c:114 utils/adt/numutils.c:75 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 #: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format msgid "value \"%s\" is out of range for type %s" msgstr "valore \"%s\" fuori dall'intervallo consentito per il tipo %s" -#: utils/adt/cash.c:653 utils/adt/cash.c:703 utils/adt/cash.c:754 -#: utils/adt/cash.c:803 utils/adt/cash.c:855 utils/adt/cash.c:905 -#: utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 -#: utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:704 -#: utils/adt/int.c:846 utils/adt/int.c:954 utils/adt/int.c:1043 -#: utils/adt/int.c:1082 utils/adt/int.c:1110 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6902 -#: utils/adt/numeric.c:7191 utils/adt/numeric.c:8204 utils/adt/timestamp.c:3216 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3469 +#: utils/adt/float.c:3532 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 +#: utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 +#: utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 +#: utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 +#: utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3235 #, c-format msgid "division by zero" msgstr "divisione per zero" @@ -19362,162 +20219,171 @@ msgstr "divisione per zero" msgid "\"char\" out of range" msgstr "\"char\" fuori dall'intervallo consentito" -#: utils/adt/date.c:67 utils/adt/timestamp.c:95 utils/adt/varbit.c:53 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 #: utils/adt/varchar.c:46 #, c-format msgid "invalid type modifier" msgstr "modificatore di tipo non valido" -#: utils/adt/date.c:79 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "la precisione di TIME(%d)%s non può essere negativa" -#: utils/adt/date.c:85 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "la precisione di TIME(%d)%s è stata ridotta al massimo consentito (%d)" -#: utils/adt/date.c:146 utils/adt/datetime.c:1209 utils/adt/datetime.c:2117 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "il valore \"current\" per i tipi date/time non è più supportato" -#: utils/adt/date.c:172 utils/adt/date.c:180 utils/adt/formatting.c:3582 -#: utils/adt/formatting.c:3591 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 +#: utils/adt/formatting.c:3615 #, c-format msgid "date out of range: \"%s\"" msgstr "data fuori dall'intervallo consentito: \"%s\"" -#: utils/adt/date.c:227 utils/adt/date.c:539 utils/adt/date.c:563 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 #: utils/adt/xml.c:2089 #, c-format msgid "date out of range" msgstr "data fuori dall'intervallo consentito" -#: utils/adt/date.c:273 utils/adt/timestamp.c:564 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "valori del campo data fuori dall'intervallo consentito: %d-%02d-%02d" -#: utils/adt/date.c:280 utils/adt/date.c:289 utils/adt/timestamp.c:570 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "data fuori dall'intervallo consentito: %d-%02d-%02d" -#: utils/adt/date.c:327 utils/adt/date.c:350 utils/adt/date.c:376 -#: utils/adt/date.c:1092 utils/adt/date.c:1138 utils/adt/date.c:1672 -#: utils/adt/date.c:1703 utils/adt/date.c:1732 utils/adt/date.c:2469 -#: utils/adt/datetime.c:1690 utils/adt/formatting.c:3457 -#: utils/adt/formatting.c:3489 utils/adt/formatting.c:3557 -#: utils/adt/json.c:1539 utils/adt/json.c:1561 utils/adt/jsonb.c:824 -#: utils/adt/jsonb.c:848 utils/adt/nabstime.c:456 utils/adt/nabstime.c:499 -#: utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 utils/adt/timestamp.c:230 -#: utils/adt/timestamp.c:262 utils/adt/timestamp.c:692 -#: utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 -#: utils/adt/timestamp.c:812 utils/adt/timestamp.c:2795 -#: utils/adt/timestamp.c:2816 utils/adt/timestamp.c:2829 -#: utils/adt/timestamp.c:2838 utils/adt/timestamp.c:2846 -#: utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2924 -#: utils/adt/timestamp.c:2937 utils/adt/timestamp.c:2948 -#: utils/adt/timestamp.c:2956 utils/adt/timestamp.c:3512 -#: utils/adt/timestamp.c:3637 utils/adt/timestamp.c:3678 -#: utils/adt/timestamp.c:3759 utils/adt/timestamp.c:3805 -#: utils/adt/timestamp.c:3908 utils/adt/timestamp.c:4307 -#: utils/adt/timestamp.c:4406 utils/adt/timestamp.c:4416 -#: utils/adt/timestamp.c:4508 utils/adt/timestamp.c:4610 -#: utils/adt/timestamp.c:4620 utils/adt/timestamp.c:4852 -#: utils/adt/timestamp.c:4866 utils/adt/timestamp.c:4871 -#: utils/adt/timestamp.c:4885 utils/adt/timestamp.c:4930 -#: utils/adt/timestamp.c:4962 utils/adt/timestamp.c:4969 -#: utils/adt/timestamp.c:5002 utils/adt/timestamp.c:5006 -#: utils/adt/timestamp.c:5075 utils/adt/timestamp.c:5079 -#: utils/adt/timestamp.c:5093 utils/adt/timestamp.c:5127 utils/adt/xml.c:2111 -#: utils/adt/xml.c:2118 utils/adt/xml.c:2138 utils/adt/xml.c:2145 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 +#: utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 +#: utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 +#: utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:456 +#: utils/adt/nabstime.c:499 utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 +#: utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2814 utils/adt/timestamp.c:2835 +#: utils/adt/timestamp.c:2848 utils/adt/timestamp.c:2857 +#: utils/adt/timestamp.c:2865 utils/adt/timestamp.c:2920 +#: utils/adt/timestamp.c:2943 utils/adt/timestamp.c:2956 +#: utils/adt/timestamp.c:2967 utils/adt/timestamp.c:2975 +#: utils/adt/timestamp.c:3635 utils/adt/timestamp.c:3760 +#: utils/adt/timestamp.c:3801 utils/adt/timestamp.c:3891 +#: utils/adt/timestamp.c:3937 utils/adt/timestamp.c:4040 +#: utils/adt/timestamp.c:4447 utils/adt/timestamp.c:4546 +#: utils/adt/timestamp.c:4556 utils/adt/timestamp.c:4648 +#: utils/adt/timestamp.c:4750 utils/adt/timestamp.c:4760 +#: utils/adt/timestamp.c:4992 utils/adt/timestamp.c:5006 +#: utils/adt/timestamp.c:5011 utils/adt/timestamp.c:5025 +#: utils/adt/timestamp.c:5070 utils/adt/timestamp.c:5102 +#: utils/adt/timestamp.c:5109 utils/adt/timestamp.c:5142 +#: utils/adt/timestamp.c:5146 utils/adt/timestamp.c:5215 +#: utils/adt/timestamp.c:5219 utils/adt/timestamp.c:5233 +#: utils/adt/timestamp.c:5267 utils/adt/xml.c:2111 utils/adt/xml.c:2118 +#: utils/adt/xml.c:2138 utils/adt/xml.c:2145 #, c-format msgid "timestamp out of range" msgstr "timestamp fuori dall'intervallo consentito" -#: utils/adt/date.c:514 +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "non si possono sottrarre date infinite" -#: utils/adt/date.c:592 utils/adt/date.c:623 utils/adt/date.c:641 -#: utils/adt/date.c:2506 utils/adt/date.c:2516 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format msgid "date out of range for timestamp" msgstr "data fuori dall'intervallo consentito per timestamp" -#: utils/adt/date.c:1164 +#: utils/adt/date.c:1190 #, c-format msgid "cannot convert reserved abstime value to date" msgstr "non è possibile convertire un valore speciale per abstime in una data" -#: utils/adt/date.c:1182 utils/adt/date.c:1188 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 #, c-format msgid "abstime out of range for date" msgstr "abstime fuori dall'intervallo massimo per una data" -#: utils/adt/date.c:1301 utils/adt/date.c:2020 +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format msgid "time out of range" msgstr "ora fuori dall'intervallo consentito" -#: utils/adt/date.c:1357 utils/adt/timestamp.c:589 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "campo temporale fuori dall'intervallo consentito: %d:%02d:%02g" -#: utils/adt/date.c:1907 utils/adt/date.c:1920 +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 +#: utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 +#: utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 +#: utils/adt/timestamp.c:3284 utils/adt/timestamp.c:3315 +#: utils/adt/timestamp.c:3346 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "dimensione precedente o successiva non valida nella funzione finestra" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "unità \"%s\" di \"time\" non è riconosciuta" -#: utils/adt/date.c:2028 +#: utils/adt/date.c:2099 #, c-format msgid "time zone displacement out of range" msgstr "la differenza di fuso orario è fuori dall'intervallo consentito" -#: utils/adt/date.c:2601 utils/adt/date.c:2614 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "unità \"%s\" di \"time with time zone\" non è riconosciuta" -#: utils/adt/date.c:2687 utils/adt/datetime.c:931 utils/adt/datetime.c:1848 -#: utils/adt/datetime.c:4636 utils/adt/timestamp.c:503 -#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:4877 -#: utils/adt/timestamp.c:5085 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 +#: utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 +#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:5017 +#: utils/adt/timestamp.c:5225 #, c-format msgid "time zone \"%s\" not recognized" msgstr "fuso orario \"%s\" non riconosciuto" -#: utils/adt/date.c:2719 utils/adt/timestamp.c:4919 utils/adt/timestamp.c:5116 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5059 utils/adt/timestamp.c:5256 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "l'intervallo di fusi orari \"%s\" non può contenere mesi o giorni" -#: utils/adt/datetime.c:3772 utils/adt/datetime.c:3779 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "valore del campo date/time fuori dall'intervallo consentito: \"%s\"" -#: utils/adt/datetime.c:3781 +#: utils/adt/datetime.c:3770 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "Forse è necessario impostare un \"datestyle\" diverso." -#: utils/adt/datetime.c:3786 +#: utils/adt/datetime.c:3775 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "valore del campo interval fuori dall'intervallo consentito: \"%s\"" -#: utils/adt/datetime.c:3792 +#: utils/adt/datetime.c:3781 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "la differenza di fuso orario è fuori dall'intervallo consentito: \"%s\"" -#: utils/adt/datetime.c:4638 +#: utils/adt/datetime.c:4627 #, c-format msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "Il nome del fuso orario figura nel file di configurazione delle abbreviazioni di fuso orario \"%s\"." @@ -19527,27 +20393,22 @@ msgstr "Il nome del fuso orario figura nel file di configurazione delle abbrevia msgid "invalid Datum pointer" msgstr "puntatore al Datum non valido" -#: utils/adt/dbsize.c:116 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "apertura della directory del tablespace \"%s\" fallita: %m" - -#: utils/adt/dbsize.c:764 utils/adt/dbsize.c:832 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format msgid "invalid size: \"%s\"" msgstr "dimensione non valida: \"%s\"" -#: utils/adt/dbsize.c:833 +#: utils/adt/dbsize.c:828 #, c-format msgid "Invalid size unit: \"%s\"." msgstr "Unità di dimensione non valida: \"%s\"." -#: utils/adt/dbsize.c:834 +#: utils/adt/dbsize.c:829 #, c-format msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "Le unità valide sono \"bytes\", \"kB\", \"MB\", \"GB\" e \"TB\"." -#: utils/adt/domains.c:91 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "il tipo %s non è un dominio" @@ -19587,704 +20448,716 @@ msgstr "fine sequenza base64 non valida" msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "I dati di input mancano di padding, sono troncati o comunque corrotti." -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:785 -#: utils/adt/json.c:825 utils/adt/json.c:841 utils/adt/json.c:853 -#: utils/adt/json.c:863 utils/adt/json.c:914 utils/adt/json.c:946 -#: utils/adt/json.c:965 utils/adt/json.c:977 utils/adt/json.c:989 -#: utils/adt/json.c:1134 utils/adt/json.c:1148 utils/adt/json.c:1159 -#: utils/adt/json.c:1167 utils/adt/json.c:1175 utils/adt/json.c:1183 -#: utils/adt/json.c:1191 utils/adt/json.c:1199 utils/adt/json.c:1207 -#: utils/adt/json.c:1215 utils/adt/json.c:1245 utils/adt/varlena.c:296 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 #: utils/adt/varlena.c:337 #, c-format msgid "invalid input syntax for type %s" msgstr "sintassi di input non valida per il tipo %s" -#: utils/adt/enum.c:115 -#, c-format -msgid "unsafe use of new value \"%s\" of enum type %s" -msgstr "uso non sicuro del nuovo valore \"%s\" dell'enumerazione %s" - -#: utils/adt/enum.c:118 -#, c-format -msgid "New enum values must be committed before they can be used." -msgstr "I nuovi valori di enumerazione devono ricevere un commit prima di poter essere usati." - -#: utils/adt/enum.c:136 utils/adt/enum.c:146 utils/adt/enum.c:204 -#: utils/adt/enum.c:214 +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 +#: utils/adt/enum.c:123 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "la sintassi per l'enumerazione %s non è valida: \"%s\"" -#: utils/adt/enum.c:176 utils/adt/enum.c:242 utils/adt/enum.c:301 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format msgid "invalid internal value for enum: %u" msgstr "il valore interno per l'enumerazione non è valido: %u" -#: utils/adt/enum.c:461 utils/adt/enum.c:490 utils/adt/enum.c:530 -#: utils/adt/enum.c:550 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 +#: utils/adt/enum.c:449 #, c-format msgid "could not determine actual enum type" msgstr "determinazione del tipo reale di enumerazione fallita" -#: utils/adt/enum.c:469 utils/adt/enum.c:498 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format msgid "enum %s contains no values" msgstr "l'enumerazione %s non contiene valori" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 +#: utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "il tipo %s non è composito" + +#: utils/adt/float.c:55 #, c-format msgid "value out of range: overflow" msgstr "il valore è fuori dall'intervallo consentito: overflow" -#: utils/adt/float.c:63 +#: utils/adt/float.c:60 #, c-format msgid "value out of range: underflow" msgstr "il valore è fuori dall'intervallo consentito: underflow" -#: utils/adt/float.c:312 +#: utils/adt/float.c:309 #, c-format msgid "\"%s\" is out of range for type real" msgstr "\"%s\" è fuori dall'intervallo consentito per il tipo real" -#: utils/adt/float.c:537 +#: utils/adt/float.c:534 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "\"%s\" è fuori dall'intervallo consentito per il tipo double precision" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:334 -#: utils/adt/int.c:760 utils/adt/int.c:789 utils/adt/int.c:810 -#: utils/adt/int.c:830 utils/adt/int.c:864 utils/adt/int.c:1159 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3050 utils/adt/numeric.c:3059 +#: utils/adt/float.c:1381 utils/adt/float.c:1439 utils/adt/int.c:332 +#: utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 +#: utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 +#: utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format msgid "smallint out of range" msgstr "il valore è fuori dall'intervallo consentito per il tipo smallint" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7624 +#: utils/adt/float.c:1565 utils/adt/numeric.c:7802 #, c-format msgid "cannot take square root of a negative number" msgstr "non è possibile estrarre la radice quadrata di un numero negativo" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2853 +#: utils/adt/float.c:1626 utils/adt/numeric.c:3017 #, c-format msgid "zero raised to a negative power is undefined" msgstr "zero elevato a potenza negativa non è definito" -#: utils/adt/float.c:1476 utils/adt/numeric.c:2859 +#: utils/adt/float.c:1630 utils/adt/numeric.c:3023 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "un numero negativo elevato a potenza non intera è un valore di tipo complesso" -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7890 +#: utils/adt/float.c:1696 utils/adt/float.c:1726 utils/adt/numeric.c:8068 #, c-format msgid "cannot take logarithm of zero" msgstr "non è possibile calcolare il logaritmo di zero" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7894 +#: utils/adt/float.c:1700 utils/adt/float.c:1730 utils/adt/numeric.c:8072 #, c-format msgid "cannot take logarithm of a negative number" msgstr "non è possibile calcolare il logaritmo di un numero negativo" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 -#: utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 -#: utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 -#: utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: utils/adt/float.c:1760 utils/adt/float.c:1790 utils/adt/float.c:1882 +#: utils/adt/float.c:1908 utils/adt/float.c:1935 utils/adt/float.c:1961 +#: utils/adt/float.c:2108 utils/adt/float.c:2143 utils/adt/float.c:2307 +#: utils/adt/float.c:2361 utils/adt/float.c:2425 utils/adt/float.c:2480 #, c-format msgid "input is out of range" msgstr "il valore di input è fuori dall'intervallo consentito" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1493 +#: utils/adt/float.c:3686 utils/adt/numeric.c:1504 #, c-format msgid "count must be greater than zero" msgstr "il valore count dev'essere maggiore di zero" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1500 +#: utils/adt/float.c:3691 utils/adt/numeric.c:1511 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "l'operando e i valori minimo e massimo non possono essere NaN" -#: utils/adt/float.c:3543 +#: utils/adt/float.c:3697 #, c-format msgid "lower and upper bounds must be finite" msgstr "i valori minimo e massimo devono essere finiti" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1513 +#: utils/adt/float.c:3731 utils/adt/numeric.c:1524 #, c-format msgid "lower bound cannot equal upper bound" msgstr "il valore minimo non può essere uguale a quello massimo" -#: utils/adt/formatting.c:493 +#: utils/adt/formatting.c:488 #, c-format msgid "invalid format specification for an interval value" msgstr "la specifica di formato per un intervallo non è valida" -#: utils/adt/formatting.c:494 +#: utils/adt/formatting.c:489 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Gli intervalli non sono legati a specifiche date di calendario." -#: utils/adt/formatting.c:1060 +#: utils/adt/formatting.c:1059 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "\"EEEE\" dev'essere l'ultimo pattern usato" -#: utils/adt/formatting.c:1068 +#: utils/adt/formatting.c:1067 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "\"9\" dev'essere più avanti di \"PR\"" -#: utils/adt/formatting.c:1084 +#: utils/adt/formatting.c:1083 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "\"0\" dev'essere più avanti di \"PR\"" -#: utils/adt/formatting.c:1111 +#: utils/adt/formatting.c:1110 #, c-format msgid "multiple decimal points" msgstr "troppi punti decimali" -#: utils/adt/formatting.c:1115 utils/adt/formatting.c:1198 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "non è possibile usare \"V\" ed un punto decimale insieme" -#: utils/adt/formatting.c:1127 +#: utils/adt/formatting.c:1126 #, c-format msgid "cannot use \"S\" twice" msgstr "non è possibile usare \"S\" due volte" -#: utils/adt/formatting.c:1131 +#: utils/adt/formatting.c:1130 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "non è possibile usare sia \"S\" che \"PL\"/\"MI\"/\"SG\"/\"PR\" insieme" -#: utils/adt/formatting.c:1151 +#: utils/adt/formatting.c:1150 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "non è possibile usare sia \"S\" che \"MI\" insieme" -#: utils/adt/formatting.c:1161 +#: utils/adt/formatting.c:1160 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "non è possibile usare sia \"S\" che \"PL\" insieme" -#: utils/adt/formatting.c:1171 +#: utils/adt/formatting.c:1170 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "non è possibile usare sia \"S\" che \"SG\" insieme" -#: utils/adt/formatting.c:1180 +#: utils/adt/formatting.c:1179 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "non è possibile usare sia \"PR\" che \"S\"/\"PL\"/\"MI\"/\"SG\" insieme" -#: utils/adt/formatting.c:1206 +#: utils/adt/formatting.c:1205 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "non è possibile usare \"EEEE\" due volte" -#: utils/adt/formatting.c:1212 +#: utils/adt/formatting.c:1211 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "\"EEEE\" non è compatibile con altri formati" -#: utils/adt/formatting.c:1213 +#: utils/adt/formatting.c:1212 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "\"EEEE\" può essere usato soltanto insieme a pattern di cifre e punti decimali." -#: utils/adt/formatting.c:1402 +#: utils/adt/formatting.c:1392 #, c-format msgid "\"%s\" is not a number" msgstr "\"%s\" non è un numero" -#: utils/adt/formatting.c:1480 +#: utils/adt/formatting.c:1470 #, c-format msgid "case conversion failed: %s" msgstr "conversione maiuscole/minuscole fallita: %s" -#: utils/adt/formatting.c:1546 +#: utils/adt/formatting.c:1535 #, c-format msgid "could not determine which collation to use for lower() function" msgstr "non è stato possibile determinare quale ordinamento usare per la funzione lower()" -#: utils/adt/formatting.c:1669 +#: utils/adt/formatting.c:1657 #, c-format msgid "could not determine which collation to use for upper() function" msgstr "non è stato possibile determinare quale ordinamento usare per la funzione upper()" -#: utils/adt/formatting.c:1793 +#: utils/adt/formatting.c:1780 #, c-format msgid "could not determine which collation to use for initcap() function" msgstr "non è stato possibile determinare quale ordinamento usare per la funzione initcap()" -#: utils/adt/formatting.c:2160 +#: utils/adt/formatting.c:2148 #, c-format msgid "invalid combination of date conventions" msgstr "la combinazione di convenzioni di date non è valida" -#: utils/adt/formatting.c:2161 +#: utils/adt/formatting.c:2149 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr "Non è possibile usare la convenzione gregoriana e ISO per settimane in un modello di formattazione." -#: utils/adt/formatting.c:2178 +#: utils/adt/formatting.c:2166 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "sono presenti valori contraddittori per il campo \"%s\" nella stringa di formattazione" -#: utils/adt/formatting.c:2180 +#: utils/adt/formatting.c:2168 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Questo valore contraddice una impostazione precedente per lo stesso tipo di campo" -#: utils/adt/formatting.c:2241 +#: utils/adt/formatting.c:2229 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "la stringa di origine è troppo corta per il campo di formattazione \"%s\"" -#: utils/adt/formatting.c:2243 +#: utils/adt/formatting.c:2231 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "Il campo necessita di %d caratteri ma ne restano solo %d." -#: utils/adt/formatting.c:2246 utils/adt/formatting.c:2260 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "Se la stringa di partenza non ha lunghezza fissa, prova ad usare il modificatore \"FM\"." -#: utils/adt/formatting.c:2256 utils/adt/formatting.c:2269 -#: utils/adt/formatting.c:2399 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 +#: utils/adt/formatting.c:2387 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "valore \"%s\" per \"%s\" non valido" -#: utils/adt/formatting.c:2258 +#: utils/adt/formatting.c:2246 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "Il campo necessita di %d caratteri, ma è stato possibile analizzarne solo %d." -#: utils/adt/formatting.c:2271 +#: utils/adt/formatting.c:2259 #, c-format msgid "Value must be an integer." msgstr "Il valore deve essere un integer." -#: utils/adt/formatting.c:2276 +#: utils/adt/formatting.c:2264 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "il valore \"%s\" nella stringa di origine è fuori dall'intervallo consentito" -#: utils/adt/formatting.c:2278 +#: utils/adt/formatting.c:2266 #, c-format msgid "Value must be in the range %d to %d." msgstr "Il valore deve essere compreso fra %d e %d." -#: utils/adt/formatting.c:2401 +#: utils/adt/formatting.c:2389 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "Il valore fornito non corrisponde a nessuno di quelli consentiti per questo campo." -#: utils/adt/formatting.c:2586 utils/adt/formatting.c:2606 -#: utils/adt/formatting.c:2626 utils/adt/formatting.c:2646 -#: utils/adt/formatting.c:2665 utils/adt/formatting.c:2684 -#: utils/adt/formatting.c:2708 utils/adt/formatting.c:2726 -#: utils/adt/formatting.c:2744 utils/adt/formatting.c:2762 -#: utils/adt/formatting.c:2779 utils/adt/formatting.c:2796 +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 +#: utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 +#: utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 +#: utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 +#: utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 +#: utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 #, c-format msgid "localized string format value too long" msgstr "valore del formato della stringa localizzata troppo lungo" -#: utils/adt/formatting.c:3083 +#: utils/adt/formatting.c:3084 #, c-format msgid "formatting field \"%s\" is only supported in to_char" msgstr "il campo di formattazione \"%s\" è supportato solo in to_char" -#: utils/adt/formatting.c:3194 +#: utils/adt/formatting.c:3209 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "stringa di input non valida per \"Y,YYY\"" -#: utils/adt/formatting.c:3700 +#: utils/adt/formatting.c:3724 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "l'ora \"%d\" non è valida su un orologio a 12 ore" -#: utils/adt/formatting.c:3702 +#: utils/adt/formatting.c:3726 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "Usa l'orologio a 24 ore o fornisci un'ora compresa fra 1 e 12." -#: utils/adt/formatting.c:3808 +#: utils/adt/formatting.c:3832 #, c-format msgid "cannot calculate day of year without year information" msgstr "non è possibile calcolare il giorno dell'anno senza informazioni sull'anno" -#: utils/adt/formatting.c:4675 +#: utils/adt/formatting.c:4737 #, c-format msgid "\"EEEE\" not supported for input" msgstr "l'uso di \"EEEE\" non è supportato per l'input" -#: utils/adt/formatting.c:4687 +#: utils/adt/formatting.c:4749 #, c-format msgid "\"RN\" not supported for input" msgstr "l'uso di \"RN\" non è supportato per l'input" -#: utils/adt/genfile.c:63 +#: utils/adt/genfile.c:79 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "i riferimenti alla directory padre (\"..\") non sono consentiti" -#: utils/adt/genfile.c:74 +#: utils/adt/genfile.c:90 #, c-format msgid "absolute path not allowed" msgstr "i percorsi assoluti non sono consentiti" -#: utils/adt/genfile.c:79 +#: utils/adt/genfile.c:95 #, c-format msgid "path must be in or below the current directory" msgstr "il percorso dev'essere nella directory corrente o in una sua sottodirectory" -#: utils/adt/genfile.c:126 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "la lunghezza richiesta è eccessiva" -#: utils/adt/genfile.c:143 +#: utils/adt/genfile.c:159 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "spostamento nel file \"%s\" fallito: %m" -#: utils/adt/genfile.c:201 utils/adt/genfile.c:242 -#, c-format -msgid "must be superuser to read files" -msgstr "solo un superutente può leggere i file" - -#: utils/adt/genfile.c:319 +#: utils/adt/genfile.c:219 #, c-format -msgid "must be superuser to get file information" -msgstr "solo un superutente può ottenere informazioni sul file" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "solo i superutenti possono leggere file con adminpack 1.0" -#: utils/adt/genfile.c:405 +#: utils/adt/genfile.c:220 #, c-format -msgid "must be superuser to get directory listings" -msgstr "solo un superutente può elencare il contenuto della directory" +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "Considera l'uso di pg_file_read(), che è parte del core, invece." -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:939 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "specificazione di linea non valida: A e B non possono essere entrambi zero" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:947 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "specificazione di linea non valida: devono essere due punti distinti" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 -#: utils/adt/geo_ops.c:5181 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 +#: utils/adt/geo_ops.c:5180 #, c-format msgid "too many points requested" msgstr "il numero di punti richiesti è eccessivo" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1403 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "il numero di punti nel valore del \"path\" esterno non è valido" -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2554 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "la funzione \"dist_lb\" non è implementata" -#: utils/adt/geo_ops.c:3015 +#: utils/adt/geo_ops.c:3014 #, c-format msgid "function \"close_sl\" not implemented" msgstr "la funzione \"close_sl\" non è implementata" -#: utils/adt/geo_ops.c:3117 +#: utils/adt/geo_ops.c:3116 #, c-format msgid "function \"close_lb\" not implemented" msgstr "la funzione \"close_lb\" non è implementata" -#: utils/adt/geo_ops.c:3406 +#: utils/adt/geo_ops.c:3405 #, c-format msgid "cannot create bounding box for empty polygon" msgstr "non è possibile creare un bounding box per il poligono vuoto" -#: utils/adt/geo_ops.c:3487 +#: utils/adt/geo_ops.c:3486 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "il numero di punti nel valore \"polygon\" esterno non è valido" -#: utils/adt/geo_ops.c:4012 +#: utils/adt/geo_ops.c:4011 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "la funzione \"poly_distance\" non è implementata" -#: utils/adt/geo_ops.c:4365 +#: utils/adt/geo_ops.c:4364 #, c-format msgid "function \"path_center\" not implemented" msgstr "la funzione \"path_center\" non è implementata" -#: utils/adt/geo_ops.c:4382 +#: utils/adt/geo_ops.c:4381 #, c-format msgid "open path cannot be converted to polygon" msgstr "un path aperto non può essere convertito in un poligono" -#: utils/adt/geo_ops.c:4631 +#: utils/adt/geo_ops.c:4630 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "il raggio nel valore esterno di \"circle\" non è valido" -#: utils/adt/geo_ops.c:5167 +#: utils/adt/geo_ops.c:5166 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "non è possibile convertire un cerchio con raggio nullo in un poligono" -#: utils/adt/geo_ops.c:5172 +#: utils/adt/geo_ops.c:5171 #, c-format msgid "must request at least 2 points" msgstr "devono essere richiesti almeno 2 punti" -#: utils/adt/geo_ops.c:5216 +#: utils/adt/geo_ops.c:5215 #, c-format msgid "cannot convert empty polygon to circle" msgstr "non è possibile convertire un poligono vuoto in un cerchio" -#: utils/adt/int.c:162 +#: utils/adt/int.c:160 #, c-format msgid "int2vector has too many elements" msgstr "ci sono troppi elementi nell'int2vector" -#: utils/adt/int.c:237 +#: utils/adt/int.c:235 #, c-format msgid "invalid int2vector data" msgstr "dati int2vector non validi" -#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "ci sono troppi elementi nell'oidvector" -#: utils/adt/int.c:1347 utils/adt/int8.c:1460 utils/adt/numeric.c:1401 -#: utils/adt/timestamp.c:5178 utils/adt/timestamp.c:5259 +#: utils/adt/int.c:1379 utils/adt/int8.c:1309 utils/adt/numeric.c:1412 +#: utils/adt/timestamp.c:5318 utils/adt/timestamp.c:5399 #, c-format msgid "step size cannot equal zero" msgstr "il valore del passo non può essere uguale a zero" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:105 -#, c-format -msgid "invalid input syntax for %s: \"%s\"" -msgstr "sintassi di input non valida per %s: \"%s\"" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:3005 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 +#: utils/adt/numutils.c:105 +#, c-format +msgid "invalid input syntax for integer: \"%s\"" +msgstr "sintassi di input non valida per un intero: \"%s\"" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 +#: utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 +#: utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 +#: utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 +#: utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 +#: utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 +#: utils/adt/int8.c:1218 utils/adt/int8.c:1253 utils/adt/numeric.c:3169 #: utils/adt/varbit.c:1655 #, c-format msgid "bigint out of range" msgstr "bigint fuori dall'intervallo consentito" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1266 #, c-format msgid "OID out of range" msgstr "OID fuori dall'intervallo consentito" -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Il carattere con valore 0x%02x deve essere sottoposto ad escape." -#: utils/adt/json.c:827 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "\"\\u\" deve essere seguito da quattro cifre esadecimali." -#: utils/adt/json.c:843 +#: utils/adt/json.c:844 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "un carattere surrogato alto Unicode non può seguire un altro surrogato alto" -#: utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:916 -#: utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "un carattere surrogato basso Unicode deve seguire un surrogato alto" -#: utils/adt/json.c:879 utils/adt/json.c:902 +#: utils/adt/json.c:880 utils/adt/json.c:903 #, c-format msgid "unsupported Unicode escape sequence" msgstr "sequenza di escape Unicode non supportata" -#: utils/adt/json.c:880 +#: utils/adt/json.c:881 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 non può essere convertito in testo." -#: utils/adt/json.c:903 +#: utils/adt/json.c:904 #, c-format msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." msgstr "i codici escape Unicode non possono essere usati per caratteri con codice superiore ad 007F quando l'encoding del server non è UTF8" -#: utils/adt/json.c:948 utils/adt/json.c:966 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "La sequenza di escape \"\\%s\" non è valida." -#: utils/adt/json.c:1135 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "La stringa di input è terminata inaspettatamente." -#: utils/adt/json.c:1149 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "Era prevista la fine dell'input, trovato \"%s\" invece." -#: utils/adt/json.c:1160 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "Era previsto un valore JSON, trovato \"%s\" invece." -#: utils/adt/json.c:1168 utils/adt/json.c:1216 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "Era prevista una stringa, trovato \"%s\" invece." -#: utils/adt/json.c:1176 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "Era previsto un elemento di array oppure \"]\", trovato \"%s\" invece." -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "Era previsto \",\" oppure \"]\", trovato \"%s\" invece." -#: utils/adt/json.c:1192 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "Era prevista una stringa oppure \"}\", trovato \"%s\" invece." -#: utils/adt/json.c:1200 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "Era previsto \":\", trovato \"%s\" invece." -#: utils/adt/json.c:1208 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "Era previsto \",\" oppure \"}\", trovato \"%s\" invece." -#: utils/adt/json.c:1246 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "Il token \"%s\" non è valido." -#: utils/adt/json.c:1318 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "dati JSON, riga %d: %s%s%s" -#: utils/adt/json.c:1474 utils/adt/jsonb.c:725 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "la chiave deve essere uno scalare, non array, composito né json" -#: utils/adt/json.c:2011 -#, c-format -msgid "could not determine data type for argument 1" -msgstr "impossibile determinare il tipo di dato per l'argomento 1" - -#: utils/adt/json.c:2021 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format -msgid "could not determine data type for argument 2" -msgstr "impossibile determinare il tipo di dato per l'argomento 2" +msgid "could not determine data type for argument %d" +msgstr "impossibile determinare il tipo di dato per l'argomento %d" -#: utils/adt/json.c:2045 utils/adt/jsonb.c:1782 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format msgid "field name must not be null" msgstr "il nome del campo non può essere nullo" -#: utils/adt/json.c:2122 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format msgid "argument list must have even number of elements" msgstr "la lista di argomenti deve avere un numero pari di elementi" -#: utils/adt/json.c:2123 +#: utils/adt/json.c:2195 #, c-format msgid "The arguments of json_build_object() must consist of alternating keys and values." msgstr "Gli argomenti di json_build_object() devono consistere in una serie alternata di chiavi e valori." -#: utils/adt/json.c:2147 utils/adt/json.c:2168 utils/adt/json.c:2227 -#, c-format -msgid "could not determine data type for argument %d" -msgstr "impossibile determinare il tipo di dato per l'argomento %d" - -#: utils/adt/json.c:2153 +#: utils/adt/json.c:2210 #, c-format msgid "argument %d cannot be null" msgstr "l'argomento %d non può essere nullo" -#: utils/adt/json.c:2154 +#: utils/adt/json.c:2211 #, c-format msgid "Object keys should be text." msgstr "Le chiavi degli oggetti devono essere testo." -#: utils/adt/json.c:2289 utils/adt/jsonb.c:1364 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format msgid "array must have two columns" msgstr "l'array deve avere due colonne" -#: utils/adt/json.c:2313 utils/adt/json.c:2397 utils/adt/jsonb.c:1388 -#: utils/adt/jsonb.c:1483 +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 +#: utils/adt/jsonb.c:1395 #, c-format msgid "null value not allowed for object key" msgstr "valori null non ammessi per le chiavi di oggetti" -#: utils/adt/json.c:2386 utils/adt/jsonb.c:1472 +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 #, c-format msgid "mismatched array dimensions" msgstr "le dimensioni degli array non combaciano" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:258 #, c-format msgid "string too long to represent as jsonb string" msgstr "la stringa è troppo lunga per essere rappresentata come stringa jsonb" -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:259 #, c-format msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "A causa di una restrizione nell'implementazione le stringhe jsonb non possono superare i %d byte." -#: utils/adt/jsonb.c:1183 +#: utils/adt/jsonb.c:1147 #, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "numero di argomenti non valido: gli oggetti devono essere coppie chiave-valore appaiate" +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "Gli argomenti di jsonb_build_object() devono essere coppie chiave-valore appaiate." -#: utils/adt/jsonb.c:1196 +#: utils/adt/jsonb.c:1159 #, c-format msgid "argument %d: key must not be null" msgstr "argomento %d: la chiave non può essere null" -#: utils/adt/jsonb.c:1215 utils/adt/jsonb.c:1238 utils/adt/jsonb.c:1298 -#, c-format -msgid "argument %d: could not determine data type" -msgstr "argomento %d: impossibile determinare il tipo di dati" - -#: utils/adt/jsonb.c:1835 +#: utils/adt/jsonb.c:1747 #, c-format msgid "object keys must be strings" msgstr "le chiavi dell'oggetto devono essere stringhe" +#: utils/adt/jsonb.c:1910 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "non è possibile convertire un null jsonb al tipo %s" + +#: utils/adt/jsonb.c:1911 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "non è possibile convertire una stringa jsonb al tipo %s" + +#: utils/adt/jsonb.c:1912 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "non è possibile convertire un numero jsonb al tipo %s" + +#: utils/adt/jsonb.c:1913 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "non è possibile convertire un booleano jsonb al tipo %s" + +#: utils/adt/jsonb.c:1914 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "non è possibile convertire un array jsonb al tipo %s" + +#: utils/adt/jsonb.c:1915 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "non è possibile convertire un oggetto jsonb al tipo %s" + +#: utils/adt/jsonb.c:1916 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "non è possibile convertire un array o oggetto jsonb al tipo %s" + #: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" @@ -20295,174 +21168,194 @@ msgstr "il numero di coppie dell'oggetto jsonb supera il massimo consentito (%zu msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "il numero di elementi dell'array jsonb supera il massimo consentito (%zu)" -#: utils/adt/jsonb_util.c:1526 utils/adt/jsonb_util.c:1546 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "la dimensione totale degli elementi dell'array jsonb supera il massimo di %u byte" -#: utils/adt/jsonb_util.c:1607 utils/adt/jsonb_util.c:1642 -#: utils/adt/jsonb_util.c:1662 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "la dimensione totale degli elementi dell'oggetto jsonb supera il massimo di %u byte" -#: utils/adt/jsonfuncs.c:510 utils/adt/jsonfuncs.c:675 -#: utils/adt/jsonfuncs.c:2262 utils/adt/jsonfuncs.c:3377 -#: utils/adt/jsonfuncs.c:3661 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3824 #, c-format msgid "cannot call %s on a scalar" msgstr "non è possibile eseguire %s su uno scalare" -#: utils/adt/jsonfuncs.c:515 utils/adt/jsonfuncs.c:662 -#: utils/adt/jsonfuncs.c:3366 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "non è possibile eseguire %s su un array" -#: utils/adt/jsonfuncs.c:1578 utils/adt/jsonfuncs.c:1613 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "non è possibile ottenere la lunghezza di uno scalare" -#: utils/adt/jsonfuncs.c:1582 utils/adt/jsonfuncs.c:1601 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "non è possibile ottenere la lunghezza di un oggetto che non è un array" -#: utils/adt/jsonfuncs.c:1678 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "non è possibile eseguire %s su un argomento che non è un oggetto" -#: utils/adt/jsonfuncs.c:1696 utils/adt/jsonfuncs.c:3192 -#: utils/adt/jsonfuncs.c:3486 +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "funzione che restituisce record eseguita in un contesto che non può accettare il tipo record" -#: utils/adt/jsonfuncs.c:1935 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "non è possibile decostruire un array come un oggetto" -#: utils/adt/jsonfuncs.c:1947 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "non è possibile decostruire uno scalare" -#: utils/adt/jsonfuncs.c:1993 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "non è possibile estrarre elementi da uno scalare" -#: utils/adt/jsonfuncs.c:1997 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "non è possibile estrarre elementi da un oggetto" -#: utils/adt/jsonfuncs.c:2249 utils/adt/jsonfuncs.c:3550 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3708 #, c-format msgid "cannot call %s on a non-array" msgstr "non è possibile eseguire %s su un argomento che non è un array" -#: utils/adt/jsonfuncs.c:2315 utils/adt/jsonfuncs.c:2320 -#: utils/adt/jsonfuncs.c:2337 utils/adt/jsonfuncs.c:2343 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 #, c-format -msgid "expected json array" -msgstr "atteso un array json" +msgid "expected JSON array" +msgstr "atteso un array JSON" -#: utils/adt/jsonfuncs.c:2316 +#: utils/adt/jsonfuncs.c:2334 #, c-format -msgid "see the value of key \"%s\"" -msgstr "vedi il valore della chiave \"%s\"" +msgid "See the value of key \"%s\"." +msgstr "Vedi il valore della chiave \"%s\"." -#: utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2356 #, c-format -msgid "see the array element %s of key \"%s\"" -msgstr "vedi l'elemento dell'array %s della chiave \"%s\"" +msgid "See the array element %s of key \"%s\"." +msgstr "Vedi l'elemento dell'array %s della chiave \"%s\"." -#: utils/adt/jsonfuncs.c:2344 +#: utils/adt/jsonfuncs.c:2362 #, c-format -msgid "see the array element %s" -msgstr "vedi l'elemento dell'array %s" +msgid "See the array element %s." +msgstr "Vedi l'elemento dell'array %s." -#: utils/adt/jsonfuncs.c:2379 +#: utils/adt/jsonfuncs.c:2397 #, c-format -msgid "malformed json array" -msgstr "array json non valido" +msgid "malformed JSON array" +msgstr "array JSON non valido" -#: utils/adt/jsonfuncs.c:3152 utils/adt/jsonfuncs.c:3462 +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "il primo elemento di %s deve essere di tipo riga" -#: utils/adt/jsonfuncs.c:3194 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format msgid "Try calling the function in the FROM clause using a column definition list." msgstr "Prova ad eseguire la funzione nella clausola FROM usando una lista di definizioni di colonne." -#: utils/adt/jsonfuncs.c:3567 utils/adt/jsonfuncs.c:3643 +#: utils/adt/jsonfuncs.c:3725 utils/adt/jsonfuncs.c:3806 #, c-format msgid "argument of %s must be an array of objects" msgstr "l'argomento di %s deve essere un array di oggetti" -#: utils/adt/jsonfuncs.c:3595 +#: utils/adt/jsonfuncs.c:3758 #, c-format msgid "cannot call %s on an object" msgstr "non è possibile eseguire %s su un oggetto" -#: utils/adt/jsonfuncs.c:4071 utils/adt/jsonfuncs.c:4130 -#: utils/adt/jsonfuncs.c:4210 +#: utils/adt/jsonfuncs.c:4235 utils/adt/jsonfuncs.c:4294 +#: utils/adt/jsonfuncs.c:4374 #, c-format msgid "cannot delete from scalar" msgstr "non è possibile eliminare da uno scalare" -#: utils/adt/jsonfuncs.c:4215 +#: utils/adt/jsonfuncs.c:4379 #, c-format msgid "cannot delete from object using integer index" msgstr "non è possibile eliminare da un oggetto usando numeri interi come indici" -#: utils/adt/jsonfuncs.c:4281 utils/adt/jsonfuncs.c:4373 +#: utils/adt/jsonfuncs.c:4445 utils/adt/jsonfuncs.c:4537 #, c-format msgid "cannot set path in scalar" msgstr "non è possibile impostare un percorso in uno scalare" -#: utils/adt/jsonfuncs.c:4326 +#: utils/adt/jsonfuncs.c:4490 #, c-format msgid "cannot delete path in scalar" msgstr "non è possibile eliminare un percorso in uno scalare" -#: utils/adt/jsonfuncs.c:4496 +#: utils/adt/jsonfuncs.c:4660 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "concatenazione invalida di oggetti jsonb" -#: utils/adt/jsonfuncs.c:4530 +#: utils/adt/jsonfuncs.c:4694 #, c-format msgid "path element at position %d is null" msgstr "l'elemento di percorso in posizione %d è nullo" -#: utils/adt/jsonfuncs.c:4616 +#: utils/adt/jsonfuncs.c:4780 #, c-format msgid "cannot replace existing key" msgstr "non è possibile sostituire una chiave esistente" -#: utils/adt/jsonfuncs.c:4617 +#: utils/adt/jsonfuncs.c:4781 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "Prova ad utilizzare la funzione jsonb_set per rimpiazzare il valore della chiave." -#: utils/adt/jsonfuncs.c:4699 +#: utils/adt/jsonfuncs.c:4863 #, c-format msgid "path element at position %d is not an integer: \"%s\"" msgstr "l'elemento di percorso in posizione %d non è un intero: \"%s\"" +#: utils/adt/jsonfuncs.c:4982 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "tipo di flag non valido, solo array e scalari sono consentiti" + +#: utils/adt/jsonfuncs.c:4989 +#, c-format +msgid "flag array element is not a string" +msgstr "l'elemento dell'array di flag non è una stringa" + +#: utils/adt/jsonfuncs.c:4990 utils/adt/jsonfuncs.c:5012 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "I valori possibili sono: \"string\", \"numeric\", \"boolean\", \"key\" e \"all\"" + +#: utils/adt/jsonfuncs.c:5010 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "flag errato nell'array di flag: \"%s\"" + #: utils/adt/levenshtein.c:133 #, c-format msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "L'argomento levenshtein supera la lunghezza massima di %d caratteri" -#: utils/adt/like.c:183 utils/adt/selfuncs.c:5525 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5806 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "non è stato possibile determinare quale ordinamento usare per ILIKE" @@ -20472,12 +21365,12 @@ msgstr "non è stato possibile determinare quale ordinamento usare per ILIKE" msgid "LIKE pattern must not end with escape character" msgstr "i pattern per LIKE non possono terminare con un carattere di escape" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "la stringa di escape non è valida" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "La stringa di escape deve essere vuota o contenere un solo carattere." @@ -20492,109 +21385,119 @@ msgstr "non si possono usare advisory lock in un'operazione parallela" msgid "invalid octet value in \"macaddr\" value: \"%s\"" msgstr "ottetto non valido nel valore \"macaddr\": \"%s\"" -#: utils/adt/mac8.c:554 +#: utils/adt/mac8.c:563 #, c-format msgid "macaddr8 data out of range to convert to macaddr" msgstr "dato macaddr8 fuori dall'intervallo valido per convertire a macaddr" -#: utils/adt/mac8.c:555 +#: utils/adt/mac8.c:564 #, c-format -msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes, from the left, for example: XX-XX-XX-FF-FE-XX-XX-XX, are eligible to be converted from macaddr8 to macaddr." -msgstr "Solo gli indirizzi che hanno valori FF ed FE nel 4º e 5º byte da sinistra, per esempio XX-XX-XX-FF-FE-XX-XX-XX, possono essere convertiti da macaddr8 a macaddr." +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Solo gli indirizzi che hanno valori FF ed FE nel 4º e 5º byte da sinistra, per esempio XX-XX-XX-ff-fe-XX-XX-XX, possono essere convertiti da macaddr8 a macaddr." -#: utils/adt/misc.c:238 +#: utils/adt/misc.c:239 #, c-format msgid "PID %d is not a PostgreSQL server process" msgstr "il PID %d non è un processo del server PostgreSQL" -#: utils/adt/misc.c:289 +#: utils/adt/misc.c:290 #, c-format msgid "must be a superuser to cancel superuser query" msgstr "solo un superutente può annullare la query di un superutente" -#: utils/adt/misc.c:294 +#: utils/adt/misc.c:295 #, c-format msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" msgstr "occorre essere un membro del ruolo la cui query deve essere annullata o membro di pg_signal_backend" -#: utils/adt/misc.c:313 +#: utils/adt/misc.c:314 #, c-format msgid "must be a superuser to terminate superuser process" msgstr "solo un superutente può terminare il processo di un superutente" -#: utils/adt/misc.c:318 +#: utils/adt/misc.c:319 #, c-format msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" msgstr "occorre essere un membro del ruolo la cui processo deve essere terminato o membro di pg_signal_backend" -#: utils/adt/misc.c:335 +#: utils/adt/misc.c:336 #, c-format msgid "failed to send signal to postmaster: %m" msgstr "invio del segnale al postmaster fallito: %m" #: utils/adt/misc.c:355 #, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "solo i superutenti possono rotare i file di log con adminpack 1.0" + +#: utils/adt/misc.c:356 +#, c-format +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "Considera l'uso di pg_logfile_rotate(), che è parte del core, invece." + +#: utils/adt/misc.c:361 utils/adt/misc.c:381 +#, c-format msgid "rotation not possible because log collection not active" msgstr "non è stato possibile eseguire la rotazione perché la raccolta dei log non è attiva" -#: utils/adt/misc.c:392 +#: utils/adt/misc.c:418 #, c-format msgid "global tablespace never has databases" msgstr "il tablespace globale non contiene mai dei database" -#: utils/adt/misc.c:413 +#: utils/adt/misc.c:439 #, c-format msgid "%u is not a tablespace OID" msgstr "%u non è l'OID di un tablespace" -#: utils/adt/misc.c:606 +#: utils/adt/misc.c:626 msgid "unreserved" msgstr "non riservato" -#: utils/adt/misc.c:610 +#: utils/adt/misc.c:630 msgid "unreserved (cannot be function or type name)" msgstr "non riservato (non può essere una funzione o il nome di un tipo)" -#: utils/adt/misc.c:614 +#: utils/adt/misc.c:634 msgid "reserved (can be function or type name)" msgstr "riservato (può essere una funzione o il nome di un tipo)" -#: utils/adt/misc.c:618 +#: utils/adt/misc.c:638 msgid "reserved" msgstr "riservato" -#: utils/adt/misc.c:792 utils/adt/misc.c:806 utils/adt/misc.c:845 -#: utils/adt/misc.c:851 utils/adt/misc.c:857 utils/adt/misc.c:880 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 +#: utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 #, c-format msgid "string is not a valid identifier: \"%s\"" msgstr "la stringa non è un identificatore valido: \"%s\"" -#: utils/adt/misc.c:794 +#: utils/adt/misc.c:814 #, c-format msgid "String has unclosed double quotes." msgstr "La stringa ha virgolette non chiuse." -#: utils/adt/misc.c:808 +#: utils/adt/misc.c:828 #, c-format msgid "Quoted identifier must not be empty." msgstr "L'identificativo non può essere vuoto." -#: utils/adt/misc.c:847 +#: utils/adt/misc.c:867 #, c-format msgid "No valid identifier before \".\"." msgstr "L'identificativo prima del \".\" non è valido." -#: utils/adt/misc.c:853 +#: utils/adt/misc.c:873 #, c-format msgid "No valid identifier after \".\"." msgstr "L'identificativo dopo il \".\" non è valido." -#: utils/adt/misc.c:914 +#: utils/adt/misc.c:934 #, c-format msgid "log format \"%s\" is not supported" msgstr "il formato di log \"%s\" non è supportato" -#: utils/adt/misc.c:915 +#: utils/adt/misc.c:935 #, c-format msgid "The supported log formats are \"stderr\" and \"csvlog\"." msgstr "I formati supportati sono \"stderr\" e \"csvlog\"." @@ -20629,8 +21532,8 @@ msgstr "il valore \"%s\" non è valido per cidr" msgid "Value has bits set to right of mask." msgstr "Il valore ha dei bit settati a destra della maschera." -#: utils/adt/network.c:111 utils/adt/network.c:582 utils/adt/network.c:607 -#: utils/adt/network.c:632 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 +#: utils/adt/network.c:642 #, c-format msgid "could not format inet value: %m" msgstr "formattazione del valore inet fallita: %m" @@ -20663,109 +21566,114 @@ msgstr "valore \"cidr\" esterno non valido" msgid "invalid mask length: %d" msgstr "la lunghezza della maschera non è valida: %d" -#: utils/adt/network.c:650 +#: utils/adt/network.c:660 #, c-format msgid "could not format cidr value: %m" msgstr "formattazione del valore cidr fallita: %m" -#: utils/adt/network.c:883 +#: utils/adt/network.c:893 #, c-format msgid "cannot merge addresses from different families" msgstr "non è possibile unire indirizzi di famiglie diverse" -#: utils/adt/network.c:1302 +#: utils/adt/network.c:1309 #, c-format msgid "cannot AND inet values of different sizes" msgstr "non è possibile eseguire l'AND fra valori di tipo inet di dimensione diversa" -#: utils/adt/network.c:1334 +#: utils/adt/network.c:1341 #, c-format msgid "cannot OR inet values of different sizes" msgstr "non è possibile eseguire l'OR fra valori di tipo inet di dimensione diversa" -#: utils/adt/network.c:1395 utils/adt/network.c:1471 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format msgid "result is out of range" msgstr "il risultato è fuori dall'intervallo consentito" -#: utils/adt/network.c:1436 +#: utils/adt/network.c:1443 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "non è possibile sottrarre valori di tipo inet di dimensione diversa" -#: utils/adt/numeric.c:819 +#: utils/adt/numeric.c:830 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "il segno nel valore \"numeric\" esterno non è valido" -#: utils/adt/numeric.c:825 +#: utils/adt/numeric.c:836 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "la scala nel valore \"numeric\" esterno non è valida" -#: utils/adt/numeric.c:834 +#: utils/adt/numeric.c:845 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "una delle cifre nel valore \"numeric\" esterno non è valida" -#: utils/adt/numeric.c:1024 utils/adt/numeric.c:1038 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "la precisione di NUMERIC (%d) deve essere compresa fra 1 e %d" -#: utils/adt/numeric.c:1029 +#: utils/adt/numeric.c:1040 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "il numero di cifre decimali di NUMERIC (%d) deve essere compreso fra 0 e la precisione %d" -#: utils/adt/numeric.c:1047 +#: utils/adt/numeric.c:1058 #, c-format msgid "invalid NUMERIC type modifier" msgstr "modificatore del tipo NUMERIC non valido" -#: utils/adt/numeric.c:1379 +#: utils/adt/numeric.c:1390 #, c-format msgid "start value cannot be NaN" msgstr "il valore d'inizio non può essere NaN" -#: utils/adt/numeric.c:1384 +#: utils/adt/numeric.c:1395 #, c-format msgid "stop value cannot be NaN" msgstr "il valore di fine non può essere NaN" -#: utils/adt/numeric.c:1394 +#: utils/adt/numeric.c:1405 #, c-format msgid "step size cannot be NaN" msgstr "la dimensione dell'intervallo non può essere NaN" -#: utils/adt/numeric.c:2589 utils/adt/numeric.c:5551 utils/adt/numeric.c:5996 -#: utils/adt/numeric.c:7700 utils/adt/numeric.c:8125 utils/adt/numeric.c:8240 -#: utils/adt/numeric.c:8313 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 +#: utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 +#: utils/adt/numeric.c:8490 #, c-format msgid "value overflows numeric format" msgstr "il valore causa un overflow nel formato numeric" -#: utils/adt/numeric.c:2931 +#: utils/adt/numeric.c:3095 #, c-format msgid "cannot convert NaN to integer" msgstr "non è possibile convertire NaN in un integer" -#: utils/adt/numeric.c:2997 +#: utils/adt/numeric.c:3161 #, c-format msgid "cannot convert NaN to bigint" msgstr "non è possibile convertire NaN in un bigint" -#: utils/adt/numeric.c:3042 +#: utils/adt/numeric.c:3206 #, c-format msgid "cannot convert NaN to smallint" msgstr "non è possibile convertire NaN in uno smallint" -#: utils/adt/numeric.c:6066 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "non è possibile convertire infinity in numeric" + +#: utils/adt/numeric.c:6240 #, c-format msgid "numeric field overflow" msgstr "il campo numeric causa un overflow" -#: utils/adt/numeric.c:6067 +#: utils/adt/numeric.c:6241 #, c-format msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "Un campo con precisione %d e %d cifre decimali deve arrotondarsi ad un valore assoluto inferiore a %s%d." @@ -20780,28 +21688,28 @@ msgstr "il valore \"%s\" è fuori dall'intervallo consentito per un intero a 8 b msgid "invalid oidvector data" msgstr "i dati nell'oidvector non sono validi" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "il carattere richiesto è troppo grande" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "il carattere richiesto è troppo grande per la codifica: %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "il carattere richiesto non è valido per la codifica: %d" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "non sono consentiti caratteri nulli" -#: utils/adt/orderedsetaggs.c:426 utils/adt/orderedsetaggs.c:531 -#: utils/adt/orderedsetaggs.c:670 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "il valore percentile %g non è tra 0 e 1" @@ -20811,92 +21719,97 @@ msgstr "il valore percentile %g non è tra 0 e 1" msgid "Apply system library package updates." msgstr "Applica gli aggiornamenti ai pacchetti di sistema." -#: utils/adt/pg_locale.c:1239 +#: utils/adt/pg_locale.c:1249 #, c-format msgid "could not create locale \"%s\": %m" msgstr "creazione del locale \"%s\" fallita: %m" -#: utils/adt/pg_locale.c:1242 +#: utils/adt/pg_locale.c:1252 #, c-format msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "Il sistema operativo non ha trovato dati di locale per il locale di nome \"%s\"." -#: utils/adt/pg_locale.c:1339 +#: utils/adt/pg_locale.c:1353 #, c-format msgid "collations with different collate and ctype values are not supported on this platform" msgstr "le collazioni con tipi diversi di ordinamento e ctype non sono supportati su questa piattaforma" -#: utils/adt/pg_locale.c:1348 +#: utils/adt/pg_locale.c:1362 #, c-format msgid "collation provider LIBC is not supported on this platform" msgstr "fornitore di ordinamento LIBC non supportato su questa piattaforma" -#: utils/adt/pg_locale.c:1361 utils/adt/pg_locale.c:1443 +#: utils/adt/pg_locale.c:1374 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ordinamenti con valori diversi di collate e ctype non sono supportati da ICU" + +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 #, c-format msgid "could not open collator for locale \"%s\": %s" msgstr "apertura dell'ordinamento per il locale \"%s\" fallita: %s" -#: utils/adt/pg_locale.c:1370 +#: utils/adt/pg_locale.c:1391 #, c-format msgid "ICU is not supported in this build" msgstr "ICU non supportato in questo build" -#: utils/adt/pg_locale.c:1371 +#: utils/adt/pg_locale.c:1392 #, c-format msgid "You need to rebuild PostgreSQL using --with-icu." msgstr "Occorre ricompilare PostgreSQL usando --with-icu." -#: utils/adt/pg_locale.c:1391 +#: utils/adt/pg_locale.c:1412 #, c-format msgid "collation \"%s\" has no actual version, but a version was specified" msgstr "l'ordinamento \"%s\" non ha una versione, ma una versione è stata specificata" -#: utils/adt/pg_locale.c:1398 +#: utils/adt/pg_locale.c:1419 #, c-format msgid "collation \"%s\" has version mismatch" msgstr "la versione dell'ordinamento \"%s\" non combacia" -#: utils/adt/pg_locale.c:1400 +#: utils/adt/pg_locale.c:1421 #, c-format msgid "The collation in the database was created using version %s, but the operating system provides version %s." msgstr "L'ordinamento nel database è stato creato usando la versione %s, ma il sistema operativo fornisce la versione %s." -#: utils/adt/pg_locale.c:1403 +#: utils/adt/pg_locale.c:1424 #, c-format msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." msgstr "Ricostruisci tutti gli oggetti che usano questo ordinamento ed esegui ALTER COLLATION %s REFRESH VERSION, oppure ricompila PostgreSQL con la versione giusta della libreria." -#: utils/adt/pg_locale.c:1483 +#: utils/adt/pg_locale.c:1508 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "apertura del convertitore ICU per l'encoding \"%s\" fallita: %s" -#: utils/adt/pg_locale.c:1503 +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 #, c-format msgid "ucnv_toUChars failed: %s" msgstr "ucnv_toUChars fallito: %s" -#: utils/adt/pg_locale.c:1521 +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 #, c-format msgid "ucnv_fromUChars failed: %s" msgstr "ucnv_fromUChars fallito: %s" -#: utils/adt/pg_locale.c:1693 +#: utils/adt/pg_locale.c:1758 #, c-format msgid "invalid multibyte character for locale" msgstr "carattere multibyte non valido per il locale" -#: utils/adt/pg_locale.c:1694 +#: utils/adt/pg_locale.c:1759 #, c-format msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." msgstr "Il locale LC_CTYPE del server probabilmente non è compatibile con la codifica del database." -#: utils/adt/pg_upgrade_support.c:28 +#: utils/adt/pg_upgrade_support.c:29 #, c-format msgid "function can only be called when server is in binary upgrade mode" msgstr "la funzione può essere richiamata solo quando il server è in modalità di aggiornamento binario" -#: utils/adt/pgstatfuncs.c:473 +#: utils/adt/pgstatfuncs.c:474 #, c-format msgid "invalid command name: \"%s\"" msgstr "nome di comando non valido: \"%s\"" @@ -20936,233 +21849,236 @@ msgstr "il risultato della differenza di intervalli non sarebbe continuo" msgid "result of range union would not be contiguous" msgstr "il risultato dell'unione di intervalli non sarebbe continuo" -#: utils/adt/rangetypes.c:1533 +#: utils/adt/rangetypes.c:1597 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "il limite inferiore dell'intervallo dev'essere minore o uguale del limite superiore" -#: utils/adt/rangetypes.c:1916 utils/adt/rangetypes.c:1929 -#: utils/adt/rangetypes.c:1943 +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 +#: utils/adt/rangetypes.c:2007 #, c-format msgid "invalid range bound flags" msgstr "flag di limiti dell'intervallo non valido" -#: utils/adt/rangetypes.c:1917 utils/adt/rangetypes.c:1930 -#: utils/adt/rangetypes.c:1944 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "I valori validi sono \"[]\", \"[)\", \"(]\" e \"()\"." -#: utils/adt/rangetypes.c:2009 utils/adt/rangetypes.c:2026 -#: utils/adt/rangetypes.c:2039 utils/adt/rangetypes.c:2057 -#: utils/adt/rangetypes.c:2068 utils/adt/rangetypes.c:2112 -#: utils/adt/rangetypes.c:2120 +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 +#: utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 +#: utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 +#: utils/adt/rangetypes.c:2184 #, c-format msgid "malformed range literal: \"%s\"" msgstr "letterale di intervallo non definito correttamente: \"%s\"" -#: utils/adt/rangetypes.c:2011 +#: utils/adt/rangetypes.c:2075 #, c-format msgid "Junk after \"empty\" key word." msgstr "Dati spuri dopo la parola chiave \"empty\"." -#: utils/adt/rangetypes.c:2028 +#: utils/adt/rangetypes.c:2092 #, c-format msgid "Missing left parenthesis or bracket." msgstr "Manca la parentesi aperta." -#: utils/adt/rangetypes.c:2041 +#: utils/adt/rangetypes.c:2105 #, c-format msgid "Missing comma after lower bound." msgstr "Manca la virgola dopo il limite inferiore." -#: utils/adt/rangetypes.c:2059 +#: utils/adt/rangetypes.c:2123 #, c-format msgid "Too many commas." msgstr "Troppe virgole." -#: utils/adt/rangetypes.c:2070 +#: utils/adt/rangetypes.c:2134 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "Caratteri spuri dopo la parentesi chiusa." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1344 utils/adt/varlena.c:3948 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 #, c-format msgid "regular expression failed: %s" msgstr "l'espressione regolare %s è fallita" -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 #, c-format msgid "invalid regexp option: \"%c\"" msgstr "l'opzione regexp \"%c\" non è valida" -#: utils/adt/regexp.c:862 +#: utils/adt/regexp.c:866 #, c-format msgid "regexp_match does not support the global option" msgstr "regexp_match non supporta l'opzione globale" -#: utils/adt/regexp.c:863 +#: utils/adt/regexp.c:867 #, c-format msgid "Use the regexp_matches function instead." msgstr "Usa la funzione regexp_matches." -#: utils/adt/regexp.c:1163 +#: utils/adt/regexp.c:1049 +#, c-format +msgid "too many regular expression matches" +msgstr "troppe corrispondenze nell'espressione regolare" + +#: utils/adt/regexp.c:1244 #, c-format msgid "regexp_split_to_table does not support the global option" msgstr "regexp_split_to_table non supporta l'opzione globale" -#: utils/adt/regexp.c:1219 +#: utils/adt/regexp.c:1297 #, c-format msgid "regexp_split_to_array does not support the global option" msgstr "regexp_split_to_array non supporta l'opzione globale" -#: utils/adt/regproc.c:105 +#: utils/adt/regproc.c:106 #, c-format msgid "more than one function named \"%s\"" msgstr "più di una funzione si chiama \"%s\"" -#: utils/adt/regproc.c:523 +#: utils/adt/regproc.c:524 #, c-format msgid "more than one operator named %s" msgstr "più di un operatore si chiama %s" -#: utils/adt/regproc.c:690 utils/adt/regproc.c:731 gram.y:7854 +#: utils/adt/regproc.c:691 utils/adt/regproc.c:732 gram.y:8182 #, c-format msgid "missing argument" msgstr "argomento mancante" -#: utils/adt/regproc.c:691 utils/adt/regproc.c:732 gram.y:7855 +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8183 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." msgstr "Usa NONE per indicare l'argomento mancante in un operatore unario." -#: utils/adt/regproc.c:695 utils/adt/regproc.c:736 utils/adt/regproc.c:1864 -#: utils/adt/ruleutils.c:8888 utils/adt/ruleutils.c:9056 +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9132 utils/adt/ruleutils.c:9300 #, c-format msgid "too many arguments" msgstr "troppi argomenti" -#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 #, c-format msgid "Provide two argument types for operator." msgstr "Fornisci due tipi di argomento per l'operatore." -#: utils/adt/regproc.c:1448 utils/adt/regproc.c:1472 utils/adt/regproc.c:1573 -#: utils/adt/regproc.c:1597 utils/adt/regproc.c:1699 utils/adt/regproc.c:1704 -#: utils/adt/varlena.c:3203 utils/adt/varlena.c:3208 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 #, c-format msgid "invalid name syntax" msgstr "la sintassi per il nome non è valida" -#: utils/adt/regproc.c:1762 +#: utils/adt/regproc.c:1763 #, c-format msgid "expected a left parenthesis" msgstr "era attesa un parentesi tonda aperta" -#: utils/adt/regproc.c:1778 +#: utils/adt/regproc.c:1779 #, c-format msgid "expected a right parenthesis" msgstr "era attesa un parentesi tonda chiusa" -#: utils/adt/regproc.c:1797 +#: utils/adt/regproc.c:1798 #, c-format msgid "expected a type name" msgstr "era atteso il nome di un tipo" -#: utils/adt/regproc.c:1829 +#: utils/adt/regproc.c:1830 #, c-format msgid "improper type name" msgstr "il nome del tipo non è corretto" -#: utils/adt/ri_triggers.c:314 utils/adt/ri_triggers.c:371 -#: utils/adt/ri_triggers.c:790 utils/adt/ri_triggers.c:1013 -#: utils/adt/ri_triggers.c:1169 utils/adt/ri_triggers.c:1350 -#: utils/adt/ri_triggers.c:1515 utils/adt/ri_triggers.c:1691 -#: utils/adt/ri_triggers.c:1871 utils/adt/ri_triggers.c:2062 -#: utils/adt/ri_triggers.c:2120 utils/adt/ri_triggers.c:2225 -#: utils/adt/ri_triggers.c:2402 gram.y:3678 +#: utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 +#: utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 +#: utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 +#: utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 +#: utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 gram.y:3817 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "il MATCH PARTIAL non è stato ancora implementato" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 -#: utils/adt/ri_triggers.c:3315 +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 +#: utils/adt/ri_triggers.c:2842 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "la INSERT o l'UPDATE sulla tabella \"%s\" viola il vincolo di chiave esterna \"%s\"" -#: utils/adt/ri_triggers.c:346 utils/adt/ri_triggers.c:2493 +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL non consente l'uso di valori chiave nulli e non nulli insieme." -#: utils/adt/ri_triggers.c:2732 +#: utils/adt/ri_triggers.c:2273 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "la funzione \"%s\" deve essere eseguita per un INSERT" -#: utils/adt/ri_triggers.c:2738 +#: utils/adt/ri_triggers.c:2279 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "la funzione \"%s\" deve essere eseguita per un UPDATE" -#: utils/adt/ri_triggers.c:2744 +#: utils/adt/ri_triggers.c:2285 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "la funzione \"%s\" deve essere eseguita per una DELETE" -#: utils/adt/ri_triggers.c:2767 +#: utils/adt/ri_triggers.c:2308 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "non ci sono elementi pg_constraint per il trigger \"%s\" sulla tabella \"%s\"" -#: utils/adt/ri_triggers.c:2769 +#: utils/adt/ri_triggers.c:2310 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "Rimuovi questo trigger di integrità referenziale e relativi elementi collegati, poi esegui ALTER TABLE ADD CONSTRAINT." -#: utils/adt/ri_triggers.c:3225 +#: utils/adt/ri_triggers.c:2689 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "la query di integrità referenziale su \"%s\" dal vincolo \"%s\" su \"%s\" ha restituito un risultato inatteso" -#: utils/adt/ri_triggers.c:3229 +#: utils/adt/ri_triggers.c:2693 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Ciò è probabilmente dovuto ad una RULE che ha riscritto la query." -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/ri_triggers.c:2846 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "La chiave (%s)=(%s) non è presente nella tabella \"%s\"." -#: utils/adt/ri_triggers.c:3322 +#: utils/adt/ri_triggers.c:2849 #, c-format msgid "Key is not present in table \"%s\"." msgstr "La chiave non è presente nella tabella \"%s\"." -#: utils/adt/ri_triggers.c:3328 +#: utils/adt/ri_triggers.c:2855 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "l'istruzione UPDATE o DELETE sulla tabella \"%s\" viola il vincolo di chiave esterna \"%s\" sulla tabella \"%s\"" -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/ri_triggers.c:2860 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "La chiave (%s)=(%s) è ancora referenziata dalla tabella \"%s\"." -#: utils/adt/ri_triggers.c:3336 +#: utils/adt/ri_triggers.c:2863 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "La chiave è ancora referenziata dalla tabella \"%s\"." -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "l'input di un tipo composito anonimo non è implementato" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 +#: utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 #, c-format msgid "malformed record literal: \"%s\"" msgstr "letterale record non corretto: \"%s\"" @@ -21172,59 +22088,59 @@ msgstr "letterale record non corretto: \"%s\"" msgid "Missing left parenthesis." msgstr "Manca la parentesi tonda aperta." -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:185 #, c-format msgid "Too few columns." msgstr "Il numero di colonne è insufficiente." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:268 #, c-format msgid "Too many columns." msgstr "Troppe colonne." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:276 #, c-format msgid "Junk after right parenthesis." msgstr "Sono presenti caratteri spuri dopo la parentesi chiusa." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:530 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "il numero di colonne non è corretto, %d invece di %d" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:558 #, c-format msgid "wrong data type: %u, expected %u" msgstr "il tipo di dati non è corretto, %u invece di %u" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:619 #, c-format msgid "improper binary format in record column %d" msgstr "il formato binario nella colonna %d del record non è corretto" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 utils/adt/rowtypes.c:1396 -#: utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 +#: utils/adt/rowtypes.c:1657 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "non è possibile confrontare i tipi di colonne dissimili %s e %s alla colonna %d del record" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 utils/adt/rowtypes.c:1529 -#: utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 +#: utils/adt/rowtypes.c:1731 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "non è possibile confrontare tipi di record con diverso numero di colonne" -#: utils/adt/ruleutils.c:4655 +#: utils/adt/ruleutils.c:4823 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "la regola \"%s\" ha un tipo di evento non supportato %d" -#: utils/adt/selfuncs.c:5510 +#: utils/adt/selfuncs.c:5791 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "il confronto case insensitive sul tipo bytea non è supportato" -#: utils/adt/selfuncs.c:5612 +#: utils/adt/selfuncs.c:5893 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "il confronto con espressioni regolari sul tipo bytea non è supportato" @@ -21287,14 +22203,14 @@ msgid "timestamp out of range: \"%g\"" msgstr "timestamp fuori dall'intervallo consentito: \"%g\" " #: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 -#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:2994 -#: utils/adt/timestamp.c:2999 utils/adt/timestamp.c:3004 -#: utils/adt/timestamp.c:3054 utils/adt/timestamp.c:3061 -#: utils/adt/timestamp.c:3068 utils/adt/timestamp.c:3088 -#: utils/adt/timestamp.c:3095 utils/adt/timestamp.c:3102 -#: utils/adt/timestamp.c:3132 utils/adt/timestamp.c:3140 -#: utils/adt/timestamp.c:3184 utils/adt/timestamp.c:3507 -#: utils/adt/timestamp.c:3632 utils/adt/timestamp.c:4000 +#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3013 +#: utils/adt/timestamp.c:3018 utils/adt/timestamp.c:3023 +#: utils/adt/timestamp.c:3073 utils/adt/timestamp.c:3080 +#: utils/adt/timestamp.c:3087 utils/adt/timestamp.c:3107 +#: utils/adt/timestamp.c:3114 utils/adt/timestamp.c:3121 +#: utils/adt/timestamp.c:3151 utils/adt/timestamp.c:3159 +#: utils/adt/timestamp.c:3203 utils/adt/timestamp.c:3630 +#: utils/adt/timestamp.c:3755 utils/adt/timestamp.c:4140 #, c-format msgid "interval out of range" msgstr "il valore di interval è fuori dall'intervallo consentito" @@ -21319,46 +22235,46 @@ msgstr "la precisione di INTERVAL(%d) è stata ridotta al massimo consentito %d" msgid "interval(%d) precision must be between %d and %d" msgstr "la precisione di INTERVAL(%d) deve essere compresa fra %d e %d" -#: utils/adt/timestamp.c:2595 +#: utils/adt/timestamp.c:2614 #, c-format msgid "cannot subtract infinite timestamps" msgstr "non è possibile sottrarre valori infiniti di TIMESTAMP" -#: utils/adt/timestamp.c:3751 utils/adt/timestamp.c:4260 -#: utils/adt/timestamp.c:4427 utils/adt/timestamp.c:4448 +#: utils/adt/timestamp.c:3883 utils/adt/timestamp.c:4400 +#: utils/adt/timestamp.c:4567 utils/adt/timestamp.c:4588 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "unità \"%s\" di timestamp non supportata" -#: utils/adt/timestamp.c:3765 utils/adt/timestamp.c:4214 -#: utils/adt/timestamp.c:4458 +#: utils/adt/timestamp.c:3897 utils/adt/timestamp.c:4354 +#: utils/adt/timestamp.c:4598 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "unità \"%s\" di timestamp non riconosciuta" -#: utils/adt/timestamp.c:3897 utils/adt/timestamp.c:4255 -#: utils/adt/timestamp.c:4628 utils/adt/timestamp.c:4650 +#: utils/adt/timestamp.c:4029 utils/adt/timestamp.c:4395 +#: utils/adt/timestamp.c:4768 utils/adt/timestamp.c:4790 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "unità \"%s\" di timestamp with time zone non supportata" -#: utils/adt/timestamp.c:3914 utils/adt/timestamp.c:4209 -#: utils/adt/timestamp.c:4659 +#: utils/adt/timestamp.c:4046 utils/adt/timestamp.c:4349 +#: utils/adt/timestamp.c:4799 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "unità \"%s\" di timestamp with time zone non riconosciuta" -#: utils/adt/timestamp.c:3987 +#: utils/adt/timestamp.c:4127 #, c-format msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "le unità di intervallo \"%s\" non sono supportate perché generalmente i mesi hanno settimane frazionali" -#: utils/adt/timestamp.c:3993 utils/adt/timestamp.c:4753 +#: utils/adt/timestamp.c:4133 utils/adt/timestamp.c:4893 #, c-format msgid "interval units \"%s\" not supported" msgstr "unità \"%s\" di interval non supportata" -#: utils/adt/timestamp.c:4009 utils/adt/timestamp.c:4776 +#: utils/adt/timestamp.c:4149 utils/adt/timestamp.c:4916 #, c-format msgid "interval units \"%s\" not recognized" msgstr "unità \"%s\" di interval non riconosciuta" @@ -21388,43 +22304,43 @@ msgstr "la funzione trigger suppress_redundant_updates deve essere invocata su o msgid "gtsvector_in not implemented" msgstr "la funzione gtsvector_in non è implementata" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "la distanza nell'operatore di frase non può essere maggiore di %d" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "errore di sintassi in tsquery: \"%s\"" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "non ci sono operandi in tsquery: \"%s\"" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "il valore in tsquery è troppo grande: \"%s\"" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "l'operando in tsquery è troppo lungo: \"%s\"" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "la parola in tsquery è troppo lunga: \"%s\"" -#: utils/adt/tsquery.c:642 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "la query di ricerca di testo non contiene alcun lessema: \"%s\"" -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "tsquery troppo grande" @@ -21530,86 +22446,74 @@ msgstr "la configurazione di ricerca di testo \"%s\" deve avere uno schema" msgid "column \"%s\" is not of a character type" msgstr "la colonna \"%s\" non è di tipo carattere" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "errore di sintassi in tsvector: \"%s\"" -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "non c'è alcun carattere sottoposto ad escape: \"%s\"" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "le informazioni di posizione nel tsvector sono errate: \"%s\"" #: utils/adt/txid.c:135 #, c-format -msgid "transaction ID " -msgstr "ID transazione " +msgid "transaction ID %s is in the future" +msgstr "l'ID di transazione %s è nel futuro" #: utils/adt/txid.c:624 #, c-format msgid "invalid external txid_snapshot data" msgstr "dati txid_snapshot esterni non validi" -#: utils/adt/txid.c:758 utils/adt/txid.c:779 -msgid "in progress" -msgstr "in esecuzione" - -#: utils/adt/txid.c:760 -msgid "committed" -msgstr "completata" - -#: utils/adt/txid.c:762 utils/adt/txid.c:777 -msgid "aborted" -msgstr "annullata" - -#: utils/adt/varbit.c:58 utils/adt/varchar.c:51 +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 #, c-format msgid "length for type %s must be at least 1" msgstr "la lunghezza per il tipo %s dev'essere almeno 1" -#: utils/adt/varbit.c:63 utils/adt/varchar.c:55 +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 #, c-format msgid "length for type %s cannot exceed %d" msgstr "la lunghezza per il tipo %s non può essere superiore a %d" -#: utils/adt/varbit.c:164 utils/adt/varbit.c:476 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "la lunghezza della stringa di bit supera il massimo consentito (%d)" -#: utils/adt/varbit.c:178 utils/adt/varbit.c:321 utils/adt/varbit.c:378 +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "la lunghezza della stringa di bit %d non corrisponde a quella del tipo bit(%d)" -#: utils/adt/varbit.c:200 utils/adt/varbit.c:512 +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "\"%c\" non è una cifra binaria valida" -#: utils/adt/varbit.c:225 utils/adt/varbit.c:537 +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "\"%c\" non è una cifra esadecimale valida" -#: utils/adt/varbit.c:312 utils/adt/varbit.c:628 +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 #, c-format msgid "invalid length in external bit string" msgstr "la lunghezza della stringa esterna di bit non è valida" -#: utils/adt/varbit.c:490 utils/adt/varbit.c:637 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "la stringa di bit è troppo lunga per il tipo bit varying(%d)" -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:841 -#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2868 -#: utils/adt/varlena.c:2935 +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 +#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 +#: utils/adt/varlena.c:2979 #, c-format msgid "negative substring length not allowed" msgstr "non è consentita una stringa con lunghezza negativa" @@ -21634,7 +22538,7 @@ msgstr "non è possibile eseguire lo XOR fra stringhe di bit di dimensioni diver msgid "bit index %d out of valid range (0..%d)" msgstr "l'indice %d è fuori dall'intervallo valido (0..%d)" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3127 +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 #, c-format msgid "new bit must be 0 or 1" msgstr "il nuovo bit deve essere 0 o 1" @@ -21649,7 +22553,7 @@ msgstr "il valore è troppo lungo per il tipo character(%d)" msgid "value too long for type character varying(%d)" msgstr "il valore è troppo lungo per il tipo character varying(%d)" -#: utils/adt/varlena.c:1416 utils/adt/varlena.c:1861 +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "non è stato possibile determinare quale ordinamento usare per la comparazione tra stringhe" @@ -21664,63 +22568,63 @@ msgstr "conversione della stringa in UTF-16 fallita: codice errore %lu" msgid "could not compare Unicode strings: %m" msgstr "comparazione delle stringhe Unicode fallita: %m" -#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2141 +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 #, c-format msgid "collation failed: %s" msgstr "ordinamento fallito: %s" -#: utils/adt/varlena.c:2356 +#: utils/adt/varlena.c:2394 #, c-format msgid "sort key generation failed: %s" msgstr "generazione della chiave di ordinamento fallita: %s" -#: utils/adt/varlena.c:3013 utils/adt/varlena.c:3044 utils/adt/varlena.c:3079 -#: utils/adt/varlena.c:3115 +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 +#: utils/adt/varlena.c:3158 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "l'indice %d è fuori dall'intervallo valido, 0..%d" -#: utils/adt/varlena.c:4044 +#: utils/adt/varlena.c:4201 #, c-format msgid "field position must be greater than zero" msgstr "il campo deve essere maggiore di zero" -#: utils/adt/varlena.c:4934 +#: utils/adt/varlena.c:5080 #, c-format msgid "unterminated format() type specifier" msgstr "specifica di tipo per format() non terminata" -#: utils/adt/varlena.c:4935 utils/adt/varlena.c:5069 utils/adt/varlena.c:5190 +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Per un singolo \"%%\" usa \"%%%%\"." -#: utils/adt/varlena.c:5067 utils/adt/varlena.c:5188 +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 #, c-format msgid "unrecognized format() type specifier \"%c\"" msgstr "specifica di tipo per format() \"%c\" non riconosciuta" -#: utils/adt/varlena.c:5080 utils/adt/varlena.c:5137 +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 #, c-format msgid "too few arguments for format()" msgstr "numero di argomenti non sufficiente per format()" -#: utils/adt/varlena.c:5232 utils/adt/varlena.c:5415 +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 #, c-format msgid "number is out of range" msgstr "il numero è al di fuori dell'intervallo consentito" -#: utils/adt/varlena.c:5296 utils/adt/varlena.c:5324 +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "il formato specifica l'argomento 0, ma gli argomenti sono numerati a partire da 1" -#: utils/adt/varlena.c:5317 +#: utils/adt/varlena.c:5463 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "la posizione dell'argomento di larghezza deve finire con \"$\"" -#: utils/adt/varlena.c:5362 +#: utils/adt/varlena.c:5508 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "i valori vuoti non possono essere formattati come un identificativo SQL" @@ -21750,7 +22654,7 @@ msgstr "Per questa funzionalità è necessario che il server sia compilato con i msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "Occorre configurare PostgreSQL con l'opzione --with-libxml e ricompilarlo." -#: utils/adt/xml.c:241 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:241 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "nome di codifica non valido \"%s\"" @@ -21849,133 +22753,133 @@ msgstr "XML non supporta i valori infiniti per il tipo timestamp." msgid "invalid query" msgstr "query non valida" -#: utils/adt/xml.c:3870 +#: utils/adt/xml.c:3874 #, c-format msgid "invalid array for XML namespace mapping" msgstr "l'array per il mapping del namespace XML non è valido" -#: utils/adt/xml.c:3871 +#: utils/adt/xml.c:3875 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "L'array deve avere due dimensioni e la lunghezza del secondo asse deve essere pari a 2." -#: utils/adt/xml.c:3895 +#: utils/adt/xml.c:3899 #, c-format msgid "empty XPath expression" msgstr "l'espressione XPath è vuota" -#: utils/adt/xml.c:3939 +#: utils/adt/xml.c:3951 #, c-format msgid "neither namespace name nor URI may be null" msgstr "né il nome del namespace né l'URI possono essere nulli" -#: utils/adt/xml.c:3946 +#: utils/adt/xml.c:3958 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "registrazione del namespace XML con nome \"%s\" ed URI \"%s\" fallita" -#: utils/adt/xml.c:4300 +#: utils/adt/xml.c:4309 #, c-format msgid "DEFAULT namespace is not supported" msgstr "il namespace DEFAULT non è supportato" -#: utils/adt/xml.c:4329 +#: utils/adt/xml.c:4338 #, c-format msgid "row path filter must not be empty string" msgstr "il percorso del filtro di riga non può essere vuoto" -#: utils/adt/xml.c:4360 +#: utils/adt/xml.c:4369 #, c-format msgid "column path filter must not be empty string" msgstr "il percorso del filtro di colonna non può essere vuoto" -#: utils/adt/xml.c:4542 +#: utils/adt/xml.c:4555 #, c-format msgid "more than one value returned by column XPath expression" msgstr "l'espressione XPath ha restituito più di un valore" -#: utils/cache/lsyscache.c:2612 utils/cache/lsyscache.c:2645 -#: utils/cache/lsyscache.c:2678 utils/cache/lsyscache.c:2711 +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "il tipo %s non è completamente definito" -#: utils/cache/lsyscache.c:2617 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "nessuna funzione di input disponibile per il tipo %s" -#: utils/cache/lsyscache.c:2650 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "nessuna funzione di output disponibile per il tipo %s" -#: utils/cache/plancache.c:722 +#: utils/cache/partcache.c:202 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "alla classe di operatori \"%s\" del metodi di accesso %s manca la funzione di supporto %d per il tipo %s" + +#: utils/cache/plancache.c:723 #, c-format msgid "cached plan must not change result type" msgstr "il cached plan non deve cambiare il tipo del risultato" -#: utils/cache/relcache.c:5791 +#: utils/cache/relcache.c:5824 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "creazione del file di inizializzazione della cache delle relazioni \"%s\" fallita: %m" -#: utils/cache/relcache.c:5793 +#: utils/cache/relcache.c:5826 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Proseguo in ogni caso, ma c'è qualcosa che non funziona." -#: utils/cache/relcache.c:6063 +#: utils/cache/relcache.c:6180 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "rimozione del file di cache \"%s\" fallita: %m" -#: utils/cache/relmapper.c:509 +#: utils/cache/relmapper.c:513 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "non è possibile eseguire PREPARE in una transazione che ha modificato la mappa delle relazioni" -#: utils/cache/relmapper.c:652 utils/cache/relmapper.c:754 +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 #, c-format msgid "could not open relation mapping file \"%s\": %m" msgstr "apertura del file della mappa delle relazioni \"%s\" fallita: %m" -#: utils/cache/relmapper.c:666 +#: utils/cache/relmapper.c:669 #, c-format msgid "could not read relation mapping file \"%s\": %m" msgstr "lettura del file della mappa delle relazioni \"%s\" fallita: %m" -#: utils/cache/relmapper.c:677 +#: utils/cache/relmapper.c:680 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "il file della mappa delle relazioni \"%s\" contiene dati non validi" -#: utils/cache/relmapper.c:687 +#: utils/cache/relmapper.c:690 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "il file della mappa delle relazioni \"%s\" ha un checksum non valido" -#: utils/cache/relmapper.c:788 +#: utils/cache/relmapper.c:789 #, c-format msgid "could not write to relation mapping file \"%s\": %m" msgstr "scrittura nel file della mappa delle relazioni \"%s\" fallita: %m" -#: utils/cache/relmapper.c:803 +#: utils/cache/relmapper.c:804 #, c-format msgid "could not fsync relation mapping file \"%s\": %m" msgstr "fsync del file della mappa delle relazioni \"%s\" fallito: %m" -#: utils/cache/relmapper.c:810 +#: utils/cache/relmapper.c:811 #, c-format msgid "could not close relation mapping file \"%s\": %m" msgstr "chiusura del file della mappa delle relazioni \"%s\" fallita: %m" -#: utils/cache/typcache.c:1223 -#, c-format -msgid "type %s is not composite" -msgstr "il tipo %s non è composito" - -#: utils/cache/typcache.c:1237 +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 #, c-format msgid "record type has not been registered" msgstr "il tipo del record non è stato registrato" @@ -22005,86 +22909,86 @@ msgstr "riapertura del file \"%s\" come stderr fallita: %m" msgid "could not reopen file \"%s\" as stdout: %m" msgstr "riapertura del file \"%s\" come stdout fallita: %m" -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 +#: utils/error/elog.c:2394 utils/error/elog.c:2411 utils/error/elog.c:2427 msgid "[unknown]" msgstr "[sconosciuto]" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 +#: utils/error/elog.c:2887 utils/error/elog.c:3190 utils/error/elog.c:3298 msgid "missing error text" msgstr "testo dell'errore mancante" -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 -#: utils/error/elog.c:3299 +#: utils/error/elog.c:2890 utils/error/elog.c:2893 utils/error/elog.c:3301 +#: utils/error/elog.c:3304 #, c-format msgid " at character %d" msgstr " al carattere %d" -#: utils/error/elog.c:2898 utils/error/elog.c:2905 +#: utils/error/elog.c:2903 utils/error/elog.c:2910 msgid "DETAIL: " msgstr "DETTAGLI: " -#: utils/error/elog.c:2912 +#: utils/error/elog.c:2917 msgid "HINT: " msgstr "SUGGERIMENTO: " -#: utils/error/elog.c:2919 +#: utils/error/elog.c:2924 msgid "QUERY: " msgstr "QUERY: " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2931 msgid "CONTEXT: " msgstr "CONTESTO: " -#: utils/error/elog.c:2936 +#: utils/error/elog.c:2941 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "POSIZIONE: %s, %s:%d\n" -#: utils/error/elog.c:2943 +#: utils/error/elog.c:2948 #, c-format msgid "LOCATION: %s:%d\n" msgstr "POSIZIONE: %s:%d\n" -#: utils/error/elog.c:2957 +#: utils/error/elog.c:2962 msgid "STATEMENT: " msgstr "ISTRUZIONE: " #. translator: This string will be truncated at 47 #. characters expanded. -#: utils/error/elog.c:3414 +#: utils/error/elog.c:3419 #, c-format msgid "operating system error %d" msgstr "errore del sistema operativo %d" -#: utils/error/elog.c:3612 +#: utils/error/elog.c:3617 msgid "DEBUG" msgstr "DEBUG" -#: utils/error/elog.c:3616 +#: utils/error/elog.c:3621 msgid "LOG" msgstr "LOG" -#: utils/error/elog.c:3619 +#: utils/error/elog.c:3624 msgid "INFO" msgstr "INFO" -#: utils/error/elog.c:3622 +#: utils/error/elog.c:3627 msgid "NOTICE" msgstr "NOTIFICA" -#: utils/error/elog.c:3625 +#: utils/error/elog.c:3630 msgid "WARNING" msgstr "ATTENZIONE" -#: utils/error/elog.c:3628 +#: utils/error/elog.c:3633 msgid "ERROR" msgstr "ERRORE" -#: utils/error/elog.c:3631 +#: utils/error/elog.c:3636 msgid "FATAL" msgstr "FATALE" -#: utils/error/elog.c:3634 +#: utils/error/elog.c:3639 msgid "PANIC" msgstr "PANICO" @@ -22093,11 +22997,6 @@ msgstr "PANICO" msgid "could not find function \"%s\" in file \"%s\"" msgstr "funzione \"%s\" non trovata nel file \"%s\"" -#: utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 utils/fmgr/dfmgr.c:466 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "accesso al file \"%s\" fallito: %m" - #: utils/fmgr/dfmgr.c:239 #, c-format msgid "could not load library \"%s\": %s" @@ -22177,341 +23076,376 @@ msgstr "componente di lunghezza zero nel parametro \"dynamic_library_path\"" msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "il componente nel parametro \"dynamic_library_path\" non è un percorso assoluto." -#: utils/fmgr/fmgr.c:239 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "la funzione interna \"%s\" non è nella tabella interna di lookup" -#: utils/fmgr/fmgr.c:399 +#: utils/fmgr/fmgr.c:485 #, c-format msgid "could not find function information for function \"%s\"" msgstr "informazioni sulla funzione \"%s\" non trovate" -#: utils/fmgr/fmgr.c:401 +#: utils/fmgr/fmgr.c:487 #, c-format msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." msgstr "Le funzioni richiamabili da SQL devono avere un PG_FUNCTION_INFO_V1(nome) corrispondente." -#: utils/fmgr/fmgr.c:419 +#: utils/fmgr/fmgr.c:505 #, c-format msgid "unrecognized API version %d reported by info function \"%s\"" msgstr "versione API sconosciuto %d riportata dalla funzione info \"%s\"" -#: utils/fmgr/fmgr.c:2132 +#: utils/fmgr/fmgr.c:2210 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "funzione di validazione del linguaggio %u chiamata per il linguaggio %u invece di %u" -#: utils/fmgr/funcapi.c:354 +#: utils/fmgr/funcapi.c:358 #, c-format msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "non è stato possibile determinare il tipo reale di risultato della funzione \"%s\" dichiarata con tipo restituito %s" -#: utils/fmgr/funcapi.c:1341 utils/fmgr/funcapi.c:1372 +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 #, c-format msgid "number of aliases does not match number of columns" msgstr "il numero di alias non corrisponde al numero delle colonne" -#: utils/fmgr/funcapi.c:1366 +#: utils/fmgr/funcapi.c:1429 #, c-format msgid "no column alias was provided" msgstr "non è stato fornito nessun alias colonna" -#: utils/fmgr/funcapi.c:1390 +#: utils/fmgr/funcapi.c:1453 #, c-format msgid "could not determine row description for function returning record" msgstr "non è stato possibile determinare la descrizione della riga per la funzione che restituisce record" -#: utils/init/miscinit.c:122 +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "la directory dei dati \"%s\" non esiste" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "lettura dei permessi della directory \"%s\" fallita: %m" + +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "la directory dei dati specificata \"%s\" non è una directory" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "la directory dei dati \"%s\" ha il proprietario errato" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Il server deve essere avviato dall'utente che possiede la directory dei dati." + +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "la directory di dati \"%s\" ha permessi non validi" + +#: utils/init/miscinit.c:159 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "I permessi dovrebbero essere u=rwx (0700) o u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:218 #, c-format msgid "could not change directory to \"%s\": %m" msgstr "spostamento nella directory \"%s\" fallito: %m" -#: utils/init/miscinit.c:450 utils/misc/guc.c:6115 +#: utils/init/miscinit.c:554 utils/misc/guc.c:6361 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "non è possibile impostare il parametro \"%s\" nell'ambito di operazioni a sicurezza ristretta" -#: utils/init/miscinit.c:511 +#: utils/init/miscinit.c:615 #, c-format msgid "role with OID %u does not exist" msgstr "il ruolo con OID %u non esiste" -#: utils/init/miscinit.c:541 +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "al ruolo \"%s\" non è consentito effettuare il login" -#: utils/init/miscinit.c:559 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "troppe connessioni per il ruolo \"%s\"" -#: utils/init/miscinit.c:619 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "permesso di impostare l'autorizzazione della sessione negato" -#: utils/init/miscinit.c:702 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "OID del ruolo non valido: %u" -#: utils/init/miscinit.c:756 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "il database è stato arrestato" -#: utils/init/miscinit.c:843 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "creazione del file di lock \"%s\" fallita: %m" -#: utils/init/miscinit.c:857 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "apertura del file di lock \"%s\" fallita: %m" -#: utils/init/miscinit.c:864 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "lettura dal file di lock \"%s\" fallita: %m" -#: utils/init/miscinit.c:873 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "il file di lock \"%s\" è vuoto" -#: utils/init/miscinit.c:874 +#: utils/init/miscinit.c:978 #, c-format msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." msgstr "O c'è un altro server in avvio, oppure il file di lock è rimasto da un precedente crash in avvio del server." -#: utils/init/miscinit.c:921 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "il file di lock \"%s\" esiste già" -#: utils/init/miscinit.c:925 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "C'è un altro postgres (PID %d) in esecuzione nella directory dei dati \"%s\"?" -#: utils/init/miscinit.c:927 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "C'è un altro postmaster (PID %d) in esecuzione nella directory dei dati \"%s\"?" -#: utils/init/miscinit.c:930 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "C'è un altro postgres (PID %d) che sta usando il file socket \"%s\"?" -#: utils/init/miscinit.c:932 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "C'è un altro postmaster (PID %d) che sta usando il file socket \"%s\"?" -#: utils/init/miscinit.c:968 +#: utils/init/miscinit.c:1069 #, c-format msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" msgstr "il blocco di memoria condivisa preesistente (key %lu, ID %lu) è ancora in uso" -#: utils/init/miscinit.c:971 +#: utils/init/miscinit.c:1072 #, c-format msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." msgstr "Se sei sicuro che non ci siano vecchi processi server ancora in esecuzione, rimuovi il blocco di memoria condivisa, o semplicemente cancella il file \"%s\"." -#: utils/init/miscinit.c:987 +#: utils/init/miscinit.c:1088 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "rimozione del vecchio file di lock \"%s\" fallita: %m" -#: utils/init/miscinit.c:989 +#: utils/init/miscinit.c:1090 #, c-format msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "Sembra che il file sia stato abbandonato accidentalmente, ma non può essere rimosso. Per favore rimuovilo manualmente e riprova." -#: utils/init/miscinit.c:1026 utils/init/miscinit.c:1040 -#: utils/init/miscinit.c:1051 +#: utils/init/miscinit.c:1127 utils/init/miscinit.c:1141 +#: utils/init/miscinit.c:1152 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "scrittura del file di lock \"%s\" fallita: %m" -#: utils/init/miscinit.c:1182 utils/init/miscinit.c:1318 utils/misc/guc.c:8920 +#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1427 utils/misc/guc.c:9202 #, c-format msgid "could not read from file \"%s\": %m" msgstr "lettura dal file \"%s\" fallita: %m" -#: utils/init/miscinit.c:1306 +#: utils/init/miscinit.c:1415 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "apertura del file \"%s\" fallita: %m; si procederà comunque" -#: utils/init/miscinit.c:1331 +#: utils/init/miscinit.c:1440 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "il file di lock \"%s\" contiene il PID sbagliato: %ld invece di %ld" -#: utils/init/miscinit.c:1370 utils/init/miscinit.c:1386 +#: utils/init/miscinit.c:1479 utils/init/miscinit.c:1495 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "\"%s\" non è una directory di dati valida" -#: utils/init/miscinit.c:1372 +#: utils/init/miscinit.c:1481 #, c-format msgid "File \"%s\" is missing." msgstr "Il file \"%s\" è mancante." -#: utils/init/miscinit.c:1388 +#: utils/init/miscinit.c:1497 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "Il file \"%s\" non contiene dati validi." -#: utils/init/miscinit.c:1390 +#: utils/init/miscinit.c:1499 #, c-format msgid "You might need to initdb." msgstr "Potrebbe essere necessario eseguire initdb." -#: utils/init/miscinit.c:1398 +#: utils/init/miscinit.c:1507 #, c-format msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." msgstr "La directory dei dati è stata inizializzata da PostgreSQL versione %s, che non è compatibile con questa versione %s." -#: utils/init/miscinit.c:1469 +#: utils/init/miscinit.c:1574 #, c-format msgid "loaded library \"%s\"" msgstr "libreria \"%s\" caricata" -#: utils/init/postinit.c:251 +#: utils/init/postinit.c:252 #, c-format -msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "connessione di replica autorizzata: utente=%s SSL abilitato (protocollo=%s, cifrario=%s, compressione=%s)" +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "connessione di replica autorizzata: utente=%s SSL abilitato (protocollo=%s, cifrario=%s, bit=%d, compressione=%s)" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "off" msgstr "disattivato" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "on" msgstr "attivato" -#: utils/init/postinit.c:257 +#: utils/init/postinit.c:261 #, c-format msgid "replication connection authorized: user=%s" msgstr "connessione di replica autorizzata: utente=%s" -#: utils/init/postinit.c:265 +#: utils/init/postinit.c:269 #, c-format -msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)" -msgstr "connessione autorizzata: utente=%s database=%s SSL abilitato (protocollo=%s, cifrario=%s, compressione=%s)" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "connessione autorizzata: utente=%s database=%s SSL abilitato (protocollo=%s, cifrario=%s, bit=%d, compressione=%s)" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:278 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "connessione autorizzata: utente=%s database=%s" -#: utils/init/postinit.c:303 +#: utils/init/postinit.c:310 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "il database \"%s\" è scomparso da database pg_database" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:312 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "L'OID %u del database ora sembra appartenere a \"%s\"." -#: utils/init/postinit.c:325 +#: utils/init/postinit.c:332 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "il database \"%s\" attualmente non accetta connessioni" -#: utils/init/postinit.c:338 +#: utils/init/postinit.c:345 #, c-format msgid "permission denied for database \"%s\"" msgstr "permesso negato per il database \"%s\"" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:346 #, c-format msgid "User does not have CONNECT privilege." msgstr "L'utente non ha il privilegio CONNECT." -#: utils/init/postinit.c:356 +#: utils/init/postinit.c:363 #, c-format msgid "too many connections for database \"%s\"" msgstr "troppe connessioni al database \"%s\"" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format msgid "database locale is incompatible with operating system" msgstr "il locale del database è incompatibile col sistema operativo" -#: utils/init/postinit.c:379 +#: utils/init/postinit.c:386 #, c-format msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." msgstr "Il database di database è stato inizializzato con LC_COLLATE \"%s\", che non è riconosciuto da setlocale()." -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "Crea di nuovo il database con un altro locale oppure installa il locale mancante." -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:393 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "Il database è stato inizializzato con LC_CTYPE \"%s\", che non è riconosciuto da setlocale()." -#: utils/init/postinit.c:719 +#: utils/init/postinit.c:726 #, c-format msgid "no roles are defined in this database system" msgstr "nessun ruolo definito in questo database" -#: utils/init/postinit.c:720 +#: utils/init/postinit.c:727 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Dovresti eseguire immediatamente CREATE USER \"%s\" SUPERUSER;." -#: utils/init/postinit.c:756 +#: utils/init/postinit.c:763 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "non sono accettate nuove connessioni di replica durante lo spegnimento del database" -#: utils/init/postinit.c:760 +#: utils/init/postinit.c:767 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "solo un superutente può connettersi durante lo spegnimento del database" -#: utils/init/postinit.c:770 +#: utils/init/postinit.c:777 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "solo un superutente può connettersi in modalità di aggiornamento binario" -#: utils/init/postinit.c:784 +#: utils/init/postinit.c:791 #, c-format msgid "remaining connection slots are reserved for non-replication superuser connections" msgstr "i rimanenti slot di connessione sono riservati a connessioni di superutenti non di replica" -#: utils/init/postinit.c:794 +#: utils/init/postinit.c:801 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "solo un superutente o il ruolo di replica può avviare walsender" -#: utils/init/postinit.c:863 +#: utils/init/postinit.c:870 #, c-format msgid "database %u does not exist" msgstr "il database %u non esiste" -#: utils/init/postinit.c:952 +#: utils/init/postinit.c:959 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Sembra sia stato appena eliminato o rinominato." -#: utils/init/postinit.c:970 +#: utils/init/postinit.c:977 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "La sottodirectory del database \"%s\" risulta mancante." -#: utils/init/postinit.c:975 +#: utils/init/postinit.c:982 #, c-format msgid "could not access directory \"%s\": %m" msgstr "accesso alla directory \"%s\" fallito: %m" @@ -22533,42 +23467,47 @@ msgstr "ID di codifica %d non previsto per il set di caratteri ISO 8859" msgid "unexpected encoding ID %d for WIN character sets" msgstr "ID di codifica %d non previsto per il set di caratteri WIN" +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "codifica \"%s\" non supportata da ICU" + #: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "il nome della codifica è troppo lungo" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "la conversione fra %s e %s non è supportata" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "la funzione di conversione predefinita da \"%s\" a \"%s\" non esiste" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "La stringa di %d byte è troppo lunga per una conversione di codifica." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "il nome della codifica di origine \"%s\" non è valido" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "il nome della codifica di destinazione \"%s\" non è valido" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "byte non valido per la codifica \"%s\": 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "bind_textdomain_codeset fallito" @@ -22583,1558 +23522,1666 @@ msgstr "sequenza di byte non valida per la codifica \"%s\": %s" msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" msgstr "il carattere con sequenza di byte %s nella codifica \"%s\" non ha un equivalente nella codifica \"%s\"" -#: utils/misc/guc.c:570 +#: utils/misc/guc.c:571 msgid "Ungrouped" msgstr "Varie" -#: utils/misc/guc.c:572 +#: utils/misc/guc.c:573 msgid "File Locations" msgstr "Posizione dei File" -#: utils/misc/guc.c:574 +#: utils/misc/guc.c:575 msgid "Connections and Authentication" msgstr "Connessioni ed Autenticazione" -#: utils/misc/guc.c:576 +#: utils/misc/guc.c:577 msgid "Connections and Authentication / Connection Settings" msgstr "Connessioni ed Autenticazione / Impostazioni di Connessione" -#: utils/misc/guc.c:578 -msgid "Connections and Authentication / Security and Authentication" -msgstr "Connessioni ed Autenticazione / Sicurezza ed Autenticazione" +#: utils/misc/guc.c:579 +msgid "Connections and Authentication / Authentication" +msgstr "Connessioni ed Autenticazione / Autenticazione" -#: utils/misc/guc.c:580 +#: utils/misc/guc.c:581 +msgid "Connections and Authentication / SSL" +msgstr "Connessioni ed Autenticazione / SSL" + +#: utils/misc/guc.c:583 msgid "Resource Usage" msgstr "Uso delle Risorse" -#: utils/misc/guc.c:582 +#: utils/misc/guc.c:585 msgid "Resource Usage / Memory" msgstr "Uso delle Risorse / Memoria" -#: utils/misc/guc.c:584 +#: utils/misc/guc.c:587 msgid "Resource Usage / Disk" msgstr "Uso delle Risorse / Disco" -#: utils/misc/guc.c:586 +#: utils/misc/guc.c:589 msgid "Resource Usage / Kernel Resources" msgstr "Uso delle Risorse / Risorse del Kernel" -#: utils/misc/guc.c:588 +#: utils/misc/guc.c:591 msgid "Resource Usage / Cost-Based Vacuum Delay" msgstr "Uso delle Risorse / Intervallo di Vacuum Basato sul Costo" -#: utils/misc/guc.c:590 +#: utils/misc/guc.c:593 msgid "Resource Usage / Background Writer" msgstr "Uso delle Risorse / Scrittura in Background" -#: utils/misc/guc.c:592 +#: utils/misc/guc.c:595 msgid "Resource Usage / Asynchronous Behavior" msgstr "Uso delle Risorse / Comportamento Asincrono" -#: utils/misc/guc.c:594 +#: utils/misc/guc.c:597 msgid "Write-Ahead Log" msgstr "Write-Ahead Log" -#: utils/misc/guc.c:596 +#: utils/misc/guc.c:599 msgid "Write-Ahead Log / Settings" msgstr "Write-Ahead Log / Impostazioni" -#: utils/misc/guc.c:598 +#: utils/misc/guc.c:601 msgid "Write-Ahead Log / Checkpoints" msgstr "Write-Ahead Log / Checkpoint" -#: utils/misc/guc.c:600 +#: utils/misc/guc.c:603 msgid "Write-Ahead Log / Archiving" msgstr "Write-Ahead Log / Archiviazione" -#: utils/misc/guc.c:602 +#: utils/misc/guc.c:605 msgid "Replication" msgstr "Replica" -#: utils/misc/guc.c:604 +#: utils/misc/guc.c:607 msgid "Replication / Sending Servers" msgstr "Replica / Server di Invio" -#: utils/misc/guc.c:606 +#: utils/misc/guc.c:609 msgid "Replication / Master Server" msgstr "Replica / Server Master" -#: utils/misc/guc.c:608 +#: utils/misc/guc.c:611 msgid "Replication / Standby Servers" msgstr "Replica / Serve in Standby" -#: utils/misc/guc.c:610 +#: utils/misc/guc.c:613 msgid "Replication / Subscribers" msgstr "Replica / Sottoscrizioni" -#: utils/misc/guc.c:612 +#: utils/misc/guc.c:615 msgid "Query Tuning" msgstr "Tuning delle Query" -#: utils/misc/guc.c:614 +#: utils/misc/guc.c:617 msgid "Query Tuning / Planner Method Configuration" msgstr "Tuning delle Query / Configurazione dei Metodi del Planner" -#: utils/misc/guc.c:616 +#: utils/misc/guc.c:619 msgid "Query Tuning / Planner Cost Constants" msgstr "Tuning delle Query / Costanti di Costo del Planner" -#: utils/misc/guc.c:618 +#: utils/misc/guc.c:621 msgid "Query Tuning / Genetic Query Optimizer" msgstr "Tuning delle Query / Ottimizzatore Genetico delle Query" -#: utils/misc/guc.c:620 +#: utils/misc/guc.c:623 msgid "Query Tuning / Other Planner Options" msgstr "Tuning delle Query / Altre Opzioni del Planner" -#: utils/misc/guc.c:622 +#: utils/misc/guc.c:625 msgid "Reporting and Logging" msgstr "Report e Log" -#: utils/misc/guc.c:624 +#: utils/misc/guc.c:627 msgid "Reporting and Logging / Where to Log" msgstr "Report e Log / Dove inviare i Log" -#: utils/misc/guc.c:626 +#: utils/misc/guc.c:629 msgid "Reporting and Logging / When to Log" msgstr "Report e Log / Quando inviare i Log" -#: utils/misc/guc.c:628 +#: utils/misc/guc.c:631 msgid "Reporting and Logging / What to Log" msgstr "Report e Log / Cosa indicare nei Log" -#: utils/misc/guc.c:630 +#: utils/misc/guc.c:633 msgid "Process Title" msgstr "Titolo del Processo" -#: utils/misc/guc.c:632 +#: utils/misc/guc.c:635 msgid "Statistics" msgstr "Statistiche" -#: utils/misc/guc.c:634 +#: utils/misc/guc.c:637 msgid "Statistics / Monitoring" msgstr "Statistiche / Monitoring" -#: utils/misc/guc.c:636 +#: utils/misc/guc.c:639 msgid "Statistics / Query and Index Statistics Collector" msgstr "Statistiche / Raccolta delle Statistiche su Query e Indici" -#: utils/misc/guc.c:638 +#: utils/misc/guc.c:641 msgid "Autovacuum" msgstr "Autovacuum" -#: utils/misc/guc.c:640 +#: utils/misc/guc.c:643 msgid "Client Connection Defaults" msgstr "Valori Predefiniti Connessioni Client" -#: utils/misc/guc.c:642 +#: utils/misc/guc.c:645 msgid "Client Connection Defaults / Statement Behavior" msgstr "Valori Predefiniti Connessioni Client / Comportamento Istruzioni" -#: utils/misc/guc.c:644 +#: utils/misc/guc.c:647 msgid "Client Connection Defaults / Locale and Formatting" msgstr "Valori Predefiniti Connessioni Client / Locale e Formattazione" -#: utils/misc/guc.c:646 +#: utils/misc/guc.c:649 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "Valori Predefiniti Connessioni Client / Precaricamento Librerie Condivise" -#: utils/misc/guc.c:648 +#: utils/misc/guc.c:651 msgid "Client Connection Defaults / Other Defaults" msgstr "Valori Predefiniti Connessioni Client / Altri Default" -#: utils/misc/guc.c:650 +#: utils/misc/guc.c:653 msgid "Lock Management" msgstr "Gestione dei Lock" -#: utils/misc/guc.c:652 +#: utils/misc/guc.c:655 msgid "Version and Platform Compatibility" msgstr "Versione e Compatibilità della Piattaforma" -#: utils/misc/guc.c:654 +#: utils/misc/guc.c:657 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "Versione e Compatibilità della Piattaforma / Versioni Precedenti di PostgreSQL" -#: utils/misc/guc.c:656 +#: utils/misc/guc.c:659 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "Versione e Compatibilità della Piattaforma / Altre Piattaforme e Client" -#: utils/misc/guc.c:658 +#: utils/misc/guc.c:661 msgid "Error Handling" msgstr "Gestione degli Errori" -#: utils/misc/guc.c:660 +#: utils/misc/guc.c:663 msgid "Preset Options" msgstr "Opzioni Preimpostate" -#: utils/misc/guc.c:662 +#: utils/misc/guc.c:665 msgid "Customized Options" msgstr "Opzioni Personalizzate" -#: utils/misc/guc.c:664 +#: utils/misc/guc.c:667 msgid "Developer Options" msgstr "Opzioni di Sviluppo" #: utils/misc/guc.c:721 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "Le unità di misura valide sono \"kB\", \"MB\", \"GB\", and \"TB\"." +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Le unità di misura valide per questo parametro sono \"B\", \"kB\", \"MB\", \"GB\" e \"TB\"." -#: utils/misc/guc.c:748 +#: utils/misc/guc.c:763 msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." msgstr "Le unità di misura valide sono \"ms\", \"s\", \"min\", \"h\" e \"d\"." -#: utils/misc/guc.c:807 +#: utils/misc/guc.c:822 msgid "Enables the planner's use of sequential-scan plans." msgstr "Abilita l'uso da parte del planner dei piani di scansione sequenziale." -#: utils/misc/guc.c:816 +#: utils/misc/guc.c:831 msgid "Enables the planner's use of index-scan plans." msgstr "Abilita l'uso da parte del planner dei piani di scansione degli indici." -#: utils/misc/guc.c:825 +#: utils/misc/guc.c:840 msgid "Enables the planner's use of index-only-scan plans." msgstr "Abilita l'uso da parte del planner dei piani di scansione dei soli indici." -#: utils/misc/guc.c:834 +#: utils/misc/guc.c:849 msgid "Enables the planner's use of bitmap-scan plans." msgstr "Abilita l'uso da parte del planner dei piani di scansione bitmap." -#: utils/misc/guc.c:843 +#: utils/misc/guc.c:858 msgid "Enables the planner's use of TID scan plans." msgstr "Abilita l'uso da parte del planner dei piani di scansione TID." -#: utils/misc/guc.c:852 +#: utils/misc/guc.c:867 msgid "Enables the planner's use of explicit sort steps." msgstr "Abilita l'uso da parte del planner di passaggi di ordinamento esplicito." -#: utils/misc/guc.c:861 +#: utils/misc/guc.c:876 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Abilita l'uso da parte del planner di piani di aggregazione basati su hash." -#: utils/misc/guc.c:870 +#: utils/misc/guc.c:885 msgid "Enables the planner's use of materialization." msgstr "Abilita l'uso da parte del planner di materializzazione." -#: utils/misc/guc.c:879 +#: utils/misc/guc.c:894 msgid "Enables the planner's use of nested-loop join plans." msgstr "Abilita l'uso da parte del planner di piani di join annidati." -#: utils/misc/guc.c:888 +#: utils/misc/guc.c:903 msgid "Enables the planner's use of merge join plans." msgstr "Abilita l'uso da parte del planner di piani di join ad unione." -#: utils/misc/guc.c:897 +#: utils/misc/guc.c:912 msgid "Enables the planner's use of hash join plans." msgstr "Abilita l'uso da parte del planner di piani di join basati su hash." -#: utils/misc/guc.c:906 +#: utils/misc/guc.c:921 msgid "Enables the planner's use of gather merge plans." -msgstr "Abilita l'uso da parte del planner di pani gather merge." +msgstr "Abilita l'uso da parte del planner di piani gather merge." + +#: utils/misc/guc.c:930 +msgid "Enables partitionwise join." +msgstr "Abilita join partizione su partizione." + +#: utils/misc/guc.c:939 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Abilita aggregazione e raggruppamento partizione per partizione." + +#: utils/misc/guc.c:948 +msgid "Enables the planner's use of parallel append plans." +msgstr "Abilita l'uso da parte del planner di piani di append paralleli." -#: utils/misc/guc.c:916 +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Abilita l'uso da parte del planner di piani di hash paralleli." + +#: utils/misc/guc.c:966 +msgid "Enable plan-time and run-time partition pruning." +msgstr "Abilita eliminazione delle partizioni durante la pianificazione e l'esecuzione." + +#: utils/misc/guc.c:967 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "Permetti al planner e all'esecutore di comparare i margini delle partizioni alle condizioni nelle query per determinare quali partizioni devono essere esaminate." + +#: utils/misc/guc.c:977 msgid "Enables genetic query optimization." msgstr "Abilita l'ottimizzatore genetico di query." -#: utils/misc/guc.c:917 +#: utils/misc/guc.c:978 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Questo algoritmo cerca di realizzare piani senza effettuare una ricerca esaustiva." -#: utils/misc/guc.c:927 +#: utils/misc/guc.c:988 msgid "Shows whether the current user is a superuser." msgstr "Mostra se l'utente attuale è un superutente o meno." -#: utils/misc/guc.c:937 +#: utils/misc/guc.c:998 msgid "Enables advertising the server via Bonjour." msgstr "Abilita la pubblicazione del server via Bonjour." -#: utils/misc/guc.c:946 +#: utils/misc/guc.c:1007 msgid "Collects transaction commit time." msgstr "Raccogli l'ora di commit delle transazioni." -#: utils/misc/guc.c:955 +#: utils/misc/guc.c:1016 msgid "Enables SSL connections." msgstr "Abilita le connessioni SSL." -#: utils/misc/guc.c:964 +#: utils/misc/guc.c:1025 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Usa anche ssl_passphrase_command durante il riavvio del server." + +#: utils/misc/guc.c:1034 msgid "Give priority to server ciphersuite order." msgstr "Dai priorità all'ordine di cifrari del server." -#: utils/misc/guc.c:973 +#: utils/misc/guc.c:1043 msgid "Forces synchronization of updates to disk." msgstr "Forza la sincronizzazione degli aggiornamenti sul disco." -#: utils/misc/guc.c:974 +#: utils/misc/guc.c:1044 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." msgstr "Il server userà in diversi punti la chiamata di sistema fsync() per assicurarsi che gli aggiornamenti vengano scritti fisicamente sul disco. Questo assicura che un cluster di database possa essere recuperato in uno stato consistente dopo un crash di sistema o dell'hardware." -#: utils/misc/guc.c:985 +#: utils/misc/guc.c:1055 msgid "Continues processing after a checksum failure." msgstr "Condinua l'elaborazione dopo un errore in una somma di controllo." -#: utils/misc/guc.c:986 +#: utils/misc/guc.c:1056 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." msgstr "La rilevazione di un errore in una somma di controllo di solito fa generare a PostgreSQL un errore che fa abortire la transazione corrente. Impostare ignore_checksum_failure a \"true\" fa sì che il sistema ignori l'errore (che viene riportato come un avviso), consentendo al processo di continuare. Questo comportamento potrebbe causare crash o altri problemi gravi. Ha effetto solo se se somme di controllo sono abilitate." -#: utils/misc/guc.c:1000 +#: utils/misc/guc.c:1070 msgid "Continues processing past damaged page headers." msgstr "Continua l'esecuzione oltre le intestazioni di pagina danneggiate." -#: utils/misc/guc.c:1001 +#: utils/misc/guc.c:1071 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "Il rilevamento di una intestazione di pagina danneggiata normalmente fa sì che PostgreSQL segnali un errore, interrompendo la transazione corrente. L'attivazione di zero_damaged_pages fa sì che il sistema invece riporti un warning, azzeri la pagina danneggiata e continui l'esecuzione. Questo comportamento può distruggere dei dati, in particolare tutte quelle righe situate nella pagina danneggiata." -#: utils/misc/guc.c:1014 +#: utils/misc/guc.c:1084 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "Scrivi pagine intere nel WAL non appena modificate dopo un checkpoint." -#: utils/misc/guc.c:1015 +#: utils/misc/guc.c:1085 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." msgstr "La scrittura di una pagina durante un crash del sistema operativo potrebbe essere stata scritta su disco solo parzialmente. Durante il ripristino, le variazioni di riga memorizzate nel WAL non sono sufficienti al ripristino. Questa operazione scrive le pagine nel WAL appena modificate dopo un checkpoint nel WAL in maniera da rendere possibile un ripristino completo." -#: utils/misc/guc.c:1028 +#: utils/misc/guc.c:1098 msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." msgstr "Scrivi pagine complete nel WAL appena modificate dopo un checkpoint, anche dopo modifiche non critiche." -#: utils/misc/guc.c:1038 +#: utils/misc/guc.c:1108 msgid "Compresses full-page writes written in WAL file." msgstr "Comprimi le scritture di pagine complete scritte nel file WAL." -#: utils/misc/guc.c:1048 +#: utils/misc/guc.c:1118 msgid "Logs each checkpoint." msgstr "Registra nel log ogni checkpoint." -#: utils/misc/guc.c:1057 +#: utils/misc/guc.c:1127 msgid "Logs each successful connection." msgstr "Registra nel log tutte le connessioni avvenute con successo." -#: utils/misc/guc.c:1066 +#: utils/misc/guc.c:1136 msgid "Logs end of a session, including duration." msgstr "Registra nel log la fine delle sessioni, compresa la sua durata." -#: utils/misc/guc.c:1075 +#: utils/misc/guc.c:1145 msgid "Logs each replication command." msgstr "Registra nel log ogni comando di replica." -#: utils/misc/guc.c:1084 +#: utils/misc/guc.c:1154 msgid "Shows whether the running server has assertion checks enabled." msgstr "Mostra se il server in esecuzione ha i controlli di assert attivi." -#: utils/misc/guc.c:1099 +#: utils/misc/guc.c:1169 msgid "Terminate session on any error." msgstr "Termina la sessione su qualunque errore." -#: utils/misc/guc.c:1108 +#: utils/misc/guc.c:1178 msgid "Reinitialize server after backend crash." msgstr "Reinizializza il server dopo un crash del backend." -#: utils/misc/guc.c:1118 +#: utils/misc/guc.c:1188 msgid "Logs the duration of each completed SQL statement." msgstr "Registra nel log la durata di ogni istruzione SQL completata." -#: utils/misc/guc.c:1127 +#: utils/misc/guc.c:1197 msgid "Logs each query's parse tree." msgstr "Registra nel log l'albero di parsing di tutte le query." -#: utils/misc/guc.c:1136 +#: utils/misc/guc.c:1206 msgid "Logs each query's rewritten parse tree." msgstr "Registra nel log l'albero di parsing riscritto di tutte le query." -#: utils/misc/guc.c:1145 +#: utils/misc/guc.c:1215 msgid "Logs each query's execution plan." msgstr "Registra nel log il piano di esecuzione di tutte le query." -#: utils/misc/guc.c:1154 +#: utils/misc/guc.c:1224 msgid "Indents parse and plan tree displays." msgstr "Indenta gli alberi di parsing e dei piani di esecuzione." -#: utils/misc/guc.c:1163 +#: utils/misc/guc.c:1233 msgid "Writes parser performance statistics to the server log." msgstr "Registra nel log del server le statistiche sulle prestazioni del parser." -#: utils/misc/guc.c:1172 +#: utils/misc/guc.c:1242 msgid "Writes planner performance statistics to the server log." msgstr "Registra nel log del server le statistiche sulle prestazioni del planner." -#: utils/misc/guc.c:1181 +#: utils/misc/guc.c:1251 msgid "Writes executor performance statistics to the server log." msgstr "Registra nel log del server le statistiche sulle prestazioni dell'esecutore." -#: utils/misc/guc.c:1190 +#: utils/misc/guc.c:1260 msgid "Writes cumulative performance statistics to the server log." msgstr "Registra nel log del server le statistiche sulle prestazioni cumulative." -#: utils/misc/guc.c:1200 +#: utils/misc/guc.c:1270 msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "Registra nel log statistiche sull'uso di risorse di sistema (memoria e CPU) su varie operazioni B-tree." -#: utils/misc/guc.c:1212 +#: utils/misc/guc.c:1282 msgid "Collects information about executing commands." msgstr "Raccogli informazioni sull'esecuzione dei comandi." -#: utils/misc/guc.c:1213 +#: utils/misc/guc.c:1283 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "Abilita la raccolta di informazioni sui comandi in esecuzione per ogni sessione, insieme all'orario in cui l'esecuzione del comando è iniziata." -#: utils/misc/guc.c:1223 +#: utils/misc/guc.c:1293 msgid "Collects statistics on database activity." msgstr "Raccogli statistiche sull'attività del database." -#: utils/misc/guc.c:1232 +#: utils/misc/guc.c:1302 msgid "Collects timing statistics for database I/O activity." msgstr "Raccogli statistiche sull'attività di I/O del database." -#: utils/misc/guc.c:1242 +#: utils/misc/guc.c:1312 msgid "Updates the process title to show the active SQL command." msgstr "Aggiorna il titolo del processo per indicare il comando SQL in esecuzione." -#: utils/misc/guc.c:1243 +#: utils/misc/guc.c:1313 msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "Abilita l'aggiornamento del titolo del processo ogni volta che un nuovo comando SQL viene ricevuto dal server." -#: utils/misc/guc.c:1256 +#: utils/misc/guc.c:1326 msgid "Starts the autovacuum subprocess." msgstr "Avvia il sottoprocesso autovacuum." -#: utils/misc/guc.c:1266 +#: utils/misc/guc.c:1336 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Genera un output di debug per LISTEN e NOTIFY." -#: utils/misc/guc.c:1278 +#: utils/misc/guc.c:1348 msgid "Emits information about lock usage." msgstr "Emette informazioni sull'uso dei lock." -#: utils/misc/guc.c:1288 +#: utils/misc/guc.c:1358 msgid "Emits information about user lock usage." msgstr "Emette informazioni sull'uso dei lock utente." -#: utils/misc/guc.c:1298 +#: utils/misc/guc.c:1368 msgid "Emits information about lightweight lock usage." msgstr "Emette informazioni sull'uso dei lock leggeri." -#: utils/misc/guc.c:1308 +#: utils/misc/guc.c:1378 msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "Emette informazioni su tutti i lock attivi quando avviene un timeout di lock." -#: utils/misc/guc.c:1320 +#: utils/misc/guc.c:1390 msgid "Logs long lock waits." msgstr "Inserisci nel log le attese lunghe su lock." -#: utils/misc/guc.c:1330 +#: utils/misc/guc.c:1400 msgid "Logs the host name in the connection logs." msgstr "Inserisci nel log lo host name delle connessioni." -#: utils/misc/guc.c:1331 +#: utils/misc/guc.c:1401 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." msgstr "Normalmente, viene inserito nel log solo l'indirizzo IP dell'host connesso. Se vuoi mostrare anche il nome host puoi attivando questa parametro ma, a seconda di come è definito il sistema di risoluzione dei nomi, ciò potrebbe comportare una penalizzazione delle prestazioni non trascurabile." -#: utils/misc/guc.c:1342 +#: utils/misc/guc.c:1412 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Tratta l'espressione \"expr=NULL\" come \"expr IS NULL\"." -#: utils/misc/guc.c:1343 +#: utils/misc/guc.c:1413 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "Se abilitato, le espressioni nella forma expr = NULL (o NULL = expr) vengono trattate come expr IS NULL, in modo cioè che restituiscano TRUE se expr viene valutato con valore NULL e falso in ogni altro caso. Il comportamento corretto prevede che expr = NULL valga sempre NULL (sconosciuto)." -#: utils/misc/guc.c:1355 +#: utils/misc/guc.c:1425 msgid "Enables per-database user names." msgstr "Abilita nomi di utenti diversificati per ogni database." -#: utils/misc/guc.c:1364 +#: utils/misc/guc.c:1434 msgid "Sets the default read-only status of new transactions." msgstr "Imposta lo stato predefinito di sola lettura per le nuove transazioni." -#: utils/misc/guc.c:1373 +#: utils/misc/guc.c:1443 msgid "Sets the current transaction's read-only status." msgstr "Imposta lo stato di sola lettura per la transazione corrente." -#: utils/misc/guc.c:1383 +#: utils/misc/guc.c:1453 msgid "Sets the default deferrable status of new transactions." msgstr "Imposta lo stato predefinito deferibile per le nuove transazioni." -#: utils/misc/guc.c:1392 +#: utils/misc/guc.c:1462 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." msgstr "Indica se deferire una transazione serializzabile in sola lettura finché possa essere eseguita senza possibili fallimenti di serializzazione." -#: utils/misc/guc.c:1402 +#: utils/misc/guc.c:1472 msgid "Enable row security." msgstr "Abilita la sicurezza delle righe." -#: utils/misc/guc.c:1403 +#: utils/misc/guc.c:1473 msgid "When enabled, row security will be applied to all users." msgstr "Quando abilitata, la sicurezza delle righe verrà applicata a tutti gli utenti." -#: utils/misc/guc.c:1411 +#: utils/misc/guc.c:1481 msgid "Check function bodies during CREATE FUNCTION." msgstr "Esegui un controllo sulla definizione del corpo durante la CREATE FUNCTION." -#: utils/misc/guc.c:1420 +#: utils/misc/guc.c:1490 msgid "Enable input of NULL elements in arrays." msgstr "Abilita l'input di elementi NULL negli array." -#: utils/misc/guc.c:1421 +#: utils/misc/guc.c:1491 msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." msgstr "Se abilitato, un NULL senza apici come valore di input in un array indica un valore nullo; altrimenti è preso letteralmente." -#: utils/misc/guc.c:1431 +#: utils/misc/guc.c:1501 msgid "Create new tables with OIDs by default." msgstr "Crea le nuove tabella con gli OID in maniera predefinita." -#: utils/misc/guc.c:1440 +#: utils/misc/guc.c:1510 msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "Avvia un sottoprocesso per catturare in un file di log l'output di stderr e/o di csvlog." -#: utils/misc/guc.c:1449 +#: utils/misc/guc.c:1519 msgid "Truncate existing log files of same name during log rotation." msgstr "Tronca un file di log esistente con lo stesso nome durante la rotazione dei log." -#: utils/misc/guc.c:1460 +#: utils/misc/guc.c:1530 msgid "Emit information about resource usage in sorting." msgstr "Genera informazioni sull'uso delle risorse durante gli ordinamenti." -#: utils/misc/guc.c:1474 +#: utils/misc/guc.c:1544 msgid "Generate debugging output for synchronized scanning." msgstr "Genera output di debug per le scansioni sincronizzate." -#: utils/misc/guc.c:1489 +#: utils/misc/guc.c:1559 msgid "Enable bounded sorting using heap sort." msgstr "Abilita il bounded sorting usando lo heap sort." -#: utils/misc/guc.c:1502 +#: utils/misc/guc.c:1572 msgid "Emit WAL-related debugging output." msgstr "Genera output di debug relativo al WAL." -#: utils/misc/guc.c:1514 +#: utils/misc/guc.c:1584 msgid "Datetimes are integer based." msgstr "I valori di data e tempo sono basati su interi." -#: utils/misc/guc.c:1525 +#: utils/misc/guc.c:1595 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "Imposta se i nomi di utente con Kerberos e GSSAPI debbano essere trattati come case-insensitive." -#: utils/misc/guc.c:1535 +#: utils/misc/guc.c:1605 msgid "Warn about backslash escapes in ordinary string literals." msgstr "Avverti sull'uso degli escape con backslash nei letterali stringa ordinarie." -#: utils/misc/guc.c:1545 +#: utils/misc/guc.c:1615 msgid "Causes '...' strings to treat backslashes literally." msgstr "Fa sì che le stringhe '...' trattino i backslash letteralmente." -#: utils/misc/guc.c:1556 +#: utils/misc/guc.c:1626 msgid "Enable synchronized sequential scans." msgstr "Abilita le scansioni sequenziali sincronizzate." -#: utils/misc/guc.c:1566 +#: utils/misc/guc.c:1636 msgid "Allows connections and queries during recovery." msgstr "Consente connessioni e query durante il recupero" -#: utils/misc/guc.c:1576 +#: utils/misc/guc.c:1646 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "Consente un feedback da un hot standby al primario che eviterà conflitti di query" -#: utils/misc/guc.c:1586 +#: utils/misc/guc.c:1656 msgid "Allows modifications of the structure of system tables." msgstr "Consente le modifiche alla struttura delle tabelle di sistema." -#: utils/misc/guc.c:1597 +#: utils/misc/guc.c:1667 msgid "Disables reading from system indexes." msgstr "Disabilita la lettura dagli indici di sistema." -#: utils/misc/guc.c:1598 +#: utils/misc/guc.c:1668 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "Non impedisce l'aggiornamento degli indici ed è perciò utilizzabile tranquillamente. Al peggio causa rallentamenti." -#: utils/misc/guc.c:1609 +#: utils/misc/guc.c:1679 msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "Abilita la modalità compatibile col passato del controllo dei privilegi sui large object." -#: utils/misc/guc.c:1610 +#: utils/misc/guc.c:1680 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." msgstr "Evita il controllo dei privilegi quando si leggono o modificano large object, per compatibilità con versioni di PostgreSQL precedenti la 9.0." -#: utils/misc/guc.c:1620 +#: utils/misc/guc.c:1690 msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "Emetti un avviso per i costrutti che hanno cambiato significato da PostgreSQL 9.4." -#: utils/misc/guc.c:1630 +#: utils/misc/guc.c:1700 msgid "When generating SQL fragments, quote all identifiers." msgstr "Quando vengono generati frammenti SQL, metti tra virgolette tutti gli identificatori." -#: utils/misc/guc.c:1640 +#: utils/misc/guc.c:1710 msgid "Shows whether data checksums are turned on for this cluster." msgstr "Mostra se i checksum di dati sono attivi in questo cluster." -#: utils/misc/guc.c:1651 +#: utils/misc/guc.c:1721 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "Aggiungi un numero sequenziale ai messaggi syslog per evitare la soppressione di duplicati." -#: utils/misc/guc.c:1661 +#: utils/misc/guc.c:1731 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "Dividi i messaggi inviati a syslog in linee inferiori a 1024 byte." -#: utils/misc/guc.c:1680 +#: utils/misc/guc.c:1741 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Controlla se Gather e Gather Merge possano anche eseguire sottopiani." + +#: utils/misc/guc.c:1742 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "I nodi di raccolta possono anche eseguire sottopiani, o solo raccogliere tuple?" + +#: utils/misc/guc.c:1751 +msgid "Allow JIT compilation." +msgstr "Permetti compilazione JIT." + +#: utils/misc/guc.c:1761 +msgid "Register JIT compiled function with debugger." +msgstr "Registra la funzione compilata con JIT col debugger." + +#: utils/misc/guc.c:1778 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Scrivi il bitcode LLVM per facilitare il debugging JIT." + +#: utils/misc/guc.c:1789 +msgid "Allow JIT compilation of expressions." +msgstr "Permetti la compilazione JIT di espressioni." + +#: utils/misc/guc.c:1800 +msgid "Register JIT compiled function with perf profiler." +msgstr "Registra la funzione compilata con JIT con il perf profiler." + +#: utils/misc/guc.c:1817 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Permetti al compilatore JIT di deformare tuple." + +#: utils/misc/guc.c:1837 msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." msgstr "Forza il passaggio al prossimo file WAL se un nuovo file non è stato iniziato entro N secondi." -#: utils/misc/guc.c:1691 +#: utils/misc/guc.c:1848 msgid "Waits N seconds on connection startup after authentication." msgstr "Attendi N secondi all'avvio della connessione dopo l'autenticazione." -#: utils/misc/guc.c:1692 utils/misc/guc.c:2237 +#: utils/misc/guc.c:1849 utils/misc/guc.c:2400 msgid "This allows attaching a debugger to the process." msgstr "Ciò consente di agganciare un debugger al processo." -#: utils/misc/guc.c:1701 +#: utils/misc/guc.c:1858 msgid "Sets the default statistics target." msgstr "Definisce la destinazione delle statistiche di default." -#: utils/misc/guc.c:1702 +#: utils/misc/guc.c:1859 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "Questo vale per le colonne di tabelle che non hanno definito una destinazione specifica per colonne per mezzo di un ALTER TABLE SET STATISTICS." -#: utils/misc/guc.c:1711 +#: utils/misc/guc.c:1868 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "Definisce la dimensione della lista FROM oltre la quale le sottoquery non vengono ridotte." -#: utils/misc/guc.c:1713 +#: utils/misc/guc.c:1870 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." msgstr "Il planner fonderà le sottoquery nelle query superiori se la lista FROM risultante avrebbe non più di questi elementi." -#: utils/misc/guc.c:1723 +#: utils/misc/guc.c:1880 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "Definisce la dimensione della lista FROM oltre la quale i costrutti JOIN non vengono più appiattiti." -#: utils/misc/guc.c:1725 +#: utils/misc/guc.c:1882 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." msgstr "Il planner appiattisce i costrutti di JOIN espliciti in liste di elementi FROM ogni volta che ne risulterebbe una lista con non più di questi elementi." -#: utils/misc/guc.c:1735 +#: utils/misc/guc.c:1892 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "Definisce la soglia di elementi FROM oltre la quale viene usato il GEQO." -#: utils/misc/guc.c:1744 +#: utils/misc/guc.c:1901 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: prova a definire i default per gli altri parametri di GEQO." -#: utils/misc/guc.c:1753 +#: utils/misc/guc.c:1910 msgid "GEQO: number of individuals in the population." msgstr "GEQO: numero di individui nella popolazione." -#: utils/misc/guc.c:1754 utils/misc/guc.c:1763 +#: utils/misc/guc.c:1911 utils/misc/guc.c:1920 msgid "Zero selects a suitable default value." msgstr "Lo zero selezione un valore ammissibile come default." -#: utils/misc/guc.c:1762 +#: utils/misc/guc.c:1919 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: numero di iterazioni dell'algoritmo." -#: utils/misc/guc.c:1773 +#: utils/misc/guc.c:1930 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Definisce il tempo di attesa su un lock prima di verificare si tratti di un deadlock." -#: utils/misc/guc.c:1784 +#: utils/misc/guc.c:1941 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "Imposta l'intervallo massimo prima di annullare le query quando un server in hot standby sta processando dati da un WAL archiviato." -#: utils/misc/guc.c:1795 +#: utils/misc/guc.c:1952 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." msgstr "Imposta l'intervallo massimo prima di annullare le query quando un server in hot standby sta processando dati da un WAL streamed." -#: utils/misc/guc.c:1806 +#: utils/misc/guc.c:1963 msgid "Sets the maximum interval between WAL receiver status reports to the primary." msgstr "Imposta l'intervallo massimo tra i rapporti di stato del ricevitore dei WAL al primario." -#: utils/misc/guc.c:1817 +#: utils/misc/guc.c:1974 msgid "Sets the maximum wait time to receive data from the primary." msgstr "Imposta un tempo massimo di attesa per la ricezione di dati dal primario." -#: utils/misc/guc.c:1828 +#: utils/misc/guc.c:1985 msgid "Sets the maximum number of concurrent connections." msgstr "Imposta il numero massimo di connessioni concorrenti." -#: utils/misc/guc.c:1838 +#: utils/misc/guc.c:1996 msgid "Sets the number of connection slots reserved for superusers." msgstr "Imposta il numero di slot per connessioni riservate ai superutenti." -#: utils/misc/guc.c:1852 +#: utils/misc/guc.c:2010 msgid "Sets the number of shared memory buffers used by the server." msgstr "Imposta il numero di buffer di memoria condivisa usati dal server." -#: utils/misc/guc.c:1863 +#: utils/misc/guc.c:2021 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Definisce il numero massimo di buffer temporanei usati da ogni sessione." -#: utils/misc/guc.c:1874 +#: utils/misc/guc.c:2032 msgid "Sets the TCP port the server listens on." msgstr "Imposta il numero di porta TCP sulla quale il server è in ascolto." -#: utils/misc/guc.c:1884 +#: utils/misc/guc.c:2042 msgid "Sets the access permissions of the Unix-domain socket." msgstr "Imposta i permessi di accesso del socket di dominio Unix." -#: utils/misc/guc.c:1885 +#: utils/misc/guc.c:2043 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "I socket di dominio Unix utilizzano i normali permessi dei file system Unix. Il valore del parametro deve essere la specifica numerica dei permessi nella stessa forma accettata dalle chiamate di sistema chmod e umask. (Per usare il classico formato ottale, il valore numerico deve iniziare con 0 (zero).)" -#: utils/misc/guc.c:1899 +#: utils/misc/guc.c:2057 msgid "Sets the file permissions for log files." msgstr "Imposta i permessi dei file di log." -#: utils/misc/guc.c:1900 +#: utils/misc/guc.c:2058 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" msgstr "Il valore del parametro deve essere la specifica numerica dei permessi nella stessa forma accettata dalle chiamate di sistema chmod e umask. (Per usare il classico formato ottale, il valore numerico deve iniziare con 0 (zero).)" -#: utils/misc/guc.c:1913 +#: utils/misc/guc.c:2072 +msgid "Mode of the data directory." +msgstr "Modo della directory dei dati." + +#: utils/misc/guc.c:2073 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Il valore del parametro deve essere la specifica numerica dei permessi nella stessa forma accettata dalle chiamate di sistema chmod e umask. (Per usare il classico formato ottale, il valore numerico deve iniziare con 0 (zero).)" + +#: utils/misc/guc.c:2086 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Imposta la quantità massima di memoria utilizzabile per gli spazi di lavoro delle query." -#: utils/misc/guc.c:1914 +#: utils/misc/guc.c:2087 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." msgstr "Questa quantità di memoria può essere utilizzata per ogni operazione di ordinamento interno e per ogni tabella hash prima di passare ai file temporanei su disco." -#: utils/misc/guc.c:1926 +#: utils/misc/guc.c:2099 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Imposta la quantità massima di memoria utilizzabile per le operazioni di manutenzione." -#: utils/misc/guc.c:1927 +#: utils/misc/guc.c:2100 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "Queste includono operazioni quali VACUUM e CREATE INDEX." -#: utils/misc/guc.c:1937 -msgid "Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "Imposta il numero massimo di tuple che possono essere ordinate usando il rimpiazzo della selezione." - -#: utils/misc/guc.c:1938 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "Quando un è presente un numero maggiore di tuple verrà usato quicksort." - -#: utils/misc/guc.c:1952 +#: utils/misc/guc.c:2115 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Imposta la profondità massima dello stack, in kilobyte." -#: utils/misc/guc.c:1963 +#: utils/misc/guc.c:2126 msgid "Limits the total size of all temporary files used by each process." msgstr "Limita la dimensione totale di tutti i file temporanei usata da ogni processo." -#: utils/misc/guc.c:1964 +#: utils/misc/guc.c:2127 msgid "-1 means no limit." msgstr "-1 vuol dire senza limiti." -#: utils/misc/guc.c:1974 +#: utils/misc/guc.c:2137 msgid "Vacuum cost for a page found in the buffer cache." msgstr "Costo del VACUUM per una pagina trovata nella cache dei buffer." -#: utils/misc/guc.c:1984 +#: utils/misc/guc.c:2147 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "Costo del VACUUM per una pagina non trovata nella cache dei buffer." -#: utils/misc/guc.c:1994 +#: utils/misc/guc.c:2157 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "Costo del VACUUM per una pagina resa sporca dal VACUUM." -#: utils/misc/guc.c:2004 +#: utils/misc/guc.c:2167 msgid "Vacuum cost amount available before napping." msgstr "Costo totale del VACUUM prima della pausa." -#: utils/misc/guc.c:2014 +#: utils/misc/guc.c:2177 msgid "Vacuum cost delay in milliseconds." msgstr "Il costo del VACUUM come ritardo in millisecondi." -#: utils/misc/guc.c:2025 +#: utils/misc/guc.c:2188 msgid "Vacuum cost delay in milliseconds, for autovacuum." msgstr "Il costo del VACUUM come ritardo in millisecondi, per l'autovacuum." -#: utils/misc/guc.c:2036 +#: utils/misc/guc.c:2199 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "Il costo totale del VACUUM prima della pausa, per l'autovacuum." -#: utils/misc/guc.c:2046 +#: utils/misc/guc.c:2209 msgid "Sets the maximum number of simultaneously open files for each server process." msgstr "Imposta il numero massimo di file aperti contemporaneamente per ogni processo server." -#: utils/misc/guc.c:2059 +#: utils/misc/guc.c:2222 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Imposta il numero massimo di transazioni preparate contemporanee." -#: utils/misc/guc.c:2070 +#: utils/misc/guc.c:2233 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Imposta l'OID minimo delle tabelle per tracciare i lock." -#: utils/misc/guc.c:2071 +#: utils/misc/guc.c:2234 msgid "Is used to avoid output on system tables." msgstr "È usato per evitare l'output su tabelle di sistema." -#: utils/misc/guc.c:2080 +#: utils/misc/guc.c:2243 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Imposta l'OID delle tabelle con tracciamento dei lock non facoltativo." -#: utils/misc/guc.c:2092 +#: utils/misc/guc.c:2255 msgid "Sets the maximum allowed duration of any statement." msgstr "Imposta la durata massima consentita per qualsiasi istruzione." -#: utils/misc/guc.c:2093 utils/misc/guc.c:2104 utils/misc/guc.c:2115 +#: utils/misc/guc.c:2256 utils/misc/guc.c:2267 utils/misc/guc.c:2278 msgid "A value of 0 turns off the timeout." msgstr "Il valore 0 disabilita il timeout." -#: utils/misc/guc.c:2103 +#: utils/misc/guc.c:2266 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Imposta la durata massima consentita di qualsiasi attesa per un lock." -#: utils/misc/guc.c:2114 +#: utils/misc/guc.c:2277 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "Imposta la durata massima permessa per ogni transazione inattiva." -#: utils/misc/guc.c:2125 +#: utils/misc/guc.c:2288 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "Anzianità minima alla quale il VACUUM deve congelare una riga di tabella." -#: utils/misc/guc.c:2135 +#: utils/misc/guc.c:2298 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "Anzianità alla quale il VACUUM deve scandire l'intera tabella per congelarne le tuple." -#: utils/misc/guc.c:2145 +#: utils/misc/guc.c:2308 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "Anzianità minima alla quale VACUUM deve congelare un MultiXactId in una riga di tabella." -#: utils/misc/guc.c:2155 +#: utils/misc/guc.c:2318 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "Anzianità del multixact alla quale VACUUM deve scandire tutta la tabella per congelare le tuple." -#: utils/misc/guc.c:2165 +#: utils/misc/guc.c:2328 msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." msgstr "Numero di transazioni per cui VACUUM e pulizia HOT devono essere deferibili, se impostata." -#: utils/misc/guc.c:2178 +#: utils/misc/guc.c:2341 msgid "Sets the maximum number of locks per transaction." msgstr "Definisce il numero massimo di lock per transazione." -#: utils/misc/guc.c:2179 +#: utils/misc/guc.c:2342 msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "La tabella degli shared lock è dimensionata secondo l'assunzione che al massimo max_locks_per_transaction * max_connections distinti oggetti avranno bisogni di essere lockati in un determinato istante." -#: utils/misc/guc.c:2190 +#: utils/misc/guc.c:2353 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Imposta il numero massimo di lock di predicato per transazione." -#: utils/misc/guc.c:2191 +#: utils/misc/guc.c:2354 msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." msgstr "La tabella dei lock di predicato è dimensionata secondo l'assunzione che al massimo max_pred_locks_per_transaction * max_connections distinti oggetti avranno bisogni di essere lockati in un determinato istante." -#: utils/misc/guc.c:2202 +#: utils/misc/guc.c:2365 msgid "Sets the maximum number of predicate-locked pages and tuples per relation." msgstr "Imposta il numero di pagine e tuple bloccate da lock di predicato per relazione." -#: utils/misc/guc.c:2203 -msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation level lock." +#: utils/misc/guc.c:2366 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." msgstr "Se più di questo numero totale di pagine e tuple nella stessa relazione sono bloccate da una connessione, questi lock verranno sostituiti da un lock a livello di relazione." -#: utils/misc/guc.c:2213 +#: utils/misc/guc.c:2376 msgid "Sets the maximum number of predicate-locked tuples per page." msgstr "Imposta il numero massimo di tuple bloccate da lock di predicato per pagina." -#: utils/misc/guc.c:2214 -msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page level lock." +#: utils/misc/guc.c:2377 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." msgstr "Se più di questo numero di tuple nella stessa pagina sono bloccate da una connessione, questi lock verranno sostituiti da un lock a livello di pagina." -#: utils/misc/guc.c:2224 +#: utils/misc/guc.c:2387 msgid "Sets the maximum allowed time to complete client authentication." msgstr "Imposta il tempo massimo consentito per completare l'autenticazione del client." -#: utils/misc/guc.c:2236 +#: utils/misc/guc.c:2399 msgid "Waits N seconds on connection startup before authentication." msgstr "Attendi N secondi all'avvio della connessione prima dell'autenticazione." -#: utils/misc/guc.c:2247 +#: utils/misc/guc.c:2410 msgid "Sets the number of WAL files held for standby servers." msgstr "Imposta il numero di file WAL trattenuti dai server in standby." -#: utils/misc/guc.c:2257 +#: utils/misc/guc.c:2420 msgid "Sets the minimum size to shrink the WAL to." msgstr "Imposta la dimensione minima a cui ridurre il file WAL." -#: utils/misc/guc.c:2268 +#: utils/misc/guc.c:2432 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Imosta la dimensione del WAL che fa scattare un checkpoint." -#: utils/misc/guc.c:2279 +#: utils/misc/guc.c:2444 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "Imposta il tempo massimo intercorrente fra due checkpoint automatici del WAL." -#: utils/misc/guc.c:2290 +#: utils/misc/guc.c:2455 msgid "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "Abilita gli avvertimenti se i segmenti dei checkpoint sono riempiti più frequentemente di questo valore." -#: utils/misc/guc.c:2292 +#: utils/misc/guc.c:2457 msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." msgstr "Scrive un messaggio nel log del server se i checkpoint dovuti al riempimento dei file dei segmenti dei checkpoint avvengono più frequentemente di questo numero di secondi. Il valore 0 (zero) disabilita questi avvisi." -#: utils/misc/guc.c:2304 utils/misc/guc.c:2461 utils/misc/guc.c:2488 +#: utils/misc/guc.c:2469 utils/misc/guc.c:2626 utils/misc/guc.c:2654 msgid "Number of pages after which previously performed writes are flushed to disk." msgstr "Numerp di pagine dopo il quale le scritture effettuate in precedenza sono scaricate su disco." -#: utils/misc/guc.c:2315 +#: utils/misc/guc.c:2480 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "Imposta il numero di buffer delle pagine su disco in shared memory per il WAL." -#: utils/misc/guc.c:2326 +#: utils/misc/guc.c:2491 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Tempo tra due flush del WAL effettuati dal processo di scrittura WAL." -#: utils/misc/guc.c:2337 +#: utils/misc/guc.c:2502 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "Quantità di WAL da emettere dal processo di scrittura per far scattare un flush." -#: utils/misc/guc.c:2349 +#: utils/misc/guc.c:2514 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "Imposta il numero massimo di processi WAL sender in esecuzione simultanea." -#: utils/misc/guc.c:2360 +#: utils/misc/guc.c:2525 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Imposta il numero massimo di slot di replica definiti simultaneamente." -#: utils/misc/guc.c:2370 +#: utils/misc/guc.c:2535 msgid "Sets the maximum time to wait for WAL replication." msgstr "Imposta il tempo di attesa massimo per una replica WAL." -#: utils/misc/guc.c:2381 +#: utils/misc/guc.c:2546 msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." msgstr "Imposta il ritardo in microsecondi tra il commit della transazione e il flushing del WAL su disco." -#: utils/misc/guc.c:2393 +#: utils/misc/guc.c:2558 msgid "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "Imposta il numero minimo di transazioni concorrenti aperte prima di eseguire un commit_delay" -#: utils/misc/guc.c:2404 +#: utils/misc/guc.c:2569 msgid "Sets the number of digits displayed for floating-point values." msgstr "Imposta il numero di cifre visualizzate per i valori in virgola mobile." -#: utils/misc/guc.c:2405 +#: utils/misc/guc.c:2570 msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." msgstr "Ciò ha effetto sui tipi di dati real, double precision e geometrici. Il valore del parametro è sommato al numero standard di cifre (FLT_DIG o DBL_DIG a seconda dei casi)." -#: utils/misc/guc.c:2416 +#: utils/misc/guc.c:2581 msgid "Sets the minimum execution time above which statements will be logged." msgstr "Imposta il tempo minimo di esecuzione oltre il quale le istruzioni vengono registrate nel log." -#: utils/misc/guc.c:2418 +#: utils/misc/guc.c:2583 msgid "Zero prints all queries. -1 turns this feature off." msgstr "Il valore 0 (zero) fa sì che tutte le query siano registrate. Il valore -1 disabilita questa caratteristica." -#: utils/misc/guc.c:2428 +#: utils/misc/guc.c:2593 msgid "Sets the minimum execution time above which autovacuum actions will be logged." msgstr "Imposta il tempo minimo di esecuzione oltre il quale le azioni dell'autovacuum vengono registrate nel log." -#: utils/misc/guc.c:2430 +#: utils/misc/guc.c:2595 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "Il valore 0 (zero) fa sì che tutte le azioni siano registrate. Il valore -1 disabilita il logging dell'autovacuum." -#: utils/misc/guc.c:2440 +#: utils/misc/guc.c:2605 msgid "Background writer sleep time between rounds." msgstr "Il tempo di pausa fra due tornate del background writer." -#: utils/misc/guc.c:2451 +#: utils/misc/guc.c:2616 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "Il numero massimo di pagine LRU che il background writer scarica ad ogni tornata." -#: utils/misc/guc.c:2474 +#: utils/misc/guc.c:2639 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "Il numero di richieste simultanee che possono essere gestite con efficienza dal sottosistema a dischi." -#: utils/misc/guc.c:2475 +#: utils/misc/guc.c:2640 msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." msgstr "Per i sistemi RAID, questo valore è pari all'incirca al numero di dischi fisici nell'array." -#: utils/misc/guc.c:2501 +#: utils/misc/guc.c:2667 msgid "Maximum number of concurrent worker processes." msgstr "Numero massimo di processi worker concorrenti." -#: utils/misc/guc.c:2513 +#: utils/misc/guc.c:2679 msgid "Maximum number of logical replication worker processes." msgstr "Numero massimo di processi worker di replica logica." -#: utils/misc/guc.c:2525 +#: utils/misc/guc.c:2691 msgid "Maximum number of table synchronization workers per subscription." msgstr "Numero massimo di processi worker di sincronizzazione per sottoscrizione." -#: utils/misc/guc.c:2535 +#: utils/misc/guc.c:2701 msgid "Automatic log file rotation will occur after N minutes." msgstr "La rotazione automatica dei log avviene dopo N minuti." -#: utils/misc/guc.c:2546 +#: utils/misc/guc.c:2712 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "La rotazione automatica dei log avviene dopo N kilobyte." -#: utils/misc/guc.c:2557 +#: utils/misc/guc.c:2723 msgid "Shows the maximum number of function arguments." msgstr "Mostra il numero massimo di argomenti delle funzioni." -#: utils/misc/guc.c:2568 +#: utils/misc/guc.c:2734 msgid "Shows the maximum number of index keys." msgstr "Mostra il numero massimo di chiavi degli indici." -#: utils/misc/guc.c:2579 +#: utils/misc/guc.c:2745 msgid "Shows the maximum identifier length." msgstr "Mostra la lunghezza massima per gli identificatori." -#: utils/misc/guc.c:2590 +#: utils/misc/guc.c:2756 msgid "Shows the size of a disk block." msgstr "Mostra la dimensione di un blocco su disco." -#: utils/misc/guc.c:2601 +#: utils/misc/guc.c:2767 msgid "Shows the number of pages per disk file." msgstr "Mostra il numero di pagine per file su disco." -#: utils/misc/guc.c:2612 +#: utils/misc/guc.c:2778 msgid "Shows the block size in the write ahead log." msgstr "Mostra la dimensione del log di write ahead." -#: utils/misc/guc.c:2623 +#: utils/misc/guc.c:2789 msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "Imposta il tempo di attesa prima di riprovare a recuperare un WAL dopo un tentativo fallito." -#: utils/misc/guc.c:2635 -msgid "Shows the number of pages per write ahead log segment." -msgstr "Mostra il numero di pagine per un segmento del log di write ahead." +#: utils/misc/guc.c:2801 +msgid "Shows the size of write ahead log segments." +msgstr "Mostra la dimensione dei segmenti del log di write ahead" -#: utils/misc/guc.c:2648 +#: utils/misc/guc.c:2814 msgid "Time to sleep between autovacuum runs." msgstr "Tempo di pausa fra due esecuzioni di autovacuum." -#: utils/misc/guc.c:2658 +#: utils/misc/guc.c:2824 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "Numero minimo di modifiche o cancellazioni di tuple prima dell'esecuzione di un autovacuum." -#: utils/misc/guc.c:2667 +#: utils/misc/guc.c:2833 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "Numero minimo di inserimenti, modifiche o cancellazioni di tuple prima dell'esecuzione di un analyze." -#: utils/misc/guc.c:2677 +#: utils/misc/guc.c:2843 msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "Anzianità alla quale eseguire un autovacuum su una tabella per prevenire il wraparound dell'ID delle transazioni." -#: utils/misc/guc.c:2688 +#: utils/misc/guc.c:2854 msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "Anzianità multixaxt a cui eseguire l'autovacuum di una tabella per prevenire il wraparound del multixact." -#: utils/misc/guc.c:2698 +#: utils/misc/guc.c:2864 msgid "Sets the maximum number of simultaneously running autovacuum worker processes." msgstr "Imposta il numero massimo dei processi worker dell'autovacuum in esecuzione contemporanea." -#: utils/misc/guc.c:2708 +#: utils/misc/guc.c:2874 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Imposta il numero massimo di processi paralleli per operazioni di manutenzione." + +#: utils/misc/guc.c:2884 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Imposta il numero massimo di processi paralleli per nodo di esecuzione." -#: utils/misc/guc.c:2718 -msgid "Sets the maximum number of parallel workers than can be active at one time." +#: utils/misc/guc.c:2894 +msgid "Sets the maximum number of parallel workers that can be active at one time." msgstr "Imposta il numero massimo di worker paralleli che possono essere attivi contemporaneamente." -#: utils/misc/guc.c:2728 +#: utils/misc/guc.c:2904 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "Imposta la memoria massima utilizzabile da ogni processo autovacuum." -#: utils/misc/guc.c:2739 +#: utils/misc/guc.c:2915 msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." msgstr "Tempo prima che uno snapshot sia troppo vecchio per leggere le pagine cambiate dopo che era stato effettuato." -#: utils/misc/guc.c:2740 +#: utils/misc/guc.c:2916 msgid "A value of -1 disables this feature." msgstr "Il valore -1 disabilita questa feature." -#: utils/misc/guc.c:2750 +#: utils/misc/guc.c:2926 msgid "Time between issuing TCP keepalives." msgstr "Tempo di attesa fra due keepalive TCP." -#: utils/misc/guc.c:2751 utils/misc/guc.c:2762 +#: utils/misc/guc.c:2927 utils/misc/guc.c:2938 msgid "A value of 0 uses the system default." msgstr "Il valore 0 (zero) fa sì che si applichi il valore predefinito di sistema." -#: utils/misc/guc.c:2761 +#: utils/misc/guc.c:2937 msgid "Time between TCP keepalive retransmits." msgstr "Tempo che intercorre fra due ritrasmissioni del keepalive TCP." -#: utils/misc/guc.c:2772 +#: utils/misc/guc.c:2948 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "Il rinegoziamento SSL non è più supportato: può essere solo 0." -#: utils/misc/guc.c:2783 +#: utils/misc/guc.c:2959 msgid "Maximum number of TCP keepalive retransmits." msgstr "Numero massimo di ritrasmissioni del keepalive TCP." -#: utils/misc/guc.c:2784 +#: utils/misc/guc.c:2960 msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." msgstr "Ciò controlla il numero di ritrasmissioni consecutive del keepalive che possono andare perdute prima che una connessione sia considerata morta. Il valore 0 (zero) fa sì che si applichi il valore predefinito di sistema." -#: utils/misc/guc.c:2795 +#: utils/misc/guc.c:2971 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Imposta il risultato massimo consentito per le ricerche esatte tramite GIN." -#: utils/misc/guc.c:2806 +#: utils/misc/guc.c:2982 msgid "Sets the planner's assumption about the size of the disk cache." msgstr "Imposta le assunzioni del planner in merito alla dimensione della cache dei dischi." -#: utils/misc/guc.c:2807 +#: utils/misc/guc.c:2983 msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." msgstr "Cioè la porzione della cache dei dischi nel kernel che sarà usata per i file dati di PostgreSQL. Viene misurata in pagine disco, che normalmente sono da 8 KB ciascuna." -#: utils/misc/guc.c:2819 +#: utils/misc/guc.c:2995 msgid "Sets the minimum amount of table data for a parallel scan." msgstr "Imposta la quantità minima di dati di una tabella per uno scan parallelo." -#: utils/misc/guc.c:2820 +#: utils/misc/guc.c:2996 msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." msgstr "Se il planner stima che leggerà un numero di pagine di tabella troppo basso per raggiungere questo limite, non verrà preso in considerazione uno scan parallelo." -#: utils/misc/guc.c:2830 +#: utils/misc/guc.c:3006 msgid "Sets the minimum amount of index data for a parallel scan." msgstr "Imposta la quantità minima di dati di un indice per uno scan parallelo." -#: utils/misc/guc.c:2831 +#: utils/misc/guc.c:3007 msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." msgstr "Se il planner stima che leggerà un numero di pagine di indice troppo basso per raggiungere questo limite, non verrà preso in considerazione uno scan parallelo." -#: utils/misc/guc.c:2842 +#: utils/misc/guc.c:3018 msgid "Shows the server version as an integer." msgstr "Mostra la versione del server come un intero." -#: utils/misc/guc.c:2853 +#: utils/misc/guc.c:3029 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "Registra nel log l'uso di file temporanei più grandi di questo numero di kilobyte." -#: utils/misc/guc.c:2854 +#: utils/misc/guc.c:3030 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "Il valore 0 (zero) fa registrare tutti i file. Il default è -1 (che disabilita la registrazione)." -#: utils/misc/guc.c:2864 +#: utils/misc/guc.c:3040 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Imposta la dimensione in byte riservata a pg_stat_activity.query." -#: utils/misc/guc.c:2879 +#: utils/misc/guc.c:3051 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Imposta la dimensione massima della lista di attesa per gli indici GIN." -#: utils/misc/guc.c:2899 +#: utils/misc/guc.c:3071 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "Imposta la stima del planner del costo di una pagina di disco letta sequenzialmente." -#: utils/misc/guc.c:2909 +#: utils/misc/guc.c:3081 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "Imposta la stima del planner del costo di una pagina di disco letta non sequenzialmente." -#: utils/misc/guc.c:2919 +#: utils/misc/guc.c:3091 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "Imposta la stima del planner del costo di elaborazione di ogni tupla (riga)." -#: utils/misc/guc.c:2929 +#: utils/misc/guc.c:3101 msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." msgstr "Imposta la stima del il planner del costo di elaborazione di un singolo elemento di indice durante una scansione di indice." -#: utils/misc/guc.c:2939 +#: utils/misc/guc.c:3111 msgid "Sets the planner's estimate of the cost of processing each operator or function call." msgstr "Imposta la stima del planner del costo di elaborazione di un singolo operatore o chiamata di funzione." -#: utils/misc/guc.c:2949 +#: utils/misc/guc.c:3121 msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." msgstr "Imposta la stima del planner del costo di passare ogni tupla (riga) dal worker al backend master." -#: utils/misc/guc.c:2959 +#: utils/misc/guc.c:3131 msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "Imposta la stima del planner del costo di avvio dei processi worker per una query parallela." -#: utils/misc/guc.c:2970 +#: utils/misc/guc.c:3142 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Effettua la compilazione JIT se la query è più costosa." + +#: utils/misc/guc.c:3143 +msgid "-1 disables JIT compilation." +msgstr "-1 disabilita la compilazione JIT." + +#: utils/misc/guc.c:3152 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Ottimizza le funzioni compilate con JIT se la query è più costosa." + +#: utils/misc/guc.c:3153 +msgid "-1 disables optimization." +msgstr "-1 disabilita l'ottimizzazione." + +#: utils/misc/guc.c:3162 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Effettua l'inlining JIT se la query è più costosa." + +#: utils/misc/guc.c:3163 +msgid "-1 disables inlining." +msgstr "-1 disabilita l'inlining." + +#: utils/misc/guc.c:3172 msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." msgstr "Imposta la stima del planner della frazione delle righe di un cursore che verranno lette." -#: utils/misc/guc.c:2981 +#: utils/misc/guc.c:3183 msgid "GEQO: selective pressure within the population." msgstr "GEQO: pressione selettiva all'interno della popolazione." -#: utils/misc/guc.c:2991 +#: utils/misc/guc.c:3193 msgid "GEQO: seed for random path selection." msgstr "GEQO: seme per la selezione casuale dei percorsi." -#: utils/misc/guc.c:3001 +#: utils/misc/guc.c:3203 msgid "Multiple of the average buffer usage to free per round." msgstr "Multiplo dell'utilizzo medio dei buffer da liberarsi ad ogni giro." -#: utils/misc/guc.c:3011 +#: utils/misc/guc.c:3213 msgid "Sets the seed for random-number generation." msgstr "Imposta il seme per la generazione di numeri casuali." -#: utils/misc/guc.c:3022 +#: utils/misc/guc.c:3224 msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." msgstr "Il numero di modifiche o cancellazioni di tuple prima di un VACUUM, come frazione di reltuples." -#: utils/misc/guc.c:3031 +#: utils/misc/guc.c:3233 msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." msgstr "Numero di inserimenti, modifiche o cancellazioni di tuple prima di un ANALYZE, come frazione di reltuples." -#: utils/misc/guc.c:3041 +#: utils/misc/guc.c:3243 msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." msgstr "Il tempo speso nell'eseguire il flush dei buffer sporchi durante i checkpoint, come frazione dell'intervallo di checkpoint." -#: utils/misc/guc.c:3060 +#: utils/misc/guc.c:3253 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Numero di inserimenti di tuple prima della pulizia dell'indice come frazione di reltuples." + +#: utils/misc/guc.c:3272 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "Imposta il comando di shell che verrà eseguito per archiviare un file WAL." -#: utils/misc/guc.c:3070 +#: utils/misc/guc.c:3282 msgid "Sets the client's character set encoding." msgstr "Imposta la codifica dei caratteri del client." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3293 msgid "Controls information prefixed to each log line." msgstr "Controlla l'informazione usata come prefisso per ogni riga di log." -#: utils/misc/guc.c:3082 +#: utils/misc/guc.c:3294 msgid "If blank, no prefix is used." msgstr "Se lasciata vuota non sarà usato alcun prefisso." -#: utils/misc/guc.c:3091 +#: utils/misc/guc.c:3303 msgid "Sets the time zone to use in log messages." msgstr "Imposta il fuso orario da usarsi nei messaggi di log." -#: utils/misc/guc.c:3101 +#: utils/misc/guc.c:3313 msgid "Sets the display format for date and time values." msgstr "Imposta il formato per la visualizzazione dei valori di data e ora." -#: utils/misc/guc.c:3102 +#: utils/misc/guc.c:3314 msgid "Also controls interpretation of ambiguous date inputs." msgstr "Controlla anche l'interpretazione di input ambigui per le date." -#: utils/misc/guc.c:3113 +#: utils/misc/guc.c:3325 msgid "Sets the default tablespace to create tables and indexes in." msgstr "Imposta il tablespace di default in cui create tabelle e indici." -#: utils/misc/guc.c:3114 +#: utils/misc/guc.c:3326 msgid "An empty string selects the database's default tablespace." msgstr "Una stringa vuota selezione il tablespace predefinito del database." -#: utils/misc/guc.c:3124 +#: utils/misc/guc.c:3336 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "Definisce i(l) tablespace da usarsi per le tabelle temporanee e i file di ordinamento." -#: utils/misc/guc.c:3135 +#: utils/misc/guc.c:3347 msgid "Sets the path for dynamically loadable modules." msgstr "Definisce il percorso per i moduli caricabili dinamicamente." -#: utils/misc/guc.c:3136 +#: utils/misc/guc.c:3348 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "Se si deve aprire un modulo caricabile dinamicamente e il nome specificato non contiene un percorso di directory (se non contiene uno slash) il sistema cercherà il file specificato in questo percorso." -#: utils/misc/guc.c:3149 +#: utils/misc/guc.c:3361 msgid "Sets the location of the Kerberos server key file." msgstr "Imposta la posizione del key file del server Kerberos." -#: utils/misc/guc.c:3160 +#: utils/misc/guc.c:3372 msgid "Sets the Bonjour service name." msgstr "Imposta il nome del servizio Bonjour." -#: utils/misc/guc.c:3172 +#: utils/misc/guc.c:3384 msgid "Shows the collation order locale." msgstr "Mostra la localizzazione dell'ordine di collazione." -#: utils/misc/guc.c:3183 +#: utils/misc/guc.c:3395 msgid "Shows the character classification and case conversion locale." msgstr "Mostra la localizzazione per la classificazione dei caratteri e la conversione maiuscole/minuscole." -#: utils/misc/guc.c:3194 +#: utils/misc/guc.c:3406 msgid "Sets the language in which messages are displayed." msgstr "Mostra la lingua in cui i messaggi sono visualizzati." -#: utils/misc/guc.c:3204 +#: utils/misc/guc.c:3416 msgid "Sets the locale for formatting monetary amounts." msgstr "Imposta la localizzazione per la formattazione delle quantità monetarie." -#: utils/misc/guc.c:3214 +#: utils/misc/guc.c:3426 msgid "Sets the locale for formatting numbers." msgstr "Imposta la localizzazione per la formattazione dei numeri." -#: utils/misc/guc.c:3224 +#: utils/misc/guc.c:3436 msgid "Sets the locale for formatting date and time values." msgstr "Imposta la localizzazione per la formattazione per i valori di tipo data e ora." -#: utils/misc/guc.c:3234 +#: utils/misc/guc.c:3446 msgid "Lists shared libraries to preload into each backend." msgstr "Imposta la lista delle librerie condivise da precaricare on ogni backend." -#: utils/misc/guc.c:3245 +#: utils/misc/guc.c:3457 msgid "Lists shared libraries to preload into server." msgstr "Imposta la lista delle librerie condivise da precaricare nel server." -#: utils/misc/guc.c:3256 +#: utils/misc/guc.c:3468 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "Imposta la lista delle librarie condivise non privilegiate da precaricare in ogni backend." -#: utils/misc/guc.c:3267 +#: utils/misc/guc.c:3479 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "Imposta l'ordine di ricerca degli schema per i nomi che non hanno un qualifica di schema." -#: utils/misc/guc.c:3279 +#: utils/misc/guc.c:3491 msgid "Sets the server (database) character set encoding." msgstr "Imposta la codifica del set di caratteri per il server (database)." -#: utils/misc/guc.c:3291 +#: utils/misc/guc.c:3503 msgid "Shows the server version." msgstr "Mostra la versione del server." -#: utils/misc/guc.c:3303 +#: utils/misc/guc.c:3515 msgid "Sets the current role." msgstr "Mostra il ruolo corrente." -#: utils/misc/guc.c:3315 +#: utils/misc/guc.c:3527 msgid "Sets the session user name." msgstr "Mostra il nome dell'utente della sessione." -#: utils/misc/guc.c:3326 +#: utils/misc/guc.c:3538 msgid "Sets the destination for server log output." msgstr "Imposta la destinazione per l'output dei log del server." -#: utils/misc/guc.c:3327 +#: utils/misc/guc.c:3539 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." msgstr "I valori validi sono combinazioni di \"stderr\", \"syslog\", \"csvlog\" ed \"eventlog\", a seconda delle piattaforme." -#: utils/misc/guc.c:3338 +#: utils/misc/guc.c:3550 msgid "Sets the destination directory for log files." msgstr "Imposta la directory di destinazione dei file di log." -#: utils/misc/guc.c:3339 +#: utils/misc/guc.c:3551 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "Può essere specificata sia come relativa alla directory data sia come percorso assoluto." -#: utils/misc/guc.c:3349 +#: utils/misc/guc.c:3561 msgid "Sets the file name pattern for log files." msgstr "Imposta il pattern dei nomi dei file di log." -#: utils/misc/guc.c:3360 +#: utils/misc/guc.c:3572 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "Imposta il nome del programma da utilizzato per identificare i messaggi di PostgreSQL in syslog." -#: utils/misc/guc.c:3371 +#: utils/misc/guc.c:3583 msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "Imposta il nome del programma da usarsi per identificare i messaggi di PostgreSQL nel registro degli eventi." -#: utils/misc/guc.c:3382 +#: utils/misc/guc.c:3594 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "Imposta il fuso orario per visualizzare ed interpretare gli orari." -#: utils/misc/guc.c:3392 +#: utils/misc/guc.c:3604 msgid "Selects a file of time zone abbreviations." msgstr "Seleziona un file contenente le abbreviazioni dei fusi orari." -#: utils/misc/guc.c:3402 +#: utils/misc/guc.c:3614 msgid "Sets the current transaction's isolation level." msgstr "Imposta il livello di isolamento per la transazione in corso." -#: utils/misc/guc.c:3413 +#: utils/misc/guc.c:3625 msgid "Sets the owning group of the Unix-domain socket." msgstr "Imposta il gruppo di appartenenza per i socket di dominio Unix." -#: utils/misc/guc.c:3414 +#: utils/misc/guc.c:3626 msgid "The owning user of the socket is always the user that starts the server." msgstr "L'utente che possiede il socket è sempre l'utente che ha avviato il server." -#: utils/misc/guc.c:3424 +#: utils/misc/guc.c:3636 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "Imposta la directory dove i socket di dominio Unix verranno creati." -#: utils/misc/guc.c:3439 +#: utils/misc/guc.c:3651 msgid "Sets the host name or IP address(es) to listen to." msgstr "Imposta il nome host o gli indirizzi IP su cui ascoltare." -#: utils/misc/guc.c:3454 +#: utils/misc/guc.c:3666 msgid "Sets the server's data directory." msgstr "Imposta la posizione della directory dati" -#: utils/misc/guc.c:3465 +#: utils/misc/guc.c:3677 msgid "Sets the server's main configuration file." msgstr "Imposta il file primario di configurazione del server." -#: utils/misc/guc.c:3476 +#: utils/misc/guc.c:3688 msgid "Sets the server's \"hba\" configuration file." msgstr "Imposta il file di configurazione \"hba\" del server." -#: utils/misc/guc.c:3487 +#: utils/misc/guc.c:3699 msgid "Sets the server's \"ident\" configuration file." msgstr "Imposta il file di configurazione \"ident\" del server." -#: utils/misc/guc.c:3498 +#: utils/misc/guc.c:3710 msgid "Writes the postmaster PID to the specified file." msgstr "Scrivi il PID del postmaster nel file specificato." -#: utils/misc/guc.c:3509 +#: utils/misc/guc.c:3721 msgid "Location of the SSL server certificate file." msgstr "Posizione del file di certificati del server SSL." -#: utils/misc/guc.c:3519 +#: utils/misc/guc.c:3731 msgid "Location of the SSL server private key file." msgstr "Posizione del file della chiave privata del server SSL." -#: utils/misc/guc.c:3529 +#: utils/misc/guc.c:3741 msgid "Location of the SSL certificate authority file." msgstr "Posizione del file di autorità dei certificati del server SSL." -#: utils/misc/guc.c:3539 +#: utils/misc/guc.c:3751 msgid "Location of the SSL certificate revocation list file." msgstr "Posizione del file della lista di revoche di certificati SSL." -#: utils/misc/guc.c:3549 +#: utils/misc/guc.c:3761 msgid "Writes temporary statistics files to the specified directory." msgstr "Scrive i file di statistiche temporanee nella directory specificata." -#: utils/misc/guc.c:3560 +#: utils/misc/guc.c:3772 msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "Numero di standby sincroni e lista dei nomi di quelli potenziali sincroni." -#: utils/misc/guc.c:3571 +#: utils/misc/guc.c:3783 msgid "Sets default text search configuration." msgstr "Imposta la configurazione di ricerca di testo predefinita." -#: utils/misc/guc.c:3581 +#: utils/misc/guc.c:3793 msgid "Sets the list of allowed SSL ciphers." msgstr "Imposta la lista di codici SSL consentiti." -#: utils/misc/guc.c:3596 +#: utils/misc/guc.c:3808 msgid "Sets the curve to use for ECDH." msgstr "Imposta la curva da usare per l'ECHD." -#: utils/misc/guc.c:3611 +#: utils/misc/guc.c:3823 +msgid "Location of the SSL DH parameters file." +msgstr "Posizione del file di parametri SSH DH." + +#: utils/misc/guc.c:3834 +msgid "Command to obtain passphrases for SSL." +msgstr "Comando per ottenere la passphrase per SSL." + +#: utils/misc/guc.c:3844 msgid "Sets the application name to be reported in statistics and logs." msgstr "Imposta il nome dell'applicazione da riportare nelle statistiche e nei log." -#: utils/misc/guc.c:3622 +#: utils/misc/guc.c:3855 msgid "Sets the name of the cluster, which is included in the process title." msgstr "Imposta il nome del cluster, che è incluso nel titolo del processo." -#: utils/misc/guc.c:3633 +#: utils/misc/guc.c:3866 msgid "Sets the WAL resource managers for which WAL consistency checks are done." msgstr "Imposta i gestori di risorse WAL per cui vengono effettuati i controlli di consistenza WAL." -#: utils/misc/guc.c:3634 +#: utils/misc/guc.c:3867 msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." msgstr "Immagini di pagine complete verranno loggate per tutti i blocchi di dati e comparati con i risultati del replay del WAL." -#: utils/misc/guc.c:3653 +#: utils/misc/guc.c:3877 +msgid "JIT provider to use." +msgstr "Fornitore JIT da usare." + +#: utils/misc/guc.c:3897 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "Imposta se \"\\'\" è consentito nei letterali stringa." -#: utils/misc/guc.c:3663 +#: utils/misc/guc.c:3907 msgid "Sets the output format for bytea." msgstr "Imposta il formato di output di bytea." -#: utils/misc/guc.c:3673 +#: utils/misc/guc.c:3917 msgid "Sets the message levels that are sent to the client." msgstr "Imposta quali livelli di messaggi sono inviati al client" -#: utils/misc/guc.c:3674 utils/misc/guc.c:3727 utils/misc/guc.c:3738 -#: utils/misc/guc.c:3804 +#: utils/misc/guc.c:3918 utils/misc/guc.c:3971 utils/misc/guc.c:3982 +#: utils/misc/guc.c:4048 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "Ogni livello include tutti i livelli che lo seguono. Più avanti il livello, meno messaggi sono inviati." -#: utils/misc/guc.c:3684 +#: utils/misc/guc.c:3928 msgid "Enables the planner to use constraints to optimize queries." msgstr "Permette al planner di usare i vincoli per ottimizzare le query." -#: utils/misc/guc.c:3685 +#: utils/misc/guc.c:3929 msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "La scansioni delle tabelle saranno evitate se i loro vincoli garantiscono che nessuna riga corrisponda con la query." -#: utils/misc/guc.c:3695 +#: utils/misc/guc.c:3939 msgid "Sets the transaction isolation level of each new transaction." msgstr "Imposta il livello di isolamento predefinito per ogni nuova transazione." -#: utils/misc/guc.c:3705 +#: utils/misc/guc.c:3949 msgid "Sets the display format for interval values." msgstr "Imposta il formato di visualizzazione per intervalli." -#: utils/misc/guc.c:3716 +#: utils/misc/guc.c:3960 msgid "Sets the verbosity of logged messages." msgstr "Imposta la prolissità dei messaggi registrati." -#: utils/misc/guc.c:3726 +#: utils/misc/guc.c:3970 msgid "Sets the message levels that are logged." msgstr "Imposta i livelli dei messaggi registrati." -#: utils/misc/guc.c:3737 +#: utils/misc/guc.c:3981 msgid "Causes all statements generating error at or above this level to be logged." msgstr "Fa in modo che tutti gli eventi che generano errore a questo livello o a un livello superiore siano registrati nel log." -#: utils/misc/guc.c:3748 +#: utils/misc/guc.c:3992 msgid "Sets the type of statements logged." msgstr "Imposta il tipo di istruzioni registrato nel log." -#: utils/misc/guc.c:3758 +#: utils/misc/guc.c:4002 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "Imposta la \"facility\" da usare quando syslog è abilitato." -#: utils/misc/guc.c:3773 +#: utils/misc/guc.c:4017 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "Imposta il comportamento delle sessioni per i trigger e le regole di riscrittura." -#: utils/misc/guc.c:3783 +#: utils/misc/guc.c:4027 msgid "Sets the current transaction's synchronization level." msgstr "Imposta il livello di sincronizzazione della transazione corrente." -#: utils/misc/guc.c:3793 +#: utils/misc/guc.c:4037 msgid "Allows archiving of WAL files using archive_command." msgstr "Consente l'archiviazione dei file WAL con l'uso di archive_command." -#: utils/misc/guc.c:3803 +#: utils/misc/guc.c:4047 msgid "Enables logging of recovery-related debugging information." msgstr "Abilita il logging di informazioni di debug relative al recupero." -#: utils/misc/guc.c:3819 +#: utils/misc/guc.c:4063 msgid "Collects function-level statistics on database activity." msgstr "Raccogli statistiche al livello di funzioni sull'attività del database." -#: utils/misc/guc.c:3829 +#: utils/misc/guc.c:4073 msgid "Set the level of information written to the WAL." msgstr "Imposta il livello delle informazioni scritte nel WAL." -#: utils/misc/guc.c:3839 +#: utils/misc/guc.c:4083 msgid "Selects the dynamic shared memory implementation used." msgstr "Seleziona l'implementazione di memoria dinamica condivisa utilizzata." -#: utils/misc/guc.c:3849 +#: utils/misc/guc.c:4093 msgid "Selects the method used for forcing WAL updates to disk." msgstr "Seleziona il metodo usato per forzare aggiornamenti WAL su disco." -#: utils/misc/guc.c:3859 +#: utils/misc/guc.c:4103 msgid "Sets how binary values are to be encoded in XML." msgstr "imposta come i valori binari devono essere codificati nel formato XML." -#: utils/misc/guc.c:3869 +#: utils/misc/guc.c:4113 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "Imposta se qualunque dato XML nelle operazioni di parsing e serializzazione implicite debba essere considerato come un documento o frammento di un contenuto." -#: utils/misc/guc.c:3880 -msgid "Use of huge pages on Linux." -msgstr "Uso delle pagine huge su Linux." +#: utils/misc/guc.c:4124 +msgid "Use of huge pages on Linux or Windows." +msgstr "Uso di hige pages su Linux o Windows." -#: utils/misc/guc.c:3890 +#: utils/misc/guc.c:4134 msgid "Forces use of parallel query facilities." msgstr "Forza l'uso delle query parallele." -#: utils/misc/guc.c:3891 +#: utils/misc/guc.c:4135 msgid "If possible, run query using a parallel worker and with parallel restrictions." msgstr "Se possibile, effettua le query usando worker paralleli e con restrizioni di parallelismo." -#: utils/misc/guc.c:3900 +#: utils/misc/guc.c:4144 msgid "Encrypt passwords." msgstr "Cripta le password." -#: utils/misc/guc.c:3901 +#: utils/misc/guc.c:4145 msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." msgstr "Quando si indica una password in CREATE USER o ALTER USER senza indicare ENCRYPTED o UNENCRYPTED, questo parametro determina se la password debba essere criptata o meno." -#: utils/misc/guc.c:4703 +#: utils/misc/guc.c:4947 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: accesso alla directory \"%s\" fallito: %s\n" -#: utils/misc/guc.c:4708 +#: utils/misc/guc.c:4952 #, c-format msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" msgstr "Esegui initdb o pg_basebackup per inizializzare una directory di dati PostgreSQL.\n" -#: utils/misc/guc.c:4728 +#: utils/misc/guc.c:4972 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -24143,12 +25190,12 @@ msgstr "" "%s non sa dove trovare il file di configurazione del server.\n" "Devi specificare le opzioni --config-file o -D, oppure impostare la variabile d'ambiente PGDATA.\n" -#: utils/misc/guc.c:4747 +#: utils/misc/guc.c:4991 #, c-format msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s: accesso al file di configurazione del server \"%s\" fallito: %s\n" -#: utils/misc/guc.c:4773 +#: utils/misc/guc.c:5017 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -24157,7 +25204,7 @@ msgstr "" "%s non sa dove trovare i dati di sistema del database.\n" "Possono essere specificati come \"data_directory\" in \"%s\", oppure dall'opzione -D, oppure dalla variabile d'ambiente PGDATA.\n" -#: utils/misc/guc.c:4821 +#: utils/misc/guc.c:5065 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -24166,7 +25213,7 @@ msgstr "" "%s non sa dove trovare il file di configurazione \"hba\".\n" "Può essere specificato come \"hba_file\" in \"%s\", oppure dall'opzione -D, oppure dalla variabile d'ambiente PGDATA.\n" -#: utils/misc/guc.c:4844 +#: utils/misc/guc.c:5088 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -24175,171 +25222,181 @@ msgstr "" "%s non sa dove trovare il file di configurazione \"ident\".\n" "Può essere specificato come \"ident_file\" in \"%s\", oppure dall'opzione -D, oppure dalla variabile d'ambiente PGDATA.\n" -#: utils/misc/guc.c:5518 utils/misc/guc.c:5565 +#: utils/misc/guc.c:5763 utils/misc/guc.c:5810 msgid "Value exceeds integer range." msgstr "Il valore non rientra nel limite possibile per gli interi." -#: utils/misc/guc.c:5788 +#: utils/misc/guc.c:6033 #, c-format msgid "parameter \"%s\" requires a numeric value" msgstr "il parametro \"%s\" richiede un valore numerico" -#: utils/misc/guc.c:5797 +#: utils/misc/guc.c:6042 #, c-format msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" msgstr "%g non è compreso nell'intervallo di validità del il parametro \"%s\" (%g .. %g)" -#: utils/misc/guc.c:5950 utils/misc/guc.c:7296 +#: utils/misc/guc.c:6195 utils/misc/guc.c:7565 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "non è possibile impostare parametri durante un'operazione parallela" -#: utils/misc/guc.c:5957 utils/misc/guc.c:6708 utils/misc/guc.c:6761 -#: utils/misc/guc.c:7124 utils/misc/guc.c:7883 utils/misc/guc.c:8051 -#: utils/misc/guc.c:9727 +#: utils/misc/guc.c:6202 utils/misc/guc.c:6954 utils/misc/guc.c:7007 +#: utils/misc/guc.c:7058 utils/misc/guc.c:7394 utils/misc/guc.c:8161 +#: utils/misc/guc.c:8329 utils/misc/guc.c:10006 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "parametro di configurazione \"%s\" sconosciuto" -#: utils/misc/guc.c:5972 utils/misc/guc.c:7136 +#: utils/misc/guc.c:6217 utils/misc/guc.c:7406 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "il parametro \"%s\" non può essere cambiato" -#: utils/misc/guc.c:5995 utils/misc/guc.c:6188 utils/misc/guc.c:6278 -#: utils/misc/guc.c:6368 utils/misc/guc.c:6476 utils/misc/guc.c:6571 -#: guc-file.l:350 +#: utils/misc/guc.c:6240 utils/misc/guc.c:6434 utils/misc/guc.c:6524 +#: utils/misc/guc.c:6614 utils/misc/guc.c:6722 utils/misc/guc.c:6817 +#: guc-file.l:353 #, c-format msgid "parameter \"%s\" cannot be changed without restarting the server" msgstr "il parametro \"%s\" non può essere cambiato senza riavviare il server" -#: utils/misc/guc.c:6005 +#: utils/misc/guc.c:6250 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "il parametro \"%s\" non può essere cambiato ora" -#: utils/misc/guc.c:6023 utils/misc/guc.c:6069 utils/misc/guc.c:9743 +#: utils/misc/guc.c:6268 utils/misc/guc.c:6315 utils/misc/guc.c:10022 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "permesso di impostare il parametro \"%s\" negato" -#: utils/misc/guc.c:6059 +#: utils/misc/guc.c:6305 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "il parametro \"%s\" non può essere impostato dopo l'avvio della connessione" -#: utils/misc/guc.c:6107 +#: utils/misc/guc.c:6353 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "il parametro \"%s\" non può essere impostato da una funzione che ha i privilegi del creatore" -#: utils/misc/guc.c:6716 utils/misc/guc.c:6766 utils/misc/guc.c:8058 +#: utils/misc/guc.c:6962 utils/misc/guc.c:7012 utils/misc/guc.c:8336 #, c-format msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" msgstr "occorre essere un superutente o un membro di pg_read_all_settings per esaminare \"%s\"" -#: utils/misc/guc.c:6833 +#: utils/misc/guc.c:7103 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s accetta un unico argomento" -#: utils/misc/guc.c:7084 +#: utils/misc/guc.c:7354 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" msgstr "solo un superutente può eseguire il comando ALTER SYSTEM" -#: utils/misc/guc.c:7169 +#: utils/misc/guc.c:7439 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "il valore del parametro di ALTER SYSTEM non può contenere un \"a capo\"" -#: utils/misc/guc.c:7214 +#: utils/misc/guc.c:7484 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "non è possibile analizzare il contenuto del file \"%s\"" -#: utils/misc/guc.c:7372 +#: utils/misc/guc.c:7641 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT non è implementato" -#: utils/misc/guc.c:7456 +#: utils/misc/guc.c:7725 #, c-format msgid "SET requires parameter name" msgstr "SET richiede il nome del parametro" -#: utils/misc/guc.c:7580 +#: utils/misc/guc.c:7858 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "tentativo di ridefinire il parametro \"%s\"" -#: utils/misc/guc.c:9360 +#: utils/misc/guc.c:9639 #, c-format msgid "parameter \"%s\" could not be set" msgstr "il parametro \"%s\" non può essere impostato" -#: utils/misc/guc.c:9447 +#: utils/misc/guc.c:9726 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "non è stato possibile interpretare l'impostazione del parametro \"%s\"" -#: utils/misc/guc.c:9805 utils/misc/guc.c:9839 +#: utils/misc/guc.c:10084 utils/misc/guc.c:10118 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "valore non valido per il parametro \"%s\": %d" -#: utils/misc/guc.c:9873 +#: utils/misc/guc.c:10152 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "valore non valido per il parametro \"%s\": %g" -#: utils/misc/guc.c:10143 +#: utils/misc/guc.c:10422 #, c-format msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." msgstr "\"temp_buffers\" non può essere modificato dopo che la sessione ha utilizzato qualsiasi tabella temporanea." -#: utils/misc/guc.c:10155 +#: utils/misc/guc.c:10434 #, c-format msgid "Bonjour is not supported by this build" msgstr "Bonjour non è supportato in questo binario" -#: utils/misc/guc.c:10168 +#: utils/misc/guc.c:10447 #, c-format msgid "SSL is not supported by this build" msgstr "SSL non è supportato in questo binario" -#: utils/misc/guc.c:10180 +#: utils/misc/guc.c:10459 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "Non è possibile abilitare il parametro quando \"log_statement_stats\" è abilitato." -#: utils/misc/guc.c:10192 +#: utils/misc/guc.c:10471 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "Non è possibile abilitare \"log_statement_stats\" quando \"log_parser_stats\", \"log_planner_stats\" o \"log_executor_stats\" sono abilitati." +#: utils/misc/guc.c:10687 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgstr "effective_io_concurrency deve essere impostato a 0 su piattaforme che non hanno posix_fadvise()" + #: utils/misc/help_config.c:131 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "errore interno: tipo di parametro sconosciuto\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format msgid "query-specified return tuple and function return type are not compatible" msgstr "la tupla che la query specifica e il tipo restituito dalla funzione non sono compatibili" -#: utils/misc/pg_controldata.c:58 utils/misc/pg_controldata.c:138 -#: utils/misc/pg_controldata.c:244 utils/misc/pg_controldata.c:311 +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "il CRC di controllo calcolato non combacia con quello nel file" -#: utils/misc/rls.c:128 +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: utente: %d.%02d s, sistema: %d.%02d s, passati: %d.%02d s" + +#: utils/misc/rls.c:127 #, c-format msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "la query sarebbe influenzata dalla regola di sicurezza per riga pre la tabella \"%s\"" -#: utils/misc/rls.c:130 +#: utils/misc/rls.c:129 #, c-format msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "Per disabilitare la regola di sicurezza per il proprietario della tabella usa ALTER TABLE NO FORCE ROW LEVEL SECURITY." @@ -24414,75 +25471,103 @@ msgstr "la riga è troppo lunga nel file di fusi orari \"%s\", riga %d" msgid "@INCLUDE without file name in time zone file \"%s\", line %d" msgstr "@INCLUDE senza nome del file nel file di fusi orari \"%s\", riga %d" -#: utils/mmgr/aset.c:405 +#: utils/mmgr/aset.c:483 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "Errore durante la creazione del contesto di memoria \"%s\"." -#: utils/mmgr/dsa.c:518 utils/mmgr/dsa.c:1323 +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1325 #, c-format msgid "could not attach to dynamic shared area" msgstr "collegamento all'area dinamica condivisa fallito" -#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 -#, c-format -msgid "Failed on DSA request of size %zu." -msgstr "Errore su richiesta DSA di dimensione %zu." - -#: utils/mmgr/mcxt.c:726 utils/mmgr/mcxt.c:761 utils/mmgr/mcxt.c:798 -#: utils/mmgr/mcxt.c:835 utils/mmgr/mcxt.c:869 utils/mmgr/mcxt.c:898 -#: utils/mmgr/mcxt.c:932 utils/mmgr/mcxt.c:983 utils/mmgr/mcxt.c:1017 -#: utils/mmgr/mcxt.c:1051 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 #, c-format -msgid "Failed on request of size %zu." -msgstr "Errore durante la richiesta di dimensione %zu." +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Errore durante la richiesta di dimensione %zu nel contesto di memoria \"%s\"." -#: utils/mmgr/portalmem.c:186 +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "il cursore \"%s\" esiste già" -#: utils/mmgr/portalmem.c:190 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "chiusura del cursore esistente \"%s\"" -#: utils/mmgr/portalmem.c:394 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "il portale \"%s\" non può essere eseguito" -#: utils/mmgr/portalmem.c:474 +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "non è possibile eliminare il portale pinned \"%s\"" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "non è possibile eliminare il portale attivo \"%s\"" -#: utils/mmgr/portalmem.c:678 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "non è possibile eseguire PREPARE in una transazione che ha creato un cursore WITH HOLD" -#: utils/sort/logtape.c:252 +#: utils/mmgr/portalmem.c:1263 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "non è possibile eseguire comandi di transazioni in un loop su cursore che non sia di sola lettura" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "lettura del blocco %ld dal file temporaneo fallita: %m" -#: utils/sort/tuplesort.c:3072 +#: utils/sort/logtape.c:439 +#, c-format +msgid "could not determine size of temporary file \"%s\"" +msgstr "determinazione della dimensione del file temporaneo \"%s\" fallita" + +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "scrittura nel file temporaneo fallita: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "errore nella lettura dal file temporaneo tuplestore condiviso" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "blocco non previsto nel file temporaneo tuplestore condiviso" + +#: utils/sort/tuplesort.c:2967 #, c-format msgid "cannot have more than %d runs for an external sort" msgstr "non è possibile avere più di %d esecuzioni per un sort esterno" -#: utils/sort/tuplesort.c:4141 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "creazione dell'indice univoco \"%s\" fallita" -#: utils/sort/tuplesort.c:4143 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "La chiave %s è duplicata." -#: utils/sort/tuplesort.c:4144 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "Esistono chiavi duplicate." @@ -24508,538 +25593,559 @@ msgstr "lettura dal file temporaneo tuplestore fallita: %m" msgid "could not write to tuplestore temporary file: %m" msgstr "scrittura nel file temporaneo tuplestore fallita: %m" -#: utils/time/snapmgr.c:618 +#: utils/time/snapmgr.c:622 #, c-format msgid "The source transaction is not running anymore." msgstr "La transazione di origine non è più in esecuzione." # translator: %s represents an SQL statement name -#: utils/time/snapmgr.c:1198 +#: utils/time/snapmgr.c:1200 #, c-format msgid "cannot export a snapshot from a subtransaction" msgstr "non è possibile esportare uno snapshot da una sotto-transazione" -#: utils/time/snapmgr.c:1347 utils/time/snapmgr.c:1352 -#: utils/time/snapmgr.c:1357 utils/time/snapmgr.c:1372 -#: utils/time/snapmgr.c:1377 utils/time/snapmgr.c:1382 -#: utils/time/snapmgr.c:1481 utils/time/snapmgr.c:1497 -#: utils/time/snapmgr.c:1522 +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 +#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 +#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 +#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 +#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 #, c-format msgid "invalid snapshot data in file \"%s\"" msgstr "dati dello snapshot non validi nel file \"%s\"" -#: utils/time/snapmgr.c:1419 +#: utils/time/snapmgr.c:1456 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "SET TRANSACTION SNAPSHOT dev'essere invocato prima di qualunque query" -#: utils/time/snapmgr.c:1428 +#: utils/time/snapmgr.c:1465 #, c-format msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" msgstr "una transazione che importa uno snapshot deve avere livello di isolamento SERIALIZABLE o REPEATABLE READ" -#: utils/time/snapmgr.c:1437 utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 #, c-format msgid "invalid snapshot identifier: \"%s\"" msgstr "identificativo di snapshot non valido: \"%s\"" -#: utils/time/snapmgr.c:1535 +#: utils/time/snapmgr.c:1573 #, c-format msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" msgstr "una transazione serializzabile non può importare uno snapshot da una transazione non serializzabile" -#: utils/time/snapmgr.c:1539 +#: utils/time/snapmgr.c:1577 #, c-format msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" msgstr "una transazione non di sola lettura non può importare uno snapshot da una transazione di sola lettura" -#: utils/time/snapmgr.c:1554 +#: utils/time/snapmgr.c:1592 #, c-format msgid "cannot import a snapshot from a different database" msgstr "non è possibile importare uno snapshot da un database diverso" -#: gram.y:1008 +#: gram.y:1026 #, c-format msgid "UNENCRYPTED PASSWORD is no longer supported" msgstr "UNENCRYPTED PASSWORD non è più supportato" -#: gram.y:1009 +#: gram.y:1027 #, c-format msgid "Remove UNENCRYPTED to store the password in encrypted form instead." msgstr "Rimuovi UNENCRYPTED per memorizzare la password in formato criptato." -#: gram.y:1071 +#: gram.y:1089 #, c-format msgid "unrecognized role option \"%s\"" msgstr "opzione di ruolo \"%s\" sconosciuta" -#: gram.y:1345 gram.y:1360 +#: gram.y:1336 gram.y:1351 #, c-format msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTS non può includere elementi dello schema" -#: gram.y:1505 +#: gram.y:1496 #, c-format msgid "current database cannot be changed" msgstr "il database corrente non può essere cambiato" -#: gram.y:1629 +#: gram.y:1620 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" msgstr "l'intervallo della time zone deve essere HOUR o HOUR TO MINUTE" -#: gram.y:2644 +#: gram.y:2138 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "i numeri di colonne devono essere nell'intervallo tra 1 e %d" + +#: gram.y:2677 #, c-format msgid "sequence option \"%s\" not supported here" msgstr "l'opzione della sequenza \"%s\" non è supportata qui" -#: gram.y:2857 gram.y:2886 +#: gram.y:2706 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "modulo per partizione hash fornito più di una volta" + +#: gram.y:2715 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "resto per partizione hash fornito più di una volta" + +#: gram.y:2722 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "specifica di vincolo di partizione hash \"%s\" non riconosciuto" + +#: gram.y:2730 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "il modulo per la partizione hash deve essere specificato" + +#: gram.y:2734 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "il resto per la partizione hash deve essere specificato" + +#: gram.y:2986 gram.y:3015 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "STDIN/STDOUT non sono consentiti con PROGRAM" -#: gram.y:3196 gram.y:3203 gram.y:11092 gram.y:11100 +#: gram.y:3325 gram.y:3332 gram.y:11465 gram.y:11473 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "GLOBAL è deprecato nella creazione di tabelle temporanee" -#: gram.y:5128 +#: gram.y:5299 #, c-format msgid "unrecognized row security option \"%s\"" msgstr "opzione di sicurezza riga \"%s\" non riconosciuta" -#: gram.y:5129 +#: gram.y:5300 #, c-format msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." msgstr "Solo le regole PERMISSIVE o RESTRICTIVE sono attualmente supportate." -#: gram.y:5237 +#: gram.y:5408 msgid "duplicate trigger events specified" msgstr "evento del trigger specificato più volte" -#: gram.y:5380 +#: gram.y:5556 #, c-format msgid "conflicting constraint properties" msgstr "proprietà del vincolo in conflitto" -#: gram.y:5486 +#: gram.y:5662 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "CREATE ASSERTION non è stata ancora implementata" -#: gram.y:5501 +#: gram.y:5677 #, c-format msgid "DROP ASSERTION is not yet implemented" msgstr "DROP ASSERTION non è stata ancora implementata" -#: gram.y:5881 +#: gram.y:6057 #, c-format msgid "RECHECK is no longer required" msgstr "RECHECK non è più richiesto" -#: gram.y:5882 +#: gram.y:6058 #, c-format msgid "Update your data type." msgstr "Aggiorna il tuo tipo di dato." -#: gram.y:7525 +#: gram.y:7794 #, c-format msgid "aggregates cannot have output arguments" msgstr "gli aggregati non possono avere argomenti di output" -#: gram.y:9667 gram.y:9685 +#: gram.y:10048 gram.y:10066 #, c-format msgid "WITH CHECK OPTION not supported on recursive views" msgstr "WITH CHECK OPTION non supportato su viste ricorsive" -#: gram.y:10218 +#: gram.y:10563 #, c-format msgid "unrecognized VACUUM option \"%s\"" msgstr "opzione di VACUUM \"%s\" sconosciuta" -#: gram.y:11200 +#: gram.y:11573 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "La sintassi LIMIT #,# non è supportata" -#: gram.y:11201 +#: gram.y:11574 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "Usa separatamente le clausole LIMIT ed OFFSET." -#: gram.y:11482 gram.y:11507 +#: gram.y:11872 gram.y:11897 #, c-format msgid "VALUES in FROM must have an alias" msgstr "VALUES nel FROM deve avere un alias" -#: gram.y:11483 gram.y:11508 +#: gram.y:11873 gram.y:11898 #, c-format msgid "For example, FROM (VALUES ...) [AS] foo." msgstr "Per esempio, FROM (VALUES ...) [AS] foo." -#: gram.y:11488 gram.y:11513 +#: gram.y:11878 gram.y:11903 #, c-format msgid "subquery in FROM must have an alias" msgstr "la sottoquery in FROM deve avere un alias" -#: gram.y:11489 gram.y:11514 +#: gram.y:11879 gram.y:11904 #, c-format msgid "For example, FROM (SELECT ...) [AS] foo." msgstr "Per esempio, FROM (SELECT ...) [AS] foo." -#: gram.y:11968 +#: gram.y:12358 #, c-format msgid "only one DEFAULT value is allowed" msgstr "solo un valore DEFAULT è consentito" -#: gram.y:11977 +#: gram.y:12367 #, c-format msgid "only one PATH value per column is allowed" msgstr "solo un valore PATH per colonna è consentito" -#: gram.y:11986 +#: gram.y:12376 #, c-format msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" msgstr "dichiarazioni NULL / NOT NULL in conflitto o ridondanti per la colonna \"%s\"" -#: gram.y:11995 +#: gram.y:12385 #, c-format msgid "unrecognized column option \"%s\"" msgstr "opzione di colonna \"%s\" non riconosciuta" -#: gram.y:12249 +#: gram.y:12639 #, c-format msgid "precision for type float must be at least 1 bit" msgstr "la precisione per il tipo float dev'essere di almeno un bit" -#: gram.y:12258 +#: gram.y:12648 #, c-format msgid "precision for type float must be less than 54 bits" msgstr "la precisione per il tipo float dev'essere inferiore a 54 bit" -#: gram.y:12749 +#: gram.y:13139 #, c-format msgid "wrong number of parameters on left side of OVERLAPS expression" msgstr "numero errato di parametri a sinistra dell'espressione OVERLAPS" -#: gram.y:12754 +#: gram.y:13144 #, c-format msgid "wrong number of parameters on right side of OVERLAPS expression" msgstr "numero errato di parametri a destra dell'espressione OVERLAPS" -#: gram.y:12929 +#: gram.y:13319 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "il predicato UNIQUE non è stato ancora implementato" -#: gram.y:13276 +#: gram.y:13666 #, c-format msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" msgstr "non si può usare più di una clausola ORDER BY con WITHIN GROUOP" -#: gram.y:13281 +#: gram.y:13671 #, c-format msgid "cannot use DISTINCT with WITHIN GROUP" msgstr "non si può usare DISTINCT con WITHIN GROUP" -#: gram.y:13286 +#: gram.y:13676 #, c-format msgid "cannot use VARIADIC with WITHIN GROUP" msgstr "non si può usare VARIADIC con WITHIN GROUP" -#: gram.y:13712 -#, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING è supportato solo con UNBOUNDED" - -#: gram.y:13718 -#, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING è supportato solo con UNBOUNDED" - -#: gram.y:13745 gram.y:13768 +#: gram.y:14129 gram.y:14152 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" msgstr "l'inizio della finestra non può essere UNBOUNDED FOLLOWING" -#: gram.y:13750 +#: gram.y:14134 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "una finestra che inizia dalla riga seguente non può terminare alla riga corrente" -#: gram.y:13773 +#: gram.y:14157 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" msgstr "la fine della finestra non può essere UNBOUNDED PRECEDING" -#: gram.y:13779 +#: gram.y:14163 #, c-format msgid "frame starting from current row cannot have preceding rows" msgstr "una finestra che inizia dalla riga corrente non può avere righe precedenti" -#: gram.y:13786 +#: gram.y:14170 #, c-format msgid "frame starting from following row cannot have preceding rows" msgstr "una finestra che inizia dalla riga seguente non può avere righe precedenti" -#: gram.y:14421 +#: gram.y:14813 #, c-format msgid "type modifier cannot have parameter name" msgstr "un modificatore di tipo non può avere un nome di parametro" -#: gram.y:14427 +#: gram.y:14819 #, c-format msgid "type modifier cannot have ORDER BY" msgstr "un modificatore di tipo non può avere ORDER BY" -#: gram.y:14491 gram.y:14497 +#: gram.y:14884 gram.y:14891 #, c-format msgid "%s cannot be used as a role name here" msgstr "%s non può essere usato come nome di ruolo qui" -#: gram.y:15159 gram.y:15348 +#: gram.y:15562 gram.y:15751 msgid "improper use of \"*\"" msgstr "uso improprio di \"*\"" -#: gram.y:15412 +#: gram.y:15815 #, c-format msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" msgstr "un aggregato su insiemi ordinati con un argomento diretto VARIADIC deve avere un argomento aggregato VARIADIC sullo stesso tipo" -#: gram.y:15449 +#: gram.y:15852 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "non è possibile avere più di una clausola ORDER BY" -#: gram.y:15460 +#: gram.y:15863 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "non è possibile avere più di una clausola OFFSET" -#: gram.y:15469 +#: gram.y:15872 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "non è possibile avere più di una clausola LIMIT" -#: gram.y:15478 +#: gram.y:15881 #, c-format msgid "multiple WITH clauses not allowed" msgstr "non è possibile avere più di una clausola WITH" -#: gram.y:15682 +#: gram.y:16085 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "gli argomenti OUT e INOUT non sono permessi nelle funzioni TABLE" -#: gram.y:15783 +#: gram.y:16186 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "non è possibile avere più di una clausola COLLATE" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15821 gram.y:15834 +#: gram.y:16224 gram.y:16237 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "un vincolo %s non può essere marcato DEFERRABLE" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15847 +#: gram.y:16250 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "un vincolo %s non può essere marcato NOT VALID" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15860 +#: gram.y:16263 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "un vincolo %s non può essere marcato NO INHERIT" -#: guc-file.l:313 +#: guc-file.l:316 #, c-format msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" msgstr "parametro di configurazione \"%s\" sconosciuto nel file \"%s\" riga %u" -#: guc-file.l:386 +#: guc-file.l:389 #, c-format msgid "parameter \"%s\" removed from configuration file, reset to default" msgstr "il parametro \"%s\" è stato rimosso dal file di configurazione, valore predefinito ripristinato" -#: guc-file.l:452 +#: guc-file.l:455 #, c-format msgid "parameter \"%s\" changed to \"%s\"" msgstr "il parametro \"%s\" è stato modificato a \"%s\"" -#: guc-file.l:494 +#: guc-file.l:497 #, c-format msgid "configuration file \"%s\" contains errors" msgstr "il file di configurazione \"%s\" contiene errori" -#: guc-file.l:499 +#: guc-file.l:502 #, c-format msgid "configuration file \"%s\" contains errors; unaffected changes were applied" msgstr "il file di configurazione \"%s\" contiene errori; i cambiamenti senza errori sono stati applicati" -#: guc-file.l:504 +#: guc-file.l:507 #, c-format msgid "configuration file \"%s\" contains errors; no changes were applied" msgstr "il file di configurazione \"%s\" contiene errori; nessun cambiamento effettuato" -#: guc-file.l:577 +#: guc-file.l:580 #, c-format msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" msgstr "apertura del file di configurazione \"%s\" fallita: massima profondità di annidamento raggiunta" -#: guc-file.l:604 +#: guc-file.l:607 #, c-format msgid "skipping missing configuration file \"%s\"" msgstr "file di configurazione mancante \"%s\" saltato" -#: guc-file.l:858 +#: guc-file.l:861 #, c-format msgid "syntax error in file \"%s\" line %u, near end of line" msgstr "errore di sintassi nel file \"%s\" riga %u, vicino alla fine della riga" -#: guc-file.l:868 +#: guc-file.l:871 #, c-format msgid "syntax error in file \"%s\" line %u, near token \"%s\"" msgstr "errore di sintassi nel file \"%s\" riga %u, vicino al token \"%s\"" -#: guc-file.l:888 +#: guc-file.l:891 #, c-format msgid "too many syntax errors found, abandoning file \"%s\"" msgstr "troppi errori di sintassi, file \"%s\" abbandonato" -#: guc-file.l:940 +#: guc-file.l:943 #, c-format msgid "could not open configuration directory \"%s\": %m" msgstr "apertura della directory di configurazione \"%s\" fallita: %m" -#: repl_gram.y:320 repl_gram.y:352 +#: repl_gram.y:336 repl_gram.y:368 #, c-format msgid "invalid timeline %u" msgstr "timeline %u non valida" -#: repl_scanner.l:125 +#: repl_scanner.l:129 msgid "invalid streaming start location" msgstr "posizione di avvio dello streaming non valida" -#: repl_scanner.l:176 scan.l:670 +#: repl_scanner.l:180 scan.l:683 msgid "unterminated quoted string" msgstr "stringa tra virgolette non terminata" -#: scan.l:432 +#: scan.l:445 msgid "unterminated /* comment" msgstr "commento /* non terminato" -#: scan.l:461 +#: scan.l:474 msgid "unterminated bit string literal" msgstr "letterale di stringa di bit non terminato" -#: scan.l:482 +#: scan.l:495 msgid "unterminated hexadecimal string literal" msgstr "letterale di stringa esadecimale non terminato" -#: scan.l:532 +#: scan.l:545 #, c-format msgid "unsafe use of string constant with Unicode escapes" msgstr "uso non sicuro di stringa costante con gli escape Unicode" -#: scan.l:533 +#: scan.l:546 #, c-format msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." msgstr "Le stringhe costanti con escape Unicode non possono essere usate quando standard_conforming_strings è disabilitato." -#: scan.l:579 scan.l:778 +#: scan.l:592 scan.l:791 msgid "invalid Unicode escape character" msgstr "carattere escape Unicode non valido" -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1337 -#: scan.l:1364 scan.l:1368 scan.l:1406 scan.l:1410 scan.l:1432 scan.l:1442 +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 +#: scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 msgid "invalid Unicode surrogate pair" msgstr "coppia surrogata Unicode non valida" -#: scan.l:627 +#: scan.l:640 #, c-format msgid "invalid Unicode escape" msgstr "escape Unicode non valido" -#: scan.l:628 +#: scan.l:641 #, c-format msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." msgstr "Gli escape Unicode devono essere \\uXXXX or \\UXXXXXXXX." -#: scan.l:639 +#: scan.l:652 #, c-format msgid "unsafe use of \\' in a string literal" msgstr "uso non sicuro di \\' in una stringa letterale" -#: scan.l:640 +#: scan.l:653 #, c-format msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." msgstr "Usa '' per scrivere gli apici in una stringa. \\' non è sicuro in codifiche solo client." -#: scan.l:715 +#: scan.l:728 msgid "unterminated dollar-quoted string" msgstr "stringa delimitata da dollari non terminata" -#: scan.l:732 scan.l:758 scan.l:773 +#: scan.l:745 scan.l:771 scan.l:786 msgid "zero-length delimited identifier" msgstr "identificativo delimitato di lunghezza zero" -#: scan.l:793 syncrep_scanner.l:89 +#: scan.l:806 syncrep_scanner.l:91 msgid "unterminated quoted identifier" msgstr "identificativo tra virgolette non terminato" -#: scan.l:924 +#: scan.l:969 msgid "operator too long" msgstr "operatore troppo lungo" #. translator: %s is typically the translation of "syntax error" -#: scan.l:1077 +#: scan.l:1125 #, c-format msgid "%s at end of input" msgstr "%s alla fine dell'input" #. translator: first %s is typically the translation of "syntax error" -#: scan.l:1085 +#: scan.l:1133 #, c-format msgid "%s at or near \"%s\"" msgstr "%s a o presso \"%s\"" -#: scan.l:1251 scan.l:1283 +#: scan.l:1294 scan.l:1326 msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" msgstr "i valori escape Unicode non possono essere usati per code point superiori a 007F se la codifica del server non è UTF8" -#: scan.l:1279 scan.l:1424 +#: scan.l:1322 scan.l:1467 msgid "invalid Unicode escape value" msgstr "valore escape Unicode non valido" -#: scan.l:1488 +#: scan.l:1531 #, c-format msgid "nonstandard use of \\' in a string literal" msgstr "uso non standard di \\' in una stringa letterale" -#: scan.l:1489 +#: scan.l:1532 #, c-format msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." msgstr "Usa '' per scrivere gli apici nelle stringhe, oppure usa la sintassi di escape delle stringhe (E'...')." -#: scan.l:1498 +#: scan.l:1541 #, c-format msgid "nonstandard use of \\\\ in a string literal" msgstr "uso non standard di \\\\ in una stringa letterale" -#: scan.l:1499 +#: scan.l:1542 #, c-format msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." msgstr "Usa la sintassi di escape delle stringhe per i backslash, cioè E'\\\\'." -#: scan.l:1513 +#: scan.l:1556 #, c-format msgid "nonstandard use of escape in a string literal" msgstr "uso non standard dell'escape in una stringa letterale" -#: scan.l:1514 +#: scan.l:1557 #, c-format msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." msgstr "Usa la sintassi di escape per le stringhe per effettuare gli escape, cioè, E'\\r\\n'." diff --git a/src/backend/po/ja.po b/src/backend/po/ja.po index 2fa5d48a826..7fd1142fdd4 100644 --- a/src/backend/po/ja.po +++ b/src/backend/po/ja.po @@ -1,331 +1,706 @@ # backend.po +# Japanese message translation file for backend +# +# Copyright (C) 2011-2018 PostgreSQL Global Development Group +# # HOTTA Michihide , 2011. +# Kyotaro Horiguchi , 2018. +# +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.1 beta 2\n" +"Project-Id-Version: PostgreSQL 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 13:05+0900\n" -"PO-Revision-Date: 2014-08-16 16:41+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-12-19 01:11+0000\n" +"PO-Revision-Date: 2018-10-12 14:04+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.5.4\n" -#: ../port/chklocale.c:258 -#, c-format -#| msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" -msgid "could not determine encoding for codeset \"%s\"" -msgstr "コードセット\"%s\"用ã®ç¬¦å·åŒ–æ–¹å¼ã‚’決定ã§ãã¾ã›ã‚“" - -#: ../port/chklocale.c:259 ../port/chklocale.c:388 -#, c-format -msgid "Please report this to ." -msgstr "ã“れをã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。" - -#: ../port/chklocale.c:380 ../port/chklocale.c:386 -#, c-format -msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" -msgstr "ロケール\"%s\"用ã®ç¬¦å·åŒ–æ–¹å¼ã‚’決定ã§ãã¾ã›ã‚“: コードセットã¯\"%s\"ã§ã™" +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 +msgid "not recorded" +msgstr "記録ã•れã¦ã„ã¾ã›ã‚“" -#: ../port/dirmod.c:217 +#: ../common/controldata_utils.c:58 commands/copy.c:3189 +#: commands/extension.c:3330 utils/adt/genfile.c:151 #, c-format -msgid "could not set junction for \"%s\": %s" -msgstr "\"%s\"ã®æŽ¥åˆã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "could not open file \"%s\" for reading: %m" +msgstr "ファイル\"%s\"を読ã¿å–り用ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: ../port/dirmod.c:220 +#: ../common/controldata_utils.c:62 #, c-format -msgid "could not set junction for \"%s\": %s\n" -msgstr "\"%s\"ã®æŽ¥åˆã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: ファイル\"%s\"を読ã¿å–り用ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: ../port/dirmod.c:292 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 +#: access/transam/xlog.c:3440 access/transam/xlog.c:10942 +#: access/transam/xlog.c:10955 access/transam/xlog.c:11380 +#: access/transam/xlog.c:11460 access/transam/xlog.c:11499 +#: access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 +#: access/transam/xlogfuncs.c:677 commands/extension.c:3340 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3304 replication/walsender.c:510 +#: storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format -msgid "could not get junction for \"%s\": %s" -msgstr "\"%s\" ã®åˆ†å²ç‚¹ (junction) ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "could not read file \"%s\": %m" +msgstr "ファイル\"%s\"ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: ../port/dirmod.c:295 +#: ../common/controldata_utils.c:78 #, c-format -msgid "could not get junction for \"%s\": %s\n" -msgstr "\"%s\"ã®junctionを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: ../port/dirmod.c:377 +#: ../common/controldata_utils.c:86 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "could not read file \"%s\": read %d of %d" +msgstr "ファイル\"%1$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %3$dãƒã‚¤ãƒˆã®ã†ã¡%2$dãƒã‚¤ãƒˆã‚’読ã¿è¾¼ã¿ã¾ã—ãŸ" -#: ../port/dirmod.c:414 +#: ../common/controldata_utils.c:90 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "ディレクトリ\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%1$s: ファイル\"%2$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %4$dãƒã‚¤ãƒˆã®ã†ã¡%3$dãƒã‚¤ãƒˆã‚’読ã¿è¾¼ã¿ã¾ã—ãŸ\n" -#: ../port/dirmod.c:497 -#, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "\"%s\"ã¨ã„ã†ãƒ•ァイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" +#: ../common/controldata_utils.c:112 +msgid "byte ordering mismatch" +msgstr "ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒåˆã£ã¦ã„ã¾ã›ã‚“" -#: ../port/dirmod.c:524 ../port/dirmod.c:541 +#: ../common/controldata_utils.c:114 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "\"%s\"ã¨ã„ã†ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¾ãŸã¯ãƒ•ァイルを削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory.\n" +msgstr "" +"警告:ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒç•°ãªã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n" +"pg_controlファイルを格ç´ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒæœ¬ãƒ—ログラムã§ä½¿ç”¨\n" +"ã•れるもã®ã¨ç•°ãªã£ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ã“ã®å ´åˆä»¥ä¸‹ã®çµæžœã¯ä¸æ­£ç¢ºã«ãªã‚Šã¾ã™ã€‚ã¾ãŸã€PostgreSQL\n" +"インストレーションã¯ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨äº’æ›æ€§ãŒãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。\n" -#: ../port/exec.c:127 ../port/exec.c:241 ../port/exec.c:284 +#: ../common/exec.c:127 ../common/exec.c:241 ../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" -msgstr "ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’èªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgstr "カレントディレクトリをèªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../port/exec.c:146 +#: ../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" -msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"ã¯ç„¡åйã§ã™" +msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"ã¯ä¸æ­£ã§ã™" -#: ../port/exec.c:195 +#: ../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ" -#: ../port/exec.c:202 +#: ../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" -msgstr "実行ã™ã‚‹\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" +msgstr "実行ã™ã¹ã\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: ../port/exec.c:257 ../port/exec.c:293 +#: ../common/exec.c:257 ../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../port/exec.c:272 +#: ../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "シンボリックリンク\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ" -#: ../port/exec.c:523 +#: ../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "pcloseãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: ../port/open.c:112 +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 +#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 +#: utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 +#: utils/misc/ps_status.c:217 #, c-format -msgid "could not open file \"%s\": %s" -msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "out of memory\n" +msgstr "メモリä¸è¶³ã§ã™\n" -#: ../port/open.c:113 -msgid "lock violation" -msgstr "ロックé•å" +#: ../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nullãƒã‚¤ãƒ³ã‚¿ã¯è¤‡è£½ã§ãã¾ã›ã‚“(内部エラー)\n" -#: ../port/open.c:113 -msgid "sharing violation" -msgstr "共有é•å" +#: ../common/file_utils.c:82 ../common/file_utils.c:186 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\"ファイルã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: ../port/open.c:114 +#: ../common/file_utils.c:162 #, c-format -msgid "Continuing to retry for 30 seconds." -msgstr "å†è©¦è¡Œã‚’30ç§’ç¶šã‘ã¾ã™" +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: ../port/open.c:115 +#: ../common/file_utils.c:198 #, c-format -msgid "You might have antivirus, backup, or similar software interfering with the database system." -msgstr "データベースシステムã«å¹²æ¸‰ã™ã‚‹ã‚¢ãƒ³ãƒã‚¦ã‚£ãƒ«ã‚¹ã€ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãªã©ã®ã‚½ãƒ•トウェアãŒå­˜åœ¨ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" -#: ../port/strerror.c:25 +#: ../common/file_utils.c:231 ../common/file_utils.c:291 +#: ../common/file_utils.c:367 #, c-format -msgid "unrecognized error %d" -msgstr "䏿˜Žãªã‚¨ãƒ©ãƒ¼ %d" +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/file_utils.c:304 ../common/file_utils.c:376 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/pgfnames.c:45 +#, c-format +msgid "could not open directory \"%s\": %s\n" +msgstr "ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/pgfnames.c:72 +#, c-format +msgid "could not read directory \"%s\": %s\n" +msgstr "ディレクトリ\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/pgfnames.c:84 +#, c-format +msgid "could not close directory \"%s\": %s\n" +msgstr "ディレクトリ\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6482 +#: lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 +#: libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2390 +#: postmaster/postmaster.c:2412 postmaster/postmaster.c:3979 +#: postmaster/postmaster.c:4687 postmaster/postmaster.c:4762 +#: postmaster/postmaster.c:5454 postmaster/postmaster.c:5791 +#: replication/libpqwalreceiver/libpqwalreceiver.c:260 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:781 storage/file/fd.c:1220 storage/file/fd.c:1381 +#: storage/file/fd.c:2294 storage/ipc/procarray.c:1066 +#: storage/ipc/procarray.c:1554 storage/ipc/procarray.c:1561 +#: storage/ipc/procarray.c:1982 storage/ipc/procarray.c:2606 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 +#: utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 +#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4240 utils/misc/guc.c:4256 utils/misc/guc.c:4269 +#: utils/misc/guc.c:7244 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 utils/mmgr/generation.c:249 +#: utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 +#: utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 utils/mmgr/mcxt.c:975 +#: utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 +#: utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 +#, c-format +msgid "out of memory" +msgstr "メモリä¸è¶³ã§ã™" + +#: ../common/relpath.c:58 +#, c-format +msgid "invalid fork name" +msgstr "䏿­£ãªãƒ•ォークåã§ã™" + +#: ../common/relpath.c:59 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "有効ãªãƒ•ォークåã¯\"main\"ã€\"fsm\"ã€\"vm\"ãŠã‚ˆã³\"init\"ã§ã™ã€‚" + +#: ../common/restricted_token.c:68 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: 警告: ã“ã®ãƒ—ラットフォームã§ã¯åˆ¶é™ä»˜ãトークンを作æˆã§ãã¾ã›ã‚“\n" + +#: ../common/restricted_token.c:77 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: プロセストークンをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../common/restricted_token.c:90 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: SIDを割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../common/restricted_token.c:110 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: 制é™ä»˜ãトークンを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../common/restricted_token.c:132 +#, c-format +msgid "%s: could not start process for command \"%s\": error code %lu\n" +msgstr "%s: \"%s\"コマンド用ã®ãƒ—ロセスを起動ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../common/restricted_token.c:170 +#, c-format +msgid "%s: could not re-execute with restricted token: error code %lu\n" +msgstr "%s: 制é™ä»˜ãトークンã§å†å®Ÿè¡Œã§ãã¾ã›ã‚“ã§ã—ãŸ: %lu\n" -#: ../port/wait_error.c:47 +#: ../common/restricted_token.c:186 +#, c-format +msgid "%s: could not get exit code from subprocess: error code %lu\n" +msgstr "%s: サブプロセスã®çµ‚了コードをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: エラーコード %lu\n" + +#: ../common/rmtree.c:77 +#, c-format +msgid "could not stat file or directory \"%s\": %s\n" +msgstr "ファイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: ../common/rmtree.c:104 ../common/rmtree.c:121 +#, c-format +msgid "could not remove file or directory \"%s\": %s\n" +msgstr "ディレクトリã¾ãŸã¯ãƒ•ァイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "パスワードãŒé•·ã™ãŽã¾ã™" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "実効ユーザID %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: ../common/username.c:45 libpq/auth.c:2038 +msgid "user does not exist" +msgstr "ユーザãŒå­˜åœ¨ã—ã¾ã›ã‚“" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "ユーザåã®å‚ç…§ã«å¤±æ•—: エラーコード %lu" + +#: ../common/wait_error.c:45 #, c-format msgid "command not executable" -msgstr "コマンドã¯å®Ÿè¡Œå½¢å¼ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "コマンドã¯å®Ÿè¡Œå¯èƒ½å½¢å¼ã§ã¯ã‚りã¾ã›ã‚“" -#: ../port/wait_error.c:51 +#: ../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "コマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: ../port/wait_error.c:56 +#: ../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "å­ãƒ—ロセスãŒçµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" -#: ../port/wait_error.c:63 +#: ../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "å­ãƒ—ロセスãŒä¾‹å¤–0x%Xã§çµ‚了ã—ã¾ã—ãŸ" -#: ../port/wait_error.c:73 +#: ../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" -msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%sã§çµ‚了ã—ã¾ã—ãŸ" +msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%sã«ã‚ˆã‚Šçµ‚了ã—ã¾ã—ãŸ" -#: ../port/wait_error.c:77 +#: ../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "å­ãƒ—ロセスã¯ã‚·ã‚°ãƒŠãƒ«%dã«ã‚ˆã‚Šçµ‚了ã—ã¾ã—ãŸ" -#: ../port/wait_error.c:82 +#: ../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" -msgstr "å­ãƒ—ロセスã¯ä¸æ˜Žã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹%dã§çµ‚了ã—ã¾ã—ãŸ" +msgstr "å­ãƒ—ロセスã¯èªè­˜ã§ããªã„ステータス%dã§çµ‚了ã—ã¾ã—ãŸ" + +#: ../port/chklocale.c:288 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "コードセット\"%s\"用ã®ç¬¦å·åŒ–æ–¹å¼ã‚’決定ã§ãã¾ã›ã‚“" + +#: ../port/chklocale.c:409 ../port/chklocale.c:415 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "ロケール\"%s\"用ã®ç¬¦å·åŒ–æ–¹å¼ã‚’決定ã§ãã¾ã›ã‚“: コードセットã¯\"%s\"ã§ã™" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "\"%s\"ã®ã‚¸ãƒ£ãƒ³ã‚¯ã‚·ãƒ§ãƒ³ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\"ã®ã‚¸ãƒ£ãƒ³ã‚¯ã‚·ãƒ§ãƒ³ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "\"%s\"ã®ã‚¸ãƒ£ãƒ³ã‚¯ã‚·ãƒ§ãƒ³ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\"ã®ã‚¸ãƒ£ãƒ³ã‚¯ã‚·ãƒ§ãƒ³ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../port/open.c:111 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: ../port/open.c:112 +msgid "lock violation" +msgstr "ロックé•å" + +#: ../port/open.c:112 +msgid "sharing violation" +msgstr "共有é•å" -#: ../port/win32error.c:188 +#: ../port/open.c:113 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "å†è©¦è¡Œã‚’30ç§’é–“ç¶šã‘ã¾ã™ã€‚" + +#: ../port/open.c:114 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "データベースシステムã«å¹²æ¸‰ã™ã‚‹ã‚¢ãƒ³ãƒã‚¦ã‚£ãƒ«ã‚¹ã€ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¨ã„ã£ãŸã‚½ãƒ•トウェアãŒå­˜åœ¨ã™ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "ç¾åœ¨ã®ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../port/strerror.c:25 +#, c-format +msgid "unrecognized error %d" +msgstr "èªè­˜ã§ããªã„エラー %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "管ç†è€…グループã®SIDを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "PowerUsersグループã®SIDを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "アクセストークンã®ãƒ¡ãƒ³ãƒãƒ¼ã‚·ãƒƒãƒ—を確èªã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "インデックス\"%s\" ページ%uã®BRIN範囲è¦ç´„ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 +#: access/transam/xlog.c:10354 access/transam/xlog.c:10881 +#: access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 +#: access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 +#: access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 +#: access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "リカãƒãƒªã¯ç¾åœ¨é€²è¡Œä¸­ã§ã™" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN制御関数ã¯ãƒªã‚«ãƒãƒªä¸­ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。" + +#: access/brin/brin.c:886 access/brin/brin.c:963 +#, c-format +msgid "block number out of range: %s" +msgstr "ブロック番å·ãŒç¯„囲外ã§ã™: %s" + +#: access/brin/brin.c:909 access/brin/brin.c:986 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\"ã¯BRINインデックスã§ã¯ã‚りã¾ã›ã‚“" + +#: access/brin/brin.c:925 access/brin/brin.c:1002 +#, c-format +msgid "could not open parent table of index %s" +msgstr "インデックス%sã®è¦ªãƒ†ãƒ¼ãƒ–ルをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1376 access/nbtree/nbtinsert.c:678 +#: access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "インデックス行サイズ%1$zuã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%3$s\"ã§ã®æœ€å¤§å€¤%2$zuã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "BRINインデックスãŒå£Šã‚Œã¦ã„ã¾ã™: 範囲マップã®ä¸æ•´åˆ" + +#: access/brin/brin_revmap.c:404 +#, c-format +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "消ã•れãšã«æ®‹ã£ãŸãƒ—レースホルダータプルãŒBRINインデックス\"%s\"ã§è¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€å‰Šé™¤ã—ã¾ã™" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "BRINインデックス\"%2$s\"ã®ãƒ–ロック %3$u ã®ãƒšãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—ãŒäºˆæœŸã—ãªã„値 0x%1$04X ã§ã™" + +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ä¸æ­£ãªã‚µãƒãƒ¼ãƒˆç•ªå·%4$dã‚’æŒã¤é–¢æ•°%3$sã‚’å«ã‚“ã§ã„ã¾ã™" + +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ã‚µãƒãƒ¼ãƒˆç•ªå·%4$dã«å¯¾ã—ã¦é–“é•ã£ãŸã‚·ã‚°ãƒãƒãƒ£ã‚’æŒã¤é–¢æ•°%3$sã‚’å«ã‚“ã§ã„ã¾ã™" + +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ä¸æ­£ãªã‚¹ãƒˆãƒ©ãƒ†ã‚¸ç•ªå·%4$dã‚’æŒã¤æ¼”ç®—å­\"%3$s\"ã‚’å«ã‚“ã§ã„ã¾ã™" + +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:209 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯æ¼”ç®—å­%3$sã«å¯¾ã™ã‚‹ä¸æ­£ãªORDER BY指定をå«ã‚“ã§ã„ã¾ã™" + +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯é–“é•ã£ãŸã‚·ã‚°ãƒãƒãƒ£ã‚’æŒã¤æ¼”ç®—å­%3$sã‚’å«ã‚“ã§ã„ã¾ã™" + +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯%3$sã¨%4$sã®åž‹ã«å¯¾ã™ã‚‹æ¼”ç®—å­ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" + +#: access/brin/brin_validate.c:244 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯åž‹%3$sã¨%4$sã«å¯¾ã™ã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•°ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format -msgid "mapped win32 error code %lu to %d" -msgstr "win32ã®ã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰%luã‚’%dã«å¯¾å¿œä»˜ã‘ã¾ã—ãŸ" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯æ¼”ç®—å­ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" -#: ../port/win32error.c:199 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -msgid "unrecognized win32 error code: %lu" -msgstr "未知ã®Win32エラーコードãŒä¸æ˜Žã§ã™: %lu" +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯ã‚µãƒãƒ¼ãƒˆé–¢æ•°%3$dã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" -#: access/common/heaptuple.c:645 access/common/heaptuple.c:1399 +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "列数(%d)ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: access/common/indextuple.c:57 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "インデックス列数(%d)ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: access/common/indextuple.c:168 access/spgist/spgutils.c:605 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format -msgid "index row requires %lu bytes, maximum size is %lu" -msgstr "インデックス行ã¯%luãƒã‚¤ãƒˆè¦æ±‚。最大サイズã¯%luã§ã™" +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "インデックス行ãŒ%zuãƒã‚¤ãƒˆã‚’å¿…è¦ã¨ã—ã¾ã™ãŒæœ€å¤§å€¤ã¯%zuã§ã™" -#: access/common/printtup.c:279 tcop/fastpath.c:182 tcop/fastpath.c:571 -#: tcop/postgres.c:1678 +#: access/common/printtup.c:365 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1778 #, c-format msgid "unsupported format code: %d" msgstr "未サãƒãƒ¼ãƒˆã®æ›¸å¼ã‚³ãƒ¼ãƒ‰: %d" -#: access/common/reloptions.c:364 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "ユーザ定義リレーションã®ãƒ‘ラメータ型ã®åˆ¶é™ã‚’è¶…ãˆã¾ã—ãŸ" -#: access/common/reloptions.c:648 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "RESETã«ã¯ãƒ‘ラメータã®å€¤ã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: access/common/reloptions.c:681 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" -msgstr "未知ã®ãƒ‘ラメータ namaspace \"%s\"" +msgstr "èªè­˜ã§ããªã„パラメータ namaspace \"%s\"" -#: access/common/reloptions.c:925 parser/parse_clause.c:266 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" -msgstr "未知ã®ãƒ‘ラメータ \"%s\"" +msgstr "èªè­˜ã§ããªã„ラメータ \"%s\"" -#: access/common/reloptions.c:950 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" -msgstr "パラメータ\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" +msgstr "パラメータ\"%s\"ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¾ã—ãŸ" -#: access/common/reloptions.c:965 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" -msgstr "ブールオプション値 \"%s\" ã¯ç„¡åйã§ã™: %s" +msgstr "䏿­£ãªãƒ–ール型オプションã®å€¤ \"%s\": %s" -#: access/common/reloptions.c:976 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" -msgstr "整数値オプションã®å€¤ \"%s\" ãŒç„¡åйã§ã™: %s" +msgstr "䏿­£ãªæ•´æ•°åž‹ã‚ªãƒ—ションã®å€¤ \"%s\": %s" -#: access/common/reloptions.c:981 access/common/reloptions.c:999 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" -msgstr "値 %s ã¯ã‚ªãƒ—ション \"%s\" ã®ç¯„囲外ã§ã™" +msgstr "値%sã¯ã‚ªãƒ—ション\"%s\"ã®ç¯„囲外ã§ã™" -#: access/common/reloptions.c:983 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." -msgstr "有効ãªå€¤ã®ç¯„囲㯠\"%d\" ~ \"%d\" ã§ã™ã€‚" +msgstr "有効ãªå€¤ã®ç¯„囲ã¯\"%d\"~\"%d\"ã§ã™ã€‚" -#: access/common/reloptions.c:994 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" -msgstr "æµ®å‹•å°æ•°ç‚¹ã‚ªãƒ—ションã®å€¤ \"%s\" ãŒç„¡åйã§ã™: %s" +msgstr "䏿­£ãªæµ®å‹•å°æ•°ç‚¹åž‹ã‚ªãƒ—ションã®å€¤ \"%s\": %s" -#: access/common/reloptions.c:1001 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." -msgstr "有効ãªå€¤ã®ç¯„囲㯠\"%f\" ~ \"%f\" ã§ã™ã€‚" +msgstr "有効ãªå€¤ã®ç¯„囲ã¯\"%f\"~\"%f\"ã§ã™ã€‚" #: access/common/tupconvert.c:108 #, c-format msgid "Returned type %s does not match expected type %s in column %d." -msgstr "列 %3$d ã§è¿”ã•れãŸåž‹ %1$s ãŒæœŸå¾…ã™ã‚‹åž‹ %2$s ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "列%3$dã§è¿”ã•れãŸåž‹%1$sãŒã€æœŸå¾…ã™ã‚‹åž‹%2$sã¨ä¸€è‡´ã—ã¾ã›ã‚“" #: access/common/tupconvert.c:136 #, c-format msgid "Number of returned columns (%d) does not match expected column count (%d)." -msgstr "è¿”ã•れãŸåˆ—æ•°(%d)ãŒæœŸå¾…ã™ã‚‹åˆ—æ•°(%d)ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "è¿”ã•れãŸåˆ—æ•°(%d)ãŒã€æœŸå¾…ã™ã‚‹åˆ—æ•°(%d)ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: access/common/tupconvert.c:241 +#: access/common/tupconvert.c:329 #, c-format msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." -msgstr "åž‹ %1$s ã®å±žæ€§ \"%2$s\" ãŒå¯¾å¿œã™ã‚‹åž‹ %3$s ã®å±žæ€§ã¨åˆè‡´ã—ã¾ã›ã‚“" +msgstr "%1$såž‹ã®å±žæ€§\"%2$s\"ãŒå¯¾å¿œã™ã‚‹%3$såž‹ã®å±žæ€§ã¨åˆè‡´ã—ã¾ã›ã‚“" -#: access/common/tupconvert.c:253 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." -msgstr "åž‹ %2$s ã®å±žæ€§ \"%1$s\" ãŒåž‹ %3$s 中ã«å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "%2$såž‹ã®å±žæ€§\"%1$s\"ãŒ%3$såž‹ã®ä¸­ã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: access/common/tupdesc.c:619 parser/parse_relation.c:1310 +#: access/common/tupdesc.c:837 parser/parse_clause.c:819 +#: parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" -msgstr "列\"%s\"ã‚’SETOFã§å®£è¨€ã§ãã¾ã›ã‚“" +msgstr "列\"%s\"ã¯SETOFã¨ã—ã¦å®£è¨€ã§ãã¾ã›ã‚“" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "記録リストãŒé•·ã™ãŽã¾ã™" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "maintenance_work_mem ã‚’å°ã•ãã—ã¦ãã ã•ã„。" -#: access/gin/ginentrypage.c:100 access/nbtree/nbtinsert.c:540 -#: access/nbtree/nbtsort.c:485 access/spgist/spgdoinsert.c:1888 +#: access/gin/ginfast.c:1019 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -msgstr "インデックス \"%3$s\" ã§ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹è¡Œã®ã‚µã‚¤ã‚º %1$lu ãŒæœ€å¤§å€¤ %2$lu ã‚’è¶…ãˆã¦ã„ã¾ã™" +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "GINä¿ç•™ãƒªã‚¹ãƒˆã¯ãƒªã‚«ãƒãƒªä¸­ã«ã¯å‡¦ç†ã§ãã¾ã›ã‚“。" -#: access/gin/ginscan.c:400 +#: access/gin/ginfast.c:1026 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\"ã¯GINインデックスã§ã¯ã‚りã¾ã›ã‚“" + +#: access/gin/ginfast.c:1037 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚インデックスã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“" + +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" -msgstr "å¤ã„ GIN インデックスã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å…¨ä½“ã®ã‚¹ã‚­ãƒ£ãƒ³ã‚„ NULL ã®æ¤œç´¢ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "å¤ã„GINインデックスã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å…¨ä½“ã®ã‚¹ã‚­ãƒ£ãƒ³ã‚„nullã®æ¤œç´¢ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: access/gin/ginscan.c:401 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." -msgstr "修復ã™ã‚‹ã«ã¯ REINDEX INDEX \"%s\" ã‚’ãŠã“ãªã£ã¦ãã ã•ã„" +msgstr "修復ã™ã‚‹ã«ã¯ REINDEX INDEX \"%s\" ã‚’ãŠã“ãªã£ã¦ãã ã•ã„。" + +#: access/gin/ginutil.c:138 executor/execExpr.c:1868 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 +#: utils/adt/rowtypes.c:935 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "åž‹%sã®æ¯”較関数ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" + +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "アクセスメソッド %2$s ã®æ¼”ç®—å­æ—\"%1$s\"ãŒå·¦å³è¾ºã®å…¥åŠ›åž‹ãŒç•°ãªã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•° %3$s ã‚’å«ã‚“ã§ã„ã¾ã™" + +#: access/gin/ginvalidate.c:257 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯ã‚µãƒãƒ¼ãƒˆé–¢æ•°%3$dã¾ãŸã¯%4$dã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" -#: access/gist/gist.c:610 access/gist/gistvacuum.c:266 +#: access/gist/gist.c:713 access/gist/gistvacuum.c:257 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "インデックス \"%s\" 内ã«ç„¡åйã¨åˆ¤æ–­ã•れã¦ã„る内部タプルãŒã‚りã¾ã™" -#: access/gist/gist.c:612 access/gist/gistvacuum.c:268 +#: access/gist/gist.c:715 access/gist/gistvacuum.c:259 #, c-format msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." -msgstr "ã“れã¯ã€PostgreSQL 9.1ã¸ã‚¢ãƒƒãƒ—グレードã™ã‚‹å‰ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ãƒªã‚«ãƒãƒªã«ãŠã‘ã‚‹ä¸å®Œå…¨ãªãƒšãƒ¼ã‚¸åˆ†å‰²ãŒåŽŸå› ã§ã™ã€‚" +msgstr "ã“れã¯ã€PostgreSQL 9.1ã¸ã‚¢ãƒƒãƒ—グレードã™ã‚‹å‰ã®ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ãƒªã‚«ãƒãƒªã«ãŠã‘ã‚‹ä¸å®Œå…¨ãªãƒšãƒ¼ã‚¸åˆ†å‰²ãŒåŽŸå› ã§ç™ºç”Ÿã—ã¾ã™ã€‚" -#: access/gist/gist.c:613 access/gist/gistutil.c:693 -#: access/gist/gistutil.c:704 access/gist/gistvacuum.c:269 -#: access/hash/hashutil.c:172 access/hash/hashutil.c:183 -#: access/hash/hashutil.c:195 access/hash/hashutil.c:216 -#: access/nbtree/nbtpage.c:508 access/nbtree/nbtpage.c:519 +#: access/gist/gist.c:716 access/gist/gistutil.c:759 access/gist/gistutil.c:770 +#: access/gist/gistvacuum.c:260 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 +#: access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "REINDEXを行ã£ã¦ãã ã•ã„。" -#: access/gist/gistbuild.c:254 +#: access/gist/gistbuild.c:250 #, c-format msgid "invalid value for \"buffering\" option" -msgstr "\"buffering\"オプションã®å€¤ãŒç„¡åйã§ã™" +msgstr "䏿­£ãª\"buffering\"オプションã®å€¤" -#: access/gist/gistbuild.c:255 +#: access/gist/gistbuild.c:251 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "有効ãªå€¤ã®ç¯„囲ã¯\"on\"ã€\"off\"ã€\"auto\"ã§ã™ã€‚" -#: access/gist/gistbuildbuffers.c:780 utils/sort/logtape.c:213 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "一時ファイルã®ãƒ–ロック%ldを書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" @@ -338,2349 +713,2961 @@ msgstr "インデックス\"%2$s\"ã®åˆ—%1$dã«å¯¾ã™ã‚‹ãƒ”ックスプリット #: access/gist/gistsplit.c:448 #, c-format msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." -msgstr "" -"ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯æœ€é©ã§ã¯ã‚りã¾ã›ã‚“。最é©åŒ–ã™ã‚‹ãŸã‚ã«ã¯é–‹ç™ºè€…ã«é€£çµ¡ã™ã‚‹ã‹\n" -"ã“ã®åˆ—ã‚’CREATE INDEXコマンドã®2番目ã®ã‚‚ã®ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã“ã¨ã‚’試ã¿ã¦ãã ã•ã„" +msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯æœ€é©ã§ã¯ã‚りã¾ã›ã‚“。最é©åŒ–ã™ã‚‹ãŸã‚ã«ã¯é–‹ç™ºè€…ã«é€£çµ¡ã™ã‚‹ã‹ã€ã“ã®åˆ—ã‚’CREATE INDEXコマンドã®2番目ã®åˆ—ã¨ã—ã¦ã¿ã¦ãã ã•ã„。" -#: access/gist/gistutil.c:690 access/hash/hashutil.c:169 -#: access/nbtree/nbtpage.c:505 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" -msgstr "インデックス\"%s\"ã®ãƒ–ロック %uã«äºˆæœŸã—ãªã„ゼロページãŒã‚りã¾ã™" +msgstr "インデックス\"%s\"ã®ãƒ–ロック%uã«äºˆæœŸã—ã¦ã„ãªã„ゼロã§åŸ‹ã‚られãŸãƒšãƒ¼ã‚¸ãŒã‚りã¾ã™" -#: access/gist/gistutil.c:701 access/hash/hashutil.c:180 -#: access/hash/hashutil.c:192 access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" -msgstr "インデックス\"%s\"ã®ãƒ–ロック %uã«ç ´æã—ãŸãƒšãƒ¼ã‚¸ãŒã‚りã¾ã™" +msgstr "インデックス\"%s\"ã®ãƒ–ロック%uã«ç ´æã—ãŸãƒšãƒ¼ã‚¸ãŒã‚りã¾ã™" + +#: access/gist/gistvalidate.c:196 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯æ¼”ç®—å­%3$sã«å¯¾ã™ã‚‹éžã‚µãƒãƒ¼ãƒˆã®ORDER BY指定をå«ã‚“ã§ã„ã¾ã™" + +#: access/gist/gistvalidate.c:207 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯æ¼”ç®—å­%3$sã«å¯¾ã™ã‚‹æ­£ã—ããªã„ORDER BYæ¼”ç®—å­æ—ã‚’å«ã‚“ã§ã„ã¾ã™" -#: access/hash/hashinsert.c:68 +#: access/hash/hashinsert.c:83 #, c-format -msgid "index row size %lu exceeds hash maximum %lu" -msgstr "インデックスã®è¡Œã‚µã‚¤ã‚º%luãŒãƒãƒƒã‚·ãƒ¥ã®æœ€å¤§%luã‚’è¶…ãˆã¦ã„ã¾ã™" +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "インデックス行ã®ã‚µã‚¤ã‚º%zuãŒãƒãƒƒã‚·ãƒ¥ã§ã®æœ€å¤§å€¤%zuã‚’è¶…ãˆã¦ã„ã¾ã™" -#: access/hash/hashinsert.c:71 access/spgist/spgdoinsert.c:1892 -#: access/spgist/spgutils.c:667 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "ãƒãƒƒãƒ•ァページよりも大ããªå€¤ã‚’インデックスã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" -#: access/hash/hashovfl.c:546 +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "䏿­£ãªã‚ªãƒ¼ãƒãƒ¼ãƒ•ローブロック番å·%u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" -msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã®ä¸­ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ•ローページãŒã‚りã¾ã›ã‚“" +msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã®ä¸­ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ•ローページãŒè¶³ã‚Šã¾ã›ã‚“" -#: access/hash/hashsearch.c:153 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å…¨ä½“ã®ã‚¹ã‚­ãƒ£ãƒ³ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: access/hash/hashutil.c:208 +#: access/hash/hashutil.c:277 #, c-format msgid "index \"%s\" is not a hash index" msgstr "インデックス\"%s\"ã¯ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: access/hash/hashutil.c:214 +#: access/hash/hashutil.c:283 #, c-format msgid "index \"%s\" has wrong hash version" msgstr "インデックス\"%s\"ã®ãƒãƒƒã‚·ãƒ¥ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒä¸æ­£ã§ã™" -#: access/heap/heapam.c:1198 access/heap/heapam.c:1226 -#: access/heap/heapam.c:1258 catalog/aclchk.c:1742 +#: access/hash/hashvalidate.c:191 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯æ¼”ç®—å­%3$sã«å¯¾ã™ã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•°ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ç•°ãªã‚‹åž‹é–“ã«å¯¾å¿œã™ã‚‹æ¼”ç®—å­ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 +#: access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" msgstr "\"%s\"ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" -#: access/heap/heapam.c:1203 access/heap/heapam.c:1231 -#: access/heap/heapam.c:1263 catalog/aclchk.c:1749 commands/tablecmds.c:8359 -#: commands/tablecmds.c:10721 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 +#: access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10345 +#: commands/tablecmds.c:13630 #, c-format msgid "\"%s\" is a composite type" msgstr "\"%s\"ã¯è¤‡åˆåž‹ã§ã™" -#: access/heap/heapam.c:4028 access/heap/heapam.c:4240 -#: access/heap/heapam.c:4295 +#: access/heap/heapam.c:2645 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "並列ワーカã§ã¯ã‚¿ãƒ—ãƒ«ã®æŒ¿å…¥ã¯ã§ãã¾ã›ã‚“" + +#: access/heap/heapam.c:3092 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ã‚¿ãƒ—ルã®å‰Šé™¤ã¯ã§ãã¾ã›ã‚“" + +#: access/heap/heapam.c:3138 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "ä¸å¯è¦–ã®ã‚¿ãƒ—ルを削除ã—よã†ã¨ã—ã¾ã—ãŸ" + +#: access/heap/heapam.c:3573 access/heap/heapam.c:6410 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ã‚¿ãƒ—ãƒ«ã®æ›´æ–°ã¯ã§ãã¾ã›ã‚“" + +#: access/heap/heapam.c:3721 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "ä¸å¯è¦–ã®ã‚¿ãƒ—ルを更新ã—よã†ã¨ã—ã¾ã—ãŸ" + +#: access/heap/heapam.c:5086 access/heap/heapam.c:5124 +#: access/heap/heapam.c:5376 executor/execMain.c:2662 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "リレーション\"%s\"ã®è¡Œãƒ­ãƒƒã‚¯ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: access/heap/hio.c:240 access/heap/rewriteheap.c:603 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:682 #, c-format -msgid "row is too big: size %lu, maximum size %lu" -msgstr "行ãŒå¤§ãã™ãŽã¾ã™: サイズã¯%luã€ä¸Šé™ã¯%lu" +msgid "row is too big: size %zu, maximum size %zu" +msgstr "行ãŒå¤§ãã™ãŽã¾ã™: サイズã¯%zuã€ä¸Šé™ã¯%zu" -#: access/index/indexam.c:169 catalog/objectaddress.c:842 -#: commands/indexcmds.c:1738 commands/tablecmds.c:232 -#: commands/tablecmds.c:10712 +#: access/heap/rewriteheap.c:942 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "ファイル\"%1$s\"ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€%3$dãƒã‚¤ãƒˆä¸­%2$dãƒã‚¤ãƒˆæ›¸ãè¾¼ã¿ã¾ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:982 access/heap/rewriteheap.c:1203 +#: access/heap/rewriteheap.c:1302 access/transam/timeline.c:411 +#: access/transam/timeline.c:490 access/transam/xlog.c:3307 +#: access/transam/xlog.c:3473 replication/logical/snapbuild.c:1648 +#: replication/slot.c:1313 replication/slot.c:1405 storage/file/fd.c:639 +#: storage/file/fd.c:3533 storage/smgr/md.c:1044 storage/smgr/md.c:1289 +#: storage/smgr/md.c:1463 utils/misc/guc.c:7266 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1036 access/heap/rewriteheap.c:1155 +#: access/transam/timeline.c:314 access/transam/timeline.c:465 +#: access/transam/xlog.c:3261 access/transam/xlog.c:3411 +#: access/transam/xlog.c:10692 access/transam/xlog.c:10730 +#: access/transam/xlog.c:11133 postmaster/postmaster.c:4454 +#: replication/logical/origin.c:575 replication/slot.c:1262 +#: storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1165 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "ファイル\"%s\"ã‚’%uãƒã‚¤ãƒˆã«åˆ‡ã‚Šè©°ã‚られã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1173 replication/walsender.c:490 +#: storage/smgr/md.c:1999 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "ファイル \"%s\" ã®çµ‚端ã¸ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1190 access/transam/timeline.c:369 +#: access/transam/timeline.c:404 access/transam/timeline.c:482 +#: access/transam/xlog.c:3293 access/transam/xlog.c:3464 +#: postmaster/postmaster.c:4464 postmaster/postmaster.c:4474 +#: replication/logical/origin.c:590 replication/logical/origin.c:635 +#: replication/logical/origin.c:657 replication/logical/snapbuild.c:1624 +#: replication/slot.c:1296 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1349 utils/init/miscinit.c:1360 +#: utils/init/miscinit.c:1368 utils/misc/guc.c:7227 utils/misc/guc.c:7258 +#: utils/misc/guc.c:9120 utils/misc/guc.c:9134 utils/time/snapmgr.c:1302 +#: utils/time/snapmgr.c:1309 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "ファイル\"%s\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1277 access/transam/xlogarchive.c:112 +#: access/transam/xlogarchive.c:459 postmaster/postmaster.c:1275 +#: postmaster/syslogger.c:1456 replication/logical/origin.c:563 +#: replication/logical/reorderbuffer.c:2810 +#: replication/logical/snapbuild.c:1567 replication/logical/snapbuild.c:1966 +#: replication/slot.c:1375 storage/file/fd.c:690 storage/file/fd.c:3133 +#: storage/file/fd.c:3195 storage/file/reinit.c:255 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1410 +#: utils/time/snapmgr.c:1640 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/heap/rewriteheap.c:1291 access/transam/timeline.c:111 +#: access/transam/timeline.c:236 access/transam/timeline.c:333 +#: access/transam/xlog.c:3238 access/transam/xlog.c:3356 +#: access/transam/xlog.c:3397 access/transam/xlog.c:3674 +#: access/transam/xlog.c:3752 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1465 replication/basebackup.c:517 +#: replication/basebackup.c:1391 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2304 +#: replication/logical/reorderbuffer.c:2571 +#: replication/logical/reorderbuffer.c:3284 +#: replication/logical/snapbuild.c:1610 replication/logical/snapbuild.c:1710 +#: replication/slot.c:1390 replication/walsender.c:483 +#: replication/walsender.c:2412 storage/file/copydir.c:161 +#: storage/file/fd.c:622 storage/file/fd.c:3428 storage/file/fd.c:3512 +#: storage/smgr/md.c:608 utils/error/elog.c:1872 utils/init/miscinit.c:1273 +#: utils/init/miscinit.c:1408 utils/init/miscinit.c:1485 utils/misc/guc.c:7486 +#: utils/misc/guc.c:7518 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/index/amapi.c:83 commands/amcmds.c:163 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "アクセスメソッド\"%s\"ã®ã‚¿ã‚¤ãƒ—ãŒ%sã§ã¯ã‚りã¾ã›ã‚“" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "インデックスアクセスメソッド\"%s\"ã¯ãƒãƒ³ãƒ‰ãƒ©ã‚’æŒã£ã¦ã„ã¾ã›ã‚“" + +#: access/index/indexam.c:160 catalog/objectaddress.c:1223 +#: commands/indexcmds.c:2282 commands/tablecmds.c:249 commands/tablecmds.c:273 +#: commands/tablecmds.c:13621 commands/tablecmds.c:14875 #, c-format msgid "\"%s\" is not an index" msgstr "\"%s\"ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: access/nbtree/nbtinsert.c:392 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "é‡è¤‡ã‚­ãƒ¼ãŒä¸€æ„性制約\"%s\"ã«é•åã—ã¦ã„ã¾ã™" -#: access/nbtree/nbtinsert.c:394 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." -msgstr "キー %s ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgstr "キー %s ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚" -#: access/nbtree/nbtinsert.c:462 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" -msgstr "インデックス \"%s\" 内ã§è¡Œã®å†æ¤œç´¢ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgstr "インデックス\"%s\"内ã§è¡Œã®å†æ¤œç´¢ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: access/nbtree/nbtinsert.c:464 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." -msgstr "ã“れã¯ä¸å¤‰ã§ãªã„インデックス評価å¼ãŒåŽŸå› ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™" +msgstr "ã“れã¯ä¸å¤‰ã§ãªã„インデックスå¼ãŒåŽŸå› ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™" -#: access/nbtree/nbtinsert.c:544 access/nbtree/nbtsort.c:489 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" "Consider a function index of an MD5 hash of the value, or use full text indexing." msgstr "" -"ãƒãƒƒãƒ•ァページã®1/3ã‚’è¶…ãˆã‚‹å€¤ã‚’インデックスã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。\n" -"値ã®MD5ãƒãƒƒã‚·ãƒ¥ã¸ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’行ã†é–¢æ•°ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’検討ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯å…¨æ–‡ãƒ†ã‚­ã‚¹ãƒˆã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使用ã—ã¦ãã ã•ã„。" +"ãƒãƒƒãƒ•ァページã®1/3ã‚’è¶…ãˆã‚‹å€¤ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹åŒ–ã§ãã¾ã›ã‚“。\n" +"MD5ãƒãƒƒã‚·ãƒ¥ã«ã‚ˆã‚‹é–¢æ•°ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’検討ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯å…¨æ–‡ãƒ†ã‚­ã‚¹ãƒˆã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使用ã—ã¦ãã ã•ã„。" -#: access/nbtree/nbtpage.c:159 access/nbtree/nbtpage.c:361 -#: access/nbtree/nbtpage.c:448 parser/parse_utilcmd.c:1618 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 +#: access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2054 #, c-format msgid "index \"%s\" is not a btree" msgstr "インデックス\"%s\"ã¯btreeã§ã¯ã‚りã¾ã›ã‚“" -#: access/nbtree/nbtpage.c:165 access/nbtree/nbtpage.c:367 -#: access/nbtree/nbtpage.c:454 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 +#: access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "インデックス\"%s\"ã«ãŠã‘ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸æ•´åˆ: ファイルãƒãƒ¼ã‚¸ãƒ§ãƒ³ %dã€ã‚³ãƒ¼ãƒ‰ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "インデックス\"%s\"ã«ãŠã‘ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸æ•´åˆ: ファイルãƒãƒ¼ã‚¸ãƒ§ãƒ³ %dã€ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %dã€ã‚µãƒãƒ¼ãƒˆã•れる最å°ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d" -#: access/spgist/spgutils.c:664 +#: access/nbtree/nbtpage.c:1320 #, c-format -msgid "SP-GiST inner tuple size %lu exceeds maximum %lu" -msgstr "SP-GiSTインデックスタプルサイズ%luãŒæœ€å¤§%luã‚’è¶…ãˆã¦ã„ã¾ã™" +msgid "index \"%s\" contains a half-dead internal page" +msgstr "インデックス\"%s\"ã«å‰Šé™¤å‡¦ç†ä¸­ã®å†…部ページãŒã‚りã¾ã™" -#: access/transam/multixact.c:924 +#: access/nbtree/nbtpage.c:1322 #, c-format -#| msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" -msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" -msgstr "データベース\"%s\"ã«ãŠã‘る周回ã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯æ–°ã—ãMultiXactIdsを生æˆã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’å—付ã‘ã¾ã›ã‚“" +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "ã“れã¯9.3ã‹ãれ以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã€ã‚¢ãƒƒãƒ—グレードå‰ã«VACUUMãŒä¸­æ–­ã•れãŸéš›ã«èµ·ããŸå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚REINDEXã—ã¦ãã ã•ã„。" -#: access/transam/multixact.c:926 access/transam/multixact.c:933 -#: access/transam/multixact.c:948 access/transam/multixact.c:957 +#: access/nbtree/nbtvalidate.c:236 #, c-format -#| msgid "" -#| "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -#| "You might also need to commit or roll back old prepared transactions." -msgid "" +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯åž‹%3$sã¨%4$sã«å¯¾å¿œã™ã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•°ã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: access/spgist/spgutils.c:136 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "リーフ型ãŒå…¥åŠ›åž‹ã¨ç•°ãªã‚‹å ´åˆã¯åœ§ç¸®ãƒ¡ã‚½ãƒƒãƒ‰ã®å®šç¾©ãŒå¿…è¦ã§ã™" + +#: access/spgist/spgutils.c:743 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST内部タプルã®ã‚µã‚¤ã‚º%zuãŒæœ€å¤§å€¤%zuã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: access/spgist/spgvalidate.c:269 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯%4$såž‹ã«å¯¾ã™ã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•°%3$dã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "サンプリングã®å‰²åˆã¯0ã¨100ã®é–“ã§ã™" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "トランザクション%uã®ã‚³ãƒŸãƒƒãƒˆã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ã¯å–å¾—ã§ãã¾ã›ã‚“" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "コミットタイムスタンプ情報をå–å¾—ã§ãã¾ã›ã‚“" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "マスタサーãƒã§è¨­å®šãƒ‘ラメータ\"%s\"ãŒonã«è¨­å®šã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„" + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "設定パラメータ\"%s\"ãŒè¨­å®šã•れã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" + +#: access/transam/multixact.c:1000 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "データベース\"%s\"ã«ãŠã‘ã‚‹MultiXactIds周回ã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯æ–°ã—ãMultiXactIdsを生æˆã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ã‘付ã‘ã¾ã›ã‚“" + +#: access/transam/multixact.c:1002 access/transam/multixact.c:1009 +#: access/transam/multixact.c:1033 access/transam/multixact.c:1042 +#, c-format +msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"データベース全体㮠VACUUM を実行ã—ã¦ãã ã•ã„。\n" -"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ãŒå¿…è¦ãªå ´åˆã‚‚ã‚りã¾ã™ã€‚" +"ãã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å…¨ä½“ã® VACUUM を実行ã—ã¦ãã ã•ã„。\n" +"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã€ã‚‚ã—ãã¯å¤ã„レプリケーションスロットã®å‰Šé™¤ã‚‚å¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: access/transam/multixact.c:931 +#: access/transam/multixact.c:1007 #, c-format -#| msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" -msgstr "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å‘¨å›žã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€æ–°ã—ã„MultiXactIdsを生æˆã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’å—付ã‘ãªã„状態ã«ãªã£ã¦ã„ã¾ã™" +msgstr "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å‘¨å›žã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€æ–°ã—ã„MultiXactIdsを生æˆã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã‚’å—ã‘付ã‘ãªã„状態ã«ãªã£ã¦ã„ã¾ã™" -#: access/transam/multixact.c:943 access/transam/multixact.c:1989 +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 #, c-format -#| msgid "database \"%s\" must be vacuumed within %u transactions" msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" -msgstr[0] "データベース\"%s\"ã¯%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -msgstr[1] "データベース\"%s\"ã¯%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr[0] "データベース\"%s\"ã¯ã‚ã¨%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«VACUUMã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgstr[1] "データベース\"%s\"ã¯ã‚ã¨%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«VACUUMã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: access/transam/multixact.c:952 access/transam/multixact.c:1998 +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 #, c-format -#| msgid "database with OID %u must be vacuumed within %u transactions" msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" -msgstr[0] "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯ %u 個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" -msgstr[1] "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯ %u 個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr[0] "OID %u ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯ã‚ã¨%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«VACUUMã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgstr[1] "OID %u ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯ã‚ã¨%u個ã®MultiXactIdãŒä½¿ã‚れるå‰ã«VACUUMã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: access/transam/multixact.c:1098 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "マルãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®\"メンãƒ\"ãŒåˆ¶é™ã‚’è¶…ãˆã¾ã—ãŸ" + +#: access/transam/multixact.c:1099 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã§%u個ã®ãƒ¡ãƒ³ãƒã‚’æŒã¤ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒç”Ÿæˆã•れã¾ã™ãŒã€æ®‹ã‚Šã®ã‚¹ãƒšãƒ¼ã‚¹ã¯ %u 個ã®ãƒ¡ãƒ³ãƒåˆ†ã—ã‹ã‚りã¾ã›ã‚“。" +msgstr[1] "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã§%u個ã®ãƒ¡ãƒ³ãƒã‚’æŒã¤ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒç”Ÿæˆã•れã¾ã™ãŒã€æ®‹ã‚Šã®ã‚¹ãƒšãƒ¼ã‚¹ã¯ %u 個ã®ãƒ¡ãƒ³ãƒåˆ†ã—ã‹ã‚りã¾ã›ã‚“。" + +#: access/transam/multixact.c:1104 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age 㨠vacuum_multixact_freeze_table_age をよりå°ã•ãªå€¤ã«è¨­å®šã—ã¦OID %u ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å…¨ä½“ã«VACUUMを実行ã—ã¦ãã ã•ã„。" + +#: access/transam/multixact.c:1135 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "OID %u ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯æ›´ã«%d個ã®ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¡ãƒ³ãƒãŒä½¿ç”¨ã•れるå‰ã«VACUUMを実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgstr[1] "OID %u ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯æ›´ã«%d個ã®ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¡ãƒ³ãƒãŒä½¿ç”¨ã•れるå‰ã«VACUUMを実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: access/transam/multixact.c:1140 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age 㨠vacuum_multixact_freeze_table_age をよりå°ã•ãªå€¤ã«è¨­å®šã—ãŸä¸Šã§ã€ãã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§VACUUMを実行ã—ã¦ãã ã•ã„。" -#: access/transam/multixact.c:1102 +#: access/transam/multixact.c:1277 #, c-format msgid "MultiXactId %u does no longer exist -- apparent wraparound" msgstr "MultiXactId %uã¯ã‚‚ã†å­˜åœ¨ã—ã¾ã›ã‚“: 周回ã—ã¦ã„るよã†ã§ã™" -#: access/transam/multixact.c:1110 +#: access/transam/multixact.c:1285 #, c-format -#| msgid "could not truncate directory \"%s\": apparent wraparound" msgid "MultiXactId %u has not been created yet -- apparent wraparound" msgstr "MultiXactId %uを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: 周回ã—ã¦ã„る様å­" -#: access/transam/multixact.c:1954 +#: access/transam/multixact.c:2268 #, c-format -#| msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "MultiXactIdã®å‘¨å›žåˆ¶é™ã¯ %u ã§ã€OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã‚ˆã‚Šåˆ¶é™ã•れã¦ã„ã¾ã™" -#: access/transam/multixact.c:1994 access/transam/multixact.c:2003 -#: access/transam/varsup.c:137 access/transam/varsup.c:144 -#: access/transam/varsup.c:373 access/transam/varsup.c:380 +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 +#: access/transam/varsup.c:146 access/transam/varsup.c:153 +#: access/transam/varsup.c:405 access/transam/varsup.c:412 #, c-format msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "データベースã®åœæ­¢ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å…¨ä½“ã® VACUUM を実行ã—ã¦ãã ã•ã„。\n" -"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ãŒå¿…è¦ãªå ´åˆã‚‚ã‚りã¾ã™ã€‚" +"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã€ã‚‚ã—ãã¯å¤ã„レプリケーションスロットã®å‰Šé™¤ã‚‚å¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: access/transam/multixact.c:2451 +#: access/transam/multixact.c:2602 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "最å¤ã®MultiXactIdメンãƒã¯ã‚ªãƒ•セット%uã«ã‚りã¾ã™" + +#: access/transam/multixact.c:2606 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "最å¤ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆæ¸ˆã¿ã®ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å­˜åœ¨ã—ãªã„ãŸã‚ã€ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¡ãƒ³ãƒãƒ¼ã®å‘¨å›žé˜²æ­¢æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã—ãŸ" + +#: access/transam/multixact.c:2628 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "マルãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¡ãƒ³ãƒãƒ¼ã®å‘¨å›žé˜²æ­¢æ©Ÿèƒ½ãŒæœ‰åйã«ãªã‚Šã¾ã—ãŸ" + +#: access/transam/multixact.c:2631 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "マルãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®åœæ­¢ä¸Šé™ãŒãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%2$uを起点ã«ã—ã¦%1$uã«ãªã‚Šã¾ã—ãŸ" + +#: access/transam/multixact.c:3011 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "最å¤ã®ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªæœ€å¤ã®ã‚‚ã®ã¯%uã€åˆ‡ã‚Šè©°ã‚をスキップã—ã¾ã™" + +#: access/transam/multixact.c:3029 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "マルãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uãŒãƒ‡ã‚£ã‚¹ã‚¯ä¸Šã«å­˜åœ¨ã—ãªã„ãŸã‚ã€ãã“ã¾ã§ã®åˆ‡ã‚Šè©°ã‚ãŒã§ãã¾ã›ã‚“ã€åˆ‡ã‚Šè©°ã‚をスキップã—ã¾ã™" + +#: access/transam/multixact.c:3355 #, c-format -#| msgid "invalid role OID: %u" msgid "invalid MultiXactId: %u" -msgstr "無効ãªMultiXactId: %u" +msgstr "䏿­£ãªMultiXactId: %u" + +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "パラレルワーカã®åˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "è©³ç´°ãªæƒ…å ±ãŒã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã«ã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: access/transam/slru.c:607 +#: access/transam/parallel.c:849 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "並列処ç†ä¸­ã«postmasterãŒçµ‚了ã—ã¾ã—ãŸ" + +#: access/transam/parallel.c:1036 +#, c-format +msgid "lost connection to parallel worker" +msgstr "パラレルワーカã¸ã®æŽ¥ç¶šã‚’失ã„ã¾ã—ãŸ" + +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 +msgid "parallel worker" +msgstr "パラレルワーカ" + +#: access/transam/parallel.c:1249 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "動的共有メモリセグメントをマップã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: access/transam/parallel.c:1254 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "動的共有メモリセグメントã®ãƒžã‚¸ãƒƒã‚¯ãƒŠãƒ³ãƒãŒä¸æ­£ã§ã™" + +#: access/transam/slru.c:668 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "ファイル\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“。ゼロã¨ã—ã¦èª­ã¿è¾¼ã¿ã¾ã™" -#: access/transam/slru.c:837 access/transam/slru.c:843 -#: access/transam/slru.c:850 access/transam/slru.c:857 -#: access/transam/slru.c:864 access/transam/slru.c:871 +#: access/transam/slru.c:906 access/transam/slru.c:912 +#: access/transam/slru.c:919 access/transam/slru.c:926 +#: access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "トランザクション%uã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: access/transam/slru.c:838 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:844 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "ファイル\"%s\"ã®ã‚ªãƒ•セット%uã«ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:851 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "ファイル\"%s\"ã®ã‚ªãƒ•セット%uを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:858 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "ファイル\"%s\"ã®ã‚ªãƒ•セット%uã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:865 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:872 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "ファイル\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/slru.c:1127 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" -msgstr "ディレクトリ\"%s\"を切り詰ã‚ã§ãã¾ã›ã‚“ã§ã—ãŸ: 周回ã—ã¦ã„る様å­" +msgstr "ディレクトリ\"%s\"を切り詰ã‚ã§ãã¾ã›ã‚“ã§ã—ãŸ: 明らã‹ã«å‘¨å›žã—ã¦ã„ã¾ã™" -#: access/transam/slru.c:1201 access/transam/slru.c:1219 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "ファイル\"%s\"を削除ã—ã¦ã„ã¾ã™" -#: access/transam/timeline.c:110 access/transam/timeline.c:235 -#: access/transam/timeline.c:333 access/transam/xlog.c:3366 -#: access/transam/xlog.c:3497 access/transam/xlog.c:3534 -#: access/transam/xlog.c:3809 access/transam/xlog.c:3887 -#: replication/basebackup.c:366 replication/basebackup.c:992 -#: replication/walsender.c:368 replication/walsender.c:1326 -#: storage/file/copydir.c:158 storage/file/copydir.c:248 storage/smgr/md.c:587 -#: storage/smgr/md.c:845 utils/error/elog.c:1739 utils/init/miscinit.c:1063 -#: utils/init/miscinit.c:1192 -#, c-format -msgid "could not open file \"%s\": %m" -msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:147 access/transam/timeline.c:152 +#: access/transam/timeline.c:148 access/transam/timeline.c:153 #, c-format msgid "syntax error in history file: %s" msgstr "å±¥æ­´ãƒ•ã‚¡ã‚¤ãƒ«å†…ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼: %s" -#: access/transam/timeline.c:148 +#: access/transam/timeline.c:149 #, c-format msgid "Expected a numeric timeline ID." -msgstr "æ•°å­—ã®æ™‚系列IDを想定ã—ã¾ã—ãŸã€‚" +msgstr "æ•°å­—ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³IDを想定ã—ã¾ã—ãŸã€‚" -#: access/transam/timeline.c:153 +#: access/transam/timeline.c:154 #, c-format -#| msgid "force a transaction log checkpoint" -msgid "Expected a transaction log switchpoint location." -msgstr "トランザクションログã®åˆ‡æ›¿ãˆãƒã‚¤ãƒ³ãƒˆã‚’想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "Expected a write-ahead log switchpoint location." +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ã®åˆ‡ã‚Šæ›¿ãˆç‚¹ã®å ´æ‰€ãŒã‚ã‚‹ã¯ãšã§ã—ãŸã€‚" -#: access/transam/timeline.c:157 +#: access/transam/timeline.c:158 #, c-format msgid "invalid data in history file: %s" -msgstr "履歴ファイル内ã®ç„¡åйãªãƒ‡ãƒ¼ã‚¿: %s" +msgstr "履歴ファイル内ã®ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿: %s" -#: access/transam/timeline.c:158 +#: access/transam/timeline.c:159 #, c-format msgid "Timeline IDs must be in increasing sequence." -msgstr "時系列IDã¯æ˜‡é †ã®ä¸¦ã³ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "タイムラインIDã¯æ˜‡é †ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: access/transam/timeline.c:178 +#: access/transam/timeline.c:179 #, c-format msgid "invalid data in history file \"%s\"" -msgstr "履歴ファイル\"%s\"内ã«ç„¡åйãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã—ãŸ" +msgstr "履歴ファイル\"%s\"内ã«ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã—ãŸ" -#: access/transam/timeline.c:179 +#: access/transam/timeline.c:180 #, c-format msgid "Timeline IDs must be less than child timeline's ID." -msgstr "時系列IDã¯å‰¯æ™‚系列IDよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“。" - -#: access/transam/timeline.c:314 access/transam/timeline.c:471 -#: access/transam/xlog.c:3390 access/transam/xlog.c:3549 -#: access/transam/xlog.c:9842 access/transam/xlog.c:10159 -#: postmaster/postmaster.c:4149 storage/file/copydir.c:165 -#: storage/smgr/md.c:305 utils/time/snapmgr.c:926 -#, c-format -msgid "could not create file \"%s\": %m" -msgstr "ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:345 access/transam/xlog.c:3562 -#: access/transam/xlog.c:10010 access/transam/xlog.c:10023 -#: access/transam/xlog.c:10391 access/transam/xlog.c:10434 -#: access/transam/xlogfuncs.c:586 access/transam/xlogfuncs.c:605 -#: replication/walsender.c:393 storage/file/copydir.c:179 -#: utils/adt/genfile.c:139 -#, c-format -msgid "could not read file \"%s\": %m" -msgstr "ファイル\"%s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:366 access/transam/timeline.c:400 -#: access/transam/timeline.c:487 access/transam/xlog.c:3446 -#: access/transam/xlog.c:3581 postmaster/postmaster.c:4159 -#: postmaster/postmaster.c:4169 storage/file/copydir.c:190 -#: utils/init/miscinit.c:1128 utils/init/miscinit.c:1137 -#: utils/init/miscinit.c:1144 utils/misc/guc.c:7655 utils/misc/guc.c:7669 -#: utils/time/snapmgr.c:931 utils/time/snapmgr.c:938 -#, c-format -msgid "could not write to file \"%s\": %m" -msgstr "ファイル\"%s\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:406 access/transam/timeline.c:493 -#: access/transam/xlog.c:3458 access/transam/xlog.c:3588 -#: storage/file/copydir.c:262 storage/smgr/md.c:967 storage/smgr/md.c:1198 -#: storage/smgr/md.c:1371 -#, c-format -msgid "could not fsync file \"%s\": %m" -msgstr "ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "タイムラインIDã¯å­ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³IDよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: access/transam/timeline.c:411 access/transam/timeline.c:498 -#: access/transam/xlog.c:3464 access/transam/xlog.c:3593 -#: access/transam/xlogfuncs.c:611 commands/copy.c:1469 -#: storage/file/copydir.c:204 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 +#: access/transam/xlog.c:3314 access/transam/xlog.c:3479 +#: access/transam/xlogfuncs.c:683 commands/copy.c:1760 +#: storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "ファイル\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/timeline.c:428 access/transam/timeline.c:515 +#: access/transam/timeline.c:578 #, c-format -msgid "could not link file \"%s\" to \"%s\": %m" -msgstr "ファイル\"%s\"ã‹ã‚‰\"%s\"ã¸ã®ãƒªãƒ³ã‚¯ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:435 access/transam/timeline.c:522 -#: access/transam/xlog.c:5613 access/transam/xlog.c:6492 -#: access/transam/xlogarchive.c:457 access/transam/xlogarchive.c:474 -#: access/transam/xlogarchive.c:581 postmaster/pgarch.c:756 -#: utils/time/snapmgr.c:949 -#, c-format -msgid "could not rename file \"%s\" to \"%s\": %m" -msgstr "ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/timeline.c:594 -#, c-format -#| msgid "%s: starting timeline %u is not present in the server\n" msgid "requested timeline %u is not in this server's history" msgstr "è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uãŒã‚µãƒ¼ãƒã®å±¥æ­´ä¸Šã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: access/transam/twophase.c:253 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "トランザクション識別å­\"%s\"ã¯é•·ã™ãŽã¾ã™" -#: access/transam/twophase.c:260 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ç„¡åйã§ã™ã€‚" +msgstr "ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æº–å‚™ã¯ç„¡åйã«ã•れã¦ã„ã‚‹ãŸã‚ã§ãã¾ã›ã‚“。" -#: access/transam/twophase.c:261 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "max_prepared_transactionsã‚’éžã‚¼ãƒ­ã«è¨­å®šã—ã¦ãã ã•ã„。" -#: access/transam/twophase.c:294 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "トランザクション識別å­\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: access/transam/twophase.c:303 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "準備済ã¿ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æœ€å¤§æ•°ã«é”ã—ã¾ã—ãŸ" -#: access/transam/twophase.c:304 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "max_prepared_transactionsを増加ã—ã¦ãã ã•ã„(ç¾çж%d)。" -#: access/transam/twophase.c:431 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³è­˜åˆ¥å­\"%s\"ã¯å®Ÿè¡Œä¸­ã§ã™" +msgstr "識別å­\"%s\"ã®æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒ­ãƒƒã‚¯ãŒå–å¾—ã§ãã¾ã›ã‚“" -#: access/transam/twophase.c:439 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã™ã‚‹ãŸã‚ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®çµ‚äº†ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: access/transam/twophase.c:440 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." -msgstr "トランザクションを準備ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "スーパーユーザã¾ãŸã¯ã“ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’準備ã—ãŸãƒ¦ãƒ¼ã‚¶ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: access/transam/twophase.c:451 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒåˆ¥ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«å±žã—ã¦ã„ã¾ã™" +msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯åˆ¥ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«å±žã—ã¦ã„ã¾ã™" -#: access/transam/twophase.c:452 +#: access/transam/twophase.c:605 #, c-format msgid "Connect to the database where the transaction was prepared to finish it." -msgstr "終了ã•ã›ã‚‹ãŸã‚ã«ã¯ãã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’準備ã—ãŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¦ãã ã•ã„" +msgstr "終了ã•ã›ã‚‹ãŸã‚ã«ã¯ã“ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’準備ã—ãŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¦ãã ã•ã„。" -#: access/transam/twophase.c:466 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ä¸­ã«è­˜åˆ¥å­ \"%s\" ã‚’æŒã¤ã‚‚ã®ã¯ã‚りã¾ã›ã‚“" +msgstr "識別å­\"%s\"ã®æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ã‚りã¾ã›ã‚“" -#: access/transam/twophase.c:969 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "2ç›¸çŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¤§é•·ãŒåˆ¶é™ã‚’è¶…ãˆã¾ã—ãŸ" -#: access/transam/twophase.c:982 -#, c-format -msgid "could not create two-phase state file \"%s\": %m" -msgstr "2相状態ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/twophase.c:996 access/transam/twophase.c:1013 -#: access/transam/twophase.c:1062 access/transam/twophase.c:1482 -#: access/transam/twophase.c:1489 -#, c-format -msgid "could not write two-phase state file: %m" -msgstr "2ç›¸çŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/twophase.c:1022 -#, c-format -msgid "could not seek in two-phase state file: %m" -msgstr "2相状態ファイルをシークã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/twophase.c:1068 access/transam/twophase.c:1507 -#, c-format -msgid "could not close two-phase state file: %m" -msgstr "2相状態ファイルをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/twophase.c:1148 access/transam/twophase.c:1588 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "2相状態ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/twophase.c:1165 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" -msgstr "2相状態ファイル\"%s\"ã®statãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "2相状態ファイル\"%s\"ã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/twophase.c:1197 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "2相状態ファイル\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/twophase.c:1293 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "WALリーダã®å‰²ã‚Šå½“ã¦ã«ä¸­ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: access/transam/twophase.c:1390 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "WALã®%X/%Xã‹ã‚‰2相状態を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ" + +#: access/transam/twophase.c:1398 #, c-format -msgid "two-phase state file for transaction %u is corrupt" -msgstr "トランザクション%u用ã®2相状態ファイルãŒç ´æã—ã¦ã„ã¾ã™" +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "WALã®%X/%Xã«ã‚ã‚‹ã¯ãšã®2相状態ã®ãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã›ã‚“" -#: access/transam/twophase.c:1444 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "2相状態ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/twophase.c:1473 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "2相状態ファイル\"%s\"ã‚’å†ä½œæˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/twophase.c:1501 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 +#, c-format +msgid "could not write two-phase state file: %m" +msgstr "2ç›¸çŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "2相状態ファイルをfsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/twophase.c:1597 +#: access/transam/twophase.c:1719 +#, c-format +msgid "could not close two-phase state file: %m" +msgstr "2相状態ファイルをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/twophase.c:1807 #, c-format -msgid "could not fsync two-phase state file \"%s\": %m" -msgstr "2相状態ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "é•·æ™‚é–“å®Ÿè¡Œä¸­ã®æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãŸã‚ã«%u個ã®2ç›¸çŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸ãè¾¼ã¾ã‚Œã¾ã—ãŸ" +msgstr[1] "é•·æ™‚é–“å®Ÿè¡Œä¸­ã®æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãŸã‚ã«%u個ã®2ç›¸çŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ›¸ãè¾¼ã¾ã‚Œã¾ã—ãŸ" -#: access/transam/twophase.c:1604 +#: access/transam/twophase.c:2036 #, c-format -msgid "could not close two-phase state file \"%s\": %m" -msgstr "2相状態ファイル\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "recovering prepared transaction %u from shared memory" +msgstr "共有メモリã‹ã‚‰æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uを復元ã—ã¾ã™" -#: access/transam/twophase.c:1669 +#: access/transam/twophase.c:2126 #, c-format -msgid "removing future two-phase state file \"%s\"" -msgstr "å°†æ¥ã®2相状態ファイル\"%s\"を削除ã—ã¦ã„ã¾ã™" +msgid "removing stale two-phase state file for transaction %u" +msgstr "ä¸è¦ã«ãªã£ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®2相状態ファイルを削除ã—ã¾ã™" -#: access/transam/twophase.c:1685 access/transam/twophase.c:1696 -#: access/transam/twophase.c:1815 access/transam/twophase.c:1826 -#: access/transam/twophase.c:1899 +#: access/transam/twophase.c:2133 #, c-format -msgid "removing corrupt two-phase state file \"%s\"" -msgstr "ç ´æã—ãŸ2相状態ファイル\"%s\"を削除ã—ã¦ã„ã¾ã™" +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "ä¸è¦ã«ãªã£ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®2相状態をメモリã‹ã‚‰å‰Šé™¤ã—ã¾ã™" -#: access/transam/twophase.c:1804 access/transam/twophase.c:1888 +#: access/transam/twophase.c:2146 #, c-format -msgid "removing stale two-phase state file \"%s\"" -msgstr "å¤ããªã£ãŸ2相状態ファイル\"%s\"を削除ã—ã¦ã„ã¾ã™" +msgid "removing future two-phase state file for transaction %u" +msgstr "未æ¥ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®2相状態ファイルを削除ã—ã¾ã™" -#: access/transam/twophase.c:1906 +#: access/transam/twophase.c:2153 #, c-format -msgid "recovering prepared transaction %u" -msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uを復旧ã—ã¦ã„ã¾ã™" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "未æ¥ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®2相状態をメモリã‹ã‚‰å‰Šé™¤ã—ã¾ã™" -#: access/transam/varsup.c:115 +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 +#, c-format +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "トランザクション%uã®ç ´æã—ãŸ2相状態ファイルを削除ã—ã¾ã™" + +#: access/transam/twophase.c:2193 +#, c-format +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "トランザクション%uã®ç ´æã—ãŸ2相状態をメモリã‹ã‚‰å‰Šé™¤ã—ã¾ã™" + +#: access/transam/varsup.c:124 #, c-format msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" -msgstr "データベース\"%s\"ã«ãŠã‘る周回ã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å•ã„åˆã‚ã›ã‚’å—付ã‘ã¾ã›ã‚“" +msgstr "データベース\"%s\"ã«ãŠã‘る周回ã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“" -#: access/transam/varsup.c:117 access/transam/varsup.c:124 +#: access/transam/varsup.c:126 access/transam/varsup.c:133 #, c-format -#| msgid "" -#| "Stop the postmaster and use a standalone backend to vacuum that database.\n" -#| "You might also need to commit or roll back old prepared transactions." msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"postmaster ã‚’åœæ­¢å¾Œã€ã‚·ãƒ³ã‚°ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¢ãƒ¼ãƒ‰ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’ãƒã‚­ãƒ¥ãƒ¼ãƒ ã—ã¦ãã ã•ã„。\n" -"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ãŒå¿…è¦ãªå ´åˆã‚‚ã‚りã¾ã™ã€‚" +"postmaster ã‚’åœæ­¢å¾Œã€ã‚·ãƒ³ã‚°ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¢ãƒ¼ãƒ‰ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’VACUUMを実行ã—ã¦ãã ã•ã„。\n" +"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã€ã‚‚ã—ãã¯å¤ã„レプリケーションスロットã®å‰Šé™¤ã‚‚å¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: access/transam/varsup.c:122 +#: access/transam/varsup.c:131 #, c-format msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" -msgstr "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å‘¨å›žã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ç¾åœ¨ã¯å•ã„åˆã‚ã›ã‚’å—付ã‘ãªã„状態ã«ãªã£ã¦ã„ã¾ã™" +msgstr "OID %uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å‘¨å›žã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ã‚’防ããŸã‚ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘ã¦ã„ã¾ã›ã‚“" -#: access/transam/varsup.c:134 access/transam/varsup.c:370 +#: access/transam/varsup.c:143 access/transam/varsup.c:402 #, c-format msgid "database \"%s\" must be vacuumed within %u transactions" -msgstr "データベース\"%s\"ã¯%uトランザクション以内ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "データベース\"%s\"ã¯%uトランザクション以内ã«VACUUMã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: access/transam/varsup.c:141 access/transam/varsup.c:377 +#: access/transam/varsup.c:150 access/transam/varsup.c:409 #, c-format msgid "database with OID %u must be vacuumed within %u transactions" -msgstr "OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯ %u トランザクション以内ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "OID %uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯%uトランザクション以内ã«VACUUMを実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: access/transam/varsup.c:335 +#: access/transam/varsup.c:367 #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" -msgstr "トランザクション ID ã®å‘¨å›žåˆ¶é™ã¯ %u ã§ã€OID %u ã‚’æŒã¤ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã‚ˆã‚Šåˆ¶é™ã•れã¦ã„ã¾ã™" +msgstr "トランザクションIDã®å‘¨å›žåˆ¶é™å€¤ã¯OID %uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã‚ˆã‚Š%uã«åˆ¶é™ã•れã¦ã„ã¾ã™" -#: access/transam/xact.c:774 +#: access/transam/xact.c:960 #, c-format -msgid "cannot have more than 2^32-1 commands in a transaction" -msgstr "1 トランザクション内ã«ã¯ 2^32-1 個以上ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’ä¿æŒã§ãã¾ã›ã‚“" +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "1トランザクション内ã§ã¯ 2^32-2 個より多ãã®ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã§ãã¾ã›ã‚“" -#: access/transam/xact.c:1322 +#: access/transam/xact.c:1485 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" -msgstr "コミットã•れãŸã‚µãƒ–ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æœ€å¤§æ•° (%d) ãŒåˆ¶é™ã‚’è¶Šãˆã¾ã—ãŸ" +msgstr "コミットã•れãŸã‚µãƒ–ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³æ•°ã®æœ€å¤§å€¤(%d)ãŒåˆ¶é™ã‚’è¶Šãˆã¾ã—ãŸ" -#: access/transam/xact.c:2102 +#: access/transam/xact.c:2296 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" -msgstr "一時テーブルã«å¯¾ã™ã‚‹æ“作を行ã†ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "一時テーブルã«å¯¾ã™ã‚‹æ“作を行ã£ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: access/transam/xact.c:2112 +#: access/transam/xact.c:2306 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" -msgstr "公開ã•れãŸã‚¹ãƒŠãƒƒãƒ—ショットをæŒã¤ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "エクスãƒãƒ¼ãƒˆã•れãŸã‚¹ãƒŠãƒƒãƒ—ショットをæŒã¤ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:2315 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションワーカã‹ã‚‰æ“作ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:2921 +#: access/transam/xact.c:3200 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%sã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ–ロックã®å†…å´ã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:2931 +#: access/transam/xact.c:3210 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%sã¯ã‚µãƒ–トランザクションブロックã®å†…å´ã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:2941 +#: access/transam/xact.c:3220 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "%sã¯é–¢æ•°ã¾ãŸã¯è¤‡æ•°ã‚³ãƒžãƒ³ãƒ‰æ–‡å­—列ã‹ã‚‰å®Ÿè¡Œã§ãã¾ã›ã‚“" +msgid "%s cannot be executed from a function" +msgstr "%s ã¯é–¢æ•°å†…ã§ã®å®Ÿè¡Œã¯ã§ãã¾ã›ã‚“" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:2992 +#: access/transam/xact.c:3289 access/transam/xact.c:3913 +#: access/transam/xact.c:3982 access/transam/xact.c:4093 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%sã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ–ロック内ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: access/transam/xact.c:3174 +#: access/transam/xact.c:3482 #, c-format msgid "there is already a transaction in progress" -msgstr "ã™ã§ã«ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒé€²è¡Œä¸­ã§ã™" +msgstr "ã™ã§ã«ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå®Ÿè¡Œä¸­ã§ã™" -#: access/transam/xact.c:3342 access/transam/xact.c:3435 +#: access/transam/xact.c:3593 access/transam/xact.c:3663 +#: access/transam/xact.c:3772 #, c-format msgid "there is no transaction in progress" -msgstr "進行中ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“" +msgstr "実行中ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“" + +#: access/transam/xact.c:3674 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "並列処ç†ä¸­ã«ã¯ã‚³ãƒŸãƒƒãƒˆã¯ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:3783 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "パラレル処ç†ä¸­ã«ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:3877 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "パラレル処ç†ä¸­ã«ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã¯å®šç¾©ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:3964 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã®è§£æ”¾ã¯ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:3974 access/transam/xact.c:4025 +#: access/transam/xact.c:4085 access/transam/xact.c:4134 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "セーブãƒã‚¤ãƒ³ãƒˆ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: access/transam/xact.c:3531 access/transam/xact.c:3582 -#: access/transam/xact.c:3588 access/transam/xact.c:3632 -#: access/transam/xact.c:3681 access/transam/xact.c:3687 +#: access/transam/xact.c:4031 access/transam/xact.c:4140 #, c-format -msgid "no such savepoint" -msgstr "ãã®ã‚ˆã†ãªã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“" +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "セーブãƒã‚¤ãƒ³ãƒˆ\"%s\"ã¯ç¾åœ¨ã®ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆãƒ¬ãƒ™ãƒ«ã«ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: access/transam/xact.c:4344 +#: access/transam/xact.c:4073 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "パラレル処ç†ä¸­ã«ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã®ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:4201 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ã‚µãƒ–トランザクションを開始ã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:4269 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ã‚µãƒ–トランザクションをコミットã§ãã¾ã›ã‚“" + +#: access/transam/xact.c:4907 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" -msgstr "1 トランザクション内ã«ã¯ 2^32-1 個以上ã®ã‚µãƒ–ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ä¿æŒã§ãã¾ã›ã‚“" +msgstr "1トランザクション内ã«ã¯ 2^32-1 個より多ãã®ã‚µãƒ–トランザクションを作æˆã§ãã¾ã›ã‚“" -#: access/transam/xlog.c:2701 +#: access/transam/xlog.c:2492 #, c-format -#| msgid "Could not seek in file \"%s\" to offset %u: %m." msgid "could not seek in log file %s to offset %u: %m" msgstr "ログファイル\"%s\"をオフセット%uã«ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:2721 +#: access/transam/xlog.c:2514 #, c-format -#| msgid "could not write to log file %u, segment %u at offset %u, length %lu: %m" -msgid "could not write to log file %s at offset %u, length %lu: %m" -msgstr "ログファイル%sã®ã‚ªãƒ•セット%uã«é•·ã•%luã§æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "ログファイル%sã®ã‚ªãƒ•セット%uã«é•·ã•%zuã®æ›¸ãè¾¼ã¿ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:2963 +#: access/transam/xlog.c:2792 #, c-format -#| msgid "updated min recovery point to %X/%X" msgid "updated min recovery point to %X/%X on timeline %u" -msgstr "最å°ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚’タイムライン%3$uã® %1$X/%2$X ã«æ›´æ–°ã—ã¾ã—ãŸ" +msgstr "最å°ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚’タイムライン%3$uã®%1$X/%2$Xã«æ›´æ–°ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:3565 +#: access/transam/xlog.c:3444 #, c-format msgid "not enough data in file \"%s\"" msgstr "ファイル\"%s\"内ã®ãƒ‡ãƒ¼ã‚¿ãŒä¸å分ã§ã™" -#: access/transam/xlog.c:3684 -#, c-format -#| msgid "could not link file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" -msgid "could not link file \"%s\" to \"%s\" (initialization of log file): %m" -msgstr "ファイル\"%s\"ã‚’\"%s\"ã«ãƒªãƒ³ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ(ログファイルã®åˆæœŸåŒ–): %m" - -#: access/transam/xlog.c:3696 +#: access/transam/xlog.c:3589 #, c-format -#| msgid "could not rename file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" -msgid "could not rename file \"%s\" to \"%s\" (initialization of log file): %m" -msgstr "ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ(ログファイルã®åˆæœŸåŒ–): %m" +msgid "could not open write-ahead log file \"%s\": %m" +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:3724 +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 #, c-format -#| msgid "%s: could not open transaction log file \"%s\": %s\n" -msgid "could not open transaction log file \"%s\": %m" -msgstr "トランザクションログファイル \"%s\" をオープンã§ãã¾ã›ã‚“: %m" - -#: access/transam/xlog.c:3913 -#, c-format -#| msgid "could not close file \"%s\": %m" msgid "could not close log file %s: %m" msgstr "ログファイル\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:3972 replication/walsender.c:1321 +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 +#: replication/walsender.c:2407 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "è¦æ±‚ã•れ㟠WAL セグメント %s ã¯ã™ã§ã«å‰Šé™¤ã•れã¦ã„ã¾ã™" -#: access/transam/xlog.c:4029 access/transam/xlog.c:4206 -#, c-format -msgid "could not open transaction log directory \"%s\": %m" -msgstr "トランザクションログディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/xlog.c:4077 +#: access/transam/xlog.c:4051 #, c-format -msgid "recycled transaction log file \"%s\"" -msgstr "トランザクションログファイル\"%s\"を回åŽã—ã¾ã—ãŸ" +msgid "recycled write-ahead log file \"%s\"" +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"ã‚’å†åˆ©ç”¨ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:4093 +#: access/transam/xlog.c:4063 #, c-format -msgid "removing transaction log file \"%s\"" -msgstr "トランザクションログファイル\"%s\"を削除ã—ã¾ã—ãŸ" +msgid "removing write-ahead log file \"%s\"" +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"を削除ã—ã¾ã™" -#: access/transam/xlog.c:4116 +#: access/transam/xlog.c:4083 #, c-format -msgid "could not rename old transaction log file \"%s\": %m" -msgstr "å¤ã„トランザクションログファイル \"%s\" をリãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not rename old write-ahead log file \"%s\": %m" +msgstr "å¤ã„先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"をリãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4128 -#, c-format -msgid "could not remove old transaction log file \"%s\": %m" -msgstr "å¤ã„トランザクションログファイル \"%s\" を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/xlog.c:4166 access/transam/xlog.c:4176 +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 #, c-format msgid "required WAL directory \"%s\" does not exist" -msgstr "WAL ディレクトリ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "WALディレクトリ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: access/transam/xlog.c:4182 +#: access/transam/xlog.c:4141 #, c-format msgid "creating missing WAL directory \"%s\"" -msgstr "見ã¤ã‹ã‚‰ãªã‹ã£ãŸ WAL ディレクトリ \"%s\" を作æˆã—ã¦ã„ã¾ã™ ... " +msgstr "ãªã‹ã£ãŸWALディレクトリ\"%s\"を作æˆã—ã¦ã„ã¾ã™" -#: access/transam/xlog.c:4185 +#: access/transam/xlog.c:4144 #, c-format msgid "could not create missing directory \"%s\": %m" -msgstr "ディレクトリ\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/xlog.c:4219 -#, c-format -msgid "removing transaction log backup history file \"%s\"" -msgstr "トランザクションログãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—履歴ファイル\"%s\"を削除ã—ã¦ã„ã¾ã™" +msgstr "ãªã‹ã£ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:4415 +#: access/transam/xlog.c:4252 #, c-format -#| msgid "unexpected timeline ID %u in log file %u, segment %u, offset %u" msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "ログファイル%2$sã€ã‚ªãƒ•セット%3$uã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID%1$uã¯æƒ³å®šå¤–ã§ã™" -#: access/transam/xlog.c:4537 +#: access/transam/xlog.c:4380 #, c-format msgid "new timeline %u is not a child of database system timeline %u" -msgstr "æ–°ã—ã„æ™‚系列 %u ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®æ™‚系列 %u ã®ç³»åˆ—ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "æ–°ã—ã„タイムライン%uã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã®å­ã§ã¯ã‚りã¾ã›ã‚“" -#: access/transam/xlog.c:4551 +#: access/transam/xlog.c:4394 #, c-format -#| msgid "new timeline %u is not a child of database system timeline %u" msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" -msgstr "æ–°ã—ã„タイムライン %u ã¯ç¾åœ¨ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ %uã‹ã‚‰ç¾åœ¨ã®ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆ%X/%Xよりå‰ã«ãƒ•ォークã•れã¾ã—ãŸ" +msgstr "æ–°ã—ã„タイムライン%uã¯ç¾åœ¨ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã‹ã‚‰ç¾åœ¨ã®ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆ%X/%Xよりå‰ã«åˆ†å²ã—ã¦ã„ã¾ã™" -#: access/transam/xlog.c:4570 +#: access/transam/xlog.c:4413 #, c-format msgid "new target timeline is %u" -msgstr "æ–°ã—ã„対象時系列㯠%u ã§ã™" +msgstr "æ–°ã—ã„目標タイムラインã¯%uã§ã™" -#: access/transam/xlog.c:4649 +#: access/transam/xlog.c:4493 #, c-format msgid "could not create control file \"%s\": %m" msgstr "制御ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4660 access/transam/xlog.c:4885 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 #, c-format msgid "could not write to control file: %m" msgstr "制御ファイルを書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4666 access/transam/xlog.c:4891 +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 #, c-format msgid "could not fsync control file: %m" msgstr "制御ファイルをfsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4671 access/transam/xlog.c:4896 +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 #, c-format msgid "could not close control file: %m" msgstr "制御ファイルをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4689 access/transam/xlog.c:4874 +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 #, c-format msgid "could not open control file \"%s\": %m" msgstr "制御ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4695 +#: access/transam/xlog.c:4548 #, c-format msgid "could not read from control file: %m" msgstr "制御ファイルを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:4708 access/transam/xlog.c:4717 -#: access/transam/xlog.c:4741 access/transam/xlog.c:4748 -#: access/transam/xlog.c:4755 access/transam/xlog.c:4760 -#: access/transam/xlog.c:4767 access/transam/xlog.c:4774 -#: access/transam/xlog.c:4781 access/transam/xlog.c:4788 -#: access/transam/xlog.c:4795 access/transam/xlog.c:4802 -#: access/transam/xlog.c:4811 access/transam/xlog.c:4818 -#: access/transam/xlog.c:4827 access/transam/xlog.c:4834 -#: access/transam/xlog.c:4843 access/transam/xlog.c:4850 -#: utils/init/miscinit.c:1210 +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "制御ファイルを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %d ãƒã‚¤ãƒˆã ã‘読ã¿è¾¼ã¿ã¾ã—ãŸãŒã€èª­ã¿è¾¼ã‚‚ã†ã¨ã—ã¦ã„ãŸã®ã¯ %d ãƒã‚¤ãƒˆã§ã™" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 +#: access/transam/xlog.c:4599 access/transam/xlog.c:4606 +#: access/transam/xlog.c:4613 access/transam/xlog.c:4618 +#: access/transam/xlog.c:4625 access/transam/xlog.c:4632 +#: access/transam/xlog.c:4639 access/transam/xlog.c:4646 +#: access/transam/xlog.c:4653 access/transam/xlog.c:4660 +#: access/transam/xlog.c:4669 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4685 access/transam/xlog.c:4692 +#: utils/init/miscinit.c:1506 #, c-format msgid "database files are incompatible with server" msgstr "データベースファイルãŒã‚µãƒ¼ãƒã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: access/transam/xlog.c:4709 +#: access/transam/xlog.c:4567 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." msgstr "データベースクラスタã¯PG_CONTROL_VERSION %d (0x%08x)ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯PG_CONTROL_VERSION %d (0x%08x)ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4713 +#: access/transam/xlog.c:4571 #, c-format msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." -msgstr "" -"ã“れã¯ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ã®ä¸æ•´åˆå•題ã«ãªã‚Šå¾—ã¾ã™ã€‚initdbã—ãªã‘れã°ãªã‚‰ãªã„\n" -"よã†ã§ã™ã€‚" +msgstr "ã“れã¯ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ã®ä¸æ•´åˆã®å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚initdbを実行ã™ã‚‹å¿…è¦ãŒã‚りãã†ã§ã™ã€‚" -#: access/transam/xlog.c:4718 +#: access/transam/xlog.c:4576 #, c-format msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." msgstr "データベースクラスタã¯PG_CONTROL_VERSION %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ PG_CONTROL_VERSION %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4721 access/transam/xlog.c:4745 -#: access/transam/xlog.c:4752 access/transam/xlog.c:4757 +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 +#: access/transam/xlog.c:4610 access/transam/xlog.c:4615 #, c-format msgid "It looks like you need to initdb." -msgstr "initdbãŒå¿…è¦ã®ã‚ˆã†ã§ã™" +msgstr "initdbãŒå¿…è¦ã®ã‚ˆã†ã§ã™ã€‚" -#: access/transam/xlog.c:4732 +#: access/transam/xlog.c:4590 #, c-format msgid "incorrect checksum in control file" msgstr "制御ファイル内ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:4742 +#: access/transam/xlog.c:4600 #, c-format msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." msgstr "データベースクラスタ㯠CATALOG_VERSION_NO %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ CATALOG_VERSION_NO %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4749 +#: access/transam/xlog.c:4607 #, c-format msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." msgstr "データベースクラスタ㯠MAXALIGN %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ MAXALIGN %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4756 +#: access/transam/xlog.c:4614 #, c-format msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "データベースクラスタã¯ã‚µãƒ¼ãƒå®Ÿè¡Œãƒ•ァイルã¨ç•°ãªã‚‹æµ®å‹•å°æ•°ç‚¹æ›¸å¼ã‚’使用ã—ã¦ã„るよã†ã§ã™ã€‚" -#: access/transam/xlog.c:4761 +#: access/transam/xlog.c:4619 #, c-format msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "データベースクラスタ㯠BLCKSZ %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ BLCKSZ %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4764 access/transam/xlog.c:4771 -#: access/transam/xlog.c:4778 access/transam/xlog.c:4785 -#: access/transam/xlog.c:4792 access/transam/xlog.c:4799 -#: access/transam/xlog.c:4806 access/transam/xlog.c:4814 -#: access/transam/xlog.c:4821 access/transam/xlog.c:4830 -#: access/transam/xlog.c:4837 access/transam/xlog.c:4846 -#: access/transam/xlog.c:4853 +#: access/transam/xlog.c:4622 access/transam/xlog.c:4629 +#: access/transam/xlog.c:4636 access/transam/xlog.c:4643 +#: access/transam/xlog.c:4650 access/transam/xlog.c:4657 +#: access/transam/xlog.c:4664 access/transam/xlog.c:4672 +#: access/transam/xlog.c:4679 access/transam/xlog.c:4688 +#: access/transam/xlog.c:4695 #, c-format msgid "It looks like you need to recompile or initdb." -msgstr "å†ã‚³ãƒ³ãƒ‘イルもã—ã㯠initdb ãŒå¿…è¦ãã†ã§ã™" +msgstr "å†ã‚³ãƒ³ãƒ‘イルもã—ã㯠initdb ãŒå¿…è¦ãã†ã§ã™ã€‚" -#: access/transam/xlog.c:4768 +#: access/transam/xlog.c:4626 #, c-format msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." msgstr "データベースクラスタ㯠RELSEG_SIZE %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ RELSEG_SIZE %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4775 +#: access/transam/xlog.c:4633 #, c-format msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." msgstr "データベースクラスタ㯠XLOG_BLCKSZ %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ XLOG_BLCKSZ %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4782 -#, c-format -msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." -msgstr "データベースクラスタ㯠XLOG_SEG_SIZE %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ XLOG_SEG_SIZE %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" - -#: access/transam/xlog.c:4789 +#: access/transam/xlog.c:4640 #, c-format msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." msgstr "データベースクラスタ㯠NAMEDATALEN %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ NAMEDATALEN %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4796 +#: access/transam/xlog.c:4647 #, c-format msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." msgstr "データベースクラスタ㯠INDEX_MAX_KEYS %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ INDEX_MAX_KEYS %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4803 +#: access/transam/xlog.c:4654 #, c-format msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." msgstr "データベースクラスタ㯠TOAST_MAX_CHUNK_SIZE %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ TOAST_MAX_CHUNK_SIZE %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4812 -#, c-format -msgid "The database cluster was initialized without HAVE_INT64_TIMESTAMP but the server was compiled with HAVE_INT64_TIMESTAMP." -msgstr "データベースクラスタ㯠HAVE_INT64_TIMESTAMP ãªã—ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ HAVE_INT64_TIMESTAMP ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" - -#: access/transam/xlog.c:4819 +#: access/transam/xlog.c:4661 #, c-format -msgid "The database cluster was initialized with HAVE_INT64_TIMESTAMP but the server was compiled without HAVE_INT64_TIMESTAMP." -msgstr "データベースクラスタ㯠HAVE_INT64_TIMESTAMP ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ HAVE_INT64_TIMESTAMP ãªã—ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "データベースクラスタ㯠LOBLKSIZE %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ LOBLKSIZE %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4828 +#: access/transam/xlog.c:4670 #, c-format msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." msgstr "データベースクラスタ㯠USE_FLOAT4_BYVAL ãªã—ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒå´ã¯ USE_FLOAT4_BYVAL 付ãã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4835 +#: access/transam/xlog.c:4677 #, c-format msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." msgstr "データベースクラスタ㯠USE_FLOAT4_BYVAL 付ãã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒå´ã¯ USE_FLOAT4_BYVAL ãªã—ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4844 +#: access/transam/xlog.c:4686 #, c-format msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." msgstr "データベースクラスタ㯠USE_FLOAT8_BYVAL ãªã—ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒå´ã¯ USE_FLOAT8_BYVAL 付ãã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:4851 +#: access/transam/xlog.c:4693 #, c-format msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." msgstr "データベースクラスタ㯠USE_FLOAT8_BYVAL 付ãã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒå´ã¯ USE_FLOAT8_BYVAL ãªã—ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:5239 +#: access/transam/xlog.c:4702 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WALセグメントã®ã‚µã‚¤ã‚ºæŒ‡å®šã¯1MBã¨1GBã®é–“ã®2ã®ç´¯ä¹—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“ã€ã—ã‹ã—コントロールファイルã§ã¯%dãƒã‚¤ãƒˆã¨ãªã£ã¦ã„ã¾ã™" +msgstr[1] "WALセグメントã®ã‚µã‚¤ã‚ºæŒ‡å®šã¯1MBã¨1GBã®é–“ã®2ã®ç´¯ä¹—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“ã€ã—ã‹ã—コントロールファイルã§ã¯%dãƒã‚¤ãƒˆã¨ãªã£ã¦ã„ã¾ã™" + +#: access/transam/xlog.c:4714 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" ã¯æœ€ä½Žã§ã‚‚ \"wal_segment_size\" ã®2å€ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: access/transam/xlog.c:4718 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" ã¯æœ€ä½Žã§ã‚‚ \"wal_segment_size\" ã®2å€ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: access/transam/xlog.c:5105 #, c-format -msgid "could not write bootstrap transaction log file: %m" -msgstr "ブートストラップ・トランザクションã®ãƒ­ã‚°ãƒ•ァイルを書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not generate secret authorization token" +msgstr "秘密ã®èªè¨¼ãƒˆãƒ¼ã‚¯ãƒ³ã‚’生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: access/transam/xlog.c:5245 +#: access/transam/xlog.c:5195 #, c-format -msgid "could not fsync bootstrap transaction log file: %m" -msgstr "ブートストラップ・トランザクションログファイルをfsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "ブートストラップã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:5250 +#: access/transam/xlog.c:5203 #, c-format -msgid "could not close bootstrap transaction log file: %m" -msgstr "ブートストラップ・トランザクションログファイルをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "ブートストラップã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイルをfsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:5320 +#: access/transam/xlog.c:5209 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "ブートストラップã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイルをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/xlog.c:5291 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "リカãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ァイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:5360 access/transam/xlog.c:5451 -#: access/transam/xlog.c:5462 commands/extension.c:527 -#: commands/extension.c:535 utils/misc/guc.c:5429 +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 #, c-format -msgid "parameter \"%s\" requires a Boolean value" -msgstr "パラメータ\"%s\"ã¯boolean値ãŒå¿…è¦ã§ã™" +msgid "invalid value for recovery parameter \"%s\": \"%s\"" +msgstr "リカãƒãƒªãƒ‘ラメータ\"%s\"ã®å€¤ãŒä¸æ­£: \"%s\"" -#: access/transam/xlog.c:5376 +#: access/transam/xlog.c:5340 +#, c-format +msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." +msgstr "有効ãªå€¤ã¯ \"pause\"ã€\"promote\"ãŠã‚ˆã³\"shutdown\"。" + +#: access/transam/xlog.c:5360 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" -msgstr "recovery_target_timelineãŒç„¡åйãªç•ªå·ã§ã™: \"%s\"" +msgstr "recovery_target_timelineãŒä¸æ­£ãªç•ªå·ã§ã™: \"%s\"" -#: access/transam/xlog.c:5392 +#: access/transam/xlog.c:5377 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" -msgstr "recovery_target_xidãŒç„¡åйãªç•ªå·ã§ã™: \"%s\"" +msgstr "recovery_target_xidãŒä¸æ­£ãªç•ªå·ã§ã™: \"%s\"" + +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_time ã«æœ‰åйãªã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“: \"%s\"" -#: access/transam/xlog.c:5436 +#: access/transam/xlog.c:5420 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "recovery_target_nameãŒé•·éŽãŽã¾ã™ï¼ˆæœ€å¤§%d文字)" -#: access/transam/xlog.c:5483 +#: access/transam/xlog.c:5454 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "\"immediate\"ã®ã¿ãŒæŒ‡å®šå¯èƒ½ã§ã™ã€‚" + +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 +#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5993 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "パラメータ\"%s\"ã«ã¯booleanを指定ã—ã¾ã™" + +#: access/transam/xlog.c:5513 +#, c-format +msgid "parameter \"%s\" requires a temporal value" +msgstr "パラメータ\"%s\"ã«ã¯æ™‚間を指定ã—ã¾ã™" + +#: access/transam/xlog.c:5515 catalog/dependency.c:969 catalog/dependency.c:970 +#: catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 +#: catalog/dependency.c:989 commands/tablecmds.c:1070 +#: commands/tablecmds.c:10805 commands/user.c:1064 commands/view.c:509 +#: libpq/auth.c:336 replication/syncrep.c:1162 storage/lmgr/deadlock.c:1139 +#: storage/lmgr/proc.c:1331 utils/adt/acl.c:5344 utils/misc/guc.c:6015 +#: utils/misc/guc.c:6108 utils/misc/guc.c:10098 utils/misc/guc.c:10132 +#: utils/misc/guc.c:10166 utils/misc/guc.c:10200 utils/misc/guc.c:10235 +#, c-format +msgid "%s" +msgstr "%s" + +#: access/transam/xlog.c:5522 #, c-format msgid "unrecognized recovery parameter \"%s\"" -msgstr "リカãƒãƒªãƒ‘ラメータ \"%s\"ãŒä¸æ˜Žã§ã™" +msgstr "èªè­˜ã§ããªã„リカãƒãƒªãƒ‘ラメータ\"%s\"" -#: access/transam/xlog.c:5494 +#: access/transam/xlog.c:5533 #, c-format msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" -msgstr "リカãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ァイル \"%s\" ã§ primary_conninfo 㨠restore_command ã®ã„ãšã‚Œã‚‚指定ã•れã¦ã„ã¾ã›ã‚“" +msgstr "リカãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ァイル\"%s\"ã§primary_conninfoã¨restore_commandã®ã„ãšã‚Œã‚‚指定ã•れã¦ã„ã¾ã›ã‚“" -#: access/transam/xlog.c:5496 +#: access/transam/xlog.c:5535 #, c-format -msgid "The database server will regularly poll the pg_xlog subdirectory to check for files placed there." -msgstr "データベースサーãƒã¯é€šå¸¸ pg_xlog サブディレクトリを poll ã—ã¦ï¼ˆå®šæœŸçš„ã«ç›£è¦–ã—ã¦ï¼‰ã€ãã“ã«ãƒ•ァイルãŒç½®ã‹ã‚ŒãŸã‹ã©ã†ã‹ã‚’調ã¹ã¾ã™ã€‚" +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "データベースサーãƒã¯pg_walサブディレクトリã«ç½®ã‹ã‚ŒãŸãƒ•ァイルを定期的ã«ç¢ºèªã—ã¾ã™ã€‚" -#: access/transam/xlog.c:5502 +#: access/transam/xlog.c:5542 #, c-format msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" -msgstr "スタンãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ãŒæœ‰åйã§ãªã„å ´åˆã€ãƒªã‚«ãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ァイル \"%s\" ã§ restore_command を指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スタンãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ã‚’有効ã«ã—ãªã„å ´åˆã¯ã€ãƒªã‚«ãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ァイル\"%s\"ã§restore_commandã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: access/transam/xlog.c:5522 +#: access/transam/xlog.c:5563 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "スタンãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ã¯ã‚·ãƒ³ã‚°ãƒ«ãƒ¦ãƒ¼ã‚¶ã‚µãƒ¼ãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: access/transam/xlog.c:5582 #, c-format msgid "recovery target timeline %u does not exist" -msgstr "リカãƒãƒªå¯¾è±¡æ™‚系列%uãŒå­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "リカãƒãƒªç›®æ¨™ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uãŒå­˜åœ¨ã—ã¾ã›ã‚“" -#: access/transam/xlog.c:5617 +#: access/transam/xlog.c:5703 #, c-format msgid "archive recovery complete" msgstr "アーカイブリカãƒãƒªãŒå®Œäº†ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:5742 +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 #, c-format -msgid "recovery stopping after commit of transaction %u, time %s" -msgstr "リカãƒãƒªãŒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚³ãƒŸãƒƒãƒˆã€æ™‚刻%sã®å¾Œã«åœæ­¢ã—ã¾ã—ãŸ" +msgid "recovery stopping after reaching consistency" +msgstr "リカãƒãƒªå‡¦ç†ã¯ä¸€è²«æ€§ç¢ºä¿å¾Œã«åœæ­¢ã—ã¾ã™" -#: access/transam/xlog.c:5747 +#: access/transam/xlog.c:5783 #, c-format -msgid "recovery stopping before commit of transaction %u, time %s" -msgstr "リカãƒãƒªãŒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚³ãƒŸãƒƒãƒˆã€æ™‚刻%sã®å‰ã«åœæ­¢ã—ã¾ã—ãŸ" +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "リカãƒãƒªå‡¦ç†ã¯WALä½ç½®(LSN)\"%X/%X\"ã®å‰ã§åœæ­¢ã—ã¾ã™" -#: access/transam/xlog.c:5755 +#: access/transam/xlog.c:5869 #, c-format -msgid "recovery stopping after abort of transaction %u, time %s" -msgstr "リカãƒãƒªãŒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚¢ãƒœãƒ¼ãƒˆã€æ™‚刻%sã®å¾Œã«åœæ­¢ã—ã¾ã—ãŸ" +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "リカãƒãƒªå‡¦ç†ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚³ãƒŸãƒƒãƒˆã€æ™‚刻%sã®å‰ã«åœæ­¢ã—ã¾ã™" -#: access/transam/xlog.c:5760 +#: access/transam/xlog.c:5876 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" -msgstr "リカãƒãƒªãŒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚¢ãƒœãƒ¼ãƒˆã€æ™‚刻%sã®å‰ã«åœæ­¢ã—ã¾ã—ãŸ" +msgstr "リカãƒãƒªå‡¦ç†ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚¢ãƒœãƒ¼ãƒˆã€æ™‚刻%sã®å‰ã«åœæ­¢ã—ã¾ã™" -#: access/transam/xlog.c:5769 +#: access/transam/xlog.c:5922 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" -msgstr "リカãƒãƒªãŒæ™‚刻 %2$s ã«å¾©å…ƒãƒã‚¤ãƒ³ãƒˆ \"%1$s\" ã§åœæ­¢ã—ã¾ã—ãŸ" +msgstr "リカãƒãƒªå‡¦ç†ã¯å¾©å…ƒãƒã‚¤ãƒ³ãƒˆ\"%s\"ã€æ™‚刻%s ã«åœæ­¢ã—ã¾ã™" + +#: access/transam/xlog.c:5940 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "リカãƒãƒªå‡¦ç†ã¯WALä½ç½®(LSN)\"%X/%X\"ã®å¾Œã§åœæ­¢ã—ã¾ã™" + +#: access/transam/xlog.c:6008 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "リカãƒãƒªå‡¦ç†ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚³ãƒŸãƒƒãƒˆã€æ™‚刻%sã®å¾Œã«åœæ­¢ã—ã¾ã™" -#: access/transam/xlog.c:5803 +#: access/transam/xlog.c:6016 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "リカãƒãƒªå‡¦ç†ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã®ã‚¢ãƒœãƒ¼ãƒˆã€æ™‚刻%sã®å¾Œã«åœæ­¢ã—ã¾ã™" + +#: access/transam/xlog.c:6056 #, c-format msgid "recovery has paused" -msgstr "リカãƒãƒªã¯ã™ã§ã«åœæ­¢ã•れã¦ã„ã¾ã™" +msgstr "リカãƒãƒªã¯ä¸€æ™‚åœæ­¢ä¸­ã§ã™" -#: access/transam/xlog.c:5804 +#: access/transam/xlog.c:6057 #, c-format -msgid "Execute pg_xlog_replay_resume() to continue." -msgstr "pg_xlog_replay_resume() ã‚’å‹•ã‹ã—ã¦å‡¦ç†ã‚’継続ã—ã¦ãã ã•ã„" +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "å†é–‹ã™ã‚‹ã«ã¯ pg_xlog_replay_resume() を実行ã—ã¦ãã ã•ã„" -#: access/transam/xlog.c:5934 +#: access/transam/xlog.c:6265 #, c-format msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" msgstr "%s = %d ãŒãƒžã‚¹ã‚¿ãƒ¼ã‚µãƒ¼ãƒã®è¨­å®šå€¤ï¼ˆ%d)よりå°ã•ã„ã®ã§ã€ãƒ›ãƒƒãƒˆã‚¹ã‚¿ãƒ³ãƒã‚¤ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“" -#: access/transam/xlog.c:5956 +#: access/transam/xlog.c:6291 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" -msgstr "wal_level=minimal ã§ WAL ãŒç”Ÿæˆã•れã¾ã—ãŸã€‚データãŒãªã„å ´åˆãŒã‚りã¾ã™ã€‚" +msgstr "wal_level=minimal ã§WALãŒç”Ÿæˆã•れã¾ã—ãŸã€‚データãŒå¤±ã‚れるå¯èƒ½æ€§ãŒã‚りã¾ã™" -#: access/transam/xlog.c:5957 +#: access/transam/xlog.c:6292 #, c-format msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." -msgstr "ã“れãŒèµ·ã“ã‚‹ã®ã¯ã€æ–°ã—ã„ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を行ã‚ãªã„ã§ã€ä¸€æ™‚的㫠wal_level=minimal ã«ã—ãŸå ´åˆã§ã™ã€‚" +msgstr "ã“ã‚Œã¯æ–°ã—ã„ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’å–らãšã«ã€ä¸€æ™‚的㫠wal_level=minimal ã«ã—ãŸå ´åˆã«èµ·ã“りã¾ã™ã€‚" -#: access/transam/xlog.c:5968 +#: access/transam/xlog.c:6303 #, c-format -msgid "hot standby is not possible because wal_level was not set to \"hot_standby\" on the master server" -msgstr "マスターサーãƒã§ wal_level ㌠\"hot_standby\" ã«ãªã£ã¦ã„ãªã‹ã£ãŸã®ã§ã€ãƒ›ãƒƒãƒˆã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚’使用ã§ãã¾ã›ã‚“" +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "マスターサーãƒã§wal_levelãŒ\"replica\"ã«è¨­å®šã•れã¦ã„ãªã„ãŸã‚ã€ãƒ›ãƒƒãƒˆã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚’使用ã§ãã¾ã›ã‚“" -#: access/transam/xlog.c:5969 +#: access/transam/xlog.c:6304 #, c-format -msgid "Either set wal_level to \"hot_standby\" on the master, or turn off hot_standby here." -msgstr "マスター㧠wal_level ã‚’ \"hot_standby\" ã«ã™ã‚‹ã‹ã€ã¾ãŸã¯ã“ã“ã§ãƒ›ãƒƒãƒˆã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚’無効ã«ã—ã¦ãã ã•ã„。" +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "マスターã§wal_levelã‚’\"replica\"ã«ã™ã‚‹ã‹ã€ã¾ãŸã¯ã“ã“ã§hot_standbyを無効ã«ã—ã¦ãã ã•ã„。" -#: access/transam/xlog.c:6024 +#: access/transam/xlog.c:6356 #, c-format msgid "control file contains invalid data" -msgstr "制御ファイル内ã«ç„¡åйãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" +msgstr "制御ファイル内ã«ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" -#: access/transam/xlog.c:6030 +#: access/transam/xlog.c:6362 #, c-format msgid "database system was shut down at %s" msgstr "データベースシステム㯠%s ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:6035 +#: access/transam/xlog.c:6367 #, c-format msgid "database system was shut down in recovery at %s" -msgstr "データベースシステムãŒãƒªã‚«ãƒãƒªä¸­ã« %s ã§ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" +msgstr "データベースシステムã¯ãƒªã‚«ãƒãƒªä¸­ %s ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:6039 +#: access/transam/xlog.c:6371 #, c-format msgid "database system shutdown was interrupted; last known up at %s" -msgstr "データベースシステムã®ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ãŒä¸­æ–­ã•れã¾ã—ãŸ:今回㯠%s ã¾ã§ã¯åˆ°é”ã—ã¾ã—ãŸ" +msgstr "データベースシステムã¯ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ä¸­ã«ä¸­æ–­ã•れã¾ã—ãŸ; %s ã¾ã§å‹•作ã—ã¦ã„ãŸã“ã¨ã¯ç¢ºèªã§ãã¾ã™" -#: access/transam/xlog.c:6043 +#: access/transam/xlog.c:6375 #, c-format msgid "database system was interrupted while in recovery at %s" -msgstr "データベースシステムã¯ãƒªã‚«ãƒãƒªä¸­ã« %s ã§ä¸­æ–­ã•れã¾ã—ãŸ" +msgstr "データベースシステムã¯ãƒªã‚«ãƒãƒªä¸­ %s ã«ä¸­æ–­ã•れã¾ã—ãŸ" -#: access/transam/xlog.c:6045 +#: access/transam/xlog.c:6377 #, c-format msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." -msgstr "ã“れã¯ãŠãらãデータ破æã®å¯èƒ½æ€§ãŒã‚りã€ãƒªã‚«ãƒãƒªã®ãŸã‚ã«ç›´å‰ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を使用ã—ãªã‘れã°ãªã‚‰ãªã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚" +msgstr "ã“れã¯ãŠãらãデータ破æãŒã‚りã€ãƒªã‚«ãƒãƒªã®ãŸã‚ã«ç›´å‰ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を使用ã—ãªã‘れã°ãªã‚‰ãªã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚" -#: access/transam/xlog.c:6049 +#: access/transam/xlog.c:6381 #, c-format msgid "database system was interrupted while in recovery at log time %s" -msgstr "データベースシステムã¯ãƒ­ã‚°æ™‚é–“%sã«ãƒªã‚«ãƒãƒªä¸­ã«ä¸­æ–­ã•れã¾ã—ãŸ" +msgstr "データベースシステムã¯ãƒªã‚«ãƒãƒªä¸­ãƒ­ã‚°æ™‚刻 %s ã«ä¸­æ–­ã•れã¾ã—ãŸ" -#: access/transam/xlog.c:6051 +#: access/transam/xlog.c:6383 #, c-format msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." -msgstr "ã“れãŒä½•回も発生ã™ã‚‹å ´åˆã€ãƒ‡ãƒ¼ã‚¿ãŒç ´æã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚ã“れ以å‰ã®çŠ¶æ…‹ã¾ã§ãƒªã‚«ãƒãƒªãƒ¼ã§æˆ»ã—ã¦ã‚„らãªã„ã¨ã„ã‘ãªã„ã‹ã‚‚ã—れã¾ã›ã‚“。" +msgstr "ã“れãŒ1回以上起ããŸå ´åˆã¯ãƒ‡ãƒ¼ã‚¿ãŒç ´æã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹ãŸã‚ã€ã‚ˆã‚Šä»¥å‰ã®ãƒªã‚«ãƒãƒªç›®æ¨™ã‚’é¸ã¶å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: access/transam/xlog.c:6055 +#: access/transam/xlog.c:6387 #, c-format msgid "database system was interrupted; last known up at %s" -msgstr "データベースシステムã¯ä¸­æ–­ã•れã¾ã—ãŸ: 今回㯠%s ã¾ã§ã¯åˆ°é”ã—ã¦ã„ã¾ã™" +msgstr "データベースシステムã¯ä¸­æ–­ã•れã¾ã—ãŸ: %s ã¾ã§å‹•作ã—ã¦ã„ãŸã“ã¨ã¯ç¢ºèªã§ãã¾ã™" -#: access/transam/xlog.c:6109 +#: access/transam/xlog.c:6443 #, c-format msgid "entering standby mode" msgstr "スタンãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ã«å…¥ã‚Šã¾ã™" -#: access/transam/xlog.c:6112 +#: access/transam/xlog.c:6446 #, c-format msgid "starting point-in-time recovery to XID %u" -msgstr "XID %u ã«å¯¾ã—ã¦ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¦ã„ã¾ã™" +msgstr "XID%uã¾ã§ã®ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6116 +#: access/transam/xlog.c:6450 #, c-format msgid "starting point-in-time recovery to %s" -msgstr "%s ã«å¯¾ã—ã¦ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¦ã„ã¾ã™" +msgstr "%sã¾ã§ã®ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6120 +#: access/transam/xlog.c:6454 #, c-format msgid "starting point-in-time recovery to \"%s\"" -msgstr "\"%s\" ã«å¯¾ã—ã¦ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¦ã„ã¾ã™" +msgstr "\"%s\"ã¾ã§ã®ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6124 +#: access/transam/xlog.c:6458 #, c-format -msgid "starting archive recovery" -msgstr "アーカイブリカãƒãƒªã‚’é–‹å§‹ã—ã¦ã„ã¾ã™" +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "WALä½ç½®(LSN) \"%X/%X\" ã¾ã§ã®ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6140 commands/sequence.c:1035 lib/stringinfo.c:266 -#: libpq/auth.c:1025 libpq/auth.c:1381 libpq/auth.c:1449 libpq/auth.c:1851 -#: postmaster/bgworker.c:220 postmaster/bgworker.c:413 -#: postmaster/postmaster.c:2160 postmaster/postmaster.c:2191 -#: postmaster/postmaster.c:3691 postmaster/postmaster.c:4374 -#: postmaster/postmaster.c:4460 postmaster/postmaster.c:5149 -#: postmaster/postmaster.c:5582 storage/buffer/buf_init.c:154 -#: storage/buffer/localbuf.c:397 storage/file/fd.c:403 storage/file/fd.c:800 -#: storage/file/fd.c:918 storage/file/fd.c:1531 storage/ipc/procarray.c:894 -#: storage/ipc/procarray.c:1334 storage/ipc/procarray.c:1341 -#: storage/ipc/procarray.c:1658 storage/ipc/procarray.c:2148 -#: utils/adt/formatting.c:1526 utils/adt/formatting.c:1646 -#: utils/adt/formatting.c:1767 utils/adt/regexp.c:209 utils/adt/varlena.c:3652 -#: utils/adt/varlena.c:3673 utils/fmgr/dfmgr.c:224 utils/hash/dynahash.c:379 -#: utils/hash/dynahash.c:456 utils/hash/dynahash.c:970 -#: utils/init/miscinit.c:151 utils/init/miscinit.c:172 -#: utils/init/miscinit.c:182 utils/mb/mbutils.c:374 utils/mb/mbutils.c:675 -#: utils/misc/guc.c:3432 utils/misc/guc.c:3448 utils/misc/guc.c:3461 -#: utils/misc/tzparser.c:455 utils/mmgr/aset.c:499 utils/mmgr/aset.c:678 -#: utils/mmgr/aset.c:873 utils/mmgr/aset.c:1116 +#: access/transam/xlog.c:6463 #, c-format -msgid "out of memory" -msgstr "メモリä¸è¶³ã§ã™" +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "最もå¤ã„一貫性確ä¿ç‚¹ã¾ã§ã®ãƒã‚¤ãƒ³ãƒˆã‚¤ãƒ³ã‚¿ã‚¤ãƒ ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6141 +#: access/transam/xlog.c:6466 #, c-format -msgid "Failed while allocating an XLog reading processor." -msgstr "Xlog読ã¿å–り処ç†ã‚’割り当ã¦ä¸­ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" +msgid "starting archive recovery" +msgstr "アーカイブリカãƒãƒªã‚’é–‹å§‹ã—ã¦ã„ã¾ã™" -#: access/transam/xlog.c:6166 access/transam/xlog.c:6233 +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 #, c-format msgid "checkpoint record is at %X/%X" -msgstr "%X/%Xã«ãŠã‘ã‚‹ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã¯%X/%Xã«ã‚りã¾ã™" -#: access/transam/xlog.c:6180 +#: access/transam/xlog.c:6534 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒå‚ç…§ã—ã¦ã„ã‚‹ redo ä½ç½®ã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ" -#: access/transam/xlog.c:6181 access/transam/xlog.c:6188 +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 #, c-format msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®é †åºã‚’変更ã—ã¦ã„ãªã„å ´åˆã¯ã€ãƒ•ァイル \"%s/backup_label\" を削除ã—ã¦ãã ã•ã„" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‹ã‚‰ã®ãƒªã‚¹ãƒˆã‚¢ã‚’ã—ã¦ã„ã‚‹ã®ã§ãªã‘れã°ã€ãƒ•ァイル \"%s/backup_label\" を削除ã—ã¦ã¿ã¦ãã ã•ã„。" -#: access/transam/xlog.c:6187 +#: access/transam/xlog.c:6541 #, c-format msgid "could not locate required checkpoint record" -msgstr "è¦æ±‚ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä½ç½®ã¸ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: access/transam/xlog.c:6243 access/transam/xlog.c:6258 -#, c-format -msgid "could not locate a valid checkpoint record" -msgstr "有効ãªãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: access/transam/xlog.c:6252 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "%X/%Xã«ãŠã‘ã‚‹ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã®å‰ã‚’使用ã—ã¦ã„ã¾ã™" +msgstr "å¿…è¦ãªãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" -#: access/transam/xlog.c:6282 +#: access/transam/xlog.c:6567 commands/tablespace.c:641 #, c-format -#| msgid "requested timeline %u is not a child of database system timeline %u" -msgid "requested timeline %u is not a child of this server's history" -msgstr "è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã¯ã“ã®ã‚µãƒ¼ãƒã®å±¥æ­´ã‹ã‚‰ç¶™æ‰¿ã•れã¦ã„ã¾ã›ã‚“" +msgid "could not create symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:6284 +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 #, c-format -msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." -msgstr "タイムライン%3$uã®æœ€çµ‚ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã¯%1$X/%2$Xã§ã™ãŒã€è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã®å±¥æ­´ã®ä¸­ã§ã¯ã‚µãƒ¼ãƒã¯ãã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã®%4$X/%5$Xã‹ã‚‰ãƒ•ォークã•れã¾ã—ãŸã€‚" +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "ファイル\"%2$s\"ãŒå­˜åœ¨ã—ãªã„ãŸã‚ファイル\"%1$s\"を無視ã—ã¾ã™" -#: access/transam/xlog.c:6300 +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 #, c-format -#| msgid "requested timeline %u is not a child of database system timeline %u" -msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" -msgstr "è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%1$uã¯ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%4$uã®æœ€å°ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆ%2$X/%3$Xã‚’å«ã¿ã¾ã›ã‚“" +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "ファイル\"%s\"ã¯\"%s\"ã«ãƒªãƒãƒ¼ãƒ ã•れã¾ã—ãŸã€‚" -#: access/transam/xlog.c:6309 +#: access/transam/xlog.c:6607 #, c-format -msgid "redo record is at %X/%X; shutdown %s" -msgstr "REDOレコードã¯%X/%X シャットダウン %s" +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" -#: access/transam/xlog.c:6313 +#: access/transam/xlog.c:6657 #, c-format -msgid "next transaction ID: %u/%u; next OID: %u" -msgstr "次ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ID: %u/%u 次ã®OID: %u" +msgid "could not locate a valid checkpoint record" +msgstr "有効ãªãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" -#: access/transam/xlog.c:6317 +#: access/transam/xlog.c:6695 #, c-format -msgid "next MultiXactId: %u; next MultiXactOffset: %u" -msgstr "次ã®MultiXactId: %u 次ã®MultiXactOffset: %u" +msgid "requested timeline %u is not a child of this server's history" +msgstr "è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã¯ã“ã®ã‚µãƒ¼ãƒã®å±¥æ­´ã‹ã‚‰ã®å­å­«ã§ã¯ã‚りã¾ã›ã‚“" -#: access/transam/xlog.c:6320 +#: access/transam/xlog.c:6697 #, c-format -msgid "oldest unfrozen transaction ID: %u, in database %u" -msgstr "データベース %2$u å†…ã§æœ€å¤ã®æœªå‡çµãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ ID: %1$u" +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "タイムライン%3$uã®æœ€çµ‚ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã¯%1$X/%2$Xã§ã™ãŒã€è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã®å±¥æ­´ã®ä¸­ã§ã¯ã‚µãƒ¼ãƒã¯ãã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã‹ã‚‰%4$X/%5$Xã§åˆ†å²ã—ã¦ã„ã¾ã™ã€‚" -#: access/transam/xlog.c:6323 +#: access/transam/xlog.c:6713 #, c-format -#| msgid "oldest unfrozen transaction ID: %u, in database %u" -msgid "oldest MultiXactId: %u, in database %u" -msgstr "データベース %2$u å†…ã§æœ€å¤ã®MultiXactId: %1$u" +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%1$uã¯ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%4$uã®æœ€å°ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆ%2$X/%3$Xã‚’å«ã¿ã¾ã›ã‚“" -#: access/transam/xlog.c:6327 +#: access/transam/xlog.c:6744 #, c-format msgid "invalid next transaction ID" -msgstr "次ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³IDãŒç„¡åйã§ã™" +msgstr "次ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³IDãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:6376 +#: access/transam/xlog.c:6839 #, c-format msgid "invalid redo in checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®REDOãŒç„¡åйã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ä¸æ­£ãªREDO" -#: access/transam/xlog.c:6387 +#: access/transam/xlog.c:6850 #, c-format msgid "invalid redo record in shutdown checkpoint" -msgstr "シャットダウン・ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘ã‚‹REDOレコードãŒç„¡åйã§ã™" +msgstr "シャットダウン・ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘ã‚‹ä¸æ­£ãªREDOレコード" -#: access/transam/xlog.c:6418 +#: access/transam/xlog.c:6878 #, c-format msgid "database system was not properly shut down; automatic recovery in progress" -msgstr "データベースシステムã¯é©åˆ‡ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã•れã¾ã›ã‚“ã§ã—ãŸã€‚自動リカãƒãƒªã‚’行ã£ã¦ã„ã¾ã™" +msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã¯æ­£ã—ãシャットダウンã•れã¦ã„ã¾ã›ã‚“; 自動リカãƒãƒªã‚’実行中" -#: access/transam/xlog.c:6422 +#: access/transam/xlog.c:6882 #, c-format -#| msgid "recovery target timeline %u does not exist" msgid "crash recovery starts in timeline %u and has target timeline %u" -msgstr "クラッシュリカãƒãƒªãŒã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã§å§‹ã¾ã‚Šã€å¯¾è±¡ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã‚’æŒã¡ã¾ã™" +msgstr "タイムライン%uã‹ã‚‰ã€ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uを目標ã¨ã—ã¦ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ãƒªã‚«ãƒãƒªã‚’é–‹å§‹ã—ã¾ã™" -#: access/transam/xlog.c:6459 +#: access/transam/xlog.c:6925 #, c-format msgid "backup_label contains data inconsistent with control file" -msgstr "backup_labelã«åˆ¶å¾¡ãƒ•ァイルã¨ä¸€è²«æ€§ãŒãªã„データãŒå«ã¾ã‚Œã¾ã™" +msgstr "backup_labelã«åˆ¶å¾¡ãƒ•ã‚¡ã‚¤ãƒ«ã¨æ•´åˆã—ãªã„データãŒå«ã¾ã‚Œã¾ã™" -#: access/transam/xlog.c:6460 +#: access/transam/xlog.c:6926 #, c-format msgid "This means that the backup is corrupted and you will have to use another backup for recovery." -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒç ´æã—ã¦ãŠã‚Šã€ãƒªã‚«ãƒãƒªã®ãŸã‚ã«ã¯ä»–ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を使用ã—ãªã‘れã°ãªã‚‰ãªã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚" +msgstr "ã“れã¯ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒç ´æã—ã¦ãŠã‚Šã€ãƒªã‚«ãƒãƒªã«ã¯ä»–ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を使用ã—ãªã‘れã°ãªã‚‰ãªã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚" -#: access/transam/xlog.c:6525 +#: access/transam/xlog.c:7017 #, c-format msgid "initializing for hot standby" msgstr "ホットスタンãƒã‚¤ã®ãŸã‚ã®åˆæœŸåŒ–を行ã£ã¦ã„ã¾ã™" -#: access/transam/xlog.c:6662 +#: access/transam/xlog.c:7149 #, c-format msgid "redo starts at %X/%X" -msgstr "%X/%Xã®REDOã‚’é–‹å§‹ã—ã¾ã™" +msgstr "REDOã‚’%X/%Xã‹ã‚‰é–‹å§‹ã—ã¾ã™" + +#: access/transam/xlog.c:7383 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "è¦æ±‚ã•れãŸãƒªã‚«ãƒãƒªåœæ­¢ãƒã‚¤ãƒ³ãƒˆã¯ã€ä¸€è²«æ€§ãŒã‚るリカãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚ˆã‚Šå‰ã«ã‚りã¾ã™" -#: access/transam/xlog.c:6853 +#: access/transam/xlog.c:7421 #, c-format msgid "redo done at %X/%X" -msgstr "%X/%Xã®REDOãŒçµ‚ã‚りã¾ã—ãŸ" +msgstr "REDOãŒ%X/%Xã§çµ‚了ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:6858 access/transam/xlog.c:8688 +#: access/transam/xlog.c:7426 #, c-format msgid "last completed transaction was at log time %s" -msgstr "最後ã«å®Œäº†ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ãƒ­ã‚°æ™‚刻%sã§ã—ãŸ" +msgstr "最後ã«å®Œäº†ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒ­ã‚°æ™‚刻ã¯%sã§ã—ãŸ" -#: access/transam/xlog.c:6866 +#: access/transam/xlog.c:7435 #, c-format msgid "redo is not required" msgstr "REDOã¯å¿…è¦ã‚りã¾ã›ã‚“" -#: access/transam/xlog.c:6914 -#, c-format -msgid "requested recovery stop point is before consistent recovery point" -msgstr "è¦æ±‚ã•れãŸãƒªã‚«ãƒãƒªåœæ­¢ãƒã‚¤ãƒ³ãƒˆãŒã€å¯¾å¿œã™ã‚‹ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚ˆã‚Šå‰ã«ã‚りã¾ã™" - -#: access/transam/xlog.c:6930 access/transam/xlog.c:6934 +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 #, c-format msgid "WAL ends before end of online backup" -msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®çµ‚了よりå‰ã« WAL ãŒçµ‚了ã—ã¾ã—ãŸ" +msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®çµ‚了よりå‰ã«WALãŒçµ‚了ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:6931 +#: access/transam/xlog.c:7511 #, c-format msgid "All WAL generated while online backup was taken must be available at recovery." -msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—å–得期間ã«ç”Ÿæˆã•れãŸã™ã¹ã¦ã®WALã¯ã€ãƒªã‚«ãƒãƒªæ™‚ã«åˆ©ç”¨å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—中ã«ç”Ÿæˆã•れãŸã™ã¹ã¦ã®WALãŒãƒªã‚«ãƒãƒªã§åˆ©ç”¨å¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: access/transam/xlog.c:6935 +#: access/transam/xlog.c:7515 #, c-format msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." -msgstr "pg_start_backup() を使ã£ãŸã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—㯠pg_stop_backup() ã§çµ‚了ã™ã‚‹å¿…è¦ãŒã‚りã€ã¾ãŸãã®æ™‚点ã¾ã§ã®ã™ã¹ã¦ã® WAL ã¯ãƒªã‚«ãƒãƒªã«ãŠã„ã¦åˆ©ç”¨å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "pg_start_backup() を使ã£ãŸã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—㯠pg_stop_backup() ã§çµ‚了ãªã‘れã°ãªã‚‰ãšã€ã‹ã¤ãã®æ™‚点ã¾ã§ã®ã™ã¹ã¦ã®WALã¯ãƒªã‚«ãƒãƒªã§åˆ©ç”¨å¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: access/transam/xlog.c:6938 +#: access/transam/xlog.c:7518 #, c-format msgid "WAL ends before consistent recovery point" -msgstr "WAL ãŒå¯¾å¿œã™ã‚‹ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚ˆã‚Šå‰ã§çµ‚了ã—ã¾ã™" +msgstr "WALãŒä¸€è²«æ€§ãŒã‚るリカãƒãƒªãƒã‚¤ãƒ³ãƒˆã‚ˆã‚Šå‰ã§çµ‚了ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:6965 +#: access/transam/xlog.c:7552 #, c-format msgid "selected new timeline ID: %u" -msgstr "é¸æŠžã•ã‚ŒãŸæ–°ã—ã„タイムラインID: %u" +msgstr "æ–°ã—ã„タイムラインIDã‚’é¸æŠž: %u" -#: access/transam/xlog.c:7325 +#: access/transam/xlog.c:7989 #, c-format msgid "consistent recovery state reached at %X/%X" -msgstr "%X/%X ã§ãƒªã‚«ãƒãƒªãƒ¼çŠ¶æ…‹ã®æ•´åˆãŒå–れã¾ã—ãŸ" +msgstr "%X/%X ã§ãƒªã‚«ãƒãƒªã®ä¸€è²«æ€§ãŒç¢ºä¿ã•れã¾ã—ãŸ" -#: access/transam/xlog.c:7496 +#: access/transam/xlog.c:8181 #, c-format msgid "invalid primary checkpoint link in control file" -msgstr "制御ファイル内ã®ãƒ—ライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒªãƒ³ã‚¯ãŒç„¡åйã§ã™" - -#: access/transam/xlog.c:7500 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "制御ファイル内ã®ã‚»ã‚«ãƒ³ãƒ€ãƒªãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒªãƒ³ã‚¯ãŒç„¡åйã§ã™" +msgstr "åˆ¶å¾¡ãƒ•ã‚¡ã‚¤ãƒ«å†…ã®æœ€åˆã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã¸ã®ãƒªãƒ³ã‚¯ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7504 +#: access/transam/xlog.c:8185 #, c-format msgid "invalid checkpoint link in backup_label file" -msgstr "backup_labelファイル内ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒªãƒ³ã‚¯ãŒç„¡åйã§ã™" +msgstr "backup_labelファイル内ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã¸ã®ãƒªãƒ³ã‚¯ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7521 +#: access/transam/xlog.c:8202 #, c-format msgid "invalid primary checkpoint record" -msgstr "プライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒç„¡åйã§ã™" - -#: access/transam/xlog.c:7525 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "セカンダリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒç„¡åйã§ã™" +msgstr "最åˆã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7529 +#: access/transam/xlog.c:8206 #, c-format msgid "invalid checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒç„¡åйã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7540 +#: access/transam/xlog.c:8217 #, c-format msgid "invalid resource manager ID in primary checkpoint record" -msgstr "プライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒç„¡åйã§ã™" - -#: access/transam/xlog.c:7544 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "セカンダリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒç„¡åйã§ã™" +msgstr "プライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7548 +#: access/transam/xlog.c:8221 #, c-format msgid "invalid resource manager ID in checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒç„¡åйã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒã§ä¸æ­£ã§ã™" -#: access/transam/xlog.c:7560 +#: access/transam/xlog.c:8234 #, c-format msgid "invalid xl_info in primary checkpoint record" -msgstr "プライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒç„¡åйã§ã™" - -#: access/transam/xlog.c:7564 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "セカンダリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒç„¡åйã§ã™" +msgstr "最åˆã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7568 +#: access/transam/xlog.c:8238 #, c-format msgid "invalid xl_info in checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒç„¡åйã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7580 +#: access/transam/xlog.c:8249 #, c-format msgid "invalid length of primary checkpoint record" -msgstr "プライマリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºãŒç„¡åйã§ã™" - -#: access/transam/xlog.c:7584 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "セカンダリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºãŒç„¡åйã§ã™" +msgstr "最åˆã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7588 +#: access/transam/xlog.c:8253 #, c-format msgid "invalid length of checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºãŒç„¡åйã§ã™" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒä¸æ­£ã§ã™" -#: access/transam/xlog.c:7748 +#: access/transam/xlog.c:8459 #, c-format msgid "shutting down" msgstr "シャットダウンã—ã¦ã„ã¾ã™" -#: access/transam/xlog.c:7771 +#: access/transam/xlog.c:8779 #, c-format -msgid "database system is shut down" -msgstr "データベースシステムã¯ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" +msgid "checkpoint skipped because system is idle" +msgstr "システムãŒã‚¢ã‚¤ãƒ‰ãƒ«çŠ¶æ…‹ãªãŸã‚ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒã‚¹ã‚­ãƒƒãƒ—ã•れã¾ã—ãŸ" -#: access/transam/xlog.c:8237 +#: access/transam/xlog.c:8984 #, c-format -msgid "concurrent transaction log activity while database system is shutting down" -msgstr "データベースシャットダウン中ã«ã€åŒæ™‚ã«å®Ÿè¡Œä¸­ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ­ã‚°å‡¦ç†ãŒã‚りã¾ã—ãŸ" +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "データベースã®ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã«ä¸¦è¡Œã—ã¦ã€å…ˆè¡Œæ›¸ãã“ã¿ãƒ­ã‚°ãŒç™ºç”Ÿã—ã¾ã—ãŸ" -#: access/transam/xlog.c:8514 +#: access/transam/xlog.c:9241 #, c-format msgid "skipping restartpoint, recovery has already ended" -msgstr "å†é–‹ãƒã‚¤ãƒ³ãƒˆã‚’スキップã—ã¾ã™ã€‚リカãƒãƒªã¯ã™ã§ã«çµ‚ã‚ã£ã¦ã„ã¾ã™ã€‚" +msgstr "å†é–‹ãƒã‚¤ãƒ³ãƒˆã‚’スキップã—ã¾ã™ã€ãƒªã‚«ãƒãƒªã¯ã™ã§ã«çµ‚ã‚ã£ã¦ã„ã¾ã™" -#: access/transam/xlog.c:8537 +#: access/transam/xlog.c:9264 #, c-format msgid "skipping restartpoint, already performed at %X/%X" -msgstr "%X/%X ã§ã™ã§ã«å®Ÿè¡Œæ¸ˆã¿ã®å†é–‹ãƒã‚¤ãƒ³ãƒˆã‚’スキップã—ã¦ã„ã¾ã™" +msgstr "%X/%X ã§ã™ã§ã«å®Ÿè¡Œæ¸ˆã¿ã®å†é–‹ãƒã‚¤ãƒ³ãƒˆã‚’スキップã—ã¾ã™" -#: access/transam/xlog.c:8686 +#: access/transam/xlog.c:9431 #, c-format msgid "recovery restart point at %X/%X" -msgstr "ãƒã‚¤ãƒ³ãƒˆ %X/%X ã§ãƒªã‚«ãƒãƒªã‚’å†é–‹ã—ã¾ã™" +msgstr "リカãƒãƒªå†é–‹ãƒã‚¤ãƒ³ãƒˆã¯%X/%Xã§ã™" + +#: access/transam/xlog.c:9433 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "最後ã«å®Œäº†ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ãƒ­ã‚°æ™‚刻 %s ã®ã‚‚ã®ã§ã™" -#: access/transam/xlog.c:8812 +#: access/transam/xlog.c:9567 #, c-format msgid "restore point \"%s\" created at %X/%X" -msgstr "%2$X/%3$X ã«ãƒªã‚¹ãƒˆã‚¢ãƒã‚¤ãƒ³ãƒˆ \"%1$s\" を書ãè¾¼ã¿ã¾ã—ãŸ" +msgstr "復帰ãƒã‚¤ãƒ³ãƒˆ\"%s\"ãŒ%X/%Xã«ä½œæˆã•れã¾ã—ãŸ" -#: access/transam/xlog.c:9030 +#: access/transam/xlog.c:9705 #, c-format -#| msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦æƒ³å®šå¤–ã®å‰å›žã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID %u(ç¾åœ¨ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³IDã¯%u)ãŒã‚りã¾ã—ãŸ" -#: access/transam/xlog.c:9039 +#: access/transam/xlog.c:9714 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦æƒ³å®šå¤–ã®æ™‚系列ID %u(%uã®å¾Œ)ãŒã‚りã¾ã—ãŸ" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦æƒ³å®šå¤–ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID %u (%uã®å¾Œ)ãŒã‚りã¾ã—ãŸ" -#: access/transam/xlog.c:9055 +#: access/transam/xlog.c:9730 #, c-format msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" msgstr "タイムライン%4$uã®æœ€å°ãƒªã‚«ãƒãƒªãƒã‚¤ãƒ³ãƒˆ%2$X/%3$Xã«é”ã™ã‚‹å‰ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®æƒ³å®šå¤–ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID%1$u。" -#: access/transam/xlog.c:9122 +#: access/transam/xlog.c:9806 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã€ãƒªã‚«ãƒãƒªã‚’継続ã§ãã¾ã›ã‚“" -#: access/transam/xlog.c:9183 access/transam/xlog.c:9231 -#: access/transam/xlog.c:9254 +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 +#: access/transam/xlog.c:9941 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦æƒ³å®šå¤–ã®æ™‚系列ID %u(%uã®ã¯ãš)ãŒã‚りã¾ã—ãŸ" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ã«ãŠã„ã¦æƒ³å®šå¤–ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID %u(%uã®ã¯ãš)ãŒã‚りã¾ã—ãŸ" -#: access/transam/xlog.c:9488 +#: access/transam/xlog.c:10222 #, c-format -#| msgid "could not fsync log file %u, segment %u: %m" msgid "could not fsync log segment %s: %m" -msgstr "ログファイル%sã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "ログセグメントファイル%sã«fsyncã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:9512 +#: access/transam/xlog.c:10247 #, c-format -#| msgid "could not fsync file \"%s\": %m" msgid "could not fsync log file %s: %m" -msgstr "ログファイル%sã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "ログファイル%sã®fsyncã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:9520 +#: access/transam/xlog.c:10255 #, c-format -#| msgid "could not fsync write-through log file %u, segment %u: %m" msgid "could not fsync write-through log file %s: %m" -msgstr "write-throughログファイル%sã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "ライトスルーログファイル%sã®fsyncã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:9529 +#: access/transam/xlog.c:10264 #, c-format -#| msgid "could not fdatasync log file %u, segment %u: %m" msgid "could not fdatasync log file %s: %m" -msgstr "ログファイル%sã‚’fdatasyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/xlog.c:9601 access/transam/xlog.c:9939 -#, c-format -msgid "must be superuser or replication role to run a backup" -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を実行ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザもã—ãã¯ãƒ¬ãƒ—リケーションロールã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: access/transam/xlog.c:9609 access/transam/xlog.c:9947 -#: access/transam/xlogfuncs.c:109 access/transam/xlogfuncs.c:141 -#: access/transam/xlogfuncs.c:183 access/transam/xlogfuncs.c:207 -#: access/transam/xlogfuncs.c:289 access/transam/xlogfuncs.c:363 -#, c-format -msgid "recovery is in progress" -msgstr "リカãƒãƒªãƒ¼ã¯ã™ã§ã«å®Ÿè¡Œä¸­ã§ã™" +msgstr "ログファイル%sã®fdatasyncã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:9610 access/transam/xlog.c:9948 -#: access/transam/xlogfuncs.c:110 access/transam/xlogfuncs.c:142 -#: access/transam/xlogfuncs.c:184 access/transam/xlogfuncs.c:208 +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 +#: access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 +#: access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 +#: access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." -msgstr "リカãƒãƒªãƒ¼ä¸­ã¯ WAL 制御関数を実行ã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªä¸­ã¯WAL制御関数ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“。" -#: access/transam/xlog.c:9619 access/transam/xlog.c:9957 +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 #, c-format msgid "WAL level not sufficient for making an online backup" -msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を行ã†ã«ã¯ WAL レベルãŒä¸è¶³ã—ã¦ã„ã¾ã™" +msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を行ã†ã«ã¯WALレベルãŒä¸å分ã§ã™" -#: access/transam/xlog.c:9620 access/transam/xlog.c:9958 -#: access/transam/xlogfuncs.c:148 +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 +#: access/transam/xlogfuncs.c:320 #, c-format -msgid "wal_level must be set to \"archive\" or \"hot_standby\" at server start." -msgstr "サーãƒã®é–‹å§‹æ™‚ã« wal_level ã‚’ \"archive\" ã¾ãŸã¯ \"hot_standby\" ã«ã‚»ãƒƒãƒˆã—ã¦ãã ã•ã„" +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "サーãƒã®é–‹å§‹æ™‚ã«wal_levelã‚’\"replica\"ã¾ãŸã¯ \"logical\"ã«ã‚»ãƒƒãƒˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: access/transam/xlog.c:9625 +#: access/transam/xlog.c:10370 #, c-format msgid "backup label too long (max %d bytes)" -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ラベルãŒé•·ã™ãŽã¾ã™(最大 %d ãƒã‚¤ãƒˆ)" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ラベルãŒé•·ã™ãŽã¾ã™ (最大%dãƒã‚¤ãƒˆ)" -#: access/transam/xlog.c:9656 access/transam/xlog.c:9833 +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 +#: access/transam/xlog.c:10721 #, c-format msgid "a backup is already in progress" msgstr "ã™ã§ã«ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒé€²è¡Œä¸­ã§ã™" -#: access/transam/xlog.c:9657 +#: access/transam/xlog.c:10408 #, c-format msgid "Run pg_stop_backup() and try again." -msgstr "pg_stop_backup()を実行ã—ã€å†è©¦è¡Œã—ã¦ãã ã•ã„" +msgstr "pg_stop_backup()を実行後ã«å†è©¦è¡Œã—ã¦ãã ã•ã„" -#: access/transam/xlog.c:9751 +#: access/transam/xlog.c:10504 #, c-format msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" -msgstr "full_page_writes=offã§ç”Ÿæˆã•れãŸWALã¯æœ€çµ‚リスタートãƒã‚¤ãƒ³ãƒˆä»¥é™å†ç”Ÿã•れã¾ã™" +msgstr "full_page_writes=off ã§ç”Ÿæˆã•れãŸWALã¯æœ€çµ‚リスタートãƒã‚¤ãƒ³ãƒˆã‹ã‚‰å†ç”Ÿã•れã¾ã™" -#: access/transam/xlog.c:9753 access/transam/xlog.c:10108 +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 #, c-format -#| msgid "This means that the backup being taken on standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." -msgstr "ã¤ã¾ã‚Šã‚¹ã‚¿ãƒ³ãƒã‚¤ã§å–å¾—ã•れãŸãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒç ´æã—ã¦ã„ã‚‹ãŸã‚使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。マスタã§full_page_writesを有効ã«ã—CHECKPOINTを実行ã—ã€å†åº¦ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を試行ã—ã¦ãã ã•ã„。" +msgstr "ã¤ã¾ã‚Šã‚¹ã‚¿ãƒ³ãƒã‚¤ã§å–å¾—ã•れãŸãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒç ´æã—ã¦ã„ã‚‹ãŸã‚使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。マスタã§full_page_writesを有効ã«ã—CHECKPOINTを実行ã—ãŸã®ã¡ã€å†åº¦ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を試行ã—ã¦ãã ã•ã„。" -#: access/transam/xlog.c:9827 access/transam/xlog.c:9998 -#: access/transam/xlogarchive.c:106 access/transam/xlogarchive.c:265 -#: guc-file.l:771 replication/basebackup.c:372 replication/basebackup.c:427 -#: storage/file/copydir.c:75 storage/file/copydir.c:118 utils/adt/dbsize.c:69 -#: utils/adt/dbsize.c:219 utils/adt/dbsize.c:299 utils/adt/genfile.c:108 -#: utils/adt/genfile.c:280 +#: access/transam/xlog.c:10574 replication/basebackup.c:1232 +#: utils/adt/misc.c:517 #, c-format -msgid "could not stat file \"%s\": %m" -msgstr "ファイル\"%s\"ã®statãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not read symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を読ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:9834 +#: access/transam/xlog.c:10581 replication/basebackup.c:1237 +#: utils/adt/misc.c:522 #, c-format -msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を行ã£ã¦ã„ãªã„ã“ã¨ãŒç¢ºå®Ÿã§ã‚れã°ã€ãƒ•ァイル\"%s\"を削除ã—ã€å†å®Ÿè¡Œã—ã¦ãã ã•ã„" +msgid "symbolic link \"%s\" target is too long" +msgstr "シンボリックリンク\"%s\"ã®å‚ç…§å…ˆãŒé•·ã™ãŽã¾ã™" -#: access/transam/xlog.c:9851 access/transam/xlog.c:10171 +#: access/transam/xlog.c:10633 commands/tablespace.c:391 +#: commands/tablespace.c:553 replication/basebackup.c:1252 utils/adt/misc.c:530 #, c-format -msgid "could not write file \"%s\": %m" -msgstr "ファイル\"%s\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: access/transam/xlog.c:10002 +msgid "tablespaces are not supported on this platform" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ãƒ†ãƒ¼ãƒ–ル空間ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 +#: access/transam/xlog.c:10930 access/transam/xlogarchive.c:104 +#: access/transam/xlogarchive.c:264 commands/copy.c:1890 commands/copy.c:3199 +#: commands/extension.c:3319 commands/tablespace.c:782 +#: commands/tablespace.c:873 guc-file.l:1004 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1525 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1733 +#: storage/file/fd.c:3113 storage/file/fd.c:3295 storage/file/fd.c:3380 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:131 utils/adt/genfile.c:382 #, c-format -msgid "a backup is not in progress" -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒå®Ÿè¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" +msgid "could not stat file \"%s\": %m" +msgstr "ファイル\"%s\"ã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlog.c:10028 access/transam/xlogarchive.c:114 -#: access/transam/xlogarchive.c:466 storage/smgr/md.c:405 -#: storage/smgr/md.c:454 storage/smgr/md.c:1318 +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 #, c-format -msgid "could not remove file \"%s\": %m" -msgstr "ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒé€²è¡Œä¸­ã§ãªã„ã“ã¨ãŒç¢ºã‹ã§ã‚れã°ã€ãƒ•ァイル\"%s\"を削除ã—å†å®Ÿè¡Œã—ã¦ãã ã•ã„。" + +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 +#: access/transam/xlog.c:11150 postmaster/syslogger.c:1476 +#: postmaster/syslogger.c:1489 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "ファイル\"%s\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/xlog.c:10907 +#, c-format +msgid "exclusive backup not in progress" +msgstr "排他ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯é€²è¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" -#: access/transam/xlog.c:10041 access/transam/xlog.c:10054 -#: access/transam/xlog.c:10405 access/transam/xlog.c:10411 -#: access/transam/xlogfuncs.c:616 +#: access/transam/xlog.c:10934 +#, c-format +msgid "a backup is not in progress" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒé€²è¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" + +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 +#: access/transam/xlog.c:11394 access/transam/xlog.c:11400 +#: access/transam/xlog.c:11448 access/transam/xlog.c:11521 +#: access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" -msgstr "ファイル\"%s\"内ã®ãƒ‡ãƒ¼ã‚¿ãŒç„¡åйã§ã™" +msgstr "ファイル\"%s\"内ã®ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿" -#: access/transam/xlog.c:10058 replication/basebackup.c:826 +#: access/transam/xlog.c:11037 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—中ã«ã‚¹ã‚¿ãƒ³ãƒã‚¤ãŒæ˜‡æ ¼ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:10059 replication/basebackup.c:827 +#: access/transam/xlog.c:11038 replication/basebackup.c:1090 #, c-format msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." -msgstr "ã¤ã¾ã‚Šå–得中ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯ç ´æã—ã¦ã„ã‚‹ãŸã‚使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。別ã®ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’å–å¾—ã—ã¦ãã ã•ã„。" +msgstr "ã¤ã¾ã‚Šå–得中ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯ç ´æã—ã¦ã„ã‚‹ãŸã‚使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。å†åº¦ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’å–å¾—ã—ã¦ãã ã•ã„。" -#: access/transam/xlog.c:10106 +#: access/transam/xlog.c:11085 #, c-format msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "full_page_writes=offã§ç”Ÿæˆã•れãŸWALã¯ã‚ªãƒ³ãƒ©ã‚¤ãƒ³ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—中ã«å†ç”Ÿã•れã¾ã™" -#: access/transam/xlog.c:10220 +#: access/transam/xlog.c:11205 #, c-format msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" msgstr "pg_stop_backup ã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—ãŒçµ‚了ã—ã€è¦æ±‚ã•れ㟠WAL セグメントãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れるã®ã‚’å¾…ã£ã¦ã„ã¾ã™" -#: access/transam/xlog.c:10230 +#: access/transam/xlog.c:11215 #, c-format msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "pg_stop_backup ã¯æœªã ã«è¦æ±‚ã•れãŸã™ã¹ã¦ã® WAL セグメントãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れるã®ã‚’å¾…ã£ã¦ã„ã¾ã™ï¼ˆ%d 秒経éŽï¼‰" -#: access/transam/xlog.c:10232 +#: access/transam/xlog.c:11217 #, c-format msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." msgstr "archive_commandãŒé©åˆ‡ã«å®Ÿè¡Œã•れãŸã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。pg_stop_backupã¯å®‰å…¨ã«å–り消ã™ã“ã¨ãŒã§ãã¾ã™ãŒã€ã™ã¹ã¦ã®WALセグメントãŒãªã„ã¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。" -#: access/transam/xlog.c:10239 +#: access/transam/xlog.c:11224 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" -msgstr "pg_stop_backup ãŒå®Œäº†ã—ã€è¦æ±‚ã•れãŸã™ã¹ã¦ã® WAL セグメントãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れã¾ã—ãŸ" +msgstr "pg_stop_backup ãŒå®Œäº†ã—ã€å¿…è¦ãªã™ã¹ã¦ã®WALセグメントãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れã¾ã—ãŸ" -#: access/transam/xlog.c:10243 +#: access/transam/xlog.c:11228 #, c-format msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" -msgstr "WAL ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ãŒæœ‰åйã«ãªã£ã¦ã„ã¾ã›ã‚“ã€‚è¦æ±‚ã•れãŸã™ã¹ã¦ã® WAL セグメントãŒåˆ¥ã®æ–¹æ³•ã§ã‚³ãƒ”ーã•れã€ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒå®Œäº†ã§ãã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" +msgstr "WAL ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ãŒæœ‰åйã«ãªã£ã¦ã„ã¾ã›ã‚“。ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を完了ã•ã›ã‚‹ã«ã¯ã€ã™ã¹ã¦ã®å¿…è¦ãªWALセグメントãŒä»–ã®æ–¹æ³•ã§ã‚³ãƒ”ーã•れãŸã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。" -#: access/transam/xlog.c:10456 +#: access/transam/xlog.c:11431 #, c-format -msgid "xlog redo %s" -msgstr "xlog å†å®Ÿè¡Œ %s" +msgid "backup time %s in file \"%s\"" +msgstr "ファイル\"%2$s\"内ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—時刻㯠%1$s" -#: access/transam/xlog.c:10496 +#: access/transam/xlog.c:11436 #, c-format -msgid "online backup mode canceled" -msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—モードãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" +msgid "backup label %s in file \"%s\"" +msgstr "ファイル\"%2$s\"内ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ラベル㯠%1$s" -#: access/transam/xlog.c:10497 +#: access/transam/xlog.c:11449 #, c-format -msgid "\"%s\" was renamed to \"%s\"." -msgstr "\"%s\" 㯠\"%s\" ã«ãƒªãƒãƒ¼ãƒ ã•れã¾ã—ãŸ" +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "読ã¿å–られãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³IDã¯%uã§ã—ãŸãŒã€%uã§ã‚ã‚‹ã¯ãšã§ã™" -#: access/transam/xlog.c:10504 +#: access/transam/xlog.c:11453 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "ファイル\"%2$s\"内ã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—タイムライン㯠%1$u" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11561 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "%X/%Xã«ã‚ã‚‹%sã®WALå†ç”Ÿ" + +#: access/transam/xlog.c:11610 #, c-format msgid "online backup mode was not canceled" msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—モードã¯ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¦ã„ã¾ã›ã‚“" -#: access/transam/xlog.c:10505 +#: access/transam/xlog.c:11611 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m。" + +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 +#: access/transam/xlog.c:11642 #, c-format -msgid "Could not rename \"%s\" to \"%s\": %m." -msgstr "\"%s\" ã¨ã„ã†åå‰ã‚’ \"%s\" ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "online backup mode canceled" +msgstr "オンラインãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—モードãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" + +#: access/transam/xlog.c:11633 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "ファイル\"%s\"ã€\"%s\"ã®åå‰ã¯ãれãžã‚Œ\"%s\"ã€\"%s\"ã¸ã¨å¤‰æ›´ã•れã¾ã—ãŸã€‚" -#: access/transam/xlog.c:10625 replication/walreceiver.c:930 -#: replication/walsender.c:1338 +#: access/transam/xlog.c:11643 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "ファイル\"%s\"ã®åå‰ã¯\"%s\"ã«å¤‰æ›´ã§ãã¾ã—ãŸãŒã€\"%s\"ã®åå‰ã¯\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 +#: replication/walreceiver.c:1019 replication/walsender.c:2424 #, c-format -#| msgid "could not seek in log file %u, segment %u to offset %u: %m" msgid "could not seek in log segment %s to offset %u: %m" msgstr "ログセグメント%sをオフセット%uã¾ã§ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:10637 +#: access/transam/xlog.c:11785 #, c-format -#| msgid "could not read from log file %u, segment %u, offset %u: %m" msgid "could not read from log segment %s, offset %u: %m" msgstr "ログセグメント%sã€ã‚ªãƒ•セット%uを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlog.c:11101 +#: access/transam/xlog.c:12314 #, c-format msgid "received promote request" -msgstr "æŽ¨é€²è¦æ±‚(promote request)ã‚’å—ã‘å–りã¾ã—ãŸ" +msgstr "æ˜‡æ ¼è¦æ±‚ã‚’å—ä¿¡ã—ã¾ã—ãŸ" -#: access/transam/xlog.c:11114 +#: access/transam/xlog.c:12327 #, c-format msgid "trigger file found: %s" -msgstr "トリガファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸï¼š%s" +msgstr "トリガファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ: %s" + +#: access/transam/xlog.c:12336 +#, c-format +msgid "could not stat trigger file \"%s\": %m" +msgstr "トリガファイル\"%s\"ã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: access/transam/xlogarchive.c:244 +#: access/transam/xlogarchive.c:243 #, c-format msgid "archive file \"%s\" has wrong size: %lu instead of %lu" -msgstr "アーカイブファイル\"%s\"ã®ã‚µã‚¤ã‚ºãŒä¸æ­£ã§ã™: %lu。%luを想定" +msgstr "アーカイブファイル\"%s\"ã®ã‚µã‚¤ã‚ºãŒä¸æ­£ã§ã™: %luã€æ­£ã—ãã¯%lu" -#: access/transam/xlogarchive.c:253 +#: access/transam/xlogarchive.c:252 #, c-format msgid "restored log file \"%s\" from archive" msgstr "ログファイル\"%s\"をアーカイブã‹ã‚‰ãƒªã‚¹ãƒˆã‚¢ã—ã¾ã—ãŸ" -#: access/transam/xlogarchive.c:303 +#: access/transam/xlogarchive.c:297 #, c-format -msgid "could not restore file \"%s\" from archive: return code %d" -msgstr "アーカイブã‹ã‚‰ãƒ•ァイル\"%s\"をリストアã§ãã¾ã›ã‚“ã§ã—ãŸ: 戻りコード %d" +msgid "could not restore file \"%s\" from archive: %s" +msgstr "ファイル\"%s\"をアーカイブã‹ã‚‰ãƒªã‚¹ãƒˆã‚¢ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" #. translator: First %s represents a recovery.conf parameter name like -#. "recovery_end_command", and the 2nd is the value of that parameter. -#: access/transam/xlogarchive.c:414 +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:406 #, c-format -msgid "%s \"%s\": return code %d" -msgstr "%s \"%s\": リターンコード %d" +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:593 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1500 +#: replication/logical/snapbuild.c:1663 replication/slot.c:598 +#: replication/slot.c:1211 replication/slot.c:1326 storage/file/fd.c:650 +#: storage/file/fd.c:745 utils/time/snapmgr.c:1318 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "アーカイブステータスファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:601 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" -msgstr "アーカイブステータスファイル\\\"%s\\\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "アーカイブステータスファイル\"%s\"ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlogfuncs.c:104 +#: access/transam/xlogfuncs.c:54 #, c-format -msgid "must be superuser to switch transaction log files" -msgstr "トランザクションログファイルを切り替ãˆã‚‰ã‚Œã‚‹ã®ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã ã‘ã§ã™" +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãŒ pg_stop_backup ã®å‘¼ã³å‡ºã—å‰ã«çµ‚了ã—ãŸãŸã‚ã€ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯ç•°å¸¸çµ‚了ã—ã¾ã—ãŸ" -#: access/transam/xlogfuncs.c:136 +#: access/transam/xlogfuncs.c:84 #, c-format -msgid "must be superuser to create a restore point" -msgstr "リストアãƒã‚¤ãƒ³ãƒˆã‚’作れるã®ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã ã‘ã§ã™" +msgid "a backup is already in progress in this session" +msgstr "ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§ã¯ã™ã§ã«ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒé€²è¡Œä¸­ã§ã™" -#: access/transam/xlogfuncs.c:147 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format -msgid "WAL level not sufficient for creating a restore point" -msgstr "リストアãƒã‚¤ãƒ³ãƒˆã‚’作るã«ã¯ WAL レベルãŒä¸è¶³ã—ã¦ã„ã¾ã™" +msgid "non-exclusive backup in progress" +msgstr "éžæŽ’ä»–ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒé€²è¡Œä¸­ã§ã™" -#: access/transam/xlogfuncs.c:155 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format -msgid "value too long for restore point (maximum %d characters)" -msgstr "リストアãƒã‚¤ãƒ³ãƒˆã¨ã—ã¦ã¯å€¤ãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§ %d 文字)" +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "pg_stop_backup('f') を実行ã—よã†ã¨ã—ã¦ã„ãŸã®ã§ã¯ãªã„ã§ã™ã‹?" + +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 +#: commands/event_trigger.c:2016 commands/extension.c:1895 +#: commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:722 +#: executor/execExpr.c:2209 executor/execSRF.c:715 executor/functions.c:1034 +#: foreign/foreign.c:488 libpq/hba.c:2603 replication/logical/launcher.c:1127 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 +#: replication/slotfuncs.c:200 replication/walsender.c:3203 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 +#: utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8829 +#: utils/mmgr/portalmem.c:1134 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "ã“ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§é›†åˆå€¤ã®é–¢æ•°ã¯é›†åˆã‚’å—ã‘付ã‘られã¾ã›ã‚“" + +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 +#: commands/event_trigger.c:2020 commands/extension.c:1899 +#: commands/extension.c:2008 commands/extension.c:2232 commands/prepare.c:726 +#: foreign/foreign.c:493 libpq/hba.c:2607 replication/logical/launcher.c:1131 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 +#: replication/slotfuncs.c:204 replication/walsender.c:3207 +#: utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 +#: utils/misc/guc.c:8833 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "マテリアライズモードãŒå¿…è¦ã§ã™ãŒã€ç¾åœ¨ã®ã‚³ãƒ³ãƒ†ã‚¯ã‚¹ãƒˆã§ç¦æ­¢ã•れã¦ã„ã¾ã™" + +#: access/transam/xlogfuncs.c:241 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "éžæŽ’ä»–ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¯é€²è¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" + +#: access/transam/xlogfuncs.c:242 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "pg_stop_backup('t') を実行ã—よã†ã¨ã—ã¦ã„ãŸã®ã§ã¯ãªã„ã§ã™ã‹?" -#: access/transam/xlogfuncs.c:290 +#: access/transam/xlogfuncs.c:319 #, c-format -msgid "pg_xlogfile_name_offset() cannot be executed during recovery." -msgstr "リカãƒãƒªä¸­ã¯ pg_xlogfile_name_offset() を実行ã§ãã¾ã›ã‚“" +msgid "WAL level not sufficient for creating a restore point" +msgstr "リストアãƒã‚¤ãƒ³ãƒˆã‚’作るã«ã¯WALレベルãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: access/transam/xlogfuncs.c:302 access/transam/xlogfuncs.c:373 -#: access/transam/xlogfuncs.c:530 access/transam/xlogfuncs.c:536 +#: access/transam/xlogfuncs.c:327 #, c-format -msgid "could not parse transaction log location \"%s\"" -msgstr "トランザクションログä½ç½®\"%s\"ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "value too long for restore point (maximum %d characters)" +msgstr "リストアãƒã‚¤ãƒ³ãƒˆã¨ã—ã¦ã¯å€¤ãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§%d文字)" -#: access/transam/xlogfuncs.c:364 +#: access/transam/xlogfuncs.c:465 #, c-format -msgid "pg_xlogfile_name() cannot be executed during recovery." -msgstr "リカãƒãƒªä¸­ã¯ pg_xlogfile_name() を実行ã§ãã¾ã›ã‚“" +msgid "pg_walfile_name_offset() cannot be executed during recovery." +msgstr "リカãƒãƒªä¸­ã¯ pg_walfile_name_offset() を実行ã§ãã¾ã›ã‚“" -#: access/transam/xlogfuncs.c:392 access/transam/xlogfuncs.c:414 -#: access/transam/xlogfuncs.c:436 +#: access/transam/xlogfuncs.c:521 #, c-format -msgid "must be superuser to control recovery" -msgstr "リカãƒãƒªã‚’制御ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "pg_walfile_name() cannot be executed during recovery." +msgstr "リカãƒãƒªä¸­ã¯ pg_walfile_name() を実行ã§ãã¾ã›ã‚“" -#: access/transam/xlogfuncs.c:397 access/transam/xlogfuncs.c:419 -#: access/transam/xlogfuncs.c:441 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" -msgstr "リカãƒãƒªãŒå®Ÿè¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "リカãƒãƒªãŒé€²è¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“" -#: access/transam/xlogfuncs.c:398 access/transam/xlogfuncs.c:420 -#: access/transam/xlogfuncs.c:442 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." -msgstr "リカãƒãƒªåˆ¶å¾¡é–¢æ•°ã‚’実行ã§ãã‚‹ã®ã¯ãƒªã‚«ãƒãƒªä¸­ã®ã¿ã§ã™" +msgstr "リカãƒãƒªåˆ¶å¾¡é–¢æ•°ãƒªã‚«ãƒãƒªä¸­ã«ã®ã¿ã‚’実行å¯èƒ½ã§ã™ã€‚" + +#: access/transam/xlogreader.c:299 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚ªãƒ•セットãŒä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:307 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "%X/%Xã§ã¯ç¶™ç¶šãƒ¬ã‚³ãƒ¼ãƒ‰ãŒå¿…è¦ã§ã™" + +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒä¸æ­£ã§ã™:é•·ã•ã¯%uã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ãŒã€å®Ÿéš›ã¯%uã§ã—ãŸ" + +#: access/transam/xlogreader.c:363 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰é•·%1$uãŒå¤§ãã™ãŽã¾ã™" + +#: access/transam/xlogreader.c:404 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%Xã§contrecordフラグãŒã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:417 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "%2$X/%3$Xã®contrecordã®é•·ã• %1$u ã¯ä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:654 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$Xã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ID %1$uã¯ä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "%3$X/%4$Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã®å¾Œæ–¹ãƒªãƒ³ã‚¯%1$X/%2$XãŒä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:722 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ‡ãƒ¼ã‚¿ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:759 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "ログセグメント%2$sã€ã‚ªãƒ•セット%3$uã®ãƒžã‚¸ãƒƒã‚¯ç•ªå·%1$04Xã¯ä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ログセグメント %2$sã€ã‚ªãƒ•セット%3$uã®æƒ…報ビット%1$04Xã¯ä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:799 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL ファイルã¯ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ç”±æ¥ã®ã‚‚ã®ã§ã™: WALファイルã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ è­˜åˆ¥å­ã¯ %s ã§ã€pg_control ã«ãŠã‘るデータベースシステムã®è­˜åˆ¥å­ã¯ %s ã§ã™ã€‚" + +#: access/transam/xlogreader.c:806 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL ファイルã¯ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ç”±æ¥ã®ã‚‚ã®ã§ã™: ページヘッダーã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚µã‚¤ã‚ºãŒæ­£ã—ãã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:812 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL ファイルã¯ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ç”±æ¥ã®ã‚‚ã®ã§ã™: ページヘッダーã®XLOG_BLCKSZãŒæ­£ã—ãã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:843 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "ログセグメント%3$sã€ã‚ªãƒ•セット%4$uã«æƒ³å®šå¤–ã®ãƒšãƒ¼ã‚¸ã‚¢ãƒ‰ãƒ¬ã‚¹%1$X/%2$X" + +#: access/transam/xlogreader.c:868 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "ログセグメント%3$sã€ã‚ªãƒ•セット%4$uã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ID %1$u(%2$uã®å¾Œ)ãŒé †åºé€šã‚Šã§ã¯ã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:1113 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "block_id %uãŒ%X/%Xã§ä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:1136 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATAãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€%X/%Xã«ãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:1143 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATAãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“ãŒã€%2$X/%3$Xã®ãƒ‡ãƒ¼ã‚¿é•·ã¯%1$uã§ã™" + +#: access/transam/xlogreader.c:1179 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€%4$X/%5$Xã§ãƒ›ãƒ¼ãƒ«ã‚ªãƒ•セット%1$uã€é•·ã•%2$uã€ãƒ–ロックイメージ長%3$uã§ã™" + +#: access/transam/xlogreader.c:1195 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“ãŒã€%3$X/%4$Xã«ãŠã‘るホールオフセット%1$uã®é•·ã•ãŒ%2$uã§ã™" + +#: access/transam/xlogreader.c:1210 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSEDãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€%2$X/%3$Xã«ãŠã„ã¦ãƒ–ロックイメージ長ãŒ%1$uã§ã™" + +#: access/transam/xlogreader.c:1225 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLEã‚‚BKPIMAGE_IS_COMPRESSEDも設定ã•れã¦ã„ã¾ã›ã‚“ãŒã€%2$X/%3$Xã«ãŠã„ã¦ãƒ–ロックイメージ長ãŒ%1$uã§ã™" + +#: access/transam/xlogreader.c:1241 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_RELãŒè¨­å®šã•れã¦ã„ã¾ã™ãŒã€%X/%Xã«ãŠã„ã¦ä»¥å‰ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“" + +#: access/transam/xlogreader.c:1253 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%2$X/%3$Xã«ãŠã‘ã‚‹block_id %1$uãŒä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:1342 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºãŒä¸æ­£ã§ã™" + +#: access/transam/xlogreader.c:1431 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%Xã€ãƒ–ロック %d ã§ã®åœ§ç¸®ã‚¤ãƒ¡ãƒ¼ã‚¸ãŒä¸æ­£ã§ã™" + +#: access/transam/xlogutils.c:751 replication/walsender.c:2443 +#, c-format +msgid "could not read from log segment %s, offset %u, length %lu: %m" +msgstr "ログセグメント %sã®ã‚ªãƒ•セット %uã‹ã‚‰é•·ã• %lu ã§èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: access/transam/xlogfuncs.c:491 access/transam/xlogfuncs.c:497 +#: bootstrap/bootstrap.c:268 #, c-format -msgid "invalid input syntax for transaction log location: \"%s\"" -msgstr "トランザクションログä½ç½®\"%s\"ã«å¯¾ã™ã‚‹ç„¡åйãªå…¥åŠ›æ§‹æ–‡ã§ã™" +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X オプションã®å€¤ã¯1MBã‹ã‚‰1GBã®é–“ã®2ã®ç´¯ä¹—を指定ã—ã¾ã™" -#: bootstrap/bootstrap.c:286 postmaster/postmaster.c:745 tcop/postgres.c:3451 +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:826 tcop/postgres.c:3581 #, c-format msgid "--%s requires a value" msgstr "--%sã«ã¯å€¤ãŒå¿…è¦ã§ã™" -#: bootstrap/bootstrap.c:291 postmaster/postmaster.c:750 tcop/postgres.c:3456 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:831 tcop/postgres.c:3586 #, c-format msgid "-c %s requires a value" msgstr "-c %sã¯å€¤ãŒå¿…è¦ã§ã™" -#: bootstrap/bootstrap.c:302 postmaster/postmaster.c:762 -#: postmaster/postmaster.c:775 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:843 +#: postmaster/postmaster.c:856 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "詳細ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„。\n" +msgstr "詳細ã«ã¤ã„ã¦ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„。\n" -#: bootstrap/bootstrap.c:311 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" -msgstr "%s: コマンドライン引数ãŒç„¡åйã§ã™\n" +msgstr "%s: コマンドライン引数ãŒä¸æ­£ã§ã™\n" -#: catalog/aclchk.c:206 +#: catalog/aclchk.c:203 #, c-format msgid "grant options can only be granted to roles" -msgstr "グラントオプションã¯ãƒ­ãƒ¼ãƒ«ã«ã®ã¿ä¸Žãˆã‚‹ã“ã¨ãŒã§ãã¾ã™" +msgstr "グラントオプションã¯ãƒ­ãƒ¼ãƒ«ã«ã®ã¿ä»˜ä¸Žã§ãã¾ã™" -#: catalog/aclchk.c:329 +#: catalog/aclchk.c:326 #, c-format msgid "no privileges were granted for column \"%s\" of relation \"%s\"" -msgstr "リレーション \"%2$s\" ã®ã‚«ãƒ©ãƒ  \"%1$s\" ã«ã¯æ¨©é™ãŒä»˜ä¸Žã•れã¾ã›ã‚“ã§ã—ãŸ" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\" ã«ä»˜ä¸Žã•ã‚ŒãŸæ¨©é™ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:334 +#: catalog/aclchk.c:331 #, c-format msgid "no privileges were granted for \"%s\"" -msgstr "\"%s\"ã«ã¯æ¨©é™ãŒä»˜ä¸Žã•れã¾ã›ã‚“ã§ã—ãŸ" +msgstr "\"%s\"ã«ä»˜ä¸Žã•ã‚ŒãŸæ¨©é™ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:342 +#: catalog/aclchk.c:339 #, c-format msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" -msgstr "リレーション \"%2$s\" ã®ã‚«ãƒ©ãƒ  \"%1$s\" ã«ã¯å…¨ã¦ã®æ¨©é™ãŒä»˜ä¸Žã•れãŸã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã«å¯¾ã—ã¦ä¸€éƒ¨ã®æ¨©é™ãŒä»˜ä¸Žã•れã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/aclchk.c:347 +#: catalog/aclchk.c:344 #, c-format msgid "not all privileges were granted for \"%s\"" -msgstr "\"%s\"ã«ã¯å…¨ã¦ã®æ¨©é™ãŒä»˜ä¸Žã•れãŸã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã«å¯¾ã—ã¦ä¸€éƒ¨ã®æ¨©é™ãŒä»˜ä¸Žã•れã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/aclchk.c:358 +#: catalog/aclchk.c:355 #, c-format msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" -msgstr "リレーション \"%2$s\" ã®ã‚«ãƒ©ãƒ  \"%1$s\" ã‹ã‚‰ã¯æ¨©é™ãŒå‰¥å¥ªã§ããªã‹ã£ãŸå¯èƒ½æ€§ãŒã‚りã¾ã™" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã«å¯¾ã—ã¦å–り消ã›ãŸæ¨©é™ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:363 +#: catalog/aclchk.c:360 #, c-format msgid "no privileges could be revoked for \"%s\"" -msgstr "\"%s\"ã®æ¨©é™ã‚’剥奪ã§ããªã‹ã£ãŸå¯èƒ½æ€§ãŒã‚りã¾ã™" +msgstr "\"%s\"ã«å¯¾ã—ã¦å–り消ã›ãŸæ¨©é™ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:371 +#: catalog/aclchk.c:368 #, c-format msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" -msgstr "リレーション \"%2$s\" ã®ã‚«ãƒ©ãƒ  \"%1$s\" ã‹ã‚‰ã¯å…¨ã¦ã®æ¨©é™ãŒå‰¥å¥ªã§ããŸã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã«å¯¾ã—ã¦ä¸€éƒ¨ã®æ¨©é™ãŒå–り消ã›ã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/aclchk.c:376 +#: catalog/aclchk.c:373 #, c-format msgid "not all privileges could be revoked for \"%s\"" -msgstr "\"%s\"ã®å…¨ã¦ã®æ¨©é™ã‚’å–り上ã’られã¾ã›ã‚“ã§ã—ãŸ" +msgstr "\"%s\"ã«å¯¾ã—ã¦ä¸€éƒ¨ã®æ¨©é™ãŒå–り消ã›ã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/aclchk.c:455 catalog/aclchk.c:933 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" -msgstr "リレーションã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "リレーションã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã®ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:459 catalog/aclchk.c:937 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" -msgstr "シーケンスã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "シーケンスã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã®ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:463 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" -msgstr "データベースã§ã¯æ¨©é™ã®ä»–タイプ %s ã¯ç„¡åйã§ã™" +msgstr "データベースã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:467 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" -msgstr "ãƒ‰ãƒ¡ã‚¤ãƒ³ã¯æ¨©é™%s種類ã¯ç„¡åйã§ã™" +msgstr "ドメインã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:471 catalog/aclchk.c:941 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" -msgstr "関数ã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "関数ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:475 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" -msgstr "言語ã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "言語ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:479 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" -msgstr "ラージオブジェクトã«å¯¾ã—ã¦æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "ラージオブジェクトã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:483 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" -msgstr "スキーマã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "スキーマã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" + +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "プロシージャã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ルーãƒãƒ³ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã®ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:487 +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" -msgstr "テーブル空間ã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "テーブル空間ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:491 catalog/aclchk.c:945 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" -msgstr "åž‹ã§ã¯æ¨©é™%s種類ã¯ç„¡åйã§ã™" +msgstr "åž‹ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:495 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" -msgstr "外部データラッパーã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "外部データラッパーã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:499 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" -msgstr "外部サーãƒã§ã¯æ¨©é™ã®ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "外部サーãƒã«å¯¾ã™ã‚‹ä¸æ­£ãªæ¨©é™ã‚¿ã‚¤ãƒ— %s" -#: catalog/aclchk.c:538 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" -msgstr "リレーションã§ã¯åž‹æ¨©é™ã®ã¿ãŒæœ‰åйã§ã™" +msgstr "列権é™ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«å¯¾ã—ã¦ã®ã¿æœ‰åйã§ã™" -#: catalog/aclchk.c:688 catalog/aclchk.c:3904 catalog/aclchk.c:4681 -#: catalog/objectaddress.c:575 catalog/pg_largeobject.c:113 -#: storage/large_object/inv_api.c:277 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 +#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 +#: storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" -msgstr "ラージオブジェクト\"%u\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" - -#: catalog/aclchk.c:875 catalog/aclchk.c:883 commands/collationcmds.c:91 -#: commands/copy.c:923 commands/copy.c:941 commands/copy.c:949 -#: commands/copy.c:957 commands/copy.c:965 commands/copy.c:973 -#: commands/copy.c:981 commands/copy.c:989 commands/copy.c:997 -#: commands/copy.c:1013 commands/copy.c:1032 commands/copy.c:1047 -#: commands/dbcommands.c:147 commands/dbcommands.c:155 -#: commands/dbcommands.c:163 commands/dbcommands.c:171 -#: commands/dbcommands.c:179 commands/dbcommands.c:187 -#: commands/dbcommands.c:195 commands/dbcommands.c:1333 -#: commands/dbcommands.c:1341 commands/extension.c:1250 -#: commands/extension.c:1258 commands/extension.c:1266 -#: commands/extension.c:2674 commands/foreigncmds.c:483 -#: commands/foreigncmds.c:492 commands/functioncmds.c:496 -#: commands/functioncmds.c:588 commands/functioncmds.c:596 -#: commands/functioncmds.c:604 commands/functioncmds.c:1670 -#: commands/functioncmds.c:1678 commands/sequence.c:1164 -#: commands/sequence.c:1172 commands/sequence.c:1180 commands/sequence.c:1188 -#: commands/sequence.c:1196 commands/sequence.c:1204 commands/sequence.c:1212 -#: commands/sequence.c:1220 commands/typecmds.c:296 commands/typecmds.c:1331 -#: commands/typecmds.c:1340 commands/typecmds.c:1348 commands/typecmds.c:1356 -#: commands/typecmds.c:1364 commands/user.c:135 commands/user.c:152 -#: commands/user.c:160 commands/user.c:168 commands/user.c:176 -#: commands/user.c:184 commands/user.c:192 commands/user.c:200 -#: commands/user.c:208 commands/user.c:216 commands/user.c:224 -#: commands/user.c:232 commands/user.c:496 commands/user.c:508 -#: commands/user.c:516 commands/user.c:524 commands/user.c:532 -#: commands/user.c:540 commands/user.c:548 commands/user.c:556 -#: commands/user.c:565 commands/user.c:573 +msgstr "ラージオブジェクト%uã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 +#: commands/copy.c:1063 commands/copy.c:1083 commands/copy.c:1092 +#: commands/copy.c:1101 commands/copy.c:1110 commands/copy.c:1119 +#: commands/copy.c:1128 commands/copy.c:1137 commands/copy.c:1146 +#: commands/copy.c:1164 commands/copy.c:1180 commands/copy.c:1200 +#: commands/copy.c:1217 commands/dbcommands.c:155 commands/dbcommands.c:164 +#: commands/dbcommands.c:173 commands/dbcommands.c:182 +#: commands/dbcommands.c:191 commands/dbcommands.c:200 +#: commands/dbcommands.c:209 commands/dbcommands.c:218 +#: commands/dbcommands.c:227 commands/dbcommands.c:1427 +#: commands/dbcommands.c:1436 commands/dbcommands.c:1445 +#: commands/dbcommands.c:1454 commands/extension.c:1678 +#: commands/extension.c:1688 commands/extension.c:1698 +#: commands/extension.c:1708 commands/extension.c:2949 +#: commands/foreigncmds.c:537 commands/foreigncmds.c:546 +#: commands/functioncmds.c:559 commands/functioncmds.c:684 +#: commands/functioncmds.c:693 commands/functioncmds.c:702 +#: commands/functioncmds.c:711 commands/functioncmds.c:2105 +#: commands/functioncmds.c:2113 commands/publicationcmds.c:92 +#: commands/sequence.c:1255 commands/sequence.c:1265 commands/sequence.c:1275 +#: commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 +#: commands/sequence.c:1315 commands/sequence.c:1325 commands/sequence.c:1335 +#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 +#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 +#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 +#: commands/subscriptioncmds.c:179 commands/tablecmds.c:6277 +#: commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 +#: commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 +#: commands/user.c:134 commands/user.c:148 commands/user.c:157 +#: commands/user.c:166 commands/user.c:175 commands/user.c:184 +#: commands/user.c:193 commands/user.c:202 commands/user.c:211 +#: commands/user.c:220 commands/user.c:229 commands/user.c:238 +#: commands/user.c:247 commands/user.c:555 commands/user.c:563 +#: commands/user.c:571 commands/user.c:579 commands/user.c:587 +#: commands/user.c:595 commands/user.c:603 commands/user.c:611 +#: commands/user.c:620 commands/user.c:628 commands/user.c:636 +#: parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 +#: replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "ç«¶åˆã™ã‚‹ã‚ªãƒ—ションã€ã‚ã‚‹ã„ã¯ä½™è¨ˆãªã‚ªãƒ—ションãŒã‚りã¾ã™" -#: catalog/aclchk.c:978 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "デフォルト権é™ã¯åˆ—ã«ã¯è¨­å®šã§ãã¾ã›ã‚“" -#: catalog/aclchk.c:1492 catalog/objectaddress.c:1021 commands/analyze.c:386 -#: commands/copy.c:4159 commands/sequence.c:1466 commands/tablecmds.c:4839 -#: commands/tablecmds.c:4934 commands/tablecmds.c:4984 -#: commands/tablecmds.c:5088 commands/tablecmds.c:5135 -#: commands/tablecmds.c:5219 commands/tablecmds.c:5307 -#: commands/tablecmds.c:7382 commands/tablecmds.c:7586 -#: commands/tablecmds.c:7978 commands/trigger.c:592 parser/analyze.c:1973 -#: parser/parse_relation.c:2234 parser/parse_relation.c:2306 -#: parser/parse_target.c:918 parser/parse_type.c:124 utils/adt/acl.c:2840 -#: utils/adt/ruleutils.c:1779 +#: catalog/aclchk.c:1212 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "GRANT/REVOKE ON SCHEMAS を使ã£ã¦ã„る時ã«ã¯ IN SCHEMA å¥ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 +#: commands/copy.c:4819 commands/sequence.c:1690 commands/tablecmds.c:5923 +#: commands/tablecmds.c:6071 commands/tablecmds.c:6128 +#: commands/tablecmds.c:6202 commands/tablecmds.c:6296 +#: commands/tablecmds.c:6355 commands/tablecmds.c:6494 +#: commands/tablecmds.c:6576 commands/tablecmds.c:6668 +#: commands/tablecmds.c:6762 commands/tablecmds.c:9098 +#: commands/tablecmds.c:9377 commands/tablecmds.c:9793 commands/trigger.c:904 +#: parser/analyze.c:2337 parser/parse_relation.c:2735 +#: parser/parse_relation.c:2798 parser/parse_target.c:1030 +#: parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2466 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:1757 catalog/objectaddress.c:849 commands/sequence.c:1053 -#: commands/tablecmds.c:214 commands/tablecmds.c:10686 utils/adt/acl.c:2076 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1128 +#: commands/tablecmds.c:231 commands/tablecmds.c:13594 utils/adt/acl.c:2076 #: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 #: utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\"ã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:1795 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "シーケンス \"%s\" ã§ã¯ USAGE, SELECT, UPDATE 権é™ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™" -#: catalog/aclchk.c:1812 +#: catalog/aclchk.c:1898 #, c-format -msgid "invalid privilege type USAGE for table" -msgstr "テーブルã§ã¯æ¨©é™ã‚¿ã‚¤ãƒ— USAGE ã¯ç„¡åйã§ã™" +msgid "invalid privilege type %s for table" +msgstr "テーブルã«å¯¾ã™ã‚‹æ¨©é™ã‚¿ã‚¤ãƒ—%sã¯ä¸æ­£ã§ã™" -#: catalog/aclchk.c:1977 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" -msgstr "カラムã§ã¯æ¨©é™ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" +msgstr "列ã§ã¯æ¨©é™ã‚¿ã‚¤ãƒ— %s ã¯ç„¡åйã§ã™" -#: catalog/aclchk.c:1990 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "シーケンス \"%s\" ã§ã¯ USAGE, SELECT, UPDATE ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™" -#: catalog/aclchk.c:2574 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "言語\"%s\"ã¯ä¿¡é ¼ã•れã¦ã„ã¾ã›ã‚“" -#: catalog/aclchk.c:2576 +#: catalog/aclchk.c:2661 #, c-format -msgid "Only superusers can use untrusted languages." -msgstr "スーパーユーザã®ã¿ãŒä¿¡é ¼ã•れãªã„言語を使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "ä¿¡é ¼ã•れãªã„言語ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã®ã¿ãŒä½¿ç”¨å¯èƒ½ãªãŸã‚ã€GRANTã¨REVOKEã¯ä¿¡é ¼ã•れãªã„言語上ã§ã¯å®Ÿè¡Œä¸å¯ã§ã™ã€‚" -#: catalog/aclchk.c:3092 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "é…åˆ—åž‹ã®æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“" -#: catalog/aclchk.c:3093 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "代ã‚りã«è¦ç´ åž‹ã®æ¨©é™ã‚’設定ã—ã¦ãã ã•ã„。" -#: catalog/aclchk.c:3100 catalog/objectaddress.c:1072 commands/typecmds.c:3186 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" msgstr "\"%s\"ã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/aclchk.c:3220 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" -msgstr "権é™ã‚¿ã‚¤ãƒ— \"%s\" ã‚’èªè­˜ã§ãã¾ã›ã‚“" +msgstr "èªè­˜ã§ããªã„権é™ã‚¿ã‚¤ãƒ—\"%s\"" -#: catalog/aclchk.c:3269 +#: catalog/aclchk.c:3364 #, c-format -msgid "permission denied for column %s" -msgstr "カラム %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for aggregate %s" +msgstr "集約 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3271 +#: catalog/aclchk.c:3367 #, c-format -msgid "permission denied for relation %s" -msgstr "リレーション %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for collation %s" +msgstr "ç…§åˆé †åº %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3273 commands/sequence.c:560 commands/sequence.c:773 -#: commands/sequence.c:815 commands/sequence.c:852 commands/sequence.c:1518 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for sequence %s" -msgstr "シーケンス%sã«å¯¾ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for column %s" +msgstr "列 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3275 +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for conversion %s" +msgstr "å¤‰æ› %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" -msgstr "データベース %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "データベース %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3277 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "関数 %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for domain %s" +msgstr "ドメイン %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3279 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "æ¼”ç®—å­ %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for event trigger %s" +msgstr "イベントトリガ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3281 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "åž‹ %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for extension %s" +msgstr "機能拡張 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3283 +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "外部データラッパ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "外部サーム%s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "外部テーブル %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "関数 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "インデックス %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3403 #, c-format msgid "permission denied for language %s" -msgstr "言語 %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "言語 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3285 +#: catalog/aclchk.c:3406 #, c-format msgid "permission denied for large object %s" -msgstr "ラージオブジェクト %s ã«å¯¾ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "ラージオブジェクト %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3287 +#: catalog/aclchk.c:3409 #, c-format -msgid "permission denied for schema %s" -msgstr "スキーマ %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for materialized view %s" +msgstr "実体化ビュー %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3289 +#: catalog/aclchk.c:3412 #, c-format msgid "permission denied for operator class %s" -msgstr "演算å­ã‚¯ãƒ©ã‚¹%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "演算å­ã‚¯ãƒ©ã‚¹ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "æ¼”ç®—å­ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3291 +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" -msgstr "æ¼”ç®—å­æ—%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "æ¼”ç®—å­æ— %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3293 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "ç…§åˆé †åº %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for policy %s" +msgstr "ãƒãƒªã‚· %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3295 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "変æ›%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for procedure %s" +msgstr "プロシージャ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3297 +#: catalog/aclchk.c:3427 #, c-format -msgid "permission denied for tablespace %s" -msgstr "テーブル空間%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for publication %s" +msgstr "パブリケーション%sã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3299 +#: catalog/aclchk.c:3430 #, c-format -msgid "permission denied for text search dictionary %s" -msgstr "テキスト検索辞書%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for routine %s" +msgstr "ルーãƒãƒ³ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "スキーマ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3436 commands/sequence.c:598 commands/sequence.c:832 +#: commands/sequence.c:874 commands/sequence.c:915 commands/sequence.c:1788 +#: commands/sequence.c:1852 +#, c-format +msgid "permission denied for sequence %s" +msgstr "シーケンス %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3439 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "統計情報オブジェクト %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "サブスクリプション %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3301 +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "テーブル %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3448 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "テーブル空間 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3451 #, c-format msgid "permission denied for text search configuration %s" -msgstr "テキスト検索設定%sã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "テキスト検索設定 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3303 +#: catalog/aclchk.c:3454 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "外部データラッパー %s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for text search dictionary %s" +msgstr "テキスト検索辞書 %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3305 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for foreign server %s" -msgstr "外部サーム%s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for type %s" +msgstr "åž‹ %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3307 +#: catalog/aclchk.c:3460 #, c-format -#| msgid "permission denied for sequence %s" -msgid "permission denied for event trigger %s" -msgstr "イベントトリガ%sã«å¯¾ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "permission denied for view %s" +msgstr "ビュー %s ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: catalog/aclchk.c:3309 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for extension %s" -msgstr "拡張機能%s ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "must be owner of aggregate %s" +msgstr "集約 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3315 catalog/aclchk.c:3317 +#: catalog/aclchk.c:3498 #, c-format -msgid "must be owner of relation %s" -msgstr "リレーション%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of collation %s" +msgstr "ç…§åˆé †åº %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3319 +#: catalog/aclchk.c:3501 #, c-format -msgid "must be owner of sequence %s" -msgstr "シーケンス%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of conversion %s" +msgstr "å¤‰æ› %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3321 +#: catalog/aclchk.c:3504 #, c-format msgid "must be owner of database %s" -msgstr "データベース%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "データベース %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3323 +#: catalog/aclchk.c:3507 #, c-format -msgid "must be owner of function %s" -msgstr "関数%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of domain %s" +msgstr "ドメイン %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3325 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of operator %s" -msgstr "演算å­%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of event trigger %s" +msgstr "イベントトリガ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3327 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of type %s" -msgstr "åž‹%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of extension %s" +msgstr "機能拡張 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "外部データラッパー %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "外部サーム%s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "外部テーブル %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of function %s" +msgstr "関数 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3329 +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "インデックス %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" -msgstr "言語%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "言語 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3331 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" -msgstr "ラージオブジェクト %s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ラージオブジェクト %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3333 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "スキーマ%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of materialized view %s" +msgstr "実体化ビュー %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3335 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" -msgstr "演算å­ã‚¯ãƒ©ã‚¹%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "演算å­ã‚¯ãƒ©ã‚¹ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "æ¼”ç®—å­ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3337 +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" -msgstr "演算å­ãƒ•ァミリー %s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æ¼”ç®—å­æ— %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3339 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "ç…§åˆé †åº %s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of procedure %s" +msgstr "プロシージャ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3341 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "変æ›%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of publication %s" +msgstr "パブリケーション %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3343 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of tablespace %s" -msgstr "テーブル空間%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of routine %s" +msgstr "ルーãƒãƒ³ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3345 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "テキスト検索辞書%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of sequence %s" +msgstr "シーケンス %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3347 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "テキスト検索設定%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of subscription %s" +msgstr "サブスクリプション %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3349 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "外部データラッパー %s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of table %s" +msgstr "テーブル %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3351 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign server %s" -msgstr "外部サーム%s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of type %s" +msgstr "åž‹ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3353 +#: catalog/aclchk.c:3570 #, c-format -#| msgid "must be owner of sequence %s" -msgid "must be owner of event trigger %s" -msgstr "イベントトリガ%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of view %s" +msgstr "ビュー %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3355 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of extension %s" -msgstr "拡張機能 %s ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be owner of schema %s" +msgstr "スキーマ %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3397 +#: catalog/aclchk.c:3576 #, c-format -msgid "permission denied for column \"%s\" of relation \"%s\"" -msgstr "リレーション \"%2$s\" ã®ã‚«ãƒ©ãƒ  \"%1$s\" ã¸ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "must be owner of statistics object %s" +msgstr "統計情報オブジェクト %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3437 +#: catalog/aclchk.c:3579 #, c-format -msgid "role with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るロールã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "must be owner of tablespace %s" +msgstr "テーブル空間 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3582 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "テキスト検索設定 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "テキスト検索辞書 %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "リレーション %s ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/aclchk.c:3536 catalog/aclchk.c:3544 +#: catalog/aclchk.c:3643 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" + +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" -msgstr "OID ㌠%2$u ã§ã‚るリレーションã®å±žæ€§ %1$d ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %2$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«å±žæ€§%1$dã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:3617 catalog/aclchk.c:4532 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るリレーションã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:3717 catalog/aclchk.c:4950 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "OID %uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:3771 catalog/aclchk.c:4610 tcop/fastpath.c:223 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "OID %uã®é–¢æ•°ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:3825 catalog/aclchk.c:4636 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る言語ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®è¨€èªžã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:3989 catalog/aclchk.c:4708 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るスキーマã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ã‚¹ã‚­ãƒ¼ãƒžã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4043 catalog/aclchk.c:4735 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るテーブル空間ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ãƒ†ãƒ¼ãƒ–ル空間ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4101 catalog/aclchk.c:4869 commands/foreigncmds.c:299 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る外部データラッパーã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®å¤–部データラッパーã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4162 catalog/aclchk.c:4896 commands/foreigncmds.c:406 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る外部サーãƒã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®å¤–部サーãƒã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4221 catalog/aclchk.c:4235 catalog/aclchk.c:4558 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚ã‚‹åž‹ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®åž‹ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4584 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る演算å­ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®æ¼”ç®—å­ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4761 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る演算å­ã‚¯ãƒ©ã‚¹ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4788 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚ã‚‹æ¼”ç®—å­æ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®æ¼”ç®—å­æ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4815 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るテキスト検索辞書ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ãƒ†ã‚­ã‚¹ãƒˆæ¤œç´¢è¾žæ›¸ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4842 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るテキスト検索設定ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ãƒ†ã‚­ã‚¹ãƒˆæ¤œç´¢è¨­å®šã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4923 commands/event_trigger.c:506 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format -#| msgid "language with OID %u does not exist" msgid "event trigger with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚るイベントトリガã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ã‚¤ãƒ™ãƒ³ãƒˆãƒˆãƒªã‚¬ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:4976 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚ã‚‹ç…§åˆé †åºã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®ç…§åˆé †åºã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:5002 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る変æ›ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®å¤‰æ›ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/aclchk.c:5043 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" -msgstr "OID ㌠%u ã§ã‚る拡張機能ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "OID %uã®æ©Ÿèƒ½æ‹¡å¼µã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/catalog.c:63 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 #, c-format -msgid "invalid fork name" -msgstr "無効ãªåˆ†å²åã§ã™" +msgid "publication with OID %u does not exist" +msgstr "OID %uã®ãƒ‘ブリケーションã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/catalog.c:64 +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 #, c-format -msgid "Valid fork names are \"main\", \"fsm\", and \"vm\"." -msgstr "有効ãªåˆ†å²åã¯\"main\"ã€\"fsm\"ãŠã‚ˆã³\"vm\" ã§ã™" +msgid "subscription with OID %u does not exist" +msgstr "OID %uã®ã‚µãƒ–スクリプションã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/dependency.c:626 +#: catalog/aclchk.c:5354 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "OID %uã®çµ±è¨ˆæƒ…報オブジェクトã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" msgstr "%2$sãŒå¿…è¦ã¨ã—ã¦ã„ã‚‹ãŸã‚%1$sを削除ã§ãã¾ã›ã‚“" -#: catalog/dependency.c:629 +#: catalog/dependency.c:614 #, c-format msgid "You can drop %s instead." msgstr "代ã‚りã«%sを削除ã§ãã¾ã™" -#: catalog/dependency.c:790 catalog/pg_shdepend.c:571 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "データベースシステムãŒå¿…è¦ã¨ã—ã¦ã„ã‚‹ãŸã‚%sを削除ã§ãã¾ã›ã‚“" -#: catalog/dependency.c:906 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" -msgstr "%sã¸ã®è‡ªå‹•カスケードを削除ã—ã¾ã™" +msgstr "削除ã¯è‡ªå‹•ã§%sã¸ä¼æ’­ã—ã¾ã™" -#: catalog/dependency.c:918 catalog/dependency.c:927 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" -msgstr "%sã¯%sã«ä¾å­˜ã—ã¾ã™" +msgstr "%sã¯%sã«ä¾å­˜ã—ã¦ã„ã¾ã™" -#: catalog/dependency.c:939 catalog/dependency.c:948 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" -msgstr "%sã¸ã®ã‚«ã‚¹ã‚±ãƒ¼ãƒ‰ã‚’削除ã—ã¾ã™" +msgstr "削除ã¯%sã¸ä¼æ’­ã—ã¾ã™" -#: catalog/dependency.c:956 catalog/pg_shdepend.c:682 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -2690,1027 +3677,1312 @@ msgid_plural "" "and %d other objects (see server log for list)" msgstr[0] "" "\n" -"ãŠã‚ˆã³%dã®ãã®ä»–ã®ã‚ªãƒ–ジェクト(一覧ã«ã¤ã„ã¦ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„)" +"ãŠã‚ˆã³%d個ã®ãã®ä»–ã®ã‚ªãƒ–ジェクト(一覧ã«ã¤ã„ã¦ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„)" msgstr[1] "" "\n" -"ãŠã‚ˆã³%dã®ãã®ä»–ã®ã‚ªãƒ–ジェクト(一覧ã«ã¤ã„ã¦ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„)" +"ãŠã‚ˆã³%d個ã®ãã®ä»–ã®ã‚ªãƒ–ジェクト(一覧ã«ã¤ã„ã¦ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„)" -#: catalog/dependency.c:968 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" -msgstr "ä»–ã®ã‚ªãƒ–ジェクトãŒä¾å­˜ã—ã¦ã„ã¾ã™ã®ã§%sを削除ã§ãã¾ã›ã‚“" - -#: catalog/dependency.c:970 catalog/dependency.c:971 catalog/dependency.c:977 -#: catalog/dependency.c:978 catalog/dependency.c:989 catalog/dependency.c:990 -#: catalog/objectaddress.c:751 commands/tablecmds.c:740 -#: commands/tablecmds.c:8809 commands/user.c:988 commands/view.c:478 -#: port/win32/security.c:51 storage/lmgr/deadlock.c:955 -#: storage/lmgr/proc.c:1172 utils/misc/guc.c:5526 utils/misc/guc.c:5861 -#: utils/misc/guc.c:8227 utils/misc/guc.c:8261 utils/misc/guc.c:8295 -#: utils/misc/guc.c:8329 utils/misc/guc.c:8364 -#, c-format -msgid "%s" -msgstr "%s" +msgstr "ä»–ã®ã‚ªãƒ–ジェクトãŒä¾å­˜ã—ã¦ã„ã‚‹ãŸã‚%sを削除ã§ãã¾ã›ã‚“" -#: catalog/dependency.c:972 catalog/dependency.c:979 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "ä¾å­˜ã—ã¦ã„るオブジェクトも削除ã™ã‚‹ã«ã¯DROP ... CASCADEを使用ã—ã¦ãã ã•ã„" -#: catalog/dependency.c:976 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" -msgstr "ä»–ã®ã‚ªãƒ–ジェクトãŒä¾å­˜ã—ã¦ã„ã‚‹ãŸã‚希望ã™ã‚‹ã‚ªãƒ–ジェクトを削除ã§ãã¾ã›ã‚“" +msgstr "ä»–ã®ã‚ªãƒ–ジェクトãŒä¾å­˜ã—ã¦ã„ã‚‹ãŸã‚指定ã—ãŸã‚ªãƒ–ジェクトを削除ã§ãã¾ã›ã‚“" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:985 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" -msgstr[0] "ä»–ã® %d 個ã®ã‚ªãƒ–ジェクトã¸ã®ã‚«ã‚¹ã‚±ãƒ¼ãƒ‰ã‚’削除ã—ã¾ã™" -msgstr[1] "ä»–ã® %d 個ã®ã‚ªãƒ–ジェクトã¸ã®ã‚«ã‚¹ã‚±ãƒ¼ãƒ‰ã‚’削除ã—ã¾ã™" +msgstr[0] "削除ã¯ä»–ã®%d個ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦ã‚‚行ã‚れã¾ã™" +msgstr[1] "削除ã¯ä»–ã®%d個ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦ã‚‚行ã‚れã¾ã™" + +#: catalog/dependency.c:1644 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "%såž‹ã®å®šæ•°ã‚’ã“ã“ã§ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/heap.c:266 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "\"%s.%s\"を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: catalog/heap.c:268 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." -msgstr "ç¾æ™‚点ã§ã¯ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" +msgstr "ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ã®æ›´æ–°ã¯ç¾åœ¨ç¦æ­¢ã•れã¦ã„ã¾ã™" -#: catalog/heap.c:403 commands/tablecmds.c:1379 commands/tablecmds.c:1820 -#: commands/tablecmds.c:4484 +#: catalog/heap.c:433 commands/tablecmds.c:1865 commands/tablecmds.c:2398 +#: commands/tablecmds.c:5490 #, c-format msgid "tables can have at most %d columns" -msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã¯æœ€å¤§ã§%d列æŒã¤ã“ã¨ãŒã§ãã¾ã™" +msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã¯æœ€å¤§ã§%d列ã¾ã§ã—ã‹æŒã¦ã¾ã›ã‚“" -#: catalog/heap.c:420 commands/tablecmds.c:4740 +#: catalog/heap.c:452 commands/tablecmds.c:5786 #, c-format msgid "column name \"%s\" conflicts with a system column name" -msgstr "列å\"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ç”¨ã®åˆ—åã¨ç«¶åˆã—ã¾ã™" +msgstr "列å\"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ç”¨ã®åˆ—åã«ä½¿ã‚れã¦ã„ã¾ã™" -#: catalog/heap.c:436 +#: catalog/heap.c:468 #, c-format msgid "column name \"%s\" specified more than once" msgstr "列å\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: catalog/heap.c:486 -#, c-format -msgid "column \"%s\" has type \"unknown\"" -msgstr "列\"%s\"ã¯\"unknown\"åž‹ã§ã™" - -#: catalog/heap.c:487 -#, c-format -msgid "Proceeding with relation creation anyway." -msgstr "ã¨ã‚Šã‚ãˆãšãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ä½œæˆã‚’進ã‚ã¾ã™" - -#: catalog/heap.c:500 +#: catalog/heap.c:521 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "列\"%s\"ã¯ä»®æƒ³åž‹%sã§ã™" -#: catalog/heap.c:530 +#: catalog/heap.c:551 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "複åˆåž‹ %s ãŒãれ自身ã®ãƒ¡ãƒ³ãƒãƒ¼ã«ãªã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/heap.c:572 commands/createas.c:342 +#: catalog/heap.c:593 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "ç…§åˆå¯èƒ½ãªåž‹ %2$s ã‚’æŒã¤åˆ— \"%1$s\" ã®ãŸã‚ã®ç…§åˆé †åºã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/heap.c:574 commands/createas.c:344 commands/indexcmds.c:1085 -#: commands/view.c:115 regex/regc_pg_locale.c:262 utils/adt/formatting.c:1517 -#: utils/adt/formatting.c:1569 utils/adt/formatting.c:1637 -#: utils/adt/formatting.c:1689 utils/adt/formatting.c:1758 -#: utils/adt/formatting.c:1822 utils/adt/like.c:212 utils/adt/selfuncs.c:5195 -#: utils/adt/varlena.c:1381 +#: catalog/heap.c:595 commands/createas.c:204 commands/createas.c:501 +#: commands/indexcmds.c:1588 commands/tablecmds.c:13880 commands/view.c:105 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 +#: utils/adt/selfuncs.c:5807 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "ç…§åˆé †åºã‚’明示ã™ã‚‹ã«ã¯ COLLATE å¥ã‚’使ã„ã¾ã™" -#: catalog/heap.c:1046 catalog/index.c:776 commands/tablecmds.c:2522 +#: catalog/heap.c:1084 catalog/index.c:876 commands/tablecmds.c:3160 #, c-format msgid "relation \"%s\" already exists" msgstr "リレーション\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/heap.c:1062 catalog/pg_type.c:402 catalog/pg_type.c:705 -#: commands/typecmds.c:238 commands/typecmds.c:738 commands/typecmds.c:1089 -#: commands/typecmds.c:1307 commands/typecmds.c:2059 +#: catalog/heap.c:1100 catalog/pg_type.c:417 catalog/pg_type.c:732 +#: commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 +#: commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "åž‹\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/heap.c:1063 +#: catalog/heap.c:1101 #, c-format msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." -msgstr "リレーションã¯åŒã˜åå‰ã®é–¢é€£ã™ã‚‹åž‹ã‚’æŒã¡ã¾ã™ã€‚ã“ã®ãŸã‚既存ã®åž‹ã¨ç«¶åˆã—ãªã„åå‰ã‚’使用ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "リレーションã¯åŒã˜åå‰ã®é–¢é€£ã™ã‚‹åž‹ã‚’æŒã¡ã¾ã™ã€‚ã“ã®ãŸã‚既存ã®åž‹ã¨ç«¶åˆã—ãªã„åå‰ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/heap.c:2248 +#: catalog/heap.c:1130 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中ã«pg_classã®ãƒ’ープOIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" + +#: catalog/heap.c:2333 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"ã« NO INHERIT 制約ã¯è¿½åŠ ã§ãã¾ã›ã‚“" + +#: catalog/heap.c:2598 #, c-format msgid "check constraint \"%s\" already exists" -msgstr "ãƒã‚§ãƒƒã‚¯åˆ¶ç´„\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgstr "検査制約\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/heap.c:2401 catalog/pg_constraint.c:650 commands/tablecmds.c:5633 +#: catalog/heap.c:2768 catalog/index.c:890 catalog/pg_constraint.c:1069 +#: commands/tablecmds.c:7138 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "ã™ã§ã«åˆ¶ç´„\"%s\"ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/heap.c:2411 +#: catalog/heap.c:2775 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "制約\"%s\"ã¯ã€ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"上ã®ç¶™æ‰¿ã•れã¦ã„ãªã„制約ã¨ç«¶åˆã—ã¾ã™" -#: catalog/heap.c:2425 +#: catalog/heap.c:2786 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "制約\"%s\"ã¯ã€ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"上ã®ç¶™æ‰¿ã•れãŸåˆ¶ç´„ã¨ç«¶åˆã—ã¾ã™" + +#: catalog/heap.c:2796 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "制約\"%s\"ã¯ã€ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"上㮠NOT VALID 制約ã¨ç«¶åˆã—ã¾ã™" + +#: catalog/heap.c:2801 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "継承ã•れãŸå®šç¾©ã«ã‚ˆã‚Šåˆ¶ç´„ \"%s\" をマージã—ã¦ã„ã¾ã™" -#: catalog/heap.c:2518 +#: catalog/heap.c:2916 #, c-format msgid "cannot use column references in default expression" msgstr "デフォルトå¼ã«ã¯åˆ—å‚照を使用ã§ãã¾ã›ã‚“" -#: catalog/heap.c:2529 -#, c-format -msgid "default expression must not return a set" -msgstr "デフォルトå¼ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" - -#: catalog/heap.c:2548 rewrite/rewriteHandler.c:1032 +#: catalog/heap.c:2941 rewrite/rewriteHandler.c:1177 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "列\"%s\"ã®åž‹ã¯%sã§ã™ãŒã€ãƒ‡ãƒ•ォルトå¼ã®åž‹ã¯%sã§ã™" -#: catalog/heap.c:2553 commands/prepare.c:374 parser/parse_node.c:398 -#: parser/parse_target.c:509 parser/parse_target.c:758 -#: parser/parse_target.c:768 rewrite/rewriteHandler.c:1037 +#: catalog/heap.c:2946 commands/prepare.c:384 parser/parse_node.c:430 +#: parser/parse_target.c:590 parser/parse_target.c:865 +#: parser/parse_target.c:875 rewrite/rewriteHandler.c:1182 #, c-format msgid "You will need to rewrite or cast the expression." -msgstr "å¼ã‚’æ›¸ãæ›ãˆã‚‹ã‹ã‚­ãƒ£ã‚¹ãƒˆã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "å¼ã‚’æ›¸ãæ›ãˆã‚‹ã‹ã‚­ãƒ£ã‚¹ãƒˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/heap.c:2600 +#: catalog/heap.c:2993 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "検査制約ã§ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®ã¿ã‚’å‚ç…§ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: catalog/heap.c:2840 +#: catalog/heap.c:3243 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "ON COMMITã¨å¤–部キーã®çµ„ã¿åˆã‚ã›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: catalog/heap.c:2841 +#: catalog/heap.c:3244 #, c-format msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "テーブル\"%s\"ã¯\"%s\"ã‚’å‚ç…§ã—ã¾ã™ã€‚ã—ã‹ã—ã€ã“れらã®ON COMMIT設定ã¯åŒä¸€ã§ã¯ã‚りã¾ã›ã‚“。" -#: catalog/heap.c:2846 +#: catalog/heap.c:3249 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "外部キー制約ã§å‚ç…§ã•れã¦ã„るテーブルを削除ã§ãã¾ã›ã‚“" -#: catalog/heap.c:2847 +#: catalog/heap.c:3250 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "テーブル\"%s\"ã¯\"%s\"ã‚’å‚ç…§ã—ã¾ã™ã€‚" -#: catalog/heap.c:2849 +#: catalog/heap.c:3252 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "åŒæ™‚ã«ãƒ†ãƒ¼ãƒ–ル\"%s\"ãŒtruncateã•れã¾ã—ãŸã€‚TRUNCATE ... CASCADEを使用ã—ã¦ãã ã•ã„。" -#: catalog/index.c:203 parser/parse_utilcmd.c:1391 parser/parse_utilcmd.c:1477 +#: catalog/index.c:233 parser/parse_utilcmd.c:1823 parser/parse_utilcmd.c:1910 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "テーブル\"%s\"ã«è¤‡æ•°ã®ãƒ—ライマリキーをæŒãŸã›ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/index.c:221 +#: catalog/index.c:251 #, c-format msgid "primary keys cannot be expressions" msgstr "プライマリキーをå¼ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/index.c:737 catalog/index.c:1141 +#: catalog/index.c:820 catalog/index.c:1291 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "ユーザã«ã‚ˆã‚‹ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ãƒ†ãƒ¼ãƒ–ルã«å¯¾ã™ã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®å®šç¾©ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: catalog/index.c:747 +#: catalog/index.c:830 #, c-format msgid "concurrent index creation on system catalog tables is not supported" -msgstr "システムカタログテーブルã®åŒæ™‚インデックス作æˆã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "システムカタログテーブルã®ä¸¦è¡Œçš„インデックス作æˆã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: catalog/index.c:765 +#: catalog/index.c:848 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "initdbã®å¾Œã«å…±æœ‰ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’作æˆã§ãã¾ã›ã‚“" -#: catalog/index.c:1406 +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 +#: parser/parse_utilcmd.c:205 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "リレーション \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: catalog/index.c:918 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中ã«pg_classã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹OIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" + +#: catalog/index.c:1566 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLYã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã§æœ€åˆã®æ“作ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: catalog/index.c:1964 +#: catalog/index.c:2295 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "テーブル\"%2$s\"用ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%1$s\" を構築ã—ã¦ã„ã¾ã™" +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "テーブル\"%2$s\"ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%1$s\" ã‚’éžä¸¦åˆ—ã§æ§‹ç¯‰ã—ã¦ã„ã¾ã™" -#: catalog/index.c:3136 +#: catalog/index.c:2300 #, c-format -msgid "cannot reindex temporary tables of other sessions" -msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルをå†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ä»˜ã‘ã§ãã¾ã›ã‚“" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "テーブル\"%2$s\"ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%1$s\" ã‚’ %3$d 個ã®ãƒ‘ãƒ©ãƒ¬ãƒ«ãƒ¯ãƒ¼ã‚«ã‚’è¦æ±‚ã—ã¦æ§‹ç¯‰ã—ã¦ã„ã¾ã™" +msgstr[1] "テーブル\"%2$s\"ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%1$s\" ã‚’ %3$d 個ã®ãƒ‘ãƒ©ãƒ¬ãƒ«ãƒ¯ãƒ¼ã‚«ã‚’è¦æ±‚ã—ã¦æ§‹ç¯‰ã—ã¦ã„ã¾ã™" -#: catalog/namespace.c:247 catalog/namespace.c:445 catalog/namespace.c:539 -#: commands/trigger.c:4233 +#: catalog/index.c:3689 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルã¯å†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ãã¾ã›ã‚“" + +#: catalog/index.c:3820 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "インデックス\"%s\"ã¯å†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã•れã¾ã—ãŸ" + +#: catalog/index.c:3891 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "パーティションテーブル㮠REINDEX ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“ã€\"%s\" ã¯ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: catalog/namespace.c:248 catalog/namespace.c:452 catalog/namespace.c:546 +#: commands/trigger.c:5400 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "データベース間ã®å‚ç…§ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“: \"%s.%s.%s\"" -#: catalog/namespace.c:304 +#: catalog/namespace.c:305 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "一時テーブルã«ã¯ã‚¹ã‚­ãƒ¼ãƒžåを指定ã§ãã¾ã›ã‚“" -#: catalog/namespace.c:383 +#: catalog/namespace.c:386 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "リレーション\"%s.%s\"ã®ãƒ­ãƒƒã‚¯ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/namespace.c:388 commands/lockcmds.c:146 +#: catalog/namespace.c:391 commands/lockcmds.c:152 commands/lockcmds.c:238 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "リレーション\"%s\"ã®ãƒ­ãƒƒã‚¯ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/namespace.c:412 parser/parse_relation.c:977 +#: catalog/namespace.c:419 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "リレーション\"%s.%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:417 parser/parse_relation.c:990 -#: parser/parse_relation.c:998 utils/adt/regproc.c:853 +#: catalog/namespace.c:424 parser/parse_relation.c:1171 +#: parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "リレーション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:485 catalog/namespace.c:2834 commands/extension.c:1400 -#: commands/extension.c:1406 +#: catalog/namespace.c:492 catalog/namespace.c:3011 commands/extension.c:1466 +#: commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "作æˆå…ˆã®ã‚¹ã‚­ãƒ¼ãƒžãŒé¸æŠžã•れã¦ã„ã¾ã›ã‚“" -#: catalog/namespace.c:637 catalog/namespace.c:650 +#: catalog/namespace.c:644 catalog/namespace.c:657 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚スキーマã®ä¸­ã«ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“" -#: catalog/namespace.c:641 +#: catalog/namespace.c:648 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "éžä¸€æ™‚スキーマã®ä¸­ã«ä¸€æ™‚リレーションを作æˆã§ãã¾ã›ã‚“" -#: catalog/namespace.c:656 +#: catalog/namespace.c:663 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "一時スキーマã®ä¸­ã«ã¯ä¸€æ™‚リレーションã—ã‹ä½œæˆã§ãã¾ã›ã‚“" -#: catalog/namespace.c:2136 +#: catalog/namespace.c:2201 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "統計情報オブジェクト\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/namespace.c:2324 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "テキスト検索パーサ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:2262 +#: catalog/namespace.c:2450 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "テキスト検索辞書\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:2389 +#: catalog/namespace.c:2577 #, c-format msgid "text search template \"%s\" does not exist" msgstr "テキスト検索テンプレート\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:2515 commands/tsearchcmds.c:1168 -#: utils/cache/ts_cache.c:619 +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1185 +#: utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "テキスト検索設定\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:2628 parser/parse_expr.c:788 parser/parse_target.c:1108 +#: catalog/namespace.c:2816 parser/parse_expr.c:793 parser/parse_target.c:1220 #, c-format msgid "cross-database references are not implemented: %s" msgstr "データベース間ã®å‚ç…§ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“: %s" -#: catalog/namespace.c:2634 gram.y:12234 gram.y:13432 parser/parse_expr.c:795 -#: parser/parse_target.c:1115 +#: catalog/namespace.c:2822 gram.y:14708 gram.y:16140 parser/parse_expr.c:800 +#: parser/parse_target.c:1227 #, c-format msgid "improper qualified name (too many dotted names): %s" -msgstr "修飾åãŒä¸é©åˆ‡ã§ã™(ドット付ãã®åå‰ãŒå¤šã™ãŽã¾ã™): %s" - -#: catalog/namespace.c:2768 -#, c-format -msgid "%s is already in schema \"%s\"" -msgstr "%s ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž \"%s\" 内ã«å­˜åœ¨ã—ã¾ã™" +msgstr "修飾åãŒä¸é©åˆ‡ã§ã™(ドット区切りã®åå‰ãŒå¤šã™ãŽã¾ã™): %s" -#: catalog/namespace.c:2776 +#: catalog/namespace.c:2953 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "一時スキーマã¸ã€ã¾ãŸã¯ä¸€æ™‚スキーマã‹ã‚‰ã‚ªãƒ–ジェクトを移動ã§ãã¾ã›ã‚“" -#: catalog/namespace.c:2782 +#: catalog/namespace.c:2959 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "TOASTスキーマã¸ã€ã¾ãŸã¯TOASTスキーマã‹ã‚‰ã‚ªãƒ–ジェクトを移動ã§ãã¾ã›ã‚“" -#: catalog/namespace.c:2855 commands/schemacmds.c:212 -#: commands/schemacmds.c:288 +#: catalog/namespace.c:3032 commands/schemacmds.c:256 commands/schemacmds.c:334 +#: commands/tablecmds.c:1015 #, c-format msgid "schema \"%s\" does not exist" msgstr "スキーマ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:2886 +#: catalog/namespace.c:3063 #, c-format msgid "improper relation name (too many dotted names): %s" -msgstr "リレーションåãŒä¸é©åˆ‡ã§ã™(ドット付ãã®åå‰ãŒå¤šã™ãŽã¾ã™): %s" +msgstr "リレーションåãŒä¸é©åˆ‡ã§ã™(ドット区切りã®åå‰ãŒå¤šã™ãŽã¾ã™): %s" -#: catalog/namespace.c:3327 +#: catalog/namespace.c:3597 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "エンコーディング \"%2$s\" ã®ãŸã‚ã®ç…§åˆé †åº \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:3382 +#: catalog/namespace.c:3652 #, c-format msgid "conversion \"%s\" does not exist" msgstr "変æ›\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/namespace.c:3590 +#: catalog/namespace.c:3860 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "データベース\"%s\"ã«ä¸€æ™‚テーブルを作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: catalog/namespace.c:3606 +#: catalog/namespace.c:3876 #, c-format msgid "cannot create temporary tables during recovery" -msgstr "リカãƒãƒªä¸­ã«ä¸€æ™‚テーブルを作æˆã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªä¸­ã¯ä¸€æ™‚テーブルを作æˆã§ãã¾ã›ã‚“" -#: catalog/namespace.c:3850 commands/tablespace.c:1079 commands/variable.c:61 -#: replication/syncrep.c:676 utils/misc/guc.c:8394 +#: catalog/namespace.c:3882 #, c-format -msgid "List syntax is invalid." -msgstr "ãƒªã‚¹ãƒˆã®æ–‡æ³•ãŒç„¡åйã§ã™" +msgid "cannot create temporary tables during a parallel operation" +msgstr "並行処ç†ä¸­ã¯ä¸€æ™‚テーブルを作æˆã§ãã¾ã›ã‚“" -#: catalog/objectaddress.c:719 -msgid "database name cannot be qualified" -msgstr "データベースåを修飾ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:722 commands/extension.c:2427 +#: catalog/namespace.c:4165 commands/tablespace.c:1171 commands/variable.c:64 +#: utils/misc/guc.c:10267 utils/misc/guc.c:10345 #, c-format -msgid "extension name cannot be qualified" -msgstr "拡張機能åを修飾ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:725 -msgid "tablespace name cannot be qualified" -msgstr "テーブル空間åを修飾ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:728 -msgid "role name cannot be qualified" -msgstr "ロールåを修飾ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:731 -msgid "schema name cannot be qualified" -msgstr "スキーマåを修飾ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:734 -msgid "language name cannot be qualified" -msgstr "言語åを修飾ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:737 -msgid "foreign-data wrapper name cannot be qualified" -msgstr "外部データラッパーåを修飾ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:740 -msgid "server name cannot be qualified" -msgstr "サーãƒåを修飾ã§ãã¾ã›ã‚“" - -#: catalog/objectaddress.c:743 -#| msgid "server name cannot be qualified" -msgid "event trigger name cannot be qualified" -msgstr "イベントトリガã®åå‰ã‚’修飾ã§ãã¾ã›ã‚“" +msgid "List syntax is invalid." +msgstr "リスト文法ãŒç„¡åйã§ã™" -#: catalog/objectaddress.c:856 commands/lockcmds.c:94 commands/tablecmds.c:208 -#: commands/tablecmds.c:1240 commands/tablecmds.c:4031 -#: commands/tablecmds.c:7489 +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 +#: commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1723 +#: commands/tablecmds.c:4985 commands/tablecmds.c:9216 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/objectaddress.c:863 commands/tablecmds.c:220 -#: commands/tablecmds.c:4055 commands/tablecmds.c:10691 commands/view.c:153 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 +#: commands/tablecmds.c:5015 commands/tablecmds.c:13599 commands/view.c:143 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\"ã¯ãƒ“ューã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/objectaddress.c:870 commands/matview.c:166 commands/tablecmds.c:226 -#: commands/tablecmds.c:10696 +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 +#: commands/tablecmds.c:13604 #, c-format -#| msgid "\"%s\" is not a table or view" msgid "\"%s\" is not a materialized view" -msgstr "\"%s\"ã¯ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã¯å®Ÿä½“化ビューã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/objectaddress.c:877 commands/tablecmds.c:244 -#: commands/tablecmds.c:4058 commands/tablecmds.c:10701 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 +#: commands/tablecmds.c:5018 commands/tablecmds.c:13609 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\" ã¯å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/objectaddress.c:1008 +#: catalog/objectaddress.c:1300 +#, c-format +msgid "must specify relation and object name" +msgstr "リレーションã¨ã‚ªãƒ–ジェクトã®åå‰ã®æŒ‡å®šãŒå¿…è¦ã§ã™" + +#: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 #, c-format msgid "column name must be qualified" -msgstr "列åを修飾ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "列åを修飾ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/objectaddress.c:1061 commands/functioncmds.c:127 -#: commands/tablecmds.c:236 commands/typecmds.c:3252 parser/parse_func.c:1624 -#: parser/parse_type.c:203 utils/adt/acl.c:4374 utils/adt/regproc.c:1017 +#: catalog/objectaddress.c:1472 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã«å¯¾ã™ã‚‹ãƒ‡ãƒ•ォルト値ãŒå­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 +#: commands/tablecmds.c:253 commands/typecmds.c:3324 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 #, c-format msgid "type \"%s\" does not exist" msgstr "åž‹\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/objectaddress.c:1217 libpq/be-fsstubs.c:352 +#: catalog/objectaddress.c:1628 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "%4$sã®æ¼”ç®—å­ %1$d (%2$s, %3$s) ãŒã‚りã¾ã›ã‚“" + +#: catalog/objectaddress.c:1659 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "%4$s ã®é–¢æ•° %1$d (%2$s, %3$s) ãŒã‚りã¾ã›ã‚“" + +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "ユーザ\"%s\"ã«å¯¾ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングãŒã‚µãƒ¼ãƒ\"%s\"ã«ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 +#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 +#: foreign/foreign.c:688 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "サーãƒãƒ¼ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:1792 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "パブリケーション\"%2$s\"ã®ç™ºè¡Œãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:1854 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "デフォルトã®ACLオブジェクトタイプ\"%c\"ã¯èªè­˜ã§ãã¾ã›ã‚“" + +#: catalog/objectaddress.c:1855 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "有効ãªå€¤ã¯ \"%c\", \"%c\", \"%c\", \"%c\", \"%c\" ã§ã™ã€‚" + +#: catalog/objectaddress.c:1906 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "ユーザ\"%s\"ã«å¯¾ã™ã‚‹ã€åå‰ç©ºé–“\"%s\"ã®%sã¸ã®ãƒ‡ãƒ•ォルトã®ACLã¯ã‚りã¾ã›ã‚“" + +#: catalog/objectaddress.c:1911 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "ユーザ\"%s\"ã«å¯¾ã™ã‚‹%sã¸ã®ãƒ‡ãƒ•ォルトACLã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 +#: catalog/objectaddress.c:2053 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "åå‰ã¾ãŸã¯å¼•æ•°ã®ãƒªã‚¹ãƒˆã¯nullã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: catalog/objectaddress.c:1972 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "サãƒãƒ¼ãƒˆã•れãªã„オブジェクトタイプ\"%s\"" + +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 +#: catalog/objectaddress.c:2151 +#, c-format +msgid "name list length must be exactly %d" +msgstr "åå‰ãƒªã‚¹ãƒˆã®é•·ã•ã¯æ­£ç¢ºã«%dã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: catalog/objectaddress.c:2014 +#, c-format +msgid "large object OID may not be null" +msgstr "ラージオブジェクトã®OIDã¯nullã«ã¯ãªã‚Šå¾—ã¾ã›ã‚“" + +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:2093 +#, c-format +msgid "name list length must be at least %d" +msgstr "åå‰ãƒªã‚¹ãƒˆã®é•·ã•ã¯%d以上ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "引数リストã®é•·ã•ã¯ã¡ã‚‡ã†ã©%dã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" -msgstr "ラージオブジェクト %u ã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ラージオブジェクト %u ã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/objectaddress.c:1232 commands/functioncmds.c:1298 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 #, c-format msgid "must be owner of type %s or type %s" -msgstr "åž‹%sã¾ãŸã¯åž‹%sã®æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "åž‹%sã¾ãŸã¯åž‹%sã®æ‰€æœ‰è€…ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/objectaddress.c:1263 catalog/objectaddress.c:1279 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" -msgstr "スーパーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スーパーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: catalog/objectaddress.c:1270 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "CREATEROLE 権é™ãŒå¿…è¦ã§ã™" -#: catalog/objectaddress.c:1516 +#: catalog/objectaddress.c:2481 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "èªè­˜ã•れãªã„オブジェクトタイプ\"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " 列 %s" +msgid "column %s of %s" +msgstr "%2$s ã®åˆ— %1$s" -#: catalog/objectaddress.c:1522 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" -msgstr "関数 %s" +msgstr "関数%s" -#: catalog/objectaddress.c:1527 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" -msgstr "åž‹ %s" +msgstr "åž‹%s" -#: catalog/objectaddress.c:1557 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" -msgstr "%sã‹ã‚‰%sã¸ã®ã‚­ãƒ£ã‚¹ãƒˆ" +msgstr "%sã‹ã‚‰%sã¸ã®åž‹å¤‰æ›" -#: catalog/objectaddress.c:1577 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" -msgstr "ç…§åˆé †åº %s" +msgstr "ç…§åˆé †åº%s" -#: catalog/objectaddress.c:1601 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" -msgstr "%2$s ã«å¯¾ã™ã‚‹åˆ¶ç´„ %1$s" +msgstr "%2$sã«å¯¾ã™ã‚‹åˆ¶ç´„%1$s" -#: catalog/objectaddress.c:1607 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" -msgstr "制約 %s" +msgstr "制約%s" -#: catalog/objectaddress.c:1624 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" -msgstr "å¤‰æ› %s" +msgstr "変æ›%s" -#: catalog/objectaddress.c:1661 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" -msgstr "%s用ã®ãƒ‡ãƒ•ォルト" +msgid "default value for %s" +msgstr "%s ã®ãƒ‡ãƒ•ォルト値" -#: catalog/objectaddress.c:1678 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "言語%s" -#: catalog/objectaddress.c:1684 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" -msgstr "ラージオブジェクト %u" +msgstr "ラージオブジェクト%u" -#: catalog/objectaddress.c:1689 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "演算å­%s" -#: catalog/objectaddress.c:1721 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "アクセスメソッド%2$sç”¨ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹%1$s" +#: catalog/objectaddress.c:2939 +#, c-format +msgid "access method %s" +msgstr "アクセスメソッド%s" + #. translator: %d is the operator strategy (a number), the #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:1771 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" -msgstr "%4$s ã®æ¼”ç®—å­ %1$d (%2$s, %3$s): %5$s" +msgstr "%4$sã®æ¼”ç®—å­%1$d (%2$s, %3$s): %5$s" #. translator: %d is the function number, the first two %s's #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:1821 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "%4$s ã®é–¢æ•° %1$d (%2$s, %3$s): %5$s" -#: catalog/objectaddress.c:1861 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "rule %s on " -msgstr "ã®ãƒ«ãƒ¼ãƒ« %s" +msgid "rule %s on %s" +msgstr "%2$s ã®ãƒ«ãƒ¼ãƒ« %1$s" -#: catalog/objectaddress.c:1896 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "トリガ %sã€å¯¾è±¡:" +msgid "trigger %s on %s" +msgstr "%2$s ã®ãƒˆãƒªã‚¬ %1$s" -#: catalog/objectaddress.c:1913 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" -msgstr "スキーマ %s" +msgstr "スキーマ%s" + +#: catalog/objectaddress.c:3152 +#, c-format +msgid "statistics object %s" +msgstr "統計オブジェクト%s" -#: catalog/objectaddress.c:1926 +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" -msgstr "テキスト検索パーサ %s" +msgstr "テキスト検索パーサ%s" -#: catalog/objectaddress.c:1941 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" -msgstr "テキスト検索辞書 %s" +msgstr "テキスト検索辞書%s" -#: catalog/objectaddress.c:1956 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" -msgstr "テキスト検索テンプレート %s" +msgstr "テキスト検索テンプレート%s" -#: catalog/objectaddress.c:1971 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" -msgstr "テキスト検索設定 %s" +msgstr "テキスト検索設定%s" -#: catalog/objectaddress.c:1979 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" -msgstr "ロール %s" +msgstr "ロール%s" -#: catalog/objectaddress.c:1992 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" -msgstr "データベース %s" +msgstr "データベース%s" -#: catalog/objectaddress.c:2004 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" -msgstr "テーブル空間 %s" +msgstr "テーブル空間%s" -#: catalog/objectaddress.c:2013 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" -msgstr "外部データラッパー %s" +msgstr "外部データラッパー%s" -#: catalog/objectaddress.c:2022 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" -msgstr "サーム%s" +msgstr "サーãƒ%s" -#: catalog/objectaddress.c:2047 +#: catalog/objectaddress.c:3337 #, c-format -msgid "user mapping for %s" -msgstr "%s ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ング" +msgid "user mapping for %s on server %s" +msgstr "サーãƒ%2$s上ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ング%1$s" -#: catalog/objectaddress.c:2081 +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "スキーマ %2$s ã®ãƒ­ãƒ¼ãƒ« %1$s ã®ã‚‚ã®ã§ã‚ã‚‹æ–°ã—ã„リレーションã®ãƒ‡ãƒ•ォルト権é™" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" -msgstr "æ–°ã—ã„リレーションã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ« %s ã«å±žã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„リレーションã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ«%sã«å±žã—ã¾ã™ã€‚" + +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "スキーマ %2$s ã®ãƒ­ãƒ¼ãƒ« %1$s ã®ã‚‚ã®ã§ã‚ã‚‹æ–°ã—ã„シーケンスã®ãƒ‡ãƒ•ォルト権é™" -#: catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" -msgstr "æ–°ã—ã„シーケンスã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ« %s ã«å±žã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„シーケンスã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ«%sã«å±žã—ã¾ã™ã€‚" -#: catalog/objectaddress.c:2091 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "スキーマ %2$s ã®ãƒ­ãƒ¼ãƒ« %1$s ã®ã‚‚ã®ã§ã‚ã‚‹æ–°ã—ã„関数ã®ãƒ‡ãƒ•ォルト権é™" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" -msgstr "æ–°ã—ã„関数ã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ« %s ã«å±žã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„関数ã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ«%sã«å±žã—ã¾ã™ã€‚" + +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "スキーマ %2$s ã®ãƒ­ãƒ¼ãƒ« %1$s ã®ã‚‚ã®ã§ã‚ã‚‹æ–°ã—ã„åž‹ã®ãƒ‡ãƒ•ォルト権é™" -#: catalog/objectaddress.c:2096 +#: catalog/objectaddress.c:3416 #, c-format -#| msgid "default privileges on new sequences belonging to role %s" msgid "default privileges on new types belonging to role %s" -msgstr "æ–°ã—ã„åž‹ã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ« %s ã«å±žã—ã¾ã™" +msgstr "æ–°ã—ã„åž‹ã«é–¢ã™ã‚‹ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ã€ãƒ­ãƒ¼ãƒ«%sã«å±žã—ã¾ã™" -#: catalog/objectaddress.c:2102 +#: catalog/objectaddress.c:3422 #, c-format -msgid "default privileges belonging to role %s" -msgstr "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ãƒ­ãƒ¼ãƒ« %s ã«å±žã—ã¾ã™ã€‚" +msgid "default privileges on new schemas belonging to role %s" +msgstr "ロール%sã«å±žã™ã‚‹æ–°ã—ã„スキーマ上ã®ãƒ‡ãƒ•ォルト権é™" + +#: catalog/objectaddress.c:3429 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "スキーマ %2$s ã®ãƒ­ãƒ¼ãƒ« %1$s ã«å±žã™ã‚‹ãƒ‡ãƒ•ォルト権é™" -#: catalog/objectaddress.c:2110 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr "スキーマ %s ã«ãŠã„ã¦" +msgid "default privileges belonging to role %s" +msgstr "ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¨©é™ã¯ãƒ­ãƒ¼ãƒ«%sã«å±žã—ã¾ã™ã€‚" -#: catalog/objectaddress.c:2127 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" -msgstr "拡張機能 %s" +msgstr "機能拡張%s" -#: catalog/objectaddress.c:2140 +#: catalog/objectaddress.c:3464 #, c-format -#| msgid "List of event triggers" msgid "event trigger %s" -msgstr "イベントトリガ %s" +msgstr "イベントトリガ%s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 +#, c-format +msgid "policy %s on %s" +msgstr "%2$s ã®ãƒãƒªã‚· %1$s" + +#: catalog/objectaddress.c:3510 +#, c-format +msgid "publication %s" +msgstr "パブリケーション%s" -#: catalog/objectaddress.c:2200 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 +#, c-format +msgid "publication of %s in publication %s" +msgstr "パブリケーション %2$s ã§ã® %1$s ã®ç™ºè¡Œ" + +#: catalog/objectaddress.c:3544 +#, c-format +msgid "subscription %s" +msgstr "サブスクリプション%s" + +#: catalog/objectaddress.c:3562 +#, c-format +msgid "transform for %s language %s" +msgstr "言語%2$sã®%1$såž‹ã«å¯¾ã™ã‚‹å¤‰æ›" + +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" -msgstr "テーブル %s" +msgstr "テーブル%s" -#: catalog/objectaddress.c:2204 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" -msgstr "インデックス %s" +msgstr "インデックス%s" -#: catalog/objectaddress.c:2208 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "シーケンス%s" -#: catalog/objectaddress.c:2212 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "TOASTテーブル%s" -#: catalog/objectaddress.c:2216 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "ビュー%s" -#: catalog/objectaddress.c:2220 +#: catalog/objectaddress.c:3646 #, c-format -#| msgid "materialized view" msgid "materialized view %s" -msgstr "マテリアライズドビュー %s" +msgstr "実体化ビュー%s" -#: catalog/objectaddress.c:2224 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "複åˆåž‹%s" -#: catalog/objectaddress.c:2228 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" -msgstr "外部テーブル %s" +msgstr "外部テーブル%s" -#: catalog/objectaddress.c:2233 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "リレーション%s" -#: catalog/objectaddress.c:2270 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" -msgstr "アクセスメソッド%2$sç”¨ã®æ¼”ç®—å­æ—%1$s" +msgstr "アクセスメソッド%2$sã®æ¼”ç®—å­æ—%1$s" + +#: catalog/partition.c:180 catalog/pg_constraint.c:467 commands/analyze.c:1499 +#: commands/indexcmds.c:928 commands/tablecmds.c:942 commands/tablecmds.c:9278 +#: commands/tablecmds.c:14493 commands/tablecmds.c:14983 +#: executor/execExprInterp.c:3275 executor/execMain.c:1940 +#: executor/execMain.c:2019 executor/execMain.c:2067 executor/execMain.c:2173 +#: executor/execPartition.c:462 executor/execPartition.c:522 +#: executor/execPartition.c:638 executor/execPartition.c:741 +#: executor/execPartition.c:812 executor/execPartition.c:1010 +#: executor/nodeModifyTable.c:1859 +msgid "could not convert row type" +msgstr "行型ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: catalog/pg_aggregate.c:126 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "集約ã¯%d個以上ã®å¼•æ•°ã‚’å–ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr[1] "集約ã¯%d個以上ã®å¼•æ•°ã‚’å–ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/pg_aggregate.c:102 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" -msgstr "é·ç§»ç”¨ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’決定ã§ãã¾ã›ã‚“" +msgstr "é·ç§»ãƒ‡ãƒ¼ã‚¿åž‹ã‚’決定ã§ãã¾ã›ã‚“" -#: catalog/pg_aggregate.c:103 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." -msgstr "é·ç§»ç”¨ã®åž‹ã¨ã—ã¦å¤šæ§˜åž‹ã‚’使用ã™ã‚‹é›†ç´„ã¯å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å°‘ãªãã¨ã‚‚1ã¤å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "é·ç§»å¤šæ§˜åž‹ã‚’用ã„る集約ã¯å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å°‘ãªãã¨ã‚‚1ã¤å–ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/pg_aggregate.c:126 +#: catalog/pg_aggregate.c:173 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "å¯å¤‰é•·å¼•æ•°ã®é †åºé›†åˆé›†ç´„ã¯VARIADICåž‹ã®ANYを使ã†å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/pg_aggregate.c:199 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "仮想集åˆé›†ç´„ã¯é›†ç´„ã•れãŸå¼•æ•°ã«é©åˆã™ã‚‹ç›´æŽ¥å¼•æ•°ã‚’æŒã¤å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "é·ç§»é–¢æ•°ã®æˆ»ã‚Šå€¤åž‹%sã¯%sã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/pg_aggregate.c:146 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "é·ç§»é–¢æ•°ãŒSTRICTã‹ã¤é·ç§»ç”¨ã®åž‹ãŒå…¥åŠ›åž‹ã¨ãƒã‚¤ãƒŠãƒªäº’æ›ãŒãªã„å ´åˆåˆæœŸå€¤ã‚’çœç•¥ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: catalog/pg_aggregate.c:177 catalog/pg_proc.c:241 catalog/pg_proc.c:248 +#: catalog/pg_aggregate.c:335 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "逆é·ç§»é–¢æ•°%sã®æˆ»ã‚Šå€¤ã®åž‹ãŒ%sã§ã¯ã‚りã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "集約ã®å‰é€²ã¨å転ã®é·ç§»é–¢æ•°ã®STRICT属性ã¯ä¸€è‡´ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "追加ã®å¼•æ•°ã‚’æŒã¤æœ€çµ‚関数ã¯STRICT宣言ã§ãã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:427 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "çµåˆé–¢æ•°%sã®æˆ»ã‚Šå€¤ã®åž‹ãŒ%sã§ã¯ã‚りã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2943 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "é·ç§»ã‚¿ã‚¤ãƒ—%sã®çµåˆé–¢æ•°ã¯STRICT宣言ã§ãã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:458 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "直列化関数%sã®æˆ»ã‚Šå€¤ã®åž‹ãŒ%sã§ã¯ã‚りã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:479 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "復元関数%sã®æˆ»ã‚Šå€¤ã®åž‹ãŒ%sã§ã¯ã‚りã¾ã›ã‚“" + +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "çµæžœã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’決定ã§ãã¾ã›ã‚“" -#: catalog/pg_aggregate.c:178 +#: catalog/pg_aggregate.c:496 #, c-format msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." -msgstr "多様型を返ã™é›†ç´„ã¯å°‘ãªãã¨ã‚‚1ã¤ã®å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "多様型を返ã™é›†ç´„ã¯å°‘ãªãã¨ã‚‚1ã¤ã®å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/pg_aggregate.c:190 catalog/pg_proc.c:254 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" -msgstr "\"internal\"仮想型ã®å±é™ºãªä½¿ç”¨" +msgstr "\"internal\"仮想型ã®å®‰å…¨ã§ã¯ãªã„使用" -#: catalog/pg_aggregate.c:191 catalog/pg_proc.c:255 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format msgid "A function returning \"internal\" must have at least one \"internal\" argument." -msgstr "\"internal\"\"ã‚’è¿”ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®\"internal\"åž‹ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "\"internal\"\"ã‚’è¿”ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®\"internal\"åž‹ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/pg_aggregate.c:199 +#: catalog/pg_aggregate.c:562 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "移動集約ã®å®Ÿè£…ãŒ%s型を返å´ã—ã¾ã—ãŸã€ã—ã‹ã—普通ã®å®Ÿè£…ã®æ–¹ã¯%s型を返å´ã—ã¦ã„ã¾ã™" + +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "ソート演算å­ã¯å˜ä¸€å¼•æ•°ã®é›†ç´„ã§ã®ã¿æŒ‡å®šå¯èƒ½ã§ã™" -#: catalog/pg_aggregate.c:358 commands/typecmds.c:1656 -#: commands/typecmds.c:1707 commands/typecmds.c:1738 commands/typecmds.c:1761 -#: commands/typecmds.c:1782 commands/typecmds.c:1809 commands/typecmds.c:1836 -#: commands/typecmds.c:1913 commands/typecmds.c:1955 parser/parse_func.c:298 -#: parser/parse_func.c:309 parser/parse_func.c:1603 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 +#: commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 +#: commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 +#: commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 +#: parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 +#: parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "関数%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/pg_aggregate.c:364 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "関数%sã¯é›†åˆã‚’è¿”ã—ã¾ã™" -#: catalog/pg_aggregate.c:389 +#: catalog/pg_aggregate.c:840 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "ã“ã®é›†ç´„ã§ä½¿ã†ã«ã¯é–¢æ•°%s㯠VARIADIC ANY ã‚’å—ã‘付ã‘ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "関数%sã¯å®Ÿè¡Œæ™‚ã®åž‹å¼·åˆ¶ãŒå¿…è¦ã§ã™" -#: catalog/pg_collation.c:77 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format -msgid "collation \"%s\" for encoding \"%s\" already exists" -msgstr "エンコーディング \"%2$s\" ã®ç…§åˆé †åº \"%1$s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgid "collation \"%s\" already exists, skipping" +msgstr "ç…§åˆé †åº\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: catalog/pg_collation.c:94 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "エンコーディング\"%2$s\"ã«å¯¾ã™ã‚‹ç…§åˆé †åº\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: catalog/pg_collation.c:91 +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "ç…§åˆé †åº \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_constraint.c:659 +#: catalog/pg_collation.c:104 #, c-format -msgid "constraint \"%s\" for domain %s already exists" -msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "エンコーディング \"%2$s\" ã®ç…§åˆé †åº \"%1$s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_constraint.c:792 +#: catalog/pg_constraint.c:1077 #, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "テーブル\"%s\"ã«ã¯è¤‡æ•°ã®\"%s\"ã¨ã„ã†åå‰ã®åˆ¶ç´„ãŒã‚りã¾ã™" +msgid "constraint \"%s\" for domain %s already exists" +msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_constraint.c:804 +#: catalog/pg_constraint.c:1256 catalog/pg_constraint.c:1349 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/pg_constraint.c:850 -#, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "ドメイン\"%s\"ã«ã¯è¤‡æ•°ã®\"%s\"ã¨ã„ã†åå‰ã®åˆ¶ç´„ãŒã‚りã¾ã™" - -#: catalog/pg_constraint.c:862 +#: catalog/pg_constraint.c:1438 #, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" +msgid "constraint \"%s\" for domain %s does not exist" msgstr "ドメイン\"%2$s\"ã«å¯¾ã™ã‚‹åˆ¶ç´„\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/pg_conversion.c:67 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "変æ›\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_conversion.c:80 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "%sã‹ã‚‰%sã¸ã®ãƒ‡ãƒ•ォルトã®å¤‰æ›ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_depend.c:165 commands/extension.c:2930 +#: catalog/pg_depend.c:163 commands/extension.c:3218 #, c-format msgid "%s is already a member of extension \"%s\"" -msgstr "%s ã¯ã™ã§ã«æ‹¡å¼µæ©Ÿèƒ½ \"%s\" ã®ãƒ¡ãƒ³ãƒã§ã™" +msgstr "%s ã¯ã™ã§ã«æ©Ÿèƒ½æ‹¡å¼µ \"%s\" ã®ãƒ¡ãƒ³ãƒã§ã™" -#: catalog/pg_depend.c:324 +#: catalog/pg_depend.c:322 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "システムオブジェクトã§ã‚ã‚‹ãŸã‚ã€%sã®ä¾å­˜é–¢ä¿‚を削除ã§ãã¾ã›ã‚“。" -#: catalog/pg_enum.c:114 catalog/pg_enum.c:201 +#: catalog/pg_enum.c:115 catalog/pg_enum.c:201 catalog/pg_enum.c:488 #, c-format msgid "invalid enum label \"%s\"" -msgstr "列挙ラベル\"%s\"ã¯ç„¡åйã§ã™" +msgstr "列挙ラベル\"%s\"ã¯ä¸æ­£ã§ã™" -#: catalog/pg_enum.c:115 catalog/pg_enum.c:202 +#: catalog/pg_enum.c:116 catalog/pg_enum.c:202 catalog/pg_enum.c:489 #, c-format msgid "Labels must be %d characters or less." msgstr "ラベルã¯%d文字数以内ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" #: catalog/pg_enum.c:230 #, c-format -#| msgid "relation \"%s\" already exists, skipping" msgid "enum label \"%s\" already exists, skipping" -msgstr "列挙ラベル \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚スキップã—ã¾ã™ã€‚" +msgstr "列挙ラベル \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: catalog/pg_enum.c:237 +#: catalog/pg_enum.c:237 catalog/pg_enum.c:532 #, c-format -#| msgid "language \"%s\" already exists" msgid "enum label \"%s\" already exists" msgstr "列挙ラベル\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_enum.c:292 +#: catalog/pg_enum.c:292 catalog/pg_enum.c:527 #, c-format msgid "\"%s\" is not an existing enum label" msgstr "\"%s\" ã¯æ—¢å­˜ã®åˆ—挙型ラベルã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/pg_enum.c:353 +#: catalog/pg_enum.c:350 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中㫠pg_enum ã®OIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" + +#: catalog/pg_enum.c:360 #, c-format msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" msgstr "ALTER TYPE ADD BEFORE/AFTER ã¯ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードã§ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: catalog/pg_namespace.c:61 commands/schemacmds.c:220 +#: catalog/pg_namespace.c:63 commands/schemacmds.c:264 #, c-format msgid "schema \"%s\" already exists" msgstr "スキーマ\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_operator.c:222 catalog/pg_operator.c:362 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "\"%s\"ã¯æœ‰åŠ¹ãªæ¼”ç®—å­åã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/pg_operator.c:371 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" -msgstr "二項演算å­ã®ã¿ãŒäº¤ä»£æ¼”ç®—å­ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" +msgstr "二項演算å­ã®ã¿ãŒäº¤æ›å­ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "二項演算å­ã®ã¿ãŒçµåˆé¸æŠžæ€§ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "二項演算å­ã®ã¿ãŒãƒžãƒ¼ã‚¸çµåˆå¯èƒ½ã§ã™" -#: catalog/pg_operator.c:383 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "二項演算å­ã®ã¿ãŒãƒãƒƒã‚·ãƒ¥å¯èƒ½ã§ã™" -#: catalog/pg_operator.c:394 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "ブール型演算å­ã®ã¿ãŒå¦å®šæ¼”ç®—å­ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: catalog/pg_operator.c:398 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" -msgstr "ブール型演算å­ã®ã¿ãŒåˆ¶é™é¸æŠžæ€§ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" +msgstr "ブール型演算å­ã®ã¿ãŒåˆ¶é™é¸æŠžçŽ‡ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" -msgstr "ブール型演算å­ã®ã¿ãŒçµåˆé¸æŠžæ€§ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" +msgstr "ブール型演算å­ã®ã¿ãŒçµåˆé¸æŠžçŽ‡ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "ブール型演算å­ã®ã¿ãŒãƒžãƒ¼ã‚¸çµåˆå¯èƒ½ã§ã™" -#: catalog/pg_operator.c:410 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "ブール型演算å­ã®ã¿ãŒãƒãƒƒã‚·ãƒ¥å¯èƒ½ã§ã™" -#: catalog/pg_operator.c:422 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "演算å­%sã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: catalog/pg_operator.c:615 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "演算å­ã¯è‡ªèº«ã®å¦å®šå­ã‚„ソート演算å­ã«ãªã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:129 parser/parse_func.c:1648 parser/parse_func.c:1688 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "関数ã¯%dã‚’è¶…ãˆã‚‹å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -msgstr[1] "関数ã¯%dã‚’è¶…ãˆã‚‹å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr[1] "関数ã¯%d個を超ãˆã‚‹å¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:242 +#: catalog/pg_proc.c:241 #, c-format msgid "A function returning a polymorphic type must have at least one polymorphic argument." -msgstr "多様型を返ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "多様型を返ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®å¤šæ§˜åž‹ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/pg_proc.c:249 +#: catalog/pg_proc.c:248 #, c-format -#| msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." -msgstr "\"anyrange\"ã‚’è¿”ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®\"anyrange\"åž‹ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "\"anyrange\"ã‚’è¿”ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®\"anyrange\"åž‹ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: catalog/pg_proc.c:267 +#: catalog/pg_proc.c:383 #, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "\"%s\"ã¯ã™ã§ã«åž‹%sã®å±žæ€§ã§ã™" +msgid "function \"%s\" already exists with same argument types" +msgstr "åŒã˜å¼•数型をæŒã¤é–¢æ•°\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" #: catalog/pg_proc.c:393 #, c-format -msgid "function \"%s\" already exists with same argument types" -msgstr "åŒã˜å¼•数型をæŒã¤é–¢æ•°\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgid "cannot change routine kind" +msgstr "ルーãƒãƒ³ã®ç¨®åˆ¥ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: catalog/pg_proc.c:395 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\"ã¯é›†ç´„関数ã§ã™ã€‚" + +#: catalog/pg_proc.c:397 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\"ã¯é–¢æ•°ã§ã™ã€‚" + +#: catalog/pg_proc.c:399 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\"ã¯ãƒ—ロシージャã§ã™ã€‚" + +#: catalog/pg_proc.c:401 +#, c-format +msgid "\"%s\" is a window function." +msgstr "関数 \"%s\" ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã§ã™ã€‚" + +#: catalog/pg_proc.c:419 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "プロシージャã®å‡ºåŠ›ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æœ‰ç„¡ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:407 catalog/pg_proc.c:430 +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 #, c-format msgid "cannot change return type of existing function" msgstr "既存ã®é–¢æ•°ã®æˆ»ã‚Šå€¤åž‹ã‚’変更ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:408 catalog/pg_proc.c:432 catalog/pg_proc.c:475 -#: catalog/pg_proc.c:499 catalog/pg_proc.c:526 +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 +#: catalog/pg_proc.c:520 catalog/pg_proc.c:548 #, c-format -#| msgid "Use DROP FUNCTION first." -msgid "Use DROP FUNCTION %s first." -msgstr "ã¾ãšDROP FUNCTION %sを使用ã—ã¦ãã ã•ã„。" +msgid "Use %s %s first." +msgstr "ã¾ãš %s %s を使用ã—ã¦ãã ã•ã„。" -#: catalog/pg_proc.c:431 +#: catalog/pg_proc.c:447 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "OUTパラメータã§å®šç¾©ã•れãŸè¡Œåž‹ãŒç•°ãªã‚Šã¾ã™ã€‚" -#: catalog/pg_proc.c:473 +#: catalog/pg_proc.c:491 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "入力パラメーター \"%s\" ã®å称を変更ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:498 +#: catalog/pg_proc.c:518 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "既存ã®é–¢æ•°ã‹ã‚‰ãƒ‘ラメータã®ãƒ‡ãƒ•ォルト値を削除ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:525 +#: catalog/pg_proc.c:546 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "既存ã®ãƒ‘ラメータã®ãƒ‡ãƒ•ォルト値ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’変更ã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:538 +#: catalog/pg_proc.c:749 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "\"%s\"ã¨ã„ã†åå‰ã®çµ„ã¿è¾¼ã¿é–¢æ•°ã¯ã‚りã¾ã›ã‚“" + +#: catalog/pg_proc.c:847 #, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "関数 \"%s\" ã¯é›†ç´„関数ã§ã™" +msgid "SQL functions cannot return type %s" +msgstr "SQL関数ã¯åž‹%sã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:543 +#: catalog/pg_proc.c:862 #, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "関数 \"%s\" ã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL関数ã¯åž‹%sã®å¼•æ•°ã¨å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: catalog/pg_proc.c:551 +#: catalog/pg_proc.c:950 executor/functions.c:1434 #, c-format -msgid "function \"%s\" is a window function" -msgstr "関数 \"%s\" ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã§ã™" +msgid "SQL function \"%s\"" +msgstr "SQL関数\"%s\"" -#: catalog/pg_proc.c:556 +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 #, c-format -msgid "function \"%s\" is not a window function" -msgstr "関数 \"%s\" ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã§ã¯ã‚りã¾ã›ã‚“" +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\"ã¯ãƒ‘ーティションテーブルã§ã™" -#: catalog/pg_proc.c:733 +#: catalog/pg_publication.c:59 #, c-format -msgid "there is no built-in function named \"%s\"" -msgstr "\"%s\"ã¨ã„ã†åå‰ã®é–¢æ•°ã¯çµ„ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã›ã‚“" +msgid "Adding partitioned tables to publications is not supported." +msgstr "パブリケーションã¸ã®ãƒ‘ーティションテーブルã®è¿½åŠ ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: catalog/pg_proc.c:825 +#: catalog/pg_publication.c:60 #, c-format -msgid "SQL functions cannot return type %s" -msgstr "SQL関数ã¯åž‹%sã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "You can add the table partitions individually." +msgstr "å„パーティション個別ã«ãªã‚‰è¿½åŠ ã¯å¯èƒ½ã§ã™ã€‚" -#: catalog/pg_proc.c:840 +#: catalog/pg_publication.c:68 #, c-format -msgid "SQL functions cannot have arguments of type %s" -msgstr "SQL関数ã¯åž‹%sã®å¼•æ•°ã¨å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "Only tables can be added to publications." +msgstr "パブリケーションã«ã¯ãƒ†ãƒ¼ãƒ–ルã®ã¿ãŒè¿½åŠ ã§ãã¾ã™" -#: catalog/pg_proc.c:926 executor/functions.c:1411 +#: catalog/pg_publication.c:74 #, c-format -msgid "SQL function \"%s\"" -msgstr "SQL関数\"%s\"" +msgid "\"%s\" is a system table" +msgstr "\"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ルã§ã™" + +#: catalog/pg_publication.c:76 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "システムテーブルをパブリケーションã«è¿½åŠ ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: catalog/pg_publication.c:82 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "テーブル\"%s\"ã¯ãƒ¬ãƒ—リケーションã§ãã¾ã›ã‚“" + +#: catalog/pg_publication.c:84 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "一時テーブルã¨UNLOGGEDテーブルã¯ãƒ¬ãƒ—リケーションã§ãã¾ã›ã‚“" + +#: catalog/pg_publication.c:175 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "リレーション\"%s\"ã¯ã™ã§ã«ãƒ‘ブリケーション\"%s\"ã®ãƒ¡ãƒ³ãƒã§ã™" + +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 +#: commands/publicationcmds.c:415 commands/publicationcmds.c:716 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "パブリケーション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: catalog/pg_shdepend.c:689 +#: catalog/pg_shdepend.c:692 #, c-format msgid "" "\n" @@ -3725,30 +4997,35 @@ msgstr[1] "" "\n" "ãŠã‚ˆã³ã€ä»–ã®%dã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å†…ã®ã‚ªãƒ–ジェクト(一覧ã«ã¤ã„ã¦ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„)" -#: catalog/pg_shdepend.c:1001 +#: catalog/pg_shdepend.c:998 #, c-format msgid "role %u was concurrently dropped" -msgstr "ロール%uã®å‰Šé™¤ãŒåŒæ™‚ã«èµ·ãã¾ã—ãŸ" +msgstr "ロール%uã®å‰Šé™¤ãŒåŒæ™‚ã«è¡Œã‚れã¾ã—ãŸ" -#: catalog/pg_shdepend.c:1020 +#: catalog/pg_shdepend.c:1017 #, c-format msgid "tablespace %u was concurrently dropped" -msgstr "テーブル空間%uãŒåŒæ™‚ã«å‰Šé™¤ã•れã¾ã—ãŸ" +msgstr "テーブル空間%uã®å‰Šé™¤ãŒåŒæ™‚ã«è¡Œã‚れã¾ã—ãŸ" -#: catalog/pg_shdepend.c:1035 +#: catalog/pg_shdepend.c:1032 #, c-format msgid "database %u was concurrently dropped" -msgstr "データベース %u ãŒåŒæ™‚ã«å‰Šé™¤ã•れã¾ã—ãŸ" +msgstr "データベース%uã®å‰Šé™¤ãŒåŒæ™‚ã«è¡Œã‚れã¾ã—ãŸ" -#: catalog/pg_shdepend.c:1079 +#: catalog/pg_shdepend.c:1077 #, c-format msgid "owner of %s" msgstr "%sã®æ‰€æœ‰è€…" -#: catalog/pg_shdepend.c:1081 +#: catalog/pg_shdepend.c:1079 #, c-format msgid "privileges for %s" -msgstr "%s ã®æ¨©é™" +msgstr "%sã®æ¨©é™" + +#: catalog/pg_shdepend.c:1081 +#, c-format +msgid "target of %s" +msgstr "%sã®å¯¾è±¡" #. translator: %s will always be "database %s" #: catalog/pg_shdepend.c:1089 @@ -3763,2072 +5040,2570 @@ msgstr[1] "%2$s内ã®%1$d個ã®ã‚ªãƒ–ジェクト" msgid "cannot drop objects owned by %s because they are required by the database system" msgstr "データベースシステムãŒå¿…è¦ã¨ã—ã¦ã„ã‚‹ãŸã‚%sãŒæ‰€æœ‰ã™ã‚‹ã‚ªãƒ–ジェクトを削除ã§ãã¾ã›ã‚“" -#: catalog/pg_shdepend.c:1303 +#: catalog/pg_shdepend.c:1315 #, c-format msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "データベースシステムãŒå¿…è¦ã¨ã—ã¦ã„ã‚‹ãŸã‚%sãŒæ‰€æœ‰ã™ã‚‹ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ‰€æœ‰è€…ã‚’å†å‰²ã‚Šå½“ã¦ã§ãã¾ã›ã‚“" -#: catalog/pg_type.c:243 +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 +#: commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "サブスクリプション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: catalog/pg_type.c:135 catalog/pg_type.c:459 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中ã«pg_typeã®OIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" + +#: catalog/pg_type.c:241 #, c-format msgid "invalid type internal size %d" -msgstr "åž‹ã®å†…部サイズ%dã¯ç„¡åйã§ã™" +msgstr "åž‹ã®å†…部サイズ%dã¯ä¸æ­£ã§ã™" -#: catalog/pg_type.c:259 catalog/pg_type.c:267 catalog/pg_type.c:275 -#: catalog/pg_type.c:284 +#: catalog/pg_type.c:257 catalog/pg_type.c:265 catalog/pg_type.c:273 +#: catalog/pg_type.c:282 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" -msgstr "値渡ã—åž‹ã§ã‚µã‚¤ã‚ºãŒ %2$d ã®å ´åˆã€ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆ \"%1$c\" ã¯ç„¡åйã§ã™" +msgstr "値渡ã—åž‹ã§ã‚µã‚¤ã‚ºãŒ%2$dã®å ´åˆã€ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆ\"%1$c\"ã¯ä¸æ­£ã§ã™" -#: catalog/pg_type.c:291 +#: catalog/pg_type.c:289 #, c-format msgid "internal size %d is invalid for passed-by-value type" -msgstr "値渡ã—åž‹ã®å ´åˆã€å†…部サイズ%dã¯ç„¡åйã§ã™" +msgstr "値渡ã—åž‹ã®å ´åˆã€å†…部サイズ%dã¯ä¸æ­£ã§ã™" -#: catalog/pg_type.c:300 catalog/pg_type.c:306 +#: catalog/pg_type.c:298 catalog/pg_type.c:304 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" -msgstr "å¯å¤‰é•·åž‹ã®å ´åˆã€ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆ \"%c\" ã¯ç„¡åйã§ã™" +msgstr "å¯å¤‰é•·åž‹ã®å ´åˆã€ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆ\"%c\"ã¯ä¸æ­£ã§ã™" -#: catalog/pg_type.c:314 +#: catalog/pg_type.c:312 #, c-format msgid "fixed-size types must have storage PLAIN" -msgstr "固定長型ã®å ´åˆã¯ PLAIN æ ¼ç´æ–¹å¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "固定長型ã®å ´åˆã¯PLAINæ ¼ç´æ–¹å¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: catalog/pg_type.c:772 +#: catalog/pg_type.c:801 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "\"%s\"åž‹å‘ã‘ã®é…列型ã®åå‰ã‚’å½¢æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: catalog/toasting.c:91 commands/indexcmds.c:375 commands/tablecmds.c:4040 -#: commands/tablecmds.c:10611 +#: catalog/toasting.c:105 commands/indexcmds.c:443 commands/tablecmds.c:4997 +#: commands/tablecmds.c:13487 #, c-format -#| msgid "\"%s\" is not a table or view" msgid "\"%s\" is not a table or materialized view" -msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルやマテリアライズドビューã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルや実体化ビューã§ã¯ã‚りã¾ã›ã‚“" -#: catalog/toasting.c:142 +#: catalog/toasting.c:158 #, c-format msgid "shared tables cannot be toasted after initdb" msgstr "initdbã®å¾Œã§å…±æœ‰ãƒ†ãƒ¼ãƒ–ルをTOAST化ã§ãã¾ã›ã‚“" -#: commands/aggregatecmds.c:106 +#: commands/aggregatecmds.c:166 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "é †åºé›†åˆé›†ç´„ã®ã¿ãŒä»®æƒ³é›†ç´„ã«ãªã‚Šå¾—ã¾ã™" + +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" -msgstr "集約ã®å±žæ€§\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "集約ã®å±žæ€§\"%sã¯èªè­˜ã§ãã¾ã›ã‚“" -#: commands/aggregatecmds.c:116 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" -msgstr "集約ã®stypeを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "集約ã®stypeを指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/aggregatecmds.c:120 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" -msgstr "集約用ã®çŠ¶æ…‹é·ç§»é–¢æ•°ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "集約用ã®çŠ¶æ…‹é·ç§»é–¢æ•°ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/aggregatecmds.c:217 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "mstype を指定ã—ãŸå ´åˆã¯é›†ç´„ã® msfunc も設定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/aggregatecmds.c:221 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "mstype を指定ã—ãŸå ´åˆã¯é›†ç´„ã® minvfunc も設定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/aggregatecmds.c:228 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "集約㮠msfunc 㯠mstype を指定ã—ã¦ãªã„å ´åˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/aggregatecmds.c:232 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "集約㮠minvfunc 㯠mstype を指定ã—ã¦ã„ãªã„å ´åˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/aggregatecmds.c:236 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "集約㮠mfinalfunc 㯠mstype を指定ã—ã¦ã„ãªã„å ´åˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/aggregatecmds.c:240 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "集約㮠msspace 㯠mstype を指定ã—ã¦ã„ãªã„å ´åˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/aggregatecmds.c:244 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "集約㮠minitcond 㯠mstype を指定ã—ã¦ã„ãªã„å ´åˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: commands/aggregatecmds.c:137 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" -msgstr "集約ã®å…¥åŠ›åž‹ã‚’æŒ‡å®šã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "集約ã®å…¥åŠ›åž‹ã‚’æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/aggregatecmds.c:162 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "集約ã®å…¥åŠ›åž‹æŒ‡å®šã§åŸºæœ¬åž‹ãŒå†—é•·ã§ã™" -#: commands/aggregatecmds.c:195 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "集約ã®é·ç§»ãƒ‡ãƒ¼ã‚¿ã®åž‹ã‚’%sã«ã§ãã¾ã›ã‚“" -#: commands/alter.c:79 commands/event_trigger.c:194 +#: commands/aggregatecmds.c:356 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "直列化関数ã¯é›†ç´„é·ç§»ãƒ‡ãƒ¼ã‚¿ã®åž‹ãŒ%sã®å ´åˆã«ã ã‘指定å¯èƒ½ã§ã™" + +#: commands/aggregatecmds.c:366 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "直列化関数ã¨å¾©å…ƒé–¢æ•°ã¯ä¸¡æ–¹æŒ‡å®šã™ã‚‹ã‹ã€ä¸¡æ–¹æŒ‡å®šã—ãªã„ã‹ã®ã©ã¡ã‚‰ã‹ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "パラメータ\"parallel\"ã¯SAVEã€RESTRICTEDã¾ãŸã¯UNSAFEã®ã„ãšã‚Œã‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "パラメータ \"%s\" 㯠READ_ONLYã€SHAREABLE ã¾ãŸã¯ READ_WRITE ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format -#| msgid "server \"%s\" already exists" msgid "event trigger \"%s\" already exists" -msgstr "イベントトリガ \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgstr "イベントトリガ\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/alter.c:82 commands/foreigncmds.c:541 +#: commands/alter.c:87 commands/foreigncmds.c:595 #, c-format msgid "foreign-data wrapper \"%s\" already exists" -msgstr "外部データラッパー \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgstr "外部データラッパー\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/alter.c:85 commands/foreigncmds.c:834 +#: commands/alter.c:90 commands/foreigncmds.c:898 #, c-format msgid "server \"%s\" already exists" -msgstr "サーãƒãƒ¼ \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgstr "サーãƒãƒ¼\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/alter.c:88 commands/proclang.c:356 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "言語\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/alter.c:111 +#: commands/alter.c:96 commands/publicationcmds.c:176 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "パブリケーション\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/alter.c:99 commands/subscriptioncmds.c:358 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "サブスクリプション\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/alter.c:122 #, c-format msgid "conversion \"%s\" already exists in schema \"%s\"" msgstr "変æ›\"%s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/alter.c:115 +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "統計情報オブジェクト\"%s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/alter.c:130 #, c-format -#| msgid "text search parser \"%s\" already exists" msgid "text search parser \"%s\" already exists in schema \"%s\"" msgstr "テキスト検索パーサ\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"存在ã—ã¾ã™" -#: commands/alter.c:119 +#: commands/alter.c:134 #, c-format -#| msgid "text search dictionary \"%s\" already exists" msgid "text search dictionary \"%s\" already exists in schema \"%s\"" msgstr "テキスト検索辞書\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"存在ã—ã¾ã™" -#: commands/alter.c:123 +#: commands/alter.c:138 #, c-format -#| msgid "text search template \"%s\" already exists" msgid "text search template \"%s\" already exists in schema \"%s\"" msgstr "テキスト検索テンプレート\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"存在ã—ã¾ã™" -#: commands/alter.c:127 +#: commands/alter.c:142 #, c-format -#| msgid "text search configuration \"%s\" already exists" msgid "text search configuration \"%s\" already exists in schema \"%s\"" msgstr "テキスト検索設定\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"存在ã—ã¾ã™" -#: commands/alter.c:201 +#: commands/alter.c:216 #, c-format -#| msgid "must be superuser to examine \"%s\"" msgid "must be superuser to rename %s" -msgstr "%sã®åå‰ã‚’変更ã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "%sã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/alter.c:585 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" -msgstr "%sã®ã‚¹ã‚­ãƒ¼ãƒžã‚’設定ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "%sã®ã‚¹ã‚­ãƒ¼ãƒžã‚’設定ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/amcmds.c:58 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "アクセスメソッド\"%s\"を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" + +#: commands/amcmds.c:60 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "アクセスメソッドを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/amcmds.c:68 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "アクセスメソッド\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/amcmds.c:123 +#, c-format +msgid "must be superuser to drop access methods" +msgstr "アクセスメソッドを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/amcmds.c:174 commands/indexcmds.c:173 commands/indexcmds.c:583 +#: commands/opclasscmds.c:364 commands/opclasscmds.c:778 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "アクセスメソッド\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/amcmds.c:250 +#, c-format +msgid "handler function is not specified" +msgstr "ãƒãƒ³ãƒ‰ãƒ©é–¢æ•°ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" -#: commands/analyze.c:155 +#: commands/amcmds.c:262 commands/event_trigger.c:245 +#: commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 +#: commands/trigger.c:696 parser/parse_clause.c:990 +#, c-format +msgid "function %s must return type %s" +msgstr "関数%sã¯åž‹%sã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" -msgstr "\"%s\"ã®è§£æžã‚’スキップã—ã¦ã„ã¾ã™ --- ロックを利用ã§ãã¾ã›ã‚“" +msgstr "\"%s\"ã®ANALYZEをスキップã—ã¦ã„ã¾ã™ --- ロックç²å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "\"%s\"ã®ANALYZEをスキップã—ã¦ã„ã¾ã™ --- リレーションã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/analyze.c:172 +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã®ã¿ãŒè§£æžã§ãã¾ã™" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã®ã¿ãŒANALYZEを実行ã§ãã¾ã™" -#: commands/analyze.c:176 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒè§£æžã§ãã¾ã™" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒANALYZEを実行ã§ãã¾ã™" -#: commands/analyze.c:180 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- テーブルã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒè§£æžã§ãã¾ã™" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- テーブルã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒANALYZEを実行ã§ãã¾ã™" -#: commands/analyze.c:240 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- ã“ã®å¤–部テーブルを解æžã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- ã“ã®å¤–部テーブルã«å¯¾ã—ã¦ANALYZEを実行ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/analyze.c:251 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- テーブルã§ãªã„ã‚‚ã®ã‚„特殊ãªã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ルを解æžã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- テーブルã§ãªã„ã‚‚ã®ã‚„特別ãªã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ルã«å¯¾ã—ã¦ANALYZEを実行ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/analyze.c:328 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "\"%s.%s\"継承ツリーを解æžã—ã¦ã„ã¾ã™" -#: commands/analyze.c:333 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "\"%s.%s\"ã‚’è§£æžã—ã¦ã„ã¾ã™" -#: commands/analyze.c:651 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ãŒ2回以上ç¾ã‚Œã¾ã™" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" -msgstr "テーブル\"%s.%s.%sã®è‡ªå‹•è§£æžã€‚システム使用状æ³: %s\"" +msgstr "テーブル\"%s.%s.%s\"ã®è‡ªå‹•ANALYZE システム使用状æ³: %s\"" -#: commands/analyze.c:1294 +#: commands/analyze.c:1273 #, c-format msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" -msgstr "\"%1$s\": %3$uページã®å†…%2$dをスキャン。%4$.0fã®æœ‰åйãªè¡Œã¨%5$.0fã®ä¸è¦ãªè¡Œã‚’嫿œ‰ã€‚%6$d行をサンプリング。推定ç·è¡Œæ•°ã¯%7$.0f" +msgstr "\"%1$s\": %3$uページã®å†…%2$dをスキャン。%4$.0fã®æœ‰åйãªè¡Œã¨%5$.0fã®ä¸è¦ãªè¡ŒãŒå­˜åœ¨ã€‚%6$d行をサンプリング。推定ç·è¡Œæ•°ã¯%7$.0f" -#: commands/analyze.c:1558 executor/execQual.c:2848 -msgid "could not convert row type" -msgstr "行ã®åž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" +#: commands/analyze.c:1353 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "継承ツリー\"%s.%s\"ã®ANALYZEをスキップã—ã¾ã™ --- ã“ã®ãƒ„リーã«ã¯å­ãƒ†ãƒ¼ãƒ–ルãŒã‚りã¾ã›ã‚“" -#: commands/async.c:546 +#: commands/analyze.c:1451 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "継承ツリー\"%s.%s\"ã®ANALYZEをスキップã—ã¾ã™ --- ã“ã®ãƒ„リーã«ã¯ã‚¢ãƒŠãƒ©ã‚¤ã‚ºå¯èƒ½ãªå­ãƒ†ãƒ¼ãƒ–ルãŒã‚りã¾ã›ã‚“" + +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "ãƒãƒ£ãƒãƒ«åãŒç©ºã§ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/async.c:551 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "ãƒãƒ£ãƒãƒ«åãŒé•·ã™ãŽã¾ã™" -#: commands/async.c:558 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "ペイロード文字列ãŒé•·ã™ãŽã¾ã™" -#: commands/async.c:743 +#: commands/async.c:756 #, c-format msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" -msgstr "ã™ã§ã« LISTEN / UNLISTEN / NOTIFY を実行ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ PREPARE ã§ãã¾ã›ã‚“" +msgstr "LISTEN / UNLISTEN / NOTIFY を実行ã—ã¦ã„るトランザクション㯠PREPARE ã§ãã¾ã›ã‚“" -#: commands/async.c:846 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "NOTIFY キューã§ç™ºç”Ÿã—ãŸé€šçŸ¥ã‚¤ãƒ™ãƒ³ãƒˆãŒå¤šã™ãŽã¾ã™" -#: commands/async.c:1419 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTYFY キュー㌠%.0f%% ã¾ã§ä¸€æ¯ã«ãªã£ã¦ã„ã¾ã™" -#: commands/async.c:1421 +#: commands/async.c:1493 #, c-format msgid "The server process with PID %d is among those with the oldest transactions." -msgstr "PID %d ã®ã‚µãƒ¼ãƒãƒ—ロセスã¯ã€æœ€ã‚‚å¤ã„トランザクション中ã«ã‚りã¾ã™ã€‚" +msgstr "PID %d ã®ã‚µãƒ¼ãƒãƒ—ロセスã¯ã€ã“ã®ä¸­ã§æœ€ã‚‚å¤ã„トランザクションを実行中ã§ã™ã€‚" -#: commands/async.c:1424 +#: commands/async.c:1496 #, c-format msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." -msgstr "プロセスãŒç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã™ã‚‹ã¾ã§ NOTYFY キューを空ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "ã“ã®ãƒ—ロセスãŒç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã™ã‚‹ã¾ã§ NOTYFY キューを空ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/cluster.c:128 commands/cluster.c:366 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルをクラスタ化ã§ãã¾ã›ã‚“" -#: commands/cluster.c:158 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "パーティションテーブルã«å¯¾ã—㦠CLUSTER ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "テーブル\"%s\"ã«ã¯äº‹å‰ã«ã‚¯ãƒ©ã‚¹ã‚¿åŒ–ã•れãŸã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯ã‚りã¾ã›ã‚“" -#: commands/cluster.c:172 commands/tablecmds.c:8659 +#: commands/cluster.c:181 commands/tablecmds.c:10644 commands/tablecmds.c:12549 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/cluster.c:355 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "共有カタログをクラスタ化ã§ãã¾ã›ã‚“" -#: commands/cluster.c:370 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" -msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルã¯ãƒã‚­ãƒ¥ãƒ¼ãƒ ã§ãã¾ã›ã‚“" +msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルã«å¯¾ã—ã¦ã¯VACUUMを実行ã§ãã¾ã›ã‚“" -#: commands/cluster.c:434 +#: commands/cluster.c:439 commands/tablecmds.c:12559 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/cluster.c:442 +#: commands/cluster.c:447 #, c-format msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "インデックス\"%s\"ã§ã‚¯ãƒ©ã‚¹ã‚¿åŒ–ã§ãã¾ã›ã‚“。アクセスメソッドãŒã‚¯ãƒ©ã‚¹ã‚¿åŒ–をサãƒãƒ¼ãƒˆã—ãªã„ãŸã‚ã§ã™" -#: commands/cluster.c:454 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "部分インデックス\"%s\"をクラスタ化ã§ãã¾ã›ã‚“" -#: commands/cluster.c:468 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" -msgstr "無効ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"をクラスタ化ã§ãã¾ã›ã‚“" +msgstr "無効ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã§ã¯ã‚¯ãƒ©ã‚¹ã‚¿åŒ–ã§ãã¾ã›ã‚“" + +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "パーティションテーブル内ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯ CLUSTER 済ã¿ã¨ãƒžãƒ¼ã‚¯ã§ãã¾ã›ã‚“`" -#: commands/cluster.c:920 +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr " \"%3$s\" ã«å¯¾ã™ã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ã‚’使ã£ã¦ \"%1$s.%2$s\" をクラスタ化ã—ã¦ã„ã¾ã™" -#: commands/cluster.c:926 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "シーケンシャルスキャンã¨ã‚½ãƒ¼ãƒˆã‚’使ã£ã¦ \"%s.%s\" をクラスタ化ã—ã¦ã„ã¾ã™" -#: commands/cluster.c:931 commands/vacuumlazy.c:411 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" -msgstr "\"%s.%s\"ã‚’ãƒã‚­ãƒ¥ãƒ¼ãƒ ã—ã¦ã„ã¾ã™" +msgstr "\"%s.%s\"ã«å¯¾ã—ã¦VACUUMを実行ã—ã¦ã„ã¾ã™" -#: commands/cluster.c:1090 +#: commands/cluster.c:1106 #, c-format msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" -msgstr "\"%1$s\": å…¨ %4$u ページ中ã«è¦‹ã¤ã‹ã£ãŸè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼šç§»å‹•å¯èƒ½ %2$.0f 行ã€å‰Šé™¤ä¸å¯ %3$.0f 行" +msgstr "\"%1$s\": å…¨ %4$u ページ中ã«è¦‹ã¤ã‹ã£ãŸè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³: 移動å¯èƒ½ %2$.0f 行ã€å‰Šé™¤ä¸å¯ %3$.0f 行" -#: commands/cluster.c:1094 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" "%s." msgstr "" -"%.0f 個ã®ç„¡åйãªè¡Œã‚’今ã¯ã¾ã å‰Šé™¤ã§ãã¾ã›ã‚“。\n" +"%.0f 個ã®ç„¡åйãªè¡ŒãŒä»Šã¯ã¾ã å‰Šé™¤ã§ãã¾ã›ã‚“。\n" "%s." -#: commands/collationcmds.c:79 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "ç…§åˆé †åºã®å±žæ€§ \"%s\" ãŒèªè­˜ã§ãã¾ã›ã‚“" -#: commands/collationcmds.c:124 +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "ç…§åˆé †åº\"default\"ã¯è¤‡è£½ã§ãã¾ã›ã‚“" + +#: commands/collationcmds.c:172 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "èªè­˜ã§ããªã„ã®ç…§åˆé †åºãƒ—ロãƒã‚¤ãƒ€: %s" + +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" -msgstr "\"lc_collate\"パラメータを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "\"lc_collate\"ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: commands/collationcmds.c:129 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" -msgstr "\"lc_ctype\" パラメータを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "\"lc_ctype\" ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: commands/collationcmds.c:163 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "エンコーディング \"%2$s\" ã®ãŸã‚ã®ç…§åˆé †åº \"%1$s\" ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž \"%3$s\" 内ã«å­˜åœ¨ã—ã¾ã™" -#: commands/collationcmds.c:174 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "ç…§åˆé †åº \"%s\" ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž \"%s\" 内ã«å­˜åœ¨ã—ã¾ã™" -#: commands/comment.c:62 commands/dbcommands.c:770 commands/dbcommands.c:919 -#: commands/dbcommands.c:1022 commands/dbcommands.c:1195 -#: commands/dbcommands.c:1384 commands/dbcommands.c:1479 -#: commands/dbcommands.c:1896 utils/init/postinit.c:770 -#: utils/init/postinit.c:838 utils/init/postinit.c:855 +#: commands/collationcmds.c:304 #, c-format -msgid "database \"%s\" does not exist" -msgstr "データベース\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "changing version from %s to %s" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã‹ã‚‰%sã¸ã®å¤‰æ›´" -#: commands/comment.c:101 commands/seclabel.c:114 parser/parse_utilcmd.c:686 +#: commands/collationcmds.c:319 #, c-format -#| msgid "\"%s\" is not a table, view, composite type, or foreign table" -msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" -msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€è¤‡åˆåž‹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" +msgid "version has not changed" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå¤‰ã‚ã£ã¦ã„ã¾ã›ã‚“" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2699 +#: commands/collationcmds.c:450 #, c-format -msgid "function \"%s\" was not called by trigger manager" -msgstr "関数\"%s\"ã¯ãƒˆãƒªã‚¬é–¢æ•°ã¨ã—ã¦å‘¼ã³å‡ºã•れã¦ã„ã¾ã›ã‚“" +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "ロケールå\"%s\"ã‚’ã€è¨€èªžã‚¿ã‚°ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2708 +#: commands/collationcmds.c:511 #, c-format -msgid "function \"%s\" must be fired AFTER ROW" -msgstr "関数\"%s\"ã‚’AFTER ROWã§ç™ºè¡Œã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be superuser to import system collations" +msgstr "システム照åˆé †åºã‚’インãƒãƒ¼ãƒˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/constraint.c:81 +#: commands/collationcmds.c:534 commands/copy.c:1844 commands/copy.c:3174 +#: libpq/be-secure-common.c:80 #, c-format -msgid "function \"%s\" must be fired for INSERT or UPDATE" -msgstr "関数\"%s\"ã‚’INSERTã¾ãŸã¯UPDATEã§ç™ºè¡Œã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "could not execute command \"%s\": %m" +msgstr "コマンド\"%s\"を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/conversioncmds.c:67 +#: commands/collationcmds.c:665 #, c-format -msgid "source encoding \"%s\" does not exist" -msgstr "変æ›å…ƒç¬¦å·åŒ–æ–¹å¼\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "no usable system locales were found" +msgstr "使用ã§ãるシステムロケールãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: commands/conversioncmds.c:74 +#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 +#: commands/dbcommands.c:1100 commands/dbcommands.c:1290 +#: commands/dbcommands.c:1513 commands/dbcommands.c:1627 +#: commands/dbcommands.c:2043 utils/init/postinit.c:853 +#: utils/init/postinit.c:958 utils/init/postinit.c:975 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "データベース\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€å®Ÿä½“化ビューã€è¤‡åˆåž‹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" + +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "関数\"%s\"ã¯ãƒˆãƒªã‚¬é–¢æ•°ã¨ã—ã¦å‘¼ã³å‡ºã•れã¦ã„ã¾ã›ã‚“" + +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "関数\"%s\"ã¯AFTER ROWトリガã§å®Ÿè¡Œã—ã¦ãã ã•ã„" + +#: commands/constraint.c:81 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "関数\"%s\"ã¯INSERTã¾ãŸã¯UPDATEトリガã§å®Ÿè¡Œã—ã¦ãã ã•ã„" + +#: commands/conversioncmds.c:65 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "変æ›å…ƒç¬¦å·åŒ–æ–¹å¼\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "変æ›å…ˆç¬¦å·åŒ–æ–¹å¼\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/conversioncmds.c:88 +#: commands/conversioncmds.c:86 #, c-format -msgid "encoding conversion function %s must return type \"void\"" -msgstr "エンコード変æ›é–¢æ•° %s 㯠\"void\" 型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "encoding conversion function %s must return type %s" +msgstr "エンコード変æ›é–¢æ•°%sã¯%s型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/copy.c:358 commands/copy.c:370 commands/copy.c:404 -#: commands/copy.c:414 +#: commands/copy.c:374 commands/copy.c:408 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "標準入出力を介ã—ãŸCOPY BINARYã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/copy.c:512 +#: commands/copy.c:508 #, c-format -#| msgid "could not write to COPY file: %m" msgid "could not write to COPY program: %m" msgstr "COPYãƒ—ãƒ­ã‚°ãƒ©ãƒ ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/copy.c:517 +#: commands/copy.c:513 #, c-format msgid "could not write to COPY file: %m" msgstr "COPYãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/copy.c:530 +#: commands/copy.c:526 #, c-format msgid "connection lost during COPY to stdout" msgstr "標準出力ã¸ã®COPYä¸­ã«æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸ" -#: commands/copy.c:571 +#: commands/copy.c:570 #, c-format msgid "could not read from COPY file: %m" msgstr "COPYファイルã‹ã‚‰èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/copy.c:587 commands/copy.c:606 commands/copy.c:610 -#: tcop/fastpath.c:293 tcop/postgres.c:352 tcop/postgres.c:388 +#: commands/copy.c:588 commands/copy.c:609 commands/copy.c:613 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" -msgstr "オープン中ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’æŒã¤ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæŽ¥ç¶šã«æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã—ãŸ" +msgstr "トランザクションを実行中ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæŽ¥ç¶šã§æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:622 +#: commands/copy.c:626 #, c-format msgid "COPY from stdin failed: %s" msgstr "標準入力ã‹ã‚‰ã®COPYãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: commands/copy.c:638 +#: commands/copy.c:642 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" -msgstr "標準入力ã‹ã‚‰ã®COPYä¸­ã«æƒ³å®šå¤–ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡ž0x%02XãŒã‚りã¾ã—ãŸ" +msgstr "標準入力ã‹ã‚‰ã®COPYä¸­ã«æƒ³å®šå¤–ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—0x%02XãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:792 +#: commands/copy.c:808 #, c-format -#| msgid "must be superuser to COPY to or from a file" -msgid "must be superuser to COPY to or from an external program" -msgstr "外部プログラムを入力ã¾ãŸã¯å‡ºåŠ›ã¨ã—ãŸCOPを行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "外部プログラムを入出力対象ã¨ã—ãŸCOPYを行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯ pg_execute_server_program ロールã®ãƒ¡ãƒ³ãƒã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/copy.c:793 commands/copy.c:799 +#: commands/copy.c:809 commands/copy.c:818 commands/copy.c:825 #, c-format msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "標準入出力経由ã®COPYã¯èª°ã§ã‚‚実行å¯èƒ½ã§ã™ã€‚ã¾ãŸpsqlã®\\\\copyも誰ã§ã‚‚実行ã§ãã¾ã™" -#: commands/copy.c:798 +#: commands/copy.c:817 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "ファイルã‹ã‚‰ã® COPY を行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯ pg_read_server_files ロールã®ãƒ¡ãƒ³ãƒã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/copy.c:824 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "ファイル経由ã®COPY FROMã€COPY TOを行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "ファイルã¸ã® COPY を行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯ pg_write_server_files ロールã®ãƒ¡ãƒ³ãƒã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/copy.c:934 +#: commands/copy.c:887 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM ã§è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/copy.c:888 +#, c-format +msgid "Use INSERT statements instead." +msgstr "代ã‚りã«INSERTを文使用ã—ã¦ãã ã•ã„。" + +#: commands/copy.c:1075 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "COPY フォーマット \"%s\" ã‚’èªè­˜ã§ãã¾ã›ã‚“" -#: commands/copy.c:1005 commands/copy.c:1019 commands/copy.c:1039 +#: commands/copy.c:1155 commands/copy.c:1171 commands/copy.c:1186 +#: commands/copy.c:1208 #, c-format msgid "argument to option \"%s\" must be a list of column names" -msgstr "オプション \"%s\" ã®å¼•æ•°ã¯åˆ—åã®ä¸¦ã³ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "オプション \"%s\" ã®å¼•æ•°ã¯åˆ—åã®ãƒªã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1052 +#: commands/copy.c:1223 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "オプション \"%s\" ã®å¼•æ•°ã¯æœ‰åйãªã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°åã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1058 +#: commands/copy.c:1230 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" -msgstr "時間帯 \"%s\" ã‚’èªè­˜ã§ãã¾ã›ã‚“" +msgstr "タイムゾーン\"%s\"ã‚’èªè­˜ã§ãã¾ã›ã‚“" -#: commands/copy.c:1069 +#: commands/copy.c:1242 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "BINARYモードã§ã¯DELIMITERを指定ã§ãã¾ã›ã‚“" -#: commands/copy.c:1074 +#: commands/copy.c:1247 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "BINARYモードã§ã¯NULLを指定ã§ãã¾ã›ã‚“" -#: commands/copy.c:1096 +#: commands/copy.c:1269 #, c-format msgid "COPY delimiter must be a single one-byte character" -msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã¯å˜ä¸€ã®ï¼‘ãƒã‚¤ãƒˆæ–‡å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã¯å˜ä¸€ã®1ãƒã‚¤ãƒˆæ–‡å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1103 +#: commands/copy.c:1276 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã¯æ”¹è¡Œã‚„復帰記å·ã¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/copy.c:1109 +#: commands/copy.c:1282 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "COPYã®NULL表ç¾ã«ã¯æ”¹è¡Œã‚„復帰記å·ã‚’使用ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1126 +#: commands/copy.c:1299 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã‚’\"%s\"ã¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1132 +#: commands/copy.c:1305 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "COPY HEADERã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1138 +#: commands/copy.c:1311 #, c-format msgid "COPY quote available only in CSV mode" msgstr "COPYã®å¼•用符ã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1143 +#: commands/copy.c:1316 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "COPYã®å¼•用符ã¯å˜ä¸€ã®1ãƒã‚¤ãƒˆæ–‡å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1148 +#: commands/copy.c:1321 #, c-format msgid "COPY delimiter and quote must be different" msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã¨å¼•用符ã¯ç•°ãªã‚‹æ–‡å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1154 +#: commands/copy.c:1327 #, c-format msgid "COPY escape available only in CSV mode" msgstr "COPYã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1159 +#: commands/copy.c:1332 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "COPYã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã¯å˜ä¸€ã®1ãƒã‚¤ãƒˆæ–‡å­—ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/copy.c:1165 +#: commands/copy.c:1338 #, c-format msgid "COPY force quote available only in CSV mode" -msgstr "COPYã® force quoteå¥ã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" +msgstr "COPYã®FORCE_QUOTEオプションã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1169 +#: commands/copy.c:1342 #, c-format msgid "COPY force quote only available using COPY TO" -msgstr "COPYã® force quoteå¥ã¯COPY TOã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" +msgstr "COPYã®FORCE_QUOTEオプションã¯COPY TOã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1175 +#: commands/copy.c:1348 #, c-format msgid "COPY force not null available only in CSV mode" -msgstr "COPYã® force not nullå¥ã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" +msgstr "COPYã®FORCE_NOT_NULLオプションã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1179 +#: commands/copy.c:1352 #, c-format msgid "COPY force not null only available using COPY FROM" -msgstr "COPYã® force not nullå¥ã¯COPY FROMã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" +msgstr "COPYã®FORCE_NOT_NULLオプションã¯COPY FROMã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" + +#: commands/copy.c:1358 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "COPYã®FORCE_NULLオプションã¯CSVモードã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" + +#: commands/copy.c:1363 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "COPYã®FORCE_NOT_NULLオプションã¯COPY FROMã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/copy.c:1185 +#: commands/copy.c:1369 #, c-format msgid "COPY delimiter must not appear in the NULL specification" -msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã‚’NULLå¥ã®å€¤ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgstr "COPYã®åŒºåˆ‡ã‚Šæ–‡å­—ã‚’NULLオプションã®å€¤ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/copy.c:1192 +#: commands/copy.c:1376 #, c-format msgid "CSV quote character must not appear in the NULL specification" -msgstr "COPYã®å¼•用符をNULLå¥ã®å€¤ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgstr "COPYã®å¼•用符をNULLオプションã®å€¤ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/copy.c:1254 +#: commands/copy.c:1437 #, c-format msgid "table \"%s\" does not have OIDs" msgstr "テーブル\"%s\"ã¯OIDã‚’æŒã¡ã¾ã›ã‚“" -#: commands/copy.c:1271 +#: commands/copy.c:1454 #, c-format -msgid "COPY (SELECT) WITH OIDS is not supported" -msgstr "COPY (SELECT) WITH OIDSã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgid "COPY (query) WITH OIDS is not supported" +msgstr "COPY (query) WITH OIDSã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/copy.c:1297 +#: commands/copy.c:1475 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "DO INSTEAD NOTHING ルール㯠COPY ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/copy.c:1489 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "æ¡ä»¶ä»˜ã DO INSTEAD ルール㯠COPY ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/copy.c:1493 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "DO ALSO ルール㯠COPY ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/copy.c:1498 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "マルãƒã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã® DO INSTEAD ルール㯠COPY ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/copy.c:1508 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO)ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/copy.c:1360 +#: commands/copy.c:1525 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "COPY文中ã®å•ã„åˆã‚ã›ã§ã¯RETURNINGå¥ãŒå¿…é ˆã§ã™" + +#: commands/copy.c:1553 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "COPYæ–‡ã§å‚ç…§ã•れã¦ã„るリレーションãŒå¤‰æ›´ã•れã¾ã—ãŸ" + +#: commands/copy.c:1612 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "FORCE_QUOTE指定ã•れãŸåˆ—\"%s\"ã¯COPYã§å‚ç…§ã•れã¾ã›ã‚“" + +#: commands/copy.c:1635 #, c-format -msgid "FORCE QUOTE column \"%s\" not referenced by COPY" -msgstr "FORCE QUOTEã•れãŸåˆ—\"%s\"ã¯COPYã§å‚ç…§ã•れã¾ã›ã‚“" +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NOT_NULL指定ã•れãŸåˆ—\"%s\"ã¯COPYã§å‚ç…§ã•れã¾ã›ã‚“" -#: commands/copy.c:1382 +#: commands/copy.c:1658 #, c-format -msgid "FORCE NOT NULL column \"%s\" not referenced by COPY" -msgstr "FORCE NOT NULLã•れãŸåˆ—\"%s\"ã¯COPYã§å‚ç…§ã•れã¾ã›ã‚“" +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NULL指定ã•れãŸåˆ—\"%s\"ã¯COPYã§å‚ç…§ã•れã¾ã›ã‚“" -#: commands/copy.c:1446 +#: commands/copy.c:1724 libpq/be-secure-common.c:102 #, c-format -#| msgid "could not close pipe to external command: %s\n" msgid "could not close pipe to external command: %m" msgstr "外部コマンドã«å¯¾ã™ã‚‹ãƒ‘イプをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/copy.c:1449 +#: commands/copy.c:1739 #, c-format msgid "program \"%s\" failed" -msgstr "プログラム\"%s\"ãŒå¤±æ•—ã—ã¾ã—ãŸ" +msgstr "プログラム\"%s\"ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ" -#: commands/copy.c:1498 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from view \"%s\"" msgstr "ビュー\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1500 commands/copy.c:1506 commands/copy.c:1512 +#: commands/copy.c:1792 commands/copy.c:1798 commands/copy.c:1804 +#: commands/copy.c:1815 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "COPY (SELECT ...) TO構文を試ã—ã¦ãã ã•ã„" -#: commands/copy.c:1504 +#: commands/copy.c:1796 #, c-format -#| msgid "cannot copy from view \"%s\"" msgid "cannot copy from materialized view \"%s\"" -msgstr "マテリアライズドビュー\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" +msgstr "実体化ビュー\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1510 +#: commands/copy.c:1802 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "外部テーブル \"%s\" ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1516 +#: commands/copy.c:1808 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "シーケンス\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1521 +#: commands/copy.c:1813 #, c-format -msgid "cannot copy from non-table relation \"%s\"" -msgstr "テーブル以外ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" +msgid "cannot copy from partitioned table \"%s\"" +msgstr "パーティションテーブル \"%s\" ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1544 commands/copy.c:2545 +#: commands/copy.c:1819 #, c-format -#| msgid "could not execute command \"%s\": %s\n" -msgid "could not execute command \"%s\": %m" -msgstr "コマンド\"%s\"を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "cannot copy from non-table relation \"%s\"" +msgstr "テーブル以外ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã‹ã‚‰ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:1559 +#: commands/copy.c:1859 #, c-format msgid "relative path not allowed for COPY to file" -msgstr "ファイルã¸ã®COPYã§ã¯ç›¸å¯¾ãƒ‘ã‚¹ã§æŒ‡å®šã§ãã¾ã›ã‚“" +msgstr "ファイルã¸ã®COPYã§ã¯ç›¸å¯¾ãƒ‘ã‚¹ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: commands/copy.c:1567 +#: commands/copy.c:1880 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "ファイル\"%s\"を書ãè¾¼ã¿ç”¨ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/copy.c:1574 commands/copy.c:2563 +#: commands/copy.c:1883 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TOã«ã‚ˆã£ã¦PostgreSQLサーãƒãƒ—ロセスã¯ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚’行ã„ã¾ã™ã€‚psqlã® \\copy ã®ã‚ˆã†ãªã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆå´ã®ä»•組ã¿ãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" + +#: commands/copy.c:1896 commands/copy.c:3205 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\"ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã™" -#: commands/copy.c:1899 +#: commands/copy.c:2222 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "%sã®COPYã€‚è¡Œç•ªå· %d。列 %s" +msgid "COPY %s, line %s, column %s" +msgstr "%sã®COPYã€è¡Œ %sã€åˆ— %s" -#: commands/copy.c:1903 commands/copy.c:1950 +#: commands/copy.c:2226 commands/copy.c:2273 #, c-format -msgid "COPY %s, line %d" -msgstr "%sã®COPYã€‚è¡Œç•ªå· %d" +msgid "COPY %s, line %s" +msgstr "%sã®COPYã€è¡Œ %s" -#: commands/copy.c:1914 +#: commands/copy.c:2237 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "%sã®COPYã€‚è¡Œç•ªå· %d。列 %s: \"%s\"" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "%sã®COPYã€è¡Œ %sã€åˆ— %s: \"%s\"" -#: commands/copy.c:1922 +#: commands/copy.c:2245 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "%sã®COPYã€‚è¡Œç•ªå· %d。列 %s: 入力ãŒãƒŒãƒ«ã§ã™" +msgid "COPY %s, line %s, column %s: null input" +msgstr "%sã®COPYã€è¡Œ %sã€åˆ— %s: null ãŒå…¥åŠ›ã•れã¾ã—ãŸ" -#: commands/copy.c:1944 +#: commands/copy.c:2267 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "%sã®COPYã€‚è¡Œç•ªå· %d: \"%s\"" +msgid "COPY %s, line %s: \"%s\"" +msgstr "%sã®COPYã€è¡Œ %s: \"%s\"" -#: commands/copy.c:2028 +#: commands/copy.c:2363 #, c-format msgid "cannot copy to view \"%s\"" msgstr "ビュー\"%s\"ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:2033 +#: commands/copy.c:2365 #, c-format -#| msgid "cannot copy to view \"%s\"" -msgid "cannot copy to materialized view \"%s\"" -msgstr "マテリアライズドビュー\"%s\"ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "ビューã¸ã®ã‚³ãƒ”ーをå¯èƒ½ã«ã™ã‚‹ãŸã‚ã«ã¯ã€INSTEAD OF INSERTトリガを作æˆã—ã¦ãã ã•ã„。" -#: commands/copy.c:2038 +#: commands/copy.c:2369 #, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "外部テーブル \"%s\" ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" +msgid "cannot copy to materialized view \"%s\"" +msgstr "実体化ビュー\"%s\"ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:2043 +#: commands/copy.c:2374 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "シーケンス\"%s\"ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:2048 +#: commands/copy.c:2379 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "テーブル以外ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#: commands/copy.c:2111 +#: commands/copy.c:2464 +#, fuzzy, c-format +#| msgid "cannot cluster a partitioned table" +msgid "cannot perform FREEZE on a partitioned table" +msgstr "パーティションテーブルã«å¯¾ã—㦠CLUSTER ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/copy.c:2479 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" -msgstr "ã“れã¾ã§ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æ´»å‹•ã®ãŸã‚FREEZEを行ã†ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "先行ã™ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æ´»å‹•ã®ãŸã‚FREEZEを実行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/copy.c:2117 +#: commands/copy.c:2485 #, c-format msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" -msgstr "ç¾åœ¨ã®å‰¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã«ãŠã„ã¦ãƒ†ãƒ¼ãƒ–ルãŒä½œæˆã•れã¦ã„ãªã„ã¾ãŸã¯æ¶ˆåŽ»ã•れãŸãŸã‚FREEZEを行ã†ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "ã“ã®ãƒ†ãƒ¼ãƒ–ルã¯ç¾åœ¨ã®ã‚µãƒ–トランザクションã«ãŠã„ã¦ä½œæˆã¾ãŸã¯åˆ‡ã‚Šè©°ã‚ã•れã¦ã„ãªã„ãŸã‚ã€FREEZEを実行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/copy.c:2556 utils/adt/genfile.c:123 +#: commands/copy.c:3192 #, c-format -msgid "could not open file \"%s\" for reading: %m" -msgstr "ファイル\"%s\"を読ã¿å–り用ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROMã«ã‚ˆã£ã¦PostgreSQLサーãƒãƒ—ロセスã¯ãƒ•ァイルを読ã¿è¾¼ã¿ã¾ã™ã€‚psqlã® \\copy ã®ã‚ˆã†ãªã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆå´ã®ä»•組ã¿ãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" -#: commands/copy.c:2583 +#: commands/copy.c:3225 #, c-format msgid "COPY file signature not recognized" msgstr "COPYファイルã®ã‚·ã‚°ãƒãƒãƒ£ãŒä¸æ˜Žã§ã™" -#: commands/copy.c:2588 +#: commands/copy.c:3230 #, c-format msgid "invalid COPY file header (missing flags)" -msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒç„¡åйã§ã™(フラグãŒã‚りã¾ã›ã‚“)" +msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒä¸æ­£ã§ã™(フラグãŒã‚りã¾ã›ã‚“)" -#: commands/copy.c:2594 +#: commands/copy.c:3236 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€å†…ã®é‡è¦ãªãƒ•ラグãŒä¸æ˜Žã§ã™" -#: commands/copy.c:2600 +#: commands/copy.c:3242 #, c-format msgid "invalid COPY file header (missing length)" -msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒç„¡åйã§ã™(サイズãŒã‚りã¾ã›ã‚“)" +msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒä¸æ­£ã§ã™(サイズãŒã‚りã¾ã›ã‚“)" -#: commands/copy.c:2607 +#: commands/copy.c:3249 #, c-format msgid "invalid COPY file header (wrong length)" -msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒç„¡åйã§ã™(サイズãŒä¸æ­£ã§ã™)" +msgstr "COPYファイルã®ãƒ˜ãƒƒãƒ€ãŒä¸æ­£ã§ã™(サイズãŒä¸æ­£ã§ã™)" -#: commands/copy.c:2740 commands/copy.c:3430 commands/copy.c:3660 +#: commands/copy.c:3380 commands/copy.c:4089 commands/copy.c:4319 #, c-format msgid "extra data after last expected column" msgstr "推定最終列ã®å¾Œã«ä½™è¨ˆãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:2750 +#: commands/copy.c:3390 #, c-format msgid "missing data for OID column" msgstr "OID列ã®ãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã›ã‚“" -#: commands/copy.c:2756 +#: commands/copy.c:3396 #, c-format msgid "null OID in COPY data" msgstr "COPYデータã®OIDãŒNULLã§ã—ãŸ" -#: commands/copy.c:2766 commands/copy.c:2872 +#: commands/copy.c:3406 commands/copy.c:3530 #, c-format msgid "invalid OID in COPY data" -msgstr "COPYデータã®OIDãŒç„¡åйã§ã™" +msgstr "COPYデータã®OIDãŒä¸æ­£ã§ã™" -#: commands/copy.c:2781 +#: commands/copy.c:3422 #, c-format msgid "missing data for column \"%s\"" msgstr "列\"%s\"ã®ãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã›ã‚“" -#: commands/copy.c:2847 +#: commands/copy.c:3505 #, c-format msgid "received copy data after EOF marker" msgstr "EOF マーカーã®å¾Œã‚ã§ã‚³ãƒ”ーデータをå—ä¿¡ã—ã¾ã—ãŸ" -#: commands/copy.c:2854 +#: commands/copy.c:3512 #, c-format msgid "row field count is %d, expected %d" msgstr "行ã®ãƒ•ィールド数ã¯%dã€ãã®æœŸå¾…値ã¯%dã§ã™" -#: commands/copy.c:3194 commands/copy.c:3211 +#: commands/copy.c:3853 commands/copy.c:3870 #, c-format msgid "literal carriage return found in data" msgstr "データã®ä¸­ã«å¾©å¸°è¨˜å·ãã®ã‚‚ã®ãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:3195 commands/copy.c:3212 +#: commands/copy.c:3854 commands/copy.c:3871 #, c-format msgid "unquoted carriage return found in data" msgstr "データã®ä¸­ã«å¼•用符ã®ãªã„復帰記å·ãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:3197 commands/copy.c:3214 +#: commands/copy.c:3856 commands/copy.c:3873 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "復帰記å·ã¯\"\\r\"ã¨è¡¨ç¾ã—ã¦ãã ã•ã„" -#: commands/copy.c:3198 commands/copy.c:3215 +#: commands/copy.c:3857 commands/copy.c:3874 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "復帰記å·ã‚’表ç¾ã™ã‚‹ã«ã¯CSVãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’å¼•ç”¨ç¬¦ã§æ‹¬ã£ã¦ãã ã•ã„" -#: commands/copy.c:3227 +#: commands/copy.c:3886 #, c-format msgid "literal newline found in data" msgstr "データã®ä¸­ã«æ”¹è¡Œè¨˜å·ãã®ã‚‚ã®ãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:3228 +#: commands/copy.c:3887 #, c-format msgid "unquoted newline found in data" msgstr "データã®ä¸­ã«å¼•用符ã®ãªã„改行記å·ãŒã‚りã¾ã—ãŸ" -#: commands/copy.c:3230 +#: commands/copy.c:3889 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "改行記å·ã¯\"\\n\"ã¨è¡¨ç¾ã—ã¦ãã ã•ã„" -#: commands/copy.c:3231 +#: commands/copy.c:3890 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "改行記å·ã‚’表ç¾ã™ã‚‹ã«ã¯CSVãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã‚’å¼•ç”¨ç¬¦ã§æ‹¬ã£ã¦ãã ã•ã„" -#: commands/copy.c:3277 commands/copy.c:3313 +#: commands/copy.c:3936 commands/copy.c:3972 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "コピー終端記å·ãŒã“れã¾ã§ã®æ”¹è¡Œæ–¹å¼ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: commands/copy.c:3286 commands/copy.c:3302 +#: commands/copy.c:3945 commands/copy.c:3961 #, c-format msgid "end-of-copy marker corrupt" msgstr "コピー終端記å·ãŒç ´æã—ã¦ã„ã¾ã™" -#: commands/copy.c:3744 +#: commands/copy.c:4403 #, c-format msgid "unterminated CSV quoted field" msgstr "CSV引用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: commands/copy.c:3821 commands/copy.c:3840 +#: commands/copy.c:4480 commands/copy.c:4499 #, c-format msgid "unexpected EOF in COPY data" msgstr "COPYデータã®ä¸­ã«æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã™" -#: commands/copy.c:3830 +#: commands/copy.c:4489 #, c-format msgid "invalid field size" -msgstr "フィールドサイズãŒç„¡åйã§ã™" +msgstr "フィールドサイズãŒä¸æ­£ã§ã™" -#: commands/copy.c:3853 +#: commands/copy.c:4512 #, c-format msgid "incorrect binary data format" msgstr "ãƒã‚¤ãƒŠãƒªãƒ‡ãƒ¼ã‚¿æ›¸å¼ãŒä¸æ­£ã§ã™" -#: commands/copy.c:4164 commands/indexcmds.c:1006 commands/tablecmds.c:1404 -#: commands/tablecmds.c:2213 parser/parse_relation.c:2740 -#: utils/adt/tsvector_op.c:1417 +#: commands/copy.c:4824 commands/indexcmds.c:1473 commands/statscmds.c:206 +#: commands/tablecmds.c:1891 commands/tablecmds.c:2448 +#: commands/tablecmds.c:2829 parser/parse_relation.c:3288 +#: parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" msgstr "列\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/copy.c:4171 commands/tablecmds.c:1430 commands/trigger.c:601 -#: parser/parse_target.c:934 parser/parse_target.c:945 +#: commands/copy.c:4831 commands/tablecmds.c:1918 commands/trigger.c:913 +#: parser/parse_target.c:1046 parser/parse_target.c:1057 #, c-format msgid "column \"%s\" specified more than once" msgstr "列\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: commands/createas.c:352 +#: commands/createas.c:213 commands/createas.c:509 #, c-format -#| msgid "too many column aliases specified for function %s" msgid "too many column names were specified" msgstr "指定ã•れãŸåˆ—別åãŒå¤šã™ãŽã¾ã™" -#: commands/dbcommands.c:202 +#: commands/createas.c:550 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã«ã¯ãƒãƒªã‚·ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: commands/dbcommands.c:235 #, c-format msgid "LOCATION is not supported anymore" msgstr "LOCATIONã¯ã‚‚ã¯ã‚„サãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: commands/dbcommands.c:203 +#: commands/dbcommands.c:236 #, c-format msgid "Consider using tablespaces instead." msgstr "代ã‚りã«ãƒ†ãƒ¼ãƒ–ル空間ã®ä½¿ç”¨ã‚’検討ã—ã¦ãã ã•ã„" -#: commands/dbcommands.c:226 utils/adt/ascii.c:144 +#: commands/dbcommands.c:262 utils/adt/ascii.c:145 #, c-format msgid "%d is not a valid encoding code" msgstr "%dã¯æœ‰åйãªç¬¦å·åŒ–æ–¹å¼ã‚³ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:236 utils/adt/ascii.c:126 +#: commands/dbcommands.c:273 utils/adt/ascii.c:127 #, c-format msgid "%s is not a valid encoding name" msgstr "%sã¯æœ‰åйãªç¬¦å·åŒ–æ–¹å¼åã§ã¯ã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:254 commands/dbcommands.c:1365 commands/user.c:260 -#: commands/user.c:601 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 +#: commands/user.c:664 #, c-format msgid "invalid connection limit: %d" -msgstr "æŽ¥ç¶šåˆ¶é™æ•° %d ã¯ç„¡åйã§ã™" +msgstr "䏿­£ãªæŽ¥ç¶šæ•°åˆ¶é™: %d" -#: commands/dbcommands.c:273 +#: commands/dbcommands.c:311 #, c-format msgid "permission denied to create database" msgstr "データベースを作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:296 +#: commands/dbcommands.c:334 #, c-format msgid "template database \"%s\" does not exist" msgstr "テンプレートデータベース\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/dbcommands.c:308 +#: commands/dbcommands.c:346 #, c-format msgid "permission denied to copy database \"%s\"" msgstr "データベース\"%s\"をコピーã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:324 +#: commands/dbcommands.c:362 #, c-format msgid "invalid server encoding %d" -msgstr "サーãƒã®ç¬¦å·åŒ–æ–¹å¼%dã¯ç„¡åйã§ã™" +msgstr "サーãƒã®ç¬¦å·åŒ–æ–¹å¼%dã¯ä¸æ­£ã§ã™" -#: commands/dbcommands.c:330 commands/dbcommands.c:335 +#: commands/dbcommands.c:368 commands/dbcommands.c:373 #, c-format msgid "invalid locale name: \"%s\"" -msgstr "ロケールå\"%s\"ã¯ç„¡åйã§ã™" +msgstr "ロケールå\"%s\"ã¯ä¸æ­£ã§ã™" -#: commands/dbcommands.c:355 +#: commands/dbcommands.c:393 #, c-format msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" msgstr "æ–°ã—ã„符å·åŒ–æ–¹å¼(%s)ã¯ãƒ†ãƒ³ãƒ—レートデータベースã®ç¬¦å·åŒ–æ–¹å¼(%s)ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:358 +#: commands/dbcommands.c:396 #, c-format msgid "Use the same encoding as in the template database, or use template0 as template." msgstr "テンプレートデータベースã®ç¬¦å·åŒ–æ–¹å¼ã¨åŒã˜ã‚‚ã®ã‚’使ã†ã‹ã€ã‚‚ã—ã㯠template0 をテンプレートã¨ã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„" -#: commands/dbcommands.c:363 +#: commands/dbcommands.c:401 #, c-format msgid "new collation (%s) is incompatible with the collation of the template database (%s)" msgstr "æ–°ã—ã„ç…§åˆé †åº(%s)ã¯ãƒ†ãƒ³ãƒ—レートデータベースã®ç…§åˆé †åº(%s)ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:365 +#: commands/dbcommands.c:403 #, c-format msgid "Use the same collation as in the template database, or use template0 as template." msgstr "テンプレートデータベースã®ç…§åˆé †åºã¨åŒã˜ã‚‚ã®ã‚’使ã†ã‹ã€ã‚‚ã—ã㯠template0 をテンプレートã¨ã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„" -#: commands/dbcommands.c:370 +#: commands/dbcommands.c:408 #, c-format msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" msgstr "æ–°ã—ã„LC_CTYPE(%s)ã¯ãƒ†ãƒ³ãƒ—レートデータベース(%s)ã®LC_CTYPEã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:372 +#: commands/dbcommands.c:410 #, c-format msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." msgstr "テンプレートデータベースã®LC_CTYPEã¨åŒã˜ã‚‚ã®ã‚’使ã†ã‹ã€ã‚‚ã—ãã¯template0をテンプレートã¨ã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„" -#: commands/dbcommands.c:394 commands/dbcommands.c:1068 +#: commands/dbcommands.c:432 commands/dbcommands.c:1146 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "デフォルトã®ãƒ†ãƒ¼ãƒ–ル空間ã¨ã—ã¦pg_globalを使用ã§ãã¾ã›ã‚“" -#: commands/dbcommands.c:420 +#: commands/dbcommands.c:458 #, c-format msgid "cannot assign new default tablespace \"%s\"" msgstr "æ–°ã—ã„デフォルトã®ãƒ†ãƒ¼ãƒ–ル空間\"%s\"を割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“" -#: commands/dbcommands.c:422 +#: commands/dbcommands.c:460 #, c-format msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." -msgstr "データベース\"%s\"ã®ã„ãã¤ã‹ãƒ†ãƒ¼ãƒ–ルã¯ã™ã§ã«ã“ã®ãƒ†ãƒ¼ãƒ–ル空間ã«ã‚りã¾ã™ã®ã§ã€ç«¶åˆã—ã¦ã„ã¾ã™" +msgstr "データベース\"%s\"ã®ã„ãã¤ã‹ãƒ†ãƒ¼ãƒ–ルã¯ã™ã§ã«ã“ã®ãƒ†ãƒ¼ãƒ–ル空間ã«ã‚ã‚‹ãŸã‚ã€ç«¶åˆã—ã¦ã„ã¾ã™ã€‚" -#: commands/dbcommands.c:442 commands/dbcommands.c:939 +#: commands/dbcommands.c:480 commands/dbcommands.c:1016 #, c-format msgid "database \"%s\" already exists" msgstr "データベース\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/dbcommands.c:456 +#: commands/dbcommands.c:494 #, c-format msgid "source database \"%s\" is being accessed by other users" msgstr "å…ƒã¨ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%s\"ã¯ä»–ã®ãƒ¦ãƒ¼ã‚¶ã«ã‚ˆã£ã¦ã‚¢ã‚¯ã‚»ã‚¹ã•れã¦ã„ã¾ã™" -#: commands/dbcommands.c:701 commands/dbcommands.c:716 +#: commands/dbcommands.c:736 commands/dbcommands.c:751 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "符å·åŒ–æ–¹å¼\"%s\"ãŒãƒ­ã‚±ãƒ¼ãƒ«\"%s\"ã«åˆã„ã¾ã›ã‚“" -#: commands/dbcommands.c:704 +#: commands/dbcommands.c:739 #, c-format msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." msgstr "é¸æŠžã•れãŸLC_CTYPEを設定ã™ã‚‹ã«ã¯ã€ç¬¦å·åŒ–æ–¹å¼\"%s\"ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/dbcommands.c:719 +#: commands/dbcommands.c:754 #, c-format msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." msgstr "é¸æŠžã•れãŸLC_COLLATEを設定ã™ã‚‹ã«ã¯ã€ç¬¦å·åŒ–æ–¹å¼\"%s\"ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/dbcommands.c:777 +#: commands/dbcommands.c:815 #, c-format msgid "database \"%s\" does not exist, skipping" -msgstr "データベース\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "データベース\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dbcommands.c:801 +#: commands/dbcommands.c:839 #, c-format msgid "cannot drop a template database" msgstr "テンプレートデータベースを削除ã§ãã¾ã›ã‚“" -#: commands/dbcommands.c:807 +#: commands/dbcommands.c:845 #, c-format msgid "cannot drop the currently open database" msgstr "ç¾åœ¨ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るデータベースを削除ã§ãã¾ã›ã‚“" -#: commands/dbcommands.c:818 commands/dbcommands.c:961 -#: commands/dbcommands.c:1090 +#: commands/dbcommands.c:858 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "データベース\"%s\"ã¯æœ‰åйãªè«–ç†ãƒ¬ãƒ—リケーションスロットã§ä½¿ç”¨ä¸­ã§ã™" + +#: commands/dbcommands.c:860 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d 個ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªã‚¹ãƒ­ãƒƒãƒˆãŒã‚りã¾ã™ã€‚" +msgstr[1] "%d 個ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªã‚¹ãƒ­ãƒƒãƒˆãŒã‚りã¾ã™ã€‚" + +#: commands/dbcommands.c:874 commands/dbcommands.c:1038 +#: commands/dbcommands.c:1168 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "データベース\"%s\"ã¯ä»–ã®ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹ã•れã¦ã„ã¾ã™" -#: commands/dbcommands.c:930 +#: commands/dbcommands.c:887 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "データベース\"%s\"ã¯è«–ç†ãƒ¬ãƒ—リケーションã®ã‚µãƒ–スクリプションã§ä½¿ç”¨ä¸­ã§ã™" + +#: commands/dbcommands.c:889 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d個ã®ã‚µãƒ–スクリプションãŒã‚りã¾ã™" +msgstr[1] "%d個ã®ã‚µãƒ–スクリプションãŒã‚りã¾ã™" + +#: commands/dbcommands.c:1007 #, c-format msgid "permission denied to rename database" msgstr "データベースã®åå‰ã‚’変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:950 +#: commands/dbcommands.c:1027 #, c-format msgid "current database cannot be renamed" msgstr "ç¾åœ¨ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/dbcommands.c:1046 +#: commands/dbcommands.c:1124 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "ç¾åœ¨ã‚ªãƒ¼ãƒ—ン中ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒ†ãƒ¼ãƒ–ルスペースã¯å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/dbcommands.c:1130 +#: commands/dbcommands.c:1227 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" msgstr "データベース \"%s\" ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ä¸­ã«ã€ãƒ†ãƒ¼ãƒ–ルスペース \"%s\"ã«ã™ã§ã«å­˜åœ¨ã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã™" -#: commands/dbcommands.c:1132 +#: commands/dbcommands.c:1229 #, c-format msgid "You must move them back to the database's default tablespace before using this command." -msgstr "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’使ã†å‰ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒ‡ãƒ•ォルトã®ãƒ†ãƒ¼ãƒ–ãƒ«ã‚¹ãƒšãƒ¼ã‚¹ã«æˆ»ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’使ã†å‰ã«ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒ‡ãƒ•ォルトã®ãƒ†ãƒ¼ãƒ–ãƒ«ã‚¹ãƒšãƒ¼ã‚¹ã«æˆ»ã™å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/dbcommands.c:1263 commands/dbcommands.c:1751 -#: commands/dbcommands.c:1957 commands/dbcommands.c:2005 -#: commands/tablespace.c:585 +#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 +#: commands/dbcommands.c:2104 commands/dbcommands.c:2159 +#: commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "å…ƒã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª \"%s\" ã«ä¸è¦ãªãƒ•ã‚¡ã‚¤ãƒ«ãŒæ®‹ã£ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: commands/dbcommands.c:1519 +#: commands/dbcommands.c:1475 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "オプション\"%s\"ã¯ä»–ã®ã‚ªãƒ—ションã¨ä¸€ç·’ã«æŒ‡å®šã¯ã§ãã¾ã›ã‚“" + +#: commands/dbcommands.c:1530 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "ç¾åœ¨ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¸ã®æŽ¥ç¶šã¯ç¦æ­¢ã§ãã¾ã›ã‚“" + +#: commands/dbcommands.c:1667 #, c-format msgid "permission denied to change owner of database" msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/dbcommands.c:1840 +#: commands/dbcommands.c:1987 #, c-format msgid "There are %d other session(s) and %d prepared transaction(s) using the database." msgstr "ä»–ã«ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’使ã£ã¦ã„ã‚‹ %d 個ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã¨ %d å€‹ã®æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚りã¾ã™ã€‚" -#: commands/dbcommands.c:1843 +#: commands/dbcommands.c:1990 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "ä»–ã«ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’使ã£ã¦ã„ã‚‹ %d 個ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒã‚りã¾ã™ã€‚" msgstr[1] "ä»–ã«ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’使ã£ã¦ã„ã‚‹ %d 個ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ãŒã‚りã¾ã™ã€‚" -#: commands/dbcommands.c:1848 +#: commands/dbcommands.c:1995 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." msgstr[0] "ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’使用ã™ã‚‹æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒ%d存在ã—ã¾ã™ã€‚" msgstr[1] "ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’使用ã™ã‚‹æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒ%d存在ã—ã¾ã™ã€‚" -#: commands/define.c:54 commands/define.c:209 commands/define.c:241 -#: commands/define.c:269 +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 +#: commands/define.c:288 commands/define.c:334 #, c-format msgid "%s requires a parameter" msgstr "%sã¯ãƒ‘ラメータãŒå¿…è¦ã§ã™" -#: commands/define.c:95 commands/define.c:106 commands/define.c:176 -#: commands/define.c:194 +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 +#: commands/define.c:213 #, c-format msgid "%s requires a numeric value" msgstr "%sã¯æ•°å€¤ãŒå¿…è¦ã§ã™" -#: commands/define.c:162 +#: commands/define.c:157 #, c-format msgid "%s requires a Boolean value" msgstr "パラメータ\"%s\"ã¯boolean値ãŒå¿…è¦ã§ã™" -#: commands/define.c:223 +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%sã¯æ•´æ•°å€¤ãŒå¿…è¦ã§ã™" + +#: commands/define.c:242 #, c-format msgid "argument of %s must be a name" msgstr "%sã®å¼•æ•°ã¯åå‰ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/define.c:253 +#: commands/define.c:272 #, c-format msgid "argument of %s must be a type name" msgstr "%sã®å¼•æ•°ã¯åž‹åã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/define.c:278 -#, c-format -msgid "%s requires an integer value" -msgstr "%sã¯æ•´æ•°å€¤ãŒå¿…è¦ã§ã™" - -#: commands/define.c:299 +#: commands/define.c:318 #, c-format msgid "invalid argument for %s: \"%s\"" -msgstr "%sã®å¼•æ•°ãŒç„¡åйã§ã™: \"%s\"" +msgstr "%sã®å¼•æ•°ãŒä¸æ­£ã§ã™: \"%s\"" -#: commands/dropcmds.c:100 commands/functioncmds.c:1080 -#: utils/adt/ruleutils.c:1895 +#: commands/dropcmds.c:98 commands/functioncmds.c:1212 +#: utils/adt/ruleutils.c:2564 #, c-format msgid "\"%s\" is an aggregate function" msgstr "\"%s\"ã¯é›†ç´„関数ã§ã™" -#: commands/dropcmds.c:102 +#: commands/dropcmds.c:100 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "集約関数を削除ã™ã‚‹ã«ã¯DROP AGGREGATEを使用ã—ã¦ãã ã•ã„" -#: commands/dropcmds.c:143 commands/tablecmds.c:237 +#: commands/dropcmds.c:149 commands/sequence.c:440 commands/tablecmds.c:2913 +#: commands/tablecmds.c:3071 commands/tablecmds.c:3114 +#: commands/tablecmds.c:12932 tcop/utility.c:1163 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:179 commands/dropcmds.c:278 commands/tablecmds.c:1020 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "スキーマ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:219 commands/dropcmds.c:258 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" -msgstr "åž‹\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "åž‹\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:147 +#: commands/dropcmds.c:248 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "アクセスメソッド\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:266 #, c-format msgid "collation \"%s\" does not exist, skipping" -msgstr "ç…§åˆé †åº \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "ç…§åˆé †åº \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:151 +#: commands/dropcmds.c:273 #, c-format msgid "conversion \"%s\" does not exist, skipping" -msgstr "変æ›\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "変æ›\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:155 +#: commands/dropcmds.c:284 #, c-format -msgid "schema \"%s\" does not exist, skipping" -msgstr "スキーマ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "統計情報オブジェクト\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:159 +#: commands/dropcmds.c:291 #, c-format msgid "text search parser \"%s\" does not exist, skipping" -msgstr "テキスト検索パーサ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テキスト検索パーサ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:163 +#: commands/dropcmds.c:298 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" -msgstr "テキスト検索辞書\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テキスト検索辞書\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:167 +#: commands/dropcmds.c:305 #, c-format msgid "text search template \"%s\" does not exist, skipping" -msgstr "テキスト検索テンプレート\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テキスト検索テンプレート\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:171 +#: commands/dropcmds.c:312 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" -msgstr "テキスト検索設定\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テキスト検索設定\"%sã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:175 +#: commands/dropcmds.c:317 #, c-format msgid "extension \"%s\" does not exist, skipping" -msgstr "拡張機能 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¦ã„ã¾ã™" +msgstr "機能拡張 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:179 +#: commands/dropcmds.c:327 #, c-format msgid "function %s(%s) does not exist, skipping" -msgstr "関数%s(%s)ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "関数%s(%s)ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:340 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "プロシージャ %s(%s) ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:353 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "ルーãƒãƒ³ %s(%s) ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:184 +#: commands/dropcmds.c:366 #, c-format msgid "aggregate %s(%s) does not exist, skipping" -msgstr "集約%s(%s)ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "集約%s(%s)ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:189 +#: commands/dropcmds.c:379 #, c-format msgid "operator %s does not exist, skipping" -msgstr "演算å­%sãŒå­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "演算å­%sã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:193 +#: commands/dropcmds.c:385 #, c-format msgid "language \"%s\" does not exist, skipping" -msgstr "言語\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "言語\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:197 +#: commands/dropcmds.c:394 #, c-format msgid "cast from type %s to type %s does not exist, skipping" -msgstr "åž‹%sã‹ã‚‰åž‹%sã¸ã®ã‚­ãƒ£ã‚¹ãƒˆã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "åž‹%sã‹ã‚‰åž‹%sã¸ã®ã‚­ãƒ£ã‚¹ãƒˆã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:403 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "åž‹%sã€è¨€èªž\"%s\"ã«å¯¾ã™ã‚‹å¤‰æ›ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:411 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"ã®ãƒˆãƒªã‚¬\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:204 +#: commands/dropcmds.c:420 #, c-format -msgid "trigger \"%s\" for table \"%s\" does not exist, skipping" -msgstr "テーブル\"%2$s\"ã®ãƒˆãƒªã‚¬\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "リレーション\"%2$s\"ã®ãƒãƒªã‚·\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:210 +#: commands/dropcmds.c:427 #, c-format -#| msgid "server \"%s\" does not exist, skipping" msgid "event trigger \"%s\" does not exist, skipping" -msgstr "イベントトリガ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "イベントトリガ \"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:214 +#: commands/dropcmds.c:433 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" -msgstr "リレーション\"%2$s\"ã®ãƒ«ãƒ¼ãƒ«\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "リレーション\"%2$s\"ã®ãƒ«ãƒ¼ãƒ«\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:220 +#: commands/dropcmds.c:440 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" -msgstr "外部データラッパー \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "外部データラッパ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:224 +#: commands/dropcmds.c:444 #, c-format msgid "server \"%s\" does not exist, skipping" -msgstr "外部データラッパー \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "外部データラッパ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:228 +#: commands/dropcmds.c:453 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" -msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "アクセスメソッド\"%2$s\"ã«å¯¾ã™ã‚‹æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/dropcmds.c:233 +#: commands/dropcmds.c:465 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" -msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­æ—\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "アクセスメソッド\"%2$s\"ã«å¯¾ã™ã‚‹æ¼”ç®—å­æ—\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/dropcmds.c:472 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "パブリケーション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/event_trigger.c:149 +#: commands/event_trigger.c:187 #, c-format -#| msgid "permission denied to create extension \"%s\"" msgid "permission denied to create event trigger \"%s\"" -msgstr "イベントトリガ \"%s\" を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "イベントトリガ \"%s\"を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/event_trigger.c:151 +#: commands/event_trigger.c:189 #, c-format -#| msgid "Must be superuser to create a foreign-data wrapper." msgid "Must be superuser to create an event trigger." -msgstr "イベントトリガを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "イベントトリガを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/event_trigger.c:159 +#: commands/event_trigger.c:198 #, c-format -#| msgid "unrecognized time zone name: \"%s\"" msgid "unrecognized event name \"%s\"" -msgstr "イベントåãŒä¸æ˜Žã§ã™: \"%s\"" +msgstr "識別ã§ããªã„イベントå\"%s\"" -#: commands/event_trigger.c:176 +#: commands/event_trigger.c:215 #, c-format -#| msgid "unrecognized file format \"%d\"\n" msgid "unrecognized filter variable \"%s\"" -msgstr "フィルタ変数\"%s\"ã¯ä¸æ˜Žã§ã™" - -#: commands/event_trigger.c:203 -#, c-format -#| msgid "function %s must return type \"trigger\"" -msgid "function \"%s\" must return type \"event_trigger\"" -msgstr "関数%sã¯\"event_trigger\"型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "識別ã§ããªã„フィルタ変数\"%s\"" -#: commands/event_trigger.c:228 +#: commands/event_trigger.c:270 #, c-format -#| msgid "interval units \"%s\" not recognized" msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "フィルタã®å€¤\"%s\"ã¯ãƒ•ィルタ変数\"%s\"ã§ã¯èªè­˜ã•れã¾ã›ã‚“" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:234 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format -#| msgid "collations are not supported by type %s" msgid "event triggers are not supported for %s" -msgstr "%s ã§ã¯ã‚¤ãƒ™ãƒ³ãƒˆãƒˆãƒªã‚¬ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +msgstr "%sã§ã¯ã‚¤ãƒ™ãƒ³ãƒˆãƒˆãƒªã‚¬ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: commands/event_trigger.c:289 +#: commands/event_trigger.c:369 #, c-format -#| msgid "table name \"%s\" specified more than once" msgid "filter variable \"%s\" specified more than once" msgstr "フィルタ変数\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: commands/event_trigger.c:434 commands/event_trigger.c:477 -#: commands/event_trigger.c:568 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 +#: commands/event_trigger.c:651 #, c-format -#| msgid "server \"%s\" does not exist" msgid "event trigger \"%s\" does not exist" msgstr "イベントトリガ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/event_trigger.c:536 +#: commands/event_trigger.c:620 #, c-format -#| msgid "permission denied to change owner of foreign-data wrapper \"%s\"" msgid "permission denied to change owner of event trigger \"%s\"" msgstr "イベントトリガ \"%s\" ã®æ‰€æœ‰è€…を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/event_trigger.c:538 +#: commands/event_trigger.c:622 #, c-format -#| msgid "The owner of a foreign-data wrapper must be a superuser." msgid "The owner of an event trigger must be a superuser." msgstr "ã‚¤ãƒ™ãƒ³ãƒˆãƒˆãƒªã‚¬ã®æ‰€æœ‰è€…ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/event_trigger.c:1216 +#: commands/event_trigger.c:1457 #, c-format -#| msgid "%s is not allowed in a non-volatile function" msgid "%s can only be called in a sql_drop event trigger function" -msgstr "sql_dropイベントトリガ関数ã§ã¯%sã®ã¿ã‚’呼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™" +msgstr "%sã¯sql_dropイベントトリガ関数内ã§ã®ã¿å‘¼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™" -#: commands/event_trigger.c:1223 commands/extension.c:1650 -#: commands/extension.c:1759 commands/extension.c:1952 commands/prepare.c:702 -#: executor/execQual.c:1719 executor/execQual.c:1744 executor/execQual.c:2113 -#: executor/execQual.c:5255 executor/functions.c:1011 foreign/foreign.c:421 -#: replication/walsender.c:1887 utils/adt/jsonfuncs.c:924 -#: utils/adt/jsonfuncs.c:1093 utils/adt/jsonfuncs.c:1593 -#: utils/fmgr/funcapi.c:61 utils/mmgr/portalmem.c:986 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format -msgid "set-valued function called in context that cannot accept a set" -msgstr "ã“ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§é›†åˆå€¤ã®é–¢æ•°ã¯é›†åˆã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%sã¯table_rewriteイベントトリガ関数ã§ã®ã¿å‘¼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™" -#: commands/event_trigger.c:1227 commands/extension.c:1654 -#: commands/extension.c:1763 commands/extension.c:1956 commands/prepare.c:706 -#: foreign/foreign.c:426 replication/walsender.c:1891 -#: utils/mmgr/portalmem.c:990 +#: commands/event_trigger.c:2009 #, c-format -msgid "materialize mode required, but it is not allowed in this context" -msgstr "実体化モードãŒè¦æ±‚ã•れã¾ã—ãŸãŒã€ã“ã®æ–‡è„ˆã§ã¯è¨±ã•れã¾ã›ã‚“" +msgid "%s can only be called in an event trigger function" +msgstr "%sã¯ã‚¤ãƒ™ãƒ³ãƒˆãƒˆãƒªã‚¬é–¢æ•°ã§ã®ã¿å‘¼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™" -#: commands/explain.c:163 +#: commands/explain.c:192 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "EXPLAIN オプション \"%s\" ãŒèªè­˜ã§ããªã„値ã§ã™: \"%s\"" -#: commands/explain.c:169 +#: commands/explain.c:199 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "EXPLAIN オプション \"%s\" ãŒèªè­˜ã§ãã¾ã›ã‚“" -#: commands/explain.c:176 +#: commands/explain.c:207 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "EXPLAIN オプション㮠BUFFERS ã«ã¯ ANALYZE 指定ãŒå¿…è¦ã§ã™" -#: commands/explain.c:185 +#: commands/explain.c:216 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "EXPLAINオプションã®TIMINGã«ã¯ANALYZE指定ãŒå¿…è¦ã§ã™" -#: commands/extension.c:148 commands/extension.c:2632 +#: commands/extension.c:168 commands/extension.c:2907 #, c-format msgid "extension \"%s\" does not exist" -msgstr "拡張機能 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "機能拡張 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/extension.c:247 commands/extension.c:256 commands/extension.c:268 -#: commands/extension.c:278 +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 +#: commands/extension.c:298 #, c-format msgid "invalid extension name: \"%s\"" -msgstr "拡張機能åãŒç„¡åйã§ã™: \"%s\"" +msgstr "機能拡張åãŒä¸æ­£ã§ã™: \"%s\"" -#: commands/extension.c:248 +#: commands/extension.c:268 #, c-format msgid "Extension names must not be empty." -msgstr "拡張機能åãŒç„¡åйã§ã™: 空ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "機能拡張åãŒç„¡åйã§ã™: 空ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:257 +#: commands/extension.c:277 #, c-format msgid "Extension names must not contain \"--\"." -msgstr "拡張機能åã« \"--\" ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "機能拡張åã« \"--\" ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:269 +#: commands/extension.c:289 #, c-format msgid "Extension names must not begin or end with \"-\"." -msgstr "拡張機能å㌠\"-\" ã§å§‹ã¾ã£ãŸã‚Šçµ‚ã‚ã£ãŸã‚Šã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "機能拡張å㌠\"-\" ã§å§‹ã¾ã£ãŸã‚Šçµ‚ã‚ã£ãŸã‚Šã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:279 +#: commands/extension.c:299 #, c-format msgid "Extension names must not contain directory separator characters." -msgstr "拡張機能åã«ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®åŒºåˆ‡ã‚Šæ–‡å­—ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "機能拡張åã«ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®åŒºåˆ‡ã‚Šæ–‡å­—ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:294 commands/extension.c:303 commands/extension.c:312 -#: commands/extension.c:322 +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 +#: commands/extension.c:342 #, c-format msgid "invalid extension version name: \"%s\"" -msgstr "拡張機能ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³åãŒç„¡åйã§ã™: \"%s\"" +msgstr "機能拡張ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³åãŒä¸æ­£ã™: \"%s\"" -#: commands/extension.c:295 +#: commands/extension.c:315 #, c-format msgid "Version names must not be empty." msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³åãŒç„¡åйã§ã™: 空ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:304 +#: commands/extension.c:324 #, c-format msgid "Version names must not contain \"--\"." msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³åã« \"--\" ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:313 +#: commands/extension.c:333 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³åãŒ\"-\" ã§å§‹ã¾ã£ãŸã‚Šçµ‚ã‚ã£ãŸã‚Šã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:323 +#: commands/extension.c:343 #, c-format msgid "Version names must not contain directory separator characters." msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³åã«ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®åŒºåˆ‡ã‚Šæ–‡å­—ãŒå«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:473 +#: commands/extension.c:493 #, c-format msgid "could not open extension control file \"%s\": %m" -msgstr "拡張機能ã®åˆ¶å¾¡ãƒ•ァイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "機能拡張ã®åˆ¶å¾¡ãƒ•ァイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/extension.c:495 commands/extension.c:505 +#: commands/extension.c:515 commands/extension.c:525 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" -msgstr "ã‚»ã‚«ãƒ³ãƒ€ãƒªã®æ‹¡å¼µæ©Ÿèƒ½åˆ¶å¾¡ãƒ•ァイルã«ãƒ‘ラメータ \"%s\" を設定ã§ãã¾ã›ã‚“" +msgstr "ã‚»ã‚«ãƒ³ãƒ€ãƒªã®æ©Ÿèƒ½æ‹¡å¼µåˆ¶å¾¡ãƒ•ァイルã«ãƒ‘ラメータ \"%s\" を設定ã§ãã¾ã›ã‚“" -#: commands/extension.c:544 +#: commands/extension.c:564 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "\"%s\" ã¯æœ‰åйãªç¬¦å·åŒ–æ–¹å¼åã§ã¯ã‚りã¾ã›ã‚“" -#: commands/extension.c:558 +#: commands/extension.c:578 #, c-format msgid "parameter \"%s\" must be a list of extension names" -msgstr "パラメータ \"%s\" ã¯æ‹¡å¼µæ©Ÿèƒ½åã®ãƒªã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "パラメータ \"%s\" ã¯æ©Ÿèƒ½æ‹¡å¼µåã®ãƒªã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:565 +#: commands/extension.c:585 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "ファイル \"%2$s\" 中ã«èªè­˜ã§ããªã„パラメータ \"%1$s\" ãŒã‚りã¾ã™" -#: commands/extension.c:574 +#: commands/extension.c:594 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "\"relocatable\" ãŒçœŸã®å ´åˆã¯ãƒ‘ラメータ \"schema\" ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: commands/extension.c:726 +#: commands/extension.c:761 #, c-format msgid "transaction control statements are not allowed within an extension script" -msgstr "トランザクション制御ステートメントを拡張機能スクリプトã®ä¸­ã«æ›¸ãã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "トランザクション制御ステートメントを機能拡張スクリプトã®ä¸­ã«æ›¸ãã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/extension.c:794 +#: commands/extension.c:807 #, c-format msgid "permission denied to create extension \"%s\"" -msgstr "拡張機能 \"%s\" を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "機能拡張 \"%s\" を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/extension.c:796 +#: commands/extension.c:809 #, c-format msgid "Must be superuser to create this extension." -msgstr "ã“ã®æ‹¡å¼µæ©Ÿèƒ½ã‚’作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã“ã®æ©Ÿèƒ½æ‹¡å¼µã‚’生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/extension.c:800 +#: commands/extension.c:813 #, c-format msgid "permission denied to update extension \"%s\"" -msgstr "拡張機能 \"%s\" ã‚’æ›´æ–°ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "機能拡張 \"%s\" ã‚’æ›´æ–°ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/extension.c:802 +#: commands/extension.c:815 #, c-format msgid "Must be superuser to update this extension." -msgstr "ã“ã®æ‹¡å¼µæ©Ÿèƒ½ã‚’æ›´æ–°ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã“ã®æ©Ÿèƒ½æ‹¡å¼µã‚’æ›´æ–°ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/extension.c:1084 +#: commands/extension.c:1097 #, c-format msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" -msgstr "拡張機能 \"%s\" ã«ã¤ã„ã¦ã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã‹ã‚‰ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã¸ã®ã‚¢ãƒƒãƒ—デートパスãŒã‚りã¾ã›ã‚“" +msgstr "機能拡張 \"%s\" ã«ã¤ã„ã¦ã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã‹ã‚‰ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã¸ã®ã‚¢ãƒƒãƒ—デートパスãŒã‚りã¾ã›ã‚“" -#: commands/extension.c:1211 +#: commands/extension.c:1304 commands/extension.c:2968 #, c-format -msgid "extension \"%s\" already exists, skipping" -msgstr "拡張機能 \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚スキップã—ã¦ã„ã¾ã™" +msgid "version to install must be specified" +msgstr "インストールã™ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’指定ã—ã¦ãã ã•ã„" -#: commands/extension.c:1218 +#: commands/extension.c:1326 #, c-format -msgid "extension \"%s\" already exists" -msgstr "拡張機能 \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgid "FROM version must be different from installation target version \"%s\"" +msgstr "FROM ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã¨ç•°ãªã£ã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:1229 +#: commands/extension.c:1391 #, c-format -msgid "nested CREATE EXTENSION is not supported" -msgstr "入れå­ã® CREATE EXTENSION ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "機能拡張\"%s\"ã«ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³\"%s\"ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚¹ã‚¯ãƒªãƒ—トもアップデートパスもã‚りã¾ã›ã‚“" -#: commands/extension.c:1284 commands/extension.c:2692 +#: commands/extension.c:1426 #, c-format -msgid "version to install must be specified" -msgstr "インストールã™ã‚‹ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "機能拡張\"%s\" ã¯ã‚¹ã‚­ãƒ¼ãƒž \"%s\" 内ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/extension.c:1301 +#: commands/extension.c:1579 #, c-format -msgid "FROM version must be different from installation target version \"%s\"" -msgstr "FROM ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%s\" ã¨ç•°ãªã£ã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "機能拡張\"%s\"ã¨\"%s\"ã®é–“ã«å¾ªç’°ä¾å­˜é–¢ä¿‚ãŒæ¤œå‡ºã•れã¾ã—ãŸ" -#: commands/extension.c:1356 +#: commands/extension.c:1584 #, c-format -msgid "extension \"%s\" must be installed in schema \"%s\"" -msgstr "拡張機能 \"%s\" ã¯ã‚¹ã‚­ãƒ¼ãƒž \"%s\" 内ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "installing required extension \"%s\"" +msgstr "å¿…è¦ãªæ©Ÿèƒ½æ‹¡å¼µã‚’インストールã—ã¾ã™:\"%s\"" -#: commands/extension.c:1440 commands/extension.c:2835 +#: commands/extension.c:1608 #, c-format msgid "required extension \"%s\" is not installed" -msgstr "è¦æ±‚ã•ã‚ŒãŸæ‹¡å¼µæ©Ÿèƒ½ã€€\"%s\" ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“" +msgstr "è¦æ±‚ã•ã‚ŒãŸæ©Ÿèƒ½æ‹¡å¼µã€€\"%s\" ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“" + +#: commands/extension.c:1611 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "å¿…è¦ãªæ©Ÿèƒ½æ‹¡å¼µã‚’一緒ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã«ã¯ CREATE EXTENSION ... CASCADE を使ã£ã¦ãã ã•ã„。" + +#: commands/extension.c:1648 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "機能拡張 \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/extension.c:1655 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "機能拡張 \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/extension.c:1666 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "入れå­ã® CREATE EXTENSION ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: commands/extension.c:1602 +#: commands/extension.c:1847 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "変更ã•れã¦ã„ã‚‹ãŸã‚æ‹¡å¼µ\"%s\"を削除ã§ãã¾ã›ã‚“" -#: commands/extension.c:2073 +#: commands/extension.c:2349 #, c-format msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" msgstr "pg_extension_config_dump()ã¯CREATE EXTENSIONã«ã‚ˆã‚Šå®Ÿè¡Œã•れるSQLスクリプトã‹ã‚‰ã®ã¿å‘¼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã™" -#: commands/extension.c:2085 +#: commands/extension.c:2361 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u ãŒãƒ†ãƒ¼ãƒ–ルをå‚ç…§ã—ã¦ã„ã¾ã›ã‚“" -#: commands/extension.c:2090 +#: commands/extension.c:2366 #, c-format msgid "table \"%s\" is not a member of the extension being created" -msgstr "テーブル \"%s\" ã¯ç”Ÿæˆã•れよã†ã¨ã—ã¦ã„る拡張機能ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" +msgstr "テーブル \"%s\" ã¯ç”Ÿæˆã•れよã†ã¨ã—ã¦ã„る機能拡張ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" -#: commands/extension.c:2454 +#: commands/extension.c:2722 #, c-format msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" -msgstr "拡張機能ãŒãã®ã‚¹ã‚­ãƒ¼ãƒžã‚’å«ã‚“ã§ã„ã‚‹ãŸã‚ã€æ‹¡å¼µæ©Ÿèƒ½\"%s\"をスキーマ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“" +msgstr "機能拡張ãŒãã®ã‚¹ã‚­ãƒ¼ãƒžã‚’å«ã‚“ã§ã„ã‚‹ãŸã‚ã€æ©Ÿèƒ½æ‹¡å¼µ\"%s\"をスキーマ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“" -#: commands/extension.c:2494 commands/extension.c:2557 +#: commands/extension.c:2763 commands/extension.c:2826 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" -msgstr "拡張機能 \"%s\" 㯠SET SCHEMAをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "機能拡張 \"%s\" 㯠SET SCHEMAをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/extension.c:2559 +#: commands/extension.c:2828 #, c-format msgid "%s is not in the extension's schema \"%s\"" -msgstr "拡張機能ã®ã‚¹ã‚­ãƒ¼ãƒž \"%2$s\" ã« %1$s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" +msgstr "機能拡張ã®ã‚¹ã‚­ãƒ¼ãƒž \"%2$s\" ã« %1$s ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: commands/extension.c:2612 +#: commands/extension.c:2887 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "入れå­ã«ãªã£ãŸ ALTER EXTENSION ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/extension.c:2703 +#: commands/extension.c:2979 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" -msgstr "拡張機能 \"%2$s\" ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%1$s\" ã¯ã™ã§ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™" +msgstr "機能拡張 \"%2$s\" ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ \"%1$s\" ã¯ã™ã§ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã™" -#: commands/extension.c:2942 +#: commands/extension.c:3230 #, c-format -#| msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "スキーマ\"%s\"ã‚’æ‹¡å¼µ\"%s\"ã«è¿½åŠ ã§ãã¾ã›ã‚“。ãã®ã‚¹ã‚­ãƒ¼ãƒžã«ãã®æ‹¡å¼µãŒå«ã¾ã‚Œã¦ã„ã‚‹ãŸã‚ã§ã™" -#: commands/extension.c:2960 +#: commands/extension.c:3258 #, c-format msgid "%s is not a member of extension \"%s\"" -msgstr "%s ã¯æ‹¡å¼µæ©Ÿèƒ½ \"%s\" ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" +msgstr "%s ã¯æ©Ÿèƒ½æ‹¡å¼µ \"%s\" ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/extension.c:3324 +#, c-format +msgid "file \"%s\" is too large" +msgstr "ファイル\"%s\"ã¯å¤§ãã™ãŽã¾ã™" -#: commands/foreigncmds.c:135 commands/foreigncmds.c:144 +#: commands/foreigncmds.c:150 commands/foreigncmds.c:159 #, c-format msgid "option \"%s\" not found" msgstr "オプション \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: commands/foreigncmds.c:154 +#: commands/foreigncmds.c:169 #, c-format msgid "option \"%s\" provided more than once" -msgstr "オプション \"%s\" ãŒï¼’回以上指定ã•れã¾ã—ãŸ" +msgstr "オプション \"%s\" ãŒ2回以上指定ã•れã¾ã—ãŸ" -#: commands/foreigncmds.c:220 commands/foreigncmds.c:228 +#: commands/foreigncmds.c:223 commands/foreigncmds.c:231 #, c-format msgid "permission denied to change owner of foreign-data wrapper \"%s\"" msgstr "外部データラッパー \"%s\" ã®æ‰€æœ‰è€…を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/foreigncmds.c:222 +#: commands/foreigncmds.c:225 #, c-format msgid "Must be superuser to change owner of a foreign-data wrapper." -msgstr "スーパーユーザã®ã¿ãŒå¤–éƒ¨ãƒ‡ãƒ¼ã‚¿ãƒ©ãƒƒãƒ‘ãƒ¼ã®æ‰€æœ‰è€…を変更ã§ãã¾ã™" +msgstr "å¤–éƒ¨ãƒ‡ãƒ¼ã‚¿ãƒ©ãƒƒãƒ‘ãƒ¼ã®æ‰€æœ‰è€…を変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/foreigncmds.c:230 +#: commands/foreigncmds.c:233 #, c-format msgid "The owner of a foreign-data wrapper must be a superuser." msgstr "å¤–éƒ¨ãƒ‡ãƒ¼ã‚¿ãƒ©ãƒƒãƒ‘ãƒ¼ã®æ‰€æœ‰è€…ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/foreigncmds.c:268 commands/foreigncmds.c:652 foreign/foreign.c:600 +#: commands/foreigncmds.c:291 commands/foreigncmds.c:706 foreign/foreign.c:667 #, c-format msgid "foreign-data wrapper \"%s\" does not exist" msgstr "外部データラッパー \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/foreigncmds.c:377 commands/foreigncmds.c:940 -#: commands/foreigncmds.c:1281 foreign/foreign.c:621 -#, c-format -msgid "server \"%s\" does not exist" -msgstr "サーãƒãƒ¼ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" - -#: commands/foreigncmds.c:433 -#, c-format -msgid "function %s must return type \"fdw_handler\"" -msgstr "関数 %s 㯠\"fdw_handler\" 型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: commands/foreigncmds.c:528 +#: commands/foreigncmds.c:582 #, c-format msgid "permission denied to create foreign-data wrapper \"%s\"" msgstr "外部データラッパー \"%s\" を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/foreigncmds.c:530 +#: commands/foreigncmds.c:584 #, c-format msgid "Must be superuser to create a foreign-data wrapper." -msgstr "テーブル空間を作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "外部データラッパを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/foreigncmds.c:642 +#: commands/foreigncmds.c:696 #, c-format msgid "permission denied to alter foreign-data wrapper \"%s\"" msgstr "外部データラッパー \"%s\" を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/foreigncmds.c:644 +#: commands/foreigncmds.c:698 #, c-format msgid "Must be superuser to alter a foreign-data wrapper." -msgstr "外部データラッパーを変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "外部データラッパーを更新ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/foreigncmds.c:675 +#: commands/foreigncmds.c:729 #, c-format msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" msgstr "外部データラッパーã®ãƒãƒ³ãƒ‰ãƒ©ãƒ¼ã‚’変更ã™ã‚‹ã¨ã€æ—¢å­˜ã®å¤–éƒ¨ãƒ†ãƒ¼ãƒ–ãƒ«ã®æŒ¯ã‚‹èˆžã„ãŒå¤‰ã‚ã‚‹ã“ã¨ãŒã‚りã¾ã™" -#: commands/foreigncmds.c:689 +#: commands/foreigncmds.c:744 #, c-format msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" -msgstr "外部データラッパーã®ãƒãƒªãƒ‡ãƒ¼ã‚¿ï¼ˆæ¤œè¨¼ç”¨é–¢æ•°ï¼‰ã‚’変更ã™ã‚‹ã¨ã€ãれã«ä¾å­˜ã™ã‚‹ã‚ªãƒ—ションãŒç„¡åйã«ãªã‚‹å ´åˆãŒã‚りã¾ã™" +msgstr "外部データラッパーã®ãƒãƒªãƒ‡ãƒ¼ã‚¿ï¼ˆæ¤œè¨¼ç”¨é–¢æ•°ï¼‰ã‚’変更ã™ã‚‹ã¨ã€ãれã«ä¾å­˜ã™ã‚‹ã‚ªãƒ—ションãŒä¸æ­£ã«ãªã‚‹å ´åˆãŒã‚りã¾ã™" + +#: commands/foreigncmds.c:890 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "サーãƒ\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/foreigncmds.c:1102 +#: commands/foreigncmds.c:1175 #, c-format -msgid "user mapping \"%s\" already exists for server %s" -msgstr "ユーザーマッピング \"%s\" ã¯ã‚µãƒ¼ãƒãƒ¼ \"%s\" 用ã¨ã—ã¦ã™ã§ã«å­˜åœ¨ã—ã¾ã™" +msgid "user mapping for \"%s\" already exists for server %s, skipping" +msgstr "\"%s\"ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングã¯ã‚µãƒ¼ãƒ%sã«å¯¾ã—ã¦ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/foreigncmds.c:1190 commands/foreigncmds.c:1297 +#: commands/foreigncmds.c:1185 #, c-format -msgid "user mapping \"%s\" does not exist for the server" -msgstr "ãã®ã‚µãƒ¼ãƒãƒ¼ç”¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒžãƒƒãƒ”ング \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "user mapping for \"%s\" already exists for server %s" +msgstr "\"%s\"ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングã¯ã‚µãƒ¼ãƒãƒ¼\"%s\"ã«å¯¾ã—ã¦ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/foreigncmds.c:1284 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 +#, c-format +msgid "user mapping for \"%s\" does not exist for the server" +msgstr "\"%s\"ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングã¯ã“ã®ã‚µãƒ¼ãƒã«å¯¾ã—ã¦ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" -msgstr "サーãƒãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "サーãƒãƒ¼ãŒå­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/foreigncmds.c:1302 +#: commands/foreigncmds.c:1402 #, c-format -msgid "user mapping \"%s\" does not exist for the server, skipping" -msgstr "ãã®ã‚µãƒ¼ãƒãƒ¼ç”¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒžãƒƒãƒ”ング \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgid "user mapping for \"%s\" does not exist for the server, skipping" +msgstr "\"%s\"ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングã“ã®ã‚µãƒ¼ãƒã«ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/functioncmds.c:99 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format -msgid "SQL function cannot return shell type %s" -msgstr "SQL関数ã¯ã‚·ã‚§ãƒ«åž‹%sã‚’ã‹ãˆã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "外部データラッパー\"%s\"ã«ã¯ãƒãƒ³ãƒ‰ãƒ©ãŒã‚りã¾ã›ã‚“" + +#: commands/foreigncmds.c:1559 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "外部データラッパー\"%s\"㯠IMPORT FOREIGN SCHEMA をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: commands/foreigncmds.c:1662 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "外部テーブル\"%s\"をインãƒãƒ¼ãƒˆã—ã¾ã™" #: commands/functioncmds.c:104 #, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL関数ã¯ã‚·ã‚§ãƒ«åž‹%sã‚’è¿”å´ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: commands/functioncmds.c:109 +#, c-format msgid "return type %s is only a shell" -msgstr "戻り値型%sã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™" +msgstr "戻り値型%sã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«åž‹ã§ã™" -#: commands/functioncmds.c:133 parser/parse_type.c:285 +#: commands/functioncmds.c:139 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "シェル型\"%s\"ã«åž‹ä¿®æ­£å­ã‚’指定ã§ãã¾ã›ã‚“" -#: commands/functioncmds.c:139 +#: commands/functioncmds.c:145 #, c-format msgid "type \"%s\" is not yet defined" msgstr "åž‹\"%s\"ã¯æœªå®šç¾©ã§ã™" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:146 #, c-format msgid "Creating a shell type definition." -msgstr "シェル型定義を作æˆã—ã¦ã„ã¾ã™" +msgstr "シェル型ã®å®šç¾©ã‚’作æˆã—ã¾ã™" -#: commands/functioncmds.c:224 +#: commands/functioncmds.c:238 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "SQL関数ã¯ã‚·ã‚§ãƒ«åž‹\"%s\"ã‚’å—ã‘付ã‘られã¾ã›ã‚“" -#: commands/functioncmds.c:229 +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "集約ã¯ã‚·ã‚§ãƒ«åž‹\"%s\"ã‚’å—ã‘付ã‘られã¾ã›ã‚“" + +#: commands/functioncmds.c:249 #, c-format msgid "argument type %s is only a shell" msgstr "引数型%sã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:259 #, c-format msgid "type %s does not exist" msgstr "åž‹%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/functioncmds.c:251 +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "集約ã¯é›†åˆå¼•æ•°ã‚’å—ã‘付ã‘られã¾ã›ã‚“" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "プロシージャã¯é›†åˆå¼•æ•°ã‚’å—ã‘付ã‘ã¾ã›ã‚“" + +#: commands/functioncmds.c:281 #, c-format msgid "functions cannot accept set arguments" msgstr "関数ã¯é›†åˆã‚’引数ã¨ã—ã¦å—ã‘付ã‘られã¾ã›ã‚“" -#: commands/functioncmds.c:260 +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "プロシージャã¯å‡ºåŠ›å¼•æ•°ã‚’æŒã¦ã¾ã›ã‚“" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT å¼•æ•°ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/functioncmds.c:300 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "VARIADIC ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã¯æœ€å¾Œã®å…¥åŠ›ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:287 +#: commands/functioncmds.c:330 #, c-format msgid "VARIADIC parameter must be an array" msgstr "VARIADIC パラメータã¯é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:327 +#: commands/functioncmds.c:370 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "パラメータ \"%s\" ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: commands/functioncmds.c:342 +#: commands/functioncmds.c:385 #, c-format msgid "only input parameters can have default values" msgstr "入力パラメータã®ã¿ãŒãƒ‡ãƒ•ォルト値をæŒã¦ã¾ã™" -#: commands/functioncmds.c:357 +#: commands/functioncmds.c:400 #, c-format msgid "cannot use table references in parameter default value" msgstr "パラメータã®ãƒ‡ãƒ•ォルト値ã¨ã—ã¦ãƒ†ãƒ¼ãƒ–ルå‚照を使用ã§ãã¾ã›ã‚“" -#: commands/functioncmds.c:381 +#: commands/functioncmds.c:424 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "デフォルト値をæŒã¤ãƒ‘ラメータã®å¾Œã«ã‚る入力パラメータã¯ã€å¿…ãšãƒ‡ãƒ•ォルト値をæŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:631 +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "プロシージャ定義内ã®ä¸æ­£ãªå±žæ€§" + +#: commands/functioncmds.c:747 #, c-format msgid "no function body specified" msgstr "é–¢æ•°æœ¬ä½“ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:641 +#: commands/functioncmds.c:757 #, c-format msgid "no language specified" msgstr "è¨€èªžãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" -#: commands/functioncmds.c:664 commands/functioncmds.c:1119 +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 #, c-format msgid "COST must be positive" -msgstr "ã‚³ã‚¹ãƒˆã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "COSTã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:672 commands/functioncmds.c:1127 +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 #, c-format msgid "ROWS must be positive" msgstr "ROWSã¯æ­£æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:711 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "䏿˜Žãªé–¢æ•°å±žæ€§\"%s\"ã¯ç„¡è¦–ã—ã¾ã—ãŸ" - -#: commands/functioncmds.c:762 +#: commands/functioncmds.c:842 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "言語\"%s\"ã§ã¯ASé …ç›®ã¯1ã¤ã ã‘å¿…è¦ã§ã™" -#: commands/functioncmds.c:850 commands/functioncmds.c:1704 -#: commands/proclang.c:553 +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 +#: commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "言語\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/functioncmds.c:852 commands/functioncmds.c:1706 +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "言語をデータベースã«èª­ã¿è¾¼ã‚€ãŸã‚ã«ã¯CREATE LANGUAGEを使用ã—ã¦ãã ã•ã„" +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "言語をデータベースã«èª­ã¿è¾¼ã‚€ãŸã‚ã«ã¯ CREATE EXTENSION を使用ã—ã¦ãã ã•ã„" -#: commands/functioncmds.c:887 commands/functioncmds.c:1110 +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 #, c-format msgid "only superuser can define a leakproof function" msgstr "スーパーユーザã®ã¿ãŒãƒªãƒ¼ã‚¯ãƒ—ルーフ関数を定義ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: commands/functioncmds.c:909 +#: commands/functioncmds.c:1023 #, c-format msgid "function result type must be %s because of OUT parameters" -msgstr "OUTパラメータã®ãŸã‚ã€é–¢æ•°ã®æˆ»ã‚Šå€¤åž‹ã¯%sã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "OUTパラメータã§å®šç¾©ã•れã¦ã„ã‚‹ãŸã‚ã€é–¢æ•°ã®æˆ»ã‚Šå€¤åž‹ã¯%sã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:922 +#: commands/functioncmds.c:1036 #, c-format msgid "function result type must be specified" msgstr "関数ã®çµæžœåž‹ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:957 commands/functioncmds.c:1131 +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "関数ãŒé›†åˆã‚’è¿”ã™å ´åˆã«ROWSã¯é©ã—ã¦ã„ã¾ã›ã‚“" -#: commands/functioncmds.c:1284 +#: commands/functioncmds.c:1440 #, c-format msgid "source data type %s is a pseudo-type" msgstr "変æ›å…ƒãƒ‡ãƒ¼ã‚¿åž‹%sã¯ä»®æƒ³åž‹ã§ã™" -#: commands/functioncmds.c:1290 +#: commands/functioncmds.c:1446 #, c-format msgid "target data type %s is a pseudo-type" msgstr "変æ›å…ˆãƒ‡ãƒ¼ã‚¿åž‹%sã¯ä»®æƒ³åž‹ã§ã™" -#: commands/functioncmds.c:1314 +#: commands/functioncmds.c:1470 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "å…ƒã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã‚ã‚‹ãŸã‚ã€ã‚­ãƒ£ã‚¹ãƒˆã¯ç„¡è¦–ã•れã¾ã™" -#: commands/functioncmds.c:1319 +#: commands/functioncmds.c:1475 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "対象ã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã‚ã‚‹ãŸã‚ã€ã‚­ãƒ£ã‚¹ãƒˆã¯ç„¡è¦–ã•れã¾ã™" -#: commands/functioncmds.c:1346 +#: commands/functioncmds.c:1500 #, c-format msgid "cast function must take one to three arguments" -msgstr "キャスト関数ã®å¼•æ•°ã¯1ã¤ã‹ã‚‰3ã¤ã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "キャスト関数ã®å¼•æ•°ã¯1ã¤ã‹ã‚‰3ã¤ã¾ã§ã§ã™" -#: commands/functioncmds.c:1350 +#: commands/functioncmds.c:1504 #, c-format msgid "argument of cast function must match or be binary-coercible from source data type" -msgstr "キャスト関数ã®å¼•æ•°ã¯å¤‰æ›å…ƒãƒ‡ãƒ¼ã‚¿åž‹ã¨ä¸€è‡´ã™ã‚‹ã‹ã€ã¾ãŸã¯ãƒã‚¤ãƒŠãƒªåž‹ã‚’å¼·è¦ã§ããªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "キャスト関数ã®å¼•æ•°ã¯å¤‰æ›å…ƒãƒ‡ãƒ¼ã‚¿åž‹ã¨åŒä¸€ã§ã‚ã‚‹ã‹ã€å¤‰æ›å…ƒãƒ‡ãƒ¼ã‚¿åž‹ã‹ã‚‰ãƒã‚¤ãƒŠãƒªå¤‰æ›å¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/functioncmds.c:1354 +#: commands/functioncmds.c:1508 #, c-format -msgid "second argument of cast function must be type integer" -msgstr "キャスト関数ã®ç¬¬2å¼•æ•°ã¯æ•´æ•°åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "second argument of cast function must be type %s" +msgstr "キャスト関数ã®ç¬¬2引数ã¯%såž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:1358 +#: commands/functioncmds.c:1513 #, c-format -msgid "third argument of cast function must be type boolean" -msgstr "キャスト関数ã®ç¬¬3引数ã¯è«–ç†åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "third argument of cast function must be type %s" +msgstr "キャスト関数ã®ç¬¬3引数ã¯%såž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:1362 +#: commands/functioncmds.c:1518 #, c-format msgid "return data type of cast function must match or be binary-coercible to target data type" -msgstr "ã‚­ãƒ£ã‚¹ãƒˆé–¢æ•°ã®æˆ»ã‚Šå€¤ãƒ‡ãƒ¼ã‚¿åž‹ã¯å¤‰æ›å¾Œãƒ‡ãƒ¼ã‚¿åž‹ã¨ä¸€è‡´ã™ã‚‹ã‹ã€ã¾ãŸã¯ãƒã‚¤ãƒŠãƒªåž‹ã‚’å¼·è¦ã§ããªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã‚­ãƒ£ã‚¹ãƒˆé–¢æ•°ã®æˆ»ã‚Šå€¤ãƒ‡ãƒ¼ã‚¿åž‹ã¯å¤‰æ›å…ˆãƒ‡ãƒ¼ã‚¿åž‹ã¨ä¸€è‡´ã™ã‚‹ã‹ã€å¤‰æ›å…ˆãƒ‡ãƒ¼ã‚¿åž‹ã¸ãƒã‚¤ãƒŠãƒªå¤‰æ›å¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/functioncmds.c:1373 +#: commands/functioncmds.c:1529 #, c-format msgid "cast function must not be volatile" msgstr "キャスト関数ã¯volatileã§ã¯ã„ã‘ã¾ã›ã‚“" -#: commands/functioncmds.c:1378 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "キャスト関数ã¯é›†ç´„関数ã§ã¯ã„ã‘ã¾ã›ã‚“" - -#: commands/functioncmds.c:1382 +#: commands/functioncmds.c:1534 #, c-format -msgid "cast function must not be a window function" -msgstr "キャスト関数ã¯é›†ç´„関数ã§ã¯ã„ã‘ã¾ã›ã‚“" +msgid "cast function must be a normal function" +msgstr "キャスト関数ã¯é€šå¸¸ã®é–¢æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:1386 +#: commands/functioncmds.c:1538 #, c-format msgid "cast function must not return a set" msgstr "キャスト関数ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: commands/functioncmds.c:1412 +#: commands/functioncmds.c:1564 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" -msgstr "WITHOUT FUNCTIONå¥ä»˜ãã®ã‚­ãƒ£ã‚¹ãƒˆã‚’作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "WITHOUT FUNCTION指定ã®ã‚­ãƒ£ã‚¹ãƒˆã‚’作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/functioncmds.c:1427 +#: commands/functioncmds.c:1579 #, c-format msgid "source and target data types are not physically compatible" msgstr "変æ›å…ƒã¨å¤‰æ›å…ˆã®ãƒ‡ãƒ¼ã‚¿åž‹ã®é–“ã«ã¯ç‰©ç†çš„ãªäº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:1442 +#: commands/functioncmds.c:1594 #, c-format msgid "composite data types are not binary-compatible" msgstr "複åˆãƒ‡ãƒ¼ã‚¿åž‹ã¯ãƒã‚¤ãƒŠãƒªäº’æ›ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:1448 +#: commands/functioncmds.c:1600 #, c-format msgid "enum data types are not binary-compatible" msgstr "列挙データ型ã¯ãƒã‚¤ãƒŠãƒªäº’æ›ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:1454 +#: commands/functioncmds.c:1606 #, c-format msgid "array data types are not binary-compatible" msgstr "é…列データ型ã¯ãƒã‚¤ãƒŠãƒªäº’æ›ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:1471 +#: commands/functioncmds.c:1623 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "ドメインデータ型ã¯ãƒã‚¤ãƒŠãƒªäº’æ›ã¨ã—ã¦ãƒžãƒ¼ã‚¯ã•れã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/functioncmds.c:1481 +#: commands/functioncmds.c:1633 #, c-format msgid "source data type and target data type are the same" msgstr "変æ›å…ƒã¨å¤‰æ›å…ˆã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒåŒä¸€ã§ã™" -#: commands/functioncmds.c:1514 +#: commands/functioncmds.c:1666 #, c-format msgid "cast from type %s to type %s already exists" msgstr "åž‹%sã‹ã‚‰åž‹%sã¸ã®ã‚­ãƒ£ã‚¹ãƒˆã¯ã™ã§ã«å­˜åœ¨ã—ã¦ã„ã¾ã™" -#: commands/functioncmds.c:1589 +#: commands/functioncmds.c:1739 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "åž‹%sã‹ã‚‰åž‹%sã¸ã®ã‚­ãƒ£ã‚¹ãƒˆã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/functioncmds.c:1638 +#: commands/functioncmds.c:1778 +#, c-format +msgid "transform function must not be volatile" +msgstr "変æ›é–¢æ•°ã¯volatileã§ã¯ã„ã‘ã¾ã›ã‚“" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "transform function must be a normal function" +msgstr "変æ›é–¢æ•°ã¯é€šå¸¸ã®é–¢æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/functioncmds.c:1786 +#, c-format +msgid "transform function must not return a set" +msgstr "変æ›é–¢æ•°ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" + +#: commands/functioncmds.c:1790 +#, c-format +msgid "transform function must take one argument" +msgstr "変æ›é–¢æ•°ã¯å¼•æ•°ã‚’1ã¤ã¨ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/functioncmds.c:1794 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "変æ›é–¢æ•°ã®ç¬¬1引数ã¯%såž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/functioncmds.c:1832 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "データ型%sã¯æ“¬ä¼¼åž‹ã§ã™" + +#: commands/functioncmds.c:1838 +#, c-format +msgid "data type %s is a domain" +msgstr "データ型%sã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã™" + +#: commands/functioncmds.c:1878 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQLé–¢æ•°ã®æˆ»ã‚Šå€¤ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯%sã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/functioncmds.c:1904 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "TO SQLé–¢æ•°ã®æˆ»ã‚Šå€¤ãƒ‡ãƒ¼ã‚¿åž‹ã¯ã“ã®å¤‰æ›é–¢æ•°ã®ãƒ‡ãƒ¼ã‚¿åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: commands/functioncmds.c:1931 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "åž‹%sã€è¨€èªž\"%s\"ã®å¤‰æ›ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/functioncmds.c:2020 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "åž‹%sã€è¨€èªž\"%s\"ã®å¤‰æ›ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/functioncmds.c:2071 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "関数%sã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«å­˜åœ¨ã—ã¾ã™" -#: commands/functioncmds.c:1691 +#: commands/functioncmds.c:2126 #, c-format msgid "no inline code specified" msgstr "ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³ã‚³ãƒ¼ãƒ‰ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" -#: commands/functioncmds.c:1736 +#: commands/functioncmds.c:2172 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "言語 \"%s\" ã§ã¯ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³ã‚³ãƒ¼ãƒ‰å®Ÿè¡Œã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/indexcmds.c:160 commands/indexcmds.c:481 -#: commands/opclasscmds.c:364 commands/opclasscmds.c:784 -#: commands/opclasscmds.c:1743 +#: commands/functioncmds.c:2284 #, c-format -msgid "access method \"%s\" does not exist" -msgstr "アクセスメソッド\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "プロシージャã«ã¯ %d 個以上ã®å¼•数を渡ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr[1] "プロシージャã«ã¯ %d 個以上ã®å¼•数を渡ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/indexcmds.c:339 +#: commands/indexcmds.c:393 #, c-format msgid "must specify at least one column" msgstr "å°‘ãªãã¨ã‚‚1ã¤ã®åˆ—を指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/indexcmds.c:343 +#: commands/indexcmds.c:397 #, c-format msgid "cannot use more than %d columns in an index" msgstr "インデックスã«ã¯%dã‚’è¶…ãˆã‚‹åˆ—を使用ã§ãã¾ã›ã‚“" -#: commands/indexcmds.c:370 +#: commands/indexcmds.c:437 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "外部テーブル \"%s\" ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’作æˆã§ãã¾ã›ã‚“" -#: commands/indexcmds.c:385 +#: commands/indexcmds.c:462 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "パーティションテーブル\"%s\"ã«ã¯ CREATE INDEX CONCURRENTLY ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/indexcmds.c:467 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "パーティションテーブル \"%s\" ã«ã¯æŽ’他制約を作æˆã§ãã¾ã›ã‚“" + +#: commands/indexcmds.c:477 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルã«å¯¾ã™ã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’作æˆã§ãã¾ã›ã‚“" -#: commands/indexcmds.c:440 commands/tablecmds.c:522 commands/tablecmds.c:8961 +#: commands/indexcmds.c:542 commands/tablecmds.c:615 commands/tablecmds.c:10953 +#: commands/tablecmds.c:11087 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "共有リレーションã®ã¿ã‚’pg_globalãƒ†ãƒ¼ãƒ–ãƒ«ç©ºé–“ã«æ ¼ç´ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: commands/indexcmds.c:473 +#: commands/indexcmds.c:575 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "å¤ã„メソッド\"rtree\"をアクセスメソッド\"gist\"ã«ç½®æ›ã—ã¦ã„ã¾ã™" -#: commands/indexcmds.c:490 +#: commands/indexcmds.c:593 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "アクセスメソッド \"%s\" ã§ã¯ä¸€æ„性インデックスをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/indexcmds.c:495 +#: commands/indexcmds.c:598 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "アクセスメソッド \"%s\" ã§ã¯åŒ…å«åˆ—をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: commands/indexcmds.c:603 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "アクセスメソッド\"%s\"ã¯è¤‡æ•°åˆ—インデックスをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: commands/indexcmds.c:500 +#: commands/indexcmds.c:608 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "アクセスメソッド \"%s\" ã¯æŽ’é™¤åˆ¶ç´„ã‚’ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/indexcmds.c:579 +#: commands/indexcmds.c:720 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "パーティションキー定義ã§ã¯ %s 制約ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: commands/indexcmds.c:722 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "%s 制約ã¯ãƒ‘ーティションキーãŒå¼ã‚’å«ã‚€å ´åˆã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/indexcmds.c:740 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "%s 制約定義内ã®åˆ—ãŒè¶³ã‚Šã¾ã›ã‚“" + +#: commands/indexcmds.c:742 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "テーブル \"%2$s\" 上㮠%1$s制約ã«ãƒ‘ーティションキーã®ä¸€éƒ¨ã§ã‚る列 \"%3$s\" ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“。" + +#: commands/indexcmds.c:761 commands/indexcmds.c:781 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "システム列ã¸ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ä½œæˆã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/indexcmds.c:806 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%1$s %2$sã¯ãƒ†ãƒ¼ãƒ–ル\"%4$s\"ã«æš—黙的ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%3$s\"を作æˆã—ã¾ã™" -#: commands/indexcmds.c:935 +#: commands/indexcmds.c:1402 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "インデックスã®è¿°éƒ¨ã®é–¢æ•°ã¯IMMUTABLEマークãŒå¿…è¦ã§ã™" -#: commands/indexcmds.c:1001 parser/parse_utilcmd.c:1795 +#: commands/indexcmds.c:1468 parser/parse_utilcmd.c:2237 +#: parser/parse_utilcmd.c:2361 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "キーã¨ã—ã¦æŒ‡åã•れãŸåˆ—\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/indexcmds.c:1061 +#: commands/indexcmds.c:1492 parser/parse_utilcmd.c:1586 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "包å«åˆ—ã§ã¯å¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: commands/indexcmds.c:1533 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®é–¢æ•°ã¯IMMUTABLEマークãŒå¿…è¦ã§ã™" -#: commands/indexcmds.c:1084 +#: commands/indexcmds.c:1548 +#, c-format +msgid "including column does not support a collation" +msgstr "包å«åˆ—ã¯ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: commands/indexcmds.c:1552 +#, c-format +msgid "including column does not support an operator class" +msgstr "包å«åˆ—ã¯æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: commands/indexcmds.c:1556 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "包å«åˆ—㯠ASC/DESC オプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: commands/indexcmds.c:1560 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "包å«åˆ—㯠NULLS FIRST/LAST オプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: commands/indexcmds.c:1587 #, c-format msgid "could not determine which collation to use for index expression" msgstr "インデックスå¼ã§ä½¿ç”¨ã™ã‚‹ç…§åˆé †åºã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: commands/indexcmds.c:1092 commands/typecmds.c:781 parser/parse_expr.c:2275 -#: parser/parse_type.c:499 parser/parse_utilcmd.c:2668 utils/adt/misc.c:527 +#: commands/indexcmds.c:1595 commands/tablecmds.c:13887 commands/typecmds.c:833 +#: parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3392 +#: utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "%s åž‹ã§ã¯ç…§åˆé †åºã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: commands/indexcmds.c:1130 +#: commands/indexcmds.c:1633 #, c-format msgid "operator %s is not commutative" -msgstr "æ¼”ç®—å­ %s ã¯äº¤æ›å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "æ¼”ç®—å­ %s ã¯å¯æ›ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/indexcmds.c:1132 +#: commands/indexcmds.c:1635 #, c-format msgid "Only commutative operators can be used in exclusion constraints." -msgstr "排除制約ã§ä½¿ãˆã‚‹ã®ã¯äº¤æ›æ¼”ç®—å­ã ã‘ã§ã™" +msgstr "排除制約ã§ä½¿ãˆã‚‹ã®ã¯å¯æ›æ¼”ç®—å­ã ã‘ã§ã™" -#: commands/indexcmds.c:1158 +#: commands/indexcmds.c:1661 #, c-format msgid "operator %s is not a member of operator family \"%s\"" -msgstr "æ¼”ç®—å­ %s ã¯æ¼”ç®—å­ãƒ•ァミリー \"%s\" ã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "演算å­%sã¯æ¼”ç®—å­æ—\"%s\"ã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/indexcmds.c:1161 +#: commands/indexcmds.c:1664 #, c-format msgid "The exclusion operator must be related to the index operator class for the constraint." -msgstr "ã“ã®åˆ¶ç´„æ¡ä»¶ã«ã¤ã„ã¦ã¯ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã«å¯¾ã—ã¦æŽ’é™¤åˆ¶ç´„ãŒé–¢é€£ä»˜ã‘られãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã“ã®æŽ’é™¤ã«ä½¿ç”¨ã™ã‚‹æ¼”ç®—å­ã¯ã“ã®åˆ¶ç´„ã«ä½¿ç”¨ã™ã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹æ¼”ç®—å­ã«é–¢é€£ä»˜ã‘られã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/indexcmds.c:1196 +#: commands/indexcmds.c:1699 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "アクセスメソッド\"%s\"ã¯ASC/DESCオプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: commands/indexcmds.c:1201 +#: commands/indexcmds.c:1704 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "アクセスメソッド\"%s\"ã¯NULLS FIRST/LASTオプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: commands/indexcmds.c:1257 commands/typecmds.c:1886 +#: commands/indexcmds.c:1763 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"ã«ã¯ãƒ‡ãƒ¼ã‚¿åž‹%1$s用ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ãŒã‚りã¾ã›ã‚“" -#: commands/indexcmds.c:1259 +#: commands/indexcmds.c:1765 #, c-format msgid "You must specify an operator class for the index or define a default operator class for the data type." -msgstr "ã“ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ç”¨ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã€ã‚ã‚‹ã„ã¯ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã®ãƒ‡ãƒ•ォルト演算å­ã‚¯ãƒ©ã‚¹ã‚’定義ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã“ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã‹ã€ã‚ã‚‹ã„ã¯ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã®ãƒ‡ãƒ•ォルト演算å­ã‚¯ãƒ©ã‚¹ã‚’定義ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: commands/indexcmds.c:1288 commands/indexcmds.c:1296 -#: commands/opclasscmds.c:208 +#: commands/indexcmds.c:1794 commands/indexcmds.c:1802 +#: commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/indexcmds.c:1309 commands/typecmds.c:1874 +#: commands/indexcmds.c:1815 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "演算å­ã‚¯ãƒ©ã‚¹\"%s\"ã¯ãƒ‡ãƒ¼ã‚¿åž‹%sã‚’å—ã‘付ã‘ã¾ã›ã‚“" -#: commands/indexcmds.c:1399 +#: commands/indexcmds.c:1905 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "データ型%sã«ã¯è¤‡æ•°ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ãŒã‚りã¾ã™" -#: commands/indexcmds.c:1775 +#: commands/indexcmds.c:2320 #, c-format msgid "table \"%s\" has no indexes" msgstr "テーブル\"%s\"ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯ã‚りã¾ã›ã‚“" -#: commands/indexcmds.c:1805 +#: commands/indexcmds.c:2375 #, c-format msgid "can only reindex the currently open database" -msgstr "ç¾åœ¨ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るデータベースã®ã¿ã‚’å†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ä»˜ã‘ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" +msgstr "ç¾åœ¨ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るデータベースã®ã¿ã‚’å†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: commands/indexcmds.c:1893 +#: commands/indexcmds.c:2493 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "テーブル\"%s.%s\"ã¯å†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹åŒ–ã•れã¾ã—ãŸ" -#: commands/matview.c:173 +#: commands/indexcmds.c:2515 #, c-format -msgid "CONCURRENTLY cannot be used when the materialized view is not populated" -msgstr "マテリアライズドビューã«ãƒ‡ãƒ¼ã‚¿ãŒæŠ•å…¥ã•れã¦ã„ãªã„時ã«CONCURRENTLYを使用ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "パーティションインデックスã«å¯¾ã™ã‚‹ REINDEX ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: commands/lockcmds.c:100 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã§ã‚‚ビューã§ã‚‚ã‚りã¾ã›ã‚“" + +#: commands/lockcmds.c:224 rewrite/rewriteHandler.c:1836 +#: rewrite/rewriteHandler.c:3532 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "リレーション\"%s\"ã®ãƒ«ãƒ¼ãƒ«ã§ç„¡é™å†å¸°ã‚’検出ã—ã¾ã—ãŸ" #: commands/matview.c:179 #, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "実体化ビューã«ãƒ‡ãƒ¼ã‚¿ãŒæŠ•å…¥ã•れã¦ã„ãªã„å ´åˆã¯CONCURRENTLYを使用ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/matview.c:185 +#, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "CONCURRENTLYã¨WITH NO DATAã‚ªãƒ—ã‚·ãƒ§ãƒ³ã‚’åŒæ™‚ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/matview.c:575 +#: commands/matview.c:244 #, c-format -msgid "new data for \"%s\" contains duplicate rows without any NULL columns" -msgstr "\"%s\"ã«å¯¾ã™ã‚‹æ–°ã—ã„データã«ã¯NULL列をæŒãŸãªã„é‡è¤‡è¡ŒãŒã‚りã¾ã™" +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "実体化ビュー\"%s\"ã‚’å¹³è¡Œçš„ã«æœ€æ–°åŒ–ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/matview.c:577 +#: commands/matview.c:247 #, c-format -#| msgid "%s: %s" -msgid "Row: %s" -msgstr "行: %s" +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "実体化ビュー上ã®1ã¤ä»¥ä¸Šã®åˆ—ã«å¯¾ã—ã¦WHEREå¥ã‚’æŒãŸãªã„UNIQUEインデックスを作æˆã—ã¦ãã ã•ã„。" -#: commands/matview.c:680 +#: commands/matview.c:645 #, c-format -#| msgid "Unlogged materialized view \"%s.%s\"" -msgid "cannot refresh materialized view \"%s\" concurrently" -msgstr "マテリアライズドビュー \"%s\"ã‚’åŒæ™‚ã«æ›´æ–°ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "実体化ビュー\"%s\"ã«å¯¾ã™ã‚‹æ–°ã—ã„データã«ã¯NULL列をæŒãŸãªã„é‡è¤‡è¡ŒãŒã‚りã¾ã™" -#: commands/matview.c:682 +#: commands/matview.c:647 #, c-format -msgid "Create a UNIQUE index with no WHERE clause on one or more columns of the materialized view." -msgstr "マテリアライズドビュー上ã®ï¼‘ã¤ä»¥ä¸Šã®åˆ—ã«å¯¾ã—ã¦WHEREå¥ã‚’æŒãŸãªã„UNIQUEインデックスを作æˆã—ã¾ã™ã€‚" +msgid "Row: %s" +msgstr "行: %s" -#: commands/opclasscmds.c:132 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­æ—\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/opclasscmds.c:267 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" @@ -5836,263 +7611,318 @@ msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ã™ã§ã«å­˜ #: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" -msgstr "演算å­ã‚¯ãƒ©ã‚¹ã‚’作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "演算å­ã‚¯ãƒ©ã‚¹ã‚’作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:474 commands/opclasscmds.c:860 -#: commands/opclasscmds.c:990 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 +#: commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" -msgstr "演算å­ç•ªå·%dãŒç„¡åйã§ã™ã€‚1ã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "演算å­ç•ªå·%dãŒä¸æ­£ã§ã™ã€‚1ã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:525 commands/opclasscmds.c:911 -#: commands/opclasscmds.c:1005 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 +#: commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "プロシージャ番å·%dãŒç„¡åйã§ã™ã€‚1ã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "演算å­ç•ªå·%dãŒä¸æ­£ã§ã™ã€1ã¨%dã®é–“ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:555 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "æ ¼ç´åž‹ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: commands/opclasscmds.c:582 +#: commands/opclasscmds.c:576 #, c-format msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "アクセスメソッド\"%s\"用ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¨ç•°ãªã‚‹æ ¼ç´åž‹ã‚’使用ã§ãã¾ã›ã‚“" -#: commands/opclasscmds.c:598 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "アクセスメソッド\"%2$s\"ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/opclasscmds.c:626 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "演算å­ã‚¯ãƒ©ã‚¹\"%s\"ã‚’åž‹%sã®ãƒ‡ãƒ•ォルトã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: commands/opclasscmds.c:629 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "演算å­ã‚¯ãƒ©ã‚¹\"%s\"ã¯ã™ã§ã«ãƒ‡ãƒ•ォルトã§ã™ã€‚" -#: commands/opclasscmds.c:754 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" -msgstr "æ¼”ç®—å­æ—を作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æ¼”ç®—å­æ—を作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:810 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" -msgstr "æ¼”ç®—å­æ—を変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æ¼”ç®—å­æ—ã‚’æ›´æ–°ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:876 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" -msgstr "演算å­ã®å¼•æ•°åž‹ã¯ALTER OPERATOR FAMILYã§æŒ‡å®šã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ALTER OPERATOR FAMILYã§ã¯æ¼”ç®—å­ã®å¼•æ•°åž‹ã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: commands/opclasscmds.c:940 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "ALTER OPERATOR FAMILYã§ã¯STORAGEを指定ã§ãã¾ã›ã‚“" -#: commands/opclasscmds.c:1056 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" -msgstr "1ã¾ãŸã¯2ã¤ã®å¼•æ•°åž‹ãŒæŒ‡å®šã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "1ã¾ãŸã¯2ã¤ã®å¼•æ•°åž‹ãŒæŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:1082 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "インデックス演算å­ã¯äºŒé …演算å­ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:1107 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "アクセスメソッド \"%s\" ã¯ä¸¦ã¹æ›¿ãˆæ¼”ç®—å­ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/opclasscmds.c:1120 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" -msgstr "インデックス検索演算å­ã¯ãƒ–ール型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "インデックス検索演算å­ã¯ãƒ–ール型を返ã™å¿…è¦ãŒã‚りã¾ã™" + +#: commands/opclasscmds.c:1144 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree比較関数ã¯2ã¤ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1148 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "btree比較プロシージャã¯2ã¤ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "btree comparison functions must return integer" +msgstr "btreeæ¯”è¼ƒé–¢æ•°ã¯æ•´æ•°ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1165 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "btreeæ¯”è¼ƒãƒ—ãƒ­ã‚·ãƒ¼ã‚¸ãƒ£ã¯æ•´æ•°ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btreeソートサãƒãƒ¼ãƒˆé–¢æ•°ã¯\"internal\"型をå–らãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:1183 +#: commands/opclasscmds.c:1169 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "btreeソートサãƒãƒ¼ãƒˆãƒ—ロシージャã¯\"internal\"型をå—付ã‘ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "btree sort support functions must return void" +msgstr "btreeソートサãƒãƒ¼ãƒˆé–¢æ•°ã¯voidã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/opclasscmds.c:1187 +#: commands/opclasscmds.c:1180 #, c-format -msgid "btree sort support procedures must return void" -msgstr "btreeソートサãƒãƒ¼ãƒˆãƒ—ロシージャã¯voidã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "btree in_range functions must have five arguments" +msgstr "btree in_range 関数ã¯5ã¤ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:1199 +#: commands/opclasscmds.c:1184 #, c-format -msgid "hash procedures must have one argument" -msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ—ロシージャã¯1ã¤ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "btree in_range functions must return boolean" +msgstr "btree in_range 関数ã¯ãƒ–ール型を返ã™å¿…è¦ãŒã‚りã¾ã™" #: commands/opclasscmds.c:1203 #, c-format -msgid "hash procedures must return integer" -msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ—ãƒ­ã‚·ãƒ¼ã‚¸ãƒ£ã¯æ•´æ•°ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "hash function 1 must have one argument" +msgstr "ãƒãƒƒã‚·ãƒ¥é–¢æ•°1ã¯å¼•æ•°ã‚’1ã¤å–ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/opclasscmds.c:1207 +#, c-format +msgid "hash function 1 must return integer" +msgstr "ãƒãƒƒã‚·ãƒ¥é–¢æ•°1ã¯æ•´æ•°ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" + +#: commands/opclasscmds.c:1214 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "ãƒãƒƒã‚·ãƒ¥é–¢æ•°2ã¯2ã¤ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/opclasscmds.c:1218 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "ãƒãƒƒã‚·ãƒ¥é–¢æ•°2㯠bigint ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:1227 +#: commands/opclasscmds.c:1243 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "関連ã™ã‚‹ãƒ‡ãƒ¼ã‚¿åž‹ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚µãƒãƒ¼ãƒˆãƒ—ãƒ­ã‚·ãƒ¼ã‚¸ãƒ£ã§æŒ‡å®šã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "associated data types must be specified for index support function" +msgstr "インデックスサãƒãƒ¼ãƒˆé–¢æ•°ã«å¯¾ã—ã¦é–¢é€£ãƒ‡ãƒ¼ã‚¿åž‹ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/opclasscmds.c:1252 +#: commands/opclasscmds.c:1268 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "(%2$s,%3$s)用ã®ãƒ—ロシージャ番å·%1$dãŒè¤‡æ•°ã‚りã¾ã™" +msgid "function number %d for (%s,%s) appears more than once" +msgstr "(%2$s,%3$s)ã«å¯¾å¿œã™ã‚‹æ¼”ç®—å­ç•ªå·%1$dãŒè¤‡æ•°ã‚りã¾ã™" -#: commands/opclasscmds.c:1259 +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "(%2$s,%3$s)ç”¨ã®æ¼”ç®—å­ç•ªå·%1$dãŒè¤‡æ•°ã‚りã¾ã™" -#: commands/opclasscmds.c:1308 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "演算å­%d(%s,%s)ã¯ã™ã§ã«æ¼”ç®—å­æ—\"%s\"ã«å­˜åœ¨ã—ã¾ã™" -#: commands/opclasscmds.c:1424 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "関数%d(%s,%s)ã¯ã™ã§ã«æ¼”ç®—å­æ—\"%s\"内ã«å­˜åœ¨ã—ã¾ã™" -#: commands/opclasscmds.c:1514 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "演算å­%d(%s,%s)ã¯æ¼”ç®—å­æ—\"%s\"内ã«ã‚りã¾ã›ã‚“" -#: commands/opclasscmds.c:1554 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "関数%d(%s,%s)ã¯æ¼”ç®—å­æ—\"%s\"内ã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/opclasscmds.c:1699 +#: commands/opclasscmds.c:1696 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%3$s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/opclasscmds.c:1722 +#: commands/opclasscmds.c:1719 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "アクセスメソッド\"%2$s\"ç”¨ã®æ¼”ç®—å­æ—\"%1$s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%3$s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/operatorcmds.c:97 -#, c-format -msgid "=> is deprecated as an operator name" -msgstr ">= ã¯æ¼”ç®—å­åã¨ã—ã¦å»ƒæ­¢äºˆå®šã§ã‚ã‚Šã€æŽ¨å¥¨ã•れã¾ã›ã‚“" - -#: commands/operatorcmds.c:98 -#, c-format -msgid "This name may be disallowed altogether in future versions of PostgreSQL." -msgstr "PostgreSQL ã®å°†æ¥ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã€ã“ã®åå‰ãŒä½¿ãˆãªããªã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™" - -#: commands/operatorcmds.c:119 commands/operatorcmds.c:127 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "演算å­ã®å¼•æ•°ã«ã¯SETOF型を使用ã§ãã¾ã›ã‚“" -#: commands/operatorcmds.c:155 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "演算å­ã®å±žæ€§\"%s\"ã¯ä¸æ˜Žã§ã™" #: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "演算å­ã®ãƒ—ロシージャを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "operator function must be specified" +msgstr "演算å­é–¢æ•°ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" #: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" -msgstr "å°‘ãªãã¨ã‚‚å³è¾ºã‹å·¦è¾ºã®ã©ã¡ã‚‰ã‹ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "å·¦å³è¾ºã®ã†ã¡å°‘ãªãã¨ã‚‚ã©ã¡ã‚‰ã‹ä¸€æ–¹ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/operatorcmds.c:244 +#: commands/operatorcmds.c:280 #, c-format -msgid "restriction estimator function %s must return type \"float8\"" -msgstr "制約推測用関数 %s 㯠\"float8\" 型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "restriction estimator function %s must return type %s" +msgstr "制約推定関数 %s 㯠%s型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/operatorcmds.c:283 +#: commands/operatorcmds.c:326 #, c-format -msgid "join estimator function %s must return type \"float8\"" -msgstr "JOIN 推測用関数 %s 㯠\"float8\" 型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "join estimator function %s must return type %s" +msgstr "JOIN推定関数 %s 㯠%s型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/portalcmds.c:61 commands/portalcmds.c:160 -#: commands/portalcmds.c:212 +#: commands/operatorcmds.c:451 #, c-format -msgid "invalid cursor name: must not be empty" -msgstr "カーソルåãŒç„¡åйã§ã™: 空ã§ã¯ã„ã‘ã¾ã›ã‚“" +msgid "operator attribute \"%s\" cannot be changed" +msgstr "演算å­ã®å±žæ€§\"%s\"ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/portalcmds.c:168 commands/portalcmds.c:222 -#: executor/execCurrent.c:67 utils/adt/xml.c:2395 utils/adt/xml.c:2562 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 +#: commands/tablecmds.c:1276 commands/tablecmds.c:1736 +#: commands/tablecmds.c:2723 commands/tablecmds.c:4967 +#: commands/tablecmds.c:7374 commands/tablecmds.c:13520 +#: commands/tablecmds.c:13555 commands/trigger.c:316 commands/trigger.c:1526 +#: commands/trigger.c:1635 rewrite/rewriteDefine.c:272 +#: rewrite/rewriteDefine.c:924 #, c-format -msgid "cursor \"%s\" does not exist" -msgstr "カーソル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "permission denied: \"%s\" is a system catalog" +msgstr "権é™ãŒã‚りã¾ã›ã‚“: \"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ã§ã™" -#: commands/portalcmds.c:341 tcop/pquery.c:740 tcop/pquery.c:1404 +#: commands/policy.c:170 #, c-format -msgid "portal \"%s\" cannot be run" -msgstr "ãƒãƒ¼ã‚¿ãƒ«\"%s\"を実行ã§ãã¾ã›ã‚“" +msgid "ignoring specified roles other than PUBLIC" +msgstr "PUBLICä»¥å¤–ã®æŒ‡å®šã•れãŸãƒ­ãƒ¼ãƒ«ã‚’無視ã—ã¾ã™" -#: commands/portalcmds.c:415 +#: commands/policy.c:171 #, c-format -msgid "could not reposition held cursor" -msgstr "ä¿æŒã—ãŸã‚«ãƒ¼ã‚½ãƒ«ã®ä½ç½®ã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "All roles are members of the PUBLIC role." +msgstr "å…¨ã¦ã®ãƒ­ãƒ¼ãƒ«ãŒPUBLICロールã®ãƒ¡ãƒ³ãƒãƒ¼ã§ã™ã€‚" -#: commands/prepare.c:71 +#: commands/policy.c:514 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "ロール\"%s\"ã¯\"%s\"ã«å¯¾ã™ã‚‹ãƒãƒªã‚·\"%s\"ã‹ã‚‰ã¯å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: commands/policy.c:720 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "SELECTã¾ãŸã¯DELETEã«ã¯ WITH CHECK ã‚’é©ç”¨ã§ãã¾ã›ã‚“" + +#: commands/policy.c:729 commands/policy.c:1027 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "INSERTã§ã¯WITH CHECKå¼ã®ã¿ãŒæŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/policy.c:802 commands/policy.c:1247 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "テーブル\"%2$s\"ã«å¯¾ã™ã‚‹ãƒãƒªã‚·\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "テーブル\"%2$s\"ã«å¯¾ã™ã‚‹ãƒãƒªã‚·\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/policy.c:1017 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "SELECTã€DELETEã«ã¯USINGå¼ã®ã¿ãŒæŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "カーソルåãŒä¸æ­£ã§ã™: 空ã§ã¯ã„ã‘ã¾ã›ã‚“" + +#: commands/portalcmds.c:190 commands/portalcmds.c:244 +#: executor/execCurrent.c:69 utils/adt/xml.c:2469 utils/adt/xml.c:2639 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "カーソル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/prepare.c:75 #, c-format msgid "invalid statement name: must not be empty" -msgstr "æ–‡ã®åå‰ã¯ç„¡åйã§ã™: 空ã§ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "䏿­£ãªæ–‡ã®åå‰: 空ã§ã¯ã„ã‘ã¾ã›ã‚“" -#: commands/prepare.c:129 parser/parse_param.c:304 tcop/postgres.c:1304 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1399 #, c-format msgid "could not determine data type of parameter $%d" msgstr "パラメータ$%dã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒæ±ºå®šã§ãã¾ã›ã‚“" -#: commands/prepare.c:147 +#: commands/prepare.c:159 #, c-format msgid "utility statements cannot be prepared" -msgstr "ユーティリティ文を準備ã§ãã¾ã›ã‚“" +msgstr "ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£æ–‡ã¯æº–å‚™ã§ãã¾ã›ã‚“" -#: commands/prepare.c:257 commands/prepare.c:264 +#: commands/prepare.c:269 commands/prepare.c:274 #, c-format msgid "prepared statement is not a SELECT" msgstr "準備ã•ã‚ŒãŸæ–‡ã¯SELECTã§ã¯ã‚りã¾ã›ã‚“" -#: commands/prepare.c:332 +#: commands/prepare.c:342 #, c-format msgid "wrong number of parameters for prepared statement \"%s\"" msgstr "準備ã•ã‚ŒãŸæ–‡\"%s\"ã®ãƒ‘ラメータ数ãŒé–“é•ã£ã¦ã„ã¾ã™" -#: commands/prepare.c:334 +#: commands/prepare.c:344 #, c-format msgid "Expected %d parameters but got %d." msgstr "%dパラメータを想定ã—ã¾ã—ãŸãŒã€%dパラメータã§ã—ãŸ" -#: commands/prepare.c:370 +#: commands/prepare.c:380 #, c-format msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "パラメータ$%dã®åž‹%sを想定ã—ã¦ã„ã‚‹åž‹%sã«å¼·åˆ¶ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/prepare.c:465 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "準備ã•ã‚ŒãŸæ–‡\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/prepare.c:504 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "準備ã•ã‚ŒãŸæ–‡\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" @@ -6105,1386 +7935,2249 @@ msgstr "CREATE LANGUAGEパラメータã®ä»£ã‚りã«pg_pltemplateã®æƒ…報を #: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" -msgstr "手続ã言語\"%s\"ã®ä½œæˆã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: commands/proclang.c:116 commands/proclang.c:278 -#, c-format -msgid "function %s must return type \"language_handler\"" -msgstr "関数%sã¯\"language_handler\"型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "手続ã言語\"%s\"を生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/proclang.c:242 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "言語\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/proclang.c:244 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "サãƒãƒ¼ãƒˆã•れã¦ã„る言語ã¯pg_pltemplateシステムカタログ内ã«åˆ—挙ã•れã¦ã„ã¾ã™" -#: commands/proclang.c:252 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" -msgstr "手続ã言語ã®ä½œæˆã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "手続ã言語を生æˆã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 +#: commands/typecmds.c:471 +#, c-format +msgid "changing return type of function %s from %s to %s" +msgstr "関数%sã®æˆ»ã‚Šå€¤åž‹ã‚’%sã‹ã‚‰%sã«å¤‰æ›´ã—ã¾ã™" + +#: commands/publicationcmds.c:109 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\"オプションã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒä¸æ­£ã§ã™" + +#: commands/publicationcmds.c:127 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "識別ã§ããªã„\"publish\"ã®å€¤: \"%s\"" + +#: commands/publicationcmds.c:133 +#, c-format +msgid "unrecognized publication parameter: %s" +msgstr "識別ã§ããªã„パブリケーションã®ãƒ‘ラメータ: \"%s\"" + +#: commands/publicationcmds.c:166 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "FOR ALL TABLE 指定ã®ãƒ‘ブリケーションを生æˆã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/proclang.c:271 +#: commands/publicationcmds.c:335 #, c-format -msgid "changing return type of function %s from \"opaque\" to \"language_handler\"" -msgstr "関数%sã®æˆ»ã‚Šå€¤åž‹ã‚’\"opaque\"ã‹ã‚‰\"language_handler\"ã«å¤‰æ›´ã—ã¦ã„ã¾ã™" +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "パブリケーション\"%s\"ã¯ã€€FOR ALL TABLES ã¨å®šç¾©ã•れã¦ã„ã¾ã™" -#: commands/schemacmds.c:84 commands/schemacmds.c:236 +#: commands/publicationcmds.c:337 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "FOR ALL TABLES指定ã®ãƒ‘ブリケーションã§ã¯ãƒ†ãƒ¼ãƒ–ルã®è¿½åŠ ã‚„å‰Šé™¤ã¯ã§ãã¾ã›ã‚“。" + +#: commands/publicationcmds.c:638 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "リレーション\"%s\"ã¯ãƒ‘ブリケーションã®ä¸€éƒ¨ã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/publicationcmds.c:681 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "パブリケーション\"%s\"ã®æ‰€æœ‰è€…を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" + +#: commands/publicationcmds.c:683 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLES設定ã®ãƒ‘ãƒ–ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã®æ‰€æœ‰è€…ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/schemacmds.c:106 commands/schemacmds.c:280 #, c-format msgid "unacceptable schema name \"%s\"" msgstr "スキーマå\"%s\"ã¯å—ã‘付ã‘られã¾ã›ã‚“" -#: commands/schemacmds.c:85 commands/schemacmds.c:237 +#: commands/schemacmds.c:107 commands/schemacmds.c:281 #, c-format msgid "The prefix \"pg_\" is reserved for system schemas." msgstr "接頭辞\"pg_\"ã¯ã‚·ã‚¹ãƒ†ãƒ ã‚¹ã‚­ãƒ¼ãƒžç”¨ã«äºˆç´„ã•れã¦ã„ã¾ã™" -#: commands/schemacmds.c:99 +#: commands/schemacmds.c:121 #, c-format -#| msgid "relation \"%s\" already exists, skipping" msgid "schema \"%s\" already exists, skipping" -msgstr "スキーマ \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚スキップã—ã¾ã™ã€‚" +msgstr "スキーマ \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/seclabel.c:58 +#: commands/seclabel.c:60 #, c-format msgid "no security label providers have been loaded" msgstr "セキュリティラベルã®ãƒ—ロãƒã‚¤ãƒ€ãŒãƒ­ãƒ¼ãƒ‰ã•れã¾ã›ã‚“ã§ã—ãŸ" -#: commands/seclabel.c:62 +#: commands/seclabel.c:64 #, c-format msgid "must specify provider when multiple security label providers have been loaded" -msgstr "複数ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ©ãƒ™ãƒ«ãƒ—ロãƒã‚¤ãƒ€ãŒãƒ­ãƒ¼ãƒ‰ã•ã‚ŒãŸæ™‚ã¯ã€ãƒ—ロãƒã‚¤ãƒ€ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "複数ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ©ãƒ™ãƒ«ãƒ—ロãƒã‚¤ãƒ€ãŒãƒ­ãƒ¼ãƒ‰ã•ã‚ŒãŸæ™‚ã¯ã€ãƒ—ロãƒã‚¤ãƒ€ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/seclabel.c:80 +#: commands/seclabel.c:82 #, c-format msgid "security label provider \"%s\" is not loaded" msgstr "セキュリティラベルプロãƒã‚¤ãƒ€\"%s\" ã¯ãƒ­ãƒ¼ãƒ‰ã•れã¦ã„ã¾ã›ã‚“" -#: commands/sequence.c:127 +#: commands/sequence.c:138 #, c-format msgid "unlogged sequences are not supported" -msgstr "ログをå–らãªã„シーケンスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" - -#: commands/sequence.c:425 commands/tablecmds.c:2294 commands/tablecmds.c:2473 -#: commands/tablecmds.c:10099 parser/parse_utilcmd.c:2359 tcop/utility.c:1041 -#, c-format -msgid "relation \"%s\" does not exist, skipping" -msgstr "リレーション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "UNLOGGEDシーケンスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" # (%s) -#: commands/sequence.c:643 +#: commands/sequence.c:697 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: シーケンス\"%s\"ã®æœ€å¤§å€¤(%s)ã«é”ã—ã¾ã—ãŸ" -#: commands/sequence.c:666 +#: commands/sequence.c:720 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: シーケンス\"%s\"ã®æœ€å°å€¤(%s)ã«é”ã—ã¾ã—ãŸ" -#: commands/sequence.c:779 +#: commands/sequence.c:838 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "本セッションã§ã‚·ãƒ¼ã‚±ãƒ³ã‚¹\"%s\"ã®currvalã¯ã¾ã å®šç¾©ã•れã¦ã„ã¾ã›ã‚“" -#: commands/sequence.c:798 commands/sequence.c:804 +#: commands/sequence.c:857 commands/sequence.c:863 #, c-format msgid "lastval is not yet defined in this session" msgstr "本セッションã§lastvalã¯ã¾ã å®šç¾©ã•れã¦ã„ã¾ã›ã‚“" -#: commands/sequence.c:873 +#: commands/sequence.c:951 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: 値%sã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹\"%s\"ã®ç¯„囲(%s..%s)外ã§ã™\"" -#: commands/sequence.c:1242 +#: commands/sequence.c:1348 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "䏿­£ãªã‚ªãƒ—ション SEQUENCE NAME" + +#: commands/sequence.c:1374 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "識別列ã®åž‹ã¯smallintã€integerã¾ãŸã¯bigintã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/sequence.c:1375 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "シーケンスã®åž‹ã¯smallintã€integerã¾ãŸã¯bigintã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/sequence.c:1409 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENTã¯ã‚¼ãƒ­ã§ã¯ã„ã‘ã¾ã›ã‚“" -#: commands/sequence.c:1298 +#: commands/sequence.c:1462 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) ã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ãƒ‡ãƒ¼ã‚¿åž‹%sã®ç¯„囲外ã§ã™" + +#: commands/sequence.c:1499 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s) ã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ãƒ‡ãƒ¼ã‚¿åž‹%sã®ç¯„囲外ã§ã™" + +#: commands/sequence.c:1513 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s)ã¯MAXVALUE (%s)よりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/sequence.c:1323 +#: commands/sequence.c:1540 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "STARTã®å€¤(%s)ã¯MINVALUE(%s)よりå°ã•ãã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/sequence.c:1335 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "STARTã®å€¤(%s)ã¯MAXVALUE(%s)より大ããã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/sequence.c:1365 +#: commands/sequence.c:1582 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "RESTART ã®å€¤(%s)㯠MINVALUE(%s) よりå°ã•ãã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/sequence.c:1377 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "RESTART ã®å€¤(%s)㯠MAXVALUE(%s) より大ããã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/sequence.c:1392 +#: commands/sequence.c:1609 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE(%s)ã¯ã‚¼ãƒ­ã‚ˆã‚Šå¤§ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/sequence.c:1424 +#: commands/sequence.c:1646 #, c-format msgid "invalid OWNED BY option" -msgstr "無効ãªOWNED BYオプションã§ã™" +msgstr "䏿­£ãªOWNED BYオプションã§ã™" -#: commands/sequence.c:1425 +#: commands/sequence.c:1647 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "OWNED BY table.column ã¾ãŸã¯ OWNED BY NONEを指定ã—ã¦ãã ã•ã„。" -#: commands/sequence.c:1448 +#: commands/sequence.c:1672 #, c-format -#| msgid "referenced relation \"%s\" is not a table" msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "å‚ç…§å…ˆã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/sequence.c:1455 +#: commands/sequence.c:1679 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "シーケンスã¯é–¢é€£ã™ã‚‹ãƒ†ãƒ¼ãƒ–ルã¨åŒã˜æ‰€æœ‰è€…ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/sequence.c:1459 +#: commands/sequence.c:1683 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "シーケンスã¯é–¢é€£ã™ã‚‹ãƒ†ãƒ¼ãƒ–ルã¨åŒã˜ã‚¹ã‚­ãƒ¼ãƒžã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/tablecmds.c:206 +#: commands/sequence.c:1705 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "è­˜åˆ¥ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®æ‰€æœ‰è€…ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/sequence.c:1706 commands/tablecmds.c:10335 +#: commands/tablecmds.c:12952 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "シーケンス\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«ãƒªãƒ³ã‚¯ã•れã¦ã„ã¾ã™" + +#: commands/statscmds.c:93 commands/statscmds.c:102 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICSã§æŒ‡å®šå¯èƒ½ãªãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯ä¸€ã¤ã®ã¿ã§ã™" + +#: commands/statscmds.c:120 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "リレーション\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルや外部テーブルã€ã¾ãŸã¯å®Ÿä½“化ビューã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/statscmds.c:163 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "統計情報オブジェクト\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/statscmds.c:171 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "統計情報オブジェクト\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" + +#: commands/statscmds.c:193 commands/statscmds.c:199 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICSã§ã¯å˜ç´”ãªåˆ—å‚ç…§ã®ã¿ãŒæŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/statscmds.c:214 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "システム列ã«å¯¾ã™ã‚‹çµ±è¨ˆæƒ…å ±ã®ä½œæˆã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/statscmds.c:221 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "列\"%s\"ã®åž‹%sã¯ãƒ‡ãƒ•ォルトã®btreeオペレータクラスをæŒãŸãªã„ãŸã‚統計情報ã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“" + +#: commands/statscmds.c:228 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "統計情報ã¯%dã‚’è¶…ãˆã‚‹åˆ—を使用ã§ãã¾ã›ã‚“" + +#: commands/statscmds.c:243 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "拡張統計情報ã«ã¯æœ€ä½Žã§ã‚‚2ã¤ã®åˆ—ãŒå¿…è¦ã§ã™" + +#: commands/statscmds.c:261 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "定形情報定義中ã®åˆ—åãŒé‡è¤‡ã—ã¦ã„ã¾ã™" + +#: commands/statscmds.c:289 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "èªè­˜ã§ããªã„統計情報種別\"%s\"" + +#: commands/subscriptioncmds.c:187 +#, c-format +msgid "unrecognized subscription parameter: %s" +msgstr "èªè­˜ã§ããªã„サブスクリプションパラメータ: %s" + +#: commands/subscriptioncmds.c:200 +#, c-format +msgid "connect = false and enabled = true are mutually exclusive options" +msgstr "connect = false 㨠enabled = true ã¯æŽ’ä»–ãªã‚ªãƒ—ションã§ã™" + +#: commands/subscriptioncmds.c:205 +#, c-format +msgid "connect = false and create_slot = true are mutually exclusive options" +msgstr "connect = false 㨠create_slot = true ã¯æŽ’ä»–ãªã‚ªãƒ—ションã§ã™" + +#: commands/subscriptioncmds.c:210 +#, c-format +msgid "connect = false and copy_data = true are mutually exclusive options" +msgstr "connect = false 㨠copy_data = true ã¯æŽ’ä»–ãªã‚ªãƒ—ションã§ã™" + +#: commands/subscriptioncmds.c:227 +#, c-format +msgid "slot_name = NONE and enabled = true are mutually exclusive options" +msgstr "slot_name = NONE 㨠enabled = true ã¯æŽ’ä»–ãªã‚ªãƒ—ションã§ã™" + +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +msgstr "slot_name = NONE 㨠create_slot = true ã¯æŽ’ä»–ãªã‚ªãƒ—ションã§ã™" + +#: commands/subscriptioncmds.c:237 +#, c-format +msgid "subscription with slot_name = NONE must also set enabled = false" +msgstr "slot_name = NONE ã¨ã—ãŸã‚µãƒ–スクリプションã§ã¯ enabled = false ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/subscriptioncmds.c:242 +#, c-format +msgid "subscription with slot_name = NONE must also set create_slot = false" +msgstr "slot_name = NONE ã¨ã—ãŸã‚µãƒ–スクリプションã§ã¯ create_slot = false ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/subscriptioncmds.c:283 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "パブリケーションå\"%s\"ãŒ2回以上使ã‚れã¦ã„ã¾ã™" + +#: commands/subscriptioncmds.c:347 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "サブスクリプションを生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 +#: replication/logical/tablesync.c:856 replication/logical/worker.c:1722 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "発行サーãƒã¸ã®æŽ¥ç¶šãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: commands/subscriptioncmds.c:469 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "発行サーãƒã§ãƒ¬ãƒ—リケーションスロット\"%s\"を作æˆã—ã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:486 +#, c-format +msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" +msgstr "テーブルã¯è³¼èª­ã•れã¦ã„ã¾ã›ã‚“ã€ãƒ†ãƒ¼ãƒ–ルを購読ã™ã‚‹ãŸã‚ã«ã¯ ALTER SUBSCRIPTION ... REFRESH PUBLICATION を実行ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/subscriptioncmds.c:576 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "テーブル\"%s.%s\"ãŒã‚µãƒ–スクリプション\"%s\"ã«è¿½åŠ ã•れã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:600 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "テーブル\"%s.%s\"ãŒã‚µãƒ–スクリプション\"%s\"ã‹ã‚‰å‰Šé™¤ã•れã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:669 +#, c-format +msgid "cannot set slot_name = NONE for enabled subscription" +msgstr "有効ã«ã•れã¦ã„るサブスクリプションã«ã¯ slot_name = NONE を指定ã§ãã¾ã›ã‚“" + +#: commands/subscriptioncmds.c:703 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "スロットåを指定ã•れã¦ã„ãªã„サブスクリプションを有効ã«ã¯ã§ãã¾ã›ã‚“" + +#: commands/subscriptioncmds.c:749 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "refresh指定ã•れ㟠ALTER SUBSCRIPTION ã¯ç„¡åŠ¹åŒ–ã•れã¦ã„るサブスクリプションã«ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false) を使ã£ã¦ãã ã•ã„。" + +#: commands/subscriptioncmds.c:768 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESHã¯ç„¡åŠ¹åŒ–ã•れã¦ã„るサブスクリプションã«ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/subscriptioncmds.c:847 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "サブスクリプション\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/subscriptioncmds.c:972 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "レプリケーションスロット\"%s\"を削除ã™ã‚‹ãŸã‚ã®ç™ºè¡Œè€…サーãƒã¸ã®æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 +#: replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 +#, c-format +msgid "The error was: %s" +msgstr "発生ã—ãŸã‚¨ãƒ©ãƒ¼: %s" + +#: commands/subscriptioncmds.c:975 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." +msgstr "サブスクリプションã®ã‚¹ãƒ­ãƒƒãƒˆã¸ã®é–¢é€£ä»˜ã‘を解除ã™ã‚‹ã«ã¯ ALTER SUBSCRIPTION ... SET (slot_name = NONE) を実行ã—ã¦ãã ã•ã„。" + +#: commands/subscriptioncmds.c:986 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "発行サーãƒä¸Šã®ãƒ¬ãƒ—リケーションスロット\"%s\"ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "発行サーãƒä¸Šã®ãƒ¬ãƒ—リケーションスロット\"%s\"を削除ã—ã¾ã—ãŸ" + +#: commands/subscriptioncmds.c:1032 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "サブスクリプション\"%s\"ã®æ‰€æœ‰è€…を変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" + +#: commands/subscriptioncmds.c:1034 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "ã‚µãƒ–ã‚¹ã‚¯ãƒªãƒ—ã‚·ãƒ§ãƒ³ã®æ‰€æœ‰è€…ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: commands/subscriptioncmds.c:1147 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "発行テーブルã®ä¸€è¦§ã‚’発行サーãƒã‹ã‚‰å—ã‘å–れã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist" msgstr "テーブル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:207 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 #, c-format msgid "table \"%s\" does not exist, skipping" -msgstr "テーブル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テーブル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:209 +#: commands/tablecmds.c:226 commands/tablecmds.c:268 msgid "Use DROP TABLE to remove a table." msgstr "テーブルを削除ã™ã‚‹ã«ã¯DROP TABLEを使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:212 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist" msgstr "シーケンス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:213 +#: commands/tablecmds.c:230 #, c-format msgid "sequence \"%s\" does not exist, skipping" -msgstr "シーケンス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "シーケンス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:215 +#: commands/tablecmds.c:232 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "シーケンスを削除ã™ã‚‹ã«ã¯DROP SEQUENCEを使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:218 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist" msgstr "ビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:219 +#: commands/tablecmds.c:236 #, c-format msgid "view \"%s\" does not exist, skipping" -msgstr "ビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "ビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:221 +#: commands/tablecmds.c:238 msgid "Use DROP VIEW to remove a view." msgstr "ビューを削除ã™ã‚‹ã«ã¯DROP VIEWを使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:224 +#: commands/tablecmds.c:241 #, c-format -#| msgid "view \"%s\" does not exist" msgid "materialized view \"%s\" does not exist" -msgstr "マテリアライズドビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "実体化ビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:225 +#: commands/tablecmds.c:242 #, c-format -#| msgid "view \"%s\" does not exist, skipping" msgid "materialized view \"%s\" does not exist, skipping" -msgstr "マテリアライズドビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "実体化ビュー\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:227 -#| msgid "Use DROP VIEW to remove a view." +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." -msgstr "マテリアライズドビューを削除ã™ã‚‹ã«ã¯DROP MATERIALIZED VIEWを使用ã—ã¦ãã ã•ã„。" +msgstr "実体化ビューを削除ã™ã‚‹ã«ã¯DROP MATERIALIZED VIEWを使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:230 parser/parse_utilcmd.c:1546 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:14918 +#: parser/parse_utilcmd.c:1982 #, c-format msgid "index \"%s\" does not exist" msgstr "インデックス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:231 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" -msgstr "インデックス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "インデックス\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "インデックスを削除ã™ã‚‹ã«ã¯DROP INDEXを使用ã—ã¦ãã ã•ã„" -#: commands/tablecmds.c:238 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" msgstr "\"%s\"ã¯åž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:239 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "型を削除ã™ã‚‹ã«ã¯DROP TYPEを使用ã—ã¦ãã ã•ã„" -#: commands/tablecmds.c:242 commands/tablecmds.c:7964 -#: commands/tablecmds.c:10031 +#: commands/tablecmds.c:259 commands/tablecmds.c:9779 +#: commands/tablecmds.c:12732 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "外部テーブル \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:243 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" -msgstr "外部テーブル \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™" +msgstr "外部テーブル \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:245 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "外部テーブルを削除ã™ã‚‹ã«ã¯ DROP FOREIGN TABLE を使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:466 +#: commands/tablecmds.c:555 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMITã¯ä¸€æ™‚テーブルã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: commands/tablecmds.c:470 parser/parse_utilcmd.c:521 -#: parser/parse_utilcmd.c:532 parser/parse_utilcmd.c:549 -#: parser/parse_utilcmd.c:611 -#, c-format -#| msgid "collations are not supported by type %s" -msgid "constraints are not supported on foreign tables" -msgstr "外部テーブルã§ã¯åˆ¶ç´„ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" - -#: commands/tablecmds.c:490 +#: commands/tablecmds.c:583 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ¼åˆ¶é™æ“作中ã¯ã€ä¸€æ™‚テーブルを作æˆã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:766 +#: commands/tablecmds.c:684 +#, c-format +msgid "cannot create table with OIDs as partition of table without OIDs" +msgstr "OIDã‚’æŒã¤ãƒ†ãƒ¼ãƒ–ルをã€OIDã‚’æŒãŸãªã„テーブルã®ãƒ‘ーティションã¨ã—ã¦ç”Ÿæˆã™ã‚‹ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:808 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\"ã¯ãƒ‘ーティションã•れã¦ã„ã¾ã›ã‚“" + +#: commands/tablecmds.c:889 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "%d以上ã®åˆ—を使ã£ãŸãƒ‘ーティションã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:1096 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLYã¯è¤‡æ•°ã‚ªãƒ–ジェクトã®å‰Šé™¤ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/tablecmds.c:770 +#: commands/tablecmds.c:1100 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLYã¯CASCADEをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: commands/tablecmds.c:915 commands/tablecmds.c:1253 -#: commands/tablecmds.c:2109 commands/tablecmds.c:4013 -#: commands/tablecmds.c:5838 commands/tablecmds.c:10647 commands/trigger.c:196 -#: commands/trigger.c:1074 commands/trigger.c:1180 rewrite/rewriteDefine.c:275 -#: rewrite/rewriteDefine.c:863 tcop/utility.c:116 +#: commands/tablecmds.c:1382 #, c-format -msgid "permission denied: \"%s\" is a system catalog" -msgstr "権é™ãŒã‚りã¾ã›ã‚“: \"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ã§ã™" +msgid "cannot truncate only a partitioned table" +msgstr "パーティションã®è¦ªãƒ†ãƒ¼ãƒ–ルã®ã¿ã®åˆ‡ã‚Šè©°ã‚ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:1383 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "ONLY キーワードを指定ã—ãªã„ã§ãã ã•ã„ã€ã‚‚ã—ãã¯å­ãƒ†ãƒ¼ãƒ–ルã«å¯¾ã—ã¦ç›´æŽ¥ TRUNCATE ONLY を実行ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:1029 +#: commands/tablecmds.c:1452 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "テーブル\"%s\"ã¸ã®ã‚«ã‚¹ã‚±ãƒ¼ãƒ‰ã‚’削除ã—ã¾ã™" -#: commands/tablecmds.c:1263 +#: commands/tablecmds.c:1746 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルを削除ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:1468 parser/parse_utilcmd.c:1758 +#: commands/tablecmds.c:1987 commands/tablecmds.c:11483 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"ã‹ã‚‰ã®ç¶™æ‰¿ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:1992 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "パーティションã®å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã‹ã‚‰ã®ç¶™æ‰¿ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:2000 parser/parse_utilcmd.c:2199 +#: parser/parse_utilcmd.c:2322 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "継承ã—よã†ã¨ã—ãŸãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:2012 #, c-format -msgid "inherited relation \"%s\" is not a table" -msgstr "継承ã•れるリレーション\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "一時リレーションを永続リレーション \"%s\" ã®å­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ä½œã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:1475 commands/tablecmds.c:9216 +#: commands/tablecmds.c:2021 commands/tablecmds.c:11462 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "一時リレーション\"%s\"ã‹ã‚‰ç¶™æ‰¿ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:1483 commands/tablecmds.c:9224 +#: commands/tablecmds.c:2031 commands/tablecmds.c:11470 #, c-format -#| msgid "cannot inherit from temporary relation \"%s\"" msgid "cannot inherit from temporary relation of another session" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚リレーションã‹ã‚‰ç¶™æ‰¿ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:1499 commands/tablecmds.c:9258 +#: commands/tablecmds.c:2048 commands/tablecmds.c:11594 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "リレーション\"%s\"ãŒè¤‡æ•°å›žç¶™æ‰¿ã•れã¾ã—ãŸ" -#: commands/tablecmds.c:1547 +#: commands/tablecmds.c:2097 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "複数ã®ç¶™æ‰¿ã•れる列\"%s\"ã®å®šç¾©ã‚’マージã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1555 +#: commands/tablecmds.c:2105 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "継承ã•れる列\"%s\"ã®åž‹ãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1557 commands/tablecmds.c:1578 -#: commands/tablecmds.c:1765 commands/tablecmds.c:1787 -#: parser/parse_coerce.c:1592 parser/parse_coerce.c:1612 -#: parser/parse_coerce.c:1632 parser/parse_coerce.c:1677 -#: parser/parse_coerce.c:1714 parser/parse_param.c:218 +#: commands/tablecmds.c:2107 commands/tablecmds.c:2130 +#: commands/tablecmds.c:2335 commands/tablecmds.c:2365 +#: parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 +#: parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 +#: parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s対%s" -#: commands/tablecmds.c:1564 +#: commands/tablecmds.c:2116 #, c-format msgid "inherited column \"%s\" has a collation conflict" -msgstr "継承ã•れる列 \"%s\" ã®ç…§åˆé †åºãŒç«¶åˆã—ã¦ã„ã¾ã™" +msgstr "継承ã•れる列 \"%s\"ã®ç…§åˆé †åºãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1566 commands/tablecmds.c:1775 -#: commands/tablecmds.c:4437 +#: commands/tablecmds.c:2118 commands/tablecmds.c:2347 +#: commands/tablecmds.c:5427 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\" 対 \"%s\"" -#: commands/tablecmds.c:1576 +#: commands/tablecmds.c:2128 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" -msgstr "継承ã•れる列 \"%s\" ã®æ ¼ç´ãƒ‘ラメーターãŒç«¶åˆã—ã¦ã„ã¾ã™" +msgstr "継承ã•れる列 \"%s\"ã®æ ¼ç´ãƒ‘ラメーターãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1688 parser/parse_utilcmd.c:852 -#: parser/parse_utilcmd.c:1193 parser/parse_utilcmd.c:1269 +#: commands/tablecmds.c:2241 commands/tablecmds.c:9287 +#: parser/parse_utilcmd.c:1116 parser/parse_utilcmd.c:1515 +#: parser/parse_utilcmd.c:1622 #, c-format msgid "cannot convert whole-row table reference" msgstr "行全体ã®ãƒ†ãƒ¼ãƒ–ルå‚照を変æ›ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:1689 parser/parse_utilcmd.c:853 +#: commands/tablecmds.c:2242 parser/parse_utilcmd.c:1117 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "制約\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã¸ã®è¡Œå…¨ä½“ã®å‚ç…§ã‚’å«ã¿ã¾ã™ã€‚" -#: commands/tablecmds.c:1755 +#: commands/tablecmds.c:2321 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "継承ã•れる定義ã§åˆ— \"%s\" をマージã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1763 +#: commands/tablecmds.c:2325 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "継承ã•れる定義ã§åˆ—\"%s\"を移動ã—ã¦ãƒžãƒ¼ã‚¸ã—ã¾ã™" + +#: commands/tablecmds.c:2326 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "ãƒ¦ãƒ¼ã‚¶ãŒæŒ‡å®šã—ãŸåˆ—ãŒç¶™æ‰¿ã—ãŸåˆ—ã®ä½ç½®ã«ç§»å‹•ã•れã¾ã—ãŸã€‚" + +#: commands/tablecmds.c:2333 #, c-format msgid "column \"%s\" has a type conflict" msgstr "列\"%s\"ã®åž‹ãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1773 +#: commands/tablecmds.c:2345 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "列 \"%s\" ã®ç…§åˆé †åºãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1785 +#: commands/tablecmds.c:2363 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "列 \"%s\" ã®æ ¼ç´ãƒ‘ラメーターãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:1837 +#: commands/tablecmds.c:2466 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "列\"%s\"ã¯ç«¶åˆã™ã‚‹ãƒ‡ãƒ•ォルト値を継承ã—ã¾ã™" -#: commands/tablecmds.c:1839 +#: commands/tablecmds.c:2468 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "ç«¶åˆã‚’解消ã™ã‚‹ã«ã¯æ˜Žç¤ºçš„ã«ãƒ‡ãƒ•ォルトを指定ã—ã¦ãã ã•ã„" -#: commands/tablecmds.c:1886 +#: commands/tablecmds.c:2515 #, c-format msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "ç•°ãªã‚‹å¼ã‚’æŒã¤æ¤œæŸ»åˆ¶ç´„å\"%s\"ãŒè¤‡æ•°ã‚りã¾ã™ã€‚" -#: commands/tablecmds.c:2080 +#: commands/tablecmds.c:2692 #, c-format msgid "cannot rename column of typed table" -msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®ã‚«ãƒ©ãƒ ã‚’リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®åˆ—をリãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:2097 +#: commands/tablecmds.c:2711 #, c-format -#| msgid "\"%s\" is not a table, view, composite type, index, or foreign table" msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" -msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€è¤‡åˆåž‹ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€å®Ÿä½“化ビューã€è¤‡åˆåž‹ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:2189 +#: commands/tablecmds.c:2805 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" -msgstr "継承ã•れる列\"%s\"ã®åå‰ã‚’å­ãƒ†ãƒ¼ãƒ–ルã§å¤‰æ›´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "継承ã•れる列\"%s\"ã®åå‰ã‚’å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚変更ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:2221 +#: commands/tablecmds.c:2837 #, c-format msgid "cannot rename system column \"%s\"" msgstr "システム列%s\"ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:2236 +#: commands/tablecmds.c:2852 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "継承ã•れる列\"%s\"ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:2383 +#: commands/tablecmds.c:3004 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" -msgstr "継承ã•れる制約\"%s\"ã®åå‰ã‚’å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚変更ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "継承ã•れる制約\"%s\"ã®åå‰ã‚’å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚変更ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:2390 +#: commands/tablecmds.c:3011 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "継承ã•れる制約\"%s\"ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2601 +#: commands/tablecmds.c:3237 #, c-format msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§å®Ÿè¡Œä¸­ã®å•ã„åˆã‚ã›ã§ä½¿ç”¨ã•れã¦ã„ã‚‹ãŸã‚ \"%2$s\" ã‚’ %1$s ã§ãã¾ã›ã‚“" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2610 +#: commands/tablecmds.c:3247 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" -msgstr "トリガイベントを待機ã—ã¦ã„ã‚‹ãŸã‚ \"%2$s\" ã‚’ %1$s ã§ãã¾ã›ã‚“" +msgstr "ä¿ç•™ä¸­ã®ãƒˆãƒªã‚¬ã‚¤ãƒ™ãƒ³ãƒˆãŒã‚ã‚‹ãŸã‚\"%2$s\"ã‚’%1$sã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:3520 +#: commands/tablecmds.c:4395 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "システムリレーション\"%sã‚’æ›¸ãæ›ãˆã‚‰ã‚Œã¾ã›ã‚“" -#: commands/tablecmds.c:3530 +#: commands/tablecmds.c:4401 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "カタログテーブルã¨ã—ã¦ä½¿ç”¨ã•れã¦ã„るテーブル\"%s\"ã¯æ›¸ãæ›ãˆã‚‰ã‚Œã¾ã›ã‚“" + +#: commands/tablecmds.c:4411 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚ãƒ†ãƒ¼ãƒ–ãƒ«ã‚’æ›¸ãæ›ãˆã‚‰ã‚Œã¾ã›ã‚“" -#: commands/tablecmds.c:3761 +#: commands/tablecmds.c:4688 #, c-format msgid "rewriting table \"%s\"" -msgstr "テーブル \"%s\" ã«å†æ›¸è¾¼ã—ã¦ã„ã¾ã™" +msgstr "テーブル\"%s\"ã«å†æ›¸è¾¼ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:3765 +#: commands/tablecmds.c:4692 #, c-format msgid "verifying table \"%s\"" -msgstr "テーブル \"%s\" を検証ã—ã¦ã„ã¾ã™" +msgstr "テーブル\"%s\"を検証ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:3873 +#: commands/tablecmds.c:4808 #, c-format msgid "column \"%s\" contains null values" msgstr "列\"%s\"ã«ã¯NULL値ãŒã‚りã¾ã™" -#: commands/tablecmds.c:3888 commands/tablecmds.c:6873 +#: commands/tablecmds.c:4824 commands/tablecmds.c:8521 #, c-format msgid "check constraint \"%s\" is violated by some row" -msgstr "一部ã®è¡Œã§æ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" +msgstr "一部ã®è¡ŒãŒæ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" + +#: commands/tablecmds.c:4842 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "デフォルトパーティションã®ä¸€éƒ¨ã®è¡ŒãŒæ›´æ–°å¾Œã®ãƒ‘ーティション制約ã«é•åã—ã¦ã„ã¾ã™" + +#: commands/tablecmds.c:4846 +#, c-format +msgid "partition constraint is violated by some row" +msgstr "一部ã®è¡ŒãŒãƒ‘ーティション制約ã«é•åã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:4034 commands/trigger.c:190 commands/trigger.c:1068 -#: commands/trigger.c:1172 rewrite/rewriteDefine.c:269 -#: rewrite/rewriteDefine.c:858 +#: commands/tablecmds.c:4988 commands/trigger.c:310 rewrite/rewriteDefine.c:266 +#: rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルやビューã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4037 +#: commands/tablecmds.c:4991 commands/trigger.c:1520 commands/trigger.c:1626 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルやビューã€ã¾ãŸã¯å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:4994 #, c-format -#| msgid "\"%s\" is not a table, view, sequence, or foreign table" msgid "\"%s\" is not a table, view, materialized view, or index" -msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€å®Ÿä½“化ビューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4043 +#: commands/tablecmds.c:5000 #, c-format -#| msgid "\"%s\" is not a table or index" msgid "\"%s\" is not a table, materialized view, or index" -msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルやマテリアライズドビューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルや実体化ビューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:5003 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルや実体化ビューã€ã¾ãŸã¯å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4046 +#: commands/tablecmds.c:5006 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルや外部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4049 +#: commands/tablecmds.c:5009 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€è¤‡åˆåž‹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4052 +#: commands/tablecmds.c:5012 commands/tablecmds.c:6430 #, c-format -#| msgid "\"%s\" is not a table, view, composite type, or foreign table" -msgid "\"%s\" is not a table, materialized view, composite type, or foreign table" -msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€è¤‡åˆåž‹ã€å¤–部テーブルã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルやインデックスã€å®Ÿä½“化ビューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4062 +#: commands/tablecmds.c:5022 #, c-format msgid "\"%s\" is of the wrong type" msgstr "\"%s\" ã¯èª¤ã£ãŸåž‹ã§ã™" -#: commands/tablecmds.c:4212 commands/tablecmds.c:4219 +#: commands/tablecmds.c:5197 commands/tablecmds.c:5204 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "åž‹\"%s\"を変更ã§ãã¾ã›ã‚“。列\"%s\".\"%s\"ã§ãã®åž‹ã‚’使用ã—ã¦ã„ã‚‹ãŸã‚ã§ã™" -#: commands/tablecmds.c:4226 +#: commands/tablecmds.c:5211 #, c-format msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "列%2$s\".\"%3$s\"ãŒãã®è¡Œåž‹ã‚’使用ã—ã¦ã„ã‚‹ãŸã‚ã€å¤–部テーブル\"%1$s\"を変更ã§ãã¾ã›ã‚“。" -#: commands/tablecmds.c:4233 +#: commands/tablecmds.c:5218 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "テーブル\"%s\"を変更ã§ãã¾ã›ã‚“。ãã®è¡Œåž‹ã‚’列\"%s\".\"%s\"ã§ä½¿ç”¨ã—ã¦ã„ã‚‹ãŸã‚ã§ã™" -#: commands/tablecmds.c:4295 +#: commands/tablecmds.c:5272 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®åž‹ã§ã‚ã‚‹ãŸã‚ã€å¤–部テーブル \"%s\" を変更ã§ãã¾ã›ã‚“。" -#: commands/tablecmds.c:4297 +#: commands/tablecmds.c:5274 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルを変更ã™ã‚‹å ´åˆã‚‚ ALTER .. CASCADE を使用ã—ã¦ãã ã•ã„" -#: commands/tablecmds.c:4341 +#: commands/tablecmds.c:5320 #, c-format msgid "type %s is not a composite type" msgstr "åž‹ %s ã¯è¤‡åˆåž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:4367 +#: commands/tablecmds.c:5346 #, c-format msgid "cannot add column to typed table" -msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã«ã‚«ãƒ©ãƒ ã‚’追加ã§ãã¾ã›ã‚“" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã«åˆ—を追加ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:5390 +#, c-format +msgid "cannot add column to a partition" +msgstr "パーティションã«åˆ—ã¯è¿½åŠ ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:4429 commands/tablecmds.c:9412 +#: commands/tablecmds.c:5419 commands/tablecmds.c:11721 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" -msgstr "å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ãŒç•°ãªã‚‹åž‹ã®åˆ—\"%s\"ã‚’æŒã£ã¦ã„ã¾ã™" +msgstr "å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«ç•°ãªã‚‹åž‹ã®åˆ—\"%s\"ãŒã‚りã¾ã™" -#: commands/tablecmds.c:4435 commands/tablecmds.c:9419 +#: commands/tablecmds.c:5425 commands/tablecmds.c:11728 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" -msgstr "å­ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«ç•°ãªã‚‹ç…§åˆé †åºã®åˆ— \"%s\" ãŒã‚りã¾ã™" +msgstr "å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«ç•°ãªã‚‹ç…§åˆé †åºã®åˆ—\"%s\"ãŒã‚りã¾ã™" -#: commands/tablecmds.c:4445 +#: commands/tablecmds.c:5435 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" -msgstr "å­ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«ç«¶åˆã™ã‚‹ã‚«ãƒ©ãƒ  \"%s\" ãŒã‚りã¾ã™" +msgstr "å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«ç«¶åˆã™ã‚‹åˆ—\"%s\"ãŒã‚りã¾ã™" -#: commands/tablecmds.c:4457 +#: commands/tablecmds.c:5446 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "å­\"%2$s\"ã®åˆ—\"%1$s\"ã®å®šç¾©ã‚’マージã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:4678 +#: commands/tablecmds.c:5470 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "å­ãƒ†ãƒ¼ãƒ–ルをæŒã¤ãƒ†ãƒ¼ãƒ–ルã«è­˜åˆ¥åˆ—ã‚’å†å¸°çš„ã«è¿½åŠ ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:5719 #, c-format msgid "column must be added to child tables too" -msgstr "列ã¯å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚追加ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "列ã¯å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚追加ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/tablecmds.c:5794 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:4745 +#: commands/tablecmds.c:5801 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/tablecmds.c:4848 commands/tablecmds.c:4943 -#: commands/tablecmds.c:4991 commands/tablecmds.c:5095 -#: commands/tablecmds.c:5142 commands/tablecmds.c:5226 -#: commands/tablecmds.c:7391 commands/tablecmds.c:7986 +#: commands/tablecmds.c:5899 commands/tablecmds.c:8967 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "パーティションãŒå­˜åœ¨ã™ã‚‹å ´åˆã«ã¯ãƒ‘ーティションテーブルã®ã¿ã‹ã‚‰åˆ¶ç´„を削除ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:5900 commands/tablecmds.c:6044 +#: commands/tablecmds.c:6828 commands/tablecmds.c:8968 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ONLYキーワードを指定ã—ãªã„ã§ãã ã•ã„。" + +#: commands/tablecmds.c:5932 commands/tablecmds.c:6080 +#: commands/tablecmds.c:6135 commands/tablecmds.c:6211 +#: commands/tablecmds.c:6305 commands/tablecmds.c:6364 +#: commands/tablecmds.c:6514 commands/tablecmds.c:6584 +#: commands/tablecmds.c:6676 commands/tablecmds.c:9107 +#: commands/tablecmds.c:9802 #, c-format msgid "cannot alter system column \"%s\"" msgstr "システム列\"%s\"を変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:4884 +#: commands/tablecmds.c:5938 commands/tablecmds.c:6141 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯è­˜åˆ¥åˆ—ã§ã™" + +#: commands/tablecmds.c:5974 #, c-format msgid "column \"%s\" is in a primary key" msgstr "列\"%s\"ã¯ãƒ—ライマリキーã§ä½¿ç”¨ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:5042 +#: commands/tablecmds.c:5996 #, c-format -#| msgid "\"%s\" is not a table, index, or foreign table" -msgid "\"%s\" is not a table, materialized view, index, or foreign table" -msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルやインデックスã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "列\"%s\"ã¯è¦ªãƒ†ãƒ¼ãƒ–ルã§NOT NULL指定ã•れã¦ã„ã¾ã™" + +#: commands/tablecmds.c:6043 +#, c-format +msgid "cannot add constraint to only the partitioned table when partitions exist" +msgstr "パーティションãŒå­˜åœ¨ã™ã‚‹å ´åˆã«ã¯ãƒ‘ーティションテーブルã®ã¿ã«åˆ¶ç´„を追加ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:6143 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "代ã‚り㫠ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY を使ã£ã¦ãã ã•ã„。" + +#: commands/tablecmds.c:6222 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "識別列を追加ã™ã‚‹ã«ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã®åˆ—\"%s\"ã¯NOT NULLã¨å®£è¨€ã•れã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/tablecmds.c:6228 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯ã™ã§ã«è­˜åˆ¥åˆ—ã§ã™" + +#: commands/tablecmds.c:6234 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯ã™ã§ã«ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ãŒæŒ‡å®šã•れã¦ã„ã¾ã™" + +#: commands/tablecmds.c:6311 commands/tablecmds.c:6372 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯è­˜åˆ¥åˆ—ã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:6377 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$s\"ã¯è­˜åˆ¥åˆ—ã§ã¯ã‚りã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" + +#: commands/tablecmds.c:6442 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "éžã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹åˆ—を番å·ã§å‚ç…§ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:5069 +#: commands/tablecmds.c:6473 #, c-format msgid "statistics target %d is too low" -msgstr "統計情報対象%dã¯å°ã•ã™ãŽã¾ã™" +msgstr "統計情報目標%dã¯å°ã•ã™ãŽã¾ã™" -#: commands/tablecmds.c:5077 +#: commands/tablecmds.c:6481 #, c-format msgid "lowering statistics target to %d" -msgstr "統計情報対象を%dã«æ¸›ã‚‰ã—ã¾ã—ã¦ã„ã¾ã™" +msgstr "統計情報目標を%dã«æ¸›ã‚‰ã—ã¾ã™" + +#: commands/tablecmds.c:6504 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "リレーション \"%2$s\"ã®åˆ— %1$d ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/tablecmds.c:6523 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "インデックス \"%2$s\" ã®åŒ…å«åˆ— \"%1$s\"ã¸ã®çµ±è¨ˆæƒ…å ±ã®å¤‰æ›´ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:6528 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "インデックス \"%2$s\"ã®éžå¼åˆ—\"%1$s\"ã®çµ±è¨ˆæƒ…å ±ã®å¤‰æ›´ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:6530 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "代ã‚りã«ãƒ†ãƒ¼ãƒ–ルカラムã®çµ±è¨ˆæƒ…報を変更ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:5207 +#: commands/tablecmds.c:6656 #, c-format msgid "invalid storage type \"%s\"" -msgstr "ä¿ç®¡æ–¹å¼\"%s\"ã¯ç„¡åйã§ã™" +msgstr "䏿­£ãªæ ¼ç´ã‚¿ã‚¤ãƒ—\"%s\"" -#: commands/tablecmds.c:5238 +#: commands/tablecmds.c:6688 #, c-format msgid "column data type %s can only have storage PLAIN" -msgstr "列ã®ãƒ‡ãƒ¼ã‚¿åž‹%sã¯ä¿ç®¡æ–¹å¼PLAINã—ã‹å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "列ã®ãƒ‡ãƒ¼ã‚¿åž‹%sã¯æ ¼ç´ã‚¿ã‚¤ãƒ—PLAINã—ã‹å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:5272 +#: commands/tablecmds.c:6723 #, c-format msgid "cannot drop column from typed table" -msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã‹ã‚‰ã‚«ãƒ©ãƒ ã‚’削除ã§ãã¾ã›ã‚“" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã‹ã‚‰åˆ—を削除ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:5313 +#: commands/tablecmds.c:6768 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" -msgstr "リレーション \"%2$s\" ã®åˆ— \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™ã€‚" +msgstr "リレーション \"%2$s\" ã®åˆ— \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:5326 +#: commands/tablecmds.c:6781 #, c-format msgid "cannot drop system column \"%s\"" msgstr "システム列\"%s\"を削除ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:5333 +#: commands/tablecmds.c:6788 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "継承ã•れる列\"%s\"を削除ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:5562 +#: commands/tablecmds.c:6799 +#, c-format +msgid "cannot drop column named in partition key" +msgstr "ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã‚­ãƒ¼ã«æŒ‡å®šã•れã¦ã„る列ã¯å‰Šé™¤ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:6803 +#, c-format +msgid "cannot drop column referenced in partition key expression" +msgstr "パーティションキーå¼ã§å‚ç…§ã•れã¦ã„る列ã¯å‰Šé™¤ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:6827 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "å­ãƒ†ãƒ¼ãƒ–ルãŒå­˜åœ¨ã™ã‚‹å ´åˆã«ã¯ãƒ‘ーティションã®è¦ªãƒ†ãƒ¼ãƒ–ルã®ã¿ã‹ã‚‰åˆ—を削除ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:7032 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ã¯ãƒ‘ーティションテーブルã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/tablecmds.c:7057 #, c-format msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" -msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%s\" ã‚’ \"%s\" ã«ãƒªãƒãƒ¼ãƒ ã—ã¾ã™" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã‚’\"%s\"ã«ãƒªãƒãƒ¼ãƒ ã—ã¾ã™" -#: commands/tablecmds.c:5765 +#: commands/tablecmds.c:7273 #, c-format msgid "constraint must be added to child tables too" -msgstr "制約ã¯å­ãƒ†ãƒ¼ãƒ–ルã«ã‚‚追加ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "制約ã¯å­ãƒ†ãƒ¼ãƒ–ルã«ã‚‚追加ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:5832 +#: commands/tablecmds.c:7345 +#, c-format +msgid "cannot reference partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"ã¯å‚ç…§ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:7353 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "パーティションテーブル\"%s\"上ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã‚’å‚ç…§ã™ã‚‹å¤–部キー定義ã§ã¯ONLY指定ã¯ã§ãã¾ã›ã‚“ " + +#: commands/tablecmds.c:7359 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "パーティションテーブル\"%1$s\"ã«ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%2$s\"ã‚’å‚ç…§ã™ã‚‹ NOT VALID 指定ã®å¤–部キーã¯è¿½åŠ ã§ãã¾ã›ã‚“ " + +#: commands/tablecmds.c:7362 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "ã“ã®æ©Ÿèƒ½ã¯ãƒ‘ーティションテーブルã«å¯¾ã—ã¦ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。" + +#: commands/tablecmds.c:7368 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "å‚ç…§å…ˆã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:5855 +#: commands/tablecmds.c:7391 #, c-format msgid "constraints on permanent tables may reference only permanent tables" -msgstr "永続テーブルã¸ã®åˆ¶ç´„ã¯æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルã ã‘ã‚’å‚ç…§ã™ã‚‹å ´åˆãŒã‚りã¾ã™" +msgstr "永続テーブルã®åˆ¶ç´„ã¯æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルã ã‘ã‚’å‚ç…§ã§ãã¾ã™" -#: commands/tablecmds.c:5862 +#: commands/tablecmds.c:7398 #, c-format msgid "constraints on unlogged tables may reference only permanent or unlogged tables" -msgstr "ログをå–らãªã„(unlogged)テーブルã«å¯¾ã™ã‚‹åˆ¶ç´„ã¯ã€æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯ãƒ­ã‚°ã‚’å–らãªã„テーブルã ã‘ã‚’å‚ç…§ã™ã‚‹å ´åˆãŒã‚りã¾ã™" +msgstr "UNLOGGEDテーブルã«å¯¾ã™ã‚‹åˆ¶ç´„ã¯ã€æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯UNLOGGEDテーブルã ã‘ã‚’å‚ç…§ã™ã‚‹å ´åˆãŒã‚りã¾ã™" -#: commands/tablecmds.c:5868 +#: commands/tablecmds.c:7404 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "一時テーブルã«å¯¾ã™ã‚‹åˆ¶ç´„ã¯ä¸€æ™‚テーブルã ã‘ã‚’å‚ç…§ã™ã‚‹å ´åˆãŒã‚りã¾ã™" -#: commands/tablecmds.c:5872 +#: commands/tablecmds.c:7408 #, c-format -#| msgid "constraints on temporary tables may reference only temporary tables" msgid "constraints on temporary tables must involve temporary tables of this session" -msgstr "一時テーブルã«å¯¾ã™ã‚‹åˆ¶ç´„ã¯ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルをå«ã‚ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "一時テーブルã«å¯¾ã™ã‚‹åˆ¶ç´„ã«ã¯ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルを加ãˆã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:5933 +#: commands/tablecmds.c:7468 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "外部キーã®å‚照列数ã¨éžå‚照列数ãŒåˆã„ã¾ã›ã‚“" -#: commands/tablecmds.c:6040 +#: commands/tablecmds.c:7575 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "外部キー制約\"%sã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: commands/tablecmds.c:6043 +#: commands/tablecmds.c:7578 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "キーã¨ãªã‚‹åˆ—\"%s\"ã¨\"%s\"ã¨ã®é–“ã§åž‹ã«äº’æ›æ€§ãŒã‚りã¾ã›ã‚“:%sã¨%s" -#: commands/tablecmds.c:6242 commands/tablecmds.c:6365 -#: commands/tablecmds.c:7230 commands/tablecmds.c:7286 +#: commands/tablecmds.c:7821 commands/tablecmds.c:7986 +#: commands/tablecmds.c:8935 commands/tablecmds.c:8999 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "リレーション \"%2$s\" ã®åˆ¶ç´„ \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:6248 +#: commands/tablecmds.c:7828 #, c-format -#| msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "リレーション\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å¤–部キー制約ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:6372 +#: commands/tablecmds.c:7994 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "リレーション\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å¤–部キー制約ã§ã‚‚検査制約ã§ã‚‚ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:6441 +#: commands/tablecmds.c:8064 #, c-format msgid "constraint must be validated on child tables too" -msgstr "制約ã¯å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚検証ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "制約ã¯å­ãƒ†ãƒ¼ãƒ–ルã§ã‚‚検証ã•れる必è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:6503 +#: commands/tablecmds.c:8132 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "外部キー制約ã§å‚ç…§ã•れる列\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablecmds.c:6508 +#: commands/tablecmds.c:8137 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "外部キーã§ã¯%dã‚’è¶…ãˆã‚‹ã‚­ãƒ¼ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:6573 +#: commands/tablecmds.c:8202 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "被å‚照テーブル \"%s\" ã«ã¯é…å»¶å¯èƒ½ãƒ—ライマリキーã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:6590 +#: commands/tablecmds.c:8219 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "被å‚照テーブル\"%s\"ã«ã¯ãƒ—ライマリキーãŒã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:6742 +#: commands/tablecmds.c:8284 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "外部キーã®è¢«å‚照列リストã«ã¯é‡è¤‡ãŒã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/tablecmds.c:8378 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "被å‚照テーブル \"%s\" ã«å¯¾ã—ã¦ã¯ã€é…å»¶å¯èƒ½ãªä¸€æ„性制約ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:6747 +#: commands/tablecmds.c:8383 #, c-format msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "被å‚照テーブル \"%s\" ã«ã€æŒ‡å®šã—ãŸã‚­ãƒ¼ã«ä¸€è‡´ã™ã‚‹ä¸€æ„性制約ãŒã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:6906 +#: commands/tablecmds.c:8554 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "外部キー制約 \"%s\" を検証ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:7202 +#: commands/tablecmds.c:8892 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "リレーション \"%2$s\" ã®ç¶™æ‰¿ã•れãŸåˆ¶ç´„ \"%1$s\" を削除ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7236 +#: commands/tablecmds.c:8941 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" -msgstr "リレーション \"%2$s\" ã®åˆ¶ç´„ \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™ã€‚" +msgstr "リレーション \"%2$s\" ã®åˆ¶ç´„ \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablecmds.c:7375 +#: commands/tablecmds.c:9091 #, c-format msgid "cannot alter column type of typed table" msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®åˆ—ã®åž‹ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7398 +#: commands/tablecmds.c:9114 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "継承ã•れる列\"%s\"を変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7445 +#: commands/tablecmds.c:9125 +#, c-format +msgid "cannot alter type of column named in partition key" +msgstr "ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã‚­ãƒ¼ã«æŒ‡å®šã•れã¦ã„る列ã®åž‹ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:9129 +#, c-format +msgid "cannot alter type of column referenced in partition key expression" +msgstr "パーティションキーå¼ã§å‚ç…§ã•れã¦ã„る列ã®åž‹ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:9179 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "列\"%s\"ã«å¯¾ã™ã‚‹USINGå¥ã®çµæžœã¯è‡ªå‹•çš„ã«%såž‹ã«åž‹å¤‰æ›ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:9182 #, c-format -msgid "transform expression must not return a set" -msgstr "変æ›å¼ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" +msgid "You might need to add an explicit cast." +msgstr "å¿…è¦ã«å¿œã˜ã¦æ˜Žç¤ºçš„ãªåž‹å¤‰æ›ã‚’追加ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:7464 +#: commands/tablecmds.c:9186 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" -msgstr "列\"%s\"ã‚’åž‹%sã«ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" +msgstr "列\"%s\"ã¯åž‹%sã«ã¯è‡ªå‹•çš„ã«åž‹å¤‰æ›ã§ãã¾ã›ã‚“" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:9189 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "å¿…è¦ã«å¿œã˜ã¦\"USING %s::%s\"を追加ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:7466 +#: commands/tablecmds.c:9288 #, c-format -msgid "Specify a USING expression to perform the conversion." -msgstr "変æ›ã‚’行ã†ãŸã‚ã«USINGå¼ã‚’指定ã—ã¦ãã ã•ã„" +msgid "USING expression contains a whole-row table reference." +msgstr "USINGå¼ãŒå…¨è¡Œãƒ†ãƒ¼ãƒ–ルå‚ç…§ã‚’å«ã‚“ã§ã„ã¾ã™ã€‚" -#: commands/tablecmds.c:7515 +#: commands/tablecmds.c:9299 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "継承ã•れる列\"%s\"ã®åž‹ã‚’å­ãƒ†ãƒ¼ãƒ–ルã§å¤‰æ›´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/tablecmds.c:7596 +#: commands/tablecmds.c:9388 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "列\"%s\"ã®åž‹ã‚’2回変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7632 +#: commands/tablecmds.c:9424 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "列\"%s\"ã®ãƒ‡ãƒ•ォルト値を自動的ã«%såž‹ã«ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7758 +#: commands/tablecmds.c:9530 #, c-format msgid "cannot alter type of a column used by a view or rule" -msgstr "ビューã¾ãŸã¯ãƒ«ãƒ¼ãƒ«ã§ä½¿ç”¨ã•れる列ã®åž‹ã‚’変更ã§ãã¾ã›ã‚“" +msgstr "ビューã¾ãŸã¯ãƒ«ãƒ¼ãƒ«ã§ä½¿ç”¨ã•れる列ã®åž‹ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:7759 commands/tablecmds.c:7778 +#: commands/tablecmds.c:9531 commands/tablecmds.c:9550 +#: commands/tablecmds.c:9568 #, c-format msgid "%s depends on column \"%s\"" msgstr "%sã¯åˆ—\"%s\"ã«ä¾å­˜ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:7777 +#: commands/tablecmds.c:9549 #, c-format msgid "cannot alter type of a column used in a trigger definition" -msgstr "トリガー定義ã§ä½¿ç”¨ã•れる列ã®åž‹ã‚’変更ã§ãã¾ã›ã‚“" +msgstr "トリガー定義ã§ä½¿ç”¨ã•れる列ã®åž‹ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:9567 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "ãƒãƒªã‚·å®šç¾©ã§ä½¿ç”¨ã•れã¦ã„る列ã®åž‹ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:8329 +#: commands/tablecmds.c:10305 commands/tablecmds.c:10317 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "インデックス\"%s\"ã®æ‰€æœ‰è€…を変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:8331 +#: commands/tablecmds.c:10307 commands/tablecmds.c:10319 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "代ã‚りã«ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ‰€æœ‰è€…を変更ã—ã¦ãã ã•ã„" -#: commands/tablecmds.c:8347 +#: commands/tablecmds.c:10333 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "シーケンス\"%s\"ã®æ‰€æœ‰è€…を変更ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:8349 commands/tablecmds.c:10118 -#, c-format -msgid "Sequence \"%s\" is linked to table \"%s\"." -msgstr "シーケンス\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«ãƒªãƒ³ã‚¯ã•れã¦ã„ã¾ã™" - -#: commands/tablecmds.c:8361 commands/tablecmds.c:10722 +#: commands/tablecmds.c:10347 commands/tablecmds.c:13631 #, c-format msgid "Use ALTER TYPE instead." -msgstr "代ã‚りã«ALTER TYPEを使用ã—ã¦ãã ã•ã„" +msgstr "代ã‚りã«ALTER TYPEを使用ã—ã¦ãã ã•ã„。" -#: commands/tablecmds.c:8370 +#: commands/tablecmds.c:10356 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã€å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:8702 +#: commands/tablecmds.c:10696 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "SET TABLESPACEサブコマンドを複数指定ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:8772 +#: commands/tablecmds.c:10771 #, c-format -#| msgid "\"%s\" is not a table, index, or TOAST table" msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" -msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€TOASTテーブルã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€å®Ÿä½“化ビューã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã€TOASTテーブルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:8808 commands/view.c:477 +#: commands/tablecmds.c:10804 commands/view.c:508 #, c-format -msgid "WITH CHECK OPTION is supported only on auto-updatable views" -msgstr "WITH CHECK OPTIONã¯è‡ªå‹•æ›´æ–°å¯èƒ½ãƒ“ューã«å¯¾ã—ã¦ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¾ã™" +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTIONã¯è‡ªå‹•æ›´æ–°å¯èƒ½ãƒ“ューã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¾ã™" -#: commands/tablecmds.c:8954 +#: commands/tablecmds.c:10946 #, c-format msgid "cannot move system relation \"%s\"" msgstr "システムリレーション\"%s\"を移動ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:8970 +#: commands/tablecmds.c:10962 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルを移動ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9107 storage/buffer/bufmgr.c:479 +#: commands/tablecmds.c:11153 #, c-format -#| msgid "invalid page header in block %u of relation %s" -msgid "invalid page in block %u of relation %s" -msgstr "リレーション %2$s ã® %1$u ブロック目ã®ãƒšãƒ¼ã‚¸ãŒç„¡åйã§ã™" +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "テーブルスペースã«ã¯ãƒ†ãƒ¼ãƒ–ルã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŠã‚ˆã³å®Ÿä½“化ビューã—ã‹ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:9185 +#: commands/tablecmds.c:11165 #, c-format -msgid "cannot change inheritance of typed table" -msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®ç¶™æ‰¿ã‚’変更ã§ãã¾ã›ã‚“" +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "pg_globalテーブルスペースã¨ã®é–“ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ç§»å‹•ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9231 +#: commands/tablecmds.c:11258 #, c-format -#| msgid "cannot rewrite temporary tables of other sessions" -msgid "cannot inherit to temporary relation of another session" +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "リレーション\"%s.%s\"ã®ãƒ­ãƒƒã‚¯ãŒç²å¾—ã§ããªã‹ã£ãŸãŸã‚中断ã—ã¾ã™" + +#: commands/tablecmds.c:11274 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "テーブルスペース\"%s\"ã«ã¯åˆè‡´ã™ã‚‹ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ" + +#: commands/tablecmds.c:11341 storage/buffer/bufmgr.c:915 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "リレーション%2$sã®ãƒ–ロック%1$uã«ä¸æ­£ãªãƒšãƒ¼ã‚¸" + +#: commands/tablecmds.c:11421 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®ç¶™æ‰¿ã‚’変更ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:11426 commands/tablecmds.c:11969 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "パーティションã®ç¶™æ‰¿ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:11431 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "パーティションテーブルã®ç¶™æ‰¿ã¯å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:11477 +#, c-format +msgid "cannot inherit to temporary relation of another session" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルを継承ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9285 +#: commands/tablecmds.c:11490 +#, c-format +msgid "cannot inherit from a partition" +msgstr "パーティションã‹ã‚‰ã®ç¶™æ‰¿ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:11512 commands/tablecmds.c:14215 #, c-format msgid "circular inheritance not allowed" -msgstr "循環ã—ãŸç¶™æ‰¿ã‚’行ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "循環継承を行ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9286 +#: commands/tablecmds.c:11513 commands/tablecmds.c:14216 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\"ã¯ã™ã§ã«\"%s\"ã®å­ã§ã™" -#: commands/tablecmds.c:9294 +#: commands/tablecmds.c:11521 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" msgstr "OIDã‚’æŒãŸãªã„テーブル\"%s\"ã‚’OIDã‚’æŒã¤ãƒ†ãƒ¼ãƒ–ル\"%s\"ã‹ã‚‰ç¶™æ‰¿ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9430 +#: commands/tablecmds.c:11534 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "トリガ\"%s\"ã«ã‚ˆã£ã¦ãƒ†ãƒ¼ãƒ–ル\"%s\"ãŒç¶™æ‰¿å­ãƒ†ãƒ¼ãƒ–ルã«ãªã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:11536 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルを使用ã—ãŸROWトリガã¯ç¶™æ‰¿é–¢ä¿‚ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/tablecmds.c:11739 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" -msgstr "å­ãƒ†ãƒ¼ãƒ–ルã®åˆ—\"%s\"ã¯NOT NULLå°ãŒä»˜ã„ã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "å­ãƒ†ãƒ¼ãƒ–ルã®åˆ—\"%s\"ã¯NOT NULLã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tablecmds.c:9446 +#: commands/tablecmds.c:11766 commands/tablecmds.c:11805 #, c-format msgid "child table is missing column \"%s\"" msgstr "å­ãƒ†ãƒ¼ãƒ–ルã«ã¯åˆ—\"%s\"ãŒã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:9529 +#: commands/tablecmds.c:11893 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" -msgstr "å­ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«ã¯ãƒã‚§ãƒƒã‚¯åˆ¶ç´„ \"%s\" ã®ãŸã‚ã®ç•°ãªã£ãŸå®šç¾©ã‚’æŒã£ã¦ã„ã¾ã™" +msgstr "å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã§ã¯æ¤œæŸ»åˆ¶ç´„\"%s\"ã«ç•°ãªã£ãŸå®šç¾©ãŒã•れã¦ã„ã¾ã™" -#: commands/tablecmds.c:9537 +#: commands/tablecmds.c:11901 #, c-format msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "制約\"%s\"ã¯å­ãƒ†ãƒ¼ãƒ–ル\"%s\"上ã®ç¶™æ‰¿ã•れãªã„制約ã¨ç«¶åˆã—ã¾ã™" -#: commands/tablecmds.c:9561 +#: commands/tablecmds.c:11912 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "制約\"%s\"ã¯å­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®NOT VALID制約ã¨è¡çªã—ã¦ã„ã¾ã™" + +#: commands/tablecmds.c:11947 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "å­ãƒ†ãƒ¼ãƒ–ルã«ã¯åˆ¶ç´„ \"%s\" ãŒã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:9641 +#: commands/tablecmds.c:12036 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "リレーション\"%s\"ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã®ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:12042 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "リレーション\"%s\"ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã®è¦ªã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:9867 +#: commands/tablecmds.c:12268 #, c-format msgid "typed tables cannot inherit" msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã¯ç¶™æ‰¿ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:9898 +#: commands/tablecmds.c:12299 #, c-format msgid "table is missing column \"%s\"" msgstr "テーブルã«ã¯åˆ— \"%s\" ãŒã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:9908 +#: commands/tablecmds.c:12310 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" -msgstr "テーブルã«ã¯åˆ— \"%s\" ãŒã‚りã€ãã®åž‹ã¯ \"%s\" ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™" +msgstr "テーブルã«ã¯åˆ—\"%s\"ãŒã‚りã¾ã™ãŒåž‹ã¯\"%s\"ã‚’å¿…è¦ã¨ã—ã¦ã„ã¾ã™" -#: commands/tablecmds.c:9917 +#: commands/tablecmds.c:12319 #, c-format msgid "table \"%s\" has different type for column \"%s\"" -msgstr "テーブル \"%s\" ã«ã¯ç•°ãªã‚‹åž‹ã®åˆ— \"%s\" ãŒã‚りã¾ã™" +msgstr "テーブル\"%s\"ã§ã¯åˆ—\"%s\"ã®åž‹ãŒç•°ãªã£ã¦ã„ã¾ã™" -#: commands/tablecmds.c:9930 +#: commands/tablecmds.c:12333 #, c-format msgid "table has extra column \"%s\"" -msgstr "テーブルã«ä½™è¨ˆãªåˆ— \"%s\" ãŒã‚りã¾ã™" +msgstr "テーブルã«ä½™åˆ†ãªåˆ—\"%s\"ãŒã‚りã¾ã™" -#: commands/tablecmds.c:9980 +#: commands/tablecmds.c:12385 #, c-format msgid "\"%s\" is not a typed table" -msgstr "\"%s\" ã¯åž‹ä»˜ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\"ã¯åž‹ä»˜ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:12567 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "éžãƒ¦ãƒ‹ãƒ¼ã‚¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã¯è¤‡è£½è­˜åˆ¥ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12573 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "ä¸€æ„æ€§ã‚’峿™‚検査ã—ãªã„インデックス\"%s\"ã¯è¤‡è£½è­˜åˆ¥ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12579 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã¯è¤‡è£½è­˜åˆ¥ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:10117 +#: commands/tablecmds.c:12585 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "部分インデックス\"%s\"を複製識別ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12591 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "無効ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã¯è¤‡è£½è­˜åˆ¥ã¨ã—ã¦ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12612 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "列%2$dã¯ã‚·ã‚¹ãƒ†ãƒ åˆ—ã§ã‚ã‚‹ãŸã‚インデックス\"%1$s\"ã¯è¤‡è£½è­˜åˆ¥ã«ã¯ä½¿ãˆã¾ã›ã‚“" + +#: commands/tablecmds.c:12619 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "列\"%2$s\"ã¯nullå¯ã§ã‚ã‚‹ãŸã‚インデックス\"%1$s\"ã¯è¤‡è£½è­˜åˆ¥ã«ã¯ä½¿ãˆã¾ã›ã‚“" + +#: commands/tablecmds.c:12812 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "テーブル\"%s\"ã¯ä¸€æ™‚テーブルã§ã‚ã‚‹ãŸã‚ã€ãƒ­ã‚°å‡ºåŠ›è¨­å®šã‚’å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12836 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "テーブル\"%s\"ã¯ãƒ‘ブリケーションã®ä¸€éƒ¨ã§ã‚ã‚‹ãŸã‚ã€UNLOGGEDã«å¤‰æ›´ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12838 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "UNLOGGEDリレーションã¯ãƒ¬ãƒ—リケーションã§ãã¾ã›ã‚“。" + +#: commands/tablecmds.c:12883 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "テーブル\"%s\"ã¯UNLOGGEDテーブル\"%s\"ã‚’å‚ç…§ã—ã¦ã„ã‚‹ãŸã‚LOGGEDã«ã¯è¨­å®šã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12893 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "テーブル\"%s\"ã¯LOGGEDテーブル\"%s\"ã‚’å‚ç…§ã—ã¦ã„ã‚‹ãŸã‚UNLOGGEDã«ã¯è¨­å®šã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:12951 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "所有ã™ã‚‹ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’ä»–ã®ã‚¹ã‚­ãƒ¼ãƒžã«ç§»å‹•ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tablecmds.c:10213 +#: commands/tablecmds.c:13057 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "リレーション\"%s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/tablecmds.c:10706 +#: commands/tablecmds.c:13614 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\" ã¯è¤‡åˆåž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablecmds.c:10736 +#: commands/tablecmds.c:13646 #, c-format -#| msgid "\"%s\" is not a table, view, sequence, or foreign table" msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" -msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€ãƒžãƒ†ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ‰ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã€å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€å®Ÿä½“化ビューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã€å¤–部テーブルã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:13681 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "識別ã§ããªã„パーティションストラテジ \"%s\"" + +#: commands/tablecmds.c:13689 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "\"list\"パーティションストラテジã¯2ã¤ä»¥ä¸Šã®åˆ—ã«å¯¾ã—ã¦ã¯ä½¿ãˆã¾ã›ã‚“" + +#: commands/tablecmds.c:13754 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã‚­ãƒ¼ã«æŒ‡å®šã•れã¦ã„る列\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/tablecmds.c:13761 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "パーティションキーã§ã‚·ã‚¹ãƒ†ãƒ åˆ—\"%s\"ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:13824 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "パーティションキーå¼ã§ä½¿ã‚れる関数ã¯IMMUTABLE指定ã•れã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/tablecmds.c:13841 +#, c-format +msgid "partition key expressions cannot contain whole-row references" +msgstr "パーティションキーå¼ã¯å…¨è¡Œå‚ç…§ã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:13848 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "パーティションキーå¼ã¯ã‚·ã‚¹ãƒ†ãƒ åˆ—ã¸ã®å‚ç…§ã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tablespace.c:156 commands/tablespace.c:173 -#: commands/tablespace.c:184 commands/tablespace.c:192 -#: commands/tablespace.c:604 storage/file/copydir.c:50 +#: commands/tablecmds.c:13858 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "定数å¼ã‚’パーティションキーã¨ã—ã¦ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:13879 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "パーティションå¼ã§ä½¿ç”¨ã™ã¹ãç…§åˆé †åºã‚’特定ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:13912 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "データ型 %s ã«ã¯ãƒ‡ãƒ•ォルトã®ãƒãƒƒã‚·ãƒ¥æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ãŒã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:13914 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "ãƒãƒƒã‚·ãƒ¥æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã«ãƒ‡ãƒ•ォルトã®ãƒãƒƒã‚·ãƒ¥æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’定義ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: commands/tablecmds.c:13918 +#, c-format +msgid "data type %s has no default btree operator class" +msgstr "データ型%sã«ã¯ãƒ‡ãƒ•ォルトã®btree演算å­ã‚¯ãƒ©ã‚¹ãŒã‚りã¾ã›ã‚“" + +#: commands/tablecmds.c:13920 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "btree演算å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã«ãƒ‡ãƒ•ォルトã®btree演算å­ã‚¯ãƒ©ã‚¹ã‚’定義ã™ã‚‹ã‹ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: commands/tablecmds.c:14045 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "テーブル\"%s\"ã®ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³åˆ¶ç´„ã¯æ—¢å­˜ã®åˆ¶ç´„ã«ã‚ˆã£ã¦æš—é»™çš„ã«æº€ãŸã•れã¦ã„ã¾ã™" + +#: commands/tablecmds.c:14049 partitioning/partbounds.c:621 +#: partitioning/partbounds.c:666 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "デフォルトパーティション \"%s\" ã«å¯¾ã™ã‚‹æ›´æ–°ã•れãŸãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³åˆ¶ç´„ã¯æ—¢å­˜ã®åˆ¶ç´„ã«ã‚ˆã£ã¦æš—é»™çš„ã«æº€ãŸã•れã¦ã„ã¾ã™" + +#: commands/tablecmds.c:14155 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\"ã¯ã™ã§ãƒ‘ーティションã§ã™" + +#: commands/tablecmds.c:14161 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルをパーティションã«ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14177 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "継承å­ãƒ†ãƒ¼ãƒ–ルをパーティションã«ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14191 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "継承親テーブルをパーティションã«ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14225 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "一時リレーションを永続リレーション \"%s\" ã®å­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14233 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "永続リレーションを一時リレーション\"%s\"ã®ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14241 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "他セッションã®ä¸€æ™‚リレーションã®ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14248 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "他セッションã®ä¸€æ™‚リレーションã«ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14254 +#, c-format +msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +msgstr "OIDã‚’æŒãŸãªã„テーブル\"%s\"ã‚’OIDã‚’æŒã¤ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14262 +#, c-format +msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" +msgstr "OIDã‚’æŒã¤ãƒ†ãƒ¼ãƒ–ル\"%s\"ã‚’OIDã‚’æŒãŸãªã„テーブル\"%s\"ã®ãƒ‘ーティションå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14284 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "テーブル\"%1$s\"ã¯è¦ªãƒ†ãƒ¼ãƒ–ル\"%3$s\"ã«ãªã„列\"%2$s\"ã‚’å«ã‚“ã§ã„ã¾ã™" + +#: commands/tablecmds.c:14287 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "æ–°ã—ã„パーティションã¯è¦ªã«å­˜åœ¨ã™ã‚‹åˆ—ã®ã¿ã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚" + +#: commands/tablecmds.c:14299 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "トリガ\"%s\"ã®ãŸã‚ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"ã¯ãƒ‘ーティションã®å­ãƒ†ãƒ¼ãƒ–ルã«ã¯ãªã‚Œã¾ã›ã‚“" + +#: commands/tablecmds.c:14301 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルを使用ã™ã‚‹ROWトリガã¯ãƒ‘ーティションã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: commands/tablecmds.c:14952 commands/tablecmds.c:14971 +#: commands/tablecmds.c:14993 commands/tablecmds.c:15012 +#: commands/tablecmds.c:15068 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "インデックス \"%s\" をインデックス \"%s\"ã®å­ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¨ã—ã¦ã‚¢ã‚¿ãƒƒãƒã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: commands/tablecmds.c:14955 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "インデックス \"%s\" ã¯ã™ã§ã«åˆ¥ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã«ã‚¢ã‚¿ãƒƒãƒã•れã¦ã„ã¾ã™ã€‚" + +#: commands/tablecmds.c:14974 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "インデックス \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ル \"%s\" ã®ã©ã®å­ãƒ†ãƒ¼ãƒ–ルã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã‚‚ã‚りã¾ã›ã‚“。" + +#: commands/tablecmds.c:14996 +#, c-format +msgid "The index definitions do not match." +msgstr "インデックス定義ãŒåˆè‡´ã—ã¾ã›ã‚“。" + +#: commands/tablecmds.c:15015 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "インデックス \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ル \"%s\" ã®åˆ¶ç´„ã«å±žã—ã¦ã„ã¾ã™ãŒã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%s\" ã«ã¯åˆ¶ç´„ãŒã‚りã¾ã›ã‚“。" + +#: commands/tablecmds.c:15071 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "å­ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«ã¯ã™ã§ã«ä»–ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒã‚¢ã‚¿ãƒƒãƒã•れã¦ã„ã¾ã™ã€‚" + +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:625 replication/slot.c:1199 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/tablespace.c:203 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "ディレクトリ\"%s\"ã®statãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/tablespace.c:212 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "\"%s\"ã¯å­˜åœ¨ã—ã¾ã™ãŒã€ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablespace.c:242 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "テーブル空間\"%s\"を作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/tablespace.c:244 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." -msgstr "テーブル空間を作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "テーブル空間を生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/tablespace.c:260 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "テーブル空間ã®å ´æ‰€ã«ã¯å˜ä¸€å¼•用符をå«ã‚ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tablespace.c:270 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "テーブル空間ã®å ´æ‰€ã¯çµ¶å¯¾ãƒ‘スã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/tablespace.c:281 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "テーブル空間ã®å ´æ‰€\"%s\"ã¯é•·ã™ãŽã¾ã™" -#: commands/tablespace.c:291 commands/tablespace.c:856 +#: commands/tablespace.c:297 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "テーブル空間ã®å ´æ‰€ã¯ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ä¸­ã«æŒ‡å®šã™ã¹ãã§ã¯ã‚りã¾ã›ã‚“" + +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "テーブル空間å\"%s\"ã‚’å—ã‘付ã‘られã¾ã›ã‚“" -#: commands/tablespace.c:293 commands/tablespace.c:857 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "接頭辞\"pg_\"ã¯ã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ル空間用ã«äºˆç´„ã•れã¦ã„ã¾ã™" -#: commands/tablespace.c:303 commands/tablespace.c:869 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "テーブル空間\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/tablespace.c:372 commands/tablespace.c:530 -#: replication/basebackup.c:162 replication/basebackup.c:913 -#: utils/adt/misc.c:372 -#, c-format -msgid "tablespaces are not supported on this platform" -msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ãƒ†ãƒ¼ãƒ–ル空間をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#: commands/tablespace.c:412 commands/tablespace.c:839 -#: commands/tablespace.c:918 commands/tablespace.c:991 -#: commands/tablespace.c:1129 commands/tablespace.c:1329 +#: commands/tablespace.c:430 commands/tablespace.c:935 +#: commands/tablespace.c:1015 commands/tablespace.c:1083 +#: commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "テーブル空間\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablespace.c:418 +#: commands/tablespace.c:436 #, c-format msgid "tablespace \"%s\" does not exist, skipping" -msgstr "テーブル空間\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "テーブル空間\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tablespace.c:487 +#: commands/tablespace.c:512 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "テーブル空間\"%s\"ã¯ç©ºã§ã¯ã‚りã¾ã›ã‚“" -#: commands/tablespace.c:561 +#: commands/tablespace.c:584 #, c-format msgid "directory \"%s\" does not exist" msgstr "ディレクトリ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablespace.c:562 +#: commands/tablespace.c:585 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "サーãƒã‚’å†èµ·å‹•ã™ã‚‹å‰ã«ãƒ†ãƒ¼ãƒ–ルスペース用ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’作æˆã—ã¦ãã ã•ã„" -#: commands/tablespace.c:567 +#: commands/tablespace.c:590 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "ディレクトリ\"%s\"ã«æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/tablespace.c:599 +#: commands/tablespace.c:620 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "ディレクトリ \"%s\" ã¯ã™ã§ã«ãƒ†ãƒ¼ãƒ–ルスペースã¨ã—ã¦ä½¿ã‚れã¦ã„ã¾ã™" -#: commands/tablespace.c:614 commands/tablespace.c:775 -#, c-format -msgid "could not remove symbolic link \"%s\": %m" -msgstr "シンボリックリンク\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: commands/tablespace.c:624 -#, c-format -msgid "could not create symbolic link \"%s\": %m" -msgstr "シンボリックリンク\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: commands/tablespace.c:690 commands/tablespace.c:700 -#: postmaster/postmaster.c:1298 replication/basebackup.c:265 -#: replication/basebackup.c:553 storage/file/copydir.c:56 -#: storage/file/copydir.c:99 storage/file/fd.c:1896 utils/adt/genfile.c:354 -#: utils/adt/misc.c:272 utils/misc/tzparser.c:323 +#: commands/tablespace.c:705 commands/tablespace.c:715 +#: postmaster/postmaster.c:1476 storage/file/fd.c:2695 +#: storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 +#: utils/adt/misc.c:436 utils/misc/tzparser.c:339 #, c-format msgid "could not open directory \"%s\": %m" msgstr "ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/tablespace.c:730 commands/tablespace.c:743 -#: commands/tablespace.c:767 +#: commands/tablespace.c:744 commands/tablespace.c:757 +#: commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3125 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: commands/tablespace.c:996 +#: commands/tablespace.c:806 commands/tablespace.c:894 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "シンボリックリンク\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: commands/tablespace.c:816 commands/tablespace.c:903 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\"ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã‚‚シンボリックリンクã§ã‚‚ã‚りã¾ã›ã‚“" + +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "テーブル空間 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tablespace.c:1428 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "テーブル空間%u用ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’削除ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: commands/tablespace.c:1430 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "å¿…è¦ãªã‚‰ã°æ‰‹ä½œæ¥­ã§ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’削除ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: commands/trigger.c:163 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" msgstr "\"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" -#: commands/trigger.c:165 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "テーブル㯠INSTEAD OF トリガーをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:176 commands/trigger.c:183 +#: commands/trigger.c:237 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "パーティションテーブル㯠BEFORE / FOR EACH ROW トリガをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“。" + +#: commands/trigger.c:255 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "パーティションテーブルã«å¯¾ã™ã‚‹ãƒˆãƒªã‚¬ã¯é·ç§»ãƒ†ãƒ¼ãƒ–ルをæŒã¦ã¾ã›ã‚“。" + +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" msgstr "\"%s\" ã¯ãƒ“ューã§ã™" -#: commands/trigger.c:178 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "ビューã¯è¡Œãƒ¬ãƒ™ãƒ«ã® BEFORE / AFTER トリガーをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:185 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "ビュー㯠TRUNCATE トリガーをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:241 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 +#: commands/trigger.c:437 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\"ã¯å¤–部テーブルã§ã™" + +#: commands/trigger.c:286 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "外部テーブル㯠INSTEAD OF トリガをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“。" + +#: commands/trigger.c:293 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "外部テーブル㯠TRUNCATE トリガをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“。" + +#: commands/trigger.c:305 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "外部テーブルã¯åˆ¶ç´„トリガをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“。" + +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" -msgstr "TRUNCATE FOR EACH ROW トリガーã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "TRUNCATE FOR EACH ROW トリガã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: commands/trigger.c:249 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "INSTEAD OF トリガー㯠FOR EACH ROW ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/trigger.c:253 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "INSTEAD OF トリガー㯠WHEN æ¡ä»¶ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:257 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "INSTEAD OF トリガーã¯åˆ—リストをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:316 commands/trigger.c:329 +#: commands/trigger.c:425 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "REFERENCINGå¥ã§ã®ROW変数ã®å‘½åã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/trigger.c:426 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルを指定ã™ã‚‹ã«ã¯ OLD TABLE ã¾ãŸã¯ NEW TABLE を使ã£ã¦ãã ã•ã„" + +#: commands/trigger.c:439 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "外部テーブルã«å¯¾ã™ã‚‹ãƒˆãƒªã‚¬ã¯é·ç§»ãƒ†ãƒ¼ãƒ–ルをæŒã¦ã¾ã›ã‚“。" + +#: commands/trigger.c:446 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "ビューã«å¯¾ã™ã‚‹ãƒˆãƒªã‚¬ã¯é·ç§»ãƒ†ãƒ¼ãƒ–ルをæŒã¦ã¾ã›ã‚“。" + +#: commands/trigger.c:466 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルをもã£ãŸROWトリガã¯ç¶™æ‰¿å­ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: commands/trigger.c:472 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルåã¯AFTERトリガã§ã®æŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/trigger.c:477 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "é·ç§»ãƒ†ãƒ¼ãƒ–ルを使用ã™ã‚‹TRUNCATEトリガã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: commands/trigger.c:494 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "2ã¤ä»¥ä¸Šã®ã‚¤ãƒ™ãƒ³ãƒˆã«å¯¾ã™ã‚‹ãƒˆãƒªã‚¬ã«ã¯é·ç§»ãƒ†ãƒ¼ãƒ–ãƒ«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "列リストを指定ã—ãŸãƒˆãƒªã‚¬ã«å¯¾ã—ã¦ã¯é·ç§»ãƒ†ãƒ¼ãƒ–ãƒ«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/trigger.c:522 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE ã¯INSERTã¾ãŸã¯UPDATEトリガã«å¯¾ã—ã¦ã®ã¿æŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/trigger.c:527 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE ã¯è¤‡æ•°å›žæŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE ã¯DELETEã¾ãŸã¯UPDATEトリガã«å¯¾ã—ã¦ã®ã¿æŒ‡å®šå¯èƒ½ã§ã™" + +#: commands/trigger.c:542 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE ã¯è¤‡æ•°å›žæŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/trigger.c:552 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "OLD TABLE ã®åå‰ã¨ NEW TABLE ã®åå‰ã¯åŒã˜ã«ã¯ã§ãã¾ã›ã‚“" + +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" -msgstr "ステートメントトリガー㮠WHEN æ¡ä»¶ã§ã¯ã‚«ãƒ©ãƒ å€¤ã‚’å‚ç…§ã§ãã¾ã›ã‚“" +msgstr "ステートメントトリガー㮠WHEN æ¡ä»¶ã§ã¯åˆ—ã®å€¤ã‚’å‚ç…§ã§ãã¾ã›ã‚“" -#: commands/trigger.c:321 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "INSERT トリガー㮠WHEN æ¡ä»¶ã§ã¯ OLD 値をå‚ç…§ã§ãã¾ã›ã‚“" -#: commands/trigger.c:334 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "DELETE トリガー㮠WHEN æ¡ä»¶ã§ã¯ NEW 値をå‚ç…§ã§ãã¾ã›ã‚“" -#: commands/trigger.c:339 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" -msgstr "BEFORE トリガー㮠WHEN æ¡ä»¶ã§ã¯ NEW システムカラムをå‚ç…§ã§ãã¾ã›ã‚“" - -#: commands/trigger.c:384 -#, c-format -msgid "changing return type of function %s from \"opaque\" to \"trigger\"" -msgstr "関数%sã®æˆ»ã‚Šå€¤åž‹ã‚’\"opaque\"ã‹ã‚‰\"trigger\"ã¸å¤‰æ›´ã—ã¦ã„ã¾ã™" - -#: commands/trigger.c:391 -#, c-format -msgid "function %s must return type \"trigger\"" -msgstr "関数%sã¯\"trigger\"型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "BEFORE トリガー㮠WHEN æ¡ä»¶ã§ã¯ NEW システム列をå‚ç…§ã§ãã¾ã›ã‚“" -#: commands/trigger.c:503 commands/trigger.c:1249 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "リレーション\"%2$s\"用ã®ãƒˆãƒªã‚¬\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/trigger.c:788 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "被å‚照テーブルã®UPDATEトリガãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" -#: commands/trigger.c:789 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "被å‚照テーブルã®DELETEトリガãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" -#: commands/trigger.c:790 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "å‚照テーブルã®ãƒˆãƒªã‚¬ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸã€‚" -#: commands/trigger.c:899 commands/trigger.c:915 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "制約\"%s\" %sã«å¯¾ã™ã‚‹ä¸å®Œå…¨ãªãƒˆãƒªã‚¬ã‚°ãƒ«ãƒ¼ãƒ—を無視ã—ã¾ã™ã€‚" -#: commands/trigger.c:927 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "トリガグループを制約\"%s\" %sã«å¤‰æ›ã—ã¦ã„ã¾ã™" -#: commands/trigger.c:1139 commands/trigger.c:1297 commands/trigger.c:1413 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "テーブル\"%2$s\"ã®ãƒˆãƒªã‚¬\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/trigger.c:1378 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "権é™ãŒã‚りã¾ã›ã‚“: \"%s\"ã¯ã‚·ã‚¹ãƒ†ãƒ ãƒˆãƒªã‚¬ã§ã™" -#: commands/trigger.c:1874 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "トリガ関数%uã¯NULL値を返ã—ã¾ã—ãŸ" -#: commands/trigger.c:1933 commands/trigger.c:2132 commands/trigger.c:2320 -#: commands/trigger.c:2579 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 +#: commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "BEFORE STATEMENTトリガã¯å€¤ã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/trigger.c:2641 executor/nodeModifyTable.c:432 -#: executor/nodeModifyTable.c:713 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 +#: executor/nodeModifyTable.c:1244 #, c-format msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "更新対象ã®ã‚¿ãƒ—ルã¯ã™ã§ã«ç¾åœ¨ã®ã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã£ã¦ç™ºè¡Œã•ã‚ŒãŸæ“作ã«ã‚ˆã£ã¦å¤‰æ›´ã•れã¦ã„ã¾ã™" -#: commands/trigger.c:2642 executor/nodeModifyTable.c:433 -#: executor/nodeModifyTable.c:714 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 +#: executor/nodeModifyTable.c:1245 #, c-format msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "ä»–ã®è¡Œã¸ã®å¤‰æ›´ã‚’伿¬ã•ã›ã‚‹ãŸã‚ã«BEFOREトリガã§ã¯ãªãAFTERトリガã®ä½¿ç”¨ã‚’検討ã—ã¦ãã ã•ã„" -#: commands/trigger.c:2656 executor/execMain.c:2023 -#: executor/nodeLockRows.c:165 executor/nodeModifyTable.c:445 -#: executor/nodeModifyTable.c:726 +#: commands/trigger.c:3320 executor/execMain.c:2727 executor/nodeLockRows.c:220 +#: executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 +#: executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" -msgstr "åŒæ™‚æ›´æ–°ã®ãŸã‚直列化アクセスãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "æ›´æ–°ãŒåŒæ™‚ã«è¡Œã‚れãŸãŸã‚アクセスã®ç›´åˆ—化ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: commands/trigger.c:4285 +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 +#: executor/nodeLockRows.c:224 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "ロック対象ã®ã‚¿ãƒ—ルã¯åŒæ™‚ã«è¡Œã‚ã‚ŒãŸæ›´æ–°ã«ã‚ˆã£ã¦ã™ã§ã«ä»–ã®å­ãƒ†ãƒ¼ãƒ–ルã«ç§»å‹•ã•れã¦ã„ã¾ã™" + +#: commands/trigger.c:5452 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "制約\"%s\"ã¯é…å»¶å¯èƒ½ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/trigger.c:4308 +#: commands/trigger.c:5475 #, c-format msgid "constraint \"%s\" does not exist" msgstr "制約\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tsearchcmds.c:114 commands/tsearchcmds.c:671 +#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:679 #, c-format msgid "function %s should return type %s" msgstr "関数%sã¯åž‹%sã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/tsearchcmds.c:186 +#: commands/tsearchcmds.c:192 #, c-format msgid "must be superuser to create text search parsers" -msgstr "テキスト検索パーサを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "テキスト検索パーサを生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tsearchcmds.c:234 +#: commands/tsearchcmds.c:240 #, c-format msgid "text search parser parameter \"%s\" not recognized" msgstr "テキスト検索パーサ\"%s\"ã¯ä¸æ˜Žã§ã™" -#: commands/tsearchcmds.c:244 +#: commands/tsearchcmds.c:250 #, c-format msgid "text search parser start method is required" msgstr "テキスト検索パーサã®é–‹å§‹ãƒ¡ã‚½ãƒƒãƒ‰ãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:249 +#: commands/tsearchcmds.c:255 #, c-format msgid "text search parser gettoken method is required" msgstr "テキスト検索パーサã®gettokenメソッドãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:254 +#: commands/tsearchcmds.c:260 #, c-format msgid "text search parser end method is required" msgstr "テキスト検索パーサã®çµ‚了メソッドãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:259 +#: commands/tsearchcmds.c:265 #, c-format msgid "text search parser lextypes method is required" msgstr "テキスト検索パーサã®lextypesメソッドãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:376 +#: commands/tsearchcmds.c:384 #, c-format msgid "text search template \"%s\" does not accept options" msgstr "テキスト検索テンプレート\"%s\"ã¯ã‚ªãƒ—ションをå—ã‘付ã‘ã¾ã›ã‚“" -#: commands/tsearchcmds.c:449 +#: commands/tsearchcmds.c:458 #, c-format msgid "text search template is required" msgstr "テキスト検索テンプレートãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:735 +#: commands/tsearchcmds.c:746 #, c-format msgid "must be superuser to create text search templates" -msgstr "テキスト検索テンプレートを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "テキスト検索テンプレートを生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/tsearchcmds.c:772 +#: commands/tsearchcmds.c:783 #, c-format msgid "text search template parameter \"%s\" not recognized" msgstr "テキスト検索テンプレートã®ãƒ‘ラメータ\"%sã¯ä¸æ˜Žã§ã™ã€‚" -#: commands/tsearchcmds.c:782 +#: commands/tsearchcmds.c:793 #, c-format msgid "text search template lexize method is required" msgstr "テキスト検索テンプレートã®lexizeメソッドãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:988 +#: commands/tsearchcmds.c:1000 #, c-format msgid "text search configuration parameter \"%s\" not recognized" msgstr "テキスト検索設定ã®ãƒ‘ラメータ\"%s\"ã¯ä¸æ˜Žã§ã™" -#: commands/tsearchcmds.c:995 +#: commands/tsearchcmds.c:1007 #, c-format msgid "cannot specify both PARSER and COPY options" msgstr "PARSERã¨COPYオプションをã¾ã¨ã‚ã¦æŒ‡å®šã§ãã¾ã›ã‚“" -#: commands/tsearchcmds.c:1023 +#: commands/tsearchcmds.c:1043 #, c-format msgid "text search parser is required" msgstr "テキスト検索パーサãŒå¿…è¦ã§ã™" -#: commands/tsearchcmds.c:1247 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "トークン型\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tsearchcmds.c:1469 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "トークン型\"%s\"ã«å¯¾ã™ã‚‹ãƒžãƒƒãƒ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/tsearchcmds.c:1475 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" -msgstr "トークン型\"%s\"ã«å¯¾ã™ã‚‹ãƒžãƒƒãƒ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "トークン型\"%s\"ã«å¯¾ã™ã‚‹ãƒžãƒƒãƒ—ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/tsearchcmds.c:1628 commands/tsearchcmds.c:1739 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" -msgstr "無効ãªãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒªã‚¹ãƒˆã®æ›¸å¼ã§ã™: \"%s\"" +msgstr "䏿­£ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒªã‚¹ãƒˆã®æ›¸å¼ã§ã™: \"%s\"" -#: commands/typecmds.c:183 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" -msgstr "基本型を作æˆã§ãã‚‹ã®ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã ã‘ã§ã™" +msgstr "基本型を作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:289 commands/typecmds.c:1370 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "åž‹ã®å±žæ€§\"%s\"ã¯ä¸æ˜Žã§ã™" @@ -7492,7 +10185,7 @@ msgstr "åž‹ã®å±žæ€§\"%s\"ã¯ä¸æ˜Žã§ã™" #: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" -msgstr "型カテゴリ \"%s\" ãŒç„¡åйã§ã™ã€‚å˜ç´”㪠ASCII ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "型カテゴリ\"%s\"ãŒä¸æ­£ã§ã™ã€‚å˜ç´”ãªASCIIã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" #: commands/typecmds.c:362 #, c-format @@ -7512,502 +10205,619 @@ msgstr "æ ¼ç´æ–¹å¼\"%s\"ã¯ä¸æ˜Žã§ã™" #: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" -msgstr "åž‹ã®å…¥åŠ›é–¢æ•°ã‚’æŒ‡å®šã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "åž‹ã®å…¥åŠ›é–¢æ•°ã®æŒ‡å®šãŒå¿…è¦ã§ã™" #: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" -msgstr "åž‹ã®å‡ºåŠ›é–¢æ•°ã‚’æŒ‡å®šã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "åž‹ã®å‡ºåŠ›é–¢æ•°ã®æŒ‡å®šãŒå¿…è¦ã§ã™" #: commands/typecmds.c:431 #, c-format msgid "type modifier output function is useless without a type modifier input function" msgstr "型修正入力関数ãŒãªã„å ´åˆã®åž‹ä¿®æ­£å‡ºåŠ›é–¢æ•°ã¯æ„味ãŒã‚りã¾ã›ã‚“" -#: commands/typecmds.c:454 -#, c-format -msgid "changing return type of function %s from \"opaque\" to %s" -msgstr "関数%sã®æˆ»ã‚Šå€¤åž‹ã‚’\"opaque\"ã‹ã‚‰%sã«å¤‰æ›´ã—ã¦ã„ã¾ã™" - #: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" -msgstr "åž‹ã®å…¥åŠ›é–¢æ•°%sã¯åž‹%sã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: commands/typecmds.c:471 -#, c-format -msgid "changing return type of function %s from \"opaque\" to \"cstring\"" -msgstr "関数%sã®æˆ»ã‚Šå€¤åž‹ã‚’\"opaque\"ã‹ã‚‰\"cstring\"ã«å¤‰æ›´ã—ã¦ã„ã¾ã™" +msgstr "åž‹ã®å…¥åŠ›é–¢æ•°%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" #: commands/typecmds.c:478 #, c-format -msgid "type output function %s must return type \"cstring\"" -msgstr "åž‹ã®å‡ºåŠ›é–¢æ•°%sã¯åž‹\"cstring\"ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "type output function %s must return type %s" +msgstr "åž‹ã®å‡ºåŠ›é–¢æ•°%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" #: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" -msgstr "åž‹ã®å—信関数%sã¯åž‹%sã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "åž‹ã®å—信関数%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" #: commands/typecmds.c:496 #, c-format -msgid "type send function %s must return type \"bytea\"" -msgstr "åž‹ã®é€ä¿¡é–¢æ•°%sã¯åž‹\"bytea\"ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "type send function %s must return type %s" +msgstr "åž‹ã®é€ä¿¡é–¢æ•°%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" + +#: commands/typecmds.c:561 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "åž‹ã®å…¥åŠ›é–¢æ•°%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/typecmds.c:566 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "åž‹ã®å‡ºåŠ›é–¢æ•°%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/typecmds.c:571 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr "åž‹ã®å—信関数%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/typecmds.c:576 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "åž‹ã®é€ä¿¡é–¢æ•°%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/typecmds.c:581 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "型修正å­ã®å…¥åŠ›é–¢æ•°%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: commands/typecmds.c:586 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "型修正å­ã®å‡ºåŠ›é–¢æ•°%sã¯volatileã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/typecmds.c:761 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "\"%s\"ã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã®åŸºæœ¬åž‹ã¨ã—ã¦ç„¡åйã§ã™" -#: commands/typecmds.c:847 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "デフォルトå¼ãŒè¤‡æ•°ã‚りã¾ã™" -#: commands/typecmds.c:909 commands/typecmds.c:918 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "NULL制約ã¨NOT NULL制約ãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: commands/typecmds.c:934 +#: commands/typecmds.c:986 #, c-format -#| msgid "CHECK constraints for domains cannot be marked NO INHERIT" msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "ドメインã«å¯¾ã™ã‚‹æ¤œæŸ»åˆ¶ç´„ã¯NO INHERITå°ã‚’付ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/typecmds.c:943 commands/typecmds.c:2452 +#: commands/typecmds.c:995 commands/typecmds.c:2585 #, c-format msgid "unique constraints not possible for domains" msgstr "ドメインã§ã¯ä¸€æ„性制約ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:949 commands/typecmds.c:2458 +#: commands/typecmds.c:1001 commands/typecmds.c:2591 #, c-format msgid "primary key constraints not possible for domains" msgstr "ドメインã§ã¯ãƒ—ライマリキー制約ã¯ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:955 commands/typecmds.c:2464 +#: commands/typecmds.c:1007 commands/typecmds.c:2597 #, c-format msgid "exclusion constraints not possible for domains" msgstr "ドメインã§ã¯æŽ’除制約ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:961 commands/typecmds.c:2470 +#: commands/typecmds.c:1013 commands/typecmds.c:2603 #, c-format msgid "foreign key constraints not possible for domains" msgstr "ドメイン用ã®å¤–部キー制約ã¯ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:970 commands/typecmds.c:2479 +#: commands/typecmds.c:1022 commands/typecmds.c:2612 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "ドメインã§ã¯åˆ¶ç´„é…å»¶ã®æŒ‡å®šã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/typecmds.c:1242 utils/cache/typcache.c:1071 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" msgstr "%s ã¯æ•°å€¤ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/typecmds.c:1378 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "åž‹ã®å±žæ€§\"subtype\"ãŒå¿…è¦ã§ã™" -#: commands/typecmds.c:1383 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "ç¯„å›²ã®æ´¾ç”Ÿå…ƒåž‹ã‚’%sã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:1402 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" -msgstr "範囲ã®ç…§åˆé †åºãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€æ´¾ç”Ÿå…ƒåž‹ãŒç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "範囲ã®ç…§åˆé †åºãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€æ´¾ç”Ÿã‚‚ã¨åž‹ãŒç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: commands/typecmds.c:1638 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "関数%sã®å¼•数型を\"opaque\"ã‹ã‚‰\"cstring\"ã«å¤‰æ›´ã—ã¦ã„ã¾ã™" -#: commands/typecmds.c:1689 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "関数%sã®å¼•数型を\"opaque\"ã‹ã‚‰%sã«å¤‰æ›´ã—ã¦ã„ã¾ã™" -#: commands/typecmds.c:1788 +#: commands/typecmds.c:1898 #, c-format -msgid "typmod_in function %s must return type \"integer\"" -msgstr "typmod_in関数%sã¯\"integer\"型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "typmod_in function %s must return type %s" +msgstr "typmod_in関数%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:1815 +#: commands/typecmds.c:1925 #, c-format -msgid "typmod_out function %s must return type \"cstring\"" -msgstr "typmod_out関数%sã¯åž‹\"cstring\"ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "typmod_out function %s must return type %s" +msgstr "typmod_out関数%sã¯åž‹%sã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:1842 +#: commands/typecmds.c:1952 #, c-format -msgid "type analyze function %s must return type \"boolean\"" -msgstr "åž‹ã®è§£æžé–¢æ•°%sã¯\"boolean\"型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "type analyze function %s must return type %s" +msgstr "åž‹ã®ANALYZE関数%sã¯%s型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:1888 +#: commands/typecmds.c:1998 #, c-format msgid "You must specify an operator class for the range type or define a default operator class for the subtype." -msgstr "ã“ã®ç¯„å›²åž‹ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã€ã‚ã‚‹ã„ã¯ãã®æ´¾ç”Ÿå…ƒåž‹ã®ãƒ‡ãƒ•ォルト演算å­ã‚¯ãƒ©ã‚¹ã‚’定義ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã“ã®ç¯„å›²åž‹ã«æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’指定ã™ã‚‹ã‹ã€æ´¾ç”Ÿå…ƒã®åž‹ã§ãƒ‡ãƒ•ォルト演算å­ã‚¯ãƒ©ã‚¹ã‚’定義ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: commands/typecmds.c:1919 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" -msgstr "ç¯„å›²ã®æ­£è¦åŒ–関数%sã¯ç¯„囲型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ç¯„å›²ã®æ­£è¦åŒ–関数 %s ã¯ç¯„囲型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:1925 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" -msgstr "ç¯„å›²ã®æ­£è¦åŒ–関数%sã¯ä¸å¤‰ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ç¯„å›²ã®æ­£è¦åŒ–関数 %s ã¯ä¸å¤‰é–¢æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2071 #, c-format -msgid "range subtype diff function %s must return type double precision" -msgstr "ç¯„å›²ã®æ´¾ç”Ÿå…ƒåž‹ã®å·®ç•°é–¢æ•°%sã¯å€ç²¾åº¦åž‹ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "range subtype diff function %s must return type %s" +msgstr "ç¯„å›²ã®æ´¾ç”Ÿå…ƒã®åž‹ã®å·®åˆ†é–¢æ•° %s 㯠%s型を返ã™å¿…è¦ãŒã‚りã¾ã™" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" -msgstr "ç¯„å›²ã®æ´¾ç”Ÿå…ƒåž‹ã®å·®ç•°é–¢æ•°%sã¯ä¸å¤‰ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ç¯„å›²ã®æ´¾ç”Ÿå…ƒã®åž‹ã®å·®åˆ†é–¢æ•° %s ã¯ä¸å¤‰é–¢æ•°ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/typecmds.c:2105 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中ã«pg_typeã®é…列型OIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" -#: commands/typecmds.c:2286 +#: commands/typecmds.c:2410 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "テーブル\"%2$s\"ã®åˆ—\"%1$s\"ã«NULL値ãŒã‚りã¾ã™" -#: commands/typecmds.c:2395 commands/typecmds.c:2573 +#: commands/typecmds.c:2524 commands/typecmds.c:2709 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/typecmds.c:2399 +#: commands/typecmds.c:2528 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" -msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。スキップã—ã¾ã™ã€‚" +msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/typecmds.c:2579 +#: commands/typecmds.c:2716 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯æ¤œæŸ»åˆ¶ç´„ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/typecmds.c:2683 +#: commands/typecmds.c:2822 #, c-format msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "テーブル\"%2$s\"ã®åˆ—\"%1$s\"ã«æ–°ã—ã„制約ã«é•åã™ã‚‹å€¤ãŒã‚りã¾ã™" -#: commands/typecmds.c:2896 commands/typecmds.c:3266 commands/typecmds.c:3424 +#: commands/typecmds.c:3050 commands/typecmds.c:3256 commands/typecmds.c:3338 +#: commands/typecmds.c:3525 #, c-format msgid "%s is not a domain" msgstr "%s ã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã¯ã‚りã¾ã›ã‚“" -#: commands/typecmds.c:2929 +#: commands/typecmds.c:3083 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "ドメイン\"%2$s\"ã®åˆ¶ç´„\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/typecmds.c:2979 +#: commands/typecmds.c:3134 #, c-format msgid "cannot use table references in domain check constraint" msgstr "ãƒ‰ãƒ¡ã‚¤ãƒ³ã®æ¤œæŸ»åˆ¶ç´„ã§ã¯ãƒ†ãƒ¼ãƒ–ルå‚照を使用ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:3198 commands/typecmds.c:3278 commands/typecmds.c:3532 +#: commands/typecmds.c:3268 commands/typecmds.c:3350 commands/typecmds.c:3642 #, c-format msgid "%s is a table's row type" msgstr "%sã¯ãƒ†ãƒ¼ãƒ–ルã®è¡Œåž‹ã§ã™" -#: commands/typecmds.c:3200 commands/typecmds.c:3280 commands/typecmds.c:3534 +#: commands/typecmds.c:3270 commands/typecmds.c:3352 commands/typecmds.c:3644 #, c-format msgid "Use ALTER TABLE instead." msgstr "代ã‚りã«ALTER TABLEを使用ã—ã¦ãã ã•ã„" -#: commands/typecmds.c:3207 commands/typecmds.c:3287 commands/typecmds.c:3451 +#: commands/typecmds.c:3277 commands/typecmds.c:3359 commands/typecmds.c:3557 #, c-format msgid "cannot alter array type %s" msgstr "é…列型%sを変更ã§ãã¾ã›ã‚“" -#: commands/typecmds.c:3209 commands/typecmds.c:3289 commands/typecmds.c:3453 +#: commands/typecmds.c:3279 commands/typecmds.c:3361 commands/typecmds.c:3559 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "åž‹%sを変更ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ã“れã¯åŒæ™‚ã«ãã®é…列型も変更ã—ã¾ã™ã€‚" -#: commands/typecmds.c:3518 +#: commands/typecmds.c:3627 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "åž‹\"%s\"ã¯ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/user.c:145 +#: commands/user.c:141 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSIDã¯ã‚‚ã†æŒ‡å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: commands/user.c:277 +#: commands/user.c:295 #, c-format msgid "must be superuser to create superusers" -msgstr "スーパーユーザを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スーパーユーザを生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:284 +#: commands/user.c:302 #, c-format msgid "must be superuser to create replication users" -msgstr "レプリケーションユーザを作æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "レプリケーションユーザを生æˆã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: commands/user.c:309 commands/user.c:707 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "bypassrls属性を変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:291 +#: commands/user.c:316 #, c-format msgid "permission denied to create role" msgstr "ロールを作æˆã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:298 commands/user.c:1119 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 gram.y:14873 +#: gram.y:14911 utils/adt/acl.c:5342 utils/adt/acl.c:5348 #, c-format msgid "role name \"%s\" is reserved" msgstr "ロールå\"%s\"ã¯äºˆç´„ã•れã¦ã„ã¾ã™" -#: commands/user.c:311 commands/user.c:1113 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "\"pg_\"ã§å§‹ã¾ã‚‹ãƒ­ãƒ¼ãƒ«åã¯äºˆç´„ã•れã¦ã„ã¾ã™ã€‚" + +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "ロール\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: commands/user.c:618 commands/user.c:827 commands/user.c:933 -#: commands/user.c:1088 commands/variable.c:856 commands/variable.c:928 -#: utils/adt/acl.c:5090 utils/init/miscinit.c:433 +#: commands/user.c:406 commands/user.c:816 #, c-format -msgid "role \"%s\" does not exist" -msgstr "ロール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "empty string is not a valid password, clearing password" +msgstr "ç©ºã®æ–‡å­—列ã¯ãƒ‘スワードã¨ã—ã¦ä½¿ãˆã¾ã›ã‚“ã€ãƒ‘スワードを消去ã—ã¾ã™" + +#: commands/user.c:437 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモード中ã«pg_authidã®OIDãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" -#: commands/user.c:631 commands/user.c:846 commands/user.c:1357 -#: commands/user.c:1494 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 +#: commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" -msgstr "スーパーユーザを変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スーパーユーザを更新ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:638 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" -msgstr "レプリケーションユーザを変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "レプリケーションユーザを更新ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:654 commands/user.c:854 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "権é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:884 +#: commands/user.c:953 #, c-format -#| msgid "must be superuser to alter an operator family" msgid "must be superuser to alter settings globally" -msgstr "設定をグローãƒãƒ«ã«å¤‰æ›´ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "サーãƒå…¨ä½“ã®è¨­å®šã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:906 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "ロールを削除ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:938 +#: commands/user.c:999 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "DROP ROLE ã§ç‰¹æ®Šãƒ­ãƒ¼ãƒ«ã®è­˜åˆ¥å­ã¯ä½¿ãˆã¾ã›ã‚“" + +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 +#: commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "ロール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" -msgstr "ロール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。çœç•¥ã—ã¾ã™" +msgstr "ロール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“ã€ã‚¹ã‚­ãƒƒãƒ—ã—ã¾ã™" -#: commands/user.c:950 commands/user.c:954 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ã‚’削除ã§ãã¾ã›ã‚“" -#: commands/user.c:958 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "セッションã®ãƒ¦ãƒ¼ã‚¶ã‚’削除ã§ãã¾ã›ã‚“" -#: commands/user.c:969 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" -msgstr "スーパーユーザを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スーパーユーザを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:985 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "ä»–ã®ã‚ªãƒ–ジェクトãŒä¾å­˜ã—ã¦ã„ã¾ã™ã®ã§ãƒ­ãƒ¼ãƒ«\"%s\"を削除ã§ãã¾ã›ã‚“" -#: commands/user.c:1103 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "セッションユーザã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/user.c:1107 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ã®åå‰ã‚’変更ã§ãã¾ã›ã‚“" -#: commands/user.c:1130 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" -msgstr "スーパーユーザã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スーパーユーザã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:1137 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "ロールã®åå‰ã‚’変更ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:1158 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "ロールåãŒå¤‰æ›´ã•れãŸãŸã‚MD5パスワードãŒã‚¯ãƒªã‚¢ã•れã¾ã—ãŸ" -#: commands/user.c:1218 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" -msgstr "カラムå㌠GRANT/REVOKE ROLE ã«å«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "列å㌠GRANT/REVOKE ROLE ã«å«ã¾ã‚Œã¦ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/user.c:1256 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" msgstr "オブジェクトを削除ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:1283 commands/user.c:1292 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" msgstr "オブジェクトをå†å‰²å½“ã¦ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: commands/user.c:1365 commands/user.c:1502 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" -msgstr "ロール\"%s\"ã«adminオプションãŒãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ロール\"%s\"ã«ã¯ ADMIN OPTION ãŒå¿…è¦ã§ã™" -#: commands/user.c:1373 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" -msgstr "権é™ä»˜ä¸Žè€…を設定ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "権é™ä»˜ä¸Žè€…を指定ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/user.c:1398 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" -msgstr "ロール\"%s\"ã¯ãƒ­ãƒ¼ãƒ«\"%s\"ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" +msgstr "ロール\"%s\"ã¯ãƒ­ãƒ¼ãƒ«\"%s\"ã®ãƒ¡ãƒ³ãƒã§ã™" -#: commands/user.c:1413 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "ロール\"%s\"ã¯ã™ã§ã«ãƒ­ãƒ¼ãƒ«\"%s\"ã®ãƒ¡ãƒ³ãƒã§ã™" -#: commands/user.c:1524 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "ロール\"%s\"ã¯ãƒ­ãƒ¼ãƒ«\"%s\"ã®ãƒ¡ãƒ³ãƒã§ã¯ã‚りã¾ã›ã‚“" -#: commands/vacuum.c:437 +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "ANALYZE オプションã¯åˆ—リストãŒä¸Žãˆã‚‰ã‚Œã¦ã„ã‚‹ã¨ãã®ã¿æŒ‡å®šã§ãã¾ã™" + +#: commands/vacuum.c:203 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%sã¯VACUUMã‚„ANALYZEã‹ã‚‰ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: commands/vacuum.c:213 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "VACUUM ã®ã‚ªãƒ—ションDISABLE_PAGE_SKIPPINGã¯FULLã¨åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "最もå¤ã„xminãŒå¤ã™ãŽã¾ã™" -#: commands/vacuum.c:438 +#: commands/vacuum.c:658 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"周回å•題を回é¿ã™ã‚‹ãŸã‚ã«ã™ãã«å®Ÿè¡Œä¸­ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã—ã¦ãã ã•ã„。\n" +"å¤ã„準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ã‚³ãƒŸãƒƒãƒˆã¾ãŸã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã€ã‚‚ã—ãã¯å¤ã„レプリケーションスロットã®å‰Šé™¤ãŒå¿…è¦ãªå ´åˆã‚‚ã‚りã¾ã™ã€‚" + +#: commands/vacuum.c:698 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." -msgstr "周回å•題を回é¿ã™ã‚‹ãŸã‚ã™ãã«ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るトランザクションをクローズã—ã¦ãã ã•ã„。" +msgid "oldest multixact is far in the past" +msgstr "最å¤ã®ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå¤ã™ãŽã¾ã™" -#: commands/vacuum.c:892 +#: commands/vacuum.c:699 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "周回å•題を回é¿ã™ã‚‹ãŸã‚ã«ã€ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’使用ã—ã¦ã„る実行中ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã™ãã«ã‚¯ãƒ­ãƒ¼ã‚ºã—ã¦ãã ã•ã„。" + +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" -msgstr "データベースã®ä¸€éƒ¨ã¯20億トランザクション以上ã®é–“ã«ãƒã‚­ãƒ¥ãƒ¼ãƒ ã•れã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" +msgstr "データベースã®ä¸€éƒ¨ã¯20億トランザクション以上ã®é–“ã«VACUUMを実行ã•れã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" -#: commands/vacuum.c:893 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "トランザクションã®å‘¨å›žã«ã‚ˆã‚‹ãƒ‡ãƒ¼ã‚¿æå¤±ãŒç™ºç”Ÿã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™" -#: commands/vacuum.c:1004 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" -msgstr "\"%s\" ã®ãƒã‚­ãƒ¥ãƒ¼ãƒ ã‚’スキップã—ã¦ã„ã¾ã™ -- ロックを利用ã§ãã¾ã›ã‚“" +msgstr "\"%s\" ã®VACUUM処ç†ã‚’スキップã—ã¦ã„ã¾ã™ -- ロックをç²å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "\"%s\" ã®VACUUM処ç†ã‚’スキップã—ã¦ã„ã¾ã™ -- リレーションã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: commands/vacuum.c:1030 +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã®ã¿ãŒãƒã‚­ãƒ¥ãƒ¼ãƒ ã§ãã¾ã™" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザã®ã¿ãŒVACUUMを実行ã§ãã¾ã™" -#: commands/vacuum.c:1034 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" -msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザもã—ãã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒãƒã‚­ãƒ¥ãƒ¼ãƒ ã§ãã¾ã™" +msgstr "\"%s\" をスキップã—ã¦ã„ã¾ã™ --- スーパーユーザもã—ãã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒVACUUMを実行ã§ãã¾ã™" -#: commands/vacuum.c:1038 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" -msgstr "\"%s\"を飛ã°ã—ã¦ã„ã¾ã™ --- テーブルã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒãƒã‚­ãƒ¥ãƒ¼ãƒ ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" +msgstr "\"%s\"を飛ã°ã—ã¦ã„ã¾ã™ --- テーブルã¾ãŸã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ‰€æœ‰è€…ã®ã¿ãŒVACUUMを実行ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: commands/vacuum.c:1056 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" -msgstr "\"%s\"をスキップã—ã¦ã„ã¾ã™ --- テーブルã§ã¯ãªã„ã‚‚ã®ã‚„ã€ç‰¹åˆ¥ãªã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ルã¯ãƒã‚­ãƒ¥ãƒ¼ãƒ ã§ãã¾ã›ã‚“" +msgstr "\"%s\"をスキップã—ã¦ã„ã¾ã™ --- テーブルã§ã¯ãªã„ã‚‚ã®ã‚„ã€ç‰¹åˆ¥ãªã‚·ã‚¹ãƒ†ãƒ ãƒ†ãƒ¼ãƒ–ルã«å¯¾ã—ã¦ã¯VACUUMを実行ã§ãã¾ã›ã‚“" -#: commands/vacuumlazy.c:314 +#: commands/vacuumlazy.c:378 #, c-format -#| msgid "" -#| "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" -#| "pages: %d removed, %d remain\n" -#| "tuples: %.0f removed, %.0f remain\n" -#| "buffer usage: %d hits, %d misses, %d dirtied\n" -#| "avg read rate: %.3f MiB/s, avg write rate: %.3f MiB/s\n" -#| "system usage: %s" -msgid "" -"automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" -"pages: %d removed, %d remain\n" -"tuples: %.0f removed, %.0f remain\n" -"buffer usage: %d hits, %d misses, %d dirtied\n" -"avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" -"system usage: %s" -msgstr "" -"テーブル\"%s.%s.%s\"ã®è‡ªå‹•ãƒã‚­ãƒ¥ãƒ¼ãƒ : インデックススキャン: %d\n" -"ページ: %dを削除ã€%dãŒæ®‹å­˜\n" -"タプル: %.0fを削除ã€%.0fãŒæ®‹å­˜\n" -"ãƒãƒƒãƒ•ァ使用:%dヒット〠%d失敗ã€%d ダーティ化\n" -"å¹³å‡èª­ã¿å–り速度:%.3f MB/sã€å¹³å‡æ›¸ãè¾¼ã¿é€Ÿåº¦: %.3f MB/s\n" -"システム使用状æ³: %s" +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"ã®ç©æ¥µçš„自動VACUUM: インデックススキャン: %d\n" -#: commands/vacuumlazy.c:645 +#: commands/vacuumlazy.c:380 #, c-format -msgid "relation \"%s\" page %u is uninitialized --- fixing" -msgstr "リレーション\"%s\" ページ%uã¯åˆæœŸåŒ–ã•れã¦ã„ã¾ã›ã‚“ --- 修正ã—ã¦ã„ã¾ã™" +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "テーブル\"%s.%s.%s\"ã®è‡ªå‹•VACUUM: インデックススキャン: %d\n" -#: commands/vacuumlazy.c:1034 +#: commands/vacuumlazy.c:386 #, c-format -msgid "\"%s\": removed %.0f row versions in %u pages" -msgstr "\"%s\": %.0f行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%uページã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ" +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "ページ: %uを削除ã€%uãŒæ®‹å­˜ã€%uãŒãƒ”ンã«ã‚ˆã£ã¦ã‚¹ã‚­ãƒƒãƒ—ã€%uãŒå‡çµã«ã‚ˆã£ã¦ã‚¹ã‚­ãƒƒãƒ—\n" -#: commands/vacuumlazy.c:1039 +#: commands/vacuumlazy.c:392 #, c-format -msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" -msgstr "\"%1$s\": å…¨ %5$u ページ中㮠%4$u ページã§è¦‹ã¤ã‹ã£ãŸè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³ï¼šç§»å‹•å¯èƒ½ %2$.0f 行ã€å‰Šé™¤ä¸å¯ %3$.0f 行" +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "タプル: %.0fを削除, %.0fãŒæ®‹å­˜, %.0fãŒå‚ç…§ã•れã¦ã„ãªã„ãŒã¾ã å‰Šé™¤ã§ããªã„, 最å¤ã®xmin: %u\n" -#: commands/vacuumlazy.c:1043 +#: commands/vacuumlazy.c:398 #, c-format -msgid "" -"%.0f dead row versions cannot be removed yet.\n" -"There were %.0f unused item pointers.\n" -"%u pages are entirely empty.\n" -"%s." -msgstr "" -"%.0f ã®ä¸è¦ãªè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ã¾ã å‰Šé™¤ã§ãã¾ã›ã‚“。\n" -"未使用アイテムã¸ã®ãƒã‚¤ãƒ³ã‚¿ãŒ %.0f 個ã‚りã¾ã—ãŸã€‚\n" -"%u ページãŒå®Œå…¨ã«ç©ºã§ã™ã€‚\n" -"%s" +msgid "buffer usage: %d hits, %d misses, %d dirtied\n" +msgstr "ãƒãƒƒãƒ•ァ使用: %dヒット, %d失敗, %d ダーティ化\n" -#: commands/vacuumlazy.c:1114 +#: commands/vacuumlazy.c:402 #, c-format -msgid "\"%s\": removed %d row versions in %d pages" -msgstr "\"%s\": %d行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%dページã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ" +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "å¹³å‡èª­ã¿å–り速度: %.3f MB/s, 平凿›¸ãè¾¼ã¿é€Ÿåº¦: %.3f MB/s\n" -#: commands/vacuumlazy.c:1117 commands/vacuumlazy.c:1273 -#: commands/vacuumlazy.c:1444 +#: commands/vacuumlazy.c:404 #, c-format -msgid "%s." -msgstr "%s。" +msgid "system usage: %s" +msgstr "システム使用状æ³: %s" -#: commands/vacuumlazy.c:1270 +#: commands/vacuumlazy.c:500 #, c-format -msgid "scanned index \"%s\" to remove %d row versions" -msgstr "%2$d行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’削除ã™ã‚‹ãŸã‚インデックス\"%1$s\"をスキャンã—ã¾ã—ãŸ" +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "\"%s.%s\"ã«å¯¾ã—ã¦ç©æ¥µçš„VACUUMを実行ã—ã¦ã„ã¾ã™" -#: commands/vacuumlazy.c:1315 +#: commands/vacuumlazy.c:881 #, c-format -msgid "index \"%s\" now contains %.0f row versions in %u pages" -msgstr "ç¾åœ¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã¯%.0f行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%uページã§å«ã‚“ã§ã„ã¾ã™" +msgid "relation \"%s\" page %u is uninitialized --- fixing" +msgstr "リレーション\"%s\" ページ%uã¯åˆæœŸåŒ–ã•れã¦ã„ã¾ã›ã‚“ --- 修正ã—ã¦ã„ã¾ã™" + +#: commands/vacuumlazy.c:1417 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": %.0f行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%uページã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ" + +#: commands/vacuumlazy.c:1427 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f 個ã®ä¸è¦ãªè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã¾ã å‰Šé™¤ã§ãã¾ã›ã‚“ã€æœ€å¤ã®xmin: %u\n" + +#: commands/vacuumlazy.c:1429 +#, c-format +msgid "There were %.0f unused item pointers.\n" +msgstr "%.0få€‹ã®æœªä½¿ç”¨ã®ã‚¢ã‚¤ãƒ†ãƒ ãƒã‚¤ãƒ³ã‚¿ãŒã‚りã¾ã—ãŸã€‚\n" + +#: commands/vacuumlazy.c:1431 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "ãƒãƒƒãƒ•ァピンã®ãŸã‚%uページãŒã‚¹ã‚­ãƒƒãƒ—ã•れã¾ã—ãŸã€" +msgstr[1] "ãƒãƒƒãƒ•ã‚¡ãŒå›ºå®šã•れã¦ã„ã‚‹%uページãŒã‚¹ã‚­ãƒƒãƒ—ã•れã¾ã—ãŸã€" + +#: commands/vacuumlazy.c:1435 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%uページã®å‡çµãƒšãƒ¼ã‚¸ã€‚\n" +msgstr[1] "%uページã®å‡çµãƒšãƒ¼ã‚¸ã€‚\n" + +#: commands/vacuumlazy.c:1439 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%uページãŒå®Œå…¨ã«ç©ºã§ã™ã€‚\n" +msgstr[1] "%uページãŒå®Œå…¨ã«ç©ºã§ã™ã€‚\n" + +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s。" + +#: commands/vacuumlazy.c:1446 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%1$s\": å…¨ %5$u ページ中㮠%4$u ページã§è¦‹ã¤ã‹ã£ãŸè¡Œãƒãƒ¼ã‚¸ãƒ§ãƒ³: 削除å¯èƒ½ %2$.0f 行ã€å‰Šé™¤ä¸å¯ %3$.0f 行" + +#: commands/vacuumlazy.c:1515 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": %d行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%dページã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ" + +#: commands/vacuumlazy.c:1704 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "%2$d行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’削除ã™ã‚‹ãŸã‚インデックス\"%1$s\"をスキャンã—ã¾ã—ãŸ" + +#: commands/vacuumlazy.c:1756 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "ç¾åœ¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã¯%.0f行ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’%uページã§å«ã‚“ã§ã„ã¾ã™" -#: commands/vacuumlazy.c:1319 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -8018,2291 +10828,2887 @@ msgstr "" "%uインデックスページãŒå‰Šé™¤ã•れã€%uãŒç¾åœ¨å†åˆ©ç”¨å¯èƒ½ã§ã™\n" "%s" -#: commands/vacuumlazy.c:1376 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" -msgstr "\"%s\":ç«¶åˆã™ã‚‹ãƒ­ãƒƒã‚¯è¦æ±‚ã®ãŸã‚æ¶ˆåŽ»ã‚’åœæ­¢ã—ã¦ã„ã¾ã™" +msgstr "\"%s\":ç«¶åˆã™ã‚‹ãƒ­ãƒƒã‚¯ãŒå­˜åœ¨ã™ã‚‹ãŸã‚切り詰ã‚を中断ã—ã¾ã™" -#: commands/vacuumlazy.c:1441 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "\"%s\": %u削除ã•れã€%uページã«ãªã‚Šã¾ã—ãŸ" -#: commands/vacuumlazy.c:1497 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" -msgstr "\"%s\": ç«¶åˆã™ã‚‹ãƒ­ãƒƒã‚¯è¦æ±‚ã®ãŸã‚ã«æ¶ˆåŽ»ã‚’ä¸€æ™‚åœæ­¢ã—ã¦ã„ã¾ã™" +msgstr "\"%s\": ç«¶åˆã™ã‚‹ãƒ­ãƒƒã‚¯è¦æ±‚ãŒå­˜åœ¨ã™ã‚‹ãŸã‚ã€åˆ‡ã‚Šè©°ã‚ã‚’ä¿ç•™ã—ã¾ã™" -#: commands/variable.c:162 utils/misc/guc.c:8418 +#: commands/variable.c:165 utils/misc/guc.c:10307 utils/misc/guc.c:10369 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "䏿˜Žãªã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã§ã™: \"%s\"" -#: commands/variable.c:174 +#: commands/variable.c:177 #, c-format msgid "Conflicting \"datestyle\" specifications." -msgstr "\"datestyle\" 指定ãŒç«¶åˆã—ã¦ã„ã¾ã™" +msgstr "\"datestyle\" 指定ãŒç«¶åˆã—ã¦ã„ã¾ã™ã€‚" -#: commands/variable.c:313 +#: commands/variable.c:299 #, c-format msgid "Cannot specify months in time zone interval." -msgstr "タイムゾーンã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒ«ã«æœˆã¯æŒ‡å®šã§ãã¾ã›ã‚“" +msgstr "タイムゾーンã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒ«æŒ‡å®šã§ã¯æœˆã¯æŒ‡å®šã§ãã¾ã›ã‚“。" -#: commands/variable.c:319 +#: commands/variable.c:305 #, c-format msgid "Cannot specify days in time zone interval." -msgstr "タイムゾーンã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒ«ã«æ—¥ã¯æŒ‡å®šã§ãã¾ã›ã‚“" +msgstr "タイムゾーンã®ã‚¤ãƒ³ã‚¿ãƒ¼ãƒãƒ«æŒ‡å®šã§ã¯æ—¥ã¯æŒ‡å®šã§ãã¾ã›ã‚“。" -#: commands/variable.c:363 commands/variable.c:486 +#: commands/variable.c:343 commands/variable.c:425 #, c-format msgid "time zone \"%s\" appears to use leap seconds" -msgstr "時間帯\"%s\"ã¯ã†ã‚‹ã†ç§’を使用ã™ã‚‹ã‚ˆã†ã§ã™" +msgstr "タイムゾーン\"%s\"ã¯ã†ã‚‹ã†ç§’を使用ã™ã‚‹ã‚ˆã†ã§ã™" -#: commands/variable.c:365 commands/variable.c:488 +#: commands/variable.c:345 commands/variable.c:427 #, c-format msgid "PostgreSQL does not support leap seconds." -msgstr "PostgreSQLã¯ã†ã‚‹ã†ç§’をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "PostgreSQLã¯ã†ã‚‹ã†ç§’をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "UTCã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚ªãƒ•セットãŒç¯„囲外ã§ã™ã€‚" -#: commands/variable.c:552 +#: commands/variable.c:494 #, c-format msgid "cannot set transaction read-write mode inside a read-only transaction" msgstr "読ã¿å–りã®ã¿ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã§ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¢ãƒ¼ãƒ‰ã‚’èª­ã¿æ›¸ãモードã«è¨­å®šã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/variable.c:559 +#: commands/variable.c:501 #, c-format msgid "transaction read-write mode must be set before any query" -msgstr "ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’èª­ã¿æ›¸ãモードã«è¨­å®šã™ã‚‹å‰ã«ã€ä½•らã‹ã®ã‚¯ã‚¨ãƒªãƒ¼ã‚’発行ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "トランザクションã®èª­ã¿æ›¸ãモードã®è¨­å®šã¯ã€å•ã„åˆã‚ã›ã‚ˆã‚Šå‰ã«è¡Œã†å¿…è¦ãŒã‚りã¾ã™" -#: commands/variable.c:566 +#: commands/variable.c:508 #, c-format msgid "cannot set transaction read-write mode during recovery" -msgstr "リカãƒãƒªãƒ¼ä¸­ã«ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’èª­ã¿æ›¸ãモードã«è¨­å®šã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªä¸­ã«ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’èª­ã¿æ›¸ãモードã«è¨­å®šã§ãã¾ã›ã‚“" -#: commands/variable.c:615 +#: commands/variable.c:557 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" -msgstr "SET TRANSACTION ISOLATION LEVELã‚’å…¨ã¦ã®å•ã„åˆã‚ã›ã®å‰ã«å‘¼ã³å‡ºã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "SET TRANSACTION ISOLATION LEVEL ã¯å•ã„åˆã‚ã›ã‚ˆã‚Šå‰ã«å®Ÿè¡Œã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/variable.c:622 +#: commands/variable.c:564 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "SET TRANSACTION ISOLATION LEVELをサブトランザクションã§å‘¼ã³å‡ºã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: commands/variable.c:629 storage/lmgr/predicate.c:1585 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "ホットスタンãƒã‚¤ä¸­ã¯ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºãƒ¢ãƒ¼ãƒ‰ã‚’使用ã§ãã¾ã›ã‚“" -#: commands/variable.c:630 +#: commands/variable.c:572 #, c-format msgid "You can use REPEATABLE READ instead." msgstr "代ã‚り㫠REPEATABLE READ を使ã£ã¦ãã ã•ã„" -#: commands/variable.c:678 +#: commands/variable.c:620 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" -msgstr "SET TRANSACTION [NOT] DEFERRABLE をサブトランザクション内部ã§å‘¼ã³å‡ºã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "SET TRANSACTION [NOT] DEFERRABLE をサブトランザクション内部ã§ã¯å‘¼ã³å‡ºã›ã¾ã›ã‚“" -#: commands/variable.c:684 +#: commands/variable.c:626 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" -msgstr "SET TRANSACTION [NOT] DEFERRABLE ã¯ã™ã¹ã¦ã®å•ã„åˆã‚ã›ã®å‰ã«å‘¼ã³å‡ºã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "SET TRANSACTION [NOT] DEFERRABLE ã¯å•ã„åˆã‚ã›ã‚ˆã‚Šå‰ã«å®Ÿè¡Œã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: commands/variable.c:766 +#: commands/variable.c:708 #, c-format msgid "Conversion between %s and %s is not supported." -msgstr "%s 㨠%s é–“ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "%sã¨%s é–“ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。" -#: commands/variable.c:773 +#: commands/variable.c:715 #, c-format msgid "Cannot change \"client_encoding\" now." -msgstr "ç¾åœ¨ã¯ \"client_encoding\" を変更ã§ãã¾ã›ã‚“" +msgstr "ç¾åœ¨ã¯ \"client_encoding\" を変更ã§ãã¾ã›ã‚“。" + +#: commands/variable.c:776 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "並列処ç†ä¸­ã¯\"client_encoding\"を変更ã§ãã¾ã›ã‚“" -#: commands/variable.c:943 +#: commands/variable.c:912 #, c-format msgid "permission denied to set role \"%s\"" msgstr "ロール\"%s\"を設定ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" #: commands/view.c:54 #, c-format -#| msgid "invalid value for \"buffering\" option" msgid "invalid value for \"check_option\" option" -msgstr "\"check_option\"オプションã®å€¤ãŒç„¡åйã§ã™" +msgstr "\"check_option\"オプションã®å€¤ãŒä¸æ­£ã§ã™" #: commands/view.c:55 #, c-format -#| msgid "Valid values are \"on\", \"off\", and \"auto\"." -msgid "Valid values are \"local\", and \"cascaded\"." -msgstr "有効ãªå€¤ã¯\"local\"ã€\"cascaded\"ã§ã™ã€‚" +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "有効ãªå€¤ã¯\"local\"ã¨\"cascaded\"ã§ã™ã€‚" -#: commands/view.c:113 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" -msgstr "ビューã®åˆ— \"%s\" ã§ä½¿ç”¨ã™ã‚‹ç…§åˆé †åºã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "ビューã®åˆ—\"%s\"ã§ä½¿ç”¨ã™ã‚‹ç…§åˆé †åºã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: commands/view.c:128 +#: commands/view.c:117 #, c-format msgid "view must have at least one column" msgstr "ビューã«ã¯å°‘ãªãã¨ã‚‚1ã¤ã®åˆ—ãŒå¿…è¦ã§ã™" -#: commands/view.c:259 commands/view.c:271 +#: commands/view.c:285 commands/view.c:297 #, c-format msgid "cannot drop columns from view" -msgstr "ビューã‹ã‚‰ã‚«ãƒ©ãƒ ã‚’削除ã§ãã¾ã›ã‚“" +msgstr "ビューã‹ã‚‰ã¯åˆ—を削除ã§ãã¾ã›ã‚“" -#: commands/view.c:276 +#: commands/view.c:302 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" -msgstr "ビューã®ã‚«ãƒ©ãƒ ã®åå‰ã‚’ \"%s\" ã‹ã‚‰ \"%s\" ã«å¤‰æ›´ã§ãã¾ã›ã‚“" +msgstr "ビューã®åˆ—åã‚’\"%s\"ã‹ã‚‰\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/view.c:284 +#: commands/view.c:310 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" -msgstr "ビューã®ã‚«ãƒ©ãƒ  \"%s\" ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’ %s ã‹ã‚‰ %s ã«å¤‰æ›´ã§ãã¾ã›ã‚“" +msgstr "ビューã®åˆ— \"%s\"ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’ %s ã‹ã‚‰ %s ã«å¤‰æ›´ã§ãã¾ã›ã‚“" -#: commands/view.c:420 +#: commands/view.c:455 #, c-format msgid "views must not contain SELECT INTO" msgstr "ビューã§ã¯ SELECT INTO を使用ã§ãã¾ã›ã‚“" -#: commands/view.c:433 +#: commands/view.c:467 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "ビューã§ã¯ WITH å¥ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: commands/view.c:507 +#: commands/view.c:537 #, c-format msgid "CREATE VIEW specifies more column names than columns" -msgstr "CREATE VIEWã§ã¯åˆ—よりも多ãã®åˆ—åを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "CREATE VIEW ã§åˆ—よりも多ãã®åˆ—åãŒæŒ‡å®šã•れã¦ã„ã¾ã™" -#: commands/view.c:515 +#: commands/view.c:545 #, c-format msgid "views cannot be unlogged because they do not have storage" -msgstr "ビューã¯ãã‚Œç”¨ã®æ ¼ç´é ˜åŸŸã‚’æŒãŸãªã„ã®ã§ã€ãƒ­ã‚°ã‚’å–らãªã„ã®ã¯è¨±ã•れã¾ã›ã‚“" +msgstr "ビューã¯è‡ªèº«ã®æ ¼ç´é ˜åŸŸã‚’æŒãŸãªã„ã®ã§ã€UNLOGGEDã«ã¯ã§ãã¾ã›ã‚“" -#: commands/view.c:529 +#: commands/view.c:559 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "ビュー\"%s\"ã¯ä¸€æ™‚ビューã¨ãªã‚Šã¾ã™" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:78 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "カーソル\"%s\"ã¯SELECTå•ã„åˆã‚ã›ã§ã¯ã‚りã¾ã›ã‚“" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:84 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "カーソル\"%s\"ã¯ä»¥å‰ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰ä¿æŒã•れã¦ã„ã¾ã™" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:116 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" -msgstr "カーソル \"%s\" ã«ã¯ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«å¯¾ã™ã‚‹è¤‡æ•°ã® FOR UPDATE/SHAREå‚ç…§ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" +msgstr "カーソル\"%s\"ã«ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«å¯¾ã™ã‚‹è¤‡æ•°ã®FOR UPDATE/SHAREå‚ç…§ãŒã‚りã¾ã™" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:125 #, c-format msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" -msgstr "カーソル \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ル \"%s\" ã¸ã® FOR UPDATE/SHARE å‚ç…§ã‚’æŒã£ã¦ã„ã¾ã›ã‚“" +msgstr "カーソル\"%s\"ã«ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã¸ã® FOR UPDATE/SHAREå‚ç…§ãŒã‚りã¾ã›ã‚“" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:135 executor/execCurrent.c:180 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "カーソル\"%s\"ã¯è¡Œä¸Šã«ä½ç½®ã—ã¦ã„ã¾ã›ã‚“" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:167 executor/execCurrent.c:226 +#: executor/execCurrent.c:238 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "カーソル\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã‚’å˜ç´”ãªæ›´æ–°å¯èƒ½ã‚¹ã‚­ãƒ£ãƒ³ã§ã¯ã‚りã¾ã›ã‚“" -#: executor/execCurrent.c:231 executor/execQual.c:1138 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 #, c-format msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" -msgstr "パラメータã®åž‹ %d (%s) ãŒãƒ—ラン (%s) を準備ã™ã‚‹æ™‚点ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "パラメータã®åž‹%d(%s)ãŒå®Ÿè¡Œè¨ˆç”»(%s)を準備ã™ã‚‹æ™‚点ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: executor/execCurrent.c:243 executor/execQual.c:1150 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 #, c-format msgid "no value found for parameter %d" msgstr "パラメータ%dã®å€¤ãŒã‚りã¾ã›ã‚“" -#: executor/execMain.c:953 +#: executor/execExpr.c:856 parser/parse_agg.c:794 +#, c-format +msgid "window function calls cannot be nested" +msgstr "ウィンドウ関数ã®å‘¼ã³å‡ºã—を入れå­ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: executor/execExpr.c:1314 +#, c-format +msgid "target type is not an array" +msgstr "対象型ã¯é…列ã§ã¯ã‚りã¾ã›ã‚“" + +#: executor/execExpr.c:1647 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW()列ã®åž‹ãŒ%2$sã§ã¯ãªã%1$sã§ã™" + +#: executor/execExpr.c:2182 executor/execSRF.c:697 parser/parse_func.c:126 +#: parser/parse_func.c:640 parser/parse_func.c:1014 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "関数ã«%dã‚’è¶…ãˆã‚‹å¼•数を渡ã›ã¾ã›ã‚“" +msgstr[1] "関数ã«%dã‚’è¶…ãˆã‚‹å¼•数を渡ã›ã¾ã›ã‚“" + +#: executor/execExpr.c:2480 executor/execExpr.c:2486 +#: executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 +#: utils/adt/arrayfuncs.c:5820 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "é…åˆ—ã®æ¬¡æ•°(%d)ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: executor/execExprInterp.c:1879 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "%2$såž‹ã®å±žæ€§%1$dãŒå‰Šé™¤ã•れã¦ã„ã¾ã™" + +#: executor/execExprInterp.c:1885 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "åž‹%2$sã®å±žæ€§%1$dã®åž‹ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 +#: executor/execExprInterp.c:2933 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "テーブルã®åž‹ã¯%sã§ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%sを想定ã—ã¦ã„ã¾ã™ã€‚" + +#: executor/execExprInterp.c:2374 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "ã“ã®ã‚¿ã‚¤ãƒ—ã®ãƒ†ãƒ¼ãƒ–ルã§ã¯WHERE CURRENT OFをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: executor/execExprInterp.c:2591 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "äº’æ›æ€§ãŒãªã„é…列をマージã§ãã¾ã›ã‚“" + +#: executor/execExprInterp.c:2592 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "è¦ç´ åž‹%sã®é…列をè¦ç´ åž‹%sã®ARRAYå¼ã«å«ã‚られã¾ã›ã‚“" + +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "多次元é…列ã®é…列å¼ã®æ¬¡æ•°ãŒã‚ã£ã¦ã„ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 +#, c-format +msgid "attribute %d has wrong type" +msgstr "属性%dã®åž‹ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: executor/execExprInterp.c:3042 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "代入ã«ãŠã‘ã‚‹é…åˆ—ã®æ·»ãˆå­—ã¯nullã«ã¯ã§ãã¾ã›ã‚“" + +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "ドメイン%sã¯null値を許ã—ã¾ã›ã‚“" + +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "ドメイン%sã®å€¤ãŒæ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" + +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 +#: executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 +#: executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 +#: executor/nodeModifyTable.c:142 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "テーブルã®è¡Œåž‹ã¨å•ã„åˆã‚ã›ã§æŒ‡å®šã—ãŸè¡Œåž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“" + +#: executor/execExprInterp.c:3862 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "テーブル行ã«ã¯%d属性ã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" +msgstr[1] "テーブル行ã«ã¯%d属性ã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" + +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "テーブルã§ã¯ %2$d 番目ã®åž‹ã¯ %1$s ã§ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯ %3$s を想定ã—ã¦ã„ã¾ã™ã€‚" + +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "åºæ•°ä½ç½®%dã®å‰Šé™¤ã•れãŸå±žæ€§ã«ãŠã‘ã‚‹ç‰©ç†æ ¼ç´å½¢å¼ãŒä¸€è‡´ã—ã¾ã›ã‚“。" + +#: executor/execIndexing.c:543 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT ã¯é…å»¶å¯ãªãƒ¦ãƒ‹ãƒ¼ã‚¯åˆ¶ç´„/排除制約ã®èª¿åœä¸»ä½“ã¨ã—ã¦ã®æŒ‡å®šã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: executor/execIndexing.c:818 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "排除制約\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: executor/execIndexing.c:821 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "キー %s ãŒã‚­ãƒ¼ %s ã¨ç«¶åˆã—ã¦ã„ã¾ã™" + +#: executor/execIndexing.c:823 +#, c-format +msgid "Key conflicts exist." +msgstr "キーã®ç«¶åˆãŒå­˜åœ¨ã—ã¾ã™" + +#: executor/execIndexing.c:829 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "é‡è¤‡ã‚­ãƒ¼ã®å€¤ãŒæŽ’除制約\"%s\"ã«é•åã—ã¦ã„ã¾ã™" + +#: executor/execIndexing.c:832 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "キー %s ãŒæ—¢å­˜ã®ã‚­ãƒ¼ %s ã¨ç«¶åˆã—ã¦ã„ã¾ã™" + +#: executor/execIndexing.c:834 +#, c-format +msgid "Key conflicts with existing key." +msgstr "ã‚­ãƒ¼ãŒæ—¢å­˜ã®ã‚­ãƒ¼ã¨è¡çªã—ã¦ã„ã¾ã™" + +#: executor/execMain.c:1116 #, c-format msgid "cannot change sequence \"%s\"" msgstr "シーケンス\"%s\"を変更ã§ãã¾ã›ã‚“" -#: executor/execMain.c:959 +#: executor/execMain.c:1122 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "TOASTリレーション\"%s\"を変更ã§ãã¾ã›ã‚“" -#: executor/execMain.c:977 rewrite/rewriteHandler.c:2344 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2773 #, c-format msgid "cannot insert into view \"%s\"" -msgstr "ビュー \"%s\" ã¸ã¯æŒ¿å…¥(INSERT)ã§ãã¾ã›ã‚“" +msgstr "ビュー\"%s\"ã¸ã¯æŒ¿å…¥(INSERT)ã§ãã¾ã›ã‚“" -#: executor/execMain.c:979 rewrite/rewriteHandler.c:2347 +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2776 #, c-format msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." msgstr "ビューã¸ã®æŒ¿å…¥ã‚’å¯èƒ½ã«ã™ã‚‹ãŸã‚ã«ã€INSTEAD OF INSERTトリガã¾ãŸã¯ç„¡æ¡ä»¶ã®ON INSERT DO INSTEADルールを作æˆã—ã¦ãã ã•ã„。" -#: executor/execMain.c:985 rewrite/rewriteHandler.c:2352 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2781 #, c-format msgid "cannot update view \"%s\"" -msgstr "ビュー \"%s\" ã¯æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "ビュー\"%s\"ã¯æ›´æ–°ã§ãã¾ã›ã‚“" -#: executor/execMain.c:987 rewrite/rewriteHandler.c:2355 +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2784 #, c-format msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." msgstr "ビューã¸ã®æ›´æ–°ã‚’å¯èƒ½ã«ã™ã‚‹ãŸã‚ã«ã€INSTEAD OF UPDATEトリガã¾ãŸã¯ç„¡æ¡ä»¶ã®ON UPDATE DO INSTEADルールを作æˆã—ã¦ãã ã•ã„。" -#: executor/execMain.c:993 rewrite/rewriteHandler.c:2360 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2789 #, c-format msgid "cannot delete from view \"%s\"" -msgstr "ビュー \"%s\" ã‹ã‚‰ã¯å‰Šé™¤ã§ãã¾ã›ã‚“" +msgstr "ビュー\"%s\"ã‹ã‚‰ã¯å‰Šé™¤ã§ãã¾ã›ã‚“" -#: executor/execMain.c:995 rewrite/rewriteHandler.c:2363 +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2792 #, c-format msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." msgstr "ビューã‹ã‚‰ã®å‰Šé™¤ã‚’å¯èƒ½ã«ã™ã‚‹ãŸã‚ã«ã€INSTEAD OF DELETEトリガã¾ãŸã¯ç„¡æ¡ä»¶ã®ON DELETE DO INSTEADルールを作æˆã—ã¦ãã ã•ã„。" -#: executor/execMain.c:1006 +#: executor/execMain.c:1169 #, c-format -#| msgid "cannot change view \"%s\"" msgid "cannot change materialized view \"%s\"" -msgstr "マテリアライズドビュー\"%s\"を変更ã§ãã¾ã›ã‚“" +msgstr "実体化ビュー\"%s\"を変更ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1018 +#: executor/execMain.c:1181 #, c-format -#| msgid "cannot copy to foreign table \"%s\"" msgid "cannot insert into foreign table \"%s\"" -msgstr "外部テーブル \"%s\" ã¸ã®æŒ¿å…¥ã¯ã§ãã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã¸ã®æŒ¿å…¥ãŒã§ãã¾ã›ã‚“" -#: executor/execMain.c:1024 +#: executor/execMain.c:1187 #, c-format -#| msgid "foreign table \"%s\" does not exist" msgid "foreign table \"%s\" does not allow inserts" -msgstr "外部テーブル \"%s\" ã¯æŒ¿å…¥ã‚’許ã—ã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã¯æŒ¿å…¥ã‚’許ã—ã¾ã›ã‚“" -#: executor/execMain.c:1031 +#: executor/execMain.c:1194 #, c-format -#| msgid "cannot change foreign table \"%s\"" msgid "cannot update foreign table \"%s\"" -msgstr "外部テーブル \"%s\"ã‚’æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "外部テーブル \"%s\"ã®æ›´æ–°ãŒã§ãã¾ã›ã‚“" -#: executor/execMain.c:1037 +#: executor/execMain.c:1200 #, c-format -#| msgid "foreign table \"%s\" does not exist" msgid "foreign table \"%s\" does not allow updates" -msgstr "外部テーブル \"%s\" ã¯æ›´æ–°ã‚’許ã—ã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã¯æ›´æ–°ã‚’許ã—ã¾ã›ã‚“" -#: executor/execMain.c:1044 +#: executor/execMain.c:1207 #, c-format -#| msgid "cannot copy from foreign table \"%s\"" msgid "cannot delete from foreign table \"%s\"" -msgstr "外部テーブル \"%s\" ã‹ã‚‰å‰Šé™¤ã§ãã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã‹ã‚‰ã®å‰Šé™¤ãŒã§ãã¾ã›ã‚“" -#: executor/execMain.c:1050 +#: executor/execMain.c:1213 #, c-format -#| msgid "foreign table \"%s\" does not exist" msgid "foreign table \"%s\" does not allow deletes" -msgstr "外部テーブル \"%s\" ã¯å‰Šé™¤ã‚’許ã—ã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã¯å‰Šé™¤ã‚’許ã—ã¾ã›ã‚“" -#: executor/execMain.c:1061 +#: executor/execMain.c:1224 #, c-format msgid "cannot change relation \"%s\"" msgstr "リレーション\"%s\"を変更ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1085 +#: executor/execMain.c:1251 #, c-format msgid "cannot lock rows in sequence \"%s\"" -msgstr "シーケンス \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "シーケンス\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1092 +#: executor/execMain.c:1258 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" -msgstr "TOAST リレーション \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "TOAST リレーション\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1099 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in view \"%s\"" -msgstr "ビュー \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "ビュー\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1106 +#: executor/execMain.c:1273 #, c-format -#| msgid "cannot lock rows in view \"%s\"" msgid "cannot lock rows in materialized view \"%s\"" -msgstr "マテリアライズドビュー \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "実体化ビュー\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1113 +#: executor/execMain.c:1282 executor/execMain.c:2974 +#: executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" -msgstr "外部テーブル \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "外部テーブル\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1119 +#: executor/execMain.c:1288 #, c-format msgid "cannot lock rows in relation \"%s\"" -msgstr "リレーション \"%s\" ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" +msgstr "リレーション\"%s\"ã§ã¯è¡Œã®ãƒ­ãƒƒã‚¯ã¯ã§ãã¾ã›ã‚“" -#: executor/execMain.c:1603 +#: executor/execMain.c:1959 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "列\"%s\"内ã®NULL値ã¯NOT NULL制約é•åã§ã™" +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "リレーション\"%s\"ã®æ–°ã—ã„行ã¯ãƒ‘ーティション制約ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execMain.c:1605 executor/execMain.c:1620 executor/execMain.c:1664 +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 +#: executor/execMain.c:2195 #, c-format msgid "Failing row contains %s." msgstr "失敗ã—ãŸè¡Œã¯%sã‚’å«ã¿ã¾ã™" -#: executor/execMain.c:1618 -#, c-format -msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgstr "リレーション\"%s\"ã®æ–°ã—ã„è¡Œã¯æ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" - -#: executor/execMain.c:1662 -#, c-format -msgid "new row violates WITH CHECK OPTION for view \"%s\"" -msgstr "æ–°ã—ã„行ã¯ãƒ“ュー\"%s\"ã®WITH CHECK OPTIONã«é•åã—ã¾ã™" - -#: executor/execQual.c:305 executor/execQual.c:333 executor/execQual.c:3101 -#: utils/adt/array_userfuncs.c:430 utils/adt/arrayfuncs.c:233 -#: utils/adt/arrayfuncs.c:512 utils/adt/arrayfuncs.c:1247 -#: utils/adt/arrayfuncs.c:2920 utils/adt/arrayfuncs.c:4945 +#: executor/execMain.c:2039 #, c-format -msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "é…åˆ—ã®æ¬¡æ•°(%d)ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "列\"%s\"内ã®NULL値ã¯NOT NULL制約é•åã§ã™" -#: executor/execQual.c:318 executor/execQual.c:346 +#: executor/execMain.c:2086 #, c-format -msgid "array subscript in assignment must not be null" -msgstr "代入ã«ãŠã‘ã‚‹é…åˆ—ã®æ·»ãˆå­—ã¯NULLã§ã¯ã„ã‘ã¾ã›ã‚“" +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "リレーション\"%s\"ã®æ–°ã—ã„è¡Œã¯æ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:641 executor/execQual.c:4022 +#: executor/execMain.c:2193 #, c-format -msgid "attribute %d has wrong type" -msgstr "属性%dã®åž‹ãŒé–“é•ã£ã¦ã„ã¾ã™" +msgid "new row violates check option for view \"%s\"" +msgstr "æ–°ã—ã„行ã¯ãƒ“ュー\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã‚ªãƒ—ションã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:642 executor/execQual.c:4023 +#: executor/execMain.c:2203 #, c-format -msgid "Table has type %s, but query expects %s." -msgstr "テーブルã®åž‹ã¯%sã§ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%sを想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "æ–°ã—ã„行ã¯ãƒ†ãƒ¼ãƒ–ル\"%2$s\"行レベルセキュリティãƒãƒªã‚·\"%1$s\"ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:845 executor/execQual.c:862 executor/execQual.c:1026 -#: executor/nodeModifyTable.c:85 executor/nodeModifyTable.c:95 -#: executor/nodeModifyTable.c:112 executor/nodeModifyTable.c:120 +#: executor/execMain.c:2208 #, c-format -msgid "table row type and query-specified row type do not match" -msgstr "テーブルã®è¡Œåž‹ã¨å•ã„åˆã‚ã›ã§æŒ‡å®šã—ãŸè¡Œåž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“" +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "æ–°ã—ã„行ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:846 +#: executor/execMain.c:2215 #, c-format -msgid "Table row contains %d attribute, but query expects %d." -msgid_plural "Table row contains %d attributes, but query expects %d." -msgstr[0] "テーブル行ã«ã¯%d属性ã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" -msgstr[1] "テーブル行ã«ã¯%d属性ã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "æ–°ã—ã„行ã¯ãƒ†ãƒ¼ãƒ–ル\"%1$s\"ã®è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·\"%2$s\"(USINGå¼)ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:863 executor/nodeModifyTable.c:96 +#: executor/execMain.c:2220 #, c-format -msgid "Table has type %s at ordinal position %d, but query expects %s." -msgstr "テーブルã§ã¯ %2$d 番目ã®åž‹ã¯ %1$s ã§ã™ãŒã€å•ã„åˆã‚ã›ã§ã¯ %3$s を想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "æ–°ã—ã„行ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã®è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·(USINGå¼)ã«é•åã—ã¦ã„ã¾ã™" -#: executor/execQual.c:1027 executor/execQual.c:1625 +#: executor/execPartition.c:337 #, c-format -msgid "Physical storage mismatch on dropped attribute at ordinal position %d." -msgstr "åºæ•°ä½ç½®%dã®å‰Šé™¤ã•れãŸå±žæ€§ã«ãŠã‘ã‚‹ç‰©ç†æ ¼ç´æ–¹å¼ãŒä¸€è‡´ã—ã¾ã›ã‚“。" +msgid "no partition of relation \"%s\" found for row" +msgstr "行ã«å¯¾å¿œã™ã‚‹ãƒ‘ーティションãŒãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s\"ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: executor/execQual.c:1304 parser/parse_func.c:94 parser/parse_func.c:333 -#: parser/parse_func.c:681 +#: executor/execPartition.c:339 #, c-format -msgid "cannot pass more than %d argument to a function" -msgid_plural "cannot pass more than %d arguments to a function" -msgstr[0] "関数ã«%dã‚’è¶…ãˆã‚‹å¼•数を渡ã›ã¾ã›ã‚“" -msgstr[1] "関数ã«%dã‚’è¶…ãˆã‚‹å¼•数を渡ã›ã¾ã›ã‚“" +msgid "Partition key of the failing row contains %s." +msgstr "失敗ã—ãŸè¡Œã®ãƒ‘ーティションキーã¯%sã‚’å«ã¿ã¾ã™ã€‚" -#: executor/execQual.c:1493 +#: executor/execReplication.c:197 executor/execReplication.c:361 #, c-format -msgid "functions and operators can take at most one set argument" -msgstr "é–¢æ•°ã¨æ¼”ç®—å­ã¯å¤šãã¦ã‚‚1ã¤ã®é›†åˆå¼•æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã™" +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "ロック対象ã®ã‚¿ãƒ—ルã¯åŒæ™‚ã«è¡Œã‚ã‚ŒãŸæ›´æ–°ã«ã‚ˆã£ã¦ä»–ã®å­ãƒ†ãƒ¼ãƒ–ルã«ç§»å‹•ã•れã¦ã„ã¾ã™ã€å†è©¦è¡Œã—ã¦ã„ã¾ã™" -#: executor/execQual.c:1543 +#: executor/execReplication.c:201 executor/execReplication.c:365 #, c-format -msgid "function returning setof record called in context that cannot accept type record" -msgstr "複数行レコードを返ã™é–¢æ•°ãŒã€ãƒ¬ã‚³ãƒ¼ãƒ‰åž‹ã‚’å—ã‘付ã‘ãªã„文脈ã§å‘¼ã³å‡ºã•れã¾ã—ãŸ" +msgid "concurrent update, retrying" +msgstr "åŒæ™‚æ›´æ–°ãŒã‚りã¾ã—ãŸã€ãƒªãƒˆãƒ©ã‚¤ã—ã¾ã™" -#: executor/execQual.c:1598 executor/execQual.c:1614 executor/execQual.c:1624 +#: executor/execReplication.c:262 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 +#: utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 #, c-format -msgid "function return row and query-specified return row do not match" -msgstr "å•ã„åˆã‚ã›ãŒæŒ‡å®šã—ãŸæˆ»ã‚Šå€¤ã®è¡Œã¨å®Ÿéš›ã®é–¢æ•°ã®æˆ»ã‚Šå€¤ã®è¡ŒãŒä¸€è‡´ã—ã¾ã›ã‚“" +msgid "could not identify an equality operator for type %s" +msgstr "åž‹%sã®ç­‰ä¾¡æ€§æ¼”ç®—å­ã‚’識別ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: executor/execQual.c:1599 +#: executor/execReplication.c:578 #, c-format -msgid "Returned row contains %d attribute, but query expects %d." -msgid_plural "Returned row contains %d attributes, but query expects %d." -msgstr[0] "%d属性をæŒã¤è¡ŒãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" -msgstr[1] "%d属性をæŒã¤è¡ŒãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%dを想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "テーブル\"%s\"ã¯è¤‡è£½è­˜åˆ¥ã‚’æŒãŸãšã‹ã¤æ›´æ–°ã‚’発行ã—ã¦ã„ã‚‹ãŸã‚ã€æ›´æ–°ã§ãã¾ã›ã‚“" -#: executor/execQual.c:1615 +#: executor/execReplication.c:580 #, c-format -msgid "Returned type %s at ordinal position %d, but query expects %s." -msgstr "åºæ•°ä½ç½®%2$dã®åž‹%1$sãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%3$sを想定ã—ã¦ã„ã¾ã™ã€‚" +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ›´æ–°ã‚’å¯èƒ½ã«ã™ã‚‹ã«ã¯ ALTER TABLE ã§ REPLICA IDENTITY を設定ã—ã¦ãã ã•ã„。" -#: executor/execQual.c:1859 executor/execQual.c:2284 +#: executor/execReplication.c:584 #, c-format -msgid "table-function protocol for materialize mode was not followed" -msgstr "materializeモードã§ã¯ãƒ†ãƒ¼ãƒ–ル関数プロトコルã«å¾“ã„ã¾ã›ã‚“" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "テーブル\"%s\"ã¯è¤‡è£½è­˜åˆ¥ãŒãªãã‹ã¤å‰Šé™¤ã‚’発行ã—ã¦ã„ã‚‹ãŸã‚ã€ã“ã®ãƒ†ãƒ¼ãƒ–ルã§ã¯è¡Œã®å‰Šé™¤ãŒã§ãã¾ã›ã‚“" -#: executor/execQual.c:1879 executor/execQual.c:2291 +#: executor/execReplication.c:586 #, c-format -msgid "unrecognized table-function returnMode: %d" -msgstr "テーブル関数ã®returnModeãŒä¸æ˜Žã§ã™: %d" +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "ã“ã®ãƒ†ãƒ¼ãƒ–ルã§ã®è¡Œå‰Šé™¤ã‚’å¯èƒ½ã«ã™ã‚‹ã«ã¯ ALTER TABLE ã§ REPLICA IDENTITY を設定ã—ã¦ãã ã•ã„。" -#: executor/execQual.c:2201 +#: executor/execReplication.c:605 #, c-format -msgid "function returning set of rows cannot return null value" -msgstr "行ã®é›†åˆã‚’è¿”ã™é–¢æ•°ã¯NULL値を返ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "logical replication target relation \"%s.%s\" is not a table" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションã®å¯¾è±¡ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" -#: executor/execQual.c:2258 +#: executor/execSRF.c:308 #, c-format msgid "rows returned by function are not all of the same row type" msgstr "関数ã‹ã‚‰æˆ»ã•れãŸè¡Œã¯ã™ã¹ã¦ãŒåŒã˜è¡Œåž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: executor/execQual.c:2449 -#, c-format -msgid "IS DISTINCT FROM does not support set arguments" -msgstr "IS DISTINCT FROM ã¯é›†åˆå¼•数をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" - -#: executor/execQual.c:2526 -#, c-format -msgid "op ANY/ALL (array) does not support set arguments" -msgstr "op ANY/ALL (array)ã¯é›†åˆå¼•数をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" - -#: executor/execQual.c:3079 -#, c-format -msgid "cannot merge incompatible arrays" -msgstr "äº’æ›æ€§ãŒãªã„é…列をマージã§ãã¾ã›ã‚“" - -#: executor/execQual.c:3080 -#, c-format -msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." -msgstr "è¦ç´ åž‹%sã®é…列をè¦ç´ åž‹%sã®ARRAYå¼ã«å«ã‚られã¾ã›ã‚“" - -#: executor/execQual.c:3121 executor/execQual.c:3148 -#: utils/adt/arrayfuncs.c:547 -#, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions" -msgstr "多次元é…åˆ—ã¯æ¬¡æ•°ã«åˆã£ãŸé…列å¼ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: executor/execQual.c:3663 -#, c-format -msgid "NULLIF does not support set arguments" -msgstr "NULLIFã¯é›†åˆå¼•数をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" - -#: executor/execQual.c:3893 utils/adt/domains.c:131 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format -msgid "domain %s does not allow null values" -msgstr "ドメイン%sã¯NULL値を許ã—ã¾ã›ã‚“" - -#: executor/execQual.c:3923 utils/adt/domains.c:168 -#, c-format -msgid "value for domain %s violates check constraint \"%s\"" -msgstr "ドメイン%sã®å€¤ãŒæ¤œæŸ»åˆ¶ç´„\"%s\"ã«é•åã—ã¦ã„ã¾ã™" - -#: executor/execQual.c:4281 -#, c-format -#| msgid "pointer to pointer is not supported for this data type" -msgid "WHERE CURRENT OF is not supported for this table type" -msgstr "ã“ã®ç¨®é¡žã®ãƒ†ãƒ¼ãƒ–ルã§ã¯WHERE CURRENT OFをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" +msgid "table-function protocol for materialize mode was not followed" +msgstr "実体化モードã®ãƒ†ãƒ¼ãƒ–ル関数プロトコルã«å¾“ã£ã¦ã„ã¾ã›ã‚“" -#: executor/execQual.c:4425 optimizer/util/clauses.c:583 -#: parser/parse_agg.c:354 +#: executor/execSRF.c:363 executor/execSRF.c:665 #, c-format -msgid "aggregate function calls cannot be nested" -msgstr "集約関数ã®å‘¼ã³å‡ºã—を入れå­ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "unrecognized table-function returnMode: %d" +msgstr "識別ã§ããªã„テーブル関数ã®returnMode: %d" -#: executor/execQual.c:4465 optimizer/util/clauses.c:658 -#: parser/parse_agg.c:450 +#: executor/execSRF.c:871 #, c-format -msgid "window function calls cannot be nested" -msgstr "ウィンドウ関数ã®å‘¼ã³å‡ºã—を入れå­ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "function returning setof record called in context that cannot accept type record" +msgstr "レコード集åˆã‚’è¿”ã™é–¢æ•°ãŒã€ãƒ¬ã‚³ãƒ¼ãƒ‰åž‹ãŒå—ã‘付ã‘られãªã„文脈ã§å‘¼ã³å‡ºã•れã¾ã—ãŸ" -#: executor/execQual.c:4677 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format -msgid "target type is not an array" -msgstr "対照型ã¯é…列ã§ã¯ã‚りã¾ã›ã‚“" +msgid "function return row and query-specified return row do not match" +msgstr "å•ã„åˆã‚ã›ãŒæŒ‡å®šã—ãŸæˆ»ã‚Šå€¤ã®è¡Œã¨å®Ÿéš›ã®é–¢æ•°ã®æˆ»ã‚Šå€¤ã®è¡ŒãŒä¸€è‡´ã—ã¾ã›ã‚“" -#: executor/execQual.c:4791 +#: executor/execSRF.c:927 #, c-format -msgid "ROW() column has type %s instead of type %s" -msgstr "ROW()ã®åˆ—ã¯åž‹%2$sã§ã¯ãªãåž‹%1$sã‚’æŒã¡ã¾ã™" +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "%d属性をæŒã¤è¡ŒãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%d個を想定ã—ã¦ã„ã¾ã™ã€‚" +msgstr[1] "%d属性をæŒã¤è¡ŒãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%d個を想定ã—ã¦ã„ã¾ã™ã€‚" -#: executor/execQual.c:4926 utils/adt/arrayfuncs.c:3383 -#: utils/adt/rowtypes.c:951 +#: executor/execSRF.c:943 #, c-format -msgid "could not identify a comparison function for type %s" -msgstr "åž‹%sã®æ¯”較関数を識別ã§ãã¾ã›ã‚“" +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "åºæ•°ä½ç½®%2$dã®åž‹%1$sãŒè¿”ã•れã¾ã—ãŸã€‚å•ã„åˆã‚ã›ã§ã¯%3$sを想定ã—ã¦ã„ã¾ã™ã€‚" -#: executor/execUtils.c:844 +#: executor/execUtils.c:687 #, c-format -#| msgid "Materialized view \"%s.%s\"" msgid "materialized view \"%s\" has not been populated" -msgstr "マテリアライズドビュー \"%s\"ã«ã¯ãƒ‡ãƒ¼ã‚¿ãŒæŠ•å…¥ã•れã¦ã„ã¾ã›ã‚“" +msgstr "実体化ビュー\"%s\"ã«ã¯ãƒ‡ãƒ¼ã‚¿ãŒæ ¼ç´ã•れã¦ã„ã¾ã›ã‚“" -#: executor/execUtils.c:846 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "REFRESH MATERIALIZED VIEWコマンドを使用ã—ã¦ãã ã•ã„。" -#: executor/execUtils.c:1323 -#, c-format -msgid "could not create exclusion constraint \"%s\"" -msgstr "排除制約 \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: executor/execUtils.c:1325 -#, c-format -msgid "Key %s conflicts with key %s." -msgstr "キー %s ãŒã‚­ãƒ¼ %s ã¨ç«¶åˆã—ã¦ã„ã¾ã™" - -#: executor/execUtils.c:1332 -#, c-format -msgid "conflicting key value violates exclusion constraint \"%s\"" -msgstr "é‡è¤‡ã‚­ãƒ¼ã®å€¤ãŒæŽ’除制約 \"%s\" ã«é•åã—ã¦ã„ã¾ã™" - -#: executor/execUtils.c:1334 -#, c-format -msgid "Key %s conflicts with existing key %s." -msgstr "キー %s ãŒæ—¢å­˜ã®ã‚­ãƒ¼ %s ã¨ç«¶åˆã—ã¦ã„ã¾ã™" - #: executor/functions.c:225 #, c-format msgid "could not determine actual type of argument declared %s" -msgstr "%s都宣言ã•れãŸå¼•æ•°ã®åž‹ã‚’決定ã§ãã¾ã›ã‚“" +msgstr "%sã¨å®£è¨€ã•れãŸå¼•æ•°ã®åž‹ã‚’決定ã§ãã¾ã›ã‚“" + +#: executor/functions.c:521 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "SQL関数ã®ä¸­ã§ã¯ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã¨ã®é–“ã®COPYã¯ã§ãã¾ã›ã‚“" #. translator: %s is a SQL statement name -#: executor/functions.c:498 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "SQL関数ã§ã¯%sã¯è¨±ã•れã¾ã›ã‚“" #. translator: %s is a SQL statement name -#: executor/functions.c:505 executor/spi.c:1365 executor/spi.c:2149 +#: executor/functions.c:535 executor/spi.c:1422 executor/spi.c:2212 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "volatile関数以外ã§ã¯%sã¯è¨±ã•れã¾ã›ã‚“" -#: executor/functions.c:630 +#: executor/functions.c:656 #, c-format msgid "could not determine actual result type for function declared to return type %s" msgstr "戻り値型%sã¨ã—ã¦å®£è¨€ã•れãŸé–¢æ•°ã®å®Ÿéš›ã®çµæžœåž‹ã‚’決定ã§ãã¾ã›ã‚“" -#: executor/functions.c:1395 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "SQL関数\"%s\"ã®è¡Œç•ªå· %d" -#: executor/functions.c:1421 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "SQL関数\"%s\"ã®èµ·å‹•中" -#: executor/functions.c:1580 executor/functions.c:1617 -#: executor/functions.c:1629 executor/functions.c:1742 -#: executor/functions.c:1775 executor/functions.c:1805 +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "出力引数をæŒã¤ãƒ—ロシージャã®å‘¼ã³å‡ºã—ã¯SQL関数ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: executor/functions.c:1657 executor/functions.c:1690 +#: executor/functions.c:1702 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "%sã‚’è¿”ã™ã¨å®£è¨€ã•れãŸé–¢æ•°ã«ãŠã„ã¦æˆ»ã‚Šå€¤åž‹ãŒä¸€è‡´ã—ã¾ã›ã‚“" -#: executor/functions.c:1582 +#: executor/functions.c:1659 #, c-format msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." -msgstr "é–¢æ•°ã®æœ€å¾Œã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã¯ SELECT ã‚‚ã—ã㯠RETURNING 付ãã®INSERT/UPDATE/DELETE ã®ã„ãšã‚Œã‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "é–¢æ•°ã®æœ€å¾Œã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã¯ SELECT ã‚‚ã—ã㯠INSERT/UPDATE/DELETE RETURNING ã®ã„ãšã‚Œã‹ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: executor/functions.c:1619 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." -msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã¯æ­£ç¢ºã«1列を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã¯ã¡ã‚‡ã†ã©1列を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: executor/functions.c:1631 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." -msgstr "å®Ÿéš›ã®æˆ»ã‚Šå€¤åž‹ã¯%sã§ã™" +msgstr "å®Ÿéš›ã®æˆ»ã‚Šå€¤åž‹ã¯%sã§ã™ã€‚" -#: executor/functions.c:1744 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." -msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒè¿”ã™åˆ—ãŒå¤šã™ãŽã¾ã™" +msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒè¿”ã™åˆ—ãŒå¤šã™ãŽã¾ã™ã€‚" -#: executor/functions.c:1777 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." -msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒåˆ— %3$d ã§ %2$s ã§ã¯ãªã %1$s ã‚’è¿”ã—ã¾ã—ãŸ" +msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒåˆ—%3$dã§%2$sã§ã¯ãªã%1$sã‚’è¿”ã—ã¾ã—ãŸã€‚" -#: executor/functions.c:1807 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." -msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒè¿”ã™åˆ—ãŒå°‘ãªã™ãŽã¾ã™" +msgstr "最後ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒè¿”ã™åˆ—ãŒå°‘ãªã™ãŽã¾ã™ã€‚" -#: executor/functions.c:1856 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "戻り値型%sã¯SQL関数ã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: executor/nodeAgg.c:1752 executor/nodeWindowAgg.c:1870 +#: executor/nodeAgg.c:2802 parser/parse_agg.c:633 parser/parse_agg.c:663 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "集約関数ã®å‘¼ã³å‡ºã—を入れå­ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: executor/nodeAgg.c:2988 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "集約%uã¯å…¥åŠ›ãƒ‡ãƒ¼ã‚¿åž‹ã¨é·ç§»ç”¨ã®åž‹é–“ã§äº’æ›æ€§ãŒå¿…è¦ã§ã™" -#: executor/nodeHashjoin.c:823 executor/nodeHashjoin.c:853 +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "カスタムスキャン\"%s\"ã¯MarkPosをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "ãƒãƒƒã‚·ãƒ¥çµåˆç”¨ä¸€æ™‚ãƒ•ã‚¡ã‚¤ãƒ«ã‚’å·»ãæˆ»ã—ã§ãã¾ã›ã‚“: %m" -#: executor/nodeHashjoin.c:888 executor/nodeHashjoin.c:894 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "ãƒãƒƒã‚·ãƒ¥çµåˆç”¨ä¸€æ™‚ファイルを書ã出ã›ã¾ã›ã‚“: %m" -#: executor/nodeHashjoin.c:928 executor/nodeHashjoin.c:938 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "ãƒãƒƒã‚·ãƒ¥çµåˆç”¨ä¸€æ™‚ファイルã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“: %m" -#: executor/nodeLimit.c:253 +#: executor/nodeIndexonlyscan.c:236 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "概算è·é›¢é–¢æ•°ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚ªãƒ³ãƒªãƒ¼ã‚¹ã‚­ãƒ£ãƒ³ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET ã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: executor/nodeLimit.c:280 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT ã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: executor/nodeMergejoin.c:1576 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOINã¯ãƒžãƒ¼ã‚¸çµåˆå¯èƒ½ãªçµåˆæ¡ä»¶ã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" -#: executor/nodeMergejoin.c:1596 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOINã¯ãƒžãƒ¼ã‚¸çµåˆå¯èƒ½ãªçµåˆæ¡ä»¶ã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" -#: executor/nodeModifyTable.c:86 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "å•ã„åˆã‚ã›ã®åˆ—ãŒå¤šã™ãŽã¾ã™" -#: executor/nodeModifyTable.c:113 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." -msgstr "クエリー㧠%d 番目ã«å‰Šé™¤ã•れるカラムã®å€¤ã‚’指定ã—ã¦ã„ã¾ã™ã€‚" +msgstr "å•ã„åˆã‚ã›ã§ %d 番目ã«å‰Šé™¤ã•れる列ã®å€¤ã‚’指定ã—ã¦ã„ã¾ã™ã€‚" -#: executor/nodeModifyTable.c:121 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." -msgstr "å•ã„åˆã‚ã›ã®åˆ—ãŒå°‘ãªã™ãŽã¾ã™" +msgstr "å•ã„åˆã‚ã›ã®åˆ—ãŒå°‘ãªã™ãŽã¾ã™ã€‚" -#: executor/nodeSubplan.c:304 executor/nodeSubplan.c:343 -#: executor/nodeSubplan.c:970 +#: executor/nodeModifyTable.c:773 #, c-format -msgid "more than one row returned by a subquery used as an expression" -msgstr "副å•ã„åˆã‚ã›ã§1行を超ãˆã‚‹è¡Œã‚’è¿”ã™ã‚‚ã®ãŒå¼ã¨ã—ã¦ä½¿ç”¨ã•れã¾ã—ãŸ" +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "削除対象ã®ã‚¿ãƒ—ルã¯åŒæ™‚ã«è¡Œã‚ã‚ŒãŸæ›´æ–°ã«ã‚ˆã£ã¦ã™ã§ã«ä»–ã®å­ãƒ†ãƒ¼ãƒ–ルã«ç§»å‹•ã•れã¦ã„ã¾ã™" -#: executor/nodeWindowAgg.c:1254 +#: executor/nodeModifyTable.c:1085 #, c-format -msgid "frame starting offset must not be null" -msgstr "フレームãƒã‚¤ãƒ³ã‚¿ã®ã‚ªãƒ•セット㯠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgid "invalid ON UPDATE specification" +msgstr "䏿­£ãª ON UPDATE 指定ã§ã™" -#: executor/nodeWindowAgg.c:1267 +#: executor/nodeModifyTable.c:1086 #, c-format -msgid "frame starting offset must not be negative" -msgstr "フレーム開始オフセットã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "çµæžœã‚¿ãƒ—ルをもã¨ã®ãƒ‘ーティションã§ã¯ãªãç•°ãªã‚‹ãƒ‘ーティションã«è¿½åŠ ã—よã†ã¨ã—ã¾ã—ãŸã€‚" -#: executor/nodeWindowAgg.c:1280 +#: executor/nodeModifyTable.c:1261 #, c-format -msgid "frame ending offset must not be null" -msgstr "フレーム終了オフセット㯠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "更新対象ã®ã‚¿ãƒ—ルã¯åŒæ™‚ã«è¡Œã‚ã‚ŒãŸæ›´æ–°ã«ã‚ˆã£ã¦ã™ã§ã«ä»–ã®å­ãƒ†ãƒ¼ãƒ–ルã«ç§»å‹•ã•れã¦ã„ã¾ã™" -#: executor/nodeWindowAgg.c:1293 +#: executor/nodeModifyTable.c:1412 #, c-format -msgid "frame ending offset must not be negative" -msgstr "フレーム終了オフセットã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "ON CONFLICT DO UPDATE コマンドã¯è¡Œã«å†åº¦å½±éŸ¿ã‚’与ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: executor/spi.c:213 +#: executor/nodeModifyTable.c:1413 #, c-format -msgid "transaction left non-empty SPI stack" -msgstr "トランザクションã¯ç©ºã§ãªã„SPIスタックを残ã—ã¾ã—ãŸ" +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "åŒã˜ã‚³ãƒžãƒ³ãƒ‰ã§ã®æŒ¿å…¥å€™è£œã®è¡ŒãŒåŒã˜åˆ¶ç´„値をæŒã¤ã“ã¨ãŒãªã„よã†ã«ã—ã¦ãã ã•ã„" -#: executor/spi.c:214 executor/spi.c:278 +#: executor/nodeSamplescan.c:279 #, c-format -msgid "Check for missing \"SPI_finish\" calls." -msgstr "\"SPI_finish\"å‘¼å‡ºã®æŠœã‘を確èªãã ã•ã„" +msgid "TABLESAMPLE parameter cannot be null" +msgstr "TABLESAMPLEパラメータã«nullã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: executor/spi.c:277 +#: executor/nodeSamplescan.c:291 #, c-format -msgid "subtransaction left non-empty SPI stack" -msgstr "サブトランザクションãŒç©ºã§ãªã„SPIスタックを残ã—ã¾ã—ãŸ" +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "TABLESAMPLE REPEATABLE パラメータã«nullã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: executor/spi.c:1229 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1127 #, c-format -msgid "cannot open multi-query plan as cursor" -msgstr "カーソルã«ãƒžãƒ«ãƒã‚¯ã‚¨ãƒªãƒ—ランを開ãã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "more than one row returned by a subquery used as an expression" +msgstr "å¼ã¨ã—ã¦ä½¿ç”¨ã•れãŸå‰¯å•ã„åˆã‚ã›ãŒ2行以上ã®è¡Œã‚’è¿”ã—ã¾ã—ãŸ" -#. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1234 +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "åå‰ç©ºé–“URIã«nullã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "行フィルタå¼ã¯nullã«ãªã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "列フィルタå¼ã¯nullã«ãªã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "列\"%s\"ã®ãƒ•ィルタãŒnullã§ã™ã€‚" + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "列\"%s\"ã§nullã¯è¨±ã•れã¦ã„ã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "ç§»å‹•é›†ç´„ã®æŽ¨ç§»é–¢æ•°ã¯nullã‚’è¿”å´ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:2057 +#, c-format +msgid "frame starting offset must not be null" +msgstr "フレームã®é–‹å§‹ã‚ªãƒ•セット㯠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:2070 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "フレームã®é–‹å§‹ã‚ªãƒ•セットã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:2082 +#, c-format +msgid "frame ending offset must not be null" +msgstr "フレームã®çµ‚了オフセット㯠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:2095 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "フレームã®çµ‚了オフセットã¯è² æ•°ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "集約関数 %s ã¯ã‚¦ã‚¤ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¨ã—ã¦ã®ä½¿ç”¨ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: executor/spi.c:233 executor/spi.c:272 +#, c-format +msgid "invalid transaction termination" +msgstr "䏿­£ãªãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³çµ‚了" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "サブトランザクションã®å®Ÿè¡Œä¸­ã¯ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã›ã‚“" + +#: executor/spi.c:278 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "サブトランザクションã®å®Ÿè¡Œä¸­ã¯ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã§ãã¾ã›ã‚“" + +#: executor/spi.c:317 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "トランザクションã¯ç©ºã§ãªã„SPIスタックを残ã—ã¾ã—ãŸ" + +#: executor/spi.c:318 executor/spi.c:381 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "\"SPI_finish\"å‘¼å‡ºã®æŠœã‘を確èªãã ã•ã„" + +#: executor/spi.c:380 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "サブトランザクションãŒç©ºã§ãªã„SPIスタックを残ã—ã¾ã—ãŸ" + +#: executor/spi.c:1283 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "カーソルã«ãƒžãƒ«ãƒã‚¯ã‚¨ãƒªã®å®Ÿè¡Œè¨ˆç”»ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1288 #, c-format msgid "cannot open %s query as cursor" msgstr "カーソルã§%så•ã„åˆã‚ã›ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“" -#: executor/spi.c:1342 +#: executor/spi.c:1393 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHAREã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: executor/spi.c:1343 parser/analyze.c:2094 +#: executor/spi.c:1394 parser/analyze.c:2474 #, c-format msgid "Scrollable cursors must be READ ONLY." -msgstr "スクロールå¯èƒ½ã‚«ãƒ¼ã‚½ãƒ«ã¯èª­ã¿å–りã®ã¿ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スクロールå¯èƒ½ã‚«ãƒ¼ã‚½ãƒ«ã¯èª­ã¿å–り専用ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: executor/spi.c:2439 +#: executor/spi.c:2534 #, c-format msgid "SQL statement \"%s\"" msgstr "SQLæ–‡ \"%s\"" -#: foreign/foreign.c:192 +#: executor/tqueue.c:70 #, c-format -msgid "user mapping not found for \"%s\"" -msgstr "\"%s\" ã«å¯¾ã™ã‚‹ãƒ¦ãƒ¼ã‚¶å¯¾å¿œè¡¨ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" +msgid "could not send tuple to shared-memory queue" +msgstr "共有メモリキューã«ã‚¿ãƒ—ルをé€å‡ºã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: foreign/foreign.c:348 +#: foreign/foreign.c:188 #, c-format -msgid "foreign-data wrapper \"%s\" has no handler" -msgstr "外部データラッパー \"%s\" ã«ã¯ãƒãƒ³ãƒ‰ãƒ©ãŒã‚りã¾ã›ã‚“" +msgid "user mapping not found for \"%s\"" +msgstr "\"%s\" ã«å¯¾ã™ã‚‹ãƒ¦ãƒ¼ã‚¶å¯¾å¿œè¡¨ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: foreign/foreign.c:573 +#: foreign/foreign.c:640 #, c-format msgid "invalid option \"%s\"" -msgstr "\"%s\" オプションã¯ç„¡åйã§ã™" +msgstr "䏿­£ãªã‚ªãƒ—ション\"%s\" " -#: foreign/foreign.c:574 +#: foreign/foreign.c:641 #, c-format msgid "Valid options in this context are: %s" -msgstr "ã“ã®æ–‡è„ˆã§æœ‰åйãªã‚ªãƒ—ション:%s" +msgstr "ã“ã®æ–‡è„ˆã§æœ‰åйãªã‚ªãƒ—ション: %s" + +#: gram.y:1026 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD ã¯ä»Šå¾Œã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: gram.y:1027 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "UNENCRYPTED を削除ã—ã¦ãã ã•ã„。ãã†ã™ã‚Œã°æ›¿ã‚りã«ãƒ‘スワードを暗å·åŒ–å½¢å¼ã§æ ¼ç´ã—ã¾ã™ã€‚" -#: gram.y:946 +#: gram.y:1089 #, c-format msgid "unrecognized role option \"%s\"" msgstr "ロールオプション \"%s\" ãŒèªè­˜ã§ãã¾ã›ã‚“" -#: gram.y:1228 gram.y:1243 +#: gram.y:1336 gram.y:1351 #, c-format msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTSã‚“ã¯ã‚¹ã‚­ãƒ¼ãƒžè¦ç´ ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: gram.y:1385 +#: gram.y:1496 #, c-format msgid "current database cannot be changed" msgstr "ç¾åœ¨ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’変更ã§ãã¾ã›ã‚“" -#: gram.y:1512 gram.y:1527 +#: gram.y:1620 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" -msgstr "時間帯ã®é–“éš”ã¯HOURã¾ãŸã¯HOUR TO MINUTEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "タイムゾーンã®é–“éš”ã¯HOURã¾ãŸã¯HOUR TO MINUTEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: gram.y:2138 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "列番å·ã¯1ã‹ã‚‰%dã¾ã§ã®ç¯„囲ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: gram.y:2677 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "シーケンスã®ã‚ªãƒ—ション\"%s\"ã¯ã“ã“ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: gram.y:2706 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã§æ³•(除数)ãŒ2回以上指定ã•れã¦ã„ã¾ã™" + +#: gram.y:2715 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã§å‰°ä½™ãŒ2回以上指定ã•れã¦ã„ã¾ã™" + +#: gram.y:2722 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã®å¢ƒç•Œæ¡ä»¶ \"%s\" ãŒèªè­˜ã§ãã¾ã›ã‚“" + +#: gram.y:2730 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã§ã¯æ³•(除数)ã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: gram.y:1532 gram.y:10069 gram.y:12359 +#: gram.y:2734 #, c-format -msgid "interval precision specified twice" -msgstr "インターãƒãƒ«åž‹ã®ç²¾åº¦ãŒï¼’回指定ã•れã¾ã—ãŸ" +msgid "remainder for hash partition must be specified" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã§ã¯å‰°ä½™ã®æŒ‡å®šãŒå¿…è¦ã§ã™" -#: gram.y:2379 gram.y:2408 +#: gram.y:2986 gram.y:3015 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "STDIN/STDOUTã¯PROGRAMã¨åŒæ™‚ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:2666 gram.y:2673 gram.y:9331 gram.y:9339 +#: gram.y:3325 gram.y:3332 gram.y:11462 gram.y:11470 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "一時テーブル作æˆã«ãŠã‘ã‚‹GLOBALã¯å»ƒæ­¢äºˆå®šã§ã™" -#: gram.y:3110 utils/adt/ri_triggers.c:310 utils/adt/ri_triggers.c:367 -#: utils/adt/ri_triggers.c:786 utils/adt/ri_triggers.c:1009 -#: utils/adt/ri_triggers.c:1165 utils/adt/ri_triggers.c:1346 -#: utils/adt/ri_triggers.c:1511 utils/adt/ri_triggers.c:1687 -#: utils/adt/ri_triggers.c:1867 utils/adt/ri_triggers.c:2058 -#: utils/adt/ri_triggers.c:2116 utils/adt/ri_triggers.c:2221 -#: utils/adt/ri_triggers.c:2386 +#: gram.y:3814 utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 +#: utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 +#: utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 +#: utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 +#: utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "MMATCH PARTIAL ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:4343 +#: gram.y:5296 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "èªè­˜ã§ããªã„行セキュリティオプション \"%s\"" + +#: gram.y:5297 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "ç¾æ™‚点ã§ã¯ PERMISSIVE ã‚‚ã—ã㯠RESTRICTIVE ãƒãƒªã‚·ã®ã¿ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" + +#: gram.y:5405 msgid "duplicate trigger events specified" msgstr "é‡è¤‡ã—ãŸãƒˆãƒªã‚¬ãƒ¼ã‚¤ãƒ™ãƒ³ãƒˆãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: gram.y:4438 parser/parse_utilcmd.c:2589 parser/parse_utilcmd.c:2615 +#: gram.y:5546 parser/parse_utilcmd.c:3313 parser/parse_utilcmd.c:3339 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "INITIALLY DEFERREDã¨å®£è¨€ã•れãŸåˆ¶ç´„ã¯DEFERRABLEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: gram.y:4445 +#: gram.y:5553 #, c-format msgid "conflicting constraint properties" msgstr "制約属性ã®ç«¶åˆ" -#: gram.y:4577 +#: gram.y:5659 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "CREATE ASSERTIONã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:4593 +#: gram.y:5674 #, c-format msgid "DROP ASSERTION is not yet implemented" msgstr "DROP ASSERTIONã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:4943 +#: gram.y:6054 #, c-format msgid "RECHECK is no longer required" msgstr "RECHECK ã¯ã‚‚ã¯ã‚„å¿…è¦ã¨ã•れã¾ã›ã‚“" -#: gram.y:4944 +#: gram.y:6055 #, c-format msgid "Update your data type." msgstr "データ型を更新ã—ã¦ãã ã•ã„" -#: gram.y:6646 utils/adt/regproc.c:656 +#: gram.y:7791 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "集約ã¯å‡ºåŠ›ã®å¼•æ•°ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: gram.y:8179 utils/adt/regproc.c:691 utils/adt/regproc.c:732 #, c-format msgid "missing argument" -msgstr "引数ãŒã‚りã¾ã›ã‚“" +msgstr "引数ãŒè¶³ã‚Šã¾ã›ã‚“" -#: gram.y:6647 utils/adt/regproc.c:657 +#: gram.y:8180 utils/adt/regproc.c:692 utils/adt/regproc.c:733 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." -msgstr "å˜é …演算å­ã®å­˜åœ¨ã—ãªã„引数を表ã™ã®ã«NONEを使用ã—ã¦ãã ã•ã„。" +msgstr "å˜é …演算å­ã®å­˜åœ¨ã—ãªã„引数を表ã™ã«ã¯NONEを使用ã—ã¦ãã ã•ã„。" -#: gram.y:8027 gram.y:8045 +#: gram.y:10045 gram.y:10063 #, c-format -#| msgid "WITH CHECK OPTION is not implemented" msgid "WITH CHECK OPTION not supported on recursive views" msgstr "WITH CHECK OPTIONã¯å†å¸°ãƒ“ューã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:8976 +#: gram.y:10560 #, c-format -msgid "number of columns does not match number of values" -msgstr "åˆ—ã®æ•°ãŒVALUESã®æ•°ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgid "unrecognized VACUUM option \"%s\"" +msgstr "èªè­˜ã§ããªã„VACUUMオプション \"%s\"" -#: gram.y:9435 +#: gram.y:11570 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "LIMIT #,#æ§‹æ–‡ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:9436 +#: gram.y:11571 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "分割ã—ã¦LIMITã¨OFFSETå¥ã‚’使用ã—ã¦ãã ã•ã„" -#: gram.y:9649 gram.y:9674 +#: gram.y:11869 gram.y:11894 #, c-format msgid "VALUES in FROM must have an alias" -msgstr "FROMå¥ã®VALUESã¯åˆ¥åã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "FROMå¥ã®VALUESã«ã¯åˆ¥åãŒå¿…è¦ã§ã™" -#: gram.y:9650 gram.y:9675 +#: gram.y:11870 gram.y:11895 #, c-format msgid "For example, FROM (VALUES ...) [AS] foo." msgstr "例ãˆã°ã€FROM (VALUES ...) [AS] foo。" -#: gram.y:9655 gram.y:9680 +#: gram.y:11875 gram.y:11900 #, c-format msgid "subquery in FROM must have an alias" -msgstr "FROMå¥ã®å‰¯å•ã„åˆã‚ã›ã¯åˆ¥åã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "FROMå¥ã®å‰¯å•ã„åˆã‚ã›ã«ã¯åˆ¥åãŒå¿…è¦ã§ã™" -#: gram.y:9656 gram.y:9681 +#: gram.y:11876 gram.y:11901 #, c-format msgid "For example, FROM (SELECT ...) [AS] foo." msgstr "例ãˆã°ã€FROM (SELECT ...) [AS] foo。" -#: gram.y:10195 +#: gram.y:12354 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "DEFAULT値ã¯ä¸€ã¤ã ã‘指定å¯èƒ½ã§ã™" + +#: gram.y:12363 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "列一ã¤ã«ã¤ãPATH値ã¯ä¸€ã¤ã ã‘指定å¯èƒ½ã§ã™" + +#: gram.y:12372 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "列\"%s\"ã§NULL / NOT NULL宣言ãŒè¡çªã—ã¦ã„ã‚‹ã‹é‡è¤‡ã—ã¦ã„ã¾ã™" + +#: gram.y:12381 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "èªè­˜ã§ããªã„列オプション \"%s\"" + +#: gram.y:12635 #, c-format msgid "precision for type float must be at least 1 bit" -msgstr "æµ®å‹•å°æ•°ç‚¹æ•°ã®åž‹ã®ç²¾åº¦ã¯æœ€ä½Žã§ã‚‚1ビットãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æµ®å‹•å°æ•°ç‚¹æ•°ã®åž‹ã®ç²¾åº¦ã¯æœ€ä½Žã§ã‚‚1ビット必è¦ã§ã™" -#: gram.y:10204 +#: gram.y:12644 #, c-format msgid "precision for type float must be less than 54 bits" -msgstr "æµ®å‹•å°æ•°ç‚¹æ•°ã®åž‹ã®ç²¾åº¦ã¯54ビットよりもå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æµ®å‹•å°æ•°ç‚¹åž‹ã®ç²¾åº¦ã¯54ビットより低ããªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: gram.y:13135 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPSå¼ã®å·¦è¾ºã®ãƒ‘ラメータ数ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: gram.y:13140 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPSå¼ã®å³è¾ºã®ãƒ‘ラメータ数ãŒé–“é•ã£ã¦ã„ã¾ã™" -#: gram.y:10863 +#: gram.y:13315 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "UNIQUE 述部ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: gram.y:11626 +#: gram.y:13662 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "複数ã®ORDER BYå¥ã¯WITHIN GROUPã¨ä¸€ç·’ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gram.y:13667 #, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING 㯠UNBOUNDED ãªã—ã®å ´åˆã®ã¿ã®ã‚µãƒãƒ¼ãƒˆã§ã™" +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCT 㯠WITHIN GROUP ã¨åŒæ™‚ã«ã¯ä½¿ãˆã¾ã›ã‚“" -#: gram.y:11632 +#: gram.y:13672 #, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING 㯠UNBOUNDED ãªã—ã®å ´åˆã®ã¿ã®ã‚µãƒãƒ¼ãƒˆã§ã™" +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADIC 㯠WITHIN GROUP ã¨åŒæ™‚ã«ã¯ä½¿ãˆã¾ã›ã‚“" -#: gram.y:11659 gram.y:11682 +#: gram.y:14125 gram.y:14148 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" -msgstr "æ§‹æˆã®é–‹å§‹éƒ¨åˆ†ãŒ UNBOUNDED FOLLOWING ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "フレームã®é–‹å§‹ã¯ UNBOUNDED FOLLOWING ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: gram.y:11664 +#: gram.y:14130 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "次ã®è¡Œã‹ã‚‰å§‹ã¾ã‚‹ãƒ•レームã¯ã€ç¾åœ¨è¡Œã§ã¯çµ‚了ã§ãã¾ã›ã‚“" -#: gram.y:11687 +#: gram.y:14153 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" -msgstr "æ§‹æˆã®æœ«å°¾ãŒ UNBOUNDED PRECEDING ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "フレームã®çµ‚了㯠UNBOUNDED PRECEDING ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: gram.y:11693 +#: gram.y:14159 #, c-format msgid "frame starting from current row cannot have preceding rows" -msgstr "ç¾åœ¨è¡Œã‹ã‚‰å§‹ã¾ã‚‹ãƒ•レームã¯ã€ãれã¾ã§ã®è¡Œã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "ç¾åœ¨è¡Œã‹ã‚‰å§‹ã¾ã‚‹ãƒ•レームã¯ã€å…ˆè¡Œã™ã‚‹è¡Œã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: gram.y:11700 +#: gram.y:14166 #, c-format msgid "frame starting from following row cannot have preceding rows" -msgstr "次ã®è¡Œã‹ã‚‰å§‹ã¾ã‚‹ãƒ•レームã¯ã€ãれã¾ã§ã®è¡Œã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "次ã®è¡Œã‹ã‚‰å§‹ã¾ã‚‹ãƒ•レームã¯ã€å…ˆè¡Œã™ã‚‹è¡Œã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: gram.y:12334 +#: gram.y:14809 #, c-format msgid "type modifier cannot have parameter name" msgstr "型修正å­ã¯ãƒ‘ラメータåã‚’æŒã¤ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: gram.y:12947 gram.y:13147 -msgid "improper use of \"*\"" -msgstr " \"*\" ã®ä½¿ã„æ–¹ãŒä¸é©åˆ‡ã§ã™" - -#: gram.y:13084 +#: gram.y:14815 #, c-format -msgid "wrong number of parameters on left side of OVERLAPS expression" -msgstr "OVERLAPSå¼ã®å·¦è¾ºã®ãƒ‘ラメータ数ãŒé–“é•ã£ã¦ã„ã¾ã™" +msgid "type modifier cannot have ORDER BY" +msgstr "型修正å­ã¯ORDER BYã‚’æŒã¤ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: gram.y:13091 +#: gram.y:14880 gram.y:14887 #, c-format -msgid "wrong number of parameters on right side of OVERLAPS expression" -msgstr "OVERLAPSå¼ã®å³è¾ºã®ãƒ‘ラメータ数ãŒé–“é•ã£ã¦ã„ã¾ã™" +msgid "%s cannot be used as a role name here" +msgstr "%sã¯ã“ã“ã§ã¯ãƒ­ãƒ¼ãƒ«åã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: gram.y:15558 gram.y:15747 +msgid "improper use of \"*\"" +msgstr " \"*\" ã®ä½¿ã„æ–¹ãŒä¸é©åˆ‡ã§ã™" -#: gram.y:13110 gram.y:13127 tsearch/spell.c:518 tsearch/spell.c:535 -#: tsearch/spell.c:552 tsearch/spell.c:569 tsearch/spell.c:591 +#: gram.y:15710 gram.y:15727 tsearch/spell.c:954 tsearch/spell.c:971 +#: tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 #, c-format msgid "syntax error" msgstr "構文エラー" -#: gram.y:13198 +#: gram.y:15811 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "VARIADIC直接引数を使ã£ãŸé †åºé›†åˆé›†ç´„ã¯åŒã˜ãƒ‡ãƒ¼ã‚¿ã‚¿ã‚¤ãƒ—ã®VARIADICé›†ç´„å¼•æ•°ã‚’ä¸€ã¤æŒã¤å¿…è¦ãŒã‚りã¾ã™" + +#: gram.y:15848 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "複数ã®ORDER BYå¥ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:13209 +#: gram.y:15859 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "複数ã®OFFSETå¥ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:13218 +#: gram.y:15868 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "複数ã®LIMITå¥ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:13227 +#: gram.y:15877 #, c-format msgid "multiple WITH clauses not allowed" msgstr "複数㮠WITH å¥ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:13373 +#: gram.y:16081 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "テーブル関数ã§ã¯ OUT 㨠INOUT 引数ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: gram.y:13474 +#: gram.y:16182 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "複数㮠COLLATE å¥ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:13512 gram.y:13525 +#: gram.y:16220 gram.y:16233 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "%s制約ã¯é…å»¶å¯èƒ½ã«ã¯ã§ãã¾ã›ã‚“" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:13538 +#: gram.y:16246 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "%s制約ã«NOT VALIDå°ã‚’付ã‘ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:13551 +#: gram.y:16259 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "%s制約ã«NO INHERITå°ã‚’付ã‘ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: guc-file.l:192 +#: guc-file.l:316 #, c-format msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" msgstr "ファイル\"%2$s\"ã€%3$u行ã®è¨­å®šãƒ‘ラメータ\"%1$s\"ã¯ä¸æ˜Žã§ã™" -#: guc-file.l:227 utils/misc/guc.c:5282 utils/misc/guc.c:5458 -#: utils/misc/guc.c:5562 utils/misc/guc.c:5663 utils/misc/guc.c:5784 -#: utils/misc/guc.c:5892 +#: guc-file.l:353 utils/misc/guc.c:6249 utils/misc/guc.c:6443 +#: utils/misc/guc.c:6533 utils/misc/guc.c:6623 utils/misc/guc.c:6731 +#: utils/misc/guc.c:6826 #, c-format msgid "parameter \"%s\" cannot be changed without restarting the server" msgstr "パラメータ \"%s\" を変更ã™ã‚‹ã«ã¯ã‚µãƒ¼ãƒãƒ¼ã®å†èµ·å‹•ãŒå¿…è¦ã§ã™" -#: guc-file.l:255 +#: guc-file.l:389 #, c-format msgid "parameter \"%s\" removed from configuration file, reset to default" msgstr "パラメーター \"%s\" ãŒè¨­å®šãƒ•ァイルã‹ã‚‰å‰Šé™¤ã•れã¾ã—ãŸã€‚ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã‚Šã¾ã™ã€‚" -#: guc-file.l:317 +#: guc-file.l:455 #, c-format msgid "parameter \"%s\" changed to \"%s\"" msgstr "パラメータ \"%s\" 㯠\"%s\" ã«å¤‰æ›´ã•れã¾ã—ãŸ" -#: guc-file.l:351 +#: guc-file.l:497 #, c-format msgid "configuration file \"%s\" contains errors" msgstr "設定ファイル\"%s\"ã«ã¯ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™" -#: guc-file.l:356 +#: guc-file.l:502 #, c-format msgid "configuration file \"%s\" contains errors; unaffected changes were applied" msgstr "設定ファイル\"%s\"ã«ã¯ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ã€‚影響ãŒãªã„変更ã¯é©ç”¨ã•れã¾ã—ãŸ" -#: guc-file.l:361 +#: guc-file.l:507 #, c-format msgid "configuration file \"%s\" contains errors; no changes were applied" msgstr "設定ファイル\"%s\"ã«ã¯ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™ã€‚変更ã¯é©ç”¨ã•れã¾ã›ã‚“ã§ã—ãŸ" -#: guc-file.l:425 +#: guc-file.l:580 #, c-format msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" msgstr "設定ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: 入れå­é•·ãŒä¸Šé™ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: guc-file.l:438 libpq/hba.c:1802 +#: guc-file.l:596 libpq/hba.c:2142 libpq/hba.c:2550 #, c-format msgid "could not open configuration file \"%s\": %m" msgstr "設定ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: guc-file.l:444 +#: guc-file.l:607 #, c-format msgid "skipping missing configuration file \"%s\"" msgstr "存在ã—ãªã„設定ファイル\"%s\"をスキップã—ã¾ã™" -#: guc-file.l:650 +#: guc-file.l:861 #, c-format msgid "syntax error in file \"%s\" line %u, near end of line" msgstr "ファイル\"%s\"ã®è¡Œ%uã®è¡Œæœ«è¿‘辺ã§ã§æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã—ãŸ" -#: guc-file.l:655 +#: guc-file.l:871 #, c-format msgid "syntax error in file \"%s\" line %u, near token \"%s\"" msgstr "ファイル\"%s\"ã®è¡Œ%uã®ãƒˆãƒ¼ã‚¯ãƒ³\"%s\"è¿‘è¾ºã§æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã—ãŸ" -#: guc-file.l:671 +#: guc-file.l:891 #, c-format msgid "too many syntax errors found, abandoning file \"%s\"" msgstr "多ãã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã—ãŸã€‚ファイル\"%s\"を断念ã—ã¾ã™" -#: guc-file.l:716 +#: guc-file.l:943 #, c-format -#| msgid "could not open configuration file \"%s\": %m" msgid "could not open configuration directory \"%s\": %m" msgstr "設定ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: lib/stringinfo.c:267 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 +#: utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "ファイル\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "æ‰€è¦æ™‚é–“: インライン化: %.3fsã€æœ€é©åŒ–: %.3fsã€å‡ºåŠ›: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:715 utils/mmgr/dsa.c:797 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "サイズ%zuã®å‹•的共有エリアã®è¦æ±‚ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: lib/stringinfo.c:278 #, c-format msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." msgstr "%dãƒã‚¤ãƒˆã‚’æŒã¤æ–‡å­—列ãƒãƒƒãƒ•ã‚¡ã‚’%dãƒã‚¤ãƒˆå¤šãã€å¤§ããã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。" -#: libpq/auth.c:257 +#: libpq/auth-scram.c:251 #, c-format -msgid "authentication failed for user \"%s\": host rejected" -msgstr "ユーザ\"%s\"ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ: ホストを拒絶ã—ã¾ã—ãŸ" +msgid "client selected an invalid SASL authentication mechanism" +msgstr "クライアントãŒç„¡åйãªSASLèªè¨¼æ©Ÿæ§‹ã‚’é¸æŠžã—ã¾ã—ãŸ" + +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "ユーザ\"%s\"ã«å¯¾ã™ã‚‹ä¸æ­£ãªSCRAMベリファイア" + +#: libpq/auth-scram.c:283 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM verifier." +msgstr "ユーザ\"%s\"ã¯æœ‰åйãªSCRAMベリファイアをæŒã¡ã¾ã›ã‚“。" + +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 +#: libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 +#: libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 +#: libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 +#: libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 +#, c-format +msgid "malformed SCRAM message" +msgstr "䏿­£ãªãƒ•ォーマットã®SCRAMメッセージã§ã™" + +#: libpq/auth-scram.c:362 +#, c-format +msgid "The message is empty." +msgstr "メッセージãŒç©ºã§ã™ã€‚" + +#: libpq/auth-scram.c:367 +#, c-format +msgid "Message length does not match input length." +msgstr "メッセージã®é•·ã•ãŒå…¥åŠ›ã®é•·ã•ã¨ä¸€è‡´ã—ã¾ã›ã‚“" + +#: libpq/auth-scram.c:399 +#, c-format +msgid "invalid SCRAM response" +msgstr "䏿­£ãªSCRAM応答" + +#: libpq/auth-scram.c:400 +#, c-format +msgid "Nonce does not match." +msgstr "Nonce ãŒåˆè‡´ã—ã¾ã›ã‚“" + +#: libpq/auth-scram.c:474 +#, c-format +msgid "could not generate random salt" +msgstr "乱数ソルトを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: libpq/auth-scram.c:661 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "属性\"%c\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" + +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "属性\"%c\"ã¨ã—ã¦ã¯æ–‡å­—\"=\"を想定ã—ã¦ã„ã¾ã—ãŸã€‚" + +#: libpq/auth-scram.c:780 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "属性を想定ã—ã¾ã—ãŸãŒã€ä¸æ­£ãªæ–‡å­—\"%s\"ã§ã—ãŸã€‚" + +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "クライアント㯠SCRAM-SHA-256-PLUS ã‚’é¸æŠžã—ã¾ã—ãŸãŒã€SCRAM メッセージã«ã¯ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°æƒ…å ±ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“。" + +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "カンマを想定ã—ã¦ã„ã¾ã—ãŸãŒã€æ–‡å­—\"%s\"ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ" + +#: libpq/auth-scram.c:926 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "SCRAM ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã®ãƒã‚´ã‚·ã‚¨ãƒ¼ã‚·ãƒ§ãƒ³ã‚¨ãƒ©ãƒ¼" + +#: libpq/auth-scram.c:927 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "クライアント㯠SCRAM ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ãŒã€ã‚µãƒ¼ãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ãªã„ã¨æ€ã£ã¦ã„ã¾ã™ã€‚ã—ã‹ã—実際ã«ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚" + +#: libpq/auth-scram.c:949 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "クライアントã¯ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ãªã—ã® SCRAM-SHA-256 ã‚’é¸æŠžã—ã¾ã—ãŸãŒã€SCRAM メッセージã«ã¯ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°æƒ…å ±ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚" + +#: libpq/auth-scram.c:960 +#, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "SCRAM ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã‚¿ã‚¤ãƒ— \"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "予期ã—ãªã„ãƒãƒ£ãƒãƒ«å‰²ã‚Šå½“ã¦ãƒ•ラグ \"%s\"" + +#: libpq/auth-scram.c:977 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "クライアントã¯èªè¨¼è­˜åˆ¥å­ã‚’使ã£ã¦ã„ã¾ã™ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: libpq/auth-scram.c:982 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "client-fist-message ã§ã®æƒ³å®šå¤–ã®å±žæ€§\"%s\"" + +#: libpq/auth-scram.c:998 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "クライアントã¯ã‚µãƒãƒ¼ãƒˆå¤–ã®SCRAMæ‹¡å¼µã‚’è¦æ±‚ã—ã¦ã„ã¾ã™" + +#: libpq/auth-scram.c:1012 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM nonce ã®ä¸­ã«è¡¨ç¤ºä¸èƒ½ãªæ–‡å­—ãŒã‚りã¾ã™" + +#: libpq/auth-scram.c:1129 +#, c-format +msgid "could not generate random nonce" +msgstr "乱数nonceを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: libpq/auth-scram.c:1233 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "SCRAM ãƒãƒ£ãƒãƒ«ãƒã‚¤ãƒ³ãƒ‡ã‚£ãƒ³ã‚°ã®ç¢ºèªã§å¤±æ•—ã—ã¾ã—ãŸ" + +#: libpq/auth-scram.c:1251 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "client-final-message ä¸­ã«æƒ³å®šå¤–ã® SCRAM channel-binding 属性ãŒã‚りã¾ã—ãŸ" + +#: libpq/auth-scram.c:1268 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "client-final-message 中㮠proof ã®å½¢å¼ãŒä¸æ­£ã§ã™" + +#: libpq/auth-scram.c:1276 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "client-final-message ã®çµ‚端ã«ä¸è¦ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™ã€‚" -#: libpq/auth.c:260 +#: libpq/auth.c:282 #, c-format -msgid "Kerberos 5 authentication failed for user \"%s\"" -msgstr "ユーザ\"%s\"ã®Kerberos 5èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "authentication failed for user \"%s\": host rejected" +msgstr "ユーザ\"%s\"ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ: ホストを拒絶ã—ã¾ã—ãŸ" -#: libpq/auth.c:263 +#: libpq/auth.c:285 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®\"trust\"èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:266 +#: libpq/auth.c:288 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®Identèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:269 +#: libpq/auth.c:291 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "ユーザ \"%s\" ã§å¯¾å‘(peer)èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:273 +#: libpq/auth.c:296 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®ãƒ‘スワードèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:278 +#: libpq/auth.c:301 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®GSSAPIèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:281 +#: libpq/auth.c:304 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®SSPIèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:284 +#: libpq/auth.c:307 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®PAMèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:287 +#: libpq/auth.c:310 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "ユーザ\"%s\"ã®BSDèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: libpq/auth.c:313 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "ユーザ\"%s\"ã®LDAPèªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:290 +#: libpq/auth.c:316 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "ユーザ \"%s\" ã®è¨¼æ˜Žæ›¸èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:293 +#: libpq/auth.c:319 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "ユーザ \"%s\" ã® RADIUS èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:296 +#: libpq/auth.c:322 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" -msgstr "ユーザ\"%s\"ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ: èªè¨¼æ–¹å¼ãŒç„¡åйã§ã™" +msgstr "ユーザ\"%s\"ã®èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ: èªè¨¼æ–¹å¼ãŒä¸æ­£ã§ã™" -#: libpq/auth.c:304 +#: libpq/auth.c:326 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "接続ã¯pg_hba.confã®è¡Œ%dã«ä¸€è‡´ã—ã¾ã—ãŸ: \"%s\"" -#: libpq/auth.c:359 +#: libpq/auth.c:373 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "クライアント証明書ã¯ãƒ«ãƒ¼ãƒˆè¨¼æ˜Žæ›¸ã‚¹ãƒˆã‚¢ãŒåˆ©ç”¨ã§ãã‚‹å ´åˆã«ã®ã¿æ¤œè¨¼ã•れã¾ã™" + +#: libpq/auth.c:384 #, c-format msgid "connection requires a valid client certificate" msgstr "ã“ã®æŽ¥ç¶šã«ã¯æœ‰åйãªã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆè¨¼æ˜ŽãŒå¿…è¦ã§ã™" -#: libpq/auth.c:401 +#: libpq/auth.c:417 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf ã®è¨­å®šã§ãƒ›ã‚¹ãƒˆ \"%s\"ã€ãƒ¦ãƒ¼ã‚¶ \"%s\", %s 用ã®ãƒ¬ãƒ—リケーション接続を拒å¦ã—ã¾ã—ãŸ" -#: libpq/auth.c:403 libpq/auth.c:419 libpq/auth.c:467 libpq/auth.c:485 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL off" msgstr "SSL無効" -#: libpq/auth.c:403 libpq/auth.c:419 libpq/auth.c:467 libpq/auth.c:485 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL on" msgstr "SSL有効" -#: libpq/auth.c:407 +#: libpq/auth.c:423 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "pg_hba.conf ã®è¨­å®šã§ãƒ›ã‚¹ãƒˆ \"%s\"ã€ãƒ¦ãƒ¼ã‚¶ \"%s\"用ã®ãƒ¬ãƒ—リケーション接続を拒å¦ã—ã¾ã—ãŸ" -#: libpq/auth.c:416 +#: libpq/auth.c:432 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf ã®è¨­å®šã§ãƒ›ã‚¹ãƒˆ \"%s\"ã€ãƒ¦ãƒ¼ã‚¶ \"%s\"ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ \"%s\", %sã®æŽ¥ç¶šã‚’æ‹’å¦ã—ã¾ã—ãŸ" -#: libpq/auth.c:423 +#: libpq/auth.c:439 #, c-format msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" msgstr "pg_hba.conf ã®è¨­å®šã§ãƒ›ã‚¹ãƒˆ \"%s\"ã€ãƒ¦ãƒ¼ã‚¶ \"%s\"ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ \"%s\" 用ã®ãƒ¬ãƒ—リケーション接続を拒å¦ã—ã¾ã—ãŸ" -#: libpq/auth.c:452 +#: libpq/auth.c:468 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "クライアントIPアドレスã¯\"%s\"ã«è§£æ±ºã•れã€å‰æ–¹æ¤œç´¢ã¨ä¸€è‡´ã—ã¾ã—ãŸã€‚" -#: libpq/auth.c:454 +#: libpq/auth.c:471 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "クライアントIPアドレスã¯\"%s\"ã«è§£æ±ºã•れã¾ã—ãŸã€‚剿–¹æ¤œç´¢ã¯æ¤œæŸ»ã•れã¾ã›ã‚“。" -#: libpq/auth.c:456 +#: libpq/auth.c:474 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "クライアントIPアドレスã¯\"%s\"ã«è§£æ±ºã•れã€å‰æ–¹æ¤œç´¢ã¨ä¸€è‡´ã—ã¾ã›ã‚“ã§ã—ãŸã€‚" -#: libpq/auth.c:465 +#: libpq/auth.c:477 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "クライアントã®ãƒ›ã‚¹ãƒˆå\"%s\"ã‚’IPアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s。" + +#: libpq/auth.c:482 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "クライアントã®IPアドレスをホストåã«è§£æ±ºã§ãã¾ã›ã‚“ã§ã—ãŸ: %s。" + +#: libpq/auth.c:491 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "pg_hba.conf ã«ãƒ›ã‚¹ãƒˆ\"%s\"ã€ãƒ¦ãƒ¼ã‚¶\"%s\", %s用ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" -#: libpq/auth.c:472 +#: libpq/auth.c:498 #, c-format msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" msgstr "pg_hba.conf ã«ãƒ›ã‚¹ãƒˆ\"%s\"ã€ãƒ¦ãƒ¼ã‚¶\"%s\"用ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" -#: libpq/auth.c:482 +#: libpq/auth.c:508 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "pg_hba.conf ã«ãƒ›ã‚¹ãƒˆ\"%s\"ã€ãƒ¦ãƒ¼ã‚¶\"%s\"ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%s, %s用ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" -#: libpq/auth.c:490 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "pg_hba.conf ã«ãƒ›ã‚¹ãƒˆ\"%s\"ã€ãƒ¦ãƒ¼ã‚¶\"%s\"ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%s用ã®ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" -#: libpq/auth.c:542 libpq/hba.c:1206 -#, c-format -msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" -msgstr "\"db_user_namespace\" ãŒæœ‰åйã®å ´åˆã€MD5 èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" - -#: libpq/auth.c:666 +#: libpq/auth.c:669 #, c-format msgid "expected password response, got message type %d" -msgstr "パスワード応答を想定ã—ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡ž%dã‚’å—ã‘å–りã¾ã—ãŸ" +msgstr "パスワード応答を想定ã—ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—%dã‚’å—ã‘å–りã¾ã—ãŸ" -#: libpq/auth.c:694 +#: libpq/auth.c:697 #, c-format msgid "invalid password packet size" -msgstr "パスワードパケットã®ã‚µã‚¤ã‚ºãŒç„¡åйã§ã™" - -#: libpq/auth.c:698 -#, c-format -msgid "received password packet" -msgstr "パスワードパケットをå—ã‘å–りã¾ã—ãŸ" +msgstr "パスワードパケットã®ã‚µã‚¤ã‚ºãŒä¸æ­£ã§ã™" -#: libpq/auth.c:756 +#: libpq/auth.c:715 #, c-format -msgid "Kerberos initialization returned error %d" -msgstr "Kerberosã®åˆæœŸåŒ–ã«ã¦ã‚¨ãƒ©ãƒ¼%dãŒè¿”ã•れã¾ã—ãŸ" +msgid "empty password returned by client" +msgstr "クライアントã‹ã‚‰ç©ºã®ãƒ‘スワードãŒè¿”ã•れã¾ã—ãŸ" -#: libpq/auth.c:766 +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format -msgid "Kerberos keytab resolving returned error %d" -msgstr "Kerberosã®keytab解決ã«ã¦ã‚¨ãƒ©ãƒ¼%dãŒè¿”ã•れã¾ã—ãŸ" +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "\"db_user_namespace\" ãŒæœ‰åйã®å ´åˆã€MD5 èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: libpq/auth.c:790 +#: libpq/auth.c:841 #, c-format -msgid "Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d" -msgstr "Kerberosã®sname_to_principal(\"%s\", \"%s\")ã«ã¦ã‚¨ãƒ©ãƒ¼%dãŒè¿”ã•れã¾ã—ãŸ" +msgid "could not generate random MD5 salt" +msgstr "ランダムãªMD5ソルトã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:835 +#: libpq/auth.c:887 #, c-format -msgid "Kerberos recvauth returned error %d" -msgstr "Kerberosã®recvauthã«ã¦ã‚¨ãƒ©ãƒ¼%dãŒè¿”ã•れã¾ã—ãŸ" +msgid "SASL authentication is not supported in protocol version 2" +msgstr "プロトコルãƒãƒ¼ã‚¸ãƒ§ãƒ³2ã§ã¯SASLèªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:858 +#: libpq/auth.c:920 #, c-format -msgid "Kerberos unparse_name returned error %d" -msgstr "Kerberosã®unparse_nameã«ã¦ã‚¨ãƒ©ãƒ¼%dãŒè¿”ã•れã¾ã—ãŸ" +msgid "expected SASL response, got message type %d" +msgstr "SASL応答を想定ã—ã¦ã„ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—%dã‚’å—ã‘å–りã¾ã—ãŸ" -#: libpq/auth.c:1006 +#: libpq/auth.c:1112 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "プロトコルãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2 ã§ã¯ GSSAPI ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:1061 +#: libpq/auth.c:1172 #, c-format msgid "expected GSS response, got message type %d" msgstr "GSS応答を想定ã—ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ— %d ã‚’å—ã‘å–りã¾ã—ãŸ" -#: libpq/auth.c:1120 +#: libpq/auth.c:1234 msgid "accepting GSS security context failed" -msgstr "GSSセキュリティコンテキストã®å—付ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgstr "GSSセキュリティコンテキストã®å—ã‘付ã‘ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:1146 +#: libpq/auth.c:1260 msgid "retrieving GSS user name failed" msgstr "GSSユーザåã®å—ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:1263 +#: libpq/auth.c:1385 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "プロトコルãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2 ã§ã¯ SSPI ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:1278 +#: libpq/auth.c:1400 msgid "could not acquire SSPI credentials" msgstr "SSPIã®è³‡æ ¼ãƒãƒ³ãƒ‰ãƒ«ã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:1295 +#: libpq/auth.c:1418 #, c-format msgid "expected SSPI response, got message type %d" -msgstr "SSPI応答を想定ã—ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡ž%dã‚’å—ã‘å–りã¾ã—ãŸ" +msgstr "SSPI応答を想定ã—ã¾ã—ãŸãŒã€ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—%dã‚’å—ã‘å–りã¾ã—ãŸ" -#: libpq/auth.c:1367 +#: libpq/auth.c:1491 msgid "could not accept SSPI security context" msgstr "SSPIセキュリティコンテキストをå—ã‘付ã‘られã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:1429 +#: libpq/auth.c:1553 msgid "could not get token from SSPI security context" msgstr "SSPIセキュリティコンテキストã‹ã‚‰ãƒˆãƒ¼ã‚¯ãƒ³ã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:1673 +#: libpq/auth.c:1672 libpq/auth.c:1691 +#, c-format +msgid "could not translate name" +msgstr "åå‰ã®å¤‰æ›ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: libpq/auth.c:1704 +#, c-format +msgid "realm name too long" +msgstr "realmåãŒé•·ã™ãŽã¾ã™" + +#: libpq/auth.c:1719 +#, c-format +msgid "translated account name too long" +msgstr "変æ›å¾Œã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆåãŒé•·ã™ãŽã¾ã™" + +#: libpq/auth.c:1905 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "Ident接続用ã®ã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1688 +#: libpq/auth.c:1920 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "ローカルアドレス\"%s\"ã«ãƒã‚¤ãƒ³ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1700 +#: libpq/auth.c:1932 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"ã€ãƒãƒ¼ãƒˆ%sã®Identサーãƒã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1720 +#: libpq/auth.c:1954 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"ã€ãƒãƒ¼ãƒˆ%sã®Identサーãƒã«å•ã„åˆã‚ã›ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1735 +#: libpq/auth.c:1971 #, c-format msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "アドレス\"%s\"ã€ãƒãƒ¼ãƒˆ%sã®Identサーãƒã‹ã‚‰ã®å¿œç­”ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1745 +#: libpq/auth.c:1981 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" -msgstr "Identサーãƒã‹ã‚‰ã®å¿œç­”ã®æ›¸å¼ãŒç„¡åйã§ã™: \"%s\"" +msgstr "Identサーãƒã‹ã‚‰ã®å¿œç­”ã®æ›¸å¼ãŒä¸æ­£ã§ã™: \"%s\"" -#: libpq/auth.c:1784 +#: libpq/auth.c:2021 #, c-format msgid "peer authentication is not supported on this platform" msgstr "ã“ã®ãƒ—ラットフォームã§ã¯å¯¾å‘(peer)èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:1788 +#: libpq/auth.c:2025 #, c-format msgid "could not get peer credentials: %m" msgstr "ピアã®è³‡æ ¼è¨¼æ˜Žã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:1797 +#: libpq/auth.c:2036 #, c-format -msgid "local user with ID %d does not exist" -msgstr "ID %dã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "could not look up local user ID %ld: %s" +msgstr "ローカルユーザID %ldã®å‚ç…§ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/auth.c:1880 libpq/auth.c:2151 libpq/auth.c:2516 -#, c-format -msgid "empty password returned by client" -msgstr "クライアントã‹ã‚‰ç©ºã®ãƒ‘スワードãŒè¿”ã•れã¾ã—ãŸ" - -#: libpq/auth.c:1890 +#: libpq/auth.c:2124 #, c-format msgid "error from underlying PAM layer: %s" msgstr "背後ã®PAM層ã§ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã—ãŸ: %s" -#: libpq/auth.c:1959 +#: libpq/auth.c:2193 #, c-format msgid "could not create PAM authenticator: %s" msgstr "PAM authenticatorを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/auth.c:1970 +#: libpq/auth.c:2204 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/auth.c:1981 +#: libpq/auth.c:2236 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: libpq/auth.c:2248 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "\"pam_set_item(PAM_CONV)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/auth.c:1992 +#: libpq/auth.c:2259 #, c-format msgid "pam_authenticate failed: %s" msgstr "\"pam_authenticateãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/auth.c:2003 +#: libpq/auth.c:2270 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmtãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/auth.c:2014 +#: libpq/auth.c:2281 #, c-format msgid "could not release PAM authenticator: %s" msgstr "PAM authenticatorを解放ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/auth.c:2047 -#, c-format -#| msgid "could not initialize LDAP: error code %d" -msgid "could not initialize LDAP: %m" -msgstr "LDAPã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: libpq/auth.c:2050 +#: libpq/auth.c:2357 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "LDAPã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %d" -#: libpq/auth.c:2060 +#: libpq/auth.c:2406 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "LDAPã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: libpq/auth.c:2416 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "ã“ã® LDAP ライブラリã§ã¯ ldaps ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: libpq/auth.c:2424 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "LDAPã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: libpq/auth.c:2434 #, c-format -#| msgid "could not set LDAP protocol version: error code %d" msgid "could not set LDAP protocol version: %s" msgstr "LDAPプロトコルãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/auth.c:2089 +#: libpq/auth.c:2465 #, c-format msgid "could not load wldap32.dll" -msgstr "wldap32.dllã®èª­ã¿è¾¼ã¿ãŒã§ãã¾ã›ã‚“" +msgstr "wldap32.dllãŒèª­ã¿è¾¼ã‚ã¾ã›ã‚“" -#: libpq/auth.c:2097 +#: libpq/auth.c:2473 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "wldap32.dllã®_ldap_start_tls_sA関数を読ã¿è¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:2098 +#: libpq/auth.c:2474 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "ã“ã®ãƒ—ラットフォームã§ã¯LDAP over SSLをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" -#: libpq/auth.c:2113 +#: libpq/auth.c:2489 #, c-format -#| msgid "could not start LDAP TLS session: error code %d" msgid "could not start LDAP TLS session: %s" msgstr "LDAP TLSセッションを開始ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/auth.c:2135 +#: libpq/auth.c:2552 #, c-format msgid "LDAP server not specified" msgstr "LDAP サーãƒãƒ¼ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" -#: libpq/auth.c:2188 +#: libpq/auth.c:2607 #, c-format msgid "invalid character in user name for LDAP authentication" -msgstr "LDAP èªè¨¼ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼åã®ä¸­ã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™" +msgstr "LDAP èªè¨¼ã§ãƒ¦ãƒ¼ã‚¶åã®ä¸­ã«ä¸æ­£ãªæ–‡å­—ãŒã‚りã¾ã™" -#: libpq/auth.c:2203 +#: libpq/auth.c:2624 #, c-format -#| msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": error code %d" msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "サーãƒãƒ¼ \"%2$s\" ã§ã€ldapbinddn \"%1$s\" ã«ã‚ˆã‚‹ LDAP ãƒã‚¤ãƒ³ãƒ‰ã‚’実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %3$s" -#: libpq/auth.c:2228 +#: libpq/auth.c:2653 #, c-format -#| msgid "could not search LDAP for filter \"%s\" on server \"%s\": error code %d" msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "サーãƒãƒ¼ \"%2$s\" ã§ã€ãƒ•ィルタ \"%1$s\" ã«ã‚ˆã‚‹ LDAP 検索ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %3$s" -#: libpq/auth.c:2239 +#: libpq/auth.c:2667 #, c-format -#| msgid "server \"%s\" does not exist" msgid "LDAP user \"%s\" does not exist" msgstr "LDAPサーãƒãƒ¼ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: libpq/auth.c:2240 +#: libpq/auth.c:2668 #, c-format -#| msgid "LDAP search failed for filter \"%s\" on server \"%s\": no such user" msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "サーãƒãƒ¼ \"%2$s\" ã§ã€ãƒ•ィルタ \"%1$s\" ã«ã‚ˆã‚‹ LDAP 検索ãŒä½•ã‚‚è¿”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚" -#: libpq/auth.c:2244 +#: libpq/auth.c:2672 #, c-format -#| msgid "function %s is not unique" msgid "LDAP user \"%s\" is not unique" msgstr "LDAPユーザ\"%s\"ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" -#: libpq/auth.c:2245 +#: libpq/auth.c:2673 #, c-format -#| msgid "LDAP search failed for filter \"%s\" on server \"%s\": no such user" msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "サーãƒãƒ¼ \"%2$s\" ã§ã€ãƒ•ィルタ \"%1$s\" ã«ã‚ˆã‚‹ LDAP 検索ãŒ%3$d項目返ã—ã¾ã—ãŸã€‚" msgstr[1] "サーãƒãƒ¼ \"%2$s\" ã§ã€ãƒ•ィルタ \"%1$s\" ã«ã‚ˆã‚‹ LDAP 検索ãŒ%3$d項目返ã—ã¾ã—ãŸã€‚" -#: libpq/auth.c:2263 +#: libpq/auth.c:2693 #, c-format msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" -msgstr "サーム\"%2$s\" ã§ \"%1$s\" ã«ãƒžãƒƒãƒã™ã‚‹æœ€åˆã®ã‚¨ãƒ³ãƒˆãƒªã® dn ã‚’å–å¾—ã§ãã¾ã›ã‚“:%3$s" +msgstr "サーム\"%2$s\" ã§ \"%1$s\" ã«ãƒžãƒƒãƒã™ã‚‹æœ€åˆã®ã‚¨ãƒ³ãƒˆãƒªã® dn ã‚’å–å¾—ã§ãã¾ã›ã‚“: %3$s" -#: libpq/auth.c:2283 +#: libpq/auth.c:2714 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "サーãƒãƒ¼ \"%s\" ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ \"%s\" ã®æ¤œç´¢å¾Œã€unbind ã§ãã¾ã›ã‚“: %s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "サーãƒãƒ¼ \"%2$s\" ã§ãƒ¦ãƒ¼ã‚¶ \"%1$s\" ã®æ¤œç´¢å¾Œã€unbind ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:2320 +#: libpq/auth.c:2745 #, c-format -#| msgid "LDAP login failed for user \"%s\" on server \"%s\": error code %d" msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "サーãƒ\"%2$s\"ã§ãƒ¦ãƒ¼ã‚¶\"%1$s\"ã®LDAPログインãŒå¤±æ•—ã—ã¾ã—ãŸ: %3$s" -#: libpq/auth.c:2348 +#: libpq/auth.c:2774 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP診断: %s" + +#: libpq/auth.c:2799 #, c-format msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" -msgstr "ユーザ \"%s\" ã®è¨¼æ˜Žæ›¸èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸï¼šã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆè¨¼æ˜Žæ›¸ã«ãƒ¦ãƒ¼ã‚¶åãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" +msgstr "ユーザ \"%s\" ã®è¨¼æ˜Žæ›¸èªè¨¼ã«å¤±æ•—ã—ã¾ã—ãŸ: クライアント証明書ã«ãƒ¦ãƒ¼ã‚¶åãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:2472 +#: libpq/auth.c:2902 #, c-format msgid "RADIUS server not specified" msgstr "RADIUS サーãƒãƒ¼ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:2479 +#: libpq/auth.c:2909 #, c-format msgid "RADIUS secret not specified" msgstr "RADIUS secret ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:2495 libpq/hba.c:1622 +#: libpq/auth.c:2923 #, c-format -msgid "could not translate RADIUS server name \"%s\" to address: %s" -msgstr "RADIUS サーãƒå \"%s\" をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUSèªè¨¼ã§ã¯%d文字より長ã„パスワードã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: libpq/auth.c:2523 +#: libpq/auth.c:3028 libpq/hba.c:1908 #, c-format -msgid "RADIUS authentication does not support passwords longer than 16 characters" -msgstr "RADIUS èªè¨¼ã§ã¯ 16 文字以上ã®ãƒ‘スワードã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "RADIUS サーãƒå \"%s\" をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/auth.c:2534 +#: libpq/auth.c:3042 #, c-format msgid "could not generate random encryption vector" -msgstr "乱数化ベクトルを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "ãƒ©ãƒ³ãƒ€ãƒ ãªæš—å·åŒ–ベクトルを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/auth.c:2557 +#: libpq/auth.c:3076 #, c-format msgid "could not perform MD5 encryption of password" -msgstr "パスワード㮠MD5 æš—å·åŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgstr "パスワードã®MD5æš—å·åŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:2579 +#: libpq/auth.c:3102 #, c-format msgid "could not create RADIUS socket: %m" -msgstr "RADIUS ã®ã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "RADIUSã®ã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:2600 +#: libpq/auth.c:3124 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "ローカル㮠RADIUS ソケットをãƒã‚¤ãƒ³ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:2610 +#: libpq/auth.c:3134 #, c-format msgid "could not send RADIUS packet: %m" msgstr "RADIUS パケットをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:2639 libpq/auth.c:2664 +#: libpq/auth.c:3167 libpq/auth.c:3193 #, c-format -msgid "timeout waiting for RADIUS response" -msgstr "RADIUS ã®å¿œç­”å¾…ã¡ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ" +msgid "timeout waiting for RADIUS response from %s" +msgstr "%sã‹ã‚‰ã®RADIUSã®å¿œç­”å¾…ã¡ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ" -#: libpq/auth.c:2657 +#: libpq/auth.c:3186 #, c-format msgid "could not check status on RADIUS socket: %m" -msgstr "RADIUS ソケットã®çŠ¶æ…‹ã‚’ãƒã‚§ãƒƒã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "RADIUSソケットã®çŠ¶æ…‹ã‚’ãƒã‚§ãƒƒã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:2686 +#: libpq/auth.c:3216 #, c-format msgid "could not read RADIUS response: %m" -msgstr "RADIUS 応答を読ã‚ã¾ã›ã‚“ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "RADIUS応答を読ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/auth.c:2698 libpq/auth.c:2702 +#: libpq/auth.c:3229 libpq/auth.c:3233 #, c-format -msgid "RADIUS response was sent from incorrect port: %d" -msgstr "RADIUS応答ãŒèª¤ã£ãŸãƒãƒ¼ãƒˆã‹ã‚‰é€ã‚‰ã‚Œã¾ã—ãŸï¼š%d" +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "%sã‹ã‚‰ã®RADIUS応答ãŒèª¤ã£ãŸãƒãƒ¼ãƒˆã‹ã‚‰é€ã‚‰ã‚Œã¦ãã¾ã—ãŸ: %d" -#: libpq/auth.c:2711 +#: libpq/auth.c:3242 #, c-format -msgid "RADIUS response too short: %d" -msgstr "RADIUS応答ãŒçŸ­ã™ãŽã¾ã™ï¼š%d" +msgid "RADIUS response from %s too short: %d" +msgstr "%sã‹ã‚‰ã®RADIUS応答ãŒçŸ­ã™ãŽã¾ã™: %d" -#: libpq/auth.c:2718 +#: libpq/auth.c:3249 #, c-format -msgid "RADIUS response has corrupt length: %d (actual length %d)" -msgstr "RADIUS応答ã®é•·ã•ãŒæ­£ã—ãã‚りã¾ã›ã‚“:%d(実際ã®é•·ã•ã¯%d)" +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "%sã‹ã‚‰ã®RADIUS応答ãŒé–“é•ã£ãŸé•·ã•ã‚’ä¿æŒã—ã¦ã„ã¾ã™: %d(実際ã®é•·ã•ã¯%d)" -#: libpq/auth.c:2726 +#: libpq/auth.c:3257 #, c-format -msgid "RADIUS response is to a different request: %d (should be %d)" -msgstr "別ã®ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã™ã‚‹RADIUS応答ã§ã™ï¼š%d(%d ã§ã‚ã‚‹ã¹ã)" +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "%sã‹ã‚‰ã®RADIUS応答ã¯ç•°ãªã‚‹ãƒªã‚¯ã‚¨ã‚¹ãƒˆã«å¯¾ã™ã‚‹ã‚‚ã®ã§ã™: %d (%d ã§ã‚ã‚‹ã¯ãš)" -#: libpq/auth.c:2751 +#: libpq/auth.c:3282 #, c-format msgid "could not perform MD5 encryption of received packet" -msgstr "å—信パケット㮠MD5 æš—å·åŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgstr "å—信パケットã®MD5æš—å·åŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/auth.c:2760 +#: libpq/auth.c:3291 #, c-format -msgid "RADIUS response has incorrect MD5 signature" -msgstr "RADIUS 応答㮠MD5 ã‚·ã‚°ãƒãƒãƒ£ãŒèª¤ã£ã¦ã„ã¾ã™" +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "%sã‹ã‚‰ã®RADIUS応答ãŒé–“é•ã£ãŸMD5ã‚·ã‚°ãƒãƒãƒ£ã‚’ä¿æŒã—ã¦ã„ã¾ã™" -#: libpq/auth.c:2777 +#: libpq/auth.c:3309 #, c-format -msgid "RADIUS response has invalid code (%d) for user \"%s\"" -msgstr "ユーザ\"%2$s\"ã«å¯¾ã™ã‚‹RADIUS応答(%1$d)ãŒç„¡åйã§ã™" +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "%1$sã‹ã‚‰ã®RADIUS応答ãŒãƒ¦ãƒ¼ã‚¶\"%3$s\"ã«ã¨ã£ã¦ä¸æ­£ãªã‚³ãƒ¼ãƒ‰(%2$d)ã‚’ä¿æŒã—ã¦ã„ã¾ã™" -#: libpq/be-fsstubs.c:134 libpq/be-fsstubs.c:165 libpq/be-fsstubs.c:199 -#: libpq/be-fsstubs.c:239 libpq/be-fsstubs.c:264 libpq/be-fsstubs.c:312 -#: libpq/be-fsstubs.c:335 libpq/be-fsstubs.c:583 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format msgid "invalid large-object descriptor: %d" -msgstr "ラージオブジェクト記述å­ãŒç„¡åйã§ã™: %d" +msgstr "ラージオブジェクト記述å­ãŒä¸æ­£ã§ã™: %d" -#: libpq/be-fsstubs.c:180 libpq/be-fsstubs.c:218 libpq/be-fsstubs.c:602 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "ラージオブジェクト %u ã«å¯¾ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgid "large object descriptor %d was not opened for reading" +msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆè¨˜è¿°å­ %d ã¯èª­ã¿è¾¼ã¿ç”¨ã«ã‚ªãƒ¼ãƒ—ンã•れã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/be-fsstubs.c:205 libpq/be-fsstubs.c:589 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format msgid "large object descriptor %d was not opened for writing" msgstr "ラージオブジェクト記述å­%dã¯æ›¸ãè¾¼ã¿ç”¨ã«é–‹ã‹ã‚Œã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/be-fsstubs.c:247 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "lo_lseekã®çµæžœãŒãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクト記述å­ã®ç¯„囲%dã‚’è¶…ãˆã¦ã„ã¾ã™" -#: libpq/be-fsstubs.c:320 +#: libpq/be-fsstubs.c:285 #, c-format -#| msgid "invalid large-object descriptor: %d" msgid "lo_tell result out of range for large-object descriptor %d" msgstr "lo_tellã®çµæžœãŒãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクト記述å­ã®ç¯„囲%dã‚’è¶…ãˆã¦ã„ã¾ã™" -#: libpq/be-fsstubs.c:457 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "サーãƒã‚µã‚¤ãƒ‰ã®lo_import()を使用ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: libpq/be-fsstubs.c:458 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "libpqã§æä¾›ã•れるlo_import()ã¯èª°ã§ã‚‚使用ã§ãã¾ã™" - -#: libpq/be-fsstubs.c:471 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "サーãƒãƒ•ァイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-fsstubs.c:493 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "サーãƒãƒ•ァイル\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-fsstubs.c:523 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "サーãƒã‚µã‚¤ãƒ‰ã®lo_export()を使用ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: libpq/be-fsstubs.c:524 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "libpqã§æä¾›ã•れるクライアントサイドã®lo_export()ã¯èª°ã§ã‚‚使用ã§ãã¾ã™" - -#: libpq/be-fsstubs.c:549 +#: libpq/be-fsstubs.c:511 #, c-format msgid "could not create server file \"%s\": %m" msgstr "サーãƒãƒ•ァイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-fsstubs.c:561 +#: libpq/be-fsstubs.c:523 #, c-format msgid "could not write server file \"%s\": %m" msgstr "サーãƒãƒ•ァイル\"%s\"を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-secure.c:284 libpq/be-secure.c:379 +#: libpq/be-fsstubs.c:752 #, c-format -msgid "SSL error: %s" -msgstr "SSLエラーã§ã™: %s" +msgid "large object read request is too large" +msgstr "ラージオブジェクトã®èª­ã¿è¾¼ã¿è¦æ±‚ãŒå¤§ãã™ãŽã¾ã™" -#: libpq/be-secure.c:293 libpq/be-secure.c:388 libpq/be-secure.c:939 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 +#: utils/adt/genfile.c:306 #, c-format -msgid "unrecognized SSL error code: %d" -msgstr "SSLエラーコードãŒä¸æ˜Žã§ã™: %d" +msgid "requested length cannot be negative" +msgstr "è² ã®é•·ã•を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: libpq/be-secure.c:332 libpq/be-secure.c:336 libpq/be-secure.c:346 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 +#: storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 +#: storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "SSL renegotiation failure" -msgstr "SSLå†èª¿åœã®å¤±æ•—" +msgid "permission denied for large object %u" +msgstr "ラージオブジェクト %u ã«å¯¾ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: libpq/be-secure.c:340 +#: libpq/be-secure-common.c:91 #, c-format -msgid "SSL failed to send renegotiation request" -msgstr "SSLã§å†èª¿åœè¦æ±‚ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "could not read from command \"%s\": %m" +msgstr "コマンド \"%s\" ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-secure.c:737 +#: libpq/be-secure-common.c:109 #, c-format -msgid "could not create SSL context: %s" -msgstr "SSLコンテキストを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "command \"%s\" failed" +msgstr "コマンド \"%s\"ã®å®Ÿè¡Œã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/be-secure.c:753 -#, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "サーãƒè¨¼æ˜Žæ›¸ãƒ•ァイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" - -#: libpq/be-secure.c:759 +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "秘密キーファイル\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-secure.c:774 +#: libpq/be-secure-common.c:148 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "秘密キーファイル\"%s\"ã¯é€šå¸¸ã®ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“" + +#: libpq/be-secure-common.c:163 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "秘密キーファイル\"%s\"ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ¦ãƒ¼ã‚¶ã‚‚ã—ãã¯rootã®æ‰€æœ‰ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" -msgstr "秘密キーファイル \"%s\" ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯å…¨å“¡ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã™" +msgstr "秘密キーファイル\"%s\"ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯å…¨å“¡ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã™" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "ファイルã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ¦ãƒ¼ã‚¶ã®æ‰€æœ‰ã®å ´åˆã¯ u=rw (0600) ã‹ãれよりも低ã„パーミッションã€root所有ã®å ´åˆã¯ u=rw,g=r (0640) ã‹ãれよりも低ã„パーミッションã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "SSLコンテキストを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "サーãƒè¨¼æ˜Žæ›¸ãƒ•ァイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:776 +#: libpq/be-secure-openssl.c:167 #, c-format -msgid "Permissions should be u=rw (0600) or less." -msgstr "権é™ã¯u=rwx(0700)ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "パスフレーズãŒè¦æ±‚ã•れãŸãŸã‚秘密キーファイル\"%s\"をリロードã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/be-secure.c:783 +#: libpq/be-secure-openssl.c:172 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "秘密キーファイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:788 +#: libpq/be-secure-openssl.c:181 #, c-format msgid "check of private key failed: %s" msgstr "ç§˜å¯†ã‚­ãƒ¼ã®æ¤œæŸ»ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/be-secure.c:808 +#: libpq/be-secure-openssl.c:208 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "æš—å·æ–¹å¼ãƒªã‚¹ãƒˆãŒã‚»ãƒƒãƒˆã§ãã¾ã›ã‚“ (利用å¯èƒ½ãªæš—å·æ–¹å¼ãŒã‚りã¾ã›ã‚“)" + +#: libpq/be-secure-openssl.c:226 #, c-format msgid "could not load root certificate file \"%s\": %s" -msgstr "ルート証明ファイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgstr "ルート証明書ファイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:832 +#: libpq/be-secure-openssl.c:253 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "SSL証明書失効リストファイル\"%s\"ã¯ç„¡è¦–ã•れã¾ã—ãŸ" -#: libpq/be-secure.c:834 +#: libpq/be-secure-openssl.c:255 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "SSLライブラリãŒè¨¼æ˜Žæ›¸å¤±åŠ¹ãƒªã‚¹ãƒˆã‚’ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" -#: libpq/be-secure.c:839 +#: libpq/be-secure-openssl.c:262 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "SSL証明失効リストファイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:884 +#: libpq/be-secure-openssl.c:337 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "SSLæŽ¥ç¶šã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: SSLã‚³ãƒ³ãƒ†ã‚¯ã‚¹ãƒˆãŒæº–å‚™ã§ãã¦ã„ã¾ã›ã‚“" + +#: libpq/be-secure-openssl.c:345 #, c-format msgid "could not initialize SSL connection: %s" msgstr "SSLæŽ¥ç¶šã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:893 +#: libpq/be-secure-openssl.c:353 #, c-format msgid "could not set SSL socket: %s" msgstr "SSLソケットを設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:919 +#: libpq/be-secure-openssl.c:408 #, c-format msgid "could not accept SSL connection: %m" msgstr "SSL接続をå—ã‘付ã‘られã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/be-secure.c:923 libpq/be-secure.c:934 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "SSL接続をå—ã‘付ã‘られã¾ã›ã‚“ã§ã—ãŸ: EOFを検出ã—ã¾ã—ãŸ" -#: libpq/be-secure.c:928 +#: libpq/be-secure-openssl.c:417 #, c-format msgid "could not accept SSL connection: %s" msgstr "SSL接続をå—ã‘付ã‘られã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/be-secure.c:984 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 +#: libpq/be-secure-openssl.c:623 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "èªè­˜ã§ããªã„SSLエラーコード: %d" + +#: libpq/be-secure-openssl.c:470 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "SSL 証明書ã®ã‚³ãƒ¢ãƒ³ãƒãƒ¼ãƒ ã« null ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" -#: libpq/be-secure.c:995 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format -msgid "SSL connection from \"%s\"" -msgstr "\"%s\"ã‹ã‚‰ã®SSL接続" +msgid "SSL error: %s" +msgstr "SSLエラー: %s" + +#: libpq/be-secure-openssl.c:788 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "DHパラメータファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: libpq/be-secure-openssl.c:800 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "DHパラーメータをロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: libpq/be-secure-openssl.c:810 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "䏿­£ãªDHパラメータã§ã™: %s" + +#: libpq/be-secure-openssl.c:818 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "䏿­£ãªDHパラメータ: pã¯ç´ æ•°ã§ã¯ã‚りã¾ã›ã‚“" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "䏿­£ãªDHパラメータ: é©åˆ‡ãªç”Ÿæˆå™¨ã‚‚安全ãªç´ æ•°ã‚‚ã‚りã¾ã›ã‚“" + +#: libpq/be-secure-openssl.c:981 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: DHパラメータをロードã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: libpq/be-secure-openssl.c:989 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: DHパラメータを設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: libpq/be-secure-openssl.c:1013 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: èªè­˜ã§ããªã„曲線å: %s" + +#: libpq/be-secure-openssl.c:1022 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: キーを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/be-secure.c:1046 +#: libpq/be-secure-openssl.c:1050 msgid "no SSL error reported" msgstr "SSLエラーã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: libpq/be-secure.c:1050 +#: libpq/be-secure-openssl.c:1054 #, c-format msgid "SSL error code %lu" msgstr "SSLエラーコード: %lu" -#: libpq/hba.c:188 +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "\"%s\"ã‹ã‚‰ã®SSL接続" + +#: libpq/be-secure.c:196 libpq/be-secure.c:284 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "予期ã—ãªã„postmasterã®çµ‚了ã®ãŸã‚ã€ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã—ã¾ã™" + +#: libpq/crypt.c:51 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "ロール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“。" + +#: libpq/crypt.c:61 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "ユーザ\"%s\"ã¯ãƒ‘スワードãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“。" + +#: libpq/crypt.c:79 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "ユーザ\"%s\"ã®ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã¯æœŸé™åˆ‡ã‚Œã§ã™ã€‚" + +#: libpq/crypt.c:173 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "ユーザ\"%s\"ã®ãƒ‘スワードã¯ã¯MD5èªè¨¼ã§ä½¿ç”¨ä¸èƒ½ã§ã™ã€‚" + +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "ユーザ\"%s\"ã®ãƒ‘スワードãŒåˆè‡´ã—ã¾ã›ã‚“。" + +#: libpq/crypt.c:281 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "ユーザ\"%s\"ã®ãƒ‘スワードã¯è­˜åˆ¥ä¸èƒ½ãªå½¢å¼ã§ã™ã€‚" + +#: libpq/hba.c:235 #, c-format msgid "authentication file token too long, skipping: \"%s\"" msgstr "èªè¨¼ãƒ•ァイルã®ãƒˆãƒ¼ã‚¯ãƒ³ãŒé•·ã™ãŽã¾ã™ã®ã§ã€é£›ã°ã—ã¾ã™: \"%s\"" -#: libpq/hba.c:332 +#: libpq/hba.c:407 #, c-format msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" msgstr "セカンダリèªè¨¼ãƒ•ァイル\"@%s\"ã‚’\"%s\"ã¨ã—ã¦ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/hba.c:409 +#: libpq/hba.c:509 #, c-format -#| msgid "authentication file token too long, skipping: \"%s\"" msgid "authentication file line too long" msgstr "èªè¨¼ãƒ•ァイルãŒé•·ã™ãŽã¾ã™" -#: libpq/hba.c:410 libpq/hba.c:775 libpq/hba.c:791 libpq/hba.c:821 -#: libpq/hba.c:867 libpq/hba.c:880 libpq/hba.c:902 libpq/hba.c:911 -#: libpq/hba.c:934 libpq/hba.c:946 libpq/hba.c:965 libpq/hba.c:986 -#: libpq/hba.c:997 libpq/hba.c:1052 libpq/hba.c:1070 libpq/hba.c:1082 -#: libpq/hba.c:1099 libpq/hba.c:1109 libpq/hba.c:1123 libpq/hba.c:1139 -#: libpq/hba.c:1154 libpq/hba.c:1165 libpq/hba.c:1207 libpq/hba.c:1239 -#: libpq/hba.c:1250 libpq/hba.c:1270 libpq/hba.c:1281 libpq/hba.c:1292 -#: libpq/hba.c:1309 libpq/hba.c:1334 libpq/hba.c:1371 libpq/hba.c:1381 -#: libpq/hba.c:1438 libpq/hba.c:1450 libpq/hba.c:1463 libpq/hba.c:1546 -#: libpq/hba.c:1624 libpq/hba.c:1642 libpq/hba.c:1663 tsearch/ts_locale.c:182 +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 +#: libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 +#: libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 +#: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 +#: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 +#: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 +#: libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 +#: libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 +#: libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 +#: libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 +#: libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "設定ファイル \"%2$s\" ã® %1$d 行目" -#: libpq/hba.c:622 -#, c-format -msgid "could not translate host name \"%s\" to address: %s" -msgstr "ホストå \"%s\" をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" - #. translator: the second %s is a list of auth methods -#: libpq/hba.c:773 +#: libpq/hba.c:865 #, c-format msgid "authentication option \"%s\" is only valid for authentication methods %s" msgstr "èªè¨¼ã‚ªãƒ—ション\"%s\"ã¯èªè¨¼æ–¹å¼%sã§ã®ã¿æœ‰åйã§ã™" -#: libpq/hba.c:789 +#: libpq/hba.c:885 #, c-format msgid "authentication method \"%s\" requires argument \"%s\" to be set" msgstr "èªè¨¼æ–¹å¼\"%s\"ã®å ´åˆã¯å¼•æ•°\"%s\"ãŒã‚»ãƒƒãƒˆã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: libpq/hba.c:810 +#: libpq/hba.c:913 #, c-format msgid "missing entry in file \"%s\" at end of line %d" msgstr "ファイル\"%s\"ã®æœ€çµ‚行%dã§ã‚¨ãƒ³ãƒˆãƒªãŒè¶³ã‚Šã¾ã›ã‚“" -#: libpq/hba.c:820 +#: libpq/hba.c:924 #, c-format msgid "multiple values in ident field" msgstr "identヂールド内ã®è¤‡æ•°ã®å€¤" -#: libpq/hba.c:865 +#: libpq/hba.c:973 #, c-format msgid "multiple values specified for connection type" -msgstr "接続種類ã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" +msgstr "接続タイプã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: libpq/hba.c:866 +#: libpq/hba.c:974 #, c-format msgid "Specify exactly one connection type per line." -msgstr "1行ã«ï¼‘ã¤ã®æŽ¥ç¶šç¨®é¡žã ã‘を指定ã—ã¦ãã ã•ã„" +msgstr "1行ã«1ã¤ã®æŽ¥ç¶šã‚¿ã‚¤ãƒ—ã ã‘を指定ã—ã¦ãã ã•ã„" -#: libpq/hba.c:879 +#: libpq/hba.c:988 #, c-format msgid "local connections are not supported by this build" -msgstr "ã“ã®ãƒ“ルドã§ã¯ local 接続ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "ã“ã®ãƒ“ルドã§ã¯local接続ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/hba.c:900 +#: libpq/hba.c:1009 #, c-format -msgid "hostssl requires SSL to be turned on" -msgstr "hostssl 㯠SSL を有効ã«ã™ã‚‹ã‚ˆã†è¦æ±‚ã—ã¦ã„ã¾ã™" +msgid "hostssl record cannot match because SSL is disabled" +msgstr "SSLãŒç„¡åйãªãŸã‚ã€hostssl行ã¯ç…§åˆã§ãã¾ã›ã‚“" -#: libpq/hba.c:901 +#: libpq/hba.c:1010 #, c-format msgid "Set ssl = on in postgresql.conf." -msgstr "postgresql.conf ã§ ssl = on ã«è¨­å®šã—ã¦ãã ã•ã„" +msgstr "postgresql.confã§ ssl = on ã«è¨­å®šã—ã¦ãã ã•ã„。" -#: libpq/hba.c:909 +#: libpq/hba.c:1018 #, c-format -msgid "hostssl is not supported by this build" -msgstr "ã“ã®ãƒ“ルドã§ã¯ hostssl ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "ã“ã®ãƒ“ルドã§ã¯hostsslã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ãªã„ãŸã‚ã€hostssl行ã¯ç…§åˆã§ãã¾ã›ã‚“" -#: libpq/hba.c:910 +#: libpq/hba.c:1019 #, c-format msgid "Compile with --with-openssl to use SSL connections." -msgstr "SSL 接続を有効ã«ã™ã‚‹ã«ã¯ --with-openssl ã§ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„" +msgstr "SSL 接続を有効ã«ã™ã‚‹ã«ã¯ --with-openssl ã§ã‚³ãƒ³ãƒ‘イルã—ã¦ãã ã•ã„。" -#: libpq/hba.c:932 +#: libpq/hba.c:1039 #, c-format msgid "invalid connection type \"%s\"" -msgstr "接続オプションタイプ \"%s\" ã¯ç„¡åйã§ã™" +msgstr "接続オプションタイプ \"%s\" ã¯ä¸æ­£ã§ã™" -#: libpq/hba.c:945 +#: libpq/hba.c:1053 #, c-format msgid "end-of-line before database specification" msgstr "データベース指定ã®å‰ã«è¡Œæœ«ã‚’検出ã—ã¾ã—ãŸ" -#: libpq/hba.c:964 +#: libpq/hba.c:1073 #, c-format msgid "end-of-line before role specification" msgstr "ロール指定ã®å‰ã«è¡Œæœ«ã‚’検出ã—ã¾ã—ãŸ" -#: libpq/hba.c:985 +#: libpq/hba.c:1095 #, c-format msgid "end-of-line before IP address specification" msgstr "IP アドレス指定ã®å‰ã«è¡Œæœ«ã‚’検出ã—ã¾ã—ãŸ" -#: libpq/hba.c:995 +#: libpq/hba.c:1106 #, c-format msgid "multiple values specified for host address" msgstr "ホストアドレスã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: libpq/hba.c:996 +#: libpq/hba.c:1107 #, c-format msgid "Specify one address range per line." -msgstr "1行ã«ï¼‘ã¤ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ç¯„囲を指定ã—ã¦ãã ã•ã„" +msgstr "1行ã«1ã¤ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ç¯„囲を指定ã—ã¦ãã ã•ã„" -#: libpq/hba.c:1050 +#: libpq/hba.c:1162 #, c-format msgid "invalid IP address \"%s\": %s" -msgstr "IP アドレス \"%s\" ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“: %s" +msgstr "䏿­£ãªIPアドレス\"%s\": %s" -#: libpq/hba.c:1068 +#: libpq/hba.c:1182 #, c-format msgid "specifying both host name and CIDR mask is invalid: \"%s\"" -msgstr "ホストå㨠CIDR マスクを両方指定ã™ã‚‹ã®ã¯ç„¡åйã§ã™ï¼š\"%s\"" +msgstr "ホストåã¨CIDRマスクを両方指定ã™ã‚‹ã®ã¯ä¸æ­£ã§ã™: \"%s\"" -#: libpq/hba.c:1080 +#: libpq/hba.c:1196 #, c-format msgid "invalid CIDR mask in address \"%s\"" -msgstr "IP アドレス \"%s\" 内㮠CIDR マスクãŒç„¡åйã§ã™" +msgstr "IPアドレス\"%s\"内㮠CIDR マスクãŒä¸æ­£ã§ã™" -#: libpq/hba.c:1097 +#: libpq/hba.c:1215 #, c-format msgid "end-of-line before netmask specification" msgstr "ãƒãƒƒãƒˆãƒžã‚¹ã‚¯æŒ‡å®šã®å‰ã«è¡Œæœ«ã‚’検出ã—ã¾ã—ãŸ" -#: libpq/hba.c:1098 +#: libpq/hba.c:1216 #, c-format msgid "Specify an address range in CIDR notation, or provide a separate netmask." -msgstr "CIDR記法ã§ã‚¢ãƒ‰ãƒ¬ã‚¹ç¯„囲を指定ã—ã¦ãã ã•ã„。ã¾ãŸã¯åˆ¥ã®ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚’æä¾›ã—ã¦ãã ã•ã„" +msgstr "CIDR記法ã§ã‚¢ãƒ‰ãƒ¬ã‚¹ç¯„囲を指定ã—ã¦ã™ã‚‹ã‹ã€ãƒãƒƒãƒˆãƒžã‚¹ã‚¯ã‚’分ã‘ã¦æŒ‡å®šã—ã¦ãã ã•ã„。" -#: libpq/hba.c:1108 +#: libpq/hba.c:1227 #, c-format msgid "multiple values specified for netmask" msgstr "ãƒãƒƒãƒˆãƒžã‚¹ã‚¯ã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: libpq/hba.c:1121 +#: libpq/hba.c:1241 #, c-format msgid "invalid IP mask \"%s\": %s" -msgstr "IP マスク \"%s\" ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“: %s" +msgstr "䏿­£ãªIPマスク\"%s\": %s" -#: libpq/hba.c:1138 +#: libpq/hba.c:1260 #, c-format msgid "IP address and mask do not match" msgstr "IPアドレスã¨ãƒžã‚¹ã‚¯ãŒä¸€è‡´ã—ã¾ã›ã‚“" -#: libpq/hba.c:1153 +#: libpq/hba.c:1276 #, c-format msgid "end-of-line before authentication method" msgstr "èªè¨¼æ–¹å¼æŒ‡å®šã®å‰ã«è¡Œæœ«ã‚’検出ã—ã¾ã—ãŸ" -#: libpq/hba.c:1163 +#: libpq/hba.c:1287 #, c-format msgid "multiple values specified for authentication type" -msgstr "èªè¨¼ç¨®é¡žã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" +msgstr "èªè¨¼ã‚¿ã‚¤ãƒ—ã§è¤‡æ•°ã®å€¤ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: libpq/hba.c:1164 +#: libpq/hba.c:1288 #, c-format msgid "Specify exactly one authentication type per line." -msgstr "1行ã«ï¼‘ã¤ã®èªè¨¼ç¨®é¡žã ã‘を指定ã—ã¦ãã ã•ã„" +msgstr "èªè¨¼ã‚¿ã‚¤ãƒ—ã¯1行ã«1ã¤ã ã‘指定ã—ã¦ãã ã•ã„。" -#: libpq/hba.c:1237 +#: libpq/hba.c:1365 #, c-format msgid "invalid authentication method \"%s\"" -msgstr "èªè¨¼æ–¹å¼ \"%s\" ãŒæœ‰åйã§ã¯ã‚りã¾ã›ã‚“" +msgstr "䏿­£ãªèªè¨¼æ–¹å¼\"%s\"" -#: libpq/hba.c:1248 +#: libpq/hba.c:1378 #, c-format msgid "invalid authentication method \"%s\": not supported by this build" -msgstr "無効ãªèªè¨¼æ–¹å¼ \"%s\":ã“ã®ãƒ“ルドã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#: libpq/hba.c:1269 -#, c-format -msgid "krb5 authentication is not supported on local sockets" -msgstr "ローカルソケット上㮠KRB5 èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "䏿­£ãªèªè¨¼æ–¹å¼\"%s\": ã“ã®ãƒ“ルドã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: libpq/hba.c:1280 +#: libpq/hba.c:1401 #, c-format msgid "gssapi authentication is not supported on local sockets" -msgstr "ローカルソケットã§ã¯ gssapi èªè¨¼ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgstr "ローカルソケットã§ã¯gssapièªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: libpq/hba.c:1291 +#: libpq/hba.c:1413 #, c-format msgid "peer authentication is only supported on local sockets" -msgstr "ピアèªè¨¼ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã‚½ã‚±ãƒƒãƒˆã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™" +msgstr "peerèªè¨¼ã¯ãƒ­ãƒ¼ã‚«ãƒ«ã‚½ã‚±ãƒƒãƒˆã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™" -#: libpq/hba.c:1308 +#: libpq/hba.c:1431 #, c-format msgid "cert authentication is only supported on hostssl connections" -msgstr "hostssl 接続ã§ã¯è¨¼æ˜Žæ›¸èªè¨¼ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™" +msgstr "hostssl接続ã§ã¯è¨¼æ˜Žæ›¸èªè¨¼ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™" -#: libpq/hba.c:1333 +#: libpq/hba.c:1481 #, c-format msgid "authentication option not in name=value format: %s" -msgstr "èªè¨¼ã‚ªãƒ—ション㌠åå‰=値 å½¢å¼ã«ãªã£ã¦ã„ã¾ã›ã‚“:%s" +msgstr "èªè¨¼ã‚ªãƒ—ション㌠åå‰=値 å½¢å¼ã«ãªã£ã¦ã„ã¾ã›ã‚“: %s" -#: libpq/hba.c:1370 +#: libpq/hba.c:1522 #, c-format -#| msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, or ldapsearchattribute together with ldapprefix" -msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurl together with ldapprefix" -msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or ldapurlã¯ã€ldapprefix ã¨åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn〠ldapbinddnã€ldapbindpasswdã€ldapsearchattributeã€, ldapsearchfilter ã¾ãŸã¯ldapurlã¯ã€ldapprefixã¨åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: libpq/hba.c:1380 +#: libpq/hba.c:1533 #, c-format msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "\"ldap\" èªè¨¼æ–¹å¼ã®å ´åˆã¯å¼•æ•° \"ldapbasedn\", \"ldapprefix\" \"ldapsuffix\" ã®ã„ãšã‚Œã‹ã‚’指定ã—ã¦ãã ã•ã„" -#: libpq/hba.c:1424 -msgid "ident, peer, krb5, gssapi, sspi, and cert" -msgstr "identã€peerã€krb5ã€gssapiã€sspiãŠã‚ˆã³cert" +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattributeã€ldapsearchfilter ã¨åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: libpq/hba.c:1437 +#: libpq/hba.c:1566 #, c-format -msgid "clientcert can only be configured for \"hostssl\" rows" -msgstr "クライアント証明書㯠\"hostssl\" ãªè¡Œã§ã®ã¿è¨­å®šã§ãã¾ã™" +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUSサーãƒãƒ¼ã®ãƒªã‚¹ãƒˆã¯ç©ºã«ã¯ã§ãã¾ã›ã‚“" -#: libpq/hba.c:1448 +#: libpq/hba.c:1576 #, c-format -msgid "client certificates can only be checked if a root certificate store is available" -msgstr "クライアント証明書ã¯ãƒ«ãƒ¼ãƒˆè¨¼æ˜Žæ›¸ã‚¹ãƒˆã‚¢ãŒåˆ©ç”¨ã§ãã‚‹å ´åˆã«ã®ã¿æ¤œè¨¼ã•れã¾ã™" +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUSシークレットã®ãƒªã‚¹ãƒˆã¯ç©ºã«ã¯ã§ãã¾ã›ã‚“" -#: libpq/hba.c:1449 +#: libpq/hba.c:1629 #, c-format -msgid "Make sure the configuration parameter \"ssl_ca_file\" is set." -msgstr "設定パラメータ\"ssl_ca_file\"ãŒè¨­å®šã•れã¦ã„ã‚‹ã‹ç¢ºèªã—ã¦ãã ã•ã„" +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "%sã®æ•°(%d)ã¯1ã¾ãŸã¯%sã®æ•°(%d)ã¨åŒã˜ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: libpq/hba.c:1462 +# +#: libpq/hba.c:1663 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "identã€peerã€gssapiã€sspiãŠã‚ˆã³cert" + +#: libpq/hba.c:1672 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "クライアント証明書㯠\"hostssl\" ãªè¡Œã§ã®ã¿è¨­å®šã§ãã¾ã™" + +#: libpq/hba.c:1688 #, c-format msgid "clientcert can not be set to 0 when using \"cert\" authentication" msgstr "\"cert\" èªè¨¼ã‚’使ã†å ´åˆã¯ clientcert ㌠0 ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: libpq/hba.c:1489 +#: libpq/hba.c:1725 #, c-format -#| msgid "could not open file \"%s\": %s" msgid "could not parse LDAP URL \"%s\": %s" -msgstr "LDAP URL\"%s\"ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgstr "LDAP URL\"%s\"をパースã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/hba.c:1497 +#: libpq/hba.c:1736 #, c-format -#| msgid "unsupported format code: %d" msgid "unsupported LDAP URL scheme: %s" msgstr "未サãƒãƒ¼ãƒˆã®LDAP URLコード: %s" -#: libpq/hba.c:1513 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "LDAP URLã§ã¯ãƒ•ィルタã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" - -#: libpq/hba.c:1521 +#: libpq/hba.c:1760 #, c-format -#| msgid "LDAP over SSL is not supported on this platform." msgid "LDAP URLs not supported on this platform" msgstr "ã“ã®ãƒ—ラットフォームã§ã¯LDAP URLをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。" -#: libpq/hba.c:1545 +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "䏿­£ãª ldapscheme ã®å€¤: \"%s\"" + +#: libpq/hba.c:1796 #, c-format msgid "invalid LDAP port number: \"%s\"" -msgstr "無効ãªLDAPãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"" +msgstr "䏿­£ãªLDAPãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"" + +# +#: libpq/hba.c:1842 libpq/hba.c:1849 +msgid "gssapi and sspi" +msgstr "gssapiãŠã‚ˆã³sspi" -#: libpq/hba.c:1591 libpq/hba.c:1599 -msgid "krb5, gssapi, and sspi" -msgstr "krb5ã€gssapiãŠã‚ˆã³sspi" +#: libpq/hba.c:1858 libpq/hba.c:1867 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1889 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "RADIUSサーãƒã®ãƒªã‚¹ãƒˆ\"%s\"ã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: libpq/hba.c:1937 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "RADIUSãƒãƒ¼ãƒˆã®ãƒªã‚¹ãƒˆ\"%s\"ã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" -#: libpq/hba.c:1641 +#: libpq/hba.c:1951 #, c-format msgid "invalid RADIUS port number: \"%s\"" -msgstr "無効㪠RADIUS ãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"" +msgstr "䏿­£ãªRADIUSãƒãƒ¼ãƒˆç•ªå·: \"%s\"" -#: libpq/hba.c:1661 +#: libpq/hba.c:1973 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "RADIUSシークレットã®ãƒªã‚¹ãƒˆ\"%s\"ã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: libpq/hba.c:1995 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "RADIUS識別å­ã®ãƒªã‚¹ãƒˆ\"%s\"ã®ãƒ‘ースã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: libpq/hba.c:2009 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "èªè¨¼ã‚ªãƒ—ションåã‚’èªè­˜ã§ãã¾ã›ã‚“: \"%s\"" -#: libpq/hba.c:1852 +#: libpq/hba.c:2193 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "設定ファイル\"%s\"ã«ã¯ä½•ã‚‚å«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" -#: libpq/hba.c:1948 +#: libpq/hba.c:2706 #, c-format msgid "invalid regular expression \"%s\": %s" -msgstr "æ­£è¦è¡¨ç¾\"%s\"ãŒç„¡åйã§ã™: %s" +msgstr "䏿­£ãªæ­£è¦è¡¨ç¾\"%s\": %s" -#: libpq/hba.c:2008 +#: libpq/hba.c:2766 #, c-format msgid "regular expression match for \"%s\" failed: %s" -msgstr "æ­£è¦è¡¨ç¾\"%s\"ã§ãƒžãƒƒãƒãƒ³ã‚°ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" +msgstr "æ­£è¦è¡¨ç¾\"%s\"ã§ç…§åˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s" -#: libpq/hba.c:2025 +#: libpq/hba.c:2785 #, c-format msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" -msgstr "æ­£è¦è¡¨ç¾\"%s\"ã«ã¯\"%s\"ã«ãŠã‘る後方å‚ç…§ãŒè¦æ±‚ã™ã‚‹å‰¯è¡¨ç¾å¼ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" +msgstr "æ­£è¦è¡¨ç¾\"%s\"ã«ã¯\"%s\"ã«ãŠã‘る後方å‚ç…§ãŒè¦æ±‚ã™ã‚‹å‰¯è¡¨ç¾ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" -#: libpq/hba.c:2121 +#: libpq/hba.c:2882 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" -msgstr "与ãˆã‚‰ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼å (%s) ã¨èªè¨¼ã•れãŸãƒ¦ãƒ¼ã‚¶ãƒ¼å (%s) ãŒä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "与ãˆã‚‰ã‚ŒãŸãƒ¦ãƒ¼ã‚¶å (%s) ã¨èªè¨¼ã•れãŸãƒ¦ãƒ¼ã‚¶å (%s) ãŒä¸€è‡´ã—ã¾ã›ã‚“" -#: libpq/hba.c:2141 +#: libpq/hba.c:2902 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "\"%3$s\"ã¨ã—ã¦èªè¨¼ã•れãŸãƒ¦ãƒ¼ã‚¶ \"%2$s\" ã¯ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ— \"%1$s\" ã«ä¸€è‡´ã—ã¾ã›ã‚“" -#: libpq/hba.c:2176 +#: libpq/hba.c:2935 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "ユーザマップファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqcomm.c:314 +#: libpq/pqcomm.c:220 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "ソケットをéžãƒ–ロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: libpq/pqcomm.c:374 #, c-format -#| msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" msgstr "Unixドメインソケットã®ãƒ‘ス\"%s\"ãŒé•·ã™ãŽã¾ã™(最大 %d ãƒã‚¤ãƒˆ)" -#: libpq/pqcomm.c:335 +#: libpq/pqcomm.c:395 #, c-format msgid "could not translate host name \"%s\", service \"%s\" to address: %s" msgstr "ホストå\"%s\"ã€ã‚µãƒ¼ãƒ“ス\"%s\"をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/pqcomm.c:339 +#: libpq/pqcomm.c:399 #, c-format msgid "could not translate service \"%s\" to address: %s" msgstr "サービス\"%s\"をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: libpq/pqcomm.c:366 +#: libpq/pqcomm.c:426 #, c-format msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" msgstr "è¦æ±‚ã•れãŸã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’å…¨ã¦ãƒã‚¤ãƒ³ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: MAXLISTEN (%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: libpq/pqcomm.c:375 +#: libpq/pqcomm.c:435 msgid "IPv4" msgstr "IPv4" -#: libpq/pqcomm.c:379 +#: libpq/pqcomm.c:439 msgid "IPv6" msgstr "IPv6" -#: libpq/pqcomm.c:384 +#: libpq/pqcomm.c:444 msgid "Unix" msgstr "Unix" -#: libpq/pqcomm.c:389 +#: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" msgstr "アドレスファミリ %d ã‚’èªè­˜ã§ãã¾ã›ã‚“" -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:400 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:475 #, c-format -msgid "could not create %s socket: %m" -msgstr "%sソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not create %s socket for address \"%s\": %m" +msgstr "アドレス\"%s\"ã«å¯¾ã™ã‚‹%sソケットã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: libpq/pqcomm.c:425 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:501 #, c-format -msgid "setsockopt(SO_REUSEADDR) failed: %m" -msgstr "setsockopt(SO_REUSEADDR)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"ã«å¯¾ã™ã‚‹setsockopt(SO_REUSEADDR)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#: libpq/pqcomm.c:440 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:518 #, c-format -msgid "setsockopt(IPV6_V6ONLY) failed: %m" -msgstr "setsockopt(IPV6_V6ONLY)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"ã«å¯¾ã™ã‚‹setsockopt(IPV6_V6ONLY)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:459 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:538 #, c-format -msgid "could not bind %s socket: %m" -msgstr "%sソケットをãƒã‚¤ãƒ³ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not bind %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"ã®bindã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: libpq/pqcomm.c:462 +#: libpq/pqcomm.c:541 #, c-format msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." -msgstr "ã™ã§ã«ä»–ã«postmasterãŒãƒãƒ¼ãƒˆ%dã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹? 稼動ã—ã¦ã„ãªã‘れã°ã‚½ã‚±ãƒƒãƒˆãƒ•ァイル\"%s\"を削除ã—å†å®Ÿè¡Œã—ã¦ãã ã•ã„" +msgstr "ã™ã§ã«ä»–ã«postmasterãŒãƒãƒ¼ãƒˆ%dã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹? 稼動ã—ã¦ã„ãªã‘れã°ã‚½ã‚±ãƒƒãƒˆãƒ•ァイル\"%s\"を削除ã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。" -#: libpq/pqcomm.c:465 +#: libpq/pqcomm.c:544 #, c-format msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." -msgstr "ã™ã§ã«ä»–ã«postmasterãŒãƒãƒ¼ãƒˆ%dã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹? 稼動ã—ã¦ã„ãªã‘ã‚Œã°æ•°ç§’å¾…ã£ã¦ã‹ã‚‰å†å®Ÿè¡Œã—ã¦ãã ã•ã„" +msgstr "ã™ã§ã«ä»–ã«postmasterãŒãƒãƒ¼ãƒˆ%dã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹? 稼動ã—ã¦ã„ãªã‘ã‚Œã°æ•°ç§’å¾…ã£ã¦ã‹ã‚‰å†è©¦è¡Œã—ã¦ãã ã•ã„。" -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:498 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:577 #, c-format -msgid "could not listen on %s socket: %m" -msgstr "%sソケットをlistenã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not listen on %s address \"%s\": %m" +msgstr "%sアドレス\"%s\"ã®listenã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: libpq/pqcomm.c:588 +#: libpq/pqcomm.c:586 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "Unixソケット\"%s\"ã§å¾…ã¡å—ã‘ã¦ã„ã¾ã™" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:592 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "%sアドレス\"%s\"ã€ãƒãƒ¼ãƒˆ%dã§å¾…ã¡å—ã‘ã¦ã„ã¾ã™" + +#: libpq/pqcomm.c:675 #, c-format msgid "group \"%s\" does not exist" msgstr "グループ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: libpq/pqcomm.c:598 +#: libpq/pqcomm.c:685 #, c-format msgid "could not set group of file \"%s\": %m" msgstr "ファイル\"%s\"ã®ã‚°ãƒ«ãƒ¼ãƒ—を設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqcomm.c:609 +#: libpq/pqcomm.c:696 #, c-format msgid "could not set permissions of file \"%s\": %m" msgstr "ファイル\"%s\"ã®æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqcomm.c:639 +#: libpq/pqcomm.c:726 #, c-format msgid "could not accept new connection: %m" msgstr "æ–°ã—ã„æŽ¥ç¶šã‚’å—ã‘付ã‘ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqcomm.c:811 -#, c-format -#| msgid "could not set socket to non-blocking mode: %m" -msgid "could not set socket to nonblocking mode: %m" -msgstr "ソケットをéžãƒ–ロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: libpq/pqcomm.c:817 +#: libpq/pqcomm.c:927 #, c-format -msgid "could not set socket to blocking mode: %m" -msgstr "ソケットをブロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "there is no client connection" +msgstr "クライアント接続ãŒã‚りã¾ã›ã‚“" -#: libpq/pqcomm.c:869 libpq/pqcomm.c:959 +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 #, c-format msgid "could not receive data from client: %m" msgstr "クライアントã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqcomm.c:1110 +#: libpq/pqcomm.c:1219 tcop/postgres.c:4020 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "プロトコルã®åŒæœŸãŒå¤±ã‚れãŸãŸã‚コãƒã‚¯ã‚·ãƒ§ãƒ³ã‚’終了ã—ã¾ã™" + +#: libpq/pqcomm.c:1285 #, c-format msgid "unexpected EOF within message length word" msgstr "メッセージ長ワード内ã®EOFã¯æƒ³å®šå¤–ã§ã™" -#: libpq/pqcomm.c:1121 +#: libpq/pqcomm.c:1296 #, c-format msgid "invalid message length" -msgstr "メッセージ長ãŒç„¡åйã§ã™" +msgstr "メッセージ長ãŒä¸æ­£ã§ã™" -#: libpq/pqcomm.c:1143 libpq/pqcomm.c:1153 +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 #, c-format msgid "incomplete message from client" msgstr "クライアントã‹ã‚‰ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒä¸å®Œå…¨ã§ã™" -#: libpq/pqcomm.c:1283 +#: libpq/pqcomm.c:1464 #, c-format msgid "could not send data to client: %m" msgstr "クライアントã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: libpq/pqformat.c:436 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "メッセージ内ã«ãƒ‡ãƒ¼ã‚¿ãŒæ®‹ã£ã¦ã„ã¾ã›ã‚“" -#: libpq/pqformat.c:556 libpq/pqformat.c:574 libpq/pqformat.c:595 -#: utils/adt/arrayfuncs.c:1416 utils/adt/rowtypes.c:573 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 #, c-format msgid "insufficient data left in message" msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å†…ã«æ®‹ã‚‹ãƒ‡ãƒ¼ã‚¿ãŒä¸å分ã§ã™" -#: libpq/pqformat.c:636 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" -msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å†…ã®æ–‡å­—列ãŒç„¡åйã§ã™" +msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸å†…ã®æ–‡å­—列ãŒä¸æ­£ã§ã™" -#: libpq/pqformat.c:652 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" -msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æ›¸å¼ãŒç„¡åйã§ã™" - -#: main/main.c:231 -#, c-format -msgid "%s: setsysinfo failed: %s\n" -msgstr "%s: setsysinfoãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgstr "ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®æ›¸å¼ãŒä¸æ­£ã§ã™" -#: main/main.c:253 +#: main/main.c:264 #, c-format msgid "%s: WSAStartup failed: %d\n" msgstr "%s: WSAStartupãŒå¤±æ•—ã—ã¾ã—ãŸ: %d\n" -#: main/main.c:276 +#: main/main.c:328 #, c-format msgid "" "%s is the PostgreSQL server.\n" @@ -10311,7 +13717,7 @@ msgstr "" "%sã¯PostgreSQLサーãƒã§ã™\n" "\n" -#: main/main.c:277 +#: main/main.c:329 #, c-format msgid "" "Usage:\n" @@ -10319,120 +13725,115 @@ msgid "" "\n" msgstr "" "使用方法:\n" -"\" %s [オプション]...\n" +" %s [オプション]...\n" "\n" -#: main/main.c:278 +#: main/main.c:330 #, c-format msgid "Options:\n" msgstr "オプション:\n" -#: main/main.c:280 -#, c-format -msgid " -A 1|0 enable/disable run-time assert checking\n" -msgstr " -A 1|0 実行時ã®ã‚¢ã‚µãƒ¼ãƒˆæ¤œæŸ»ã‚’有効/無効ã«ã—ã¾ã™\n" - -#: main/main.c:282 +#: main/main.c:331 #, c-format msgid " -B NBUFFERS number of shared buffers\n" -msgstr " -B NBUFFERS 共有ãƒãƒƒãƒ•ã‚¡æ•°ã§ã™\n" +msgstr " -B NBUFFERS 共有ãƒãƒƒãƒ•ã‚¡ã®æ•°\n" -#: main/main.c:283 +#: main/main.c:332 #, c-format msgid " -c NAME=VALUE set run-time parameter\n" -msgstr " -c NAME=VALUE 実行時パラメータを設定ã—ã¾ã™\n" +msgstr " -c NAME=VALUE 実行時パラメータã®è¨­å®š\n" -#: main/main.c:284 +#: main/main.c:333 #, c-format msgid " -C NAME print value of run-time parameter, then exit\n" -msgstr " -C NAME 実行時パラメータã®å€¤ã‚’表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -C NAME 実行時パラメータã®å€¤ã‚’表示ã—ã€çµ‚了ã—ã¾ã™\n" -#: main/main.c:285 +#: main/main.c:334 #, c-format msgid " -d 1-5 debugging level\n" -msgstr " -d 1-5 デãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«ã§ã™\n" +msgstr " -d 1-5 デãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«\n" -#: main/main.c:286 +#: main/main.c:335 #, c-format msgid " -D DATADIR database directory\n" -msgstr " -D DATADIR データベースディレクトリã§ã™\n" +msgstr " -D DATADIR データベースディレクトリ\n" -#: main/main.c:287 +#: main/main.c:336 #, c-format msgid " -e use European date input format (DMY)\n" -msgstr " -e ヨーロッパ方å¼ã®æ—¥ä»˜å…¥åŠ›ã‚’è¡Œã„ã¾ã™(DMY)\n" +msgstr " -e ヨーロッパå¼ã®æ—¥ä»˜ãƒ•ォーマットã§ã®å…¥åŠ›(DMY)\n" -#: main/main.c:288 +#: main/main.c:337 #, c-format msgid " -F turn fsync off\n" msgstr " -F fsyncを無効ã«ã—ã¾ã™\n" -#: main/main.c:289 +#: main/main.c:338 #, c-format msgid " -h HOSTNAME host name or IP address to listen on\n" -msgstr " -h HOSTNAME 接続を監視ã™ã‚‹ãƒ›ã‚¹ãƒˆåã¾ãŸã¯IPアドレスã§ã™\n" +msgstr " -h HOSTNAME 接続を待ã¡å—ã‘るホストåã¾ãŸã¯IPアドレス\n" -#: main/main.c:290 +#: main/main.c:339 #, c-format msgid " -i enable TCP/IP connections\n" msgstr " -i TCP/IP接続を有効ã«ã—ã¾ã™\n" -#: main/main.c:291 +#: main/main.c:340 #, c-format msgid " -k DIRECTORY Unix-domain socket location\n" -msgstr " -k DIRECTORY Unixドメインソケットã®å ´æ‰€ã§ã™\n" +msgstr " -k DIRECTORY Unixドメインソケットã®å ´æ‰€\n" -#: main/main.c:293 +#: main/main.c:342 #, c-format msgid " -l enable SSL connections\n" msgstr " -l SSL接続を有効ã«ã—ã¾ã™\n" -#: main/main.c:295 +#: main/main.c:344 #, c-format msgid " -N MAX-CONNECT maximum number of allowed connections\n" -msgstr " -N MAX-CONNECT 許容ã™ã‚‹æœ€å¤§æŽ¥ç¶šæ•°ã§ã™\n" +msgstr " -N MAX-CONNECT 許容ã™ã‚‹æœ€å¤§æŽ¥ç¶šæ•°\n" -#: main/main.c:296 +#: main/main.c:345 #, c-format msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" msgstr " -o OPTIONS 個々ã®ã‚µãƒ¼ãƒãƒ—ロセスã«\"OPTIONS\"を渡ã—ã¾ã™(å¤ã„å½¢å¼)\n" -#: main/main.c:297 +#: main/main.c:346 #, c-format msgid " -p PORT port number to listen on\n" -msgstr " -p PORT 接続を監視ã™ã‚‹ãƒãƒ¼ãƒˆç•ªå·ã§ã™\n" +msgstr " -p PORT 接続を待ã¡å—ã‘ã‚‹ãƒãƒ¼ãƒˆç•ªå·\n" -#: main/main.c:298 +#: main/main.c:347 #, c-format msgid " -s show statistics after each query\n" msgstr " -s å„å•ã„åˆã‚ã›ã®å¾Œã«çµ±è¨ˆæƒ…報を表示ã—ã¾ã™\n" -#: main/main.c:299 +#: main/main.c:348 #, c-format msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" -msgstr " -S WORK-MEM ソート用ã®ãƒ¡ãƒ¢ãƒªé‡ã‚’設定ã—ã¾ã™(KBå˜ä½)\n" +msgstr " -S WORK-MEM ソート用ã®ãƒ¡ãƒ¢ãƒªé‡ (KBå˜ä½)\n" -#: main/main.c:300 +#: main/main.c:349 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" -#: main/main.c:301 +#: main/main.c:350 #, c-format msgid " --NAME=VALUE set run-time parameter\n" msgstr " --NAME=VALUE 実行時パラメータを設定ã—ã¾ã™\n" -#: main/main.c:302 +#: main/main.c:351 #, c-format msgid " --describe-config describe configuration parameters, then exit\n" -msgstr " --describe-config 設定パラメータã®èª¬æ˜Žã‚’出力ã—終了ã—ã¾ã™\n" +msgstr " --describe-config 設定パラメータã®èª¬æ˜Žã‚’出力ã—ã€çµ‚了ã—ã¾ã™\n" -#: main/main.c:303 +#: main/main.c:352 #, c-format msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" -#: main/main.c:305 +#: main/main.c:354 #, c-format msgid "" "\n" @@ -10441,42 +13842,42 @@ msgstr "" "\n" "開発者å‘ã‘オプション:\n" -#: main/main.c:306 +#: main/main.c:355 #, c-format msgid " -f s|i|n|m|h forbid use of some plan types\n" -msgstr " -f s|i|n|m|h ã„ãã¤ã‹ã®è¨ˆç”»åž‹ã‚’ç¦æ­¢ã—ã¾ã™\n" +msgstr " -f s|i|n|m|h ã„ãã¤ã‹ã®ãƒ—ãƒ©ãƒ³ã‚¿ã‚¤ãƒ—ã‚’ç¦æ­¢ã—ã¾ã™\n" -#: main/main.c:307 +#: main/main.c:356 #, c-format msgid " -n do not reinitialize shared memory after abnormal exit\n" msgstr " -n 異常終了後ã«å…±æœ‰ãƒ¡ãƒ¢ãƒªã®å†åˆæœŸåŒ–を行ã„ã¾ã›ã‚“\n" -#: main/main.c:308 +#: main/main.c:357 #, c-format msgid " -O allow system table structure changes\n" msgstr " -O システムテーブル構造ã®å¤‰æ›´ã‚’許å¯ã—ã¾ã™\n" -#: main/main.c:309 +#: main/main.c:358 #, c-format msgid " -P disable system indexes\n" msgstr " -P システムインデックスを無効ã«ã—ã¾ã™\n" -#: main/main.c:310 +#: main/main.c:359 #, c-format msgid " -t pa|pl|ex show timings after each query\n" -msgstr " -t pa|pl|ex å„å•ã„åˆã‚ã›ã®å¾Œã«ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’表示ã—ã¾ã™\n" +msgstr " -t pa|pl|ex å„å•ã„åˆã‚ã›ã®å¾Œã«æ™‚間情報を表示ã—ã¾ã™\n" -#: main/main.c:311 +#: main/main.c:360 #, c-format msgid " -T send SIGSTOP to all backend processes if one dies\n" -msgstr " -T 1ã¤ã®ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã‚µãƒ¼ãƒãŒåœæ­¢ã—ãŸæ™‚ã«å…¨ã¦ã®ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã‚µãƒ¼ãƒã«SIGSTOPã‚’é€ä¿¡ã—ã¾ã™\n" +msgstr " -T 1ã¤ã®ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãƒ—ãƒ­ã‚»ã‚¹ç•°å¸¸åœæ­¢ã—ãŸæ™‚ã«å…¨ã¦ã®ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãƒ—ロセスSIGSTOPã‚’é€ä¿¡ã—ã¾ã™\n" -#: main/main.c:312 +#: main/main.c:361 #, c-format msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" -msgstr " -W NUM デãƒãƒƒã‚¬ã‚’設定ã§ãるよã†ã«NUM秒待機ã—ã¾ã™\n" +msgstr " -W NUM デãƒãƒƒã‚¬ã‚’アタッãƒã§ãるよã†ã«NUM秒待機ã—ã¾ã™\n" -#: main/main.c:314 +#: main/main.c:363 #, c-format msgid "" "\n" @@ -10485,37 +13886,37 @@ msgstr "" "\n" "シングルユーザモード用ã®ã‚ªãƒ—ション:\n" -#: main/main.c:315 +#: main/main.c:364 #, c-format msgid " --single selects single-user mode (must be first argument)\n" msgstr " --single ã‚·ãƒ³ã‚°ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¾ã™ï¼ˆæœ€åˆã®å¼•æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)\n" -#: main/main.c:316 +#: main/main.c:365 #, c-format msgid " DBNAME database name (defaults to user name)\n" msgstr " DBNAME データベースå(デフォルトã¯ãƒ¦ãƒ¼ã‚¶åã§ã™ï¼‰\n" -#: main/main.c:317 +#: main/main.c:366 #, c-format msgid " -d 0-5 override debugging level\n" msgstr " -d 1-5 デãƒãƒƒã‚°ãƒ¬ãƒ™ãƒ«ã‚’上書ãã—ã¾ã™\n" -#: main/main.c:318 +#: main/main.c:367 #, c-format msgid " -E echo statement before execution\n" msgstr " -E 実行å‰ã«æ–‡ã‚’表示ã—ã¾ã™\n" -#: main/main.c:319 +#: main/main.c:368 #, c-format msgid " -j do not use newline as interactive query delimiter\n" msgstr " -j 対話å¼å•ã„åˆã‚ã›ã®åŒºåˆ‡ã‚Šã¨ã—ã¦æ”¹è¡Œã‚’使用ã—ã¾ã›ã‚“\n" -#: main/main.c:320 main/main.c:325 +#: main/main.c:369 main/main.c:374 #, c-format msgid " -r FILENAME send stdout and stderr to given file\n" -msgstr " -r FILENAME æ¨™æº–å‡ºåŠ›ã¨æ¨™æº–エラー出力を指定ã—ãŸãƒ•ァイルã«é€ä¿¡ã—ã¾ã™\n" +msgstr " -r FILENAME æ¨™æº–å‡ºåŠ›ã¨æ¨™æº–エラー出力を指定ã—ãŸãƒ•ァイルã«å‡ºåŠ›ã—ã¾ã™\n" -#: main/main.c:322 +#: main/main.c:371 #, c-format msgid "" "\n" @@ -10524,22 +13925,22 @@ msgstr "" "\n" "åˆæœŸèµ·å‹•用ã®ã‚ªãƒ—ション:\n" -#: main/main.c:323 +#: main/main.c:372 #, c-format msgid " --boot selects bootstrapping mode (must be first argument)\n" msgstr " --boot åˆæœŸèµ·å‹•ãƒ¢ãƒ¼ãƒ‰ã‚’é¸æŠžã—ã¾ã™ï¼ˆæœ€åˆã®å¼•æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“)\n" -#: main/main.c:324 +#: main/main.c:373 #, c-format msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" -msgstr " DBNAME データベースåï¼ˆåˆæœŸèµ·å‹•モードã§ã¯ç¾©å‹™çš„ãªå¼•数)\n" +msgstr " DBNAME データベースåï¼ˆåˆæœŸèµ·å‹•モードã§ã¯å¿…é ˆã®å¼•数)\n" -#: main/main.c:326 +#: main/main.c:375 #, c-format msgid " -x NUM internal use\n" msgstr " -x NUM 内部使用\n" -#: main/main.c:328 +#: main/main.c:377 #, c-format msgid "" "\n" @@ -10550,12 +13951,12 @@ msgid "" "Report bugs to .\n" msgstr "" "\n" -"実効時設定パラメータã®å…¨ä¸€è¦§ã¨ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚„設定ファイルã«ãŠã‘ã‚‹\n" +"å…¨ã¦ã®å®Ÿè¡Œæ™‚設定パラメータã®ä¸€è¦§ã¨ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚„設定ファイルã«ãŠã‘ã‚‹\n" "設定方法ã«ã¤ã„ã¦ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" "\n" "ä¸å…·åˆã¯ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„\n" -#: main/main.c:342 +#: main/main.c:391 #, c-format msgid "" "\"root\" execution of the PostgreSQL server is not permitted.\n" @@ -10563,17 +13964,17 @@ msgid "" "possible system security compromise. See the documentation for\n" "more information on how to properly start the server.\n" msgstr "" -"PostgreSQLã‚’\"root\"ã§å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" -"システムセキュリティã®å±é™ºé˜²æ­¢ã®ãŸã‚éžç‰¹æ¨©ãƒ¦ãƒ¼ã‚¶IDã§ã‚µãƒ¼ãƒã‚’èµ·å‹•ã—ãª\n" -"ã‘れã°ãªã‚Šã¾ã›ã‚“。é©åˆ‡ãªã‚µãƒ¼ãƒã®èµ·å‹•方法ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’\n" +"PostgreSQLã®\"root\"ã§ã®å®Ÿè¡Œã¯è¨±å¯ã•れã¾ã›ã‚“。\n" +"システムセキュリティã®ä½Žä¸‹ã‚’防止ã™ã‚‹ãŸã‚ã€ã‚µãƒ¼ãƒã¯éžç‰¹æ¨©ãƒ¦ãƒ¼ã‚¶IDã§èµ·å‹•\n" +"ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚é©åˆ‡ãªã‚µãƒ¼ãƒã®èµ·å‹•方法ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’\n" "å‚ç…§ã—ã¦ãã ã•ã„\n" -#: main/main.c:359 +#: main/main.c:408 #, c-format msgid "%s: real and effective user IDs must match\n" -msgstr "%s: リアルユーザIDã¨å®ŸåŠ¹ãƒ¦ãƒ¼ã‚¶IDã¯ä¸€è‡´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgstr "%s: 実ユーザIDã¨å®ŸåŠ¹ãƒ¦ãƒ¼ã‚¶IDã¯ä¸€è‡´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: main/main.c:366 +#: main/main.c:415 #, c-format msgid "" "Execution of PostgreSQL by a user with administrative permissions is not\n" @@ -10582,703 +13983,987 @@ msgid "" "possible system security compromises. See the documentation for\n" "more information on how to properly start the server.\n" msgstr "" -"PostgreSQLを管ç†è€…権é™ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ã§å®Ÿè¡Œã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" -"システムセキュリティã®å±é™ºé˜²æ­¢ã®ãŸã‚éžç‰¹æ¨©ãƒ¦ãƒ¼ã‚¶IDã§ã‚µãƒ¼ãƒã‚’èµ·å‹•ã—ãª\n" -"ã‘れã°ãªã‚Šã¾ã›ã‚“。é©åˆ‡ãªã‚µãƒ¼ãƒã®èµ·å‹•方法ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’\n" +"PostgreSQLを管ç†è€…権é™ã‚’æŒã¤ãƒ¦ãƒ¼ã‚¶ã§ã®å®Ÿè¡Œã¯è¨±å¯ã•れã¾ã›ã‚“。\n" +"システムセキュリティã®ä½Žä¸‹ã‚’防止ã™ã‚‹ãŸã‚ã€ã‚µãƒ¼ãƒã¯éžç‰¹æ¨©ãƒ¦ãƒ¼ã‚¶IDã§èµ·å‹•\n" +"ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚é©åˆ‡ãªã‚µãƒ¼ãƒã®èµ·å‹•方法ã«é–¢ã™ã‚‹è©³ç´°ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’\n" "å‚ç…§ã—ã¦ãã ã•ã„\n" -#: main/main.c:387 +#: nodes/extensible.c:66 #, c-format -msgid "%s: invalid effective UID: %d\n" -msgstr "%s: 実効UIDãŒç„¡åйã§ã™: %d\n" +msgid "extensible node type \"%s\" already exists" +msgstr "æ‹¡å¼µå¯èƒ½ãƒŽãƒ¼ãƒ‰ã‚¿ã‚¤ãƒ—\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: main/main.c:400 +#: nodes/extensible.c:114 #, c-format -msgid "%s: could not determine user name (GetUserName failed)\n" -msgstr "%s: ユーザåを決定ã§ãã¾ã›ã‚“ã§ã—ãŸ(GetUserNameãŒå¤±æ•—ã—ã¾ã—ãŸ)\n" +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods \"%s\" ã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“" -#: nodes/nodeFuncs.c:115 nodes/nodeFuncs.c:141 parser/parse_coerce.c:1782 -#: parser/parse_coerce.c:1810 parser/parse_coerce.c:1886 -#: parser/parse_expr.c:1736 parser/parse_func.c:377 parser/parse_oper.c:948 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "データ型%sã®é…列型ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/path/joinrels.c:722 +#: optimizer/path/joinrels.c:837 #, c-format msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "FULL JOIN ã¯ãƒžãƒ¼ã‚¸çµåˆå¯èƒ½ã‚‚ã—ãã¯ãƒãƒƒã‚·ãƒ¥çµåˆå¯èƒ½ãªå ´åˆã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:876 +#: optimizer/plan/initsplan.c:1221 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE cannot be applied to the nullable side of an outer join" msgid "%s cannot be applied to the nullable side of an outer join" -msgstr "外部çµåˆã®NULLã«ãªã‚‹å¯èƒ½æ€§ãŒã‚ã‚‹æ–¹ã§ã¯%sã‚’é©ç”¨ã§ãã¾ã›ã‚“" +msgstr "外部çµåˆã®NULLå¯ãªå´ã§ã¯%sã‚’é©ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1113 parser/analyze.c:1321 parser/analyze.c:1519 -#: parser/analyze.c:2253 +#: optimizer/plan/planner.c:1767 parser/analyze.c:1651 parser/analyze.c:1848 +#: parser/analyze.c:2679 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE is not allowed with UNION/INTERSECT/EXCEPT" msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "UNION/INTERSECT/EXCEPTã§ã¯%sを使用ã§ãã¾ã›ã‚“" -#: optimizer/plan/planner.c:2671 +#: optimizer/plan/planner.c:2339 optimizer/plan/planner.c:4060 #, c-format msgid "could not implement GROUP BY" -msgstr "GROUP BY を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "GROUP BY を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/plan/planner.c:2672 optimizer/plan/planner.c:2840 -#: optimizer/prep/prepunion.c:824 +#: optimizer/plan/planner.c:2340 optimizer/plan/planner.c:4061 +#: optimizer/plan/planner.c:4804 optimizer/prep/prepunion.c:1080 #, c-format msgid "Some of the datatypes only support hashing, while others only support sorting." -msgstr "ãƒãƒƒã‚·ãƒ¥ã®ã¿ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ãƒ‡ãƒ¼ã‚¿åž‹ã‚‚ã‚れã°ã€ã‚½ãƒ¼ãƒˆã®ã¿ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ã‚‚ã®ã‚‚ã‚りã¾ã™" +msgstr "一部ã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒãƒãƒƒã‚·ãƒ¥ã®ã¿ã‚’サãƒãƒ¼ãƒˆã™ã‚‹ä¸€æ–¹ã§ã€åˆ¥ã®åž‹ã¯ã‚½ãƒ¼ãƒˆã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã™ã€‚" -#: optimizer/plan/planner.c:2839 +#: optimizer/plan/planner.c:4803 #, c-format msgid "could not implement DISTINCT" -msgstr "DISTINCT を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "DISTINCTを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/plan/planner.c:3426 +#: optimizer/plan/planner.c:5486 #, c-format msgid "could not implement window PARTITION BY" -msgstr "ウィンドウ㮠PARTITION BY を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "ウィンドウ㮠PARTITION BY を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/plan/planner.c:3427 +#: optimizer/plan/planner.c:5487 #, c-format msgid "Window partitioning columns must be of sortable datatypes." -msgstr "ウィンドウ・パーティショニングã™ã‚‹ã‚«ãƒ©ãƒ ã¯ã€ã‚½ãƒ¼ãƒˆå¯èƒ½ãªãƒ‡ãƒ¼ã‚¿åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ウィンドウ分割ã«ä½¿ç”¨ã™ã‚‹åˆ—ã¯ã€ã‚½ãƒ¼ãƒˆå¯èƒ½ãªãƒ‡ãƒ¼ã‚¿åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: optimizer/plan/planner.c:3431 +#: optimizer/plan/planner.c:5491 #, c-format msgid "could not implement window ORDER BY" -msgstr "ウィンドウ㮠ORDER BY を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "ウィンドウ㮠ORDER BY を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/plan/planner.c:3432 +#: optimizer/plan/planner.c:5492 #, c-format msgid "Window ordering columns must be of sortable datatypes." -msgstr "ウィンドウã®é †åºä»˜ã‘ã‚’ã™ã‚‹ã‚«ãƒ©ãƒ ã¯ã€ã‚½ãƒ¼ãƒˆå¯èƒ½ãªãƒ‡ãƒ¼ã‚¿åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ウィンドウã®é †åºä»˜ã‘ã‚’ã™ã‚‹åˆ—ã¯ã€ã‚½ãƒ¼ãƒˆå¯èƒ½ãªãƒ‡ãƒ¼ã‚¿åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: optimizer/plan/setrefs.c:404 +#: optimizer/plan/setrefs.c:414 #, c-format msgid "too many range table entries" -msgstr "範囲テーブルã®é …ç›®ãŒå¤šã™ãŽã¾ã™" +msgstr "ãƒ¬ãƒ³ã‚¸ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ•°ãŒå¤šã™ãŽã¾ã™" -#: optimizer/prep/prepunion.c:418 +#: optimizer/prep/prepunion.c:544 #, c-format msgid "could not implement recursive UNION" -msgstr "å†å¸° UNION を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "å†å¸°UNIONを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/prep/prepunion.c:419 +#: optimizer/prep/prepunion.c:545 #, c-format msgid "All column datatypes must be hashable." -msgstr "ã™ã¹ã¦ã®ã‚«ãƒ©ãƒ ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯ãƒãƒƒã‚·ãƒ¥å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã™ã¹ã¦ã®åˆ—ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯ãƒãƒƒã‚·ãƒ¥å¯èƒ½ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:823 +#: optimizer/prep/prepunion.c:1079 #, c-format msgid "could not implement %s" -msgstr "%s を実装ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "%sを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: optimizer/util/clauses.c:4328 +#: optimizer/util/clauses.c:4895 #, c-format msgid "SQL function \"%s\" during inlining" -msgstr "SQL関数\"%s\"ãŒã‚¤ãƒ³ãƒ©ã‚¤ãƒ³ã«ãªã£ã¦ã„ã¾ã™" +msgstr "SQL関数\"%s\"ã®ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³åŒ–処ç†ä¸­" -#: optimizer/util/plancat.c:104 +#: optimizer/util/plancat.c:127 #, c-format msgid "cannot access temporary or unlogged relations during recovery" -msgstr "リカãƒãƒªä¸­ã¯ä¸€æ™‚テーブルや記録ã•れãªã„(unlogged)テーブルã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªä¸­ã¯ä¸€æ™‚テーブルやUNLOGGEDテーブルã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“" + +#: optimizer/util/plancat.c:651 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "è¡Œå…¨ä½“ã«æ¸¡ã‚‹ãƒ¦ãƒ‹ãƒ¼ã‚¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®æŽ¨å®šæŒ‡å®šã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/analyze.c:618 parser/analyze.c:1093 +#: optimizer/util/plancat.c:668 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ON CONFLICTå¥ä¸­ã®åˆ¶ç´„ã«ã¯é–¢é€£ä»˜ã‘られるインデックスãŒã‚りã¾ã›ã‚“" + +#: optimizer/util/plancat.c:719 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATEã§ã®æŽ’除制約ã®ä½¿ç”¨ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: optimizer/util/plancat.c:824 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "ON CONFLICT 指定ã«åˆè‡´ã™ã‚‹ãƒ¦ãƒ‹ãƒ¼ã‚¯åˆ¶ç´„ã¾ãŸã¯æŽ’除制約ãŒã‚りã¾ã›ã‚“" + +#: parser/analyze.c:709 parser/analyze.c:1414 #, c-format msgid "VALUES lists must all be the same length" msgstr "VALUESリストã¯ã™ã¹ã¦åŒã˜é•·ã•ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/analyze.c:785 +#: parser/analyze.c:919 #, c-format msgid "INSERT has more expressions than target columns" -msgstr "INSERTã«ã¦å¯¾è±¡åˆ—よりも多ãã®å¼ãŒã‚りã¾ã™" +msgstr "INSERTã«å¯¾è±¡åˆ—よりも多ãã®å¼ãŒã‚りã¾ã™" -#: parser/analyze.c:803 +#: parser/analyze.c:937 #, c-format msgid "INSERT has more target columns than expressions" -msgstr "INSERTã«ã¦å¼ã‚ˆã‚Šã‚‚多ãã®å¯¾è±¡åˆ—ãŒã‚りã¾ã™" +msgstr "INSERTã«å¼ã‚ˆã‚Šã‚‚多ãã®å¯¾è±¡åˆ—ãŒã‚りã¾ã™" -#: parser/analyze.c:807 +#: parser/analyze.c:941 #, c-format msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" -msgstr "挿入元ã®è¡Œè¡¨ç¾ã« INSERT ãŒæœŸå¾…ã™ã‚‹ã®ã¨åŒã˜åˆ—æ•°ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã†ã£ã‹ã‚Šä½™è¨ˆãªã‚«ãƒƒã‚³ã‚’ã¤ã‘ãŸã‚Šã—ã¾ã›ã‚“ã§ã—ãŸã‹ï¼Ÿ" +msgstr "挿入ソースãŒINSERTãŒæœŸå¾…ã™ã‚‹ã®ã¨åŒã˜åˆ—æ•°ã‚’å«ã‚€è¡Œè¡¨ç¾ã«ãªã£ã¦ã„ã¾ã™ã€‚ã†ã£ã‹ã‚Šä½™è¨ˆãªã‚«ãƒƒã‚³ã‚’ã¤ã‘ãŸã‚Šã—ã¾ã›ã‚“ã§ã—ãŸã‹ï¼Ÿ" -#: parser/analyze.c:915 parser/analyze.c:1294 +#: parser/analyze.c:1227 parser/analyze.c:1624 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "ã“ã“ã§ã¯SELECT ... INTOã¯è¨±ã•れã¾ã›ã‚“" -#: parser/analyze.c:1107 -#, c-format -msgid "DEFAULT can only appear in a VALUES list within INSERT" -msgstr "VALUESリスト内ã®DEFAULTã¯INSERTã®å ´åˆã®ã¿ä½¿ç”¨ã§ãã¾ã™" - #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1226 parser/analyze.c:2425 +#: parser/analyze.c:1556 parser/analyze.c:2858 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE cannot be applied to VALUES" msgid "%s cannot be applied to VALUES" msgstr "%sã‚’VALUESã«ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: parser/analyze.c:1447 +#: parser/analyze.c:1775 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" -msgstr "無効ãªUNION/INTERSECT/EXCEPT ORDER BYå¥ã§ã™" +msgstr "䏿­£ãªUNION/INTERSECT/EXCEPT ORDER BYå¥ã§ã™" -#: parser/analyze.c:1448 +#: parser/analyze.c:1776 #, c-format msgid "Only result column names can be used, not expressions or functions." -msgstr "å¼ã‚„関数ã§ã¯ãªãã€çµæžœåˆ—ã®åå‰ã®ã¿ãŒä½¿ç”¨ã•れã¾ã™ã€‚" +msgstr "å¼ã‚„関数ã§ã¯ãªãã€çµæžœåˆ—ã®åå‰ã®ã¿ãŒä½¿ç”¨ã§ãã¾ã™ã€‚" -#: parser/analyze.c:1449 +#: parser/analyze.c:1777 #, c-format msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." -msgstr "å¼/関数をã™ã¹ã¦ã®SELECTã«ã¤ã‘ã¦ãã ã•ã„。ã¾ãŸã¯UNIONã‚’FROMå¥ã«ç§»å‹•ã—ã¦ãã ã•ã„" +msgstr "å¼/関数をã™ã¹ã¦ã®SELECTã«ã¤ã‘ã¦ãã ã•ã„。ã¾ãŸã¯ã“ã®UNIONã‚’FROMå¥ã«ç§»å‹•ã—ã¦ãã ã•ã„。" -#: parser/analyze.c:1509 +#: parser/analyze.c:1838 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTOã¯UNION/INTERSECT/EXCEPTã®æœ€åˆã®SELECTã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: parser/analyze.c:1573 +#: parser/analyze.c:1910 #, c-format msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "UNION/INTERSECT/EXCEPTã®è¦ç´ ã¨ãªã‚‹æ–‡ã§ã¯åŒä¸€å•ã„åˆã‚ã›ãƒ¬ãƒ™ãƒ«ã®ä»–ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å‚ç…§ã§ãã¾ã›ã‚“" -#: parser/analyze.c:1662 +#: parser/analyze.c:1999 #, c-format msgid "each %s query must have the same number of columns" -msgstr "%så•ã„åˆã‚ã›ã¯ãれãžã‚ŒåŒã˜åˆ—æ•°ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ã™ã¹ã¦ã®%så•ã„åˆã‚ã›ã¯åŒã˜åˆ—æ•°ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" -#: parser/analyze.c:2054 +#: parser/analyze.c:2392 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNINGã«ã¯å°‘ãªãã¨ã‚‚1ã¤ã®åˆ—ãŒå¿…è¦ã§ã™" + +#: parser/analyze.c:2433 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" -msgstr "SCROLLã¨NO SCROLLã®ä¸¡æ–¹ã‚’指定ã§ãã¾ã›ã‚“" +msgstr "SCROLLã¨NO SCROLLã®ä¸¡æ–¹ã‚’åŒæ™‚ã«ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: parser/analyze.c:2072 +#: parser/analyze.c:2452 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" -msgstr "DECLARE CURSOR ã§ã¯ WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’å«ã‚“ã§ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "DECLARE CURSOR ã§ã¯ WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹æ–‡ã‚’å«ã‚“ã§ã¯ãªã‚Šã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2080 +#: parser/analyze.c:2460 #, c-format -#| msgid "DECLARE CURSOR WITH HOLD ... FOR UPDATE/SHARE is not supported" msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %sã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/analyze.c:2083 +#: parser/analyze.c:2463 #, c-format msgid "Holdable cursors must be READ ONLY." -msgstr "ä¿æŒå¯èƒ½ã‚«ãƒ¼ã‚½ãƒ«ã¯èª­ã¿å–りã®ã¿ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "ä¿æŒå¯èƒ½ã‚«ãƒ¼ã‚½ãƒ«ã¯èª­ã¿å–り専用ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2091 +#: parser/analyze.c:2471 #, c-format -#| msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %sã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2102 +#: parser/analyze.c:2482 #, c-format -#| msgid "DECLARE INSENSITIVE CURSOR ... FOR UPDATE/SHARE is not supported" msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %sã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/analyze.c:2105 +#: parser/analyze.c:2485 #, c-format msgid "Insensitive cursors must be READ ONLY." -msgstr "ç„¡å応カーソルã¯èª­ã¿å–りã®ã¿ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "INSENSITIVEカーソルã¯èª­ã¿å–り専用ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: parser/analyze.c:2171 +#: parser/analyze.c:2551 #, c-format -#| msgid "views must not contain data-modifying statements in WITH" msgid "materialized views must not use data-modifying statements in WITH" -msgstr "マテリアライズドビューã§ã¯ WITH å¥ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹æ–‡ã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "実体化ビューã§ã¯WITHå¥ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹æ–‡ã‚’å«ã‚“ã§ã¯ãªã‚Šã¾ã›ã‚“" -#: parser/analyze.c:2181 +#: parser/analyze.c:2561 #, c-format -#| msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgid "materialized views must not use temporary tables or views" -msgstr "マテリアライズドビューã§ã¯ä¸€æ™‚テーブルやビューを使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "実体化ビューã§ã¯ä¸€æ™‚テーブルやビューを使用ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: parser/analyze.c:2191 +#: parser/analyze.c:2571 #, c-format msgid "materialized views may not be defined using bound parameters" -msgstr "マテリアライズドビューã¯å¢ƒç•Œãƒ‘ラメータを用ã„ã¦å®šç¾©ã§ãã¾ã›ã‚“" +msgstr "実体化ビューã¯å¢ƒç•Œãƒ‘ラメータを用ã„ã¦å®šç¾©ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: parser/analyze.c:2203 +#: parser/analyze.c:2583 #, c-format -#| msgid "materialized view" msgid "materialized views cannot be UNLOGGED" -msgstr "マテリアライズドビューをUNLOGGEDã«ã¯ã§ãã¾ã›ã‚“" +msgstr "実体化ビューをUNLOGGEDã«ã¯ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2260 +#: parser/analyze.c:2686 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE is not allowed with DISTINCT clause" msgid "%s is not allowed with DISTINCT clause" msgstr "DISTINCTå¥ã§ã¯%sを使用ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2267 +#: parser/analyze.c:2693 #, c-format -#| msgid "aggregates not allowed in GROUP BY clause" msgid "%s is not allowed with GROUP BY clause" msgstr "GROUP BYå¥ã§%sを使用ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2274 +#: parser/analyze.c:2700 #, c-format -#| msgid "window functions not allowed in HAVING clause" msgid "%s is not allowed with HAVING clause" msgstr "HAVING å¥ã§ã¯%sを使用ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2281 +#: parser/analyze.c:2707 #, c-format -#| msgid "%s is not allowed in a SQL function" msgid "%s is not allowed with aggregate functions" -msgstr "集約関数ã§ã¯%sã¯è¨±ã•れã¾ã›ã‚“" +msgstr "集約関数ã§ã¯%sã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2288 +#: parser/analyze.c:2714 #, c-format -#| msgid "%s is not allowed in a SQL function" msgid "%s is not allowed with window functions" -msgstr "ウィンドウ関数ã§ã¯%sã¯è¨±ã•れã¾ã›ã‚“" +msgstr "ウィンドウ関数ã§ã¯%sã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2295 +#: parser/analyze.c:2721 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE is not allowed with set-returning functions in the target list" msgid "%s is not allowed with set-returning functions in the target list" -msgstr "ターゲットリストã®ä¸­ã§ã¯%sを集åˆã‚’è¿”ã™é–¢æ•°ã¨ä¸€ç·’ã«ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "ターゲットリストã®ä¸­ã§ã¯%sを集åˆè¿”å´é–¢æ•°ã¨ä¸€ç·’ã«ä½¿ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2374 +#: parser/analyze.c:2800 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE must specify unqualified relation names" msgid "%s must specify unqualified relation names" -msgstr "%sã§ã¯æœªä¿®é£¾ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³åを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "%sã§ã¯æœªä¿®é£¾ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³åを指定ã—ã¦ãã ã•ã„" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2407 +#: parser/analyze.c:2831 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE cannot be applied to a join" msgid "%s cannot be applied to a join" msgstr "%sã‚’çµåˆã«ä½¿ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2416 +#: parser/analyze.c:2840 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE cannot be applied to a function" msgid "%s cannot be applied to a function" msgstr "%sを関数ã«ä½¿ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2434 +#: parser/analyze.c:2849 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%sã¯ãƒ†ãƒ¼ãƒ–ル関数ã«ã¯é©ç”¨ã§ãã¾ã›ã‚“" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 #, c-format -#| msgid "SELECT FOR UPDATE/SHARE cannot be applied to a WITH query" msgid "%s cannot be applied to a WITH query" -msgstr "%s㯠WITHå•ã„åˆã‚ã›ã«ã¯é©ç”¨ã§ãã¾ã›ã‚“" +msgstr "%sã¯WITHå•ã„åˆã‚ã›ã«ã¯é©ç”¨ã§ãã¾ã›ã‚“" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%sã¯åå‰ä»˜ãタプルストアã«ã¯é©ç”¨ã§ãã¾ã›ã‚“" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2451 +#: parser/analyze.c:2893 #, c-format -#| msgid "relation \"%s\" in FOR UPDATE/SHARE clause not found in FROM clause" msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "%2$så¥ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%1$s\"ã¯FROMå¥ã«ã‚りã¾ã›ã‚“" -#: parser/parse_agg.c:144 parser/parse_oper.c:219 +#: parser/parse_agg.c:221 parser/parse_oper.c:222 #, c-format msgid "could not identify an ordering operator for type %s" msgstr "åž‹%sã®é †åºæ¼”ç®—å­ã‚’識別ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_agg.c:146 +#: parser/parse_agg.c:223 #, c-format msgid "Aggregates with DISTINCT must be able to sort their inputs." -msgstr "DISTINCT 付ãã®é›†ç´„関数ã¯ã€ãれã«å¯¾ã™ã‚‹å…¥åŠ›ã‚’ã‚½ãƒ¼ãƒˆã§ããªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "DISTINCT 付ãã®é›†ç´„関数ã¯ã€å…¥åŠ›ãŒã‚½ãƒ¼ãƒˆå¯èƒ½ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: parser/parse_agg.c:258 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPINGã®å¼•æ•°ã¯32より少ããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_agg.c:193 -#| msgid "aggregates not allowed in JOIN conditions" +#: parser/parse_agg.c:361 msgid "aggregate functions are not allowed in JOIN conditions" msgstr "JOINæ¡ä»¶ã§é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:199 -#| msgid "aggregate functions not allowed in a recursive query's recursive term" +#: parser/parse_agg.c:363 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "グルーピング演算ã¯JOINæ¡ä»¶ã®ä¸­ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:375 msgid "aggregate functions are not allowed in FROM clause of their own query level" -msgstr "集約関数ã¯è‡ªèº«ã®å•ã„åˆã‚ã›ãƒ¬ãƒ™ãƒ«ã®FROMå¥ã®ä¸­ã§ã¯è¨±ã•れã¾ã›ã‚“" +msgstr "集約関数ã¯è‡ªèº«ã®å•ã„åˆã‚ã›ãƒ¬ãƒ™ãƒ«ã®FROMå¥ã®ä¸­ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:377 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "グルーピング演算ã¯è‡ªèº«ã®ã‚¯ã‚¨ãƒªãƒ¬ãƒ™ãƒ«ã®FROMå¥ã®ä¸­ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:202 -#| msgid "cannot use aggregate function in function expression in FROM" +#: parser/parse_agg.c:382 msgid "aggregate functions are not allowed in functions in FROM" -msgstr "FROMå¥ã®é–¢æ•°ã®ä¸­ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "集約関数ã¯FROMå¥å†…ã®é–¢æ•°ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:384 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "グルーピング演算ã¯FROMå¥å†…ã®é–¢æ•°ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:392 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "集約関数ã¯ãƒãƒªã‚·å¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:220 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:394 +msgid "grouping operations are not allowed in policy expressions" +msgstr "グルーピング演算ã¯ãƒãƒªã‚·å¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:411 msgid "aggregate functions are not allowed in window RANGE" -msgstr "ウィンドウRANGEã®ä¸­ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "集約関数ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦RANGEã®ä¸­ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:223 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:413 +msgid "grouping operations are not allowed in window RANGE" +msgstr "ウィンドウ定義ã®RANGEå¥ã®ä¸­ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:418 msgid "aggregate functions are not allowed in window ROWS" -msgstr "ウィンドウROWSã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "ウィンドウ定義ã®ROWSå¥ã§ã¯é›†ç´„関数ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:420 +msgid "grouping operations are not allowed in window ROWS" +msgstr "ウィンドウ定義ã®ROWSå¥ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:254 -#| msgid "cannot use aggregate function in check constraint" +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "ウィンドウ定義ã®GROUPSå¥ã§ã¯é›†ç´„関数ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "ウィンドウ定義ã®GROUPSå¥ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:461 msgid "aggregate functions are not allowed in check constraints" -msgstr "ãƒã‚§ãƒƒã‚¯åˆ¶ç´„ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "検査制約ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:258 -#| msgid "aggregate functions not allowed in a recursive query's recursive term" +#: parser/parse_agg.c:463 +msgid "grouping operations are not allowed in check constraints" +msgstr "検査制約ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:470 msgid "aggregate functions are not allowed in DEFAULT expressions" -msgstr "DEFAULTå¼ã®ä¸­ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "DEFAULTå¼ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:261 -#| msgid "cannot use aggregate function in index expression" +#: parser/parse_agg.c:472 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "DEFAULTå¼ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:477 msgid "aggregate functions are not allowed in index expressions" -msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã«ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "インデックスå¼ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:479 +msgid "grouping operations are not allowed in index expressions" +msgstr "インデックスå¼ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:264 -#| msgid "aggregate functions not allowed in a recursive query's recursive term" +#: parser/parse_agg.c:484 msgid "aggregate functions are not allowed in index predicates" -msgstr "インデックスã®è¿°éƒ¨ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "インデックス述語ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:267 -#| msgid "cannot use aggregate function in transform expression" +#: parser/parse_agg.c:486 +msgid "grouping operations are not allowed in index predicates" +msgstr "インデックス述語ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:491 msgid "aggregate functions are not allowed in transform expressions" msgstr "変æ›å¼ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:270 -#| msgid "cannot use aggregate function in EXECUTE parameter" +#: parser/parse_agg.c:493 +msgid "grouping operations are not allowed in transform expressions" +msgstr "変æ›å¼ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:498 msgid "aggregate functions are not allowed in EXECUTE parameters" -msgstr "EXECUTEã®ãƒ‘ラメータã«é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "EXECUTEã®ãƒ‘ラメータã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:500 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "EXECUTEã®ãƒ‘ラメータã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:273 -#| msgid "cannot use aggregate function in trigger WHEN condition" +#: parser/parse_agg.c:505 msgid "aggregate functions are not allowed in trigger WHEN conditions" -msgstr "トリガー㮠WHEN æ¡ä»¶ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "トリガã®WHENæ¡ä»¶ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:507 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "トリガã®WHENæ¡ä»¶ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "パーティションキーå¼ã§ã¯é›†ç´„関数ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "パーティションキーå¼ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "CALLã®å¼•æ•°ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALLã®å¼•æ•°ã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:293 parser/parse_clause.c:1285 +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 #, c-format -#| msgid "aggregate function calls cannot be nested" msgid "aggregate functions are not allowed in %s" -msgstr "%sã®ä¸­ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "%sã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:548 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "%sã§ã¯ã‚°ãƒ«ãƒ¼ãƒ”ング演算を使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:656 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "アウタレベルã®é›†ç´„ã¯ç›´æŽ¥å¼•æ•°ã«ä½Žä½ã®å¤‰æ•°ã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:735 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "集åˆè¿”å´é–¢æ•°ã®å‘¼ã³å‡ºã—ã«é›†ç´„関数ã®å‘¼ã³å‡ºã—ã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 +#: parser/parse_func.c:866 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "ã“ã®é›†åˆè¿”å´é–¢æ•°ã‚’LATERAL FROMé …ç›®ã«ç§»å‹•ã§ãã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: parser/parse_agg.c:403 +#: parser/parse_agg.c:741 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "集約関数ã®å‘¼ã³å‡ºã—ã«ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã®å‘¼ã³å‡ºã—ã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:476 -#| msgid "window functions not allowed in JOIN conditions" +#: parser/parse_agg.c:820 msgid "window functions are not allowed in JOIN conditions" msgstr "JOINæ¡ä»¶ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:483 -#| msgid "window functions not allowed in JOIN conditions" +#: parser/parse_agg.c:827 msgid "window functions are not allowed in functions in FROM" msgstr "FROMå¥å†…ã®é–¢æ•°ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:498 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:833 +msgid "window functions are not allowed in policy expressions" +msgstr "ãƒãƒªã‚·å¼ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:846 msgid "window functions are not allowed in window definitions" -msgstr "ウィンドウ定義ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +msgstr "ウィンドウ定義ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:529 -#| msgid "window functions not allowed in JOIN conditions" +#: parser/parse_agg.c:878 msgid "window functions are not allowed in check constraints" msgstr "検査制約ã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:533 -#| msgid "window functions not allowed in JOIN conditions" +#: parser/parse_agg.c:882 msgid "window functions are not allowed in DEFAULT expressions" msgstr "DEFAULTå¼ã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:536 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:885 msgid "window functions are not allowed in index expressions" -msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +msgstr "インデックスå¼ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:539 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:888 msgid "window functions are not allowed in index predicates" -msgstr "インデックスã®è¿°éƒ¨ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +msgstr "インデックス述語ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:542 -#| msgid "window functions not allowed in window definition" +#: parser/parse_agg.c:891 msgid "window functions are not allowed in transform expressions" msgstr "変æ›å¼ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:545 -#| msgid "window functions not allowed in WHERE clause" +#: parser/parse_agg.c:894 msgid "window functions are not allowed in EXECUTE parameters" msgstr "EXECUTEパラメータã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:548 -#| msgid "window functions not allowed in JOIN conditions" +#: parser/parse_agg.c:897 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "トリガã®WHENæ¡ä»¶ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "パーティションキーå¼ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "CALLã®å¼•æ•°ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:568 parser/parse_clause.c:1294 +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 #, c-format -#| msgid "window functions not allowed in WHERE clause" msgid "window functions are not allowed in %s" msgstr "%sã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:602 parser/parse_clause.c:1705 +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 #, c-format msgid "window \"%s\" does not exist" -msgstr "ウィンドウ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "ウィンドウ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: parser/parse_agg.c:1042 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "ã‚°ãƒ«ãƒ¼ãƒ”ãƒ³ã‚°ã‚»ãƒƒãƒˆã®æ•°ãŒå¤šã™ãŽã¾ã™ (最大4096)" -#: parser/parse_agg.c:764 +#: parser/parse_agg.c:1191 #, c-format -#| msgid "aggregate functions not allowed in a recursive query's recursive term" msgid "aggregate functions are not allowed in a recursive query's recursive term" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼ã®å†å¸°é …目中ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›ã®å†å¸°é …ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" -#: parser/parse_agg.c:918 +#: parser/parse_agg.c:1384 #, c-format msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" -msgstr "列\"%s.%s\"ã¯GROUP BYå¥ã§å‡ºç¾ã—ãªã‘れã°ãªã‚‰ãªã„ã‹ã€é›†ç´„関数内ã§ä½¿ç”¨ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "列\"%s.%s\"ã¯GROUP BYå¥ã§æŒ‡å®šã™ã‚‹ã‹ã€é›†ç´„関数内ã§ä½¿ç”¨ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_agg.c:924 +#: parser/parse_agg.c:1387 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "é †åºé›†åˆé›†ç´„ã®ç›´æŽ¥å¼•æ•°ã¯ã‚°ãƒ«ãƒ¼ãƒ”ングã•れãŸåˆ—ã®ã¿ã‚’使用ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: parser/parse_agg.c:1392 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "外部å•ã„åˆã‚ã›ã‹ã‚‰å‰¯å•ã„åˆã‚ã›ãŒã‚°ãƒ«ãƒ¼ãƒ—化ã•れã¦ã„ãªã„列\"%s.%s\"を使用ã—ã¦ã„ã¾ã™" -#: parser/parse_clause.c:845 +#: parser/parse_agg.c:1556 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "GROUPINGã®å¼•æ•°ã¯é–¢é€£ã™ã‚‹ã‚¯ã‚¨ãƒªãƒ¬ãƒ™ãƒ«ã®ã‚°ãƒ«ãƒ¼ãƒ”ングå¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_clause.c:199 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "リレーション\"%s\"ã¯æ›´æ–°æ–‡ã®å¯¾è±¡ã«ã¯ãªã‚Œã¾ã›ã‚“" + +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "集åˆè¿”å´é–¢æ•°ã¯FROMã®æœ€ä¸Šä½ãƒ¬ãƒ™ãƒ«ã«ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: parser/parse_clause.c:655 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "åŒã˜é–¢æ•°ã«å¯¾ã—ã¦è¤‡æ•°ã®åˆ—定義リストをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:688 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "複数ã®é–¢æ•°ã‚’ä¼´ã£ãŸ ROWS FROM() ã¯åˆ—定義リストをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:689 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "ROWS FROM() 内ã®ãれãžã‚Œã®é–¢æ•°ã”ã¨ã«å€‹åˆ¥ã®åˆ—定義リストを付ã‘ã¦ãã ã•ã„。" + +#: parser/parse_clause.c:695 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "複数ã®å¼•æ•°ã‚’ã‚‚ã¤UNNEST()ã¯åˆ—定義リストをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:696 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "ROWS FROM() ã®ä¸­ã§å€‹åˆ¥ã« UNNEST() をコールã—ã¦ã€åˆ—定義リストをãれãžã‚Œã«ä»˜åŠ ã—ã¦ãã ã•ã„。" + +#: parser/parse_clause.c:703 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY ã¯åˆ—定義リストãŒã‚ã‚‹ã¨ãã¯ä½¿ãˆã¾ã›ã‚“" + +#: parser/parse_clause.c:704 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "ROWS FROM() ã®ä¸­ã«åˆ—定義リストをãŠã„ã¦ãã ã•ã„。" + +#: parser/parse_clause.c:807 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "FOR ORDINALITY 列ã¯ä¸€ã¤ã¾ã§ã§ã™" + +#: parser/parse_clause.c:868 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "列å\"%s\"ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" + +#: parser/parse_clause.c:910 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "åå‰ç©ºé–“å\"%s\"ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" + +#: parser/parse_clause.c:920 +#, c-format +msgid "only one default namespace is allowed" +msgstr "デフォルトåå‰ç©ºé–“ã¯ä¸€ã¤ã—ã‹è¨±ã•れã¾ã›ã‚“" + +#: parser/parse_clause.c:982 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "テーブルサンプルメソッド%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: parser/parse_clause.c:1004 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "テーブルサンプルメソッド%sã¯%d個ã®å¼•æ•°ã‚’å¿…è¦ã¨ã—ã¾ã™ã€%d個ã§ã¯ã‚りã¾ã›ã‚“" +msgstr[1] "テーブルサンプルメソッド%sã¯%d個ã®å¼•æ•°ã‚’å¿…è¦ã¨ã—ã¾ã™ã€%d個ã§ã¯ã‚りã¾ã›ã‚“" + +#: parser/parse_clause.c:1038 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "テーブルサンプルメソッド%sã¯REPEATABLEをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: parser/parse_clause.c:1208 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLEå¥ã¯ãƒ†ãƒ¼ãƒ–ルãŠã‚ˆã³å®Ÿä½“化ビューã®ã¿ã«é©ç”¨å¯èƒ½ã§ã™" + +#: parser/parse_clause.c:1378 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "USINGå¥ã«åˆ—å\"%s\"ãŒè¤‡æ•°ã‚りã¾ã™" -#: parser/parse_clause.c:860 +#: parser/parse_clause.c:1393 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "左テーブルã«åˆ—å\"%s\"ãŒè¤‡æ•°ã‚りã¾ã™" -#: parser/parse_clause.c:869 +#: parser/parse_clause.c:1402 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "USINGå¥ã§æŒ‡å®šã—ãŸåˆ—\"%sãŒå·¦ãƒ†ãƒ¼ãƒ–ルã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_clause.c:883 +#: parser/parse_clause.c:1416 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "å³ãƒ†ãƒ¼ãƒ–ルã«åˆ—å\"%s\"ãŒè¤‡æ•°ã‚りã¾ã™" -#: parser/parse_clause.c:892 +#: parser/parse_clause.c:1425 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "USINGå¥ã§æŒ‡å®šã—ãŸåˆ—\"%sãŒå³ãƒ†ãƒ¼ãƒ–ルã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_clause.c:946 +#: parser/parse_clause.c:1479 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "列\"%s\"ã®åˆ¥åリストã®ã‚¨ãƒ³ãƒˆãƒªãŒå¤šã™ãŽã¾ã™" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1255 +#: parser/parse_clause.c:1788 #, c-format msgid "argument of %s must not contain variables" msgstr "%sã®å¼•æ•°ã«ã¯å¤‰æ•°ã‚’使用ã§ãã¾ã›ã‚“" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1420 +#: parser/parse_clause.c:1953 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s \"%s\"ã¯æ›–昧ã§ã™" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1449 +#: parser/parse_clause.c:1982 #, c-format msgid "non-integer constant in %s" msgstr "%sã«æ•´æ•°ä»¥å¤–ã®å®šæ•°ãŒã‚りã¾ã™" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1471 +#: parser/parse_clause.c:2004 #, c-format msgid "%s position %d is not in select list" msgstr "%sã®ä½ç½®%dã¯SELECTリストã«ã‚りã¾ã›ã‚“" -#: parser/parse_clause.c:1693 +#: parser/parse_clause.c:2445 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBEã¯12è¦ç´ ã«åˆ¶é™ã•れã¦ã„ã¾ã™" + +#: parser/parse_clause.c:2651 #, c-format msgid "window \"%s\" is already defined" msgstr "ウィンドウ \"%s\" ã¯ã™ã§ã«å®šç¾©æ¸ˆã¿ã§ã™" -#: parser/parse_clause.c:1749 +#: parser/parse_clause.c:2712 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "ウィンドウ \"%s\" ã® PARTITION BY å¥ã‚’オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã§ãã¾ã›ã‚“" -#: parser/parse_clause.c:1761 +#: parser/parse_clause.c:2724 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "ウィンドウ \"%s\" ã® ORDER BY å¥ã‚’オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã§ãã¾ã›ã‚“" -#: parser/parse_clause.c:1783 +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "フレームå¥ã‚’ã‚‚ã£ã¦ã„ã‚‹ãŸã‚ã€ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦\"%s\"ã¯ã‚³ãƒ”ーã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:2762 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "ã“ã®OVERå¥ä¸­ã®æ‹¬å¼§ã‚’無視ã—ã¾ã—ãŸ" + +#: parser/parse_clause.c:2782 #, c-format -msgid "cannot override frame clause of window \"%s\"" -msgstr "ウィンドウ \"%s\" ã®æ§‹æˆå¥ã‚’オーãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã§ãã¾ã›ã‚“" +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "offset PRECEDING/FOLLOWING ã‚’ä¼´ã£ãŸ RANGE ã¯ãŸã ä¸€ã¤ã® ORDER BY 列を必è¦ã¨ã—ã¾ã™" -#: parser/parse_clause.c:1849 +#: parser/parse_clause.c:2805 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPSフレーム指定ã¯ORDER BYå¥ã‚’å¿…è¦ã¨ã—ã¾ã™" + +#: parser/parse_clause.c:2875 #, c-format msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" msgstr "DISTINCT ã‚„ ORDER BY 表ç¾ã‚’ä¼´ãªã†é›†ç´„ã¯å¼•数リストã®ä¸­ã«ç¾ã‚Œãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_clause.c:1850 +#: parser/parse_clause.c:2876 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "SELECT DISTINCTã§ã¯ORDER BYã®å¼ã¯SELECTリスト内ã«ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_clause.c:1936 parser/parse_clause.c:1968 +#: parser/parse_clause.c:2908 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "DISTINCTã‚’ä¼´ã£ãŸé›†ç´„ã¯ã€æœ€ä½Žã§ã‚‚一ã¤ã®å¼•æ•°ã‚’å–ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: parser/parse_clause.c:2909 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCTã«ã¯å°‘ãªãã¨ã‚‚1ã¤ã®åˆ—ãŒå¿…è¦ã§ã™" + +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "SELECT DISTINCT ONã®å¼ã¯ORDER BYå¼ã®å…ˆé ­ã«ä¸€è‡´ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_clause.c:2090 +#: parser/parse_clause.c:3085 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESCã¯ON CONFLICTå¥ã§ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:3091 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LASTã¯ON CONFLICTå¥ã§ã¯æŒ‡å®šã§ãã¾ã›ã‚“" + +#: parser/parse_clause.c:3170 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE ã¯æŽ¨å®šæŒ‡å®šã¾ãŸã¯åˆ¶ç´„åã‚’å¿…è¦ã¨ã—ã¾ã™" + +#: parser/parse_clause.c:3171 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "例ãˆã°ã€ ON CONFLICT (column_name)。" + +#: parser/parse_clause.c:3182 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "システムカタログテーブルã§ã¯ON CONFLICTã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT ã¯ã‚«ã‚¿ãƒ­ã‚°ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ä½¿ç”¨ä¸­ã®ãƒ†ãƒ¼ãƒ–ル\"%s\"ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: parser/parse_clause.c:3333 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "演算å­\"%s\"ã¯æœ‰åйãªé †åºä»˜ã‘演算å­åã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_clause.c:2092 +#: parser/parse_clause.c:3335 #, c-format msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "é †åºä»˜ã‘演算å­ã¯B-Treeæ¼”ç®—å­æ—ã®\"<\"ã¾ãŸã¯\">\"è¦ç´ ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: parser/parse_coerce.c:933 parser/parse_coerce.c:963 -#: parser/parse_coerce.c:981 parser/parse_coerce.c:996 -#: parser/parse_expr.c:1770 parser/parse_expr.c:2244 parser/parse_target.c:852 +#: parser/parse_clause.c:3646 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "offset PRECEDING/FOLLOWING ã‚’ä¼´ã£ãŸ RANGE ã¯åˆ—åž‹ %s ã«å¯¾ã—ã¦ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "offset PRECEDING/FOLLOWING ã‚’ä¼´ã£ãŸ RANGE ã¯åˆ—åž‹ %s ã¨ã‚ªãƒ•セット型 %s ã«å¯¾ã—ã¦ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "オフセット値をé©åˆ‡ãªåž‹ã«ã‚­ãƒ£ã‚¹ãƒˆã—ã¦ãã ã•ã„。" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "offset PRECEDING/FOLLOWING ã‚’ä¼´ã£ãŸ RANGE ã¯åˆ—åž‹ %s ã¨ã‚ªãƒ•セット型 %s ã«å¯¾ã—ã¦è¤‡æ•°ã®è§£é‡ˆãŒå¯èƒ½ã«ãªã£ã¦ã„ã¾ã™" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "オフセット値をæ„図ã—ãŸåž‹ãã®ã‚‚ã®ã«ã‚­ãƒ£ã‚¹ãƒˆã—ã¦ãã ã•ã„。" + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:961 #, c-format msgid "cannot cast type %s to %s" -msgstr "åž‹%sã‹ã‚‰%sã¸ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" +msgstr "åž‹%sã‹ã‚‰%sã¸ã®åž‹å¤‰æ›ãŒã§ãã¾ã›ã‚“" -#: parser/parse_coerce.c:966 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." -msgstr "入力列ãŒå°‘ãªã™ãŽã¾ã™" +msgstr "入力列ãŒå°‘ãªã™ãŽã¾ã™ã€‚" -#: parser/parse_coerce.c:984 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." -msgstr "列%3$dã«ã¦åž‹%1$sã‹ã‚‰%2$sã¸ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" +msgstr "列%3$dã§åž‹%1$sã‹ã‚‰%2$sã¸ã®åž‹å¤‰æ›ãŒã§ãã¾ã›ã‚“。" -#: parser/parse_coerce.c:999 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." -msgstr "入力列ãŒå¤šã™ãŽã¾ã™" +msgstr "入力列ãŒå¤šã™ãŽã¾ã™ã€‚" #. translator: first %s is name of a SQL construct, eg WHERE -#: parser/parse_coerce.c:1042 +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format -msgid "argument of %s must be type boolean, not type %s" -msgstr "%s ã®å¼•数㯠%s åž‹ã§ã¯ãªãブール型ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "argument of %s must be type %s, not type %s" +msgstr "%1$sã®å¼•æ•°ã¯åž‹%3$sã§ã¯ãªã%2$såž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1052 parser/parse_coerce.c:1101 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "%sã®å¼•æ•°ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1089 -#, c-format -msgid "argument of %s must be type %s, not type %s" -msgstr "%1$sã®å¼•æ•°ã¯åž‹%3$sã§ã¯ãªã%2$såž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1222 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "%sã®åž‹%sã¨%sを一致ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1289 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "%sã§åž‹%sã‹ã‚‰%sã¸å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_coerce.c:1591 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "\"anyelement\"ã¨å®£è¨€ã•れãŸå¼•æ•°ãŒå…¨ã¦åŒã˜ã§ã‚りã¾ã›ã‚“" -#: parser/parse_coerce.c:1611 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "\"anyarray\"ã¨å®£è¨€ã•れãŸå¼•æ•°ãŒå…¨ã¦åŒã˜ã§ã‚りã¾ã›ã‚“" -#: parser/parse_coerce.c:1631 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "\"anyrange\"ã¨å®£è¨€ã•れãŸå¼•æ•°ãŒå…¨ã¦åŒã˜ã§ã‚りã¾ã›ã‚“" -#: parser/parse_coerce.c:1660 parser/parse_coerce.c:1871 -#: parser/parse_coerce.c:1905 +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 #, c-format -msgid "argument declared \"anyarray\" is not an array but type %s" -msgstr "\"anyarray\"ã¨å®£è¨€ã•れãŸå¼•æ•°ãŒé…列ã§ãªãåž‹%sã§ã—ãŸ" +msgid "argument declared %s is not an array but type %s" +msgstr "%sã¨å®£è¨€ã•れãŸå¼•æ•°ãŒé…列ã§ã¯ãªã%såž‹ã§ã™" -#: parser/parse_coerce.c:1676 +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 #, c-format -msgid "argument declared \"anyarray\" is not consistent with argument declared \"anyelement\"" -msgstr "\"anyarray\"ã¨å®£è¨€ã•れãŸå¼•æ•°ã¨\"anyelement\"ã¨å®£è¨€ã•れãŸå¼•æ•°ã¨ã§æ•´åˆæ€§ãŒã‚りã¾ã›ã‚“" +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "%sã¨å®£è¨€ã•れãŸå¼•æ•°ã¨%sã¨å®£è¨€ã•れãŸå¼•æ•°ã¨ã§æ•´åˆæ€§ãŒã‚りã¾ã›ã‚“" -#: parser/parse_coerce.c:1697 parser/parse_coerce.c:1918 +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 #, c-format -#| msgid "argument declared \"anyrange\" is not a range but type %s" -msgid "argument declared \"anyrange\" is not a range type but type %s" -msgstr "\"anyrange\"ã¨å®£è¨€ã•れãŸå¼•æ•°ãŒç¯„囲型ã§ã¯ãªãåž‹%sã§ã—ãŸ" +msgid "argument declared %s is not a range type but type %s" +msgstr "%sã¨å®£è¨€ã•れãŸå¼•æ•°ãŒç¯„囲型ã§ã¯ãªãåž‹%sã§ã™" -#: parser/parse_coerce.c:1713 +#: parser/parse_coerce.c:1865 #, c-format -msgid "argument declared \"anyrange\" is not consistent with argument declared \"anyelement\"" -msgstr "\"anyrange\"ã¨å®£è¨€ã•れãŸå¼•æ•°ã¨\"anyelement\"ã¨å®£è¨€ã•れãŸå¼•æ•°ã¨ã§æ•´åˆæ€§ãŒã‚りã¾ã›ã‚“" +msgid "could not determine polymorphic type because input has type %s" +msgstr "入力型ãŒ%sã§ã‚ã£ãŸãŸã‚多様型ã®ç¢ºå®šãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_coerce.c:1733 -#, c-format -msgid "could not determine polymorphic type because input has type \"unknown\"" -msgstr "入力型ãŒ\"unknown\"ã§ã‚ã£ãŸãŸã‚多様型を決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: parser/parse_coerce.c:1743 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" -msgstr "anynonarrayã¨åˆã†åž‹ã¯é…列型ã§ã™: %s" +msgstr "anynonarrayã¨ç…§åˆã•れãŸã¯é…列型ã§ã™: %s" -#: parser/parse_coerce.c:1753 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" -msgstr "anyenumã«åˆã†åž‹ã¯åˆ—挙型ã§ã¯ã‚りã¾ã›ã‚“: %s" +msgstr "anyenumã¨ç…§åˆã•れãŸåž‹ã¯åˆ—挙型ã§ã¯ã‚りã¾ã›ã‚“: %s" -#: parser/parse_coerce.c:1793 parser/parse_coerce.c:1823 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "データ型%sã®ç¯„囲型ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_collate.c:214 parser/parse_collate.c:458 +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 #, c-format msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" msgstr "æš—é»™ã®ç…§åˆé †åº \"%s\" 㨠\"%s\" ã®é–“ã«ç…§åˆé †åºã®ãƒŸã‚¹ãƒžãƒƒãƒãŒã‚りã¾ã™" -#: parser/parse_collate.c:217 parser/parse_collate.c:461 +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 #, c-format msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." msgstr "片方もã—ãã¯ä¸¡æ–¹ã®å¼ã«å¯¾ã—㦠COLLATE å¥ã‚’é©ç”¨ã™ã‚‹ã“ã¨ã§ç…§åˆé †åºã‚’é¸æŠžã§ãã¾ã™" -#: parser/parse_collate.c:794 +#: parser/parse_collate.c:831 #, c-format msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" msgstr "明示的ãªç…§åˆé †åº \"%s\" 㨠\"%s\" ã®é–“ã«ç…§åˆé †åºã®ãƒŸã‚¹ãƒžãƒƒãƒãŒã‚りã¾ã™" @@ -11286,32 +14971,32 @@ msgstr "明示的ãªç…§åˆé †åº \"%s\" 㨠\"%s\" ã®é–“ã«ç…§åˆé †åºã®ãƒŸ #: parser/parse_cte.c:42 #, c-format msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°çš„å‚ç…§ãŒã€ãã®éžå†å¸°é …目内ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›\"%s\"ã¸ã®å†å¸°çš„å‚ç…§ãŒã€ãã®éžå†å¸°é …内ã«ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_cte.c:44 #, c-format msgid "recursive reference to query \"%s\" must not appear within a subquery" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°çš„å‚ç…§ãŒã€å‰¯å•ã„åˆã‚ã›å†…ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›\"%s\"ã¸ã®å†å¸°çš„å‚ç…§ãŒã€å‰¯å•ã„åˆã‚ã›å†…ã«ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_cte.c:46 #, c-format msgid "recursive reference to query \"%s\" must not appear within an outer join" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°çš„å‚ç…§ãŒã€å¤–部çµåˆå†…ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›\"%s\"ã¸ã®å†å¸°çš„å‚ç…§ãŒã€å¤–部çµåˆå†…ã«ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_cte.c:48 #, c-format msgid "recursive reference to query \"%s\" must not appear within INTERSECT" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°çš„å‚ç…§ãŒã€INTERSECT 内ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›\"%s\"ã¸ã®å†å¸°çš„å‚ç…§ãŒã€INTERSECT内ã«ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_cte.c:50 #, c-format msgid "recursive reference to query \"%s\" must not appear within EXCEPT" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°çš„å‚ç…§ãŒã€EXCEPT 内ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›\"%s\"ã¸ã®å†å¸°çš„å‚ç…§ãŒã€EXCEPT内ã§ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_cte.c:132 #, c-format msgid "WITH query name \"%s\" specified more than once" -msgstr "WITH クエリーå \"%s\" ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¾ã—ãŸ" +msgstr "WITH å•ã„åˆã‚ã›å \"%s\" ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¾ã—ãŸ" #: parser/parse_cte.c:264 #, c-format @@ -11321,886 +15006,1209 @@ msgstr "データを変更ã™ã‚‹ã‚ˆã†ãªã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’å«ã‚€ WITH å¥ #: parser/parse_cte.c:313 #, c-format msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼ \"%s\" ã® %d 個目ã®ã‚«ãƒ©ãƒ ãŒéžå†å¸°é …目内㧠%s åž‹ã«ãªã£ã¦ã„ã¾ã™ãŒã€å…¨ä½“çš„ã«ã¯ %s åž‹ã«ãªã£ã¦ã„ã¾ã™" +msgstr "å†å¸°å•ã„åˆã‚ã›\"%s\"ã®åˆ—%dã®åž‹ã¯ã€éžå†å¸°é …ã®å†…ã§ã¯%sã«ãªã£ã¦ã„ã¾ã™ãŒå…¨ä½“ã¨ã—ã¦ã¯%sã§ã™" #: parser/parse_cte.c:319 #, c-format msgid "Cast the output of the non-recursive term to the correct type." -msgstr "éžå†å¸°é …ç›®ã®å‡ºåŠ›ã‚’æ­£ã—ã„åž‹ã«ã‚­ãƒ£ã‚¹ãƒˆã—ã¦ãã ã•ã„" +msgstr "éžå†å¸°é …ã®å‡ºåŠ›ã‚’æ­£ã—ã„åž‹ã«å¤‰æ›ã—ã¦ãã ã•ã„。" #: parser/parse_cte.c:324 #, c-format msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼ \"%s\" ã® %d 個目ã®åˆ—ãŒéžå†å¸°è¡¨ç¾ã«ãŠã„ã¦ç…§åˆé †åº \"%s\" ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™ãŒã€å…¨ä½“ã®ç…§åˆé †åºãŒ \"%s\" ã§ã™ã€‚" +msgstr "å†å¸°å•ã„åˆã‚ã›\"%s\"ã®åˆ—%dã®ç…§åˆé †åºã¯ã€éžå†å¸°é …ã§ã¯\"%s\"ã§ã™ãŒå…¨ä½“ã¨ã—ã¦ã¯\"%s\"ã§ã™" #: parser/parse_cte.c:328 #, c-format msgid "Use the COLLATE clause to set the collation of the non-recursive term." -msgstr "éžå†å¸°é …ç›®ã®ç…§åˆé †åºã‚’設定ã™ã‚‹ã«ã¯ COLLATE å¥ã‚’使ã£ã¦ãã ã•ã„" +msgstr "COLLATEå¥ã‚’使ã£ã¦éžå†å¸°é …ã®ç…§åˆé †åºã‚’設定ã—ã¦ãã ã•ã„。" -#: parser/parse_cte.c:419 +#: parser/parse_cte.c:418 #, c-format msgid "WITH query \"%s\" has %d columns available but %d columns specified" -msgstr "WITH クエリー \"%s\" ã§ã¯ %d 個ã®ã‚«ãƒ©ãƒ ãŒä½¿ç”¨ã§ãã¾ã™ãŒã€%d 個ã®ã‚«ãƒ©ãƒ ãŒæŒ‡å®šã•れã¾ã—ãŸ" +msgstr "WITHå•ã„åˆã‚ã›\"%s\"ã«ã¯%d列ã—ã‹ã‚りã¾ã›ã‚“ãŒã€%d列指定ã•れã¦ã„ã¾ã™" -#: parser/parse_cte.c:599 +#: parser/parse_cte.c:598 #, c-format msgid "mutual recursion between WITH items is not implemented" -msgstr "WITH 項目間åŒå£«ã®å†å¸°ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgstr "WITH項目間ã®å†å¸°ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:651 +#: parser/parse_cte.c:650 #, c-format msgid "recursive query \"%s\" must not contain data-modifying statements" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼ \"%s\" ã¯ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’å«ã‚“ã§ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›\"%s\"ã¯ãƒ‡ãƒ¼ã‚¿ã‚’æ›´æ–°ã™ã‚‹ã‚¹æ–‡ã‚’å«ã‚“ã§ã„ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: parser/parse_cte.c:659 +#: parser/parse_cte.c:658 #, c-format msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼ \"%s\" ã« éžå†å¸°é …ç›® UNION [ALL] å†å¸°é …ç›® ãŒã‚りã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›\"%s\"ãŒã€<éžå†å¸°é …> UNION [ALL] <å†å¸°é …> ã®å½¢å¼ã«ãªã£ã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:703 +#: parser/parse_cte.c:702 #, c-format msgid "ORDER BY in a recursive query is not implemented" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼å†…ã® ORDER BY ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›å†…ã® ORDER BY ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:709 +#: parser/parse_cte.c:708 #, c-format msgid "OFFSET in a recursive query is not implemented" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼å†…ã® OFFSET ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›å†…ã® OFFSET ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:715 +#: parser/parse_cte.c:714 #, c-format msgid "LIMIT in a recursive query is not implemented" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼å†…ã® LIMIT ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›å†…ã® LIMIT ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:721 +#: parser/parse_cte.c:720 #, c-format msgid "FOR UPDATE/SHARE in a recursive query is not implemented" -msgstr "å†å¸°ã‚¯ã‚¨ãƒªãƒ¼å†…ã® FOR UPDATE/SHARE ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgstr "å†å¸°å•ã„åˆã‚ã›å†…ã® FOR UPDATE/SHARE ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_cte.c:778 +#: parser/parse_cte.c:777 #, c-format msgid "recursive reference to query \"%s\" must not appear more than once" -msgstr "クエリー \"%s\" ã¸ã®å†å¸°å‚ç…§ãŒï¼’回以上ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã› \"%s\" ã¸ã®å†å¸°å‚ç…§ãŒ2回以上ç¾ã‚Œã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_expr.c:350 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "ã“ã®æ–‡è„ˆã§ã¯DEFAULTã¯ä½¿ãˆã¾ã›ã‚“" -#: parser/parse_expr.c:389 parser/parse_relation.c:2726 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 +#: parser/parse_relation.c:3307 #, c-format msgid "column %s.%s does not exist" msgstr "列%s.%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_expr.c:401 +#: parser/parse_expr.c:415 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "データ型%2$sã®åˆ—\"%1$s\"ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_expr.c:407 +#: parser/parse_expr.c:421 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "レコードデータ型ã®åˆ—\"%s\"を識別ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_expr.c:413 +#: parser/parse_expr.c:427 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "列記法 .%sãŒåž‹%sã«ä½¿ç”¨ã•れã¾ã—ãŸãŒã€ã“ã®åž‹ã¯è¤‡åˆåž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_expr.c:443 parser/parse_target.c:640 +#: parser/parse_expr.c:458 parser/parse_target.c:728 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "\"*\" を通ã—ãŸè¡Œå±•é–‹ã¯ã€ã“ã“ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_expr.c:766 parser/parse_relation.c:530 -#: parser/parse_relation.c:611 parser/parse_target.c:1087 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 +#: parser/parse_relation.c:789 parser/parse_target.c:1199 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "列å‚ç…§\"%s\"ã¯æ›–昧ã§ã™" -#: parser/parse_expr.c:822 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "パラメータ$%dãŒã‚りã¾ã›ã‚“" -#: parser/parse_expr.c:1034 +#: parser/parse_expr.c:1070 #, c-format msgid "NULLIF requires = operator to yield boolean" -msgstr "NULLIFã§ã¯=演算å­ãŒbooleanã‚’è¿”ã™ã“ã¨ã‚’å¿…è¦ã¨ã—ã¾ã™" +msgstr "NULLIF ã§ã¯ = 演算å­ãŒ boolean ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 +#, c-format +msgid "%s must not return a set" +msgstr "%sã¯é›†åˆã‚’è¿”ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 +#, c-format +msgid "number of columns does not match number of values" +msgstr "åˆ—ã®æ•°ãŒVALUESã®æ•°ã¨ä¸€è‡´ã—ã¾ã›ã‚“" + +#: parser/parse_expr.c:1570 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "複数列ã®UPDATEé …ç›®ã®ã‚½ãƒ¼ã‚¹ã¯å‰¯å•åˆã›ã¾ãŸã¯ROW()å¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_expr.c:1466 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "集åˆè¿”å´é–¢æ•°ã¯%sã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_expr.c:1825 msgid "cannot use subquery in check constraint" -msgstr "ãƒã‚§ãƒƒã‚¯åˆ¶ç´„ã§ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" +msgstr "検査制約ã§ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1470 -#| msgid "cannot use subquery in index expression" +#: parser/parse_expr.c:1829 msgid "cannot use subquery in DEFAULT expression" msgstr "DEFAULTå¼ã«ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1473 +#: parser/parse_expr.c:1832 msgid "cannot use subquery in index expression" msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã«ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1476 +#: parser/parse_expr.c:1835 msgid "cannot use subquery in index predicate" msgstr "インデックスã®è¿°éƒ¨ã«å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1479 +#: parser/parse_expr.c:1838 msgid "cannot use subquery in transform expression" msgstr "変æ›å¼ã§ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1482 +#: parser/parse_expr.c:1841 msgid "cannot use subquery in EXECUTE parameter" msgstr "EXECUTEã®ãƒ‘ラメータã«å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1485 +#: parser/parse_expr.c:1844 msgid "cannot use subquery in trigger WHEN condition" msgstr "トリガー㮠WHEN æ¡ä»¶ã§ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1542 -#, c-format -msgid "subquery must return a column" -msgstr "副å•ã„åˆã‚ã›ã¯1列を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#: parser/parse_expr.c:1847 +msgid "cannot use subquery in partition key expression" +msgstr "パーティションキーå¼ã§ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1549 +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "CALLã®å¼•æ•°ã§å‰¯å•ã„åˆã‚ã›ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_expr.c:1903 #, c-format msgid "subquery must return only one column" msgstr "副å•ã„åˆã‚ã›ã¯1列ã®ã¿ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_expr.c:1609 +#: parser/parse_expr.c:1987 #, c-format msgid "subquery has too many columns" msgstr "副å•ã„åˆã‚ã›ã®åˆ—ãŒå¤šã™ãŽã¾ã™" -#: parser/parse_expr.c:1614 +#: parser/parse_expr.c:1992 #, c-format msgid "subquery has too few columns" msgstr "副å•ã„åˆã‚ã›ã®åˆ—ãŒå°‘ãªã™ãŽã¾ã™" -#: parser/parse_expr.c:1710 +#: parser/parse_expr.c:2093 #, c-format msgid "cannot determine type of empty array" msgstr "空ã®é…列ã®ãƒ‡ãƒ¼ã‚¿åž‹ã‚’決定ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:1711 +#: parser/parse_expr.c:2094 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." -msgstr "希望ã™ã‚‹åž‹ã«æ˜Žç¤ºçš„ã«ã‚­ãƒ£ã‚¹ãƒˆã—ã¦ãã ã•ã„。例:ARRAY[]::integer[]" +msgstr "å¿…è¦ãªåž‹ã«æ˜Žç¤ºçš„ã«ã‚­ãƒ£ã‚¹ãƒˆã—ã¦ãã ã•ã„。例: ARRAY[]::integer[]" -#: parser/parse_expr.c:1725 +#: parser/parse_expr.c:2108 #, c-format msgid "could not find element type for data type %s" -msgstr "データ型 %s ã®è¦ç´ ã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ" +msgstr "データ型%sã®è¦ç´ ã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_expr.c:1951 +#: parser/parse_expr.c:2395 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "ç„¡åã®XML属性値ã¯åˆ—å‚ç…§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_expr.c:1952 +#: parser/parse_expr.c:2396 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "ç„¡åã®XMLè¦ç´ å€¤ã¯åˆ—å‚ç…§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_expr.c:1967 +#: parser/parse_expr.c:2411 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "XML属性å\"%s\"ãŒè¤‡æ•°ã‚りã¾ã™" -#: parser/parse_expr.c:2074 +#: parser/parse_expr.c:2518 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "XMLSERIALIZE ã®çµæžœã‚’ %s ã¸ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:2317 parser/parse_expr.c:2517 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format msgid "unequal number of entries in row expressions" msgstr "行å¼ã«ãŠã„ã¦é …目数ãŒä¸€è‡´ã—ã¾ã›ã‚“" -#: parser/parse_expr.c:2327 +#: parser/parse_expr.c:2824 #, c-format msgid "cannot compare rows of zero length" msgstr "é•·ã•0ã®è¡Œã‚’比較ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:2352 +#: parser/parse_expr.c:2849 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "行比較演算å­ã¯åž‹%sã§ã¯ãªãbooleanã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_expr.c:2359 +#: parser/parse_expr.c:2856 #, c-format msgid "row comparison operator must not return a set" msgstr "行比較演算å­ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: parser/parse_expr.c:2418 parser/parse_expr.c:2463 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "行比較演算å­%sã®è§£é‡ˆã‚’決定ã§ãã¾ã›ã‚“" -#: parser/parse_expr.c:2420 +#: parser/parse_expr.c:2917 #, c-format msgid "Row comparison operators must be associated with btree operator families." -msgstr "行比較演算å­ã¯B-Treeæ¼”ç®—å­æ—ã¨é–¢é€£ä»˜ã‘ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "行比較演算å­ã¯btreeæ¼”ç®—å­æ—ã¨é–¢é€£ä»˜ã‘ã•れãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: parser/parse_expr.c:2465 +#: parser/parse_expr.c:2958 #, c-format msgid "There are multiple equally-plausible candidates." -msgstr "複数ã®ã‚‚ã£ã¨ã‚‚らã—ã•ãŒç­‰ã—ã„候補ãŒå­˜åœ¨ã—ã¾ã™ã€‚" +msgstr "åŒç¨‹åº¦ã®é©åˆåº¦ã®å€™è£œãŒè¤‡æ•°å­˜åœ¨ã—ã¾ã™ã€‚" -#: parser/parse_expr.c:2557 +#: parser/parse_expr.c:3051 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROMã§ã¯=演算å­ã¯booleanã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_func.c:150 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "演算å­ã®å„ªå…ˆé †ä½ã®å¤‰æ›´: %sã¯ä»Šã§ã¯%sより低ã„優先順ä½ã§ã™" + +#: parser/parse_func.c:185 #, c-format msgid "argument name \"%s\" used more than once" -msgstr "引数å \"%s\" ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¾ã—ãŸ" +msgstr "引数å\"%s\"ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¾ã—ãŸ" -#: parser/parse_func.c:161 +#: parser/parse_func.c:196 #, c-format msgid "positional argument cannot follow named argument" msgstr "ä½ç½®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒ¼ã®æ¬¡ã«ã¯åå‰ä»˜ãã®å¼•数を指定ã§ãã¾ã›ã‚“。" -#: parser/parse_func.c:240 +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "%sã¯ãƒ—ロシージャã§ã¯ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "関数を呼ã³å‡ºã™ã«ã¯ SELECT を使用ã—ã¦ãã ã•ã„。" + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "%sã¯ãƒ—ロシージャã§ã™" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "関数を呼ã³å‡ºã™ã«ã¯ CALL を使用ã—ã¦ãã ã•ã„。" + +#: parser/parse_func.c:306 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "%s(*)ãŒæŒ‡å®šã•れã¾ã—ãŸãŒ%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_func.c:247 +#: parser/parse_func.c:313 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "DISTINCTãŒæŒ‡å®šã•れã¾ã—ãŸãŒ%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_func.c:253 +#: parser/parse_func.c:319 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUPãŒæŒ‡å®šã•れã¾ã—ãŸãŒ%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:325 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" -msgstr "ORDER BY ãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€%s ãŒé›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "ORDER BY ãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_func.c:259 +#: parser/parse_func.c:331 #, c-format -#| msgid "DISTINCT specified, but %s is not an aggregate function" msgid "FILTER specified, but %s is not an aggregate function" -msgstr "FILTERãŒæŒ‡å®šã•れã¾ã—ãŸãŒ%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "FILTERãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€%sã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_func.c:265 +#: parser/parse_func.c:337 #, c-format msgid "OVER specified, but %s is not a window function nor an aggregate function" -msgstr "OVER ãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€%s ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¨é›†ç´„関数ã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" +msgstr "OVERãŒæŒ‡å®šã•れã¾ã—ãŸãŒã€%sã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¨é›†ç´„関数ã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:375 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "é †åºé›†åˆé›†ç´„%sã«ã¯ WITHIN GROUP ãŒå¿…è¦ã§ã™" + +#: parser/parse_func.c:381 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVERã¯é †åºé›†åˆé›†ç´„%sã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_func.c:412 parser/parse_func.c:441 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "é †åºé›†åˆé›†ç´„%1$sã¯ã‚りã¾ã™ãŒã€ãれã¯%3$d個ã§ã¯ãªã%2$d個ã®ç›´æŽ¥å¼•æ•°ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚" + +#: parser/parse_func.c:466 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "仮想集åˆé›†ç´„%sを使ã†ã«ã¯ã€ä»®æƒ³ç›´æŽ¥å¼•æ•°(今ã¯%d)ãŒã‚½ãƒ¼ãƒˆåˆ—ã®æ•°(今ã¯%d)ã¨ä¸€è‡´ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: parser/parse_func.c:480 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "é †åºé›†åˆé›†ç´„%sã¯ã‚りã¾ã™ãŒã€ãれã¯å°‘ãªãã¨ã‚‚%d個ã®ç›´æŽ¥å¼•æ•°ã‚’å¿…è¦ã¨ã—ã¾ã™ã€‚" + +#: parser/parse_func.c:499 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%sã¯é †åºé›†åˆé›†ç´„ã§ã¯ãªã„ãŸã‚ã€WITHIN GROUP ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:512 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "ウィンドウ関数%sã«ã¯OVERå¥ãŒå¿…è¦ã§ã™" + +#: parser/parse_func.c:519 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "ウィンドウ関数%sã¯WITHIN GROUPã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "プロシージャ %s ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:551 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "最善ã®å€™è£œãƒ—ãƒ­ã‚·ãƒ¼ã‚¸ãƒ£ã‚’é¸æŠžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: parser/parse_func.c:287 +#: parser/parse_func.c:557 #, c-format msgid "function %s is not unique" msgstr "関数 %s ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" -#: parser/parse_func.c:290 +#: parser/parse_func.c:560 #, c-format msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "最善ã®å€™è£œé–¢æ•°ã‚’é¸æŠžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" -#: parser/parse_func.c:301 +#: parser/parse_func.c:599 #, c-format msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." -msgstr "与ãˆã‚‰ã‚ŒãŸåå‰ã¨å¼•æ•°ã«åˆè‡´ã™ã‚‹é›†ç´„関数ãŒã‚りã¾ã›ã‚“。ãŠãらã ORDER BY ã®ä½ç½®ã«èª¤ã‚ŠãŒã‚りã¾ã™ã€‚ORDER BY ã¯é›†ç´„関数ã®ã™ã¹ã¦ã®æ­£è¦è¡¨ç¾å¼•æ•°ã®å¾Œã«ç¾ã‚Œãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "指定ã—ãŸåå‰ã¨å¼•æ•°åž‹ã«åˆè‡´ã™ã‚‹é›†ç´„関数ãŒã‚りã¾ã›ã‚“。ãŠãらã ORDER BY ã®ä½ç½®ã«èª¤ã‚ŠãŒã‚りã¾ã™ã€‚ORDER BY ã¯é›†ç´„関数ã®ã™ã¹ã¦ã®é€šå¸¸ã®å¼•æ•°ã®å¾Œã«ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "プロシージャ %s ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: parser/parse_func.c:610 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "指定ã—ãŸåç§°ã¨å¼•æ•°ã®åž‹ã«åˆã†æ¼”ç®—å­ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: parser/parse_func.c:312 +#: parser/parse_func.c:619 #, c-format msgid "No function matches the given name and argument types. You might need to add explicit type casts." -msgstr "指定åç§°ã€æŒ‡å®šå¼•æ•°åž‹ã«åˆã†é–¢æ•°ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" +msgstr "指定ã—ãŸåå‰ã¨å¼•æ•°åž‹ã«åˆè‡´ã™ã‚‹é–¢æ•°ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹å¤‰æ›ãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: parser/parse_func.c:399 +#: parser/parse_func.c:721 #, c-format -#| msgid "VARIADIC parameter must be an array" msgid "VARIADIC argument must be an array" msgstr "VARIADIC引数ã¯é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_func.c:440 parser/parse_func.c:507 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*)ã¯ãƒ‘ラメータãŒãªã„集約関数ã®å‘¼ã³å‡ºã—ã«ä½¿ç”¨ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_func.c:447 +#: parser/parse_func.c:780 #, c-format msgid "aggregates cannot return sets" msgstr "集約ã¯é›†åˆã‚’è¿”ã›ã¾ã›ã‚“" -#: parser/parse_func.c:459 +#: parser/parse_func.c:795 #, c-format msgid "aggregates cannot use named arguments" msgstr "集約ã§ã¯åå‰ä»˜ã引数ã¯ä½¿ãˆã¾ã›ã‚“" -#: parser/parse_func.c:478 +#: parser/parse_func.c:827 #, c-format -msgid "window function call requires an OVER clause" -msgstr "ウィンドウ関数ã®å‘¼ã³å‡ºã—ã«ã¯ OVER å¥ãŒå¿…è¦ã§ã™" +msgid "DISTINCT is not implemented for window functions" +msgstr "ウィンドウ関数ã«å¯¾ã™ã‚‹DISTINCTã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_func.c:497 +#: parser/parse_func.c:847 #, c-format -msgid "DISTINCT is not implemented for window functions" -msgstr "ウィンドウ関数ã«å¯¾ã™ã‚‹ DISTINCT ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "ウィンドウ関数ã«å¯¾ã™ã‚‹é›†ç´„ã® ORDER BY ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_func.c:518 +#: parser/parse_func.c:856 #, c-format -#| msgid "DISTINCT is not implemented for window functions" -msgid "FILTER is not implemented in non-aggregate window functions" +msgid "FILTER is not implemented for non-aggregate window functions" msgstr "éžé›†ç´„ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã«å¯¾ã™ã‚‹FILTERã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_func.c:527 +#: parser/parse_func.c:865 #, c-format -msgid "aggregate ORDER BY is not implemented for window functions" -msgstr "ウィンドウ関数ã«å¯¾ã™ã‚‹é›†ç´„ã® ORDER BY ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgid "window function calls cannot contain set-returning function calls" +msgstr "集約関数ã®å‘¼ã³å‡ºã—ã«é›†åˆè¿”å´é–¢æ•°ã®å‘¼ã³å‡ºã—ã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: parser/parse_func.c:533 +#: parser/parse_func.c:873 #, c-format msgid "window functions cannot return sets" msgstr "ウィンドウ関数ã¯é›†åˆã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: parser/parse_func.c:544 +#: parser/parse_func.c:2059 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "関数å\"%s\"ã¯ä¸€æ„ã§ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:2061 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "関数を曖昧ã•ãªãé¸æŠžã™ã‚‹ã«ã¯å¼•数リストを指定ã—ã¦ãã ã•ã„。" + +#: parser/parse_func.c:2071 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "\"%s\"ã¨ã„ã†åå‰ã®é–¢æ•°ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s ã¯é–¢æ•°ã§ã¯ã‚りã¾ã›ã‚“" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "\"%s\"ã¨ã„ã†åå‰ã®ãƒ—ロシージャã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: parser/parse_func.c:2198 #, c-format -msgid "window functions cannot use named arguments" -msgstr "ウィンドウ関数ã§ã¯åå‰ä»˜ã引数を使ãˆã¾ã›ã‚“" +msgid "could not find an aggregate named \"%s\"" +msgstr "\"%s\"ã¨ã„ã†åå‰ã®é›†ç´„ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" -#: parser/parse_func.c:1711 +#: parser/parse_func.c:2203 #, c-format msgid "aggregate %s(*) does not exist" msgstr "集約%s(*)ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_func.c:1716 +#: parser/parse_func.c:2208 #, c-format msgid "aggregate %s does not exist" msgstr "集約%sã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_func.c:1735 +#: parser/parse_func.c:2221 #, c-format msgid "function %s is not an aggregate" msgstr "関数%sã¯é›†ç´„ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_node.c:84 +#: parser/parse_func.c:2271 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯JOINæ¡ä»¶ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2292 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯ãƒãƒªã‚·å¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2308 +msgid "set-returning functions are not allowed in window definitions" +msgstr "ウィンドウ定義ã§ã¯é›†åˆè¿”å´é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2346 +msgid "set-returning functions are not allowed in check constraints" +msgstr "集åˆè¿”å´é–¢æ•°ã¯æ¤œæŸ»åˆ¶ç´„ã®ä¸­ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2350 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯DEFAULTå¼ã®ä¸­ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2353 +msgid "set-returning functions are not allowed in index expressions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2356 +msgid "set-returning functions are not allowed in index predicates" +msgstr "集åˆè¿”å´é–¢æ•°ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹è¿°èªžã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2359 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯å¤‰æ›å¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2362 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "集åˆè¿”å´é–¢æ•°ã¯EXECUTEパラメータã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2365 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯ãƒˆãƒªã‚¬ã®WHENæ¡ä»¶ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "集åˆè¿”å´é–¢æ•°ã¯ãƒ‘ーティションキーå¼ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "CALLã®å¼•æ•°ã«é›†åˆè¿”å´é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_node.c:87 #, c-format msgid "target lists can have at most %d entries" -msgstr "å¯¾è±¡ãƒªã‚¹ãƒˆã¯æœ€å¤§ã§%dエントリæŒã¤ã“ã¨ãŒã§ãã¾ã™" +msgstr "ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒªã‚¹ãƒˆã¯æœ€å¤§ã§ã‚‚%dエントリã¾ã§ã—ã‹æŒã¦ã¾ã›ã‚“" -#: parser/parse_node.c:241 +#: parser/parse_node.c:256 #, c-format msgid "cannot subscript type %s because it is not an array" -msgstr "é…列ã§ã¯ã‚りã¾ã›ã‚“ã®ã§ã€åž‹%sã«æ·»ãˆå­—ã‚’ã¤ã‘られã¾ã›ã‚“" +msgstr "é…列ã§ã¯ãªã„ãŸã‚ã€åž‹%sã«ã¯æ·»ãˆå­—ã‚’ã¤ã‘られã¾ã›ã‚“" -#: parser/parse_node.c:343 parser/parse_node.c:370 +#: parser/parse_node.c:358 parser/parse_node.c:395 #, c-format msgid "array subscript must have type integer" msgstr "é…åˆ—ã®æ·»ãˆå­—ã¯æ•´æ•°åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_node.c:394 +#: parser/parse_node.c:426 #, c-format msgid "array assignment requires type %s but expression is of type %s" msgstr "é…列ã®ä»£å…¥ã§ã¯åž‹%sãŒå¿…è¦ã§ã—ãŸãŒã€å¼ã¯åž‹%sã§ã—ãŸ" -#: parser/parse_oper.c:124 parser/parse_oper.c:718 utils/adt/regproc.c:490 -#: utils/adt/regproc.c:510 utils/adt/regproc.c:669 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format msgid "operator does not exist: %s" msgstr "演算å­ãŒå­˜åœ¨ã—ã¾ã›ã‚“: %s" -#: parser/parse_oper.c:221 +#: parser/parse_oper.c:224 #, c-format msgid "Use an explicit ordering operator or modify the query." -msgstr "明示的ã«é †åºæ¼”ç®—å­ã‚’使用ã™ã‚‹ã‹å•ã„åˆã‚ã›ã‚’変更ã—ã¦ãã ã•ã„" - -#: parser/parse_oper.c:225 utils/adt/arrayfuncs.c:3181 -#: utils/adt/arrayfuncs.c:3700 utils/adt/arrayfuncs.c:5253 -#: utils/adt/rowtypes.c:1186 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "åž‹%sã®ç­‰ä¾¡æ€§æ¼”ç®—å­ã‚’識別ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "明示的ã«é †åºæ¼”ç®—å­ã‚’使用ã™ã‚‹ã‹å•ã„åˆã‚ã›ã‚’変更ã—ã¦ãã ã•ã„。" -#: parser/parse_oper.c:476 +#: parser/parse_oper.c:480 #, c-format msgid "operator requires run-time type coercion: %s" -msgstr "演算å­ã¯å®Ÿè¡Œæ™‚ã®åž‹å¼·åˆ¶ãŒå¿…è¦ã§ã™: %s" +msgstr "演算å­ã«å®Ÿè¡Œæ™‚ã®åž‹å¼·åˆ¶ãŒå¿…è¦ã§ã™: %s" -#: parser/parse_oper.c:710 +#: parser/parse_oper.c:716 #, c-format msgid "operator is not unique: %s" msgstr "演算å­ã¯ä¸€æ„ã§ã¯ã‚りã¾ã›ã‚“: %s" -#: parser/parse_oper.c:712 +#: parser/parse_oper.c:718 #, c-format msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgstr "最善ã®å€™è£œæ¼”ç®—å­ã‚’é¸æŠžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" -#: parser/parse_oper.c:720 +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "指定ã—ãŸåç§°ã¨å¼•æ•°ã®åž‹ã«åˆã†æ¼”ç®—å­ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" + +#: parser/parse_oper.c:729 #, c-format -msgid "No operator matches the given name and argument type(s). You might need to add explicit type casts." -msgstr "指定åç§°ã€æŒ‡å®šå¼•æ•°åž‹ã«åˆã†æ¼”ç®—å­ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“" +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "指定ã—ãŸåç§°ã¨å¼•æ•°ã®åž‹ã«åˆã†æ¼”ç®—å­ãŒã‚りã¾ã›ã‚“。明示的ãªåž‹ã‚­ãƒ£ã‚¹ãƒˆãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: parser/parse_oper.c:779 parser/parse_oper.c:893 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" -msgstr "演算å­ã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™ï¼š%s" +msgstr "演算å­ã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™: %s" -#: parser/parse_oper.c:881 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" -msgstr "æ¼”ç®—å­ ANY/ALL (é…列) ã¯å³å´ã«é…列ãŒå¿…è¦ã§ã™" +msgstr "æ¼”ç®—å­ ANY/ALL (é…列) å³è¾ºã«é…列ãŒå¿…è¦ã§ã™" -#: parser/parse_oper.c:923 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" -msgstr "æ¼”ç®—å­ ANY/ALL (é…列) ã®æ¼”ç®—å­ã¯ãƒ–ール型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æ¼”ç®—å­ ANY/ALL (é…列) ã¯ãƒ–ール型を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_oper.c:928 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" -msgstr "æ¼”ç®—å­ ANY/ALL (é…列) ã®æ¼”ç®—å­ã¯é›†åˆã‚’è¿”ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "æ¼”ç®—å­ ANY/ALL (é…列) 集åˆã‚’è¿”ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" #: parser/parse_param.c:216 #, c-format msgid "inconsistent types deduced for parameter $%d" msgstr "パラメータ$%dã«ã¤ã„ã¦æŽ¨å®šã•れãŸåž‹ãŒä¸æ•´åˆã§ã™" -#: parser/parse_relation.c:157 +#: parser/parse_relation.c:176 #, c-format msgid "table reference \"%s\" is ambiguous" msgstr "テーブルå‚ç…§\"%s\"ã¯æ›–昧ã§ã™" -#: parser/parse_relation.c:164 parser/parse_relation.c:216 -#: parser/parse_relation.c:618 parser/parse_relation.c:2690 +#: parser/parse_relation.c:220 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "テーブルå‚ç…§%uã¯æ›–昧ã§ã™" + +#: parser/parse_relation.c:419 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "テーブルå\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" + +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" -msgstr "テーブル\"%s\"用ã®FROMå¥ã«å¯¾ã™ã‚‹ç„¡åйãªå‚ç…§ã§ã™ã€‚" +msgstr "テーブル\"%s\"用ã®FROMå¥ã«å¯¾ã™ã‚‹ä¸æ­£ãªå‚ç…§" -#: parser/parse_relation.c:166 parser/parse_relation.c:218 -#: parser/parse_relation.c:620 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format -msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." -msgstr "LATERALå‚ç…§ã§ã¯çµ„ã¿åˆã‚ã›ã‚‹çµåˆç¨®é¡žã¯INNERã¾ãŸã¯LEFTã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "テーブル\"%s\"ã®é …ç›®ãŒã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã®ã“ã®éƒ¨åˆ†ã‹ã‚‰ã¯å‚ç…§ã§ãã¾ã›ã‚“。\"" -#: parser/parse_relation.c:209 +#: parser/parse_relation.c:451 #, c-format -msgid "table reference %u is ambiguous" -msgstr "テーブルå‚ç…§%uã¯æ›–昧ã§ã™" +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "LATERALå‚ç…§ã§ã¯çµ„ã¿åˆã‚ã›ã‚‹çµåˆã®ã‚¿ã‚¤ãƒ—ã¯INNERã¾ãŸã¯LEFTã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_relation.c:395 +#: parser/parse_relation.c:727 #, c-format -msgid "table name \"%s\" specified more than once" -msgstr "テーブルå\"%s\"ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "検査制約ã§å‚ç…§ã•れるシステム列\"%s\"ã¯ä¸æ­£ã§ã™" -#: parser/parse_relation.c:882 parser/parse_relation.c:1182 -#: parser/parse_relation.c:1566 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 +#: parser/parse_relation.c:1936 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "テーブル\"%s\"ã§ã¯%d列使用ã§ãã¾ã™ãŒã€%d列指定ã•れã¾ã—ãŸ" -#: parser/parse_relation.c:920 -#, c-format -msgid "too many column aliases specified for function %s" -msgstr "関数%sã§æŒ‡å®šã•れãŸåˆ—別åãŒå¤šã™ãŽã¾ã™" - -#: parser/parse_relation.c:992 +#: parser/parse_relation.c:1173 #, c-format msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." -msgstr "\"%s\" ã¨ã„ㆠWITH é …ç›®ãŒã‚りã¾ã™ãŒã€ã“れã¯ã‚¯ã‚¨ãƒªãƒ¼ã®ã“ã®éƒ¨åˆ†ã‹ã‚‰ã¯å‚ç…§ã§ãã¾ã›ã‚“。" +msgstr "\"%s\" ã¨ã„ㆠWITH é …ç›®ã¯ã‚りã¾ã™ãŒã€ã“れã¯å•ã„åˆã‚ã›ã®ã“ã®éƒ¨åˆ†ã‹ã‚‰ã¯å‚ç…§ã§ãã¾ã›ã‚“。" -#: parser/parse_relation.c:994 +#: parser/parse_relation.c:1175 #, c-format msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "WITH RECURSIVE を使ã†ã‹ã€ã‚‚ã—ã㯠WITH é …ç›®ã®å ´æ‰€ã‚’変ãˆã¦å‰æ–¹å‚ç…§ã‚’ãªãã—ã¦ãã ã•ã„" -#: parser/parse_relation.c:1260 +#: parser/parse_relation.c:1486 #, c-format msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "列定義リストã¯\"record\"ã‚’è¿”ã™é–¢æ•°ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™" -#: parser/parse_relation.c:1268 +#: parser/parse_relation.c:1495 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "\"record\"ã‚’è¿”ã™é–¢æ•°ã§ã¯åˆ—定義リストãŒå¿…è¦ã§ã™" -#: parser/parse_relation.c:1291 -#, c-format -#| msgid "a column definition list is required for functions returning \"record\"" -msgid "WITH ORDINALITY is not supported for functions returning \"record\"" -msgstr "\"record\"ã‚’è¿”ã™é–¢æ•°ã§ã¯WITH ORDINALITYã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#: parser/parse_relation.c:1325 +#: parser/parse_relation.c:1575 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" -msgstr "FROMå¥ã®é–¢æ•°\"%s\"ãŒã‚µãƒãƒ¼ãƒˆã•れãªã„戻り値型%sã‚’æŒã¡ã¾ã™" +msgstr "FROMå¥ã®é–¢æ•°\"%s\"ã®æˆ»ã‚Šå€¤åž‹%sã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_relation.c:1398 +#: parser/parse_relation.c:1764 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "VALUESリスト\"%s\"ã¯%d列使用å¯èƒ½ã§ã™ãŒã€%dåˆ—ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: parser/parse_relation.c:1451 +#: parser/parse_relation.c:1819 #, c-format msgid "joins can have at most %d columns" -msgstr "JOIN ã§æŒ‡å®šã§ãã‚‹ã®ã¯ã€æœ€å¤§ %d カラムã§ã™" +msgstr "JOIN ã§æŒ‡å®šã§ãã‚‹ã®ã¯ã€æœ€å¤§ %d 列ã§ã™" -#: parser/parse_relation.c:1539 +#: parser/parse_relation.c:1909 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" -msgstr "WITH クエリー \"%s\" ã« RETURNING å¥ãŒã‚りã¾ã›ã‚“" +msgstr "WITH å•ã„åˆã‚ã› \"%s\" ã« RETURNING å¥ãŒã‚りã¾ã›ã‚“" -#: parser/parse_relation.c:2293 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 +#: parser/parse_relation.c:3011 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"ã®åˆ—\"%1$d\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: parser/parse_relation.c:2693 +#: parser/parse_relation.c:3230 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." -msgstr "テーブル別å\"%s\"ã«å¯¾ã™ã‚‹å‚ç…§ã‚’æ„図ã—ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" +msgstr "テーブル別å\"%s\"ã‚’å‚ç…§å‚ç…§ã—よã†ã¨ã—ã¦ã„ãŸã‚ˆã†ã§ã™ã€‚" -#: parser/parse_relation.c:2695 -#, c-format -msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." -msgstr "テーブル\"%s\"ã®é …ç›®ãŒã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã®ã“ã®éƒ¨åˆ†ã‹ã‚‰ã¯å‚ç…§ã§ãã¾ã›ã‚“。\"" - -#: parser/parse_relation.c:2701 +#: parser/parse_relation.c:3238 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "テーブル\"%s\"用ã®FROMå¥ã‚¨ãƒ³ãƒˆãƒªãŒã‚りã¾ã›ã‚“" -#: parser/parse_relation.c:2741 +#: parser/parse_relation.c:3290 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "列\"%s.%s\"ã‚’å‚ç…§ã—よã†ã¨ã—ã¦ã„ãŸã‚ˆã†ã§ã™ã€‚" + +#: parser/parse_relation.c:3292 #, c-format -#| msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." msgstr "テーブル\"%2$s\"ã«ã¯\"%1$s\"ã¨ã„ã†åå‰ã®åˆ—ãŒã‚りã¾ã™ãŒã€å•ã„åˆã‚ã›ã®ã“ã®éƒ¨åˆ†ã‹ã‚‰ã¯å‚ç…§ã§ãã¾ã›ã‚“。" -#: parser/parse_target.c:402 parser/parse_target.c:693 +#: parser/parse_relation.c:3309 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "列\"%s.%s\"ã¾ãŸã¯åˆ—\"%s.%s\"ã‚’å‚ç…§ã—よã†ã¨ã—ã¦ã„ãŸã‚ˆã†ã§ã™ã€‚" + +#: parser/parse_target.c:483 parser/parse_target.c:790 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "システム列\"%s\"ã«ä»£å…¥ã§ãã¾ã›ã‚“" -#: parser/parse_target.c:430 +#: parser/parse_target.c:511 #, c-format msgid "cannot set an array element to DEFAULT" msgstr "é…列è¦ç´ ã«DEFAULTを設定ã§ãã¾ã›ã‚“" -#: parser/parse_target.c:435 +#: parser/parse_target.c:516 #, c-format msgid "cannot set a subfield to DEFAULT" msgstr "サブフィールドã«DEFAULTを設定ã§ãã¾ã›ã‚“" -#: parser/parse_target.c:504 +#: parser/parse_target.c:585 #, c-format msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "列\"%s\"ã¯åž‹%sã§ã™ãŒã€å¼ã¯åž‹%sã§ã—ãŸ" -#: parser/parse_target.c:677 +#: parser/parse_target.c:774 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" msgstr "åž‹%3$sãŒè¤‡åˆåž‹ã§ã‚りã¾ã›ã‚“ã®ã§ã€åˆ—\"%2$s\"ã®ãƒ•ィールド\"%1$s\"ã«ä»£å…¥ã§ãã¾ã›ã‚“。" -#: parser/parse_target.c:686 +#: parser/parse_target.c:783 #, c-format msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" msgstr "データ型%3$sã®åˆ—ãŒã‚りã¾ã›ã‚“ã®ã§ã€åˆ—\"%2$s\"ã®ãƒ•ィールド\"%1$s\"ã«ä»£å…¥ã§ãã¾ã›ã‚“。" -#: parser/parse_target.c:753 +#: parser/parse_target.c:860 #, c-format msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "\"%s\"ã¸ã®é…列代入ã«ã¯åž‹%sãŒå¿…è¦ã§ã™ãŒã€å¼ã¯åž‹%sã§ã—ãŸ" -#: parser/parse_target.c:763 +#: parser/parse_target.c:870 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "サブフィールド\"%s\"ã¯åž‹%sã§ã™ãŒã€å¼ã¯åž‹%sã§ã—ãŸ" -#: parser/parse_target.c:1177 +#: parser/parse_target.c:1289 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "テーブル指定ã®ãªã„SELECT *ã¯ç„¡åйã§ã™" -#: parser/parse_type.c:84 +#: parser/parse_type.c:83 #, c-format msgid "improper %%TYPE reference (too few dotted names): %s" -msgstr "%%TYPEå‚ç…§ãŒä¸é©åˆ‡ã§ã™(ドット付ãã®åå‰ãŒå°‘ãªã™ãŽã¾ã™: %s" +msgstr "%%TYPEå‚ç…§ãŒä¸é©åˆ‡ã§ã™(ドット区切りã®åå‰ãŒå°‘ãªã™ãŽã¾ã™: %s" -#: parser/parse_type.c:106 +#: parser/parse_type.c:105 #, c-format msgid "improper %%TYPE reference (too many dotted names): %s" -msgstr "%%TYPEå‚ç…§ãŒä¸é©åˆ‡ã§ã™(ドット付ãã®åå‰ãŒå¤šã™ãŽã¾ã™: %s" +msgstr "%%TYPEå‚ç…§ãŒä¸é©åˆ‡ã§ã™(ドット区切りã®åå‰ãŒå¤šã™ãŽã¾ã™: %s" -#: parser/parse_type.c:134 +#: parser/parse_type.c:140 #, c-format msgid "type reference %s converted to %s" msgstr "åž‹å‚ç…§%sã¯%sã«å¤‰æ›ã•れã¾ã—ãŸ" -#: parser/parse_type.c:209 utils/cache/typcache.c:198 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format msgid "type \"%s\" is only a shell" msgstr "åž‹\"%s\"ã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™" -#: parser/parse_type.c:294 +#: parser/parse_type.c:346 #, c-format msgid "type modifier is not allowed for type \"%s\"" msgstr "åž‹\"%s\"ã§ã¯åž‹ä¿®æ­£å­ã¯è¨±ã•れã¾ã›ã‚“" -#: parser/parse_type.c:337 +#: parser/parse_type.c:388 #, c-format msgid "type modifiers must be simple constants or identifiers" msgstr "型修正å­ã¯å˜ç´”ãªå®šæ•°ã¾ãŸã¯è­˜åˆ¥å­ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: parser/parse_type.c:648 parser/parse_type.c:747 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" -msgstr "åž‹ã®åå‰\"%s\"ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªåž‹å\"%s\"" -#: parser/parse_utilcmd.c:177 +#: parser/parse_utilcmd.c:272 #, c-format -msgid "relation \"%s\" already exists, skipping" -msgstr "リレーション \"%s\" ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™ã€‚スキップã—ã¾ã™ã€‚" - -#: parser/parse_utilcmd.c:342 -#, c-format -msgid "array of serial is not implemented" -msgstr "連番(SERIAL)ã®é…列ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" +msgid "cannot create partitioned table as inheritance child" +msgstr "パーティションテーブルを継承ã®å­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦ä½œæˆã¯ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:390 +#: parser/parse_utilcmd.c:448 #, c-format msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" msgstr "%1$sã¯ã‚·ãƒªã‚¢ãƒ«åˆ—\"%3$s.%4$s\"ç”¨ã«æš—黙的ãªã‚·ãƒ¼ã‚±ãƒ³ã‚¹\"%2$s\"を作æˆã—ã¾ã™ã€‚" -#: parser/parse_utilcmd.c:484 parser/parse_utilcmd.c:496 +#: parser/parse_utilcmd.c:571 +#, c-format +msgid "array of serial is not implemented" +msgstr "連番(SERIAL)ã®é…列ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 #, c-format msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "テーブル\"%2$s\"ã®åˆ—\"%1$s\"ã§NULL宣言ã¨NOT NULL宣言ãŒç«¶åˆã—ã¦ã„ã¾ã™" -#: parser/parse_utilcmd.c:508 +#: parser/parse_utilcmd.c:671 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "テーブル\"%2$s\"ã®åˆ—\"%1$s\"ã§è¤‡æ•°ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã®æŒ‡å®šãŒã‚りã¾ã™" -#: parser/parse_utilcmd.c:675 +#: parser/parse_utilcmd.c:688 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã§ã¯è­˜åˆ¥åˆ—ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "パーティションã§ã¯è­˜åˆ¥åˆ—ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:701 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "テーブル\"%2$s\"ã®åˆ—\"%1$s\"ã«è¤‡æ•°ã®è­˜åˆ¥æŒ‡å®šãŒã‚りã¾ã™" + +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "外部テーブルã§ã¯ä¸»ã‚­ãƒ¼åˆ¶ç´„ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "外部テーブルã§ã¯ãƒ¦ãƒ‹ãƒ¼ã‚¯åˆ¶ç´„ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "外部テーブルã§ã¯å¤–部キー制約ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:778 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "デフォルト値ã¨è­˜åˆ¥æŒ‡å®šã®ä¸¡æ–¹ãŒãƒ†ãƒ¼ãƒ–ル\"%2$s\"ã®åˆ—\"%1$s\"ã«æŒ‡å®šã•れã¦ã„ã¾ã™" + +#: parser/parse_utilcmd.c:843 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "外部テーブルã§ã¯é™¤å¤–制約ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:849 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "パーティションテーブルã§ã¯é™¤å¤–制約ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:913 #, c-format -#| msgid "\"%s\" is not a table or foreign table" msgid "LIKE is not supported for creating foreign tables" msgstr "外部テーブルã®ä½œæˆã«ãŠã„ã¦LIKEã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1194 parser/parse_utilcmd.c:1270 +#: parser/parse_utilcmd.c:1516 parser/parse_utilcmd.c:1623 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "インデックス\"%s\"ã«ã¯è¡Œå…¨ä½“ã®ãƒ†ãƒ¼ãƒ–ルå‚ç…§ãŒå«ã¾ã‚Œã¾ã™" -#: parser/parse_utilcmd.c:1537 +#: parser/parse_utilcmd.c:1973 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "CREATE TABLE ã§ã¯æ—¢å­˜ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使ãˆã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1557 +#: parser/parse_utilcmd.c:1993 #, c-format msgid "index \"%s\" is already associated with a constraint" -msgstr "インデックス \"%s\" ã¯ã™ã§ã«ï¼‘ã¤ã®åˆ¶ç´„ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã‚Œã„ã¾ã™" +msgstr "インデックス \"%s\" ã¯ã™ã§ã«1ã¤ã®åˆ¶ç´„ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚Œã‚Œã„ã¾ã™" -#: parser/parse_utilcmd.c:1565 +#: parser/parse_utilcmd.c:2001 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "インデックス \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ル \"%s\" ã«ã¯å±žã—ã¦ã„ã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1572 +#: parser/parse_utilcmd.c:2008 #, c-format msgid "index \"%s\" is not valid" msgstr "インデックス \"%s\" ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1578 +#: parser/parse_utilcmd.c:2014 #, c-format msgid "\"%s\" is not a unique index" msgstr "\"%s\"ã¯ãƒ¦ãƒ‹ãƒ¼ã‚¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1579 parser/parse_utilcmd.c:1586 -#: parser/parse_utilcmd.c:1593 parser/parse_utilcmd.c:1663 +#: parser/parse_utilcmd.c:2015 parser/parse_utilcmd.c:2022 +#: parser/parse_utilcmd.c:2029 parser/parse_utilcmd.c:2101 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." -msgstr "ãã®ã‚ˆã†ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使ã£ã¦ãƒ—ãƒ©ã‚¤ãƒžãƒªã‚­ãƒ¼ã‚„ä¸€æ„æ€§åˆ¶ç´„を作æˆã§ãã¾ã›ã‚“" +msgstr "ã“ã®ã‚ˆã†ãªã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使ã£ã¦ãƒ—ãƒ©ã‚¤ãƒžãƒªã‚­ãƒ¼ã‚„ä¸€æ„æ€§åˆ¶ç´„を作æˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1585 +#: parser/parse_utilcmd.c:2021 #, c-format msgid "index \"%s\" contains expressions" -msgstr "インデックス \"%s\" ã¯å¼ã‚’å«ã‚“ã§ã„ã¾ã™" +msgstr "インデックス\"%s\"ã¯å¼ã‚’å«ã‚“ã§ã„ã¾ã™" -#: parser/parse_utilcmd.c:1592 +#: parser/parse_utilcmd.c:2028 #, c-format msgid "\"%s\" is a partial index" -msgstr "\"%s\" ã¯éƒ¨åˆ†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" +msgstr "\"%s\"ã¯éƒ¨åˆ†ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" -#: parser/parse_utilcmd.c:1604 +#: parser/parse_utilcmd.c:2040 #, c-format msgid "\"%s\" is a deferrable index" -msgstr "\"%s\" ã¯é…å»¶å¯èƒ½ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" +msgstr "\"%s\"ã¯é…å»¶å¯èƒ½ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" -#: parser/parse_utilcmd.c:1605 +#: parser/parse_utilcmd.c:2041 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." -msgstr "é…å»¶å¯èƒ½ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使ã£ãŸé…å»¶ä¸å¯åˆ¶ç´„ã¯ä½œã‚Œã¾ã›ã‚“" +msgstr "é…å»¶å¯èƒ½ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使ã£ãŸé…å»¶ä¸å¯åˆ¶ç´„ã¯ä½œã‚Œã¾ã›ã‚“。" -#: parser/parse_utilcmd.c:1662 +#: parser/parse_utilcmd.c:2100 #, c-format msgid "index \"%s\" does not have default sorting behavior" -msgstr "インデックス \"%s\" ã¯ãƒ‡ãƒ•ォルトã®ã‚½ãƒ¼ãƒˆå‹•作をæŒã¡ã¾ã›ã‚“" +msgstr "インデックス\"%s\"ã¯ãƒ‡ãƒ•ォルトã®ã‚½ãƒ¼ãƒˆå‹•作をæŒã¡ã¾ã›ã‚“" -#: parser/parse_utilcmd.c:1807 +#: parser/parse_utilcmd.c:2249 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "列\"%s\"ãŒãƒ—ライマリキー制約内ã«2回出ç¾ã—ã¾ã™" -#: parser/parse_utilcmd.c:1813 +#: parser/parse_utilcmd.c:2255 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "列 \"%s\" ãŒä¸€æ„性制約内ã«2回出ç¾ã—ã¾ã™" -#: parser/parse_utilcmd.c:1984 -#, c-format -msgid "index expression cannot return a set" -msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯é›†åˆã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" - -#: parser/parse_utilcmd.c:1995 +#: parser/parse_utilcmd.c:2578 #, c-format msgid "index expressions and predicates can refer only to the table being indexed" -msgstr "インデックスå¼ã¨è¡“後ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ä»˜ã‘ã•れるテーブルã®ã¿ã‚’å‚ç…§ã§ãã¾ã™" +msgstr "インデックスå¼ã¨è¿°èªžã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ä»˜ã‘ã•れるテーブルã®ã¿ã‚’å‚ç…§ã§ãã¾ã™" -#: parser/parse_utilcmd.c:2038 +#: parser/parse_utilcmd.c:2624 #, c-format -#| msgid "multidimensional arrays are not supported" msgid "rules on materialized views are not supported" -msgstr "マテリアライズドビューã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +msgstr "実体化ビューã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2099 +#: parser/parse_utilcmd.c:2685 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "ルールã®WHEREæ¡ä»¶ã«ä»–ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¸ã®å‚ç…§ã‚’æŒãŸã›ã‚‰ã‚Œã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2171 +#: parser/parse_utilcmd.c:2757 #, c-format msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "ルールã®WHEREæ¡ä»¶ã¯SELECTã€INSERTã€UPDATEã€DELETE動作ã®ã¿ã‚’æŒã¤ã“ã¨ãŒã§ãã¾ã™" -#: parser/parse_utilcmd.c:2189 parser/parse_utilcmd.c:2288 -#: rewrite/rewriteHandler.c:442 rewrite/rewriteManip.c:1032 +#: parser/parse_utilcmd.c:2775 parser/parse_utilcmd.c:2874 +#: rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "æ¡ä»¶ä»˜ãã®UNION/INTERSECT/EXCEPTæ–‡ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2207 +#: parser/parse_utilcmd.c:2793 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "ON SELECTルールã§ã¯OLDを使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2211 +#: parser/parse_utilcmd.c:2797 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "ON SELECTルールã§ã¯NEWを使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2220 +#: parser/parse_utilcmd.c:2806 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "ON INSERTルールã§ã¯OLDを使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2226 +#: parser/parse_utilcmd.c:2812 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "ON DELETEルールã§ã¯NEWを使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2254 +#: parser/parse_utilcmd.c:2840 #, c-format msgid "cannot refer to OLD within WITH query" -msgstr "WITH クエリー内ã§ã¯ OLD ã¯å‚ç…§ã§ãã¾ã›ã‚“" +msgstr "WITH å•ã„åˆã‚ã›å†…ã§ã¯ OLD ã¯å‚ç…§ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2261 +#: parser/parse_utilcmd.c:2847 #, c-format msgid "cannot refer to NEW within WITH query" -msgstr "WITH クエリー内ã§ã¯ NEW ã¯å‚ç…§ã§ãã¾ã›ã‚“" +msgstr "WITH å•ã„åˆã‚ã›å†…ã§ã¯ NEW ã¯å‚ç…§ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2561 +#: parser/parse_utilcmd.c:3285 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "DEFERRABLEå¥ã®å ´æ‰€ãŒé–“é•ã£ã¦ã„ã¾ã™" -#: parser/parse_utilcmd.c:2566 parser/parse_utilcmd.c:2581 +#: parser/parse_utilcmd.c:3290 parser/parse_utilcmd.c:3305 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "複数ã®DEFERRABLE/NOT DEFERRABLEå¥ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2576 +#: parser/parse_utilcmd.c:3300 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "NOT DEFERRABLEå¥ã®å ´æ‰€ãŒé–“é•ã£ã¦ã„ã¾ã™" -#: parser/parse_utilcmd.c:2597 +#: parser/parse_utilcmd.c:3321 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "INITIALLY DEFERREDå¥ã®å ´æ‰€ãŒé–“é•ã£ã¦ã„ã¾ã™<" -#: parser/parse_utilcmd.c:2602 parser/parse_utilcmd.c:2628 +#: parser/parse_utilcmd.c:3326 parser/parse_utilcmd.c:3352 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "複数ã®INITIALLY IMMEDIATE/DEFERREDå¥ã‚’使用ã§ãã¾ã›ã‚“" -#: parser/parse_utilcmd.c:2623 +#: parser/parse_utilcmd.c:3347 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "INITIALLY IMMEDIATEå¥ã®å ´æ‰€ãŒé–“é•ã£ã¦ã„ã¾ã™<" -#: parser/parse_utilcmd.c:2814 +#: parser/parse_utilcmd.c:3538 #, c-format msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATEã§æŒ‡å®šã—ãŸã‚¹ã‚­ãƒ¼ãƒž(%s)ãŒä½œæˆå…ˆã®ã‚¹ã‚­ãƒ¼ãƒž(%s)ã¨ç•°ãªã‚Šã¾ã™" -#: parser/scansup.c:194 +#: parser/parse_utilcmd.c:3572 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "テーブル\"%s\"ã¯ãƒ‘ーティションã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3579 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "インデックス\"%s\"ã¯ãƒ‘ーティションã•れã¦ã„ã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3613 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションテーブルã¯ãƒ‡ãƒ•ォルトパーティションをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3630 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã«å¯¾ã™ã‚‹ä¸æ­£ãªå¢ƒç•ŒæŒ‡å®š" + +#: parser/parse_utilcmd.c:3636 partitioning/partbounds.c:2127 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã®æ³•ã¯æ­£ã®æ•´æ•°ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: parser/parse_utilcmd.c:3643 partitioning/partbounds.c:2135 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã®å‰°ä½™ã¯æ³•よりもå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3655 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "リストパーティションã«å¯¾ã™ã‚‹ä¸æ­£ãªå¢ƒç•ŒæŒ‡å®š" + +#: parser/parse_utilcmd.c:3711 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "範囲パーティションã«å¯¾ã™ã‚‹ä¸æ­£ãªå¢ƒç•ŒæŒ‡å®š" + +#: parser/parse_utilcmd.c:3717 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROMã¯å…¨ã¦ã®ãƒ‘ーティション列ã”ã¨ã«ä¸€ã¤ã®å€¤ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3721 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TOã¯å…¨ã¦ã®ãƒ‘ーティション列ã”ã¨ã«ä¸€ã¤ã®å€¤ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3768 parser/parse_utilcmd.c:3782 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "範囲境界ã§NULLã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3829 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "MAXVALUEã«ç¶šã境界値ã¯MAXVALUEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3836 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "MINVALUEã«ç¶šã境界値ã¯MINVALUEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3867 parser/parse_utilcmd.c:3879 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "指定ã—ãŸå€¤ã¯åˆ—\"%s\"ã®%såž‹ã«å¤‰æ›ã§ãã¾ã›ã‚“" + +#: parser/parse_utilcmd.c:3881 +#, c-format +msgid "The cast requires a non-immutable conversion." +msgstr "型変æ›ã«ã¯ä¸å¤‰(IMMUTABLE)ãªå¤‰æ›ãŒå¿…è¦ã§ã™ã€‚" + +#: parser/parse_utilcmd.c:3882 +#, c-format +msgid "Try putting the literal value in single quotes." +msgstr "リテラル値をシングルクォートã§å›²ã£ã¦ã¿ã¦ãã ã•ã„。" + +#: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" -msgstr "è­˜åˆ¥å­ \"%s\" ã‚’ \"%s\" ã«åˆ‡ã‚Šè©°ã‚ã¾ã™" +msgstr "識別å­\"%s\"ã¯\"%s\"ã«åˆ‡ã‚Šè©°ã‚られã¾ã™" -#: port/pg_latch.c:336 port/unix_latch.c:336 +#: partitioning/partbounds.c:331 #, c-format -msgid "poll() failed: %m" -msgstr "poll() ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "パーティション\"%s\"ã¯æ—¢å­˜ã®ãƒ‡ãƒ•ォルトパーティション\"%s\"ã¨é‡è¤‡ã—ã¦ã„ã¾ã™" -#: port/pg_latch.c:423 port/unix_latch.c:423 -#: replication/libpqwalreceiver/libpqwalreceiver.c:356 +#: partitioning/partbounds.c:390 #, c-format -msgid "select() failed: %m" -msgstr "select() ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³ã®æ³•(除数)ã¯æ¬¡ã«å¤§ããªæ³•ã®å› æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: port/pg_sema.c:111 port/sysv_sema.c:111 +#: partitioning/partbounds.c:486 #, c-format -msgid "could not create semaphores: %m" -msgstr "セマフォを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "empty range bound specified for partition \"%s\"" +msgstr "リレーション\"%s\"ã«å¯¾ã—ã¦ç©ºã®ç¯„å›²å¢ƒç•ŒãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: port/pg_sema.c:112 port/sysv_sema.c:112 +#: partitioning/partbounds.c:488 #, c-format -msgid "Failed system call was semget(%lu, %d, 0%o)." -msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯semget(%lu, %d, 0%o)ã§ã™ã€‚" +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "指定ã•れãŸä¸‹é™%sã¯ä¸Šé™%sより大ãã„ã‹åŒã˜ã§ã™ã€‚" -#: port/pg_sema.c:116 port/sysv_sema.c:116 +#: partitioning/partbounds.c:585 #, c-format -msgid "" -"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" -"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." -msgstr "" -"ã“ã®ã‚¨ãƒ©ãƒ¼ãŒèµ·ã“ã£ãŸã‹ã‚‰ã¨ã„ã£ã¦ã€åˆ¥ã«ãƒ‡ã‚£ã‚¹ã‚¯ãŒè¶³ã‚Šãªããªã£ãŸã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“。ã“ã®åŽŸå› ã¯ã‚»ãƒžãƒ•ã‚©ã‚»ãƒƒãƒˆã®æœ€å¤§æ•°(SEMMNI)ã«é”ã—ãŸã‹ã€ã¾ãŸã¯ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã®ã‚»ãƒžãƒ•ã‚©æ•°(SEMMNS)を使ã„ãã£ãŸå ´åˆã§ã™ã€‚対処ã¨ã—ã¦ã¯ã€å¯¾å¿œã™ã‚‹ã‚«ãƒ¼ãƒãƒ«ã®ãƒ‘ラメータを増やã™å¿…è¦ãŒã‚りã¾ã™ã€‚ã‚‚ã—ã㯠PostgreSQLã® max_connections を減らã™ã“ã¨ã§ã€æ¶ˆè²»ã™ã‚‹ã‚»ãƒžãƒ•ã‚©ã®æ•°ã‚’減らã—ã¦ãã ã•ã„。\n" -"共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "パーティション\"%s\"ã¯ãƒ‘ーティション\"%s\"ã¨é‡è¤‡ãŒã‚りã¾ã™" -#: port/pg_sema.c:143 port/sysv_sema.c:143 +#: partitioning/partbounds.c:685 #, c-format -msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." -msgstr "" -"ãŠãらãカーãƒãƒ«ã®SEMVMX値を最低ã§ã‚‚%dã¾ã§å¢—ã‚„ã™å¿…è¦ãŒã‚りã¾ã™ã€‚\n" -"詳細ã¯PostgreSQLã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’調ã¹ã¦ãã ã•ã„。" +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "デフォルトパーティション\"%2$s\"ã®å­ãƒ†ãƒ¼ãƒ–ルã§ã‚ã‚‹ãŸã‚テーブル\"%1$s\"ã®ã‚¹ã‚­ãƒ£ãƒ³ã‚’スキップã—ã¾ã™" + +#: partitioning/partbounds.c:724 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "デフォルトパーティション\"%s\"ã®ä¸€éƒ¨ã®è¡ŒãŒæ›´æ–°å¾Œã®ãƒ‘ーティション制約ã«é•åã—ã¦ã„ã¾ã™" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションã®å‰°ä½™ã¯éžè² ã®æ•´æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: port/pg_shmem.c:164 port/sysv_shmem.c:164 +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\"ã¯ãƒãƒƒã‚·ãƒ¥ãƒ‘ーティションテーブルã§ã¯ã‚りã¾ã›ã‚“" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³åˆ—ã®æ•°(%d)ã¨ä¸Žãˆã‚‰ã‚ŒãŸã‚­ãƒ¼å€¤ã®æ•°(%d)ãŒä¸€è‡´ã—ã¦ã„ã¾ã›ã‚“" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "パーティションキーã®åˆ— %d 㯠\"%s\"åž‹ã§ã™ã€ã—ã‹ã—与ãˆã‚‰ã‚ŒãŸå€¤ã¯ \"%s\"åž‹ã§ã™" + +#: port/pg_shmem.c:196 port/sysv_shmem.c:196 #, c-format msgid "could not create shared memory segment: %m" -msgstr "共有メモリセグメントを作æˆã§ãã¾ã›ã‚“: %m" +msgstr "共有メモリセグメントを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: port/pg_shmem.c:165 port/sysv_shmem.c:165 +#: port/pg_shmem.c:197 port/sysv_shmem.c:197 #, c-format -msgid "Failed system call was shmget(key=%lu, size=%lu, 0%o)." -msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯shmget(key=%lu, size=%lu, 0%o)ã§ã—ãŸã€‚" +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯shmget(key=%lu, size=%zu, 0%o)ã§ã™ã€‚" -#: port/pg_shmem.c:169 port/sysv_shmem.c:169 +#: port/pg_shmem.c:201 port/sysv_shmem.c:201 #, c-format -#| msgid "" -#| "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space, or exceeded your kernel's SHMALL parameter. You can either reduce the request size or reconfigure the kernel with larger SHMALL. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.\n" -#| "The PostgreSQL documentation contains more information about shared memory configuration." msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" "The PostgreSQL documentation contains more information about shared memory configuration." @@ -12208,637 +16216,634 @@ msgstr "" "通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQLãŒè¦æ±‚ã™ã‚‹å…±æœ‰ãƒ¡ãƒ¢ãƒªã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒã‚«ãƒ¼ãƒãƒ«ã®SHMMAXパラメータを超ãˆãŸå ´åˆã€ã¾ãŸã¯å¯èƒ½æ€§ã¨ã—ã¦ã¯ã‚«ãƒ¼ãƒãƒ«ã®SHMMINパラメータよりå°ã•ã„å ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚\n" "共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" -#: port/pg_shmem.c:176 port/sysv_shmem.c:176 +#: port/pg_shmem.c:208 port/sysv_shmem.c:208 #, c-format -#| msgid "" -#| "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space, or exceeded your kernel's SHMALL parameter. You can either reduce the request size or reconfigure the kernel with larger SHMALL. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.\n" -#| "The PostgreSQL documentation contains more information about shared memory configuration." msgid "" "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" "The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQLãŒè¦æ±‚ã™ã‚‹å…±æœ‰ãƒ¡ãƒ¢ãƒªã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒã‚«ãƒ¼ãƒãƒ«ã® SHMALL パラメータを超ãˆãŸå ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚カーãƒãƒ«ã‚’冿§‹ç¯‰ã—ã€ã‚«ãƒ¼ãƒãƒ«ã®SHMALLを増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n" -"共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" +"通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQLãŒè¦æ±‚ã™ã‚‹å…±æœ‰ãƒ¡ãƒ¢ãƒªã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒã‚«ãƒ¼ãƒãƒ«ã®SHMALLパラメータを超ãˆãŸå ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚より大ããªSHMALLã§ã‚«ãƒ¼ãƒãƒ«ã‚’å†è¨­å®šã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n" +"ã“れ以上ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã®è¨­å®šã«é–¢ã™ã‚‹æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" -#: port/pg_shmem.c:182 port/sysv_shmem.c:182 +#: port/pg_shmem.c:214 port/sysv_shmem.c:214 #, c-format -#| msgid "" -#| "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached. If you cannot increase the shared memory limit, reduce PostgreSQL's shared memory request (currently %lu bytes), perhaps by reducing shared_buffers or max_connections.\n" -#| "The PostgreSQL documentation contains more information about shared memory configuration." msgid "" "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" "The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"ã“ã®ã‚¨ãƒ©ãƒ¼ãŒèµ·ã“ã£ãŸã‹ã‚‰ã¨ã„ã£ã¦ã€åˆ¥ã«ãƒ‡ã‚£ã‚¹ã‚¯ãŒè¶³ã‚Šãªããªã£ãŸã‚ã‘ã§ã¯ã‚りã¾ã›ã‚“。ã“ã®åŽŸå› ã®ã²ã¨ã¤ã¯å…±æœ‰ãƒ¡ãƒ¢ãƒªã®è­˜åˆ¥å­ã‚’使ã„ãã£ãŸå ´åˆã§ã™ãŒã€ã“ã®å ´åˆã¯ã‚«ãƒ¼ãƒãƒ«ã® SHMMNI を増やã™å¿…è¦ã‚ã‚りã¾ã™ã€‚ã‚‚ã†ã²ã¨ã¤ã®å¯èƒ½æ€§ã¯ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã‚’使ã„ãã£ãŸå ´åˆã§ã™ã€‚\n" -"共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" +"ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ãƒ‡ã‚£ã‚¹ã‚¯ã®å®¹é‡ä¸è¶³ã‚’æ„味ã—ã¦ã„ã¾ã›ã‚“。ã“ã®ã‚¨ãƒ©ãƒ¼ã®è¦å› ã®ä¸€ã¤ã¯å…±æœ‰ãƒ¡ãƒ¢ãƒªã®è­˜åˆ¥å­ã®æž¯æ¸‡ã§ã™ã€‚ã“ã®å ´åˆã¯ã‚«ãƒ¼ãƒãƒ«ã®SHMMNIパラメータを増やã™å¿…è¦ãŒã‚りã¾ã™ãŒã€ãã†ã§ãªã‘れã°è¦å› ã¯ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã®åˆ¶é™ã¸åˆ°é”ã¨ãªã‚Šã¾ã™ã€‚\n" +"ã“れ以上ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã®è¨­å®šã«é–¢ã™ã‚‹æƒ…å ±ã¯ã€PostgreSQLã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" -#: port/pg_shmem.c:417 port/sysv_shmem.c:417 +#: port/pg_shmem.c:505 port/sysv_shmem.c:505 #, c-format -#| msgid "could not create shared memory segment: %m" msgid "could not map anonymous shared memory: %m" msgstr "匿å共有メモリをマップã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: port/pg_shmem.c:419 port/sysv_shmem.c:419 +#: port/pg_shmem.c:507 port/sysv_shmem.c:507 #, c-format -#| msgid "" -#| "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space, or exceeded your kernel's SHMALL parameter. You can either reduce the request size or reconfigure the kernel with larger SHMALL. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.\n" -#| "The PostgreSQL documentation contains more information about shared memory configuration." -msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory or swap space. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." -msgstr "通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQL ãŒè¦æ±‚ã™ã‚‹å…±æœ‰ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºãŒåˆ©ç”¨å¯èƒ½ãªãƒ¡ãƒ¢ãƒªã‚„スワップ容é‡ã‚’è¶…ãˆãŸå ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚è¦æ±‚サイズ(ç¾åœ¨ %lu ãƒã‚¤ãƒˆï¼‰ã‚’減らã™ã«ã¯ã€PostgreSQL ã® shared_buffers ã¾ãŸã¯ max_connections を減らã™ã“ã¨ã§PostgreSQLã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºã‚’減らã—ã¦ãã ã•ã„。" +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQL ãŒè¦æ±‚ã™ã‚‹å…±æœ‰ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºãŒåˆ©ç”¨å¯èƒ½ãªãƒ¡ãƒ¢ãƒªã‚„スワップ容é‡ã€ãªã„ã—ã¯ãƒ’ュージページを超ãˆãŸå ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚è¦æ±‚サイズ(ç¾åœ¨ %zu ãƒã‚¤ãƒˆï¼‰ã‚’減らã™ãŸã‚ã«ã€shared_buffers ã¾ãŸã¯ max_connections を減らã™ã“ã¨ã§PostgreSQLã®å…±æœ‰ãƒ¡ãƒ¢ãƒªã®ä½¿ç”¨é‡ã‚’減らã—ã¦ãã ã•ã„。" -#: port/pg_shmem.c:505 port/sysv_shmem.c:505 +#: port/pg_shmem.c:573 port/sysv_shmem.c:573 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ãƒ’ュージページをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: port/pg_shmem.c:668 port/sysv_shmem.c:668 #, c-format msgid "could not stat data directory \"%s\": %m" -msgstr "データディレクトリ\"%s\"ã‚’statã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "データディレクトリ\"%s\"ã®statã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: port/sysv_sema.c:123 +#, c-format +msgid "could not create semaphores: %m" +msgstr "セマフォを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: port/sysv_sema.c:124 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯semget(%lu, %d, 0%o)ã§ã™ã€‚" + +#: port/sysv_sema.c:128 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€ãƒ‡ã‚£ã‚¹ã‚¯ãŒè¶³ã‚Šãªããªã£ãŸã“ã¨ã‚’æ„味ã—ã¦ã„ã¾ã›ã‚“。ã“ã®åŽŸå› ã¯ã‚»ãƒžãƒ•ォセット数ãŒä¸Šé™(SEMMNI)ã«é”ã—ãŸã‹ã€ã¾ãŸã¯ã‚·ã‚¹ãƒ†ãƒ å…¨ä½“ã§ã®ã‚»ãƒžãƒ•ォ数を上é™ã¾ã§(SEMMNS)を使ã„ãã£ãŸå ´åˆã§ã™ã€‚対処ã¨ã—ã¦ã¯ã€å¯¾å¿œã™ã‚‹ã‚«ãƒ¼ãƒãƒ«ã®ãƒ‘ラメータを増やã™å¿…è¦ãŒã‚りã¾ã™ã€‚ã‚‚ã—ã㯠PostgreSQLã® max_connections を減らã™ã“ã¨ã§ã€æ¶ˆè²»ã™ã‚‹ã‚»ãƒžãƒ•ã‚©ã®æ•°ã‚’減らã—ã¦ãã ã•ã„。\n" +"共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" + +#: port/sysv_sema.c:158 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "" +"ãŠãらãカーãƒãƒ«ã®SEMVMX値を最低ã§ã‚‚%dã¾ã§å¢—ã‚„ã™å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"詳細ã¯PostgreSQLã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’調ã¹ã¦ãã ã•ã„。" -#: port/win32/crashdump.c:108 +#: port/win32/crashdump.c:121 #, c-format msgid "could not load dbghelp.dll, cannot write crash dump\n" msgstr "dbghelp.dll をロードã§ããšã€ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ãƒ€ãƒ³ãƒ—も書ãè¾¼ã‚ã¾ã›ã‚“\n" -#: port/win32/crashdump.c:116 +#: port/win32/crashdump.c:129 #, c-format msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" -msgstr "dbghelp.dll ã§è¦æ±‚ã•れãŸé–¢æ•°ã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸã€‚クラッシュダンプを書ãè¾¼ã‚ã¾ã›ã‚“\n" +msgstr "dbghelp.dll ã§å¿…è¦ã¨ã™ã‚‹é–¢æ•°ã‚’ロードã§ãã¾ã›ã‚“ã§ã—ãŸã€‚クラッシュダンプを書ãè¾¼ã‚ã¾ã›ã‚“\n" -#: port/win32/crashdump.c:147 +#: port/win32/crashdump.c:160 #, c-format msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" -msgstr "クラッシュダンプファイル\"%s\"を書ãè¾¼ã¿ç”¨ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸï¼šã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ %lu\n" +msgstr "クラッシュダンプファイル\"%s\"を書ãè¾¼ã¿ç”¨ã«ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" -#: port/win32/crashdump.c:154 +#: port/win32/crashdump.c:167 #, c-format msgid "wrote crash dump to file \"%s\"\n" msgstr "クラッシュダンプを\"%s\"ã«æ›¸ãè¾¼ã¿ã¾ã—ãŸ\n" -#: port/win32/crashdump.c:156 +#: port/win32/crashdump.c:169 #, c-format msgid "could not write crash dump to file \"%s\": error code %lu\n" -msgstr "クラッシュダンプを\"%s\"ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸï¼šã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ %lu\n" - -#: port/win32/security.c:43 -#, c-format -msgid "could not open process token: error code %lu\n" -msgstr "プロセストークンをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" - -#: port/win32/security.c:63 -#, c-format -msgid "could not get SID for Administrators group: error code %lu\n" -msgstr "管ç†è€…グループã®SIDを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" - -#: port/win32/security.c:72 -#, c-format -msgid "could not get SID for PowerUsers group: error code %lu\n" -msgstr "PowerUsersグループã®SIDを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" +msgstr "クラッシュダンプã®\"%s\"ã¸ã®æ›¸ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: port/win32/signal.c:193 +#: port/win32/signal.c:194 #, c-format msgid "could not create signal listener pipe for PID %d: error code %lu" msgstr "pid %dã«å¯¾ã™ã‚‹ã‚·ã‚°ãƒŠãƒ«ç›£è¦–パイプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: port/win32/signal.c:273 port/win32/signal.c:305 +#: port/win32/signal.c:274 port/win32/signal.c:306 #, c-format msgid "could not create signal listener pipe: error code %lu; retrying\n" -msgstr "シグナル監視パイプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu: å†å®Ÿè¡Œä¸­\n" +msgstr "シグナル監視パイプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu: å†å®Ÿè¡Œã—ã¾ã™\n" -#: port/win32/signal.c:316 +#: port/win32/signal.c:317 #, c-format msgid "could not create signal dispatch thread: error code %lu\n" msgstr "シグナルディスパッãƒç”¨ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" -#: port/win32_sema.c:94 +#: port/win32_sema.c:104 #, c-format msgid "could not create semaphore: error code %lu" msgstr "セマフォを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: port/win32_sema.c:165 +#: port/win32_sema.c:181 #, c-format msgid "could not lock semaphore: error code %lu" msgstr "セマフォをロックã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: port/win32_sema.c:178 +#: port/win32_sema.c:201 #, c-format msgid "could not unlock semaphore: error code %lu" msgstr "セマフォã®ãƒ­ãƒƒã‚¯ã‚’解除ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: port/win32_sema.c:207 +#: port/win32_sema.c:231 #, c-format msgid "could not try-lock semaphore: error code %lu" -msgstr "セマフォã®ãƒ­ãƒƒã‚¯ã‚’試ã¿ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" +msgstr "セマフォã®ãƒ­ãƒƒã‚¯è©¦è¡Œã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu" + +#: port/win32_shmem.c:122 port/win32_shmem.c:130 port/win32_shmem.c:142 +#: port/win32_shmem.c:157 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "Lock Pages in Memoryユーザ権é™ã‚’有効ã«ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" + +#: port/win32_shmem.c:123 port/win32_shmem.c:131 port/win32_shmem.c:143 +#: port/win32_shmem.c:158 +#, c-format +msgid "Failed system call was %s." +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯ %s ã§ã™ã€‚" + +#: port/win32_shmem.c:153 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "Lock Pages in Memoryユーザ権é™ã‚’有効ã«ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: port/win32_shmem.c:154 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "PostgreSQL を実行ã™ã‚‹Windowsユーザアカウント㫠Lock Pages in Memory 権é™ã‚’付与ã—ã¦ãã ã•ã„。" + +#: port/win32_shmem.c:210 +#, c-format +msgid "the processor does not support large pages" +msgstr "ã“ã®ãƒ—ロセッサã¯ãƒ©ãƒ¼ã‚¸ãƒšãƒ¼ã‚¸ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: port/win32_shmem.c:212 port/win32_shmem.c:217 +#, c-format +msgid "disabling huge pages" +msgstr "ヒュージページを無効ã«ã—ã¾ã™" -#: port/win32_shmem.c:168 port/win32_shmem.c:203 port/win32_shmem.c:224 +#: port/win32_shmem.c:279 port/win32_shmem.c:315 port/win32_shmem.c:333 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "共有メモリセグメントを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: port/win32_shmem.c:169 +#: port/win32_shmem.c:280 #, c-format -msgid "Failed system call was CreateFileMapping(size=%lu, name=%s)." -msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯CreateFileMapping(size=%lu, name=%s)ã§ã—ãŸã€‚" +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯CreateFileMapping(size=%zu, name=%s)ã§ã™ã€‚" -#: port/win32_shmem.c:193 +#: port/win32_shmem.c:305 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "既存ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªãƒ–ロックã¯ã¾ã ä½¿ç”¨ä¸­ã§ã™" -#: port/win32_shmem.c:194 +#: port/win32_shmem.c:306 #, c-format msgid "Check if there are any old server processes still running, and terminate them." -msgstr "å¤ã„サーãƒãƒ—ロセスãŒå®Ÿè¡Œä¸­ã§ãªã„ã‹æ¤œæŸ»ã—ã€ãれを終了ã•ã›ã¦ãã ã•ã„" +msgstr "å¤ã„サーãƒãƒ—ロセスを確èªã—ã€å®Ÿè¡Œä¸­ã§ã‚れã°çµ‚了ã•ã›ã¦ãã ã•ã„。" -#: port/win32_shmem.c:204 +#: port/win32_shmem.c:316 #, c-format msgid "Failed system call was DuplicateHandle." -msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯MapViewOfFileExã§ã—ãŸã€‚" +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯MapViewOfFileExã§ã™ã€‚" -#: port/win32_shmem.c:225 +#: port/win32_shmem.c:334 #, c-format msgid "Failed system call was MapViewOfFileEx." -msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯MapViewOfFileExã§ã—ãŸã€‚" +msgstr "失敗ã—ãŸã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ¼ãƒ«ã¯MapViewOfFileExã§ã™ã€‚" -#: postmaster/autovacuum.c:372 +#: postmaster/autovacuum.c:406 #, c-format msgid "could not fork autovacuum launcher process: %m" -msgstr "autovacuum ランãƒãƒ£ãƒ¼ãƒ—ロセスを fork ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "自動VACUUM起動プロセスを fork ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/autovacuum.c:417 +#: postmaster/autovacuum.c:442 #, c-format msgid "autovacuum launcher started" -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ãƒ©ãƒ³ãƒãƒ£ãƒ—ロセス" +msgstr "自動VACUUM起動プロセス" -#: postmaster/autovacuum.c:783 +#: postmaster/autovacuum.c:832 #, c-format msgid "autovacuum launcher shutting down" -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ãƒ©ãƒ³ãƒãƒ£ã‚’åœæ­¢ã—ã¦ã„ã¾ã™" +msgstr "自動VACUUMèµ·å‹•ãƒ—ãƒ­ã‚»ã‚¹ã‚’åœæ­¢ã—ã¦ã„ã¾ã™" -#: postmaster/autovacuum.c:1447 +#: postmaster/autovacuum.c:1494 #, c-format msgid "could not fork autovacuum worker process: %m" -msgstr "autovacuum ワーカープロセスを fork ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "自動VACUUMワーカープロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/autovacuum.c:1666 +#: postmaster/autovacuum.c:1700 #, c-format msgid "autovacuum: processing database \"%s\"" -msgstr "autovacuum: データベース\"%s\"ã®å‡¦ç†ä¸­ã§ã™" +msgstr "自動VACUUM: データベース\"%s\"ã®å‡¦ç†ä¸­ã§ã™" -#: postmaster/autovacuum.c:2060 +#: postmaster/autovacuum.c:2269 #, c-format -msgid "autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "autovacuum: データベース \"%3$s\" ã«ãŠã„ã¦ã€è¦ªãŒãªããªã£ãŸä¸€æ™‚テーブル \"%1$s\".\"%2$s\" を削除ã—ã¦ã„ã¾ã™" +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "自動VACUUM: 孤立ã—ãŸä¸€æ™‚テーブル\"%s.%s.%s\"を削除ã—ã¾ã™" -#: postmaster/autovacuum.c:2072 +#: postmaster/autovacuum.c:2498 #, c-format -msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "autovacuum: データベース \"%3$s\" ã«ãŠã„ã¦ã€è¦ªãŒãªããªã£ãŸä¸€æ™‚テーブル \"%1$s\".\"%2$s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã—ãŸ" +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "テーブル\"%s.%s.%s\"ã«å¯¾ã™ã‚‹è‡ªå‹•VACUUM" -#: postmaster/autovacuum.c:2336 +#: postmaster/autovacuum.c:2501 #, c-format -msgid "automatic vacuum of table \"%s.%s.%s\"" -msgstr "テーブル\"%s.%s.%s\"ã®è‡ªå‹•ãƒã‚­ãƒ¥ãƒ¼ãƒ " +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "テーブル\"%s.%s.%s\"ã«å¯¾ã™ã‚‹è‡ªå‹•ANALYZE" -#: postmaster/autovacuum.c:2339 +#: postmaster/autovacuum.c:2694 #, c-format -msgid "automatic analyze of table \"%s.%s.%s\"" -msgstr "テーブル\"%s.%s.%s\"ã®è‡ªå‹•è§£æž" +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "リレーション\"%s.%s.%s\"ã®ä½œæ¥­ã‚¨ãƒ³ãƒˆãƒªã‚’処ç†ã—ã¦ã„ã¾ã™" -#: postmaster/autovacuum.c:2835 +#: postmaster/autovacuum.c:3273 #, c-format msgid "autovacuum not started because of misconfiguration" -msgstr "誤設定ã®ãŸã‚autovacuumã‚’èµ·å‹•ã§ãã¾ã›ã‚“" +msgstr "誤設定ã®ãŸã‚自動VACUUMãŒèµ·å‹•ã§ãã¾ã›ã‚“" -#: postmaster/autovacuum.c:2836 +#: postmaster/autovacuum.c:3274 #, c-format msgid "Enable the \"track_counts\" option." -msgstr "\"track_counts\"オプションを有効ã«ã—ã¾ã™ã€‚" +msgstr "\"track_counts\"オプションを有効ã«ã—ã¦ãã ã•ã„。" -#: postmaster/bgworker.c:258 postmaster/bgworker.c:371 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\"を登録ã—ã¦ã„ã¾ã™" -#: postmaster/bgworker.c:287 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\"ã®ç™»éŒ²ã‚’解除ã—ã¦ã„ã¾ã™" -#: postmaster/bgworker.c:326 +#: postmaster/bgworker.c:592 #, c-format msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"\"%s: ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šã‚’è¦æ±‚ã™ã‚‹ãŸã‚ã«ã¯å…±æœ‰ãƒ¡ãƒ¢ãƒªã‚’割り当ã¦ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"\"%s: ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šã‚’è¦æ±‚ã™ã‚‹ãŸã‚ã«ã¯å…±æœ‰ãƒ¡ãƒ¢ãƒªã«ã‚¢ã‚¿ãƒƒãƒã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: postmaster/bgworker.c:335 +#: postmaster/bgworker.c:601 #, c-format msgid "background worker \"%s\": cannot request database access if starting at postmaster start" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": postmaster起動時ã«èµ·å‹•ã—ã¦ã„ã‚‹å ´åˆã«ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¢ã‚¯ã‚»ã‚¹ã‚’è¦æ±‚ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": postmaster起動中ã«èµ·å‹•ã—ã¦ã„ã‚‹å ´åˆã«ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¢ã‚¯ã‚»ã‚¹ã‚’è¦æ±‚ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: postmaster/bgworker.c:349 +#: postmaster/bgworker.c:615 #, c-format -#| msgid "%s: invalid status interval \"%s\"\n" msgid "background worker \"%s\": invalid restart interval" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": 無効ãªå†èµ·å‹•é–“éš”" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": 䏿­£ãªå†èµ·å‹•é–“éš”" + +#: postmaster/bgworker.c:630 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": パラレルワーカã¯å†èµ·å‹•ã™ã‚‹ã‚ˆã†ã«è¨­å®šã—ã¦ã¯ã„ã‘ã¾ã›ã‚“" + +#: postmaster/bgworker.c:674 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "管ç†è€…コマンドã«ã‚ˆã‚Šãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\"を終了ã—ã¦ã„ã¾ã™" -#: postmaster/bgworker.c:378 +#: postmaster/bgworker.c:863 #, c-format msgid "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": shared_preload_librariesã«ç™»éŒ²ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: postmaster/bgworker.c:396 +#: postmaster/bgworker.c:875 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\": å‹•çš„ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ã®ã¿ãŒé€šçŸ¥ã‚’è¦æ±‚ã§ãã¾ã™" + +#: postmaster/bgworker.c:890 #, c-format -#| msgid "too many arguments" msgid "too many background workers" msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ãŒå¤šã™ãŽã¾ã™" -#: postmaster/bgworker.c:397 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "Up to %d background workers can be registered with the current settings." msgstr[0] "ç¾åœ¨ã®è¨­å®šã§ã¯æœ€å¤§%dã®ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ã‚’登録ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" msgstr[1] "ç¾åœ¨ã®è¨­å®šã§ã¯æœ€å¤§%dã®ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ã‚’登録ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" -#: postmaster/bgworker.c:401 +#: postmaster/bgworker.c:895 #, c-format -#| msgid "Consider increasing the configuration parameter \"checkpoint_segments\"." msgid "Consider increasing the configuration parameter \"max_worker_processes\"." -msgstr "設定パラメータ\"max_worker_processes\"ã®å¢—加を検討ã—ã¦ãã ã•ã„" +msgstr "設定パラメータ\"max_worker_processes\"を増やã™ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„" -#: postmaster/checkpointer.c:481 +#: postmaster/checkpointer.c:464 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" msgstr[0] "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®ç™ºç”Ÿå‘¨æœŸãŒçŸ­ã™ãŽã¾ã™(%dç§’é–“éš”)" msgstr[1] "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®ç™ºç”Ÿå‘¨æœŸãŒçŸ­ã™ãŽã¾ã™(%dç§’é–“éš”)" -#: postmaster/checkpointer.c:485 -#, c-format -msgid "Consider increasing the configuration parameter \"checkpoint_segments\"." -msgstr "設定パラメータ\"checkpoint_segments\"ã®å¢—加を検討ã—ã¦ãã ã•ã„" - -#: postmaster/checkpointer.c:630 +#: postmaster/checkpointer.c:468 #, c-format -msgid "transaction log switch forced (archive_timeout=%d)" -msgstr "トランザクションログ切り替ãˆãŒå¼·åˆ¶ã•れã¾ã™ï¼ˆarchive_timeout=%d)" +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "設定パラメータ\"max_wal_size\"を増やã™ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„" -#: postmaster/checkpointer.c:1083 +#: postmaster/checkpointer.c:1082 #, c-format msgid "checkpoint request failed" msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆè¦æ±‚ãŒå¤±æ•—ã—ã¾ã—ãŸ" -#: postmaster/checkpointer.c:1084 +#: postmaster/checkpointer.c:1083 #, c-format msgid "Consult recent messages in the server log for details." msgstr "詳細ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã®æœ€è¿‘ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’調査ã—ã¦ãã ã•ã„" -#: postmaster/checkpointer.c:1280 +#: postmaster/checkpointer.c:1278 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "ãŽã£ã—り詰ã¾ã£ãŸ fsync リクエストã®ã‚­ãƒ¥ãƒ¼ã®ã†ã¡ %d ã‹ã‚‰ %d ã¾ã§ã®ã‚¨ãƒ³ãƒˆãƒª" -#: postmaster/pgarch.c:165 +#: postmaster/pgarch.c:148 #, c-format msgid "could not fork archiver: %m" -msgstr "アーカイãƒã‚’forkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "アーカイãƒã®forkã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: postmaster/pgarch.c:491 +#: postmaster/pgarch.c:456 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "archive_modeã¯æœ‰åйã§ã™ãŒã€archive_commandãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" -#: postmaster/pgarch.c:506 +#: postmaster/pgarch.c:484 #, c-format -#| msgid "transaction log file \"%s\" could not be archived: too many failures" -msgid "archiving transaction log file \"%s\" failed too many times, will try again later" -msgstr "トランザクションログファイル\"%s\"ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–処ç†ãŒä½•回も失敗ã—ã¾ã—ãŸã€‚後ã§å†åº¦è©¦ã—ã¾ã™" +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–処ç†ã®å¤±æ•—回数ãŒè¶…éŽã—ã¾ã—ãŸã€å¾Œã§å†åº¦è©¦ã—ã¾ã™" -#: postmaster/pgarch.c:609 +#: postmaster/pgarch.c:585 #, c-format msgid "archive command failed with exit code %d" msgstr "アーカイブコマンドãŒãƒªã‚¿ãƒ¼ãƒ³ã‚³ãƒ¼ãƒ‰ %dã§å¤±æ•—ã—ã¾ã—ãŸ" -#: postmaster/pgarch.c:611 postmaster/pgarch.c:621 postmaster/pgarch.c:628 -#: postmaster/pgarch.c:634 postmaster/pgarch.c:643 +#: postmaster/pgarch.c:587 postmaster/pgarch.c:597 postmaster/pgarch.c:604 +#: postmaster/pgarch.c:610 postmaster/pgarch.c:619 #, c-format msgid "The failed archive command was: %s" msgstr "失敗ã—ãŸã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã‚³ãƒžãƒ³ãƒ‰ã¯æ¬¡ã®ã¨ãŠã‚Šã§ã™: %s" -#: postmaster/pgarch.c:618 +#: postmaster/pgarch.c:594 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "アーカイブコマンドãŒä¾‹å¤–0x%Xã§çµ‚了ã—ã¾ã—ãŸ" -#: postmaster/pgarch.c:620 postmaster/postmaster.c:3259 +#: postmaster/pgarch.c:596 postmaster/postmaster.c:3567 #, c-format msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "16進値ã®èª¬æ˜Žã«ã¤ã„ã¦ã¯C インクルードファイル\"ntstatus.h\"ã‚’å‚ç…§ã—ã¦ãã ã•ã„。" -#: postmaster/pgarch.c:625 +#: postmaster/pgarch.c:601 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "アーカイブコマンドã¯ã‚·ã‚°ãƒŠãƒ«%dã«ã‚ˆã‚Šçµ‚了ã—ã¾ã—ãŸ: %s" -#: postmaster/pgarch.c:632 +#: postmaster/pgarch.c:608 #, c-format msgid "archive command was terminated by signal %d" msgstr "アーカイブコマンドã¯ã‚·ã‚°ãƒŠãƒ«%dã«ã‚ˆã‚Šçµ‚了ã—ã¾ã—ãŸ" -#: postmaster/pgarch.c:641 +#: postmaster/pgarch.c:617 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "アーカイブコマンドã¯ä¸æ˜Žã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹%dã§çµ‚了ã—ã¾ã—ãŸ" -#: postmaster/pgarch.c:653 -#, c-format -msgid "archived transaction log file \"%s\"" -msgstr "トランザクションログファイル\"%s\"をアーカイブã—ã¾ã—ãŸ" - -#: postmaster/pgarch.c:702 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "アーカイブステータスディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: postmaster/pgstat.c:347 +#: postmaster/pgstat.c:395 #, c-format msgid "could not resolve \"localhost\": %s" msgstr "\"localhost\"を解決ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: postmaster/pgstat.c:370 +#: postmaster/pgstat.c:418 #, c-format msgid "trying another address for the statistics collector" msgstr "統計情報コレクタ用ã®åˆ¥ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’試ã¿ã¦ã„ã¾ã™" -#: postmaster/pgstat.c:379 +#: postmaster/pgstat.c:427 #, c-format msgid "could not create socket for statistics collector: %m" msgstr "統計情報コレクタ用ã®ã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:391 +#: postmaster/pgstat.c:439 #, c-format msgid "could not bind socket for statistics collector: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã‚’ãƒã‚¤ãƒ³ãƒ‰ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:402 +#: postmaster/pgstat.c:450 #, c-format msgid "could not get address of socket for statistics collector: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã‹ã‚‰ã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:418 +#: postmaster/pgstat.c:466 #, c-format msgid "could not connect socket for statistics collector: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:439 +#: postmaster/pgstat.c:487 #, c-format msgid "could not send test message on socket for statistics collector: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã«è©¦é¨“メッセージをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:465 +#: postmaster/pgstat.c:513 #, c-format msgid "select() failed in statistics collector: %m" msgstr "統計情報コレクタã§select()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#: postmaster/pgstat.c:480 +#: postmaster/pgstat.c:528 #, c-format msgid "test message did not get through on socket for statistics collector" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã‹ã‚‰è©¦é¨“メッセージを入手ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/pgstat.c:495 +#: postmaster/pgstat.c:543 #, c-format msgid "could not receive test message on socket for statistics collector: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã‹ã‚‰è©¦é¨“メッセージをå—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:505 +#: postmaster/pgstat.c:553 #, c-format msgid "incorrect test message transmission on socket for statistics collector" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã§ã®è©¦é¨“メッセージã®é€ä¿¡ãŒä¸æ­£ã§ã™" -#: postmaster/pgstat.c:528 +#: postmaster/pgstat.c:576 #, c-format msgid "could not set statistics collector socket to nonblocking mode: %m" msgstr "統計情報コレクタã®ã‚½ã‚±ãƒƒãƒˆã‚’éžãƒ–ロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:538 +#: postmaster/pgstat.c:615 #, c-format msgid "disabling statistics collector for lack of working socket" msgstr "ä½œæ¥­ç”¨ã‚½ã‚±ãƒƒãƒˆã®æ¬ è½ã®ãŸã‚統計情報コレクタを無効ã«ã—ã¦ã„ã¾ã™" -#: postmaster/pgstat.c:665 +#: postmaster/pgstat.c:762 #, c-format msgid "could not fork statistics collector: %m" msgstr "統計情報コレクタをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:1204 postmaster/pgstat.c:1228 postmaster/pgstat.c:1259 -#, c-format -msgid "must be superuser to reset statistics counters" -msgstr "統計情報カウンタをリセットã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#: postmaster/pgstat.c:1235 +#: postmaster/pgstat.c:1342 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "èªè­˜ã§ããªã„リセットターゲット: \"%s\"" -#: postmaster/pgstat.c:1236 +#: postmaster/pgstat.c:1343 #, c-format -msgid "Target must be \"bgwriter\"." -msgstr "ターゲット㯠\"bgwriter\" ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "対象ã¯\"archiver\"ã¾ãŸã¯\"bgwriter\"ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: postmaster/pgstat.c:3181 +#: postmaster/pgstat.c:4362 #, c-format msgid "could not read statistics message: %m" msgstr "統計情報メッセージを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3510 postmaster/pgstat.c:3680 +#: postmaster/pgstat.c:4694 postmaster/pgstat.c:4851 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "一時統計情報ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3572 postmaster/pgstat.c:3725 +#: postmaster/pgstat.c:4761 postmaster/pgstat.c:4896 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "一時統計情報ファイル\"%s\"ã«æ›¸ãè¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3581 postmaster/pgstat.c:3734 +#: postmaster/pgstat.c:4770 postmaster/pgstat.c:4905 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "一時統計情報ファイル\"%s\"をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3589 postmaster/pgstat.c:3742 +#: postmaster/pgstat.c:4778 postmaster/pgstat.c:4913 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "一時統計情報ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3823 postmaster/pgstat.c:3998 postmaster/pgstat.c:4152 +#: postmaster/pgstat.c:5002 postmaster/pgstat.c:5208 postmaster/pgstat.c:5361 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "統計情報ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: postmaster/pgstat.c:3835 postmaster/pgstat.c:3845 postmaster/pgstat.c:3866 -#: postmaster/pgstat.c:3881 postmaster/pgstat.c:3939 postmaster/pgstat.c:4010 -#: postmaster/pgstat.c:4030 postmaster/pgstat.c:4048 postmaster/pgstat.c:4064 -#: postmaster/pgstat.c:4082 postmaster/pgstat.c:4098 postmaster/pgstat.c:4164 -#: postmaster/pgstat.c:4176 postmaster/pgstat.c:4201 postmaster/pgstat.c:4223 +#: postmaster/pgstat.c:5014 postmaster/pgstat.c:5024 postmaster/pgstat.c:5045 +#: postmaster/pgstat.c:5067 postmaster/pgstat.c:5082 postmaster/pgstat.c:5145 +#: postmaster/pgstat.c:5220 postmaster/pgstat.c:5240 postmaster/pgstat.c:5258 +#: postmaster/pgstat.c:5274 postmaster/pgstat.c:5292 postmaster/pgstat.c:5308 +#: postmaster/pgstat.c:5373 postmaster/pgstat.c:5385 postmaster/pgstat.c:5397 +#: postmaster/pgstat.c:5422 postmaster/pgstat.c:5444 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "統計情報ファイル \"%s\" ãŒç ´æã—ã¦ã„ã¾ã™" -#: postmaster/pgstat.c:4650 +#: postmaster/pgstat.c:5573 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "統計情報コレクタãŒå¿œç­”ã—ãªã„ãŸã‚ã€æœ€æ–°ã®çµ±è¨ˆå€¤ã®æ›¿ã‚りã«å¤ã„値を使用ã—ã¾ã™" + +#: postmaster/pgstat.c:5900 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "æ•´ç†å‡¦ç†ã«ãŠã„ã¦ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒãƒƒã‚·ãƒ¥ãƒ†ãƒ¼ãƒ–ルãŒç ´æã—ã¾ã—㟠--- 中断ã—ã¾ã™" -#: postmaster/postmaster.c:636 +#: postmaster/postmaster.c:717 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" -msgstr "%s: -fオプションã®ç„¡åйãªå¼•æ•°: \"%s\"\n" +msgstr "%s: -fオプションã«å¯¾ã™ã‚‹ä¸æ­£ãªå¼•æ•°: \"%s\"\n" -#: postmaster/postmaster.c:722 +#: postmaster/postmaster.c:803 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" -msgstr "%s: -tオプションã®ç„¡åйãªå¼•æ•°: \"%s\"\n" +msgstr "%s: -tオプションã«å¯¾ã™ã‚‹ä¸æ­£ãªå¼•æ•°: \"%s\"\n" -#: postmaster/postmaster.c:773 +#: postmaster/postmaster.c:854 #, c-format msgid "%s: invalid argument: \"%s\"\n" -msgstr "%s: 無効ãªå¼•æ•°: \"%s\"\n" - -#: postmaster/postmaster.c:808 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s: superuser_reserved_connectionsã¯max_connectionsよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgstr "%s: 䏿­£ãªå¼•æ•°: \"%s\"\n" -#: postmaster/postmaster.c:813 +#: postmaster/postmaster.c:896 #, c-format -#| msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_sendersã¯max_connectionsよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) 㨠max_wal_senders (%d) ã®åˆè¨ˆã¯ max_connections (%d) よりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: postmaster/postmaster.c:818 +#: postmaster/postmaster.c:903 #, c-format -msgid "WAL archival (archive_mode=on) requires wal_level \"archive\" or \"hot_standby\"" -msgstr "WAL アーカイブ(archive_mode=on) ã§ã¯ wal_level ã‚’ \"archive\" ã¾ãŸã¯ \"hot_standby\" ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "wal_levelãŒ\"minimal\"ã®æ™‚ã¯WALã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã¯æœ‰åйã«ã§ãã¾ã›ã‚“" -#: postmaster/postmaster.c:821 +#: postmaster/postmaster.c:906 #, c-format -msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"archive\" or \"hot_standby\"" -msgstr "WAL ストリーミング(max_wal_senders > 0) ã§ã¯ wal_level ã‚’ \"archive\" ã¾ãŸã¯ \"hot_standby\" ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WALストリーミング(max_wal_senders > 0)を行ã†ã«ã¯ wal_levelã‚’\"replica\"ã¾ãŸã¯\"logical\"ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: postmaster/postmaster.c:829 +#: postmaster/postmaster.c:914 #, c-format msgid "%s: invalid datetoken tables, please fix\n" -msgstr "%s: データトークンテーブルãŒç„¡åйã§ã™ã€‚修復ã—ã¦ãã ã•ã„\n" +msgstr "%s: データトークンテーブルãŒä¸æ­£ã§ã™ã€ä¿®å¾©ã—ã¦ãã ã•ã„\n" -#: postmaster/postmaster.c:911 +#: postmaster/postmaster.c:1028 postmaster/postmaster.c:1126 +#: utils/init/miscinit.c:1555 #, c-format -msgid "invalid list syntax for \"listen_addresses\"" -msgstr "\"listen_addresses\"用ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒç„¡åйã§ã™" +msgid "invalid list syntax in parameter \"%s\"" +msgstr "パラメータ\"%s\"ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒä¸æ­£ã§ã™" -#: postmaster/postmaster.c:941 +#: postmaster/postmaster.c:1059 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "\"%s\"ã«é–¢ã™ã‚‹ç›£è¦–用ソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:947 +#: postmaster/postmaster.c:1065 #, c-format msgid "could not create any TCP/IP sockets" msgstr "TCP/IPソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1008 -#, c-format -#| msgid "invalid list syntax for \"listen_addresses\"" -msgid "invalid list syntax for \"unix_socket_directories\"" -msgstr "\"unix_socket_directories\"用ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒç„¡åйã§ã™" - -#: postmaster/postmaster.c:1029 +#: postmaster/postmaster.c:1148 #, c-format -#| msgid "could not create Unix-domain socket" msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "ディレクトリ\"%s\"ã«ãŠã„ã¦Unixドメインソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1035 +#: postmaster/postmaster.c:1154 #, c-format -#| msgid "could not create Unix-domain socket" msgid "could not create any Unix-domain sockets" msgstr "Unixドメインソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1047 +#: postmaster/postmaster.c:1166 #, c-format msgid "no socket created for listening" msgstr "監視用ã«ä½œæˆã™ã‚‹ã‚½ã‚±ãƒƒãƒˆã¯ã‚りã¾ã›ã‚“" -#: postmaster/postmaster.c:1087 +#: postmaster/postmaster.c:1206 #, c-format msgid "could not create I/O completion port for child queue" msgstr "å­ã‚­ãƒ¥ãƒ¼å‘ã‘ã®I/O終了ãƒãƒ¼ãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1116 +#: postmaster/postmaster.c:1235 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: 外部PIDファイル\"%s\"ã®æ¨©é™ã‚’変更ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: postmaster/postmaster.c:1120 +#: postmaster/postmaster.c:1239 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: 外部PIDファイル\"%s\"ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: postmaster/postmaster.c:1174 +#: postmaster/postmaster.c:1296 #, c-format msgid "ending log output to stderr" msgstr "標準エラー出力ã¸ã®ãƒ­ã‚°å‡ºåŠ›ã‚’çµ‚äº†ã—ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:1175 +#: postmaster/postmaster.c:1297 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "ã“ã®å¾Œã®ãƒ­ã‚°å‡ºåŠ›ã¯ãƒ­ã‚°é…é€å…ˆ\"%s\"ã«å‡ºåŠ›ã•れã¾ã™ã€‚" -#: postmaster/postmaster.c:1201 utils/init/postinit.c:199 +#: postmaster/postmaster.c:1323 utils/init/postinit.c:214 #, c-format msgid "could not load pg_hba.conf" msgstr "pg_hba.conf ã®èª­ã¿è¾¼ã¿ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1277 -#, c-format -msgid "%s: could not locate matching postgres executable" -msgstr "%s: 一致ã™ã‚‹postgres実行ファイルãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" - -#: postmaster/postmaster.c:1300 utils/misc/tzparser.c:325 -#, c-format -msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." -msgstr "ã“れã¯ã€PostgreSQLã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒä¸å®Œå…¨ã§ã‚ã‚‹ã‹ã¾ãŸã¯ã€ãƒ•ァイル\"%s\"ãŒæœ¬æ¥ã®å ´æ‰€ã‹ã‚‰ãªããªã£ã¦ã—ã¾ã£ãŸã“ã¨ã‚’示ã—ã¦ã„ã¾ã™ã€‚" - -#: postmaster/postmaster.c:1328 +#: postmaster/postmaster.c:1349 #, c-format -msgid "data directory \"%s\" does not exist" -msgstr "データディレクトリ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgid "postmaster became multithreaded during startup" +msgstr "postmasterã¯èµ·å‹•値処ç†ä¸­ã¯ãƒžãƒ«ãƒã‚¹ãƒ¬ãƒƒãƒ‰ã§å‹•作ã—ã¾ã™" -#: postmaster/postmaster.c:1333 +#: postmaster/postmaster.c:1350 #, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "ディレクトリ\"%s\"ã®æ¨©é™ã‚’読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "LC_ALL環境変数を使用å¯èƒ½ãªãƒ­ã‚±ãƒ¼ãƒ«ã«è¨­å®šã—ã¦ãã ã•ã„。" -#: postmaster/postmaster.c:1341 +#: postmaster/postmaster.c:1455 #, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "指定ã•れãŸãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" - -#: postmaster/postmaster.c:1357 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "データディレクトリ\"%s\"ã®æ‰€æœ‰è€…情報ãŒé–“é•ã£ã¦ã„ã¾ã™" - -#: postmaster/postmaster.c:1359 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "データディレクトリを所有ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãŒã‚µãƒ¼ãƒã‚’èµ·å‹•ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" - -#: postmaster/postmaster.c:1379 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "データディレクトリ\"%s\"ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ç¬¬ä¸‰è€…ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã™" +msgid "%s: could not locate matching postgres executable" +msgstr "%s: 一致ã™ã‚‹postgres実行ファイルãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:1381 +#: postmaster/postmaster.c:1478 utils/misc/tzparser.c:341 #, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "権é™ã¯u=rwx(0700)ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "ã“れã¯ã€PostgreSQLã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãŒä¸å®Œå…¨ã§ã‚ã‚‹ã‹ã¾ãŸã¯ã€ãƒ•ァイル\"%s\"ãŒæœ¬æ¥ã®å ´æ‰€ã‹ã‚‰ãªããªã£ã¦ã—ã¾ã£ãŸã“ã¨ã‚’示ã—ã¦ã„ã¾ã™ã€‚" -#: postmaster/postmaster.c:1392 +#: postmaster/postmaster.c:1505 #, c-format msgid "" "%s: could not find the database system\n" @@ -12849,1851 +16854,2972 @@ msgstr "" "ディレクトリ\"%s\"ã«ã‚ã‚‹ã‚‚ã®ã¨æƒ³å®šã—ã¦ã„ã¾ã—ãŸãŒã€\n" "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: postmaster/postmaster.c:1557 +#: postmaster/postmaster.c:1682 #, c-format msgid "select() failed in postmaster: %m" msgstr "postmasterã§select()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#: postmaster/postmaster.c:1749 postmaster/postmaster.c:1780 +#: postmaster/postmaster.c:1837 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "データディレクトリã®ãƒ­ãƒƒã‚¯ãƒ•ァイルãŒä¸æ­£ãªãŸã‚ã€å³æ™‚シャットダウンを実行中ã§ã™" + +#: postmaster/postmaster.c:1915 postmaster/postmaster.c:1946 #, c-format msgid "incomplete startup packet" msgstr "開始パケットãŒä¸å®Œå…¨ã§ã™" -#: postmaster/postmaster.c:1761 +#: postmaster/postmaster.c:1927 #, c-format msgid "invalid length of startup packet" -msgstr "開始パケットã®é•·ã•ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªé–‹å§‹ãƒ‘ケット長" -#: postmaster/postmaster.c:1818 +#: postmaster/postmaster.c:1985 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "SSL調åœå¿œç­”ã®é€ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: postmaster/postmaster.c:1847 +#: postmaster/postmaster.c:2011 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "フロントエンドプロトコル%u.%uをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“: サーãƒã¯%u.0ã‹ã‚‰ %u.%uã¾ã§ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™" -#: postmaster/postmaster.c:1898 +#: postmaster/postmaster.c:2075 utils/misc/guc.c:6013 utils/misc/guc.c:6106 +#: utils/misc/guc.c:7432 utils/misc/guc.c:10195 utils/misc/guc.c:10229 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "パラメータ\"%s\"ã®å€¤ãŒä¸æ­£ã§ã™: \"%s\"" + +#: postmaster/postmaster.c:2078 #, c-format -msgid "invalid value for boolean option \"replication\"" -msgstr "ブールオプション \"replication\" ã¯ç„¡åйã§ã™" +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "有効ãªå€¤: \"false\", 0, \"true\", 1, \"database\"。" -#: postmaster/postmaster.c:1918 +#: postmaster/postmaster.c:2108 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" -msgstr "é–‹å§‹ãƒ‘ã‚±ãƒƒãƒˆã®æ§‹æˆãŒç„¡åйã§ã™ã€‚最終ãƒã‚¤ãƒˆã«æƒ³å®šå¤–ã®ã‚¿ãƒ¼ãƒŸãƒãƒ¼ã‚¿ãŒã‚りã¾ã—ãŸ" +msgstr "開始パケットã®é…ç½®ãŒä¸æ­£ã§ã™: 最終ãƒã‚¤ãƒˆã¯ã‚¿ãƒ¼ãƒŸãƒãƒ¼ã‚¿ã§ã‚ã‚‹ã¯ãšã§ã™" -#: postmaster/postmaster.c:1946 +#: postmaster/postmaster.c:2146 #, c-format msgid "no PostgreSQL user name specified in startup packet" -msgstr "é–‹å§‹ãƒ‘ã‚±ãƒƒãƒˆä¸­ã«æŒ‡å®šã•れãŸPostgreSQLユーザåã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "é–‹å§‹ãƒ‘ã‚±ãƒƒãƒˆã§æŒ‡å®šã•れãŸPostgreSQLユーザåã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: postmaster/postmaster.c:2003 +#: postmaster/postmaster.c:2205 #, c-format msgid "the database system is starting up" -msgstr "データベースシステムã¯èµ·å‹•ã—ã¦ã„ã¾ã™" +msgstr "データベースシステムã¯èµ·å‹•中ã§ã™" -#: postmaster/postmaster.c:2008 +#: postmaster/postmaster.c:2210 #, c-format msgid "the database system is shutting down" msgstr "データベースシステムã¯ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:2013 +#: postmaster/postmaster.c:2215 #, c-format msgid "the database system is in recovery mode" msgstr "データベースシステムã¯ãƒªã‚«ãƒãƒªãƒ¢ãƒ¼ãƒ‰ã§ã™" -#: postmaster/postmaster.c:2018 storage/ipc/procarray.c:278 -#: storage/ipc/sinvaladt.c:304 storage/lmgr/proc.c:337 +#: postmaster/postmaster.c:2220 storage/ipc/procarray.c:292 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:346 #, c-format msgid "sorry, too many clients already" msgstr "ç¾åœ¨ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæ•°ãŒå¤šã™ãŽã¾ã™" -#: postmaster/postmaster.c:2080 +#: postmaster/postmaster.c:2310 #, c-format msgid "wrong key in cancel request for process %d" msgstr "プロセス%dã«å¯¾ã™ã‚‹ã‚­ãƒ£ãƒ³ã‚»ãƒ«è¦æ±‚ã«ãŠã„ã¦ã‚­ãƒ¼ãŒé–“é•ã£ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:2088 +#: postmaster/postmaster.c:2318 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "ã‚­ãƒ£ãƒ³ã‚»ãƒ«è¦æ±‚内ã®PID %dãŒã©ã®ãƒ—ロセスã«ã‚‚一致ã—ã¾ã›ã‚“" -#: postmaster/postmaster.c:2308 +#: postmaster/postmaster.c:2529 #, c-format msgid "received SIGHUP, reloading configuration files" msgstr "SIGHUPã‚’å—ã‘å–りã¾ã—ãŸã€‚設定ファイルをリロードã—ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:2334 +#: postmaster/postmaster.c:2554 +#, c-format +msgid "pg_hba.conf was not reloaded" +msgstr "pg_hba.confã¯å†èª­ã¿è¾¼ã¿ã•れã¦ã„ã¾ã›ã‚“" + +#: postmaster/postmaster.c:2558 #, c-format -msgid "pg_hba.conf not reloaded" -msgstr "pg_hba.conf ã¯å†èª­ã¿è¾¼ã¿ã•れã¾ã›ã‚“" +msgid "pg_ident.conf was not reloaded" +msgstr "pg_ident.confã¯å†èª­ã¿è¾¼ã¿ã•れã¦ã„ã¾ã›ã‚“" -#: postmaster/postmaster.c:2338 +#: postmaster/postmaster.c:2568 #, c-format -#| msgid "pg_hba.conf not reloaded" -msgid "pg_ident.conf not reloaded" -msgstr "pg_ident.conf ã¯å†èª­ã¿è¾¼ã¿ã•れã¾ã›ã‚“" +msgid "SSL configuration was not reloaded" +msgstr "SSL設定ã¯å†èª­ã¿è¾¼ã¿ã•れã¦ã„ã¾ã›ã‚“" -#: postmaster/postmaster.c:2379 +#: postmaster/postmaster.c:2616 #, c-format msgid "received smart shutdown request" msgstr "ã‚¹ãƒžãƒ¼ãƒˆã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ" -#: postmaster/postmaster.c:2432 +#: postmaster/postmaster.c:2674 #, c-format msgid "received fast shutdown request" msgstr "é«˜é€Ÿã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ" -#: postmaster/postmaster.c:2458 +#: postmaster/postmaster.c:2707 #, c-format msgid "aborting any active transactions" msgstr "活動中ã®å…¨ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’アボートã—ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:2492 +#: postmaster/postmaster.c:2741 #, c-format msgid "received immediate shutdown request" msgstr "峿™‚ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³è¦æ±‚ã‚’å—ã‘å–りã¾ã—ãŸ" -#: postmaster/postmaster.c:2556 postmaster/postmaster.c:2577 +#: postmaster/postmaster.c:2808 +#, c-format +msgid "shutdown at recovery target" +msgstr "リカãƒãƒªç›®æ¨™ã§ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã™" + +#: postmaster/postmaster.c:2824 postmaster/postmaster.c:2847 msgid "startup process" msgstr "起動プロセス" -#: postmaster/postmaster.c:2559 +#: postmaster/postmaster.c:2827 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "起動プロセスã®å¤±æ•—ã®ãŸã‚起動を中断ã—ã¦ã„ã¾ã™" + +#: postmaster/postmaster.c:2888 +#, c-format +msgid "database system is ready to accept connections" +msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®æŽ¥ç¶šå—ã‘ä»˜ã‘æº–å‚™ãŒæ•´ã„ã¾ã—ãŸã€‚" + +#: postmaster/postmaster.c:2909 +msgid "background writer process" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãƒ—ロセス" + +#: postmaster/postmaster.c:2963 +msgid "checkpointer process" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆå‡¦ç†ãƒ—ロセス" + +#: postmaster/postmaster.c:2979 +msgid "WAL writer process" +msgstr "WALライタプロセス" + +#: postmaster/postmaster.c:2994 +msgid "WAL receiver process" +msgstr "WAL å—信プロセス" + +#: postmaster/postmaster.c:3009 +msgid "autovacuum launcher process" +msgstr "自動VACUUM起動プロセス" + +#: postmaster/postmaster.c:3024 +msgid "archiver process" +msgstr "アーカイãƒãƒ—ロセス" + +#: postmaster/postmaster.c:3040 +msgid "statistics collector process" +msgstr "統計情報åŽé›†ãƒ—ロセス" + +#: postmaster/postmaster.c:3054 +msgid "system logger process" +msgstr "システムログå–得プロセス" + +#: postmaster/postmaster.c:3116 +#, c-format +msgid "background worker \"%s\"" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\"" + +#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 +#: postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 +msgid "server process" +msgstr "サーãƒãƒ—ロセス" + +#: postmaster/postmaster.c:3299 +#, c-format +msgid "terminating any other active server processes" +msgstr "ä»–ã®æ´»å‹•中ã®ã‚µãƒ¼ãƒãƒ—ロセスを終了ã—ã¦ã„ã¾ã™" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3555 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d)ã¯çµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" + +#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 +#: postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 +#: postmaster/postmaster.c:3598 +#, c-format +msgid "Failed process was running: %s" +msgstr "失敗ã—ãŸãƒ—ロセスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã—ãŸ: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3565 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d)ã¯ä¾‹å¤–%Xã§çµ‚了ã—ã¾ã—ãŸ" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3575 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d)ã¯ã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3586 +#, c-format +msgid "%s (PID %d) was terminated by signal %d" +msgstr "%s (PID %d)ã¯ã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3596 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d)ã¯èªè­˜ã§ããªã„ステータス%dã§çµ‚了ã—ã¾ã—ãŸ" + +#: postmaster/postmaster.c:3783 +#, c-format +msgid "abnormal database system shutdown" +msgstr "データベースシステムã¯ç•°å¸¸ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" + +#: postmaster/postmaster.c:3823 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "å…¨ã¦ã®ã‚µãƒ¼ãƒãƒ—ロセスãŒçµ‚了ã—ã¾ã—ãŸ: å†åˆæœŸåŒ–ã—ã¦ã„ã¾ã™" + +#: postmaster/postmaster.c:3993 postmaster/postmaster.c:5418 +#: postmaster/postmaster.c:5782 +#, c-format +msgid "could not generate random cancel key" +msgstr "ランダムãªã‚­ãƒ£ãƒ³ã‚»ãƒ«ã‚­ãƒ¼ã‚’生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: postmaster/postmaster.c:4047 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "æŽ¥ç¶šç”¨ã®æ–°ã—ã„プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:4089 +msgid "could not fork new process for connection: " +msgstr "æŽ¥ç¶šç”¨ã®æ–°ã—ã„プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: postmaster/postmaster.c:4203 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "接続をå—ã‘付ã‘ã¾ã—ãŸ: ホスト=%s ãƒãƒ¼ãƒˆç•ªå·=%s" + +#: postmaster/postmaster.c:4208 +#, c-format +msgid "connection received: host=%s" +msgstr "接続をå—ã‘付ã‘ã¾ã—ãŸ: ホスト=%s" + +#: postmaster/postmaster.c:4493 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "サーãƒãƒ—ロセス\"%s\"を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:4646 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "共有メモリã®ç¢ºä¿ã®ãƒªãƒˆãƒ©ã‚¤å›žæ•°ãŒå¤šã™ãŽã‚‹ãŸã‚中断ã—ã¾ã™" + +#: postmaster/postmaster.c:4647 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "ã“れã¯ASLRã¾ãŸã¯ã‚¢ãƒ³ãƒã‚¦ã‚¤ãƒ«ã‚¹ã‚½ãƒ•トウェアãŒåŽŸå› ã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" + +#: postmaster/postmaster.c:4858 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "SSLæ§‹æˆã¯å­ãƒ—ロセスã§ã¯èª­ã¿è¾¼ã‚ã¾ã›ã‚“" + +#: postmaster/postmaster.c:4990 +#, c-format +msgid "Please report this to ." +msgstr "ã“れをã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。" + +#: postmaster/postmaster.c:5077 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "データベースシステムã¯ãƒªãƒ¼ãƒ‰ã‚ªãƒ³ãƒªãƒ¼æŽ¥ç¶šã®å—ã‘ä»˜ã‘æº–å‚™ãŒã§ãã¾ã—ãŸ" + +#: postmaster/postmaster.c:5346 +#, c-format +msgid "could not fork startup process: %m" +msgstr "起動プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5350 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãƒ—ロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5354 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆå‡¦ç†ãƒ—ロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5358 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "WALライタプロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5362 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "WAL å—信プロセスを fork ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5366 +#, c-format +msgid "could not fork process: %m" +msgstr "プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:5553 postmaster/postmaster.c:5576 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "登録時ã«ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šã®å¿…è¦æ€§ãŒç¤ºã•れã¦ã„ã¾ã›ã‚“" + +#: postmaster/postmaster.c:5560 postmaster/postmaster.c:5583 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«å†…ã®ä¸æ­£ãªå‡¦ç†ãƒ¢ãƒ¼ãƒ‰" + +#: postmaster/postmaster.c:5655 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ãƒ—ロセス\"%s\"ã‚’èµ·å‹•ã—ã¦ã„ã¾ã™" + +#: postmaster/postmaster.c:5667 +#, c-format +msgid "could not fork worker process: %m" +msgstr "ワーカプロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/postmaster.c:6100 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã§ä½¿ç”¨ã™ã‚‹ãŸã‚ã«ã‚½ã‚±ãƒƒãƒˆ%dを複製ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %d" + +#: postmaster/postmaster.c:6132 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "継承ã—ãŸã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %d\n" + +#: postmaster/postmaster.c:6161 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ãƒ•ァイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: postmaster/postmaster.c:6168 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ãƒ•ァイル\"%s\"ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: postmaster/postmaster.c:6177 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: postmaster/postmaster.c:6194 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ã®ãƒ“ューをマップã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: postmaster/postmaster.c:6203 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ã®ãƒ“ューをアンマップã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: postmaster/postmaster.c:6210 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãƒ‘ラメータ変数ã®ãƒãƒ³ãƒ‰ãƒ«ã‚’クローズã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード%lu\n" + +#: postmaster/postmaster.c:6371 +#, c-format +msgid "could not read exit code for process\n" +msgstr "å­ãƒ—ロセスã®çµ‚了コードã®èª­ã¿è¾¼ã¿ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: postmaster/postmaster.c:6376 +#, c-format +msgid "could not post child completion status\n" +msgstr "個プロセスã®çµ‚了コードを投稿ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: postmaster/syslogger.c:470 postmaster/syslogger.c:1146 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "ロガーパイプã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:520 +#, c-format +msgid "logger shutting down" +msgstr "ãƒ­ã‚¬ãƒ¼ã‚’åœæ­¢ã—ã¦ã„ã¾ã™" + +#: postmaster/syslogger.c:564 postmaster/syslogger.c:578 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "syslog用ã®ãƒ‘イプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:629 +#, c-format +msgid "could not fork system logger: %m" +msgstr "システムロガーをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:665 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "ログ出力をログåŽé›†ãƒ—ロセスã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã—ã¦ã„ã¾ã™" + +#: postmaster/syslogger.c:666 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "ã“ã“ã‹ã‚‰ã®ãƒ­ã‚°å‡ºåŠ›ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã«ç¾ã‚Œã¾ã™ã€‚" + +#: postmaster/syslogger.c:674 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "標準出力ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:679 postmaster/syslogger.c:696 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "標準エラー出力ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:1101 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: postmaster/syslogger.c:1218 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "ロックファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: postmaster/syslogger.c:1280 postmaster/syslogger.c:1330 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "自動ローテーションを無効ã«ã—ã¦ã„ã¾ã™(å†åº¦æœ‰åйã«ã™ã‚‹ã«ã¯SIGHUPを使用ã—ã¦ãã ã•ã„)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "æ­£è¦è¡¨ç¾ã®éš›ã«ã©ã®ç…§åˆè¦å‰‡ã‚’使ã†ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: repl_gram.y:336 repl_gram.y:368 +#, c-format +msgid "invalid timeline %u" +msgstr "タイムライン%uã¯ä¸æ­£ã§ã™" + +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "ストリーミングã®é–‹å§‹ä½ç½®ãŒä¸æ­£ã§ã™" + +#: repl_scanner.l:180 scan.l:683 +msgid "unterminated quoted string" +msgstr "文字列ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" + +#: replication/basebackup.c:343 +#, c-format +msgid "could not stat control file \"%s\": %m" +msgstr "制御ファイル\"%s\"ã®çŠ¶æ…‹ã‚’ç¢ºèªã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: replication/basebackup.c:450 +#, c-format +msgid "could not find any WAL files" +msgstr "WALファイルãŒå…¨ãã‚りã¾ã›ã‚“" + +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "WALファイル\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" + +#: replication/basebackup.c:530 replication/basebackup.c:558 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "想定ã—ãªã„WALファイルã®ã‚µã‚¤ã‚º\"%s\"" + +#: replication/basebackup.c:544 replication/basebackup.c:1536 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を中止ã—ã¦ã„ã¾ã™" + +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr " åˆè¨ˆã§ %s 個ã®ãƒ‡ãƒ¼ã‚¿ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ã‚’検出ã—ã¾ã—ãŸ" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—中ã«ãƒã‚§ãƒƒã‚¯ã‚µãƒ ç¢ºèªãŒå¤±æ•—ã—ã¾ã—ãŸ" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "\"%s\" オプションã¯é‡è¤‡ã—ã¦ã„ã¾ã™" + +#: replication/basebackup.c:717 utils/misc/guc.c:6023 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%dã¯ãƒ‘ラメータ\"%s\"ã®æœ‰åŠ¹ç¯„å›²ã‚’è¶…ãˆã¦ã„ã¾ã™(%d .. %d)" + +#: replication/basebackup.c:991 replication/basebackup.c:1161 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\"ã¨ã„ã†ãƒ•ァイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %m" + +#: replication/basebackup.c:1316 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "スペシャルファイル \"%s\" をスキップã—ã¦ã„ã¾ã™" + +#: replication/basebackup.c:1421 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "ファイル \"%2$s\" ã‚»ã‚°ãƒ¡ãƒ³ãƒˆç•ªå· %1$d ã¯ä¸æ­£ã§ã™" + +#: replication/basebackup.c:1440 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "ファイル \"%s\"ã€ãƒ–ロック %d ã§ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ: 読ã¿è¾¼ã¿ãƒãƒƒãƒ•ァサイズ %d ã¨ãƒšãƒ¼ã‚¸ã‚µã‚¤ã‚º %d ãŒç•°ãªã£ã¦ã„ã¾ã™" + +#: replication/basebackup.c:1484 replication/basebackup.c:1500 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "ファイル \"%s\" ã‚’ fseek ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: replication/basebackup.c:1492 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "ファイル \"%2$s\" ã§ãƒ–ロック %1$d ã®å†èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %3$m" + +#: replication/basebackup.c:1516 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "ファイル\"%s\"ã®ãƒ–ロック%dã§ãƒã‚§ãƒƒã‚¯ã‚µãƒ æ¤œè¨¼ãŒå¤±æ•—ã—ã¾ã—ãŸ: 計算ã•れãŸãƒã‚§ãƒƒã‚¯ã‚µãƒ ã¯%Xã§ã™ãŒæƒ³å®šã¯%Xã§ã™" + +#: replication/basebackup.c:1523 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "ファイル \"%s\" ã§ã®ä»¥é™ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ã¯å ±å‘Šã•れã¾ã›ã‚“" + +#: replication/basebackup.c:1581 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "ファイル \"%s\" ã§ã¯åˆè¨ˆ %d 個ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ" + +#: replication/basebackup.c:1609 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "ファイルåãŒtarフォーマットã«å¯¾ã—ã¦é•·ã™ãŽã¾ã™: \"%s\"" + +#: replication/basebackup.c:1614 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "シンボリックリンクã®ãƒªãƒ³ã‚¯å…ˆtarã®ãƒ•ォーマットã«ã¨ã£ã¦é•·ã™ãŽã¾ã™: ファイルå \"%s\", リンク先 \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "䏿­£ãªæŽ¥ç¶šæ–‡å­—åˆ—ã®æ§‹æ–‡: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 +#, c-format +msgid "could not parse connection string: %s" +msgstr "接続文字列をパースã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "プライマリサーãƒã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®è­˜åˆ¥å­ã¨ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ ID ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 +#: replication/libpqwalreceiver/libpqwalreceiver.c:550 +#, c-format +msgid "invalid response from primary server" +msgstr "プライマリサーãƒã‹ã‚‰ã®å¿œç­”ãŒä¸æ­£ã§ã™" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "システムを識別ã§ãã¾ã›ã‚“ã§ã—ãŸ: å—ä¿¡ã—ãŸã®ã¯%d行ã§%dåˆ—ã€æœŸå¾…ã—ã¦ã„ãŸã®ã¯%d行ã§%d以上ã®åˆ—ã§ã—ãŸã€‚" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 +#: replication/libpqwalreceiver/libpqwalreceiver.c:416 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "WAL ストリーミングを開始ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "プライマリã«ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã®çµ‚了メッセージをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "ストリーミングã®çµ‚äº†å¾Œã®æƒ³å®šå¤–ã®çµæžœã‚»ãƒƒãƒˆ" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "ストリーミングCOPY終了中ã®ã‚¨ãƒ©ãƒ¼: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "ストリーミングコマンドã®çµæžœèª­ã¿å–り中ã®ã‚¨ãƒ©ãƒ¼: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "CommandCompleteå¾Œã®æƒ³å®šå¤–ã®çµæžœ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "プライマリサーãƒã‹ã‚‰ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³å±¥æ­´ãƒ•ァイルをå—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "2個ã®ãƒ•ィールドをæŒã¤1個ã®ã‚¿ãƒ—ルを期待ã—ã¦ã„ã¾ã—ãŸãŒã€%2$d 個ã®ãƒ•ィールドをæŒã¤ %1$d 個ã®ã‚¿ãƒ—ルをå—ä¿¡ã—ã¾ã—ãŸã€‚" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 +#: replication/libpqwalreceiver/libpqwalreceiver.c:756 +#: replication/libpqwalreceiver/libpqwalreceiver.c:762 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "WAL ストリームã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "WAL ストリームã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "レプリケーションスロット\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 +#, c-format +msgid "invalid query response" +msgstr "䏿­£ãªå•ã„åˆã‚ã›å¿œç­”" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d個ã®åˆ—を期待ã—ã¦ã„ã¾ã—ãŸãŒã€%d列をå—ä¿¡ã—ã¾ã—ãŸã€‚" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 +#, c-format +msgid "the query interface requires a database connection" +msgstr "クエリインタフェースã®å‹•作ã«ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚³ãƒã‚¯ã‚·ãƒ§ãƒ³ãŒå¿…è¦ã§ã™" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 +msgid "empty query" +msgstr "空ã®å•ã„åˆã‚ã›" + +#: replication/logical/launcher.c:310 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "サブスクリプション\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションワーカを起動ã—ã¾ã™" + +#: replication/logical/launcher.c:317 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "max_replication_slots = 0 ã®æ™‚ã¯è«–ç†ãƒ¬ãƒ—リケーションワーカã¯èµ·å‹•ã§ãã¾ã›ã‚“" + +#: replication/logical/launcher.c:397 +#, c-format +msgid "out of logical replication worker slots" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションワーカスロットã¯å…¨ã¦ä½¿ç”¨ä¸­ã§ã™" + +#: replication/logical/launcher.c:398 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "max_logical_replication_workersを増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。" + +#: replication/logical/launcher.c:453 +#, c-format +msgid "out of background worker slots" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ã‚¹ãƒ­ãƒƒãƒˆãŒè¶³ã‚Šã¾ã›ã‚“" + +#: replication/logical/launcher.c:454 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "max_worker_processesを増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" + +#: replication/logical/launcher.c:661 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションワーカスロット%dãŒç©ºã„ã¦ã„ãªã„ãŸã‚接続ã§ãã¾ã›ã‚“" + +#: replication/logical/launcher.c:670 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションワーカスロット%dãŒæ—¢ã«ä»–ã®ãƒ¯ãƒ¼ã‚«ã«ä½¿ç”¨ã•れã¦ã„ã‚‹ãŸã‚接続ã§ãã¾ã›ã‚“" + +#: replication/logical/launcher.c:988 +#, c-format +msgid "logical replication launcher started" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションランãƒãƒ£ãŒèµ·å‹•ã—ã¾ã—ãŸ" + +#: replication/logical/logical.c:90 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚’行ã†ãŸã‚ã«ã¯ wal_level >= logical ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: replication/logical/logical.c:95 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚’行ã†ã«ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šãŒå¿…è¦ã§ã™" + +#: replication/logical/logical.c:113 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "リカãƒãƒªä¸­ã¯è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: replication/logical/logical.c:255 replication/logical/logical.c:386 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "物ç†ãƒ¬ãƒ—リケーションスロットを論ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã«ä½¿ç”¨ã™ã‚‹ã¨ã¯ã§ãã¾ã›ã‚“" + +#: replication/logical/logical.c:260 replication/logical/logical.c:391 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "レプリケーションスロット\"%s\"ã¯ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§ã¯ä½œæˆã•れã¦ã„ã¾ã›ã‚“" + +#: replication/logical/logical.c:267 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "è«–ç†ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚¹ãƒ­ãƒƒãƒˆã¯æ›¸ãè¾¼ã¿ã‚’行ã£ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ä¸­ã§ç”Ÿæˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: replication/logical/logical.c:431 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "スロット\"%s\"ã®è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚’é–‹å§‹ã—ã¾ã™" + +#: replication/logical/logical.c:433 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "%3$X/%4$Xã‹ã‚‰WALを読ã¿å–ã£ã¦ã€%1$X/%2$X以é™ã«ã‚³ãƒŸãƒƒãƒˆã•れるトランザクションをストリーミングã—ã¾ã™ã€‚" + +#: replication/logical/logical.c:583 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールãƒãƒƒã‚¯ã®å‡¦ç†ä¸­, 関連LSN %X/%X" + +#: replication/logical/logical.c:590 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "スロット\"%s\", 出力プラグイン\"%s\", %sコールãƒãƒƒã‚¯ã®å‡¦ç†ä¸­" + +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "レプリケーションスロットを使用ã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯replicationロールã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: replication/logical/logicalfuncs.c:153 +#, c-format +msgid "slot name must not be null" +msgstr "スロットåã¯nullã§ã¯ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: replication/logical/logicalfuncs.c:169 +#, c-format +msgid "options array must not be null" +msgstr "オプションé…列ã¯nullã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: replication/logical/logicalfuncs.c:200 +#, c-format +msgid "array must be one-dimensional" +msgstr "é…列ã¯1次元ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: replication/logical/logicalfuncs.c:206 +#, c-format +msgid "array must not contain nulls" +msgstr "é…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" + +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 +#: utils/adt/jsonb.c:1269 +#, c-format +msgid "array must have even number of elements" +msgstr "é…列ã®è¦ç´ æ•°ã¯å¶æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: replication/logical/logicalfuncs.c:269 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰å‡ºåŠ›ãƒ—ãƒ©ã‚°ã‚¤ãƒ³\"%s\"ã¯ãƒã‚¤ãƒŠãƒªå‡ºåŠ›ã‚’ç”Ÿæˆã—ã¾ã™, ã—ã‹ã—関数\"%s\"ã¯ãƒ†ã‚­ã‚¹ãƒˆãƒ‡ãƒ¼ã‚¿ã‚’期待ã—ã¦ã„ã¾ã™" + +#: replication/logical/origin.c:185 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "スーパーユーザã®ã¿ãŒãƒ¬ãƒ—リケーション基点ã®å•ã„åˆã‚ã›ã‚„æ“作ãŒã§ãã¾ã™" + +#: replication/logical/origin.c:190 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "max_replication_slots = 0 ã®æ™‚ã¯ãƒ¬ãƒ—リケーション起点ã®å•ã„åˆã‚ã›ã¯æ“作ã¯ã§ãã¾ã›ã‚“" + +#: replication/logical/origin.c:195 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "リカãƒãƒªä¸­ã¯ãƒ¬ãƒ—リケーション基点をæ“作ã§ãã¾ã›ã‚“" + +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "レプリケーション基点\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: replication/logical/origin.c:321 #, c-format -msgid "aborting startup due to startup process failure" -msgstr "起動プロセスã®å¤±æ•—ã®ãŸã‚起動を中断ã—ã¦ã„ã¾ã™" +msgid "could not find free replication origin OID" +msgstr "複製基点OIDã®ç©ºããŒã‚りã¾ã›ã‚“" -#: postmaster/postmaster.c:2617 +#: replication/logical/origin.c:369 #, c-format -msgid "database system is ready to accept connections" -msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®æŽ¥ç¶šå—ä»˜æº–å‚™ãŒæ•´ã„ã¾ã—ãŸã€‚" +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "OID%dã®ãƒ¬ãƒ—リケーション起点を削除ã§ãã¾ã›ã‚“, PID%dã§ä½¿ç”¨ä¸­ã§ã™" -#: postmaster/postmaster.c:2632 -msgid "background writer process" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãƒ—ロセス" +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "OIDãŒ%uã®ãƒ¬ãƒ—リケーション基点ãŒã‚りã¾ã›ã‚“" -#: postmaster/postmaster.c:2686 -msgid "checkpointer process" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆå‡¦ç†ãƒ—ロセス" +#: replication/logical/origin.c:725 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "レプリケーションãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®ãƒžã‚¸ãƒƒã‚¯å€¤%uã¯ä¸æ­£ã§ã™ã€æ­£ã—ã„値ã¯%u" -#: postmaster/postmaster.c:2702 -msgid "WAL writer process" -msgstr "WALライタプロセス" +#: replication/logical/origin.c:757 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "ファイル\"%1$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %3$zuãƒã‚¤ãƒˆã®ã†ã¡%2$dãƒã‚¤ãƒˆã‚’読ã¿è¾¼ã¿ã¾ã—ãŸ" -#: postmaster/postmaster.c:2716 -msgid "WAL receiver process" -msgstr "WAL å—信プロセス" +#: replication/logical/origin.c:766 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "使用å¯èƒ½ãªãƒ¬ãƒ—リケーションステートãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã€max_replication_slotsを増やã—ã¦ãã ã•ã„" -#: postmaster/postmaster.c:2731 -msgid "autovacuum launcher process" -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ãƒ©ãƒ³ãƒãƒ£ãƒ—ロセス" +#: replication/logical/origin.c:784 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "レプリケーションスロットãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ %uã¯é–“é•ã£ã¦ã„ã¾ã™ã€æ­£ã—ãã¯%uã§ã™" -#: postmaster/postmaster.c:2746 -msgid "archiver process" -msgstr "アーカイãƒãƒ—ロセス" +#: replication/logical/origin.c:908 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "OID%dã®ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³èµ·ç‚¹ã¯æ—¢ã«PID%dã§ä½¿ç”¨ä¸­ã§ã™" -#: postmaster/postmaster.c:2762 -msgid "statistics collector process" -msgstr "統計情報åŽé›†ãƒ—ロセス" +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "OID%uã®ãƒ¬ãƒ—リケーション基点ã«å¯¾ã™ã‚‹ãƒ¬ãƒ—リケーション状態スロットã®ç©ºããŒã‚りã¾ã›ã‚“" -#: postmaster/postmaster.c:2776 -msgid "system logger process" -msgstr "システムログå–得プロセス" +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 +#: replication/slot.c:1559 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "max_replication_slotsを増やã—ã¦å†åº¦è©¦ã—ã¦ãã ã•ã„" -#: postmaster/postmaster.c:2838 -#| msgid "server process" -msgid "worker process" -msgstr "ワーカプロセス" +#: replication/logical/origin.c:1065 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "æ—¢ã«åˆæœŸåŒ–ã•れã¦ã„ã‚‹å ´åˆã¯ãƒ¬ãƒ—リケーション起点ã®åˆæœŸåŒ–ã¯ã§ãã¾ã›ã‚“" -#: postmaster/postmaster.c:2908 postmaster/postmaster.c:2927 -#: postmaster/postmaster.c:2934 postmaster/postmaster.c:2952 -msgid "server process" -msgstr "サーãƒãƒ—ロセス" +#: replication/logical/origin.c:1094 +#, c-format +msgid "replication identifier %d is already active for PID %d" +msgstr "レプリケーション識別å­%dã¯ã™ã§ã«PID%dã§æ´»å‹•中ã§ã™" -#: postmaster/postmaster.c:2993 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 +#: replication/logical/origin.c:1363 #, c-format -msgid "terminating any other active server processes" -msgstr "ä»–ã®æ´»å‹•中ã®ã‚µãƒ¼ãƒãƒ—ロセスを終了ã—ã¦ã„ã¾ã™" +msgid "no replication origin is configured" +msgstr "ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³èµ·ç‚¹ãŒæ§‹æˆã•れã¦ã„ã¾ã›ã‚“" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3247 +#: replication/logical/relation.c:255 #, c-format -msgid "%s (PID %d) exited with exit code %d" -msgstr "%s (PID %d)ã¯çµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "è«–ç†ãƒ¬ãƒ—リケーション対象ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: postmaster/postmaster.c:3249 postmaster/postmaster.c:3260 -#: postmaster/postmaster.c:3271 postmaster/postmaster.c:3280 -#: postmaster/postmaster.c:3290 +#: replication/logical/relation.c:297 #, c-format -msgid "Failed process was running: %s" -msgstr "失敗ã—ãŸãƒ—ロセスãŒå®Ÿè¡Œã—ã¦ã„ã¾ã—ãŸ: %s" +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションã®å¯¾è±¡ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ã¯ãƒ¬ãƒ—リケートã•れãŸåˆ—ã®ä¸€éƒ¨ã‚’失ã£ã¦ã„ã¾ã™" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3257 +#: replication/logical/relation.c:337 #, c-format -msgid "%s (PID %d) was terminated by exception 0x%X" -msgstr "%s (PID %d)ã¯ä¾‹å¤–%Xã§çµ‚了ã—ã¾ã—ãŸ" +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ãŒREPLICA IDENTITYインデックスã§ã‚·ã‚¹ãƒ†ãƒ åˆ—を使用ã—ã¦ã„ã¾ã™" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3267 +#: replication/logical/reorderbuffer.c:2503 #, c-format -msgid "%s (PID %d) was terminated by signal %d: %s" -msgstr "%s (PID %d)ã¯ã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ: %s" +msgid "could not write to data file for XID %u: %m" +msgstr "XID%uã®ãŸã‚ã®ãƒ‡ãƒ¼ã‚¿ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ã出ã—ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3278 +#: replication/logical/reorderbuffer.c:2596 +#: replication/logical/reorderbuffer.c:2618 #, c-format -msgid "%s (PID %d) was terminated by signal %d" -msgstr "%s (PID %d)ã¯ã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ" +msgid "could not read from reorderbuffer spill file: %m" +msgstr "ä¸¦ã¹æ›¿ãˆãƒãƒƒãƒ•ã‚¡ã®ã‚ãµã‚Œãƒ•ァイルã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3288 +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 #, c-format -msgid "%s (PID %d) exited with unrecognized status %d" -msgstr "%s (PID %d)ã¯èªè­˜ã§ããªã„ステータス%dã§çµ‚了ã—ã¾ã—ãŸ" +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "ä¸¦ã¹æ›¿ãˆãƒãƒƒãƒ•ã‚¡ã®ã‚ãµã‚Œãƒ•ァイルã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %2$uãƒã‚¤ãƒˆã®ã¯ãšãŒ%1$dãƒã‚¤ãƒˆã§ã—ãŸ" -#: postmaster/postmaster.c:3476 +#: replication/logical/reorderbuffer.c:2845 #, c-format -msgid "abnormal database system shutdown" -msgstr "データベースシステムã¯ç•°å¸¸ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "pg_repslot/%2$s/*.xid ã®å‰Šé™¤ä¸­ã«ãƒ•ァイル\"%1$s\"ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ:: %3$m" -#: postmaster/postmaster.c:3515 +#: replication/logical/reorderbuffer.c:3311 #, c-format -msgid "all server processes terminated; reinitializing" -msgstr "å…¨ã¦ã®ã‚µãƒ¼ãƒãƒ—ロセスãŒçµ‚了ã—ã¾ã—ãŸ: å†åˆæœŸåŒ–ã—ã¦ã„ã¾ã™" +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "ファイル\"%1$s\"ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %3$dãƒã‚¤ãƒˆã®ã¯ãšãŒ%2$dãƒã‚¤ãƒˆã§ã—ãŸ" -#: postmaster/postmaster.c:3759 +#: replication/logical/snapbuild.c:612 #, c-format -msgid "could not fork new process for connection: %m" -msgstr "æŽ¥ç¶šç”¨ã®æ–°ã—ã„プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "initial slot snapshot too large" +msgstr "åˆæœŸã‚¹ãƒ­ãƒƒãƒˆã‚¹ãƒŠãƒƒãƒ—ショットãŒå¤§ãã™ãŽã¾ã™" -#: postmaster/postmaster.c:3801 -msgid "could not fork new process for connection: " -msgstr "æŽ¥ç¶šç”¨ã®æ–°ã—ã„プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ" +#: replication/logical/snapbuild.c:664 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "エクスãƒãƒ¼ãƒˆã•れãŸè«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚¹ãƒŠãƒƒãƒ—ショット: \"%s\" (%u個ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ID ã‚’å«ã‚€)" +msgstr[1] "エクスãƒãƒ¼ãƒˆã•れãŸè«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚¹ãƒŠãƒƒãƒ—ショット: \"%s\" (%u個ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ID ã‚’å«ã‚€)" -#: postmaster/postmaster.c:3908 +#: replication/logical/snapbuild.c:1269 replication/logical/snapbuild.c:1362 +#: replication/logical/snapbuild.c:1872 #, c-format -msgid "connection received: host=%s port=%s" -msgstr "接続をå—ã‘付ã‘ã¾ã—ãŸ: ホスト=%s ãƒãƒ¼ãƒˆç•ªå·=%s" +msgid "logical decoding found consistent point at %X/%X" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã¯ä¸€è²«æ€§ãƒã‚¤ãƒ³ãƒˆã‚’%X/%Xã§ç™ºè¦‹ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:3913 +#: replication/logical/snapbuild.c:1271 #, c-format -msgid "connection received: host=%s" -msgstr "接続をå—ã‘付ã‘ã¾ã—ãŸ: ホスト=%s" +msgid "There are no running transactions." +msgstr "実行中ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ã‚りã¾ã›ã‚“。" -#: postmaster/postmaster.c:4188 +#: replication/logical/snapbuild.c:1313 #, c-format -msgid "could not execute server process \"%s\": %m" -msgstr "サーãƒãƒ—ロセス\"%s\"を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical decoding found initial starting point at %X/%X" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã¯åˆæœŸé–‹å§‹ç‚¹ã‚’%X/%Xã§ç™ºè¦‹ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:4736 +#: replication/logical/snapbuild.c:1315 replication/logical/snapbuild.c:1339 #, c-format -msgid "database system is ready to accept read only connections" -msgstr "データベースシステムã¯ãƒªãƒ¼ãƒ‰ã‚ªãƒ³ãƒªãƒ¼æŽ¥ç¶šã®å—付準備ãŒã§ãã¾ã—ãŸ" +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "%2$uよりå¤ã„トランザクション(ãŠãŠã‚ˆã%1$d個)ã®å®Œäº†ã‚’å¾…ã£ã¦ã„ã¾ã™" -#: postmaster/postmaster.c:5049 +#: replication/logical/snapbuild.c:1337 #, c-format -msgid "could not fork startup process: %m" -msgstr "起動プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã¯åˆæœŸã®ä¸€è²«æ€§ãƒã‚¤ãƒ³ãƒˆã‚’%X/%Xã§ç™ºè¦‹ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:5053 +#: replication/logical/snapbuild.c:1364 #, c-format -msgid "could not fork background writer process: %m" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãƒ—ロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "There are no old transactions anymore." +msgstr "å¤ã„トランザクションã¯ã“れ以上ã¯ã‚りã¾ã›ã‚“" -#: postmaster/postmaster.c:5057 +#: replication/logical/snapbuild.c:1736 replication/logical/snapbuild.c:1767 +#: replication/logical/snapbuild.c:1787 replication/logical/snapbuild.c:1806 #, c-format -msgid "could not fork checkpointer process: %m" -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆå‡¦ç†ãƒ—ロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "could not read file \"%s\", read %d of %d: %m" +msgstr "ファイル\"%1$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€%3$dãƒã‚¤ãƒˆä¸­%2$dãƒã‚¤ãƒˆ: %m" -#: postmaster/postmaster.c:5061 +#: replication/logical/snapbuild.c:1742 #, c-format -msgid "could not fork WAL writer process: %m" -msgstr "WALライタプロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "スナップショット構築状態ファイル\"%1$s\"ã®ãƒžã‚¸ãƒƒã‚¯å€¤ãŒä¸æ­£ã§ã™: %3$uã®ã¯ãšãŒ%2$uã§ã—ãŸ" -#: postmaster/postmaster.c:5065 +#: replication/logical/snapbuild.c:1747 #, c-format -msgid "could not fork WAL receiver process: %m" -msgstr "WAL å—信プロセスを fork ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "スナップショット状態ファイル\"%1$s\"ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³%2$uã¯ã‚µãƒãƒ¼ãƒˆå¤–ã§ã™: %3$uã®ã¯ãšãŒ%2$uã§ã—ãŸ" -#: postmaster/postmaster.c:5069 +#: replication/logical/snapbuild.c:1819 #, c-format -msgid "could not fork process: %m" -msgstr "プロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "スナップショット生æˆçŠ¶æ…‹ãƒ•ã‚¡ã‚¤ãƒ«\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒä¸€è‡´ã—ã¾ã›ã‚“: %uã§ã™ãŒã€%uã§ã‚ã‚‹ã¹ãã§ã™" -#: postmaster/postmaster.c:5230 +#: replication/logical/snapbuild.c:1874 #, c-format -msgid "database connection requirement not indicated during registration" -msgstr "登録時ã«ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æŽ¥ç¶šã®å¿…è¦æ€§ãŒç¤ºã•れã¦ã„ã¾ã›ã‚“" +msgid "Logical decoding will begin using saved snapshot." +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã¯ä¿å­˜ã•れãŸã‚¹ãƒŠãƒƒãƒ—ショットを使ã£ã¦é–‹å§‹ã—ã¾ã™ã€‚" -#: postmaster/postmaster.c:5237 +#: replication/logical/snapbuild.c:1946 #, c-format -#| msgid "invalid XML processing instruction" -msgid "invalid processing mode in background worker" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«å†…ã®ç„¡åйãªå‡¦ç†ãƒ¢ãƒ¼ãƒ‰" +msgid "could not parse file name \"%s\"" +msgstr "ファイルå\"%s\"をパースã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:5292 +#: replication/logical/tablesync.c:138 #, c-format -#| msgid "terminating connection due to administrator command" -msgid "terminating background worker \"%s\" due to administrator command" -msgstr "管ç†è€…コマンドã«ã‚ˆã‚Šãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«\"%s\"を終了ã—ã¦ã„ã¾ã™" +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "サブスクリプション\"%s\"ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«å¯¾ã™ã‚‹è«–ç†ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒ†ãƒ¼ãƒ–ãƒ«åŒæœŸãƒ¯ãƒ¼ã‚«ãŒçµ‚了ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:5491 +#: replication/logical/tablesync.c:685 #, c-format -#| msgid "background writer process" -msgid "starting background worker process \"%s\"" -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ¯ãƒ¼ã‚«ãƒ—ロセス\"%s\"ã‚’èµ·å‹•ã—ã¦ã„ã¾ã™" +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "テーブル\"%s.%s\"ã®ãƒ†ãƒ¼ãƒ–ル情報を発行サーãƒã‹ã‚‰å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: postmaster/postmaster.c:5502 +#: replication/logical/tablesync.c:691 #, c-format -#| msgid "could not fork WAL writer process: %m" -msgid "could not fork worker process: %m" -msgstr "ワーカプロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "table \"%s.%s\" not found on publisher" +msgstr "テーブル\"%s.%s\"ãŒç™ºè¡Œã‚µãƒ¼ãƒä¸Šã§è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:5857 +#: replication/logical/tablesync.c:721 #, c-format -msgid "could not duplicate socket %d for use in backend: error code %d" -msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã§ä½¿ç”¨ã™ã‚‹ãŸã‚ã«ã‚½ã‚±ãƒƒãƒˆ%dを複製ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %d" +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "テーブル\"%s.%s\"ã®ãƒ†ãƒ¼ãƒ–ル情報ã®å–å¾—ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" -#: postmaster/postmaster.c:5889 +#: replication/logical/tablesync.c:791 #, c-format -msgid "could not create inherited socket: error code %d\n" -msgstr "継承ã—ãŸã‚½ã‚±ãƒƒãƒˆã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %d\n" +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "テーブル\"%s.%s\"ã®åˆæœŸå†…容ã®ã‚³ãƒ”ーを開始ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: postmaster/postmaster.c:5918 postmaster/postmaster.c:5925 +#: replication/logical/tablesync.c:904 #, c-format -msgid "could not read from backend variables file \"%s\": %s\n" -msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ãƒ•ァイル\"%s\"ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "table copy could not start transaction on publisher" +msgstr "テーブルコピー中ã«ç™ºè¡Œã‚µãƒ¼ãƒä¸Šã§ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³é–‹å§‹ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:5934 +#: replication/logical/tablesync.c:926 #, c-format -msgid "could not remove file \"%s\": %s\n" -msgstr "ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "table copy could not finish transaction on publisher" +msgstr "テーブルコピー中ã«ç™ºè¡Œã‚µãƒ¼ãƒä¸Šã§ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³çµ‚了ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: postmaster/postmaster.c:5951 +#: replication/logical/worker.c:307 #, c-format -msgid "could not map view of backend variables: error code %lu\n" -msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ã®ãƒ“ューをマップã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "レプリケーション対象リレーション\"%s.%s\" 列\"%s\"ã®ãƒªãƒ¢ãƒ¼ãƒˆã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿ã‚’処ç†ä¸­ã€ãƒªãƒ¢ãƒ¼ãƒˆã§ã®åž‹ %sã€ãƒ­ãƒ¼ã‚«ãƒ«ã§ã®åž‹ %s" -#: postmaster/postmaster.c:5960 +#: replication/logical/worker.c:528 #, c-format -msgid "could not unmap view of backend variables: error code %lu\n" -msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰å¤‰æ•°ã®ãƒ“ューをアンマップã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" +msgid "ORIGIN message sent out of order" +msgstr "ORIGINメッセージãŒé–“é•ã£ãŸé †åºã§é€å‡ºã•れã¦ã„ã¾ã™" -#: postmaster/postmaster.c:5967 +#: replication/logical/worker.c:661 #, c-format -msgid "could not close handle to backend parameter variables: error code %lu\n" -msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãƒ‘ラメータ変数ã®ãƒãƒ³ãƒ‰ãƒ«ã‚’クローズã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード%lu\n" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションã®å¯¾è±¡ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ã¯è¤‡è£½ã®è­˜åˆ¥åˆ—を期待ã—ã¦ã„ã¾ã—ãŸãŒã€ç™ºè¡Œã‚µãƒ¼ãƒã¯é€ä¿¡ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: postmaster/postmaster.c:6123 +#: replication/logical/worker.c:668 #, c-format -msgid "could not read exit code for process\n" -msgstr "å­ãƒ—ロセスã®çµ‚了コードã®èª­ã¿è¾¼ã¿ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n" +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションã®å¯¾è±¡ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ãŒè­˜åˆ¥åˆ—インデックスも主キーをもã£ã¦ãŠã‚‰ãšã€ã‹ã¤ç™ºè¡Œã•れãŸãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒREPLICA IDENTITY FULLã¨ãªã£ã¦ã„ã¾ã›ã‚“" -#: postmaster/postmaster.c:6128 +#: replication/logical/worker.c:1007 #, c-format -msgid "could not post child completion status\n" -msgstr "個プロセスã®çµ‚了コードを投稿ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" +msgid "invalid logical replication message type \"%c\"" +msgstr "䏿­£ãªè«–ç†ãƒ¬ãƒ—リケーションã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—\"%c\"" -#: postmaster/syslogger.c:468 postmaster/syslogger.c:1067 +#: replication/logical/worker.c:1148 #, c-format -msgid "could not read from logger pipe: %m" -msgstr "ロガーパイプã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "data stream from publisher has ended" +msgstr "発行サーãƒã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆãƒªãƒ¼ãƒ ãŒçµ‚了ã—ã¾ã—ãŸ" -#: postmaster/syslogger.c:517 +#: replication/logical/worker.c:1307 #, c-format -msgid "logger shutting down" -msgstr "ãƒ­ã‚¬ãƒ¼ã‚’åœæ­¢ã—ã¦ã„ã¾ã™" +msgid "terminating logical replication worker due to timeout" +msgstr "タイムアウトã«ã‚ˆã‚Šè«–ç†ãƒ¬ãƒ—リケーションワーカを終了ã—ã¦ã„ã¾ã™" -#: postmaster/syslogger.c:561 postmaster/syslogger.c:575 +#: replication/logical/worker.c:1455 #, c-format -msgid "could not create pipe for syslog: %m" -msgstr "syslog用ã®ãƒ‘イプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "サブスクリプション\"%s\"ãŒå‰Šé™¤ã•れãŸãŸã‚ã€å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒåœæ­¢ã—ã¾ã™" -#: postmaster/syslogger.c:611 +#: replication/logical/worker.c:1469 #, c-format -msgid "could not fork system logger: %m" -msgstr "システムロガーをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "サブスクリプション\"%s\"ãŒç„¡åŠ¹åŒ–ã•れãŸãŸã‚ã€å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒåœæ­¢ã—ã¾ã™" -#: postmaster/syslogger.c:647 +#: replication/logical/worker.c:1483 #, c-format -msgid "redirecting log output to logging collector process" -msgstr "ログ出力をログåŽé›†ãƒ—ロセスã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã—ã¦ã„ã¾ã™" +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "接続情報ãŒå¤‰æ›´ã•れãŸãŸã‚ã€ã‚µãƒ–スクリプション\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒå†èµ·å‹•ã—ã¾ã™" -#: postmaster/syslogger.c:648 +#: replication/logical/worker.c:1497 #, c-format -msgid "Future log output will appear in directory \"%s\"." -msgstr "ã“ã“ã‹ã‚‰ã®ãƒ­ã‚°å‡ºåŠ›ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã«ç¾ã‚Œã¾ã™ã€‚" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "サブスクリプション\"%s\"ã®åå‰ãŒå¤‰æ›´ã•れãŸãŸã‚ã€å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒå†èµ·å‹•ã—ã¾ã™" -#: postmaster/syslogger.c:656 +#: replication/logical/worker.c:1514 #, c-format -msgid "could not redirect stdout: %m" -msgstr "標準出力ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "レプリケーションスロットã®åå‰ãŒå¤‰æ›´ã•れãŸãŸã‚ã€ã‚µãƒ–スクリプション\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒå†èµ·å‹•ã—ã¾ã™" -#: postmaster/syslogger.c:661 postmaster/syslogger.c:677 +#: replication/logical/worker.c:1528 #, c-format -msgid "could not redirect stderr: %m" -msgstr "標準エラー出力ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "サブスクリプションãŒè³¼èª­ã™ã‚‹ãƒ‘ブリケーションãŒå¤‰æ›´ã•れãŸãŸã‚ã€ã‚µãƒ–スクリプション\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒå†èµ·å‹•ã—ã¾ã™" -#: postmaster/syslogger.c:1022 +#: replication/logical/worker.c:1631 #, c-format -msgid "could not write to log file: %s\n" -msgstr "ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "サブスクリプション%uãŒå‰Šé™¤ã•れãŸãŸã‚ã€å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ã®èµ·å‹•を中断ã—ã¾ã™" -#: postmaster/syslogger.c:1162 +#: replication/logical/worker.c:1643 #, c-format -msgid "could not open log file \"%s\": %m" -msgstr "ロックファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "サブスクリプション\"%s\"ãŒèµ·å‹•中ã«ç„¡åŠ¹åŒ–ã•れãŸãŸã‚ã€å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ã¯èµ·å‹•ã—ã¾ã›ã‚“" -#: postmaster/syslogger.c:1224 postmaster/syslogger.c:1268 +#: replication/logical/worker.c:1661 #, c-format -msgid "disabling automatic rotation (use SIGHUP to re-enable)" -msgstr "自動ローテーションを無効ã«ã—ã¦ã„ã¾ã™(å†åº¦æœ‰åйã«ã™ã‚‹ã«ã¯SIGHUPを使用ã—ã¦ãã ã•ã„)" +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "サブスクリプション\"%s\"ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒ†ãƒ¼ãƒ–ãƒ«åŒæœŸãƒ¯ãƒ¼ã‚«ãŒèµ·å‹•ã—ã¾ã—ãŸ" -#: regex/regc_pg_locale.c:261 +#: replication/logical/worker.c:1665 #, c-format -msgid "could not determine which collation to use for regular expression" -msgstr "æ­£è¦è¡¨ç¾ã®éš›ã«ã©ã®ç…§åˆè¦å‰‡ã‚’使ã†ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "サブスクリプション\"%s\"ã«å¯¾å¿œã™ã‚‹è«–ç†ãƒ¬ãƒ—リケーションé©ç”¨ãƒ¯ãƒ¼ã‚«ãŒèµ·å‹•ã—ã¾ã—ãŸ" -#: repl_gram.y:183 repl_gram.y:200 +#: replication/logical/worker.c:1705 #, c-format -#| msgid "invalid field size" -msgid "invalid timeline %u" -msgstr "タイムライン%uã¯ç„¡åйã§ã™" +msgid "subscription has no replication slot set" +msgstr "サブスクリプションã«ãƒ¬ãƒ—リケーションスロットãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“" -#: repl_scanner.l:94 -msgid "invalid streaming start location" -msgstr "ストリーミングã®é–‹å§‹ä½ç½®ãŒç„¡åйã§ã™" +#: replication/pgoutput/pgoutput.c:117 +#, c-format +msgid "invalid proto_version" +msgstr "䏿­£ãªproto_version" -#: repl_scanner.l:116 scan.l:657 -msgid "unterminated quoted string" -msgstr "文字列ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\" ã¯ç¯„囲外ã§ã™" -#: repl_scanner.l:126 +#: replication/pgoutput/pgoutput.c:139 #, c-format -msgid "syntax error: unexpected character \"%s\"" -msgstr "構文エラー。予期ã—ãªã„文字 \"%s\"" +msgid "invalid publication_names syntax" +msgstr "publication_namesã®æ§‹æ–‡ãŒä¸æ­£ã§ã™" -#: replication/basebackup.c:135 replication/basebackup.c:893 -#: utils/adt/misc.c:360 +#: replication/pgoutput/pgoutput.c:181 #, c-format -msgid "could not read symbolic link \"%s\": %m" -msgstr "シンボリックリンク \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "クライアント㌠proto_version=%d ã‚’é€ä¿¡ã—ã¦ãã¾ã—ãŸãŒã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d以下ã®ãƒ—ロトコルã®ã¿ã—ã‹ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: replication/basebackup.c:142 replication/basebackup.c:897 -#: utils/adt/misc.c:364 +#: replication/pgoutput/pgoutput.c:187 #, c-format -msgid "symbolic link \"%s\" target is too long" -msgstr "シンボリックリンク\"%s\"ã®å‚ç…§å…ˆã¯é•·ã™ãŽã¾ã™" +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "クライアント㌠proto_version=%d ã‚’é€ä¿¡ã—ã¦ãã¾ã—ãŸãŒã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d以上ã®ãƒ—ロトコルã®ã¿ã—ã‹ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: replication/basebackup.c:200 +#: replication/pgoutput/pgoutput.c:193 #, c-format -msgid "could not stat control file \"%s\": %m" -msgstr "制御ファイル\"%s\"ã®çŠ¶æ…‹ã‚’ç¢ºèªã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "publication_names parameter missing" +msgstr "publication_namesãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" -#: replication/basebackup.c:317 replication/basebackup.c:331 -#: replication/basebackup.c:340 +#: replication/slot.c:182 #, c-format -#| msgid "could not fsync file \"%s\": %m" -msgid "could not find WAL file \"%s\"" -msgstr "WALファイル\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" +msgid "replication slot name \"%s\" is too short" +msgstr "レプリケーションスロットå\"%s\"ã¯çŸ­ã™ãŽã¾ã™" -#: replication/basebackup.c:379 replication/basebackup.c:402 +#: replication/slot.c:191 #, c-format -#| msgid "unexpected message type \"%c\"" -msgid "unexpected WAL file size \"%s\"" -msgstr "想定ã—ãªã„WALファイルã®ã‚µã‚¤ã‚º\"%s\"" +msgid "replication slot name \"%s\" is too long" +msgstr "レプリケーションスロットå\"%s\"ã¯é•·ã™ãŽã¾ã™" -#: replication/basebackup.c:390 replication/basebackup.c:1011 +#: replication/slot.c:204 #, c-format -msgid "base backup could not send data, aborting backup" -msgstr "ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を中止ã—ã¦ã„ã¾ã™" +msgid "replication slot name \"%s\" contains invalid character" +msgstr "レプリケーションスロットå\"%s\"ã¯ä¸æ­£ãªæ–‡å­—ã‚’å«ã‚“ã§ã„ã¾ã™" -#: replication/basebackup.c:474 replication/basebackup.c:483 -#: replication/basebackup.c:492 replication/basebackup.c:501 -#: replication/basebackup.c:510 +#: replication/slot.c:206 #, c-format -msgid "duplicate option \"%s\"" -msgstr "\"%s\" オプションã¯é‡è¤‡ã—ã¦ã„ã¾ã™" +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "レプリケーションスロットåã¯å°æ–‡å­—ã€æ•°å­—ã¨ã‚¢ãƒ³ãƒ€ãƒ¼ã‚¹ã‚³ã‚¢ã®ã¿ã‚’å«ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚" -#: replication/basebackup.c:763 replication/basebackup.c:847 +#: replication/slot.c:253 #, c-format -msgid "could not stat file or directory \"%s\": %m" -msgstr "\"%s\"ã¨ã„ã†ãƒ•ァイルã¾ãŸã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æƒ…報をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %m" +msgid "replication slot \"%s\" already exists" +msgstr "レプリケーションスロット\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: replication/basebackup.c:947 +#: replication/slot.c:263 #, c-format -msgid "skipping special file \"%s\"" -msgstr "スペシャルファイル \"%s\" をスキップã—ã¦ã„ã¾ã™" +msgid "all replication slots are in use" +msgstr "レプリケーションスロットã¯å…¨ã¦ä½¿ç”¨ä¸­ã§ã™" -#: replication/basebackup.c:1001 +#: replication/slot.c:264 #, c-format -msgid "archive member \"%s\" too large for tar format" -msgstr "アーカイブメンム\"%s\" ㌠tar å½¢å¼ã¨ã—ã¦ã¯å¤§ãã™ãŽã¾ã™" +msgid "Free one or increase max_replication_slots." +msgstr "ã©ã‚Œã‹ä¸€ã¤ã‚’解放ã™ã‚‹ã‹ã€max_replication_slots を大ããã—ã¦ãã ã•ã„。" -#: replication/libpqwalreceiver/libpqwalreceiver.c:105 +#: replication/slot.c:387 #, c-format -msgid "could not connect to the primary server: %s" -msgstr "プライマリサーãƒã¸ã®æŽ¥ç¶šãŒã§ãã¾ã›ã‚“ã§ã—ãŸï¼š%s" +msgid "replication slot \"%s\" does not exist" +msgstr "レプリケーションスロット\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: replication/libpqwalreceiver/libpqwalreceiver.c:129 +#: replication/slot.c:398 replication/slot.c:948 #, c-format -msgid "could not receive database system identifier and timeline ID from the primary server: %s" -msgstr "プライマリサーãƒã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ã®è­˜åˆ¥å­ã¨ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ ID ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸï¼š%s" +msgid "replication slot \"%s\" is active for PID %d" +msgstr "レプリケーションスロット\"%s\"ã¯PID%dã§ä½¿ç”¨ä¸­ã§ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:140 -#: replication/libpqwalreceiver/libpqwalreceiver.c:287 +#: replication/slot.c:632 replication/slot.c:1141 replication/slot.c:1495 #, c-format -msgid "invalid response from primary server" -msgstr "プライマリサーãƒã‹ã‚‰ã®å¿œç­”ãŒç„¡åйã§ã™" +msgid "could not remove directory \"%s\"" +msgstr "ディレクトリ\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:141 +#: replication/slot.c:983 #, c-format -msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." -msgstr "3個ã®ãƒ•ィールドをæŒã¤ï¼‘個ã®ã‚¿ãƒ—ルを期待ã—ã¦ã„ã¾ã—ãŸãŒã€%2$d 個ã®ãƒ•ィールドをæŒã¤ %1$d 個ã®ã‚¿ãƒ—ルをå—ä¿¡ã—ã¾ã—ãŸã€‚" +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "レプリケーションスロット㯠max_replication_slots > 0 ã®ã¨ãã ã‘使用ã§ãã¾ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:156 +#: replication/slot.c:988 #, c-format -msgid "database system identifier differs between the primary and standby" -msgstr "データベースシステムã®è­˜åˆ¥å­ãŒãƒ—ライマリサーãƒã¨ã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚µãƒ¼ãƒé–“ã§ç•°ãªã‚Šã¾ã™" +msgid "replication slots can only be used if wal_level >= replica" +msgstr "レプリケーションスロット㯠wal_level >= replica ã®ã¨ãã ã‘使用ã§ãã¾ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:157 +#: replication/slot.c:1427 replication/slot.c:1467 #, c-format -msgid "The primary's identifier is %s, the standby's identifier is %s." -msgstr "プライマリå´ã®è­˜åˆ¥å­ã¯ %s ã§ã™ãŒã€ã‚¹ã‚¿ãƒ³ãƒã‚¤å´ã®è­˜åˆ¥å­ã¯ %s ã§ã™ã€‚" +msgid "could not read file \"%s\", read %d of %u: %m" +msgstr "ファイル\"%1$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€%3$uãƒã‚¤ãƒˆã®ã†ã¡%2$dãƒã‚¤ãƒˆ: %4$m" -#: replication/libpqwalreceiver/libpqwalreceiver.c:194 +#: replication/slot.c:1436 #, c-format -msgid "could not start WAL streaming: %s" -msgstr "WAL ストリーミングを開始ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "レプリケーションスロットファイル\"%1$s\"ã®ãƒžã‚¸ãƒƒã‚¯å€¤ãŒä¸æ­£ã§ã™: %3$uã®ã¯ãšãŒ%2$uã§ã—ãŸ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:212 +#: replication/slot.c:1443 #, c-format -#| msgid "could not send data to server: %s\n" -msgid "could not send end-of-streaming message to primary: %s" -msgstr "プライマリã«ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã®çµ‚了メッセージをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "レプリケーションスロットファイル\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆå¤–ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³%uã§ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:234 +#: replication/slot.c:1450 #, c-format -#| msgid "unexpected result status for \\watch\n" -msgid "unexpected result set after end-of-streaming" -msgstr "ストリーミングã®çµ‚äº†å¾Œã®æƒ³å®šå¤–ã®çµæžœã‚»ãƒƒãƒˆ" +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "レプリケーションスロットファイル\"%s\"ã®ã‚µã‚¤ã‚º%uã¯ç•°å¸¸ã§ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:246 +#: replication/slot.c:1482 #, c-format -#| msgid "error reading large object %u: %s" -msgid "error reading result of streaming command: %s" -msgstr "ストリーミングコマンドã®çµæžœã‚’読ã¿å–り中ã«ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã—ãŸ: %s" +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "レプリケーションスロットファイル\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒä¸€è‡´ã—ã¾ã›ã‚“: %uã§ã™ãŒã€%uã§ã‚ã‚‹ã¹ãã§ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:253 +#: replication/slot.c:1516 +#, fuzzy, c-format +#| msgid "logical decoding requires wal_level >= logical" +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "è«–ç†ãƒ‡ã‚³ãƒ¼ãƒ‰ã‚’行ã†ãŸã‚ã«ã¯ wal_level >= logical ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: replication/slot.c:1518 #, c-format -#| msgid "unexpected PQresultStatus: %d\n" -msgid "unexpected result after CommandComplete: %s" -msgstr "CommandCompleteå¾Œã®æƒ³å®šå¤–ã®çµæžœ: %s" +msgid "Change wal_level to be logical or higher." +msgstr "" -#: replication/libpqwalreceiver/libpqwalreceiver.c:276 +#: replication/slot.c:1522 +#, fuzzy, c-format +#| msgid "replication slots can only be used if wal_level >= replica" +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "レプリケーションスロット㯠wal_level >= replica ã®ã¨ãã ã‘使用ã§ãã¾ã™" + +#: replication/slot.c:1524 #, c-format -#| msgid "could not receive database system identifier and timeline ID from the primary server: %s" -msgid "could not receive timeline history file from the primary server: %s" -msgstr "プライマリサーãƒã‹ã‚‰ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³å±¥æ­´ãƒ•ァイルをå—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸï¼š%s" +msgid "Change wal_level to be replica or higher." +msgstr "" -#: replication/libpqwalreceiver/libpqwalreceiver.c:288 +#: replication/slot.c:1558 #, c-format -#| msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." -msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." -msgstr "2個ã®ãƒ•ィールドをæŒã¤ï¼‘個ã®ã‚¿ãƒ—ルを期待ã—ã¦ã„ã¾ã—ãŸãŒã€%2$d 個ã®ãƒ•ィールドをæŒã¤ %1$d 個ã®ã‚¿ãƒ—ルをå—ä¿¡ã—ã¾ã—ãŸã€‚" +msgid "too many replication slots active before shutdown" +msgstr "シャットダウンå‰ã®ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ãªãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚¹ãƒ­ãƒƒãƒˆã®æ•°ãŒå¤šã™ãŽã¾ã™" -#: replication/libpqwalreceiver/libpqwalreceiver.c:316 +#: replication/slotfuncs.c:490 #, c-format -msgid "socket not open" -msgstr "ソケットãŒã‚ªãƒ¼ãƒ—ンã•れã¦ã„ã¾ã›ã‚“" +msgid "invalid target wal lsn" +msgstr "䏿­£ãªç›®æ¨™WAL LSN" -#: replication/libpqwalreceiver/libpqwalreceiver.c:489 -#: replication/libpqwalreceiver/libpqwalreceiver.c:512 -#: replication/libpqwalreceiver/libpqwalreceiver.c:518 +#: replication/slotfuncs.c:512 #, c-format -msgid "could not receive data from WAL stream: %s" -msgstr "WAL ストリームã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "事å‰ã« WAL ã®ç•™ä¿ã‚’ã—ã¦ã„ãªã„レプリケーションスロットを進ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: replication/libpqwalreceiver/libpqwalreceiver.c:537 +#: replication/slotfuncs.c:528 #, c-format -msgid "could not send data to WAL stream: %s" -msgstr "WAL ストリームã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "レプリケーションスロットを %X/%X ã«é€²ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã€æœ€å°å€¤ã¯ %X/%X" -#: replication/syncrep.c:207 +#: replication/syncrep.c:246 #, c-format msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "管ç†è€…コマンドã«ã‚ˆã‚ŠåŒæœŸãƒ¬ãƒ—リケーションã®å¾…ã¡çŠ¶æ…‹ã‚’ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã€æŽ¥ç¶šã‚’çµ‚äº†ã—ã¦ã„ã¾ã™" -#: replication/syncrep.c:208 replication/syncrep.c:225 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgstr "トランザクションã¯ãƒ­ãƒ¼ã‚«ãƒ«ã§ã¯ã™ã§ã«ã‚³ãƒŸãƒƒãƒˆæ¸ˆã¿ã§ã™ãŒã€ã‚¹ã‚¿ãƒ³ãƒã‚¤å´ã«ã¯ãƒ¬ãƒ—リケーションã•れã¦ã„ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" -#: replication/syncrep.c:224 +#: replication/syncrep.c:263 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "ユーザã‹ã‚‰ã®è¦æ±‚ã«ã‚ˆã‚ŠåŒæœŸãƒ¬ãƒ—リケーションã®å¾…ã¡çŠ¶æ…‹ã‚’ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã—ã¦ã„ã¾ã™" -#: replication/syncrep.c:354 +#: replication/syncrep.c:397 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "スタンãƒã‚¤ã® \"%s\" ã«ã¯å„ªå…ˆåº¦ %u ã§åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ãŒè¨­å®šã•れã¦ã„ã¾ã™" -#: replication/syncrep.c:456 +# y, c-format +#: replication/syncrep.c:460 #, c-format -msgid "standby \"%s\" is now the synchronous standby with priority %u" -msgstr "スタンãƒã‚¤ã® \"%s\" ã«ã¯å„ªå…ˆåº¦ %u ã§åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ãŒè¨­å®šã•れã¦ã„ã¾ã™" +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "スタンãƒã‚¤\"%s\"ã¯å„ªå…ˆåº¦%uã®åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã«ãªã‚Šã¾ã—ãŸ" + +#: replication/syncrep.c:464 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "スタンãƒã‚¤\"%s\"ã¯å®šè¶³æ•°åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã®å€™è£œã«ãªã‚Šã¾ã—ãŸ" + +#: replication/syncrep.c:1164 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: replication/syncrep.c:1170 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã®æ•°(%d)ã¯1以上ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: replication/walreceiver.c:167 +#: replication/walreceiver.c:169 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "管ç†è€…コマンドã«ã‚ˆã‚Š WAL å—信プロセスを終了ã—ã¦ã„ã¾ã™" -#: replication/walreceiver.c:330 +#: replication/walreceiver.c:309 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "プライマリサーãƒã¸ã®æŽ¥ç¶šãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: replication/walreceiver.c:359 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "データベースシステムã®è­˜åˆ¥å­ãŒãƒ—ライマリサーãƒã¨ã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚µãƒ¼ãƒé–“ã§ç•°ãªã‚Šã¾ã™" + +#: replication/walreceiver.c:360 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "プライマリå´ã®è­˜åˆ¥å­ã¯ %s ã§ã™ãŒã€ã‚¹ã‚¿ãƒ³ãƒã‚¤å´ã®è­˜åˆ¥å­ã¯ %s ã§ã™ã€‚" + +#: replication/walreceiver.c:371 #, c-format -#| msgid "timeline %u of the primary does not match recovery target timeline %u" msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "ãƒ—ãƒ©ã‚¤ãƒžãƒªã®æœ€å¤§ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uãŒã€ãƒªã‚«ãƒãƒªã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ %uよりé…れã¦ã„ã¾ã™" -#: replication/walreceiver.c:364 +#: replication/walreceiver.c:407 #, c-format -#| msgid "%s: starting log streaming at %X/%X (timeline %u)\n" msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "プライマリã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%3$uã® %1$X/%2$Xã‹ã‚‰ã§WALストリーミングを始ã‚ã¾ã™" -#: replication/walreceiver.c:369 +#: replication/walreceiver.c:412 #, c-format -#| msgid "%s: starting log streaming at %X/%X (timeline %u)\n" msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "タイムライン%3$uã® %1$X/%2$Xã‹ã‚‰ã§WALストリーミングをå†é–‹ã—ã¾ã™" -#: replication/walreceiver.c:403 +#: replication/walreceiver.c:441 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "WAL ストリーミングを継続ã§ãã¾ã›ã‚“。リカãƒãƒªã¯ã™ã§ã«çµ‚ã‚ã£ã¦ã„ã¾ã™ã€‚" -#: replication/walreceiver.c:440 +#: replication/walreceiver.c:478 #, c-format msgid "replication terminated by primary server" msgstr "プライマリサーãƒã«ã‚ˆã‚Šãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãŒæ‰“ã¡åˆ‡ã‚‰ã‚Œã¾ã—ãŸ" -#: replication/walreceiver.c:441 +#: replication/walreceiver.c:479 #, c-format -#| msgid "%s: switched to timeline %u at %X/%X\n" msgid "End of WAL reached on timeline %u at %X/%X." msgstr "タイムライン%uã®%X/%Xã§WALã®æœ€å¾Œã«é”ã—ã¾ã—ãŸ" -#: replication/walreceiver.c:488 +#: replication/walreceiver.c:574 #, c-format -#| msgid "terminating walsender process due to replication timeout" msgid "terminating walreceiver due to timeout" msgstr "レプリケーションタイムアウトã«ã‚ˆã‚Šwalreceiverを終了ã—ã¦ã„ã¾ã™" -#: replication/walreceiver.c:528 +#: replication/walreceiver.c:614 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "プライマリサーãƒã«ã¯è¦æ±‚ã•れãŸã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%u上ã«ã“れ以上WALãŒã‚りã¾ã›ã‚“" -#: replication/walreceiver.c:543 replication/walreceiver.c:896 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format -#| msgid "could not close log file %u, segment %u: %m" msgid "could not close log segment %s: %m" msgstr "ログセグメント%sをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: replication/walreceiver.c:665 +#: replication/walreceiver.c:754 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "プライマリサーãƒã‹ã‚‰ãƒ©ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%u用ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³å±¥æ­´ãƒ•ァイルをå–り込ã¿ã—ã¦ã„ã¾ã™" -#: replication/walreceiver.c:947 +#: replication/walreceiver.c:1036 #, c-format -#| msgid "could not write to log file %u, segment %u at offset %u, length %lu: %m" msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "ログファイルセグメント%sã®ã‚ªãƒ•セット%uã«é•·ã•%luã§æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: replication/walsender.c:375 storage/smgr/md.c:1785 -#, c-format -msgid "could not seek to end of file \"%s\": %m" -msgstr "ファイル \"%s\" ã®çµ‚端(EOF)をシークã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: replication/walsender.c:379 +#: replication/walsender.c:494 #, c-format -#| msgid "could not seek to end of file \"%s\": %m" msgid "could not seek to beginning of file \"%s\": %m" msgstr "ファイル \"%s\" ã®å…ˆé ­ã«ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: replication/walsender.c:484 +#: replication/walsender.c:535 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM ㌠START_REPLICATION ã®å‰ã«å®Ÿè¡Œã•れã¦ã„ã¾ã›ã‚“" + +#: replication/walsender.c:552 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションスロットã¯ç‰©ç†ãƒ¬ãƒ—リケーションã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" + +#: replication/walsender.c:615 #, c-format -#| msgid "%s: starting timeline %u is not present in the server\n" msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "タイムライン%3$u上ã®è¦æ±‚ã•れãŸé–‹å§‹ãƒã‚¤ãƒ³ãƒˆ%1$X/%2$Xã¯ã‚µãƒ¼ãƒã®å±¥æ­´ã«ã‚りã¾ã›ã‚“" -#: replication/walsender.c:488 +#: replication/walsender.c:619 #, c-format -#| msgid "%s: switched to timeline %u at %X/%X\n" msgid "This server's history forked from timeline %u at %X/%X." msgstr "サーãƒã®å±¥æ­´ã¯ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã®%X/%Xã‹ã‚‰ãƒ•ォークã—ã¾ã—ãŸã€‚" -#: replication/walsender.c:533 +#: replication/walsender.c:664 #, c-format msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "è¦æ±‚ã•れãŸé–‹å§‹ãƒã‚¤ãƒ³ãƒˆ%X/%Xã¯ã‚µãƒ¼ãƒã®WALフラッシュä½ç½®%X/%Xより進んã§ã„ã¾ã™" -#: replication/walsender.c:707 replication/walsender.c:757 -#: replication/walsender.c:806 +#: replication/walsender.c:893 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ä¸­ã§ã¯å‘¼ã³å‡ºã›ã¾ã›ã‚“" + +#: replication/walsender.c:902 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ä¸­ã§å‘¼ã³å‡ºã™å¿…è¦ãŒã‚りã¾ã™" + +#: replication/walsender.c:907 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT㯠分離レベルREPEATABLE READã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã§å®Ÿè¡Œã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: replication/walsender.c:912 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT ã¯æœ€åˆã®å•ã„åˆã‚ã›ã®å®Ÿè¡Œå‰ã«å‘¼ã³å‡ºã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: replication/walsender.c:917 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT ã¯ã‚µãƒ–トランザクション内ã§å‘¼ã³å‡ºã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: replication/walsender.c:1063 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "昇格後ã«WALé€ä¿¡ãƒ—ロセスを終了ã—ã¾ã™" + +#: replication/walsender.c:1448 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "WALé€ä¿¡ãƒ—ロセスãŒåœæ­¢ãƒ¢ãƒ¼ãƒ‰ã®é–“ã¯æ–°ã—ã„コマンドを実行ã§ãã¾ã›ã‚“" + +#: replication/walsender.c:1481 +#, c-format +msgid "received replication command: %s" +msgstr "レプリケーションコマンドをå—ä¿¡ã—ã¾ã—ãŸ: %s" + +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1033 +#: tcop/postgres.c:1357 tcop/postgres.c:1617 tcop/postgres.c:2023 +#: tcop/postgres.c:2396 tcop/postgres.c:2475 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚¢ãƒœãƒ¼ãƒˆã—ã¾ã—ãŸã€‚トランザクションブロックãŒçµ‚ã‚ã‚‹ã¾ã§ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡è¦–ã•れã¾ã™" + +#: replication/walsender.c:1562 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "物ç†ãƒ¬ãƒ—リケーション用ã®WALé€ä¿¡ãƒ—ロセスã§SQLコマンドã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" + +#: replication/walsender.c:1610 replication/walsender.c:1626 #, c-format msgid "unexpected EOF on standby connection" msgstr "スタンãƒã‚¤æŽ¥ç¶šã§æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã—ãŸ" -#: replication/walsender.c:726 +#: replication/walsender.c:1640 #, c-format -#| msgid "unexpected message type \"%c\"" msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "CopyDoneã‚’å—ä¿¡ã—ãŸå¾Œã®æƒ³å®šã—ãªã„スタンãƒã‚¤ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—\"%c\"" -#: replication/walsender.c:774 +#: replication/walsender.c:1678 #, c-format msgid "invalid standby message type \"%c\"" -msgstr "スタンãƒã‚¤ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—\"%c\"ãŒç„¡åйã§ã™" +msgstr "スタンãƒã‚¤ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚¿ã‚¤ãƒ—\"%c\"ã¯ä¸æ­£ã§ã™" -#: replication/walsender.c:828 +#: replication/walsender.c:1719 #, c-format msgid "unexpected message type \"%c\"" msgstr "想定ã—ãªã„メッセージタイプ\"%c\"" -#: replication/walsender.c:1042 -#, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "スタンãƒã‚¤ã® \"%s\" ã¯ãƒ—ãƒ©ã‚¤ãƒžãƒªã«æ˜‡æ ¼ã—ã¾ã—ãŸ" - -#: replication/walsender.c:1135 +#: replication/walsender.c:2097 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "レプリケーションタイムアウトã«ã‚ˆã‚Š WAL é€ä¿¡ãƒ—ロセスを終了ã—ã¦ã„ã¾ã™" -#: replication/walsender.c:1205 +#: replication/walsender.c:2181 #, c-format -msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" -msgstr "è¦æ±‚ã•れãŸã‚¹ã‚¿ãƒ³ãƒã‚¤æŽ¥ç¶šãŒ max_wal_senders ã‚’è¶…ãˆã¦ã„ã¾ã™ï¼ˆç¾åœ¨ã¯ %d)" +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" ã¯ä¸Šæµã‚µãƒ¼ãƒã«è¿½ã„ã¤ãã¾ã—ãŸ" -#: replication/walsender.c:1355 +#: replication/walsender.c:2290 #, c-format -#| msgid "could not read from log file %u, segment %u, offset %u, length %lu: %m" -msgid "could not read from log segment %s, offset %u, length %lu: %m" -msgstr "ログセグメント %sã®ã‚ªãƒ•セット %uã‹ã‚‰é•·ã• %lu ã§èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "è¦æ±‚ã•れãŸã‚¹ã‚¿ãƒ³ãƒã‚¤æŽ¥ç¶šãŒ max_wal_senders ã‚’è¶…ãˆã¦ã„ã¾ã™ï¼ˆç¾åœ¨ã¯ %d)" -#: rewrite/rewriteDefine.c:113 rewrite/rewriteDefine.c:918 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "リレーション\"%2$s\"ã®ãƒ«ãƒ¼ãƒ«\"%1$s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: rewrite/rewriteDefine.c:299 +#: rewrite/rewriteDefine.c:296 #, c-format msgid "rule actions on OLD are not implemented" msgstr "OLDã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:300 +#: rewrite/rewriteDefine.c:297 #, c-format msgid "Use views or triggers instead." msgstr "代ã‚りã«ãƒ“ューã‹ãƒˆãƒªã‚¬ã‚’使用ã—ã¦ãã ã•ã„。" -#: rewrite/rewriteDefine.c:304 +#: rewrite/rewriteDefine.c:301 #, c-format msgid "rule actions on NEW are not implemented" msgstr "NEWã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:305 +#: rewrite/rewriteDefine.c:302 #, c-format msgid "Use triggers instead." msgstr "代ã‚りã«ãƒˆãƒªã‚¬ã‚’使用ã—ã¦ãã ã•ã„。" -#: rewrite/rewriteDefine.c:318 +#: rewrite/rewriteDefine.c:315 #, c-format msgid "INSTEAD NOTHING rules on SELECT are not implemented" msgstr "SELECTã«å¯¾ã™ã‚‹INSTEAD NOTHINGルールã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:319 +#: rewrite/rewriteDefine.c:316 #, c-format msgid "Use views instead." msgstr "代ã‚りã«ãƒ“ューを使用ã—ã¦ãã ã•ã„" -#: rewrite/rewriteDefine.c:327 +#: rewrite/rewriteDefine.c:324 #, c-format msgid "multiple actions for rules on SELECT are not implemented" msgstr "SELECTã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã«ãŠã‘る複数ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:338 +#: rewrite/rewriteDefine.c:334 #, c-format msgid "rules on SELECT must have action INSTEAD SELECT" msgstr "SELECTã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã¯INSTEAD SELECTアクションをæŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:346 +#: rewrite/rewriteDefine.c:342 #, c-format msgid "rules on SELECT must not contain data-modifying statements in WITH" msgstr "SELECT ã®ãƒ«ãƒ¼ãƒ«ã§ã¯ WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’å«ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:354 +#: rewrite/rewriteDefine.c:350 #, c-format msgid "event qualifications are not implemented for rules on SELECT" msgstr "SELECTã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã§ã¯ã‚¤ãƒ™ãƒ³ãƒˆæ¡ä»¶ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:379 +#: rewrite/rewriteDefine.c:377 #, c-format msgid "\"%s\" is already a view" msgstr "\"%s\"ã¯ã™ã§ã«ãƒ“ューã§ã™" -#: rewrite/rewriteDefine.c:403 +#: rewrite/rewriteDefine.c:401 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "\"%s\"用ã®ãƒ“ューã®ãƒ«ãƒ¼ãƒ«ã®åå‰ã¯\"%s\"ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:431 +#: rewrite/rewriteDefine.c:428 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "パーティションテーブル\"%s\"ã¯ãƒ“ューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "パーティションå­ãƒ†ãƒ¼ãƒ–ル\"%s\"ã¯ãƒ“ューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: rewrite/rewriteDefine.c:442 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" -msgstr "空ã§ã¯ã‚りã¾ã›ã‚“ã®ã§ãƒ†ãƒ¼ãƒ–ル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“" +msgstr "空ã§ã¯ãªã„ãŸã‚ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:439 +#: rewrite/rewriteDefine.c:450 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" -msgstr "トリガをæŒã£ã¦ã„ã‚‹ãŸã‚テーブル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "トリガをæŒã£ã¦ã„ã‚‹ãŸã‚ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:441 +#: rewrite/rewriteDefine.c:452 #, c-format msgid "In particular, the table cannot be involved in any foreign key relationships." -msgstr "具体的ã«ã¯ã€ãƒ†ãƒ¼ãƒ–ルã«å¤–部キー関係をæŒãŸã›ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "特ã«ã€ã“ã®ãƒ†ãƒ¼ãƒ–ルã¯ä¸€åˆ‡ã®å¤–部キー関係ã«çµ„ã¿è¾¼ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteDefine.c:446 +#: rewrite/rewriteDefine.c:457 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "インデックスをæŒã£ã¦ã„ã‚‹ãŸã‚テーブル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:452 +#: rewrite/rewriteDefine.c:463 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "å­ãƒ†ãƒ¼ãƒ–ルをæŒã£ã¦ã„ã‚‹ãŸã‚テーブル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:479 +#: rewrite/rewriteDefine.c:469 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹ãŸã‚ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: rewrite/rewriteDefine.c:475 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "行レベルセキュリティãƒãƒªã‚·ãŒã‚ã‚‹ãŸã‚ã€ãƒ†ãƒ¼ãƒ–ル\"%s\"をビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: rewrite/rewriteDefine.c:502 #, c-format msgid "cannot have multiple RETURNING lists in a rule" -msgstr "ルールã§ã¯è¤‡æ•°ã®RETURNING行をæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "ルールã¯è¤‡æ•°ã®RETURNINGリストをæŒã¤ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:484 +#: rewrite/rewriteDefine.c:507 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "æ¡ä»¶ä»˜ã®ãƒ«ãƒ¼ãƒ«ã§ã¯RETURNINGリストã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:488 +#: rewrite/rewriteDefine.c:511 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" -msgstr "INSTEAD以外ã®ãƒ«ãƒ¼ãƒ«ã§ã¯RETURNINGã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +msgstr "INSTEAD以外ã®ãƒ«ãƒ¼ãƒ«ã§ã¯RETURNINGリストã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:647 +#: rewrite/rewriteDefine.c:675 #, c-format msgid "SELECT rule's target list has too many entries" -msgstr "SELECTルールã®å¯¾è±¡ãƒªã‚¹ãƒˆã®é …ç›®ãŒå¤šã™ãŽã¾ã™" +msgstr "SELECTルールã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒªã‚¹ãƒˆã®è¦ç´ ãŒå¤šã™ãŽã¾ã™" -#: rewrite/rewriteDefine.c:648 +#: rewrite/rewriteDefine.c:676 #, c-format msgid "RETURNING list has too many entries" -msgstr "RETURNINGリストã®é …ç›®ãŒå¤šã™ãŽã¾ã™" +msgstr "RETURNINGリストã®è¦ç´ ãŒå¤šã™ãŽã¾ã™" -#: rewrite/rewriteDefine.c:664 +#: rewrite/rewriteDefine.c:703 #, c-format msgid "cannot convert relation containing dropped columns to view" -msgstr "削除ã•れãŸåˆ—ã‚’æŒã¤ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ビューã«å¤‰æ›ã§ãã¾ã›ã‚“" +msgstr "削除ã•れãŸåˆ—ã‚’æŒã¤ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’ビューã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:669 +#: rewrite/rewriteDefine.c:704 #, c-format -msgid "SELECT rule's target entry %d has different column name from \"%s\"" -msgstr "SELECTルールã®å¯¾è±¡é …ç›®%dã¯\"%s\"ã¨ç•°ãªã‚‹åˆ—åã‚’æŒã£ã¦ã„ã¾ã™" +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "削除ã•れãŸåˆ—ã‚’æŒã¤ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«RETURNINGリストを生æˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: rewrite/rewriteDefine.c:675 +#: rewrite/rewriteDefine.c:710 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECTルールã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚¨ãƒ³ãƒˆãƒª%dã¯åˆ—\"%s\"ã¨ã¯ç•°ãªã‚‹åˆ—åã‚’æŒã£ã¦ã„ã¾ã™" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECTã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚¨ãƒ³ãƒˆãƒªã¯\"%s\"ã¨å付ã‘られã¦ã„ã¾ã™ã€‚" + +#: rewrite/rewriteDefine.c:721 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "SELECTルールã®å¯¾è±¡é …ç›®%dã¯\"%s\"ã¨ç•°ãªã‚‹åˆ—型をæŒã£ã¦ã„ã¾ã™" -#: rewrite/rewriteDefine.c:677 +#: rewrite/rewriteDefine.c:723 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "RETURNINGリスト項目%dã¯\"%s\"ã¨ç•°ãªã‚‹åˆ—型をæŒã£ã¦ã„ã¾ã™" -#: rewrite/rewriteDefine.c:692 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECTã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆã‚¨ãƒ³ãƒˆãƒªã®åž‹ã¯%sã§ã™ãŒã€åˆ—ã®åž‹ã¯%sã§ã™ã€‚" + +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNINGリストã®è¦ç´ ã®åž‹ã¯%sã§ã™ãŒã€åˆ—ã®åž‹ã¯%sã§ã™ã€‚" + +#: rewrite/rewriteDefine.c:745 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "SELECTルールã®å¯¾è±¡é …ç›®%dã¯\"%s\"ã¨ç•°ãªã‚‹åˆ—ã®ã‚µã‚¤ã‚ºã‚’æŒã£ã¦ã„ã¾ã™" -#: rewrite/rewriteDefine.c:694 +#: rewrite/rewriteDefine.c:747 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "RETURNINGリスト項目%dã¯\"%s\"ã¨ç•°ãªã‚‹åˆ—ã®ã‚µã‚¤ã‚ºã‚’æŒã£ã¦ã„ã¾ã™" -#: rewrite/rewriteDefine.c:702 +#: rewrite/rewriteDefine.c:764 #, c-format msgid "SELECT rule's target list has too few entries" -msgstr "SELECTルールã®å¯¾è±¡ãƒªã‚¹ãƒˆã®é …ç›®ãŒå°‘ãªã™ãŽã¾ã™" +msgstr "SELECTルールã®ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒªã‚¹ãƒˆã®é …ç›®ãŒå°‘ãªã™ãŽã¾ã™" -#: rewrite/rewriteDefine.c:703 +#: rewrite/rewriteDefine.c:765 #, c-format msgid "RETURNING list has too few entries" msgstr "RETURNINGリストã®é …ç›®ãŒå°‘ãªã™ãŽã¾ã™" -#: rewrite/rewriteDefine.c:795 rewrite/rewriteDefine.c:909 -#: rewrite/rewriteSupport.c:112 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 +#: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "リレーション\"%2$s\"ã®ãƒ«ãƒ¼ãƒ«\"%1$s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: rewrite/rewriteDefine.c:928 +#: rewrite/rewriteDefine.c:990 #, c-format -#| msgid "multiple OFFSET clauses not allowed" msgid "renaming an ON SELECT rule is not allowed" msgstr "ON SELECTルールã®åå‰ã‚’変更ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:485 +#: rewrite/rewriteHandler.c:541 #, c-format msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" -msgstr "WITH ã®ã‚¯ã‚¨ãƒªãƒ¼å \"%s\" ãŒã€ãƒ«ãƒ¼ãƒ«ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¨æ›¸ãæ›ãˆã‚‰ã‚Œã‚ˆã†ã¨ã—ã¦ã„るクエリーã®ä¸¡æ–¹ã«ç¾ã‚Œã¦ã„ã¾ã™" +msgstr "WITH ã®å•ã„åˆã‚ã›å \"%s\" ãŒã€ãƒ«ãƒ¼ãƒ«ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã¨æ›¸ãæ›ãˆã‚‰ã‚Œã‚ˆã†ã¨ã—ã¦ã„ã‚‹å•ã„åˆã‚ã›ã®ä¸¡æ–¹ã«ç¾ã‚Œã¦ã„ã¾ã™" -#: rewrite/rewriteHandler.c:545 +#: rewrite/rewriteHandler.c:601 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "複数ルールã§ã¯RETURNINGリストをæŒã¤ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:876 rewrite/rewriteHandler.c:894 +#: rewrite/rewriteHandler.c:823 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "列\"%s\"ã¸ã®æŒ¿å…¥ã¯ã§ãã¾ã›ã‚“" + +#: rewrite/rewriteHandler.c:824 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "列\"%s\"㯠GENERATED ALWAYS ã¨ã—ã¦å®šç¾©ã•れã¦ã„ã¾ã™ã€‚" + +#: rewrite/rewriteHandler.c:826 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "OVERRIDING SYSTEM VALUE を指定ã™ã‚‹ã“ã¨ã§æŒ¿å…¥ã‚’強制ã§ãã¾ã™ã€‚" + +#: rewrite/rewriteHandler.c:838 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "列\"%s\"ã¯DEFAULTã«ã®ã¿æ›´æ–°å¯èƒ½ã§ã™" + +#: rewrite/rewriteHandler.c:1000 rewrite/rewriteHandler.c:1018 #, c-format msgid "multiple assignments to same column \"%s\"" msgstr "åŒã˜åˆ—\"%s\"ã«è¤‡æ•°ã®ä»£å…¥ãŒã‚りã¾ã™" -#: rewrite/rewriteHandler.c:1656 rewrite/rewriteHandler.c:2876 +#: rewrite/rewriteHandler.c:1921 #, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "リレーション\"%s\"ã®ãƒ«ãƒ¼ãƒ«ã§ç„¡é™å†å¸°ã‚’検出ã—ã¾ã—ãŸ" +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "リレーション\"%s\"ã®ãƒãƒªã‚·ã§ç„¡é™å†å¸°ã‚’検出ã—ã¾ã—ãŸ" + +#: rewrite/rewriteHandler.c:2241 +msgid "Junk view columns are not updatable." +msgstr "ã‚¸ãƒ£ãƒ³ã‚¯ãƒ“ãƒ¥ãƒ¼åˆ—ã¯æ›´æ–°ä¸å¯ã§ã™ã€‚" -#: rewrite/rewriteHandler.c:2004 +#: rewrite/rewriteHandler.c:2246 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "基底リレーションã®åˆ—ã§ã¯ãªã„ãƒ“ãƒ¥ãƒ¼åˆ—ã¯æ›´æ–°ä¸å¯ã§ã™ã€‚" + +#: rewrite/rewriteHandler.c:2249 +msgid "View columns that refer to system columns are not updatable." +msgstr "システム列をå‚ç…§ã™ã‚‹ãƒ“ãƒ¥ãƒ¼åˆ—ã¯æ›´æ–°ä¸å¯ã§ã™ã€‚" + +#: rewrite/rewriteHandler.c:2252 +msgid "View columns that return whole-row references are not updatable." +msgstr "全行å‚ç…§ã‚’è¿”ã™ãƒ“ãƒ¥ãƒ¼åˆ—ã¯æ›´æ–°ä¸å¯ã§ã™ã€‚" + +#: rewrite/rewriteHandler.c:2313 msgid "Views containing DISTINCT are not automatically updatable." -msgstr "DISTINCTã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "DISTINCTã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2007 +#: rewrite/rewriteHandler.c:2316 msgid "Views containing GROUP BY are not automatically updatable." -msgstr "GROUP BYã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "GROUP BYã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2010 +#: rewrite/rewriteHandler.c:2319 msgid "Views containing HAVING are not automatically updatable." -msgstr "HAVINGã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "HAVINGã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2013 +#: rewrite/rewriteHandler.c:2322 msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." -msgstr "UNIONã€INTERSECTã€EXCEPTã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "UNIONã€INTERSECTã€EXCEPTã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2016 +#: rewrite/rewriteHandler.c:2325 msgid "Views containing WITH are not automatically updatable." -msgstr "WITHã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "WITHã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2019 +#: rewrite/rewriteHandler.c:2328 msgid "Views containing LIMIT or OFFSET are not automatically updatable." -msgstr "LIMITã€OFFSETã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "LIMITã€OFFSETã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" + +#: rewrite/rewriteHandler.c:2340 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "集約関数を返ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2027 -msgid "Security-barrier views are not automatically updatable." -msgstr "セキュリティä¿è­·ã•れãŸãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +#: rewrite/rewriteHandler.c:2343 +msgid "Views that return window functions are not automatically updatable." +msgstr "ウィンドウ関数を返ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2034 rewrite/rewriteHandler.c:2038 -#: rewrite/rewriteHandler.c:2045 +#: rewrite/rewriteHandler.c:2346 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "集åˆè¿”å´é–¢æ•°ã‚’è¿”ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" + +#: rewrite/rewriteHandler.c:2353 rewrite/rewriteHandler.c:2357 +#: rewrite/rewriteHandler.c:2365 msgid "Views that do not select from a single table or view are not automatically updatable." -msgstr "å˜ä¸€ã®ãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯ãƒ“ューã‹ã‚‰selectã—ã¦ã„ãªã„ビューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +msgstr "å˜ä¸€ã®ãƒ†ãƒ¼ãƒ–ルã¾ãŸã¯ãƒ“ューã‹ã‚‰selectã—ã¦ã„ãªã„ビューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2068 -msgid "Views that return columns that are not columns of their base relation are not automatically updatable." -msgstr "基リレーションã«å­˜åœ¨ã—ãªã„列を返ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +#: rewrite/rewriteHandler.c:2368 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "TABLESAMPLEã‚’å«ã‚€ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2071 -msgid "Views that return system columns are not automatically updatable." -msgstr "システム列を返ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +#: rewrite/rewriteHandler.c:2392 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "æ›´æ–°å¯èƒ½ãªåˆ—ã‚’æŒãŸãªã„ビューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“。" -#: rewrite/rewriteHandler.c:2074 -msgid "Views that return whole-row references are not automatically updatable." -msgstr "行全体ã¸ã®å‚ç…§ã‚’è¿”ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +#: rewrite/rewriteHandler.c:2849 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "ビュー\"%2$s\"ã®åˆ—\"%1$s\"ã¸ã®æŒ¿å…¥ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2077 -msgid "Views that return the same column more than once are not automatically updatable." -msgstr "åŒã˜åˆ—を複数返ã™ãƒ“ューã¯è‡ªå‹•æ›´æ–°ã§ãã¾ã›ã‚“" +#: rewrite/rewriteHandler.c:2857 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "ビュー\"%2$s\"ã®åˆ—\"%1$s\"ã¯æ›´æ–°ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2699 +#: rewrite/rewriteHandler.c:3327 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒã‚ã‚‹å ´åˆã¯ DO INSTEAD NOTHING ルールã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2713 +#: rewrite/rewriteHandler.c:3341 #, c-format msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒã‚ã‚‹å ´åˆã¯ã€æ¡ä»¶ä»˜ã DO INSTEAD ルールã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2717 +#: rewrite/rewriteHandler.c:3345 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒã‚ã‚‹å ´åˆã¯ DO ALSO ルールã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2722 +#: rewrite/rewriteHandler.c:3350 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "WITH ã«ãƒ‡ãƒ¼ã‚¿ã‚’変更ã™ã‚‹ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆãŒã‚ã‚‹å ´åˆã¯ãƒžãƒ«ãƒã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã® DO INSTEAD ルールã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2913 +#: rewrite/rewriteHandler.c:3569 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "リレーション\"%s\"ã¸ã®INSERT RETURNINGを行ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2915 +#: rewrite/rewriteHandler.c:3571 #, c-format msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "RETURNINGå¥ã‚’æŒã¤ç„¡æ¡ä»¶ã®ON INSERT DO INSTEADルールãŒå¿…è¦ã§ã™ã€‚" -#: rewrite/rewriteHandler.c:2920 +#: rewrite/rewriteHandler.c:3576 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "リレーション\"%s\"ã¸ã®UPDATE RETURNINGを行ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2922 +#: rewrite/rewriteHandler.c:3578 #, c-format msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "RETURNINGå¥ã‚’æŒã¤ç„¡æ¡ä»¶ã®ON UPDATE DO INSTEADルールãŒå¿…è¦ã§ã™ã€‚" -#: rewrite/rewriteHandler.c:2927 +#: rewrite/rewriteHandler.c:3583 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "リレーション\"%s\"ã¸ã®DELETE RETURNINGを行ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: rewrite/rewriteHandler.c:2929 +#: rewrite/rewriteHandler.c:3585 #, c-format msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "RETURNINGå¥ã‚’æŒã¤ç„¡æ¡ä»¶ã®ON DELETE DO INSTEADルールãŒå¿…è¦ã§ã™ã€‚" -#: rewrite/rewriteHandler.c:2993 +#: rewrite/rewriteHandler.c:3603 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "ON CONFLICTå¥ã‚’ä¼´ã†INSERTã¯ã€INSERTã¾ãŸã¯UPDATEルールをæŒã¤ãƒ†ãƒ¼ãƒ–ルã§ã¯ä½¿ãˆã¾ã›ã‚“" + +#: rewrite/rewriteHandler.c:3660 #, c-format msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" -msgstr "複数クエリーã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã«ã‚ˆã‚Šæ›¸ãæ›ãˆã‚‰ã‚ŒãŸã‚¯ã‚¨ãƒªãƒ¼ã§ã¯ WITH を使用ã§ãã¾ã›ã‚“" +msgstr "複数å•ã„åˆã‚ã›ã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ«ã«ã‚ˆã‚Šæ›¸ãæ›ãˆã‚‰ã‚ŒãŸå•ã„åˆã‚ã›ã§ã¯ WITH を使用ã§ãã¾ã›ã‚“" -#: rewrite/rewriteManip.c:1020 +#: rewrite/rewriteManip.c:1003 #, c-format msgid "conditional utility statements are not implemented" msgstr "æ¡ä»¶ä»˜ãã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£æ–‡ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteManip.c:1185 +#: rewrite/rewriteManip.c:1169 #, c-format msgid "WHERE CURRENT OF on a view is not implemented" msgstr "ビューã«å¯¾ã™ã‚‹WHERE CURRENT OFã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: rewrite/rewriteSupport.c:154 -#, c-format -msgid "rule \"%s\" does not exist" -msgstr "ルール\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" - -#: rewrite/rewriteSupport.c:167 -#, c-format -msgid "there are multiple rules named \"%s\"" -msgstr "複数ã®\"%s\"ã¨ã„ã†åå‰ã®ãƒ«ãƒ¼ãƒ«ãŒã‚りã¾ã™" - -#: rewrite/rewriteSupport.c:168 +#: rewrite/rewriteManip.c:1503 #, c-format -msgid "Specify a relation name as well as a rule name." -msgstr "ルールåã«åŠ ãˆãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³åを指定ã—ã¦ãã ã•ã„" +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "ON UPDATE ルールã®NEW変数ã¯ã€å¯¾è±¡ã®UPDATEコマンドã§ã®è¤‡æ•°åˆ—代入ã®ä¸€éƒ¨ã¨ãªã‚‹åˆ—ã‚’å‚ç…§ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: scan.l:423 +#: scan.l:445 msgid "unterminated /* comment" msgstr "/*コメントãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: scan.l:452 +#: scan.l:474 msgid "unterminated bit string literal" -msgstr "ビット文字列リテラルã®çµ‚端ãŒã‚りã¾ã›ã‚“" +msgstr "ビット列リテラルã®çµ‚端ãŒã‚りã¾ã›ã‚“" -#: scan.l:473 +#: scan.l:495 msgid "unterminated hexadecimal string literal" msgstr "16進数文字列リテラルã®çµ‚端ãŒã‚りã¾ã›ã‚“" -#: scan.l:523 +#: scan.l:545 #, c-format msgid "unsafe use of string constant with Unicode escapes" msgstr "Unicodeエスケープを使ã£ãŸæ–‡å­—列定数ã®å±é™ºãªä½¿ç”¨" -#: scan.l:524 +#: scan.l:546 #, c-format msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." msgstr "Unicodeエスケープã¯standard_conforming_stringsãŒç„¡åŠ¹ãªæ™‚ã«ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" -#: scan.l:567 scan.l:759 +#: scan.l:592 scan.l:791 msgid "invalid Unicode escape character" -msgstr "Unicode ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªUnicodeエスケープ文字" -#: scan.l:592 scan.l:600 scan.l:608 scan.l:609 scan.l:610 scan.l:1288 -#: scan.l:1315 scan.l:1319 scan.l:1357 scan.l:1361 scan.l:1383 +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 +#: scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 msgid "invalid Unicode surrogate pair" -msgstr "Unicode ã®ã‚µãƒ­ã‚²ãƒ¼ãƒˆãƒšã‚¢ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªUnicodeサロゲートペア" -#: scan.l:614 +#: scan.l:640 #, c-format msgid "invalid Unicode escape" -msgstr "Unicode ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªUnicodeエスケープ" -#: scan.l:615 +#: scan.l:641 #, c-format msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." -msgstr "Unicode エスケープ㯠\\uXXXX ã¾ãŸã¯ \\UXXXXXXXX ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "Unicodeエスケープã¯\\uXXXXã¾ãŸã¯\\UXXXXXXXXã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: scan.l:626 +#: scan.l:652 #, c-format msgid "unsafe use of \\' in a string literal" msgstr "文字列リテラルã§å®‰å…¨ã§ã¯ãªã„\\'ãŒä½¿ç”¨ã•れã¾ã—ãŸã€‚" -#: scan.l:627 +#: scan.l:653 #, c-format msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." msgstr "文字列内ã§å¼•用符を記述ã™ã‚‹ã«ã¯''を使用ã—ã¦ãã ã•ã„。\\'ã¯ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®ã¿ã§æœ‰åйãªç¬¦å·åŒ–å½¢å¼ã§ã¯å®‰å…¨ã§ã¯ã‚りã¾ã›ã‚“。" -#: scan.l:702 +#: scan.l:728 msgid "unterminated dollar-quoted string" msgstr "文字列ã®ãƒ‰ãƒ«å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: scan.l:719 scan.l:741 scan.l:754 +#: scan.l:745 scan.l:771 scan.l:786 msgid "zero-length delimited identifier" -msgstr "区切りã¤ã識別å­ã®é•·ã•ãŒã‚¼ãƒ­ã§ã™" +msgstr "二é‡å¼•用符ã§å›²ã¾ã‚ŒãŸè­˜åˆ¥å­ã®é•·ã•ãŒã‚¼ãƒ­ã§ã™" -#: scan.l:773 +#: scan.l:806 syncrep_scanner.l:91 msgid "unterminated quoted identifier" msgstr "識別å­ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: scan.l:877 +#: scan.l:969 msgid "operator too long" msgstr "演算å­ãŒé•·ã™ãŽã¾ã™" #. translator: %s is typically the translation of "syntax error" -#: scan.l:1035 +#: scan.l:1125 #, c-format msgid "%s at end of input" msgstr "å…¥åŠ›ã®æœ€å¾Œã§ %s" #. translator: first %s is typically the translation of "syntax error" -#: scan.l:1043 +#: scan.l:1133 #, c-format msgid "%s at or near \"%s\"" msgstr "\"%2$s\"ã¾ãŸã¯ãã®è¿‘辺ã§%1$s" -#: scan.l:1204 scan.l:1236 +#: scan.l:1294 scan.l:1326 msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" msgstr "サーãƒãƒ¼ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãŒ UTF-8 ã§ã¯ãªã„å ´åˆã€ã‚³ãƒ¼ãƒ‰ãƒã‚¤ãƒ³ãƒˆã®å€¤ãŒ 007F 以上ã«ã¤ã„ã¦ã¯ Unicode ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—値ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: scan.l:1232 scan.l:1375 +#: scan.l:1322 scan.l:1467 msgid "invalid Unicode escape value" -msgstr "Unicode ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—シーケンスãŒç„¡åйã§ã™" +msgstr "䏿­£ãªUnicodeエスケープシーケンスã®å€¤" -#: scan.l:1431 +#: scan.l:1531 #, c-format msgid "nonstandard use of \\' in a string literal" -msgstr "文字列リテラルã§éžæ¨™æº–çš„ãª\\'ãŒä½¿ç”¨ã•れã¾ã—ãŸã€‚" +msgstr "文字列リテラルãªã„ã§ã®\\'ã®éžæ¨™æº–çš„ãªä½¿ç”¨" -#: scan.l:1432 +#: scan.l:1532 #, c-format msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." -msgstr "文字列内ã§å¼•用符を記述ã™ã‚‹ã«ã¯''を使用ã—ã¦ãã ã•ã„。ã¾ãŸã¯ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文(E'...')を使用ã—ã¦ãã ã•ã„。" +msgstr "文字列内ã§å˜ä¸€å¼•用符を記述ã™ã‚‹ã«ã¯''ã€ã¾ãŸã¯ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文(E'...')を使用ã—ã¦ãã ã•ã„。" -#: scan.l:1441 +#: scan.l:1541 #, c-format msgid "nonstandard use of \\\\ in a string literal" -msgstr "文字列リテラルã§éžæ¨™æº–çš„ãª\\\\ãŒä½¿ç”¨ã•れã¾ã—ãŸã€‚" +msgstr "文字列リテラル内ã§ã®\\\\ã®éžæ¨™æº–çš„ãªä½¿ç”¨" -#: scan.l:1442 +#: scan.l:1542 #, c-format msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." -msgstr "ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ç”¨ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文ã€ä¾‹ãˆã°E'\\\\'を使用ã—ã¦ãã ã•ã„。" +msgstr "ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文ã€ä¾‹ãˆã°E'\\\\'を使用ã—ã¦ãã ã•ã„。" -#: scan.l:1456 +#: scan.l:1556 #, c-format msgid "nonstandard use of escape in a string literal" -msgstr "文字列リテラル内ã§éžæ¨™æº–çš„ãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ãŒä½¿ç”¨ã•れã¾ã—ãŸ" +msgstr "文字列リテラル内ã§ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã®éžæ¨™æº–çš„ãªä½¿ç”¨" -#: scan.l:1457 +#: scan.l:1557 #, c-format msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." -msgstr "エスケープ用ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文ã€ä¾‹ãˆã°E'\\\\r\\\\n'を使用ã—ã¦ãã ã•ã„" +msgstr "エスケープã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列構文ã€ä¾‹ãˆã°E'\\r\\n'を使用ã—ã¦ãã ã•ã„。" -#: snowball/dict_snowball.c:180 +#: snowball/dict_snowball.c:177 #, c-format msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" -msgstr "言語\"%s\"ãŠã‚ˆã³ç¬¦å·åŒ–æ–¹å¼\"%s\"用ã«ä½¿ç”¨å¯èƒ½ãªSnowball語幹抽出ãŒã‚りã¾ã›ã‚“" +msgstr "言語\"%s\"ãŠã‚ˆã³ç¬¦å·åŒ–æ–¹å¼\"%s\"用ã«ä½¿ç”¨å¯èƒ½ãªSnowballステマãŒã‚りã¾ã›ã‚“" -#: snowball/dict_snowball.c:203 tsearch/dict_ispell.c:73 -#: tsearch/dict_simple.c:48 +#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 #, c-format msgid "multiple StopWords parameters" -msgstr "é‡è¤‡ã™ã‚‹StopWordsパラメータ" +msgstr "é‡è¤‡ã—ãŸStopWordsパラメータ" -#: snowball/dict_snowball.c:212 +#: snowball/dict_snowball.c:209 #, c-format msgid "multiple Language parameters" -msgstr "é‡è¤‡ã™ã‚‹Languageパラメータ" +msgstr "é‡è¤‡ã—ãŸLanguageパラメータ" -#: snowball/dict_snowball.c:219 +#: snowball/dict_snowball.c:216 #, c-format msgid "unrecognized Snowball parameter: \"%s\"" -msgstr "未知ã®Snowballパラメータ: \"%s\"" +msgstr "èªè­˜ã§ããªã„Snowballパラメータ: \"%s\"" -#: snowball/dict_snowball.c:227 +#: snowball/dict_snowball.c:224 #, c-format msgid "missing Language parameter" msgstr "LanguageパラメータãŒã‚りã¾ã›ã‚“" -#: storage/buffer/bufmgr.c:140 storage/buffer/bufmgr.c:245 +#: statistics/dependencies.c:534 +#, c-format +msgid "invalid zero-length item array in MVDependencies" +msgstr "MVDependenciesã«ä¸æ­£ãªé•·ã•0ã®é …ç›®é…列ãŒã‚りã¾ã™" + +#: statistics/dependencies.c:672 statistics/dependencies.c:725 +#: statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 +#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 +#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 +#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 +#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 +#: utils/adt/pseudotypes.c:393 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "%såž‹ã®å€¤ã¯å—ã‘付ã‘られã¾ã›ã‚“" + +#: statistics/extended_stats.c:104 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "統計オブジェクト\"%s.%s\"ãŒãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³\"%s.%s\"ã«å¯¾ã—ã¦è¨ˆç®—ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: statistics/mvdistinct.c:262 +#, c-format +msgid "invalid ndistinct magic %08x (expected %08x)" +msgstr "䏿­£ãªndistinctã®ãƒžã‚¸ãƒƒã‚¯%08x (%08xã§ã‚ã‚‹ã¯ãšã§ã™)" + +#: statistics/mvdistinct.c:267 +#, c-format +msgid "invalid ndistinct type %d (expected %d)" +msgstr "䏿­£ãªndistinctタイプ%d (%d ã§ã‚ã‚‹ã¯ãšã§ã™)" + +#: statistics/mvdistinct.c:272 +#, c-format +msgid "invalid zero-length item array in MVNDistinct" +msgstr "MVNDistinctã«ä¸æ­£ãªé•·ã•0ã®é …ç›®é…列ãŒã‚りã¾ã™" + +#: statistics/mvdistinct.c:281 +#, c-format +msgid "invalid MVNDistinct size %zd (expected at least %zd)" +msgstr "䏿­£ãªMVNDistinctã®ã‚µã‚¤ã‚º%zd (最低%zdã§ã‚ã‚‹ã¯ãšã§ã™)" + +#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "ä»–ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ä¸€æ™‚テーブルã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“" -#: storage/buffer/bufmgr.c:382 +#: storage/buffer/bufmgr.c:807 #, c-format msgid "unexpected data beyond EOF in block %u of relation %s" msgstr "リレーション %2$s ã® %1$u ブロック目ã§ã€EOF ã®å…ˆã«æƒ³å®šå¤–ã®ãƒ‡ãƒ¼ã‚¿ã‚’検出ã—ã¾ã—ãŸ" -#: storage/buffer/bufmgr.c:384 +#: storage/buffer/bufmgr.c:809 #, c-format msgid "This has been seen to occur with buggy kernels; consider updating your system." msgstr "ã“れã¯ã‚«ãƒ¼ãƒãƒ«ã®ä¸å…·åˆã§ç™ºç”Ÿã—ãŸæ¨¡æ§˜ã§ã™ã€‚ã‚·ã‚¹ãƒ†ãƒ ã®æ›´æ–°ã‚’検討ã—ã¦ãã ã•ã„。" -#: storage/buffer/bufmgr.c:471 +#: storage/buffer/bufmgr.c:907 #, c-format -#| msgid "invalid page header in block %u of relation %s; zeroing out page" msgid "invalid page in block %u of relation %s; zeroing out page" -msgstr "リレーション %2$s ã® %1$u ブロック目ã®ãƒšãƒ¼ã‚¸ãŒç„¡åйã§ã™ï¼šãƒšãƒ¼ã‚¸ã‚’ゼロã§åŸ‹ã‚ã¾ã—ãŸ" +msgstr "リレーション %2$s ã® %1$u ブロック目ã®ãƒšãƒ¼ã‚¸ãŒä¸æ­£ã§ã™: ページをゼロã§åŸ‹ã‚ã¾ã—ãŸ" -#: storage/buffer/bufmgr.c:3141 +#: storage/buffer/bufmgr.c:4013 #, c-format msgid "could not write block %u of %s" msgstr "%u ブロックを %s ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ" -#: storage/buffer/bufmgr.c:3143 +#: storage/buffer/bufmgr.c:4015 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "複数回失敗ã—ã¾ã—㟠---ãšã£ã¨æ›¸ãè¾¼ã¿ã‚¨ãƒ©ãƒ¼ãŒç¶šãã‹ã‚‚ã—れã¾ã›ã‚“。" -#: storage/buffer/bufmgr.c:3164 storage/buffer/bufmgr.c:3183 +#: storage/buffer/bufmgr.c:4036 storage/buffer/bufmgr.c:4055 #, c-format msgid "writing block %u of relation %s" msgstr "ブロック %u ã‚’ リレーション %s ã«æ›¸ã込んã§ã„ã¾ã™" -#: storage/buffer/localbuf.c:190 +#: storage/buffer/bufmgr.c:4358 +#, c-format +msgid "snapshot too old" +msgstr "スナップショットãŒå¤ã™ãŽã¾ã™" + +#: storage/buffer/localbuf.c:199 #, c-format msgid "no empty local buffer available" msgstr "利用ã§ãã‚‹ã€ç©ºã®ãƒ­ãƒ¼ã‚«ãƒ«ãƒãƒƒãƒ•ã‚¡ãŒã‚りã¾ã›ã‚“" -#: storage/file/fd.c:450 +#: storage/buffer/localbuf.c:427 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ä¸€æ™‚テーブルã«ã¯ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“" + +#: storage/file/buffile.c:317 +#, fuzzy, c-format +#| msgid "could not open temporary file \"%s\": %m" +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "一時ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/buffile.c:814 +#, fuzzy, c-format +#| msgid "could not determine size of temporary file \"%s\"" +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "一時ファイル\"%s\"ã®ã‚µã‚¤ã‚ºã®ç¢ºèªã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: storage/file/fd.c:451 storage/file/fd.c:523 storage/file/fd.c:559 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "ダーティーデータを書ã出ã—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:481 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "ダーティーデータã®ã‚µã‚¤ã‚ºã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:533 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "ãƒ‡ãƒ¼ã‚¿ã®æ›¸ã出ã—中ã«munmap()ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: storage/file/fd.c:734 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "ファイル\"%s\"ã‹ã‚‰\"%s\"ã¸ã®ãƒªãƒ³ã‚¯ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:828 #, c-format msgid "getrlimit failed: %m" msgstr "getrlimitãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#: storage/file/fd.c:540 +#: storage/file/fd.c:918 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "サーãƒãƒ—ロセスを起動ã•ã›ã‚‹ãŸã‚ã«åˆ©ç”¨ã§ãるファイル記述å­ãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: storage/file/fd.c:541 +#: storage/file/fd.c:919 #, c-format msgid "System allows %d, we need at least %d." msgstr "システムã§ã¯%d使用ã§ãã¾ã™ãŒã€å°‘ãªãã¨ã‚‚%då¿…è¦ã§ã™" -#: storage/file/fd.c:582 storage/file/fd.c:1616 storage/file/fd.c:1709 -#: storage/file/fd.c:1857 +#: storage/file/fd.c:970 storage/file/fd.c:2379 storage/file/fd.c:2489 +#: storage/file/fd.c:2640 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "ファイル記述å­ãŒä¸è¶³ã—ã¦ã„ã¾ã™: %m: 解放後å†å®Ÿè¡Œã—ã¦ãã ã•ã„" -#: storage/file/fd.c:1156 +#: storage/file/fd.c:1313 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "一時ファイル: パス \"%s\"ã€ã‚µã‚¤ã‚º %lu" -#: storage/file/fd.c:1305 +#: storage/file/fd.c:1445 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "一時ディレクトリ\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:1452 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "一時サブディレクトリ\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:1645 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:1680 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:1721 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "一時ファイル\"%s\"ã‚’ unlink ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/fd.c:2010 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "一時ファイルã®ã‚µã‚¤ã‚ºãŒtemp_file_limit(%d KB)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: storage/file/fd.c:1592 storage/file/fd.c:1642 +#: storage/file/fd.c:2355 storage/file/fd.c:2414 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "ファイル\"%2$s\"をオープンã—よã†ã¨ã—ãŸæ™‚ã«maxAllocatedDescs(%1$d)を超ãˆã¾ã—ãŸ" -#: storage/file/fd.c:1682 +#: storage/file/fd.c:2459 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "コマンド\"%2$s\"を実行ã—よã†ã¨ã—ãŸæ™‚ã«maxAllocatedDescs(%1$d)を超ãˆã¾ã—ãŸ" -#: storage/file/fd.c:1833 +#: storage/file/fd.c:2616 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "ディレクトリ\"%2$s\"をオープンã—よã†ã¨ã—ãŸæ™‚ã«maxAllocatedDescs(%1$d)を超ãˆã¾ã—ãŸ" -#: storage/file/fd.c:1916 +#: storage/file/fd.c:2707 #, c-format msgid "could not read directory \"%s\": %m" msgstr "ディレクトリ\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/ipc/shmem.c:190 storage/lmgr/lock.c:863 storage/lmgr/lock.c:891 -#: storage/lmgr/lock.c:2556 storage/lmgr/lock.c:3655 storage/lmgr/lock.c:3720 -#: storage/lmgr/lock.c:4009 storage/lmgr/predicate.c:2320 -#: storage/lmgr/predicate.c:2335 storage/lmgr/predicate.c:3731 -#: storage/lmgr/predicate.c:4875 storage/lmgr/proc.c:196 -#: utils/hash/dynahash.c:966 +#: storage/file/fd.c:3139 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "ä¸€æ™‚ãƒ•ã‚¡ã‚¤ãƒ«ç”¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æƒ³å®šå¤–ã®ãƒ•ァイルãŒã‚りã¾ã—ãŸ: \"%s\"" + +#: storage/file/fd.c:3461 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"ã‚’ rmdir ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/file/sharedfileset.c:93 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "ã™ã§ã«ç ´æ£„ã•れã¦ã„ã‚‹ãŸã‚ SharedFileSet ã«ã‚¢ã‚¿ãƒƒãƒã§ãã¾ã›ã‚“" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "動的共有メモリã®åˆ¶å¾¡ã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒå£Šã‚Œã¦ã„ã¾ã™" + +#: storage/ipc/dsm.c:398 +#, c-format +msgid "dynamic shared memory is disabled" +msgstr "動的共有メモリãŒç„¡åйã«ã•れã¦ã„ã¾ã™" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +msgstr "dynamic_shared_memory_type ã‚’\"none\"以外ã®å€¤ã«è¨­å®šã—ã¦ãã ã•ã„。" + +#: storage/ipc/dsm.c:419 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "動的共有メモリã®åˆ¶å¾¡ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã®å†…容ãŒä¸æ­£ã§ã™" + +#: storage/ipc/dsm.c:515 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "動的共有メモリセグメントãŒå¤šã™ãŽã¾ã™" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 +#: storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 +#: storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をアンマップã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 +#: storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 +#: storage/ipc/dsm_impl.c:904 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 +#: storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"ã¸ã®statãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 +#: storage/ipc/dsm_impl.c:997 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "共有メモリセグメント\"%s\"ã®%zuãƒã‚¤ãƒˆã¸ã®ã‚µã‚¤ã‚ºå¤‰æ›´ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 +#: storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"をマップã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:576 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "共有メモリセグメントをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:775 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "共有メモリセグメント\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "\"%s\"ã®ãƒãƒ³ãƒ‰ãƒ«ã®è¤‡è£½ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: storage/ipc/latch.c:829 +#, c-format +msgid "epoll_ctl() failed: %m" +msgstr "epoll_ctl() ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: storage/ipc/latch.c:1060 +#, c-format +msgid "epoll_wait() failed: %m" +msgstr "epoll_wait() ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: storage/ipc/latch.c:1182 +#, c-format +msgid "poll() failed: %m" +msgstr "poll() ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 +#: storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 +#: storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 +#: storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 +#: storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" -msgstr "共有メモリãŒä¸è¶³ã—ã¦ã„ã¾ã™" +msgstr "共有メモリãŒè¶³ã‚Šã¾ã›ã‚“" -#: storage/ipc/shmem.c:346 storage/ipc/shmem.c:399 +#: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 #, c-format -msgid "not enough shared memory for data structure \"%s\" (%lu bytes requested)" -msgstr "データ構造体 \"%s\" 用ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™ï¼ˆ %lu ãƒã‚¤ãƒˆå¿…è¦ï¼‰" +msgid "out of shared memory (%zu bytes requested)" +msgstr "共有メモリãŒè¶³ã‚Šã¾ã›ã‚“ (%zu ãƒã‚¤ãƒˆè¦æ±‚ã—ã¾ã—ãŸ)" -#: storage/ipc/shmem.c:365 +#: storage/ipc/shmem.c:421 #, c-format msgid "could not create ShmemIndex entry for data structure \"%s\"" msgstr "データ構造体 \"%s\" ã®ãŸã‚ã® ShmemIndex エントリを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: storage/ipc/shmem.c:380 +#: storage/ipc/shmem.c:436 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "データ構造体\"%s\"ã®ãŸã‚ã®ShmemIndexエントリã®ã‚µã‚¤ã‚ºãŒèª¤ã£ã¦ã„ã¾ã™: %zuãƒã‚¤ãƒˆã‚’期待ã—ã¾ã—ãŸãŒã€å®Ÿéš›ã¯%zuãƒã‚¤ãƒˆã§ã—ãŸ" + +#: storage/ipc/shmem.c:453 #, c-format -msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %lu, actual %lu" -msgstr "データ構造体 \"%s\" ã®ãŸã‚ã® ShmemIndex エントリã®ã‚µã‚¤ã‚ºãŒèª¤ã£ã¦ã„ã¾ã™ï¼šæœŸå¾…値ï¼%luã€å®Ÿéš›ï¼%lu" +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "データ構造体\"%s\"ã®ãŸã‚ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™ ( %zu ãƒã‚¤ãƒˆãŒå¿…è¦)" -#: storage/ipc/shmem.c:427 storage/ipc/shmem.c:446 +#: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 #, c-format msgid "requested shared memory size overflows size_t" msgstr "è¦æ±‚ã•れãŸå…±æœ‰ãƒ¡ãƒ¢ãƒªã®ã‚µã‚¤ã‚ºã¯size_tã‚’è¶…ãˆã¦ã„ã¾ã™" -#: storage/ipc/standby.c:499 tcop/postgres.c:2941 +#: storage/ipc/standby.c:558 tcop/postgres.c:3056 #, c-format msgid "canceling statement due to conflict with recovery" -msgstr "リカãƒãƒªãƒ¼ã§ç«¶åˆãŒç™ºç”Ÿã—ãŸãŸã‚ステートメントをキャンセルã—ã¦ã„ã¾ã™" +msgstr "リカãƒãƒªã§ç«¶åˆãŒç™ºç”Ÿã—ãŸãŸã‚ステートメントをキャンセルã—ã¦ã„ã¾ã™" -#: storage/ipc/standby.c:500 tcop/postgres.c:2222 +#: storage/ipc/standby.c:559 tcop/postgres.c:2329 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "リカãƒãƒªæ™‚ã«ãƒ¦ãƒ¼ã‚¶ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒãƒãƒƒãƒ•ã‚¡ã®ãƒ‡ãƒƒãƒ‰ãƒ­ãƒƒã‚¯ã‚’引ãèµ·ã“ã—ã¾ã—ãŸã€‚" -#: storage/large_object/inv_api.c:270 +#: storage/large_object/inv_api.c:190 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "OID%uã€ãƒšãƒ¼ã‚¸%dã«å¯¾å¿œã™ã‚‹pg_largeobjectã®ã‚¨ãƒ³ãƒˆãƒªã®ãƒ‡ãƒ¼ã‚¿ãƒ•ィールドã®å¤§ãã•%dã¯ä¸æ­£ã§ã™" + +#: storage/large_object/inv_api.c:271 #, c-format -#| msgid "invalid OID for large object (%u)\n" msgid "invalid flags for opening a large object: %d" -msgstr "ラージオブジェクトを開ããŸã‚ã®ãƒ•ラグãŒç„¡åйã§ã™: %d" +msgstr "ラージオブジェクトを開ããŸã‚ã®ãƒ•ラグãŒä¸æ­£ã§ã™: %d" -#: storage/large_object/inv_api.c:409 +#: storage/large_object/inv_api.c:461 #, c-format -#| msgid "invalid escape string" msgid "invalid whence setting: %d" -msgstr "無効ãªwhence設定: %d" +msgstr "䏿­£ãªwhence設定: %d" -#: storage/large_object/inv_api.c:572 +#: storage/large_object/inv_api.c:633 #, c-format -#| msgid "invalid large-object descriptor: %d" msgid "invalid large object write request size: %d" -msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ›¸ã出ã—è¦æ±‚サイズãŒç„¡åйã§ã™: %d" +msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ›¸ã出ã—è¦æ±‚サイズãŒä¸æ­£ã§ã™: %d" -#: storage/lmgr/deadlock.c:925 +#: storage/lmgr/deadlock.c:1109 #, c-format msgid "Process %d waits for %s on %s; blocked by process %d." msgstr "プロセス %d 㯠%s ã‚’ %s ã§å¾…機ã—ã¦ã„ã¾ã—ãŸãŒã€ãƒ—ロセス %d ã§ãƒ–ロックã•れã¾ã—ãŸ" -#: storage/lmgr/deadlock.c:944 +#: storage/lmgr/deadlock.c:1128 #, c-format msgid "Process %d: %s" msgstr "プロセス %d: %s" -#: storage/lmgr/deadlock.c:953 +#: storage/lmgr/deadlock.c:1137 #, c-format msgid "deadlock detected" msgstr "デッドロックを検出ã—ã¾ã—ãŸ" -#: storage/lmgr/deadlock.c:956 +#: storage/lmgr/deadlock.c:1140 #, c-format msgid "See server log for query details." -msgstr "クエリーã®è©³ç´°ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„" +msgstr "å•ã„åˆã‚ã›ã®è©³ç´°ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„" + +#: storage/lmgr/lmgr.c:767 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ル(%1$u,%2$u)ã®æ›´æ–°ä¸­" + +#: storage/lmgr/lmgr.c:770 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ル(%1$u,%2$u)ã®å‰Šé™¤ä¸­" + +#: storage/lmgr/lmgr.c:773 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ル(%1$u,%2$u)ã®ãƒ­ãƒƒã‚¯ä¸­" + +#: storage/lmgr/lmgr.c:776 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ãƒ«ã®æ›´æ–°å¾Œãƒãƒ¼ã‚¸ãƒ§ãƒ³(%1$u,%2$u)ã®ãƒ­ãƒƒã‚¯ä¸­" + +#: storage/lmgr/lmgr.c:779 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¿ãƒ—ル(%1$u,%2$u)ã®æŒ¿å…¥ä¸­" + +#: storage/lmgr/lmgr.c:782 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ル(%1$u,%2$u)ã®ä¸€æ„性ã®ç¢ºèªä¸­" + +#: storage/lmgr/lmgr.c:785 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®æ›´æ–°ã•れãŸã‚¿ãƒ—ル(%1$u,%2$u)ã®å†ãƒã‚§ãƒƒã‚¯ä¸­" + +#: storage/lmgr/lmgr.c:788 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "リレーション\"%3$s\"ã®ã‚¿ãƒ—ル(%1$u,%2$u)ã«å¯¾ã™ã‚‹æŽ’除制約ã®ãƒã‚§ãƒƒã‚¯ä¸­" -#: storage/lmgr/lmgr.c:675 +#: storage/lmgr/lmgr.c:1008 #, c-format msgid "relation %u of database %u" msgstr "データベース%2$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³%1$u" -#: storage/lmgr/lmgr.c:681 +#: storage/lmgr/lmgr.c:1014 #, c-format msgid "extension of relation %u of database %u" msgstr "データベース%2$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³%1$uã®æ‹¡å¼µ" -#: storage/lmgr/lmgr.c:687 +#: storage/lmgr/lmgr.c:1020 #, c-format msgid "page %u of relation %u of database %u" msgstr "データベース%3$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³%2$uã®ãƒšãƒ¼ã‚¸%1$u" -#: storage/lmgr/lmgr.c:694 +#: storage/lmgr/lmgr.c:1027 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "データベース%4$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³%3$uã®ã‚¿ãƒ—ル(%2$u,%1$u)" -#: storage/lmgr/lmgr.c:702 +#: storage/lmgr/lmgr.c:1035 #, c-format msgid "transaction %u" msgstr "トランザクション %u" -#: storage/lmgr/lmgr.c:707 +#: storage/lmgr/lmgr.c:1040 #, c-format msgid "virtual transaction %d/%u" msgstr "仮想トランザクション %d/%u" -#: storage/lmgr/lmgr.c:713 +#: storage/lmgr/lmgr.c:1046 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "トランザクション%2$uã®æŠ•æ©Ÿçš„æ›¸ãè¾¼ã¿ãƒˆãƒ¼ã‚¯ãƒ³%1$u" + +#: storage/lmgr/lmgr.c:1052 #, c-format msgid "object %u of class %u of database %u" msgstr "データベース%3$uã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³%2$uã®ã‚ªãƒ–ジェクト%1$u" -#: storage/lmgr/lmgr.c:721 +#: storage/lmgr/lmgr.c:1060 #, c-format msgid "user lock [%u,%u,%u]" msgstr "ユーザロック[%u,%u,%u]" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:1067 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "アドãƒã‚¤ã‚¶ãƒªãƒ»ãƒ­ãƒƒã‚¯[%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:736 +#: storage/lmgr/lmgr.c:1075 #, c-format msgid "unrecognized locktag type %d" -msgstr "ロックタグ種類%dã¯ä¸æ˜Žã§ã™" +msgstr "ロックタグタイプ%dã¯ä¸æ˜Žã§ã™" -#: storage/lmgr/lock.c:721 +#: storage/lmgr/lock.c:740 #, c-format msgid "cannot acquire lock mode %s on database objects while recovery is in progress" -msgstr "リカãƒãƒªãƒ¼ã®å®Ÿè¡Œä¸­ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクトã§ãƒ­ãƒƒã‚¯ãƒ¢ãƒ¼ãƒ‰ %s ã‚’ç²å¾—ã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªã®å®Ÿè¡Œä¸­ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクトã§ãƒ­ãƒƒã‚¯ãƒ¢ãƒ¼ãƒ‰ %s ã‚’ç²å¾—ã§ãã¾ã›ã‚“" -#: storage/lmgr/lock.c:723 +#: storage/lmgr/lock.c:742 #, c-format msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." -msgstr "リカãƒãƒªãƒ¼ã®å®Ÿè¡Œä¸­ã¯ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクト㧠RowExclusiveLock ã‚‚ã—ãã¯ãれ以下ã ã‘ãŒç²å¾—ã§ãã¾ã™" +msgstr "リカãƒãƒªã®å®Ÿè¡Œä¸­ã¯ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクト㧠RowExclusiveLock ã‚‚ã—ãã¯ãれ以下ã ã‘ãŒç²å¾—ã§ãã¾ã™" -#: storage/lmgr/lock.c:864 storage/lmgr/lock.c:892 storage/lmgr/lock.c:2557 -#: storage/lmgr/lock.c:3656 storage/lmgr/lock.c:3721 storage/lmgr/lock.c:4010 +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 +#: storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "max_locks_per_transactionを増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: storage/lmgr/lock.c:2988 storage/lmgr/lock.c:3100 +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 #, c-format msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "åŒä¸€ã‚ªãƒ–ジェクト上ã«ã‚»ãƒƒã‚·ãƒ§ãƒ³ãƒ¬ãƒ™ãƒ«ã¨ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ¬ãƒ™ãƒ«ã®ãƒ­ãƒƒã‚¯ã®ä¸¡æ–¹ã‚’ä¿æŒã—ã¦ã„る時ã«PREPAREã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: storage/lmgr/predicate.c:671 +#: storage/lmgr/predicate.c:682 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "RWConflictPoolã«èª­ã¿æ›¸ãç«¶åˆã‚’記録ã™ã‚‹ãŸã‚ã®è¦ç´ ãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: storage/lmgr/predicate.c:672 storage/lmgr/predicate.c:700 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "トランザクションã®åŒæ™‚実行数を減らã™ã‹ max_connections を増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: storage/lmgr/predicate.c:699 +#: storage/lmgr/predicate.c:710 #, c-format msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "RWConflictPoolã«èª­ã¿æ›¸ãç«¶åˆã®å¯èƒ½æ€§ã‚’記録ã™ã‚‹ãŸã‚ã®è¦ç´ ãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: storage/lmgr/predicate.c:904 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "シリアライズå¯èƒ½ãªç«¶åˆè¿½è·¡ã®ãŸã‚ã®ãƒ¡ãƒ¢ãƒªãŒã‚‚ã†ã™ã一æ¯ã«ãªã‚Šã¾ã™" - -#: storage/lmgr/predicate.c:905 -#, c-format -msgid "There might be an idle transaction or a forgotten prepared transaction causing this." -msgstr "ã“ã®åŽŸå› ã¨ãªã£ã¦ã„ã‚‹ã€ã‚¢ã‚¤ãƒ‰ãƒ«çŠ¶æ…‹ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¾ãŸã¯ä½¿ã‚れãªã„ã¾ã¾ã®æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" - -#: storage/lmgr/predicate.c:1187 storage/lmgr/predicate.c:1259 -#, c-format -msgid "not enough shared memory for elements of data structure \"%s\" (%lu bytes requested)" -msgstr "データ構造体 \"%s\" ã®è¦ç´ ã®ãŸã‚ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™ï¼ˆ %lu ãƒã‚¤ãƒˆå¿…è¦ï¼‰" - -#: storage/lmgr/predicate.c:1547 +#: storage/lmgr/predicate.c:1515 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "é…å»¶å¯èƒ½ã‚¹ãƒŠãƒƒãƒ—ショットã¯å®‰å…¨ã§ã¯ã‚りã¾ã›ã‚“。新ã—ã„スナップショットをå–å¾—ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚" -#: storage/lmgr/predicate.c:1586 +#: storage/lmgr/predicate.c:1604 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "\"default_transaction_isolation\"ãŒ\"serializable\"ã«è¨­å®šã•れã¾ã—ãŸã€‚" -#: storage/lmgr/predicate.c:1587 +#: storage/lmgr/predicate.c:1605 #, c-format msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." msgstr "ã“ã®ãƒ‡ãƒ•ォルトを変更ã™ã‚‹ãŸã‚ã«ã¯\"SET default_transaction_isolation = 'repeatable read'\"を使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" -#: storage/lmgr/predicate.c:1626 +#: storage/lmgr/predicate.c:1645 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "スナップショットをインãƒãƒ¼ãƒˆã™ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯READ ONLY DEFERRABLEã§ã¯ã„ã‘ã¾ã›ã‚“" -#: storage/lmgr/predicate.c:1696 utils/time/snapmgr.c:348 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 +#: utils/time/snapmgr.c:627 #, c-format msgid "could not import the requested snapshot" msgstr "è¦æ±‚ã—ãŸã‚¹ãƒŠãƒƒãƒ—ショットをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: storage/lmgr/predicate.c:1697 utils/time/snapmgr.c:349 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "å…ƒã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³%uã¯ã‚‚ã†å®Ÿè¡Œã—ã¦ã„ã¾ã›ã‚“" +msgid "The source process with PID %d is not running anymore." +msgstr "PID%dã§ã‚ã‚‹ã‚½ãƒ¼ã‚¹ãƒ—ãƒ­ã‚»ã‚¹ã¯æ—¢ã«å®Ÿè¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“。" -#: storage/lmgr/predicate.c:2321 storage/lmgr/predicate.c:2336 -#: storage/lmgr/predicate.c:3732 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 +#: storage/lmgr/predicate.c:3763 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "max_pred_locks_per_transaction を増やã™å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: storage/lmgr/predicate.c:3886 storage/lmgr/predicate.c:3975 -#: storage/lmgr/predicate.c:3983 storage/lmgr/predicate.c:4022 -#: storage/lmgr/predicate.c:4261 storage/lmgr/predicate.c:4599 -#: storage/lmgr/predicate.c:4611 storage/lmgr/predicate.c:4653 -#: storage/lmgr/predicate.c:4691 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 +#: storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 +#: storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 +#: storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 +#: storage/lmgr/predicate.c:4721 #, c-format msgid "could not serialize access due to read/write dependencies among transactions" msgstr "トランザクション間㧠read/write ã®ä¾å­˜æ€§ãŒã‚ã£ãŸãŸã‚ã€ã‚¢ã‚¯ã‚»ã‚¹ã®ç›´åˆ—化ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: storage/lmgr/predicate.c:3888 storage/lmgr/predicate.c:3977 -#: storage/lmgr/predicate.c:3985 storage/lmgr/predicate.c:4024 -#: storage/lmgr/predicate.c:4263 storage/lmgr/predicate.c:4601 -#: storage/lmgr/predicate.c:4613 storage/lmgr/predicate.c:4655 -#: storage/lmgr/predicate.c:4693 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 +#: storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 +#: storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 +#: storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 +#: storage/lmgr/predicate.c:4723 #, c-format msgid "The transaction might succeed if retried." msgstr "リトライãŒè¡Œã‚れãŸå ´åˆã€ã“ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯æˆåŠŸã™ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: storage/lmgr/proc.c:1160 +#: storage/lmgr/proc.c:1318 #, c-format -#| msgid "Process %d waits for %s on %s" msgid "Process %d waits for %s on %s." msgstr "プロセス%dã¯%sã‚’%sã§å¾…機ã—ã¦ã„ã¾ã™ã€‚" -#: storage/lmgr/proc.c:1170 +#: storage/lmgr/proc.c:1329 #, c-format msgid "sending cancel to blocking autovacuum PID %d" -msgstr "ブロックã—ã¦ã„る自動ãƒã‚­ãƒ¥ãƒ¼ãƒ PID %dã¸ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã‚’é€ä»˜ã—ã¦ã„ã¾ã™" +msgstr "ブロックã—ã¦ã„る自動VACUUMプロセスã®PID %dã¸ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã‚’é€ä»˜ã—ã¦ã„ã¾ã™" -#: storage/lmgr/proc.c:1182 utils/adt/misc.c:136 +#: storage/lmgr/proc.c:1347 utils/adt/misc.c:270 #, c-format msgid "could not send signal to process %d: %m" msgstr "プロセス%dã«ã‚·ã‚°ãƒŠãƒ«ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/lmgr/proc.c:1217 +#: storage/lmgr/proc.c:1449 #, c-format msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" msgstr "プロセス%1$dã¯ã€%4$ld.%5$03d ms後ã«ã‚­ãƒ¥ãƒ¼ã®é †ç•ªã‚’å†èª¿æ•´ã™ã‚‹ã“ã¨ã§ã€%3$s上ã®%2$sã«å¯¾ã™ã‚‹ãƒ‡ãƒƒãƒ‰ãƒ­ãƒƒã‚¯ã‚’防ãŽã¾ã—ãŸã€‚" -#: storage/lmgr/proc.c:1229 +#: storage/lmgr/proc.c:1464 #, c-format msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "プロセス%1$dã¯ã€%3$s上ã®%2$sã«å¯¾ã—%4$ld.%5$03d ms待機ã™ã‚‹ãƒ‡ãƒƒãƒ‰ãƒ­ãƒƒã‚¯ã‚’検知ã—ã¾ã—ãŸ" -#: storage/lmgr/proc.c:1235 +#: storage/lmgr/proc.c:1473 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "プロセス%dã¯%sã‚’%sã§å¾…機ã—ã¦ã„ã¾ã™ã€‚%ld.%03dミリ秒後" -#: storage/lmgr/proc.c:1239 +#: storage/lmgr/proc.c:1480 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "プロセス%1$dã¯%4$ld.%5$03d ms後ã«%3$s上ã®%2$sã‚’ç²å¾—ã—ã¾ã—ãŸ" -#: storage/lmgr/proc.c:1255 +#: storage/lmgr/proc.c:1496 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "プロセス%1$dã¯%4$ld.%5$03d ms後ã«%3$s上ã§%2$sã‚’ç²å¾—ã™ã‚‹ã“ã¨ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: storage/page/bufpage.c:143 +#: storage/page/bufpage.c:151 #, c-format msgid "page verification failed, calculated checksum %u but expected %u" msgstr "ページ検証ãŒå¤±æ•—ã—ã¾ã—ãŸã€‚計算ã•れãŸãƒã‚§ãƒƒã‚¯ã‚µãƒ ã¯%uã§ã™ãŒæƒ³å®šã¯%uã§ã™" -#: storage/page/bufpage.c:199 storage/page/bufpage.c:460 -#: storage/page/bufpage.c:693 storage/page/bufpage.c:823 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 +#: storage/page/bufpage.c:744 storage/page/bufpage.c:877 +#: storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "ページãƒã‚¤ãƒ³ã‚¿ãŒç ´æã—ã¦ã„ã¾ã™: lower = %u, upper = %u, special = %u\"" -#: storage/page/bufpage.c:503 +#: storage/page/bufpage.c:529 #, c-format msgid "corrupted item pointer: %u" msgstr "アイテムãƒã‚¤ãƒ³ã‚¿ãŒç ´æã—ã¦ã„ã¾ã™: %u" -#: storage/page/bufpage.c:514 storage/page/bufpage.c:875 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "アイテム長ãŒç ´æã—ã¦ã„ã¾ã™: åˆè¨ˆ %u 利用å¯èƒ½ç©ºé–“ %u" -#: storage/page/bufpage.c:712 storage/page/bufpage.c:848 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 +#: storage/page/bufpage.c:1099 #, c-format msgid "corrupted item pointer: offset = %u, size = %u" msgstr "アイテムãƒã‚¤ãƒ³ã‚¿ãŒç ´æã—ã¦ã„ã¾ã™: オフセット = %u サイズ = %u" -#: storage/smgr/md.c:427 storage/smgr/md.c:898 +#: storage/page/bufpage.c:901 +#, c-format +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "ç ´æã—ãŸã‚¢ã‚¤ãƒ†ãƒ ãƒã‚¤ãƒ³ã‚¿: オフセット=%u〠長ã•=%u" + +#: storage/smgr/md.c:448 storage/smgr/md.c:974 #, c-format msgid "could not truncate file \"%s\": %m" msgstr "ファイル \"%s\" ã®åˆ‡ã‚Šè©°ã‚処ç†ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/smgr/md.c:494 +#: storage/smgr/md.c:515 #, c-format msgid "cannot extend file \"%s\" beyond %u blocks" msgstr "ファイル \"%s\" ã‚’ %u ãƒ–ãƒ­ãƒƒã‚¯ä»¥ä¸Šã«æ‹¡å¼µã§ãã¾ã›ã‚“" -#: storage/smgr/md.c:516 storage/smgr/md.c:677 storage/smgr/md.c:752 +#: storage/smgr/md.c:537 storage/smgr/md.c:754 storage/smgr/md.c:830 #, c-format msgid "could not seek to block %u in file \"%s\": %m" msgstr "ファイル \"%2$s\" ã§ %1$u ブロック目ã«ã‚·ãƒ¼ã‚¯ã§ãã¾ã›ã‚“ã§ã—ãŸ: %3$m" -#: storage/smgr/md.c:524 +#: storage/smgr/md.c:545 #, c-format msgid "could not extend file \"%s\": %m" msgstr "ファイル \"%s\" ã‚’æ‹¡å¼µã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/smgr/md.c:526 storage/smgr/md.c:533 storage/smgr/md.c:779 +#: storage/smgr/md.c:547 storage/smgr/md.c:554 storage/smgr/md.c:857 #, c-format msgid "Check free disk space." msgstr "ディスクã®ç©ºã容é‡ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ãã ã•ã„。" -#: storage/smgr/md.c:530 +#: storage/smgr/md.c:551 #, c-format msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" -msgstr "ファイル \"%1$s\" ã‚’æ‹¡å¼µã§ãã¾ã›ã‚“ã§ã—ãŸï¼š%4$u ブロック㧠%3$d ãƒã‚¤ãƒˆä¸­ %2$d ãƒã‚¤ãƒˆåˆ†ã®ã¿ã‚’書ã出ã—ã¾ã—ãŸã€‚" +msgstr "ファイル \"%1$s\" ã‚’æ‹¡å¼µã§ãã¾ã›ã‚“ã§ã—ãŸ: %4$u ブロック㧠%3$d ãƒã‚¤ãƒˆä¸­ %2$d ãƒã‚¤ãƒˆåˆ†ã®ã¿ã‚’書ã出ã—ã¾ã—ãŸã€‚" -#: storage/smgr/md.c:695 +#: storage/smgr/md.c:772 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "ファイル \"%2$s\" ã§ %1$u ブロックを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %3$m" -#: storage/smgr/md.c:711 +#: storage/smgr/md.c:788 #, c-format msgid "could not read block %u in file \"%s\": read only %d of %d bytes" -msgstr "ファイル \"%2$s\" ã®ãƒ–ロック %1$u を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸï¼š%4$d ãƒã‚¤ãƒˆä¸­ %3$d ãƒã‚¤ãƒˆåˆ†ã®ã¿èª­ã¿å–りã¾ã—ãŸ" +msgstr "ファイル \"%2$s\" ã®ãƒ–ロック %1$u を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %4$d ãƒã‚¤ãƒˆä¸­ %3$d ãƒã‚¤ãƒˆåˆ†ã®ã¿èª­ã¿å–りã¾ã—ãŸ" -#: storage/smgr/md.c:770 +#: storage/smgr/md.c:848 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "ファイル \"%2$s\" ã§ %1$u ãƒ–ãƒ­ãƒƒã‚¯ãŒæ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %3$m" -#: storage/smgr/md.c:775 +#: storage/smgr/md.c:853 #, c-format msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" -msgstr "ファイル \"%2$s\" ã®ãƒ–ロック %1$u を書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸï¼š%4$d ãƒã‚¤ãƒˆä¸­ %3$d ãƒã‚¤ãƒˆåˆ†ã®ã¿æ›¸ãè¾¼ã¿ã¾ã—ãŸ" +msgstr "ファイル \"%2$s\" ã®ãƒ–ロック %1$u を書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %4$d ãƒã‚¤ãƒˆä¸­ %3$d ãƒã‚¤ãƒˆåˆ†ã®ã¿æ›¸ãè¾¼ã¿ã¾ã—ãŸ" -#: storage/smgr/md.c:874 +#: storage/smgr/md.c:945 #, c-format msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" -msgstr "ファイル \"%s\" ã‚’ %u ブロックã«åˆ‡ã‚Šè©°ã‚られã¾ã›ã‚“ã§ã—ãŸï¼šç¾åœ¨ã¯ %u ブロックã®ã¿ã¨ãªã‚Šã¾ã—ãŸ" +msgstr "ファイル \"%s\" ã‚’ %u ブロックã«åˆ‡ã‚Šè©°ã‚られã¾ã›ã‚“ã§ã—ãŸ: ç¾åœ¨ã¯ %u ブロックã®ã¿ã¨ãªã‚Šã¾ã—ãŸ" -#: storage/smgr/md.c:923 +#: storage/smgr/md.c:1000 #, c-format msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "ファイル \"%s\" ã‚’ %u ブロックã«åˆ‡ã‚Šè©°ã‚られã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/smgr/md.c:1203 +#: storage/smgr/md.c:1295 #, c-format msgid "could not fsync file \"%s\" but retrying: %m" msgstr "ファイル \"%s\" ã‚’ fsync ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: storage/smgr/md.c:1366 +#: storage/smgr/md.c:1458 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚­ãƒ¥ãƒ¼ãŒæº€æ¯ã«ã¤ã fsync リクエストã®ãƒ•ォワードãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: storage/smgr/md.c:1763 +#: storage/smgr/md.c:1964 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "ファイル\"%s\"(対象ブロック%u)をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: ç›´å‰ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã¯%uブロックã ã‘ã§ã—ãŸ" + +#: storage/smgr/md.c:1978 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "ファイル \"%s\"(対象ブロック %u)をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:502 tcop/fastpath.c:632 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" -msgstr "関数呼ã³å‡ºã—メッセージ内ã®å¼•数サイズ%dãŒç„¡åйã§ã™" - -#: tcop/fastpath.c:304 tcop/postgres.c:363 tcop/postgres.c:399 -#, c-format -msgid "unexpected EOF on client connection" -msgstr "ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæŽ¥ç¶šã«æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã—ãŸ" - -#: tcop/fastpath.c:318 tcop/postgres.c:952 tcop/postgres.c:1262 -#: tcop/postgres.c:1520 tcop/postgres.c:1923 tcop/postgres.c:2290 -#: tcop/postgres.c:2365 -#, c-format -msgid "current transaction is aborted, commands ignored until end of transaction block" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚¢ãƒœãƒ¼ãƒˆã—ã¾ã—ãŸã€‚トランザクションブロックãŒçµ‚ã‚ã‚‹ã¾ã§ã‚³ãƒžãƒ³ãƒ‰ã¯ç„¡è¦–ã•れã¾ã™" +msgstr "関数呼ã³å‡ºã—メッセージ内ã®å¼•数サイズ%dãŒä¸æ­£ã§ã™" -#: tcop/fastpath.c:346 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "è¿‘é“関数呼ã³å‡ºã—: \"%s\"(OID %u))" -#: tcop/fastpath.c:428 tcop/postgres.c:1122 tcop/postgres.c:1387 -#: tcop/postgres.c:1764 tcop/postgres.c:1981 +#: tcop/fastpath.c:389 tcop/postgres.c:1218 tcop/postgres.c:1482 +#: tcop/postgres.c:1864 tcop/postgres.c:2085 #, c-format msgid "duration: %s ms" msgstr "期間: %s ミリ秒" -#: tcop/fastpath.c:432 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "期間: %s ミリ秒 è¿‘é“関数呼ã³å‡ºã—: \"%s\" (OID %u)" -#: tcop/fastpath.c:470 tcop/fastpath.c:597 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "関数呼ã³å‡ºã—メッセージã«ã¯%d引数ã‚りã¾ã—ãŸãŒã€é–¢æ•°ã«ã¯%då¿…è¦ã§ã™" -#: tcop/fastpath.c:478 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "関数呼ã³å‡ºã—メッセージã«ã¯%dã®å¼•数書å¼ãŒã‚りã¾ã—ãŸãŒã€å¼•æ•°ã¯%dã§ã—ãŸ" -#: tcop/fastpath.c:565 tcop/fastpath.c:648 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "関数引数%dã®ãƒã‚¤ãƒŠãƒªãƒ‡ãƒ¼ã‚¿æ›¸å¼ãŒä¸æ­£ã§ã™" -#: tcop/postgres.c:427 tcop/postgres.c:439 tcop/postgres.c:450 -#: tcop/postgres.c:462 tcop/postgres.c:4228 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆæŽ¥ç¶šã«æƒ³å®šå¤–ã®EOFãŒã‚りã¾ã—ãŸ" + +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4408 #, c-format msgid "invalid frontend message type %d" -msgstr "フロントエンドメッセージ種類%dãŒç„¡åйã§ã™" +msgstr "フロントエンドメッセージタイプ%dãŒä¸æ­£ã§ã™" -#: tcop/postgres.c:893 +#: tcop/postgres.c:973 #, c-format msgid "statement: %s" msgstr "æ–‡: %s" -#: tcop/postgres.c:1127 +#: tcop/postgres.c:1223 #, c-format msgid "duration: %s ms statement: %s" msgstr "期間: %s ミリ秒 æ–‡: %s" -#: tcop/postgres.c:1177 +#: tcop/postgres.c:1273 #, c-format msgid "parse %s: %s" -msgstr "è§£æž %s: %s" +msgstr "パース %s: %s" -#: tcop/postgres.c:1235 +#: tcop/postgres.c:1330 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "準備ã•ã‚ŒãŸæ–‡ã«è¤‡æ•°ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’挿入ã§ãã¾ã›ã‚“" -#: tcop/postgres.c:1392 +#: tcop/postgres.c:1487 #, c-format msgid "duration: %s ms parse %s: %s" -msgstr "期間: %s ミリ秒 è§£æž%s : %s" +msgstr "期間: %s ミリ秒 パース%s : %s" -#: tcop/postgres.c:1437 +#: tcop/postgres.c:1532 #, c-format msgid "bind %s to %s" msgstr "ãƒã‚¤ãƒ³ãƒ‰%s: %s" -#: tcop/postgres.c:1456 tcop/postgres.c:2271 +#: tcop/postgres.c:1551 tcop/postgres.c:2377 #, c-format msgid "unnamed prepared statement does not exist" msgstr "ç„¡åã®æº–å‚™ã•ã‚ŒãŸæ–‡ãŒå­˜åœ¨ã—ã¾ã›ã‚“" -#: tcop/postgres.c:1498 +#: tcop/postgres.c:1594 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "ãƒã‚¤ãƒ³ãƒ‰ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯%dパラメータ書å¼ã‚りã¾ã—ãŸãŒãƒ‘ラメータã¯%dã§ã—ãŸ" -#: tcop/postgres.c:1504 +#: tcop/postgres.c:1600 #, c-format msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "ãƒã‚¤ãƒ³ãƒ‰ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯%dパラメータをæä¾›ã—ã¾ã—ãŸãŒã€æº–å‚™ã•ã‚ŒãŸæ–‡\"%s\"ã§ã¯%då¿…è¦ã§ã—ãŸ" -#: tcop/postgres.c:1671 +#: tcop/postgres.c:1771 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "ãƒã‚¤ãƒ³ãƒ‰ãƒ‘ラメータ%dã«ãŠã„ã¦ãƒã‚¤ãƒŠãƒªãƒ‡ãƒ¼ã‚¿æ›¸å¼ãŒä¸æ­£ã§ã™" -#: tcop/postgres.c:1769 +#: tcop/postgres.c:1869 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "期間: %s ミリ秒 ãƒã‚¤ãƒ³ãƒ‰ %s%s%s: %s" -#: tcop/postgres.c:1817 tcop/postgres.c:2351 +#: tcop/postgres.c:1917 tcop/postgres.c:2461 #, c-format msgid "portal \"%s\" does not exist" msgstr "ãƒãƒ¼ã‚¿ãƒ«\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: tcop/postgres.c:1902 +#: tcop/postgres.c:2002 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1904 tcop/postgres.c:1989 +#: tcop/postgres.c:2004 tcop/postgres.c:2093 msgid "execute fetch from" msgstr "å–り出ã—実行" -#: tcop/postgres.c:1905 tcop/postgres.c:1990 +#: tcop/postgres.c:2005 tcop/postgres.c:2094 msgid "execute" msgstr "実行" -#: tcop/postgres.c:1986 +#: tcop/postgres.c:2090 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "期間: %s ミリ秒 %s %s%s%s: %s" -#: tcop/postgres.c:2112 +#: tcop/postgres.c:2216 #, c-format msgid "prepare: %s" msgstr "準備: %s" -#: tcop/postgres.c:2175 +#: tcop/postgres.c:2282 #, c-format msgid "parameters: %s" msgstr "パラメータ: %s" -#: tcop/postgres.c:2194 +#: tcop/postgres.c:2301 #, c-format msgid "abort reason: recovery conflict" -msgstr "異常終了ã®ç†ç”±ï¼šãƒªã‚«ãƒãƒªãŒè¡çªã—ãŸãŸã‚" +msgstr "異常終了ã®ç†ç”±: リカãƒãƒªãŒè¡çªã—ãŸãŸã‚" -#: tcop/postgres.c:2210 +#: tcop/postgres.c:2317 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "ユーザãŒå…±æœ‰ãƒãƒƒãƒ•ァ・ピンを長ãä¿æŒã—éŽãŽã¦ã„ã¾ã—ãŸ" -#: tcop/postgres.c:2213 +#: tcop/postgres.c:2320 #, c-format msgid "User was holding a relation lock for too long." msgstr "ユーザリレーションã®ãƒ­ãƒƒã‚¯ã‚’é•·ãä¿æŒã—éŽãŽã¦ã„ã¾ã—ãŸ" -#: tcop/postgres.c:2216 +#: tcop/postgres.c:2323 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "削除ã•れるã¹ãテーブルスペースをユーザãŒä½¿ã£ã¦ã„ã¾ã—ãŸï¼ˆã‚‚ã—ãã¯ãã®å¯èƒ½æ€§ãŒã‚りã¾ã—ãŸï¼‰ã€‚" -#: tcop/postgres.c:2219 +#: tcop/postgres.c:2326 #, c-format msgid "User query might have needed to see row versions that must be removed." -msgstr "削除ã•れるã¹ããƒãƒ¼ã‚¸ãƒ§ãƒ³ã®è¡Œã‚’ユーザクエリãŒå‚ç…§ã—ãªã‘れã°ãªã‚‰ãªã‹ã£ãŸå¯èƒ½æ€§ãŒã‚りã¾ã—ãŸã€‚" +msgstr "削除ã•れるã¹ããƒãƒ¼ã‚¸ãƒ§ãƒ³ã®è¡Œã‚’ユーザå•ã„åˆã‚ã›ãŒå‚ç…§ã—ãªã‘れã°ãªã‚‰ãªã‹ã£ãŸå¯èƒ½æ€§ãŒã‚りã¾ã—ãŸã€‚" -#: tcop/postgres.c:2225 +#: tcop/postgres.c:2332 #, c-format msgid "User was connected to a database that must be dropped." msgstr "削除ã•れるã¹ãデータベースã«ãƒ¦ãƒ¼ã‚¶ãŒæŽ¥ç¶šã—ã¦ã„ã¾ã—ãŸã€‚" -#: tcop/postgres.c:2547 +#: tcop/postgres.c:2657 #, c-format msgid "terminating connection because of crash of another server process" -msgstr "ä»–ã®ã‚µãƒ¼ãƒãƒ—ロセスãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸãŸã‚接続を終了ã—ã¦ã„ã¾ã™" +msgstr "ä»–ã®ã‚µãƒ¼ãƒãƒ—ロセスãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸãŸã‚接続を終了ã—ã¾ã™" -#: tcop/postgres.c:2548 +#: tcop/postgres.c:2658 #, c-format msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." msgstr "" @@ -14701,219 +19827,246 @@ msgstr "" "postmasterã¯ã“ã®ã‚µãƒ¼ãƒãƒ—ロセスã«å¯¾ã—ã€ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ロールãƒãƒƒã‚¯\n" "ã—終了ã™ã‚‹ã‚ˆã†æŒ‡ç¤ºã—ã¾ã—ãŸã€‚" -#: tcop/postgres.c:2552 tcop/postgres.c:2936 +#: tcop/postgres.c:2662 tcop/postgres.c:2986 #, c-format msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "ã“ã®å¾Œã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«å†æŽ¥ç¶šã—ã€ã‚³ãƒžãƒ³ãƒ‰ã‚’繰り返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: tcop/postgres.c:2665 +#: tcop/postgres.c:2744 #, c-format msgid "floating-point exception" msgstr "æµ®å‹•å°æ•°ç‚¹ä¾‹å¤–" -#: tcop/postgres.c:2666 +#: tcop/postgres.c:2745 #, c-format msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." -msgstr "" -"ç„¡åŠ¹ãªæµ®å‹•å°æ•°ç‚¹æ“作ãŒé€šçŸ¥ã•れã¾ã—ãŸã€‚ãŠãらãã“れã¯ã€ç¯„囲外ã®çµæžœã‚„0割りãª\n" -"ã©ã®ç„¡åŠ¹ãªæ“作をæ„味ã—ã¦ã„ã¾ã™ã€‚" +msgstr "䏿­£ãªæµ®å‹•å°æ•°ç‚¹æ¼”ç®—ãŒã‚·ã‚°ãƒŠãƒ«ã•れã¾ã—ãŸã€‚ãŠãらãã“れã¯ã€ç¯„囲外ã®çµæžœã‚‚ã—ãã¯0除算ã®ã‚ˆã†ãªä¸æ­£ãªæ¼”ç®—ã«ã‚ˆã‚‹ã‚‚ã®ã§ã™ã€‚" + +#: tcop/postgres.c:2916 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "タイムアウトã«ã‚ˆã‚Šèªè¨¼å‡¦ç†ã‚’キャンセルã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2840 +#: tcop/postgres.c:2920 #, c-format msgid "terminating autovacuum process due to administrator command" -msgstr "管ç†è€…コマンドã«ã‚ˆã‚Šè‡ªå‹•ãƒã‚­ãƒ¥ãƒ¼ãƒ ã‚’終了ã—ã¦ã„ã¾ã™" +msgstr "管ç†è€…コマンドã«ã‚ˆã‚Šè‡ªå‹•VACUUM処ç†ã‚’終了ã—ã¦ã„ã¾ã™" + +#: tcop/postgres.c:2924 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "管ç†è€…コマンドã«ã‚ˆã‚Šã€è«–ç†ãƒ¬ãƒ—リケーションワーカを終了ã—ã¾ã™" -#: tcop/postgres.c:2846 tcop/postgres.c:2856 tcop/postgres.c:2934 +#: tcop/postgres.c:2928 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "è«–ç†ãƒ¬ãƒ—リケーションランãƒãƒ£ã‚’åœæ­¢ã—ã¾ã™" + +#: tcop/postgres.c:2941 tcop/postgres.c:2951 tcop/postgres.c:2984 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "リカãƒãƒªã§ç«¶åˆãŒç™ºç”Ÿã—ãŸãŸã‚ã€æŽ¥ç¶šã‚’çµ‚äº†ã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2862 +#: tcop/postgres.c:2957 #, c-format msgid "terminating connection due to administrator command" msgstr "管ç†è€…コマンドã«ã‚ˆã‚ŠæŽ¥ç¶šã‚’çµ‚äº†ã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2874 +#: tcop/postgres.c:2967 #, c-format msgid "connection to client lost" msgstr "クライアントã¸ã®æŽ¥ç¶šãŒåˆ‡ã‚Œã¾ã—ãŸã€‚" -#: tcop/postgres.c:2889 -#, c-format -msgid "canceling authentication due to timeout" -msgstr "タイムアウトã«ã‚ˆã‚Šèªè¨¼å‡¦ç†ã‚’キャンセルã—ã¦ã„ã¾ã™" - -#: tcop/postgres.c:2904 +#: tcop/postgres.c:3033 #, c-format -#| msgid "canceling statement due to statement timeout" msgid "canceling statement due to lock timeout" -msgstr "ロックã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ã‚ˆã‚Šã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’キャンセルã—ã¦ã„ã¾ã™" +msgstr "ロックã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã®ãŸã‚ステートメントをキャンセルã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2913 +#: tcop/postgres.c:3040 #, c-format msgid "canceling statement due to statement timeout" -msgstr "ステートメントã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã«ã‚ˆã‚Šã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’キャンセルã—ã¦ã„ã¾ã™" +msgstr "ステートメントã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã®ãŸã‚ステートメントをキャンセルã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2922 +#: tcop/postgres.c:3047 #, c-format msgid "canceling autovacuum task" -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ä½œæ¥­ã‚’キャンセルã—ã¦ã„ã¾ã™" +msgstr "自動VACUUM処ç†ã‚’キャンセルã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:2957 +#: tcop/postgres.c:3070 #, c-format msgid "canceling statement due to user request" msgstr "ユーザã‹ã‚‰ã®è¦æ±‚ã«ã‚ˆã‚Šæ–‡ã‚’キャンセルã—ã¦ã„ã¾ã™" -#: tcop/postgres.c:3085 tcop/postgres.c:3107 +#: tcop/postgres.c:3080 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "トランザクション中アイドルタイムアウトã®ãŸã‚接続を終了ã—ã¾ã™" + +#: tcop/postgres.c:3194 #, c-format msgid "stack depth limit exceeded" msgstr "スタック長制é™ã‚’è¶Šãˆã¾ã—ãŸ" -#: tcop/postgres.c:3086 tcop/postgres.c:3108 +#: tcop/postgres.c:3195 #, c-format msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." msgstr "ãŠä½¿ã„ã®ãƒ—ラットフォームã«ãŠã‘るスタック長ã®åˆ¶é™ã«é©åˆã™ã‚‹ã“ã¨ã‚’確èªå¾Œã€è¨­å®šãƒ‘ラメータ \"max_stack_depth\"(ç¾åœ¨ %dkB)を増やã—ã¦ãã ã•ã„。" -#: tcop/postgres.c:3124 +#: tcop/postgres.c:3258 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." -msgstr "\"max_stack_depth\" 㯠%ldkB ã‚’è¶Šãˆãªã„よã†ã«ã—ã¦ãã ã•ã„" +msgstr "\"max_stack_depth\" 㯠%ldkB ã‚’è¶Šãˆã¦ã¯ãªã‚Šã¾ã›ã‚“。" -#: tcop/postgres.c:3126 +#: tcop/postgres.c:3260 #, c-format msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." -msgstr "プラットフォームã®ã‚¹ã‚¿ãƒƒã‚¯é•·ã‚’\"ulimit -s\"(システムã«åˆã‚ã›ã¦ãã ã•ã„)を使用ã—ã¦å¢—加ã—ã¦ãã ã•ã„" +msgstr "プラットフォームã®ã‚¹ã‚¿ãƒƒã‚¯é•·åˆ¶é™ã‚’\"ulimit -s\"ã¾ãŸã¯åŒç­‰ã®æ©Ÿèƒ½ã‚’使用ã—ã¦å¢—加ã—ã¦ãã ã•ã„" -#: tcop/postgres.c:3490 +#: tcop/postgres.c:3620 #, c-format msgid "invalid command-line argument for server process: %s" -msgstr "サーãƒãƒ—ロセス用ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å¼•æ•°ãŒç„¡åйã§ã™: %s" +msgstr "サーãƒãƒ—ロセスã«å¯¾ã™ã‚‹ä¸æ­£ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å¼•æ•°: %s" -#: tcop/postgres.c:3491 tcop/postgres.c:3497 +#: tcop/postgres.c:3621 tcop/postgres.c:3627 #, c-format msgid "Try \"%s --help\" for more information." msgstr "詳細ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„。" -#: tcop/postgres.c:3495 +#: tcop/postgres.c:3625 #, c-format msgid "%s: invalid command-line argument: %s" -msgstr "%s: コマンドライン引数ãŒç„¡åйã§ã™: %s" +msgstr "%s: 䏿­£ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å¼•æ•°: %s" -#: tcop/postgres.c:3582 +#: tcop/postgres.c:3687 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: データベースåもユーザåも指定ã•れã¦ã„ã¾ã›ã‚“" -#: tcop/postgres.c:4136 +#: tcop/postgres.c:4316 #, c-format msgid "invalid CLOSE message subtype %d" -msgstr "CLOSEメッセージã®ã‚µãƒ–タイプ%dãŒç„¡åйã§ã™" +msgstr "䏿­£ãªCLOSEメッセージã®ã‚µãƒ–タイプ%d" -#: tcop/postgres.c:4171 +#: tcop/postgres.c:4351 #, c-format msgid "invalid DESCRIBE message subtype %d" -msgstr "DESCRIBEメッセージã®ã‚µãƒ–タイプ%dãŒç„¡åйã§ã™" +msgstr "䏿­£ãªDESCRIBEメッセージã®ã‚µãƒ–タイプ%d" -#: tcop/postgres.c:4249 +#: tcop/postgres.c:4429 #, c-format -#| msgid "cast function must not be an aggregate function" msgid "fastpath function calls not supported in a replication connection" -msgstr "レプリケーション接続ã§ã¯ã€è¿‘é“関数呼ã³å‡ºã—ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "レプリケーション接続ã§ã¯é«˜é€Ÿé–¢æ•°å‘¼ã³å‡ºã—ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: tcop/postgres.c:4253 +#: tcop/postgres.c:4433 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "レプリケーション接続ã§ã¯æ‹¡å¼µå•ã„åˆã‚ã›ãƒ—ロトコルã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: tcop/postgres.c:4423 +#: tcop/postgres.c:4610 #, c-format msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" -msgstr "接続を切断: セッション期間: %d:%02d:%02d.%03d ユーザ=%s データベース=%s ホスト=%s%s%s" +msgstr "接続を切断: セッション時間: %d:%02d:%02d.%03d ユーザ=%s データベース=%s ホスト=%s%s%s" -#: tcop/pquery.c:662 +#: tcop/pquery.c:645 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "ãƒã‚¤ãƒ³ãƒ‰ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã¯%dã®çµæžœæ›¸å¼ãŒã‚りã¾ã—ãŸãŒã€å•ã„åˆã‚ã›ã¯%d列ã§ã—ãŸ" -#: tcop/pquery.c:972 +#: tcop/pquery.c:952 #, c-format msgid "cursor can only scan forward" msgstr "カーゾルã¯å‰æ–¹ã¸ã®ã‚¹ã‚­ãƒ£ãƒ³ã—ã‹ã§ãã¾ã›ã‚“" -#: tcop/pquery.c:973 +#: tcop/pquery.c:953 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "後方スキャンを有効ã«ã™ã‚‹ãŸã‚ã«ã¯SCROLLオプションを付ã‘ã¦å®£è¨€ã—ã¦ãã ã•ã„。" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:269 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "リードオンリーã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã§ã¯ %s を実行ã§ãã¾ã›ã‚“" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:288 +#: tcop/utility.c:263 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "並列処ç†ä¸­ã¯%sを実行ã§ãã¾ã›ã‚“" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" -msgstr "リカãƒãƒªãƒ¼ä¸­ã¯ %s を実行ã§ãã¾ã›ã‚“" +msgstr "リカãƒãƒªä¸­ã¯ %s を実行ã§ãã¾ã›ã‚“" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:306 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ¼åˆ¶é™æ“作ã®ä¸­ã§ã¯ %s を実行ã§ãã¾ã›ã‚“" -#: tcop/utility.c:764 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" -msgstr "CHECKPOINTを実行ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "CHECKPOINTを実行ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: tcop/utility.c:1341 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "パーティションテーブル\"%s\"ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’作æˆã§ãã¾ã›ã‚“" + +#: tcop/utility.c:1343 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "テーブル \"%s\" ã¯å¤–部テーブルをå­ãƒ†ãƒ¼ãƒ–ルã¨ã—ã¦å«ã‚“ã§ã„ã¾ã™" -#: tsearch/dict_ispell.c:51 tsearch/dict_thesaurus.c:614 +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" msgstr "é‡è¤‡ã™ã‚‹DictFileパラメータ" -#: tsearch/dict_ispell.c:62 +#: tsearch/dict_ispell.c:63 #, c-format msgid "multiple AffFile parameters" msgstr "é‡è¤‡ã™ã‚‹AffFileパラメータ" -#: tsearch/dict_ispell.c:81 +#: tsearch/dict_ispell.c:82 #, c-format msgid "unrecognized Ispell parameter: \"%s\"" msgstr "未知ã®Ispellパラメータ: \"%s\"" -#: tsearch/dict_ispell.c:95 +#: tsearch/dict_ispell.c:96 #, c-format msgid "missing AffFile parameter" msgstr "AffFileパラメータãŒã‚りã¾ã›ã‚“" -#: tsearch/dict_ispell.c:101 tsearch/dict_thesaurus.c:638 +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:648 #, c-format msgid "missing DictFile parameter" msgstr "DictFileパラメータãŒã‚りã¾ã›ã‚“" -#: tsearch/dict_simple.c:57 +#: tsearch/dict_simple.c:58 #, c-format msgid "multiple Accept parameters" msgstr "é‡è¤‡ã™ã‚‹Acceptパラメータ" -#: tsearch/dict_simple.c:65 +#: tsearch/dict_simple.c:66 #, c-format msgid "unrecognized simple dictionary parameter: \"%s\"" msgstr "未知ã®å˜ç´”辞書パラメータ: \"%s\"" -#: tsearch/dict_synonym.c:117 +#: tsearch/dict_synonym.c:118 #, c-format msgid "unrecognized synonym parameter: \"%s\"" msgstr "未知ã®é¡žç¾©èªžãƒ‘ラメータ: \"%s\"" -#: tsearch/dict_synonym.c:124 +#: tsearch/dict_synonym.c:125 #, c-format msgid "missing Synonyms parameter" msgstr "類義語パラメータãŒã‚りã¾ã›ã‚“" -#: tsearch/dict_synonym.c:131 +#: tsearch/dict_synonym.c:132 #, c-format msgid "could not open synonym file \"%s\": %m" msgstr "類義語ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" @@ -14938,104 +20091,140 @@ msgstr "想定外ã®è¡Œæœ«ã‚‚ã—ãã¯å˜èªžã®çµ‚端ã§ã™" msgid "unexpected end of line" msgstr "想定外ã®è¡Œæœ«ã§ã™" -#: tsearch/dict_thesaurus.c:411 +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "シソーラスè¦ç´ ä¸­ã®èªžå½™ç´ ãŒå¤šã™ãŽã¾ã™" + +#: tsearch/dict_thesaurus.c:421 #, c-format msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" msgstr "シソーラスサンプルå˜èªž\"%s\"ã¯å‰¯è¾žæ›¸ã§èªè­˜ã•れã¾ã›ã‚“(è¦å‰‡%d)" -#: tsearch/dict_thesaurus.c:417 +#: tsearch/dict_thesaurus.c:427 #, c-format msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" msgstr "シソーラスサンプルå˜èªž\"%s\"ã¯ã‚¹ãƒˆãƒƒãƒ—ワードã§ã™(è¦å‰‡%d)" -#: tsearch/dict_thesaurus.c:420 +#: tsearch/dict_thesaurus.c:430 #, c-format msgid "Use \"?\" to represent a stop word within a sample phrase." msgstr "サンプルフレーズ内ã®ã‚¹ãƒˆãƒƒãƒ—ワードを表ã™ã«ã¯\"?\"を使用ã—ã¦ãã ã•ã„" -#: tsearch/dict_thesaurus.c:566 +#: tsearch/dict_thesaurus.c:576 #, c-format msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" msgstr "シソーラス置æ›å˜èªž\"%s\"ã¯ã‚¹ãƒˆãƒƒãƒ—ワードã§ã™(è¦å‰‡%d)" -#: tsearch/dict_thesaurus.c:573 +#: tsearch/dict_thesaurus.c:583 #, c-format msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" msgstr "シソーラス置æ›å˜èªž\"%s\"ã¯å‰¯è¾žæ›¸ã§èªè­˜ã•れã¾ã›ã‚“(è¦å‰‡%d)" -#: tsearch/dict_thesaurus.c:585 +#: tsearch/dict_thesaurus.c:595 #, c-format msgid "thesaurus substitute phrase is empty (rule %d)" msgstr "シソーラス置æ›ãƒ•レーズã¯ç©ºã§ã™(è¦å‰‡%d)" -#: tsearch/dict_thesaurus.c:623 +#: tsearch/dict_thesaurus.c:633 #, c-format msgid "multiple Dictionary parameters" msgstr "é‡è¤‡ã™ã‚‹è¾žæ›¸ãƒ‘ラメータ" -#: tsearch/dict_thesaurus.c:630 +#: tsearch/dict_thesaurus.c:640 #, c-format msgid "unrecognized Thesaurus parameter: \"%s\"" msgstr "未知ã®ã‚·ã‚½ãƒ¼ãƒ©ã‚¹ãƒ‘ラメータ \"%s\"" -#: tsearch/dict_thesaurus.c:642 +#: tsearch/dict_thesaurus.c:652 #, c-format msgid "missing Dictionary parameter" msgstr "DictionaryパラメータãŒã‚りã¾ã›ã‚“" -#: tsearch/spell.c:276 +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1034 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "䏿­£ãªæŽ¥è¾žãƒ•ラグ\"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1038 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "接辞フラグ\"%s\"ã¯ç¯„囲外ã§ã™" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "接辞フラグ中ã®ä¸æ­£ãªæ–‡å­—\"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "\"long\"フラグ値を伴ã£ãŸä¸æ­£ãªæŽ¥è¾žãƒ•ラグ\"%s\"" + +#: tsearch/spell.c:522 #, c-format msgid "could not open dictionary file \"%s\": %m" msgstr "辞書ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: tsearch/spell.c:439 utils/adt/regexp.c:194 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" -msgstr "æ­£è¦è¡¨ç¾ãŒç„¡åйã§ã™: %s" +msgstr "æ­£è¦è¡¨ç¾ãŒä¸æ­£ã§ã™: %s" -#: tsearch/spell.c:596 tsearch/spell.c:842 tsearch/spell.c:862 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format -msgid "multibyte flag character is not allowed" -msgstr "マルãƒãƒã‚¤ãƒˆãƒ•ラグ付ãã®æ–‡å­—ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgid "invalid affix alias \"%s\"" +msgstr "䏿­£ãªæŽ¥è¾žã®åˆ¥å \"%s\"" -#: tsearch/spell.c:629 tsearch/spell.c:687 tsearch/spell.c:780 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "affixファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: tsearch/spell.c:675 +#: tsearch/spell.c:1265 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell辞書ã¯ãƒ•ラグ値\"default\"ã€\"long\"ãŠã‚ˆã³\"num\"ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™" + +#: tsearch/spell.c:1309 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "䏿­£ãªæ•°ã®ãƒ•ラグベクタã®åˆ¥å" + +#: tsearch/spell.c:1332 #, c-format -msgid "Ispell dictionary supports only default flag value" -msgstr "Ispell ã®è¾žæ›¸ã¯ãƒ‡ãƒ•ォルトフラグ値ã®ã¿ã‚’サãƒãƒ¼ãƒˆã—ã¾ã™" +msgid "number of aliases exceeds specified number %d" +msgstr "別åã®æ•°ãŒæŒ‡å®šã•ã‚ŒãŸæ•° %d ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: tsearch/spell.c:873 +#: tsearch/spell.c:1547 #, c-format -msgid "wrong affix file format for flag" -msgstr "フラグã«é–¢ã™ã‚‹ affix ãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸å¼ãŒèª¤ã£ã¦ã„ã¾ã™" +msgid "affix file contains both old-style and new-style commands" +msgstr "æŽ¥è¾žãƒ•ã‚¡ã‚¤ãƒ«ãŒæ–°æ—§ä¸¡æ–¹ã®å½¢å¼ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’å«ã‚“ã§ã„ã¾ã™" -#: tsearch/to_tsany.c:163 utils/adt/tsvector.c:269 utils/adt/tsvector_op.c:530 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "TSベクターã®ãŸã‚ã®æ–‡å­—列ãŒé•·ã™ãŽã¾ã™(%dãƒã‚¤ãƒˆã€æœ€å¤§ã¯%dãƒã‚¤ãƒˆ)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" -msgstr "設定ファイル\"%2$s\"ã®%1$d行目:\"%3$s\"" +msgstr "設定ファイル\"%2$s\"ã®%1$d行目: \"%3$s\"" #: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "wchar_tã‹ã‚‰ã‚µãƒ¼ãƒç¬¦å·åŒ–æ–¹å¼ã¸ã®å¤‰æ›ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" -#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:560 -#: tsearch/ts_parse.c:567 +#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:566 +#: tsearch/ts_parse.c:573 #, c-format msgid "word is too long to be indexed" msgstr "インデックス付ã‘ã™ã‚‹ã«ã¯å˜èªžãŒé•·ã™ãŽã¾ã™" -#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:561 -#: tsearch/ts_parse.c:568 +#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:567 +#: tsearch/ts_parse.c:574 #, c-format msgid "Words longer than %d characters are ignored." msgstr "%dより長ã„å˜èªžã¯ç„¡è¦–ã•れã¾ã™ã€‚" @@ -15043,124 +20232,124 @@ msgstr "%dより長ã„å˜èªžã¯ç„¡è¦–ã•れã¾ã™ã€‚" #: tsearch/ts_utils.c:51 #, c-format msgid "invalid text search configuration file name \"%s\"" -msgstr "テキスト検索設定ファイルåã¯%sã¯ç„¡åйã§ã™" +msgstr "テキスト検索設定ファイルåã¯%sã¯ä¸æ­£ã§ã™" #: tsearch/ts_utils.c:83 #, c-format msgid "could not open stop-word file \"%s\": %m" msgstr "ストップワードファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: tsearch/wparser.c:306 +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 #, c-format msgid "text search parser does not support headline creation" msgstr "テキスト検索パーサã¯è¦‹å‡ºã—作æˆã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: tsearch/wparser_def.c:2551 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "未知ã®è¦‹å‡ºã—パラメータ: \"%s\"" -#: tsearch/wparser_def.c:2560 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "MinWordsã¯MaxWordsよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: tsearch/wparser_def.c:2564 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "MinWordsã¯æ­£ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: tsearch/wparser_def.c:2568 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "ShortWordã¯>= 0ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: tsearch/wparser_def.c:2572 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "MaxFragments 㯠0 以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format msgid "identifier too long" msgstr "識別å­ãŒé•·ã™ãŽã¾ã™" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format msgid "Identifier must be less than %d characters." msgstr "識別å­ã¯%d文字より短ããªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "キーワードãŒä¸æ˜Žã§ã™: \"%s\"" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "ACLキーワードã¯\"group\"ã¾ãŸã¯\"user\"ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "åå‰ãŒã‚りã¾ã›ã‚“" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "\"group\"ã¾ãŸã¯\"user\"キーワードã®å¾Œã«ã¯åå‰ãŒå¿…è¦ã§ã™ã€‚" -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "\"=\"記å·ãŒã‚りã¾ã›ã‚“" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" -msgstr "モード文字ãŒç„¡åйã§ã™: \"%s\"ã®ä¸€ã¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "䏿­£ãªãƒ¢ãƒ¼ãƒ‰æ–‡å­—: \"%s\"ã®ä¸€ã¤ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "\"/\"記å·ã®å¾Œã«ã¯åå‰ãŒå¿…è¦ã§ã™" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "権é™ä»˜ä¸Žè€…をデフォルトã®ãƒ¦ãƒ¼ã‚¶ID %uã«ã—ã¦ã„ã¾ã™" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "ACLé…列ã«ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿åž‹ãŒã‚りã¾ã™ã€‚" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "ACLé…列ã¯1次元ã®é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "ACLé…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "ACL指定ã®å¾Œã«ä½™è¨ˆãªã”ã¿ãŒã‚りã¾ã™" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1213 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "グラントオプションã§ãã®æ¨©é™ä»˜ä¸Žè€…ã«æ¨©é™ã‚’戻ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1274 #, c-format msgid "dependent privileges exist" msgstr "ä¾å­˜ã™ã‚‹æ¨©é™ãŒå­˜åœ¨ã—ã¾ã™" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1275 #, c-format msgid "Use CASCADE to revoke them too." msgstr "ã“れらもå–り上ã’ã‚‹ã«ã¯CASCADEを使用ã—ã¦ãã ã•ã„" @@ -15178,251 +20367,338 @@ msgstr "aclremoveã¯ã‚‚ã†ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" #: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format msgid "unrecognized privilege type: \"%s\"" -msgstr "権é™ç¨®é¡žãŒä¸æ˜Žã§ã™: \"%s\"" +msgstr "権é™ã‚¿ã‚¤ãƒ—ãŒä¸æ˜Žã§ã™: \"%s\"" -#: utils/adt/acl.c:3427 utils/adt/regproc.c:122 utils/adt/regproc.c:143 -#: utils/adt/regproc.c:293 +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "関数\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/adt/acl.c:4876 +#: utils/adt/acl.c:4959 #, c-format msgid "must be member of role \"%s\"" msgstr "ロール\"%s\"ã®ãƒ¡ãƒ³ãƒã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:48 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 +#: utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "é…åˆ—ã®æ¬¡æ•°ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 +#: utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format -msgid "could not determine input data types" -msgstr "入力データ型を決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "could not determine input data type" +msgstr "入力データ型を特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/array_userfuncs.c:82 +#: utils/adt/array_userfuncs.c:85 #, c-format -msgid "neither input type is an array" -msgstr "入力型ãŒé…列ã§ã¯ã‚りã¾ã›ã‚“" +msgid "input data type is not an array" +msgstr "入力データ型ã¯é…列ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:103 utils/adt/array_userfuncs.c:113 -#: utils/adt/arrayfuncs.c:1281 utils/adt/float.c:1214 utils/adt/float.c:1273 -#: utils/adt/float.c:2824 utils/adt/float.c:2840 utils/adt/int.c:623 -#: utils/adt/int.c:652 utils/adt/int.c:673 utils/adt/int.c:704 -#: utils/adt/int.c:737 utils/adt/int.c:759 utils/adt/int.c:907 -#: utils/adt/int.c:928 utils/adt/int.c:955 utils/adt/int.c:995 -#: utils/adt/int.c:1016 utils/adt/int.c:1043 utils/adt/int.c:1076 -#: utils/adt/int.c:1159 utils/adt/int8.c:1247 utils/adt/numeric.c:2242 -#: utils/adt/numeric.c:2251 utils/adt/varbit.c:1145 utils/adt/varbit.c:1537 -#: utils/adt/varlena.c:1013 utils/adt/varlena.c:2036 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1376 utils/adt/float.c:1464 +#: utils/adt/float.c:3765 utils/adt/float.c:3779 utils/adt/int.c:755 +#: utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 +#: utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 +#: utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 +#: utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 +#: utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 +#: utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format msgid "integer out of range" msgstr "integerã®ç¯„囲外ã§ã™" -#: utils/adt/array_userfuncs.c:121 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "引数ã¯ç©ºã‹1次元ã®é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:224 utils/adt/array_userfuncs.c:263 -#: utils/adt/array_userfuncs.c:300 utils/adt/array_userfuncs.c:329 -#: utils/adt/array_userfuncs.c:357 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "äº’æ›æ€§ãŒãªã„é…列を連çµã§ãã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:225 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "è¦ç´ åž‹%sã¨%sã®é…列ã®é€£çµã«ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:264 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "è¦ç´ æ•°%dã¨%dã®é…列ã®é€£çµã«ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:301 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "ç•°ãªã‚‹è¦ç´ æ¬¡æ•°ã®é…列ã®é€£çµã«ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。" -#: utils/adt/array_userfuncs.c:330 utils/adt/array_userfuncs.c:358 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "ç•°ãªã‚‹æ¬¡æ•°ã®é…列ã®é€£çµã«ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。" -#: utils/adt/array_userfuncs.c:426 utils/adt/arrayfuncs.c:1243 -#: utils/adt/arrayfuncs.c:2916 utils/adt/arrayfuncs.c:4941 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format -msgid "invalid number of dimensions: %d" -msgstr "次数ãŒç„¡åйã§ã™: %d" +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "多次元é…列内ã®è¦ç´ ã®æ¤œç´¢ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: utils/adt/array_userfuncs.c:487 utils/adt/json.c:1587 utils/adt/json.c:1664 +#: utils/adt/array_userfuncs.c:686 #, c-format -msgid "could not determine input data type" -msgstr "入力データ型を特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "initial position must not be null" +msgstr "åˆæœŸä½ç½®nullã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:240 utils/adt/arrayfuncs.c:252 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format -msgid "missing dimension value" -msgstr "次元数ãŒã‚りã¾ã›ã‚“" +msgid "malformed array literal: \"%s\"" +msgstr "é…åˆ—ãƒªãƒ†ãƒ©ãƒ«ã®æ›¸å¼ãŒèª¤ã£ã¦ã„ã¾ã™: \"%s\"" + +#: utils/adt/arrayfuncs.c:270 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "\"[\"ã¯é…åˆ—æ¬¡å…ƒã®æ˜Žç¤ºçš„ãªæŒ‡å®šã®å…ˆé ­ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/arrayfuncs.c:262 +#: utils/adt/arrayfuncs.c:284 #, c-format -msgid "missing \"]\" in array dimensions" -msgstr "é…åˆ—ã®æ¬¡å…ƒã«\"]\"ãŒã‚りã¾ã›ã‚“" +msgid "Missing array dimension value." +msgstr "é…åˆ—ã®æ¬¡å…ƒæ•°ã®å€¤ãŒã‚りã¾ã›ã‚“。" -#: utils/adt/arrayfuncs.c:270 utils/adt/arrayfuncs.c:2441 -#: utils/adt/arrayfuncs.c:2469 utils/adt/arrayfuncs.c:2484 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "é…åˆ—ã®æ¬¡å…ƒã®å¾Œã«\"%s\"ãŒã‚りã¾ã›ã‚“。" + +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "上é™ã‚’下é™ã‚ˆã‚Šå°ã•ãã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:282 utils/adt/arrayfuncs.c:308 +#: utils/adt/arrayfuncs.c:317 #, c-format -msgid "array value must start with \"{\" or dimension information" -msgstr "é…列値ã¯\"[\"ã‹æ¬¡å…ƒæƒ…å ±ã‹ã‚‰å§‹ã¾ã‚‰ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "Array value must start with \"{\" or dimension information." +msgstr "é…列値ã¯\"{\"ã¾ãŸã¯æ¬¡å…ƒæƒ…å ±ã‹ã‚‰å§‹ã¾ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/arrayfuncs.c:296 +#: utils/adt/arrayfuncs.c:346 #, c-format -msgid "missing assignment operator" -msgstr "代入演算å­ãŒã‚りã¾ã›ã‚“" +msgid "Array contents must start with \"{\"." +msgstr "é…列ã®å†…容ã¯\"{\"ã§å§‹ã¾ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/arrayfuncs.c:313 utils/adt/arrayfuncs.c:319 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format -msgid "array dimensions incompatible with array literal" -msgstr "é…åˆ—ã®æ¬¡å…ƒã¨é…列リテラルã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" +msgid "Specified array dimensions do not match array contents." +msgstr "指定ã•れãŸé…åˆ—ã®æ¬¡å…ƒæ•°ãŒé…列ã®å†…容ã¨åˆè‡´ã—ã¦ã„ã¾ã›ã‚“。" -#: utils/adt/arrayfuncs.c:449 utils/adt/arrayfuncs.c:464 -#: utils/adt/arrayfuncs.c:473 utils/adt/arrayfuncs.c:487 -#: utils/adt/arrayfuncs.c:507 utils/adt/arrayfuncs.c:535 -#: utils/adt/arrayfuncs.c:540 utils/adt/arrayfuncs.c:580 -#: utils/adt/arrayfuncs.c:601 utils/adt/arrayfuncs.c:620 -#: utils/adt/arrayfuncs.c:730 utils/adt/arrayfuncs.c:739 -#: utils/adt/arrayfuncs.c:769 utils/adt/arrayfuncs.c:784 -#: utils/adt/arrayfuncs.c:837 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 +#: utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format -msgid "malformed array literal: \"%s\"" -msgstr "é…åˆ—ãƒªãƒ†ãƒ©ãƒ«ã®æ›¸å¼ãŒèª¤ã£ã¦ã„ã¾ã™: \"%s\"" +msgid "Unexpected end of input." +msgstr "想定外ã®å…¥åŠ›ã®çµ‚端。" -#: utils/adt/arrayfuncs.c:876 utils/adt/arrayfuncs.c:1478 -#: utils/adt/arrayfuncs.c:2800 utils/adt/arrayfuncs.c:2948 -#: utils/adt/arrayfuncs.c:5041 utils/adt/arrayfuncs.c:5373 -#: utils/adt/arrayutils.c:93 utils/adt/arrayutils.c:102 -#: utils/adt/arrayutils.c:109 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format -msgid "array size exceeds the maximum allowed (%d)" -msgstr "é…åˆ—ã®æ¬¡æ•°ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" +msgid "Unexpected \"%c\" character." +msgstr "æƒ³å®šå¤–ã®æ–‡å­—\"%c\"。" + +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 +#, c-format +msgid "Unexpected array element." +msgstr "想定外ã®é…列è¦ç´ ã€‚" + +#: utils/adt/arrayfuncs.c:590 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "対応ã—ãªã„ \"%c\" 文字。" + +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "多次元é…列ã¯åˆè‡´ã™ã‚‹æ¬¡å…ƒã®å‰¯é…列をæŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: utils/adt/arrayfuncs.c:675 +#, c-format +msgid "Junk after closing right brace." +msgstr "峿‹¬å¼§ã®å¾Œã«ã”ã¿ãŒã‚りã¾ã™ã€‚" + +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5816 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "䏿­£ãªæ¬¡å…ƒæ•°: %d" -#: utils/adt/arrayfuncs.c:1254 +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" -msgstr "é…列フラグãŒç„¡åйã§ã™" +msgstr "䏿­£ãªé…列フラグ" -#: utils/adt/arrayfuncs.c:1262 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" -msgstr "è¦ç´ åž‹ãŒé–“é•ã£ã¦ã„ã¾ã™" +msgstr "é–“é•ã£ãŸè¦ç´ åž‹" -#: utils/adt/arrayfuncs.c:1312 utils/adt/rangetypes.c:325 -#: utils/cache/lsyscache.c:2530 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "åž‹%sã«ã¯ãƒã‚¤ãƒŠãƒªå…¥åŠ›é–¢æ•°ãŒã‚りã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:1452 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "é…列è¦ç´ %dã®ãƒã‚¤ãƒŠãƒªæ›¸å¼ãŒä¸é©åˆ‡ã§ã™" -#: utils/adt/arrayfuncs.c:1534 utils/adt/rangetypes.c:330 -#: utils/cache/lsyscache.c:2563 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "åž‹%sã«ã¯ãƒã‚¤ãƒŠãƒªå‡ºåŠ›é–¢æ•°ãŒã‚りã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:1908 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "固定長é…列ã®éƒ¨åˆ†é…列ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:2081 utils/adt/arrayfuncs.c:2103 -#: utils/adt/arrayfuncs.c:2137 utils/adt/arrayfuncs.c:2423 -#: utils/adt/arrayfuncs.c:4921 utils/adt/arrayfuncs.c:4953 -#: utils/adt/arrayfuncs.c:4970 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 +#: utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 +#: utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 +#: utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "é…åˆ—ã®æ·»ãˆå­—ãŒä¸æ­£ãªæ•°å€¤ã§ã™" -#: utils/adt/arrayfuncs.c:2086 utils/adt/arrayfuncs.c:2179 -#: utils/adt/arrayfuncs.c:2474 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "é…åˆ—ã®æ·»ãˆå­—ãŒç¯„囲外ã§ã™" -#: utils/adt/arrayfuncs.c:2091 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "固定長é…列ã®è¦ç´ ã«NULL値を代入ã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:2377 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "固定長é…列ã®éƒ¨åˆ†é…åˆ—ã®æ›´æ–°ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:2413 utils/adt/arrayfuncs.c:2500 +#: utils/adt/arrayfuncs.c:2839 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "é…列ã®ã‚¹ãƒ©ã‚¤ã‚¹ã®æ·»ãˆå­—ã¯ä¸¡æ–¹ã®å¢ƒç•Œã‚’示ã™å¿…è¦ãŒã‚りã¾ã™" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "空ã®é…列値ã®ã‚¹ãƒ©ã‚¤ã‚¹ã«ä»£å…¥ã™ã‚‹ã«ã¯ã€ã‚¹ãƒ©ã‚¤ã‚¹ã®ç¯„囲ã¯å®Œå…¨ã«æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "å…ƒã®é…列ãŒå°ã•ã™ãŽã¾ã™" -#: utils/adt/arrayfuncs.c:3055 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "ã“ã®æ–‡è„ˆã§ã¯NULLã®é…列è¦ç´ ã¯è¨±ã•れã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:3158 utils/adt/arrayfuncs.c:3366 -#: utils/adt/arrayfuncs.c:3683 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4124 #, c-format msgid "cannot compare arrays of different element types" msgstr "è¦ç´ åž‹ã®ç•°ãªã‚‹é…列を比較ã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:3568 utils/adt/rangetypes.c:1206 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 +#: utils/adt/rangetypes.c:1317 #, c-format msgid "could not identify a hash function for type %s" msgstr "åž‹ %s ã®ãƒãƒƒã‚·ãƒ¥é–¢æ•°ã‚’識別ã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:4819 utils/adt/arrayfuncs.c:4859 +#: utils/adt/arrayfuncs.c:4040 #, c-format -msgid "dimension array or low bound array cannot be null" -msgstr "次元é…列もã—ãã¯ä¸‹é™å€¤é…列㌠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgid "could not identify an extended hash function for type %s" +msgstr "åž‹ %s ã®æ‹¡å¼µãƒãƒƒã‚·ãƒ¥é–¢æ•°ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/arrayfuncs.c:4922 utils/adt/arrayfuncs.c:4954 +#: utils/adt/arrayfuncs.c:5216 #, c-format -msgid "Dimension array must be one dimensional." -msgstr "次元é…列ã¯1次元ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "data type %s is not an array type" +msgstr "データ型%sã¯é…列型ã§ã¯ã‚りã¾ã›ã‚“" + +#: utils/adt/arrayfuncs.c:5271 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "nullé…列ã¯é€£çµã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:4927 utils/adt/arrayfuncs.c:4959 +#: utils/adt/arrayfuncs.c:5299 #, c-format -msgid "wrong range of array subscripts" -msgstr "é…åˆ—ã®æ·»å­—ã®ç¯„囲ãŒèª¤ã£ã¦ã„ã¾ã™" +msgid "cannot accumulate empty arrays" +msgstr "空ã®é…列ã¯é€£çµã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:4928 utils/adt/arrayfuncs.c:4960 +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 #, c-format -msgid "Lower bound of dimension array must be one." -msgstr "次元é…åˆ—ã®æ·»å­—ã®ä¸‹é™ã¯ï¼‘ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "cannot accumulate arrays of different dimensionality" +msgstr "次元ã®ç•°ãªã‚‹é…列ã¯çµåˆã§ãã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:4933 utils/adt/arrayfuncs.c:4965 +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "次元é…列もã—ãã¯ä¸‹é™å€¤é…列㌠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "次元é…列ã¯1次元ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 #, c-format msgid "dimension values cannot be null" msgstr "次元値㫠null ã¯è¨±ã•れã¾ã›ã‚“" -#: utils/adt/arrayfuncs.c:4971 +#: utils/adt/arrayfuncs.c:5840 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "下é™é…åˆ—ãŒæ¬¡å…ƒé…列ã®ã‚µã‚¤ã‚ºã¨ç•°ãªã£ã¦ã„ã¾ã™" -#: utils/adt/arrayfuncs.c:5238 +#: utils/adt/arrayfuncs.c:6086 #, c-format -#| msgid "multidimensional arrays are not supported" msgid "removing elements from multidimensional arrays is not supported" msgstr "多次元é…列ã‹ã‚‰ã®è¦ç´ å‰Šé™¤ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +#: utils/adt/arrayfuncs.c:6363 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "閾値ã¯1次元ã®é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/arrayfuncs.c:6368 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "閾値é…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" + #: utils/adt/arrayutils.c:209 #, c-format msgid "typmod array must be type cstring[]" @@ -15438,30 +20714,49 @@ msgstr "typmodé…列ã¯1次元ã®é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" msgid "typmod array must not contain nulls" msgstr "typmodé…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/ascii.c:75 +#: utils/adt/ascii.c:76 #, c-format msgid "encoding conversion from %s to ASCII not supported" msgstr "%s符å·åŒ–æ–¹å¼ã‹ã‚‰ASCIIã¸ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/bool.c:153 +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 +#: utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 +#: utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 +#: utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 +#: utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 +#: utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 +#: utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 +#: utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 +#: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 +#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1542 +#: utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 +#: utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 +#: utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 +#: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 +#: utils/adt/uuid.c:136 #, c-format -msgid "invalid input syntax for type boolean: \"%s\"" -msgstr "booleanåž‹ã¸ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "\"%s\"åž‹ã®å…¥åŠ›æ§‹æ–‡ãŒä¸æ­£ã§ã™: \"%s\"" -#: utils/adt/cash.c:246 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 +#: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format -msgid "invalid input syntax for type money: \"%s\"" -msgstr "moneyåž‹ã¸ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgid "value \"%s\" is out of range for type %s" +msgstr "値\"%s\"ã¯åž‹%sã®ç¯„囲外ã§ã™" -#: utils/adt/cash.c:609 utils/adt/cash.c:659 utils/adt/cash.c:710 -#: utils/adt/cash.c:759 utils/adt/cash.c:811 utils/adt/cash.c:861 -#: utils/adt/float.c:841 utils/adt/float.c:905 utils/adt/float.c:2583 -#: utils/adt/float.c:2646 utils/adt/geo_ops.c:4127 utils/adt/int.c:719 -#: utils/adt/int.c:861 utils/adt/int.c:969 utils/adt/int.c:1058 -#: utils/adt/int.c:1097 utils/adt/int.c:1125 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:846 utils/adt/int8.c:954 -#: utils/adt/int8.c:1043 utils/adt/int8.c:1151 utils/adt/numeric.c:4510 -#: utils/adt/numeric.c:4793 utils/adt/timestamp.c:3021 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3526 +#: utils/adt/float.c:3589 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 +#: utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 +#: utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 +#: utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 +#: utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3238 #, c-format msgid "division by zero" msgstr "0 ã«ã‚ˆã‚‹é™¤ç®—ãŒè¡Œã‚れã¾ã—ãŸ" @@ -15471,147 +20766,196 @@ msgstr "0 ã«ã‚ˆã‚‹é™¤ç®—ãŒè¡Œã‚れã¾ã—ãŸ" msgid "\"char\" out of range" msgstr "\"char\"ã®ç¯„囲外ã§ã™" -#: utils/adt/date.c:68 utils/adt/timestamp.c:93 utils/adt/varbit.c:52 -#: utils/adt/varchar.c:44 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 +#: utils/adt/varchar.c:46 #, c-format msgid "invalid type modifier" -msgstr "無効ãªåž‹ä¿®é£¾å­ã§ã™ã€‚" +msgstr "䏿­£ãªåž‹ä¿®é£¾å­ã§ã™ã€‚" -#: utils/adt/date.c:73 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "(%d)%sã®ç²¾åº¦ã¯è² ã§ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/date.c:79 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "TIME(%d)%sã®ä½å–りを許容最大値%dã¾ã§æ¸›ã‚‰ã—ã¾ã—ãŸ" -#: utils/adt/date.c:144 utils/adt/datetime.c:1200 utils/adt/datetime.c:1942 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "日付時刻ã®å€¤\"current\"ã¯ã‚‚ã†ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/date.c:169 utils/adt/formatting.c:3412 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 +#: utils/adt/formatting.c:3615 #, c-format msgid "date out of range: \"%s\"" msgstr "日付ãŒç¯„囲外ã§ã™: \"%s\"" -#: utils/adt/date.c:219 utils/adt/xml.c:2033 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2089 #, c-format msgid "date out of range" msgstr "日付ãŒç¯„囲外ã§ã™" -#: utils/adt/date.c:383 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "日付フィールドã®å€¤ãŒç¯„囲外ã§ã™: %d-%02d-%02d" + +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "日付ãŒç¯„囲外ã§ã™: %d-%02d-%02d" + +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 +#: utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 +#: utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 +#: utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:459 +#: utils/adt/nabstime.c:502 utils/adt/nabstime.c:532 utils/adt/nabstime.c:575 +#: utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2817 utils/adt/timestamp.c:2838 +#: utils/adt/timestamp.c:2851 utils/adt/timestamp.c:2860 +#: utils/adt/timestamp.c:2868 utils/adt/timestamp.c:2923 +#: utils/adt/timestamp.c:2946 utils/adt/timestamp.c:2959 +#: utils/adt/timestamp.c:2970 utils/adt/timestamp.c:2978 +#: utils/adt/timestamp.c:3638 utils/adt/timestamp.c:3763 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3894 +#: utils/adt/timestamp.c:3940 utils/adt/timestamp.c:4043 +#: utils/adt/timestamp.c:4450 utils/adt/timestamp.c:4549 +#: utils/adt/timestamp.c:4559 utils/adt/timestamp.c:4651 +#: utils/adt/timestamp.c:4753 utils/adt/timestamp.c:4763 +#: utils/adt/timestamp.c:4995 utils/adt/timestamp.c:5009 +#: utils/adt/timestamp.c:5014 utils/adt/timestamp.c:5028 +#: utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5105 +#: utils/adt/timestamp.c:5112 utils/adt/timestamp.c:5145 +#: utils/adt/timestamp.c:5149 utils/adt/timestamp.c:5218 +#: utils/adt/timestamp.c:5222 utils/adt/timestamp.c:5236 +#: utils/adt/timestamp.c:5270 utils/adt/xml.c:2111 utils/adt/xml.c:2118 +#: utils/adt/xml.c:2138 utils/adt/xml.c:2145 +#, c-format +msgid "timestamp out of range" +msgstr "timestampã®ç¯„囲外ã§ã™" + +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "ç„¡é™å¤§ã®æ—¥ä»˜ã¯æ¸›ç®—ã§ãã¾ã›ã‚“" -#: utils/adt/date.c:440 utils/adt/date.c:477 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format msgid "date out of range for timestamp" msgstr "ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—ã§æ—¥ä»˜ãŒç¯„囲外ã§ã™" -#: utils/adt/date.c:936 utils/adt/date.c:982 utils/adt/date.c:1549 -#: utils/adt/date.c:1585 utils/adt/date.c:2457 utils/adt/formatting.c:3288 -#: utils/adt/formatting.c:3320 utils/adt/formatting.c:3388 -#: utils/adt/nabstime.c:481 utils/adt/nabstime.c:524 utils/adt/nabstime.c:554 -#: utils/adt/nabstime.c:597 utils/adt/timestamp.c:226 -#: utils/adt/timestamp.c:269 utils/adt/timestamp.c:502 -#: utils/adt/timestamp.c:541 utils/adt/timestamp.c:2676 -#: utils/adt/timestamp.c:2697 utils/adt/timestamp.c:2710 -#: utils/adt/timestamp.c:2719 utils/adt/timestamp.c:2776 -#: utils/adt/timestamp.c:2799 utils/adt/timestamp.c:2812 -#: utils/adt/timestamp.c:2823 utils/adt/timestamp.c:3259 -#: utils/adt/timestamp.c:3388 utils/adt/timestamp.c:3429 -#: utils/adt/timestamp.c:3517 utils/adt/timestamp.c:3563 -#: utils/adt/timestamp.c:3674 utils/adt/timestamp.c:3998 -#: utils/adt/timestamp.c:4137 utils/adt/timestamp.c:4147 -#: utils/adt/timestamp.c:4209 utils/adt/timestamp.c:4349 -#: utils/adt/timestamp.c:4359 utils/adt/timestamp.c:4574 -#: utils/adt/timestamp.c:4653 utils/adt/timestamp.c:4660 -#: utils/adt/timestamp.c:4686 utils/adt/timestamp.c:4690 -#: utils/adt/timestamp.c:4747 utils/adt/xml.c:2055 utils/adt/xml.c:2062 -#: utils/adt/xml.c:2082 utils/adt/xml.c:2089 -#, c-format -msgid "timestamp out of range" -msgstr "timestampã®ç¯„囲外ã§ã™" - -#: utils/adt/date.c:1008 +#: utils/adt/date.c:1190 #, c-format msgid "cannot convert reserved abstime value to date" msgstr "予約ã•れãŸabstimeã‹ã‚‰dateã¸ã®å¤‰æ›ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/date.c:1162 utils/adt/date.c:1169 utils/adt/date.c:1947 -#: utils/adt/date.c:1954 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 +#, c-format +msgid "abstime out of range for date" +msgstr "絶対時間ãŒd日付ã®ç¯„囲外ã§ã™" + +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format msgid "time out of range" msgstr "時刻ãŒç¯„囲外ã§ã™" -#: utils/adt/date.c:1825 utils/adt/date.c:1842 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "時刻フィールドã®å€¤ãŒç¯„囲外ã§ã™: %d:%02d:%02g" + +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 +#: utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 +#: utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 +#: utils/adt/timestamp.c:3287 utils/adt/timestamp.c:3318 +#: utils/adt/timestamp.c:3349 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "ウィンドウ関数ã§ã®ä¸æ­£ãªã‚µã‚¤ã‚ºã® PRECEDING ã¾ãŸã¯ FOLLOWING 指定" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "\"time\"ã®å˜ä½\"%s\"ãŒä¸æ˜Žã§ã™" -#: utils/adt/date.c:1963 +#: utils/adt/date.c:2099 #, c-format msgid "time zone displacement out of range" -msgstr "時間帯ã®ç½®æ›ãŒç¯„囲外ã§ã™" +msgstr "タイムゾーンã®ç½®æ›ãŒç¯„囲外ã§ã™" -#: utils/adt/date.c:2587 utils/adt/date.c:2604 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "\"time with time zone\"ã®å˜ä½\"%s\"ãŒä¸æ˜Žã§ã™" -#: utils/adt/date.c:2662 utils/adt/datetime.c:931 utils/adt/datetime.c:1671 -#: utils/adt/timestamp.c:4586 utils/adt/timestamp.c:4758 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 +#: utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 +#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:5020 +#: utils/adt/timestamp.c:5228 #, c-format msgid "time zone \"%s\" not recognized" -msgstr "時間帯\"%s\"ã¯ä¸æ˜Žã§ã™" +msgstr "タイムゾーン\"%s\"ã¯ä¸æ˜Žã§ã™" -#: utils/adt/date.c:2702 utils/adt/timestamp.c:4611 utils/adt/timestamp.c:4784 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5062 utils/adt/timestamp.c:5259 #, c-format -#| msgid "interval time zone \"%s\" must not specify month" msgid "interval time zone \"%s\" must not include months or days" -msgstr "intervalã«ã‚ˆã‚‹æ™‚間帯\"%s\"ã«ã¯æœˆã¾ãŸã¯æ—¥ã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "intervalã«ã‚ˆã‚‹ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³\"%s\"ã«ã¯æœˆã¾ãŸã¯æ—¥ã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/datetime.c:3545 utils/adt/datetime.c:3552 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "日付時刻ã®ãƒ•ィールドãŒç¯„囲外ã§ã™: \"%s\"" -#: utils/adt/datetime.c:3554 +#: utils/adt/datetime.c:3770 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "ä»–ã®\"datestyle\"設定ãŒå¿…è¦ã‹ã‚‚ã—れã¾ã›ã‚“。" -#: utils/adt/datetime.c:3559 +#: utils/adt/datetime.c:3775 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "intervalフィールドã®å€¤ãŒç¯„囲外ã§ã™: \"%s\"" -#: utils/adt/datetime.c:3565 +#: utils/adt/datetime.c:3781 #, c-format msgid "time zone displacement out of range: \"%s\"" -msgstr "時間帯ã®ç½®æ›ãŒç¯„囲外ã§ã™: \"%s\"" +msgstr "タイムゾーンã®ç½®æ›ãŒç¯„囲外ã§ã™: \"%s\"" -#. translator: first %s is inet or cidr -#: utils/adt/datetime.c:3572 utils/adt/network.c:107 +#: utils/adt/datetime.c:4627 #, c-format -msgid "invalid input syntax for type %s: \"%s\"" -msgstr "\"%s\"åž‹ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "ã“ã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã¯ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³çœç•¥å\"%s\"ã®æ§‹æˆãƒ•ァイルã«ã‚るよã†ã§ã™ã€‚" -#: utils/adt/datum.c:80 utils/adt/datum.c:92 +#: utils/adt/datum.c:86 utils/adt/datum.c:98 #, c-format msgid "invalid Datum pointer" -msgstr "Datumãƒã‚¤ãƒ³ã‚¿ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªDatumãƒã‚¤ãƒ³ã‚¿" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "䏿­£ãªã‚µã‚¤ã‚º: \"%s\"" -#: utils/adt/dbsize.c:109 +#: utils/adt/dbsize.c:828 #, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "テーブル空間ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgid "Invalid size unit: \"%s\"." +msgstr "䏿­£ãªã‚µã‚¤ã‚ºã®å˜ä½: \"%s\"" -#: utils/adt/domains.c:83 +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "有効ãªå˜ä½ã¯ \"bytes\"ã€\"kB\"ã€\"MB\"ã€\"GB\"ãã—ã¦\"TB\"。" + +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "åž‹%sã¯ãƒ‰ãƒ¡ã‚¤ãƒ³ã§ã¯ã‚りã¾ã›ã‚“" @@ -15624,56 +20968,75 @@ msgstr "符å·åŒ–æ–¹å¼ãŒä¸æ˜Žã§ã™: \"%s\"" #: utils/adt/encode.c:150 #, c-format msgid "invalid hexadecimal digit: \"%c\"" -msgstr "16進数表ç¾ãŒç„¡åйã§ã™: \"%c\"" +msgstr "䏿­£ãª16進数表ç¾: \"%c\"" #: utils/adt/encode.c:178 #, c-format msgid "invalid hexadecimal data: odd number of digits" -msgstr "16進数データãŒç„¡åйã§ã™: ãŠã‹ã—ãªæ•°å€¤è¡¨ç¾ã§ã™" +msgstr "䏿­£ãª16進数データ: æ¡æ•°ãŒå¥‡æ•°ã§ã™" #: utils/adt/encode.c:295 #, c-format -msgid "unexpected \"=\"" -msgstr "\"=\"ã¯æƒ³å®šå¤–ã§ã™" +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "base64シーケンスã®ãƒ‡ã‚³ãƒ¼ãƒ‰ä¸­ã«æƒ³å®šå¤–ã®\"=\"" #: utils/adt/encode.c:307 #, c-format -msgid "invalid symbol" -msgstr "シンボルãŒç„¡åйã§ã™" +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "base64シーケンスã®ãƒ‡ã‚³ãƒ¼ãƒ‰ä¸­ã«ä¸æ­£ãªã‚·ãƒ³ãƒœãƒ«\"%c\"" #: utils/adt/encode.c:327 #, c-format -msgid "invalid end sequence" -msgstr "終了シーケンスãŒç„¡åйã§ã™" +msgid "invalid base64 end sequence" +msgstr "䏿­£ãªbase64終了シーケンス" + +#: utils/adt/encode.c:328 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "入力データã«ãƒ‘ディングãŒã‚りã¾ã›ã‚“ã€åˆ‡ã‚Šè©°ã‚られãŸã‹ã•ã‚‚ãªã‘れã°å£Šã‚Œã¦ã„ã¾ã™ã€‚" -#: utils/adt/encode.c:441 utils/adt/encode.c:506 utils/adt/varlena.c:255 -#: utils/adt/varlena.c:296 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 +#: utils/adt/varlena.c:337 #, c-format -msgid "invalid input syntax for type bytea" -msgstr "byteaåž‹ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™" +msgid "invalid input syntax for type %s" +msgstr "%såž‹ã«å¯¾ã™ã‚‹ä¸æ­£ãªå…¥åŠ›æ§‹æ–‡" #: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 #: utils/adt/enum.c:123 #, c-format msgid "invalid input value for enum %s: \"%s\"" -msgstr "列挙型%sã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgstr "列挙型%sã®ä¸æ­£ãªå…¥åŠ›æ§‹æ–‡: \"%s\"" -#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:198 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format msgid "invalid internal value for enum: %u" -msgstr "列挙型用ã®å†…部値ãŒç„¡åйã§ã™: %u" +msgstr "列挙型用ã®ä¸æ­£ãªå†…部値: %u" -#: utils/adt/enum.c:357 utils/adt/enum.c:386 utils/adt/enum.c:426 -#: utils/adt/enum.c:446 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 +#: utils/adt/enum.c:449 #, c-format msgid "could not determine actual enum type" msgstr "実際ã®åˆ—挙型を決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/enum.c:365 utils/adt/enum.c:394 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format msgid "enum %s contains no values" msgstr "列挙型 %s ã«å€¤ãŒã‚りã¾ã›ã‚“" +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 +#: utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "åž‹%sã¯è¤‡åˆåž‹ã§ã¯ã‚りã¾ã›ã‚“" + #: utils/adt/float.c:55 #, c-format msgid "value out of range: overflow" @@ -15684,1560 +21047,1766 @@ msgstr "範囲外ã®å€¤ã§ã™: オーãƒãƒ¼ãƒ•ロー" msgid "value out of range: underflow" msgstr "範囲外ã®å€¤ã§ã™: アンダーフロー" -#: utils/adt/float.c:207 utils/adt/float.c:281 utils/adt/float.c:337 -#, c-format -msgid "invalid input syntax for type real: \"%s\"" -msgstr "åž‹realã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/float.c:275 +#: utils/adt/float.c:309 #, c-format msgid "\"%s\" is out of range for type real" msgstr "åž‹realã§ã¯\"%s\"ã¯ç¯„囲外ã§ã™" -#: utils/adt/float.c:438 utils/adt/float.c:512 utils/adt/float.c:568 -#: utils/adt/numeric.c:3972 utils/adt/numeric.c:3998 -#, c-format -msgid "invalid input syntax for type double precision: \"%s\"" -msgstr "åž‹double precisionã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/float.c:506 +#: utils/adt/float.c:534 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "åž‹double precisionã§ã¯\"%s\"ã¯ç¯„囲外ã§ã™" -#: utils/adt/float.c:1232 utils/adt/float.c:1290 utils/adt/int.c:349 -#: utils/adt/int.c:775 utils/adt/int.c:804 utils/adt/int.c:825 -#: utils/adt/int.c:845 utils/adt/int.c:879 utils/adt/int.c:1174 -#: utils/adt/int8.c:1272 utils/adt/numeric.c:2339 utils/adt/numeric.c:2348 +#: utils/adt/float.c:1408 utils/adt/float.c:1496 utils/adt/int.c:332 +#: utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 +#: utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 +#: utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format msgid "smallint out of range" msgstr "smallintã®ç¯„囲外ã§ã™" -#: utils/adt/float.c:1416 utils/adt/numeric.c:5186 +#: utils/adt/float.c:1622 utils/adt/numeric.c:7802 #, c-format msgid "cannot take square root of a negative number" msgstr "è² ã®å€¤ã®å¹³æ–¹æ ¹ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: utils/adt/float.c:1458 utils/adt/numeric.c:2159 +#: utils/adt/float.c:1683 utils/adt/numeric.c:3017 #, c-format msgid "zero raised to a negative power is undefined" msgstr "0 ã®è² æ•°ä¹—ã¯å®šç¾©ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/float.c:1462 utils/adt/numeric.c:2165 +#: utils/adt/float.c:1687 utils/adt/numeric.c:3023 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "è² æ•°ã‚’æ•´æ•°ã§ãªã„æ•°ã§ã¹ãä¹—ã™ã‚‹ã¨ã€çµæžœãŒè¤‡é›‘ã«ãªã‚Šã¾ã™" -#: utils/adt/float.c:1528 utils/adt/float.c:1558 utils/adt/numeric.c:5404 +#: utils/adt/float.c:1753 utils/adt/float.c:1783 utils/adt/numeric.c:8068 #, c-format msgid "cannot take logarithm of zero" msgstr "ゼロã®å¯¾æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: utils/adt/float.c:1532 utils/adt/float.c:1562 utils/adt/numeric.c:5408 +#: utils/adt/float.c:1757 utils/adt/float.c:1787 utils/adt/numeric.c:8072 #, c-format msgid "cannot take logarithm of a negative number" msgstr "è² ã®å€¤ã®å¯¾æ•°ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: utils/adt/float.c:1589 utils/adt/float.c:1610 utils/adt/float.c:1631 -#: utils/adt/float.c:1653 utils/adt/float.c:1674 utils/adt/float.c:1695 -#: utils/adt/float.c:1717 utils/adt/float.c:1738 +#: utils/adt/float.c:1817 utils/adt/float.c:1847 utils/adt/float.c:1939 +#: utils/adt/float.c:1965 utils/adt/float.c:1992 utils/adt/float.c:2018 +#: utils/adt/float.c:2165 utils/adt/float.c:2200 utils/adt/float.c:2364 +#: utils/adt/float.c:2418 utils/adt/float.c:2482 utils/adt/float.c:2537 #, c-format msgid "input is out of range" msgstr "入力ãŒç¯„囲外ã§ã™" -#: utils/adt/float.c:2800 utils/adt/numeric.c:1212 +#: utils/adt/float.c:3743 utils/adt/numeric.c:1504 #, c-format msgid "count must be greater than zero" msgstr "カウントã¯0より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/float.c:2805 utils/adt/numeric.c:1219 +#: utils/adt/float.c:3748 utils/adt/numeric.c:1511 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "オペランドã®ä¸‹é™ã¨ä¸Šé™ã‚’NaNã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/float.c:2811 +#: utils/adt/float.c:3754 #, c-format msgid "lower and upper bounds must be finite" msgstr "下é™ãŠã‚ˆã³ä¸Šé™ã¯æœ‰é™ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/float.c:2849 utils/adt/numeric.c:1232 +#: utils/adt/float.c:3788 utils/adt/numeric.c:1524 #, c-format msgid "lower bound cannot equal upper bound" msgstr "下é™ã‚’上é™ã¨åŒã˜ã«ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:492 +#: utils/adt/formatting.c:488 #, c-format msgid "invalid format specification for an interval value" -msgstr "\"tinterval\"å€¤ã®æ›¸å¼æŒ‡å®šãŒç„¡åйã§ã™" +msgstr "\"tinterval\"値ã«å¯¾ã™ã‚‹ä¸æ­£ãªæ›¸å¼æŒ‡å®š" -#: utils/adt/formatting.c:493 +#: utils/adt/formatting.c:489 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "時間間隔ãŒç‰¹å®šã®æš¦æ—¥ä»˜ã«çµã³ã¤ã„ã¦ã„ã¾ã›ã‚“" -#: utils/adt/formatting.c:1062 +#: utils/adt/formatting.c:1059 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "\"EEEE\" ã¯æœ€çµ‚パターンã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/formatting.c:1070 +#: utils/adt/formatting.c:1067 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "\"9\"ã¯\"PR\"ã®å‰ã«ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/formatting.c:1086 +#: utils/adt/formatting.c:1083 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "\"0\"ã¯\"PR\"ã®å‰ã«ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/formatting.c:1113 +#: utils/adt/formatting.c:1110 #, c-format msgid "multiple decimal points" msgstr "複数ã®å°æ•°ç‚¹ãŒã‚りã¾ã™" -#: utils/adt/formatting.c:1117 utils/adt/formatting.c:1200 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "\"V\"ã¨å°æ•°ç‚¹ã‚’混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1129 +#: utils/adt/formatting.c:1126 #, c-format msgid "cannot use \"S\" twice" -msgstr "\"S\" ã¯ï¼‘回ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgstr "\"S\" ã¯1回ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1133 +#: utils/adt/formatting.c:1130 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "\"S\"ã¨\"PL\"/\"MI\"/\"SG\"/\"PR\"を混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1153 +#: utils/adt/formatting.c:1150 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "\"S\"ã¨\"MI\"を混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1163 +#: utils/adt/formatting.c:1160 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "\"S\"ã¨\"PL\"を混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1173 +#: utils/adt/formatting.c:1170 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "\"S\"ã¨\"SG\"を混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1182 +#: utils/adt/formatting.c:1179 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "\"PR\"ã¨\"S\"/\"PL\"/\"MI\"/\"SG\"を混在ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1208 +#: utils/adt/formatting.c:1205 #, c-format msgid "cannot use \"EEEE\" twice" -msgstr "\"EEEE\" ã¯ï¼‘回ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“" +msgstr "\"EEEE\" ã¯1回ã—ã‹ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:1214 +#: utils/adt/formatting.c:1211 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "\"EEEE\" ãŒä»–ã®ãƒ•ォーマットã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“。" -#: utils/adt/formatting.c:1215 +#: utils/adt/formatting.c:1212 #, c-format msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "\"EEEE\" ã¯æ•°å€¤ã¾ãŸã¯å°æ•°ç‚¹ãƒ‘ターンã¨å…±ã«æŒ‡å®šã—ã¦ãã ã•ã„。" -#: utils/adt/formatting.c:1415 +#: utils/adt/formatting.c:1392 #, c-format msgid "\"%s\" is not a number" msgstr "\"%s\"ã¯æ•°å€¤ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/formatting.c:1516 utils/adt/formatting.c:1568 +#: utils/adt/formatting.c:1470 +#, c-format +msgid "case conversion failed: %s" +msgstr "文字ケースã®å¤‰æ›ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: utils/adt/formatting.c:1535 #, c-format msgid "could not determine which collation to use for lower() function" msgstr "lower() 関数ã«å¯¾ã—ã¦ã©ã®ç…§åˆé †åºã‚’é©ç”¨ã™ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/formatting.c:1636 utils/adt/formatting.c:1688 +#: utils/adt/formatting.c:1657 #, c-format msgid "could not determine which collation to use for upper() function" msgstr "upper() 関数ã«å¯¾ã—ã¦ã©ã®ç…§åˆé †åºã‚’é©ç”¨ã™ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/formatting.c:1757 utils/adt/formatting.c:1821 +#: utils/adt/formatting.c:1780 #, c-format msgid "could not determine which collation to use for initcap() function" msgstr "initcap() 関数ã«å¯¾ã—ã¦ã©ã®ç…§åˆé †åºã‚’é©ç”¨ã™ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/formatting.c:2125 +#: utils/adt/formatting.c:2148 #, c-format msgid "invalid combination of date conventions" -msgstr "日付表ç¾ã®çµ„ã¿åˆã‚ã›ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªæš¦æ³•ã®çµ„ã¿åˆã‚ã›" -#: utils/adt/formatting.c:2126 +#: utils/adt/formatting.c:2149 #, c-format msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." -msgstr "書å¼ãƒ†ãƒ³ãƒ—レートã®ä¸­ã§ã¯ã€ã‚°ãƒ¬ã‚´ãƒªã‚¢æš¦ã¨ ISO ã®é€±æ—¥è¡¨ç¾ã‚’混在ã•ã›ã¦ã¯ãªã‚Šã¾ã›ã‚“。" +msgstr "å˜ä¸€ã®æ›¸å¼ãƒ†ãƒ³ãƒ—レートã®ä¸­ã§ã¯ã€ã‚°ãƒ¬ã‚´ãƒªã‚ªæš¦ã¨ISO歴週日付を混在ã•ã›ãªã„ã§ãã ã•ã„。" -#: utils/adt/formatting.c:2143 +#: utils/adt/formatting.c:2166 #, c-format msgid "conflicting values for \"%s\" field in formatting string" -msgstr "\"%s\" フィールドã®å€¤ã¨æ›¸å¼æ–‡å­—列ãŒç«¶åˆã—ã¦ã„ã¾ã™" +msgstr "æ›¸å¼æ–‡å­—列中ã§\"%s\"フィールドã®å€¤ãŒè¡çªã—ã¦ã„ã¾ã™" -#: utils/adt/formatting.c:2145 +#: utils/adt/formatting.c:2168 #, c-format msgid "This value contradicts a previous setting for the same field type." -msgstr "ã“ã®å€¤ã‚’åŒã˜ãƒ•ィールド型ã«ã™ã‚‹ã«ã‚ãŸã‚Šã€ç›´å‰ã®è¨­å®šã¨çŸ›ç›¾ã—ã¦ã„ã¾ã™" +msgstr "ã“ã®å€¤ã¯åŒã˜ãƒ•ィールド型ã«å¯¾ã™ã‚‹ä»¥å‰ã®è¨­å®šã¨çŸ›ç›¾ã—ã¦ã„ã¾ã™" -#: utils/adt/formatting.c:2206 +#: utils/adt/formatting.c:2229 #, c-format msgid "source string too short for \"%s\" formatting field" -msgstr "書å¼ãƒ•ィールド \"%s\" ã§ã€å…ƒã®æ–‡å­—列ãŒçŸ­ã™ãŽã¾ã™" +msgstr "書å¼ãƒ•ィールド\"%s\"ã«å¯¾ã—ã¦å…ƒã®æ–‡å­—列ãŒçŸ­ã™ãŽã¾ã™" -#: utils/adt/formatting.c:2208 +#: utils/adt/formatting.c:2231 #, c-format msgid "Field requires %d characters, but only %d remain." -msgstr "フィールドã«ã¯ %d 文字必è¦ã§ã™ãŒã€%d 文字ã—ã‹æ®‹ã£ã¦ã„ã¾ã›ã‚“" +msgstr "フィールドã«ã¯%d文字必è¦ã§ã™ãŒã€%d文字ã—ã‹æ®‹ã£ã¦ã„ã¾ã›ã‚“。" -#: utils/adt/formatting.c:2211 utils/adt/formatting.c:2225 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format msgid "If your source string is not fixed-width, try using the \"FM\" modifier." -msgstr "å…ƒã®æ–‡å­—列ãŒå›ºå®šé•·ã§ãªã„å ´åˆã¯ã€ä¿®é£¾å­ \"FM\" を試ã—ã¦ã¿ã¦ãã ã•ã„" +msgstr "å…ƒã®æ–‡å­—列ãŒå›ºå®šé•·ã§ãªã„å ´åˆã¯ã€ä¿®é£¾å­ \"FM\" を試ã—ã¦ã¿ã¦ãã ã•ã„。" -#: utils/adt/formatting.c:2221 utils/adt/formatting.c:2234 -#: utils/adt/formatting.c:2364 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 +#: utils/adt/formatting.c:2387 #, c-format msgid "invalid value \"%s\" for \"%s\"" -msgstr " \"%2$s\" ã¸ã‚»ãƒƒãƒˆã™ã‚‹ãŸã‚ã®å€¤ \"%1$s\" ãŒç„¡åйã§ã™" +msgstr "\"%2$s\"ã«å¯¾ã™ã‚‹ä¸æ­£ãªå€¤\"%1$s\"" -#: utils/adt/formatting.c:2223 +#: utils/adt/formatting.c:2246 #, c-format msgid "Field requires %d characters, but only %d could be parsed." -msgstr "ã“ã®ãƒ•ィールドã«ã¯ %d 文字必è¦ã§ã™ãŒã€%d 文字ã—ã‹æ¤œå‡ºã•れã¾ã›ã‚“ã§ã—ãŸã€‚" +msgstr "ã“ã®ãƒ•ィールドã«ã¯%d文字必è¦ã§ã™ãŒã€%d文字ã—ã‹ãƒ‘ースã•れã¾ã›ã‚“ã§ã—ãŸã€‚" -#: utils/adt/formatting.c:2236 +#: utils/adt/formatting.c:2259 #, c-format msgid "Value must be an integer." -msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ—ãƒ­ã‚·ãƒ¼ã‚¸ãƒ£ã¯æ•´æ•°ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "å€¤ã¯æ•´æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/formatting.c:2241 +#: utils/adt/formatting.c:2264 #, c-format msgid "value for \"%s\" in source string is out of range" -msgstr "ã‚‚ã¨ã®æ–‡å­—列ã«ãŠã„㦠\"%s\" ã®ãŸã‚ã®å€¤ãŒç¯„囲外ã§ã™" +msgstr "ã‚‚ã¨ã®æ–‡å­—列ã«ãŠã„ã¦\"%s\"ã«å¯¾å¿œã™ã‚‹å€¤ãŒç¯„囲外ã§ã™" -#: utils/adt/formatting.c:2243 +#: utils/adt/formatting.c:2266 #, c-format msgid "Value must be in the range %d to %d." -msgstr "値㯠%d ã‹ã‚‰ %d ã¾ã§ã®ç¯„囲ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" +msgstr "値ã¯%dã‹ã‚‰%dã¾ã§ã®ç¯„囲ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/formatting.c:2366 +#: utils/adt/formatting.c:2389 #, c-format msgid "The given value did not match any of the allowed values for this field." -msgstr "与ãˆã‚‰ã‚ŒãŸå€¤ãŒã“ã®é …ç›®ã«å¯¾ã—ã¦è¨±ã•れるã„ãšã‚Œã®å€¤ã¨ã‚‚マッãƒã—ã¾ã›ã‚“" +msgstr "与ãˆã‚‰ã‚ŒãŸå€¤ãŒã“ã®é …ç›®ã«å¯¾ã—ã¦è¨±ã•れるã„ãšã‚Œã®å€¤ã¨ã‚‚マッãƒã—ã¾ã›ã‚“。" + +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 +#: utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 +#: utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 +#: utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 +#: utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 +#: utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 +#, c-format +msgid "localized string format value too long" +msgstr "地域化ã—ãŸæ–‡å­—列ã®ãƒ•ォーマットãŒé•·ã™ãŽã¾ã™" -#: utils/adt/formatting.c:2933 +#: utils/adt/formatting.c:3084 #, c-format -#| msgid "\"TZ\"/\"tz\" format patterns are not supported in to_date" -msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" -msgstr "to_date ã§ã¯ \"TZ\"/\"tz\"/\"OF\" å½¢å¼ã®ãƒ‘ターンをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "形弿Œ‡å®šãƒ•ィールド\"%s\"ã¯to_charã®ä¸­ã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" -#: utils/adt/formatting.c:3041 +#: utils/adt/formatting.c:3209 #, c-format msgid "invalid input string for \"Y,YYY\"" -msgstr " \"Y,YYY\" ã«ã‚»ãƒƒãƒˆã™ã‚‹ãŸã‚ã®å…¥åŠ›æ–‡å­—åˆ—ãŒæœ‰åйã§ã¯ã‚りã¾ã›ã‚“" +msgstr " \"Y,YYY\"ã«å¯¾å¿œã™ã‚‹å…¥åŠ›æ–‡å­—åˆ—ãŒä¸æ­£ã§ã™" -#: utils/adt/formatting.c:3544 +#: utils/adt/formatting.c:3724 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" -msgstr "12時間形å¼ã§ã¯ \"%d\" 時ã¯ç„¡åйã§ã™" +msgstr "12時間形å¼ã§ã¯\"%d\"時ã¯ä¸æ­£ã§ã™" -#: utils/adt/formatting.c:3546 +#: utils/adt/formatting.c:3726 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." -msgstr "24時間形å¼ã‚’使ã†ã‹ã€ã‚‚ã—ã㯠1 ã‹ã‚‰ 12 ã®é–“ã§æŒ‡å®šã—ã¦ãã ã•ã„" +msgstr "24時間形å¼ã‚’使ã†ã‹ã€ã‚‚ã—ã㯠1 ã‹ã‚‰ 12 ã®é–“ã§æŒ‡å®šã—ã¦ãã ã•ã„。" -#: utils/adt/formatting.c:3641 +#: utils/adt/formatting.c:3832 #, c-format msgid "cannot calculate day of year without year information" -msgstr "å¹´ã®æƒ…å ±ãªã—ã§ã¯å¹´å†…日数を計算ã§ãã¾ã›ã‚“" +msgstr "å¹´ã®æƒ…å ±ãªã—ã§ã¯å¹´å†…ã®æ—¥æ•°ã¯è¨ˆç®—ã§ãã¾ã›ã‚“" -#: utils/adt/formatting.c:4491 +#: utils/adt/formatting.c:4737 #, c-format msgid "\"EEEE\" not supported for input" -msgstr "\"EEEE\" ã¯å…¥åŠ›ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "\"EEEE\" ã¯å…¥åŠ›ã¨ã—ã¦ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: utils/adt/formatting.c:4503 +#: utils/adt/formatting.c:4749 #, c-format msgid "\"RN\" not supported for input" -msgstr "\"RN\" ã¯å…¥åŠ›ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "\"RN\" ã¯å…¥åŠ›ã¨ã—ã¦ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: utils/adt/genfile.c:61 +#: utils/adt/genfile.c:79 #, c-format msgid "reference to parent directory (\"..\") not allowed" -msgstr "親ディレクトリã®å‚照(\"..\")ã¯ã§ãã¾ã›ã‚“" +msgstr "親ディレクトリã¸ã®å‚照(\"..\")ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/genfile.c:72 +#: utils/adt/genfile.c:90 #, c-format msgid "absolute path not allowed" -msgstr "絶対経路ã¯ã§ãã¾ã›ã‚“" +msgstr "絶対パスã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/genfile.c:77 +#: utils/adt/genfile.c:95 #, c-format msgid "path must be in or below the current directory" -msgstr "パスã¯ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚‚ã—ãã¯ãã®é…下ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "パスã¯ã‚«ãƒ¬ãƒ³ãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚‚ã—ãã¯ãã®ä¸‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/genfile.c:118 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1048 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "è¦æ±‚ã—ãŸé•·ã•ãŒé•·ã™ãŽã¾ã™" -#: utils/adt/genfile.c:130 +#: utils/adt/genfile.c:159 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "ファイル\"%s\"をシークã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/adt/genfile.c:180 utils/adt/genfile.c:204 utils/adt/genfile.c:225 -#: utils/adt/genfile.c:249 +#: utils/adt/genfile.c:219 #, c-format -msgid "must be superuser to read files" -msgstr "ファイルを読ã¿è¾¼ã‚€ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "adminpack 1.0 ã§ãƒ•ァイルを読ã¿è¾¼ã‚€ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/adt/genfile.c:187 utils/adt/genfile.c:232 +#: utils/adt/genfile.c:220 #, c-format -msgid "requested length cannot be negative" -msgstr "è² ã®é•·ã•を指定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "代ã‚りã«ã‚³ã‚¢ã®ä¸€éƒ¨ã§ã‚ã‚‹ pg_file_read() 使用を検討ã—ã¦ãã ã•ã„" -#: utils/adt/genfile.c:273 +#: utils/adt/geo_ops.c:939 #, c-format -msgid "must be superuser to get file information" -msgstr "ファイル情報を入手ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "invalid line specification: A and B cannot both be zero" +msgstr "䏿­£ãªç›´ç·šã®æŒ‡å®š: Aã¨Bã¯åŒæ™‚ã«0ã«ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/genfile.c:337 +#: utils/adt/geo_ops.c:947 #, c-format -msgid "must be superuser to get directory listings" -msgstr "ディレクトリ一覧を得るã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "invalid line specification: must be two distinct points" +msgstr "䏿­£ãªç›´ç·šã®æŒ‡å®š: 2ã¤ã®ç‚¹ã¯ç•°ãªã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/adt/geo_ops.c:296 utils/adt/geo_ops.c:4248 utils/adt/geo_ops.c:5169 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 +#: utils/adt/geo_ops.c:5180 #, c-format msgid "too many points requested" -msgstr "è¦æ±‚ã•れãŸãƒã‚¤ãƒ³ãƒˆãŒå¤šã™ãŽã¾ã™" - -#: utils/adt/geo_ops.c:319 -#, c-format -msgid "could not format \"path\" value" -msgstr "\"path\"ã®å€¤ã‚’æ•´å½¢ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: utils/adt/geo_ops.c:394 -#, c-format -msgid "invalid input syntax for type box: \"%s\"" -msgstr "åž‹boxã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/geo_ops.c:953 -#, c-format -msgid "invalid input syntax for type line: \"%s\"" -msgstr "åž‹lineã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgstr "è¦æ±‚ã•れãŸç‚¹ãŒå¤šã™ãŽã¾ã™" -#: utils/adt/geo_ops.c:960 utils/adt/geo_ops.c:1027 utils/adt/geo_ops.c:1042 -#: utils/adt/geo_ops.c:1054 -#, c-format -msgid "type \"line\" not yet implemented" -msgstr "åž‹\"line\"ã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" - -#: utils/adt/geo_ops.c:1408 utils/adt/geo_ops.c:1431 -#, c-format -msgid "invalid input syntax for type path: \"%s\"" -msgstr "åž‹pathã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/geo_ops.c:1470 +#: utils/adt/geo_ops.c:1403 #, c-format msgid "invalid number of points in external \"path\" value" -msgstr "\"path\"ã®å¤–部値ã«ãŠã‘ã‚‹ãƒã‚¤ãƒ³ãƒˆæ•°ãŒç„¡åйã§ã™" - -#: utils/adt/geo_ops.c:1813 -#, c-format -msgid "invalid input syntax for type point: \"%s\"" -msgstr "åž‹pointã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/geo_ops.c:2041 -#, c-format -msgid "invalid input syntax for type lseg: \"%s\"" -msgstr "åž‹lsegã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgstr "\"path\"ã®å¤–部値ã«ãŠã‘ã‚‹ç‚¹ã®æ•°ãŒä¸æ­£ã§ã™" -#: utils/adt/geo_ops.c:2645 +#: utils/adt/geo_ops.c:2554 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "関数\"dist_lb\"ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/geo_ops.c:3158 +#: utils/adt/geo_ops.c:3014 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "関数\"close_sl\"ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: utils/adt/geo_ops.c:3116 #, c-format msgid "function \"close_lb\" not implemented" msgstr "関数\"close_lb\"ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/geo_ops.c:3447 +#: utils/adt/geo_ops.c:3405 #, c-format msgid "cannot create bounding box for empty polygon" msgstr "空ã®å¤šè§’å½¢ã«å¯¾ã™ã‚‹å¢ƒç•ŒçŸ©å½¢ã‚’作æˆã§ãã¾ã›ã‚“" -#: utils/adt/geo_ops.c:3471 utils/adt/geo_ops.c:3483 -#, c-format -msgid "invalid input syntax for type polygon: \"%s\"" -msgstr "åž‹polygonã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/geo_ops.c:3523 +#: utils/adt/geo_ops.c:3486 #, c-format msgid "invalid number of points in external \"polygon\" value" -msgstr "\"polygon\"ã®å¤–部値ã®ãƒã‚¤ãƒ³ãƒˆæ•°ãŒç„¡åйã§ã™" +msgstr "\"polygon\"ã®å¤–部値ã®ç‚¹ã®æ•°ãŒä¸æ­£ã§ã™" -#: utils/adt/geo_ops.c:4046 +#: utils/adt/geo_ops.c:4011 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "関数\"poly_distance\"ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/geo_ops.c:4360 +#: utils/adt/geo_ops.c:4364 #, c-format msgid "function \"path_center\" not implemented" msgstr "関数\"path_center\"ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/geo_ops.c:4377 +#: utils/adt/geo_ops.c:4381 #, c-format msgid "open path cannot be converted to polygon" msgstr "開経路を多角形ã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/geo_ops.c:4546 utils/adt/geo_ops.c:4556 utils/adt/geo_ops.c:4571 -#: utils/adt/geo_ops.c:4577 -#, c-format -msgid "invalid input syntax for type circle: \"%s\"" -msgstr "åž‹circleã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/geo_ops.c:4599 utils/adt/geo_ops.c:4607 -#, c-format -msgid "could not format \"circle\" value" -msgstr "\"circle\"値を整形ã§ãã¾ã›ã‚“" - -#: utils/adt/geo_ops.c:4634 +#: utils/adt/geo_ops.c:4630 #, c-format msgid "invalid radius in external \"circle\" value" -msgstr "\"circle\"ã®å¤–部値ã®åŠå¾„ãŒç„¡åйã§ã™" +msgstr "\"circle\"ã®å¤–部値ã®åŠå¾„ãŒä¸æ­£ã§ã™" -#: utils/adt/geo_ops.c:5155 +#: utils/adt/geo_ops.c:5166 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "åŠå¾„0ã®å††ã‚’多角形ã«è¿”é‚„ã§ãã¾ã›ã‚“" -#: utils/adt/geo_ops.c:5160 +#: utils/adt/geo_ops.c:5171 #, c-format msgid "must request at least 2 points" msgstr "å°‘ãªãã¨ã‚‚2ãƒã‚¤ãƒ³ãƒˆã‚’è¦æ±‚ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/geo_ops.c:5204 utils/adt/geo_ops.c:5227 +#: utils/adt/geo_ops.c:5215 #, c-format msgid "cannot convert empty polygon to circle" msgstr "空ã®å¤šè§’形を円ã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/int.c:162 +#: utils/adt/int.c:160 #, c-format msgid "int2vector has too many elements" msgstr "int2vectorã®è¦ç´ æ•°ãŒå¤šã™ãŽã¾ã™" -#: utils/adt/int.c:237 +#: utils/adt/int.c:235 #, c-format msgid "invalid int2vector data" -msgstr "int2vectorデータãŒç„¡åйã§ã™" +msgstr "䏿­£ãªint2vectorデータ" -#: utils/adt/int.c:243 utils/adt/oid.c:212 utils/adt/oid.c:293 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "oidvectorã®è¦ç´ ãŒå¤šã™ãŽã¾ã™" -#: utils/adt/int.c:1362 utils/adt/int8.c:1409 utils/adt/timestamp.c:4845 -#: utils/adt/timestamp.c:4926 +#: utils/adt/int.c:1379 utils/adt/int8.c:1325 utils/adt/numeric.c:1412 +#: utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5402 #, c-format msgid "step size cannot equal zero" msgstr "ステップ数をゼロã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:103 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 +#: utils/adt/numutils.c:105 #, c-format msgid "invalid input syntax for integer: \"%s\"" -msgstr "åž‹integerã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/int8.c:114 -#, c-format -msgid "value \"%s\" is out of range for type bigint" -msgstr "値\"%s\"ã¯åž‹bigintã®ç¯„囲外ã§ã™" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:783 -#: utils/adt/int8.c:804 utils/adt/int8.c:831 utils/adt/int8.c:864 -#: utils/adt/int8.c:892 utils/adt/int8.c:913 utils/adt/int8.c:940 -#: utils/adt/int8.c:980 utils/adt/int8.c:1001 utils/adt/int8.c:1028 -#: utils/adt/int8.c:1061 utils/adt/int8.c:1089 utils/adt/int8.c:1110 -#: utils/adt/int8.c:1137 utils/adt/int8.c:1310 utils/adt/int8.c:1349 -#: utils/adt/numeric.c:2294 utils/adt/varbit.c:1617 +msgstr "integerã«å¯¾ã™ã‚‹ä¸æ­£ãªå…¥åŠ›æ§‹æ–‡: \"%s\"" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 +#: utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 +#: utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 +#: utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 +#: utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 +#: utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 +#: utils/adt/int8.c:1227 utils/adt/int8.c:1269 utils/adt/numeric.c:3169 +#: utils/adt/varbit.c:1655 #, c-format msgid "bigint out of range" msgstr "bigintã®ç¯„囲外ã§ã™" -#: utils/adt/int8.c:1366 +#: utils/adt/int8.c:1282 #, c-format msgid "OID out of range" msgstr "OIDã®ç¯„囲外ã§ã™" -#: utils/adt/json.c:675 utils/adt/json.c:715 utils/adt/json.c:730 -#: utils/adt/json.c:741 utils/adt/json.c:751 utils/adt/json.c:785 -#: utils/adt/json.c:797 utils/adt/json.c:828 utils/adt/json.c:846 -#: utils/adt/json.c:858 utils/adt/json.c:870 utils/adt/json.c:1000 -#: utils/adt/json.c:1014 utils/adt/json.c:1025 utils/adt/json.c:1033 -#: utils/adt/json.c:1041 utils/adt/json.c:1049 utils/adt/json.c:1057 -#: utils/adt/json.c:1065 utils/adt/json.c:1073 utils/adt/json.c:1081 -#: utils/adt/json.c:1111 -#, c-format -msgid "invalid input syntax for type json" -msgstr "jsonåž‹ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™" - -#: utils/adt/json.c:676 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "0x%02x値をæŒã¤æ–‡å­—ã¯ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/json.c:716 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." -msgstr "\"\\u\"ã®å¾Œã«ã¯16進数ã®ï¼”æ¡ãŒç¶šã‹ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "\"\\u\"ã®å¾Œã«ã¯16進数ã®4æ¡ãŒç¶šã‹ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/json.c:731 +#: utils/adt/json.c:844 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Unicodeã®ãƒã‚¤ã‚µãƒ­ã‚²ãƒ¼ãƒˆã¯ãƒã‚¤ã‚µãƒ­ã‚²ãƒ¼ãƒˆã«ç¶šã„ã¦ã¯ã„ã‘ã¾ã›ã‚“。" -#: utils/adt/json.c:742 utils/adt/json.c:752 utils/adt/json.c:798 -#: utils/adt/json.c:859 utils/adt/json.c:871 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Unicodeã®ãƒ­ãƒ¼ã‚µãƒ­ã‚²ãƒ¼ãƒˆã¯ãƒã‚¤ã‚µãƒ­ã‚²ãƒ¼ãƒˆã«ç¶šã‹ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/json.c:786 +#: utils/adt/json.c:880 utils/adt/json.c:903 +#, c-format +msgid "unsupported Unicode escape sequence" +msgstr "サãƒãƒ¼ãƒˆã•れãªã„Unicodeエスケープシーケンス" + +#: utils/adt/json.c:881 +#, c-format +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 ã¯ãƒ†ã‚­ã‚¹ãƒˆã«å¤‰æ›ã§ãã¾ã›ã‚“。" + +#: utils/adt/json.c:904 #, c-format -#| msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." -msgstr "サーãƒãƒ¼ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãŒ UTF-8 ã§ã¯ãªã„å ´åˆã€ã‚³ãƒ¼ãƒ‰ãƒã‚¤ãƒ³ãƒˆã®å€¤ãŒ 007F 以上ã«ã¤ã„ã¦ã¯ Unicode ã®ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—値ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。" +msgstr "サーãƒãƒ¼ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãŒUTF-8ã§ã¯ãªã„å ´åˆã€ã‚³ãƒ¼ãƒ‰ãƒã‚¤ãƒ³ãƒˆã®å€¤ãŒ 007F 以上ã«ã¤ã„ã¦ã¯Unicodeエスケープã®å€¤ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。" -#: utils/adt/json.c:829 utils/adt/json.c:847 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." -msgstr "エスケープシーケンス\"\\%s\" ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“" +msgstr "エスケープシーケンス\"\\%s\"ã¯ä¸æ­£ã§ã™ã€‚" -#: utils/adt/json.c:1001 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." -msgstr "å…¥åŠ›æ–‡å­—åˆ—ãŒæ„図ã›ãšçµ‚了ã—ã¾ã—ãŸ" +msgstr "入力文字列ãŒäºˆæœŸã›ãšçµ‚了ã—ã¾ã—ãŸã€‚" -#: utils/adt/json.c:1015 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." -msgstr "想定ã§ã¯å…¥åŠ›ã®çµ‚端ã€çµæžœã¯\"%s\"" +msgstr "入力ã®çµ‚端を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1026 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." -msgstr "想定ã§ã¯JSON値ã€çµæžœã§ã¯\"%s\"" +msgstr "JSON値を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1034 utils/adt/json.c:1082 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." -msgstr "想定ã§ã¯æ–‡å­—列ã€çµæžœã§ã¯\"%s\"" +msgstr "文字列を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1042 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." -msgstr "想定ã§ã¯é…列è¦ç´ ã¾ãŸã¯\"]\"ã€çµæžœã§ã¯\"%s\"" +msgstr "é…列è¦ç´ ã¾ãŸã¯\"]\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1050 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." -msgstr "想定ã§ã¯\",\"ã¾ãŸã¯\"]\"ã€çµæžœã§ã¯\"%s\"" +msgstr "\",\"ã¾ãŸã¯\"]\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1058 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." -msgstr "想定ã§ã¯æ–‡å­—列ã¾ãŸã¯\"}\"ã€çµæžœã§ã¯\"%s\"" +msgstr "文字列ã¾ãŸã¯\"}\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1066 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." -msgstr "想定ã§ã¯\":\"ã€çµæžœã§ã¯\"%s\"" +msgstr "\":\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1074 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." -msgstr "想定ã§ã¯\",\"ã¾ãŸã¯\"}\"ã€çµæžœã§ã¯\"%s\"" +msgstr "\",\"ã¾ãŸã¯\"}\"を想定ã—ã¦ã„ã¾ã—ãŸãŒã€\"%s\"ã§ã—ãŸã€‚" -#: utils/adt/json.c:1112 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." -msgstr "トークン\"%s\"ã¯æœ‰åйã§ã¯ã‚りã¾ã›ã‚“" +msgstr "トークン\"%s\"ã¯ä¸æ­£ã§ã™ã€‚" -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" -msgstr "JSONデータã€%d行: %s%s%s" +msgstr "JSONデータã€%d行目: %s%s%s" -#: utils/adt/jsonfuncs.c:323 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format -msgid "cannot call json_object_keys on an array" -msgstr "é…列ã«å¯¾ã—ã¦json_object_keysを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "key value must be scalar, not array, composite, or json" +msgstr "キー値ã¯é…列ã§ã‚‚複åˆåž‹ã§ã‚‚JSONã§ã‚‚ãªãã€ã‚¹ã‚«ãƒ©ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:335 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format -msgid "cannot call json_object_keys on a scalar" -msgstr "スカラã«å¯¾ã—ã¦json_object_keysを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "could not determine data type for argument %d" +msgstr "引数%dã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒç¢ºå®šã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/jsonfuncs.c:440 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format -msgid "cannot call function with null path elements" -msgstr "パスè¦ç´ ãŒNULLã§é–¢æ•°ã‚’呼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "field name must not be null" +msgstr "フィールドåã¯nullã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:457 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format -msgid "cannot call function with empty path elements" -msgstr "パスè¦ç´ ãŒç©ºã§é–¢æ•°ã‚’呼ã³å‡ºã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgid "argument list must have even number of elements" +msgstr "引数リストã®è¦ç´ æ•°ã¯å¶æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:569 +#: utils/adt/json.c:2195 #, c-format -#| msgid "cannot set an array element to DEFAULT" -msgid "cannot extract array element from a non-array" -msgstr "éžé…列ã‹ã‚‰é…列è¦ç´ ã‚’å–り出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "The arguments of json_build_object() must consist of alternating keys and values." +msgstr "json_build_object()ã®å¼•æ•°ã§ã¯ã‚­ãƒ¼ã¨å€¤ãŒäº¤äº’ã«ãªã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/jsonfuncs.c:684 +#: utils/adt/json.c:2210 #, c-format -msgid "cannot extract field from a non-object" -msgstr "éžã‚ªãƒ–ジェクトã‹ã‚‰ãƒ•ィールドをå–り出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "argument %d cannot be null" +msgstr "引数%dã¯nullã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:800 +#: utils/adt/json.c:2211 #, c-format -#| msgid "cannot export a snapshot from a subtransaction" -msgid "cannot extract element from a scalar" -msgstr "スカラã‹ã‚‰è¦ç´ ã‚’å–り出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "Object keys should be text." +msgstr "オブジェクトキーã¯ãƒ†ã‚­ã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/jsonfuncs.c:856 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format -#| msgid "cannot accept a value of type anynonarray" -msgid "cannot get array length of a non-array" -msgstr "éžé…列ã‹ã‚‰é…列長を得るã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "array must have two columns" +msgstr "é…åˆ—ã¯æœ€ä½Žã§ã‚‚2ã¤ã®åˆ—ãŒå¿…è¦ã§ã™" + +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 +#: utils/adt/jsonb.c:1395 +#, c-format +msgid "null value not allowed for object key" +msgstr "オブジェクトキーã«nullã¯ä½¿ãˆã¾ã›ã‚“" + +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 +#, c-format +msgid "mismatched array dimensions" +msgstr "é…åˆ—ã®æ¬¡å…ƒãŒåˆã£ã¦ã„ã¾ã›ã‚“" + +#: utils/adt/jsonb.c:258 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "文字列ã¯jsonb文字列ã¨ã—ã¦è¡¨ç¾ã™ã‚‹ã«ã¯é•·ã™ãŽã¾ã™" + +#: utils/adt/jsonb.c:259 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "実装上ã®åˆ¶ç´„ã®ãŸã‚ã€jsonb文字列ã¯%dãƒã‚¤ãƒˆã¾ã§ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: utils/adt/jsonb.c:1147 +#, c-format +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "jsonb_build_object()ã®å¼•æ•°ã§ã¯ã‚­ãƒ¼ã¨å€¤ãŒäº¤äº’ã«ãªã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" + +#: utils/adt/jsonb.c:1159 +#, c-format +msgid "argument %d: key must not be null" +msgstr "引数%d: キーã¯nullã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1747 +#, c-format +msgid "object keys must be strings" +msgstr "オブエクã¨ã‚­ãƒ¼ã¯æ–‡å­—列ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: utils/adt/jsonb.c:1910 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "jsonb null ã¯%såž‹ã«ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1911 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "jsonb文字列ã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1912 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "jsonb numericã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1913 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "jsonbブール型ã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1914 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "jsonbé…列ã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1915 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "jsonbオブジェクトã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb.c:1916 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "jsonbã®é…列ã¾ãŸã¯ã‚ªãƒ–ジェクトã¯%såž‹ã¸ã¯ã‚­ãƒ£ã‚¹ãƒˆã§ãã¾ã›ã‚“" + +#: utils/adt/jsonb_util.c:657 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "jsonbオブジェクトペア数ãŒè¨±ã•ã‚ŒãŸæœ€å¤§ã®å€¤(%zu)を上回ã£ã¦ã„ã¾ã™" + +#: utils/adt/jsonb_util.c:698 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "jsonbã®é…列è¦ç´ ã®æ•°ãŒè¨±ã•ã‚ŒãŸæœ€å¤§ã®å€¤(%zu)を上回ã£ã¦ã„ã¾ã™" + +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "jsonbã®é…列è¦ç´ ã®å…¨ä½“ã®å¤§ãã•ãŒè¨±ã•ã‚ŒãŸæœ€å¤§å€¤%uãƒã‚¤ãƒˆã‚’上回ã£ã¦ã„ã¾ã™" + +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "jsonbã®ã‚ªãƒ–ジェクトè¦ç´ å…¨ä½“ã®ã‚µã‚¤ã‚ºãŒæœ€å¤§å€¤ã§ã‚ã‚‹%uã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "スカラã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 +#, c-format +msgid "cannot call %s on an array" +msgstr "é…列ã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:868 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format -#| msgid "cannot set an array element to DEFAULT" msgid "cannot get array length of a scalar" msgstr "スカラã‹ã‚‰é…列長を得るã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1044 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "é…列ã§ã¯ç„¡ã„ã‚‚ã®ã‹ã‚‰ã‹ã‚‰é…列長を得るã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:1691 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "éžã‚ªãƒ–ジェクトã«å¯¾ã—ã¦%sã¯å‘¼ã³å‡ºã›ã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "レコード型をå—ã‘付ã‘られãªã„コンテキストã§ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã³å‡ºã•れã¾ã—ãŸ" + +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "é…列をオブジェクトã¨ã—ã¦å†æ§‹ç¯‰ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1056 +#: utils/adt/jsonfuncs.c:1961 #, c-format -#| msgid "cannot convert NaN to smallint" msgid "cannot deconstruct a scalar" msgstr "ã‚¹ã‚«ãƒ©ã‚’å†æ§‹ç¯‰ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1185 +#: utils/adt/jsonfuncs.c:2007 #, c-format -msgid "cannot call json_array_elements on a non-array" -msgstr "éžé…列ã«å¯¾ã—ã¦json_array_elementsを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "cannot extract elements from a scalar" +msgstr "スカラã‹ã‚‰è¦ç´ ã‚’å–り出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1197 +#: utils/adt/jsonfuncs.c:2011 #, c-format -msgid "cannot call json_array_elements on a scalar" -msgstr "スカラã«å¯¾ã—ã¦json_array_elementsを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "cannot extract elements from an object" +msgstr "オブジェクトã‹ã‚‰è¦ç´ ã‚’å–り出ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1242 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format -#| msgid "argument of %s must be a type name" -msgid "first argument of json_populate_record must be a row type" -msgstr "json_populate_recordã®æœ€åˆã®å¼•æ•°ã¯è¡Œåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "cannot call %s on a non-array" +msgstr "éžé…列ã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1472 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 #, c-format -msgid "cannot call %s on a nested object" -msgstr "入れå­ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "expected JSON array" +msgstr "JSONé…列を期待ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/jsonfuncs.c:1533 +#: utils/adt/jsonfuncs.c:2334 #, c-format -#| msgid "cannot accept a value of type anyarray" -msgid "cannot call %s on an array" -msgstr "é…列ã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "See the value of key \"%s\"." +msgstr "キー\"%s\"ã®å€¤ã‚’見ã¦ãã ã•ã„。" -#: utils/adt/jsonfuncs.c:1544 +#: utils/adt/jsonfuncs.c:2356 #, c-format -#| msgid "cannot cast type %s to %s" -msgid "cannot call %s on a scalar" -msgstr "スカラã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "See the array element %s of key \"%s\"." +msgstr "キー\"%s\"ã®é…列è¦ç´ %sを見ã¦ãã ã•ã„。" + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "é…列è¦ç´ %sを見ã¦ãã ã•ã„。" + +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "䏿­£ãªå½¢å¼ã®JSONé…列" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "%sã®æœ€åˆã®å¼•æ•°ã¯è¡Œåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 +#, c-format +msgid "Try calling the function in the FROM clause using a column definition list." +msgstr "FROMå¥ã§åˆ—定義リストを使ã£ã¦ã“ã®é–¢æ•°ã‚’呼ã³å‡ºã—ã¦ã¿ã¦ãã ã•ã„。" + +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "%sã®å¼•æ•°ã¯ã‚ªãƒ–ジェクトé…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:3764 +#, c-format +msgid "cannot call %s on an object" +msgstr "オブジェクトã«å¯¾ã—ã¦%sを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 +#, c-format +msgid "cannot delete from scalar" +msgstr "スカラã‹ã‚‰å‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:4385 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "オブジェクトã‹ã‚‰æ•´æ•°æ·»å­—を使ã£ã¦å‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 +#, c-format +msgid "cannot set path in scalar" +msgstr "スカラã«ãƒ‘スを設定ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:4496 +#, c-format +msgid "cannot delete path in scalar" +msgstr "スカラã§ãƒ‘スを削除ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/jsonfuncs.c:4666 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "jsonbオブジェクト間ã®ä¸æ­£ãªçµåˆ" + +#: utils/adt/jsonfuncs.c:4700 +#, c-format +msgid "path element at position %d is null" +msgstr "ä½ç½®%dã®ãƒ‘スè¦ç´ ãŒnullã§ã™" + +#: utils/adt/jsonfuncs.c:4786 +#, c-format +msgid "cannot replace existing key" +msgstr "既存ã®ã‚­ãƒ¼ã‚’ç½®ãæ›ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1584 +#: utils/adt/jsonfuncs.c:4787 #, c-format -msgid "first argument of json_populate_recordset must be a row type" -msgstr "json_populate_recordsetã®æœ€åˆã®å¼•æ•°ã¯è¡Œåž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "Try using the function jsonb_set to replace key value." +msgstr "jsonb_set関数を使ã£ã¦ã‚­ãƒ¼å€¤ã‚’ç½®ãæ›ãˆã‚‹ã“ã¨ã‚’試ã—ã¦ãã ã•ã„。" -#: utils/adt/jsonfuncs.c:1700 +#: utils/adt/jsonfuncs.c:4869 #, c-format -msgid "cannot call json_populate_recordset on an object" -msgstr "オブジェクトã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "ä½ç½®%dã®ãƒ‘スè¦ç´ ãŒæ•´æ•°ã§ã¯ã‚りã¾ã›ã‚“: \"%s\"" -#: utils/adt/jsonfuncs.c:1704 +#: utils/adt/jsonfuncs.c:4988 #, c-format -msgid "cannot call json_populate_recordset with nested objects" -msgstr "入れå­ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "é–“é•ã£ãŸãƒ•ラグã®ã‚¿ã‚¤ãƒ—ã€é…列ãŠã‚ˆã³ã‚¹ã‚«ãƒ©ã®ã¿è¨±ã•れã¾ã™" -#: utils/adt/jsonfuncs.c:1839 +#: utils/adt/jsonfuncs.c:4995 #, c-format -msgid "must call json_populate_recordset on an array of objects" -msgstr "オブジェクトã®é…列ã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "flag array element is not a string" +msgstr "フラグé…列ã®è¦ç´ ãŒæ–‡å­—列ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/jsonfuncs.c:1850 +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 #, c-format -msgid "cannot call json_populate_recordset with nested arrays" -msgstr "入れå­ã®é…列ã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "使用å¯èƒ½ãªå€¤ã¯: \"string\", \"numeric\", \"boolean\", \"key\"ã€ãŠã‚ˆã³ \"all\"" -#: utils/adt/jsonfuncs.c:1861 +#: utils/adt/jsonfuncs.c:5016 #, c-format -msgid "cannot call json_populate_recordset on a scalar" -msgstr "スカラã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "wrong flag in flag array: \"%s\"" +msgstr "フラグé…列内ã®é–“é•ã£ãŸãƒ•ラグ値: \"%s\"" -#: utils/adt/jsonfuncs.c:1881 +#: utils/adt/levenshtein.c:133 #, c-format -msgid "cannot call json_populate_recordset on a nested object" -msgstr "入れå­ã®ã‚ªãƒ–ジェクトã«å¯¾ã—ã¦json_populate_recordsetを呼ã³å‡ºã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "レーベンシュタインè·é›¢é–¢æ•°ã®å¼•æ•°ã®é•·ã•ãŒä¸Šé™ã®%d文字を超ãˆã¦ã„ã¾ã™" -#: utils/adt/like.c:211 utils/adt/selfuncs.c:5194 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5806 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "ILIKE ã§ä½¿ç”¨ã™ã‚‹ç…§åˆé †åºã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/like_match.c:104 utils/adt/like_match.c:164 +#: utils/adt/like_match.c:107 utils/adt/like_match.c:167 #, c-format msgid "LIKE pattern must not end with escape character" msgstr "LIKE パターンã¯ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字ã§çµ‚ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/like_match.c:289 utils/adt/regexp.c:683 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" -msgstr "エスケープシーケンスãŒç„¡åйã§ã™" +msgstr "䏿­£ãªã‚¨ã‚¹ã‚±ãƒ¼ãƒ—文字列" -#: utils/adt/like_match.c:290 utils/adt/regexp.c:684 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "エスケープ文字ã¯ç©ºã‹1文字ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/mac.c:65 +#: utils/adt/lockfuncs.c:664 #, c-format -msgid "invalid input syntax for type macaddr: \"%s\"" -msgstr "åž‹macaddrã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgid "cannot use advisory locks during a parallel operation" +msgstr "並列処ç†ä¸­ã¯å‹§å‘Šçš„ロックã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" -#: utils/adt/mac.c:72 +#: utils/adt/mac.c:102 #, c-format msgid "invalid octet value in \"macaddr\" value: \"%s\"" -msgstr "\"macaddr\"ã®å€¤ã§ã‚ªã‚¯ãƒ†ãƒƒãƒˆå€¤ãŒç„¡åйã§ã™: \"%s\"" +msgstr "\"macaddr\"ã®å€¤ã§ã®ä¸æ­£ãªã‚ªã‚¯ãƒ†ãƒƒãƒˆå€¤: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8データãŒmacaddråž‹ã«å¤‰æ›ã™ã‚‹ã«ã¯ç¯„囲外ã§ã™" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "å·¦ã‹ã‚‰4ã€5ãƒã‚¤ãƒˆç›®ã«FFã¨FEãŒã‚るアドレスã€å…·ä½“çš„ã«ã¯ xx:xx:xx:ff:fe:xx:xx:xx ã®ã¿ãŒmacaddr8ã‹ã‚‰macaddrã«å¤‰æ›ã§ãã¾ã™ã€‚" -#: utils/adt/misc.c:111 +#: utils/adt/misc.c:239 #, c-format msgid "PID %d is not a PostgreSQL server process" msgstr "PID %dã¯PostgreSQLサーãƒãƒ—ロセスã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/misc.c:154 +#: utils/adt/misc.c:290 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "スーパーユーザã®å•ã„åˆã‚ã›ã‚’キャンセルã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: utils/adt/misc.c:295 #, c-format -msgid "must be superuser or have the same role to cancel queries running in other server processes" -msgstr "ä»–ã®ã‚µãƒ¼ãƒãƒ—ロセスã§å®Ÿè¡Œä¸­ã®å•ã„åˆã‚ã›ã‚’キャンセルã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯åŒã˜ãƒ­ãƒ¼ãƒ«ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "キャンセルã—よã†ã¨ã—ã¦ã„ã‚‹å•ã„åˆã‚ã›ã®ãƒ­ãƒ¼ãƒ«ã¾ãŸã¯pg_signal_backendã®ãƒ¡ãƒ³ãƒã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/adt/misc.c:171 +#: utils/adt/misc.c:314 #, c-format -msgid "must be superuser or have the same role to terminate other server processes" -msgstr "ä»–ã®ã‚µãƒ¼ãƒãƒ—ロセスを終ã‚らã›ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯åŒã˜ãƒ­ãƒ¼ãƒ«ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be a superuser to terminate superuser process" +msgstr "スーパーユーザã®ãƒ—ロセスを終了ã•ã›ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/adt/misc.c:185 +#: utils/adt/misc.c:319 #, c-format -msgid "must be superuser to signal the postmaster" -msgstr "postmasterã«ã‚·ã‚°ãƒŠãƒ«ã‚’é€ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "終了ã—よã†ã¨ã—ã¦ã„るプロセスã®ãƒ­ãƒ¼ãƒ«ã¾ãŸã¯pg_signal_backendã®ãƒ¡ãƒ³ãƒã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/misc.c:190 +#: utils/adt/misc.c:336 #, c-format msgid "failed to send signal to postmaster: %m" msgstr "postmasterã«ã‚·ã‚°ãƒŠãƒ«ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/adt/misc.c:207 +#: utils/adt/misc.c:355 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "adminpack 1.0 ã§ãƒ­ã‚°ãƒ•ァイルをローテートã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" + +#: utils/adt/misc.c:356 #, c-format -msgid "must be superuser to rotate log files" -msgstr "ログファイルをローテートã•ã›ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "代ã‚りã«ã‚³ã‚¢ã®ä¸€éƒ¨ã§ã‚ã‚‹ pg_logfile_rotate() ã®ä½¿ç”¨ã‚’検討ã—ã¦ãã ã•ã„" -#: utils/adt/misc.c:212 +#: utils/adt/misc.c:361 utils/adt/misc.c:381 #, c-format msgid "rotation not possible because log collection not active" msgstr "ログåŽé›†ãŒæ´»å‹•ã—ã¦ã„ã¾ã›ã‚“ã®ã§ãƒ­ãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³ã‚’行ã†ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: utils/adt/misc.c:254 +#: utils/adt/misc.c:418 #, c-format msgid "global tablespace never has databases" msgstr "グローãƒãƒ«ãƒ†ãƒ¼ãƒ–ル空間ã«ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒã‚りã¾ã›ã‚“" -#: utils/adt/misc.c:275 +#: utils/adt/misc.c:439 #, c-format msgid "%u is not a tablespace OID" msgstr "%uã¯ãƒ†ãƒ¼ãƒ–ル空間ã®OIDã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/misc.c:472 +#: utils/adt/misc.c:626 msgid "unreserved" msgstr "予約ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/misc.c:476 +#: utils/adt/misc.c:630 msgid "unreserved (cannot be function or type name)" msgstr "予約ã•れã¦ã„ã¾ã›ã‚“(関数ã¾ãŸã¯åž‹åã«ã¯ã§ãã¾ã›ã‚“)" -#: utils/adt/misc.c:480 +#: utils/adt/misc.c:634 msgid "reserved (can be function or type name)" msgstr "予約ã•れã¦ã„ã¾ã™ï¼ˆé–¢æ•°ã¾ãŸã¯åž‹åã«ã§ãã¾ã™ï¼‰" -#: utils/adt/misc.c:484 +#: utils/adt/misc.c:638 msgid "reserved" msgstr "予約ã•れã¦ã„ã¾ã™" -#: utils/adt/nabstime.c:161 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 +#: utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "æ–‡å­—åˆ—ã¯æœ‰åйãªè­˜åˆ¥å­ã§ã¯ã‚りã¾ã›ã‚“: \"%s\"" + +#: utils/adt/misc.c:814 +#, c-format +msgid "String has unclosed double quotes." +msgstr "文字列中ã«é–‰ã˜ã‚‰ã‚Œã¦ã„ãªã„二é‡å¼•用符ãŒã‚りã¾ã™ã€‚" + +#: utils/adt/misc.c:828 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "引用符ã§å›²ã¾ã‚ŒãŸè­˜åˆ¥å­ã¯ç©ºã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“。" + +#: utils/adt/misc.c:867 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "\".\"ã®å‰ã«æœ‰åйãªè­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“。" + +#: utils/adt/misc.c:873 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "\".\"ã®å¾Œã«æœ‰åйãªè­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“。" + +#: utils/adt/misc.c:934 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "ログ形å¼\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: utils/adt/misc.c:935 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "サãƒãƒ¼ãƒˆã•れã¦ã„るログ形å¼ã¯\"stderr\"ã¨\"csvlog\"ã§ã™ã€‚" + +#: utils/adt/nabstime.c:140 #, c-format msgid "invalid time zone name: \"%s\"" -msgstr "時間帯åç§°ãŒç„¡åйã§ã™: \"%s\"" +msgstr "䏿­£ãªã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³å: \"%s\"" -#: utils/adt/nabstime.c:507 utils/adt/nabstime.c:580 +#: utils/adt/nabstime.c:485 utils/adt/nabstime.c:558 #, c-format msgid "cannot convert abstime \"invalid\" to timestamp" msgstr "abstimeã®\"invalid\"ã‚’timestampã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/nabstime.c:807 +#: utils/adt/nabstime.c:785 #, c-format msgid "invalid status in external \"tinterval\" value" -msgstr "\"tinterval\"ã®å¤–部値ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒç„¡åйã§ã™" +msgstr "\"tinterval\"ã®å¤–部値ã§ä¸æ­£ãªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹å€¤" -#: utils/adt/nabstime.c:881 +#: utils/adt/nabstime.c:855 #, c-format msgid "cannot convert reltime \"invalid\" to interval" -msgstr "reltimeã®\"invalid\"ã‚’intervalã«å¤‰æ›ã§ãã¾ã›ã‚“" - -#: utils/adt/nabstime.c:1576 -#, c-format -msgid "invalid input syntax for type tinterval: \"%s\"" -msgstr "åž‹tintervalã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgstr "reltimeã®\"invalid\"ã¯intervalã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/network.c:118 +#: utils/adt/network.c:69 #, c-format msgid "invalid cidr value: \"%s\"" -msgstr "CIDR値ãŒç„¡åйã§ã™: \"%s\"" +msgstr "䏿­£ãªCIDR値: \"%s\"" -#: utils/adt/network.c:119 utils/adt/network.c:249 +#: utils/adt/network.c:70 utils/adt/network.c:200 #, c-format msgid "Value has bits set to right of mask." -msgstr "値ã«ã¯ãƒžã‚¹ã‚¯ã®å³å´ã«ã‚»ãƒƒãƒˆã•れãŸãƒ“ットãŒã‚りã¾ã™" +msgstr "値ã§ã¯ãƒžã‚¹ã‚¯ã®å³å´ã®ãƒ“ットãŒã‚»ãƒƒãƒˆã•れã¦ã„ã¾ã™ã€‚" -#: utils/adt/network.c:160 utils/adt/network.c:614 utils/adt/network.c:639 -#: utils/adt/network.c:664 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 +#: utils/adt/network.c:642 #, c-format msgid "could not format inet value: %m" -msgstr "inet値を整形ã§ãã¾ã›ã‚“: %m" +msgstr "inet値を整形ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" #. translator: %s is inet or cidr -#: utils/adt/network.c:217 +#: utils/adt/network.c:168 #, c-format msgid "invalid address family in external \"%s\" value" -msgstr "外部 \"%s\" 値内ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ•ァミリãŒç„¡åйã§ã™" +msgstr "外部ã®\"%s\"値内ã®ä¸æ­£ãªã‚¢ãƒ‰ãƒ¬ã‚¹ãƒ•ァミリ" #. translator: %s is inet or cidr -#: utils/adt/network.c:224 +#: utils/adt/network.c:175 #, c-format msgid "invalid bits in external \"%s\" value" -msgstr "外部 \"%s\" 値内ã®ãƒ“ットãŒç„¡åйã§ã™" +msgstr "外部ã®\"%s\"値内ã®ä¸æ­£ãªãƒ“ット列" #. translator: %s is inet or cidr -#: utils/adt/network.c:233 +#: utils/adt/network.c:184 #, c-format msgid "invalid length in external \"%s\" value" -msgstr "外部 \"%s\" 値内ã®é•·ã•ãŒç„¡åйã§ã™" +msgstr "外部ã®\"%s\"値内ã®ä¸æ­£ãªé•·ã•" -#: utils/adt/network.c:248 +#: utils/adt/network.c:199 #, c-format msgid "invalid external \"cidr\" value" -msgstr "\"cidr\"ã®å¤–部値ãŒç„¡åйã§ã™" +msgstr "\"cidr\"ã®å¤–部値ãŒä¸æ­£ã§ã™" -#: utils/adt/network.c:370 utils/adt/network.c:397 +#: utils/adt/network.c:295 utils/adt/network.c:318 #, c-format msgid "invalid mask length: %d" -msgstr "マスク長ãŒç„¡åйã§ã™: %d" +msgstr "䏿­£ãªãƒžã‚¹ã‚¯é•·: %d" -#: utils/adt/network.c:682 +#: utils/adt/network.c:660 #, c-format msgid "could not format cidr value: %m" -msgstr "cidr値を整形ã§ãã¾ã›ã‚“: %m" +msgstr "cidr値を整形ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: utils/adt/network.c:893 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "ç•°ãªã‚‹ãƒ•ァミリã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯çµåˆã§ãã¾ã›ã‚“" -#: utils/adt/network.c:1255 +#: utils/adt/network.c:1309 #, c-format msgid "cannot AND inet values of different sizes" msgstr "サイズãŒç•°ãªã‚‹inet値ã®ANDã¯ã§ãã¾ã›ã‚“" -#: utils/adt/network.c:1287 +#: utils/adt/network.c:1341 #, c-format msgid "cannot OR inet values of different sizes" msgstr "サイズãŒç•°ãªã‚‹inet値ã®ORã¯ã§ãã¾ã›ã‚“" -#: utils/adt/network.c:1348 utils/adt/network.c:1424 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format msgid "result is out of range" msgstr "çµæžœãŒç¯„囲外ã§ã™" -#: utils/adt/network.c:1389 +#: utils/adt/network.c:1443 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "サイズãŒç•°ãªã‚‹inet値ã®å¼•ãç®—ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/numeric.c:485 utils/adt/numeric.c:512 utils/adt/numeric.c:3253 -#: utils/adt/numeric.c:3276 utils/adt/numeric.c:3300 utils/adt/numeric.c:3307 -#, c-format -msgid "invalid input syntax for type numeric: \"%s\"" -msgstr "numericåž‹ã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/numeric.c:655 +#: utils/adt/numeric.c:830 #, c-format -msgid "invalid length in external \"numeric\" value" -msgstr "\"numeric\"ã®å¤–部値ã®é•·ã•ãŒç„¡åйã§ã™" +msgid "invalid sign in external \"numeric\" value" +msgstr "外部\"numeric\"ã®å€¤ã®ç¬¦å·ãŒä¸æ­£ã§ã™" -#: utils/adt/numeric.c:666 +#: utils/adt/numeric.c:836 #, c-format -msgid "invalid sign in external \"numeric\" value" -msgstr "\"numeric\"ã®å¤–部値ã®ç¬¦å·ãŒç„¡åйã§ã™" +msgid "invalid scale in external \"numeric\" value" +msgstr "外部\"numeric\"ã®å€¤ã®ä½å–りãŒä¸æ­£ã§ã™" -#: utils/adt/numeric.c:676 +#: utils/adt/numeric.c:845 #, c-format msgid "invalid digit in external \"numeric\" value" -msgstr "\"numeric\"ã®å¤–éƒ¨å€¤ã®æ¡ãŒç„¡åйã§ã™" +msgstr "外部\"numeric\"ã®å€¤ã®æ¡ãŒä¸æ­£ã§ã™" -#: utils/adt/numeric.c:859 utils/adt/numeric.c:873 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "NUMERICã®ç²¾åº¦%dã¯1ã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/numeric.c:864 +#: utils/adt/numeric.c:1040 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "NUMERICã®ä½å–り%dã¯0ã‹ã‚‰ç²¾åº¦%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/numeric.c:882 +#: utils/adt/numeric.c:1058 #, c-format msgid "invalid NUMERIC type modifier" -msgstr "無効ãªNUMERICåž‹ã®ä¿®æ­£å­ã§ã™" +msgstr "䏿­£ãªNUMERICåž‹ã®ä¿®æ­£å­" + +#: utils/adt/numeric.c:1390 +#, c-format +msgid "start value cannot be NaN" +msgstr "開始値ã¯NaNã«ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/numeric.c:1395 +#, c-format +msgid "stop value cannot be NaN" +msgstr "終了値ã¯NaNã«ã¯ã§ãã¾ã›ã‚“" + +#: utils/adt/numeric.c:1405 +#, c-format +msgid "step size cannot be NaN" +msgstr "加算é‡ã¯NaNã«ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/numeric.c:1889 utils/adt/numeric.c:3750 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 +#: utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 +#: utils/adt/numeric.c:8490 #, c-format msgid "value overflows numeric format" -msgstr "値ãŒnumericã®æ›¸å¼ã§ã‚ªãƒ¼ãƒãƒ•ローã—ã¦ã„ã¾ã™" +msgstr "値ãŒnumericã®å½¢å¼ã§ã‚ªãƒ¼ãƒãƒ•ローã—ã¾ã™" -#: utils/adt/numeric.c:2220 +#: utils/adt/numeric.c:3095 #, c-format msgid "cannot convert NaN to integer" msgstr "NaNã‚’integerã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/numeric.c:2286 +#: utils/adt/numeric.c:3161 #, c-format msgid "cannot convert NaN to bigint" msgstr "NaNã‚’bigintã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/numeric.c:2331 +#: utils/adt/numeric.c:3206 #, c-format msgid "cannot convert NaN to smallint" msgstr "NaNã‚’smallintã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/numeric.c:3820 -#, c-format -msgid "numeric field overflow" -msgstr "numericフィールドãŒã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¦ã„ã¾ã™" - -#: utils/adt/numeric.c:3821 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 #, c-format -msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." -msgstr "精度 %dã€ä½å–り %dã‚’æŒã¤ãƒ•ィールドã¯ã€%s%dよりå°ã•ãªçµ¶å¯¾å€¤ã«ä¸¸ã‚られã¾ã™ã€‚" - -#: utils/adt/numeric.c:5276 -#, c-format -msgid "argument for function \"exp\" too big" -msgstr "関数\"exp\"ã®å¼•æ•°ãŒå¤§ãã™ãŽã¾ã™" +msgid "cannot convert infinity to numeric" +msgstr "infinityã‚’numericã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: utils/adt/numutils.c:75 +#: utils/adt/numeric.c:6240 #, c-format -msgid "value \"%s\" is out of range for type integer" -msgstr "値\"%s\"ã¯åž‹integerã®ç¯„囲外ã§ã™" +msgid "numeric field overflow" +msgstr "numericフィールドã®ã‚ªãƒ¼ãƒãƒ¼ãƒ•ロー" -#: utils/adt/numutils.c:81 +#: utils/adt/numeric.c:6241 #, c-format -msgid "value \"%s\" is out of range for type smallint" -msgstr "値\"%s\"ã¯åž‹smallintã®ç¯„囲外ã§ã™" +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "精度%dã€ä½å–り%dã‚’æŒã¤ãƒ•ィールドã¯ã€%s%dよりå°ã•ãªçµ¶å¯¾å€¤ã«ä¸¸ã‚られã¾ã™ã€‚" -#: utils/adt/numutils.c:87 +#: utils/adt/numutils.c:89 #, c-format msgid "value \"%s\" is out of range for 8-bit integer" -msgstr "値\"%s\"ã¯ï¼˜ãƒ“ット整数ã®ç¯„囲外ã§ã™" - -#: utils/adt/oid.c:43 utils/adt/oid.c:57 utils/adt/oid.c:63 utils/adt/oid.c:84 -#, c-format -msgid "invalid input syntax for type oid: \"%s\"" -msgstr "åž‹oidã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/oid.c:69 utils/adt/oid.c:107 -#, c-format -msgid "value \"%s\" is out of range for type oid" -msgstr "値\"%s\"ã¯åž‹oidã®ç¯„囲外ã§ã™" +msgstr "値\"%s\"ã¯8ビット整数ã®ç¯„囲外ã§ã™" -#: utils/adt/oid.c:287 +#: utils/adt/oid.c:290 #, c-format msgid "invalid oidvector data" -msgstr "oidvectorデータãŒç„¡åйã§ã™" +msgstr "䏿­£ãªoidvectorデータ" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" -msgstr "è¦æ±‚ã—ãŸæ–‡å­—ãŒé•·ã™ãŽã¾ã™" +msgstr "è¦æ±‚ã•ã‚ŒãŸæ–‡å­—ãŒå¤§ãã™ãŽã¾ã™" -#: utils/adt/oracle_compat.c:941 utils/adt/oracle_compat.c:995 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" -msgstr "è¦æ±‚ã—ãŸæ–‡å­—ã¯ç¬¦å·åŒ–æ–¹å¼ã§ã¯é•·ã™ãŽã¾ã™: %d" - -#: utils/adt/oracle_compat.c:988 -#, c-format -msgid "null character not permitted" -msgstr "NULL文字ã¯è¨±ã•れã¾ã›ã‚“" - -#: utils/adt/pg_locale.c:1044 -#, c-format -msgid "could not create locale \"%s\": %m" -msgstr "ロケール \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: utils/adt/pg_locale.c:1047 -#, c-format -msgid "The operating system could not find any locale data for the locale name \"%s\"." -msgstr "オペレーティングシステムã¯ãƒ­ã‚±ãƒ¼ãƒ«å\"%s\"ã«å¯¾ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ãƒ‡ãƒ¼ã‚¿ã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸã€‚" - -#: utils/adt/pg_locale.c:1134 -#, c-format -msgid "collations with different collate and ctype values are not supported on this platform" -msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ç•°ãªã£ãŸ collate 㨠ctype ã«ã‚ˆã‚‹ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#: utils/adt/pg_locale.c:1149 -#, c-format -msgid "nondefault collations are not supported on this platform" -msgstr "ã“ã®ãƒ—ラットフォームã§ãƒ‡ãƒ•ォルトã§ãªã„ç…§åˆé †åºã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgstr "è¦æ±‚ã•ã‚ŒãŸæ–‡å­—ã¯ç¬¦å·åŒ–ã™ã‚‹ã«ã¯å¤§ãã™ãŽã¾ã™: %d" -#: utils/adt/pg_locale.c:1320 +#: utils/adt/oracle_compat.c:987 #, c-format -msgid "invalid multibyte character for locale" -msgstr "ロケールã§ã¯ãƒžãƒ«ãƒãƒã‚¤ãƒˆæ–‡å­—ã¯ç„¡åйã§ã™" +msgid "requested character not valid for encoding: %d" +msgstr "è¦æ±‚ã•ã‚ŒãŸæ–‡å­—ã¯ä¸æ­£ãªãŸã‚符å·åŒ–ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“: %d" -#: utils/adt/pg_locale.c:1321 +#: utils/adt/oracle_compat.c:1001 #, c-format -msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." -msgstr "サーãƒã®LC_CTYPEロケールã¯ãŠãらãデータベースã®ç¬¦å·åŒ–æ–¹å¼ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" +msgid "null character not permitted" +msgstr "NULL文字ã¯è¨±ã•れã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:95 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format -msgid "cannot accept a value of type any" -msgstr "åž‹anyã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "percentile value %g is not between 0 and 1" +msgstr "ç™¾åˆ†ä½æ•°ã®å€¤%gãŒ0ã¨1ã®é–“ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:108 +#: utils/adt/pg_locale.c:1034 #, c-format -msgid "cannot display a value of type any" -msgstr "åž‹anyã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "Apply system library package updates." +msgstr "ã‚·ã‚¹ãƒ†ãƒ ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã®æ›´æ–°ã‚’é©ç”¨ã—ã¦ãã ã•ã„。" -#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:150 +#: utils/adt/pg_locale.c:1249 #, c-format -msgid "cannot accept a value of type anyarray" -msgstr "åž‹anyarrayã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "could not create locale \"%s\": %m" +msgstr "ロケール\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/adt/pseudotypes.c:175 +#: utils/adt/pg_locale.c:1252 #, c-format -msgid "cannot accept a value of type anyenum" -msgstr "anyenumåž‹ã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "オペレーティングシステムã¯ãƒ­ã‚±ãƒ¼ãƒ«å\"%s\"ã®ãƒ­ã‚±ãƒ¼ãƒ«ãƒ‡ãƒ¼ã‚¿ã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸã€‚" -#: utils/adt/pseudotypes.c:199 +#: utils/adt/pg_locale.c:1353 #, c-format -msgid "cannot accept a value of type anyrange" -msgstr "anyrangeåž‹ã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯å€¤ãŒç•°ãªã‚‹collateã¨ctypeã«ã‚ˆã‚‹ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:276 +#: utils/adt/pg_locale.c:1362 #, c-format -msgid "cannot accept a value of type trigger" -msgstr "åž‹triggerã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "collation provider LIBC is not supported on this platform" +msgstr "ç…§åˆé †åºãƒ—ロãƒã‚¤ãƒ€LIBCã¯ã“ã®ãƒ—ラットフォームã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:289 +#: utils/adt/pg_locale.c:1374 #, c-format -msgid "cannot display a value of type trigger" -msgstr "åž‹triggerã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ICUã¯å€¤ãŒç•°ãªã‚‹collateã¨ctypeã«ã‚ˆã‚‹ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:303 +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 #, c-format -#| msgid "cannot accept a value of type trigger" -msgid "cannot accept a value of type event_trigger" -msgstr "åž‹event_triggerã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "could not open collator for locale \"%s\": %s" +msgstr "ロケール\"%s\"ã®ç…§åˆå™¨ã‚’オープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: utils/adt/pseudotypes.c:316 +#: utils/adt/pg_locale.c:1391 #, c-format -#| msgid "cannot display a value of type trigger" -msgid "cannot display a value of type event_trigger" -msgstr "åž‹event_triggerã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "ICU is not supported in this build" +msgstr "ã“ã®ãƒ“ルドã§ã¯ICUã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:330 +#: utils/adt/pg_locale.c:1392 #, c-format -msgid "cannot accept a value of type language_handler" -msgstr "åž‹language_handlerã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "--with-icuを使用ã—ã¦PostgreSQLã‚’å†æ§‹ç¯‰ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/pseudotypes.c:343 +#: utils/adt/pg_locale.c:1412 #, c-format -msgid "cannot display a value of type language_handler" -msgstr "åž‹language_handlerã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "ç…§åˆé †åº\"%s\"ã«ã¯å®Ÿéš›ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“ãŒã€ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れã¦ã„ã¾ã™" -#: utils/adt/pseudotypes.c:357 +#: utils/adt/pg_locale.c:1419 #, c-format -msgid "cannot accept a value of type fdw_handler" -msgstr "fdw_handler åž‹ã®å€¤ã¯å—ã‘付ã‘られã¾ã›ã‚“" +msgid "collation \"%s\" has version mismatch" +msgstr "ç…§åˆé †åº\"%s\"ã§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´ãŒèµ·ãã¦ã„ã¾ã™" -#: utils/adt/pseudotypes.c:370 +#: utils/adt/pg_locale.c:1421 #, c-format -msgid "cannot display a value of type fdw_handler" -msgstr "fdw_handler åž‹ã®å€¤ã¯è¡¨ç¤ºã§ãã¾ã›ã‚“" +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "データベース中ã®ç…§åˆé †åºã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã§ä½œæˆã•れã¦ã„ã¾ã™ãŒã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã‚’æä¾›ã—ã¦ã„ã¾ã™ã€‚" -#: utils/adt/pseudotypes.c:384 +#: utils/adt/pg_locale.c:1424 #, c-format -msgid "cannot accept a value of type internal" -msgstr "åž‹intervalã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "ã“ã®ç…§åˆé †åºã®å½±éŸ¿ã‚’å—ã‘ã‚‹å…¨ã¦ã®ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã‚’å†æ§‹ç¯‰ã—ã¦ã€ALTER COLLATION %s REFRESH VERSIONを実行ã™ã‚‹ã‹ã€æ­£ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ãƒ©ã‚¤ãƒ–ラリを用ã„ã¦PostgreSQLをビルドã—ã¦ãã ã•ã„。" -#: utils/adt/pseudotypes.c:397 +#: utils/adt/pg_locale.c:1508 #, c-format -msgid "cannot display a value of type internal" -msgstr "åž‹intervalã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "エンコーディング\"%s\"ã®ICU変æ›å™¨ã‚’オープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: utils/adt/pseudotypes.c:411 +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 #, c-format -msgid "cannot accept a value of type opaque" -msgstr "åž‹opaqueã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "ucnv_toUChars failed: %s" +msgstr "ucnv_toUCharsãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: utils/adt/pseudotypes.c:424 +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 #, c-format -msgid "cannot display a value of type opaque" -msgstr "åž‹opaqueã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "ucnv_fromUChars failed: %s" +msgstr "ucnv_fromUCharsãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: utils/adt/pseudotypes.c:438 +#: utils/adt/pg_locale.c:1758 #, c-format -msgid "cannot accept a value of type anyelement" -msgstr "åž‹anyelementã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "invalid multibyte character for locale" +msgstr "ロケールã«å¯¾ã™ã‚‹ä¸æ­£ãªãƒžãƒ«ãƒãƒã‚¤ãƒˆæ–‡å­—" -#: utils/adt/pseudotypes.c:451 +#: utils/adt/pg_locale.c:1759 #, c-format -msgid "cannot display a value of type anyelement" -msgstr "åž‹anyelementã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "ãŠãらãサーãƒã®LC_CTYPEロケールã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ç¬¦å·åŒ–æ–¹å¼ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:464 +#: utils/adt/pg_upgrade_support.c:29 #, c-format -msgid "cannot accept a value of type anynonarray" -msgstr "åž‹anynonarrayã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "function can only be called when server is in binary upgrade mode" +msgstr "関数ã¯ã‚µãƒ¼ãƒãŒãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—グレードモードã§ã‚ã‚‹ã¨ãã®ã¿å‘¼ã³å‡ºã›ã¾ã™" -#: utils/adt/pseudotypes.c:477 +#: utils/adt/pgstatfuncs.c:474 #, c-format -msgid "cannot display a value of type anynonarray" -msgstr "åž‹anynonarrayã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgid "invalid command name: \"%s\"" +msgstr "䏿­£ãªã‚³ãƒžãƒ³ãƒ‰å: \"%s\"" -#: utils/adt/pseudotypes.c:490 +#: utils/adt/pseudotypes.c:247 #, c-format msgid "cannot accept a value of a shell type" -msgstr "シェル型ã®å€¤ã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgstr "シェル型ã®å€¤ã¯å—ã‘付ã‘られã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:503 +#: utils/adt/pseudotypes.c:260 #, c-format msgid "cannot display a value of a shell type" -msgstr "シェル型ã®å€¤ã‚’表示ã§ãã¾ã›ã‚“" +msgstr "シェル型ã®å€¤ã¯è¡¨ç¤ºã§ãã¾ã›ã‚“" + +#: utils/adt/pseudotypes.c:350 utils/adt/pseudotypes.c:376 +#, c-format +msgid "cannot output a value of type %s" +msgstr "%såž‹ã®å€¤ã¯å‡ºåŠ›ã§ãã¾ã›ã‚“" -#: utils/adt/pseudotypes.c:525 utils/adt/pseudotypes.c:549 +#: utils/adt/pseudotypes.c:403 #, c-format -msgid "cannot accept a value of type pg_node_tree" -msgstr "pg_node_tree åž‹ã®å€¤ã¯å—ã‘付ã‘られã¾ã›ã‚“" +msgid "cannot display a value of type %s" +msgstr "%såž‹ã®å€¤ã¯è¡¨ç¤ºã§ãã¾ã›ã‚“" -#: utils/adt/rangetypes.c:396 +#: utils/adt/rangetypes.c:405 #, c-format -#| msgid "range constructor flags argument must not be NULL" msgid "range constructor flags argument must not be null" msgstr "範囲コンストラクタフラグ引数ã¯NULLã§ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/rangetypes.c:983 +#: utils/adt/rangetypes.c:992 #, c-format msgid "result of range difference would not be contiguous" -msgstr "範囲ã®å·®ç•°ã®çµæžœã¯é€£ç¶šçš„ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "範囲ã®å·®åˆ†ãŒé€£ç¶šã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/rangetypes.c:1044 +#: utils/adt/rangetypes.c:1053 #, c-format msgid "result of range union would not be contiguous" -msgstr "範囲ã®å’Œé›†åˆã®çµæžœã¯é€£ç¶šçš„ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "範囲ã®å’ŒãŒé€£ç¶šã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/rangetypes.c:1496 +#: utils/adt/rangetypes.c:1597 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "範囲ã®ä¸‹é™ã¯ç¯„囲ã®ä¸Šé™ä»¥ä¸‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/rangetypes.c:1879 utils/adt/rangetypes.c:1892 -#: utils/adt/rangetypes.c:1906 +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 +#: utils/adt/rangetypes.c:2007 #, c-format msgid "invalid range bound flags" -msgstr "範囲ã®å¢ƒç•Œãƒ•ラグãŒç„¡åйã§ã™" +msgstr "䏿­£ãªç¯„囲境界フラグ" -#: utils/adt/rangetypes.c:1880 utils/adt/rangetypes.c:1893 -#: utils/adt/rangetypes.c:1907 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "有効ãªå€¤ã¯\"[]\"ã€\"[)\"ã€\"(]\"ã€\"()\"ã§ã™" -#: utils/adt/rangetypes.c:1972 utils/adt/rangetypes.c:1989 -#: utils/adt/rangetypes.c:2002 utils/adt/rangetypes.c:2020 -#: utils/adt/rangetypes.c:2031 utils/adt/rangetypes.c:2075 -#: utils/adt/rangetypes.c:2083 +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 +#: utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 +#: utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 +#: utils/adt/rangetypes.c:2184 #, c-format msgid "malformed range literal: \"%s\"" msgstr "䏿­£ãªç¯„囲リテラル: \"%s\"" -#: utils/adt/rangetypes.c:1974 +#: utils/adt/rangetypes.c:2075 #, c-format -#| msgid "Junk after \"empty\" keyword." msgid "Junk after \"empty\" key word." msgstr "\"empty\"キーワードã®å¾Œã«ã‚´ãƒŸãŒã‚りã¾ã™ã€‚" -#: utils/adt/rangetypes.c:1991 +#: utils/adt/rangetypes.c:2092 #, c-format msgid "Missing left parenthesis or bracket." msgstr "左括弧ã¾ãŸã¯å·¦è§’括弧ãŒã‚りã¾ã›ã‚“" -#: utils/adt/rangetypes.c:2004 +#: utils/adt/rangetypes.c:2105 #, c-format msgid "Missing comma after lower bound." msgstr "下é™å€¤ã®å¾Œã«ã‚«ãƒ³ãƒžãŒã‚りã¾ã›ã‚“" -#: utils/adt/rangetypes.c:2022 +#: utils/adt/rangetypes.c:2123 #, c-format msgid "Too many commas." msgstr "カンマãŒå¤šã™ãŽã¾ã™" -#: utils/adt/rangetypes.c:2033 +#: utils/adt/rangetypes.c:2134 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "峿‹¬å¼§ã¾ãŸã¯å³è§’括弧ã®å¾Œã«ã”ã¿ãŒã‚りã¾ã™" -#: utils/adt/rangetypes.c:2077 utils/adt/rangetypes.c:2085 -#: utils/adt/rowtypes.c:206 utils/adt/rowtypes.c:214 -#, c-format -msgid "Unexpected end of input." -msgstr "想定外ã®å…¥åŠ›ã®çµ‚端ã§ã™" - -#: utils/adt/regexp.c:274 utils/adt/regexp.c:1222 utils/adt/varlena.c:3041 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 #, c-format msgid "regular expression failed: %s" msgstr "æ­£è¦è¡¨ç¾ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: utils/adt/regexp.c:411 +#: utils/adt/regexp.c:426 #, c-format msgid "invalid regexp option: \"%c\"" -msgstr "æ­£è¦è¡¨ç¾ã‚ªãƒ—ションãŒç„¡åйã§ã™: \"%c\"" +msgstr "䏿­£ãªæ­£è¦è¡¨ç¾ã‚ªãƒ—ション: \"%c\"" + +#: utils/adt/regexp.c:866 +#, c-format +msgid "regexp_match does not support the global option" +msgstr "regexp_matchã¯globalオプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: utils/adt/regexp.c:867 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "代ã‚りã«regexp_matchesを使ã£ã¦ãã ã•ã„。" + +#: utils/adt/regexp.c:1049 +#, c-format +msgid "too many regular expression matches" +msgstr "æ­£è¦è¡¨ç¾ã®ãƒžãƒƒãƒãŒå¤šéŽãŽã¾ã™" -#: utils/adt/regexp.c:883 +#: utils/adt/regexp.c:1244 #, c-format -msgid "regexp_split does not support the global option" -msgstr "regexp_splitã¯ã‚°ãƒ­ãƒ¼ãƒãƒ«ã‚ªãƒ—ションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" +msgid "regexp_split_to_table does not support the global option" +msgstr "regexp_split_to_tableã¯globalオプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: utils/adt/regproc.c:127 utils/adt/regproc.c:147 +#: utils/adt/regexp.c:1297 +#, c-format +msgid "regexp_split_to_array does not support the global option" +msgstr "regexp_split_to_arrayã¯globalオプションをサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" + +#: utils/adt/regproc.c:106 #, c-format msgid "more than one function named \"%s\"" msgstr "\"%s\"ã¨ã„ã†åå‰ã®é–¢æ•°ãŒè¤‡æ•°ã‚りã¾ã™" -#: utils/adt/regproc.c:494 utils/adt/regproc.c:514 +#: utils/adt/regproc.c:524 #, c-format msgid "more than one operator named %s" msgstr "%sã¨ã„ã†åå‰ã®æ¼”ç®—å­ãŒè¤‡æ•°ã‚りã¾ã™" -#: utils/adt/regproc.c:661 utils/adt/regproc.c:1531 utils/adt/ruleutils.c:7368 -#: utils/adt/ruleutils.c:7424 utils/adt/ruleutils.c:7469 +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9134 utils/adt/ruleutils.c:9302 #, c-format msgid "too many arguments" msgstr "引数ãŒå¤šã™ãŽã¾ã™" -#: utils/adt/regproc.c:662 +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 #, c-format msgid "Provide two argument types for operator." -msgstr "演算å­ã«ã¯2ã¤ã®å¼•数型をæä¾›ã—ã¦ãã ã•ã„" +msgstr "演算å­ã§ã¯2ã¤ã®å¼•数型を指定ã—ã¦ãã ã•ã„" -#: utils/adt/regproc.c:1366 utils/adt/regproc.c:1371 utils/adt/varlena.c:2313 -#: utils/adt/varlena.c:2318 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 #, c-format msgid "invalid name syntax" -msgstr "å剿§‹æ–‡ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªåå‰ã®æ§‹æ–‡" -#: utils/adt/regproc.c:1429 +#: utils/adt/regproc.c:1763 #, c-format msgid "expected a left parenthesis" msgstr "左括弧を想定ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/regproc.c:1445 +#: utils/adt/regproc.c:1779 #, c-format msgid "expected a right parenthesis" msgstr "峿‹¬å¼§ã‚’想定ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/regproc.c:1464 +#: utils/adt/regproc.c:1798 #, c-format msgid "expected a type name" msgstr "åž‹ã®åå‰ã‚’想定ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/regproc.c:1496 +#: utils/adt/regproc.c:1830 #, c-format msgid "improper type name" msgstr "åž‹ã®åå‰ãŒä¸é©åˆ‡ã§ã™" -#: utils/adt/ri_triggers.c:339 utils/adt/ri_triggers.c:2474 -#: utils/adt/ri_triggers.c:3226 +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 +#: utils/adt/ri_triggers.c:2842 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "テーブル\"%s\"ã¸ã®æŒ¿å…¥ã€æ›´æ–°ã¯å¤–部キー制約\"%s\"ã«é•åã—ã¦ã„ã¾ã™" -#: utils/adt/ri_triggers.c:342 utils/adt/ri_triggers.c:2477 +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MACTH FULLã§ã¯NULLキー値ã¨éžNULLキー値を混在ã§ãã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:2716 +#: utils/adt/ri_triggers.c:2273 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "関数\"%s\"ã‚’INSERTã§ç™ºè¡Œã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:2722 +#: utils/adt/ri_triggers.c:2279 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "関数\"%s\"ã‚’UPDATEã§ç™ºè¡Œã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:2728 +#: utils/adt/ri_triggers.c:2285 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "関数\"%s\"ã‚’DELETEã§ç™ºè¡Œã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:2751 +#: utils/adt/ri_triggers.c:2308 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "テーブル\"%2$s\"ã®ãƒˆãƒªã‚¬\"%1$s\"用ã®pg_constrainté …ç›®ãŒã‚りã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:2753 +#: utils/adt/ri_triggers.c:2310 #, c-format msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." msgstr "ã“ã®å‚ç…§æ•´åˆæ€§ãƒˆãƒªã‚¬ã¨ãã®å¯¾è±¡ã‚’削除ã—ã€ALTER TABLE ADD CONSTRAINTを実行ã—ã¦ãã ã•ã„" -#: utils/adt/ri_triggers.c:3176 +#: utils/adt/ri_triggers.c:2689 #, c-format msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" msgstr "\"%3$s\"ã®åˆ¶ç´„\"%2$s\"ã‹ã‚‰\"%1$s\"ã«è¡Œã‚れãŸå‚ç…§æ•´åˆæ€§å•ã„åˆã‚ã›ãŒæƒ³å®šå¤–ã®çµæžœã«ãªã‚Šã¾ã—ãŸ" -#: utils/adt/ri_triggers.c:3180 +#: utils/adt/ri_triggers.c:2693 #, c-format msgid "This is most likely due to a rule having rewritten the query." -msgstr "ã“れã¯ã»ã¨ã‚“ã©ã®å ´åˆã“ã®å•ã„åˆã‚ã›ã‚’æ›¸ãæ›ãˆã‚‹ãƒ«ãƒ¼ãƒ«ãŒåŽŸå› ã§ã™" +msgstr "ã“ã‚Œã¯æ¦‚ã­ã“ã®å•ã„åˆã‚ã›ã‚’æ›¸ãæ›ãˆã‚‹ãƒ«ãƒ¼ãƒ«ãŒåŽŸå› ã§ã™" -#: utils/adt/ri_triggers.c:3229 +#: utils/adt/ri_triggers.c:2846 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "テーブル\"%3$s\"ã«ã‚­ãƒ¼(%1$s)=(%2$s)ãŒã‚りã¾ã›ã‚“" -#: utils/adt/ri_triggers.c:3236 +#: utils/adt/ri_triggers.c:2849 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "テーブル\"%s\"ã«ã‚­ãƒ¼ãŒã‚りã¾ã›ã‚“。" + +#: utils/adt/ri_triggers.c:2855 #, c-format msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "テーブル\"%1$s\"ã®æ›´æ–°ã¾ãŸã¯å‰Šé™¤ã¯ã€ãƒ†ãƒ¼ãƒ–ル\"%3$s\"ã®å¤–部キー制約\"%2$s\"ã«é•åã—ã¾ã™" -#: utils/adt/ri_triggers.c:3240 +#: utils/adt/ri_triggers.c:2860 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "キー(%s)=(%s)ã¯ã¾ã ãƒ†ãƒ¼ãƒ–ル\"%s\"ã‹ã‚‰å‚ç…§ã•れã¦ã„ã¾ã™" -#: utils/adt/rowtypes.c:100 utils/adt/rowtypes.c:489 +#: utils/adt/ri_triggers.c:2863 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "テーブル\"%s\"ã‹ã‚‰ã‚­ãƒ¼ãŒã¾ã å‚ç…§ã•れã¦ã„ã¾ã™ã€‚" + +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "匿å複åˆåž‹ã®å…¥åŠ›ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/rowtypes.c:153 utils/adt/rowtypes.c:181 utils/adt/rowtypes.c:204 -#: utils/adt/rowtypes.c:212 utils/adt/rowtypes.c:264 utils/adt/rowtypes.c:272 +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 +#: utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 #, c-format msgid "malformed record literal: \"%s\"" msgstr "ãŠã‹ã—ãªãƒ¬ã‚³ãƒ¼ãƒ‰ãƒªãƒ†ãƒ©ãƒ«ã§ã™: \"%s\"" -#: utils/adt/rowtypes.c:154 +#: utils/adt/rowtypes.c:156 #, c-format msgid "Missing left parenthesis." msgstr "左括弧ãŒã‚りã¾ã›ã‚“" -#: utils/adt/rowtypes.c:182 +#: utils/adt/rowtypes.c:185 #, c-format msgid "Too few columns." msgstr "列ãŒå°‘ãªã™ãŽã¾ã™" -#: utils/adt/rowtypes.c:265 +#: utils/adt/rowtypes.c:268 #, c-format msgid "Too many columns." msgstr "列ãŒå¤šã™ãŽã¾ã™" -#: utils/adt/rowtypes.c:273 +#: utils/adt/rowtypes.c:276 #, c-format msgid "Junk after right parenthesis." msgstr "峿‹¬å¼§ã®å¾Œã«ã”ã¿ãŒã‚りã¾ã™" -#: utils/adt/rowtypes.c:538 +#: utils/adt/rowtypes.c:530 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "列数ãŒé–“é•ã£ã¦ã„ã¾ã™: %d。%dを想定ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/rowtypes.c:565 +#: utils/adt/rowtypes.c:558 #, c-format msgid "wrong data type: %u, expected %u" msgstr "データ型ãŒé–“é•ã£ã¦ã„ã¾ã™: %u。%uを想定ã—ã¦ã„ã¾ã—ãŸ" -#: utils/adt/rowtypes.c:626 +#: utils/adt/rowtypes.c:619 #, c-format msgid "improper binary format in record column %d" msgstr "レコード列%dã®ãƒã‚¤ãƒŠãƒªæ›¸å¼ãŒä¸é©åˆ‡ã§ã™" -#: utils/adt/rowtypes.c:926 utils/adt/rowtypes.c:1161 +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 +#: utils/adt/rowtypes.c:1657 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" -msgstr "レコードã®ã‚«ãƒ©ãƒ  %3$d ã«ãŠã„ã¦ã€å…¨ãç•°ãªã‚‹åž‹ %1$s 㨠%2$s ã§ã¯æ¯”較ãŒã§ãã¾ã›ã‚“" +msgstr "レコードã®åˆ— %3$d ã«ãŠã„ã¦ã€å…¨ãç•°ãªã‚‹åž‹ %1$s 㨠%2$s ã§ã¯æ¯”較ãŒã§ãã¾ã›ã‚“" -#: utils/adt/rowtypes.c:1012 utils/adt/rowtypes.c:1232 +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 +#: utils/adt/rowtypes.c:1731 #, c-format msgid "cannot compare record types with different numbers of columns" -msgstr "個数ãŒç•°ãªã‚‹ã‚«ãƒ©ãƒ åŒå£«ã§ã¯ãƒ¬ã‚³ãƒ¼ãƒ‰åž‹ã®æ¯”較ãŒã§ãã¾ã›ã‚“" +msgstr "個数ãŒç•°ãªã‚‹åˆ—åŒå£«ã§ã¯ãƒ¬ã‚³ãƒ¼ãƒ‰åž‹ã®æ¯”較ãŒã§ãã¾ã›ã‚“" -#: utils/adt/ruleutils.c:3816 +#: utils/adt/ruleutils.c:4825 #, c-format msgid "rule \"%s\" has unsupported event type %d" -msgstr "ルール\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„イベント種類%dã‚’æŒã¡ã¾ã™" +msgstr "ルール\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ãªã„イベントタイプ%dã‚’æŒã¡ã¾ã™" -#: utils/adt/selfuncs.c:5179 +#: utils/adt/selfuncs.c:5791 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "åž‹byteaã§ã¯å¤§æ–‡å­—å°æ–‡å­—ã®åŒºåˆ¥ã‚’ã—ãªã„マッãƒã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: utils/adt/selfuncs.c:5282 +#: utils/adt/selfuncs.c:5893 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "åž‹byteaã§ã¯æ­£è¦è¡¨ç¾ã®ãƒžãƒƒãƒã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“" -#: utils/adt/tid.c:71 utils/adt/tid.c:79 utils/adt/tid.c:87 -#, c-format -msgid "invalid input syntax for type tid: \"%s\"" -msgstr "åž‹tidã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" - -#: utils/adt/timestamp.c:98 +#: utils/adt/timestamp.c:107 #, c-format msgid "TIMESTAMP(%d)%s precision must not be negative" msgstr "TIMESTAMP(%d)%s ã®ç²¾åº¦ã¯è² ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/adt/timestamp.c:104 +#: utils/adt/timestamp.c:113 #, c-format msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "TIMESTAMP(%d)%sã®ä½å–りを許容最大値%dã¾ã§æ¸›ã‚‰ã—ã¾ã—ãŸ" -#: utils/adt/timestamp.c:172 utils/adt/timestamp.c:446 +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestampãŒç¯„囲外ã§ã™: \"%s\"" + +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 +#: utils/adt/timestamp.c:941 +#, c-format +msgid "date/time value \"%s\" is no longer supported" +msgstr "日付時刻ã®å€¤\"%s\"ã¯ã‚‚ã†ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: utils/adt/timestamp.c:362 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "timestamp(%d)ã®ç²¾åº¦ã¯%dã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/timestamp.c:484 +#, c-format +msgid "invalid input syntax for numeric time zone: \"%s\"" +msgstr "数値タイムゾーンã®ä¸æ­£ãªå…¥åŠ›æ§‹æ–‡: \"%s\"" + +#: utils/adt/timestamp.c:486 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "数字タイムゾーンã¯å…ˆé ­ã®æ–‡å­—ãŒ\"-\"ã¾ãŸã¯\"+\"ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: utils/adt/timestamp.c:499 #, c-format -msgid "timestamp out of range: \"%s\"" -msgstr "timestampãŒç¯„囲外ã§ã™: \"%s\"" +msgid "numeric time zone \"%s\" out of range" +msgstr "数値タイムゾーン\"%s\"ãŒãŒç¯„囲外ã§ã™" -#: utils/adt/timestamp.c:190 utils/adt/timestamp.c:464 -#: utils/adt/timestamp.c:674 +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 #, c-format -msgid "date/time value \"%s\" is no longer supported" -msgstr "日付時刻ã®å€¤\"%s\"ã¯ã‚‚ã†ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestampãŒç¯„囲外ã§ã™: %d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:260 +#: utils/adt/timestamp.c:720 #, c-format msgid "timestamp cannot be NaN" msgstr "タイムスタンプ㯠NaN ã«ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/timestamp.c:381 +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 #, c-format -msgid "timestamp(%d) precision must be between %d and %d" -msgstr "timestamp(%d)ã®ç²¾åº¦ã¯%dã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "timestamp out of range: \"%g\"" +msgstr "timestampãŒç¯„囲外ã§ã™: \"%g\"" -#: utils/adt/timestamp.c:668 utils/adt/timestamp.c:3254 -#: utils/adt/timestamp.c:3383 utils/adt/timestamp.c:3774 +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 +#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3016 +#: utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3026 +#: utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3083 +#: utils/adt/timestamp.c:3090 utils/adt/timestamp.c:3110 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3162 +#: utils/adt/timestamp.c:3206 utils/adt/timestamp.c:3633 +#: utils/adt/timestamp.c:3758 utils/adt/timestamp.c:4143 #, c-format msgid "interval out of range" msgstr "intervalãŒç¯„囲外ã§ã™" -#: utils/adt/timestamp.c:809 utils/adt/timestamp.c:842 +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 #, c-format msgid "invalid INTERVAL type modifier" -msgstr "無効ãªINTERVALåž‹ã®ä¿®æ­£å­ã§ã™" +msgstr "䏿­£ãªINTERVALåž‹ã®ä¿®æ­£å­ã§ã™" -#: utils/adt/timestamp.c:825 +#: utils/adt/timestamp.c:1084 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "INTERVAL(%d)ã®ç²¾åº¦ã¯è² ã§ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/timestamp.c:831 +#: utils/adt/timestamp.c:1090 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "INTERVAL(%d)ã®ç²¾åº¦ã‚’許容最大値%dã¾ã§æ¸›ã‚‰ã—ã¾ã—ãŸ" -#: utils/adt/timestamp.c:1183 +#: utils/adt/timestamp.c:1462 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "interval(%d)ã®ç²¾åº¦ã¯%dã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/timestamp.c:2452 +#: utils/adt/timestamp.c:2617 #, c-format msgid "cannot subtract infinite timestamps" msgstr "ç„¡é™å¤§ã®timestampを減算ã§ãã¾ã›ã‚“" -#: utils/adt/timestamp.c:3509 utils/adt/timestamp.c:4115 -#: utils/adt/timestamp.c:4155 +#: utils/adt/timestamp.c:3886 utils/adt/timestamp.c:4403 +#: utils/adt/timestamp.c:4570 utils/adt/timestamp.c:4591 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "timestampã®å˜ä½\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/timestamp.c:3523 utils/adt/timestamp.c:4165 +#: utils/adt/timestamp.c:3900 utils/adt/timestamp.c:4357 +#: utils/adt/timestamp.c:4601 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "timestampã®å˜ä½\"%s\"ã¯ä¸æ˜Žã§ã™" -#: utils/adt/timestamp.c:3663 utils/adt/timestamp.c:4326 -#: utils/adt/timestamp.c:4367 +#: utils/adt/timestamp.c:4032 utils/adt/timestamp.c:4398 +#: utils/adt/timestamp.c:4771 utils/adt/timestamp.c:4793 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "timestamp with time zoneã®å˜ä½\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/timestamp.c:3680 utils/adt/timestamp.c:4376 +#: utils/adt/timestamp.c:4049 utils/adt/timestamp.c:4352 +#: utils/adt/timestamp.c:4802 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "timestamp with time zoneã®å˜ä½\"%s\"ã¯ä¸æ˜Žã§ã™" -#: utils/adt/timestamp.c:3761 +#: utils/adt/timestamp.c:4130 #, c-format msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "月ã¯é€šå¸¸é€±ã‚’å«ã‚“ã§ã„ã¾ã™ã®ã§ã€intervalã®å˜ä½\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/timestamp.c:3767 utils/adt/timestamp.c:4482 +#: utils/adt/timestamp.c:4136 utils/adt/timestamp.c:4896 #, c-format msgid "interval units \"%s\" not supported" msgstr "intervalã®å˜ä½\"%s\"ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/timestamp.c:3783 utils/adt/timestamp.c:4509 +#: utils/adt/timestamp.c:4152 utils/adt/timestamp.c:4919 #, c-format msgid "interval units \"%s\" not recognized" msgstr "intervalã®å˜ä½\"%s\"ã¯ä¸æ˜Žã§ã™" -#: utils/adt/timestamp.c:4579 utils/adt/timestamp.c:4751 -#, c-format -msgid "could not convert to time zone \"%s\"" -msgstr "時間帯\"%s\"ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" - #: utils/adt/trigfuncs.c:42 #, c-format msgid "suppress_redundant_updates_trigger: must be called as trigger" @@ -17258,281 +22827,332 @@ msgstr "suppress_redundant_updates_trigger: update å‰ã«å‘¼ã°ã‚Œãªã‘れ㰠msgid "suppress_redundant_updates_trigger: must be called for each row" msgstr "suppress_redundant_updates_trigger: å„行ã”ã¨ã«å‘¼ã°ã‚Œãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/tsgistidx.c:98 +#: utils/adt/tsgistidx.c:100 #, c-format msgid "gtsvector_in not implemented" msgstr "gtsvector_inã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/tsquery.c:154 utils/adt/tsquery.c:389 +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "フレーズ演算å­ã§æŒ‡å®šã™ã‚‹è·é›¢ã¯%d以下ã§ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 #: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "tsqueryå†…ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼: \"%s\"" -#: utils/adt/tsquery.c:175 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "tsquery内ã«ã‚ªãƒšãƒ©ãƒ³ãƒ‰ãŒã‚りã¾ã›ã‚“\"%s\"" -#: utils/adt/tsquery.c:247 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "tsquery内ã®å€¤ãŒå¤§ãã™ãŽã¾ã™: \"%s\"" -#: utils/adt/tsquery.c:252 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "tsqueryã®ã‚ªãƒšãƒ©ãƒ³ãƒ‰ãŒé•·éŽãŽã¾ã™: \"%s\"" -#: utils/adt/tsquery.c:280 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "tsquery内ã®å˜èªžãŒé•·ã™ãŽã¾ã™: \"%s\"" -#: utils/adt/tsquery.c:509 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "テキスト検索å•ã„åˆã‚ã›ãŒå­—å¥è¦ç´ ã‚’å«ã¿ã¾ã›ã‚“: \"%s\"" -#: utils/adt/tsquery_cleanup.c:284 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsqueryãŒå¤§ãã™ãŽã¾ã™" + +#: utils/adt/tsquery_cleanup.c:407 #, c-format msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" msgstr "テキスト検索å•ã„åˆã‚ã›ã¯ã‚¹ãƒˆãƒƒãƒ—ワードã®ã¿ã‚’å«ã‚€ã€ã‚ã‚‹ã„ã¯ã€å­—å¥è¦ç´ ã‚’å«ã¿ã¾ã›ã‚“。無視ã•れã¾ã™" -#: utils/adt/tsquery_rewrite.c:293 +#: utils/adt/tsquery_op.c:123 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "フレーズ演算å­ã§æŒ‡å®šã™ã‚‹è·é›¢ã¯%dよりå°ã•ã„æ­£ã®æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/tsquery_rewrite.c:321 #, c-format msgid "ts_rewrite query must return two tsquery columns" msgstr "ts_rewriteå•ã„åˆã‚ã›ã¯2列ã®tsquery列を返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/tsrank.c:403 +#: utils/adt/tsrank.c:413 #, c-format msgid "array of weight must be one-dimensional" msgstr "é‡ã¿é…列ã¯1次元ã®é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/tsrank.c:408 +#: utils/adt/tsrank.c:418 #, c-format msgid "array of weight is too short" msgstr "é‡ã¿é…列ãŒçŸ­ã™ãŽã¾ã™" -#: utils/adt/tsrank.c:413 +#: utils/adt/tsrank.c:423 #, c-format msgid "array of weight must not contain nulls" msgstr "é‡ã¿é…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/adt/tsrank.c:422 utils/adt/tsrank.c:748 +#: utils/adt/tsrank.c:432 utils/adt/tsrank.c:869 #, c-format msgid "weight out of range" msgstr "é‡ã¿ãŒç¯„囲外ã§ã™" -#: utils/adt/tsvector.c:212 +#: utils/adt/tsvector.c:214 #, c-format msgid "word is too long (%ld bytes, max %ld bytes)" msgstr "å˜èªžãŒé•·ã™ãŽã¾ã™(%ldãƒã‚¤ãƒˆã€æœ€å¤§ã¯%ldãƒã‚¤ãƒˆ)" -#: utils/adt/tsvector.c:219 +#: utils/adt/tsvector.c:221 #, c-format msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "tsベクターã®ãŸã‚ã®æ–‡å­—列ãŒé•·ã™ãŽã¾ã™(%ldãƒã‚¤ãƒˆã€æœ€å¤§ã¯%ldãƒã‚¤ãƒˆ)" -#: utils/adt/tsvector_op.c:1173 +#: utils/adt/tsvector_op.c:323 utils/adt/tsvector_op.c:610 +#: utils/adt/tsvector_op.c:778 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "語彙素é…列ã«ã¯nullã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" + +#: utils/adt/tsvector_op.c:853 +#, c-format +msgid "weight array may not contain nulls" +msgstr "é‡ã¿ä»˜ã‘é…列ã«ã¯nullã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" + +#: utils/adt/tsvector_op.c:877 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "識別ä¸èƒ½ãªé‡ã¿ä»˜ã‘: \"%c\"" + +#: utils/adt/tsvector_op.c:2314 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "ts_statã¯1ã¤ã®tsvector列ã®ã¿ã‚’è¿”ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1353 +#: utils/adt/tsvector_op.c:2496 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "tsvector列\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1359 +#: utils/adt/tsvector_op.c:2503 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "値\"%s\"ã¯åž‹tsvectorã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1371 +#: utils/adt/tsvector_op.c:2515 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "設定列\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1377 +#: utils/adt/tsvector_op.c:2521 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "%s列ã¯regconfigåž‹ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1384 +#: utils/adt/tsvector_op.c:2528 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "設定列\"%s\"ã‚’NULLã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1397 +#: utils/adt/tsvector_op.c:2541 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "テキスト検索設定åç§°\"%s\"ã¯ã‚¹ã‚­ãƒ¼ãƒžä¿®é£¾ã—ãªã‘れナãƒã‚Šã¾ã›ã‚“" -#: utils/adt/tsvector_op.c:1422 +#: utils/adt/tsvector_op.c:2566 #, c-format msgid "column \"%s\" is not of a character type" -msgstr "カラム \"%s\" ã¯æ–‡å­—åž‹ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "列 \"%s\" ã¯æ–‡å­—åž‹ã§ã¯ã‚りã¾ã›ã‚“" #: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "tsvectorå†…ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼: %s" -#: utils/adt/tsvector_parser.c:199 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "エスケープ文字ãŒã‚りã¾ã›ã‚“: \"%s\"" -#: utils/adt/tsvector_parser.c:316 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "tsvector内ã®ä½ç½®æƒ…å ±ãŒé–“é•ã£ã¦ã„ã¾ã™: \"%s\"" -#: utils/adt/uuid.c:128 +#: utils/adt/txid.c:135 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "トランザクションID%sã¯æœªæ¥ã§ã™" + +#: utils/adt/txid.c:624 #, c-format -msgid "invalid input syntax for uuid: \"%s\"" -msgstr "uuidã®å…¥åŠ›æ§‹æ–‡ãŒç„¡åйã§ã™: \"%s\"" +msgid "invalid external txid_snapshot data" +msgstr "䏿­£ãªå¤–部txid_snapshotデータ" -#: utils/adt/varbit.c:57 utils/adt/varchar.c:49 +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 #, c-format msgid "length for type %s must be at least 1" msgstr "åž‹%sã®é•·ã•ã¯æœ€ä½Žã§ã‚‚1ã§ã™" -#: utils/adt/varbit.c:62 utils/adt/varchar.c:53 +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 #, c-format msgid "length for type %s cannot exceed %d" msgstr "åž‹%sã®é•·ã•ã¯%dã‚’è¶…ãˆã‚‰ã‚Œã¾ã›ã‚“" -#: utils/adt/varbit.c:167 utils/adt/varbit.c:310 utils/adt/varbit.c:367 +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "ビット列ã®é•·ã•ãŒä¸Šé™å€¤ã‚’è¶…ãˆã¦ã„ã¾ã™(%d)" + +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 #, c-format msgid "bit string length %d does not match type bit(%d)" -msgstr "ビット文字列長%dã¯bit(%d)ã«ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "ビット列長%dãŒåž‹bit(%d)ã«ä¸€è‡´ã—ã¾ã›ã‚“" -#: utils/adt/varbit.c:189 utils/adt/varbit.c:491 +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "\"%c\"ã¯æœ‰åйãª2進数表ç¾ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/varbit.c:214 utils/adt/varbit.c:516 +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "\"%c\"ã¯æœ‰åйãª16進数表ç¾ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/varbit.c:301 utils/adt/varbit.c:604 +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 #, c-format msgid "invalid length in external bit string" -msgstr "ビット文字列ã®å¤–部表ç¾ã®é•·ã•ãŒç„¡åйã§ã™" +msgstr "ビット列ã®å¤–部値ã®ä¸æ­£ãªé•·ã•" -#: utils/adt/varbit.c:469 utils/adt/varbit.c:613 utils/adt/varbit.c:708 +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 #, c-format msgid "bit string too long for type bit varying(%d)" -msgstr "ビット文字列ã¯åž‹bit varying(%d)ã«ã¯é•·ã™ãŽã¾ã™" +msgstr "ビット列ã¯åž‹bit varying(%d)ã«ã¯é•·ã™ãŽã¾ã™" -#: utils/adt/varbit.c:1038 utils/adt/varbit.c:1140 utils/adt/varlena.c:800 -#: utils/adt/varlena.c:864 utils/adt/varlena.c:1008 utils/adt/varlena.c:1964 -#: utils/adt/varlena.c:2031 +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 +#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 +#: utils/adt/varlena.c:2979 #, c-format msgid "negative substring length not allowed" -msgstr "è² ã®é•·ã•ã®substringã¯ã§ãã¾ã›ã‚“" +msgstr "è² ã®é•·ã•ã®substringã¯è¨±ã•れã¾ã›ã‚“" -#: utils/adt/varbit.c:1198 +#: utils/adt/varbit.c:1226 #, c-format msgid "cannot AND bit strings of different sizes" -msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット文字列ã®ANDã¯ã§ãã¾ã›ã‚“" +msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット列ã®ANDã¯ã§ãã¾ã›ã‚“" -#: utils/adt/varbit.c:1240 +#: utils/adt/varbit.c:1268 #, c-format msgid "cannot OR bit strings of different sizes" -msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット文字列ã®ORã¯ã§ãã¾ã›ã‚“" +msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット列ã®ORã¯ã§ãã¾ã›ã‚“" -#: utils/adt/varbit.c:1287 +#: utils/adt/varbit.c:1315 #, c-format msgid "cannot XOR bit strings of different sizes" -msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット文字列ã®XORã¯ã§ãã¾ã›ã‚“" +msgstr "サイズãŒç•°ãªã‚‹ãƒ“ット列ã®XORã¯ã§ãã¾ã›ã‚“" -#: utils/adt/varbit.c:1765 utils/adt/varbit.c:1823 +#: utils/adt/varbit.c:1803 utils/adt/varbit.c:1861 #, c-format msgid "bit index %d out of valid range (0..%d)" -msgstr "ビット型インデックス %d ãŒæœ‰åŠ¹ç¯„å›² 0 ã‹ã‚‰ %d ã¾ã§ã®é–“ã«ã‚りã¾ã›ã‚“" +msgstr "ビットã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹%dãŒæœ‰åŠ¹ç¯„å›²0..%dã®é–“ã«ã‚りã¾ã›ã‚“" -#: utils/adt/varbit.c:1774 utils/adt/varlena.c:2231 +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 #, c-format msgid "new bit must be 0 or 1" -msgstr "æ–°ã—ã„ビット㯠0 ã‹ 1 ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "æ–°ã—ã„ビットã¯0ã‹1ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/varchar.c:153 utils/adt/varchar.c:306 +#: utils/adt/varchar.c:155 utils/adt/varchar.c:308 #, c-format msgid "value too long for type character(%d)" msgstr "値ã¯åž‹character(%d)ã¨ã—ã¦ã¯é•·ã™ãŽã¾ã™" -#: utils/adt/varchar.c:468 utils/adt/varchar.c:622 +#: utils/adt/varchar.c:470 utils/adt/varchar.c:623 #, c-format msgid "value too long for type character varying(%d)" msgstr "値ã¯åž‹character varying(%d)ã¨ã—ã¦ã¯é•·ã™ãŽã¾ã™" -#: utils/adt/varlena.c:1380 +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 #, c-format msgid "could not determine which collation to use for string comparison" -msgstr "文字列比較ã«ãŠã„ã¦ã©ã®ç…§åˆé †åºã‚’é©ç”¨ã™ã¹ãã‹ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "文字列比較ã§ä½¿ç”¨ã™ã‚‹ç…§åˆé †åºã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/varlena.c:1426 utils/adt/varlena.c:1439 +#: utils/adt/varlena.c:1472 utils/adt/varlena.c:1485 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "文字列をUTF-16ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu" -#: utils/adt/varlena.c:1454 +#: utils/adt/varlena.c:1500 #, c-format msgid "could not compare Unicode strings: %m" msgstr "Unicode文字列を比較ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/adt/varlena.c:2109 utils/adt/varlena.c:2140 utils/adt/varlena.c:2176 -#: utils/adt/varlena.c:2219 +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 +#, c-format +msgid "collation failed: %s" +msgstr "ç…§åˆé †åºã«ã‚ˆã‚‹æ¯”較ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: utils/adt/varlena.c:2394 +#, c-format +msgid "sort key generation failed: %s" +msgstr "ソートキーã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 +#: utils/adt/varlena.c:3158 #, c-format msgid "index %d out of valid range, 0..%d" -msgstr "インデックス%dã¯æœ‰åŠ¹ç¯„å›²0ã‹ã‚‰%dã¾ã§ã®é–“ã«ã‚りã¾ã›ã‚“" +msgstr "インデックス%dã¯æœ‰åŠ¹ç¯„å›²0..%dã®é–“ã«ã‚りã¾ã›ã‚“" -#: utils/adt/varlena.c:3137 +#: utils/adt/varlena.c:4201 #, c-format msgid "field position must be greater than zero" msgstr "フィールドä½ç½®ã¯0より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/varlena.c:4017 +#: utils/adt/varlena.c:5080 +#, c-format +msgid "unterminated format() type specifier" +msgstr "終端ã•れã¦ã„ãªã„format()型指定å­" + +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 #, c-format -#| msgid "unterminated conversion specifier" -msgid "unterminated format specifier" -msgstr "æ›¸å¼æŒ‡å®šå­ã®çµ‚端ãŒã‚りã¾ã›ã‚“" +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "一ã¤ã®\"%%\"ã«ã¯\"%%%%\"を使ã£ã¦ãã ã•ã„。" -#: utils/adt/varlena.c:4150 utils/adt/varlena.c:4270 +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 #, c-format -#| msgid "unrecognized conversion specifier \"%c\"" -msgid "unrecognized conversion type specifier \"%c\"" -msgstr "変æ›åž‹æŒ‡ç¤ºå­ãŒèªè­˜ã§ãã¾ã›ã‚“: \"%c\"" +msgid "unrecognized format() type specifier \"%c\"" +msgstr "èªè­˜ã§ããªã„変æ›åž‹æŒ‡ç¤ºå­: \"%c\"" -#: utils/adt/varlena.c:4162 utils/adt/varlena.c:4219 +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 #, c-format -msgid "too few arguments for format" -msgstr "書å¼ç”¨ã®å¼•æ•°ãŒå°‘ãªã™ãŽã¾ã™" +msgid "too few arguments for format()" +msgstr "format()ã®å¼•æ•°ãŒå°‘ãªã™ãŽã¾ã™" -#: utils/adt/varlena.c:4313 utils/adt/varlena.c:4496 +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 #, c-format -#| msgid "input is out of range" msgid "number is out of range" msgstr "数値ãŒç¯„囲外ã§ã™" -#: utils/adt/varlena.c:4377 utils/adt/varlena.c:4405 +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 #, c-format -#| msgid "conversion specifies argument 0, but arguments are numbered from 1" msgid "format specifies argument 0, but arguments are numbered from 1" -msgstr "書å¼ã¯å¼•æ•° 0 を指定ã—ã¦ã„ã¾ã™ãŒã€å¼•数㌠1 ã‹ã‚‰å§‹ã¾ã£ã¦ã„ã¾ã™" +msgstr "書å¼ã¯å¼•æ•°0を指定ã—ã¦ã„ã¾ã™ãŒã€å¼•æ•°ãŒ1ã‹ã‚‰å§‹ã¾ã£ã¦ã„ã¾ã™" -#: utils/adt/varlena.c:4398 +#: utils/adt/varlena.c:5463 #, c-format -#| msgid "third argument of cast function must be type boolean" msgid "width argument position must be ended by \"$\"" msgstr "width引数ã®ä½ç½®ã¯\"$\"ã§çµ‚ã‚らãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/varlena.c:4443 +#: utils/adt/varlena.c:5508 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "NULLã¯SQL識別å­ã¨ã—ã¦æ›¸å¼ä»˜ã‘ã§ãã¾ã›ã‚“" @@ -17540,234 +23160,254 @@ msgstr "NULLã¯SQL識別å­ã¨ã—ã¦æ›¸å¼ä»˜ã‘ã§ãã¾ã›ã‚“" #: utils/adt/windowfuncs.c:243 #, c-format msgid "argument of ntile must be greater than zero" -msgstr "ntile カウントã¯0より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "ntileã®å€¤ã¯0より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" #: utils/adt/windowfuncs.c:465 #, c-format msgid "argument of nth_value must be greater than zero" -msgstr "nth_value 引数㯠0 より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "nth_valueã®å€¤0より大ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/adt/xml.c:170 +#: utils/adt/xml.c:220 #, c-format msgid "unsupported XML feature" msgstr "未サãƒãƒ¼ãƒˆã®XML機能ã§ã™ã€‚" -#: utils/adt/xml.c:171 +#: utils/adt/xml.c:221 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "ã“ã®æ©Ÿèƒ½ã¯libxmlサãƒãƒ¼ãƒˆã‚’付ã‘ãŸã‚µãƒ¼ãƒãŒå¿…è¦ã§ã™ã€‚" -#: utils/adt/xml.c:172 +#: utils/adt/xml.c:222 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." -msgstr "--with-libxmlを使用ã—ã¦PostgreSQLã‚’å†æ§‹ç¯‰ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "--with-libxmlを使用ã—ã¦PostgreSQLã‚’å†æ§‹ç¯‰ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" -#: utils/adt/xml.c:191 utils/mb/mbutils.c:515 +#: utils/adt/xml.c:241 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" -msgstr "符å·åŒ–æ–¹å¼å\"%s\"ãŒç„¡åйã§ã™" +msgstr "䏿­£ãªç¬¦å·åŒ–æ–¹å¼å\"%s\"" -#: utils/adt/xml.c:437 utils/adt/xml.c:442 +#: utils/adt/xml.c:484 utils/adt/xml.c:489 #, c-format msgid "invalid XML comment" -msgstr "無効ãªXMLコメントã§ã™" +msgstr "無効ãªXMLコメント" -#: utils/adt/xml.c:571 +#: utils/adt/xml.c:618 #, c-format msgid "not an XML document" msgstr "XML文書ã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/xml.c:730 utils/adt/xml.c:753 +#: utils/adt/xml.c:777 utils/adt/xml.c:800 #, c-format msgid "invalid XML processing instruction" msgstr "無効ãªXML処ç†å‘½ä»¤ã§ã™" -#: utils/adt/xml.c:731 +#: utils/adt/xml.c:778 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "XML処ç†å‘½ä»¤ã®å¯¾è±¡åã‚’\"%s\"ã¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" -#: utils/adt/xml.c:754 +#: utils/adt/xml.c:801 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "XML処ç†å‘½ä»¤ã«ã¯\"?>\"ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" -#: utils/adt/xml.c:833 +#: utils/adt/xml.c:880 #, c-format msgid "xmlvalidate is not implemented" msgstr "XML ã®å¦¥å½“性検査ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/adt/xml.c:912 +#: utils/adt/xml.c:959 #, c-format msgid "could not initialize XML library" msgstr "XMLãƒ©ã‚¤ãƒ–ãƒ©ãƒªã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/xml.c:913 +#: utils/adt/xml.c:960 #, c-format msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "libxml2ãŒäº’æ›æ€§ãŒãªã„文字型をæŒã¡ã¾ã™: sizeof(char)=%uã€sizeof(xmlChar)=%u" -#: utils/adt/xml.c:999 +#: utils/adt/xml.c:1046 #, c-format msgid "could not set up XML error handler" msgstr "XMLエラーãƒãƒ³ãƒ‰ãƒ©ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/adt/xml.c:1000 +#: utils/adt/xml.c:1047 #, c-format msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." msgstr "ã“れã¯ãŠãらã使用ã™ã‚‹libxml2ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒPostgreSQLを構築ã™ã‚‹æ™‚ã«ä½¿ç”¨ã—ãŸlibxml2ヘッダã¨äº’æ›æ€§ãŒãªã„ã“ã¨ã‚’示ã—ã¾ã™ã€‚" -#: utils/adt/xml.c:1735 +#: utils/adt/xml.c:1797 msgid "Invalid character value." msgstr "文字ã®å€¤ãŒæœ‰åйã§ã¯ã‚りã¾ã›ã‚“" -#: utils/adt/xml.c:1738 +#: utils/adt/xml.c:1800 msgid "Space required." -msgstr "スペースをã‚ã‘ã¦ãã ã•ã„" +msgstr "スペースをã‚ã‘ã¦ãã ã•ã„。" -#: utils/adt/xml.c:1741 +#: utils/adt/xml.c:1803 msgid "standalone accepts only 'yes' or 'no'." -msgstr "standalone ã«ã¯ 'yes' ã‹ 'no' ã ã‘ãŒæœ‰åйã§ã™" +msgstr "standalone ã«ã¯ 'yes' ã‹ 'no' ã ã‘ãŒæœ‰åйã§ã™ã€‚" -#: utils/adt/xml.c:1744 +#: utils/adt/xml.c:1806 msgid "Malformed declaration: missing version." -msgstr "宣言ãŒèª¤ã£ã¦ã„ã¾ã™ï¼šãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“" +msgstr "䏿­£ãªå½¢å¼ã®å®£è¨€: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒã‚りã¾ã›ã‚“。" -#: utils/adt/xml.c:1747 +#: utils/adt/xml.c:1809 msgid "Missing encoding in text declaration." -msgstr "テキスト宣言ã«ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“" +msgstr "テキスト宣言ã«ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã®æŒ‡å®šãŒã‚りã¾ã›ã‚“。" -#: utils/adt/xml.c:1750 +#: utils/adt/xml.c:1812 msgid "Parsing XML declaration: '?>' expected." -msgstr "XML 宣言ã®ãƒ‘ース中: '>?' ãŒå¿…è¦ã§ã™ã€‚" +msgstr "XML 宣言ã®ãƒ‘ース中: '>?' ãŒå¿…è¦ã§ã™ã€‚" -#: utils/adt/xml.c:1753 +#: utils/adt/xml.c:1815 #, c-format msgid "Unrecognized libxml error code: %d." -msgstr "libxml ã®ã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ã‚’èªè­˜ã§ãã¾ã›ã‚“: %d" +msgstr "èªè­˜ã§ããªã„libxml ã®ã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰: %d" -#: utils/adt/xml.c:2034 +#: utils/adt/xml.c:2090 #, c-format msgid "XML does not support infinite date values." -msgstr "XMLã¯ç„¡é™ã®ãƒ‡ãƒ¼ã‚¿å€¤ã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“。" +msgstr "XMLã¯ãƒ‡ãƒ¼ã‚¿å€¤ã¨ã—ã¦ç„¡é™ã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“。" -#: utils/adt/xml.c:2056 utils/adt/xml.c:2083 +#: utils/adt/xml.c:2112 utils/adt/xml.c:2139 #, c-format msgid "XML does not support infinite timestamp values." -msgstr "XMLã¯ç„¡é™ã®ã‚¿ã‚¤ãƒ ã‚¹ã‚¿ãƒ³ãƒ—値をサãƒãƒ¼ãƒˆã—ã¾ã›ã‚“。" +msgstr "XMLタイムスタンプ値ã¨ã—ã¦ã¯ç„¡é™ã‚’サãƒãƒ¼ãƒˆã—ã¾ã›ã‚“。" -#: utils/adt/xml.c:2474 +#: utils/adt/xml.c:2551 #, c-format msgid "invalid query" -msgstr "無効ãªå•ã„åˆã‚ã›ã§ã™" +msgstr "䏿­£ãªç„¡åйãªå•ã„åˆã‚ã›" -#: utils/adt/xml.c:3789 +#: utils/adt/xml.c:3874 #, c-format msgid "invalid array for XML namespace mapping" -msgstr "XMLåå‰ç©ºé–“マッピング用ã®é…列ãŒç„¡åйã§ã™" +msgstr "XMLåå‰ç©ºé–“マッピングã«å¯¾ã™ã‚‹ä¸æ­£ãªé…列" -#: utils/adt/xml.c:3790 +#: utils/adt/xml.c:3875 #, c-format msgid "The array must be two-dimensional with length of the second axis equal to 2." -msgstr "é…列ã¯ç¬¬2軸ã®é•·ã•ãŒ2ã®ã€2次元é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +msgstr "ã“ã®é…列ã¯ç¬¬2軸ã®é•·ã•ãŒ2ã§ã‚ã‚‹2次元é…列ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/adt/xml.c:3814 +#: utils/adt/xml.c:3899 #, c-format msgid "empty XPath expression" -msgstr "XPathå¼ãŒç©ºã§ã™" +msgstr "空ã®XPathå¼" -#: utils/adt/xml.c:3863 +#: utils/adt/xml.c:3951 #, c-format msgid "neither namespace name nor URI may be null" -msgstr "åå‰ç©ºé–“ã®åå‰ãŒURIã§ã‚‚空ã§ã‚‚ã‚りã¾ã›ã‚“" +msgstr "åå‰ç©ºé–“åã‚‚URIã‚‚nullã«ã¯ã§ãã¾ã›ã‚“" -#: utils/adt/xml.c:3870 +#: utils/adt/xml.c:3958 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" -msgstr "\"%s\"ã¨ã„ã†åå‰ã®XMLåå‰ç©ºé–“ãŠã‚ˆã³URI\"%s\"を登録ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" +msgstr "\"%s\"ã¨ã„ã†åå‰ã®XMLåå‰ç©ºé–“ãŠã‚ˆã³URI\"%s\"を登録ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/cache/lsyscache.c:2459 utils/cache/lsyscache.c:2492 -#: utils/cache/lsyscache.c:2525 utils/cache/lsyscache.c:2558 +#: utils/adt/xml.c:4309 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "デフォルトåå‰ç©ºé–“ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" + +#: utils/adt/xml.c:4338 +#, c-format +msgid "row path filter must not be empty string" +msgstr "行パスフィルタã¯ç©ºæ–‡å­—列ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/xml.c:4369 +#, c-format +msgid "column path filter must not be empty string" +msgstr "列パスフィルタ空文字列ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" + +#: utils/adt/xml.c:4555 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "列XPathå¼ãŒ2ã¤ä»¥ä¸Šã®å€¤ã‚’è¿”å´ã—ã¾ã—ãŸ" + +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "åž‹%sã¯å˜ãªã‚‹ã‚·ã‚§ãƒ«ã§ã™" -#: utils/cache/lsyscache.c:2464 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "åž‹%sã®åˆ©ç”¨å¯èƒ½ãªå…¥åŠ›é–¢æ•°ãŒã‚りã¾ã›ã‚“" -#: utils/cache/lsyscache.c:2497 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "åž‹%sã®åˆ©ç”¨å¯èƒ½ãªå‡ºåŠ›é–¢æ•°ãŒã‚りã¾ã›ã‚“" -#: utils/cache/plancache.c:695 +#: utils/cache/partcache.c:202 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "アクセスメソッド %2$s ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹\"%1$s\"ã¯%4$såž‹ã«å¯¾å¿œã™ã‚‹ã‚µãƒãƒ¼ãƒˆé–¢æ•°%3$dã‚’å«ã‚“ã§ã„ã¾ã›ã‚“" + +#: utils/cache/plancache.c:723 #, c-format msgid "cached plan must not change result type" -msgstr "キャッシュã—ãŸè¨ˆç”»ã¯çµæžœåž‹ã‚’変更ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" +msgstr "キャッシュã—ãŸå®Ÿè¡Œè¨ˆç”»ã¯çµæžœåž‹ã‚’変更ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: utils/cache/relcache.c:4543 +#: utils/cache/relcache.c:5829 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚­ãƒ£ãƒƒã‚·ãƒ¥åˆæœŸåŒ–ファイル\"%sを作æˆã§ãã¾ã›ã‚“: %m" -#: utils/cache/relcache.c:4545 +#: utils/cache/relcache.c:5831 #, c-format msgid "Continuing anyway, but there's something wrong." -msgstr "ã¨ã‚Šã‚ãˆãšç¶šè¡Œã—ã¾ã™ãŒã€ä½•ã‹ãŒé–“é•ã£ã¦ã„ã¾ã™" +msgstr "ã¨ã‚Šã‚ãˆãšç¶šè¡Œã—ã¾ã™ãŒã€ä½•ã‹ãŒãŠã‹ã—ã„ã§ã™ã€‚" -#: utils/cache/relcache.c:4759 +#: utils/cache/relcache.c:6185 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "キャッシュファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/cache/relmapper.c:506 +#: utils/cache/relmapper.c:513 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" -msgstr "リレーションã®ãƒžãƒƒãƒ”ングを変更ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ PREPARE ã§ãã¾ã›ã‚“" +msgstr "リレーションã®ãƒžãƒƒãƒ”ングを変更ã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯PREPAREã§ãã¾ã›ã‚“" -#: utils/cache/relmapper.c:649 utils/cache/relmapper.c:749 +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 #, c-format msgid "could not open relation mapping file \"%s\": %m" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" をオープンã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/cache/relmapper.c:662 +#: utils/cache/relmapper.c:669 #, c-format msgid "could not read relation mapping file \"%s\": %m" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/cache/relmapper.c:672 +#: utils/cache/relmapper.c:680 #, c-format msgid "relation mapping file \"%s\" contains invalid data" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã«ç„¡åйãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã«ä¸æ­£ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" -#: utils/cache/relmapper.c:682 +#: utils/cache/relmapper.c:690 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã®ä¸­ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒæ­£ã—ãã‚りã¾ã›ã‚“" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã®ä¸­ã«ä¸æ­£ãªãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒã‚りã¾ã™" -#: utils/cache/relmapper.c:788 +#: utils/cache/relmapper.c:789 #, c-format msgid "could not write to relation mapping file \"%s\": %m" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" を書ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" を書ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/cache/relmapper.c:801 +#: utils/cache/relmapper.c:804 #, c-format msgid "could not fsync relation mapping file \"%s\": %m" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" ã‚’ fsync ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\"ã®fsyncã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/cache/relmapper.c:807 +#: utils/cache/relmapper.c:811 #, c-format msgid "could not close relation mapping file \"%s\": %m" -msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\" をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: utils/cache/typcache.c:704 -#, c-format -msgid "type %s is not composite" -msgstr "åž‹%sã¯è¤‡åˆåž‹ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "リレーションã®ãƒžãƒƒãƒ”ング用ファイル \"%s\"ã®ã‚¯ãƒ­ãƒ¼ã‚ºã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/cache/typcache.c:718 +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 #, c-format msgid "record type has not been registered" msgstr "レコード型ã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“" @@ -17775,1905 +23415,2310 @@ msgstr "レコード型ã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“" #: utils/error/assert.c:34 #, c-format msgid "TRAP: ExceptionalCondition: bad arguments\n" -msgstr "TRAP: ExceptionalCondition: ä¸è‰¯ãªå¼•æ•°\n" +msgstr "TRAP: ExceptionalCondition: 䏿­£ãªå¼•æ•°\n" #: utils/error/assert.c:37 #, c-format msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" -msgstr "TRAP: %s(\\\"%s\\\", ファイル: \\\"%s\\\", 行数: %d)\n" +msgstr "TRAP: %s(\"%s\", ファイル: \"%s\", 行: %d)\n" + +#: utils/error/elog.c:322 utils/error/elog.c:1304 +#, c-format +msgid "error occurred at %s:%d before error message processing is available\n" +msgstr "エラーメッセージã®å‡¦ç†ãŒå¯èƒ½ã«ãªã‚‹å‰ã«ã‚¨ãƒ©ãƒ¼ãŒ%s:%dã§ç™ºç”Ÿã—ã¾ã—ãŸ\n" -#: utils/error/elog.c:1749 +#: utils/error/elog.c:1882 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" -msgstr "ファイル\"%s\"を標準エラーã¨ã—ã¦å†ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "ファイル\"%s\"ã®æ¨™æº–エラー出力ã¨ã—ã¦ã®å†ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/error/elog.c:1762 +#: utils/error/elog.c:1895 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" -msgstr "ファイル\"%s\"を標準出力ã¨ã—ã¦å†ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "ファイル\"%s\"ã®æ¨™æº–出力ã¨ã—ã¦ã®å†ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ: %m" -#: utils/error/elog.c:2178 utils/error/elog.c:2188 utils/error/elog.c:2198 +#: utils/error/elog.c:2387 utils/error/elog.c:2404 utils/error/elog.c:2420 msgid "[unknown]" -msgstr "[unknown]" +msgstr "[䏿˜Ž]" -#: utils/error/elog.c:2546 utils/error/elog.c:2845 utils/error/elog.c:2953 +#: utils/error/elog.c:2880 utils/error/elog.c:3183 utils/error/elog.c:3291 msgid "missing error text" msgstr "エラーテキストãŒã‚りã¾ã›ã‚“" -#: utils/error/elog.c:2549 utils/error/elog.c:2552 utils/error/elog.c:2956 -#: utils/error/elog.c:2959 +#: utils/error/elog.c:2883 utils/error/elog.c:2886 utils/error/elog.c:3294 +#: utils/error/elog.c:3297 #, c-format msgid " at character %d" -msgstr "(文字ä½ç½® %d)" +msgstr "(%d文字目)" -#: utils/error/elog.c:2562 utils/error/elog.c:2569 +#: utils/error/elog.c:2896 utils/error/elog.c:2903 msgid "DETAIL: " msgstr "詳細: " -#: utils/error/elog.c:2576 +#: utils/error/elog.c:2910 msgid "HINT: " msgstr "ヒント: " -#: utils/error/elog.c:2583 +#: utils/error/elog.c:2917 msgid "QUERY: " -msgstr "クエリー: " +msgstr "å•ã„åˆã‚ã›: " -#: utils/error/elog.c:2590 +#: utils/error/elog.c:2924 msgid "CONTEXT: " -msgstr "コンテキスト: " +msgstr "文脈: " -#: utils/error/elog.c:2600 +#: utils/error/elog.c:2934 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "場所: %s, %s:%d\n" -#: utils/error/elog.c:2607 +#: utils/error/elog.c:2941 #, c-format msgid "LOCATION: %s:%d\n" msgstr "場所: %s:%d\n" -#: utils/error/elog.c:2621 +#: utils/error/elog.c:2955 msgid "STATEMENT: " -msgstr "ステートメント: " +msgstr "æ–‡: " #. translator: This string will be truncated at 47 #. characters expanded. -#: utils/error/elog.c:3068 +#: utils/error/elog.c:3412 #, c-format msgid "operating system error %d" msgstr "オペレーティングシステムエラー %d" -#: utils/error/elog.c:3091 +#: utils/error/elog.c:3610 msgid "DEBUG" msgstr "DEBUG" -#: utils/error/elog.c:3095 +#: utils/error/elog.c:3614 msgid "LOG" msgstr "LOG" -#: utils/error/elog.c:3098 +#: utils/error/elog.c:3617 msgid "INFO" msgstr "INFO" -#: utils/error/elog.c:3101 +#: utils/error/elog.c:3620 msgid "NOTICE" msgstr "NOTICE" -#: utils/error/elog.c:3104 +#: utils/error/elog.c:3623 msgid "WARNING" msgstr "WARNING" -#: utils/error/elog.c:3107 +#: utils/error/elog.c:3626 msgid "ERROR" msgstr "ERROR" -#: utils/error/elog.c:3110 +#: utils/error/elog.c:3629 msgid "FATAL" msgstr "FATAL" -#: utils/error/elog.c:3113 +#: utils/error/elog.c:3632 msgid "PANIC" msgstr "PANIC" -#: utils/fmgr/dfmgr.c:125 +#: utils/fmgr/dfmgr.c:121 #, c-format msgid "could not find function \"%s\" in file \"%s\"" msgstr "ファイル\"%2$s\"内ã«é–¢æ•°\"%1$s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: utils/fmgr/dfmgr.c:204 utils/fmgr/dfmgr.c:413 utils/fmgr/dfmgr.c:461 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "ファイル\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#: utils/fmgr/dfmgr.c:242 +#: utils/fmgr/dfmgr.c:239 #, c-format msgid "could not load library \"%s\": %s" msgstr "ライブラリ\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: utils/fmgr/dfmgr.c:274 +#: utils/fmgr/dfmgr.c:271 #, c-format msgid "incompatible library \"%s\": missing magic block" msgstr "\"%s\"ã¯äº’æ›æ€§ãŒãªã„ライブラリã§ã™ã€‚ãƒžã‚¸ãƒƒã‚¯ãƒ–ãƒ­ãƒƒã‚¯ã®æ¬ è½" -#: utils/fmgr/dfmgr.c:276 +#: utils/fmgr/dfmgr.c:273 #, c-format msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." msgstr "拡張ライブラリã¯PG_MODULE_MAGICマクロを使用ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: utils/fmgr/dfmgr.c:312 +#: utils/fmgr/dfmgr.c:319 #, c-format msgid "incompatible library \"%s\": version mismatch" msgstr "\"%s\"ã¯äº’æ›æ€§ãŒãªã„ライブラリã§ã™: ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´" -#: utils/fmgr/dfmgr.c:314 +#: utils/fmgr/dfmgr.c:321 #, c-format -msgid "Server is version %d.%d, library is version %d.%d." -msgstr "サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%d.%dã€ãƒ©ã‚¤ãƒ–ラリã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯%d.%d<ã§ã™ã€‚" +msgid "Server is version %d, library is version %s." +msgstr "サーãƒã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%dã€ãƒ©ã‚¤ãƒ–ラリã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã§ã™ã€‚" -#: utils/fmgr/dfmgr.c:333 +#: utils/fmgr/dfmgr.c:338 #, c-format msgid "Server has FUNC_MAX_ARGS = %d, library has %d." msgstr "サーãƒå´ã¯ FUNC_MAX_ARGS = %d ã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ラリå´ã¯ %d ã§ã™" -#: utils/fmgr/dfmgr.c:342 +#: utils/fmgr/dfmgr.c:347 #, c-format msgid "Server has INDEX_MAX_KEYS = %d, library has %d." msgstr "サーãƒå´ã¯ INDEX_MAX_KEYS = %d ã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ラリå´ã¯ %d ã§ã™" -#: utils/fmgr/dfmgr.c:351 +#: utils/fmgr/dfmgr.c:356 #, c-format msgid "Server has NAMEDATALEN = %d, library has %d." msgstr "サーãƒå´ã¯ NAMEDATALEN = %d ã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ラリå´ã¯ %d ã§ã™" -#: utils/fmgr/dfmgr.c:360 +#: utils/fmgr/dfmgr.c:365 #, c-format msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." msgstr "サーãƒå´ã¯FLOAT4PASSBYVAL = %sã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ラリå´ã¯%sã§ã™ã€‚" -#: utils/fmgr/dfmgr.c:369 +#: utils/fmgr/dfmgr.c:374 #, c-format msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." msgstr "サーãƒå´ã¯FLOAT8PASSBYVAL = %sã§ã™ãŒã€ãƒ©ã‚¤ãƒ–ラリå´ã¯%sã§ã™ã€‚" -#: utils/fmgr/dfmgr.c:376 +#: utils/fmgr/dfmgr.c:381 msgid "Magic block has unexpected length or padding difference." msgstr "ãƒžã‚¸ãƒƒã‚¯ãƒ–ãƒ­ãƒƒã‚¯ãŒæ„図ã—ãªã„é•·ã•ã§ã‚ã‚‹ã‹ã€ã¾ãŸã¯ãƒ‘ディングãŒç•°ãªã‚Šã¾ã™ã€‚" -#: utils/fmgr/dfmgr.c:379 +#: utils/fmgr/dfmgr.c:384 #, c-format msgid "incompatible library \"%s\": magic block mismatch" msgstr "\"%s\"ã¯äº’æ›æ€§ãŒãªã„ライブラリã§ã™: マジックブロックã®ä¸ä¸€è‡´" -#: utils/fmgr/dfmgr.c:545 +#: utils/fmgr/dfmgr.c:548 #, c-format msgid "access to library \"%s\" is not allowed" msgstr "ライブラリ\"%s\"ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ã¯è¨±ã•れã¦ã„ã¾ã›ã‚“" -#: utils/fmgr/dfmgr.c:572 +#: utils/fmgr/dfmgr.c:574 #, c-format msgid "invalid macro name in dynamic library path: %s" -msgstr "ダイナミックライブラリパス内ã®ãƒžã‚¯ãƒ­ãŒç„¡åйã§ã™: %s" +msgstr "ダイナミックライブラリパス内ã®ãƒžã‚¯ãƒ­ãŒä¸æ­£ã§ã™: %s" -#: utils/fmgr/dfmgr.c:617 +#: utils/fmgr/dfmgr.c:614 #, c-format msgid "zero-length component in parameter \"dynamic_library_path\"" msgstr "パラメータ\"dynamic_library_path\"内ã«é•·ã•ãŒ0ã®è¦ç´ ãŒã‚りã¾ã™" -#: utils/fmgr/dfmgr.c:636 +#: utils/fmgr/dfmgr.c:633 #, c-format msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "パラメータ\"dynamic_library_path\"内ã®è¦ç´ ãŒçµ¶å¯¾ãƒ‘スã§ã‚りã¾ã›ã‚“" -#: utils/fmgr/fmgr.c:271 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "内部関数\"%s\"ã¯å†…部用検索テーブルã«ã‚りã¾ã›ã‚“" -#: utils/fmgr/fmgr.c:481 +#: utils/fmgr/fmgr.c:485 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "関数\"%s\"ã®é–¢æ•°æƒ…å ±ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "SQL呼ã³å‡ºã—å¯èƒ½ãªé–¢æ•°ã«ã¯PG_FUNCTION_INFO_V1(funcname)宣言ãŒå¿…è¦ã§ã™" + +#: utils/fmgr/fmgr.c:505 #, c-format msgid "unrecognized API version %d reported by info function \"%s\"" msgstr "info関数\"%2$s\"ã§å ±å‘Šã•れãŸAPIãƒãƒ¼ã‚¸ãƒ§ãƒ³%1$dãŒä¸æ˜Žã§ã™" -#: utils/fmgr/fmgr.c:852 utils/fmgr/fmgr.c:2113 +#: utils/fmgr/fmgr.c:2210 #, c-format -msgid "function %u has too many arguments (%d, maximum is %d)" -msgstr "関数%uã®å¼•æ•°ãŒå¤šã™ãŽã¾ã™(%d。最大ã¯%d)" +msgid "language validation function %u called for language %u instead of %u" +msgstr "言語有効性検査関数%1$uãŒè¨€èªž%3$uã§ã¯ãªã%2$uã«å¯¾ã—ã¦å‘¼ã³å‡ºã•れã¾ã—ãŸ" -#: utils/fmgr/funcapi.c:355 +#: utils/fmgr/funcapi.c:358 #, c-format msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "戻り値型%2$sã¨ã—ã¦å®£è¨€ã•れãŸé–¢æ•°\"%1$s\"ã®å®Ÿéš›ã®çµæžœåž‹ã‚’決定ã§ãã¾ã›ã‚“" -#: utils/fmgr/funcapi.c:1301 utils/fmgr/funcapi.c:1332 +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 #, c-format msgid "number of aliases does not match number of columns" msgstr "別åã®æ•°ãŒåˆ—ã®æ•°ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: utils/fmgr/funcapi.c:1326 +#: utils/fmgr/funcapi.c:1429 #, c-format msgid "no column alias was provided" msgstr "列ã®åˆ¥åãŒæä¾›ã•れã¦ã„ã¾ã›ã‚“ã§ã—ãŸ" -#: utils/fmgr/funcapi.c:1350 +#: utils/fmgr/funcapi.c:1453 #, c-format msgid "could not determine row description for function returning record" msgstr "レコードを返ã™é–¢æ•°ã«ã¤ã„ã¦ã®èª¬æ˜Žã®è¡Œã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/init/miscinit.c:116 +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "データディレクトリ\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "ディレクトリ\"%s\"ã®æ¨©é™ã‚’読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" + +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "指定ã•れãŸãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª \"%s\" ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "データディレクトリ\"%s\"ã®æ‰€æœ‰è€…情報ãŒé–“é•ã£ã¦ã„ã¾ã™" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "データディレクトリを所有ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãŒã‚µãƒ¼ãƒã‚’èµ·å‹•ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "データディレクトリ\"%s\"ã®æ¨©é™è¨­å®šãŒä¸æ­£ã§ã™" + +#: utils/init/miscinit.c:159 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "権é™ã¯ u=rwx(0700) ã¾ãŸã¯ u=rwx,g=rx (0750) ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: utils/init/miscinit.c:218 #, c-format msgid "could not change directory to \"%s\": %m" msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:382 utils/misc/guc.c:5379 +#: utils/init/miscinit.c:554 utils/misc/guc.c:6370 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒ¼åˆ¶é™æ“作内ã§ãƒ‘ラメーター \"%s\" を設定ã§ãã¾ã›ã‚“" -#: utils/init/miscinit.c:461 +#: utils/init/miscinit.c:615 +#, c-format +msgid "role with OID %u does not exist" +msgstr "OID ㌠%u ã§ã‚るロールã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "ロール\"%s\"ã¯ãƒ­ã‚°ã‚¤ãƒ³ã™ã‚‹ã“ã¨ãŒè¨±ã•れã¦ã„ã¾ã›ã‚“" -#: utils/init/miscinit.c:479 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "ロール\"%s\"ã‹ã‚‰ã®æŽ¥ç¶šãŒå¤šã™ãŽã¾ã™" -#: utils/init/miscinit.c:539 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "set session authorizationç”¨ã®æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: utils/init/miscinit.c:619 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" -msgstr "ロールIDãŒç„¡åйã§ã™: %u" +msgstr "䏿­£ãªãƒ­ãƒ¼ãƒ«ID: %u" + +#: utils/init/miscinit.c:860 +#, c-format +msgid "database system is shut down" +msgstr "データベースシステムã¯ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¾ã—ãŸ" -#: utils/init/miscinit.c:746 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "ロックファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:760 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "ロックファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:766 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "ロックファイル\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:774 +#: utils/init/miscinit.c:977 #, c-format -#| msgid "%s: the PID file \"%s\" is empty\n" msgid "lock file \"%s\" is empty" msgstr "ロックファイル\"%s\"ãŒç©ºã§ã™" -#: utils/init/miscinit.c:775 +#: utils/init/miscinit.c:978 #, c-format msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." msgstr "ä»–ã®ã‚µãƒ¼ãƒãŒç¨¼åƒã—ã¦ã„ã‚‹ã‹ã€å‰å›žã®ã‚µãƒ¼ãƒèµ·å‹•失敗ã®ãŸã‚ãƒ­ãƒƒã‚¯ãƒ•ã‚¡ã‚¤ãƒ«ãŒæ®‹ã£ã¦ã„ã‚‹ã‹ã®ã„ãšã‚Œã‹ã§ã™" -#: utils/init/miscinit.c:822 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "ロックファイル\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: utils/init/miscinit.c:826 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "ä»–ã®postgres(PID %d)ãŒãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹?" -#: utils/init/miscinit.c:828 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "ä»–ã®postmaster(PID %d)ãŒãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã§ç¨¼å‹•ã—ã¦ã„ã¾ã›ã‚“ã‹?" -#: utils/init/miscinit.c:831 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "ä»–ã®postgres(PID %d)ãŒã‚½ã‚±ãƒƒãƒˆãƒ•ァイル\"%s\"を使用ã—ã¦ã„ã¾ã›ã‚“ã‹?" -#: utils/init/miscinit.c:833 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "ä»–ã®postmaster(PID %d)ãŒã‚½ã‚±ãƒƒãƒˆãƒ•ァイル\"%s\"を使用ã—ã¦ã„ã¾ã›ã‚“ã‹?" -#: utils/init/miscinit.c:869 +#: utils/init/miscinit.c:1069 #, c-format msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" msgstr "既存ã®å…±æœ‰ãƒ¡ãƒ¢ãƒªãƒ–ロック(キー%luã€ID %lu)ãŒã¾ã ä½¿ç”¨ä¸­ã§ã™" -#: utils/init/miscinit.c:872 +#: utils/init/miscinit.c:1072 #, c-format msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." msgstr "å¤ã„サーãƒãƒ—ロセスãŒç¨¼å‹•中ã§ãªã„ã“ã¨ãŒç¢ºå®Ÿã§ã‚れã°ã€å…±æœ‰ãƒ¡ãƒ¢ãƒªãƒ–ロックを削除ã™ã‚‹ã‹ã€ã¾ãŸã¯å˜ã«ãƒ•ァイル \"%s\" を削除ã—ã¦ãã ã•ã„。" -#: utils/init/miscinit.c:888 +#: utils/init/miscinit.c:1088 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "å¤ã„ロックファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:890 +#: utils/init/miscinit.c:1090 #, c-format msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "ã“ã®ãƒ•ァイルã¯å¶ç„¶æ®‹ã£ã¦ã—ã¾ã£ãŸã‚ˆã†ã§ã™ãŒã€å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚手作業ã§ã“れを削除ã—å†å®Ÿè¡Œã—ã¦ãã ã•ã„。" -#: utils/init/miscinit.c:926 utils/init/miscinit.c:937 -#: utils/init/miscinit.c:947 +#: utils/init/miscinit.c:1127 utils/init/miscinit.c:1141 +#: utils/init/miscinit.c:1152 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "ロックファイル\"%s\"ã«æ›¸ã出ã›ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:1072 utils/misc/guc.c:7740 +#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1427 utils/misc/guc.c:9211 #, c-format msgid "could not read from file \"%s\": %m" msgstr "ファイル\"%s\"ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/init/miscinit.c:1186 utils/init/miscinit.c:1199 +#: utils/init/miscinit.c:1415 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m; ã¨ã‚Šã‚ãˆãšç¶šã‘ã¾ã™" + +#: utils/init/miscinit.c:1440 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "ロックファイル\"%s\"ãŒèª¤ã£ãŸPIDã‚’ã‚‚ã£ã¦ã„ã¾ã™: %ldã€æ­£ã—ãã¯%ld" + +#: utils/init/miscinit.c:1479 utils/init/miscinit.c:1495 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "\"%s\"ã¯æœ‰åйãªãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“" -#: utils/init/miscinit.c:1188 +#: utils/init/miscinit.c:1481 #, c-format msgid "File \"%s\" is missing." msgstr "ファイル\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/init/miscinit.c:1201 +#: utils/init/miscinit.c:1497 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "ファイル\"%s\"ã«æœ‰åйãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã›ã‚“。" -#: utils/init/miscinit.c:1203 +#: utils/init/miscinit.c:1499 #, c-format msgid "You might need to initdb." msgstr "initdbã™ã‚‹å¿…è¦ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#: utils/init/miscinit.c:1211 -#, c-format -msgid "The data directory was initialized by PostgreSQL version %ld.%ld, which is not compatible with this version %s." -msgstr "データディレクトリã¯PostgreSQLãƒãƒ¼ã‚¸ãƒ§ãƒ³%ld.%ldã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã“れã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" - -#: utils/init/miscinit.c:1260 +#: utils/init/miscinit.c:1507 #, c-format -msgid "invalid list syntax in parameter \"%s\"" -msgstr "パラメータ\"%s\"ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒç„¡åйã§ã™" +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "データディレクトリã¯PostgreSQLãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã“れã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã¨ã¯äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: utils/init/miscinit.c:1297 +#: utils/init/miscinit.c:1574 #, c-format msgid "loaded library \"%s\"" msgstr "ライブラリ\"%s\"をロードã—ã¾ã—ãŸ" -#: utils/init/postinit.c:234 +#: utils/init/postinit.c:252 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "レプリケーション接続ã®èªè¨¼å®Œäº†: ユーザ=%s SLL有効 (プロトコル=%sã€æš—å·æ–¹å¼=%sã€ãƒ“ット長=%dã€åœ§ç¸®=%s)" + +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "off" +msgstr "無効" + +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "on" +msgstr "有効" + +#: utils/init/postinit.c:261 #, c-format msgid "replication connection authorized: user=%s" msgstr "レプリケーション接続ã®èªè¨¼å®Œäº†: ユーザ=%s" -#: utils/init/postinit.c:238 +#: utils/init/postinit.c:269 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "接続ã®èªè¨¼å®Œäº†: ユーザ=%s データベース=%s SSL有効 (プロトコル=%sã€æš—å·æ–¹å¼=%sã€ãƒ“ット長=%dã€åœ§ç¸®=%s)" + +#: utils/init/postinit.c:278 #, c-format msgid "connection authorized: user=%s database=%s" -msgstr "接続ã®èªè¨¼å®Œäº†: ユーザ=%sã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹=%s" +msgstr "接続ã®èªè¨¼å®Œäº†: ユーザ=%s データベース=%s" -#: utils/init/postinit.c:269 +#: utils/init/postinit.c:310 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "データベース\"%s\"ã¯pg_databaseã‹ã‚‰æ¶ˆå¤±ã—ã¾ã—ãŸ" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:312 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." -msgstr "OID %uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯\"%s\"ã«å±žã™ã‚‹ã‚ˆã†ã§ã™ã€‚" +msgstr "OID%uã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯\"%s\"ã«å±žã™ã‚‹ã‚ˆã†ã§ã™ã€‚" -#: utils/init/postinit.c:291 +#: utils/init/postinit.c:332 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "ç¾åœ¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%s\"ã¯æŽ¥ç¶šã‚’å—ã‘付ã‘ã¾ã›ã‚“" -#: utils/init/postinit.c:304 +#: utils/init/postinit.c:345 #, c-format msgid "permission denied for database \"%s\"" -msgstr "データベース\"%s\"ã«æ¨©é™ãŒã‚りã¾ã›ã‚“" +msgstr "データベース\"%s\"ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹ãŒæ‹’å¦ã•れã¾ã—ãŸ" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:346 #, c-format msgid "User does not have CONNECT privilege." -msgstr "ユーザã¯CONNECT権é™ã‚’æŒã¡ã¾ã›ã‚“" +msgstr "ユーザã¯CONNECT権é™ã‚’æŒã¡ã¾ã›ã‚“。" -#: utils/init/postinit.c:322 +#: utils/init/postinit.c:363 #, c-format msgid "too many connections for database \"%s\"" msgstr "データベース\"%s\"ã¸ã®æŽ¥ç¶šãŒå¤šã™ãŽã¾ã™" -#: utils/init/postinit.c:344 utils/init/postinit.c:351 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format msgid "database locale is incompatible with operating system" msgstr "データベースã®ãƒ­ã‚±ãƒ¼ãƒ«ãŒã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã¨äº’æ›æ€§ãŒã‚りã¾ã›ã‚“" -#: utils/init/postinit.c:345 +#: utils/init/postinit.c:386 #, c-format msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." msgstr "データベース㯠LC_COLLATE \"%s\" ã§åˆæœŸåŒ–ã•れã¦ã„ã¾ã™ãŒã€setlocale() ã§ã“れをèªè­˜ã•れã¾ã›ã‚“" -#: utils/init/postinit.c:347 utils/init/postinit.c:354 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format msgid "Recreate the database with another locale or install the missing locale." msgstr "データベースを別ã®ãƒ­ã‚±ãƒ¼ãƒ«ã§å†ç”Ÿæˆã™ã‚‹ã‹ã€ã¾ãŸã¯ä¸è¶³ã—ã¦ã„るロケールをインストールã—ã¦ãã ã•ã„" -#: utils/init/postinit.c:352 +#: utils/init/postinit.c:393 #, c-format msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." msgstr "データベース㯠LC_CTYPE \"%s\" ã§åˆæœŸåŒ–ã•れã¦ã„ã¾ã™ãŒã€setlocale()ã§ã“れをèªè­˜ã•れã¾ã›ã‚“" -#: utils/init/postinit.c:648 +#: utils/init/postinit.c:726 #, c-format msgid "no roles are defined in this database system" msgstr "データベースシステム内ã§ãƒ­ãƒ¼ãƒ«ãŒå®šç¾©ã•れã¦ã„ã¾ã›ã‚“" -#: utils/init/postinit.c:649 +#: utils/init/postinit.c:727 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "ã™ãã« CREATE USER \"%s\" SUPERUSER; を実行ã—ã¦ãã ã•ã„。" -#: utils/init/postinit.c:685 +#: utils/init/postinit.c:763 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "データベースã®ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ä¸­ã¯ã€æ–°ã—ã„レプリケーション接続ã¯è¨±å¯ã•れã¾ã›ã‚“" -#: utils/init/postinit.c:689 +#: utils/init/postinit.c:767 #, c-format msgid "must be superuser to connect during database shutdown" -msgstr "データベースã®ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ä¸­ã«æŽ¥ç¶šã§ãã‚‹ã®ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã ã‘ã§ã™" +msgstr "データベースã®ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ä¸­ã«æŽ¥ç¶šã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/init/postinit.c:699 +#: utils/init/postinit.c:777 #, c-format msgid "must be superuser to connect in binary upgrade mode" -msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—ã‚°ãƒ¬ãƒ¼ãƒ‰ãƒ¢ãƒ¼ãƒ‰ä¸­ã«æŽ¥ç¶šã§ãã‚‹ã®ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã ã‘ã§ã™" +msgstr "ãƒã‚¤ãƒŠãƒªã‚¢ãƒƒãƒ—ã‚°ãƒ¬ãƒ¼ãƒ‰ãƒ¢ãƒ¼ãƒ‰ä¸­ã«æŽ¥ç¶šã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/init/postinit.c:713 +#: utils/init/postinit.c:791 #, c-format msgid "remaining connection slots are reserved for non-replication superuser connections" -msgstr "スーパーユーザã«ã‚ˆã‚‹æŽ¥ç¶šç”¨ã«äºˆç´„ã•ã‚Œã‚‹æŽ¥ç¶šã‚¹ãƒ­ãƒƒãƒˆã®æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "æ®‹ã‚Šã®æŽ¥ç¶šã‚¹ãƒ­ãƒƒãƒˆã¯ãƒ¬ãƒ—リケーションユーザã§ã¯ãªã„スーパーユーザ用ã«äºˆç´„ã•れã¦ã„ã¾ã™" -#: utils/init/postinit.c:727 +#: utils/init/postinit.c:801 #, c-format msgid "must be superuser or replication role to start walsender" -msgstr "WALSENDERã‚’é–‹å§‹ã™ã‚‹ãŸã‚ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯replicationロールã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "walsenderã‚’èµ·å‹•ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯replicationロールã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/init/postinit.c:787 +#: utils/init/postinit.c:870 #, c-format msgid "database %u does not exist" msgstr "データベース %u ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/init/postinit.c:839 +#: utils/init/postinit.c:959 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "削除ã¾ãŸã¯ãƒªãƒãƒ¼ãƒ ã•れãŸã°ã‹ã‚Šã®ã‚ˆã†ã§ã™ã€‚" -#: utils/init/postinit.c:857 +#: utils/init/postinit.c:977 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "データベースã®ã‚µãƒ–ディレクトリ\"%s\"ãŒã‚りã¾ã›ã‚“。" -#: utils/init/postinit.c:862 +#: utils/init/postinit.c:982 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ディレクトリ\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/mb/conv.c:519 +#: utils/mb/conv.c:488 utils/mb/conv.c:680 #, c-format msgid "invalid encoding number: %d" -msgstr "符å·åŒ–æ–¹å¼ç•ªå·ãŒç„¡åйã§ã™: %d" +msgstr "䏿­£ãªç¬¦å·åŒ–æ–¹å¼ç•ªå·: %d" -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:136 -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:163 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 #, c-format msgid "unexpected encoding ID %d for ISO 8859 character sets" msgstr "ISO8859文字セットã«å¯¾ã™ã‚‹ç¬¦å·åŒ–æ–¹å¼ID %dã¯æƒ³å®šå¤–ã§ã™" -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:126 -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:153 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 #, c-format msgid "unexpected encoding ID %d for WIN character sets" msgstr "WIN文字セットã«å¯¾ã™ã‚‹ç¬¦å·åŒ–æ–¹å¼ID %dã¯æƒ³å®šå¤–ã§ã™<" -#: utils/mb/encnames.c:494 +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "エンコーディング\"%s\"ã¯ICUã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" + +#: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "符å·åŒ–æ–¹å¼åç§°ãŒé•·ã™ãŽã¾ã™" -#: utils/mb/mbutils.c:281 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "%sã¨%sé–“ã®å¤‰æ›ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/mb/mbutils.c:351 +#: utils/mb/mbutils.c:355 #, c-format msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "符å·åŒ–æ–¹å¼\"%s\"ã‹ã‚‰\"%s\"用ã®ãƒ‡ãƒ•ォルト変æ›é–¢æ•°ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: utils/mb/mbutils.c:375 utils/mb/mbutils.c:676 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "%dãƒã‚¤ãƒˆã®æ–‡å­—列ã¯ç¬¦å·åŒ–変æ›ã§ã¯é•·ã™ãŽã¾ã™ã€‚" -#: utils/mb/mbutils.c:462 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" -msgstr "変æ›å…ƒç¬¦å·åŒ–æ–¹å¼ãŒç„¡åйã§ã™: \"%s\"" +msgstr "䏿­£ãªå¤‰æ›å…ƒç¬¦å·åŒ–æ–¹å¼å: \"%s\"" -#: utils/mb/mbutils.c:467 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" -msgstr "変æ›å…ˆç¬¦å·åŒ–æ–¹å¼ãŒç„¡åйã§ã™: \"%s\"" +msgstr "䏿­£ãªå¤‰æ›å…ˆç¬¦å·åŒ–æ–¹å¼å: \"%s\"" -#: utils/mb/mbutils.c:589 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" -msgstr "符å·åŒ–æ–¹å¼\"%s\"ã§ç„¡åйãªãƒã‚¤ãƒˆå€¤ã§ã™: 0x%02x" +msgstr "符å·åŒ–æ–¹å¼\"%s\"ã«å¯¾ã™ã‚‹ä¸æ­£ãªãƒã‚¤ãƒˆå€¤: 0x%02x" -#: utils/mb/mbutils.c:917 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "bind_textdomain_codesetãŒå¤±æ•—ã—ã¾ã—ãŸ" -#: utils/mb/wchar.c:2018 +#: utils/mb/wchar.c:2015 #, c-format msgid "invalid byte sequence for encoding \"%s\": %s" -msgstr "符å·åŒ–æ–¹å¼\"%s\"ã§ç„¡åйãªãƒã‚¤ãƒˆã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§ã™: %s" +msgstr "符å·åŒ–æ–¹å¼\"%s\"ã«å¯¾ã™ã‚‹ä¸æ­£ãªãƒã‚¤ãƒˆåˆ—ã§ã™: %s" -#: utils/mb/wchar.c:2051 +#: utils/mb/wchar.c:2048 #, c-format msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" -msgstr "符å·åŒ–æ–¹å¼\"%2$s\"ã«ãŠã‘ã‚‹%1$sãƒã‚¤ãƒˆã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’æŒã¤æ–‡å­—ã¯\"%3$s\"符å·åŒ–æ–¹å¼ã§ã¯ç­‰ã—ãã‚りã¾ã›ã‚“" +msgstr "符å·åŒ–æ–¹å¼\"%2$s\"ã«ãŠã„ã¦ãƒã‚¤ãƒˆåˆ—%1$sã§ã‚る文字ã¯ç¬¦å·åŒ–æ–¹å¼\"%3$s\"ã§ç­‰ä¾¡ãªæ–‡å­—ã‚’æŒã¡ã¾ã›ã‚“" -#: utils/misc/guc.c:521 +#: utils/misc/guc.c:572 msgid "Ungrouped" msgstr "ãã®ä»–" -#: utils/misc/guc.c:523 +#: utils/misc/guc.c:574 msgid "File Locations" msgstr "ファイルã®ä½ç½®" -#: utils/misc/guc.c:525 +#: utils/misc/guc.c:576 msgid "Connections and Authentication" msgstr "接続ã¨èªè¨¼" -#: utils/misc/guc.c:527 +#: utils/misc/guc.c:578 msgid "Connections and Authentication / Connection Settings" msgstr "接続ã¨èªè¨¼/接続設定" -#: utils/misc/guc.c:529 -msgid "Connections and Authentication / Security and Authentication" -msgstr "接続ã¨èªè¨¼/セキュリティã¨èªè¨¼" +#: utils/misc/guc.c:580 +msgid "Connections and Authentication / Authentication" +msgstr "接続ã¨èªè¨¼/èªè¨¼" + +#: utils/misc/guc.c:582 +msgid "Connections and Authentication / SSL" +msgstr "接続ã¨èªè¨¼/SSL" -#: utils/misc/guc.c:531 +#: utils/misc/guc.c:584 msgid "Resource Usage" -msgstr "リソースã®ä½¿ç”¨" +msgstr "使用リソース" -#: utils/misc/guc.c:533 +#: utils/misc/guc.c:586 msgid "Resource Usage / Memory" -msgstr "リソースã®ä½¿ç”¨/メモリ" +msgstr "使用リソース/メモリ" -#: utils/misc/guc.c:535 +#: utils/misc/guc.c:588 msgid "Resource Usage / Disk" -msgstr "リソースã®ä½¿ç”¨/ディスク" +msgstr "使用リソース/ディスク" -#: utils/misc/guc.c:537 +#: utils/misc/guc.c:590 msgid "Resource Usage / Kernel Resources" -msgstr "リソースã®ä½¿ç”¨/カーãƒãƒ«ãƒªã‚½ãƒ¼ã‚¹" +msgstr "使用リソース/カーãƒãƒ«ãƒªã‚½ãƒ¼ã‚¹" -#: utils/misc/guc.c:539 +#: utils/misc/guc.c:592 msgid "Resource Usage / Cost-Based Vacuum Delay" -msgstr "使用リソース / コストベース㮠vacuum é…å»¶" +msgstr "使用リソース / コストベースvacuumé…å»¶" -#: utils/misc/guc.c:541 +#: utils/misc/guc.c:594 msgid "Resource Usage / Background Writer" msgstr "使用リソース / ãƒãƒƒã‚¯ã‚°ãƒ©ã‚¦ãƒ³ãƒ‰ãƒ»ãƒ©ã‚¤ã‚¿" -#: utils/misc/guc.c:543 +#: utils/misc/guc.c:596 msgid "Resource Usage / Asynchronous Behavior" -msgstr "使用リソース / éžåŒæœŸå‡¦ç†" +msgstr "使用リソース / éžåŒæœŸå‹•作" -#: utils/misc/guc.c:545 +#: utils/misc/guc.c:598 msgid "Write-Ahead Log" msgstr "ログ先行書ãè¾¼ã¿" -#: utils/misc/guc.c:547 +#: utils/misc/guc.c:600 msgid "Write-Ahead Log / Settings" msgstr "ログ先行書ã込㿠/ 設定" -#: utils/misc/guc.c:549 +#: utils/misc/guc.c:602 msgid "Write-Ahead Log / Checkpoints" msgstr "ログ先行書ã込㿠/ ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆ" -#: utils/misc/guc.c:551 +#: utils/misc/guc.c:604 msgid "Write-Ahead Log / Archiving" msgstr "ログ先行書ã込㿠/ アーカイビング" -#: utils/misc/guc.c:553 +#: utils/misc/guc.c:606 msgid "Replication" msgstr "レプリケーション" -#: utils/misc/guc.c:555 +#: utils/misc/guc.c:608 msgid "Replication / Sending Servers" -msgstr "レプリケーション/é€ä¿¡ã‚µãƒ¼ãƒ" +msgstr "レプリケーション / é€ä¿¡ã‚µãƒ¼ãƒ" -#: utils/misc/guc.c:557 +#: utils/misc/guc.c:610 msgid "Replication / Master Server" -msgstr "レプリケーション/マスタサーãƒ" +msgstr "レプリケーション / マスタサーãƒ" -#: utils/misc/guc.c:559 +#: utils/misc/guc.c:612 msgid "Replication / Standby Servers" -msgstr "レプリケーション/スタンãƒã‚¤ã‚µãƒ¼ãƒ" +msgstr "レプリケーション / スタンãƒã‚¤ã‚µãƒ¼ãƒ" -#: utils/misc/guc.c:561 +#: utils/misc/guc.c:614 +msgid "Replication / Subscribers" +msgstr "レプリケーション / 購読サーãƒ" + +#: utils/misc/guc.c:616 msgid "Query Tuning" -msgstr "å•ã„åˆã‚ã›ã®èª¿æ•´" +msgstr "å•ã„åˆã‚ã›ã®ãƒãƒ¥ãƒ¼ãƒ‹ãƒ³ã‚°" -#: utils/misc/guc.c:563 +#: utils/misc/guc.c:618 msgid "Query Tuning / Planner Method Configuration" -msgstr "å•ã„åˆã‚ã›ã®èª¿æ•´/プランナ手法ã®è¨­å®š" +msgstr "å•ã„åˆã‚ã›ã®ãƒãƒ¥ãƒ¼ãƒ‹ãƒ³ã‚° / プランナ手法設定" -#: utils/misc/guc.c:565 +#: utils/misc/guc.c:620 msgid "Query Tuning / Planner Cost Constants" -msgstr "å•ã„åˆã‚ã›ã®èª¿æ•´/プランナã®ã‚³ã‚¹ãƒˆå®šæ•°" +msgstr "å•ã„åˆã‚ã›ã®ãƒãƒ¥ãƒ¼ãƒ‹ãƒ³ã‚° / プランナコスト定数" -#: utils/misc/guc.c:567 +#: utils/misc/guc.c:622 msgid "Query Tuning / Genetic Query Optimizer" -msgstr "å•ã„åˆã‚ã›ã®èª¿æ•´/éºä¼çš„å•ã„åˆã‚ã›ã‚ªãƒ—ティマイザ" +msgstr "å•ã„åˆã‚ã›ã®ãƒãƒ¥ãƒ¼ãƒ‹ãƒ³ã‚° / éºä¼çš„å•ã„åˆã‚ã›ã‚ªãƒ—ティマイザ" -#: utils/misc/guc.c:569 +#: utils/misc/guc.c:624 msgid "Query Tuning / Other Planner Options" -msgstr "å•ã„åˆã‚ã›ã®èª¿æ•´/ãã®ä»–ã®ãƒ—ランãªã®ã‚ªãƒ—ション" +msgstr "å•ã„åˆã‚ã›ã®ãƒãƒ¥ãƒ¼ãƒ‹ãƒ³ã‚° / ãã®ä»–ã®ãƒ—ランオプション" -#: utils/misc/guc.c:571 +#: utils/misc/guc.c:626 msgid "Reporting and Logging" -msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°" +msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°å‡ºåŠ›" -#: utils/misc/guc.c:573 +#: utils/misc/guc.c:628 msgid "Reporting and Logging / Where to Log" -msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°/ログã®å ´æ‰€" +msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°å‡ºåŠ› / ログã®å‡ºåŠ›å…ˆ" -#: utils/misc/guc.c:575 +#: utils/misc/guc.c:630 msgid "Reporting and Logging / When to Log" -msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°/ログã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°" +msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°å‡ºåŠ› / ログã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°" -#: utils/misc/guc.c:577 +#: utils/misc/guc.c:632 msgid "Reporting and Logging / What to Log" -msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°/ログã®å†…容" +msgstr "レãƒãƒ¼ãƒˆã¨ãƒ­ã‚°å‡ºåŠ› / ログã®å†…容" + +#: utils/misc/guc.c:634 +msgid "Process Title" +msgstr "プロセスタイトル" -#: utils/misc/guc.c:579 +#: utils/misc/guc.c:636 msgid "Statistics" msgstr "統計情報" -#: utils/misc/guc.c:581 +#: utils/misc/guc.c:638 msgid "Statistics / Monitoring" -msgstr "統計情報/監視" +msgstr "統計情報 / 監視" -#: utils/misc/guc.c:583 +#: utils/misc/guc.c:640 msgid "Statistics / Query and Index Statistics Collector" -msgstr "統計情報/å•ã„åˆã‚ã›ã¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®çµ±è¨ˆæƒ…å ±åŽé›†å™¨" +msgstr "統計情報 / å•ã„åˆã‚ã›ã¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®çµ±è¨ˆæƒ…å ±åŽé›†å™¨" -#: utils/misc/guc.c:585 +#: utils/misc/guc.c:642 msgid "Autovacuum" -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ " +msgstr "自動VACUUM" -#: utils/misc/guc.c:587 +#: utils/misc/guc.c:644 msgid "Client Connection Defaults" -msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト" +msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト設定" -#: utils/misc/guc.c:589 +#: utils/misc/guc.c:646 msgid "Client Connection Defaults / Statement Behavior" -msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト/æ–‡ã®æŒ¯èˆžã„" +msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト設定 / æ–‡ã®æŒ¯èˆžã„" -#: utils/misc/guc.c:591 +#: utils/misc/guc.c:648 msgid "Client Connection Defaults / Locale and Formatting" -msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト/ãƒ­ã‚±ãƒ¼ãƒ«ã¨æ•´å½¢" +msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト設定 / ãƒ­ã‚±ãƒ¼ãƒ«ã¨æ•´å½¢" -#: utils/misc/guc.c:593 -#| msgid "Client Connection Defaults / Locale and Formatting" +#: utils/misc/guc.c:650 msgid "Client Connection Defaults / Shared Library Preloading" -msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト/共有ライブラリã®äº‹å‰èª­ã¿è¾¼ã¿" +msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト設定 / ライブラリã®äº‹å‰èª­ã¿è¾¼ã¿" -#: utils/misc/guc.c:595 +#: utils/misc/guc.c:652 msgid "Client Connection Defaults / Other Defaults" -msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト/ãã®ä»–ã®ãƒ‡ãƒ•ォルト" +msgstr "クライアント接続ã®ãƒ‡ãƒ•ォルト設定 / ãã®ä»–ã®ãƒ‡ãƒ•ォルト設定" -#: utils/misc/guc.c:597 +#: utils/misc/guc.c:654 msgid "Lock Management" msgstr "ロック管ç†" -#: utils/misc/guc.c:599 +#: utils/misc/guc.c:656 msgid "Version and Platform Compatibility" -msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ãƒ—ラットフォーム間ã®äº’æ›æ€§" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŠã‚ˆã³ãƒ—ラットフォーム間ã®äº’æ›æ€§" -#: utils/misc/guc.c:601 +#: utils/misc/guc.c:658 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" -msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ãƒ—ラットフォーム間ã®äº’æ›æ€§/以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®PostgreSQL" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŠã‚ˆã³ãƒ—ラットフォーム間ã®äº’æ›æ€§ / PostgreSQLã®ä»¥å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: utils/misc/guc.c:603 +#: utils/misc/guc.c:660 msgid "Version and Platform Compatibility / Other Platforms and Clients" -msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã€ãƒ—ラットフォーム間ã®äº’æ›æ€§/ä»–ã®ãƒ—ラットフォームã¨ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆ" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŠã‚ˆã³ãƒ—ラットフォーム間ã®äº’æ›æ€§ / ä»–ã®ãƒ—ラットフォームãŠã‚ˆã³ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆ" -#: utils/misc/guc.c:605 +#: utils/misc/guc.c:662 msgid "Error Handling" msgstr "エラーãƒãƒ³ãƒ‰ãƒªãƒ³ã‚°" -#: utils/misc/guc.c:607 +#: utils/misc/guc.c:664 msgid "Preset Options" msgstr "事å‰è¨­å®šã‚ªãƒ—ション" -#: utils/misc/guc.c:609 +#: utils/misc/guc.c:666 msgid "Customized Options" -msgstr "カスタマイズ用オプション" +msgstr "独自オプション" -#: utils/misc/guc.c:611 +#: utils/misc/guc.c:668 msgid "Developer Options" msgstr "開発者å‘ã‘オプション" -#: utils/misc/guc.c:665 +#: utils/misc/guc.c:722 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "ã“ã®ãƒ‘ラメータã§ä½¿ç”¨å¯èƒ½ãªå˜ä½ã¯\"B\"ã€\"kB\"ã€\"MB\"ã€\"GB\"ãŠã‚ˆã³\"TB\"ã§ã™ã€‚" + +#: utils/misc/guc.c:764 +msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "ã“ã®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æœ‰åйå˜ä½ã¯\"ms\"ã€\"s\"ã€\"min\"ã€\"h\"ã€\"d\"ã§ã™ã€‚" + +#: utils/misc/guc.c:823 msgid "Enables the planner's use of sequential-scan plans." -msgstr "プランナã«ã‚ˆã‚‹ã‚·ãƒ¼ã‚±ãƒ³ã‚·ãƒ£ãƒ«ã‚¹ã‚­ãƒ£ãƒ³è¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚·ãƒ£ãƒ«ã‚¹ã‚­ãƒ£ãƒ³ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:674 +#: utils/misc/guc.c:832 msgid "Enables the planner's use of index-scan plans." -msgstr "プランナã«ã‚ˆã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³è¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:683 +#: utils/misc/guc.c:841 msgid "Enables the planner's use of index-only-scan plans." -msgstr "プランナã«ã‚ˆã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚ªãƒ³ãƒªãƒ¼ã‚¹ã‚­ãƒ£ãƒ³è¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚ªãƒ³ãƒªãƒ¼ã‚¹ã‚­ãƒ£ãƒ³ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:692 +#: utils/misc/guc.c:850 msgid "Enables the planner's use of bitmap-scan plans." -msgstr "プランナã«ã‚ˆã‚‹ãƒ“ットマップスキャン計画ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ãƒ“ットマップスキャンプランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:701 +#: utils/misc/guc.c:859 msgid "Enables the planner's use of TID scan plans." -msgstr "プランナã«ã‚ˆã‚‹TIDスキャン計画ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®TIDスキャンプランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:710 +#: utils/misc/guc.c:868 msgid "Enables the planner's use of explicit sort steps." -msgstr "プランナã«ã‚ˆã‚‹æ˜Žç¤ºçš„ソート段階ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®æ˜Žç¤ºçš„ソートã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:719 +#: utils/misc/guc.c:877 msgid "Enables the planner's use of hashed aggregation plans." -msgstr "プランナã«ã‚ˆã‚‹ãƒãƒƒã‚·ãƒ¥ã•れãŸé›†ç´„計画ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ãƒãƒƒã‚·ãƒ¥é›†ç´„プランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:728 +#: utils/misc/guc.c:886 msgid "Enables the planner's use of materialization." -msgstr "プランナã«ã‚ˆã‚‹å…·ä½“化(materialization)ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®å®Ÿä½“化ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:737 +#: utils/misc/guc.c:895 msgid "Enables the planner's use of nested-loop join plans." -msgstr "プランナã«ã‚ˆã‚‹å…¥ã‚Œå­çŠ¶ãƒ«ãƒ¼ãƒ—çµåˆè¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ãƒã‚¹ãƒˆãƒ«ãƒ¼ãƒ—ジョインプランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:746 +#: utils/misc/guc.c:904 msgid "Enables the planner's use of merge join plans." -msgstr "プランナã«ã‚ˆã‚‹ãƒžãƒ¼ã‚¸çµåˆè¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ãƒžãƒ¼ã‚¸ã‚¸ãƒ§ã‚¤ãƒ³ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:755 +#: utils/misc/guc.c:913 msgid "Enables the planner's use of hash join plans." -msgstr "プランナã«ã‚ˆã‚‹ãƒãƒƒã‚·ãƒ¥çµåˆè¨ˆç”»ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "プランナã§ã®ãƒãƒƒã‚·ãƒ¥ã‚¸ãƒ§ã‚¤ãƒ³ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:764 +#: utils/misc/guc.c:922 +msgid "Enables the planner's use of gather merge plans." +msgstr "プランナã§ã®ã‚®ãƒ£ã‚¶ãƒ¼ãƒžãƒ¼ã‚¸ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:931 +msgid "Enables partitionwise join." +msgstr "パーティションå˜ä½ã‚¸ãƒ§ã‚¤ãƒ³ã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:940 +msgid "Enables partitionwise aggregation and grouping." +msgstr "パーティションå˜ä½ã®é›†ç´„ãŠã‚ˆã³ã‚°ãƒ«ãƒ¼ãƒ”ングを有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:949 +msgid "Enables the planner's use of parallel append plans." +msgstr "プランナã§ã®ä¸¦åˆ—アペンドプランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:958 +msgid "Enables the planner's use of parallel hash plans." +msgstr "プランナã§ã®ä¸¦åˆ—ãƒãƒƒã‚·ãƒ¥ãƒ—ランã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:967 +msgid "Enable plan-time and run-time partition pruning." +msgstr "実行時ã®ãƒ‘ーティション除外処ç†ã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:968 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "実行計画時ã¨å®Ÿè¡Œæ™‚ã®ã€ã‚¯ã‚¨ãƒªä¸­ã®æ¡ä»¶ã¨ãƒ‘ãƒ¼ãƒ†ã‚£ã‚·ãƒ§ãƒ³å¢ƒç•Œã®æ¯”較ã«åŸºã¥ã„ãŸãƒ‘ーティションå˜ä½ã®ã‚¹ã‚­ãƒ£ãƒ³é™¤å¤–処ç†ã‚’許å¯ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:978 msgid "Enables genetic query optimization." msgstr "éºä¼çš„å•ã„åˆã‚ã›æœ€é©åŒ–を有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:765 +#: utils/misc/guc.c:979 msgid "This algorithm attempts to do planning without exhaustive searching." -msgstr "ã“ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã§ã¯ã€ã—らã¿ã¤ã¶ã—検索を行ã‚ãªã„計画ã®ä½œæˆã‚’試ã¿ã¾ã™ã€‚" +msgstr "ã“ã®ã‚¢ãƒ«ã‚´ãƒªã‚ºãƒ ã§ã¯ã€å…¨æ•°æŽ¢ç´¢ã‚’ä¼´ã‚ãšã«è¡Œã†å®Ÿè¡Œè¨ˆç”»ã®ä½œæˆã‚’試ã¿ã¾ã™ã€‚" -#: utils/misc/guc.c:775 +#: utils/misc/guc.c:989 msgid "Shows whether the current user is a superuser." msgstr "ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ãŒã‚¹ãƒ¼ãƒ‘ーユーザã‹ã©ã†ã‹ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:785 +#: utils/misc/guc.c:999 msgid "Enables advertising the server via Bonjour." -msgstr "Bonjour を経由ã—ãŸã‚µãƒ¼ãƒãƒ¼åºƒå‘Šã‚’有効ã«ã—ã¾ã™" +msgstr "Bonjour を経由ã—ãŸã‚µãƒ¼ãƒãƒ¼ã®ã‚¢ãƒ‰ãƒã‚¿ã‚¤ã‚ºã‚’有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1008 +msgid "Collects transaction commit time." +msgstr "トランザクションã®ã‚³ãƒŸãƒƒãƒˆæ™‚刻をåŽé›†ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:794 +#: utils/misc/guc.c:1017 msgid "Enables SSL connections." msgstr "SSL接続を有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:803 +#: utils/misc/guc.c:1026 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "サーãƒãƒªãƒ­ãƒ¼ãƒ‰æ™‚ã«ã‚‚ ssl_passphrase_command を使用ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1035 +msgid "Give priority to server ciphersuite order." +msgstr "サーãƒå´ã®æš—å·ã‚¹ã‚¤ãƒ¼ãƒˆé †åºã‚’優先ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1044 msgid "Forces synchronization of updates to disk." msgstr "å¼·åˆ¶çš„ã«æ›´æ–°ã‚’ディスクã«åŒæœŸã—ã¾ã™ã€‚" -#: utils/misc/guc.c:804 +#: utils/misc/guc.c:1045 msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." -msgstr "サーãƒã¯ã€ç¢ºå®Ÿã«æ›´æ–°ãŒç‰©ç†çš„ã«ãƒ‡ã‚£ã‚¹ã‚¯ã«æ›¸ãè¾¼ã¾ã‚Œã‚‹ã‚ˆã†ã«è¤‡æ•°ã®ã¨ã“ã‚ã§fsync()システムコールを使用ã—ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚„ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸå¾Œã§ã‚‚データベースクラスタã¯ä¸€è²«ã—ãŸçŠ¶æ…‹ã«å¾©æ—§ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" +msgstr "サーãƒã¯ã€ç¢ºå®Ÿã«æ›´æ–°ãŒç‰©ç†çš„ã«ãƒ‡ã‚£ã‚¹ã‚¯ã«æ›¸ãè¾¼ã¾ã‚Œã‚‹ã‚ˆã†ã«è¤‡æ•°ã®å ´æ‰€ã§fsync()システムコールを使用ã—ã¾ã™ã€‚ã“れã«ã‚ˆã‚Šã€ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ã‚„ãƒãƒ¼ãƒ‰ã‚¦ã‚§ã‚¢ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸå¾Œã§ã‚‚データベースクラスタã¯ä¸€è²«ã—ãŸçŠ¶æ…‹ã«å¾©æ—§ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" -#: utils/misc/guc.c:815 -#| msgid "Continues processing past damaged page headers." +#: utils/misc/guc.c:1056 msgid "Continues processing after a checksum failure." msgstr "ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ã®å¾Œå‡¦ç†ã‚’継続ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:816 -#| msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +#: utils/misc/guc.c:1057 msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." msgstr "ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚¨ãƒ©ãƒ¼ã‚’検知ã™ã‚‹ã¨ã€é€šå¸¸PostgreSQLã¯ã‚¨ãƒ©ãƒ¼ã®å ±å‘Šã‚’行ãªã„ã€ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’中断ã•ã›ã¾ã™ã€‚ignore_checksum_failureを真ã«è¨­å®šã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã‚¨ãƒ©ãƒ¼ã‚’無視ã—ã¾ã™ï¼ˆä»£ã‚りã«è­¦å‘Šã‚’報告ã—ã¾ã™ï¼‰ã“ã®å‹•作ã¯ã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã‚„ä»–ã®æ·±åˆ»ãªå•題を引ãèµ·ã“ã™ã‹ã‚‚ã—れã¾ã›ã‚“。ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒæœ‰åйãªå ´åˆã«ã®ã¿åŠ¹æžœãŒã‚りã¾ã™ã€‚" -#: utils/misc/guc.c:830 +#: utils/misc/guc.c:1071 msgid "Continues processing past damaged page headers." msgstr "ç ´æã—ãŸãƒšãƒ¼ã‚¸ãƒ˜ãƒƒãƒ€ãŒã‚ã£ã¦ã‚‚処ç†ã‚’継続ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:831 +#: utils/misc/guc.c:1072 msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." msgstr "ページヘッダã®éšœå®³ãŒåˆ†ã‹ã‚‹ã¨ã€é€šå¸¸PostgreSQLã¯ã‚¨ãƒ©ãƒ¼ã®å ±å‘Šã‚’行ãªã„ã€ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’中断ã•ã›ã¾ã™ã€‚zero_damaged_pagesを真ã«è¨­å®šã™ã‚‹ã“ã¨ã«ã‚ˆã‚Šã€ã‚·ã‚¹ãƒ†ãƒ ã¯ä»£ã‚りã«è­¦å‘Šã‚’報告ã—ã€éšœå®³ã®ã‚るページをゼロã§åŸ‹ã‚ã€å‡¦ç†ã‚’継続ã—ã¾ã™ã€‚ ã“ã®å‹•作ã«ã‚ˆã‚Šã€éšœå®³ã®ã‚ã£ãŸãƒšãƒ¼ã‚¸ä¸Šã«ã‚ã‚‹å…¨ã¦ã®è¡Œã®ãƒ‡ãƒ¼ã‚¿ã‚’破壊ã•れã¾ã™ã€‚" -#: utils/misc/guc.c:844 +#: utils/misc/guc.c:1085 msgid "Writes full pages to WAL when first modified after a checkpoint." -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¾Œæœ€åˆã«å¤‰æ›´ã•ã‚ŒãŸæ™‚ã€ãƒšãƒ¼ã‚¸å…¨ä½“ã‚’WALã«æ›¸ã出ã—ã¾ã™ã€‚" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¾Œæœ€åˆã«å¤‰æ›´ã•れãŸéš›ã«ãƒšãƒ¼ã‚¸å…¨ä½“ã‚’WALã«å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:845 +#: utils/misc/guc.c:1086 msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." -msgstr "" -"オペレーティングシステムãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸæ™‚ã«ãƒšãƒ¼ã‚¸æ›¸ãè¾¼ã¿ãŒå®Ÿè¡Œä¸­ã ã£ãŸå ´åˆ\n" -"ã«ã®ã¿ã€éƒ¨åˆ†çš„ãªãƒ‡ã‚£ã‚¹ã‚¯ã¸ã®æ›¸ã出ã—ãŒèµ·ã“ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚リカãƒãƒªä¸­ã€WAL\n" -"ã«ä¿å­˜ã•れãŸè¡Œã®å¤‰æ›´ã§ã¯å®Œå…¨ã«å¾©æ—§ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã®ã‚ªãƒ—ションã«ã‚ˆã‚Šã€\n" -"ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¾Œã®æœ€åˆã®å¤‰æ›´æ™‚ã«WALã«ãƒšãƒ¼ã‚¸ã‚’書ã出ã—ã¾ã™ã®ã§ã€å®Œå…¨ãªå¾©æ—§\n" -"ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚" +msgstr "ページ書ãè¾¼ã¿å‡¦ç†ä¸­ã«ã‚ªãƒšãƒ¬ãƒ¼ãƒ†ã‚£ãƒ³ã‚°ã‚·ã‚¹ãƒ†ãƒ ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã™ã‚‹ã¨ã€ãƒ‡ã‚£ã‚¹ã‚¯ã¸ã®æ›¸ãè¾¼ã¿ãŒä¸€éƒ¨åˆ†ã®ã¿è¡Œã‚れるå¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚リカãƒãƒªã§ã¯ã€WALã«ä¿å­˜ã•れãŸè¡Œã®å¤‰æ›´ã ã‘ã§ã¯å®Œå…¨ã«å¾©æ—§ã•ã›ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。ã“ã®ã‚ªãƒ—ションã«ã‚ˆã‚Šã€ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¾Œã®æœ€åˆã®æ›´æ–°æ™‚ã«WALã«ãƒšãƒ¼ã‚¸ã‚’出力ã™ã‚‹ãŸã‚ã€å®Œå…¨ãªå¾©æ—§ãŒå¯èƒ½ã«ãªã‚Šã¾ã™ã€‚" + +#: utils/misc/guc.c:1099 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¾Œæœ€åˆã«æ›´æ–°ã•ã‚ŒãŸæ™‚ã«ã€é‡è¦ãªæ›´æ–°ã§ã¯ãªãã¦ã‚‚ページ全体をWALã«æ›¸ã出ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:857 +#: utils/misc/guc.c:1109 +msgid "Compresses full-page writes written in WAL file." +msgstr "WALファイルã«å‡ºåŠ›ã•れる全ページ出力を圧縮ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1119 msgid "Logs each checkpoint." -msgstr "å„ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚’ログã«å‡ºåŠ›ã—ã¾ã™ã€‚" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚’ログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:866 +#: utils/misc/guc.c:1128 msgid "Logs each successful connection." -msgstr "æˆåŠŸã—ãŸæŽ¥ç¶šã‚’å…¨ã¦ãƒ­ã‚°ã«å‡ºåŠ›ã—ã¾ã™ã€‚" +msgstr "æˆåŠŸã—ãŸæŽ¥ç¶šã‚’å…¨ã¦ãƒ­ã‚°ã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:875 +#: utils/misc/guc.c:1137 msgid "Logs end of a session, including duration." -msgstr "セッションã®çµ‚了時刻ã¨ãã®æœŸé–“をログã«å‡ºåŠ›ã—ã¾ã™ã€‚" +msgstr "セッションã®çµ‚了時刻ã¨ãã®æœŸé–“をログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:884 -msgid "Turns on various assertion checks." -msgstr "å„種アサーション検査を有効ã«ã—ã¾ã™ã€‚" +#: utils/misc/guc.c:1146 +msgid "Logs each replication command." +msgstr "å„レプリケーションコマンドをログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:885 -msgid "This is a debugging aid." -msgstr "ã“れã¯ãƒ‡ãƒãƒƒã‚°ç”¨ã§ã™ã€‚" +#: utils/misc/guc.c:1155 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "起動中ã®ã‚µãƒ¼ãƒãŒã‚¢ã‚µãƒ¼ã‚·ãƒ§ãƒ³ãƒã‚§ãƒƒã‚¯ã‚’有効ã«ã—ã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:899 +#: utils/misc/guc.c:1170 msgid "Terminate session on any error." msgstr "何ã‹ã‚‰ã®ã‚¨ãƒ©ãƒ¼ãŒã‚れã°ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’終了ã—ã¾ã™" -#: utils/misc/guc.c:908 +#: utils/misc/guc.c:1179 msgid "Reinitialize server after backend crash." msgstr "ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ãŒã‚¯ãƒ©ãƒƒã‚·ãƒ¥ã—ãŸå¾Œã‚µãƒ¼ãƒã‚’å†åˆæœŸåŒ–ã—ã¾ã™" -#: utils/misc/guc.c:918 +#: utils/misc/guc.c:1189 msgid "Logs the duration of each completed SQL statement." -msgstr "完了ã—ãŸSQLå…¨ã¦ã®æœŸé–“をログã«å‡ºåŠ›ã—ã¾ã™ã€‚" +msgstr "完了ã—ãŸSQLå…¨ã¦ã®å®Ÿè¡Œæ™‚間をログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:927 +#: utils/misc/guc.c:1198 msgid "Logs each query's parse tree." -msgstr "å„クエリーã®ãƒ‘ースツリーã®ãƒ­ã‚°ã‚’å–りã¾ã™" +msgstr "å•ã„åˆã‚ã›ã®ãƒ‘ースツリーをログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:936 +#: utils/misc/guc.c:1207 msgid "Logs each query's rewritten parse tree." -msgstr "å„クエリーã®ãƒ‘ースツリーãŒå†åº¦æ›¸ã‹ã‚ŒãŸåˆ†ã®ãƒ­ã‚°ã‚’å–りã¾ã™" +msgstr "リライト後ã®å•ã„åˆã‚ã›ã®ãƒ‘ースツリーをログを記録ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:945 +#: utils/misc/guc.c:1216 msgid "Logs each query's execution plan." -msgstr "å„クエリーã®å®Ÿè¡Œè¨ˆç”»ã‚’ログã«å‡ºåŠ›ã—ã¾ã™ã€‚" +msgstr "å•ã„åˆã‚ã›ã®å®Ÿè¡Œè¨ˆç”»ã‚’ログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:954 +#: utils/misc/guc.c:1225 msgid "Indents parse and plan tree displays." -msgstr "è§£æžãƒ„リーã¨è¨ˆç”»ãƒ„リーã®è¡¨ç¤ºã‚’インデントã—ã¾ã™ã€‚" +msgstr "パースツリーã¨å®Ÿè¡Œè¨ˆç”»ãƒ„リーã®è¡¨ç¤ºã‚’インデントã—ã¾ã™ã€‚" -#: utils/misc/guc.c:963 +#: utils/misc/guc.c:1234 msgid "Writes parser performance statistics to the server log." msgstr "ãƒ‘ãƒ¼ã‚µã®æ€§èƒ½çµ±è¨ˆæƒ…報をサーãƒãƒ­ã‚°ã«å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:972 +#: utils/misc/guc.c:1243 msgid "Writes planner performance statistics to the server log." msgstr "ãƒ—ãƒ©ãƒ³ãƒŠã®æ€§èƒ½çµ±è¨ˆæƒ…報をサーãƒãƒ­ã‚°ã«å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:981 +#: utils/misc/guc.c:1252 msgid "Writes executor performance statistics to the server log." msgstr "ã‚¨ã‚°ã‚¼ã‚­ãƒ¥ãƒ¼ã‚¿ã®æ€§èƒ½çµ±è¨ˆæƒ…報をサーãƒãƒ­ã‚°ã«å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:990 +#: utils/misc/guc.c:1261 msgid "Writes cumulative performance statistics to the server log." msgstr "ç´¯ç©ã®æ€§èƒ½çµ±è¨ˆæƒ…報をサーãƒãƒ­ã‚°ã«å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1000 utils/misc/guc.c:1074 utils/misc/guc.c:1084 -#: utils/misc/guc.c:1094 utils/misc/guc.c:1104 utils/misc/guc.c:1851 -#: utils/misc/guc.c:1861 -msgid "No description available." -msgstr "説明文ã¯ã‚りã¾ã›ã‚“" +#: utils/misc/guc.c:1271 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "B-treeã®å„種æ“作ã«é–¢ã™ã‚‹ã‚·ã‚¹ãƒ†ãƒ ãƒªã‚½ãƒ¼ã‚¹(メモリã¨CPU)ã®ä½¿ç”¨çµ±è¨ˆã‚’ログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1012 +#: utils/misc/guc.c:1283 msgid "Collects information about executing commands." msgstr "実行中ã®ã‚³ãƒžãƒ³ãƒ‰ã«é–¢ã™ã‚‹æƒ…報をåŽé›†ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1013 +#: utils/misc/guc.c:1284 msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." -msgstr "å„セッションã§ç¾åœ¨å®Ÿè¡Œä¸­ã®ã‚³ãƒžãƒ³ãƒ‰ã«é–¢ã—ã¦ã€ãã®ã‚³ãƒžãƒ³ãƒ‰ãŒå®Ÿè¡Œã‚’é–‹å§‹ã—ãŸæ™‚ç‚¹ã®æ™‚刻ã¨ä¸€ç·’ã«æƒ…å ±ã®åŽé›†ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "ãã®ã‚³ãƒžãƒ³ãƒ‰ãŒå®Ÿè¡Œã‚’é–‹å§‹ã—ãŸæ™‚刻を伴ã£ãŸã€å„セッションã§ã®ç¾æ™‚点ã§å®Ÿè¡Œä¸­ã®ã‚³ãƒžãƒ³ãƒ‰ã«é–¢ã™ã‚‹æƒ…å ±ã®åŽé›†ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1023 +#: utils/misc/guc.c:1294 msgid "Collects statistics on database activity." msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ´»å‹•ã«ã¤ã„ã¦çµ±è¨ˆæƒ…報をåŽé›†ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1032 +#: utils/misc/guc.c:1303 msgid "Collects timing statistics for database I/O activity." msgstr "データベースã®I/O動作ã«é–¢ã™ã‚‹æ™‚間測定統計情報をåŽé›†ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1042 +#: utils/misc/guc.c:1313 msgid "Updates the process title to show the active SQL command." msgstr "活動中ã®SQLコマンドを表示ã™ã‚‹ã‚ˆã†ãƒ—ロセスタイトルを更新ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1043 +#: utils/misc/guc.c:1314 msgid "Enables updating of the process title every time a new SQL command is received by the server." -msgstr "æ–°ã—ã„SQLコマンドをサーãƒãŒå—ä¿¡ã™ã‚‹åº¦ã«ãƒ—ロセスタイトルを更新ã™ã‚‹ã“ã¨ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„SQLコマンドをサーãƒãŒå—ä¿¡ã™ã‚‹åº¦ã«è¡Œã†ãƒ—ãƒ­ã‚»ã‚¹ã‚¿ã‚¤ãƒˆãƒ«ã®æ›´æ–°ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1052 +#: utils/misc/guc.c:1327 msgid "Starts the autovacuum subprocess." -msgstr "subprocessサブプロセスを起動ã—ã¾ã™ã€‚" +msgstr "autovacuumサブプロセスを起動ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1062 +#: utils/misc/guc.c:1337 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "LISTENã¨NOTIFYコマンドã®ãŸã‚ã®ãƒ‡ãƒãƒƒã‚°å‡ºåŠ›ã‚’ç”Ÿæˆã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1116 +#: utils/misc/guc.c:1349 +msgid "Emits information about lock usage." +msgstr "ロック使用状æ³ã«é–¢ã™ã‚‹æƒ…報を出力ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1359 +msgid "Emits information about user lock usage." +msgstr "ユーザロックã®ä½¿ç”¨çжæ³ã«é–¢ã™ã‚‹æƒ…報を出力ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1369 +msgid "Emits information about lightweight lock usage." +msgstr "軽é‡ãƒ­ãƒƒã‚¯ã®ä½¿ç”¨çжæ³ã«é–¢ã™ã‚‹æƒ…報を出力ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1379 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "デッドロックã®ç™ºç”Ÿæ™‚点ã®å…¨ã¦ã®ãƒ­ãƒƒã‚¯ã«ã¤ã„ã¦ã®æƒ…報をダンプã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1391 msgid "Logs long lock waits." -msgstr "長期ã®ãƒ­ãƒƒã‚¯å¾…機をログã«è¨˜éŒ²ã—ã¾ã™ã€‚" +msgstr "長時間ã®ãƒ­ãƒƒã‚¯å¾…機をログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1126 +#: utils/misc/guc.c:1401 msgid "Logs the host name in the connection logs." msgstr "接続ログ内ã§ãƒ›ã‚¹ãƒˆåを出力ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1127 +#: utils/misc/guc.c:1402 msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." -msgstr "デフォルトã§ã¯ã€æŽ¥ç¶šãƒ­ã‚°ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ã¯æŽ¥ç¶šãƒ›ã‚¹ãƒˆã®IPアドレスã®ã¿ãŒè¡¨ç¤ºã•れã¾ã™ã€‚ ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã“ã¨ã§ã€ãƒ›ã‚¹ãƒˆåもログã«è¡¨ç¤ºã•れるよã†ã«ãªã‚Šã¾ã™ã€‚ ホストå解決ã®è¨­å®šæ¬¡ç¬¬ã§ã€ç„¡è¦–ã§ããªã„ã»ã©ã®æ€§èƒ½ã®æ‚ªåŒ–ãŒèª²ã›ã‚‰ã‚Œã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。" - -#: utils/misc/guc.c:1138 -msgid "Causes subtables to be included by default in various commands." -msgstr "å„種コマンドã«ãŠã„ã¦ã€ãƒ‡ãƒ•ォルトã§å­ãƒ†ãƒ¼ãƒ–ルをå«ã‚るよã†ã«ã—ã¾ã™ã€‚" - -#: utils/misc/guc.c:1147 -msgid "Encrypt passwords." -msgstr "パスワードを暗å·åŒ–ã—ã¾ã™ã€‚" - -#: utils/misc/guc.c:1148 -msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." -msgstr "ENCRYPTEDã‚‚ã—ãã¯UNENCRYPTEDã®æŒ‡å®šç„¡ã—ã«CREATE USERã‚‚ã—ãã¯ALTER USERã§ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæŒ‡å®šã•れãŸå ´åˆã€ã“ã®ã‚ªãƒ—ションãŒãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æš—å·åŒ–を行ãªã†ã‹ã©ã†ã‹ã‚’決定ã—ã¾ã™ã€‚" +msgstr "デフォルトã§ã¯ã€æŽ¥ç¶šãƒ­ã‚°ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã«ã¯æŽ¥ç¶šãƒ›ã‚¹ãƒˆã®IPアドレスã®ã¿ãŒè¡¨ç¤ºã•れã¾ã™ã€‚ ã“ã®ã‚ªãƒ—ションを有効ã«ã™ã‚‹ã“ã¨ã§ã€ãƒ›ã‚¹ãƒˆåもログã«è¡¨ç¤ºã•れるよã†ã«ãªã‚Šã¾ã™ã€‚ ホストå解決ã®è¨­å®šã«ã‚ˆã£ã¦ã¯ã§ã€ç„¡è¦–ã§ããªã„ã»ã©ã®æ€§èƒ½ã®æ‚ªåŒ–ãŒèµ·ãã†ã‚‹ã“ã¨ã«æ³¨æ„ã—ã¦ãã ã•ã„。" -#: utils/misc/guc.c:1158 +#: utils/misc/guc.c:1413 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "\"expr=NULL\"ã¨ã„ã†å½¢ã®å¼ã¯\"expr IS NULL\"ã¨ã—ã¦æ‰±ã„ã¾ã™ã€‚" -#: utils/misc/guc.c:1159 +#: utils/misc/guc.c:1414 msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." msgstr "有効ã«ã—ãŸå ´åˆã€expr = NULL(ã¾ãŸã¯NULL = expr)ã¨ã„ã†å½¢ã®å¼ã¯expr IS NULLã¨ã—ã¦æ‰±ã‚れã¾ã™ã€‚ã¤ã¾ã‚Šã€exprã®è©•価ãŒNULL値ã®å ´åˆã«çœŸã‚’ã€ã•ã‚‚ãªãã°å½ã‚’è¿”ã—ã¾ã™ã€‚expr = NULLã®SQL仕様ã«åŸºã¥ã„ãŸæ­£ã—ã„動作ã¯å¸¸ã«NULL(未知)ã‚’è¿”ã™ã“ã¨ã§ã™ã€‚" -#: utils/misc/guc.c:1171 +#: utils/misc/guc.c:1426 msgid "Enables per-database user names." msgstr "データベース毎ã®ãƒ¦ãƒ¼ã‚¶åを許å¯ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1181 -msgid "This parameter doesn't do anything." -msgstr "ã“ã®ãƒ‘ラメータã¯ä½•ã‚‚ã—ã¾ã›ã‚“。" - -#: utils/misc/guc.c:1182 -msgid "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients." -msgstr "å¤ã„7.3ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‹ã‚‰ã®SET AUTOCOMMIT TO ONã§ã‚¨ãƒ©ãƒ¼ã«ã•ã›ãŸããªã„ãŸã‚ã ã‘ã«ã“れã¯å­˜åœ¨ã—ã¾ã™ã€‚" - -#: utils/misc/guc.c:1191 +#: utils/misc/guc.c:1435 msgid "Sets the default read-only status of new transactions." -msgstr "æ–°ã—ã„トランザクションã®èª­ã¿å–りã®ã¿ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ãƒ‡ãƒ•ォルトを設定ã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„トランザクションã®ãƒªãƒ¼ãƒ‰ã‚ªãƒ³ãƒªãƒ¼è¨­å®šã®ãƒ‡ãƒ•ォルト値を設定。" -#: utils/misc/guc.c:1200 +#: utils/misc/guc.c:1444 msgid "Sets the current transaction's read-only status." -msgstr "ç¾æ„›ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®èª­ã¿å–りã®ã¿ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒªãƒ¼ãƒ‰ã‚ªãƒ³ãƒªãƒ¼è¨­å®šã‚’設定。" -#: utils/misc/guc.c:1210 +#: utils/misc/guc.c:1454 msgid "Sets the default deferrable status of new transactions." -msgstr "æ–°ã—ã„トランザクションã®é…å»¶å¯èƒ½ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã®ãƒ‡ãƒ•ォルトを設定ã—ã¾ã™ã€‚" +msgstr "æ–°ã—ã„トランザクションã®é…å»¶å¯å¦è¨­å®šã®ãƒ‡ãƒ•ォルト値を設定。" -#: utils/misc/guc.c:1219 +#: utils/misc/guc.c:1463 msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." -msgstr "リードオンリーã®ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºå¯èƒ½ãªãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã€ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºã«å¤±æ•—ã™ã‚‹ã“ã¨ãªã実行ã§ãã‚‹ã“ã¨ã‚’ä¿è¨¼ã§ãã‚‹ã¾ã§é…å»¶ã•ã›ã‚‹ã‹ã©ã†ã‹" +msgstr "リードオンリーã®ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºå¯èƒ½ãªãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ã€ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚ºã«å¤±æ•—ã™ã‚‹ã“ã¨ãªã実行ã§ãã‚‹ã¾ã§é…å»¶ã•ã›ã‚‹ã‹ã©ã†ã‹" + +#: utils/misc/guc.c:1473 +msgid "Enable row security." +msgstr "行セキュリティを有効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1474 +msgid "When enabled, row security will be applied to all users." +msgstr "有効ã«ã™ã‚‹ã¨ã€è¡Œã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãŒå…¨ã¦ã®ãƒ¦ãƒ¼ã‚¶ã«é©ç”¨ã•れã¾ã™ã€‚" -#: utils/misc/guc.c:1229 +#: utils/misc/guc.c:1482 msgid "Check function bodies during CREATE FUNCTION." msgstr "CREATE FUNCTION中ã«é–¢æ•°æœ¬ä½“を検査ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1238 +#: utils/misc/guc.c:1491 msgid "Enable input of NULL elements in arrays." -msgstr "é…列内ã®NULLè¦ç´ å…¥åŠ›ã‚’å¯èƒ½ã«ã—ã¾ã™ã€Œã€‚" +msgstr "é…列内ã®NULLè¦ç´ å…¥åŠ›ã‚’å¯èƒ½ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1239 +#: utils/misc/guc.c:1492 msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." -msgstr "有効ã«ã™ã‚‹ã¨ã€é…列入力値ã«ãŠã‘る引用符ã®ãªã„NULLã¯NULL値をæ„味ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ã•ã‚‚ãªãã°ãã®ã¾ã¾è§£é‡ˆã•れã¾ã™ã€‚" +msgstr "有効ã«ã™ã‚‹ã¨ã€é…列入力値ã«ãŠã‘る引用符ã®ãªã„NULLã¯NULL値をæ„味ã™ã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚ã•ã‚‚ãªãã°æ–‡å­—通りã«è§£é‡ˆã•れã¾ã™ã€‚" -#: utils/misc/guc.c:1249 +#: utils/misc/guc.c:1502 msgid "Create new tables with OIDs by default." msgstr "æ–°è¦ã®ãƒ†ãƒ¼ãƒ–ルをデフォルトã§OID付ãã§ä½œæˆã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1258 +#: utils/misc/guc.c:1511 msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "標準エラー出力ã€CSVログã€ã¾ãŸã¯ãã®ä¸¡æ–¹ã‚’ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã«æ•æ‰ã™ã‚‹ãŸã‚ã®å­ãƒ—ロセスを開始ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1267 +#: utils/misc/guc.c:1520 msgid "Truncate existing log files of same name during log rotation." msgstr "ãƒ­ã‚°ãƒ­ãƒ¼ãƒ†ãƒ¼ã‚·ãƒ§ãƒ³æ™‚ã«æ—¢å­˜ã®åŒä¸€åç§°ã®ãƒ­ã‚°ãƒ•ァイルを切り詰ã‚ã¾ã™ã€‚" -#: utils/misc/guc.c:1278 +#: utils/misc/guc.c:1531 msgid "Emit information about resource usage in sorting." msgstr "ソート中ã«ãƒªã‚½ãƒ¼ã‚¹ä½¿ç”¨çжæ³ã«é–¢ã™ã‚‹æƒ…報を発行ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1292 +#: utils/misc/guc.c:1545 msgid "Generate debugging output for synchronized scanning." msgstr "åŒæœŸã‚¹ã‚­ãƒ£ãƒ³å‡¦ç†ã®ãƒ‡ãƒãƒƒã‚°å‡ºåŠ›ã‚’ç”Ÿæˆã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1307 +#: utils/misc/guc.c:1560 msgid "Enable bounded sorting using heap sort." msgstr "ヒープソートを使用ã—ãŸå¢ƒç•Œã®ã‚½ãƒ¼ãƒˆå‡¦ç†ã‚’有効ã«ã—ã¾ã™" -#: utils/misc/guc.c:1320 +#: utils/misc/guc.c:1573 msgid "Emit WAL-related debugging output." msgstr "WAL関連ã®ãƒ‡ãƒãƒƒã‚°å‡ºåŠ›ã‚’å‡ºåŠ›ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1332 +#: utils/misc/guc.c:1585 msgid "Datetimes are integer based." msgstr "æ—¥ä»˜æ™‚åˆ»ã¯æ•´æ•°ãƒ™ãƒ¼ã‚¹ã§ã™ã€‚" -#: utils/misc/guc.c:1347 +#: utils/misc/guc.c:1596 msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "KerberosãŠã‚ˆã³GSSAPIユーザåã‚’å¤§æ–‡å­—å°æ–‡å­—を区別ã—ã¦æ‰±ã†ã‹ã©ã†ã‹ã‚’設定ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1357 +#: utils/misc/guc.c:1606 msgid "Warn about backslash escapes in ordinary string literals." msgstr "æ™®é€šã®æ–‡å­—列リテラル内ã®ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—を警告ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1367 +#: utils/misc/guc.c:1616 msgid "Causes '...' strings to treat backslashes literally." msgstr "'...' 文字列ã¯ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚’ãã®ã¾ã¾æ‰±ã„ã¾ã™ã€‚" -#: utils/misc/guc.c:1378 +#: utils/misc/guc.c:1627 msgid "Enable synchronized sequential scans." msgstr "åŒæœŸã‚·ãƒ¼ã‚±ãƒ³ã‚·ãƒ£ãƒ«ã‚¹ã‚­ãƒ£ãƒ³ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1388 -msgid "Allows archiving of WAL files using archive_command." -msgstr "archive_command.\"を使用ã—ãŸWALファイルã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–処ç†ã‚’許å¯ã—ã¾ã™ã€‚" - -#: utils/misc/guc.c:1398 +#: utils/misc/guc.c:1637 msgid "Allows connections and queries during recovery." -msgstr "リカãƒãƒªãƒ¼ä¸­ã§ã‚‚接続ã¨ã‚¯ã‚¨ãƒªã‚’å—ã‘付ã‘ã¾ã™" +msgstr "リカãƒãƒªä¸­ã§ã‚‚接続ã¨å•ã„åˆã‚ã›ã‚’å—ã‘付ã‘ã¾ã™" -#: utils/misc/guc.c:1408 +#: utils/misc/guc.c:1647 msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." -msgstr "クエリーã®è¡çªã‚’é¿ã‘ã‚‹ãŸã‚ホットスタンãƒã‚¤ã‹ã‚‰ãƒ—ライマリã¸ã®ãƒ•ィードãƒãƒƒã‚¯ã‚’å—ã‘付ã‘ã¾ã™" +msgstr "å•ã„åˆã‚ã›ã®è¡çªã‚’é¿ã‘ã‚‹ãŸã‚ã®ãƒ›ãƒƒãƒˆã‚¹ã‚¿ãƒ³ãƒã‚¤ã‹ã‚‰ãƒ—ライマリã¸ã®ãƒ•ィードãƒãƒƒã‚¯ã‚’å—ã‘付ã‘ã¾ã™" -#: utils/misc/guc.c:1418 +#: utils/misc/guc.c:1657 msgid "Allows modifications of the structure of system tables." -msgstr "システムテーブル構造ã«å¤‰æ›´ã‚’許å¯ã—ã¾ã™ã€‚" +msgstr "システムテーブル構造ã®å¤‰æ›´ã‚’許å¯ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1429 +#: utils/misc/guc.c:1668 msgid "Disables reading from system indexes." msgstr "システムインデックスã®èª­ã¿å–りを無効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1430 +#: utils/misc/guc.c:1669 msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." -msgstr "ã“れã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®æ›´æ–°ã¯é˜²ãŽã¾ã›ã‚“ã®ã§ã€ä½¿ç”¨ã—ã¦ã‚‚安全ã§ã™ã€‚最大ã®å½±éŸ¿ã¯ä½Žé€ŸåŒ–ã§ã™ã€‚" +msgstr "ã“れã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®æ›´æ–°ã¯å¦¨ã’ãªã„ãŸã‚使用ã—ã¦ã‚‚安全ã§ã™ã€‚最も大ããªæ‚ªå½±éŸ¿ã¯ä½Žé€ŸåŒ–ã§ã™ã€‚" -#: utils/misc/guc.c:1441 +#: utils/misc/guc.c:1680 msgid "Enables backward compatibility mode for privilege checks on large objects." -msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã§æ¨©é™ãƒã‚§ãƒƒã‚¯ã‚’行ã†éš›ã€ä¸‹ä½äº’æ›æ€§ãƒ¢ãƒ¼ãƒ‰ã‚’有効ã«ã—ã¾ã™ã€‚" +msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã§æ¨©é™ãƒã‚§ãƒƒã‚¯ã‚’行ã†éš›ã€å¾Œæ–¹äº’æ›æ€§ãƒ¢ãƒ¼ãƒ‰ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1442 +#: utils/misc/guc.c:1681 msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." -msgstr "9.0 以å‰ã® PostgreSQL ã¨ã®äº’æ›ã®ãŸã‚ã€ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクトを読んã ã‚Šå¤‰æ›´ã—ãŸã‚Šã™ã‚‹éš›ã«æ¨©é™ãƒã‚§ãƒƒã‚¯ã‚’スキップã™ã‚‹ã€‚" +msgstr "9.0 よりå‰ã®PostgreSQLã¨ã®äº’æ›ã®ãŸã‚ã€ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクトを読んã ã‚Šå¤‰æ›´ã—ãŸã‚Šã™ã‚‹éš›ã«æ¨©é™ãƒã‚§ãƒƒã‚¯ã‚’スキップã™ã‚‹ã€‚" + +#: utils/misc/guc.c:1691 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "PostgreSQL 9.4以陿„味ãŒå¤‰ã‚ã£ã¦ã„ã‚‹æ§‹æ–‡ã«å¯¾ã—ã¦è­¦å‘Šã‚’出ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1452 +#: utils/misc/guc.c:1701 msgid "When generating SQL fragments, quote all identifiers." -msgstr "SQL フラグメントを生æˆã™ã‚‹æ™‚ã¯ã€ã™ã¹ã¦ã®è­˜åˆ¥å­ã‚’引用符ã§å›²ã‚“ã§ãã ã•ã„" +msgstr "SQL文を生æˆã™ã‚‹æ™‚ã«ã€ã™ã¹ã¦ã®è­˜åˆ¥å­ã‚’引用符ã§å›²ã¿ã¾ã™ã€‚" -#: utils/misc/guc.c:1471 -msgid "Forces a switch to the next xlog file if a new file has not been started within N seconds." -msgstr "Nç§’ä»¥å†…ã«æ–°ã—ã„ファイルãŒå§‹ã¾ã‚‰ãªã„å ´åˆã«æ¬¡ã®xlogファイルã¸ã®åˆ‡ã‚Šæ›¿ãˆã‚’強制ã—ã¾ã™ã€‚" +#: utils/misc/guc.c:1711 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "データãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ã§æœ‰åйã«ãªã£ã¦ã„ã‚‹ã‹ã©ã†ã‹ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1482 +#: utils/misc/guc.c:1722 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "シーケンス番å·ã‚’付加ã™ã‚‹ã“ã¨ã§syslogメッセージã®é‡è¤‡ã‚’防ãŽã¾ã™ã€‚" + +#: utils/misc/guc.c:1732 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "syslogã«é€å‡ºã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’行å˜ä½ã§åˆ†å‰²ã—ã¦ã€1024ãƒã‚¤ãƒˆã«åŽã¾ã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1742 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Gather ãŠã‚ˆã³ Gather Merge ã§ã‚‚下ä½ãƒ—ランを実行ã™ã‚‹ã‹ã©ã†ã‹ã‚’制御ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1743 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Gather ノードã§ã‚‚下ä½ãƒ—ランを実行ã—ã¾ã™ã‹ã€ã‚‚ã—ãã¯ãŸã ã‚¿ãƒ—ルã®åŽé›†ã®ã¿ã‚’行ã„ã¾ã™ã‹?" + +#: utils/misc/guc.c:1752 +msgid "Allow JIT compilation." +msgstr "JITコンパイルを許å¯ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1762 +msgid "Register JIT compiled function with debugger." +msgstr "JITコンパイルã•れãŸé–¢æ•°ã‚’デãƒãƒƒã‚¬ã«ç™»éŒ²ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1779 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "LLVMビットコードを出力ã—ã¦ã€JITデãƒãƒƒã‚°ã‚’容易ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1790 +msgid "Allow JIT compilation of expressions." +msgstr "å¼ã®JITコンパイルを許å¯ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1801 +msgid "Register JIT compiled function with perf profiler." +msgstr "perfプロファイラã«JITコンパイルã•れãŸé–¢æ•°ã‚’登録ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1818 +msgid "Allow JIT compilation of tuple deforming." +msgstr "タプル分解処ç†ã®JITコンパイルを許å¯ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1829 +msgid "Whether to continue running after a failure to sync data files." +msgstr "" + +#: utils/misc/guc.c:1847 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Nç§’ä»¥å†…ã«æ–°ã—ã„ファイルãŒå§‹ã¾ã‚‰ãªã„å ´åˆã«ã¯ã€æ¬¡ã®xlogファイルã¸ã®åˆ‡ã‚Šæ›¿ãˆã‚’強制ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:1858 msgid "Waits N seconds on connection startup after authentication." -msgstr "èªè¨¼å¾Œã®æŽ¥ç¶šé–‹å§‹ã¾ã§N秒待機ã—ã¾ã™ã€‚" +msgstr "èªè¨¼å¾Œã€æŽ¥ç¶šé–‹å§‹ã¾ã§N秒待機ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1483 utils/misc/guc.c:1965 +#: utils/misc/guc.c:1859 utils/misc/guc.c:2410 msgid "This allows attaching a debugger to the process." msgstr "ã“れã«ã‚ˆã‚Šãƒ‡ãƒãƒƒã‚¬ãŒãƒ—ãƒ­ã‚»ã‚¹ã«æŽ¥ç¶šã§ãã¾ã™ã€‚" -#: utils/misc/guc.c:1492 +#: utils/misc/guc.c:1868 msgid "Sets the default statistics target." -msgstr "デフォルトã®çµ±è¨ˆæƒ…報対象を設定ã—ã¾ã™ã€‚" +msgstr "デフォルトã®çµ±è¨ˆæƒ…å ±åŽé›†ç›®æ¨™ã‚’設定。" -#: utils/misc/guc.c:1493 +#: utils/misc/guc.c:1869 msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." -msgstr "ALTER TABLE SET STATISTICS経由ã§åˆ—指定ã®å¯¾è±¡ã‚’æŒãŸãªã„テーブル列ã«ã¤ã„ã¦ã®ãƒ‡ãƒ•ォルトã®çµ±è¨ˆæƒ…報対象を設定ã—ã¾ã™ã€‚" +msgstr "ALTER TABLE SET STATISTICS経由ã§åˆ—固有ã®ç›®æ¨™å€¤ã‚’æŒãŸãªã„テーブル列ã«ã¤ã„ã¦ã®çµ±è¨ˆæƒ…å ±åŽé›†ç›®æ¨™ã‚’設定ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1502 +#: utils/misc/guc.c:1878 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." -msgstr "副å•ã„åˆã‚ã›ã‚’折りãŸãŸã¾ãªã„上é™ã®FROMリストã®ã‚µã‚¤ã‚ºã‚’設定ã—ã¾ã™ã€‚" +msgstr "副å•ã„åˆã‚ã›ã‚’展開ã™ã‚‹ä¸Šé™ã®FROMリストã®ã‚µã‚¤ã‚ºã‚’設定。" -#: utils/misc/guc.c:1504 +#: utils/misc/guc.c:1880 msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." -msgstr "最終的ãªFROMリストãŒã“ã®å€¤ä»¥ä¸Šå¤šããªã„å ´åˆã€ãƒ—ランナã¯å‰¯å•ã„åˆã‚ã›ã‚’上ä½å•ã„åˆã‚ã›ã«ãƒžãƒ¼ã‚¸ã—ã¾ã™ã€‚" +msgstr "最終的ãªFROMリストãŒã“ã®å€¤ã‚ˆã‚Šå¤šãã®è¦ç´ ã‚’æŒãŸãªã„時ã«ã€ãƒ—ランナã¯å‰¯å•ã„åˆã‚ã›ã‚’上ä½å•ã„åˆã‚ã›ã«ãƒžãƒ¼ã‚¸ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1514 +#: utils/misc/guc.c:1890 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." -msgstr "JOINå¼ã‚’å¹³å¦åŒ–ã—ãªã„上é™ã®FROMリストã®ã‚µã‚¤ã‚ºã‚’設定ã—ã¾ã™ã€‚" +msgstr "JOINå¼ã‚’å¹³å¦åŒ–ã™ã‚‹ä¸Šé™ã®FROMリストã®ã‚µã‚¤ã‚ºã‚’設定。" -#: utils/misc/guc.c:1516 +#: utils/misc/guc.c:1892 msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." -msgstr "最終的ã«ãƒªã‚¹ãƒˆãŒã“ã®å€¤ä»¥ä¸‹ã®é …目数ã«ãªã‚‹æ™‚ã€ãƒ—ランナã¯ã€æ˜Žç¤ºçš„ãªJOIN構文をFROMé …ç›®ã®ãƒªã‚¹ãƒˆã«ç›´ã—ã¾ã™ã€‚ " +msgstr "最終的ã«FROMリストã®é …目数ãŒã“ã®å€¤ã‚’è¶…ãˆãªã„時ã«ã¯å¸¸ã«ã€ãƒ—ãƒ©ãƒ³ãƒŠã¯æ˜Žç¤ºçš„ãªJOIN構文をFROMé …ç›®ã®ãƒªã‚¹ãƒˆã«çµ„ã¿è¾¼ã¿ã¾ã™ã€‚" -#: utils/misc/guc.c:1526 +#: utils/misc/guc.c:1902 msgid "Sets the threshold of FROM items beyond which GEQO is used." -msgstr "GEQOを使用ã™ã‚‹FROMアイテム数ã®é–¾å€¤ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ã“ã®æ•°ã‚’è¶…ãˆã‚‹ã¨GEQOを使用ã™ã‚‹FROM項目数ã®é–¾å€¤ã‚’設定。" -#: utils/misc/guc.c:1535 +#: utils/misc/guc.c:1911 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: effortã¯ä»–ã®GEQOパラメータã®ãƒ‡ãƒ•ォルトを設定ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•れã¾ã™ã€‚" -#: utils/misc/guc.c:1544 +#: utils/misc/guc.c:1920 msgid "GEQO: number of individuals in the population." -msgstr "GEQO: éºä¼çš„個体群内ã®å€‹ä½“æ•°ã§ã™ã€‚" +msgstr "GEQO: 集団内ã®å€‹ä½“数。" -#: utils/misc/guc.c:1545 utils/misc/guc.c:1554 +#: utils/misc/guc.c:1921 utils/misc/guc.c:1930 msgid "Zero selects a suitable default value." msgstr "0ã¯é©åˆ‡ãªãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã‚’é¸æŠžã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1553 +#: utils/misc/guc.c:1929 msgid "GEQO: number of iterations of the algorithm." -msgstr "GEQO: アルゴリズムã®å復数ã§ã™ã€‚" +msgstr "GEQO: アルゴリズムã®å復回数ã§ã™ã€‚" -#: utils/misc/guc.c:1564 +#: utils/misc/guc.c:1940 msgid "Sets the time to wait on a lock before checking for deadlock." -msgstr "デッドロック状態ãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’調ã¹ã‚‹å‰ã«ãƒ­ãƒƒã‚¯ã‚’å¾…ã¤æ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "デッドロック状態ãŒã‚ã‚‹ã‹ã©ã†ã‹ã‚’調ã¹ã‚‹å‰ã«ãƒ­ãƒƒã‚¯ã‚’å¾…ã¤æ™‚間を設定。" -#: utils/misc/guc.c:1575 +#: utils/misc/guc.c:1951 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." -msgstr "ホットスタンãƒã‚¤ã‚µãƒ¼ãƒãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れ㟠WAL データを処ç†ã—ã¦ã„ã‚‹å ´åˆã¯ã€ã‚¯ã‚¨ãƒªã‚’キャンセルã™ã‚‹å‰ã«é…å»¶ç§’æ•°ã®æœ€å¤§å€¤ã‚’セットã—ã¦ãã ã•ã„。" +msgstr "ホットスタンãƒã‚¤ã‚µãƒ¼ãƒãŒã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•れ㟠WAL データを処ç†ã—ã¦ã„ã‚‹å ´åˆã¯ã€å•ã„åˆã‚ã›ã‚’キャンセルã™ã‚‹å‰ã«é…å»¶ç§’æ•°ã®æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:1586 +#: utils/misc/guc.c:1962 msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." -msgstr "ホットスタンãƒã‚¤ã‚µãƒ¼ãƒãŒã‚¹ãƒˆãƒªãƒ¼ãƒ ã® WAL データを処ç†ã—ã¦ã„ã‚‹å ´åˆã¯ã€ã‚¯ã‚¨ãƒªã‚’キャンセルã™ã‚‹å‰ã«é…å»¶ç§’æ•°ã®æœ€å¤§å€¤ã‚’セットã—ã¦ãã ã•ã„。" +msgstr "ホットスタンãƒã‚¤ã‚µãƒ¼ãƒãŒã‚¹ãƒˆãƒªãƒ¼ãƒ ã® WAL データを処ç†ã—ã¦ã„ã‚‹å ´åˆã¯ã€å•ã„åˆã‚ã›ã‚’キャンセルã™ã‚‹å‰ã«é…å»¶ç§’æ•°ã®æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:1597 +#: utils/misc/guc.c:1973 msgid "Sets the maximum interval between WAL receiver status reports to the primary." -msgstr "WALå—信処ç†ã‹ã‚‰ãƒ—ライマリã¸ã®çŠ¶æ…‹å ±å‘Šã®æœ€å¤§é–“隔を設定ã—ã¾ã™" +msgstr "WALå—信処ç†ã‹ã‚‰ãƒ—ライマリã¸ã®çŠ¶æ…‹å ±å‘Šã®æœ€å¤§é–“隔を設定。" -#: utils/misc/guc.c:1608 -#| msgid "Sets the maximum interval between WAL receiver status reports to the primary." +#: utils/misc/guc.c:1984 msgid "Sets the maximum wait time to receive data from the primary." -msgstr "プライマリã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿å—信を待機ã™ã‚‹æœ€å¤§æ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "プライマリã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿å—信を待機ã™ã‚‹æœ€å¤§æ™‚間を設定。" -#: utils/misc/guc.c:1619 +#: utils/misc/guc.c:1995 msgid "Sets the maximum number of concurrent connections." -msgstr "åŒæ™‚æŽ¥ç¶šæ•°ã®æœ€å¤§å€¤ã‚’設定ã—ã¾ã™ã€‚" +msgstr "åŒæ™‚æŽ¥ç¶šæ•°ã®æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:1629 +#: utils/misc/guc.c:2006 msgid "Sets the number of connection slots reserved for superusers." -msgstr "スーパーユーザã«ã‚ˆã‚‹æŽ¥ç¶šç”¨ã«äºˆç´„ã•ã‚Œã‚‹æŽ¥ç¶šã‚¹ãƒ­ãƒƒãƒˆã®æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "スーパーユーザã«ã‚ˆã‚‹æŽ¥ç¶šç”¨ã«äºˆç´„ã•ã‚Œã‚‹æŽ¥ç¶šã‚¹ãƒ­ãƒƒãƒˆã®æ•°ã‚’設定。" -#: utils/misc/guc.c:1643 +#: utils/misc/guc.c:2020 msgid "Sets the number of shared memory buffers used by the server." -msgstr "サーãƒã§ä½¿ç”¨ã•れる共有メモリã®ãƒãƒƒãƒ•ァ数を設定ã—ã¾ã™ã€‚" +msgstr "サーãƒã§ä½¿ç”¨ã•れる共有メモリã®ãƒãƒƒãƒ•ァ数を設定。" -#: utils/misc/guc.c:1654 +#: utils/misc/guc.c:2031 msgid "Sets the maximum number of temporary buffers used by each session." -msgstr "å„セッションã§ä½¿ç”¨ã•れる一時ãƒãƒƒãƒ•ã‚¡ã®æœ€å¤§æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "å„セッションã§ä½¿ç”¨ã•れる一時ãƒãƒƒãƒ•ã‚¡ã®æœ€å¤§æ•°ã‚’設定。" -#: utils/misc/guc.c:1665 +#: utils/misc/guc.c:2042 msgid "Sets the TCP port the server listens on." -msgstr "サーãƒãŒæŽ¥ç¶šã‚’監視ã™ã‚‹TCPãƒãƒ¼ãƒˆã‚’設定ã—ã¾ã™ã€‚" +msgstr "サーãƒãŒæŽ¥ç¶šã‚’監視ã™ã‚‹TCPãƒãƒ¼ãƒˆã‚’設定。" -#: utils/misc/guc.c:1675 +#: utils/misc/guc.c:2052 msgid "Sets the access permissions of the Unix-domain socket." -msgstr "Unixドメインソケットã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’設定ã—ã¾ã™ã€‚" +msgstr "Unixドメインソケットã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’設定。" -#: utils/misc/guc.c:1676 +#: utils/misc/guc.c:2053 msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" -msgstr "Unixドメインソケットã¯ã€é€šå¸¸ã®Unixファイルシステム権é™ã®è¨­å®šã‚’使ã„ã¾ã™ã€‚ ã“ã®ãƒ‘ラメータ値㯠chmod 㨠umask システムコールãŒå—ã‘付ã‘る数値ã®ãƒ¢ãƒ¼ãƒ‰æŒ‡å®šã‚’想定ã—ã¦ã„ã¾ã™ï¼ˆæ…£ç¿’çš„ãª8進数書å¼ã‚’使ã†ãŸã‚ã«ã¯ã€0(ゼロ)ã§å§‹ã¾ã‚‰ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“)。 " +msgstr "Unixドメインソケットã¯ã€é€šå¸¸ã®Unixファイルシステム権é™ã®è¨­å®šã‚’使ã„ã¾ã™ã€‚ ã“ã®ãƒ‘ラメータ値㯠chmod 㨠umask システムコールãŒå—ã‘付ã‘る数値ã®ãƒ¢ãƒ¼ãƒ‰æŒ‡å®šã‚’想定ã—ã¦ã„ã¾ã™ï¼ˆæ…£ç¿’çš„ãª8進数書å¼ã‚’使ã†ãŸã‚ã«ã¯ã€0(ゼロ)ã§å§‹ã‚ãªãã¦ã¯ãªã‚Šã¾ã›ã‚“)。 " -#: utils/misc/guc.c:1690 +#: utils/misc/guc.c:2067 msgid "Sets the file permissions for log files." -msgstr "ログファイルã®ãƒ‘ーミッションを設定ã—ã¾ã™ã€‚" +msgstr "ログファイルã®ãƒ‘ーミッションを設定。" -#: utils/misc/guc.c:1691 +#: utils/misc/guc.c:2068 msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" -msgstr "ã“ã®ãƒ‘タメータ値㯠chmod ã‚„ umask システムコールã§ä½¿ãˆã‚‹ã‚ˆã†ãªæ•°å€¤ãƒ¢ãƒ¼ãƒ‰æŒ‡å®šã§ã‚ã‚‹ã“ã¨ãŒæƒ³å®šã•れã¾ã™ï¼ˆæ…£ç¿’çš„ãªè¨˜æ³•ã§ã‚ã‚‹ 8 進数書å¼ã‚’使ã†å ´åˆã¯å…ˆé ­ã« 0 (ゼロ) ã‚’ã¤ã‘ã¦ãã ã•ã„)。 " +msgstr "ã“ã®ãƒ‘タメータ値㯠chmod ã‚„ umask システムコールã§ä½¿ãˆã‚‹ã‚ˆã†ãªæ•°å€¤ãƒ¢ãƒ¼ãƒ‰æŒ‡å®šã§ã‚ã‚‹ã“ã¨ãŒæƒ³å®šã•れã¾ã™ï¼ˆæ…£ç¿’çš„ãªè¨˜æ³•ã§ã‚ã‚‹8進数書å¼ã‚’使ã†å ´åˆã¯å…ˆé ­ã«0(ゼロ) ã‚’ã¤ã‘ã¦ãã ã•ã„)。 " -#: utils/misc/guc.c:1704 +#: utils/misc/guc.c:2082 +msgid "Mode of the data directory." +msgstr "データディレクトリã®ãƒ‘ーミッション値。" + +#: utils/misc/guc.c:2083 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "ã“ã®ãƒ‘タメータ値㯠chmod ã‚„ umask システムコールãŒå—ã‘付ã‘る数値形å¼ã®ãƒ¢ãƒ¼ãƒ‰æŒ‡å®šã§ã™ï¼ˆæ…£ç¿’çš„ãª8進形å¼ã‚’使ã†å ´åˆã¯å…ˆé ­ã«0(ゼロ) ã‚’ã¤ã‘ã¦ãã ã•ã„)。 " + +#: utils/misc/guc.c:2096 msgid "Sets the maximum memory to be used for query workspaces." -msgstr "å•ã„åˆã‚ã›ã®ä½œæ¥­ç”¨ç©ºé–“ã¨ã—ã¦ä½¿ç”¨ã•ã‚Œã‚‹ãƒ¡ãƒ¢ãƒªã®æœ€å¤§å€¤ã‚’設定ã—ã¾ã™ã€‚" +msgstr "å•ã„åˆã‚ã›ã®ä½œæ¥­ç”¨ç©ºé–“ã¨ã—ã¦ä½¿ç”¨ã•ã‚Œã‚‹ãƒ¡ãƒ¢ãƒªã®æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:1705 +#: utils/misc/guc.c:2097 msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." -msgstr "一時ディスクファイルã¸ã®åˆ‡æ›¿ãˆã‚’行ã†å‰ã«ã€å†…部ソートæ“作ã¨ãƒãƒƒã‚·ãƒ¥ãƒ†ãƒ¼ãƒ–ルã§ä½¿ã‚れるメモリã®é‡ã‚’指定ã—ã¾ã™ã€‚" +msgstr "内部ソートæ“作ã¨ãƒãƒƒã‚·ãƒ¥ãƒ†ãƒ¼ãƒ–ルã§ä½¿ã‚れるメモリã®é‡ãŒã“ã®é‡ã«é”ã—ãŸæ™‚ã«ä¸€æ™‚ディスクファイルã¸ã®åˆ‡æ›¿ãˆã‚’行ã„ã¾ã™ã€‚" -#: utils/misc/guc.c:1717 +#: utils/misc/guc.c:2109 msgid "Sets the maximum memory to be used for maintenance operations." -msgstr "ä¿å®ˆä½œæ¥­ã§ä½¿ç”¨ã•れる最大メモリé‡ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ä¿å®ˆä½œæ¥­ã§ä½¿ç”¨ã•れる最大メモリé‡ã‚’設定。" -#: utils/misc/guc.c:1718 +#: utils/misc/guc.c:2110 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "VACUUMã‚„CREATE INDEXãªã©ã®ä½œæ¥­ãŒå«ã¾ã‚Œã¾ã™ã€‚" -#: utils/misc/guc.c:1733 +#: utils/misc/guc.c:2125 msgid "Sets the maximum stack depth, in kilobytes." -msgstr "ã‚¹ã‚¿ãƒƒã‚¯é•·ã®æœ€å¤§å€¤ã‚’キロãƒã‚¤ãƒˆå˜ä½ã§è¨­å®šã—ã¾ã™ã€‚" +msgstr "ã‚¹ã‚¿ãƒƒã‚¯é•·ã®æœ€å¤§å€¤ã‚’キロãƒã‚¤ãƒˆå˜ä½ã§è¨­å®šã€‚" -#: utils/misc/guc.c:1744 -msgid "Limits the total size of all temporary files used by each session." -msgstr "å„セッションã§ä½¿ç”¨ã•れる一時ファイルã™ã¹ã¦ã®æœ€å¤§ã‚µã‚¤ã‚ºã‚’設定ã—ã¾ã™ã€‚" +#: utils/misc/guc.c:2136 +msgid "Limits the total size of all temporary files used by each process." +msgstr "å„プロセスã§ä½¿ç”¨ã•れる全ã¦ã®ä¸€æ™‚ファイルã®åˆè¨ˆã‚µã‚¤ã‚ºã‚’制é™ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1745 +#: utils/misc/guc.c:2137 msgid "-1 means no limit." -msgstr "-1ã¯ç„¡åˆ¶é™ã‚’æ„味ã—ã¾ã™" +msgstr "-1ã¯ç„¡åˆ¶é™ã‚’æ„味ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1755 +#: utils/misc/guc.c:2147 msgid "Vacuum cost for a page found in the buffer cache." -msgstr "ãƒãƒƒãƒ•ァキャッシュã«ã‚ã‚‹ãƒãƒƒãƒ•ã‚¡ã‚’ãƒã‚­ãƒ¥ãƒ¼ãƒ ã™ã‚‹éš›ã®ã‚³ã‚¹ãƒˆã§ã™ã€‚" +msgstr "ãƒãƒƒãƒ•ァキャッシュã«ã‚ã‚‹1ã¤ã®ãƒšãƒ¼ã‚¸ã‚’VACUUM処ç†ã™ã‚‹éš›ã®ã‚³ã‚¹ãƒˆã€‚" -#: utils/misc/guc.c:1765 +#: utils/misc/guc.c:2157 msgid "Vacuum cost for a page not found in the buffer cache." -msgstr "ãƒãƒƒãƒ•ァキャッシュã«ãªã„ãƒãƒƒãƒ•ã‚¡ã‚’ãƒã‚­ãƒ¥ãƒ¼ãƒ ã™ã‚‹éš›ã®ã‚³ã‚¹ãƒˆã§ã™ã€‚" +msgstr "ãƒãƒƒãƒ•ァキャッシュã«ãªã„1ã¤ã®ãƒšãƒ¼ã‚¸ã‚’VACUUM処ç†ã™ã‚‹éš›ã®ã‚³ã‚¹ãƒˆã€‚" -#: utils/misc/guc.c:1775 +#: utils/misc/guc.c:2167 msgid "Vacuum cost for a page dirtied by vacuum." -msgstr "ãƒã‚­ãƒ¥ãƒ¼ãƒ å‡¦ç†ãŒãƒšãƒ¼ã‚¸ã‚’変更ã™ã‚‹éš›ã«èª²ã›ã‚‰ã‚Œã‚‹ã‚³ã‚¹ãƒˆã§ã™ã€‚" +msgstr "VACUUM処ç†ãŒ1ã¤ã®ãƒšãƒ¼ã‚¸ã‚’ダーティã«ã—ãŸéš›ã«èª²ã™ã‚³ã‚¹ãƒˆã€‚" -#: utils/misc/guc.c:1785 +#: utils/misc/guc.c:2177 msgid "Vacuum cost amount available before napping." -msgstr "ãƒã‚­ãƒ¥ãƒ¼ãƒ å‡¦ç†ãƒ—ロセスãŒä¼‘æ­¢ã™ã‚‹ã“ã¨ã«ãªã‚‹ã‚³ã‚¹ãƒˆã®åˆè¨ˆã§ã™ã€‚ " +msgstr "VACUUM処ç†ã‚’一時休止ã•ã›ã‚‹ã¾ã§ã«ä½¿ç”¨ã§ãるコスト。" -#: utils/misc/guc.c:1795 +#: utils/misc/guc.c:2187 msgid "Vacuum cost delay in milliseconds." -msgstr "ミリ秒å˜ä½ã®ã‚³ã‚¹ãƒˆãƒ™ãƒ¼ã‚¹ã®ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®é…延時間ã§ã™ã€‚" +msgstr "ミリ秒å˜ä½ã®ã‚³ã‚¹ãƒˆãƒ™ãƒ¼ã‚¹ã®VACUUM処ç†ã®é…延時間ã§ã™ã€‚" -#: utils/misc/guc.c:1806 +#: utils/misc/guc.c:2198 msgid "Vacuum cost delay in milliseconds, for autovacuum." -msgstr "autovacuum用ã®ãƒŸãƒªç§’å˜ä½ã®ã‚³ã‚¹ãƒˆãƒ™ãƒ¼ã‚¹ã®ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®é…延時間ã§ã™ã€‚" +msgstr "自動VACUUM用ã®ãƒŸãƒªç§’å˜ä½ã®ã‚³ã‚¹ãƒˆãƒ™ãƒ¼ã‚¹ã®VACUUM処ç†ã®é…延時間ã§ã™ã€‚" -#: utils/misc/guc.c:1817 +#: utils/misc/guc.c:2209 msgid "Vacuum cost amount available before napping, for autovacuum." -msgstr "autovacuum用ã®ãƒã‚­ãƒ¥ãƒ¼ãƒ å‡¦ç†ãƒ—ロセスãŒä¼‘æ­¢ã™ã‚‹ã“ã¨ã«ãªã‚‹ã‚³ã‚¹ãƒˆã®åˆè¨ˆã§ã™ã€‚ " +msgstr "自動VACUUM用ã®VACUUM処ç†ã‚’一時休止ã•ã›ã‚‹ã¾ã§ã«ä½¿ç”¨ã§ãるコスト。" -#: utils/misc/guc.c:1827 +#: utils/misc/guc.c:2219 msgid "Sets the maximum number of simultaneously open files for each server process." -msgstr "å„サーãƒå­ãƒ—ロセスã§åŒæ™‚ã«ã‚ªãƒ¼ãƒ—ンã§ãã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¤§æ•°ã‚’設定ã—ã¾ã™ã€‚ " +msgstr "å„サーãƒãƒ—ロセスã§åŒæ™‚ã«ã‚ªãƒ¼ãƒ—ンã§ãã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã®æœ€å¤§æ•°ã‚’設定。" -#: utils/misc/guc.c:1840 +#: utils/misc/guc.c:2232 msgid "Sets the maximum number of simultaneously prepared transactions." -msgstr "準備ã•れãŸ1トランザクションã®åŒæ™‚最大数を設定ã—ã¾ã™ã€‚" +msgstr "åŒæ™‚ã«æº–備状態ã«ã§ãã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æœ€å¤§æ•°ã‚’設定。" + +#: utils/misc/guc.c:2243 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "ロックã®è¿½è·¡ã‚’行ã†ãƒ†ãƒ¼ãƒ–ãƒ«ã®æœ€å°ã®OIDを設定。" -#: utils/misc/guc.c:1873 +#: utils/misc/guc.c:2244 +msgid "Is used to avoid output on system tables." +msgstr "システムテーブルã«é–¢ã™ã‚‹ã®å‡ºåŠ›ã‚’é¿ã‘ã‚‹ãŸã‚ã«ä½¿ã„ã¾ã™ã€‚" + +#: utils/misc/guc.c:2253 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "ç„¡æ¡ä»¶ã§ãƒ­ãƒƒã‚¯ã®è¿½è·¡ã‚’行ã†ãƒ†ãƒ¼ãƒ–ルã®OIDを設定。" + +#: utils/misc/guc.c:2265 msgid "Sets the maximum allowed duration of any statement." -msgstr "å…¨ã¦ã®æ–‡ã®æœ€å¤§å®Ÿè¡Œæ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "ã‚らゆる文ã«å¯¾ã—ã¦å®Ÿè¡Œæ™‚é–“ã¨ã—ã¦è¨±å®¹ã™ã‚‹ä¸Šé™å€¤ã‚’設定。" -#: utils/misc/guc.c:1874 utils/misc/guc.c:1885 +#: utils/misc/guc.c:2266 utils/misc/guc.c:2277 utils/misc/guc.c:2288 msgid "A value of 0 turns off the timeout." -msgstr "ゼロã¨ã„ã†å€¤ã¯ã“ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã‚’無効ã«ã—ã¾ã™ã€‚ " +msgstr "0ã§ã“ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã¯ç„¡åйã«ãªã‚Šã¾ã™ã€‚ " -#: utils/misc/guc.c:1884 -#| msgid "Sets the maximum allowed duration of any statement." +#: utils/misc/guc.c:2276 msgid "Sets the maximum allowed duration of any wait for a lock." -msgstr "何らã‹ã®ãƒ­ãƒƒã‚¯å¾…機ã«ãŠã„ã¦è¨±å®¹ã•れる最大期間を設定ã—ã¾ã™ã€‚" +msgstr "ロックã®å¾…機時間ã¨ã—ã¦è¨±å®¹ã™ã‚‹æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2287 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "ã‚らゆるアイドル状態ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æŒç¶šæ™‚é–“ã¨ã—ã¦è¨±å®¹ã™ã‚‹ä¸Šé™å€¤ã‚’設定。" -#: utils/misc/guc.c:1895 +#: utils/misc/guc.c:2298 msgid "Minimum age at which VACUUM should freeze a table row." -msgstr "VACUUM ãŒãƒ†ãƒ¼ãƒ–ル行をå‡çµã™ã‚‹ã¾ã§ã®æœ€å°æ™‚é–“" +msgstr "VACUUM ãŒãƒ†ãƒ¼ãƒ–ル行をå‡çµã™ã‚‹ã¾ã§ã®æœ€å°ã®ãƒ†ãƒ¼ãƒ–ル年齢" -#: utils/misc/guc.c:1905 +#: utils/misc/guc.c:2308 msgid "Age at which VACUUM should scan whole table to freeze tuples." -msgstr "テーブル行をå‡çµã™ã‚‹ãŸã‚ã« VACUUM ãŒãƒ†ãƒ¼ãƒ–ル全体をスキャンã™ã‚‹ã¾ã§ã®æ™‚é–“" +msgstr "行ã®å‡çµã®ãŸã‚ã®å…¨ãƒ†ãƒ¼ãƒ–ルスキャンを強制ã™ã‚‹ãƒ†ãƒ¼ãƒ–ル年齢" + +#: utils/misc/guc.c:2318 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "テーブル行ã§ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³IDã®å‡çµã‚’強制ã™ã‚‹æœ€å°ã®ãƒ†ãƒ¼ãƒ–ル年齢" + +#: utils/misc/guc.c:2328 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "行ã®å‡çµã®ãŸã‚ã«å…¨ãƒ†ãƒ¼ãƒ–ルスキャンを強制ã™ã‚‹ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ†ãƒ¼ãƒ–ル年齢" -#: utils/misc/guc.c:1915 +#: utils/misc/guc.c:2338 msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." -msgstr "ã‚‚ã—ã‚れã°ã€VACUUM ã‚„ HOT ã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—ã‚’é…å»¶ã•ã›ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³æ•°" +msgstr "設定ã—ã¦ã„れã°ã€VACUUMã‚„HOTã®ã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—ã‚’é…å»¶ã•ã›ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³æ•°ã€‚" -#: utils/misc/guc.c:1928 +#: utils/misc/guc.c:2351 msgid "Sets the maximum number of locks per transaction." -msgstr "1トランザクション当ãŸã‚Šã®æœ€å¤§ãƒ­ãƒƒã‚¯æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "1トランザクション当ãŸã‚Šã®ãƒ­ãƒƒã‚¯æ•°ã®ä¸Šé™ã‚’設定。" -#: utils/misc/guc.c:1929 +#: utils/misc/guc.c:2352 msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." -msgstr "共有ロックテーブルã®å¤§ãã•ã¯ã€æœ€å¤§max_locks_per_transaction * max_connections個ã®å€‹åˆ¥ã®ã‚ªãƒ–ジェクトãŒã‚る時点ã§ãƒ­ãƒƒã‚¯ã•れる必è¦ãŒã‚ã‚‹ã¨ã„ã†ä»®å®šã§æ±ºå®šã•れã¾ã™ã€‚" +msgstr "共有ロックテーブルã®å¤§ãã•ã¯ã€æœ€å¤§max_locks_per_transaction * max_connections個ã®å€‹åˆ¥ã®ã‚ªãƒ–ジェクトãŒã„ã‹ãªã‚‹æ™‚点ã§ã‚‚ロックã•れる必è¦ãŒã‚ã‚‹ã¨ã„ã†ä»®å®šã®ä¸‹ã«æ±ºå®šã•れã¾ã™ã€‚" -#: utils/misc/guc.c:1940 +#: utils/misc/guc.c:2363 msgid "Sets the maximum number of predicate locks per transaction." -msgstr "1 トランザクション当ãŸã‚Šã®æœ€å¤§ãƒ­ãƒƒã‚¯æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "1トランザクション当ãŸã‚Šã®è¿°èªžãƒ­ãƒƒã‚¯æ•°ã®ä¸Šé™ã‚’設定。" -#: utils/misc/guc.c:1941 +#: utils/misc/guc.c:2364 msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." -msgstr "共有ロックテーブルã®å¤§ãã•ã¯ã€æœ€å¤§ max_pred_locks_per_transaction * max_connections 個ã®å€‹åˆ¥ã®ã‚ªãƒ–ジェクトãŒåŒæ™‚ã«ãƒ­ãƒƒã‚¯ã•れる必è¦ãŒã‚ã‚‹ã¨ã„ã†ä»®å®šã®å…ƒã«æ±ºã‚られã¾ã™ã€‚" +msgstr "共有ロックテーブルã®å¤§ãã•ã¯ã€æœ€å¤§ max_pred_locks_per_transaction * max_connections 個ã®å€‹åˆ¥ã®ã‚ªãƒ–ジェクトãŒã„ã‹ãªã‚‹æ™‚点ã§ã‚‚ロックã•れる必è¦ãŒã‚ã‚‹ã¨ã„ã†ä»®å®šã®ä¸‹ã«æ±ºã‚られã¾ã™ã€‚" + +#: utils/misc/guc.c:2375 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "1リレーション当ãŸã‚Šã§è¿°èªžãƒ­ãƒƒã‚¯ã•れるページã¨ã‚¿ãƒ—ãƒ«ã®æ•°ã®ä¸Šé™å€¤ã‚’設定。" -#: utils/misc/guc.c:1952 +#: utils/misc/guc.c:2376 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "ã‚るコãƒã‚¯ã‚·ãƒ§ãƒ³ã§ã€åŒã˜ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³å†…ã§ãƒ­ãƒƒã‚¯ã•れるページ数ã¨ã‚¿ãƒ—ル数ã®åˆè¨ˆãŒã“ã®å€¤ã‚’è¶…ãˆãŸã¨ãã«ã¯ã€ã“れらã®ãƒ­ãƒƒã‚¯ã¯ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãƒ¬ãƒ™ãƒ«ã®ãƒ­ãƒƒã‚¯ã«ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚" + +#: utils/misc/guc.c:2386 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "1ページã‚ãŸã‚Šã§è¿°èªžãƒ­ãƒƒã‚¯ã•れるタプル数ã®ä¸Šé™å€¤ã‚’設定。" + +#: utils/misc/guc.c:2387 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "ã‚るコãƒã‚¯ã‚·ãƒ§ãƒ³ã§ ã€åŒã˜ãƒšãƒ¼ã‚¸ä¸Šã§ãƒ­ãƒƒã‚¯ã•ã‚Œã‚‹ã‚¿ãƒ—ãƒ«ã®æ•°ãŒã“ã®å€¤ã‚’è¶…ãˆãŸã¨ãã«ã¯ã€ã“れらã®ãƒ­ãƒƒã‚¯ã¯ãƒšãƒ¼ã‚¸ãƒ¬ãƒ™ãƒ«ã®ãƒ­ãƒƒã‚¯ã«ç½®ãæ›ãˆã‚‰ã‚Œã¾ã™ã€‚" + +#: utils/misc/guc.c:2397 msgid "Sets the maximum allowed time to complete client authentication." -msgstr "クライアントèªè¨¼ã®å®Œäº†ã¾ã§ã®æœ€å¤§æ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "クライアントèªè¨¼ã®å®Œäº†ã¾ã§ã®æ‰€è¦æ™‚é–“ã¨ã—ã¦è¨±å®¹ã™ã‚‹æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:1964 +#: utils/misc/guc.c:2409 msgid "Waits N seconds on connection startup before authentication." -msgstr "èªè¨¼å‰ã®æŽ¥ç¶šé–‹å§‹ã¾ã§N秒待機ã—ã¾ã™ã€‚" +msgstr "接続開始ã®éš›ã€èªè¨¼å‰ã«N秒待機ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:1975 +#: utils/misc/guc.c:2420 msgid "Sets the number of WAL files held for standby servers." -msgstr "待機用サーãƒã§ä¿æŒã•れる WAL ファイル数を設定ã—ã¾ã™ã€‚" +msgstr "スタンãƒã‚¤ã‚µãƒ¼ãƒã®ãŸã‚ã«ä¿æŒã™ã‚‹WALファイル数を設定。" -#: utils/misc/guc.c:1985 -msgid "Sets the maximum distance in log segments between automatic WAL checkpoints." -msgstr "自動WALãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®é–“ã®æœ€å¤§è·é›¢ã‚’ã€ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã®æ•°ã§è¨­å®šã—ã¾ã™ã€‚" +#: utils/misc/guc.c:2430 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "WALを縮å°ã•ã›ã‚‹éš›ã®æœ€å°ã®ã‚µã‚¤ã‚ºã‚’設定。" -#: utils/misc/guc.c:1995 +#: utils/misc/guc.c:2442 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å¥‘機ã¨ãªã‚‹WALã®ã‚µã‚¤ã‚ºã‚’指定。" + +#: utils/misc/guc.c:2454 msgid "Sets the maximum time between automatic WAL checkpoints." -msgstr "自動WALãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®æœ€å¤§é–“隔を設定ã—ã¾ã™ã€‚" +msgstr "自動WALãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®æœ€å¤§é–“隔を設定。" -#: utils/misc/guc.c:2006 +#: utils/misc/guc.c:2465 msgid "Enables warnings if checkpoint segments are filled more frequently than this." -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚»ã‚°ãƒ¡ãƒ³ãƒˆã®æº¢ã‚Œé »åº¦ãŒã“れよりも多ã‘れã°è­¦å‘Šã—ã¾ã™ã€‚" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒã“ã®å€¤ã‚ˆã‚Šã‚‚çŸ­ã„æ™‚é–“ã§ä½¿ã„åˆ‡ã‚‰ã‚ŒãŸæ™‚ã«è­¦å‘Šã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2008 +#: utils/misc/guc.c:2467 msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." -msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚»ã‚°ãƒ¡ãƒ³ãƒˆãƒ•ã‚¡ã‚¤ãƒ«ãŒæº¢ã‚Œã‚‹ã“ã¨ãŒåŽŸå› ã§èµ·ãã‚‹ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒã€ã“ã“ã§æŒ‡å®šã—ãŸç§’数よりも頻ç¹ã«ç™ºç”Ÿã™ã‚‹å ´åˆã€ã‚µãƒ¼ãƒãƒ­ã‚°ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’書ã出ã—ã¾ã™ã€‚ デフォルトã¯30ç§’ã§ã™ã€‚ ゼロã¯ã“ã®è­¦å‘Šã‚’無効ã«ã—ã¾ã™ã€‚ " +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚»ã‚°ãƒ¡ãƒ³ãƒˆãƒ•ァイルを使ã„切るã“ã¨ãŒåŽŸå› ã§èµ·ãã‚‹ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒã€ã“ã“ã§æŒ‡å®šã—ãŸç§’数よりも頻ç¹ã«ç™ºç”Ÿã™ã‚‹å ´åˆã€ã‚µãƒ¼ãƒãƒ­ã‚°ã«ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’書ã出ã—ã¾ã™ã€‚ デフォルトã¯30ç§’ã§ã™ã€‚ ゼロã¯ã“ã®è­¦å‘Šã‚’無効ã«ã—ã¾ã™ã€‚ " -#: utils/misc/guc.c:2020 +#: utils/misc/guc.c:2479 utils/misc/guc.c:2636 utils/misc/guc.c:2664 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "ã™ã§ã«å®Ÿè¡Œã•ã‚ŒãŸæ›¸ãè¾¼ã¿ãŒãƒ‡ã‚£ã‚¹ã‚¯ã«æ›¸ã出ã•れるã¾ã§ã®ãƒšãƒ¼ã‚¸æ•°ã€‚" + +#: utils/misc/guc.c:2490 msgid "Sets the number of disk-page buffers in shared memory for WAL." -msgstr "共有メモリ内ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸã€WALデータ用ã®ãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ãƒãƒƒãƒ•ã‚¡æ•°ã§ã™ã€‚" +msgstr "共有メモリ内ã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸã€WALデータ用ã®ãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ãƒãƒƒãƒ•ァ数を設定。" -#: utils/misc/guc.c:2031 -msgid "WAL writer sleep time between WAL flushes." -msgstr "WALåã出ã—ã®é–“ã€WALライタãŒå¾…機ã™ã‚‹æ™‚é–“ã§ã™ã€‚" +#: utils/misc/guc.c:2501 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "WALライタã§å®Ÿè¡Œã™ã‚‹æ›¸ã出ã—ã®æ™‚間間隔。" -#: utils/misc/guc.c:2042 -#| msgid "Sets the maximum number of concurrent connections." -msgid "Sets the number of slots for concurrent xlog insertions." -msgstr "åŒæ™‚xlog挿入用ã®ã‚¹ãƒ­ãƒƒãƒˆæ•°ã‚’設定ã—ã¾ã™ã€‚" +#: utils/misc/guc.c:2512 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "書ã出ã—ãŒå®Ÿè¡Œã•れるã¾ã§ã«WALライタã§å‡ºåŠ›ã™ã‚‹WALã®é‡ã€‚" -#: utils/misc/guc.c:2054 +#: utils/misc/guc.c:2524 msgid "Sets the maximum number of simultaneously running WAL sender processes." -msgstr "WAL sender ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¤§åŒæ™‚実行数を設定ã—ã¾ã™ã€‚" +msgstr "WALé€ä¿¡ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¤§åŒæ™‚実行数を設定。" -#: utils/misc/guc.c:2064 +#: utils/misc/guc.c:2535 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "åŒæ™‚ã«å®šç¾©ã§ãã‚‹ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚¹ãƒ­ãƒƒãƒˆã®æ•°ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2545 msgid "Sets the maximum time to wait for WAL replication." -msgstr "WAL レプリケーションã®ãŸã‚ã®æœ€å¤§ã®å¾…ã¡æ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "WALãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å¾…ã¤æ™‚é–“ã®æœ€å¤§å€¤ã‚’設定。" -#: utils/misc/guc.c:2075 +#: utils/misc/guc.c:2556 msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." -msgstr "トランザクションã®ã‚³ãƒŸãƒƒãƒˆã‹ã‚‰WALãƒãƒƒãƒ•ã‚¡ã®ãƒ‡ã‚£ã‚¹ã‚¯åã出ã—ã¾ã§ã®é…延時間をマイクロ秒å˜ä½ã§è¨­å®šã—ã¾ã™ã€‚" +msgstr "トランザクションã®ã‚³ãƒŸãƒƒãƒˆã‹ã‚‰WALã®ãƒ‡ã‚£ã‚¹ã‚¯æ›¸ã出ã—ã¾ã§ã®é…延時間をマイクロ秒å˜ä½ã§è¨­å®šã€‚" -#: utils/misc/guc.c:2087 +#: utils/misc/guc.c:2568 msgid "Sets the minimum concurrent open transactions before performing commit_delay." -msgstr "commit_delayé…å»¶ã®å®Ÿè¡Œå‰ã«å¿…è¦ã¨ãªã‚‹ã€åŒæ™‚ã«é–‹ã„ã¦ã„ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®æœ€å°æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "commit_delay ã®å®Ÿè¡Œã®å¥‘機ã¨ãªã‚‹ã€åŒæ™‚ã«é–‹ã„ã¦ã„ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³æ•°ã®æœ€å°å€¤ã‚’設定。" -#: utils/misc/guc.c:2098 +#: utils/misc/guc.c:2579 msgid "Sets the number of digits displayed for floating-point values." -msgstr "æµ®å‹•å°æ•°ç‚¹å€¤ã®è¡¨ç¤ºæ¡æ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "æµ®å‹•å°æ•°ç‚¹å€¤ã®è¡¨ç¤ºæ¡æ•°ã‚’を設定。" -#: utils/misc/guc.c:2099 +#: utils/misc/guc.c:2580 msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." msgstr "ã“ã®ãƒ‘ラメータã¯ã€realã€double precisionã€å¹¾ä½•データ型ã«å½±éŸ¿ã—ã¾ã™ã€‚ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿å€¤ãŒæ¨™æº–çš„ãªæ¡æ•°(FLT_DIG ã‚‚ã—ã㯠DBL_DIGã©ã¡ã‚‰ã‹é©åˆ‡ãªæ–¹)ã«è¿½åŠ ã•れã¾ã™ã€‚" -#: utils/misc/guc.c:2110 +#: utils/misc/guc.c:2591 msgid "Sets the minimum execution time above which statements will be logged." -msgstr "ログをã¨ã‚‹æ–‡ã«ã¤ã„ã¦ã€ãã®æœ€å°ã®æ–‡å®Ÿè¡Œæ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "æ–‡ã®ãƒ­ã‚°ã‚’記録ã™ã‚‹æœ€å°ã®å®Ÿè¡Œæ™‚間を設定。" -#: utils/misc/guc.c:2112 +#: utils/misc/guc.c:2593 msgid "Zero prints all queries. -1 turns this feature off." -msgstr "ゼロã«ã™ã‚‹ã¨ã€å…¨ã¦ã®å•ã„åˆã‚ã›ã‚’出力ã—ã¾ã™ã€‚-1ã¯ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã™ã€‚" +msgstr "ゼロã«ã™ã‚‹ã¨å…¨ã¦ã®å•ã„åˆã‚ã›ã‚’出力ã—ã¾ã™ã€‚-1ã¯ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2122 +#: utils/misc/guc.c:2603 msgid "Sets the minimum execution time above which autovacuum actions will be logged." -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®æ´»å‹•をログã«ã¨ã‚‹æ–‡å ´åˆã®æœ€å°ã®å®Ÿè¡Œæ™‚間を設定ã—ã¾ã™ã€‚" +msgstr "自動VACUUMã®æ´»å‹•ã®ãƒ­ã‚°ã‚’記録ã™ã‚‹æœ€å°ã®å®Ÿè¡Œæ™‚間を設定。" -#: utils/misc/guc.c:2124 +#: utils/misc/guc.c:2605 msgid "Zero prints all actions. -1 turns autovacuum logging off." -msgstr "ゼロã¯ã™ã¹ã¦ã®æ´»å‹•を出力ã—ã¾ã™ã€‚-1ã¯è‡ªå‹•ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®ãƒ­ã‚°è¨˜éŒ²ã‚’無効ã«ã—ã¾ã™ã€‚" +msgstr "ゼロã¯ã™ã¹ã¦ã®æ´»å‹•を出力ã—ã¾ã™ã€‚-1ã¯è‡ªå‹•VACUUMã®ãƒ­ã‚°è¨˜éŒ²ã‚’無効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2134 +#: utils/misc/guc.c:2615 msgid "Background writer sleep time between rounds." -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ã®å‹•作周期ã®å¾…機時間" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ã®å‘¨æœŸæ¯Žã®å¾…機時間" -#: utils/misc/guc.c:2145 +#: utils/misc/guc.c:2626 msgid "Background writer maximum number of LRU pages to flush per round." -msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãŒ1周期ã§åãå‡ºã™æœ€å¤§LRUページ数" +msgstr "ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ©ã‚¤ã‚¿ãŒ1å‘¨æœŸã§æ›¸ã出ã™LRUãƒšãƒ¼ã‚¸æ•°ã®æœ€å¤§å€¤ã€‚" -#: utils/misc/guc.c:2161 +#: utils/misc/guc.c:2649 msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." -msgstr "ディスクサブシステムã«ã‚ˆã£ã¦å分処ç†å¯èƒ½ãªåŒæ™‚並行リクエスト数" +msgstr "ディスクサブシステムãŒåŠ¹çŽ‡çš„ã«å‡¦ç†å¯èƒ½ãªåŒæ™‚並行リクエスト数" -#: utils/misc/guc.c:2162 +#: utils/misc/guc.c:2650 msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." -msgstr "RAID アレイã§ã¯ã€ã“れã¯ãŠãŠã‚€ã­ã‚¢ãƒ¬ã‚¤ä¸­ã®ãƒ‰ãƒ©ã‚¤ãƒ–ã®ã‚¹ãƒ”ンドル数ã«ãªã‚Šã¾ã™" +msgstr "RAIDアレイã§ã¯ã€ã“れã¯ãŠãŠã‚€ã­ã‚¢ãƒ¬ã‚¤ä¸­ã®ãƒ‰ãƒ©ã‚¤ãƒ–ã®ã‚¹ãƒ”ンドル数ã«ãªã‚Šã¾ã™ã€‚" -#: utils/misc/guc.c:2177 -#| msgid "Sets the maximum number of concurrent connections." +#: utils/misc/guc.c:2677 msgid "Maximum number of concurrent worker processes." -msgstr "åŒæ™‚å®Ÿè¡Œãƒ¯ãƒ¼ã‚«ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¤§æ•°ã§ã™ã€‚" +msgstr "åŒæ™‚ã«å®Ÿè¡Œã•ã‚Œã‚‹ãƒ¯ãƒ¼ã‚«ãƒ—ãƒ­ã‚»ã‚¹æ•°ã®æœ€å¤§å€¤ã§ã™ã€‚" -#: utils/misc/guc.c:2187 +#: utils/misc/guc.c:2689 +msgid "Maximum number of logical replication worker processes." +msgstr "ãƒ¬ãƒ—ãƒªã‚±ãƒ¼ã‚·ãƒ§ãƒ³ãƒ¯ãƒ¼ã‚«ãƒ—ãƒ­ã‚»ã‚¹æ•°ã®æœ€å¤§å€¤ã§ã™ã€‚" + +#: utils/misc/guc.c:2701 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "サブスクリプション毎ã®ãƒ†ãƒ¼ãƒ–ãƒ«åŒæœŸãƒ¯ãƒ¼ã‚«æ•°ã®æœ€å¤§å€¤ã§ã™ã€‚" + +#: utils/misc/guc.c:2711 msgid "Automatic log file rotation will occur after N minutes." -msgstr "ログファイルã®è‡ªå‹•ローテーションã¯N秒後ã«èµ·ã“りã¾ã™" +msgstr "ログファイルã®è‡ªå‹•ローテーションã¯N秒経éŽã®éš›ã«è¡Œã‚れã¾ã™ã€‚" -#: utils/misc/guc.c:2198 +#: utils/misc/guc.c:2722 msgid "Automatic log file rotation will occur after N kilobytes." -msgstr "ログファイルã®è‡ªå‹•ローテーションã¯Nキロãƒã‚¤ãƒˆå¾Œã«èµ·ã“りã¾ã™" +msgstr "ログファイルã®è‡ªå‹•ローテーションã¯Nキロãƒã‚¤ãƒˆæ›¸ã込んã éš›ã«è¡Œã‚れã¾ã™ã€‚" -#: utils/misc/guc.c:2209 +#: utils/misc/guc.c:2733 msgid "Shows the maximum number of function arguments." msgstr "関数ã®å¼•æ•°ã®æœ€å¤§æ•°ã‚’示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2220 +#: utils/misc/guc.c:2744 msgid "Shows the maximum number of index keys." msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚­ãƒ¼ã®æœ€å¤§æ•°ã‚’示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2231 +#: utils/misc/guc.c:2755 msgid "Shows the maximum identifier length." msgstr "識別å­ã®æœ€å¤§é•·ã‚’示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2242 +#: utils/misc/guc.c:2766 msgid "Shows the size of a disk block." msgstr "ディスクブロックサイズを示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2253 +#: utils/misc/guc.c:2777 msgid "Shows the number of pages per disk file." msgstr "ディスクファイルã”ã¨ã®ãƒšãƒ¼ã‚¸æ•°ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2264 +#: utils/misc/guc.c:2788 msgid "Shows the block size in the write ahead log." msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°(WAL)ã«ãŠã‘るブロックサイズを表示ã—ã¾ã™" -#: utils/misc/guc.c:2275 -msgid "Shows the number of pages per write ahead log segment." -msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°(WAL)セグメントã”ã¨ã®ãƒšãƒ¼ã‚¸æ•°ã‚’表示ã—ã¾ã™" +#: utils/misc/guc.c:2799 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "WALã®å–り出ã—ã®å¤±æ•—後ã«å†è©¦è¡Œã™ã‚‹å›žæ•°ã‚’設定。" -#: utils/misc/guc.c:2288 +#: utils/misc/guc.c:2811 +msgid "Shows the size of write ahead log segments." +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°(WAL)セグメントã®ã‚µã‚¤ã‚ºã‚’表示ã—ã¾ã™" + +#: utils/misc/guc.c:2824 msgid "Time to sleep between autovacuum runs." -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®å¾…機間隔)。" +msgstr "自動VACUUMã®å®Ÿè¡Œé–‹å§‹é–“隔。" -#: utils/misc/guc.c:2298 +#: utils/misc/guc.c:2834 msgid "Minimum number of tuple updates or deletes prior to vacuum." -msgstr "ãƒã‚­ãƒ¥ãƒ¼ãƒ ã‚’行ã†ã¾ã§ã®ã€ã‚¿ãƒ—ルを更新ã¾ãŸã¯å‰Šé™¤ã—ãŸå›žæ•°ã®æœ€å°å€¤ã€‚" +msgstr "VACUUMを行ã†ã¾ã§ã®ã€ã‚¿ãƒ—ルを更新ã¾ãŸã¯å‰Šé™¤ã—ãŸå›žæ•°ã®æœ€å°å€¤ã€‚" -#: utils/misc/guc.c:2307 +#: utils/misc/guc.c:2843 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "è§£æžã™ã‚‹ã¾ã§ã®ã€ã‚¿ãƒ—ãƒ«ã‚’æŒ¿å…¥ã€æ›´æ–°ã€å‰Šé™¤ã—ãŸå›žæ•°ã®æœ€å°å€¤ã€‚" -#: utils/misc/guc.c:2317 +#: utils/misc/guc.c:2853 msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." -msgstr "トランザクションID周回を防ããŸã‚ã«ãƒ†ãƒ¼ãƒ–ルを自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ã™ã‚‹å¹´ä»£ã§ã™ã€‚" +msgstr "トランザクションID周回を防ããŸã‚ã«ãƒ†ãƒ¼ãƒ–ルを自動VACUUMã™ã‚‹ãƒ†ãƒ¼ãƒ–ル年齢ã§ã™ã€‚" -#: utils/misc/guc.c:2328 +#: utils/misc/guc.c:2864 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "マルãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å‘¨å›žã‚’防止ã™ã‚‹ãŸã‚ã«ãƒ†ãƒ¼ãƒ–ルを自動VACUUMã™ã‚‹ã€ãƒžãƒ«ãƒãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãƒ†ãƒ¼ãƒ–ル年齢。" + +#: utils/misc/guc.c:2874 msgid "Sets the maximum number of simultaneously running autovacuum worker processes." -msgstr "自動ãƒã‚­ãƒ¥ãƒ¼ãƒ ã®ãƒ¯ãƒ¼ã‚«ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¤§åŒæ™‚実行数を設定ã—ã¾ã™ã€‚" +msgstr "自動VACUUMã®ãƒ¯ãƒ¼ã‚«ãƒ—ãƒ­ã‚»ã‚¹ã®æœ€å¤§åŒæ™‚実行数を設定。" -#: utils/misc/guc.c:2338 +#: utils/misc/guc.c:2884 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "ã²ã¨ã¤ã®ä¿å®ˆä½œæ¥­ã«å‰²ã‚Šå½“ã¦ã‚‹ä¸¦åˆ—処ç†ãƒ—ãƒ­ã‚»ã‚¹ã®æ•°ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2894 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "エグゼキュータノードã‚ãŸã‚Šã®ä¸¦åˆ—処ç†ãƒ—ãƒ­ã‚»ã‚¹ã®æ•°ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2904 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "åŒæ™‚ã«æ´»å‹•å¯èƒ½ãªä¸¦åˆ—処ç†ãƒ¯ãƒ¼ã‚«ã®æ•°ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2914 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "自動VACUUMプロセスã§ä½¿ç”¨ã™ã‚‹ãƒ¡ãƒ¢ãƒªé‡ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2925 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "スナップショットå–å¾—å¾Œã€æ›´æ–°ã•れãŸãƒšãƒ¼ã‚¸ãŒèª­ã¿å–れãªããªã‚‹ã¾ã§ã®æ™‚間。" + +#: utils/misc/guc.c:2926 +msgid "A value of -1 disables this feature." +msgstr "-1ã§ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:2936 msgid "Time between issuing TCP keepalives." -msgstr "TCPキープアライブを発行ã™ã‚‹é–“隔。" +msgstr "TCPキープアライブを発行ã™ã‚‹æ™‚間間隔。" -#: utils/misc/guc.c:2339 utils/misc/guc.c:2350 +#: utils/misc/guc.c:2937 utils/misc/guc.c:2948 msgid "A value of 0 uses the system default." -msgstr "ゼロã¨ã„ã†å€¤ã¯ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルトを使用ã—ã¾ã™ã€‚" +msgstr "0ã§ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルトを使用ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2349 +#: utils/misc/guc.c:2947 msgid "Time between TCP keepalive retransmits." -msgstr "TCPキープアライブをå†é€ä¿¡ã™ã‚‹ã¾ã§ã®æ™‚間。" +msgstr "TCPキープアライブã®å†é€ä¿¡ã®æ™‚間間隔。" -#: utils/misc/guc.c:2360 -msgid "Set the amount of traffic to send and receive before renegotiating the encryption keys." -msgstr "æš—å·åŒ–キーをå†ãƒã‚´ã‚·ã‚¨ãƒ¼ãƒˆã™ã‚‹å‰ã«ã€é€ä¿¡ã™ã‚‹ãƒˆãƒ©ãƒ•ィックé‡ã‚’セットã—ã¦ãã ã•ã„。" +#: utils/misc/guc.c:2958 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSLã®å†ãƒã‚´ã‚·ã‚¨ãƒ¼ã‚·ãƒ§ãƒ³ã¯ä»Šå¾Œã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“; 0ã®ã¿ã«è¨­å®šå¯èƒ½ã§ã™ã€‚" -#: utils/misc/guc.c:2371 +#: utils/misc/guc.c:2969 msgid "Maximum number of TCP keepalive retransmits." -msgstr "TCPキープアライブã®å†åˆ©ç”¨æ•°ã®æœ€å¤§æ•°ã§ã™ã€‚" +msgstr "TCPキープアライブã®å†é€ä¿¡å›žæ•°ã®æœ€å¤§å€¤ã§ã™ã€‚" -#: utils/misc/guc.c:2372 +#: utils/misc/guc.c:2970 msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." -msgstr "" -"ã“れã¯ã€æŽ¥ç¶šãŒä¸è¦ã¨ãªã£ãŸã¨ã¿ãªã™å‰ã«å¤±ã‚れるå¯èƒ½æ€§ãŒã‚ã‚‹ã€é€£ç¶šçš„ãªã‚­ãƒ¼ãƒ—ã‚¢\n" -"ライブã®å†åˆ©ç”¨æ•°ã‚’を制御ã—ã¾ã™ã€‚0ã¨ã„ã†å€¤ã§ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルトを使用ã—ã¾ã™ã€‚" +msgstr "ã“れã¯ã€æŽ¥ç¶šãŒå¤±ã‚れるã¨åˆ¤æ–­ã™ã‚‹ã¾ã§ã«å†é€ä¿¡ã•れるã€ã²ã¨ã¤ã¥ãã®ã‚­ãƒ¼ãƒ—ã‚¢ãƒ©ã‚¤ãƒ–ã®æ•°ã‚’制御ã—ã¾ã™ã€‚0ã®æ™‚ã¯ã§ã‚·ã‚¹ãƒ†ãƒ ã®ãƒ‡ãƒ•ォルトを使用ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2383 +#: utils/misc/guc.c:2981 msgid "Sets the maximum allowed result for exact search by GIN." -msgstr "GINã«ã‚ˆã‚‹æ­£ç¢ºãªæ¤œç´¢ã«å¯¾ã—ã¦è¨±ã•れる最大ã®çµæžœæ•°ã‚’設定ã—ã¾ã™ã€‚" +msgstr "GINã«ã‚ˆã‚‹æ­£ç¢ºãªæ¤œç´¢ã«å¯¾ã—ã¦è¨±å®¹ã™ã‚‹çµæžœæ•°ã®æœ€å¤§å€¤ã‚’設定。" + +#: utils/misc/guc.c:2992 +#, fuzzy +#| msgid "Sets the planner's assumption about the size of the disk cache." +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "ディスクキャッシュã®ã‚µã‚¤ã‚ºã«é–¢ã™ã‚‹ãƒ—ãƒ©ãƒ³ãƒŠã®æƒ³å®šã‚’設定。" -#: utils/misc/guc.c:2394 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "ディスクキャッシュã®ã‚µã‚¤ã‚ºã«é–¢ã™ã‚‹ãƒ—ãƒ©ãƒ³ãƒŠã®æŽ¨æ¸¬ã‚’è¨­å®šã—ã¾ã™ã€‚" +#: utils/misc/guc.c:2993 +#, fuzzy +#| msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "ã¤ã¾ã‚Šã€PostgreSQLã®ãƒ‡ãƒ¼ã‚¿ãƒ•ァイルã§ä½¿ç”¨ã•れるカーãƒãƒ«ã®ãƒ‡ã‚£ã‚¹ã‚¯ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®é‡ã§ã™ã€‚ã“れã¯é€šå¸¸8KBã®ãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ã‚’å˜ä½ã¨ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2395 -msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." -msgstr "ã¤ã¾ã‚Šã€PostgreSQLã®ãƒ‡ãƒ¼ã‚¿ãƒ•ァイル用ã«ä½¿ç”¨ã•れるカーãƒãƒ«ã®ãƒ‡ã‚£ã‚¹ã‚¯ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã®é‡ã§ã™ã€‚ã“れã¯é€šå¸¸8KBã®ãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ã‚’å˜ä½ã¨ã—ã¾ã™ã€‚" +#: utils/misc/guc.c:3004 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "並列スキャンを検討ã™ã‚‹ãƒ†ãƒ¼ãƒ–ルデータã®é‡ã®æœ€å°å€¤ã‚’設定。" -#: utils/misc/guc.c:2408 +#: utils/misc/guc.c:3005 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "ã“ã®é™åº¦ã«åˆ°é”ã§ããªã„よã†ãªå°‘ãªã„テーブルページ数ã—ã‹èª­ã¿å–らãªã„ã¨ãƒ—ランナãŒè¦‹ç©ã‚‚ã£ãŸå ´åˆã€ä¸¦åˆ—ã‚¹ã‚­ãƒ£ãƒ³ã¯æ¤œè¨Žã•れã¾ã›ã‚“。" + +#: utils/misc/guc.c:3015 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "並列スキャンを検討ã™ã‚‹ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãƒ‡ãƒ¼ã‚¿ã®é‡ã®æœ€å°å€¤ã‚’設定。" + +#: utils/misc/guc.c:3016 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "ã“ã®é™åº¦ã«åˆ°é”ã§ããªã„よã†ãªå°‘ãªã„ページ数ã—ã‹èª­ã¿å–らãªã„ã¨ãƒ—ランナãŒè¦‹ç©ã‚‚ã£ãŸå ´åˆã€ä¸¦åˆ—ã‚¹ã‚­ãƒ£ãƒ³ã¯æ¤œè¨Žã•れã¾ã›ã‚“。" + +#: utils/misc/guc.c:3027 msgid "Shows the server version as an integer." msgstr "サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’整数値ã§è¡¨ç¤ºã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2419 +#: utils/misc/guc.c:3038 msgid "Log the use of temporary files larger than this number of kilobytes." -msgstr "キロãƒã‚¤ãƒˆå˜ä½ã§ã“ã®æ•°å€¤ï½™ã‚Šå¤§ããªä¸€æ™‚ファイルã®ä½¿ç”¨ã‚’ログã«è¨˜éŒ²ã—ã¾ã™ã€‚" +msgstr "ã“ã®ã‚­ãƒ­ãƒã‚¤ãƒˆæ•°ã‚ˆã‚Šã‚‚大ããªä¸€æ™‚ファイルã®ä½¿ç”¨ã‚’ログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2420 +#: utils/misc/guc.c:3039 msgid "Zero logs all files. The default is -1 (turning this feature off)." -msgstr "ゼロã«ã™ã‚‹ã¨ã€å…¨ã¦ã®ãƒ•ァイルを出力ã—ã¾ã™ã€‚デフォルトã¯-1ã§ã™ã€‚(ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã™ã€‚)" +msgstr "ゼロã«ã™ã‚‹ã¨ã€å…¨ã¦ã®ãƒ•ァイルを記録ã—ã¾ã™ã€‚デフォルトã¯-1ã§ã™(ã“ã®æ©Ÿèƒ½ã‚’無効ã«ã—ã¾ã™)。" -#: utils/misc/guc.c:2430 +#: utils/misc/guc.c:3049 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." -msgstr "pg_stat_activity.queryã§äºˆç´„ã•れã¦ã„るサイズをãƒã‚¤ãƒˆå˜ä½ã§æŒ‡å®šã—ã¦ãã ã•ã„" +msgstr "pg_stat_activity.queryã®ãŸã‚ã«äºˆç´„ã™ã‚‹ã‚µã‚¤ã‚ºã‚’ãƒã‚¤ãƒˆå˜ä½ã§è¨­å®šã€‚" + +#: utils/misc/guc.c:3060 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "GINインデックスã®ä¿ç•™ãƒªã‚¹ãƒˆã®æœ€å¤§ã‚µã‚¤ã‚ºã‚’設定。" -#: utils/misc/guc.c:2449 +#: utils/misc/guc.c:3080 msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." -msgstr "プランナã®ã‚·ãƒ¼ã‚±ãƒ³ã‚·ãƒ£ãƒ«ã«å–りã ã•れãŸãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ã®ã‚³ã‚¹ãƒˆã®æ¦‚算を設定ã—ã¾ã™ã€‚" +msgstr "ã²ã¨ç¶šãã«èª­ã¿è¾¼ã‚€ãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" -#: utils/misc/guc.c:2459 +#: utils/misc/guc.c:3090 msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." -msgstr "プランナã®é †ä¸åŒã«å–りã ã•れãŸãƒ‡ã‚£ã‚¹ã‚¯ãƒšãƒ¼ã‚¸ã®ã‚³ã‚¹ãƒˆã®æ¦‚算を設定ã—ã¾ã™ã€‚" +msgstr "ã²ã¨ç¶šãã§ã¯èª­ã¿è¾¼ã‚ãªã„ディスクページã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" -#: utils/misc/guc.c:2469 +#: utils/misc/guc.c:3100 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." -msgstr "プランナãŒå„タプル(行)を処ç†ã™ã‚‹ã‚³ã‚¹ãƒˆã‚’設定ã—ã¾ã™ã€‚" +msgstr "一ã¤ã®ã‚¿ãƒ—ル(行)ã®å‡¦ç†ã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" -#: utils/misc/guc.c:2479 +#: utils/misc/guc.c:3110 msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." -msgstr "プランナãŒã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¹ã‚­ãƒ£ãƒ³æ™‚ã«ãれãžã‚Œã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹é …目を処ç†ã™ã‚‹ãŸã‚ã®æ¦‚算コストを設定ã—ã¾ã™ã€‚ " +msgstr "インデックススキャンã«ãŠã‘る一ã¤ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¨ãƒ³ãƒˆãƒªã®å‡¦ç†ã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。 " -#: utils/misc/guc.c:2489 +#: utils/misc/guc.c:3120 msgid "Sets the planner's estimate of the cost of processing each operator or function call." -msgstr "プランナã®ã€å„演算å­å‘¼ã³å‡ºã—ã€å„関数呼ã³å‡ºã—を処ç†ã™ã‚‹æ¦‚算コストを設定ã—ã¾ã™ã€‚" +msgstr "一ã¤ã®æ¼”ç®—å­ã¾ãŸã¯é–¢æ•°ã®å‡¦ç†ã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" + +#: utils/misc/guc.c:3130 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "並列処ç†ãƒ¯ãƒ¼ã‚«ã‹ã‚‰ãƒžã‚¹ã‚¿ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã¸ã®ä¸€ã¤ã®ã‚¿ãƒ—ル(行)ã®å—ã‘æ¸¡ã—ã«ã¤ã„ã¦ãƒ—ランナãŒä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" + +#: utils/misc/guc.c:3140 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "並列å•ã„åˆã‚ã›å®Ÿè¡Œã®ãŸã‚ã®ãƒ¯ãƒ¼ã‚«ãƒ—ロセスã®èµ·å‹•ã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹è¦‹ç©ã‚‚りコストを設定。" + +#: utils/misc/guc.c:3151 +msgid "Perform JIT compilation if query is more expensive." +msgstr "å•ã„åˆã‚ã›ãŒã“ã®å€¤ã‚ˆã‚Šé«˜ã‚³ã‚¹ãƒˆã§ã‚れã°JITコンパイルを実行ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:3152 +msgid "-1 disables JIT compilation." +msgstr "-1 ã§JITã‚³ãƒ³ãƒ‘ã‚¤ãƒ«ã‚’ç¦æ­¢ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:3161 +msgid "Optimize JITed functions if query is more expensive." +msgstr "å•ã„åˆã‚ã›ãŒã“ã®å€¤ã‚ˆã‚Šé«˜ã‚³ã‚¹ãƒˆã§ã‚れã°JITコンパイルã•れãŸé–¢æ•°ã‚’最é©åŒ–ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2500 +#: utils/misc/guc.c:3162 +msgid "-1 disables optimization." +msgstr "-1ã§æœ€é©åŒ–を行ã‚ãªããªã‚Šã¾ã™ã€‚" + +#: utils/misc/guc.c:3171 +msgid "Perform JIT inlining if query is more expensive." +msgstr "å•ã„åˆã‚ã›ãŒã“ã®å€¤ã‚ˆã‚Šé«˜ã‚³ã‚¹ãƒˆã§ã‚れã°JITコンパイルã•れãŸé–¢æ•°ã‚’インライン化ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:3172 +msgid "-1 disables inlining." +msgstr "-1 ã§ã‚¤ãƒ³ãƒ©ã‚¤ãƒ³åŒ–ã‚’ç¦æ­¢ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:3181 msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." -msgstr "å–り出ã•れるカーソル行ã®å‰²åˆã«ã¤ã„ã¦ã€ãƒ—ランナã®äºˆæ¸¬å€¤ã‚’設定ã—ã¾ã™ã€‚" +msgstr "カーソルã‹ã‚‰å–り出ã•れる行数ã®å…¨è¡Œã«å¯¾ã™ã‚‹å‰²åˆã«ã¤ã„ã¦ãƒ—ランナã§ä½¿ç”¨ã™ã‚‹å€¤ã‚’設定。" -#: utils/misc/guc.c:2511 +#: utils/misc/guc.c:3192 msgid "GEQO: selective pressure within the population." -msgstr "GEQO: 個体群内ã®é¸æŠžåœ§åŠ›ã§ã™ã€‚" +msgstr "GEQO: 集åˆå†…ã®é¸æŠžåœ§åŠ›ã€‚" -#: utils/misc/guc.c:2521 +#: utils/misc/guc.c:3202 msgid "GEQO: seed for random path selection." -msgstr "GEQO: ä¹±æ•°ãƒ‘ã‚¹é¸æŠžç”¨ã®ã‚·ãƒ¼ãƒ‰" +msgstr "GEQO: ãƒ©ãƒ³ãƒ€ãƒ ãƒ‘ã‚¹é¸æŠžç”¨ã®ã‚·ãƒ¼ãƒ‰" -#: utils/misc/guc.c:2531 +#: utils/misc/guc.c:3212 msgid "Multiple of the average buffer usage to free per round." -msgstr "1周ã”ã¨ã«é–‹æ”¾ã™ã‚‹ã¹ãã®ãƒãƒƒãƒ•ã‚¡ã®ä½¿ç”¨é‡å¹³å‡ã«æŽ›ã‘ã‚‹å€æ•°" +msgstr "周期ã”ã¨ã«è§£æ”¾ã™ã‚‹ãƒãƒƒãƒ•ã‚¡æ•°ã®å¹³å‡ãƒãƒƒãƒ•ァ使用é‡ã«å¯¾ã™ã‚‹å€æ•°" -#: utils/misc/guc.c:2541 +#: utils/misc/guc.c:3222 msgid "Sets the seed for random-number generation." -msgstr "ランダム生æˆç”¨ã®ã‚·ãƒ¼ãƒ‰ã‚’設定ã—ã¾ã™ã€‚" +msgstr "乱数生æˆç”¨ã®ã‚·ãƒ¼ãƒ‰ã‚’設定。" -#: utils/misc/guc.c:2552 +#: utils/misc/guc.c:3233 msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." -msgstr "reltuplesã®ä¸€éƒ¨ã¨ã—ã¦ãƒã‚­ãƒ¥ãƒ¼ãƒ ã‚’行ã†ã¾ã§ã®ã€ã‚¿ãƒ—ãƒ«ã®æ›´æ–°ã¾ãŸã¯å‰Šé™¤å›žæ•°ã€‚" +msgstr "VACUUMãŒå®Ÿè¡Œã•れるã¾ã§ã®ã‚¿ãƒ—ãƒ«ã®æ›´æ–°ã¾ãŸã¯å‰Šé™¤å›žæ•°ã®reltuplesã«å¯¾ã™ã‚‹å‰²åˆã€‚" -#: utils/misc/guc.c:2561 +#: utils/misc/guc.c:3242 msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." -msgstr "reltuplesã®ä¸€éƒ¨ã¨ã—ã¦è§£æžã‚’行ã†ã¾ã§ã®ã€ã‚¿ãƒ—ãƒ«ã®æŒ¿å…¥ã€æ›´æ–°ã¾ãŸã¯å‰Šé™¤å›žæ•°ã€‚" +msgstr "ANALYZEãŒå®Ÿè¡Œã•れるã¾ã§ã®ã‚¿ãƒ—ãƒ«ã®æ›´æ–°ã¾ãŸã¯å‰Šé™¤å›žæ•°ã®reltuplesã«å¯¾ã™ã‚‹å‰²åˆã€‚" -#: utils/misc/guc.c:2571 +#: utils/misc/guc.c:3252 msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." -msgstr "" -"ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘るダーティãƒãƒƒãƒ•ã‚¡ã®åã出ã—ã«è¦ã—ãŸæ™‚間(ãƒã‚§ãƒƒã‚¯\n" -"ãƒã‚¤ãƒ³ãƒˆé–“éš”ã«ãŠã‘る割åˆï¼‰ã€‚" +msgstr "ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä¸­ã«ãƒ€ãƒ¼ãƒ†ã‚£ãƒãƒƒãƒ•ã‚¡ã®æ›¸ã出ã—ã«ä½¿ã†æ™‚é–“ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆé–“éš”ã«å¯¾ã™ã‚‹å‰²åˆã€‚" -#: utils/misc/guc.c:2590 +#: utils/misc/guc.c:3262 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "インデックスクリーンアップãŒå®Ÿè¡Œã•れるã¾ã§ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚¿ãƒ—ãƒ«ã®æŒ¿å…¥è¡Œæ•°ã®reltuplesã«å¯¾ã™ã‚‹å‰²åˆã€‚" + +# hoge +#: utils/misc/guc.c:3281 msgid "Sets the shell command that will be called to archive a WAL file." -msgstr "WALファイルã®ä¿ç®¡ã®ãŸã‚ã«å‘¼ã³å‡ºã•れるシェルスクリプトを設定ã—ã¾ã™ã€‚" +msgstr "WALファイルã®ä¿ç®¡ã®ãŸã‚ã«å‘¼ã³å‡ºã•れるシェルスクリプトを設定。" -#: utils/misc/guc.c:2600 +#: utils/misc/guc.c:3291 msgid "Sets the client's character set encoding." -msgstr "ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®æ–‡å­—セット符å·åŒ–æ–¹å¼ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®æ–‡å­—集åˆã®ç¬¦å·åŒ–æ–¹å¼ã‚’設定。" -#: utils/misc/guc.c:2611 +#: utils/misc/guc.c:3302 msgid "Controls information prefixed to each log line." msgstr "å„ログ行ã®å‰ã«ä»˜ã‘る情報を制御ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2612 +#: utils/misc/guc.c:3303 msgid "If blank, no prefix is used." -msgstr "ã‚‚ã—空ã§ã‚ã‚Œã°æŽ¥é ­è¾žã¯ã‚りã¾ã›ã‚“" +msgstr "ã‚‚ã—空ã§ã‚れã°ãªã«ã‚‚付加ã—ã¾ã›ã‚“。" -#: utils/misc/guc.c:2621 +#: utils/misc/guc.c:3312 msgid "Sets the time zone to use in log messages." -msgstr "ログメッセージã§ã—ã‹å‰²ã‚Œã‚‹æ™‚間帯を設定ã—ã¾ã™ã€‚" +msgstr "ログメッセージ使用ã™ã‚‹ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚’設定。" -#: utils/misc/guc.c:2631 +#: utils/misc/guc.c:3322 msgid "Sets the display format for date and time values." -msgstr "日付時刻値ã®è¡¨ç¤ºç”¨æ›¸å¼ã‚’設定ã—ã¾ã™ã€‚" +msgstr "日付時刻値ã®è¡¨ç¤ºç”¨æ›¸å¼ã‚’設定。" -#: utils/misc/guc.c:2632 +#: utils/misc/guc.c:3323 msgid "Also controls interpretation of ambiguous date inputs." msgstr "æ›–æ˜§ãªæ—¥ä»˜ã®å…¥åŠ›ã®è§£é‡ˆã‚‚制御ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2643 +#: utils/misc/guc.c:3334 msgid "Sets the default tablespace to create tables and indexes in." -msgstr "テーブルã¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ä½œæˆå…ˆã¨ãªã‚‹ãƒ‡ãƒ•ォルトã®ãƒ†ãƒ¼ãƒ–ル空間を設定ã—ã¾ã™ã€‚" +msgstr "テーブルã¨ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®ä½œæˆå…ˆã¨ãªã‚‹ãƒ‡ãƒ•ォルトã®ãƒ†ãƒ¼ãƒ–ル空間を設定。" -#: utils/misc/guc.c:2644 +#: utils/misc/guc.c:3335 msgid "An empty string selects the database's default tablespace." msgstr "空文字列ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ãƒ‡ãƒ•ォルトã®ãƒ†ãƒ¼ãƒ–ãƒ«ç©ºé–“ã‚’é¸æŠžã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2654 +#: utils/misc/guc.c:3345 msgid "Sets the tablespace(s) to use for temporary tables and sort files." -msgstr "一時テーブルã¨ãƒ•ァイルã®ã‚½ãƒ¼ãƒˆã§ä½¿ç”¨ã•れるテーブル空間を設定ã—ã¾ã™ã€‚" +msgstr "一時テーブルã¨ãƒ•ァイルã®ã‚½ãƒ¼ãƒˆã§ä½¿ç”¨ã•れるテーブル空間を設定。" -#: utils/misc/guc.c:2665 +#: utils/misc/guc.c:3356 msgid "Sets the path for dynamically loadable modules." -msgstr "動的ロードå¯èƒ½ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®ãƒ‘スを設定ã—ã¾ã™ã€‚" +msgstr "動的ロードå¯èƒ½ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®ãƒ‘スを設定。" -#: utils/misc/guc.c:2666 +#: utils/misc/guc.c:3357 msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." msgstr "オープンã™ã‚‹å¿…è¦ãŒã‚る動的ロードå¯èƒ½ãªãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã«ã¤ã„ã¦ã€æŒ‡å®šã•れãŸãƒ•ァイルåã«ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªè¦ç´ ãŒãªã„(ã¤ã¾ã‚Šã€åå‰ã«ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ãŒå«ã¾ã‚Œãªã„)å ´åˆã€ã‚·ã‚¹ãƒ†ãƒ ã¯æŒ‡å®šã•れãŸãƒ•ァイルをã“ã®ãƒ‘スã‹ã‚‰æ¤œç´¢ã—ã¾ã™ã€‚ " -#: utils/misc/guc.c:2679 +#: utils/misc/guc.c:3370 msgid "Sets the location of the Kerberos server key file." -msgstr "Kerberosサーãƒã‚­ãƒ¼ãƒ•ァイルã®å ´æ‰€ã‚’設定ã—ã¾ã™ã€‚" - -#: utils/misc/guc.c:2690 -msgid "Sets the name of the Kerberos service." -msgstr "Kerberosサービスåを設定ã—ã¾ã™ã€‚" +msgstr "Kerberosサーãƒã‚­ãƒ¼ãƒ•ァイルã®å ´æ‰€ã‚’設定。" -#: utils/misc/guc.c:2700 +#: utils/misc/guc.c:3381 msgid "Sets the Bonjour service name." -msgstr "Bonjour サービスåを設定ã—ã¾ã™ã€‚" +msgstr "Bonjour サービスåを設定。" -#: utils/misc/guc.c:2712 +#: utils/misc/guc.c:3393 msgid "Shows the collation order locale." msgstr "テキストデータã®ã‚½ãƒ¼ãƒˆæ™‚ã«ä½¿ç”¨ã•れるロケールを表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2723 +#: utils/misc/guc.c:3404 msgid "Shows the character classification and case conversion locale." msgstr "文字クラス分類ã€å¤§æ–‡å­—å°æ–‡å­—変æ›ã‚’決定ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2734 +#: utils/misc/guc.c:3415 msgid "Sets the language in which messages are displayed." -msgstr "表示用メッセージã®è¨€èªžã‚’設定ã—ã¾ã™ã€‚" +msgstr "表示用メッセージã®è¨€èªžã‚’設定。" -#: utils/misc/guc.c:2744 +#: utils/misc/guc.c:3425 msgid "Sets the locale for formatting monetary amounts." -msgstr "通貨書å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定ã—ã¾ã™ã€‚ " +msgstr "通貨書å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定。 " -#: utils/misc/guc.c:2754 +#: utils/misc/guc.c:3435 msgid "Sets the locale for formatting numbers." -msgstr "æ•°å­—ã®æ›¸å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "æ•°å­—ã®æ›¸å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定。" -#: utils/misc/guc.c:2764 +#: utils/misc/guc.c:3445 msgid "Sets the locale for formatting date and time values." -msgstr "æ—¥ä»˜ã¨æ™‚é–“ã®æ›¸å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "æ—¥ä»˜ã¨æ™‚é–“ã®æ›¸å¼ã§ä½¿ç”¨ã™ã‚‹ãƒ­ã‚±ãƒ¼ãƒ«ã‚’設定。" -#: utils/misc/guc.c:2774 +#: utils/misc/guc.c:3455 msgid "Lists shared libraries to preload into each backend." msgstr "å„ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã«äº‹å‰ãƒ­ãƒ¼ãƒ‰ã™ã‚‹å…±æœ‰ãƒ©ã‚¤ãƒ–ラリを列挙ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2785 +#: utils/misc/guc.c:3466 msgid "Lists shared libraries to preload into server." msgstr "サーãƒã«äº‹å‰ãƒ­ãƒ¼ãƒ‰ã™ã‚‹å…±æœ‰ãƒ©ã‚¤ãƒ–ラリを列挙ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2796 -#| msgid "Lists shared libraries to preload into each backend." +#: utils/misc/guc.c:3477 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "å„ãƒãƒƒã‚¯ã‚¨ãƒ³ãƒ‰ã«äº‹å‰èª­ã¿è¾¼ã¿ã™ã‚‹éžç‰¹æ¨©å…±æœ‰ãƒ©ã‚¤ãƒ–ラリを列挙ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2807 +#: utils/misc/guc.c:3488 msgid "Sets the schema search order for names that are not schema-qualified." -msgstr "スキーマ部をå«ã¾ãªã„åå‰ã«å¯¾ã™ã‚‹ã‚¹ã‚­ãƒ¼ãƒžã®æ¤œç´¢é †ã‚’設定ã—ã¾ã™ã€‚" +msgstr "スキーマ部をå«ã¾ãªã„åå‰ã«å¯¾ã™ã‚‹ã‚¹ã‚­ãƒ¼ãƒžã®æ¤œç´¢é †ã‚’設定。" -#: utils/misc/guc.c:2819 +#: utils/misc/guc.c:3500 msgid "Sets the server (database) character set encoding." -msgstr "サーãƒ(データベース)文字セット符å·åŒ–æ–¹å¼ã‚’設定ã—ã¾ã™ã€‚" +msgstr "サーãƒ(データベース)文字セット符å·åŒ–æ–¹å¼ã‚’設定。" -#: utils/misc/guc.c:2831 +#: utils/misc/guc.c:3512 msgid "Shows the server version." msgstr "サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2843 +#: utils/misc/guc.c:3524 msgid "Sets the current role." -msgstr "ç¾åœ¨ã®ãƒ­ãƒ¼ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ç¾åœ¨ã®ãƒ­ãƒ¼ãƒ«ã‚’設定。" -#: utils/misc/guc.c:2855 +#: utils/misc/guc.c:3536 msgid "Sets the session user name." -msgstr "セッションユーザåを設定ã—ã¾ã™ã€‚" +msgstr "セッションユーザåを設定。" -#: utils/misc/guc.c:2866 +#: utils/misc/guc.c:3547 msgid "Sets the destination for server log output." -msgstr "サーãƒãƒ­ã‚°ã®å‡ºåŠ›å…ˆã‚’è¨­å®šã—ã¾ã™ã€‚" +msgstr "サーãƒãƒ­ã‚°ã®å‡ºåŠ›å…ˆã‚’è¨­å®šã€‚" -#: utils/misc/guc.c:2867 +#: utils/misc/guc.c:3548 msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." msgstr "有効ãªå€¤ã¯ã€ãƒ—ラットフォームã«ä¾å­˜ã—ã¾ã™ãŒã€\"stderr\"ã€\"syslog\"ã€\"csvlog\"ã€\"eventlog\"ã®çµ„ã¿åˆã‚ã›ã§ã™ã€‚" -#: utils/misc/guc.c:2878 +#: utils/misc/guc.c:3559 msgid "Sets the destination directory for log files." -msgstr "ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã®æ ¼ç´ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定ã—ã¾ã™ã€‚" +msgstr "ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã®æ ¼ç´ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定。" -#: utils/misc/guc.c:2879 +#: utils/misc/guc.c:3560 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "データディレクトリã‹ã‚‰ã®ç›¸å¯¾ãƒ‘スã§ã‚‚絶対パスã§ã‚‚指定ã§ãã¾ã™" -#: utils/misc/guc.c:2889 +#: utils/misc/guc.c:3570 msgid "Sets the file name pattern for log files." -msgstr "ログファイルã®ãƒ•ァイルåパターンを設定ã—ã¾ã™ã€‚" +msgstr "ログファイルã®ãƒ•ァイルåパターンを設定。" -#: utils/misc/guc.c:2900 +#: utils/misc/guc.c:3581 msgid "Sets the program name used to identify PostgreSQL messages in syslog." -msgstr "syslog内ã§PostgreSQLã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’識別ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•れるプログラムåを設定ã—ã¾ã™ã€‚" +msgstr "syslog内ã§PostgreSQLã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’識別ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•れるプログラムåを設定。" -#: utils/misc/guc.c:2911 +#: utils/misc/guc.c:3592 msgid "Sets the application name used to identify PostgreSQL messages in the event log." -msgstr "イベントログ内ã§PostgreSQLã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’識別ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•れるアプリケーションåを設定ã—ã¾ã™ã€‚" +msgstr "イベントログ内ã§PostgreSQLã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’識別ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã•れるアプリケーションåを設定。" -#: utils/misc/guc.c:2922 +#: utils/misc/guc.c:3603 msgid "Sets the time zone for displaying and interpreting time stamps." -msgstr "タイムスタンプã®è¡¨ç¤ºã¨è§£é‡ˆã«ä½¿ç”¨ã™ã‚‹æ™‚間帯を設定ã—ã¾ã™ã€‚" +msgstr "タイムスタンプã®è¡¨ç¤ºã¨è§£é‡ˆã«ä½¿ç”¨ã™ã‚‹ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚’設定。" -#: utils/misc/guc.c:2932 +#: utils/misc/guc.c:3613 msgid "Selects a file of time zone abbreviations." -msgstr "時間帯çœç•¥å½¢ç”¨ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚" +msgstr "タイムゾーンçœç•¥å½¢ç”¨ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚" -#: utils/misc/guc.c:2942 +#: utils/misc/guc.c:3623 msgid "Sets the current transaction's isolation level." -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®éš”離レベルを設定ã—ã¾ã™ã€‚" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®åˆ†é›¢ãƒ¬ãƒ™ãƒ«ã‚’設定。" -#: utils/misc/guc.c:2953 +#: utils/misc/guc.c:3634 msgid "Sets the owning group of the Unix-domain socket." -msgstr "Unixドメインソケットを所有ã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—を設定ã—ã¾ã™ã€‚" +msgstr "Unixドメインソケットを所有ã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—を設定。" -#: utils/misc/guc.c:2954 +#: utils/misc/guc.c:3635 msgid "The owning user of the socket is always the user that starts the server." msgstr "ソケットを所有ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ã¯å¸¸ã«ã‚µãƒ¼ãƒã‚’é–‹å§‹ã—ãŸãƒ¦ãƒ¼ã‚¶ã§ã™ã€‚" -#: utils/misc/guc.c:2964 -#| msgid "Sets the directory where the Unix-domain socket will be created." +#: utils/misc/guc.c:3645 msgid "Sets the directories where Unix-domain sockets will be created." -msgstr "Unixドメインソケットã®ä½œæˆå…ˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定ã—ã¾ã™ã€‚" +msgstr "Unixドメインソケットã®ä½œæˆå…ˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定。" -#: utils/misc/guc.c:2979 +#: utils/misc/guc.c:3660 msgid "Sets the host name or IP address(es) to listen to." -msgstr "接続を監視ã™ã‚‹ãƒ›ã‚¹ãƒˆåã¾ãŸã¯IPアドレスを設定ã—ã¾ã™ã€‚" +msgstr "接続を監視ã™ã‚‹ãƒ›ã‚¹ãƒˆåã¾ãŸã¯IPアドレスを設定。" -#: utils/misc/guc.c:2990 +#: utils/misc/guc.c:3675 msgid "Sets the server's data directory." -msgstr "サーãƒã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定ã—ã¾ã™ã€‚" +msgstr "サーãƒã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’設定。" -#: utils/misc/guc.c:3001 +#: utils/misc/guc.c:3686 msgid "Sets the server's main configuration file." -msgstr "サーãƒã®ãƒ¡ã‚¤ãƒ³è¨­å®šãƒ•ァイルを設定ã—ã¾ã™ã€‚" +msgstr "サーãƒã®ãƒ¡ã‚¤ãƒ³è¨­å®šãƒ•ァイルを設定。" -#: utils/misc/guc.c:3012 +#: utils/misc/guc.c:3697 msgid "Sets the server's \"hba\" configuration file." -msgstr "サーãƒã®\"hba\"設定ファイルを設定ã—ã¾ã™ã€‚" +msgstr "サーãƒã®\"hba\"設定ファイルを設定。" -#: utils/misc/guc.c:3023 +#: utils/misc/guc.c:3708 msgid "Sets the server's \"ident\" configuration file." -msgstr "サーãƒã®\"ident\"設定ファイルを設定ã—ã¾ã™ã€‚" +msgstr "サーãƒã®\"ident\"設定ファイルを設定。" -#: utils/misc/guc.c:3034 +#: utils/misc/guc.c:3719 msgid "Writes the postmaster PID to the specified file." msgstr "postmasterã®PIDを指定ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ãè¾¼ã¿ã¾ã™ã€‚" -#: utils/misc/guc.c:3045 +#: utils/misc/guc.c:3730 msgid "Location of the SSL server certificate file." msgstr "SSLサーãƒè¨¼æ˜Žæ›¸ãƒ•ァイルã®å ´æ‰€ã§ã™" -#: utils/misc/guc.c:3055 +#: utils/misc/guc.c:3740 msgid "Location of the SSL server private key file." msgstr "SSLサーãƒç§˜å¯†ã‚­ãƒ¼ãƒ•ァイルã®å ´æ‰€ã§ã™ã€‚" -#: utils/misc/guc.c:3065 +#: utils/misc/guc.c:3750 msgid "Location of the SSL certificate authority file." msgstr "SSLèªè¨¼å±€ãƒ•ァイルã®å ´æ‰€ã§ã™" -#: utils/misc/guc.c:3075 +#: utils/misc/guc.c:3760 msgid "Location of the SSL certificate revocation list file." msgstr "SSL証明書失効リストファイルã®å ´æ‰€ã§ã™ã€‚" -#: utils/misc/guc.c:3085 +#: utils/misc/guc.c:3770 msgid "Writes temporary statistics files to the specified directory." msgstr "一時的ãªçµ±è¨ˆæƒ…報ファイルを指定ã—ãŸãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ›¸ãè¾¼ã¿ã¾ã™ã€‚" -#: utils/misc/guc.c:3096 -msgid "List of names of potential synchronous standbys." -msgstr "åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã®å¯èƒ½æ€§ãŒã‚ã‚‹åç§°ã®ä¸€è¦§ã§ã™ã€‚" +#: utils/misc/guc.c:3781 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã®æ•°ã¨åŒæœŸã‚¹ã‚¿ãƒ³ãƒã‚¤å€™è£œã®åå‰ã®ä¸€è¦§ã€‚" -#: utils/misc/guc.c:3107 +#: utils/misc/guc.c:3792 msgid "Sets default text search configuration." msgstr "デフォルトã®ãƒ†ã‚­ã‚¹ãƒˆæ¤œç´¢è¨­å®šã‚’設定ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3117 +#: utils/misc/guc.c:3802 msgid "Sets the list of allowed SSL ciphers." -msgstr "SSLæš—å·ã¨ã—ã¦è¨±ã•れるリストを設定ã—ã¾ã™ã€‚" +msgstr "SSLæš—å·ã¨ã—ã¦è¨±ã•れるリストを設定。" + +#: utils/misc/guc.c:3817 +msgid "Sets the curve to use for ECDH." +msgstr "ECDHã§ä½¿ç”¨ã™ã‚‹æ›²ç·šã‚’設定。" + +#: utils/misc/guc.c:3832 +msgid "Location of the SSL DH parameters file." +msgstr "SSLã®DHパラメータファイルã®å ´æ‰€ã§ã™ã€‚" -#: utils/misc/guc.c:3132 +#: utils/misc/guc.c:3843 +msgid "Command to obtain passphrases for SSL." +msgstr "SSLã®ãƒ‘スフレーズをå–å¾—ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰ã€‚" + +#: utils/misc/guc.c:3853 msgid "Sets the application name to be reported in statistics and logs." -msgstr "統計やログã§å ±å‘Šã•れるアプリケーションåを設定ã—ã¾ã™ã€‚" +msgstr "統計やログã§å ±å‘Šã•れるアプリケーションåを設定。" -#: utils/misc/guc.c:3152 +#: utils/misc/guc.c:3864 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "プロセスã®ã‚¿ã‚¤ãƒˆãƒ«ã«å«ã¾ã‚Œã‚‹ã‚¯ãƒ©ã‚¹ã‚¿åを指定。" + +#: utils/misc/guc.c:3875 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "WALã®æ•´åˆæ€§ãƒã‚§ãƒƒã‚¯ã‚’行ã†å¯¾è±¡ã¨ã™ã‚‹ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ã‚’設定。" + +#: utils/misc/guc.c:3876 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "全ページイメージãŒå…¨ã¦ã®ãƒ‡ãƒ¼ã‚¿ãƒ–ロックã«å¯¾ã—ã¦è¨˜éŒ²ã•れã€WALå†ç”Ÿã®çµæžœã¨ã‚¯ãƒ­ã‚¹ãƒã‚§ãƒƒã‚¯ã•れã¾ã™ã€‚" + +#: utils/misc/guc.c:3886 +msgid "JIT provider to use." +msgstr "使用ã™ã‚‹JITプロãƒã‚¤ãƒ€ã€‚" + +#: utils/misc/guc.c:3906 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "\"\\'\"ã„ãšã‚Œã‹ã®é›†åˆã¯æ–‡å­—列リテラルã§è¨±ã•れã¦ã„ã¾ã™ã€‚" -#: utils/misc/guc.c:3162 +#: utils/misc/guc.c:3916 msgid "Sets the output format for bytea." -msgstr "bytea ã®å‡ºåŠ›ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã‚’è¨­å®šã—ã¾ã™ã€‚" +msgstr "bytea ã®å‡ºåŠ›ãƒ•ã‚©ãƒ¼ãƒžãƒƒãƒˆã‚’è¨­å®šã€‚" -#: utils/misc/guc.c:3172 +#: utils/misc/guc.c:3926 msgid "Sets the message levels that are sent to the client." -msgstr "クライアントã«é€ä¿¡ã•れる最å°ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "クライアントã«é€ä¿¡ã•れる最å°ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒ¬ãƒ™ãƒ«ã‚’設定。" -#: utils/misc/guc.c:3173 utils/misc/guc.c:3226 utils/misc/guc.c:3237 -#: utils/misc/guc.c:3293 +#: utils/misc/guc.c:3927 utils/misc/guc.c:3980 utils/misc/guc.c:3991 +#: utils/misc/guc.c:4057 msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr " å„レベルã«ã¯ãã®ãƒ¬ãƒ™ãƒ«ä»¥ä¸‹ã®å…¨ã¦ãŒå«ã¾ã‚Œã¾ã™ã€‚レベルを低ãã™ã‚‹ã»ã©ã€é€ä¿¡ã•れるメッセージã¯ã‚ˆã‚Šå°‘ãªããªã‚Šã¾ã™ã€‚ " -#: utils/misc/guc.c:3183 +#: utils/misc/guc.c:3937 msgid "Enables the planner to use constraints to optimize queries." msgstr "プランナã«ã‚ˆã‚‹ã€å•ã„åˆã‚ã›ã‚’最é©åŒ–ã™ã‚‹åˆ¶ç´„ã®ä½¿ç”¨ã‚’有効ã«ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3184 +#: utils/misc/guc.c:3938 msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "制約ã«ã‚ˆã‚Šã€å•ã„åˆã‚ã›ã«ä¸€è‡´ã™ã‚‹è¡ŒãŒå­˜åœ¨ã—ãªã„ã“ã¨ãŒä¿è¨¼ã•れã¦ã„ã‚‹å ´åˆã€ãƒ†ãƒ¼ãƒ–ルã®ã‚¹ã‚­ãƒ£ãƒ³ã‚’行ã„ã¾ã›ã‚“。" -#: utils/misc/guc.c:3194 +#: utils/misc/guc.c:3948 msgid "Sets the transaction isolation level of each new transaction." -msgstr "æ–°è¦ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³éš”離レベルを設定ã—ã¾ã™ã€‚" +msgstr "æ–°è¦ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³åˆ†é›¢ãƒ¬ãƒ™ãƒ«ã‚’設定。" -#: utils/misc/guc.c:3204 +#: utils/misc/guc.c:3958 msgid "Sets the display format for interval values." -msgstr "時刻インターãƒãƒ«å€¤ã®è¡¨ç¤ºãƒ•ォーマットを設定ã—ã¾ã™ã€‚" +msgstr "インターãƒãƒ«å€¤ã®è¡¨ç¤ºãƒ•ォーマットを設定。" -#: utils/misc/guc.c:3215 +#: utils/misc/guc.c:3969 msgid "Sets the verbosity of logged messages." -msgstr "ログ出力メッセージã®è©³ç´°åº¦ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ログ出力メッセージã®è©³ç´°åº¦ã‚’設定。" -#: utils/misc/guc.c:3225 +#: utils/misc/guc.c:3979 msgid "Sets the message levels that are logged." -msgstr "ログã«å‡ºåŠ›ã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ログã«å‡ºåŠ›ã™ã‚‹ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒ¬ãƒ™ãƒ«ã‚’設定。" -#: utils/misc/guc.c:3236 +#: utils/misc/guc.c:3990 msgid "Causes all statements generating error at or above this level to be logged." msgstr "ã“ã®ãƒ¬ãƒ™ãƒ«ä»¥ä¸Šã®ã‚¨ãƒ©ãƒ¼ã‚’発生ã•ã›ãŸå…¨ã¦ã®SQL文をログã«è¨˜éŒ²ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3247 +#: utils/misc/guc.c:4001 msgid "Sets the type of statements logged." -msgstr "ログ出力ã™ã‚‹æ–‡ã®ç¨®é¡žã‚’設定ã—ã¾ã™ã€‚" +msgstr "ログ出力ã™ã‚‹æ–‡ã®ç¨®é¡žã‚’設定。" -#: utils/misc/guc.c:3257 +#: utils/misc/guc.c:4011 msgid "Sets the syslog \"facility\" to be used when syslog enabled." -msgstr "syslogを有効ã«ã—ãŸå ´åˆã«ä½¿ç”¨ã™ã‚‹syslog \"facility\"を設定ã—ã¾ã™ã€‚" +msgstr "syslogを有効ã«ã—ãŸå ´åˆã«ä½¿ç”¨ã™ã‚‹syslog \"facility\"を設定。" -#: utils/misc/guc.c:3272 +#: utils/misc/guc.c:4026 msgid "Sets the session's behavior for triggers and rewrite rules." -msgstr "ãƒˆãƒªã‚¬ã¨æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã«é–¢ã™ã‚‹ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®å‹•作を設定ã—ã¾ã™ã€‚" +msgstr "ãƒˆãƒªã‚¬ã¨æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã«é–¢ã™ã‚‹ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®å‹•作を設定。" -#: utils/misc/guc.c:3282 +#: utils/misc/guc.c:4036 msgid "Sets the current transaction's synchronization level." -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®åŒæœŸãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®åŒæœŸãƒ¬ãƒ™ãƒ«ã‚’設定。" -#: utils/misc/guc.c:3292 +#: utils/misc/guc.c:4046 +msgid "Allows archiving of WAL files using archive_command." +msgstr "archive_command.\"を使用ã—ãŸWALファイルã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–処ç†ã‚’許å¯ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4056 msgid "Enables logging of recovery-related debugging information." msgstr "リカãƒãƒªé–¢é€£ã®ãƒ‡ãƒãƒƒã‚°æƒ…å ±ã®è¨˜éŒ²ã‚’行ã„ã¾ã™" -#: utils/misc/guc.c:3308 +#: utils/misc/guc.c:4072 msgid "Collects function-level statistics on database activity." msgstr "データベースã®å‹•作ã«é–¢ã—ã¦ã€é–¢æ•°ãƒ¬ãƒ™ãƒ«ã®çµ±è¨ˆæƒ…報をåŽé›†ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3318 +#: utils/misc/guc.c:4082 msgid "Set the level of information written to the WAL." -msgstr "WAL ã«æ›¸ã出ã•れる情報ã®ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" +msgstr "WALã«æ›¸ã出ã•れる情報ã®ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4092 +msgid "Selects the dynamic shared memory implementation used." +msgstr "使用ã™ã‚‹å‹•的共有メモリã®å®Ÿè£…ã‚’é¸æŠžã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3328 +#: utils/misc/guc.c:4102 msgid "Selects the method used for forcing WAL updates to disk." -msgstr "強制的ã«WALã®æ›´æ–°ã‚’ディスクã«åã出ã™ãŸã‚ã®æ–¹æ³•ã‚’é¸æŠžã—ã¾ã™ã€‚" +msgstr "WALã®æ›´æ–°ã®ãƒ‡ã‚£ã‚¹ã‚¯ã¸ã®æ›¸ã出ã—を強制ã™ã‚‹ã‚ã®æ–¹æ³•ã‚’é¸æŠžã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3338 +#: utils/misc/guc.c:4112 msgid "Sets how binary values are to be encoded in XML." msgstr "ã©ã®ã‚ˆã†ã«ãƒã‚¤ãƒŠãƒªå€¤ã‚’XMLã«ç¬¦å·åŒ–ã™ã‚‹ã‹ã‚’設定ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:3348 +#: utils/misc/guc.c:4122 msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." -msgstr "暗黙的ãªè§£æžãŠã‚ˆã³ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚¼ãƒ¼ã‚·ãƒ§ãƒ³æ“作ã«ãŠã„ã¦XMLデータを文書ã¨ã¿ãªã™ã‹æ–­ç‰‡ã¨ã¿ãªã™ã‹ã‚’設定ã—ã¾ã™ã€‚" +msgstr "暗黙的ãªãƒ‘ースãŠã‚ˆã³ç›´åˆ—化æ“作ã«ãŠã„ã¦XMLデータを文書ã¨ã¿ãªã™ã‹æ–­ç‰‡ã¨ã¿ãªã™ã‹ã‚’設定ã—ã¾ã™ã€‚" -#: utils/misc/guc.c:4162 +#: utils/misc/guc.c:4133 +msgid "Use of huge pages on Linux or Windows." +msgstr "LinuxãŠã‚ˆã³Windowsã§ãƒ’ュージページを使用設定。" + +#: utils/misc/guc.c:4143 +msgid "Forces use of parallel query facilities." +msgstr "並列å•ã„åˆã‚ã›æ©Ÿæ§‹ã‚’強制的ã«ä½¿ç”¨ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4144 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "å¯èƒ½ã§ã‚れã°å•ã„åˆã‚ã›ã‚’並列処ç†ãƒ¯ãƒ¼ã‚«ã‚’使ã£ã¦ã€ä¸¦åˆ—処ç†ã®åˆ¶é™ã®å…ƒã«å®Ÿè¡Œã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4153 +msgid "Encrypt passwords." +msgstr "パスワードを暗å·åŒ–ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4154 +msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +msgstr "ENCRYPTEDã‚‚ã—ãã¯UNENCRYPTEDã®æŒ‡å®šç„¡ã—ã«CREATE USERã‚‚ã—ãã¯ALTER USERã§ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ãŒæŒ‡å®šã•れãŸå ´åˆã€ã“ã®ã‚ªãƒ—ションãŒãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æš—å·åŒ–を行ãªã†ã‹ã©ã†ã‹ã‚’決定ã—ã¾ã™ã€‚" + +#: utils/misc/guc.c:4956 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: utils/misc/guc.c:4961 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "initdbã¾ãŸã¯pg_basebackupを実行ã—ã¦ã€PostgreSQLãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’åˆæœŸåŒ–ã—ã¦ãã ã•ã„。\n" + +#: utils/misc/guc.c:4981 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -19683,12 +25728,12 @@ msgstr "" "--config-fileã¾ãŸã¯-Dオプションを指定ã™ã‚‹ã€ã‚ã‚‹ã„ã¯PGDATA環境変数を設\n" "定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" -#: utils/misc/guc.c:4181 +#: utils/misc/guc.c:5000 #, c-format -msgid "%s cannot access the server configuration file \"%s\": %s\n" -msgstr "%sã¯ã‚µãƒ¼ãƒè¨­å®šãƒ•ァイル\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“: %s\n" +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: サーãƒè¨­å®šãƒ•ァイル\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“: %s\n" -#: utils/misc/guc.c:4202 +#: utils/misc/guc.c:5026 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -19698,7 +25743,7 @@ msgstr "" "\"%s\"内ã§\"data_directory\"を指定ã™ã‚‹ã€-Dオプションを指定ã™ã‚‹ã€PGDATAç’°\n" "境変数ã§è¨­å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" -#: utils/misc/guc.c:4242 +#: utils/misc/guc.c:5074 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -19708,7 +25753,7 @@ msgstr "" "\"%s\"内ã§\"hba_directory\"を指定ã™ã‚‹ã€-Dオプションを指定ã™ã‚‹ã€PGDATAç’°\n" "境変数ã§è¨­å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" -#: utils/misc/guc.c:4265 +#: utils/misc/guc.c:5097 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -19718,951 +25763,588 @@ msgstr "" "\"%s\"内ã§\"ident_directory\"を指定ã™ã‚‹ã€-Dオプションを指定ã™ã‚‹ã€PGDATAç’°\n" "境変数ã§è¨­å®šã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" -#: utils/misc/guc.c:4857 utils/misc/guc.c:5037 +#: utils/misc/guc.c:5772 utils/misc/guc.c:5819 msgid "Value exceeds integer range." msgstr "å€¤ãŒæ•´æ•°ç¯„囲を超ãˆã¦ã„ã¾ã™ã€‚" -#: utils/misc/guc.c:4876 -#| msgid "Valid units for this parameter are \"kB\", \"MB\", and \"GB\"." -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "ã“ã®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æœ‰åйå˜ä½ã¯\"kB\"ã€\"MB\"ã€\"GB\"ã€\"TB\"ã§ã™ã€‚" +#: utils/misc/guc.c:6042 +#, c-format +msgid "parameter \"%s\" requires a numeric value" +msgstr "パラメータ\"%s\"ã¯æ•°å€¤ãŒå¿…è¦ã§ã™" + +#: utils/misc/guc.c:6051 +#, c-format +msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%gã¯ãƒ‘ラメータ\"%s\"ã®æœ‰åŠ¹ç¯„å›²ã‚’è¶…ãˆã¦ã„ã¾ã™(%g .. %g)" -#: utils/misc/guc.c:4951 -msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." -msgstr "ã“ã®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã®æœ‰åйå˜ä½ã¯\"ms\"ã€\"s\"ã€\"min\"ã€\"h\"ã€\"d\"ã§ã™ã€‚" +#: utils/misc/guc.c:6204 utils/misc/guc.c:7574 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "並列処ç†ä¸­ã¯ãƒ‘ラメータã®è¨­å®šã¯ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:5244 utils/misc/guc.c:6026 utils/misc/guc.c:6078 -#: utils/misc/guc.c:6811 utils/misc/guc.c:6970 utils/misc/guc.c:8144 +#: utils/misc/guc.c:6211 utils/misc/guc.c:6963 utils/misc/guc.c:7016 +#: utils/misc/guc.c:7067 utils/misc/guc.c:7403 utils/misc/guc.c:8170 +#: utils/misc/guc.c:8338 utils/misc/guc.c:10015 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "設定パラメータ\"%s\"ã¯ä¸æ˜Žã§ã™" -#: utils/misc/guc.c:5259 +#: utils/misc/guc.c:6226 utils/misc/guc.c:7415 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "パラメータ\"%s\"を変更ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:5292 +#: utils/misc/guc.c:6259 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "ç¾åœ¨ãƒ‘ラメータ\"%s\"を変更ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:5323 -#, c-format -msgid "parameter \"%s\" cannot be set after connection start" -msgstr "接続開始後ã«ãƒ‘ラメータ\"%s\"を変更ã§ãã¾ã›ã‚“" - -#: utils/misc/guc.c:5333 utils/misc/guc.c:8160 +#: utils/misc/guc.c:6277 utils/misc/guc.c:6324 utils/misc/guc.c:10031 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "パラメータ\"%s\"を設定ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" -#: utils/misc/guc.c:5371 +#: utils/misc/guc.c:6314 #, c-format -msgid "cannot set parameter \"%s\" within security-definer function" -msgstr "セキュリティー定義用関数内ã§ãƒ‘ラメーター \"%s\" を設定ã§ãã¾ã›ã‚“" +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "接続開始後ã«ãƒ‘ラメータ\"%s\"を変更ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:5524 utils/misc/guc.c:5859 utils/misc/guc.c:8324 -#: utils/misc/guc.c:8358 +#: utils/misc/guc.c:6362 #, c-format -msgid "invalid value for parameter \"%s\": \"%s\"" -msgstr "パラメータ\"%s\"ã®å€¤ãŒç„¡åйã§ã™: \"%s\"" +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "セキュリティー定義用関数内ã§ãƒ‘ラメーター \"%s\" を設定ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:5533 +#: utils/misc/guc.c:6971 utils/misc/guc.c:7021 utils/misc/guc.c:8345 #, c-format -msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" -msgstr "%dã¯ãƒ‘ラメータ\"%s\"ã®æœ‰åŠ¹ç¯„å›²ã‚’è¶…ãˆã¦ã„ã¾ã™(%d .. %d)" +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "\"%s\"ã®å†…容を見るã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã¾ãŸã¯pg_read_all_settingsロールã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/misc/guc.c:5626 +#: utils/misc/guc.c:7112 #, c-format -msgid "parameter \"%s\" requires a numeric value" -msgstr "パラメータ\"%s\"ã¯æ•°å€¤ãŒå¿…è¦ã§ã™" +msgid "SET %s takes only one argument" +msgstr "SET %sã¯1ã¤ã®å¼•æ•°ã®ã¿ã‚’å–りã¾ã™" -#: utils/misc/guc.c:5634 +#: utils/misc/guc.c:7363 #, c-format -msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" -msgstr "%gã¯ãƒ‘ラメータ\"%s\"ã®æœ‰åŠ¹ç¯„å›²ã‚’è¶…ãˆã¦ã„ã¾ã™(%g .. %g)" +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "ALTER SYSTEM コマンドを実行ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#: utils/misc/guc.c:6034 utils/misc/guc.c:6082 utils/misc/guc.c:6974 +#: utils/misc/guc.c:7448 #, c-format -msgid "must be superuser to examine \"%s\"" -msgstr "\"%s\"を確èªã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "ALTER SYSTEMã§ã®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿å€¤ã¯æ”¹è¡Œã‚’å«ã‚“ã§ã¯ã„ã‘ã¾ã›ã‚“" -#: utils/misc/guc.c:6148 +#: utils/misc/guc.c:7493 #, c-format -msgid "SET %s takes only one argument" -msgstr "SET %sã¯1ã¤ã®å¼•æ•°ã®ã¿ã‚’å–りã¾ã™" +msgid "could not parse contents of file \"%s\"" +msgstr "ファイル\"%s\"ã®å†…容をパースã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/misc/guc.c:6319 +#: utils/misc/guc.c:7650 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOTã¯ã¾ã å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: utils/misc/guc.c:6399 +#: utils/misc/guc.c:7734 #, c-format msgid "SET requires parameter name" msgstr "SETã«ã¯ãƒ‘ラメータåãŒå¿…è¦ã§ã™" -#: utils/misc/guc.c:6513 +#: utils/misc/guc.c:7867 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "パラメータ\"%s\"ã‚’å†å®šç¾©ã—よã†ã¨ã—ã¦ã„ã¾ã™" -#: utils/misc/guc.c:7863 +#: utils/misc/guc.c:9648 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "パラメータ\"%s\"を設定ã§ãã¾ã›ã‚“" + +#: utils/misc/guc.c:9735 #, c-format msgid "could not parse setting for parameter \"%s\"" -msgstr "パラメータ\"%s\"ã®è¨­å®šã‚’è§£æžã§ãã¾ã›ã‚“" +msgstr "パラメータ\"%s\"ã®è¨­å®šã‚’パースã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:8222 utils/misc/guc.c:8256 +#: utils/misc/guc.c:10093 utils/misc/guc.c:10127 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "パラメータ\"%s\"ã®å€¤ãŒç„¡åйã§ã™: %d" -#: utils/misc/guc.c:8290 +#: utils/misc/guc.c:10161 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "パラメータ\"%s\"ã®å€¤ãŒç„¡åйã§ã™: %g" -#: utils/misc/guc.c:8480 +#: utils/misc/guc.c:10445 #, c-format msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." msgstr "当該セッションã§ä½•らã‹ã®ä¸€æ™‚テーブルãŒã‚¢ã‚¯ã‚»ã‚¹ã•れãŸå¾Œã¯ \"temp_buffers\"を変更ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:8492 -#, c-format -msgid "SET AUTOCOMMIT TO OFF is no longer supported" -msgstr "SET AUTOCOMMIT TO OFFã¯ã‚‚ã†ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#: utils/misc/guc.c:8504 -#, c-format -msgid "assertion checking is not supported by this build" -msgstr "ã“ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«ã¯ã‚¢ã‚µãƒ¼ãƒˆæ¤œæŸ»ã¯çµ„ã¿è¾¼ã¾ã‚Œã¦ã„ã¾ã›ã‚“" - -#: utils/misc/guc.c:8517 +#: utils/misc/guc.c:10457 #, c-format msgid "Bonjour is not supported by this build" msgstr "ã“ã®ãƒ“ルドã§ã¯ bonjour ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/misc/guc.c:8530 +#: utils/misc/guc.c:10470 #, c-format msgid "SSL is not supported by this build" msgstr "ã“ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã§ã¯SSLã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: utils/misc/guc.c:8542 +#: utils/misc/guc.c:10482 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "\"log_statement_stats\"ãŒçœŸã®å ´åˆã€ãƒ‘ラメータを有効ã«ã§ãã¾ã›ã‚“" -#: utils/misc/guc.c:8554 +#: utils/misc/guc.c:10494 #, c-format msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "\"log_parser_stats\"ã€\"log_planner_stats\"ã€\"log_executor_stats\"ã®ã„ãšã‚Œã‹ãŒçœŸã®å ´åˆã¯ \"log_statement_stats\" を有効ã«ã§ãã¾ã›ã‚“" +#: utils/misc/guc.c:10710 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgstr "posix_fadvise() ã‚’ã‚‚ãŸãªã„プラットフォームã§ã¯effective_io_concurrencyã¯0ã«è¨­å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" + #: utils/misc/help_config.c:131 #, c-format msgid "internal error: unrecognized run-time parameter type\n" -msgstr "内部エラー: 実行時パラメータ種類ãŒä¸æ˜Žã§ã™\n" +msgstr "内部エラー: 実行時ã®ãƒ‘ラメータ型ãŒèªè­˜ã§ãã¾ã›ã‚“\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "å•ã„åˆã‚ã›ã§æŒ‡å®šã•れãŸè¿”å´ã‚¿ãƒ—ルã¨é–¢æ•°ã®è¿”り値ã®åž‹ãŒäº’æ›ã§ã¯ã‚りã¾ã›ã‚“" + +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "算出ã•れãŸCRCãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒãƒ•ã‚¡ã‚¤ãƒ«ã«æ ¼ç´ã•れã¦ã„る値ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: utils/misc/timeout.c:380 +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: ユーザ: %d.%02dç§’ã€ã‚·ã‚¹ãƒ†ãƒ : %d.%02dç§’ã€çµŒéŽæ™‚é–“: %d.%02dç§’" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "å•ã„åˆã‚ã›ã¯ãƒ†ãƒ¼ãƒ–ル\"%s\"ã«å¯¾ã™ã‚‹è¡Œãƒ¬ãƒ™ãƒ«ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·ã®å½±éŸ¿ã‚’å—ã‘ã¾ã™" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ‰€æœ‰è€…ã«å¯¾ã™ã‚‹ãƒãƒªã‚·ã‚’無効ã«ã™ã‚‹ã«ã¯ã€ALTER TABLE NO FORCE ROW LEVEL SECURITY を使ã£ã¦ãã ã•ã„。" + +#: utils/misc/timeout.c:388 #, c-format -#| msgid "cannot move system relation \"%s\"" msgid "cannot add more timeout reasons" -msgstr "ã“れ以上タイムアウトã•ã›ã‚‹ç†ç”±ã‚’追加ã§ãã¾ã›ã‚“" +msgstr "ã“れ以上ã®ã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆè¦å› ã‚’追加ã§ãã¾ã›ã‚“" #: utils/misc/tzparser.c:61 #, c-format msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%3$s\"ã®%4$dè¡Œã®æ™‚間帯çœç•¥å½¢\"%1$s\"ãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§%2$d文字)" - -#: utils/misc/tzparser.c:68 -#, c-format -msgid "time zone offset %d is not a multiple of 900 sec (15 min) in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%2$s\"ã®%3$dè¡Œã®æ™‚間帯オフセット%1$dã¯900秒(15分)ã®å€æ•°ã§ã¯ã‚りã¾ã›ã‚“。" +msgstr "タイムゾーンファイル\"%3$s\"ã®%4$d行ã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³çœç•¥å½¢\"%1$s\"ãŒé•·ã™ãŽã¾ã™ï¼ˆæœ€å¤§%2$d文字)" -#: utils/misc/tzparser.c:80 +#: utils/misc/tzparser.c:73 #, c-format msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%2$s\"ã®%3$dè¡Œã®æ™‚間帯オフセット%1$dã¯ç¯„囲外ã§ã™" +msgstr "タイムゾーンファイル\"%2$s\"ã®%3$d行ã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚ªãƒ•セット%1$dã¯ç¯„囲外ã§ã™" -#: utils/misc/tzparser.c:115 +#: utils/misc/tzparser.c:112 #, c-format msgid "missing time zone abbreviation in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã§æ™‚間帯çœç•¥å½¢ãŒã‚りã¾ã›ã‚“" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã§ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³çœç•¥å½¢ãŒã‚りã¾ã›ã‚“" -#: utils/misc/tzparser.c:124 +#: utils/misc/tzparser.c:121 #, c-format msgid "missing time zone offset in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã§æ™‚間帯オフセットãŒã‚りã¾ã›ã‚“" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã§ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚ªãƒ•セットãŒã‚りã¾ã›ã‚“" -#: utils/misc/tzparser.c:131 +#: utils/misc/tzparser.c:133 #, c-format msgid "invalid number for time zone offset in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã®æ™‚間帯オフセット数値ãŒç„¡åйã§ã™" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã®ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ã‚ªãƒ•セット値ãŒç„¡åйã§ã™" -#: utils/misc/tzparser.c:154 +#: utils/misc/tzparser.c:169 #, c-format msgid "invalid syntax in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã§æ§‹æ–‡ãŒç„¡åйã§ã™" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã§æ§‹æ–‡ãŒç„¡åйã§ã™" -#: utils/misc/tzparser.c:218 +#: utils/misc/tzparser.c:237 #, c-format msgid "time zone abbreviation \"%s\" is multiply defined" -msgstr "時間帯çœç•¥å½¢\"%s\"ãŒè¤‡æ•°å®šç¾©ã•れã¦ã„ã¾ã™" +msgstr "タイムゾーンçœç•¥å½¢\"%s\"ãŒè¤‡æ•°å®šç¾©ã•れã¦ã„ã¾ã™" -#: utils/misc/tzparser.c:220 +#: utils/misc/tzparser.c:239 #, c-format msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã®é …ç›®ã¯ã€ãƒ•ァイル\"%s\"ã®è¡Œ%dã¨ç«¶åˆã—ã¾ã™ã€‚" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã®é …ç›®ã¯ã€ãƒ•ァイル\"%s\"ã®è¡Œ%dã¨ç«¶åˆã—ã¾ã™ã€‚" -#: utils/misc/tzparser.c:285 +#: utils/misc/tzparser.c:301 #, c-format msgid "invalid time zone file name \"%s\"" -msgstr "時間帯ファイルåãŒç„¡åйã§ã™: \"%s\"" +msgstr "タイムゾーンファイルåãŒç„¡åйã§ã™: \"%s\"" -#: utils/misc/tzparser.c:298 +#: utils/misc/tzparser.c:314 #, c-format msgid "time zone file recursion limit exceeded in file \"%s\"" -msgstr "ファイル\"%s\"ã§æ™‚間帯ファイルã®å†å¸°ã®ä¸Šé™ã‚’è¶…ãˆã¾ã—ãŸã€‚" +msgstr "ファイル\"%s\"ã§ã‚¿ã‚¤ãƒ ã‚¾ãƒ¼ãƒ³ãƒ•ァイルã®å†å¸°ã®ä¸Šé™ã‚’è¶…ãˆã¾ã—ãŸã€‚" -#: utils/misc/tzparser.c:337 utils/misc/tzparser.c:350 +#: utils/misc/tzparser.c:353 utils/misc/tzparser.c:366 #, c-format msgid "could not read time zone file \"%s\": %m" -msgstr "時間帯ファイル\"%s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" +msgstr "タイムゾーンファイル\"%s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/misc/tzparser.c:360 +#: utils/misc/tzparser.c:376 #, c-format msgid "line is too long in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dãŒé•·ã™ãŽã¾ã™ã€‚" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dãŒé•·ã™ãŽã¾ã™ã€‚" -#: utils/misc/tzparser.c:383 +#: utils/misc/tzparser.c:399 #, c-format msgid "@INCLUDE without file name in time zone file \"%s\", line %d" -msgstr "時間帯ファイル\"%s\"ã®è¡Œ%dã«ãƒ•ァイルåãŒãªã„@INCLUDEãŒã‚りã¾ã™" +msgstr "タイムゾーンファイル\"%s\"ã®è¡Œ%dã«ãƒ•ァイルåãŒãªã„@INCLUDEãŒã‚りã¾ã™" -#: utils/mmgr/aset.c:500 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "メモリコンテキスト\"%s\"ã®ä½œæˆæ™‚ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: utils/mmgr/aset.c:679 utils/mmgr/aset.c:874 utils/mmgr/aset.c:1117 +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1325 #, c-format -msgid "Failed on request of size %lu." -msgstr "サイズ%luã®è¦æ±‚ã«å¤±æ•—ã—ã¾ã—ãŸ" +msgid "could not attach to dynamic shared area" +msgstr "動的共有エリアをアタッãƒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/mmgr/portalmem.c:208 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "メモリコンテクスト\"%2$s\"ã§ã‚µã‚¤ã‚º%1$zuã®è¦æ±‚ãŒå¤±æ•—ã—ã¾ã—ãŸã€‚" + +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "カーソル\"%s\"ã¯ã™ã§ã«å­˜åœ¨ã—ã¾ã™" -#: utils/mmgr/portalmem.c:212 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "既存ã®ã‚«ãƒ¼ã‚½ãƒ«\"%s\"をクローズã—ã¦ã„ã¾ã™" -#: utils/mmgr/portalmem.c:479 +#: utils/mmgr/portalmem.c:398 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "ãƒãƒ¼ã‚¿ãƒ«\"%s\"を実行ã§ãã¾ã›ã‚“" + +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "固定ã•れãŸãƒãƒ¼ã‚¿ãƒ«\"%s\"ã¯å‰Šé™¤ã§ãã¾ã›ã‚“" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "アクテイブãªãƒãƒ¼ã‚¿ãƒ« \"%s\" を削除ã§ãã¾ã›ã‚“" -#: utils/mmgr/portalmem.c:669 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "WITH HOLD 付ãã®ã‚«ãƒ¼ã‚½ãƒ«ã‚’作æˆã—ãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ PREPARE ã§ãã¾ã›ã‚“" -#: utils/sort/logtape.c:215 +#: utils/mmgr/portalmem.c:1263 #, c-format -msgid "Perhaps out of disk space?" -msgstr "ディスク容é‡ãŒä¸è¶³ã—ã¦ã„ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™" +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "読ã¿è¾¼ã¿å°‚用ã§ã¯ãªã„カーソルã®ãƒ«ãƒ¼ãƒ—内ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å‘½ä»¤ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“" -#: utils/sort/logtape.c:232 +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "一時ファイルã®ãƒ–ロック%ldを読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" -#: utils/sort/tuplesort.c:3184 +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "一時ファイルã¸ã®æ›¸ã出ã—ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "タプルストア共有一時ファイルã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "タプルストア共有一時ファイル内ã«äºˆæœŸã—ãªã„ãƒãƒ£ãƒ³ã‚¯ãŒã‚りã¾ã—ãŸ" + +#: utils/sort/tuplesort.c:2967 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "外部ソートã§ã¯%d以上ã®ãƒ©ãƒ³æ•°ã¯æ‰±ãˆã¾ã›ã‚“" + +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" -msgstr "ä¸€æ„æ€§ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "一æ„インデックス\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: utils/sort/tuplesort.c:3186 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." -msgstr "キー %s ã¯é‡è¤‡ã—ã¦ã„ã¾ã™ã€‚" +msgstr "キー%sã¯é‡è¤‡ã—ã¦ã„ã¾ã™ã€‚" -#: utils/time/snapmgr.c:840 +#: utils/sort/tuplesort.c:4054 +#, c-format +msgid "Duplicate keys exist." +msgstr "é‡è¤‡ã—ãŸã‚­ãƒ¼ãŒå­˜åœ¨ã—ã¾ã™ã€‚" + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file: %m" +msgstr "タプルストア一時ファイルã®ã‚·ãƒ¼ã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 +#: utils/sort/tuplestore.c:1556 +#, c-format +msgid "could not read from tuplestore temporary file: %m" +msgstr "タプルストア一時ファイルã‹ã‚‰ã®èª­ã¿è¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 +#: utils/sort/tuplestore.c:1529 +#, c-format +msgid "could not write to tuplestore temporary file: %m" +msgstr "タプルストア一時ファイルã¸ã®æ›¸ãè¾¼ã¿ã«å¤±æ•—ã—ã¾ã—ãŸ: %m" + +#: utils/time/snapmgr.c:622 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "å…ƒã¨ãªã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ã™ã§ã«å®Ÿè¡Œä¸­ã§ã¯ã‚りã¾ã›ã‚“。" + +#: utils/time/snapmgr.c:1200 #, c-format msgid "cannot export a snapshot from a subtransaction" -msgstr "サブトランザクションブロックã‹ã‚‰ã‚¹ãƒŠãƒƒãƒ—ショットを公開ã§ãã¾ã›ã‚“" +msgstr "サブトランザクションã‹ã‚‰ã‚¹ãƒŠãƒƒãƒ—ショットをエクスãƒãƒ¼ãƒˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: utils/time/snapmgr.c:990 utils/time/snapmgr.c:995 utils/time/snapmgr.c:1000 -#: utils/time/snapmgr.c:1015 utils/time/snapmgr.c:1020 -#: utils/time/snapmgr.c:1025 utils/time/snapmgr.c:1124 -#: utils/time/snapmgr.c:1140 utils/time/snapmgr.c:1165 +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 +#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 +#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 +#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 +#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 #, c-format msgid "invalid snapshot data in file \"%s\"" -msgstr "ファイル\"%s\"内ã®ã‚¹ãƒŠãƒƒãƒ—ショットデータãŒç„¡åйã§ã™" +msgstr "ファイル\"%s\"内ã®ã‚¹ãƒŠãƒƒãƒ—ショットデータãŒä¸æ­£ã§ã™" -#: utils/time/snapmgr.c:1062 +#: utils/time/snapmgr.c:1456 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "SET TRANSACTION SNAPSHOTã‚’å…¨ã¦ã®å•ã„åˆã‚ã›ã®å‰ã«å‘¼ã³å‡ºã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/time/snapmgr.c:1071 +#: utils/time/snapmgr.c:1465 #, c-format msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" -msgstr "スナップショットをインãƒãƒ¼ãƒˆã™ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯SERIALIZABLEã¾ãŸã¯REPEATABLE READ隔離レベルをæŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "スナップショットをインãƒãƒ¼ãƒˆã™ã‚‹ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯SERIALIZABLEã¾ãŸã¯REPEATABLE READ分離レベルã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: utils/time/snapmgr.c:1080 utils/time/snapmgr.c:1089 +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 #, c-format msgid "invalid snapshot identifier: \"%s\"" -msgstr "スナップショット識別å­ç„¡åйã§ã™: \"%s\"" +msgstr "無効ãªã‚¹ãƒŠãƒƒãƒ—ショット識別å­: \"%s\"" -#: utils/time/snapmgr.c:1178 +#: utils/time/snapmgr.c:1573 #, c-format msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" -msgstr "シリアライザブルトランザクションã¯ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚¶ãƒ–ル以外ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰ã®ã‚¹ãƒŠãƒƒãƒ—ショットをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“" +msgstr "シリアライザブルトランザクションã¯ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚¶ãƒ–ルã§ã¯ãªã„トランザクションã‹ã‚‰ã®ã‚¹ãƒŠãƒƒãƒ—ショットをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“" -#: utils/time/snapmgr.c:1182 +#: utils/time/snapmgr.c:1577 #, c-format msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" -msgstr "読ã¿å–りã®ã¿ã®ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚¶ãƒ–ルトランザクションã§ã¯ã€èª­ã¿å–りã®ã¿ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‹ã‚‰ã‚¹ãƒŠãƒƒãƒ—ショットを読ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "読ã¿å–りã®ã¿ã®ã‚·ãƒªã‚¢ãƒ©ã‚¤ã‚¶ãƒ–ルトランザクションã§ã¯ã€èª­ã¿å–り専用トランザクションã‹ã‚‰ã‚¹ãƒŠãƒƒãƒ—ショットを読ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: utils/time/snapmgr.c:1197 +#: utils/time/snapmgr.c:1592 #, c-format msgid "cannot import a snapshot from a different database" msgstr "ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‹ã‚‰ã®ã‚¹ãƒŠãƒƒãƒ—ショットを読ã¿è¾¼ã‚€ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#~ msgid "trigger_file = '%s'" -#~ msgstr "trigger_file = '%s'" - -#~ msgid "invalid xlog switch record at %X/%X" -#~ msgstr "%X/%Xã®xlog切り替ãˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒç„¡åйã§ã™" - -#~ msgid "Write-Ahead Log / Streaming Replication" -#~ msgstr "ログ先行書ã込㿠/ ストリーミング・レプリケーション" - -#~ msgid "%s: could not fork background process: %s\n" -#~ msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ—ロセスをforkã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" - -#~ msgid "syntax error in recovery command file: %s" -#~ msgstr "リカãƒãƒªã‚³ãƒžãƒ³ãƒ‰ãƒ•ã‚¡ã‚¤ãƒ«å†…ã®æ§‹æ–‡ã‚¨ãƒ©ãƒ¼: %s" - -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "ディレクトリを\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#~ msgid "consistent state delayed because recovery snapshot incomplete" -#~ msgstr "リカãƒãƒªãƒ¼ã‚¹ãƒŠãƒƒãƒ—ショットãŒä¸å®Œå…¨ã®ãŸã‚ã€ä¸€è²«æ€§çŠ¶æ…‹ãŒé…å»¶ã—ã¾ã—ãŸ" - -#~ msgid "invalid record length at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒç„¡åйã§ã™" - -#~ msgid "invalid list syntax for parameter \"log_destination\"" -#~ msgstr "パラメータ\"log_destination\"ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒç„¡åйã§ã™" - -#~ msgid "record with incorrect prev-link %X/%X at %X/%X" -#~ msgstr "ç›´å‰ã®ãƒªãƒ³ã‚¯%1$X/%2$XãŒä¸æ­£ãªãƒ¬ã‚³ãƒ¼ãƒ‰ãŒ%3$X/%4$Xã«ã‚りã¾ã™" - -#~ msgid "Sets the message levels that are logged during recovery." -#~ msgstr "リカãƒãƒªãƒ¼ä¸­ã«ãƒ­ã‚°ã‚’å–ã‚‹ã¹ãメッセージã®ãƒ¬ãƒ™ãƒ«ã‚’設定ã—ã¾ã™ã€‚" - -#~ msgid "unlogged GiST indexes are not supported" -#~ msgstr "ログã®å–得を行ã‚ãªã„(unlogged) GiST インデックスã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" - -#~ msgid "Sets immediate fsync at commit." -#~ msgstr "コミット時ã«å³åº§ã«fsyncã™ã‚‹ã‚ˆã†è¨­å®šã—ã¾ã™" - -#~ msgid "there is no contrecord flag in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル%uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%uã€ã‚ªãƒ•セット%uã«contrecordãŒã‚りã¾ã›ã‚“" - -#~ msgid "Cancelled on identification as a pivot, during commit attempt." -#~ msgstr "コミットã®è©¦è¡Œä¸­ã€ãƒ”ボットã¨ã—ã¦ã®è­˜åˆ¥å‡¦ç†ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" - -#~ msgid "invalid magic number %04X in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル%2$uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%3$uã€ã‚ªãƒ•セット%4$uã®ãƒžã‚¸ãƒƒã‚¯ç•ªå·%1$04Xã¯ç„¡åйã§ã™" - -#~ msgid "unable to open directory pg_tblspc: %m" -#~ msgstr "ディレクトリ pg_tblspc をオープンã§ãã¾ã›ã‚“: %m" - -#~ msgid "cannot use aggregate function in rule WHERE condition" -#~ msgstr "ルールã®WHEREæ¡ä»¶ã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "Not safe to send CSV data\n" -#~ msgstr "CSVデータをé€ä¿¡ã™ã‚‹ã«ã¯å®‰å…¨ã§ã¯ã‚りã¾ã›ã‚“\n" - -#~ msgid "cannot use window function in trigger WHEN condition" -#~ msgstr "トリガー㮠WHEN æ¡ä»¶ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "recovery is still in progress, can't accept WAL streaming connections" -#~ msgstr "リカãƒãƒªãŒã¾ã å®Ÿè¡Œä¸­ã«ã¤ãã€WAL ストリーミング接続をå—ã‘付ã‘られã¾ã›ã‚“" - -#~ msgid "incorrect resource manager data checksum in record at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ‡ãƒ¼ã‚¿ã®ãƒã‚§ãƒƒã‚¯ã‚µãƒ ãŒä¸æ­£ã§ã™" - -#~ msgid "invalid interval value for time zone: day not allowed" -#~ msgstr "æ™‚é–“å¸¯ã®æ™‚間間隔値ãŒç„¡åйã§ã™: æ—¥ã¯è¨±ã•れã¾ã›ã‚“" - -#~ msgid "A function returning ANYRANGE must have at least one ANYRANGE argument." -#~ msgstr "ANYRANGEã‚’è¿”ã™é–¢æ•°ã¯å°‘ãªãã¨ã‚‚1ã¤ã®ANYRANGE引数をå–らãªã‘れã°ãªã‚Šã¾ã›ã‚“。" - -#~ msgid "database \"%s\" not found" -#~ msgstr "データベース \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" - -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help ヘルプを表示ã—終了ã—ã¾ã™\n" - -#~ msgid "recovery_target_name = '%s'" -#~ msgstr "recovery_target_name = '%s'" - -#~ msgid "RETURNING cannot contain references to other relations" -#~ msgstr "RETURNINGã«ä»–ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¸ã®å‚ç…§ã‚’æŒãŸã›ã‚‰ã‚Œã¾ã›ã‚“" - -#~ msgid "cannot reference permanent table from temporary table constraint" -#~ msgstr "一時テーブルã®åˆ¶ç´„ã‹ã‚‰æ°¸ç¶šãƒ†ãƒ¼ãƒ–ルをå‚ç…§ã§ãã¾ã›ã‚“" - -#~ msgid "JOIN/ON clause refers to \"%s\", which is not part of JOIN" -#~ msgstr "JOIN/ONå¥ãŒ\"%s\"ã‚’å‚ç…§ã—ã¦ã„ã¾ã™ãŒã€ã“れãŒJOINã«å«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" - -#~ msgid "must be superuser to comment on text search template" -#~ msgstr "テキスト検索テンプレートã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’ã¤ã‘ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "Incorrect XLOG_BLCKSZ in page header." -#~ msgstr "ページヘッダ内ã®XLOG_BLCKSZãŒä¸æ­£ã§ã™ã€‚" - -#~ msgid "unrecognized \"datestyle\" key word: \"%s\"" -#~ msgstr "\"datestyle\"キーワードãŒä¸æ˜Žã§ã™: \"%s\"" - -#~ msgid "invalid standby query string: %s" -#~ msgstr "スタンãƒã‚¤ã‚¯ã‚¨ãƒªæ–‡å­—列ãŒç„¡åйã§ã™ï¼š%s" - -#~ msgid "must be superuser to comment on text search parser" -#~ msgstr "テキスト検索パーサã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’ã¤ã‘ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "VALUES must not contain OLD or NEW references" -#~ msgstr "VALUESã«ã¯OLDã‚„NEWã¸ã®å‚ç…§ã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" - -#~ msgid "CREATE TABLE AS cannot specify INTO" -#~ msgstr "CREATE TABLE ASã¯INTOを指定ã§ãã¾ã›ã‚“" - -#~ msgid "could not get effective UID from peer credentials: %m" -#~ msgstr "相手å´ã®è³‡æ ¼æƒ…å ±ã‹ã‚‰å®Ÿåй UID ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#~ msgid "access to %s" -#~ msgstr "%sã¸ã®ã‚¢ã‚¯ã‚»ã‚¹" - -#~ msgid "function \"%s\" already exists in schema \"%s\"" -#~ msgstr "関数\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«å­˜åœ¨ã—ã¾ã™" - -#~ msgid "Cancelled on conflict out to old pivot." -#~ msgstr "ç«¶åˆã«ã‚ˆã‚Šã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã€å¤ã„ãƒ”ãƒœãƒƒãƒˆã«æˆ»ã‚Šã¾ã—ãŸ" - -#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with window functions" -#~ msgstr "ウィンドウ関数ã§ã¯ SELECT FOR UPDATE/SHARE を使用ã§ãã¾ã›ã‚“" - -#~ msgid "Ident authentication is not supported on local connections on this platform" -#~ msgstr "ã“ã®ãƒ—ラットフォームã®ãƒ­ãƒ¼ã‚«ãƒ«æŽ¥ç¶šã§ã¯Identèªè¨¼ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#~ msgid "default values on foreign tables are not supported" -#~ msgstr "外部テーブルã«å¯¾ã™ã‚‹ãƒ‡ãƒ•ォルト値指定ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#~ msgid "function \"%s\" is already in schema \"%s\"" -#~ msgstr "関数\"%s\"ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž\"%s\"内ã«å­˜åœ¨ã—ã¾ã™" - -#~ msgid "argument of %s must not contain aggregate functions" -#~ msgstr "%s ã®å¼•æ•°ã«ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "parameter \"recovery_target_inclusive\" requires a Boolean value" -#~ msgstr "パラメータ \"recovery_target_inclusive\" ã«ã¯ãƒ–ール値を指定ã—ã¾ã™" - -#~ msgid "unexpected pageaddr %X/%X in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル%3$uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%4$uã€ã‚ªãƒ•セット%5$uã®ãƒšãƒ¼ã‚¸ã‚¢ãƒ‰ãƒ¬ã‚¹%1$X/%2$Xã¯æƒ³å®šå¤–ã§ã™" - -#~ msgid "recovery_target_timeline = latest" -#~ msgstr "recovery_target_timeline = latest" - -#~ msgid "shutdown requested, aborting active base backup" -#~ msgstr "シャットダウンã®è¦æ±‚ãŒãªã•れãŸã®ã§ã€å‹•作中ã®ãƒ™ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—を中止ã—ã¦ã„ã¾ã™" - -#~ msgid "parameter \"standby_mode\" requires a Boolean value" -#~ msgstr "パラメータ \"standby_mode\" ã«ã¯ãƒ–ール値ãŒå¿…è¦ã§ã™" - -#~ msgid "You need an unconditional ON UPDATE DO INSTEAD rule or an INSTEAD OF UPDATE trigger." -#~ msgstr "ç„¡æ¡ä»¶ã® ON UPDATE DO INSTEAD ルールもã—ã㯠INSTEAD OF UPDATE トリガーãŒå¿…è¦ã§ã™" - -#~ msgid "resetting unlogged relations: cleanup %d init %d" -#~ msgstr "ログをå–らãªã„リレーションをリセットã—ã¦ã„ã¾ã™ï¼šã‚¯ãƒªãƒ¼ãƒ³ã‚¢ãƒƒãƒ—:%d init: %d " - -#~ msgid "\"interval\" time zone \"%s\" not valid" -#~ msgstr "\"interval\"ã®æ™‚間帯\"%s\"ãŒç„¡åйã§ã™" - -#~ msgid "parser stack overflow" -#~ msgstr "パーサースタックオーãƒãƒ¼ãƒ•ロー" - -#~ msgid "cannot use aggregate function in parameter default value" -#~ msgstr "パラメータã®ãƒ‡ãƒ•ォルト値ã¨ã—ã¦é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "DECLARE CURSOR cannot specify INTO" -#~ msgstr "DECLARE CURSORã§ã¯INTOを指定ã§ãã¾ã›ã‚“" - -#~ msgid "index \"%s\" needs VACUUM FULL or REINDEX to finish crash recovery" -#~ msgstr "クラッシュリカãƒãƒªã‚’完了ã™ã‚‹ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã‚’VACUUM FULLã¾ãŸã¯REINDEXã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "out of memory\n" -#~ msgstr "メモリä¸è¶³ã§ã™\n" - -#~ msgid "cannot use aggregate function in UPDATE" -#~ msgstr "UPDATEã§ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "recovery_target_timeline = %u" -#~ msgstr "recovery_target_timeline = %u" - -#~ msgid "record length %u at %X/%X too long" -#~ msgstr "%2$X/%3$Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰é•·%1$uãŒå¤§ãã™ãŽã¾ã™" - -#~ msgid "must be member of role \"%s\" to comment upon it" -#~ msgstr "コメントを付与ã™ã‚‹ã«ã¯ãƒ­ãƒ¼ãƒ«\"%s\"ã®ãƒ¡ãƒ³ãƒã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "cannot use subquery in default expression" -#~ msgstr "デフォルトå¼ã«ã¯å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "recovery_target_time = '%s'" -#~ msgstr "recovery_target_time = '%s'" - -#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with HAVING clause" -#~ msgstr "HAVINGå¥ã§ã¯SELECT FOR UPDATE/SHAREを使用ã§ãã¾ã›ã‚“" - -#~ msgid "Must be superuser to drop a foreign-data wrapper." -#~ msgstr "外部データラッパーを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "cannot use window function in EXECUTE parameter" -#~ msgstr "EXECUTE ã®ãƒ‘ラメータã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL, or use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster specification from the table." -#~ msgstr "" -#~ "列\"%s\"ã‚’ NOT NULLã¨ã™ã‚‹ã€ã¾ãŸã¯ã€ALTER TABLE ... SET WITHOUT CLUSTERを使用ã—ã¦ãƒ†ãƒ¼\n" -#~ "ブルã‹ã‚‰ã‚¯ãƒ©ã‚¹ã‚¿æŒ‡å®šã‚’削除ã™ã‚‹ã“ã¨ã§ã€ã“ã®å•題を回é¿ã§ãã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" - -#~ msgid "aggregates not allowed in WHERE clause" -#~ msgstr "WHEREå¥ã§ã¯é›†ç´„を使用ã§ãã¾ã›ã‚“" - -#~ msgid "must be superuser to drop text search parsers" -#~ msgstr "テキスト検索パーサを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "cannot use window function in default expression" -#~ msgstr "デフォルトå¼ã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "See server log for details." -#~ msgstr "詳細ã¯ã‚µãƒ¼ãƒãƒ­ã‚°ã‚’å‚ç…§ã—ã¦ãã ã•ã„" - -#~ msgid "function expression in FROM cannot refer to other relations of same query level" -#~ msgstr "FROMå¥ã®é–¢æ•°å¼ã§ã¯åŒä¸€å•ã„åˆã‚ã›ãƒ¬ãƒ™ãƒ«ã®ä»–ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å‚ç…§ã§ãã¾ã›ã‚“" - -#~ msgid "cannot cluster on expressional index \"%s\" because its index access method does not handle null values" -#~ msgstr "å¼ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã§ã‚¯ãƒ©ã‚¹ã‚¿åŒ–ã§ãã¾ã›ã‚“。インデックスアクセスメソッドãŒNULL値を扱ã‚ãªã„ãŸã‚ã§ã™" - -#~ msgid "\"%s\" is a foreign table" -#~ msgstr "\"%s\"ã¯å¤–部テーブルã§ã™" - -#~ msgid "clustering \"%s.%s\"" -#~ msgstr "\"%s.%s\"をクラスタ化ã—ã¦ã„ã¾ã™" - -#~ msgid "arguments of row IN must all be row expressions" -#~ msgstr "行ã®IN引数ã¯ã™ã¹ã¦è¡Œå¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "tablespace %u is not empty" -#~ msgstr "テーブル空間 %u ã¯ç©ºã§ã¯ã‚りã¾ã›ã‚“" - -#~ msgid "Incorrect XLOG_SEG_SIZE in page header." -#~ msgstr "ページヘッダ内ã®XLOG_SEG_SIZEãŒä¸æ­£ã§ã™ã€‚" - -#~ msgid "ALTER TYPE USING is only supported on plain tables" -#~ msgstr "ALTER TYPE USING ã¯å˜ç´”ãªãƒ†ãƒ¼ãƒ–ルã§ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" - -#~ msgid "" -#~ "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.\n" -#~ "If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.\n" -#~ "The PostgreSQL documentation contains more information about shared memory configuration." -#~ msgstr "" -#~ "通常ã“ã®ã‚¨ãƒ©ãƒ¼ã¯ã€PostgreSQL ãŒè¦æ±‚ã—ãŸå…±æœ‰ãƒ¡ãƒ¢ãƒªã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒã‚«ãƒ¼ãƒãƒ«ã®SHMMAX パラメータを超ãˆãŸå ´åˆã«ç™ºç”Ÿã—ã¾ã™ã€‚ã“ã®è¦æ±‚サイズを減らã™ã“ã¨ã‚‚ã§ãã¾ã™ã—ã€SHMMAX を増やã—ã¦ã‚«ãƒ¼ãƒãƒ«ã‚’冿§‹ç¯‰ã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚è¦æ±‚サイズ(ç¾åœ¨ %lu ãƒã‚¤ãƒˆï¼‰ã‚’減らã—ãŸã„å ´åˆã¯ PostgreSQL ã® shared_buffers ã‚‚ã—ã㯠max_connections を減らã—ã¦ãã ã•ã„。\n" -#~ "ã“ã®è¦æ±‚サイズãŒã™ã§ã«å°ã•ã„å ´åˆã€ã“れãŒã‚«ãƒ¼ãƒãƒ«ã® SHMMIN よりå°ã•ããªã£ã¦ã—ã¾ã£ã¦ã„ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。ãã®ã‚ˆã†ãªå ´åˆã¯è¦æ±‚サイズを大ããã™ã‚‹ã‹ã€ SHMMIN ã‚’ãれã«ãµã•ã‚ã—ã„値ã«å†æ§‹æˆã—ã¦ãã ã•ã„。\n" -#~ "共有メモリã®è¨­å®šã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ã¯ã€PostgreSQL ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã«è¨˜è¼‰ã•れã¦ã„ã¾ã™ã€‚" - -#~ msgid "recovery_target_inclusive = %s" -#~ msgstr "recovery_target_inclusive = %s" - -#~ msgid "must be superuser to rename text search templates" -#~ msgstr "テキスト検索テンプレートã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "hostssl not supported on this platform" -#~ msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ hostssl をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#~ msgid "invalid standby handshake message type %d" -#~ msgstr "スタンãƒã‚¤ãƒãƒ³ãƒ‰ã‚·ã‚§ã‚¤ã‚¯ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã®ã‚¿ã‚¤ãƒ— %d ãŒç„¡åйã§ã™" - -#~ msgid "could not open new log file \"%s\": %m" -#~ msgstr "æ–°ã—ã„ログファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#~ msgid "CREATE TABLE AS specifies too many column names" -#~ msgstr "CREATE TABLE ASã§æŒ‡å®šã—ãŸåˆ—æ•°ãŒå¤šã™ãŽã¾ã™" - -#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL." -#~ msgstr "列\"%s\"ã‚’NOT NULLã¨ã™ã‚‹ã“ã¨ã§ã€ã“れを回é¿ã§ãã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" - -#~ msgid "large object %u was already dropped" -#~ msgstr "ラージオブジェクト %u ã¯ã™ã§ã«å‰Šé™¤ã•れã¦ã„ã¾ã™" - -#~ msgid "cannot cluster on index \"%s\" because access method does not handle null values" -#~ msgstr "インデックス\"%s\"ã§ã‚¯ãƒ©ã‚¹ã‚¿åŒ–ã§ãã¾ã›ã‚“。アクセスメソッドãŒNULL値を扱ã‚ãªã„ãŸã‚ã§ã™" - -#~ msgid "LDAP search failed for filter \"%s\" on server \"%s\": user is not unique (%ld matches)" -#~ msgstr "サーム\"%2$s\" ã§ãƒ•ィルタ \"%1$s\" ã«ã‚ˆã‚‹ LDAP 検索ã«å¤±æ•—ã—ã¾ã—ãŸï¼šãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒä¸€æ„ã§ã¯ã‚りã¾ã›ã‚“(%3$ld 個見ã¤ã‹ã‚Šã¾ã—ãŸï¼‰" - -#~ msgid "argument to pg_get_expr() must come from system catalogs" -#~ msgstr "pg_get_expr() ã¸ã®å¼•æ•°ã¯ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°ç”±æ¥ã®ã‚‚ã®ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "No rows were found in \"%s\"." -#~ msgstr "\"%s\"ã«è¡ŒãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" - -#~ msgid "syntax error: cannot back up" -#~ msgstr "構文エラー:ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“" - -#~ msgid "could not open file \"%s\" (log file %u, segment %u): %m" -#~ msgstr "ファイル\"%s\"(ログファイル%uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%u)をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#~ msgid "unable to read symbolic link %s: %m" -#~ msgstr "シンボリックリンク \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %m" - -#~ msgid "Sets the list of known custom variable classes." -#~ msgstr "既知ã®ã‚«ã‚¹ã‚¿ãƒ å¤‰æ•°ã‚¯ãƒ©ã‚¹ã®ãƒªã‚¹ãƒˆã‚’設定ã—ã¾ã™ã€‚" - -#~ msgid "subquery cannot have SELECT INTO" -#~ msgstr "副å•ã„åˆã‚ã›ã§ã¯ SELECT INTO を使用ã§ãã¾ã›ã‚“" - -#~ msgid "cannot use aggregate function in VALUES" -#~ msgstr "VALUESã§é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "subquery in FROM cannot have SELECT INTO" -#~ msgstr "FROMå¥ã®å‰¯å•ã„åˆã‚ã›ã§ã¯SELECT INTOを使用ã§ãã¾ã›ã‚“" - -#~ msgid "could not enable credential reception: %m" -#~ msgstr "資格証明ã®å—信を有効ã«ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" - -#~ msgid "standby_mode = '%s'" -#~ msgstr "standby_mode = '%s'" - -#~ msgid "Use ALTER AGGREGATE to rename aggregate functions." -#~ msgstr "集約関数ã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ALTER AGGREGATEを使用ã—ã¦ãã ã•ã„。" - -#~ msgid "recovery_target_xid = %u" -#~ msgstr "recovery_target_xid = %u" - -#~ msgid "contrecord is requested by %X/%X" -#~ msgstr "%X/%Xã§ã¯contrecordãŒå¿…è¦ã§ã™" - -#~ msgid "removing built-in function \"%s\"" -#~ msgstr "組ã¿è¾¼ã¿é–¢æ•°\"%s\"を削除ã—ã¦ã„ã¾ã™" - -#~ msgid "cannot use aggregate function in RETURNING" -#~ msgstr "RETURNINGã«ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid "must be superuser to drop text search templates" -#~ msgstr "テキスト検索テンプレートを削除ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "invalid contrecord length %u in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル%2$uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%3$uã€ã‚ªãƒ•セット%4$uã®contrecordã®é•·ã•%1$uãŒç„¡åйã§ã™" - -#~ msgid "could not obtain lock on relation with OID %u" -#~ msgstr "OID %u ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã«å¯¾ã™ã‚‹ãƒ­ãƒƒã‚¯ã‚’ç²å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#~ msgid "out-of-sequence timeline ID %u (after %u) in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル%3$uã€ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ%4$uã€ã‚ªãƒ•セット%5$uã®æ™‚系列ID %1$u(%2$uã®å¾Œ)ã¯é †åºã«å¾“ã£ã¦ã„ã¾ã›ã‚“" - -#~ msgid "must be superuser to comment on procedural language" -#~ msgstr "手続ã言語ã«ã‚³ãƒ¡ãƒ³ãƒˆã‚’ã¤ã‘ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with GROUP BY clause" -#~ msgstr "GROUP BYå¥ã§ã¯SELECT FOR UPDATE/SHAREを使用ã§ãã¾ã›ã‚“" - -#~ msgid "array must not contain null values" -#~ msgstr "é…列ã«ã¯NULL値をå«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" - -#~ msgid "cannot use aggregate in index predicate" -#~ msgstr "インデックスã®è¿°éƒ¨ã«é›†ç´„を使用ã§ãã¾ã›ã‚“" - -#~ msgid "replication connection authorized: user=%s host=%s port=%s" -#~ msgstr "レプリケーション接続ã®èªè¨¼å®Œäº†: ユーザ=%sã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹=%sã€ãƒãƒ¼ãƒˆç•ªå·=%s" - -#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with aggregate functions" -#~ msgstr "集約関数ã§ã¯SELECT FOR UPDATE/SHAREを使用ã§ãã¾ã›ã‚“" - -#~ msgid "index \"%s\" is not a b-tree" -#~ msgstr "インデックス \"%s\" ã¯btreeã§ã¯ã‚りã¾ã›ã‚“" - -#~ msgid "cannot use aggregate function in default expression" -#~ msgstr "デフォルトå¼ã«ã¯é›†ç´„関数を使用ã§ãã¾ã›ã‚“" - -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を出力ã—終了ã—ã¾ã™\n" - -#~ msgid "SELECT FOR UPDATE/SHARE cannot be used with foreign table \"%s\"" -#~ msgstr "SELECT FOR UPDATE/SHARE ã¯å¤–部テーブル \"%s\" ã¨ä¸€ç·’ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" - -#~ msgid "select() failed in logger process: %m" -#~ msgstr "ロガープロセスã§select()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" - -#~ msgid "constraints on foreign tables are not supported" -#~ msgstr "外部テーブルã¸ã®åˆ¶ç´„ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#~ msgid "SSL certificate revocation list file \"%s\" not found, skipping: %s" -#~ msgstr "SSL証明書失効リストファイル\"%s\"ãŒã‚りã¾ã›ã‚“。çœç•¥ã—ã¾ã™: %s" - -#~ msgid "window functions not allowed in GROUP BY clause" -#~ msgstr "GROUP BY å¥ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "pause_at_recovery_target = '%s'" -#~ msgstr "pause_at_recovery_target = '%s'" - -#~ msgid "incorrect total length in record at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®å…¨é•·ãŒä¸æ­£ã§ã™" - -#~ msgid "primary_conninfo = '%s'" -#~ msgstr "primary_conninfo = '%s'" - -#~ msgid "subquery in FROM cannot refer to other relations of same query level" -#~ msgstr "FROMå¥ã®å‰¯å•ã„åˆã‚ã›ã§ã¯ã€åŒä¸€å•ã„åˆã‚ã›ãƒ¬ãƒ™ãƒ«ã®ä»–ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã‚’å‚ç…§ã§ãã¾ã›ã‚“" - -#~ msgid "INSERT ... SELECT cannot specify INTO" -#~ msgstr "INSERT ... SELECTã§ã¯INTOを指定ã§ãã¾ã›ã‚“" - -#~ msgid "cannot use window function in transform expression" -#~ msgstr "変æ›å¼ã®ä¸­ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“" - -#~ msgid "syntax error; also virtual memory exhausted" -#~ msgstr "構文エラー:ã•らã«ä»®æƒ³ãƒ¡ãƒ¢ãƒªãƒ¼ã‚ªãƒ¼ãƒãƒ¼" - -#~ msgid "cannot use window function in function expression in FROM" -#~ msgstr "FROM å¥å†…ã®é–¢æ•°å¼ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "Cancelled on identification as a pivot, during write." -#~ msgstr "書ãè¾¼ã¿ã®éš›ã€ãƒ”ボットã¨ã—ã¦ã®è­˜åˆ¥å‡¦ç†ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" - -#~ msgid "cannot use window function in check constraint" -#~ msgstr "ãƒã‚§ãƒƒã‚¯åˆ¶ç´„ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "Cancelled on conflict out to old pivot %u." -#~ msgstr "ç«¶åˆã«ã‚ˆã‚Šã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã€å¤ã„ピボット %u ã«æˆ»ã‚Šã¾ã—ãŸ" - -#~ msgid "argument of %s must not contain window functions" -#~ msgstr "%s ã®å¼•æ•°ã«ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "%s: could not dissociate from controlling TTY: %s\n" -#~ msgstr "%s: 制御TTYã‹ã‚‰åˆ‡ã‚Šé›¢ã›ã¾ã›ã‚“ã§ã—ãŸ: %s\n" - -#~ msgid "Use ALTER FOREIGN TABLE instead." -#~ msgstr "代ã‚りã«ALTER FOREIGN TABLEを使用ã—ã¦ãã ã•ã„" - -#~ msgid "Make sure the root.crt file is present and readable." -#~ msgstr "root.crt ファイルãŒå­˜åœ¨ã—ã€ã‹ã¤èª­ã‚る状態ã«ãªã£ã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„" - -#~ msgid "index \"%s\" is not ready" -#~ msgstr "インデックス \"%s\" ã¯åˆ©ç”¨æº–å‚™ãŒã§ãã¦ã„ã¾ã›ã‚“" - -#~ msgid "%s (%x)" -#~ msgstr "%s (%x)" - -#~ msgid "WAL file is from different database system" -#~ msgstr "WAL ファイルã¯ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ç”±æ¥ã®ã‚‚ã®ã§ã™" - -#~ msgid "recovery_end_command = '%s'" -#~ msgstr "recovery_end_command = '%s'" - -#~ msgid "cannot use window function in rule WHERE condition" -#~ msgstr "ルール㮠WHERE å¥ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" - -#~ msgid "%s: could not open log file \"%s/%s\": %s\n" -#~ msgstr "%s: ログファイル \"%s/%s\" をオープンã§ãã¾ã›ã‚“: %s\n" - -#~ msgid "must be superuser to rename text search parsers" -#~ msgstr "テキスト検索パーサã®åå‰ã‚’変更ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid "EnumValuesCreate() can only set a single OID" -#~ msgstr "EnumValuesCreate() ã¯å˜ç‹¬ã® OID ã®ã¿ã‚’セットã§ãã¾ã™" - -#~ msgid "terminating all walsender processes to force cascaded standby(s) to update timeline and reconnect" -#~ msgstr "カスケードã•れãŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚’強制的ã«ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã‚’æ›´æ–°ã—å†æŽ¥ç¶šã•ã›ã‚‹ãŸã‚ã«ã™ã¹ã¦ã®WALé€ä¿¡å‡¦ç†ã‚’終了ã—ã¾ã™" - -#~ msgid "must be superuser to SET SCHEMA of %s" -#~ msgstr "%s ã® SET SCHEMA ã‚’ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "テーブル\"%s\"ã«ã¯è¤‡æ•°ã®\"%s\"ã¨ã„ã†åå‰ã®åˆ¶ç´„ãŒã‚りã¾ã™" -#~ msgid "%s already exists in schema \"%s\"" -#~ msgstr "%s ã¯ã™ã§ã«ã‚¹ã‚­ãƒ¼ãƒž \"%s\" 内ã«å­˜åœ¨ã—ã¾ã™" +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "ドメイン%sã«ã¯è¤‡æ•°ã®\"%s\"ã¨ã„ã†åå‰ã®åˆ¶ç´„ãŒã‚りã¾ã™" -#~ msgid "column name list not allowed in CREATE TABLE / AS EXECUTE" -#~ msgstr "CREATE TABLE / AS EXECUTEã§ã¯åˆ—åリストを使用ã§ãã¾ã›ã‚“" +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "パーティションテーブル \"%s\" ã‚’å‚ç…§ã™ã‚‹å¤–部キー㯠ONLY ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#~ msgid "streaming replication successfully connected to primary" -#~ msgstr "ストリーミングレプリケーションãŒãƒ—ライマリã«ç„¡äº‹æŽ¥ç¶šã§ãã¾ã—ãŸ" +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "プロシージャ番å·%dãŒä¸æ­£ã§ã™ã€‚1ã‹ã‚‰%dã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#~ msgid "subquery in WITH cannot have SELECT INTO" -#~ msgstr "WITH ã«ãŠã‘る副å•ã„åˆã‚ã›ã§ã¯ SELECT INTO を使用ã§ãã¾ã›ã‚“" +#~ msgid "hash procedure 1 must have one argument" +#~ msgstr "ãƒãƒƒã‚·ãƒ¥ãƒ—ロシージャ1ã¯1ã¤ã®å¼•æ•°ã‚’å–らãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#~ msgid "You need an unconditional ON INSERT DO INSTEAD rule or an INSTEAD OF INSERT trigger." -#~ msgstr "ç„¡æ¡ä»¶ã® ON INSERT DO INSTEAD ルールもã—ã㯠INSTEAD OF INSERT トリガーãŒå¿…è¦ã§ã™" +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "(%2$s,%3$s)用ã®ãƒ—ロシージャ番å·%1$dãŒè¤‡æ•°ã‚りã¾ã™" -#~ msgid "standby connections not allowed because wal_level=minimal" -#~ msgstr "wal_level=minimal ãªã®ã§ã€ã‚¹ã‚¿ãƒ³ãƒã‚¤æŽ¥ç¶šã¯ã§ãã¾ã›ã‚“" +#~ msgid "operator procedure must be specified" +#~ msgstr "演算å­ã®ãƒ—ロシージャを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#~ msgid "terminating walsender process to force cascaded standby to update timeline and reconnect" -#~ msgstr "カスケードã•れãŸã‚¹ã‚¿ãƒ³ãƒã‚¤ã‚’強制的ã«ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã‚’æ›´æ–°ã—å†æŽ¥ç¶šã•ã›ã‚‹ãŸã‚ã«ã€WALé€ä¿¡ãƒ—ロセスを終了ã—ã¦ã„ã¾ã™" +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "%sã¯é–¢æ•°ã¾ãŸã¯ãƒžãƒ«ãƒã‚³ãƒžãƒ³ãƒ‰æ–‡å­—列ã‹ã‚‰å®Ÿè¡Œã§ãã¾ã›ã‚“" -#~ msgid "missing or erroneous pg_hba.conf file" -#~ msgstr "pg_hba.confファイルãŒå­˜åœ¨ã—ãªã„ã€ã¾ãŸã¯ã€pg_hba.confファイルã®ã‚¨ãƒ©ãƒ¼" +#~ msgid "no such savepoint" +#~ msgstr "ãã®ã‚ˆã†ãªã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã¯ã‚りã¾ã›ã‚“" -#~ msgid "WAL file database system identifier is %s, pg_control database system identifier is %s." -#~ msgstr "WAL ファイルã«ãŠã‘るデータベースシステムã®è­˜åˆ¥å­ã¯ %s ã§ã€pg_control ã«ãŠã‘るデータベースシステムã®è­˜åˆ¥å­ã¯ %s ã§ã™ã€‚" +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#~ msgid "Cancelled on conflict out to pivot %u, during read." -#~ msgstr "読ã¿è¾¼ã¿ã®éš›ã€ãƒ”ボット %u ã¸ã®ç«¶åˆã«ã‚ˆã‚Šã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" +#~ msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "データベースクラスタ㯠XLOG_SEG_SIZE %d ã§åˆæœŸåŒ–ã•れã¾ã—ãŸãŒã€ã‚µãƒ¼ãƒã¯ XLOG_SEG_SIZE %d ã§ã‚³ãƒ³ãƒ‘イルã•れã¦ã„ã¾ã™ã€‚" -#~ msgid "large object %u was not opened for writing" -#~ msgstr "ラージオブジェクト%uã¯æ›¸ãè¾¼ã¿ç”¨ã«é–‹ã‹ã‚Œã¦ã„ã¾ã›ã‚“" +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "%X/%Xã«ã‚ã‚‹å‰ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ä½¿ç”¨ã—ã¾ã™" -#~ msgid "Cancelled on identification as a pivot, during conflict in checking." -#~ msgstr "ãƒã‚§ãƒƒã‚¯ã®éš›ã«ç«¶åˆãŒç™ºç”Ÿã—ã€ãƒ”ボットã¨ã—ã¦ã®è­˜åˆ¥å‡¦ç†ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "制御ファイル内ã®äºŒç•ªç›®ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã¸ã®ãƒªãƒ³ã‚¯ãŒä¸æ­£ã§ã™" -#~ msgid "You need an unconditional ON DELETE DO INSTEAD rule or an INSTEAD OF DELETE trigger." -#~ msgstr "ç„¡æ¡ä»¶ã® ON DELETE DO INSTEAD ルールもã—ã㯠INSTEAD OF DELETE トリガーãŒå¿…è¦ã§ã™" +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "二番目ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰ãŒä¸æ­£ã§ã™" -#~ msgid "Cancelled on identification as a pivot, with conflict out to old committed transaction %u." -#~ msgstr "ç«¶åˆã«ã‚ˆã‚Šãƒ”ボットã¨ã—ã¦ã®è­˜åˆ¥å‡¦ç†ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã€å¤ã„コミット済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ %u ã«æˆ»ã‚Šã¾ã—ãŸ" +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "セカンダリãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£IDãŒä¸æ­£ã§ã™" -#~ msgid "Not enough memory for reassigning the prepared transaction's locks." -#~ msgstr "準備ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ãƒ­ãƒƒã‚¯ã‚’å†å‰²ã‚Šå½“ã¦ã™ã‚‹ã«ã¯ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™ã€‚" +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "二番目ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰å†…ã®xl_infoãŒä¸æ­£ã§ã™" -#~ msgid "Cancelled on identification as a pivot, during conflict out checking." -#~ msgstr "ç«¶åˆãƒã‚§ãƒƒã‚¯ä¸­ã«ãƒ”ボットã¨ã—ã¦ã®è­˜åˆ¥å‡¦ç†ãŒã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "二番目ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãƒ¬ã‚³ãƒ¼ãƒ‰é•·ãŒä¸æ­£ã§ã™" -#~ msgid "cannot use subquery in parameter default value" -#~ msgstr "パラメータã®ãƒ‡ãƒ•ォルト値ã¨ã—ã¦å‰¯å•ã„åˆã‚ã›ã‚’使用ã§ãã¾ã›ã‚“" +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "WAL ファイルã¯ç•°ãªã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚·ã‚¹ãƒ†ãƒ ç”±æ¥ã®ã‚‚ã®ã§ã™: ページヘッダーã®XLOG_SEG_SIZEãŒæ­£ã—ãã‚りã¾ã›ã‚“" -#~ msgid "poll() failed in statistics collector: %m" -#~ msgstr "統計情報コレクタã§poll()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %m" +#~ msgid " in schema %s" +#~ msgstr "スキーマ%sã«ãŠã„ã¦" -#~ msgid "inconsistent use of year %04d and \"BC\"" -#~ msgstr "å¹´%04dã¨\"BC\"ã®ä½¿ç”¨ã«ã¯ä¸€è²«æ€§ãŒã‚りã¾ã›ã‚“" +#~ msgid "%s in publication %s" +#~ msgstr "パブリケーション%2$sã®%1$s" -#~ msgid "unrecognized \"log_destination\" key word: \"%s\"" -#~ msgstr "\"log_destination\"キーワードãŒä¸æ˜Žã§ã™: \"%s\"" +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "\"%s\"ã¯ã™ã§ã«åž‹%sã®å±žæ€§ã§ã™" -#~ msgid "VALUES must not contain table references" -#~ msgstr "VALUESã«ã¯ãƒ†ãƒ¼ãƒ–ルå‚ç…§ã‚’å«ã‚ã¦ã¯ã„ã‘ã¾ã›ã‚“" +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "関数 \"%s\" ã¯é›†ç´„関数ã§ã™" -#~ msgid "cannot reference temporary table from permanent table constraint" -#~ msgstr "永続テーブルã®åˆ¶ç´„ã‹ã‚‰ä¸€æ™‚テーブルをå‚ç…§ã§ãã¾ã›ã‚“" +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "関数 \"%s\" ã¯é›†ç´„関数ã§ã¯ã‚りã¾ã›ã‚“" -#~ msgid "argument number is out of range" -#~ msgstr "å¼•æ•°ã®æ•°ãŒç¯„囲を超ãˆã¦ã„ã¾ã™" +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "関数 \"%s\" ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã§ã¯ã‚りã¾ã›ã‚“" -#~ msgid "could not create log file \"%s\": %m" -#~ msgstr "ログファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "ファイルを入出力対象ã¨ã—ãŸCOPYを行ã†ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "xrecoff \"%X\" is out of valid range, 0..%X" -#~ msgstr "xrecoff \"%X\"ã¯æœ‰åŠ¹ç¯„å›²0ã‹ã‚‰%Xã¾ã§ã®é–“ã«ã‚りã¾ã›ã‚“" +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "外部テーブル \"%s\" ã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“" -#~ msgid "index \"%s\" needs VACUUM or REINDEX to finish crash recovery" -#~ msgstr "クラッシュリカãƒãƒªã‚’完了ã™ã‚‹ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹\"%s\"ã‚’VACUUMã¾ãŸã¯REINDEXã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "挿入タプルã®å¤–部テーブルã¸ã®é…é€ã¯ã§ãã¾ã›ã‚“" -#~ msgid "Incomplete insertion detected during crash replay." -#~ msgstr "クラッシュリカãƒãƒªä¸­ã«ä¸å®Œå…¨ãªæŒ¿å…¥ã‚’検知ã—ã¾ã—ãŸ" +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "䏿˜Žãªé–¢æ•°å±žæ€§\"%s\"ã¯ç„¡è¦–ã—ã¾ã—ãŸ" -#~ msgid "Lines should have the format parameter = 'value'." -#~ msgstr "行ã¯ã€parameter = 'value'ã¨ã„ã†æ›¸å¼ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" +#~ msgid "cast function must not be an aggregate function" +#~ msgstr "キャスト関数ã¯é›†ç´„関数ã§ã¯ã„ã‘ã¾ã›ã‚“" -#~ msgid "Use SELECT ... UNION ALL ... instead." -#~ msgstr "代ã‚りã«SELECT ... UNION ALL ... を使用ã—ã¦ãã ã•ã„" +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "変æ›é–¢æ•°ã¯é›†ç´„関数ã§ã¯ã„ã‘ã¾ã›ã‚“" -#~ msgid "invalid list syntax for parameter \"datestyle\"" -#~ msgstr "パラメータ\"datestyle\"用ã®ãƒªã‚¹ãƒˆæ§‹æ–‡ãŒç„¡åйã§ã™" +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "列\"%s\"ãŒãƒ‘ーティションキーã«2回以上出ç¾ã—ã¦ã„ã¾ã™" -#~ msgid "WAL sender sleep time between WAL replications." -#~ msgstr "WAL レプリケーションã®é–“ã€WAL sender ãŒå¾…機ã™ã‚‹æ™‚é–“ã§ã™ã€‚" +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "周回å•題を回é¿ã™ã‚‹ãŸã‚ã™ãã«ã‚ªãƒ¼ãƒ—ンã—ã¦ã„るトランザクションをクローズã—ã¦ãã ã•ã„。" -#~ msgid "SELECT FOR UPDATE/SHARE cannot be applied to NEW or OLD" -#~ msgstr "SELECT FOR UPDATE/SHAREã‚’NEWã‚„OLDã«ä½¿ç”¨ã§ãã¾ã›ã‚“" +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "集約%uã®çµåˆé–¢æ•°ã¯STRICT宣言ã•れã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "cannot use window function in parameter default value" -#~ msgstr "パラメータã®ãƒ‡ãƒ•ォルト値ã¨ã—ã¦ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING 㯠UNBOUNDED ãªã—ã®å ´åˆã®ã¿ã®ã‚µãƒãƒ¼ãƒˆã§ã™" -#~ msgid "cannot drop \"%s\" because it is being used by active queries in this session" -#~ msgstr "ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§å®Ÿè¡Œä¸­ã®ã‚¯ã‚¨ãƒªãƒ¼ã§ä½¿ç”¨ã•れã¦ã„ã‚‹ãŸã‚ \"%s\" を削除ã§ãã¾ã›ã‚“" +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING 㯠UNBOUNDED ãªã—ã®å ´åˆã®ã¿ã®ã‚µãƒãƒ¼ãƒˆã§ã™" -#~ msgid "If this parameter is set, the server will automatically run in the background and any controlling terminals are dissociated." -#~ msgstr "ã“ã®ã‚ªãƒ—ションを設定ã™ã‚‹ã¨ã€ã‚µãƒ¼ãƒã¯è‡ªå‹•çš„ã«ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ã§èµ·å‹•ã—ã€åˆ¶å¾¡ç«¯æœ«ã‚’切り離ã—ã¾ã™ã€‚" +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "クライアントãŒSCRAMãƒãƒ£ãƒãƒ«å‰²ã‚Šå½“ã¦ã‚’è¦æ±‚ã—ã¦ã„ã¾ã™ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#~ msgid "parameter \"lc_collate\" parameter must be specified" -#~ msgstr "\"lc_collate\" パラメータを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "サーãƒã‚µã‚¤ãƒ‰ã®lo_import()を使用ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "cannot use window function in VALUES" -#~ msgstr "VALUES 内ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "libpqã§æä¾›ã•れるlo_import()ã¯èª°ã§ã‚‚使用ã§ãã¾ã™" -#~ msgid "invalid interval value for time zone: month not allowed" -#~ msgstr "時間帯ã®å†…部値ãŒç„¡åйã§ã™: 月ã¯è¨±ã•れã¾ã›ã‚“" +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "サーãƒã‚µã‚¤ãƒ‰ã®lo_export()を使用ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "Runs the server silently." -#~ msgstr "サーãƒã‚’出力ãªã—ã§å®Ÿè¡Œã—ã¾ã™ã€‚" +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "libpqã§æä¾›ã•れるクライアントサイドã®lo_export()ã¯èª°ã§ã‚‚使用ã§ãã¾ã™" -#~ msgid "permission denied to drop foreign-data wrapper \"%s\"" -#~ msgstr "外部データラッパー \"%s\" を削除ã™ã‚‹æ¨©é™ãŒã‚りã¾ã›ã‚“" +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "ON CONFLICT節ã¯ãƒ‘ーティションテーブルã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#~ msgid "uncataloged table %s" -#~ msgstr "カタログã«ãªã„テーブル%s" +#~ msgid "primary key constraints are not supported on partitioned tables" +#~ msgstr "パーティションテーブルã§ã¯ä¸»ã‚­ãƒ¼åˆ¶ç´„ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#~ msgid "index %u/%u/%u needs VACUUM FULL or REINDEX to finish crash recovery" -#~ msgstr "クラッシュリカãƒãƒªã‚’完了ã™ã‚‹ã«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹%u/%u/%uã‚’VACUUM FULLã¾ãŸã¯REINDEXã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "パーティションテーブルã§ã¯å¤–部キー制約ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#~ msgid "record with zero length at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã‚µã‚¤ã‚ºã¯0ã§ã™" +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "アーカイブステータスディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#~ msgid "foreign key constraint \"%s\" of relation \"%s\" does not exist" -#~ msgstr "リレーション \"%2$s\" ã®å¤–部キー制約 \"%1$s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s: max_wal_sendersã¯max_connectionsよりå°ã•ããªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#~ msgid "cannot use window function in UPDATE" -#~ msgstr "UPDATE 内ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "データディレクトリ\"%s\"ã¯ã‚°ãƒ«ãƒ¼ãƒ—ã¾ãŸã¯ç¬¬ä¸‰è€…ã‹ã‚‰ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ã§ã™" -#~ msgid "archive_cleanup_command = '%s'" -#~ msgstr "archive_cleanup_command = '%s'" +#~ msgid "worker process" +#~ msgstr "ワーカプロセス" -#~ msgid "invalid resource manager ID %u at %X/%X" -#~ msgstr "%2$X/%3$Xã®ãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ID %1$uãŒç„¡åйã§ã™" +#~ msgid "built-in type %u not found" +#~ msgstr "組ã¿è¾¼ã¿åž‹%uãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#~ msgid "restore_command = '%s'" -#~ msgstr "restore_command = '%s'" +#~ msgid "This can be caused by having a publisher with a higher PostgreSQL major version than the subscriber." +#~ msgstr "ã“れã¯ç™ºè¡Œã‚µãƒ¼ãƒã®PostgreSQLメジャーãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒè³¼èª­ã‚µãƒ¼ãƒã‚ˆã‚Šã‚‚æ–°ã—ã„å ´åˆã«èµ·ãã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚" -#~ msgid "Use ALTER AGGREGATE to change owner of aggregate functions." -#~ msgstr "é›†ç´„é–¢æ•°ã®æ‰€æœ‰è€…を変更ã™ã‚‹ã«ã¯ALTER AGGREGATEを使用ã—ã¦ãã ã•ã„。" +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "è«–ç†ãƒ¬ãƒ—リケーションã§å¿…è¦ã¨ãªã‚‹ãƒ‡ãƒ¼ã‚¿åž‹\"%s.%s\"ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#~ msgid "SSPI error %x" -#~ msgstr "SSPIエラーã§ã™: %x" +#~ msgid "logical replication could not find row for delete in replication target relation \"%s\"" +#~ msgstr "è«–ç†ãƒ¬ãƒ—リケーションã¯ãƒ¬ãƒ—リケーション対象リレーション\"%s\"ã§å‰Šé™¤å¯¾è±¡è¡Œã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "invalid record offset at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚ªãƒ•セットãŒç„¡åйã§ã™" +#~ msgid "memory for serializable conflict tracking is nearly exhausted" +#~ msgstr "シリアライズå¯èƒ½ãªç«¶åˆè¿½è·¡ã®ãŸã‚ã®ãƒ¡ãƒ¢ãƒªãŒã‚‚ã†ã™ã一æ¯ã«ãªã‚Šã¾ã™" -#~ msgid "could not access root certificate file \"%s\": %m" -#~ msgstr "ルート証明ファイル \"%s\" ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" +#~ msgid "There might be an idle transaction or a forgotten prepared transaction causing this." +#~ msgstr "ã“ã®åŽŸå› ã¨ãªã£ã¦ã„ã‚‹ã€ã‚¢ã‚¤ãƒ‰ãƒ«çŠ¶æ…‹ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¾ãŸã¯ä½¿ã‚れãªã„ã¾ã¾ã®æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“" -#~ msgid "cannot use window function in RETURNING" -#~ msgstr "RETURNING ã§ã¯ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦é–¢æ•°ã‚’使用ã§ãã¾ã›ã‚“" +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "テーブル空間ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %m" -#~ msgid "Certificates will not be checked against revocation list." -#~ msgstr "証明書ã¯å¤±åŠ¹ãƒªã‚¹ãƒˆã«å¯¾ã—ã¦æ¤œæŸ»ã•れã¾ã›ã‚“。" +#~ msgid "must be superuser to get file information" +#~ msgstr "ファイル情報をå–å¾—ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "invalid info bits %04X in log file %u, segment %u, offset %u" -#~ msgstr "ログファイル %2$u ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ %3$uã€ã‚ªãƒ•セット %4$u ã®æƒ…報ビット %1$04X ã¯ç„¡åйã§ã™" +#~ msgid "must be superuser to get directory listings" +#~ msgstr "ディレクトリ一覧をå–å¾—ã™ã‚‹ã«ã¯ã‚¹ãƒ¼ãƒ‘ーユーザã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™" -#~ msgid "%s: could not open file \"%s\": %s\n" -#~ msgstr "%s: ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +#~ msgid "Sets the maximum number of tuples to be sorted using replacement selection." +#~ msgstr "é¸æŠžã‚½ãƒ¼ãƒˆã‚’ä½¿ç”¨ã™ã‚‹æœ€å¤§ã®ã‚¿ãƒ—ル数。" -#~ msgid "incorrect hole size in record at %X/%X" -#~ msgstr "%X/%Xã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã®ãƒ›ãƒ¼ãƒ«ã‚µã‚¤ã‚ºãŒä¸æ­£ã§ã™" +#~ msgid "When more tuples than this are present, quicksort will be used." +#~ msgstr "ã“ã‚Œä»¥ä¸Šã®æ•°ã®ã‚¿ãƒ—ルãŒã‚ã‚‹å ´åˆã«ã¯ã€ã‚¯ã‚¤ãƒƒã‚¯ã‚½ãƒ¼ãƒˆã‚’使ã„ã¾ã™ã€‚" -#~ msgid "\"%s\" is not a table, view, or composite type" -#~ msgstr "\"%s\"ã¯ãƒ†ãƒ¼ãƒ–ルã€ãƒ“ューã€è¤‡åˆåž‹ã®ã„ãšã‚Œã§ã‚‚ã‚りã¾ã›ã‚“" +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "BufFile \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ" diff --git a/src/backend/po/ko.po b/src/backend/po/ko.po index c5225ffa19c..cdb913caa9d 100644 --- a/src/backend/po/ko.po +++ b/src/backend/po/ko.po @@ -3,89 +3,80 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: postgres (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-02 11:23+0900\n" -"PO-Revision-Date: 2017-03-02 11:28:26+0900\n" +"POT-Creation-Date: 2018-09-10 09:25+0900\n" +"PO-Revision-Date: 2018-09-11 15:15+0900\n" "Last-Translator: Ioseph Kim \n" -"Language-Team: Korean Team \n" +"Language-Team: Korean Team \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../common/config_info.c:131 ../common/config_info.c:139 -#: ../common/config_info.c:147 ../common/config_info.c:155 -#: ../common/config_info.c:163 ../common/config_info.c:171 -#: ../common/config_info.c:179 ../common/config_info.c:187 -#: ../common/config_info.c:195 +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 msgid "not recorded" msgstr "기ë¡ë˜ì–´ 있지 않ìŒ" -#: ../common/controldata_utils.c:52 commands/copy.c:2833 -#: commands/extension.c:3141 utils/adt/genfile.c:134 +#: ../common/controldata_utils.c:58 commands/copy.c:3146 +#: commands/extension.c:3330 utils/adt/genfile.c:151 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "\"%s\" íŒŒì¼ ì¼ê¸° 모드로 열기 실패: %m" -#: ../common/controldata_utils.c:56 +#: ../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì½ê¸° 모드로 열기 실패: %s\n" -#: ../common/controldata_utils.c:66 access/transam/timeline.c:346 -#: access/transam/xlog.c:3220 access/transam/xlog.c:10423 -#: access/transam/xlog.c:10436 access/transam/xlog.c:10828 -#: access/transam/xlog.c:10871 access/transam/xlog.c:10910 -#: access/transam/xlog.c:10953 access/transam/xlogfuncs.c:665 -#: access/transam/xlogfuncs.c:684 commands/extension.c:3151 -#: replication/logical/origin.c:665 replication/logical/origin.c:695 -#: replication/logical/reorderbuffer.c:3099 replication/walsender.c:499 -#: storage/file/copydir.c:176 utils/adt/genfile.c:151 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 +#: access/transam/xlog.c:3433 access/transam/xlog.c:10926 +#: access/transam/xlog.c:10939 access/transam/xlog.c:11364 +#: access/transam/xlog.c:11444 access/transam/xlog.c:11483 +#: access/transam/xlog.c:11526 access/transam/xlogfuncs.c:658 +#: access/transam/xlogfuncs.c:677 commands/extension.c:3340 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3294 replication/walsender.c:510 +#: storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format msgid "could not read file \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: ../common/controldata_utils.c:69 +#: ../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 없습니다: %s\n" #: ../common/controldata_utils.c:86 -msgid "calculated CRC checksum does not match value stored in file" -msgstr "ê³„ì‚°ëœ CRC ì²´í¬ì„¬ ê°’ì´ íŒŒì¼ì— ì €ìž¥ëœ ê°’ê³¼ 다름" +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %d ì½ìŒ, ì „ì²´ %d" -#: ../common/controldata_utils.c:88 +#: ../common/controldata_utils.c:90 #, c-format -msgid "" -"WARNING: Calculated CRC checksum does not match value stored in file.\n" -"Either the file is corrupt, or it has a different layout than this program\n" -"is expecting. The results below are untrustworthy.\n" -"\n" -msgstr "" -"경고: ê³„ì‚°ëœ CRC ì²´í¬ì„¬ê°’ì´ íŒŒì¼ì— 있는 ê°’ê³¼ 틀립니다.\n" -"ì´ ê²½ìš°ëŠ” 파ì¼ì´ ì†ìƒë˜ì—ˆê±°ë‚˜, ì´ í”„ë¡œê·¸ëž¨ê³¼ 컨트롤 파ì¼ì˜ ë²„ì „ì´ í‹€ë¦°\n" -"경우입니다. ê²°ê³¼ê°’ë“¤ì€ ë¯¿ì§€ 못할 ê°’ë“¤ì´ ì¶œë ¥ë  ìˆ˜ 있습니다.\n" -"\n" +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %d ì½ìŒ, ì „ì²´ %d\n" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "ë°”ì´íЏ 순서 불ì¼ì¹˜" -#: ../common/controldata_utils.c:99 +#: ../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, " -"and\n" +"used by this program. In that case the results below would be incorrect, and\n" "the PostgreSQL installation would be incompatible with this data directory.\n" msgstr "" "경고: ë°”ì´íЏ 순서가 ì¼ì¹˜í•˜ì§€ 않습니다.\n" "pg_control 파ì¼ì„ 저장하는 ë° ì‚¬ìš©ëœ ë°”ì´íЏ 순서는 \n" -"ì´ í”„ë¡œê·¸ëž¨ì—서 사용하는 순서와 ì¼ì¹˜í•´ì•¼ 합니다. ì´ ê²½ìš° 아래 결과는 올바르" -"ì§€ 않으며\n" +"ì´ í”„ë¡œê·¸ëž¨ì—서 사용하는 순서와 ì¼ì¹˜í•´ì•¼ 합니다. ì´ ê²½ìš° 아래 결과는 올바르지 않으며\n" "ì´ ë°ì´í„° ë””ë ‰í„°ë¦¬ì— PostgreSQLì„ ì„¤ì¹˜í•  수 없습니다.\n" #: ../common/exec.c:127 ../common/exec.c:241 ../common/exec.c:284 @@ -126,7 +117,9 @@ msgstr "pclose 실패: %s" #: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 #: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 -#: ../port/path.c:670 ../port/path.c:687 +#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 +#: utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 +#: utils/misc/ps_status.c:217 #, c-format msgid "out of memory\n" msgstr "메모리 부족\n" @@ -136,6 +129,37 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 중복할 수 ì—†ìŒ (ë‚´ë¶€ 오류)\n" +#: ../common/file_utils.c:82 ../common/file_utils.c:186 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ ìƒíƒœ 정보를 ì½ì„ 수 없습니다: %s\n" + +#: ../common/file_utils.c:162 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" + +#: ../common/file_utils.c:198 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" + +#: ../common/file_utils.c:231 ../common/file_utils.c:291 +#: ../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" + +#: ../common/file_utils.c:304 ../common/file_utils.c:376 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: \"%s\" íŒŒì¼ fsync 실패: %s\n" + +#: ../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" + #: ../common/pgfnames.c:45 #, c-format msgid "could not open directory \"%s\": %s\n" @@ -152,41 +176,42 @@ msgid "could not close directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" #: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1262 -#: access/transam/xlog.c:6108 lib/stringinfo.c:258 libpq/auth.c:850 -#: libpq/auth.c:1213 libpq/auth.c:1281 libpq/auth.c:1797 -#: postmaster/bgworker.c:289 postmaster/bgworker.c:796 -#: postmaster/postmaster.c:2335 postmaster/postmaster.c:2366 -#: postmaster/postmaster.c:3899 postmaster/postmaster.c:4589 -#: postmaster/postmaster.c:4664 postmaster/postmaster.c:5339 -#: postmaster/postmaster.c:5603 -#: replication/libpqwalreceiver/libpqwalreceiver.c:143 -#: replication/logical/logical.c:168 storage/buffer/localbuf.c:436 -#: storage/file/fd.c:736 storage/file/fd.c:1164 storage/file/fd.c:1282 -#: storage/file/fd.c:1993 storage/ipc/procarray.c:1061 -#: storage/ipc/procarray.c:1547 storage/ipc/procarray.c:1554 -#: storage/ipc/procarray.c:1968 storage/ipc/procarray.c:2571 -#: utils/adt/formatting.c:1522 utils/adt/formatting.c:1642 -#: utils/adt/formatting.c:1763 utils/adt/pg_locale.c:463 -#: utils/adt/pg_locale.c:647 utils/adt/regexp.c:219 utils/adt/varlena.c:4440 -#: utils/adt/varlena.c:4461 utils/fmgr/dfmgr.c:216 utils/hash/dynahash.c:429 -#: utils/hash/dynahash.c:535 utils/hash/dynahash.c:1047 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3888 utils/misc/guc.c:3904 -#: utils/misc/guc.c:3917 utils/misc/guc.c:6863 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:509 utils/mmgr/mcxt.c:767 utils/mmgr/mcxt.c:802 -#: utils/mmgr/mcxt.c:839 utils/mmgr/mcxt.c:876 utils/mmgr/mcxt.c:910 -#: utils/mmgr/mcxt.c:939 utils/mmgr/mcxt.c:973 utils/mmgr/mcxt.c:1055 -#: utils/mmgr/mcxt.c:1089 utils/mmgr/mcxt.c:1138 +#: ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6475 +#: lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 +#: libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2390 +#: postmaster/postmaster.c:2412 postmaster/postmaster.c:3979 +#: postmaster/postmaster.c:4687 postmaster/postmaster.c:4762 +#: postmaster/postmaster.c:5454 postmaster/postmaster.c:5791 +#: replication/libpqwalreceiver/libpqwalreceiver.c:260 +#: replication/logical/logical.c:174 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:781 storage/file/fd.c:1219 storage/file/fd.c:1380 +#: storage/file/fd.c:2286 storage/ipc/procarray.c:1055 +#: storage/ipc/procarray.c:1543 storage/ipc/procarray.c:1550 +#: storage/ipc/procarray.c:1965 storage/ipc/procarray.c:2589 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 +#: utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 +#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4230 utils/misc/guc.c:4246 utils/misc/guc.c:4259 +#: utils/misc/guc.c:7234 utils/misc/tzparser.c:468 utils/mmgr/aset.c:482 +#: utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 utils/mmgr/generation.c:249 +#: utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 +#: utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 utils/mmgr/mcxt.c:975 +#: utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 +#: utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format msgid "out of memory" msgstr "메모리 부족" -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "ìž˜ëª»ëœ í¬í¬ ì´ë¦„" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "유효한 í¬í¬ ì´ë¦„ì€ \"main\", \"fsm\" ë° \"vm\"입니다." @@ -236,71 +261,70 @@ msgstr "\"%s\" 파ì¼ì´ë‚˜ 디렉터리 ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %s\n" msgid "could not remove file or directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 삭제할 수 ì—†ìŒ: %s\n" -#: ../common/username.c:45 +# # nonun 부분 begin +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "비밀번호가 너무 ê¹ë‹ˆë‹¤." + +#: ../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "%ld UID를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: ../common/username.c:47 libpq/auth.c:1744 +#: ../common/username.c:45 libpq/auth.c:2038 msgid "user does not exist" msgstr "ì‚¬ìš©ìž ì—†ìŒ" -#: ../common/username.c:62 +#: ../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ì‚¬ìš©ìž ì´ë¦„ 찾기 실패: 오류 코드 %lu" -#: ../common/wait_error.c:47 +#: ../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: ../common/wait_error.c:51 +#: ../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "해당 명령어 ì—†ìŒ" -#: ../common/wait_error.c:56 +#: ../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "하위 í”„ë¡œê·¸ëž¨ì€ %d 코드로 마쳤습니다" -#: ../common/wait_error.c:63 +#: ../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "0x%X 예외처리로 하위 프로세스가 종료ë˜ì—ˆìŠµë‹ˆë‹¤" -#: ../common/wait_error.c:73 +#: ../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "%s 시그ë„ì´ ê°ì§€ë˜ì–´ 하위 프로세스가 종료ë˜ì—ˆìŠµë‹ˆë‹¤" -#: ../common/wait_error.c:77 +#: ../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "하위 í”„ë¡œê·¸ëž¨ì€ %d ì‹ í˜¸ì— ì˜í•´ì„œ 종료ë˜ì—ˆìŠµë‹ˆë‹¤" -#: ../common/wait_error.c:82 +#: ../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "하위 프로그램 í”„ë¡œê·¸ëž¨ì€ ì˜ˆìƒì¹˜ 못한 %d ìƒíƒœê°’으로 종료ë˜ì—ˆìŠµë‹ˆë‹¤" -#: ../port/chklocale.c:293 +#: ../port/chklocale.c:288 #, c-format msgid "could not determine encoding for codeset \"%s\"" msgstr "\"%s\" 코드 세트 í™˜ê²½ì— ì‚¬ìš©í•  ì¸ì½”ë”©ì„ ê²°ì •í•  수 없습니다" -#: ../port/chklocale.c:294 ../port/chklocale.c:423 -#: postmaster/postmaster.c:4868 -#, c-format -msgid "Please report this to ." -msgstr "ì´ ë‚´ìš©ì„ ì£¼ì†Œë¡œ 보고하십시오." - -#: ../port/chklocale.c:415 ../port/chklocale.c:421 +#: ../port/chklocale.c:409 ../port/chklocale.c:415 #, c-format msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" -msgstr "" -"\"%s\" ë¡œì¼€ì¼ í™˜ê²½ì—서 사용할 ì¸ì½”ë”©ì„ ê²°ì •í•  수 없습니다. 코드 세트: \"%s\"" +msgstr "\"%s\" ë¡œì¼€ì¼ í™˜ê²½ì—서 사용할 ì¸ì½”ë”©ì„ ê²°ì •í•  수 없습니다. 코드 세트: \"%s\"" #: ../port/dirmod.c:218 #, c-format @@ -322,32 +346,28 @@ msgstr "\"%s\" 파ì¼ì˜ ì •ì…˜ì„ êµ¬í•  수 ì—†ìŒ: %s" msgid "could not get junction for \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì˜ ì •ì…˜ì„ êµ¬í•  수 ì—†ìŒ: %s\n" -#: ../port/open.c:112 +#: ../port/open.c:111 #, c-format msgid "could not open file \"%s\": %s" msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s" -#: ../port/open.c:113 +#: ../port/open.c:112 msgid "lock violation" msgstr "잠금 위반" -#: ../port/open.c:113 +#: ../port/open.c:112 msgid "sharing violation" msgstr "공유 위반" -#: ../port/open.c:114 +#: ../port/open.c:113 #, c-format msgid "Continuing to retry for 30 seconds." msgstr "30ì´ˆ ë™ì•ˆ 계ì†í•´ì„œ 다시 시ë„합니다." -#: ../port/open.c:115 +#: ../port/open.c:114 #, c-format -msgid "" -"You might have antivirus, backup, or similar software interfering with the " -"database system." -msgstr "" -"ë°”ì´ëŸ¬ìФ 백신 프로그램, 백업 ë˜ëŠ” 유사한 소프트웨어가 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì„ " -"ë°©í•´í•  수 있습니다." +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "ë°”ì´ëŸ¬ìФ 백신 프로그램, 백업 ë˜ëŠ” 유사한 소프트웨어가 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì„ ë°©í•´í•  수 있습니다." #: ../port/path.c:654 #, c-format @@ -359,175 +379,209 @@ msgstr "현재 작업 디렉터리를 알 수 ì—†ìŒ: %s\n" msgid "unrecognized error %d" msgstr "알 수 없는 오류 %d" -#: ../port/win32security.c:68 -#, c-format -msgid "could not open process token: error code %lu\n" -msgstr "프로세스 토í°ì„ ì—´ 수 ì—†ìŒ: 오류 코드 %lu\n" - -#: ../port/win32security.c:89 +#: ../port/win32security.c:62 #, c-format msgid "could not get SID for Administrators group: error code %lu\n" msgstr "Administrators ê·¸ë£¹ì˜ SID를 가져올 수 ì—†ìŒ: 오류 코드 %lu\n" -#: ../port/win32security.c:99 +#: ../port/win32security.c:72 #, c-format msgid "could not get SID for PowerUsers group: error code %lu\n" msgstr "PowerUsers ê·¸ë£¹ì˜ SID를 가져올 수 ì—†ìŒ: 오류 코드 %lu\n" -#: access/brin/brin.c:810 +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "í† í° ë§´ë²„ì‰½ ì ‘ê·¼ì„ í™•ì¸ í•  수 ì—†ìŒ: 오류 코드 %lu\n" + +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "\"%s\" ì¸ë±ìФì—서 BRIN 범위 요약 ìš”ì²­ì´ ê¸°ë¡ë˜ì§€ 못함, 해당 페ì´ì§€: %u" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 +#: access/transam/xlog.c:10338 access/transam/xlog.c:10865 +#: access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 +#: access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 +#: access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 +#: access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "복구 작업 ì§„í–‰ 중" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN 제어 함수는 복구 작업 중ì—는 실행 ë  ìˆ˜ ì—†ìŒ" + +#: access/brin/brin.c:886 access/brin/brin.c:963 +#, c-format +msgid "block number out of range: %s" +msgstr "ë¸”ë¡ ë²ˆí˜¸ê°€ 범위를 벗어남: %s" + +#: access/brin/brin.c:909 access/brin/brin.c:986 #, c-format msgid "\"%s\" is not a BRIN index" -msgstr "\"%s\" ê°ì²´ëŠ” BRIN ì¸ë±ìŠ¤ê°€ 아닙니다" +msgstr "\"%s\" 개체는 BRIN ì¸ë±ìŠ¤ê°€ 아닙니다" -#: access/brin/brin.c:826 +#: access/brin/brin.c:925 access/brin/brin.c:1002 #, c-format msgid "could not open parent table of index %s" msgstr "%s ì¸ë±ìŠ¤ì— ëŒ€í•œ ìƒìœ„ í…Œì´ë¸”ì„ ì—´ 수 ì—†ìŒ" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:362 -#: access/brin/brin_pageops.c:828 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1376 access/nbtree/nbtinsert.c:678 +#: access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "ì¸ë±ìФ í–‰ í¬ê¸° %zuì´(ê°€) 최대값 %zu(\"%s\" ì¸ë±ìФ)ì„(를) 초과함" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "BRIN ì¸ë±ìФ ì†ìƒ: 범위 ì§€ë„ê°€ ì—°ê²°ë˜ì§€ 않ìŒ" + +#: access/brin/brin_revmap.c:404 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -msgstr "ì¸ë±ìФ í–‰ í¬ê¸° %luì´(ê°€) 최대값 %lu(\"%s\" ì¸ë±ìФ)ì„(를) 초과함" +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "\"%s\" BRIN ì¸ë±ìФì—서 leftover placeholder íŠœí”Œì´ ë°œê²¬ë˜ì—ˆìŒ, 지움" -#: access/brin/brin_revmap.c:459 +#: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "예ìƒì¹˜ 못한 0x%04X 페ì´ì§€ 타입: \"%s\" BRIN ì¸ë±ìФ %u 블ë¡" -#: access/brin/brin_validate.c:115 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format -msgid "" -"brin operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸(%d)로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/brin/brin_validate.c:131 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format -msgid "" -"brin operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s 함수가 ìž˜ëª»ëœ signature 번호(%d)로 지정ë˜ì—ˆìе" -"니다." +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/brin/brin_validate.c:153 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 #, c-format -msgid "" -"brin operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ì „ëžµ 번호(%d)로 지정ë˜ì—ˆìŠµë‹ˆ" -"다." +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/brin/brin_validate.c:182 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:209 #, c-format -msgid "" -"brin operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." -#: access/brin/brin_validate.c:195 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 #, c-format -msgid "brin operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ signature를 사용합니다." +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." -#: access/brin/brin_validate.c:233 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 #, c-format -msgid "brin operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì—는 %s, %s ìžë£Œí˜•ìš© ì—°ì‚°ìžê°€ 없습니다" +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì—는 %s, %s ìžë£Œí˜•ìš© ì—°ì‚°ìžê°€ 없습니다" -#: access/brin/brin_validate.c:243 +#: access/brin/brin_validate.c:244 #, c-format -msgid "" -"brin operator family \"%s\" is missing support function(s) for types %s and " -"%s" -msgstr "\"%s\" brin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì—는 %s, %s ìžë£Œí˜•용으로 쓸 함수가 없습니다" +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì—는 %s, %s ìžë£Œí˜•용으로 쓸 함수가 없습니다" -#: access/brin/brin_validate.c:256 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format -msgid "brin operator class \"%s\" is missing operator(s)" -msgstr "\"%s\" brin ì—°ì‚°ìž í´ëž˜ìŠ¤ì— ì—°ì‚°ìžê°€ 빠졌습니다" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(ì ‘ê·¼ 방법: %s)ì— ì—°ì‚°ìžê°€ 빠졌습니다" -#: access/brin/brin_validate.c:267 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -msgid "brin operator class \"%s\" is missing support function %d" -msgstr "\"%s\" brin ì—°ì‚°ìž í´ëž˜ìŠ¤ì— %d ì§€ì› í•¨ìˆ˜ê°€ ì—†ìŒ" +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(ì ‘ê·¼ 방법: %s)ì— %d ì§€ì› í•¨ìˆ˜ê°€ 빠졌습니다." -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1339 +#: access/common/heaptuple.c:1089 access/common/heaptuple.c:1805 #, c-format msgid "number of columns (%d) exceeds limit (%d)" -msgstr "ì—´ 수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" +msgstr "칼럼 개수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" -msgstr "ì¸ë±ìФ ì—´ 수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" +msgstr "ì¸ë±ìФ 칼럼 개수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:642 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "ì¸ë±ìФ í–‰(row)ì€ %zu ë°”ì´íŠ¸ë¥¼ 필요로 함, 최대 í¬ê¸°ëŠ” %zu" -#: access/common/printtup.c:292 tcop/fastpath.c:182 tcop/fastpath.c:544 -#: tcop/postgres.c:1719 +#: access/common/printtup.c:365 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1755 #, c-format msgid "unsupported format code: %d" msgstr "ì§€ì›í•˜ì§€ 않는 í¬ë§· 코드: %d" -#: access/common/reloptions.c:493 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "ì‚¬ìš©ìž ì •ì˜ ê´€ê³„ 매개 변수 í˜•ì‹ ì œí•œì„ ì´ˆê³¼í•¨" -#: access/common/reloptions.c:775 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "매개 ë³€ìˆ˜ì˜ ê°’ìœ¼ë¡œ RESETì€ ì˜¬ 수 ì—†ìŒ" -#: access/common/reloptions.c:808 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "\"%s\" 매개 변수 네임스페ì´ìŠ¤ë¥¼ ì¸ì‹í•  수 ì—†ìŒ" -#: access/common/reloptions.c:1050 parser/parse_clause.c:281 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "알 수 없는 환경 설정 ì´ë¦„입니다 \"%s\"" -#: access/common/reloptions.c:1080 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "\"%s\" 매개 변수가 여러 번 지정ë¨" -#: access/common/reloptions.c:1096 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "\"%s\" 부울 옵션 ê°’ì´ ìž˜ëª»ë¨: %s" -#: access/common/reloptions.c:1108 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "\"%s\" 정수 옵션 ê°’ì´ ìž˜ëª»ë¨: %s" -#: access/common/reloptions.c:1114 access/common/reloptions.c:1134 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "ê°’ %sì€(는) \"%s\" 옵션 범위를 벗어남" -#: access/common/reloptions.c:1116 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "유효한 ê°’ì€ \"%d\"ì—서 \"%d\" 사ì´ìž…니다." -#: access/common/reloptions.c:1128 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "\"%s\" ë¶€ë™ ì†Œìˆ˜ì  ì˜µì…˜ ê°’ì´ ìž˜ëª»ë¨: %s" -#: access/common/reloptions.c:1136 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "유효한 ê°’ì€ \"%f\"ì—서 \"%f\" 사ì´ìž…니다." @@ -535,33 +589,28 @@ msgstr "유효한 ê°’ì€ \"%f\"ì—서 \"%f\" 사ì´ìž…니다." #: access/common/tupconvert.c:108 #, c-format msgid "Returned type %s does not match expected type %s in column %d." -msgstr "" -"반환 ìžë£Œí˜•으로 %s í˜•ì„ ì§€ì •í–ˆì§€ë§Œ, ì¹¼ëŸ¼ì€ %s ìžë£Œí˜•입니다. 해당 칼럼: %d 번" -"째 칼럼" +msgstr "반환 ìžë£Œí˜•으로 %s í˜•ì„ ì§€ì •í–ˆì§€ë§Œ, ì¹¼ëŸ¼ì€ %s ìžë£Œí˜•입니다. 해당 칼럼: %d 번째 칼럼" #: access/common/tupconvert.c:136 #, c-format -msgid "" -"Number of returned columns (%d) does not match expected column count (%d)." +msgid "Number of returned columns (%d) does not match expected column count (%d)." msgstr "반환할 칼럼 수(%d)와 예ìƒë˜ëŠ” 칼럼수(%d)ê°€ 다릅니다." -#: access/common/tupconvert.c:314 +#: access/common/tupconvert.c:329 #, c-format -msgid "" -"Attribute \"%s\" of type %s does not match corresponding attribute of type " -"%s." -msgstr "" -" \"%s\" ì†ì„±(ëŒ€ìƒ ìžë£Œí˜• %s)ì´ %s ìžë£Œí˜•ì˜ ì†ì„± ê°€ìš´ë° ê´€ë ¨ëœ ê²ƒì´ ì—†ìŠµë‹ˆë‹¤" +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr " \"%s\" ì†ì„±(ëŒ€ìƒ ìžë£Œí˜• %s)ì´ %s ìžë£Œí˜•ì˜ ì†ì„± ê°€ìš´ë° ê´€ë ¨ëœ ê²ƒì´ ì—†ìŠµë‹ˆë‹¤" -#: access/common/tupconvert.c:326 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "\"%s\" ì†ì„±(ëŒ€ìƒ ìžë£Œí˜• %s)ì´ %s ìžë£Œí˜•ì—는 없습니다." -#: access/common/tupdesc.c:635 parser/parse_relation.c:1518 +#: access/common/tupdesc.c:834 parser/parse_clause.c:819 +#: parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" -msgstr "\"%s\" ì—´ì€ SETOF를 지정할 수 없습니다" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ SETOF를 지정할 수 없습니다" #: access/gin/ginbulk.c:44 #, c-format @@ -573,142 +622,79 @@ msgstr "í¬ìŠ¤íŒ… 목ë¡ì´ 너무 ê¹ë‹ˆë‹¤" msgid "Reduce maintenance_work_mem." msgstr "maintenance_work_mem ì„¤ì •ê°’ì„ ì¤„ì´ì„¸ìš”." -#: access/gin/ginentrypage.c:109 access/gist/gist.c:1337 -#: access/nbtree/nbtinsert.c:576 access/nbtree/nbtsort.c:488 -#: access/spgist/spgdoinsert.c:1907 -#, c-format -msgid "index row size %zu exceeds maximum %zu for index \"%s\"" -msgstr "ì¸ë±ìФ í–‰ í¬ê¸° %zuì´(ê°€) 최대값 %zu(\"%s\" ì¸ë±ìФ)ì„(를) 초과함" - -#: access/gin/ginfast.c:989 access/transam/xlog.c:9858 -#: access/transam/xlog.c:10362 access/transam/xlogfuncs.c:293 -#: access/transam/xlogfuncs.c:320 access/transam/xlogfuncs.c:359 -#: access/transam/xlogfuncs.c:380 access/transam/xlogfuncs.c:401 -#: access/transam/xlogfuncs.c:471 access/transam/xlogfuncs.c:527 -#, c-format -msgid "recovery is in progress" -msgstr "복구 작업 ì§„í–‰ 중" - -#: access/gin/ginfast.c:990 +#: access/gin/ginfast.c:1019 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "GIN 팬딩 목ë¡ì€ 복구 작업 중ì—는 ì •ë¦¬ë  ìˆ˜ 없습니다." -#: access/gin/ginfast.c:997 +#: access/gin/ginfast.c:1026 #, c-format msgid "\"%s\" is not a GIN index" -msgstr "\"%s\" ê°ì²´ëŠ” GIN ì¸ë±ìŠ¤ê°€ 아닙니다" +msgstr "\"%s\" 개체는 GIN ì¸ë±ìŠ¤ê°€ 아닙니다" -#: access/gin/ginfast.c:1008 +#: access/gin/ginfast.c:1037 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ ì¸ë±ìŠ¤ëŠ” 접근할 수 ì—†ìŒ" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" -msgstr "" -"GIN ì¸ë±ìŠ¤ê°€ 옛날 버전ì´ì–´ì„œ ì¸ë±ìФ ì „ì²´ íƒìƒ‰, null íƒìƒ‰ ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 ì—†" -"습니다." +msgstr "GIN ì¸ë±ìŠ¤ê°€ 옛날 버전ì´ì–´ì„œ ì¸ë±ìФ ì „ì²´ íƒìƒ‰, null íƒìƒ‰ ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다." -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "ì´ ë¬¸ì œë¥¼ 고치려면, ë‹¤ìŒ ëª…ë ¹ì„ ìˆ˜í–‰í•˜ì„¸ìš”: REINDEX INDEX \"%s\"" -#: access/gin/ginvalidate.c:92 -#, c-format -msgid "" -"gin operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— cross-type registration 으로 %s ì§€ì› í”„ë¡œì‹œì ¸ê°€ í¬" -"함ë˜ì–´ 있습니다." - -#: access/gin/ginvalidate.c:148 -#, c-format -msgid "" -"gin operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆìе" -"니다." - -#: access/gin/ginvalidate.c:160 -#, c-format -msgid "" -"gin operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d 로 " -"지정ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: access/gin/ginvalidate.c:179 -#, c-format -msgid "" -"gin operator family \"%s\" contains operator %s with invalid strategy number " -"%d" -msgstr "" -"\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìŠµë‹ˆ" -"다." - -#: access/gin/ginvalidate.c:192 -#, c-format -msgid "" -"gin operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." - -#: access/gin/ginvalidate.c:205 +#: access/gin/ginutil.c:138 executor/execExpr.c:1867 +#: utils/adt/arrayfuncs.c:3777 utils/adt/arrayfuncs.c:6375 +#: utils/adt/rowtypes.c:935 #, c-format -msgid "gin operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" gin ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." +msgid "could not identify a comparison function for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 비êµí•¨ìˆ˜ë¥¼ ì°¾ì„ ìˆ˜ 없습니다." -#: access/gin/ginvalidate.c:246 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format -msgid "gin operator class \"%s\" is missing support function %d" -msgstr "\"%s\" gin ì—°ì‚°ìž í´ëž˜ìŠ¤ì— %d ì§€ì› í•¨ìˆ˜ê°€ 빠졌습니다." +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— ì„œë¡œ 다른 양쪽 ìž…ë ¥ ìžë£Œí˜• ì¸ìžë¥¼ 사용할 수 있는 %s ì§€ì› í•¨ìˆ˜ê°€ í¬í•¨ë˜ì–´ 있ìŒ" -#: access/gin/ginvalidate.c:256 +#: access/gin/ginvalidate.c:257 #, c-format -msgid "gin operator class \"%s\" is missing support function %d or %d" -msgstr "\"%s\" gin ì—°ì‚°ìž í´ëž˜ìФì—는 %d ë˜ëŠ” %d ì§€ì› í•¨ìˆ˜ê°€ 빠졌습니다" +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(ì ‘ê·¼ 방법: %s)ì—는 %d ë˜ëŠ” %d ì§€ì› í•¨ìˆ˜ê°€ 빠졌습니다" -#: access/gist/gist.c:680 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:713 access/gist/gistvacuum.c:257 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "\"%s\" ì¸ë±ìŠ¤ì— ìž˜ëª»ëœ ë‚´ë¶€ íŠœí”Œì´ ìžˆë‹¤ê³  확ì¸ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/gist/gist.c:682 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:715 access/gist/gistvacuum.c:259 #, c-format -msgid "" -"This is caused by an incomplete page split at crash recovery before " -"upgrading to PostgreSQL 9.1." -msgstr "" -"ì´ ë¬¸ì œëŠ” PostgreSQL 9.1 버전으로 업그레ì´ë“œ 하기 ì „ì— ìž¥ì•  복구 처리ì—서 잘" -"ëª»ëœ íŽ˜ì´ì§€ 분리 ë•Œë¬¸ì— ë°œìƒí–ˆìŠµë‹ˆë‹¤." +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "ì´ ë¬¸ì œëŠ” PostgreSQL 9.1 버전으로 업그레ì´ë“œ 하기 ì „ì— ìž¥ì•  복구 처리ì—서 ìž˜ëª»ëœ íŽ˜ì´ì§€ 분리 ë•Œë¬¸ì— ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: access/gist/gist.c:683 access/gist/gistutil.c:738 -#: access/gist/gistutil.c:749 access/gist/gistvacuum.c:261 -#: access/hash/hashutil.c:172 access/hash/hashutil.c:183 -#: access/hash/hashutil.c:195 access/hash/hashutil.c:216 -#: access/nbtree/nbtpage.c:518 access/nbtree/nbtpage.c:529 +#: access/gist/gist.c:716 access/gist/gistutil.c:759 access/gist/gistutil.c:770 +#: access/gist/gistvacuum.c:260 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 +#: access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "REINDEX 명령으로 다시 ì¸ë±ìŠ¤ë¥¼ 만드세요" -#: access/gist/gistbuild.c:249 +#: access/gist/gistbuild.c:250 #, c-format msgid "invalid value for \"buffering\" option" msgstr "\"buffering\" 옵션 ê°’ì´ ì˜¬ë°”ë¥´ì§€ 않습니다" -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:251 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "유효한 ê°’: \"on\", \"off\", \"auto\"" -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:209 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "임시파ì¼ì˜ %ld ë¸”ëŸ­ì„ ì“¸ 수 ì—†ìŒ: %m" @@ -716,605 +702,361 @@ msgstr "임시파ì¼ì˜ %ld ë¸”ëŸ­ì„ ì“¸ 수 ì—†ìŒ: %m" #: access/gist/gistsplit.c:446 #, c-format msgid "picksplit method for column %d of index \"%s\" failed" -msgstr "%d ì—´(\"%s\" ì¸ë±ìФ)ì— ëŒ€í•œ picksplit 메서드 실패" +msgstr "%d 칼럼(\"%s\" ì¸ë±ìФ)ì— ëŒ€í•œ picksplit 메서드 실패" #: access/gist/gistsplit.c:448 #, c-format -msgid "" -"The index is not optimal. To optimize it, contact a developer, or try to use " -"the column as the second one in the CREATE INDEX command." -msgstr "" -"ì¸ë±ìŠ¤ê°€ 최ì í™”ë˜ì§€ 않았습니다. 최ì í™”하려면 개발ìžì—게 문ì˜í•˜ê±°ë‚˜, CREATE " -"INDEX 명령ì—서 해당 ì—´ì„ ë‘ ë²ˆì§¸ ì¸ë±ìŠ¤ë¡œ 사용하십시오." +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "ì¸ë±ìŠ¤ê°€ 최ì í™”ë˜ì§€ 않았습니다. 최ì í™”하려면 개발ìžì—게 문ì˜í•˜ê±°ë‚˜, CREATE INDEX 명령ì—서 해당 ì¹¼ëŸ¼ì„ ë‘ ë²ˆì§¸ ì¸ë±ìŠ¤ë¡œ 사용하십시오." -#: access/gist/gistutil.c:735 access/hash/hashutil.c:169 -#: access/nbtree/nbtpage.c:515 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "\"%s\" ì¸ë±ìŠ¤ì˜ %u번째 블럭ì—서 예ìƒì¹˜ ì•Šì€ zero pageê°€ 있습니다" -#: access/gist/gistutil.c:746 access/hash/hashutil.c:180 -#: access/hash/hashutil.c:192 access/nbtree/nbtpage.c:526 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "\"%s\" ì¸ë±ìŠ¤íŠ¸ %u번째 ë¸”ëŸ­ì´ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤" -#: access/gist/gistvalidate.c:92 -#, c-format -msgid "" -"gist operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— cross-type registration 으로 %s ì§€ì› í”„ë¡œì‹œì ¸ê°€ " -"í¬í•¨ë˜ì–´ 있습니다." - -#: access/gist/gistvalidate.c:145 -#, c-format -msgid "" -"gist operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆ" -"습니다." - -#: access/gist/gistvalidate.c:157 -#, c-format -msgid "" -"gist operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d " -"로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: access/gist/gistvalidate.c:177 -#, c-format -msgid "" -"gist operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìŠµë‹ˆ" -"다." - -#: access/gist/gistvalidate.c:195 -#, c-format -msgid "" -"gist operator family \"%s\" contains unsupported ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ì§€ì›í•˜ì§€ 않는 ORDER BY 명세를 사용합" -"니다." - -#: access/gist/gistvalidate.c:206 -#, c-format -msgid "" -"gist operator family \"%s\" contains incorrect ORDER BY opfamily " -"specification for operator %s" -msgstr "" -"\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." - -#: access/gist/gistvalidate.c:225 +#: access/gist/gistvalidate.c:196 #, c-format -msgid "gist operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" gist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %s ì—°ì‚°ìžê°€ ì§€ì›í•˜ì§€ 않는 ORDER BY 명세를 사용합니다." -#: access/gist/gistvalidate.c:264 +#: access/gist/gistvalidate.c:207 #, c-format -msgid "gist operator class \"%s\" is missing support function %d" -msgstr "\"%s\" gist ì—°ì‚°ìž í´ëž˜ìŠ¤ì— %d ì§€ì› í•¨ìˆ˜ê°€ 빠졌습니다." +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." -#: access/hash/hashinsert.c:70 +#: access/hash/hashinsert.c:83 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "ì¸ë±ìФ í–‰ í¬ê¸°ê°€ 초과ë¨: 현재값 %zu, 최대값 %zu" -#: access/hash/hashinsert.c:72 access/spgist/spgdoinsert.c:1911 -#: access/spgist/spgutils.c:703 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "ë²„í¼ íŽ˜ì´ì§€ë³´ë‹¤ í° ê°’ì€ ì¸ë±ì‹±í•  수 없습니다." -#: access/hash/hashovfl.c:546 +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "ìž˜ëª»ëœ ì˜¤ë²„í”Œë¡œìš° ë¸”ë¡ ë²ˆí˜¸: %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "\"%s\" 해시 ì¸ë±ìФì—서 오버플로우 페ì´ì§€ 초과" -#: access/hash/hashsearch.c:153 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "해시 ì¸ë±ìŠ¤ëŠ” whole-index scanì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: access/hash/hashutil.c:208 +#: access/hash/hashutil.c:277 #, c-format msgid "index \"%s\" is not a hash index" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 해시 ì¸ë±ìŠ¤ê°€ 아님" -#: access/hash/hashutil.c:214 +#: access/hash/hashutil.c:283 #, c-format msgid "index \"%s\" has wrong hash version" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” ìž˜ëª»ëœ í•´ì‹œ 버전임" -#: access/hash/hashvalidate.c:98 -#, c-format -msgid "" -"hash operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— cross-type registration 으로 %s ì§€ì› í”„ë¡œì‹œì ¸ê°€ " -"í¬í•¨ë˜ì–´ 있습니다." - -#: access/hash/hashvalidate.c:113 -#, c-format -msgid "" -"hash operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d " -"로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: access/hash/hashvalidate.c:130 -#, c-format -msgid "" -"hash operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆ" -"습니다." - -#: access/hash/hashvalidate.c:151 -#, c-format -msgid "" -"hash operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìŠµë‹ˆ" -"다." - -#: access/hash/hashvalidate.c:164 -#, c-format -msgid "" -"hash operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." - -#: access/hash/hashvalidate.c:177 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." - -#: access/hash/hashvalidate.c:189 -#, c-format -msgid "hash operator family \"%s\" lacks support function for operator %s" -msgstr "\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžìš© ì§€ì› í•¨ìˆ˜ê°€ ì—†ìŒ" - -#: access/hash/hashvalidate.c:217 -#, c-format -msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "" -"\"%s\" hash ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ìžë£Œí˜•ê³¼ %s ìžë£Œí˜•ì„ ë‹¤ë£¨ëŠ” ì—°ì‚°ìžê°€ ì—†ìŒ" - -#: access/hash/hashvalidate.c:231 +#: access/hash/hashvalidate.c:191 #, c-format -msgid "hash operator class \"%s\" is missing operator(s)" -msgstr "%s hash ì—°ì‚°ìž í´ëž˜ìŠ¤ì— ì—°ì‚°ìžê°€ 빠졌ìŒ" +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %s ì—°ì‚°ìžìš© ì§€ì› í•¨ìˆ˜ê°€ ì—†ìŒ" -#: access/hash/hashvalidate.c:247 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "hash operator family \"%s\" is missing cross-type operator(s)" -msgstr "%s hash ì—°ì‚°ìž í´ëž˜ìŠ¤ì— cross-type ì—°ì‚°ìžê°€ 빠졌ìŒ" +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "%s ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— cross-type ì—°ì‚°ìžê°€ 빠졌ìŒ" -#: access/heap/heapam.c:1295 access/heap/heapam.c:1323 -#: access/heap/heapam.c:1355 catalog/aclchk.c:1756 +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 +#: access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" -msgstr "\"%s\" ê°ì²´ëŠ” ì¸ë±ìŠ¤ìž„" +msgstr "\"%s\" 개체는 ì¸ë±ìŠ¤ìž„" -#: access/heap/heapam.c:1300 access/heap/heapam.c:1328 -#: access/heap/heapam.c:1360 catalog/aclchk.c:1763 commands/tablecmds.c:9081 -#: commands/tablecmds.c:12189 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 +#: access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10340 +#: commands/tablecmds.c:13543 #, c-format msgid "\"%s\" is a composite type" -msgstr "\"%s\" ê°ì²´ëŠ” 복합 ìžë£Œí˜•입니다" +msgstr "\"%s\" 개체는 복합 ìžë£Œí˜•입니다" -#: access/heap/heapam.c:2567 +#: access/heap/heapam.c:2639 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "병렬 작업 중ì—는 íŠœí”Œì„ ì¶”ê°€ í•  수 ì—†ìŒ" +msgid "cannot insert tuples in a parallel worker" +msgstr "병렬 작업ìžëŠ” íŠœí”Œì„ ì¶”ê°€ í•  수 ì—†ìŒ" -#: access/heap/heapam.c:3017 +#: access/heap/heapam.c:3083 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "병렬 작업 중ì—는 íŠœí”Œì„ ì§€ìš¸ 수 ì—†ìŒ" -#: access/heap/heapam.c:3063 +#: access/heap/heapam.c:3129 #, c-format msgid "attempted to delete invisible tuple" msgstr "ë³¼ 수 없는 íŠœí”Œì„ ì‚­ì œ 하려고 함" -#: access/heap/heapam.c:3489 access/heap/heapam.c:6240 +#: access/heap/heapam.c:3564 access/heap/heapam.c:6401 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "병렬 작업 ì¤‘ì— íŠœí”Œ ê°±ì‹ ì€ í•  수 ì—†ìŒ" -#: access/heap/heapam.c:3611 +#: access/heap/heapam.c:3712 #, c-format msgid "attempted to update invisible tuple" msgstr "ë³¼ 수 없는 íŠœí”Œì„ ë³€ê²½í•˜ë ¤ê³  함" -#: access/heap/heapam.c:4963 access/heap/heapam.c:5001 -#: access/heap/heapam.c:5253 executor/execMain.c:2314 +#: access/heap/heapam.c:5077 access/heap/heapam.c:5115 +#: access/heap/heapam.c:5367 executor/execMain.c:2660 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì˜ 잠금 정보를 구할 수 ì—†ìŒ" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:664 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:670 #, c-format msgid "row is too big: size %zu, maximum size %zu" -msgstr "ì—´(row)ì´ ë„ˆë¬´ í½ë‹ˆë‹¤: í¬ê¸° %zu, 최대값 %zu" +msgstr "로우가 너무 í½ë‹ˆë‹¤: í¬ê¸° %zu, 최대값 %zu" -#: access/heap/rewriteheap.c:923 +#: access/heap/rewriteheap.c:930 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "\"%s\" íŒŒì¼ ì“°ê¸° 실패, %d / %d 기ë¡í•¨: %m." -#: access/heap/rewriteheap.c:963 access/heap/rewriteheap.c:1175 -#: access/heap/rewriteheap.c:1272 access/transam/timeline.c:407 -#: access/transam/timeline.c:483 access/transam/xlog.c:3087 -#: access/transam/xlog.c:3249 replication/logical/snapbuild.c:1605 -#: replication/slot.c:1088 replication/slot.c:1173 storage/file/fd.c:631 -#: storage/file/fd.c:3129 storage/smgr/md.c:1041 storage/smgr/md.c:1274 -#: storage/smgr/md.c:1447 utils/misc/guc.c:6885 +#: access/heap/rewriteheap.c:970 access/heap/rewriteheap.c:1191 +#: access/heap/rewriteheap.c:1290 access/transam/timeline.c:411 +#: access/transam/timeline.c:490 access/transam/xlog.c:3300 +#: access/transam/xlog.c:3466 replication/logical/snapbuild.c:1645 +#: replication/slot.c:1308 replication/slot.c:1400 storage/file/fd.c:639 +#: storage/file/fd.c:3515 storage/smgr/md.c:1044 storage/smgr/md.c:1277 +#: storage/smgr/md.c:1450 utils/misc/guc.c:7256 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "\"%s\" íŒŒì¼ fsync 실패: %m" -#: access/heap/rewriteheap.c:1018 access/heap/rewriteheap.c:1138 -#: access/transam/timeline.c:315 access/transam/timeline.c:461 -#: access/transam/xlog.c:3043 access/transam/xlog.c:3192 -#: access/transam/xlog.c:10192 access/transam/xlog.c:10230 -#: access/transam/xlog.c:10603 postmaster/postmaster.c:4364 -#: replication/logical/origin.c:542 replication/slot.c:1045 -#: storage/file/copydir.c:162 storage/smgr/md.c:327 utils/time/snapmgr.c:1275 +#: access/heap/rewriteheap.c:1024 access/heap/rewriteheap.c:1143 +#: access/transam/timeline.c:314 access/transam/timeline.c:465 +#: access/transam/xlog.c:3254 access/transam/xlog.c:3404 +#: access/transam/xlog.c:10676 access/transam/xlog.c:10714 +#: access/transam/xlog.c:11117 postmaster/postmaster.c:4454 +#: replication/logical/origin.c:575 replication/slot.c:1257 +#: storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 #, c-format msgid "could not create file \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ 만들 수 ì—†ìŒ: %m" -#: access/heap/rewriteheap.c:1147 +#: access/heap/rewriteheap.c:1153 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "\"%s\" 파ì¼ì„ %u í¬ê¸°ë¡œ 정리할 수 ì—†ìŒ: %m" -#: access/heap/rewriteheap.c:1154 replication/walsender.c:481 -#: storage/smgr/md.c:1899 +#: access/heap/rewriteheap.c:1161 replication/walsender.c:490 +#: storage/smgr/md.c:1986 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "\"%s\" 파ì¼ì˜ ëì„ ì°¾ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/heap/rewriteheap.c:1165 access/transam/timeline.c:367 -#: access/transam/timeline.c:401 access/transam/timeline.c:477 -#: access/transam/xlog.c:3078 access/transam/xlog.c:3242 -#: postmaster/postmaster.c:4374 postmaster/postmaster.c:4384 -#: replication/logical/origin.c:551 replication/logical/origin.c:587 -#: replication/logical/origin.c:603 replication/logical/snapbuild.c:1589 -#: replication/slot.c:1074 storage/file/copydir.c:187 -#: utils/init/miscinit.c:1228 utils/init/miscinit.c:1237 -#: utils/init/miscinit.c:1244 utils/misc/guc.c:6846 utils/misc/guc.c:6877 -#: utils/misc/guc.c:8727 utils/misc/guc.c:8741 utils/time/snapmgr.c:1280 -#: utils/time/snapmgr.c:1287 +#: access/heap/rewriteheap.c:1178 access/transam/timeline.c:369 +#: access/transam/timeline.c:404 access/transam/timeline.c:482 +#: access/transam/xlog.c:3286 access/transam/xlog.c:3457 +#: postmaster/postmaster.c:4464 postmaster/postmaster.c:4474 +#: replication/logical/origin.c:590 replication/logical/origin.c:635 +#: replication/logical/origin.c:657 replication/logical/snapbuild.c:1624 +#: replication/slot.c:1291 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1341 utils/init/miscinit.c:1352 +#: utils/init/miscinit.c:1360 utils/misc/guc.c:7217 utils/misc/guc.c:7248 +#: utils/misc/guc.c:9110 utils/misc/guc.c:9124 utils/time/snapmgr.c:1302 +#: utils/time/snapmgr.c:1309 #, c-format msgid "could not write to file \"%s\": %m" msgstr "\"%s\" íŒŒì¼ ì“°ê¸° 실패: %m" -#: access/heap/rewriteheap.c:1248 access/transam/xlog.c:10441 -#: access/transam/xlogarchive.c:114 access/transam/xlogarchive.c:468 -#: replication/logical/origin.c:529 replication/logical/reorderbuffer.c:2632 -#: replication/logical/reorderbuffer.c:2689 -#: replication/logical/snapbuild.c:1533 replication/logical/snapbuild.c:1908 -#: replication/slot.c:1147 storage/ipc/dsm.c:326 storage/smgr/md.c:427 -#: storage/smgr/md.c:476 storage/smgr/md.c:1394 +#: access/heap/rewriteheap.c:1265 access/transam/xlogarchive.c:113 +#: access/transam/xlogarchive.c:469 postmaster/postmaster.c:1275 +#: postmaster/syslogger.c:1456 replication/logical/origin.c:563 +#: replication/logical/reorderbuffer.c:2800 +#: replication/logical/snapbuild.c:1567 replication/logical/snapbuild.c:1963 +#: replication/slot.c:1370 storage/file/fd.c:690 storage/file/fd.c:3118 +#: storage/file/fd.c:3180 storage/file/reinit.c:255 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1397 +#: utils/time/snapmgr.c:1640 #, c-format msgid "could not remove file \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" -#: access/heap/rewriteheap.c:1262 access/transam/timeline.c:111 -#: access/transam/timeline.c:236 access/transam/timeline.c:334 -#: access/transam/xlog.c:3019 access/transam/xlog.c:3136 -#: access/transam/xlog.c:3177 access/transam/xlog.c:3450 -#: access/transam/xlog.c:3528 access/transam/xlogutils.c:701 -#: replication/basebackup.c:403 replication/basebackup.c:1150 -#: replication/logical/origin.c:658 replication/logical/reorderbuffer.c:2156 -#: replication/logical/reorderbuffer.c:2402 -#: replication/logical/reorderbuffer.c:3081 -#: replication/logical/snapbuild.c:1582 replication/logical/snapbuild.c:1666 -#: replication/slot.c:1162 replication/walsender.c:474 -#: replication/walsender.c:2100 storage/file/copydir.c:155 -#: storage/file/fd.c:614 storage/file/fd.c:3041 storage/file/fd.c:3108 -#: storage/smgr/md.c:609 utils/error/elog.c:1879 utils/init/miscinit.c:1163 -#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1362 utils/misc/guc.c:7105 -#: utils/misc/guc.c:7138 +#: access/heap/rewriteheap.c:1279 access/transam/timeline.c:111 +#: access/transam/timeline.c:236 access/transam/timeline.c:333 +#: access/transam/xlog.c:3231 access/transam/xlog.c:3349 +#: access/transam/xlog.c:3390 access/transam/xlog.c:3667 +#: access/transam/xlog.c:3745 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1465 replication/basebackup.c:510 +#: replication/basebackup.c:1384 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2294 +#: replication/logical/reorderbuffer.c:2561 +#: replication/logical/reorderbuffer.c:3274 +#: replication/logical/snapbuild.c:1610 replication/logical/snapbuild.c:1707 +#: replication/slot.c:1385 replication/walsender.c:483 +#: replication/walsender.c:2412 storage/file/copydir.c:161 +#: storage/file/fd.c:622 storage/file/fd.c:3410 storage/file/fd.c:3494 +#: storage/smgr/md.c:608 utils/error/elog.c:1879 utils/init/miscinit.c:1265 +#: utils/init/miscinit.c:1400 utils/init/miscinit.c:1477 utils/misc/guc.c:7476 +#: utils/misc/guc.c:7508 #, c-format msgid "could not open file \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: access/index/amapi.c:82 commands/amcmds.c:164 +#: access/index/amapi.c:83 commands/amcmds.c:163 #, c-format msgid "access method \"%s\" is not of type %s" msgstr "\"%s\" ì ‘ê·¼ ë°©ë²•ì€ %s ìžë£Œí˜•ì—는 쓸 수 ì—†ìŒ" -#: access/index/amapi.c:98 +#: access/index/amapi.c:99 #, c-format msgid "index access method \"%s\" does not have a handler" msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì— ëŒ€í•œ 핸들러가 ì—†ìŒ" -#: access/index/indexam.c:155 catalog/objectaddress.c:1196 -#: commands/indexcmds.c:1800 commands/tablecmds.c:242 -#: commands/tablecmds.c:12180 +#: access/index/indexam.c:160 catalog/objectaddress.c:1223 +#: commands/indexcmds.c:2271 commands/tablecmds.c:249 commands/tablecmds.c:273 +#: commands/tablecmds.c:13534 commands/tablecmds.c:14765 #, c-format msgid "\"%s\" is not an index" -msgstr "\"%s\" ê°ì²´ëŠ” ì¸ë±ìŠ¤ê°€ 아닙니다" +msgstr "\"%s\" 개체는 ì¸ë±ìŠ¤ê°€ 아닙니다" -#: access/nbtree/nbtinsert.c:428 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "ì¤‘ë³µëœ í‚¤ ê°’ì´ \"%s\" 고유 제약 ì¡°ê±´ì„ ìœ„ë°˜í•¨" -#: access/nbtree/nbtinsert.c:430 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." msgstr "%s 키가 ì´ë¯¸ 있습니다." -#: access/nbtree/nbtinsert.c:497 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "\"%s\" ì¸ë±ìФì—서 튜플 재검색 실패" -#: access/nbtree/nbtinsert.c:499 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "ì´ ë¬¸ì œëŠ” non-immutable ì¸ë±ìФ í‘œí˜„ì‹ ë•Œë¬¸ì¸ë“¯ 합니다." -#: access/nbtree/nbtinsert.c:579 access/nbtree/nbtsort.c:491 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" -"Consider a function index of an MD5 hash of the value, or use full text " -"indexing." +"Consider a function index of an MD5 hash of the value, or use full text indexing." msgstr "" "ë²„í¼ íŽ˜ì´ì§€ì˜ 1/3보다 í° ê°’ì€ ì¸ë±ì‹±í•  수 없습니다.\n" "ê°’ì˜ MD5 해시 함수 ì¸ë±ìŠ¤ë¥¼ 고려하거나 ì „ì²´ í…스트 ì¸ë±ì‹±ì„ 사용하십시오." -#: access/nbtree/nbtpage.c:168 access/nbtree/nbtpage.c:371 -#: access/nbtree/nbtpage.c:458 parser/parse_utilcmd.c:1702 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 +#: access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2056 #, c-format msgid "index \"%s\" is not a btree" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” btree ì¸ë±ìŠ¤ê°€ 아닙니다" -#: access/nbtree/nbtpage.c:174 access/nbtree/nbtpage.c:377 -#: access/nbtree/nbtpage.c:464 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 +#: access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "\"%s\" ì¸ë±ìŠ¤ì˜ ë²„ì „ì´ í‹€ë¦½ë‹ˆë‹¤: íŒŒì¼ ë²„ì „ %d, 코드 버전 %d" +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "\"%s\" ì¸ë±ìŠ¤ì˜ ë²„ì „ì´ í‹€ë¦½ë‹ˆë‹¤: íŒŒì¼ ë²„ì „ %d, 현재 버전 %d, 최소 ì§€ì› ë²„ì „ %d" -#: access/nbtree/nbtpage.c:1152 +#: access/nbtree/nbtpage.c:1320 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "\"%s\" ì¸ë±ìŠ¤ì— ë°˜ì¯¤ 죽ì€(half-dead) ë‚´ë¶€ 페ì´ì§€ê°€ 있ìŒ" -#: access/nbtree/nbtpage.c:1154 -#, c-format -msgid "" -"This can be caused by an interrupted VACUUM in version 9.3 or older, before " -"upgrade. Please REINDEX it." -msgstr "" -"ì´ ë¬¸ì œëŠ” 9.3 버전 ì´í•˜ 환경ì—서 VACUUM ìž‘ì—…ì´ ì¤‘ì§€ë˜ê³ , ê·¸ ìƒíƒœë¡œ 업그레ì´ë“œ" -"ë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ í½ë‹ˆë‹¤. 해당 ì¸ë±ìŠ¤ë¥¼ 다시 만드십시오." - -#: access/nbtree/nbtvalidate.c:100 -#, c-format -msgid "" -"btree operator family \"%s\" contains function %s with invalid support " -"number %d" -msgstr "" -"\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜ì—ˆ" -"습니다." - -#: access/nbtree/nbtvalidate.c:112 -#, c-format -msgid "" -"btree operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d " -"로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: access/nbtree/nbtvalidate.c:132 +#: access/nbtree/nbtpage.c:1322 #, c-format -msgid "" -"btree operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìе" -"니다." - -#: access/nbtree/nbtvalidate.c:145 -#, c-format -msgid "" -"btree operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." - -#: access/nbtree/nbtvalidate.c:158 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "ì´ ë¬¸ì œëŠ” 9.3 버전 ì´í•˜ 환경ì—서 VACUUM ìž‘ì—…ì´ ì¤‘ì§€ë˜ê³ , ê·¸ ìƒíƒœë¡œ 업그레ì´ë“œë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ í½ë‹ˆë‹¤. 해당 ì¸ë±ìŠ¤ë¥¼ 다시 만드십시오." -#: access/nbtree/nbtvalidate.c:200 +#: access/nbtree/nbtvalidate.c:236 #, c-format -msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì—는 %s ìžë£Œí˜•ê³¼ %s ìžë£Œí˜•ìš© ì—°ì‚°ìžê°€ 빠졌ìŒ" +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì—는 %s ìžë£Œí˜•ê³¼ %s ìžë£Œí˜•ìš© ì§€ì› í•¨ìˆ˜ê°€ 빠졌ìŒ" -#: access/nbtree/nbtvalidate.c:210 +#: access/spgist/spgutils.c:136 #, c-format -msgid "" -"btree operator family \"%s\" is missing support function for types %s and %s" -msgstr "" -"\"%s\" btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì—는 %s ìžë£Œí˜•ê³¼ %s ìžë£Œí˜•ìš© ì§€ì› í•¨ìˆ˜ê°€ 빠졌ìŒ" - -#: access/nbtree/nbtvalidate.c:224 -#, c-format -msgid "btree operator class \"%s\" is missing operator(s)" -msgstr "\"%s\" btree ì—°ì‚°ìž í´ëž˜ìФì—는 ì—°ì‚°ìžê°€ 빠졌ìŒ" +msgid "compress method must be defined when leaf type is different from input type" +msgstr "ìž…ë ¥ ìžë£Œí˜•ì—서 리프 ìœ í˜•ì´ ë‹¤ë¥¼ 때 ì••ì¶• ë°©ë²•ì€ ë°˜ë“œì‹œ ì •ì˜í•´ì•¼ 함" -#: access/nbtree/nbtvalidate.c:241 -#, c-format -msgid "btree operator family \"%s\" is missing cross-type operator(s)" -msgstr "\"%s\" btree ì—°ì‚°ìž í´ëž˜ìФì—는 cross-type ì—°ì‚°ìžê°€ 빠졌ìŒ" - -#: access/spgist/spgutils.c:700 +#: access/spgist/spgutils.c:743 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "SP-GiST ë‚´ë¶€ 튜플 í¬ê¸°ê°€ 초과ë¨: 현재값 %zu, 최대값 %zu" -#: access/spgist/spgvalidate.c:92 -#, c-format -msgid "" -"spgist operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— cross-type registration 으로 %s ì§€ì› í”„ë¡œì‹œì ¸" -"ê°€ í¬í•¨ë˜ì–´ 있습니다." - -#: access/spgist/spgvalidate.c:115 -#, c-format -msgid "" -"spgist operator family \"%s\" contains function %s with invalid support " -"number %d" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ ì§€ì› ë²ˆí˜¸ %d 로 지정ë˜" -"었습니다." - -#: access/spgist/spgvalidate.c:127 -#, c-format -msgid "" -"spgist operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s 함수가 ìž˜ëª»ëœ signature ì§€ì› ë²ˆí˜¸ %d " -"로 지정ë˜ì—ˆìŠµë‹ˆë‹¤." - -#: access/spgist/spgvalidate.c:146 -#, c-format -msgid "" -"spgist operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— í¬í•¨ëœ %s ì—°ì‚°ìžì˜ %d 번 ì „ëžµ 번호가 잘못ë˜ì—ˆìе" -"니다." - -#: access/spgist/spgvalidate.c:159 -#, c-format -msgid "" -"spgist operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ORDER BY 명세를 사용합니다." - -#: access/spgist/spgvalidate.c:172 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with wrong signature" -msgstr "\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %s ì—°ì‚°ìžê°€ ìž˜ëª»ëœ ê¸°í˜¸ë¥¼ 사용합니다." - -#: access/spgist/spgvalidate.c:200 -#, c-format -msgid "" -"spgist operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "" -"\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì—서 %s ìžë£Œí˜•ê³¼ %s ìžë£Œí˜•ìš© ì—°ì‚°ìžê°€ 빠졌ìŒ" - -#: access/spgist/spgvalidate.c:220 +#: access/spgist/spgvalidate.c:269 #, c-format -msgid "" -"spgist operator family \"%s\" is missing support function %d for type %s" -msgstr "\"%s\" spgist ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— %d ì§€ì› í•¨ìˆ˜ê°€ %s ìžë£Œí˜•용으로 없습니다." - -#: access/spgist/spgvalidate.c:233 -#, c-format -msgid "spgist operator class \"%s\" is missing operator(s)" -msgstr "\"%s\" spgist ì—°ì‚°ìž í´ëž˜ìŠ¤ì— ì—°ì‚°ìžê°€ 빠졌ìŒ" +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: %s)ì— %d ì§€ì› í•¨ìˆ˜ê°€ %s ìžë£Œí˜•용으로 없습니다." #: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 #, c-format msgid "sample percentage must be between 0 and 100" msgstr "샘플 í¼ì„¼íЏ ê°’ì€ 0ì—서 100 사ì´ì—¬ì•¼ 함" -#: access/transam/commit_ts.c:294 +#: access/transam/commit_ts.c:295 #, c-format msgid "cannot retrieve commit timestamp for transaction %u" msgstr "%u íŠ¸ëžœìž­ì…˜ì˜ ì»¤ë°‹ 타임스탬프를 알 수 ì—†ìŒ" -#: access/transam/commit_ts.c:392 +#: access/transam/commit_ts.c:393 #, c-format msgid "could not get commit timestamp data" msgstr "커밋 타임스탬프 ìžë£Œë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: access/transam/commit_ts.c:394 +#: access/transam/commit_ts.c:395 #, c-format -msgid "" -"Make sure the configuration parameter \"%s\" is set on the master server." +msgid "Make sure the configuration parameter \"%s\" is set on the master server." msgstr "ìš´ì˜ ì„œë²„ì—서 \"%s\" 환경 설정 매개 ë³€ìˆ˜ê°’ì„ ì§€ì • 하세요." -#: access/transam/commit_ts.c:396 libpq/hba.c:1439 +#: access/transam/commit_ts.c:397 #, c-format msgid "Make sure the configuration parameter \"%s\" is set." msgstr "\"%s\" 환경 설정 매개 변수를 지정하세요." #: access/transam/multixact.c:1000 #, c-format -msgid "" -"database is not accepting commands that generate new MultiXactIds to avoid " -"wraparound data loss in database \"%s\"" -msgstr "" -"\"%s\" ë°ì´í„°ë² ì´ìФ ìžë£Œ ì†ì‹¤ì„ 막기 위해 새로운 MultiXactId 만드는 ìž‘ì—…ì„ " -"ë” ì´ìƒ í•  수 없습니다." +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ ìžë£Œ ì†ì‹¤ì„ 막기 위해 새로운 MultiXactId 만드는 ìž‘ì—…ì„ ë” ì´ìƒ í•  수 없습니다." #: access/transam/multixact.c:1002 access/transam/multixact.c:1009 #: access/transam/multixact.c:1033 access/transam/multixact.c:1042 #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "해당 ë°ì´í„°ë² ì´ìФ 단위로 VACUUM ìž‘ì—…ì„ ì§„í–‰í•˜ì‹­ì‹œì˜¤.\n" -"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹í•˜ê±°ë‚˜ 롤백할 필요가 있습니다." +"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹ë˜ëŠ” 롤백하거나 잠긴 복제 ìŠ¬ë¡¯ì„ ì§€ìš¸ 필요가 있습니다." #: access/transam/multixact.c:1007 #, c-format -msgid "" -"database is not accepting commands that generate new MultiXactIds to avoid " -"wraparound data loss in database with OID %u" -msgstr "" -"%u OID ë°ì´í„°ë² ì´ìФ ìžë£Œ ì†ì‹¤ì„ 막기 위해 새로운 MultiXactId 만드는 ìž‘ì—…ì„ " -"ë” ì´ìƒ í•  수 없습니다." +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "%u OID ë°ì´í„°ë² ì´ìФ ìžë£Œ ì†ì‹¤ì„ 막기 위해 새로운 MultiXactId 만드는 ìž‘ì—…ì„ ë” ì´ìƒ í•  수 없습니다." -#: access/transam/multixact.c:1028 access/transam/multixact.c:2314 +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 #, c-format msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" -msgid_plural "" -"database \"%s\" must be vacuumed before %u more MultiXactIds are used" -msgstr[0] "" -"\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— VACUUM ìž‘ì—…ì„ í•´ì•¼ 합니" -"다." +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— VACUUM ìž‘ì—…ì„ í•´ì•¼ 합니다." -#: access/transam/multixact.c:1037 access/transam/multixact.c:2323 +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 #, c-format -msgid "" -"database with OID %u must be vacuumed before %u more MultiXactId is used" -msgid_plural "" -"database with OID %u must be vacuumed before %u more MultiXactIds are used" -msgstr[0] "" -"%u OID ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— VACUUM ìž‘ì—…ì„ í•´ì•¼ 합니" -"다." +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "%u OID ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— VACUUM ìž‘ì—…ì„ í•´ì•¼ 합니다." #: access/transam/multixact.c:1098 #, c-format @@ -1323,45 +1065,25 @@ msgstr "multixact \"회수\" 초과" #: access/transam/multixact.c:1099 #, c-format -msgid "" -"This command would create a multixact with %u members, but the remaining " -"space is only enough for %u member." -msgid_plural "" -"This command would create a multixact with %u members, but the remaining " -"space is only enough for %u members." -msgstr[0] "" -"ì´ ëª…ë ¹ì€ %u ê°œì˜ multixact를 ì¨ì•¼í•˜ëŠ”ë°, 쓸 수 있는 ê³µê°„ì€ %u ê°œ ë¿ìž…니다." +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "ì´ ëª…ë ¹ì€ %u ê°œì˜ multixact를 ì¨ì•¼í•˜ëŠ”ë°, 쓸 수 있는 ê³µê°„ì€ %u ê°œ ë¿ìž…니다." #: access/transam/multixact.c:1104 #, c-format -msgid "" -"Execute a database-wide VACUUM in database with OID %u with reduced " -"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " -"settings." -msgstr "" -"vacuum_multixact_freeze_min_age, vacuum_multixact_freeze_table_age ê°’ì„ ì¡°ì •" -"하고, %u OID ë°ì´í„°ë² ì´ìФ 대ìƒìœ¼ë¡œ VACUUM ìž‘ì—…ì„ í•˜ì‹­ì‹œì˜¤." +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age, vacuum_multixact_freeze_table_age ê°’ì„ ì¡°ì •í•˜ê³ , %u OID ë°ì´í„°ë² ì´ìФ 대ìƒìœ¼ë¡œ VACUUM ìž‘ì—…ì„ í•˜ì‹­ì‹œì˜¤." #: access/transam/multixact.c:1135 #, c-format -msgid "" -"database with OID %u must be vacuumed before %d more multixact member is used" -msgid_plural "" -"database with OID %u must be vacuumed before %d more multixact members are " -"used" -msgstr[0] "" -"%u OID ë°ì´í„°ë² ì´ìŠ¤ëŠ” %d ê°œì˜ ë©€í‹°íŠ¸ëžœìž­ì…˜ì„ ì‚¬ìš©í•˜ê¸° ì „ì— vacuum ìž‘ì—…ì„ í•´" -"야 합니다." +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "%u OID ë°ì´í„°ë² ì´ìŠ¤ëŠ” %d ê°œì˜ ë©€í‹°íŠ¸ëžœìž­ì…˜ì„ ì‚¬ìš©í•˜ê¸° ì „ì— vacuum ìž‘ì—…ì„ í•´ì•¼ 합니다." #: access/transam/multixact.c:1140 #, c-format -msgid "" -"Execute a database-wide VACUUM in that database with reduced " -"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " -"settings." -msgstr "" -"vacuum_multixact_freeze_min_age 설정값과 vacuum_multixact_freeze_table_age ê°’" -"ì„ ì¤„ì—¬ì„œ ë°ì´í„°ë² ì´ìФ 단위로 VACUUM ìž‘ì—…ì„ ì§„í–‰í•˜ì„¸ìš”." +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "vacuum_multixact_freeze_min_age 설정값과 vacuum_multixact_freeze_table_age ê°’ì„ ì¤„ì—¬ì„œ ë°ì´í„°ë² ì´ìФ 단위로 VACUUM ìž‘ì—…ì„ ì§„í–‰í•˜ì„¸ìš”." #: access/transam/multixact.c:1277 #, c-format @@ -1373,141 +1095,139 @@ msgstr "%u번 MultiXactId ë”ì´ìƒ ì—†ìŒ -- 번호 겹침 í˜„ìƒ ë°œìƒ" msgid "MultiXactId %u has not been created yet -- apparent wraparound" msgstr "%u번 MultiXactId를 만들 수 ì—†ìŒ -- 번호 겹침 í˜„ìƒ ë°œìƒ" -#: access/transam/multixact.c:2264 +#: access/transam/multixact.c:2268 #, c-format msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "MultiXactId 겹침 한계는 %u 입니다. %u OID ë°ì´í„°ë² ì´ìФì—서 제한ë¨" -#: access/transam/multixact.c:2319 access/transam/multixact.c:2328 +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 #: access/transam/varsup.c:146 access/transam/varsup.c:153 -#: access/transam/varsup.c:384 access/transam/varsup.c:391 +#: access/transam/varsup.c:405 access/transam/varsup.c:412 #, c-format msgid "" -"To avoid a database shutdown, execute a database-wide VACUUM in that " -"database.\n" -"You might also need to commit or roll back old prepared transactions." +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"ë°ì´í„°ë² ì´ìŠ¤ê°€ 종료ë˜ì§€ 않ë„ë¡ í•˜ë ¤ë©´ ë°ì´í„°ë² ì´ìФ ìˆ˜ì¤€ì˜ VACUUMì„ ì‹¤í–‰í•˜ì‹­ì‹œ" -"오.\n" -"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹í•˜ê±°ë‚˜ 롤백할 필요가 있습니다." +"ë°ì´í„°ë² ì´ìŠ¤ê°€ 종료ë˜ì§€ 않ë„ë¡ í•˜ë ¤ë©´ ë°ì´í„°ë² ì´ìФ ìˆ˜ì¤€ì˜ VACUUMì„ ì‹¤í–‰í•˜ì‹­ì‹œì˜¤.\n" +"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹ë˜ëŠ” 롤백 하거나, 잠긴 복제 ìŠ¬ë¡¯ì„ ì§€ìš¸ 필요가 있습니다." -#: access/transam/multixact.c:2598 +#: access/transam/multixact.c:2602 #, c-format msgid "oldest MultiXactId member is at offset %u" msgstr "ì œì¼ ì˜¤ëž˜ëœ MultiXactId ê°’ì€ %u ìœ„ì¹˜ì— ìžˆìŒ" -#: access/transam/multixact.c:2602 +#: access/transam/multixact.c:2606 #, c-format -msgid "" -"MultiXact member wraparound protections are disabled because oldest " -"checkpointed MultiXact %u does not exist on disk" -msgstr "" -"가장 ì˜¤ëž˜ëœ ì²´í¬í¬ì¸íЏ ìž‘ì—…ì´ ì™„ë£Œëœ %u 멀티 트랜잭션 번호가 디스í¬ì— 없기 때" -"문ì—, 멀티 트랜잭션 번호 겹침 ë°©ì§€ ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ 있습니다." +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "가장 ì˜¤ëž˜ëœ ì²´í¬í¬ì¸íЏ ìž‘ì—…ì´ ì™„ë£Œëœ %u 멀티 트랜잭션 번호가 디스í¬ì— 없기 때문ì—, 멀티 트랜잭션 번호 겹침 ë°©ì§€ ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ 있습니다." -#: access/transam/multixact.c:2624 +#: access/transam/multixact.c:2628 #, c-format msgid "MultiXact member wraparound protections are now enabled" msgstr "멀티 트랜잭션 번호 겹침 ë°©ì§€ ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì—ˆìŒ" -#: access/transam/multixact.c:2626 +#: access/transam/multixact.c:2631 #, c-format msgid "MultiXact member stop limit is now %u based on MultiXact %u" msgstr "멀티 트랜잭션 중지 제한 번호는 %u 입니다. (%u ë©€í‹°íŠ¸ëžœìž­ì…˜ì— ê¸°ì´ˆí•¨)" -#: access/transam/multixact.c:3006 +#: access/transam/multixact.c:3011 #, c-format -msgid "" -"oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" -msgstr "" -"가장 ì˜¤ëž˜ëœ ë©€í‹° 트랜잭션 번호는 %u, 가장 최신 ê²ƒì€ %u, truncate 작업 건너뜀" +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "가장 ì˜¤ëž˜ëœ ë©€í‹° 트랜잭션 번호는 %u, 가장 최신 ê²ƒì€ %u, truncate 작업 건너뜀" -#: access/transam/multixact.c:3024 +#: access/transam/multixact.c:3029 #, c-format -msgid "" -"cannot truncate up to MultiXact %u because it does not exist on disk, " -"skipping truncation" -msgstr "" -"디스í¬ì— 해당 멀티 트랜잭션 번호가 없어, %u 멀티 트랜잭션 번호로 truncate 못" -"함, truncate 작업 건너뜀" +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "디스í¬ì— 해당 멀티 트랜잭션 번호가 없어, %u 멀티 트랜잭션 번호로 truncate 못함, truncate 작업 건너뜀" -#: access/transam/multixact.c:3350 +#: access/transam/multixact.c:3355 #, c-format msgid "invalid MultiXactId: %u" msgstr "ìž˜ëª»ëœ MultiXactId: %u" -#: access/transam/parallel.c:589 +#: access/transam/parallel.c:660 access/transam/parallel.c:783 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "병렬 ìž‘ì—…ìž ì´ˆê¸°í™” 실패" + +#: access/transam/parallel.c:661 access/transam/parallel.c:784 +#, c-format +msgid "More details may be available in the server log." +msgstr "보다 ìžì„¸í•œ ë‚´ìš©ì€ ì„œë²„ ë¡œê·¸ì— ë‚¨ê²¨ì¡Œì„ ìˆ˜ 있습니다." + +#: access/transam/parallel.c:845 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "병렬 트랜잭션 처리 중 postmaster 종료ë¨" -#: access/transam/parallel.c:774 +#: access/transam/parallel.c:1032 #, c-format msgid "lost connection to parallel worker" msgstr "병렬 처리 ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ ì—°ê²° ëŠê¹€" -#: access/transam/parallel.c:833 access/transam/parallel.c:835 +#: access/transam/parallel.c:1098 access/transam/parallel.c:1100 msgid "parallel worker" msgstr "병렬 처리 작업ìž" -#: access/transam/parallel.c:974 +#: access/transam/parallel.c:1245 #, c-format msgid "could not map dynamic shared memory segment" msgstr "ë™ì  공유 메모리 세그먼트를 할당할 수 ì—†ìŒ" -#: access/transam/parallel.c:979 +#: access/transam/parallel.c:1250 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "ë™ì  공유 메모리 ì„¸ê·¸ë¨¼íŠ¸ì— ìž˜ëª»ëœ ë§¤ì§ ë²ˆí˜¸ê°€ 있ìŒ" -#: access/transam/slru.c:665 +#: access/transam/slru.c:668 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "\"%s\" íŒŒì¼ ì—†ìŒ, 0으로 ì½ìŒ" -#: access/transam/slru.c:895 access/transam/slru.c:901 -#: access/transam/slru.c:908 access/transam/slru.c:915 -#: access/transam/slru.c:922 access/transam/slru.c:929 +#: access/transam/slru.c:906 access/transam/slru.c:912 +#: access/transam/slru.c:919 access/transam/slru.c:926 +#: access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "%u íŠ¸ëžœìž­ì…˜ì˜ ìƒíƒœë¥¼ 액세스할 수 ì—†ìŒ" -#: access/transam/slru.c:896 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m." -#: access/transam/slru.c:902 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "\"%s\" 파ì¼ì—서 %u 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %m." -#: access/transam/slru.c:909 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "\"%s\" 파ì¼ì—서 %u 위치를 ì½ì„ 수 ì—†ìŒ: %m." -#: access/transam/slru.c:916 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "\"%s\" 파ì¼ì—서 %u ìœ„ì¹˜ì— ì“¸ 수 ì—†ìŒ: %m." -#: access/transam/slru.c:923 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "\"%s\" íŒŒì¼ fsync 실패: %m." -#: access/transam/slru.c:930 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "\"%s\" 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m." -#: access/transam/slru.c:1185 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "\"%s\" 디렉터리를 비울 수 ì—†ìŒ: 랩어ë¼ìš´ë“œ ë°œìƒ" -#: access/transam/slru.c:1240 access/transam/slru.c:1296 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "\"%s\" íŒŒì¼ ì‚­ì œ 중" @@ -1524,7 +1244,7 @@ msgstr "ìˆ«ìž íƒ€ìž„ë¼ì¸ IDê°€ 필요합니다." #: access/transam/timeline.c:154 #, c-format -msgid "Expected a transaction log switchpoint location." +msgid "Expected a write-ahead log switchpoint location." msgstr "트랜잭션 로그 전환 위치 ê°’ì´ ìžˆì–´ì•¼ 함" #: access/transam/timeline.c:158 @@ -1547,1545 +1267,1367 @@ msgstr "작업내역 파ì¼ì— ìž˜ëª»ëœ ìžë£Œê°€ 있ìŒ: \"%s\"" msgid "Timeline IDs must be less than child timeline's ID." msgstr "타임ë¼ì¸ ID는 하위 타임ë¼ì¸ ID보다 작아야 합니다." -#: access/transam/timeline.c:412 access/transam/timeline.c:488 -#: access/transam/xlog.c:3093 access/transam/xlog.c:3254 -#: access/transam/xlogfuncs.c:690 commands/copy.c:1708 -#: storage/file/copydir.c:201 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 +#: access/transam/xlog.c:3307 access/transam/xlog.c:3472 +#: access/transam/xlogfuncs.c:683 commands/copy.c:1742 +#: storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/transam/timeline.c:570 +#: access/transam/timeline.c:578 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "요청한 %u 타ì´ë¼ì¸ì´ ì´ ì„œë²„ ë‚´ì—­ì—는 ì—†ìŒ" -#: access/transam/twophase.c:363 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "\"%s\" 트랜잭션 ì‹ë³„ìžê°€ 너무 ê¹ë‹ˆë‹¤" -#: access/transam/twophase.c:370 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" msgstr "ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ë¹„í™œì„±í™”ë¨" -#: access/transam/twophase.c:371 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "max_prepared_transactions ì„¤ì •ê°’ì„ 0ì´ ì•„ë‹Œ 값으로 설정하십시오." -#: access/transam/twophase.c:390 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "\"%s\" ì´ë¦„ì˜ íŠ¸ëžœìž­ì…˜ ì‹ë³„ìžê°€ ì´ë¯¸ 사용 중입니다" -#: access/transam/twophase.c:399 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì˜ ìµœëŒ€ 개수를 ëª¨ë‘ ì‚¬ìš©í–ˆìŠµë‹ˆë‹¤" -#: access/transam/twophase.c:400 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "max_prepared_transactions ê°’ì„ ëŠ˜ë ¤ì£¼ì„¸ìš” (현재 %d)." -#: access/transam/twophase.c:540 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "\"%s\" ì´ë¦„ì˜ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ ì‹ë³„ìžê°€ 여러 ê³³ì—서 ì“°ì´ê³  있습니다" -#: access/transam/twophase.c:546 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" msgstr "ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ ë내기 작업 권한 ì—†ìŒ" -#: access/transam/twophase.c:547 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "해당 ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì˜ ì†Œìœ ì£¼ì´ê±°ë‚˜ superuser여야합니다" -#: access/transam/twophase.c:558 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" msgstr "ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ë‹¤ë¥¸ ë°ì´í„°ë² ì´ìŠ¤ì— ì†í•´ 있ìŒ" -#: access/transam/twophase.c:559 +#: access/transam/twophase.c:605 #, c-format -msgid "" -"Connect to the database where the transaction was prepared to finish it." +msgid "Connect to the database where the transaction was prepared to finish it." msgstr "ìž‘ì—…ì„ ë§ˆì¹˜ë ¤ë©´ ê·¸ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆëŠ” ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²°í•˜ì‹­ì‹œì˜¤." -#: access/transam/twophase.c:574 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ì—†ìŠµë‹ˆë‹¤" -#: access/transam/twophase.c:1043 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "2단계 ìƒíƒœ íŒŒì¼ ìµœëŒ€ 길ì´ë¥¼ 초과함" -#: access/transam/twophase.c:1161 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "\"%s\" ì´ë¦„ì˜ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1178 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" msgstr "\"%s\" ì´ë¦„ì˜ two-phase ìƒíƒœì •ë³´ 파ì¼ì˜ 파ì¼ì •보를 알 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1210 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "\"%s\" ì´ë¦„ì˜ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1263 access/transam/xlog.c:6109 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6476 #, c-format -msgid "Failed while allocating an XLog reading processor." -msgstr "XLog ì½ê¸° 프로세서를 할당하는 ì¤‘ì— ì˜¤ë¥˜ ë°œìƒ" +msgid "Failed while allocating a WAL reading processor." +msgstr "WAL ì½ê¸° 프로세서를 할당하는 ì¤‘ì— ì˜¤ë¥˜ ë°œìƒ" -#: access/transam/twophase.c:1269 +#: access/transam/twophase.c:1390 #, c-format -msgid "could not read two-phase state from xlog at %X/%X" -msgstr "two-phase ìƒíƒœì •ë³´ì„ ì½ì„ 수 ì—†ìŒ xlog 위치: %X/%X" +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "two-phase ìƒíƒœì •ë³´ì„ ì½ì„ 수 ì—†ìŒ WAL 위치: %X/%X" -#: access/transam/twophase.c:1277 +#: access/transam/twophase.c:1398 #, c-format -msgid "expected two-phase state data is not present in xlog at %X/%X" -msgstr "xlog %X/%X ìœ„ì¹˜ì— 2단계 커밋 ìƒíƒœ ìžë£Œê°€ 없습니다" +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "WAL %X/%X ìœ„ì¹˜ì— 2단계 커밋 ìƒíƒœ ìžë£Œê°€ 없습니다" -#: access/transam/twophase.c:1512 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "\"%s\" ì´ë¦„ì˜ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1542 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "\"%s\" ì´ë¦„ì˜ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 다시 만들 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1551 access/transam/twophase.c:1558 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 #, c-format msgid "could not write two-phase state file: %m" msgstr "two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 쓸 수 ì—†ìŒ: %m" -#: access/transam/twophase.c:1570 +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "two-phase ìƒíƒœì •ë³´ 파ì¼ì˜ fsync 작업 실패: %m" -#: access/transam/twophase.c:1576 +#: access/transam/twophase.c:1719 #, c-format msgid "could not close two-phase state file: %m" msgstr "two-phase ìƒíƒœì •ë³´ 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/transam/twophase.c:1649 +#: access/transam/twophase.c:1807 #, c-format -msgid "" -"%u two-phase state file was written for long-running prepared transactions" -msgid_plural "" -"%u two-phase state files were written for long-running prepared transactions" -msgstr[0] "" +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "긴 실행 미리 ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ ìš© %u ê°œì˜ 2단계 ìƒíƒœ 파ì¼ì´ 저장ë˜ì—ˆìŒ" -#: access/transam/twophase.c:1713 +#: access/transam/twophase.c:2036 #, c-format -msgid "removing future two-phase state file \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ future two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" +msgid "recovering prepared transaction %u from shared memory" +msgstr "공유 메모리ì—서 %u ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì„ ë³µêµ¬í•¨" -#: access/transam/twophase.c:1729 access/transam/twophase.c:1740 -#: access/transam/twophase.c:1860 access/transam/twophase.c:1871 -#: access/transam/twophase.c:1948 +#: access/transam/twophase.c:2126 #, c-format -msgid "removing corrupt two-phase state file \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ìž˜ëª»ëœ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" +msgid "removing stale two-phase state file for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 ì˜¤ëž˜ëœ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" -#: access/transam/twophase.c:1849 access/transam/twophase.c:1937 +#: access/transam/twophase.c:2133 #, c-format -msgid "removing stale two-phase state file \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ì˜¤ëž˜ëœ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 ì˜¤ëž˜ëœ two-phase ìƒíƒœì •보를 공유 메모리ì—서 삭제함" -#: access/transam/twophase.c:1955 +#: access/transam/twophase.c:2146 #, c-format -msgid "recovering prepared transaction %u" -msgstr "%u ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì„ ë³µêµ¬í•¨" +msgid "removing future two-phase state file for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 future two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" -#: access/transam/varsup.c:124 +#: access/transam/twophase.c:2153 #, c-format -msgid "" -"database is not accepting commands to avoid wraparound data loss in database " -"\"%s\"" -msgstr "" -"\"%s\" ë°ì´í„°ë² ì´ìФ 트랜잭션 ID ê²¹ì¹¨ì— ì˜í•œ ìžë£Œ ì†ì‹¤ì„ 방지하기 위해 ë” ì´" -"ìƒ ìžë£Œ ì¡°ìž‘ ìž‘ì—…ì„ í—ˆìš©í•˜ì§€ 않습니다" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 future two-phase ìƒíƒœì •보를 메모리ì—서 삭제함" + +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 +#, c-format +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 ìž˜ëª»ëœ two-phase ìƒíƒœì •ë³´ 파ì¼ì„ 삭제함" + +#: access/transam/twophase.c:2193 +#, c-format +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "%u 트랜잭션ì—서 사용하는 ìž˜ëª»ëœ two-phase ìƒíƒœì •보를 메모리ì—서 삭제함" + +#: access/transam/varsup.c:124 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 트랜잭션 ID ê²¹ì¹¨ì— ì˜í•œ ìžë£Œ ì†ì‹¤ì„ 방지하기 위해 ë” ì´ìƒ ìžë£Œ ì¡°ìž‘ ìž‘ì—…ì„ í—ˆìš©í•˜ì§€ 않습니다" #: access/transam/varsup.c:126 access/transam/varsup.c:133 #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"postmaster를 중지하고 ë‹¨ì¼ ì‚¬ìš©ìž ëª¨ë“œë¡œ 서버를 실행한 ë’¤ VACUUM ìž‘ì—…ì„ í•˜ì‹­" -"시오.\n" -"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹í•˜ê±°ë‚˜ 롤백할 필요가 있습니다." +"postmaster를 중지하고 ë‹¨ì¼ ì‚¬ìš©ìž ëª¨ë“œë¡œ 서버를 실행한 ë’¤ VACUUM ìž‘ì—…ì„ í•˜ì‹­ì‹œì˜¤.\n" +"ë˜í•œ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹ ë˜ëŠ” 롤백하거나, 잠긴 복제 ìŠ¬ë¡¯ì„ ì§€ìš¸ 필요가 있습니다." #: access/transam/varsup.c:131 #, c-format -msgid "" -"database is not accepting commands to avoid wraparound data loss in database " -"with OID %u" -msgstr "" -"%u OID ë°ì´í„°ë² ì´ìФì—서 ìžë£Œ 겹침으로 ë°œìƒí•  수 있는 ìžë£Œ ì†ì‹¤ì„ 방지하기 위" -"í•´ ëª…ë ¹ì„ ìˆ˜ë½í•˜ì§€ 않ìŒ" +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "%u OID ë°ì´í„°ë² ì´ìФì—서 ìžë£Œ 겹침으로 ë°œìƒí•  수 있는 ìžë£Œ ì†ì‹¤ì„ 방지하기 위해 ëª…ë ¹ì„ ìˆ˜ë½í•˜ì§€ 않ìŒ" -#: access/transam/varsup.c:143 access/transam/varsup.c:381 +#: access/transam/varsup.c:143 access/transam/varsup.c:402 #, c-format msgid "database \"%s\" must be vacuumed within %u transactions" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— ì²­ì†Œí•´ì•¼ 합니다" -#: access/transam/varsup.c:150 access/transam/varsup.c:388 +#: access/transam/varsup.c:150 access/transam/varsup.c:409 #, c-format msgid "database with OID %u must be vacuumed within %u transactions" msgstr "%u OID ë°ì´í„°ë² ì´ìŠ¤ëŠ” %uë²ˆì˜ íŠ¸ëžœìž­ì…˜ì´ ë°œìƒë˜ê¸° ì „ì— ì²­ì†Œí•´ì•¼ 합니다" -#: access/transam/varsup.c:346 +#: access/transam/varsup.c:367 #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "트랜잭션 ID 겹침 ì œí•œì€ %u번 입니다., %u OID ë°ì´í„°ë² ì´ìФì—서 제한ë¨" -#: access/transam/xact.c:943 +#: access/transam/xact.c:938 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ 안ì—서는 2^32-2 ê°œì˜ ëª…ë ¹ì„ ì´ˆê³¼í•  수 ì—†ìŒ" -#: access/transam/xact.c:1467 +#: access/transam/xact.c:1463 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "ì»¤ë°‹ëœ í•˜ìœ„ 트랜잭션 수(%d)ê°€ 최대치를 초과함" -#: access/transam/xact.c:2263 +#: access/transam/xact.c:2258 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" msgstr "임시 í…Œì´ë¸”ì— ëŒ€í•´ ì‹¤í–‰ëœ íŠ¸ëžœìž­ì…˜ì„ PREPAREí•  수 ì—†ìŒ" -#: access/transam/xact.c:2273 +#: access/transam/xact.c:2268 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "스냅샷으로 내보낸 íŠ¸ëžœìž­ì…˜ì€ PREPARE ìž‘ì—…ì„ í•  수 ì—†ìŒ" +#: access/transam/xact.c:2277 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "논리 복제 작업ìžë¥¼ 사용하는 íŠ¸ëžœìž­ì…˜ì€ PREPARE í•  수 ì—†ìŒ" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3155 +#: access/transam/xact.c:3162 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s ëª…ë ¹ì€ íŠ¸ëžœìž­ì…˜ 블럭안ì—서 실행할 수 ì—†ìŒ" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3165 +#: access/transam/xact.c:3172 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s ëª…ë ¹ì€ ì„œë¸ŒíŠ¸ëžœìž­ì…˜ 블럭안ì—서 실행할 수 ì—†ìŒ" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3175 +#: access/transam/xact.c:3182 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "%s ëª…ë ¹ì€ í•¨ìˆ˜ë‚˜ 다중명령ì—서 실행할 수 ì—†ìŒ" +msgid "%s cannot be executed from a function" +msgstr "%s ì ˆì€ í•¨ìˆ˜ì—세ㅓ ì‹¤í–‰ë  ìˆ˜ ì—†ìŒ" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3246 +#: access/transam/xact.c:3251 access/transam/xact.c:3875 +#: access/transam/xact.c:3944 access/transam/xact.c:4055 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s ëª…ë ¹ì€ íŠ¸ëžœìž­ì…˜ 블럭ì—서만 ì‚¬ìš©ë  ìˆ˜ 있ìŒ" -#: access/transam/xact.c:3430 +#: access/transam/xact.c:3444 #, c-format msgid "there is already a transaction in progress" msgstr "ì´ë¯¸ 트랜잭션 ìž‘ì—…ì´ ì§„í–‰ 중입니다" -#: access/transam/xact.c:3598 access/transam/xact.c:3701 +#: access/transam/xact.c:3555 access/transam/xact.c:3625 +#: access/transam/xact.c:3734 #, c-format msgid "there is no transaction in progress" msgstr "현재 트랜잭션 ìž‘ì—…ì„ í•˜ì§€ 않고 있습니다" -#: access/transam/xact.c:3609 +#: access/transam/xact.c:3636 #, c-format msgid "cannot commit during a parallel operation" msgstr "ë°ì´í„°ë² ì´ìФ íŠ¸ëžœìž­ì…˜ì„ commit í•  수 ì—†ìŒ" -#: access/transam/xact.c:3712 +#: access/transam/xact.c:3745 #, c-format msgid "cannot abort during a parallel operation" msgstr "병렬 작업 중ì—는 중지 í•  수 ì—†ìŒ" -#: access/transam/xact.c:3754 +#: access/transam/xact.c:3839 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "병렬 작업 중ì—는 savepoint ì§€ì •ì„ í•  수 ì—†ìŒ" -#: access/transam/xact.c:3821 +#: access/transam/xact.c:3926 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "병렬 작업 중ì—는 savepoint를 지울 수 ì—†ìŒ" -#: access/transam/xact.c:3832 access/transam/xact.c:3884 -#: access/transam/xact.c:3890 access/transam/xact.c:3946 -#: access/transam/xact.c:3996 access/transam/xact.c:4002 +#: access/transam/xact.c:3936 access/transam/xact.c:3987 +#: access/transam/xact.c:4047 access/transam/xact.c:4096 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "\"%s\" ì´ë¦„ì˜ ì €ìž¥ìœ„ì¹˜ê°€ ì—†ìŒ" + +#: access/transam/xact.c:3993 access/transam/xact.c:4102 #, c-format -msgid "no such savepoint" -msgstr "그런 savepointê°€ 없습니다" +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "현재 저장위치 수준ì—서 \"%s\" ì´ë¦„ì˜ ì €ìž¥ìœ„ì¹˜ê°€ ì—†ìŒ" -#: access/transam/xact.c:3934 +#: access/transam/xact.c:4035 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "병렬 작업 중ì—는 savepoint 지정 취소 ìž‘ì—…ì„ í•  수 ì—†ìŒ" -#: access/transam/xact.c:4062 +#: access/transam/xact.c:4163 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "병렬 처리 중ì—는 í•˜ìœ„íŠ¸ëžœìž­ì…˜ì„ ì‹œìž‘í•  수 ì—†ìŒ" -#: access/transam/xact.c:4129 +#: access/transam/xact.c:4231 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "병렬 처리 중ì—는 í•˜ìœ„íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹í•  수 ì—†ìŒ" -#: access/transam/xact.c:4737 +#: access/transam/xact.c:4869 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ 안ì—서는 2^32-1 ê°œì˜ í•˜ìœ„íŠ¸ëžœìž­ì…˜ì„ ì´ˆê³¼í•  수 ì—†ìŒ" -#: access/transam/xlog.c:2299 +#: access/transam/xlog.c:2485 #, c-format msgid "could not seek in log file %s to offset %u: %m" msgstr "%s 파ì¼ì—서 %u 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/transam/xlog.c:2319 +#: access/transam/xlog.c:2507 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "%s 로그 íŒŒì¼ ì“°ê¸° 실패, 위치 %u, ê¸¸ì´ %zu: %m" -#: access/transam/xlog.c:2582 +#: access/transam/xlog.c:2785 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "최소 복구 ì§€ì : %X/%X, 타임ë¼ì¸: %u 변경 완료" -#: access/transam/xlog.c:3224 +#: access/transam/xlog.c:3437 #, c-format msgid "not enough data in file \"%s\"" msgstr "\"%s\" 파ì¼ì— ìžë£Œê°€ 불충분합니다" -#: access/transam/xlog.c:3365 +#: access/transam/xlog.c:3582 #, c-format -msgid "could not open transaction log file \"%s\": %m" -msgstr "\"%s\" 트랜잭션 로그 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "could not open write-ahead log file \"%s\": %m" +msgstr "\"%s\" WAL 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:3554 access/transam/xlog.c:5339 +#: access/transam/xlog.c:3771 access/transam/xlog.c:5666 #, c-format msgid "could not close log file %s: %m" msgstr "%s 로그 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/transam/xlog.c:3611 access/transam/xlogutils.c:696 -#: replication/walsender.c:2095 +#: access/transam/xlog.c:3837 access/transam/xlogutils.c:703 +#: replication/walsender.c:2407 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "요청한 %s WAL ì¡°ê° íŒŒì¼ì€ ì´ë¯¸ 지워졌ìŒ" -#: access/transam/xlog.c:3671 access/transam/xlog.c:3746 -#: access/transam/xlog.c:3944 -#, c-format -msgid "could not open transaction log directory \"%s\": %m" -msgstr "\"%s\" 트랜잭션 로그 디렉터리 열기 실패: %m" - -#: access/transam/xlog.c:3827 +#: access/transam/xlog.c:4044 #, c-format -msgid "recycled transaction log file \"%s\"" +msgid "recycled write-ahead log file \"%s\"" msgstr "\"%s\" 트랜잭션 로그 íŒŒì¼ ìž¬í™œìš©í•¨" -#: access/transam/xlog.c:3839 +#: access/transam/xlog.c:4056 #, c-format -msgid "removing transaction log file \"%s\"" +msgid "removing write-ahead log file \"%s\"" msgstr "\"%s\" 트랜잭션 로그 íŒŒì¼ ì‚­ì œ 중" -#: access/transam/xlog.c:3859 +#: access/transam/xlog.c:4076 #, c-format -msgid "could not rename old transaction log file \"%s\": %m" +msgid "could not rename old write-ahead log file \"%s\": %m" msgstr "ì´ì „ 트랜잭션 로그 íŒŒì¼ \"%s\"ì˜ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:3871 -#, c-format -msgid "could not remove old transaction log file \"%s\": %m" -msgstr "ì´ì „ 트랜잭션 로그 íŒŒì¼ \"%s\"ì„(를) 제거할 수 ì—†ìŒ: %m" - -#: access/transam/xlog.c:3904 access/transam/xlog.c:3914 +#: access/transam/xlog.c:4118 access/transam/xlog.c:4128 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "필요한 WAL 디렉터리 \"%s\"ì´(ê°€) ì—†ìŒ" -#: access/transam/xlog.c:3920 +#: access/transam/xlog.c:4134 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "누ë½ëœ WAL 디렉터리 \"%s\"ì„(를) 만드는 중" -#: access/transam/xlog.c:3923 +#: access/transam/xlog.c:4137 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "누ë½ëœ \"%s\" 디렉터리를 만들 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:3954 -#, c-format -msgid "removing transaction log backup history file \"%s\"" -msgstr "\"%s\" 트랜잭션 로그 백업 히스토리 íŒŒì¼ ì‚­ì œ 중" - -#: access/transam/xlog.c:4035 +#: access/transam/xlog.c:4245 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "예ìƒì¹˜ 못한 타임ë¼ì¸ ID %u, 로그 ì¡°ê°: %s, 위치: %u" -#: access/transam/xlog.c:4157 +#: access/transam/xlog.c:4373 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "요청한 %u 타임ë¼ì¸ì€ %u ë°ì´í„°ë² ì´ìФ 시스템 타임ë¼ì¸ì˜ 하위가 아님" -#: access/transam/xlog.c:4171 +#: access/transam/xlog.c:4387 #, c-format -msgid "" -"new timeline %u forked off current database system timeline %u before " -"current recovery point %X/%X" +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" msgstr "" -#: access/transam/xlog.c:4190 +#: access/transam/xlog.c:4406 #, c-format msgid "new target timeline is %u" msgstr "새 ëŒ€ìƒ íƒ€ìž„ë¼ì¸: %u" -#: access/transam/xlog.c:4270 +#: access/transam/xlog.c:4486 #, c-format msgid "could not create control file \"%s\": %m" msgstr "\"%s\" 컨트롤 íŒŒì¼ ë§Œë“¤ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:4281 access/transam/xlog.c:4517 +#: access/transam/xlog.c:4498 access/transam/xlog.c:4752 #, c-format msgid "could not write to control file: %m" msgstr "컨트롤 파ì¼ì„ 쓸 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:4287 access/transam/xlog.c:4523 +#: access/transam/xlog.c:4506 access/transam/xlog.c:4760 #, c-format msgid "could not fsync control file: %m" msgstr "컨트롤 íŒŒì¼ fsync 실패: %m" -#: access/transam/xlog.c:4292 access/transam/xlog.c:4528 +#: access/transam/xlog.c:4512 access/transam/xlog.c:4766 #, c-format msgid "could not close control file: %m" msgstr "컨트롤 íŒŒì¼ ë‹«ê¸° 실패: %m" -#: access/transam/xlog.c:4310 access/transam/xlog.c:4506 +#: access/transam/xlog.c:4531 access/transam/xlog.c:4740 #, c-format msgid "could not open control file \"%s\": %m" msgstr "\"%s\" 컨트롤 íŒŒì¼ ì—´ê¸° 실패: %m" -#: access/transam/xlog.c:4316 +#: access/transam/xlog.c:4541 #, c-format msgid "could not read from control file: %m" msgstr "컨트롤 íŒŒì¼ ì½ê¸° 실패: %m" -#: access/transam/xlog.c:4329 access/transam/xlog.c:4338 -#: access/transam/xlog.c:4362 access/transam/xlog.c:4369 -#: access/transam/xlog.c:4376 access/transam/xlog.c:4381 -#: access/transam/xlog.c:4388 access/transam/xlog.c:4395 -#: access/transam/xlog.c:4402 access/transam/xlog.c:4409 -#: access/transam/xlog.c:4416 access/transam/xlog.c:4423 -#: access/transam/xlog.c:4430 access/transam/xlog.c:4439 -#: access/transam/xlog.c:4446 access/transam/xlog.c:4455 -#: access/transam/xlog.c:4462 access/transam/xlog.c:4471 -#: access/transam/xlog.c:4478 utils/init/miscinit.c:1380 +#: access/transam/xlog.c:4544 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "컨트롤 íŒŒì¼ ì½ê¸° 실패: %d ì½ìŒ, %d ì½ì–´ì•¼ 함" + +#: access/transam/xlog.c:4559 access/transam/xlog.c:4568 +#: access/transam/xlog.c:4592 access/transam/xlog.c:4599 +#: access/transam/xlog.c:4606 access/transam/xlog.c:4611 +#: access/transam/xlog.c:4618 access/transam/xlog.c:4625 +#: access/transam/xlog.c:4632 access/transam/xlog.c:4639 +#: access/transam/xlog.c:4646 access/transam/xlog.c:4653 +#: access/transam/xlog.c:4662 access/transam/xlog.c:4669 +#: access/transam/xlog.c:4678 access/transam/xlog.c:4685 +#: utils/init/miscinit.c:1498 #, c-format msgid "database files are incompatible with server" msgstr "ë°ì´í„°ë² ì´ìФ 파ì¼ë“¤ì´ 서버와 í˜¸í™˜ì„±ì´ ì—†ìŠµë‹ˆë‹¤" -#: access/transam/xlog.c:4330 +#: access/transam/xlog.c:4560 #, c-format -msgid "" -"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), " -"but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” PG_CONTROL_VERSION %d (0x%08x)(으)로 초기화ë˜ì—ˆì§€ë§Œ " -"서버는 PG_CONTROL_VERSION %d (0x%08x)(으)로 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” PG_CONTROL_VERSION %d (0x%08x)(으)로 초기화ë˜ì—ˆì§€ë§Œ 서버는 PG_CONTROL_VERSION %d (0x%08x)(으)로 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4334 +#: access/transam/xlog.c:4564 #, c-format -msgid "" -"This could be a problem of mismatched byte ordering. It looks like you need " -"to initdb." -msgstr "" -"ì´ê²ƒì€ ë°”ì´íЏ 순서 불ì¼ì¹˜ ë¬¸ì œì¼ ìˆ˜ 있습니다. initdb ìž‘ì—…ì´ í•„ìš”í•´ 보입니다." +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "ì´ê²ƒì€ ë°”ì´íЏ 순서 불ì¼ì¹˜ ë¬¸ì œì¼ ìˆ˜ 있습니다. initdb ìž‘ì—…ì´ í•„ìš”í•´ 보입니다." -#: access/transam/xlog.c:4339 +#: access/transam/xlog.c:4569 #, c-format -msgid "" -"The database cluster was initialized with PG_CONTROL_VERSION %d, but the " -"server was compiled with PG_CONTROL_VERSION %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” PG_CONTROL_VERSION %d 버전으로 초기화 ë˜ì—ˆì§€ë§Œ, 서" -"버는 PG_CONTROL_VERSION %d 버전으로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” PG_CONTROL_VERSION %d 버전으로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 PG_CONTROL_VERSION %d 버전으로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4342 access/transam/xlog.c:4366 -#: access/transam/xlog.c:4373 access/transam/xlog.c:4378 +#: access/transam/xlog.c:4572 access/transam/xlog.c:4596 +#: access/transam/xlog.c:4603 access/transam/xlog.c:4608 #, c-format msgid "It looks like you need to initdb." msgstr "initdb ëª…ë ¹ì´ í•„ìš”í•œ 듯 합니다" -#: access/transam/xlog.c:4353 +#: access/transam/xlog.c:4583 #, c-format msgid "incorrect checksum in control file" msgstr "컨트롤 파ì¼ì— ìž˜ëª»ëœ ì²´í¬ì„¬ ê°’ì´ ìžˆìŠµë‹ˆë‹¤" -#: access/transam/xlog.c:4363 +#: access/transam/xlog.c:4593 #, c-format -msgid "" -"The database cluster was initialized with CATALOG_VERSION_NO %d, but the " -"server was compiled with CATALOG_VERSION_NO %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” CATALOG_VERSION_NO %d 버전으로 초기화 ë˜ì—ˆì§€ë§Œ, 서" -"버는 CATALOG_VERSION_NO %d 버전으로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” CATALOG_VERSION_NO %d 버전으로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 CATALOG_VERSION_NO %d 버전으로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4370 +#: access/transam/xlog.c:4600 #, c-format -msgid "" -"The database cluster was initialized with MAXALIGN %d, but the server was " -"compiled with MAXALIGN %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” MAXALIGN %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"MAXALIGN %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” MAXALIGN %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 MAXALIGN %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4377 +#: access/transam/xlog.c:4607 #, c-format -msgid "" -"The database cluster appears to use a different floating-point number format " -"than the server executable." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ì™€ 서버 실행 파ì¼ì´ 서로 다른 ë¶€ë™ ì†Œìˆ˜ì  ìˆ«ìž í˜•ì‹ì„ 사" -"용하고 있습니다." +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ì™€ 서버 실행 파ì¼ì´ 서로 다른 ë¶€ë™ ì†Œìˆ˜ì  ìˆ«ìž í˜•ì‹ì„ 사용하고 있습니다." -#: access/transam/xlog.c:4382 +#: access/transam/xlog.c:4612 #, c-format -msgid "" -"The database cluster was initialized with BLCKSZ %d, but the server was " -"compiled with BLCKSZ %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” BLCKSZ %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 BLCKSZ " -"%d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” BLCKSZ %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 BLCKSZ %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4385 access/transam/xlog.c:4392 -#: access/transam/xlog.c:4399 access/transam/xlog.c:4406 -#: access/transam/xlog.c:4413 access/transam/xlog.c:4420 -#: access/transam/xlog.c:4427 access/transam/xlog.c:4434 -#: access/transam/xlog.c:4442 access/transam/xlog.c:4449 -#: access/transam/xlog.c:4458 access/transam/xlog.c:4465 -#: access/transam/xlog.c:4474 access/transam/xlog.c:4481 +#: access/transam/xlog.c:4615 access/transam/xlog.c:4622 +#: access/transam/xlog.c:4629 access/transam/xlog.c:4636 +#: access/transam/xlog.c:4643 access/transam/xlog.c:4650 +#: access/transam/xlog.c:4657 access/transam/xlog.c:4665 +#: access/transam/xlog.c:4672 access/transam/xlog.c:4681 +#: access/transam/xlog.c:4688 #, c-format msgid "It looks like you need to recompile or initdb." -msgstr "" -"서버를 새로 ì»´íŒŒì¼ í•˜ê±°ë‚˜ initdb ëª…ë ¹ì„ ì‚¬ìš©í•´ 새로 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ " -"다시 만들거나 해야할 것 같습니다." +msgstr "서버를 새로 ì»´íŒŒì¼ í•˜ê±°ë‚˜ initdb ëª…ë ¹ì„ ì‚¬ìš©í•´ 새로 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 다시 만들거나 해야할 것 같습니다." -#: access/transam/xlog.c:4389 +#: access/transam/xlog.c:4619 #, c-format -msgid "" -"The database cluster was initialized with RELSEG_SIZE %d, but the server was " -"compiled with RELSEG_SIZE %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” RELSEG_SIZE %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"RELSEG_SIZE %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” RELSEG_SIZE %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 RELSEG_SIZE %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4396 +#: access/transam/xlog.c:4626 #, c-format -msgid "" -"The database cluster was initialized with XLOG_BLCKSZ %d, but the server was " -"compiled with XLOG_BLCKSZ %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” XLOG_BLCKSZ %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"XLOG_BLCKSZ %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” XLOG_BLCKSZ %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 XLOG_BLCKSZ %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4403 +#: access/transam/xlog.c:4633 #, c-format -msgid "" -"The database cluster was initialized with XLOG_SEG_SIZE %d, but the server " -"was compiled with XLOG_SEG_SIZE %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” XLOG_SEG_SIZE %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"XLOG_SEG_SIZE %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” NAMEDATALEN %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 NAMEDATALEN %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4410 +#: access/transam/xlog.c:4640 #, c-format -msgid "" -"The database cluster was initialized with NAMEDATALEN %d, but the server was " -"compiled with NAMEDATALEN %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” NAMEDATALEN %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"NAMEDATALEN %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” INDEX_MAX_KEYS %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 INDEX_MAX_KEYS %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4417 +#: access/transam/xlog.c:4647 #, c-format -msgid "" -"The database cluster was initialized with INDEX_MAX_KEYS %d, but the server " -"was compiled with INDEX_MAX_KEYS %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” INDEX_MAX_KEYS %d (으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"INDEX_MAX_KEYS %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” TOAST_MAX_CHUNK_SIZE %d(으)로 초기화ë˜ì—ˆì§€ë§Œ 서버는 TOAST_MAX_CHUNK_SIZE %d(으)로 ì»´íŒŒì¼ ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4424 +#: access/transam/xlog.c:4654 #, c-format -msgid "" -"The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the " -"server was compiled with TOAST_MAX_CHUNK_SIZE %d." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” TOAST_MAX_CHUNK_SIZE %d(으)로 초기화ë˜ì—ˆì§€ë§Œ 서버는 " -"TOAST_MAX_CHUNK_SIZE %d(으)로 ì»´íŒŒì¼ ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” LOBLKSIZE %d(으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 LOBLKSIZE %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4431 +#: access/transam/xlog.c:4663 #, c-format -msgid "" -"The database cluster was initialized with LOBLKSIZE %d, but the server was " -"compiled with LOBLKSIZE %d." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” LOBLKSIZE %d(으)로 초기화 ë˜ì—ˆì§€ë§Œ, 서버는 " -"LOBLKSIZE %d (으)로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT4_BYVAL ì—†ì´ ì´ˆê¸°í™”ë˜ì—ˆì§€ë§Œ, 서버는 USE_FLOAT4_BYVALì„ ì‚¬ìš©í•˜ì—¬ 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4440 +#: access/transam/xlog.c:4670 #, c-format -msgid "" -"The database cluster was initialized without HAVE_INT64_TIMESTAMP but the " -"server was compiled with HAVE_INT64_TIMESTAMP." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” HAVE_INT64_TIMESTAMP ê°’ì´ false로 초기화 ë˜ì—ˆì§€" -"ë§Œ, 서버는 HAVE_INT64_TIMESTAMP ê°’ì´ true로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT4_BYVALì„ ì‚¬ìš©í•˜ì—¬ 초기화ë˜ì—ˆì§€ë§Œ, 서버는 USE_FLOAT4_BYVAL ì—†ì´ ì»´íŒŒì¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4447 +#: access/transam/xlog.c:4679 #, c-format -msgid "" -"The database cluster was initialized with HAVE_INT64_TIMESTAMP but the " -"server was compiled without HAVE_INT64_TIMESTAMP." -msgstr "" -"ì´ ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” HAVE_INT64_TIMESTAMP ê°’ì´ true로 초기화 ë˜ì—ˆì§€ë§Œ, " -"서버는 HAVE_INT64_TIMESTAMP ê°’ì´ false로 ì»´íŒŒì¼ ë˜ì–´ìžˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT8_BYVAL ì—†ì´ ì´ˆê¸°í™”ë˜ì—ˆì§€ë§Œ, 서버는 USE_FLOAT8_BYVALì„ ì‚¬ìš©í•˜ì—¬ 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4456 +#: access/transam/xlog.c:4686 #, c-format -msgid "" -"The database cluster was initialized without USE_FLOAT4_BYVAL but the server " -"was compiled with USE_FLOAT4_BYVAL." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT4_BYVAL ì—†ì´ ì´ˆê¸°í™”ë˜ì—ˆì§€ë§Œ, 서버는 " -"USE_FLOAT4_BYVALì„ ì‚¬ìš©í•˜ì—¬ 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT8_BYVALì„ ì‚¬ìš©í•˜ì—¬ 초기화ë˜ì—ˆì§€ë§Œ, 서버는 USE_FLOAT8_BYVAL ì—†ì´ ì»´íŒŒì¼ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:4463 +#: access/transam/xlog.c:4695 #, c-format -msgid "" -"The database cluster was initialized with USE_FLOAT4_BYVAL but the server " -"was compiled without USE_FLOAT4_BYVAL." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT4_BYVALì„ ì‚¬ìš©í•˜ì—¬ 초기화ë˜ì—ˆì§€ë§Œ, 서버는 " -"USE_FLOAT4_BYVAL ì—†ì´ ì»´íŒŒì¼ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL ì¡°ê° íŒŒì¼ì€ 1MB부터 1GB ì‚¬ì´ 2^n í¬ê¸°ì—¬ì•¼ 하지만, 컨트롤 파ì¼ì—는 %d ë°”ì´íŠ¸ë¡œ 지정ë˜ì—ˆìŒ" -#: access/transam/xlog.c:4472 +#: access/transam/xlog.c:4707 #, c-format -msgid "" -"The database cluster was initialized without USE_FLOAT8_BYVAL but the server " -"was compiled with USE_FLOAT8_BYVAL." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT8_BYVAL ì—†ì´ ì´ˆê¸°í™”ë˜ì—ˆì§€ë§Œ, 서버는 " -"USE_FLOAT8_BYVALì„ ì‚¬ìš©í•˜ì—¬ 컴파ì¼ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"." +msgstr "\"min_wal_size\" ê°’ì€ \"wal_segment_size\" ê°’ì˜ ìµœì†Œ 2ë°° ì´ìƒì´ì–´ì•¼ 함" -#: access/transam/xlog.c:4479 +#: access/transam/xlog.c:4711 #, c-format -msgid "" -"The database cluster was initialized with USE_FLOAT8_BYVAL but the server " -"was compiled without USE_FLOAT8_BYVAL." -msgstr "" -"ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” USE_FLOAT8_BYVALì„ ì‚¬ìš©í•˜ì—¬ 초기화ë˜ì—ˆì§€ë§Œ, 서버는 " -"USE_FLOAT8_BYVAL ì—†ì´ ì»´íŒŒì¼ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"." +msgstr "\"man_wal_size\" ê°’ì€ \"wal_segment_size\" ê°’ì˜ ìµœì†Œ 2ë°° ì´ìƒì´ì–´ì•¼ 함" + +#: access/transam/xlog.c:5098 +#, c-format +msgid "could not generate secret authorization token" +msgstr "비밀 ì¸ì¦ 토í°ì„ 만들 수 ì—†ìŒ" -#: access/transam/xlog.c:4900 +#: access/transam/xlog.c:5188 #, c-format -msgid "could not write bootstrap transaction log file: %m" +msgid "could not write bootstrap write-ahead log file: %m" msgstr "bootstrap 트랜잭션 로그 파ì¼ì„ 쓸 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:4906 +#: access/transam/xlog.c:5196 #, c-format -msgid "could not fsync bootstrap transaction log file: %m" +msgid "could not fsync bootstrap write-ahead log file: %m" msgstr "bootstrap 트랜잭션 로그 파ì¼ì„ fsyncí•  수 ì—†ìŒ: %m" -#: access/transam/xlog.c:4911 +#: access/transam/xlog.c:5202 #, c-format -msgid "could not close bootstrap transaction log file: %m" +msgid "could not close bootstrap write-ahead log file: %m" msgstr "bootstrap 트랜잭션 로그 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: access/transam/xlog.c:4986 +#: access/transam/xlog.c:5284 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "복구명령 íŒŒì¼ \"%s\"ì„ ì—´ 수 없습니다: %m" -#: access/transam/xlog.c:5032 access/transam/xlog.c:5117 +#: access/transam/xlog.c:5330 access/transam/xlog.c:5444 #, c-format msgid "invalid value for recovery parameter \"%s\": \"%s\"" msgstr "ìž˜ëª»ëœ \"%s\" 복구 매개 ë³€ìˆ˜ì˜ ê°’: \"%s\"" -#: access/transam/xlog.c:5035 +#: access/transam/xlog.c:5333 #, c-format msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." msgstr "사용할 수 있는 ê°’: \"pause\", \"promote\", \"shutdown\"" -#: access/transam/xlog.c:5055 +#: access/transam/xlog.c:5353 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" msgstr "recovery_target_timeline 값으로 ìž˜ëª»ëœ ìˆ«ìž: \"%s\"" -#: access/transam/xlog.c:5072 +#: access/transam/xlog.c:5370 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" msgstr "recovery_target_xid 값으로 ìž˜ëª»ëœ ìˆ«ìž: \"%s\"" -#: access/transam/xlog.c:5103 +#: access/transam/xlog.c:5390 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_time ê°’ì´ ìž˜ëª»ëœ íƒ€ìž„ìŠ¤íƒ¬í”„ìž„: \"%s\"" + +#: access/transam/xlog.c:5413 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "recovery_target_name ì„¤ì •ê°’ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤ (최대 %d 문ìž)" -#: access/transam/xlog.c:5120 +#: access/transam/xlog.c:5447 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "ì´ ê°’ìœ¼ë¡œëŠ” \"immediate\" ë§Œ 허용합니다." -#: access/transam/xlog.c:5133 access/transam/xlog.c:5144 -#: commands/extension.c:534 commands/extension.c:542 utils/misc/guc.c:5640 +#: access/transam/xlog.c:5460 access/transam/xlog.c:5471 +#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5983 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "\"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ì€ boolean ê°’ì´ì–´ì•¼í•©ë‹ˆë‹¤." -#: access/transam/xlog.c:5179 +#: access/transam/xlog.c:5506 #, c-format msgid "parameter \"%s\" requires a temporal value" msgstr "\"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ì€ ì‹œê°„ê°’ì´ì–´ì•¼ 합니다." -#: access/transam/xlog.c:5181 catalog/dependency.c:990 -#: catalog/dependency.c:991 catalog/dependency.c:997 catalog/dependency.c:998 -#: catalog/dependency.c:1009 catalog/dependency.c:1010 -#: catalog/objectaddress.c:1100 commands/tablecmds.c:796 -#: commands/tablecmds.c:9542 commands/user.c:1045 commands/view.c:499 -#: libpq/auth.c:307 replication/syncrep.c:919 storage/lmgr/deadlock.c:1139 -#: storage/lmgr/proc.c:1278 utils/adt/acl.c:5281 utils/misc/guc.c:5662 -#: utils/misc/guc.c:5755 utils/misc/guc.c:9708 utils/misc/guc.c:9742 -#: utils/misc/guc.c:9776 utils/misc/guc.c:9810 utils/misc/guc.c:9845 +#: access/transam/xlog.c:5508 catalog/dependency.c:969 catalog/dependency.c:970 +#: catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 +#: catalog/dependency.c:989 commands/tablecmds.c:1069 +#: commands/tablecmds.c:10804 commands/user.c:1064 commands/view.c:505 +#: libpq/auth.c:336 replication/syncrep.c:1158 storage/lmgr/deadlock.c:1139 +#: storage/lmgr/proc.c:1324 utils/adt/acl.c:5269 utils/misc/guc.c:6005 +#: utils/misc/guc.c:6098 utils/misc/guc.c:10088 utils/misc/guc.c:10122 +#: utils/misc/guc.c:10156 utils/misc/guc.c:10190 utils/misc/guc.c:10225 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlog.c:5188 +#: access/transam/xlog.c:5515 #, c-format msgid "unrecognized recovery parameter \"%s\"" msgstr "알 수 없는 복구 매개 변수 ì´ë¦„: \"%s\"" -#: access/transam/xlog.c:5199 +#: access/transam/xlog.c:5526 #, c-format -msgid "" -"recovery command file \"%s\" specified neither primary_conninfo nor " -"restore_command" -msgstr "" -"복구 명령 íŒŒì¼ \"%s\"ì—서 primary_conninfo 설정ë„, restore_command ì„¤ì •ë„ ì—†" -"습니다." +msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" +msgstr "복구 명령 íŒŒì¼ \"%s\"ì—서 primary_conninfo 설정ë„, restore_command ì„¤ì •ë„ ì—†ìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:5201 +#: access/transam/xlog.c:5528 #, c-format -msgid "" -"The database server will regularly poll the pg_xlog subdirectory to check " -"for files placed there." -msgstr "" -"ë°ì´í„°ë² ì´ìФ 서버는 ì¼ë°˜ì ìœ¼ë¡œ 주 서버ì—서 ë°œìƒí•œ 트랜잭션 로그를 ë°˜ì˜í•˜ê¸° 위" -"í•´ pg_xlog 하위 디렉터리를 조사할 것입니다." +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "ë°ì´í„°ë² ì´ìФ 서버는 ì¼ë°˜ì ìœ¼ë¡œ 주 서버ì—서 ë°œìƒí•œ 트랜잭션 로그를 ë°˜ì˜í•˜ê¸° 위해 pg_wal 하위 디렉터리를 조사할 것입니다." -#: access/transam/xlog.c:5208 +#: access/transam/xlog.c:5535 #, c-format -msgid "" -"recovery command file \"%s\" must specify restore_command when standby mode " -"is not enabled" -msgstr "" -"대기 모드를 활성화 하지 않았다면(standby_mode = off), 복구 명령 íŒŒì¼ \"%s\"ì—" -"서 restore_command ì„¤ì •ì€ ë°˜ë“œì‹œ 있어야 합니다." +msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" +msgstr "대기 모드를 활성화 하지 않았다면(standby_mode = off), 복구 명령 íŒŒì¼ \"%s\"ì—서 restore_command ì„¤ì •ì€ ë°˜ë“œì‹œ 있어야 합니다." -#: access/transam/xlog.c:5229 +#: access/transam/xlog.c:5556 #, c-format msgid "standby mode is not supported by single-user servers" msgstr "ë‹¨ì¼ ì‚¬ìš©ìž ì„œë²„ë¥¼ 대ìƒìœ¼ë¡œ 대기 모드를 사용할 수 없습니다." -#: access/transam/xlog.c:5248 +#: access/transam/xlog.c:5575 #, c-format msgid "recovery target timeline %u does not exist" msgstr "%u 복구 ëŒ€ìƒ íƒ€ìž„ë¼ì¸ì´ ì—†ìŒ" -#: access/transam/xlog.c:5369 +#: access/transam/xlog.c:5696 #, c-format msgid "archive recovery complete" msgstr "ì•„ì¹´ì´ë¸Œ 복구 완료" -#: access/transam/xlog.c:5428 access/transam/xlog.c:5656 +#: access/transam/xlog.c:5755 access/transam/xlog.c:6021 #, c-format msgid "recovery stopping after reaching consistency" msgstr "ì¼ê´€ì„±ì„ 다 맞추어 복구 ìž‘ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." -#: access/transam/xlog.c:5516 +#: access/transam/xlog.c:5776 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "복구 중지 위치(LSN): \"%X/%X\" ì´ì „" + +#: access/transam/xlog.c:5862 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "%u 트랜잭션 커밋 ì „ 복구 중지함, 시간 %s" -#: access/transam/xlog.c:5523 +#: access/transam/xlog.c:5869 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "%u 트랜잭션 중단 ì „ 복구 중지함, 시간 %s" -#: access/transam/xlog.c:5568 +#: access/transam/xlog.c:5915 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "복구 중지함, 복구 위치 \"%s\", 시간 %s" -#: access/transam/xlog.c:5636 +#: access/transam/xlog.c:5933 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "복구 중지 위치(LSN): \"%X/%X\" ì´í›„" + +#: access/transam/xlog.c:6001 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "%u 트랜잭션 커밋 후 복구 중지함, 시간 %s" -#: access/transam/xlog.c:5644 +#: access/transam/xlog.c:6009 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "%u 트랜잭션 중단 후 복구 중지함, 시간 %s" -#: access/transam/xlog.c:5683 +#: access/transam/xlog.c:6049 #, c-format msgid "recovery has paused" msgstr "복구 ìž‘ì—…ì´ ì¼ì‹œ 중지 ë¨" -#: access/transam/xlog.c:5684 +#: access/transam/xlog.c:6050 #, c-format -msgid "Execute pg_xlog_replay_resume() to continue." -msgstr "ê³„ì† ì§„í–‰í•˜ë ¤ë©´, pg_xlog_replay_resume() 함수를 호출하세요." +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "ê³„ì† ì§„í–‰í•˜ë ¤ë©´, pg_wal_replay_resume() 함수를 호출하세요." -#: access/transam/xlog.c:5891 +#: access/transam/xlog.c:6258 #, c-format -msgid "" -"hot standby is not possible because %s = %d is a lower setting than on the " -"master server (its value was %d)" -msgstr "" -"ì½ê¸° ì „ìš© 대기 서버로 ìš´ì˜ì´ 불가능합니다. 현재 %s = %d ì„¤ì •ì€ ì£¼ ì„œë²„ì˜ ì„¤ì •" -"ê°’(%d)보다 낮게 설정 ë˜ì–´ 있기 때문입니다." +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "ì½ê¸° ì „ìš© 대기 서버로 ìš´ì˜ì´ 불가능합니다. 현재 %s = %d ì„¤ì •ì€ ì£¼ ì„œë²„ì˜ ì„¤ì •ê°’(%d)보다 낮게 설정 ë˜ì–´ 있기 때문입니다." -#: access/transam/xlog.c:5917 +#: access/transam/xlog.c:6284 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" -msgstr "" -"WAL ë‚´ìš©ì´ wal_level=minimal 설정으로 만들여졌습니다. ìžë£Œê°€ ì†ì‹¤ ë  ìˆ˜ 있습" -"니다." +msgstr "WAL ë‚´ìš©ì´ wal_level=minimal 설정으로 만들여졌습니다. ìžë£Œê°€ ì†ì‹¤ ë  ìˆ˜ 있습니다." -#: access/transam/xlog.c:5918 +#: access/transam/xlog.c:6285 #, c-format -msgid "" -"This happens if you temporarily set wal_level=minimal without taking a new " -"base backup." -msgstr "" -"ì´ ë¬¸ì œëŠ” 새 ë² ì´ìФ ë°±ì—…ì„ ë°›ì§€ ì•Šì€ ìƒíƒœì—서 서버가 ì¼ì‹œì ìœ¼ë¡œ " -"wal_level=minimal 설정으로 ìš´ì˜ëœ ì ì´ 있다면 ë°œìƒí•©ë‹ˆë‹¤." +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "ì´ ë¬¸ì œëŠ” 새 ë² ì´ìФ ë°±ì—…ì„ ë°›ì§€ ì•Šì€ ìƒíƒœì—서 서버가 ì¼ì‹œì ìœ¼ë¡œ wal_level=minimal 설정으로 ìš´ì˜ëœ ì ì´ 있다면 ë°œìƒí•©ë‹ˆë‹¤." -#: access/transam/xlog.c:5929 +#: access/transam/xlog.c:6296 #, c-format -msgid "" -"hot standby is not possible because wal_level was not set to \"replica\" or " -"higher on the master server" -msgstr "" -"주 서버 wal_level ì„¤ì •ì´ \"replica\" ë˜ëŠ” ê·¸ ì´ìƒ 수준으로 설정ë˜ì§€ 않아, ì½" -"기 ì „ìš© ë³´ì¡° 서버로 ìš´ì˜ë  수 ì—†ìŒ" +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "주 서버 wal_level ì„¤ì •ì´ \"replica\" ë˜ëŠ” ê·¸ ì´ìƒ 수준으로 설정ë˜ì§€ 않아, ì½ê¸° ì „ìš© ë³´ì¡° 서버로 ìš´ì˜ë  수 ì—†ìŒ" -#: access/transam/xlog.c:5930 +#: access/transam/xlog.c:6297 #, c-format -msgid "" -"Either set wal_level to \"replica\" on the master, or turn off hot_standby " -"here." -msgstr "" -"ìš´ì˜ ì„œë²„ì˜ í™˜ê²½ 설정ì—서 wal_leve = \"replica\" 형태로 지정하든가 " -"hot_standby = off 형태로 지정하십시오." +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "ìš´ì˜ ì„œë²„ì˜ í™˜ê²½ 설정ì—서 wal_leve = \"replica\" 형태로 지정하든가 hot_standby = off 형태로 지정하십시오." -#: access/transam/xlog.c:5987 +#: access/transam/xlog.c:6349 #, c-format msgid "control file contains invalid data" msgstr "컨트롤 파ì¼ì— ìž˜ëª»ëœ ë°ì´í„°ê°€ 있습니다" -#: access/transam/xlog.c:5993 +#: access/transam/xlog.c:6355 #, c-format msgid "database system was shut down at %s" msgstr "ë°ì´í„°ë² ì´ìФ 시스템 마지막 ê°€ë™ ì¤‘ì§€ 시ê°: %s" -#: access/transam/xlog.c:5998 +#: access/transam/xlog.c:6360 #, c-format msgid "database system was shut down in recovery at %s" msgstr "복구 중 ë°ì´í„°ë² ì´ìФ 시스템 마지막 ê°€ë™ ì¤‘ì§€ 시ê°: %s" -#: access/transam/xlog.c:6002 +#: access/transam/xlog.c:6364 #, c-format msgid "database system shutdown was interrupted; last known up at %s" -msgstr "" -"ë°ì´í„°ë² ì´ìФ 시스템 셧다운 ìž‘ì—…ì´ ë¹„ì •ìƒì ìœ¼ë¡œ 종료ë˜ì—ˆìŒ; 마지막 ìš´ì˜ì‹œê°„: " -"%s" +msgstr "ë°ì´í„°ë² ì´ìФ 시스템 셧다운 ìž‘ì—…ì´ ë¹„ì •ìƒì ìœ¼ë¡œ 종료ë˜ì—ˆìŒ; 마지막 ìš´ì˜ì‹œê°„: %s" -#: access/transam/xlog.c:6006 +#: access/transam/xlog.c:6368 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "ë°ì´í„°ë² ì´ìФ 시스템 복구하는 ë„중 비정ìƒì ìœ¼ë¡œ ê°€ë™ ì¤‘ì§€ëœ ì‹œê°: %s" -#: access/transam/xlog.c:6008 +#: access/transam/xlog.c:6370 #, c-format -msgid "" -"This probably means that some data is corrupted and you will have to use the " -"last backup for recovery." -msgstr "" -"ì´ ì‚¬íƒœëŠ” 몇몇 ë°ì´í„°ê°€ ì†ìƒë˜ì—ˆì„ ì˜ë¯¸í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 확ì¸í•´ ë³´ê³ , 필요하" -"다면, 마지막 백업 ìžë£Œë¡œ 복구해서 사용하세요." +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "ì´ ì‚¬íƒœëŠ” 몇몇 ë°ì´í„°ê°€ ì†ìƒë˜ì—ˆì„ ì˜ë¯¸í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 확ì¸í•´ ë³´ê³ , 필요하다면, 마지막 백업 ìžë£Œë¡œ 복구해서 사용하세요." -#: access/transam/xlog.c:6012 +#: access/transam/xlog.c:6374 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ë¡œê·¸ 시간 %sì— ë³µêµ¬ ë„중 중지 ë˜ì—ˆìŒ" -#: access/transam/xlog.c:6014 +#: access/transam/xlog.c:6376 #, c-format -msgid "" -"If this has occurred more than once some data might be corrupted and you " -"might need to choose an earlier recovery target." -msgstr "" -"ì´ ì‚¬íƒœë¡œ 몇몇 ìžë£Œê°€ ì†ìƒë˜ì—ˆì„ ìˆ˜ë„ ìžˆëŠ”ë°, ì´ëŸ° 경우ë¼ë©´,확ì¸í•´ ë³´ê³ , í•„ìš”" -"하다면, 마지막 백업 ìžë£Œë¡œ 복구해서 사용하세요." +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "ì´ ì‚¬íƒœë¡œ 몇몇 ìžë£Œê°€ ì†ìƒë˜ì—ˆì„ ìˆ˜ë„ ìžˆëŠ”ë°, ì´ëŸ° 경우ë¼ë©´,확ì¸í•´ ë³´ê³ , 필요하다면, 마지막 백업 ìžë£Œë¡œ 복구해서 사용하세요." -#: access/transam/xlog.c:6018 +#: access/transam/xlog.c:6380 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ë¹„ì •ìƒì ìœ¼ë¡œ 종료ë˜ì—ˆìŒ; 마지막 ìš´ì˜ì‹œê°„: %s" -#: access/transam/xlog.c:6074 +#: access/transam/xlog.c:6436 #, c-format msgid "entering standby mode" msgstr "대기 모드로 전환합니다" -#: access/transam/xlog.c:6077 +#: access/transam/xlog.c:6439 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "%u XID까지 ì‹œì  ê¸°ë°˜ 복구 ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6081 +#: access/transam/xlog.c:6443 #, c-format msgid "starting point-in-time recovery to %s" msgstr "%s 까지 ì‹œì  ë³µêµ¬ ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6085 +#: access/transam/xlog.c:6447 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "\"%s\" 복구 ëŒ€ìƒ ì´ë¦„까지 ì‹œì  ë³µêµ¬ ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6089 +#: access/transam/xlog.c:6451 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "\"%X/%X\" 위치(LSN)까지 ì‹œì  ë³µêµ¬ ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" + +#: access/transam/xlog.c:6456 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "ë™ê¸°í™” í•  수 있는 마지막 ì§€ì ê¹Œì§€ ì‹œì  ë³µêµ¬ ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6092 +#: access/transam/xlog.c:6459 #, c-format msgid "starting archive recovery" msgstr "ì•„ì¹´ì´ë¸Œ 복구 ìž‘ì—…ì„ ì‹œìž‘í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6136 access/transam/xlog.c:6264 +#: access/transam/xlog.c:6513 access/transam/xlog.c:6638 #, c-format msgid "checkpoint record is at %X/%X" msgstr "ì²´í¬í¬ì¸íЏ 레코드 위치: %X/%X" -#: access/transam/xlog.c:6150 +#: access/transam/xlog.c:6527 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "ì²´í¬í¬ì¸íЏ 기ë¡ìœ¼ë¡œ 참조하는 재실행 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: access/transam/xlog.c:6151 access/transam/xlog.c:6158 +#: access/transam/xlog.c:6528 access/transam/xlog.c:6535 #, c-format -msgid "" -"If you are not restoring from a backup, try removing the file \"%s/" -"backup_label\"." -msgstr "" -"실시간 백업 ìžë£Œë¡œë¶€í„° 복구 ìž‘ì—…ì„ í•˜ì§€ 않으려면, \"%s/backup_lable\" 파ì¼ì„ " -"ì‚­ì œ 하세요." +msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." +msgstr "실시간 백업 ìžë£Œë¡œë¶€í„° 복구 ìž‘ì—…ì„ í•˜ì§€ 않으려면, \"%s/backup_lable\" 파ì¼ì„ ì‚­ì œ 하세요." -#: access/transam/xlog.c:6157 +#: access/transam/xlog.c:6534 #, c-format msgid "could not locate required checkpoint record" msgstr "ìš”ì²­ëœ ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì˜ ìœ„ì¹˜ë¥¼ 바르게 ìž¡ì„ ìˆ˜ ì—†ìŒ" -#: access/transam/xlog.c:6183 commands/tablespace.c:641 +#: access/transam/xlog.c:6560 commands/tablespace.c:641 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "\"%s\" 심벌릭 ë§í¬ë¥¼ 만들 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:6215 access/transam/xlog.c:6221 +#: access/transam/xlog.c:6592 access/transam/xlog.c:6598 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "\"%s\" íŒŒì¼ ë¬´ì‹œí•¨, \"%s\" íŒŒì¼ ì—†ìŒ" -#: access/transam/xlog.c:6217 access/transam/xlog.c:11032 +#: access/transam/xlog.c:6594 access/transam/xlog.c:11605 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿¨ìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:6223 +#: access/transam/xlog.c:6600 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:6274 access/transam/xlog.c:6289 +#: access/transam/xlog.c:6650 #, c-format msgid "could not locate a valid checkpoint record" msgstr "ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì˜ ìœ„ì¹˜ë¥¼ 바르게 ìž¡ì„ ìˆ˜ ì—†ìŒ" -#: access/transam/xlog.c:6283 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "ì´ì „ ì²´í¬í¬ì¸íЏ 레코드를 사용함, 위치: %X/%X" - -#: access/transam/xlog.c:6327 +#: access/transam/xlog.c:6688 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "요청한 %u 타임ë¼ì¸ì€ 서버 타임ë¼ì¸ì˜ 하위가 아님" -#: access/transam/xlog.c:6329 +#: access/transam/xlog.c:6690 #, c-format -msgid "" -"Latest checkpoint is at %X/%X on timeline %u, but in the history of the " -"requested timeline, the server forked off from that timeline at %X/%X." -msgstr "" -"마지막 ì²´í¬í¬ì¸íЏ 위치는 %X/%X (%u 타임ë¼ì¸)입니다. 하지만, ìš”ì²­ë°›ì€ íƒ€ìž„ë¼" -"ì¸ ë‚´ì—­íŒŒì¼ì—는 ê·¸ 타임ë¼ì¸ %X/%X 위치ì—서 분기ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "마지막 ì²´í¬í¬ì¸íЏ 위치는 %X/%X (%u 타임ë¼ì¸)입니다. 하지만, ìš”ì²­ë°›ì€ íƒ€ìž„ë¼ì¸ 내역파ì¼ì—는 ê·¸ 타임ë¼ì¸ %X/%X 위치ì—서 분기ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:6345 +#: access/transam/xlog.c:6706 #, c-format -msgid "" -"requested timeline %u does not contain minimum recovery point %X/%X on " -"timeline %u" -msgstr "" -"요청한 %u 타임ë¼ì¸ì€ %X/%X 최소 복구 위치가 없습니다, 기존 타임ë¼ì¸: %u" +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "요청한 %u 타임ë¼ì¸ì€ %X/%X 최소 복구 위치가 없습니다, 기존 타임ë¼ì¸: %u" -#: access/transam/xlog.c:6376 +#: access/transam/xlog.c:6737 #, c-format msgid "invalid next transaction ID" msgstr "ìž˜ëª»ëœ ë‹¤ìŒ íŠ¸ëžœìž­ì…˜ ID" -#: access/transam/xlog.c:6459 +#: access/transam/xlog.c:6831 #, c-format msgid "invalid redo in checkpoint record" msgstr "ì²´í¬í¬ì¸íЏ 레코드 ì•ˆì— ìž˜ëª»ëœ redo ì •ë³´ê°€ 있ìŒ" -#: access/transam/xlog.c:6470 +#: access/transam/xlog.c:6842 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "ìš´ì˜ ì¤‘ì§€ ì²´í¬í¬ì¸íЏì—서 ìž˜ëª»ëœ ìž¬ì‹¤í–‰ ì •ë³´ 발견" -#: access/transam/xlog.c:6498 +#: access/transam/xlog.c:6870 #, c-format -msgid "" -"database system was not properly shut down; automatic recovery in progress" -msgstr "" -"ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì •ìƒì ìœ¼ë¡œ 종료ë˜ì§€ 못했습니다, ìžë™ 복구 ìž‘ì—…ì„ ì§„í–‰í•©" -"니다" +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì •ìƒì ìœ¼ë¡œ 종료ë˜ì§€ 못했습니다, ìžë™ 복구 ìž‘ì—…ì„ ì§„í–‰í•©ë‹ˆë‹¤" -#: access/transam/xlog.c:6502 +#: access/transam/xlog.c:6874 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" -msgstr "" -"%u 타임ë¼ì¸ìœ¼ë¡œ ë¹„ì •ìƒ ì¤‘ì§€ì— ëŒ€í•œ ë³µêµ¬ìž‘ì—…ì„ ì‹œìž‘í•¨, 기존 타임ë¼ì¸: %u" +msgstr "%u 타임ë¼ì¸ìœ¼ë¡œ ë¹„ì •ìƒ ì¤‘ì§€ì— ëŒ€í•œ ë³µêµ¬ìž‘ì—…ì„ ì‹œìž‘í•¨, 기존 타임ë¼ì¸: %u" -#: access/transam/xlog.c:6546 +#: access/transam/xlog.c:6917 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label íŒŒì¼ ì•ˆì— ì»¨íŠ¸ë¡¤ 파ì¼ê³¼ ì¼ê´€ì„±ì´ ë§žì§€ 않는 ìžë£Œê°€ 있ìŒ" -#: access/transam/xlog.c:6547 +#: access/transam/xlog.c:6918 #, c-format -msgid "" -"This means that the backup is corrupted and you will have to use another " -"backup for recovery." -msgstr "" -"ì´ ë¬¸ì œëŠ” 백업 ìžë£Œ ìžì²´ê°€ ì†ìƒ ë˜ì—ˆìŒì„ ë§í•©ë‹ˆë‹¤. 다른 백업본으로 복구 작업" -"ì„ ì§„í–‰í•´ì•¼ 합니다." +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "ì´ ë¬¸ì œëŠ” 백업 ìžë£Œ ìžì²´ê°€ ì†ìƒ ë˜ì—ˆìŒì„ ë§í•©ë‹ˆë‹¤. 다른 백업본으로 복구 ìž‘ì—…ì„ ì§„í–‰í•´ì•¼ 합니다." -#: access/transam/xlog.c:6621 +#: access/transam/xlog.c:7009 #, c-format msgid "initializing for hot standby" msgstr "ì½ê¸° ì „ìš© ë³´ì¡° 서버로 초기화 중입니다." -#: access/transam/xlog.c:6753 +#: access/transam/xlog.c:7141 #, c-format msgid "redo starts at %X/%X" msgstr "%X/%Xì—서 redo 작업 시작ë¨" -#: access/transam/xlog.c:6978 +#: access/transam/xlog.c:7375 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "요청한 복구 중지 ì§€ì ì´ ì¼ì¹˜í•˜ëŠ” 복구 ì§€ì  ì•žì— ìžˆìŒ" -#: access/transam/xlog.c:7016 +#: access/transam/xlog.c:7413 #, c-format msgid "redo done at %X/%X" msgstr "%X/%Xì—서 redo 작업 완료" -#: access/transam/xlog.c:7021 access/transam/xlog.c:8969 +#: access/transam/xlog.c:7418 #, c-format msgid "last completed transaction was at log time %s" msgstr "마지막 ì™„ë£Œëœ íŠ¸ëžœìž­ì…˜ ê¸°ë¡ ì‹œê°„: %s" -#: access/transam/xlog.c:7030 +#: access/transam/xlog.c:7427 #, c-format msgid "redo is not required" msgstr "재반ì˜í•´ì•¼ í•  íŠ¸ëžœìž­ì…˜ì´ ì—†ìŒ" -#: access/transam/xlog.c:7105 access/transam/xlog.c:7109 +#: access/transam/xlog.c:7502 access/transam/xlog.c:7506 #, c-format msgid "WAL ends before end of online backup" msgstr "온ë¼ì¸ 백업 작업 ëë‚˜ê¸°ì „ì— WAL 작업 종료ë¨" -#: access/transam/xlog.c:7106 +#: access/transam/xlog.c:7503 #, c-format -msgid "" -"All WAL generated while online backup was taken must be available at " -"recovery." -msgstr "" -"온ë¼ì¸ 백업 중 만들어진 WAL ì¡°ê° íŒŒì¼ì€ 복구 작업ì—서 반드시 ëª¨ë‘ ìžˆì–´ì•¼ 합니" -"다." +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "온ë¼ì¸ 백업 중 만들어진 WAL ì¡°ê° íŒŒì¼ì€ 복구 작업ì—서 반드시 ëª¨ë‘ ìžˆì–´ì•¼ 합니다." -#: access/transam/xlog.c:7110 +#: access/transam/xlog.c:7507 #, c-format -msgid "" -"Online backup started with pg_start_backup() must be ended with " -"pg_stop_backup(), and all WAL up to that point must be available at recovery." -msgstr "" -"pg_start_backup() 함수를 호출해서 시작한 온ë¼ì¸ ë°±ì—…ì€ pg_stop_backup() 함수" -"로 종료ë˜ì–´ì•¼ 하며, ê·¸ ì‚¬ì´ ë§Œë“¤ì–´ì§„ WAL ì¡°ê° íŒŒì¼ì€ 복구 작업ì—서 ëª¨ë‘ í•„ìš”" -"합니다." +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "pg_start_backup() 함수를 호출해서 시작한 온ë¼ì¸ ë°±ì—…ì€ pg_stop_backup() 함수로 종료ë˜ì–´ì•¼ 하며, ê·¸ ì‚¬ì´ ë§Œë“¤ì–´ì§„ WAL ì¡°ê° íŒŒì¼ì€ 복구 작업ì—서 ëª¨ë‘ í•„ìš”í•©ë‹ˆë‹¤." -#: access/transam/xlog.c:7113 +#: access/transam/xlog.c:7510 #, c-format msgid "WAL ends before consistent recovery point" msgstr "WALì´ ì¼ì¹˜í•˜ëŠ” 복구 ì§€ì  ì•žì—서 종료ë¨" -#: access/transam/xlog.c:7140 +#: access/transam/xlog.c:7544 #, c-format msgid "selected new timeline ID: %u" msgstr "지정한 새 타임ë¼ì¸ ID: %u" -#: access/transam/xlog.c:7551 +#: access/transam/xlog.c:7981 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "%X/%X 위치ì—서 복구 ì¼ê´€ì„±ì„ 맞춤" -#: access/transam/xlog.c:7742 +#: access/transam/xlog.c:8173 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "컨트롤 파ì¼ì—서 ìž˜ëª»ëœ primary checkpoint ë§í¬ 발견" -#: access/transam/xlog.c:7746 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "컨트롤 파ì¼ì—서 ìž˜ëª»ëœ secondary checkpoint ë§í¬ 발견" - -#: access/transam/xlog.c:7750 +#: access/transam/xlog.c:8177 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "백업 ë¼ë²¨ 파ì¼ì—서 ìž˜ëª»ëœ ì²´í¬í¬ì¸íЏ ë§í¬ 발견" -#: access/transam/xlog.c:7767 +#: access/transam/xlog.c:8194 #, c-format msgid "invalid primary checkpoint record" msgstr "ìž˜ëª»ëœ primary checkpoint 레코드" -#: access/transam/xlog.c:7771 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "ìž˜ëª»ëœ secondary checkpoint 레코드" - -#: access/transam/xlog.c:7775 +#: access/transam/xlog.c:8198 #, c-format msgid "invalid checkpoint record" msgstr "ìž˜ëª»ëœ checkpoint 레코드" -#: access/transam/xlog.c:7786 +#: access/transam/xlog.c:8209 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "primary checkpoint 레코드ì—서 ìž˜ëª»ëœ ìžì› ê´€ë¦¬ìž ID 발견" -#: access/transam/xlog.c:7790 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "secondary checkpoint 레코드ì—서 ìž˜ëª»ëœ ìžì› ê´€ë¦¬ìž ID 발견" - -#: access/transam/xlog.c:7794 +#: access/transam/xlog.c:8213 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "checkpoint 레코드ì—서 ìž˜ëª»ëœ ìžì› ê´€ë¦¬ìž ID 발견" -#: access/transam/xlog.c:7806 +#: access/transam/xlog.c:8226 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "primary checkpoint 레코드ì—서 ìž˜ëª»ëœ xl_info 발견" -#: access/transam/xlog.c:7810 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "secondary checkpoint 레코드ì—서 ìž˜ëª»ëœ xl_info 발견" - -#: access/transam/xlog.c:7814 +#: access/transam/xlog.c:8230 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "checkpoint 레코드ì—서 ìž˜ëª»ëœ xl_info 발견" -#: access/transam/xlog.c:7825 +#: access/transam/xlog.c:8241 #, c-format msgid "invalid length of primary checkpoint record" msgstr "primary checkpoint 레코드 길ì´ê°€ 잘못ë˜ì—ˆìŒ" -#: access/transam/xlog.c:7829 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "secondary checkpoint 레코드 길ì´ê°€ 잘못ë˜ì—ˆìŒ" - -#: access/transam/xlog.c:7833 +#: access/transam/xlog.c:8245 #, c-format msgid "invalid length of checkpoint record" msgstr "checkpoint 레코드 길ì´ê°€ 잘못ë˜ì—ˆìŒ" -#: access/transam/xlog.c:8001 +#: access/transam/xlog.c:8451 #, c-format msgid "shutting down" msgstr "서비스를 멈추고 있습니다" -#: access/transam/xlog.c:8514 +#: access/transam/xlog.c:8771 #, c-format -msgid "" -"concurrent transaction log activity while database system is shutting down" -msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì¤‘ì§€ë˜ëŠ” ë™ì•ˆ 현재 트랜잭션 로그가 활성화 ë˜ì—ˆìŒ" +msgid "checkpoint skipped because system is idle" +msgstr "ì‹œìŠ¤í…œì´ ë†€ê³  있어 ì²´í¬í¬ì¸íЏ 작업 건너뜀" + +#: access/transam/xlog.c:8976 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì¤‘ì§€ë˜ëŠ” ë™ì•ˆ ë™ì‹œ 트랜잭션 로그가 활성화 ë˜ì—ˆìŒ" -#: access/transam/xlog.c:8768 +#: access/transam/xlog.c:9233 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "다시 시작 ì§€ì ì„ 건너뜀, 복구가 ì´ë¯¸ 종료ë¨" -#: access/transam/xlog.c:8791 +#: access/transam/xlog.c:9256 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "다시 시작 ì§€ì ì„ 건너뜀, %X/%Xì—서 ì´ë¯¸ 수행ë¨" -#: access/transam/xlog.c:8967 +#: access/transam/xlog.c:9423 #, c-format msgid "recovery restart point at %X/%X" msgstr "%X/%Xì—서 복구 작업 시작함" -#: access/transam/xlog.c:9100 +#: access/transam/xlog.c:9425 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "마지막 ì™„ë£Œëœ íŠ¸ëžœìž­ì…˜ ê¸°ë¡ ì‹œê°„ì€ %s 입니다." + +#: access/transam/xlog.c:9559 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "\"%s\" ì´ë¦„ì˜ ë³µêµ¬ 위치는 %X/%Xì— ë§Œë“¤ì—ˆìŒ" -#: access/transam/xlog.c:9230 +#: access/transam/xlog.c:9689 #, c-format -msgid "" -"unexpected previous timeline ID %u (current timeline ID %u) in checkpoint " -"record" -msgstr "" -"ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì— ì˜ˆê¸°ì¹˜ ì•Šì€ ì´ì „ 타임ë¼ì¸ID %u(현재 타임ë¼ì¸ID: %u)" +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì— ì˜ˆê¸°ì¹˜ ì•Šì€ ì´ì „ 타임ë¼ì¸ID %u(현재 타임ë¼ì¸ID: %u)" -#: access/transam/xlog.c:9239 +#: access/transam/xlog.c:9698 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì— ì˜ˆê¸°ì¹˜ ì•Šì€ íƒ€ìž„ë¼ì¸ ID %uì´(ê°€) 있ìŒ(%u ë’¤)" -#: access/transam/xlog.c:9255 +#: access/transam/xlog.c:9714 #, c-format -msgid "" -"unexpected timeline ID %u in checkpoint record, before reaching minimum " -"recovery point %X/%X on timeline %u" -msgstr "" -"ì²´í¬í¬ì¸íЏ ë‚´ì—­ ì•ˆì— %u 타임ë¼ì¸ IDê°€ 기대한 것과 다릅니다. ë°œìƒ ìœ„ì¹˜: %X/%X " -"(타임ë¼ì¸: %u) 최소 복구 위치 ì´ì „" +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "ì²´í¬í¬ì¸íЏ ë‚´ì—­ ì•ˆì— %u 타임ë¼ì¸ IDê°€ 기대한 것과 다릅니다. ë°œìƒ ìœ„ì¹˜: %X/%X (타임ë¼ì¸: %u) 최소 복구 위치 ì´ì „" -#: access/transam/xlog.c:9326 +#: access/transam/xlog.c:9790 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "온ë¼ì¸ ë°±ì–´ì´ ì·¨ì†Œë˜ì—ˆìŒ, 복구를 ê³„ì† í•  수 ì—†ìŒ" -#: access/transam/xlog.c:9382 access/transam/xlog.c:9429 -#: access/transam/xlog.c:9452 +#: access/transam/xlog.c:9846 access/transam/xlog.c:9902 +#: access/transam/xlog.c:9925 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "ì²´í¬í¬ì¸íЏ ë ˆì½”ë“œì— ì˜ˆê¸°ì¹˜ ì•Šì€ íƒ€ìž„ë¼ì¸ ID %uì´(ê°€) 있ìŒ(%uì´ì–´ì•¼ 함)" -#: access/transam/xlog.c:9727 +#: access/transam/xlog.c:10206 #, c-format msgid "could not fsync log segment %s: %m" msgstr "%s 로그 ì¡°ê° fsync 실패: %m" -#: access/transam/xlog.c:9751 +#: access/transam/xlog.c:10231 #, c-format msgid "could not fsync log file %s: %m" msgstr "\"%s\" 로그 íŒŒì¼ fsync 실패: %m" -#: access/transam/xlog.c:9759 +#: access/transam/xlog.c:10239 #, c-format msgid "could not fsync write-through log file %s: %m" msgstr "write-through 로그 파ì¼(%s)ì„ fsyncí•  수 ì—†ìŒ: %m" -#: access/transam/xlog.c:9768 +#: access/transam/xlog.c:10248 #, c-format msgid "could not fdatasync log file %s: %m" msgstr "%s 로그파ì¼ì„ fdatasyncí•  수 ì—†ìŒ: %m" -#: access/transam/xlog.c:9859 access/transam/xlog.c:10363 -#: access/transam/xlogfuncs.c:294 access/transam/xlogfuncs.c:321 -#: access/transam/xlogfuncs.c:360 access/transam/xlogfuncs.c:381 -#: access/transam/xlogfuncs.c:402 +#: access/transam/xlog.c:10339 access/transam/xlog.c:10866 +#: access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 +#: access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 +#: access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "WAL 제어 함수는 복구 작업 중ì—는 실행 ë  ìˆ˜ ì—†ìŒ" -#: access/transam/xlog.c:9868 access/transam/xlog.c:10372 +#: access/transam/xlog.c:10348 access/transam/xlog.c:10875 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "온ë¼ì¸ 백업 ìž‘ì—…ì„ í•˜ê¸° 위한 WAL ìˆ˜ì¤€ì´ ì¶©ë¶„ì¹˜ 않습니다." -#: access/transam/xlog.c:9869 access/transam/xlog.c:10373 -#: access/transam/xlogfuncs.c:327 +#: access/transam/xlog.c:10349 access/transam/xlog.c:10876 +#: access/transam/xlogfuncs.c:320 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." -msgstr "" -"wal_level ê°’ì„ \"replica\" ë˜ëŠ” \"logical\"로 지정하고 서버를 실행하십시오." +msgstr "wal_level ê°’ì„ \"replica\" ë˜ëŠ” \"logical\"로 지정하고 서버를 실행하십시오." -#: access/transam/xlog.c:9874 +#: access/transam/xlog.c:10354 #, c-format msgid "backup label too long (max %d bytes)" msgstr "백업 ë¼ë²¨ ì´ë¦„ì´ ë„ˆë¬´ 긺(최대 %d ë°”ì´íЏ)" -#: access/transam/xlog.c:9911 access/transam/xlog.c:10183 -#: access/transam/xlog.c:10221 +#: access/transam/xlog.c:10391 access/transam/xlog.c:10667 +#: access/transam/xlog.c:10705 #, c-format msgid "a backup is already in progress" msgstr "ì´ë¯¸ 백업 ìž‘ì—…ì´ ì§„í–‰ 중입니다" -#: access/transam/xlog.c:9912 +#: access/transam/xlog.c:10392 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "pg_stop_backup() 함수를 실행하고 나서 다시 시ë„하세요." -#: access/transam/xlog.c:10007 +#: access/transam/xlog.c:10488 #, c-format -msgid "" -"WAL generated with full_page_writes=off was replayed since last restartpoint" -msgstr "" -"마지막 재시작 위치부터 재반ì˜ëœ WAL ë‚´ìš©ì´ full_page_writes=off 설정으로 만들" -"ì–´ì§„ 내용입니다." +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "마지막 재시작 위치부터 재반ì˜ëœ WAL ë‚´ìš©ì´ full_page_writes=off 설정으로 만들어진 내용입니다." -#: access/transam/xlog.c:10009 access/transam/xlog.c:10554 +#: access/transam/xlog.c:10490 access/transam/xlog.c:11071 #, c-format -msgid "" -"This means that the backup being taken on the standby is corrupt and should " -"not be used. Enable full_page_writes and run CHECKPOINT on the master, and " -"then try an online backup again." -msgstr "" -"ì´ ê²½ìš° 대기 ì„œë²„ì˜ ìžë£Œê°€ ì†ì‹¤ë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤. full_page_writes 설" -"ì •ì„ í™œì„±í™” 하고, 주 서버ì—서 CHECKPOINT ëª…ë ¹ì„ ì‹¤í–‰í•˜ê³ , 온ë¼ì¸ ë°±ì—…ì„ ë‹¤ì‹œ " -"해서 사용하세요." +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "ì´ ê²½ìš° 대기 ì„œë²„ì˜ ìžë£Œê°€ ì†ì‹¤ë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤. full_page_writes ì„¤ì •ì„ í™œì„±í™” 하고, 주 서버ì—서 CHECKPOINT ëª…ë ¹ì„ ì‹¤í–‰í•˜ê³ , 온ë¼ì¸ ë°±ì—…ì„ ë‹¤ì‹œ 해서 사용하세요." -#: access/transam/xlog.c:10076 replication/basebackup.c:1026 -#: utils/adt/misc.c:498 +#: access/transam/xlog.c:10558 replication/basebackup.c:1225 +#: utils/adt/misc.c:517 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "\"%s\" 심볼릭 ë§í¬ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:10083 replication/basebackup.c:1031 -#: utils/adt/misc.c:503 +#: access/transam/xlog.c:10565 replication/basebackup.c:1230 +#: utils/adt/misc.c:522 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "\"%s\" 심볼릭 ë§í¬ì˜ 대ìƒì´ 너무 긺" -#: access/transam/xlog.c:10136 commands/tablespace.c:391 -#: commands/tablespace.c:553 replication/basebackup.c:1047 -#: utils/adt/misc.c:511 +#: access/transam/xlog.c:10617 commands/tablespace.c:391 +#: commands/tablespace.c:553 replication/basebackup.c:1245 utils/adt/misc.c:530 #, c-format msgid "tablespaces are not supported on this platform" msgstr "í…Œì´ë¸”스페ì´ìФ ê¸°ëŠ¥ì€ ì´ í”Œëž«í¼ì—서는 ì§€ì›í•˜ì§€ 않습니다." -#: access/transam/xlog.c:10177 access/transam/xlog.c:10215 -#: access/transam/xlog.c:10411 access/transam/xlogarchive.c:106 -#: access/transam/xlogarchive.c:265 commands/copy.c:1815 commands/copy.c:2839 -#: commands/extension.c:3130 commands/tablespace.c:782 -#: commands/tablespace.c:873 replication/basebackup.c:409 -#: replication/basebackup.c:477 replication/logical/snapbuild.c:1491 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2903 -#: storage/file/fd.c:2995 utils/adt/dbsize.c:70 utils/adt/dbsize.c:220 -#: utils/adt/dbsize.c:300 utils/adt/genfile.c:114 utils/adt/genfile.c:333 -#: guc-file.l:1002 +#: access/transam/xlog.c:10661 access/transam/xlog.c:10699 +#: access/transam/xlog.c:10914 access/transam/xlogarchive.c:105 +#: access/transam/xlogarchive.c:265 commands/copy.c:1872 commands/copy.c:3156 +#: commands/extension.c:3319 commands/tablespace.c:782 +#: commands/tablespace.c:873 guc-file.l:1004 replication/basebackup.c:516 +#: replication/basebackup.c:586 replication/logical/snapbuild.c:1525 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1732 +#: storage/file/fd.c:3098 storage/file/fd.c:3277 storage/file/fd.c:3362 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:131 utils/adt/genfile.c:382 #, c-format msgid "could not stat file \"%s\": %m" msgstr "\"%s\" 파ì¼ì˜ ìƒíƒœê°’ì„ ì•Œ 수 ì—†ìŒ: %m" -#: access/transam/xlog.c:10184 access/transam/xlog.c:10222 +#: access/transam/xlog.c:10668 access/transam/xlog.c:10706 #, c-format -msgid "" -"If you're sure there is no backup in progress, remove file \"%s\" and try " -"again." -msgstr "" -"실재로는 백업 ìž‘ì—…ì„ ì•ˆí•˜ê³  있다고 확신한다면, \"%s\" 파ì¼ì„ 삭제하고 다시 시" -"ë„í•´ 보십시오." +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "실재로는 백업 ìž‘ì—…ì„ ì•ˆí•˜ê³  있다고 확신한다면, \"%s\" 파ì¼ì„ 삭제하고 다시 시ë„í•´ 보십시오." -#: access/transam/xlog.c:10201 access/transam/xlog.c:10239 -#: access/transam/xlog.c:10615 +#: access/transam/xlog.c:10685 access/transam/xlog.c:10723 +#: access/transam/xlog.c:11134 postmaster/syslogger.c:1476 +#: postmaster/syslogger.c:1489 #, c-format msgid "could not write file \"%s\": %m" msgstr "\"%s\" íŒŒì¼ ì“°ê¸° 실패: %m" -#: access/transam/xlog.c:10388 +#: access/transam/xlog.c:10891 #, c-format msgid "exclusive backup not in progress" msgstr "exclusive 백업 ìž‘ì—…ì„ í•˜ì§€ 않고 있습니다" -#: access/transam/xlog.c:10415 +#: access/transam/xlog.c:10918 #, c-format msgid "a backup is not in progress" msgstr "현재 백업 ìž‘ì—…ì„ í•˜ì§€ 않고 있습니다" -#: access/transam/xlog.c:10489 access/transam/xlog.c:10502 -#: access/transam/xlog.c:10842 access/transam/xlog.c:10848 -#: access/transam/xlog.c:10932 access/transam/xlogfuncs.c:695 +#: access/transam/xlog.c:11004 access/transam/xlog.c:11017 +#: access/transam/xlog.c:11378 access/transam/xlog.c:11384 +#: access/transam/xlog.c:11432 access/transam/xlog.c:11505 +#: access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" msgstr "\"%s\" 파ì¼ì— 유효하지 ì•Šì€ ìžë£Œê°€ 있습니다" -#: access/transam/xlog.c:10506 replication/basebackup.c:938 +#: access/transam/xlog.c:11021 replication/basebackup.c:1082 #, c-format msgid "the standby was promoted during online backup" msgstr "대기 서버가 온ë¼ì¸ 백업 중 주 서버로 전환ë˜ì—ˆìŠµë‹ˆë‹¤" -#: access/transam/xlog.c:10507 replication/basebackup.c:939 +#: access/transam/xlog.c:11022 replication/basebackup.c:1083 #, c-format -msgid "" -"This means that the backup being taken is corrupt and should not be used. " -"Try taking another online backup." -msgstr "" -"ì´ëŸ° 경우, 해당 백업 ìžë£Œê°€ ì†ìƒë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤. 다른 ë°±ì—…ë³¸ì„ ì´ìš©" -"하세요." +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "ì´ëŸ° 경우, 해당 백업 ìžë£Œê°€ ì†ìƒë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤. 다른 ë°±ì—…ë³¸ì„ ì´ìš©í•˜ì„¸ìš”." -#: access/transam/xlog.c:10552 +#: access/transam/xlog.c:11069 #, c-format -msgid "" -"WAL generated with full_page_writes=off was replayed during online backup" -msgstr "" -"온ë¼ì¸ 백업 ë„중 full_page_writes=off 설정으로 만들어진 WAL ë‚´ìš©ì´ ìž¬ë°˜ì˜ë˜ì—ˆ" -"습니다." +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "온ë¼ì¸ 백업 ë„중 full_page_writes=off 설정으로 만들어진 WAL ë‚´ìš©ì´ ìž¬ë°˜ì˜ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:10664 +#: access/transam/xlog.c:11189 #, c-format -msgid "" -"pg_stop_backup cleanup done, waiting for required WAL segments to be archived" -msgstr "" -"pg_stop_backup ìž‘ì—…ì´ ë났습니다. 필요한 WAL ì¡°ê° íŒŒì¼ì´ ì•„ì¹´ì´ë¸Œ ë˜ê¸¸ 기다리" -"ê³  있습니다." +msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" +msgstr "pg_stop_backup ìž‘ì—…ì´ ë났습니다. 필요한 WAL ì¡°ê° íŒŒì¼ì´ ì•„ì¹´ì´ë¸Œ ë˜ê¸¸ 기다리고 있습니다." -#: access/transam/xlog.c:10674 +#: access/transam/xlog.c:11199 #, c-format -msgid "" -"pg_stop_backup still waiting for all required WAL segments to be archived " -"(%d seconds elapsed)" +msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "pg_stop_backupì—서 ì•„ì¹´ì´ë¹™ì´ 완료ë˜ê¸°ë¥¼ 기다리고 ìžˆìŒ (%dì´ˆ 경과)" -#: access/transam/xlog.c:10676 +#: access/transam/xlog.c:11201 #, c-format -msgid "" -"Check that your archive_command is executing properly. pg_stop_backup can " -"be canceled safely, but the database backup will not be usable without all " -"the WAL segments." -msgstr "" -"archive_command ì„¤ì •ì„ ì‚´íŽ´ë³´ì„¸ìš”. pg_stop_backup ìž‘ì—…ì€ ì•ˆì „í•˜ê²Œ 취소 í•  " -"수 있지만, ë°ì´í„°ë² ì´ìФ ë°±ì—…ì€ ëª¨ë“  WAL ì¡°ê° ì—†ì´ëŠ” ì‚¬ìš©ë  ìˆ˜ 없습니다." +msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." +msgstr "archive_command ì„¤ì •ì„ ì‚´íŽ´ë³´ì„¸ìš”. pg_stop_backup ìž‘ì—…ì€ ì•ˆì „í•˜ê²Œ 취소 í•  수 있지만, ë°ì´í„°ë² ì´ìФ ë°±ì—…ì€ ëª¨ë“  WAL ì¡°ê° ì—†ì´ëŠ” ì‚¬ìš©ë  ìˆ˜ 없습니다." -#: access/transam/xlog.c:10683 +#: access/transam/xlog.c:11208 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" -msgstr "" -"pg_stop_backup ìž‘ì—…ì´ ë났습니다. 모든 필요한 WAL ì¡°ê°ë“¤ì´ ì•„ì¹´ì´ë¸Œ ë˜ì—ˆìŠµë‹ˆ" -"다." +msgstr "pg_stop_backup ìž‘ì—…ì´ ë났습니다. 모든 필요한 WAL ì¡°ê°ë“¤ì´ ì•„ì¹´ì´ë¸Œ ë˜ì—ˆìŠµë‹ˆë‹¤." -#: access/transam/xlog.c:10687 +#: access/transam/xlog.c:11212 #, c-format -msgid "" -"WAL archiving is not enabled; you must ensure that all required WAL segments " -"are copied through other means to complete the backup" -msgstr "" -"WAL ì•„ì¹´ì´ë¸Œ ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ 있습니다; ì´ ê²½ìš°ëŠ” 백업 ë’¤ ë³µêµ¬ì— í•„ìš”í•œ " -"모든 WAL ì¡°ê° íŒŒì¼ë“¤ì„ ì§ì ‘ 찾아서 따로 보관해 ë‘어야 바르게 복구 í•  수 있습" -"니다." +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL ì•„ì¹´ì´ë¸Œ ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ 있습니다; ì´ ê²½ìš°ëŠ” 백업 ë’¤ ë³µêµ¬ì— í•„ìš”í•œ 모든 WAL ì¡°ê° íŒŒì¼ë“¤ì„ ì§ì ‘ 찾아서 따로 보관해 ë‘어야 바르게 복구 í•  수 있습니다." + +#: access/transam/xlog.c:11415 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "백업 시간: %s, ì €ìž¥ëœ íŒŒì¼: \"%s\"" + +#: access/transam/xlog.c:11420 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "백업 ë¼ë²¨: %s, ì €ìž¥ëœ íŒŒì¼: \"%s\"" + +#: access/transam/xlog.c:11433 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "타임ë¼ì¸ IDê°€ %u 값으로 ë¶„ì„했지만, ê¸°ëŒ€ê°’ì€ %u ìž„" + +#: access/transam/xlog.c:11437 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "백업 타임ë¼ì¸: %u, ì €ìž¥ëœ íŒŒì¼: \"%s\"" -#. translator: %s is an XLog record description -#: access/transam/xlog.c:10972 +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11545 #, c-format -msgid "xlog redo at %X/%X for %s" -msgstr "xlog redo 위치: %X/%X, 대ìƒ: %s" +msgid "WAL redo at %X/%X for %s" +msgstr "WAL redo 위치: %X/%X, 대ìƒ: %s" -#: access/transam/xlog.c:11021 +#: access/transam/xlog.c:11594 #, c-format msgid "online backup mode was not canceled" msgstr "온ë¼ì¸ 백업 모드가 취소ë˜ì§€ 않았ìŒ" -#: access/transam/xlog.c:11022 +#: access/transam/xlog.c:11595 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %m." -#: access/transam/xlog.c:11031 access/transam/xlog.c:11043 -#: access/transam/xlog.c:11053 +#: access/transam/xlog.c:11604 access/transam/xlog.c:11616 +#: access/transam/xlog.c:11626 #, c-format msgid "online backup mode canceled" msgstr "온ë¼ì¸ 백업 모드가 취소ë¨" -#: access/transam/xlog.c:11044 +#: access/transam/xlog.c:11617 #, c-format -msgid "" -"Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." -msgstr "" -"예ìƒí•œ 것처럼, \"%s\", \"%s\" 파ì¼ì„ \"%s\", \"%s\" ì´ë¦„으로 바꿨습니다." +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "예ìƒí•œ 것처럼, \"%s\", \"%s\" 파ì¼ì„ \"%s\", \"%s\" ì´ë¦„으로 바꿨습니다." -#: access/transam/xlog.c:11054 +#: access/transam/xlog.c:11627 #, c-format -msgid "" -"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to " -"\"%s\": %m." -msgstr "" -"\"%s\" 파ì¼ì€ \"%s\" ì´ë¦„으로 바꿨지만, \"%s\" 파ì¼ì€ \"%s\" ì´ë¦„으로 바꾸지 " -"못했습니다: %m." +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "\"%s\" 파ì¼ì€ \"%s\" ì´ë¦„으로 바꿨지만, \"%s\" 파ì¼ì€ \"%s\" ì´ë¦„으로 바꾸지 못했습니다: %m." -#: access/transam/xlog.c:11176 access/transam/xlogutils.c:718 -#: replication/walreceiver.c:994 replication/walsender.c:2112 +#: access/transam/xlog.c:11753 access/transam/xlogutils.c:727 +#: replication/walreceiver.c:1019 replication/walsender.c:2424 #, c-format msgid "could not seek in log segment %s to offset %u: %m" msgstr "%s 로그 ì¡°ê°ì—서 해당 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %u: %m" -#: access/transam/xlog.c:11188 +#: access/transam/xlog.c:11769 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "%s 로그 ì¡°ê°ì—서 ì½ê¸° 실패, 위치: %u: %m" -#: access/transam/xlog.c:11662 +#: access/transam/xlog.c:12298 #, c-format msgid "received promote request" msgstr "ìš´ì˜ ì „í™˜ 신호를 받았습니다." -#: access/transam/xlog.c:11675 +#: access/transam/xlog.c:12311 #, c-format msgid "trigger file found: %s" msgstr "트리거 파ì¼ì´ 있ìŒ: %s" -#: access/transam/xlog.c:11684 +#: access/transam/xlog.c:12320 #, c-format msgid "could not stat trigger file \"%s\": %m" msgstr "\"%s\" 트리거 파ì¼ì˜ ìƒíƒœê°’ì„ ì•Œ 수 ì—†ìŒ: %m" @@ -3108,886 +2650,1012 @@ msgstr "ì•„ì¹´ì´ë¸Œì—서 \"%s\" íŒŒì¼ ë³µì› ì‹¤íŒ¨: %s" #. translator: First %s represents a recovery.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:415 +#: access/transam/xlogarchive.c:416 #, c-format msgid "%s \"%s\": %s" msgstr "%s \"%s\": %s" -#: access/transam/xlogarchive.c:458 replication/logical/snapbuild.c:1619 -#: replication/slot.c:480 replication/slot.c:992 replication/slot.c:1100 -#: storage/file/fd.c:642 storage/file/fd.c:700 utils/time/snapmgr.c:1298 +#: access/transam/xlogarchive.c:459 postmaster/syslogger.c:1500 +#: replication/logical/snapbuild.c:1660 replication/slot.c:598 +#: replication/slot.c:1206 replication/slot.c:1321 storage/file/fd.c:650 +#: storage/file/fd.c:745 utils/time/snapmgr.c:1318 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %m" -#: access/transam/xlogarchive.c:525 access/transam/xlogarchive.c:589 +#: access/transam/xlogarchive.c:526 access/transam/xlogarchive.c:590 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "\"%s\" archive status 파ì¼ì„ 만들 수 없습니다: %m" -#: access/transam/xlogarchive.c:533 access/transam/xlogarchive.c:597 +#: access/transam/xlogarchive.c:534 access/transam/xlogarchive.c:598 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "\"%s\" archive status 파ì¼ì— 쓸 수 없습니다: %m" -#: access/transam/xlogfuncs.c:58 +#: access/transam/xlogfuncs.c:54 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" -msgstr "" -"pg_stop_backup ìž‘ì—…ì´ í˜¸ì¶œë˜ê¸° ì „ì— ë°±ì—”ë“œê°€ 종료ë˜ì–´ ë°±ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." +msgstr "pg_stop_backup ìž‘ì—…ì´ í˜¸ì¶œë˜ê¸° ì „ì— ë°±ì—”ë“œê°€ 종료ë˜ì–´ ë°±ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." -#: access/transam/xlogfuncs.c:88 +#: access/transam/xlogfuncs.c:84 #, c-format msgid "a backup is already in progress in this session" msgstr "ì´ë¯¸ ì´ ì„¸ì…˜ì—서 백업 ìž‘ì—…ì´ ì§„í–‰ 중입니다" -#: access/transam/xlogfuncs.c:94 commands/tablespace.c:705 -#: commands/tablespace.c:715 postmaster/postmaster.c:1406 -#: replication/basebackup.c:297 replication/basebackup.c:637 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2369 -#: storage/file/fd.c:2968 storage/ipc/dsm.c:300 utils/adt/genfile.c:439 -#: utils/adt/misc.c:411 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "\"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %m" - -#: access/transam/xlogfuncs.c:155 access/transam/xlogfuncs.c:229 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format msgid "non-exclusive backup in progress" msgstr "non-exclusive 백업 ì§„í–‰ 중입니다" -#: access/transam/xlogfuncs.c:156 access/transam/xlogfuncs.c:230 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "pg_stop_backup('f') 형태로 함수를 호출했나요?" -#: access/transam/xlogfuncs.c:200 commands/event_trigger.c:1445 -#: commands/event_trigger.c:1996 commands/extension.c:1729 -#: commands/extension.c:1838 commands/extension.c:2031 commands/prepare.c:702 -#: executor/execQual.c:1757 executor/execQual.c:1782 executor/execQual.c:2157 -#: executor/execQual.c:5438 executor/functions.c:1031 foreign/foreign.c:492 -#: replication/logical/logicalfuncs.c:175 replication/logical/origin.c:1391 -#: replication/slotfuncs.c:189 replication/walsender.c:2761 -#: utils/adt/jsonfuncs.c:1483 utils/adt/jsonfuncs.c:1613 -#: utils/adt/jsonfuncs.c:1801 utils/adt/jsonfuncs.c:1928 -#: utils/adt/jsonfuncs.c:2694 utils/adt/pgstatfuncs.c:554 -#: utils/adt/pgstatfuncs.c:655 utils/fmgr/funcapi.c:61 utils/misc/guc.c:8436 -#: utils/mmgr/portalmem.c:1074 +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 +#: commands/event_trigger.c:2015 commands/extension.c:1895 +#: commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:722 +#: executor/execExpr.c:2208 executor/execSRF.c:715 executor/functions.c:1034 +#: foreign/foreign.c:488 libpq/hba.c:2600 replication/logical/launcher.c:1127 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 +#: replication/slotfuncs.c:200 replication/walsender.c:3203 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 +#: utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8819 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" -msgstr "" -"set-values 함수(í…Œì´ë¸” 리턴 함수)ê°€ set ì •ì˜ ì—†ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤ (í…Œì´ë¸”ê³¼ í•´" -"당 ì—´ alias 지정하세요)" +msgstr "set-values 함수(í…Œì´ë¸” 리턴 함수)ê°€ set ì •ì˜ ì—†ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤ (í…Œì´ë¸”ê³¼ 해당 ì—´ alias 지정하세요)" -#: access/transam/xlogfuncs.c:204 commands/event_trigger.c:1449 -#: commands/event_trigger.c:2000 commands/extension.c:1733 -#: commands/extension.c:1842 commands/extension.c:2035 commands/prepare.c:706 -#: foreign/foreign.c:497 replication/logical/logicalfuncs.c:179 -#: replication/logical/origin.c:1395 replication/slotfuncs.c:193 -#: replication/walsender.c:2765 utils/adt/pgstatfuncs.c:558 -#: utils/adt/pgstatfuncs.c:659 utils/misc/guc.c:8440 utils/misc/pg_config.c:44 -#: utils/mmgr/portalmem.c:1078 +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 +#: commands/event_trigger.c:2019 commands/extension.c:1899 +#: commands/extension.c:2008 commands/extension.c:2232 commands/prepare.c:726 +#: foreign/foreign.c:493 libpq/hba.c:2604 replication/logical/launcher.c:1131 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 +#: replication/slotfuncs.c:204 replication/walsender.c:3207 +#: utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 +#: utils/misc/guc.c:8823 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "materialize 모드가 필요합니다만, ì´ êµ¬ë¬¸ì—서는 허용ë˜ì§€ 않습니다" -#: access/transam/xlogfuncs.c:247 +#: access/transam/xlogfuncs.c:241 #, c-format msgid "non-exclusive backup is not in progress" msgstr "non-exclusive 백업 ìƒíƒœê°€ 아닙니다" -#: access/transam/xlogfuncs.c:248 +#: access/transam/xlogfuncs.c:242 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "pg_stop_backup('t') 형태로 함수를 호출했나요?" -#: access/transam/xlogfuncs.c:326 +#: access/transam/xlogfuncs.c:319 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "WAL ìˆ˜ì¤€ì´ ë³µì› ìœ„ì¹˜ë¥¼ 만들 수 없는 수준입니다" -#: access/transam/xlogfuncs.c:334 +#: access/transam/xlogfuncs.c:327 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "ë³µì› ìœ„ì¹˜ ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤. (최대값, %d 글ìž)" -#: access/transam/xlogfuncs.c:472 +#: access/transam/xlogfuncs.c:465 #, c-format -msgid "pg_xlogfile_name_offset() cannot be executed during recovery." -msgstr "복구 중ì—는 pg_xlogfile_name_offset() 함수를 실행할 수 없습니다." +msgid "pg_walfile_name_offset() cannot be executed during recovery." +msgstr "복구 중ì—는 pg_walfile_name_offset() 함수를 실행할 수 없습니다." -#: access/transam/xlogfuncs.c:528 +#: access/transam/xlogfuncs.c:521 #, c-format -msgid "pg_xlogfile_name() cannot be executed during recovery." -msgstr "복구 중ì—는 pg_xlogfile_name() 함수를 실행할 수 없습니다." +msgid "pg_walfile_name() cannot be executed during recovery." +msgstr "복구 중ì—는 pg_walfile_name() 함수를 실행할 수 없습니다." -#: access/transam/xlogfuncs.c:548 access/transam/xlogfuncs.c:568 -#: access/transam/xlogfuncs.c:585 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" msgstr "현재 복구 작업 ìƒíƒœê°€ 아닙니다" -#: access/transam/xlogfuncs.c:549 access/transam/xlogfuncs.c:569 -#: access/transam/xlogfuncs.c:586 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "복구 제어 함수는 복구 ìž‘ì—…ì¼ ë•Œë§Œ 실행할 수 있습니다." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 위치: %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "%X/%Xì—서 contrecord를 필요로 함" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:624 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 길ì´: %X/%X, 기대값 %u, 실재값 %u" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:363 #, c-format msgid "record length %u at %X/%X too long" msgstr "너무 긴 길ì´(%u)ì˜ ë ˆì½”ë“œê°€ %X/%Xì— ìžˆìŒ" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "%X/%X ìœ„ì¹˜ì— contrecord 플래그가 ì—†ìŒ" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "ìž˜ëª»ëœ contrecord ê¸¸ì´ %u, 위치 %X/%X" -#: access/transam/xlogreader.c:632 +#: access/transam/xlogreader.c:654 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ìž˜ëª»ëœ ìžì› 관리 ID %u, 위치: %X/%X" -#: access/transam/xlogreader.c:646 access/transam/xlogreader.c:663 +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "ë ˆì½”ë“œì˜ ìž˜ëª»ëœ í”„ë¦¬ë§í¬ %X/%X, 해당 레코드 %X/%X" -#: access/transam/xlogreader.c:700 +#: access/transam/xlogreader.c:722 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "ìž˜ëª»ëœ ìžì›ê´€ë¦¬ìž ë°ì´í„° ì²´í¬ì„¬, 위치: %X/%X 레코드" -#: access/transam/xlogreader.c:733 +#: access/transam/xlogreader.c:759 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "%04X ë§¤ì§ ë²ˆí˜¸ê°€ 잘못ë¨, 로그 íŒŒì¼ %s, 위치 %u" -#: access/transam/xlogreader.c:747 access/transam/xlogreader.c:798 +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "ìž˜ëª»ëœ ì •ë³´ 비트 %04X, 로그 íŒŒì¼ %s, 위치 %u" -#: access/transam/xlogreader.c:773 +#: access/transam/xlogreader.c:799 #, c-format -msgid "" -"WAL file is from different database system: WAL file database system " -"identifier is %s, pg_control database system identifier is %s" -msgstr "" -"WAL 파ì¼ì´ 다른 ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤. WAL 파ì¼ì˜ 시스템 ì‹ë³„ìžëŠ” %s, pg_control " -"ì˜ ì‹ë³„ìžëŠ” %s" +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL 파ì¼ì´ 다른 ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤. WAL 파ì¼ì˜ 시스템 ì‹ë³„ìžëŠ” %s, pg_control ì˜ ì‹ë³„ìžëŠ” %s" -#: access/transam/xlogreader.c:780 +#: access/transam/xlogreader.c:806 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_SEG_SIZE in page " -"header" -msgstr "" -"WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì˜ XLOG_SEG_SIZE " -"ê°’ì´ ë°”ë¥´ì§€ 않ìŒ" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì— ì§€ì •ëœ ê°’ì´ ìž˜ëª»ëœ ì¡°ê° í¬ê¸°ìž„" -#: access/transam/xlogreader.c:786 +#: access/transam/xlogreader.c:812 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " -"header" -msgstr "" -"WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì˜ XLOG_BLCKSZ ê°’" -"ì´ ë°”ë¥´ì§€ 않ìŒ" +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì˜ XLOG_BLCKSZ ê°’ì´ ë°”ë¥´ì§€ 않ìŒ" -#: access/transam/xlogreader.c:812 +#: access/transam/xlogreader.c:843 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "ìž˜ëª»ëœ íŽ˜ì´ì§€ 주소 %X/%X, 로그 íŒŒì¼ %s, 위치 %u" -#: access/transam/xlogreader.c:837 +#: access/transam/xlogreader.c:868 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "타임ë¼ì¸ 범위 벗어남 %u (ì´ì „ 번호 %u), 로그 íŒŒì¼ %s, 위치 %u" -#: access/transam/xlogreader.c:1081 +#: access/transam/xlogreader.c:1113 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "%u block_id는 범위를 벗어남, 위치 %X/%X" -#: access/transam/xlogreader.c:1103 +#: access/transam/xlogreader.c:1136 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA 지정했지만, %X/%X ì— ìžë£Œê°€ ì—†ìŒ" -#: access/transam/xlogreader.c:1110 +#: access/transam/xlogreader.c:1143 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA 지정 않았지만, %u 길ì´ì˜ ìžë£Œê°€ 있ìŒ, 위치 %X/%X" -#: access/transam/xlogreader.c:1143 +#: access/transam/xlogreader.c:1179 #, c-format -msgid "" -"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " -"%X/%X" -msgstr "" -"BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: " -"%u, 대ìƒ: %X/%X" +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" -#: access/transam/xlogreader.c:1159 +#: access/transam/xlogreader.c:1195 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" -msgstr "" -"BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ì•ˆë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, 대ìƒ: %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ì•ˆë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, 대ìƒ: %X/%X" -#: access/transam/xlogreader.c:1174 +#: access/transam/xlogreader.c:1210 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" -msgstr "" -"BKPIMAGE_IS_COMPRESSED ì„¤ì •ì´ ë˜ì–´ 있지만, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED ì„¤ì •ì´ ë˜ì–´ 있지만, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" -#: access/transam/xlogreader.c:1189 +#: access/transam/xlogreader.c:1225 #, c-format -msgid "" -"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " -"length is %u at %X/%X" -msgstr "" -"BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED 지정 안ë˜ì–´ 있으나, ë¸”ë¡ ì´ë¯¸ì§€ 길" -"ì´ëŠ” %u, 대ìƒ: %X/%X" +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED 지정 안ë˜ì–´ 있으나, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´ëŠ” %u, 대ìƒ: %X/%X" -#: access/transam/xlogreader.c:1205 +#: access/transam/xlogreader.c:1241 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL ì„¤ì •ì´ ë˜ì–´ 있지만, %X/%X ì— ì´ì „ 릴레ì´ì…˜ ì—†ìŒ" -#: access/transam/xlogreader.c:1217 +#: access/transam/xlogreader.c:1253 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "ìž˜ëª»ëœ block_id %u, 위치 %X/%X" -#: access/transam/xlogreader.c:1282 +#: access/transam/xlogreader.c:1342 #, c-format msgid "record with invalid length at %X/%X" msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 길ì´, 위치 %X/%X" -#: access/transam/xlogreader.c:1371 +#: access/transam/xlogreader.c:1431 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "ìž˜ëª»ëœ ì••ì¶• ì´ë¯¸ì§€, 위치 %X/%X, ë¸”ë¡ %d" -#: access/transam/xlogutils.c:739 replication/walsender.c:2129 +#: access/transam/xlogutils.c:751 replication/walsender.c:2443 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "%s 로그 ì¡°ê° ì½ê¸° 실패, 위치 %u, ê¸¸ì´ %lu: %m" -#: bootstrap/bootstrap.c:269 postmaster/postmaster.c:793 tcop/postgres.c:3501 +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X ê°’ì€ 1 MB ~ 1 GB ì‚¬ì´ 2^n ê°’ì´ì–´ì•¼ 함" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:826 tcop/postgres.c:3558 #, c-format msgid "--%s requires a value" msgstr "--%s ì˜µì…˜ì€ í•´ë‹¹ ê°’ì„ ì§€ì •í•´ì•¼í•©ë‹ˆë‹¤" -#: bootstrap/bootstrap.c:274 postmaster/postmaster.c:798 tcop/postgres.c:3506 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:831 tcop/postgres.c:3563 #, c-format msgid "-c %s requires a value" msgstr "-c %s ì˜µì…˜ì€ í•´ë‹¹ ê°’ì„ ì§€ì •í•´ì•¼í•©ë‹ˆë‹¤" -#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:810 -#: postmaster/postmaster.c:823 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:843 +#: postmaster/postmaster.c:856 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "ìžì œí•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보십시오.\n" -#: bootstrap/bootstrap.c:294 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: ìž˜ëª»ëœ ëª…ë ¹í–‰ ì¸ìž\n" -#: catalog/aclchk.c:201 +#: catalog/aclchk.c:203 #, c-format msgid "grant options can only be granted to roles" msgstr "grant ì˜µì…˜ë“¤ì€ ë¡¤ì—서만 ì§€ì •ë  ìˆ˜ 있습니다" -#: catalog/aclchk.c:324 +#: catalog/aclchk.c:326 #, c-format msgid "no privileges were granted for column \"%s\" of relation \"%s\"" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\")ì— ëŒ€í•œ ê¶Œí•œì´ ë¶€ì—¬ë˜ì§€ 않았ìŒ" -#: catalog/aclchk.c:329 +#: catalog/aclchk.c:331 #, c-format msgid "no privileges were granted for \"%s\"" msgstr "\"%s\"ì— ëŒ€í•œ ê¶Œí•œì´ ë¶€ì—¬ë˜ì§€ 않았ìŒ" -#: catalog/aclchk.c:337 +#: catalog/aclchk.c:339 #, c-format msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\")ì— ëŒ€í•œ ì¼ë¶€ ê¶Œí•œì´ ë¶€ì—¬ë˜ì§€ 않았ìŒ" -#: catalog/aclchk.c:342 +#: catalog/aclchk.c:344 #, c-format msgid "not all privileges were granted for \"%s\"" msgstr "\"%s\"ì— ëŒ€í•œ ì¼ë¶€ ê¶Œí•œì´ ë¶€ì—¬ë˜ì§€ 않았ìŒ" -#: catalog/aclchk.c:353 +#: catalog/aclchk.c:355 #, c-format msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\")ì— ëŒ€í•œ ê¶Œí•œì„ ì·¨ì†Œí•  수 ì—†ìŒ" -#: catalog/aclchk.c:358 +#: catalog/aclchk.c:360 #, c-format msgid "no privileges could be revoked for \"%s\"" msgstr "\"%s\"ì— ëŒ€í•œ ê¶Œí•œì„ ì·¨ì†Œí•  수 ì—†ìŒ" -#: catalog/aclchk.c:366 +#: catalog/aclchk.c:368 #, c-format -msgid "" -"not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\")ì˜ ì¼ë¶€ ê¶Œí•œì„ ë°•íƒˆí•  수 ì—†ìŒ" -#: catalog/aclchk.c:371 +#: catalog/aclchk.c:373 #, c-format msgid "not all privileges could be revoked for \"%s\"" msgstr "\"%s\"ì— ëŒ€í•œ ì¼ë¶€ ê¶Œí•œì„ ì·¨ì†Œí•  수 ì—†ìŒ" -#: catalog/aclchk.c:453 catalog/aclchk.c:943 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" msgstr "릴레ì´ì…˜ì˜ %s ê¶Œí•œì€ ìž˜ëª»ëœ ì¢…ë¥˜ìž„" -#: catalog/aclchk.c:457 catalog/aclchk.c:947 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" msgstr "ì‹œí€€ìŠ¤ì˜ %s ê¶Œí•œì€ ìž˜ëª»ëœ ì¢…ë¥˜ìž„" -#: catalog/aclchk.c:461 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "%s ê¶Œí•œì€ ë°ì´í„°ë² ì´ìФì—는 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:465 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "%s ê¶Œí•œì€ ë„ë©”ì¸ì—서 유효하지 않ìŒ" -#: catalog/aclchk.c:469 catalog/aclchk.c:951 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" msgstr "%s ê¶Œí•œì€ í•¨ìˆ˜ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:473 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "%s ê¶Œí•œì€ í”„ë¡œì‹œì£¼ì–¼ 언어ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:477 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" -msgstr "%s ê¶Œí•œì€ ëŒ€í˜• ê°ì²´ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" +msgstr "%s ê¶Œí•œì€ ëŒ€í˜• 개체ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:481 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" msgstr "%s ê¶Œí•œì€ ìŠ¤í‚¤ë§ˆ(schema)ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:485 +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "프로시져용 %s 권한 종류가 잘못ë¨" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "루틴용 %s 권한 종류가 잘못ë¨" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "%s ê¶Œí•œì€ í…Œì´ë¸”스페ì´ìФì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:489 catalog/aclchk.c:955 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" msgstr "%s ê¶Œí•œì€ ìžë£Œí˜•ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:493 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "%s 권한 형ì‹ì€ 외부 ë°ì´í„° 래í¼ì— 유효하지 않ìŒ" -#: catalog/aclchk.c:497 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "%s 권한 형ì‹ì€ 외부 ì„œë²„ì— ìœ íš¨í•˜ì§€ 않ìŒ" -#: catalog/aclchk.c:536 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "칼럼 ê¶Œí•œì€ ë¦´ë ˆì´ì…˜ì—서만 유효함" -#: catalog/aclchk.c:695 catalog/aclchk.c:3923 catalog/aclchk.c:4705 -#: catalog/objectaddress.c:873 catalog/pg_largeobject.c:113 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 +#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 +#: storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" msgstr "%u large object ì—†ìŒ" -#: catalog/aclchk.c:882 catalog/aclchk.c:890 commands/collationcmds.c:92 -#: commands/copy.c:1047 commands/copy.c:1065 commands/copy.c:1073 -#: commands/copy.c:1081 commands/copy.c:1089 commands/copy.c:1097 -#: commands/copy.c:1105 commands/copy.c:1113 commands/copy.c:1121 -#: commands/copy.c:1137 commands/copy.c:1151 commands/copy.c:1170 -#: commands/copy.c:1185 commands/dbcommands.c:155 commands/dbcommands.c:163 -#: commands/dbcommands.c:171 commands/dbcommands.c:179 -#: commands/dbcommands.c:187 commands/dbcommands.c:195 -#: commands/dbcommands.c:203 commands/dbcommands.c:211 -#: commands/dbcommands.c:219 commands/dbcommands.c:1397 -#: commands/dbcommands.c:1405 commands/dbcommands.c:1413 -#: commands/dbcommands.c:1421 commands/extension.c:1219 -#: commands/extension.c:1227 commands/extension.c:1235 -#: commands/extension.c:1243 commands/extension.c:2761 -#: commands/foreigncmds.c:539 commands/foreigncmds.c:548 -#: commands/functioncmds.c:533 commands/functioncmds.c:649 -#: commands/functioncmds.c:657 commands/functioncmds.c:665 -#: commands/functioncmds.c:673 commands/functioncmds.c:2085 -#: commands/functioncmds.c:2093 commands/sequence.c:1189 -#: commands/sequence.c:1197 commands/sequence.c:1205 commands/sequence.c:1213 -#: commands/sequence.c:1221 commands/sequence.c:1229 commands/sequence.c:1237 -#: commands/sequence.c:1245 commands/typecmds.c:295 commands/typecmds.c:1382 -#: commands/typecmds.c:1391 commands/typecmds.c:1399 commands/typecmds.c:1407 -#: commands/typecmds.c:1415 commands/user.c:139 commands/user.c:156 -#: commands/user.c:164 commands/user.c:172 commands/user.c:180 -#: commands/user.c:188 commands/user.c:196 commands/user.c:204 -#: commands/user.c:212 commands/user.c:220 commands/user.c:228 -#: commands/user.c:236 commands/user.c:244 commands/user.c:537 -#: commands/user.c:549 commands/user.c:557 commands/user.c:565 -#: commands/user.c:573 commands/user.c:581 commands/user.c:589 -#: commands/user.c:597 commands/user.c:606 commands/user.c:614 -#: commands/user.c:622 +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 +#: commands/copy.c:1057 commands/copy.c:1077 commands/copy.c:1086 +#: commands/copy.c:1095 commands/copy.c:1104 commands/copy.c:1113 +#: commands/copy.c:1122 commands/copy.c:1131 commands/copy.c:1140 +#: commands/copy.c:1158 commands/copy.c:1174 commands/copy.c:1194 +#: commands/copy.c:1211 commands/dbcommands.c:155 commands/dbcommands.c:164 +#: commands/dbcommands.c:173 commands/dbcommands.c:182 +#: commands/dbcommands.c:191 commands/dbcommands.c:200 +#: commands/dbcommands.c:209 commands/dbcommands.c:218 +#: commands/dbcommands.c:227 commands/dbcommands.c:1427 +#: commands/dbcommands.c:1436 commands/dbcommands.c:1445 +#: commands/dbcommands.c:1454 commands/extension.c:1678 +#: commands/extension.c:1688 commands/extension.c:1698 +#: commands/extension.c:1708 commands/extension.c:2949 +#: commands/foreigncmds.c:537 commands/foreigncmds.c:546 +#: commands/functioncmds.c:558 commands/functioncmds.c:683 +#: commands/functioncmds.c:692 commands/functioncmds.c:701 +#: commands/functioncmds.c:710 commands/functioncmds.c:2104 +#: commands/functioncmds.c:2112 commands/publicationcmds.c:92 +#: commands/sequence.c:1256 commands/sequence.c:1266 commands/sequence.c:1276 +#: commands/sequence.c:1286 commands/sequence.c:1296 commands/sequence.c:1306 +#: commands/sequence.c:1316 commands/sequence.c:1326 commands/sequence.c:1336 +#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 +#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 +#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 +#: commands/subscriptioncmds.c:179 commands/tablecmds.c:6261 +#: commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 +#: commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 +#: commands/user.c:134 commands/user.c:148 commands/user.c:157 +#: commands/user.c:166 commands/user.c:175 commands/user.c:184 +#: commands/user.c:193 commands/user.c:202 commands/user.c:211 +#: commands/user.c:220 commands/user.c:229 commands/user.c:238 +#: commands/user.c:247 commands/user.c:555 commands/user.c:563 +#: commands/user.c:571 commands/user.c:579 commands/user.c:587 +#: commands/user.c:595 commands/user.c:603 commands/user.c:611 +#: commands/user.c:620 commands/user.c:628 commands/user.c:636 +#: parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 +#: replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "ìƒì¶©í•˜ê±°ë‚˜ ì¤‘ë³µëœ ì˜µì…˜ë“¤" -#: catalog/aclchk.c:988 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "default privileges ì„¤ì •ì€ ì¹¼ëŸ¼ 대ìƒìœ¼ë¡œ í•  수 ì—†ìŒ" -#: catalog/aclchk.c:1502 catalog/objectaddress.c:1390 commands/analyze.c:376 -#: commands/copy.c:4458 commands/sequence.c:1491 commands/tablecmds.c:5198 -#: commands/tablecmds.c:5304 commands/tablecmds.c:5364 -#: commands/tablecmds.c:5477 commands/tablecmds.c:5534 -#: commands/tablecmds.c:5628 commands/tablecmds.c:5724 -#: commands/tablecmds.c:7915 commands/tablecmds.c:8177 -#: commands/tablecmds.c:8597 commands/trigger.c:642 parser/analyze.c:2228 -#: parser/parse_relation.c:2628 parser/parse_relation.c:2690 -#: parser/parse_target.c:951 parser/parse_type.c:127 utils/adt/acl.c:2840 -#: utils/adt/ruleutils.c:1984 +#: catalog/aclchk.c:1212 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "GRANT/REVOKE ON SCHEMAS êµ¬ë¬¸ì„ ì“¸ 때는 IN SCHEMA êµ¬ë¬¸ì„ ì“¸ 수 ì—†ìŒ" + +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 +#: commands/copy.c:4776 commands/sequence.c:1691 commands/tablecmds.c:5907 +#: commands/tablecmds.c:6055 commands/tablecmds.c:6112 +#: commands/tablecmds.c:6186 commands/tablecmds.c:6280 +#: commands/tablecmds.c:6339 commands/tablecmds.c:6478 +#: commands/tablecmds.c:6560 commands/tablecmds.c:6652 +#: commands/tablecmds.c:6746 commands/tablecmds.c:9080 +#: commands/tablecmds.c:9359 commands/tablecmds.c:9796 commands/trigger.c:904 +#: parser/analyze.c:2337 parser/parse_relation.c:2735 +#: parser/parse_relation.c:2798 parser/parse_target.c:1024 +#: parser/parse_type.c:127 utils/adt/acl.c:2843 utils/adt/ruleutils.c:2464 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" -msgstr "\"%s\" ì—´ì€ \"%s\" 릴레ì´ì…˜(relation)ì— ì—†ìŒ" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ \"%s\" 릴레ì´ì…˜(relation)ì— ì—†ìŒ" -#: catalog/aclchk.c:1771 catalog/objectaddress.c:1203 commands/sequence.c:1078 -#: commands/tablecmds.c:224 commands/tablecmds.c:12154 utils/adt/acl.c:2076 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1129 +#: commands/tablecmds.c:231 commands/tablecmds.c:13507 utils/adt/acl.c:2076 #: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 #: utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\" 시퀀스가 아님" -#: catalog/aclchk.c:1809 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "\"%s\" 시퀀스는 USAGE, SELECT ë° UPDATE 권한만 ì§€ì›í•¨" -#: catalog/aclchk.c:1826 +#: catalog/aclchk.c:1898 #, c-format -msgid "invalid privilege type USAGE for table" -msgstr "í…Œì´ë¸”ì—서 USAGE ê¶Œí•œì€ ìž˜ëª»ë˜ì—ˆìŒ" +msgid "invalid privilege type %s for table" +msgstr "%s ê¶Œí•œì€ í…Œì´ë¸”ì—서 사용할 수 ì—†ì€ ê¶Œí•œ 형태임" -#: catalog/aclchk.c:1994 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" msgstr "%s 권한 형ì‹ì€ 칼럼ì—서 유효하지 않ìŒ" -#: catalog/aclchk.c:2007 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "\"%s\" 시퀀스는 SELECT ì—´ 권한만 ì§€ì›í•¨" -#: catalog/aclchk.c:2601 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "\"%s\" 프로시주얼 언어는 안전하지 못합니다" -#: catalog/aclchk.c:2603 +#: catalog/aclchk.c:2661 #, c-format -msgid "" -"GRANT and REVOKE are not allowed on untrusted languages, because only " -"superusers can use untrusted languages." -msgstr "" -"안전하지 ì•Šì€ í”„ë¡œì‹œì ¸ ì–¸ì–´ì— ëŒ€í•´ì„œëŠ” GRANT ë˜ëŠ” REVOKE ìž‘ì—…ì„ í—ˆìš©í•˜ì§€ 않습" -"니다, 안전하지 ì•Šì€ í”„ë¡œì‹œì ¸ 언어는 슈í¼ìœ ì €ë§Œ 사용할 수 있기 때문입니다." +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "안전하지 ì•Šì€ í”„ë¡œì‹œì ¸ ì–¸ì–´ì— ëŒ€í•´ì„œëŠ” GRANT ë˜ëŠ” REVOKE ìž‘ì—…ì„ í—ˆìš©í•˜ì§€ 않습니다, 안전하지 ì•Šì€ í”„ë¡œì‹œì ¸ 언어는 슈í¼ìœ ì €ë§Œ 사용할 수 있기 때문입니다." -#: catalog/aclchk.c:3129 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "배열형 ìžë£Œí˜•ì— ê¶Œí•œ ì„¤ì •ì„ í•  수 ì—†ìŒ" -#: catalog/aclchk.c:3130 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "ê·¸ ë°°ì—´ ìš”ì†Œì— í•´ë‹¹í•˜ëŠ” ìžë£Œí˜•ì— ëŒ€í•´ì„œ ì ‘ê·¼ 권한 ì„¤ì •ì„ í•˜ì„¸ìš”." -#: catalog/aclchk.c:3137 catalog/objectaddress.c:1523 commands/typecmds.c:3146 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” ë„ë©”ì¸ì´ 아닙니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” ë„ë©”ì¸ì´ 아닙니다" -#: catalog/aclchk.c:3260 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "알 수 없는 권한 타입 \"%s\"" -#: catalog/aclchk.c:3309 +#: catalog/aclchk.c:3364 #, c-format -msgid "permission denied for column %s" -msgstr "%s ì¹¼ëŸ¼ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for aggregate %s" +msgstr "%s ì§‘ê³„í•¨ìˆ˜ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for collation %s" +msgstr "%s 정렬정ì˜(collation) ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3311 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for relation %s" -msgstr "%s 릴레ì´ì…˜(relation) ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for column %s" +msgstr "%s ì¹¼ëŸ¼ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3313 commands/sequence.c:561 commands/sequence.c:786 -#: commands/sequence.c:828 commands/sequence.c:865 commands/sequence.c:1543 +#: catalog/aclchk.c:3373 #, c-format -msgid "permission denied for sequence %s" -msgstr "%s 시퀀스 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for conversion %s" +msgstr "%s 문ìžì½”드변환규칙(conversion) ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3315 +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" msgstr "%s ë°ì´í„°ë² ì´ìФ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3317 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "%s 함수 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for domain %s" +msgstr "%s ë„ë©”ì¸ì— 대한 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3319 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "%s ì—°ì‚°ìž ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for event trigger %s" +msgstr "%s ì´ë²¤íЏ 트리거 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3321 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "%s ìžë£Œí˜• ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for extension %s" +msgstr "%s 확장 모듈 ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "%s 외부 ë°ì´í„° ëž˜í¼ ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "%s 외부 서버 ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "%s 외부 í…Œì´ë¸” ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "%s 함수 ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "%s ì¸ë±ìФ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3323 +#: catalog/aclchk.c:3403 #, c-format msgid "permission denied for language %s" msgstr "%s 프로시주얼 언어 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3325 +#: catalog/aclchk.c:3406 #, c-format msgid "permission denied for large object %s" -msgstr "%s 대형 ê°ì²´ ì ‘ê·¼ 권한 ì—†ìŒ" +msgstr "%s 대형 개체 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3327 +#: catalog/aclchk.c:3409 #, c-format -msgid "permission denied for schema %s" -msgstr "%s 스키마(schema) ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for materialized view %s" +msgstr "%s êµ¬ì²´í™”ëœ ë·°ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3329 +#: catalog/aclchk.c:3412 #, c-format msgid "permission denied for operator class %s" msgstr "%s ì—°ì‚°ìž í´ëž˜ìФ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3331 +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "%s ì—°ì‚°ìž ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" msgstr "%s ì—°ì‚°ìž íŒ¨ë°€ë¦¬ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3333 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "%s 정렬정ì˜(collation) ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for policy %s" +msgstr "%s ì •ì±…ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3335 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "%s 문ìžì½”드변환규칙(conversion) ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for procedure %s" +msgstr "%s í”„ë¡œì‹œì ¸ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3337 +#: catalog/aclchk.c:3427 #, c-format -msgid "permission denied for tablespace %s" -msgstr "%s í…Œì´ë¸”스페ì´ìФ ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for publication %s" +msgstr "%s 발행 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3339 +#: catalog/aclchk.c:3430 #, c-format -msgid "permission denied for text search dictionary %s" -msgstr "%s 전문 검색 사전 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for routine %s" +msgstr "%s ë£¨í‹´ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "%s 스키마(schema) ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3436 commands/sequence.c:599 commands/sequence.c:833 +#: commands/sequence.c:875 commands/sequence.c:916 commands/sequence.c:1789 +#: commands/sequence.c:1853 +#, c-format +msgid "permission denied for sequence %s" +msgstr "%s 시퀀스 ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3439 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "%s 개체 통계정보 ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "%s êµ¬ë… ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "%s í…Œì´ë¸”ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" + +#: catalog/aclchk.c:3448 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "%s í…Œì´ë¸”스페ì´ìФ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3341 +#: catalog/aclchk.c:3451 #, c-format msgid "permission denied for text search configuration %s" msgstr "%s 전문 검색 구성 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3343 +#: catalog/aclchk.c:3454 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "%s 외부 ë°ì´í„° ëž˜í¼ ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for text search dictionary %s" +msgstr "%s 전문 검색 사전 ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3345 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for foreign server %s" -msgstr "%s 외부 서버 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for type %s" +msgstr "%s ìžë£Œí˜• ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3347 +#: catalog/aclchk.c:3460 #, c-format -msgid "permission denied for event trigger %s" -msgstr "%s ì´ë²¤íЏ 트리거 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "permission denied for view %s" +msgstr "%s ë·°ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3349 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for extension %s" -msgstr "%s 확장 모듈 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "must be owner of aggregate %s" +msgstr "%s ì§‘ê³„í•¨ìˆ˜ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3355 catalog/aclchk.c:3357 +#: catalog/aclchk.c:3498 #, c-format -msgid "must be owner of relation %s" -msgstr "%s 릴레ì´ì…˜(relation)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of collation %s" +msgstr "%s 정렬정ì˜(collation)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3359 +#: catalog/aclchk.c:3501 #, c-format -msgid "must be owner of sequence %s" -msgstr "%s ì‹œí€€ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of conversion %s" +msgstr "%s 문ìžì½”드변환규칙(conversion)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3361 +#: catalog/aclchk.c:3504 #, c-format msgid "must be owner of database %s" msgstr "%s ë°ì´í„°ë² ì´ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3363 +#: catalog/aclchk.c:3507 #, c-format -msgid "must be owner of function %s" -msgstr "%s í•¨ìˆ˜ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of domain %s" +msgstr "%s ë„ë©”ì¸ì˜ 소유주여야만 합니다" -#: catalog/aclchk.c:3365 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of operator %s" -msgstr "%s ì—°ì‚°ìžì˜ 소유주여야만 합니다" +msgid "must be owner of event trigger %s" +msgstr "%s ì´ë²¤íЏ íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3367 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of type %s" -msgstr "%s ìžë£Œí˜•ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of extension %s" +msgstr "%s 확장 ëª¨ë“ˆì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "%s 외부 ë°ì´í„° 래í¼ì˜ 소유주여야 함" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "%s 외부 ì„œë²„ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "%s 외부 í…Œì´ë¸”ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" -#: catalog/aclchk.c:3369 +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of function %s" +msgstr "%s í•¨ìˆ˜ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "%s ì¸ë±ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" msgstr "%s 프로시주얼 ì–¸ì–´ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3371 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" -msgstr "%s 대형 ê°ì²´ì˜ 소유주여야만 합니다" +msgstr "%s 대형 ê°œì²´ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3373 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "%s 스키마(schema)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of materialized view %s" +msgstr "%s êµ¬ì²´í™”ëœ ë·°ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3375 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" msgstr "%s ì—°ì‚°ìž í´ëž˜ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3377 +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "%s ì—°ì‚°ìžì˜ 소유주여야만 합니다" + +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" msgstr "%s ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" -#: catalog/aclchk.c:3379 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "%s 정렬정ì˜(collation)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of procedure %s" +msgstr "%s í”„ë¡œì‹œì ¸ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3381 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "%s 문ìžì½”드변환규칙(conversion)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of publication %s" +msgstr "%s ë°œí–‰ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3383 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of tablespace %s" -msgstr "%s í…Œì´ë¸”스페ì´ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of routine %s" +msgstr "%s ë£¨í‹´ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3385 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "%s 전문 검색 ì‚¬ì „ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" +msgid "must be owner of sequence %s" +msgstr "%s ì‹œí€€ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3387 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "%s 전문 검색 êµ¬ì„±ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" +msgid "must be owner of subscription %s" +msgstr "%s 구ë…ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3389 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "%s 외부 ë°ì´í„° 래í¼ì˜ 소유주여야 함" +msgid "must be owner of table %s" +msgstr "%s í…Œì´ë¸”ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3391 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign server %s" -msgstr "%s 외부 ì„œë²„ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" +msgid "must be owner of type %s" +msgstr "%s ìžë£Œí˜•ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3393 +#: catalog/aclchk.c:3570 #, c-format -msgid "must be owner of event trigger %s" -msgstr "%s ì´ë²¤íЏ íŠ¸ë¦¬ê±°ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of view %s" +msgstr "%s ë·°ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3395 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of extension %s" -msgstr "%s 확장 ëª¨ë“ˆì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" +msgid "must be owner of schema %s" +msgstr "%s 스키마(schema)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3576 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "%s 통계정보 ê°œì²´ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3579 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "%s í…Œì´ë¸”스페ì´ìŠ¤ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" + +#: catalog/aclchk.c:3582 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "%s 전문 검색 êµ¬ì„±ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" + +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "%s 전문 검색 ì‚¬ì „ì˜ ì†Œìœ ì£¼ì—¬ì•¼ 함" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "%s 릴레ì´ì…˜(relation)ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/aclchk.c:3437 +#: catalog/aclchk.c:3643 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\") ì ‘ê·¼ 권한 ì—†ìŒ" -#: catalog/aclchk.c:3556 catalog/aclchk.c:3564 +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "%d번째 ì†ì„±(해당 릴레ì´ì…˜ OID: %u)ì´ ì—†ìŒ" -#: catalog/aclchk.c:3637 catalog/aclchk.c:4556 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" msgstr "OID %u 릴레ì´ì…˜(relation) ì—†ìŒ" -#: catalog/aclchk.c:3736 catalog/aclchk.c:4974 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "OID %u ë°ì´í„°ë² ì´ìФ ì—†ìŒ" -#: catalog/aclchk.c:3790 catalog/aclchk.c:4634 tcop/fastpath.c:223 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "OID %u 함수 ì—†ìŒ" -#: catalog/aclchk.c:3844 catalog/aclchk.c:4660 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" msgstr "OID %u 언어 ì—†ìŒ" -#: catalog/aclchk.c:4008 catalog/aclchk.c:4732 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" msgstr "OID %u 스키마 ì—†ìŒ" -#: catalog/aclchk.c:4062 catalog/aclchk.c:4759 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" msgstr "OID %u í…Œì´ë¸”스페ì´ìФ ì—†ìŒ" -#: catalog/aclchk.c:4121 catalog/aclchk.c:4893 commands/foreigncmds.c:325 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "OIDê°€ %uì¸ ì™¸ë¶€ ë°ì´í„° 래í¼ê°€ ì—†ìŒ" -#: catalog/aclchk.c:4183 catalog/aclchk.c:4920 commands/foreigncmds.c:461 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" msgstr "OIDê°€ %uì¸ ì™¸ë¶€ 서버가 ì—†ìŒ" -#: catalog/aclchk.c:4243 catalog/aclchk.c:4582 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" msgstr "OID %u ìžë£Œí˜• ì—†ìŒ" -#: catalog/aclchk.c:4608 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" msgstr "OID %u ì—°ì‚°ìž ì—†ìŒ" -#: catalog/aclchk.c:4785 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" msgstr "OID %u ì—°ì‚°ìž í´ëž˜ìФ ì—†ìŒ" -#: catalog/aclchk.c:4812 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" msgstr "OIDê°€ %uì¸ ì—°ì‚°ìž íŒ¨ë°€ë¦¬ê°€ ì—†ìŒ" -#: catalog/aclchk.c:4839 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "OIDê°€ %uì¸ ì „ë¬¸ 검색 ì‚¬ì „ì´ ì—†ìŒ" -#: catalog/aclchk.c:4866 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "OIDê°€ %uì¸ í…스트 검색 êµ¬ì„±ì´ ì—†ìŒ" -#: catalog/aclchk.c:4947 commands/event_trigger.c:587 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format msgid "event trigger with OID %u does not exist" msgstr "OID %u ì´ë²¤íЏ 트리거가 ì—†ìŒ" -#: catalog/aclchk.c:5000 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" msgstr "OID %u 정렬정ì˜(collation) ì—†ìŒ" -#: catalog/aclchk.c:5026 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" msgstr "OID %u ì¸ì½”딩 변환규칙(conversion) ì—†ìŒ" -#: catalog/aclchk.c:5067 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" msgstr "OID %u 확장 ëª¨ë“ˆì´ ì—†ìŒ" -#: catalog/dependency.c:645 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "OID %u 발행 ì—†ìŒ" + +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "OID %u êµ¬ë… ì—†ìŒ" + +#: catalog/aclchk.c:5354 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "OID %u 통계정보 개체 ì—†ìŒ" + +#: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" msgstr "%s 삭제할 수 ì—†ìŒ, %sì—서 필요로함" -#: catalog/dependency.c:648 +#: catalog/dependency.c:614 #, c-format msgid "You can drop %s instead." msgstr "대신ì—, drop %s ëª…ë ¹ì„ ì‚¬ìš©í•  수 있ìŒ." -#: catalog/dependency.c:810 catalog/pg_shdepend.c:576 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" -msgstr "%s ê°ì²´ëŠ” ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ ì—†ìŒ" +msgstr "%s 개체는 ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ ì—†ìŒ" -#: catalog/dependency.c:926 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" -msgstr "%s ê°ì²´ê°€ ìžë™ìœ¼ë¡œ ë©ë‹¬ì•„ ì‚­ì œë¨" +msgstr "%s 개체가 ìžë™ìœ¼ë¡œ ë©ë‹¬ì•„ ì‚­ì œë¨" -#: catalog/dependency.c:938 catalog/dependency.c:947 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" msgstr "%s ì˜ì¡´ëŒ€ìƒ: %s" -#: catalog/dependency.c:959 catalog/dependency.c:968 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" -msgstr "%s ê°ì²´ê°€ ë©ë‹¬ì•„ ì‚­ì œë¨" +msgstr "%s 개체가 ë©ë‹¬ì•„ ì‚­ì œë¨" -#: catalog/dependency.c:976 catalog/pg_shdepend.c:687 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -3996,489 +3664,430 @@ msgid_plural "" "\n" "and %d other objects (see server log for list)" msgstr[0] "" -msgstr[1] "" +"\n" +"%d ê°œì˜ ê¸°íƒ€ ê°œì²´ë“¤ë„ í•¨ê»˜ 처리함 (목ë¡ì€ 서버 ë¡œê·¸ì— ê¸°ë¡ë¨)" -#: catalog/dependency.c:988 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" -msgstr "기타 다른 ê°ì²´ë“¤ì´ ì´ ê°ì²´ì— ì˜ì¡´í•˜ê³  있어, %s 삭제할 수 ì—†ìŒ" +msgstr "기타 다른 ê°œì²´ë“¤ì´ ì´ ê°œì²´ì— ì˜ì¡´í•˜ê³  있어, %s 삭제할 수 ì—†ìŒ" -#: catalog/dependency.c:992 catalog/dependency.c:999 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." -msgstr "" -"ì´ ê°ì²´ì™€ ê´€ê³„ëœ ëª¨ë“  ê°ì²´ë“¤ì„ 함께 삭제하려면 DROP ... CASCADE ëª…ë ¹ì„ ì‚¬ìš©í•˜" -"십시오" +msgstr "ì´ ê°œì²´ì™€ ê´€ê³„ëœ ëª¨ë“  ê°œì²´ë“¤ì„ í•¨ê»˜ 삭제하려면 DROP ... CASCADE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤" -#: catalog/dependency.c:996 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" -msgstr "다른 ê°ì²´ê°€ ì›í•˜ëŠ” ê°ì²´ë¥¼ 사용하고 있으므로 해당 ê°ì²´ë¥¼ 삭제할 수 ì—†ìŒ" +msgstr "다른 개체가 ì›í•˜ëŠ” 개체를 사용하고 있으므로 해당 개체를 삭제할 수 ì—†ìŒ" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:1005 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" -msgstr[0] "%dê°œì˜ ë‹¤ë¥¸ ê°ì²´ì— 대한 관련 항목 ì‚­ì œ" +msgstr[0] "%dê°œì˜ ë‹¤ë¥¸ ê°œì²´ì— ëŒ€í•œ 관련 항목 ì‚­ì œ" -#: catalog/dependency.c:1633 +#: catalog/dependency.c:1644 #, c-format -msgid "constant of the type \"regrole\" cannot be used here" -msgstr "\"regrole\" ìžë£Œí˜• ìƒìˆ˜ëŠ” 여기서 사용할 수 ì—†ìŒ" +msgid "constant of the type %s cannot be used here" +msgstr "%s ìžë£Œí˜•ì€ ì—¬ê¸°ì„œ 사용할 수 ì—†ìŒ" -#: catalog/heap.c:278 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "\"%s.%s\" 만들 ê¶Œí•œì´ ì—†ìŒ" -#: catalog/heap.c:280 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "시스템 카탈로그 ë³€ê²½ì€ í˜„ìž¬ 허용하지 않습니다." -#: catalog/heap.c:415 commands/tablecmds.c:1439 commands/tablecmds.c:1896 -#: commands/tablecmds.c:4820 +#: catalog/heap.c:425 commands/tablecmds.c:1861 commands/tablecmds.c:2385 +#: commands/tablecmds.c:5474 #, c-format msgid "tables can have at most %d columns" msgstr "한 í…Œì´ë¸”ì— ì§€ì •í•  수 있는 최대 ì—´ 수는 %d입니다" -#: catalog/heap.c:432 commands/tablecmds.c:5081 +#: catalog/heap.c:444 commands/tablecmds.c:5770 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "\"%s\" ì—´ ì´ë¦„ì€ ì‹œìŠ¤í…œ ì—´ ì´ë¦„ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤" -#: catalog/heap.c:448 +#: catalog/heap.c:460 #, c-format msgid "column name \"%s\" specified more than once" msgstr "\"%s\" 칼럼 ì´ë¦„ì´ ì—¬ëŸ¬ 번 지정ë¨" -#: catalog/heap.c:498 -#, c-format -msgid "column \"%s\" has type \"unknown\"" -msgstr "\"%s\" ì—´ì˜ ìžë£Œí˜•ì´ \"unknown\" 입니다" - -#: catalog/heap.c:499 -#, c-format -msgid "Proceeding with relation creation anyway." -msgstr "관계 ìž‘ì„±ì„ ê³„ì†í•©ë‹ˆë‹¤." - -#: catalog/heap.c:512 +#: catalog/heap.c:513 #, c-format msgid "column \"%s\" has pseudo-type %s" -msgstr "\"%s\" ì—´ì€ %s ì˜ì‚¬ ìžë£Œí˜•(pseudo-type)ì„ ì‚¬ìš©í•©ë‹ˆë‹¤" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ %s ì˜ì‚¬ ìžë£Œí˜•(pseudo-type)ì„ ì‚¬ìš©í•©ë‹ˆë‹¤" -#: catalog/heap.c:542 +#: catalog/heap.c:543 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "%s 복합 ìžë£Œí˜•ì€ ìžê¸° ìžì‹ ì˜ 구성ì›ìœ¼ë¡œ 만들 수 ì—†ìŒ" -#: catalog/heap.c:584 commands/createas.c:201 commands/createas.c:498 +#: catalog/heap.c:585 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" -msgstr "" -"column \"%s\" ì¹¼ëŸ¼ì— ì‚¬ìš©í•˜ëŠ” %s ìžë£Œí˜•ì—서 사용할 ì •ë ¬ê·œì¹™ì„ ê²°ì •í•  수 없습" -"니다." +msgstr "column \"%s\" ì¹¼ëŸ¼ì— ì‚¬ìš©í•˜ëŠ” %s ìžë£Œí˜•ì—서 사용할 ì •ë ¬ê·œì¹™ì„ ê²°ì •í•  수 없습니다." -#: catalog/heap.c:586 commands/createas.c:204 commands/createas.c:501 -#: commands/indexcmds.c:1133 commands/view.c:103 regex/regc_pg_locale.c:262 -#: utils/adt/formatting.c:1513 utils/adt/formatting.c:1565 -#: utils/adt/formatting.c:1633 utils/adt/formatting.c:1685 -#: utils/adt/formatting.c:1754 utils/adt/formatting.c:1818 -#: utils/adt/like.c:213 utils/adt/selfuncs.c:5334 utils/adt/varlena.c:1421 -#: utils/adt/varlena.c:1826 +#: catalog/heap.c:587 commands/createas.c:204 commands/createas.c:501 +#: commands/indexcmds.c:1577 commands/tablecmds.c:13793 commands/view.c:103 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 +#: utils/adt/selfuncs.c:5807 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "명시ì ìœ¼ë¡œ ì •ë ¬ ê·œì¹™ì„ ì§€ì •í•˜ë ¤ë©´ COLLATE ì ˆì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: catalog/heap.c:1067 catalog/index.c:792 commands/tablecmds.c:2623 +#: catalog/heap.c:1076 catalog/index.c:870 commands/tablecmds.c:3148 #, c-format msgid "relation \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ë¦´ë ˆì´ì…˜(relation)ì´ ì´ë¯¸ 있습니다" -#: catalog/heap.c:1083 catalog/pg_type.c:412 catalog/pg_type.c:722 -#: commands/typecmds.c:237 commands/typecmds.c:784 commands/typecmds.c:1135 -#: commands/typecmds.c:1357 commands/typecmds.c:2113 +#: catalog/heap.c:1092 catalog/pg_type.c:409 catalog/pg_type.c:731 +#: commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 +#: commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "\"%s\" ìžë£Œí˜•ì´ ì´ë¯¸ 있습니다" -#: catalog/heap.c:1084 +#: catalog/heap.c:1093 #, c-format -msgid "" -"A relation has an associated type of the same name, so you must use a name " -"that doesn't conflict with any existing type." -msgstr "" -"í•˜ë‚˜ì˜ ë¦´ë ˆì´ì…˜ì€ ê·¸ ì´ë¦„ê³¼ ê°™ì€ ìžë£Œí˜•ê³¼ 관계합니다. 그래서, ì´ë¯¸ ê°™ì€ ì´ë¦„" -"ì˜ ìžë£Œí˜•ì´ ìžˆë‹¤ë©´ 해당 릴레ì´ì…˜ì„ 만들 수 없습니다. 다른 ì´ë¦„ì„ ì‚¬ìš©í•˜ì„¸ìš”." +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "í•˜ë‚˜ì˜ ë¦´ë ˆì´ì…˜ì€ ê·¸ ì´ë¦„ê³¼ ê°™ì€ ìžë£Œí˜•ê³¼ 관계합니다. 그래서, ì´ë¯¸ ê°™ì€ ì´ë¦„ì˜ ìžë£Œí˜•ì´ ìžˆë‹¤ë©´ 해당 릴레ì´ì…˜ì„ 만들 수 없습니다. 다른 ì´ë¦„ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: catalog/heap.c:1112 +#: catalog/heap.c:1122 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때, pg_class ìžë£Œ OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: catalog/heap.c:2291 +#: catalog/heap.c:2334 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "\"%s\" 파티션 í…Œì´ë¸”ì—는 NO INHERIT ì¡°ê±´ì„ ì‚¬ìš©í•  수 ì—†ìŒ" + +#: catalog/heap.c:2599 #, c-format msgid "check constraint \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì²´í¬ ì œì•½ ì¡°ê±´ì´ ì´ë¯¸ 있습니다" -#: catalog/heap.c:2456 catalog/pg_constraint.c:654 commands/tablecmds.c:6069 +#: catalog/heap.c:2769 catalog/index.c:884 catalog/pg_constraint.c:916 +#: commands/tablecmds.c:7122 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" -msgstr "" -"\"%s\" 제약 ì¡°ê±´ì´ ì´ë¯¸ \"%s\" 릴레ì´ì…˜(relation)ì—서 사용ë˜ê³  있습니다" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ ì´ë¯¸ \"%s\" 릴레ì´ì…˜(relation)ì—서 사용ë˜ê³  있습니다" -#: catalog/heap.c:2463 +#: catalog/heap.c:2776 #, c-format -msgid "" -"constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" -msgstr "" -"\"%s\" 제약 ì¡°ê±´ì´ ë¹„ìƒì† 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤, 해당 릴레ì´ì…˜: \"%s\"" +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ ë¹„ìƒì† 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤, 해당 릴레ì´ì…˜: \"%s\"" -#: catalog/heap.c:2474 +#: catalog/heap.c:2787 #, c-format -msgid "" -"constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "\"%s\" 제약 ì¡°ê±´ì´ ìƒì† 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤, 해당 릴레ì´ì…˜: \"%s\"" -#: catalog/heap.c:2484 +#: catalog/heap.c:2797 #, c-format -msgid "" -"constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" -msgstr "" -"\"%s\" 제약 ì¡°ê±´ì´ NOT VALID 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤, 해당 릴레ì´ì…˜: \"%s\"" +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ NOT VALID 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤, 해당 릴레ì´ì…˜: \"%s\"" -#: catalog/heap.c:2489 +#: catalog/heap.c:2802 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "\"%s\" 제약 ì¡°ê±´ì„ ìƒì†ëœ ì •ì˜ì™€ 병합하는 중" -#: catalog/heap.c:2595 +#: catalog/heap.c:2917 #, c-format msgid "cannot use column references in default expression" msgstr "default 표현ì‹ì—서는 ì—´ reference를 사용할 수 ì—†ìŒ" -#: catalog/heap.c:2606 -#, c-format -msgid "default expression must not return a set" -msgstr "default 표현ì‹ì€ í•˜ë‚˜ì˜ setì„ ë°˜í™˜í•˜ë©´ 안ë©ë‹ˆë‹¤" - -#: catalog/heap.c:2625 rewrite/rewriteHandler.c:1084 +#: catalog/heap.c:2942 rewrite/rewriteHandler.c:1177 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" -msgstr "" -"\"%s\" ì—´ì˜ ìžë£Œí˜•ì€ %s ì¸ë°, default 표현ì‹ì—서는 %s ìžë£Œí˜•ì„ ì‚¬ìš©í–ˆìŠµë‹ˆë‹¤" +msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì€ %s ì¸ë°, default 표현ì‹ì—서는 %s ìžë£Œí˜•ì„ ì‚¬ìš©í–ˆìŠµë‹ˆë‹¤" -#: catalog/heap.c:2630 commands/prepare.c:374 parser/parse_node.c:428 -#: parser/parse_target.c:539 parser/parse_target.c:789 -#: parser/parse_target.c:799 rewrite/rewriteHandler.c:1089 +#: catalog/heap.c:2947 commands/prepare.c:384 parser/parse_node.c:430 +#: parser/parse_target.c:590 parser/parse_target.c:859 +#: parser/parse_target.c:869 rewrite/rewriteHandler.c:1182 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "다시 ì •ì˜í•˜ê±°ë‚˜ 형변화ìžë¥¼ 사용해보십시오" -#: catalog/heap.c:2677 +#: catalog/heap.c:2994 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "\"%s\" í…Œì´ë¸”ë§Œì´ ì²´í¬ ì œì•½ ì¡°ê±´ì—서 ì°¸ì¡°ë  ìˆ˜ 있습니다" -#: catalog/heap.c:2917 +#: catalog/heap.c:3237 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "ON COMMIT ë° ì™¸ëž˜ 키 ì¡°í•©ì´ ì§€ì›ë˜ì§€ 않ìŒ" -#: catalog/heap.c:2918 +#: catalog/heap.c:3238 #, c-format -msgid "" -"Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " -"setting." -msgstr "" -"\"%s\" í…Œì´ë¸”ì—서 \"%s\" í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ëŠ”ë° ON COMMIT ì„¤ì •ì´ ê°™ì§€ 않습니다." +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "\"%s\" í…Œì´ë¸”ì—서 \"%s\" í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ëŠ”ë° ON COMMIT ì„¤ì •ì´ ê°™ì§€ 않습니다." -#: catalog/heap.c:2923 +#: catalog/heap.c:3243 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" -msgstr "" -"_^_ í…Œì´ë¸” ë‚´ìš©ì„ ëª¨ë‘ ì‚­ì œí•  수 ì—†ìŒ, 참조키(foreign key) 제약 ì¡°ê±´ 안ì—서" +msgstr "_^_ í…Œì´ë¸” ë‚´ìš©ì„ ëª¨ë‘ ì‚­ì œí•  수 ì—†ìŒ, 참조키(foreign key) 제약 ì¡°ê±´ 안ì—서" -#: catalog/heap.c:2924 +#: catalog/heap.c:3244 #, c-format msgid "Table \"%s\" references \"%s\"." -msgstr "\"%s\" í…Œì´ë¸”ì€ \"%s\" ê°ì²´ë¥¼ 참조합니다." +msgstr "\"%s\" í…Œì´ë¸”ì€ \"%s\" 개체를 참조합니다." -#: catalog/heap.c:2926 +#: catalog/heap.c:3246 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." -msgstr "" -"\"%s\" í…Œì´ë¸”ë„ í•¨ê»˜ ìžë£Œë¥¼ 지우거나, TRUNCATE ... CASCADE êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." +msgstr "\"%s\" í…Œì´ë¸”ë„ í•¨ê»˜ ìžë£Œë¥¼ 지우거나, TRUNCATE ... CASCADE êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: catalog/index.c:210 parser/parse_utilcmd.c:1473 parser/parse_utilcmd.c:1559 +#: catalog/index.c:231 parser/parse_utilcmd.c:1825 parser/parse_utilcmd.c:1912 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "\"%s\" í…Œì´ë¸”ì—는 ì´ë¯¸ 기본키가 있습니다" -#: catalog/index.c:228 +#: catalog/index.c:249 #, c-format msgid "primary keys cannot be expressions" msgstr "기본기(primary key)를 표현할 수 ì—†ìŒ" -#: catalog/index.c:742 catalog/index.c:1160 +#: catalog/index.c:814 catalog/index.c:1285 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "시스템 카탈로그 í…Œì´ë¸”ì—는 ì‚¬ìš©ìž ì •ì˜ ì¸ë±ìŠ¤ë¥¼ 지정할 수 없습니다" -#: catalog/index.c:752 +#: catalog/index.c:824 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "시스템 카탈로그 í…Œì´ë¸”ì—서 공존하는 ì¸ë±ìФ 만들기는 ì§€ì›í•˜ì§€ 않습니다" -#: catalog/index.c:770 +#: catalog/index.c:842 #, c-format msgid "shared indexes cannot be created after initdb" -msgstr "" -"공유ë˜ëŠ” ì¸ë±ìŠ¤ë“¤ì€ initdb 명령으로 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 만든 다ìŒì—는 ë§Œ" -"들 수 없습니다" +msgstr "공유ë˜ëŠ” ì¸ë±ìŠ¤ë“¤ì€ initdb 명령으로 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 만든 다ìŒì—는 만들 수 없습니다" -#: catalog/index.c:784 commands/createas.c:249 commands/sequence.c:141 -#: parser/parse_utilcmd.c:191 +#: catalog/index.c:862 commands/createas.c:250 commands/sequence.c:152 +#: parser/parse_utilcmd.c:205 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "\"%s\" ì´ë¦„ì˜ ë¦´ë ˆì´ì…˜(relation)ì´ ì´ë¯¸ 있습니다, 건너뜀" -#: catalog/index.c:820 +#: catalog/index.c:912 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때, pg_class ì¸ë±ìФ OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: catalog/index.c:1422 +#: catalog/index.c:1560 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY ëª…ë ¹ì€ íŠ¸ëžœìž­ì…˜ ë‚´ 가장 처ìŒì— 있어야 합니다" -#: catalog/index.c:2004 +#: catalog/index.c:2289 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "\"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" í…Œì´ë¸”ì— ì´ì–´ 만드는 중" + +#: catalog/index.c:2294 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "\"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" í…Œì´ë¸”ì—서 만드는 중" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "\"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" í…Œì´ë¸”ì—서 만드는 중, 병렬 작업ìžìˆ˜: %d" -#: catalog/index.c:3322 +#: catalog/index.c:3683 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "임시 í…Œì´ë¸”ì˜ ì¸ë±ìФ 재ìƒì„± ìž‘ì—…ì€ ë‹¤ë¥¸ 세션ì—서 í•  수 ì—†ìŒ" -#: catalog/index.c:3454 +#: catalog/index.c:3814 #, c-format msgid "index \"%s\" was reindexed" msgstr "\"%s\" ì¸ë±ìŠ¤ê°€ 다시 만들어졌ìŒ" -#: catalog/index.c:3456 commands/vacuumlazy.c:1338 commands/vacuumlazy.c:1414 -#: commands/vacuumlazy.c:1603 commands/vacuumlazy.c:1813 +#: catalog/index.c:3885 #, c-format -msgid "%s." -msgstr "%s." +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì˜ REINDEX ìž‘ì—…ì€ ì•„ì§ êµ¬í˜„ë˜ì§€ 않았ìŒ, \"%s\" 건너뜀" -#: catalog/namespace.c:249 catalog/namespace.c:447 catalog/namespace.c:541 -#: commands/trigger.c:4523 +#: catalog/namespace.c:248 catalog/namespace.c:452 catalog/namespace.c:546 +#: commands/trigger.c:5397 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "서로 다른 ë°ì´í„°ë² ì´ìŠ¤ê°„ì˜ ì°¸ì¡°ëŠ” 구현ë˜ì–´ìžˆì§€ 않습니다: \"%s.%s.%s\"" -#: catalog/namespace.c:306 +#: catalog/namespace.c:305 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "임시 í…Œì´ë¸”ì€ ìŠ¤í‚¤ë§ˆ ì´ë¦„ì„ ì§€ì •í•  수 ì—†ìŒ" -#: catalog/namespace.c:385 +#: catalog/namespace.c:386 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "\"%s.%s\" 릴레ì´ì…˜ì˜ 잠금 정보를 구할 수 ì—†ìŒ" -#: catalog/namespace.c:390 commands/lockcmds.c:146 +#: catalog/namespace.c:391 commands/lockcmds.c:152 commands/lockcmds.c:238 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì˜ 잠금 정보를 구할 수 ì—†ìŒ" -#: catalog/namespace.c:414 parser/parse_relation.c:1138 +#: catalog/namespace.c:419 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "\"%s.%s\" ì´ë¦„ì˜ ë¦´ë ˆì´ì…˜(relation)ì´ ì—†ìŠµë‹ˆë‹¤" -#: catalog/namespace.c:419 parser/parse_relation.c:1151 -#: parser/parse_relation.c:1159 utils/adt/regproc.c:1034 +#: catalog/namespace.c:424 parser/parse_relation.c:1171 +#: parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ë¦´ë ˆì´ì…˜(relation)ì´ ì—†ìŠµë‹ˆë‹¤" -#: catalog/namespace.c:487 catalog/namespace.c:2841 commands/extension.c:1383 -#: commands/extension.c:1389 +#: catalog/namespace.c:492 catalog/namespace.c:3011 commands/extension.c:1466 +#: commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "ì„ íƒëœ 스키마 ì—†ìŒ, 대ìƒ:" -#: catalog/namespace.c:639 catalog/namespace.c:652 +#: catalog/namespace.c:644 catalog/namespace.c:657 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ 스키마 안ì—는 릴레ì´ì…˜ì„ 만들 수 ì—†ìŒ" -#: catalog/namespace.c:643 +#: catalog/namespace.c:648 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "임시 스키마가 아닌 ìŠ¤í‚¤ë§ˆì— ìž„ì‹œ 릴레ì´ì…˜ì„ 만들 수 ì—†ìŒ" -#: catalog/namespace.c:658 +#: catalog/namespace.c:663 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "임시 스키마 안ì—는 임시 릴레ì´ì…˜ë§Œ 만들 수 있ìŒ" -#: catalog/namespace.c:2154 +#: catalog/namespace.c:2201 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "\"%s\" 통계정보 개체가 ì—†ìŒ" + +#: catalog/namespace.c:2324 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "\"%s\" 전문 검색 파서가 ì—†ìŒ" -#: catalog/namespace.c:2280 +#: catalog/namespace.c:2450 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "\"%s\" 전문 검색 ì‚¬ì „ì´ ì—†ìŒ" -#: catalog/namespace.c:2407 +#: catalog/namespace.c:2577 #, c-format msgid "text search template \"%s\" does not exist" msgstr "\"%s\" 전문 검색 í…œí”Œë¦¿ì´ ì—†ìŒ" -#: catalog/namespace.c:2533 commands/tsearchcmds.c:1197 -#: utils/cache/ts_cache.c:611 +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1185 +#: utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "\"%s\" 전문 검색 êµ¬ì„±ì´ ì—†ìŒ" -#: catalog/namespace.c:2646 parser/parse_expr.c:792 parser/parse_target.c:1141 +#: catalog/namespace.c:2816 parser/parse_expr.c:793 parser/parse_target.c:1214 #, c-format msgid "cross-database references are not implemented: %s" msgstr "서로 다른 ë°ì´í„°ë² ì´ìŠ¤ê°„ì˜ ì°¸ì¡°ëŠ” 구현ë˜ì–´ìžˆì§€ 않습니다: %s" -#: catalog/namespace.c:2652 parser/parse_expr.c:799 parser/parse_target.c:1148 -#: gram.y:13454 gram.y:14823 +#: catalog/namespace.c:2822 gram.y:14712 gram.y:16144 parser/parse_expr.c:800 +#: parser/parse_target.c:1221 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "ì ë‹¹í•˜ì§€ ì•Šì€ qualified ì´ë¦„ 입니다 (너무 ë§Žì€ ì ì´ 있네요): %s" -#: catalog/namespace.c:2783 +#: catalog/namespace.c:2953 #, c-format msgid "cannot move objects into or out of temporary schemas" -msgstr "임시 스키마로(ì—서) ê°ì²´ë¥¼ ì´ë™í•  수 없습니다" +msgstr "임시 스키마로(ì—서) 개체를 ì´ë™í•  수 없습니다" -#: catalog/namespace.c:2789 +#: catalog/namespace.c:2959 #, c-format msgid "cannot move objects into or out of TOAST schema" -msgstr "TOAST 스키마로(ì—서) ê°ì²´ë¥¼ ì´ë™í•  수 없습니다" +msgstr "TOAST 스키마로(ì—서) 개체를 ì´ë™í•  수 없습니다" -#: catalog/namespace.c:2862 commands/schemacmds.c:238 -#: commands/schemacmds.c:317 commands/tablecmds.c:741 +#: catalog/namespace.c:3032 commands/schemacmds.c:256 commands/schemacmds.c:334 +#: commands/tablecmds.c:1014 #, c-format msgid "schema \"%s\" does not exist" msgstr "\"%s\" 스키마(schema) ì—†ìŒ" -#: catalog/namespace.c:2893 +#: catalog/namespace.c:3063 #, c-format msgid "improper relation name (too many dotted names): %s" -msgstr "" -"ì ë‹¹í•˜ì§€ ì•Šì€ ë¦´ë ˆì´ì…˜(relation) ì´ë¦„ 입니다 (너무 ë§Žì€ ì ì´ 있네요): %s" +msgstr "ì ë‹¹í•˜ì§€ ì•Šì€ ë¦´ë ˆì´ì…˜(relation) ì´ë¦„ 입니다 (너무 ë§Žì€ ì ì´ 있네요): %s" -#: catalog/namespace.c:3403 +#: catalog/namespace.c:3597 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "\"%s\" 정렬정ì˜(collation)ê°€ \"%s\" ì¸ì½”딩ì—서는 쓸 수 ì—†ìŒ" -#: catalog/namespace.c:3458 +#: catalog/namespace.c:3652 #, c-format msgid "conversion \"%s\" does not exist" msgstr "\"%s\" 문ìžì½”드변환규칙(conversion) ì—†ìŒ" -#: catalog/namespace.c:3666 +#: catalog/namespace.c:3860 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "\"%s\" ë°ì´í„°ë² ì´ìФì—서 임시 파ì¼ì„ 만들 ê¶Œí•œì´ ì—†ìŒ" -#: catalog/namespace.c:3682 +#: catalog/namespace.c:3876 #, c-format msgid "cannot create temporary tables during recovery" msgstr "복구 작업 중ì—는 임시 í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: catalog/namespace.c:3688 +#: catalog/namespace.c:3882 #, c-format -msgid "cannot create temporary tables in parallel mode" -msgstr "병렬 모드ì—서는 임시 í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" +msgid "cannot create temporary tables during a parallel operation" +msgstr "병렬 작업 ì¤‘ì— ìž„ì‹œ í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: catalog/namespace.c:3932 commands/tablespace.c:1173 commands/variable.c:63 -#: utils/misc/guc.c:9875 +#: catalog/namespace.c:4165 commands/tablespace.c:1171 commands/variable.c:64 +#: utils/misc/guc.c:10257 utils/misc/guc.c:10335 #, c-format msgid "List syntax is invalid." msgstr "ëª©ë¡ ë¬¸ë²•ì´ í‹€ë ¸ìŠµë‹ˆë‹¤." -#: catalog/objectaddress.c:1065 -msgid "access method name cannot be qualified" -msgstr "ì ‘ê·¼ 방법 ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1068 -msgid "database name cannot be qualified" -msgstr "ë°ì´í„°ë² ì´ìФ ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1071 commands/extension.c:2507 -#, c-format -msgid "extension name cannot be qualified" -msgstr "확장 모듈 ì´ë¦„으로 ì ë‹¹í•˜ì§€ 않습니다" - -#: catalog/objectaddress.c:1074 -msgid "tablespace name cannot be qualified" -msgstr "í…Œì´ë¸”스페ì´ìФ ì´ë¦„으로 ì ë‹¹í•˜ì§€ 않습니다" - -#: catalog/objectaddress.c:1077 -msgid "role name cannot be qualified" -msgstr "롤(role)ì´ë¦„으로 ì ë‹¹í•˜ì§€ 않습니다" - -#: catalog/objectaddress.c:1080 -msgid "schema name cannot be qualified" -msgstr "스키마 ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1083 -msgid "language name cannot be qualified" -msgstr "프로시주얼 언어 ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1086 -msgid "foreign-data wrapper name cannot be qualified" -msgstr "외부ìžë£Œ ëž©í¼ ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1089 -msgid "server name cannot be qualified" -msgstr "서버 ì´ë¦„으로 ì ë‹¹í•˜ì§€ 않습니다" - -#: catalog/objectaddress.c:1092 -msgid "event trigger name cannot be qualified" -msgstr "ì´ë²¤íЏ 트리거 ì´ë¦„ì´ ì ë‹¹ì¹˜ 않습니다" - -#: catalog/objectaddress.c:1210 commands/lockcmds.c:94 commands/policy.c:94 -#: commands/policy.c:382 commands/policy.c:471 commands/tablecmds.c:218 -#: commands/tablecmds.c:1300 commands/tablecmds.c:4347 -#: commands/tablecmds.c:8017 +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 +#: commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1719 +#: commands/tablecmds.c:4969 commands/tablecmds.c:9198 #, c-format msgid "\"%s\" is not a table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ì´ ì•„ë‹˜" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ì´ ì•„ë‹˜" -#: catalog/objectaddress.c:1217 commands/tablecmds.c:230 -#: commands/tablecmds.c:4377 commands/tablecmds.c:12159 commands/view.c:141 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 +#: commands/tablecmds.c:4999 commands/tablecmds.c:13512 commands/view.c:141 #, c-format msgid "\"%s\" is not a view" -msgstr "\"%s\" ê°ì²´ëŠ” ë·°ê°€ 아님" +msgstr "\"%s\" 개체는 ë·°ê°€ 아님" -#: catalog/objectaddress.c:1224 commands/matview.c:174 -#: commands/tablecmds.c:236 commands/tablecmds.c:12164 +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 +#: commands/tablecmds.c:13517 #, c-format msgid "\"%s\" is not a materialized view" -msgstr "\"%s\" ê°ì²´ëŠ” êµ¬ì²´í™”ëœ ë·°(materialized view)ê°€ 아닙니다" +msgstr "\"%s\" 개체는 êµ¬ì²´í™”ëœ ë·°(materialized view)ê°€ 아닙니다" -#: catalog/objectaddress.c:1231 commands/tablecmds.c:254 -#: commands/tablecmds.c:4380 commands/tablecmds.c:12169 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 +#: commands/tablecmds.c:5002 commands/tablecmds.c:13522 #, c-format msgid "\"%s\" is not a foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” 외부 í…Œì´ë¸”ì´ ì•„ë‹˜" +msgstr "\"%s\" 개체는 외부 í…Œì´ë¸”ì´ ì•„ë‹˜" + +#: catalog/objectaddress.c:1300 +#, c-format +msgid "must specify relation and object name" +msgstr "릴레ì´ì…˜ê³¼ 개체 ì´ë¦„ì„ ì§€ì •í•´ì•¼ 합니다" #: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 #, c-format @@ -4490,772 +4099,873 @@ msgstr "칼럼 ì´ë¦„으로 ì ë‹¹í•˜ì§€ 않습니다" msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "\"%s\" 칼럼(해당 릴레ì´ì…˜: \"%s\")ì˜ ê¸°ë³¸ê°’ì„ ì§€ì •í•˜ì§€ 않았ìŒ" -#: catalog/objectaddress.c:1512 commands/functioncmds.c:128 -#: commands/tablecmds.c:246 commands/typecmds.c:3214 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:795 utils/adt/acl.c:4374 -#: utils/adt/regproc.c:1225 +#: catalog/objectaddress.c:1509 commands/functioncmds.c:132 +#: commands/tablecmds.c:253 commands/typecmds.c:3323 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4377 #, c-format msgid "type \"%s\" does not exist" msgstr "\"%s\" ìžë£Œí˜• ì—†ìŒ" -#: catalog/objectaddress.c:1629 +#: catalog/objectaddress.c:1628 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "%d (%s, %s) ì—°ì‚°ìž(ëŒ€ìƒ %s) ì—†ìŒ" -#: catalog/objectaddress.c:1658 +#: catalog/objectaddress.c:1659 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "%d (%s, %s) 함수(ëŒ€ìƒ %s) ì—†ìŒ" -#: catalog/objectaddress.c:1707 catalog/objectaddress.c:1733 +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "\"%s\" 사용ìžì— 대한 ì‚¬ìš©ìž ë§µí•‘ ì •ë³´(ëŒ€ìƒ ì„œë²„: \"%s\")ê°€ ì—†ìŒ" -#: catalog/objectaddress.c:1722 commands/foreigncmds.c:430 -#: commands/foreigncmds.c:997 commands/foreigncmds.c:1359 -#: foreign/foreign.c:692 +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 +#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 +#: foreign/foreign.c:688 #, c-format msgid "server \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì„œë²„ê°€ ì—†ìŒ" -#: catalog/objectaddress.c:1794 +#: catalog/objectaddress.c:1792 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "\"%s\" 발행 릴레ì´ì…˜ì€ \"%s\" ë°œí–‰ì— ì—†ìŠµë‹ˆë‹¤." + +#: catalog/objectaddress.c:1854 #, c-format -msgid "unrecognized default ACL object type %c" -msgstr "알 수 없는 기본 ACL ê°ì²´ 타입 %c" +msgid "unrecognized default ACL object type \"%c\"" +msgstr "알 수 없는 기본 ACL 개체 타입 \"%c\"" -#: catalog/objectaddress.c:1795 +#: catalog/objectaddress.c:1855 #, c-format -msgid "Valid object types are \"r\", \"S\", \"f\", and \"T\"." -msgstr "유효한 ê°ì²´ 형태는 \"r\", \"S\", \"f\", \"T\"." +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "유효한 개체 형태는 \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." -#: catalog/objectaddress.c:1841 +#: catalog/objectaddress.c:1906 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" -msgstr "\"%s\" 사용ìžìš© 기본 ACL ì—†ìŒ. (해당 스키마: \"%s\", 해당 ê°ì²´: %s)" +msgstr "\"%s\" 사용ìžìš© 기본 ACL ì—†ìŒ. (해당 스키마: \"%s\", 해당 개체: %s)" -#: catalog/objectaddress.c:1846 +#: catalog/objectaddress.c:1911 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" -msgstr "\"%s\" 사용ìžìš© 기본 ACL ì—†ìŒ. (해당 ê°ì²´: %s)" +msgstr "\"%s\" 사용ìžìš© 기본 ACL ì—†ìŒ. (해당 개체: %s)" -#: catalog/objectaddress.c:1873 catalog/objectaddress.c:1929 -#: catalog/objectaddress.c:1984 +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 +#: catalog/objectaddress.c:2053 #, c-format msgid "name or argument lists may not contain nulls" msgstr "ì´ë¦„ì´ë‚˜ ì¸ìž 목ë¡ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: catalog/objectaddress.c:1905 +#: catalog/objectaddress.c:1972 #, c-format msgid "unsupported object type \"%s\"" msgstr "\"%s\" 형 ì§€ì›í•˜ì§€ 않ìŒ" -#: catalog/objectaddress.c:1925 catalog/objectaddress.c:1943 +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 +#: catalog/objectaddress.c:2151 #, c-format msgid "name list length must be exactly %d" msgstr "ì´ë¦„ ëª©ë¡ ê¸¸ì´ëŠ” %d ì´ì–´ì•¼ 합니다." -#: catalog/objectaddress.c:1947 +#: catalog/objectaddress.c:2014 #, c-format msgid "large object OID may not be null" -msgstr "대형 ê°ì²´ OID는 null ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgstr "대형 개체 OID는 null ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: catalog/objectaddress.c:1956 catalog/objectaddress.c:2016 -#: catalog/objectaddress.c:2023 +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:2093 #, c-format msgid "name list length must be at least %d" msgstr "ì´ë¦„ ëª©ë¡ ê¸¸ì´ëŠ” ì ì–´ë„ %d ê°œ ì´ìƒì´ì–´ì•¼ 함" -#: catalog/objectaddress.c:2009 catalog/objectaddress.c:2029 +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 #, c-format msgid "argument list length must be exactly %d" msgstr "ì¸ìž 목ë¡ì€ %d 개여야 함" -#: catalog/objectaddress.c:2165 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" -msgstr "%u 대경 ê°ì²´ì˜ 소유주여야만 합니다" +msgstr "%u 대경 ê°œì²´ì˜ ì†Œìœ ì£¼ì—¬ì•¼ë§Œ 합니다" -#: catalog/objectaddress.c:2180 commands/functioncmds.c:1426 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1453 #, c-format msgid "must be owner of type %s or type %s" msgstr "%s, %s ìžë£Œí˜•ì˜ ì†Œìœ ì£¼ì—¬ì•¼í•©ë‹ˆë‹¤" -#: catalog/objectaddress.c:2220 catalog/objectaddress.c:2237 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" msgstr "슈í¼ìœ ì ¸ì—¬ì•¼í•¨" -#: catalog/objectaddress.c:2227 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "CREATEROLE ê¶Œí•œì´ ìžˆì–´ì•¼ 함" -#: catalog/objectaddress.c:2302 +#: catalog/objectaddress.c:2481 #, c-format msgid "unrecognized object type \"%s\"" -msgstr "알 수 없는 ê°ì²´ 형태 \"%s\"" +msgstr "알 수 없는 개체 형태 \"%s\"" -#: catalog/objectaddress.c:2497 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " %s ì—´" +msgid "column %s of %s" +msgstr " %s 칼럼(%s ì˜)" -#: catalog/objectaddress.c:2503 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" msgstr "%s 함수" -#: catalog/objectaddress.c:2508 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" msgstr "%s ìžë£Œí˜•" -#: catalog/objectaddress.c:2538 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" msgstr "%s ìžë£Œí˜•ì„ %s ìžë£Œí˜•으로 바꾸는 작업" -#: catalog/objectaddress.c:2558 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" msgstr "collation %s" -#: catalog/objectaddress.c:2582 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" -msgstr "%s 제약 ì¡°ê±´(해당 ê°ì²´: %s)" +msgstr "%s 제약 ì¡°ê±´(해당 개체: %s)" -#: catalog/objectaddress.c:2588 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" msgstr "%s 제약 ì¡°ê±´" -#: catalog/objectaddress.c:2605 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" msgstr "%s 문ìžì½”드변환규칙" -#: catalog/objectaddress.c:2642 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" -msgstr "default for %s" +msgid "default value for %s" +msgstr "%s ìš© 기본값" -#: catalog/objectaddress.c:2651 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "프로시주얼 언어 %s" -#: catalog/objectaddress.c:2656 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" -msgstr "%u 대형 ê°ì²´" +msgstr "%u 대형 개체" -#: catalog/objectaddress.c:2661 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "%s ì—°ì‚°ìž" -#: catalog/objectaddress.c:2693 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "%s ì—°ì‚°ìž í´ëž˜ìФ, %s ì¸ë±ìФ 액세스 방법" +#: catalog/objectaddress.c:2939 +#, c-format +msgid "access method %s" +msgstr "%s ì ‘ê·¼ 방법" + #. translator: %d is the operator strategy (a number), the #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2743 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" -msgstr "%d (%s, %s) ì—°ì‚°ìž (ì—°ì‚°ìž ê°€ì¡±: %s): %s" +msgstr "%d (%s, %s) ì—°ì‚°ìž (ì—°ì‚°ìž íŒ¨ë°€ë¦¬: %s): %s" #. translator: %d is the function number, the first two %s's #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2793 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" -msgstr "%d (%s, %s) 함수 (ì—°ì‚°ìž ê°€ì¡±: %s): %s" - -#: catalog/objectaddress.c:2833 -#, c-format -msgid "rule %s on " -msgstr "%s 룰(rule), 해당 í…Œì´ë¸”: " +msgstr "%d (%s, %s) 함수 (ì—°ì‚°ìž íŒ¨ë°€ë¦¬: %s): %s" -#: catalog/objectaddress.c:2855 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "transform for %s language %s" -msgstr "%s 형 변환ìž, 대ìƒì–¸ì–´: %s" +msgid "rule %s on %s" +msgstr "%s 룰(rule), 해당 í…Œì´ë¸”: %s" -#: catalog/objectaddress.c:2889 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "%s 트리거, 해당 í…Œì´ë¸”: " +msgid "trigger %s on %s" +msgstr "%s 트리거, 해당 í…Œì´ë¸”: %s" -#: catalog/objectaddress.c:2906 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" msgstr "%s 스키마" -#: catalog/objectaddress.c:2919 +#: catalog/objectaddress.c:3152 +#, c-format +msgid "statistics object %s" +msgstr "%s 통계정보 개체" + +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" msgstr "%s 전문 검색 파서" -#: catalog/objectaddress.c:2934 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" msgstr "%s 전문 검색 사전" -#: catalog/objectaddress.c:2949 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" msgstr "%s 전문 검색 템플릿" -#: catalog/objectaddress.c:2964 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" msgstr "%s 전문 검색 구성" -#: catalog/objectaddress.c:2972 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" msgstr "%s 롤" -#: catalog/objectaddress.c:2985 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" msgstr "%s ë°ì´í„°ë² ì´ìФ" -#: catalog/objectaddress.c:2997 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" msgstr "%s í…Œì´ë¸”스페ì´ìФ" -#: catalog/objectaddress.c:3006 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" msgstr "%s 외부 ë°ì´í„° 래í¼" -#: catalog/objectaddress.c:3015 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" msgstr "%s 서버" -#: catalog/objectaddress.c:3043 +#: catalog/objectaddress.c:3337 #, c-format msgid "user mapping for %s on server %s" msgstr "%sì— ëŒ€í•œ ì‚¬ìš©ìž ë§¤í•‘, 해당 서버: %s" -#: catalog/objectaddress.c:3078 +#: catalog/objectaddress.c:3382 +#, c-format +#| msgid "default privileges on new relations belonging to role %s" +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)ì´ ìƒˆ í…Œì´ë¸”ì„ ë§Œë“¤ 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "%s ë¡¤ì´ ìƒˆ í…Œì´ë¸”ì„ ë§Œë“¤ 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3083 +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)ì´ ìƒˆ 시퀀스를 만들 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" + +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "%s ë¡¤ì´ ìƒˆ 시퀀스를 만들 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3088 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)ì´ ìƒˆ 함수를 만들 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "%s ë¡¤ì´ ìƒˆ 함수를 만들 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3093 +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)ì´ ìƒˆ ìžë£Œí˜•ì„ ë§Œë“¤ 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" + +#: catalog/objectaddress.c:3416 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "%s ë¡¤ì´ ìƒˆ ìžë£Œí˜•ì„ ë§Œë“¤ 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3099 +#: catalog/objectaddress.c:3422 #, c-format -msgid "default privileges belonging to role %s" -msgstr "%s ë¡¤ì˜ ê¸°ë³¸ ì ‘ê·¼ 권한" +msgid "default privileges on new schemas belonging to role %s" +msgstr "%s ë¡¤ì´ ìƒˆ 시퀀스를 만들 때 기본ì ìœ¼ë¡œ 지정할 ì ‘ê·¼ 권한" + +#: catalog/objectaddress.c:3429 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "%s 롤(해당 스키마: %s)ì˜ ê¸°ë³¸ ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3107 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr ", ëŒ€ìƒ ìŠ¤í‚¤ë§ˆ: %s" +msgid "default privileges belonging to role %s" +msgstr "%s ë¡¤ì˜ ê¸°ë³¸ ì ‘ê·¼ 권한" -#: catalog/objectaddress.c:3124 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" msgstr "%s 확장 모듈" -#: catalog/objectaddress.c:3137 +#: catalog/objectaddress.c:3464 #, c-format msgid "event trigger %s" msgstr "%s ì´ë²¤íЏ 트리거" -#: catalog/objectaddress.c:3169 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 #, c-format -msgid "policy %s on " -msgstr "%s ì •ì±… " +msgid "policy %s on %s" +msgstr "%s ì •ì±…(%s ì˜)" -#: catalog/objectaddress.c:3187 +#: catalog/objectaddress.c:3510 #, c-format -msgid "access method %s" -msgstr "%s ì ‘ê·¼ 방법" +msgid "publication %s" +msgstr "%s 발행" -#: catalog/objectaddress.c:3247 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 +#, c-format +#| msgid "%s in publication %s" +msgid "publication of %s in publication %s" +msgstr "%s 발행 (해당 발행ì´ë¦„: %s)" + +#: catalog/objectaddress.c:3544 +#, c-format +msgid "subscription %s" +msgstr "%s 구ë…" + +#: catalog/objectaddress.c:3562 +#, c-format +msgid "transform for %s language %s" +msgstr "%s 형 변환ìž, 대ìƒì–¸ì–´: %s" + +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" msgstr "%s í…Œì´ë¸”" -#: catalog/objectaddress.c:3251 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" msgstr "%s ì¸ë±ìФ" -#: catalog/objectaddress.c:3255 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "%s 시퀀스" -#: catalog/objectaddress.c:3259 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "%s 토스트 í…Œì´ë¸”" -#: catalog/objectaddress.c:3263 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "%s ë·°" -#: catalog/objectaddress.c:3267 +#: catalog/objectaddress.c:3646 #, c-format msgid "materialized view %s" msgstr "%s êµ¬ì²´í™”ëœ ë·°" -#: catalog/objectaddress.c:3271 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "%s 복합 ìžë£Œí˜•" -#: catalog/objectaddress.c:3275 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" msgstr "%s 외부 í…Œì´ë¸”" -#: catalog/objectaddress.c:3280 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "%s 릴레ì´ì…˜" -#: catalog/objectaddress.c:3317 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" msgstr "%s ì—°ì‚°ìž íŽ˜ë°€ë¦¬, ì ‘ê·¼ 방법: %s" -#: catalog/pg_aggregate.c:125 +#: catalog/partition.c:180 catalog/pg_constraint.c:420 commands/analyze.c:1499 +#: commands/indexcmds.c:917 commands/tablecmds.c:941 commands/tablecmds.c:9260 +#: commands/tablecmds.c:14401 commands/tablecmds.c:14873 +#: executor/execExprInterp.c:3302 executor/execMain.c:1938 +#: executor/execMain.c:2017 executor/execMain.c:2065 executor/execMain.c:2171 +#: executor/execPartition.c:432 executor/execPartition.c:492 +#: executor/execPartition.c:608 executor/execPartition.c:711 +#: executor/execPartition.c:782 executor/execPartition.c:980 +#: executor/nodeModifyTable.c:1859 +msgid "could not convert row type" +msgstr "로우 ìžë£Œí˜•ì„ ë³€í™˜ í•  수 ì—†ìŒ" + +#: catalog/pg_aggregate.c:126 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "집계 함수ì—는 %dê°œ ì´ìƒì˜ ì¸ìžë¥¼ 사용할 수 ì—†ìŒ" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" msgstr "처리할(변환할) ìžë£Œí˜•ì„ ê²°ì •í•  수 ì—†ìŒ" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format -msgid "" -"An aggregate using a polymorphic transition type must have at least one " -"polymorphic argument." -msgstr "" -"다형 변환 형ì‹ì„ 사용하는 집계ì—는 다형 ì¸ìžê°€ 하나 ì´ìƒ 있어야 합니다." +msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." +msgstr "다형 변환 형ì‹ì„ 사용하는 집계ì—는 다형 ì¸ìžê°€ 하나 ì´ìƒ 있어야 합니다." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:173 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "variadic 순서있는 세트 집계함수는 VARIADIC ANY í˜•ì„ ì‚¬ìš©í•´ì•¼ 합니다" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:199 #, c-format -msgid "" -"a hypothetical-set aggregate must have direct arguments matching its " -"aggregated arguments" +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "%s ì´ë¦„ì˜ transition í•¨ìˆ˜ì˜ ë¦¬í„´ ìžë£Œí˜•ì´ %s í˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format -msgid "" -"must not omit initial value when transition function is strict and " -"transition type is not compatible with input type" -msgstr "" -"변환 함수가 엄격하고 변환 형ì‹ì´ ìž…ë ¥ 형ì‹ê³¼ 호환ë˜ì§€ 않는 경우 ì´ˆê¸°ê°’ì„ ìƒëžµ" -"하면 안ë¨" +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "변환 함수가 엄격하고 변환 형ì‹ì´ ìž…ë ¥ 형ì‹ê³¼ 호환ë˜ì§€ 않는 경우 ì´ˆê¸°ê°’ì„ ìƒëžµí•˜ë©´ 안ë¨" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:335 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "%s inverse transition í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì´ %s í˜•ì´ ì•„ë‹™ë‹ˆë‹¤." -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2334 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 #, c-format -msgid "" -"strictness of aggregate's forward and inverse transition functions must match" +msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 #, c-format msgid "final function with extra arguments must not be declared STRICT" -msgstr "" +msgstr "부가 ì¸ìžë¥¼ 쓰는 마침 함수는 STRICT ì˜µì…˜ì´ ì—†ì–´ì•¼ 함" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:427 #, c-format msgid "return type of combine function %s is not %s" msgstr "%s combine í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì´ %s í˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: catalog/pg_aggregate.c:436 +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2943 #, c-format -msgid "" -"combine function with \"%s\" transition type must not be declared STRICT" -msgstr "" +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "%s ìžë£Œí˜•ì„ ì „ë‹¬ 값으로 사용하는 ì¡°í•© 함수는 STRICT ì†ì„±ì„ 가져야 합니다" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:458 #, c-format msgid "return type of serialization function %s is not %s" msgstr "%s serialization í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì´ %s í˜•ì´ ì•„ë‹™ë‹ˆë‹¤." -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:479 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "%s deserialization í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì´ %s í˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:246 catalog/pg_proc.c:253 +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "ê²°ê³¼ ìžë£Œí˜•ì„ ê²°ì •í•  수 ì—†ìŒ" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:496 #, c-format -msgid "" -"An aggregate returning a polymorphic type must have at least one polymorphic " -"argument." -msgstr "" -"다형 ìžë£Œí˜•ì„ ë°˜í™˜í•˜ëŠ” 집계ì—는 다형 ìžë£Œí˜• ì¸ìžê°€ 하나 ì´ìƒ 있어야 합니다." +msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." +msgstr "다형 ìžë£Œí˜•ì„ ë°˜í™˜í•˜ëŠ” 집계ì—는 다형 ìžë£Œí˜• ì¸ìžê°€ 하나 ì´ìƒ 있어야 합니다." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:259 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "\"internal\" ì˜ì‚¬-ìžë£Œí˜•ì˜ ì‚¬ìš©ì´ ì•ˆì „í•˜ì§€ 않습니다" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:260 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format -msgid "" -"A function returning \"internal\" must have at least one \"internal\" " -"argument." -msgstr "" -"\"internal\" ìžë£Œí˜•ì„ ë¦¬í„´í•˜ëŠ” 함수는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¸ìžê°€ \"internal\" " -"ìžë£Œí˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." +msgid "A function returning \"internal\" must have at least one \"internal\" argument." +msgstr "\"internal\" ìžë£Œí˜•ì„ ë¦¬í„´í•˜ëŠ” 함수는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¸ìžê°€ \"internal\" ìžë£Œí˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:562 #, c-format -msgid "" -"moving-aggregate implementation returns type %s, but plain implementation " -"returns type %s" +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "ì •ë ¬ ì—°ì‚°ìžëŠ” ë‹¨ì¼ ì¸ìž 집계ì—ë§Œ 지정할 수 있ìŒ" -#: catalog/pg_aggregate.c:812 commands/typecmds.c:1705 -#: commands/typecmds.c:1756 commands/typecmds.c:1787 commands/typecmds.c:1810 -#: commands/typecmds.c:1831 commands/typecmds.c:1858 commands/typecmds.c:1885 -#: commands/typecmds.c:1962 commands/typecmds.c:2004 parser/parse_func.c:364 -#: parser/parse_func.c:393 parser/parse_func.c:418 parser/parse_func.c:432 -#: parser/parse_func.c:507 parser/parse_func.c:518 parser/parse_func.c:1923 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 +#: commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 +#: commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 +#: commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 +#: parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 +#: parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "%s ì´ë¦„ì˜ í•¨ìˆ˜ê°€ ì—†ìŒ" -#: catalog/pg_aggregate.c:818 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "%s 함수는 한 setì„ ë¦¬í„´í•¨" -#: catalog/pg_aggregate.c:833 +#: catalog/pg_aggregate.c:840 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "%s 함수가 ì´ ì§‘ê³„ìž‘ì—…ì— ì‚¬ìš©ë˜ë ¤ë©´ VARIADIC ANY í˜•ì„ ìˆ˜ìš©í•´ì•¼ 합니다." -#: catalog/pg_aggregate.c:857 +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "%s 함수는 run-time type coercionì„ í•„ìš”ë¡œ 함" -#: catalog/pg_collation.c:77 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format -msgid "collation \"%s\" for encoding \"%s\" already exists" -msgstr "\"%s\" ì •ë ¬ê·œì¹™ì´ \"%s\" ì¸ì½”ë”©ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다" +msgid "collation \"%s\" already exists, skipping" +msgstr "\"%s\" ì´ë¦„ì˜ ì •ë ¬ê·œì¹™ì´ ì´ë¯¸ 있습니다, 건너뜀" + +#: catalog/pg_collation.c:94 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "\"%s\" ì •ë ¬ê·œì¹™ì´ \"%s\" ì¸ì½”ë”©ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다, 건너뜀" -#: catalog/pg_collation.c:91 +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "\"%s\" ì •ë ¬ê·œì¹™ì´ ì´ë¯¸ 있습니다" -#: catalog/pg_constraint.c:663 +#: catalog/pg_collation.c:104 #, c-format -msgid "constraint \"%s\" for domain %s already exists" -msgstr "\"%s\" 제약 ì¡°ê±´ì´ %s ë„ë©”ì¸ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다" +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "\"%s\" ì •ë ¬ê·œì¹™ì´ \"%s\" ì¸ì½”ë”©ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다" -#: catalog/pg_constraint.c:797 +#: catalog/pg_constraint.c:924 #, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "\"%s\" í…Œì´ë¸”ì—는 \"%s\" ì´ë¦„ì˜ ì œì•½ ì¡°ê±´ì´ ì—¬ëŸ¬ê°œ 있습니다" +msgid "constraint \"%s\" for domain %s already exists" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ %s ë„ë©”ì¸ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다" -#: catalog/pg_constraint.c:809 +#: catalog/pg_constraint.c:1087 catalog/pg_constraint.c:1180 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "\"%s\" 제약 ì¡°ê±´ì€ \"%s\" í…Œì´ë¸”ì— ì—†ìŒ" -#: catalog/pg_constraint.c:855 -#, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "\"%s\" ë„ë©”ì¸ì—는 \"%s\" ì´ë¦„ì˜ ì œì•½ ì¡°ê±´ì´ ì—¬ëŸ¬ê°œ 있습니다" - -#: catalog/pg_constraint.c:867 +#: catalog/pg_constraint.c:1269 #, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" -msgstr "\"%s\" 제약 ì¡°ê±´ì€ \"%s\" ë„ë©”ì¸ì— ì—†ìŒ" +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "\"%s\" 제약 ì¡°ê±´ì€ %s ë„ë©”ì¸ì— ì—†ìŒ" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ë³€í™˜ê·œì¹™(conversion)ì´ ì´ë¯¸ 있ìŒ" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "%s 코드ì—서 %s 코드로 변환하는 기본 변환규칙(conversion)ì€ ì´ë¯¸ 있ìŒ" -#: catalog/pg_depend.c:165 commands/extension.c:3029 +#: catalog/pg_depend.c:163 commands/extension.c:3218 #, c-format msgid "%s is already a member of extension \"%s\"" -msgstr "%s ê°ì²´ëŠ” \"%s\" í™•ìž¥ëª¨ë“ˆì— ì´ë¯¸ 구성ì›ìž…니다" +msgstr "%s 개체는 \"%s\" í™•ìž¥ëª¨ë“ˆì— ì´ë¯¸ 구성ì›ìž…니다" -#: catalog/pg_depend.c:324 +#: catalog/pg_depend.c:322 #, c-format msgid "cannot remove dependency on %s because it is a system object" -msgstr "%s ì˜ì¡´ê°ì²´ë“¤ì€ 시스템 ê°ì²´ì´ê¸° ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ 없습니다" +msgstr "%s ì˜ì¡´ê°œì²´ë“¤ì€ 시스템 개체ì´ê¸° ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ 없습니다" -#: catalog/pg_enum.c:115 catalog/pg_enum.c:202 +#: catalog/pg_enum.c:115 catalog/pg_enum.c:201 catalog/pg_enum.c:488 #, c-format msgid "invalid enum label \"%s\"" msgstr "\"%s\" 열거형 ë¼ë²¨ì´ 잘못ë¨" -#: catalog/pg_enum.c:116 catalog/pg_enum.c:203 +#: catalog/pg_enum.c:116 catalog/pg_enum.c:202 catalog/pg_enum.c:489 #, c-format msgid "Labels must be %d characters or less." msgstr "ë¼ë²¨ì€ %dìž ì´í•˜ì—¬ì•¼ 합니다." -#: catalog/pg_enum.c:231 +#: catalog/pg_enum.c:230 #, c-format msgid "enum label \"%s\" already exists, skipping" msgstr "\"%s\" ì´ë¦„ì˜ ì—´ê±°í˜• ë¼ë²¨ì´ ì´ë¯¸ 있ìŒ, 건너뜀" -#: catalog/pg_enum.c:238 +#: catalog/pg_enum.c:237 catalog/pg_enum.c:532 #, c-format msgid "enum label \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì—´ê±°í˜• ë¼ë²¨ì´ ì´ë¯¸ 있ìŒ" -#: catalog/pg_enum.c:293 +#: catalog/pg_enum.c:292 catalog/pg_enum.c:527 #, c-format msgid "\"%s\" is not an existing enum label" msgstr "\"%s\" 열거형 ë¼ë²¨ì´ ì—†ìŒ" -#: catalog/pg_enum.c:349 +#: catalog/pg_enum.c:350 #, c-format msgid "pg_enum OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때 pg_enum OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: catalog/pg_enum.c:359 +#: catalog/pg_enum.c:360 #, c-format msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" -msgstr "" -"ALTER TYPE ADD BEFORE/AFTER êµ¬ë¬¸ì€ ì´ì§„ 업그레ì´ë“œ 작업ì—서 호환하지 않습니다" +msgstr "ALTER TYPE ADD BEFORE/AFTER êµ¬ë¬¸ì€ ì´ì§„ 업그레ì´ë“œ 작업ì—서 호환하지 않습니다" -#: catalog/pg_namespace.c:61 commands/schemacmds.c:246 +#: catalog/pg_namespace.c:63 commands/schemacmds.c:264 #, c-format msgid "schema \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ìŠ¤í‚¤ë§ˆ(schema)ê°€ ì´ë¯¸ 있ìŒ" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:360 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "\"%s\" 타당한 ì—°ì‚°ìž ì´ë¦„ì´ ì•„ë‹˜" -#: catalog/pg_operator.c:369 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" msgstr "_^_ ë°”ì´ë„ˆë¦¬ ì—°ì‚°ìžë§Œì´ commutator를 가질 수 있ìŒ" -#: catalog/pg_operator.c:373 commands/operatorcmds.c:485 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "_^_ ë°”ì´ë„ˆë¦¬ ì—°ì‚°ìžë§Œì´ join selectivity를 가질 수 있ìŒ" -#: catalog/pg_operator.c:377 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "_^_ ë°”ì´ë„ˆë¦¬ ì—°ì‚°ìžë§Œì´ merge joiní•  수 있ìŒ" -#: catalog/pg_operator.c:381 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "_^_ ë°”ì´ë„ˆë¦¬ ì—°ì‚°ìžë§Œì´ 해시할 수 있ìŒ" -#: catalog/pg_operator.c:392 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "부울 ì—°ì‚°ìžë§Œ 부정어를 í¬í•¨í•  수 있ìŒ" -#: catalog/pg_operator.c:396 commands/operatorcmds.c:493 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "부울 ì—°ì‚°ìžë§Œ 제한 ì„ íƒì„ í¬í•¨í•  수 있ìŒ" -#: catalog/pg_operator.c:400 commands/operatorcmds.c:497 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "부울 ì—°ì‚°ìžë§Œ ì¡°ì¸ ì„ íƒì„ í¬í•¨í•  수 있ìŒ" -#: catalog/pg_operator.c:404 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "부울 ì—°ì‚°ìžë§Œ 머지 ì¡°ì¸ì„ 지정할 수 있ìŒ" -#: catalog/pg_operator.c:408 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "부울 ì—°ì‚°ìžë§Œ 해시를 지정할 수 있ìŒ" -#: catalog/pg_operator.c:420 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "%s ì—°ì‚°ìžê°€ ì´ë¯¸ 있ìŒ" -#: catalog/pg_operator.c:617 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "ì—°ì‚°ìžëŠ” ìžì‹ ì˜ negator나 sort ì—°ì‚°ìžê°€ ë  ìˆ˜ 없습니다" -#: catalog/pg_proc.c:134 parser/parse_func.c:1947 parser/parse_func.c:1987 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "함수는 %dê°œ ì´ìƒì˜ ì¸ìžë¥¼ 사용할 수 ì—†ìŒ" -#: catalog/pg_proc.c:247 +#: catalog/pg_proc.c:241 #, c-format -msgid "" -"A function returning a polymorphic type must have at least one polymorphic " -"argument." +msgid "A function returning a polymorphic type must have at least one polymorphic argument." msgstr "다형 형ì‹ì„ 반환하는 함수ì—는 다형 ì¸ìžê°€ 하나 ì´ìƒ 있어야 합니다." -#: catalog/pg_proc.c:254 -#, c-format -msgid "" -"A function returning \"anyrange\" must have at least one \"anyrange\" " -"argument." -msgstr "" -"\"anyrange\" ìžë£Œí˜•ì„ ë°˜í™˜í•˜ëŠ” 함수는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¸ìžê°€ \"anyrange\" " -"ìžë£Œí˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." - -#: catalog/pg_proc.c:272 +#: catalog/pg_proc.c:248 #, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "\"%s\"ì€(는) ì´ë¯¸ %s 형ì‹ì˜ ì†ì„±ìž„" +msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." +msgstr "\"anyrange\" ìžë£Œí˜•ì„ ë°˜í™˜í•˜ëŠ” 함수는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¸ìžê°€ \"anyrange\" ìžë£Œí˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." -#: catalog/pg_proc.c:403 +#: catalog/pg_proc.c:383 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "ì´ë¯¸ ê°™ì€ ì¸ìž ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ëŠ” \"%s\" 함수가 있습니다" -#: catalog/pg_proc.c:417 catalog/pg_proc.c:440 +#: catalog/pg_proc.c:393 #, c-format -msgid "cannot change return type of existing function" -msgstr "ì´ë¯¸ 있는 í•¨ìˆ˜ì˜ ë¦¬í„´ ìžë£Œí˜•ì€ ë°”ê¿€ 수 없습니다" +msgid "cannot change routine kind" +msgstr "루틴 종류를 바꿀 수 ì—†ìŒ" -#: catalog/pg_proc.c:418 catalog/pg_proc.c:442 catalog/pg_proc.c:485 -#: catalog/pg_proc.c:509 catalog/pg_proc.c:536 +#: catalog/pg_proc.c:395 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "먼저 DROP FUNCTION %s 명령으로 함수를 ì‚­ì œ 하세요" +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" 개체는 집계 함수입니다" -#: catalog/pg_proc.c:441 +#: catalog/pg_proc.c:397 #, c-format -msgid "Row type defined by OUT parameters is different." -msgstr "OUT 매개 ë³€ìˆ˜ì— ì •ì˜ëœ í–‰ 형ì‹ì´ 다릅니다." +msgid "\"%s\" is a function." +msgstr "\"%s\" 개체는 함수입니다." -#: catalog/pg_proc.c:483 +#: catalog/pg_proc.c:399 #, c-format -msgid "cannot change name of input parameter \"%s\"" -msgstr "\"%s\" ìž…ë ¥ 매개 변수 ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ" +msgid "\"%s\" is a procedure." +msgstr "\"%s\" 개체는 프로시져입니다." -#: catalog/pg_proc.c:508 +#: catalog/pg_proc.c:401 #, c-format -msgid "cannot remove parameter defaults from existing function" -msgstr "기존 함수ì—서 매개 변수 기본 ê°’ì„ ì œê±°í•  수 ì—†ìŒ" +msgid "\"%s\" is a window function." +msgstr "\"%s\" 개체는 윈ë„ìš° 함수입니다." -#: catalog/pg_proc.c:535 +#: catalog/pg_proc.c:419 #, c-format -msgid "cannot change data type of existing parameter default value" -msgstr "기존 매개 변수 기본 ê°’ì˜ ë°ì´í„° 형ì‹ì„ 바꿀 수 ì—†ìŒ" +msgid "cannot change whether a procedure has output parameters" +msgstr "프로시져는 출력 매개 변수를 사용하ë„ë¡ ë³€ê²½ í•  수 ì—†ìŒ" + +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 +#, c-format +msgid "cannot change return type of existing function" +msgstr "ì´ë¯¸ 있는 í•¨ìˆ˜ì˜ ë¦¬í„´ ìžë£Œí˜•ì€ ë°”ê¿€ 수 없습니다" + +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 +#: catalog/pg_proc.c:520 catalog/pg_proc.c:548 +#, c-format +msgid "Use %s %s first." +msgstr "먼저 %s %s ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: catalog/pg_proc.c:548 +#: catalog/pg_proc.c:447 #, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "\"%s\" 함수는 집계 함수임" +msgid "Row type defined by OUT parameters is different." +msgstr "OUT 매개 ë³€ìˆ˜ì— ì •ì˜ëœ í–‰ 형ì‹ì´ 다릅니다." -#: catalog/pg_proc.c:553 +#: catalog/pg_proc.c:491 #, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "\"%s\" 함수는 집계 함수가 아님" +msgid "cannot change name of input parameter \"%s\"" +msgstr "\"%s\" ìž…ë ¥ 매개 변수 ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ" -#: catalog/pg_proc.c:561 +#: catalog/pg_proc.c:518 #, c-format -msgid "function \"%s\" is a window function" -msgstr "\"%s\" 함수는 윈ë„ìš° 함수임" +msgid "cannot remove parameter defaults from existing function" +msgstr "기존 함수ì—서 매개 변수 기본 ê°’ì„ ì œê±°í•  수 ì—†ìŒ" -#: catalog/pg_proc.c:566 +#: catalog/pg_proc.c:546 #, c-format -msgid "function \"%s\" is not a window function" -msgstr "\"%s\" 함수는 윈ë„ìš° 함수가 아님" +msgid "cannot change data type of existing parameter default value" +msgstr "기존 매개 변수 기본 ê°’ì˜ ë°ì´í„° 형ì‹ì„ 바꿀 수 ì—†ìŒ" -#: catalog/pg_proc.c:774 +#: catalog/pg_proc.c:757 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "\"%s\" ì´ë¦„ì˜ ë‚´ìž¥ 함수가 ì—†ìŒ" -#: catalog/pg_proc.c:872 +#: catalog/pg_proc.c:855 #, c-format msgid "SQL functions cannot return type %s" msgstr "SQL 함수는 %s ìžë£Œí˜•ì„ ë¦¬í„´í•  수 ì—†ìŒ" -#: catalog/pg_proc.c:887 +#: catalog/pg_proc.c:870 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "SQL í•¨ìˆ˜ì˜ ì¸ìžë¡œ %s ìžë£Œí˜•ì€ ì‚¬ìš©ë  ìˆ˜ 없습니다" -#: catalog/pg_proc.c:973 executor/functions.c:1431 +#: catalog/pg_proc.c:958 executor/functions.c:1434 #, c-format msgid "SQL function \"%s\"" msgstr "\"%s\" SQL 함수" -#: catalog/pg_shdepend.c:694 +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" 개체는 íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ìž„" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Adding partitioned tables to publications is not supported." +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì„ ë°œí–‰í•˜ëŠ” ê²ƒì€ ì§€ì›í•˜ì§€ 않습니다" + +#: catalog/pg_publication.c:60 +#, c-format +msgid "You can add the table partitions individually." +msgstr "파티션 í…Œì´ë¸”ì„ ê°ê° ë°œí–‰ì— ì¶”ê°€í•  수는 있습니다." + +#: catalog/pg_publication.c:68 +#, c-format +msgid "Only tables can be added to publications." +msgstr "í…Œì´ë¸” 개체만 ë°œí–‰ì— ì¶”ê°€í•  수 있습니다." + +#: catalog/pg_publication.c:74 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" 개체는 시스템 í…Œì´ë¸”입니다." + +#: catalog/pg_publication.c:76 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "시스템 í…Œì´ë¸”ì€ ë°œí–‰ì— ì¶”ê°€í•  수 없습니다." + +#: catalog/pg_publication.c:82 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "\"%s\" í…Œì´ë¸”ì€ ë³µì œë  ìˆ˜ ì—†ìŒ" + +#: catalog/pg_publication.c:84 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "임시 í…Œì´ë¸”, unlogged í…Œì´ë¸”ì€ ë³µì œë  ìˆ˜ ì—†ìŒ" + +#: catalog/pg_publication.c:175 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì€ ì´ë¯¸ \"%s\" ë°œí–‰ì— í¬í•¨ë˜ì–´ 있습니다" + +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 +#: commands/publicationcmds.c:415 commands/publicationcmds.c:716 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "\"%s\" ì´ë¦„ì˜ ë°œí–‰ì€ ì—†ìŠµë‹ˆë‹¤" + +#: catalog/pg_shdepend.c:692 #, c-format msgid "" "\n" @@ -5265,247 +4975,262 @@ msgid_plural "" "and objects in %d other databases (see server log for list)" msgstr[0] "" -#: catalog/pg_shdepend.c:1006 +#: catalog/pg_shdepend.c:998 #, c-format msgid "role %u was concurrently dropped" msgstr "%u ë¡¤ì´ ë™ì‹œì— ì‚­ì œë˜ì—ˆìŒ" -#: catalog/pg_shdepend.c:1025 +#: catalog/pg_shdepend.c:1017 #, c-format msgid "tablespace %u was concurrently dropped" msgstr "%u í…Œì´ë¸”스페ì´ìŠ¤ëŠ” 현재 ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤" -#: catalog/pg_shdepend.c:1040 +#: catalog/pg_shdepend.c:1032 #, c-format msgid "database %u was concurrently dropped" msgstr "%u ë°ì´í„°ë² ì´ìŠ¤ëŠ” 현재 ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤" -#: catalog/pg_shdepend.c:1085 +#: catalog/pg_shdepend.c:1077 #, c-format msgid "owner of %s" -msgstr "%s ê°ì²´ì˜ 소유주" +msgstr "%s ê°œì²´ì˜ ì†Œìœ ì£¼" -#: catalog/pg_shdepend.c:1087 +#: catalog/pg_shdepend.c:1079 #, c-format msgid "privileges for %s" msgstr "\"%s\"ì— ëŒ€í•œ 권한" -#: catalog/pg_shdepend.c:1089 +#: catalog/pg_shdepend.c:1081 #, c-format msgid "target of %s" -msgstr "%s ê°ì²´ 대ìƒ" +msgstr "%s 개체 대ìƒ" #. translator: %s will always be "database %s" -#: catalog/pg_shdepend.c:1097 +#: catalog/pg_shdepend.c:1089 #, c-format msgid "%d object in %s" msgid_plural "%d objects in %s" -msgstr[0] "%d ê°ì²´(ë°ì´í„°ë² ì´ìФ: %s)" +msgstr[0] "%d 개체(ë°ì´í„°ë² ì´ìФ: %s)" -#: catalog/pg_shdepend.c:1208 +#: catalog/pg_shdepend.c:1200 #, c-format -msgid "" -"cannot drop objects owned by %s because they are required by the database " -"system" -msgstr "" -"%s ì†Œìœ ì£¼ì˜ ê°ì²´ 삭제는 ê·¸ ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  " -"수 ì—†ìŒ" +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "%s ì†Œìœ ì£¼ì˜ ê°œì²´ 삭제는 ê·¸ ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ ì—†ìŒ" -#: catalog/pg_shdepend.c:1323 +#: catalog/pg_shdepend.c:1315 #, c-format -msgid "" -"cannot reassign ownership of objects owned by %s because they are required " -"by the database system" -msgstr "" -"%s ì†Œìœ ì£¼ì˜ ê°ì²´ 삭제는 ê·¸ ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  " -"수 ì—†ìŒ" +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "%s ì†Œìœ ì£¼ì˜ ê°œì²´ 삭제는 ê·¸ ë°ì´í„°ë² ì´ìФ 시스템ì—서 필요하기 ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ ì—†ìŒ" + +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 +#: commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "\"%s\" ì´ë¦„ì˜ êµ¬ë…ì€ ì—†ìŠµë‹ˆë‹¤." -#: catalog/pg_type.c:136 catalog/pg_type.c:454 +#: catalog/pg_type.c:135 catalog/pg_type.c:451 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때 pg_type OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: catalog/pg_type.c:253 +#: catalog/pg_type.c:250 #, c-format msgid "invalid type internal size %d" msgstr "ìž˜ëª»ëœ ìžë£Œí˜•ì˜ ë‚´ë¶€ í¬ê¸° %d" -#: catalog/pg_type.c:269 catalog/pg_type.c:277 catalog/pg_type.c:285 -#: catalog/pg_type.c:294 +#: catalog/pg_type.c:266 catalog/pg_type.c:274 catalog/pg_type.c:282 +#: catalog/pg_type.c:291 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "\"%c\" ì •ë ¬ì€ í¬ê¸°ê°€ %dì¸ ì „ë‹¬ ê°’ 형ì‹ì— 유효하지 않ìŒ" -#: catalog/pg_type.c:301 +#: catalog/pg_type.c:298 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "ë‚´ë¶€ í¬ê¸° %dì€(는) 전달 ê°’ 형ì‹ì— 유효하지 않ìŒ" -#: catalog/pg_type.c:310 catalog/pg_type.c:316 +#: catalog/pg_type.c:307 catalog/pg_type.c:313 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "\"%c\" ì •ë ¬ì€ ê°€ë³€ ê¸¸ì´ í˜•ì‹ì— 유효하지 않ìŒ" -#: catalog/pg_type.c:324 +#: catalog/pg_type.c:321 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "_^_ ê³ ì •í¬ê¸° ìžë£Œí˜•ì€ PLAIN ì €ìž¥ë°©ë²•ì„ ê°€ì ¸ì•¼ë§Œ 합니다" -#: catalog/pg_type.c:789 +#: catalog/pg_type.c:800 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "\"%s\" 형ì‹ì˜ ë°°ì—´ í˜•ì‹ ì´ë¦„ì„ ìƒì„±í•  수 ì—†ìŒ" -#: catalog/toasting.c:105 commands/indexcmds.c:389 commands/tablecmds.c:4359 -#: commands/tablecmds.c:12047 +#: catalog/toasting.c:105 commands/indexcmds.c:442 commands/tablecmds.c:4981 +#: commands/tablecmds.c:13400 #, c-format msgid "\"%s\" is not a table or materialized view" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ë„ êµ¬ì²´í™”ëœ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„ êµ¬ì²´í™”ëœ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" #: catalog/toasting.c:158 #, c-format msgid "shared tables cannot be toasted after initdb" msgstr "공유ë˜ëŠ” í…Œì´ë¸”ì€ initdb ë’¤ì—는 toast ë  ìˆ˜ 없습니다" -#: commands/aggregatecmds.c:159 +#: commands/aggregatecmds.c:166 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "순서 있는 세트 집계함수만 가설ì ì¼ 수 있습니다" -#: commands/aggregatecmds.c:184 +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "\"%s\" ì†ì„±ì„ aggregateì—서 알 수 ì—†ìŒ" -#: commands/aggregatecmds.c:194 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" msgstr "aggregate stype ê°’ì„ ì§€ì •í•˜ì…”ì•¼í•©ë‹ˆë‹¤" -#: commands/aggregatecmds.c:198 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" msgstr "aggregate sfunc ê°’ì„ ì§€ì •í•˜ì…”ì•¼í•©ë‹ˆë‹¤" -#: commands/aggregatecmds.c:210 +#: commands/aggregatecmds.c:217 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "mstype ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ msfunc ì˜µì…˜ë„ í•¨ê»˜ 지정 해야 함" -#: commands/aggregatecmds.c:214 +#: commands/aggregatecmds.c:221 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "mstype ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ minvfunc ì˜µì…˜ë„ í•¨ê»˜ 지정 해야 함" -#: commands/aggregatecmds.c:221 +#: commands/aggregatecmds.c:228 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "msfunc ì˜µì…˜ì€ mstype 옵션과 함께 사용해야 함" -#: commands/aggregatecmds.c:225 +#: commands/aggregatecmds.c:232 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "minvfunc ì˜µì…˜ì€ mstype 옵션과 함께 사용해야 함" -#: commands/aggregatecmds.c:229 +#: commands/aggregatecmds.c:236 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "mfinalfunc ì˜µì…˜ì€ mstype 옵션과 함께 사용해야 함" -#: commands/aggregatecmds.c:233 +#: commands/aggregatecmds.c:240 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "msspace ì˜µì…˜ì€ mstype 옵션과 함께 사용해야 함" -#: commands/aggregatecmds.c:237 +#: commands/aggregatecmds.c:244 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "minitcond ì˜µì…˜ì€ mstype 옵션과 함께 사용해야 함" -#: commands/aggregatecmds.c:257 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" msgstr "aggregate ìž…ë ¥ ìžë£Œí˜•ì„ ì§€ì •í•´ì•¼ 합니다" -#: commands/aggregatecmds.c:287 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "집계 ìž…ë ¥ í˜•ì‹ ì§€ì •ì—서 basetypeì´ ì¤‘ë³µë¨" -#: commands/aggregatecmds.c:328 commands/aggregatecmds.c:369 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "%s ìžë£Œí˜•ì€ aggregate transition ìžë£Œí˜•으로 사용할 수 없습니다" -#: commands/aggregatecmds.c:340 +#: commands/aggregatecmds.c:356 #, c-format -msgid "" -"serialization functions may be specified only when the aggregate transition " -"data type is %s" +msgid "serialization functions may be specified only when the aggregate transition data type is %s" msgstr "" -#: commands/aggregatecmds.c:350 +#: commands/aggregatecmds.c:366 #, c-format -msgid "" -"must specify both or neither of serialization and deserialization functions" +msgid "must specify both or neither of serialization and deserialization functions" msgstr "" -#: commands/aggregatecmds.c:415 commands/functioncmds.c:570 +#: commands/aggregatecmds.c:431 commands/functioncmds.c:603 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "\"parallel\" 옵션 ê°’ì€ SAFE, RESTRICTED, UNSAFE ë§Œ 지정할 수 있ìŒ" -#: commands/alter.c:80 commands/event_trigger.c:231 +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "\"%s\" ì¸ìžê°’ì€ READ_ONLY, SHAREABLE, READ_WRITE ì…‹ 중 하나여야 함" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format msgid "event trigger \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì´ë²¤íЏ 트리거가 ì´ë¯¸ 있ìŒ" -#: commands/alter.c:83 commands/foreigncmds.c:597 +#: commands/alter.c:87 commands/foreigncmds.c:595 #, c-format msgid "foreign-data wrapper \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì™¸ë¶€ ìžë£Œ 래í¼ê°€ ì´ë¯¸ 있ìŒ" -#: commands/alter.c:86 commands/foreigncmds.c:890 +#: commands/alter.c:90 commands/foreigncmds.c:898 #, c-format msgid "server \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì„œë²„ê°€ ì´ë¯¸ 있ìŒ" -#: commands/alter.c:89 commands/proclang.c:366 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ í”„ë¡œì‹œì£¼ì–¼ 언어가 ì´ë¯¸ 있습니다" -#: commands/alter.c:112 +#: commands/alter.c:96 commands/publicationcmds.c:176 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ ë°œí–‰ì´ ì´ë¯¸ 있습니다" + +#: commands/alter.c:99 commands/subscriptioncmds.c:358 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ êµ¬ë…ì´ ì´ë¯¸ 있습니다" + +#: commands/alter.c:122 #, c-format msgid "conversion \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" ì´ë¦„ì˜ ë³€í™˜ê·œì¹™(conversin)ì´ \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있습니다" -#: commands/alter.c:116 +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" ì´ë¦„ì˜ í†µê³„ì •ë³´ 개체는 \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있습니다" + +#: commands/alter.c:130 #, c-format msgid "text search parser \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 전문 검색 파서가 \"%s\" 스키마 ì•ˆì— ì´ë¯¸ 있ìŒ" -#: commands/alter.c:120 +#: commands/alter.c:134 #, c-format msgid "text search dictionary \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 전문 검색 ì‚¬ì „ì´ \"%s\" 스키마 ì•ˆì— ì´ë¯¸ 있ìŒ" -#: commands/alter.c:124 +#: commands/alter.c:138 #, c-format msgid "text search template \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 전문 검색 í…œí”Œë¦¿ì´ \"%s\" 스키마 ì•ˆì— ì´ë¯¸ 있ìŒ" -#: commands/alter.c:128 +#: commands/alter.c:142 #, c-format msgid "text search configuration \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 전문 검색 êµ¬ì„±ì´ \"%s\" 스키마 ì•ˆì— ì´ë¯¸ 있ìŒ" -#: commands/alter.c:202 +#: commands/alter.c:216 #, c-format msgid "must be superuser to rename %s" msgstr "%s ì´ë¦„ 변경 ìž‘ì—…ì€ ìŠˆí¼ìœ ì €ë§Œ í•  수 있ìŒ" -#: commands/alter.c:655 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" msgstr "%sì˜ ìŠ¤í‚¤ë§ˆ ì§€ì •ì€ ìŠˆí¼ìœ ì ¸ì—¬ì•¼í•©ë‹ˆë‹¤" @@ -5525,227 +5250,216 @@ msgstr "슈í¼ìœ ì €ë§Œ ì ‘ê·¼ ë°©ë²•ì„ ë§Œë“¤ 수 있습니다." msgid "access method \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì´ ì´ë¯¸ 있습니다." -#: commands/amcmds.c:124 +#: commands/amcmds.c:123 #, c-format msgid "must be superuser to drop access methods" msgstr "ì ‘ê·¼ ë°©ë²•ì€ ìŠˆí¼ìœ ì €ë§Œ 삭제할 수 있습니다." -#: commands/amcmds.c:175 commands/indexcmds.c:164 commands/indexcmds.c:496 -#: commands/opclasscmds.c:365 commands/opclasscmds.c:790 +#: commands/amcmds.c:174 commands/indexcmds.c:172 commands/indexcmds.c:582 +#: commands/opclasscmds.c:364 commands/opclasscmds.c:778 #, c-format msgid "access method \"%s\" does not exist" msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/amcmds.c:251 +#: commands/amcmds.c:250 #, c-format msgid "handler function is not specified" msgstr "핸들러 함수 ë¶€ë¶„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤" -#: commands/amcmds.c:263 commands/event_trigger.c:240 -#: commands/foreigncmds.c:489 commands/proclang.c:117 commands/proclang.c:288 -#: commands/trigger.c:441 parser/parse_clause.c:761 +#: commands/amcmds.c:262 commands/event_trigger.c:245 +#: commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 +#: commands/trigger.c:696 parser/parse_clause.c:989 #, c-format msgid "function %s must return type %s" msgstr "%s 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/analyze.c:145 +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" msgstr "\"%s\" ë¶„ì„ ê±´ë„ˆëœ€ --- 잠글 수 ì—†ìŒ" -#: commands/analyze.c:162 +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "\"%s\" ë¶„ì„ ê±´ë„ˆëœ€ --- 릴레ì´ì…˜ì–´ ì—†ìŒ" + +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" msgstr "\"%s\" ë¶„ì„ ê±´ë„ˆëœ€ --- 슈í¼ìœ ì €ë§Œ ë¶„ì„í•  수 있ìŒ" -#: commands/analyze.c:166 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" -msgstr "" -"\"%s\" ë¶„ì„ ê±´ë„ˆëœ€ --- 슈í¼ìœ ì € ë˜ëŠ” ë°ì´í„°ë² ì´ìФ 소유주만 ë¶„ì„í•  수 있ìŒ" +msgstr "\"%s\" ë¶„ì„ ê±´ë„ˆëœ€ --- 슈í¼ìœ ì € ë˜ëŠ” ë°ì´í„°ë² ì´ìФ 소유주만 ë¶„ì„í•  수 있ìŒ" -#: commands/analyze.c:170 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" msgstr "\"%s\" 건너뜀 --- í…Œì´ë¸”ì´ë‚˜ ë°ì´í„°ë² ì´ìФ ì†Œìœ ì£¼ë§Œì´ ë¶„ì„í•  수 있ìŒ" -#: commands/analyze.c:230 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "\"%s\" 건너뜀 --- 외부 í…Œì´ë¸”ì€ ë¶„ì„í•  수 ì—†ìŒ" -#: commands/analyze.c:241 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" -msgstr "" -"\"%s\" 건너뜀 --- í…Œì´ë¸”ì´ ì•„ë‹ˆê±°ë‚˜, 특수 시스템 í…Œì´ë¸”ë“¤ì€ ë¶„ì„í•  수 ì—†ìŒ" +msgstr "\"%s\" 건너뜀 --- í…Œì´ë¸”ì´ ì•„ë‹ˆê±°ë‚˜, 특수 시스템 í…Œì´ë¸”ë“¤ì€ ë¶„ì„í•  수 ì—†ìŒ" -#: commands/analyze.c:320 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "\"%s.%s\" ìƒì† 관계 ë¶„ì„중" -#: commands/analyze.c:325 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "\"%s.%s\" ìžë£Œ 통계 수집 중" -#: commands/analyze.c:650 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "\"%s\" ì¹¼ëŸ¼ì´ \"%s\" 릴레ì´ì…˜ì—서 ë‘ ë²ˆ ì´ìƒ 사용ë˜ì—ˆìŒ" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "\"%s.%s.%s\" í…Œì´ë¸”ì˜ ì‹œìŠ¤í…œ 사용 ìžë™ ë¶„ì„: %s" -#: commands/analyze.c:1204 +#: commands/analyze.c:1273 #, c-format -msgid "" -"\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead " -"rows; %d rows in sample, %.0f estimated total rows" -msgstr "" -"\"%s\": íƒìƒ‰í•œ 페ì´ì§€: %d, 전체페ì´ì§€: %u, 실ìžë£Œ: %.0fê°œ, 쓰레기ìžë£Œ: %.0f" -"ê°œ; 표본 추출 ìžë£Œ: %dê°œ, 예ìƒí•œ ì´ ìžë£Œ: %.0fê°œ" +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "\"%s\": íƒìƒ‰í•œ 페ì´ì§€: %d, 전체페ì´ì§€: %u, 실ìžë£Œ: %.0fê°œ, 쓰레기ìžë£Œ: %.0fê°œ; 표본 추출 ìžë£Œ: %dê°œ, 예ìƒí•œ ì´ ìžë£Œ: %.0fê°œ" -#: commands/analyze.c:1283 +#: commands/analyze.c:1353 #, c-format -msgid "" -"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " -"contains no child tables" -msgstr "" -"\"%s.%s\" ìƒì† ë‚˜ë¬´ì˜ í†µê³„ 수집 건너뜀 --- ì´ ìƒì† 나무ì—는 하위 í…Œì´ë¸”ì´ ì—†" -"ìŒ" +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "\"%s.%s\" ìƒì† ë‚˜ë¬´ì˜ í†µê³„ 수집 건너뜀 --- ì´ ìƒì† 나무ì—는 하위 í…Œì´ë¸”ì´ ì—†ìŒ" -#: commands/analyze.c:1372 +#: commands/analyze.c:1451 #, c-format -msgid "" -"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " -"contains no analyzable child tables" -msgstr "" -"\"%s.%s\" ìƒì† ë‚˜ë¬´ì˜ í†µê³„ 수집 건너뜀 --- ì´ ìƒì† 나무ì—는 통계 수집할 하위 " -"í…Œì´ë¸”ì´ ì—†ìŒ" - -#: commands/analyze.c:1420 commands/tablecmds.c:8079 executor/execQual.c:2927 -msgid "could not convert row type" -msgstr "로우 ìžë£Œí˜•ì„ ë³€í™˜ í•  수 ì—†ìŒ" +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "\"%s.%s\" ìƒì† ë‚˜ë¬´ì˜ í†µê³„ 수집 건너뜀 --- ì´ ìƒì† 나무ì—는 통계 수집할 하위 í…Œì´ë¸”ì´ ì—†ìŒ" -#: commands/async.c:555 +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "ì±„ë„ ì´ë¦„ì€ ë¹„ì›Œë‘˜ 수 ì—†ìŒ" -#: commands/async.c:560 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "ì±„ë„ ì´ë¦„ì´ ë„ˆë¬´ 긺" # # nonun 부분 begin -#: commands/async.c:567 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "payload 문ìžì—´ì´ 너무 긺" -#: commands/async.c:753 +#: commands/async.c:756 #, c-format -msgid "" -"cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" -msgstr "" -"LISTEN, UNLISTEN ë˜ëŠ” NOTIFY 옵션으로 ì‹¤í–‰ëœ íŠ¸ëžœìž­ì…˜ì„ PREPAREí•  수 ì—†ìŒ" +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "LISTEN, UNLISTEN ë˜ëŠ” NOTIFY 옵션으로 ì‹¤í–‰ëœ íŠ¸ëžœìž­ì…˜ì„ PREPAREí•  수 ì—†ìŒ" -#: commands/async.c:856 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "NOTIFY íì— ë„ˆë¬´ ë§Žì€ ì•Œë¦¼ì´ ìžˆìŠµë‹ˆë‹¤" -#: commands/async.c:1486 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTIFY í 사용률: %.0f%%" -#: commands/async.c:1488 +#: commands/async.c:1493 #, c-format -msgid "" -"The server process with PID %d is among those with the oldest transactions." +msgid "The server process with PID %d is among those with the oldest transactions." msgstr "%d PID 서버 프로세스가 가장 ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì„ ì‚¬ìš©í•˜ê³  있습니다." -#: commands/async.c:1491 +#: commands/async.c:1496 #, c-format -msgid "" -"The NOTIFY queue cannot be emptied until that process ends its current " -"transaction." -msgstr "" -"ì´ í”„ë¡œì„¸ìŠ¤ì˜ í˜„ìž¬ íŠ¸ëžœìž­ì…˜ì„ ì¢…ë£Œí•˜ì§€ 않으면, NOTIFY í를 비울 수 없습니다" +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "ì´ í”„ë¡œì„¸ìŠ¤ì˜ í˜„ìž¬ íŠ¸ëžœìž­ì…˜ì„ ì¢…ë£Œí•˜ì§€ 않으면, NOTIFY í를 비울 수 없습니다" -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì€ cluster ìž‘ì—…ì„ í•  수 없습니다" -#: commands/cluster.c:159 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "파티션 ëœ í…Œì´ë¸”ì€ í´ëŸ¬ìŠ¤í„° ìž‘ì—…ì„ í•  수 ì—†ìŒ" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "\"%s\" í…Œì´ë¸”ì„ ìœ„í•œ previously clustered ì¸ë±ìŠ¤ê°€ ì—†ìŒ" -#: commands/cluster.c:173 commands/tablecmds.c:9383 commands/tablecmds.c:11143 +#: commands/cluster.c:181 commands/tablecmds.c:10643 commands/tablecmds.c:12493 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” \"%s\" í…Œì´ë¸”ì— ì—†ìŒ" -#: commands/cluster.c:353 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "ê³µìœ ëœ ì¹´íƒˆë¡œê·¸ëŠ” í´ëŸ¬ìŠ¤í„° ìž‘ì—…ì„ í•  수 ì—†ìŒ" -#: commands/cluster.c:368 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì€ vacuum ìž‘ì—…ì„ í•  수 ì—†ìŒ" -#: commands/cluster.c:431 commands/tablecmds.c:11153 +#: commands/cluster.c:439 commands/tablecmds.c:12503 #, c-format msgid "\"%s\" is not an index for table \"%s\"" -msgstr "\"%s\" ê°ì²´ëŠ” \"%s\" í…Œì´ë¸”ì„ ìœ„í•œ ì¸ë±ìŠ¤ê°€ 아님" +msgstr "\"%s\" 개체는 \"%s\" í…Œì´ë¸”ì„ ìœ„í•œ ì¸ë±ìŠ¤ê°€ 아님" -#: commands/cluster.c:439 +#: commands/cluster.c:447 #, c-format -msgid "" -"cannot cluster on index \"%s\" because access method does not support " -"clustering" -msgstr "" -"\"%s\" ì¸ë±ìŠ¤ëŠ” ìžë£Œ 액세스 ë°©ë²•ì´ cluster ìž‘ì—…ì„ í•  수 없는 방법입니다." +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” ìžë£Œ 액세스 ë°©ë²•ì´ cluster ìž‘ì—…ì„ í•  수 없는 방법입니다." -#: commands/cluster.c:451 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" -msgstr "" -"\"%s\" ì¸ë±ìŠ¤ê°€ 부분ì¸ë±ìФ(partial index)ë¼ì„œ cluster ìž‘ì—…ì„ í•  수 없습니다" +msgstr "\"%s\" ì¸ë±ìŠ¤ê°€ 부분ì¸ë±ìФ(partial index)ë¼ì„œ cluster ìž‘ì—…ì„ í•  수 없습니다" -#: commands/cluster.c:465 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "ìž˜ëª»ëœ \"%s\" ì¸ë±ìŠ¤ì— ëŒ€í•´ í´ëŸ¬ìŠ¤í„°ë§í•  수 ì—†ìŒ" -#: commands/cluster.c:918 +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œ ì¸ë±ìФ í´ëŸ¬ìŠ¤í„° 표시를 í•  수 ì—†ìŒ" + +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr " \"%s.%s\" í´ëŸ¬ìŠ¤í„°ë§ ì¤‘ (사용 ì¸ë±ìФ: \"%s\")" -#: commands/cluster.c:924 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" -msgstr "순차 íƒìƒ‰ê³¼ ì •ë ¬ì„ ì´ìš©í•´ì„œ \"%s.%s\" ê°ì²´ í´ëŸ¬ìŠ¤í„°ë§ ì¤‘" +msgstr "순차 íƒìƒ‰ê³¼ ì •ë ¬ì„ ì´ìš©í•´ì„œ \"%s.%s\" 개체 í´ëŸ¬ìŠ¤í„°ë§ ì¤‘" -#: commands/cluster.c:929 commands/vacuumlazy.c:479 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" msgstr "\"%s.%s\" 청소 중" -#: commands/cluster.c:1088 +#: commands/cluster.c:1106 #, c-format -msgid "" -"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" -msgstr "" -"\"%s\": 삭제가능한 %.0fê°œ, 삭제불가능한 %.0fê°œì˜ í–‰ ë²„ì „ì„ %u 페ì´ì§€ì—서 발견" -"í–ˆìŒ." +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "\"%s\": 삭제가능한 %.0fê°œ, 삭제불가능한 %.0fê°œì˜ í–‰ ë²„ì „ì„ %u 페ì´ì§€ì—서 발견했ìŒ." -#: commands/cluster.c:1092 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5754,55 +5468,92 @@ msgstr "" "%.0f ê°œì˜ ì‚¬ìš©í•˜ì§€ 않는 로우 ë²„ì „ì„ ì•„ì§ ì§€ìš°ì§€ 못했ìŒ.\n" "%s." -#: commands/collationcmds.c:80 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "\"%s\" ì—°ì‚°ìž ì†ì„±ì„ 처리할 수 ì—†ìŒ" -#: commands/collationcmds.c:125 +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "\"default\" ì •ë ¬ê·œì¹™ì€ ë³µì‚¬ë  ìˆ˜ ì—†ìŒ" + +#: commands/collationcmds.c:172 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "알 수 없는 정렬규칙 ì œê³µìž ì´ë¦„: %s" + +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "\"lc_collate\" ì˜µì…˜ì„ ì§€ì •í•´ì•¼ 함" -#: commands/collationcmds.c:130 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "\"lc_ctype\" ì˜µì…˜ì„ ì§€ì •í•´ì•¼ 함" -#: commands/collationcmds.c:166 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 정렬규칙(ëŒ€ìƒ ì¸ì½”딩: \"%s\")ì´ \"%s\" 스키마 ì•ˆì— ì´ë¯¸ 있ìŒ" -#: commands/collationcmds.c:177 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" ì •ë ¬ê·œì¹™ì´ \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있습니다" -#: commands/comment.c:62 commands/dbcommands.c:797 commands/dbcommands.c:962 -#: commands/dbcommands.c:1067 commands/dbcommands.c:1257 -#: commands/dbcommands.c:1477 commands/dbcommands.c:1594 -#: commands/dbcommands.c:2011 utils/init/postinit.c:841 -#: utils/init/postinit.c:943 utils/init/postinit.c:960 +#: commands/collationcmds.c:304 +#, c-format +msgid "changing version from %s to %s" +msgstr "%sì—서 %s 버전으로 바꿉니다" + +#: commands/collationcmds.c:319 +#, c-format +msgid "version has not changed" +msgstr "ë²„ì „ì´ ë°”ë€Œì§€ 않았습니다" + +#: commands/collationcmds.c:450 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "\"%s\" ë¡œì¼€ì¼ ì´ë¦„ì„ ì–¸ì–´ 태그로 변환할 수 ì—†ìŒ: %s" + +#: commands/collationcmds.c:511 +#, c-format +msgid "must be superuser to import system collations" +msgstr "시스템 ì •ë ¬ê·œì¹™ì„ ê°€ì ¸ì˜¤ë ¤ë©´ 슈í¼ìœ ì €ì—¬ì•¼í•¨" + +#: commands/collationcmds.c:534 commands/copy.c:1826 commands/copy.c:3131 +#: libpq/be-secure-common.c:80 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ: %m" + +#: commands/collationcmds.c:665 +#, c-format +msgid "no usable system locales were found" +msgstr "사용할 수 있는 시스템 로케ì¼ì´ ì—†ìŒ" + +#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 +#: commands/dbcommands.c:1100 commands/dbcommands.c:1290 +#: commands/dbcommands.c:1513 commands/dbcommands.c:1627 +#: commands/dbcommands.c:2043 utils/init/postinit.c:853 +#: utils/init/postinit.c:958 utils/init/postinit.c:975 #, c-format msgid "database \"%s\" does not exist" msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ ì—†ìŒ" -#: commands/comment.c:101 commands/seclabel.c:116 parser/parse_utilcmd.c:753 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, composite type, or foreign " -"table" -msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ë„, ë·°ë„, êµ¬ì²´í™”ëœ ë·°ë„, 복합 ìžë£Œí˜•ë„, 외부 í…Œì´ë¸”ë„ ì•„" -"닙니다." +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„, ë·°ë„, êµ¬ì²´í™”ëœ ë·°ë„, 복합 ìžë£Œí˜•ë„, 외부 í…Œì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2715 +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "\"%s\" 함수가 트리거 관리ìžì—서 호출ë˜ì§€ 않았ìŒ" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2724 +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "AFTER ROWì—서 \"%s\" 함수를 실행해야 함" @@ -5812,546 +5563,547 @@ msgstr "AFTER ROWì—서 \"%s\" 함수를 실행해야 함" msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "INSERT ë˜ëŠ” UPDATEì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" -#: commands/conversioncmds.c:67 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "\"%s\" ì›ë³¸ ì¸ì½”딩 ì—†ìŒ" -#: commands/conversioncmds.c:74 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "\"%s\" ëŒ€ìƒ ì¸ì½”딩 ì—†ìŒ" -#: commands/conversioncmds.c:88 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "%s ì¸ì½”딩 변환 함수는 %s í˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/copy.c:362 commands/copy.c:374 commands/copy.c:408 -#: commands/copy.c:420 +#: commands/copy.c:372 commands/copy.c:406 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY ëª…ë ¹ì€ stdout, stdin ìž…ì¶œë ¥ì„ ì§€ì›í•˜ì§€ 않습니다" -#: commands/copy.c:520 +#: commands/copy.c:506 #, c-format msgid "could not write to COPY program: %m" msgstr "COPY 프로그램으로 파ì¼ì„ 쓸 수 없습니다: %m" -#: commands/copy.c:525 +#: commands/copy.c:511 #, c-format msgid "could not write to COPY file: %m" msgstr "COPY 파ì¼ë¡œë¡œ 파ì¼ì„ 쓸 수 없습니다: %m" -#: commands/copy.c:538 +#: commands/copy.c:524 #, c-format msgid "connection lost during COPY to stdout" msgstr "COPY 명령ì—서 stdout으로 ìžë£Œë¥¼ 내보내는 ë™ì•ˆ ì—°ê²°ì´ ëŠê²¼ìŠµë‹ˆë‹¤" -#: commands/copy.c:579 +#: commands/copy.c:568 #, c-format msgid "could not read from COPY file: %m" msgstr "COPY ëª…ë ¹ì— ì‚¬ìš©í•  파ì¼ì„ ì½ì„ 수 없습니다: %m" -#: commands/copy.c:595 commands/copy.c:616 commands/copy.c:620 -#: tcop/postgres.c:341 tcop/postgres.c:377 tcop/postgres.c:404 +#: commands/copy.c:584 commands/copy.c:605 commands/copy.c:609 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "열린 트랜잭션과 함께 í´ë¼ì´ì–¸íЏ ì—°ê²°ì—서 예ìƒì¹˜ ì•Šì€ EOF 발견ë¨" -#: commands/copy.c:633 +#: commands/copy.c:622 #, c-format msgid "COPY from stdin failed: %s" msgstr "COPY 명령ì—서 stdin으로 ìžë£Œ 가져오기 실패: %s" -#: commands/copy.c:649 +#: commands/copy.c:638 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" -msgstr "" -"COPY 명령으로 stdin으로 ìžë£Œë¥¼ 가져오는 ë™ì•ˆ 예ìƒì¹˜ ì•Šì€ ë©”ì‹œì§€ 타입 0x%02X " -"발견ë¨" +msgstr "COPY 명령으로 stdin으로 ìžë£Œë¥¼ 가져오는 ë™ì•ˆ 예ìƒì¹˜ ì•Šì€ ë©”ì‹œì§€ 타입 0x%02X 발견ë¨" -#: commands/copy.c:806 +#: commands/copy.c:804 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "외부 í”„ë¡œê·¸ëž¨ì„ ì´ìš©í•˜ëŠ” COPY ìž‘ì—…ì€ ìŠˆí¼ìœ ì €ë§Œ 허용합니다." +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "외부 í”„ë¡œê·¸ëž¨ì„ ì´ìš©í•˜ëŠ” COPY ìž‘ì—…ì€ ìŠˆí¼ìœ ì €ì™€ pg_execute_server_program 롤 소ì†ì›ë§Œ 허용합니다." -#: commands/copy.c:807 commands/copy.c:813 +#: commands/copy.c:805 commands/copy.c:814 commands/copy.c:821 #, c-format -msgid "" -"Anyone can COPY to stdout or from stdin. psql's \\copy command also works " -"for anyone." +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." msgstr "ì¼ë°˜ 사용ìžì¸ë°, ì´ ìž‘ì—…ì´ í•„ìš”í•˜ë©´, psqlì˜ \\copy ëª…ë ¹ì„ ì´ìš©í•˜ì„¸ìš”" -#: commands/copy.c:812 +#: commands/copy.c:813 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "" -"COPY 명령으로 ìžë£Œë¥¼ 파ì¼ë¡œ 내보내거나 파ì¼ì—서 가져오려면, superuser여야만 " -"합니다" +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "파ì¼ì„ ì½ì–´ COPY 명령으로 ìžë£Œë¥¼ 저장하려면, 슈í¼ìœ ì €ì´ê±°ë‚˜ pg_read_server_files 롤 구성ì›ì´ì–´ì•¼ 합니다." + +#: commands/copy.c:820 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "COPY 명령 결과를 파ì¼ë¡œ 저장하려면, 슈í¼ìœ ì €ì´ê±°ë‚˜ pg_write_server_files 롤 구성ì›ì´ì–´ì•¼ 합니다." -#: commands/copy.c:879 +#: commands/copy.c:883 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "로우 단위 보안 기능으로 COPY FROM ëª…ë ¹ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/copy.c:880 +#: commands/copy.c:884 #, c-format msgid "Use INSERT statements instead." msgstr "ëŒ€ì‹ ì— INSERT êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: commands/copy.c:1058 +#: commands/copy.c:1069 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "\"%s\" COPY ì–‘ì‹ì€ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/copy.c:1129 commands/copy.c:1143 commands/copy.c:1157 -#: commands/copy.c:1177 +#: commands/copy.c:1149 commands/copy.c:1165 commands/copy.c:1180 +#: commands/copy.c:1202 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "\"%s\" ì˜µì…˜ì— ëŒ€í•œ ì¸ìžëŠ” 칼럼 ì´ë¦„ 목ë¡ì´ì–´ì•¼ 합니다." -#: commands/copy.c:1190 +#: commands/copy.c:1217 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "\"%s\" ì˜µì…˜ì— ëŒ€í•œ ì¸ìžëŠ” ì¸ì½”딩 ì´ë¦„ì´ì–´ì•¼ 합니다." -#: commands/copy.c:1196 commands/dbcommands.c:232 commands/dbcommands.c:1427 +#: commands/copy.c:1224 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" msgstr "\"%s\" ì˜µì…˜ì€ íƒ€ë‹¹í•˜ì§€ 않습니다." -#: commands/copy.c:1207 +#: commands/copy.c:1236 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "BINARY 모드ì—서는 DELIMITER ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" -#: commands/copy.c:1212 +#: commands/copy.c:1241 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "BINARY 모드ì—서는 NULL ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" -#: commands/copy.c:1234 +#: commands/copy.c:1263 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "COPY 구분ìžëŠ” 1ë°”ì´íŠ¸ì˜ ë‹¨ì¼ ë¬¸ìžì—¬ì•¼ 함" -#: commands/copy.c:1241 +#: commands/copy.c:1270 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "COPY 명령ì—서 사용할 칼럼 구분ìžë¡œ 줄바꿈 문ìžë“¤ì„ 사용할 수 없습니다" -#: commands/copy.c:1247 +#: commands/copy.c:1276 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "COPY null 표현ì—서 줄바꿈 ë˜ëŠ” ìºë¦¬ì§€ ë¦¬í„´ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/copy.c:1264 +#: commands/copy.c:1293 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "COPY 구분ìžëŠ” \"%s\"ì¼ ìˆ˜ ì—†ìŒ" -#: commands/copy.c:1270 +#: commands/copy.c:1299 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "COPY HEADER는 CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1276 +#: commands/copy.c:1305 #, c-format msgid "COPY quote available only in CSV mode" msgstr "COPY 따옴표는 CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1281 +#: commands/copy.c:1310 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "COPY 따옴표는 1ë°”ì´íŠ¸ì˜ ë‹¨ì¼ ë¬¸ìžì—¬ì•¼ 함" -#: commands/copy.c:1286 +#: commands/copy.c:1315 #, c-format msgid "COPY delimiter and quote must be different" msgstr "COPY êµ¬ë¶„ìž ë° ë”°ì˜´í‘œëŠ” 서로 달ë¼ì•¼ 함" -#: commands/copy.c:1292 +#: commands/copy.c:1321 #, c-format msgid "COPY escape available only in CSV mode" msgstr "COPY ì´ìŠ¤ì¼€ì´í”„는 CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1297 +#: commands/copy.c:1326 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "COPY ì´ìŠ¤ì¼€ì´í”„는 1ë°”ì´íŠ¸ì˜ ë‹¨ì¼ ë¬¸ìžì—¬ì•¼ 함" -#: commands/copy.c:1303 +#: commands/copy.c:1332 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "COPY force quote는 CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1307 +#: commands/copy.c:1336 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "COPY force quote는 COPY TOì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1313 +#: commands/copy.c:1342 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "COPY force not nullì€ CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1317 +#: commands/copy.c:1346 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "COPY force not nullì€ COPY FROMì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1323 +#: commands/copy.c:1352 #, c-format msgid "COPY force null available only in CSV mode" msgstr "COPY force nullì€ CSV 모드ì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1328 +#: commands/copy.c:1357 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "COPY force nullì€ COPY FROMì—서만 사용할 수 있ìŒ" -#: commands/copy.c:1334 +#: commands/copy.c:1363 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "COPY 구분ìžëŠ” NULL ì§€ì •ì— í‘œì‹œë˜ì§€ 않아야 함" -#: commands/copy.c:1341 +#: commands/copy.c:1370 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "CSV 따옴표는 NULL ì§€ì •ì— í‘œì‹œë˜ì§€ 않아야 함" -#: commands/copy.c:1402 +#: commands/copy.c:1431 #, c-format msgid "table \"%s\" does not have OIDs" -msgstr "" -"\"%s\" í…Œì´ë¸”ì€ without oids ì†ì„±ìœ¼ë¡œ ë§Œë“¤ì–´ì¡Œê¸°ì— OID ê°’ì„ êµ¬í•  수 없습니다" +msgstr "\"%s\" í…Œì´ë¸”ì€ without oids ì†ì„±ìœ¼ë¡œ ë§Œë“¤ì–´ì¡Œê¸°ì— OID ê°’ì„ êµ¬í•  수 없습니다" -#: commands/copy.c:1419 +#: commands/copy.c:1448 #, c-format msgid "COPY (query) WITH OIDS is not supported" msgstr "COPY (쿼리) WITH OIDS ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/copy.c:1439 +#: commands/copy.c:1469 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "DO INSTEAD NOTHING 룰(rule)ì€ COPY 구문ì—서 ì§€ì›í•˜ì§€ 않습니다." -#: commands/copy.c:1453 +#: commands/copy.c:1483 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "ì„ íƒì  DO INSTEAD ë£°ì€ COPY 구문ì—서 ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/copy.c:1457 +#: commands/copy.c:1487 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "DO ALSO 룰(rule)ì€ COPY 구문ì—서 ì§€ì›í•˜ì§€ 않습니다." -#: commands/copy.c:1462 +#: commands/copy.c:1492 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "다중 구문 DO INSTEAD ë£°ì€ COPY 구문ì—서 ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/copy.c:1472 +#: commands/copy.c:1502 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/copy.c:1489 +#: commands/copy.c:1519 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "COPY 쿼리는 RETURNING ì ˆì´ ìžˆì–´ì•¼ 합니다" -#: commands/copy.c:1517 +#: commands/copy.c:1547 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "COPY ë¬¸ì— ì˜í•´ ì°¸ì¡°ëœ ë¦´ë ˆì´ì…˜ì´ 변경 ë˜ì—ˆìŒ" -#: commands/copy.c:1575 +#: commands/copy.c:1606 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "\"%s\" FORCE_QUOTE ì¹¼ëŸ¼ì€ COPYì—서 참조ë˜ì§€ 않ìŒ" -#: commands/copy.c:1597 +#: commands/copy.c:1629 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "\"%s\" FORCE_NOT_NULL ì¹¼ëŸ¼ì€ COPYì—서 참조ë˜ì§€ 않ìŒ" -#: commands/copy.c:1619 +#: commands/copy.c:1652 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" -msgstr "\"%s\" FORCE_NULL ì—´ì€ COPYì—서 참조ë˜ì§€ 않ìŒ" +msgstr "\"%s\" FORCE_NULL ì¹¼ëŸ¼ì€ COPYì—서 참조ë˜ì§€ 않ìŒ" -#: commands/copy.c:1684 +#: commands/copy.c:1718 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "외부 명령으로 파ì´í”„를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: commands/copy.c:1688 +#: commands/copy.c:1722 #, c-format msgid "program \"%s\" failed" msgstr "\"%s\" 프로그램 실패" -#: commands/copy.c:1738 +#: commands/copy.c:1772 #, c-format msgid "cannot copy from view \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” ë·°(view)입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” ë·°(view)입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" -#: commands/copy.c:1740 commands/copy.c:1746 commands/copy.c:1752 +#: commands/copy.c:1774 commands/copy.c:1780 commands/copy.c:1786 +#: commands/copy.c:1797 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "COPY (SELECT ...) TO ë³€í˜•ì„ ì‹œë„하십시오." -#: commands/copy.c:1744 +#: commands/copy.c:1778 #, c-format msgid "cannot copy from materialized view \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” êµ¬ì²´í™”ëœ ë·°ìž…ë‹ˆë‹¤. ìžë£Œë¥¼ 내보낼 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” êµ¬ì²´í™”ëœ ë·°ìž…ë‹ˆë‹¤. ìžë£Œë¥¼ 내보낼 수 없습니다" -#: commands/copy.c:1750 +#: commands/copy.c:1784 #, c-format msgid "cannot copy from foreign table \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” 외부 í…Œì´ë¸”입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” 외부 í…Œì´ë¸”입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" -#: commands/copy.c:1756 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from sequence \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” 시퀀스입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” 시퀀스입니다. ìžë£Œë¥¼ 내보낼 수 없습니다" -#: commands/copy.c:1761 +#: commands/copy.c:1795 #, c-format -msgid "cannot copy from non-table relation \"%s\"" -msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ì´ ì•„ë‹Œ 릴레ì´ì…˜(relation)ì´ê¸°ì— ìžë£Œë¥¼ 내보낼 수 없습니" -"다" +msgid "cannot copy from partitioned table \"%s\"" +msgstr "\"%s\" 파티션 ëœ í…Œì´ë¸”ì—서 복사할 수 ì—†ìŒ" -#: commands/copy.c:1786 commands/copy.c:2822 +#: commands/copy.c:1801 #, c-format -msgid "could not execute command \"%s\": %m" -msgstr "\"%s\" ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ: %m" +msgid "cannot copy from non-table relation \"%s\"" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ì´ ì•„ë‹Œ 릴레ì´ì…˜(relation)ì´ê¸°ì— ìžë£Œë¥¼ 내보낼 수 없습니다" -#: commands/copy.c:1801 +#: commands/copy.c:1841 #, c-format msgid "relative path not allowed for COPY to file" msgstr "COPY ëª…ë ¹ì— ì‚¬ìš©í•  íŒŒì¼ ì´ë¦„으로 ìƒëŒ€ê²½ë¡œëŠ” 사용할 수 없습니다" -#: commands/copy.c:1809 +#: commands/copy.c:1862 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "\"%s\" íŒŒì¼ ì—´ê¸° 실패: %m" -#: commands/copy.c:1821 commands/copy.c:2845 +#: commands/copy.c:1865 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO ëª…ë ¹ì€ PostgreSQL 서버 프로세스가 작업하기 때문ì—, ì„œë²„ì— ê·¸ 결과가 저장ëœë‹¤. í´ë¼ì´ì–¸íЏ 쪽ì—서 ê·¸ 결과를 저장하려면, psql \\copy 명령으로 처리할 수 있다." + +#: commands/copy.c:1878 commands/copy.c:3162 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\" 디렉터리임" -#: commands/copy.c:2144 +#: commands/copy.c:2204 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "%s 복사, %d번째 줄, %s ì—´" +msgid "COPY %s, line %s, column %s" +msgstr "%s 복사, %s번째 줄, %s ì—´" -#: commands/copy.c:2148 commands/copy.c:2195 +#: commands/copy.c:2208 commands/copy.c:2255 #, c-format -msgid "COPY %s, line %d" -msgstr "%s 복사, %d번째 줄" +msgid "COPY %s, line %s" +msgstr "%s 복사, %s번째 줄" -#: commands/copy.c:2159 +#: commands/copy.c:2219 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "%s 복사, %d번째 줄, %s ì—´: \"%s\"" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "%s 복사, %s번째 줄, %s ì—´: \"%s\"" -#: commands/copy.c:2167 +#: commands/copy.c:2227 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, %dí–‰, %s ì—´: null ìž…ë ¥" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, %sí–‰, %s ì—´: null ìž…ë ¥" -#: commands/copy.c:2189 +#: commands/copy.c:2249 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "%s 복사, %d번째 줄: \"%s\"" +msgid "COPY %s, line %s: \"%s\"" +msgstr "%s 복사, %s번째 줄: \"%s\"" -#: commands/copy.c:2273 +#: commands/copy.c:2345 #, c-format msgid "cannot copy to view \"%s\"" -msgstr "\"%s\" ë·°(view)ì— ë³µì‚¬í•  수 ì—†ìŒ" +msgstr "\"%s\" 뷰로 복사할 수 ì—†ìŒ" -#: commands/copy.c:2278 +#: commands/copy.c:2347 #, c-format -msgid "cannot copy to materialized view \"%s\"" -msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°(view)ì— ë³µì‚¬í•  수 ì—†ìŒ" +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "뷰를 통해 ìžë£Œë¥¼ 입력하려면, INSTEAD OF INSERT 트리거를 사용하세요" -#: commands/copy.c:2283 +#: commands/copy.c:2351 #, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "\"%s\" 외부 í…Œì´ë¸”ì— ë³µì‚¬í•  수 ì—†ìŒ" +msgid "cannot copy to materialized view \"%s\"" +msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°(view)ì— ë³µì‚¬í•  수 ì—†ìŒ" -#: commands/copy.c:2288 +#: commands/copy.c:2356 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "\"%s\" ì‹œí€€ìŠ¤ì— ë³µì‚¬í•  수 ì—†ìŒ" -#: commands/copy.c:2293 +#: commands/copy.c:2361 #, c-format msgid "cannot copy to non-table relation \"%s\"" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ì´ ì•„ë‹Œ 릴레ì´ì…˜(relation)ì´ê¸°ì— 복사할 수 ì—†ìŒ" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ì´ ì•„ë‹Œ 릴레ì´ì…˜(relation)ì´ê¸°ì— 복사할 수 ì—†ìŒ" -#: commands/copy.c:2356 +#: commands/copy.c:2436 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" -msgstr "" -"먼저 시작한 다른 íŠ¸ëžœìž­ì…˜ì´ ì•„ì§ í™œì„± ìƒíƒœì—¬ì„œ FREEZE ìž‘ì—…ì€ ì§„í–‰í•  수 ì—†ìŒ" +msgstr "먼저 시작한 다른 íŠ¸ëžœìž­ì…˜ì´ ì•„ì§ í™œì„± ìƒíƒœì—¬ì„œ FREEZE ìž‘ì—…ì€ ì§„í–‰í•  수 ì—†ìŒ" -#: commands/copy.c:2362 +#: commands/copy.c:2442 #, c-format -msgid "" -"cannot perform FREEZE because the table was not created or truncated in the " -"current subtransaction" -msgstr "" -"현재 하위 트랜잭션ì—서 만들어지거나 비워진 í…Œì´ë¸”ì´ ì•„ë‹ˆê¸° ë•Œë¬¸ì— FREEZE 작업" -"ì„ í•  수 ì—†ìŒ" +msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "현재 하위 트랜잭션ì—서 만들어지거나 비워진 í…Œì´ë¸”ì´ ì•„ë‹ˆê¸° ë•Œë¬¸ì— FREEZE ìž‘ì—…ì„ í•  수 ì—†ìŒ" + +#: commands/copy.c:3149 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROM ëª…ë ¹ì€ PostgreSQL 서버 프로세스가 한 파ì¼ì„ ì½ì–´ 처리합니다. í´ë¼ì´ì–¸íЏ ìª½ì— ìžˆëŠ” 파ì¼ì„ ì½ì–´ 처리 하려면, psqlì˜ \\copy 내장 명령어를 사용하세요." -#: commands/copy.c:2865 +#: commands/copy.c:3182 #, c-format msgid "COPY file signature not recognized" msgstr "file signature 복사는 ì¸ì‹ë˜ì§€ 않았ìŒ" -#: commands/copy.c:2870 +#: commands/copy.c:3187 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "COPY 명령ì—서 ìž˜ëª»ëœ íŒŒì¼ í—¤ë”를 사용함(플래그 빠졌ìŒ)" -#: commands/copy.c:2876 +#: commands/copy.c:3193 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "_^_ 복사 íŒŒì¼ í—¤ë”ì•ˆì— critical flags ê°’ë“¤ì„ ì¸ì‹í•  수 ì—†ìŒ" -#: commands/copy.c:2882 +#: commands/copy.c:3199 #, c-format msgid "invalid COPY file header (missing length)" msgstr "복사 íŒŒì¼ í—¤ë”ì— length ê°’ì´ ë¹ ì¡ŒìŒ" -#: commands/copy.c:2889 +#: commands/copy.c:3206 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "복사 íŒŒì¼ í—¤ë”ì— length ê°’ì´ ìž˜ëª»ë˜ì—ˆìŒ" -#: commands/copy.c:3022 commands/copy.c:3729 commands/copy.c:3959 +#: commands/copy.c:3337 commands/copy.c:4046 commands/copy.c:4276 #, c-format msgid "extra data after last expected column" -msgstr "마지막 ì—´ì„ ì´ˆê³¼í•´ì„œ ë˜ ë‹¤ë¥¸ ë°ì´í„°ê°€ 있ìŒ" +msgstr "마지막 ì¹¼ëŸ¼ì„ ì´ˆê³¼í•´ì„œ ë˜ ë‹¤ë¥¸ ë°ì´í„°ê°€ 있ìŒ" -#: commands/copy.c:3032 +#: commands/copy.c:3347 #, c-format msgid "missing data for OID column" msgstr "OID ì—´ì— ìžë£Œê°€ ì—†ìŒ" -#: commands/copy.c:3038 +#: commands/copy.c:3353 #, c-format msgid "null OID in COPY data" msgstr "복사 ë°ì´í„°ì— null OID ê°’ì´ ìžˆìŒ" -#: commands/copy.c:3048 commands/copy.c:3171 +#: commands/copy.c:3363 commands/copy.c:3487 #, c-format msgid "invalid OID in COPY data" msgstr "복사 ë°ì´í„°ì— ìž˜ëª»ëœ OID ê°’ì´ ìžˆìŒ" -#: commands/copy.c:3063 +#: commands/copy.c:3379 #, c-format msgid "missing data for column \"%s\"" -msgstr "\"%s\" ì—´ì˜ ìžë£Œê°€ 빠졌ìŒ" +msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ìžë£Œê°€ 빠졌ìŒ" -#: commands/copy.c:3146 +#: commands/copy.c:3462 #, c-format msgid "received copy data after EOF marker" msgstr "EOF 표시 ë’¤ì—ë„ ë³µì‚¬ ë°ì´í„°ë¥¼ 받았ìŒ" -#: commands/copy.c:3153 +#: commands/copy.c:3469 #, c-format msgid "row field count is %d, expected %d" msgstr "í–‰(row) 필드 갯수가 %d ìž„, 예ìƒê°’ì€ %d" -#: commands/copy.c:3493 commands/copy.c:3510 +#: commands/copy.c:3810 commands/copy.c:3827 #, c-format msgid "literal carriage return found in data" msgstr "ë°ì´í„°ì— carriage return ê°’ì´ ìž˜ëª»ë˜ì—ˆìŒ" -#: commands/copy.c:3494 commands/copy.c:3511 +#: commands/copy.c:3811 commands/copy.c:3828 #, c-format msgid "unquoted carriage return found in data" msgstr "ë°ì´í„°ì— carriage return ê°’ 표기가 잘못 ë˜ì—ˆìŒ" -#: commands/copy.c:3496 commands/copy.c:3513 +#: commands/copy.c:3813 commands/copy.c:3830 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "carriage return값으로 \"\\r\" 문ìžë¥¼ 사용하세요" -#: commands/copy.c:3497 commands/copy.c:3514 +#: commands/copy.c:3814 commands/copy.c:3831 #, c-format msgid "Use quoted CSV field to represent carriage return." -msgstr "" -"carriage return 문ìžë¥¼ 그대로 ì ìš©í•˜ë ¤ë©´, quoted CSV 필드를 사용하세요." +msgstr "carriage return 문ìžë¥¼ 그대로 ì ìš©í•˜ë ¤ë©´, quoted CSV 필드를 사용하세요." -#: commands/copy.c:3526 +#: commands/copy.c:3843 #, c-format msgid "literal newline found in data" msgstr "ë°ì´í„°ì— newline ê°’ì´ ìž˜ëª»ë˜ì—ˆìŒ" -#: commands/copy.c:3527 +#: commands/copy.c:3844 #, c-format msgid "unquoted newline found in data" msgstr "ë°ì´í„°ì— newline ê°’ì´ ìž˜ëª» ë˜ì—ˆìŒ" -#: commands/copy.c:3529 +#: commands/copy.c:3846 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "newline 값으로 \"\\n\" 문ìžë¥¼ 사용하세요" -#: commands/copy.c:3530 +#: commands/copy.c:3847 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "newline 문ìžë¥¼ 그대로 ì ìš©í•˜ë ¤ë©´, quoted CSV 필드를 사용하세요." -#: commands/copy.c:3576 commands/copy.c:3612 +#: commands/copy.c:3893 commands/copy.c:3929 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "end-of-copy 마í¬ëŠ” ì´ì „ newline 모양가 틀립니다" -#: commands/copy.c:3585 commands/copy.c:3601 +#: commands/copy.c:3902 commands/copy.c:3918 #, c-format msgid "end-of-copy marker corrupt" msgstr "end-of-copy 마í¬ê°€ 잘못ë˜ì—ˆìŒ" -#: commands/copy.c:4043 +#: commands/copy.c:4360 #, c-format msgid "unterminated CSV quoted field" msgstr "종료ë˜ì§€ ì•Šì€ CSV 따옴표 필드" -#: commands/copy.c:4120 commands/copy.c:4139 +#: commands/copy.c:4437 commands/copy.c:4456 #, c-format msgid "unexpected EOF in COPY data" msgstr "복사 ìžë£Œ ì•ˆì— ì˜ˆìƒì¹˜ ì•Šì€ EOF 발견" -#: commands/copy.c:4129 +#: commands/copy.c:4446 #, c-format msgid "invalid field size" msgstr "ìž˜ëª»ëœ í•„ë“œ í¬ê¸°" -#: commands/copy.c:4152 +#: commands/copy.c:4469 #, c-format msgid "incorrect binary data format" msgstr "ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ ìžë£Œ í¬ë§·" -#: commands/copy.c:4463 commands/indexcmds.c:1054 commands/tablecmds.c:1464 -#: commands/tablecmds.c:2291 parser/parse_relation.c:3177 -#: parser/parse_relation.c:3197 utils/adt/tsvector_op.c:2559 +#: commands/copy.c:4781 commands/indexcmds.c:1462 commands/statscmds.c:206 +#: commands/tablecmds.c:1897 commands/tablecmds.c:2413 +#: commands/tablecmds.c:2824 parser/parse_relation.c:3288 +#: parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" -msgstr "\"%s\" ì´ë¦„ì˜ ì—´ì´ ì—†ìŠµë‹ˆë‹¤" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì€ ì—†ìŠµë‹ˆë‹¤" -#: commands/copy.c:4470 commands/tablecmds.c:1490 commands/trigger.c:651 -#: parser/parse_target.c:967 parser/parse_target.c:978 +#: commands/copy.c:4788 commands/tablecmds.c:1923 commands/tablecmds.c:2439 +#: commands/trigger.c:913 parser/parse_target.c:1040 parser/parse_target.c:1051 #, c-format msgid "column \"%s\" specified more than once" -msgstr "\"%s\" ì—´ì„ í•˜ë‚˜ ì´ìƒ 지정했ìŒ" +msgstr "\"%s\" ì¹¼ëŸ¼ì„ í•˜ë‚˜ ì´ìƒ 지정했ìŒ" #: commands/createas.c:213 commands/createas.c:509 #, c-format @@ -6363,258 +6115,236 @@ msgstr "너무 ë§Žì€ ì¹¼ëŸ¼ ì´ë¦„ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤." msgid "policies not yet implemented for this command" msgstr "ì´ ëª…ë ¹ì„ ìœ„í•œ ì •ì±…ì€ ì•„ì§ êµ¬í˜„ë˜ì–´ 있지 않습니다" -#: commands/dbcommands.c:226 +#: commands/dbcommands.c:235 #, c-format msgid "LOCATION is not supported anymore" msgstr "LOCATION 예약어는 ì´ì œ ë”ì´ìƒ ì§€ì›í•˜ì§€ 않습니다" -#: commands/dbcommands.c:227 +#: commands/dbcommands.c:236 #, c-format msgid "Consider using tablespaces instead." msgstr "ëŒ€ì‹ ì— í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ ì´ìš©í•˜ì„¸ìš”." -#: commands/dbcommands.c:251 utils/adt/ascii.c:144 +#: commands/dbcommands.c:262 utils/adt/ascii.c:145 #, c-format msgid "%d is not a valid encoding code" msgstr "%d ê°’ì€ ìž˜ëª»ëœ ì¸ì½”딩 코드임" -#: commands/dbcommands.c:261 utils/adt/ascii.c:126 +#: commands/dbcommands.c:273 utils/adt/ascii.c:127 #, c-format msgid "%s is not a valid encoding name" msgstr "%s ì´ë¦„ì€ ìž˜ëª»ëœ ì¸ì½”딩 ì´ë¦„ìž„" -#: commands/dbcommands.c:279 commands/dbcommands.c:1458 commands/user.c:272 -#: commands/user.c:650 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 +#: commands/user.c:664 #, c-format msgid "invalid connection limit: %d" msgstr "ìž˜ëª»ëœ ì—°ê²° 제한: %d" -#: commands/dbcommands.c:298 +#: commands/dbcommands.c:311 #, c-format msgid "permission denied to create database" msgstr "ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 만들 ê¶Œí•œì´ ì—†ìŒ" -#: commands/dbcommands.c:321 +#: commands/dbcommands.c:334 #, c-format msgid "template database \"%s\" does not exist" msgstr "\"%s\" 템플릿 ë°ì´í„°ë² ì´ìФ ì—†ìŒ" -#: commands/dbcommands.c:333 +#: commands/dbcommands.c:346 #, c-format msgid "permission denied to copy database \"%s\"" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 복사할 ê¶Œí•œì´ ì—†ìŒ" -#: commands/dbcommands.c:349 +#: commands/dbcommands.c:362 #, c-format msgid "invalid server encoding %d" msgstr "ìž˜ëª»ëœ ì„œë²„ ì¸ì½”딩 %d" -#: commands/dbcommands.c:355 commands/dbcommands.c:360 +#: commands/dbcommands.c:368 commands/dbcommands.c:373 #, c-format msgid "invalid locale name: \"%s\"" msgstr "\"%s\" ë¡œì¼€ì¼ ì´ë¦„ì´ ìž˜ëª»ë¨" -#: commands/dbcommands.c:380 +#: commands/dbcommands.c:393 #, c-format -msgid "" -"new encoding (%s) is incompatible with the encoding of the template database " -"(%s)" +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" msgstr "새 ì¸ì½”딩(%s)ì´ í…œí”Œë¦¿ ë°ì´í„°ë² ì´ìŠ¤ì˜ ì¸ì½”딩(%s)ê³¼ 호환ë˜ì§€ 않ìŒ" -#: commands/dbcommands.c:383 +#: commands/dbcommands.c:396 #, c-format -msgid "" -"Use the same encoding as in the template database, or use template0 as " -"template." -msgstr "" -"템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ ì¸ì½”ë”©ì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿ìœ¼ë¡œ 사용" -"하십시오." +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ ì¸ì½”ë”©ì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿ìœ¼ë¡œ 사용하십시오." -#: commands/dbcommands.c:388 +#: commands/dbcommands.c:401 #, c-format -msgid "" -"new collation (%s) is incompatible with the collation of the template " -"database (%s)" -msgstr "" -"새 ë°ì´í„° ì •ë ¬ 규칙 (%s)ì´ í…œí”Œë¦¿ ë°ì´í„°ë² ì´ìŠ¤ì˜ ë°ì´í„° ì •ë ¬ 규칙(%s)ê³¼ 호환" -"ë˜ì§€ 않ìŒ" +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "새 ë°ì´í„° ì •ë ¬ 규칙 (%s)ì´ í…œí”Œë¦¿ ë°ì´í„°ë² ì´ìŠ¤ì˜ ë°ì´í„° ì •ë ¬ 규칙(%s)ê³¼ 호환ë˜ì§€ 않ìŒ" -#: commands/dbcommands.c:390 +#: commands/dbcommands.c:403 #, c-format -msgid "" -"Use the same collation as in the template database, or use template0 as " -"template." -msgstr "" -"템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ ë°ì´í„° ì •ë ¬ ê·œì¹™ì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿" -"으로 사용하십시오." +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ ë°ì´í„° ì •ë ¬ ê·œì¹™ì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿ìœ¼ë¡œ 사용하십시오." -#: commands/dbcommands.c:395 +#: commands/dbcommands.c:408 #, c-format -msgid "" -"new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database " -"(%s)" +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" msgstr "새 LC_CTYPE (%s)ì´ í…œí”Œë¦¿ ë°ì´í„°ë² ì´ìŠ¤ì˜ LC_CTYPE (%s)ê³¼ 호환ë˜ì§€ 않ìŒ" -#: commands/dbcommands.c:397 +#: commands/dbcommands.c:410 #, c-format -msgid "" -"Use the same LC_CTYPE as in the template database, or use template0 as " -"template." -msgstr "" -"템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ LC_CTYPEì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿ìœ¼ë¡œ 사" -"용하십시오." +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "템플릿 ë°ì´í„°ë² ì´ìŠ¤ì™€ ë™ì¼í•œ LC_CTYPEì„ ì‚¬ìš©í•˜ê±°ë‚˜ template0ì„ í…œí”Œë¦¿ìœ¼ë¡œ 사용하십시오." -#: commands/dbcommands.c:419 commands/dbcommands.c:1113 +#: commands/dbcommands.c:432 commands/dbcommands.c:1146 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "pg_globalì„ ê¸°ë³¸ í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 사용할 수 ì—†ìŒ" -#: commands/dbcommands.c:445 +#: commands/dbcommands.c:458 #, c-format msgid "cannot assign new default tablespace \"%s\"" msgstr "새 \"%s\" í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 지정할 수 없습니다." -#: commands/dbcommands.c:447 +#: commands/dbcommands.c:460 #, c-format -msgid "" -"There is a conflict because database \"%s\" already has some tables in this " -"tablespace." -msgstr "" -"\"%s\" ë°ì´í„°ë² ì´ìФ ì†Œì† ëª‡ëª‡ í…Œì´ë¸”ë“¤ì´ ì´ í…Œì´ë¸”스페ì´ìŠ¤ì•ˆì— ìžˆì–´ì„œ ì¶©ëŒì´ " -"ì¼ì–´ë‚©ë‹ˆë‹¤." +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ ì†Œì† ëª‡ëª‡ í…Œì´ë¸”ë“¤ì´ ì´ í…Œì´ë¸”스페ì´ìŠ¤ì•ˆì— ìžˆì–´ì„œ ì¶©ëŒì´ ì¼ì–´ë‚©ë‹ˆë‹¤." -#: commands/dbcommands.c:467 commands/dbcommands.c:982 +#: commands/dbcommands.c:480 commands/dbcommands.c:1016 #, c-format msgid "database \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ë°ì´í„°ë² ì´ìŠ¤ëŠ” ì´ë¯¸ 있ìŒ" -#: commands/dbcommands.c:481 +#: commands/dbcommands.c:494 #, c-format msgid "source database \"%s\" is being accessed by other users" msgstr "\"%s\" ì›ë³¸ ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 다른 사용ìžê°€ 액세스하기 시작했습니다" -#: commands/dbcommands.c:726 commands/dbcommands.c:741 +#: commands/dbcommands.c:736 commands/dbcommands.c:751 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "\"%s\" ì¸ì½”ë”©ì€ \"%s\" 로케ì¼ê³¼ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: commands/dbcommands.c:729 +#: commands/dbcommands.c:739 #, c-format msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." msgstr "ì„ íƒí•œ LC_CTYPE 설정ì—는 \"%s\" ì¸ì½”ë”©ì´ í•„ìš”í•©ë‹ˆë‹¤." -#: commands/dbcommands.c:744 +#: commands/dbcommands.c:754 #, c-format msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." msgstr "ì„ íƒí•œ LC_COLLATE 설정ì—는 \"%s\" ì¸ì½”ë”©ì´ í•„ìš”í•©ë‹ˆë‹¤." -#: commands/dbcommands.c:804 +#: commands/dbcommands.c:815 #, c-format msgid "database \"%s\" does not exist, skipping" msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ ì—†ìŒ, 건너 뜀" -#: commands/dbcommands.c:828 +#: commands/dbcommands.c:839 #, c-format msgid "cannot drop a template database" msgstr "템플릿 ë°ì´í„°ë² ì´ìŠ¤ëŠ” 삭제할 수 없습니다" -#: commands/dbcommands.c:834 +#: commands/dbcommands.c:845 #, c-format msgid "cannot drop the currently open database" msgstr "현재 ì—´ë ¤ 있는 ë°ì´í„°ë² ì´ìŠ¤ëŠ” 삭제할 수 없습니다" -#: commands/dbcommands.c:844 +#: commands/dbcommands.c:858 #, c-format -msgid "database \"%s\" is used by a logical replication slot" -msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ê°€ 논리 복제 슬롯ì—ì˜í•´ 사용ë˜ì—ˆìŒ" +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” 논리 복제 ìŠ¬ë¡¯ì´ í™œì„±í™” ë˜ì–´ 있습니다" -#: commands/dbcommands.c:846 +#: commands/dbcommands.c:860 #, c-format -msgid "There is %d slot, %d of them active." -msgid_plural "There are %d slots, %d of them active." -msgstr[0] "" +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d ê°œì˜ í™œì„± ìŠ¬ë¡¯ì´ ìžˆìŠµë‹ˆë‹¤." -#: commands/dbcommands.c:860 commands/dbcommands.c:1004 -#: commands/dbcommands.c:1135 +#: commands/dbcommands.c:874 commands/dbcommands.c:1038 +#: commands/dbcommands.c:1168 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 다른 사용ìžê°€ 액세스하기 시작했습니다" -#: commands/dbcommands.c:973 +#: commands/dbcommands.c:887 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ê°€ 논리 복제 구ë…으로 사용ë˜ì—ˆìŒ" + +#: commands/dbcommands.c:889 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d ê°œì˜ êµ¬ë…ì´ ìžˆìŠµë‹ˆë‹¤." + +#: commands/dbcommands.c:1007 #, c-format msgid "permission denied to rename database" msgstr "ë°ì´í„°ë² ì´ìФ ì´ë¦„ì„ ë°”ê¿€ ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/dbcommands.c:993 +#: commands/dbcommands.c:1027 #, c-format msgid "current database cannot be renamed" msgstr "현재 ë°ì´í„°ë² ì´ìŠ¤ì˜ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ" -#: commands/dbcommands.c:1091 +#: commands/dbcommands.c:1124 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "현재 ì—´ë ¤ 있는 ë°ì´í„°ë² ì´ìŠ¤ì˜ í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 바꿀 수 ì—†ìŒ" -#: commands/dbcommands.c:1194 +#: commands/dbcommands.c:1227 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" -msgstr "" -"\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì˜ ì¼ë¶€ 릴레ì´ì…˜ë“¤ì´ \"%s\" í…Œì´ë¸”스페ì´ìŠ¤ì— ì´ë¯¸ 있ìŒ" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì˜ ì¼ë¶€ 릴레ì´ì…˜ë“¤ì´ \"%s\" í…Œì´ë¸”스페ì´ìŠ¤ì— ì´ë¯¸ 있ìŒ" -#: commands/dbcommands.c:1196 +#: commands/dbcommands.c:1229 #, c-format -msgid "" -"You must move them back to the database's default tablespace before using " -"this command." -msgstr "" -"ì´ ëª…ë ¹ì„ ì‚¬ìš©í•˜ê¸° ì „ì— ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 다시 ì´ë™í•´ì•¼ í•©" -"니다." +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "ì´ ëª…ë ¹ì„ ì‚¬ìš©í•˜ê¸° ì „ì— ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 다시 ì´ë™í•´ì•¼ 합니다." -#: commands/dbcommands.c:1325 commands/dbcommands.c:1868 -#: commands/dbcommands.c:2072 commands/dbcommands.c:2120 +#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 +#: commands/dbcommands.c:2104 commands/dbcommands.c:2159 #: commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" -msgstr "" -"불필요한 ì¼ë¶€ 파ì¼ì´ ì´ì „ ë°ì´í„°ë² ì´ìФ 디렉터리 \"%s\"ì— ë‚¨ì•„ ìžˆì„ ìˆ˜ 있ìŒ" +msgstr "불필요한 ì¼ë¶€ 파ì¼ì´ ì´ì „ ë°ì´í„°ë² ì´ìФ 디렉터리 \"%s\"ì— ë‚¨ì•„ ìžˆì„ ìˆ˜ 있ìŒ" -#: commands/dbcommands.c:1440 +#: commands/dbcommands.c:1475 #, c-format msgid "option \"%s\" cannot be specified with other options" msgstr "\"%s\" ì˜µì…˜ì€ ë‹¤ë¥¸ 옵션들과 함께 사용할 수 없습니다." -#: commands/dbcommands.c:1494 +#: commands/dbcommands.c:1530 #, c-format msgid "cannot disallow connections for current database" msgstr "현재 ë°ì´í„°ë² ì´ìФ ì—°ê²°ì„ í—ˆìš©í•˜ì§€ 않습니다." -#: commands/dbcommands.c:1634 +#: commands/dbcommands.c:1667 #, c-format msgid "permission denied to change owner of database" msgstr "ë°ì´í„°ë² ì´ìФ 소유주를 바꿀 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/dbcommands.c:1955 +#: commands/dbcommands.c:1987 #, c-format -msgid "" -"There are %d other session(s) and %d prepared transaction(s) using the " -"database." -msgstr "" -"ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 사용하는 %dê°œì˜ ë‹¤ë¥¸ 세션과 %dê°œì˜ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆìŠµë‹ˆë‹¤." +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 사용하는 %dê°œì˜ ë‹¤ë¥¸ 세션과 %dê°œì˜ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆìŠµë‹ˆë‹¤." -#: commands/dbcommands.c:1958 +#: commands/dbcommands.c:1990 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 사용하는 %dê°œì˜ ë‹¤ë¥¸ ì„¸ì…˜ì´ ìžˆìŠµë‹ˆë‹¤." -#: commands/dbcommands.c:1963 +#: commands/dbcommands.c:1995 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." msgstr[0] "ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 사용하는 %dê°œì˜ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆìŠµë‹ˆë‹¤." #: commands/define.c:54 commands/define.c:228 commands/define.c:260 -#: commands/define.c:288 +#: commands/define.c:288 commands/define.c:334 #, c-format msgid "%s requires a parameter" msgstr "%s 매개 변수를 필요로 함" @@ -6650,474 +6380,479 @@ msgstr "%sì˜ ì¸ìžëŠ” ìžë£Œí˜• ì´ë¦„ì´ì–´ì•¼í•©ë‹ˆë‹¤" msgid "invalid argument for %s: \"%s\"" msgstr "%sì˜ ìž˜ëª»ëœ ì¸ìž: \"%s\"" -#: commands/dropcmds.c:112 commands/functioncmds.c:1203 -#: utils/adt/ruleutils.c:2080 +#: commands/dropcmds.c:98 commands/functioncmds.c:1211 +#: utils/adt/ruleutils.c:2562 #, c-format msgid "\"%s\" is an aggregate function" msgstr "\"%s\" 함수는 집계 함수입니다" -#: commands/dropcmds.c:114 +#: commands/dropcmds.c:100 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "집계 함수는 DROP AGGREGATE 명령으로 삭제할 수 있습니다" -#: commands/dropcmds.c:165 commands/sequence.c:424 commands/tablecmds.c:2378 -#: commands/tablecmds.c:2529 commands/tablecmds.c:2571 -#: commands/tablecmds.c:11524 tcop/utility.c:1119 +#: commands/dropcmds.c:149 commands/sequence.c:441 commands/tablecmds.c:2908 +#: commands/tablecmds.c:3059 commands/tablecmds.c:3102 +#: commands/tablecmds.c:12876 tcop/utility.c:1160 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "\"%s\" 릴레ì´ì…˜ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:195 commands/dropcmds.c:296 commands/tablecmds.c:746 +#: commands/dropcmds.c:179 commands/dropcmds.c:278 commands/tablecmds.c:1019 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "\"%s\" 스키마(schema) ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:237 commands/dropcmds.c:276 commands/tablecmds.c:247 +#: commands/dropcmds.c:219 commands/dropcmds.c:258 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "\"%s\" ìžë£Œí˜• ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:266 +#: commands/dropcmds.c:248 #, c-format msgid "access method \"%s\" does not exist, skipping" msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ 방법 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:284 +#: commands/dropcmds.c:266 #, c-format msgid "collation \"%s\" does not exist, skipping" msgstr "\"%s\" 정렬규칙 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:291 +#: commands/dropcmds.c:273 #, c-format msgid "conversion \"%s\" does not exist, skipping" msgstr "\"%s\" 문ìžì½”드변환규칙(conversion) ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:302 +#: commands/dropcmds.c:284 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "\"%s\" 통계정보 개체 ì—†ìŒ, 무시함" + +#: commands/dropcmds.c:291 #, c-format msgid "text search parser \"%s\" does not exist, skipping" msgstr "\"%s\" 전문 검색 파서가 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:309 +#: commands/dropcmds.c:298 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" msgstr "\"%s\" 전문 검색 ì‚¬ì „ì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:316 +#: commands/dropcmds.c:305 #, c-format msgid "text search template \"%s\" does not exist, skipping" msgstr "\"%s\" 전문 검색 í…œí”Œë¦¿ì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:323 +#: commands/dropcmds.c:312 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" msgstr "\"%s\" 전문 검색 êµ¬ì„±ì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:328 +#: commands/dropcmds.c:317 #, c-format msgid "extension \"%s\" does not exist, skipping" msgstr "\"%s\" 확장 모듈 ì—†ìŒ, 건너 뜀" -#: commands/dropcmds.c:335 +#: commands/dropcmds.c:327 #, c-format msgid "function %s(%s) does not exist, skipping" msgstr "%s(%s) 함수가 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:344 +#: commands/dropcmds.c:340 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "%s(%s) 프로시져 ì—†ìŒ, 건너뜀" + +#: commands/dropcmds.c:353 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "%s(%s) 루틴 ì—†ìŒ, 건너뜀" + +#: commands/dropcmds.c:366 #, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "%s(%s) 집계 함수 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:353 +#: commands/dropcmds.c:379 #, c-format msgid "operator %s does not exist, skipping" msgstr "%s ì—°ì‚°ìžê°€ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:358 +#: commands/dropcmds.c:385 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "\"%s\" 프로시주얼 언어 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:367 +#: commands/dropcmds.c:394 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "%s 형ì—서 %s 형으로 바꾸는 형변환 규칙(cast)ì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:376 +#: commands/dropcmds.c:403 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "%s í˜•ë³€í™˜ìž (사용언어 \"%s\") ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:384 +#: commands/dropcmds.c:411 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr " \"%s\" 트리거가 \"%s\" 릴레ì´ì…˜ì— ì§€ì •ëœ ê²ƒì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:393 +#: commands/dropcmds.c:420 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr " \"%s\" ì •ì±…ì´ \"%s\" 릴레ì´ì…˜ì— ì§€ì •ëœ ê²ƒì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:400 +#: commands/dropcmds.c:427 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "\"%s\" ì´ë²¤íЏ 트리거 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:406 +#: commands/dropcmds.c:433 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr " \"%s\" 룰(rule)ì´ \"%s\" 릴레ì´ì…˜ì— ì§€ì •ëœ ê²ƒì´ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:413 +#: commands/dropcmds.c:440 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ê°€ ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:417 +#: commands/dropcmds.c:444 #, c-format msgid "server \"%s\" does not exist, skipping" msgstr "\"%s\" 서버가 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:426 +#: commands/dropcmds.c:453 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" -msgstr "" -"\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” \"%s\" ì¸ë±ìФ ì ‘ê·¼ 방법ì—서 사용할 수 ì—†ìŒ, 건너뜀" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” \"%s\" ì¸ë±ìФ ì ‘ê·¼ 방법ì—서 사용할 수 ì—†ìŒ, 건너뜀" -#: commands/dropcmds.c:438 +#: commands/dropcmds.c:465 #, c-format -msgid "" -"operator family \"%s\" does not exist for access method \"%s\", skipping" +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(\"%s\" ì ‘ê·¼ 방법)ê°€ ì—†ìŒ, 건너뜀" -#: commands/event_trigger.c:182 +#: commands/dropcmds.c:472 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "\"%s\" 발행 ì—†ìŒ, 건너뜀" + +#: commands/event_trigger.c:187 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "\"%s\" ì´ë²¤íЏ 트리거를 만들 ê¶Œí•œì´ ì—†ìŒ" -#: commands/event_trigger.c:184 +#: commands/event_trigger.c:189 #, c-format msgid "Must be superuser to create an event trigger." msgstr "슈í¼ìœ ì €ë§Œ ì´ë²¤íЏ 트리거를 만들 수 있습니다." -#: commands/event_trigger.c:193 +#: commands/event_trigger.c:198 #, c-format msgid "unrecognized event name \"%s\"" msgstr "알 수 없는 ì´ë²¤íЏ ì´ë¦„: \"%s\"" -#: commands/event_trigger.c:210 +#: commands/event_trigger.c:215 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "알 수 없는 í•„í„° 변수: \"%s\"" -#: commands/event_trigger.c:265 +#: commands/event_trigger.c:270 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "\"%s\" í•„í„°ê°’ì€ \"%s\" í•„í„° 변수으로 쓸 수 ì—†ìŒ" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:271 commands/event_trigger.c:341 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format msgid "event triggers are not supported for %s" msgstr "%s ìš© ì´ë²¤íЏ 트리거는 ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/event_trigger.c:364 +#: commands/event_trigger.c:369 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "\"%s\" í•„í„° 변수가 한 번 ì´ìƒ 사용ë˜ì—ˆìŠµë‹ˆë‹¤." -#: commands/event_trigger.c:512 commands/event_trigger.c:556 -#: commands/event_trigger.c:649 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 +#: commands/event_trigger.c:651 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "\"%s\" ì´ë²¤íЏ 트리거 ì—†ìŒ" -#: commands/event_trigger.c:617 +#: commands/event_trigger.c:620 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "\"%s\" ì´ë²¤íЏ 트리거 소유주를 변경할 ê¶Œí•œì´ ì—†ìŒ" -#: commands/event_trigger.c:619 +#: commands/event_trigger.c:622 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "ì´ë²¤íЏ 트리거 소유주는 슈í¼ìœ ì €ì—¬ì•¼ 합니다." -#: commands/event_trigger.c:1438 +#: commands/event_trigger.c:1457 #, c-format msgid "%s can only be called in a sql_drop event trigger function" -msgstr "%s ê°ì²´ëŠ” sql_drop ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." +msgstr "%s 개체는 sql_drop ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." -#: commands/event_trigger.c:1558 commands/event_trigger.c:1579 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" -msgstr "" -"%s ê°ì²´ëŠ” table_rewrite ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." +msgstr "%s 개체는 table_rewrite ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." -#: commands/event_trigger.c:1989 +#: commands/event_trigger.c:2008 #, c-format msgid "%s can only be called in an event trigger function" -msgstr "%s ê°ì²´ëŠ” ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." +msgstr "%s 개체는 ì´ë²¤íЏ 트리거 함수 안ì—서만 호출 ë˜ì–´ì•¼ 합니다." -#: commands/explain.c:185 +#: commands/explain.c:192 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "\"%s\" EXPLAIN 옵션ì—서 쓸 수 없는 ê°’: \"%s\"" -#: commands/explain.c:191 +#: commands/explain.c:199 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "ìž˜ëª»ëœ EXPLAIN 옵션: \"%s\"" -#: commands/explain.c:198 +#: commands/explain.c:207 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "BUFFERS ì˜µì…˜ì€ EXPLAIN ANALYZEì—서만 쓸 수 있습니다." -#: commands/explain.c:207 +#: commands/explain.c:216 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "TIMING ì˜µì…˜ì€ EXPLAIN ANALYZEì—서만 쓸 수 있습니다." -#: commands/extension.c:155 commands/extension.c:2719 +#: commands/extension.c:168 commands/extension.c:2907 #, c-format msgid "extension \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ í™•ìž¥ ëª¨ë“ˆì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/extension.c:254 commands/extension.c:263 commands/extension.c:275 -#: commands/extension.c:285 +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 +#: commands/extension.c:298 #, c-format msgid "invalid extension name: \"%s\"" msgstr "ìž˜ëª»ëœ í™•ìž¥ 모듈 ì´ë¦„: \"%s\"" -#: commands/extension.c:255 +#: commands/extension.c:268 #, c-format msgid "Extension names must not be empty." msgstr "확장 모듈 ì´ë¦„ì„ ì§€ì •í•˜ì„¸ìš”." -#: commands/extension.c:264 +#: commands/extension.c:277 #, c-format msgid "Extension names must not contain \"--\"." msgstr "확장 모듈 ì´ë¦„ì— \"--\" 문ìžê°€ í¬í•¨ë  수 없습니다." -#: commands/extension.c:276 +#: commands/extension.c:289 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "확장 모듈 ì´ë¦„ì˜ ì‹œìž‘ê³¼ ëì—는 \"-\" 문ìžë¥¼ 사용할 수 없습니다." -#: commands/extension.c:286 +#: commands/extension.c:299 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "확장 모듈 ì´ë¦„ì—는 디렉터리 구분 문ìžë¥¼ 사용할 수 없습니다." -#: commands/extension.c:301 commands/extension.c:310 commands/extension.c:319 -#: commands/extension.c:329 +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 +#: commands/extension.c:342 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "ìž˜ëª»ëœ í™•ìž¥ 모듈 버전 ì´ë¦„: \"%s\"" -#: commands/extension.c:302 +#: commands/extension.c:315 #, c-format msgid "Version names must not be empty." msgstr "버전 ì´ë¦„ì€ ë¹„ì–´ìžˆìœ¼ë©´ 안ë©ë‹ˆë‹¤" -#: commands/extension.c:311 +#: commands/extension.c:324 #, c-format msgid "Version names must not contain \"--\"." msgstr "버전 ì´ë¦„ì— \"--\" 문ìžê°€ í¬í•¨ë  수 없습니다." -#: commands/extension.c:320 +#: commands/extension.c:333 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "버전 ì´ë¦„ì˜ ì•ž ë’¤ì— \"-\" 문ìžë¥¼ 쓸 수 없습니다." -#: commands/extension.c:330 +#: commands/extension.c:343 #, c-format msgid "Version names must not contain directory separator characters." msgstr "버전 ì´ë¦„ì—는 디렉터리 분리 문ìžë¥¼ 쓸 수 없습니다." -#: commands/extension.c:480 +#: commands/extension.c:493 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "\"%s\" 확장 모듈 제어 íŒŒì¼ ì—´ê¸° 실패: %m" -#: commands/extension.c:502 commands/extension.c:512 +#: commands/extension.c:515 commands/extension.c:525 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "\"%s\" 매개 변수는 ì´ì°¨ 확장 모듈 제어 파ì¼ì—서는 사용할 수 없습니다." -#: commands/extension.c:551 +#: commands/extension.c:564 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "\"%s\" ì´ë¦„ì€ ìž˜ëª»ëœ ì¸ì½”딩 ì´ë¦„ìž„" -#: commands/extension.c:565 +#: commands/extension.c:578 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "\"%s\" 매개 변수는 확장 모듈 ì´ë¦„ 목ë¡ì´ì–´ì•¼ 함" -#: commands/extension.c:572 +#: commands/extension.c:585 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "알 수 없는 \"%s\" 매개 변수가 \"%s\" íŒŒì¼ ì•ˆì— ìžˆìŠµë‹ˆë‹¤." -#: commands/extension.c:581 +#: commands/extension.c:594 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" -msgstr "" -"\"relocatable\" ê°’ì´ true ì¸ ê²½ìš° \"schema\" 매개 변수는 사용할 수 없습니다." +msgstr "\"relocatable\" ê°’ì´ true ì¸ ê²½ìš° \"schema\" 매개 변수는 사용할 수 없습니다." -#: commands/extension.c:722 +#: commands/extension.c:761 #, c-format -msgid "" -"transaction control statements are not allowed within an extension script" +msgid "transaction control statements are not allowed within an extension script" msgstr "확장 모듈 스í¬ë¦½íЏ 안ì—서는 트랜잭션 제어 êµ¬ë¬¸ì€ ì‚¬ìš©í•  수 없습니다." -#: commands/extension.c:790 +#: commands/extension.c:807 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "\"%s\" 확장 ëª¨ë“ˆì„ ë§Œë“¤ ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/extension.c:792 +#: commands/extension.c:809 #, c-format msgid "Must be superuser to create this extension." msgstr "확장 ëª¨ë“ˆì€ ìŠˆí¼ìœ ì €ë§Œ 만들 수 있습니다." -#: commands/extension.c:796 +#: commands/extension.c:813 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "\"%s\" 확장 ëª¨ë“ˆì„ ì—…ë°ì´íŠ¸í•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤." -#: commands/extension.c:798 +#: commands/extension.c:815 #, c-format msgid "Must be superuser to update this extension." msgstr "슈í¼ìœ ì €ë§Œ 해당 ëª¨ë“ˆì„ ì—…ë°ì´íЏ í•  수 있습니다." -#: commands/extension.c:1080 +#: commands/extension.c:1097 #, c-format -msgid "" -"extension \"%s\" has no update path from version \"%s\" to version \"%s\"" -msgstr "" -"\"%s\" 확장 ëª¨ë“ˆì„ \"%s\" 버전ì—서 \"%s\" 버전으로 ì—…ë°ì´íŠ¸í•  ë°©ë²•ì´ ì—†ìŠµë‹ˆ" -"다." +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "\"%s\" 확장 ëª¨ë“ˆì„ \"%s\" 버전ì—서 \"%s\" 버전으로 ì—…ë°ì´íŠ¸í•  ë°©ë²•ì´ ì—†ìŠµë‹ˆë‹¤." -#: commands/extension.c:1262 commands/extension.c:2779 +#: commands/extension.c:1304 commands/extension.c:2968 #, c-format msgid "version to install must be specified" msgstr "설치할 ë²„ì „ì„ ì§€ì •í•´ì•¼ 합니다." -#: commands/extension.c:1279 +#: commands/extension.c:1326 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "FROM ì ˆì— ì§€ì •í•œ ë²„ì „ì€ ì„¤ì¹˜ëœ \"%s\" 버전과 달ë¼ì•¼ 합니다" -#: commands/extension.c:1344 +#: commands/extension.c:1391 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "\"%s\" 확장 모듈ì—는 \"%s\" 버전용 설치나 ì—…ë°ì´íЏ 스í¬ë¦½íŠ¸ê°€ 없습니다." + +#: commands/extension.c:1426 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "\"%s\" 확장 ëª¨ë“ˆì€ \"%s\" 스키마 ì•ˆì— ì„¤ì¹˜ë˜ì–´ì•¼ 합니다." -#: commands/extension.c:1436 +#: commands/extension.c:1579 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "\"%s\" 확장 모듈과 \"%s\" 확장 ëª¨ë“ˆì´ ì„œë¡œ ì˜ì¡´ 관계입니다" -#: commands/extension.c:1441 +#: commands/extension.c:1584 #, c-format msgid "installing required extension \"%s\"" msgstr "\"%s\" 확장 ëª¨ë“ˆì´ í•„ìš”í•´ì„œ 실치 하는 중" -#: commands/extension.c:1469 commands/extension.c:2924 +#: commands/extension.c:1608 #, c-format msgid "required extension \"%s\" is not installed" msgstr "\"%s\" 확장 ëª¨ë“ˆì´ í•„ìš”í•œë°, 설치ë˜ì–´ 있지 않습니다." -#: commands/extension.c:1471 +#: commands/extension.c:1611 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." -msgstr "" -"필요한 ëª¨ë“ˆì„ í•¨ê»˜ 설치하려면, CREATE EXTENSION ... CASCADE êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸" -"ìš”." +msgstr "필요한 ëª¨ë“ˆì„ í•¨ê»˜ 설치하려면, CREATE EXTENSION ... CASCADE êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/extension.c:1535 +#: commands/extension.c:1648 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "\"%s\" 확장 ëª¨ë“ˆì´ ì´ë¯¸ 있ìŒ, 건너뜀" -#: commands/extension.c:1542 +#: commands/extension.c:1655 #, c-format msgid "extension \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ í™•ìž¥ ëª¨ë“ˆì´ ì´ë¯¸ 있습니다" -#: commands/extension.c:1553 +#: commands/extension.c:1666 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "ì¤‘ì²©ëœ CREATE EXTENSION êµ¬ë¬¸ì€ ì§€ì›í•˜ì§€ 않습니다." -#: commands/extension.c:1681 +#: commands/extension.c:1847 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" -msgstr "%s ì˜ì¡´ê°ì²´ë“¤ì€ 시스템 ê°ì²´ì´ê¸° ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ 없습니다" +msgstr "%s ì˜ì¡´ê°œì²´ë“¤ì€ 시스템 개체ì´ê¸° ë•Œë¬¸ì— ì‚­ì œ ë  ìˆ˜ 없습니다" -#: commands/extension.c:2152 +#: commands/extension.c:2349 #, c-format -msgid "" -"pg_extension_config_dump() can only be called from an SQL script executed by " -"CREATE EXTENSION" -msgstr "" -"pg_extension_config_dump() 함수는 CREATE EXTENSION 명령ì—서 ë‚´ë¶€ì ìœ¼ë¡œ 사용하" -"는 SQL 스í¬ë¦½íЏ ë‚´ì—서만 사용할 수 있습니다." +msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "pg_extension_config_dump() 함수는 CREATE EXTENSION 명령ì—서 ë‚´ë¶€ì ìœ¼ë¡œ 사용하는 SQL 스í¬ë¦½íЏ ë‚´ì—서만 사용할 수 있습니다." -#: commands/extension.c:2164 +#: commands/extension.c:2361 #, c-format msgid "OID %u does not refer to a table" msgstr "%u OID ìžë£Œê°€ í…Œì´ë¸”ì— ì—†ìŠµë‹ˆë‹¤" -#: commands/extension.c:2169 +#: commands/extension.c:2366 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "\"%s\" í…Œì´ë¸”ì€ ë§Œë“¤ë ¤ê³  하는 확장 ëª¨ë“ˆì˜ êµ¬ì„± 요소가 아닙니다." -#: commands/extension.c:2534 +#: commands/extension.c:2722 #, c-format -msgid "" -"cannot move extension \"%s\" into schema \"%s\" because the extension " -"contains the schema" +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "\"%s\" 확장 ëª¨ë“ˆì´ \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있어 옮길 수 없습니다." -#: commands/extension.c:2574 commands/extension.c:2637 +#: commands/extension.c:2763 commands/extension.c:2826 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "\"%s\" 확장 ëª¨ë“ˆì€ SET SCHEMA êµ¬ë¬¸ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/extension.c:2639 +#: commands/extension.c:2828 #, c-format msgid "%s is not in the extension's schema \"%s\"" -msgstr "%s ê°ì²´ê°€ 확장 모듈 ìŠ¤í‚¤ë§ˆì¸ \"%s\" ì•ˆì— ì—†ìŒ" +msgstr "%s 개체가 확장 모듈 ìŠ¤í‚¤ë§ˆì¸ \"%s\" ì•ˆì— ì—†ìŒ" -#: commands/extension.c:2699 +#: commands/extension.c:2887 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "ì¤‘ì²©ëœ ALTER EXTENSION êµ¬ë¬¸ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/extension.c:2790 +#: commands/extension.c:2979 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "\"%s\" ë²„ì „ì˜ \"%s\" 확장 ëª¨ë“ˆì´ ì´ë¯¸ 설치 ë˜ì–´ 있ìŒ" -#: commands/extension.c:3041 +#: commands/extension.c:3230 #, c-format -msgid "" -"cannot add schema \"%s\" to extension \"%s\" because the schema contains the " -"extension" -msgstr "" -"\"%s\" ìŠ¤í‚¤ë§ˆì— \"%s\" 확장 ëª¨ë“ˆì„ ì¶”ê°€í•  수 ì—†ìŒ, ì´ë¯¸ 해당 스키마 ì•ˆì— í¬" -"함ë˜ì–´ 있ìŒ" +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "\"%s\" ìŠ¤í‚¤ë§ˆì— \"%s\" 확장 ëª¨ë“ˆì„ ì¶”ê°€í•  수 ì—†ìŒ, ì´ë¯¸ 해당 스키마 ì•ˆì— í¬í•¨ë˜ì–´ 있ìŒ" -#: commands/extension.c:3069 +#: commands/extension.c:3258 #, c-format msgid "%s is not a member of extension \"%s\"" -msgstr "\"%s\" ê°ì²´ëŠ” \"%s\" 확장 ëª¨ë“ˆì˜ êµ¬ì„± 요소가 아닙니다" +msgstr "\"%s\" 개체는 \"%s\" 확장 ëª¨ë“ˆì˜ êµ¬ì„± 요소가 아닙니다" -#: commands/extension.c:3135 +#: commands/extension.c:3324 #, c-format msgid "file \"%s\" is too large" msgstr "\"%s\" 파ì¼ì´ 너무 í½ë‹ˆë‹¤." @@ -7147,838 +6882,901 @@ msgstr "슈í¼ìœ ì €ë§Œ 외부 ìžë£Œ 래í¼ì˜ 소유주를 바꿀 수 있습 msgid "The owner of a foreign-data wrapper must be a superuser." msgstr "외부 ìžë£Œ 래í¼ì˜ 소유주는 슈í¼ìœ ì €ì—¬ì•¼ 합니다." -#: commands/foreigncmds.c:292 commands/foreigncmds.c:709 foreign/foreign.c:671 +#: commands/foreigncmds.c:291 commands/foreigncmds.c:706 foreign/foreign.c:667 #, c-format msgid "foreign-data wrapper \"%s\" does not exist" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ê°€ ì—†ìŒ" -#: commands/foreigncmds.c:584 +#: commands/foreigncmds.c:582 #, c-format msgid "permission denied to create foreign-data wrapper \"%s\"" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ë¥¼ 만들 ê¶Œí•œì´ ì—†ìŒ" -#: commands/foreigncmds.c:586 +#: commands/foreigncmds.c:584 #, c-format msgid "Must be superuser to create a foreign-data wrapper." msgstr "슈í¼ìœ ì €ë§Œ 외부 ìžë£Œ 래í¼ë¥¼ 만들 수 있습니다." -#: commands/foreigncmds.c:699 +#: commands/foreigncmds.c:696 #, c-format msgid "permission denied to alter foreign-data wrapper \"%s\"" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ë¥¼ 변경할 ê¶Œí•œì´ ì—†ìŒ" -#: commands/foreigncmds.c:701 +#: commands/foreigncmds.c:698 #, c-format msgid "Must be superuser to alter a foreign-data wrapper." msgstr "슈í¼ìœ ì €ë§Œ 외부 ìžë£Œ 래í¼ë¥¼ 변경할 수 있습니다." -#: commands/foreigncmds.c:732 +#: commands/foreigncmds.c:729 #, c-format -msgid "" -"changing the foreign-data wrapper handler can change behavior of existing " -"foreign tables" -msgstr "" -"외부 ìžë£Œ ëž©í¼ í•¸ë“¤ëŸ¬ë¥¼ 바꾸면, ê·¸ê²ƒì„ ì‚¬ìš©í•˜ëŠ” 외부 í…Œì´ë¸”ì˜ ë‚´ìš©ì´ ë°”ë€” 수 " -"있습니다." +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "외부 ìžë£Œ ëž©í¼ í•¸ë“¤ëŸ¬ë¥¼ 바꾸면, ê·¸ê²ƒì„ ì‚¬ìš©í•˜ëŠ” 외부 í…Œì´ë¸”ì˜ ë‚´ìš©ì´ ë°”ë€” 수 있습니다." -#: commands/foreigncmds.c:747 +#: commands/foreigncmds.c:744 #, c-format -msgid "" -"changing the foreign-data wrapper validator can cause the options for " -"dependent objects to become invalid" -msgstr "" -"외부 ìžë£Œ ëž˜í¼ ìœ íš¨ì„± 검사기를 바꾸면 ì¢…ì† ê°ì²´ì— 대한 ì˜µì…˜ì´ ìœ íš¨í•˜ì§€ ì•Šì„ " -"수 있ìŒ" +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "외부 ìžë£Œ ëž˜í¼ ìœ íš¨ì„± 검사기를 바꾸면 ì¢…ì† ê°œì²´ì— ëŒ€í•œ ì˜µì…˜ì´ ìœ íš¨í•˜ì§€ ì•Šì„ ìˆ˜ 있ìŒ" + +#: commands/foreigncmds.c:890 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "\"%s\" ì´ë¦„ì˜ ì™¸ë¶€ 서버가 ì´ë¯¸ 있ìŒ, 건너뜀" + +#: commands/foreigncmds.c:1175 +#, c-format +msgid "user mapping for \"%s\" already exists for server %s, skipping" +msgstr "\"%s\" ì‚¬ìš©ìž ë§¤í•‘ì´ %s 서버용으로 ì´ë¯¸ 있ìŒ, 건너뜀" -#: commands/foreigncmds.c:1165 +#: commands/foreigncmds.c:1185 #, c-format -msgid "user mapping \"%s\" already exists for server %s" +msgid "user mapping for \"%s\" already exists for server %s" msgstr "\"%s\" ì‚¬ìš©ìž ë§¤í•‘ì´ %s 서버용으로 ì´ë¯¸ 있ìŒ" -#: commands/foreigncmds.c:1259 commands/foreigncmds.c:1375 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 #, c-format -msgid "user mapping \"%s\" does not exist for the server" +msgid "user mapping for \"%s\" does not exist for the server" msgstr "해당 서버용 \"%s\" ì‚¬ìš©ìž ë§¤í•‘ì´ ì—†ìŒ" -#: commands/foreigncmds.c:1362 +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" msgstr "서버가 ì—†ìŒ, 건너뜀" -#: commands/foreigncmds.c:1380 +#: commands/foreigncmds.c:1402 #, c-format -msgid "user mapping \"%s\" does not exist for the server, skipping" +msgid "user mapping for \"%s\" does not exist for the server, skipping" msgstr "\"%s\" ì‚¬ìš©ìž ë§¤í•‘ì´ í•´ë‹¹ 서버용으로 ì—†ìŒ, 건너뜀" -#: commands/foreigncmds.c:1532 foreign/foreign.c:361 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ìš© 핸들러가 ì—†ìŒ" -#: commands/foreigncmds.c:1538 +#: commands/foreigncmds.c:1559 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "\"%s\" 외부 ìžë£Œ 래í¼ëŠ” IMPORT FOREIGN SCHEMA êµ¬ë¬¸ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/foreigncmds.c:1631 +#: commands/foreigncmds.c:1662 #, c-format msgid "importing foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸” 가져 오는 중" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:103 #, c-format msgid "SQL function cannot return shell type %s" msgstr "SQL 함수는 shell type %s 리턴할 수 ì—†ìŒ" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:108 #, c-format msgid "return type %s is only a shell" msgstr "_^_ %s 리턴 ìžë£Œí˜•ì€ í•˜ë‚˜ì˜ shellë§Œ 있습니다" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:138 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "\"%s\" ì…¸ 형ì‹ì— 대해 í˜•ì‹ í•œì •ìžë¥¼ 지정할 수 ì—†ìŒ" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:144 #, c-format msgid "type \"%s\" is not yet defined" msgstr "\"%s\" ìžë£Œí˜•ì´ ì•„ì§ ì •ì˜ë˜ì§€ 않았ìŒ" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:145 #, c-format msgid "Creating a shell type definition." msgstr "ì…¸ 타입 ì •ì˜ë¥¼ 만들고 있습니다" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:237 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "SQL 함수는 ì…¸ 타입 %s 수용할 수 ì—†ìŒ" -#: commands/functioncmds.c:245 +#: commands/functioncmds.c:243 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "집계 함수는 ì…¸ 타입 %s 수용할 수 ì—†ìŒ" -#: commands/functioncmds.c:250 +#: commands/functioncmds.c:248 #, c-format msgid "argument type %s is only a shell" msgstr "%s ì¸ìž ìžë£Œí˜•ì€ ë‹¨ì§€ 셸입니다" -#: commands/functioncmds.c:260 +#: commands/functioncmds.c:258 #, c-format msgid "type %s does not exist" msgstr "%s ìžë£Œí˜• ì—†ìŒ" -#: commands/functioncmds.c:274 +#: commands/functioncmds.c:272 #, c-format msgid "aggregates cannot accept set arguments" msgstr "집계 함수는 세트 ì¸ìžë¥¼ ìž…ë ¥ ì¸ìžë¡œ 쓸 수 ì—†ìŒ" -#: commands/functioncmds.c:278 +#: commands/functioncmds.c:276 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "프로시져ì—서는 ì§‘í•© ì¸ìžë¥¼ ìž…ë ¥ ì¸ìžë¡œ 쓸 수 ì—†ìŒ" + +#: commands/functioncmds.c:280 #, c-format msgid "functions cannot accept set arguments" -msgstr "함수는 세트 ì¸ìžë¥¼ ìž…ë ¥ ì¸ìžë¡œ 쓸 수 ì—†ìŒ" +msgstr "함수는 세트 ì¸ìžë¥¼ 쓸 수 ì—†ìŒ" #: commands/functioncmds.c:288 #, c-format +msgid "procedures cannot have OUT arguments" +msgstr "프로시저는 OUT ì¸ìžë¥¼ 쓸 수 ì—†ìŒ" + +#: commands/functioncmds.c:289 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT ì¸ìžê°€ 허용ë¨" + +#: commands/functioncmds.c:299 +#, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "VARIADIC 매개 변수는 마지막 ìž…ë ¥ 매개 변수여야 함" -#: commands/functioncmds.c:316 +#: commands/functioncmds.c:329 #, c-format msgid "VARIADIC parameter must be an array" msgstr "VARIADIC 매개 변수는 ë°°ì—´ì´ì–´ì•¼ 함" -#: commands/functioncmds.c:356 +#: commands/functioncmds.c:369 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "\"%s\" 매개 변수가 여러 번 사용 ë¨" -#: commands/functioncmds.c:371 +#: commands/functioncmds.c:384 #, c-format msgid "only input parameters can have default values" msgstr "ìž…ë ¥ 매개 변수ì—서만 ê¸°ë³¸ê°’ì„ ì‚¬ìš©í•  수 있ìŒ" -#: commands/functioncmds.c:386 +#: commands/functioncmds.c:399 #, c-format msgid "cannot use table references in parameter default value" msgstr "ìž…ë ¥ 매개 변수 초기값으로 í…Œì´ë¸” ì°¸ì¡°í˜•ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/functioncmds.c:410 +#: commands/functioncmds.c:423 #, c-format msgid "input parameters after one with a default value must also have defaults" -msgstr "" -"기본 ê°’ì´ ìžˆëŠ” ìž…ë ¥ 매개 변수 ë’¤ì— ì˜¤ëŠ” ìž…ë ¥ 매개 변수ì—ë„ ê¸°ë³¸ ê°’ì´ ìžˆì–´ì•¼ " -"함" +msgstr "기본 ê°’ì´ ìžˆëŠ” ìž…ë ¥ 매개 변수 ë’¤ì— ì˜¤ëŠ” ìž…ë ¥ 매개 변수ì—ë„ ê¸°ë³¸ ê°’ì´ ìžˆì–´ì•¼ 함" + +#: commands/functioncmds.c:565 commands/functioncmds.c:715 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "프로시져 ì •ì˜ì— ìž˜ëª»ëœ ì†ì„±ì´ 있ìŒ" -#: commands/functioncmds.c:701 +#: commands/functioncmds.c:746 #, c-format msgid "no function body specified" msgstr "함수 본문(body) ë¶€ë¶„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤" -#: commands/functioncmds.c:711 +#: commands/functioncmds.c:756 #, c-format msgid "no language specified" msgstr "처리할 프로시주얼 언어를 지정하지 않았습니다" -#: commands/functioncmds.c:736 commands/functioncmds.c:1243 +#: commands/functioncmds.c:781 commands/functioncmds.c:1255 #, c-format msgid "COST must be positive" msgstr "COST는 양수여야 함" -#: commands/functioncmds.c:744 commands/functioncmds.c:1251 +#: commands/functioncmds.c:789 commands/functioncmds.c:1263 #, c-format msgid "ROWS must be positive" msgstr "ROWS는 양수여야 함" -#: commands/functioncmds.c:785 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "알수 없는 함수 ì†ì„± \"%s\" 무시ë¨" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:841 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "\"%s\" 언어ì—는 í•˜ë‚˜ì˜ AS 항목만 필요함" -#: commands/functioncmds.c:929 commands/functioncmds.c:2119 -#: commands/proclang.c:563 +#: commands/functioncmds.c:936 commands/functioncmds.c:2138 +#: commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "\"%s\" 프로시주얼 언어 ì—†ìŒ" -#: commands/functioncmds.c:931 commands/functioncmds.c:2121 +#: commands/functioncmds.c:938 commands/functioncmds.c:2140 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "" -"ë°ì´í„°ë² ì´ìФ ë‚´ì—서 프로시주얼 언어를 사용하려면 먼저 CREATE LANGUAGE 명령으" -"로 사용할 언어를 등ë¡í•˜ì„¸ìš”." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "ë°ì´í„°ë² ì´ìФ ë‚´ì—서 프로시주얼 언어를 사용하려면 먼저 CREATE EXTENSION 명령으로 사용할 언어를 등ë¡í•˜ì„¸ìš”." -#: commands/functioncmds.c:966 commands/functioncmds.c:1235 +#: commands/functioncmds.c:973 commands/functioncmds.c:1247 #, c-format msgid "only superuser can define a leakproof function" msgstr "슈í¼ìœ ì €ë§Œ leakproof 함수를 만들 수 있습니다" -#: commands/functioncmds.c:1010 +#: commands/functioncmds.c:1022 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "OUT 매개 변수로 ì¸í•´ 함수 ê²°ê³¼ 형ì‹ì€ %sì´ì–´ì•¼ 함" -#: commands/functioncmds.c:1023 +#: commands/functioncmds.c:1035 #, c-format msgid "function result type must be specified" msgstr "í•¨ìˆ˜ì˜ ë¦¬í„´ ìžë£Œí˜•ì„ ì§€ì •í•´ì•¼ 합니다" -#: commands/functioncmds.c:1077 commands/functioncmds.c:1255 +#: commands/functioncmds.c:1087 commands/functioncmds.c:1267 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "함수ì—서 세트를 반환하지 않는 경우 ROWS를 ì ìš©í•  수 ì—†ìŒ" -#: commands/functioncmds.c:1412 +#: commands/functioncmds.c:1439 #, c-format msgid "source data type %s is a pseudo-type" msgstr "%s ì›ë³¸ ìžë£Œí˜•ì´ ì˜ì‚¬ìžë£Œí˜•(pseudo-type) 입니다" -#: commands/functioncmds.c:1418 +#: commands/functioncmds.c:1445 #, c-format msgid "target data type %s is a pseudo-type" msgstr "%s ëŒ€ìƒ ìžë£Œí˜•ì´ ì˜ì‚¬ìžë£Œí˜•(pseudo-type) 입니다" -#: commands/functioncmds.c:1442 +#: commands/functioncmds.c:1469 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "ì›ë³¸ ìžë£Œí˜•ì´ ë„ë©”ì¸ì´ì–´ì„œ ìžë£Œí˜• ë³€í™˜ì„ ë¬´ì‹œí•©ë‹ˆë‹¤." -#: commands/functioncmds.c:1447 +#: commands/functioncmds.c:1474 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "ëŒ€ìƒ ìžë£Œí˜•ì´ ë„ë©”ì¸ì´ì–´ì„œ ìžë£Œí˜• ë³€í™˜ì„ ë¬´ì‹œí•©ë‹ˆë‹¤." -#: commands/functioncmds.c:1474 +#: commands/functioncmds.c:1499 #, c-format msgid "cast function must take one to three arguments" msgstr "형변환 함수는 1-3ê°œì˜ ì¸ìžë§Œ 지정할 수 있습니다" -#: commands/functioncmds.c:1478 +#: commands/functioncmds.c:1503 #, c-format -msgid "" -"argument of cast function must match or be binary-coercible from source data " -"type" -msgstr "" -"형변환 í•¨ìˆ˜ì˜ ì¸ìžë¡œ 쓸 ìžë£Œí˜•ì€ ì›ë³¸ ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ê±°ë‚˜ ë°”ì´ë„ˆë¦¬ ì°¨ì›ìœ¼ë¡œ " -"ê°™ì€ ìžë£Œí˜•ì´ì–´ì•¼ 함" +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "형변환 í•¨ìˆ˜ì˜ ì¸ìžë¡œ 쓸 ìžë£Œí˜•ì€ ì›ë³¸ ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ê±°ë‚˜ ë°”ì´ë„ˆë¦¬ ì°¨ì›ìœ¼ë¡œ ê°™ì€ ìžë£Œí˜•ì´ì–´ì•¼ 함" -#: commands/functioncmds.c:1482 +#: commands/functioncmds.c:1507 #, c-format -msgid "second argument of cast function must be type integer" -msgstr "형변화 í•¨ìˆ˜ì˜ ë‘번째 ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ integer여야합니다" +msgid "second argument of cast function must be type %s" +msgstr "형변화 í•¨ìˆ˜ì˜ ë‘번째 ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ %s 형ì´ì—¬ì•¼í•©ë‹ˆë‹¤" -#: commands/functioncmds.c:1486 +#: commands/functioncmds.c:1512 #, c-format -msgid "third argument of cast function must be type boolean" -msgstr "형변화 í•¨ìˆ˜ì˜ ì„¸ë²ˆì§¸ ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ booleanì´ì—¬ì•¼í•©ë‹ˆë‹¤" +msgid "third argument of cast function must be type %s" +msgstr "형변화 í•¨ìˆ˜ì˜ ì„¸ë²ˆì§¸ ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ %s 형ì´ì—¬ì•¼í•©ë‹ˆë‹¤" -#: commands/functioncmds.c:1490 +#: commands/functioncmds.c:1517 #, c-format -msgid "" -"return data type of cast function must match or be binary-coercible to " -"target data type" -msgstr "" -"형변환 í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì€ ëŒ€ìƒ ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ê±°ë‚˜ ë°”ì´ë„ˆë¦¬ ì°¨ì›ìœ¼ë¡œ ê°™ì€ " -"ìžë£Œí˜•ì´ì–´ì•¼ 함" +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "형변환 í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì€ ëŒ€ìƒ ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ê±°ë‚˜ ë°”ì´ë„ˆë¦¬ ì°¨ì›ìœ¼ë¡œ ê°™ì€ ìžë£Œí˜•ì´ì–´ì•¼ 함" -#: commands/functioncmds.c:1501 +#: commands/functioncmds.c:1528 #, c-format msgid "cast function must not be volatile" msgstr "형변환 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/functioncmds.c:1506 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "형변환 함수는 집계 함수가 아니여야합니다" - -#: commands/functioncmds.c:1510 +#: commands/functioncmds.c:1533 #, c-format -msgid "cast function must not be a window function" -msgstr "형변환 함수는 윈ë„ìš° 함수가 아니여야 함" +msgid "cast function must be a normal function" +msgstr "형변환 함수는 ì¼ë°˜ 함수여야 합니다" -#: commands/functioncmds.c:1514 +#: commands/functioncmds.c:1537 #, c-format msgid "cast function must not return a set" msgstr "형변환 함수는 세트(set)를 리턴할 수 없습니다" -#: commands/functioncmds.c:1540 +#: commands/functioncmds.c:1563 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "CREATE CAST ... WITHOUT FUNCTION ëª…ë ¹ì€ ìŠˆí¼ìœ ì €ë§Œ 실행할 수 있습니다" -#: commands/functioncmds.c:1555 +#: commands/functioncmds.c:1578 #, c-format msgid "source and target data types are not physically compatible" msgstr "ì›ë³¸ ìžë£Œí˜•ê³¼ ëŒ€ìƒ ìžë£Œí˜•ì´ ì„œë¡œ 논리ì ì¸ í˜¸í™˜ì„±ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/functioncmds.c:1570 +#: commands/functioncmds.c:1593 #, c-format msgid "composite data types are not binary-compatible" msgstr "복합 ìžë£Œí˜•ì€ ë°”ì´ë„ˆë¦¬ì™€ 호환ë˜ì§€ 않ìŒ" -#: commands/functioncmds.c:1576 +#: commands/functioncmds.c:1599 #, c-format msgid "enum data types are not binary-compatible" msgstr "ì—´ê±° ìžë£Œí˜•ì€ ë°”ì´ë„ˆë¦¬ì™€ 호환ë˜ì§€ 않ìŒ" -#: commands/functioncmds.c:1582 +#: commands/functioncmds.c:1605 #, c-format msgid "array data types are not binary-compatible" msgstr "ë°°ì—´ ìžë£Œí˜•ì€ ë°”ì´ë„ˆë¦¬ì™€ 호환ë˜ì§€ 않ìŒ" -#: commands/functioncmds.c:1599 +#: commands/functioncmds.c:1622 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "ë„ë©”ì¸ ìžë£Œí˜•ì€ ë°”ì´ë„ˆë¦¬ì™€ 호환ë˜ì§€ 않ìŒ" -#: commands/functioncmds.c:1609 +#: commands/functioncmds.c:1632 #, c-format msgid "source data type and target data type are the same" msgstr "ì›ë³¸ ìžë£Œí˜•ê³¼ ëŒ€ìƒ ìžë£Œí˜•ì˜ í˜•íƒœê°€ 같습니다" -#: commands/functioncmds.c:1642 +#: commands/functioncmds.c:1665 #, c-format msgid "cast from type %s to type %s already exists" msgstr "%s 형ì—서 %s 형으로 변환하는 형변환 규칙(cast)ì´ ì´ë¯¸ 있습니다" -#: commands/functioncmds.c:1717 +#: commands/functioncmds.c:1738 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "%s 형ì—서 %s 형으로 바꾸는 형변환 규칙(cast)ê°€ ì—†ìŒ" -#: commands/functioncmds.c:1756 +#: commands/functioncmds.c:1777 #, c-format msgid "transform function must not be volatile" msgstr "형변환 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/functioncmds.c:1760 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "형변환 함수는 집계 함수가 아니여야합니다" - -#: commands/functioncmds.c:1764 +#: commands/functioncmds.c:1781 #, c-format -msgid "transform function must not be a window function" -msgstr "형변환 함수는 윈ë„ìš° 함수가 아니여야 함" +msgid "transform function must be a normal function" +msgstr "형변환 함수는 ì¼ë°˜ 함수여야합니다." -#: commands/functioncmds.c:1768 +#: commands/functioncmds.c:1785 #, c-format msgid "transform function must not return a set" msgstr "형변환 함수는 세트(set)를 리턴할 수 없습니다" -#: commands/functioncmds.c:1772 +#: commands/functioncmds.c:1789 #, c-format msgid "transform function must take one argument" msgstr "형변환 함수는 1ê°œì˜ ì¸ìžë§Œ 지정할 수 있습니다" -#: commands/functioncmds.c:1776 +#: commands/functioncmds.c:1793 #, c-format -msgid "first argument of transform function must be type \"internal\"" -msgstr "형변화 í•¨ìˆ˜ì˜ ì²«ë²ˆì§¸ ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ \"internal\"ì´ì—¬ì•¼í•©ë‹ˆë‹¤" +msgid "first argument of transform function must be type %s" +msgstr "형변화 í•¨ìˆ˜ì˜ ì²«ë²ˆì§¸ ì¸ìž ìžë£Œí˜•ì€ ë°˜ë“œì‹œ %s 형ì´ì—¬ì•¼í•©ë‹ˆë‹¤" -#: commands/functioncmds.c:1813 +#: commands/functioncmds.c:1831 #, c-format msgid "data type %s is a pseudo-type" msgstr "%s ìžë£Œí˜•ì€ ì˜ì‚¬ìžë£Œí˜•(pseudo-type) 입니다" -#: commands/functioncmds.c:1819 +#: commands/functioncmds.c:1837 #, c-format msgid "data type %s is a domain" msgstr "%s ìžë£Œí˜•ì€ ë„ë©”ì¸ìž…니다" -#: commands/functioncmds.c:1859 +#: commands/functioncmds.c:1877 #, c-format -msgid "return data type of FROM SQL function must be \"internal\"" -msgstr "FROM SQL í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì€ \"internal\" ì´ì–´ì•¼ 함" +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQL í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì€ %s 형ì´ì–´ì•¼ 함" -#: commands/functioncmds.c:1884 +#: commands/functioncmds.c:1903 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "TO SQL í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì€ ë³€í™˜ ìžë£Œí˜•ì´ì–´ì•¼ 함" -#: commands/functioncmds.c:1911 +#: commands/functioncmds.c:1930 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "%s ìžë£Œí˜•(ëŒ€ìƒ ì–¸ì–´: \"%s\")ì„ ìœ„í•œ 형변환 ê·œì¹™ì€ ì´ë¯¸ 있습니다." -#: commands/functioncmds.c:2002 +#: commands/functioncmds.c:2019 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "%s ìžë£Œí˜•(ëŒ€ìƒ ì–¸ì–´: \"%s\")ì„ ìœ„í•œ 형변환 ê·œì¹™ì€ ì—†ìŠµë‹ˆë‹¤." -#: commands/functioncmds.c:2053 +#: commands/functioncmds.c:2070 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "%s 함수는 ì´ë¯¸ \"%s\" ìŠ¤í‚¤ë§ˆì•ˆì— ìžˆìŠµë‹ˆë‹¤" -#: commands/functioncmds.c:2106 +#: commands/functioncmds.c:2125 #, c-format msgid "no inline code specified" msgstr "내장 코드가 빠졌습니다" -#: commands/functioncmds.c:2151 +#: commands/functioncmds.c:2171 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "\"%s\" 프로시주얼 언어는 내장 코드 실행 ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다" -#: commands/indexcmds.c:349 +#: commands/functioncmds.c:2269 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "í”„ë¡œì‹œì ¸ì— %dê°œì˜ ì¸ìž ì´ìƒì„ 전달할 수 ì—†ìŒ" + +#: commands/indexcmds.c:392 #, c-format msgid "must specify at least one column" -msgstr "ì ì–´ë„ 하나 ì´ìƒì˜ ì—´ì„ ì§€ì •í•´ 주십시오" +msgstr "ì ì–´ë„ 하나 ì´ìƒì˜ ì¹¼ëŸ¼ì„ ì§€ì •í•´ 주십시오" -#: commands/indexcmds.c:353 +#: commands/indexcmds.c:396 #, c-format msgid "cannot use more than %d columns in an index" -msgstr "í•˜ë‚˜ì˜ ì¸ë±ìФì—서는 %d개보다 ë§Žì€ ì—´ì„ ì‚¬ìš©í•  수 없습니다" +msgstr "í•˜ë‚˜ì˜ ì¸ë±ìФì—서는 %d개보다 ë§Žì€ ì¹¼ëŸ¼ì„ ì‚¬ìš©í•  수 없습니다" -#: commands/indexcmds.c:384 +#: commands/indexcmds.c:436 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸” 대ìƒìœ¼ë¡œ ì¸ë±ìŠ¤ë¥¼ 만들 수 ì—†ìŒ" -#: commands/indexcmds.c:399 +#: commands/indexcmds.c:461 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œ ë™ì‹œì— ì¸ë±ìŠ¤ë¥¼ 만들 수 ì—†ìŒ" + +#: commands/indexcmds.c:466 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œ 제외 ì œì•½ì¡°ê±´ì„ ë§Œë“¤ 수 ì—†ìŒ" + +#: commands/indexcmds.c:476 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì— ì¸ë±ìŠ¤ë¥¼ 만들 수는 없습니다" -#: commands/indexcmds.c:455 commands/tablecmds.c:546 commands/tablecmds.c:9694 +#: commands/indexcmds.c:541 commands/tablecmds.c:614 commands/tablecmds.c:10952 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "공유 관계만 pg_global í…Œì´ë¸”스페ì´ìŠ¤ì— ë°°ì¹˜í•  수 있ìŒ" -#: commands/indexcmds.c:488 +#: commands/indexcmds.c:574 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "사용하지 않는 \"rtree\" ë°©ë²•ì„ \"gist\" 액세스 방법으로 대체하는 중" -#: commands/indexcmds.c:506 +#: commands/indexcmds.c:592 #, c-format -msgid "hash indexes are not WAL-logged and their use is discouraged" -msgstr "hash ì¸ë±ìŠ¤ëŠ” WAL 기ë¡ì„ 하지 않습니다. ì´ ì‚¬ìš©ì€ ê¶Œìž¥í•˜ì§€ 않습니다" +msgid "access method \"%s\" does not support unique indexes" +msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì€ ê³ ìœ  ì¸ë±ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다" -#: commands/indexcmds.c:511 +#: commands/indexcmds.c:597 #, c-format -msgid "access method \"%s\" does not support unique indexes" -msgstr "\"%s\" ì¸ë±ìФ 액세스 ë°©ë²•ì€ ê³ ìœ  ì¸ë±ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다" +msgid "access method \"%s\" does not support included columns" +msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì€ í¬í•¨ëœ ì¹¼ëŸ¼ì„ ì§€ì›í•˜ì§€ 않습니다" -#: commands/indexcmds.c:516 +#: commands/indexcmds.c:602 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" -msgstr "\"%s\" ì¸ë±ìФ 액세스 ë°©ë²•ì€ ë‹¤ì¤‘ ì—´ ì¸ë±ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다" +msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì€ ë‹¤ì¤‘ ì—´ ì¸ë±ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다" -#: commands/indexcmds.c:521 +#: commands/indexcmds.c:607 #, c-format msgid "access method \"%s\" does not support exclusion constraints" -msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì€ exclusion 제약 ì¡°ê±´ì„ ì§€ì›í•˜ì§€ 않습니다" +msgstr "\"%s\" ì¸ë±ìФ ì ‘ê·¼ ë°©ë²•ì€ ì œì™¸ 제약 ì¡°ê±´ì„ ì§€ì›í•˜ì§€ 않습니다" + +#: commands/indexcmds.c:719 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "파티션 키 ì •ì˜ì—는 %s ì œì•½ì¡°ê±´ì„ ì§€ì›í•˜ì§€ 않ìŒ" + +#: commands/indexcmds.c:721 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "%s ì œì•½ì¡°ê±´ì€ íŒŒí‹°ì…˜ 키 í¬í•¨ 표현ì‹ì— 사용할 수 없습니다" + +#: commands/indexcmds.c:739 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "%s 제약조건 ì •ì˜ì— 불충분한 칼럼들" + +#: commands/indexcmds.c:741 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "" -#: commands/indexcmds.c:591 commands/indexcmds.c:611 +#: commands/indexcmds.c:760 commands/indexcmds.c:780 #, c-format msgid "index creation on system columns is not supported" msgstr "시스템 카탈로그 í…Œì´ë¸”ì— ëŒ€í•œ ì¸ë±ìФ 만들기는 ì§€ì›í•˜ì§€ 않습니다" -#: commands/indexcmds.c:636 +#: commands/indexcmds.c:805 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s 명령으로 \"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" í…Œì´ë¸”ì— ìžë™ìœ¼ë¡œ 만들었ìŒ" -#: commands/indexcmds.c:983 +#: commands/indexcmds.c:1391 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" -msgstr "" -"ì¸ë±ìФ 술어(predicate)ì—서 사용하는 함수는 IMMUTABLE íŠ¹ì„±ì´ ìžˆì–´ì•¼í•©ë‹ˆë‹¤" +msgstr "ì¸ë±ìФ 술어(predicate)ì—서 사용하는 함수는 IMMUTABLE íŠ¹ì„±ì´ ìžˆì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/indexcmds.c:1049 parser/parse_utilcmd.c:1881 +#: commands/indexcmds.c:1457 parser/parse_utilcmd.c:2239 +#: parser/parse_utilcmd.c:2363 #, c-format msgid "column \"%s\" named in key does not exist" -msgstr "키ì—서 지정한 \"%s\" ì—´ì´ ì—†ìŠµë‹ˆë‹¤" +msgstr "키ì—서 지정한 \"%s\" ì¹¼ëŸ¼ì´ ì—†ìŠµë‹ˆë‹¤" + +#: commands/indexcmds.c:1481 parser/parse_utilcmd.c:1588 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "í¬í•¨ëœ ì¹¼ëŸ¼ì— ì“°ì¸ í‘œí˜„ì‹ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/indexcmds.c:1109 +#: commands/indexcmds.c:1522 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "ì¸ë±ìФ ì‹(expression)ì— ì‚¬ìš©í•˜ëŠ” 함수는 IMMUTABLE íŠ¹ì„±ì´ ìžˆì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/indexcmds.c:1132 +#: commands/indexcmds.c:1537 #, c-format -msgid "could not determine which collation to use for index expression" +msgid "including column does not support a collation" +msgstr "í¬í•¨ëœ ì¹¼ëŸ¼ì€ ë¬¸ìžì •ë ¬ê·œì¹™ì„ ì§€ì›í•˜ì§€ 않ìŒ" + +#: commands/indexcmds.c:1541 +#, c-format +msgid "including column does not support an operator class" +msgstr "í¬í•¨ëœ ì¹¼ëŸ¼ì€ ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않ìŒ" + +#: commands/indexcmds.c:1545 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "í¬í•¨ëœ ì¹¼ëŸ¼ì€ ASC/DESC ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" + +#: commands/indexcmds.c:1549 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "í¬í•¨ëœ ì¹¼ëŸ¼ì€ NULLS FIRST/LAST ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" + +#: commands/indexcmds.c:1576 +#, c-format +msgid "could not determine which collation to use for index expression" msgstr "해당 ì¸ë±ìФì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 없습니다." -#: commands/indexcmds.c:1140 commands/typecmds.c:827 parser/parse_expr.c:2608 -#: parser/parse_type.c:550 parser/parse_utilcmd.c:2807 utils/adt/misc.c:666 +#: commands/indexcmds.c:1584 commands/tablecmds.c:13800 commands/typecmds.c:833 +#: parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3394 +#: utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "%s ìžë£Œí˜•ì€ collation ì§€ì› ì•ˆí•¨" -#: commands/indexcmds.c:1178 +#: commands/indexcmds.c:1622 #, c-format msgid "operator %s is not commutative" msgstr "%s ì—°ì‚°ìžëŠ” êµí™˜ë²•ì¹™ì´ ì„±ë¦½í•˜ì§€ 않습니다" -#: commands/indexcmds.c:1180 +#: commands/indexcmds.c:1624 #, c-format msgid "Only commutative operators can be used in exclusion constraints." -msgstr "" -"exclude 제약조건용 ì¸ë±ìŠ¤ë¥¼ 만들 때는 êµí™˜ë²•ì¹™ì´ ì„±ë¦½í•˜ëŠ” ì—°ì‚°ìžë§Œ 사용할 수 " -"있습니다." +msgstr "exclude 제약조건용 ì¸ë±ìŠ¤ë¥¼ 만들 때는 êµí™˜ë²•ì¹™ì´ ì„±ë¦½í•˜ëŠ” ì—°ì‚°ìžë§Œ 사용할 수 있습니다." -#: commands/indexcmds.c:1206 +#: commands/indexcmds.c:1650 #, c-format msgid "operator %s is not a member of operator family \"%s\"" -msgstr "%s ì—°ì‚°ìžëŠ” \"%s\" ì—°ì‚°ìž ê°€ì¡± 구성ì›ì´ 아닙니다." +msgstr "%s ì—°ì‚°ìžëŠ” \"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ 구성ì›ì´ 아닙니다." -#: commands/indexcmds.c:1209 +#: commands/indexcmds.c:1653 #, c-format -msgid "" -"The exclusion operator must be related to the index operator class for the " -"constraint." -msgstr "" -"제외 ì—°ì‚°ìžëŠ” 해당 제약 ì¡°ê±´ìš© ì¸ë±ìФ ì—°ì‚°ìž í´ëž˜ìŠ¤ì˜ ì†Œì†ì´ì–´ì•¼ 합니다." +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "제외 ì—°ì‚°ìžëŠ” 해당 제약 ì¡°ê±´ìš© ì¸ë±ìФ ì—°ì‚°ìž í´ëž˜ìŠ¤ì˜ ì†Œì†ì´ì–´ì•¼ 합니다." -#: commands/indexcmds.c:1244 +#: commands/indexcmds.c:1688 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "\"%s\" ì ‘ê·¼ ë°©ë²•ì€ ASC/DESC ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/indexcmds.c:1249 +#: commands/indexcmds.c:1693 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "\"%s\" ì ‘ê·¼ ë°©ë²•ì€ NULLS FIRST/LAST ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/indexcmds.c:1305 commands/typecmds.c:1935 +#: commands/indexcmds.c:1752 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" -msgstr "" -"%s ìžë£Œí˜•ì€ \"%s\" ì¸ë±ìФ 액세스 ë°©ë²•ì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìФ(operator " -"class)ê°€ 없습니다. " +msgstr "%s ìžë£Œí˜•ì€ \"%s\" ì¸ë±ìФ 액세스 ë°©ë²•ì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìФ(operator class)ê°€ 없습니다. " -#: commands/indexcmds.c:1307 +#: commands/indexcmds.c:1754 #, c-format -msgid "" -"You must specify an operator class for the index or define a default " -"operator class for the data type." -msgstr "" -"ì´ ì¸ë±ìŠ¤ë¥¼ 위한 ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ 지정하거나 먼저 ì´ ìžë£Œí˜•ì„ ìœ„í•œ 기본 ì—°ì‚°" -"ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•´ ë‘어야합니다" +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "ì´ ì¸ë±ìŠ¤ë¥¼ 위한 ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ 지정하거나 먼저 ì´ ìžë£Œí˜•ì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•´ ë‘어야합니다" -#: commands/indexcmds.c:1336 commands/indexcmds.c:1344 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1783 commands/indexcmds.c:1791 +#: commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" -msgstr "" -"\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” \"%s\" ì¸ë±ìФ 액세스 방법ì—서 사용할 수 없습니다" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” \"%s\" ì¸ë±ìФ 액세스 방법ì—서 사용할 수 없습니다" -#: commands/indexcmds.c:1357 commands/typecmds.c:1923 +#: commands/indexcmds.c:1804 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" -#: commands/indexcmds.c:1447 +#: commands/indexcmds.c:1894 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "%s ìžë£Œí˜•ì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìŠ¤ê°€ 여러개 있습니다" -#: commands/indexcmds.c:1838 +#: commands/indexcmds.c:2309 #, c-format msgid "table \"%s\" has no indexes" msgstr "\"%s\" í…Œì´ë¸”ì—는 사용할 수 있는 ì¸ë±ìŠ¤ê°€ 없습니다" -#: commands/indexcmds.c:1893 +#: commands/indexcmds.c:2364 #, c-format msgid "can only reindex the currently open database" msgstr "열려있는 현재 ë°ì´í„°ë² ì´ìФì—서만 reindex ëª…ë ¹ì„ ì‚¬ìš©í•  수 있습니다" -#: commands/indexcmds.c:1993 +#: commands/indexcmds.c:2482 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "\"%s.%s\" í…Œì´ë¸”ì˜ ì¸ë±ìŠ¤ë“¤ì„ ë‹¤ì‹œ 만들었습니다." -#: commands/matview.c:181 +#: commands/indexcmds.c:2504 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "파티션 ëœ ì¸ë±ìŠ¤ìš© REINDEX ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ë˜ì–´ 있지 않ìŒ" + +#: commands/lockcmds.c:100 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/lockcmds.c:224 rewrite/rewriteHandler.c:1836 +#: rewrite/rewriteHandler.c:3532 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜(relation)ì—서 ì§€ì •ëœ ë£°ì—서 ìž˜ëª»ëœ ìž¬ê·€í˜¸ì¶œì´ ë°œê²¬ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: commands/matview.c:179 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" -msgstr "" -"êµ¬ì²´í™”ëœ ë·°ì˜ ìžë£Œê°€ 정리ë˜ê³  ìžˆì„ ë•ŒëŠ” CONCURRENTLY ì˜µì…˜ì„ ì‚¬ìš©í•  수 없습니" -"다." +msgstr "êµ¬ì²´í™”ëœ ë·°ì˜ ìžë£Œê°€ 정리ë˜ê³  ìžˆì„ ë•ŒëŠ” CONCURRENTLY ì˜µì…˜ì„ ì‚¬ìš©í•  수 없습니다." -#: commands/matview.c:187 +#: commands/matview.c:185 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "CONCURRENTLY 옵션과, WITH NO DATA ì˜µì…˜ì„ í•¨ê»˜ 사용할 수 없습니다." -#: commands/matview.c:257 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°ë¥¼ ë™ì‹œì— 재갱신 í•  수 없습니다." -#: commands/matview.c:260 +#: commands/matview.c:247 #, c-format -msgid "" -"Create a unique index with no WHERE clause on one or more columns of the " -"materialized view." -msgstr "" -"êµ¬ì²´í™”ëœ ë·°ì˜ í•˜ë‚˜ ë˜ëŠ” 하나 ì´ìƒì˜ ì¹¼ëŸ¼ì— ëŒ€í•œ WHERE ì ˆ 없는 고유 ì¸ë±ìŠ¤ë¥¼ " -"만드세요." +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "êµ¬ì²´í™”ëœ ë·°ì˜ í•˜ë‚˜ ë˜ëŠ” 하나 ì´ìƒì˜ ì¹¼ëŸ¼ì— ëŒ€í•œ WHERE ì ˆ 없는 고유 ì¸ë±ìŠ¤ë¥¼ 만드세요." -#: commands/matview.c:657 +#: commands/matview.c:645 #, c-format -msgid "" -"new data for materialized view \"%s\" contains duplicate rows without any " -"null columns" -msgstr "" -"\"%s\" êµ¬ì²´í™”ëœ ë·°ì˜ ìƒˆ ìžë£Œì— 아무런 null 칼럼 ì—†ì´ ì¤‘ë³µëœ ë¡œìš°ë¥¼ í¬í•¨í•˜ê³  " -"있습니다" +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°ì˜ ìƒˆ ìžë£Œì— 아무런 null 칼럼 ì—†ì´ ì¤‘ë³µëœ ë¡œìš°ë¥¼ í¬í•¨í•˜ê³  있습니다" -#: commands/matview.c:659 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "로우: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" -msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ê°€ ì—†ìŒ, 해당 ì ‘ê·¼ 방법: \"%s\"" +msgstr "\"%s\" ì—°ì‚°ìž ì—†ìŒ, 해당 ì ‘ê·¼ 방법: \"%s\"" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ê°€ ì´ë¯¸ 있ìŒ, 해당 ì ‘ê·¼ 방법: \"%s\"" -#: commands/opclasscmds.c:404 +#: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" msgstr "ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” 슈í¼ìœ ì €ë§Œ 만들 수 있습니다" -#: commands/opclasscmds.c:478 commands/opclasscmds.c:863 -#: commands/opclasscmds.c:996 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 +#: commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "ìž˜ëª»ëœ ì—°ì‚°ìž ë²ˆí˜¸: %d, 타당한 번호는 1부터 %d까지 입니다" -#: commands/opclasscmds.c:529 commands/opclasscmds.c:914 -#: commands/opclasscmds.c:1011 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 +#: commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "ìž˜ëª»ëœ í”„ë¡œì‹œì € 번호 %d, ì´ ë²ˆí˜¸ëŠ” 1부터 %d까지입니다" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "ìž˜ëª»ëœ í•¨ìˆ˜ 번호: %d, 타당한 번호는 1부터 %d까지 입니다" -#: commands/opclasscmds.c:559 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "저장 ë°©ë²•ì´ ì¤‘ë³µë˜ì—ˆìŠµë‹ˆë‹¤" -#: commands/opclasscmds.c:586 +#: commands/opclasscmds.c:576 #, c-format -msgid "" -"storage type cannot be different from data type for access method \"%s\"" +msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "스토리지 ìžë£Œí˜•ì€ \"%s\" ì ‘ê·¼ ë°©ë²•ì˜ ìžë£Œí˜•ê³¼ 같아야 합니다." -#: commands/opclasscmds.c:602 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФì—는 ì´ë¯¸ \"%s\" 액세스 ë°©ë²•ì´ ì‚¬ìš©ë˜ê³  있습니다" -#: commands/opclasscmds.c:630 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ %s ìžë£Œí˜•ì˜ ê¸°ë³¸ê°’ìœ¼ë¡œ 지정할 수 없습니다" -#: commands/opclasscmds.c:633 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ëŠ” ì´ë¯¸ 기본 ì—°ì‚°ìž í´ëž˜ìŠ¤ìž…ë‹ˆë‹¤" -#: commands/opclasscmds.c:760 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" msgstr "슈í¼ìœ ì €ë§Œ ì—°ì‚°ìž íŒ¨ë°€ë¦¬ë¥¼ 만들 수 있ìŒ" -#: commands/opclasscmds.c:816 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" msgstr "슈í¼ìœ ì €ë§Œ ì—°ì‚°ìž íŒ¨ë°€ë¦¬ë¥¼ 변경할 수 있ìŒ" -#: commands/opclasscmds.c:879 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "ì—°ì‚°ìž ì¸ìž 형ì‹ì´ ALTER OPERATOR FAMILYì— ì§€ì •ë˜ì–´ 있어야 함" -#: commands/opclasscmds.c:943 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "ALTER OPERATOR FAMILYì—서 STORAGE를 지정할 수 ì—†ìŒ" -#: commands/opclasscmds.c:1066 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" msgstr "í•œë‘ ê°œì˜ ì¸ìž 형ì‹ì„ 지정해야 함" -#: commands/opclasscmds.c:1092 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "ì¸ë±ìФ ì—°ì‚°ìžëŠ” ë°”ì´ë„ˆë¦¬ì—¬ì•¼ 함" -#: commands/opclasscmds.c:1111 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "\"%s\" ì ‘ê·¼ ë°©ë²•ì€ ì •ë ¬ ìž‘ì—…ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/opclasscmds.c:1122 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" msgstr "ì¸ë±ìФ 검색 ì—°ì‚°ìžëŠ” ë¶€ìš¸í˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/opclasscmds.c:1164 +#: commands/opclasscmds.c:1144 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "btree ë¹„êµ í”„ë¡œì‹œì €ì—는 ë‘ ê°œì˜ ì¸ìžê°€ 있어야 함" +msgid "btree comparison functions must have two arguments" +msgstr "btree ë¹„êµ í•¨ìˆ˜ëŠ” ë‘ ê°œì˜ ì¸ìžê°€ 있어야 함" -#: commands/opclasscmds.c:1168 +#: commands/opclasscmds.c:1148 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "btree ë¹„êµ í”„ë¡œì‹œì €ëŠ” 반드시 integer ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" +msgid "btree comparison functions must return integer" +msgstr "btree ë¹„êµ í•¨ìˆ˜ëŠ” 반드시 integer ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/opclasscmds.c:1185 +#: commands/opclasscmds.c:1165 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "" -"btree ì •ë ¬ ì§€ì› í”„ë¡œì‹œì €ëŠ” 반드시 \"internal\" ìžë£Œí˜• ìž…ë ¥ ì¸ìžë¡œ 사용해야함" +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btree ì •ë ¬ ì§€ì› í•¨ìˆ˜ëŠ” 반드시 \"internal\" ìžë£Œí˜• ìž…ë ¥ ì¸ìžë¡œ 사용해야함" + +#: commands/opclasscmds.c:1169 +#, c-format +msgid "btree sort support functions must return void" +msgstr "btree ì •ë ¬ ì§€ì› í•¨ìˆ˜ëŠ” 반드시 void ê°’ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/opclasscmds.c:1189 +#: commands/opclasscmds.c:1180 #, c-format -msgid "btree sort support procedures must return void" -msgstr "btree ì •ë ¬ ì§€ì› í”„ë¡œì‹œì €ëŠ” 반드시 void ê°’ì„ ë°˜í™˜í•´ì•¼ 함" +msgid "btree in_range functions must have five arguments" +msgstr "btree in_range 함수는 ë‹¤ì„¯ê°œì˜ ì¸ìžê°€ 필요합니다" -#: commands/opclasscmds.c:1201 +#: commands/opclasscmds.c:1184 #, c-format -msgid "hash procedures must have one argument" -msgstr "해시 프로시저ì—는 í•˜ë‚˜ì˜ ì¸ìžê°€ 있어야 함" +msgid "btree in_range functions must return boolean" +msgstr "btree in_range 함수는 boolean ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/opclasscmds.c:1205 +#: commands/opclasscmds.c:1203 #, c-format -msgid "hash procedures must return integer" +msgid "hash function 1 must have one argument" +msgstr "해시 함수는 1ê°œì˜ ì¸ìžë§Œ 지정할 수 있습니다" + +#: commands/opclasscmds.c:1207 +#, c-format +msgid "hash function 1 must return integer" msgstr "해시 프로시저는 정수를 반환해야 함" -#: commands/opclasscmds.c:1229 +#: commands/opclasscmds.c:1214 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "해시 함수 2는 2ê°œì˜ ì¸ìžë§Œ 지정할 수 있습니다" + +#: commands/opclasscmds.c:1218 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "ì¸ë±ìФ ì§€ì› í”„ë¡œì‹œì €ì— ëŒ€í•´ 관련 ë°ì´í„° 형ì‹ì„ 지정해야 함" +msgid "hash function 2 must return bigint" +msgstr "해시 함수 2는 bigintí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/opclasscmds.c:1254 +#: commands/opclasscmds.c:1243 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "프로시저 번호 %dì´(ê°€) (%s,%s)ì— ëŒ€í•´ 여러 번 표시ë¨" +msgid "associated data types must be specified for index support function" +msgstr "ì¸ë±ìФ ì§€ì› í•¨ìˆ˜ì— ëŒ€í•´ 관련 ë°ì´í„° 형ì‹ì„ 지정해야 함" -#: commands/opclasscmds.c:1261 +#: commands/opclasscmds.c:1268 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "함수 번호 %dì´(ê°€) (%s,%s)ì— ëŒ€í•´ 여러 번 표시ë¨" + +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "ì—°ì‚°ìž ë²ˆí˜¸ %dì´(ê°€) (%s,%s)ì— ëŒ€í•´ 여러 번 표시ë¨" -#: commands/opclasscmds.c:1310 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "%d(%s,%s) ì—°ì‚°ìžê°€ \"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— ì´ë¯¸ 있ìŒ" -#: commands/opclasscmds.c:1426 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "%d(%s,%s) 함수가 \"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— ì´ë¯¸ 있ìŒ" -#: commands/opclasscmds.c:1516 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "%d(%s,%s) ì—°ì‚°ìžê°€ \"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— ì—†ìŒ" -#: commands/opclasscmds.c:1556 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "%d(%s,%s) 함수가 \"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì— ì—†ìŒ" -#: commands/opclasscmds.c:1686 +#: commands/opclasscmds.c:1696 #, c-format -msgid "" -"operator class \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" -msgstr "" -"\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(\"%s\" 액세스 ë°©ë²•ì„ ì‚¬ìš©í•˜ëŠ”)는 ì´ë¯¸ \"%s\" 스키마 안" -"ì— ìžˆìŠµë‹ˆë‹¤" +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(\"%s\" 액세스 ë°©ë²•ì„ ì‚¬ìš©í•˜ëŠ”)는 ì´ë¯¸ \"%s\" 스키마 ì•ˆì— ìžˆìŠµë‹ˆë‹¤" -#: commands/opclasscmds.c:1709 +#: commands/opclasscmds.c:1719 #, c-format -msgid "" -"operator family \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" ì—°ì‚°ìž íŒ¨ë°€ë¦¬(ì ‘ê·¼ 방법: \"%s\")ê°€ \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있ìŒ" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "SETOF 형ì‹ì€ ì—°ì‚°ìž ì¸ìžì— 허용ë˜ì§€ 않ìŒ" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:457 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "\"%s\" ì—°ì‚°ìž ì†ì„±ì„ 처리할 수 ì—†ìŒ" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "ì—°ì‚°ìž í”„ë¡œì‹œì €ëŠ” 반드시 지정해 주어야합니다" +msgid "operator function must be specified" +msgstr "ìžë£Œí˜• 함수를 지정하십시오" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "왼쪽 ì´ë‚˜ 오른쪽 중 ì ì–´ë„ í•˜ë‚˜ì˜ ì¸ìžëŠ” 지정해야 합니다" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "%s 제한 ì˜ˆìƒ í•¨ìˆ˜ëŠ” %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "%s ì¡°ì¸ ì˜ˆìƒ í•¨ìˆ˜ëŠ” %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" @@ -7988,13 +7786,13 @@ msgstr "%s ì¡°ì¸ ì˜ˆìƒ í•¨ìˆ˜ëŠ” %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" msgid "operator attribute \"%s\" cannot be changed" msgstr "\"%s\" ì—°ì‚°ìž ì†ì„± 바꿀 수 ì—†ìŒ" -#: commands/policy.c:87 commands/policy.c:388 commands/policy.c:477 -#: commands/tablecmds.c:971 commands/tablecmds.c:1313 -#: commands/tablecmds.c:2185 commands/tablecmds.c:4329 -#: commands/tablecmds.c:6280 commands/tablecmds.c:12080 -#: commands/tablecmds.c:12115 commands/trigger.c:241 commands/trigger.c:1125 -#: commands/trigger.c:1233 rewrite/rewriteDefine.c:273 -#: rewrite/rewriteDefine.c:917 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 +#: commands/tablecmds.c:1275 commands/tablecmds.c:1732 +#: commands/tablecmds.c:2718 commands/tablecmds.c:4951 +#: commands/tablecmds.c:7356 commands/tablecmds.c:13433 +#: commands/tablecmds.c:13468 commands/trigger.c:316 commands/trigger.c:1526 +#: commands/trigger.c:1635 rewrite/rewriteDefine.c:272 +#: rewrite/rewriteDefine.c:924 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "액세스 권한 ì—†ìŒ: \"%s\" 시스템 카탈로그임" @@ -8009,138 +7807,179 @@ msgstr "PUBLIC 아닌 지정한 모든 롤 무시함" msgid "All roles are members of the PUBLIC role." msgstr "모든 ë¡¤ì´ PUBLIC ë¡¤ì˜ ì†Œì†ìž…니다." -#: commands/policy.c:501 +#: commands/policy.c:514 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "\"%s\" ë¡¤ì„ \"%s\" ì •ì±… (ëŒ€ìƒ ë¦´ë ˆì´ì…˜: \"%s\")ì—서 ì‚­ì œë  ìˆ˜ ì—†ìŒ" -#: commands/policy.c:710 +#: commands/policy.c:720 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK ì˜µì…˜ì€ SELECT나 DELETE ìž‘ì—…ì— ì ìš© ë  ìˆ˜ ì—†ìŒ" -#: commands/policy.c:719 commands/policy.c:1019 +#: commands/policy.c:729 commands/policy.c:1027 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "INSERT êµ¬ë¬¸ì— ëŒ€í•´ì„œë§Œ WITH CHECK ì˜µì…˜ì„ í—ˆìš©í•©ë‹ˆë‹¤" -#: commands/policy.c:792 commands/policy.c:1242 +#: commands/policy.c:802 commands/policy.c:1247 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "\"%s\" ì •ì±…ì´ \"%s\" í…Œì´ë¸”ì— ì´ë¯¸ 지정ë˜ì–´ìžˆìŠµë‹ˆë‹¤" -#: commands/policy.c:991 commands/policy.c:1270 commands/policy.c:1345 +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "\"%s\" ì •ì±…ì´ \"%s\" í…Œì´ë¸”ì— ì—†ìŒ" -#: commands/policy.c:1009 +#: commands/policy.c:1017 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "USING 구문만 SELECT, DELETE ìž‘ì—…ì— ì“¸ 수 있ìŒ" -#: commands/portalcmds.c:61 commands/portalcmds.c:160 -#: commands/portalcmds.c:212 +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 #, c-format msgid "invalid cursor name: must not be empty" msgstr "ìž˜ëª»ëœ ì»¤ì„œ ì´ë¦„: 비어있으면 안ë©ë‹ˆë‹¤" -#: commands/portalcmds.c:168 commands/portalcmds.c:222 -#: executor/execCurrent.c:67 utils/adt/xml.c:2389 utils/adt/xml.c:2556 +#: commands/portalcmds.c:190 commands/portalcmds.c:244 +#: executor/execCurrent.c:68 utils/adt/xml.c:2469 utils/adt/xml.c:2639 #, c-format msgid "cursor \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì»¤ì„œê°€ ì—†ìŒ" -#: commands/prepare.c:71 +#: commands/prepare.c:75 #, c-format msgid "invalid statement name: must not be empty" msgstr "ìž˜ëª»ëœ ëª…ë ¹ë¬¸ ì´ë¦„: 비어있으면 안ë©ë‹ˆë‹¤" -#: commands/prepare.c:129 parser/parse_param.c:304 tcop/postgres.c:1343 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1376 #, c-format msgid "could not determine data type of parameter $%d" msgstr "$%d 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•ì„ ì•Œìˆ˜ê°€ 없습니다." -#: commands/prepare.c:147 +#: commands/prepare.c:159 #, c-format msgid "utility statements cannot be prepared" msgstr "utility ëª…ë ¹ë¬¸ë“¤ì€ ë¯¸ë¦¬ 준비할 수 없습니다" -#: commands/prepare.c:257 commands/prepare.c:264 +#: commands/prepare.c:269 commands/prepare.c:274 #, c-format msgid "prepared statement is not a SELECT" msgstr "ì¤€ë¹„ëœ ëª…ë ¹ë¬¸ì´ SELECT êµ¬ë¬¸ì´ ì•„ë‹™ë‹ˆë‹¤." -#: commands/prepare.c:332 +#: commands/prepare.c:342 #, c-format msgid "wrong number of parameters for prepared statement \"%s\"" msgstr "prepared statement \"%s\"ì— ë§¤ê°œ 변수 수가 틀렸습니다" -#: commands/prepare.c:334 +#: commands/prepare.c:344 #, c-format msgid "Expected %d parameters but got %d." msgstr "%d ê°œì˜ ë§¤ê°œ 변수가 요구ë˜ëŠ”ë° %d ê°œë§Œì´ ì¡´ìž¬í•©ë‹ˆë‹¤" -#: commands/prepare.c:370 +#: commands/prepare.c:380 #, c-format msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "??? parameter $%d of type %s 는 expected type %s 로 강요할 수 없다" -#: commands/prepare.c:465 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ ì¤€ë¹„ëœ ëª…ë ¹ë¬¸(prepared statement)ì´ ì´ë¯¸ 있습니다" -#: commands/prepare.c:504 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì¤€ë¹„ëœ ëª…ë ¹ë¬¸(prepared statement) ì—†ìŒ" -#: commands/proclang.c:87 +#: commands/proclang.c:86 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "CREATE LANGUAGE ì˜ ë§¤ê°œ 변수 ëŒ€ì‹ ì— pg_pltemplate 정보를 ì´ìš©í•˜ì„¸ìš”" -#: commands/proclang.c:97 +#: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "슈í¼ìœ ì €ë§Œ \"%s\" 프로시저 언어를 만들 수 있ìŒ" -#: commands/proclang.c:252 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "ì§€ì›í•˜ì§€ 않는 프로시저 언어 \"%s\"" -#: commands/proclang.c:254 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "ì§€ì›í•˜ëŠ” 언어 목ë¡ì€ pg_pltemplate 시스템 ì¹´íƒˆë¡œê·¸ì— ìžˆìŠµë‹ˆë‹¤." -#: commands/proclang.c:262 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" msgstr "슈í¼ìœ ì €ë§Œ ì‚¬ìš©ìž ì§€ì • 프로시저 언어를 만들 수 있ìŒ" -#: commands/proclang.c:281 +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 +#: commands/typecmds.c:471 #, c-format -msgid "" -"changing return type of function %s from \"opaque\" to \"language_handler\"" -msgstr "" -"%s 함수ì—서 \"opaque\" ìžë£Œí˜•ì„ \"language_handler\" ìžë£Œí˜•으로 리턴 ìžë£Œí˜•" -"ì„ ë°”ê¿‰ë‹ˆë‹¤" +msgid "changing return type of function %s from %s to %s" +msgstr "%s í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì„ %sì—서 %s ìžë£Œí˜•으로 바꿉니다" + +#: commands/publicationcmds.c:109 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\" ì˜µì…˜ì˜ ëª©ë¡ ë¬¸ë²•ì´ ìž˜ëª»ë¨" + +#: commands/publicationcmds.c:127 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "알 수 없는 \"publish\" ê°’: \"%s\"" + +#: commands/publicationcmds.c:133 +#, c-format +msgid "unrecognized publication parameter: %s" +msgstr "ì¸ì‹í•  수 없는 발행 매개 변수: %s" + +#: commands/publicationcmds.c:166 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "FOR ALL TABLES ì˜µì…˜ì˜ ë°œí–‰ì„ ë§Œë“œë ¤ë©´ 슈í¼ìœ ì €ì—¬ì•¼ë§Œ 합니다" + +#: commands/publicationcmds.c:335 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "\"%s\" ë°œí–‰ì€ FOR ALL TABLES 옵션으로 ì •ì˜ë˜ì–´ 있습니다." + +#: commands/publicationcmds.c:337 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "FOR ALL TABLES ë°œí–‰ì— ìƒˆ í…Œì´ë¸”ì„ ì¶”ê°€í•˜ê±°ë‚˜ 한 í…Œì´ë¸”ì„ ëº„ 수 없습니다." + +#: commands/publicationcmds.c:638 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "\"%s\" 릴레ì´ì…˜ì€ 해당 ë°œí–‰ì— í¬í•¨ë˜ì–´ 있지 않습니다" + +#: commands/publicationcmds.c:681 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "\"%s\" ë°œí–‰ì˜ ì†Œìœ ì£¼ë¥¼ 바꿀 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" + +#: commands/publicationcmds.c:683 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLES 옵션용 ë°œí–‰ì˜ ì†Œìœ ì£¼ëŠ” 슈í¼ìœ ì €ì—¬ì•¼ë§Œ 합니다" -#: commands/schemacmds.c:99 commands/schemacmds.c:262 +#: commands/schemacmds.c:106 commands/schemacmds.c:280 #, c-format msgid "unacceptable schema name \"%s\"" msgstr "\"%s\" 스키마 ì´ë¦„ì´ ì ë‹¹í•˜ì§€ 못합니다" -#: commands/schemacmds.c:100 commands/schemacmds.c:263 +#: commands/schemacmds.c:107 commands/schemacmds.c:281 #, c-format msgid "The prefix \"pg_\" is reserved for system schemas." -msgstr "" -"\"pg_\" 문ìžë¡œ 시작하는 스키마는 시스템ì—서 사용하는 ì˜ˆì•½ëœ ìŠ¤í‚¤ë§ˆìž…ë‹ˆë‹¤." +msgstr "\"pg_\" 문ìžë¡œ 시작하는 스키마는 시스템ì—서 사용하는 ì˜ˆì•½ëœ ìŠ¤í‚¤ë§ˆìž…ë‹ˆë‹¤." -#: commands/schemacmds.c:114 +#: commands/schemacmds.c:121 #, c-format msgid "schema \"%s\" already exists, skipping" msgstr "\"%s\" ì´ë¦„ì˜ ìŠ¤í‚¤ë§ˆ(schema)ê°€ ì´ë¯¸ 있ìŒ, 건너뜀" @@ -8152,8 +7991,7 @@ msgstr "ë¡œë“œëœ ë³´ì•ˆ ë¼ë²¨ 제공ìžê°€ ì—†ìŒ" #: commands/seclabel.c:64 #, c-format -msgid "" -"must specify provider when multiple security label providers have been loaded" +msgid "must specify provider when multiple security label providers have been loaded" msgstr "다중 보안 ë ˆì´ë¸” 제공ìžê°€ 로드 ë  ë•Œ 제공ìžë¥¼ 지정해야 합니다." #: commands/seclabel.c:82 @@ -8161,1149 +7999,1727 @@ msgstr "다중 보안 ë ˆì´ë¸” 제공ìžê°€ 로드 ë  ë•Œ 제공ìžë¥¼ 지정 msgid "security label provider \"%s\" is not loaded" msgstr "\"%s\" ì´ë¦„ì˜ ë³´ì•ˆ ë¼ë²¨ 제공ìžê°€ 로드ë˜ì–´ 있지 않ìŒ" -#: commands/sequence.c:127 +#: commands/sequence.c:138 #, c-format msgid "unlogged sequences are not supported" msgstr "로그를 남기지 않는 시퀀스는 ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/sequence.c:651 +#: commands/sequence.c:698 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: \"%s\" ì‹œí€€ìŠ¤ì˜ ìµœëŒ€ê°’(%s)ì´ ë˜ì—ˆìŠµë‹ˆë‹¤" -#: commands/sequence.c:674 +#: commands/sequence.c:721 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: \"%s\" ì‹œí€€ìŠ¤ì˜ ìµœì†Œê°’(%s)ì´ ë˜ì—ˆìŠµë‹ˆë‹¤" -#: commands/sequence.c:792 +#: commands/sequence.c:839 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "\"%s\" ì‹œí€€ìŠ¤ì˜ currval ê°’ì´ í˜„ìž¬ ì„¸ì…˜ì— ì§€ì •ë˜ì–´ 있지 않습니다" -#: commands/sequence.c:811 commands/sequence.c:817 +#: commands/sequence.c:858 commands/sequence.c:864 #, c-format msgid "lastval is not yet defined in this session" msgstr "ì´ ì„¸ì…˜ì—는 lastval ê°’ì´ ì•„ì§ê¹Œì§€ 지정ë˜ì§€ 않았습니다" -#: commands/sequence.c:893 +#: commands/sequence.c:952 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: %s ê°’ì€ \"%s\" ì‹œí€€ìŠ¤ì˜ ë²”ìœ„(%s..%s)를 벗어났습니다" -#: commands/sequence.c:1267 +#: commands/sequence.c:1349 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "ìž˜ëª»ëœ SEQUENCE NAME 시퀀스 옵션" + +#: commands/sequence.c:1375 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "ì‹ë³„ ì¹¼ëŸ¼ì— ì“¸ ìžë£Œí˜•ì€ smallint, integer, bigint ìžë£Œí˜•ë§Œ 쓸 수 있ìŒ" + +#: commands/sequence.c:1376 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "ì‹œí€€ìŠ¤ì— ì“¸ ìžë£Œí˜•ì€ smallint, integer, bigint ìžë£Œí˜•ë§Œ 쓸 수 있ìŒ" + +#: commands/sequence.c:1410 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT ê°’ì€ 0(zero)ì´ ë  ìˆ˜ 없습니다" -#: commands/sequence.c:1323 +#: commands/sequence.c:1463 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) ê°’ì´ í—ˆìš© 범위 ë°–ìž„, 해당 시퀀스 ìžë£Œí˜•: %s" + +#: commands/sequence.c:1500 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) ê°’ì´ í—ˆìš© 범위 ë°–ìž„, 해당 시퀀스 ìžë£Œí˜•: %s" + +#: commands/sequence.c:1514 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) ê°’ì€ MAXVALUE (%s) 값보다 작아야합니다" -#: commands/sequence.c:1348 +#: commands/sequence.c:1541 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "START ê°’(%s)ì€ MINVALUE(%s)보다 ìž‘ì„ ìˆ˜ ì—†ìŒ" -#: commands/sequence.c:1360 +#: commands/sequence.c:1553 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "START ê°’(%s)ì€ MAXVALUE(%s)보다 í´ ìˆ˜ ì—†ìŒ" -#: commands/sequence.c:1390 +#: commands/sequence.c:1583 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "RESTART ê°’(%s)ì€ MINVALUE(%s)보다 ìž‘ì„ ìˆ˜ ì—†ìŒ" -#: commands/sequence.c:1402 +#: commands/sequence.c:1595 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "RESTART ê°’(%s)ì€ MAXVALUE(%s)보다 í´ ìˆ˜ ì—†ìŒ" -#: commands/sequence.c:1417 +#: commands/sequence.c:1610 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE (%s) ê°’ì€ 0(zero)보다 커야합니다" -#: commands/sequence.c:1449 +#: commands/sequence.c:1647 #, c-format msgid "invalid OWNED BY option" msgstr "ìž˜ëª»ëœ OWNED BY 옵션" -#: commands/sequence.c:1450 +#: commands/sequence.c:1648 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "OWNED BY í…Œì´ë¸”.ì—´ ë˜ëŠ” OWNED BY NONEì„ ì§€ì •í•˜ì‹­ì‹œì˜¤." -#: commands/sequence.c:1473 +#: commands/sequence.c:1673 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "참조ë˜ëŠ” \"%s\" 릴레ì´ì…˜ì€ í…Œì´ë¸” ë˜ëŠ” 외부 í…Œì´ë¸”ì´ ì•„ë‹™ë‹ˆë‹¤" -#: commands/sequence.c:1480 +#: commands/sequence.c:1680 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "시퀀스 ë° ì´ ì‹œí€€ìŠ¤ê°€ ì—°ê²°ëœ í…Œì´ë¸”ì˜ ì†Œìœ ì£¼ê°€ 같아야 함" -#: commands/sequence.c:1484 +#: commands/sequence.c:1684 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "시퀀스 ë° ì´ ì‹œí€€ìŠ¤ê°€ ì—°ê²°ëœ í…Œì´ë¸”ì´ ê°™ì€ ìŠ¤í‚¤ë§ˆì— ìžˆì–´ì•¼ 함" -#: commands/tablecmds.c:216 +#: commands/sequence.c:1706 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "ì‹ë³„ ì‹œí€€ìŠ¤ì˜ ì†Œìœ ì£¼ëŠ” 바꿀 수 ì—†ìŒ" + +#: commands/sequence.c:1707 commands/tablecmds.c:10330 +#: commands/tablecmds.c:12896 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "\"%s\" 시퀀스는 \"%s\" í…Œì´ë¸”ì— ì¢…ì†ë˜ì–´ 있습니다." + +#: commands/statscmds.c:93 commands/statscmds.c:102 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS 명령ì—서는 í•˜ë‚˜ì˜ ë¦´ë ˆì´ì…˜ë§Œ 사용할 수 있ìŒ" + +#: commands/statscmds.c:120 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„, 외부 í…Œì´ë¸”ë„, êµ¬ì²´í™”ëœ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/statscmds.c:163 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "\"%s\" ì´ë¦„ì˜ í†µê³„ì •ë³´ 개체가 ì´ë¯¸ 있습니다, 건너뜀" + +#: commands/statscmds.c:171 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ í†µê³„ì •ë³´ 개체가 ì´ë¯¸ 있ìŒ" + +#: commands/statscmds.c:193 commands/statscmds.c:199 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS 명령ì—서는 단순 칼럼 참조만 허용합니다." + +#: commands/statscmds.c:214 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "시스템 ì¹¼ëŸ¼ì— ëŒ€í•œ 통계정보 개체 만들기는 ì§€ì›í•˜ì§€ 않습니다" + +#: commands/statscmds.c:221 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ì‚¬ìš©ìž í†µê³„ì •ë³´ ìˆ˜ì§‘ì´ ë¶ˆê°€ëŠ¥í•©ë‹ˆë‹¤. %s ìžë£Œí˜•ì€ ê¸°ë³¸ btree ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•˜ì§€ 않았습니다" + +#: commands/statscmds.c:228 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "통계정보 개체ì—서는 %d개보다 ë§Žì€ ì¹¼ëŸ¼ì„ ì‚¬ìš©í•  수 없습니다" + +#: commands/statscmds.c:243 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "í™•ìž¥ëœ í†µê³„ì •ë³´ëŠ” ë‘ ê°œ ì´ìƒì˜ ì¹¼ëŸ¼ì´ í•„ìš”í•©ë‹ˆë‹¤." + +#: commands/statscmds.c:261 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "통계정보 ì •ì˜ì—서 사용하는 ì¹¼ëŸ¼ì´ ì¤‘ë³µë˜ì—ˆìŠµë‹ˆë‹¤" + +#: commands/statscmds.c:289 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "알 수 없는 통계정보 종류 \"%s\"" + +#: commands/subscriptioncmds.c:187 +#, c-format +msgid "unrecognized subscription parameter: %s" +msgstr "알 수 없는 êµ¬ë… ë§¤ê°œ 변수: \"%s\"" + +#: commands/subscriptioncmds.c:200 +#, c-format +msgid "connect = false and enabled = true are mutually exclusive options" +msgstr "connect = false 옵션과 enabled = true ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:205 +#, c-format +msgid "connect = false and create_slot = true are mutually exclusive options" +msgstr "connect = false 옵션과 create_slot = true ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:210 +#, c-format +msgid "connect = false and copy_data = true are mutually exclusive options" +msgstr "connect = false 옵션과 copy_data = true ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:227 +#, c-format +msgid "slot_name = NONE and enabled = true are mutually exclusive options" +msgstr "slot_name = NONE 옵션과 enabled = true ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +msgstr "slot_name = NONE 옵션과 create_slot = true ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:237 +#, c-format +msgid "subscription with slot_name = NONE must also set enabled = false" +msgstr "구ë…ì—서 slot_name = NONE ì˜µì…˜ì€ enabled = false 옵션과 함께 사용해야 함" + +#: commands/subscriptioncmds.c:242 +#, c-format +msgid "subscription with slot_name = NONE must also set create_slot = false" +msgstr "구ë…ì—서 slot_name = NONE ì˜µì…˜ì€ create_slot = false 옵션과 함께 사용해야 함" + +#: commands/subscriptioncmds.c:283 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "\"%s\" 발행 ì´ë¦„ì´ ì—¬ëŸ¬ 번 사용 ë¨" + +#: commands/subscriptioncmds.c:347 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "êµ¬ë… ë§Œë“¤ê¸°ëŠ” 슈í¼ìœ ì ¸ ê¶Œí•œì´ í•„ìš”í•©ë‹ˆë‹¤" + +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 +#: replication/logical/tablesync.c:856 replication/logical/worker.c:1722 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "발행 ì„œë²„ì— ì—°ê²° í•  수 ì—†ìŒ: %s" + +#: commands/subscriptioncmds.c:469 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì´ ì—†ìŠµë‹ˆë‹¤" + +#: commands/subscriptioncmds.c:486 +#, c-format +msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" +msgstr "구ë…하고 있는 í…Œì´ë¸”ì´ ì—†ìŠµë‹ˆë‹¤, ALTER SUBSCRIPTION ... REFRESH PUBLICATION 명령으로 í…Œì´ë¸”ì„ êµ¬ë…í•  수 있습니다" + +#: commands/subscriptioncmds.c:576 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "\"%s.%s\" í…Œì´ë¸”ì„ \"%s\" 구ë…ì— ì¶”ê°€í–ˆìŠµë‹ˆë‹¤" + +#: commands/subscriptioncmds.c:600 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "\"%s.%s\" í…Œì´ë¸”ì„ \"%s\" 구ë…ì—서 삭제했습니다" + +#: commands/subscriptioncmds.c:669 +#, c-format +msgid "cannot set slot_name = NONE for enabled subscription" +msgstr "êµ¬ë… í™œì„±í™”ë¥¼ 위해서는 slot_name = NONE ì˜µì…˜ì€ ì‚¬ìš©í•  수 없습니다" + +#: commands/subscriptioncmds.c:703 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "슬롯 ì´ë¦„ ì—†ì´ëŠ” 구ë…ì„ í™œì„±í™” í•  수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:749 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "비활성화 ìƒíƒœì¸ 구ë…ì— ëŒ€í•´ì„œëŠ” ALTER SUBSCRIPTION 명령으로 갱신할 수 없습니다" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "" + +#: commands/subscriptioncmds.c:768 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "비활성화 ìƒíƒœì¸ 구ë…ì— ëŒ€í•´ì„œëŠ” ALTER SUBSCRIPTION ... REFRESH ëª…ë ¹ì„ í—ˆìš©í•˜ì§€ 않습니다." + +#: commands/subscriptioncmds.c:847 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "\"%s\" êµ¬ë… ì—†ìŒ, 건너뜀" + +#: commands/subscriptioncmds.c:972 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "" + +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 +#: replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 +#, c-format +msgid "The error was: %s" +msgstr "해당 오류: %s" + +#: commands/subscriptioncmds.c:975 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." +msgstr "구ë…ê³¼ ìŠ¬ë¡¯ì„ ë¶„ë¦¬í•  때는 ALTER SUBSCRIPTION ... SET (slot_name = NONE) ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." + +#: commands/subscriptioncmds.c:986 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "발행용 \"%s\" 복제 ìŠ¬ë¡¯ì„ ì‚­ì œ í•  수 ì—†ìŒ" + +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "발행ì—서 \"%s\" 복제 ìŠ¬ë¡¯ì„ ì‚­ì œí–ˆìŒ" + +#: commands/subscriptioncmds.c:1032 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "\"%s\" êµ¬ë… ì†Œìœ ì£¼ë¥¼ 변경할 ê¶Œí•œì´ ì—†ìŒ" + +#: commands/subscriptioncmds.c:1034 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "êµ¬ë… ì†Œìœ ì£¼ëŠ” 슈í¼ìœ ì €ì—¬ì•¼ 합니다." + +#: commands/subscriptioncmds.c:1147 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "구ë…ì—서 복제 í…Œì´ë¸” 목ë¡ì„ 구할 수 ì—†ìŒ: %s" + +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist" msgstr "\"%s\" í…Œì´ë¸” ì—†ìŒ" -#: commands/tablecmds.c:217 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 #, c-format msgid "table \"%s\" does not exist, skipping" msgstr "\"%s\" í…Œì´ë¸” ì—†ìŒ, 무시함" -#: commands/tablecmds.c:219 +#: commands/tablecmds.c:226 commands/tablecmds.c:268 msgid "Use DROP TABLE to remove a table." msgstr "í…Œì´ë¸”ì„ ì‚­ì œí•˜ë ¤ë©´, DROP TABLE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:222 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist" msgstr "\"%s\" 시퀀스 ì—†ìŒ" -#: commands/tablecmds.c:223 +#: commands/tablecmds.c:230 #, c-format msgid "sequence \"%s\" does not exist, skipping" msgstr "\"%s\" 시퀀스 ì—†ìŒ, 무시함" -#: commands/tablecmds.c:225 +#: commands/tablecmds.c:232 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "시퀀스를 삭제하려면 DROP SEQUENCE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist" msgstr "\"%s\" ë·°(view) ì—†ìŒ" -#: commands/tablecmds.c:229 +#: commands/tablecmds.c:236 #, c-format msgid "view \"%s\" does not exist, skipping" msgstr "\"%s\" ë·°(view) ì—†ìŒ, 무시함" -#: commands/tablecmds.c:231 +#: commands/tablecmds.c:238 msgid "Use DROP VIEW to remove a view." msgstr "뷰를 삭제하려면, DROP VIEW ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ êµ¬ì²´í™”ëœ ë·°ê°€ ì—†ìŒ" -#: commands/tablecmds.c:235 +#: commands/tablecmds.c:242 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·° ì—†ìŒ, 건너뜀" -#: commands/tablecmds.c:237 +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "êµ¬ì²´í™”ëœ ë·°ë¥¼ 삭제하려면, DROP MATERIALIZED VIEW ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:240 parser/parse_utilcmd.c:1630 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:14808 +#: parser/parse_utilcmd.c:1984 #, c-format msgid "index \"%s\" does not exist" msgstr "\"%s\" ì¸ë±ìФ ì—†ìŒ" -#: commands/tablecmds.c:241 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "\"%s\" ì¸ë±ìФ ì—†ìŒ, 무시함" -#: commands/tablecmds.c:243 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "ì¸ë±ìŠ¤ë¥¼ 삭제하려면, DROP INDEX ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" -msgstr "\"%s\" ê°ì²´ëŠ” ìžë£Œí˜•ì´ ì•„ë‹˜" +msgstr "\"%s\" 개체는 ìžë£Œí˜•ì´ ì•„ë‹˜" -#: commands/tablecmds.c:249 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "ìžë£Œí˜•ì„ ì‚­ì œí•˜ë ¤ë©´ DROP TYPE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:252 commands/tablecmds.c:8583 -#: commands/tablecmds.c:11335 +#: commands/tablecmds.c:259 commands/tablecmds.c:9782 +#: commands/tablecmds.c:12676 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "\"%s\" 외부 í…Œì´ë¸” ì—†ìŒ" -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "\"%s\" 외부 í…Œì´ë¸” ì—†ìŒ, 건너뜀" -#: commands/tablecmds.c:255 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "외부 í…Œì´ë¸”ì„ ì‚­ì œí•˜ë ¤ë©´, DROP FOREIGN TABLE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: commands/tablecmds.c:494 +#: commands/tablecmds.c:554 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT ì˜µì…˜ì€ ìž„ì‹œ í…Œì´ë¸”ì—서만 ì‚¬ìš©ë  ìˆ˜ 있습니다" -#: commands/tablecmds.c:514 +#: commands/tablecmds.c:582 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "보안 제한 작업 ë‚´ì—서 임시 í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: commands/tablecmds.c:822 +#: commands/tablecmds.c:683 +#, c-format +msgid "cannot create table with OIDs as partition of table without OIDs" +msgstr "OID 없는 í…Œì´ë¸”ì˜ íŒŒí‹°ì…˜ í…Œì´ë¸”로 OID 있는 í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" + +#: commands/tablecmds.c:807 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\" 파티션 ëœ í…Œì´ë¸” 아님" + +#: commands/tablecmds.c:888 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "%d개보다 ë§Žì€ ì¹¼ëŸ¼ì„ ì´ìš©í•´ì„œ 파티션할 수 ì—†ìŒ" + +#: commands/tablecmds.c:1095 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY ëª…ë ¹ì€ í•˜ë‚˜ì˜ ì¸ë±ìŠ¤ë§Œ 지울 수 있습니다" -#: commands/tablecmds.c:826 +#: commands/tablecmds.c:1099 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY 명령ì—서는 CASCADE ì˜µì…˜ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/tablecmds.c:1085 +#: commands/tablecmds.c:1381 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "파티션 ëœ í…Œì´ë¸”ë§Œ truncate í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:1382 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "ONLY ì˜µì…˜ì„ ë¹¼ê³  사용하거나, 하위 파티션 í…Œì´ë¸”ì„ ëŒ€ìƒìœ¼ë¡œ ì§ì ‘ TRUNCATE ONLY ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." + +#: commands/tablecmds.c:1451 #, c-format msgid "truncate cascades to table \"%s\"" -msgstr "\"%s\" ê°ì²´ì˜ ìžë£Œë„ 함께 ì‚­ì œë¨" +msgstr "\"%s\" ê°œì²´ì˜ ìžë£Œë„ 함께 ì‚­ì œë¨" -#: commands/tablecmds.c:1323 +#: commands/tablecmds.c:1742 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸” ìžë£ŒëŠ” 비울(truncate) 수 없습니다" -#: commands/tablecmds.c:1529 parser/parse_utilcmd.c:1844 +#: commands/tablecmds.c:1973 commands/tablecmds.c:11427 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "\"%s\" 파티션 ëœ í…Œì´ë¸”로부터 ìƒì†í•  수 없습니다" + +#: commands/tablecmds.c:1978 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "\"%s\" 파티션 í…Œì´ë¸”입니다, 그래서 ìƒì† 대ìƒì´ ë  ìˆ˜ 없습니다" + +#: commands/tablecmds.c:1986 parser/parse_utilcmd.c:2201 +#: parser/parse_utilcmd.c:2324 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "ìƒì†í•  \"%s\" 릴레ì´ì…˜(relation)ì€ í…Œì´ë¸”ë„, 외부 í…Œì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:1536 commands/tablecmds.c:10150 +#: commands/tablecmds.c:1998 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì€ ì¼ë°˜ í…Œì´ë¸”입니다. 임시 í…Œì´ë¸”ì„ ì´ê²ƒì˜ 파티션 í…Œì´ë¸”로 만들 수 없습니다" + +#: commands/tablecmds.c:2007 commands/tablecmds.c:11406 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "\"%s\" 임시 í…Œì´ë¸”입니다, 그래서 ìƒì† 대ìƒì´ ë  ìˆ˜ 없습니다" -#: commands/tablecmds.c:1544 commands/tablecmds.c:10158 +#: commands/tablecmds.c:2017 commands/tablecmds.c:11414 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”입니다, 그래서 ìƒì† 대ìƒì´ ë  ìˆ˜ 없습니다" -#: commands/tablecmds.c:1560 commands/tablecmds.c:10192 +#: commands/tablecmds.c:2034 commands/tablecmds.c:11538 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "\"%s\" í…Œì´ë¸”ì´ ì—¬ëŸ¬ 번 ìƒì†ë¨" -#: commands/tablecmds.c:1608 +#: commands/tablecmds.c:2083 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "\"%s\" ì¹¼ëŸ¼ì´ ì¤‘ë³µë˜ì–´ ìƒì†ë©ë‹ˆë‹¤." -#: commands/tablecmds.c:1616 +#: commands/tablecmds.c:2091 #, c-format msgid "inherited column \"%s\" has a type conflict" -msgstr "ìƒìœ„ í…Œì´ë¸”ì—서 지정한 \"%s\" ì—´ì˜ ìžë£Œí˜•ë“¤ì´ ì¼ì¹˜í•˜ì§€ 않습니다" +msgstr "ìƒìœ„ í…Œì´ë¸”ì—서 지정한 \"%s\" ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ë“¤ì´ ì¼ì¹˜í•˜ì§€ 않습니다" -#: commands/tablecmds.c:1618 commands/tablecmds.c:1641 -#: commands/tablecmds.c:1839 commands/tablecmds.c:1863 -#: parser/parse_coerce.c:1630 parser/parse_coerce.c:1650 -#: parser/parse_coerce.c:1670 parser/parse_coerce.c:1715 -#: parser/parse_coerce.c:1752 parser/parse_param.c:218 +#: commands/tablecmds.c:2093 commands/tablecmds.c:2116 +#: commands/tablecmds.c:2322 commands/tablecmds.c:2352 +#: parser/parse_coerce.c:1716 parser/parse_coerce.c:1736 +#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1802 +#: parser/parse_coerce.c:1841 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s 형과 %s 형" -#: commands/tablecmds.c:1627 +#: commands/tablecmds.c:2102 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "ìƒì† ë°›ì€ \"%s\" ì¹¼ëŸ¼ì˜ ì •ë ¬ê·œì¹™ì—서 ì¶©ëŒí•©ë‹ˆë‹¤." -#: commands/tablecmds.c:1629 commands/tablecmds.c:1851 -#: commands/tablecmds.c:4767 +#: commands/tablecmds.c:2104 commands/tablecmds.c:2334 +#: commands/tablecmds.c:5411 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\" 형과 \"%s\" 형" -#: commands/tablecmds.c:1639 +#: commands/tablecmds.c:2114 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "ìƒì† ë°›ì€ \"%s\" ì¹¼ëŸ¼ì˜ ìŠ¤í† ë¦¬ì§€ 설정값ì—서 ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:1752 commands/tablecmds.c:8088 -#: parser/parse_utilcmd.c:923 parser/parse_utilcmd.c:1274 -#: parser/parse_utilcmd.c:1350 +#: commands/tablecmds.c:2228 commands/tablecmds.c:9269 +#: parser/parse_utilcmd.c:1117 parser/parse_utilcmd.c:1517 +#: parser/parse_utilcmd.c:1624 #, c-format msgid "cannot convert whole-row table reference" msgstr "ì „ì²´ 로우 í…Œì´ë¸” 참조형으로 변환할 수 ì—†ìŒ" -#: commands/tablecmds.c:1753 parser/parse_utilcmd.c:924 +#: commands/tablecmds.c:2229 parser/parse_utilcmd.c:1118 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "\"%s\" ì œì•½ì¡°ê±´ì— \"%s\" í…Œì´ë¸” ì „ì²´ 로우 참조가 있습니다" -#: commands/tablecmds.c:1825 +#: commands/tablecmds.c:2308 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "\"%s\" ì¹¼ëŸ¼ì„ ìƒì†ëœ ì •ì˜ì™€ 병합하는 중" -#: commands/tablecmds.c:1829 +#: commands/tablecmds.c:2312 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "\"%s\" ì¹¼ëŸ¼ì„ ìƒì†ëœ ì •ì˜ì™€ ì´ë™, 병합하는 중" -#: commands/tablecmds.c:1830 +#: commands/tablecmds.c:2313 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "ì‚¬ìš©ìž ì§€ì • ì¹¼ëŸ¼ì´ ìƒì†ëœ ì¹¼ëŸ¼ì˜ ìœ„ì¹˜ë¡œ ì´ë™ë˜ì—ˆìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:1837 +#: commands/tablecmds.c:2320 #, c-format msgid "column \"%s\" has a type conflict" msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì´ ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:1849 +#: commands/tablecmds.c:2332 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ì •ë ¬ê·œì¹™ì´ ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:1861 +#: commands/tablecmds.c:2350 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ìŠ¤í† ë¦¬ì§€ ì„¤ì •ê°’ì´ ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:1913 +#: commands/tablecmds.c:2461 #, c-format msgid "column \"%s\" inherits conflicting default values" -msgstr "" -"ìƒì† 받는 \"%s\" ì—´ ìžë£Œí˜•ê³¼ ì´ ì—´ì— ì§€ì •í•œ default ê°’ì˜ ìžë£Œí˜•ì´ ì„œë¡œ 다릅니" -"다" +msgstr "ìƒì† 받는 \"%s\" ì—´ ìžë£Œí˜•ê³¼ ì´ ì—´ì— ì§€ì •í•œ default ê°’ì˜ ìžë£Œí˜•ì´ ì„œë¡œ 다릅니다" -#: commands/tablecmds.c:1915 +#: commands/tablecmds.c:2463 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "ì´ ì¶©ëŒì„ 피하려면, default ê°’ì„ ë°”ë¥´ê²Œ 지정하십시오." -#: commands/tablecmds.c:1962 +#: commands/tablecmds.c:2510 #, c-format -msgid "" -"check constraint name \"%s\" appears multiple times but with different " -"expressions" -msgstr "" -"\"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ ì´ë¦„ì´ ì—¬ëŸ¬ 번 나타나지만, ê°ê° 다른 ì‹ìœ¼ë¡œ ë˜ì–´ìžˆìŒ" +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "\"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ ì´ë¦„ì´ ì—¬ëŸ¬ 번 나타나지만, ê°ê° 다른 ì‹ìœ¼ë¡œ ë˜ì–´ìžˆìŒ" -#: commands/tablecmds.c:2156 +#: commands/tablecmds.c:2687 #, c-format msgid "cannot rename column of typed table" msgstr "칼럼 ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ" -#: commands/tablecmds.c:2173 +#: commands/tablecmds.c:2706 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, composite type, index, or " -"foreign table" -msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ë„, ë·°ë„, êµ¬ì²´í™”ëœ ë·°ë„, 복합 ìžë£Œí˜•ë„, ì¸ë±ìФë„, 외부 í…Œ" -"ì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤." +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„, ë·°ë„, êµ¬ì²´í™”ëœ ë·°ë„, 복합 ìžë£Œí˜•ë„, ì¸ë±ìФë„, 외부 í…Œì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:2267 +#: commands/tablecmds.c:2800 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" -msgstr "하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì—´ì˜ ì´ë¦„ì„ ë°”ê¾¸ì–´ì•¼ 함" +msgstr "하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì¹¼ëŸ¼ì˜ ì´ë¦„ì„ ë°”ê¾¸ì–´ì•¼ 함" -#: commands/tablecmds.c:2299 +#: commands/tablecmds.c:2832 #, c-format msgid "cannot rename system column \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ì—´ì€ ì‹œìŠ¤í…œ 열입니다, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì€ ì‹œìŠ¤í…œ 칼럼입니다, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" -#: commands/tablecmds.c:2314 +#: commands/tablecmds.c:2847 #, c-format msgid "cannot rename inherited column \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ì—´ì€ ìƒì† ë°›ì€ ì—´ìž…ë‹ˆë‹¤, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì€ ìƒì† ë°›ì€ ì¹¼ëŸ¼ìž…ë‹ˆë‹¤, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" -#: commands/tablecmds.c:2469 +#: commands/tablecmds.c:2999 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" -msgstr "" -"하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì œì•½ì¡°ê±´ì€ í•˜ìœ„ í…Œì´ë¸”ì—ì„œë„ ì´ë¦„ì´ ë°”ë€Œì–´ì•¼ " -"함" +msgstr "하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì œì•½ì¡°ê±´ì€ í•˜ìœ„ í…Œì´ë¸”ì—ì„œë„ ì´ë¦„ì´ ë°”ë€Œì–´ì•¼ 함" -#: commands/tablecmds.c:2476 +#: commands/tablecmds.c:3006 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "\"%s\" ìƒì†ëœ ì œì•½ì¡°ê±´ì€ ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2702 +#: commands/tablecmds.c:3225 #, c-format -msgid "" -"cannot %s \"%s\" because it is being used by active queries in this session" +msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "ì´ ì„¸ì…˜ì˜ í™œì„± 쿼리ì—서 사용 중ì´ë¯€ë¡œ %s \"%s\" ìž‘ì—…ì„ í•  수 ì—†ìŒ" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2711 +#: commands/tablecmds.c:3235 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "보류 ì¤‘ì¸ íŠ¸ë¦¬ê±° ì´ë²¤íŠ¸ê°€ 있으므로 %s \"%s\" ìž‘ì—…ì„ í•  수 ì—†ìŒ" -#: commands/tablecmds.c:3785 +#: commands/tablecmds.c:4379 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "\"%s\" 시스템 릴레ì´ì…˜ì„ 다시 쓰기(rewrite) í•  수 ì—†ìŒ" -#: commands/tablecmds.c:3791 +#: commands/tablecmds.c:4385 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "카탈로그 í…Œì´ë¸”로 사용ë˜ì–´ \"%s\" í…Œì´ë¸”ì„ rewrite 못함" -#: commands/tablecmds.c:3801 +#: commands/tablecmds.c:4395 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì„ ë‹¤ì‹œ 쓰기(rewrite) í•  수 ì—†ìŒ" -#: commands/tablecmds.c:4069 +#: commands/tablecmds.c:4672 #, c-format msgid "rewriting table \"%s\"" msgstr "\"%s\" íŒŒì¼ ë‹¤ì‹œ 쓰는 중" -#: commands/tablecmds.c:4073 +#: commands/tablecmds.c:4676 #, c-format msgid "verifying table \"%s\"" msgstr "\"%s\" íŒŒì¼ ê²€ì‚¬ 중" -#: commands/tablecmds.c:4187 +#: commands/tablecmds.c:4792 #, c-format msgid "column \"%s\" contains null values" msgstr "\"%s\" ì—´ì—는 null ê°’ ìžë£Œê°€ 있습니다" -#: commands/tablecmds.c:4202 commands/tablecmds.c:7385 +#: commands/tablecmds.c:4808 commands/tablecmds.c:8503 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "\"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ì„ ìœ„ë°˜í•˜ëŠ” 몇몇 ìžë£Œê°€ ì´ë¯¸ 있습니다" -#: commands/tablecmds.c:4350 commands/trigger.c:235 -#: rewrite/rewriteDefine.c:267 rewrite/rewriteDefine.c:912 +#: commands/tablecmds.c:4826 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "기본 파티션용 ë°”ë€ íŒŒí‹°ì…˜ ì œì•½ì¡°ê±´ì´ ëª‡ëª‡ ìžë£Œì—서 바르지 않아 사용할 수 ì—†ìŒ" + +#: commands/tablecmds.c:4830 +#, c-format +msgid "partition constraint is violated by some row" +msgstr "파티션 제약 ì¡°ê±´ì„ ìœ„ë°˜í•˜ëŠ” 몇몇 ìžë£Œê°€ ì´ë¯¸ 있습니다" + +#: commands/tablecmds.c:4972 commands/trigger.c:310 rewrite/rewriteDefine.c:266 +#: rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ë„ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„ ë·°ë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4353 commands/trigger.c:1119 commands/trigger.c:1224 +#: commands/tablecmds.c:4975 commands/trigger.c:1520 commands/trigger.c:1626 #, c-format msgid "\"%s\" is not a table, view, or foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, ë·°, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”, ë·°, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4356 +#: commands/tablecmds.c:4978 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4362 +#: commands/tablecmds.c:4984 #, c-format msgid "\"%s\" is not a table, materialized view, or index" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4365 +#: commands/tablecmds.c:4987 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." +msgstr "\"%s\" 개체는 í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:4368 +#: commands/tablecmds.c:4990 #, c-format msgid "\"%s\" is not a table or foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”ë„ ì™¸ë¶€ í…Œì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”ë„ ì™¸ë¶€ í…Œì´ë¸”ë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4371 +#: commands/tablecmds.c:4993 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, 복합 ìžë£Œí˜•, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." +msgstr "\"%s\" 개체는 í…Œì´ë¸”, 복합 ìžë£Œí˜•, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:4374 commands/tablecmds.c:5426 +#: commands/tablecmds.c:4996 commands/tablecmds.c:6414 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" -msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." +msgstr "\"%s\" 개체는 í…Œì´ë¸”, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:4384 +#: commands/tablecmds.c:5006 #, c-format msgid "\"%s\" is of the wrong type" -msgstr "\"%s\" ê°ì²´ëŠ” ìž˜ëª»ëœ ê°ì²´í˜•입니다." +msgstr "\"%s\" 개체는 ìž˜ëª»ëœ ê°œì²´í˜•ìž…ë‹ˆë‹¤." -#: commands/tablecmds.c:4536 commands/tablecmds.c:4543 +#: commands/tablecmds.c:5181 commands/tablecmds.c:5188 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "\"%s\" ìžë£Œí˜• 변경할 수 ì—†ìŒ(\"%s.%s\" 칼럼ì—서 해당 형ì‹ì„ 사용함)" -#: commands/tablecmds.c:4550 +#: commands/tablecmds.c:5195 #, c-format -msgid "" -"cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" -msgstr "" -"\"%s\" 외부 í…Œì´ë¸”ì„ ë³€ê²½í•  수 ì—†ìŒ(\"%s.%s\" 칼럼ì—서 해당 로우 í˜•ì„ ì‚¬ìš©í•¨)" +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "\"%s\" 외부 í…Œì´ë¸”ì„ ë³€ê²½í•  수 ì—†ìŒ(\"%s.%s\" 칼럼ì—서 해당 로우 í˜•ì„ ì‚¬ìš©í•¨)" -#: commands/tablecmds.c:4557 +#: commands/tablecmds.c:5202 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" -msgstr "" -"\"%s\" í…Œì´ë¸”ì„ ë³€ê²½í•  수 ì—†ìŒ(\"%s.%s\" 칼럼ì—서 해당 로우 형ì‹ì„ 사용함)" +msgstr "\"%s\" í…Œì´ë¸”ì„ ë³€ê²½í•  수 ì—†ìŒ(\"%s.%s\" 칼럼ì—서 해당 로우 형ì‹ì„ 사용함)" -#: commands/tablecmds.c:4619 +#: commands/tablecmds.c:5256 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" -msgstr "" -"\"%s\" ìžë£Œí˜•ì„ ë³€ê²½í•  수 ì—†ìŒ, ì´ ìžë£Œí˜•ì€ typed í…Œì´ë¸”ì˜ ìžë£Œí˜•ì´ê¸° 때문" +msgstr "\"%s\" ìžë£Œí˜•ì„ ë³€ê²½í•  수 ì—†ìŒ, ì´ ìžë£Œí˜•ì€ typed í…Œì´ë¸”ì˜ ìžë£Œí˜•ì´ê¸° 때문" -#: commands/tablecmds.c:4621 +#: commands/tablecmds.c:5258 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." -msgstr "" -"ì´ ê°ì²´ì™€ ê´€ê³„ëœ ëª¨ë“  ê°ì²´ë“¤ì„ 함께 변경하려면 ALTER ... CASCADE ëª…ë ¹ì„ ì‚¬ìš©" -"하십시오" +msgstr "ì´ ê°œì²´ì™€ ê´€ê³„ëœ ëª¨ë“  ê°œì²´ë“¤ì„ í•¨ê»˜ 변경하려면 ALTER ... CASCADE ëª…ë ¹ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤" -#: commands/tablecmds.c:4665 +#: commands/tablecmds.c:5304 #, c-format msgid "type %s is not a composite type" msgstr "%s ìžë£Œí˜•ì€ ë³µí•© ìžë£Œí˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:4691 +#: commands/tablecmds.c:5330 #, c-format msgid "cannot add column to typed table" msgstr "typed í…Œì´ë¸”ì—는 ì¹¼ëŸ¼ì„ ì¶”ê°€ í•  수 ì—†ìŒ" -#: commands/tablecmds.c:4759 commands/tablecmds.c:10351 +#: commands/tablecmds.c:5374 +#, c-format +msgid "cannot add column to a partition" +msgstr "파티션 í…Œì´ë¸”ì—는 ì¹¼ëŸ¼ì„ ì¶”ê°€ í•  수 없습니다" + +#: commands/tablecmds.c:5403 commands/tablecmds.c:11665 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" -msgstr "" -"\"%s\" ìƒì†ëœ í…Œì´ë¸”ì˜ \"%s\" ì—´ ìžë£Œí˜•ì´ ìƒìœ„ í…Œì´ë¸”ì˜ ìžë£Œí˜•ê³¼ 틀립니다" +msgstr "\"%s\" ìƒì†ëœ í…Œì´ë¸”ì˜ \"%s\" ì—´ ìžë£Œí˜•ì´ ìƒìœ„ í…Œì´ë¸”ì˜ ìžë£Œí˜•ê³¼ 틀립니다" -#: commands/tablecmds.c:4765 commands/tablecmds.c:10358 +#: commands/tablecmds.c:5409 commands/tablecmds.c:11672 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" -msgstr "" -"\"%s\" ìƒì†ëœ í…Œì´ë¸”ì˜ \"%s\" 칼럼 ì •ë ¬ê·œì¹™ì´ ìƒìœ„ í…Œì´ë¸”ì˜ ì •ë ¬ê·œì¹™ê³¼ 틀립니" -"다" +msgstr "\"%s\" ìƒì†ëœ í…Œì´ë¸”ì˜ \"%s\" 칼럼 ì •ë ¬ê·œì¹™ì´ ìƒìœ„ í…Œì´ë¸”ì˜ ì •ë ¬ê·œì¹™ê³¼ 틀립니다" -#: commands/tablecmds.c:4775 +#: commands/tablecmds.c:5419 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" msgstr "\"%s\" 하위 í…Œì´ë¸”ì— ì¶©ëŒí•˜ëŠ” \"%s\" ì¹¼ëŸ¼ì´ ìžˆìŒ" -#: commands/tablecmds.c:4787 +#: commands/tablecmds.c:5430 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "\"%s\" ì—´(\"%s\" 하위)ì˜ ì •ì˜ë¥¼ 병합하는 중" -#: commands/tablecmds.c:5014 +#: commands/tablecmds.c:5454 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "하위 í…Œì´ë¸”ì— ìž¬ê·€ì ìœ¼ë¡œ ì‹ë³„ ì¹¼ëŸ¼ì„ ì¶”ê°€í•  수는 ì—†ìŒ" + +#: commands/tablecmds.c:5703 #, c-format msgid "column must be added to child tables too" -msgstr "하위 í…Œì´ë¸”ì—ë„ ì—´ì„ ì¶”ê°€í•´ì•¼ 함" +msgstr "하위 í…Œì´ë¸”ì—ë„ ì¹¼ëŸ¼ì„ ì¶”ê°€í•´ì•¼ 함" -#: commands/tablecmds.c:5089 +#: commands/tablecmds.c:5778 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì´ \"%s\" 릴레ì´ì…˜ì— ì´ë¯¸ 있습니다, 건너뜀" -#: commands/tablecmds.c:5096 +#: commands/tablecmds.c:5785 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" -msgstr "\"%s\" ì´ë¦„ì˜ ì—´ì´ \"%s\" 릴레ì´ì…˜ì— ì´ë¯¸ 있습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì€ \"%s\" 릴레ì´ì…˜ì— ì´ë¯¸ 있습니다" + +#: commands/tablecmds.c:5883 commands/tablecmds.c:8949 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "하위 í…Œì´ë¸”ì´ ìžˆëŠ” 경우, ìƒìœ„ í…Œì´ë¸”ì˜ ì œì•½ì¡°ê±´ë§Œ 지울 수는 ì—†ìŒ" + +#: commands/tablecmds.c:5884 commands/tablecmds.c:6028 +#: commands/tablecmds.c:6812 commands/tablecmds.c:8950 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ONLY ì˜µì…˜ì„ ë¹¼ê³  사용하세요." -#: commands/tablecmds.c:5207 commands/tablecmds.c:5313 -#: commands/tablecmds.c:5371 commands/tablecmds.c:5485 -#: commands/tablecmds.c:5542 commands/tablecmds.c:5636 -#: commands/tablecmds.c:7924 commands/tablecmds.c:8606 +#: commands/tablecmds.c:5916 commands/tablecmds.c:6064 +#: commands/tablecmds.c:6119 commands/tablecmds.c:6195 +#: commands/tablecmds.c:6289 commands/tablecmds.c:6348 +#: commands/tablecmds.c:6498 commands/tablecmds.c:6568 +#: commands/tablecmds.c:6660 commands/tablecmds.c:9089 +#: commands/tablecmds.c:9805 #, c-format msgid "cannot alter system column \"%s\"" -msgstr "\"%s\" ì—´ì€ ì‹œìŠ¤í…œ 열입니다. 그래서 ë³€ê²½ë  ìˆ˜ 없습니다" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ì‹œìŠ¤í…œ 칼럼입니다. 그래서 ë³€ê²½ë  ìˆ˜ 없습니다" + +#: commands/tablecmds.c:5922 commands/tablecmds.c:6125 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "\"%s\" 칼럼(해당 í…Œì´ë¸”: \"%s\")ì€ ì‹ë³„ 칼럼입니다." -#: commands/tablecmds.c:5243 +#: commands/tablecmds.c:5958 #, c-format msgid "column \"%s\" is in a primary key" -msgstr "\"%s\" ì—´ì€ ê¸°ë³¸í‚¤ 열입니다" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ê¸°ë³¸í‚¤ 칼럼입니다" + +#: commands/tablecmds.c:5980 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "파티션 í…Œì´ë¸”ì—서 \"%s\" ì¹¼ëŸ¼ì€ NOT NULL ì†ì„±ìœ¼ë¡œ ë˜ì–´ 있습니다" + +#: commands/tablecmds.c:6027 +#, c-format +msgid "cannot add constraint to only the partitioned table when partitions exist" +msgstr "" + +#: commands/tablecmds.c:6127 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "" + +#: commands/tablecmds.c:6206 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "" + +#: commands/tablecmds.c:6212 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼(해당 릴레ì´ì…˜: \"%s\")ì€ ì´ë¯¸ ì‹ë³„ 칼럼입니다" + +#: commands/tablecmds.c:6218 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼(해당 릴레ì´ì…˜: \"%s\")ì€ ì´ë¯¸ default 입니다" -#: commands/tablecmds.c:5458 +#: commands/tablecmds.c:6295 commands/tablecmds.c:6356 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼(해당 릴레ì´ì…˜: \"%s\")ì€ ì‹ë³„ ì¹¼ëŸ¼ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/tablecmds.c:6361 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼(해당 릴레ì´ì…˜: \"%s\")ì€ ì‹ë³„ ì¹¼ëŸ¼ì´ ì•„ë‹˜, 건너뜀" + +#: commands/tablecmds.c:6426 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "" + +#: commands/tablecmds.c:6457 #, c-format msgid "statistics target %d is too low" msgstr "ëŒ€ìƒ í†µê³„ê°’(%d)ì´ ë„ˆë¬´ 낮습니다" -#: commands/tablecmds.c:5466 +#: commands/tablecmds.c:6465 #, c-format msgid "lowering statistics target to %d" msgstr "%d 값으로 ëŒ€ìƒ í†µê³„ê°’ì„ ë‚®ì¶¥ë‹ˆë‹¤" -#: commands/tablecmds.c:5616 +#: commands/tablecmds.c:6488 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "%d번째 ì¹¼ëŸ¼ì´ ì—†ìŠµë‹ˆë‹¤. 해당 릴레ì´ì…˜: \"%s\"" + +#: commands/tablecmds.c:6507 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "\"%s\" í¬í•¨ëœ 칼럼 (해당 ì¸ë±ìФ: \"%s\") 관련 통계정보를 수정할 수 ì—†ìŒ" + +#: commands/tablecmds.c:6512 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "\"%s\" ë¹„í‘œí˜„ì‹ ì¹¼ëŸ¼ (해당 ì¸ë±ìФ: \"%s\") 관련 통계정보를 수정할 수 ì—†ìŒ" + +#: commands/tablecmds.c:6514 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "ëŒ€ì‹ ì— í…Œì´ë¸” 칼럼 대ìƒìœ¼ë¡œ 통계정보를 수정하세요." + +#: commands/tablecmds.c:6640 #, c-format msgid "invalid storage type \"%s\"" msgstr "ìž˜ëª»ëœ STORAGE ê°’: \"%s\"" -#: commands/tablecmds.c:5648 +#: commands/tablecmds.c:6672 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "%s ìžë£Œí˜•ì˜ columnì˜ STORAGE ê°’ì€ ë°˜ë“œì‹œ PLAIN ì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/tablecmds.c:5686 +#: commands/tablecmds.c:6707 #, c-format msgid "cannot drop column from typed table" msgstr "typed í…Œì´ë¸”ì—서 ì¹¼ëŸ¼ì„ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/tablecmds.c:5730 +#: commands/tablecmds.c:6752 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "\"%s\" ì¹¼ëŸ¼ì€ \"%s\" 릴레ì´ì…˜ì— ì—†ìŒ, 건너뜀" -#: commands/tablecmds.c:5743 +#: commands/tablecmds.c:6765 #, c-format msgid "cannot drop system column \"%s\"" msgstr "\"%s\" ì¹¼ëŸ¼ì€ ì‹œìŠ¤í…œ 칼럼입니다, ì‚­ì œë  ìˆ˜ 없습니다" -#: commands/tablecmds.c:5750 +#: commands/tablecmds.c:6772 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "\"%s\" ì¹¼ëŸ¼ì€ ìƒì†ë°›ì€ 칼럼입니다, ì‚­ì œë  ìˆ˜ 없습니다" -#: commands/tablecmds.c:5990 +#: commands/tablecmds.c:6783 #, c-format -msgid "" -"ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" -msgstr "" -"ALTER TABLE / ADD CONSTRAINT USING INDEX ìž‘ì—…ì€ \"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" ì´ë¦„으" -"로 바꿀 것입니다." +msgid "cannot drop column named in partition key" +msgstr "파티션 키로 ì“°ì´ëŠ” ì¹¼ëŸ¼ì€ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/tablecmds.c:6203 +#: commands/tablecmds.c:6787 #, c-format -msgid "constraint must be added to child tables too" -msgstr "하위 í…Œì´ë¸”ì—ë„ ì œì•½ ì¡°ê±´ì„ ì¶”ê°€í•´ì•¼ 함" +msgid "cannot drop column referenced in partition key expression" +msgstr "파티션 표현ì‹ì—서 참조하는 ì¹¼ëŸ¼ì€ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/tablecmds.c:6274 +#: commands/tablecmds.c:6811 #, c-format -msgid "referenced relation \"%s\" is not a table" -msgstr "참조ë˜ëŠ” \"%s\" 릴레ì´ì…˜ì€ í…Œì´ë¸”ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "파티션 í…Œì´ë¸”ì´ ìžˆëŠ” íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì—서 ê·¸ í…Œì´ë¸”ë§Œ ì¹¼ëŸ¼ì„ ì‚­ì œ í•  수 ì—†ìŒ" -#: commands/tablecmds.c:6297 +#: commands/tablecmds.c:7016 #, c-format -msgid "constraints on permanent tables may reference only permanent tables" -msgstr "ì˜êµ¬ 저장용 í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì˜êµ¬ 저장용 í…Œì´ë¸”ì„ ì°¸ì¡° 합니다." +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ìž‘ì—…ì€ íŒŒí‹°ì…˜ ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œëŠ” ì§€ì›í•˜ì§€ 않ìŒ" -#: commands/tablecmds.c:6304 +#: commands/tablecmds.c:7041 #, c-format -msgid "" -"constraints on unlogged tables may reference only permanent or unlogged " -"tables" -msgstr "" -"unlogged í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì˜êµ¬ 저장용 í…Œì´ë¸” ë˜ëŠ” unlogged í…Œì´ë¸”ì„ ì°¸ì¡°" -"합니다." +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ìž‘ì—…ì€ \"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" ì´ë¦„으로 바꿀 것입니다." -#: commands/tablecmds.c:6310 +#: commands/tablecmds.c:7257 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "하위 í…Œì´ë¸”ì—ë„ ì œì•½ ì¡°ê±´ì„ ì¶”ê°€í•´ì•¼ 함" + +#: commands/tablecmds.c:7329 +#, c-format +msgid "cannot reference partitioned table \"%s\"" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì„ ì°¸ì¡° í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:7337 +#, c-format +msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì„ ì°¸ì¡° 하는 참조키는 ONLY 예약어가 없어야 함" + +#: commands/tablecmds.c:7342 +#, c-format +msgid "cannot add NOT VALID foreign key to relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì— NOT VALID 참조키를 추가 í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:7344 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "ì´ ê¸°ëŠ¥ì€ íŒŒí‹°ì…˜ ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œëŠ” ì•„ì§ ì§€ì›í•˜ì§€ 않습니다." + +#: commands/tablecmds.c:7350 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr "ì°¸ì¡°ëœ \"%s\" 릴레ì´ì…˜ì€ í…Œì´ë¸”ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/tablecmds.c:7373 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "ì˜êµ¬ 저장용 í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì˜êµ¬ 저장용 í…Œì´ë¸”ì„ ì°¸ì¡° 합니다." + +#: commands/tablecmds.c:7380 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "unlogged í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì˜êµ¬ 저장용 í…Œì´ë¸” ë˜ëŠ” unlogged í…Œì´ë¸”ì„ ì°¸ì¡°í•©ë‹ˆë‹¤." + +#: commands/tablecmds.c:7386 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "임시 í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ìž„ì‹œ í…Œì´ë¸”ì— ëŒ€í•´ì„œë§Œ 참조할 것입니다." -#: commands/tablecmds.c:6314 +#: commands/tablecmds.c:7390 #, c-format -msgid "" -"constraints on temporary tables must involve temporary tables of this session" -msgstr "" -"임시 í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì´ ì„¸ì…˜ìš© 임시 í…Œì´ë¸”ì— ëŒ€í•´ì„œë§Œ ì ìš© ë©ë‹ˆë‹¤." +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "임시 í…Œì´ë¸”ì˜ ì œì•½ ì¡°ê±´ì€ ì´ ì„¸ì…˜ìš© 임시 í…Œì´ë¸”ì— ëŒ€í•´ì„œë§Œ ì ìš© ë©ë‹ˆë‹¤." -#: commands/tablecmds.c:6375 +#: commands/tablecmds.c:7450 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "참조키(foreign key) disagree를 위한 참조하는, ë˜ëŠ” 참조ë˜ëŠ” ì—´ 수" -#: commands/tablecmds.c:6482 +#: commands/tablecmds.c:7557 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "\"%s\" 참조키(foreign key) 제약 ì¡°ê±´ì€ êµ¬í˜„ë˜ì–´ì§ˆ 수 없습니다" -#: commands/tablecmds.c:6485 +#: commands/tablecmds.c:7560 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." -msgstr "" -"\"%s\" ì—´ê³¼ \"%s\" ì—´ ì¸ë±ìŠ¤ëŠ” 함께 사용할 수 없는 ìžë£Œí˜•입니다: %s and %s." +msgstr "\"%s\" ì—´ê³¼ \"%s\" ì—´ ì¸ë±ìŠ¤ëŠ” 함께 사용할 수 없는 ìžë£Œí˜•입니다: %s and %s." -#: commands/tablecmds.c:6692 commands/tablecmds.c:6860 -#: commands/tablecmds.c:7763 commands/tablecmds.c:7819 +#: commands/tablecmds.c:7803 commands/tablecmds.c:7968 +#: commands/tablecmds.c:8917 commands/tablecmds.c:8981 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "\"%s\" 제약 ì¡°ê±´ì´ \"%s\" 릴레ì´ì…˜ì— 없습니다." -#: commands/tablecmds.c:6698 +#: commands/tablecmds.c:7810 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "\"%s\" 제약 ì¡°ê±´(해당 í…Œì´ë¸”: \"%s\")ì€ ì°¸ì¡°í‚¤ ì œì•½ì¡°ê±´ì´ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:6867 +#: commands/tablecmds.c:7976 #, c-format -msgid "" -"constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" -msgstr "" -"\"%s\" 제약 ì¡°ê±´(해당 í…Œì´ë¸”: \"%s\")ì€ ì°¸ì¡°í‚¤ë„ ì²´í¬ ì œì•½ ì¡°ê±´ë„ ì•„ë‹™ë‹ˆë‹¤." +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "\"%s\" 제약 ì¡°ê±´(해당 í…Œì´ë¸”: \"%s\")ì€ ì°¸ì¡°í‚¤ë„ ì²´í¬ ì œì•½ ì¡°ê±´ë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:6935 +#: commands/tablecmds.c:8046 #, c-format msgid "constraint must be validated on child tables too" msgstr "하위 í…Œì´ë¸”ì—ë„ ì œì•½ ì¡°ê±´ì´ ìœ íš¨í•´ì•¼ 함" -#: commands/tablecmds.c:7004 +#: commands/tablecmds.c:8114 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" -msgstr "참조키(foreign key) 제약 ì¡°ê±´ì—서 참조하는 \"%s\" ì—´ì´ ì—†ìŒ" +msgstr "참조키(foreign key) 제약 ì¡°ê±´ì—서 참조하는 \"%s\" ì¹¼ëŸ¼ì´ ì—†ìŒ" -#: commands/tablecmds.c:7009 +#: commands/tablecmds.c:8119 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "참조키(foreign key)ì—서 %d 키 개수보다 ë§Žì´ ê°€ì§ˆ 수 ì—†ìŒ" -#: commands/tablecmds.c:7074 +#: commands/tablecmds.c:8184 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "참조ë˜ëŠ” \"%s\" í…Œì´ë¸”ì˜ ì§€ì—° 가능한 기본키를 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:7091 +#: commands/tablecmds.c:8201 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "참조ë˜ëŠ” \"%s\" í…Œì´ë¸”ì—는 기본키(primary key)ê°€ 없습니다" -#: commands/tablecmds.c:7156 +#: commands/tablecmds.c:8266 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "ì°¸ì¡°í‚¤ì˜ ì°¸ì¡° 칼럼 목ë¡ì— ì¹¼ëŸ¼ì´ ì¤‘ë³µë˜ë©´ 안ë©ë‹ˆë‹¤" -#: commands/tablecmds.c:7250 +#: commands/tablecmds.c:8360 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "참조ë˜ëŠ” \"%s\" í…Œì´ë¸”ì˜ ì§€ì—° 가능한 ìœ ë‹ˆí¬ ì œì•½ ì¡°ê±´ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/tablecmds.c:7255 +#: commands/tablecmds.c:8365 #, c-format -msgid "" -"there is no unique constraint matching given keys for referenced table \"%s\"" -msgstr "" -"참조ë˜ëŠ” \"%s\" í…Œì´ë¸”ì„ ìœ„í•œ 주워진 키와 ì¼ì¹˜í•˜ëŠ” 고유 제약 ì¡°ê±´ì´ ì—†ìŠµë‹ˆë‹¤" +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "참조ë˜ëŠ” \"%s\" í…Œì´ë¸”ì„ ìœ„í•œ 주워진 키와 ì¼ì¹˜í•˜ëŠ” 고유 제약 ì¡°ê±´ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:7418 +#: commands/tablecmds.c:8536 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "\"%s\" 참조키 제약 ì¡°ê±´ 검사 중" -#: commands/tablecmds.c:7717 +#: commands/tablecmds.c:8874 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "ìƒì†ëœ \"%s\" 제약 ì¡°ê±´(해당 í…Œì´ë¸”: \"%s\")ì„ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/tablecmds.c:7769 +#: commands/tablecmds.c:8923 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "\"%s\" 제약 ì¡°ê±´(해당 í…Œì´ë¸”: \"%s\")ì´ ì—†ìŒ, 건너뜀" -#: commands/tablecmds.c:7908 +#: commands/tablecmds.c:9073 #, c-format msgid "cannot alter column type of typed table" msgstr "typed í…Œì´ë¸”ì˜ ì¹¼ëŸ¼ ìžë£Œí˜•ì€ ë³€ê²½í•  수 ì—†ìŒ" -#: commands/tablecmds.c:7931 +#: commands/tablecmds.c:9096 #, c-format msgid "cannot alter inherited column \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ì—´ì€ ìƒì† ë°›ì€ ì—´ìž…ë‹ˆë‹¤, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì€ ìƒì† ë°›ì€ ì¹¼ëŸ¼ìž…ë‹ˆë‹¤, ì´ë¦„ì„ ë°”ê¿€ 수 없습니다" -#: commands/tablecmds.c:7980 +#: commands/tablecmds.c:9107 #, c-format -msgid "" -"result of USING clause for column \"%s\" cannot be cast automatically to " -"type %s" -msgstr "" -"\"%s\" 칼럼ì—서 ì“°ì¸ USING ì ˆì˜ ê²°ê³¼ê°€ %s ìžë£Œí˜•으로 ìžë™ í˜•ë³€í™˜ì„ í•  수 ì—†ìŒ" +msgid "cannot alter type of column named in partition key" +msgstr "파티션 키로 사용ë˜ëŠ” ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì€ ë°”ê¿€ 수 ì—†ìŒ" + +#: commands/tablecmds.c:9111 +#, c-format +msgid "cannot alter type of column referenced in partition key expression" +msgstr "파티션 키 표현ì‹ì—서 참조ë˜ëŠ” ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì€ ë°”ê¿€ 수 ì—†ìŒ" -#: commands/tablecmds.c:7983 +#: commands/tablecmds.c:9161 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" 칼럼ì—서 ì“°ì¸ USING ì ˆì˜ ê²°ê³¼ê°€ %s ìžë£Œí˜•으로 ìžë™ í˜•ë³€í™˜ì„ í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:9164 #, c-format msgid "You might need to add an explicit cast." msgstr "ëª…ì‹œì  í˜•ë³€í™˜ì„ í•´ì•¼í•  것 같습니다." -#: commands/tablecmds.c:7987 +#: commands/tablecmds.c:9168 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì„ %s 형으로 형변환할 수 ì—†ìŒ" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:7990 +#: commands/tablecmds.c:9171 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "\"USING %s::%s\" êµ¬ë¬¸ì„ ì¶”ê°€í•´ì•¼ í•  것 같습니다." -#: commands/tablecmds.c:8089 +#: commands/tablecmds.c:9270 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "USING 표현ì‹ì—서 ì „ì²´ 로우 í…Œì´ë¸” 참조를 í¬í•¨í•˜ê³  있습니다." -#: commands/tablecmds.c:8100 +#: commands/tablecmds.c:9281 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" -msgstr "하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì—´ì˜ í˜•ì‹ì„ 바꾸어야 함" +msgstr "하위 í…Œì´ë¸”ì—ì„œë„ ìƒì†ëœ \"%s\" ì¹¼ëŸ¼ì˜ í˜•ì‹ì„ 바꾸어야 함" -#: commands/tablecmds.c:8187 +#: commands/tablecmds.c:9370 #, c-format msgid "cannot alter type of column \"%s\" twice" -msgstr "\"%s\" ì—´ì€ ì‹œìŠ¤í…œ 열입니다. 그래서 ë³€ê²½ë  ìˆ˜ 없습니다" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ì‹œìŠ¤í…œ 칼럼입니다. 그래서 ë³€ê²½ë  ìˆ˜ 없습니다" -#: commands/tablecmds.c:8223 +#: commands/tablecmds.c:9406 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "\"%s\" ì¹¼ëŸ¼ì˜ ê¸°ë³¸ ê°’ì„ %s 형으로 형변환할 수 ì—†ìŒ" -#: commands/tablecmds.c:8349 +#: commands/tablecmds.c:9533 #, c-format msgid "cannot alter type of a column used by a view or rule" -msgstr "ë·° ë˜ëŠ” 규칙ì—서 사용하는 ì—´ì˜ í˜•ì‹ì„ 변경할 수 ì—†ìŒ" +msgstr "ë·° ë˜ëŠ” 규칙ì—서 사용하는 ì¹¼ëŸ¼ì˜ í˜•ì‹ì„ 변경할 수 ì—†ìŒ" -#: commands/tablecmds.c:8350 commands/tablecmds.c:8369 -#: commands/tablecmds.c:8387 +#: commands/tablecmds.c:9534 commands/tablecmds.c:9553 +#: commands/tablecmds.c:9571 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s ì˜ì¡´ëŒ€ìƒ ì—´: \"%s\"" -#: commands/tablecmds.c:8368 +#: commands/tablecmds.c:9552 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "트리거 ì •ì˜ì—서 사용하는 ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì„ ë³€ê²½í•  수 ì—†ìŒ" -#: commands/tablecmds.c:8386 +#: commands/tablecmds.c:9570 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "ì •ì±… ì •ì˜ì—서 사용하는 ì¹¼ëŸ¼ì˜ ìžë£Œí˜•ì„ ë³€ê²½í•  수 ì—†ìŒ" -#: commands/tablecmds.c:9051 +#: commands/tablecmds.c:10300 commands/tablecmds.c:10312 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "\"%s\" ì¸ë±ìŠ¤ì˜ ì†Œìœ ì£¼ë¥¼ 바꿀 수 ì—†ìŒ" -#: commands/tablecmds.c:9053 +#: commands/tablecmds.c:10302 commands/tablecmds.c:10314 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "ëŒ€ì‹ ì— ê·¸ ì¸ë±ìŠ¤ì˜ í•´ë‹¹ í…Œì´ë¸” 소유ìžì„ 변경하세요." -#: commands/tablecmds.c:9069 +#: commands/tablecmds.c:10328 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "\"%s\" ì‹œí€€ìŠ¤ì˜ ì†Œìœ ì£¼ë¥¼ 바꿀 수 ì—†ìŒ" -#: commands/tablecmds.c:9071 commands/tablecmds.c:11543 -#, c-format -msgid "Sequence \"%s\" is linked to table \"%s\"." -msgstr "\"%s\" 시퀀스는 \"%s\" í…Œì´ë¸”ì— ì¢…ì†ë˜ì–´ 있습니다." - -#: commands/tablecmds.c:9083 commands/tablecmds.c:12190 +#: commands/tablecmds.c:10342 commands/tablecmds.c:13544 #, c-format msgid "Use ALTER TYPE instead." msgstr "대신 ALTER TYPEì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: commands/tablecmds.c:9092 +#: commands/tablecmds.c:10351 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, ë·°, 시퀀스, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" +msgstr "\"%s\" 개체는 í…Œì´ë¸”, ë·°, 시퀀스, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:9435 +#: commands/tablecmds.c:10695 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "SET TABLESPACE êµ¬ë¬¸ì´ ì¤‘ë³µ 사용ë˜ì—ˆìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:9508 +#: commands/tablecmds.c:10770 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" -msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ, TOAST í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™" -"니다." +msgstr "\"%s\" 개체는 í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, ì¸ë±ìФ, TOAST í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤." -#: commands/tablecmds.c:9541 commands/view.c:498 +#: commands/tablecmds.c:10803 commands/view.c:504 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" -msgstr "" -"WITH CHECK OPTION ì˜µì…˜ì€ ìžë™ 갱신 가능한 ë·°ì— ëŒ€í•´ì„œë§Œ 사용할 수 있습니다" +msgstr "WITH CHECK OPTION ì˜µì…˜ì€ ìžë™ 갱신 가능한 ë·°ì— ëŒ€í•´ì„œë§Œ 사용할 수 있습니다" -#: commands/tablecmds.c:9687 +#: commands/tablecmds.c:10945 #, c-format msgid "cannot move system relation \"%s\"" msgstr "\"%s\" 시스템 릴레ì´ì…˜ìž…니다. ì´ë™í•  수 없습니다" -#: commands/tablecmds.c:9703 +#: commands/tablecmds.c:10961 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ë“¤ì€ ì´ë™í•  수 없습니다" -#: commands/tablecmds.c:9840 +#: commands/tablecmds.c:11097 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "í…Œì´ë¸”스페ì´ìŠ¤ì— í…Œì´ë¸”ê³¼ ì¸ë±ìŠ¤ì™€ êµ¬ì²´í™”ëœ ë·°ë§Œ 있습니다." -#: commands/tablecmds.c:9852 +#: commands/tablecmds.c:11109 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" -msgstr "" -"해당 ê°ì²´ë¥¼ pg_global í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 옮기거나 ê·¸ 반대로 작업할 수 ì—†ìŒ" +msgstr "해당 개체를 pg_global í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 옮기거나 ê·¸ 반대로 작업할 수 ì—†ìŒ" -#: commands/tablecmds.c:9943 +#: commands/tablecmds.c:11202 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "\"%s.%s\" 릴레ì´ì…˜ì„ 잠글 수 없어 중지 중입니다" -#: commands/tablecmds.c:9959 +#: commands/tablecmds.c:11218 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "ê²€ìƒ‰ì¡°ê±´ì— ì¼ì¹˜í•˜ëŠ” 릴레ì´ì…˜ì´ \"%s\" í…Œì´ë¸”스페ì´ìŠ¤ì— ì—†ìŒ" -#: commands/tablecmds.c:10033 storage/buffer/bufmgr.c:915 +#: commands/tablecmds.c:11285 storage/buffer/bufmgr.c:915 #, c-format msgid "invalid page in block %u of relation %s" msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì— ìž˜ëª»ëœ íŽ˜ì´ì§€ê°€ 있ìŒ" -#: commands/tablecmds.c:10115 +#: commands/tablecmds.c:11365 #, c-format msgid "cannot change inheritance of typed table" msgstr "typed í…Œì´ë¸”ì˜ ìƒì† 정보는 변경할 수 ì—†ìŒ" -#: commands/tablecmds.c:10165 +#: commands/tablecmds.c:11370 commands/tablecmds.c:11913 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "파티션 í…Œì´ë¸”ì˜ ìƒì† 정보는 바꿀 수 ì—†ìŒ" + +#: commands/tablecmds.c:11375 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì˜ ìƒì† 정보는 바꿀 수 ì—†ìŒ" + +#: commands/tablecmds.c:11421 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì„ ìƒì†í•  수 ì—†ìŒ" -#: commands/tablecmds.c:10219 +#: commands/tablecmds.c:11434 +#, c-format +msgid "cannot inherit from a partition" +msgstr "파티션 í…Œì´ë¸”ì—서 ìƒì† í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:11456 commands/tablecmds.c:14123 #, c-format msgid "circular inheritance not allowed" msgstr "순환 ë˜ëŠ” ìƒì†ì€ 허용하지 않습니다" -#: commands/tablecmds.c:10220 +#: commands/tablecmds.c:11457 commands/tablecmds.c:14124 #, c-format msgid "\"%s\" is already a child of \"%s\"." -msgstr "\"%s\" ê°ì²´ëŠ” ì´ë¯¸ \"%s\" ê°ì²´ë¡œë¶€í„° ìƒì†ë°›ì€ ìƒíƒœìž…니다." +msgstr "\"%s\" 개체는 ì´ë¯¸ \"%s\" 개체로부터 ìƒì†ë°›ì€ ìƒíƒœìž…니다." -#: commands/tablecmds.c:10228 +#: commands/tablecmds.c:11465 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +msgstr "\"%s\" í…Œì´ë¸”ì´ OID ì—´ ì—†ì´ OID 있는 \"%s\" í…Œì´ë¸”ì—서 ìƒì† ë  ìˆ˜ 없습니다." + +#: commands/tablecmds.c:11478 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "\"%s\" 트리거(해당 í…Œì´ë¸” \"%s\")ì€ í•˜ìœ„í…Œì´ë¸” ìƒì†ê³¼ 관련ë˜ì–´ 보호ë˜ê³  있습니다." + +#: commands/tablecmds.c:11480 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" msgstr "" -"\"%s\" í…Œì´ë¸”ì´ OID ì—´ ì—†ì´ OID 있는 \"%s\" í…Œì´ë¸”ì—서 ìƒì† ë  ìˆ˜ 없습니다." -#: commands/tablecmds.c:10369 +#: commands/tablecmds.c:11683 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" -msgstr "ìžì‹ í…Œì´ë¸”ì˜ \"%s\" ì—´ì€ NOT NULL ì†ì„±ì´ 있어야합니다" +msgstr "ìžì‹ í…Œì´ë¸”ì˜ \"%s\" ì¹¼ëŸ¼ì€ NOT NULL ì†ì„±ì´ 있어야합니다" -#: commands/tablecmds.c:10385 commands/tablecmds.c:10418 +#: commands/tablecmds.c:11710 commands/tablecmds.c:11749 #, c-format msgid "child table is missing column \"%s\"" -msgstr "ìžì‹ í…Œì´ë¸”ì—는 \"%s\" ì—´ì´ ì—†ìŠµë‹ˆë‹¤" +msgstr "ìžì‹ í…Œì´ë¸”ì—는 \"%s\" ì¹¼ëŸ¼ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:10501 +#: commands/tablecmds.c:11837 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "\"%s\" 하위 í…Œì´ë¸”ì— \"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ì— ëŒ€í•œ 다른 ì •ì˜ê°€ 있ìŒ" -#: commands/tablecmds.c:10509 +#: commands/tablecmds.c:11845 #, c-format -msgid "" -"constraint \"%s\" conflicts with non-inherited constraint on child table \"%s" -"\"" -msgstr "" -"\"%s\" 제약 ì¡°ê±´ì´ \"%s\" 하위 í…Œì´ë¸”ì— ìžˆëŠ” 비 ìƒì† 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤" +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ \"%s\" 하위 í…Œì´ë¸”ì— ìžˆëŠ” 비 ìƒì† 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:10520 +#: commands/tablecmds.c:11856 #, c-format -msgid "" -"constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" -msgstr "" -"\"%s\" 제약 ì¡°ê±´ì´ \"%s\" 하위 í…Œì´ë¸”ì— ìžˆëŠ” NOT VALID 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤" +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "\"%s\" 제약 ì¡°ê±´ì´ \"%s\" 하위 í…Œì´ë¸”ì— ìžˆëŠ” NOT VALID 제약 ì¡°ê±´ê³¼ ì¶©ëŒí•©ë‹ˆë‹¤" -#: commands/tablecmds.c:10544 +#: commands/tablecmds.c:11891 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "ìžì‹ í…Œì´ë¸”ì— \"%s\" 제약 ì¡°ê±´ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:10628 +#: commands/tablecmds.c:11980 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì€ \"%s\" 릴레ì´ì…˜ì˜ íŒŒí‹°ì…˜ì´ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/tablecmds.c:11986 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì€ \"%s\" 릴레ì´ì…˜ì˜ 부모가 아닙니다" -#: commands/tablecmds.c:10862 +#: commands/tablecmds.c:12212 #, c-format msgid "typed tables cannot inherit" msgstr "typed í…Œì´ë¸”ì€ ìƒì†í•  수 ì—†ìŒ" -#: commands/tablecmds.c:10893 +#: commands/tablecmds.c:12243 #, c-format msgid "table is missing column \"%s\"" msgstr "í…Œì´ë¸”ì—는 \"%s\" ì¹¼ëŸ¼ì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/tablecmds.c:10903 +#: commands/tablecmds.c:12254 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "\"%s\" ì¹¼ëŸ¼ì€ \"%s\" ìžë£Œí˜•입니다." -#: commands/tablecmds.c:10912 +#: commands/tablecmds.c:12263 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "\"%s\" í…Œì´ë¸”ì˜ \"%s\" 칼럼 ìžë£Œí˜• 틀립니다" -#: commands/tablecmds.c:10925 +#: commands/tablecmds.c:12277 #, c-format msgid "table has extra column \"%s\"" msgstr "\"%s\" ì¹¼ëŸ¼ì€ í™•ìž¥í˜•ìž…ë‹ˆë‹¤" -#: commands/tablecmds.c:10977 +#: commands/tablecmds.c:12329 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\" í…Œì´ë¸”ì€ typed í…Œì´ë¸”ì´ ì•„ë‹™ë‹ˆë‹¤" -#: commands/tablecmds.c:11161 +#: commands/tablecmds.c:12511 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” ìœ ë‹ˆí¬ ì¸ë±ìŠ¤ê°€ 아니여서, 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:11167 +#: commands/tablecmds.c:12517 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "\"%s\" non-immediate ì¸ë±ìŠ¤ëŠ” 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:11173 +#: commands/tablecmds.c:12523 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” expression ì¸ë±ìŠ¤ì—¬ì„œ, 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:11179 +#: commands/tablecmds.c:12529 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "\"%s\" ì¸ë±ìŠ¤ê°€ 부분ì¸ë±ìŠ¤ì—¬ì„œ, 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:11185 +#: commands/tablecmds.c:12535 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" -msgstr "" -"\"%s\" ì¸ë±ìŠ¤ëŠ” 사용할 수 없는 ì¸ë±ìŠ¤ì—¬ì„œ, 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 사용할 수 없는 ì¸ë±ìŠ¤ì—¬ì„œ, 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ" -#: commands/tablecmds.c:11206 +#: commands/tablecmds.c:12556 #, c-format -msgid "" -"index \"%s\" cannot be used as replica identity because column %d is a " -"system column" -msgstr "" -"\"%s\" ì¸ë±ìŠ¤ëŠ” 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ, %d 번째 ì¹¼ëŸ¼ì´ ì‹œìŠ¤í…œ 칼럼임" +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ, %d 번째 ì¹¼ëŸ¼ì´ ì‹œìŠ¤í…œ 칼럼임" -#: commands/tablecmds.c:11213 +#: commands/tablecmds.c:12563 #, c-format -msgid "" -"index \"%s\" cannot be used as replica identity because column \"%s\" is " -"nullable" -msgstr "" -"\"%s\" ì¸ë±ìŠ¤ëŠ” 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ, \"%s\" ì¹¼ëŸ¼ì´ null ê°’ 사용가능 " -"ì†ì„±ìž„" +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 복제 ì‹ë³„ìžë¡œ 사용할 수 ì—†ìŒ, \"%s\" ì¹¼ëŸ¼ì´ null ê°’ 사용가능 ì†ì„±ìž„" -#: commands/tablecmds.c:11416 +#: commands/tablecmds.c:12756 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "\"%s\" í…Œì´ë¸”ì€ ìž„ì‹œ í…Œì´ë¸”ì´ê¸°ì—, 통계 정보를 변경 í•  수 ì—†ìŒ" -#: commands/tablecmds.c:11475 +#: commands/tablecmds.c:12780 #, c-format -msgid "" -"could not change table \"%s\" to logged because it references unlogged table " -"\"%s\"" -msgstr "" -"\"%s\" í…Œì´ë¸”ì´ \"%s\" unlogged í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ê³  있어 logged ì†ì„±ìœ¼ë¡œ 바꿀 " -"수 ì—†ìŒ" +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "\"%s\" í…Œì´ë¸”ì€ ë°œìƒì— 사용하고 있어, unlogged ì†ì„±ìœ¼ë¡œ 바꿀 수 ì—†ìŒ" -#: commands/tablecmds.c:11485 +#: commands/tablecmds.c:12782 #, c-format -msgid "" -"could not change table \"%s\" to unlogged because it references logged table " -"\"%s\"" -msgstr "" -"\"%s\" í…Œì´ë¸”ì´ \"%s\" logged í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ê³  있어 unlogged ì†ì„±ìœ¼ë¡œ 바꿀 " -"수 ì—†ìŒ" +msgid "Unlogged relations cannot be replicated." +msgstr "unlogged 릴레ì´ì…˜ 복제할 수 없습니다." + +#: commands/tablecmds.c:12827 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì´ \"%s\" unlogged í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ê³  있어 logged ì†ì„±ìœ¼ë¡œ 바꿀 수 ì—†ìŒ" -#: commands/tablecmds.c:11542 +#: commands/tablecmds.c:12837 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì´ \"%s\" logged í…Œì´ë¸”ì„ ì°¸ì¡°í•˜ê³  있어 unlogged ì†ì„±ìœ¼ë¡œ 바꿀 수 ì—†ìŒ" + +#: commands/tablecmds.c:12895 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "ì†Œìœ ëœ ì‹œí€€ìŠ¤ë¥¼ 다른 스키마로 ì´ë™í•  수 ì—†ìŒ" -#: commands/tablecmds.c:11647 +#: commands/tablecmds.c:13001 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì´ \"%s\" ìŠ¤í‚¤ë§ˆì— ì´ë¯¸ 있습니다" -#: commands/tablecmds.c:12174 +#: commands/tablecmds.c:13527 #, c-format msgid "\"%s\" is not a composite type" -msgstr "\"%s\" ê°ì²´ëŠ” 복합 ìžë£Œí˜•입니다" +msgstr "\"%s\" 개체는 복합 ìžë£Œí˜•입니다" -#: commands/tablecmds.c:12204 +#: commands/tablecmds.c:13559 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "\"%s\" 개체는 í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, 시퀀스, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™ë‹ˆë‹¤" + +#: commands/tablecmds.c:13594 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "알 수 없는 파티션 규칙 \"%s\"" + +#: commands/tablecmds.c:13602 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "둘 ì´ìƒì˜ ì¹¼ëŸ¼ì„ ì‚¬ìš©í•  \"list\" íŒŒí‹°ì…˜ì€ ì‚¬ìš©í•  수 없습니다" + +#: commands/tablecmds.c:13667 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "\"%s\" ì¹¼ëŸ¼ì´ íŒŒí‹°ì…˜ 키로 사용ë˜ê³  있지 않습니다" + +#: commands/tablecmds.c:13674 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ì‹œìŠ¤í…œ 칼럼입니다. 그래서 파티션 키로 ì‚¬ìš©ë  ìˆ˜ 없습니다" + +#: commands/tablecmds.c:13737 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "파티션 키로 사용할 함수는 IMMUTABLE íŠ¹ì„±ì´ ìžˆì–´ì•¼í•©ë‹ˆë‹¤" + +#: commands/tablecmds.c:13754 +#, c-format +msgid "partition key expressions cannot contain whole-row references" +msgstr "파티션 키 표현ì‹ì—서 ì „ì²´ 로우 참조를 í¬í•¨í•  수 없습니다" + +#: commands/tablecmds.c:13761 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "파티션 키 표현ì‹ì—서는 시스템 칼럼 참조를 í¬í•¨í•  수 없습니다" + +#: commands/tablecmds.c:13771 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "파티션 키로 ìƒìˆ˜ëŠ” 쓸 수 없습니다" + +#: commands/tablecmds.c:13792 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "파티션 표현ì‹ì— 쓸 ë¬¸ìž ì •ë ¬ ê·œì¹™ì„ ê²°ì •í•  수 없습니다" + +#: commands/tablecmds.c:13825 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "%s ìžë£Œí˜•ìš© 기본 해시 ì—°ì‚°ìž í´ëž˜ìŠ¤ê°€ 없습니다" + +#: commands/tablecmds.c:13827 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "해당 ìžë£Œí˜•ì„ ìœ„í•œ 해시 ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ 지정하거나 기본 해시 ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•´ ë‘어야합니다" + +#: commands/tablecmds.c:13831 +#, c-format +msgid "data type %s has no default btree operator class" +msgstr "%s ìžë£Œí˜•ì€ ê¸°ë³¸ btree ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•˜ì§€ 않았습니다" + +#: commands/tablecmds.c:13833 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "해당 ìžë£Œí˜•ì„ ìœ„í•œ btree ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ 지정하거나 기본 btree ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ ì •ì˜í•´ ë‘어야합니다" + +#: commands/tablecmds.c:13958 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "" + +#: commands/tablecmds.c:13962 partitioning/partbounds.c:621 +#: partitioning/partbounds.c:666 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "" + +#: commands/tablecmds.c:14063 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" ì´ë¦„ì˜ íŒŒí‹°ì…˜ í…Œì´ë¸”ì´ ì´ë¯¸ 있습니다" + +#: commands/tablecmds.c:14069 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "파티션 í…Œì´ë¸”로 typed í…Œì´ë¸”ì„ ì¶”ê°€í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:14085 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "파티션 í…Œì´ë¸”로 ìƒì†ì„ ì´ìš©í•œ 하위 í…Œì´ë¸”ì„ ì¶”ê°€í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:14099 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "파티션 í…Œì´ë¸”로 ìƒì†ìš© ìƒìœ„ í…Œì´ë¸”ì„ ì¶”ê°€í•  수 ì—†ìŒ" + +#: commands/tablecmds.c:14133 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì€ ì¼ë°˜ í…Œì´ë¸”입니다, 임시 파티션 í…Œì´ë¸”ì„ ì¶”ê°€í•  수 없습니다" + +#: commands/tablecmds.c:14141 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì€ ìž„ì‹œ í…Œì´ë¸”입니다, ì¼ë°˜ 파티션 í…Œì´ë¸”ì„ ì¶”ê°€í•  수 없습니다" + +#: commands/tablecmds.c:14149 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì„ íŒŒí‹°ì…˜ í…Œì´ë¸”로 추가할 수 없습니다" + +#: commands/tablecmds.c:14156 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì„ íŒŒí‹°ì…˜ í…Œì´ë¸”로 추가할 수 없습니다" + +#: commands/tablecmds.c:14162 +#, c-format +msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +msgstr "without oids \"%s\" í…Œì´ë¸”ì´ with oids \"%s\" 파티션 í…Œì´ë¸”로 추가할 수 ì—†ìŒ" + +#: commands/tablecmds.c:14170 +#, c-format +msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" +msgstr "with oids \"%s\" í…Œì´ë¸”ì´ without oids \"%s\" 파티션 í…Œì´ë¸”로 추가할 수 ì—†ìŒ" + +#: commands/tablecmds.c:14192 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì˜ \"%s\" ì¹¼ëŸ¼ì´ ìƒìœ„ í…Œì´ë¸”ì¸ \"%s\"ì— ì—†ìŒ" + +#: commands/tablecmds.c:14195 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "새 파티션 í…Œì´ë¸”ì€ ìƒìœ„ í…Œì´ë¸”ì˜ ì¹¼ëŸ¼ê³¼ ë™ì¼í•´ì•¼ 합니다." + +#: commands/tablecmds.c:14207 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "\"%s\" 트리거가 \"%s\" í…Œì´ë¸”ì— ìžˆì–´ 파티션 í…Œì´ë¸”로 í¬í•¨ ë  ìˆ˜ 없습니다" + +#: commands/tablecmds.c:14209 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "ROW íŠ¸ë¦¬ê±°ë“¤ì´ ìžˆëŠ” í…Œì´ë¸”ì„ íŒŒí‹°ì…˜ í…Œì´ë¸”로 í¬í•¨í•˜ëŠ” ê¸°ëŠ¥ì€ ì§€ì›í•˜ì§€ 않습니다" + +#: commands/tablecmds.c:14842 commands/tablecmds.c:14861 +#: commands/tablecmds.c:14883 commands/tablecmds.c:14902 +#: commands/tablecmds.c:14958 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "\"%s\" ì¸ë±ìŠ¤ë¥¼ \"%s\" ì¸ë±ìŠ¤ì˜ íŒŒí‹°ì…˜ìœ¼ë¡œ 추가할 수 ì—†ìŒ" + +#: commands/tablecmds.c:14845 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” ì´ë¯¸ 다른 ì¸ë±ìŠ¤ì— ì¶”ê°€ë˜ì–´ 있ìŒ." + +#: commands/tablecmds.c:14864 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” \"%s\" í…Œì´ë¸”ì˜ í•˜ìœ„ 파티션 ëŒ€ìƒ ì¸ë±ìŠ¤ê°€ 아닙니다." + +#: commands/tablecmds.c:14886 +#, c-format +msgid "The index definitions do not match." +msgstr "ì¸ë±ìФ ì •ì˜ê°€ ì¼ì¹˜í•˜ì§€ 않습니다." + +#: commands/tablecmds.c:14905 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." msgstr "" -"\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”, ë·°, êµ¬ì²´í™”ëœ ë·°, 시퀀스, 외부 í…Œì´ë¸” ê·¸ ì–´ëŠ ê²ƒë„ ì•„ë‹™" -"니다" -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:625 replication/slot.c:980 storage/file/copydir.c:47 +#: commands/tablecmds.c:14961 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "\"%s\" 파티션 용으로 다른 ì¸ë±ìŠ¤ê°€ 추가ë˜ì–´ 있습니다." + +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:625 replication/slot.c:1194 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "\"%s\" 디렉터리를 만들 수 ì—†ìŒ: %m" -#: commands/tablespace.c:209 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "\"%s\" 디렉터리 ìƒíƒœë¥¼ 파악할 수 ì—†ìŒ: %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "\"%s\" 파ì¼ì´ 존재하지만 디렉터리가 아닙니다" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "\"%s\" í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 만들 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "í…Œì´ë¸”스페ì´ìŠ¤ëŠ” 슈í¼ìœ ì €ë§Œ 만들 수 있습니다." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "í…Œì´ë¸”스페ì´ìФ 위치ì—는 ìž‘ì€ ë”°ì˜´í‘œë¥¼ 사용할 수 ì—†ìŒ" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "í…Œì´ë¸”스페ì´ìФ 경로는 절대경로여야합니다" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "í…Œì´ë¸”스페ì´ìФ 경로가 너무 ê¹ë‹ˆë‹¤: \"%s\"" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" -msgstr "í…Œì´ë¸”스페ì´ìФ 경로는 ë°ì´í„° 디렉토리 ì•ˆì— ìžˆìœ¼ë©´ 안ë©ë‹ˆë‹¤" +msgstr "í…Œì´ë¸”스페ì´ìФ 경로는 ë°ì´í„° 디렉터리 ì•ˆì— ìžˆìœ¼ë©´ 안ë©ë‹ˆë‹¤" -#: commands/tablespace.c:304 commands/tablespace.c:952 +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "\"%s\" í…Œì´ë¸”스페ì´ìФ ì´ë¦„ì€ ì ë‹¹ì¹˜ 않습니다" -#: commands/tablespace.c:306 commands/tablespace.c:953 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "\"pg_\" 문ìžë¡œ 시작하는 í…Œì´ë¸”스페ì´ìŠ¤ëŠ” 시스템 í…Œì´ë¸”스페ì´ìŠ¤ìž…ë‹ˆë‹¤." -#: commands/tablespace.c:316 commands/tablespace.c:965 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ í…Œì´ë¸”스페ì´ìŠ¤ëŠ” ì´ë¯¸ 있ìŒ" #: commands/tablespace.c:430 commands/tablespace.c:935 -#: commands/tablespace.c:1016 commands/tablespace.c:1085 -#: commands/tablespace.c:1218 commands/tablespace.c:1418 +#: commands/tablespace.c:1015 commands/tablespace.c:1083 +#: commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "\"%s\" í…Œì´ë¸”스페ì´ìФ ì—†ìŒ" @@ -9338,8 +9754,16 @@ msgstr "\"%s\" 디렉터리 액세스 ê¶Œí•œì„ ì§€ì •í•  수 ì—†ìŒ: %m" msgid "directory \"%s\" already in use as a tablespace" msgstr "\"%s\" 디렉터리는 ì´ë¯¸ í…Œì´ë¸”스페ì´ìŠ¤ë¡œ 사용 중임" +#: commands/tablespace.c:705 commands/tablespace.c:715 +#: postmaster/postmaster.c:1476 storage/file/fd.c:2680 +#: storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 +#: utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %m" + #: commands/tablespace.c:744 commands/tablespace.c:757 -#: commands/tablespace.c:793 commands/tablespace.c:885 +#: commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3110 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "\"%s\" 디렉터리를 삭제할 수 ì—†ìŒ: %m" @@ -9354,197 +9778,271 @@ msgstr "\"%s\" 심벌릭 ë§í¬ë¥¼ 삭제할 수 ì—†ìŒ: %m" msgid "\"%s\" is not a directory or symbolic link" msgstr "\"%s\" 디렉터리ë„, 심볼릭 ë§í¬ë„ 아님" -#: commands/tablespace.c:1090 +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "\"%s\" í…Œì´ë¸”스페ì´ìФ ì—†ìŒ" -#: commands/tablespace.c:1517 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "%u OID í…Œì´ë¸”스페ì´ìŠ¤ìš© 디렉터리는 ì‚­ì œë  ìˆ˜ ì—†ìŒ" -#: commands/tablespace.c:1519 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "필요하다면 OS 작업으로 ê·¸ 디레터리를 삭제하세요" -#: commands/trigger.c:184 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" -msgstr "\"%s\" ê°ì²´ëŠ” í…Œì´ë¸”입니다." +msgstr "\"%s\" 개체는 í…Œì´ë¸”입니다." -#: commands/trigger.c:186 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "í…Œì´ë¸”ì— INSTEAD OF 트리거는 설정할 수 ì—†ìŒ" -#: commands/trigger.c:197 commands/trigger.c:204 +#: commands/trigger.c:237 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì€ BEFORE / FOR EACH ROW 트리거를 사용할 수 ì—†ìŒ" + +#: commands/trigger.c:255 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì— ì§€ì •ëœ íŠ¸ë¦¬ê±°ëŠ” 전달 í…Œì´ë¸”ì„ ê°€ì§ˆ 수 ì—†ìŒ." + +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" -msgstr "\"%s\" ê°ì²´ëŠ” 뷰입니다." +msgstr "\"%s\" 개체는 뷰입니다." -#: commands/trigger.c:199 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "ë·°ì— ë¡œìš° 단위 BEFORE, AFTER 트리거는 설정할 수 ì—†ìŒ" -#: commands/trigger.c:206 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "ë·°ì— TRUNCATE 트리거는 설정할 수 ì—†ìŒ" -#: commands/trigger.c:214 commands/trigger.c:221 commands/trigger.c:228 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 +#: commands/trigger.c:437 #, c-format msgid "\"%s\" is a foreign table" -msgstr "\"%s\" ê°ì²´ëŠ” 외부 í…Œì´ë¸”입니다." +msgstr "\"%s\" 개체는 외부 í…Œì´ë¸”입니다." -#: commands/trigger.c:216 +#: commands/trigger.c:286 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "외부테ì´ë¸”ì— INSTEAD OF 트리거는 설정할 수 ì—†ìŒ" -#: commands/trigger.c:223 +#: commands/trigger.c:293 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "외부 í…Œì´ë¸”ì—는 TRUNCATE 트리거를 사용할 수 ì—†ìŒ" -#: commands/trigger.c:230 +#: commands/trigger.c:305 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "외부 í…Œì´ë¸”ì— ì œì•½ ì¡°ê±´ 트리거는 설정할 수 ì—†ìŒ" -#: commands/trigger.c:293 +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "TRUNCATE FOR EACH ROW 트리거는 ì§€ì›ë˜ì§€ 않ìŒ" -#: commands/trigger.c:301 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "INSTEAD OF 트리거는 FOR EACH ROW 옵션으로 설정해야 함" -#: commands/trigger.c:305 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "INSTEAD OF 트리거는 WHEN ì¡°ê±´ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/trigger.c:309 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "INSTEAD OF 트리거는 칼럼 목ë¡ì„ 사용할 수 ì—†ìŒ" -#: commands/trigger.c:366 commands/trigger.c:379 +#: commands/trigger.c:425 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "" + +#: commands/trigger.c:426 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "" + +#: commands/trigger.c:439 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "외부 í…Œì´ë¸”ì˜ íŠ¸ë¦¬ê±°ë“¤ì€ ì „í™˜ í…Œì´ë¸”ì„ ê°€ì§ˆ 수 ì—†ìŒ." + +#: commands/trigger.c:446 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "ë·°ì— ì •ì˜í•œ íŠ¸ë¦¬ê±°ë“¤ì€ ì „í™˜ í…Œì´ë¸”ì„ ê°€ì§ˆ 수 ì—†ìŒ." + +#: commands/trigger.c:466 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "" + +#: commands/trigger.c:472 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "" + +#: commands/trigger.c:477 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "전환 í…Œì´ë¸”ì—서 TRUNCATE 트리거는 ì§€ì›í•˜ì§€ 않습니다" + +#: commands/trigger.c:494 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "전환 í…Œì´ë¸”ì€ í•˜ë‚˜ ì´ìƒì˜ ì´ë²¤íŠ¸ì— ëŒ€í•œ 트리거를 지정할 수 없습니다" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "전환 í…Œì´ë¸”ì€ ì¹¼ëŸ¼ 목ë¡ë“¤ì— 대한 트리거를 지정할 수 없습니다" + +#: commands/trigger.c:522 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "" + +#: commands/trigger.c:527 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "" + +#: commands/trigger.c:542 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "" + +#: commands/trigger.c:552 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "" + +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì—는 칼럼 ê°’ì„ ì°¸ì¡°í•  수는 ì—†ìŒ" -#: commands/trigger.c:371 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "INSERT 트리거ì—ì„œì˜ WHEN ì¡°ê±´ì—는 OLD ê°’ì„ ì°¸ì¡°í•  수 ì—†ìŒ" -#: commands/trigger.c:384 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "DELETE 트리거ì—ì„œì˜ WHEN ì¡°ê±´ì—는 NEW ê°’ì„ ì°¸ì¡°í•  수 ì—†ìŒ" -#: commands/trigger.c:389 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "WHEN ì¡°ê±´ì ˆì´ ìžˆëŠ” BEFORE 트리거는 NEW 시스템 ì¹¼ëŸ¼ì„ ì°¸ì¡°í•  수 ì—†ìŒ" -#: commands/trigger.c:434 -#, c-format -msgid "changing return type of function %s from \"opaque\" to \"trigger\"" -msgstr "%s í•¨ìˆ˜ì˜ ë¦¬í„´ ìžë£Œí˜•ì„ \"opaque\"ì—서 \"trigger\"로 바꿉니다" - -#: commands/trigger.c:553 commands/trigger.c:1303 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "\"%s\" ì´ë¦„ì˜ íŠ¸ë¦¬ê±°ê°€ \"%s\" í…Œì´ë¸”ì— ì´ë¯¸ 있습니다" -#: commands/trigger.c:838 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "ì°¸ì¡°ëœ í…Œì´ë¸”ì˜ UPDATE 트리거를 찾았습니다." -#: commands/trigger.c:839 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "ì°¸ì¡°ëœ í…Œì´ë¸”ì˜ DELETE 트리거를 찾았습니다." -#: commands/trigger.c:840 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "참조 í…Œì´ë¸”ì˜ íŠ¸ë¦¬ê±°ë¥¼ 찾았습니다." -#: commands/trigger.c:949 commands/trigger.c:965 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "\"%s\" %s 제약 ì¡°ê±´ì— ëŒ€í•œ 불완전한 트리거 ê·¸ë£¹ì„ ë¬´ì‹œí•˜ëŠ” 중" -#: commands/trigger.c:977 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "트리거 ê·¸ë£¹ì„ \"%s\" %s 제약 조건으로 변환하는 중" -#: commands/trigger.c:1190 commands/trigger.c:1351 commands/trigger.c:1469 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "\"%s\" 트리거는 \"%s\" í…Œì´ë¸”ì— ì—†ìŒ" -#: commands/trigger.c:1434 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" -msgstr "액세스 권한 ì—†ìŒ: \"%s\" ê°ì²´ëŠ” 시스템 트리거임" +msgstr "액세스 권한 ì—†ìŒ: \"%s\" 개체는 시스템 트리거임" -#: commands/trigger.c:1930 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "%u 트리거 함수가 null ê°’ì„ ë¦¬í„´í–ˆìŠµë‹ˆë‹¤" -#: commands/trigger.c:1989 commands/trigger.c:2188 commands/trigger.c:2392 -#: commands/trigger.c:2664 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 +#: commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "BEFORE STATEMENT 트리거는 ë¦¬í„´ê°’ì´ ìžˆìœ¼ë©´ 안ë©ë‹ˆë‹¤" -#: commands/trigger.c:2726 executor/nodeModifyTable.c:679 -#: executor/nodeModifyTable.c:972 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 +#: executor/nodeModifyTable.c:1244 #, c-format -msgid "" -"tuple to be updated was already modified by an operation triggered by the " -"current command" -msgstr "" -"현재 명령으로 ì‹¤í–‰ëœ íŠ¸ë¦¬ê±° 작업으로 변경해야할 ìžë£Œê°€ ì´ë¯¸ 바뀌었습니다." +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "현재 명령으로 ì‹¤í–‰ëœ íŠ¸ë¦¬ê±° 작업으로 변경해야할 ìžë£Œê°€ ì´ë¯¸ 바뀌었습니다." -#: commands/trigger.c:2727 executor/nodeModifyTable.c:680 -#: executor/nodeModifyTable.c:973 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 +#: executor/nodeModifyTable.c:1245 #, c-format -msgid "" -"Consider using an AFTER trigger instead of a BEFORE trigger to propagate " -"changes to other rows." -msgstr "" -"다른 로우를 변경하는 ì¼ì„ BEFORE 트리거 ëŒ€ì‹ ì— AFTER 트리거 ì‚¬ìš©ì„ ê³ ë ¤í•´ ë³´" -"십시오" +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "다른 로우를 변경하는 ì¼ì„ BEFORE 트리거 ëŒ€ì‹ ì— AFTER 트리거 ì‚¬ìš©ì„ ê³ ë ¤í•´ 보십시오" -#: commands/trigger.c:2741 executor/execMain.c:2379 -#: executor/nodeLockRows.c:216 executor/nodeModifyTable.c:213 -#: executor/nodeModifyTable.c:692 executor/nodeModifyTable.c:985 -#: executor/nodeModifyTable.c:1151 +#: commands/trigger.c:3320 executor/execMain.c:2725 executor/nodeLockRows.c:220 +#: executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 +#: executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" msgstr "ë™ì‹œ ì—…ë°ì´íЏ ë•Œë¬¸ì— ìˆœì°¨ì  ì•¡ì„¸ìŠ¤ê°€ 불가능합니다" -#: commands/trigger.c:4575 +#: commands/trigger.c:3324 executor/execMain.c:2729 executor/execMain.c:2804 +#: executor/nodeLockRows.c:224 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "잠글 íŠœí”Œì€ ë™ì‹œ ì—…ë°ì´íŠ¸ë¡œ 다른 파티션으로 ì´ë¯¸ 옮겨졌ìŒ" + +#: commands/trigger.c:5449 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "\"%s\" 제약 ì¡°ê±´ì€ DEFERRABLE ì†ì„±ìœ¼ë¡œ 만들어지지 않았습니다" -#: commands/trigger.c:4598 +#: commands/trigger.c:5472 #, c-format msgid "constraint \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì œì•½ ì¡°ê±´ì´ ì—†ìŒ" -#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:685 +#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:679 #, c-format msgid "function %s should return type %s" msgstr "%s 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" @@ -9579,703 +10077,711 @@ msgstr "í…스트 검색 파서 end 메서드가 필요함" msgid "text search parser lextypes method is required" msgstr "í…스트 검색 파서 lextypes 메서드가 필요함" -#: commands/tsearchcmds.c:386 +#: commands/tsearchcmds.c:384 #, c-format msgid "text search template \"%s\" does not accept options" msgstr "\"%s\" 전문 검색 í…œí”Œë¦¿ì´ ì˜µì…˜ì„ ìˆ˜ë½í•˜ì§€ 않ìŒ" -#: commands/tsearchcmds.c:460 +#: commands/tsearchcmds.c:458 #, c-format msgid "text search template is required" msgstr "전문 검색 í…œí”Œë¦¿ì´ í•„ìš”í•¨" -#: commands/tsearchcmds.c:752 +#: commands/tsearchcmds.c:746 #, c-format msgid "must be superuser to create text search templates" msgstr "슈í¼ìœ ì €ë§Œ 전문 검색 í…œí”Œë¦¿ì„ ë§Œë“¤ 수 있ìŒ" -#: commands/tsearchcmds.c:789 +#: commands/tsearchcmds.c:783 #, c-format msgid "text search template parameter \"%s\" not recognized" msgstr "\"%s\" 전문 검색 템플릿 매개 변수를 ì¸ì‹í•  수 ì—†ìŒ" -#: commands/tsearchcmds.c:799 +#: commands/tsearchcmds.c:793 #, c-format msgid "text search template lexize method is required" msgstr "전문 검색 템플릿 lexize 메서드가 필요함" -#: commands/tsearchcmds.c:1008 +#: commands/tsearchcmds.c:1000 #, c-format msgid "text search configuration parameter \"%s\" not recognized" msgstr "\"%s\" 전문 검색 구성 매개 변수를 ì¸ì‹í•  수 ì—†ìŒ" -#: commands/tsearchcmds.c:1015 +#: commands/tsearchcmds.c:1007 #, c-format msgid "cannot specify both PARSER and COPY options" msgstr "PARSER 옵션과 COPY ì˜µì…˜ì„ ëª¨ë‘ ì§€ì •í•  수 ì—†ìŒ" -#: commands/tsearchcmds.c:1051 +#: commands/tsearchcmds.c:1043 #, c-format msgid "text search parser is required" msgstr "전문 검색 파서가 필요함" -#: commands/tsearchcmds.c:1278 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "\"%s\" í† í° í˜•ì‹ì´ ì—†ìŒ" -#: commands/tsearchcmds.c:1502 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "\"%s\" í† í° í˜•ì‹ì— 대한 ë§¤í•‘ì´ ì—†ìŒ" -#: commands/tsearchcmds.c:1508 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "\"%s\" í† í° í˜•ì‹ì— 대한 ë§¤í•‘ì´ ì—†ìŒ, 건너뜀" -#: commands/tsearchcmds.c:1663 commands/tsearchcmds.c:1774 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "ìž˜ëª»ëœ ë§¤ê°œ 변수 ëª©ë¡ í˜•ì‹: \"%s\"" -#: commands/typecmds.c:181 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" msgstr "슈í¼ìœ ì €ë§Œ 기본 형ì‹ì„ 만들 수 있ìŒ" -#: commands/typecmds.c:288 commands/typecmds.c:1421 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "ìž˜ëª»ëœ \"%s\" ì†ì„±ì˜ ìžë£Œí˜•" -#: commands/typecmds.c:342 +#: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "\"%s\" í˜•ì‹ ë²”ì£¼ê°€ 잘못ë¨: 단순 ASCII여야 함" -#: commands/typecmds.c:361 +#: commands/typecmds.c:362 #, c-format msgid "array element type cannot be %s" msgstr "ë°°ì—´ ìš”ì†Œì˜ ìžë£Œí˜•으로 %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" -#: commands/typecmds.c:393 +#: commands/typecmds.c:394 #, c-format msgid "alignment \"%s\" not recognized" msgstr "ìž˜ëª»ëœ ALIGNMENT ê°’: \"%s\"" -#: commands/typecmds.c:410 +#: commands/typecmds.c:411 #, c-format msgid "storage \"%s\" not recognized" msgstr "ìž˜ëª»ëœ STORAGE ê°’: \"%s\"" -#: commands/typecmds.c:421 +#: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" msgstr "ìžë£Œí˜• ìž…ë ¥ 함수를 지정하십시오" -#: commands/typecmds.c:425 +#: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" msgstr "ìžë£Œí˜• 출력 함수를 지정하십시오" -#: commands/typecmds.c:430 +#: commands/typecmds.c:431 #, c-format -msgid "" -"type modifier output function is useless without a type modifier input " -"function" +msgid "type modifier output function is useless without a type modifier input function" msgstr "í˜•ì‹ í•œì •ìž ìž…ë ¥ 함수가 없으면 í˜•ì‹ í•œì •ìž ì¶œë ¥ 함수는 ì˜ë¯¸ê°€ ì—†ìŒ" -#: commands/typecmds.c:453 commands/typecmds.c:470 -#, c-format -msgid "changing return type of function %s from %s to %s" -msgstr "%s í•¨ìˆ˜ì˜ ë°˜í™˜ ìžë£Œí˜•ì„ %sì—서 %s ìžë£Œí˜•으로 바꿉니다" - -#: commands/typecmds.c:460 +#: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" msgstr "ìžë£Œí˜• %s ìž…ë ¥ í•¨ìˆ˜ì˜ %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:477 +#: commands/typecmds.c:478 #, c-format msgid "type output function %s must return type %s" msgstr "%s ìžë£Œí˜• 출력 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:486 +#: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" msgstr "%s ìžë£Œí˜• receive 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:495 +#: commands/typecmds.c:496 #, c-format msgid "type send function %s must return type %s" msgstr "%s ìžë£Œí˜• 전송 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:560 +#: commands/typecmds.c:561 #, c-format msgid "type input function %s should not be volatile" msgstr "%s ìžë£Œí˜• ìž…ë ¥ 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:565 +#: commands/typecmds.c:566 #, c-format msgid "type output function %s should not be volatile" msgstr "%s ìžë£Œí˜• 출력 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:570 +#: commands/typecmds.c:571 #, c-format msgid "type receive function %s should not be volatile" msgstr "%s ìžë£Œí˜• 수신 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:575 +#: commands/typecmds.c:576 #, c-format msgid "type send function %s should not be volatile" msgstr "%s ìžë£Œí˜• 송신 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:580 +#: commands/typecmds.c:581 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "%s ìžë£Œí˜• 형변환 ìž…ë ¥ 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:585 +#: commands/typecmds.c:586 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "%s ìžë£Œí˜• 형변환 출력 함수는 volatile íŠ¹ì„±ì´ ì—†ì–´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:807 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "\"%s\" ìžë£Œí˜•ì€ ë„ë©”ì¸ì˜ 기반 ìžë£Œí˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: commands/typecmds.c:893 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "default í‘œí˜„ì‹ ì—¬ëŸ¬ê°œ 있ìŒ" -#: commands/typecmds.c:955 commands/typecmds.c:964 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "NULL/NOT NULL ì¡°ê±´ì´ í•¨ê»˜ 있ìŒ" -#: commands/typecmds.c:980 +#: commands/typecmds.c:986 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "ë„ë©”ì¸ìš© ì²´í¬ ì œì•½ ì¡°ê±´ì—는 NO INHERIT ì˜µì…˜ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/typecmds.c:989 commands/typecmds.c:2522 +#: commands/typecmds.c:995 commands/typecmds.c:2584 #, c-format msgid "unique constraints not possible for domains" msgstr "고유 제약 ì¡°ê±´ì€ ë„ë©”ì¸ ì •ì˜ì— 사용할 수 ì—†ìŒ" -#: commands/typecmds.c:995 commands/typecmds.c:2528 +#: commands/typecmds.c:1001 commands/typecmds.c:2590 #, c-format msgid "primary key constraints not possible for domains" msgstr "기본키 제약 ì¡°ê±´ì„ ë„ë©”ì¸ ì •ì˜ì— 사용할 수 ì—†ìŒ" -#: commands/typecmds.c:1001 commands/typecmds.c:2534 +#: commands/typecmds.c:1007 commands/typecmds.c:2596 #, c-format msgid "exclusion constraints not possible for domains" msgstr "exclusion 제약 ì¡°ê±´ì€ ë„ë©”ì¸ì—는 사용할 수 ì—†ìŒ" -#: commands/typecmds.c:1007 commands/typecmds.c:2540 +#: commands/typecmds.c:1013 commands/typecmds.c:2602 #, c-format msgid "foreign key constraints not possible for domains" msgstr "참조키(foreign key) 제약 ì¡°ê±´ì€ ë„ë©”ì¸(domain) ì •ì˜ì— 사용할 수 ì—†ìŒ" -#: commands/typecmds.c:1016 commands/typecmds.c:2549 +#: commands/typecmds.c:1022 commands/typecmds.c:2611 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "ë„ë©”ì¸ì— 대해 제약 ì¡°ê±´ ì§€ì—°ì„ ì§€ì •í•  수 ì—†ìŒ" -#: commands/typecmds.c:1291 utils/cache/typcache.c:1630 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" -msgstr "%s ê°ì²´ëŠ” ë‚˜ì—´í˜•ì´ ì•„ë‹˜" +msgstr "%s 개체는 ë‚˜ì—´í˜•ì´ ì•„ë‹˜" -#: commands/typecmds.c:1429 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "\"subtype\" ì†ì„±ì´ 필요함" -#: commands/typecmds.c:1434 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "range subtypeì€ %s 아니여야 함" -#: commands/typecmds.c:1453 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" -msgstr "" -"range í˜•ì— ì •ë ¬ ê·œì¹™ì„ ì§€ì •í–ˆì§€ë§Œ, ì†Œì† ìžë£Œí˜•ì´ ê·¸ ì •ë ¬ ê·œì¹™ì„ ì§€ì›í•˜ì§€ 않습" -"니다" +msgstr "range í˜•ì— ì •ë ¬ ê·œì¹™ì„ ì§€ì •í–ˆì§€ë§Œ, ì†Œì† ìžë£Œí˜•ì´ ê·¸ ì •ë ¬ ê·œì¹™ì„ ì§€ì›í•˜ì§€ 않습니다" -#: commands/typecmds.c:1687 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "%s í•¨ìˆ˜ì˜ ì¸ìž ìžë£Œí˜•ì„ \"opaque\"ì—서 \"cstring\"으로 바꿉니다" -#: commands/typecmds.c:1738 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "%s í•¨ìˆ˜ì˜ ì¸ìž ìžë£Œí˜•ì„ \"opaque\"ì—서 %s ìžë£Œí˜•으로 바꿉니다" -#: commands/typecmds.c:1837 +#: commands/typecmds.c:1898 #, c-format msgid "typmod_in function %s must return type %s" msgstr "%s typmod_in 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/typecmds.c:1864 +#: commands/typecmds.c:1925 #, c-format msgid "typmod_out function %s must return type %s" msgstr "%s typmod_out 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/typecmds.c:1891 +#: commands/typecmds.c:1952 #, c-format msgid "type analyze function %s must return type %s" msgstr "%s ìžë£Œí˜• ë¶„ì„ í•¨ìˆ˜ëŠ” %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼ 함" -#: commands/typecmds.c:1937 +#: commands/typecmds.c:1998 #, c-format -msgid "" -"You must specify an operator class for the range type or define a default " -"operator class for the subtype." -msgstr "" -"subtypeì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìŠ¤ë‚˜ range ìžë£Œí˜•ì„ ìœ„í•œ í•˜ë‚˜ì˜ ì—°ì‚°ìž í´ëž˜ìФ" -"를 지정해야 합니다" +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "subtypeì„ ìœ„í•œ 기본 ì—°ì‚°ìž í´ëž˜ìŠ¤ë‚˜ range ìžë£Œí˜•ì„ ìœ„í•œ í•˜ë‚˜ì˜ ì—°ì‚°ìž í´ëž˜ìŠ¤ë¥¼ 지정해야 합니다" -#: commands/typecmds.c:1968 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" msgstr "%s 범위 기준 함수는 range ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:1974 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" msgstr "%s 범위 기준 함수는 immutable ì†ì„±ì´ì–´ì•¼ 합니다" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2071 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "%s 범위 하위 ìžë£Œ ë¹„êµ í•¨ìˆ˜ëŠ” %s ìžë£Œí˜•ì„ ë°˜í™˜í•´ì•¼í•©ë‹ˆë‹¤" -#: commands/typecmds.c:2017 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "%s 범위 하위 ìžë£Œ ë¹„êµ í•¨ìˆ˜ëŠ” immutable ì†ì„±ì´ì–´ì•¼ 합니다" -#: commands/typecmds.c:2044 +#: commands/typecmds.c:2105 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때 pg_type ë°°ì—´ OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: commands/typecmds.c:2348 +#: commands/typecmds.c:2409 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "\"%s\" ì—´(해당 í…Œì´ë¸” \"%s\")ì˜ ìžë£Œ ê°€ìš´ë° null ê°’ì´ ìžˆìŠµë‹ˆë‹¤" -#: commands/typecmds.c:2463 commands/typecmds.c:2646 +#: commands/typecmds.c:2523 commands/typecmds.c:2708 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "\"%s\" 제약 ì¡°ê±´ \"%s\" ë„ë©”ì¸ì— í¬í•¨ë˜ì–´ 있지 않습니다." -#: commands/typecmds.c:2467 +#: commands/typecmds.c:2527 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "\"%s\" 제약 ì¡°ê±´ \"%s\" ë„ë©”ì¸ì— í¬í•¨ë˜ì–´ 있지 않ìŒ, 건너뜀" -#: commands/typecmds.c:2652 +#: commands/typecmds.c:2715 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "\"%s\" 제약 ì¡°ê±´(해당 ë„ë©”ì¸: \"%s\")ì€ check ì œì•½ì¡°ê±´ì´ ì•„ë‹˜" -#: commands/typecmds.c:2758 +#: commands/typecmds.c:2821 #, c-format -msgid "" -"column \"%s\" of table \"%s\" contains values that violate the new constraint" -msgstr "" -"\"%s\" ì—´(해당 í…Œì´ë¸” \"%s\")ì˜ ìžë£Œ 중ì—, 새 제약 ì¡°ê±´ì„ ìœ„ë°˜í•˜ëŠ” ìžë£Œê°€ 있" -"습니다" +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "\"%s\" ì—´(해당 í…Œì´ë¸” \"%s\")ì˜ ìžë£Œ 중ì—, 새 제약 ì¡°ê±´ì„ ìœ„ë°˜í•˜ëŠ” ìžë£Œê°€ 있습니다" -#: commands/typecmds.c:2971 commands/typecmds.c:3228 commands/typecmds.c:3417 +#: commands/typecmds.c:3049 commands/typecmds.c:3255 commands/typecmds.c:3337 +#: commands/typecmds.c:3524 #, c-format msgid "%s is not a domain" -msgstr "\"%s\" ì´ë¦„ì˜ ê°ì²´ëŠ” ë„ë©”ì¸ì´ 아닙니다" +msgstr "\"%s\" ì´ë¦„ì˜ ê°œì²´ëŠ” ë„ë©”ì¸ì´ 아닙니다" -#: commands/typecmds.c:3005 +#: commands/typecmds.c:3082 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "\"%s\" 제약 ì¡°ê±´ì´ \"%s\" ë„ë©”ì¸ì— ì´ë¯¸ 지정ë˜ì–´ 있습니다" -#: commands/typecmds.c:3055 +#: commands/typecmds.c:3133 #, c-format msgid "cannot use table references in domain check constraint" msgstr "ë„ë©”ì¸ ìš© ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 í…Œì´ë¸” 참조를 사용할 수 없습니다" -#: commands/typecmds.c:3158 commands/typecmds.c:3240 commands/typecmds.c:3534 +#: commands/typecmds.c:3267 commands/typecmds.c:3349 commands/typecmds.c:3641 #, c-format msgid "%s is a table's row type" msgstr "%s ìžë£Œí˜•ì€ í…Œì´ë¸”ì˜ í–‰ ìžë£Œí˜•(row type)입니다" -#: commands/typecmds.c:3160 commands/typecmds.c:3242 commands/typecmds.c:3536 +#: commands/typecmds.c:3269 commands/typecmds.c:3351 commands/typecmds.c:3643 #, c-format msgid "Use ALTER TABLE instead." msgstr "대신 ALTER TABLEì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: commands/typecmds.c:3167 commands/typecmds.c:3249 commands/typecmds.c:3449 +#: commands/typecmds.c:3276 commands/typecmds.c:3358 commands/typecmds.c:3556 #, c-format msgid "cannot alter array type %s" msgstr "%s ë°°ì—´ 형ì‹ì„ 변경할 수 ì—†ìŒ" -#: commands/typecmds.c:3169 commands/typecmds.c:3251 commands/typecmds.c:3451 +#: commands/typecmds.c:3278 commands/typecmds.c:3360 commands/typecmds.c:3558 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "%s 형ì‹ì„ 변경할 수 있으며, ì´ë ‡ê²Œ 하면 ë°°ì—´ 형ì‹ë„ 변경ë©ë‹ˆë‹¤." -#: commands/typecmds.c:3519 +#: commands/typecmds.c:3626 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "%s ìžë£Œí˜•ì´ ì´ë¯¸ \"%s\" 스키마 ì•ˆì— ìžˆìŠµë‹ˆë‹¤" -#: commands/user.c:149 +#: commands/user.c:141 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSID는 ë” ì´ìƒ 지정할 수 ì—†ìŒ" -#: commands/user.c:291 +#: commands/user.c:295 #, c-format msgid "must be superuser to create superusers" msgstr "새 슈í¼ìœ ì €ë¥¼ 만드려면 슈í¼ìœ ì ¸ì—¬ì•¼ë§Œ 합니다" -#: commands/user.c:298 +#: commands/user.c:302 #, c-format msgid "must be superuser to create replication users" msgstr "새 복제작업용 사용ìžë¥¼ 만드려면 슈í¼ìœ ì €ì—¬ì•¼ë§Œ 합니다" -#: commands/user.c:305 commands/user.c:693 +#: commands/user.c:309 commands/user.c:707 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "슈í¼ìœ ì €ë§Œ bypassrls ì†ì„±ì„ 바꿀 수 있ìŒ" -#: commands/user.c:312 +#: commands/user.c:316 #, c-format msgid "permission denied to create role" msgstr "롤 만들 권한 ì—†ìŒ" -#: commands/user.c:322 commands/user.c:1176 commands/user.c:1183 -#: utils/adt/acl.c:5279 utils/adt/acl.c:5285 gram.y:13619 gram.y:13654 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 gram.y:14877 +#: gram.y:14915 utils/adt/acl.c:5267 utils/adt/acl.c:5273 #, c-format msgid "role name \"%s\" is reserved" msgstr "\"%s\" 롤 ì´ë¦„ì€ ë‚´ë¶€ì ìœ¼ë¡œ 사용ë˜ê³  있습니다" -#: commands/user.c:324 commands/user.c:1178 commands/user.c:1185 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "\"pg_\"로 시작하는 롤 ì´ë¦„ì€ ì‚¬ìš©í•  수 없습니다." -#: commands/user.c:336 commands/user.c:1191 +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "\"%s\" 롤 ì´ë¦„ì´ ì´ë¯¸ 있습니다" -#: commands/user.c:414 +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "비밀번호로 빈 문ìžì—´ì„ 사용할 수 없습니다. 비밀번호를 없앱니다" + +#: commands/user.c:437 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "ì´ì§„ 업그레ì´ë“œ 작업 때 pg_authid OID ê°’ì´ ì§€ì •ë˜ì§€ 않았습니다" -#: commands/user.c:679 commands/user.c:896 commands/user.c:1432 -#: commands/user.c:1578 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 +#: commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" msgstr "슈í¼ìœ ì €ì˜ ì†ì„±ì„ 변경하련 슈í¼ìœ ì ¸ì—¬ì•¼ë§Œ 합니다" -#: commands/user.c:686 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" msgstr "복제작업용 사용ìžì˜ ì†ì„±ì„ 변경하련 슈í¼ìœ ì ¸ì—¬ì•¼ë§Œ 합니다" -#: commands/user.c:709 commands/user.c:904 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "권한 ì—†ìŒ" -#: commands/user.c:934 +#: commands/user.c:953 #, c-format msgid "must be superuser to alter settings globally" msgstr "슈í¼ìœ ì €ë§Œ ì „ì—­ 환경 ì„¤ì •ì„ ë°”ê¿€ 수 있습니다." -#: commands/user.c:956 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "ë¡¤ì„ ì‚­ì œí•  ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤" -#: commands/user.c:980 +#: commands/user.c:999 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "DROP ROLE 명령으로 삭제할 수 없는 특별한 롤입니다" -#: commands/user.c:990 commands/user.c:1147 commands/variable.c:825 -#: commands/variable.c:897 utils/adt/acl.c:5121 utils/adt/acl.c:5173 -#: utils/adt/acl.c:5206 utils/adt/acl.c:5224 utils/init/miscinit.c:502 +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 +#: commands/variable.c:894 utils/adt/acl.c:5124 utils/adt/acl.c:5171 +#: utils/adt/acl.c:5199 utils/adt/acl.c:5217 utils/init/miscinit.c:599 #, c-format msgid "role \"%s\" does not exist" msgstr "\"%s\" 롤(role) ì—†ìŒ" -#: commands/user.c:995 +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "\"%s\" 룰(rule) ì—†ìŒ, 건너 뜀" -#: commands/user.c:1007 commands/user.c:1011 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "현재 사용ìžëŠ” ì‚­ì œ ë  ìˆ˜ 없습니다" -#: commands/user.c:1015 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "세션 사용ìžëŠ” ì‚­ì œ ë  ìˆ˜ 없습니다" -#: commands/user.c:1026 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" msgstr "superuser를 사용ìžë¥¼ 삭제하려면 superuser여야만 합니다" -#: commands/user.c:1042 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" -msgstr "기타 다른 ê°ì²´ë“¤ì´ ì´ ë¡¤ì— ì˜ì¡´í•˜ê³  있어, \"%s\" ë¡¤ì„ ì‚­ì œí•  수 ì—†ìŒ" +msgstr "기타 다른 ê°œì²´ë“¤ì´ ì´ ë¡¤ì— ì˜ì¡´í•˜ê³  있어, \"%s\" ë¡¤ì„ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/user.c:1163 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "세션 사용ìžì˜ ì´ë¦„ì€ ë°”ê¿€ 수 없습니다" -#: commands/user.c:1167 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "현재 사용ìžì˜ ì´ë¦„ì€ ë°”ê¿€ 수 없습니다" -#: commands/user.c:1201 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" msgstr "superuserì˜ ì´ë¦„ì„ ë°”ê¾¸ë ¤ë©´ superuser여야 합니다" -#: commands/user.c:1208 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "롤 ì´ë¦„ 바꾸기 권한 ì—†ìŒ" -#: commands/user.c:1229 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "롤 ì´ë¦„ì´ ë³€ê²½ ë˜ì–´ MD5 암호를 지웠습니다" -#: commands/user.c:1291 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "GRANT/REVOKE ROLEì— ì—´ ì´ë¦„ì„ í¬í•¨í•  수 ì—†ìŒ" -#: commands/user.c:1329 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" -msgstr "ê°ì²´ë¥¼ 삭제할 ê¶Œí•œì´ ì—†ìŒ" +msgstr "개체를 삭제할 ê¶Œí•œì´ ì—†ìŒ" -#: commands/user.c:1356 commands/user.c:1365 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" -msgstr "ê°ì²´ ê¶Œí•œì„ ìž¬ 지정할 ê¶Œí•œì´ ì—†ìŒ" +msgstr "개체 ê¶Œí•œì„ ìž¬ 지정할 ê¶Œí•œì´ ì—†ìŒ" -#: commands/user.c:1440 commands/user.c:1586 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" msgstr "\"%s\" ì—­í• ì— admin ì˜µì…˜ì´ ìžˆì–´ì•¼ 함" -#: commands/user.c:1457 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" msgstr "grantor(?)를 지정하려면 슈í¼ìœ ì ¸ì—¬ì•¼í•©ë‹ˆë‹¤" -#: commands/user.c:1482 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "\"%s\" ë¡¤ì€ \"%s\" ë¡¤ì˜ êµ¬ì„±ì›ìž…니다" -#: commands/user.c:1497 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "role \"%s\" is already a member of role \"%s\"" -#: commands/user.c:1608 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "\"%s\" ë¡¤ì€ \"%s\"ë¡¤ì˜ êµ¬ì„±ì›ì´ 아닙니다" -#: commands/vacuum.c:185 +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "ANALYZE ì˜µì…˜ì€ ì¹¼ëŸ¼ 목ë¡ì´ ì œê³µë  ë•Œ 사용할 수 있습니다" + +#: commands/vacuum.c:203 #, c-format msgid "%s cannot be executed from VACUUM or ANALYZE" msgstr "%s ëª…ë ¹ì€ VACUUM, ANALYZE 명령ì—서 실행 ë  ìˆ˜ ì—†ìŒ" -#: commands/vacuum.c:195 +#: commands/vacuum.c:213 #, c-format msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" -msgstr "" -"VACUUM 명령ì—서 DISABLE_PAGE_SKIPPING 옵션과 FULL ì˜µì…˜ì„ í•¨ê»˜ 사용할 수 없습" -"니다." +msgstr "VACUUM 명령ì—서 DISABLE_PAGE_SKIPPING 옵션과 FULL ì˜µì…˜ì„ í•¨ê»˜ 사용할 수 없습니다." # # search5 부분 -#: commands/vacuum.c:535 +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "가장 ì˜¤ëž˜ëœ xminì´ ë„ˆë¬´ 옛날 것입니다." -#: commands/vacuum.c:536 +#: commands/vacuum.c:658 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" -"트랜잭션ID 최대값 초과로 ìžë£Œê°€ ê²¹ì³ì§€ëŠ” 문제를 피하기 위해서는 지금 즉시 ì—´" -"ë ¤ 있는 모든 íŠ¸ëžœìž­ì…˜ì„ ë‹«ìœ¼ì‹­ì‹œì˜¤." +"트랜잭션 겹침 문제를 피하기 위해서는 최대한 빨리 ì—´ë ¤ 있는 íŠ¸ëžœìž­ì…˜ì„ ë‹«ìœ¼ì‹­ì‹œì˜¤.\n" +"ë˜í•œ 미리 ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ë“¤ë„ ì»¤ë°‹ ë˜ëŠ” 롤백해야하며, 잠긴 복제 ìŠ¬ë¡¯ë„ ì§€ì›Œì•¼í•©ë‹ˆë‹¤." # # search5 부분 -#: commands/vacuum.c:575 +#: commands/vacuum.c:698 #, c-format msgid "oldest multixact is far in the past" msgstr "가장 ì˜¤ëž˜ëœ multixact ê°’ì´ ë„ˆë¬´ 옛날 것입니다." -#: commands/vacuum.c:576 +#: commands/vacuum.c:699 #, c-format -msgid "" -"Close open transactions with multixacts soon to avoid wraparound problems." -msgstr "" -"멀티 트랜잭션 ID 겹침 사고를 막기 위해 빨리 열린 멀티 íŠ¸ëžœìž­ì…˜ë“¤ì„ ë‹«ìœ¼ì‹­ì‹œ" -"오." +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "멀티 트랜잭션 ID 겹침 사고를 막기 위해 빨리 열린 멀티 íŠ¸ëžœìž­ì…˜ë“¤ì„ ë‹«ìœ¼ì‹­ì‹œì˜¤." -#: commands/vacuum.c:1146 +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" -msgstr "" -"몇몇 ë°ì´í„°ë² ì´ìŠ¤ê°€ 20ì–µ ì´ìƒì˜ íŠ¸ëžœìž­ì…˜ì„ ì²˜ë¦¬í–ˆìŒì—ë„ ë¶ˆêµ¬í•˜ê³  청소가ë˜ì§€ " -"않았습니다" +msgstr "몇몇 ë°ì´í„°ë² ì´ìŠ¤ê°€ 20ì–µ ì´ìƒì˜ íŠ¸ëžœìž­ì…˜ì„ ì²˜ë¦¬í–ˆìŒì—ë„ ë¶ˆêµ¬í•˜ê³  청소가ë˜ì§€ 않았습니다" -#: commands/vacuum.c:1147 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." msgstr "ì´ë¯¸ 트래잭션 ID 겹침 현ìƒìœ¼ë¡œ ìžë£Œ ì†ì‹¤ì´ ë°œìƒí–ˆì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: commands/vacuum.c:1268 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" -msgstr "\"%s\" ê°ì²´ vacuum 건너뜀 --- 사용 가능한 ìž ê¸ˆì´ ì—†ìŒ" +msgstr "\"%s\" 개체 vacuum 건너뜀 --- 사용 가능한 ìž ê¸ˆì´ ì—†ìŒ" + +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "\"%s\" 개체 vacuum 건너뜀 --- 해당 릴레ì´ì…˜ ì—†ìŒ" -#: commands/vacuum.c:1294 +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "\"%s\" 건너뜀 --- 슈í¼ìœ ì €ë§Œ 청소할 수 있ìŒ" -#: commands/vacuum.c:1298 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "\"%s\" 건너뜀 --- 슈í¼ìœ ì € ë˜ëŠ” ë°ì´í„°ë² ì´ìФ 소유주만 청소할 수 있ìŒ" -#: commands/vacuum.c:1302 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "\"%s\" 건너뜀 --- ì´ í…Œì´ë¸”ì´ë‚˜ ë°ì´í„°ë² ì´ìŠ¤ì˜ ì†Œìœ ì£¼ë§Œ 청소할 수 있ìŒ" -#: commands/vacuum.c:1320 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" -msgstr "" -"\"%s\" 건너뜀 --- í…Œì´ë¸”ì´ ì•„ë‹Œ 것 ë˜ëŠ” 특별 시스템 í…Œì´ë¸” ë“±ì€ ì²­ì†Œí•  수 ì—†" -"ìŒ" +msgstr "\"%s\" 건너뜀 --- í…Œì´ë¸”ì´ ì•„ë‹Œ 것 ë˜ëŠ” 특별 시스템 í…Œì´ë¸” ë“±ì€ ì²­ì†Œí•  수 ì—†ìŒ" -#: commands/vacuumlazy.c:366 +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "ì ê·¹ì ì¸ \"%s.%s.%s\" í…Œì´ë¸” ìžë™ 청소: ì¸ë±ìФ íƒìƒ‰: %d\n" + +#: commands/vacuumlazy.c:380 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" msgstr "\"%s.%s.%s\" í…Œì´ë¸” ìžë™ 청소: ì¸ë±ìФ íƒìƒ‰: %d\n" -#: commands/vacuumlazy.c:371 +#: commands/vacuumlazy.c:386 #, c-format -msgid "" -"pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" msgstr "페ì´ì§€: %u ì‚­ì œë¨, %u 남ìŒ, %u í•€ë‹ìœ¼ë¡œ 건너뜀, %u ë™ê²°ë˜ì–´ 건너뜀\n" -#: commands/vacuumlazy.c:377 +#: commands/vacuumlazy.c:392 #, c-format -msgid "" -"tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" -msgstr "튜플: %.0f ì‚­ì œë¨, %.0f 남ìŒ, %.0f 삭제할 수 없는 ì£½ì€ íŠœí”Œ\n" +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "튜플: %.0f ì‚­ì œë¨, %.0f 남ìŒ, %.0f 삭제할 수 없는 ì£½ì€ íŠœí”Œ, ì œì¼ ëŠ™ì€ xmin: %u\n" -#: commands/vacuumlazy.c:382 +#: commands/vacuumlazy.c:398 #, c-format msgid "buffer usage: %d hits, %d misses, %d dirtied\n" msgstr "ë²„í¼ ì‚¬ìš©ëŸ‰: %d 조회, %d 놓침, %d 변경ë¨\n" -#: commands/vacuumlazy.c:386 +#: commands/vacuumlazy.c:402 #, c-format msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" msgstr "í‰ê·  ì½ê¸° ì†ë„: %.3f MB/s, í‰ê·  쓰기 ì†ë„: %.3f MB/s\n" -#: commands/vacuumlazy.c:388 +#: commands/vacuumlazy.c:404 #, c-format msgid "system usage: %s" msgstr "시스템 사용량: %s" -#: commands/vacuumlazy.c:846 +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "ì ê·¹ì ìœ¼ë¡œ \"%s.%s\" 청소 중" + +#: commands/vacuumlazy.c:881 #, c-format msgid "relation \"%s\" page %u is uninitialized --- fixing" msgstr "\"%s\" 릴레ì´ì…˜ %u 페ì´ì§€ëŠ” 초기화ë˜ì§€ ì•Šì•˜ìŒ --- 수정함" -#: commands/vacuumlazy.c:1316 +#: commands/vacuumlazy.c:1417 #, c-format msgid "\"%s\": removed %.0f row versions in %u pages" msgstr "\"%s\": %.0fê°œì˜ í–‰ ë²„ì „ì„ %uê°œ 페ì´ì§€ì—서 삭제했습니다." -#: commands/vacuumlazy.c:1326 +#: commands/vacuumlazy.c:1427 #, c-format -msgid "%.0f dead row versions cannot be removed yet.\n" -msgstr "%.0fê°œì˜ ì£½ì€ ë¡œìš° ë²„ì „ì„ ì•„ì§ ì§€ìš¸ 수 없습니다.\n" +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0fê°œì˜ ì£½ì€ ë¡œìš° ë²„ì „ì„ ì•„ì§ ì§€ìš¸ 수 없습니다, ì œì¼ ëŠ™ì€ xmin: %u\n" -#: commands/vacuumlazy.c:1328 +#: commands/vacuumlazy.c:1429 #, c-format msgid "There were %.0f unused item pointers.\n" msgstr "%.0fê°œì˜ ì‚¬ìš©ë˜ì§€ ì•Šì€ ì•„ì´í…œ í¬ì¸í„°ê°€ 있습니다.\n" -#: commands/vacuumlazy.c:1330 +#: commands/vacuumlazy.c:1431 #, c-format -msgid "Skipped %u page due to buffer pins.\n" -msgid_plural "Skipped %u pages due to buffer pins.\n" -msgstr[0] "%u 페ì´ì§€ë¥¼ ë²„í¼ í•€ë‹ìœ¼ë¡œ 건너 뛰었습니다.\n" +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "%u 페ì´ì§€ë¥¼ ë²„í¼ í•€ë‹ìœ¼ë¡œ 건너 뛰었습니다, " -#: commands/vacuumlazy.c:1334 +#: commands/vacuumlazy.c:1435 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "" + +#: commands/vacuumlazy.c:1439 #, c-format msgid "%u page is entirely empty.\n" msgid_plural "%u pages are entirely empty.\n" msgstr[0] "" -#: commands/vacuumlazy.c:1342 +#: commands/vacuumlazy.c:1443 #, c-format -msgid "" -"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u " -"pages" -msgstr "" -"\"%s\": 지울 수 있는 ìžë£Œ %.0fê°œ, 지울 수 없는 ìžë£Œ %.0f개를 %u/%uê°œ 페ì´ì§€ì—" -"서 찾았ìŒ" +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%s\": 지울 수 있는 ìžë£Œ %.0fê°œ, 지울 수 없는 ìžë£Œ %.0f개를 %u/%uê°œ 페ì´ì§€ì—서 찾았ìŒ" -#: commands/vacuumlazy.c:1411 +#: commands/vacuumlazy.c:1515 #, c-format msgid "\"%s\": removed %d row versions in %d pages" msgstr "\"%s\": %d ê°œ ìžë£Œë¥¼ %d 페ì´ì§€ì—서 삭제했ìŒ" -#: commands/vacuumlazy.c:1600 +#: commands/vacuumlazy.c:1704 #, c-format msgid "scanned index \"%s\" to remove %d row versions" msgstr "\"%s\" ì¸ë±ìŠ¤ë¥¼ 스캔해서 %dê°œì˜ í–‰ ë²„ì „ë“¤ì„ ì§€ì› ìŠµë‹ˆë‹¤" -#: commands/vacuumlazy.c:1646 +#: commands/vacuumlazy.c:1756 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” %.0f í–‰ ë²„ì „ì„ %u 페ì´ì§€ì—서 í¬í•¨í•˜ê³  있습니다." -#: commands/vacuumlazy.c:1650 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -10286,119 +10792,117 @@ msgstr "" "%uê°œ ì¸ë±ìФ 페ì´ì§€ë¥¼ 삭제해서, %uê°œ 페ì´ì§€ë¥¼ 다시 사용합니다.\n" "%s." -#: commands/vacuumlazy.c:1745 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" msgstr "\"%s\": 잠금 요청 ì¶©ëŒë¡œ ìžë£Œ 비우기 ìž‘ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤" -#: commands/vacuumlazy.c:1810 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "\"%s\": %u ì—서 %u 페ì´ì§€ë¡œ 정지했ìŒ" -#: commands/vacuumlazy.c:1866 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" msgstr "\"%s\": 잠금 요청 ì¶©ëŒë¡œ ìžë£Œ 비우기 ìž‘ì—…ì„ ì§€ì—°í•©ë‹ˆë‹¤" -#: commands/variable.c:164 utils/misc/guc.c:9899 +#: commands/variable.c:165 utils/misc/guc.c:10297 utils/misc/guc.c:10359 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "알 수 없는 키워드: \"%s\"" -#: commands/variable.c:176 +#: commands/variable.c:177 #, c-format msgid "Conflicting \"datestyle\" specifications." msgstr "\"datestyle\" ì§€ì •ì´ ì¶©ëŒí•¨" -#: commands/variable.c:298 +#: commands/variable.c:299 #, c-format msgid "Cannot specify months in time zone interval." msgstr "타임 ì¡´ ê°„ê²©ì— ë‹¬ì„ ì§€ì •í•  수 ì—†ìŒ" -#: commands/variable.c:304 +#: commands/variable.c:305 #, c-format msgid "Cannot specify days in time zone interval." msgstr "타임 ì¡´ ê°„ê²©ì— ì¼ì„ 지정할 수 ì—†ìŒ" -#: commands/variable.c:346 commands/variable.c:428 +#: commands/variable.c:343 commands/variable.c:425 #, c-format msgid "time zone \"%s\" appears to use leap seconds" msgstr "\"%s\" time zone ì—서 leap second를 사용합니다" -#: commands/variable.c:348 commands/variable.c:430 +#: commands/variable.c:345 commands/variable.c:427 #, c-format msgid "PostgreSQL does not support leap seconds." msgstr "PostgreSQLì—서는 leap second를 ì§€ì›í•˜ì§€ 않습니다" -#: commands/variable.c:357 +#: commands/variable.c:354 #, c-format msgid "UTC timezone offset is out of range." msgstr "UTC 타입존 오프세트 범위가 벗어남." -#: commands/variable.c:497 +#: commands/variable.c:494 #, c-format msgid "cannot set transaction read-write mode inside a read-only transaction" msgstr "ì½ê¸° ì „ìš© 트랜잭션 ë‚´ì—서 íŠ¸ëžœìž­ì…˜ì„ ì½ê¸°/쓰기 모드로 설정할 수 ì—†ìŒ" -#: commands/variable.c:504 +#: commands/variable.c:501 #, c-format msgid "transaction read-write mode must be set before any query" msgstr "ì½ê¸°/쓰기 모드 íŠ¸ëžœìž­ì…˜ì€ ëª¨ë“  쿼리 ì•žì— ì§€ì •í•´ì•¼ 합니다." -#: commands/variable.c:511 +#: commands/variable.c:508 #, c-format msgid "cannot set transaction read-write mode during recovery" msgstr "복구 작업 중ì—는 íŠ¸ëžœìž­ì…˜ì„ ì½ê¸°/쓰기 모드로 설정할 수 ì—†ìŒ" -#: commands/variable.c:560 +#: commands/variable.c:557 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" msgstr "쿼리보다 먼저 SET TRANSACTION ISOLATION LEVELì„ í˜¸ì¶œí•´ì•¼ 함" -#: commands/variable.c:567 +#: commands/variable.c:564 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "하위 트랜잭션ì—서 SET TRANSACTION ISOLATION LEVELì„ í˜¸ì¶œí•˜ì§€ 않아야 함" -#: commands/variable.c:574 storage/lmgr/predicate.c:1587 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "ì½ê¸° ì „ìš© ë³´ì¡° 서버 ìƒíƒœì—서는 serializable 모드를 사용할 수 ì—†ìŒ" -#: commands/variable.c:575 +#: commands/variable.c:572 #, c-format msgid "You can use REPEATABLE READ instead." msgstr "대신ì—, REPEATABLE READ ëª…ë ¹ì„ ì‚¬ìš©í•  수 있ìŒ." -#: commands/variable.c:623 +#: commands/variable.c:620 #, c-format -msgid "" -"SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" -msgstr "" -"하위 트랜잭션ì—서 SET TRANSACTION [NOT] DEFERRABLE êµ¬ë¬¸ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "하위 트랜잭션ì—서 SET TRANSACTION [NOT] DEFERRABLE êµ¬ë¬¸ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: commands/variable.c:629 +#: commands/variable.c:626 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" msgstr "모든 쿼리보다 먼저 SET TRANSACTION [NOT] DEFERRABLE êµ¬ë¬¸ì„ ì‚¬ìš©í•´ì•¼ 함" -#: commands/variable.c:711 +#: commands/variable.c:708 #, c-format msgid "Conversion between %s and %s is not supported." msgstr "%s ì¸ì½”딩과 %s ì¸ì½”딩 사ì´ì˜ ë³€í™˜ì€ ì§€ì›í•˜ì§€ 않습니다" -#: commands/variable.c:718 +#: commands/variable.c:715 #, c-format msgid "Cannot change \"client_encoding\" now." -msgstr "\"client_encoding\" ê°’ì„ ë°”ê¿€ 수 ì—†ìŒ" +msgstr "\"client_encoding\" ê°’ì„ ì§€ê¸ˆì€ ë°”ê¿€ 수 ì—†ìŒ" -#: commands/variable.c:779 +#: commands/variable.c:776 #, c-format -msgid "cannot change client_encoding in a parallel worker" -msgstr "병렬 작업ìžì—서는 client_encoding ì„¤ì •ì„ í•  수 ì—†ìŒ" +msgid "cannot change client_encoding during a parallel operation" +msgstr "병렬 작업 중ì—는 client_encoding ì„¤ì •ì„ í•  수 ì—†ìŒ" -#: commands/variable.c:915 +#: commands/variable.c:912 #, c-format msgid "permission denied to set role \"%s\"" msgstr "\"%s\" 롤 ê¶Œí•œì„ ì§€ì •í•  수 ì—†ìŒ" @@ -10423,479 +10927,485 @@ msgstr "\"%s\" 칼럼 ìžë£Œ 처리를 위한 ì •ë ¬ ê·œì¹™ì„ ê²°ì •í•  수 ì—† msgid "view must have at least one column" msgstr "ë·°ì—는 ì ì–´ë„ 한 ê°œ ì´ìƒì˜ ì¹¼ëŸ¼ì´ ìžˆì–´ì•¼ 합니다" -#: commands/view.c:280 commands/view.c:292 +#: commands/view.c:281 commands/view.c:293 #, c-format msgid "cannot drop columns from view" msgstr "ë·°ì—서 ì¹¼ëŸ¼ì„ ì‚­ì œí•  수 ì—†ìŒ" -#: commands/view.c:297 +#: commands/view.c:298 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "ë·°ì—서 \"%s\" 칼럼 ì´ë¦„ì„ \"%s\"(으)로 바꿀 수 ì—†ìŒ" -#: commands/view.c:305 +#: commands/view.c:306 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "ë·°ì—서 \"%s\" 칼럼 ìžë£Œí˜•ì„ì„ %sì—서 %s(으)로 바꿀 수 ì—†ìŒ" -#: commands/view.c:444 +#: commands/view.c:451 #, c-format msgid "views must not contain SELECT INTO" msgstr "ë·°ì—는 SELECT INTO êµ¬ë¬¸ì„ í¬í•¨í•  수 ì—†ìŒ" -#: commands/view.c:457 +#: commands/view.c:463 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "뷰로 ì‚¬ìš©ë  ì¿¼ë¦¬ì˜ WITH ì ˆì—는 ìžë£Œ 변경 êµ¬ë¬¸ì´ ìžˆìœ¼ë©´ 안ë©ë‹ˆë‹¤." -#: commands/view.c:528 +#: commands/view.c:533 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "CREATE VIEW 는 columns 보다는 ì¢€ë” ë§Žì€ ì—´ ì´ë¦„ì„ ëª…ì‹œí•´ì•¼ 한다" -#: commands/view.c:536 +#: commands/view.c:541 #, c-format msgid "views cannot be unlogged because they do not have storage" -msgstr "" -"뷰는 저장 ê³µê°„ì„ ì‚¬ìš©í•˜ì§€ 않기 ë•Œë¬¸ì— unlogged ì†ì„±ì„ 지정할 수 없습니다." +msgstr "뷰는 저장 ê³µê°„ì„ ì‚¬ìš©í•˜ì§€ 않기 ë•Œë¬¸ì— unlogged ì†ì„±ì„ 지정할 수 없습니다." -#: commands/view.c:550 +#: commands/view.c:555 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "\"%s\" 뷰는 임시ì ì¸ 뷰로 만들어집니다" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:77 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "\"%s\" 커서는 SELECT 쿼리가 아님" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:83 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "\"%s\" 커서는 ì´ì „ 트랜잭션ì—서 보류ë¨" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:115 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" -msgstr "" -"\"%s\" 커서ì—는 \"%s\" í…Œì´ë¸”ì— ëŒ€í•œ FOR UPDATE/SHARE 참조가 여러 ê°œ 있ìŒ" +msgstr "\"%s\" 커서ì—는 \"%s\" í…Œì´ë¸”ì— ëŒ€í•œ FOR UPDATE/SHARE 참조가 여러 ê°œ 있ìŒ" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:124 #, c-format -msgid "" -"cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "\"%s\" ì»¤ì„œì— \"%s\" í…Œì´ë¸”ì— ëŒ€í•œ FOR UPDATE/SHARE 참조가 ì—†ìŒ" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:134 executor/execCurrent.c:177 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "\"%s\" 커서가 ë¡œìš°ì— ë†“ì—¬ 있지 않ìŒ" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:164 executor/execCurrent.c:219 +#: executor/execCurrent.c:231 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "\"%s\" 커서는 \"%s\" í…Œì´ë¸”ì˜ ë‹¨ìˆœ ì—…ë°ì´íЏ 가능한 ìŠ¤ìº”ì´ ì•„ë‹˜" -#: executor/execCurrent.c:231 executor/execQual.c:1178 +#: executor/execCurrent.c:273 executor/execExprInterp.c:2311 #, c-format -msgid "" -"type of parameter %d (%s) does not match that when preparing the plan (%s)" -msgstr "" -"%d번째 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•(%s)ì´ ë¯¸ë¦¬ ì¤€ë¹„ëœ ì‹¤í–‰ê³„íšì˜ ìžë£Œí˜•(%s)ê³¼ 다릅니다" +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "%d번째 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•(%s)ì´ ë¯¸ë¦¬ ì¤€ë¹„ëœ ì‹¤í–‰ê³„íšì˜ ìžë£Œí˜•(%s)ê³¼ 다릅니다" -#: executor/execCurrent.c:243 executor/execQual.c:1190 +#: executor/execCurrent.c:285 executor/execExprInterp.c:2323 #, c-format msgid "no value found for parameter %d" msgstr "%d번째 매개 변수 ê°’ì´ ì—†ìŠµë‹ˆë‹¤" -#: executor/execIndexing.c:544 +#: executor/execExpr.c:856 parser/parse_agg.c:794 #, c-format -msgid "" -"ON CONFLICT does not support deferrable unique constraints/exclusion " -"constraints as arbiters" -msgstr "" -"지연 가능한 고유 제약조건ì´ë‚˜ 제외 제약 ì¡°ê±´ì€ ON CONFLICT íŒë³„ìžë¡œ 사용할 " -"수 없습니다." +msgid "window function calls cannot be nested" +msgstr "윈ë„ìš° 함수 í˜¸ì¶œì„ ì¤‘ì²©í•  수 ì—†ìŒ" -#: executor/execIndexing.c:821 +#: executor/execExpr.c:1314 #, c-format -msgid "could not create exclusion constraint \"%s\"" -msgstr "\"%s\" exclusion 제약 ì¡°ê±´ì„ ë§Œë“¤ 수 ì—†ìŒ" - -#: executor/execIndexing.c:824 +msgid "target type is not an array" +msgstr "ëŒ€ìƒ ìžë£Œí˜•ì´ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." + +#: executor/execExpr.c:1646 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW() ì¹¼ëŸ¼ì€ %s ìžë£Œí˜•ì„ ê°€ì§‘ë‹ˆë‹¤. %s ìžë£Œí˜• 대신ì—" + +#: executor/execExpr.c:2181 executor/execSRF.c:697 parser/parse_func.c:126 +#: parser/parse_func.c:640 parser/parse_func.c:1014 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "í•¨ìˆ˜ì— ìµœëŒ€ %dê°œì˜ ì¸ìžë¥¼ 전달할 수 있ìŒ" + +#: executor/execExpr.c:2479 executor/execExpr.c:2485 +#: executor/execExprInterp.c:2640 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1289 +#: utils/adt/arrayfuncs.c:3335 utils/adt/arrayfuncs.c:5291 +#: utils/adt/arrayfuncs.c:5808 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "지정한 ë°°ì—´ í¬ê¸°(%d)ê°€ 최대치(%d)를 초과했습니다" + +#: executor/execExprInterp.c:1879 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "%d 번째 ì†ì„±(ëŒ€ìƒ ìžë£Œí˜• %s)ì´ ì‚­ì œë˜ì—ˆìŒ" + +#: executor/execExprInterp.c:1885 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "%d 번째 ì†ì„±(ëŒ€ìƒ ìžë£Œí˜• %s)ì˜ ìžë£Œí˜•ì´ ìž˜ëª»ë˜ì—ˆìŒ" + +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2913 +#: executor/execExprInterp.c:2960 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "í…Œì´ë¸”ì—는 %s ìžë£Œí˜•ì´ì§€ë§Œ, 쿼리ì—서는 %s ìžë£Œí˜•입니다." + +#: executor/execExprInterp.c:2401 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "WHERE CURRENT OF êµ¬ë¬¸ì€ ì´ í…Œì´ë¸” 형 대ìƒìœ¼ë¡œ ì§€ì›í•˜ì§€ 않습니다." + +#: executor/execExprInterp.c:2618 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "ë°°ì—´ 형태가 서로 틀려 병합할 수 없습니다" + +#: executor/execExprInterp.c:2619 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "%s ìžë£Œí˜•ì˜ ìš”ì†Œë¡œ êµ¬ì„±ëœ ë°°ì—´ì€ %s ìžë£Œí˜•ì˜ ìš”ì†Œë¡œ êµ¬ì„±ëœ ARRAY êµ¬ë¬¸ì— í¬í•¨ë  수 없습니다." + +#: executor/execExprInterp.c:2660 executor/execExprInterp.c:2690 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—는 ì¼ì¹˜í•˜ëŠ” ì°¨ì›ì´ í¬í•¨ëœ ë°°ì—´ ì‹ì´ 있어야 함" + +#: executor/execExprInterp.c:2912 executor/execExprInterp.c:2959 +#, c-format +msgid "attribute %d has wrong type" +msgstr "%d ì†ì„±ì˜ 형ì‹ì´ 잘못ë¨" + +#: executor/execExprInterp.c:3069 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "ë°°ì—´ 하위 스í¬ë¦½íŠ¸ë¡œ 지정하는 값으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다" + +#: executor/execExprInterp.c:3502 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "%s ë„ë©”ì¸ì—서는 null ê°’ì„ í—ˆìš©í•˜ì§€ 않습니다" + +#: executor/execExprInterp.c:3517 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "%s ë„ë©”ì¸ìš© ê°’ì´ \"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" + +#: executor/execExprInterp.c:3888 executor/execExprInterp.c:3905 +#: executor/execExprInterp.c:4007 executor/nodeModifyTable.c:106 +#: executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 +#: executor/nodeModifyTable.c:142 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "í…Œì´ë¸” í–‰ 형ì‹ê³¼ 쿼리 지정 í–‰ 형ì‹ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" + +#: executor/execExprInterp.c:3889 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "í…Œì´ë¸” í–‰ì—는 %dê°œ ì†ì„±ì´ í¬í•¨ë˜ì–´ ìžˆëŠ”ë° ì¿¼ë¦¬ì—는 %d개가 필요합니다." + +#: executor/execExprInterp.c:3906 executor/nodeModifyTable.c:118 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "í…Œì´ë¸”ì—는 %s 형ì‹ì´ 있는ë°(서수 위치 %d) 쿼리ì—는 %sì´(ê°€) 필요합니다." + +#: executor/execExprInterp.c:4008 executor/execSRF.c:953 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "서수 위치 %dì˜ ì‚­ì œëœ ì†ì„±ì—서 실제 스토리지 불ì¼ì¹˜ê°€ ë°œìƒí•©ë‹ˆë‹¤." + +#: executor/execIndexing.c:543 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "지연 가능한 고유 제약조건ì´ë‚˜ 제외 제약 ì¡°ê±´ì€ ON CONFLICT íŒë³„ìžë¡œ 사용할 수 없습니다." + +#: executor/execIndexing.c:818 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "\"%s\" exclusion 제약 ì¡°ê±´ì„ ë§Œë“¤ 수 ì—†ìŒ" + +#: executor/execIndexing.c:821 #, c-format msgid "Key %s conflicts with key %s." msgstr "%s 키와 %s ê°€ ì¶©ëŒí•¨" -#: executor/execIndexing.c:826 +#: executor/execIndexing.c:823 #, c-format msgid "Key conflicts exist." msgstr "키 ì¶©ëŒ ë°œìƒ" -#: executor/execIndexing.c:832 +#: executor/execIndexing.c:829 #, c-format msgid "conflicting key value violates exclusion constraint \"%s\"" msgstr "\"%s\" exclusion 제약 ì¡°ê±´ì— ë”°ë¼ í‚¤ ê°’ ì¶©ëŒì´ ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: executor/execIndexing.c:835 +#: executor/execIndexing.c:832 #, c-format msgid "Key %s conflicts with existing key %s." msgstr "%s 키가 ì´ë¯¸ 있는 %s 키와 ì¶©ëŒí•©ë‹ˆë‹¤." -#: executor/execIndexing.c:837 +#: executor/execIndexing.c:834 #, c-format msgid "Key conflicts with existing key." msgstr "키가 기존 키와 ì¶©ëŒí•¨" -#: executor/execMain.c:1027 +#: executor/execMain.c:1114 #, c-format msgid "cannot change sequence \"%s\"" msgstr "\"%s\" 시퀀스를 바꿀 수 ì—†ìŒ" -#: executor/execMain.c:1033 +#: executor/execMain.c:1120 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "\"%s\" TOAST 릴레ì´ì…˜ì„ 바꿀 수 ì—†ìŒ" -#: executor/execMain.c:1051 rewrite/rewriteHandler.c:2648 +#: executor/execMain.c:1138 rewrite/rewriteHandler.c:2773 #, c-format msgid "cannot insert into view \"%s\"" msgstr "\"%s\" ë·°ì— ìžë£Œë¥¼ 입력할 수 없습니다" -#: executor/execMain.c:1053 rewrite/rewriteHandler.c:2651 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2776 #, c-format -msgid "" -"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or " -"an unconditional ON INSERT DO INSTEAD rule." -msgstr "" -"뷰를 통해 ìžë£Œë¥¼ 입력하려면, INSTEAD OF INSERT 트리거나 ON INSERT DO INSTEAD " -"ë£°ì„ ì‚¬ìš©í•˜ì„¸ìš”" +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "뷰를 통해 ìžë£Œë¥¼ 입력하려면, INSTEAD OF INSERT 트리거나 ON INSERT DO INSTEAD ë£°ì„ ì‚¬ìš©í•˜ì„¸ìš”" -#: executor/execMain.c:1059 rewrite/rewriteHandler.c:2656 +#: executor/execMain.c:1146 rewrite/rewriteHandler.c:2781 #, c-format msgid "cannot update view \"%s\"" msgstr "\"%s\" 뷰로는 ìžë£Œë¥¼ 갱신할 수 없습니다" -#: executor/execMain.c:1061 rewrite/rewriteHandler.c:2659 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2784 #, c-format -msgid "" -"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an " -"unconditional ON UPDATE DO INSTEAD rule." -msgstr "" -"ë·° ìžë£Œ 갱신 ê¸°ëŠ¥ì€ INSTEAD OF UPDATE 트리거를 사용하거나, ON UPDATE DO " -"INSTEAD ì†ì„±ìœ¼ë¡œ ë£°ì„ ë§Œë“¤ì–´ì„œ 사용해 보세요." +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "ë·° ìžë£Œ 갱신 ê¸°ëŠ¥ì€ INSTEAD OF UPDATE 트리거를 사용하거나, ON UPDATE DO INSTEAD ì†ì„±ìœ¼ë¡œ ë£°ì„ ë§Œë“¤ì–´ì„œ 사용해 보세요." -#: executor/execMain.c:1067 rewrite/rewriteHandler.c:2664 +#: executor/execMain.c:1154 rewrite/rewriteHandler.c:2789 #, c-format msgid "cannot delete from view \"%s\"" msgstr "\"%s\" 뷰로는 ìžë£Œë¥¼ 삭제할 수 없습니다" -#: executor/execMain.c:1069 rewrite/rewriteHandler.c:2667 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2792 #, c-format -msgid "" -"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an " -"unconditional ON DELETE DO INSTEAD rule." -msgstr "" -"ë·° ìžë£Œ ì‚­ì œ ê¸°ëŠ¥ì€ INSTEAD OF DELETE 트리거를 사용하거나, ON DELETE DO " -"INSTEAD ì†ì„±ìœ¼ë¡œ ë£°ì„ ë§Œë“¤ì–´ì„œ 사용해 보세요." +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "ë·° ìžë£Œ ì‚­ì œ ê¸°ëŠ¥ì€ INSTEAD OF DELETE 트리거를 사용하거나, ON DELETE DO INSTEAD ì†ì„±ìœ¼ë¡œ ë£°ì„ ë§Œë“¤ì–´ì„œ 사용해 보세요." -#: executor/execMain.c:1080 +#: executor/execMain.c:1167 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°ë¥¼ 바꿀 수 ì—†ìŒ" -#: executor/execMain.c:1092 +#: executor/execMain.c:1179 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸”ì— ìžë£Œë¥¼ 입력할 수 ì—†ìŒ" -#: executor/execMain.c:1098 +#: executor/execMain.c:1185 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "\"%s\" 외부 í…Œì´ë¸”ì€ ìžë£Œ ìž…ë ¥ì„ í—ˆìš©í•˜ì§€ 않ìŒ" -#: executor/execMain.c:1105 +#: executor/execMain.c:1192 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸”ì— ìžë£Œë¥¼ 변경 í•  수 ì—†ìŒ" -#: executor/execMain.c:1111 +#: executor/execMain.c:1198 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "\"%s\" 외부 í…Œì´ë¸”ì€ ìžë£Œ ë³€ê²½ì„ í—ˆìš©í•˜ì§€ 않ìŒ" -#: executor/execMain.c:1118 +#: executor/execMain.c:1205 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸”ì— ìžë£Œë¥¼ ì‚­ì œ í•  수 ì—†ìŒ" -#: executor/execMain.c:1124 +#: executor/execMain.c:1211 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "\"%s\" 외부 í…Œì´ë¸”ì€ ìžë£Œ 삭제를 허용하지 않ìŒ" -#: executor/execMain.c:1135 +#: executor/execMain.c:1222 #, c-format msgid "cannot change relation \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì„ 바꿀 수 ì—†ìŒ" -#: executor/execMain.c:1161 +#: executor/execMain.c:1249 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "\"%s\" 시퀀스ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1168 +#: executor/execMain.c:1256 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "\"%s\" TOAST 릴레ì´ì…˜ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1175 +#: executor/execMain.c:1263 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "\"%s\" ë·°ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1183 +#: executor/execMain.c:1271 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1192 executor/execMain.c:2613 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1280 executor/execMain.c:2972 +#: executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "\"%s\" 외부 í…Œì´ë¸”ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1198 +#: executor/execMain.c:1286 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "\"%s\" 릴레ì´ì…˜ì—서 로우를 잠글 수 ì—†ìŒ" -#: executor/execMain.c:1731 +#: executor/execMain.c:1957 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "\"%s\" ì¹¼ëŸ¼ì˜ null ê°’ì´ not null ì œì•½ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤." +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "새 ìžë£Œê°€ \"%s\" 릴레ì´ì…˜ì˜ 파티션 제약 ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" -#: executor/execMain.c:1733 executor/execMain.c:1759 executor/execMain.c:1848 +#: executor/execMain.c:1959 executor/execMain.c:2039 executor/execMain.c:2086 +#: executor/execMain.c:2193 #, c-format msgid "Failing row contains %s." msgstr "실패한 ìžë£Œ: %s" -#: executor/execMain.c:1757 +#: executor/execMain.c:2037 +#, c-format +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "\"%s\" ì¹¼ëŸ¼ì˜ null ê°’ì´ not null ì œì•½ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤." + +#: executor/execMain.c:2084 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "새 ìžë£Œê°€ \"%s\" 릴레ì´ì…˜ì˜ \"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" -#: executor/execMain.c:1846 +#: executor/execMain.c:2191 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "새 ìžë£Œê°€ \"%s\" ë·°ì˜ ì²´í¬ ì œì•½ ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" -#: executor/execMain.c:1856 +#: executor/execMain.c:2201 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" -msgstr "" -"새 ìžë£Œê°€ \"%s\" 로우 단위 보안 ì •ì±…ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤, 해당 í…Œì´ë¸”: \"%s\"" +msgstr "새 ìžë£Œê°€ \"%s\" 로우 단위 보안 ì •ì±…ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤, 해당 í…Œì´ë¸”: \"%s\"" -#: executor/execMain.c:1861 +#: executor/execMain.c:2206 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "새 ìžë£Œê°€ \"%s\" í…Œì´ë¸”ì˜ ë¡œìš° 단위 보안 ì •ì±…ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤." -#: executor/execMain.c:1868 -#, c-format -msgid "" -"new row violates row-level security policy \"%s\" (USING expression) for " -"table \"%s\"" -msgstr "" -"새 ìžë£Œê°€ \"%s\" 로우 단위 보안 ì •ì±…(USING ì ˆ 사용)ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤, 해당 í…Œì´" -"블: \"%s\"" - -#: executor/execMain.c:1873 -#, c-format -msgid "" -"new row violates row-level security policy (USING expression) for table \"%s" -"\"" -msgstr "" -"새 ìžë£Œê°€ \"%s\" í…Œì´ë¸”ì˜ ë¡œìš° 단위 보안 ì •ì±…(USING ì ˆ 사용)ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤." - -#: executor/execQual.c:302 executor/execQual.c:339 executor/execQual.c:3236 -#: utils/adt/array_userfuncs.c:484 utils/adt/arrayfuncs.c:260 -#: utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 -#: utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5241 -#: utils/adt/arrayfuncs.c:5758 -#, c-format -msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "지정한 ë°°ì—´ í¬ê¸°(%d)ê°€ 최대치(%d)를 초과했습니다" - -#: executor/execQual.c:324 executor/execQual.c:360 +#: executor/execMain.c:2213 #, c-format -msgid "array subscript in assignment must not be null" -msgstr "ë°°ì—´ 하위 스í¬ë¦½íŠ¸ë¡œ 지정하는 값으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다" +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "새 ìžë£Œê°€ \"%s\" 로우 단위 보안 ì •ì±…(USING ì ˆ 사용)ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤, 해당 í…Œì´ë¸”: \"%s\"" -#: executor/execQual.c:657 executor/execQual.c:4183 +#: executor/execMain.c:2218 #, c-format -msgid "attribute %d has wrong type" -msgstr "%d ì†ì„±ì˜ 형ì‹ì´ 잘못ë¨" +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "새 ìžë£Œê°€ \"%s\" í…Œì´ë¸”ì˜ ë¡œìš° 단위 보안 ì •ì±…(USING ì ˆ 사용)ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤." -#: executor/execQual.c:658 executor/execQual.c:4184 +#: executor/execPartition.c:307 #, c-format -msgid "Table has type %s, but query expects %s." -msgstr "í…Œì´ë¸”ì—는 %s ìžë£Œí˜•ì´ì§€ë§Œ, 쿼리ì—서는 %s ìžë£Œí˜•입니다." +msgid "no partition of relation \"%s\" found for row" +msgstr "해당 로우를 위한 \"%s\" 릴레ì´ì…˜ìš© íŒŒí‹°ì…˜ì´ ì—†ìŒ" -#: executor/execQual.c:851 executor/execQual.c:868 executor/execQual.c:1068 -#: executor/nodeModifyTable.c:95 executor/nodeModifyTable.c:105 -#: executor/nodeModifyTable.c:122 executor/nodeModifyTable.c:130 +#: executor/execPartition.c:309 #, c-format -msgid "table row type and query-specified row type do not match" -msgstr "í…Œì´ë¸” í–‰ 형ì‹ê³¼ 쿼리 지정 í–‰ 형ì‹ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" +msgid "Partition key of the failing row contains %s." +msgstr "실패한 ë¡œìš°ì˜ íŒŒí‹°ì…˜ 키 ê°’: %s" -#: executor/execQual.c:852 +#: executor/execReplication.c:197 executor/execReplication.c:361 #, c-format -msgid "Table row contains %d attribute, but query expects %d." -msgid_plural "Table row contains %d attributes, but query expects %d." -msgstr[0] "" -"í…Œì´ë¸” í–‰ì—는 %dê°œ ì†ì„±ì´ í¬í•¨ë˜ì–´ ìžˆëŠ”ë° ì¿¼ë¦¬ì—는 %d개가 필요합니다." +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "다른 ì—…ë°ì´íЏ 작업으로 ìž êµ´ íŠœí”Œì´ ì´ë¯¸ 다른 파티션으로 ì´ë™ë˜ì—ˆìŒ, 재시ë„함" -#: executor/execQual.c:869 executor/nodeModifyTable.c:106 +#: executor/execReplication.c:201 executor/execReplication.c:365 #, c-format -msgid "Table has type %s at ordinal position %d, but query expects %s." -msgstr "" -"í…Œì´ë¸”ì—는 %s 형ì‹ì´ 있는ë°(서수 위치 %d) 쿼리ì—는 %sì´(ê°€) 필요합니다." +msgid "concurrent update, retrying" +msgstr "ë™ì‹œ ì—…ë°ì´íЏ, 다시 ì‹œë„ ì¤‘" -#: executor/execQual.c:1069 executor/execQual.c:1665 +#: executor/execReplication.c:262 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3613 utils/adt/arrayfuncs.c:4129 +#: utils/adt/arrayfuncs.c:6089 utils/adt/rowtypes.c:1179 #, c-format -msgid "Physical storage mismatch on dropped attribute at ordinal position %d." -msgstr "서수 위치 %dì˜ ì‚­ì œëœ ì†ì„±ì—서 실제 스토리지 불ì¼ì¹˜ê°€ ë°œìƒí•©ë‹ˆë‹¤." +msgid "could not identify an equality operator for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 ë™ë“± ì—°ì‚°ìž(equality operator)를 ì°¾ì„ ìˆ˜ 없습니다." -#: executor/execQual.c:1344 parser/parse_func.c:115 parser/parse_func.c:542 -#: parser/parse_func.c:897 +#: executor/execReplication.c:578 #, c-format -msgid "cannot pass more than %d argument to a function" -msgid_plural "cannot pass more than %d arguments to a function" -msgstr[0] "í•¨ìˆ˜ì— ìµœëŒ€ %dê°œì˜ ì¸ìžë¥¼ 전달할 수 있ìŒ" +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "\"%s\" í…Œì´ë¸” ì—…ë°ì´íЏ 실패, ì´ í…Œì´ë¸”ì—는 복제용 ì‹ë³„ìžë¥¼ 지정하지 않았거나, updates 옵션 ì—†ì´ ë°œí–‰í–ˆìŠµë‹ˆë‹¤" -#: executor/execQual.c:1533 +#: executor/execReplication.c:580 #, c-format -msgid "functions and operators can take at most one set argument" -msgstr "함수와 ì—°ì‚°ìžëŠ” set ì¸ìžë¡œëŠ” ì˜¤ì§ í•œ 개만 사용할 수 있습니다" +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "ì—…ë°ì´íŠ¸ë¥¼ 하려면, ALTER TABLE 명령어ì—서 REPLICA IDENTITY ì˜µì…˜ì„ ì‚¬ìš©í•˜ì„¸ìš”" -#: executor/execQual.c:1583 +#: executor/execReplication.c:584 #, c-format -msgid "" -"function returning setof record called in context that cannot accept type " -"record" -msgstr "" -"setof 레코드 반환 함수가 type 레코드를 허용하지 않는 컨í…스트ì—서 호출ë¨" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "\"%s\" í…Œì´ë¸” ìžë£Œ ì‚­ì œ 실패, 복제 ì‹ë³„ìžì™€ deletes ë°œí–‰ì„ ì•ˆí•¨" -#: executor/execQual.c:1638 executor/execQual.c:1654 executor/execQual.c:1664 +#: executor/execReplication.c:586 #, c-format -msgid "function return row and query-specified return row do not match" -msgstr "함수 반환 행과 쿼리 지정 반환 í–‰ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "ì‚­ì œ 하려면, ALTER TABLE 명령어ì—서 REPLICA IDENTITY ì˜µì…˜ì„ ì‚¬ìš©í•˜ì„¸ìš”" -#: executor/execQual.c:1639 +#: executor/execReplication.c:605 #, c-format -msgid "Returned row contains %d attribute, but query expects %d." -msgid_plural "Returned row contains %d attributes, but query expects %d." -msgstr[0] "" -"ë°˜í™˜ëœ í–‰ì—는 %dê°œ ì†ì„±ì´ í¬í•¨ë˜ì–´ ìžˆëŠ”ë° ì¿¼ë¦¬ì—는 %d개가 필요합니다." +msgid "logical replication target relation \"%s.%s\" is not a table" +msgstr "\"%s.%s\" 논리 복제 ëŒ€ìƒ ë¦´ë ˆì´ì…˜ì€ í…Œì´ë¸”ì´ ì•„ë‹™ë‹ˆë‹¤" -#: executor/execQual.c:1655 +#: executor/execSRF.c:308 #, c-format -msgid "Returned type %s at ordinal position %d, but query expects %s." -msgstr "ë°˜í™˜ëœ í˜•ì‹ì€ %sì¸ë°(서수 위치 %d) 쿼리ì—는 %sì´(ê°€) 필요합니다." +msgid "rows returned by function are not all of the same row type" +msgstr "함수 호출로 반환ë˜ëŠ” 로우가 ê°™ì€ ë¡œìš°í˜•ì˜ ì „ë¶€ê°€ 아닙니다" -#: executor/execQual.c:1897 executor/execQual.c:2335 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "materialize 모드를 위한 í…Œì´ë¸” 함수 í”„ë¡œí† ì½œì´ ë’¤ì´ì–´ 오지 않았습니다" -#: executor/execQual.c:1917 executor/execQual.c:2342 +#: executor/execSRF.c:363 executor/execSRF.c:665 #, c-format msgid "unrecognized table-function returnMode: %d" msgstr "알 수 없는 í…Œì´ë¸”-함수 리턴모드: %d" -#: executor/execQual.c:2287 -#, c-format -msgid "rows returned by function are not all of the same row type" -msgstr "함수 호출로 반환ë˜ëŠ” 로우가 ê°™ì€ ë¡œìš°í˜•ì˜ ì „ë¶€ê°€ 아닙니다" - -#: executor/execQual.c:2522 -#, c-format -msgid "IS DISTINCT FROM does not support set arguments" -msgstr "IS DISTINCT FROM 구문ì—서는 set ì¸ìžë“¤ì„ ì§€ì›í•˜ì§€ 않습니다" - -#: executor/execQual.c:2599 -#, c-format -msgid "op ANY/ALL (array) does not support set arguments" -msgstr "op ANY/ALL (array) ì—서는 set ì¸ìžë“¤ì„ ì§€ì›í•˜ì§€ 않습니다" - -#: executor/execQual.c:3214 -#, c-format -msgid "cannot merge incompatible arrays" -msgstr "ë°°ì—´ 형태가 서로 틀려 병합할 수 없습니다" - -#: executor/execQual.c:3215 -#, c-format -msgid "" -"Array with element type %s cannot be included in ARRAY construct with " -"element type %s." -msgstr "" -"%s ìžë£Œí˜•ì˜ ìš”ì†Œë¡œ êµ¬ì„±ëœ ë°°ì—´ì€ %s ìžë£Œí˜•ì˜ ìš”ì†Œë¡œ êµ¬ì„±ëœ ARRAY êµ¬ë¬¸ì— í¬í•¨" -"ë  ìˆ˜ 없습니다." - -#: executor/execQual.c:3256 executor/execQual.c:3283 -#, c-format -msgid "" -"multidimensional arrays must have array expressions with matching dimensions" -msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—는 ì¼ì¹˜í•˜ëŠ” ì°¨ì›ì´ í¬í•¨ëœ ë°°ì—´ ì‹ì´ 있어야 함" - -#: executor/execQual.c:3798 -#, c-format -msgid "NULLIF does not support set arguments" -msgstr "NULLIF는 set ì¸ìžë“¤ì„ ì§€ì›í•˜ì§€ 않습니다" - -#: executor/execQual.c:4046 utils/adt/domains.c:137 -#, c-format -msgid "domain %s does not allow null values" -msgstr "%s ë„ë©”ì¸ì—서는 null ê°’ì„ í—ˆìš©í•˜ì§€ 않습니다" - -#: executor/execQual.c:4083 utils/adt/domains.c:179 -#, c-format -msgid "value for domain %s violates check constraint \"%s\"" -msgstr "%s ë„ë©”ì¸ìš© ê°’ì´ \"%s\" ì²´í¬ ì œì•½ ì¡°ê±´ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" - -#: executor/execQual.c:4438 -#, c-format -msgid "WHERE CURRENT OF is not supported for this table type" -msgstr "WHERE CURRENT OF êµ¬ë¬¸ì€ ì´ í…Œì´ë¸” 형 대ìƒìœ¼ë¡œ ì§€ì›í•˜ì§€ 않습니다." - -#: executor/execQual.c:4627 parser/parse_agg.c:758 +#: executor/execSRF.c:871 #, c-format -msgid "window function calls cannot be nested" -msgstr "윈ë„ìš° 함수 í˜¸ì¶œì„ ì¤‘ì²©í•  수 ì—†ìŒ" +msgid "function returning setof record called in context that cannot accept type record" +msgstr "setof 레코드 반환 함수가 type 레코드를 허용하지 않는 컨í…스트ì—서 호출ë¨" -#: executor/execQual.c:4839 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format -msgid "target type is not an array" -msgstr "ëŒ€ìƒ ìžë£Œí˜•ì´ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." +msgid "function return row and query-specified return row do not match" +msgstr "함수 반환 행과 쿼리 지정 반환 í–‰ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: executor/execQual.c:4956 +#: executor/execSRF.c:927 #, c-format -msgid "ROW() column has type %s instead of type %s" -msgstr "ROW() ì—´ì€ %s ìžë£Œí˜•ì„ ê°€ì§‘ë‹ˆë‹¤. %s ìžë£Œí˜• 대신ì—" +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "ë°˜í™˜ëœ í–‰ì—는 %dê°œ ì†ì„±ì´ í¬í•¨ë˜ì–´ ìžˆëŠ”ë° ì¿¼ë¦¬ì—는 %d개가 필요합니다." -#: executor/execQual.c:5091 utils/adt/arrayfuncs.c:3803 -#: utils/adt/arrayfuncs.c:6325 utils/adt/rowtypes.c:927 +#: executor/execSRF.c:943 #, c-format -msgid "could not identify a comparison function for type %s" -msgstr "%s ìžë£Œí˜•ì—서 사용할 비êµí•¨ìˆ˜ë¥¼ ì°¾ì„ ìˆ˜ 없습니다." +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "ë°˜í™˜ëœ í˜•ì‹ì€ %sì¸ë°(서수 위치 %d) 쿼리ì—는 %sì´(ê°€) 필요합니다." -#: executor/execUtils.c:813 +#: executor/execUtils.c:687 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "\"%s\" êµ¬ì²´í™”ëœ ë·°ê°€ ì•„ì§ êµ¬ì²´í™”ë˜ì§€ 못했습니다." -#: executor/execUtils.c:815 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "REFRESH MATERIALIZED VIEW ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." @@ -10905,14078 +11415,14689 @@ msgstr "REFRESH MATERIALIZED VIEW ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”." msgid "could not determine actual type of argument declared %s" msgstr "%s ì¸ìžì˜ ìžë£Œí˜•으로 지정한 ìžë£Œí˜•ì˜ ê¸°ë³¸ ìžë£Œí˜•ì„ ì°¾ì„ ìˆ˜ 없습니다" -#: executor/functions.c:511 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "SQL 함수ì—서 í´ë¼ì´ì–¸íЏ ëŒ€ìƒ COPY ìž‘ì—…ì„ í•  수 ì—†ìŒ" #. translator: %s is a SQL statement name -#: executor/functions.c:517 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "SQL 함수ì—서 %s ì§€ì›ë˜ì§€ 않ìŒ" #. translator: %s is a SQL statement name -#: executor/functions.c:524 executor/spi.c:1364 executor/spi.c:2154 +#: executor/functions.c:535 executor/spi.c:1409 executor/spi.c:2199 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s êµ¬ë¬¸ì€ ë¹„íœ˜ë°œì„± 함수(non-volatile function)ì—서 허용하지 않습니다" -#: executor/functions.c:650 +#: executor/functions.c:656 #, c-format -msgid "" -"could not determine actual result type for function declared to return type " -"%s" -msgstr "" -"%s ìžë£Œí˜•ì„ ë°˜í™˜í•œë‹¤ê³  ì •ì˜í•œ 함수ì¸ë°, 실재 반환 ìžë£Œí˜•ì„ ê²°ì •í•  수 없습니" -"다." +msgid "could not determine actual result type for function declared to return type %s" +msgstr "%s ìžë£Œí˜•ì„ ë°˜í™˜í•œë‹¤ê³  ì •ì˜í•œ 함수ì¸ë°, 실재 반환 ìžë£Œí˜•ì„ ê²°ì •í•  수 없습니다." -#: executor/functions.c:1415 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "SQL 함수 \"%s\"ì˜ ë¬¸ %d" -#: executor/functions.c:1441 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "시작 중 SQL 함수 \"%s\"" -#: executor/functions.c:1600 executor/functions.c:1637 -#: executor/functions.c:1649 executor/functions.c:1762 -#: executor/functions.c:1795 executor/functions.c:1825 +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "출력 ì¸ìžë¥¼ í¬í•¨í•œ 프로시져 í˜¸ì¶œì€ SQL 함수ì—서 ì§€ì›í•˜ì§€ 않습니다." + +#: executor/functions.c:1657 executor/functions.c:1690 +#: executor/functions.c:1702 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "리턴 ìžë£Œí˜•ì´ í•¨ìˆ˜ ì •ì˜ì—서 지정한 %s 리턴 ìžë£Œí˜•ê³¼ 틀립니다" -#: executor/functions.c:1602 +#: executor/functions.c:1659 #, c-format -msgid "" -"Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." -msgstr "" -"함수 ë‚´ìš©ì˜ ë§¨ 마지막 êµ¬ë¬¸ì€ SELECT ë˜ëŠ” INSERT/UPDATE/DELETE RETURNINGì´ì–´" -"야 합니다." +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "함수 ë‚´ìš©ì˜ ë§¨ 마지막 êµ¬ë¬¸ì€ SELECT ë˜ëŠ” INSERT/UPDATE/DELETE RETURNINGì´ì–´ì•¼ 합니다." -#: executor/functions.c:1639 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." msgstr "맨 마지막 êµ¬ë¬¸ì€ ì •í™•ížˆ í•˜ë‚˜ì˜ ì¹¼ëŸ¼ë§Œ 반환해야 합니다." -#: executor/functions.c:1651 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." msgstr "실재 반환 ìžë£Œí˜•ì€ %s" -#: executor/functions.c:1764 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "맨 마지막 êµ¬ë¬¸ì´ ë„ˆë¬´ ë§Žì€ ì¹¼ëŸ¼ì„ ë°˜í™˜í•©ë‹ˆë‹¤." -#: executor/functions.c:1797 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." -msgstr "" -"맨 마지막 êµ¬ë¬¸ì´ %s(기대ë˜ëŠ” ìžë£Œí˜•: %s) ìžë£Œí˜•ì„ %d 번째 칼럼ì—서 반환합니" -"다." +msgstr "맨 마지막 êµ¬ë¬¸ì´ %s(기대ë˜ëŠ” ìžë£Œí˜•: %s) ìžë£Œí˜•ì„ %d 번째 칼럼ì—서 반환합니다." -#: executor/functions.c:1827 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "맨 마지막 êµ¬ë¬¸ì´ ë„ˆë¬´ ì ì€ ì¹¼ëŸ¼ì„ ë°˜í™˜í•©ë‹ˆë‹¤." -#: executor/functions.c:1876 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "반환 ìžë£Œí˜•ì¸ %s ìžë£Œí˜•ì€ SQL 함수ì—서 ì§€ì›ë˜ì§€ 않ìŒ" -#: executor/nodeAgg.c:3038 +#: executor/nodeAgg.c:2802 parser/parse_agg.c:633 parser/parse_agg.c:663 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "%u OID 집계함수ì—서 쓸 ì¡°í•© 함수는 STRICT ì†ì„±ì„ 가져야 합니다" +msgid "aggregate function calls cannot be nested" +msgstr "집계 함수는 중첩ë˜ì–´ 호출 í•  수 ì—†ìŒ" -#: executor/nodeAgg.c:3083 executor/nodeWindowAgg.c:2318 +#: executor/nodeAgg.c:2988 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "%u OID ì§‘ê³„í•¨ìˆ˜ì— í˜¸í™˜ 가능한 ìž…ë ¥ 형ì‹ê³¼ 변환 형ì‹ì´ 있어야 함" -#: executor/nodeAgg.c:3149 parser/parse_agg.c:612 parser/parse_agg.c:642 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "집계 함수는 중첩ë˜ì–´ 호출 í•  수 ì—†ìŒ" - #: executor/nodeCustom.c:148 executor/nodeCustom.c:159 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ íƒìƒ‰ì€ MarkPos ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: executor/nodeHashjoin.c:823 executor/nodeHashjoin.c:853 +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "해시-ì¡°ì¸ ìž„ì‹œ 파ì¼ì„ ë˜ê°ì„ 수 ì—†ìŒ: %m" -#: executor/nodeHashjoin.c:888 executor/nodeHashjoin.c:894 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "hash-join 임시 파ì¼ì„ 쓸 수 없습니다: %m" -#: executor/nodeHashjoin.c:935 executor/nodeHashjoin.c:945 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "해시-ì¡°ì¸ ìž„ì‹œ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: executor/nodeIndexonlyscan.c:179 +#: executor/nodeIndexonlyscan.c:236 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "lossy distance í•¨ìˆ˜ë“¤ì€ ì¸ë±ìФ ë‹¨ë… íƒìƒ‰ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: executor/nodeLimit.c:253 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSETì€ ìŒìˆ˜ê°€ 아니어야 함" -#: executor/nodeLimit.c:280 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT는 ìŒìˆ˜ê°€ 아니어야 함" -#: executor/nodeMergejoin.c:1584 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOINì€ ë³‘í•©-ì¡°ì¸ ê°€ëŠ¥ ì¡°ì¸ ì¡°ê±´ì—서만 ì§€ì›ë¨" -#: executor/nodeMergejoin.c:1604 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "FULL JOINì€ ë³‘í•©-ì¡°ì¸ ê°€ëŠ¥ ì¡°ì¸ ì¡°ê±´ì—서만 ì§€ì›ë¨" -#: executor/nodeModifyTable.c:96 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "ì¿¼ë¦¬ì— ì¹¼ëŸ¼ì´ ë„ˆë¬´ 많습니다." -#: executor/nodeModifyTable.c:123 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." -msgstr "쿼리ì—서 서수 위치 %dì— ìžˆëŠ” ì‚­ì œëœ ì—´ì˜ ê°’ì„ ì œê³µí•©ë‹ˆë‹¤." +msgstr "쿼리ì—서 서수 위치 %dì— ìžˆëŠ” ì‚­ì œëœ ì¹¼ëŸ¼ì˜ ê°’ì„ ì œê³µí•©ë‹ˆë‹¤." -#: executor/nodeModifyTable.c:131 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." msgstr "ì¿¼ë¦¬ì— ì¹¼ëŸ¼ì´ ë„ˆë¬´ ì ìŠµë‹ˆë‹¤." -#: executor/nodeModifyTable.c:1132 +#: executor/nodeModifyTable.c:773 +#, c-format +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "다른 ì—…ë°ì´íЏ 작업으로 지워야할 íŠœí”Œì´ ì´ë¯¸ 다른 파티션으로 ì´ë™ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: executor/nodeModifyTable.c:1085 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "ìž˜ëª»ëœ ON UPDATE 옵션" + +#: executor/nodeModifyTable.c:1086 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "" + +#: executor/nodeModifyTable.c:1261 +#, c-format +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "다른 ì—…ë°ì´íЏ 작업으로 ì—…ë°ì´íŠ¸í•  íŠœí”Œì´ ì´ë¯¸ 다른 파티션으로 ì´ë™ë˜ì—ˆìŠµë‹ˆë‹¤" + +#: executor/nodeModifyTable.c:1412 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "" -#: executor/nodeModifyTable.c:1133 +#: executor/nodeModifyTable.c:1413 #, c-format -msgid "" -"Ensure that no rows proposed for insertion within the same command have " -"duplicate constrained values." +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "" -#: executor/nodeSamplescan.c:307 +#: executor/nodeSamplescan.c:279 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "TABLESAMPLE ì ˆì—는 반드시 부가 ì˜µì…˜ê°’ë“¤ì´ ìžˆì–´ì•¼ 합니다" -#: executor/nodeSamplescan.c:320 +#: executor/nodeSamplescan.c:291 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "TABLESAMPLE REPEATABLE ì ˆì€ ë” ì´ìƒì˜ 부가 ì˜µì…˜ì„ ì“°ë©´ 안ë©ë‹ˆë‹¤." -#: executor/nodeSubplan.c:345 executor/nodeSubplan.c:384 -#: executor/nodeSubplan.c:1036 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1116 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "표현ì‹ì— ì‚¬ìš©ëœ ì„œë¸Œì¿¼ë¦¬ 결과가 하나 ì´ìƒì˜ í–‰ì„ ë¦¬í„´í–ˆìŠµë‹ˆë‹¤" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeTableFuncscan.c:374 +#, c-format +msgid "namespace URI must not be null" +msgstr "네임스페ì´ìФ URI ê°’ì€ null ì¼ ìˆ˜ 없습니다." + +#: executor/nodeTableFuncscan.c:385 +#, c-format +msgid "row filter expression must not be null" +msgstr "로우 í•„í„° 표현ì‹ì€ nullê°’ì´ ì•„ë‹ˆì—¬ì•¼ 함" + +#: executor/nodeTableFuncscan.c:411 +#, c-format +msgid "column filter expression must not be null" +msgstr "칼럼 í•„í„° 표현ì‹ì€ nullê°’ì´ ì•„ë‹ˆì—¬ì•¼ 함" + +#: executor/nodeTableFuncscan.c:412 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "\"%s\" 칼럼용 í•„í„°ê°€ null입니다." + +#: executor/nodeTableFuncscan.c:502 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ null ê°’ì„ í—ˆìš©í•˜ì§€ 않습니다" + +#: executor/nodeWindowAgg.c:355 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "moving-aggregate transition 함수는 null ê°’ì„ ë°˜í™˜í•˜ë©´ 안ë©ë‹ˆë‹¤." -#: executor/nodeWindowAgg.c:1642 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "프래임 시작 위치값으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다." -#: executor/nodeWindowAgg.c:1655 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "프래임 시작 위치으로 ìŒìˆ˜ ê°’ì„ ì‚¬ìš©í•  수 없습니다." -#: executor/nodeWindowAgg.c:1668 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "프래임 ë 위치값으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다." -#: executor/nodeWindowAgg.c:1681 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "프래임 ë 위치값으로 ìŒìˆ˜ ê°’ì„ ì‚¬ìš©í•  수 없습니다." -#: executor/spi.c:210 +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "%s 집계 함수는 윈ë„ìš° 함수로 ì‚¬ìš©ë  ìˆ˜ 없습니다" + +#: executor/spi.c:233 executor/spi.c:272 +#, c-format +msgid "invalid transaction termination" +msgstr "ìž˜ëª»ëœ íŠ¸ëžœìž­ì…˜ 마침" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "í•˜ìœ„íŠ¸ëžœìž­ì…˜ì´ í™œì„±í™” ëœ ìƒíƒœì—서는 커밋 í•  수 ì—†ìŒ" + +#: executor/spi.c:278 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "í•˜ìœ„íŠ¸ëžœìž­ì…˜ì´ í™œì„±í™” ëœ ìƒíƒœì—서는 롤백 í•  수 ì—†ìŒ" + +#: executor/spi.c:317 #, c-format msgid "transaction left non-empty SPI stack" msgstr "íŠ¸ëžœìž­ì…˜ì´ ë¹„ì–´ìžˆì§€ ì•Šì€ SPI 스íƒì„ 남겼습니다" -#: executor/spi.c:211 executor/spi.c:275 +#: executor/spi.c:318 executor/spi.c:381 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "\"SPI_finish\" í˜¸ì¶œì´ ë¹ ì¡ŒëŠ”ì§€ 확ì¸í•˜ì„¸ìš”" -#: executor/spi.c:274 +#: executor/spi.c:380 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "하위 íŠ¸ëžœìž­ì…˜ì´ ë¹„ì–´ìžˆì§€ ì•Šì€ SPI 스íƒì„ 남겼습니다" -#: executor/spi.c:1225 +#: executor/spi.c:1270 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "멀티 쿼리를 커서로 ì—´ 수는 없습니다" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1230 +#: executor/spi.c:1275 #, c-format msgid "cannot open %s query as cursor" msgstr "%s 쿼리로 커서를 ì—´ 수 ì—†ìŒ." -#: executor/spi.c:1338 +#: executor/spi.c:1380 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE는 ì§€ì›ë˜ì§€ 않ìŒ" -#: executor/spi.c:1339 parser/analyze.c:2360 +#: executor/spi.c:1381 parser/analyze.c:2474 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "스í¬ë¡¤ 가능 커서는 READ ONLY여야 합니다." -#: executor/spi.c:2459 +#: executor/spi.c:2521 #, c-format msgid "SQL statement \"%s\"" msgstr "SQL 구문: \"%s\"" -#: executor/tqueue.c:317 +#: executor/tqueue.c:70 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "공유 메모리 í로 íŠœí”Œì„ ë³´ë‚¼ 수 ì—†ìŒ" -#: foreign/foreign.c:192 +#: foreign/foreign.c:188 #, c-format msgid "user mapping not found for \"%s\"" msgstr "\"%s\"ì— ëŒ€í•œ ì‚¬ìš©ìž ë§¤í•‘ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: foreign/foreign.c:644 +#: foreign/foreign.c:640 #, c-format msgid "invalid option \"%s\"" msgstr "\"%s\" ì˜µì…˜ì´ ìž˜ëª»ë¨" -#: foreign/foreign.c:645 +#: foreign/foreign.c:641 #, c-format msgid "Valid options in this context are: %s" msgstr "ì´ ì»¨í…스트ì—서 유효한 옵션: %s" -#: lib/stringinfo.c:259 +#: gram.y:1026 #, c-format -msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." -msgstr "%dë°”ì´íŠ¸ê°€ í¬í•¨ëœ 문ìžì—´ 버í¼ë¥¼ %dë°”ì´íЏ ë” í™•ìž¥í•  수 없습니다." +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD ì˜µì…˜ì€ ë”ì´ìƒ ì§€ì›í•˜ì§€ 않ìŒ" -#: libpq/auth.c:254 +#: gram.y:1027 #, c-format -msgid "authentication failed for user \"%s\": host rejected" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„ 실패했습니다: 호스트 ê±°ë¶€ë¨" +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "" -#: libpq/auth.c:257 +#: gram.y:1089 #, c-format -msgid "\"trust\" authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ \"trust\" ì¸ì¦ì„ 실패했습니다." +msgid "unrecognized role option \"%s\"" +msgstr "ì¸ì‹í•  수 없는 롤 옵션 \"%s\"" -#: libpq/auth.c:260 +#: gram.y:1336 gram.y:1351 #, c-format -msgid "Ident authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ Ident ì¸ì¦ì„ 실패했습니다." +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS 구문ì—서는 스키마 ìš”ì†Œë“¤ì„ í¬í•¨í•  수 없습니다." -#: libpq/auth.c:263 +#: gram.y:1496 #, c-format -msgid "Peer authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ peer ì¸ì¦ì„ 실패했습니다." +msgid "current database cannot be changed" +msgstr "현재 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 바꿀 수 ì—†ìŒ" -#: libpq/auth.c:267 +#: gram.y:1620 #, c-format -msgid "password authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ password ì¸ì¦ì„ 실패했습니다" +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "지역시간대 간격(time zone interval) ê°’ì€ ì‹œ(HOUR) ë˜ëŠ” 시분(HOUR TO MINUTE) ê°’ì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: libpq/auth.c:272 +#: gram.y:2138 #, c-format -msgid "GSSAPI authentication failed for user \"%s\"" -msgstr "\"%s\" 사용ìžì— 대한 GSSAPI ì¸ì¦ì„ 실패했습니다." +msgid "column number must be in range from 1 to %d" +msgstr "칼럼 번호는 1 - %d 사ì´ì˜ ë²”ìœ„ì— ìžˆì–´ì•¼ 합니다." -#: libpq/auth.c:275 +#: gram.y:2677 #, c-format -msgid "SSPI authentication failed for user \"%s\"" -msgstr "\"%s\" 사용ìžì— 대한 SSPI ì¸ì¦ì„ 실패했습니다." +msgid "sequence option \"%s\" not supported here" +msgstr "\"%s\" 시퀀스 ì˜µì…˜ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: libpq/auth.c:278 +#: gram.y:2706 #, c-format -msgid "PAM authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ PAM ì¸ì¦ì„ 실패했습니다." +msgid "modulus for hash partition provided more than once" +msgstr "해시 파티션용 ëª¨ë“ˆì„ í•œ 번 ì´ìƒ 지정했습니다" -#: libpq/auth.c:281 +#: gram.y:2715 #, c-format -msgid "BSD authentication failed for user \"%s\"" -msgstr "\"%s\" 사용ìžì— 대한 BSD ì¸ì¦ì„ 실패했습니다." +msgid "remainder for hash partition provided more than once" +msgstr "해시 파티션용 나머지 처리기를 한 번 ì´ìƒ 지정했습니다" -#: libpq/auth.c:284 +#: gram.y:2722 #, c-format -msgid "LDAP authentication failed for user \"%s\"" -msgstr "\"%s\" 사용ìžì˜ LDAP ì¸ì¦ì„ 실패했습니다." +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "ìž˜ëª»ëœ í•´ì‹œ 파티션 범위 명세 \"%s\"" -#: libpq/auth.c:287 +#: gram.y:2730 #, c-format -msgid "certificate authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„œ ì¸ì¦ì„ 실패했습니다" +msgid "modulus for hash partition must be specified" +msgstr "해시 파티션용 ëª¨ë“ˆì„ ì§€ì •í•˜ì„¸ìš”" -#: libpq/auth.c:290 +#: gram.y:2734 #, c-format -msgid "RADIUS authentication failed for user \"%s\"" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ RADIUS ì¸ì¦ì„ 실패했습니다." +msgid "remainder for hash partition must be specified" +msgstr "해시 파티션용 나머지 처리기를 지정하세요" -#: libpq/auth.c:293 +#: gram.y:2986 gram.y:3015 #, c-format -msgid "authentication failed for user \"%s\": invalid authentication method" -msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„ 실패했습니다: ìž˜ëª»ëœ ì¸ì¦ 방법" +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "PROGRAM 옵션과 STDIN/STDOUT ì˜µì…˜ì€ í•¨ê»˜ 쓸 수 없습니다" -#: libpq/auth.c:297 +#: gram.y:3325 gram.y:3332 gram.y:11465 gram.y:11473 #, c-format -msgid "Connection matched pg_hba.conf line %d: \"%s\"" -msgstr "pg_hba.conf 파ì¼ì˜ %d번째 ì¤„ì— ì§€ì •í•œ ì¸ì¦ ì„¤ì •ì´ ì‚¬ìš©ë¨: \"%s\"" +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL 예약어는 임시 í…Œì´ë¸” 만들기ì—서 ë” ì´ìƒ 사용하지 않습니다" -#: libpq/auth.c:352 +#: gram.y:3817 utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 +#: utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 +#: utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 +#: utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 +#: utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 #, c-format -msgid "connection requires a valid client certificate" -msgstr "ì—°ê²°ì— ìœ íš¨í•œ í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œê°€ 필요함" +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL ê¸°ëŠ¥ì€ ì•„ì§ êµ¬í˜„ 안ë˜ì—ˆìŠµë‹ˆë‹¤" -#: libpq/auth.c:394 +#: gram.y:5299 #, c-format -msgid "" -"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", %s ì—°ê²°ì´ ë³µì œìš© 연결로는 pg_hba.conf íŒŒì¼ ì„¤ì •" -"ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" - -#: libpq/auth.c:396 libpq/auth.c:412 libpq/auth.c:470 libpq/auth.c:488 -msgid "SSL off" -msgstr "SSL 중지" - -#: libpq/auth.c:396 libpq/auth.c:412 libpq/auth.c:470 libpq/auth.c:488 -msgid "SSL on" -msgstr "SSL ë™ìž‘" +msgid "unrecognized row security option \"%s\"" +msgstr "ì¸ì‹í•  수 없는 로우 단위 보안 옵션 \"%s\"" -#: libpq/auth.c:400 +#: gram.y:5300 #, c-format -msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\" ì—°ê²°ì´ ë³µì œìš© 연결로는 pg_hba.conf íŒŒì¼ ì„¤ì •ì— " -"ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" -#: libpq/auth.c:409 -#, c-format -msgid "" -"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" -"\", %s" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\", %s ì—°ê²°ì´ pg_hba.conf 파" -"ì¼ ì„¤ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" +#: gram.y:5408 +msgid "duplicate trigger events specified" +msgstr "중복 트리거 ì´ë²¤íŠ¸ê°€ 지정ë¨" -#: libpq/auth.c:416 +#: gram.y:5549 parser/parse_utilcmd.c:3315 parser/parse_utilcmd.c:3341 #, c-format -msgid "" -"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\" ì—°ê²°ì´ pg_hba.conf íŒŒì¼ ì„¤" -"ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "INITIALLY DEFERRED 로 ì„ ì–¸ëœ ì¡°ê±´ë¬¸ì€ ë°˜ë“œì‹œ DEFERABLE 여야만 한다" -#: libpq/auth.c:445 +#: gram.y:5556 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup matches." -msgstr "" -"í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ìœ¼ë¡œ ë§žìŒ" +msgid "conflicting constraint properties" +msgstr "제약조건 ì†ì„±ì´ ì¶©ëŒí•¨" -#: libpq/auth.c:448 +#: gram.y:5662 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup not checked." -msgstr "" -"í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ 사용안함" +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" -#: libpq/auth.c:451 +#: gram.y:5677 #, c-format -msgid "Client IP address resolved to \"%s\", forward lookup does not match." -msgstr "" -"í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ìœ¼ë¡œ 틀림" +msgid "DROP ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" -#: libpq/auth.c:454 +#: gram.y:6057 #, c-format -msgid "Could not translate client host name \"%s\" to IP address: %s." -msgstr "\"%s\" í´ë¼ì´ì–¸íЏ 호스트 ì´ë¦„ì„ %s IP 주소로 전환할 수 ì—†ìŒ." +msgid "RECHECK is no longer required" +msgstr "RECHECK는 ë” ì´ìƒ 필요하지 않ìŒ" -#: libpq/auth.c:459 +#: gram.y:6058 #, c-format -msgid "Could not resolve client IP address to a host name: %s." -msgstr "í´ë¼ì´ì–¸íЏ IP 주소를 파악할 수 ì—†ìŒ: ëŒ€ìƒ í˜¸ìŠ¤íŠ¸ ì´ë¦„: %s" +msgid "Update your data type." +msgstr "ìžë£Œí˜•ì„ ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤." -#: libpq/auth.c:468 +#: gram.y:7794 #, c-format -msgid "" -"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s" -"\", %s" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", %s ì—°ê²°ì´ ë³µì œìš© 연결로 pg_hba.conf 파ì¼ì— 설정" -"ë˜ì–´ 있지 않습니다" +msgid "aggregates cannot have output arguments" +msgstr "집계 함수는 output ì¸ìžë¥¼ 지정할 수 ì—†ìŒ" -#: libpq/auth.c:475 +#: gram.y:8182 utils/adt/regproc.c:691 utils/adt/regproc.c:732 #, c-format -msgid "" -"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\" ì—°ê²°ì´ ë³µì œìš© 연결로 pg_hba.conf 파ì¼ì— 설정ë˜" -"ì–´ 있지 않습니다" +msgid "missing argument" +msgstr "ì¸ìžê°€ 빠졌ìŒ" -#: libpq/auth.c:485 +#: gram.y:8183 utils/adt/regproc.c:692 utils/adt/regproc.c:733 #, c-format -msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\", %s ì—°ê²°ì— ëŒ€í•œ ì„¤ì •ì´ " -"pg_hba.conf 파ì¼ì— 없습니다." +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "단항 ì—°ì‚°ìžì—서 ì¸ìž ì—†ìŒì„ 표시할 때는 NONE ì¸ìžë¥¼ 사용하세요." -#: libpq/auth.c:493 +#: gram.y:10048 gram.y:10066 #, c-format -msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" -msgstr "" -"호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\" ì—°ê²°ì— ëŒ€í•œ ì„¤ì •ì´ pg_hba." -"conf 파ì¼ì— 없습니다." +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION êµ¬ë¬¸ì€ ìž¬ê·€ì ì¸ ë·°ì—서 ì§€ì›í•˜ì§€ 않습니다" -#: libpq/auth.c:536 libpq/hba.c:1178 +#: gram.y:10563 #, c-format -msgid "" -"MD5 authentication is not supported when \"db_user_namespace\" is enabled" -msgstr "\"db_user_namespace\"ê°€ 사용 가능한 경우 MD5 ì¸ì¦ì€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "unrecognized VACUUM option \"%s\"" +msgstr "ì¸ì‹í•  수 없는 VACUUM 옵션 \"%s\"" -#: libpq/auth.c:670 +#: gram.y:11573 #, c-format -msgid "expected password response, got message type %d" -msgstr "메시지 타입 %d를 얻는 예ìƒëœ 암호 ì‘답" +msgid "LIMIT #,# syntax is not supported" +msgstr "LIMIT #,# êµ¬ë¬¸ì€ ì§€ì›í•˜ì§€ 않습니다." -#: libpq/auth.c:698 +#: gram.y:11574 #, c-format -msgid "invalid password packet size" -msgstr "유효하지 ì•Šì€ ì•”í˜¸ 패킷 사ì´ì¦ˆ" +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "LIMIT # OFFSET # êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: libpq/auth.c:828 +#: gram.y:11872 gram.y:11897 #, c-format -msgid "GSSAPI is not supported in protocol version 2" -msgstr "프로토콜 버전 2ì—서는 GSSAPIê°€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "VALUES in FROM must have an alias" +msgstr "FROM ì•ˆì˜ VALUES는 반드시 aliasê°€ 있어야합니다" -#: libpq/auth.c:888 +#: gram.y:11873 gram.y:11898 #, c-format -msgid "expected GSS response, got message type %d" -msgstr "GSS ì‘ë‹µì´ í•„ìš”í•œë° ë©”ì‹œì§€ í˜•ì‹ %dì„(를) ë°›ìŒ" - -#: libpq/auth.c:949 -msgid "accepting GSS security context failed" -msgstr "GSS 보안 컨í…스트를 수ë½í•˜ì§€ 못함" - -#: libpq/auth.c:975 -msgid "retrieving GSS user name failed" -msgstr "GSS ì‚¬ìš©ìž ì´ë¦„ì„ ê²€ìƒ‰í•˜ì§€ 못함" +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "예, FROM (VALUES ...) [AS] foo." -#: libpq/auth.c:1094 +#: gram.y:11878 gram.y:11903 #, c-format -msgid "SSPI is not supported in protocol version 2" -msgstr "프로토콜 버전 2ì—서는 SSPIê°€ ì§€ì›ë˜ì§€ 않ìŒ" - -#: libpq/auth.c:1109 -msgid "could not acquire SSPI credentials" -msgstr "SSPI ìžê²© ì¦ëª…ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" +msgid "subquery in FROM must have an alias" +msgstr "FROM ì ˆ ë‚´ì˜ subquery ì—는 반드시 alias 를 가져야만 합니다" -#: libpq/auth.c:1127 +#: gram.y:11879 gram.y:11904 #, c-format -msgid "expected SSPI response, got message type %d" -msgstr "SSPI ì‘ë‹µì´ í•„ìš”í•œë° ë©”ì‹œì§€ í˜•ì‹ %dì„(를) ë°›ìŒ" - -#: libpq/auth.c:1199 -msgid "could not accept SSPI security context" -msgstr "SSPI 보안 컨í…스트를 수ë½í•  수 ì—†ìŒ" - -#: libpq/auth.c:1261 -msgid "could not get token from SSPI security context" -msgstr "SSPI 보안 컨í…스트ì—서 토í°ì„ 가져올 수 ì—†ìŒ" +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "예, FROM (SELECT ...) [AS] foo." -#: libpq/auth.c:1380 libpq/auth.c:1399 +#: gram.y:12358 #, c-format -msgid "could not translate name" -msgstr "ì´ë¦„ì„ ë³€í™˜í•  수 ì—†ìŒ" +msgid "only one DEFAULT value is allowed" +msgstr "" -#: libpq/auth.c:1412 +#: gram.y:12367 #, c-format -msgid "realm name too long" -msgstr "realm ì´ë¦„ì´ ë„ˆë¬´ 긺" +msgid "only one PATH value per column is allowed" +msgstr "" -#: libpq/auth.c:1427 +#: gram.y:12376 #, c-format -msgid "translated account name too long" -msgstr "ë³€í™˜ëœ ì ‘ì†ìž ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "NULL/NOT NULL ì„ ì–¸ì´ ì„œë¡œ ì¶©ëŒí•©ë‹ˆë‹¤ : \"%s\" 칼럼" -#: libpq/auth.c:1613 +#: gram.y:12385 #, c-format -msgid "could not create socket for Ident connection: %m" -msgstr "Ident ì—°ê²°ì— ì†Œì¼“ì„ ìƒì„±í•  수 없습니다: %m" +msgid "unrecognized column option \"%s\"" +msgstr "ì¸ì‹í•  수 없는 칼럼 옵션 \"%s\"" -#: libpq/auth.c:1628 +#: gram.y:12639 #, c-format -msgid "could not bind to local address \"%s\": %m" -msgstr "로컬 주소 \"%s\"ì— ë°”ì¸ë“œí•  수 없습니다: %m" +msgid "precision for type float must be at least 1 bit" +msgstr "실수형 ìžë£Œì˜ ì •ë°€ë„ ê°’ìœ¼ë¡œëŠ” ì ì–´ë„ 1 bit ì´ìƒì„ 지정해야합니다." -#: libpq/auth.c:1640 +#: gram.y:12648 #, c-format -msgid "could not connect to Ident server at address \"%s\", port %s: %m" -msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버ì—게 ì—°ê²°í•  수 없습니다: %m" +msgid "precision for type float must be less than 54 bits" +msgstr "실수형 ìžë£Œì˜ ì •ë°€ë„ ê°’ìœ¼ë¡œ 최대 54 bit 까지입니다." -#: libpq/auth.c:1662 +#: gram.y:13139 #, c-format -msgid "could not send query to Ident server at address \"%s\", port %s: %m" -msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버ì—게 질ì˜ë¥¼ 보낼 수 없습니다: %m" +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPS ì‹ì˜ ì™¼ìª½ì— ìžˆëŠ” 매개 변수 수가 잘못ë¨" -#: libpq/auth.c:1679 +#: gram.y:13144 #, c-format -msgid "" -"could not receive response from Ident server at address \"%s\", port %s: %m" -msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버로부터 ì‘ë‹µì„ ë°›ì§€ 못했습니다: %m" +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPS ì‹ì˜ ì˜¤ë¥¸ìª½ì— ìžˆëŠ” 매개 변수 수가 잘못ë¨" -#: libpq/auth.c:1689 +#: gram.y:13319 #, c-format -msgid "invalidly formatted response from Ident server: \"%s\"" -msgstr "Ident 서버로부터 ìž˜ëª»ëœ í˜•íƒœì˜ ì‘답를 보냈습니다: \"%s\"" +msgid "UNIQUE predicate is not yet implemented" +msgstr "UNIQUE 술어는 ì•„ì§ êµ¬í˜„ë˜ì§€ 못했습니다" -#: libpq/auth.c:1729 +#: gram.y:13666 #, c-format -msgid "peer authentication is not supported on this platform" -msgstr "ì´ í”Œëž«í¼ì—서는 peer ì¸ì¦ì´ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "WITHIN GROUP 구문 안ì—서 ì¤‘ë³µëœ ORDER BY êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" -#: libpq/auth.c:1733 +#: gram.y:13671 #, c-format -msgid "could not get peer credentials: %m" -msgstr "신뢰성 피어를 ì–»ì„ ìˆ˜ 없습니다: %m" +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "DISTINCTê³¼ WITHIN GROUPì„ í•¨ê»˜ 쓸 수 없습니다" -#: libpq/auth.c:1742 +#: gram.y:13676 #, c-format -msgid "could not look up local user ID %ld: %s" -msgstr "UID %ld 해당하는 사용ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "VARIADICê³¼ WITHIN GROUPì„ í•¨ê»˜ 쓸 수 없습니다" -#: libpq/auth.c:1826 libpq/auth.c:2152 libpq/auth.c:2512 +#: gram.y:14129 gram.y:14152 #, c-format -msgid "empty password returned by client" -msgstr "비어있는 암호는 í´ë¼ì´ì–¸íŠ¸ì— ì˜í•´ ëŒë ¤ë³´ëƒˆìŠµë‹ˆë‹¤" +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "프레임 ì‹œìž‘ì€ UNBOUNDED FOLLOWINGì¼ ìˆ˜ ì—†ìŒ" -#: libpq/auth.c:1836 +#: gram.y:14134 #, c-format -msgid "error from underlying PAM layer: %s" -msgstr "잠재ì ì¸ PAM ë ˆì´ì–´ì—ì„œì˜ ì—러: %s" +msgid "frame starting from following row cannot end with current row" +msgstr "ë”°ë¼ì˜¤ëŠ” ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ í˜„ìž¬ ë¡œìš°ì˜ ëì¼ ìˆ˜ 없습니다" -#: libpq/auth.c:1917 +#: gram.y:14157 #, c-format -msgid "could not create PAM authenticator: %s" -msgstr "PAM ì¸ì¦ìžë¥¼ ìƒì„±í•  수 없습니다: %s" +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "프레임 ëì€ UNBOUNDED PRECEDINGì¼ ìˆ˜ ì—†ìŒ" -#: libpq/auth.c:1928 +#: gram.y:14163 #, c-format -msgid "pam_set_item(PAM_USER) failed: %s" -msgstr "pam_set_item(PAM_USER) 실패: %s" +msgid "frame starting from current row cannot have preceding rows" +msgstr "현재 ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ ì„ í–‰í•˜ëŠ” 로우를 가질 수 없습니다" -#: libpq/auth.c:1939 +#: gram.y:14170 #, c-format -msgid "pam_set_item(PAM_RHOST) failed: %s" -msgstr "pam_set_item(PAM_RHOST) 실패: %s" +msgid "frame starting from following row cannot have preceding rows" +msgstr "ë”°ë¼ì˜¤ëŠ” ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ ì„ í–‰í•˜ëŠ” 로우를 가질 수 없습니다" -#: libpq/auth.c:1950 +#: gram.y:14813 #, c-format -msgid "pam_set_item(PAM_CONV) failed: %s" -msgstr "pam_set_item(PAM_CONV) 실패: %s" +msgid "type modifier cannot have parameter name" +msgstr "ìžë£Œí˜• 한정ìžëŠ” 매개 변수 ì´ë¦„ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: libpq/auth.c:1961 +#: gram.y:14819 #, c-format -msgid "pam_authenticate failed: %s" -msgstr "PAM ì¸ì¦ 실패: %s" +msgid "type modifier cannot have ORDER BY" +msgstr "ìžë£Œí˜• 한정ìžëŠ” ORDER BY êµ¬ë¬¸ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: libpq/auth.c:1972 +#: gram.y:14884 gram.y:14891 #, c-format -msgid "pam_acct_mgmt failed: %s" -msgstr "pam_acct_mgmt 실패: %s" +msgid "%s cannot be used as a role name here" +msgstr "%s ì´ë¦„ì€ ì—¬ê¸°ì„œ 롤 ì´ë¦„으로 사용할 수 ì—†ìŒ" -#: libpq/auth.c:1983 -#, c-format -msgid "could not release PAM authenticator: %s" -msgstr "PAM ì¸ì¦ìžë¥¼ 릴리즈할 수 없습니다: %s" +#: gram.y:15562 gram.y:15751 +msgid "improper use of \"*\"" +msgstr "\"*\" ì‚¬ìš©ì´ ìž˜ëª»ë¨" -#: libpq/auth.c:2048 +#: gram.y:15714 gram.y:15731 tsearch/spell.c:954 tsearch/spell.c:971 +#: tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 #, c-format -msgid "could not initialize LDAP: %m" -msgstr "LDAP 초기화 실패: %m" +msgid "syntax error" +msgstr "구문 오류" -#: libpq/auth.c:2051 +#: gram.y:15815 #, c-format -msgid "could not initialize LDAP: error code %d" -msgstr "LDAP 초기화 실패: 오류번호 %d" +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "" -#: libpq/auth.c:2061 +#: gram.y:15852 #, c-format -msgid "could not set LDAP protocol version: %s" -msgstr "LDAP 프로토콜 ë²„ì „ì„ ì§€ì •í•  수 ì—†ìŒ: %s" +msgid "multiple ORDER BY clauses not allowed" +msgstr "ì¤‘ë³µëœ ORDER BY êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" -#: libpq/auth.c:2090 +#: gram.y:15863 #, c-format -msgid "could not load wldap32.dll" -msgstr "could not load wldap32.dll" +msgid "multiple OFFSET clauses not allowed" +msgstr "ì¤‘ë³µëœ OFFSET êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" -#: libpq/auth.c:2098 +#: gram.y:15872 #, c-format -msgid "could not load function _ldap_start_tls_sA in wldap32.dll" -msgstr "could not load function _ldap_start_tls_sA in wldap32.dll" +msgid "multiple LIMIT clauses not allowed" +msgstr "ì¤‘ë³µëœ LIMIT êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" -#: libpq/auth.c:2099 +#: gram.y:15881 #, c-format -msgid "LDAP over SSL is not supported on this platform." -msgstr "ì´ í”Œëž«í¼ì—서는 SSLì„ ì´ìš©í•œ LDAP ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ." +msgid "multiple WITH clauses not allowed" +msgstr "ì¤‘ë³µëœ WITH ì ˆì€ í—ˆìš©í•˜ì§€ 않ìŒ" -#: libpq/auth.c:2114 +#: gram.y:16085 #, c-format -msgid "could not start LDAP TLS session: %s" -msgstr "LDAP TLS ì„¸ì…˜ì„ ì‹œìž‘í•  수 ì—†ìŒ: %s" +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "OUT ë° INOUT ì¸ìžëŠ” TABLE í•¨ìˆ˜ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: libpq/auth.c:2136 +#: gram.y:16186 #, c-format -msgid "LDAP server not specified" -msgstr "LDAP 서버가 지정ë˜ì§€ 않ìŒ" +msgid "multiple COLLATE clauses not allowed" +msgstr "ì¤‘ë³µëœ COLLATE êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" -#: libpq/auth.c:2189 +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16224 gram.y:16237 #, c-format -msgid "invalid character in user name for LDAP authentication" -msgstr "LDAP ì¸ì¦ì„ 위한 ì‚¬ìš©ìž ì´ë¦„ì— ì‚¬ìš©í•  수 없는 문ìžê°€ 있습니다" +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "%s 제약조건ì—는 DEFERRABLE ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" -#: libpq/auth.c:2204 +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16250 #, c-format -msgid "" -"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": " -"%s" -msgstr "" -"\"%s\" ldapbinddn (해당 서버: \"%s\") ì„¤ì •ì— ëŒ€í•œ LDAP ë°”ì¸ë“œ 초기화를 í•  수 " -"ì—†ìŒ: %s" +msgid "%s constraints cannot be marked NOT VALID" +msgstr "%s 제약조건ì—는 NOT VALID ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" -#: libpq/auth.c:2228 +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16263 #, c-format -msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" -msgstr "\"%s\" 필터로 LDAP 검색 실패함, ëŒ€ìƒ ì„œë²„: \"%s\": %s" +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "%s 제약조건ì—는 NO INHERIT ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" -#: libpq/auth.c:2239 +#: guc-file.l:316 #, c-format -msgid "LDAP user \"%s\" does not exist" -msgstr "\"%s\" LDAP 사용ìžê°€ ì—†ìŒ" +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "알 수 없는 환경 매개 변수 ì´ë¦„: \"%s\", 해당 파ì¼: \"%s\", 줄번호: %u" -#: libpq/auth.c:2240 +#: guc-file.l:353 utils/misc/guc.c:6239 utils/misc/guc.c:6433 +#: utils/misc/guc.c:6523 utils/misc/guc.c:6613 utils/misc/guc.c:6721 +#: utils/misc/guc.c:6816 #, c-format -msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." -msgstr "\"%s\" 필터로 \"%s\" 서버ì—서 LDAP ê²€ìƒ‰ì„ í–ˆìœ¼ë‚˜, 해당 ìžë£Œê°€ ì—†ìŒ" +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "\"%s\" 매개 변수는 서버 재실행 ì—†ì´ ì§€ê¸ˆ 변경 ë  ìˆ˜ ì—†ìŒ" -#: libpq/auth.c:2244 +#: guc-file.l:389 #, c-format -msgid "LDAP user \"%s\" is not unique" -msgstr "\"%s\" LDAP 사용ìžê°€ 유ì¼í•˜ì§€ 않습니다" +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "환경설정 파ì¼ì— \"%s\" 매개 변수가 빠졌ìŒ, ì´ˆê¸°ê°’ì„ ì‚¬ìš©í•¨" -#: libpq/auth.c:2245 +#: guc-file.l:455 #, c-format -msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." -msgid_plural "" -"LDAP search for filter \"%s\" on server \"%s\" returned %d entries." -msgstr[0] "\"%s\" 필터로 \"%s\" 서버ì—서 LDAP 검색 ê²°ê³¼ %d í•­ëª©ì„ ë°˜í™˜í•¨" +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "\"%s\" 매개 변수 ê°’ì„ \"%s\"(으)로 바꿨ìŒ" -#: libpq/auth.c:2263 +#: guc-file.l:497 #, c-format -msgid "" -"could not get dn for the first entry matching \"%s\" on server \"%s\": %s" -msgstr "\"%s\" 첫번째 항목 조회용 dn ê°’ì„ \"%s\" 서버ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" +msgid "configuration file \"%s\" contains errors" +msgstr "\"%s\" 환경 설정파ì¼ì— 오류가 있ìŒ" -#: libpq/auth.c:2283 +#: guc-file.l:502 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "\"%s\" ì‚¬ìš©ìž ê²€ìƒ‰ 후 unbind ìž‘ì—…ì„ \"%s\" 서버ì—서 í•  수 ì—†ìŒ: %s" +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "\"%s\" 환경 설정 파ì¼ì— 오류가 있어 새로 ë³€ê²½ë  ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤" -#: libpq/auth.c:2313 +#: guc-file.l:507 #, c-format -msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" -msgstr "\"%s\" 사용ìžì˜ \"%s\" LDAP 서버 ë¡œê·¸ì¸ ì‹¤íŒ¨: %s" - -#: libpq/auth.c:2341 -#, c-format -msgid "" -"certificate authentication failed for user \"%s\": client certificate " -"contains no user name" -msgstr "" -"\"%s\" 사용ìžì— 대한 ì¸ì¦ì„œ ë¡œê·¸ì¸ ì‹¤íŒ¨: í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œì— ì‚¬ìš©ìž ì´ë¦„ì´ ì—†" -"ìŒ" - -#: libpq/auth.c:2468 -#, c-format -msgid "RADIUS server not specified" -msgstr "RADIUS 서버가 지정ë˜ì§€ 않ìŒ" - -#: libpq/auth.c:2475 -#, c-format -msgid "RADIUS secret not specified" -msgstr "RADIUS 비밀키가 지정ë˜ì§€ 않ìŒ" +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "\"%s\" 환경 설정 파ì¼ì— 오류가 있어 아무 ì„¤ì •ë„ ë°˜ì˜ë˜ì§€ 않았습니다." -#: libpq/auth.c:2491 libpq/hba.c:1632 +#: guc-file.l:580 #, c-format -msgid "could not translate RADIUS server name \"%s\" to address: %s" -msgstr "\"%s\" RADIUS 서버 ì´ë¦„ì„ ì£¼ì†Œë¡œ 바꿀 수 ì—†ìŒ: %s" +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "설정 íŒŒì¼ \"%s\"ì„ ì—´ 수 없습니다: 최대 디렉터리 깊ì´ë¥¼ 초과했ìŒ" -#: libpq/auth.c:2519 +#: guc-file.l:596 libpq/hba.c:2142 libpq/hba.c:2547 #, c-format -msgid "" -"RADIUS authentication does not support passwords longer than %d characters" -msgstr "RADIUS ì¸ì¦ì€ %d ê¸€ìž ë³´ë‹¤ í° ë¹„ë°€ë²ˆí˜¸ ì¸ì¦ì„ ì§€ì›í•˜ì§€ 않습니다" +msgid "could not open configuration file \"%s\": %m" +msgstr "\"%s\" 설정 íŒŒì¼ ì„ ì—´ìˆ˜ 없습니다: %m" -#: libpq/auth.c:2531 +#: guc-file.l:607 #, c-format -msgid "could not generate random encryption vector" -msgstr "무작위 암호화 벡터를 만들 수 ì—†ìŒ" +msgid "skipping missing configuration file \"%s\"" +msgstr "\"%s\" 환경 설정파ì¼ì´ 없으나 건너뜀" -#: libpq/auth.c:2569 +#: guc-file.l:861 #, c-format -msgid "could not perform MD5 encryption of password" -msgstr "ë¹„ë°€ë²ˆí˜¸ì˜ MD5 암호를 만들 수 ì—†ìŒ" +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "\"%s\" íŒŒì¼ %u 줄 ë부분ì—서 구문 오류 있ìŒ" -# translator: %s is IPv4, IPv6, or Unix -#: libpq/auth.c:2594 +#: guc-file.l:871 #, c-format -msgid "could not create RADIUS socket: %m" -msgstr "RADIUS ì†Œì¼“ì„ ìƒì„±í•  수 없습니다: %m" +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "\"%s\" íŒŒì¼ %u 줄ì—서 구문 오류 있ìŒ, \"%s\" í† í° ë¶€ê·¼" -# translator: %s is IPv4, IPv6, or Unix -#: libpq/auth.c:2615 +#: guc-file.l:891 #, c-format -msgid "could not bind local RADIUS socket: %m" -msgstr "RADIUS ì†Œì¼“ì— ë°”ì¸ë“œí•  수 없습니다: %m" +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "구문 오류가 너무 많습니다. \"%s\" 파ì¼ì„ 무시합니다" -#: libpq/auth.c:2625 +#: guc-file.l:943 #, c-format -msgid "could not send RADIUS packet: %m" -msgstr "RADIUS íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %m" +msgid "could not open configuration directory \"%s\": %m" +msgstr "\"%s\" 환경 설정 디렉터리를 ì—´ 수 없습니다: %m" -#: libpq/auth.c:2658 libpq/auth.c:2683 +#: jit/jit.c:197 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 +#: utils/fmgr/dfmgr.c:466 #, c-format -msgid "timeout waiting for RADIUS response" -msgstr "서버 ì‹œìž‘ì„ ê¸°ë‹¤ë¦¬ëŠ” ë™ì•ˆ 시간 초과ë¨" +msgid "could not access file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì— 액세스할 수 ì—†ìŒ: %m" -# translator: %s is IPv4, IPv6, or Unix -#: libpq/auth.c:2676 +#: jit/llvm/llvmjit.c:598 #, c-format -msgid "could not check status on RADIUS socket: %m" -msgstr "RADIUS 소켓 ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "" -#: libpq/auth.c:2705 +#: lib/dshash.c:247 utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 #, c-format -msgid "could not read RADIUS response: %m" -msgstr "RADIUS ì‘ë‹µì„ ì½ì„ 수 ì—†ìŒ: %m" +msgid "Failed on DSA request of size %zu." +msgstr "í¬ê¸°ê°€ %zuì¸ DSA 요청ì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: libpq/auth.c:2717 libpq/auth.c:2721 +#: lib/stringinfo.c:278 #, c-format -msgid "RADIUS response was sent from incorrect port: %d" -msgstr "RADIUS ì‘ë‹µì´ ë°”ë¥´ì§€ ì•Šì€ í¬íŠ¸ë¡œë¶€í„° 보내졌ìŒ: %d" +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "%dë°”ì´íŠ¸ê°€ í¬í•¨ëœ 문ìžì—´ 버í¼ë¥¼ %dë°”ì´íЏ ë” í™•ìž¥í•  수 없습니다." -#: libpq/auth.c:2730 +#: libpq/auth-scram.c:251 #, c-format -msgid "RADIUS response too short: %d" -msgstr "RADIUS ì‘ë‹µì´ ë„ˆë¬´ ì§§ìŒ: %d" +msgid "client selected an invalid SASL authentication mechanism" +msgstr "í´ë¼ì´ì–¸íŠ¸ê°€ ìž˜ëª»ëœ SASL ì¸ì¦ ë©”ì¹´ë‹ˆì¦˜ì„ ì„ íƒí–ˆìŒ" -#: libpq/auth.c:2737 +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 #, c-format -msgid "RADIUS response has corrupt length: %d (actual length %d)" -msgstr "RADIUS ì‘답 길ì´ê°€ ì´ìƒí•¨: %d (실재 길ì´: %d)" +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "\"%s\" 사용ìžì— 대한 ìž˜ëª»ëœ SCRAM 유요성 검사" -#: libpq/auth.c:2745 +#: libpq/auth-scram.c:283 #, c-format -msgid "RADIUS response is to a different request: %d (should be %d)" -msgstr "RADIUS ì‘ë‹µì´ ìš”ì²­ê³¼ 다름: %d (기대값: %d)" +msgid "User \"%s\" does not have a valid SCRAM verifier." +msgstr "\"%s\" 사용ìžìš© 바른 SCRAM 유효성 검사가 없습니다." -#: libpq/auth.c:2770 +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 +#: libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 +#: libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 +#: libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 +#: libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 #, c-format -msgid "could not perform MD5 encryption of received packet" -msgstr "ë°›ì€ íŒ¨í‚·ì„ ëŒ€ìƒìœ¼ë¡œ MD5 암호화 작업할 수 ì—†ìŒ" +msgid "malformed SCRAM message" +msgstr "SCRAM 메시지가 형ì‹ì— ë§žì§€ 않습니다" -#: libpq/auth.c:2779 +#: libpq/auth-scram.c:362 #, c-format -msgid "RADIUS response has incorrect MD5 signature" -msgstr "RADIUS ì‘ë‹µì˜ MD5 ê°’ì´ ì´ìƒí•¨" +msgid "The message is empty." +msgstr "메시지가 비었습니다." -#: libpq/auth.c:2796 +#: libpq/auth-scram.c:367 #, c-format -msgid "RADIUS response has invalid code (%d) for user \"%s\"" -msgstr "RADIUS ì‘ë‹µì´ ë°”ë¥´ì§€ ì•Šì€ ê°’ìž„ (%d), ëŒ€ìƒ ì‚¬ìš©ìž: \"%s\"" +msgid "Message length does not match input length." +msgstr "메시지 길ì´ê°€ ìž…ë ¥ 길ì´ì™€ 같지 않습니다." -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 -#: libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 -#: libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 +#: libpq/auth-scram.c:399 #, c-format -msgid "invalid large-object descriptor: %d" -msgstr "유효하지 ì•Šì€ ëŒ€í˜• ê°ì²´ 설명: %d" +msgid "invalid SCRAM response" +msgstr "ìž˜ëª»ëœ SCRAM ì‘답" -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 -#: libpq/be-fsstubs.c:788 +#: libpq/auth-scram.c:400 #, c-format -msgid "permission denied for large object %u" -msgstr "%u 대형 ê°ì²´ì— 대한 ì ‘ê·¼ 권한 ì—†ìŒ" +msgid "Nonce does not match." +msgstr "í† í° ë¶ˆì¼ì¹˜" -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 +#: libpq/auth-scram.c:474 #, c-format -msgid "large object descriptor %d was not opened for writing" -msgstr "%d번 대형 ê°ì²´ 기술ìžê°€ 쓰기 모드로 열려있지 않습니다" +msgid "could not generate random salt" +msgstr "무작위 솔트 ìƒì„± 실패" -#: libpq/be-fsstubs.c:245 +#: libpq/auth-scram.c:661 #, c-format -msgid "lo_lseek result out of range for large-object descriptor %d" -msgstr "%d번 대형 ê°ì²´ 기술ìžì— 대한 lo_lseek ë°˜í™˜ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "\"%c\" ì†ì„±ì´ì–´ì•¼ 하는ë°, \"%s\" ìž„." -#: libpq/be-fsstubs.c:318 +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 #, c-format -msgid "lo_tell result out of range for large-object descriptor %d" -msgstr "%d번 대형 ê°ì²´ 기술ìžì— 대한 lo_tell ë°˜í™˜ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "\"%c\" ì†ì„±ì—는 \"=\" 문ìžê°€ 와야합니다." -#: libpq/be-fsstubs.c:455 +#: libpq/auth-scram.c:780 #, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "서버 측 lo_import() í˜¸ì¶œì„ í•˜ë ¤ë©´, 슈í¼ìœ ì €ì—¬ì•¼ 합니다" +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "ì†ì„±ê°’ì´ ì™€ì•¼í•˜ëŠ”ë°, \"%s\" ìž˜ëª»ëœ ë¬¸ìžê°€ 발견ë˜ì—ˆìŒ." -#: libpq/be-fsstubs.c:456 +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 #, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." msgstr "" -"libpq ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ ì´ìš©í•œ í´ë¼ì´ì–¸íЏ 측 lo_import() í˜¸ì¶œì€ ì•„ë¬´ë‚˜ í•  수 있습" -"니다." -#: libpq/be-fsstubs.c:469 +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 #, c-format -msgid "could not open server file \"%s\": %m" -msgstr "서버 íŒŒì¼ \"%s\"ì„ ì—´ 수 없습니다: %m" +msgid "Comma expected, but found character \"%s\"." +msgstr "쉼표가 와야하는ë°, \"%s\" 문ìžê°€ 발견ë˜ì—ˆìŒ." -#: libpq/be-fsstubs.c:491 +#: libpq/auth-scram.c:926 #, c-format -msgid "could not read server file \"%s\": %m" -msgstr "서버 íŒŒì¼ \"%s\"ì„ ì½ì„ 수 없습니다: %m" +msgid "SCRAM channel binding negotiation error" +msgstr "" -#: libpq/be-fsstubs.c:521 +#: libpq/auth-scram.c:927 #, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "서버 측 lo_export()는 슈í¼ìœ ì €ë§Œ 가능하다" +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "" -#: libpq/be-fsstubs.c:522 +#: libpq/auth-scram.c:949 #, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "아무나 libpqì— ì˜í•´ 제공ë˜ëŠ” í´ë¼ì´ì–¸íЏ 측 lo_export 를 사용할 수 있다" +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "" -#: libpq/be-fsstubs.c:547 +#: libpq/auth-scram.c:960 #, c-format -msgid "could not create server file \"%s\": %m" -msgstr "서버 íŒŒì¼ \"%s\"ì˜ ìƒì„±ì„ í•  수 없습니다: %m" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "ì§€ì›í•˜ì§€ 않는 SCRAM ì±„ë„ ë°”ì¸ë“œ 종류 \"%s\"" -#: libpq/be-fsstubs.c:559 +#: libpq/auth-scram.c:967 #, c-format -msgid "could not write server file \"%s\": %m" -msgstr "서버 íŒŒì¼ \"%s\"ì— ì“¸ 수 없습니다: %m" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "예ìƒì¹˜ 못한 ì±„ë„ ë°”ì¸ë”© 플래그 \"%s\"." -#: libpq/be-fsstubs.c:813 +#: libpq/auth-scram.c:977 #, c-format -msgid "large object read request is too large" -msgstr "대형 ê°ì²´ ì½ê¸° ìš”ì²­ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" +msgid "client uses authorization identity, but it is not supported" +msgstr "" -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:211 utils/adt/genfile.c:252 +#: libpq/auth-scram.c:982 #, c-format -msgid "requested length cannot be negative" -msgstr "요청한 길ì´ëŠ” ìŒìˆ˜ì¼ 수 ì—†ìŒ" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "" -#: libpq/be-secure-openssl.c:189 +#: libpq/auth-scram.c:998 #, c-format -msgid "could not create SSL context: %s" -msgstr "SSL 컨í…스트 정보를 ìƒì„±í•  수 없습니다: %s" +msgid "client requires an unsupported SCRAM extension" +msgstr "" -#: libpq/be-secure-openssl.c:205 +#: libpq/auth-scram.c:1012 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "서버 ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM 토í°ì— ì¸ì‡„í•  수 없는 문ìžê°€ 있ìŒ" -#: libpq/be-secure-openssl.c:211 +#: libpq/auth-scram.c:1129 #, c-format -msgid "could not access private key file \"%s\": %m" -msgstr "비밀키 \"%s\"ì— ì•¡ì„¸ìŠ¤í•  수 없습니다: %m" +msgid "could not generate random nonce" +msgstr "무작위 토í°ì„ 만들 수 ì—†ìŒ" -#: libpq/be-secure-openssl.c:217 +#: libpq/auth-scram.c:1233 #, c-format -msgid "private key file \"%s\" is not a regular file" -msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì€ ì¼ë°˜ 파ì¼ì´ 아님" +msgid "SCRAM channel binding check failed" +msgstr "" -#: libpq/be-secure-openssl.c:229 +#: libpq/auth-scram.c:1251 #, c-format -msgid "private key file \"%s\" must be owned by the database user or root" +msgid "unexpected SCRAM channel-binding attribute in client-final-message" msgstr "" -"\"%s\" ê°œì¸ í‚¤ 파ì¼ì˜ 소유주는 ë°ì´í„°ë² ì´ìФ 사용ìžì´ê±°ë‚˜ root 여야 합니다." -#: libpq/be-secure-openssl.c:249 +#: libpq/auth-scram.c:1268 #, c-format -msgid "private key file \"%s\" has group or world access" -msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì— 그룹 ë˜ëŠ” ìµëª… 액세스 ê¶Œí•œì´ ìžˆìŒ" +msgid "Malformed proof in client-final-message." +msgstr "" -#: libpq/be-secure-openssl.c:251 +#: libpq/auth-scram.c:1276 #, c-format -msgid "" -"File must have permissions u=rw (0600) or less if owned by the database " -"user, or permissions u=rw,g=r (0640) or less if owned by root." +msgid "Garbage found at the end of client-final-message." msgstr "" -"파ì¼ì˜ 소유주가 ë°ì´í„°ë² ì´ìФ 서버 ìš´ì˜ ê³„ì •ê³¼ 같다면, ì ‘ê·¼ ê¶Œí•œì„ u=rw " -"(0600) ë˜ëŠ” ë” ìž‘ê²Œ 설정하고, rootê°€ 소유주ë¼ë©´ u=rw,g=r (0640) 권한으로 지정" -"하세요" -#: libpq/be-secure-openssl.c:258 +#: libpq/auth.c:282 #, c-format -msgid "could not load private key file \"%s\": %s" -msgstr "비밀키 íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" +msgid "authentication failed for user \"%s\": host rejected" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„ 실패했습니다: 호스트 ê±°ë¶€ë¨" -#: libpq/be-secure-openssl.c:263 +#: libpq/auth.c:285 #, c-format -msgid "check of private key failed: %s" -msgstr "ë¹„ë°€í‚¤ì˜ í™•ì¸ ì‹¤íŒ¨: %s" +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ \"trust\" ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:292 +#: libpq/auth.c:288 #, c-format -msgid "could not load root certificate file \"%s\": %s" -msgstr "root ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" +msgid "Ident authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ Ident ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:316 +#: libpq/auth.c:291 #, c-format -msgid "SSL certificate revocation list file \"%s\" ignored" -msgstr "\"%s\" SSL ì¸ì¦ì„œ 파기 ëª©ë¡ íŒŒì¼ì´ 무시ë˜ì—ˆìŒ" +msgid "Peer authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ peer ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:318 +#: libpq/auth.c:296 #, c-format -msgid "SSL library does not support certificate revocation lists." -msgstr "SSL ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ ì¸ì¦ì„œ 파기 목ë¡ì„ ì§€ì›í•˜ì§€ 않습니다." +msgid "password authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ password ì¸ì¦ì„ 실패했습니다" -#: libpq/be-secure-openssl.c:323 +#: libpq/auth.c:301 #, c-format -msgid "could not load SSL certificate revocation list file \"%s\": %s" -msgstr "\"%s\" SSL ì¸ì¦ì„œ 회수 ëª©ë¡ íŒŒì¼ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "\"%s\" 사용ìžì— 대한 GSSAPI ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:370 +#: libpq/auth.c:304 #, c-format -msgid "could not initialize SSL connection: %s" -msgstr "SSLì—°ê²°ì„ ì´ˆê¸°í™”í•  수 없습니다: %s" +msgid "SSPI authentication failed for user \"%s\"" +msgstr "\"%s\" 사용ìžì— 대한 SSPI ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:378 +#: libpq/auth.c:307 #, c-format -msgid "could not set SSL socket: %s" -msgstr "SSL ì†Œì¼“ì„ ì§€ì •í•  수 없습니다: %s" +msgid "PAM authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ PAM ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:432 +#: libpq/auth.c:310 #, c-format -msgid "could not accept SSL connection: %m" -msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: %m" +msgid "BSD authentication failed for user \"%s\"" +msgstr "\"%s\" 사용ìžì— 대한 BSD ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:436 libpq/be-secure-openssl.c:447 +#: libpq/auth.c:313 #, c-format -msgid "could not accept SSL connection: EOF detected" -msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: EOF ê°ì§€ë¨" +msgid "LDAP authentication failed for user \"%s\"" +msgstr "\"%s\" 사용ìžì˜ LDAP ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:441 +#: libpq/auth.c:316 #, c-format -msgid "could not accept SSL connection: %s" -msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: %s" +msgid "certificate authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„œ ì¸ì¦ì„ 실패했습니다" -#: libpq/be-secure-openssl.c:452 libpq/be-secure-openssl.c:593 -#: libpq/be-secure-openssl.c:653 +#: libpq/auth.c:319 #, c-format -msgid "unrecognized SSL error code: %d" -msgstr "ì¸ì‹ë˜ì§€ ì•Šì€ SSL ì—러 코드 %d" +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ RADIUS ì¸ì¦ì„ 실패했습니다." -#: libpq/be-secure-openssl.c:496 +#: libpq/auth.c:322 #, c-format -msgid "SSL certificate's common name contains embedded null" -msgstr "SSL ì¸ì¦ì„œì˜ ì¼ë°˜ ì´ë¦„ì— í¬í•¨ëœ nullì´ ìžˆìŒ" +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "ì‚¬ìš©ìž \"%s\"ì˜ ì¸ì¦ì„ 실패했습니다: ìž˜ëª»ëœ ì¸ì¦ 방법" -#: libpq/be-secure-openssl.c:507 +#: libpq/auth.c:326 #, c-format -msgid "SSL connection from \"%s\"" -msgstr "\"%s\" ë¡œë¶€í„°ì˜ SSL ì—°ê²°" +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "pg_hba.conf 파ì¼ì˜ %d번째 ì¤„ì— ì§€ì •í•œ ì¸ì¦ ì„¤ì •ì´ ì‚¬ìš©ë¨: \"%s\"" -#: libpq/be-secure-openssl.c:584 libpq/be-secure-openssl.c:644 +#: libpq/auth.c:373 #, c-format -msgid "SSL error: %s" -msgstr "SSL ì—러: %s" +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "루트 ì¸ì¦ì„œ 저장소가 사용 가능한 경우ì—ë§Œ í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œë¥¼ 검사할 수 있ìŒ" -#: libpq/be-secure-openssl.c:1055 +#: libpq/auth.c:384 #, c-format -msgid "ECDH: unrecognized curve name: %s" -msgstr "ECDH: 알 수 없는 curve ì´ë¦„: %s" +msgid "connection requires a valid client certificate" +msgstr "ì—°ê²°ì— ìœ íš¨í•œ í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œê°€ 필요함" -#: libpq/be-secure-openssl.c:1060 +#: libpq/auth.c:417 #, c-format -msgid "ECDH: could not create key" -msgstr "ECDH: 키 ìƒì„± 실패" +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", %s ì—°ê²°ì´ ë³µì œìš© 연결로는 pg_hba.conf íŒŒì¼ ì„¤ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" -#: libpq/be-secure-openssl.c:1084 -msgid "no SSL error reported" -msgstr "SSL 오류 ì—†ìŒ" +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 +msgid "SSL off" +msgstr "SSL 중지" + +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 +msgid "SSL on" +msgstr "SSL ë™ìž‘" -#: libpq/be-secure-openssl.c:1088 +#: libpq/auth.c:423 #, c-format -msgid "SSL error code %lu" -msgstr "SSL 오류 번호 %lu" +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\" ì—°ê²°ì´ ë³µì œìš© 연결로는 pg_hba.conf íŒŒì¼ ì„¤ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" -#: libpq/be-secure.c:171 libpq/be-secure.c:256 +#: libpq/auth.c:432 #, c-format -msgid "terminating connection due to unexpected postmaster exit" -msgstr "postmasterì˜ ì˜ˆìƒì¹˜ 못한 종료로 ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\", %s ì—°ê²°ì´ pg_hba.conf íŒŒì¼ ì„¤ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" -#: libpq/crypt.c:54 +#: libpq/auth.c:439 #, c-format -msgid "Role \"%s\" does not exist." -msgstr "\"%s\" 롤 ì—†ìŒ" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\" ì—°ê²°ì´ pg_hba.conf íŒŒì¼ ì„¤ì •ì— ë”°ë¼ ê±°ë¶€ë©ë‹ˆë‹¤" -#: libpq/crypt.c:64 +#: libpq/auth.c:468 #, c-format -msgid "User \"%s\" has no password assigned." -msgstr "\"%s\" ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ ì•„ì§ í• ë‹¹ë˜ì§€ 않ìŒ" +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ìœ¼ë¡œ ë§žìŒ" -#: libpq/crypt.c:79 +#: libpq/auth.c:471 #, c-format -msgid "User \"%s\" has an empty password." -msgstr "\"%s\" ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ 설정ë˜ì–´ 있지 않습니다." +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ 사용안함" -#: libpq/crypt.c:159 +#: libpq/auth.c:474 #, c-format -msgid "User \"%s\" has an expired password." -msgstr "\"%s\" ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ 기한 만료ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "í´ë¼ì´ì–¸íЏ IP 주소가 \"%s\" ì´ë¦„으로 확ì¸ë¨, 호스트 ì´ë¦„ í™•ì¸ ê¸°ëŠ¥ìœ¼ë¡œ 틀림" -#: libpq/crypt.c:167 +#: libpq/auth.c:477 #, c-format -msgid "Password does not match for user \"%s\"." -msgstr "\"%s\" 사용ìžì˜ 비밀번호가 틀립니다." +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "\"%s\" í´ë¼ì´ì–¸íЏ 호스트 ì´ë¦„ì„ %s IP 주소로 전환할 수 ì—†ìŒ." -#: libpq/hba.c:188 +#: libpq/auth.c:482 #, c-format -msgid "authentication file token too long, skipping: \"%s\"" -msgstr "ì¸ì¦ 파ì¼ì˜ 토í°ì´ 너무 길어서 건너ëœë‹ˆë‹¤: \"%s\"" +msgid "Could not resolve client IP address to a host name: %s." +msgstr "í´ë¼ì´ì–¸íЏ IP 주소를 파악할 수 ì—†ìŒ: ëŒ€ìƒ í˜¸ìŠ¤íŠ¸ ì´ë¦„: %s" -#: libpq/hba.c:332 +#: libpq/auth.c:491 #, c-format -msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" -msgstr "2ì°¨ ì¸ì¦íŒŒì¼ \"%s\"으로 \"@%s\"를 ì—´ 수 없다: %m" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", %s ì—°ê²°ì´ ë³µì œìš© 연결로 pg_hba.conf 파ì¼ì— 설정ë˜ì–´ 있지 않습니다" -#: libpq/hba.c:407 +#: libpq/auth.c:498 #, c-format -msgid "authentication file line too long" -msgstr "ì¸ì¦ íŒŒì¼ ì¤„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\" ì—°ê²°ì´ ë³µì œìš© 연결로 pg_hba.conf 파ì¼ì— 설정ë˜ì–´ 있지 않습니다" -#: libpq/hba.c:408 libpq/hba.c:755 libpq/hba.c:771 libpq/hba.c:801 -#: libpq/hba.c:847 libpq/hba.c:860 libpq/hba.c:882 libpq/hba.c:891 -#: libpq/hba.c:912 libpq/hba.c:924 libpq/hba.c:943 libpq/hba.c:964 -#: libpq/hba.c:975 libpq/hba.c:1030 libpq/hba.c:1048 libpq/hba.c:1060 -#: libpq/hba.c:1077 libpq/hba.c:1087 libpq/hba.c:1101 libpq/hba.c:1117 -#: libpq/hba.c:1132 libpq/hba.c:1143 libpq/hba.c:1179 libpq/hba.c:1217 -#: libpq/hba.c:1228 libpq/hba.c:1248 libpq/hba.c:1259 libpq/hba.c:1276 -#: libpq/hba.c:1325 libpq/hba.c:1362 libpq/hba.c:1372 libpq/hba.c:1428 -#: libpq/hba.c:1440 libpq/hba.c:1453 libpq/hba.c:1545 libpq/hba.c:1634 -#: libpq/hba.c:1652 libpq/hba.c:1673 tsearch/ts_locale.c:182 +#: libpq/auth.c:508 #, c-format -msgid "line %d of configuration file \"%s\"" -msgstr "%d번째 줄(\"%s\" 환경 설정 파ì¼)" +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\", %s ì—°ê²°ì— ëŒ€í•œ ì„¤ì •ì´ pg_hba.conf 파ì¼ì— 없습니다." -#. translator: the second %s is a list of auth methods -#: libpq/hba.c:753 +#: libpq/auth.c:516 #, c-format -msgid "" -"authentication option \"%s\" is only valid for authentication methods %s" -msgstr "\"%s\" ì¸ì¦ ì˜µì…˜ì€ %s ì¸ì¦ 방법ì—ë§Œ 유효함" +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "호스트 \"%s\", ì‚¬ìš©ìž \"%s\", ë°ì´í„°ë² ì´ìФ \"%s\" ì—°ê²°ì— ëŒ€í•œ ì„¤ì •ì´ pg_hba.conf 파ì¼ì— 없습니다." -#: libpq/hba.c:769 +#: libpq/auth.c:669 #, c-format -msgid "authentication method \"%s\" requires argument \"%s\" to be set" -msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì˜ ê²½ìš° \"%s\" ì¸ìžë¥¼ 설정해야 함" +msgid "expected password response, got message type %d" +msgstr "메시지 타입 %d를 얻는 예ìƒëœ 암호 ì‘답" -#: libpq/hba.c:790 +#: libpq/auth.c:697 #, c-format -msgid "missing entry in file \"%s\" at end of line %d" -msgstr "\"%s\" 파ì¼ì˜ %d번째 ì¤„ì˜ ë ë¼ì¸ì— ë¹ ì§„ 엔트리가 있습니다 " +msgid "invalid password packet size" +msgstr "유효하지 ì•Šì€ ì•”í˜¸ 패킷 사ì´ì¦ˆ" -#: libpq/hba.c:800 +#: libpq/auth.c:715 #, c-format -msgid "multiple values in ident field" -msgstr "ident ìžë¦¬ì— 여러 ê°’ì´ ìžˆìŒ" +msgid "empty password returned by client" +msgstr "비어있는 암호는 í´ë¼ì´ì–¸íŠ¸ì— ì˜í•´ ëŒë ¤ë³´ëƒˆìŠµë‹ˆë‹¤" -#: libpq/hba.c:845 +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format -msgid "multiple values specified for connection type" -msgstr "ì—°ê²° í˜•ì‹ ìžë¦¬ì— 여러 ê°’ì´ ìžˆìŒ" +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "\"db_user_namespace\"ê°€ 사용 가능한 경우 MD5 ì¸ì¦ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: libpq/hba.c:846 +#: libpq/auth.c:841 #, c-format -msgid "Specify exactly one connection type per line." -msgstr "한 ì¤„ì— í•˜ë‚˜ì˜ ì—°ê²° 형태만 지정해야 합니다" +msgid "could not generate random MD5 salt" +msgstr "무작위 MD5 솔트 ìƒì„± 실패" -#: libpq/hba.c:859 +#: libpq/auth.c:887 #, c-format -msgid "local connections are not supported by this build" -msgstr "로컬 ì ‘ì† ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." +msgid "SASL authentication is not supported in protocol version 2" +msgstr "프로토콜 버전 2ì—서는 SASL ì¸ì¦ì„ ì§€ì›ë˜ì§€ 않ìŒ" -#: libpq/hba.c:880 +#: libpq/auth.c:920 #, c-format -msgid "hostssl requires SSL to be turned on" -msgstr "hostssl ì ‘ì†ì€ SSL ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì–´ 있어야 합니다" +msgid "expected SASL response, got message type %d" +msgstr "SASL ì‘ë‹µì´ í•„ìš”í•œë° ë©”ì‹œì§€ í˜•ì‹ %dì„(를) ë°›ìŒ" -#: libpq/hba.c:881 +#: libpq/auth.c:1112 #, c-format -msgid "Set ssl = on in postgresql.conf." -msgstr "postgresql.conf 파ì¼ì— ssl = on ì„¤ì •ì„ í•˜ì„¸ìš”." +msgid "GSSAPI is not supported in protocol version 2" +msgstr "프로토콜 버전 2ì—서는 GSSAPIê°€ ì§€ì›ë˜ì§€ 않ìŒ" -#: libpq/hba.c:889 +#: libpq/auth.c:1172 #, c-format -msgid "hostssl is not supported by this build" -msgstr "ì´ ì„œë²„ëŠ” hostssl ì ‘ì† ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다." +msgid "expected GSS response, got message type %d" +msgstr "GSS ì‘ë‹µì´ í•„ìš”í•œë° ë©”ì‹œì§€ í˜•ì‹ %dì„(를) ë°›ìŒ" + +#: libpq/auth.c:1234 +msgid "accepting GSS security context failed" +msgstr "GSS 보안 컨í…스트를 수ë½í•˜ì§€ 못함" -#: libpq/hba.c:890 +#: libpq/auth.c:1260 +msgid "retrieving GSS user name failed" +msgstr "GSS ì‚¬ìš©ìž ì´ë¦„ì„ ê²€ìƒ‰í•˜ì§€ 못함" + +#: libpq/auth.c:1385 #, c-format -msgid "Compile with --with-openssl to use SSL connections." -msgstr "" -"SSL ì—°ê²°ì„ ì‚¬ìš©í•˜ê¸° 위해 --enable-ssl ì˜µì…˜ì„ ì‚¬ìš©í•´ì„œ 서버를 다시 ì»´íŒŒì¼ í•˜ì„¸" -"ìš”" +msgid "SSPI is not supported in protocol version 2" +msgstr "프로토콜 버전 2ì—서는 SSPIê°€ ì§€ì›ë˜ì§€ 않ìŒ" + +#: libpq/auth.c:1400 +msgid "could not acquire SSPI credentials" +msgstr "SSPI ìžê²© ì¦ëª…ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" -#: libpq/hba.c:910 +#: libpq/auth.c:1418 #, c-format -msgid "invalid connection type \"%s\"" -msgstr "\"%s\" ê°’ì€ ìž˜ëª»ëœ ì—°ê²° 형ì‹ìž…니다" +msgid "expected SSPI response, got message type %d" +msgstr "SSPI ì‘ë‹µì´ í•„ìš”í•œë° ë©”ì‹œì§€ í˜•ì‹ %dì„(를) ë°›ìŒ" + +#: libpq/auth.c:1491 +msgid "could not accept SSPI security context" +msgstr "SSPI 보안 컨í…스트를 수ë½í•  수 ì—†ìŒ" + +#: libpq/auth.c:1553 +msgid "could not get token from SSPI security context" +msgstr "SSPI 보안 컨í…스트ì—서 토í°ì„ 가져올 수 ì—†ìŒ" -#: libpq/hba.c:923 +#: libpq/auth.c:1672 libpq/auth.c:1691 #, c-format -msgid "end-of-line before database specification" -msgstr "ë°ì´í„°ë² ì´ìФ 지정 ì „ì— ì¤„ ëì— ë„달함" +msgid "could not translate name" +msgstr "ì´ë¦„ì„ ë³€í™˜í•  수 ì—†ìŒ" -#: libpq/hba.c:942 +#: libpq/auth.c:1704 #, c-format -msgid "end-of-line before role specification" -msgstr "롤 지정 ì „ì— ì¤„ ëì— ë„달함" +msgid "realm name too long" +msgstr "realm ì´ë¦„ì´ ë„ˆë¬´ 긺" -#: libpq/hba.c:963 +#: libpq/auth.c:1719 #, c-format -msgid "end-of-line before IP address specification" -msgstr "IP 주소 지정 ì „ì— ì¤„ ëì— ë„달함" +msgid "translated account name too long" +msgstr "ë³€í™˜ëœ ì ‘ì†ìž ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" -#: libpq/hba.c:973 +#: libpq/auth.c:1905 #, c-format -msgid "multiple values specified for host address" -msgstr "호스트 주소 ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" +msgid "could not create socket for Ident connection: %m" +msgstr "Ident ì—°ê²°ì— ì†Œì¼“ì„ ìƒì„±í•  수 없습니다: %m" -#: libpq/hba.c:974 +#: libpq/auth.c:1920 #, c-format -msgid "Specify one address range per line." -msgstr "한 ì¤„ì— í•˜ë‚˜ì˜ ì£¼ì†Œ 범위가 있어야 합니다." +msgid "could not bind to local address \"%s\": %m" +msgstr "로컬 주소 \"%s\"ì— ë°”ì¸ë“œí•  수 없습니다: %m" -#: libpq/hba.c:1028 +#: libpq/auth.c:1932 #, c-format -msgid "invalid IP address \"%s\": %s" -msgstr "\"%s\" 형태는 ìž˜ëª»ëœ IP 주소 형태입니다: %s" +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버ì—게 ì—°ê²°í•  수 없습니다: %m" -#: libpq/hba.c:1046 +#: libpq/auth.c:1954 #, c-format -msgid "specifying both host name and CIDR mask is invalid: \"%s\"" -msgstr "호스트 ì´ë¦„ê³¼ CIDR 마스í¬ëŠ” 함께 쓸 수 없습니다: \"%s\"" +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버ì—게 질ì˜ë¥¼ 보낼 수 없습니다: %m" -#: libpq/hba.c:1058 +#: libpq/auth.c:1971 #, c-format -msgid "invalid CIDR mask in address \"%s\"" -msgstr "\"%s\" ì£¼ì†Œì— ìž˜ëª»ëœ CIDR 마스í¬ê°€ 있ìŒ" +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "주소 \"%s\", í¬íЏ %sì˜ Ident 서버로부터 ì‘ë‹µì„ ë°›ì§€ 못했습니다: %m" -#: libpq/hba.c:1075 +#: libpq/auth.c:1981 #, c-format -msgid "end-of-line before netmask specification" -msgstr "ë„·ë§ˆìŠ¤í¬ ì§€ì • ì „ì— ì¤„ ëì— ë„달함" +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "Ident 서버로부터 ìž˜ëª»ëœ í˜•íƒœì˜ ì‘답를 보냈습니다: \"%s\"" -#: libpq/hba.c:1076 +#: libpq/auth.c:2021 #, c-format -msgid "" -"Specify an address range in CIDR notation, or provide a separate netmask." -msgstr "주소 범위는 CIDR í‘œê¸°ë²•ì„ ì“°ê±°ë‚˜ ë„·ë§ˆìŠ¤í¬ í‘œê¸°ë²•ì„ ì“°ì„¸ìš”" +msgid "peer authentication is not supported on this platform" +msgstr "ì´ í”Œëž«í¼ì—서는 peer ì¸ì¦ì´ ì§€ì›ë˜ì§€ 않ìŒ" -#: libpq/hba.c:1086 +#: libpq/auth.c:2025 #, c-format -msgid "multiple values specified for netmask" -msgstr "ë„·ë§ˆìŠ¤í¬ ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" +msgid "could not get peer credentials: %m" +msgstr "신뢰성 피어를 ì–»ì„ ìˆ˜ 없습니다: %m" -#: libpq/hba.c:1099 +#: libpq/auth.c:2036 #, c-format -msgid "invalid IP mask \"%s\": %s" -msgstr "ìž˜ëª»ëœ IP 마스í¬, \"%s\": %s" +msgid "could not look up local user ID %ld: %s" +msgstr "UID %ld 해당하는 사용ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: libpq/hba.c:1116 +#: libpq/auth.c:2124 #, c-format -msgid "IP address and mask do not match" -msgstr "IP 주소와 마스í¬ê°€ ë§žì§€ 않습니다" +msgid "error from underlying PAM layer: %s" +msgstr "잠재ì ì¸ PAM ë ˆì´ì–´ì—ì„œì˜ ì—러: %s" -#: libpq/hba.c:1131 +#: libpq/auth.c:2205 #, c-format -msgid "end-of-line before authentication method" -msgstr "ì¸ì¦ 방법 ì „ì— ì¤„ ëì— ë„달함" +msgid "could not create PAM authenticator: %s" +msgstr "PAM ì¸ì¦ìžë¥¼ ìƒì„±í•  수 없습니다: %s" -#: libpq/hba.c:1141 +#: libpq/auth.c:2216 #, c-format -msgid "multiple values specified for authentication type" -msgstr "ì¸ì¦ 방법 ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) 실패: %s" -#: libpq/hba.c:1142 +#: libpq/auth.c:2227 #, c-format -msgid "Specify exactly one authentication type per line." -msgstr "í•˜ë‚˜ì˜ ì¸ì¦ ë°©ë²•ì— ëŒ€í•´ì„œ 한 줄씩 지정해야 합니다" +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) 실패: %s" -#: libpq/hba.c:1215 +#: libpq/auth.c:2238 #, c-format -msgid "invalid authentication method \"%s\"" -msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì´ ìž˜ëª»ë¨" +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) 실패: %s" -#: libpq/hba.c:1226 +#: libpq/auth.c:2249 #, c-format -msgid "invalid authentication method \"%s\": not supported by this build" -msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì´ ìž˜ëª»ë¨: ì´ ì„œë²„ì—서 ì§€ì›ë˜ì§€ 않ìŒ" +msgid "pam_authenticate failed: %s" +msgstr "PAM ì¸ì¦ 실패: %s" -#: libpq/hba.c:1247 +#: libpq/auth.c:2260 #, c-format -msgid "gssapi authentication is not supported on local sockets" -msgstr "gssapi ì¸ì¦ì€ 로컬 소켓ì—서 ì§€ì›ë˜ì§€ 않ìŒ" +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt 실패: %s" -#: libpq/hba.c:1258 +#: libpq/auth.c:2271 #, c-format -msgid "peer authentication is only supported on local sockets" -msgstr "peer ì¸ì¦ì€ 로컬 소켓ì—서만 ì§€ì›í•¨" +msgid "could not release PAM authenticator: %s" +msgstr "PAM ì¸ì¦ìžë¥¼ 릴리즈할 수 없습니다: %s" -#: libpq/hba.c:1275 +#: libpq/auth.c:2347 #, c-format -msgid "cert authentication is only supported on hostssl connections" -msgstr "cert ì¸ì¦ì€ hostssl ì—°ê²°ì—서만 ì§€ì›ë¨" +msgid "could not initialize LDAP: error code %d" +msgstr "LDAP 초기화 실패: 오류번호 %d" -#: libpq/hba.c:1324 +#: libpq/auth.c:2364 #, c-format -msgid "authentication option not in name=value format: %s" -msgstr "ì¸ì¦ ì˜µì…˜ì´ ì´ë¦„=ê°’ 형태가 아님: %s" +msgid "could not initialize LDAP: %s" +msgstr "LDAP 초기화 실패: %s" -#: libpq/hba.c:1361 +#: libpq/auth.c:2374 #, c-format -msgid "" -"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or " -"ldapurl together with ldapprefix" -msgstr "" -"ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapurl ì˜µì…˜ì€ " -"ldapprefix 옵션과 함께 사용할 수 ì—†ìŒ" +msgid "ldaps not supported with this LDAP library" +msgstr "ldap ì¸ì¦ìœ¼ë¡œ 사용할 수 없는 LDAP ë¼ì´ë¸ŒëŸ¬ë¦¬" -#: libpq/hba.c:1371 +#: libpq/auth.c:2382 #, c-format -msgid "" -"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix" -"\", or \"ldapsuffix\" to be set" -msgstr "" -"\"ldap\" ì¸ì¦ ë°©ë²•ì˜ ê²½ìš° \"ldapbasedn\", \"ldapprefix\", \"ldapsuffix\"옵션" -"ì´ ìžˆì–´ì•¼ 함" - -#: libpq/hba.c:1414 -msgid "ident, peer, gssapi, sspi, and cert" -msgstr "ident, peer, gssapi, sspi ë° cert" +msgid "could not initialize LDAP: %m" +msgstr "LDAP 초기화 실패: %m" -#: libpq/hba.c:1427 +#: libpq/auth.c:2392 #, c-format -msgid "clientcert can only be configured for \"hostssl\" rows" -msgstr "clientcert는 \"hostssl\" í–‰ì— ëŒ€í•´ì„œë§Œ 구성할 수 있ìŒ" +msgid "could not set LDAP protocol version: %s" +msgstr "LDAP 프로토콜 ë²„ì „ì„ ì§€ì •í•  수 ì—†ìŒ: %s" -#: libpq/hba.c:1438 +#: libpq/auth.c:2423 #, c-format -msgid "" -"client certificates can only be checked if a root certificate store is " -"available" -msgstr "" -"루트 ì¸ì¦ì„œ 저장소가 사용 가능한 경우ì—ë§Œ í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œë¥¼ 검사할 수 있ìŒ" +msgid "could not load wldap32.dll" +msgstr "could not load wldap32.dll" -#: libpq/hba.c:1452 +#: libpq/auth.c:2431 #, c-format -msgid "clientcert can not be set to 0 when using \"cert\" authentication" -msgstr "\"cert\" ì¸ì¦ì„ 사용하는 경우 clientcert를 0으로 설정할 수 ì—†ìŒ" +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "could not load function _ldap_start_tls_sA in wldap32.dll" -#: libpq/hba.c:1488 +#: libpq/auth.c:2432 #, c-format -msgid "could not parse LDAP URL \"%s\": %s" -msgstr "\"%s\" LDAP URLì„ ë¶„ì„í•  수 ì—†ìŒ: %s" +msgid "LDAP over SSL is not supported on this platform." +msgstr "ì´ í”Œëž«í¼ì—서는 SSLì„ ì´ìš©í•œ LDAP ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ." -#: libpq/hba.c:1496 +#: libpq/auth.c:2447 #, c-format -msgid "unsupported LDAP URL scheme: %s" -msgstr "ì§€ì›í•˜ì§€ 않는 LDAP URL 스킴: %s" +msgid "could not start LDAP TLS session: %s" +msgstr "LDAP TLS ì„¸ì…˜ì„ ì‹œìž‘í•  수 ì—†ìŒ: %s" -#: libpq/hba.c:1512 +#: libpq/auth.c:2510 #, c-format -msgid "filters not supported in LDAP URLs" -msgstr "LDAP URLì—서 í•„í„° ì†ì„±ì„ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "LDAP server not specified" +msgstr "LDAP 서버가 지정ë˜ì§€ 않ìŒ" -#: libpq/hba.c:1520 +#: libpq/auth.c:2565 #, c-format -msgid "LDAP URLs not supported on this platform" -msgstr "ì´ í”Œëž«í¼ì—서는 LDAP URL ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ." +msgid "invalid character in user name for LDAP authentication" +msgstr "LDAP ì¸ì¦ì„ 위한 ì‚¬ìš©ìž ì´ë¦„ì— ì‚¬ìš©í•  수 없는 문ìžê°€ 있습니다" -#: libpq/hba.c:1544 +#: libpq/auth.c:2582 #, c-format -msgid "invalid LDAP port number: \"%s\"" -msgstr "LDAP í¬íЏ 번호가 잘못ë¨: \"%s\"" - -#: libpq/hba.c:1584 libpq/hba.c:1591 -msgid "gssapi and sspi" -msgstr "gssapi ë° sspi" +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "\"%s\" ldapbinddn (해당 서버: \"%s\") ì„¤ì •ì— ëŒ€í•œ LDAP ë°”ì¸ë“œ 초기화를 í•  수 ì—†ìŒ: %s" -#: libpq/hba.c:1600 libpq/hba.c:1609 -msgid "sspi" -msgstr "sspi" - -#: libpq/hba.c:1651 +#: libpq/auth.c:2611 #, c-format -msgid "invalid RADIUS port number: \"%s\"" -msgstr "RADIUS í¬íЏ 번호가 잘못ë¨: \"%s\"" +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 필터로 LDAP 검색 실패함, ëŒ€ìƒ ì„œë²„: \"%s\": %s" -#: libpq/hba.c:1671 +#: libpq/auth.c:2625 #, c-format -msgid "unrecognized authentication option name: \"%s\"" -msgstr "알 수 없는 ì¸ì¦ 옵션 ì´ë¦„: \"%s\"" +msgid "LDAP user \"%s\" does not exist" +msgstr "\"%s\" LDAP 사용ìžê°€ ì—†ìŒ" -#: libpq/hba.c:1806 guc-file.l:594 +#: libpq/auth.c:2626 #, c-format -msgid "could not open configuration file \"%s\": %m" -msgstr "\"%s\" 설정 íŒŒì¼ ì„ ì—´ìˆ˜ 없습니다: %m" +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "\"%s\" 필터로 \"%s\" 서버ì—서 LDAP ê²€ìƒ‰ì„ í–ˆìœ¼ë‚˜, 해당 ìžë£Œê°€ ì—†ìŒ" -#: libpq/hba.c:1855 +#: libpq/auth.c:2630 #, c-format -msgid "configuration file \"%s\" contains no entries" -msgstr "\"%s\" 설정 파ì¼ì— 구성 í•­ëª©ì´ ì—†ìŒ" +msgid "LDAP user \"%s\" is not unique" +msgstr "\"%s\" LDAP 사용ìžê°€ 유ì¼í•˜ì§€ 않습니다" -#: libpq/hba.c:1951 +#: libpq/auth.c:2631 #, c-format -msgid "invalid regular expression \"%s\": %s" -msgstr "\"%s\" ì •ê·œì‹ì´ 잘못ë¨: %s" +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "\"%s\" 필터로 \"%s\" 서버ì—서 LDAP 검색 ê²°ê³¼ %d í•­ëª©ì„ ë°˜í™˜í•¨" -#: libpq/hba.c:2011 +#: libpq/auth.c:2651 #, c-format -msgid "regular expression match for \"%s\" failed: %s" -msgstr "\"%s\"ì— ëŒ€í•œ ì •ê·œì‹ ì¼ì¹˜ 실패: %s" +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 첫번째 항목 조회용 dn ê°’ì„ \"%s\" 서버ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: libpq/hba.c:2030 +#: libpq/auth.c:2672 #, c-format -msgid "" -"regular expression \"%s\" has no subexpressions as requested by " -"backreference in \"%s\"" -msgstr "\"%s\" ì •ê·œì‹ì—는 \"%s\"ì˜ backreferenceì—서 ìš”ì²­ëœ í•˜ìœ„ ì‹ì´ ì—†ìŒ" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "\"%s\" ì‚¬ìš©ìž ê²€ìƒ‰ 후 unbind ìž‘ì—…ì„ \"%s\" 서버ì—서 í•  수 ì—†ìŒ" -#: libpq/hba.c:2127 +#: libpq/auth.c:2703 #, c-format -msgid "provided user name (%s) and authenticated user name (%s) do not match" -msgstr "ì œê³µëœ ì‚¬ìš©ìž ì´ë¦„(%s) ë° ì¸ì¦ëœ ì‚¬ìš©ìž ì´ë¦„(%s)ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "\"%s\" 사용ìžì˜ \"%s\" LDAP 서버 ë¡œê·¸ì¸ ì‹¤íŒ¨: %s" -#: libpq/hba.c:2147 +#: libpq/auth.c:2732 #, c-format -msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" -msgstr "" -"\"%s\" 사용ìžë§µ 파ì¼ì— \"%s\" 사용ìžë¥¼ \"%s\" 사용ìžë¡œ ì¸ì¦í•  ì„¤ì •ì´ ì—†ìŒ" +msgid "LDAP diagnostics: %s" +msgstr "LDAP 진단: %s" -#: libpq/hba.c:2182 +#: libpq/auth.c:2757 #, c-format -msgid "could not open usermap file \"%s\": %m" -msgstr "\"%s\" 사용ìžë§µ 파ì¼ì„ ì—´ 수 없습니다: %m" +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "\"%s\" 사용ìžì— 대한 ì¸ì¦ì„œ ë¡œê·¸ì¸ ì‹¤íŒ¨: í´ë¼ì´ì–¸íЏ ì¸ì¦ì„œì— ì‚¬ìš©ìž ì´ë¦„ì´ ì—†ìŒ" -#: libpq/pqcomm.c:202 +#: libpq/auth.c:2860 #, c-format -msgid "could not set socket to nonblocking mode: %m" -msgstr "ì†Œì¼“ì„ nonblocking 모드로 지정할 수 ì—†ìŒ: %m" +msgid "RADIUS server not specified" +msgstr "RADIUS 서버가 지정ë˜ì§€ 않ìŒ" -#: libpq/pqcomm.c:354 +#: libpq/auth.c:2867 #, c-format -msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" -msgstr "\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ 경로가 너무 ê¹ë‹ˆë‹¤ (최대 %d ë°”ì´íЏ)" +msgid "RADIUS secret not specified" +msgstr "RADIUS 비밀키가 지정ë˜ì§€ 않ìŒ" -#: libpq/pqcomm.c:375 +#: libpq/auth.c:2881 #, c-format -msgid "could not translate host name \"%s\", service \"%s\" to address: %s" -msgstr "호스트 ì´ë¦„ \"%s\", 서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS ì¸ì¦ì€ %d ê¸€ìž ë³´ë‹¤ í° ë¹„ë°€ë²ˆí˜¸ ì¸ì¦ì„ ì§€ì›í•˜ì§€ 않습니다" -#: libpq/pqcomm.c:379 +#: libpq/auth.c:2986 libpq/hba.c:1908 #, c-format -msgid "could not translate service \"%s\" to address: %s" -msgstr "서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "\"%s\" RADIUS 서버 ì´ë¦„ì„ ì£¼ì†Œë¡œ 바꿀 수 ì—†ìŒ: %s" -#: libpq/pqcomm.c:406 +#: libpq/auth.c:3000 #, c-format -msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" -msgstr "최대 ì ‘ì†ìž 수 MAXLISTEN (%d) 초과로 ë” ì´ìƒ ì ‘ì†ì´ 불가능합니다" - -#: libpq/pqcomm.c:415 -msgid "IPv4" -msgstr "IPv4" - -#: libpq/pqcomm.c:419 -msgid "IPv6" -msgstr "IPv6" +msgid "could not generate random encryption vector" +msgstr "무작위 암호화 벡터를 만들 수 ì—†ìŒ" -#: libpq/pqcomm.c:424 -msgid "Unix" -msgstr "유닉스" +#: libpq/auth.c:3034 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "ë¹„ë°€ë²ˆí˜¸ì˜ MD5 암호를 만들 수 ì—†ìŒ" -#: libpq/pqcomm.c:429 +# translator: %s is IPv4, IPv6, or Unix +#: libpq/auth.c:3060 #, c-format -msgid "unrecognized address family %d" -msgstr "%d는 ì¸ì‹ë˜ì§€ 않는 가족 주소입니다" +msgid "could not create RADIUS socket: %m" +msgstr "RADIUS ì†Œì¼“ì„ ìƒì„±í•  수 없습니다: %m" # translator: %s is IPv4, IPv6, or Unix -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:440 +#: libpq/auth.c:3082 #, c-format -msgid "could not create %s socket: %m" -msgstr "%s ì†Œì¼“ì„ ìƒì„±í•  수 없습니다: %m" +msgid "could not bind local RADIUS socket: %m" +msgstr "RADIUS ì†Œì¼“ì— ë°”ì¸ë“œí•  수 없습니다: %m" -#: libpq/pqcomm.c:465 +#: libpq/auth.c:3092 #, c-format -msgid "setsockopt(SO_REUSEADDR) failed: %m" -msgstr "setsockopt(SO_REUSEADDR) 실패: %m" +msgid "could not send RADIUS packet: %m" +msgstr "RADIUS íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %m" -#: libpq/pqcomm.c:480 +#: libpq/auth.c:3125 libpq/auth.c:3151 #, c-format -msgid "setsockopt(IPV6_V6ONLY) failed: %m" -msgstr "setsockopt(IPV6_V6ONLY) 실패: %m" +msgid "timeout waiting for RADIUS response from %s" +msgstr "%s ì—서 RADIUS ì‘답 대기 시간 초과" # translator: %s is IPv4, IPv6, or Unix -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:499 +#: libpq/auth.c:3144 #, c-format -msgid "could not bind %s socket: %m" -msgstr "%s ì†Œì¼“ì— ë°”ì¸ë“œí•  수 없습니다: %m" +msgid "could not check status on RADIUS socket: %m" +msgstr "RADIUS 소켓 ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" -#: libpq/pqcomm.c:502 +#: libpq/auth.c:3174 #, c-format -msgid "" -"Is another postmaster already running on port %d? If not, remove socket file " -"\"%s\" and retry." -msgstr "" -"다른 postmaster ê°€ í¬íЏ %dì—서 ì´ë¯¸ 실행중ì¸ê²ƒ 같습니다? 그렇지 않다면 소켓 " -"íŒŒì¼ \"%s\"ì„ ì œê±°í•˜ê³  다시 시ë„해보십시오" +msgid "could not read RADIUS response: %m" +msgstr "RADIUS ì‘ë‹µì„ ì½ì„ 수 ì—†ìŒ: %m" -#: libpq/pqcomm.c:505 +#: libpq/auth.c:3187 libpq/auth.c:3191 #, c-format -msgid "" -"Is another postmaster already running on port %d? If not, wait a few seconds " -"and retry." -msgstr "" -"다른 postmaster ê°€ í¬íЏ %dì—서 ì´ë¯¸ 실행중ì¸ê²ƒ 같습니다? 그렇지 않다면 몇 ì´ˆ" -"를 기다렸다가 다시 시ë„해보십시오." +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "%sì—서 RADIUS ì‘ë‹µì´ ë°”ë¥´ì§€ ì•Šì€ í¬íŠ¸ë¡œë¶€í„° 보내졌ìŒ: %d" -# translator: %s is IPv4, IPv6, or Unix -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:538 +#: libpq/auth.c:3200 #, c-format -msgid "could not listen on %s socket: %m" -msgstr "%s ì†Œì¼“ì„ ë“¤ì„ ìˆ˜ 없습니다: %m" +msgid "RADIUS response from %s too short: %d" +msgstr "%sì—서 RADIUS ì‘ë‹µì´ ë„ˆë¬´ ì§§ìŒ: %d" -#: libpq/pqcomm.c:623 +#: libpq/auth.c:3207 #, c-format -msgid "group \"%s\" does not exist" -msgstr "\"%s\" 그룹 ì—†ìŒ" +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "%sì—서 RADIUS ì‘답 길ì´ê°€ ì´ìƒí•¨: %d (실재 길ì´: %d)" -#: libpq/pqcomm.c:633 +#: libpq/auth.c:3215 #, c-format -msgid "could not set group of file \"%s\": %m" -msgstr "íŒŒì¼ \"%s\" ì˜ ê·¸ë£¹ì„ ì„¸íŒ…í•  수 없습니다: %m" +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "%sì—서 RADIUS ì‘ë‹µì´ ìš”ì²­ê³¼ 다름: %d (기대값: %d)" -#: libpq/pqcomm.c:644 +#: libpq/auth.c:3240 #, c-format -msgid "could not set permissions of file \"%s\": %m" -msgstr "íŒŒì¼ \"%s\" ì˜ í¼ë¯¸ì…˜ì„ 세팅할 수 없습니다: %m" +msgid "could not perform MD5 encryption of received packet" +msgstr "ë°›ì€ íŒ¨í‚·ì„ ëŒ€ìƒìœ¼ë¡œ MD5 암호화 작업할 수 ì—†ìŒ" -#: libpq/pqcomm.c:674 +#: libpq/auth.c:3249 #, c-format -msgid "could not accept new connection: %m" -msgstr "새로운 ì—°ê²°ì„ ìƒì„±í•  수 없습니다: %m" +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "%sì—서 RADIUS ì‘ë‹µì˜ MD5 ê°’ì´ ì´ìƒí•¨" -#: libpq/pqcomm.c:885 +#: libpq/auth.c:3267 #, c-format -msgid "there is no client connection" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²°ì´ ì—†ìŒ" +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "%sì—서 RADIUS ì‘ë‹µì´ ë°”ë¥´ì§€ ì•Šì€ ê°’ìž„ (%d), ëŒ€ìƒ ì‚¬ìš©ìž: \"%s\"" -#: libpq/pqcomm.c:936 libpq/pqcomm.c:1032 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format -msgid "could not receive data from client: %m" -msgstr "í´ë¼ì´ì–¸íЏì—게 ë°ì´í„°ë¥¼ ë°›ì„ ìˆ˜ 없습니다: %m" +msgid "invalid large-object descriptor: %d" +msgstr "유효하지 ì•Šì€ ëŒ€í˜• 개체 설명: %d" -#: libpq/pqcomm.c:1177 tcop/postgres.c:3917 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "terminating connection because protocol synchronization was lost" -msgstr "프로토콜 ë™ê¸°í™” 작업 실패로 ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤" +msgid "large object descriptor %d was not opened for reading" +msgstr "%d번 대형 개체 기술ìžê°€ ì½ê¸° 모드로 열려있지 않습니다" -#: libpq/pqcomm.c:1243 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format -msgid "unexpected EOF within message length word" -msgstr "예ìƒì¹˜ 못한 EOFê°€ ë©”ì‹œì§€ì˜ ê¸¸ì´ ì›Œë“œì•ˆì—서 ë°œìƒí–ˆìŠµë‹ˆë‹¤." +msgid "large object descriptor %d was not opened for writing" +msgstr "%d번 대형 개체 기술ìžê°€ 쓰기 모드로 열려있지 않습니다" -#: libpq/pqcomm.c:1254 +#: libpq/be-fsstubs.c:212 #, c-format -msgid "invalid message length" -msgstr "ë©”ì‹œì§€ì˜ ê¸¸ì´ê°€ 유효하지 않습니다" +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "%d번 대형 개체 기술ìžì— 대한 lo_lseek ë°˜í™˜ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" -#: libpq/pqcomm.c:1276 libpq/pqcomm.c:1289 +#: libpq/be-fsstubs.c:285 #, c-format -msgid "incomplete message from client" -msgstr "í´ë¼ì´ì–¸íŠ¸ìœ¼ë¡œë¶€í„°ì˜ ì™„ì „í•˜ì§€ 못한 메시지입니다" +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "%d번 대형 개체 기술ìžì— 대한 lo_tell ë°˜í™˜ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" -#: libpq/pqcomm.c:1422 +#: libpq/be-fsstubs.c:432 #, c-format -msgid "could not send data to client: %m" -msgstr "í´ë¼ì´ì–¸íЏì—게 ë°ì´í„°ë¥¼ 보낼 수 없습니다: %m" +msgid "could not open server file \"%s\": %m" +msgstr "서버 íŒŒì¼ \"%s\"ì„ ì—´ 수 없습니다: %m" -#: libpq/pqformat.c:437 +#: libpq/be-fsstubs.c:454 #, c-format -msgid "no data left in message" -msgstr "ë©”ì‹œì§€ì— ì•„ë¬´ëŸ° ë°ì´í„°ê°€ 없습니다" +msgid "could not read server file \"%s\": %m" +msgstr "서버 íŒŒì¼ \"%s\"ì„ ì½ì„ 수 없습니다: %m" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/be-fsstubs.c:511 #, c-format -msgid "insufficient data left in message" -msgstr "부족한 ë°ì´í„°ëŠ” 메시지 ì•ˆì— ë„£ì–´ì ¸ 있습니다" +msgid "could not create server file \"%s\": %m" +msgstr "서버 íŒŒì¼ \"%s\"ì˜ ìƒì„±ì„ í•  수 없습니다: %m" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/be-fsstubs.c:523 #, c-format -msgid "invalid string in message" -msgstr "ë©”ì‹œì§€ì•ˆì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžì—´ì´ 있습니다" +msgid "could not write server file \"%s\": %m" +msgstr "서버 íŒŒì¼ \"%s\"ì— ì“¸ 수 없습니다: %m" -#: libpq/pqformat.c:682 +#: libpq/be-fsstubs.c:752 #, c-format -msgid "invalid message format" -msgstr "메시지 í¬ë§·ì´ 유효하지 않습니다." +msgid "large object read request is too large" +msgstr "대형 개체 ì½ê¸° ìš”ì²­ì´ ë„ˆë¬´ í½ë‹ˆë‹¤" -# # search5 ë -# # advance 부분 -#: main/main.c:264 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 +#: utils/adt/genfile.c:306 #, c-format -msgid "%s: WSAStartup failed: %d\n" -msgstr "%s: WSAStartup 작업 실패: %d\n" +msgid "requested length cannot be negative" +msgstr "요청한 길ì´ëŠ” ìŒìˆ˜ì¼ 수 ì—†ìŒ" -#: main/main.c:328 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 +#: storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 +#: storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "" -"%s is the PostgreSQL server.\n" -"\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL 서버입니다.\n" -"\n" +msgid "permission denied for large object %u" +msgstr "%u 대형 ê°œì²´ì— ëŒ€í•œ ì ‘ê·¼ 권한 ì—†ìŒ" -#: main/main.c:329 +#: libpq/be-secure-common.c:91 #, c-format -msgid "" -"Usage:\n" -" %s [OPTION]...\n" -"\n" -msgstr "" -"사용법:\n" -" %s [옵션]...\n" -"\n" +msgid "could not read from command \"%s\": %m" +msgstr "\"%s\" 명령ì—서 ì½ì„ 수 ì—†ìŒ: %m" -#: main/main.c:330 +#: libpq/be-secure-common.c:109 #, c-format -msgid "Options:\n" -msgstr "옵션들:\n" +msgid "command \"%s\" failed" +msgstr "\"%s\" 명령 실패" -#: main/main.c:331 +#: libpq/be-secure-common.c:139 #, c-format -msgid " -B NBUFFERS number of shared buffers\n" -msgstr " -B NBUFFERS 공유 ë²„í¼ ê°œìˆ˜\n" +msgid "could not access private key file \"%s\": %m" +msgstr "비밀키 \"%s\"ì— ì•¡ì„¸ìŠ¤í•  수 없습니다: %m" -#: main/main.c:332 +#: libpq/be-secure-common.c:148 #, c-format -msgid " -c NAME=VALUE set run-time parameter\n" -msgstr " -c NAME=VALUE 실시간 매개 변수 지정\n" +msgid "private key file \"%s\" is not a regular file" +msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì€ ì¼ë°˜ 파ì¼ì´ 아님" -#: main/main.c:333 +#: libpq/be-secure-common.c:163 #, c-format -msgid " -C NAME print value of run-time parameter, then exit\n" -msgstr " -C NAME 실시간 매개 변수 ê°’ì„ ë³´ì—¬ì£¼ê³  마침\n" +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì˜ 소유주는 ë°ì´í„°ë² ì´ìФ 사용ìžì´ê±°ë‚˜ root 여야 합니다." -#: main/main.c:334 +#: libpq/be-secure-common.c:186 #, c-format -msgid " -d 1-5 debugging level\n" -msgstr " -d 1-5 디버깅 수준\n" +msgid "private key file \"%s\" has group or world access" +msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì— 그룹 ë˜ëŠ” ìµëª… 액세스 ê¶Œí•œì´ ìžˆìŒ" -#: main/main.c:335 +#: libpq/be-secure-common.c:188 #, c-format -msgid " -D DATADIR database directory\n" -msgstr " -D DATADIR ë°ì´í„° 디렉터리\n" +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "파ì¼ì˜ 소유주가 ë°ì´í„°ë² ì´ìФ 서버 ìš´ì˜ ê³„ì •ê³¼ 같다면, ì ‘ê·¼ ê¶Œí•œì„ u=rw (0600) ë˜ëŠ” ë” ìž‘ê²Œ 설정하고, rootê°€ 소유주ë¼ë©´ u=rw,g=r (0640) 권한으로 지정하세요" -#: main/main.c:336 +#: libpq/be-secure-openssl.c:104 #, c-format -msgid " -e use European date input format (DMY)\n" -msgstr " -e ë‚ ì§œ ìž…ë ¥ ì–‘ì‹ì´ 유럽형(DMY)ì„ ì‚¬ìš©í•¨\n" +msgid "could not create SSL context: %s" +msgstr "SSL 컨í…스트 정보를 ìƒì„±í•  수 없습니다: %s" -#: main/main.c:337 +#: libpq/be-secure-openssl.c:147 #, c-format -msgid " -F turn fsync off\n" -msgstr " -F fsync 기능 ë”\n" +msgid "could not load server certificate file \"%s\": %s" +msgstr "서버 ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" -#: main/main.c:338 +#: libpq/be-secure-openssl.c:167 #, c-format -msgid " -h HOSTNAME host name or IP address to listen on\n" -msgstr " -h HOSTNAME 서버로 사용할 호스트 ì´ë¦„ ë˜ëŠ” IP\n" +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "\"%s\" ê°œì¸ í‚¤ 파ì¼ì€ 비밀번호를 입력해야 해서 ìžë™ìœ¼ë¡œ 다시 불러올 수 없습니다." -#: main/main.c:339 +#: libpq/be-secure-openssl.c:172 #, c-format -msgid " -i enable TCP/IP connections\n" -msgstr " -i TCP/IP ì—°ê²° 사용함\n" +msgid "could not load private key file \"%s\": %s" +msgstr "비밀키 íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" -#: main/main.c:340 +#: libpq/be-secure-openssl.c:181 #, c-format -msgid " -k DIRECTORY Unix-domain socket location\n" -msgstr " -k DIRECTORY 유닉스 ë„ë©”ì¸ ì†Œì¼“ 위치\n" +msgid "check of private key failed: %s" +msgstr "ë¹„ë°€í‚¤ì˜ í™•ì¸ ì‹¤íŒ¨: %s" -#: main/main.c:342 +#: libpq/be-secure-openssl.c:208 #, c-format -msgid " -l enable SSL connections\n" -msgstr " -l SSL ì—°ê²° 기능 사용함\n" +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "" -#: main/main.c:344 +#: libpq/be-secure-openssl.c:226 #, c-format -msgid " -N MAX-CONNECT maximum number of allowed connections\n" -msgstr " -N MAX-CONNECT 최대 ë™ì‹œ ì—°ê²° 개수\n" +msgid "could not load root certificate file \"%s\": %s" +msgstr "root ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" -#: main/main.c:345 +#: libpq/be-secure-openssl.c:253 #, c-format -msgid "" -" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" -msgstr "" -" -o OPTIONS 개별 서버 프로세스를 \"OPTIONS\" 옵션으로 실행 (옛기" -"능)\n" +msgid "SSL certificate revocation list file \"%s\" ignored" +msgstr "\"%s\" SSL ì¸ì¦ì„œ 파기 ëª©ë¡ íŒŒì¼ì´ 무시ë˜ì—ˆìŒ" -#: main/main.c:346 +#: libpq/be-secure-openssl.c:255 #, c-format -msgid " -p PORT port number to listen on\n" -msgstr " -p PORT 서버 í¬íЏ 번호\n" +msgid "SSL library does not support certificate revocation lists." +msgstr "SSL ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ ì¸ì¦ì„œ 파기 목ë¡ì„ ì§€ì›í•˜ì§€ 않습니다." -#: main/main.c:347 +#: libpq/be-secure-openssl.c:262 #, c-format -msgid " -s show statistics after each query\n" -msgstr " -s ê° ì¿¼ë¦¬ ë’¤ì— í†µê³„ì •ë³´ë¥¼ 보여줌\n" +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "\"%s\" SSL ì¸ì¦ì„œ 회수 ëª©ë¡ íŒŒì¼ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" -#: main/main.c:348 +#: libpq/be-secure-openssl.c:337 #, c-format -msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" -msgstr " -S WORK-MEM ì •ë ¬ìž‘ì—…ì— ì‚¬ìš©í•  메모리 í¬ê¸°(kb 단위)를 지정\n" +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "SSLì—°ê²°ì„ ì´ˆê¸°í™”í•  수 없습니다: SSL 컨í…스트를 설정 못함" -#: main/main.c:349 +#: libpq/be-secure-openssl.c:345 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" +msgid "could not initialize SSL connection: %s" +msgstr "SSLì—°ê²°ì„ ì´ˆê¸°í™”í•  수 없습니다: %s" -#: main/main.c:350 +#: libpq/be-secure-openssl.c:353 #, c-format -msgid " --NAME=VALUE set run-time parameter\n" -msgstr " --NAME=VALUE 실시간 매개 변수 지정\n" +msgid "could not set SSL socket: %s" +msgstr "SSL ì†Œì¼“ì„ ì§€ì •í•  수 없습니다: %s" -#: main/main.c:351 +#: libpq/be-secure-openssl.c:408 #, c-format -msgid " --describe-config describe configuration parameters, then exit\n" -msgstr " --describe-config 서버 환경 ì„¤ì •ê°’ì— ëŒ€í•œ ì„¤ëª…ì„ ë³´ì—¬ì£¼ê³  마침\n" +msgid "could not accept SSL connection: %m" +msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: %m" -#: main/main.c:352 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" +msgid "could not accept SSL connection: EOF detected" +msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: EOF ê°ì§€ë¨" -#: main/main.c:354 +#: libpq/be-secure-openssl.c:417 #, c-format -msgid "" -"\n" -"Developer options:\n" -msgstr "" -"\n" -"ê°œë°œìž ì˜µì…˜ë“¤:\n" +msgid "could not accept SSL connection: %s" +msgstr "SSL ì—°ê²°ì„ ë°›ì•„ë“œë¦´ 수 없습니다: %s" -#: main/main.c:355 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 +#: libpq/be-secure-openssl.c:623 #, c-format -msgid " -f s|i|n|m|h forbid use of some plan types\n" -msgstr " -f s|i|n|m|h 쿼리최ì í™”ê¸°ì˜ ê¸°ëŠ¥ì„ ì œí•œ 함\n" +msgid "unrecognized SSL error code: %d" +msgstr "ì¸ì‹ë˜ì§€ ì•Šì€ SSL ì—러 코드 %d" -#: main/main.c:356 +#: libpq/be-secure-openssl.c:470 #, c-format -msgid "" -" -n do not reinitialize shared memory after abnormal exit\n" -msgstr "" -" -n 비정ìƒì  종료 ë’¤ì— ê³µìœ  메모리를 초기화 하지 않ìŒ\n" +msgid "SSL certificate's common name contains embedded null" +msgstr "SSL ì¸ì¦ì„œì˜ ì¼ë°˜ ì´ë¦„ì— í¬í•¨ëœ nullì´ ìžˆìŒ" -#: main/main.c:357 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format -msgid " -O allow system table structure changes\n" -msgstr " -O 시스템 í…Œì´ë¸”ì˜ êµ¬ì¡°ë¥¼ 바꿀 수 있ë„ë¡ í•¨\n" +msgid "SSL error: %s" +msgstr "SSL ì—러: %s" -#: main/main.c:358 +#: libpq/be-secure-openssl.c:788 #, c-format -msgid " -P disable system indexes\n" -msgstr " -P 시스템 ì¸ë±ìŠ¤ë“¤ì„ ì‚¬ìš©í•˜ì§€ 않ìŒ\n" +msgid "could not open DH parameters file \"%s\": %m" +msgstr "\"%s\" DH 매개 변수 파ì¼ì„ ì—´ 수 없습니다: %m" -#: main/main.c:359 +#: libpq/be-secure-openssl.c:800 #, c-format -msgid " -t pa|pl|ex show timings after each query\n" -msgstr " -t pa|pl|ex ê° ì¿¼ë¦¬ ë‹¤ìŒ ìž‘ì—…ì‹œê°„ì„ ë³´ì—¬ì¤Œ\n" +msgid "could not load DH parameters file: %s" +msgstr "DH 매개 변수 파ì¼ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s" -#: main/main.c:360 +#: libpq/be-secure-openssl.c:810 #, c-format -msgid "" -" -T send SIGSTOP to all backend processes if one dies\n" -msgstr "" -" -T í•˜ë‚˜ì˜ í•˜ìœ„ 서버 프로세스가 비정ìƒìœ¼ë¡œ 마치며 모든\n" -" 다른 서버 프로세스ì—게 SIGSTOP 신호를 보냄\n" +msgid "invalid DH parameters: %s" +msgstr "ìž˜ëª»ëœ DH 매개 변수: %s" -#: main/main.c:361 +#: libpq/be-secure-openssl.c:818 #, c-format -msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" -msgstr "" -" -W NUM 디버그 ìž‘ì—…ì„ ìœ„í•´ 지정한 숫ìžì˜ ì´ˆë§Œí¼ ê¸°ë‹¤ë¦°ë‹¤\n" +msgid "invalid DH parameters: p is not prime" +msgstr "ìž˜ëª»ëœ DH 매개 변수값: p는 prime 아님" -#: main/main.c:363 +#: libpq/be-secure-openssl.c:826 #, c-format -msgid "" -"\n" -"Options for single-user mode:\n" +msgid "invalid DH parameters: neither suitable generator or safe prime" msgstr "" -"\n" -"단ì¼ì‚¬ìš©ìž 모드ì—서 사용할 수 있는 옵션들:\n" -#: main/main.c:364 +#: libpq/be-secure-openssl.c:981 #, c-format -msgid "" -" --single selects single-user mode (must be first argument)\n" -msgstr " --single ë‹¨ì¼ ì‚¬ìš©ìž ëª¨ë“œ ì„ íƒ (ì¸ìžì˜ 첫번째로 와야함)\n" +msgid "DH: could not load DH parameters" +msgstr "DH: DH 매개 변수 불러오기 실패" -#: main/main.c:365 +#: libpq/be-secure-openssl.c:989 #, c-format -msgid " DBNAME database name (defaults to user name)\n" -msgstr " DBNAME ë°ì´í„°ë² ì´ìФ ì´ë¦„ (초기값: 사용ìžì´ë¦„)\n" +msgid "DH: could not set DH parameters: %s" +msgstr "DH: DH 매개 변수 설정 실패: %s" -#: main/main.c:366 +#: libpq/be-secure-openssl.c:1013 #, c-format -msgid " -d 0-5 override debugging level\n" -msgstr " -d 0-5 디버깅 수준\n" +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: 알 수 없는 curve ì´ë¦„: %s" -#: main/main.c:367 +#: libpq/be-secure-openssl.c:1022 #, c-format -msgid " -E echo statement before execution\n" -msgstr " -E 실행하기 ì „ì— ìž‘ì—…ëª…ë ¹ì„ ì¶œë ¥í•¨\n" +msgid "ECDH: could not create key" +msgstr "ECDH: 키 ìƒì„± 실패" -#: main/main.c:368 -#, c-format -msgid "" -" -j do not use newline as interactive query delimiter\n" -msgstr "" -" -j 대화형 ì¿¼ë¦¬ì˜ ëª…ë ¹ 실행 구분 문ìžë¡œ 줄바꿈문ìžë¥¼ ì“°ì§€ 않" -"ìŒ\n" +#: libpq/be-secure-openssl.c:1050 +msgid "no SSL error reported" +msgstr "SSL 오류 ì—†ìŒ" -#: main/main.c:369 main/main.c:374 +#: libpq/be-secure-openssl.c:1054 #, c-format -msgid " -r FILENAME send stdout and stderr to given file\n" -msgstr "" -" -r FILENAME stdout, stderr 쪽으로 보내는 ë‚´ìš©ì„ FILENAME 파ì¼ë¡œ 저장" -"함\n" +msgid "SSL error code %lu" +msgstr "SSL 오류 번호 %lu" -#: main/main.c:371 +#: libpq/be-secure.c:119 #, c-format -msgid "" -"\n" -"Options for bootstrapping mode:\n" -msgstr "" -"\n" -"부트스트랩 모드ì—서 사용할 수 있는 옵션들:\n" +msgid "SSL connection from \"%s\"" +msgstr "\"%s\" ë¡œë¶€í„°ì˜ SSL ì—°ê²°" -#: main/main.c:372 +#: libpq/be-secure.c:193 libpq/be-secure.c:279 #, c-format -msgid "" -" --boot selects bootstrapping mode (must be first argument)\n" -msgstr " --boot 부트스트랩 모드로 실행 (첫번째 ì¸ìžë¡œ 와야함)\n" +msgid "terminating connection due to unexpected postmaster exit" +msgstr "postmasterì˜ ì˜ˆìƒì¹˜ 못한 종료로 ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤" -#: main/main.c:373 +#: libpq/crypt.c:51 #, c-format -msgid "" -" DBNAME database name (mandatory argument in bootstrapping " -"mode)\n" -msgstr " DBNAME ë°ì´í„°ë² ì´ìФ ì´ë¦„ (부트스트랩 모드ì—서 필수)\n" +msgid "Role \"%s\" does not exist." +msgstr "\"%s\" 롤 ì—†ìŒ" -#: main/main.c:375 +#: libpq/crypt.c:61 #, c-format -msgid " -x NUM internal use\n" -msgstr " -x NUM ë‚´ë¶€ì ì¸ 옵션\n" +msgid "User \"%s\" has no password assigned." +msgstr "\"%s\" ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ ì•„ì§ í• ë‹¹ë˜ì§€ 않ìŒ" -#: main/main.c:377 +#: libpq/crypt.c:79 #, c-format -msgid "" -"\n" -"Please read the documentation for the complete list of run-time\n" -"configuration settings and how to set them on the command line or in\n" -"the configuration file.\n" -"\n" -"Report bugs to .\n" -msgstr "" -"\n" -"ì´ ì‹¤ì‹œê°„ 환경 변수용 ì„¤ì •ê°’ë“¤ì˜ ìžì„¸í•œ 사용법과\n" -"서버 환경 설정 파ì¼ì— 어떻게 지정하고 ì‚¬ìš©í•˜ëŠ”ì§€ì— ëŒ€í•œ 사항ì€\n" -"PostgreSQL 문서를 참조하세요.\n" -"\n" -"오류 ë³´ê³ : .\n" +msgid "User \"%s\" has an expired password." +msgstr "\"%s\" ì‚¬ìš©ìž ë¹„ë°€ë²ˆí˜¸ê°€ 기한 만료ë˜ì—ˆìŠµë‹ˆë‹¤." -#: main/main.c:391 +#: libpq/crypt.c:173 #, c-format -msgid "" -"\"root\" execution of the PostgreSQL server is not permitted.\n" -"The server must be started under an unprivileged user ID to prevent\n" -"possible system security compromise. See the documentation for\n" -"more information on how to properly start the server.\n" +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "" -"시스템 보안 관련 문제로, PostgreSQL server를 \"root\" ID로 실행할 수 없습니" -"다.\n" -"반드시 ì¼ë°˜ ì‚¬ìš©ìž ID(시스템 ê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ” ID)로 서버를 실행하십시오.\n" -"Server를 어떻게 안전하게 기ë™í•˜ëŠ”ê°€ 하는 ê²ƒì€ ë¬¸ì„œë¥¼ 참조하시기 ë°”ëžë‹ˆë‹¤.\n" -#: main/main.c:408 +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 #, c-format -msgid "%s: real and effective user IDs must match\n" -msgstr "%s: real ë˜ëŠ” effective user ID ë“¤ì€ ë°˜ë“œì‹œ ì¼ì¹˜ë˜ì–´ì•¼ 한다.\n" +msgid "Password does not match for user \"%s\"." +msgstr "\"%s\" 사용ìžì˜ 비밀번호가 틀립니다." -#: main/main.c:415 +#: libpq/crypt.c:281 #, c-format -msgid "" -"Execution of PostgreSQL by a user with administrative permissions is not\n" -"permitted.\n" -"The server must be started under an unprivileged user ID to prevent\n" -"possible system security compromises. See the documentation for\n" -"more information on how to properly start the server.\n" +msgid "Password of user \"%s\" is in unrecognized format." msgstr "" -"시스템 보안 관련 문제로, PostgreSQL server를 시스템 ê´€ë¦¬ìž ID로 실행할 수 ì—†" -"습니다.\n" -"반드시 ì¼ë°˜ ì‚¬ìš©ìž ID(시스템 ê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ” ID)로 서버를 실행하십시오.\n" -"Server를 어떻게 안전하게 기ë™í•˜ëŠ”ê°€ 하는 ê²ƒì€ ë¬¸ì„œë¥¼ 참조하시기 ë°”ëžë‹ˆë‹¤.\n" -#: nodes/extensible.c:66 +#: libpq/hba.c:235 #, c-format -msgid "extensible node type \"%s\" already exists" -msgstr "\"%s\" ì´ë¦„ì˜ í™•ìž¥ê°€ëŠ¥í•œ 노드 í˜•ì´ ì´ë¯¸ 있습니다" +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "ì¸ì¦ 파ì¼ì˜ 토í°ì´ 너무 길어서 건너ëœë‹ˆë‹¤: \"%s\"" -#: nodes/extensible.c:114 +#: libpq/hba.c:407 #, c-format -msgid "ExtensibleNodeMethods \"%s\" was not registered" -msgstr "\"%s\" ExtensibleNodeMethodsê°€ 등ë¡ë˜ì–´ 있지 않ìŒ" +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "2ì°¨ ì¸ì¦íŒŒì¼ \"%s\"으로 \"@%s\"를 ì—´ 수 없다: %m" -#: nodes/nodeFuncs.c:124 nodes/nodeFuncs.c:155 parser/parse_coerce.c:1820 -#: parser/parse_coerce.c:1848 parser/parse_coerce.c:1924 -#: parser/parse_expr.c:2019 parser/parse_func.c:597 parser/parse_oper.c:952 +#: libpq/hba.c:509 #, c-format -msgid "could not find array type for data type %s" -msgstr "ìžë£Œí˜• %s ì— ëŒ€í•´ì„œëŠ” ë°°ì—´ ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" +msgid "authentication file line too long" +msgstr "ì¸ì¦ íŒŒì¼ ì¤„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" -#: optimizer/path/allpaths.c:2653 +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 +#: libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 +#: libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 +#: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 +#: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 +#: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 +#: libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 +#: libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 +#: libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 +#: libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 +#: libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:179 #, c-format -msgid "WHERE CURRENT OF is not supported on a view with no underlying relation" -msgstr "" -"no underlying 릴레ì´ì…˜ì´ 있는 ë·°ì—서는 WHERE CURRENT OF êµ¬ë¬¸ì„ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "line %d of configuration file \"%s\"" +msgstr "%d번째 줄(\"%s\" 환경 설정 파ì¼)" -#: optimizer/path/allpaths.c:2658 +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 #, c-format -msgid "" -"WHERE CURRENT OF is not supported on a view with more than one underlying " -"relation" -msgstr "" -"WHERE CURRENT OF ì˜µì…˜ì€ í•˜ë‚˜ ì´ìƒì˜ 릴레ì´ì…˜ì„ 사용하는 ë·°ì—서는 사용할 수 ì—†" -"ìŒ" +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "\"%s\" ì¸ì¦ ì˜µì…˜ì€ %s ì¸ì¦ 방법ì—ë§Œ 유효함" -#: optimizer/path/allpaths.c:2663 +#: libpq/hba.c:885 #, c-format -msgid "" -"WHERE CURRENT OF is not supported on a view with grouping or aggregation" -msgstr "WHERE CURRENT OF ì˜µì…˜ì€ ê·¸ë£¹í™”ë‚˜ 집계 작업용 ë·°ì—서는 사용할 수 ì—†ìŒ" +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì˜ ê²½ìš° \"%s\" ì¸ìžë¥¼ 설정해야 함" -#: optimizer/path/joinrels.c:802 +#: libpq/hba.c:913 #, c-format -msgid "" -"FULL JOIN is only supported with merge-joinable or hash-joinable join " -"conditions" -msgstr "" -"FULL JOIN êµ¬ë¬¸ì€ ë¨¸ì§€ ì¡°ì¸ì´ë‚˜, 해시 ì¡°ì¸ì´ 가능한 ìƒí™©ì—서만 사용할 수 있습" -"니다" +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "\"%s\" 파ì¼ì˜ %d번째 ì¤„ì˜ ë ë¼ì¸ì— ë¹ ì§„ 엔트리가 있습니다 " -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1124 +#: libpq/hba.c:924 #, c-format -msgid "%s cannot be applied to the nullable side of an outer join" -msgstr "" -"%s êµ¬ë¬¸ì€ outer ì¡°ì¸ìœ¼ë¡œ null ê°’ì´ ì˜¬ 수 있는 ìª½ì— ëŒ€í•´ì„œëŠ” ì ìš©í•  수 없습니" -"다" +msgid "multiple values in ident field" +msgstr "ident ìžë¦¬ì— 여러 ê°’ì´ ìžˆìŒ" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1480 parser/analyze.c:1549 parser/analyze.c:1747 -#: parser/analyze.c:2528 +#: libpq/hba.c:973 #, c-format -msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" -msgstr "%s êµ¬ë¬¸ì€ UNION/INTERSECT/EXCEPT 예약어들과 함께 사용할 수 없습니다." +msgid "multiple values specified for connection type" +msgstr "ì—°ê²° í˜•ì‹ ìžë¦¬ì— 여러 ê°’ì´ ìžˆìŒ" -#: optimizer/plan/planner.c:3809 +#: libpq/hba.c:974 #, c-format -msgid "could not implement GROUP BY" -msgstr "GROUP BY를 구현할 수 ì—†ìŒ" +msgid "Specify exactly one connection type per line." +msgstr "한 ì¤„ì— í•˜ë‚˜ì˜ ì—°ê²° 형태만 지정해야 합니다" -#: optimizer/plan/planner.c:3810 optimizer/plan/planner.c:4203 -#: optimizer/prep/prepunion.c:929 +#: libpq/hba.c:988 #, c-format -msgid "" -"Some of the datatypes only support hashing, while others only support " -"sorting." -msgstr "해싱만 ì§€ì›í•˜ëŠ” ìžë£Œí˜•ë„ ìžˆê³ , 정렬만 ì§€ì›í•˜ëŠ” ìžë£Œí˜•ë„ ìžˆìŠµë‹ˆë‹¤." +msgid "local connections are not supported by this build" +msgstr "로컬 ì ‘ì† ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." -#: optimizer/plan/planner.c:4202 +#: libpq/hba.c:1009 #, c-format -msgid "could not implement DISTINCT" -msgstr "DISTINCT를 구현할 수 ì—†ìŒ" +msgid "hostssl record cannot match because SSL is disabled" +msgstr "" -#: optimizer/plan/planner.c:4832 +#: libpq/hba.c:1010 #, c-format -msgid "could not implement window PARTITION BY" -msgstr "ì°½ PARTITION BY를 구현할 수 ì—†ìŒ" +msgid "Set ssl = on in postgresql.conf." +msgstr "postgresql.conf 파ì¼ì— ssl = on ì„¤ì •ì„ í•˜ì„¸ìš”." -#: optimizer/plan/planner.c:4833 +#: libpq/hba.c:1018 #, c-format -msgid "Window partitioning columns must be of sortable datatypes." -msgstr "ì°½ ë¶„í•  ì—´ì€ ì •ë ¬ 가능한 ë°ì´í„° 형ì‹ì´ì–´ì•¼ 합니다." +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "ì´ ì„œë²„ëŠ” ssl ì ‘ì† ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않아 hostssl ì¸ì¦ì„ ì§€ì›í•˜ì§€ 않습니다." -#: optimizer/plan/planner.c:4837 +#: libpq/hba.c:1019 #, c-format -msgid "could not implement window ORDER BY" -msgstr "ì°½ ORDER BY를 구현할 수 ì—†ìŒ" +msgid "Compile with --with-openssl to use SSL connections." +msgstr "SSL ì—°ê²°ì„ ì‚¬ìš©í•˜ê¸° 위해 --enable-ssl ì˜µì…˜ì„ ì‚¬ìš©í•´ì„œ 서버를 다시 ì»´íŒŒì¼ í•˜ì„¸ìš”" -#: optimizer/plan/planner.c:4838 +#: libpq/hba.c:1039 #, c-format -msgid "Window ordering columns must be of sortable datatypes." -msgstr "ì°½ 순서 지정 ì—´ì€ ì •ë ¬ 가능한 ë°ì´í„° 형ì‹ì´ì–´ì•¼ 합니다." +msgid "invalid connection type \"%s\"" +msgstr "\"%s\" ê°’ì€ ìž˜ëª»ëœ ì—°ê²° 형ì‹ìž…니다" -#: optimizer/plan/setrefs.c:415 +#: libpq/hba.c:1053 #, c-format -msgid "too many range table entries" -msgstr "너무 ë§Žì€ í…Œì´ë¸”ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "end-of-line before database specification" +msgstr "ë°ì´í„°ë² ì´ìФ 지정 ì „ì— ì¤„ ëì— ë„달함" -#: optimizer/prep/prepunion.c:484 +#: libpq/hba.c:1073 #, c-format -msgid "could not implement recursive UNION" -msgstr "재귀 UNIONì„ êµ¬í˜„í•  수 ì—†ìŒ" +msgid "end-of-line before role specification" +msgstr "롤 지정 ì „ì— ì¤„ ëì— ë„달함" -#: optimizer/prep/prepunion.c:485 +#: libpq/hba.c:1095 #, c-format -msgid "All column datatypes must be hashable." -msgstr "모든 ì—´ ë°ì´í„° 형ì‹ì€ 해시 가능해야 합니다." +msgid "end-of-line before IP address specification" +msgstr "IP 주소 지정 ì „ì— ì¤„ ëì— ë„달함" -#. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:928 +#: libpq/hba.c:1106 #, c-format -msgid "could not implement %s" -msgstr "%s êµ¬ë¬¸ì€ êµ¬í˜„í•  수 ì—†ìŒ" +msgid "multiple values specified for host address" +msgstr "호스트 주소 ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" -#: optimizer/util/clauses.c:4634 +#: libpq/hba.c:1107 #, c-format -msgid "SQL function \"%s\" during inlining" -msgstr "" +msgid "Specify one address range per line." +msgstr "한 ì¤„ì— í•˜ë‚˜ì˜ ì£¼ì†Œ 범위가 있어야 합니다." -#: optimizer/util/plancat.c:114 +#: libpq/hba.c:1162 #, c-format -msgid "cannot access temporary or unlogged relations during recovery" -msgstr "복구 작업 중ì—는 임시 í…Œì´ë¸”ì´ë‚˜, 언로그드 í…Œì´ë¸”ì„ ì ‘ê·¼í•  수 ì—†ìŒ" +msgid "invalid IP address \"%s\": %s" +msgstr "\"%s\" 형태는 ìž˜ëª»ëœ IP 주소 형태입니다: %s" -#: optimizer/util/plancat.c:611 +#: libpq/hba.c:1182 #, c-format -msgid "whole row unique index inference specifications are not supported" -msgstr "" +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "호스트 ì´ë¦„ê³¼ CIDR 마스í¬ëŠ” 함께 쓸 수 없습니다: \"%s\"" -#: optimizer/util/plancat.c:628 +#: libpq/hba.c:1196 #, c-format -msgid "constraint in ON CONFLICT clause has no associated index" -msgstr "ON CONFLICT 처리를 위해 ê´€ë ¨ëœ ì¸ë±ìŠ¤ê°€ 없습니다" +msgid "invalid CIDR mask in address \"%s\"" +msgstr "\"%s\" ì£¼ì†Œì— ìž˜ëª»ëœ CIDR 마스í¬ê°€ 있ìŒ" -#: optimizer/util/plancat.c:679 +#: libpq/hba.c:1215 #, c-format -msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" -msgstr "제외 제약 ì¡°ê±´ì´ ìžˆì–´ ON CONFLICT DO UPDATE ìž‘ì—…ì€ í•  수 없습니다" +msgid "end-of-line before netmask specification" +msgstr "ë„·ë§ˆìŠ¤í¬ ì§€ì • ì „ì— ì¤„ ëì— ë„달함" -#: optimizer/util/plancat.c:784 +#: libpq/hba.c:1216 #, c-format -msgid "" -"there is no unique or exclusion constraint matching the ON CONFLICT " -"specification" -msgstr "" -"ON CONFLICT ì ˆì„ ì‚¬ìš©í•˜ëŠ” 경우, unique 나 exclude 제약 ì¡°ê±´ì´ ìžˆì–´ì•¼ 함" +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "주소 범위는 CIDR í‘œê¸°ë²•ì„ ì“°ê±°ë‚˜ ë„·ë§ˆìŠ¤í¬ í‘œê¸°ë²•ì„ ì“°ì„¸ìš”" -#: parser/analyze.c:663 parser/analyze.c:1321 +#: libpq/hba.c:1227 #, c-format -msgid "VALUES lists must all be the same length" -msgstr "VALUES 목ë¡ì€ ëª¨ë‘ ê°™ì€ ê¸¸ì´ì—¬ì•¼ 함" +msgid "multiple values specified for netmask" +msgstr "ë„·ë§ˆìŠ¤í¬ ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" -#: parser/analyze.c:859 +#: libpq/hba.c:1241 #, c-format -msgid "INSERT has more expressions than target columns" -msgstr "INSERT êµ¬ë¬¸ì— target columns 보다 ë” ë§Žì€ í‘œí˜„ì‹ì´ 존재하고 있다" +msgid "invalid IP mask \"%s\": %s" +msgstr "ìž˜ëª»ëœ IP 마스í¬, \"%s\": %s" -#: parser/analyze.c:877 +#: libpq/hba.c:1260 #, c-format -msgid "INSERT has more target columns than expressions" -msgstr "" -"INSERT êµ¬ë¬¸ì— target columns 보다 ë” ë§Žì€ í‘œí˜„ì‹(expressions)ì´ ì¡´ìž¬í•˜ê³  있다" +msgid "IP address and mask do not match" +msgstr "IP 주소와 마스í¬ê°€ ë§žì§€ 않습니다" -#: parser/analyze.c:881 +#: libpq/hba.c:1276 #, c-format -msgid "" -"The insertion source is a row expression containing the same number of " -"columns expected by the INSERT. Did you accidentally use extra parentheses?" -msgstr "" +msgid "end-of-line before authentication method" +msgstr "ì¸ì¦ 방법 ì „ì— ì¤„ ëì— ë„달함" -#: parser/analyze.c:1142 parser/analyze.c:1522 +#: libpq/hba.c:1287 #, c-format -msgid "SELECT ... INTO is not allowed here" -msgstr "SELECT ... INTO êµ¬ë¬¸ì€ ì—¬ê¸°ì„œëŠ” 사용할 수 ì—†ìŒ" +msgid "multiple values specified for authentication type" +msgstr "ì¸ì¦ 방법 ë¶€ë¶„ì— ì—¬ëŸ¬ ê°’ì´ ì§€ì •ë¨" -#: parser/analyze.c:1335 +#: libpq/hba.c:1288 #, c-format -msgid "DEFAULT can only appear in a VALUES list within INSERT" -msgstr "DEFAULT는 INSERT ë‚´ì˜ VALUES 목ë¡ì—ë§Œ í‘œì‹œë  ìˆ˜ 있ìŒ" +msgid "Specify exactly one authentication type per line." +msgstr "í•˜ë‚˜ì˜ ì¸ì¦ ë°©ë²•ì— ëŒ€í•´ì„œ 한 줄씩 지정해야 합니다" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1454 parser/analyze.c:2698 +#: libpq/hba.c:1365 #, c-format -msgid "%s cannot be applied to VALUES" -msgstr "%s êµ¬ë¬¸ì€ VALUES ì— ì ìš©í•  수 ì—†ìŒ" +msgid "invalid authentication method \"%s\"" +msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì´ ìž˜ëª»ë¨" -#: parser/analyze.c:1675 +#: libpq/hba.c:1378 #, c-format -msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" -msgstr "UNION/INTERSECT/EXCEPT ORDER BY ì ˆì´ ìž˜ëª»ë¨" +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "\"%s\" ì¸ì¦ ë°©ë²•ì´ ìž˜ëª»ë¨: ì´ ì„œë²„ì—서 ì§€ì›ë˜ì§€ 않ìŒ" -#: parser/analyze.c:1676 +#: libpq/hba.c:1401 #, c-format -msgid "Only result column names can be used, not expressions or functions." -msgstr "ê²°ê³¼ ì—´ ì´ë¦„ë§Œ 사용할 수 있고 ì‹ ë˜ëŠ” 함수는 사용할 수 없습니다." +msgid "gssapi authentication is not supported on local sockets" +msgstr "gssapi ì¸ì¦ì€ 로컬 소켓ì—서 ì§€ì›ë˜ì§€ 않ìŒ" -#: parser/analyze.c:1677 +#: libpq/hba.c:1413 #, c-format -msgid "" -"Add the expression/function to every SELECT, or move the UNION into a FROM " -"clause." -msgstr "모든 SELECTì— ì‹/함수를 추가하거나 UNIONì„ FROM 절로 ì´ë™í•˜ì‹­ì‹œì˜¤." +msgid "peer authentication is only supported on local sockets" +msgstr "peer ì¸ì¦ì€ 로컬 소켓ì—서만 ì§€ì›í•¨" -#: parser/analyze.c:1737 +#: libpq/hba.c:1431 #, c-format -msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" -msgstr "INTO 는 UNION/INTERSECT/EXCEPT ì˜ ì²«ë²ˆì§¸ SELECT ì—ë§Œ 허용ëœë‹¤" +msgid "cert authentication is only supported on hostssl connections" +msgstr "cert ì¸ì¦ì€ hostssl ì—°ê²°ì—서만 ì§€ì›ë¨" -#: parser/analyze.c:1801 +#: libpq/hba.c:1481 #, c-format -msgid "" -"UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of " -"same query level" -msgstr "" -"UNION/INTERSECT/EXCEPT 멤버 문ì—서 ê°™ì€ ì¿¼ë¦¬ ìˆ˜ì¤€ì˜ ë‹¤ë¥¸ 관계를 참조할 수 ì—†" -"ìŒ" +msgid "authentication option not in name=value format: %s" +msgstr "ì¸ì¦ ì˜µì…˜ì´ ì´ë¦„=ê°’ 형태가 아님: %s" -#: parser/analyze.c:1890 +#: libpq/hba.c:1522 #, c-format -msgid "each %s query must have the same number of columns" -msgstr "ê°ê°ì˜ %s query 는 ê°™ì€ ìˆ˜ì˜ columns 를 가져야 한다." +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, ldapurl ì˜µì…˜ì€ ldapprefix 옵션과 함께 사용할 수 ì—†ìŒ" -#: parser/analyze.c:2283 +#: libpq/hba.c:1533 #, c-format -msgid "RETURNING must have at least one column" -msgstr "RETURNING ì ˆì—는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¹¼ëŸ¼ì´ ìžˆì–´ì•¼ 합니다" +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "\"ldap\" ì¸ì¦ ë°©ë²•ì˜ ê²½ìš° \"ldapbasedn\", \"ldapprefix\", \"ldapsuffix\"ì˜µì…˜ì´ ìžˆì–´ì•¼ 함" -#: parser/analyze.c:2320 +#: libpq/hba.c:1549 #, c-format -msgid "cannot specify both SCROLL and NO SCROLL" -msgstr "SCROLL ê³¼ NO SCROLL 둘다를 명시할 수 없다" +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute ì˜µì…˜ì€ ldapsearchfilter 옵션과 함께 사용할 수 ì—†ìŒ" -#: parser/analyze.c:2338 +#: libpq/hba.c:1566 #, c-format -msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" -msgstr "" -"DECLARE CURSOR 구문ì—서 사용하는 WITH ì ˆ 안ì—는 ìžë£Œ 변경 êµ¬ë¬¸ì´ ì—†ì–´ì•¼ 합니" -"다" +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUS 서버 목ë¡ì€ 비어 ìžˆì„ ìˆ˜ ì—†ìŒ" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2346 +#: libpq/hba.c:1576 #, c-format -msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" -msgstr "DECLARE CURSOR WITH HOLD ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUS 비밀키 목ë¡ì€ 비어 ìžˆì„ ìˆ˜ ì—†ìŒ" -#: parser/analyze.c:2349 +#: libpq/hba.c:1629 #, c-format -msgid "Holdable cursors must be READ ONLY." -msgstr "보류 가능 커서는 READ ONLY여야 합니다." +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "서버 목ë¡ê³¼ 키 목ë¡ì´ 안 ë§žìŒ: %s (%d) / %s (%d)" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2357 +#: libpq/hba.c:1663 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi ë° cert" + +#: libpq/hba.c:1672 #, c-format -msgid "DECLARE SCROLL CURSOR ... %s is not supported" -msgstr "DECLARE SCROLL CURSOR ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert는 \"hostssl\" í–‰ì— ëŒ€í•´ì„œë§Œ 구성할 수 있ìŒ" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2368 +#: libpq/hba.c:1688 #, c-format -msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" -msgstr "DECLARE INSENSITIVE CURSOR ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "clientcert can not be set to 0 when using \"cert\" authentication" +msgstr "\"cert\" ì¸ì¦ì„ 사용하는 경우 clientcert를 0으로 설정할 수 ì—†ìŒ" -#: parser/analyze.c:2371 +#: libpq/hba.c:1725 #, c-format -msgid "Insensitive cursors must be READ ONLY." -msgstr "민ê°í•˜ì§€ ì•Šì€ ì»¤ì„œëŠ” READ ONLY여야 합니다." +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "\"%s\" LDAP URLì„ ë¶„ì„í•  수 ì—†ìŒ: %s" -#: parser/analyze.c:2437 +#: libpq/hba.c:1736 #, c-format -msgid "materialized views must not use data-modifying statements in WITH" -msgstr "" -"êµ¬ì²´í™”ëœ ë·° ì •ì˜ì— 사용한 WITH ì ˆ 안ì—는 ìžë£Œ 변경 êµ¬ë¬¸ì´ ì—†ì–´ì•¼ 합니다" +msgid "unsupported LDAP URL scheme: %s" +msgstr "ì§€ì›í•˜ì§€ 않는 LDAP URL 스킴: %s" -#: parser/analyze.c:2447 +#: libpq/hba.c:1760 #, c-format -msgid "materialized views must not use temporary tables or views" -msgstr "êµ¬ì²´í™”ëœ ë·°ëŠ” 임시 í…Œì´ë¸”ì´ë‚˜ 뷰를 사용할 수 없습니다" +msgid "LDAP URLs not supported on this platform" +msgstr "ì´ í”Œëž«í¼ì—서는 LDAP URL ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ." -#: parser/analyze.c:2457 +#: libpq/hba.c:1778 #, c-format -msgid "materialized views may not be defined using bound parameters" -msgstr "" +msgid "invalid ldapscheme value: \"%s\"" +msgstr "ìž˜ëª»ëœ ldapscheme ê°’: \"%s\"" -#: parser/analyze.c:2469 +#: libpq/hba.c:1796 #, c-format -msgid "materialized views cannot be UNLOGGED" -msgstr "êµ¬ì²´í™”ëœ ë·°ëŠ” UNLOGGED ì˜µì…˜ì„ ì‚¬ìš©í•  수 없습니다." +msgid "invalid LDAP port number: \"%s\"" +msgstr "LDAP í¬íЏ 번호가 잘못ë¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2535 +#: libpq/hba.c:1842 libpq/hba.c:1849 +msgid "gssapi and sspi" +msgstr "gssapi ë° sspi" + +#: libpq/hba.c:1858 libpq/hba.c:1867 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1889 #, c-format -msgid "%s is not allowed with DISTINCT clause" -msgstr "%s ì ˆì€ DISTINCT 절과 함께 사용할 수 없습니다" +msgid "could not parse RADIUS server list \"%s\"" +msgstr "RADIUS 서버 ëª©ë¡ ë¶„ì„ ì‹¤íŒ¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2542 +#: libpq/hba.c:1937 #, c-format -msgid "%s is not allowed with GROUP BY clause" -msgstr "%s ì ˆì€ GROUP BY 절과 함께 사용할 수 없습니다" +msgid "could not parse RADIUS port list \"%s\"" +msgstr "RADIUS 서버 í¬íЏ ëª©ë¡ ë¶„ì„ ì‹¤íŒ¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2549 +#: libpq/hba.c:1951 #, c-format -msgid "%s is not allowed with HAVING clause" -msgstr "%s ì ˆì€ HAVING 절과 함께 사용할 수 없습니다" +msgid "invalid RADIUS port number: \"%s\"" +msgstr "RADIUS í¬íЏ 번호가 잘못ë¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2556 +# translator: %s is IPv4, IPv6, or Unix +#: libpq/hba.c:1973 #, c-format -msgid "%s is not allowed with aggregate functions" -msgstr "%s ì ˆì€ ì§‘ê³„ 함수와 함께 사용할 수 없습니다" +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "RADIUS 서버 비밀키 ëª©ë¡ ë¶„ì„ ì‹¤íŒ¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2563 +#: libpq/hba.c:1995 #, c-format -msgid "%s is not allowed with window functions" -msgstr "%s ì ˆì€ ìœˆë„ìš° 함수와 함께 사용할 수 없습니다" +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "RADIUS 서버 ì‹ë³„ìž ëª©ë¡ ë¶„ì„ ì‹¤íŒ¨: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2570 +#: libpq/hba.c:2009 #, c-format -msgid "%s is not allowed with set-returning functions in the target list" -msgstr "%s ì ˆì€ ëŒ€ìƒ ëª©ë¡ì—서 세트 반환 함수와 함께 사용할 수 없습니다." +msgid "unrecognized authentication option name: \"%s\"" +msgstr "알 수 없는 ì¸ì¦ 옵션 ì´ë¦„: \"%s\"" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2649 +#: libpq/hba.c:2193 #, c-format -msgid "%s must specify unqualified relation names" -msgstr "%s ì ˆì—는 unqualified 릴레ì´ì…˜ ì´ë¦„ì„ ì§€ì •í•´ì•¼ 합니다." +msgid "configuration file \"%s\" contains no entries" +msgstr "\"%s\" 설정 파ì¼ì— 구성 í•­ëª©ì´ ì—†ìŒ" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2680 +#: libpq/hba.c:2703 #, c-format -msgid "%s cannot be applied to a join" -msgstr "%s ì ˆì€ ì¡°ì¸ì„ ì ìš©í•  수 없습니다." +msgid "invalid regular expression \"%s\": %s" +msgstr "\"%s\" ì •ê·œì‹ì´ 잘못ë¨: %s" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2689 +#: libpq/hba.c:2763 #, c-format -msgid "%s cannot be applied to a function" -msgstr "%s ì ˆì€ í•¨ìˆ˜ì— ì ìš©í•  수 없습니다." +msgid "regular expression match for \"%s\" failed: %s" +msgstr "\"%s\"ì— ëŒ€í•œ ì •ê·œì‹ ì¼ì¹˜ 실패: %s" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2707 +#: libpq/hba.c:2782 #, c-format -msgid "%s cannot be applied to a WITH query" -msgstr "%s ì ˆì€ WITH ì¿¼ë¦¬ì— ì ìš©í•  수 ì—†ìŒ" +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "\"%s\" ì •ê·œì‹ì—는 \"%s\"ì˜ backreferenceì—서 ìš”ì²­ëœ í•˜ìœ„ ì‹ì´ ì—†ìŒ" -#. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2724 +#: libpq/hba.c:2879 #, c-format -msgid "relation \"%s\" in %s clause not found in FROM clause" -msgstr "\"%s\" 릴레ì´ì…˜ (ëŒ€ìƒ êµ¬ë¬¸: %s) ì´ FROM ì ˆ ë‚´ì— ì—†ìŠµë‹ˆë‹¤" +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "ì œê³µëœ ì‚¬ìš©ìž ì´ë¦„(%s) ë° ì¸ì¦ëœ ì‚¬ìš©ìž ì´ë¦„(%s)ì´ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: parser/parse_agg.c:223 parser/parse_oper.c:220 +#: libpq/hba.c:2899 #, c-format -msgid "could not identify an ordering operator for type %s" -msgstr "%s ìžë£Œí˜•ì—서 사용할 순서 정하는 ì—°ì‚°ìžë¥¼ ì°¾ì„ ìˆ˜ 없습니다." +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "\"%s\" 사용ìžë§µ 파ì¼ì— \"%s\" 사용ìžë¥¼ \"%s\" 사용ìžë¡œ ì¸ì¦í•  ì„¤ì •ì´ ì—†ìŒ" -#: parser/parse_agg.c:225 +#: libpq/hba.c:2932 #, c-format -msgid "Aggregates with DISTINCT must be able to sort their inputs." -msgstr "" -"DISTINCT와 함께 작업하는 집계 ìž‘ì—…ì€ ê·¸ ìž…ë ¥ ìžë£Œê°€ ì •ë ¬ë  ìˆ˜ 있어야 합니다" +msgid "could not open usermap file \"%s\": %m" +msgstr "\"%s\" 사용ìžë§µ 파ì¼ì„ ì—´ 수 없습니다: %m" -#: parser/parse_agg.c:260 +#: libpq/pqcomm.c:220 #, c-format -msgid "GROUPING must have fewer than 32 arguments" -msgstr "GROUPING ì¸ìžë¡œëŠ” 32ê°œ ì´ë‚´ë¡œ 지정해야 합니다" +msgid "could not set socket to nonblocking mode: %m" +msgstr "ì†Œì¼“ì„ nonblocking 모드로 지정할 수 ì—†ìŒ: %m" -#: parser/parse_agg.c:363 -msgid "aggregate functions are not allowed in JOIN conditions" -msgstr "JOIN 조건문ì—서는 집계 함수가 허용ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:365 -msgid "grouping operations are not allowed in JOIN conditions" -msgstr "JOIN 조건문ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:377 -msgid "" -"aggregate functions are not allowed in FROM clause of their own query level" -msgstr "집계 함수는 ìžì‹ ì˜ 쿼리 ìˆ˜ì¤€ì˜ FROM ì ˆì—서는 사용할 수 없습니다." - -#: parser/parse_agg.c:379 -msgid "" -"grouping operations are not allowed in FROM clause of their own query level" -msgstr "" - -#: parser/parse_agg.c:384 -msgid "aggregate functions are not allowed in functions in FROM" -msgstr "FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ í‘œí˜„ì‹ ë‚´ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:386 -msgid "grouping operations are not allowed in functions in FROM" -msgstr "FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ í‘œí˜„ì‹ ë‚´ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:394 -msgid "aggregate functions are not allowed in policy expressions" -msgstr "ì •ì±… 표현ì‹ì—서는 집계 함수 ì‚¬ìš©ì„ í—ˆìš©í•˜ì§€ 않습니다" - -#: parser/parse_agg.c:396 -msgid "grouping operations are not allowed in policy expressions" -msgstr "ì •ì±… 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:413 -msgid "aggregate functions are not allowed in window RANGE" -msgstr "윈ë„ìš° RANGE 안ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:415 -msgid "grouping operations are not allowed in window RANGE" -msgstr "윈ë„ìš° RANGE 안ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:420 -msgid "aggregate functions are not allowed in window ROWS" -msgstr "윈ë„ìš° ROWS 안ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:422 -msgid "grouping operations are not allowed in window ROWS" -msgstr "윈ë„ìš° ROWS 안ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:455 -msgid "aggregate functions are not allowed in check constraints" -msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:457 -msgid "grouping operations are not allowed in check constraints" -msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:464 -msgid "aggregate functions are not allowed in DEFAULT expressions" -msgstr "DEFAULT 표현ì‹ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:466 -msgid "grouping operations are not allowed in DEFAULT expressions" -msgstr "DEFAULT 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" - -#: parser/parse_agg.c:471 -msgid "aggregate functions are not allowed in index expressions" -msgstr "ì¸ë±ìФ 표현ì‹ì—서는 집계 함수를 사용할 수 없습니다" - -#: parser/parse_agg.c:473 -msgid "grouping operations are not allowed in index expressions" -msgstr "ì¸ë±ìФ 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" +#: libpq/pqcomm.c:374 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ 경로가 너무 ê¹ë‹ˆë‹¤ (최대 %d ë°”ì´íЏ)" -#: parser/parse_agg.c:478 -msgid "aggregate functions are not allowed in index predicates" -msgstr "집계 함수는 함수 기반 ì¸ë±ìŠ¤ì˜ í•¨ìˆ˜ë¡œ 사용할 수 없습니다" +#: libpq/pqcomm.c:395 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "호스트 ì´ë¦„ \"%s\", 서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" -#: parser/parse_agg.c:480 -msgid "grouping operations are not allowed in index predicates" -msgstr "그룹핑 ìž‘ì—…ì€ í•¨ìˆ˜ 기반 ì¸ë±ìŠ¤ì˜ í•¨ìˆ˜ë¡œ 사용할 수 없습니다" +#: libpq/pqcomm.c:399 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "서비스 \"%s\"를 변환할 수 없습니다. 주소 : %s" -#: parser/parse_agg.c:485 -msgid "aggregate functions are not allowed in transform expressions" -msgstr "transform ì‹(expression)ì— ì§‘ê³„ 함수를 사용할 수 없습니다" +#: libpq/pqcomm.c:426 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "최대 ì ‘ì†ìž 수 MAXLISTEN (%d) 초과로 ë” ì´ìƒ ì ‘ì†ì´ 불가능합니다" -#: parser/parse_agg.c:487 -msgid "grouping operations are not allowed in transform expressions" -msgstr "transform ì‹(expression)ì— ê·¸ë£¹í•‘ 작업를 사용할 수 없습니다" +#: libpq/pqcomm.c:435 +msgid "IPv4" +msgstr "IPv4" -#: parser/parse_agg.c:492 -msgid "aggregate functions are not allowed in EXECUTE parameters" -msgstr "EXECUTE 매개 변수로 집계 함수를 사용할 수 없습니다" +#: libpq/pqcomm.c:439 +msgid "IPv6" +msgstr "IPv6" -#: parser/parse_agg.c:494 -msgid "grouping operations are not allowed in EXECUTE parameters" -msgstr "EXECUTE 매개 변수로 그룹핑 ìž‘ì—…ì„ ì‚¬ìš©í•  수 없습니다" +#: libpq/pqcomm.c:444 +msgid "Unix" +msgstr "유닉스" -#: parser/parse_agg.c:499 -msgid "aggregate functions are not allowed in trigger WHEN conditions" -msgstr "íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì— ì§‘ê³„ 함수가 허용ë˜ì§€ 않습니다" +#: libpq/pqcomm.c:449 +#, c-format +msgid "unrecognized address family %d" +msgstr "%d는 ì¸ì‹ë˜ì§€ 않는 가족 주소입니다" -#: parser/parse_agg.c:501 -msgid "grouping operations are not allowed in trigger WHEN conditions" -msgstr "íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì— ê·¸ë£¹í•‘ ìž‘ì—…ì´ í—ˆìš©ë˜ì§€ 않습니다" +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:475 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "%s 소켓 만들기 실패, ëŒ€ìƒ ì£¼ì†Œ: \"%s\": %m" -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:524 parser/parse_clause.c:1550 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:501 #, c-format -msgid "aggregate functions are not allowed in %s" -msgstr "집계 함수는 %s ì ˆì—서 사용할 수 없습니다." +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%s setsockopt(SO_REUSEADDR) 실패, ëŒ€ìƒ ì£¼ì†Œ: \"%s\": %m" -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:527 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:518 #, c-format -msgid "grouping operations are not allowed in %s" -msgstr "그룹핑 ìž‘ì—…ì€ %s ì ˆì—서 사용할 수 없습니다." +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%s setsockopt(IPV6_V6ONLY) 실패, ëŒ€ìƒ ì£¼ì†Œ: \"%s\": %m" -#: parser/parse_agg.c:635 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:538 #, c-format -msgid "" -"outer-level aggregate cannot contain a lower-level variable in its direct " -"arguments" -msgstr "" +msgid "could not bind %s address \"%s\": %m" +msgstr "%s ë°”ì¸ë“œ 실패, ëŒ€ìƒ ì£¼ì†Œ: \"%s\": %m" -#: parser/parse_agg.c:706 +#: libpq/pqcomm.c:541 #, c-format -msgid "aggregate function calls cannot contain window function calls" -msgstr "집계 함수 í˜¸ì¶œì€ ìœˆë„ìš° 함수 í˜¸ì¶œì„ í¬í•¨í•  수 ì—†ìŒ" +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "다른 postmaster ê°€ í¬íЏ %dì—서 ì´ë¯¸ 실행중ì¸ê²ƒ 같습니다? 그렇지 않다면 소켓 íŒŒì¼ \"%s\"ì„ ì œê±°í•˜ê³  다시 시ë„해보십시오" -#: parser/parse_agg.c:784 -msgid "window functions are not allowed in JOIN conditions" -msgstr "윈ë„ìš° 함수는 JOIN ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" +#: libpq/pqcomm.c:544 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "다른 postmaster ê°€ í¬íЏ %dì—서 ì´ë¯¸ 실행중ì¸ê²ƒ 같습니다? 그렇지 않다면 몇 초를 기다렸다가 다시 시ë„해보십시오." -#: parser/parse_agg.c:791 -msgid "window functions are not allowed in functions in FROM" -msgstr "윈ë„ìš° 함수는 FROM ì ˆì— ìžˆëŠ” 함수로 사용할 수 ì—†ìŒ" +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:577 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "%s 리슨 실패, ëŒ€ìƒ ì£¼ì†Œ: \"%s\": %m" -#: parser/parse_agg.c:797 -msgid "window functions are not allowed in policy expressions" -msgstr "윈ë„ìš° 함수는 ì •ì±… ì‹ì— 사용할 수 ì—†ìŒ" +# translator: %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:586 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ìœ¼ë¡œ ì ‘ì†ì„ 허용합니다" -#: parser/parse_agg.c:809 -msgid "window functions are not allowed in window definitions" -msgstr "윈ë„ìš° 함수는 윈ë„ìš° 함수 ì •ì˜ì— 사용할 수 ì—†ìŒ" +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:592 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "%s, 주소: \"%s\", í¬íЏ %d 번으로 ì ‘ì†ì„ 허용합니다" -#: parser/parse_agg.c:840 -msgid "window functions are not allowed in check constraints" -msgstr "윈ë„ìš° 함수는 check ì œì•½ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" +#: libpq/pqcomm.c:675 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "\"%s\" 그룹 ì—†ìŒ" -#: parser/parse_agg.c:844 -msgid "window functions are not allowed in DEFAULT expressions" -msgstr "윈ë„ìš° 함수는 DEFAULT ì‹ì—서 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:685 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "íŒŒì¼ \"%s\" ì˜ ê·¸ë£¹ì„ ì„¸íŒ…í•  수 없습니다: %m" -#: parser/parse_agg.c:847 -msgid "window functions are not allowed in index expressions" -msgstr "윈ë„ìš° 함수는 ì¸ë±ìФ ì‹ì—서 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:696 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "íŒŒì¼ \"%s\" ì˜ í¼ë¯¸ì…˜ì„ 세팅할 수 없습니다: %m" -#: parser/parse_agg.c:850 -msgid "window functions are not allowed in index predicates" -msgstr "윈ë„ìš° 함수는 함수 기반 ì¸ë±ìФì—서 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:726 +#, c-format +msgid "could not accept new connection: %m" +msgstr "새로운 ì—°ê²°ì„ ìƒì„±í•  수 없습니다: %m" -#: parser/parse_agg.c:853 -msgid "window functions are not allowed in transform expressions" -msgstr "윈ë„ìš° 함수는 transform ì‹ì—서 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:927 +#, c-format +msgid "there is no client connection" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²°ì´ ì—†ìŒ" -#: parser/parse_agg.c:856 -msgid "window functions are not allowed in EXECUTE parameters" -msgstr "윈ë„ìš° 함수는 EXECUTE 매개 변수 설정 값으로 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 +#, c-format +msgid "could not receive data from client: %m" +msgstr "í´ë¼ì´ì–¸íЏì—게 ë°ì´í„°ë¥¼ ë°›ì„ ìˆ˜ 없습니다: %m" -#: parser/parse_agg.c:859 -msgid "window functions are not allowed in trigger WHEN conditions" -msgstr "윈ë„ìš° 함수는 íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì—서 사용할 수 ì—†ìŒ" +#: libpq/pqcomm.c:1219 tcop/postgres.c:3997 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "프로토콜 ë™ê¸°í™” 작업 실패로 ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤" -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:879 parser/parse_clause.c:1559 +#: libpq/pqcomm.c:1285 #, c-format -msgid "window functions are not allowed in %s" -msgstr "%s 안ì—서는 윈ë„ìš° 함수를 사용할 수 ì—†ìŒ" +msgid "unexpected EOF within message length word" +msgstr "예ìƒì¹˜ 못한 EOFê°€ ë©”ì‹œì§€ì˜ ê¸¸ì´ ì›Œë“œì•ˆì—서 ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: parser/parse_agg.c:913 parser/parse_clause.c:2396 +#: libpq/pqcomm.c:1296 #, c-format -msgid "window \"%s\" does not exist" -msgstr "\"%s\" 윈ë„ìš° 함수가 ì—†ìŒ" +msgid "invalid message length" +msgstr "ë©”ì‹œì§€ì˜ ê¸¸ì´ê°€ 유효하지 않습니다" -#: parser/parse_agg.c:998 +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 #, c-format -msgid "too many grouping sets present (maximum 4096)" -msgstr "너무 ë§Žì€ ê·¸ë£¹í•‘ 세트가 있습니다 (최대값 4096)" +msgid "incomplete message from client" +msgstr "í´ë¼ì´ì–¸íŠ¸ìœ¼ë¡œë¶€í„°ì˜ ì™„ì „í•˜ì§€ 못한 메시지입니다" -#: parser/parse_agg.c:1147 +#: libpq/pqcomm.c:1464 #, c-format -msgid "" -"aggregate functions are not allowed in a recursive query's recursive term" -msgstr "집계 함수는 재귀 ì¿¼ë¦¬ì˜ ìž¬ê·€ ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "could not send data to client: %m" +msgstr "í´ë¼ì´ì–¸íЏì—게 ë°ì´í„°ë¥¼ 보낼 수 없습니다: %m" -#: parser/parse_agg.c:1340 +#: libpq/pqformat.c:406 #, c-format -msgid "" -"column \"%s.%s\" must appear in the GROUP BY clause or be used in an " -"aggregate function" -msgstr "" -"column \"%s.%s\" 는 반드시 GROUP BY ì ˆë‚´ì— ìžˆì–´ì•¼ 하ë˜ì§€ ë˜ëŠ” 집계 함수 ë‚´ì—" -"서 사용ë˜ì–´ì ¸ì•¼ 한다" +msgid "no data left in message" +msgstr "ë©”ì‹œì§€ì— ì•„ë¬´ëŸ° ë°ì´í„°ê°€ 없습니다" -#: parser/parse_agg.c:1343 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1458 utils/adt/rowtypes.c:566 #, c-format -msgid "" -"Direct arguments of an ordered-set aggregate must use only grouped columns." -msgstr "" +msgid "insufficient data left in message" +msgstr "부족한 ë°ì´í„°ëŠ” 메시지 ì•ˆì— ë„£ì–´ì ¸ 있습니다" -#: parser/parse_agg.c:1348 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format -msgid "subquery uses ungrouped column \"%s.%s\" from outer query" -msgstr "" -"subquery ê°€ outer query ì—서 그룹화 ë˜ì§€ ì•Šì€ ì—´ì¸ \"%s.%s\"를 사용합니다" +msgid "invalid string in message" +msgstr "ë©”ì‹œì§€ì•ˆì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžì—´ì´ 있습니다" -#: parser/parse_agg.c:1512 +#: libpq/pqformat.c:642 #, c-format -msgid "" -"arguments to GROUPING must be grouping expressions of the associated query " -"level" -msgstr "" +msgid "invalid message format" +msgstr "메시지 í¬ë§·ì´ 유효하지 않습니다." -#: parser/parse_clause.c:649 +# # search5 ë +# # advance 부분 +#: main/main.c:264 #, c-format -msgid "multiple column definition lists are not allowed for the same function" -msgstr "다중 칼럼 ì •ì˜ ëª©ë¡ì€ ê°™ì€ í•¨ìˆ˜ìš©ìœ¼ë¡œ 허용하지 않ìŒ" +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup 작업 실패: %d\n" -#: parser/parse_clause.c:682 +#: main/main.c:328 #, c-format msgid "" -"ROWS FROM() with multiple functions cannot have a column definition list" +"%s is the PostgreSQL server.\n" +"\n" msgstr "" +"%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL 서버입니다.\n" +"\n" -#: parser/parse_clause.c:683 +#: main/main.c:329 #, c-format msgid "" -"Put a separate column definition list for each function inside ROWS FROM()." +"Usage:\n" +" %s [OPTION]...\n" +"\n" msgstr "" +"사용법:\n" +" %s [옵션]...\n" +"\n" -#: parser/parse_clause.c:689 +#: main/main.c:330 #, c-format -msgid "UNNEST() with multiple arguments cannot have a column definition list" -msgstr "" +msgid "Options:\n" +msgstr "옵션들:\n" -#: parser/parse_clause.c:690 +#: main/main.c:331 #, c-format -msgid "" -"Use separate UNNEST() calls inside ROWS FROM(), and attach a column " -"definition list to each one." -msgstr "" +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS 공유 ë²„í¼ ê°œìˆ˜\n" -#: parser/parse_clause.c:697 +#: main/main.c:332 #, c-format -msgid "WITH ORDINALITY cannot be used with a column definition list" -msgstr "WITH ORDINALITY êµ¬ë¬¸ì€ ì¹¼ëŸ¼ ì •ì˜ ëª©ë¡ê³¼ 함께 쓸 수 없습니다." +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=VALUE 실시간 매개 변수 지정\n" -#: parser/parse_clause.c:698 +#: main/main.c:333 #, c-format -msgid "Put the column definition list inside ROWS FROM()." -msgstr "ROWS FROM() ì•ˆì— ì¹¼ëŸ¼ ì •ì˜ ëª©ë¡ì„ 넣으세요." +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME 실시간 매개 변수 ê°’ì„ ë³´ì—¬ì£¼ê³  마침\n" -#: parser/parse_clause.c:753 +#: main/main.c:334 #, c-format -msgid "tablesample method %s does not exist" -msgstr "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²•ì´ ì—†ìŠµë‹ˆë‹¤" +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 디버깅 수준\n" -#: parser/parse_clause.c:775 +#: main/main.c:335 #, c-format -msgid "tablesample method %s requires %d argument, not %d" -msgid_plural "tablesample method %s requires %d arguments, not %d" -msgstr[0] "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²• %dê°œ ì¸ìžë¥¼ 지정해야함, (현재 %dê°œ)" +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR ë°ì´í„° 디렉터리\n" -#: parser/parse_clause.c:809 +#: main/main.c:336 #, c-format -msgid "tablesample method %s does not support REPEATABLE" -msgstr "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²•ì€ REPEATABLE ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" +msgid " -e use European date input format (DMY)\n" +msgstr " -e ë‚ ì§œ ìž…ë ¥ ì–‘ì‹ì´ 유럽형(DMY)ì„ ì‚¬ìš©í•¨\n" -#: parser/parse_clause.c:940 +#: main/main.c:337 #, c-format -msgid "TABLESAMPLE clause can only be applied to tables and materialized views" -msgstr "TABLESAMPLE ì ˆì€ í…Œì´ë¸”ê³¼ êµ¬ì²´í™”ëœ ë·°ì—서만 사용할 수 있습니다" +msgid " -F turn fsync off\n" +msgstr " -F fsync 기능 ë”\n" -#: parser/parse_clause.c:1110 +#: main/main.c:338 #, c-format -msgid "column name \"%s\" appears more than once in USING clause" -msgstr "USING ì ˆ ë‚´ì— ì—´ ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 사용ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME 서버로 사용할 호스트 ì´ë¦„ ë˜ëŠ” IP\n" -#: parser/parse_clause.c:1125 +#: main/main.c:339 #, c-format -msgid "common column name \"%s\" appears more than once in left table" -msgstr "left table ë‚´ì— common column ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 사용ë˜ì—ˆë‹¤" +msgid " -i enable TCP/IP connections\n" +msgstr " -i TCP/IP ì—°ê²° 사용함\n" -#: parser/parse_clause.c:1134 +#: main/main.c:340 #, c-format -msgid "column \"%s\" specified in USING clause does not exist in left table" -msgstr "USING ì¡°ê±´ì ˆì—서 지정한 \"%s\" ì—´ì´ ì™¼ìª½ í…Œì´ë¸”ì— ì—†ìŒ" +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORY 유닉스 ë„ë©”ì¸ ì†Œì¼“ 위치\n" -#: parser/parse_clause.c:1148 +#: main/main.c:342 #, c-format -msgid "common column name \"%s\" appears more than once in right table" -msgstr "common column name \"%s\"ê°€ right table ì— í•œë²ˆ ì´ìƒ 사용ë˜ì—ˆë‹¤" +msgid " -l enable SSL connections\n" +msgstr " -l SSL ì—°ê²° 기능 사용함\n" -#: parser/parse_clause.c:1157 +#: main/main.c:344 #, c-format -msgid "column \"%s\" specified in USING clause does not exist in right table" -msgstr "USING ì¡°ê±´ì ˆì—서 지정한 \"%s\" ì—´ì´ ì˜¤ë¥¸ìª½ í…Œì´ë¸”ì— ì—†ìŒ" +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT 최대 ë™ì‹œ ì—°ê²° 개수\n" -#: parser/parse_clause.c:1211 +#: main/main.c:345 #, c-format -msgid "column alias list for \"%s\" has too many entries" -msgstr " \"%s\" 를 위한 ì—´ alias list ì— ë„ˆë¬´ ë§Žì€ entry ê°€ í¬í•¨ë˜ì–´ 있다" +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o OPTIONS 개별 서버 프로세스를 \"OPTIONS\" 옵션으로 실행 (옛기능)\n" -#. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1520 +#: main/main.c:346 #, c-format -msgid "argument of %s must not contain variables" -msgstr "%s ì˜ ì¸ìžë¡œ 변수를 í¬í•¨í•  수 없습니다." +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT 서버 í¬íЏ 번호\n" -#. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1685 +#: main/main.c:347 #, c-format -msgid "%s \"%s\" is ambiguous" -msgstr "%s \"%s\" ê°€ 명확하지 ì•Šì€ í‘œí˜„ìž…ë‹ˆë‹¤." +msgid " -s show statistics after each query\n" +msgstr " -s ê° ì¿¼ë¦¬ ë’¤ì— í†µê³„ì •ë³´ë¥¼ 보여줌\n" -#. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1714 +#: main/main.c:348 #, c-format -msgid "non-integer constant in %s" -msgstr "정수가 아닌 ìƒìˆ˜ê°€ %s ì— í¬í•¨ë˜ì–´ 있습니다" +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM ì •ë ¬ìž‘ì—…ì— ì‚¬ìš©í•  메모리 í¬ê¸°(kb 단위)를 지정\n" -#. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1736 +#: main/main.c:349 #, c-format -msgid "%s position %d is not in select list" -msgstr "%s position %d ê°€ select list ì— í¬í•¨ë˜ì–´ 있지 않습니다" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" -#: parser/parse_clause.c:2178 +#: main/main.c:350 #, c-format -msgid "CUBE is limited to 12 elements" -msgstr "CUBE ì¸ìžë¡œëŠ” 12ê°œ ì´í•˜ì˜ ì¸ìžë§Œ 허용합니다" +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=VALUE 실시간 매개 변수 지정\n" -#: parser/parse_clause.c:2384 +#: main/main.c:351 #, c-format -msgid "window \"%s\" is already defined" -msgstr "\"%s\" ì´ë¦„ì˜ ìœˆë„ìš° 함수가 ì´ë¯¸ ì •ì˜ë¨" +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config 서버 환경 ì„¤ì •ê°’ì— ëŒ€í•œ ì„¤ëª…ì„ ë³´ì—¬ì£¼ê³  마침\n" -#: parser/parse_clause.c:2446 +#: main/main.c:352 #, c-format -msgid "cannot override PARTITION BY clause of window \"%s\"" -msgstr "\"%s\" ì°½ì˜ PARTITION BY ì ˆì„ ìž¬ì •ì˜í•  수 ì—†ìŒ" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: parser/parse_clause.c:2458 +#: main/main.c:354 #, c-format -msgid "cannot override ORDER BY clause of window \"%s\"" -msgstr "\"%s\" ì°½ì˜ ORDER BY ì ˆì„ ìž¬ì •ì˜í•  수 ì—†ìŒ" +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"ê°œë°œìž ì˜µì…˜ë“¤:\n" -#: parser/parse_clause.c:2488 parser/parse_clause.c:2494 +#: main/main.c:355 #, c-format -msgid "cannot copy window \"%s\" because it has a frame clause" -msgstr "프래임 ì ˆì´ ìžˆì–´, \"%s\" 윈ë„우를 복사할 수 ì—†ìŒ." +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h 쿼리최ì í™”ê¸°ì˜ ê¸°ëŠ¥ì„ ì œí•œ 함\n" -#: parser/parse_clause.c:2496 +#: main/main.c:356 #, c-format -msgid "Omit the parentheses in this OVER clause." -msgstr "OVER ì ˆì— ê´„í˜¸ê°€ 빠졌ìŒ" +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n 비정ìƒì  종료 ë’¤ì— ê³µìœ  메모리를 초기화 하지 않ìŒ\n" -#: parser/parse_clause.c:2562 +#: main/main.c:357 #, c-format -msgid "" -"in an aggregate with DISTINCT, ORDER BY expressions must appear in argument " -"list" -msgstr "" -"DISTINCT, ORDER BY 표현ì‹ì„ 집계 함수와 쓸 때는, 반드시 select list ì— ë‚˜íƒ€ë‚˜" -"야만 합니다" +msgid " -O allow system table structure changes\n" +msgstr " -O 시스템 í…Œì´ë¸”ì˜ êµ¬ì¡°ë¥¼ 바꿀 수 있ë„ë¡ í•¨\n" -#: parser/parse_clause.c:2563 +#: main/main.c:358 #, c-format -msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" -msgstr "" -"SELECT DISTINCT, ORDER BY 표현ì‹ì„ 위해서 반드시 select list ì— ë‚˜íƒ€ë‚˜ì•¼ë§Œ í•©" -"니다" +msgid " -P disable system indexes\n" +msgstr " -P 시스템 ì¸ë±ìŠ¤ë“¤ì„ ì‚¬ìš©í•˜ì§€ 않ìŒ\n" -#: parser/parse_clause.c:2596 +#: main/main.c:359 #, c-format -msgid "an aggregate with DISTINCT must have at least one argument" -msgstr "DISTINCT 예약어로 집계를 í•  경우 ì ì–´ë„ í•˜ë‚˜ì˜ ì¸ìžëŠ” 있어야 함" +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex ê° ì¿¼ë¦¬ ë‹¤ìŒ ìž‘ì—…ì‹œê°„ì„ ë³´ì—¬ì¤Œ\n" -#: parser/parse_clause.c:2597 +#: main/main.c:360 #, c-format -msgid "SELECT DISTINCT must have at least one column" -msgstr "SELECT DISTINCT êµ¬ë¬¸ì€ ì ì–´ë„ 한 ê°œ ì´ìƒì˜ ì¹¼ëŸ¼ì´ ìžˆì–´ì•¼ 합니다" +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr "" +" -T í•˜ë‚˜ì˜ í•˜ìœ„ 서버 프로세스가 비정ìƒìœ¼ë¡œ 마치며 모든\n" +" 다른 서버 프로세스ì—게 SIGSTOP 신호를 보냄\n" -#: parser/parse_clause.c:2663 parser/parse_clause.c:2695 +#: main/main.c:361 #, c-format -msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" -msgstr "" -"SELECT DISTINCT ON 표현ì‹ì€ 반드시 초기 ORDER BY 표현ì‹ê³¼ ì¼ì¹˜í•˜ì—¬ì•¼ 한다" +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NUM 디버그 ìž‘ì—…ì„ ìœ„í•´ 지정한 숫ìžì˜ ì´ˆë§Œí¼ ê¸°ë‹¤ë¦°ë‹¤\n" -#: parser/parse_clause.c:2774 +#: main/main.c:363 #, c-format -msgid "ASC/DESC is not allowed in ON CONFLICT clause" -msgstr "ASC/DESC 예약어는 ON CONFLICT 절과 함께 사용할 수 없습니다." +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"단ì¼ì‚¬ìš©ìž 모드ì—서 사용할 수 있는 옵션들:\n" -#: parser/parse_clause.c:2780 +#: main/main.c:364 #, c-format -msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" -msgstr "NULLS FIRST/LAST ì ˆì€ ON CONFLICT 절과 함께 사용할 수 없습니다." +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single ë‹¨ì¼ ì‚¬ìš©ìž ëª¨ë“œ ì„ íƒ (ì¸ìžì˜ 첫번째로 와야함)\n" -#: parser/parse_clause.c:2860 +#: main/main.c:365 #, c-format -msgid "" -"ON CONFLICT DO UPDATE requires inference specification or constraint name" -msgstr "" +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME ë°ì´í„°ë² ì´ìФ ì´ë¦„ (초기값: 사용ìžì´ë¦„)\n" -#: parser/parse_clause.c:2861 +#: main/main.c:366 #, c-format -msgid "For example, ON CONFLICT (column_name)." -msgstr "사용예, ON CONFLICT (칼럼ì´ë¦„)." +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 디버깅 수준\n" -#: parser/parse_clause.c:2872 +#: main/main.c:367 #, c-format -msgid "ON CONFLICT is not supported with system catalog tables" -msgstr "ON CONFLICT ì ˆì€ ì‹œìŠ¤í…œ 카탈로그 í…Œì´ë¸”ì—서는 사용할 수 없습니다" +msgid " -E echo statement before execution\n" +msgstr " -E 실행하기 ì „ì— ìž‘ì—…ëª…ë ¹ì„ ì¶œë ¥í•¨\n" -#: parser/parse_clause.c:2880 +#: main/main.c:368 #, c-format -msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" -msgstr "" -"\"%s\" í…Œì´ë¸”ì—는 ON CONFLICT ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다. ì´ í…Œì´ë¸”ì€ ì¹´íƒˆë¡œ" -"ê·¸ í…Œì´ë¸”로 사용ë©ë‹ˆë‹¤." +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j 대화형 ì¿¼ë¦¬ì˜ ëª…ë ¹ 실행 구분 문ìžë¡œ 줄바꿈문ìžë¥¼ ì“°ì§€ 않ìŒ\n" -#: parser/parse_clause.c:3012 +#: main/main.c:369 main/main.c:374 #, c-format -msgid "operator %s is not a valid ordering operator" -msgstr "%s ì—°ì‚°ìžëŠ” 유효한 순서 지정 ì—°ì‚°ìžê°€ 아님" +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FILENAME stdout, stderr 쪽으로 보내는 ë‚´ìš©ì„ FILENAME 파ì¼ë¡œ 저장함\n" -#: parser/parse_clause.c:3014 +#: main/main.c:371 #, c-format msgid "" -"Ordering operators must be \"<\" or \">\" members of btree operator families." +"\n" +"Options for bootstrapping mode:\n" msgstr "" -"순서 지정 ì—°ì‚°ìžëŠ” btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì˜ \"<\" or \">\" 멤버여야 합니다." +"\n" +"부트스트랩 모드ì—서 사용할 수 있는 옵션들:\n" -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2053 parser/parse_expr.c:2577 parser/parse_target.c:885 +#: main/main.c:372 #, c-format -msgid "cannot cast type %s to %s" -msgstr "%s ìžë£Œí˜•ì„ %s ìžë£Œí˜•으로 형변환할 수 없습니다." +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot 부트스트랩 모드로 실행 (첫번째 ì¸ìžë¡œ 와야함)\n" -#: parser/parse_coerce.c:1004 +#: main/main.c:373 #, c-format -msgid "Input has too few columns." -msgstr "ìž…ë ¥ì— ë„ˆë¬´ ì ì€ ì—´ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤." +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME ë°ì´í„°ë² ì´ìФ ì´ë¦„ (부트스트랩 모드ì—서 필수)\n" -#: parser/parse_coerce.c:1022 +#: main/main.c:375 #, c-format -msgid "Cannot cast type %s to %s in column %d." -msgstr "%s ìžë£Œí˜•ì„ %s ìžë£Œí˜•으로 형변환할 수 없습니다 해당 ì—´ %d." +msgid " -x NUM internal use\n" +msgstr " -x NUM ë‚´ë¶€ì ì¸ 옵션\n" -#: parser/parse_coerce.c:1037 +#: main/main.c:377 #, c-format -msgid "Input has too many columns." -msgstr "ìž…ë ¥ì— ë„ˆë¬´ ë§Žì€ ì—´ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤." +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ì´ ì‹¤ì‹œê°„ 환경 변수용 ì„¤ì •ê°’ë“¤ì˜ ìžì„¸í•œ 사용법과\n" +"서버 환경 설정 파ì¼ì— 어떻게 지정하고 ì‚¬ìš©í•˜ëŠ”ì§€ì— ëŒ€í•œ 사항ì€\n" +"PostgreSQL 문서를 참조하세요.\n" +"\n" +"오류 ë³´ê³ : .\n" -#. translator: first %s is name of a SQL construct, eg WHERE -#: parser/parse_coerce.c:1080 +#: main/main.c:391 #, c-format -msgid "argument of %s must be type boolean, not type %s" -msgstr "%sì˜ ì¸ìžëŠ” %s ìžë£Œí˜•ì´ ì•„ë‹ˆë¼, boolean ìžë£Œí˜•ì´ì–´ì•¼ 합니다" +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"시스템 보안 관련 문제로, PostgreSQL server를 \"root\" ID로 실행할 수 없습니다.\n" +"반드시 ì¼ë°˜ ì‚¬ìš©ìž ID(시스템 ê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ” ID)로 서버를 실행하십시오.\n" +"Server를 어떻게 안전하게 기ë™í•˜ëŠ”ê°€ 하는 ê²ƒì€ ë¬¸ì„œë¥¼ 참조하시기 ë°”ëžë‹ˆë‹¤.\n" -#. translator: %s is name of a SQL construct, eg WHERE -#. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1090 parser/parse_coerce.c:1139 +#: main/main.c:408 #, c-format -msgid "argument of %s must not return a set" -msgstr "%s ì˜ ì¸ìžëŠ” set(ì§‘í•©) ì„ return할수 없습니다." +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: real ë˜ëŠ” effective user ID ë“¤ì€ ë°˜ë“œì‹œ ì¼ì¹˜ë˜ì–´ì•¼ 한다.\n" -#. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1127 +#: main/main.c:415 #, c-format -msgid "argument of %s must be type %s, not type %s" -msgstr "%sì˜ ì¸ìžëŠ” %s ìžë£Œí˜•ì´ì–´ì•¼ 함(%s ìžë£Œí˜•ì´ ì•„ë‹˜)" +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"시스템 보안 관련 문제로, PostgreSQL server를 시스템 ê´€ë¦¬ìž ID로 실행할 수 없습니다.\n" +"반드시 ì¼ë°˜ ì‚¬ìš©ìž ID(시스템 ê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ” ID)로 서버를 실행하십시오.\n" +"Server를 어떻게 안전하게 기ë™í•˜ëŠ”ê°€ 하는 ê²ƒì€ ë¬¸ì„œë¥¼ 참조하시기 ë°”ëžë‹ˆë‹¤.\n" -#. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1260 +#: nodes/extensible.c:66 #, c-format -msgid "%s types %s and %s cannot be matched" -msgstr "%s ìžë£Œí˜• %s 와 %s 는 서로 매치ë˜ì§€ 않습니다" +msgid "extensible node type \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ í™•ìž¥ê°€ëŠ¥í•œ 노드 í˜•ì´ ì´ë¯¸ 있습니다" -#. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1327 +#: nodes/extensible.c:114 #, c-format -msgid "%s could not convert type %s to %s" -msgstr "%s 는 ìžë£Œí˜• %s ìžë£Œí˜•ì—서 %s ìžë£Œí˜•으로 ë³€í™˜ë  ìˆ˜ 없습니다." +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "\"%s\" ExtensibleNodeMethodsê°€ 등ë¡ë˜ì–´ 있지 않ìŒ" -#: parser/parse_coerce.c:1629 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1910 +#: parser/parse_coerce.c:1938 parser/parse_coerce.c:2014 +#: parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format -msgid "arguments declared \"anyelement\" are not all alike" -msgstr "\"anyelement\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다" +msgid "could not find array type for data type %s" +msgstr "ìžë£Œí˜• %s ì— ëŒ€í•´ì„œëŠ” ë°°ì—´ ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" -#: parser/parse_coerce.c:1649 +#: optimizer/path/joinrels.c:837 #, c-format -msgid "arguments declared \"anyarray\" are not all alike" -msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다." +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN êµ¬ë¬¸ì€ ë¨¸ì§€ ì¡°ì¸ì´ë‚˜, 해시 ì¡°ì¸ì´ 가능한 ìƒí™©ì—서만 사용할 수 있습니다" -#: parser/parse_coerce.c:1669 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1221 #, c-format -msgid "arguments declared \"anyrange\" are not all alike" -msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다." +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s êµ¬ë¬¸ì€ outer ì¡°ì¸ìœ¼ë¡œ null ê°’ì´ ì˜¬ 수 있는 ìª½ì— ëŒ€í•´ì„œëŠ” ì ìš©í•  수 없습니다" -#: parser/parse_coerce.c:1698 parser/parse_coerce.c:1909 -#: parser/parse_coerce.c:1943 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1768 parser/analyze.c:1651 parser/analyze.c:1848 +#: parser/analyze.c:2679 #, c-format -msgid "argument declared \"anyarray\" is not an array but type %s" -msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ array ê°€ 아니고, %s ìžë£Œí˜•입니다" +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s êµ¬ë¬¸ì€ UNION/INTERSECT/EXCEPT 예약어들과 함께 사용할 수 없습니다." -#: parser/parse_coerce.c:1714 +#: optimizer/plan/planner.c:2340 optimizer/plan/planner.c:4061 #, c-format -msgid "" -"argument declared \"anyarray\" is not consistent with argument declared " -"\"anyelement\"" -msgstr "" -"\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ \"anyelement\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ê³¼ ì¼ê´€ì„±ì´ 있" -"질 않습니다" +msgid "could not implement GROUP BY" +msgstr "GROUP BY를 구현할 수 ì—†ìŒ" -#: parser/parse_coerce.c:1735 parser/parse_coerce.c:1956 +#: optimizer/plan/planner.c:2341 optimizer/plan/planner.c:4062 +#: optimizer/plan/planner.c:4805 optimizer/prep/prepunion.c:1080 #, c-format -msgid "argument declared \"anyrange\" is not a range type but type %s" -msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ range ìžë£Œí˜•ì´ ì•„ë‹ˆê³ , %s ìžë£Œí˜•입니다" +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "해싱만 ì§€ì›í•˜ëŠ” ìžë£Œí˜•ë„ ìžˆê³ , 정렬만 ì§€ì›í•˜ëŠ” ìžë£Œí˜•ë„ ìžˆìŠµë‹ˆë‹¤." -#: parser/parse_coerce.c:1751 +#: optimizer/plan/planner.c:4804 #, c-format -msgid "" -"argument declared \"anyrange\" is not consistent with argument declared " -"\"anyelement\"" -msgstr "" -"\"anyrange\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ \"anyelement\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ê³¼ ì¼ê´€ì„±ì´ 있" -"질 않습니다" +msgid "could not implement DISTINCT" +msgstr "DISTINCT를 구현할 수 ì—†ìŒ" -#: parser/parse_coerce.c:1771 +#: optimizer/plan/planner.c:5487 #, c-format -msgid "could not determine polymorphic type because input has type \"unknown\"" -msgstr "ìž…ë ¥ì— \"unknown\" 형ì‹ì´ 있으므로 다변 형ì‹ì„ 확ì¸í•  수 ì—†ìŒ" +msgid "could not implement window PARTITION BY" +msgstr "ì°½ PARTITION BY를 구현할 수 ì—†ìŒ" -#: parser/parse_coerce.c:1781 +#: optimizer/plan/planner.c:5488 #, c-format -msgid "type matched to anynonarray is an array type: %s" -msgstr "anynonarrayì— ì¼ì¹˜ëœ 형ì‹ì´ ë°°ì—´ 형ì‹ìž„: %s" +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "ì°½ ë¶„í•  ì¹¼ëŸ¼ì€ ì •ë ¬ 가능한 ë°ì´í„° 형ì‹ì´ì–´ì•¼ 합니다." -#: parser/parse_coerce.c:1791 +#: optimizer/plan/planner.c:5492 #, c-format -msgid "type matched to anyenum is not an enum type: %s" -msgstr "anyenumì— ì¼ì¹˜ëœ 형ì‹ì´ ì—´ê±° 형ì‹ì´ 아님: %s" +msgid "could not implement window ORDER BY" +msgstr "ì°½ ORDER BY를 구현할 수 ì—†ìŒ" -#: parser/parse_coerce.c:1831 parser/parse_coerce.c:1861 +#: optimizer/plan/planner.c:5493 #, c-format -msgid "could not find range type for data type %s" -msgstr "ìžë£Œí˜• %s ì— ëŒ€í•´ì„œëŠ” ë°°ì—´ ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" +msgid "Window ordering columns must be of sortable datatypes." +msgstr "ì°½ 순서 지정 ì¹¼ëŸ¼ì€ ì •ë ¬ 가능한 ë°ì´í„° 형ì‹ì´ì–´ì•¼ 합니다." -#: parser/parse_collate.c:228 parser/parse_collate.c:475 -#: parser/parse_collate.c:986 +#: optimizer/plan/setrefs.c:414 #, c-format -msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" -msgstr "" -"암묵ì ìœ¼ë¡œ ì„ íƒëœ \"%s\" ì •ë ¬ 규칙와 \"%s\" ì •ë ¬ ê·œì¹™ì´ ë§¤ì¹­ë˜ì§€ 않습니다" +msgid "too many range table entries" +msgstr "너무 ë§Žì€ í…Œì´ë¸”ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤" -#: parser/parse_collate.c:231 parser/parse_collate.c:478 -#: parser/parse_collate.c:989 +#: optimizer/prep/prepunion.c:544 #, c-format -msgid "" -"You can choose the collation by applying the COLLATE clause to one or both " -"expressions." -msgstr "한 쪽 ë˜ëŠ” 서로 COLLATE ì ˆì„ ì´ìš©í•´ ì •ë ¬ ê·œì¹™ì„ ì§€ì •í•˜ì„¸ìš”" +msgid "could not implement recursive UNION" +msgstr "재귀 UNIONì„ êµ¬í˜„í•  수 ì—†ìŒ" -#: parser/parse_collate.c:834 +#: optimizer/prep/prepunion.c:545 #, c-format -msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" -msgstr "" -"명시ì ìœ¼ë¡œ 지정한 \"%s\" 정렬규칙와 \"%s\" ì •ë ¬ê·œì¹™ì´ ë§¤ì¹­ë˜ì§€ 않습니다" +msgid "All column datatypes must be hashable." +msgstr "모든 ì—´ ë°ì´í„° 형ì‹ì€ 해시 가능해야 합니다." -#: parser/parse_cte.c:42 +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1079 #, c-format -msgid "" -"recursive reference to query \"%s\" must not appear within its non-recursive " -"term" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 비재귀 구문 안ì—는 없어야 함" +msgid "could not implement %s" +msgstr "%s êµ¬ë¬¸ì€ êµ¬í˜„í•  수 ì—†ìŒ" -#: parser/parse_cte.c:44 +#: optimizer/util/clauses.c:4854 #, c-format -msgid "recursive reference to query \"%s\" must not appear within a subquery" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 하위 쿼리 ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" +msgid "SQL function \"%s\" during inlining" +msgstr "" -#: parser/parse_cte.c:46 +#: optimizer/util/plancat.c:127 #, c-format -msgid "" -"recursive reference to query \"%s\" must not appear within an outer join" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 outer join 구문 ì•ˆì— ì—†ì–´ì•¼ 함" +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "복구 작업 중ì—는 임시 í…Œì´ë¸”ì´ë‚˜, 언로그드 í…Œì´ë¸”ì„ ì ‘ê·¼í•  수 ì—†ìŒ" -#: parser/parse_cte.c:48 +#: optimizer/util/plancat.c:651 #, c-format -msgid "recursive reference to query \"%s\" must not appear within INTERSECT" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 INTERSECT ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" +msgid "whole row unique index inference specifications are not supported" +msgstr "" -#: parser/parse_cte.c:50 +#: optimizer/util/plancat.c:668 #, c-format -msgid "recursive reference to query \"%s\" must not appear within EXCEPT" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 EXCEPT ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ON CONFLICT 처리를 위해 ê´€ë ¨ëœ ì¸ë±ìŠ¤ê°€ 없습니다" -#: parser/parse_cte.c:132 +#: optimizer/util/plancat.c:719 #, c-format -msgid "WITH query name \"%s\" specified more than once" -msgstr "\"%s\" WITH 쿼리 ì´ë¦„ì´ ì—¬ëŸ¬ 번 지정ë¨" +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "제외 제약 ì¡°ê±´ì´ ìžˆì–´ ON CONFLICT DO UPDATE ìž‘ì—…ì€ í•  수 없습니다" -#: parser/parse_cte.c:264 +#: optimizer/util/plancat.c:824 #, c-format -msgid "" -"WITH clause containing a data-modifying statement must be at the top level" -msgstr "ìžë£Œë¥¼ 변경하는 êµ¬ë¬¸ì´ ìžˆëŠ” WITH ì ˆì€ ìµœìƒìœ„ ìˆ˜ì¤€ì— ìžˆì–´ì•¼ 합니다" +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "ON CONFLICT ì ˆì„ ì‚¬ìš©í•˜ëŠ” 경우, unique 나 exclude 제약 ì¡°ê±´ì´ ìžˆì–´ì•¼ 함" -#: parser/parse_cte.c:313 +#: parser/analyze.c:709 parser/analyze.c:1414 #, c-format -msgid "" -"recursive query \"%s\" column %d has type %s in non-recursive term but type " -"%s overall" -msgstr "" -"\"%s\" 재귀 ì¿¼ë¦¬ì˜ %d 번째 ì¹¼ëŸ¼ì€ ë¹„ìž¬ê·€ ì¡°ê±´ì— %s ìžë£Œí˜•ì„ í¬í•¨í•˜ëŠ”ë° ì „ì²´ì " -"으로는 %s ìžë£Œí˜•ìž„" +msgid "VALUES lists must all be the same length" +msgstr "VALUES 목ë¡ì€ ëª¨ë‘ ê°™ì€ ê¸¸ì´ì—¬ì•¼ 함" -#: parser/parse_cte.c:319 +#: parser/analyze.c:919 #, c-format -msgid "Cast the output of the non-recursive term to the correct type." -msgstr "비재귀 ì¡°ê±´ì˜ ì¶œë ¥ì„ ì˜¬ë°”ë¥¸ 형ì‹ìœ¼ë¡œ 형변환하십시오." +msgid "INSERT has more expressions than target columns" +msgstr "INSERT êµ¬ë¬¸ì— target columns 보다 ë” ë§Žì€ í‘œí˜„ì‹ì´ 존재하고 있다" -#: parser/parse_cte.c:324 +#: parser/analyze.c:937 #, c-format -msgid "" -"recursive query \"%s\" column %d has collation \"%s\" in non-recursive term " -"but collation \"%s\" overall" -msgstr "" -"\"%s\" 재귀 ì¿¼ë¦¬ì˜ %d 번째 ì¹¼ëŸ¼ì€ ë¹„ìž¬ê·€ ì¡°ê±´ì— %s ìžë£Œí˜•ì„ í¬í•¨í•˜ëŠ”ë° ì „ì²´ì " -"으로는 %s ìžë£Œí˜•ìž„" +msgid "INSERT has more target columns than expressions" +msgstr "INSERT êµ¬ë¬¸ì— target columns 보다 ë” ë§Žì€ í‘œí˜„ì‹(expressions)ì´ ì¡´ìž¬í•˜ê³  있다" -#: parser/parse_cte.c:328 +#: parser/analyze.c:941 #, c-format -msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" msgstr "" -#: parser/parse_cte.c:419 +#: parser/analyze.c:1227 parser/analyze.c:1624 #, c-format -msgid "WITH query \"%s\" has %d columns available but %d columns specified" -msgstr "" -"\"%s\" WITH 쿼리ì—는 %dê°œì˜ ì¹¼ëŸ¼ì„ ì‚¬ìš©í•  수 ìžˆëŠ”ë° %dê°œì˜ ì¹¼ëŸ¼ì´ ì§€ì •ë¨" +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO êµ¬ë¬¸ì€ ì—¬ê¸°ì„œëŠ” 사용할 수 ì—†ìŒ" -#: parser/parse_cte.c:599 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1556 parser/analyze.c:2858 #, c-format -msgid "mutual recursion between WITH items is not implemented" -msgstr "WITH 항목 ê°„ì˜ ìƒí˜¸ 재귀가 구현ë˜ì§€ 않ìŒ" +msgid "%s cannot be applied to VALUES" +msgstr "%s êµ¬ë¬¸ì€ VALUES ì— ì ìš©í•  수 ì—†ìŒ" -#: parser/parse_cte.c:651 +#: parser/analyze.c:1775 #, c-format -msgid "recursive query \"%s\" must not contain data-modifying statements" -msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì— ìžë£Œ 변경 êµ¬ë¬¸ì´ í¬í•¨ë  수 없습니다." +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "UNION/INTERSECT/EXCEPT ORDER BY ì ˆì´ ìž˜ëª»ë¨" -#: parser/parse_cte.c:659 +#: parser/analyze.c:1776 #, c-format -msgid "" -"recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] " -"recursive-term" -msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì— ë¹„ìž¬ê·€ ì¡°ê±´ í˜•íƒœì˜ UNION [ALL] 재귀 ì¡°ê±´ì´ ì—†ìŒ" +msgid "Only result column names can be used, not expressions or functions." +msgstr "ê²°ê³¼ ì—´ ì´ë¦„ë§Œ 사용할 수 있고 ì‹ ë˜ëŠ” 함수는 사용할 수 없습니다." -#: parser/parse_cte.c:703 +#: parser/analyze.c:1777 #, c-format -msgid "ORDER BY in a recursive query is not implemented" -msgstr "재귀 ì¿¼ë¦¬ì˜ ORDER BYê°€ 구현ë˜ì§€ 않ìŒ" +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "모든 SELECTì— ì‹/함수를 추가하거나 UNIONì„ FROM 절로 ì´ë™í•˜ì‹­ì‹œì˜¤." -#: parser/parse_cte.c:709 +#: parser/analyze.c:1838 #, c-format -msgid "OFFSET in a recursive query is not implemented" -msgstr "재귀 ì¿¼ë¦¬ì˜ OFFSETì´ êµ¬í˜„ë˜ì§€ 않ìŒ" +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO 는 UNION/INTERSECT/EXCEPT ì˜ ì²«ë²ˆì§¸ SELECT ì—ë§Œ 허용ëœë‹¤" -#: parser/parse_cte.c:715 +#: parser/analyze.c:1910 #, c-format -msgid "LIMIT in a recursive query is not implemented" -msgstr "재귀 ì¿¼ë¦¬ì˜ LIMITê°€ 구현ë˜ì§€ 않ìŒ" +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "UNION/INTERSECT/EXCEPT 멤버 문ì—서 ê°™ì€ ì¿¼ë¦¬ ìˆ˜ì¤€ì˜ ë‹¤ë¥¸ 관계를 참조할 수 ì—†ìŒ" -#: parser/parse_cte.c:721 +#: parser/analyze.c:1999 #, c-format -msgid "FOR UPDATE/SHARE in a recursive query is not implemented" -msgstr "재귀 ì¿¼ë¦¬ì˜ FOR UPDATE/SHAREê°€ 구현ë˜ì§€ 않ìŒ" +msgid "each %s query must have the same number of columns" +msgstr "ê°ê°ì˜ %s query 는 ê°™ì€ ìˆ˜ì˜ columns 를 가져야 한다." -#: parser/parse_cte.c:778 +#: parser/analyze.c:2392 #, c-format -msgid "recursive reference to query \"%s\" must not appear more than once" -msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 여러 번 표시ë˜ì§€ 않아야 함" +msgid "RETURNING must have at least one column" +msgstr "RETURNING ì ˆì—는 ì ì–´ë„ 하나 ì´ìƒì˜ ì¹¼ëŸ¼ì´ ìžˆì–´ì•¼ 합니다" -#: parser/parse_expr.c:390 parser/parse_relation.c:3176 -#: parser/parse_relation.c:3196 +#: parser/analyze.c:2433 #, c-format -msgid "column %s.%s does not exist" -msgstr "%s.%s 칼럼 ì—†ìŒ" +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "SCROLL ê³¼ NO SCROLL 둘다를 명시할 수 없다" -#: parser/parse_expr.c:402 +#: parser/analyze.c:2452 #, c-format -msgid "column \"%s\" not found in data type %s" -msgstr "\"%s\" ì—´ì€ %s ìžë£Œí˜•ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR 구문ì—서 사용하는 WITH ì ˆ 안ì—는 ìžë£Œ 변경 êµ¬ë¬¸ì´ ì—†ì–´ì•¼ 합니다" -#: parser/parse_expr.c:408 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2460 #, c-format -msgid "could not identify column \"%s\" in record data type" -msgstr "레코드 ë°ì´í„° 형ì‹ì—서 \"%s\" ì—´ì„ ì‹ë³„í•  수 ì—†ìŒ" +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: parser/parse_expr.c:414 +#: parser/analyze.c:2463 #, c-format -msgid "column notation .%s applied to type %s, which is not a composite type" -msgstr "" -".%s í‘œí˜„ì´ %s ìžë£Œí˜• 사용ë˜ì—ˆëŠ”ë°, ì´ëŠ” 복소수형 (complex type)ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "Holdable cursors must be READ ONLY." +msgstr "보류 가능 커서는 READ ONLY여야 합니다." -#: parser/parse_expr.c:444 parser/parse_target.c:671 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2471 #, c-format -msgid "row expansion via \"*\" is not supported here" -msgstr "\"*\"를 통한 칼럼 í™•ìž¥ì€ ì—¬ê¸°ì„œ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: parser/parse_expr.c:770 parser/parse_relation.c:668 -#: parser/parse_relation.c:768 parser/parse_target.c:1120 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2482 #, c-format -msgid "column reference \"%s\" is ambiguous" -msgstr "칼럼 참조 \"%s\" ê°€ 모호합니다." +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s êµ¬ë¬¸ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: parser/parse_expr.c:826 parser/parse_param.c:110 parser/parse_param.c:142 -#: parser/parse_param.c:199 parser/parse_param.c:298 +#: parser/analyze.c:2485 #, c-format -msgid "there is no parameter $%d" -msgstr "$%d 매개 변수가 없습니다" +msgid "Insensitive cursors must be READ ONLY." +msgstr "민ê°í•˜ì§€ ì•Šì€ ì»¤ì„œëŠ” READ ONLY여야 합니다." -#: parser/parse_expr.c:1067 +#: parser/analyze.c:2551 #, c-format -msgid "NULLIF requires = operator to yield boolean" -msgstr "NULIF ì ˆì€ boolean ê°’ì„ ì–»ê¸° 위해서 = ì—°ì‚°ìžë¥¼ 필요로 합니다" +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "êµ¬ì²´í™”ëœ ë·° ì •ì˜ì— 사용한 WITH ì ˆ 안ì—는 ìžë£Œ 변경 êµ¬ë¬¸ì´ ì—†ì–´ì•¼ 합니다" -#: parser/parse_expr.c:1501 gram.y:9887 +#: parser/analyze.c:2561 #, c-format -msgid "number of columns does not match number of values" -msgstr "ì—´ì˜ ê°œìˆ˜ì™€, valuesì˜ ê°œìˆ˜ê°€ 틀립니다" - -#: parser/parse_expr.c:1730 -msgid "cannot use subquery in check constraint" -msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 서브쿼리를 사용할 수 없습니다" - -#: parser/parse_expr.c:1734 -msgid "cannot use subquery in DEFAULT expression" -msgstr "DEFAULT ì‹ì—서는 서브쿼리를 사용할 수 없습니다" - -#: parser/parse_expr.c:1737 -msgid "cannot use subquery in index expression" -msgstr "ì¸ë±ìФ ì‹(expression)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" - -#: parser/parse_expr.c:1740 -msgid "cannot use subquery in index predicate" -msgstr "ì¸ë±ìФ 술어(predicate)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" - -#: parser/parse_expr.c:1743 -msgid "cannot use subquery in transform expression" -msgstr "transform ì‹(expression)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" - -#: parser/parse_expr.c:1746 -msgid "cannot use subquery in EXECUTE parameter" -msgstr "EXECUTE 매개 변수로 서브쿼리를 사용할 수 없습니다" - -#: parser/parse_expr.c:1749 -msgid "cannot use subquery in trigger WHEN condition" -msgstr "트리거 WHEN ì¡°ê±´ì ˆì—서는 서브쿼리를 사용할 수 없습니다" +msgid "materialized views must not use temporary tables or views" +msgstr "êµ¬ì²´í™”ëœ ë·°ëŠ” 임시 í…Œì´ë¸”ì´ë‚˜ 뷰를 사용할 수 없습니다" -#: parser/parse_expr.c:1803 +#: parser/analyze.c:2571 #, c-format -msgid "subquery must return only one column" -msgstr "subquery는 오로지 í•œê°œì˜ ì—´ë§Œì„ ëŒë ¤ 주어야 합니다." +msgid "materialized views may not be defined using bound parameters" +msgstr "" -#: parser/parse_expr.c:1887 +#: parser/analyze.c:2583 #, c-format -msgid "subquery has too many columns" -msgstr "subquery ì—ê°€ 너무 ë§Žì€ ì—´ì„ ê°€ì§‘ë‹ˆë‹¤" +msgid "materialized views cannot be UNLOGGED" +msgstr "êµ¬ì²´í™”ëœ ë·°ëŠ” UNLOGGED ì˜µì…˜ì„ ì‚¬ìš©í•  수 없습니다." -#: parser/parse_expr.c:1892 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2686 #, c-format -msgid "subquery has too few columns" -msgstr "subquery ì— ëª…ì‹œëœ ì—´ 수가 너무 ì ë‹¤" +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s ì ˆì€ DISTINCT 절과 함께 사용할 수 없습니다" -#: parser/parse_expr.c:1993 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2693 #, c-format -msgid "cannot determine type of empty array" -msgstr "빈 ë°°ì—´ì˜ ìžë£Œí˜•ì„ í™•ì¸í•  수 ì—†ìŒ" +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s ì ˆì€ GROUP BY 절과 함께 사용할 수 없습니다" -#: parser/parse_expr.c:1994 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2700 #, c-format -msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." -msgstr "ì›í•˜ëŠ” 형ì‹ìœ¼ë¡œ 명시ì ìœ¼ë¡œ 형변환하십시오(예: ARRAY[]::integer[])." +msgid "%s is not allowed with HAVING clause" +msgstr "%s ì ˆì€ HAVING 절과 함께 사용할 수 없습니다" -#: parser/parse_expr.c:2008 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2707 #, c-format -msgid "could not find element type for data type %s" -msgstr "%s ìžë£Œí˜•ì˜ ìš”ì†Œ ìžë£Œí˜•ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "%s is not allowed with aggregate functions" +msgstr "%s ì ˆì€ ì§‘ê³„ 함수와 함께 사용할 수 없습니다" -#: parser/parse_expr.c:2231 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2714 #, c-format -msgid "unnamed XML attribute value must be a column reference" -msgstr "ì´ë¦„ì´ ì§€ì •ë˜ì§€ ì•Šì€ XML ì†ì„± ê°’ì€ ì—´ 참조여야 함" +msgid "%s is not allowed with window functions" +msgstr "%s ì ˆì€ ìœˆë„ìš° 함수와 함께 사용할 수 없습니다" -#: parser/parse_expr.c:2232 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2721 #, c-format -msgid "unnamed XML element value must be a column reference" -msgstr "ì´ë¦„ì´ ì§€ì •ë˜ì§€ ì•Šì€ XML 요소 ê°’ì€ ì—´ 참조여야 함" +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s ì ˆì€ ëŒ€ìƒ ëª©ë¡ì—서 세트 반환 함수와 함께 사용할 수 없습니다." -#: parser/parse_expr.c:2247 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2800 #, c-format -msgid "XML attribute name \"%s\" appears more than once" -msgstr "\"%s\" XML ì†ì„± ì´ë¦„ì´ ì—¬ëŸ¬ 번 표시ë¨" +msgid "%s must specify unqualified relation names" +msgstr "%s ì ˆì—는 unqualified 릴레ì´ì…˜ ì´ë¦„ì„ ì§€ì •í•´ì•¼ 합니다." -#: parser/parse_expr.c:2354 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2831 #, c-format -msgid "cannot cast XMLSERIALIZE result to %s" -msgstr "XMLSERIALIZE 결과를 %s 형으로 바꿀 수 ì—†ìŒ" +msgid "%s cannot be applied to a join" +msgstr "%s ì ˆì€ ì¡°ì¸ì„ ì ìš©í•  수 없습니다." -#: parser/parse_expr.c:2650 parser/parse_expr.c:2846 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2840 #, c-format -msgid "unequal number of entries in row expressions" -msgstr "í–‰ 표현ì‹ì—서 항목 수가 ì¼ì¹˜í•˜ì§€ 않습니다" +msgid "%s cannot be applied to a function" +msgstr "%s ì ˆì€ í•¨ìˆ˜ì— ì ìš©í•  수 없습니다." -#: parser/parse_expr.c:2660 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2849 #, c-format -msgid "cannot compare rows of zero length" -msgstr "길ì´ê°€ ì˜(0)ì¸ í–‰ë“¤ì€ ë¹„êµí•  수 없습니다" +msgid "%s cannot be applied to a table function" +msgstr "%s ì ˆì€ í…Œì´ë¸” í•¨ìˆ˜ì— ì ìš©í•  수 없습니다." -#: parser/parse_expr.c:2685 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2867 #, c-format -msgid "row comparison operator must yield type boolean, not type %s" -msgstr "" -"í–‰ ë¹„êµ ì—°ì‚°ìžëŠ” booleaní˜•ì„ ë¦¬í„´í•´ì•¼í•©ë‹ˆë‹¤. %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" +msgid "%s cannot be applied to a WITH query" +msgstr "%s ì ˆì€ WITH ì¿¼ë¦¬ì— ì ìš©í•  수 ì—†ìŒ" -#: parser/parse_expr.c:2692 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2876 #, c-format -msgid "row comparison operator must not return a set" -msgstr "í–‰ ë¹„êµ ì—°ì‚°ìžëŠ” setì„ ë¦¬í„´í•  수 없습니다" +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s ì ˆì€ named tuplestoreì— ì ìš©í•  수 ì—†ìŒ" -#: parser/parse_expr.c:2751 parser/parse_expr.c:2792 +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2893 #, c-format -msgid "could not determine interpretation of row comparison operator %s" -msgstr "%s í–‰ ë¹„êµ ì—°ì‚°ìžì˜ êµ¬ë¬¸ì„ ë¶„ì„í•  수 없습니다" +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "\"%s\" 릴레ì´ì…˜ (ëŒ€ìƒ êµ¬ë¬¸: %s) ì´ FROM ì ˆ ë‚´ì— ì—†ìŠµë‹ˆë‹¤" -#: parser/parse_expr.c:2753 +#: parser/parse_agg.c:221 parser/parse_oper.c:222 #, c-format -msgid "" -"Row comparison operators must be associated with btree operator families." -msgstr "로우 ë¹„êµ ì—°ì‚°ìžë¥¼ btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì™€ 연결해야 함" +msgid "could not identify an ordering operator for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 순서 정하는 ì—°ì‚°ìžë¥¼ ì°¾ì„ ìˆ˜ 없습니다." -#: parser/parse_expr.c:2794 +#: parser/parse_agg.c:223 #, c-format -msgid "There are multiple equally-plausible candidates." -msgstr "여러 가지 등ì‹ë“¤ì´ 성립할 수 있는 ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤" +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "DISTINCT와 함께 작업하는 집계 ìž‘ì—…ì€ ê·¸ ìž…ë ¥ ìžë£Œê°€ ì •ë ¬ë  ìˆ˜ 있어야 합니다" -#: parser/parse_expr.c:2886 +#: parser/parse_agg.c:258 #, c-format -msgid "IS DISTINCT FROM requires = operator to yield boolean" -msgstr "" -"IS DISTINCT FROM ì ˆì—서 boolean ê°’ì„ ì–»ê¸° 위해서 = ì—°ì‚°ìžë¥¼ 필요로 합니다" +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING ì¸ìžë¡œëŠ” 32ê°œ ì´ë‚´ë¡œ 지정해야 합니다" -#: parser/parse_expr.c:3199 parser/parse_expr.c:3217 -#, c-format -msgid "operator precedence change: %s is now lower precedence than %s" -msgstr "ì—°ì‚°ìž ìš°ì„ ìˆœìœ„ 변경ë¨: %s ì—°ì‚°ìž ìš°ì„ ìˆœìœ„ê°€ %s 연산보다 낮습니다" +#: parser/parse_agg.c:361 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "JOIN 조건문ì—서는 집계 함수가 허용ë˜ì§€ 않습니다" -#: parser/parse_func.c:174 -#, c-format -msgid "argument name \"%s\" used more than once" -msgstr "\"%s\" ì´ë¦„ì˜ ë§¤ê°œ 변수가 여러 번 사용 ë¨" +#: parser/parse_agg.c:363 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "JOIN 조건문ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:185 -#, c-format -msgid "positional argument cannot follow named argument" +#: parser/parse_agg.c:375 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "집계 함수는 ìžì‹ ì˜ 쿼리 ìˆ˜ì¤€ì˜ FROM ì ˆì—서는 사용할 수 없습니다." + +#: parser/parse_agg.c:377 +msgid "grouping operations are not allowed in FROM clause of their own query level" msgstr "" -#: parser/parse_func.c:270 -#, c-format -msgid "%s(*) specified, but %s is not an aggregate function" -msgstr "%s(*) ê°€ 명시ë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다." +#: parser/parse_agg.c:382 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ í‘œí˜„ì‹ ë‚´ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:277 -#, c-format -msgid "DISTINCT specified, but %s is not an aggregate function" -msgstr "DISTINCT ê°€ 명시ë˜ì–´ 있는ë°, 그러나 ì´ %s 함수는 집계 함수가 아닙니다" +#: parser/parse_agg.c:384 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ í‘œí˜„ì‹ ë‚´ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:283 -#, c-format -msgid "WITHIN GROUP specified, but %s is not an aggregate function" -msgstr "WITHIN GROUP ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다" +#: parser/parse_agg.c:392 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "ì •ì±… 표현ì‹ì—서는 집계 함수 ì‚¬ìš©ì„ í—ˆìš©í•˜ì§€ 않습니다" -#: parser/parse_func.c:289 -#, c-format -msgid "ORDER BY specified, but %s is not an aggregate function" -msgstr "ORDER BY ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다." +#: parser/parse_agg.c:394 +msgid "grouping operations are not allowed in policy expressions" +msgstr "ì •ì±… 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:295 -#, c-format -msgid "FILTER specified, but %s is not an aggregate function" -msgstr "FILTER ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다" +#: parser/parse_agg.c:411 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "윈ë„ìš° RANGE 안ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:301 -#, c-format -msgid "" -"OVER specified, but %s is not a window function nor an aggregate function" -msgstr "OVER ì ˆì´ ì§€ì •ë˜ì—ˆëŠ”ë° %s 함수는 윈ë„ìš° 함수 ë˜ëŠ” 집계 함수가 아님" +#: parser/parse_agg.c:413 +msgid "grouping operations are not allowed in window RANGE" +msgstr "윈ë„ìš° RANGE 안ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:331 -#, c-format -msgid "WITHIN GROUP is required for ordered-set aggregate %s" -msgstr "순서가 있는 ì§‘ê³„í•¨ìˆ˜ì¸ %s ë•Œë¬¸ì— WITHIN GROUP ì ˆì´ í•„ìš”í•©ë‹ˆë‹¤" +#: parser/parse_agg.c:418 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "윈ë„ìš° ROWS 안ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:337 -#, c-format -msgid "OVER is not supported for ordered-set aggregate %s" -msgstr "OVER ì ˆì—서 ì •ë ¬ëœ ì„¸íŠ¸ 집계 %s 함수를 ì§€ì›í•˜ì§€ 않ìŒ" +#: parser/parse_agg.c:420 +msgid "grouping operations are not allowed in window ROWS" +msgstr "윈ë„ìš° ROWS 안ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:368 parser/parse_func.c:397 -#, c-format -msgid "" -"There is an ordered-set aggregate %s, but it requires %d direct arguments, " -"not %d." -msgstr "" +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "윈ë„ìš° GROUPS 안ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:422 -#, c-format -msgid "" -"To use the hypothetical-set aggregate %s, the number of hypothetical direct " -"arguments (here %d) must match the number of ordering columns (here %d)." -msgstr "" +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "윈ë„ìš° GROUPS 안ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:436 -#, c-format -msgid "" -"There is an ordered-set aggregate %s, but it requires at least %d direct " -"arguments." -msgstr "" +#: parser/parse_agg.c:461 +msgid "aggregate functions are not allowed in check constraints" +msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:455 -#, c-format -msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" -msgstr "" -"%s 함수는 순사가 있는 세트 집계함수가 아니여서 WITHIN GROUP ì ˆì„ ì‚¬ìš©í•  수 ì—†" -"습니다" +#: parser/parse_agg.c:463 +msgid "grouping operations are not allowed in check constraints" +msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:468 -#, c-format -msgid "window function %s requires an OVER clause" -msgstr "%s 윈ë„ìš° 함수 호출ì—는 OVER ì ˆì´ í•„ìš”í•¨" +#: parser/parse_agg.c:470 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT 표현ì‹ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:475 -#, c-format -msgid "window function %s cannot have WITHIN GROUP" -msgstr "%s 윈ë„ìš° 함수는 WITHIN GROUP ì ˆì„ ì‚¬ìš©í•  수 ì—†ìŒ" +#: parser/parse_agg.c:472 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "DEFAULT 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:496 -#, c-format -msgid "function %s is not unique" -msgstr "함수 %s 는 유ì¼ì„±ì„ 가지지 못합니다(not unique)" +#: parser/parse_agg.c:477 +msgid "aggregate functions are not allowed in index expressions" +msgstr "ì¸ë±ìФ 표현ì‹ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:499 -#, c-format -msgid "" -"Could not choose a best candidate function. You might need to add explicit " -"type casts." -msgstr "" -"ì œì¼ ì ë‹¹í•œ 함수를 ì„ íƒí•  수 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆ" -"습니다." +#: parser/parse_agg.c:479 +msgid "grouping operations are not allowed in index expressions" +msgstr "ì¸ë±ìФ 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:510 -#, c-format -msgid "" -"No aggregate function matches the given name and argument types. Perhaps you " -"misplaced ORDER BY; ORDER BY must appear after all regular arguments of the " -"aggregate." -msgstr "" -"ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ëŠ” 집계 함수가 없습니다. ORDER BY ì ˆì„ ë°”" -"른 ìœ„ì¹˜ì— ì“°ì§€ ì•Šì€ ê²ƒ 같습니다. ORDER BY ì ˆì€ ëª¨ë“  집계용 ì¸ìžë“¤ 맨 ë’¤ì— ìžˆ" -"어야 합니다." +#: parser/parse_agg.c:484 +msgid "aggregate functions are not allowed in index predicates" +msgstr "집계 함수는 함수 기반 ì¸ë±ìŠ¤ì˜ í•¨ìˆ˜ë¡œ 사용할 수 없습니다" -#: parser/parse_func.c:521 -#, c-format -msgid "" -"No function matches the given name and argument types. You might need to add " -"explicit type casts." -msgstr "" -"ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ëŠ” 함수가 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가" -"해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." +#: parser/parse_agg.c:486 +msgid "grouping operations are not allowed in index predicates" +msgstr "그룹핑 ìž‘ì—…ì€ í•¨ìˆ˜ 기반 ì¸ë±ìŠ¤ì˜ í•¨ìˆ˜ë¡œ 사용할 수 없습니다" -#: parser/parse_func.c:623 -#, c-format -msgid "VARIADIC argument must be an array" -msgstr "VARIADIC 매개 변수는 ë°°ì—´ì´ì–´ì•¼ 함" +#: parser/parse_agg.c:491 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "transform ì‹(expression)ì— ì§‘ê³„ 함수를 사용할 수 없습니다" -#: parser/parse_func.c:671 parser/parse_func.c:735 -#, c-format -msgid "%s(*) must be used to call a parameterless aggregate function" -msgstr "%s(*) 사용할 때는 ì´ í•¨ìˆ˜ê°€ 매개 변수 없는 집계 함수여야 합니다" +#: parser/parse_agg.c:493 +msgid "grouping operations are not allowed in transform expressions" +msgstr "transform ì‹(expression)ì— ê·¸ë£¹í•‘ 작업를 사용할 수 없습니다" -#: parser/parse_func.c:678 -#, c-format -msgid "aggregates cannot return sets" -msgstr "집계 함수는 세트를 반환할 수 ì—†ìŒ" +#: parser/parse_agg.c:498 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "EXECUTE 매개 변수로 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:693 -#, c-format -msgid "aggregates cannot use named arguments" -msgstr "집계 함수는 ì¸ìž ì´ë¦„ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +#: parser/parse_agg.c:500 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "EXECUTE 매개 변수로 그룹핑 ìž‘ì—…ì„ ì‚¬ìš©í•  수 없습니다" -#: parser/parse_func.c:725 -#, c-format -msgid "DISTINCT is not implemented for window functions" -msgstr "윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ DISTINCTê°€ 구현ë˜ì§€ 않ìŒ" +#: parser/parse_agg.c:505 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì— ì§‘ê³„ 함수가 허용ë˜ì§€ 않습니다" -#: parser/parse_func.c:745 -#, c-format -msgid "aggregate ORDER BY is not implemented for window functions" -msgstr "윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ 집계용 ORDER BYê°€ 구현ë˜ì§€ 않ìŒ" +#: parser/parse_agg.c:507 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì— ê·¸ë£¹í•‘ ìž‘ì—…ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:754 -#, c-format -msgid "FILTER is not implemented for non-aggregate window functions" -msgstr "비집계 윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ FILTERê°€ 구현ë˜ì§€ 않ìŒ" +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "파티션 키 표현ì‹ì—서는 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:760 -#, c-format -msgid "window functions cannot return sets" -msgstr "윈ë„ìš° 함수는 세트를 반환할 수 ì—†ìŒ" +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "파티션 키 표현ì‹ì—서는 그룹핑 ì—°ì‚°ì´ í—ˆìš©ë˜ì§€ 않습니다" -#: parser/parse_func.c:2010 -#, c-format -msgid "aggregate %s(*) does not exist" -msgstr "%s(*) 집계 함수 ì—†ìŒ" +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "CALL 매개 변수로 집계 함수를 사용할 수 없습니다" -#: parser/parse_func.c:2015 -#, c-format -msgid "aggregate %s does not exist" -msgstr "%s 집계 함수 ì—†ìŒ" +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALL 매개 변수로 그룹핑 ì—°ì‚°ì„ ì‚¬ìš©í•  수 없습니다" -#: parser/parse_func.c:2034 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:545 parser/parse_clause.c:1817 #, c-format -msgid "function %s is not an aggregate" -msgstr "%s 함수는 집계 함수가 아닙니다" +msgid "aggregate functions are not allowed in %s" +msgstr "집계 함수는 %s ì ˆì—서 사용할 수 없습니다." -#: parser/parse_node.c:84 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:548 #, c-format -msgid "target lists can have at most %d entries" -msgstr "ëŒ€ìƒ ëª©ë¡ì€ 최대 %d ê°œì˜ í•­ëª©ì„ ì§€ì •í•  수 있습니다" +msgid "grouping operations are not allowed in %s" +msgstr "그룹핑 ìž‘ì—…ì€ %s ì ˆì—서 사용할 수 없습니다." -#: parser/parse_node.c:253 +#: parser/parse_agg.c:656 #, c-format -msgid "cannot subscript type %s because it is not an array" +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "" -"ìžë£Œí˜• %s 는 ë°°ì—´ì´ ì•„ë‹ˆê¸° ë•Œë¬¸ì— ë°°ì—´ 하위 스í¬ë¦½íŠ¸ë¥¼ 기술할 수 없습니다." -#: parser/parse_node.c:356 parser/parse_node.c:393 +#: parser/parse_agg.c:735 #, c-format -msgid "array subscript must have type integer" -msgstr "ë°°ì—´ 하위 스í¬ë¦½íŠ¸ëŠ” 반드시 정수형ì´ì–´ì•¼ 합니다." +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "집계 함수 í˜¸ì¶œì€ ì§‘í•© 반환 함수 í˜¸ì¶œì„ í¬í•¨í•  수 ì—†ìŒ" -#: parser/parse_node.c:424 +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 +#: parser/parse_func.c:866 #, c-format -msgid "array assignment requires type %s but expression is of type %s" -msgstr "ë°°ì—´í• ë‹¹ì€ ìžë£Œí˜• %s ê°€ 필요하지만, 현재 표현ì‹ì´ %s ìžë£Œí˜•입니다" +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "ì§‘í•© 반환 함수를 LATERAL FROM 쪽으로 옮겨서 구현할 ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: parser/parse_oper.c:125 parser/parse_oper.c:722 utils/adt/regproc.c:583 -#: utils/adt/regproc.c:603 utils/adt/regproc.c:787 +#: parser/parse_agg.c:741 #, c-format -msgid "operator does not exist: %s" -msgstr "ì—°ì‚°ìž ì—†ìŒ: %s" +msgid "aggregate function calls cannot contain window function calls" +msgstr "집계 함수 í˜¸ì¶œì€ ìœˆë„ìš° 함수 í˜¸ì¶œì„ í¬í•¨í•  수 ì—†ìŒ" -#: parser/parse_oper.c:222 -#, c-format -msgid "Use an explicit ordering operator or modify the query." -msgstr "" -"명시ì ìœ¼ë¡œ 순차연산ìž(ordering operator) 를 사용하ë˜ì§€, ë˜ëŠ” query 를 수정하" -"ë„ë¡ í•˜ì„¸ìš”." +#: parser/parse_agg.c:820 +msgid "window functions are not allowed in JOIN conditions" +msgstr "윈ë„ìš° 함수는 JOIN ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: parser/parse_oper.c:226 utils/adt/array_userfuncs.c:794 -#: utils/adt/array_userfuncs.c:933 utils/adt/arrayfuncs.c:3639 -#: utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6039 -#: utils/adt/rowtypes.c:1167 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "" -"%s ìžë£Œí˜•ì—서 사용할 ë™ë“± ì—°ì‚°ìž(equality operator)를 ì°¾ì„ ìˆ˜ 없습니다." +#: parser/parse_agg.c:827 +msgid "window functions are not allowed in functions in FROM" +msgstr "윈ë„ìš° 함수는 FROM ì ˆì— ìžˆëŠ” 함수로 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:478 -#, c-format -msgid "operator requires run-time type coercion: %s" -msgstr "ì´ ì—°ì‚°ìžëŠ” ì‹¤í–‰ì‹œì— í˜• ê°•ì œì „í™”ì´ í•„ìš”í•©ë‹ˆë‹¤: %s" +#: parser/parse_agg.c:833 +msgid "window functions are not allowed in policy expressions" +msgstr "윈ë„ìš° 함수는 ì •ì±… ì‹ì— 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:714 -#, c-format -msgid "operator is not unique: %s" -msgstr "ì—°ì‚°ìžê°€ 고유하지 않습니다: %s" +#: parser/parse_agg.c:846 +msgid "window functions are not allowed in window definitions" +msgstr "윈ë„ìš° 함수는 윈ë„ìš° 함수 ì •ì˜ì— 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:716 -#, c-format -msgid "" -"Could not choose a best candidate operator. You might need to add explicit " -"type casts." -msgstr "" -"가장 ì ë‹¹í•œ ì—°ì‚°ìžë¥¼ ì„ íƒí•  수 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ " -"있습니다." +#: parser/parse_agg.c:878 +msgid "window functions are not allowed in check constraints" +msgstr "윈ë„ìš° 함수는 check ì œì•½ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: parser/parse_oper.c:724 -#, c-format -msgid "" -"No operator matches the given name and argument type(s). You might need to " -"add explicit type casts." -msgstr "" -"ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž 형ì‹ê³¼ ì¼ì¹˜í•˜ëŠ” ì—°ì‚°ìžê°€ 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가" -"해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." +#: parser/parse_agg.c:882 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "윈ë„ìš° 함수는 DEFAULT ì‹ì—서 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:783 parser/parse_oper.c:897 -#, c-format -msgid "operator is only a shell: %s" -msgstr "ì—°ì‚°ìžëŠ” ì…¸ì¼ ë¿ìž„: %s" +#: parser/parse_agg.c:885 +msgid "window functions are not allowed in index expressions" +msgstr "윈ë„ìš° 함수는 ì¸ë±ìФ ì‹ì—서 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:885 -#, c-format -msgid "op ANY/ALL (array) requires array on right side" -msgstr "op ANY/ALL (array) 는 ìš°ì¸¡ì— ë°°ì—´ì´ ìžˆì–´ì•¼ 합니다." +#: parser/parse_agg.c:888 +msgid "window functions are not allowed in index predicates" +msgstr "윈ë„ìš° 함수는 함수 기반 ì¸ë±ìФì—서 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:927 -#, c-format -msgid "op ANY/ALL (array) requires operator to yield boolean" -msgstr "op ANY/ALL (array) 는 boolean ì„ ì–»ê¸° 위한 ì—°ì‚°ìžê°€ 필요합니다." +#: parser/parse_agg.c:891 +msgid "window functions are not allowed in transform expressions" +msgstr "윈ë„ìš° 함수는 transform ì‹ì—서 사용할 수 ì—†ìŒ" -#: parser/parse_oper.c:932 -#, c-format -msgid "op ANY/ALL (array) requires operator not to return a set" -msgstr "op ANY/ALL (array) 는 set ì„ return 하지 않는 ì—°ì‚°ìžê°€ 요구 ë©ë‹ˆë‹¤." +#: parser/parse_agg.c:894 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "윈ë„ìš° 함수는 EXECUTE 매개 변수 설정 값으로 사용할 수 ì—†ìŒ" -#: parser/parse_param.c:216 +#: parser/parse_agg.c:897 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "윈ë„ìš° 함수는 íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "윈ë„ìš° 함수는 파티션 키 표현ì‹ì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "윈ë„ìš° 함수는 CALL 매개 변수 설정 값으로 사용할 수 ì—†ìŒ" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:923 parser/parse_clause.c:1826 #, c-format -msgid "inconsistent types deduced for parameter $%d" -msgstr "inconsistent types deduced for parameter $%d" +msgid "window functions are not allowed in %s" +msgstr "%s 안ì—서는 윈ë„ìš° 함수를 사용할 수 ì—†ìŒ" -#: parser/parse_relation.c:175 +#: parser/parse_agg.c:957 parser/parse_clause.c:2662 #, c-format -msgid "table reference \"%s\" is ambiguous" -msgstr "í…Œì´ë¸” 참조 \"%s\" ê°€ 명확하지 않습니다 (ambiguous)." +msgid "window \"%s\" does not exist" +msgstr "\"%s\" 윈ë„ìš° 함수가 ì—†ìŒ" -#: parser/parse_relation.c:219 +#: parser/parse_agg.c:1042 #, c-format -msgid "table reference %u is ambiguous" -msgstr "í…Œì´ë¸” 참조 %u ê°€ 명확하지 않습니다 (ambiguous)." +msgid "too many grouping sets present (maximum 4096)" +msgstr "너무 ë§Žì€ ê·¸ë£¹í•‘ 세트가 있습니다 (최대값 4096)" -#: parser/parse_relation.c:398 +#: parser/parse_agg.c:1191 #, c-format -msgid "table name \"%s\" specified more than once" -msgstr "í…Œì´ë¸” ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 명시ë˜ì–´ 있습니다." +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "집계 함수는 재귀 ì¿¼ë¦¬ì˜ ìž¬ê·€ ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: parser/parse_relation.c:425 parser/parse_relation.c:3116 +#: parser/parse_agg.c:1384 #, c-format -msgid "invalid reference to FROM-clause entry for table \"%s\"" -msgstr "\"%s\" í…Œì´ë¸”ì„ ì‚¬ìš©í•˜ëŠ” FROM ì ˆì— ëŒ€í•œ 참조가 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "column \"%s.%s\" 는 반드시 GROUP BY ì ˆë‚´ì— ìžˆì–´ì•¼ 하ë˜ì§€ ë˜ëŠ” 집계 함수 ë‚´ì—서 사용ë˜ì–´ì ¸ì•¼ 한다" -#: parser/parse_relation.c:428 parser/parse_relation.c:3121 +#: parser/parse_agg.c:1387 #, c-format -msgid "" -"There is an entry for table \"%s\", but it cannot be referenced from this " -"part of the query." +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "" -"\"%s\" í…Œì´ë¸”ì— ëŒ€í•œ í•­ëª©ì´ ìžˆì§€ë§Œ ì´ ì¿¼ë¦¬ 부분ì—서 참조할 수 없습니다." -#: parser/parse_relation.c:430 +#: parser/parse_agg.c:1392 #, c-format -msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "subquery ê°€ outer query ì—서 그룹화 ë˜ì§€ ì•Šì€ ì—´ì¸ \"%s.%s\"를 사용합니다" + +#: parser/parse_agg.c:1556 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "" -#: parser/parse_relation.c:706 +#: parser/parse_clause.c:199 #, c-format -msgid "system column \"%s\" reference in check constraint is invalid" -msgstr "제약 ì¡°ê±´ì—서 참조하는 \"%s\" 시스템 ì¹¼ëŸ¼ì´ ì—†ìŒ" +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "\"%s\" 릴레ì´ì…˜ì€ ìžë£Œ 변경 êµ¬ë¬¸ì˜ ëŒ€ìƒì´ ë  ìˆ˜ ì—†ìŒ" -#: parser/parse_relation.c:1066 parser/parse_relation.c:1346 -#: parser/parse_relation.c:1848 +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 #, c-format -msgid "table \"%s\" has %d columns available but %d columns specified" -msgstr "í…Œì´ë¸” \"%s\" ì—는 %d ê°œì˜ ì—´ì´ ìžˆëŠ”ë°, %d ê°œì˜ ì—´ë§Œì´ ëª…ì‹œë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "set-returning functions must appear at top level of FROM" +msgstr "" -#: parser/parse_relation.c:1153 +#: parser/parse_clause.c:655 #, c-format -msgid "" -"There is a WITH item named \"%s\", but it cannot be referenced from this " -"part of the query." -msgstr "\"%s\"(ì´)ë¼ëŠ” WITH í•­ëª©ì´ ìžˆì§€ë§Œ ì´ ì¿¼ë¦¬ 부분ì—서 참조할 수 없습니다." +msgid "multiple column definition lists are not allowed for the same function" +msgstr "다중 칼럼 ì •ì˜ ëª©ë¡ì€ ê°™ì€ í•¨ìˆ˜ìš©ìœ¼ë¡œ 허용하지 않ìŒ" -#: parser/parse_relation.c:1155 +#: parser/parse_clause.c:688 #, c-format -msgid "" -"Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "" -"WITH RECURSIVE를 사용하거나 WITH í•­ëª©ì˜ ìˆœì„œë¥¼ 변경하여 ì •ë°©í–¥ 참조를 제거하" -"십시오." -#: parser/parse_relation.c:1466 +#: parser/parse_clause.c:689 #, c-format -msgid "" -"a column definition list is only allowed for functions returning \"record\"" +msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "" -"ì—´ ì •ì˜ ë¦¬ìŠ¤íŠ¸ (column definition list) 는 오로지 \"record\" 를 리턴하는 함" -"수 ë‚´ì—서만 허용ë©ë‹ˆë‹¤." -#: parser/parse_relation.c:1475 +#: parser/parse_clause.c:695 #, c-format -msgid "a column definition list is required for functions returning \"record\"" +msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "" -"ì—´ ì •ì˜ ë¦¬ìŠ¤íŠ¸(column definition list)는 \"record\" 를 리턴하는 함수를 í•„ìš”" -"로 합니다" -#: parser/parse_relation.c:1554 +#: parser/parse_clause.c:696 #, c-format -msgid "function \"%s\" in FROM has unsupported return type %s" +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "" -"FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ \"%s\" ì— ì§€ì›ë˜ì§€ 않는 return ìžë£Œí˜• %s ì´ ìžˆìŠµë‹ˆë‹¤." -#: parser/parse_relation.c:1676 +#: parser/parse_clause.c:703 #, c-format -msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" -msgstr "" -"VALUES ë’¤ì— ì˜¤ëŠ” \"%s\" 구문ì—는 %dê°œì˜ ì—´ì´ ìžˆëŠ”ë°, 지정한 ì—´ì€ %dê°œ 입니다" +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY êµ¬ë¬¸ì€ ì¹¼ëŸ¼ ì •ì˜ ëª©ë¡ê³¼ 함께 쓸 수 없습니다." -#: parser/parse_relation.c:1731 +#: parser/parse_clause.c:704 #, c-format -msgid "joins can have at most %d columns" -msgstr "ì¡°ì¸ì—는 최대 %dê°œì˜ ì¹¼ëŸ¼ì„ í¬í•¨í•  수 있ìŒ" +msgid "Put the column definition list inside ROWS FROM()." +msgstr "ROWS FROM() ì•ˆì— ì¹¼ëŸ¼ ì •ì˜ ëª©ë¡ì„ 넣으세요." -#: parser/parse_relation.c:1821 +#: parser/parse_clause.c:807 #, c-format -msgid "WITH query \"%s\" does not have a RETURNING clause" +msgid "only one FOR ORDINALITY column is allowed" msgstr "" -#: parser/parse_relation.c:2738 parser/parse_relation.c:2900 +#: parser/parse_clause.c:868 #, c-format -msgid "column %d of relation \"%s\" does not exist" -msgstr "%d번째 ì—´ì´ ì—†ìŠµë‹ˆë‹¤. 해당 릴레ì´ì…˜: \"%s\"" +msgid "column name \"%s\" is not unique" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ìœ ì¼ì„±ì„ 가지지 못합니다(not unique)" -#: parser/parse_relation.c:3119 +#: parser/parse_clause.c:910 #, c-format -msgid "Perhaps you meant to reference the table alias \"%s\"." -msgstr "ì•„ \"%s\" alias를 참조해야 í•  것 같습니다." +msgid "namespace name \"%s\" is not unique" +msgstr "\"%s\" 네임스페ì´ìŠ¤ëŠ” 유ì¼ì„±ì„ 가지지 못합니다(not unique)" -#: parser/parse_relation.c:3127 +#: parser/parse_clause.c:920 #, c-format -msgid "missing FROM-clause entry for table \"%s\"" -msgstr "í…Œì´ë¸” \"%s\"ì— FROM ì ˆì´ ë¹ ì ¸ 있습니다." +msgid "only one default namespace is allowed" +msgstr "기본 네임스페ì´ìŠ¤ëŠ” 하나만 허용합니다" -#: parser/parse_relation.c:3179 +#: parser/parse_clause.c:981 #, c-format -msgid "Perhaps you meant to reference the column \"%s.%s\"." -msgstr "아마 \"%s.%s\" ì¹¼ëŸ¼ì„ ì°¸ì¡°í•˜ëŠ” 것 같습니다." +msgid "tablesample method %s does not exist" +msgstr "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²•ì´ ì—†ìŠµë‹ˆë‹¤" -#: parser/parse_relation.c:3181 +#: parser/parse_clause.c:1003 #, c-format -msgid "" -"There is a column named \"%s\" in table \"%s\", but it cannot be referenced " -"from this part of the query." -msgstr "" -"\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì´ \"%s\" í…Œì´ë¸”ì— ìžˆì§€ë§Œ, ì´ ì¿¼ë¦¬ì˜ ì´ ë¶€ë¶„ì—서는 ì°¸ì¡°ë  " -"수 없습니다." +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²• %dê°œ ì¸ìžë¥¼ 지정해야함, (현재 %dê°œ)" -#: parser/parse_relation.c:3198 +#: parser/parse_clause.c:1037 #, c-format -msgid "" -"Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." -msgstr "아마 \"%s.%s\" 칼럼ì´ë‚˜ \"%s.%s\" ì¹¼ëŸ¼ì„ ì°¸ì¡°í•˜ëŠ” 것 같습니다." +msgid "tablesample method %s does not support REPEATABLE" +msgstr "\"%s\" í…Œì´ë¸” ìƒ˜í”Œë§ ë°©ë²•ì€ REPEATABLE ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: parser/parse_target.c:432 parser/parse_target.c:724 +#: parser/parse_clause.c:1207 #, c-format -msgid "cannot assign to system column \"%s\"" -msgstr "시스템 ì—´ \"%s\"ì— í• ë‹¹í•  수 없습니다." +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE ì ˆì€ í…Œì´ë¸”ê³¼ êµ¬ì²´í™”ëœ ë·°ì—서만 사용할 수 있습니다" -#: parser/parse_target.c:460 +#: parser/parse_clause.c:1377 #, c-format -msgid "cannot set an array element to DEFAULT" -msgstr "ë°°ì—´ 요소를 DEFAULT 로 설정할 수 없습니다." +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "USING ì ˆ ë‚´ì— ì—´ ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 사용ë˜ì—ˆìŠµë‹ˆë‹¤" -#: parser/parse_target.c:465 +#: parser/parse_clause.c:1392 #, c-format -msgid "cannot set a subfield to DEFAULT" -msgstr "하위필드를 DEFAULT로 설정할 수 없습니다." +msgid "common column name \"%s\" appears more than once in left table" +msgstr "left table ë‚´ì— common column ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 사용ë˜ì—ˆë‹¤" -#: parser/parse_target.c:534 +#: parser/parse_clause.c:1401 #, c-format -msgid "column \"%s\" is of type %s but expression is of type %s" -msgstr "ì—´ \"%s\"ì€(는) %s ìžë£Œí˜•ì¸ë° 표현ì‹ì€ %s ìžë£Œí˜•입니다." +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "USING ì¡°ê±´ì ˆì—서 지정한 \"%s\" ì¹¼ëŸ¼ì´ ì™¼ìª½ í…Œì´ë¸”ì— ì—†ìŒ" -#: parser/parse_target.c:708 +#: parser/parse_clause.c:1415 #, c-format -msgid "" -"cannot assign to field \"%s\" of column \"%s\" because its type %s is not a " -"composite type" -msgstr "" -"\"%s\" 필드 (ëŒ€ìƒ ì—´ \"%s\")를 지정할 수 ì—†ìŒ, %s ìžë£Œí˜•ì€ ë³µí•©ìžë£Œí˜•ì´ ì•„ë‹ˆ" -"기 때문" +msgid "common column name \"%s\" appears more than once in right table" +msgstr "common column name \"%s\"ê°€ right table ì— í•œë²ˆ ì´ìƒ 사용ë˜ì—ˆë‹¤" -#: parser/parse_target.c:717 +#: parser/parse_clause.c:1424 #, c-format -msgid "" -"cannot assign to field \"%s\" of column \"%s\" because there is no such " -"column in data type %s" -msgstr "" -"\"%s\" 필드 (ëŒ€ìƒ ì—´ \"%s\")를 지정할 수 ì—†ìŒ, %s ìžë£Œí˜•ì—서 그런 ì—´ì„ ì°¾ì„ " -"수 ì—†ìŒ" +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "USING ì¡°ê±´ì ˆì—서 지정한 \"%s\" ì¹¼ëŸ¼ì´ ì˜¤ë¥¸ìª½ í…Œì´ë¸”ì— ì—†ìŒ" -#: parser/parse_target.c:784 +#: parser/parse_clause.c:1478 #, c-format -msgid "" -"array assignment to \"%s\" requires type %s but expression is of type %s" -msgstr "" -"\"%s\" ì—´ì— ì‚¬ìš©ëœ ìžë£Œí˜•ì€ %s ê°€ 필요하지만, 현재 표현ì‹ì´ %s ìžë£Œí˜•입니다" +msgid "column alias list for \"%s\" has too many entries" +msgstr " \"%s\" 를 위한 ì—´ alias list ì— ë„ˆë¬´ ë§Žì€ entry ê°€ í¬í•¨ë˜ì–´ 있다" -#: parser/parse_target.c:794 +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1787 #, c-format -msgid "subfield \"%s\" is of type %s but expression is of type %s" -msgstr "하위필드 \"%s\" 는 %s ìžë£Œí˜•ì¸ë° 표현ì‹ì€ %s ìžë£Œí˜•입니다." +msgid "argument of %s must not contain variables" +msgstr "%s ì˜ ì¸ìžë¡œ 변수를 í¬í•¨í•  수 없습니다." -#: parser/parse_target.c:1210 +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1952 #, c-format -msgid "SELECT * with no tables specified is not valid" -msgstr "í…Œì´ë¸”ì´ ëª…ì‹œë˜ì§€ ì•Šì€ SELECT * êµ¬ë¬¸ì€ ìœ íš¨í•˜ì§€ 않습니다." +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\" ê°€ 명확하지 ì•Šì€ í‘œí˜„ìž…ë‹ˆë‹¤." -#: parser/parse_type.c:83 +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1981 #, c-format -msgid "improper %%TYPE reference (too few dotted names): %s" -msgstr "" -"ì ì ˆí•˜ì§€ ì•Šì€ %%TYPE reference 입니다 (dotted name ì´ ë„ˆë¬´ ì ìŠµë‹ˆë‹¤): %s" +msgid "non-integer constant in %s" +msgstr "정수가 아닌 ìƒìˆ˜ê°€ %s ì— í¬í•¨ë˜ì–´ 있습니다" -#: parser/parse_type.c:105 +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2003 #, c-format -msgid "improper %%TYPE reference (too many dotted names): %s" -msgstr "" -"ì ì ˆí•˜ì§€ ì•Šì€ %%TYPE reference 입니다 (dotted name ì´ ë„ˆë¬´ 많습니다): %s" +msgid "%s position %d is not in select list" +msgstr "%s position %d ê°€ select list ì— í¬í•¨ë˜ì–´ 있지 않습니다" -#: parser/parse_type.c:140 +#: parser/parse_clause.c:2444 #, c-format -msgid "type reference %s converted to %s" -msgstr "ype reference %s ê°€ %s 로 변환ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "CUBE is limited to 12 elements" +msgstr "CUBE ì¸ìžë¡œëŠ” 12ê°œ ì´í•˜ì˜ ì¸ìžë§Œ 허용합니다" -#: parser/parse_type.c:261 parser/parse_type.c:805 utils/cache/typcache.c:239 +#: parser/parse_clause.c:2650 #, c-format -msgid "type \"%s\" is only a shell" -msgstr "ìžë£Œí˜• \"%s\" 는 오로지 shell ì—ë§Œ 있습니다. " +msgid "window \"%s\" is already defined" +msgstr "\"%s\" ì´ë¦„ì˜ ìœˆë„ìš° 함수가 ì´ë¯¸ ì •ì˜ë¨" -#: parser/parse_type.c:346 +#: parser/parse_clause.c:2711 #, c-format -msgid "type modifier is not allowed for type \"%s\"" -msgstr "\"%s\" 형ì‹ì—는 í˜•ì‹ í•œì •ìžë¥¼ 사용할 수 ì—†ìŒ" +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "\"%s\" ì°½ì˜ PARTITION BY ì ˆì„ ìž¬ì •ì˜í•  수 ì—†ìŒ" -#: parser/parse_type.c:388 +#: parser/parse_clause.c:2723 #, c-format -msgid "type modifiers must be simple constants or identifiers" -msgstr "ìžë£Œí˜• 한정ìžëŠ” 단순 ìƒìˆ˜ ë˜ëŠ” ì‹ë³„ìžì—¬ì•¼ 함" +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "\"%s\" ì°½ì˜ ORDER BY ì ˆì„ ìž¬ì •ì˜í•  수 ì—†ìŒ" -#: parser/parse_type.c:671 parser/parse_type.c:770 +#: parser/parse_clause.c:2753 parser/parse_clause.c:2759 #, c-format -msgid "invalid type name \"%s\"" -msgstr "\"%s\" ìžë£Œí˜• ì´ë¦„ì€ ìœ íš¨í•˜ì§€ ì•Šì€ ìžë£Œí˜•입니다." +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "프래임 ì ˆì´ ìžˆì–´, \"%s\" 윈ë„우를 복사할 수 ì—†ìŒ." -#: parser/parse_utilcmd.c:384 +#: parser/parse_clause.c:2761 #, c-format -msgid "array of serial is not implemented" -msgstr "serial ë°°ì—´ì´ êµ¬í˜„ë˜ì§€ 않ìŒ" +msgid "Omit the parentheses in this OVER clause." +msgstr "OVER ì ˆì— ê´„í˜¸ê°€ 빠졌ìŒ" -#: parser/parse_utilcmd.c:432 +#: parser/parse_clause.c:2781 #, c-format -msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" msgstr "" -"%s 명령으로 \"%s\" 시퀀스가 ìžë™ìœ¼ë¡œ ë§Œë“¤ì–´ì§ (\"%s.%s\" serial ì—´ 때문)" -#: parser/parse_utilcmd.c:526 parser/parse_utilcmd.c:538 +#: parser/parse_clause.c:2804 #, c-format -msgid "" -"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" -msgstr "NULL/NOT NULL ì„ ì–¸ì´ ì„œë¡œ ì¶©ëŒí•©ë‹ˆë‹¤ : column \"%s\" of table \"%s\"" +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS 모드는 ORDER BY êµ¬ë¬¸ì´ í•„ìš”í•¨" -#: parser/parse_utilcmd.c:550 +#: parser/parse_clause.c:2874 #, c-format -msgid "multiple default values specified for column \"%s\" of table \"%s\"" -msgstr "\"%s\" ì—´(\"%s\" í…Œì´ë¸”)ì— ëŒ€í•´ 여러 ê°œì˜ ê¸°ë³¸ ê°’ì´ ì§€ì •ë¨" +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "DISTINCT, ORDER BY 표현ì‹ì„ 집계 함수와 쓸 때는, 반드시 select list ì— ë‚˜íƒ€ë‚˜ì•¼ë§Œ 합니다" -#: parser/parse_utilcmd.c:567 parser/parse_utilcmd.c:658 +#: parser/parse_clause.c:2875 #, c-format -msgid "primary key constraints are not supported on foreign tables" -msgstr "기본키 제약 ì¡°ê±´ì„ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "SELECT DISTINCT, ORDER BY 표현ì‹ì„ 위해서 반드시 select list ì— ë‚˜íƒ€ë‚˜ì•¼ë§Œ 합니다" -#: parser/parse_utilcmd.c:576 parser/parse_utilcmd.c:668 +#: parser/parse_clause.c:2907 #, c-format -msgid "unique constraints are not supported on foreign tables" -msgstr "ìœ ë‹ˆí¬ ì œì•½ ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "DISTINCT 예약어로 집계를 í•  경우 ì ì–´ë„ í•˜ë‚˜ì˜ ì¸ìžëŠ” 있어야 함" -#: parser/parse_utilcmd.c:593 parser/parse_utilcmd.c:692 +#: parser/parse_clause.c:2908 #, c-format -msgid "foreign key constraints are not supported on foreign tables" -msgstr "참조키 제약 ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT êµ¬ë¬¸ì€ ì ì–´ë„ 한 ê°œ ì´ìƒì˜ ì¹¼ëŸ¼ì´ ìžˆì–´ì•¼ 합니다" -#: parser/parse_utilcmd.c:678 +#: parser/parse_clause.c:2974 parser/parse_clause.c:3006 #, c-format -msgid "exclusion constraints are not supported on foreign tables" -msgstr "제외 제약 ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "SELECT DISTINCT ON 표현ì‹ì€ 반드시 초기 ORDER BY 표현ì‹ê³¼ ì¼ì¹˜í•˜ì—¬ì•¼ 한다" -#: parser/parse_utilcmd.c:742 +#: parser/parse_clause.c:3084 #, c-format -msgid "LIKE is not supported for creating foreign tables" -msgstr "외부 í…Œì´ë¸”ì„ ë§Œë“¤ 때는 LIKE ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC 예약어는 ON CONFLICT 절과 함께 사용할 수 없습니다." -#: parser/parse_utilcmd.c:1275 parser/parse_utilcmd.c:1351 +#: parser/parse_clause.c:3090 #, c-format -msgid "Index \"%s\" contains a whole-row table reference." -msgstr "" +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST ì ˆì€ ON CONFLICT 절과 함께 사용할 수 없습니다." -#: parser/parse_utilcmd.c:1621 +#: parser/parse_clause.c:3169 #, c-format -msgid "cannot use an existing index in CREATE TABLE" +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "" -#: parser/parse_utilcmd.c:1641 +#: parser/parse_clause.c:3170 #, c-format -msgid "index \"%s\" is already associated with a constraint" -msgstr "" +msgid "For example, ON CONFLICT (column_name)." +msgstr "사용예, ON CONFLICT (칼럼ì´ë¦„)." -#: parser/parse_utilcmd.c:1649 +#: parser/parse_clause.c:3181 #, c-format -msgid "index \"%s\" does not belong to table \"%s\"" -msgstr "\"%s\" ì¸ë±ìŠ¤ê°€ \"%s\" í…Œì´ë¸”ìš©ì´ ì•„ë‹˜" +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT ì ˆì€ ì‹œìŠ¤í…œ 카탈로그 í…Œì´ë¸”ì—서는 사용할 수 없습니다" -#: parser/parse_utilcmd.c:1656 +#: parser/parse_clause.c:3189 #, c-format -msgid "index \"%s\" is not valid" -msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 사용가능 ìƒíƒœê°€ 아님" +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "\"%s\" í…Œì´ë¸”ì—는 ON CONFLICT ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 없습니다. ì´ í…Œì´ë¸”ì€ ì¹´íƒˆë¡œê·¸ í…Œì´ë¸”로 사용ë©ë‹ˆë‹¤." -#: parser/parse_utilcmd.c:1662 +#: parser/parse_clause.c:3332 #, c-format -msgid "\"%s\" is not a unique index" -msgstr "\"%s\" ê°ì²´ëŠ” ìœ ë‹ˆí¬ ì¸ë±ìŠ¤ê°€ 아닙니다" +msgid "operator %s is not a valid ordering operator" +msgstr "%s ì—°ì‚°ìžëŠ” 유효한 순서 지정 ì—°ì‚°ìžê°€ 아님" -#: parser/parse_utilcmd.c:1663 parser/parse_utilcmd.c:1670 -#: parser/parse_utilcmd.c:1677 parser/parse_utilcmd.c:1747 +#: parser/parse_clause.c:3334 #, c-format -msgid "Cannot create a primary key or unique constraint using such an index." -msgstr "" +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "순서 지정 ì—°ì‚°ìžëŠ” btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì˜ \"<\" or \">\" 멤버여야 합니다." -#: parser/parse_utilcmd.c:1669 +#: parser/parse_clause.c:3645 #, c-format -msgid "index \"%s\" contains expressions" -msgstr "\"%s\" ì¸ë±ìŠ¤ì— í‘œí˜„ì‹ì´ í¬í•¨ë˜ì–´ 있ìŒ" +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" -#: parser/parse_utilcmd.c:1676 +#: parser/parse_clause.c:3651 #, c-format -msgid "\"%s\" is a partial index" -msgstr "\"%s\" ê°ì²´ëŠ” 부분 ì¸ë±ìŠ¤ìž„" +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "" -#: parser/parse_utilcmd.c:1688 +#: parser/parse_clause.c:3654 #, c-format -msgid "\"%s\" is a deferrable index" -msgstr "\"%s\" ê°ì²´ëŠ” 지연가능한 ì¸ë±ìŠ¤ìž„" +msgid "Cast the offset value to an appropriate type." +msgstr "" -#: parser/parse_utilcmd.c:1689 +#: parser/parse_clause.c:3659 #, c-format -msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" msgstr "" -#: parser/parse_utilcmd.c:1746 +#: parser/parse_clause.c:3662 #, c-format -msgid "index \"%s\" does not have default sorting behavior" -msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 기본 ì •ë ¬ ë°©ë²•ì´ ì—†ìŒ" +msgid "Cast the offset value to the exact intended type." +msgstr "" -#: parser/parse_utilcmd.c:1893 +#: parser/parse_coerce.c:1017 parser/parse_coerce.c:1055 +#: parser/parse_coerce.c:1073 parser/parse_coerce.c:1088 +#: parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:955 #, c-format -msgid "column \"%s\" appears twice in primary key constraint" -msgstr "기본키 제약 ì¡°ê±´ì—서 \"%s\" ì—´ì´ ë‘ ë²ˆ 지정ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "cannot cast type %s to %s" +msgstr "%s ìžë£Œí˜•ì„ %s ìžë£Œí˜•으로 형변환할 수 없습니다." -#: parser/parse_utilcmd.c:1899 +#: parser/parse_coerce.c:1058 #, c-format -msgid "column \"%s\" appears twice in unique constraint" -msgstr "고유 제약 ì¡°ê±´ì—서 \"%s\" ì—´ì´ ë‘ ë²ˆ 지정ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "Input has too few columns." +msgstr "ìž…ë ¥ì— ë„ˆë¬´ ì ì€ ì¹¼ëŸ¼ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤." -#: parser/parse_utilcmd.c:2103 +#: parser/parse_coerce.c:1076 #, c-format -msgid "index expression cannot return a set" -msgstr "ì¸ë±ìФ ì‹ì€ 세트를 반환할 수 ì—†ìŒ" +msgid "Cannot cast type %s to %s in column %d." +msgstr "%s ìžë£Œí˜•ì„ %s ìžë£Œí˜•으로 형변환할 수 없습니다 해당 ì—´ %d." -#: parser/parse_utilcmd.c:2114 +#: parser/parse_coerce.c:1091 #, c-format -msgid "" -"index expressions and predicates can refer only to the table being indexed" -msgstr "ì¸ë±ìФ ì‹ ë° ìˆ ì–´ëŠ” ì¸ë±ì‹±ë˜ëŠ” í…Œì´ë¸”ë§Œ 참조할 수 있ìŒ" +msgid "Input has too many columns." +msgstr "ìž…ë ¥ì— ë„ˆë¬´ ë§Žì€ ì¹¼ëŸ¼ì„ ì§€ì •í–ˆìŠµë‹ˆë‹¤." -#: parser/parse_utilcmd.c:2160 +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1146 parser/parse_coerce.c:1194 #, c-format -msgid "rules on materialized views are not supported" -msgstr "êµ¬ì²´í™”ëœ ë·°ì—ì„œì˜ ë£°ì€ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "argument of %s must be type %s, not type %s" +msgstr "%sì˜ ì¸ìžëŠ” %s ìžë£Œí˜•ì´ì–´ì•¼ 함(%s ìžë£Œí˜•ì´ ì•„ë‹˜)" -#: parser/parse_utilcmd.c:2221 +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1157 parser/parse_coerce.c:1206 #, c-format -msgid "rule WHERE condition cannot contain references to other relations" -msgstr "룰ì—서 지정한 WHERE ì¡°ê±´ì— ë‹¤ë¥¸ 릴레ì´ì…˜ì— 대한 참조를 í¬í•¨í•  수 ì—†ìŒ" +msgid "argument of %s must not return a set" +msgstr "%s ì˜ ì¸ìžëŠ” set(ì§‘í•©) ì„ return할수 없습니다." -#: parser/parse_utilcmd.c:2293 +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1346 #, c-format -msgid "" -"rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE " -"actions" -msgstr "" -"룰ì—서 지정한 WHERE ì¡°ê±´ì´ ìžˆëŠ” 규칙ì—는 SELECT, INSERT, UPDATE ë˜ëŠ” DELETE " -"작업만 í¬í•¨í•  수 있ìŒ" +msgid "%s types %s and %s cannot be matched" +msgstr "%s ìžë£Œí˜• %s 와 %s 는 서로 매치ë˜ì§€ 않습니다" -#: parser/parse_utilcmd.c:2311 parser/parse_utilcmd.c:2410 -#: rewrite/rewriteHandler.c:485 rewrite/rewriteManip.c:1015 +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1413 #, c-format -msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" -msgstr "conditional UNION/INTERSECT/EXCEPT êµ¬ë¬¸ì€ êµ¬í˜„ë˜ì–´ 있지 않다" +msgid "%s could not convert type %s to %s" +msgstr "%s 는 ìžë£Œí˜• %s ìžë£Œí˜•ì—서 %s ìžë£Œí˜•으로 ë³€í™˜ë  ìˆ˜ 없습니다." -#: parser/parse_utilcmd.c:2329 +#: parser/parse_coerce.c:1715 #, c-format -msgid "ON SELECT rule cannot use OLD" -msgstr "ON SELECT ë£°ì€ OLD를 사용할 수 ì—†ìŒ" +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "\"anyelement\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다" -#: parser/parse_utilcmd.c:2333 +#: parser/parse_coerce.c:1735 #, c-format -msgid "ON SELECT rule cannot use NEW" -msgstr "ON SELECT ë£°ì€ NEW를 사용할 수 ì—†ìŒ" +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다." -#: parser/parse_utilcmd.c:2342 +#: parser/parse_coerce.c:1755 #, c-format -msgid "ON INSERT rule cannot use OLD" -msgstr "ON INSERT ë£°ì€ OLD를 사용할 수 ì—†ìŒ" +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "\"anyarray\" 로 ì„ ì–¸ëœ ì¸ìžë“¤ì´ ëª¨ë‘ ê°™ì§€ 않습니다." -#: parser/parse_utilcmd.c:2348 +#: parser/parse_coerce.c:1784 parser/parse_coerce.c:1999 +#: parser/parse_coerce.c:2033 #, c-format -msgid "ON DELETE rule cannot use NEW" -msgstr "ON DELETE ë£°ì€ NEW를 사용할 수 ì—†ìŒ" +msgid "argument declared %s is not an array but type %s" +msgstr "%s ì´ë¦„으로 ì„ ì–¸ëœ ì¸ìžê°€ arrayê°€ 아니고, %s ìžë£Œí˜•입니다" -#: parser/parse_utilcmd.c:2376 +#: parser/parse_coerce.c:1800 parser/parse_coerce.c:1839 #, c-format -msgid "cannot refer to OLD within WITH query" -msgstr "" +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "%s ì´ë¦„으로 ì„ ì–¸ëœ ì¸ìžê°€ %s 형으로 ì„ ì–¸ëœ ì¸ìžë“¤ê³¼ ì¼ê´€ì„±ì´ 없습니다질 않습니다" -#: parser/parse_utilcmd.c:2383 +#: parser/parse_coerce.c:1822 parser/parse_coerce.c:2046 #, c-format -msgid "cannot refer to NEW within WITH query" -msgstr "" +msgid "argument declared %s is not a range type but type %s" +msgstr "%s 로 ì„ ì–¸ëœ ì¸ìžê°€ range ìžë£Œí˜•ì´ ì•„ë‹ˆê³ , %s ìžë£Œí˜•입니다" -#: parser/parse_utilcmd.c:2586 +#: parser/parse_coerce.c:1860 #, c-format -msgid "transform expression must not return a set" -msgstr "transform 표현ì‹ì€ í•˜ë‚˜ì˜ ì„¸íŠ¸ë¥¼ 리턴하면 안ë©ë‹ˆë‹¤" +msgid "could not determine polymorphic type because input has type %s" +msgstr "ìž…ë ¥ì— %s í˜•ì´ ìžˆì–´ 다변 형ì‹ì„ 확ì¸í•  수 ì—†ìŒ" -#: parser/parse_utilcmd.c:2700 +#: parser/parse_coerce.c:1871 #, c-format -msgid "misplaced DEFERRABLE clause" -msgstr "DEFERABLE ì ˆì´ ìž˜ëª» 놓여져 있습니다" +msgid "type matched to anynonarray is an array type: %s" +msgstr "anynonarrayì— ì¼ì¹˜ëœ 형ì‹ì´ ë°°ì—´ 형ì‹ìž„: %s" -#: parser/parse_utilcmd.c:2705 parser/parse_utilcmd.c:2720 +#: parser/parse_coerce.c:1881 #, c-format -msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" -msgstr "여러 ê°œì˜ DEFERRABLE/NOT DEFERRABLEì ˆì€ ì‚¬ìš©í•  수 없습니다" +msgid "type matched to anyenum is not an enum type: %s" +msgstr "anyenumì— ì¼ì¹˜ëœ 형ì‹ì´ ì—´ê±° 형ì‹ì´ 아님: %s" -#: parser/parse_utilcmd.c:2715 +#: parser/parse_coerce.c:1921 parser/parse_coerce.c:1951 #, c-format -msgid "misplaced NOT DEFERRABLE clause" -msgstr "NOT DEFERABLE ì ˆì´ ìž˜ëª» 놓여 있습니다" +msgid "could not find range type for data type %s" +msgstr "ìžë£Œí˜• %s ì— ëŒ€í•´ì„œëŠ” ë°°ì—´ ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" -#: parser/parse_utilcmd.c:2728 parser/parse_utilcmd.c:2754 gram.y:4902 +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 #, c-format -msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" -msgstr "INITIALLY DEFERRED 로 ì„ ì–¸ëœ ì¡°ê±´ë¬¸ì€ ë°˜ë“œì‹œ DEFERABLE 여야만 한다" +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "암묵ì ìœ¼ë¡œ ì„ íƒëœ \"%s\" ì •ë ¬ 규칙와 \"%s\" ì •ë ¬ ê·œì¹™ì´ ë§¤ì¹­ë˜ì§€ 않습니다" -#: parser/parse_utilcmd.c:2736 +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 #, c-format -msgid "misplaced INITIALLY DEFERRED clause" -msgstr "INITIALLY DEFERRED ì ˆì´ ìž˜ëª» 놓여 있습니다" +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "한 쪽 ë˜ëŠ” 서로 COLLATE ì ˆì„ ì´ìš©í•´ ì •ë ¬ ê·œì¹™ì„ ì§€ì •í•˜ì„¸ìš”" -#: parser/parse_utilcmd.c:2741 parser/parse_utilcmd.c:2767 +#: parser/parse_collate.c:831 #, c-format -msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" -msgstr "여러 ê°œì˜ INITIALLY IMMEDIATE/DEFERRED ì ˆì€ í—ˆìš©ë˜ì§€ 않습니다" +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "명시ì ìœ¼ë¡œ 지정한 \"%s\" 정렬규칙와 \"%s\" ì •ë ¬ê·œì¹™ì´ ë§¤ì¹­ë˜ì§€ 않습니다" -#: parser/parse_utilcmd.c:2762 +#: parser/parse_cte.c:42 #, c-format -msgid "misplaced INITIALLY IMMEDIATE clause" -msgstr "INITIALLY IMMEDIATE ì ˆì´ ìž˜ëª» 놓여 있습니다" +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 비재귀 구문 안ì—는 없어야 함" -#: parser/parse_utilcmd.c:2953 +#: parser/parse_cte.c:44 #, c-format -msgid "" -"CREATE specifies a schema (%s) different from the one being created (%s)" -msgstr "CREATE êµ¬ë¬¸ì— ëª…ì‹œëœ schema (%s) ê°€ ìƒì„±ëœ (%s) ì˜ ê²ƒê³¼ 다릅니다" +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 하위 쿼리 ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" -#: parser/scansup.c:204 +#: parser/parse_cte.c:46 #, c-format -msgid "identifier \"%s\" will be truncated to \"%s\"" -msgstr "\"%s\" ì‹ë³„ìžëŠ” \"%s\"(으)로 잘림" +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 outer join 구문 ì•ˆì— ì—†ì–´ì•¼ 함" -#: port/pg_sema.c:113 port/sysv_sema.c:113 +#: parser/parse_cte.c:48 #, c-format -msgid "could not create semaphores: %m" -msgstr "세마í¬ì–´ë¥¼ 만들 수 ì—†ìŒ: %m" +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 INTERSECT ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" -#: port/pg_sema.c:114 port/sysv_sema.c:114 +#: parser/parse_cte.c:50 #, c-format -msgid "Failed system call was semget(%lu, %d, 0%o)." -msgstr "semget(%lu, %d, 0%o) í˜¸ì¶œì— ì˜í•œ 시스템 콜 실패" +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 EXCEPT ë‚´ì— í‘œì‹œë˜ì§€ 않아야 함" -#: port/pg_sema.c:118 port/sysv_sema.c:118 +#: parser/parse_cte.c:132 #, c-format -msgid "" -"This error does *not* mean that you have run out of disk space. It occurs " -"when either the system limit for the maximum number of semaphore sets " -"(SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be " -"exceeded. You need to raise the respective kernel parameter. " -"Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its " -"max_connections parameter.\n" -"The PostgreSQL documentation contains more information about configuring " -"your system for PostgreSQL." -msgstr "" -"ì´ ì˜¤ë¥˜ëŠ” 서버를 ì‹¤í–‰í•˜ëŠ”ë° í•„ìš”í•œ ë””ìŠ¤í¬ ê³µê°„ì´ ë¶€ì¡±í•´ì„œ ë°œìƒí•œ ê²ƒì´ ì•„ë‹™ë‹ˆ" -"다.\n" -"ì´ ì˜¤ë¥˜ëŠ” 시스템ì—서 지정한 최소 세마í¬ì–´ 수(SEMMNI)ê°€ 너무 í¬ê±°ë‚˜, 최대 세마" -"í¬ì–´ 수(SEMMNS)ê°€ 너무 ì ì–´ì„œ 서버를 실행할 수 ì—†ì„ ë•Œ ë°œìƒí•©ë‹ˆë‹¤. ì´ì— ë”°" -"ë¼, ì •ìƒì ìœ¼ë¡œ 서버가 실행ë˜ë ¤ë©´, 시스템 ê°’ë“¤ì„ ì¡°ì •í•  필요가 있습니다. 아니" -"ë©´, 다른 방법으로, PostgreSQLì˜ í™˜ê²½ 설정ì—서 max_connections ê°’ì„ ì¤„ì—¬ì„œ 세" -"마í¬ì–´ 사용 수를 줄여보십시오.\n" -"보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL ê´€ë¦¬ìž ë©”ë‰´ì–¼ì„ ì°¸ì¡° 하십시오." +msgid "WITH query name \"%s\" specified more than once" +msgstr "\"%s\" WITH 쿼리 ì´ë¦„ì´ ì—¬ëŸ¬ 번 지정ë¨" -#: port/pg_sema.c:148 port/sysv_sema.c:148 +#: parser/parse_cte.c:264 #, c-format -msgid "" -"You possibly need to raise your kernel's SEMVMX value to be at least %d. " -"Look into the PostgreSQL documentation for details." -msgstr "" -"커ë„ì˜ SEMVMX ê°’ì„ ì ì–´ë„ %d ì •ë„로 늘려야할 필요가 있는 것 같습니다. ìžì„¸" -"한 ê²ƒì€ PostgreSQL 문서를 참조하세요." +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "ìžë£Œë¥¼ 변경하는 êµ¬ë¬¸ì´ ìžˆëŠ” WITH ì ˆì€ ìµœìƒìœ„ ìˆ˜ì¤€ì— ìžˆì–´ì•¼ 합니다" -#: port/pg_shmem.c:175 port/sysv_shmem.c:175 +#: parser/parse_cte.c:313 #, c-format -msgid "could not create shared memory segment: %m" -msgstr "공유 메모리 세그먼트를 만들 수 ì—†ìŒ: %m" +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì˜ %d 번째 ì¹¼ëŸ¼ì€ ë¹„ìž¬ê·€ ì¡°ê±´ì— %s ìžë£Œí˜•ì„ í¬í•¨í•˜ëŠ”ë° ì „ì²´ì ìœ¼ë¡œëŠ” %s ìžë£Œí˜•ìž„" -#: port/pg_shmem.c:176 port/sysv_shmem.c:176 +#: parser/parse_cte.c:319 #, c-format -msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." -msgstr "shmget(키=%lu, í¬ê¸°=%zu, 0%o) 시스템 콜 실패" +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "비재귀 ì¡°ê±´ì˜ ì¶œë ¥ì„ ì˜¬ë°”ë¥¸ 형ì‹ìœ¼ë¡œ 형변환하십시오." -#: port/pg_shmem.c:180 port/sysv_shmem.c:180 +#: parser/parse_cte.c:324 #, c-format -msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded your kernel's SHMMAX parameter, or possibly that it is less " -"than your kernel's SHMMIN parameter.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." -msgstr "" -"ì´ ì˜¤ë¥˜ë¥¼ ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 메모리 í¬ê¸°ê°€ 커ë„ì˜ SHMMAX " -"값보다 í¬ê±°ë‚˜, SHMMIN 값보다 ì ì€ 경우 ë°œìƒí•©ë‹ˆë‹¤.\n" -"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì˜ %d 번째 ì¹¼ëŸ¼ì€ ë¹„ìž¬ê·€ ì¡°ê±´ì— %s ìžë£Œí˜•ì„ í¬í•¨í•˜ëŠ”ë° ì „ì²´ì ìœ¼ë¡œëŠ” %s ìžë£Œí˜•ìž„" -#: port/pg_shmem.c:187 port/sysv_shmem.c:187 +#: parser/parse_cte.c:328 #, c-format -msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded your kernel's SHMALL parameter. You might need to " -"reconfigure the kernel with larger SHMALL.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." -msgstr "" -"ì´ ì˜¤ë¥˜ë¥¼ ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 í¬ê¸°ê°€ 커ë„ì˜ SHMALL 값보다 " -"í° ê²½ìš° ë°œìƒí•©ë‹ˆë‹¤. ì»¤ë„ í™˜ê²½ ë³€ìˆ˜ì¸ SHMALL ê°’ì„ ì¢€ ë” í¬ê²Œ 설정하세요.\n" -"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "" -#: port/pg_shmem.c:193 port/sysv_shmem.c:193 +#: parser/parse_cte.c:418 #, c-format -msgid "" -"This error does *not* mean that you have run out of disk space. It occurs " -"either if all available shared memory IDs have been taken, in which case you " -"need to raise the SHMMNI parameter in your kernel, or because the system's " -"overall limit for shared memory has been reached.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." -msgstr "" -"ì´ ì˜¤ë¥˜ëŠ” 서버를 ì‹¤í–‰í•˜ëŠ”ë° í•„ìš”í•œ ë””ìŠ¤í¬ ê³µê°„ì´ ë¶€ì¡±í•´ì„œ ë°œìƒí•œ ê²ƒì´ ì•„ë‹™ë‹ˆ" -"다. ì´ ì˜¤ë¥˜ëŠ” 서버가 사용할 공유 메모리 ID를 ì„ ì í•˜ì§€ ëª»í–ˆì„ ë•Œ ë°œìƒí•©ë‹ˆ" -"다. ì»¤ë„ í™˜ê²½ ì„¤ì •ê°’ì¸ SHMMNI ê°’ì„ ëŠ˜ë¦¬ê±°ë‚˜, ì‹œìŠ¤í…œì˜ ê°€ìš© 공유 ë©”ëª¨ë¦¬ëŸ‰ì„ " -"확보하세요.\n" -"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "\"%s\" WITH 쿼리ì—는 %dê°œì˜ ì¹¼ëŸ¼ì„ ì‚¬ìš©í•  수 ìžˆëŠ”ë° %dê°œì˜ ì¹¼ëŸ¼ì´ ì§€ì •ë¨" -#: port/pg_shmem.c:483 port/sysv_shmem.c:483 +#: parser/parse_cte.c:598 #, c-format -msgid "could not map anonymous shared memory: %m" -msgstr "가용 공유 메모리 확보 실패: %m" +msgid "mutual recursion between WITH items is not implemented" +msgstr "WITH 항목 ê°„ì˜ ìƒí˜¸ 재귀가 구현ë˜ì§€ 않ìŒ" -#: port/pg_shmem.c:485 port/sysv_shmem.c:485 +#: parser/parse_cte.c:650 #, c-format -msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded available memory, swap space, or huge pages. To reduce the " -"request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, " -"perhaps by reducing shared_buffers or max_connections." -msgstr "" -"ì´ ì˜¤ë¥˜ëŠ” ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 메모리를 확보하지 못 í–ˆì„ ë•Œ " -"ë°œìƒí•©ë‹ˆë‹¤(물리 메모리, 스왑, huge page). 현재 요구 í¬ê¸°(%zu ë°”ì´íЏ)를 좀 줄" -"ì—¬ 보십시오. 줄ì´ëŠ” 방법ì€, shared_buffers ê°’ì„ ì¤„ì´ê±°ë‚˜ max_connections ê°’" -"ì„ ì¤„ì—¬ 보십시오." +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì— ìžë£Œ 변경 êµ¬ë¬¸ì´ í¬í•¨ë  수 없습니다." -#: port/pg_shmem.c:551 port/sysv_shmem.c:551 port/win32_shmem.c:134 +#: parser/parse_cte.c:658 #, c-format -msgid "huge pages not supported on this platform" -msgstr "huge page ê¸°ëŠ¥ì€ ì´ í”Œëž«í¼ì—서 ì§€ì›ë˜ì§€ 않ìŒ" +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "\"%s\" 재귀 ì¿¼ë¦¬ì— ë¹„ìž¬ê·€ ì¡°ê±´ í˜•íƒœì˜ UNION [ALL] 재귀 ì¡°ê±´ì´ ì—†ìŒ" -#: port/pg_shmem.c:646 port/sysv_shmem.c:646 +#: parser/parse_cte.c:702 #, c-format -msgid "could not stat data directory \"%s\": %m" -msgstr "\"%s\" ë°ì´í„° 디렉터리 ìƒíƒœë¥¼ 파악할 수 ì—†ìŒ: %m" +msgid "ORDER BY in a recursive query is not implemented" +msgstr "재귀 ì¿¼ë¦¬ì˜ ORDER BYê°€ 구현ë˜ì§€ 않ìŒ" -#: port/win32/crashdump.c:122 +#: parser/parse_cte.c:708 #, c-format -msgid "could not load dbghelp.dll, cannot write crash dump\n" -msgstr "" +msgid "OFFSET in a recursive query is not implemented" +msgstr "재귀 ì¿¼ë¦¬ì˜ OFFSETì´ êµ¬í˜„ë˜ì§€ 않ìŒ" -#: port/win32/crashdump.c:130 +#: parser/parse_cte.c:714 #, c-format -msgid "" -"could not load required functions in dbghelp.dll, cannot write crash dump\n" -msgstr "" +msgid "LIMIT in a recursive query is not implemented" +msgstr "재귀 ì¿¼ë¦¬ì˜ LIMITê°€ 구현ë˜ì§€ 않ìŒ" -#: port/win32/crashdump.c:161 +#: parser/parse_cte.c:720 #, c-format -msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" -msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 쓰기 위해 ì—´ 수 ì—†ìŒ: 오류 번호 %lu\n" +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "재귀 ì¿¼ë¦¬ì˜ FOR UPDATE/SHAREê°€ 구현ë˜ì§€ 않ìŒ" -#: port/win32/crashdump.c:168 +#: parser/parse_cte.c:777 #, c-format -msgid "wrote crash dump to file \"%s\"\n" -msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 만들었습니다.\n" +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "\"%s\" ì¿¼ë¦¬ì— ëŒ€í•œ 재귀 참조가 여러 번 표시ë˜ì§€ 않아야 함" -#: port/win32/crashdump.c:170 +#: parser/parse_expr.c:350 #, c-format -msgid "could not write crash dump to file \"%s\": error code %lu\n" -msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 쓰기 실패: 오류 번호 %lu\n" +msgid "DEFAULT is not allowed in this context" +msgstr "ì´ ì˜ì—­ì—서는 DEFAULT를 사용할 수 없습니다" -#: port/win32/signal.c:194 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 +#: parser/parse_relation.c:3307 #, c-format -msgid "could not create signal listener pipe for PID %d: error code %lu" -msgstr "%d pid를 위한 ì‹œê·¸ë„ ë¦¬ìŠ¨ë„ˆ 파ì´í”„를 만들 수 ì—†ìŒ: 오류 번호 %lu" +msgid "column %s.%s does not exist" +msgstr "%s.%s 칼럼 ì—†ìŒ" -#: port/win32/signal.c:274 port/win32/signal.c:306 +#: parser/parse_expr.c:415 #, c-format -msgid "could not create signal listener pipe: error code %lu; retrying\n" -msgstr "신호 수신기 파ì´í”„를 만들 수 ì—†ìŒ: 오류 번호 %lu, 다시 시작 중\n" +msgid "column \"%s\" not found in data type %s" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ %s ìžë£Œí˜•ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: port/win32/signal.c:317 +#: parser/parse_expr.c:421 #, c-format -msgid "could not create signal dispatch thread: error code %lu\n" -msgstr "ì‹œê·¸ë„ ë””ìŠ¤íŒ¨ì¹˜ 쓰레드를 만들 수 ì—†ìŒ: 오류 번호 %lu\n" +msgid "could not identify column \"%s\" in record data type" +msgstr "레코드 ë°ì´í„° 형ì‹ì—서 \"%s\" ì¹¼ëŸ¼ì„ ì‹ë³„í•  수 ì—†ìŒ" -#: port/win32_sema.c:94 +#: parser/parse_expr.c:427 #, c-format -msgid "could not create semaphore: error code %lu" -msgstr "세마í¬ì–´ë¥¼ 만들 수 ì—†ìŒ: 오류 번호 %lu" +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr ".%s í‘œí˜„ì´ %s ìžë£Œí˜• 사용ë˜ì—ˆëŠ”ë°, ì´ëŠ” 복소수형 (complex type)ì´ ì•„ë‹™ë‹ˆë‹¤" -#: port/win32_sema.c:167 +#: parser/parse_expr.c:458 parser/parse_target.c:722 #, c-format -msgid "could not lock semaphore: error code %lu" -msgstr "세마í¬ì–´ë¥¼ 잠글 수 ì—†ìŒ: 오류 번호 %lu" +msgid "row expansion via \"*\" is not supported here" +msgstr "\"*\"를 통한 칼럼 í™•ìž¥ì€ ì—¬ê¸°ì„œ ì§€ì›ë˜ì§€ 않ìŒ" -#: port/win32_sema.c:187 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 +#: parser/parse_relation.c:789 parser/parse_target.c:1193 #, c-format -msgid "could not unlock semaphore: error code %lu" -msgstr "세마í¬ì–´ ìž ê¸ˆì„ í•´ì œí•  수 ì—†ìŒ: 오류 번호 %lu" +msgid "column reference \"%s\" is ambiguous" +msgstr "칼럼 참조 \"%s\" ê°€ 모호합니다." -#: port/win32_sema.c:216 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format -msgid "could not try-lock semaphore: error code %lu" -msgstr "세마í¬ì–´ 잠금 ì‹œë„ ì‹¤íŒ¨: 오류 번호 %lu" +msgid "there is no parameter $%d" +msgstr "$%d 매개 변수가 없습니다" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: parser/parse_expr.c:1070 #, c-format -msgid "could not create shared memory segment: error code %lu" -msgstr "공유 메모리 세그먼트를 만들 수 ì—†ìŒ: 오류 번호 %lu" +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULIF ì ˆì€ boolean ê°’ì„ ì–»ê¸° 위해서 = ì—°ì‚°ìžë¥¼ 필요로 합니다" -#: port/win32_shmem.c:174 +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 #, c-format -msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." -msgstr "실패한 시스템 í˜¸ì¶œì€ CreateFileMapping(í¬ê¸°=%zu, ì´ë¦„=%s)입니다." +msgid "%s must not return a set" +msgstr "%sì—서는 ì§‘í•©ì„ ë°˜í™˜í•  수 없습니다." -#: port/win32_shmem.c:198 +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 #, c-format -msgid "pre-existing shared memory block is still in use" -msgstr "기존 공유 메모리 블ë¡ì´ 여전히 사용ë˜ê³  있ìŒ" +msgid "number of columns does not match number of values" +msgstr "ì¹¼ëŸ¼ì˜ ê°œìˆ˜ì™€, valuesì˜ ê°œìˆ˜ê°€ 틀립니다" -#: port/win32_shmem.c:199 +#: parser/parse_expr.c:1570 #, c-format -msgid "" -"Check if there are any old server processes still running, and terminate " -"them." -msgstr "실행 ì¤‘ì¸ ì´ì „ 서버 프로세스가 있는지 확ì¸í•˜ê³  종료하십시오." +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "" -#: port/win32_shmem.c:209 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 #, c-format -msgid "Failed system call was DuplicateHandle." -msgstr "실패한 시스템 í˜¸ì¶œì€ DuplicateHandle입니다." +msgid "set-returning functions are not allowed in %s" +msgstr "%s 안ì—서는 ì§‘í•© 반환 함수를 사용할 수 ì—†ìŒ" + +#: parser/parse_expr.c:1825 +msgid "cannot use subquery in check constraint" +msgstr "ì²´í¬ ì œì•½ ì¡°ê±´ì—서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1829 +msgid "cannot use subquery in DEFAULT expression" +msgstr "DEFAULT ì‹ì—서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1832 +msgid "cannot use subquery in index expression" +msgstr "ì¸ë±ìФ ì‹(expression)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" + +#: parser/parse_expr.c:1835 +msgid "cannot use subquery in index predicate" +msgstr "ì¸ë±ìФ 술어(predicate)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" + +#: parser/parse_expr.c:1838 +msgid "cannot use subquery in transform expression" +msgstr "transform ì‹(expression)ì— ì„œë¸Œì¿¼ë¦¬ë¥¼ 사용할 수 없습니다" + +#: parser/parse_expr.c:1841 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "EXECUTE 매개 변수로 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1844 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "트리거 WHEN ì¡°ê±´ì ˆì—서는 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1847 +msgid "cannot use subquery in partition key expression" +msgstr "파티션 키 표현ì‹ì— 서브쿼리를 사용할 수 없습니다" + +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "CALL 매개 변수로 서브쿼리를 사용할 수 없습니다" -#: port/win32_shmem.c:227 +#: parser/parse_expr.c:1903 #, c-format -msgid "Failed system call was MapViewOfFileEx." -msgstr "실패한 시스템 í˜¸ì¶œì€ MapViewOfFileEx입니다." +msgid "subquery must return only one column" +msgstr "subquery는 오로지 í•œê°œì˜ ì—´ë§Œì„ ëŒë ¤ 주어야 합니다." -#: postmaster/autovacuum.c:380 +#: parser/parse_expr.c:1987 #, c-format -msgid "could not fork autovacuum launcher process: %m" -msgstr "autovacuum 실행기 프로세스를 실행할 수 ì—†ìŒ: %m" +msgid "subquery has too many columns" +msgstr "subquery ì—ê°€ 너무 ë§Žì€ ì¹¼ëŸ¼ì„ ê°€ì§‘ë‹ˆë‹¤" -#: postmaster/autovacuum.c:416 +#: parser/parse_expr.c:1992 #, c-format -msgid "autovacuum launcher started" -msgstr "autovacuum 실행기가 시작ë¨" +msgid "subquery has too few columns" +msgstr "subquery ì— ëª…ì‹œëœ ì—´ 수가 너무 ì ë‹¤" -#: postmaster/autovacuum.c:779 +#: parser/parse_expr.c:2093 #, c-format -msgid "autovacuum launcher shutting down" -msgstr "autovacuum 실행기를 종료하는 중" +msgid "cannot determine type of empty array" +msgstr "빈 ë°°ì—´ì˜ ìžë£Œí˜•ì„ í™•ì¸í•  수 ì—†ìŒ" -#: postmaster/autovacuum.c:1441 +#: parser/parse_expr.c:2094 #, c-format -msgid "could not fork autovacuum worker process: %m" -msgstr "autovacuum ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 실행할 수 ì—†ìŒ: %m" +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "ì›í•˜ëŠ” 형ì‹ìœ¼ë¡œ 명시ì ìœ¼ë¡œ 형변환하십시오(예: ARRAY[]::integer[])." -#: postmaster/autovacuum.c:1639 +#: parser/parse_expr.c:2108 #, c-format -msgid "autovacuum: processing database \"%s\"" -msgstr "autovacuum: \"%s\" ë°ì´í„°ë² ì´ìФ 처리 중" +msgid "could not find element type for data type %s" +msgstr "%s ìžë£Œí˜•ì˜ ìš”ì†Œ ìžë£Œí˜•ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: postmaster/autovacuum.c:2052 +#: parser/parse_expr.c:2395 #, c-format -msgid "autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "" -"autovacuum: \"%s\".\"%s\" 사용 않는 임시 í…Œì´ë¸”ì„ \"%s\" ë°ì´í„°ë² ì´ìФì—서 ì‚­" -"제하는 중" +msgid "unnamed XML attribute value must be a column reference" +msgstr "ì´ë¦„ì´ ì§€ì •ë˜ì§€ ì•Šì€ XML ì†ì„± ê°’ì€ ì—´ 참조여야 함" -#: postmaster/autovacuum.c:2064 +#: parser/parse_expr.c:2396 #, c-format -msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "" -"autovacuum: \"%s\".\"%s\" 사용 않는 임시 í…Œì´ë¸”ì„ \"%s\" ë°ì´í„°ë² ì´ìФì—서 ì°¾" -"았ìŒ" +msgid "unnamed XML element value must be a column reference" +msgstr "ì´ë¦„ì´ ì§€ì •ë˜ì§€ ì•Šì€ XML 요소 ê°’ì€ ì—´ 참조여야 함" -#: postmaster/autovacuum.c:2347 +#: parser/parse_expr.c:2411 #, c-format -msgid "automatic vacuum of table \"%s.%s.%s\"" -msgstr "\"%s.%s.%s\" í…Œì´ë¸” 대ìƒìœ¼ë¡œ ìžë™ vacuum 작업 함" +msgid "XML attribute name \"%s\" appears more than once" +msgstr "\"%s\" XML ì†ì„± ì´ë¦„ì´ ì—¬ëŸ¬ 번 표시ë¨" -#: postmaster/autovacuum.c:2350 +#: parser/parse_expr.c:2518 #, c-format -msgid "automatic analyze of table \"%s.%s.%s\"" -msgstr "\"%s.%s.%s\" í…Œì´ë¸” ìžë™ ë¶„ì„" +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "XMLSERIALIZE 결과를 %s 형으로 바꿀 수 ì—†ìŒ" -#: postmaster/autovacuum.c:2899 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format -msgid "autovacuum not started because of misconfiguration" -msgstr "서버 설정 ì •ë³´ê°€ 잘못ë˜ì–´ ìžë™ 청소 ìž‘ì—…ì´ ì‹¤í–‰ë˜ì§€ 못했습니다." +msgid "unequal number of entries in row expressions" +msgstr "í–‰ 표현ì‹ì—서 항목 수가 ì¼ì¹˜í•˜ì§€ 않습니다" -#: postmaster/autovacuum.c:2900 +#: parser/parse_expr.c:2824 #, c-format -msgid "Enable the \"track_counts\" option." -msgstr "\"track_counts\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." +msgid "cannot compare rows of zero length" +msgstr "길ì´ê°€ ì˜(0)ì¸ í–‰ë“¤ì€ ë¹„êµí•  수 없습니다" -#: postmaster/bgworker.c:346 postmaster/bgworker.c:745 +#: parser/parse_expr.c:2849 #, c-format -msgid "registering background worker \"%s\"" -msgstr "" +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "í–‰ ë¹„êµ ì—°ì‚°ìžëŠ” booleaní˜•ì„ ë¦¬í„´í•´ì•¼í•©ë‹ˆë‹¤. %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 없습니다" -#: postmaster/bgworker.c:375 +#: parser/parse_expr.c:2856 #, c-format -msgid "unregistering background worker \"%s\"" -msgstr "" +msgid "row comparison operator must not return a set" +msgstr "í–‰ ë¹„êµ ì—°ì‚°ìžëŠ” setì„ ë¦¬í„´í•  수 없습니다" -#: postmaster/bgworker.c:484 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format -msgid "" -"background worker \"%s\": must attach to shared memory in order to request a " -"database connection" -msgstr "" +msgid "could not determine interpretation of row comparison operator %s" +msgstr "%s í–‰ ë¹„êµ ì—°ì‚°ìžì˜ êµ¬ë¬¸ì„ ë¶„ì„í•  수 없습니다" -#: postmaster/bgworker.c:493 +#: parser/parse_expr.c:2917 #, c-format -msgid "" -"background worker \"%s\": cannot request database access if starting at " -"postmaster start" -msgstr "" +msgid "Row comparison operators must be associated with btree operator families." +msgstr "로우 ë¹„êµ ì—°ì‚°ìžë¥¼ btree ì—°ì‚°ìž íŒ¨ë°€ë¦¬ì™€ 연결해야 함" -#: postmaster/bgworker.c:507 +#: parser/parse_expr.c:2958 #, c-format -msgid "background worker \"%s\": invalid restart interval" -msgstr "\"%s\" 백그ë¼ìš´ë“œ 작업ìž: ìž˜ëª»ëœ ìž¬ì‹¤í–‰ 간격" +msgid "There are multiple equally-plausible candidates." +msgstr "여러 가지 등ì‹ë“¤ì´ 성립할 수 있는 ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤" -#: postmaster/bgworker.c:552 +#: parser/parse_expr.c:3051 #, c-format -msgid "terminating background worker \"%s\" due to administrator command" -msgstr "ê´€ë¦¬ìž ëª…ë ¹ì— ì˜í•´ \"%s\" 백그ë¼ìš´ë“œ 작업ìžë¥¼ 종료합니다." +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM ì ˆì—서 boolean ê°’ì„ ì–»ê¸° 위해서 = ì—°ì‚°ìžë¥¼ 필요로 합니다" -#: postmaster/bgworker.c:752 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 #, c-format -msgid "" -"background worker \"%s\": must be registered in shared_preload_libraries" +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "ì—°ì‚°ìž ìš°ì„ ìˆœìœ„ 변경ë¨: %s ì—°ì‚°ìž ìš°ì„ ìˆœìœ„ê°€ %s 연산보다 낮습니다" + +#: parser/parse_func.c:185 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "\"%s\" ì´ë¦„ì˜ ë§¤ê°œ 변수가 여러 번 사용 ë¨" + +#: parser/parse_func.c:196 +#, c-format +msgid "positional argument cannot follow named argument" msgstr "" -"\"%s\" 백그ë¼ìš´ë“œ 작업ìž: 먼저 shared_preload_libraries 설정값으로 등ë¡ë˜ì–´" -"야 합니다." -#: postmaster/bgworker.c:764 +#: parser/parse_func.c:278 parser/parse_func.c:2184 #, c-format -msgid "" -"background worker \"%s\": only dynamic background workers can request " -"notification" +msgid "%s is not a procedure" +msgstr "%s 개체는 프로시져가 아님" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." msgstr "" -"\"%s\" 백그ë¼ìš´ë“œ 작업ìž: ë™ì  백그ë¼ìš´ë“œ 작업ìžë§Œ ì•Œë¦¼ì„ ìš”ì²­í•  수 있ìŒ" -#: postmaster/bgworker.c:779 +#: parser/parse_func.c:288 #, c-format -msgid "too many background workers" -msgstr "백그ë¼ìš´ë“œ 작업ìžê°€ 너무 ë§ŽìŒ" +msgid "%s is a procedure" +msgstr "%s 개체는 프로시져임" -#: postmaster/bgworker.c:780 +#: parser/parse_func.c:292 #, c-format -msgid "Up to %d background worker can be registered with the current settings." -msgid_plural "" -"Up to %d background workers can be registered with the current settings." -msgstr[0] "현재 설정으로는 %dê°œì˜ ë°±ê·¸ë¼ìš´ë“œ 작업ìžë¥¼ 사용할 수 있습니다." +msgid "To call a procedure, use CALL." +msgstr "" -#: postmaster/bgworker.c:784 +#: parser/parse_func.c:306 #, c-format -msgid "" -"Consider increasing the configuration parameter \"max_worker_processes\"." -msgstr "\"max_worker_processes\" 환경 매개 변수 ê°’ì„ ì¢€ ëŠë ¤ë³´ì‹­ì‹œì˜¤." +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) ê°€ 명시ë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다." -#: postmaster/checkpointer.c:463 +#: parser/parse_func.c:313 #, c-format -msgid "checkpoints are occurring too frequently (%d second apart)" -msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" -msgstr[0] "ì²´í¬í¬ì¸íŠ¸ê°€ 너무 ìžì£¼ ë°œìƒí•¨ (%dì´ˆ 간격)" +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT ê°€ 명시ë˜ì–´ 있는ë°, 그러나 ì´ %s 함수는 집계 함수가 아닙니다" -#: postmaster/checkpointer.c:467 +#: parser/parse_func.c:319 #, c-format -msgid "Consider increasing the configuration parameter \"max_wal_size\"." -msgstr "\"max_wal_size\" 환경 매개 변수 ê°’ì„ ì¢€ ëŠë ¤ë³´ì‹­ì‹œì˜¤." +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다" -#: postmaster/checkpointer.c:614 +#: parser/parse_func.c:325 #, c-format -msgid "transaction log switch forced (archive_timeout=%d)" -msgstr "강제로 트랜잭션 로그를 바꿨습니다 (archive_timeout=%d)" +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다." -#: postmaster/checkpointer.c:1072 +#: parser/parse_func.c:331 #, c-format -msgid "checkpoint request failed" -msgstr "ì²´í¬í¬ì¸íЏ 요청 실패" +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER ì ˆì´ ëª…ì‹œë˜ì–´ 있는ë°, ì´ %s 함수는 집계 함수가 아닙니다" -#: postmaster/checkpointer.c:1073 +#: parser/parse_func.c:337 #, c-format -msgid "Consult recent messages in the server log for details." -msgstr "ë” ìžì„¸í•œ ê²ƒì€ ì„œë²„ 로그 파ì¼ì„ 살펴보십시오." +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER ì ˆì´ ì§€ì •ë˜ì—ˆëŠ”ë° %s 함수는 윈ë„ìš° 함수 ë˜ëŠ” 집계 함수가 아님" -#: postmaster/checkpointer.c:1268 +#: parser/parse_func.c:375 #, c-format -msgid "compacted fsync request queue from %d entries to %d entries" -msgstr "" +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "순서가 있는 ì§‘ê³„í•¨ìˆ˜ì¸ %s ë•Œë¬¸ì— WITHIN GROUP ì ˆì´ í•„ìš”í•©ë‹ˆë‹¤" -#: postmaster/pgarch.c:149 +#: parser/parse_func.c:381 #, c-format -msgid "could not fork archiver: %m" -msgstr "archiver 할당(fork) 실패: %m" +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "OVER ì ˆì—서 ì •ë ¬ëœ ì„¸íŠ¸ 집계 %s 함수를 ì§€ì›í•˜ì§€ 않ìŒ" -#: postmaster/pgarch.c:456 +#: parser/parse_func.c:412 parser/parse_func.c:441 #, c-format -msgid "archive_mode enabled, yet archive_command is not set" -msgstr "archive_modeê°€ 사용 설정ë˜ì—ˆëŠ”ë° archive_commandê°€ 설정ë˜ì§€ 않ìŒ" +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "" -#: postmaster/pgarch.c:484 +#: parser/parse_func.c:466 #, c-format -msgid "" -"archiving transaction log file \"%s\" failed too many times, will try again " -"later" +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." msgstr "" -"\"%s\" 트랜잭션 로그 íŒŒì¼ ì•„ì¹´ì´ë¸Œ ìž‘ì—…ì´ ê³„ì† ì‹¤íŒ¨í•˜ê³  있습니다. 다ìŒì— ë˜ " -"시ë„í•  것입니다." -#: postmaster/pgarch.c:587 +#: parser/parse_func.c:480 #, c-format -msgid "archive command failed with exit code %d" -msgstr "ì•„ì¹´ì´ë¸Œ 명령 실패, 종료 코드: %d" +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "" -#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 -#: postmaster/pgarch.c:612 postmaster/pgarch.c:621 +#: parser/parse_func.c:499 #, c-format -msgid "The failed archive command was: %s" -msgstr "실패한 ì•„ì¹´ì´ë¸Œ 명령: %s" +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s 함수는 순사가 있는 세트 집계함수가 아니여서 WITHIN GROUP ì ˆì„ ì‚¬ìš©í•  수 없습니다" -#: postmaster/pgarch.c:596 +#: parser/parse_func.c:512 #, c-format -msgid "archive command was terminated by exception 0x%X" -msgstr "0x%X 예외로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨" +msgid "window function %s requires an OVER clause" +msgstr "%s 윈ë„ìš° 함수 호출ì—는 OVER ì ˆì´ í•„ìš”í•¨" -#: postmaster/pgarch.c:598 postmaster/postmaster.c:3491 +#: parser/parse_func.c:519 #, c-format -msgid "" -"See C include file \"ntstatus.h\" for a description of the hexadecimal value." -msgstr "16진수 ê°’ì— ëŒ€í•œ ì„¤ëª…ì€ C í¬í•¨ íŒŒì¼ \"ntstatus.h\"를 참조하십시오." +msgid "window function %s cannot have WITHIN GROUP" +msgstr "%s 윈ë„ìš° 함수는 WITHIN GROUP ì ˆì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: postmaster/pgarch.c:603 +#: parser/parse_func.c:548 #, c-format -msgid "archive command was terminated by signal %d: %s" -msgstr "%d번 시그ë„로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨: %s" +msgid "procedure %s is not unique" +msgstr "%s 프로시져는 유ì¼ì„±ì„ 가지지 못합니다(not unique)" -#: postmaster/pgarch.c:610 +#: parser/parse_func.c:551 #, c-format -msgid "archive command was terminated by signal %d" -msgstr "%d번 시그ë„로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨" +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "가장 ì ë‹¹í•œ 프로시져를 ì„ íƒí•  수 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/pgarch.c:619 +#: parser/parse_func.c:557 #, c-format -msgid "archive command exited with unrecognized status %d" -msgstr "ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¸ì‹í•  수 없는 %d ìƒíƒœë¡œ 종료ë¨" +msgid "function %s is not unique" +msgstr "함수 %s 는 유ì¼ì„±ì„ 가지지 못합니다(not unique)" -#: postmaster/pgarch.c:631 +#: parser/parse_func.c:560 #, c-format -msgid "archived transaction log file \"%s\"" -msgstr "\"%s\" 트랜잭션 로그파ì¼ì´ ì•„ì¹´ì´ë¸Œ ë¨" +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "ì œì¼ ì ë‹¹í•œ 함수를 ì„ íƒí•  수 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/pgarch.c:680 +#: parser/parse_func.c:599 #, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "\"%s\" 디렉터리를 ì—´ 수 없습니다: %m" +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ëŠ” 집계 함수가 없습니다. ORDER BY ì ˆì„ ë°”ë¥¸ ìœ„ì¹˜ì— ì“°ì§€ ì•Šì€ ê²ƒ 같습니다. ORDER BY ì ˆì€ ëª¨ë“  집계용 ì¸ìžë“¤ 맨 ë’¤ì— ìžˆì–´ì•¼ 합니다." -#: postmaster/pgstat.c:355 +#: parser/parse_func.c:607 parser/parse_func.c:2172 #, c-format -msgid "could not resolve \"localhost\": %s" -msgstr "\"localhost\" ì´ë¦„ì˜ í˜¸ìŠ¤íŠ¸ IP를 구할 수 없습니다: %s" +msgid "procedure %s does not exist" +msgstr "\"%s\" 프로시져 ì—†ìŒ" -#: postmaster/pgstat.c:378 +#: parser/parse_func.c:610 #, c-format -msgid "trying another address for the statistics collector" -msgstr "통계 수집기ì—서 사용할 다른 주소를 찾습니다" +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž 형ì‹ê³¼ ì¼ì¹˜í•˜ëŠ” 프로시져가 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/pgstat.c:387 +#: parser/parse_func.c:619 #, c-format -msgid "could not create socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다: %m" +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž ìžë£Œí˜•ê³¼ ì¼ì¹˜í•˜ëŠ” 함수가 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/pgstat.c:399 +#: parser/parse_func.c:721 #, c-format -msgid "could not bind socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 소켓과 bindí•  수 없습니다: %m" +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC 매개 변수는 ë°°ì—´ì´ì–´ì•¼ 함" -#: postmaster/pgstat.c:410 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format -msgid "could not get address of socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì˜ ì£¼ì†Œë¥¼ 구할 수 없습니다: %m" +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) 사용할 때는 ì´ í•¨ìˆ˜ê°€ 매개 변수 없는 집계 함수여야 합니다" -#: postmaster/pgstat.c:426 +#: parser/parse_func.c:780 #, c-format -msgid "could not connect socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì— ì—°ê²°í•  수 없습니다: %m" +msgid "aggregates cannot return sets" +msgstr "집계 함수는 세트를 반환할 수 ì—†ìŒ" -#: postmaster/pgstat.c:447 +#: parser/parse_func.c:795 #, c-format -msgid "could not send test message on socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 보낼 수 없습니다: %m" +msgid "aggregates cannot use named arguments" +msgstr "집계 함수는 ì¸ìž ì´ë¦„ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: postmaster/pgstat.c:473 +#: parser/parse_func.c:827 #, c-format -msgid "select() failed in statistics collector: %m" -msgstr "통계 수집기ì—서 select() 작업 오류: %m" +msgid "DISTINCT is not implemented for window functions" +msgstr "윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ DISTINCTê°€ 구현ë˜ì§€ 않ìŒ" -#: postmaster/pgstat.c:488 +#: parser/parse_func.c:847 #, c-format -msgid "test message did not get through on socket for statistics collector" -msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 처리할 수 없습니다" +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ 집계용 ORDER BYê°€ 구현ë˜ì§€ 않ìŒ" -#: postmaster/pgstat.c:503 +#: parser/parse_func.c:856 #, c-format -msgid "could not receive test message on socket for statistics collector: %m" -msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 ë°›ì„ ìˆ˜ 없습니다: %m" +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "비집계 윈ë„ìš° í•¨ìˆ˜ì— ëŒ€í•´ FILTERê°€ 구현ë˜ì§€ 않ìŒ" -#: postmaster/pgstat.c:513 +#: parser/parse_func.c:865 #, c-format -msgid "incorrect test message transmission on socket for statistics collector" -msgstr "통계 수집기ì—서 사용할 소켓으로 ìž˜ëª»ëœ í…ŒìŠ¤íŠ¸ 메시지가 전달 ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "window function calls cannot contain set-returning function calls" +msgstr "윈ë„ìš° 함수 í˜¸ì¶œì— ì§‘í•© 반환 함수 í˜¸ì¶œì„ í¬í•¨í•  수 ì—†ìŒ" -#: postmaster/pgstat.c:536 +#: parser/parse_func.c:873 #, c-format -msgid "could not set statistics collector socket to nonblocking mode: %m" -msgstr "" -"통계 수집기ì—서 사용하는 소켓 모드를 nonblocking 모드로 지정할 수 없습니다: " -"%m" +msgid "window functions cannot return sets" +msgstr "윈ë„ìš° 함수는 세트를 반환할 수 ì—†ìŒ" -#: postmaster/pgstat.c:546 +#: parser/parse_func.c:2059 #, c-format -msgid "disabling statistics collector for lack of working socket" -msgstr "현재 작업 ì†Œì¼“ì˜ ì›í• í•œ ì†Œí†µì„ ìœ„í•´ 통계 수집기 ê¸°ëŠ¥ì„ ì¤‘ì§€í•©ë‹ˆë‹¤" +msgid "function name \"%s\" is not unique" +msgstr "\"%s\" 함수 ì´ë¦„ì€ ìœ ì¼ì„±ì„ 가지지 못합니다(not unique)" -#: postmaster/pgstat.c:693 +#: parser/parse_func.c:2061 #, c-format -msgid "could not fork statistics collector: %m" -msgstr "통계 수집기를 forkí•  수 없습니다: %m" +msgid "Specify the argument list to select the function unambiguously." +msgstr "ìž…ë ¥ ì¸ìžë¥¼ 다르게 해서 ì´ ëª¨í˜¸í•¨ì„ í”¼í•˜ì„¸ìš”." -#: postmaster/pgstat.c:1261 +#: parser/parse_func.c:2071 #, c-format -msgid "unrecognized reset target: \"%s\"" -msgstr "알 수 없는 리셋 타겟: \"%s\"" +msgid "could not find a function named \"%s\"" +msgstr "\"%s\" 함수를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: postmaster/pgstat.c:1262 +#: parser/parse_func.c:2153 #, c-format -msgid "Target must be \"archiver\" or \"bgwriter\"." -msgstr "사용 가능한 íƒ€ê²Ÿì€ \"archiver\" ë˜ëŠ” \"bgwriter\"" +msgid "%s is not a function" +msgstr "%s ì´ë¦„ì˜ ê°œì²´ëŠ” 함수가 아닙니다" -#: postmaster/pgstat.c:3587 +#: parser/parse_func.c:2167 #, c-format -msgid "could not read statistics message: %m" -msgstr "통계 메시지를 ì½ì„ 수 ì—†ìŒ: %m" +msgid "could not find a procedure named \"%s\"" +msgstr "\"%s\" ì´ë¦„ì˜ í”„ë¡œì‹œì ¸ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: postmaster/pgstat.c:3918 postmaster/pgstat.c:4075 +#: parser/parse_func.c:2198 #, c-format -msgid "could not open temporary statistics file \"%s\": %m" -msgstr "\"%s\" 임시 통계 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "could not find an aggregate named \"%s\"" +msgstr "\"%s\" ì´ë¦„ì˜ ì§‘ê³„ 함수를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: postmaster/pgstat.c:3985 postmaster/pgstat.c:4120 +#: parser/parse_func.c:2203 #, c-format -msgid "could not write temporary statistics file \"%s\": %m" -msgstr "\"%s\" 임시 통계 파ì¼ì— 쓰기 실패: %m" +msgid "aggregate %s(*) does not exist" +msgstr "%s(*) 집계 함수 ì—†ìŒ" -#: postmaster/pgstat.c:3994 postmaster/pgstat.c:4129 +#: parser/parse_func.c:2208 #, c-format -msgid "could not close temporary statistics file \"%s\": %m" -msgstr "\"%s\" 임시 통계 파ì¼ì„ ë‹«ì„ ìˆ˜ 없습니다: %m" +msgid "aggregate %s does not exist" +msgstr "%s 집계 함수 ì—†ìŒ" -#: postmaster/pgstat.c:4002 postmaster/pgstat.c:4137 +#: parser/parse_func.c:2221 #, c-format -msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" -msgstr "\"%s\" 임시 통계 íŒŒì¼ ì´ë¦„ì„ \"%s\" (으)로 바꿀 수 없습니다: %m" +msgid "function %s is not an aggregate" +msgstr "%s 함수는 집계 함수가 아닙니다" -#: postmaster/pgstat.c:4226 postmaster/pgstat.c:4411 postmaster/pgstat.c:4564 -#, c-format -msgid "could not open statistics file \"%s\": %m" -msgstr "\"%s\" 통계 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +#: parser/parse_func.c:2271 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "ì§‘í•© 반환 함수는 JOIN ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: postmaster/pgstat.c:4238 postmaster/pgstat.c:4248 postmaster/pgstat.c:4258 -#: postmaster/pgstat.c:4279 postmaster/pgstat.c:4294 postmaster/pgstat.c:4348 -#: postmaster/pgstat.c:4423 postmaster/pgstat.c:4443 postmaster/pgstat.c:4461 -#: postmaster/pgstat.c:4477 postmaster/pgstat.c:4495 postmaster/pgstat.c:4511 -#: postmaster/pgstat.c:4576 postmaster/pgstat.c:4588 postmaster/pgstat.c:4600 -#: postmaster/pgstat.c:4625 postmaster/pgstat.c:4647 -#, c-format -msgid "corrupted statistics file \"%s\"" -msgstr "\"%s\" 통계 파ì¼ì´ ì†ìƒë˜ì—ˆìŒ" +#: parser/parse_func.c:2292 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "ì§‘í•© 반환 함수는 ì •ì±… ì‹ì— 사용할 수 ì—†ìŒ" -#: postmaster/pgstat.c:4776 -#, c-format -msgid "" -"using stale statistics instead of current ones because stats collector is " -"not responding" -msgstr "" -"현재 통계 수집기가 ë°˜ì‘하지 않아 부정확한 통계정보가 사용ë˜ê³  있습니다." +#: parser/parse_func.c:2308 +msgid "set-returning functions are not allowed in window definitions" +msgstr "ì§‘í•© 반환 함수는 윈ë„ìš° 함수 ì •ì˜ì— 사용할 수 ì—†ìŒ" -#: postmaster/pgstat.c:5103 -#, c-format -msgid "database hash table corrupted during cleanup --- abort" -msgstr "정리하는 ë™ì•ˆ ë°ì´í„°ë² ì´ìФ 해시 í…Œì´ë¸”ì´ ì†ìƒ ë˜ì—ˆìŠµë‹ˆë‹¤ --- 중지함" +#: parser/parse_func.c:2346 +msgid "set-returning functions are not allowed in check constraints" +msgstr "ì§‘í•© 반환 함수는 check ì œì•½ì¡°ê±´ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: postmaster/postmaster.c:684 -#, c-format -msgid "%s: invalid argument for option -f: \"%s\"\n" -msgstr "%s: -f ì˜µì…˜ì˜ ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" +#: parser/parse_func.c:2350 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "ì§‘í•© 반환 함수는 DEFAULT ì‹ì—서 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:770 -#, c-format -msgid "%s: invalid argument for option -t: \"%s\"\n" -msgstr "%s: -t ì˜µì…˜ì˜ ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" +#: parser/parse_func.c:2353 +msgid "set-returning functions are not allowed in index expressions" +msgstr "ì§‘í•© 반환 함수는 ì¸ë±ìФ ì‹ì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_func.c:2356 +msgid "set-returning functions are not allowed in index predicates" +msgstr "ì§‘í•© 반환 함수는 함수 기반 ì¸ë±ìФì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_func.c:2359 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "ì§‘í•© 반환 함수는 transform ì‹ì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_func.c:2362 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "ì§‘í•© 반환 함수는 EXECUTE 매개 변수 설정 값으로 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:821 +#: parser/parse_func.c:2365 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "ì§‘í•© 반환 함수는 íŠ¸ë¦¬ê±°ì˜ WHEN ì¡°ê±´ì ˆì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "ì§‘í•© 반환 함수는 ì¸ë±ìФ ì‹ì—서 사용할 수 ì—†ìŒ" + +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "ì§‘í•© 반환 함수는 CALL ëª…ë ¹ì˜ ì¸ìžë¡œ 사용할 수 ì—†ìŒ" + +#: parser/parse_node.c:87 #, c-format -msgid "%s: invalid argument: \"%s\"\n" -msgstr "%s: ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" +msgid "target lists can have at most %d entries" +msgstr "ëŒ€ìƒ ëª©ë¡ì€ 최대 %d ê°œì˜ í•­ëª©ì„ ì§€ì •í•  수 있습니다" -#: postmaster/postmaster.c:860 +#: parser/parse_node.c:256 #, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "" -"%s: superuser_reserved_connections ê°’ì€ max_connections 값보다 작아야합니다\n" +msgid "cannot subscript type %s because it is not an array" +msgstr "ìžë£Œí˜• %s 는 ë°°ì—´ì´ ì•„ë‹ˆê¸° ë•Œë¬¸ì— ë°°ì—´ 하위 스í¬ë¦½íŠ¸ë¥¼ 기술할 수 없습니다." -#: postmaster/postmaster.c:865 +#: parser/parse_node.c:358 parser/parse_node.c:395 #, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_senders ê°’ì€ max_connections 값보다 작아야합니다\n" +msgid "array subscript must have type integer" +msgstr "ë°°ì—´ 하위 스í¬ë¦½íŠ¸ëŠ” 반드시 정수형ì´ì–´ì•¼ 합니다." -#: postmaster/postmaster.c:870 +#: parser/parse_node.c:426 #, c-format -msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" -msgstr "wal_level ê°’ì´ \"minimal\"ì¼ ë•ŒëŠ” ì•„ì¹´ì´ë¸Œ ìž‘ì—…ì„ í•  수 없습니다." +msgid "array assignment requires type %s but expression is of type %s" +msgstr "ë°°ì—´í• ë‹¹ì€ ìžë£Œí˜• %s ê°€ 필요하지만, 현재 표현ì‹ì´ %s ìžë£Œí˜•입니다" -#: postmaster/postmaster.c:873 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format -msgid "" -"WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or " -"\"logical\"" -msgstr "" -"WAL ìŠ¤íŠ¸ë¦¬ë° ìž‘ì—…(max_wal_senders > 0 ì¸ê²½ìš°)ì€ wal_level ê°’ì´ \"replica\" ë˜" -"는 \"logical\" ì´ì–´ì•¼ 합니다." +msgid "operator does not exist: %s" +msgstr "ì—°ì‚°ìž ì—†ìŒ: %s" -#: postmaster/postmaster.c:881 +#: parser/parse_oper.c:224 #, c-format -msgid "%s: invalid datetoken tables, please fix\n" -msgstr "%s: ìž˜ëª»ëœ datetoken í…Œì´ë¸”들, 복구하십시오.\n" +msgid "Use an explicit ordering operator or modify the query." +msgstr "명시ì ìœ¼ë¡œ 순차연산ìž(ordering operator) 를 사용하ë˜ì§€, ë˜ëŠ” query 를 수정하ë„ë¡ í•˜ì„¸ìš”." -#: postmaster/postmaster.c:973 postmaster/postmaster.c:1071 -#: utils/init/miscinit.c:1429 +#: parser/parse_oper.c:480 #, c-format -msgid "invalid list syntax in parameter \"%s\"" -msgstr "\"%s\" 매개 변수 êµ¬ë¬¸ì´ ìž˜ëª» ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "operator requires run-time type coercion: %s" +msgstr "ì´ ì—°ì‚°ìžëŠ” ì‹¤í–‰ì‹œì— í˜• ê°•ì œì „í™”ì´ í•„ìš”í•©ë‹ˆë‹¤: %s" -#: postmaster/postmaster.c:1004 +#: parser/parse_oper.c:716 #, c-format -msgid "could not create listen socket for \"%s\"" -msgstr "\"%s\" ì‘당 ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" +msgid "operator is not unique: %s" +msgstr "ì—°ì‚°ìžê°€ 고유하지 않습니다: %s" -#: postmaster/postmaster.c:1010 +#: parser/parse_oper.c:718 #, c-format -msgid "could not create any TCP/IP sockets" -msgstr "TCP/IP ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다." +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "가장 ì ë‹¹í•œ ì—°ì‚°ìžë¥¼ ì„ íƒí•  수 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1093 +#: parser/parse_oper.c:727 #, c-format -msgid "could not create Unix-domain socket in directory \"%s\"" -msgstr "\"%s\" ë””ë ‰í„°ë¦¬ì— ìœ ë‹‰ìŠ¤ ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž 형ì‹ê³¼ ì¼ì¹˜í•˜ëŠ” ì—°ì‚°ìžê°€ 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1099 +#: parser/parse_oper.c:729 #, c-format -msgid "could not create any Unix-domain sockets" -msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "ì§€ì •ëœ ì´ë¦„ ë° ì¸ìž 형ì‹ê³¼ ì¼ì¹˜í•˜ëŠ” ì—°ì‚°ìžê°€ 없습니다. ëª…ì‹œì  í˜•ë³€í™˜ìžë¥¼ 추가해야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1111 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format -msgid "no socket created for listening" -msgstr "서버 ì ‘ì† ëŒ€ê¸° ìž‘ì—…ì„ ìœ„í•œ ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ" +msgid "operator is only a shell: %s" +msgstr "ì—°ì‚°ìžëŠ” ì…¸ì¼ ë¿ìž„: %s" -#: postmaster/postmaster.c:1151 +#: parser/parse_oper.c:900 #, c-format -msgid "could not create I/O completion port for child queue" -msgstr "하위 ëŒ€ê¸°ì—´ì— ëŒ€í•´ I/O 완료 í¬íŠ¸ë¥¼ 만들 수 ì—†ìŒ" +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) 는 ìš°ì¸¡ì— ë°°ì—´ì´ ìžˆì–´ì•¼ 합니다." -#: postmaster/postmaster.c:1180 +#: parser/parse_oper.c:942 #, c-format -msgid "%s: could not change permissions of external PID file \"%s\": %s\n" -msgstr "%s: \"%s\" 외부 PID 파ì¼ì˜ ì ‘ê·¼ ê¶Œí•œì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) 는 boolean ì„ ì–»ê¸° 위한 ì—°ì‚°ìžê°€ 필요합니다." -#: postmaster/postmaster.c:1184 +#: parser/parse_oper.c:947 #, c-format -msgid "%s: could not write external PID file \"%s\": %s\n" -msgstr "%s: 외부 pid íŒŒì¼ \"%s\" 를 쓸 수 ì—†ìŒ: %s\n" +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) 는 set ì„ return 하지 않는 ì—°ì‚°ìžê°€ 요구 ë©ë‹ˆë‹¤." -#: postmaster/postmaster.c:1234 +#: parser/parse_param.c:216 #, c-format -msgid "ending log output to stderr" -msgstr "stderr 쪽 로그 ì¶œë ¥ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." +msgid "inconsistent types deduced for parameter $%d" +msgstr "inconsistent types deduced for parameter $%d" -#: postmaster/postmaster.c:1235 +#: parser/parse_relation.c:176 #, c-format -msgid "Future log output will go to log destination \"%s\"." -msgstr "ìžì„¸í•œ 로그는 \"%s\" 쪽으로 기ë¡ë©ë‹ˆë‹¤." +msgid "table reference \"%s\" is ambiguous" +msgstr "í…Œì´ë¸” 참조 \"%s\" ê°€ 명확하지 않습니다 (ambiguous)." -#: postmaster/postmaster.c:1261 utils/init/postinit.c:213 +#: parser/parse_relation.c:220 #, c-format -msgid "could not load pg_hba.conf" -msgstr "pg_hba.conf를 로드할 수 ì—†ìŒ" +msgid "table reference %u is ambiguous" +msgstr "í…Œì´ë¸” 참조 %u ê°€ 명확하지 않습니다 (ambiguous)." -#: postmaster/postmaster.c:1287 +#: parser/parse_relation.c:419 #, c-format -msgid "postmaster became multithreaded during startup" -msgstr "" +msgid "table name \"%s\" specified more than once" +msgstr "í…Œì´ë¸” ì´ë¦„ \"%s\" ê°€ 한번 ì´ìƒ 명시ë˜ì–´ 있습니다." -#: postmaster/postmaster.c:1288 +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format -msgid "Set the LC_ALL environment variable to a valid locale." -msgstr "LC_ALL 환경 설정값으로 ì•Œë§žì€ ë¡œì¼€ì¼ ì´ë¦„ì„ ì§€ì •í•˜ì„¸ìš”." +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì„ ì‚¬ìš©í•˜ëŠ” FROM ì ˆì— ëŒ€í•œ 참조가 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1385 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format -msgid "%s: could not locate matching postgres executable" -msgstr "%s: 실행가능한 postgres í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ 없습니다" +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\" í…Œì´ë¸”ì— ëŒ€í•œ í•­ëª©ì´ ìžˆì§€ë§Œ ì´ ì¿¼ë¦¬ 부분ì—서 참조할 수 없습니다." -#: postmaster/postmaster.c:1408 utils/misc/tzparser.c:341 +#: parser/parse_relation.c:451 #, c-format -msgid "" -"This may indicate an incomplete PostgreSQL installation, or that the file " -"\"%s\" has been moved away from its proper location." +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "" -"ì´ ë¬¸ì œëŠ” PostgreSQL 설치가 불완전하게 ë˜ì—ˆê±°ë‚˜, \"%s\" 파ì¼ì´ 올바른 ìœ„ì¹˜ì— " -"있지 않아서 ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1436 +#: parser/parse_relation.c:727 #, c-format -msgid "data directory \"%s\" does not exist" -msgstr "\"%s\" ë°ì´í„° 디렉터리 ì—†ìŒ" +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "제약 ì¡°ê±´ì—서 참조하는 \"%s\" 시스템 ì¹¼ëŸ¼ì´ ì—†ìŒ" -#: postmaster/postmaster.c:1441 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 +#: parser/parse_relation.c:1936 #, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "\"%s\" 디렉터리 ì½ê¸° 권한 ì—†ìŒ: %m" +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "í…Œì´ë¸” \"%s\" ì—는 %d ê°œì˜ ì¹¼ëŸ¼ì´ ìžˆëŠ”ë°, %d ê°œì˜ ì¹¼ëŸ¼ë§Œ 명시ë˜ì—ˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1449 +#: parser/parse_relation.c:1173 #, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "지정한 \"%s\" ë°ì´í„° 디렉터리는 디렉터리가 아님" +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\"(ì´)ë¼ëŠ” WITH í•­ëª©ì´ ìžˆì§€ë§Œ ì´ ì¿¼ë¦¬ 부분ì—서 참조할 수 없습니다." -#: postmaster/postmaster.c:1465 +#: parser/parse_relation.c:1175 #, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "\"%s\" ë°ì´í„° 디렉터리 소유주가 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "WITH RECURSIVE를 사용하거나 WITH í•­ëª©ì˜ ìˆœì„œë¥¼ 변경하여 ì •ë°©í–¥ 참조를 제거하십시오." -#: postmaster/postmaster.c:1467 +#: parser/parse_relation.c:1486 #, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "서버는 지정한 ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ì†Œìœ ì£¼ 권한으로 시작ë˜ì–´ì•¼í•©ë‹ˆë‹¤." +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "ì—´ ì •ì˜ ë¦¬ìŠ¤íŠ¸ (column definition list) 는 오로지 \"record\" 를 리턴하는 함수 ë‚´ì—서만 허용ë©ë‹ˆë‹¤." -#: postmaster/postmaster.c:1487 +#: parser/parse_relation.c:1495 #, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "\"%s\" ë°ì´í„° 디렉터리 액세스 ê¶Œí•œì´ ìž˜ëª» ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "a column definition list is required for functions returning \"record\"" +msgstr "ì—´ ì •ì˜ ë¦¬ìŠ¤íŠ¸(column definition list)는 \"record\" 를 리턴하는 함수를 필요로 합니다" -#: postmaster/postmaster.c:1489 +#: parser/parse_relation.c:1575 #, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "액세스 ê¶Œí•œì€ u=rwx (0700) ê°’ì´ì–´ì•¼ 합니다." +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "FROM ì ˆ ë‚´ì˜ í•¨ìˆ˜ \"%s\" ì— ì§€ì›ë˜ì§€ 않는 return ìžë£Œí˜• %s ì´ ìžˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:1500 +#: parser/parse_relation.c:1764 #, c-format -msgid "" -"%s: could not find the database system\n" -"Expected to find it in the directory \"%s\",\n" -"but could not open file \"%s\": %s\n" -msgstr "" -"%s: ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì„ ì°¾ì„ ìˆ˜ 없습니다\n" -"\"%s\" 디렉터리 ì•ˆì— í•´ë‹¹ ìžë£Œê°€ 있기를 기대했는ë°,\n" -"\"%s\" 파ì¼ì„ ì—´ 수가 없었습니다: %s\n" +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUES ë’¤ì— ì˜¤ëŠ” \"%s\" 구문ì—는 %dê°œì˜ ì¹¼ëŸ¼ì´ ìžˆëŠ”ë°, 지정한 ì¹¼ëŸ¼ì€ %dê°œ 입니다" -#: postmaster/postmaster.c:1677 +#: parser/parse_relation.c:1819 #, c-format -msgid "select() failed in postmaster: %m" -msgstr "postmasterì—서 select() ìž‘ë™ ì‹¤íŒ¨: %m" +msgid "joins can have at most %d columns" +msgstr "ì¡°ì¸ì—는 최대 %dê°œì˜ ì¹¼ëŸ¼ì„ í¬í•¨í•  수 있ìŒ" -#: postmaster/postmaster.c:1828 +#: parser/parse_relation.c:1909 #, c-format -msgid "" -"performing immediate shutdown because data directory lock file is invalid" +msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "" -#: postmaster/postmaster.c:1906 postmaster/postmaster.c:1937 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 +#: parser/parse_relation.c:3011 #, c-format -msgid "incomplete startup packet" -msgstr "ì•„ì§ ì™„ë£Œë˜ì§€ ì•Šì€ ì‹œìž‘ 패킷" +msgid "column %d of relation \"%s\" does not exist" +msgstr "%d번째 ì¹¼ëŸ¼ì´ ì—†ìŠµë‹ˆë‹¤. 해당 릴레ì´ì…˜: \"%s\"" -#: postmaster/postmaster.c:1918 +#: parser/parse_relation.c:3230 #, c-format -msgid "invalid length of startup packet" -msgstr "시작 íŒ¨í‚·ì˜ ê¸¸ì´ê°€ 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "ì•„ \"%s\" alias를 참조해야 í•  것 같습니다." -#: postmaster/postmaster.c:1976 +#: parser/parse_relation.c:3238 #, c-format -msgid "failed to send SSL negotiation response: %m" -msgstr "SSL ì—°ê²° ìž‘ì—…ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤: %m" +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "í…Œì´ë¸” \"%s\"ì— FROM ì ˆì´ ë¹ ì ¸ 있습니다." -#: postmaster/postmaster.c:2005 +#: parser/parse_relation.c:3290 #, c-format -msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" -msgstr "" -"ì§€ì›í•˜ì§€ 않는 frontend 프로토콜 %u.%u: 서버ì—서 ì§€ì›í•˜ëŠ” 프로토콜 %u.0 .. %u." -"%u" +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "아마 \"%s.%s\" ì¹¼ëŸ¼ì„ ì°¸ì¡°í•˜ëŠ” 것 같습니다." -#: postmaster/postmaster.c:2068 utils/misc/guc.c:5660 utils/misc/guc.c:5753 -#: utils/misc/guc.c:7051 utils/misc/guc.c:9805 utils/misc/guc.c:9839 +#: parser/parse_relation.c:3292 #, c-format -msgid "invalid value for parameter \"%s\": \"%s\"" -msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: \"%s\"" +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\" ì´ë¦„ì˜ ì¹¼ëŸ¼ì´ \"%s\" í…Œì´ë¸”ì— ìžˆì§€ë§Œ, ì´ ì¿¼ë¦¬ì˜ ì´ ë¶€ë¶„ì—서는 ì°¸ì¡°ë  ìˆ˜ 없습니다." -#: postmaster/postmaster.c:2071 +#: parser/parse_relation.c:3309 #, c-format -msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." -msgstr "" +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "아마 \"%s.%s\" 칼럼ì´ë‚˜ \"%s.%s\" ì¹¼ëŸ¼ì„ ì°¸ì¡°í•˜ëŠ” 것 같습니다." -#: postmaster/postmaster.c:2091 +#: parser/parse_target.c:483 parser/parse_target.c:784 #, c-format -msgid "invalid startup packet layout: expected terminator as last byte" -msgstr "ìž˜ëª»ëœ ì‹œìž‘ 패킷 ë ˆì´ì•„웃: 마지막 ë°”ì´íŠ¸ë¡œ 종결문ìžê°€ 발견ë˜ì—ˆìŒ" +msgid "cannot assign to system column \"%s\"" +msgstr "시스템 ì—´ \"%s\"ì— í• ë‹¹í•  수 없습니다." -#: postmaster/postmaster.c:2119 +#: parser/parse_target.c:511 #, c-format -msgid "no PostgreSQL user name specified in startup packet" -msgstr "시작 패킷ì—서 지정한 사용ìžëŠ” PostgreSQL ì‚¬ìš©ìž ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "cannot set an array element to DEFAULT" +msgstr "ë°°ì—´ 요소를 DEFAULT 로 설정할 수 없습니다." -#: postmaster/postmaster.c:2178 +#: parser/parse_target.c:516 #, c-format -msgid "the database system is starting up" -msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ìƒˆë¡œ ê°€ë™ ì¤‘ìž…ë‹ˆë‹¤." +msgid "cannot set a subfield to DEFAULT" +msgstr "하위필드를 DEFAULT로 설정할 수 없습니다." -#: postmaster/postmaster.c:2183 +#: parser/parse_target.c:585 #, c-format -msgid "the database system is shutting down" -msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì¤‘ì§€ 중입니다" +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "ì—´ \"%s\"ì€(는) %s ìžë£Œí˜•ì¸ë° 표현ì‹ì€ %s ìžë£Œí˜•입니다." -#: postmaster/postmaster.c:2188 +#: parser/parse_target.c:768 #, c-format -msgid "the database system is in recovery mode" -msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ìžë™ 복구 작업 중입니다." +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "\"%s\" 필드 (ëŒ€ìƒ ì—´ \"%s\")를 지정할 수 ì—†ìŒ, %s ìžë£Œí˜•ì€ ë³µí•©ìžë£Œí˜•ì´ ì•„ë‹ˆê¸° 때문" -#: postmaster/postmaster.c:2193 storage/ipc/procarray.c:297 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:340 +#: parser/parse_target.c:777 #, c-format -msgid "sorry, too many clients already" -msgstr "최대 ë™ì‹œ ì ‘ì†ìž 수를 초과했습니다." +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "\"%s\" 필드 (ëŒ€ìƒ ì—´ \"%s\")를 지정할 수 ì—†ìŒ, %s ìžë£Œí˜•ì—서 그런 ì¹¼ëŸ¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: postmaster/postmaster.c:2255 +#: parser/parse_target.c:854 #, c-format -msgid "wrong key in cancel request for process %d" -msgstr "프로세스 %dì— ëŒ€í•œ 취소 ìš”ì²­ì— ìž˜ëª»ëœ í‚¤ê°€ 있ìŒ" +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "\"%s\" ì—´ì— ì‚¬ìš©ëœ ìžë£Œí˜•ì€ %s ê°€ 필요하지만, 현재 표현ì‹ì´ %s ìžë£Œí˜•입니다" -#: postmaster/postmaster.c:2263 +#: parser/parse_target.c:864 #, c-format -msgid "PID %d in cancel request did not match any process" -msgstr "취소 ìš”ì²­ì˜ PID %dê³¼(와) ì¼ì¹˜í•˜ëŠ” 프로세스가 ì—†ìŒ" +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "하위필드 \"%s\" 는 %s ìžë£Œí˜•ì¸ë° 표현ì‹ì€ %s ìžë£Œí˜•입니다." -#: postmaster/postmaster.c:2483 +#: parser/parse_target.c:1283 #, c-format -msgid "received SIGHUP, reloading configuration files" -msgstr "SIGHUP 신호를 받아서, 환경설정파ì¼ì„ 다시 ì½ê³  있습니다." +msgid "SELECT * with no tables specified is not valid" +msgstr "í…Œì´ë¸”ì´ ëª…ì‹œë˜ì§€ ì•Šì€ SELECT * êµ¬ë¬¸ì€ ìœ íš¨í•˜ì§€ 않습니다." -#: postmaster/postmaster.c:2508 +#: parser/parse_type.c:83 #, c-format -msgid "pg_hba.conf not reloaded" -msgstr "pg_hba.confê°€ 다시 로드ë˜ì§€ 않ìŒ" +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "ì ì ˆí•˜ì§€ ì•Šì€ %%TYPE reference 입니다 (dotted name ì´ ë„ˆë¬´ ì ìŠµë‹ˆë‹¤): %s" -#: postmaster/postmaster.c:2512 +#: parser/parse_type.c:105 #, c-format -msgid "pg_ident.conf not reloaded" -msgstr "pg_ident.conf 파ì¼ì´ 다시 로드ë˜ì§€ 않ìŒ" +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "ì ì ˆí•˜ì§€ ì•Šì€ %%TYPE reference 입니다 (dotted name ì´ ë„ˆë¬´ 많습니다): %s" -#: postmaster/postmaster.c:2553 +#: parser/parse_type.c:140 #, c-format -msgid "received smart shutdown request" -msgstr "smart 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." +msgid "type reference %s converted to %s" +msgstr "ype reference %s ê°€ %s 로 변환ë˜ì—ˆìŠµë‹ˆë‹¤." -#: postmaster/postmaster.c:2608 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format -msgid "received fast shutdown request" -msgstr "fast 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." - -#: postmaster/postmaster.c:2638 +msgid "type \"%s\" is only a shell" +msgstr "ìžë£Œí˜• \"%s\" 는 오로지 shell ì—ë§Œ 있습니다. " + +#: parser/parse_type.c:346 #, c-format -msgid "aborting any active transactions" -msgstr "모든 활성화 ë˜ì–´ìžˆëŠ” íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•˜ê³  있습니다." +msgid "type modifier is not allowed for type \"%s\"" +msgstr "\"%s\" 형ì‹ì—는 í˜•ì‹ í•œì •ìžë¥¼ 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:2672 +#: parser/parse_type.c:388 #, c-format -msgid "received immediate shutdown request" -msgstr "immediate 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." +msgid "type modifiers must be simple constants or identifiers" +msgstr "ìžë£Œí˜• 한정ìžëŠ” 단순 ìƒìˆ˜ ë˜ëŠ” ì‹ë³„ìžì—¬ì•¼ 함" -#: postmaster/postmaster.c:2736 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format -msgid "shutdown at recovery target" -msgstr "복구 타겟ì—서 중지함" +msgid "invalid type name \"%s\"" +msgstr "\"%s\" ìžë£Œí˜• ì´ë¦„ì€ ìœ íš¨í•˜ì§€ ì•Šì€ ìžë£Œí˜•입니다." -#: postmaster/postmaster.c:2752 postmaster/postmaster.c:2775 -msgid "startup process" -msgstr "시작 프로세스" +#: parser/parse_utilcmd.c:272 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "ìƒì† 하위 í…Œì´ë¸”로 íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: postmaster/postmaster.c:2755 +#: parser/parse_utilcmd.c:448 #, c-format -msgid "aborting startup due to startup process failure" -msgstr "시작 프로세스 실패 ë•Œë¬¸ì— ì„œë²„ ì‹œìž‘ì´ ì¤‘ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s 명령으로 \"%s\" 시퀀스가 ìžë™ìœ¼ë¡œ ë§Œë“¤ì–´ì§ (\"%s.%s\" serial ì—´ 때문)" -#: postmaster/postmaster.c:2816 +#: parser/parse_utilcmd.c:571 #, c-format -msgid "database system is ready to accept connections" -msgstr "ì´ì œ ë°ì´í„°ë² ì´ìФ 서버로 ì ‘ì†í•  수 있습니다" +msgid "array of serial is not implemented" +msgstr "serial ë°°ì—´ì´ êµ¬í˜„ë˜ì§€ 않ìŒ" -#: postmaster/postmaster.c:2835 -msgid "background writer process" -msgstr "백그ë¼ìš´ë“œ writer 프로세스" +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "NULL/NOT NULL ì„ ì–¸ì´ ì„œë¡œ ì¶©ëŒí•©ë‹ˆë‹¤ : column \"%s\" of table \"%s\"" -#: postmaster/postmaster.c:2889 -msgid "checkpointer process" -msgstr "ì²´í¬í¬ì¸íЏ 프로세스" +#: parser/parse_utilcmd.c:671 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" í…Œì´ë¸”)ì— ëŒ€í•´ 여러 ê°œì˜ ê¸°ë³¸ ê°’ì´ ì§€ì •ë¨" -#: postmaster/postmaster.c:2905 -msgid "WAL writer process" -msgstr "WAL 쓰기 프로세스" +#: parser/parse_utilcmd.c:688 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "ì‹ë³„ ì¹¼ëŸ¼ì€ íƒ€ìž…ë“œ í…Œì´ë¸”(typed table - ìžë£Œí˜•ìœ¼ë¡œì¨ í…Œì´ë¸”)ì—서는 쓸 수 ì—†ìŒ" -#: postmaster/postmaster.c:2919 -msgid "WAL receiver process" -msgstr "WAL 수신 프로세스" +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "ì‹ë³„ ì¹¼ëŸ¼ì€ íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:2934 -msgid "autovacuum launcher process" -msgstr "autovacuum 실행기 프로세스" +#: parser/parse_utilcmd.c:701 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" í…Œì´ë¸”)ì— ëŒ€í•´ 여러 ê°œì˜ ì‹ë³„ìž ì§€ì •ì´ ì‚¬ìš©ë˜ì—ˆìŒ" -#: postmaster/postmaster.c:2949 -msgid "archiver process" -msgstr "archiver 프로세스" +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "기본키 제약 ì¡°ê±´ì„ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:2965 -msgid "statistics collector process" -msgstr "통계 수집기 프로세스" +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "ìœ ë‹ˆí¬ ì œì•½ ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:2979 -msgid "system logger process" -msgstr "시스템 로그 프로세스" +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "참조키 제약 ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:3041 -msgid "worker process" -msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤" +#: parser/parse_utilcmd.c:778 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "\"%s\" 칼럼(\"%s\" í…Œì´ë¸”)ì— ëŒ€í•´ default와 ì‹ë³„ìž ì •ì˜ê°€ 함께 있ìŒ" -#: postmaster/postmaster.c:3124 postmaster/postmaster.c:3144 -#: postmaster/postmaster.c:3151 postmaster/postmaster.c:3169 -msgid "server process" -msgstr "서버 프로세스" +#: parser/parse_utilcmd.c:843 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "제외 제약 ì¡°ê±´ì€ ì™¸ë¶€ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:3223 +#: parser/parse_utilcmd.c:849 #, c-format -msgid "terminating any other active server processes" -msgstr "다른 활성화 ë˜ì–´ìžˆëŠ” 서버 프로세스를 마치고 있는 중입니다" +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "제외 제약 ì¡°ê±´ì€ íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì—서는 사용할 수 ì—†ìŒ" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3479 +#: parser/parse_utilcmd.c:913 #, c-format -msgid "%s (PID %d) exited with exit code %d" -msgstr "%s (PID %d) í”„ë¡œê·¸ëž¨ì€ %d 코드로 마쳤습니다" +msgid "LIKE is not supported for creating foreign tables" +msgstr "외부 í…Œì´ë¸”ì„ ë§Œë“¤ 때는 LIKE ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" -#: postmaster/postmaster.c:3481 postmaster/postmaster.c:3492 -#: postmaster/postmaster.c:3503 postmaster/postmaster.c:3512 -#: postmaster/postmaster.c:3522 +#: parser/parse_utilcmd.c:1518 parser/parse_utilcmd.c:1625 #, c-format -msgid "Failed process was running: %s" +msgid "Index \"%s\" contains a whole-row table reference." msgstr "" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3489 +#: parser/parse_utilcmd.c:1975 #, c-format -msgid "%s (PID %d) was terminated by exception 0x%X" -msgstr "%s (PID %d) 프로세스가 0x%X 예외로 ì¸í•´ 종료ë¨" +msgid "cannot use an existing index in CREATE TABLE" +msgstr "" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3499 +#: parser/parse_utilcmd.c:1995 #, c-format -msgid "%s (PID %d) was terminated by signal %d: %s" -msgstr "%s (PID %d) 프로세스가 %d번 시그ë„ì„ ë°›ì•„ 종료ë¨: %s" +msgid "index \"%s\" is already associated with a constraint" +msgstr "" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3510 +#: parser/parse_utilcmd.c:2003 #, c-format -msgid "%s (PID %d) was terminated by signal %d" -msgstr "%s (PID %d) 프로세스가 %d번 시그ë„ì„ ë°›ì•„ 종료ë¨" +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "\"%s\" ì¸ë±ìŠ¤ê°€ \"%s\" í…Œì´ë¸”ìš©ì´ ì•„ë‹˜" -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3520 +#: parser/parse_utilcmd.c:2010 #, c-format -msgid "%s (PID %d) exited with unrecognized status %d" -msgstr "%s (PID %d) 프로세스가 ì¸ì‹í•  수 없는 %d ìƒíƒœë¡œ 종료ë¨" +msgid "index \"%s\" is not valid" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 사용가능 ìƒíƒœê°€ 아님" -#: postmaster/postmaster.c:3707 +#: parser/parse_utilcmd.c:2016 #, c-format -msgid "abnormal database system shutdown" -msgstr "비정ìƒì ì¸ ë°ì´í„°ë² ì´ìФ 시스템 서비스를 중지" +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" 개체는 ìœ ë‹ˆí¬ ì¸ë±ìŠ¤ê°€ 아닙니다" -#: postmaster/postmaster.c:3747 +#: parser/parse_utilcmd.c:2017 parser/parse_utilcmd.c:2024 +#: parser/parse_utilcmd.c:2031 parser/parse_utilcmd.c:2103 #, c-format -msgid "all server processes terminated; reinitializing" -msgstr "모든 서버 프로세스가 중지 ë˜ì—ˆìŠµë‹ˆë‹¤; 재 초기화 중" +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "" -#: postmaster/postmaster.c:3959 +#: parser/parse_utilcmd.c:2023 #, c-format -msgid "could not fork new process for connection: %m" -msgstr "ì—°ê²°ì„ ìœ„í•œ 새 프로세스 할당(fork) 실패: %m" - -#: postmaster/postmaster.c:4001 -msgid "could not fork new process for connection: " -msgstr "ì—°ê²°ì„ ìœ„í•œ 새 프로세스 할당(fork) 실패: " +msgid "index \"%s\" contains expressions" +msgstr "\"%s\" ì¸ë±ìŠ¤ì— í‘œí˜„ì‹ì´ í¬í•¨ë˜ì–´ 있ìŒ" -#: postmaster/postmaster.c:4115 +#: parser/parse_utilcmd.c:2030 #, c-format -msgid "connection received: host=%s port=%s" -msgstr "ì ‘ì† ìˆ˜ë½: host=%s port=%s" +msgid "\"%s\" is a partial index" +msgstr "\"%s\" 개체는 부분 ì¸ë±ìŠ¤ìž„" -#: postmaster/postmaster.c:4120 +#: parser/parse_utilcmd.c:2042 #, c-format -msgid "connection received: host=%s" -msgstr "ì ‘ì† ìˆ˜ë½: host=%s" +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" 개체는 지연가능한 ì¸ë±ìŠ¤ìž„" -#: postmaster/postmaster.c:4403 +#: parser/parse_utilcmd.c:2043 #, c-format -msgid "could not execute server process \"%s\": %m" -msgstr "\"%s\" 서버 프로세스를 실행할 수 ì—†ìŒ: %m" +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "" -#: postmaster/postmaster.c:4947 +#: parser/parse_utilcmd.c:2102 #, c-format -msgid "database system is ready to accept read only connections" -msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì½ê¸° 전용으로 ì—°ê²°ì„ ìˆ˜ë½í•  준비가 ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "index \"%s\" does not have default sorting behavior" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 기본 ì •ë ¬ ë°©ë²•ì´ ì—†ìŒ" -#: postmaster/postmaster.c:5238 +#: parser/parse_utilcmd.c:2251 #, c-format -msgid "could not fork startup process: %m" -msgstr "시작 프로세스 할당(fork) 실패: %m" +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "기본키 제약 ì¡°ê±´ì—서 \"%s\" ì¹¼ëŸ¼ì´ ë‘ ë²ˆ 지정ë˜ì—ˆìŠµë‹ˆë‹¤" -#: postmaster/postmaster.c:5242 +#: parser/parse_utilcmd.c:2257 #, c-format -msgid "could not fork background writer process: %m" -msgstr "백그ë¼ìš´ writer 프로세스를 할당(fork)í•  수 없습니다: %m" +msgid "column \"%s\" appears twice in unique constraint" +msgstr "고유 제약 ì¡°ê±´ì—서 \"%s\" ì¹¼ëŸ¼ì´ ë‘ ë²ˆ 지정ë˜ì—ˆìŠµë‹ˆë‹¤" -#: postmaster/postmaster.c:5246 +#: parser/parse_utilcmd.c:2580 #, c-format -msgid "could not fork checkpointer process: %m" -msgstr "ì²´í¬í¬ì¸íЏ 프로세스를 할당(fork)í•  수 없습니다: %m" +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "ì¸ë±ìФ ì‹ ë° ìˆ ì–´ëŠ” ì¸ë±ì‹±ë˜ëŠ” í…Œì´ë¸”ë§Œ 참조할 수 있ìŒ" -#: postmaster/postmaster.c:5250 +#: parser/parse_utilcmd.c:2626 #, c-format -msgid "could not fork WAL writer process: %m" -msgstr "WAL 쓰기 프로세스를 할당(fork)í•  수 ì—†ìŒ: %m" +msgid "rules on materialized views are not supported" +msgstr "êµ¬ì²´í™”ëœ ë·°ì—ì„œì˜ ë£°ì€ ì§€ì›í•˜ì§€ 않ìŒ" -#: postmaster/postmaster.c:5254 +#: parser/parse_utilcmd.c:2687 #, c-format -msgid "could not fork WAL receiver process: %m" -msgstr "WAL 수신 프로세스를 할당(fork)í•  수 ì—†ìŒ: %m" +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "룰ì—서 지정한 WHERE ì¡°ê±´ì— ë‹¤ë¥¸ 릴레ì´ì…˜ì— 대한 참조를 í¬í•¨í•  수 ì—†ìŒ" -#: postmaster/postmaster.c:5258 +#: parser/parse_utilcmd.c:2759 #, c-format -msgid "could not fork process: %m" -msgstr "프로세스 할당(fork) 실패: %m" +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "룰ì—서 지정한 WHERE ì¡°ê±´ì´ ìžˆëŠ” 규칙ì—는 SELECT, INSERT, UPDATE ë˜ëŠ” DELETE 작업만 í¬í•¨í•  수 있ìŒ" -#: postmaster/postmaster.c:5420 postmaster/postmaster.c:5443 +#: parser/parse_utilcmd.c:2777 parser/parse_utilcmd.c:2876 +#: rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 #, c-format -msgid "database connection requirement not indicated during registration" -msgstr "" +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "conditional UNION/INTERSECT/EXCEPT êµ¬ë¬¸ì€ êµ¬í˜„ë˜ì–´ 있지 않다" -#: postmaster/postmaster.c:5427 postmaster/postmaster.c:5450 +#: parser/parse_utilcmd.c:2795 #, c-format -msgid "invalid processing mode in background worker" -msgstr "백그ë¼ìš´ë“œ 작업ìžì—서 ìž˜ëª»ëœ í”„ë¡œì„¸ì‹± 모드가 사용ë¨" +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECT ë£°ì€ OLD를 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:5502 +#: parser/parse_utilcmd.c:2799 #, c-format -msgid "starting background worker process \"%s\"" -msgstr "\"%s\" 백그ë¼ìš´ë“œ ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 시작합니다." +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECT ë£°ì€ NEW를 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:5513 +#: parser/parse_utilcmd.c:2808 #, c-format -msgid "could not fork worker process: %m" -msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 할당(fork)í•  수 ì—†ìŒ: %m" +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERT ë£°ì€ OLD를 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:5901 +#: parser/parse_utilcmd.c:2814 #, c-format -msgid "could not duplicate socket %d for use in backend: error code %d" -msgstr "백엔드ì—서 사용하기 위해 %d ì†Œì¼“ì„ ë³µì‚¬í•  수 ì—†ìŒ: 오류 코드 %d" +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETE ë£°ì€ NEW를 사용할 수 ì—†ìŒ" -#: postmaster/postmaster.c:5933 +#: parser/parse_utilcmd.c:2842 #, c-format -msgid "could not create inherited socket: error code %d\n" -msgstr "ìƒì†ëœ ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ: 오류 코드 %d\n" +msgid "cannot refer to OLD within WITH query" +msgstr "" -#: postmaster/postmaster.c:5962 +#: parser/parse_utilcmd.c:2849 #, c-format -msgid "could not open backend variables file \"%s\": %s\n" -msgstr "\"%s\" 백엔드 변수 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" +msgid "cannot refer to NEW within WITH query" +msgstr "" -#: postmaster/postmaster.c:5969 +#: parser/parse_utilcmd.c:3287 #, c-format -msgid "could not read from backend variables file \"%s\": %s\n" -msgstr "\"%s\" 백엔드 변수 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" +msgid "misplaced DEFERRABLE clause" +msgstr "DEFERABLE ì ˆì´ ìž˜ëª» 놓여져 있습니다" -#: postmaster/postmaster.c:5978 +#: parser/parse_utilcmd.c:3292 parser/parse_utilcmd.c:3307 #, c-format -msgid "could not remove file \"%s\": %s\n" -msgstr "\"%s\" 파ì¼ì„ 삭제할 수 ì—†ìŒ: %s\n" +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "여러 ê°œì˜ DEFERRABLE/NOT DEFERRABLEì ˆì€ ì‚¬ìš©í•  수 없습니다" -#: postmaster/postmaster.c:5995 +#: parser/parse_utilcmd.c:3302 #, c-format -msgid "could not map view of backend variables: error code %lu\n" -msgstr "백엔드 변수 파ì¼ì˜ view를 mapí•  수 ì—†ìŒ: 오류 코드 %lu\n" +msgid "misplaced NOT DEFERRABLE clause" +msgstr "NOT DEFERABLE ì ˆì´ ìž˜ëª» 놓여 있습니다" -#: postmaster/postmaster.c:6004 +#: parser/parse_utilcmd.c:3323 #, c-format -msgid "could not unmap view of backend variables: error code %lu\n" -msgstr "백엔드 변수 파ì¼ì˜ view를 unmapí•  수 ì—†ìŒ: 오류 코드 %lu\n" +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "INITIALLY DEFERRED ì ˆì´ ìž˜ëª» 놓여 있습니다" -#: postmaster/postmaster.c:6011 +#: parser/parse_utilcmd.c:3328 parser/parse_utilcmd.c:3354 #, c-format -msgid "could not close handle to backend parameter variables: error code %lu\n" -msgstr "백엔드 변수 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: 오류 코드 %lu\n" +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "여러 ê°œì˜ INITIALLY IMMEDIATE/DEFERRED ì ˆì€ í—ˆìš©ë˜ì§€ 않습니다" -#: postmaster/postmaster.c:6172 +#: parser/parse_utilcmd.c:3349 #, c-format -msgid "could not read exit code for process\n" -msgstr "í”„ë¡œì„¸ìŠ¤ì˜ ì¢…ë£Œ 코드를 ì½ì„ 수 ì—†ìŒ\n" +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "INITIALLY IMMEDIATE ì ˆì´ ìž˜ëª» 놓여 있습니다" -#: postmaster/postmaster.c:6177 +#: parser/parse_utilcmd.c:3540 #, c-format -msgid "could not post child completion status\n" -msgstr "하위 완료 ìƒíƒœë¥¼ 게시할 수 ì—†ìŒ\n" +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE êµ¬ë¬¸ì— ëª…ì‹œëœ schema (%s) ê°€ ìƒì„±ëœ (%s) ì˜ ê²ƒê³¼ 다릅니다" -#: postmaster/syslogger.c:441 postmaster/syslogger.c:1041 +#: parser/parse_utilcmd.c:3574 #, c-format -msgid "could not read from logger pipe: %m" -msgstr "로그 파ì´í”„ì—서 ì½ê¸° 실패: %m" +msgid "table \"%s\" is not partitioned" +msgstr "\"%s\" í…Œì´ë¸”ì€ íŒŒí‹°ì…˜ ëœ í…Œì´ë¸”ì´ ì•„ë‹˜" -#: postmaster/syslogger.c:490 +#: parser/parse_utilcmd.c:3581 #, c-format -msgid "logger shutting down" -msgstr "로그 작업 ë내는 중" +msgid "index \"%s\" is not partitioned" +msgstr "\"%s\" ì¸ë±ìŠ¤ëŠ” 파티션 ëœ ì¸ë±ìŠ¤ê°€ 아님" -#: postmaster/syslogger.c:534 postmaster/syslogger.c:548 +#: parser/parse_utilcmd.c:3615 #, c-format -msgid "could not create pipe for syslog: %m" -msgstr "syslogì—서 사용할 파ì´í”„를 만들 수 없습니다: %m" +msgid "a hash-partitioned table may not have a default partition" +msgstr "해시 íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì€ ê¸°ë³¸ íŒŒí‹°ì…˜ì„ ê°€ì§ˆ 수 ì—†ìŒ" -#: postmaster/syslogger.c:584 +#: parser/parse_utilcmd.c:3632 #, c-format -msgid "could not fork system logger: %m" -msgstr "시스템 로거(logger)를 확보하질 못 했습니다: %m" +msgid "invalid bound specification for a hash partition" +msgstr "해시 파티션용 범위 명세가 잘못ë¨" -#: postmaster/syslogger.c:620 +#: parser/parse_utilcmd.c:3638 partitioning/partbounds.c:2127 #, c-format -msgid "redirecting log output to logging collector process" +msgid "modulus for hash partition must be a positive integer" msgstr "" -#: postmaster/syslogger.c:621 +#: parser/parse_utilcmd.c:3645 partitioning/partbounds.c:2135 #, c-format -msgid "Future log output will appear in directory \"%s\"." -msgstr "" +msgid "remainder for hash partition must be less than modulus" +msgstr "해시 파티션용 나머지 처리기는 modulus 보다 작아야 함" -#: postmaster/syslogger.c:629 +#: parser/parse_utilcmd.c:3657 #, c-format -msgid "could not redirect stdout: %m" -msgstr "í‘œì¤€ì¶œë ¥ì„ redirect 하지 못했습니다: %m" +msgid "invalid bound specification for a list partition" +msgstr "list íŒŒí‹°ì…˜ì„ ìœ„í•œ 범위 ì„¤ì •ì´ ìž˜ëª»ë¨" -#: postmaster/syslogger.c:634 postmaster/syslogger.c:651 +#: parser/parse_utilcmd.c:3713 #, c-format -msgid "could not redirect stderr: %m" -msgstr "표준오류(stderr)를 redirect 하지 못했습니다: %m" +msgid "invalid bound specification for a range partition" +msgstr "range íŒŒí‹°ì…˜ì„ ìœ„í•œ 범위 ì„¤ì •ì´ ìž˜ëª»ë¨" -#: postmaster/syslogger.c:996 +#: parser/parse_utilcmd.c:3719 #, c-format -msgid "could not write to log file: %s\n" -msgstr "ë¡œê·¸íŒŒì¼ ì“°ê¸° 실패: %s\n" +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROMì—는 파티션 칼럼 당 ë”± í•˜ë‚˜ì˜ ê°’ë§Œ 지정해야 함" -#: postmaster/syslogger.c:1136 +#: parser/parse_utilcmd.c:3723 #, c-format -msgid "could not open log file \"%s\": %m" -msgstr "\"%s\" 잠금파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "TO must specify exactly one value per partitioning column" +msgstr "TOì—는 파티션 칼럼 당 ë”± í•˜ë‚˜ì˜ ê°’ë§Œ 지정해야 함" -#: postmaster/syslogger.c:1198 postmaster/syslogger.c:1242 +#: parser/parse_utilcmd.c:3770 parser/parse_utilcmd.c:3784 #, c-format -msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgid "cannot specify NULL in range bound" +msgstr "range 범위ì—는 NULL ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" + +#: parser/parse_utilcmd.c:3831 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" msgstr "" -"ë¡œê·¸íŒŒì¼ ìžë™ êµì²´ ê¸°ëŠ¥ì„ ê¸ˆì§€í•©ë‹ˆë‹¤(êµì²´í•˜ë ¤ë©´ SIGHUP 시그ë„ì„ ì‚¬ìš©í•¨)" -#: regex/regc_pg_locale.c:261 +#: parser/parse_utilcmd.c:3838 #, c-format -msgid "could not determine which collation to use for regular expression" -msgstr "ì •ê·œì‹ì„ 사용해서 사용할 정렬규칙(collation)ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "" -#: replication/basebackup.c:232 +#: parser/parse_utilcmd.c:3869 parser/parse_utilcmd.c:3881 #, c-format -msgid "could not stat control file \"%s\": %m" -msgstr "\"%s\" 컨트롤 파ì¼ì˜ 정보를 구할 수 ì—†ìŒ: %m" +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "ì§€ì •ëœ ê°’ì€ %s 형으로 형변환 í•  수 ì—†ìŒ, 해당 칼럼: \"%s\"" -#: replication/basebackup.c:341 +#: parser/parse_utilcmd.c:3883 #, c-format -msgid "could not find any WAL files" -msgstr "ì–´ë–¤ WAL 파ì¼ë„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "The cast requires a non-immutable conversion." +msgstr "í˜•ë³€í™˜ì€ non-immutable ë³€í™˜ì´ í•„ìš”í•¨" -#: replication/basebackup.c:354 replication/basebackup.c:368 -#: replication/basebackup.c:377 +#: parser/parse_utilcmd.c:3884 #, c-format -msgid "could not find WAL file \"%s\"" -msgstr "\"%s\" WAL íŒŒì¼ ì°¾ê¸° 실패" +msgid "Try putting the literal value in single quotes." +msgstr "" -#: replication/basebackup.c:416 replication/basebackup.c:442 +#: parser/scansup.c:204 #, c-format -msgid "unexpected WAL file size \"%s\"" -msgstr "\"%s\" WAL 파ì¼ì˜ í¬ê¸°ê°€ 알맞지 않ìŒ" +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "\"%s\" ì‹ë³„ìžëŠ” \"%s\"(으)로 잘림" -#: replication/basebackup.c:428 replication/basebackup.c:1160 +#: partitioning/partbounds.c:331 #, c-format -msgid "base backup could not send data, aborting backup" -msgstr "ë² ì´ìФ 백업ì—서 ìžë£Œë¥¼ 보낼 수 ì—†ìŒ. ë°±ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "\"%s\" íŒŒí‹°ì…˜ì´ \"%s\" 기본 파티션과 겹칩니다." -#: replication/basebackup.c:530 replication/basebackup.c:539 -#: replication/basebackup.c:548 replication/basebackup.c:557 -#: replication/basebackup.c:566 replication/basebackup.c:577 -#: replication/basebackup.c:594 +#: partitioning/partbounds.c:390 #, c-format -msgid "duplicate option \"%s\"" -msgstr "\"%s\" ì˜µì…˜ì„ ë‘ ë²ˆ 지정했습니다" +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "" -#: replication/basebackup.c:583 utils/misc/guc.c:5670 +#: partitioning/partbounds.c:486 #, c-format -msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgid "empty range bound specified for partition \"%s\"" msgstr "" -"%d ê°’ì€ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ìœ¼ë¡œ 타당한 범위(%d .. %d)를 벗어났습니다." -#: replication/basebackup.c:857 replication/basebackup.c:959 +#: partitioning/partbounds.c:488 #, c-format -msgid "could not stat file or directory \"%s\": %m" -msgstr "íŒŒì¼ ë˜ëŠ” 디렉터리 \"%s\"ì˜ ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "하한값(%s)ì€ ìƒí•œê°’(%s)ê³¼ 같거나 커야 합니다" -#: replication/basebackup.c:1112 +#: partitioning/partbounds.c:585 #, c-format -msgid "skipping special file \"%s\"" -msgstr "\"%s\" 특수 파ì¼ì„ 건너뜀" +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "\"%s\" íŒŒí‹°ì…˜ì´ \"%s\" 파티션과 겹칩니다." -#: replication/basebackup.c:1223 +#: partitioning/partbounds.c:685 #, c-format -msgid "file name too long for tar format: \"%s\"" -msgstr "tar 파ì¼ë¡œ 묶기ì—는 íŒŒì¼ ì´ë¦„ì´ ë„ˆë¬´ 긺: \"%s\"" +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "\"%s\" 외부 í…Œì´ë¸” íƒìƒ‰ì€ ìƒëžµí•¨, ì´ í…Œì´ë¸”ì€ \"%s\" 기본 파티션 í…Œì´ë¸”ì˜ íŒŒí‹°ì…˜ì´ê¸° 때문" -#: replication/basebackup.c:1228 +#: partitioning/partbounds.c:724 #, c-format -msgid "" -"symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "몇몇 ìžë£Œê°€ \"%s\" 기본 파티션용ì—서 ë³€ê²½ëœ íŒŒí‹°ì…˜ ì œì•½ì¡°ê±´ì„ ìœ„ë°°í•œ 것 ê°™ìŒ" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" msgstr "" -"tar í¬ë©§ì„ 사용하기ì—는 심볼릭 ë§í¬ì˜ ëŒ€ìƒ ê²½ë¡œê°€ 너무 ê¹ë‹ˆë‹¤: íŒŒì¼ ì´ë¦„ \"%s" -"\", ëŒ€ìƒ \"%s\"" -#: replication/libpqwalreceiver/libpqwalreceiver.c:119 +#: partitioning/partbounds.c:2158 #, c-format -msgid "could not connect to the primary server: %s" -msgstr "주 ì„œë²„ì— ì—°ê²° í•  수 ì—†ìŒ: %s" +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" 개체는 해시 íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì´ ì•„ë‹˜" -#: replication/libpqwalreceiver/libpqwalreceiver.c:142 +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 #, c-format -msgid "could not parse connection string: %s" -msgstr "ì ‘ì† ë¬¸ìžì—´ì„ ë¶„ì„í•  수 ì—†ìŒ: %s" +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "파티션 칼럼 수: %d, ì œê³µëœ íŒŒí‹°ì…˜ 키 수: %d 서로 다름" -#: replication/libpqwalreceiver/libpqwalreceiver.c:192 +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 #, c-format -msgid "" -"could not receive database system identifier and timeline ID from the " -"primary server: %s" +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" msgstr "" -"주 서버ì—서 ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„번호와 타임ë¼ì¸ 번호를 ë°›ì„ ìˆ˜ ì—†ìŒ: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:203 -#: replication/libpqwalreceiver/libpqwalreceiver.c:357 +#: port/pg_shmem.c:196 port/sysv_shmem.c:196 #, c-format -msgid "invalid response from primary server" -msgstr "주 서버ì—서 ìž˜ëª»ëœ ì‘ë‹µì´ ì™”ìŒ" +msgid "could not create shared memory segment: %m" +msgstr "공유 메모리 세그먼트를 만들 수 ì—†ìŒ: %m" + +#: port/pg_shmem.c:197 port/sysv_shmem.c:197 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "shmget(키=%lu, í¬ê¸°=%zu, 0%o) 시스템 콜 실패" -#: replication/libpqwalreceiver/libpqwalreceiver.c:204 +#: port/pg_shmem.c:201 port/sysv_shmem.c:201 #, c-format msgid "" -"Could not identify system: got %d rows and %d fields, expected %d rows and " -"%d or more fields." +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"ì‹œìŠ¤í…œì„ ì‹ë³„í•  수 ì—†ìŒ: 로우수 %d, 필드수 %d, 예ìƒê°’: 로우수 %d, 필드수 %d " -"ì´ìƒ" +"ì´ ì˜¤ë¥˜ë¥¼ ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 메모리 í¬ê¸°ê°€ 커ë„ì˜ SHMMAX 값보다 í¬ê±°ë‚˜, SHMMIN 값보다 ì ì€ 경우 ë°œìƒí•©ë‹ˆë‹¤.\n" +"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." -#: replication/libpqwalreceiver/libpqwalreceiver.c:220 +#: port/pg_shmem.c:208 port/sysv_shmem.c:208 #, c-format -msgid "database system identifier differs between the primary and standby" -msgstr "ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„번호가 주 서버와 대기 서버가 서로 다름" +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"ì´ ì˜¤ë¥˜ë¥¼ ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 í¬ê¸°ê°€ 커ë„ì˜ SHMALL 값보다 í° ê²½ìš° ë°œìƒí•©ë‹ˆë‹¤. ì»¤ë„ í™˜ê²½ ë³€ìˆ˜ì¸ SHMALL ê°’ì„ ì¢€ ë” í¬ê²Œ 설정하세요.\n" +"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." -#: replication/libpqwalreceiver/libpqwalreceiver.c:221 +#: port/pg_shmem.c:214 port/sysv_shmem.c:214 #, c-format -msgid "The primary's identifier is %s, the standby's identifier is %s." -msgstr "주 서버: %s, 대기 서버: %s." +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"ì´ ì˜¤ë¥˜ëŠ” 서버를 ì‹¤í–‰í•˜ëŠ”ë° í•„ìš”í•œ ë””ìŠ¤í¬ ê³µê°„ì´ ë¶€ì¡±í•´ì„œ ë°œìƒí•œ ê²ƒì´ ì•„ë‹™ë‹ˆë‹¤. ì´ ì˜¤ë¥˜ëŠ” 서버가 사용할 공유 메모리 ID를 ì„ ì í•˜ì§€ ëª»í–ˆì„ ë•Œ ë°œìƒí•©ë‹ˆë‹¤. ì»¤ë„ í™˜ê²½ ì„¤ì •ê°’ì¸ SHMMNI ê°’ì„ ëŠ˜ë¦¬ê±°ë‚˜, ì‹œìŠ¤í…œì˜ ê°€ìš© 공유 ë©”ëª¨ë¦¬ëŸ‰ì„ í™•ë³´í•˜ì„¸ìš”.\n" +"공유 메모리 ì„¤ì •ì— ëŒ€í•œ 보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL 문서를 참조하십시오." -#: replication/libpqwalreceiver/libpqwalreceiver.c:263 +#: port/pg_shmem.c:505 port/sysv_shmem.c:505 #, c-format -msgid "could not start WAL streaming: %s" -msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ìž‘ì—…ì„ ì‹œìž‘í•  수 ì—†ìŒ: %s" +msgid "could not map anonymous shared memory: %m" +msgstr "가용 공유 메모리 확보 실패: %m" -#: replication/libpqwalreceiver/libpqwalreceiver.c:281 +#: port/pg_shmem.c:507 port/sysv_shmem.c:507 #, c-format -msgid "could not send end-of-streaming message to primary: %s" -msgstr "주 서버로 ìŠ¤íŠ¸ë¦¬ë° ì¢…ë£Œ 메시지를 보낼 수 ì—†ìŒ: %s" +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "ì´ ì˜¤ë¥˜ëŠ” ì¼ë°˜ì ìœ¼ë¡œ PostgreSQLì—서 사용할 공유 메모리를 확보하지 못 í–ˆì„ ë•Œ ë°œìƒí•©ë‹ˆë‹¤(물리 메모리, 스왑, huge page). 현재 요구 í¬ê¸°(%zu ë°”ì´íЏ)를 좀 줄여 보십시오. 줄ì´ëŠ” 방법ì€, shared_buffers ê°’ì„ ì¤„ì´ê±°ë‚˜ max_connections ê°’ì„ ì¤„ì—¬ 보십시오." -#: replication/libpqwalreceiver/libpqwalreceiver.c:303 +#: port/pg_shmem.c:573 port/sysv_shmem.c:573 #, c-format -msgid "unexpected result set after end-of-streaming" -msgstr "ìŠ¤íŠ¸ë¦¬ë° ì¢…ë£Œ ìš”ì²­ì— ëŒ€í•œ ìž˜ëª»ëœ ì‘ë‹µì„ ë°›ìŒ" +msgid "huge pages not supported on this platform" +msgstr "huge page ê¸°ëŠ¥ì€ ì´ í”Œëž«í¼ì—서 ì§€ì›ë˜ì§€ 않ìŒ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:315 +#: port/pg_shmem.c:668 port/sysv_shmem.c:668 #, c-format -msgid "error reading result of streaming command: %s" -msgstr "ìŠ¤íŠ¸ë¦¬ë° ëª…ë ¹ì— ëŒ€í•œ ê²°ê³¼ 처리ì—서 오류 ë°œìƒ: %s" +msgid "could not stat data directory \"%s\": %m" +msgstr "\"%s\" ë°ì´í„° 디렉터리 ìƒíƒœë¥¼ 파악할 수 ì—†ìŒ: %m" -#: replication/libpqwalreceiver/libpqwalreceiver.c:323 +#: port/sysv_sema.c:123 #, c-format -msgid "unexpected result after CommandComplete: %s" -msgstr "CommandComplete 작업 후 예ìƒì¹˜ 못한 결과를 ë°›ìŒ: %s" +msgid "could not create semaphores: %m" +msgstr "세마í¬ì–´ë¥¼ 만들 수 ì—†ìŒ: %m" -#: replication/libpqwalreceiver/libpqwalreceiver.c:346 +#: port/sysv_sema.c:124 #, c-format -msgid "could not receive timeline history file from the primary server: %s" -msgstr "주 서버ì—서 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ ë°›ì„ ìˆ˜ ì—†ìŒ: %s" +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "semget(%lu, %d, 0%o) í˜¸ì¶œì— ì˜í•œ 시스템 콜 실패" -#: replication/libpqwalreceiver/libpqwalreceiver.c:358 +#: port/sysv_sema.c:128 #, c-format -msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." -msgstr "2ê°œì˜ ì¹¼ëŸ¼ìœ¼ë¡œ ëœ í•˜ë‚˜ì˜ íŠœí”Œì„ ì˜ˆìƒí•˜ì§€ë§Œ, %d 튜플 (%d 칼럼)ì„ ìˆ˜ì‹ í•¨" +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"ì´ ì˜¤ë¥˜ëŠ” 서버를 ì‹¤í–‰í•˜ëŠ”ë° í•„ìš”í•œ ë””ìŠ¤í¬ ê³µê°„ì´ ë¶€ì¡±í•´ì„œ ë°œìƒí•œ ê²ƒì´ ì•„ë‹™ë‹ˆë‹¤.\n" +"ì´ ì˜¤ë¥˜ëŠ” 시스템ì—서 지정한 최소 세마í¬ì–´ 수(SEMMNI)ê°€ 너무 í¬ê±°ë‚˜, 최대 세마í¬ì–´ 수(SEMMNS)ê°€ 너무 ì ì–´ì„œ 서버를 실행할 수 ì—†ì„ ë•Œ ë°œìƒí•©ë‹ˆë‹¤. ì´ì— ë”°ë¼, ì •ìƒì ìœ¼ë¡œ 서버가 실행ë˜ë ¤ë©´, 시스템 ê°’ë“¤ì„ ì¡°ì •í•  필요가 있습니다. 아니면, 다른 방법으로, PostgreSQLì˜ í™˜ê²½ 설정ì—서 max_connections ê°’ì„ ì¤„ì—¬ì„œ 세마í¬ì–´ 사용 수를 줄여보십시오.\n" +"보다 ìžì„¸í•œ ë‚´ìš©ì€ PostgreSQL ê´€ë¦¬ìž ë©”ë‰´ì–¼ì„ ì°¸ì¡° 하십시오." -#: replication/libpqwalreceiver/libpqwalreceiver.c:386 +#: port/sysv_sema.c:158 #, c-format -msgid "invalid socket: %s" -msgstr "ìž˜ëª»ëœ ì†Œì¼“: %s" +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "커ë„ì˜ SEMVMX ê°’ì„ ì ì–´ë„ %d ì •ë„로 늘려야할 필요가 있는 것 같습니다. ìžì„¸í•œ ê²ƒì€ PostgreSQL 문서를 참조하세요." -#: replication/libpqwalreceiver/libpqwalreceiver.c:426 -#: storage/ipc/latch.c:1280 +#: port/win32/crashdump.c:121 #, c-format -msgid "select() failed: %m" -msgstr "select() 실패: %m" +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "" -#: replication/libpqwalreceiver/libpqwalreceiver.c:549 -#: replication/libpqwalreceiver/libpqwalreceiver.c:576 -#: replication/libpqwalreceiver/libpqwalreceiver.c:582 +#: port/win32/crashdump.c:129 #, c-format -msgid "could not receive data from WAL stream: %s" -msgstr "WAL 스트림ì—서 ìžë£Œ 받기 실패: %s" +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "" -#: replication/libpqwalreceiver/libpqwalreceiver.c:601 +#: port/win32/crashdump.c:160 #, c-format -msgid "could not send data to WAL stream: %s" -msgstr "WAL ìŠ¤íŠ¸ë¦¼ì— ë°ì´í„°ë¥¼ 보낼 수 ì—†ìŒ: %s" +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 쓰기 위해 ì—´ 수 ì—†ìŒ: 오류 번호 %lu\n" -#: replication/logical/logical.c:83 +#: port/win32/crashdump.c:167 #, c-format -msgid "logical decoding requires wal_level >= logical" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ wal_level ê°’ì´ logical ì´ìƒì´ì–´ì•¼ 함" +msgid "wrote crash dump to file \"%s\"\n" +msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 만들었습니다.\n" -#: replication/logical/logical.c:88 +#: port/win32/crashdump.c:169 #, c-format -msgid "logical decoding requires a database connection" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ ë°ì´í„°ë² ì´ìФ ì—°ê²°ì´ í•„ìš”í•©ë‹ˆë‹¤" +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "\"%s\" 장애 ë¤í”„ 파ì¼ì„ 쓰기 실패: 오류 번호 %lu\n" -#: replication/logical/logical.c:106 +#: port/win32/signal.c:194 #, c-format -msgid "logical decoding cannot be used while in recovery" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ ë³µêµ¬ ìƒíƒœì—서는 사용할 수 ì—†ìŒ" +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "%d pid를 위한 ì‹œê·¸ë„ ë¦¬ìŠ¨ë„ˆ 파ì´í”„를 만들 수 ì—†ìŒ: 오류 번호 %lu" -#: replication/logical/logical.c:236 replication/logical/logical.c:348 +#: port/win32/signal.c:274 port/win32/signal.c:306 #, c-format -msgid "cannot use physical replication slot for logical decoding" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”©ì—서는 ë¬¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "신호 수신기 파ì´í”„를 만들 수 ì—†ìŒ: 오류 번호 %lu, 다시 시작 중\n" -#: replication/logical/logical.c:241 replication/logical/logical.c:353 +#: port/win32/signal.c:317 #, c-format -msgid "replication slot \"%s\" was not created in this database" -msgstr "\"%s\" 복제 ìŠ¬ë¡¯ì´ ì´ ë°ì´í„°ë² ì´ìФ 만들어져있지 않ìŒ" +msgid "could not create signal dispatch thread: error code %lu\n" +msgstr "ì‹œê·¸ë„ ë””ìŠ¤íŒ¨ì¹˜ 쓰레드를 만들 수 ì—†ìŒ: 오류 번호 %lu\n" -#: replication/logical/logical.c:248 +#: port/win32_sema.c:104 #, c-format -msgid "" -"cannot create logical replication slot in transaction that has performed " -"writes" -msgstr "" -"ìžë£Œ 변경 ìž‘ì—…ì´ ìžˆëŠ” 트랜잭션 안ì—서는 ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ë§Œë“¤ 수 ì—†ìŒ" +msgid "could not create semaphore: error code %lu" +msgstr "세마í¬ì–´ë¥¼ 만들 수 ì—†ìŒ: 오류 번호 %lu" -#: replication/logical/logical.c:390 +#: port/win32_sema.c:181 #, c-format -msgid "starting logical decoding for slot \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ë§Œë“œëŠ” 중" +msgid "could not lock semaphore: error code %lu" +msgstr "세마í¬ì–´ë¥¼ 잠글 수 ì—†ìŒ: 오류 번호 %lu" -#: replication/logical/logical.c:392 +#: port/win32_sema.c:201 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "" +msgid "could not unlock semaphore: error code %lu" +msgstr "세마í¬ì–´ ìž ê¸ˆì„ í•´ì œí•  수 ì—†ìŒ: 오류 번호 %lu" -#: replication/logical/logical.c:527 +#: port/win32_sema.c:231 #, c-format -msgid "" -"slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" -msgstr "" +msgid "could not try-lock semaphore: error code %lu" +msgstr "세마í¬ì–´ 잠금 ì‹œë„ ì‹¤íŒ¨: 오류 번호 %lu" -#: replication/logical/logical.c:534 +#: port/win32_shmem.c:122 port/win32_shmem.c:130 port/win32_shmem.c:142 +#: port/win32_shmem.c:157 #, c-format -msgid "slot \"%s\", output plugin \"%s\", in the %s callback" -msgstr "" +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "메모리 ì‚¬ìš©ìž ê¶Œë¦¬ì—서 페ì´ì§€ 잠금 활성화 못함: 오류 번호 %lu" -#: replication/logical/logicalfuncs.c:113 replication/slotfuncs.c:32 +#: port/win32_shmem.c:123 port/win32_shmem.c:131 port/win32_shmem.c:143 +#: port/win32_shmem.c:158 #, c-format -msgid "must be superuser or replication role to use replication slots" -msgstr "" -"복제 ìŠ¬ë¡¯ì€ superuser ë˜ëŠ” replication 롤 ì˜µì…˜ì„ í¬í•¨í•œ 사용ìžë§Œ 사용할 수 있" -"습니다." +msgid "Failed system call was %s." +msgstr "실패한 시스템 호출 %s" -#: replication/logical/logicalfuncs.c:152 +#: port/win32_shmem.c:153 #, c-format -msgid "slot name must not be null" -msgstr "슬롯 ì´ë¦„으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다" +msgid "could not enable Lock Pages in Memory user right" +msgstr "메모리 ì‚¬ìš©ìž ê¶Œë¦¬ì—서 페ì´ì§€ 잠금 활성화 못함" -#: replication/logical/logicalfuncs.c:168 +#: port/win32_shmem.c:154 #, c-format -msgid "options array must not be null" -msgstr "옵션 ë°°ì—´ì€ null ê°’ì„ ì‚¬ìš©í•  수 없습니다." +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "" -#: replication/logical/logicalfuncs.c:199 +#: port/win32_shmem.c:210 #, c-format -msgid "array must be one-dimensional" -msgstr "ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼í•©ë‹ˆë‹¤" +msgid "the processor does not support large pages" +msgstr "프로세스가 í° íŽ˜ì´ì§€ë¥¼ ì§€ì›í•˜ì§€ 않ìŒ" -#: replication/logical/logicalfuncs.c:205 +#: port/win32_shmem.c:212 port/win32_shmem.c:217 #, c-format -msgid "array must not contain nulls" -msgstr "ë°°ì—´ì—는 null ê°’ì„ í¬í•¨í•  수 없습니다" +msgid "disabling huge pages" +msgstr "í° íŽ˜ì´ì§€ 비활성화" -#: replication/logical/logicalfuncs.c:221 utils/adt/json.c:2277 -#: utils/adt/jsonb.c:1356 +#: port/win32_shmem.c:279 port/win32_shmem.c:315 port/win32_shmem.c:333 #, c-format -msgid "array must have even number of elements" -msgstr "ë°°ì—´ì€ ê·¸ ìš”ì†Œì˜ ê°œìˆ˜ê°€ ì§ìˆ˜ì—¬ì•¼ 함" +msgid "could not create shared memory segment: error code %lu" +msgstr "공유 메모리 세그먼트를 만들 수 ì—†ìŒ: 오류 번호 %lu" -#: replication/logical/logicalfuncs.c:264 +#: port/win32_shmem.c:280 #, c-format -msgid "" -"logical decoding output plugin \"%s\" produces binary output, but function " -"\"%s\" expects textual data" -msgstr "" +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "실패한 시스템 í˜¸ì¶œì€ CreateFileMapping(í¬ê¸°=%zu, ì´ë¦„=%s)입니다." -#: replication/logical/origin.c:181 +#: port/win32_shmem.c:305 #, c-format -msgid "only superusers can query or manipulate replication origins" -msgstr "슈í¼ìœ ì €ë§Œ 복제 ì›ë³¸ì— 대한 쿼리나, 관리를 í•  수 있습니다." +msgid "pre-existing shared memory block is still in use" +msgstr "기존 공유 메모리 블ë¡ì´ 여전히 사용ë˜ê³  있ìŒ" -#: replication/logical/origin.c:186 +#: port/win32_shmem.c:306 #, c-format -msgid "" -"cannot query or manipulate replication origin when max_replication_slots = 0" -msgstr "" +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "실행 ì¤‘ì¸ ì´ì „ 서버 프로세스가 있는지 확ì¸í•˜ê³  종료하십시오." -#: replication/logical/origin.c:191 +#: port/win32_shmem.c:316 #, c-format -msgid "cannot manipulate replication origins during recovery" -msgstr "" +msgid "Failed system call was DuplicateHandle." +msgstr "실패한 시스템 í˜¸ì¶œì€ DuplicateHandle입니다." -#: replication/logical/origin.c:316 +#: port/win32_shmem.c:334 #, c-format -msgid "could not find free replication origin OID" -msgstr "비어있는 복제 오리진 OID를 ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "Failed system call was MapViewOfFileEx." +msgstr "실패한 시스템 í˜¸ì¶œì€ MapViewOfFileEx입니다." -#: replication/logical/origin.c:353 +#: postmaster/autovacuum.c:406 #, c-format -msgid "could not drop replication origin with OID %d, in use by PID %d" -msgstr "" +msgid "could not fork autovacuum launcher process: %m" +msgstr "autovacuum 실행기 프로세스를 실행할 수 ì—†ìŒ: %m" -#: replication/logical/origin.c:671 +#: postmaster/autovacuum.c:442 #, c-format -msgid "replication checkpoint has wrong magic %u instead of %u" -msgstr "복제 ì²´í¬í¬ì¸íŠ¸ì˜ ìž˜ëª»ëœ ë§¤ì§ ë²ˆí˜¸: %u, 기대값: %u" +msgid "autovacuum launcher started" +msgstr "autovacuum 실행기가 시작ë¨" -#: replication/logical/origin.c:703 +#: postmaster/autovacuum.c:832 #, c-format -msgid "could not read file \"%s\": read %d of %zu" -msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %d ì½ìŒ, ì „ì²´ %zu" +msgid "autovacuum launcher shutting down" +msgstr "autovacuum 실행기를 종료하는 중" -#: replication/logical/origin.c:712 +#: postmaster/autovacuum.c:1494 #, c-format -msgid "could not find free replication state, increase max_replication_slots" -msgstr "" -"사용 가능한 복제 ìŠ¬ë¡¯ì´ ë¶€ì¡±í•©ë‹ˆë‹¤. max_replication_slots ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”" +msgid "could not fork autovacuum worker process: %m" +msgstr "autovacuum ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 실행할 수 ì—†ìŒ: %m" -#: replication/logical/origin.c:730 +#: postmaster/autovacuum.c:1700 #, c-format -msgid "replication slot checkpoint has wrong checksum %u, expected %u" -msgstr "복제 슬롯 ì²´í¬í¬ì¸íŠ¸ì˜ ì²´í¬ì„¬ ê°’ì´ ìž˜ëª»ë¨: %u, 기대값 %u" +msgid "autovacuum: processing database \"%s\"" +msgstr "autovacuum: \"%s\" ë°ì´í„°ë² ì´ìФ 처리 중" -#: replication/logical/origin.c:854 +#: postmaster/autovacuum.c:2269 #, c-format -msgid "replication origin with OID %d is already active for PID %d" -msgstr "" +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: ë” ì´ìƒ 사용하지 않는 \"%s.%s.%s\" 임시 í…Œì´ë¸”ì„ ì‚­ì œí•˜ëŠ” 중" -#: replication/logical/origin.c:865 replication/logical/origin.c:1045 +#: postmaster/autovacuum.c:2498 #, c-format -msgid "" -"could not find free replication state slot for replication origin with OID %u" -msgstr "%u OID 복제 ì˜¤ë¦¬ì§„ì„ ìœ„í•œ 여유 복제 ìŠ¬ë¡¯ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" í…Œì´ë¸” 대ìƒìœ¼ë¡œ ìžë™ vacuum 작업 함" -#: replication/logical/origin.c:867 replication/logical/origin.c:1047 -#: replication/slot.c:1299 +#: postmaster/autovacuum.c:2501 #, c-format -msgid "Increase max_replication_slots and try again." -msgstr "max_replication_slots ê°’ì„ ëŠ˜ë¦° 후 다시 시ë„í•´ 보세요" +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" í…Œì´ë¸” ìžë™ ë¶„ì„" -#: replication/logical/origin.c:1004 +#: postmaster/autovacuum.c:2694 #, c-format -msgid "cannot setup replication origin when one is already setup" -msgstr "하나가 ì´ë¯¸ 설정ë˜ì–´ ë” ì´ìƒ 복제 오리진 ì„¤ì •ì„ í•  수 ì—†ìŒ" +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" 릴레ì´ì…˜ 작업 항목 작업 중" -#: replication/logical/origin.c:1033 +#: postmaster/autovacuum.c:3273 #, c-format -msgid "replication identifier %d is already active for PID %d" -msgstr "%d번 복제 ì‹ë³„ìžê°€ %d PIDì—서 사용하고 있습니다." +msgid "autovacuum not started because of misconfiguration" +msgstr "서버 설정 ì •ë³´ê°€ 잘못ë˜ì–´ ìžë™ 청소 ìž‘ì—…ì´ ì‹¤í–‰ë˜ì§€ 못했습니다." -#: replication/logical/origin.c:1079 replication/logical/origin.c:1274 -#: replication/logical/origin.c:1294 +#: postmaster/autovacuum.c:3274 #, c-format -msgid "no replication origin is configured" -msgstr "복제 오리진 ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤" +msgid "Enable the \"track_counts\" option." +msgstr "\"track_counts\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: replication/logical/reorderbuffer.c:2330 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format -msgid "could not write to data file for XID %u: %m" -msgstr "%u XID ë‚´ìš©ì„ ë°ì´í„° 파ì¼ì— 쓸 수 ì—†ìŒ: %m" +msgid "registering background worker \"%s\"" +msgstr "" -#: replication/logical/reorderbuffer.c:2426 -#: replication/logical/reorderbuffer.c:2446 +#: postmaster/bgworker.c:427 #, c-format -msgid "could not read from reorderbuffer spill file: %m" -msgstr "reorderbuffer 처리용 파ì¼ì—서 ì½ê¸° 실패: %m" +msgid "unregistering background worker \"%s\"" +msgstr "" -#: replication/logical/reorderbuffer.c:2430 -#: replication/logical/reorderbuffer.c:2450 +#: postmaster/bgworker.c:592 #, c-format -msgid "" -"could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" msgstr "" -"reorderbuffer 처리용 파ì¼ì—서 ì½ê¸° 실패: %d ë°”ì´íЏ ì½ìŒ, 기대값 %u ë°”ì´íЏ" -#: replication/logical/reorderbuffer.c:3106 +#: postmaster/bgworker.c:601 #, c-format -msgid "could not read from file \"%s\": read %d instead of %d bytes" -msgstr "\"%s\" 파ì¼ì—서 ì½ê¸° 실패: %d ë°”ì´íЏ ì½ìŒ, 기대값 %d ë°”ì´íЏ" +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "" -#: replication/logical/snapbuild.c:598 +#: postmaster/bgworker.c:615 #, c-format -msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" -msgid_plural "" -"exported logical decoding snapshot: \"%s\" with %u transaction IDs" -msgstr[0] "" +msgid "background worker \"%s\": invalid restart interval" +msgstr "\"%s\" 백그ë¼ìš´ë“œ 작업ìž: ìž˜ëª»ëœ ìž¬ì‹¤í–‰ 간격" -#: replication/logical/snapbuild.c:917 replication/logical/snapbuild.c:1282 -#: replication/logical/snapbuild.c:1813 +#: postmaster/bgworker.c:630 #, c-format -msgid "logical decoding found consistent point at %X/%X" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ì´ì–´ì„œ 시작할 위치: %X/%X" +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "\"%s\" 백그ë¼ìš´ë“œ 작업ìž: ì´ ë³‘ë ¬ 작업ìžëŠ” 재실행 ì„¤ì •ì´ ì—†ìŒ" -#: replication/logical/snapbuild.c:919 +#: postmaster/bgworker.c:674 #, c-format -msgid "Transaction ID %u finished; no more running transactions." -msgstr "%u 트랜잭션 ID 마침; ë” ì²˜ë¦¬í•  íŠ¸ëžœìž­ì…˜ì´ ì—†ìŒ" +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "ê´€ë¦¬ìž ëª…ë ¹ì— ì˜í•´ \"%s\" 백그ë¼ìš´ë“œ 작업ìžë¥¼ 종료합니다." -#: replication/logical/snapbuild.c:1284 +#: postmaster/bgworker.c:863 #, c-format -msgid "There are no running transactions." -msgstr "실행할 íŠ¸ëžœìž­ì…˜ì´ ì—†ìŒ" +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "\"%s\" 백그ë¼ìš´ë“œ 작업ìž: 먼저 shared_preload_libraries 설정값으로 등ë¡ë˜ì–´ì•¼ 합니다." -#: replication/logical/snapbuild.c:1346 +#: postmaster/bgworker.c:875 #, c-format -msgid "logical decoding found initial starting point at %X/%X" -msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© 시작 위치: %X/%X" +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "\"%s\" 백그ë¼ìš´ë“œ 작업ìž: ë™ì  백그ë¼ìš´ë“œ 작업ìžë§Œ ì•Œë¦¼ì„ ìš”ì²­í•  수 있ìŒ" -#: replication/logical/snapbuild.c:1348 +#: postmaster/bgworker.c:890 #, c-format -msgid "%u transaction needs to finish." -msgid_plural "%u transactions need to finish." -msgstr[0] "마치려면 %uê°œì˜ íŠ¸ëžœìž­ì…˜ì´ í•„ìš”í•©ë‹ˆë‹¤." +msgid "too many background workers" +msgstr "백그ë¼ìš´ë“œ 작업ìžê°€ 너무 ë§ŽìŒ" -#: replication/logical/snapbuild.c:1687 replication/logical/snapbuild.c:1713 -#: replication/logical/snapbuild.c:1727 replication/logical/snapbuild.c:1741 +#: postmaster/bgworker.c:891 #, c-format -msgid "could not read file \"%s\", read %d of %d: %m" -msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ, %d/%d ë°”ì´íЏ ì½ìŒ: %m" +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "현재 설정으로는 %dê°œì˜ ë°±ê·¸ë¼ìš´ë“œ 작업ìžë¥¼ 사용할 수 있습니다." -#: replication/logical/snapbuild.c:1693 +#: postmaster/bgworker.c:895 #, c-format -msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" -msgstr "\"%s\" snapbuild ìƒíƒœ 파ì¼ì˜ ë§¤ì§ ë²ˆí˜¸ê°€ ì´ìƒí•¨: 현재값 %u, 기대값 %u" +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "\"max_worker_processes\" 환경 매개 변수 ê°’ì„ ì¢€ ëŠë ¤ë³´ì‹­ì‹œì˜¤." -#: replication/logical/snapbuild.c:1698 +#: postmaster/checkpointer.c:464 #, c-format -msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" -msgstr "\"%s\" snapbuild ìƒíƒœ 파ì¼ì˜ ë²„ì „ì´ ì´ìƒí•¨: 현재값 %u, 기대값 %u" +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "ì²´í¬í¬ì¸íŠ¸ê°€ 너무 ìžì£¼ ë°œìƒí•¨ (%dì´ˆ 간격)" -#: replication/logical/snapbuild.c:1754 +#: postmaster/checkpointer.c:468 #, c-format -msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" -msgstr "" +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "\"max_wal_size\" 환경 매개 변수 ê°’ì„ ì¢€ ëŠë ¤ë³´ì‹­ì‹œì˜¤." -#: replication/logical/snapbuild.c:1815 +#: postmaster/checkpointer.c:1082 #, c-format -msgid "Logical decoding will begin using saved snapshot." -msgstr "" +msgid "checkpoint request failed" +msgstr "ì²´í¬í¬ì¸íЏ 요청 실패" -#: replication/logical/snapbuild.c:1888 +#: postmaster/checkpointer.c:1083 #, c-format -msgid "could not parse file name \"%s\"" -msgstr "\"%s\" íŒŒì¼ ì´ë¦„ì„ ë¶„ì„í•  수 ì—†ìŒ" +msgid "Consult recent messages in the server log for details." +msgstr "ë” ìžì„¸í•œ ê²ƒì€ ì„œë²„ 로그 파ì¼ì„ 살펴보십시오." -#: replication/slot.c:183 +#: postmaster/checkpointer.c:1278 #, c-format -msgid "replication slot name \"%s\" is too short" -msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì´ ë„ˆë¬´ ì§§ìŒ" +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "" -#: replication/slot.c:192 +#: postmaster/pgarch.c:148 #, c-format -msgid "replication slot name \"%s\" is too long" -msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì´ ë„ˆë¬´ 긺" +msgid "could not fork archiver: %m" +msgstr "archiver 할당(fork) 실패: %m" -#: replication/slot.c:205 +#: postmaster/pgarch.c:456 #, c-format -msgid "replication slot name \"%s\" contains invalid character" -msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì— ì‚¬ìš©í•  수 없는 문ìžê°€ 있ìŒ" +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_modeê°€ 사용 설정ë˜ì—ˆëŠ”ë° archive_commandê°€ 설정ë˜ì§€ 않ìŒ" -#: replication/slot.c:207 +#: postmaster/pgarch.c:484 #, c-format -msgid "" -"Replication slot names may only contain lower case letters, numbers, and the " -"underscore character." -msgstr "" -"복제 슬롯 ì´ë¦„으로 사용할 수 있는 문ìžëŠ” ì˜ë¬¸ 소문ìž, 숫ìž, 밑줄(_) 문ìžìž…니" -"다." +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "\"%s\" 트랜잭션 로그 íŒŒì¼ ì•„ì¹´ì´ë¸Œ ìž‘ì—…ì´ ê³„ì† ì‹¤íŒ¨í•˜ê³  있습니다. 다ìŒì— ë˜ ì‹œë„í•  것입니다." -#: replication/slot.c:254 +#: postmaster/pgarch.c:587 #, c-format -msgid "replication slot \"%s\" already exists" -msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì´ ì´ë¯¸ 있습니다." +msgid "archive command failed with exit code %d" +msgstr "ì•„ì¹´ì´ë¸Œ 명령 실패, 종료 코드: %d" -#: replication/slot.c:264 +#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 +#: postmaster/pgarch.c:612 postmaster/pgarch.c:621 #, c-format -msgid "all replication slots are in use" -msgstr "모든 복제 ìŠ¬ë¡¯ì´ ì‚¬ìš© 중입니다." +msgid "The failed archive command was: %s" +msgstr "실패한 ì•„ì¹´ì´ë¸Œ 명령: %s" -#: replication/slot.c:265 +#: postmaster/pgarch.c:596 #, c-format -msgid "Free one or increase max_replication_slots." -msgstr "하나를 비우든지, max_replication_slots ì„¤ì •ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”." +msgid "archive command was terminated by exception 0x%X" +msgstr "0x%X 예외로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨" -#: replication/slot.c:361 +#: postmaster/pgarch.c:598 postmaster/postmaster.c:3567 #, c-format -msgid "replication slot \"%s\" does not exist" -msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì´ ì—†ìŠµë‹ˆë‹¤" +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "16진수 ê°’ì— ëŒ€í•œ ì„¤ëª…ì€ C í¬í•¨ íŒŒì¼ \"ntstatus.h\"를 참조하십시오." -#: replication/slot.c:365 +#: postmaster/pgarch.c:603 #, c-format -msgid "replication slot \"%s\" is active for PID %d" -msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì„ %d PID 프로세스가 사용중입니다." +msgid "archive command was terminated by signal %d: %s" +msgstr "%d번 시그ë„로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨: %s" -#: replication/slot.c:511 replication/slot.c:923 replication/slot.c:1260 +#: postmaster/pgarch.c:610 #, c-format -msgid "could not remove directory \"%s\"" -msgstr "\"%s\" 디렉터리를 삭제할 수 ì—†ìŒ" +msgid "archive command was terminated by signal %d" +msgstr "%d번 시그ë„로 ì¸í•´ ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¢…ë£Œë¨" -#: replication/slot.c:772 +#: postmaster/pgarch.c:619 #, c-format -msgid "replication slots can only be used if max_replication_slots > 0" -msgstr "복제 ìŠ¬ë¡¯ì€ max_replication_slots > 0 ìƒíƒœì—서 ì‚¬ìš©ë  ìˆ˜ 있습니다." +msgid "archive command exited with unrecognized status %d" +msgstr "ì•„ì¹´ì´ë¸Œ ëª…ë ¹ì´ ì¸ì‹í•  수 없는 %d ìƒíƒœë¡œ 종료ë¨" -#: replication/slot.c:777 +#: postmaster/pgstat.c:395 #, c-format -msgid "replication slots can only be used if wal_level >= replica" -msgstr "복제 ìŠ¬ë¡¯ì€ wal_level >= replica ìƒíƒœì—서 ì‚¬ìš©ë  ìˆ˜ 있습니다." +msgid "could not resolve \"localhost\": %s" +msgstr "\"localhost\" ì´ë¦„ì˜ í˜¸ìŠ¤íŠ¸ IP를 구할 수 없습니다: %s" -#: replication/slot.c:1192 replication/slot.c:1230 +#: postmaster/pgstat.c:418 #, c-format -msgid "could not read file \"%s\", read %d of %u: %m" -msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ, %d/%u ë°”ì´íЏ ì½ìŒ: %m" +msgid "trying another address for the statistics collector" +msgstr "통계 수집기ì—서 사용할 다른 주소를 찾습니다" -#: replication/slot.c:1201 +#: postmaster/pgstat.c:427 #, c-format -msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" -msgstr "\"%s\" 복제 슬롯 파ì¼ì˜ ë§¤ì§ ë²ˆí˜¸ê°€ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %u, 기대값 %u" +msgid "could not create socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다: %m" -#: replication/slot.c:1208 +#: postmaster/pgstat.c:439 #, c-format -msgid "replication slot file \"%s\" has unsupported version %u" -msgstr "\"%s\" 복제 슬롯 파ì¼ì€ ì§€ì›í•˜ì§€ 않는 %u 버전 파ì¼ìž…니다" +msgid "could not bind socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 소켓과 bindí•  수 없습니다: %m" -#: replication/slot.c:1215 +#: postmaster/pgstat.c:450 #, c-format -msgid "replication slot file \"%s\" has corrupted length %u" -msgstr "\"%s\" 복제 슬롯 파ì¼ì´ %u 길ì´ë¡œ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "could not get address of socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì˜ ì£¼ì†Œë¥¼ 구할 수 없습니다: %m" -#: replication/slot.c:1245 +#: postmaster/pgstat.c:466 #, c-format -msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" -msgstr "\"%s\" 복제 슬롯 파ì¼ì˜ ì²´í¬ì„¬ ê°’ì´ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %u, 기대값 %u" +msgid "could not connect socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 ì†Œì¼“ì— ì—°ê²°í•  수 없습니다: %m" -#: replication/slot.c:1298 +#: postmaster/pgstat.c:487 #, c-format -msgid "too many replication slots active before shutdown" -msgstr "서버 중지 ì „ì— ë„ˆë¬´ ë§Žì€ ë³µì œ ìŠ¬ë¡¯ì´ í™œì„±í™” ìƒíƒœìž…니다" +msgid "could not send test message on socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 보낼 수 없습니다: %m" -#: replication/syncrep.c:221 +#: postmaster/pgstat.c:513 #, c-format -msgid "" -"canceling the wait for synchronous replication and terminating connection " -"due to administrator command" -msgstr "" -"ê´€ë¦¬ìž ëª…ë ¹ì— ì˜í•´ ë™ê¸°ì‹ ë³µì œì˜ ëŒ€ê¸° 작업과 ì ‘ì† ëŠê¸° ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "select() failed in statistics collector: %m" +msgstr "통계 수집기ì—서 select() 작업 오류: %m" -#: replication/syncrep.c:222 replication/syncrep.c:239 +#: postmaster/pgstat.c:528 #, c-format -msgid "" -"The transaction has already committed locally, but might not have been " -"replicated to the standby." -msgstr "" -"주 서버ì—서는 ì´ íŠ¸ëžœìž­ì…˜ì´ ì»¤ë°‹ë˜ì—ˆì§€ë§Œ, 복제용 대기 서버ì—서는 ì•„ì§ ì»¤ë°‹ ë˜" -"ì§€ ì•Šì•˜ì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤." +msgid "test message did not get through on socket for statistics collector" +msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 처리할 수 없습니다" -#: replication/syncrep.c:238 +#: postmaster/pgstat.c:543 #, c-format -msgid "canceling wait for synchronous replication due to user request" -msgstr "ì‚¬ìš©ìž ìš”ì²­ì— ì˜í•´ ë™ê¸°ì‹ 복제 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "통계 수집기ì—서 사용할 소켓으로 테스트 메시지를 ë°›ì„ ìˆ˜ 없습니다: %m" -#: replication/syncrep.c:368 +#: postmaster/pgstat.c:553 #, c-format -msgid "standby \"%s\" now has synchronous standby priority %u" -msgstr "\"%s\" 대기 ì„œë²„ì˜ ë™ê¸°ì‹ 복제 우선순위가 %u 입니다" +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "통계 수집기ì—서 사용할 소켓으로 ìž˜ëª»ëœ í…ŒìŠ¤íŠ¸ 메시지가 전달 ë˜ì—ˆìŠµë‹ˆë‹¤" -#: replication/syncrep.c:428 +#: postmaster/pgstat.c:576 #, c-format -msgid "standby \"%s\" is now a synchronous standby with priority %u" -msgstr "\"%s\" 대기 ì„œë²„ì˜ ë™ê¸°ì‹ 복제 우선순위가 %u 로 변경ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "통계 수집기ì—서 사용하는 소켓 모드를 nonblocking 모드로 지정할 수 없습니다: %m" -#: replication/syncrep.c:921 +#: postmaster/pgstat.c:615 #, c-format -msgid "synchronous_standby_names parser failed" -msgstr "synchronous_standby_names ê°’ì„ ë¶„ì„í•  수 ì—†ìŒ" +msgid "disabling statistics collector for lack of working socket" +msgstr "현재 작업 ì†Œì¼“ì˜ ì›í• í•œ ì†Œí†µì„ ìœ„í•´ 통계 수집기 ê¸°ëŠ¥ì„ ì¤‘ì§€í•©ë‹ˆë‹¤" -#: replication/syncrep.c:927 +#: postmaster/pgstat.c:762 #, c-format -msgid "number of synchronous standbys (%d) must be greater than zero" -msgstr "ë™ê¸°ì‹ 대기 서버 수 (%d)는 0보다 커야 합니다." +msgid "could not fork statistics collector: %m" +msgstr "통계 수집기를 forkí•  수 없습니다: %m" -#: replication/walreceiver.c:173 +#: postmaster/pgstat.c:1342 #, c-format -msgid "terminating walreceiver process due to administrator command" -msgstr "ê´€ë¦¬ìž ëª…ë ¹ìœ¼ë¡œ ì¸í•´ WAL 수신기를 종료합니다." +msgid "unrecognized reset target: \"%s\"" +msgstr "알 수 없는 리셋 타겟: \"%s\"" -#: replication/walreceiver.c:344 +#: postmaster/pgstat.c:1343 #, c-format -msgid "highest timeline %u of the primary is behind recovery timeline %u" -msgstr "" -"주 ì„œë²„ì˜ ì œì¼ ìµœì‹ ì˜ íƒ€ìž„ë¼ì¸ì€ %u ì¸ë°, 복구 타임ë¼ì¸ %u 보다 옛것입니다" +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "사용 가능한 íƒ€ê²Ÿì€ \"archiver\" ë˜ëŠ” \"bgwriter\"" -#: replication/walreceiver.c:377 +#: postmaster/pgstat.c:4362 #, c-format -msgid "started streaming WAL from primary at %X/%X on timeline %u" -msgstr "주 ì„œë²„ì˜ WAL ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 위치: %X/%X (타임ë¼ì¸ %u)" +msgid "could not read statistics message: %m" +msgstr "통계 메시지를 ì½ì„ 수 ì—†ìŒ: %m" -#: replication/walreceiver.c:382 +#: postmaster/pgstat.c:4694 postmaster/pgstat.c:4851 #, c-format -msgid "restarted WAL streaming at %X/%X on timeline %u" -msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ìž¬ì‹œìž‘ 위치: %X/%X (타임ë¼ì¸ %u)" +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: replication/walreceiver.c:411 +#: postmaster/pgstat.c:4761 postmaster/pgstat.c:4896 #, c-format -msgid "cannot continue WAL streaming, recovery has already ended" -msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ê³„ì†í•  수 ì—†ìŒ, 복구가 ì´ë¯¸ 종료ë¨" +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파ì¼ì— 쓰기 실패: %m" -#: replication/walreceiver.c:448 +#: postmaster/pgstat.c:4770 postmaster/pgstat.c:4905 #, c-format -msgid "replication terminated by primary server" -msgstr "주 ì„œë²„ì— ì˜í•´ì„œ 복제가 ë남" +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "\"%s\" 임시 통계 파ì¼ì„ ë‹«ì„ ìˆ˜ 없습니다: %m" -#: replication/walreceiver.c:449 +#: postmaster/pgstat.c:4778 postmaster/pgstat.c:4913 #, c-format -msgid "End of WAL reached on timeline %u at %X/%X." -msgstr "타임ë¼ì¸ %u, 위치 %X/%X ì—서 WAL ëì— ë„달함" +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 임시 통계 íŒŒì¼ ì´ë¦„ì„ \"%s\" (으)로 바꿀 수 없습니다: %m" -#: replication/walreceiver.c:543 +#: postmaster/pgstat.c:5002 postmaster/pgstat.c:5208 postmaster/pgstat.c:5361 #, c-format -msgid "terminating walreceiver due to timeout" -msgstr "시간 제한으로 wal 수신기를 중지합니다." +msgid "could not open statistics file \"%s\": %m" +msgstr "\"%s\" 통계 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: replication/walreceiver.c:583 +#: postmaster/pgstat.c:5014 postmaster/pgstat.c:5024 postmaster/pgstat.c:5045 +#: postmaster/pgstat.c:5067 postmaster/pgstat.c:5082 postmaster/pgstat.c:5145 +#: postmaster/pgstat.c:5220 postmaster/pgstat.c:5240 postmaster/pgstat.c:5258 +#: postmaster/pgstat.c:5274 postmaster/pgstat.c:5292 postmaster/pgstat.c:5308 +#: postmaster/pgstat.c:5373 postmaster/pgstat.c:5385 postmaster/pgstat.c:5397 +#: postmaster/pgstat.c:5422 postmaster/pgstat.c:5444 #, c-format -msgid "primary server contains no more WAL on requested timeline %u" -msgstr "주 서버ì—는 요청 ë°›ì€ %u 타임ë¼ì¸ì˜ WALê°€ ë” ì´ìƒ 없습니다." +msgid "corrupted statistics file \"%s\"" +msgstr "\"%s\" 통계 파ì¼ì´ ì†ìƒë˜ì—ˆìŒ" -#: replication/walreceiver.c:598 replication/walreceiver.c:957 +#: postmaster/pgstat.c:5573 #, c-format -msgid "could not close log segment %s: %m" -msgstr "%s 로그 ì¡°ê° íŒŒì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "현재 통계 수집기가 ë°˜ì‘하지 않아 부정확한 통계정보가 사용ë˜ê³  있습니다." -#: replication/walreceiver.c:722 +#: postmaster/pgstat.c:5900 #, c-format -msgid "fetching timeline history file for timeline %u from primary server" -msgstr "주 서버ì—서 %u 타임ë¼ì¸ìš© 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ 가져옵니다." +msgid "database hash table corrupted during cleanup --- abort" +msgstr "정리하는 ë™ì•ˆ ë°ì´í„°ë² ì´ìФ 해시 í…Œì´ë¸”ì´ ì†ìƒ ë˜ì—ˆìŠµë‹ˆë‹¤ --- 중지함" -#: replication/walreceiver.c:1011 +#: postmaster/postmaster.c:717 #, c-format -msgid "could not write to log segment %s at offset %u, length %lu: %m" -msgstr "%s 로그 ì¡°ê° íŒŒì¼ ì“°ê¸° 실패: 위치 %u, ê¸¸ì´ %lu: %m" +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: -f ì˜µì…˜ì˜ ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" -#: replication/walsender.c:485 +#: postmaster/postmaster.c:803 #, c-format -msgid "could not seek to beginning of file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì—서 시작 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %m" +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: -t ì˜µì…˜ì˜ ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" -#: replication/walsender.c:536 +#: postmaster/postmaster.c:854 #, c-format -msgid "cannot use a logical replication slot for physical replication" -msgstr "ë¬¼ë¦¬ì  ë³µì œì—서 ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: ìž˜ëª»ëœ ì¸ìž: \"%s\"\n" -#: replication/walsender.c:599 +#: postmaster/postmaster.c:896 #, c-format -msgid "" -"requested starting point %X/%X on timeline %u is not in this server's history" -msgstr "ìš”ì²­ëœ %X/%X 시작 위치(타임ë¼ì¸ %u)ê°€ ì´ ì„œë²„ ë‚´ì—­ì— ì—†ìŠµë‹ˆë‹¤." +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections(%d) + max_wal_senders(%d) ê°’ì€ max_connections(%d) 값보다 작아야합니다\n" -#: replication/walsender.c:603 +#: postmaster/postmaster.c:903 #, c-format -msgid "This server's history forked from timeline %u at %X/%X." -msgstr "ì´ ì„œë²„ì˜ ì‹œìž‘ 위치: 타임ë¼ì¸ %u, 위치 %X/%X" +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "wal_level ê°’ì´ \"minimal\"ì¼ ë•ŒëŠ” ì•„ì¹´ì´ë¸Œ ìž‘ì—…ì„ í•  수 없습니다." -#: replication/walsender.c:648 +#: postmaster/postmaster.c:906 #, c-format -msgid "" -"requested starting point %X/%X is ahead of the WAL flush position of this " -"server %X/%X" -msgstr "" +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ìž‘ì—…(max_wal_senders > 0 ì¸ê²½ìš°)ì€ wal_level ê°’ì´ \"replica\" ë˜ëŠ” \"logical\" ì´ì–´ì•¼ 합니다." -#: replication/walsender.c:972 +#: postmaster/postmaster.c:914 #, c-format -msgid "terminating walsender process after promotion" -msgstr "ìš´ì˜ì „환 ë’¤ wal 송신기 프로세스를 중지합니다." +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: ìž˜ëª»ëœ datetoken í…Œì´ë¸”들, 복구하십시오.\n" -#: replication/walsender.c:1298 +#: postmaster/postmaster.c:1028 postmaster/postmaster.c:1126 +#: utils/init/miscinit.c:1547 #, c-format -msgid "received replication command: %s" -msgstr "ìˆ˜ì‹ ëœ ë³µì œ 명령: %s" +msgid "invalid list syntax in parameter \"%s\"" +msgstr "\"%s\" 매개 변수 êµ¬ë¬¸ì´ ìž˜ëª» ë˜ì—ˆìŠµë‹ˆë‹¤" -#: replication/walsender.c:1397 replication/walsender.c:1413 +#: postmaster/postmaster.c:1059 #, c-format -msgid "unexpected EOF on standby connection" -msgstr "대기 서버 ì—°ê²°ì—서 예ìƒì¹˜ 못한 EOF 발견함" +msgid "could not create listen socket for \"%s\"" +msgstr "\"%s\" ì‘당 ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" -#: replication/walsender.c:1427 +#: postmaster/postmaster.c:1065 #, c-format -msgid "unexpected standby message type \"%c\", after receiving CopyDone" -msgstr "" +msgid "could not create any TCP/IP sockets" +msgstr "TCP/IP ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다." -#: replication/walsender.c:1465 +#: postmaster/postmaster.c:1148 #, c-format -msgid "invalid standby message type \"%c\"" -msgstr "ìž˜ëª»ëœ ëŒ€ê¸° 서버 메시지 형태 \"%c\"" +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "\"%s\" ë””ë ‰í„°ë¦¬ì— ìœ ë‹‰ìŠ¤ ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" -#: replication/walsender.c:1506 +#: postmaster/postmaster.c:1154 #, c-format -msgid "unexpected message type \"%c\"" -msgstr "예ìƒì¹˜ 못한 메시지 형태: \"%c\"" +msgid "could not create any Unix-domain sockets" +msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 수 없습니다" -#: replication/walsender.c:1790 +#: postmaster/postmaster.c:1166 #, c-format -msgid "terminating walsender process due to replication timeout" -msgstr "복제 시간 제한으로 wal 송신기 프로세스를 종료합니다." +msgid "no socket created for listening" +msgstr "서버 ì ‘ì† ëŒ€ê¸° ìž‘ì—…ì„ ìœ„í•œ ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: replication/walsender.c:1875 +#: postmaster/postmaster.c:1206 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "\"%s\" 대기 서버가 ìš´ì˜ ì„œë²„ë¡œ 전환합니다" +msgid "could not create I/O completion port for child queue" +msgstr "하위 ëŒ€ê¸°ì—´ì— ëŒ€í•´ I/O 완료 í¬íŠ¸ë¥¼ 만들 수 ì—†ìŒ" -#: replication/walsender.c:1978 +#: postmaster/postmaster.c:1235 #, c-format -msgid "" -"number of requested standby connections exceeds max_wal_senders (currently " -"%d)" -msgstr "대기 서버 ì—°ê²° 수가 max_wal_senders 설정값(현재 %d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: \"%s\" 외부 PID 파ì¼ì˜ ì ‘ê·¼ ê¶Œí•œì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:973 +#: postmaster/postmaster.c:1239 #, c-format -msgid "rule \"%s\" for relation \"%s\" already exists" -msgstr "\"%s\" ì´ë¦„ì˜ ë£°(rule)ì´ \"%s\" í…Œì´ë¸”ì— ì´ë¯¸ 지정ë˜ì–´ìžˆìŠµë‹ˆë‹¤" +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: 외부 pid íŒŒì¼ \"%s\" 를 쓸 수 ì—†ìŒ: %s\n" -#: rewrite/rewriteDefine.c:297 +#: postmaster/postmaster.c:1296 #, c-format -msgid "rule actions on OLD are not implemented" -msgstr "OLDì— ëŒ€í•œ 실행 룰(rule)ì€ ì•„ì§ êµ¬í˜„ë˜ì§€ 않았습니다" +msgid "ending log output to stderr" +msgstr "stderr 쪽 로그 ì¶œë ¥ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:298 +#: postmaster/postmaster.c:1297 #, c-format -msgid "Use views or triggers instead." -msgstr "ëŒ€ì‹ ì— ë·°ë‚˜ 트리거를 사용하십시오." +msgid "Future log output will go to log destination \"%s\"." +msgstr "ìžì„¸í•œ 로그는 \"%s\" 쪽으로 기ë¡ë©ë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:302 +#: postmaster/postmaster.c:1323 utils/init/postinit.c:214 #, c-format -msgid "rule actions on NEW are not implemented" -msgstr "NEWì— ëŒ€í•œ 실행 룰(rule)ì€ ì•„ì§ êµ¬í˜„ë˜ì§€ 않았습니다" +msgid "could not load pg_hba.conf" +msgstr "pg_hba.conf를 로드할 수 ì—†ìŒ" -#: rewrite/rewriteDefine.c:303 +#: postmaster/postmaster.c:1349 #, c-format -msgid "Use triggers instead." -msgstr "ëŒ€ì‹ ì— íŠ¸ë¦¬ê±°ë¥¼ 사용하십시오." +msgid "postmaster became multithreaded during startup" +msgstr "" -#: rewrite/rewriteDefine.c:316 +#: postmaster/postmaster.c:1350 #, c-format -msgid "INSTEAD NOTHING rules on SELECT are not implemented" -msgstr "SELECT ì—서 INSTEAD NOTHING 룰(rule)ì€ êµ¬í˜„ë˜ì§€ 않았습니다" +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "LC_ALL 환경 설정값으로 ì•Œë§žì€ ë¡œì¼€ì¼ ì´ë¦„ì„ ì§€ì •í•˜ì„¸ìš”." -#: rewrite/rewriteDefine.c:317 +#: postmaster/postmaster.c:1455 #, c-format -msgid "Use views instead." -msgstr "ëŒ€ì‹ ì— ë·°ë¥¼ 사용하십시오." +msgid "%s: could not locate matching postgres executable" +msgstr "%s: 실행가능한 postgres í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ 없습니다" -#: rewrite/rewriteDefine.c:325 +#: postmaster/postmaster.c:1478 utils/misc/tzparser.c:341 #, c-format -msgid "multiple actions for rules on SELECT are not implemented" -msgstr "SELECTì— ëŒ€í•œ 다중 실행 룰(rule)ì€ êµ¬í˜„ë˜ì§€ 않았습니다" +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "ì´ ë¬¸ì œëŠ” PostgreSQL 설치가 불완전하게 ë˜ì—ˆê±°ë‚˜, \"%s\" 파ì¼ì´ 올바른 ìœ„ì¹˜ì— ìžˆì§€ 않아서 ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:336 +#: postmaster/postmaster.c:1505 #, c-format -msgid "rules on SELECT must have action INSTEAD SELECT" +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" msgstr "" -"SELECTì— ëŒ€í•œ 룰(rule)ì€ ê·¸ ì§€ì •ì— INSTEAD SELECT ì‹¤í–‰ê·œì¹™ì„ ì§€ì •í•´ì•¼ë§Œí•©ë‹ˆë‹¤" +"%s: ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì„ ì°¾ì„ ìˆ˜ 없습니다\n" +"\"%s\" 디렉터리 ì•ˆì— í•´ë‹¹ ìžë£Œê°€ 있기를 기대했는ë°,\n" +"\"%s\" 파ì¼ì„ ì—´ 수가 없었습니다: %s\n" -#: rewrite/rewriteDefine.c:344 +#: postmaster/postmaster.c:1682 #, c-format -msgid "rules on SELECT must not contain data-modifying statements in WITH" -msgstr "" +msgid "select() failed in postmaster: %m" +msgstr "postmasterì—서 select() ìž‘ë™ ì‹¤íŒ¨: %m" -#: rewrite/rewriteDefine.c:352 +#: postmaster/postmaster.c:1837 #, c-format -msgid "event qualifications are not implemented for rules on SELECT" +msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "" -"ì´ë²¤íЏ ìžê²©(event qualifications)ì€ SELECT 룰(rule)ì—서 구현ë˜ì§€ 않았습니다" -#: rewrite/rewriteDefine.c:379 +#: postmaster/postmaster.c:1915 postmaster/postmaster.c:1946 #, c-format -msgid "\"%s\" is already a view" -msgstr "\"%s\" ì´ë¦„ì˜ ë·°ê°€ ì´ë¯¸ 있습니다" +msgid "incomplete startup packet" +msgstr "ì•„ì§ ì™„ë£Œë˜ì§€ ì•Šì€ ì‹œìž‘ 패킷" -#: rewrite/rewriteDefine.c:403 +#: postmaster/postmaster.c:1927 #, c-format -msgid "view rule for \"%s\" must be named \"%s\"" -msgstr "\"%s\" 위한 ë·° 룰(view rule)ì˜ ì´ë¦„ì€ \"%s\" 여야만합니다" +msgid "invalid length of startup packet" +msgstr "시작 íŒ¨í‚·ì˜ ê¸¸ì´ê°€ 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤" -#: rewrite/rewriteDefine.c:432 +#: postmaster/postmaster.c:1985 #, c-format -msgid "could not convert table \"%s\" to a view because it is not empty" -msgstr "\"%s\" í…Œì´ë¸”ì— ìžë£Œê°€ 있기 때문ì—, í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" +msgid "failed to send SSL negotiation response: %m" +msgstr "SSL ì—°ê²° ìž‘ì—…ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤: %m" -#: rewrite/rewriteDefine.c:440 +#: postmaster/postmaster.c:2011 #, c-format -msgid "could not convert table \"%s\" to a view because it has triggers" -msgstr "\"%s\" í…Œì´ë¸”ì— íŠ¸ë¦¬ê±°ê°€ í¬í•¨ë˜ì–´ 있어 뷰로 변환할 수 없습니다" +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "ì§€ì›í•˜ì§€ 않는 frontend 프로토콜 %u.%u: 서버ì—서 ì§€ì›í•˜ëŠ” 프로토콜 %u.0 .. %u.%u" -#: rewrite/rewriteDefine.c:442 +#: postmaster/postmaster.c:2075 utils/misc/guc.c:6003 utils/misc/guc.c:6096 +#: utils/misc/guc.c:7422 utils/misc/guc.c:10185 utils/misc/guc.c:10219 #, c-format -msgid "" -"In particular, the table cannot be involved in any foreign key relationships." -msgstr "특히 í…Œì´ë¸”ì€ ì°¸ì¡°í‚¤ ê´€ê³„ì— ê´€ë ¨ë  ìˆ˜ 없습니다." +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: \"%s\"" -#: rewrite/rewriteDefine.c:447 +#: postmaster/postmaster.c:2078 #, c-format -msgid "could not convert table \"%s\" to a view because it has indexes" -msgstr "\"%s\" í…Œì´ë¸”ì— ì¸ë±ìŠ¤ê°€ í¬í•¨ë˜ì–´ 있어 뷰로 변환할 수 없습니다" +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "" -#: rewrite/rewriteDefine.c:453 +#: postmaster/postmaster.c:2108 #, c-format -msgid "could not convert table \"%s\" to a view because it has child tables" -msgstr "\"%s\" í…Œì´ë¸”ì„ ìƒì† 받는 í…Œì´ë¸”ì´ ìžˆì–´ 뷰로 변활할 수 없습니다" +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "ìž˜ëª»ëœ ì‹œìž‘ 패킷 ë ˆì´ì•„웃: 마지막 ë°”ì´íŠ¸ë¡œ 종결문ìžê°€ 발견ë˜ì—ˆìŒ" -#: rewrite/rewriteDefine.c:459 +#: postmaster/postmaster.c:2146 #, c-format -msgid "" -"could not convert table \"%s\" to a view because it has row security enabled" -msgstr "" -"로우단위 보안 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ê³  있어 \"%s\" í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" +msgid "no PostgreSQL user name specified in startup packet" +msgstr "시작 패킷ì—서 지정한 사용ìžëŠ” PostgreSQL ì‚¬ìš©ìž ì´ë¦„ì´ ì•„ë‹™ë‹ˆë‹¤" -#: rewrite/rewriteDefine.c:465 +#: postmaster/postmaster.c:2205 #, c-format -msgid "" -"could not convert table \"%s\" to a view because it has row security policies" -msgstr "로우단위 보안 ì„¤ì •ì´ ë˜ì–´ 있어 \"%s\" í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" +msgid "the database system is starting up" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ìƒˆë¡œ ê°€ë™ ì¤‘ìž…ë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:492 +#: postmaster/postmaster.c:2210 #, c-format -msgid "cannot have multiple RETURNING lists in a rule" -msgstr "í•˜ë‚˜ì˜ ruleì—서 ì—¬ëŸ¬ê°œì˜ RETURNING 목ë¡ì„ 지정할 수 없습니다" +msgid "the database system is shutting down" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì¤‘ì§€ 중입니다" -#: rewrite/rewriteDefine.c:497 +#: postmaster/postmaster.c:2215 #, c-format -msgid "RETURNING lists are not supported in conditional rules" -msgstr "RETURNING 목ë¡ì€ conditional ruleì—서는 ì§€ì›í•˜ì§€ 않습니다" +msgid "the database system is in recovery mode" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ìžë™ 복구 작업 중입니다." -#: rewrite/rewriteDefine.c:501 +#: postmaster/postmaster.c:2220 storage/ipc/procarray.c:292 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:339 #, c-format -msgid "RETURNING lists are not supported in non-INSTEAD rules" -msgstr "RETURNING 목ë¡ì€ non-INSTEAD ruleì—서는 ì§€ì›í•˜ì§€ 않습니다" +msgid "sorry, too many clients already" +msgstr "최대 ë™ì‹œ ì ‘ì†ìž 수를 초과했습니다." -#: rewrite/rewriteDefine.c:667 +#: postmaster/postmaster.c:2310 #, c-format -msgid "SELECT rule's target list has too many entries" -msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ëª©ë¡ì´ 너무 ë§Žì€ ì—”íŠ¸ë¦¬ë¥¼ 가지고 있습니다" +msgid "wrong key in cancel request for process %d" +msgstr "프로세스 %dì— ëŒ€í•œ 취소 ìš”ì²­ì— ìž˜ëª»ëœ í‚¤ê°€ 있ìŒ" -#: rewrite/rewriteDefine.c:668 +#: postmaster/postmaster.c:2318 #, c-format -msgid "RETURNING list has too many entries" -msgstr "RETURNING 목ë¡ì´ 너무 ë§Žì€ í•­ëª©ë¥¼ 가지고 있습니다" +msgid "PID %d in cancel request did not match any process" +msgstr "취소 ìš”ì²­ì˜ PID %dê³¼(와) ì¼ì¹˜í•˜ëŠ” 프로세스가 ì—†ìŒ" -#: rewrite/rewriteDefine.c:695 +#: postmaster/postmaster.c:2529 #, c-format -msgid "cannot convert relation containing dropped columns to view" -msgstr "ë·°ì—서 ì‚­ì œëœ ì—´ì„ í¬í•¨í•˜ê³  있는 릴레ì´ì…˜ì„ 변환할 수 없습니다" +msgid "received SIGHUP, reloading configuration files" +msgstr "SIGHUP 신호를 받아서, 환경설정파ì¼ì„ 다시 ì½ê³  있습니다." -#: rewrite/rewriteDefine.c:696 +#: postmaster/postmaster.c:2554 #, c-format -msgid "" -"cannot create a RETURNING list for a relation containing dropped columns" -msgstr "" -"릴레ì´ì…˜ì— ì‚­ì œëœ ì—´ì„ í¬í•¨í•˜ê³  있는 RETURNING 목ë¡ì„ 만들 수 없습니다." +msgid "pg_hba.conf was not reloaded" +msgstr "pg_hba.conf 파ì¼ì´ 다시 로드ë˜ì§€ 않았ìŒ" -#: rewrite/rewriteDefine.c:702 +#: postmaster/postmaster.c:2558 #, c-format -msgid "" -"SELECT rule's target entry %d has different column name from column \"%s\"" -msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호가(%d)ê°€ \"%s\" 칼럼 ì´ë¦„ê³¼ 틀립니다" +msgid "pg_ident.conf was not reloaded" +msgstr "pg_ident.conf 파ì¼ì´ 다시 로드ë˜ì§€ 않았ìŒ" -#: rewrite/rewriteDefine.c:704 +#: postmaster/postmaster.c:2568 #, c-format -msgid "SELECT target entry is named \"%s\"." -msgstr "SELECT ëŒ€ìƒ ì—”íŠ¸ë¦¬ ì´ë¦„ì€ \"%s\" 입니다." +msgid "SSL configuration was not reloaded" +msgstr "SSL ì„¤ì •ì´ ë‹¤ì‹œ 로드ë˜ì§€ 않았ìŒ" -#: rewrite/rewriteDefine.c:713 +#: postmaster/postmaster.c:2616 #, c-format -msgid "SELECT rule's target entry %d has different type from column \"%s\"" -msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호(%d)ê°€ \"%s\" 칼럼 ìžë£Œí˜•ê³¼ 틀립니다" +msgid "received smart shutdown request" +msgstr "smart 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:715 +#: postmaster/postmaster.c:2674 #, c-format -msgid "RETURNING list's entry %d has different type from column \"%s\"" -msgstr "RETURNING 목ë¡ì˜ %d번째 í•­ëª©ì˜ ìžë£Œí˜•ì´ \"%s\" 칼럼 ìžë£Œí˜•ê³¼ 틀립니다" +msgid "received fast shutdown request" +msgstr "fast 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:718 rewrite/rewriteDefine.c:742 +#: postmaster/postmaster.c:2707 #, c-format -msgid "SELECT target entry has type %s, but column has type %s." -msgstr "SELECT ëŒ€ìƒ ì—”íŠ¸ë¦¬ ìžë£Œí˜•ì€ %s 형ì´ì§€ë§Œ, 칼럼 ìžë£Œí˜•ì€ %s 형입니다." +msgid "aborting any active transactions" +msgstr "모든 활성화 ë˜ì–´ìžˆëŠ” íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•˜ê³  있습니다." -#: rewrite/rewriteDefine.c:721 rewrite/rewriteDefine.c:746 +#: postmaster/postmaster.c:2741 #, c-format -msgid "RETURNING list entry has type %s, but column has type %s." -msgstr "RETURNING 목ë¡ì€ %s ìžë£Œí˜•ì´ì§€ë§Œ, 칼럼 ìžë£Œí˜•ì€ %s 형입니다." +msgid "received immediate shutdown request" +msgstr "immediate 중지 ìš”ì²­ì„ ë°›ì•˜ìŠµë‹ˆë‹¤." -#: rewrite/rewriteDefine.c:737 +#: postmaster/postmaster.c:2808 #, c-format -msgid "SELECT rule's target entry %d has different size from column \"%s\"" -msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호(%d)ê°€ \"%s\" 칼럼 í¬ê¸°ì™€ 틀립니다" +msgid "shutdown at recovery target" +msgstr "복구 타겟ì—서 중지함" -#: rewrite/rewriteDefine.c:739 -#, c-format -msgid "RETURNING list's entry %d has different size from column \"%s\"" -msgstr "RETURNING 목ë¡ì˜ %d번째 í•­ëª©ì˜ í¬ê¸°ê°€ \"%s\" 칼럼 í¬ê¸°ì™€ 틀립니다" +#: postmaster/postmaster.c:2824 postmaster/postmaster.c:2847 +msgid "startup process" +msgstr "시작 프로세스" -#: rewrite/rewriteDefine.c:756 +#: postmaster/postmaster.c:2827 #, c-format -msgid "SELECT rule's target list has too few entries" -msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ëª©ë¡ì´ 너무 ì ì€ 엔트리를 가지고 있습니다" +msgid "aborting startup due to startup process failure" +msgstr "시작 프로세스 실패 ë•Œë¬¸ì— ì„œë²„ ì‹œìž‘ì´ ì¤‘ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤" -#: rewrite/rewriteDefine.c:757 +#: postmaster/postmaster.c:2888 #, c-format -msgid "RETURNING list has too few entries" -msgstr "RETURNING 목ë¡ì— 너무 ì ì€ í•­ëª©ì´ ìžˆìŠµë‹ˆë‹¤" +msgid "database system is ready to accept connections" +msgstr "ì´ì œ ë°ì´í„°ë² ì´ìФ 서버로 ì ‘ì†í•  수 있습니다" -#: rewrite/rewriteDefine.c:849 rewrite/rewriteDefine.c:964 -#: rewrite/rewriteSupport.c:112 -#, c-format -msgid "rule \"%s\" for relation \"%s\" does not exist" -msgstr " \"%s\" 룰(rule)ì´ \"%s\" 관계(relation)ì— ì§€ì •ëœ ê²ƒì´ ì—†ìŒ" +#: postmaster/postmaster.c:2909 +msgid "background writer process" +msgstr "백그ë¼ìš´ë“œ writer 프로세스" -#: rewrite/rewriteDefine.c:983 -#, c-format -msgid "renaming an ON SELECT rule is not allowed" -msgstr "ON SELECT ë£°ì˜ ì´ë¦„ 바꾸기는 허용하지 않습니다" +#: postmaster/postmaster.c:2963 +msgid "checkpointer process" +msgstr "ì²´í¬í¬ì¸íЏ 프로세스" -#: rewrite/rewriteHandler.c:528 -#, c-format -msgid "" -"WITH query name \"%s\" appears in both a rule action and the query being " -"rewritten" -msgstr "" +#: postmaster/postmaster.c:2979 +msgid "WAL writer process" +msgstr "WAL 쓰기 프로세스" -#: rewrite/rewriteHandler.c:588 -#, c-format -msgid "cannot have RETURNING lists in multiple rules" -msgstr "multiple ruleì— RETURNING 목ë¡ì„ 지정할 수 없습니다" +#: postmaster/postmaster.c:2994 +msgid "WAL receiver process" +msgstr "WAL 수신 프로세스" -#: rewrite/rewriteHandler.c:928 rewrite/rewriteHandler.c:946 -#, c-format -msgid "multiple assignments to same column \"%s\"" -msgstr "ê°™ì€ \"%s\" ì—´ì— ì§€ì •ê°’(assignment)ì´ ì¤‘ë³µë˜ì—ˆìŠµë‹ˆë‹¤" +#: postmaster/postmaster.c:3009 +msgid "autovacuum launcher process" +msgstr "autovacuum 실행기 프로세스" -#: rewrite/rewriteHandler.c:1721 rewrite/rewriteHandler.c:3331 -#, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "" -"\"%s\" 릴레ì´ì…˜(relation)ì—서 ì§€ì •ëœ ë£°ì—서 ìž˜ëª»ëœ ìž¬ê·€í˜¸ì¶œì´ ë°œê²¬ë˜ì—ˆìŠµë‹ˆë‹¤" +#: postmaster/postmaster.c:3024 +msgid "archiver process" +msgstr "archiver 프로세스" -#: rewrite/rewriteHandler.c:1806 -#, c-format -msgid "infinite recursion detected in policy for relation \"%s\"" -msgstr "\"%s\" 릴레ì´ì…˜ì˜ ì •ì±…ì—서 무한 재귀 í˜¸ì¶œì´ ë°œê²¬ ë¨" +#: postmaster/postmaster.c:3040 +msgid "statistics collector process" +msgstr "통계 수집기 프로세스" -#: rewrite/rewriteHandler.c:2123 -msgid "Junk view columns are not updatable." -msgstr "ì •í¬ ë·° ì¹¼ëŸ¼ì€ ì—…ë°ì´íŠ¸í•  수 없습니다." +#: postmaster/postmaster.c:3054 +msgid "system logger process" +msgstr "시스템 로그 프로세스" -#: rewrite/rewriteHandler.c:2128 -msgid "" -"View columns that are not columns of their base relation are not updatable." -msgstr "" +#: postmaster/postmaster.c:3116 +#, c-format +msgid "background worker \"%s\"" +msgstr "백그ë¼ìš´ë“œ ìž‘ì—…ìž \"%s\"" -#: rewrite/rewriteHandler.c:2131 -msgid "View columns that refer to system columns are not updatable." -msgstr "" +#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 +#: postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 +msgid "server process" +msgstr "서버 프로세스" -#: rewrite/rewriteHandler.c:2134 -msgid "View columns that return whole-row references are not updatable." -msgstr "" +#: postmaster/postmaster.c:3299 +#, c-format +msgid "terminating any other active server processes" +msgstr "다른 활성화 ë˜ì–´ìžˆëŠ” 서버 프로세스를 마치고 있는 중입니다" -#: rewrite/rewriteHandler.c:2192 -msgid "Views containing DISTINCT are not automatically updatable." -msgstr "" +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3555 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) í”„ë¡œê·¸ëž¨ì€ %d 코드로 마쳤습니다" -#: rewrite/rewriteHandler.c:2195 -msgid "Views containing GROUP BY are not automatically updatable." +#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 +#: postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 +#: postmaster/postmaster.c:3598 +#, c-format +msgid "Failed process was running: %s" msgstr "" -#: rewrite/rewriteHandler.c:2198 -msgid "Views containing HAVING are not automatically updatable." -msgstr "" +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3565 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) 프로세스가 0x%X 예외로 ì¸í•´ 종료ë¨" -#: rewrite/rewriteHandler.c:2201 -msgid "" -"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." -msgstr "" +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3575 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) 프로세스가 %d번 시그ë„ì„ ë°›ì•„ 종료ë¨: %s" -#: rewrite/rewriteHandler.c:2204 -msgid "Views containing WITH are not automatically updatable." -msgstr "" +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3586 +#, c-format +msgid "%s (PID %d) was terminated by signal %d" +msgstr "%s (PID %d) 프로세스가 %d번 시그ë„ì„ ë°›ì•„ 종료ë¨" -#: rewrite/rewriteHandler.c:2207 -msgid "Views containing LIMIT or OFFSET are not automatically updatable." -msgstr "" +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3596 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) 프로세스가 ì¸ì‹í•  수 없는 %d ìƒíƒœë¡œ 종료ë¨" -#: rewrite/rewriteHandler.c:2219 -msgid "Views that return aggregate functions are not automatically updatable." -msgstr "" +#: postmaster/postmaster.c:3783 +#, c-format +msgid "abnormal database system shutdown" +msgstr "비정ìƒì ì¸ ë°ì´í„°ë² ì´ìФ 시스템 서비스를 중지" -#: rewrite/rewriteHandler.c:2222 -msgid "Views that return window functions are not automatically updatable." -msgstr "" +#: postmaster/postmaster.c:3823 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "모든 서버 프로세스가 중지 ë˜ì—ˆìŠµë‹ˆë‹¤; 재 초기화 중" -#: rewrite/rewriteHandler.c:2225 -msgid "" -"Views that return set-returning functions are not automatically updatable." -msgstr "" +#: postmaster/postmaster.c:3993 postmaster/postmaster.c:5418 +#: postmaster/postmaster.c:5782 +#, c-format +msgid "could not generate random cancel key" +msgstr "무작위 취소 키를 만들 수 ì—†ìŒ" -#: rewrite/rewriteHandler.c:2232 rewrite/rewriteHandler.c:2236 -#: rewrite/rewriteHandler.c:2243 -msgid "" -"Views that do not select from a single table or view are not automatically " -"updatable." -msgstr "" +#: postmaster/postmaster.c:4047 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "ì—°ê²°ì„ ìœ„í•œ 새 프로세스 할당(fork) 실패: %m" -#: rewrite/rewriteHandler.c:2246 -msgid "Views containing TABLESAMPLE are not automatically updatable." -msgstr "" +#: postmaster/postmaster.c:4089 +msgid "could not fork new process for connection: " +msgstr "ì—°ê²°ì„ ìœ„í•œ 새 프로세스 할당(fork) 실패: " -#: rewrite/rewriteHandler.c:2270 -msgid "Views that have no updatable columns are not automatically updatable." -msgstr "" +#: postmaster/postmaster.c:4203 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "ì ‘ì† ìˆ˜ë½: host=%s port=%s" -#: rewrite/rewriteHandler.c:2724 +#: postmaster/postmaster.c:4208 #, c-format -msgid "cannot insert into column \"%s\" of view \"%s\"" -msgstr "\"%s\" 칼럼 (해당 ë·°: \"%s\")ì— ìžë£Œë¥¼ 입력할 수 없습니다" +msgid "connection received: host=%s" +msgstr "ì ‘ì† ìˆ˜ë½: host=%s" -#: rewrite/rewriteHandler.c:2732 +#: postmaster/postmaster.c:4493 #, c-format -msgid "cannot update column \"%s\" of view \"%s\"" -msgstr "\"%s\" 칼럼 (해당 ë·°: \"%s\")ì— ìžë£Œë¥¼ 갱신할 수 없습니다" +msgid "could not execute server process \"%s\": %m" +msgstr "\"%s\" 서버 프로세스를 실행할 수 ì—†ìŒ: %m" -#: rewrite/rewriteHandler.c:3130 +#: postmaster/postmaster.c:4646 #, c-format -msgid "" -"DO INSTEAD NOTHING rules are not supported for data-modifying statements in " -"WITH" +msgid "giving up after too many tries to reserve shared memory" msgstr "" -#: rewrite/rewriteHandler.c:3144 +#: postmaster/postmaster.c:4647 #, c-format -msgid "" -"conditional DO INSTEAD rules are not supported for data-modifying statements " -"in WITH" +msgid "This might be caused by ASLR or antivirus software." msgstr "" -#: rewrite/rewriteHandler.c:3148 +#: postmaster/postmaster.c:4858 #, c-format -msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgid "SSL configuration could not be loaded in child process" msgstr "" -#: rewrite/rewriteHandler.c:3153 +#: postmaster/postmaster.c:4990 #, c-format -msgid "" -"multi-statement DO INSTEAD rules are not supported for data-modifying " -"statements in WITH" -msgstr "" +msgid "Please report this to ." +msgstr "ì´ ë‚´ìš©ì„ ì£¼ì†Œë¡œ 보고하십시오." -#: rewrite/rewriteHandler.c:3368 +#: postmaster/postmaster.c:5077 #, c-format -msgid "cannot perform INSERT RETURNING on relation \"%s\"" -msgstr "\"%s\" 릴레ì´ì…˜ì—서 INSERT RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 ì—†ìŒ" +msgid "database system is ready to accept read only connections" +msgstr "ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì´ ì½ê¸° 전용으로 ì—°ê²°ì„ ìˆ˜ë½í•  준비가 ë˜ì—ˆìŠµë‹ˆë‹¤." -#: rewrite/rewriteHandler.c:3370 +#: postmaster/postmaster.c:5346 #, c-format -msgid "" -"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." -msgstr "" -"RETURNING ì ˆì—서는 무조건 ON INSERT DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆ" -"다." +msgid "could not fork startup process: %m" +msgstr "시작 프로세스 할당(fork) 실패: %m" -#: rewrite/rewriteHandler.c:3375 +#: postmaster/postmaster.c:5350 #, c-format -msgid "cannot perform UPDATE RETURNING on relation \"%s\"" -msgstr "\"%s\" 릴레ì´ì…˜ì—서 UPDATE RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 없습니다." +msgid "could not fork background writer process: %m" +msgstr "백그ë¼ìš´ writer 프로세스를 할당(fork)í•  수 없습니다: %m" -#: rewrite/rewriteHandler.c:3377 +#: postmaster/postmaster.c:5354 #, c-format -msgid "" -"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." -msgstr "" -"RETURNING ì ˆì—서는 무조건 ON UPDATE DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆ" -"다." +msgid "could not fork checkpointer process: %m" +msgstr "ì²´í¬í¬ì¸íЏ 프로세스를 할당(fork)í•  수 없습니다: %m" -#: rewrite/rewriteHandler.c:3382 +#: postmaster/postmaster.c:5358 #, c-format -msgid "cannot perform DELETE RETURNING on relation \"%s\"" -msgstr "\"%s\" 릴레ì´ì…˜ì—서 DELETE RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 없습니다." +msgid "could not fork WAL writer process: %m" +msgstr "WAL 쓰기 프로세스를 할당(fork)í•  수 ì—†ìŒ: %m" -#: rewrite/rewriteHandler.c:3384 +#: postmaster/postmaster.c:5362 #, c-format -msgid "" -"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." -msgstr "" -"TURNING ì ˆì—서는 무조건 ON DELETE DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆë‹¤" +msgid "could not fork WAL receiver process: %m" +msgstr "WAL 수신 프로세스를 할당(fork)í•  수 ì—†ìŒ: %m" -#: rewrite/rewriteHandler.c:3402 +#: postmaster/postmaster.c:5366 #, c-format -msgid "" -"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or " -"UPDATE rules" -msgstr "" +msgid "could not fork process: %m" +msgstr "프로세스 할당(fork) 실패: %m" -#: rewrite/rewriteHandler.c:3459 +#: postmaster/postmaster.c:5553 postmaster/postmaster.c:5576 #, c-format -msgid "" -"WITH cannot be used in a query that is rewritten by rules into multiple " -"queries" +msgid "database connection requirement not indicated during registration" msgstr "" -#: rewrite/rewriteManip.c:1003 +#: postmaster/postmaster.c:5560 postmaster/postmaster.c:5583 #, c-format -msgid "conditional utility statements are not implemented" -msgstr "" -"ì¡°ê±´ 유틸리티 명령 구문(conditional utility statement)ì€ êµ¬í˜„ë˜ì–´ìžˆì§€ 않습니" -"다" +msgid "invalid processing mode in background worker" +msgstr "백그ë¼ìš´ë“œ 작업ìžì—서 ìž˜ëª»ëœ í”„ë¡œì„¸ì‹± 모드가 사용ë¨" -#: rewrite/rewriteManip.c:1169 +#: postmaster/postmaster.c:5655 #, c-format -msgid "WHERE CURRENT OF on a view is not implemented" -msgstr "ë·°ì— ëŒ€í•œ WHERE CURRENT OF êµ¬ë¬¸ì´ êµ¬í˜„ë˜ì§€ 않ìŒ" +msgid "starting background worker process \"%s\"" +msgstr "\"%s\" 백그ë¼ìš´ë“œ ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 시작합니다." -#: rewrite/rewriteManip.c:1434 +#: postmaster/postmaster.c:5667 #, c-format -msgid "" -"NEW variables in ON UPDATE rules cannot reference columns that are part of a " -"multiple assignment in the subject UPDATE command" -msgstr "" +msgid "could not fork worker process: %m" +msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 할당(fork)í•  수 ì—†ìŒ: %m" -#: rewrite/rewriteSupport.c:154 +#: postmaster/postmaster.c:6100 #, c-format -msgid "rule \"%s\" does not exist" -msgstr "\"%s\" 룰(rule) ì—†ìŒ" +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "백엔드ì—서 사용하기 위해 %d ì†Œì¼“ì„ ë³µì‚¬í•  수 ì—†ìŒ: 오류 코드 %d" -#: rewrite/rewriteSupport.c:167 +#: postmaster/postmaster.c:6132 #, c-format -msgid "there are multiple rules named \"%s\"" -msgstr "\"%s\" ì´ë¦„ì˜ ë£°(rule)ì´ ì—¬ëŸ¬ê°œ 있습니다" +msgid "could not create inherited socket: error code %d\n" +msgstr "ìƒì†ëœ ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ: 오류 코드 %d\n" -#: rewrite/rewriteSupport.c:168 +#: postmaster/postmaster.c:6161 #, c-format -msgid "Specify a relation name as well as a rule name." -msgstr "룰(rule) ì´ë¦„ê³¼ 함께 릴레ì´ì…˜(relation) ì´ë¦„ë„ ì§€ì •í•˜ì‹­ì‹œì˜¤" +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "\"%s\" 백엔드 변수 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: snowball/dict_snowball.c:177 +#: postmaster/postmaster.c:6168 #, c-format -msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" -msgstr "\"%s\" 언어 ë° \"%s\" ì¸ì½”ë”©ì— ì‚¬ìš© 가능한 Snowball stemmerê°€ ì—†ìŒ" +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "\"%s\" 백엔드 변수 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:73 -#: tsearch/dict_simple.c:48 +#: postmaster/postmaster.c:6177 #, c-format -msgid "multiple StopWords parameters" -msgstr "StopWords 매개 변수가 여러 ê°œ 있ìŒ" +msgid "could not remove file \"%s\": %s\n" +msgstr "\"%s\" 파ì¼ì„ 삭제할 수 ì—†ìŒ: %s\n" -#: snowball/dict_snowball.c:209 +#: postmaster/postmaster.c:6194 #, c-format -msgid "multiple Language parameters" -msgstr "여러 ê°œì˜ ì–¸ì–´ 매개 변수가 있ìŒ" +msgid "could not map view of backend variables: error code %lu\n" +msgstr "백엔드 변수 파ì¼ì˜ view를 mapí•  수 ì—†ìŒ: 오류 코드 %lu\n" -#: snowball/dict_snowball.c:216 +#: postmaster/postmaster.c:6203 #, c-format -msgid "unrecognized Snowball parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 Snowball 매개 변수: \"%s\"" +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "백엔드 변수 파ì¼ì˜ view를 unmapí•  수 ì—†ìŒ: 오류 코드 %lu\n" -#: snowball/dict_snowball.c:224 +#: postmaster/postmaster.c:6210 #, c-format -msgid "missing Language parameter" -msgstr "Language 매개 변수가 누ë½ë¨" +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "백엔드 변수 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: 오류 코드 %lu\n" -#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 +#: postmaster/postmaster.c:6371 #, c-format -msgid "cannot access temporary tables of other sessions" -msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ" +msgid "could not read exit code for process\n" +msgstr "í”„ë¡œì„¸ìŠ¤ì˜ ì¢…ë£Œ 코드를 ì½ì„ 수 ì—†ìŒ\n" -#: storage/buffer/bufmgr.c:807 +#: postmaster/postmaster.c:6376 #, c-format -msgid "unexpected data beyond EOF in block %u of relation %s" -msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì— EOF 범위를 넘는 예기치 ì•Šì€ ë°ì´í„°ê°€ 있ìŒ" +msgid "could not post child completion status\n" +msgstr "하위 완료 ìƒíƒœë¥¼ 게시할 수 ì—†ìŒ\n" -#: storage/buffer/bufmgr.c:809 +#: postmaster/syslogger.c:470 postmaster/syslogger.c:1146 #, c-format -msgid "" -"This has been seen to occur with buggy kernels; consider updating your " -"system." -msgstr "ì´ ë¬¸ì œëŠ” 커ë„ì˜ ë¬¸ì œë¡œ 알려졌습니다. ì‹œìŠ¤í…œì„ ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤." +msgid "could not read from logger pipe: %m" +msgstr "로그 파ì´í”„ì—서 ì½ê¸° 실패: %m" -#: storage/buffer/bufmgr.c:907 +#: postmaster/syslogger.c:520 #, c-format -msgid "invalid page in block %u of relation %s; zeroing out page" -msgstr "" -"%u 블ë¡(해당 릴레ì´ì…˜: %s)ì— ìž˜ëª»ëœ íŽ˜ì´ì§€ í—¤ë”ê°€ 있ìŒ, 페ì´ì§€ë¥¼ 삭제하는 중" +msgid "logger shutting down" +msgstr "로그 작업 ë내는 중" -#: storage/buffer/bufmgr.c:3952 +#: postmaster/syslogger.c:564 postmaster/syslogger.c:578 #, c-format -msgid "could not write block %u of %s" -msgstr "%u/%s 블ë¡ì„ 쓸 수 ì—†ìŒ" +msgid "could not create pipe for syslog: %m" +msgstr "syslogì—서 사용할 파ì´í”„를 만들 수 없습니다: %m" -#: storage/buffer/bufmgr.c:3954 +#: postmaster/syslogger.c:629 #, c-format -msgid "Multiple failures --- write error might be permanent." -msgstr "여러 번 실패 --- 쓰기 오류가 ì˜êµ¬ì ì¼ 수 있습니다." +msgid "could not fork system logger: %m" +msgstr "시스템 로거(logger)를 확보하질 못 했습니다: %m" -#: storage/buffer/bufmgr.c:3975 storage/buffer/bufmgr.c:3994 +#: postmaster/syslogger.c:665 #, c-format -msgid "writing block %u of relation %s" -msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì„ ì“°ëŠ” 중" +msgid "redirecting log output to logging collector process" +msgstr "서버 로그를 로그 수집 프로세스로 보냅니다." -#: storage/buffer/bufmgr.c:4295 +#: postmaster/syslogger.c:666 #, c-format -msgid "snapshot too old" -msgstr "" +msgid "Future log output will appear in directory \"%s\"." +msgstr "ì´ì œë¶€í„° 서버 로그는 \"%s\" ë””ë ‰í„°ë¦¬ì— ë³´ê´€ë©ë‹ˆë‹¤." -#: storage/buffer/localbuf.c:199 +#: postmaster/syslogger.c:674 #, c-format -msgid "no empty local buffer available" -msgstr "비어 있는 로컬 버í¼ê°€ 없습니다" +msgid "could not redirect stdout: %m" +msgstr "í‘œì¤€ì¶œë ¥ì„ redirect 하지 못했습니다: %m" -#: storage/buffer/localbuf.c:427 +#: postmaster/syslogger.c:679 postmaster/syslogger.c:696 #, c-format -msgid "cannot access temporary tables during a parallel operation" -msgstr "병렬 작업 ì¤‘ì— ìž„ì‹œ í…Œì´ë¸”ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ" +msgid "could not redirect stderr: %m" +msgstr "표준오류(stderr)를 redirect 하지 못했습니다: %m" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: postmaster/syslogger.c:1101 #, c-format -msgid "could not flush dirty data: %m" -msgstr "dirty ìžë£Œë¥¼ flush í•  수 ì—†ìŒ: %m" +msgid "could not write to log file: %s\n" +msgstr "ë¡œê·¸íŒŒì¼ ì“°ê¸° 실패: %s\n" -#: storage/file/fd.c:473 +#: postmaster/syslogger.c:1218 #, c-format -msgid "could not determine dirty data size: %m" -msgstr "dirty ìžë£Œ í¬ê¸°ë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" 잠금파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: storage/file/fd.c:525 +#: postmaster/syslogger.c:1280 postmaster/syslogger.c:1330 #, c-format -msgid "could not munmap() while flushing data: %m" -msgstr "ìžë£Œ flush 작업 ë„중 munmap() 호출 실패: %m" +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "ë¡œê·¸íŒŒì¼ ìžë™ êµì²´ ê¸°ëŠ¥ì„ ê¸ˆì§€í•©ë‹ˆë‹¤(êµì²´í•˜ë ¤ë©´ SIGHUP 시그ë„ì„ ì‚¬ìš©í•¨)" -#: storage/file/fd.c:689 +#: regex/regc_pg_locale.c:262 #, c-format -msgid "could not link file \"%s\" to \"%s\": %m" -msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ë§í¬í•  수 ì—†ìŒ: %m" +msgid "could not determine which collation to use for regular expression" +msgstr "ì •ê·œì‹ì„ 사용해서 사용할 정렬규칙(collation)ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: storage/file/fd.c:783 +#: repl_gram.y:336 repl_gram.y:368 #, c-format -msgid "getrlimit failed: %m" -msgstr "getrlimit 실패: %m" +msgid "invalid timeline %u" +msgstr "ìž˜ëª»ëœ íƒ€ìž„ë¼ì¸: %u" -#: storage/file/fd.c:873 -#, c-format -msgid "insufficient file descriptors available to start server process" -msgstr "" -"서버 프로세스를 실행하기 위해서 열어야할 파ì¼ë“¤ì„ 못 ì—´ê³  있습니다. 다른 프로" -"그램ì—서 너무 ë§Žì€ íŒŒì¼ì„ ì—´ì–´ ë‘ê³  있습니다. 다른 í”„ë¡œê·¸ëž¨ë“¤ì„ ì¢€ ë‹«ê³  다시 " -"시ë„í•´ 보십시오" +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "ìž˜ëª»ëœ ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 위치" + +#: repl_scanner.l:180 scan.l:683 +msgid "unterminated quoted string" +msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ë¬¸ìžì—´" -#: storage/file/fd.c:874 +#: replication/basebackup.c:336 #, c-format -msgid "System allows %d, we need at least %d." -msgstr "시스템 허용치 %d, 서버 최소 허용치 %d." +msgid "could not stat control file \"%s\": %m" +msgstr "\"%s\" 컨트롤 파ì¼ì˜ 정보를 구할 수 ì—†ìŒ: %m" -#: storage/file/fd.c:915 storage/file/fd.c:2078 storage/file/fd.c:2171 -#: storage/file/fd.c:2319 +#: replication/basebackup.c:443 #, c-format -msgid "out of file descriptors: %m; release and retry" -msgstr "" -"ì—´ë ¤ 있는 파ì¼ì´ 너무 많습니다: %m; 다른 í”„ë¡œê·¸ëž¨ë“¤ì„ ì¢€ ë‹«ê³  다시 시ë„í•´ ë³´" -"십시오" +msgid "could not find any WAL files" +msgstr "ì–´ë–¤ WAL 파ì¼ë„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: storage/file/fd.c:1520 +#: replication/basebackup.c:457 replication/basebackup.c:472 +#: replication/basebackup.c:481 #, c-format -msgid "temporary file: path \"%s\", size %lu" -msgstr "임시 파ì¼: 경로 \"%s\", í¬ê¸° %lu" +msgid "could not find WAL file \"%s\"" +msgstr "\"%s\" WAL íŒŒì¼ ì°¾ê¸° 실패" -#: storage/file/fd.c:1717 +#: replication/basebackup.c:523 replication/basebackup.c:551 #, c-format -msgid "temporary file size exceeds temp_file_limit (%dkB)" -msgstr "임시 íŒŒì¼ í¬ê¸°ê°€ temp_file_limit (%dkB)를 초과했습니다" +msgid "unexpected WAL file size \"%s\"" +msgstr "\"%s\" WAL 파ì¼ì˜ í¬ê¸°ê°€ 알맞지 않ìŒ" -#: storage/file/fd.c:2054 storage/file/fd.c:2104 +#: replication/basebackup.c:537 replication/basebackup.c:1529 #, c-format -msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" -msgstr "" +msgid "base backup could not send data, aborting backup" +msgstr "ë² ì´ìФ 백업ì—서 ìžë£Œë¥¼ 보낼 수 ì—†ìŒ. ë°±ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." -#: storage/file/fd.c:2144 +#: replication/basebackup.c:609 #, c-format -msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" -msgstr "" +msgid "%s total checksum verification failures" +msgstr "%s ì „ì²´ ì²´í¬ì„¬ 검사 실패" -#: storage/file/fd.c:2295 +#: replication/basebackup.c:613 #, c-format -msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgid "checksum verification failure during base backup" msgstr "" -#: storage/file/fd.c:2381 +#: replication/basebackup.c:657 replication/basebackup.c:666 +#: replication/basebackup.c:675 replication/basebackup.c:684 +#: replication/basebackup.c:693 replication/basebackup.c:704 +#: replication/basebackup.c:721 replication/basebackup.c:730 #, c-format -msgid "could not read directory \"%s\": %m" -msgstr "\"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %m" +msgid "duplicate option \"%s\"" +msgstr "\"%s\" ì˜µì…˜ì„ ë‘ ë²ˆ 지정했습니다" -#: storage/ipc/dsm.c:363 +#: replication/basebackup.c:710 utils/misc/guc.c:6013 #, c-format -msgid "dynamic shared memory control segment is corrupt" -msgstr "ë™ì  공유 메모리 제어 ì¡°ê°ì´ ì†ìƒë˜ì—ˆìŒ" +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d ê°’ì€ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ìœ¼ë¡œ 타당한 범위(%d .. %d)를 벗어났습니다." -#: storage/ipc/dsm.c:410 +#: replication/basebackup.c:984 replication/basebackup.c:1154 #, c-format -msgid "dynamic shared memory is disabled" -msgstr "ë™ì  공유 메모리 ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ìžˆìŒ" +msgid "could not stat file or directory \"%s\": %m" +msgstr "íŒŒì¼ ë˜ëŠ” 디렉터리 \"%s\"ì˜ ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" -#: storage/ipc/dsm.c:411 +#: replication/basebackup.c:1309 #, c-format -msgid "Set dynamic_shared_memory_type to a value other than \"none\"." -msgstr "dynamic_shared_memory_type ì„¤ì •ê°’ì„ \"none\" 아닌 값으로 지정하세요." +msgid "skipping special file \"%s\"" +msgstr "\"%s\" 특수 파ì¼ì„ 건너뜀" -#: storage/ipc/dsm.c:431 +#: replication/basebackup.c:1414 #, c-format -msgid "dynamic shared memory control segment is not valid" -msgstr "ë™ì  공유 메모리 제어 ì¡°ê°ì´ 타당하지 않ìŒ" +msgid "invalid segment number %d in file \"%s\"" +msgstr "ìž˜ëª»ëœ ì¡°ê° ë²ˆí˜¸ %d, 해당 파ì¼: \"%s\"" -#: storage/ipc/dsm.c:516 +#: replication/basebackup.c:1433 #, c-format -msgid "too many dynamic shared memory segments" -msgstr "너무 ë§Žì€ ë™ì  공유 메모리 ì¡°ê°ì´ 있ìŒ" +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 -#: storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 -#: storage/ipc/dsm_impl.c:819 storage/ipc/dsm_impl.c:961 +#: replication/basebackup.c:1477 replication/basebackup.c:1493 #, c-format -msgid "could not unmap shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ unmap í•  수 ì—†ìŒ: %m" +msgid "could not fseek in file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì—서 fseek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 -#: storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:829 +#: replication/basebackup.c:1485 #, c-format -msgid "could not remove shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ 삭제할 수 ì—†ìŒ: %m" +msgid "could not reread block %d of file \"%s\": %m" +msgstr "%d ë¸”ëŸ­ì„ \"%s\" 파ì¼ì—서 다시 ì½ì„ 수 ì—†ìŒ: %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:729 -#: storage/ipc/dsm_impl.c:843 +#: replication/basebackup.c:1509 #, c-format -msgid "could not open shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "\"%s\" íŒŒì¼ ì²´í¬ì„¬ 검사 실패(해당 블럭 %d): ê³„ì‚°ëœ ì²´í¬ì„¬ì€ %X ê°’ì´ì§€ë§Œ, 기대값 %X" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 -#: storage/ipc/dsm_impl.c:774 storage/ipc/dsm_impl.c:867 +#: replication/basebackup.c:1516 #, c-format -msgid "could not stat shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê° íŒŒì¼ì˜ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %m" +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:886 -#: storage/ipc/dsm_impl.c:934 +#: replication/basebackup.c:1574 #, c-format -msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê° íŒŒì¼ì„ %zu ë°”ì´íŠ¸ë¡œ í¬ê¸° ì¡°ì ˆ í•  수 ì—†ìŒ: %m" +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 -#: storage/ipc/dsm_impl.c:750 storage/ipc/dsm_impl.c:985 +#: replication/basebackup.c:1602 #, c-format -msgid "could not map shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ map í•  수 ì—†ìŒ: %m" +msgid "file name too long for tar format: \"%s\"" +msgstr "tar 파ì¼ë¡œ 묶기ì—는 íŒŒì¼ ì´ë¦„ì´ ë„ˆë¬´ 긺: \"%s\"" -#: storage/ipc/dsm_impl.c:515 +#: replication/basebackup.c:1607 #, c-format -msgid "could not get shared memory segment: %m" -msgstr "공유 메모리 ì¡°ê°ì„ 가져올 수 ì—†ìŒ: %m" +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "tar í¬ë©§ì„ 사용하기ì—는 심볼릭 ë§í¬ì˜ ëŒ€ìƒ ê²½ë¡œê°€ 너무 ê¹ë‹ˆë‹¤: íŒŒì¼ ì´ë¦„ \"%s\", ëŒ€ìƒ \"%s\"" -#: storage/ipc/dsm_impl.c:714 +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 #, c-format -msgid "could not create shared memory segment \"%s\": %m" -msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ 만들 수 ì—†ìŒ: %m" +msgid "invalid connection string syntax: %s" +msgstr "ìž˜ëª»ëœ ì—°ê²° 문ìžì—´ 구문: %s" -#: storage/ipc/dsm_impl.c:1026 +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 #, c-format -msgid "could not duplicate handle for \"%s\": %m" -msgstr "\"%s\" ìš© 헨들러를 ì´ì¤‘í™” í•  수 ì—†ìŒ: %m" +msgid "could not parse connection string: %s" +msgstr "ì ‘ì† ë¬¸ìžì—´ì„ ë¶„ì„í•  수 ì—†ìŒ: %s" -#: storage/ipc/latch.c:778 +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 #, c-format -msgid "epoll_ctl() failed: %m" -msgstr "epoll_ctl() 실패: %m" +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "주 서버ì—서 ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„번호와 타임ë¼ì¸ 번호를 ë°›ì„ ìˆ˜ ì—†ìŒ: %s" -#: storage/ipc/latch.c:1002 +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 +#: replication/libpqwalreceiver/libpqwalreceiver.c:550 #, c-format -msgid "epoll_wait() failed: %m" -msgstr "epoll_wait() 실패: %m" +msgid "invalid response from primary server" +msgstr "주 서버ì—서 ìž˜ëª»ëœ ì‘ë‹µì´ ì™”ìŒ" -#: storage/ipc/latch.c:1122 +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 #, c-format -msgid "poll() failed: %m" -msgstr "poll() 실패: %m" +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "ì‹œìŠ¤í…œì„ ì‹ë³„í•  수 ì—†ìŒ: 로우수 %d, 필드수 %d, 예ìƒê°’: 로우수 %d, 필드수 %d ì´ìƒ" -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:189 storage/ipc/shmem.c:212 -#: storage/lmgr/lock.c:883 storage/lmgr/lock.c:917 storage/lmgr/lock.c:2682 -#: storage/lmgr/lock.c:4007 storage/lmgr/lock.c:4072 storage/lmgr/lock.c:4364 -#: storage/lmgr/predicate.c:2329 storage/lmgr/predicate.c:2344 -#: storage/lmgr/predicate.c:3736 storage/lmgr/predicate.c:4879 -#: storage/lmgr/proc.c:203 utils/hash/dynahash.c:1043 +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 +#: replication/libpqwalreceiver/libpqwalreceiver.c:416 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format -msgid "out of shared memory" -msgstr "공유 메모리 부족" +msgid "could not start WAL streaming: %s" +msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ìž‘ì—…ì„ ì‹œìž‘í•  수 ì—†ìŒ: %s" -#: storage/ipc/shmem.c:370 storage/ipc/shmem.c:421 +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 #, c-format -msgid "" -"not enough shared memory for data structure \"%s\" (%zu bytes requested)" -msgstr "\"%s\" ìžë£Œ 구조체용 공유 메모리가 부족함 (%zu ë°”ì´íŠ¸ê°€ 필요함)" +msgid "could not send end-of-streaming message to primary: %s" +msgstr "주 서버로 ìŠ¤íŠ¸ë¦¬ë° ì¢…ë£Œ 메시지를 보낼 수 ì—†ìŒ: %s" -#: storage/ipc/shmem.c:389 +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 #, c-format -msgid "could not create ShmemIndex entry for data structure \"%s\"" -msgstr "\"%s\" ìžë£Œ 구조체용 ShmemIndex í•­ëª©ì„ ë§Œë“¤ 수 ì—†ìŒ" +msgid "unexpected result set after end-of-streaming" +msgstr "ìŠ¤íŠ¸ë¦¬ë° ì¢…ë£Œ ìš”ì²­ì— ëŒ€í•œ ìž˜ëª»ëœ ì‘ë‹µì„ ë°›ìŒ" -#: storage/ipc/shmem.c:404 +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 #, c-format -msgid "" -"ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, " -"actual %zu" -msgstr "" -"\"%s\" ìžë£Œ 구조체용 ShmemIndex 항목 í¬ê¸°ê°€ 잘못ë¨: 기대값 %zu, 현재값 %zu" +msgid "error while shutting down streaming COPY: %s" +msgstr "COPY ìŠ¤íŠ¸ë¦¬ë° ì¢…ë£Œ 중 오류 ë°œìƒ: %s" -#: storage/ipc/shmem.c:452 storage/ipc/shmem.c:471 +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 #, c-format -msgid "requested shared memory size overflows size_t" -msgstr "지정한 공유 메모리 사ì´ì¦ˆê°€ size_t í¬ê¸°ë¥¼ 초과했습니다" +msgid "error reading result of streaming command: %s" +msgstr "ìŠ¤íŠ¸ë¦¬ë° ëª…ë ¹ì— ëŒ€í•œ ê²°ê³¼ 처리ì—서 오류 ë°œìƒ: %s" -#: storage/ipc/standby.c:530 tcop/postgres.c:2976 +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 #, c-format -msgid "canceling statement due to conflict with recovery" -msgstr "복구 작업 중 ì¶©ëŒì´ ë°œìƒí•´ ìž‘ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." +msgid "unexpected result after CommandComplete: %s" +msgstr "CommandComplete 작업 후 예ìƒì¹˜ 못한 결과를 ë°›ìŒ: %s" -#: storage/ipc/standby.c:531 tcop/postgres.c:2263 +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 #, c-format -msgid "User transaction caused buffer deadlock with recovery." -msgstr "복구 작업 중 ì‚¬ìš©ìž íŠ¸ëžœìž­ì…˜ì´ ë²„í¼ ë°ë“œë½ì„ 만들었습니다." +msgid "could not receive timeline history file from the primary server: %s" +msgstr "주 서버ì—서 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ ë°›ì„ ìˆ˜ ì—†ìŒ: %s" -#: storage/large_object/inv_api.c:203 +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 #, c-format -msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" -msgstr "" +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "2ê°œì˜ ì¹¼ëŸ¼ìœ¼ë¡œ ëœ í•˜ë‚˜ì˜ íŠœí”Œì„ ì˜ˆìƒí•˜ì§€ë§Œ, %d 튜플 (%d 칼럼)ì„ ìˆ˜ì‹ í•¨" -#: storage/large_object/inv_api.c:284 +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 +#: replication/libpqwalreceiver/libpqwalreceiver.c:756 +#: replication/libpqwalreceiver/libpqwalreceiver.c:762 #, c-format -msgid "invalid flags for opening a large object: %d" -msgstr "대형 ê°ì²´ë¥¼ 열기 위한 플래그가 잘못 ë¨: %d" +msgid "could not receive data from WAL stream: %s" +msgstr "WAL 스트림ì—서 ìžë£Œ 받기 실패: %s" -#: storage/large_object/inv_api.c:436 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 #, c-format -msgid "invalid whence setting: %d" -msgstr "" +msgid "could not send data to WAL stream: %s" +msgstr "WAL ìŠ¤íŠ¸ë¦¼ì— ë°ì´í„°ë¥¼ 보낼 수 ì—†ìŒ: %s" -#: storage/large_object/inv_api.c:593 +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 #, c-format -msgid "invalid large object write request size: %d" -msgstr "유효하지 ì•Šì€ ëŒ€í˜• ê°ì²´ì˜ 쓰기 ìš”ì²­ëœ í¬ê¸°: %d" +msgid "could not create replication slot \"%s\": %s" +msgstr "\"%s\" 복제 ìŠ¬ë¡¯ì„ ë§Œë“¤ 수 ì—†ìŒ: %s" -#: storage/lmgr/deadlock.c:1109 +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 #, c-format -msgid "Process %d waits for %s on %s; blocked by process %d." -msgstr "" -"%d 프로세스가 %s ìƒíƒœë¡œ 지연ë˜ê³  있ìŒ(해당 작업: %s); %d í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ 블ë¡" -"킹ë˜ì—ˆìŒ" +msgid "invalid query response" +msgstr "ìž˜ëª»ëœ ì¿¼ë¦¬ ì‘답" -#: storage/lmgr/deadlock.c:1128 +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 #, c-format -msgid "Process %d: %s" -msgstr "프로세스 %d: %s" +msgid "Expected %d fields, got %d fields." +msgstr "%dê°œì˜ ì¹¼ëŸ¼ì„ ì˜ˆìƒí•˜ì§€ë§Œ, %dê°œì˜ ì¹¼ëŸ¼ì„ ìˆ˜ì‹ í•¨" -#: storage/lmgr/deadlock.c:1137 +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 #, c-format -msgid "deadlock detected" -msgstr "deadlock ë°œìƒí–ˆìŒ" +msgid "the query interface requires a database connection" +msgstr "ì´ ì¿¼ë¦¬ ì¸í„°íŽ˜ì´ìŠ¤ëŠ” ë°ì´í„°ë² ì´ìФ ì—°ê²°ì´ í•„ìš”í•©ë‹ˆë‹¤" -#: storage/lmgr/deadlock.c:1140 -#, c-format -msgid "See server log for query details." -msgstr "쿼리 ìƒì„¸ 정보는 서버 로그를 참조하십시오." +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 +msgid "empty query" +msgstr "빈 쿼리" -#: storage/lmgr/lmgr.c:719 +#: replication/logical/launcher.c:310 #, c-format -msgid "while updating tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ê°±ì‹ í•˜ëŠ” ì¤‘ì— ë°œìƒ" +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "\"%s\" 구ë…ì„ ìœ„í•´ 논리 복제 작업ìžë¥¼ 시작합니다" -#: storage/lmgr/lmgr.c:722 +#: replication/logical/launcher.c:317 #, c-format -msgid "while deleting tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ì‚­ì œí•˜ëŠ” ì¤‘ì— ë°œìƒ" +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "max_replication_slots = 0 설정 ë•Œë¬¸ì— ë…¼ë¦¬ 복제 작업ìžë¥¼ 시작 í•  수 없습니다" -#: storage/lmgr/lmgr.c:725 +#: replication/logical/launcher.c:397 #, c-format -msgid "while locking tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u íŠœí”Œì„ \"%s\" 릴레ì´ì…˜ì—서 잠그는 ì¤‘ì— ë°œìƒ" +msgid "out of logical replication worker slots" +msgstr "ë” ì´ìƒì˜ 논리 복제 작업ìžìš© ìŠ¬ë¡¯ì´ ì—†ìŠµë‹ˆë‹¤" -#: storage/lmgr/lmgr.c:728 +#: replication/logical/launcher.c:398 #, c-format -msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" -msgstr "%u,%u ì—…ë°ì´íŠ¸ëœ ë²„ì „ 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ìž ê·¸ëŠ” ì¤‘ì— ë°œìƒ" +msgid "You might need to increase max_logical_replication_workers." +msgstr "max_logical_replication_workers ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”." -#: storage/lmgr/lmgr.c:731 +#: replication/logical/launcher.c:453 #, c-format -msgid "while inserting index tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u 튜플 ì¸ë±ìФ(해당 릴레ì´ì…˜ \"%s\")를 삽입하는 ì¤‘ì— ë°œìƒ" +msgid "out of background worker slots" +msgstr "백그ë¼ìš´ ìž‘ì—…ìž ìŠ¬ë¡¯ì´ ëª¨ìžëžë‹ˆë‹¤" -#: storage/lmgr/lmgr.c:734 +#: replication/logical/launcher.c:454 #, c-format -msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u 튜플(해당 릴레ì´ì…˜: \"%s\")ì˜ ê³ ìœ ì„±ì„ ê²€ì‚¬í•˜ëŠ” ì¤‘ì— ë°œìƒ" +msgid "You might need to increase max_worker_processes." +msgstr "max_worker_processes ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”." -#: storage/lmgr/lmgr.c:737 +#: replication/logical/launcher.c:661 #, c-format -msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" -msgstr "%u,%u ê°±ì‹ ëœ íŠœí”Œ(해당 릴레ì´ì…˜: \"%s\")ì„ ìž¬í™•ì¸í•˜ëŠ” ì¤‘ì— ë°œìƒ" +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "" -#: storage/lmgr/lmgr.c:740 +#: replication/logical/launcher.c:670 #, c-format -msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgid "logical replication worker slot %d is already used by another worker, cannot attach" msgstr "" -"%u,%u 튜플(해당 릴레ì´ì…˜: \"%s\")ì˜ ì œì™¸ 제약 ì¡°ê±´ì„ ê²€ì‚¬í•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: storage/lmgr/lmgr.c:960 +#: replication/logical/launcher.c:988 #, c-format -msgid "relation %u of database %u" -msgstr "릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" +msgid "logical replication launcher started" +msgstr "논리 복제 관리ìžê°€ 시작ë¨" -#: storage/lmgr/lmgr.c:966 +#: replication/logical/logical.c:85 #, c-format -msgid "extension of relation %u of database %u" -msgstr "%u 관계(%u ë°ì´í„°ë² ì´ìФ) 확장" +msgid "logical decoding requires wal_level >= logical" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ wal_level ê°’ì´ logical ì´ìƒì´ì–´ì•¼ 함" -#: storage/lmgr/lmgr.c:972 +#: replication/logical/logical.c:90 #, c-format -msgid "page %u of relation %u of database %u" -msgstr "페ì´ì§€ %u, 릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" +msgid "logical decoding requires a database connection" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ ë°ì´í„°ë² ì´ìФ ì—°ê²°ì´ í•„ìš”í•©ë‹ˆë‹¤" -#: storage/lmgr/lmgr.c:979 +#: replication/logical/logical.c:108 #, c-format -msgid "tuple (%u,%u) of relation %u of database %u" -msgstr "튜플 (%u,%u), 릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" +msgid "logical decoding cannot be used while in recovery" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ê¸°ëŠ¥ì€ ë³µêµ¬ ìƒíƒœì—서는 사용할 수 ì—†ìŒ" -#: storage/lmgr/lmgr.c:987 +#: replication/logical/logical.c:250 replication/logical/logical.c:381 #, c-format -msgid "transaction %u" -msgstr "트랜잭션 %u" +msgid "cannot use physical replication slot for logical decoding" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”©ì—서는 ë¬¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: storage/lmgr/lmgr.c:992 +#: replication/logical/logical.c:255 replication/logical/logical.c:386 #, c-format -msgid "virtual transaction %d/%u" -msgstr "ê°€ìƒ íŠ¸ëžœìž­ì…˜ %d/%u" +msgid "replication slot \"%s\" was not created in this database" +msgstr "\"%s\" 복제 ìŠ¬ë¡¯ì´ ì´ ë°ì´í„°ë² ì´ìФ 만들어져있지 않ìŒ" -#: storage/lmgr/lmgr.c:998 +#: replication/logical/logical.c:262 #, c-format -msgid "speculative token %u of transaction %u" -msgstr "%u 위험한 토í°, ëŒ€ìƒ íŠ¸ëžœìž­ì…˜ %u" +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "ìžë£Œ 변경 ìž‘ì—…ì´ ìžˆëŠ” 트랜잭션 안ì—서는 ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: storage/lmgr/lmgr.c:1004 +#: replication/logical/logical.c:426 #, c-format -msgid "object %u of class %u of database %u" -msgstr "ê°ì²´ %u, í´ëž˜ìФ %u, ë°ì´í„°ë² ì´ìФ %u" +msgid "starting logical decoding for slot \"%s\"" +msgstr "\"%s\" ì´ë¦„ì˜ ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ë§Œë“œëŠ” 중" -#: storage/lmgr/lmgr.c:1012 +#: replication/logical/logical.c:428 #, c-format -msgid "user lock [%u,%u,%u]" -msgstr "user lock [%u,%u,%u]" - -#: storage/lmgr/lmgr.c:1019 -#, c-format -msgid "advisory lock [%u,%u,%u,%u]" -msgstr "advisory lock [%u,%u,%u,%u]" - -#: storage/lmgr/lmgr.c:1027 -#, c-format -msgid "unrecognized locktag type %d" -msgstr "알 수 없는 locktag 형태 %d" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "" -#: storage/lmgr/lock.c:732 +#: replication/logical/logical.c:578 #, c-format -msgid "" -"cannot acquire lock mode %s on database objects while recovery is in progress" +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "" -#: storage/lmgr/lock.c:734 +#: replication/logical/logical.c:585 #, c-format -msgid "" -"Only RowExclusiveLock or less can be acquired on database objects during " -"recovery." +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "" -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2683 -#: storage/lmgr/lock.c:4008 storage/lmgr/lock.c:4073 storage/lmgr/lock.c:4365 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 #, c-format -msgid "You might need to increase max_locks_per_transaction." -msgstr "max_locks_per_transactionì„ ëŠ˜ë ¤ì•¼ í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." +msgid "must be superuser or replication role to use replication slots" +msgstr "복제 ìŠ¬ë¡¯ì€ superuser ë˜ëŠ” replication 롤 ì˜µì…˜ì„ í¬í•¨í•œ 사용ìžë§Œ 사용할 수 있습니다." -#: storage/lmgr/lock.c:3124 storage/lmgr/lock.c:3240 +#: replication/logical/logicalfuncs.c:153 #, c-format -msgid "" -"cannot PREPARE while holding both session-level and transaction-level locks " -"on the same object" -msgstr "" +msgid "slot name must not be null" +msgstr "슬롯 ì´ë¦„으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다" -#: storage/lmgr/predicate.c:675 +#: replication/logical/logicalfuncs.c:169 #, c-format -msgid "not enough elements in RWConflictPool to record a read/write conflict" -msgstr "" +msgid "options array must not be null" +msgstr "옵션 ë°°ì—´ì€ null ê°’ì„ ì‚¬ìš©í•  수 없습니다." -#: storage/lmgr/predicate.c:676 storage/lmgr/predicate.c:704 +#: replication/logical/logicalfuncs.c:200 #, c-format -msgid "" -"You might need to run fewer transactions at a time or increase " -"max_connections." -msgstr "" +msgid "array must be one-dimensional" +msgstr "ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: storage/lmgr/predicate.c:703 +#: replication/logical/logicalfuncs.c:206 #, c-format -msgid "" -"not enough elements in RWConflictPool to record a potential read/write " -"conflict" -msgstr "" +msgid "array must not contain nulls" +msgstr "ë°°ì—´ì—는 null ê°’ì„ í¬í•¨í•  수 없습니다" -#: storage/lmgr/predicate.c:909 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 +#: utils/adt/jsonb.c:1269 #, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "" +msgid "array must have even number of elements" +msgstr "ë°°ì—´ì€ ê·¸ ìš”ì†Œì˜ ê°œìˆ˜ê°€ ì§ìˆ˜ì—¬ì•¼ 함" -#: storage/lmgr/predicate.c:910 +#: replication/logical/logicalfuncs.c:269 #, c-format -msgid "" -"There might be an idle transaction or a forgotten prepared transaction " -"causing this." +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "" -#: storage/lmgr/predicate.c:1190 storage/lmgr/predicate.c:1261 +#: replication/logical/origin.c:185 #, c-format -msgid "" -"not enough shared memory for elements of data structure \"%s\" (%zu bytes " -"requested)" -msgstr "" +msgid "only superusers can query or manipulate replication origins" +msgstr "슈í¼ìœ ì €ë§Œ 복제 ì›ë³¸ì— 대한 쿼리나, 관리를 í•  수 있습니다." -#: storage/lmgr/predicate.c:1549 +#: replication/logical/origin.c:190 #, c-format -msgid "deferrable snapshot was unsafe; trying a new one" +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "" -#: storage/lmgr/predicate.c:1588 +#: replication/logical/origin.c:195 #, c-format -msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgid "cannot manipulate replication origins during recovery" msgstr "" -#: storage/lmgr/predicate.c:1589 +#: replication/logical/origin.c:230 #, c-format -msgid "" -"You can use \"SET default_transaction_isolation = 'repeatable read'\" to " -"change the default." -msgstr "" +msgid "replication origin \"%s\" does not exist" +msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ì˜¤ë¦¬ì§„ì´ ì—†ìŠµë‹ˆë‹¤" -#: storage/lmgr/predicate.c:1628 +#: replication/logical/origin.c:321 #, c-format -msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" -msgstr "" +msgid "could not find free replication origin OID" +msgstr "비어있는 복제 오리진 OID를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: storage/lmgr/predicate.c:1706 utils/time/snapmgr.c:617 -#: utils/time/snapmgr.c:623 +#: replication/logical/origin.c:369 #, c-format -msgid "could not import the requested snapshot" +msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "" -#: storage/lmgr/predicate.c:1707 utils/time/snapmgr.c:624 +#: replication/logical/origin.c:461 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "%u 소스 íŠ¸ëžœìž­ì…˜ì€ ë”ì´ìƒ 실행 중ì´ì§€ 않습니다." +msgid "replication origin with OID %u does not exist" +msgstr "OID %u 복제 ì˜¤ë¦¬ì§„ì´ ì—†ìŒ" -#: storage/lmgr/predicate.c:2330 storage/lmgr/predicate.c:2345 -#: storage/lmgr/predicate.c:3737 +#: replication/logical/origin.c:725 #, c-format -msgid "You might need to increase max_pred_locks_per_transaction." -msgstr "max_pred_locks_per_transaction ê°’ì„ ëŠ˜ë ¤ì•¼ í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "복제 ì²´í¬í¬ì¸íŠ¸ì˜ ìž˜ëª»ëœ ë§¤ì§ ë²ˆí˜¸: %u, 기대값: %u" -#: storage/lmgr/predicate.c:3891 storage/lmgr/predicate.c:3980 -#: storage/lmgr/predicate.c:3988 storage/lmgr/predicate.c:4027 -#: storage/lmgr/predicate.c:4266 storage/lmgr/predicate.c:4603 -#: storage/lmgr/predicate.c:4615 storage/lmgr/predicate.c:4657 -#: storage/lmgr/predicate.c:4695 +#: replication/logical/origin.c:757 #, c-format -msgid "" -"could not serialize access due to read/write dependencies among transactions" -msgstr "트랜잭션간 ì½ê¸°/쓰기 ì˜ì¡´ì„± ë•Œë¬¸ì— serialize ì ‘ê·¼ì„ í•  수 ì—†ìŒ" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %d ì½ìŒ, ì „ì²´ %zu" -#: storage/lmgr/predicate.c:3893 storage/lmgr/predicate.c:3982 -#: storage/lmgr/predicate.c:3990 storage/lmgr/predicate.c:4029 -#: storage/lmgr/predicate.c:4268 storage/lmgr/predicate.c:4605 -#: storage/lmgr/predicate.c:4617 storage/lmgr/predicate.c:4659 -#: storage/lmgr/predicate.c:4697 +#: replication/logical/origin.c:766 #, c-format -msgid "The transaction might succeed if retried." -msgstr "재시ë„하면 ê·¸ íŠ¸ëžœìž­ì…˜ì´ ì„±ê³µí•  것입니다." +msgid "could not find free replication state, increase max_replication_slots" +msgstr "사용 가능한 복제 ìŠ¬ë¡¯ì´ ë¶€ì¡±í•©ë‹ˆë‹¤. max_replication_slots ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”" -#: storage/lmgr/proc.c:1265 +#: replication/logical/origin.c:784 #, c-format -msgid "Process %d waits for %s on %s." -msgstr "%d 프로세스가 대기중, 잠금종류: %s, ë‚´ìš©: %s" +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "복제 슬롯 ì²´í¬í¬ì¸íŠ¸ì˜ ì²´í¬ì„¬ ê°’ì´ ìž˜ëª»ë¨: %u, 기대값 %u" -#: storage/lmgr/proc.c:1276 +#: replication/logical/origin.c:908 #, c-format -msgid "sending cancel to blocking autovacuum PID %d" -msgstr "%d PID autovacuum 블럭킹하기 위해 취소 신호를 보냅니다" +msgid "replication origin with OID %d is already active for PID %d" +msgstr "" -#: storage/lmgr/proc.c:1294 utils/adt/misc.c:270 +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 #, c-format -msgid "could not send signal to process %d: %m" -msgstr "%d 프로세스로 시스템신호(signal)를 보낼 수 없습니다: %m" +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "%u OID 복제 ì˜¤ë¦¬ì§„ì„ ìœ„í•œ 여유 복제 ìŠ¬ë¡¯ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: storage/lmgr/proc.c:1396 +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 +#: replication/slot.c:1529 #, c-format -msgid "" -"process %d avoided deadlock for %s on %s by rearranging queue order after " -"%ld.%03d ms" -msgstr "" -"%d PID 프로세스는 %s(%s)ì— ëŒ€í•´ êµì°© ìƒíƒœê°€ ë°œìƒí•˜ì§€ 않ë„ë¡ %ld.%03dms í›„ì— " -"대기열 순서를 다시 조정함" +msgid "Increase max_replication_slots and try again." +msgstr "max_replication_slots ê°’ì„ ëŠ˜ë¦° 후 다시 시ë„í•´ 보세요" -#: storage/lmgr/proc.c:1411 +#: replication/logical/origin.c:1065 #, c-format -msgid "" -"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" -msgstr "%d PID 프로세스ì—서 %s(%s) 대기중 %ld.%03dms í›„ì— êµì°© ìƒíƒœë¥¼ ê°ì§€í•¨" +msgid "cannot setup replication origin when one is already setup" +msgstr "하나가 ì´ë¯¸ 설정ë˜ì–´ ë” ì´ìƒ 복제 오리진 ì„¤ì •ì„ í•  수 ì—†ìŒ" -#: storage/lmgr/proc.c:1420 +#: replication/logical/origin.c:1094 #, c-format -msgid "process %d still waiting for %s on %s after %ld.%03d ms" -msgstr "%d PID 프로세스ì—서 여전히 %s(%s) ìž‘ì—…ì„ ê¸°ë‹¤ë¦¬ê³  있ìŒ(%ld.%03dms 후)" +msgid "replication identifier %d is already active for PID %d" +msgstr "%d번 복제 ì‹ë³„ìžê°€ %d PIDì—서 사용하고 있습니다." -#: storage/lmgr/proc.c:1427 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 +#: replication/logical/origin.c:1363 #, c-format -msgid "process %d acquired %s on %s after %ld.%03d ms" -msgstr "%d PID 프로세스가 %s(%s) ìž‘ì—…ì„ ìœ„í•´ 잠금 ì·¨ë“함(%ld.%03dms 후)" +msgid "no replication origin is configured" +msgstr "복제 오리진 ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤" -#: storage/lmgr/proc.c:1443 +#: replication/logical/relation.c:255 #, c-format -msgid "process %d failed to acquire %s on %s after %ld.%03d ms" -msgstr "프로세스 %dì—서 %s(%s)ì„(를) ì·¨ë“하지 못함(%ld.%03dms 후)" +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "\"%s.%s\" ì´ë¦„ì˜ ë…¼ë¦¬ 복제 ëŒ€ìƒ ë¦´ë ˆì´ì…˜ì´ 없습니다." -#: storage/page/bufpage.c:144 +#: replication/logical/relation.c:297 #, c-format -msgid "page verification failed, calculated checksum %u but expected %u" -msgstr "페ì´ì§€ 검사 실패, ê³„ì‚°ëœ ì²´í¬ì„¬ì€ %u, ê¸°ëŒ€ê°’ì€ %u" +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "" -#: storage/page/bufpage.c:203 storage/page/bufpage.c:522 -#: storage/page/bufpage.c:737 storage/page/bufpage.c:868 -#: storage/page/bufpage.c:968 +#: replication/logical/relation.c:337 #, c-format -msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" -msgstr "ì†ìƒëœ 페ì´ì§€ 위치: 하위값 = %u, ìƒìœ„ê°’ = %u, 특수값 = %u" +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "" -#: storage/page/bufpage.c:566 +#: replication/logical/reorderbuffer.c:2493 #, c-format -msgid "corrupted item pointer: %u" -msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: %u" +msgid "could not write to data file for XID %u: %m" +msgstr "%u XID ë‚´ìš©ì„ ë°ì´í„° 파ì¼ì— 쓸 수 ì—†ìŒ: %m" -#: storage/page/bufpage.c:577 storage/page/bufpage.c:919 -#: storage/page/bufpage.c:1074 +#: replication/logical/reorderbuffer.c:2586 +#: replication/logical/reorderbuffer.c:2608 #, c-format -msgid "corrupted item lengths: total %u, available space %u" -msgstr "ì†ìƒëœ ì•„ì´í…œ 길ì´: ì „ì²´ %u, 사용가능한 공간 %u" +msgid "could not read from reorderbuffer spill file: %m" +msgstr "reorderbuffer 처리용 파ì¼ì—서 ì½ê¸° 실패: %m" -#: storage/page/bufpage.c:756 storage/page/bufpage.c:892 +#: replication/logical/reorderbuffer.c:2590 +#: replication/logical/reorderbuffer.c:2612 #, c-format -msgid "corrupted item pointer: offset = %u, size = %u" -msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: 오프셋 = %u, í¬ê¸° = %u" +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "reorderbuffer 처리용 파ì¼ì—서 ì½ê¸° 실패: %d ë°”ì´íЏ ì½ìŒ, 기대값 %u ë°”ì´íЏ" -#: storage/page/bufpage.c:997 +#: replication/logical/reorderbuffer.c:2835 #, c-format -msgid "corrupted item pointer: offset = %u, length = %u" -msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: 오프셋 = %u, í¬ê¸° = %u" +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "\"%s\" 파ì¼ì„ 지울 수 ì—†ìŒ, pg_replslot/%s/*.xid ì‚­ì œ 작업 중: %m" -#: storage/smgr/md.c:449 storage/smgr/md.c:971 +#: replication/logical/reorderbuffer.c:3301 #, c-format -msgid "could not truncate file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì„ 비울 수 ì—†ìŒ: %m" +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "\"%s\" 파ì¼ì—서 ì½ê¸° 실패: %d ë°”ì´íЏ ì½ìŒ, 기대값 %d ë°”ì´íЏ" -#: storage/smgr/md.c:516 +#: replication/logical/snapbuild.c:612 #, c-format -msgid "cannot extend file \"%s\" beyond %u blocks" -msgstr "\"%s\" 파ì¼ì„ %uê°œ 블ë¡ì„ 초과하여 확장할 수 ì—†ìŒ" +msgid "initial slot snapshot too large" +msgstr "초기 슬롯 ìŠ¤ëƒ…ìƒ·ì´ ë„ˆë¬´ í½ë‹ˆë‹¤." -#: storage/smgr/md.c:538 storage/smgr/md.c:751 storage/smgr/md.c:827 +#: replication/logical/snapbuild.c:664 #, c-format -msgid "could not seek to block %u in file \"%s\": %m" -msgstr "%u 블ë¡ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ(해당 파ì¼: \"%s\"): %m" +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "" -#: storage/smgr/md.c:546 +#: replication/logical/snapbuild.c:1269 replication/logical/snapbuild.c:1362 +#: replication/logical/snapbuild.c:1869 #, c-format -msgid "could not extend file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì„ 확장할 수 ì—†ìŒ: %m" +msgid "logical decoding found consistent point at %X/%X" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© ì´ì–´ì„œ 시작할 위치: %X/%X" -#: storage/smgr/md.c:548 storage/smgr/md.c:555 storage/smgr/md.c:854 +#: replication/logical/snapbuild.c:1271 #, c-format -msgid "Check free disk space." -msgstr "ë””ìŠ¤í¬ ì—¬ìœ  ê³µê°„ì„ í™•ì¸í•´ 주십시오." +msgid "There are no running transactions." +msgstr "실행할 íŠ¸ëžœìž­ì…˜ì´ ì—†ìŒ" -#: storage/smgr/md.c:552 +#: replication/logical/snapbuild.c:1313 #, c-format -msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" -msgstr "\"%s\" 파ì¼ì„ 확장할 수 ì—†ìŒ: %d/%dë°”ì´íŠ¸ë§Œ %u 블ë¡ì— ì¼ìŒ" +msgid "logical decoding found initial starting point at %X/%X" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”© 시작 위치: %X/%X" -#: storage/smgr/md.c:769 +#: replication/logical/snapbuild.c:1315 replication/logical/snapbuild.c:1339 #, c-format -msgid "could not read block %u in file \"%s\": %m" -msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì—서 ì½ì„ 수 ì—†ìŒ: %m" +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "" -#: storage/smgr/md.c:785 +#: replication/logical/snapbuild.c:1337 #, c-format -msgid "could not read block %u in file \"%s\": read only %d of %d bytes" -msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì—서 ì½ì„ 수 ì—†ìŒ: %d / %d ë°”ì´íŠ¸ë§Œ ì½ìŒ" +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "ë…¼ë¦¬ì  ë””ì½”ë”©ì„ ì´ì–´ì„œ 시작할 위치: %X/%X" -#: storage/smgr/md.c:845 +#: replication/logical/snapbuild.c:1364 #, c-format -msgid "could not write block %u in file \"%s\": %m" -msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì— 쓸 수 ì—†ìŒ: %m" +msgid "There are no old transactions anymore." +msgstr "ë”ì´ìƒ ì˜¤ëž˜ëœ íŠ¸ëžœìž­ì…˜ì´ ì—†ìŠµë‹ˆë‹¤." -#: storage/smgr/md.c:850 +#: replication/logical/snapbuild.c:1733 replication/logical/snapbuild.c:1764 +#: replication/logical/snapbuild.c:1784 replication/logical/snapbuild.c:1803 #, c-format -msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" -msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì— 쓸 수 ì—†ìŒ: %d / %d ë°”ì´íŠ¸ë§Œ 씀" +msgid "could not read file \"%s\", read %d of %d: %m" +msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ, %d/%d ë°”ì´íЏ ì½ìŒ: %m" -#: storage/smgr/md.c:947 +#: replication/logical/snapbuild.c:1739 #, c-format -msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" -msgstr "\"%s\" 파ì¼ì„ %u 블럭으로 비울 수 ì—†ìŒ: 현재 %u 블럭 ë¿ ìž„" +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%s\" snapbuild ìƒíƒœ 파ì¼ì˜ ë§¤ì§ ë²ˆí˜¸ê°€ ì´ìƒí•¨: 현재값 %u, 기대값 %u" -#: storage/smgr/md.c:997 +#: replication/logical/snapbuild.c:1744 #, c-format -msgid "could not truncate file \"%s\" to %u blocks: %m" -msgstr "\"%s\" 파ì¼ì„ %u 블럭으로 정리할 수 ì—†ìŒ: %m" +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "\"%s\" snapbuild ìƒíƒœ 파ì¼ì˜ ë²„ì „ì´ ì´ìƒí•¨: 현재값 %u, 기대값 %u" -#: storage/smgr/md.c:1279 +#: replication/logical/snapbuild.c:1816 #, c-format -msgid "could not fsync file \"%s\" but retrying: %m" -msgstr "\"%s\" íŒŒì¼ fsync 실패, 재시ë„함: %m" +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "" -#: storage/smgr/md.c:1442 +#: replication/logical/snapbuild.c:1871 #, c-format -msgid "could not forward fsync request because request queue is full" -msgstr "요청 íê°€ ê°€ë“ì°¨ forward fsync ìš”ì²­ì„ ì²˜ë¦¬í•  수 ì—†ìŒ" +msgid "Logical decoding will begin using saved snapshot." +msgstr "" -#: storage/smgr/md.c:1863 +#: replication/logical/snapbuild.c:1943 #, c-format -msgid "" -"could not open file \"%s\" (target block %u): previous segment is only %u " -"blocks" -msgstr "\"%s\" 파ì¼ì„ 열기 실패(ëŒ€ìƒ ë¸”ë¡: %u): ì´ì „ ì¡°ê°ì€ %u 블럭 ë¿ìž„" +msgid "could not parse file name \"%s\"" +msgstr "\"%s\" íŒŒì¼ ì´ë¦„ì„ ë¶„ì„í•  수 ì—†ìŒ" -#: storage/smgr/md.c:1877 +#: replication/logical/tablesync.c:138 #, c-format -msgid "could not open file \"%s\" (target block %u): %m" -msgstr "\"%s\" 파ì¼ì„ 열기 실패(ëŒ€ìƒ ë¸”ë¡: %u): %m" +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "" -#: tcop/fastpath.c:111 tcop/fastpath.c:475 tcop/fastpath.c:605 +#: replication/logical/tablesync.c:685 #, c-format -msgid "invalid argument size %d in function call message" -msgstr "함수 호출 메시지 ì•ˆì— ìžˆëŠ” ìž˜ëª»ëœ %d ì¸ìž í¬ê¸°" +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "\"%s.%s\" í…Œì´ë¸”ìš© í…Œì´ë¸” 정보를 구할 수 없습니다, 해당 발행: %s" -#: tcop/fastpath.c:291 tcop/postgres.c:992 tcop/postgres.c:1301 -#: tcop/postgres.c:1559 tcop/postgres.c:1964 tcop/postgres.c:2331 -#: tcop/postgres.c:2406 +#: replication/logical/tablesync.c:691 #, c-format -msgid "" -"current transaction is aborted, commands ignored until end of transaction " -"block" +msgid "table \"%s.%s\" not found on publisher" msgstr "" -"현재 íŠ¸ëžœìž­ì…˜ì€ ì¤‘ì§€ë˜ì–´ 있습니다. ì´ íŠ¸ëžœìž­ì…˜ì„ ì¢…ë£Œí•˜ê¸° 전까지는 모든 명령" -"ì´ ë¬´ì‹œë  ê²ƒìž…ë‹ˆë‹¤" -#: tcop/fastpath.c:319 +#: replication/logical/tablesync.c:721 #, c-format -msgid "fastpath function call: \"%s\" (OID %u)" -msgstr "fastpath 함수 호출: \"%s\" (OID %u)" +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "\"%s.%s\" í…Œì´ë¸”ìš© í…Œì´ë¸” 정보를 구할 수 없습니다: %s" -#: tcop/fastpath.c:401 tcop/postgres.c:1163 tcop/postgres.c:1426 -#: tcop/postgres.c:1805 tcop/postgres.c:2022 +#: replication/logical/tablesync.c:791 #, c-format -msgid "duration: %s ms" -msgstr "실행시간: %s ms" +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "\"%s.%s\" í…Œì´ë¸”ìš© 초기 ìžë£Œ 복사를 시작할 수 없습니다: %s" -#: tcop/fastpath.c:405 +#: replication/logical/tablesync.c:904 #, c-format -msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" -msgstr "작업시간: %s ms fastpath 함수 호출: \"%s\" (OID %u)" +msgid "table copy could not start transaction on publisher" +msgstr "발행 서버ì—서는 í…Œì´ë¸” 복사 íŠ¸ëžœìž­ì…˜ì„ ì‹œìž‘í•  수 ì—†ìŒ" -#: tcop/fastpath.c:443 tcop/fastpath.c:570 +#: replication/logical/tablesync.c:926 #, c-format -msgid "function call message contains %d arguments but function requires %d" -msgstr "함수 호출 메시지는 %d ì¸ìžë¥¼ 사용하지만, 함수는 %d ì¸ìžê°€ 필요합니다" +msgid "table copy could not finish transaction on publisher" +msgstr "" -#: tcop/fastpath.c:451 +#: replication/logical/worker.c:307 #, c-format -msgid "function call message contains %d argument formats but %d arguments" -msgstr "함수 호출 메시지는 %d ì¸ìžë¥¼ 사용하지만, 함수는 %d ì¸ìžê°€ 필요합니다" +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "" -#: tcop/fastpath.c:538 tcop/fastpath.c:621 +#: replication/logical/worker.c:528 #, c-format -msgid "incorrect binary data format in function argument %d" -msgstr "함수 ì¸ìž %d ì•ˆì— ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ ìžë£Œ í˜•ì‹ ë°œê²¬ë¨" +msgid "ORIGIN message sent out of order" +msgstr "" -#: tcop/postgres.c:352 tcop/postgres.c:388 tcop/postgres.c:415 +#: replication/logical/worker.c:661 #, c-format -msgid "unexpected EOF on client connection" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²°ì—서 예ìƒì¹˜ ì•Šì€ EOF 발견ë¨" +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "" -#: tcop/postgres.c:438 tcop/postgres.c:450 tcop/postgres.c:461 -#: tcop/postgres.c:473 tcop/postgres.c:4314 +#: replication/logical/worker.c:668 #, c-format -msgid "invalid frontend message type %d" -msgstr "ìž˜ëª»ëœ frontend 메시지 형태 %d" +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "" -#: tcop/postgres.c:933 +#: replication/logical/worker.c:1007 #, c-format -msgid "statement: %s" -msgstr "명령 구문: %s" +msgid "invalid logical replication message type \"%c\"" +msgstr "ìž˜ëª»ëœ ë…¼ë¦¬ 복제 메시지 형태 \"%c\"" -#: tcop/postgres.c:1168 +#: replication/logical/worker.c:1148 #, c-format -msgid "duration: %s ms statement: %s" -msgstr "실행시간: %s ms 명령 구문: %s" +msgid "data stream from publisher has ended" +msgstr "" -#: tcop/postgres.c:1218 +#: replication/logical/worker.c:1307 #, c-format -msgid "parse %s: %s" -msgstr "구문 %s: %s" +msgid "terminating logical replication worker due to timeout" +msgstr "시간 제한으로 논리 복제 작업ìžë¥¼ 중지합니다." -#: tcop/postgres.c:1274 +#: replication/logical/worker.c:1455 #, c-format -msgid "cannot insert multiple commands into a prepared statement" -msgstr "ì¤€ë¹„ëœ ëª…ë ¹ 구문ì—는 다중 ëª…ë ¹ì„ ì‚½ìž…í•  수 없습니다" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "" -#: tcop/postgres.c:1431 +#: replication/logical/worker.c:1469 #, c-format -msgid "duration: %s ms parse %s: %s" -msgstr "실행시간: %s ms %s 구문분ì„: %s" +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "" -#: tcop/postgres.c:1476 +#: replication/logical/worker.c:1483 #, c-format -msgid "bind %s to %s" -msgstr "ë°”ì¸ë“œ: %s -> %s" +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "" -#: tcop/postgres.c:1495 tcop/postgres.c:2312 +#: replication/logical/worker.c:1497 #, c-format -msgid "unnamed prepared statement does not exist" -msgstr "ì´ë¦„없는 ì¤€ë¹„ëœ ëª…ë ¹ 구문(unnamed prepared statement) ì—†ìŒ" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "" -#: tcop/postgres.c:1537 +#: replication/logical/worker.c:1514 #, c-format -msgid "bind message has %d parameter formats but %d parameters" -msgstr "ë°”ì¸ë“œ 메시지는 %d 매개 변수 형태지만, %d 매개 변수여야함" +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "" -#: tcop/postgres.c:1543 +#: replication/logical/worker.c:1528 #, c-format -msgid "" -"bind message supplies %d parameters, but prepared statement \"%s\" requires " -"%d" +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" msgstr "" -"ë°”ì¸ë“œ 메시지는 %dê°œì˜ ë§¤ê°œ 변수를 ì§€ì›í•˜ì§€ë§Œ, \"%s\" ì¤€ë¹„ëœ ëª…ë ¹ 구문" -"(prepared statement)ì—서는%d ê°œì˜ ë§¤ê°œ 변수가 필요합니다" -#: tcop/postgres.c:1712 +#: replication/logical/worker.c:1631 #, c-format -msgid "incorrect binary data format in bind parameter %d" -msgstr "ë°”ì¸ë“œ 매개 변수 %d ì•ˆì— ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ ìžë£Œ 형태가 있ìŒ" +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "" -#: tcop/postgres.c:1810 +#: replication/logical/worker.c:1643 #, c-format -msgid "duration: %s ms bind %s%s%s: %s" -msgstr "실행시간: %s ms %s%s%s ì ‘ì†: %s" +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "" -#: tcop/postgres.c:1858 tcop/postgres.c:2392 +#: replication/logical/worker.c:1661 #, c-format -msgid "portal \"%s\" does not exist" -msgstr "\"%s\" portal ì—†ìŒ" +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "" -#: tcop/postgres.c:1943 +#: replication/logical/worker.c:1665 #, c-format -msgid "%s %s%s%s: %s" -msgstr "%s %s%s%s: %s" - -#: tcop/postgres.c:1945 tcop/postgres.c:2030 -msgid "execute fetch from" -msgstr "ìžë£Œë½‘기" - -#: tcop/postgres.c:1946 tcop/postgres.c:2031 -msgid "execute" -msgstr "쿼리실행" +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "" -#: tcop/postgres.c:2027 +#: replication/logical/worker.c:1705 #, c-format -msgid "duration: %s ms %s %s%s%s: %s" -msgstr "수행시간: %s ms %s %s%s%s: %s" +msgid "subscription has no replication slot set" +msgstr "" -#: tcop/postgres.c:2153 +#: replication/pgoutput/pgoutput.c:117 #, c-format -msgid "prepare: %s" -msgstr "prepare: %s" +msgid "invalid proto_version" +msgstr "ìž˜ëª»ëœ proto_version" -#: tcop/postgres.c:2216 +#: replication/pgoutput/pgoutput.c:122 #, c-format -msgid "parameters: %s" -msgstr "매개 변수: %s" +msgid "proto_version \"%s\" out of range" +msgstr "proto_verson \"%s\" 범위 벗어남" -#: tcop/postgres.c:2235 +#: replication/pgoutput/pgoutput.c:139 #, c-format -msgid "abort reason: recovery conflict" -msgstr "중지 ì´ìœ : 복구 ì¶©ëŒ" +msgid "invalid publication_names syntax" +msgstr "ìž˜ëª»ëœ publication_names 구문" -#: tcop/postgres.c:2251 +#: replication/pgoutput/pgoutput.c:181 #, c-format -msgid "User was holding shared buffer pin for too long." +msgid "client sent proto_version=%d but we only support protocol %d or lower" msgstr "" -#: tcop/postgres.c:2254 +#: replication/pgoutput/pgoutput.c:187 #, c-format -msgid "User was holding a relation lock for too long." +msgid "client sent proto_version=%d but we only support protocol %d or higher" msgstr "" -#: tcop/postgres.c:2257 +#: replication/pgoutput/pgoutput.c:193 #, c-format -msgid "User was or might have been using tablespace that must be dropped." -msgstr "" +msgid "publication_names parameter missing" +msgstr "publication_names 매개 변수가 빠졌ìŒ" -#: tcop/postgres.c:2260 +#: replication/slot.c:182 #, c-format -msgid "User query might have needed to see row versions that must be removed." -msgstr "" +msgid "replication slot name \"%s\" is too short" +msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì´ ë„ˆë¬´ ì§§ìŒ" -#: tcop/postgres.c:2266 +#: replication/slot.c:191 #, c-format -msgid "User was connected to a database that must be dropped." -msgstr "ì‚­ì œ ë˜ì–´ì ¸ì•¼í•  ë°ì´í„°ë² ì´ìФ ì‚¬ìš©ìž ì ‘ì†í•´ 있습니다." +msgid "replication slot name \"%s\" is too long" +msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì´ ë„ˆë¬´ 긺" -#: tcop/postgres.c:2595 +#: replication/slot.c:204 #, c-format -msgid "terminating connection because of crash of another server process" -msgstr "다른 서버 프로세스가 ì†ìƒì„ ìž…ì–´ 현재 ì—°ê²°ì„ ì¤‘ì§€í•©ë‹ˆë‹¤" - -#: tcop/postgres.c:2596 -#, c-format -msgid "" -"The postmaster has commanded this server process to roll back the current " -"transaction and exit, because another server process exited abnormally and " -"possibly corrupted shared memory." -msgstr "" -"postmaster ì—서 현재 ì´ì„œë²„ 프로세스ì—게 현재 íŠ¸ëžœìž­ì…˜ì„ ì·¨ì†Œí•˜ê³ , í´ë¼ì´ì–¸íЏ" -"ì™€ì˜ ì—°ê²°ì„ ëŠìœ¼ë¼ëŠ” ëª…ë ¹ì„ ë³´ëƒˆìŠµë‹ˆë‹¤. 왜ëƒí•˜ë©´, 다른 서버 프로세스가 비정ìƒ" -"ì ìœ¼ë¡œ 중지ë˜ì–´ 공유 메모리가 ì†ìƒë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆê¸° 때문입니다" +msgid "replication slot name \"%s\" contains invalid character" +msgstr "\"%s\" 복제 슬롯 ì´ë¦„ì— ì‚¬ìš©í•  수 없는 문ìžê°€ 있ìŒ" -#: tcop/postgres.c:2600 tcop/postgres.c:2904 +#: replication/slot.c:206 #, c-format -msgid "" -"In a moment you should be able to reconnect to the database and repeat your " -"command." -msgstr "잠시 ë’¤ì— ë‹¤ì‹œ ì—°ê²° 해서 ìž‘ì—…ì„ ê³„ì† í•˜ì‹­ì‹œì˜¤" +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "복제 슬롯 ì´ë¦„으로 사용할 수 있는 문ìžëŠ” ì˜ë¬¸ 소문ìž, 숫ìž, 밑줄(_) 문ìžìž…니다." -#: tcop/postgres.c:2686 +#: replication/slot.c:253 #, c-format -msgid "floating-point exception" -msgstr "ë¶€ë™ì†Œìˆ˜ì  예외발ìƒ" +msgid "replication slot \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì´ ì´ë¯¸ 있습니다." -#: tcop/postgres.c:2687 +#: replication/slot.c:263 #, c-format -msgid "" -"An invalid floating-point operation was signaled. This probably means an out-" -"of-range result or an invalid operation, such as division by zero." -msgstr "" -"ìž˜ëª»ëœ ë¶€ë™ì†Œìˆ˜ì  ìž‘ì—…ì´ ê°ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤. ì´ê²ƒì€ ì•„ë§ˆë„ ê²°ê³¼ê°’ 범위초과나 0으" -"로 나누는 작업과 ê°™ì€ ìž˜ëª»ëœ ì—°ì‚° ë•Œë¬¸ì— ë°œìƒí•œ 것 같습니다" +msgid "all replication slots are in use" +msgstr "모든 복제 ìŠ¬ë¡¯ì´ ì‚¬ìš© 중입니다." -#: tcop/postgres.c:2849 +#: replication/slot.c:264 #, c-format -msgid "canceling authentication due to timeout" -msgstr "시간 초과로 ì¸ì¦ ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "Free one or increase max_replication_slots." +msgstr "하나를 비우든지, max_replication_slots ì„¤ì •ê°’ì„ ëŠ˜ë¦¬ì„¸ìš”." -#: tcop/postgres.c:2853 +#: replication/slot.c:387 #, c-format -msgid "terminating autovacuum process due to administrator command" -msgstr "ê´€ë¦¬ìž ëª…ë ¹ìœ¼ë¡œ ì¸í•´ ìžë™ 청소 프로세스를 종료하는 중" +msgid "replication slot \"%s\" does not exist" +msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì´ ì—†ìŠµë‹ˆë‹¤" -#: tcop/postgres.c:2859 tcop/postgres.c:2869 tcop/postgres.c:2902 +#: replication/slot.c:398 replication/slot.c:948 #, c-format -msgid "terminating connection due to conflict with recovery" -msgstr "복구 작업 중 ì¶©ëŒë¡œ ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤." +msgid "replication slot \"%s\" is active for PID %d" +msgstr "\"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì„ %d PID 프로세스가 사용중입니다." -#: tcop/postgres.c:2875 +#: replication/slot.c:632 replication/slot.c:1136 replication/slot.c:1490 #, c-format -msgid "terminating connection due to administrator command" -msgstr "ê´€ë¦¬ìž ìš”ì²­ì— ì˜í•´ì„œ ì—°ê²°ì„ ë냅니다" +msgid "could not remove directory \"%s\"" +msgstr "\"%s\" 디렉터리를 삭제할 수 ì—†ìŒ" -#: tcop/postgres.c:2885 +#: replication/slot.c:978 #, c-format -msgid "connection to client lost" -msgstr "서버로부터 ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤." +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "복제 ìŠ¬ë¡¯ì€ max_replication_slots > 0 ìƒíƒœì—서 ì‚¬ìš©ë  ìˆ˜ 있습니다." -#: tcop/postgres.c:2953 +#: replication/slot.c:983 #, c-format -msgid "canceling statement due to lock timeout" -msgstr "잠금 대기 시간 초과로 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "replication slots can only be used if wal_level >= replica" +msgstr "복제 ìŠ¬ë¡¯ì€ wal_level >= replica ìƒíƒœì—서 ì‚¬ìš©ë  ìˆ˜ 있습니다." -#: tcop/postgres.c:2960 +#: replication/slot.c:1422 replication/slot.c:1462 #, c-format -msgid "canceling statement due to statement timeout" -msgstr "명령실행시간 초과로 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "could not read file \"%s\", read %d of %u: %m" +msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ, %d/%u ë°”ì´íЏ ì½ìŒ: %m" -#: tcop/postgres.c:2967 +#: replication/slot.c:1431 #, c-format -msgid "canceling autovacuum task" -msgstr "ìžë™ 청소 ìž‘ì—…ì„ ì·¨ì†Œí•˜ëŠ” 중" +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%s\" 복제 슬롯 파ì¼ì˜ ë§¤ì§ ë²ˆí˜¸ê°€ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %u, 기대값 %u" -#: tcop/postgres.c:2990 +#: replication/slot.c:1438 #, c-format -msgid "canceling statement due to user request" -msgstr "ì‚¬ìš©ìž ìš”ì²­ì— ì˜í•´ ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "\"%s\" 복제 슬롯 파ì¼ì€ ì§€ì›í•˜ì§€ 않는 %u 버전 파ì¼ìž…니다" -#: tcop/postgres.c:3000 +#: replication/slot.c:1445 #, c-format -msgid "terminating connection due to idle-in-transaction timeout" -msgstr "idle-in-transaction 시간 초과로 ì—°ê²°ì„ ë냅니다" +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "\"%s\" 복제 슬롯 파ì¼ì´ %u 길ì´ë¡œ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤." -#: tcop/postgres.c:3114 +#: replication/slot.c:1477 #, c-format -msgid "stack depth limit exceeded" -msgstr "ìŠ¤íƒ ê¹Šì´ë¥¼ 초과했습니다" +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "\"%s\" 복제 슬롯 파ì¼ì˜ ì²´í¬ì„¬ ê°’ì´ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %u, 기대값 %u" -#: tcop/postgres.c:3115 +#: replication/slot.c:1528 #, c-format -msgid "" -"Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " -"after ensuring the platform's stack depth limit is adequate." -msgstr "" -"먼저 OSì—서 ì§€ì›í•˜ëŠ” ìŠ¤íƒ depth ìµœëŒ€ê°’ì„ í™•ì¸í•œ ë’¤, 허용범위 안ì—서 " -"\"max_stack_depth\" (현재값: %dkB) 매개 변수 ê°’ì˜ ì„¤ì •ì¹˜ë¥¼ ì¦ê°€ì‹œí‚¤ì„¸ìš”." +msgid "too many replication slots active before shutdown" +msgstr "서버 중지 ì „ì— ë„ˆë¬´ ë§Žì€ ë³µì œ ìŠ¬ë¡¯ì´ í™œì„±í™” ìƒíƒœìž…니다" -#: tcop/postgres.c:3178 +#: replication/slotfuncs.c:490 #, c-format -msgid "\"max_stack_depth\" must not exceed %ldkB." -msgstr "\"max_stack_depth\" ê°’ì€ %ldkB를 초과할 수 없습니다" +msgid "invalid target wal lsn" +msgstr "ìž˜ëª»ëœ ëŒ€ìƒ wal lsn" -#: tcop/postgres.c:3180 +#: replication/slotfuncs.c:512 #, c-format -msgid "" -"Increase the platform's stack depth limit via \"ulimit -s\" or local " -"equivalent." -msgstr "OSì˜ \"ulimit -s\" 명령과 ê°™ì€ ê²ƒìœ¼ë¡œ ìŠ¤íƒ ê¹Šì´ë¥¼ 늘려주십시오." +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "" -#: tcop/postgres.c:3540 +#: replication/slotfuncs.c:528 #, c-format -msgid "invalid command-line argument for server process: %s" -msgstr "서버 í”„ë¡œì„¸ìŠ¤ì˜ ëª…ë ¹í–‰ ì¸ìžê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤: %s" +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" -#: tcop/postgres.c:3541 tcop/postgres.c:3547 +#: replication/syncrep.c:246 #, c-format -msgid "Try \"%s --help\" for more information." -msgstr "ìžì„¸í•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보세요." +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "ê´€ë¦¬ìž ëª…ë ¹ì— ì˜í•´ ë™ê¸°ì‹ ë³µì œì˜ ëŒ€ê¸° 작업과 ì ‘ì† ëŠê¸° ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: tcop/postgres.c:3545 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format -msgid "%s: invalid command-line argument: %s" -msgstr "%s: ìž˜ëª»ëœ ëª…ë ¹í–‰ ì¸ìž: %s" +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "주 서버ì—서는 ì´ íŠ¸ëžœìž­ì…˜ì´ ì»¤ë°‹ë˜ì—ˆì§€ë§Œ, 복제용 대기 서버ì—서는 ì•„ì§ ì»¤ë°‹ ë˜ì§€ ì•Šì•˜ì„ ê°€ëŠ¥ì„±ì´ ìžˆìŠµë‹ˆë‹¤." -#: tcop/postgres.c:3607 +#: replication/syncrep.c:263 #, c-format -msgid "%s: no database nor user name specified" -msgstr "%s: ë°ì´í„°ë² ì´ìŠ¤ì™€ 사용ìžë¥¼ 지정하지 않았습니다" +msgid "canceling wait for synchronous replication due to user request" +msgstr "ì‚¬ìš©ìž ìš”ì²­ì— ì˜í•´ ë™ê¸°ì‹ 복제 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: tcop/postgres.c:4222 +#: replication/syncrep.c:397 #, c-format -msgid "invalid CLOSE message subtype %d" -msgstr "ìž˜ëª»ëœ CLOSE 메시지 서브타입 %d" +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "\"%s\" 대기 ì„œë²„ì˜ ë™ê¸°ì‹ 복제 우선순위가 %u 입니다" -#: tcop/postgres.c:4257 +#: replication/syncrep.c:458 #, c-format -msgid "invalid DESCRIBE message subtype %d" -msgstr "ìž˜ëª»ëœ DESCRIBE 메시지 서브타입 %d" +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "\"%s\" 대기 ì„œë²„ì˜ ë™ê¸°ì‹ 복제 우선순위가 %u 로 변경ë˜ì—ˆìŠµë‹ˆë‹¤." -#: tcop/postgres.c:4335 +#: replication/syncrep.c:462 #, c-format -msgid "fastpath function calls not supported in a replication connection" -msgstr "복제 ì—°ê²°ì—서는 fastpath 함수 í˜¸ì¶œì„ ì§€ì›í•˜ì§€ 않습니다" +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "\"%s\" 대기 서버가 ë™ê¸°ì‹ 대기 서버 후보가 ë˜ì—ˆìŠµë‹ˆë‹¤" -#: tcop/postgres.c:4339 +#: replication/syncrep.c:1160 #, c-format -msgid "extended query protocol not supported in a replication connection" -msgstr "" +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names ê°’ì„ ë¶„ì„í•  수 ì—†ìŒ" -#: tcop/postgres.c:4509 +#: replication/syncrep.c:1166 #, c-format -msgid "" -"disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s" -"%s" -msgstr "" -"연결종료: 세션 시간: %d:%02d:%02d.%03d 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s 호스트=%s%s" -"%s" +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "ë™ê¸°ì‹ 대기 서버 수 (%d)는 0보다 커야 합니다." -#: tcop/pquery.c:665 +#: replication/walreceiver.c:169 #, c-format -msgid "bind message has %d result formats but query has %d columns" -msgstr "" -"ë°”ì¸ë“œ 메시지는 %d ê²°ê³¼ í¬ë©§ì„ 가지고 있고, 쿼리는 %d ì—´ì„ ê°€ì§€ê³  있습니다" +msgid "terminating walreceiver process due to administrator command" +msgstr "ê´€ë¦¬ìž ëª…ë ¹ìœ¼ë¡œ ì¸í•´ WAL 수신기를 종료합니다." -#: tcop/pquery.c:967 +#: replication/walreceiver.c:309 #, c-format -msgid "cursor can only scan forward" -msgstr "ì´ ì»¤ì„œëŠ” 앞으로 ì´ë™ 전용입니다" +msgid "could not connect to the primary server: %s" +msgstr "주 ì„œë²„ì— ì—°ê²° í•  수 ì—†ìŒ: %s" -#: tcop/pquery.c:968 +#: replication/walreceiver.c:359 #, c-format -msgid "Declare it with SCROLL option to enable backward scan." -msgstr "" -"뒤로 ì´ë™ 가능한 커서를 만드려면 SCROLL ì˜µì…˜ì„ ì¶”ê°€í•´ì„œ 커서를 만드세요." +msgid "database system identifier differs between the primary and standby" +msgstr "ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„번호가 주 서버와 대기 서버가 서로 다름" -#. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:235 +#: replication/walreceiver.c:360 #, c-format -msgid "cannot execute %s in a read-only transaction" -msgstr "ì½ê¸° ì „ìš© 트랜잭션ì—서는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "주 서버: %s, 대기 서버: %s." -#. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:253 +#: replication/walreceiver.c:371 #, c-format -msgid "cannot execute %s during a parallel operation" -msgstr "병렬 처리 작업ì—서는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "주 ì„œë²„ì˜ ì œì¼ ìµœì‹ ì˜ íƒ€ìž„ë¼ì¸ì€ %u ì¸ë°, 복구 타임ë¼ì¸ %u 보다 옛것입니다" -#. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:272 +#: replication/walreceiver.c:407 #, c-format -msgid "cannot execute %s during recovery" -msgstr "복구 작업 중ì—는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "주 ì„œë²„ì˜ WAL ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 위치: %X/%X (타임ë¼ì¸ %u)" -#. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:290 +#: replication/walreceiver.c:412 #, c-format -msgid "cannot execute %s within security-restricted operation" -msgstr "보안 제한 작업 ë‚´ì—서 %sì„(를) 실행할 수 ì—†ìŒ" +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ìž¬ì‹œìž‘ 위치: %X/%X (타임ë¼ì¸ %u)" -#: tcop/utility.c:744 +#: replication/walreceiver.c:441 #, c-format -msgid "must be superuser to do CHECKPOINT" -msgstr "CHECKPOINT ëª…ë ¹ì€ ìŠˆí¼ìœ ì €ë§Œ 사용할 수 있습니다" +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "WAL ìŠ¤íŠ¸ë¦¬ë° ê³„ì†í•  수 ì—†ìŒ, 복구가 ì´ë¯¸ 종료ë¨" -#: tsearch/dict_ispell.c:51 tsearch/dict_thesaurus.c:623 +#: replication/walreceiver.c:478 #, c-format -msgid "multiple DictFile parameters" -msgstr "DictFile 매개 변수가 여러 ê°œ 있ìŒ" +msgid "replication terminated by primary server" +msgstr "주 ì„œë²„ì— ì˜í•´ì„œ 복제가 ë남" -#: tsearch/dict_ispell.c:62 +#: replication/walreceiver.c:479 #, c-format -msgid "multiple AffFile parameters" -msgstr "AffFile 매개 변수가 여러 ê°œ 있ìŒ" +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "타임ë¼ì¸ %u, 위치 %X/%X ì—서 WAL ëì— ë„달함" -#: tsearch/dict_ispell.c:81 +#: replication/walreceiver.c:574 #, c-format -msgid "unrecognized Ispell parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 Ispell 매개 변수: \"%s\"" +msgid "terminating walreceiver due to timeout" +msgstr "시간 제한으로 wal 수신기를 중지합니다." -#: tsearch/dict_ispell.c:95 +#: replication/walreceiver.c:614 #, c-format -msgid "missing AffFile parameter" -msgstr "AffFile 매개 변수가 누ë½ë¨" +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "주 서버ì—는 요청 ë°›ì€ %u 타임ë¼ì¸ì˜ WALê°€ ë” ì´ìƒ 없습니다." -#: tsearch/dict_ispell.c:101 tsearch/dict_thesaurus.c:647 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format -msgid "missing DictFile parameter" -msgstr "DictFile 매개 변수가 누ë½ë¨" +msgid "could not close log segment %s: %m" +msgstr "%s 로그 ì¡°ê° íŒŒì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: tsearch/dict_simple.c:57 +#: replication/walreceiver.c:754 #, c-format -msgid "multiple Accept parameters" -msgstr "Accept 매개 변수가 여러 ê°œ 있ìŒ" +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "주 서버ì—서 %u 타임ë¼ì¸ìš© 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ 가져옵니다." -#: tsearch/dict_simple.c:65 +#: replication/walreceiver.c:1036 #, c-format -msgid "unrecognized simple dictionary parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 simple 사전 매개 변수: \"%s\"" +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "%s 로그 ì¡°ê° íŒŒì¼ ì“°ê¸° 실패: 위치 %u, ê¸¸ì´ %lu: %m" -#: tsearch/dict_synonym.c:117 +#: replication/walsender.c:494 #, c-format -msgid "unrecognized synonym parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 synonym 매개 변수: \"%s\"" +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì—서 시작 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %m" -#: tsearch/dict_synonym.c:124 +#: replication/walsender.c:535 #, c-format -msgid "missing Synonyms parameter" -msgstr "Synonyms 매개 변수가 누ë½ë¨" +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "" -#: tsearch/dict_synonym.c:131 +#: replication/walsender.c:552 #, c-format -msgid "could not open synonym file \"%s\": %m" -msgstr "\"%s\" ë™ì˜ì–´ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "cannot use a logical replication slot for physical replication" +msgstr "ë¬¼ë¦¬ì  ë³µì œì—서 ë…¼ë¦¬ì  ë³µì œ ìŠ¬ë¡¯ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: tsearch/dict_thesaurus.c:178 +#: replication/walsender.c:615 #, c-format -msgid "could not open thesaurus file \"%s\": %m" -msgstr "\"%s\" 기준어 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "ìš”ì²­ëœ %X/%X 시작 위치(타임ë¼ì¸ %u)ê°€ ì´ ì„œë²„ ë‚´ì—­ì— ì—†ìŠµë‹ˆë‹¤." -#: tsearch/dict_thesaurus.c:211 +#: replication/walsender.c:619 #, c-format -msgid "unexpected delimiter" -msgstr "예기치 ì•Šì€ êµ¬ë¶„ìž" +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "ì´ ì„œë²„ì˜ ì‹œìž‘ 위치: 타임ë¼ì¸ %u, 위치 %X/%X" -#: tsearch/dict_thesaurus.c:261 tsearch/dict_thesaurus.c:277 +#: replication/walsender.c:664 #, c-format -msgid "unexpected end of line or lexeme" -msgstr "예기치 ì•Šì€ ì¤„ ë ë˜ëŠ” 어휘소" +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "" -#: tsearch/dict_thesaurus.c:286 +#: replication/walsender.c:893 #, c-format -msgid "unexpected end of line" -msgstr "예기치 ì•Šì€ ì¤„ ë" +msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT êµ¬ë¬¸ì€ íŠ¸ëžœìž­ì…˜ 안ì—서는 쓸 수 없습니다." -#: tsearch/dict_thesaurus.c:296 +#: replication/walsender.c:902 #, c-format -msgid "too many lexemes in thesaurus entry" -msgstr "기준어 í•­ëª©ì— ë„ˆë¬´ ë§Žì€ ì–´íœ˜ì†Œê°€ 있ìŒ" +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT êµ¬ë¬¸ì€ íŠ¸ëžœìž­ì…˜ 안ì—서만 쓸 수 있습니다." -#: tsearch/dict_thesaurus.c:420 +#: replication/walsender.c:907 #, c-format -msgid "" -"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" -msgstr "\"%s\" 기준 단어는 하위 사전ì—서 ì¸ì‹í•  수 ì—†ìŒ(규칙 %d)" +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT êµ¬ë¬¸ì€ ê²©ë¦¬ ìˆ˜ì¤€ì´ REPEATABLE READ ì¼ë•Œë§Œ 사용할 수 있습니다." -#: tsearch/dict_thesaurus.c:426 +#: replication/walsender.c:912 #, c-format -msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" -msgstr "\"%s\" ë™ì˜ì–´ 사전 샘플 단어는 중지 단어임(규칙 %d)" +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT êµ¬ë¬¸ì€ ë§¨ ì²˜ìŒ í˜¸ì¶œ 해야 합니다." -#: tsearch/dict_thesaurus.c:429 +#: replication/walsender.c:917 #, c-format -msgid "Use \"?\" to represent a stop word within a sample phrase." -msgstr "샘플 구 ë‚´ì—서 중지 단어를 나타내려면 \"?\"를 사용하십시오." +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT êµ¬ë¬¸ì€ í•˜ìœ„ 트랜잭션ì—서는 호출 í•  수 없습니다." -#: tsearch/dict_thesaurus.c:575 +#: replication/walsender.c:1063 #, c-format -msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" -msgstr "\"%s\" ë™ì˜ì–´ 사전 대체 단어는 중지 단어임(규칙 %d)" +msgid "terminating walsender process after promotion" +msgstr "ìš´ì˜ì „환 ë’¤ wal 송신기 프로세스를 중지합니다." -#: tsearch/dict_thesaurus.c:582 +#: replication/walsender.c:1448 #, c-format -msgid "" -"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" -msgstr "\"%s\" ë™ì˜ì–´ 사전 대체 단어는 하위 사전ì—서 ì¸ì‹í•  수 ì—†ìŒ(규칙 %d)" +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "" -#: tsearch/dict_thesaurus.c:594 +#: replication/walsender.c:1481 #, c-format -msgid "thesaurus substitute phrase is empty (rule %d)" -msgstr "ë™ì˜ì–´ 사전 대체 구가 비어 있ìŒ(규칙 %d)" +msgid "received replication command: %s" +msgstr "ìˆ˜ì‹ ëœ ë³µì œ 명령: %s" -#: tsearch/dict_thesaurus.c:632 +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1010 +#: tcop/postgres.c:1334 tcop/postgres.c:1594 tcop/postgres.c:2000 +#: tcop/postgres.c:2373 tcop/postgres.c:2452 #, c-format -msgid "multiple Dictionary parameters" -msgstr "Dictionary 매개 변수가 여러 ê°œ 있ìŒ" +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "현재 íŠ¸ëžœìž­ì…˜ì€ ì¤‘ì§€ë˜ì–´ 있습니다. ì´ íŠ¸ëžœìž­ì…˜ì„ ì¢…ë£Œí•˜ê¸° 전까지는 모든 ëª…ë ¹ì´ ë¬´ì‹œë  ê²ƒìž…ë‹ˆë‹¤" -#: tsearch/dict_thesaurus.c:639 +#: replication/walsender.c:1562 #, c-format -msgid "unrecognized Thesaurus parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 Thesaurus 매개 변수: \"%s\"" +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "ë¬¼ë¦¬ì  ë³µì œë¥¼ 위한 WAL 송신기ì—서 SQL ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: tsearch/dict_thesaurus.c:651 +#: replication/walsender.c:1610 replication/walsender.c:1626 #, c-format -msgid "missing Dictionary parameter" -msgstr "Dictionary 매개 변수가 누ë½ë¨" +msgid "unexpected EOF on standby connection" +msgstr "대기 서버 ì—°ê²°ì—서 예ìƒì¹˜ 못한 EOF 발견함" -#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 -#: tsearch/spell.c:1034 +#: replication/walsender.c:1640 #, c-format -msgid "invalid affix flag \"%s\"" -msgstr "ìž˜ëª»ëœ affix 플래그: \"%s\"" +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "" -#: tsearch/spell.c:384 tsearch/spell.c:1038 +#: replication/walsender.c:1678 #, c-format -msgid "affix flag \"%s\" is out of range" -msgstr "affix 플래그 범위 초과: \"%s\"" +msgid "invalid standby message type \"%c\"" +msgstr "ìž˜ëª»ëœ ëŒ€ê¸° 서버 메시지 형태 \"%c\"" -#: tsearch/spell.c:414 +#: replication/walsender.c:1719 #, c-format -msgid "invalid character in affix flag \"%s\"" -msgstr "affix í”Œëž˜ê·¸ì— ì´ìƒí•œ 문ìžê°€ 있ìŒ: \"%s\"" +msgid "unexpected message type \"%c\"" +msgstr "예ìƒì¹˜ 못한 메시지 형태: \"%c\"" -#: tsearch/spell.c:434 +#: replication/walsender.c:2097 #, c-format -msgid "invalid affix flag \"%s\" with \"long\" flag value" -msgstr "" +msgid "terminating walsender process due to replication timeout" +msgstr "복제 시간 제한으로 wal 송신기 프로세스를 종료합니다." -#: tsearch/spell.c:522 +#: replication/walsender.c:2181 #, c-format -msgid "could not open dictionary file \"%s\": %m" -msgstr "\"%s\" 사전 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" 프로세스가 로그 전달 ë°›ì„ ì„œë²„ì™€ ì ‘ì†í–ˆìŒ" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: replication/walsender.c:2290 #, c-format -msgid "invalid regular expression: %s" -msgstr "ìž˜ëª»ëœ ì •ê·œì‹: %s" +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "대기 서버 ì—°ê²° 수가 max_wal_senders 설정값(현재 %d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" -#: tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 -#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:14405 gram.y:14422 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format -msgid "syntax error" -msgstr "구문 오류" +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ ë£°(rule)ì´ \"%s\" í…Œì´ë¸”ì— ì´ë¯¸ 지정ë˜ì–´ìžˆìŠµë‹ˆë‹¤" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: rewrite/rewriteDefine.c:296 #, c-format -msgid "invalid affix alias \"%s\"" -msgstr "ìž˜ëª»ëœ affix 별칭: \"%s\"" +msgid "rule actions on OLD are not implemented" +msgstr "OLDì— ëŒ€í•œ 실행 룰(rule)ì€ ì•„ì§ êµ¬í˜„ë˜ì§€ 않았습니다" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: rewrite/rewriteDefine.c:297 #, c-format -msgid "could not open affix file \"%s\": %m" -msgstr "\"%s\" affix 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "Use views or triggers instead." +msgstr "ëŒ€ì‹ ì— ë·°ë‚˜ 트리거를 사용하십시오." -#: tsearch/spell.c:1265 +#: rewrite/rewriteDefine.c:301 #, c-format -msgid "" -"Ispell dictionary supports only \"default\", \"long\", and \"num\" flag " -"values" -msgstr "Ispell ì‚¬ì „ì€ \"default\", \"long\", \"num\" 플래그 ê°’ë§Œ ì§€ì›í•¨" +msgid "rule actions on NEW are not implemented" +msgstr "NEWì— ëŒ€í•œ 실행 룰(rule)ì€ ì•„ì§ êµ¬í˜„ë˜ì§€ 않았습니다" -#: tsearch/spell.c:1309 +#: rewrite/rewriteDefine.c:302 #, c-format -msgid "invalid number of flag vector aliases" -msgstr "ìž˜ëª»ëœ í”Œëž˜ê·¸ 백터 별칭 개수" +msgid "Use triggers instead." +msgstr "ëŒ€ì‹ ì— íŠ¸ë¦¬ê±°ë¥¼ 사용하십시오." -#: tsearch/spell.c:1542 +#: rewrite/rewriteDefine.c:315 #, c-format -msgid "affix file contains both old-style and new-style commands" -msgstr "affix 파ì¼ì— 옛방ì‹ê³¼ ìƒˆë°©ì‹ ëª…ë ¹ì´ í•¨ê»˜ 있습니다" +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "SELECT ì—서 INSTEAD NOTHING 룰(rule)ì€ êµ¬í˜„ë˜ì§€ 않았습니다" -#: tsearch/to_tsany.c:170 utils/adt/tsvector.c:270 -#: utils/adt/tsvector_op.c:1133 +#: rewrite/rewriteDefine.c:316 #, c-format -msgid "string is too long for tsvector (%d bytes, max %d bytes)" -msgstr "" -"문ìžì—´ì´ 너무 길어서 tsvectorì— ì‚¬ìš©í•  수 ì—†ìŒ(%dë°”ì´íЏ, 최대 %dë°”ì´íЏ)" +msgid "Use views instead." +msgstr "ëŒ€ì‹ ì— ë·°ë¥¼ 사용하십시오." -#: tsearch/ts_locale.c:177 +#: rewrite/rewriteDefine.c:324 #, c-format -msgid "line %d of configuration file \"%s\": \"%s\"" -msgstr "%d번째 줄(해당 파ì¼: \"%s\"): \"%s\"" +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "SELECTì— ëŒ€í•œ 다중 실행 룰(rule)ì€ êµ¬í˜„ë˜ì§€ 않았습니다" -#: tsearch/ts_locale.c:299 +#: rewrite/rewriteDefine.c:334 #, c-format -msgid "conversion from wchar_t to server encoding failed: %m" -msgstr "wchar_tì—서 서버 ì¸ì½”딩으로 변환하지 못함: %m" +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "SELECTì— ëŒ€í•œ 룰(rule)ì€ ê·¸ ì§€ì •ì— INSTEAD SELECT ì‹¤í–‰ê·œì¹™ì„ ì§€ì •í•´ì•¼ë§Œí•©ë‹ˆë‹¤" -#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:566 -#: tsearch/ts_parse.c:573 +#: rewrite/rewriteDefine.c:342 #, c-format -msgid "word is too long to be indexed" -msgstr "단어가 너무 길어서 ì¸ë±ì‹±í•  수 ì—†ìŒ" +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "" -#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:567 -#: tsearch/ts_parse.c:574 +#: rewrite/rewriteDefine.c:350 #, c-format -msgid "Words longer than %d characters are ignored." -msgstr "%dìžë³´ë‹¤ 긴 단어는 무시ë©ë‹ˆë‹¤." +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "ì´ë²¤íЏ ìžê²©(event qualifications)ì€ SELECT 룰(rule)ì—서 구현ë˜ì§€ 않았습니다" -#: tsearch/ts_utils.c:51 +#: rewrite/rewriteDefine.c:377 #, c-format -msgid "invalid text search configuration file name \"%s\"" -msgstr "\"%s\" 전문 검색 구성 íŒŒì¼ ì´ë¦„ì´ ìž˜ëª»ë¨" +msgid "\"%s\" is already a view" +msgstr "\"%s\" ì´ë¦„ì˜ ë·°ê°€ ì´ë¯¸ 있습니다" -#: tsearch/ts_utils.c:83 +#: rewrite/rewriteDefine.c:401 #, c-format -msgid "could not open stop-word file \"%s\": %m" -msgstr "\"%s\" 중지 단어 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "\"%s\" 위한 ë·° 룰(view rule)ì˜ ì´ë¦„ì€ \"%s\" 여야만합니다" -#: tsearch/wparser.c:306 +#: rewrite/rewriteDefine.c:428 #, c-format -msgid "text search parser does not support headline creation" -msgstr "전문 검색 ë¶„ì„기ì—서 헤드ë¼ì¸ ìž‘ì„±ì„ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸”ì€ ë·°ë¡œ 변환할 수 없습니다" -#: tsearch/wparser_def.c:2583 +#: rewrite/rewriteDefine.c:434 #, c-format -msgid "unrecognized headline parameter: \"%s\"" -msgstr "ì¸ì‹í•  수 없는 headline 매개 변수: \"%s\"" +msgid "cannot convert partition \"%s\" to a view" +msgstr "\"%s\" 파티션 í…Œì´ë¸”ì€ ë·°ë¡œ 변환할 수 없습니다" -#: tsearch/wparser_def.c:2592 +#: rewrite/rewriteDefine.c:442 #, c-format -msgid "MinWords should be less than MaxWords" -msgstr "MinWords는 MaxWords보다 작아야 함" +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "\"%s\" í…Œì´ë¸”ì— ìžë£Œê°€ 있기 때문ì—, í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" -#: tsearch/wparser_def.c:2596 +#: rewrite/rewriteDefine.c:450 #, c-format -msgid "MinWords should be positive" -msgstr "MinWords는 양수여야 함" +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "\"%s\" í…Œì´ë¸”ì— íŠ¸ë¦¬ê±°ê°€ í¬í•¨ë˜ì–´ 있어 뷰로 변환할 수 없습니다" -#: tsearch/wparser_def.c:2600 +#: rewrite/rewriteDefine.c:452 #, c-format -msgid "ShortWord should be >= 0" -msgstr "ShortWord는 0보다 í¬ê±°ë‚˜ 같아야 함" +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "특히 í…Œì´ë¸”ì€ ì°¸ì¡°í‚¤ ê´€ê³„ì— ê´€ë ¨ë  ìˆ˜ 없습니다." -#: tsearch/wparser_def.c:2604 +#: rewrite/rewriteDefine.c:457 #, c-format -msgid "MaxFragments should be >= 0" -msgstr "MaxFragments는 0보다 í¬ê±°ë‚˜ 같아야 함" +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "\"%s\" í…Œì´ë¸”ì— ì¸ë±ìŠ¤ê°€ í¬í•¨ë˜ì–´ 있어 뷰로 변환할 수 없습니다" -# # nonun 부분 begin -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: rewrite/rewriteDefine.c:463 #, c-format -msgid "identifier too long" -msgstr "ì‹ë³„ìž(identifier)ê°€ 너무 ê¹ë‹ˆë‹¤." +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "\"%s\" í…Œì´ë¸”ì„ ìƒì† 받는 í…Œì´ë¸”ì´ ìžˆì–´ 뷰로 변활할 수 없습니다" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: rewrite/rewriteDefine.c:469 #, c-format -msgid "Identifier must be less than %d characters." -msgstr "ì‹ë³„ìž(Identifier)는 %d ê¸€ìž ì´ìƒì¼ 수 없습니다." +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "로우단위 보안 ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ê³  있어 \"%s\" í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" -#: utils/adt/acl.c:257 +#: rewrite/rewriteDefine.c:475 #, c-format -msgid "unrecognized key word: \"%s\"" -msgstr "알 수 없는 ì•Šì€ í‚¤ì›Œë“œ: \"%s\"" +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "로우단위 보안 ì„¤ì •ì´ ë˜ì–´ 있어 \"%s\" í…Œì´ë¸”ì„ ë·°ë¡œ 변환할 수 없습니다" -#: utils/adt/acl.c:258 +#: rewrite/rewriteDefine.c:502 #, c-format -msgid "ACL key word must be \"group\" or \"user\"." -msgstr "ACL 키워드는 \"group\" ë˜ëŠ” \"user\" ì¤‘ì— í•˜ë‚˜ì—¬ì•¼ 합니다." +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "í•˜ë‚˜ì˜ ruleì—서 ì—¬ëŸ¬ê°œì˜ RETURNING 목ë¡ì„ 지정할 수 없습니다" -#: utils/adt/acl.c:263 +#: rewrite/rewriteDefine.c:507 #, c-format -msgid "missing name" -msgstr "ì´ë¦„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤." +msgid "RETURNING lists are not supported in conditional rules" +msgstr "RETURNING 목ë¡ì€ conditional ruleì—서는 ì§€ì›í•˜ì§€ 않습니다" -#: utils/adt/acl.c:264 +#: rewrite/rewriteDefine.c:511 #, c-format -msgid "A name must follow the \"group\" or \"user\" key word." -msgstr "ì´ë¦„ì€ \"group\" ë˜ëŠ” \"user\" 키워드 ë’¤ì— ìžˆì–´ì•¼ 합니다." +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "RETURNING 목ë¡ì€ non-INSTEAD ruleì—서는 ì§€ì›í•˜ì§€ 않습니다" -#: utils/adt/acl.c:270 +#: rewrite/rewriteDefine.c:675 #, c-format -msgid "missing \"=\" sign" -msgstr "\"=\" 기호가 빠졌습니다." +msgid "SELECT rule's target list has too many entries" +msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ëª©ë¡ì´ 너무 ë§Žì€ ì—”íŠ¸ë¦¬ë¥¼ 가지고 있습니다" -#: utils/adt/acl.c:323 +#: rewrite/rewriteDefine.c:676 #, c-format -msgid "invalid mode character: must be one of \"%s\"" -msgstr "ìž˜ëª»ëœ ì¡°ê±´: \"%s\" ì¤‘ì— í•œ 가지여야 합니다." +msgid "RETURNING list has too many entries" +msgstr "RETURNING 목ë¡ì´ 너무 ë§Žì€ í•­ëª©ë¥¼ 가지고 있습니다" -#: utils/adt/acl.c:345 +#: rewrite/rewriteDefine.c:703 #, c-format -msgid "a name must follow the \"/\" sign" -msgstr "ì´ë¦„ì€ \"/\"기호 ë’¤ì— ìžˆì–´ì•¼ 합니다." +msgid "cannot convert relation containing dropped columns to view" +msgstr "ë·°ì—서 ì‚­ì œëœ ì¹¼ëŸ¼ì„ í¬í•¨í•˜ê³  있는 릴레ì´ì…˜ì„ 변환할 수 없습니다" -#: utils/adt/acl.c:353 +#: rewrite/rewriteDefine.c:704 #, c-format -msgid "defaulting grantor to user ID %u" -msgstr "%u ì‚¬ìš©ìž IDì—서 기본 권한ìžë¡œ 할당하고 있습니다" +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "릴레ì´ì…˜ì— ì‚­ì œëœ ì¹¼ëŸ¼ì„ í¬í•¨í•˜ê³  있는 RETURNING 목ë¡ì„ 만들 수 없습니다." -#: utils/adt/acl.c:544 +#: rewrite/rewriteDefine.c:710 #, c-format -msgid "ACL array contains wrong data type" -msgstr "ACL ë°°ì—´ì— ìž˜ëª»ëœ ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ê³  있습니다" +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호가(%d)ê°€ \"%s\" 칼럼 ì´ë¦„ê³¼ 틀립니다" -#: utils/adt/acl.c:548 +#: rewrite/rewriteDefine.c:712 #, c-format -msgid "ACL arrays must be one-dimensional" -msgstr "ACL ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼í•©ë‹ˆë‹¤" +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT ëŒ€ìƒ ì—”íŠ¸ë¦¬ ì´ë¦„ì€ \"%s\" 입니다." -#: utils/adt/acl.c:552 +#: rewrite/rewriteDefine.c:721 #, c-format -msgid "ACL arrays must not contain null values" -msgstr "ACL ë°°ì—´ì—는 null ê°’ì„ í¬í•¨í•  수 없습니다" +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호(%d)ê°€ \"%s\" 칼럼 ìžë£Œí˜•ê³¼ 틀립니다" -#: utils/adt/acl.c:576 +#: rewrite/rewriteDefine.c:723 #, c-format -msgid "extra garbage at the end of the ACL specification" -msgstr "ACL 설정 ì •ë³´ ëì— ëì— ì“¸ëª¨ 없는 ë‚´ìš©ë“¤ì´ ë” í¬í•¨ë˜ì–´ìžˆìŠµë‹ˆë‹¤" +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNING 목ë¡ì˜ %d번째 í•­ëª©ì˜ ìžë£Œí˜•ì´ \"%s\" 칼럼 ìžë£Œí˜•ê³¼ 틀립니다" -#: utils/adt/acl.c:1196 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 #, c-format -msgid "grant options cannot be granted back to your own grantor" -msgstr "부여 ì˜µì…˜ì„ í•´ë‹¹ 부여ìžì—게 다시 부여할 수 ì—†ìŒ" +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT ëŒ€ìƒ ì—”íŠ¸ë¦¬ ìžë£Œí˜•ì€ %s 형ì´ì§€ë§Œ, 칼럼 ìžë£Œí˜•ì€ %s 형입니다." -#: utils/adt/acl.c:1257 +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 #, c-format -msgid "dependent privileges exist" -msgstr "???ì˜ì¡´(ì ì¸) ê¶Œí•œì´ ì¡´ìž¬í•©ë‹ˆë‹¤" +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNING 목ë¡ì€ %s ìžë£Œí˜•ì´ì§€ë§Œ, 칼럼 ìžë£Œí˜•ì€ %s 형입니다." -#: utils/adt/acl.c:1258 +#: rewrite/rewriteDefine.c:745 #, c-format -msgid "Use CASCADE to revoke them too." -msgstr "ê·¸ê²ƒë“¤ì„ ì·¨ì†Œí•˜ë ¤ë©´ \"CASCADE\"를 사용하세요." +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ì—”íŠ¸ë¦¬ 번호(%d)ê°€ \"%s\" 칼럼 í¬ê¸°ì™€ 틀립니다" -#: utils/adt/acl.c:1537 +#: rewrite/rewriteDefine.c:747 #, c-format -msgid "aclinsert is no longer supported" -msgstr "aclinsert ë”ì´ìƒ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNING 목ë¡ì˜ %d번째 í•­ëª©ì˜ í¬ê¸°ê°€ \"%s\" 칼럼 í¬ê¸°ì™€ 틀립니다" -#: utils/adt/acl.c:1547 +#: rewrite/rewriteDefine.c:764 #, c-format -msgid "aclremove is no longer supported" -msgstr "aclremovie ë”ì´ìƒ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "SELECT rule's target list has too few entries" +msgstr "SELECT 룰(rule)ì˜ ëŒ€ìƒ ëª©ë¡ì´ 너무 ì ì€ 엔트리를 가지고 있습니다" -#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 +#: rewrite/rewriteDefine.c:765 #, c-format -msgid "unrecognized privilege type: \"%s\"" -msgstr "알 수 없는 권한 타입: \"%s\"" +msgid "RETURNING list has too few entries" +msgstr "RETURNING 목ë¡ì— 너무 ì ì€ í•­ëª©ì´ ìžˆìŠµë‹ˆë‹¤" -#: utils/adt/acl.c:3427 utils/adt/regproc.c:123 utils/adt/regproc.c:144 -#: utils/adt/regproc.c:319 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 +#: rewrite/rewriteSupport.c:109 #, c-format -msgid "function \"%s\" does not exist" -msgstr "\"%s\" 함수가 없습니다." +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr " \"%s\" 룰(rule)ì´ \"%s\" 관계(relation)ì— ì§€ì •ëœ ê²ƒì´ ì—†ìŒ" -#: utils/adt/acl.c:4881 +#: rewrite/rewriteDefine.c:990 #, c-format -msgid "must be member of role \"%s\"" -msgstr "\"%s\" ë¡¤ì˜ êµ¬ì„±ì›ì´ì–´ì•¼ 함" +msgid "renaming an ON SELECT rule is not allowed" +msgstr "ON SELECT ë£°ì˜ ì´ë¦„ 바꾸기는 허용하지 않습니다" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5848 -#: utils/adt/arrayfuncs.c:6159 utils/adt/arrayutils.c:93 -#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#: rewrite/rewriteHandler.c:541 #, c-format -msgid "array size exceeds the maximum allowed (%d)" -msgstr "ë°°ì—´ í¬ê¸°ê°€ 최대치 (%d)를 초과했습니다" +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:541 -#: utils/adt/array_userfuncs.c:621 utils/adt/json.c:1759 utils/adt/json.c:1854 -#: utils/adt/json.c:1892 utils/adt/jsonb.c:1126 utils/adt/jsonb.c:1155 -#: utils/adt/jsonb.c:1591 utils/adt/jsonb.c:1755 utils/adt/jsonb.c:1765 +#: rewrite/rewriteHandler.c:601 #, c-format -msgid "could not determine input data type" -msgstr "ìž…ë ¥ ìžë£Œí˜•ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "cannot have RETURNING lists in multiple rules" +msgstr "multiple ruleì— RETURNING 목ë¡ì„ 지정할 수 없습니다" -#: utils/adt/array_userfuncs.c:84 +#: rewrite/rewriteHandler.c:823 #, c-format -msgid "input data type is not an array" -msgstr "ìž…ë ¥ ìžë£Œí˜•ì´ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." +msgid "cannot insert into column \"%s\"" +msgstr "\"%s\" ì¹¼ëŸ¼ì— ìžë£Œë¥¼ 입력할 수 없습니다" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 -#: utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:623 -#: utils/adt/int.c:652 utils/adt/int.c:673 utils/adt/int.c:704 -#: utils/adt/int.c:737 utils/adt/int.c:759 utils/adt/int.c:907 -#: utils/adt/int.c:928 utils/adt/int.c:955 utils/adt/int.c:995 -#: utils/adt/int.c:1016 utils/adt/int.c:1043 utils/adt/int.c:1076 -#: utils/adt/int.c:1159 utils/adt/int8.c:1298 utils/adt/numeric.c:2903 -#: utils/adt/numeric.c:2912 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 -#: utils/adt/varlena.c:1055 utils/adt/varlena.c:2807 +#: rewrite/rewriteHandler.c:824 rewrite/rewriteHandler.c:839 #, c-format -msgid "integer out of range" -msgstr "정수 범위를 벗어남" +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: rewrite/rewriteHandler.c:826 #, c-format -msgid "argument must be empty or one-dimensional array" -msgstr "ì¸ìžëŠ” 비어있거나 1ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 -#: utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 -#: utils/adt/array_userfuncs.c:411 +#: rewrite/rewriteHandler.c:838 #, c-format -msgid "cannot concatenate incompatible arrays" -msgstr "ì—°ê²°í•  수 없는 배열들 입니다." +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ DEFAULT 로만 ì—…ë°ì´íЏ 가능합니다" -#: utils/adt/array_userfuncs.c:279 +#: rewrite/rewriteHandler.c:1000 rewrite/rewriteHandler.c:1018 #, c-format -msgid "" -"Arrays with element types %s and %s are not compatible for concatenation." -msgstr "%s ìžë£Œí˜•ì˜ ë°°ì—´ê³¼ %s ìžë£Œí˜•ì˜ ë°°ì—´ì€ ì—°ê²°í•  수 없습니다." +msgid "multiple assignments to same column \"%s\"" +msgstr "ê°™ì€ \"%s\" ì—´ì— ì§€ì •ê°’(assignment)ì´ ì¤‘ë³µë˜ì—ˆìŠµë‹ˆë‹¤" -#: utils/adt/array_userfuncs.c:318 +#: rewrite/rewriteHandler.c:1921 #, c-format -msgid "Arrays of %d and %d dimensions are not compatible for concatenation." -msgstr "%dì°¨ì›(ë°°ì—´ 깊ì´) ë°°ì—´ê³¼ %dì°¨ì› ë°°ì—´ì€ ì—°ê²°í•  수 없습니다." +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì˜ ì •ì±…ì—서 무한 재귀 í˜¸ì¶œì´ ë°œê²¬ ë¨" + +#: rewrite/rewriteHandler.c:2241 +msgid "Junk view columns are not updatable." +msgstr "ì •í¬ ë·° ì¹¼ëŸ¼ì€ ì—…ë°ì´íŠ¸í•  수 없습니다." + +#: rewrite/rewriteHandler.c:2246 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2249 +msgid "View columns that refer to system columns are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2252 +msgid "View columns that return whole-row references are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2313 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "" -#: utils/adt/array_userfuncs.c:355 +#: rewrite/rewriteHandler.c:2316 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2319 +msgid "Views containing HAVING are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2322 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2325 +msgid "Views containing WITH are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2328 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2340 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2343 +msgid "Views that return window functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2346 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2353 rewrite/rewriteHandler.c:2357 +#: rewrite/rewriteHandler.c:2365 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2368 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2392 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2849 #, c-format -msgid "" -"Arrays with differing element dimensions are not compatible for " -"concatenation." -msgstr "ì°¨ì›(ë°°ì—´ 깊ì´)ì´ ë‹¤ë¥¸ ë°°ì—´ë“¤ì„ ì„œë¡œ í•©ì¹  수 없습니다" +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "\"%s\" 칼럼 (해당 ë·°: \"%s\")ì— ìžë£Œë¥¼ 입력할 수 없습니다" -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: rewrite/rewriteHandler.c:2857 #, c-format -msgid "Arrays with differing dimensions are not compatible for concatenation." -msgstr "ì°¨ì›(ë°°ì—´ 깊ì´)ì´ ë‹¤ë¥¸ ë°°ì—´ë“¤ì„ ì„œë¡œ í•©ì¹  수 없습니다" +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "\"%s\" 칼럼 (해당 ë·°: \"%s\")ì— ìžë£Œë¥¼ 갱신할 수 없습니다" -#: utils/adt/array_userfuncs.c:480 utils/adt/arrayfuncs.c:1284 -#: utils/adt/arrayfuncs.c:3357 utils/adt/arrayfuncs.c:5754 +#: rewrite/rewriteHandler.c:3327 #, c-format -msgid "invalid number of dimensions: %d" -msgstr "ìž˜ëª»ëœ ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´): %d" +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "" -#: utils/adt/array_userfuncs.c:737 utils/adt/array_userfuncs.c:889 +#: rewrite/rewriteHandler.c:3341 #, c-format -msgid "searching for elements in multidimensional arrays is not supported" -msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—서 요소 검색 ê¸°ëŠ¥ì€ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" -#: utils/adt/array_userfuncs.c:761 +#: rewrite/rewriteHandler.c:3345 #, c-format -msgid "initial position must not be null" -msgstr "초기 ìœ„ì¹˜ê°’ì€ nullê°’ì´ ì•„ë‹ˆì—¬ì•¼ 함" +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: rewrite/rewriteHandler.c:3350 #, c-format -msgid "malformed array literal: \"%s\"" -msgstr "비정ìƒì ì¸ ë°°ì—´ 문ìž: \"%s\"" +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" -#: utils/adt/arrayfuncs.c:269 +#: rewrite/rewriteHandler.c:3569 #, c-format -msgid "\"[\" must introduce explicitly-specified array dimensions." -msgstr "ë°°ì—´ ì°¨ì› ì •ì˜ëŠ” \"[\" 문ìžë¡œ 시작해야 합니다." +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì—서 INSERT RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 ì—†ìŒ" -#: utils/adt/arrayfuncs.c:283 +#: rewrite/rewriteHandler.c:3571 #, c-format -msgid "Missing array dimension value." -msgstr "ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´) ê°’ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤." +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING ì ˆì—서는 무조건 ON INSERT DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆë‹¤." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: rewrite/rewriteHandler.c:3576 #, c-format -msgid "Missing \"%s\" after array dimensions." -msgstr "ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´) 표현ì—서 \"%s\" 문ìžê°€ 빠졌습니다." +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì—서 UPDATE RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 없습니다." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: rewrite/rewriteHandler.c:3578 #, c-format -msgid "upper bound cannot be less than lower bound" -msgstr "ìƒí•œê°’ì€ í•˜í•œê°’ë³´ë‹¤ ìž‘ì„ ìˆ˜ 없습니다" +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING ì ˆì—서는 무조건 ON UPDATE DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆë‹¤." -#: utils/adt/arrayfuncs.c:316 +#: rewrite/rewriteHandler.c:3583 #, c-format -msgid "Array value must start with \"{\" or dimension information." -msgstr "ë°°ì—´ê°’ì€ \"{\" ë˜ëŠ” ë°°ì—´ ê¹Šì´ ì •ë³´ë¡œ 시작ë˜ì–´ì•¼ 합니다" +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "\"%s\" 릴레ì´ì…˜ì—서 DELETE RETURNING ê´€ë ¨ì„ êµ¬ì„±í•  수 없습니다." -#: utils/adt/arrayfuncs.c:345 +#: rewrite/rewriteHandler.c:3585 #, c-format -msgid "Array contents must start with \"{\"." -msgstr "ë°°ì—´í˜•ì€ \"{\" 문ìžë¡œ 시작해야 합니다." +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "TURNING ì ˆì—서는 무조건 ON DELETE DO INSTEAD ì†ì„±ìœ¼ë¡œ ruleì´ ì‚¬ìš©ë˜ì–´ì•¼í•©ë‹ˆë‹¤" -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: rewrite/rewriteHandler.c:3603 #, c-format -msgid "Specified array dimensions do not match array contents." -msgstr "지정한 ë°°ì—´ ì°¨ì›ì— 해당하는 ë°°ì—´ì´ ì—†ìŠµë‹ˆë‹¤." +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "" -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2124 utils/adt/rangetypes.c:2132 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: rewrite/rewriteHandler.c:3660 #, c-format -msgid "Unexpected end of input." -msgstr "ìž…ë ¥ì˜ ì˜ˆìƒì¹˜ 못한 종료." +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "" -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: rewrite/rewriteManip.c:1003 #, c-format -msgid "Unexpected \"%c\" character." -msgstr "예기치 ì•Šì€ \"%c\" 문ìž" +msgid "conditional utility statements are not implemented" +msgstr "ì¡°ê±´ 유틸리티 명령 구문(conditional utility statement)ì€ êµ¬í˜„ë˜ì–´ìžˆì§€ 않습니다" -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: rewrite/rewriteManip.c:1169 #, c-format -msgid "Unexpected array element." -msgstr "예기치 ì•Šì€ ë°°ì—´ 요소" +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "ë·°ì— ëŒ€í•œ WHERE CURRENT OF êµ¬ë¬¸ì´ êµ¬í˜„ë˜ì§€ 않ìŒ" -#: utils/adt/arrayfuncs.c:589 +#: rewrite/rewriteManip.c:1503 #, c-format -msgid "Unmatched \"%c\" character." -msgstr "ì§ì´ 안 맞는 \"%c\" 문ìž" +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "" -#: utils/adt/arrayfuncs.c:597 -#, c-format -msgid "Multidimensional arrays must have sub-arrays with matching dimensions." -msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—는 ì¼ì¹˜í•˜ëŠ” ì°¨ì›ì´ í¬í•¨ëœ ë°°ì—´ ì‹ì´ 있어야 함" +# # advance ë +#: scan.l:445 +msgid "unterminated /* comment" +msgstr "마무리 ì•ˆëœ /* 주ì„" -#: utils/adt/arrayfuncs.c:674 -#, c-format -msgid "Junk after closing right brace." -msgstr "오른쪽 닫기 괄호 ë’¤ì— ì •í¬" +#: scan.l:474 +msgid "unterminated bit string literal" +msgstr "마무리 ì•ˆëœ ë¹„íŠ¸ 문ìžì—´ 문ìž" -#: utils/adt/arrayfuncs.c:1295 -#, c-format -msgid "invalid array flags" -msgstr "ìž˜ëª»ëœ ë°°ì—´ 플래그" +#: scan.l:495 +msgid "unterminated hexadecimal string literal" +msgstr "마무리 ì•ˆëœ 16진수 문ìžì—´ 문ìž" -#: utils/adt/arrayfuncs.c:1303 +#: scan.l:545 #, c-format -msgid "wrong element type" -msgstr "ìž˜ëª»ëœ ìš”ì†Œ 타입" +msgid "unsafe use of string constant with Unicode escapes" +msgstr "유니코드 ì´ìŠ¤ì¼€ì´í”„와 함께 문ìžì—´ ìƒìˆ˜ë¥¼ 사용하는 ê²ƒì€ ì•ˆì „í•˜ì§€ 않ìŒ" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2651 +#: scan.l:546 #, c-format -msgid "no binary input function available for type %s" -msgstr "%s ìžë£Œí˜•ì—서 사용할 ë°”ì´ë„ˆë¦¬ ìž…ë ¥ 함수가 없습니다." +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "standard_conforming_strings = off ì¸ ê²½ìš° 문ìžì—´ ìƒìˆ˜ 표기ì—서 유니코드 ì´ìŠ¤ì¼€ì´í”„를 사용할 수 없습니다." -#: utils/adt/arrayfuncs.c:1493 -#, c-format -msgid "improper binary format in array element %d" -msgstr "%d 번째 ë°°ì—´ ìš”ì†Œì˜ í¬ë§·ì´ ë¶€ì ì ˆí•©ë‹ˆë‹¤." +#: scan.l:592 scan.l:791 +msgid "invalid Unicode escape character" +msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ 문ìž" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2684 -#, c-format -msgid "no binary output function available for type %s" -msgstr "%s ìžë£Œí˜•ì—서 사용할 ë°”ì´ë„ˆë¦¬ 출력 함수가 없습니다." +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 +#: scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 +msgid "invalid Unicode surrogate pair" +msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ 대리 ìŒ" -#: utils/adt/arrayfuncs.c:2052 +#: scan.l:640 #, c-format -msgid "slices of fixed-length arrays not implemented" -msgstr "특정 í¬ê¸°ë¡œ ë°°ì—´ì„ ì ˆë‹¨í•˜ëŠ” ê¸°ëŠ¥ì€ êµ¬í˜„ë˜ì§€ 않습니다." +msgid "invalid Unicode escape" +msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ ê°’" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5740 -#: utils/adt/arrayfuncs.c:5766 utils/adt/arrayfuncs.c:5777 -#: utils/adt/json.c:2290 utils/adt/json.c:2365 utils/adt/jsonb.c:1369 -#: utils/adt/jsonb.c:1455 utils/adt/jsonfuncs.c:3529 -#: utils/adt/jsonfuncs.c:3574 utils/adt/jsonfuncs.c:3621 +#: scan.l:641 #, c-format -msgid "wrong number of array subscripts" -msgstr "ìž˜ëª»ëœ ë°°ì—´ 하위 스í¬ë¦½íЏ(1,2...ì°¨ì› ë°°ì—´ 표시 문제)" +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "유니코드 ì´ìŠ¤ì¼€ì´í”„는 \\uXXXX ë˜ëŠ” \\UXXXXXXXX 형태여야 합니다." -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: scan.l:652 #, c-format -msgid "array subscript out of range" -msgstr "ë°°ì—´ 하위 스í¬ë¦½íЏ 범위를 초과했습니다" +msgid "unsafe use of \\' in a string literal" +msgstr "문ìžì—´ ì•ˆì— \\' ì‚¬ìš©ì´ ì•ˆì „í•˜ì§€ 않습니다" -#: utils/adt/arrayfuncs.c:2240 +#: scan.l:653 #, c-format -msgid "cannot assign null value to an element of a fixed-length array" -msgstr "ê³ ì • ê¸¸ì´ ë°°ì—´ì˜ ìš”ì†Œì— null ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "ìž‘ì€ ë”°ì˜´í‘œëŠ” '' 형태로 사용하십시오. \\' í‘œê¸°ë²•ì€ í´ë¼ì´ì–¸íЏ ì „ìš© ì¸ì½”딩ì—서 안전하지 않습니다." -#: utils/adt/arrayfuncs.c:2795 -#, c-format -msgid "updates on slices of fixed-length arrays not implemented" -msgstr "ê³ ì •ëœ í¬ê¸°ì˜ ë°°ì—´ì˜ ì¡°ê°ì„ ì—…ë°ì´íЏ 하는 ê¸°ëŠ¥ì€ êµ¬í˜„ë˜ì§€ 않았습니다." +#: scan.l:728 +msgid "unterminated dollar-quoted string" +msgstr "마무리 ì•ˆëœ ë‹¬ëŸ¬-따옴표 ì•ˆì˜ ë¬¸ìžì—´" + +#: scan.l:745 scan.l:771 scan.l:786 +msgid "zero-length delimited identifier" +msgstr "길ì´ê°€ 0ì¸ êµ¬ë¶„ ì‹ë³„ìž" + +#: scan.l:806 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ì‹ë³„ìž" + +# # nonun 부분 begin +#: scan.l:969 +msgid "operator too long" +msgstr "ì—°ì‚°ìžê°€ 너무 ê¹ë‹ˆë‹¤." -#: utils/adt/arrayfuncs.c:2826 +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1125 #, c-format -msgid "array slice subscript must provide both boundaries" -msgstr "ë°°ì—´ 나누기 서브스í¬ë¦½íŠ¸ëŠ” 반드시 둘다 ë²”ìœ„ì•ˆì— ìžˆì–´ì•¼ 합니다" +msgid "%s at end of input" +msgstr "%s, ìž…ë ¥ ë부분" -#: utils/adt/arrayfuncs.c:2827 +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1133 #, c-format -msgid "" -"When assigning to a slice of an empty array value, slice boundaries must be " -"fully specified." -msgstr "" +msgid "%s at or near \"%s\"" +msgstr "%s, \"%s\" 부근" + +#: scan.l:1294 scan.l:1326 +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +msgstr "서버 ì¸ì½”ë”©ì´ UTF8ì´ ì•„ë‹Œ 경우 007F보다 í° ì½”ë“œ ì§€ì  ê°’ì—는 유니코드 ì´ìŠ¤ì¼€ì´í”„ ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" + +#: scan.l:1322 scan.l:1467 +msgid "invalid Unicode escape value" +msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ ê°’" -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: scan.l:1531 #, c-format -msgid "source array too small" -msgstr "ì›ë³¸ ë°°ì—´ì´ ë„ˆë¬´ 작습니다." +msgid "nonstandard use of \\' in a string literal" +msgstr "문ìžì—´ ì•ˆì— ìžˆëŠ” \\' 문ìžëŠ” í‘œì¤€ì´ ì•„ë‹™ë‹ˆë‹¤" -#: utils/adt/arrayfuncs.c:3513 +#: scan.l:1532 #, c-format -msgid "null array element not allowed in this context" -msgstr "ì´ êµ¬ë¬¸ì—서는 ë°°ì—´ì˜ null 요소를 허용하지 않습니다" +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "ìž‘ì€ ë”°ì˜´í‘œëŠ” '' 형태니, ì¸ìš©ë¶€í˜¸ 표기법(E'...') 형태로 사용하십시오." -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: scan.l:1541 #, c-format -msgid "cannot compare arrays of different element types" -msgstr "ë°°ì—´ 요소 ìžë£Œí˜•ì´ ì„œë¡œ 틀린 ë°°ì—´ì€ ë¹„êµí•  수 없습니다." +msgid "nonstandard use of \\\\ in a string literal" +msgstr "문ìžì—´ ì•ˆì— ìžˆëŠ” \\\\ 문ìžëŠ” í‘œì¤€ì´ ì•„ë‹™ë‹ˆë‹¤" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: scan.l:1542 #, c-format -msgid "could not identify a hash function for type %s" -msgstr "%s ìžë£Œí˜•ì—서 사용할 해쉬함수를 ì°¾ì„ ìˆ˜ 없습니다." +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "백슬래시 표기는 ì¸ìš©ë¶€í˜¸ 표기법으로 사용하세요, 예, E'\\\\'." -#: utils/adt/arrayfuncs.c:5154 +#: scan.l:1556 #, c-format -msgid "data type %s is not an array type" -msgstr "%s ìžë£Œí˜•ì€ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." +msgid "nonstandard use of escape in a string literal" +msgstr "문ìžì—´ ì•ˆì— ë¹„í‘œì¤€ escape 문ìžë¥¼ 사용하고 있습니다" -#: utils/adt/arrayfuncs.c:5209 +#: scan.l:1557 #, c-format -msgid "cannot accumulate null arrays" -msgstr "null ë°°ì—´ì„ ëˆ„ì í•  수 ì—†ìŒ" +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "ì¸ìš©ë¶€í˜¸ í‘œê¸°ë²•ì„ ì‚¬ìš©í•˜ì„¸ìš”, 예, E'\\r\\n'." -#: utils/adt/arrayfuncs.c:5237 +#: snowball/dict_snowball.c:177 #, c-format -msgid "cannot accumulate empty arrays" -msgstr "빈 ë°°ì—´ì„ ëˆ„ì í•  수 ì—†ìŒ" +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "\"%s\" 언어 ë° \"%s\" ì¸ì½”ë”©ì— ì‚¬ìš© 가능한 Snowball stemmerê°€ ì—†ìŒ" -#: utils/adt/arrayfuncs.c:5266 utils/adt/arrayfuncs.c:5272 +#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 #, c-format -msgid "cannot accumulate arrays of different dimensionality" -msgstr "ë°°ì—´ 차수가 서로 틀린 ë°°ì—´ì€ ëˆ„ì í•  수 ì—†ìŒ" +msgid "multiple StopWords parameters" +msgstr "StopWords 매개 변수가 여러 ê°œ 있ìŒ" -#: utils/adt/arrayfuncs.c:5638 utils/adt/arrayfuncs.c:5678 +#: snowball/dict_snowball.c:209 #, c-format -msgid "dimension array or low bound array cannot be null" -msgstr "ì°¨ì› ë°°ì—´ ë˜ëŠ” 하한 ë°°ì—´ì€ NULLì¼ ìˆ˜ ì—†ìŒ" +msgid "multiple Language parameters" +msgstr "여러 ê°œì˜ ì–¸ì–´ 매개 변수가 있ìŒ" -#: utils/adt/arrayfuncs.c:5741 utils/adt/arrayfuncs.c:5767 +#: snowball/dict_snowball.c:216 #, c-format -msgid "Dimension array must be one dimensional." -msgstr "ì°¨ì› ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 Snowball 매개 변수: \"%s\"" -#: utils/adt/arrayfuncs.c:5746 utils/adt/arrayfuncs.c:5772 +#: snowball/dict_snowball.c:224 #, c-format -msgid "dimension values cannot be null" -msgstr "ì°¨ì› ê°’ì€ nullì¼ ìˆ˜ ì—†ìŒ" +msgid "missing Language parameter" +msgstr "Language 매개 변수가 누ë½ë¨" -#: utils/adt/arrayfuncs.c:5778 +#: statistics/dependencies.c:534 #, c-format -msgid "Low bound array has different size than dimensions array." -msgstr "하한 ë°°ì—´ì˜ í¬ê¸°ê°€ ì°¨ì› ë°°ì—´ê³¼ 다릅니다." +msgid "invalid zero-length item array in MVDependencies" +msgstr "" -#: utils/adt/arrayfuncs.c:6024 +#: statistics/dependencies.c:672 statistics/dependencies.c:725 +#: statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 +#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 +#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 +#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 +#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 +#: utils/adt/pseudotypes.c:393 #, c-format -msgid "removing elements from multidimensional arrays is not supported" -msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—서 요소 ì‚­ì œê¸°ëŠ¥ì€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "cannot accept a value of type %s" +msgstr "%s 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/adt/arrayfuncs.c:6301 +#: statistics/extended_stats.c:104 #, c-format -msgid "thresholds must be one-dimensional array" -msgstr "threshold ê°’ì€ 1ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "\"%s.%s\" 통계정보 개체를 계산 í•  수 ì—†ìŒ: ëŒ€ìƒ ë¦´ë ˆì´ì…˜: \"%s.%s\"" -#: utils/adt/arrayfuncs.c:6306 +#: statistics/mvdistinct.c:262 #, c-format -msgid "thresholds array must not contain NULLs" -msgstr "threshold ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" +msgid "invalid ndistinct magic %08x (expected %08x)" +msgstr "" -#: utils/adt/arrayutils.c:209 +#: statistics/mvdistinct.c:267 #, c-format -msgid "typmod array must be type cstring[]" -msgstr "typmod ë°°ì—´ì€ cstring[] 형ì‹ì´ì–´ì•¼ 함" +msgid "invalid ndistinct type %d (expected %d)" +msgstr "ìž˜ëª»ëœ ndistinct 형 %d (예ìƒê°’ %d)" -#: utils/adt/arrayutils.c:214 +#: statistics/mvdistinct.c:272 #, c-format -msgid "typmod array must be one-dimensional" -msgstr "typmod ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 함" +msgid "invalid zero-length item array in MVNDistinct" +msgstr "MVNDistinctì—서 ìž˜ëª»ëœ zero-length 항목 ë°°ì—´" -#: utils/adt/arrayutils.c:219 +#: statistics/mvdistinct.c:281 #, c-format -msgid "typmod array must not contain nulls" -msgstr "typmod ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" +msgid "invalid MVNDistinct size %zd (expected at least %zd)" +msgstr "" -#: utils/adt/ascii.c:75 +#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 #, c-format -msgid "encoding conversion from %s to ASCII not supported" -msgstr "%s ì¸ì½”ë”©ì„ ASCII ì¸ì½”ë”©ìœ¼ë¡œì˜ ë³€í™˜ì€ ì§€ì›í•˜ì§€ 않습니다." +msgid "cannot access temporary tables of other sessions" +msgstr "다른 ì„¸ì…˜ì˜ ìž„ì‹œ í…Œì´ë¸”ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ" -#: utils/adt/bool.c:153 +#: storage/buffer/bufmgr.c:807 #, c-format -msgid "invalid input syntax for type boolean: \"%s\"" -msgstr "boolean ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì— EOF 범위를 넘는 예기치 ì•Šì€ ë°ì´í„°ê°€ 있ìŒ" -#: utils/adt/cash.c:246 +#: storage/buffer/bufmgr.c:809 #, c-format -msgid "invalid input syntax for type money: \"%s\"" -msgstr "money ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "ì´ ë¬¸ì œëŠ” 커ë„ì˜ ë¬¸ì œë¡œ 알려졌습니다. ì‹œìŠ¤í…œì„ ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤." -#: utils/adt/cash.c:607 utils/adt/cash.c:657 utils/adt/cash.c:708 -#: utils/adt/cash.c:757 utils/adt/cash.c:809 utils/adt/cash.c:859 -#: utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 -#: utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:719 -#: utils/adt/int.c:861 utils/adt/int.c:969 utils/adt/int.c:1058 -#: utils/adt/int.c:1097 utils/adt/int.c:1125 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6818 -#: utils/adt/numeric.c:7107 utils/adt/numeric.c:8120 -#: utils/adt/timestamp.c:3499 +#: storage/buffer/bufmgr.c:907 #, c-format -msgid "division by zero" -msgstr "0으로는 나눌수 없습니다." +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì— ìž˜ëª»ëœ íŽ˜ì´ì§€ í—¤ë”ê°€ 있ìŒ, 페ì´ì§€ë¥¼ 삭제하는 중" -#: utils/adt/char.c:169 +#: storage/buffer/bufmgr.c:4013 #, c-format -msgid "\"char\" out of range" -msgstr "\"char\" 범위를 벗어났습니다." +msgid "could not write block %u of %s" +msgstr "%u/%s 블ë¡ì„ 쓸 수 ì—†ìŒ" -#: utils/adt/date.c:67 utils/adt/timestamp.c:94 utils/adt/varbit.c:52 -#: utils/adt/varchar.c:45 +#: storage/buffer/bufmgr.c:4015 #, c-format -msgid "invalid type modifier" -msgstr "ìž˜ëª»ëœ ìžë£Œí˜• 한정ìž" +msgid "Multiple failures --- write error might be permanent." +msgstr "여러 번 실패 --- 쓰기 오류가 ì˜êµ¬ì ì¼ 수 있습니다." -#: utils/adt/date.c:72 +#: storage/buffer/bufmgr.c:4036 storage/buffer/bufmgr.c:4055 #, c-format -msgid "TIME(%d)%s precision must not be negative" -msgstr "TIME(%d)%s ì •ë°€ë„로 ìŒìˆ˜ë¥¼ 사용할 수 없습니다" +msgid "writing block %u of relation %s" +msgstr "%u 블ë¡(해당 릴레ì´ì…˜: %s)ì„ ì“°ëŠ” 중" -#: utils/adt/date.c:78 +#: storage/buffer/bufmgr.c:4358 #, c-format -msgid "TIME(%d)%s precision reduced to maximum allowed, %d" -msgstr "TIME(%d)%s ì •ë°€ë„는 최대값(%d)으로 줄였습니다" +msgid "snapshot too old" +msgstr "" -#: utils/adt/date.c:141 utils/adt/datetime.c:1278 utils/adt/datetime.c:2191 +#: storage/buffer/localbuf.c:199 #, c-format -msgid "date/time value \"current\" is no longer supported" -msgstr "ë‚ ìžì™€ 시간 ìž…ë ¥ì„ ìœ„í•œ \"current\" 는 ë”ì´ìƒ ì§€ì›í•˜ì§€ 않습니다." +msgid "no empty local buffer available" +msgstr "비어 있는 로컬 버í¼ê°€ 없습니다" -#: utils/adt/date.c:167 utils/adt/date.c:175 utils/adt/formatting.c:3529 -#: utils/adt/formatting.c:3538 +#: storage/buffer/localbuf.c:427 #, c-format -msgid "date out of range: \"%s\"" -msgstr "ë‚ ì§œ 범위가 벗어났ìŒ: \"%s\"" +msgid "cannot access temporary tables during a parallel operation" +msgstr "병렬 작업 ì¤‘ì— ìž„ì‹œ í…Œì´ë¸”ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ" -#: utils/adt/date.c:222 utils/adt/date.c:456 utils/adt/date.c:480 -#: utils/adt/xml.c:2027 +#: storage/file/buffile.c:317 #, c-format -msgid "date out of range" -msgstr "날짜가 범위를 벗어남" +msgid "could not open BufFile \"%s\"" +msgstr "\"%s\" BUfFile 파ì¼ì„ ì—´ 수 ì—†ìŒ" -#: utils/adt/date.c:264 utils/adt/timestamp.c:593 +#: storage/file/fd.c:451 storage/file/fd.c:523 storage/file/fd.c:559 #, c-format -msgid "date field value out of range: %d-%02d-%02d" -msgstr "ë‚ ì§œ í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: %d-%02d-%02d" +msgid "could not flush dirty data: %m" +msgstr "dirty ìžë£Œë¥¼ flush í•  수 ì—†ìŒ: %m" -#: utils/adt/date.c:271 utils/adt/date.c:280 utils/adt/timestamp.c:599 +#: storage/file/fd.c:481 #, c-format -msgid "date out of range: %d-%02d-%02d" -msgstr "ë‚ ì§œ 범위가 벗어났ìŒ: %d-%02d-%02d" +msgid "could not determine dirty data size: %m" +msgstr "dirty ìžë£Œ í¬ê¸°ë¥¼ 확ì¸í•  수 ì—†ìŒ: %m" -#: utils/adt/date.c:431 +#: storage/file/fd.c:533 #, c-format -msgid "cannot subtract infinite dates" -msgstr "무한 날짜를 뺄 수 ì—†ìŒ" +msgid "could not munmap() while flushing data: %m" +msgstr "ìžë£Œ flush 작업 ë„중 munmap() 호출 실패: %m" -#: utils/adt/date.c:509 utils/adt/date.c:544 utils/adt/date.c:566 -#: utils/adt/date.c:2629 utils/adt/date.c:2643 +#: storage/file/fd.c:734 #, c-format -msgid "date out of range for timestamp" -msgstr "날짜가 타임스탬프 범위를 벗어남" +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "\"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ë§í¬í•  수 ì—†ìŒ: %m" -#: utils/adt/date.c:1022 utils/adt/date.c:1068 utils/adt/date.c:1678 -#: utils/adt/date.c:1714 utils/adt/date.c:1748 utils/adt/date.c:2592 -#: utils/adt/datetime.c:1759 utils/adt/formatting.c:3404 -#: utils/adt/formatting.c:3436 utils/adt/formatting.c:3504 -#: utils/adt/json.c:1534 utils/adt/json.c:1556 utils/adt/jsonb.c:823 -#: utils/adt/jsonb.c:847 utils/adt/nabstime.c:455 utils/adt/nabstime.c:498 -#: utils/adt/nabstime.c:528 utils/adt/nabstime.c:571 utils/adt/timestamp.c:224 -#: utils/adt/timestamp.c:268 utils/adt/timestamp.c:726 -#: utils/adt/timestamp.c:735 utils/adt/timestamp.c:817 -#: utils/adt/timestamp.c:857 utils/adt/timestamp.c:3074 -#: utils/adt/timestamp.c:3095 utils/adt/timestamp.c:3108 -#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3125 -#: utils/adt/timestamp.c:3180 utils/adt/timestamp.c:3203 -#: utils/adt/timestamp.c:3216 utils/adt/timestamp.c:3227 -#: utils/adt/timestamp.c:3235 utils/adt/timestamp.c:3809 -#: utils/adt/timestamp.c:3938 utils/adt/timestamp.c:3979 -#: utils/adt/timestamp.c:4067 utils/adt/timestamp.c:4113 -#: utils/adt/timestamp.c:4224 utils/adt/timestamp.c:4631 -#: utils/adt/timestamp.c:4747 utils/adt/timestamp.c:4757 -#: utils/adt/timestamp.c:4853 utils/adt/timestamp.c:4972 -#: utils/adt/timestamp.c:4982 utils/adt/timestamp.c:5234 -#: utils/adt/timestamp.c:5248 utils/adt/timestamp.c:5253 -#: utils/adt/timestamp.c:5267 utils/adt/timestamp.c:5316 -#: utils/adt/timestamp.c:5348 utils/adt/timestamp.c:5355 -#: utils/adt/timestamp.c:5381 utils/adt/timestamp.c:5385 -#: utils/adt/timestamp.c:5454 utils/adt/timestamp.c:5458 -#: utils/adt/timestamp.c:5472 utils/adt/timestamp.c:5510 utils/adt/xml.c:2049 -#: utils/adt/xml.c:2056 utils/adt/xml.c:2076 utils/adt/xml.c:2083 +#: storage/file/fd.c:828 #, c-format -msgid "timestamp out of range" -msgstr "타임스탬프 범위를 벗어남" +msgid "getrlimit failed: %m" +msgstr "getrlimit 실패: %m" -#: utils/adt/date.c:1094 +#: storage/file/fd.c:918 #, c-format -msgid "cannot convert reserved abstime value to date" -msgstr "ì˜ˆì•½ëœ abstime ê°’ì„ date로 형변환할 수 없습니다." +msgid "insufficient file descriptors available to start server process" +msgstr "서버 프로세스를 실행하기 위해서 열어야할 파ì¼ë“¤ì„ 못 ì—´ê³  있습니다. 다른 프로그램ì—서 너무 ë§Žì€ íŒŒì¼ì„ ì—´ì–´ ë‘ê³  있습니다. 다른 í”„ë¡œê·¸ëž¨ë“¤ì„ ì¢€ ë‹«ê³  다시 시ë„í•´ 보십시오" -#: utils/adt/date.c:1112 utils/adt/date.c:1118 +#: storage/file/fd.c:919 #, c-format -msgid "abstime out of range for date" -msgstr "abstimeì˜ ë‚ ì§œê°’ì´ ë²”ìœ„ë¥¼ 벗어남" +msgid "System allows %d, we need at least %d." +msgstr "시스템 허용치 %d, 서버 최소 허용치 %d." -#: utils/adt/date.c:1258 utils/adt/date.c:1265 utils/adt/date.c:2082 -#: utils/adt/date.c:2089 +#: storage/file/fd.c:970 storage/file/fd.c:2371 storage/file/fd.c:2473 +#: storage/file/fd.c:2625 #, c-format -msgid "time out of range" -msgstr "시간 범위를 벗어남" +msgid "out of file descriptors: %m; release and retry" +msgstr "ì—´ë ¤ 있는 파ì¼ì´ 너무 많습니다: %m; 다른 í”„ë¡œê·¸ëž¨ë“¤ì„ ì¢€ ë‹«ê³  다시 시ë„í•´ 보십시오" -#: utils/adt/date.c:1326 utils/adt/timestamp.c:618 +#: storage/file/fd.c:1312 #, c-format -msgid "time field value out of range: %d:%02d:%02g" -msgstr "시간 í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: %d:%02d:%02g" +msgid "temporary file: path \"%s\", size %lu" +msgstr "임시 파ì¼: 경로 \"%s\", í¬ê¸° %lu" -#: utils/adt/date.c:1960 utils/adt/date.c:1977 +#: storage/file/fd.c:1444 #, c-format -msgid "\"time\" units \"%s\" not recognized" -msgstr "\"%s\" 는 \"time\" ìžë£Œí˜• 단위가 아닙니다." +msgid "cannot create temporary directory \"%s\": %m" +msgstr "\"%s\" 임시 디렉터리를 만들 수 ì—†ìŒ: %m" -#: utils/adt/date.c:2098 +#: storage/file/fd.c:1451 #, c-format -msgid "time zone displacement out of range" -msgstr "타임 ì¡´ 변위가 범위를 벗어남" +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "\"%s\" 임시 하위 디렉터리를 만들 수 ì—†ìŒ: %m" -#: utils/adt/date.c:2740 utils/adt/date.c:2757 +#: storage/file/fd.c:1644 #, c-format -msgid "\"time with time zone\" units \"%s\" not recognized" -msgstr "\"%s\" 는 \"time with time zone\" ìžë£Œí˜•ì˜ ë‹¨ìœ„ê°€ 아닙니다." +msgid "could not create temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파ì¼ì„ 만들 수 없습니다: %m" -#: utils/adt/date.c:2830 utils/adt/datetime.c:995 utils/adt/datetime.c:1917 -#: utils/adt/datetime.c:4743 utils/adt/timestamp.c:532 -#: utils/adt/timestamp.c:559 utils/adt/timestamp.c:5259 -#: utils/adt/timestamp.c:5464 +#: storage/file/fd.c:1679 #, c-format -msgid "time zone \"%s\" not recognized" -msgstr "\"%s\" ì´ë¦„ì˜ ì‹œê°„ëŒ€ëŠ” 없습니다." +msgid "could not open temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/date.c:2870 utils/adt/timestamp.c:5301 utils/adt/timestamp.c:5495 +#: storage/file/fd.c:1720 #, c-format -msgid "interval time zone \"%s\" must not include months or days" -msgstr "" -"\"%s\" 시간대 간격(interval time zone) 값으로 달(month) ë˜ëŠ” ì¼(day)ì„ í¬í•¨" -"í•  수 없습니다" +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "\"%s\" 임시 파ì¼ì„ 지울 수 ì—†ìŒ: %m" -#: utils/adt/datetime.c:3878 utils/adt/datetime.c:3885 +#: storage/file/fd.c:2002 #, c-format -msgid "date/time field value out of range: \"%s\"" -msgstr "ë‚ ì§œ/시간 í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: \"%s\"" +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "임시 íŒŒì¼ í¬ê¸°ê°€ temp_file_limit (%dkB)를 초과했습니다" -#: utils/adt/datetime.c:3887 +#: storage/file/fd.c:2347 storage/file/fd.c:2406 #, c-format -msgid "Perhaps you need a different \"datestyle\" setting." -msgstr "ë‚ ì§œ 표현 ë°©ì‹(\"datestyle\")ì„ ë‹¤ë¥¸ 것으로 사용하고 있는 듯 합니다." +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "" -#: utils/adt/datetime.c:3892 +#: storage/file/fd.c:2446 #, c-format -msgid "interval field value out of range: \"%s\"" -msgstr "interval í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: \"%s\"" +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "" -#: utils/adt/datetime.c:3898 +#: storage/file/fd.c:2601 #, c-format -msgid "time zone displacement out of range: \"%s\"" -msgstr "표준시간대 범위를 벗어남: \"%s\"" +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "" -#. translator: first %s is inet or cidr -#: utils/adt/datetime.c:3905 utils/adt/float.c:461 utils/adt/float.c:544 -#: utils/adt/float.c:570 utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 -#: utils/adt/geo_ops.c:178 utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 -#: utils/adt/geo_ops.c:265 utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 -#: utils/adt/geo_ops.c:1356 utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3430 -#: utils/adt/geo_ops.c:4563 utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 -#: utils/adt/network.c:58 +#: storage/file/fd.c:2692 #, c-format -msgid "invalid input syntax for type %s: \"%s\"" -msgstr "%s ìžë£Œí˜• 대한 ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %m" -#: utils/adt/datetime.c:4745 +#: storage/file/fd.c:3124 #, c-format -msgid "" -"This time zone name appears in the configuration file for time zone " -"abbreviation \"%s\"." -msgstr "" +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "임시 디렉터리ì—서 예ìƒì¹˜ 못한 íŒŒì¼ ë°œê²¬: \"%s\"" -#: utils/adt/datum.c:86 utils/adt/datum.c:98 +#: storage/file/fd.c:3443 #, c-format -msgid "invalid Datum pointer" -msgstr "ìž˜ëª»ëœ Datum í¬ì¸í„°" +msgid "could not rmdir directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 지울 수 ì—†ìŒ: %m" -#: utils/adt/dbsize.c:110 +#: storage/file/sharedfileset.c:93 #, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "\"%s\" í…Œì´ë¸” 스페ì´ìФ 디렉터리 ì—´ 수 ì—†ìŒ: %m" +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "SharedFileSet 확보 실패, ì´ë¯¸ ì‚­ì œë˜ì—ˆìŒ" -#: utils/adt/dbsize.c:757 utils/adt/dbsize.c:825 +#: storage/ipc/dsm.c:351 #, c-format -msgid "invalid size: \"%s\"" -msgstr "ìž˜ëª»ëœ í¬ê¸°: \"%s\"" +msgid "dynamic shared memory control segment is corrupt" +msgstr "ë™ì  공유 메모리 제어 ì¡°ê°ì´ ì†ìƒë˜ì—ˆìŒ" -#: utils/adt/dbsize.c:826 +#: storage/ipc/dsm.c:398 #, c-format -msgid "Invalid size unit: \"%s\"." -msgstr "ìž˜ëª»ëœ í¬ê¸° 단위: \"%s\"" +msgid "dynamic shared memory is disabled" +msgstr "ë™ì  공유 메모리 ê¸°ëŠ¥ì´ ë¹„í™œì„±í™” ë˜ì–´ìžˆìŒ" -#: utils/adt/dbsize.c:827 +#: storage/ipc/dsm.c:399 #, c-format -msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "" -"ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"bytes\",\"kB\", \"MB\", \"GB\", \"TB\"입니다." +msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +msgstr "dynamic_shared_memory_type ì„¤ì •ê°’ì„ \"none\" 아닌 값으로 지정하세요." -#: utils/adt/domains.c:86 +#: storage/ipc/dsm.c:419 #, c-format -msgid "type %s is not a domain" -msgstr "%s ìžë£Œí˜•ì€ ë„ë©”ì¸ì´ 아닙니다" +msgid "dynamic shared memory control segment is not valid" +msgstr "ë™ì  공유 메모리 제어 ì¡°ê°ì´ 타당하지 않ìŒ" -#: utils/adt/encode.c:55 utils/adt/encode.c:91 +#: storage/ipc/dsm.c:515 #, c-format -msgid "unrecognized encoding: \"%s\"" -msgstr "알 수 없는 ì¸ì½”딩: \"%s\"" +msgid "too many dynamic shared memory segments" +msgstr "너무 ë§Žì€ ë™ì  공유 메모리 ì¡°ê°ì´ 있ìŒ" -#: utils/adt/encode.c:150 +#: storage/ipc/dsm_impl.c:263 storage/ipc/dsm_impl.c:364 +#: storage/ipc/dsm_impl.c:581 storage/ipc/dsm_impl.c:696 +#: storage/ipc/dsm_impl.c:867 storage/ipc/dsm_impl.c:1011 #, c-format -msgid "invalid hexadecimal digit: \"%c\"" -msgstr "ìž˜ëª»ëœ 16진수: \"%c\"" +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ unmap í•  수 ì—†ìŒ: %m" -#: utils/adt/encode.c:178 +#: storage/ipc/dsm_impl.c:273 storage/ipc/dsm_impl.c:591 +#: storage/ipc/dsm_impl.c:706 storage/ipc/dsm_impl.c:877 #, c-format -msgid "invalid hexadecimal data: odd number of digits" -msgstr "ìž˜ëª»ëœ 16진수 ë°ì´í„°: ë°ì´í„°ì˜ 길ì´ê°€ 홀수 입니다." +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ 삭제할 수 ì—†ìŒ: %m" -#: utils/adt/encode.c:295 +#: storage/ipc/dsm_impl.c:294 storage/ipc/dsm_impl.c:777 +#: storage/ipc/dsm_impl.c:891 #, c-format -msgid "unexpected \"=\" while decoding base64 sequence" -msgstr "base64 ìžë£Œë¥¼ 디코딩 하는 중 예ìƒì¹˜ 못한 \"=\" ë¬¸ìž ë°œê²¬" +msgid "could not open shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/encode.c:307 +#: storage/ipc/dsm_impl.c:318 storage/ipc/dsm_impl.c:607 +#: storage/ipc/dsm_impl.c:822 storage/ipc/dsm_impl.c:915 #, c-format -msgid "invalid symbol \"%c\" while decoding base64 sequence" -msgstr "base64 ìžë£Œë¥¼ 디코딩 하는 중 ìž˜ëª»ëœ \"%c\" 기호 발견" +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê° íŒŒì¼ì˜ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %m" -#: utils/adt/encode.c:327 +#: storage/ipc/dsm_impl.c:338 storage/ipc/dsm_impl.c:934 +#: storage/ipc/dsm_impl.c:984 #, c-format -msgid "invalid base64 end sequence" -msgstr "base64 마침 ì¡°í•©ì´ ìž˜ëª»ë˜ì—ˆìŒ" +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê° íŒŒì¼ì„ %zu ë°”ì´íŠ¸ë¡œ í¬ê¸° ì¡°ì ˆ í•  수 ì—†ìŒ: %m" -#: utils/adt/encode.c:328 +#: storage/ipc/dsm_impl.c:388 storage/ipc/dsm_impl.c:628 +#: storage/ipc/dsm_impl.c:798 storage/ipc/dsm_impl.c:1035 #, c-format -msgid "Input data is missing padding, is truncated, or is otherwise corrupted." -msgstr "ìž…ë ¥ê°’ì— ì—¬ë°± ì²˜ë¦¬ê°’ì´ ë¹ ì¡Œê±°ë‚˜, ìžë£Œê°€ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "could not map shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ map í•  수 ì—†ìŒ: %m" -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/varlena.c:297 -#: utils/adt/varlena.c:338 +#: storage/ipc/dsm_impl.c:563 #, c-format -msgid "invalid input syntax for type bytea" -msgstr "bytea ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥" +msgid "could not get shared memory segment: %m" +msgstr "공유 메모리 ì¡°ê°ì„ 가져올 수 ì—†ìŒ: %m" -#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 -#: utils/adt/enum.c:123 +#: storage/ipc/dsm_impl.c:762 #, c-format -msgid "invalid input value for enum %s: \"%s\"" -msgstr "%s ì—´ê±°í˜•ì˜ ìž…ë ¥ ê°’ì´ ìž˜ëª»ë¨: \"%s\"" +msgid "could not create shared memory segment \"%s\": %m" +msgstr "\"%s\" 공유 메모리 ì¡°ê°ì„ 만들 수 ì—†ìŒ: %m" -#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:198 +#: storage/ipc/dsm_impl.c:1077 storage/ipc/dsm_impl.c:1125 #, c-format -msgid "invalid internal value for enum: %u" -msgstr "ì—´ê±°í˜•ì˜ ë‚´ë¶€ ê°’ì´ ìž˜ëª»ë¨: %u" +msgid "could not duplicate handle for \"%s\": %m" +msgstr "\"%s\" ìš© 헨들러를 ì´ì¤‘í™” í•  수 ì—†ìŒ: %m" -#: utils/adt/enum.c:356 utils/adt/enum.c:385 utils/adt/enum.c:425 -#: utils/adt/enum.c:445 +#: storage/ipc/latch.c:829 #, c-format -msgid "could not determine actual enum type" -msgstr "실제 ì—´ê±°í˜•ì˜ ìžë£Œí˜•ì„ í™•ì¸í•  수 ì—†ìŒ" +msgid "epoll_ctl() failed: %m" +msgstr "epoll_ctl() 실패: %m" -#: utils/adt/enum.c:364 utils/adt/enum.c:393 +#: storage/ipc/latch.c:1060 #, c-format -msgid "enum %s contains no values" -msgstr "\"%s\" 열거형 ìžë£Œì— ê°’ì´ ì—†ìŒ" +msgid "epoll_wait() failed: %m" +msgstr "epoll_wait() 실패: %m" -#: utils/adt/float.c:58 +#: storage/ipc/latch.c:1182 #, c-format -msgid "value out of range: overflow" -msgstr "ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: 오버플로" +msgid "poll() failed: %m" +msgstr "poll() 실패: %m" -#: utils/adt/float.c:63 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:903 +#: storage/lmgr/lock.c:941 storage/lmgr/lock.c:2728 storage/lmgr/lock.c:4053 +#: storage/lmgr/lock.c:4118 storage/lmgr/lock.c:4410 +#: storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 +#: storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 +#: utils/hash/dynahash.c:1065 #, c-format -msgid "value out of range: underflow" -msgstr "ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: ì–¸ë”플로" +msgid "out of shared memory" +msgstr "공유 메모리 부족" -#: utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 +#: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 #, c-format -msgid "invalid input syntax for type real: \"%s\"" -msgstr "real ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "out of shared memory (%zu bytes requested)" +msgstr "공유 메모리가 부족함 (%zu ë°”ì´íŠ¸ê°€ 필요함)" -#: utils/adt/float.c:312 +#: storage/ipc/shmem.c:421 #, c-format -msgid "\"%s\" is out of range for type real" -msgstr "\"%s\"는 real ìžë£Œí˜•ì˜ ë²”ìœ„ë¥¼ 벗어납니다." +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "\"%s\" ìžë£Œ 구조체용 ShmemIndex í•­ëª©ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: utils/adt/float.c:537 +#: storage/ipc/shmem.c:436 #, c-format -msgid "\"%s\" is out of range for type double precision" -msgstr "\"%s\"는 double precision ìžë£Œí˜•ì˜ ë²”ìœ„ë¥¼ 벗어납니다." +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "\"%s\" ìžë£Œ 구조체용 ShmemIndex 항목 í¬ê¸°ê°€ 잘못ë¨: 기대값 %zu, 현재값 %zu" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:349 -#: utils/adt/int.c:775 utils/adt/int.c:804 utils/adt/int.c:825 -#: utils/adt/int.c:845 utils/adt/int.c:879 utils/adt/int.c:1174 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3000 utils/adt/numeric.c:3009 +#: storage/ipc/shmem.c:453 #, c-format -msgid "smallint out of range" -msgstr "smallintì˜ ë²”ìœ„ë¥¼ 벗어났습니다." +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "\"%s\" ìžë£Œ 구조체용 공유 메모리가 부족함 (%zu ë°”ì´íŠ¸ê°€ 필요함)" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7540 +#: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 #, c-format -msgid "cannot take square root of a negative number" -msgstr "ìŒìˆ˜ì˜ ì œê³±ê·¼ì„ êµ¬í•  수 없습니다." +msgid "requested shared memory size overflows size_t" +msgstr "지정한 공유 메모리 사ì´ì¦ˆê°€ size_t í¬ê¸°ë¥¼ 초과했습니다" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2803 +#: storage/ipc/standby.c:558 tcop/postgres.c:3033 #, c-format -msgid "zero raised to a negative power is undefined" -msgstr "0ì˜ ìŒìˆ˜ ê±°ë“­ì œê³±ì´ ì •ì˜ë˜ì–´ 있지 않ìŒ" +msgid "canceling statement due to conflict with recovery" +msgstr "복구 작업 중 ì¶©ëŒì´ ë°œìƒí•´ ìž‘ì—…ì„ ì¤‘ì§€í•©ë‹ˆë‹¤." -#: utils/adt/float.c:1476 utils/adt/numeric.c:2809 +#: storage/ipc/standby.c:559 tcop/postgres.c:2306 #, c-format -msgid "a negative number raised to a non-integer power yields a complex result" -msgstr "ìŒìˆ˜ì˜ 비정수 ê±°ë“­ì œê³±ì„ ê³„ì‚°í•˜ë©´ 복잡한 결과가 ìƒì„±ë¨" +msgid "User transaction caused buffer deadlock with recovery." +msgstr "복구 작업 중 ì‚¬ìš©ìž íŠ¸ëžœìž­ì…˜ì´ ë²„í¼ ë°ë“œë½ì„ 만들었습니다." -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7806 +#: storage/large_object/inv_api.c:190 #, c-format -msgid "cannot take logarithm of zero" -msgstr "0ì˜ ëŒ€ìˆ˜ë¥¼ 구할 수 없습니다." +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7810 +#: storage/large_object/inv_api.c:271 #, c-format -msgid "cannot take logarithm of a negative number" -msgstr "ìŒìˆ˜ì˜ 대수를 구할 수 없습니다." +msgid "invalid flags for opening a large object: %d" +msgstr "대형 개체를 열기 위한 플래그가 잘못 ë¨: %d" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 -#: utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 -#: utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 -#: utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: storage/large_object/inv_api.c:461 #, c-format -msgid "input is out of range" -msgstr "ìž…ë ¥ê°’ì´ ë²”ìœ„ë¥¼ 벗어났습니다." +msgid "invalid whence setting: %d" +msgstr "" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1443 +#: storage/large_object/inv_api.c:633 #, c-format -msgid "count must be greater than zero" -msgstr "카운트 ê°’ì€ 0 보다 커야합니다" +msgid "invalid large object write request size: %d" +msgstr "유효하지 ì•Šì€ ëŒ€í˜• ê°œì²´ì˜ ì“°ê¸° ìš”ì²­ëœ í¬ê¸°: %d" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1450 +#: storage/lmgr/deadlock.c:1109 #, c-format -msgid "operand, lower bound, and upper bound cannot be NaN" -msgstr "피연산ìž, 하한 ë° ìƒí•œì€ NaNì¼ ìˆ˜ ì—†ìŒ" +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "%d 프로세스가 %s ìƒíƒœë¡œ 지연ë˜ê³  있ìŒ(해당 작업: %s); %d í”„ë¡œì„¸ìŠ¤ì— ì˜í•´ 블ë¡í‚¹ë˜ì—ˆìŒ" -#: utils/adt/float.c:3543 +#: storage/lmgr/deadlock.c:1128 #, c-format -msgid "lower and upper bounds must be finite" -msgstr "하한 ë° ìƒí•œì€ 유한한 ê°’ì´ì–´ì•¼ 함" +msgid "Process %d: %s" +msgstr "프로세스 %d: %s" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1463 +#: storage/lmgr/deadlock.c:1137 #, c-format -msgid "lower bound cannot equal upper bound" -msgstr "í•˜í•œê°’ì€ ìƒí•œê°’ê³¼ ê°™ì„ ìˆ˜ 없습니다" +msgid "deadlock detected" +msgstr "deadlock ë°œìƒí–ˆìŒ" -#: utils/adt/formatting.c:485 +#: storage/lmgr/deadlock.c:1140 #, c-format -msgid "invalid format specification for an interval value" -msgstr "간격 ê°’ì— ëŒ€í•œ í˜•ì‹ ì§€ì •ì´ ìž˜ëª»ë¨" +msgid "See server log for query details." +msgstr "쿼리 ìƒì„¸ 정보는 서버 로그를 참조하십시오." -#: utils/adt/formatting.c:486 +#: storage/lmgr/lmgr.c:767 #, c-format -msgid "Intervals are not tied to specific calendar dates." -msgstr "ê°„ê²©ì´ íŠ¹ì • 달력 ë‚ ì§œì— ì—°ê²°ë˜ì–´ 있지 않습니다." +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ê°±ì‹ í•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1058 +#: storage/lmgr/lmgr.c:770 #, c-format -msgid "\"EEEE\" must be the last pattern used" -msgstr "" +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ì‚­ì œí•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1066 +#: storage/lmgr/lmgr.c:773 #, c-format -msgid "\"9\" must be ahead of \"PR\"" -msgstr "???\"9\"는 \"PR\" 앞ì´ì–´ì•¼ 한다." +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u íŠœí”Œì„ \"%s\" 릴레ì´ì…˜ì—서 잠그는 ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1082 +#: storage/lmgr/lmgr.c:776 #, c-format -msgid "\"0\" must be ahead of \"PR\"" -msgstr "???\"0\"ì€ \"PR\" 앞ì´ì–´ì•¼ 한다." +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "%u,%u ì—…ë°ì´íŠ¸ëœ ë²„ì „ 튜플(해당 릴레ì´ì…˜ \"%s\")ì„ ìž ê·¸ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1109 +#: storage/lmgr/lmgr.c:779 #, c-format -msgid "multiple decimal points" -msgstr "???ì—¬ëŸ¬ê°œì˜ ì†Œìˆ«ì " +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플 ì¸ë±ìФ(해당 릴레ì´ì…˜ \"%s\")를 삽입하는 ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1113 utils/adt/formatting.c:1196 +#: storage/lmgr/lmgr.c:782 #, c-format -msgid "cannot use \"V\" and decimal point together" -msgstr "\"V\" 와 소숫ì ì„ 함께 쓸 수 없습니다." +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레ì´ì…˜: \"%s\")ì˜ ê³ ìœ ì„±ì„ ê²€ì‚¬í•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1125 +#: storage/lmgr/lmgr.c:785 #, c-format -msgid "cannot use \"S\" twice" -msgstr "\"S\"를 ë‘ ë²ˆ 사용할 수 ì—†ìŒ" +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u ê°±ì‹ ëœ íŠœí”Œ(해당 릴레ì´ì…˜: \"%s\")ì„ ìž¬í™•ì¸í•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1129 +#: storage/lmgr/lmgr.c:788 #, c-format -msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" -msgstr "\"S\" 와 \"PL\"/\"MI\"/\"SG\"/\"PR\" 를 함께 쓸 수 없습니다." +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "%u,%u 튜플(해당 릴레ì´ì…˜: \"%s\")ì˜ ì œì™¸ 제약 ì¡°ê±´ì„ ê²€ì‚¬í•˜ëŠ” ì¤‘ì— ë°œìƒ" -#: utils/adt/formatting.c:1149 +#: storage/lmgr/lmgr.c:1008 #, c-format -msgid "cannot use \"S\" and \"MI\" together" -msgstr "\"S\" 와 \"MI\" 를 함께 쓸 수 없습니다." +msgid "relation %u of database %u" +msgstr "릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" -#: utils/adt/formatting.c:1159 +#: storage/lmgr/lmgr.c:1014 #, c-format -msgid "cannot use \"S\" and \"PL\" together" -msgstr "\"S\" 와 \"PL\" 를 함께 쓸 수 없습니다." +msgid "extension of relation %u of database %u" +msgstr "%u 관계(%u ë°ì´í„°ë² ì´ìФ) 확장" -#: utils/adt/formatting.c:1169 +#: storage/lmgr/lmgr.c:1020 #, c-format -msgid "cannot use \"S\" and \"SG\" together" -msgstr "\"S\" 와 \"SG\" 를 함께 쓸 수 없습니다." +msgid "page %u of relation %u of database %u" +msgstr "페ì´ì§€ %u, 릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" -#: utils/adt/formatting.c:1178 +#: storage/lmgr/lmgr.c:1027 #, c-format -msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" -msgstr "\"PR\" 와 \"S\"/\"PL\"/\"MI\"/\"SG\" 를 함께 쓸 수 없습니다." +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "튜플 (%u,%u), 릴레ì´ì…˜ %u, ë°ì´í„°ë² ì´ìФ %u" -#: utils/adt/formatting.c:1204 +#: storage/lmgr/lmgr.c:1035 #, c-format -msgid "cannot use \"EEEE\" twice" -msgstr "\"EEEE\"를 ë‘ ë²ˆ 사용할 수 ì—†ìŒ" +msgid "transaction %u" +msgstr "트랜잭션 %u" -#: utils/adt/formatting.c:1210 +#: storage/lmgr/lmgr.c:1040 #, c-format -msgid "\"EEEE\" is incompatible with other formats" -msgstr "\"EEEE\"는 다른 í¬ë§·ê³¼ 호환하지 않습니다" +msgid "virtual transaction %d/%u" +msgstr "ê°€ìƒ íŠ¸ëžœìž­ì…˜ %d/%u" -#: utils/adt/formatting.c:1211 +#: storage/lmgr/lmgr.c:1046 #, c-format -msgid "" -"\"EEEE\" may only be used together with digit and decimal point patterns." -msgstr "" +msgid "speculative token %u of transaction %u" +msgstr "%u 위험한 토í°, ëŒ€ìƒ íŠ¸ëžœìž­ì…˜ %u" -#: utils/adt/formatting.c:1411 +#: storage/lmgr/lmgr.c:1052 #, c-format -msgid "\"%s\" is not a number" -msgstr "\"%s\"는 숫ìžê°€ 아닙니다." +msgid "object %u of class %u of database %u" +msgstr "개체 %u, í´ëž˜ìФ %u, ë°ì´í„°ë² ì´ìФ %u" -#: utils/adt/formatting.c:1512 utils/adt/formatting.c:1564 +#: storage/lmgr/lmgr.c:1060 #, c-format -msgid "could not determine which collation to use for lower() function" -msgstr "lower() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "user lock [%u,%u,%u]" +msgstr "user lock [%u,%u,%u]" -#: utils/adt/formatting.c:1632 utils/adt/formatting.c:1684 +#: storage/lmgr/lmgr.c:1067 #, c-format -msgid "could not determine which collation to use for upper() function" -msgstr "upper() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "advisory lock [%u,%u,%u,%u]" -#: utils/adt/formatting.c:1753 utils/adt/formatting.c:1817 +#: storage/lmgr/lmgr.c:1075 #, c-format -msgid "could not determine which collation to use for initcap() function" -msgstr "initcap() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "unrecognized locktag type %d" +msgstr "알 수 없는 locktag 형태 %d" -#: utils/adt/formatting.c:2114 +#: storage/lmgr/lock.c:738 #, c-format -msgid "invalid combination of date conventions" -msgstr "ë‚ ì§œ ë³€í™˜ì„ ìœ„í•œ ìž˜ëª»ëœ ì¡°í•©" +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "" -#: utils/adt/formatting.c:2115 +#: storage/lmgr/lock.c:740 #, c-format -msgid "" -"Do not mix Gregorian and ISO week date conventions in a formatting template." +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "" -"í˜•ì‹ í…œí”Œë¦¿ì— ê·¸ë ˆê³ ë¦¬ì˜¤ë ¥ê³¼ ISO week date ë³€í™˜ì„ í•¨ê»˜ 사용하지 마십시오." -#: utils/adt/formatting.c:2132 +#: storage/lmgr/lock.c:904 storage/lmgr/lock.c:942 storage/lmgr/lock.c:2729 +#: storage/lmgr/lock.c:4054 storage/lmgr/lock.c:4119 storage/lmgr/lock.c:4411 #, c-format -msgid "conflicting values for \"%s\" field in formatting string" -msgstr "í˜•ì‹ ë¬¸ìžì—´ì—서 \"%s\" í•„ë“œì˜ ê°’ì´ ì¶©ëŒí•¨" +msgid "You might need to increase max_locks_per_transaction." +msgstr "max_locks_per_transactionì„ ëŠ˜ë ¤ì•¼ í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: utils/adt/formatting.c:2134 +#: storage/lmgr/lock.c:3170 storage/lmgr/lock.c:3286 #, c-format -msgid "This value contradicts a previous setting for the same field type." -msgstr "ì´ ê°’ì€ ë™ì¼í•œ 필드 형ì‹ì˜ ì´ì „ 설정과 모순ë©ë‹ˆë‹¤." +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "" -#: utils/adt/formatting.c:2195 +#: storage/lmgr/predicate.c:682 #, c-format -msgid "source string too short for \"%s\" formatting field" -msgstr "소스 문ìžì—´ì´ 너무 짧아서 \"%s\" í˜•ì‹ í•„ë“œì— ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "" -#: utils/adt/formatting.c:2197 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format -msgid "Field requires %d characters, but only %d remain." -msgstr "í•„ë“œì— %dìžê°€ í•„ìš”í•œë° %dìžë§Œ 남았습니다." +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "" -#: utils/adt/formatting.c:2200 utils/adt/formatting.c:2214 +#: storage/lmgr/predicate.c:710 #, c-format -msgid "" -"If your source string is not fixed-width, try using the \"FM\" modifier." -msgstr "소스 문ìžì—´ì´ ê³ ì • 너비가 아닌 경우 \"FM\" 한정ìžë¥¼ 사용해 보십시오." +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "" -#: utils/adt/formatting.c:2210 utils/adt/formatting.c:2223 -#: utils/adt/formatting.c:2353 +#: storage/lmgr/predicate.c:1515 #, c-format -msgid "invalid value \"%s\" for \"%s\"" -msgstr "\"%s\" ê°’ì€ \"%s\"ì— ìœ íš¨í•˜ì§€ 않ìŒ" +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "" -#: utils/adt/formatting.c:2212 +#: storage/lmgr/predicate.c:1604 #, c-format -msgid "Field requires %d characters, but only %d could be parsed." -msgstr "í•„ë“œì— %dìžê°€ í•„ìš”í•œë° %dìžë§Œ 구문 ë¶„ì„í•  수 있습니다." +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "" -#: utils/adt/formatting.c:2225 +#: storage/lmgr/predicate.c:1605 #, c-format -msgid "Value must be an integer." -msgstr "ê°’ì€ ì •ìˆ˜ì—¬ì•¼ 합니다." +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "" -#: utils/adt/formatting.c:2230 +#: storage/lmgr/predicate.c:1645 #, c-format -msgid "value for \"%s\" in source string is out of range" -msgstr "소스 문ìžì—´ì˜ \"%s\" ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "" -#: utils/adt/formatting.c:2232 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 +#: utils/time/snapmgr.c:627 #, c-format -msgid "Value must be in the range %d to %d." -msgstr "ê°’ì€ %dì—서 %d 사ì´ì˜ ë²”ìœ„ì— ìžˆì–´ì•¼ 합니다." +msgid "could not import the requested snapshot" +msgstr "" -#: utils/adt/formatting.c:2355 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The given value did not match any of the allowed values for this field." -msgstr "ì§€ì •ëœ ê°’ì´ ì´ í•„ë“œì— í—ˆìš©ë˜ëŠ” ê°’ê³¼ ì¼ì¹˜í•˜ì§€ 않습니다." +msgid "The source process with PID %d is not running anymore." +msgstr "%d PID 소스 프로세스는 ë”ì´ìƒ 실행 중ì´ì§€ 않습니다." -#: utils/adt/formatting.c:2550 utils/adt/formatting.c:2570 -#: utils/adt/formatting.c:2590 utils/adt/formatting.c:2610 -#: utils/adt/formatting.c:2629 utils/adt/formatting.c:2648 -#: utils/adt/formatting.c:2672 utils/adt/formatting.c:2690 -#: utils/adt/formatting.c:2708 utils/adt/formatting.c:2726 -#: utils/adt/formatting.c:2743 utils/adt/formatting.c:2760 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 +#: storage/lmgr/predicate.c:3763 #, c-format -msgid "localized string format value too long" -msgstr "" +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "max_pred_locks_per_transaction ê°’ì„ ëŠ˜ë ¤ì•¼ í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: utils/adt/formatting.c:3047 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 +#: storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 +#: storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 +#: storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 +#: storage/lmgr/predicate.c:4721 #, c-format -msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" -msgstr "\"TZ\"/\"tz\"\"OF\" í˜•ì‹ íŒ¨í„´ì€ to_dateì—서 ì§€ì›ë˜ì§€ 않ìŒ" +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "트랜잭션간 ì½ê¸°/쓰기 ì˜ì¡´ì„± ë•Œë¬¸ì— serialize ì ‘ê·¼ì„ í•  수 ì—†ìŒ" -#: utils/adt/formatting.c:3156 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 +#: storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 +#: storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 +#: storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 +#: storage/lmgr/predicate.c:4723 #, c-format -msgid "invalid input string for \"Y,YYY\"" -msgstr "\"Y,YYY\"ì— ëŒ€í•œ ìž…ë ¥ 문ìžì—´ì´ 잘못ë¨" +msgid "The transaction might succeed if retried." +msgstr "재시ë„하면 ê·¸ íŠ¸ëžœìž­ì…˜ì´ ì„±ê³µí•  것입니다." -#: utils/adt/formatting.c:3668 +#: storage/lmgr/proc.c:1311 #, c-format -msgid "hour \"%d\" is invalid for the 12-hour clock" -msgstr "시간 \"%d\"ì€(는) 12ì‹œê°„ì œì— ìœ íš¨í•˜ì§€ 않ìŒ" +msgid "Process %d waits for %s on %s." +msgstr "%d 프로세스가 대기중, 잠금종류: %s, ë‚´ìš©: %s" -#: utils/adt/formatting.c:3670 +#: storage/lmgr/proc.c:1322 #, c-format -msgid "Use the 24-hour clock, or give an hour between 1 and 12." -msgstr "24시간제를 사용하거나 1ì—서 12 사ì´ì˜ ì‹œê°„ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤." +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "%d PID autovacuum 블럭킹하기 위해 취소 신호를 보냅니다" -#: utils/adt/formatting.c:3765 +#: storage/lmgr/proc.c:1340 utils/adt/misc.c:270 #, c-format -msgid "cannot calculate day of year without year information" -msgstr "ì—°ë„ ì •ë³´ ì—†ì´ ëª‡ë²ˆì§¸ ë‚ (day of year) ì¸ì§€ 계산할 수 없습니다." +msgid "could not send signal to process %d: %m" +msgstr "%d 프로세스로 시스템신호(signal)를 보낼 수 없습니다: %m" -#: utils/adt/formatting.c:4614 +#: storage/lmgr/proc.c:1442 #, c-format -msgid "\"EEEE\" not supported for input" -msgstr "\"EEEE\" ìž…ë ¥ ì–‘ì‹ì€ ì§€ì›ë˜ì§€ 않습니다." +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "%d PID 프로세스는 %s(%s)ì— ëŒ€í•´ êµì°© ìƒíƒœê°€ ë°œìƒí•˜ì§€ 않ë„ë¡ %ld.%03dms í›„ì— ëŒ€ê¸°ì—´ 순서를 다시 조정함" -#: utils/adt/formatting.c:4626 +#: storage/lmgr/proc.c:1457 #, c-format -msgid "\"RN\" not supported for input" -msgstr "\"RN\" ìž…ë ¥ ì–‘ì‹ì€ ì§€ì›ë˜ì§€ 않습니다." +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스ì—서 %s(%s) 대기중 %ld.%03dms í›„ì— êµì°© ìƒíƒœë¥¼ ê°ì§€í•¨" -#: utils/adt/genfile.c:62 +#: storage/lmgr/proc.c:1466 #, c-format -msgid "reference to parent directory (\"..\") not allowed" -msgstr "ìƒìœ„ 디렉터리(\"..\") 참조는 허용ë˜ì§€ 않ìŒ" +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스ì—서 여전히 %s(%s) ìž‘ì—…ì„ ê¸°ë‹¤ë¦¬ê³  있ìŒ(%ld.%03dms 후)" -#: utils/adt/genfile.c:73 +#: storage/lmgr/proc.c:1473 #, c-format -msgid "absolute path not allowed" -msgstr "절대 경로는 허용하지 않ìŒ" +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "%d PID 프로세스가 %s(%s) ìž‘ì—…ì„ ìœ„í•´ 잠금 ì·¨ë“함(%ld.%03dms 후)" -#: utils/adt/genfile.c:78 +#: storage/lmgr/proc.c:1489 #, c-format -msgid "path must be in or below the current directory" -msgstr "경로는 현재 디렉토리와 ê·¸ 하위 디렉터리여야 합니다." +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "프로세스 %dì—서 %s(%s)ì„(를) ì·¨ë“하지 못함(%ld.%03dms 후)" -#: utils/adt/genfile.c:125 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: storage/page/bufpage.c:151 #, c-format -msgid "requested length too large" -msgstr "ìš”ì²­ëœ ê¸¸ì´ê°€ 너무 ê¹ë‹ˆë‹¤" +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "페ì´ì§€ 검사 실패, ê³„ì‚°ëœ ì²´í¬ì„¬ì€ %u, ê¸°ëŒ€ê°’ì€ %u" -#: utils/adt/genfile.c:142 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 +#: storage/page/bufpage.c:744 storage/page/bufpage.c:877 +#: storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format -msgid "could not seek in file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %m" +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "ì†ìƒëœ 페ì´ì§€ 위치: 하위값 = %u, ìƒìœ„ê°’ = %u, 특수값 = %u" -#: utils/adt/genfile.c:200 utils/adt/genfile.c:241 +#: storage/page/bufpage.c:529 #, c-format -msgid "must be superuser to read files" -msgstr "파ì¼ì„ ì½ìœ¼ë ¤ë©´ 슈í¼ìœ ì ¸ì—¬ì•¼í•¨" +msgid "corrupted item pointer: %u" +msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: %u" -#: utils/adt/genfile.c:318 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format -msgid "must be superuser to get file information" -msgstr "íŒŒì¼ ì •ë³´ë¥¼ 보려면 superuser여야함" +msgid "corrupted item lengths: total %u, available space %u" +msgstr "ì†ìƒëœ ì•„ì´í…œ 길ì´: ì „ì²´ %u, 사용가능한 공간 %u" -#: utils/adt/genfile.c:404 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 +#: storage/page/bufpage.c:1099 #, c-format -msgid "must be superuser to get directory listings" -msgstr "디렉터리 목ë¡ì„ 보려면 superuser여야함" +msgid "corrupted item pointer: offset = %u, size = %u" +msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: 오프셋 = %u, í¬ê¸° = %u" -#: utils/adt/geo_ops.c:940 +#: storage/page/bufpage.c:901 #, c-format -msgid "invalid line specification: A and B cannot both be zero" -msgstr "ì„  ì •ì˜ê°€ 잘못ë¨: A와 B 둘다 0ì¼ ìˆ˜ëŠ” ì—†ìŒ" +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "ì†ìƒëœ ì•„ì´í…œ 위치: 오프셋 = %u, í¬ê¸° = %u" -#: utils/adt/geo_ops.c:948 +#: storage/smgr/md.c:448 storage/smgr/md.c:974 #, c-format -msgid "invalid line specification: must be two distinct points" -msgstr "ì„  ì •ì˜ê°€ 잘못ëœ: ë‘ ì ì€ 서로 다른 위치여야 함" +msgid "could not truncate file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì„ 비울 수 ì—†ìŒ: %m" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 -#: utils/adt/geo_ops.c:5181 +#: storage/smgr/md.c:515 #, c-format -msgid "too many points requested" -msgstr "너무 ë§Žì€ ì ë“¤ì´ 요청ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "\"%s\" 파ì¼ì„ %uê°œ 블ë¡ì„ 초과하여 확장할 수 ì—†ìŒ" -#: utils/adt/geo_ops.c:1404 +#: storage/smgr/md.c:537 storage/smgr/md.c:754 storage/smgr/md.c:830 #, c-format -msgid "invalid number of points in external \"path\" value" -msgstr "???\"path\" ì˜ ê°’ì— ìž˜ëª»ëœ ê°¯ìˆ˜ì˜ point들" +msgid "could not seek to block %u in file \"%s\": %m" +msgstr "%u 블ë¡ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ(해당 파ì¼: \"%s\"): %m" -#: utils/adt/geo_ops.c:2555 +#: storage/smgr/md.c:545 #, c-format -msgid "function \"dist_lb\" not implemented" -msgstr "\"dist_lb\" 함수는 구현ë˜ì§€ 않았습니다." +msgid "could not extend file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì„ 확장할 수 ì—†ìŒ: %m" -#: utils/adt/geo_ops.c:3015 +#: storage/smgr/md.c:547 storage/smgr/md.c:554 storage/smgr/md.c:857 #, c-format -msgid "function \"close_sl\" not implemented" -msgstr "\"close_sl\" 함수는 구현ë˜ì§€ 않았습니다." +msgid "Check free disk space." +msgstr "ë””ìŠ¤í¬ ì—¬ìœ  ê³µê°„ì„ í™•ì¸í•´ 주십시오." -#: utils/adt/geo_ops.c:3117 +#: storage/smgr/md.c:551 #, c-format -msgid "function \"close_lb\" not implemented" -msgstr "\"close_lb\" 함수는 구현ë˜ì§€ 않았습니다." +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "\"%s\" 파ì¼ì„ 확장할 수 ì—†ìŒ: %d/%dë°”ì´íŠ¸ë§Œ %u 블ë¡ì— ì¼ìŒ" -#: utils/adt/geo_ops.c:3406 +#: storage/smgr/md.c:772 #, c-format -msgid "cannot create bounding box for empty polygon" -msgstr "???í´ë¦¬ê³¤ ì—†ì´ ë‹«ížŒ ìƒìžë¥¼ ìƒì„±í•  수 없습니다." +msgid "could not read block %u in file \"%s\": %m" +msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì—서 ì½ì„ 수 ì—†ìŒ: %m" -#: utils/adt/geo_ops.c:3487 +#: storage/smgr/md.c:788 #, c-format -msgid "invalid number of points in external \"polygon\" value" -msgstr "???\"polygon\" ê°’ì— ìž˜ëª»ëœ ê°¯ìˆ˜ì˜ point들" +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì—서 ì½ì„ 수 ì—†ìŒ: %d / %d ë°”ì´íŠ¸ë§Œ ì½ìŒ" -#: utils/adt/geo_ops.c:4012 +#: storage/smgr/md.c:848 #, c-format -msgid "function \"poly_distance\" not implemented" -msgstr "\"poly_distance\" 함수는 구현ë˜ì§€ 않았습니다." +msgid "could not write block %u in file \"%s\": %m" +msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì— 쓸 수 ì—†ìŒ: %m" -#: utils/adt/geo_ops.c:4365 +#: storage/smgr/md.c:853 #, c-format -msgid "function \"path_center\" not implemented" -msgstr "\"path_center\" 함수는 구현ë˜ì§€ 않았습니다." +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "%u ë¸”ëŸ­ì„ \"%s\" 파ì¼ì— 쓸 수 ì—†ìŒ: %d / %d ë°”ì´íŠ¸ë§Œ 씀" -#: utils/adt/geo_ops.c:4382 +#: storage/smgr/md.c:945 #, c-format -msgid "open path cannot be converted to polygon" -msgstr "닫히지 ì•Šì€ path 는 í´ë¦¬ê³¤ìœ¼ë¡œ 변환할 수 없습니다." +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "\"%s\" 파ì¼ì„ %u 블럭으로 비울 수 ì—†ìŒ: 현재 %u 블럭 ë¿ ìž„" -#: utils/adt/geo_ops.c:4631 +#: storage/smgr/md.c:1000 #, c-format -msgid "invalid radius in external \"circle\" value" -msgstr "ë¶€ì ì ˆí•œ \"circle\" ê°’ì˜ ë°˜ì§€ë¦„" +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "\"%s\" 파ì¼ì„ %u 블럭으로 정리할 수 ì—†ìŒ: %m" -#: utils/adt/geo_ops.c:5167 +#: storage/smgr/md.c:1282 #, c-format -msgid "cannot convert circle with radius zero to polygon" -msgstr "ë°˜ì§€ë¦„ì´ 0ì¸ ì›ì€ í´ë¦¬ê³¤ìœ¼ë¡œ 변환할 수 없습니다." +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "\"%s\" íŒŒì¼ fsync 실패, 재시ë„함: %m" -#: utils/adt/geo_ops.c:5172 +#: storage/smgr/md.c:1445 #, c-format -msgid "must request at least 2 points" -msgstr "ì ì–´ë„ 2ê°œì˜ pointë“¤ì´ í•„ìš”í•©ë‹ˆë‹¤." +msgid "could not forward fsync request because request queue is full" +msgstr "요청 íê°€ ê°€ë“ì°¨ forward fsync ìš”ì²­ì„ ì²˜ë¦¬í•  수 ì—†ìŒ" -#: utils/adt/geo_ops.c:5216 +#: storage/smgr/md.c:1951 #, c-format -msgid "cannot convert empty polygon to circle" -msgstr "비어있는 í´ë¦¬ê³¤ì„ ì›ìœ¼ë¡œ 변환할 수 없습니다." +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "\"%s\" 파ì¼ì„ 열기 실패(ëŒ€ìƒ ë¸”ë¡: %u): ì´ì „ ì¡°ê°ì€ %u 블럭 ë¿ìž„" -#: utils/adt/int.c:162 +#: storage/smgr/md.c:1965 #, c-format -msgid "int2vector has too many elements" -msgstr "int2vector 는 너무 ë§Žì€ ìš”ì†Œë¥¼ 가지고 있습니다." +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "\"%s\" 파ì¼ì„ 열기 실패(ëŒ€ìƒ ë¸”ë¡: %u): %m" -#: utils/adt/int.c:237 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format -msgid "invalid int2vector data" -msgstr "ìž˜ëª»ëœ int2vector ìžë£Œ" +msgid "invalid argument size %d in function call message" +msgstr "함수 호출 메시지 ì•ˆì— ìžˆëŠ” ìž˜ëª»ëœ %d ì¸ìž í¬ê¸°" -#: utils/adt/int.c:243 utils/adt/oid.c:212 utils/adt/oid.c:293 +#: tcop/fastpath.c:307 #, c-format -msgid "oidvector has too many elements" -msgstr "oidvectorì— ë„ˆë¬´ ë§Žì€ ìš”ì†Œê°€ 있습니다" +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "fastpath 함수 호출: \"%s\" (OID %u)" -#: utils/adt/int.c:1362 utils/adt/int8.c:1460 utils/adt/numeric.c:1351 -#: utils/adt/timestamp.c:5561 utils/adt/timestamp.c:5642 +#: tcop/fastpath.c:389 tcop/postgres.c:1195 tcop/postgres.c:1459 +#: tcop/postgres.c:1841 tcop/postgres.c:2062 #, c-format -msgid "step size cannot equal zero" -msgstr "단계 í¬ê¸°ëŠ” 0ì¼ ìˆ˜ ì—†ìŒ" +msgid "duration: %s ms" +msgstr "실행시간: %s ms" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:103 +#: tcop/fastpath.c:393 #, c-format -msgid "invalid input syntax for integer: \"%s\"" -msgstr "ìž˜ëª»ëœ integer ìžë£Œí˜• ìž…ë ¥ 구문: \"%s\"" - -#: utils/adt/int8.c:114 -#, c-format -msgid "value \"%s\" is out of range for type bigint" -msgstr "입력한 \"%s\" ê°’ì€ bigint ìžë£Œí˜• 범위를 초과했습니다" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:2955 -#: utils/adt/varbit.c:1655 +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "작업시간: %s ms fastpath 함수 호출: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format -msgid "bigint out of range" -msgstr "bigintì˜ ë²”ìœ„ë¥¼ 벗어났습니다." +msgid "function call message contains %d arguments but function requires %d" +msgstr "함수 호출 메시지는 %d ì¸ìžë¥¼ 사용하지만, 함수는 %d ì¸ìžê°€ 필요합니다" -#: utils/adt/int8.c:1417 +#: tcop/fastpath.c:437 #, c-format -msgid "OID out of range" -msgstr "OIDì˜ ë²”ìœ„ë¥¼ 벗어났습니다." +msgid "function call message contains %d argument formats but %d arguments" +msgstr "함수 호출 메시지는 %d ì¸ìžë¥¼ 사용하지만, 함수는 %d ì¸ìžê°€ 필요합니다" -#: utils/adt/json.c:785 utils/adt/json.c:825 utils/adt/json.c:840 -#: utils/adt/json.c:851 utils/adt/json.c:861 utils/adt/json.c:912 -#: utils/adt/json.c:943 utils/adt/json.c:961 utils/adt/json.c:973 -#: utils/adt/json.c:985 utils/adt/json.c:1130 utils/adt/json.c:1144 -#: utils/adt/json.c:1155 utils/adt/json.c:1163 utils/adt/json.c:1171 -#: utils/adt/json.c:1179 utils/adt/json.c:1187 utils/adt/json.c:1195 -#: utils/adt/json.c:1203 utils/adt/json.c:1211 utils/adt/json.c:1241 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format -msgid "invalid input syntax for type json" -msgstr "json ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥" +msgid "incorrect binary data format in function argument %d" +msgstr "함수 ì¸ìž %d ì•ˆì— ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ ìžë£Œ í˜•ì‹ ë°œê²¬ë¨" -#: utils/adt/json.c:786 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format -msgid "Character with value 0x%02x must be escaped." -msgstr "" +msgid "unexpected EOF on client connection" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²°ì—서 예ìƒì¹˜ ì•Šì€ EOF 발견ë¨" -#: utils/adt/json.c:826 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4385 #, c-format -msgid "\"\\u\" must be followed by four hexadecimal digits." -msgstr "\"\\u\" í‘œê¸°ë²•ì€ ë’¤ì— 4ê°œì˜ 16진수가 와야합니다." +msgid "invalid frontend message type %d" +msgstr "ìž˜ëª»ëœ frontend 메시지 형태 %d" -#: utils/adt/json.c:841 +#: tcop/postgres.c:950 #, c-format -msgid "Unicode high surrogate must not follow a high surrogate." -msgstr "" +msgid "statement: %s" +msgstr "명령 구문: %s" -#: utils/adt/json.c:852 utils/adt/json.c:862 utils/adt/json.c:913 -#: utils/adt/json.c:974 utils/adt/json.c:986 +#: tcop/postgres.c:1200 #, c-format -msgid "Unicode low surrogate must follow a high surrogate." -msgstr "" +msgid "duration: %s ms statement: %s" +msgstr "실행시간: %s ms 명령 구문: %s" -#: utils/adt/json.c:877 utils/adt/json.c:900 +#: tcop/postgres.c:1250 #, c-format -msgid "unsupported Unicode escape sequence" -msgstr "ì§€ì›í•˜ì§€ 않는 유니코드 ì´ìŠ¤ì¼€ì´í”„ ì¡°í•©" +msgid "parse %s: %s" +msgstr "구문 %s: %s" -#: utils/adt/json.c:878 +#: tcop/postgres.c:1307 #, c-format -msgid "\\u0000 cannot be converted to text." -msgstr "\\u0000 ê°’ì€ text 형으로 변환할 수 ì—†ìŒ." +msgid "cannot insert multiple commands into a prepared statement" +msgstr "ì¤€ë¹„ëœ ëª…ë ¹ 구문ì—는 다중 ëª…ë ¹ì„ ì‚½ìž…í•  수 없습니다" -#: utils/adt/json.c:901 +#: tcop/postgres.c:1464 #, c-format -msgid "" -"Unicode escape values cannot be used for code point values above 007F when " -"the server encoding is not UTF8." -msgstr "" -"서버 ì¸ì½”ë”©ì´ UTF8ì´ ì•„ë‹Œ 경우 007F보다 í° ì½”ë“œ ì§€ì  ê°’ì—는 유니코드 ì´ìŠ¤ì¼€ì´" -"프 ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "duration: %s ms parse %s: %s" +msgstr "실행시간: %s ms %s 구문분ì„: %s" -#: utils/adt/json.c:944 utils/adt/json.c:962 +#: tcop/postgres.c:1509 #, c-format -msgid "Escape sequence \"\\%s\" is invalid." -msgstr "ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ ì¡°í•©: \"\\%s\"" +msgid "bind %s to %s" +msgstr "ë°”ì¸ë“œ: %s -> %s" -#: utils/adt/json.c:1131 +#: tcop/postgres.c:1528 tcop/postgres.c:2354 #, c-format -msgid "The input string ended unexpectedly." -msgstr "ìž…ë ¥ 문ìžì—´ì´ 예ìƒì¹˜ 않게 ë났ìŒ." +msgid "unnamed prepared statement does not exist" +msgstr "ì´ë¦„없는 ì¤€ë¹„ëœ ëª…ë ¹ 구문(unnamed prepared statement) ì—†ìŒ" -#: utils/adt/json.c:1145 +#: tcop/postgres.c:1571 #, c-format -msgid "Expected end of input, but found \"%s\"." -msgstr "ìž…ë ¥ ìžë£Œì˜ ëì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ì´ ë” ìžˆìŒ." +msgid "bind message has %d parameter formats but %d parameters" +msgstr "ë°”ì¸ë“œ 메시지는 %d 매개 변수 형태지만, %d 매개 변수여야함" -#: utils/adt/json.c:1156 +#: tcop/postgres.c:1577 #, c-format -msgid "Expected JSON value, but found \"%s\"." -msgstr "JSON ê°’ì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ìž„" +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "ë°”ì¸ë“œ 메시지는 %dê°œì˜ ë§¤ê°œ 변수를 ì§€ì›í•˜ì§€ë§Œ, \"%s\" ì¤€ë¹„ëœ ëª…ë ¹ 구문(prepared statement)ì—서는%d ê°œì˜ ë§¤ê°œ 변수가 필요합니다" -#: utils/adt/json.c:1164 utils/adt/json.c:1212 +#: tcop/postgres.c:1748 #, c-format -msgid "Expected string, but found \"%s\"." -msgstr "문ìžì—´ ê°’ì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ìž„" +msgid "incorrect binary data format in bind parameter %d" +msgstr "ë°”ì¸ë“œ 매개 변수 %d ì•ˆì— ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ ìžë£Œ 형태가 있ìŒ" -#: utils/adt/json.c:1172 +#: tcop/postgres.c:1846 #, c-format -msgid "Expected array element or \"]\", but found \"%s\"." -msgstr "\"]\" ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "실행시간: %s ms %s%s%s ì ‘ì†: %s" -#: utils/adt/json.c:1180 +#: tcop/postgres.c:1894 tcop/postgres.c:2438 #, c-format -msgid "Expected \",\" or \"]\", but found \"%s\"." -msgstr "\",\" ë˜ëŠ” \"]\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" +msgid "portal \"%s\" does not exist" +msgstr "\"%s\" portal ì—†ìŒ" -#: utils/adt/json.c:1188 +#: tcop/postgres.c:1979 #, c-format -msgid "Expected string or \"}\", but found \"%s\"." -msgstr "\"}\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" -#: utils/adt/json.c:1196 +#: tcop/postgres.c:1981 tcop/postgres.c:2070 +msgid "execute fetch from" +msgstr "ìžë£Œë½‘기" + +#: tcop/postgres.c:1982 tcop/postgres.c:2071 +msgid "execute" +msgstr "쿼리실행" + +#: tcop/postgres.c:2067 #, c-format -msgid "Expected \":\", but found \"%s\"." -msgstr "\":\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "수행시간: %s ms %s %s%s%s: %s" -#: utils/adt/json.c:1204 +#: tcop/postgres.c:2193 #, c-format -msgid "Expected \",\" or \"}\", but found \"%s\"." -msgstr "\",\" ë˜ëŠ” \"}\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" +msgid "prepare: %s" +msgstr "prepare: %s" -#: utils/adt/json.c:1242 +#: tcop/postgres.c:2259 #, c-format -msgid "Token \"%s\" is invalid." -msgstr "ìž˜ëª»ëœ í† í°: \"%s\"" +msgid "parameters: %s" +msgstr "매개 변수: %s" -#: utils/adt/json.c:1314 +#: tcop/postgres.c:2278 #, c-format -msgid "JSON data, line %d: %s%s%s" -msgstr "JSON ìžë£Œ, %d 번째 줄: %s%s%s" +msgid "abort reason: recovery conflict" +msgstr "중지 ì´ìœ : 복구 ì¶©ëŒ" -#: utils/adt/json.c:1469 utils/adt/jsonb.c:724 +#: tcop/postgres.c:2294 #, c-format -msgid "key value must be scalar, not array, composite, or json" +msgid "User was holding shared buffer pin for too long." msgstr "" -"키 ê°’ì€ ìŠ¤ì¹¼ë¼ í˜•ì´ì–´ì•¼ 함. ë°°ì—´, 복합 ìžë£Œí˜•, json í˜•ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/adt/json.c:2006 +#: tcop/postgres.c:2297 #, c-format -msgid "could not determine data type for argument 1" -msgstr "첫번째 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•ì„ ì•Œìˆ˜ê°€ 없습니다." +msgid "User was holding a relation lock for too long." +msgstr "" -#: utils/adt/json.c:2016 +#: tcop/postgres.c:2300 #, c-format -msgid "could not determine data type for argument 2" -msgstr "ë‘번째 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•ì„ ì•Œìˆ˜ê°€ 없습니다." +msgid "User was or might have been using tablespace that must be dropped." +msgstr "" -#: utils/adt/json.c:2040 utils/adt/jsonb.c:1781 +#: tcop/postgres.c:2303 #, c-format -msgid "field name must not be null" -msgstr "필드 ì´ë¦„ì´ null ì´ë©´ 안ë©ë‹ˆë‹¤" +msgid "User query might have needed to see row versions that must be removed." +msgstr "" -#: utils/adt/json.c:2117 +#: tcop/postgres.c:2309 #, c-format -msgid "argument list must have even number of elements" -msgstr "ì¸ìž 목ë¡ì€ ìš”ì†Œìˆ˜ì˜ ì§ìˆ˜ê°œì—¬ì•¼ 합니다." +msgid "User was connected to a database that must be dropped." +msgstr "ì‚­ì œ ë˜ì–´ì ¸ì•¼í•  ë°ì´í„°ë² ì´ìФ ì‚¬ìš©ìž ì ‘ì†í•´ 있습니다." -#: utils/adt/json.c:2118 +#: tcop/postgres.c:2634 #, c-format -msgid "" -"The arguments of json_build_object() must consist of alternating keys and " -"values." -msgstr "" -"json_build_object() í•¨ìˆ˜ì˜ ì¸ìžë“¤ì€ ê°ê° key, value ìŒìœ¼ë¡œ 있어야 합니다." +msgid "terminating connection because of crash of another server process" +msgstr "다른 서버 프로세스가 ì†ìƒì„ ìž…ì–´ 현재 ì—°ê²°ì„ ì¤‘ì§€í•©ë‹ˆë‹¤" -#: utils/adt/json.c:2142 utils/adt/json.c:2163 utils/adt/json.c:2222 +#: tcop/postgres.c:2635 #, c-format -msgid "could not determine data type for argument %d" -msgstr "%d번째 ì¸ìžì˜ ìžë£Œí˜•ì„ ì•Œìˆ˜ê°€ 없습니다." +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "postmaster ì—서 현재 ì´ì„œë²„ 프로세스ì—게 현재 íŠ¸ëžœìž­ì…˜ì„ ì·¨ì†Œí•˜ê³ , í´ë¼ì´ì–¸íŠ¸ì™€ì˜ ì—°ê²°ì„ ëŠìœ¼ë¼ëŠ” ëª…ë ¹ì„ ë³´ëƒˆìŠµë‹ˆë‹¤. 왜ëƒí•˜ë©´, 다른 서버 프로세스가 비정ìƒì ìœ¼ë¡œ 중지ë˜ì–´ 공유 메모리가 ì†ìƒë˜ì—ˆì„ ê°€ëŠ¥ì„±ì´ ìžˆê¸° 때문입니다" -#: utils/adt/json.c:2148 +#: tcop/postgres.c:2639 tcop/postgres.c:2963 #, c-format -msgid "argument %d cannot be null" -msgstr "%d 번째 ì¸ìžëŠ” null ì´ë©´ 안ë©ë‹ˆë‹¤" +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "잠시 ë’¤ì— ë‹¤ì‹œ ì—°ê²° 해서 ìž‘ì—…ì„ ê³„ì† í•˜ì‹­ì‹œì˜¤" -#: utils/adt/json.c:2149 +#: tcop/postgres.c:2721 #, c-format -msgid "Object keys should be text." -msgstr "ê°ì²´ 키는 문ìžì—´ì´ì–´ì•¼ 합니다." +msgid "floating-point exception" +msgstr "ë¶€ë™ì†Œìˆ˜ì  예외발ìƒ" -#: utils/adt/json.c:2284 utils/adt/jsonb.c:1363 +#: tcop/postgres.c:2722 #, c-format -msgid "array must have two columns" -msgstr "ë°°ì—´ì€ ë‘ê°œì˜ ì¹¼ëŸ¼ì´ì–´ì•¼ 함" +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "ìž˜ëª»ëœ ë¶€ë™ì†Œìˆ˜ì  ìž‘ì—…ì´ ê°ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤. ì´ê²ƒì€ ì•„ë§ˆë„ ê²°ê³¼ê°’ 범위초과나 0으로 나누는 작업과 ê°™ì€ ìž˜ëª»ëœ ì—°ì‚° ë•Œë¬¸ì— ë°œìƒí•œ 것 같습니다" -#: utils/adt/json.c:2308 utils/adt/json.c:2392 utils/adt/jsonb.c:1387 -#: utils/adt/jsonb.c:1482 +#: tcop/postgres.c:2893 #, c-format -msgid "null value not allowed for object key" -msgstr "ê°ì²´ 키 값으로 null ì„ í—ˆìš©í•˜ì§€ 않ìŒ" +msgid "canceling authentication due to timeout" +msgstr "시간 초과로 ì¸ì¦ ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: utils/adt/json.c:2381 utils/adt/jsonb.c:1471 +#: tcop/postgres.c:2897 #, c-format -msgid "mismatched array dimensions" -msgstr "ë°°ì—´ 차수가 안맞ìŒ" +msgid "terminating autovacuum process due to administrator command" +msgstr "ê´€ë¦¬ìž ëª…ë ¹ìœ¼ë¡œ ì¸í•´ ìžë™ 청소 프로세스를 종료하는 중" -#: utils/adt/jsonb.c:257 +#: tcop/postgres.c:2901 #, c-format -msgid "string too long to represent as jsonb string" -msgstr "jsonb 문ìžì—´ë¡œ 길ì´ë¥¼ 초과함" +msgid "terminating logical replication worker due to administrator command" +msgstr "ê´€ë¦¬ìž ìš”ì²­ì— ì˜í•´ì„œ 논리 복제 작업ìžë¥¼ ë냅니다" -#: utils/adt/jsonb.c:258 +#: tcop/postgres.c:2905 #, c-format -msgid "" -"Due to an implementation restriction, jsonb strings cannot exceed %d bytes." -msgstr "êµ¬í˜„ìƒ ì œí•œìœ¼ë¡œ jsonb 문ìžì—´ì€ %d ë°”ì´íŠ¸ë¥¼ ë„˜ì„ ìˆ˜ 없습니다." +msgid "logical replication launcher shutting down" +msgstr "논리 복제 관리ìžë¥¼ 중지하고 있습니다" -#: utils/adt/jsonb.c:1182 +#: tcop/postgres.c:2918 tcop/postgres.c:2928 tcop/postgres.c:2961 #, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "ìž˜ëª»ëœ ì¸ìž 번호: ê°ì²´ëŠ” key - value ìŒìœ¼ë¡œ 구성ë˜ì–´ì•¼ 합니다" +msgid "terminating connection due to conflict with recovery" +msgstr "복구 작업 중 ì¶©ëŒë¡œ ì—°ê²°ì„ ì¢…ë£Œí•©ë‹ˆë‹¤." -#: utils/adt/jsonb.c:1195 +#: tcop/postgres.c:2934 #, c-format -msgid "argument %d: key must not be null" -msgstr "%d 번째 ì¸ìž: 키 ê°’ì€ nullì´ë©´ 안ë©ë‹ˆë‹¤." +msgid "terminating connection due to administrator command" +msgstr "ê´€ë¦¬ìž ìš”ì²­ì— ì˜í•´ì„œ ì—°ê²°ì„ ë냅니다" -#: utils/adt/jsonb.c:1214 utils/adt/jsonb.c:1237 utils/adt/jsonb.c:1297 +#: tcop/postgres.c:2944 #, c-format -msgid "argument %d: could not determine data type" -msgstr "%d 번째 ì¸ìž: ìžë£Œí˜•ì„ íŒŒì•…í•  수 ì—†ìŒ" +msgid "connection to client lost" +msgstr "서버로부터 ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤." -#: utils/adt/jsonb.c:1834 +#: tcop/postgres.c:3010 #, c-format -msgid "object keys must be strings" -msgstr "ê°ì²´ 키는 문ìžì—´ì´ì–´ì•¼ 합니다" +msgid "canceling statement due to lock timeout" +msgstr "잠금 대기 시간 초과로 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: utils/adt/jsonb_util.c:656 +#: tcop/postgres.c:3017 #, c-format -msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" -msgstr "jsonb ê°ì²´ ìŒì˜ 개수가 최대치를 초과함 (%zu)" +msgid "canceling statement due to statement timeout" +msgstr "명령실행시간 초과로 ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: utils/adt/jsonb_util.c:697 +#: tcop/postgres.c:3024 #, c-format -msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" -msgstr "jsonb ë°°ì—´ 요소 개수가 최대치를 초과함 (%zu)" +msgid "canceling autovacuum task" +msgstr "ìžë™ 청소 ìž‘ì—…ì„ ì·¨ì†Œí•˜ëŠ” 중" -#: utils/adt/jsonb_util.c:1525 utils/adt/jsonb_util.c:1545 +#: tcop/postgres.c:3047 #, c-format -msgid "total size of jsonb array elements exceeds the maximum of %u bytes" -msgstr "jsonb ë°°ì—´ 요소 ì´ í¬ê¸°ê°€ 최대치를 초과함 (%u ë°”ì´íЏ)" +msgid "canceling statement due to user request" +msgstr "ì‚¬ìš©ìž ìš”ì²­ì— ì˜í•´ ìž‘ì—…ì„ ì·¨ì†Œí•©ë‹ˆë‹¤." -#: utils/adt/jsonb_util.c:1606 utils/adt/jsonb_util.c:1641 -#: utils/adt/jsonb_util.c:1661 +#: tcop/postgres.c:3057 #, c-format -msgid "total size of jsonb object elements exceeds the maximum of %u bytes" -msgstr "jsonb ê°ì²´ ìš”ì†Œë“¤ì˜ ì´ í¬ê¸°ê°€ 최대치를 초과함 (%u ë°”ì´íЏ)" +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "idle-in-transaction 시간 초과로 ì—°ê²°ì„ ë냅니다" -#: utils/adt/jsonfuncs.c:305 utils/adt/jsonfuncs.c:470 -#: utils/adt/jsonfuncs.c:2057 utils/adt/jsonfuncs.c:2498 -#: utils/adt/jsonfuncs.c:3004 +#: tcop/postgres.c:3171 #, c-format -msgid "cannot call %s on a scalar" -msgstr "스칼ë¼í˜•ì—서는 %s 호출 í•  수 ì—†ìŒ" +msgid "stack depth limit exceeded" +msgstr "ìŠ¤íƒ ê¹Šì´ë¥¼ 초과했습니다" -#: utils/adt/jsonfuncs.c:310 utils/adt/jsonfuncs.c:457 -#: utils/adt/jsonfuncs.c:2487 +#: tcop/postgres.c:3172 #, c-format -msgid "cannot call %s on an array" -msgstr "배열형ì—서는 %s 호출 í•  수 ì—†ìŒ" +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "먼저 OSì—서 ì§€ì›í•˜ëŠ” ìŠ¤íƒ depth ìµœëŒ€ê°’ì„ í™•ì¸í•œ ë’¤, 허용범위 안ì—서 \"max_stack_depth\" (현재값: %dkB) 매개 변수 ê°’ì˜ ì„¤ì •ì¹˜ë¥¼ ì¦ê°€ì‹œí‚¤ì„¸ìš”." -#: utils/adt/jsonfuncs.c:1373 utils/adt/jsonfuncs.c:1408 +#: tcop/postgres.c:3235 #, c-format -msgid "cannot get array length of a scalar" -msgstr "스칼ë¼í˜•ì˜ ë°°ì—´ 길ì´ë¥¼ 구할 수 ì—†ìŒ" +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\" ê°’ì€ %ldkB를 초과할 수 없습니다" -#: utils/adt/jsonfuncs.c:1377 utils/adt/jsonfuncs.c:1396 +#: tcop/postgres.c:3237 #, c-format -msgid "cannot get array length of a non-array" -msgstr "비배열형 ìžë£Œì˜ ë°°ì—´ 길ì´ë¥¼ 구할 수 ì—†ìŒ" +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "OSì˜ \"ulimit -s\" 명령과 ê°™ì€ ê²ƒìœ¼ë¡œ ìŠ¤íƒ ê¹Šì´ë¥¼ 늘려주십시오." -#: utils/adt/jsonfuncs.c:1473 +#: tcop/postgres.c:3597 #, c-format -msgid "cannot call %s on a non-object" -msgstr "비ê°ì²´í˜•ì—서 %s 호출 í•  수 ì—†ìŒ" +msgid "invalid command-line argument for server process: %s" +msgstr "서버 í”„ë¡œì„¸ìŠ¤ì˜ ëª…ë ¹í–‰ ì¸ìžê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤: %s" -#: utils/adt/jsonfuncs.c:1491 utils/adt/jsonfuncs.c:2170 -#: utils/adt/jsonfuncs.c:2707 +#: tcop/postgres.c:3598 tcop/postgres.c:3604 #, c-format -msgid "" -"function returning record called in context that cannot accept type record" -msgstr "반환 ìžë£Œí˜•ì´ recordì¸ë° 함수가 ê·¸ ìžë£Œí˜•으로 반환하지 않ìŒ" +msgid "Try \"%s --help\" for more information." +msgstr "ìžì„¸í•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보세요." -#: utils/adt/jsonfuncs.c:1730 +#: tcop/postgres.c:3602 #, c-format -msgid "cannot deconstruct an array as an object" -msgstr "" +msgid "%s: invalid command-line argument: %s" +msgstr "%s: ìž˜ëª»ëœ ëª…ë ¹í–‰ ì¸ìž: %s" -#: utils/adt/jsonfuncs.c:1742 +#: tcop/postgres.c:3664 #, c-format -msgid "cannot deconstruct a scalar" -msgstr "스칼ë¼í˜•으로 재구축할 수 ì—†ìŒ" +msgid "%s: no database nor user name specified" +msgstr "%s: ë°ì´í„°ë² ì´ìŠ¤ì™€ 사용ìžë¥¼ 지정하지 않았습니다" -#: utils/adt/jsonfuncs.c:1788 +#: tcop/postgres.c:4293 #, c-format -msgid "cannot extract elements from a scalar" -msgstr "스칼ë¼í˜•ì—서 요소를 추출할 수 ì—†ìŒ" +msgid "invalid CLOSE message subtype %d" +msgstr "ìž˜ëª»ëœ CLOSE 메시지 서브타입 %d" -#: utils/adt/jsonfuncs.c:1792 +#: tcop/postgres.c:4328 #, c-format -msgid "cannot extract elements from an object" -msgstr "ê°ì²´í˜•ì—서 요소를 추출할 수 ì—†ìŒ" +msgid "invalid DESCRIBE message subtype %d" +msgstr "ìž˜ëª»ëœ DESCRIBE 메시지 서브타입 %d" -#: utils/adt/jsonfuncs.c:2044 utils/adt/jsonfuncs.c:2803 +#: tcop/postgres.c:4406 #, c-format -msgid "cannot call %s on a non-array" -msgstr "비배열형ì—서 %s 호출 í•  수 ì—†ìŒ" +msgid "fastpath function calls not supported in a replication connection" +msgstr "복제 ì—°ê²°ì—서는 fastpath 함수 í˜¸ì¶œì„ ì§€ì›í•˜ì§€ 않습니다" -#: utils/adt/jsonfuncs.c:2131 utils/adt/jsonfuncs.c:2683 +#: tcop/postgres.c:4410 #, c-format -msgid "first argument of %s must be a row type" -msgstr "%sì˜ ì²«ë²ˆì§¸ ì¸ìžëŠ” row 형ì´ì–´ì•¼ 합니다" +msgid "extended query protocol not supported in a replication connection" +msgstr "" -#: utils/adt/jsonfuncs.c:2172 +#: tcop/postgres.c:4587 #, c-format -msgid "" -"Try calling the function in the FROM clause using a column definition list." -msgstr "함수를 호출 í•  때 FROM ì ˆì—서 칼럼 ì •ì˜ ëª©ë¡ë„ 함께 지정해야 합니다." +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "연결종료: 세션 시간: %d:%02d:%02d.%03d 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s 호스트=%s%s%s" -#: utils/adt/jsonfuncs.c:2819 utils/adt/jsonfuncs.c:2986 +#: tcop/pquery.c:645 #, c-format -msgid "argument of %s must be an array of objects" -msgstr "%sì˜ ì¸ìžëŠ” ê°ì²´ì˜ ë°°ì—´ì´ì–´ì•¼ 합니다" +msgid "bind message has %d result formats but query has %d columns" +msgstr "ë°”ì¸ë“œ 메시지는 %d ê²°ê³¼ í¬ë©§ì„ 가지고 있고, 쿼리는 %d ì¹¼ëŸ¼ì„ ê°€ì§€ê³  있습니다" -#: utils/adt/jsonfuncs.c:2843 +#: tcop/pquery.c:952 #, c-format -msgid "cannot call %s on an object" -msgstr "ê°ì²´ì—서 %s 호출할 수 ì—†ìŒ" +msgid "cursor can only scan forward" +msgstr "ì´ ì»¤ì„œëŠ” 앞으로 ì´ë™ 전용입니다" -#: utils/adt/jsonfuncs.c:3410 utils/adt/jsonfuncs.c:3463 +#: tcop/pquery.c:953 #, c-format -msgid "cannot delete from scalar" -msgstr "스칼ë¼í˜•ì—서 ì‚­ì œ í•  수 ì—†ìŒ" +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "뒤로 ì´ë™ 가능한 커서를 만드려면 SCROLL ì˜µì…˜ì„ ì¶”ê°€í•´ì„œ 커서를 만드세요." -#: utils/adt/jsonfuncs.c:3468 +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:245 #, c-format -msgid "cannot delete from object using integer index" -msgstr "ì¸ë±ìФ 번호를 사용해서 ê°ì²´ì—서 ì‚­ì œ í•  수 ì—†ìŒ" +msgid "cannot execute %s in a read-only transaction" +msgstr "ì½ê¸° ì „ìš© 트랜잭션ì—서는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." -#: utils/adt/jsonfuncs.c:3534 utils/adt/jsonfuncs.c:3626 +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:263 #, c-format -msgid "cannot set path in scalar" -msgstr "스칼ë¼í˜•ì—는 path 를 지정할 수 ì—†ìŒ" +msgid "cannot execute %s during a parallel operation" +msgstr "병렬 처리 작업ì—서는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." -#: utils/adt/jsonfuncs.c:3579 +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:282 #, c-format -msgid "cannot delete path in scalar" -msgstr "스칼ë¼í˜•ì—서 path를 지울 수 ì—†ìŒ" +msgid "cannot execute %s during recovery" +msgstr "복구 작업 중ì—는 %s ëª…ë ¹ì„ ì‹¤í–‰í•  수 없습니다." -#: utils/adt/jsonfuncs.c:3749 +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:300 #, c-format -msgid "invalid concatenation of jsonb objects" -msgstr "jsonb ê°ì²´ë“¤ì˜ ìž˜ëª»ëœ ê²°í•©" +msgid "cannot execute %s within security-restricted operation" +msgstr "보안 제한 작업 ë‚´ì—서 %sì„(를) 실행할 수 ì—†ìŒ" -#: utils/adt/jsonfuncs.c:3783 +#: tcop/utility.c:757 #, c-format -msgid "path element at position %d is null" -msgstr "%d ìœ„ì¹˜ì˜ path 요소는 null 입니다." +msgid "must be superuser to do CHECKPOINT" +msgstr "CHECKPOINT ëª…ë ¹ì€ ìŠˆí¼ìœ ì €ë§Œ 사용할 수 있습니다" -#: utils/adt/jsonfuncs.c:3869 +#: tcop/utility.c:1338 #, c-format -msgid "cannot replace existing key" -msgstr "ì´ë¯¸ 있는 키로는 대체할 수 ì—†ìŒ" +msgid "cannot create index on partitioned table \"%s\"" +msgstr "\"%s\" íŒŒí‹°ì…˜ëœ í…Œì´ë¸” 대ìƒìœ¼ë¡œ ì¸ë±ìŠ¤ë¥¼ 만들 수 ì—†ìŒ" -#: utils/adt/jsonfuncs.c:3870 +#: tcop/utility.c:1340 #, c-format -msgid "Try using the function jsonb_set to replace key value." -msgstr "키 ê°’ì„ ë³€ê²½í•˜ë ¤ë©´, jsonb_set 함수를 사용하세요." +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "\"%s\" í…Œì´ë¸”ì€ í•˜ìœ„ í…Œì´ë¸”로 외부 í…Œì´ë¸”ì„ ì‚¬ìš©í•¨." -#: utils/adt/jsonfuncs.c:3952 +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format -msgid "path element at position %d is not an integer: \"%s\"" -msgstr "%d 번째 ìœ„ì¹˜ì˜ path 요소는 정수가 아님: \"%s\"" +msgid "multiple DictFile parameters" +msgstr "DictFile 매개 변수가 여러 ê°œ 있ìŒ" -#: utils/adt/levenshtein.c:133 +#: tsearch/dict_ispell.c:63 #, c-format -msgid "levenshtein argument exceeds maximum length of %d characters" -msgstr "levenshtein ì¸ìžê°’으로 ê·¸ 길ì´ê°€ %d 문ìžì˜ 최대 길ì´ë¥¼ 초과했ìŒ" +msgid "multiple AffFile parameters" +msgstr "AffFile 매개 변수가 여러 ê°œ 있ìŒ" -#: utils/adt/like.c:212 utils/adt/selfuncs.c:5333 +#: tsearch/dict_ispell.c:82 #, c-format -msgid "could not determine which collation to use for ILIKE" -msgstr "ILIKE ì—°ì‚°ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 Ispell 매개 변수: \"%s\"" -#: utils/adt/like_match.c:107 utils/adt/like_match.c:167 +#: tsearch/dict_ispell.c:96 #, c-format -msgid "LIKE pattern must not end with escape character" -msgstr "LIKE íŒ¨í„´ì€ ì´ìŠ¤ì¼€ì´í”„ 문ìžë¡œ ë나지 않아야 함" +msgid "missing AffFile parameter" +msgstr "AffFile 매개 변수가 누ë½ë¨" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:648 #, c-format -msgid "invalid escape string" -msgstr "ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ 문ìžì—´" +msgid "missing DictFile parameter" +msgstr "DictFile 매개 변수가 누ë½ë¨" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: tsearch/dict_simple.c:58 #, c-format -msgid "Escape string must be empty or one character." -msgstr "ì´ìŠ¤ì¼€ì´í”„ 문ìžì—´ì€ 비어있거나 í•œê°œì˜ ë¬¸ìžì—¬ì•¼ 합니다." +msgid "multiple Accept parameters" +msgstr "Accept 매개 변수가 여러 ê°œ 있ìŒ" -#: utils/adt/lockfuncs.c:545 +#: tsearch/dict_simple.c:66 #, c-format -msgid "cannot use advisory locks during a parallel operation" -msgstr "병렬 작업 중ì—는 ìžë¬¸ ìžê¸ˆì„ 사용할 없습니다" +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 simple 사전 매개 변수: \"%s\"" -#: utils/adt/mac.c:68 +#: tsearch/dict_synonym.c:118 #, c-format -msgid "invalid input syntax for type macaddr: \"%s\"" -msgstr "macaddr ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 synonym 매개 변수: \"%s\"" -#: utils/adt/mac.c:75 +#: tsearch/dict_synonym.c:125 #, c-format -msgid "invalid octet value in \"macaddr\" value: \"%s\"" -msgstr "\"macaddr\"ì— ëŒ€í•œ ìž˜ëª»ëœ ì˜¥í…Ÿ(octet) ê°’: \"%s\"" +msgid "missing Synonyms parameter" +msgstr "Synonyms 매개 변수가 누ë½ë¨" -#: utils/adt/misc.c:239 +#: tsearch/dict_synonym.c:132 #, c-format -msgid "PID %d is not a PostgreSQL server process" -msgstr "PID %d í”„ë¡œê·¸ëž¨ì€ PostgreSQL 서버 프로세스가 아닙니다" +msgid "could not open synonym file \"%s\": %m" +msgstr "\"%s\" ë™ì˜ì–´ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/misc.c:290 +#: tsearch/dict_thesaurus.c:179 #, c-format -msgid "must be a superuser to cancel superuser query" -msgstr "슈í¼ìœ ì €ì˜ 쿼리를 중지하려면 슈í¼ìœ ì €ì—¬ì•¼ 합니다." +msgid "could not open thesaurus file \"%s\": %m" +msgstr "\"%s\" 기준어 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/misc.c:295 +#: tsearch/dict_thesaurus.c:212 #, c-format -msgid "" -"must be a member of the role whose query is being canceled or member of " -"pg_signal_backend" -msgstr "" -"쿼리 작업 취소하려면 작업ìžì˜ ì†Œì† ë§´ë²„ì´ê±°ë‚˜ pg_signal_backend ì†Œì† ë§´ë²„ì—¬" -"야 합니다" +msgid "unexpected delimiter" +msgstr "예기치 ì•Šì€ êµ¬ë¶„ìž" -#: utils/adt/misc.c:314 +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 #, c-format -msgid "must be a superuser to terminate superuser process" -msgstr "슈í¼ìœ ì €ì˜ ì„¸ì…˜ì„ ì •ë¦¬í•˜ë ¤ë©´ 슈í¼ìœ ì €ì—¬ì•¼ 합니다." +msgid "unexpected end of line or lexeme" +msgstr "예기치 ì•Šì€ ì¤„ ë ë˜ëŠ” 어휘소" -#: utils/adt/misc.c:319 +#: tsearch/dict_thesaurus.c:287 #, c-format -msgid "" -"must be a member of the role whose process is being terminated or member of " -"pg_signal_backend" -msgstr "" -"ì„¸ì…˜ì„ ì¢…ë£Œí•˜ë ¤ë©´ ì ‘ì†ìžì˜ ì†Œì† ë§´ë²„ì´ê±°ë‚˜ pg_signal_backend ì†Œì† ë§´ë²„ì—¬ì•¼ í•©" -"니다" +msgid "unexpected end of line" +msgstr "예기치 ì•Šì€ ì¤„ ë" -#: utils/adt/misc.c:336 +#: tsearch/dict_thesaurus.c:297 #, c-format -msgid "failed to send signal to postmaster: %m" -msgstr "postmaster로 ì‹œê·¸ë„ ë³´ë‚´ê¸° 실패: %m" +msgid "too many lexemes in thesaurus entry" +msgstr "기준어 í•­ëª©ì— ë„ˆë¬´ ë§Žì€ ì–´íœ˜ì†Œê°€ 있ìŒ" -#: utils/adt/misc.c:356 +#: tsearch/dict_thesaurus.c:421 #, c-format -msgid "rotation not possible because log collection not active" -msgstr "로그 ìˆ˜ì§‘ì´ í™œì„± ìƒíƒœê°€ 아니므로 회전할 수 ì—†ìŒ" +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "\"%s\" 기준 단어는 하위 사전ì—서 ì¸ì‹í•  수 ì—†ìŒ(규칙 %d)" -#: utils/adt/misc.c:393 +#: tsearch/dict_thesaurus.c:427 #, c-format -msgid "global tablespace never has databases" -msgstr "ì „ì—­ í…Œì´ë¸”스페ì´ìŠ¤ëŠ” ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ê²°ì½” í¬í•¨í•˜ì§€ 않습니다." +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "\"%s\" ë™ì˜ì–´ 사전 샘플 단어는 중지 단어임(규칙 %d)" -#: utils/adt/misc.c:414 +#: tsearch/dict_thesaurus.c:430 #, c-format -msgid "%u is not a tablespace OID" -msgstr "%u í…Œì´ë¸”스페ì´ìФ OIDê°€ 아님" - -#: utils/adt/misc.c:611 -msgid "unreserved" -msgstr "예약ë˜ì§€ 않ìŒ" - -#: utils/adt/misc.c:615 -msgid "unreserved (cannot be function or type name)" -msgstr "예약ë˜ì§€ 않ìŒ(함수, ìžë£Œí˜• ì´ë¦„ì¼ ìˆ˜ ì—†ìŒ)" - -#: utils/adt/misc.c:619 -msgid "reserved (can be function or type name)" -msgstr "예약ë¨(함수, ìžë£Œí˜• ì´ë¦„ì¼ ìˆ˜ 있ìŒ)" - -#: utils/adt/misc.c:623 -msgid "reserved" -msgstr "예약ë¨" +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "샘플 구 ë‚´ì—서 중지 단어를 나타내려면 \"?\"를 사용하십시오." -#: utils/adt/misc.c:797 utils/adt/misc.c:811 utils/adt/misc.c:850 -#: utils/adt/misc.c:856 utils/adt/misc.c:862 utils/adt/misc.c:885 +#: tsearch/dict_thesaurus.c:576 #, c-format -msgid "string is not a valid identifier: \"%s\"" -msgstr "문ìžì—´ì´ 타당한 ì‹ë³„ìžê°€ 아님: \"%s\"" +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "\"%s\" ë™ì˜ì–´ 사전 대체 단어는 중지 단어임(규칙 %d)" -#: utils/adt/misc.c:799 +#: tsearch/dict_thesaurus.c:583 #, c-format -msgid "String has unclosed double quotes." -msgstr "문ìžì—´ 표기ì—서 í°ë”°ì˜´í‘œ ì§ì´ 안맞습니다." +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "\"%s\" ë™ì˜ì–´ 사전 대체 단어는 하위 사전ì—서 ì¸ì‹í•  수 ì—†ìŒ(규칙 %d)" -#: utils/adt/misc.c:813 +#: tsearch/dict_thesaurus.c:595 #, c-format -msgid "Quoted identifier must not be empty." -msgstr "ì¸ìš©ë¶€í˜¸ 있는 ì‹ë³„ìž: 비어있으면 안ë©ë‹ˆë‹¤" +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "ë™ì˜ì–´ 사전 대체 구가 비어 있ìŒ(규칙 %d)" -#: utils/adt/misc.c:852 +#: tsearch/dict_thesaurus.c:633 #, c-format -msgid "No valid identifier before \".\"." -msgstr "\".\" ì „ì— íƒ€ë‹¹í•œ ì‹ë³„ìžê°€ ì—†ìŒ" +msgid "multiple Dictionary parameters" +msgstr "Dictionary 매개 변수가 여러 ê°œ 있ìŒ" -#: utils/adt/misc.c:858 +#: tsearch/dict_thesaurus.c:640 #, c-format -msgid "No valid identifier after \".\"." -msgstr "\".\" ë’¤ì— íƒ€ë‹¹í•œ ì‹ë³„ìž ì—†ìŒ" +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 Thesaurus 매개 변수: \"%s\"" -#: utils/adt/nabstime.c:136 +#: tsearch/dict_thesaurus.c:652 #, c-format -msgid "invalid time zone name: \"%s\"" -msgstr "ìž˜ëª»ëœ íƒ€ìž„ì¡´ ì´ë¦„: \"%s\"" +msgid "missing Dictionary parameter" +msgstr "Dictionary 매개 변수가 누ë½ë¨" -#: utils/adt/nabstime.c:481 utils/adt/nabstime.c:554 +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1034 #, c-format -msgid "cannot convert abstime \"invalid\" to timestamp" -msgstr "\"invalid\" abstime ìžë£Œí˜•ì„ timestamp ìžë£Œí˜•으로 변환할 수 없습니다." +msgid "invalid affix flag \"%s\"" +msgstr "ìž˜ëª»ëœ affix 플래그: \"%s\"" -#: utils/adt/nabstime.c:781 +#: tsearch/spell.c:384 tsearch/spell.c:1038 #, c-format -msgid "invalid status in external \"tinterval\" value" -msgstr "외부 \"tinterval\" ê°’ì— ìž˜ëª»ëœ ìƒíƒœê°€ 있ìŒ" +msgid "affix flag \"%s\" is out of range" +msgstr "affix 플래그 범위 초과: \"%s\"" -#: utils/adt/nabstime.c:855 +#: tsearch/spell.c:414 #, c-format -msgid "cannot convert reltime \"invalid\" to interval" -msgstr "reltime \"invalid\"를 interval로 변환할 수 ì—†ìŒ" +msgid "invalid character in affix flag \"%s\"" +msgstr "affix í”Œëž˜ê·¸ì— ì´ìƒí•œ 문ìžê°€ 있ìŒ: \"%s\"" -#: utils/adt/nabstime.c:1550 +#: tsearch/spell.c:434 #, c-format -msgid "invalid input syntax for type tinterval: \"%s\"" -msgstr "tinterval ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "" -#: utils/adt/network.c:69 +#: tsearch/spell.c:522 #, c-format -msgid "invalid cidr value: \"%s\"" -msgstr "cidr ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "could not open dictionary file \"%s\": %m" +msgstr "\"%s\" 사전 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/network.c:70 utils/adt/network.c:200 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format -msgid "Value has bits set to right of mask." -msgstr "ë§ˆìŠ¤í¬ ì˜¤ë¥¸ìª½ì— ì„¤ì •ëœ ë¹„íŠ¸ê°€ ê°’ì— í¬í•¨ë˜ì–´ 있습니다." +msgid "invalid regular expression: %s" +msgstr "ìž˜ëª»ëœ ì •ê·œì‹: %s" -#: utils/adt/network.c:111 utils/adt/network.c:607 utils/adt/network.c:632 -#: utils/adt/network.c:657 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format -msgid "could not format inet value: %m" -msgstr "inet ê°’ì˜ í˜•ì‹ì„ 지정할 수 ì—†ìŒ: %m" +msgid "invalid affix alias \"%s\"" +msgstr "ìž˜ëª»ëœ affix 별칭: \"%s\"" -#. translator: %s is inet or cidr -#: utils/adt/network.c:168 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format -msgid "invalid address family in external \"%s\" value" -msgstr "잘못 ëœ ì£¼ì†Œêµ° \"%s\"" +msgid "could not open affix file \"%s\": %m" +msgstr "\"%s\" affix 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#. translator: %s is inet or cidr -#: utils/adt/network.c:175 +#: tsearch/spell.c:1265 #, c-format -msgid "invalid bits in external \"%s\" value" -msgstr "\"%s\" ê°’ì— ìž˜ëª»ëœ ë¹„íŠ¸ê°€ 있ìŒ" +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell ì‚¬ì „ì€ \"default\", \"long\", \"num\" 플래그 ê°’ë§Œ ì§€ì›í•¨" -#. translator: %s is inet or cidr -#: utils/adt/network.c:184 +#: tsearch/spell.c:1309 #, c-format -msgid "invalid length in external \"%s\" value" -msgstr "외부 \"%s\" ê°’ì˜ ê¸¸ì´ê°€ 잘못 ë˜ì—ˆìŒ" +msgid "invalid number of flag vector aliases" +msgstr "ìž˜ëª»ëœ í”Œëž˜ê·¸ 백터 별칭 개수" -#: utils/adt/network.c:199 +#: tsearch/spell.c:1332 #, c-format -msgid "invalid external \"cidr\" value" -msgstr "외부 \"cidr\" ê°’ì´ ìž˜ëª»ë¨" +msgid "number of aliases exceeds specified number %d" +msgstr "alias 수가 지정한 %d 개수를 초과함" -#: utils/adt/network.c:321 utils/adt/network.c:348 +#: tsearch/spell.c:1547 #, c-format -msgid "invalid mask length: %d" -msgstr "ìž˜ëª»ëœ ë§ˆìŠ¤í¬ ê¸¸ì´: %d" +msgid "affix file contains both old-style and new-style commands" +msgstr "affix 파ì¼ì— 옛방ì‹ê³¼ ìƒˆë°©ì‹ ëª…ë ¹ì´ í•¨ê»˜ 있습니다" -#: utils/adt/network.c:675 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 #, c-format -msgid "could not format cidr value: %m" -msgstr "cidr ê°’ì„ ì²˜ë¦¬í•  수 ì—†ìŒ: %m" +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "문ìžì—´ì´ 너무 길어서 tsvectorì— ì‚¬ìš©í•  수 ì—†ìŒ(%dë°”ì´íЏ, 최대 %dë°”ì´íЏ)" -#: utils/adt/network.c:917 +#: tsearch/ts_locale.c:174 #, c-format -msgid "cannot merge addresses from different families" -msgstr "서로 다른 페밀리ì—서는 주소를 병합할 수 ì—†ìŒ" +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "%d번째 줄(해당 파ì¼: \"%s\"): \"%s\"" -#: utils/adt/network.c:1343 +#: tsearch/ts_locale.c:291 #, c-format -msgid "cannot AND inet values of different sizes" -msgstr "서로 í¬ê¸°ê°€ 틀린 inet ê°’ë“¤ì€ AND ì—°ì‚°ì„ í•  수 없습니다." +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "wchar_tì—서 서버 ì¸ì½”딩으로 변환하지 못함: %m" -#: utils/adt/network.c:1375 +#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:566 +#: tsearch/ts_parse.c:573 #, c-format -msgid "cannot OR inet values of different sizes" -msgstr "서로 í¬ê¸°ê°€ 틀린 inet ê°’ë“¤ì€ OR ì—°ì‚°ì„ í•  수 없습니다." +msgid "word is too long to be indexed" +msgstr "단어가 너무 길어서 ì¸ë±ì‹±í•  수 ì—†ìŒ" -#: utils/adt/network.c:1436 utils/adt/network.c:1512 +#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:567 +#: tsearch/ts_parse.c:574 #, c-format -msgid "result is out of range" -msgstr "결과가 범위를 벗어났습니다." +msgid "Words longer than %d characters are ignored." +msgstr "%dìžë³´ë‹¤ 긴 단어는 무시ë©ë‹ˆë‹¤." -#: utils/adt/network.c:1477 +#: tsearch/ts_utils.c:51 #, c-format -msgid "cannot subtract inet values of different sizes" -msgstr "inet ê°’ì—서 서로 í¬ê¸°ê°€ 틀리게 부분 추출(subtract)í•  수 ì—†ìŒ" +msgid "invalid text search configuration file name \"%s\"" +msgstr "\"%s\" 전문 검색 구성 íŒŒì¼ ì´ë¦„ì´ ìž˜ëª»ë¨" -#: utils/adt/numeric.c:542 utils/adt/numeric.c:569 utils/adt/numeric.c:5405 -#: utils/adt/numeric.c:5428 utils/adt/numeric.c:5452 +#: tsearch/ts_utils.c:83 #, c-format -msgid "invalid input syntax for type numeric: \"%s\"" -msgstr "수치 ìžë£Œí˜•ì˜ ìž…ë ¥ êµ¬ë¬¸ì— ì˜¤ë¥˜ê°€ 있습니다: \"%s\"" +msgid "could not open stop-word file \"%s\": %m" +msgstr "\"%s\" 중지 단어 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/adt/numeric.c:768 +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 #, c-format -msgid "invalid sign in external \"numeric\" value" -msgstr "외부 \"numeric\" ê°’ì˜ ë¶€í˜¸ê°€ 잘못ë¨" +msgid "text search parser does not support headline creation" +msgstr "전문 검색 ë¶„ì„기ì—서 헤드ë¼ì¸ ìž‘ì„±ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/adt/numeric.c:774 +#: tsearch/wparser_def.c:2486 #, c-format -msgid "invalid scale in external \"numeric\" value" -msgstr "외부 \"numeric\" ê°’ì˜ ìž˜ëª»ëœ ìŠ¤ì¼€ì¼" +msgid "unrecognized headline parameter: \"%s\"" +msgstr "ì¸ì‹í•  수 없는 headline 매개 변수: \"%s\"" -#: utils/adt/numeric.c:783 +#: tsearch/wparser_def.c:2495 #, c-format -msgid "invalid digit in external \"numeric\" value" -msgstr "외부 \"numeric\" ê°’ì˜ ìˆ«ìžê°€ 잘못ë¨" +msgid "MinWords should be less than MaxWords" +msgstr "MinWords는 MaxWords보다 작아야 함" -#: utils/adt/numeric.c:974 utils/adt/numeric.c:988 +#: tsearch/wparser_def.c:2499 #, c-format -msgid "NUMERIC precision %d must be between 1 and %d" -msgstr "NUMERIC ì •ë°€ë„ %d ê°’ì€ ë²”ìœ„(1 .. %d)를 벗어났습니다." +msgid "MinWords should be positive" +msgstr "MinWords는 양수여야 함" -#: utils/adt/numeric.c:979 +#: tsearch/wparser_def.c:2503 #, c-format -msgid "NUMERIC scale %d must be between 0 and precision %d" -msgstr "NUMERIC ìŠ¤ì¼€ì¼ %d ê°’ì€ ì •ë°€ë„ ë²”ìœ„(0 .. %d)를 벗어났습니다." +msgid "ShortWord should be >= 0" +msgstr "ShortWord는 0보다 í¬ê±°ë‚˜ 같아야 함" -#: utils/adt/numeric.c:997 +#: tsearch/wparser_def.c:2507 #, c-format -msgid "invalid NUMERIC type modifier" -msgstr "ìž˜ëª»ëœ NUMERIC í˜•ì‹ í•œì •ìž" +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments는 0보다 í¬ê±°ë‚˜ 같아야 함" -#: utils/adt/numeric.c:1329 +# # nonun 부분 begin +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format -msgid "start value cannot be NaN" -msgstr "ì‹œìž‘ê°’ì€ NaN ì¼ ìˆ˜ ì—†ìŒ" +msgid "identifier too long" +msgstr "ì‹ë³„ìž(identifier)ê°€ 너무 ê¹ë‹ˆë‹¤." -#: utils/adt/numeric.c:1334 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format -msgid "stop value cannot be NaN" -msgstr "ì¢…ë£Œê°’ì€ NaN ì¼ ìˆ˜ ì—†ìŒ" +msgid "Identifier must be less than %d characters." +msgstr "ì‹ë³„ìž(Identifier)는 %d ê¸€ìž ì´ìƒì¼ 수 없습니다." -#: utils/adt/numeric.c:1344 +#: utils/adt/acl.c:258 #, c-format -msgid "step size cannot be NaN" -msgstr "단계 í¬ê¸°ëŠ” NaN ì¼ ìˆ˜ ì—†ìŒ" +msgid "unrecognized key word: \"%s\"" +msgstr "알 수 없는 ì•Šì€ í‚¤ì›Œë“œ: \"%s\"" -#: utils/adt/numeric.c:2539 utils/adt/numeric.c:5467 utils/adt/numeric.c:5912 -#: utils/adt/numeric.c:7616 utils/adt/numeric.c:8041 utils/adt/numeric.c:8156 -#: utils/adt/numeric.c:8229 +#: utils/adt/acl.c:259 #, c-format -msgid "value overflows numeric format" -msgstr "ê°’ì´ ìˆ˜ì¹˜ 형ì‹ì— 넘처남" +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL 키워드는 \"group\" ë˜ëŠ” \"user\" ì¤‘ì— í•˜ë‚˜ì—¬ì•¼ 합니다." -#: utils/adt/numeric.c:2881 +#: utils/adt/acl.c:264 #, c-format -msgid "cannot convert NaN to integer" -msgstr "NaN ê°’ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ 변환할 수 없습니다" +msgid "missing name" +msgstr "ì´ë¦„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤." -#: utils/adt/numeric.c:2947 +#: utils/adt/acl.c:265 #, c-format -msgid "cannot convert NaN to bigint" -msgstr "NaN ê°’ì„ bigint형으로 변환할 수 없습니다" +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "ì´ë¦„ì€ \"group\" ë˜ëŠ” \"user\" 키워드 ë’¤ì— ìžˆì–´ì•¼ 합니다." -#: utils/adt/numeric.c:2992 +#: utils/adt/acl.c:271 #, c-format -msgid "cannot convert NaN to smallint" -msgstr "NaN ê°’ì„ smallint형으로 변환할 수 없습니다" +msgid "missing \"=\" sign" +msgstr "\"=\" 기호가 빠졌습니다." -#: utils/adt/numeric.c:5982 +#: utils/adt/acl.c:324 #, c-format -msgid "numeric field overflow" -msgstr "수치 필드 오버플로우" +msgid "invalid mode character: must be one of \"%s\"" +msgstr "ìž˜ëª»ëœ ì¡°ê±´: \"%s\" ì¤‘ì— í•œ 가지여야 합니다." -#: utils/adt/numeric.c:5983 +#: utils/adt/acl.c:346 #, c-format -msgid "" -"A field with precision %d, scale %d must round to an absolute value less " -"than %s%d." -msgstr "" -"ì „ì²´ ìžë¦¿ìˆ˜ %d, 소수 ìžë¦¿ìˆ˜ %dì˜ í•„ë“œëŠ” %s%d보다 ìž‘ì€ ì ˆëŒ€ 값으로 반올림해야 " -"합니다." +msgid "a name must follow the \"/\" sign" +msgstr "ì´ë¦„ì€ \"/\"기호 ë’¤ì— ìžˆì–´ì•¼ 합니다." -#: utils/adt/numeric.c:6254 utils/adt/numeric.c:6280 +#: utils/adt/acl.c:354 #, c-format -msgid "invalid input syntax for type double precision: \"%s\"" -msgstr "double precision ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "defaulting grantor to user ID %u" +msgstr "%u ì‚¬ìš©ìž IDì—서 기본 권한ìžë¡œ 할당하고 있습니다" -#: utils/adt/numutils.c:75 +#: utils/adt/acl.c:545 #, c-format -msgid "value \"%s\" is out of range for type integer" -msgstr "입력한 \"%s\" ê°’ì€ integer ìžë£Œí˜• 범위를 초과했습니다" +msgid "ACL array contains wrong data type" +msgstr "ACL ë°°ì—´ì— ìž˜ëª»ëœ ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ê³  있습니다" -#: utils/adt/numutils.c:81 +#: utils/adt/acl.c:549 #, c-format -msgid "value \"%s\" is out of range for type smallint" -msgstr "입력한 \"%s\" ê°’ì€ smallint ìžë£Œí˜• 범위를 초과했습니다" +msgid "ACL arrays must be one-dimensional" +msgstr "ACL ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: utils/adt/numutils.c:87 +#: utils/adt/acl.c:553 #, c-format -msgid "value \"%s\" is out of range for 8-bit integer" -msgstr "ê°’ \"%s\"ì€(는) 8비트 ì •ìˆ˜ì˜ ë²”ìœ„ë¥¼ 벗어남" +msgid "ACL arrays must not contain null values" +msgstr "ACL ë°°ì—´ì—는 null ê°’ì„ í¬í•¨í•  수 없습니다" -#: utils/adt/oid.c:43 utils/adt/oid.c:57 utils/adt/oid.c:63 utils/adt/oid.c:84 +#: utils/adt/acl.c:577 #, c-format -msgid "invalid input syntax for type oid: \"%s\"" -msgstr "ìž˜ëª»ëœ oid ìžë£Œí˜•ì˜ ìž…ë ¥: \"%s\"" +msgid "extra garbage at the end of the ACL specification" +msgstr "ACL 설정 ì •ë³´ ëì— ëì— ì“¸ëª¨ 없는 ë‚´ìš©ë“¤ì´ ë” í¬í•¨ë˜ì–´ìžˆìŠµë‹ˆë‹¤" -#: utils/adt/oid.c:69 utils/adt/oid.c:107 +#: utils/adt/acl.c:1213 #, c-format -msgid "value \"%s\" is out of range for type oid" -msgstr "입력한 \"%s\" ê°’ì€ oid ìžë£Œí˜• 범위를 초과했습니다" +msgid "grant options cannot be granted back to your own grantor" +msgstr "부여 ì˜µì…˜ì„ í•´ë‹¹ 부여ìžì—게 다시 부여할 수 ì—†ìŒ" -#: utils/adt/oid.c:287 +#: utils/adt/acl.c:1274 #, c-format -msgid "invalid oidvector data" -msgstr "ìž˜ëª»ëœ oidvector ìžë£Œ" +msgid "dependent privileges exist" +msgstr "???ì˜ì¡´(ì ì¸) ê¶Œí•œì´ ì¡´ìž¬í•©ë‹ˆë‹¤" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/acl.c:1275 #, c-format -msgid "requested character too large" -msgstr "ìš”ì²­ëœ ë¬¸ìžê°€ 너무 í¼" +msgid "Use CASCADE to revoke them too." +msgstr "ê·¸ê²ƒë“¤ì„ ì·¨ì†Œí•˜ë ¤ë©´ \"CASCADE\"를 사용하세요." -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/acl.c:1537 #, c-format -msgid "requested character too large for encoding: %d" -msgstr "요청한 문ìžê°€ 너무 커서 ì¸ì½”딩할 수 ì—†ìŒ: %d" +msgid "aclinsert is no longer supported" +msgstr "aclinsert ë”ì´ìƒ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/acl.c:1547 #, c-format -msgid "requested character not valid for encoding: %d" -msgstr "요청한 문ìžê°€ ì¸ì½”딩용으로 타당치 않ìŒ: %d" +msgid "aclremove is no longer supported" +msgstr "aclremovie ë”ì´ìƒ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format -msgid "null character not permitted" -msgstr "null 문ìžëŠ” 허용ë˜ì§€ 않ìŒ" +msgid "unrecognized privilege type: \"%s\"" +msgstr "알 수 없는 권한 타입: \"%s\"" -#: utils/adt/orderedsetaggs.c:425 utils/adt/orderedsetaggs.c:530 -#: utils/adt/orderedsetaggs.c:669 +#: utils/adt/acl.c:3430 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format -msgid "percentile value %g is not between 0 and 1" -msgstr "%g í¼ì„¼íЏ ê°’ì´ 0ê³¼ 1사ì´ê°€ 아닙니다." +msgid "function \"%s\" does not exist" +msgstr "\"%s\" 함수가 없습니다." -#: utils/adt/pg_locale.c:1029 +#: utils/adt/acl.c:4884 #, c-format -msgid "Apply system library package updates." -msgstr "OS ë¼ì´ë¸ŒëŸ¬ë¦¬ 패키지를 ì—…ë°ì´íЏ 하세요." +msgid "must be member of role \"%s\"" +msgstr "\"%s\" ë¡¤ì˜ êµ¬ì„±ì›ì´ì–´ì•¼ 함" -#: utils/adt/pg_locale.c:1234 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1520 utils/adt/arrayfuncs.c:3223 +#: utils/adt/arrayfuncs.c:3363 utils/adt/arrayfuncs.c:5898 +#: utils/adt/arrayfuncs.c:6209 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format -msgid "could not create locale \"%s\": %m" -msgstr "\"%s\" 로케ì¼ì„ 만들 수 ì—†ìŒ: %m" +msgid "array size exceeds the maximum allowed (%d)" +msgstr "ë°°ì—´ í¬ê¸°ê°€ 최대치 (%d)를 초과했습니다" -#: utils/adt/pg_locale.c:1237 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 +#: utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format -msgid "" -"The operating system could not find any locale data for the locale name \"%s" -"\"." -msgstr "ìš´ì˜ì²´ì œì—서 \"%s\" ë¡œì¼€ì¼ ì´ë¦„ì— ëŒ€í•œ ë¡œì¼€ì¼ íŒŒì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." +msgid "could not determine input data type" +msgstr "ìž…ë ¥ ìžë£Œí˜•ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/adt/pg_locale.c:1324 +#: utils/adt/array_userfuncs.c:85 #, c-format -msgid "" -"collations with different collate and ctype values are not supported on this " -"platform" -msgstr "" -"ì´ í”Œëž«í¼ì—서는 서로 다른 정렬규칙(collation)ê³¼ 문ìžì§‘í•©(ctype)ì„ í•¨ê»˜ 쓸 수 " -"없습니다." +msgid "input data type is not an array" +msgstr "ìž…ë ¥ ìžë£Œí˜•ì´ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." -#: utils/adt/pg_locale.c:1339 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1323 utils/adt/float.c:1363 utils/adt/float.c:1422 +#: utils/adt/float.c:3708 utils/adt/float.c:3722 utils/adt/int.c:755 +#: utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 +#: utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 +#: utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 +#: utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 +#: utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 +#: utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format -msgid "nondefault collations are not supported on this platform" -msgstr "" -"ì´ í”Œëž«í¼ì—서는 ê¸°ë³¸ê°’ì´ ì•„ë‹Œ 정렬규칙(collation)ì„ ì‚¬ìš©í•  수 없습니다." +msgid "integer out of range" +msgstr "정수 범위를 벗어남" -#: utils/adt/pg_locale.c:1510 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format -msgid "invalid multibyte character for locale" -msgstr "로케ì¼ì„ 위한 ìž˜ëª»ëœ ë©€í‹°ë°”ì´íЏ 문ìž" +msgid "argument must be empty or one-dimensional array" +msgstr "ì¸ìžëŠ” 비어있거나 1ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." -#: utils/adt/pg_locale.c:1511 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format -msgid "" -"The server's LC_CTYPE locale is probably incompatible with the database " -"encoding." -msgstr "ì„œë²„ì˜ LC_CTYPE 로케ì¼ì€ ì´ ë°ì´í„°ë² ì´ìФ ì¸ì½”딩과 호환ë˜ì§€ 않습니다." +msgid "cannot concatenate incompatible arrays" +msgstr "ì—°ê²°í•  수 없는 배열들 입니다." -#: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:49 +#: utils/adt/array_userfuncs.c:274 #, c-format -msgid "invalid input syntax for type pg_lsn: \"%s\"" -msgstr "pg_lsn ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "%s ìžë£Œí˜•ì˜ ë°°ì—´ê³¼ %s ìžë£Œí˜•ì˜ ë°°ì—´ì€ ì—°ê²°í•  수 없습니다." -#: utils/adt/pg_upgrade_support.c:40 +#: utils/adt/array_userfuncs.c:313 #, c-format -msgid "function can only be called when server is in binary upgrade mode" -msgstr "함수는 서버가 ì´ì§„ 업그레ì´ë“œ ìƒíƒœì—서만 호출 ë  ìˆ˜ 있습니다" +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "%dì°¨ì›(ë°°ì—´ 깊ì´) ë°°ì—´ê³¼ %dì°¨ì› ë°°ì—´ì€ ì—°ê²°í•  수 없습니다." -#: utils/adt/pgstatfuncs.c:571 +#: utils/adt/array_userfuncs.c:350 #, c-format -msgid "invalid command name: \"%s\"" -msgstr "ìž˜ëª»ëœ ëª…ë ¹ì–´ ì´ë¦„: \"%s\"" +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "ì°¨ì›(ë°°ì—´ 깊ì´)ì´ ë‹¤ë¥¸ ë°°ì—´ë“¤ì„ ì„œë¡œ í•©ì¹  수 없습니다" -#: utils/adt/pseudotypes.c:95 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format -msgid "cannot accept a value of type any" -msgstr "any 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "ì°¨ì›(ë°°ì—´ 깊ì´)ì´ ë‹¤ë¥¸ ë°°ì—´ë“¤ì„ ì„œë¡œ í•©ì¹  수 없습니다" -#: utils/adt/pseudotypes.c:108 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format -msgid "cannot display a value of type any" -msgstr "any 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—서 요소 검색 ê¸°ëŠ¥ì€ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:150 +#: utils/adt/array_userfuncs.c:686 #, c-format -msgid "cannot accept a value of type anyarray" -msgstr "anyarray 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "initial position must not be null" +msgstr "초기 ìœ„ì¹˜ê°’ì€ nullê°’ì´ ì•„ë‹ˆì—¬ì•¼ 함" -#: utils/adt/pseudotypes.c:175 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format -msgid "cannot accept a value of type anyenum" -msgstr "anyenum ìžë£Œí˜• 값으로 사용할 수 ì—†ìŒ" +msgid "malformed array literal: \"%s\"" +msgstr "비정ìƒì ì¸ ë°°ì—´ 문ìž: \"%s\"" -#: utils/adt/pseudotypes.c:199 +#: utils/adt/arrayfuncs.c:270 #, c-format -msgid "cannot accept a value of type anyrange" -msgstr "anyrange ìžë£Œí˜• 값으로 사용할 수 ì—†ìŒ" +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "ë°°ì—´ ì°¨ì› ì •ì˜ëŠ” \"[\" 문ìžë¡œ 시작해야 합니다." -#: utils/adt/pseudotypes.c:276 +#: utils/adt/arrayfuncs.c:284 #, c-format -msgid "cannot accept a value of type trigger" -msgstr "trigger ìžë£Œí˜• 값으로 사용할 수 ì—†ìŒ" +msgid "Missing array dimension value." +msgstr "ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´) ê°’ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤." -#: utils/adt/pseudotypes.c:289 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format -msgid "cannot display a value of type trigger" -msgstr "trigger ìžë£Œí˜• 값으로 표시할 수 ì—†ìŒ" +msgid "Missing \"%s\" after array dimensions." +msgstr "ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´) 표현ì—서 \"%s\" 문ìžê°€ 빠졌습니다." -#: utils/adt/pseudotypes.c:303 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2871 +#: utils/adt/arrayfuncs.c:2903 utils/adt/arrayfuncs.c:2918 #, c-format -msgid "cannot accept a value of type event_trigger" -msgstr "event_trigger 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "upper bound cannot be less than lower bound" +msgstr "ìƒí•œê°’ì€ í•˜í•œê°’ë³´ë‹¤ ìž‘ì„ ìˆ˜ 없습니다" -#: utils/adt/pseudotypes.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format -msgid "cannot display a value of type event_trigger" -msgstr "event_trigger ìžë£Œí˜• ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "Array value must start with \"{\" or dimension information." +msgstr "ë°°ì—´ê°’ì€ \"{\" ë˜ëŠ” ë°°ì—´ ê¹Šì´ ì •ë³´ë¡œ 시작ë˜ì–´ì•¼ 합니다" -#: utils/adt/pseudotypes.c:330 +#: utils/adt/arrayfuncs.c:346 #, c-format -msgid "cannot accept a value of type language_handler" -msgstr "language_handler ìžë£Œí˜• ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Array contents must start with \"{\"." +msgstr "ë°°ì—´í˜•ì€ \"{\" 문ìžë¡œ 시작해야 합니다." -#: utils/adt/pseudotypes.c:343 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format -msgid "cannot display a value of type language_handler" -msgstr "language_handler ìžë£Œí˜• ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "Specified array dimensions do not match array contents." +msgstr "지정한 ë°°ì—´ ì°¨ì›ì— 해당하는 ë°°ì—´ì´ ì—†ìŠµë‹ˆë‹¤." -#: utils/adt/pseudotypes.c:357 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 +#: utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format -msgid "cannot accept a value of type fdw_handler" -msgstr "fdw_handler ìžë£Œí˜• ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Unexpected end of input." +msgstr "ìž…ë ¥ì˜ ì˜ˆìƒì¹˜ 못한 종료." -#: utils/adt/pseudotypes.c:370 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format -msgid "cannot display a value of type fdw_handler" -msgstr "fdw_handler 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "Unexpected \"%c\" character." +msgstr "예기치 ì•Šì€ \"%c\" 문ìž" -#: utils/adt/pseudotypes.c:384 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format -msgid "cannot accept a value of type index_am_handler" -msgstr "index_am_handler 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Unexpected array element." +msgstr "예기치 ì•Šì€ ë°°ì—´ 요소" -#: utils/adt/pseudotypes.c:397 +#: utils/adt/arrayfuncs.c:590 #, c-format -msgid "cannot display a value of type index_am_handler" -msgstr "index_am_handler 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "Unmatched \"%c\" character." +msgstr "ì§ì´ 안 맞는 \"%c\" 문ìž" -#: utils/adt/pseudotypes.c:411 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format -msgid "cannot accept a value of type tsm_handler" -msgstr "tsm_handler 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—는 ì¼ì¹˜í•˜ëŠ” ì°¨ì›ì´ í¬í•¨ëœ ë°°ì—´ ì‹ì´ 있어야 함" -#: utils/adt/pseudotypes.c:424 +#: utils/adt/arrayfuncs.c:675 #, c-format -msgid "cannot display a value of type tsm_handler" -msgstr "tsm_handler 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" - -#: utils/adt/pseudotypes.c:438 -#, c-format -msgid "cannot accept a value of type internal" -msgstr "internal 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Junk after closing right brace." +msgstr "오른쪽 닫기 괄호 ë’¤ì— ì •í¬" -#: utils/adt/pseudotypes.c:451 +#: utils/adt/arrayfuncs.c:1285 utils/adt/arrayfuncs.c:3331 +#: utils/adt/arrayfuncs.c:5804 #, c-format -msgid "cannot display a value of type internal" -msgstr "internal 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "invalid number of dimensions: %d" +msgstr "ìž˜ëª»ëœ ë°°ì—´ ì°¨ì›(ë°°ì—´ 깊ì´): %d" -#: utils/adt/pseudotypes.c:465 +#: utils/adt/arrayfuncs.c:1296 #, c-format -msgid "cannot accept a value of type opaque" -msgstr "opaque 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "invalid array flags" +msgstr "ìž˜ëª»ëœ ë°°ì—´ 플래그" -#: utils/adt/pseudotypes.c:478 +#: utils/adt/arrayfuncs.c:1304 #, c-format -msgid "cannot display a value of type opaque" -msgstr "opaque 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "wrong element type" +msgstr "ìž˜ëª»ëœ ìš”ì†Œ 타입" -#: utils/adt/pseudotypes.c:492 +#: utils/adt/arrayfuncs.c:1354 utils/adt/rangetypes.c:334 +#: utils/cache/lsyscache.c:2701 #, c-format -msgid "cannot accept a value of type anyelement" -msgstr "anyelement 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "no binary input function available for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 ë°”ì´ë„ˆë¦¬ ìž…ë ¥ 함수가 없습니다." -#: utils/adt/pseudotypes.c:505 +#: utils/adt/arrayfuncs.c:1494 #, c-format -msgid "cannot display a value of type anyelement" -msgstr "anyelement 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "improper binary format in array element %d" +msgstr "%d 번째 ë°°ì—´ ìš”ì†Œì˜ í¬ë§·ì´ ë¶€ì ì ˆí•©ë‹ˆë‹¤." -#: utils/adt/pseudotypes.c:518 +#: utils/adt/arrayfuncs.c:1575 utils/adt/rangetypes.c:339 +#: utils/cache/lsyscache.c:2734 #, c-format -msgid "cannot accept a value of type anynonarray" -msgstr "anynonarray 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "no binary output function available for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 ë°”ì´ë„ˆë¦¬ 출력 함수가 없습니다." -#: utils/adt/pseudotypes.c:531 +#: utils/adt/arrayfuncs.c:2053 #, c-format -msgid "cannot display a value of type anynonarray" -msgstr "anynonarray 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "slices of fixed-length arrays not implemented" +msgstr "특정 í¬ê¸°ë¡œ ë°°ì—´ì„ ì ˆë‹¨í•˜ëŠ” ê¸°ëŠ¥ì€ êµ¬í˜„ë˜ì§€ 않습니다." -#: utils/adt/pseudotypes.c:544 +#: utils/adt/arrayfuncs.c:2231 utils/adt/arrayfuncs.c:2253 +#: utils/adt/arrayfuncs.c:2302 utils/adt/arrayfuncs.c:2538 +#: utils/adt/arrayfuncs.c:2849 utils/adt/arrayfuncs.c:5790 +#: utils/adt/arrayfuncs.c:5816 utils/adt/arrayfuncs.c:5827 +#: utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 +#: utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4289 utils/adt/jsonfuncs.c:4440 +#: utils/adt/jsonfuncs.c:4485 utils/adt/jsonfuncs.c:4532 #, c-format -msgid "cannot accept a value of a shell type" -msgstr "ì…¸ 형태 ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "wrong number of array subscripts" +msgstr "ìž˜ëª»ëœ ë°°ì—´ 하위 스í¬ë¦½íЏ(1,2...ì°¨ì› ë°°ì—´ 표시 문제)" -#: utils/adt/pseudotypes.c:557 +#: utils/adt/arrayfuncs.c:2236 utils/adt/arrayfuncs.c:2344 +#: utils/adt/arrayfuncs.c:2602 utils/adt/arrayfuncs.c:2908 #, c-format -msgid "cannot display a value of a shell type" -msgstr "shell 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" +msgid "array subscript out of range" +msgstr "ë°°ì—´ 하위 스í¬ë¦½íЏ 범위를 초과했습니다" -#: utils/adt/pseudotypes.c:579 utils/adt/pseudotypes.c:604 -#: utils/adt/pseudotypes.c:632 utils/adt/pseudotypes.c:660 +#: utils/adt/arrayfuncs.c:2241 #, c-format -msgid "cannot accept a value of type %s" -msgstr "%s 형ì‹ì˜ ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "ê³ ì • ê¸¸ì´ ë°°ì—´ì˜ ìš”ì†Œì— null ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" -#: utils/adt/pseudotypes.c:647 utils/adt/pseudotypes.c:673 +#: utils/adt/arrayfuncs.c:2796 #, c-format -msgid "cannot output a value of type %s" -msgstr "%s 형ì‹ì˜ ê°’ì€ ì¶œë ¥í•  수 ì—†ìŒ" +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "ê³ ì •ëœ í¬ê¸°ì˜ ë°°ì—´ì˜ ì¡°ê°ì„ ì—…ë°ì´íЏ 하는 ê¸°ëŠ¥ì€ êµ¬í˜„ë˜ì§€ 않았습니다." -#: utils/adt/rangetypes.c:405 +#: utils/adt/arrayfuncs.c:2827 #, c-format -msgid "range constructor flags argument must not be null" -msgstr "range ìžë£Œí˜• êµ¬ì„±ìž í”Œëž˜ê·¸ ì¸ìžë¡œ nullì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "array slice subscript must provide both boundaries" +msgstr "ë°°ì—´ 나누기 서브스í¬ë¦½íŠ¸ëŠ” 반드시 둘다 ë²”ìœ„ì•ˆì— ìžˆì–´ì•¼ 합니다" -#: utils/adt/rangetypes.c:992 +#: utils/adt/arrayfuncs.c:2828 #, c-format -msgid "result of range difference would not be contiguous" +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "" -#: utils/adt/rangetypes.c:1053 +#: utils/adt/arrayfuncs.c:2839 utils/adt/arrayfuncs.c:2934 #, c-format -msgid "result of range union would not be contiguous" -msgstr "" +msgid "source array too small" +msgstr "ì›ë³¸ ë°°ì—´ì´ ë„ˆë¬´ 작습니다." -#: utils/adt/rangetypes.c:1543 +#: utils/adt/arrayfuncs.c:3487 #, c-format -msgid "range lower bound must be less than or equal to range upper bound" -msgstr "range ìžë£Œí˜•ì˜ í•˜í•œê°’ì€ ìƒí•œê°’ê³¼ 같거나 작아야 합니다" +msgid "null array element not allowed in this context" +msgstr "ì´ êµ¬ë¬¸ì—서는 ë°°ì—´ì˜ null 요소를 허용하지 않습니다" -#: utils/adt/rangetypes.c:1926 utils/adt/rangetypes.c:1939 -#: utils/adt/rangetypes.c:1953 +#: utils/adt/arrayfuncs.c:3589 utils/adt/arrayfuncs.c:3760 +#: utils/adt/arrayfuncs.c:4112 #, c-format -msgid "invalid range bound flags" -msgstr "ìž˜ëª»ëœ range 구성 플래그" +msgid "cannot compare arrays of different element types" +msgstr "ë°°ì—´ 요소 ìžë£Œí˜•ì´ ì„œë¡œ 틀린 ë°°ì—´ì€ ë¹„êµí•  수 없습니다." -#: utils/adt/rangetypes.c:1927 utils/adt/rangetypes.c:1940 -#: utils/adt/rangetypes.c:1954 +#: utils/adt/arrayfuncs.c:3936 utils/adt/rangetypes.c:1253 +#: utils/adt/rangetypes.c:1317 #, c-format -msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." -msgstr "유효한 ê°’ì€ \"[]\", \"[)\", \"(]\", \"()\"." +msgid "could not identify a hash function for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 해시 함수를 ì°¾ì„ ìˆ˜ 없습니다." -#: utils/adt/rangetypes.c:2019 utils/adt/rangetypes.c:2036 -#: utils/adt/rangetypes.c:2049 utils/adt/rangetypes.c:2067 -#: utils/adt/rangetypes.c:2078 utils/adt/rangetypes.c:2122 -#: utils/adt/rangetypes.c:2130 +#: utils/adt/arrayfuncs.c:4028 #, c-format -msgid "malformed range literal: \"%s\"" -msgstr "비정ìƒì ì¸ range 문ìž: \"%s\"" +msgid "could not identify an extended hash function for type %s" +msgstr "%s ìžë£Œí˜•ì—서 사용할 í™•ìž¥ëœ í•´ì‹œ 함수를 ì°¾ì„ ìˆ˜ 없습니다." -#: utils/adt/rangetypes.c:2021 +#: utils/adt/arrayfuncs.c:5204 #, c-format -msgid "Junk after \"empty\" key word." -msgstr " \"empty\" 키워드 ë’¤ì— ì •í¬ê°€ 있ìŒ" +msgid "data type %s is not an array type" +msgstr "%s ìžë£Œí˜•ì€ ë°°ì—´ì´ ì•„ë‹™ë‹ˆë‹¤." -#: utils/adt/rangetypes.c:2038 +#: utils/adt/arrayfuncs.c:5259 #, c-format -msgid "Missing left parenthesis or bracket." -msgstr "왼쪽 괄호가 빠졌ìŒ" +msgid "cannot accumulate null arrays" +msgstr "null ë°°ì—´ì„ ëˆ„ì í•  수 ì—†ìŒ" -#: utils/adt/rangetypes.c:2051 +#: utils/adt/arrayfuncs.c:5287 #, c-format -msgid "Missing comma after lower bound." -msgstr "하한값 ë’¤ì— ì‰¼í‘œê°€ 빠졌ìŒ" +msgid "cannot accumulate empty arrays" +msgstr "빈 ë°°ì—´ì„ ëˆ„ì í•  수 ì—†ìŒ" -#: utils/adt/rangetypes.c:2069 +#: utils/adt/arrayfuncs.c:5316 utils/adt/arrayfuncs.c:5322 #, c-format -msgid "Too many commas." -msgstr "ì¹¼ëŸ¼ì´ ë„ˆë¬´ 많습니다." +msgid "cannot accumulate arrays of different dimensionality" +msgstr "ë°°ì—´ 차수가 서로 틀린 ë°°ì—´ì€ ëˆ„ì í•  수 ì—†ìŒ" -#: utils/adt/rangetypes.c:2080 +#: utils/adt/arrayfuncs.c:5688 utils/adt/arrayfuncs.c:5728 #, c-format -msgid "Junk after right parenthesis or bracket." -msgstr "오른쪽 괄호 다ìŒì— ì •í¬ê°€ 있ìŒ" +msgid "dimension array or low bound array cannot be null" +msgstr "ì°¨ì› ë°°ì—´ ë˜ëŠ” 하한 ë°°ì—´ì€ NULLì¼ ìˆ˜ ì—†ìŒ" -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1288 utils/adt/varlena.c:3829 +#: utils/adt/arrayfuncs.c:5791 utils/adt/arrayfuncs.c:5817 #, c-format -msgid "regular expression failed: %s" -msgstr "ìž˜ëª»ëœ ì •ê·œì‹: %s" +msgid "Dimension array must be one dimensional." +msgstr "ì°¨ì› ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." -#: utils/adt/regexp.c:422 +#: utils/adt/arrayfuncs.c:5796 utils/adt/arrayfuncs.c:5822 #, c-format -msgid "invalid regexp option: \"%c\"" -msgstr "ìž˜ëª»ëœ regexp 옵션: \"%c\"" +msgid "dimension values cannot be null" +msgstr "ì°¨ì› ê°’ì€ nullì¼ ìˆ˜ ì—†ìŒ" -#: utils/adt/regexp.c:948 +#: utils/adt/arrayfuncs.c:5828 #, c-format -msgid "regexp_split does not support the global option" -msgstr "regexp_split는 글로벌 ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" +msgid "Low bound array has different size than dimensions array." +msgstr "하한 ë°°ì—´ì˜ í¬ê¸°ê°€ ì°¨ì› ë°°ì—´ê³¼ 다릅니다." -#: utils/adt/regproc.c:128 utils/adt/regproc.c:148 +#: utils/adt/arrayfuncs.c:6074 #, c-format -msgid "more than one function named \"%s\"" -msgstr "\"%s\"(ì´)ë¼ëŠ” 함수가 ë‘ ê°œ ì´ìƒ 있ìŒ" +msgid "removing elements from multidimensional arrays is not supported" +msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—서 요소 ì‚­ì œê¸°ëŠ¥ì€ ì§€ì›ë˜ì§€ 않ìŒ" -#: utils/adt/regproc.c:587 utils/adt/regproc.c:607 +#: utils/adt/arrayfuncs.c:6351 #, c-format -msgid "more than one operator named %s" -msgstr "%s(ì´)ë¼ëŠ” ì—°ì‚°ìžê°€ ë‘ ê°œ ì´ìƒ 있ìŒ" +msgid "thresholds must be one-dimensional array" +msgstr "threshold ê°’ì€ 1ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." -#: utils/adt/regproc.c:774 utils/adt/regproc.c:815 gram.y:7302 +#: utils/adt/arrayfuncs.c:6356 #, c-format -msgid "missing argument" -msgstr "ì¸ìžê°€ 빠졌ìŒ" +msgid "thresholds array must not contain NULLs" +msgstr "threshold ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: utils/adt/regproc.c:775 utils/adt/regproc.c:816 gram.y:7303 +#: utils/adt/arrayutils.c:209 #, c-format -msgid "Use NONE to denote the missing argument of a unary operator." -msgstr "단항 ì—°ì‚°ìžì—서 ì¸ìž ì—†ìŒì„ 표시할 때는 NONE ì¸ìžë¥¼ 사용하세요." +msgid "typmod array must be type cstring[]" +msgstr "typmod ë°°ì—´ì€ cstring[] 형ì‹ì´ì–´ì•¼ 함" -#: utils/adt/regproc.c:779 utils/adt/regproc.c:820 utils/adt/regproc.c:2006 -#: utils/adt/ruleutils.c:8367 utils/adt/ruleutils.c:8536 +#: utils/adt/arrayutils.c:214 #, c-format -msgid "too many arguments" -msgstr "ì¸ìžê°€ 너무 많습니다" +msgid "typmod array must be one-dimensional" +msgstr "typmod ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 함" -#: utils/adt/regproc.c:780 utils/adt/regproc.c:821 +#: utils/adt/arrayutils.c:219 #, c-format -msgid "Provide two argument types for operator." -msgstr "ì—°ì‚°ìžë¥¼ 위해서는 ë‘ê°œì˜ ì¸ìž ìžë£Œí˜•ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤." +msgid "typmod array must not contain nulls" +msgstr "typmod ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: utils/adt/regproc.c:1594 utils/adt/regproc.c:1618 utils/adt/regproc.c:1715 -#: utils/adt/regproc.c:1739 utils/adt/regproc.c:1841 utils/adt/regproc.c:1846 -#: utils/adt/varlena.c:3084 utils/adt/varlena.c:3089 +#: utils/adt/ascii.c:76 #, c-format -msgid "invalid name syntax" -msgstr "ìž˜ëª»ëœ ì´ë¦„ 구문" +msgid "encoding conversion from %s to ASCII not supported" +msgstr "%s ì¸ì½”ë”©ì„ ASCII ì¸ì½”ë”©ìœ¼ë¡œì˜ ë³€í™˜ì€ ì§€ì›í•˜ì§€ 않습니다." -#: utils/adt/regproc.c:1904 +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 +#: utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 +#: utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 +#: utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 +#: utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 +#: utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 +#: utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 +#: utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 +#: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 +#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1539 +#: utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 +#: utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 +#: utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 +#: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 +#: utils/adt/uuid.c:136 #, c-format -msgid "expected a left parenthesis" -msgstr "왼쪽 괄호가 필요합니다." +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "%s ìžë£Œí˜• 대한 ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" -#: utils/adt/regproc.c:1920 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 +#: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format -msgid "expected a right parenthesis" -msgstr "오른쪽 괄호가 필요합니다." +msgid "value \"%s\" is out of range for type %s" +msgstr "입력한 \"%s\" ê°’ì€ %s ìžë£Œí˜• 범위를 초과했습니다" -#: utils/adt/regproc.c:1939 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3469 +#: utils/adt/float.c:3532 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 +#: utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 +#: utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 +#: utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 +#: utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3235 #, c-format -msgid "expected a type name" -msgstr "ìžë£Œí˜• ì´ë¦„ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤" +msgid "division by zero" +msgstr "0으로는 나눌수 없습니다." -#: utils/adt/regproc.c:1971 +#: utils/adt/char.c:169 #, c-format -msgid "improper type name" -msgstr "ë¶€ì ì ˆí•œ í˜•ì‹ ì´ë¦„" +msgid "\"char\" out of range" +msgstr "\"char\" 범위를 벗어났습니다." -#: utils/adt/ri_triggers.c:314 utils/adt/ri_triggers.c:371 -#: utils/adt/ri_triggers.c:790 utils/adt/ri_triggers.c:1013 -#: utils/adt/ri_triggers.c:1169 utils/adt/ri_triggers.c:1350 -#: utils/adt/ri_triggers.c:1515 utils/adt/ri_triggers.c:1691 -#: utils/adt/ri_triggers.c:1871 utils/adt/ri_triggers.c:2062 -#: utils/adt/ri_triggers.c:2120 utils/adt/ri_triggers.c:2225 -#: utils/adt/ri_triggers.c:2402 gram.y:3343 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 +#: utils/adt/varchar.c:46 #, c-format -msgid "MATCH PARTIAL not yet implemented" -msgstr "MATCH PARTIAL ê¸°ëŠ¥ì€ ì•„ì§ êµ¬í˜„ 안ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "invalid type modifier" +msgstr "ìž˜ëª»ëœ ìžë£Œí˜• 한정ìž" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 -#: utils/adt/ri_triggers.c:3315 +#: utils/adt/date.c:77 #, c-format -msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" -msgstr "" -"\"%s\" í…Œì´ë¸”ì—서 ìžë£Œ 추가, 갱신 ìž‘ì—…ì´ \"%s\" 참조키(foreign key) 제약 ì¡°ê±´" -"ì„ ìœ„ë°°í–ˆìŠµë‹ˆë‹¤" +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s ì •ë°€ë„로 ìŒìˆ˜ë¥¼ 사용할 수 없습니다" -#: utils/adt/ri_triggers.c:346 utils/adt/ri_triggers.c:2493 +#: utils/adt/date.c:83 #, c-format -msgid "MATCH FULL does not allow mixing of null and nonnull key values." -msgstr "MATCH FULLì— null 키 ê°’ê³¼ nonnull 키 ê°’ì„ í•¨ê»˜ 사용할 수 없습니다." +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s ì •ë°€ë„는 최대값(%d)으로 줄였습니다" -#: utils/adt/ri_triggers.c:2732 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format -msgid "function \"%s\" must be fired for INSERT" -msgstr "INSERTì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" +msgid "date/time value \"current\" is no longer supported" +msgstr "ë‚ ìžì™€ 시간 ìž…ë ¥ì„ ìœ„í•œ \"current\" 는 ë”ì´ìƒ ì§€ì›í•˜ì§€ 않습니다." -#: utils/adt/ri_triggers.c:2738 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 +#: utils/adt/formatting.c:3615 #, c-format -msgid "function \"%s\" must be fired for UPDATE" -msgstr "UPDATEì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" +msgid "date out of range: \"%s\"" +msgstr "ë‚ ì§œ 범위가 벗어났ìŒ: \"%s\"" -#: utils/adt/ri_triggers.c:2744 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2089 #, c-format -msgid "function \"%s\" must be fired for DELETE" -msgstr "DELETEì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" +msgid "date out of range" +msgstr "날짜가 범위를 벗어남" -#: utils/adt/ri_triggers.c:2767 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 #, c-format -msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" -msgstr "\"%s\" 트리거(해당 í…Œì´ë¸”: \"%s\")ì— ëŒ€í•œ pg_constraint í•­ëª©ì´ ì—†ìŒ" +msgid "date field value out of range: %d-%02d-%02d" +msgstr "ë‚ ì§œ í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: %d-%02d-%02d" -#: utils/adt/ri_triggers.c:2769 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 #, c-format -msgid "" -"Remove this referential integrity trigger and its mates, then do ALTER TABLE " -"ADD CONSTRAINT." -msgstr "" -"해당 트리거 관련 ê°ì²´ë¥¼ 제거한 후 ALTER TABLE ADD CONSTRAINT 명령으로 추가하" -"세요" +msgid "date out of range: %d-%02d-%02d" +msgstr "ë‚ ì§œ 범위가 벗어났ìŒ: %d-%02d-%02d" -#: utils/adt/ri_triggers.c:3225 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 +#: utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 +#: utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 +#: utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:456 +#: utils/adt/nabstime.c:499 utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 +#: utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2814 utils/adt/timestamp.c:2835 +#: utils/adt/timestamp.c:2848 utils/adt/timestamp.c:2857 +#: utils/adt/timestamp.c:2865 utils/adt/timestamp.c:2920 +#: utils/adt/timestamp.c:2943 utils/adt/timestamp.c:2956 +#: utils/adt/timestamp.c:2967 utils/adt/timestamp.c:2975 +#: utils/adt/timestamp.c:3635 utils/adt/timestamp.c:3760 +#: utils/adt/timestamp.c:3801 utils/adt/timestamp.c:3891 +#: utils/adt/timestamp.c:3937 utils/adt/timestamp.c:4040 +#: utils/adt/timestamp.c:4447 utils/adt/timestamp.c:4546 +#: utils/adt/timestamp.c:4556 utils/adt/timestamp.c:4648 +#: utils/adt/timestamp.c:4750 utils/adt/timestamp.c:4760 +#: utils/adt/timestamp.c:4992 utils/adt/timestamp.c:5006 +#: utils/adt/timestamp.c:5011 utils/adt/timestamp.c:5025 +#: utils/adt/timestamp.c:5070 utils/adt/timestamp.c:5102 +#: utils/adt/timestamp.c:5109 utils/adt/timestamp.c:5142 +#: utils/adt/timestamp.c:5146 utils/adt/timestamp.c:5215 +#: utils/adt/timestamp.c:5219 utils/adt/timestamp.c:5233 +#: utils/adt/timestamp.c:5267 utils/adt/xml.c:2111 utils/adt/xml.c:2118 +#: utils/adt/xml.c:2138 utils/adt/xml.c:2145 #, c-format -msgid "" -"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave " -"unexpected result" -msgstr "" -"\"%s\"ì— ëŒ€í•œ 참조 무결성 쿼리(제약조건: \"%s\", 해당 릴레ì´ì…˜: \"%s\")를 실" -"행하면 예기치 ì•Šì€ ê²°ê³¼ê°€ ë°œìƒí•¨" +msgid "timestamp out of range" +msgstr "타임스탬프 범위를 벗어남" -#: utils/adt/ri_triggers.c:3229 +#: utils/adt/date.c:512 #, c-format -msgid "This is most likely due to a rule having rewritten the query." -msgstr "ì´ ë¬¸ì œëŠ” 주로 ë£°ì´ ìž¬ìž‘ì„± ë˜ì—ˆì„ 때 ë°œìƒí•©ë‹ˆë‹¤." +msgid "cannot subtract infinite dates" +msgstr "무한 날짜를 뺄 수 ì—†ìŒ" -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format -msgid "Key (%s)=(%s) is not present in table \"%s\"." -msgstr "(%s)=(%s) 키가 \"%s\" í…Œì´ë¸”ì— ì—†ìŠµë‹ˆë‹¤." +msgid "date out of range for timestamp" +msgstr "날짜가 타임스탬프 범위를 벗어남" -#: utils/adt/ri_triggers.c:3322 +#: utils/adt/date.c:1190 #, c-format -msgid "Key is not present in table \"%s\"." -msgstr "\"%s\" í…Œì´ë¸”ì— í‚¤ê°€ 없습니다." +msgid "cannot convert reserved abstime value to date" +msgstr "ì˜ˆì•½ëœ abstime ê°’ì„ date로 형변환할 수 없습니다." -#: utils/adt/ri_triggers.c:3328 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 #, c-format -msgid "" -"update or delete on table \"%s\" violates foreign key constraint \"%s\" on " -"table \"%s\"" -msgstr "" -"\"%s\" í…Œì´ë¸”ì˜ ìžë£Œ 갱신, ì‚­ì œ ìž‘ì—…ì´ \"%s\" 참조키(foreign key) 제약 ì¡°ê±´ " -"- \"%s\" í…Œì´ë¸” - ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" +msgid "abstime out of range for date" +msgstr "abstimeì˜ ë‚ ì§œê°’ì´ ë²”ìœ„ë¥¼ 벗어남" -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format -msgid "Key (%s)=(%s) is still referenced from table \"%s\"." -msgstr "(%s)=(%s) 키가 \"%s\" í…Œì´ë¸”ì—서 여전히 참조ë©ë‹ˆë‹¤." +msgid "time out of range" +msgstr "시간 범위를 벗어남" -#: utils/adt/ri_triggers.c:3336 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 #, c-format -msgid "Key is still referenced from table \"%s\"." -msgstr "\"%s\" í…Œì´ë¸”ì—서 키가 여전히 참조ë©ë‹ˆë‹¤." +msgid "time field value out of range: %d:%02d:%02g" +msgstr "시간 í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: %d:%02d:%02g" -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 +#: utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 +#: utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 +#: utils/adt/timestamp.c:3284 utils/adt/timestamp.c:3315 +#: utils/adt/timestamp.c:3346 #, c-format -msgid "input of anonymous composite types is not implemented" -msgstr "ìµëª… 복합 형ì‹ì˜ ìž…ë ¥ì´ êµ¬í˜„ë˜ì–´ 있지 않ìŒ" +msgid "invalid preceding or following size in window function" +msgstr "윈ë„ìš° 함수ì—서 ì•žì— ì˜¤ê±°ë‚˜ ë’¤ì— ë”°ë¼ì˜¤ëŠ” í¬ê¸°ê°€ 잘못ë¨" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format -msgid "malformed record literal: \"%s\"" -msgstr "비정ìƒì ì¸ 레코드 문ìž: \"%s\"" +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"%s\" 는 \"time\" ìžë£Œí˜• 단위가 아닙니다." -#: utils/adt/rowtypes.c:156 +#: utils/adt/date.c:2099 #, c-format -msgid "Missing left parenthesis." -msgstr "왼쪽 괄호가 필요합니다." +msgid "time zone displacement out of range" +msgstr "타임 ì¡´ 변위가 범위를 벗어남" -#: utils/adt/rowtypes.c:184 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format -msgid "Too few columns." -msgstr "ì—´ 수가 너무 ì ë‹¤" +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"%s\" 는 \"time with time zone\" ìžë£Œí˜•ì˜ ë‹¨ìœ„ê°€ 아닙니다." -#: utils/adt/rowtypes.c:267 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 +#: utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 +#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:5017 +#: utils/adt/timestamp.c:5225 #, c-format -msgid "Too many columns." -msgstr "ì—´ì´ ë„ˆë¬´ 많습니다." +msgid "time zone \"%s\" not recognized" +msgstr "\"%s\" ì´ë¦„ì˜ ì‹œê°„ëŒ€ëŠ” 없습니다." -#: utils/adt/rowtypes.c:275 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5059 utils/adt/timestamp.c:5256 #, c-format -msgid "Junk after right parenthesis." -msgstr "오른쪽 괄호가 필요합니다." +msgid "interval time zone \"%s\" must not include months or days" +msgstr "\"%s\" 시간대 간격(interval time zone) 값으로 달(month) ë˜ëŠ” ì¼(day)ì„ í¬í•¨í•  수 없습니다" -#: utils/adt/rowtypes.c:528 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format -msgid "wrong number of columns: %d, expected %d" -msgstr "ì—´ 수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" +msgid "date/time field value out of range: \"%s\"" +msgstr "ë‚ ì§œ/시간 í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: \"%s\"" -#: utils/adt/rowtypes.c:555 +#: utils/adt/datetime.c:3770 #, c-format -msgid "wrong data type: %u, expected %u" -msgstr "ìž˜ëª»ëœ ìžë£Œí˜•: %u, 예ìƒë˜ëŠ” ìžë£Œí˜• %u" +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "ë‚ ì§œ 표현 ë°©ì‹(\"datestyle\")ì„ ë‹¤ë¥¸ 것으로 사용하고 있는 듯 합니다." -#: utils/adt/rowtypes.c:616 +#: utils/adt/datetime.c:3775 #, c-format -msgid "improper binary format in record column %d" -msgstr "%d 번째 레코드 ì—´ì—서 ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ í¬ë§·ì´ 있습니다" +msgid "interval field value out of range: \"%s\"" +msgstr "interval í•„ë“œì˜ ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: \"%s\"" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 -#: utils/adt/rowtypes.c:1396 utils/adt/rowtypes.c:1673 +#: utils/adt/datetime.c:3781 #, c-format -msgid "cannot compare dissimilar column types %s and %s at record column %d" -msgstr "서로 다른 ì—´ í˜•ì‹ %sê³¼(와) %s(레코드 ì—´ %d)ì„(를) 비êµí•  수 ì—†ìŒ" +msgid "time zone displacement out of range: \"%s\"" +msgstr "표준시간대 범위를 벗어남: \"%s\"" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 -#: utils/adt/rowtypes.c:1529 utils/adt/rowtypes.c:1769 +#: utils/adt/datetime.c:4627 #, c-format -msgid "cannot compare record types with different numbers of columns" -msgstr "칼럼 수가 서로 다른 레코드 ìžë£Œí˜•ì„ ë¹„êµí•  수 ì—†ìŒ" +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "" -#: utils/adt/ruleutils.c:4289 +#: utils/adt/datum.c:86 utils/adt/datum.c:98 #, c-format -msgid "rule \"%s\" has unsupported event type %d" -msgstr "\"%s\" ë£°ì€ %d ì´ë²¤íЏ 형태를 ì§€ì›í•˜ì§€ 않습니다" +msgid "invalid Datum pointer" +msgstr "ìž˜ëª»ëœ Datum í¬ì¸í„°" -#: utils/adt/selfuncs.c:5318 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format -msgid "case insensitive matching not supported on type bytea" -msgstr "bytea 형ì‹ì—서는 대/소문ìžë¥¼ 구분하지 않는 ì¼ì¹˜ê°€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "invalid size: \"%s\"" +msgstr "ìž˜ëª»ëœ í¬ê¸°: \"%s\"" -#: utils/adt/selfuncs.c:5421 +#: utils/adt/dbsize.c:828 #, c-format -msgid "regular-expression matching not supported on type bytea" -msgstr "bytea 형ì‹ì—서는 ì •ê·œì‹ ì¼ì¹˜ê°€ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "Invalid size unit: \"%s\"." +msgstr "ìž˜ëª»ëœ í¬ê¸° 단위: \"%s\"" -#: utils/adt/tid.c:71 utils/adt/tid.c:79 utils/adt/tid.c:87 +#: utils/adt/dbsize.c:829 #, c-format -msgid "invalid input syntax for type tid: \"%s\"" -msgstr "tid 형ì‹ì˜ ìž…ë ¥ êµ¬ë¬¸ì´ ìž˜ëª»ë¨: \"%s\"" +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"bytes\",\"kB\", \"MB\", \"GB\", \"TB\"입니다." -#: utils/adt/timestamp.c:99 +#: utils/adt/domains.c:92 #, c-format -msgid "TIMESTAMP(%d)%s precision must not be negative" -msgstr "TIMESTAMP(%d)%s ì •ë°€ë„로 ìŒìˆ˜ë¥¼ 사용할 수 없습니다" +msgid "type %s is not a domain" +msgstr "%s ìžë£Œí˜•ì€ ë„ë©”ì¸ì´ 아닙니다" -#: utils/adt/timestamp.c:105 +#: utils/adt/encode.c:55 utils/adt/encode.c:91 #, c-format -msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" -msgstr "TIMESTAMP(%d)%s ì •ë°€ë„는 최대값(%d)으로 줄였습니다" - -#: utils/adt/timestamp.c:170 utils/adt/timestamp.c:445 -#, c-format -msgid "timestamp out of range: \"%s\"" -msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: \"%s\"" +msgid "unrecognized encoding: \"%s\"" +msgstr "알 수 없는 ì¸ì½”딩: \"%s\"" -#: utils/adt/timestamp.c:188 utils/adt/timestamp.c:463 -#: utils/adt/timestamp.c:990 +#: utils/adt/encode.c:150 #, c-format -msgid "date/time value \"%s\" is no longer supported" -msgstr "ë‚ ì§œ/시간 ê°’ \"%s\"ì€(는) ë” ì´ìƒ ì§€ì›ë˜ì§€ 않ìŒ" +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "ìž˜ëª»ëœ 16진수: \"%c\"" -#: utils/adt/timestamp.c:258 utils/adt/timestamp.c:754 +#: utils/adt/encode.c:178 #, c-format -msgid "timestamp cannot be NaN" -msgstr "타임스탬프 값으로 NaN ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" +msgid "invalid hexadecimal data: odd number of digits" +msgstr "ìž˜ëª»ëœ 16진수 ë°ì´í„°: ë°ì´í„°ì˜ 길ì´ê°€ 홀수 입니다." -#: utils/adt/timestamp.c:380 +#: utils/adt/encode.c:295 #, c-format -msgid "timestamp(%d) precision must be between %d and %d" -msgstr "타임스탬프(%d) ì •ë°€ë„는 %dì—서 %d 사ì´ì—¬ì•¼ 함" +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "base64 ìžë£Œë¥¼ 디코딩 하는 중 예ìƒì¹˜ 못한 \"=\" ë¬¸ìž ë°œê²¬" -#: utils/adt/timestamp.c:513 +#: utils/adt/encode.c:307 #, c-format -msgid "invalid input syntax for numeric time zone: \"%s\"" -msgstr "숫ìží˜• 타임 ì¡´ ìž…ë ¥ì— ë¬¸ë²• 오류가 있ìŒ: \"%s\"" +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "base64 ìžë£Œë¥¼ 디코딩 하는 중 ìž˜ëª»ëœ \"%c\" 기호 발견" -#: utils/adt/timestamp.c:515 +#: utils/adt/encode.c:327 #, c-format -msgid "Numeric time zones must have \"-\" or \"+\" as first character." -msgstr "숫ìží˜• 타임 ì¡´ 형ì‹ì€ 처ìŒì— \"-\" ë˜ëŠ” \"+\" 문ìžê°€ 있어야 합니다." +msgid "invalid base64 end sequence" +msgstr "base64 마침 ì¡°í•©ì´ ìž˜ëª»ë˜ì—ˆìŒ" -#: utils/adt/timestamp.c:528 +#: utils/adt/encode.c:328 #, c-format -msgid "numeric time zone \"%s\" out of range" -msgstr "\"%s\" 숫ìží˜• 타임 ì¡´ 범위 벗어남" +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "ìž…ë ¥ê°’ì— ì—¬ë°± ì²˜ë¦¬ê°’ì´ ë¹ ì¡Œê±°ë‚˜, ìžë£Œê°€ ì†ìƒë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/adt/timestamp.c:631 utils/adt/timestamp.c:641 -#: utils/adt/timestamp.c:653 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 +#: utils/adt/varlena.c:337 #, c-format -msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" -msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: %d-%02d-%02d %d:%02d:%02g" +msgid "invalid input syntax for type %s" +msgstr "%s ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥ 구문" -#: utils/adt/timestamp.c:772 utils/adt/timestamp.c:788 +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 +#: utils/adt/enum.c:123 #, c-format -msgid "timestamp out of range: \"%g\"" -msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: \"%g\"" +msgid "invalid input value for enum %s: \"%s\"" +msgstr "%s ì—´ê±°í˜•ì˜ ìž…ë ¥ ê°’ì´ ìž˜ëª»ë¨: \"%s\"" -#: utils/adt/timestamp.c:984 utils/adt/timestamp.c:1608 -#: utils/adt/timestamp.c:2121 utils/adt/timestamp.c:3273 -#: utils/adt/timestamp.c:3278 utils/adt/timestamp.c:3283 -#: utils/adt/timestamp.c:3333 utils/adt/timestamp.c:3340 -#: utils/adt/timestamp.c:3347 utils/adt/timestamp.c:3367 -#: utils/adt/timestamp.c:3374 utils/adt/timestamp.c:3381 -#: utils/adt/timestamp.c:3411 utils/adt/timestamp.c:3419 -#: utils/adt/timestamp.c:3464 utils/adt/timestamp.c:3804 -#: utils/adt/timestamp.c:3933 utils/adt/timestamp.c:4324 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format -msgid "interval out of range" -msgstr "ê°„ê²©ì´ ë²”ìœ„ë¥¼ 벗어남" +msgid "invalid internal value for enum: %u" +msgstr "ì—´ê±°í˜•ì˜ ë‚´ë¶€ ê°’ì´ ìž˜ëª»ë¨: %u" -#: utils/adt/timestamp.c:1125 utils/adt/timestamp.c:1158 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 +#: utils/adt/enum.c:449 #, c-format -msgid "invalid INTERVAL type modifier" -msgstr "ìž˜ëª»ëœ INTERVAL í˜•ì‹ í•œì •ìž" +msgid "could not determine actual enum type" +msgstr "실제 ì—´ê±°í˜•ì˜ ìžë£Œí˜•ì„ í™•ì¸í•  수 ì—†ìŒ" -#: utils/adt/timestamp.c:1141 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format -msgid "INTERVAL(%d) precision must not be negative" -msgstr "INTERVAL(%d) ì •ë°€ë„로 ìŒìˆ˜ê°’ì´ ì˜¬ 수 없습니다" +msgid "enum %s contains no values" +msgstr "\"%s\" 열거형 ìžë£Œì— ê°’ì´ ì—†ìŒ" -#: utils/adt/timestamp.c:1147 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 +#: utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 #, c-format -msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" -msgstr "INTERVAL(%d) ì •ë°€ë„는 허용 최대치(%d)로 ê°ì†Œ ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "type %s is not composite" +msgstr "%s ìžë£Œí˜•ì€ ë³µí•© ìžë£Œí˜•ì´ ì•„ë‹™ë‹ˆë‹¤" -#: utils/adt/timestamp.c:1552 +#: utils/adt/float.c:55 #, c-format -msgid "interval(%d) precision must be between %d and %d" -msgstr "간격(%d) ì •ë°€ë„는 %dì—서 %d 사ì´ì—¬ì•¼ 함" +msgid "value out of range: overflow" +msgstr "ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: 오버플로" -#: utils/adt/timestamp.c:2850 +#: utils/adt/float.c:60 #, c-format -msgid "cannot subtract infinite timestamps" -msgstr "타임스탬프 ë¬´í•œê°’ì„ ì¶”ì¶œ í•  수 ì—†ìŒ" +msgid "value out of range: underflow" +msgstr "ê°’ì´ ë²”ìœ„ë¥¼ 벗어남: ì–¸ë”플로" -#: utils/adt/timestamp.c:4059 utils/adt/timestamp.c:4584 -#: utils/adt/timestamp.c:4768 utils/adt/timestamp.c:4793 +#: utils/adt/float.c:309 #, c-format -msgid "timestamp units \"%s\" not supported" -msgstr "\"%s\" timestamp ìœ ë‹›ì€ ì§€ì›í•˜ì§€ 않습니다" +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\"는 real ìžë£Œí˜•ì˜ ë²”ìœ„ë¥¼ 벗어납니다." -#: utils/adt/timestamp.c:4073 utils/adt/timestamp.c:4538 -#: utils/adt/timestamp.c:4803 +#: utils/adt/float.c:534 #, c-format -msgid "timestamp units \"%s\" not recognized" -msgstr "\"%s\" timestamp ìœ ë‹›ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\"는 double precision ìžë£Œí˜•ì˜ ë²”ìœ„ë¥¼ 벗어납니다." -#: utils/adt/timestamp.c:4213 utils/adt/timestamp.c:4579 -#: utils/adt/timestamp.c:4990 utils/adt/timestamp.c:5016 +#: utils/adt/float.c:1381 utils/adt/float.c:1439 utils/adt/int.c:332 +#: utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 +#: utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 +#: utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format -msgid "timestamp with time zone units \"%s\" not supported" -msgstr "\"%s\" 시간대 ìœ ë‹›ì´ ìžˆëŠ” timestamp ìžë£Œí˜•ì€ ì§€ì›í•˜ì§€ 않습니다" +msgid "smallint out of range" +msgstr "smallintì˜ ë²”ìœ„ë¥¼ 벗어났습니다." -#: utils/adt/timestamp.c:4230 utils/adt/timestamp.c:4533 -#: utils/adt/timestamp.c:5025 +#: utils/adt/float.c:1565 utils/adt/numeric.c:7802 #, c-format -msgid "timestamp with time zone units \"%s\" not recognized" -msgstr "\"%s\" 시간대 ìœ ë‹›ì´ ìžˆëŠ” timestamp ê°’ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" +msgid "cannot take square root of a negative number" +msgstr "ìŒìˆ˜ì˜ ì œê³±ê·¼ì„ êµ¬í•  수 없습니다." -#: utils/adt/timestamp.c:4311 +#: utils/adt/float.c:1626 utils/adt/numeric.c:3017 #, c-format -msgid "" -"interval units \"%s\" not supported because months usually have fractional " -"weeks" -msgstr "" +msgid "zero raised to a negative power is undefined" +msgstr "0ì˜ ìŒìˆ˜ ê±°ë“­ì œê³±ì´ ì •ì˜ë˜ì–´ 있지 않ìŒ" -#: utils/adt/timestamp.c:4317 utils/adt/timestamp.c:5131 +#: utils/adt/float.c:1630 utils/adt/numeric.c:3023 #, c-format -msgid "interval units \"%s\" not supported" -msgstr "\"%s\" 유닛 간격(interval units)ì€ ì§€ì›í•˜ì§€ 않습니다" +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "ìŒìˆ˜ì˜ 비정수 ê±°ë“­ì œê³±ì„ ê³„ì‚°í•˜ë©´ 복잡한 결과가 ìƒì„±ë¨" -#: utils/adt/timestamp.c:4333 utils/adt/timestamp.c:5158 +#: utils/adt/float.c:1696 utils/adt/float.c:1726 utils/adt/numeric.c:8068 #, c-format -msgid "interval units \"%s\" not recognized" -msgstr "\"%s\" 유닛 간격(interval units)ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" +msgid "cannot take logarithm of zero" +msgstr "0ì˜ ëŒ€ìˆ˜ë¥¼ 구할 수 없습니다." -#: utils/adt/trigfuncs.c:42 +#: utils/adt/float.c:1700 utils/adt/float.c:1730 utils/adt/numeric.c:8072 #, c-format -msgid "suppress_redundant_updates_trigger: must be called as trigger" -msgstr "suppress_redundant_updates_trigger: 트리거로 호출ë˜ì–´ì•¼ 함" +msgid "cannot take logarithm of a negative number" +msgstr "ìŒìˆ˜ì˜ 대수를 구할 수 없습니다." -#: utils/adt/trigfuncs.c:48 +#: utils/adt/float.c:1760 utils/adt/float.c:1790 utils/adt/float.c:1882 +#: utils/adt/float.c:1908 utils/adt/float.c:1935 utils/adt/float.c:1961 +#: utils/adt/float.c:2108 utils/adt/float.c:2143 utils/adt/float.c:2307 +#: utils/adt/float.c:2361 utils/adt/float.c:2425 utils/adt/float.c:2480 #, c-format -msgid "suppress_redundant_updates_trigger: must be called on update" -msgstr "suppress_redundant_updates_trigger: ì—…ë°ì´íЏ 시 호출ë˜ì–´ì•¼ 함" +msgid "input is out of range" +msgstr "ìž…ë ¥ê°’ì´ ë²”ìœ„ë¥¼ 벗어났습니다." -#: utils/adt/trigfuncs.c:54 +#: utils/adt/float.c:3686 utils/adt/numeric.c:1504 #, c-format -msgid "suppress_redundant_updates_trigger: must be called before update" -msgstr "suppress_redundant_updates_trigger: ì—…ë°ì´íЏ ì „ì— í˜¸ì¶œë˜ì–´ì•¼ 함" +msgid "count must be greater than zero" +msgstr "카운트 ê°’ì€ 0 보다 커야합니다" -#: utils/adt/trigfuncs.c:60 +#: utils/adt/float.c:3691 utils/adt/numeric.c:1511 #, c-format -msgid "suppress_redundant_updates_trigger: must be called for each row" -msgstr "suppress_redundant_updates_trigger: ê° í–‰ì— ëŒ€í•´ 호출ë˜ì–´ì•¼ 함" +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "피연산ìž, 하한 ë° ìƒí•œì€ NaNì¼ ìˆ˜ ì—†ìŒ" -#: utils/adt/tsgistidx.c:99 +#: utils/adt/float.c:3697 #, c-format -msgid "gtsvector_in not implemented" -msgstr "gtsvector_inì´ êµ¬í˜„ë˜ì–´ 있지 않ìŒ" +msgid "lower and upper bounds must be finite" +msgstr "하한 ë° ìƒí•œì€ 유한한 ê°’ì´ì–´ì•¼ 함" -#: utils/adt/tsquery.c:166 +#: utils/adt/float.c:3731 utils/adt/numeric.c:1524 #, c-format -msgid "distance in phrase operator should not be greater than %d" -msgstr "ë¶„ì„ ìž‘ì—…ì—서 사용한 ê±°ë¦¬ê°’ì€ %d 보다 í´ ìˆ˜ 없습니다" +msgid "lower bound cannot equal upper bound" +msgstr "í•˜í•œê°’ì€ ìƒí•œê°’ê³¼ ê°™ì„ ìˆ˜ 없습니다" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/formatting.c:488 #, c-format -msgid "syntax error in tsquery: \"%s\"" -msgstr "tsqueryì— êµ¬ë¬¸ 오류가 있ìŒ: \"%s\"" +msgid "invalid format specification for an interval value" +msgstr "간격 ê°’ì— ëŒ€í•œ í˜•ì‹ ì§€ì •ì´ ìž˜ëª»ë¨" -#: utils/adt/tsquery.c:275 +#: utils/adt/formatting.c:489 #, c-format -msgid "no operand in tsquery: \"%s\"" -msgstr "tsqueryì— í”¼ì—°ì‚°ìžê°€ ì—†ìŒ: \"%s\"" +msgid "Intervals are not tied to specific calendar dates." +msgstr "ê°„ê²©ì´ íŠ¹ì • 달력 ë‚ ì§œì— ì—°ê²°ë˜ì–´ 있지 않습니다." -#: utils/adt/tsquery.c:358 +#: utils/adt/formatting.c:1059 #, c-format -msgid "value is too big in tsquery: \"%s\"" -msgstr "tsqueryì˜ ê°’ì´ ë„ˆë¬´ í¼: \"%s\"" +msgid "\"EEEE\" must be the last pattern used" +msgstr "" -#: utils/adt/tsquery.c:363 +#: utils/adt/formatting.c:1067 #, c-format -msgid "operand is too long in tsquery: \"%s\"" -msgstr "tsqueryì˜ í”¼ì—°ì‚°ìžê°€ 너무 긺: \"%s\"" +msgid "\"9\" must be ahead of \"PR\"" +msgstr "???\"9\"는 \"PR\" 앞ì´ì–´ì•¼ 한다." -#: utils/adt/tsquery.c:391 +#: utils/adt/formatting.c:1083 #, c-format -msgid "word is too long in tsquery: \"%s\"" -msgstr "tsqueryì˜ ë‹¨ì–´ê°€ 너무 긺: \"%s\"" +msgid "\"0\" must be ahead of \"PR\"" +msgstr "???\"0\"ì€ \"PR\" 앞ì´ì–´ì•¼ 한다." -#: utils/adt/tsquery.c:642 +#: utils/adt/formatting.c:1110 #, c-format -msgid "text-search query doesn't contain lexemes: \"%s\"" -msgstr "í…스트 검색 ì¿¼ë¦¬ì— ì–´íœ˜ì†Œê°€ í¬í•¨ë˜ì–´ 있지 않ìŒ: \"%s\"" +msgid "multiple decimal points" +msgstr "???ì—¬ëŸ¬ê°œì˜ ì†Œìˆ«ì " -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format -msgid "tsquery is too large" -msgstr "tsquery 길ì´ê°€ 너무 ê¹ë‹ˆë‹¤" +msgid "cannot use \"V\" and decimal point together" +msgstr "\"V\" 와 소숫ì ì„ 함께 쓸 수 없습니다." -#: utils/adt/tsquery_cleanup.c:407 +#: utils/adt/formatting.c:1126 #, c-format -msgid "" -"text-search query contains only stop words or doesn't contain lexemes, " -"ignored" -msgstr "" -"í…스트 검색 ì¿¼ë¦¬ì— ì¤‘ì§€ 단어만 í¬í•¨ë˜ì–´ 있거나 어휘소가 í¬í•¨ë˜ì–´ 있지 않ìŒ, " -"무시ë¨" +msgid "cannot use \"S\" twice" +msgstr "\"S\"를 ë‘ ë²ˆ 사용할 수 ì—†ìŒ" -#: utils/adt/tsquery_op.c:122 +#: utils/adt/formatting.c:1130 #, c-format -msgid "distance in phrase operator should be non-negative and less than %d" -msgstr "ë¶„ì„ ìž‘ì—…ì—서 사용한 ê±°ë¦¬ê°’ì€ %d 보다 작고 양수값만 사용할 수 있습니다" +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "\"S\" 와 \"PL\"/\"MI\"/\"SG\"/\"PR\" 를 함께 쓸 수 없습니다." -#: utils/adt/tsquery_rewrite.c:321 +#: utils/adt/formatting.c:1150 #, c-format -msgid "ts_rewrite query must return two tsquery columns" -msgstr "ts_rewrite 쿼리는 ë‘ ê°œì˜ tsquery ì—´ì„ ë°˜í™˜í•´ì•¼ 함" +msgid "cannot use \"S\" and \"MI\" together" +msgstr "\"S\" 와 \"MI\" 를 함께 쓸 수 없습니다." -#: utils/adt/tsrank.c:412 +#: utils/adt/formatting.c:1160 #, c-format -msgid "array of weight must be one-dimensional" -msgstr "가중치 ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 함" +msgid "cannot use \"S\" and \"PL\" together" +msgstr "\"S\" 와 \"PL\" 를 함께 쓸 수 없습니다." -#: utils/adt/tsrank.c:417 +#: utils/adt/formatting.c:1170 #, c-format -msgid "array of weight is too short" -msgstr "가중치 ë°°ì—´ì´ ë„ˆë¬´ ì§§ìŒ" +msgid "cannot use \"S\" and \"SG\" together" +msgstr "\"S\" 와 \"SG\" 를 함께 쓸 수 없습니다." -#: utils/adt/tsrank.c:422 +#: utils/adt/formatting.c:1179 #, c-format -msgid "array of weight must not contain nulls" -msgstr "가중치 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "\"PR\" 와 \"S\"/\"PL\"/\"MI\"/\"SG\" 를 함께 쓸 수 없습니다." -#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:868 +#: utils/adt/formatting.c:1205 #, c-format -msgid "weight out of range" -msgstr "가중치가 범위를 벗어남" +msgid "cannot use \"EEEE\" twice" +msgstr "\"EEEE\"를 ë‘ ë²ˆ 사용할 수 ì—†ìŒ" -#: utils/adt/tsvector.c:213 +#: utils/adt/formatting.c:1211 #, c-format -msgid "word is too long (%ld bytes, max %ld bytes)" -msgstr "단어가 너무 긺(%ldë°”ì´íЏ, 최대 %ldë°”ì´íЏ)" +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\"는 다른 í¬ë§·ê³¼ 호환하지 않습니다" -#: utils/adt/tsvector.c:220 +#: utils/adt/formatting.c:1212 #, c-format -msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "" -"문ìžì—´ì´ 너무 길어서 tsvectorì— ì‚¬ìš©í•  수 ì—†ìŒ(%ldë°”ì´íЏ, 최대 %ldë°”ì´íЏ)" -#: utils/adt/tsvector_op.c:322 utils/adt/tsvector_op.c:609 -#: utils/adt/tsvector_op.c:777 +#: utils/adt/formatting.c:1392 #, c-format -msgid "lexeme array may not contain nulls" -msgstr "어휘소 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" +msgid "\"%s\" is not a number" +msgstr "\"%s\"는 숫ìžê°€ 아닙니다." -#: utils/adt/tsvector_op.c:852 +#: utils/adt/formatting.c:1470 #, c-format -msgid "weight array may not contain nulls" -msgstr "가중치 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" +msgid "case conversion failed: %s" +msgstr "ìž˜ëª»ëœ í˜• 변환 규칙: %s" -#: utils/adt/tsvector_op.c:876 +#: utils/adt/formatting.c:1535 #, c-format -msgid "unrecognized weight: \"%c\"" -msgstr "알 수 없는 가중치: \"%c\"" +msgid "could not determine which collation to use for lower() function" +msgstr "lower() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/adt/tsvector_op.c:2313 +#: utils/adt/formatting.c:1657 #, c-format -msgid "ts_stat query must return one tsvector column" -msgstr "ts_stat 쿼리는 í•˜ë‚˜ì˜ tsvector ì¹¼ëŸ¼ì„ ë°˜í™˜í•´ì•¼ 함" +msgid "could not determine which collation to use for upper() function" +msgstr "upper() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/adt/tsvector_op.c:2495 +#: utils/adt/formatting.c:1780 #, c-format -msgid "tsvector column \"%s\" does not exist" -msgstr "\"%s\" tsvector ì¹¼ëŸ¼ì´ ì—†ìŒ" +msgid "could not determine which collation to use for initcap() function" +msgstr "initcap() 함수ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/adt/tsvector_op.c:2501 +#: utils/adt/formatting.c:2148 #, c-format -msgid "column \"%s\" is not of tsvector type" -msgstr "\"%s\" ì¹¼ëŸ¼ì€ tsvector 형ì‹ì´ 아님" +msgid "invalid combination of date conventions" +msgstr "ë‚ ì§œ ë³€í™˜ì„ ìœ„í•œ ìž˜ëª»ëœ ì¡°í•©" -#: utils/adt/tsvector_op.c:2513 +#: utils/adt/formatting.c:2149 #, c-format -msgid "configuration column \"%s\" does not exist" -msgstr "\"%s\" 구성 ì¹¼ëŸ¼ì´ ì—†ìŒ" +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "í˜•ì‹ í…œí”Œë¦¿ì— ê·¸ë ˆê³ ë¦¬ì˜¤ë ¥ê³¼ ISO week date ë³€í™˜ì„ í•¨ê»˜ 사용하지 마십시오." -#: utils/adt/tsvector_op.c:2519 +#: utils/adt/formatting.c:2166 #, c-format -msgid "column \"%s\" is not of regconfig type" -msgstr "\"%s\" ì¹¼ëŸ¼ì€ regconfig í˜•ì´ ì•„ë‹˜" +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "í˜•ì‹ ë¬¸ìžì—´ì—서 \"%s\" í•„ë“œì˜ ê°’ì´ ì¶©ëŒí•¨" -#: utils/adt/tsvector_op.c:2526 +#: utils/adt/formatting.c:2168 #, c-format -msgid "configuration column \"%s\" must not be null" -msgstr "\"%s\" 구성 ì¹¼ëŸ¼ì€ nullì´ ì•„ë‹ˆì–´ì•¼ 함" +msgid "This value contradicts a previous setting for the same field type." +msgstr "ì´ ê°’ì€ ë™ì¼í•œ 필드 형ì‹ì˜ ì´ì „ 설정과 모순ë©ë‹ˆë‹¤." -#: utils/adt/tsvector_op.c:2539 +#: utils/adt/formatting.c:2229 #, c-format -msgid "text search configuration name \"%s\" must be schema-qualified" -msgstr "\"%s\" í…스트 검색 구성 ì´ë¦„ì´ ìŠ¤í‚¤ë§ˆë¡œ 한정ë˜ì–´ì•¼ 함" +msgid "source string too short for \"%s\" formatting field" +msgstr "소스 문ìžì—´ì´ 너무 짧아서 \"%s\" í˜•ì‹ í•„ë“œì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/adt/tsvector_op.c:2564 +#: utils/adt/formatting.c:2231 #, c-format -msgid "column \"%s\" is not of a character type" -msgstr "\"%s\" ì¹¼ëŸ¼ì€ ë¬¸ìží˜•ì´ ì•„ë‹˜" +msgid "Field requires %d characters, but only %d remain." +msgstr "í•„ë“œì— %dìžê°€ í•„ìš”í•œë° %dìžë§Œ 남았습니다." -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format -msgid "syntax error in tsvector: \"%s\"" -msgstr "tsvectorì— êµ¬ë¬¸ 오류가 있ìŒ: \"%s\"" +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "소스 문ìžì—´ì´ ê³ ì • 너비가 아닌 경우 \"FM\" 한정ìžë¥¼ 사용해 보십시오." -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 +#: utils/adt/formatting.c:2387 #, c-format -msgid "there is no escaped character: \"%s\"" -msgstr "ì´ìŠ¤ì¼€ì´í”„ 문ìžê°€ ì—†ìŒ: \"%s\"" +msgid "invalid value \"%s\" for \"%s\"" +msgstr "\"%s\" ê°’ì€ \"%s\"ì— ìœ íš¨í•˜ì§€ 않ìŒ" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/formatting.c:2246 #, c-format -msgid "wrong position info in tsvector: \"%s\"" -msgstr "tsvectorì— ìž˜ëª»ëœ ìœ„ì¹˜ ì •ë³´ê°€ 있ìŒ: \"%s\"" +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "í•„ë“œì— %dìžê°€ í•„ìš”í•œë° %dìžë§Œ 구문 ë¶„ì„í•  수 있습니다." -#: utils/adt/txid.c:339 +#: utils/adt/formatting.c:2259 #, c-format -msgid "invalid input syntax for type txid_snapshot: \"%s\"" -msgstr "txid_snapshot í˜•ì˜ ìž…ë ¥ êµ¬ë¬¸ì´ ìž˜ëª»ë¨: \"%s\"" +msgid "Value must be an integer." +msgstr "ê°’ì€ ì •ìˆ˜ì—¬ì•¼ 합니다." -#: utils/adt/txid.c:534 +#: utils/adt/formatting.c:2264 #, c-format -msgid "invalid external txid_snapshot data" -msgstr "외부 txid_snapshot ê°’ì´ ìž˜ëª»ë¨" +msgid "value for \"%s\" in source string is out of range" +msgstr "소스 문ìžì—´ì˜ \"%s\" ê°’ì´ ë²”ìœ„ë¥¼ 벗어남" -#: utils/adt/uuid.c:145 +#: utils/adt/formatting.c:2266 #, c-format -msgid "invalid input syntax for uuid: \"%s\"" -msgstr "uuidì˜ ìž…ë ¥ êµ¬ë¬¸ì´ ìž˜ëª»ë¨: \"%s\"" +msgid "Value must be in the range %d to %d." +msgstr "ê°’ì€ %dì—서 %d 사ì´ì˜ ë²”ìœ„ì— ìžˆì–´ì•¼ 합니다." -#: utils/adt/varbit.c:57 utils/adt/varchar.c:50 +#: utils/adt/formatting.c:2389 #, c-format -msgid "length for type %s must be at least 1" -msgstr "%s ìžë£Œí˜•ì˜ ê¸¸ì´ëŠ” 최소 1 ì´ìƒì´ì–´ì•¼í•©ë‹ˆë‹¤" +msgid "The given value did not match any of the allowed values for this field." +msgstr "ì§€ì •ëœ ê°’ì´ ì´ í•„ë“œì— í—ˆìš©ë˜ëŠ” ê°’ê³¼ ì¼ì¹˜í•˜ì§€ 않습니다." -#: utils/adt/varbit.c:62 utils/adt/varchar.c:54 +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 +#: utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 +#: utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 +#: utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 +#: utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 +#: utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 #, c-format -msgid "length for type %s cannot exceed %d" -msgstr "%s ìžë£Œí˜•ì˜ ê¸¸ì´ëŠ” 최대 %d ì´í•˜ì—¬ì•¼í•©ë‹ˆë‹¤" +msgid "localized string format value too long" +msgstr "" -#: utils/adt/varbit.c:163 utils/adt/varbit.c:475 utils/adt/varbit.c:973 +#: utils/adt/formatting.c:3084 #, c-format -msgid "bit string length exceeds the maximum allowed (%d)" -msgstr "비트 문ìžì—´ 길ì´ê°€ 최대치 (%d)를 초과했습니다" +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "\"%s\" 필드 ì–‘ì‹ì€ to_char 함수ì—서만 ì§€ì›í•©ë‹ˆë‹¤." -#: utils/adt/varbit.c:177 utils/adt/varbit.c:320 utils/adt/varbit.c:377 +#: utils/adt/formatting.c:3209 #, c-format -msgid "bit string length %d does not match type bit(%d)" -msgstr "" -"길ì´ê°€ %dì¸ ë¹„íŠ¸ 문ìžì—´ ìžë£ŒëŠ” bit(%d) ìžë£Œí˜•ì˜ ê¸¸ì´ì™€ ì¼ì¹˜í•˜ì§€ 않습니다" +msgid "invalid input string for \"Y,YYY\"" +msgstr "\"Y,YYY\"ì— ëŒ€í•œ ìž…ë ¥ 문ìžì—´ì´ 잘못ë¨" -#: utils/adt/varbit.c:199 utils/adt/varbit.c:511 +#: utils/adt/formatting.c:3724 #, c-format -msgid "\"%c\" is not a valid binary digit" -msgstr "\"%c\" 문ìžëŠ” 2진수 문ìžê°€ 아닙니다" +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "시간 \"%d\"ì€(는) 12ì‹œê°„ì œì— ìœ íš¨í•˜ì§€ 않ìŒ" -#: utils/adt/varbit.c:224 utils/adt/varbit.c:536 +#: utils/adt/formatting.c:3726 #, c-format -msgid "\"%c\" is not a valid hexadecimal digit" -msgstr "\"%c\" 문ìžëŠ” 16진수 문ìžê°€ 아닙니다" +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "24시간제를 사용하거나 1ì—서 12 사ì´ì˜ ì‹œê°„ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤." -#: utils/adt/varbit.c:311 utils/adt/varbit.c:627 +#: utils/adt/formatting.c:3832 #, c-format -msgid "invalid length in external bit string" -msgstr "외부 비트 문ìžì—´ì˜ 길ì´ê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" +msgid "cannot calculate day of year without year information" +msgstr "ì—°ë„ ì •ë³´ ì—†ì´ ëª‡ë²ˆì§¸ ë‚ (day of year) ì¸ì§€ 계산할 수 없습니다." -#: utils/adt/varbit.c:489 utils/adt/varbit.c:636 utils/adt/varbit.c:731 +#: utils/adt/formatting.c:4737 #, c-format -msgid "bit string too long for type bit varying(%d)" -msgstr "비트 문ìžì—´ì´ 너무 ê¹ë‹ˆë‹¤(해당 ìžë£Œí˜• bit varying(%d))" +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" ìž…ë ¥ ì–‘ì‹ì€ ì§€ì›ë˜ì§€ 않습니다." -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:842 -#: utils/adt/varlena.c:906 utils/adt/varlena.c:1050 utils/adt/varlena.c:2735 -#: utils/adt/varlena.c:2802 +#: utils/adt/formatting.c:4749 #, c-format -msgid "negative substring length not allowed" -msgstr "substringì—서 ìŒìˆ˜ 길ì´ëŠ” 허용하지 않ìŒ" +msgid "\"RN\" not supported for input" +msgstr "\"RN\" ìž…ë ¥ ì–‘ì‹ì€ ì§€ì›ë˜ì§€ 않습니다." -#: utils/adt/varbit.c:1226 +#: utils/adt/genfile.c:79 #, c-format -msgid "cannot AND bit strings of different sizes" -msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ë¡œ AND ì—°ì‚°ì„ í•  수 없습니다." +msgid "reference to parent directory (\"..\") not allowed" +msgstr "ìƒìœ„ 디렉터리(\"..\") 참조는 허용ë˜ì§€ 않ìŒ" -#: utils/adt/varbit.c:1268 +#: utils/adt/genfile.c:90 #, c-format -msgid "cannot OR bit strings of different sizes" -msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ë¡œ OR ì—°ì‚°ì„ í•  수 없습니다." +msgid "absolute path not allowed" +msgstr "절대 경로는 허용하지 않ìŒ" -#: utils/adt/varbit.c:1315 +#: utils/adt/genfile.c:95 #, c-format -msgid "cannot XOR bit strings of different sizes" -msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ì€ XOR ì—°ì‚°ì„ í•  수 없습니다." +msgid "path must be in or below the current directory" +msgstr "경로는 현재 디렉터리와 ê·¸ 하위 디렉터리여야 합니다." -#: utils/adt/varbit.c:1803 utils/adt/varbit.c:1861 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format -msgid "bit index %d out of valid range (0..%d)" -msgstr "비트 %d ì¸ë±ìŠ¤ì˜ ë²”ìœ„ë¥¼ 벗어남 (0..%d)" +msgid "requested length too large" +msgstr "ìš”ì²­ëœ ê¸¸ì´ê°€ 너무 ê¹ë‹ˆë‹¤" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3002 +#: utils/adt/genfile.c:159 #, c-format -msgid "new bit must be 0 or 1" -msgstr "새 ë¹„íŠ¸ê°’ì€ 0 ë˜ëŠ” 1 ì´ì–´ì•¼í•©ë‹ˆë‹¤" +msgid "could not seek in file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %m" -#: utils/adt/varchar.c:154 utils/adt/varchar.c:307 +#: utils/adt/genfile.c:219 #, c-format -msgid "value too long for type character(%d)" -msgstr "character(%d) ìžë£Œí˜•ì— ë„ˆë¬´ 긴 ìžë£Œë¥¼ 담으려고 합니다." +msgid "must be superuser to read files with adminpack 1.0" +msgstr "adminpack 1.0 확장 ëª¨ë“ˆì„ ì‚¬ìš©í•  때는 파ì¼ì„ ì½ìœ¼ë ¤ë©´ 슈í¼ìœ ì ¸ì—¬ì•¼í•¨" -#: utils/adt/varchar.c:469 utils/adt/varchar.c:623 +#: utils/adt/genfile.c:220 #, c-format -msgid "value too long for type character varying(%d)" -msgstr "character varying(%d) ìžë£Œí˜•ì— ë„ˆë¬´ 긴 ìžë£Œë¥¼ 담으려고 합니다." +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "ëŒ€ì‹ ì— pg_file_read() 내장 함수를 사용할 ê²ƒì„ ê¶Œê³ í•©ë‹ˆë‹¤." -#: utils/adt/varlena.c:1420 utils/adt/varlena.c:1825 +#: utils/adt/geo_ops.c:939 #, c-format -msgid "could not determine which collation to use for string comparison" -msgstr "문ìžì—´ ë¹„êµ ìž‘ì—…ì— ì‚¬ìš©í•  정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" +msgid "invalid line specification: A and B cannot both be zero" +msgstr "ì„  ì •ì˜ê°€ 잘못ë¨: A와 B 둘다 0ì¼ ìˆ˜ëŠ” ì—†ìŒ" -#: utils/adt/varlena.c:1478 utils/adt/varlena.c:1491 +#: utils/adt/geo_ops.c:947 #, c-format -msgid "could not convert string to UTF-16: error code %lu" -msgstr "UTF-16 ì¸ì½”딩으로 문ìžì—´ì„ 변환할 수 ì—†ìŒ: 오류번호 %lu" +msgid "invalid line specification: must be two distinct points" +msgstr "ì„  ì •ì˜ê°€ 잘못ëœ: ë‘ ì ì€ 서로 다른 위치여야 함" -#: utils/adt/varlena.c:1506 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 +#: utils/adt/geo_ops.c:5180 #, c-format -msgid "could not compare Unicode strings: %m" -msgstr "유니코드 문ìžì—´ ë¹„êµ ì‹¤íŒ¨: %m" +msgid "too many points requested" +msgstr "너무 ë§Žì€ ì ë“¤ì´ 요청ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/adt/varlena.c:2880 utils/adt/varlena.c:2911 utils/adt/varlena.c:2947 -#: utils/adt/varlena.c:2990 +#: utils/adt/geo_ops.c:1403 #, c-format -msgid "index %d out of valid range, 0..%d" -msgstr "%d ì¸ë±ìŠ¤ì˜ ë²”ìœ„ë¥¼ 벗어남, 0..%d" +msgid "invalid number of points in external \"path\" value" +msgstr "???\"path\" ì˜ ê°’ì— ìž˜ëª»ëœ ê°¯ìˆ˜ì˜ point들" -#: utils/adt/varlena.c:3925 +#: utils/adt/geo_ops.c:2554 #, c-format -msgid "field position must be greater than zero" -msgstr "필드 위치 ê°’ì€ 0 보다 커야합니다" +msgid "function \"dist_lb\" not implemented" +msgstr "\"dist_lb\" 함수는 구현ë˜ì§€ 않았습니다." -#: utils/adt/varlena.c:4804 +#: utils/adt/geo_ops.c:3014 #, c-format -msgid "unterminated format() type specifier" -msgstr "마무리 ì•ˆëœ format() 형 ì‹ë³„ìž" +msgid "function \"close_sl\" not implemented" +msgstr "\"close_sl\" 함수는 구현ë˜ì§€ 않았습니다." -#: utils/adt/varlena.c:4805 utils/adt/varlena.c:4939 utils/adt/varlena.c:5060 +#: utils/adt/geo_ops.c:3116 #, c-format -msgid "For a single \"%%\" use \"%%%%\"." -msgstr "í•˜ë‚˜ì˜ \"%%\" 문ìžë¥¼ 표시하려면, \"%%%%\" 형태로 사용하세요" +msgid "function \"close_lb\" not implemented" +msgstr "\"close_lb\" 함수는 구현ë˜ì§€ 않았습니다." -#: utils/adt/varlena.c:4937 utils/adt/varlena.c:5058 +#: utils/adt/geo_ops.c:3405 #, c-format -msgid "unrecognized format() type specifier \"%c\"" -msgstr "ì¸ì‹í•  수 없는 format() 형 ì‹ë³„ìž \"%c\"" +msgid "cannot create bounding box for empty polygon" +msgstr "???í´ë¦¬ê³¤ ì—†ì´ ë‹«ížŒ ìƒìžë¥¼ ìƒì„±í•  수 없습니다." -#: utils/adt/varlena.c:4950 utils/adt/varlena.c:5007 +#: utils/adt/geo_ops.c:3486 #, c-format -msgid "too few arguments for format()" -msgstr "format() ìž‘ì—…ì„ ìœ„í•œ ì¸ìžê°€ 너무 ì ìŒ" +msgid "invalid number of points in external \"polygon\" value" +msgstr "???\"polygon\" ê°’ì— ìž˜ëª»ëœ ê°¯ìˆ˜ì˜ point들" -#: utils/adt/varlena.c:5102 utils/adt/varlena.c:5285 +#: utils/adt/geo_ops.c:4011 #, c-format -msgid "number is out of range" -msgstr "수치 범위를 벗어남" +msgid "function \"poly_distance\" not implemented" +msgstr "\"poly_distance\" 함수는 구현ë˜ì§€ 않았습니다." -#: utils/adt/varlena.c:5166 utils/adt/varlena.c:5194 +#: utils/adt/geo_ops.c:4364 #, c-format -msgid "format specifies argument 0, but arguments are numbered from 1" -msgstr "" -"format 함수ì—서 사용할 수 있는 ì¸ìž 위치 번호는 0ì´ ì•„ë‹ˆë¼, 1부터 시작합니다" +msgid "function \"path_center\" not implemented" +msgstr "\"path_center\" 함수는 구현ë˜ì§€ 않았습니다." -#: utils/adt/varlena.c:5187 +#: utils/adt/geo_ops.c:4381 #, c-format -msgid "width argument position must be ended by \"$\"" -msgstr "ë„“ì´ ì¸ìž ìœ„ì¹˜ê°’ì€ \"$\" 문ìžë¡œ ë나야 합니다" +msgid "open path cannot be converted to polygon" +msgstr "닫히지 ì•Šì€ path 는 í´ë¦¬ê³¤ìœ¼ë¡œ 변환할 수 없습니다." -#: utils/adt/varlena.c:5232 +#: utils/adt/geo_ops.c:4630 #, c-format -msgid "null values cannot be formatted as an SQL identifier" -msgstr "null ê°’ì€ SQL ì‹ë³„ìžë¡œ í¬ë©§ë  수 ì—†ìŒ" +msgid "invalid radius in external \"circle\" value" +msgstr "ë¶€ì ì ˆí•œ \"circle\" ê°’ì˜ ë°˜ì§€ë¦„" -#: utils/adt/windowfuncs.c:243 +#: utils/adt/geo_ops.c:5166 #, c-format -msgid "argument of ntile must be greater than zero" -msgstr "ntileì˜ ì¸ìžëŠ” 0보다 커야 함" +msgid "cannot convert circle with radius zero to polygon" +msgstr "ë°˜ì§€ë¦„ì´ 0ì¸ ì›ì€ í´ë¦¬ê³¤ìœ¼ë¡œ 변환할 수 없습니다." -#: utils/adt/windowfuncs.c:465 +#: utils/adt/geo_ops.c:5171 #, c-format -msgid "argument of nth_value must be greater than zero" -msgstr "nth_valueì˜ ì¸ìžëŠ” 0보다 커야 함" +msgid "must request at least 2 points" +msgstr "ì ì–´ë„ 2ê°œì˜ pointë“¤ì´ í•„ìš”í•©ë‹ˆë‹¤." -#: utils/adt/xml.c:171 +#: utils/adt/geo_ops.c:5215 #, c-format -msgid "unsupported XML feature" -msgstr "ì§€ì›ë˜ì§€ 않는 XML 기능" +msgid "cannot convert empty polygon to circle" +msgstr "비어있는 í´ë¦¬ê³¤ì„ ì›ìœ¼ë¡œ 변환할 수 없습니다." -#: utils/adt/xml.c:172 +#: utils/adt/int.c:160 #, c-format -msgid "This functionality requires the server to be built with libxml support." -msgstr "ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ë ¤ë©´ libxml ì§€ì›ìœ¼ë¡œ 서버를 빌드해야 합니다." +msgid "int2vector has too many elements" +msgstr "int2vector 는 너무 ë§Žì€ ìš”ì†Œë¥¼ 가지고 있습니다." -#: utils/adt/xml.c:173 +#: utils/adt/int.c:235 #, c-format -msgid "You need to rebuild PostgreSQL using --with-libxml." -msgstr "--with-libxmlì„ ì‚¬ìš©í•˜ì—¬ PostgreSQLì„ ë‹¤ì‹œ 빌드해야 합니다." +msgid "invalid int2vector data" +msgstr "ìž˜ëª»ëœ int2vector ìžë£Œ" -#: utils/adt/xml.c:192 utils/mb/mbutils.c:523 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format -msgid "invalid encoding name \"%s\"" -msgstr "\"%s\" ì¸ì½”딩 ì´ë¦„ì´ ìž˜ëª»ë¨" +msgid "oidvector has too many elements" +msgstr "oidvectorì— ë„ˆë¬´ ë§Žì€ ìš”ì†Œê°€ 있습니다" -#: utils/adt/xml.c:435 utils/adt/xml.c:440 +#: utils/adt/int.c:1379 utils/adt/int8.c:1309 utils/adt/numeric.c:1412 +#: utils/adt/timestamp.c:5318 utils/adt/timestamp.c:5399 #, c-format -msgid "invalid XML comment" -msgstr "ìž˜ëª»ëœ XML 주ì„" +msgid "step size cannot equal zero" +msgstr "단계 í¬ê¸°ëŠ” 0ì¼ ìˆ˜ ì—†ìŒ" -#: utils/adt/xml.c:569 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 +#: utils/adt/numutils.c:105 #, c-format -msgid "not an XML document" -msgstr "XML 문서가 아님" - -#: utils/adt/xml.c:728 utils/adt/xml.c:751 +msgid "invalid input syntax for integer: \"%s\"" +msgstr "정수 ìžë£Œí˜• 대한 ìž˜ëª»ëœ ìž…ë ¥ 구문: \"%s\"" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 +#: utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 +#: utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 +#: utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 +#: utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 +#: utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 +#: utils/adt/int8.c:1218 utils/adt/int8.c:1253 utils/adt/numeric.c:3169 +#: utils/adt/varbit.c:1655 #, c-format -msgid "invalid XML processing instruction" -msgstr "ìž˜ëª»ëœ XML 처리 명령" +msgid "bigint out of range" +msgstr "bigintì˜ ë²”ìœ„ë¥¼ 벗어났습니다." -#: utils/adt/xml.c:729 +#: utils/adt/int8.c:1266 #, c-format -msgid "XML processing instruction target name cannot be \"%s\"." -msgstr "XML 처리 명령 ëŒ€ìƒ ì´ë¦„ì€ \"%s\"ì¼ ìˆ˜ 없습니다." +msgid "OID out of range" +msgstr "OIDì˜ ë²”ìœ„ë¥¼ 벗어났습니다." -#: utils/adt/xml.c:752 +#: utils/adt/json.c:787 #, c-format -msgid "XML processing instruction cannot contain \"?>\"." -msgstr "XML 처리 명령ì—는 \"?>\"를 í¬í•¨í•  수 없습니다." +msgid "Character with value 0x%02x must be escaped." +msgstr "" -#: utils/adt/xml.c:831 +#: utils/adt/json.c:828 #, c-format -msgid "xmlvalidate is not implemented" -msgstr "xmlvalidateê°€ 구현ë˜ì–´ 있지 않ìŒ" +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" í‘œê¸°ë²•ì€ ë’¤ì— 4ê°œì˜ 16진수가 와야합니다." -#: utils/adt/xml.c:910 +#: utils/adt/json.c:844 #, c-format -msgid "could not initialize XML library" -msgstr "XML ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 초기화할 수 ì—†ìŒ" +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "" -#: utils/adt/xml.c:911 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 #, c-format -msgid "" -"libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgid "Unicode low surrogate must follow a high surrogate." msgstr "" -"libxml2ì— í˜¸í™˜ë˜ì§€ 않는 ë¬¸ìž ìžë£Œí˜• 있ìŒ: sizeof(char)=%u, sizeof(xmlChar)=%u" -#: utils/adt/xml.c:997 +#: utils/adt/json.c:880 utils/adt/json.c:903 #, c-format -msgid "could not set up XML error handler" -msgstr "XML 오류 핸들러를 설정할 수 ì—†ìŒ" +msgid "unsupported Unicode escape sequence" +msgstr "ì§€ì›í•˜ì§€ 않는 유니코드 ì´ìŠ¤ì¼€ì´í”„ ì¡°í•©" -#: utils/adt/xml.c:998 +#: utils/adt/json.c:881 #, c-format -msgid "" -"This probably indicates that the version of libxml2 being used is not " -"compatible with the libxml2 header files that PostgreSQL was built with." -msgstr "" -"ì´ ë¬¸ì œëŠ” PostgreSQL 서버를 만들 때 사용한 libxml2 í—¤ë” íŒŒì¼ì´ í˜¸í™˜ì„±ì´ ì—†ëŠ” " -"것 같습니다." - -#: utils/adt/xml.c:1735 -msgid "Invalid character value." -msgstr "ìž˜ëª»ëœ ë¬¸ìž ê°’ìž…ë‹ˆë‹¤." - -#: utils/adt/xml.c:1738 -msgid "Space required." -msgstr "ê³µê°„ì´ í•„ìš”í•©ë‹ˆë‹¤." - -#: utils/adt/xml.c:1741 -msgid "standalone accepts only 'yes' or 'no'." -msgstr "ë…립 ì‹¤í–‰í˜•ì€ 'yes' ë˜ëŠ” 'no'ë§Œ 허용합니다." +msgid "\\u0000 cannot be converted to text." +msgstr "\\u0000 ê°’ì€ text 형으로 변환할 수 ì—†ìŒ." -#: utils/adt/xml.c:1744 -msgid "Malformed declaration: missing version." -msgstr "ì„ ì–¸ 형ì‹ì´ 잘못ë¨: ë²„ì „ì´ ëˆ„ë½ë˜ì—ˆìŠµë‹ˆë‹¤." +#: utils/adt/json.c:904 +#, c-format +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." +msgstr "서버 ì¸ì½”ë”©ì´ UTF8ì´ ì•„ë‹Œ 경우 007F보다 í° ì½”ë“œ ì§€ì  ê°’ì—는 유니코드 ì´ìŠ¤ì¼€ì´í”„ ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/adt/xml.c:1747 -msgid "Missing encoding in text declaration." -msgstr "í…스트 ì„ ì–¸ì—서 ì¸ì½”ë”©ì´ ëˆ„ë½ë˜ì—ˆìŠµë‹ˆë‹¤." +#: utils/adt/json.c:949 utils/adt/json.c:967 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ ì¡°í•©: \"\\%s\"" -#: utils/adt/xml.c:1750 -msgid "Parsing XML declaration: '?>' expected." -msgstr "XML ì„ ì–¸ 구문 ë¶„ì„ ì¤‘: '?>'ê°€ 필요합니다." +#: utils/adt/json.c:1136 +#, c-format +msgid "The input string ended unexpectedly." +msgstr "ìž…ë ¥ 문ìžì—´ì´ 예ìƒì¹˜ 않게 ë났ìŒ." -#: utils/adt/xml.c:1753 +#: utils/adt/json.c:1150 #, c-format -msgid "Unrecognized libxml error code: %d." -msgstr "ì¸ì‹í•  수 없는 libxml 오류 코드: %d." +msgid "Expected end of input, but found \"%s\"." +msgstr "ìž…ë ¥ ìžë£Œì˜ ëì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ì´ ë” ìžˆìŒ." -#: utils/adt/xml.c:2028 +#: utils/adt/json.c:1161 #, c-format -msgid "XML does not support infinite date values." -msgstr "XMLì€ ë¬´í•œ ë‚ ì§œ ê°’ì„ ì§€ì›í•˜ì§€ 않습니다." +msgid "Expected JSON value, but found \"%s\"." +msgstr "JSON ê°’ì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ìž„" -#: utils/adt/xml.c:2050 utils/adt/xml.c:2077 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format -msgid "XML does not support infinite timestamp values." -msgstr "XMLì€ ë¬´í•œ 타임스탬프 ê°’ì„ ì§€ì›í•˜ì§€ 않습니다." +msgid "Expected string, but found \"%s\"." +msgstr "문ìžì—´ ê°’ì„ ê¸°ëŒ€í–ˆëŠ”ë°, \"%s\" ê°’ìž„" -#: utils/adt/xml.c:2468 +#: utils/adt/json.c:1177 #, c-format -msgid "invalid query" -msgstr "ìž˜ëª»ëœ ì¿¼ë¦¬" +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "\"]\" ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" -#: utils/adt/xml.c:3793 +#: utils/adt/json.c:1185 #, c-format -msgid "invalid array for XML namespace mapping" -msgstr "XML 네임스페ì´ìФ ë§¤í•‘ì— ì‚¬ìš©í•  ë°°ì—´ì´ ìž˜ëª»ë¨" +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\",\" ë˜ëŠ” \"]\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" -#: utils/adt/xml.c:3794 +#: utils/adt/json.c:1193 #, c-format -msgid "" -"The array must be two-dimensional with length of the second axis equal to 2." -msgstr "" -"ì´ ë°°ì—´ì€ key, value로 êµ¬ì„±ëœ ë°°ì—´ì„ ìš”ì†Œë¡œ 하는 2ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "\"}\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" -#: utils/adt/xml.c:3818 +#: utils/adt/json.c:1201 #, c-format -msgid "empty XPath expression" -msgstr "XPath ì‹ì´ 비어 있ìŒ" +msgid "Expected \":\", but found \"%s\"." +msgstr "\":\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" -#: utils/adt/xml.c:3867 +#: utils/adt/json.c:1209 #, c-format -msgid "neither namespace name nor URI may be null" -msgstr "네임스페ì´ìФ ì´ë¦„ ë° URI는 nullì¼ ìˆ˜ ì—†ìŒ" +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\",\" ë˜ëŠ” \"}\"ê°€ í•„ìš”í•œë° \"%s\"ì´(ê°€) 있ìŒ" -#: utils/adt/xml.c:3874 +#: utils/adt/json.c:1247 #, c-format -msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" -msgstr "" -"ì´ë¦„ \"%s\" ë° URI \"%s\"ì„(를) 사용하여 XML 네임스페ì´ìŠ¤ë¥¼ 등ë¡í•  수 ì—†ìŒ" +msgid "Token \"%s\" is invalid." +msgstr "ìž˜ëª»ëœ í† í°: \"%s\"" -# # nonun 부분 end -#: utils/cache/lsyscache.c:2580 utils/cache/lsyscache.c:2613 -#: utils/cache/lsyscache.c:2646 utils/cache/lsyscache.c:2679 +#: utils/adt/json.c:1319 #, c-format -msgid "type %s is only a shell" -msgstr "%s 형ì‹ì€ ì…¸ì¼ ë¿ìž„" +msgid "JSON data, line %d: %s%s%s" +msgstr "JSON ìžë£Œ, %d 번째 줄: %s%s%s" -#: utils/cache/lsyscache.c:2585 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format -msgid "no input function available for type %s" -msgstr "%s ìžë£Œí˜•ì„ ìœ„í•œ ìž…ë ¥ 함수가 없습니다" +msgid "key value must be scalar, not array, composite, or json" +msgstr "키 ê°’ì€ ìŠ¤ì¹¼ë¼ í˜•ì´ì–´ì•¼ 함. ë°°ì—´, 복합 ìžë£Œí˜•, json í˜•ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/cache/lsyscache.c:2618 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format -msgid "no output function available for type %s" -msgstr "%s ìžë£Œí˜•ì„ ìœ„í•œ 출력 함수가 없습니다" +msgid "could not determine data type for argument %d" +msgstr "%d번째 ì¸ìžì˜ ìžë£Œí˜•ì„ ì•Œìˆ˜ê°€ 없습니다." -#: utils/cache/plancache.c:718 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format -msgid "cached plan must not change result type" -msgstr "ìºì‹œëœ 계íšì—서 ê²°ê³¼ 형ì‹ì„ 바꾸지 않아야 함" +msgid "field name must not be null" +msgstr "필드 ì´ë¦„ì´ null ì´ë©´ 안ë©ë‹ˆë‹¤" -#: utils/cache/relcache.c:5226 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format -msgid "could not create relation-cache initialization file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜-ìºì‹œ 초기화 파ì¼ì„ 만들 수 ì—†ìŒ: %m" +msgid "argument list must have even number of elements" +msgstr "ì¸ìž 목ë¡ì€ ìš”ì†Œìˆ˜ì˜ ì§ìˆ˜ê°œì—¬ì•¼ 합니다." -#: utils/cache/relcache.c:5228 +#: utils/adt/json.c:2195 #, c-format -msgid "Continuing anyway, but there's something wrong." -msgstr "어쨌든 계ì†í•˜ëŠ”ë°, 뭔가 잘못 ëœ ê²ƒì´ ìžˆìŠµë‹ˆë‹¤." +msgid "The arguments of json_build_object() must consist of alternating keys and values." +msgstr "json_build_object() í•¨ìˆ˜ì˜ ì¸ìžë“¤ì€ ê°ê° key, value ìŒìœ¼ë¡œ 있어야 합니다." -#: utils/cache/relcache.c:5502 +#: utils/adt/json.c:2210 #, c-format -msgid "could not remove cache file \"%s\": %m" -msgstr "\"%s\" ìºì‰¬ 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" +msgid "argument %d cannot be null" +msgstr "%d 번째 ì¸ìžëŠ” null ì´ë©´ 안ë©ë‹ˆë‹¤" -#: utils/cache/relmapper.c:508 +#: utils/adt/json.c:2211 #, c-format -msgid "cannot PREPARE a transaction that modified relation mapping" -msgstr "릴레ì´ì…˜ ë§µí•‘ì„ ë³€ê²½í•˜ëŠ” íŠ¸ëžœìž­ì…œì„ PREPAREí•  수 ì—†ìŒ" +msgid "Object keys should be text." +msgstr "개체 키는 문ìžì—´ì´ì–´ì•¼ 합니다." -#: utils/cache/relmapper.c:651 utils/cache/relmapper.c:751 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format -msgid "could not open relation mapping file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "array must have two columns" +msgstr "ë°°ì—´ì€ ë‘ê°œì˜ ì¹¼ëŸ¼ì´ì–´ì•¼ 함" -#: utils/cache/relmapper.c:664 +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 +#: utils/adt/jsonb.c:1395 #, c-format -msgid "could not read relation mapping file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" +msgid "null value not allowed for object key" +msgstr "개체 키 값으로 null ì„ í—ˆìš©í•˜ì§€ 않ìŒ" -#: utils/cache/relmapper.c:674 +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 #, c-format -msgid "relation mapping file \"%s\" contains invalid data" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì— ìž˜ëª»ëœ ë°ì´í„°ê°€ 있습니다" +msgid "mismatched array dimensions" +msgstr "ë°°ì—´ 차수가 안맞ìŒ" -#: utils/cache/relmapper.c:684 +#: utils/adt/jsonb.c:258 #, c-format -msgid "relation mapping file \"%s\" contains incorrect checksum" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì— ìž˜ëª»ëœ checksum ê°’ì´ ìžˆìŒ" +msgid "string too long to represent as jsonb string" +msgstr "jsonb 문ìžì—´ë¡œ 길ì´ë¥¼ 초과함" -#: utils/cache/relmapper.c:784 +#: utils/adt/jsonb.c:259 #, c-format -msgid "could not write to relation mapping file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ 쓸 수 없습니다: %m" +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "êµ¬í˜„ìƒ ì œí•œìœ¼ë¡œ jsonb 문ìžì—´ì€ %d ë°”ì´íŠ¸ë¥¼ ë„˜ì„ ìˆ˜ 없습니다." -#: utils/cache/relmapper.c:797 +#: utils/adt/jsonb.c:1147 #, c-format -msgid "could not fsync relation mapping file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ fsync í•  수 ì—†ìŒ: %m" +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "json_build_object() í•¨ìˆ˜ì˜ ì¸ìžë“¤ì€ ê°ê° key, value ìŒìœ¼ë¡œ 있어야 합니다." -#: utils/cache/relmapper.c:803 +#: utils/adt/jsonb.c:1159 #, c-format -msgid "could not close relation mapping file \"%s\": %m" -msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" +msgid "argument %d: key must not be null" +msgstr "%d 번째 ì¸ìž: 키 ê°’ì€ nullì´ë©´ 안ë©ë‹ˆë‹¤." -#: utils/cache/typcache.c:1207 +#: utils/adt/jsonb.c:1747 #, c-format -msgid "type %s is not composite" -msgstr "%s ìžë£Œí˜•ì€ ë³µí•© ìžë£Œí˜•ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "object keys must be strings" +msgstr "개체 키는 문ìžì—´ì´ì–´ì•¼ 합니다" -#: utils/cache/typcache.c:1221 +#: utils/adt/jsonb.c:1910 #, c-format -msgid "record type has not been registered" -msgstr "레코드 형ì‹ì´ 등ë¡ë˜ì§€ 않았ìŒ" +msgid "cannot cast jsonb null to type %s" +msgstr "jsonb null ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/assert.c:34 +#: utils/adt/jsonb.c:1911 #, c-format -msgid "TRAP: ExceptionalCondition: bad arguments\n" -msgstr "TRAP: ExceptionalCondition: ìž˜ëª»ëœ ì¸ìž\n" +msgid "cannot cast jsonb string to type %s" +msgstr "jsonb 문ìžì—´ ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/assert.c:37 +#: utils/adt/jsonb.c:1912 #, c-format -msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" -msgstr "TRAP: %s(\"%s\", 파ì¼: \"%s\", 줄: %d)\n" +msgid "cannot cast jsonb numeric to type %s" +msgstr "jsonb ìˆ«ìž ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/adt/jsonb.c:1913 #, c-format -msgid "error occurred at %s:%d before error message processing is available\n" -msgstr "오류 메시지 처리가 활성화 ë˜ê¸° ì „ì— %s:%d ì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤\n" +msgid "cannot cast jsonb boolean to type %s" +msgstr "jsonb 불린 ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/elog.c:1889 +#: utils/adt/jsonb.c:1914 #, c-format -msgid "could not reopen file \"%s\" as stderr: %m" -msgstr "stderr 로 사용하기 위해 \"%s\" íŒŒì¼ ë‹¤ì‹œ 열기 실패: %m" +msgid "cannot cast jsonb array to type %s" +msgstr "jsonb ë°°ì—´ ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/elog.c:1902 +#: utils/adt/jsonb.c:1915 #, c-format -msgid "could not reopen file \"%s\" as stdout: %m" -msgstr "표준출력(stdout)으로 사용하기 위해 \"%s\" 파ì¼ì„ 여는 ë„중 실패: %m" - -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 -msgid "[unknown]" -msgstr "[알수없ìŒ]" +msgid "cannot cast jsonb object to type %s" +msgstr "jsonb object ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 -msgid "missing error text" -msgstr "오류 ë‚´ìš©ì„ ëºë‹ˆë‹¤" - -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 -#: utils/error/elog.c:3299 +#: utils/adt/jsonb.c:1916 #, c-format -msgid " at character %d" -msgstr " %d 번째 ë¬¸ìž ë¶€ê·¼" - -#: utils/error/elog.c:2898 utils/error/elog.c:2905 -msgid "DETAIL: " -msgstr "ìƒì„¸ì •ë³´: " - -#: utils/error/elog.c:2912 -msgid "HINT: " -msgstr "힌트: " - -#: utils/error/elog.c:2919 -msgid "QUERY: " -msgstr "쿼리:" - -#: utils/error/elog.c:2926 -msgid "CONTEXT: " -msgstr "ë‚´ìš©: " +msgid "cannot cast jsonb array or object to type %s" +msgstr "jsonb object나 ë°°ì—´ ê°’ì„ %s ìžë£Œí˜•으로 형 변환 í•  수 ì—†ìŒ" -#: utils/error/elog.c:2936 +#: utils/adt/jsonb_util.c:657 #, c-format -msgid "LOCATION: %s, %s:%d\n" -msgstr "위치: %s, %s:%d\n" +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "jsonb 개체 ìŒì˜ 개수가 최대치를 초과함 (%zu)" -#: utils/error/elog.c:2943 +#: utils/adt/jsonb_util.c:698 #, c-format -msgid "LOCATION: %s:%d\n" -msgstr "위치: %s:%d\n" - -#: utils/error/elog.c:2957 -msgid "STATEMENT: " -msgstr "명령 구문: " +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "jsonb ë°°ì—´ 요소 개수가 최대치를 초과함 (%zu)" -#. translator: This string will be truncated at 47 -#. characters expanded. -#: utils/error/elog.c:3414 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format -msgid "operating system error %d" -msgstr "ìš´ì˜ì²´ì œ 오류 %d" - -#: utils/error/elog.c:3612 -msgid "DEBUG" -msgstr "디버그" - -#: utils/error/elog.c:3616 -msgid "LOG" -msgstr "로그" - -#: utils/error/elog.c:3619 -msgid "INFO" -msgstr "ì •ë³´" - -#: utils/error/elog.c:3622 -msgid "NOTICE" -msgstr "알림" - -#: utils/error/elog.c:3625 -msgid "WARNING" -msgstr "경고" - -#: utils/error/elog.c:3628 -msgid "ERROR" -msgstr "오류" - -#: utils/error/elog.c:3631 -msgid "FATAL" -msgstr "치명ì ì˜¤ë¥˜" - -#: utils/error/elog.c:3634 -msgid "PANIC" -msgstr "ì†ìƒ" +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "jsonb ë°°ì—´ 요소 ì´ í¬ê¸°ê°€ 최대치를 초과함 (%u ë°”ì´íЏ)" -#: utils/fmgr/dfmgr.c:117 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format -msgid "could not find function \"%s\" in file \"%s\"" -msgstr "\"%s\" 함수를 \"%s\" 파ì¼ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "jsonb 개체 ìš”ì†Œë“¤ì˜ ì´ í¬ê¸°ê°€ 최대치를 초과함 (%u ë°”ì´íЏ)" -#: utils/fmgr/dfmgr.c:196 utils/fmgr/dfmgr.c:405 utils/fmgr/dfmgr.c:453 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3824 #, c-format -msgid "could not access file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì— 액세스할 수 ì—†ìŒ: %m" +msgid "cannot call %s on a scalar" +msgstr "스칼ë¼í˜•ì—서는 %s 호출 í•  수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:234 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format -msgid "could not load library \"%s\": %s" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 불러 올 수 ì—†ìŒ: %s" +msgid "cannot call %s on an array" +msgstr "배열형ì—서는 %s 호출 í•  수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:266 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format -msgid "incompatible library \"%s\": missing magic block" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: magic black ì—†ìŒ" +msgid "cannot get array length of a scalar" +msgstr "스칼ë¼í˜•ì˜ ë°°ì—´ 길ì´ë¥¼ 구할 수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:268 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format -msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." -msgstr "확장 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 만들 때, PG_MODULE_MAGIC 매í¬ë¡œë¥¼ 사용해서 만드세요." +msgid "cannot get array length of a non-array" +msgstr "비배열형 ìžë£Œì˜ ë°°ì—´ 길ì´ë¥¼ 구할 수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:304 +#: utils/adt/jsonfuncs.c:1691 #, c-format -msgid "incompatible library \"%s\": version mismatch" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: ë²„ì „ì´ í‹€ë¦¼" +msgid "cannot call %s on a non-object" +msgstr "비개체형ì—서 %s 호출 í•  수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:306 +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 #, c-format -msgid "Server is version %d.%d, library is version %d.%d." -msgstr "서버 버전 = %d.%d, ë¼ì´ë¸ŒëŸ¬ë¦¬ 버전 %d.%d." +msgid "function returning record called in context that cannot accept type record" +msgstr "반환 ìžë£Œí˜•ì´ recordì¸ë° 함수가 ê·¸ ìžë£Œí˜•으로 반환하지 않ìŒ" -#: utils/fmgr/dfmgr.c:325 +#: utils/adt/jsonfuncs.c:1949 #, c-format -msgid "Server has FUNC_MAX_ARGS = %d, library has %d." -msgstr "ì„œë²„ì˜ ê²½ìš° FUNC_MAX_ARGS = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." +msgid "cannot deconstruct an array as an object" +msgstr "" -#: utils/fmgr/dfmgr.c:334 +#: utils/adt/jsonfuncs.c:1961 #, c-format -msgid "Server has INDEX_MAX_KEYS = %d, library has %d." -msgstr "ì„œë²„ì˜ ê²½ìš° INDEX_MAX_KEYS = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." +msgid "cannot deconstruct a scalar" +msgstr "스칼ë¼í˜•으로 재구축할 수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:343 +#: utils/adt/jsonfuncs.c:2007 #, c-format -msgid "Server has NAMEDATALEN = %d, library has %d." -msgstr "ì„œë²„ì˜ ê²½ìš° NAMEDATALEN = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." +msgid "cannot extract elements from a scalar" +msgstr "스칼ë¼í˜•ì—서 요소를 추출할 수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:352 +#: utils/adt/jsonfuncs.c:2011 #, c-format -msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." -msgstr "ì„œë²„ì˜ ê²½ìš° FLOAT4PASSBYVAL = %sì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %sì´(ê°€) 있습니다." +msgid "cannot extract elements from an object" +msgstr "개체형ì—서 요소를 추출할 수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:361 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3708 #, c-format -msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." -msgstr "ì„œë²„ì˜ ê²½ìš° FLOAT8PASSBYVAL = %sì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %sì´(ê°€) 있습니다." - -#: utils/fmgr/dfmgr.c:368 -msgid "Magic block has unexpected length or padding difference." -msgstr "ë§¤ì§ ë¸”ë¡ì— 예기치 ì•Šì€ ê¸¸ì´ ë˜ëŠ” 여백 ì°¨ì´ê°€ 있습니다." +msgid "cannot call %s on a non-array" +msgstr "비배열형ì—서 %s 호출 í•  수 ì—†ìŒ" -#: utils/fmgr/dfmgr.c:371 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 #, c-format -msgid "incompatible library \"%s\": magic block mismatch" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: magic black 틀림" +msgid "expected JSON array" +msgstr "예기치 ì•Šì€ json ë°°ì—´" -#: utils/fmgr/dfmgr.c:535 +#: utils/adt/jsonfuncs.c:2334 #, c-format -msgid "access to library \"%s\" is not allowed" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ ì‚¬ìš©ì´ ê¸ˆì§€ë˜ì–´ìžˆìŠµë‹ˆë‹¤" +msgid "See the value of key \"%s\"." +msgstr "\"%s\" í‚¤ì˜ ê°’ì„ ì§€ì •í•˜ì„¸ìš”" -#: utils/fmgr/dfmgr.c:561 +#: utils/adt/jsonfuncs.c:2356 #, c-format -msgid "invalid macro name in dynamic library path: %s" -msgstr "ë™ì  ë¼ì´ë¸ŒëŸ¬ë¦¬ 경로ì—서 ìž˜ëª»ëœ ë§¤í¬ë¡œ ì´ë¦„: %s" +msgid "See the array element %s of key \"%s\"." +msgstr "%s ë°°ì—´ 요소, 해당 키: \"%s\" 참조" -#: utils/fmgr/dfmgr.c:601 +#: utils/adt/jsonfuncs.c:2362 #, c-format -msgid "zero-length component in parameter \"dynamic_library_path\"" -msgstr "\"dynamic_library_path\" 매개 변수 값으로 길ì´ê°€ 0ì¸ ê°’ì„ ì‚¬ìš©í–ˆìŒ" +msgid "See the array element %s." +msgstr "ë°°ì—´ 요소: %s 참조" -#: utils/fmgr/dfmgr.c:620 +#: utils/adt/jsonfuncs.c:2397 #, c-format -msgid "component in parameter \"dynamic_library_path\" is not an absolute path" -msgstr "\"dynamic_library_path\" 매개 변수 값으로 절대 경로를 사용할 수 ì—†ìŒ" +msgid "malformed JSON array" +msgstr "ìž˜ëª»ëœ json ë°°ì—´" -#: utils/fmgr/fmgr.c:272 +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format -msgid "internal function \"%s\" is not in internal lookup table" -msgstr "\"%s\" ë‚´ë¶€ 함수를 ë‚´ë¶€ 검색 í…Œì´ë¸”ì—서 ì°¾ì„ ìˆ˜ 없습니다" +msgid "first argument of %s must be a row type" +msgstr "%sì˜ ì²«ë²ˆì§¸ ì¸ìžëŠ” row 형ì´ì–´ì•¼ 합니다" -#: utils/fmgr/fmgr.c:479 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format -msgid "unrecognized API version %d reported by info function \"%s\"" -msgstr "_^_ %d 알수 없는 API ë²„ì „ì´ \"%s\" í•¨ìˆ˜ì— ì˜í•´ì„œ ë³´ê³ ë˜ì—ˆìŒ" +msgid "Try calling the function in the FROM clause using a column definition list." +msgstr "함수를 호출 í•  때 FROM ì ˆì—서 칼럼 ì •ì˜ ëª©ë¡ë„ 함께 지정해야 합니다." -#: utils/fmgr/fmgr.c:849 utils/fmgr/fmgr.c:2106 +#: utils/adt/jsonfuncs.c:3725 utils/adt/jsonfuncs.c:3806 #, c-format -msgid "function %u has too many arguments (%d, maximum is %d)" -msgstr "%u 함수는 너무 ë§Žì€ ì¸ìžë¥¼ 사용하고 ìžˆìŒ (%d, 최대 %d)" +msgid "argument of %s must be an array of objects" +msgstr "%sì˜ ì¸ìžëŠ” ê°œì²´ì˜ ë°°ì—´ì´ì–´ì•¼ 합니다" -#: utils/fmgr/fmgr.c:2527 +#: utils/adt/jsonfuncs.c:3758 #, c-format -msgid "language validation function %u called for language %u instead of %u" -msgstr "" -"%u OID 언어 유효성 검사 함수가 %u OID 프로시져 언어용으로 호출ë˜ì—ˆìŒ, ì›ëž˜ ì–¸" -"어는 %u" +msgid "cannot call %s on an object" +msgstr "개체ì—서 %s 호출할 수 ì—†ìŒ" -#: utils/fmgr/funcapi.c:353 +#: utils/adt/jsonfuncs.c:4235 utils/adt/jsonfuncs.c:4294 +#: utils/adt/jsonfuncs.c:4374 #, c-format -msgid "" -"could not determine actual result type for function \"%s\" declared to " -"return type %s" -msgstr "\"%s\" í•¨ìˆ˜ì˜ ì‹¤ìž¬ 리턴 ìžë£Œí˜•ì„ ì•Œ 수 ì—†ìŒ, ì •ì˜ëœ 리턴 ìžë£Œí˜•: %s" +msgid "cannot delete from scalar" +msgstr "스칼ë¼í˜•ì—서 ì‚­ì œ í•  수 ì—†ìŒ" -#: utils/fmgr/funcapi.c:1340 utils/fmgr/funcapi.c:1371 +#: utils/adt/jsonfuncs.c:4379 #, c-format -msgid "number of aliases does not match number of columns" -msgstr "alias 수가 ì—´ 수와 틀립니다" +msgid "cannot delete from object using integer index" +msgstr "ì¸ë±ìФ 번호를 사용해서 개체ì—서 ì‚­ì œ í•  수 ì—†ìŒ" -#: utils/fmgr/funcapi.c:1365 +#: utils/adt/jsonfuncs.c:4445 utils/adt/jsonfuncs.c:4537 #, c-format -msgid "no column alias was provided" -msgstr "ì—´ ë³„ì¹­ì´ ì œê³µë˜ì§€ 않았ìŒ" +msgid "cannot set path in scalar" +msgstr "스칼ë¼í˜•ì—는 path 를 지정할 수 ì—†ìŒ" -#: utils/fmgr/funcapi.c:1389 +#: utils/adt/jsonfuncs.c:4490 #, c-format -msgid "could not determine row description for function returning record" -msgstr "레코드를 리턴하는 함수를 위한 í–‰(row) 구성 정보를 구할 수 ì—†ìŒ" +msgid "cannot delete path in scalar" +msgstr "스칼ë¼í˜•ì—서 path를 지울 수 ì—†ìŒ" -#: utils/init/miscinit.c:121 +#: utils/adt/jsonfuncs.c:4660 #, c-format -msgid "could not change directory to \"%s\": %m" -msgstr "\"%s\" ì´ë¦„ì˜ ë””ë ‰í„°ë¦¬ë¡œ ì´ë™í•  수 없습니다: %m" +msgid "invalid concatenation of jsonb objects" +msgstr "jsonb ê°œì²´ë“¤ì˜ ìž˜ëª»ëœ ê²°í•©" -#: utils/init/miscinit.c:449 utils/misc/guc.c:6016 +#: utils/adt/jsonfuncs.c:4694 #, c-format -msgid "cannot set parameter \"%s\" within security-restricted operation" -msgstr "보안 제한 작업 ë‚´ì—서 \"%s\" 매개 변수를 설정할 수 ì—†ìŒ" +msgid "path element at position %d is null" +msgstr "%d ìœ„ì¹˜ì˜ path 요소는 null 입니다." -#: utils/init/miscinit.c:510 +#: utils/adt/jsonfuncs.c:4780 #, c-format -msgid "role with OID %u does not exist" -msgstr "%u OID ë¡¤ì´ ì—†ìŒ" +msgid "cannot replace existing key" +msgstr "ì´ë¯¸ 있는 키로는 대체할 수 ì—†ìŒ" -#: utils/init/miscinit.c:540 +#: utils/adt/jsonfuncs.c:4781 #, c-format -msgid "role \"%s\" is not permitted to log in" -msgstr "\"%s\" ë¡¤ì€ ì ‘ì†ì„ 허용하지 않ìŒ" +msgid "Try using the function jsonb_set to replace key value." +msgstr "키 ê°’ì„ ë³€ê²½í•˜ë ¤ë©´, jsonb_set 함수를 사용하세요." -#: utils/init/miscinit.c:558 +#: utils/adt/jsonfuncs.c:4863 #, c-format -msgid "too many connections for role \"%s\"" -msgstr "\"%s\" ë¡¤ì˜ ìµœëŒ€ ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 초과했습니다" +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "%d 번째 ìœ„ì¹˜ì˜ path 요소는 정수가 아님: \"%s\"" -#: utils/init/miscinit.c:618 +#: utils/adt/jsonfuncs.c:4982 #, c-format -msgid "permission denied to set session authorization" -msgstr "세션 ì¸ì¦ì„ 지정하기 위한 ê¶Œí•œì´ ì—†ìŒ" +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "" -#: utils/init/miscinit.c:701 +#: utils/adt/jsonfuncs.c:4989 #, c-format -msgid "invalid role OID: %u" -msgstr "ìž˜ëª»ëœ ë¡¤ OID: %u" +msgid "flag array element is not a string" +msgstr "플래그 ë°°ì—´ 요소가 문ìžì—´ì´ 아님" -#: utils/init/miscinit.c:755 +#: utils/adt/jsonfuncs.c:4990 utils/adt/jsonfuncs.c:5012 #, c-format -msgid "database system is shut down" -msgstr "ë°ì´í„°ë² ì´ìФ 시스템 서비스를 중지했습니다" +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "" -#: utils/init/miscinit.c:842 +#: utils/adt/jsonfuncs.c:5010 #, c-format -msgid "could not create lock file \"%s\": %m" -msgstr "\"%s\" 잠금 파ì¼ì„ 만들 수 ì—†ìŒ: %m" +msgid "wrong flag in flag array: \"%s\"" +msgstr "" -#: utils/init/miscinit.c:856 +#: utils/adt/levenshtein.c:133 #, c-format -msgid "could not open lock file \"%s\": %m" -msgstr "\"%s\" 잠금파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "levenshtein ì¸ìžê°’으로 ê·¸ 길ì´ê°€ %d 문ìžì˜ 최대 길ì´ë¥¼ 초과했ìŒ" -#: utils/init/miscinit.c:862 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5806 #, c-format -msgid "could not read lock file \"%s\": %m" -msgstr "\"%s\" 잠금 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" +msgid "could not determine which collation to use for ILIKE" +msgstr "ILIKE ì—°ì‚°ì—서 사용할 정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/init/miscinit.c:870 +#: utils/adt/like_match.c:107 utils/adt/like_match.c:167 #, c-format -msgid "lock file \"%s\" is empty" -msgstr "\"%s\" 잠금 파ì¼ì´ 비었ìŒ" +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE íŒ¨í„´ì€ ì´ìŠ¤ì¼€ì´í”„ 문ìžë¡œ ë나지 않아야 함" -#: utils/init/miscinit.c:871 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format -msgid "" -"Either another server is starting, or the lock file is the remnant of a " -"previous server startup crash." -msgstr "" +msgid "invalid escape string" +msgstr "ìž˜ëª»ëœ ì´ìŠ¤ì¼€ì´í”„ 문ìžì—´" -#: utils/init/miscinit.c:918 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format -msgid "lock file \"%s\" already exists" -msgstr "\"%s\" 잠금 파ì¼ì´ ì´ë¯¸ 있ìŒ" +msgid "Escape string must be empty or one character." +msgstr "ì´ìŠ¤ì¼€ì´í”„ 문ìžì—´ì€ 비어있거나 í•œê°œì˜ ë¬¸ìžì—¬ì•¼ 합니다." -#: utils/init/miscinit.c:922 +#: utils/adt/lockfuncs.c:664 #, c-format -msgid "Is another postgres (PID %d) running in data directory \"%s\"?" -msgstr "" -"다른 postgres 프로그램(PID %d)ì´ \"%s\" ë°ì´í„° 디렉터리를 사용해서 실행중입니" -"까?" +msgid "cannot use advisory locks during a parallel operation" +msgstr "병렬 작업 중ì—는 ìžë¬¸ ìžê¸ˆì„ 사용할 없습니다" -#: utils/init/miscinit.c:924 +#: utils/adt/mac.c:102 #, c-format -msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" -msgstr "" -"다른 postmaster 프로그램(PID %d)ì´ \"%s\" ë°ì´í„° 디렉터리를 사용해서 실행중입" -"니까?" +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "\"macaddr\"ì— ëŒ€í•œ ìž˜ëª»ëœ ì˜¥í…Ÿ(octet) ê°’: \"%s\"" -#: utils/init/miscinit.c:927 +#: utils/adt/mac8.c:563 #, c-format -msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgid "macaddr8 data out of range to convert to macaddr" msgstr "" -"다른 postgres 프로그램(PID %d)ì´ \"%s\" 소켓 파ì¼ì„ 사용해서 실행중입니까?" -#: utils/init/miscinit.c:929 +#: utils/adt/mac8.c:564 #, c-format -msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." msgstr "" -"다른 postmaster 프로그램(PID %d)ì´ \"%s\" 소켓 파ì¼ì„ 사용해서 실행중입니까?" -#: utils/init/miscinit.c:965 +#: utils/adt/misc.c:239 #, c-format -msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" -msgstr "미리 í™•ë³´ëœ ê³µìœ  메모리 ì˜ì—­ (%lu 키, %lu ID)ì´ ì—¬ì „ížˆ 사용중입니다" +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d í”„ë¡œê·¸ëž¨ì€ PostgreSQL 서버 프로세스가 아닙니다" -#: utils/init/miscinit.c:968 +#: utils/adt/misc.c:290 #, c-format -msgid "" -"If you're sure there are no old server processes still running, remove the " -"shared memory block or just delete the file \"%s\"." -msgstr "" -"확실하게 공유 메모리를 사용하는 다른 프로세스가 없다고 íŒë‹¨ë˜ë©´, 공유 메모리 " -"ì˜ì—­ì„ 삭제하거나 \"%s\" 파ì¼ì„ 지우십시오." +msgid "must be a superuser to cancel superuser query" +msgstr "슈í¼ìœ ì €ì˜ 쿼리를 중지하려면 슈í¼ìœ ì €ì—¬ì•¼ 합니다." -#: utils/init/miscinit.c:984 +#: utils/adt/misc.c:295 #, c-format -msgid "could not remove old lock file \"%s\": %m" -msgstr "\"%s\" 옛 잠금 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "쿼리 작업 취소하려면 작업ìžì˜ ì†Œì† ë§´ë²„ì´ê±°ë‚˜ pg_signal_backend ì†Œì† ë§´ë²„ì—¬ì•¼ 합니다" -#: utils/init/miscinit.c:986 +#: utils/adt/misc.c:314 #, c-format -msgid "" -"The file seems accidentally left over, but it could not be removed. Please " -"remove the file by hand and try again." -msgstr "" -"그파ì¼ì€ 우연찮게 ì™¼ìª½ì„ ë„˜ì–´ê°„ 것(?) 같습지만, ì‚­ì œë  ìˆ˜ëŠ” 없습니다. ì§ì ‘ " -"ì…¸ ëª…ë ¹ì„ ì´ìš©í•´ì„œ 파ì¼ì„ ì‚­ì œ 하고 다시 시ë„í•´ 보십시오. - ë‚´ìš© ì°¸ 거시기 하" -"네" +msgid "must be a superuser to terminate superuser process" +msgstr "슈í¼ìœ ì €ì˜ ì„¸ì…˜ì„ ì •ë¦¬í•˜ë ¤ë©´ 슈í¼ìœ ì €ì—¬ì•¼ 합니다." -#: utils/init/miscinit.c:1022 utils/init/miscinit.c:1033 -#: utils/init/miscinit.c:1043 +#: utils/adt/misc.c:319 #, c-format -msgid "could not write lock file \"%s\": %m" -msgstr "\"%s\" 잠금 파ì¼ì— 쓸 수 ì—†ìŒ: %m" +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "ì„¸ì…˜ì„ ì¢…ë£Œí•˜ë ¤ë©´ ì ‘ì†ìžì˜ ì†Œì† ë§´ë²„ì´ê±°ë‚˜ pg_signal_backend ì†Œì† ë§´ë²„ì—¬ì•¼ 합니다" -#: utils/init/miscinit.c:1172 utils/init/miscinit.c:1301 utils/misc/guc.c:8818 +#: utils/adt/misc.c:336 #, c-format -msgid "could not read from file \"%s\": %m" -msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" +msgid "failed to send signal to postmaster: %m" +msgstr "postmaster로 ì‹œê·¸ë„ ë³´ë‚´ê¸° 실패: %m" -#: utils/init/miscinit.c:1291 +#: utils/adt/misc.c:355 #, c-format -msgid "could not open file \"%s\": %m; continuing anyway" -msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m; 어째든 ê³„ì† ì§„í–‰í•¨" +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "adminpack 1.0 확장 ëª¨ë“ˆì„ ì‚¬ìš©í•˜ë©´ 로그 전환하려면 슈í¼ìœ ì €ì—¬ì•¼ 합니다." -#: utils/init/miscinit.c:1314 +#: utils/adt/misc.c:356 #, c-format -msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" -msgstr "\"%s\" 잠금 파ì¼ì— 있는 PID ê°’ì´ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %ld, ì›ëž˜ê°’ %ld" +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "ëŒ€ì‹ ì— pg_logfile_rotate() 내장 함수를 사용하기를 권고합니다." -#: utils/init/miscinit.c:1356 utils/init/miscinit.c:1369 +#: utils/adt/misc.c:361 utils/adt/misc.c:381 #, c-format -msgid "\"%s\" is not a valid data directory" -msgstr "\"%s\" ê°’ì€ ë°”ë¥¸ ë°ì´í„°ë””렉터리가 아닙니다" +msgid "rotation not possible because log collection not active" +msgstr "로그 ìˆ˜ì§‘ì´ í™œì„± ìƒíƒœê°€ 아니므로 회전할 수 ì—†ìŒ" -#: utils/init/miscinit.c:1358 +#: utils/adt/misc.c:418 #, c-format -msgid "File \"%s\" is missing." -msgstr "\"%s\" 파ì¼ì´ 없습니다." +msgid "global tablespace never has databases" +msgstr "ì „ì—­ í…Œì´ë¸”스페ì´ìŠ¤ëŠ” ë°ì´í„°ë² ì´ìŠ¤ë¥¼ ê²°ì½” í¬í•¨í•˜ì§€ 않습니다." -#: utils/init/miscinit.c:1371 +#: utils/adt/misc.c:439 #, c-format -msgid "File \"%s\" does not contain valid data." -msgstr "\"%s\" 파ì¼ì— ìž˜ëª»ëœ ìžë£Œê°€ 기ë¡ë˜ì–´ 있습니다." +msgid "%u is not a tablespace OID" +msgstr "%u í…Œì´ë¸”스페ì´ìФ OIDê°€ 아님" -#: utils/init/miscinit.c:1373 -#, c-format -msgid "You might need to initdb." -msgstr "initdb ëª…ë ¹ì„ ì‹¤í–‰í•´ 새 í´ëŸ¬ìŠ¤í„°ë¥¼ 만들어야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." +#: utils/adt/misc.c:626 +msgid "unreserved" +msgstr "예약ë˜ì§€ 않ìŒ" + +#: utils/adt/misc.c:630 +msgid "unreserved (cannot be function or type name)" +msgstr "예약ë˜ì§€ 않ìŒ(함수, ìžë£Œí˜• ì´ë¦„ì¼ ìˆ˜ ì—†ìŒ)" + +#: utils/adt/misc.c:634 +msgid "reserved (can be function or type name)" +msgstr "예약ë¨(함수, ìžë£Œí˜• ì´ë¦„ì¼ ìˆ˜ 있ìŒ)" + +#: utils/adt/misc.c:638 +msgid "reserved" +msgstr "예약ë¨" -#: utils/init/miscinit.c:1381 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 +#: utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 #, c-format -msgid "" -"The data directory was initialized by PostgreSQL version %ld.%ld, which is " -"not compatible with this version %s." -msgstr "" -"ì´ ë°ì´í„° 디렉터리는 PostgreSQL %ld.%ld 버전으로 초기화 ë˜ì–´ìžˆëŠ”ë°, ì´ ì„œë²„" -"ì˜ %s ë²„ì „ì€ ì´ ë²„ì „ê³¼ í˜¸í™˜ì„±ì´ ì—†ìŠµë‹ˆë‹¤." +msgid "string is not a valid identifier: \"%s\"" +msgstr "문ìžì—´ì´ 타당한 ì‹ë³„ìžê°€ 아님: \"%s\"" -#: utils/init/miscinit.c:1452 +#: utils/adt/misc.c:814 #, c-format -msgid "loaded library \"%s\"" -msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ 로드 완료" +msgid "String has unclosed double quotes." +msgstr "문ìžì—´ 표기ì—서 í°ë”°ì˜´í‘œ ì§ì´ 안맞습니다." -#: utils/init/postinit.c:251 +#: utils/adt/misc.c:828 #, c-format -msgid "" -"replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" -msgstr "" -"복제 ì—°ê²° ì¸ì¦: 사용ìž=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, ì••ì¶•=%s)" +msgid "Quoted identifier must not be empty." +msgstr "ì¸ìš©ë¶€í˜¸ 있는 ì‹ë³„ìž: 비어있으면 안ë©ë‹ˆë‹¤" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 -msgid "off" -msgstr "off" +#: utils/adt/misc.c:867 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "\".\" ì „ì— íƒ€ë‹¹í•œ ì‹ë³„ìžê°€ ì—†ìŒ" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 -msgid "on" -msgstr "on" +#: utils/adt/misc.c:873 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "\".\" ë’¤ì— íƒ€ë‹¹í•œ ì‹ë³„ìž ì—†ìŒ" -#: utils/init/postinit.c:257 +#: utils/adt/misc.c:934 #, c-format -msgid "replication connection authorized: user=%s" -msgstr "복제 ì—°ê²° ì¸ì¦: 사용ìž=%s" +msgid "log format \"%s\" is not supported" +msgstr "\"%s\" ì–‘ì‹ì˜ 로그는 ì§€ì›í•˜ì§€ 않습니다" -#: utils/init/postinit.c:265 +#: utils/adt/misc.c:935 #, c-format -msgid "" -"connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" +msgid "The supported log formats are \"stderr\" and \"csvlog\"." msgstr "" -"ì—°ê²° ì¸ì¦: 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, ì••" -"ì¶•=%s)" -#: utils/init/postinit.c:271 +#: utils/adt/nabstime.c:137 #, c-format -msgid "connection authorized: user=%s database=%s" -msgstr "ì—°ê²° ì¸ì¦: 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s" +msgid "invalid time zone name: \"%s\"" +msgstr "ìž˜ëª»ëœ íƒ€ìž„ì¡´ ì´ë¦„: \"%s\"" -#: utils/init/postinit.c:303 +#: utils/adt/nabstime.c:482 utils/adt/nabstime.c:555 #, c-format -msgid "database \"%s\" has disappeared from pg_database" -msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” pg_database í•­ëª©ì— ì—†ìŠµë‹ˆë‹¤" +msgid "cannot convert abstime \"invalid\" to timestamp" +msgstr "\"invalid\" abstime ìžë£Œí˜•ì„ timestamp ìžë£Œí˜•으로 변환할 수 없습니다." -#: utils/init/postinit.c:305 +#: utils/adt/nabstime.c:782 #, c-format -msgid "Database OID %u now seems to belong to \"%s\"." -msgstr "ë°ì´í„°ë² ì´ìФ OID %uì´(ê°€) 현재 \"%s\"ì— ì†í•´ 있는 것 같습니다." +msgid "invalid status in external \"tinterval\" value" +msgstr "외부 \"tinterval\" ê°’ì— ìž˜ëª»ëœ ìƒíƒœê°€ 있ìŒ" -#: utils/init/postinit.c:325 +#: utils/adt/nabstime.c:852 #, c-format -msgid "database \"%s\" is not currently accepting connections" -msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” 현재 ì ‘ì†ì„ 허용하지 않습니다" +msgid "cannot convert reltime \"invalid\" to interval" +msgstr "reltime \"invalid\"를 interval로 변환할 수 ì—†ìŒ" -#: utils/init/postinit.c:338 +#: utils/adt/network.c:69 #, c-format -msgid "permission denied for database \"%s\"" -msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 액세스 권한 ì—†ìŒ" +msgid "invalid cidr value: \"%s\"" +msgstr "cidr ìžë£Œí˜•ì— ëŒ€í•œ ìž˜ëª»ëœ ìž…ë ¥: \"%s\"" -#: utils/init/postinit.c:339 +#: utils/adt/network.c:70 utils/adt/network.c:200 #, c-format -msgid "User does not have CONNECT privilege." -msgstr "사용ìžì—게 CONNECT ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤." +msgid "Value has bits set to right of mask." +msgstr "ë§ˆìŠ¤í¬ ì˜¤ë¥¸ìª½ì— ì„¤ì •ëœ ë¹„íŠ¸ê°€ ê°’ì— í¬í•¨ë˜ì–´ 있습니다." -#: utils/init/postinit.c:356 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 +#: utils/adt/network.c:642 #, c-format -msgid "too many connections for database \"%s\"" -msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 최대 ì ‘ì†ìˆ˜ë¥¼ 초과했습니다" +msgid "could not format inet value: %m" +msgstr "inet ê°’ì˜ í˜•ì‹ì„ 지정할 수 ì—†ìŒ: %m" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#. translator: %s is inet or cidr +#: utils/adt/network.c:168 #, c-format -msgid "database locale is incompatible with operating system" -msgstr "ë°ì´í„°ë² ì´ìФ 로케ì¼ì´ ìš´ì˜ ì²´ì œì™€ 호환ë˜ì§€ 않ìŒ" +msgid "invalid address family in external \"%s\" value" +msgstr "잘못 ëœ ì£¼ì†Œêµ° \"%s\"" -#: utils/init/postinit.c:379 +#. translator: %s is inet or cidr +#: utils/adt/network.c:175 #, c-format -msgid "" -"The database was initialized with LC_COLLATE \"%s\", which is not " -"recognized by setlocale()." -msgstr "" -"ë°ì´í„°ë² ì´ìŠ¤ê°€ setlocale()ì—서 ì¸ì‹í•  수 없는 LC_COLLATE \"%s\"(으)로 초기화" -"ë˜ì—ˆìŠµë‹ˆë‹¤." +msgid "invalid bits in external \"%s\" value" +msgstr "\"%s\" ê°’ì— ìž˜ëª»ëœ ë¹„íŠ¸ê°€ 있ìŒ" -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#. translator: %s is inet or cidr +#: utils/adt/network.c:184 #, c-format -msgid "" -"Recreate the database with another locale or install the missing locale." -msgstr "" -"다른 로케ì¼ë¡œ ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 다시 만들거나 누ë½ëœ 로케ì¼ì„ 설치하십시오." +msgid "invalid length in external \"%s\" value" +msgstr "외부 \"%s\" ê°’ì˜ ê¸¸ì´ê°€ 잘못 ë˜ì—ˆìŒ" -#: utils/init/postinit.c:386 +#: utils/adt/network.c:199 #, c-format -msgid "" -"The database was initialized with LC_CTYPE \"%s\", which is not recognized " -"by setlocale()." -msgstr "" -"setlocale()ì—서 ì¸ì‹í•  수 없는 \"%s\" LC_CTYPE 값으로 ë°ì´í„°ë² ì´ìŠ¤ê°€ 초기화ë˜" -"었습니다." +msgid "invalid external \"cidr\" value" +msgstr "외부 \"cidr\" ê°’ì´ ìž˜ëª»ë¨" -#: utils/init/postinit.c:714 +#: utils/adt/network.c:295 utils/adt/network.c:318 #, c-format -msgid "no roles are defined in this database system" -msgstr "ì´ ë°ì´í„°ë² ì´ìФì—는 어떠한 롤 ì •ì˜ë„ 없습니다" +msgid "invalid mask length: %d" +msgstr "ìž˜ëª»ëœ ë§ˆìŠ¤í¬ ê¸¸ì´: %d" -#: utils/init/postinit.c:715 +#: utils/adt/network.c:660 #, c-format -msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." -msgstr "ë‹¤ìŒ ëª…ë ¹ì„ ë¨¼ì € 실행하십시오: CREATE USER \"%s\" SUPERUSER;." +msgid "could not format cidr value: %m" +msgstr "cidr ê°’ì„ ì²˜ë¦¬í•  수 ì—†ìŒ: %m" -#: utils/init/postinit.c:751 +#: utils/adt/network.c:893 #, c-format -msgid "new replication connections are not allowed during database shutdown" -msgstr "ë°ì´í„°ë² ì´ìФ 중지 중ì—는 새로운 복제 ì—°ê²°ì„ í•  수 없습니다." +msgid "cannot merge addresses from different families" +msgstr "서로 다른 페밀리ì—서는 주소를 병합할 수 ì—†ìŒ" -#: utils/init/postinit.c:755 +#: utils/adt/network.c:1309 #, c-format -msgid "must be superuser to connect during database shutdown" -msgstr "슈í¼ìœ ì €ë§Œ ë°ì´í„°ë² ì´ìФ 종료 ì¤‘ì— ì—°ê²°í•  수 있ìŒ" +msgid "cannot AND inet values of different sizes" +msgstr "서로 í¬ê¸°ê°€ 틀린 inet ê°’ë“¤ì€ AND ì—°ì‚°ì„ í•  수 없습니다." -#: utils/init/postinit.c:765 +#: utils/adt/network.c:1341 #, c-format -msgid "must be superuser to connect in binary upgrade mode" -msgstr "슈í¼ìœ ì €ë§Œ ë°”ì´ë„ˆë¦¬ 업그레ì´ë“œ 모드 ì¤‘ì— ì—°ê²° í•  수 있ìŒ" +msgid "cannot OR inet values of different sizes" +msgstr "서로 í¬ê¸°ê°€ 틀린 inet ê°’ë“¤ì€ OR ì—°ì‚°ì„ í•  수 없습니다." -#: utils/init/postinit.c:779 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format -msgid "" -"remaining connection slots are reserved for non-replication superuser " -"connections" -msgstr "ë‚¨ì€ ì—°ê²° ìŠ¬ë¡¯ì€ non-replication 슈í¼ìœ ì € 연결용으로 남겨 놓았ìŒ" +msgid "result is out of range" +msgstr "결과가 범위를 벗어났습니다." -#: utils/init/postinit.c:789 +#: utils/adt/network.c:1443 #, c-format -msgid "must be superuser or replication role to start walsender" -msgstr "" -"superuser ë˜ëŠ” replication ê¶Œí•œì„ ê°€ì§„ 롤만 walsender 프로세스를 시작할 수 있" -"ìŒ" +msgid "cannot subtract inet values of different sizes" +msgstr "inet ê°’ì—서 서로 í¬ê¸°ê°€ 틀리게 부분 추출(subtract)í•  수 ì—†ìŒ" -#: utils/init/postinit.c:858 +#: utils/adt/numeric.c:830 #, c-format -msgid "database %u does not exist" -msgstr "%u ë°ì´í„°ë² ì´ìŠ¤ê°€ ì—†ìŒ" +msgid "invalid sign in external \"numeric\" value" +msgstr "외부 \"numeric\" ê°’ì˜ ë¶€í˜¸ê°€ 잘못ë¨" -#: utils/init/postinit.c:944 +#: utils/adt/numeric.c:836 #, c-format -msgid "It seems to have just been dropped or renamed." -msgstr "ì‚­ì œë˜ì—ˆê±°ë‚˜ ì´ë¦„ì´ ë°”ë€ ê²ƒ 같습니다." +msgid "invalid scale in external \"numeric\" value" +msgstr "외부 \"numeric\" ê°’ì˜ ìž˜ëª»ëœ ìŠ¤ì¼€ì¼" -#: utils/init/postinit.c:962 +#: utils/adt/numeric.c:845 #, c-format -msgid "The database subdirectory \"%s\" is missing." -msgstr "ë°ì´í„°ë² ì´ìФ ë””ë ‰í„°ë¦¬ì— \"%s\" 하위 디렉터리가 없습니다" +msgid "invalid digit in external \"numeric\" value" +msgstr "외부 \"numeric\" ê°’ì˜ ìˆ«ìžê°€ 잘못ë¨" -#: utils/init/postinit.c:967 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format -msgid "could not access directory \"%s\": %m" -msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m" +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "NUMERIC ì •ë°€ë„ %d ê°’ì€ ë²”ìœ„(1 .. %d)를 벗어났습니다." -#: utils/mb/conv.c:405 utils/mb/conv.c:591 +#: utils/adt/numeric.c:1040 #, c-format -msgid "invalid encoding number: %d" -msgstr "ìž˜ëª»ëœ ì¸ì½”딩 번호: %d" +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "NUMERIC ìŠ¤ì¼€ì¼ %d ê°’ì€ ì •ë°€ë„ ë²”ìœ„(0 .. %d)를 벗어났습니다." -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:137 -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:169 +#: utils/adt/numeric.c:1058 #, c-format -msgid "unexpected encoding ID %d for ISO 8859 character sets" -msgstr "%dì€(는) ISO 8859 ë¬¸ìž ì§‘í•©ì— ëŒ€í•œ 예기치 ì•Šì€ ì¸ì½”딩 IDìž„" +msgid "invalid NUMERIC type modifier" +msgstr "ìž˜ëª»ëœ NUMERIC í˜•ì‹ í•œì •ìž" -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:127 -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:159 +#: utils/adt/numeric.c:1390 #, c-format -msgid "unexpected encoding ID %d for WIN character sets" -msgstr "%dì€(는) WIN ë¬¸ìž ì§‘í•©ì— ëŒ€í•œ 예기치 ì•Šì€ ì¸ì½”딩 IDìž„" +msgid "start value cannot be NaN" +msgstr "ì‹œìž‘ê°’ì€ NaN ì¼ ìˆ˜ ì—†ìŒ" -#: utils/mb/encnames.c:496 +#: utils/adt/numeric.c:1395 #, c-format -msgid "encoding name too long" -msgstr "ì¸ì½”딩 ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" +msgid "stop value cannot be NaN" +msgstr "ì¢…ë£Œê°’ì€ NaN ì¼ ìˆ˜ ì—†ìŒ" -#: utils/mb/mbutils.c:307 +#: utils/adt/numeric.c:1405 #, c-format -msgid "conversion between %s and %s is not supported" -msgstr "%s ì¸ì½”딩과 %s ì¸ì½”딩 사ì´ì˜ ë³€í™˜ì€ ì§€ì›í•˜ì§€ 않습니다" +msgid "step size cannot be NaN" +msgstr "단계 í¬ê¸°ëŠ” NaN ì¼ ìˆ˜ ì—†ìŒ" -#: utils/mb/mbutils.c:366 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 +#: utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 +#: utils/adt/numeric.c:8490 #, c-format -msgid "" -"default conversion function for encoding \"%s\" to \"%s\" does not exist" -msgstr "" -"\"%s\" ì¸ì½”ë”©ì„ \"%s\" ì¸ì½”딩으로 변환할 기본 변환규칙(conversion)ì´ ì—†ìŒ" +msgid "value overflows numeric format" +msgstr "ê°’ì´ ìˆ˜ì¹˜ 형ì‹ì— 넘처남" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/adt/numeric.c:3095 #, c-format -msgid "String of %d bytes is too long for encoding conversion." -msgstr "%dë°”ì´íŠ¸ì˜ ë¬¸ìžì—´ì€ 너무 길어서 ì¸ì½”딩 ê·œì¹™ì— ë§žì§€ 않습니다." +msgid "cannot convert NaN to integer" +msgstr "NaN ê°’ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ 변환할 수 없습니다" -#: utils/mb/mbutils.c:464 +#: utils/adt/numeric.c:3161 #, c-format -msgid "invalid source encoding name \"%s\"" -msgstr "\"%s\" ì›ë³¸ ì¸ì½”딩 ì´ë¦„ì´ íƒ€ë‹¹ì¹˜ 못함" +msgid "cannot convert NaN to bigint" +msgstr "NaN ê°’ì„ bigint형으로 변환할 수 없습니다" -#: utils/mb/mbutils.c:469 +#: utils/adt/numeric.c:3206 #, c-format -msgid "invalid destination encoding name \"%s\"" -msgstr "\"%s\" ëŒ€ìƒ ì¸ì½”딩 ì´ë¦„ì´ íƒ€ë‹¹ì¹˜ 못함" +msgid "cannot convert NaN to smallint" +msgstr "NaN ê°’ì„ smallint형으로 변환할 수 없습니다" -#: utils/mb/mbutils.c:609 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 #, c-format -msgid "invalid byte value for encoding \"%s\": 0x%02x" -msgstr "\"%s\" ì¸ì½”딩ì—서 사용할 수 없는 ë°”ì´íЏ: 0x%02x" +msgid "cannot convert infinity to numeric" +msgstr "무한(infinity)ì€ ìˆ«ìžë¡œ 변환할 수 ì—†ìŒ" -#: utils/mb/mbutils.c:951 +#: utils/adt/numeric.c:6240 #, c-format -msgid "bind_textdomain_codeset failed" -msgstr "bind_textdomain_codeset 실패" +msgid "numeric field overflow" +msgstr "수치 필드 오버플로우" -#: utils/mb/wchar.c:2015 +#: utils/adt/numeric.c:6241 #, c-format -msgid "invalid byte sequence for encoding \"%s\": %s" -msgstr "\"%s\" ì¸ì½”딩ì—서 사용할 수 없는 문ìžê°€ 있ìŒ: %s" +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "ì „ì²´ ìžë¦¿ìˆ˜ %d, 소수 ìžë¦¿ìˆ˜ %dì˜ í•„ë“œëŠ” %s%d보다 ìž‘ì€ ì ˆëŒ€ 값으로 반올림해야 합니다." -#: utils/mb/wchar.c:2048 +#: utils/adt/numutils.c:89 #, c-format -msgid "" -"character with byte sequence %s in encoding \"%s\" has no equivalent in " -"encoding \"%s\"" -msgstr "" -"%s ë°”ì´íŠ¸ë¡œ ì¡°í•©ëœ ë¬¸ìž(ì¸ì½”딩: \"%s\")와 대ì‘ë˜ëŠ” ë¬¸ìž ì½”ë“œê°€ \"%s\" ì¸ì½”딩" -"ì—는 없습니다" +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "ê°’ \"%s\"ì€(는) 8비트 ì •ìˆ˜ì˜ ë²”ìœ„ë¥¼ 벗어남" -#: utils/misc/guc.c:548 -msgid "Ungrouped" -msgstr "소ì†ê·¸ë£¹ì—†ìŒ" +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "ìž˜ëª»ëœ oidvector ìžë£Œ" -#: utils/misc/guc.c:550 -msgid "File Locations" -msgstr "íŒŒì¼ ìœ„ì¹˜" +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "ìš”ì²­ëœ ë¬¸ìžê°€ 너무 í¼" -#: utils/misc/guc.c:552 -msgid "Connections and Authentication" -msgstr "ì—°ê²°ê³¼ ì¸ì¦" +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "요청한 문ìžê°€ 너무 커서 ì¸ì½”딩할 수 ì—†ìŒ: %d" -#: utils/misc/guc.c:554 -msgid "Connections and Authentication / Connection Settings" -msgstr "ì—°ê²°ê³¼ ì¸ì¦ / ì—°ê²° 설정값" +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "요청한 문ìžê°€ ì¸ì½”딩용으로 타당치 않ìŒ: %d" -#: utils/misc/guc.c:556 -msgid "Connections and Authentication / Security and Authentication" -msgstr "ì—°ê²°ê³¼ ì•ˆì¦ / 보안과 ì¸ì¦" +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "null 문ìžëŠ” 허용ë˜ì§€ 않ìŒ" -#: utils/misc/guc.c:558 -msgid "Resource Usage" -msgstr "ìžì› 사용량" +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "%g í¼ì„¼íЏ ê°’ì´ 0ê³¼ 1사ì´ê°€ 아닙니다." -#: utils/misc/guc.c:560 -msgid "Resource Usage / Memory" -msgstr "ìžì› 사용량 / 메모리" +#: utils/adt/pg_locale.c:1034 +#, c-format +msgid "Apply system library package updates." +msgstr "OS ë¼ì´ë¸ŒëŸ¬ë¦¬ 패키지를 ì—…ë°ì´íЏ 하세요." -#: utils/misc/guc.c:562 -msgid "Resource Usage / Disk" -msgstr "ìžì› 사용량 / 디스í¬" +#: utils/adt/pg_locale.c:1249 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "\"%s\" 로케ì¼ì„ 만들 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:564 -msgid "Resource Usage / Kernel Resources" -msgstr "ìžì› 사용량 / ì»¤ë„ ìžì›" +#: utils/adt/pg_locale.c:1252 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "ìš´ì˜ì²´ì œì—서 \"%s\" ë¡œì¼€ì¼ ì´ë¦„ì— ëŒ€í•œ ë¡œì¼€ì¼ íŒŒì¼ì„ ì°¾ì„ ìˆ˜ 없습니다." -#: utils/misc/guc.c:566 -msgid "Resource Usage / Cost-Based Vacuum Delay" -msgstr "ìžì› 사용량 / 비용기반 청소 지연" +#: utils/adt/pg_locale.c:1353 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "ì´ í”Œëž«í¼ì—서는 서로 다른 정렬규칙(collation)ê³¼ 문ìžì§‘í•©(ctype)ì„ í•¨ê»˜ 쓸 수 없습니다." -#: utils/misc/guc.c:568 -msgid "Resource Usage / Background Writer" -msgstr "ìžì› 사용량 / 백그ë¼ìš´ë“œ 쓰기" +#: utils/adt/pg_locale.c:1362 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "ì´ í”Œëž«í¼ì—서는 LIBC ë¬¸ìž ì •ë ¬ ì œê³µìž ê¸°ëŠ¥(ICU)ì„ ì§€ì›í•˜ì§€ 않ìŒ." -#: utils/misc/guc.c:570 -msgid "Resource Usage / Asynchronous Behavior" -msgstr "ìžì› 사용량 / 비ë™ê¸° 기능" +#: utils/adt/pg_locale.c:1374 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ICU ì§€ì› ê¸°ëŠ¥ì—서는 서로 다른 정렬규칙(collation)ê³¼ 문ìžì§‘í•©(ctype)ì„ í•¨ê»˜ 쓸 수 없습니다." -#: utils/misc/guc.c:572 -msgid "Write-Ahead Log" -msgstr "Write-Ahead 로그" +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "\"%s\" 로케ì¼ìš© ë¬¸ìž ì •ë ¬ 규칙 열기 실패: %s" -#: utils/misc/guc.c:574 -msgid "Write-Ahead Log / Settings" -msgstr "Write-Ahead 로그 / 설정값" +#: utils/adt/pg_locale.c:1391 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU ì§€ì› ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." -#: utils/misc/guc.c:576 -msgid "Write-Ahead Log / Checkpoints" -msgstr "Write-Ahead 로그 / ì²´í¬í¬ì¸íЏ" +#: utils/adt/pg_locale.c:1392 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "--with-icu ì˜µì…˜ì„ ì‚¬ìš©í•˜ì—¬ PostgreSQLì„ ë‹¤ì‹œ 빌드해야 합니다." -#: utils/misc/guc.c:578 -msgid "Write-Ahead Log / Archiving" -msgstr "Write-Ahead 로그 / ì•„ì¹´ì´ë¸Œ" +#: utils/adt/pg_locale.c:1412 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "\"%s\" ì •ë ¬ê·œì¹™ì€ ë¶„ëª…í•œ ë²„ì „ì´ ì—†ëŠ”ë° ë²„ì „ì„ ì§€ì •í–ˆìŒ" -#: utils/misc/guc.c:580 -msgid "Replication" -msgstr "복제" +#: utils/adt/pg_locale.c:1419 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "\"%s\" ì •ë ¬ê·œì¹™ì€ ë²„ì „ì´ ë§žì§€ 않ìŒ" -#: utils/misc/guc.c:582 -msgid "Replication / Sending Servers" -msgstr "복제 / 보내기 서버" +#: utils/adt/pg_locale.c:1421 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "" -#: utils/misc/guc.c:584 -msgid "Replication / Master Server" -msgstr "복제 / 주 서버" +#: utils/adt/pg_locale.c:1424 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "" -#: utils/misc/guc.c:586 -msgid "Replication / Standby Servers" -msgstr "복제 / 대기 서버" +#: utils/adt/pg_locale.c:1508 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "\"%s\" ì¸ì½”딩용 ICU 변환기 열기 실패: %s" -#: utils/misc/guc.c:588 -msgid "Query Tuning" -msgstr "쿼리 튜ë‹" +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 +#, c-format +msgid "ucnv_toUChars failed: %s" +msgstr "ucnv_toUChars 실패: %s" -#: utils/misc/guc.c:590 -msgid "Query Tuning / Planner Method Configuration" -msgstr "쿼리 íŠœë‹ / 실행계íšê¸° 메서드 설정" +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 +#, c-format +msgid "ucnv_fromUChars failed: %s" +msgstr "ucnv_fromUChars 실패: %s" -#: utils/misc/guc.c:592 -msgid "Query Tuning / Planner Cost Constants" -msgstr "쿼리 íŠœë‹ / 실행계íšê¸° 비용 ìƒìˆ˜" +#: utils/adt/pg_locale.c:1758 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "로케ì¼ì„ 위한 ìž˜ëª»ëœ ë©€í‹°ë°”ì´íЏ 문ìž" -#: utils/misc/guc.c:594 -msgid "Query Tuning / Genetic Query Optimizer" -msgstr "쿼리 íŠœë‹ / ì¼ë°˜ì ì¸ 쿼리 최ì í™”기" +#: utils/adt/pg_locale.c:1759 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "ì„œë²„ì˜ LC_CTYPE 로케ì¼ì€ ì´ ë°ì´í„°ë² ì´ìФ ì¸ì½”딩과 호환ë˜ì§€ 않습니다." -#: utils/misc/guc.c:596 -msgid "Query Tuning / Other Planner Options" -msgstr "쿼리 íŠœë‹ / 기타 실행계íšê¸° 옵션들" +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "함수는 서버가 ì´ì§„ 업그레ì´ë“œ ìƒíƒœì—서만 호출 ë  ìˆ˜ 있습니다" -#: utils/misc/guc.c:598 -msgid "Reporting and Logging" -msgstr "보고와 로그" +#: utils/adt/pgstatfuncs.c:474 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "ìž˜ëª»ëœ ëª…ë ¹ì–´ ì´ë¦„: \"%s\"" -#: utils/misc/guc.c:600 -msgid "Reporting and Logging / Where to Log" -msgstr "보고와 로그 / 로그 위치" +#: utils/adt/pseudotypes.c:247 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "ì…¸ 형태 ê°’ì€ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/misc/guc.c:602 -msgid "Reporting and Logging / When to Log" -msgstr "보고와 로그 / 로그 시ì " +#: utils/adt/pseudotypes.c:260 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "shell 형ì‹ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" -#: utils/misc/guc.c:604 -msgid "Reporting and Logging / What to Log" -msgstr "보고와 로그 / 로그 ë‚´ìš©" +#: utils/adt/pseudotypes.c:350 utils/adt/pseudotypes.c:376 +#, c-format +msgid "cannot output a value of type %s" +msgstr "%s 형ì‹ì˜ ê°’ì€ ì¶œë ¥í•  수 ì—†ìŒ" -#: utils/misc/guc.c:606 -msgid "Process Title" -msgstr "프로세스 제목" +#: utils/adt/pseudotypes.c:403 +#, c-format +msgid "cannot display a value of type %s" +msgstr "%s ìžë£Œí˜•ì˜ ê°’ì€ í‘œì‹œí•  수 ì—†ìŒ" -#: utils/misc/guc.c:608 -msgid "Statistics" -msgstr "통계" +#: utils/adt/rangetypes.c:405 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "range ìžë£Œí˜• êµ¬ì„±ìž í”Œëž˜ê·¸ ì¸ìžë¡œ nullì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: utils/misc/guc.c:610 -msgid "Statistics / Monitoring" -msgstr "통계 / 모니터ë§" +#: utils/adt/rangetypes.c:992 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "" -#: utils/misc/guc.c:612 -msgid "Statistics / Query and Index Statistics Collector" -msgstr "통계 / 쿼리 ë° ì¸ë±ìФ 사용 통계 수집기" +#: utils/adt/rangetypes.c:1053 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "" -#: utils/misc/guc.c:614 -msgid "Autovacuum" -msgstr "Autovacuum" +#: utils/adt/rangetypes.c:1597 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "range ìžë£Œí˜•ì˜ í•˜í•œê°’ì€ ìƒí•œê°’ê³¼ 같거나 작아야 합니다" -#: utils/misc/guc.c:616 -msgid "Client Connection Defaults" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값" +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 +#: utils/adt/rangetypes.c:2007 +#, c-format +msgid "invalid range bound flags" +msgstr "ìž˜ëª»ëœ range 구성 플래그" -#: utils/misc/guc.c:618 -msgid "Client Connection Defaults / Statement Behavior" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 구문 특성" +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "유효한 ê°’ì€ \"[]\", \"[)\", \"(]\", \"()\"." -#: utils/misc/guc.c:620 -msgid "Client Connection Defaults / Locale and Formatting" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 로케ì¼ê³¼ 출력양ì‹" +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 +#: utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 +#: utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 +#: utils/adt/rangetypes.c:2184 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "비정ìƒì ì¸ range 문ìž: \"%s\"" -#: utils/misc/guc.c:622 -msgid "Client Connection Defaults / Shared Library Preloading" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ 미리 로딩" +#: utils/adt/rangetypes.c:2075 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr " \"empty\" 키워드 ë’¤ì— ì •í¬ê°€ 있ìŒ" -#: utils/misc/guc.c:624 -msgid "Client Connection Defaults / Other Defaults" -msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 기타 초기값" +#: utils/adt/rangetypes.c:2092 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "왼쪽 괄호가 빠졌ìŒ" -#: utils/misc/guc.c:626 -msgid "Lock Management" -msgstr "잠금 관리" +#: utils/adt/rangetypes.c:2105 +#, c-format +msgid "Missing comma after lower bound." +msgstr "하한값 ë’¤ì— ì‰¼í‘œê°€ 빠졌ìŒ" -#: utils/misc/guc.c:628 -msgid "Version and Platform Compatibility" -msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„±" +#: utils/adt/rangetypes.c:2123 +#, c-format +msgid "Too many commas." +msgstr "ì¹¼ëŸ¼ì´ ë„ˆë¬´ 많습니다." -#: utils/misc/guc.c:630 -msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" -msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„± / ì´ì „ PostgreSQL 버전" +#: utils/adt/rangetypes.c:2134 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "오른쪽 괄호 다ìŒì— ì •í¬ê°€ 있ìŒ" -#: utils/misc/guc.c:632 -msgid "Version and Platform Compatibility / Other Platforms and Clients" -msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„± / 다른 플랫í¼ê³¼ í´ë¼ì´ì–¸íЏ" +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1420 utils/adt/varlena.c:4105 +#, c-format +msgid "regular expression failed: %s" +msgstr "ìž˜ëª»ëœ ì •ê·œì‹: %s" -#: utils/misc/guc.c:634 -msgid "Error Handling" -msgstr "오류 처리" +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regexp option: \"%c\"" +msgstr "ìž˜ëª»ëœ regexp 옵션: \"%c\"" -#: utils/misc/guc.c:636 -msgid "Preset Options" -msgstr "프리셋 옵션들" +#: utils/adt/regexp.c:866 +#, c-format +msgid "regexp_match does not support the global option" +msgstr "regexp_match는 글로벌 ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/misc/guc.c:638 -msgid "Customized Options" -msgstr "ì‚¬ìš©ìž ì •ì˜ ì˜µì…˜ë“¤" +#: utils/adt/regexp.c:867 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "ëŒ€ì‹ ì— regexp_matches 함수를 사용하세요." -#: utils/misc/guc.c:640 -msgid "Developer Options" -msgstr "ê°œë°œìž ì˜µì…˜ë“¤" +#: utils/adt/regexp.c:1047 +#, c-format +msgid "too many regular expression matches" +msgstr "너무 ë§ŽìŒ ì •ê·œì‹ ë§¤ì¹˜" -#: utils/misc/guc.c:697 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"kB\", \"MB\",\"GB\", \"TB\" 입니다." +#: utils/adt/regexp.c:1240 +#, c-format +msgid "regexp_split_to_table does not support the global option" +msgstr "regexp_split_to_tableì€ ê¸€ë¡œë²Œ ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/misc/guc.c:724 -msgid "" -"Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." -msgstr "" -"ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"ms\", \"s\", \"min\", \"h\", \"d\" 입니다." +#: utils/adt/regexp.c:1293 +#, c-format +msgid "regexp_split_to_array does not support the global option" +msgstr "regexp_splitto_array는 글로벌 ì˜µì…˜ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/misc/guc.c:783 -msgid "Enables the planner's use of sequential-scan plans." -msgstr "실행계íšìžê°€ 순차ì -스캔(sequential-sca) 계íšì„ 사용함" +#: utils/adt/regproc.c:106 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "\"%s\"(ì´)ë¼ëŠ” 함수가 ë‘ ê°œ ì´ìƒ 있ìŒ" -#: utils/misc/guc.c:792 -msgid "Enables the planner's use of index-scan plans." -msgstr "실행계íšìžê°€ ì¸ë±ìФ-스캔 계íšì„ 사용함." +#: utils/adt/regproc.c:524 +#, c-format +msgid "more than one operator named %s" +msgstr "%s(ì´)ë¼ëŠ” ì—°ì‚°ìžê°€ ë‘ ê°œ ì´ìƒ 있ìŒ" -#: utils/misc/guc.c:801 -msgid "Enables the planner's use of index-only-scan plans." -msgstr "실행계íšìžê°€ ì¸ë±ìФ-ì „ìš©-íƒìƒ‰ 계íšì„ 사용함." +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9132 utils/adt/ruleutils.c:9300 +#, c-format +msgid "too many arguments" +msgstr "ì¸ìžê°€ 너무 많습니다" -#: utils/misc/guc.c:810 -msgid "Enables the planner's use of bitmap-scan plans." -msgstr "실행계íšê¸°ê°€ bitmap-scan 계íšì„ 사용하ë„ë¡ í•¨" +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 +#, c-format +msgid "Provide two argument types for operator." +msgstr "ì—°ì‚°ìžë¥¼ 위해서는 ë‘ê°œì˜ ì¸ìž ìžë£Œí˜•ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤." -#: utils/misc/guc.c:819 -msgid "Enables the planner's use of TID scan plans." -msgstr "실행계íšìžê°€ TID 스캔 계íšì„ 사용함" +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 +#, c-format +msgid "invalid name syntax" +msgstr "ìž˜ëª»ëœ ì´ë¦„ 구문" -#: utils/misc/guc.c:828 -msgid "Enables the planner's use of explicit sort steps." -msgstr "실행계íšìžê°€ 명시 ì •ë ¬ 단계(explicit sort step)를 사용함" +#: utils/adt/regproc.c:1763 +#, c-format +msgid "expected a left parenthesis" +msgstr "왼쪽 괄호가 필요합니다." -#: utils/misc/guc.c:837 -msgid "Enables the planner's use of hashed aggregation plans." -msgstr "실행계íšìžê°€ í•´ì‹œëœ ì§‘ê³„ 계íšì„ 사용함" +#: utils/adt/regproc.c:1779 +#, c-format +msgid "expected a right parenthesis" +msgstr "오른쪽 괄호가 필요합니다." -#: utils/misc/guc.c:846 -msgid "Enables the planner's use of materialization." -msgstr "실행계íšìžê°€ materialization 계íšì„ 사용함" +#: utils/adt/regproc.c:1798 +#, c-format +msgid "expected a type name" +msgstr "ìžë£Œí˜• ì´ë¦„ì„ ì§€ì •í•˜ì‹­ì‹œì˜¤" -#: utils/misc/guc.c:855 -msgid "Enables the planner's use of nested-loop join plans." -msgstr "실행계íšìžê°€ 근접순환 ì¡°ì¸(nested-loop join) 계íšì„ 사용함" +#: utils/adt/regproc.c:1830 +#, c-format +msgid "improper type name" +msgstr "ë¶€ì ì ˆí•œ í˜•ì‹ ì´ë¦„" -#: utils/misc/guc.c:864 -msgid "Enables the planner's use of merge join plans." -msgstr "실행계íšìžê°€ 병합 ì¡°ì¸(merge join) 계íšì„ 사용함" +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 +#: utils/adt/ri_triggers.c:2842 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì—서 ìžë£Œ 추가, 갱신 ìž‘ì—…ì´ \"%s\" 참조키(foreign key) 제약 ì¡°ê±´ì„ ìœ„ë°°í–ˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:873 -msgid "Enables the planner's use of hash join plans." -msgstr "실행계íšìžê°€ 해시 ì¡°ì¸(hash join) 계íšì„ 사용함" +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULLì— null 키 ê°’ê³¼ nonnull 키 ê°’ì„ í•¨ê»˜ 사용할 수 없습니다." -#: utils/misc/guc.c:883 -msgid "Enables genetic query optimization." -msgstr "ìœ ì „ì  ì¿¼ë¦¬ 최ì í™”(GEQO)를 사용함" +#: utils/adt/ri_triggers.c:2273 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "INSERTì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" -#: utils/misc/guc.c:884 -msgid "This algorithm attempts to do planning without exhaustive searching." -msgstr "ì´ ì•Œê³ ë¦¬ì¦˜ì€ ì‹¤í–‰ê³„íšê¸°ì˜ ê³¼ë„한 작업 ë¹„ìš©ì„ ë‚®ì¶¥ë‹ˆë‹¤" +#: utils/adt/ri_triggers.c:2279 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "UPDATEì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" -#: utils/misc/guc.c:894 -msgid "Shows whether the current user is a superuser." -msgstr "현재 사용ìžê°€ 슈í¼ìœ ì €ì¸ì§€ ë³´ì—¬ì¤ë‹ˆë‹¤." +#: utils/adt/ri_triggers.c:2285 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "DELETEì— ëŒ€í•´ \"%s\" 함수를 실행해야 함" -#: utils/misc/guc.c:904 -msgid "Enables advertising the server via Bonjour." -msgstr "Bonjour 서버 사용" +#: utils/adt/ri_triggers.c:2308 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "\"%s\" 트리거(해당 í…Œì´ë¸”: \"%s\")ì— ëŒ€í•œ pg_constraint í•­ëª©ì´ ì—†ìŒ" -#: utils/misc/guc.c:913 -msgid "Collects transaction commit time." -msgstr "트랜잭션 커밋 ì‹œê°„ì„ ìˆ˜ì§‘í•¨" +#: utils/adt/ri_triggers.c:2310 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "해당 트리거 관련 개체를 제거한 후 ALTER TABLE ADD CONSTRAINT 명령으로 추가하세요" -#: utils/misc/guc.c:922 -msgid "Enables SSL connections." -msgstr "SSL ì—°ê²°ì„ ê°€ëŠ¥í•˜ê²Œ 함." +#: utils/adt/ri_triggers.c:2689 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "\"%s\"ì— ëŒ€í•œ 참조 무결성 쿼리(제약조건: \"%s\", 해당 릴레ì´ì…˜: \"%s\")를 실행하면 예기치 ì•Šì€ ê²°ê³¼ê°€ ë°œìƒí•¨" -#: utils/misc/guc.c:931 -msgid "Give priority to server ciphersuite order." -msgstr "SSL ì¸ì¦ 알고리즘 ìš°ì„  순위를 정함" +#: utils/adt/ri_triggers.c:2693 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "ì´ ë¬¸ì œëŠ” 주로 ë£°ì´ ìž¬ìž‘ì„± ë˜ì—ˆì„ 때 ë°œìƒí•©ë‹ˆë‹¤." -#: utils/misc/guc.c:940 -msgid "Forces synchronization of updates to disk." -msgstr "강제로 ë³€ê²½ëœ ë²„í¼ ìžë£Œë¥¼ 디스í¬ì™€ ë™ê¸°í™” 시킴." +#: utils/adt/ri_triggers.c:2846 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "(%s)=(%s) 키가 \"%s\" í…Œì´ë¸”ì— ì—†ìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:941 -msgid "" -"The server will use the fsync() system call in several places to make sure " -"that updates are physically written to disk. This insures that a database " -"cluster will recover to a consistent state after an operating system or " -"hardware crash." -msgstr "" -"ì´ ì„œë²„ëŠ” fsync() 시스템 콜 ê¸°ëŠ¥ì„ ì—¬ëŸ¬ ê³³ì—서 사용할 것입니다. ì´ ê¸°ëŠ¥ì€ ë¬¼" -"리ì ìœ¼ë¡œ 디스í¬ì— ë³€ê²½ëœ ìžë£Œë¥¼ 즉ê°ì ìœ¼ë¡œ 기ë¡í•¨ì„ ì˜ë¯¸í•©ë‹ˆë‹¤. ì´ ê¸°ëŠ¥ì€ ì‹œ" -"ìŠ¤í…œì˜ ë¹„ì •ìƒì ì¸ ë™ìž‘ì´ë‚˜, 하드웨어ì—서 오류가 ë°œìƒë˜ì—ˆì„ 경우ì—ë„ ìžë£Œë¥¼ 안" -"전하게 지킬 수 있ë„ë¡ ë„와줄 것입니다." +#: utils/adt/ri_triggers.c:2849 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "\"%s\" í…Œì´ë¸”ì— í‚¤ê°€ 없습니다." -#: utils/misc/guc.c:952 -msgid "Continues processing after a checksum failure." -msgstr "ì²´í¬ì„¬ 실패 후 처리 ê³„ì† í•¨" +#: utils/adt/ri_triggers.c:2855 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì˜ ìžë£Œ 갱신, ì‚­ì œ ìž‘ì—…ì´ \"%s\" 참조키(foreign key) 제약 ì¡°ê±´ - \"%s\" í…Œì´ë¸” - ì„ ìœ„ë°˜í–ˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:953 -msgid "" -"Detection of a checksum failure normally causes PostgreSQL to report an " -"error, aborting the current transaction. Setting ignore_checksum_failure to " -"true causes the system to ignore the failure (but still report a warning), " -"and continue processing. This behavior could cause crashes or other serious " -"problems. Only has an effect if checksums are enabled." -msgstr "" -"ì¼ë°˜ì ìœ¼ë¡œ ì†ìƒëœ 페ì´ì§€ í—¤ë”를 발견하게 ë˜ë©´, PostgreSQLì—서는 오류를 ë°œìƒí•˜" -"ê³ , 현재 íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•©ë‹ˆë‹¤. ignore_checksum_failure ê°’ì„ true로 지정하" -"ë©´, ì´ëŸ° ì†ìƒëœ 페ì´ì§€ë¥¼ 발견하면, 경고 메시지를 보여주고, ê³„ì† ì§„í–‰í•©ë‹ˆë‹¤. " -"ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•œë‹¤ í•¨ì€ ì„œë²„ ë¹„ì •ìƒ ì¢…ë£Œë‚˜ 기타 심ê°í•œ 문제가 ì¼ì–´ ë‚  수 있습" -"니다. ì´ ì„¤ì •ì€ ë°ì´í„° í´ëŸ¬ìŠ¤í„°ì—서 ì²´í¬ì„¬ ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì–´ 있는 경우ì—ë§Œ " -"ì˜í–¥ì„ 받습니다." +#: utils/adt/ri_triggers.c:2860 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "(%s)=(%s) 키가 \"%s\" í…Œì´ë¸”ì—서 여전히 참조ë©ë‹ˆë‹¤." -#: utils/misc/guc.c:967 -msgid "Continues processing past damaged page headers." -msgstr "ì†ìƒëœ ìžë£Œ í—¤ë” ë°œê²¬ì‹œ 작업 ì§„í–‰ 여부 ì„ íƒ" +#: utils/adt/ri_triggers.c:2863 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "\"%s\" í…Œì´ë¸”ì—서 키가 여전히 참조ë©ë‹ˆë‹¤." -#: utils/misc/guc.c:968 -msgid "" -"Detection of a damaged page header normally causes PostgreSQL to report an " -"error, aborting the current transaction. Setting zero_damaged_pages to true " -"causes the system to instead report a warning, zero out the damaged page, " -"and continue processing. This behavior will destroy data, namely all the " -"rows on the damaged page." -msgstr "" -"ì¼ë°˜ì ìœ¼ë¡œ ì†ìƒëœ 페ì´ì§€ í—¤ë”를 발견하게 ë˜ë©´, PostgreSQLì—서는 오류를 ë°œìƒí•˜" -"ê³ , 현재 íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•©ë‹ˆë‹¤. ì´ ê°’ì„ true로 지정하면, ì´ëŸ° ì†ìƒëœ 페ì´ì§€" -"를 발견하면, 경고 메시지를 보여주고, ê·¸ 페ì´ì§€ì˜ í¬ê¸°ë¥¼ 0으로 만들고 ìž‘ì—…ì„ " -"ê³„ì† ì§„í–‰í•©ë‹ˆë‹¤. ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•œë‹¤ í•¨ì€ ì†ìƒëœ ìžë£Œë¥¼ 없애겠다는 ê²ƒì„ ì˜ë¯¸í•©" -"니다. ì´ê²ƒì€ ê³§ 저장ë˜ì–´ìžˆëŠ” ìžë£Œê°€ ì‚­ì œ ë  ìˆ˜ë„ ìžˆìŒì„ ì˜ë¯¸í•˜ê¸°ë„ 합니다." - -#: utils/misc/guc.c:981 -msgid "Writes full pages to WAL when first modified after a checkpoint." -msgstr "ì²´í¬í¬ì¸íЏ 후 ì²˜ìŒ ìˆ˜ì •í•  때 ì „ì²´ 페ì´ì§€ë¥¼ WALì— ì”니다." +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "ìµëª… 복합 형ì‹ì˜ ìž…ë ¥ì´ êµ¬í˜„ë˜ì–´ 있지 않ìŒ" -#: utils/misc/guc.c:982 -msgid "" -"A page write in process during an operating system crash might be only " -"partially written to disk. During recovery, the row changes stored in WAL " -"are not enough to recover. This option writes pages when first modified " -"after a checkpoint to WAL so full recovery is possible." -msgstr "" -"ìš´ì˜ ì²´ì œê°€ ë¹„ì •ìƒ ì¢…ë£Œë˜ëŠ” 경우 처리 ì¤‘ì¸ íŽ˜ì´ì§€ 쓰기는 디스í¬ì— ì¼ë¶€ë§Œ 기ë¡" -"ë  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 복구 중 WALì— ì €ìž¥ëœ ë¡œìš° 변경 ë‚´ìš©ì´ ë¶€ì¡±í•˜ì—¬ 복구할 수 " -"ì—†ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ì´ ì˜µì…˜ì€ ì•ˆì „í•˜ê²Œ 복구가 가능하ë„ë¡ ì²´í¬í¬ì¸íЏ 후 ì²˜ìŒ " -"수정한 페ì´ì§€ëŠ” ê·¸ 페ì´ì§€ 전체를 WALì— ì”니다." +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 +#: utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "비정ìƒì ì¸ 레코드 문ìž: \"%s\"" -#: utils/misc/guc.c:995 -msgid "" -"Writes full pages to WAL when first modified after a checkpoint, even for a " -"non-critical modifications." -msgstr "" -"ì²´í¬í¬ì¸íЏ 작업 후 ìžë£Œ 페ì´ì§€ì— 첫 ë³€ê²½ì´ ìžˆëŠ” 경우, WALì— ë³€ê²½ëœ ë‚´ìš©ë§Œ 기" -"ë¡í•˜ëŠ” ê²ƒì´ ì•„ë‹ˆë¼, 해당 페ì´ì§€ 전체를 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/rowtypes.c:156 +#, c-format +msgid "Missing left parenthesis." +msgstr "왼쪽 괄호가 필요합니다." -#: utils/misc/guc.c:1005 -msgid "Compresses full-page writes written in WAL file." -msgstr "WAL 파ì¼ì— 기ë¡ë˜ëŠ” ì „ì²´ 페ì´ì§€ë¥¼ 압축함" +#: utils/adt/rowtypes.c:185 +#, c-format +msgid "Too few columns." +msgstr "ì¹¼ëŸ¼ì´ ë„ˆë¬´ ì ìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:1015 -msgid "Logs each checkpoint." -msgstr "ì²´í¬í¬ì¸íЏ 관련 정보를 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/rowtypes.c:268 +#, c-format +msgid "Too many columns." +msgstr "ì¹¼ëŸ¼ì´ ë„ˆë¬´ 많습니다." -#: utils/misc/guc.c:1024 -msgid "Logs each successful connection." -msgstr "ì—°ê²° 성공한 정보들 모ë‘를 기ë¡í•¨" +#: utils/adt/rowtypes.c:276 +#, c-format +msgid "Junk after right parenthesis." +msgstr "오른쪽 괄호가 필요합니다." -#: utils/misc/guc.c:1033 -msgid "Logs end of a session, including duration." -msgstr "ê¸°ê°„ì„ í¬í•¨í•˜ì—¬ ì„¸ì…˜ì˜ ëì„ ê¸°ë¡í•©ë‹ˆë‹¤." +#: utils/adt/rowtypes.c:530 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "ì—´ 수(%d)ê°€ 최대값(%d)ì„ ì´ˆê³¼í–ˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:1042 -msgid "Logs each replication command." -msgstr "복제 관련 작업 ë‚´ì—­ì„ ê¸°ë¡í•©ë‹ˆë‹¤." +#: utils/adt/rowtypes.c:558 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "ìž˜ëª»ëœ ìžë£Œí˜•: %u, 예ìƒë˜ëŠ” ìžë£Œí˜• %u" -#: utils/misc/guc.c:1051 -msgid "Shows whether the running server has assertion checks enabled." -msgstr "서버가 assertion 검사 ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì–´ 실행ë˜ëŠ”ì§€ ë³´ì—¬ 줌" +#: utils/adt/rowtypes.c:619 +#, c-format +msgid "improper binary format in record column %d" +msgstr "%d 번째 레코드 ì—´ì—서 ìž˜ëª»ëœ ë°”ì´ë„ˆë¦¬ í¬ë§·ì´ 있습니다" -#: utils/misc/guc.c:1066 -msgid "Terminate session on any error." -msgstr "ì–´ë–¤ 오류가 ìƒê¸°ë©´ ì„¸ì…˜ì„ ì¢…ë£Œí•¨" +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 +#: utils/adt/rowtypes.c:1657 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "서로 다른 ì—´ í˜•ì‹ %sê³¼(와) %s(레코드 ì—´ %d)ì„(를) 비êµí•  수 ì—†ìŒ" -#: utils/misc/guc.c:1075 -msgid "Reinitialize server after backend crash." -msgstr "백엔드가 ë¹„ì •ìƒ ì¢…ë£Œë˜ë©´ 서버를 재초기화함" +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 +#: utils/adt/rowtypes.c:1731 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "칼럼 수가 서로 다른 레코드 ìžë£Œí˜•ì„ ë¹„êµí•  수 ì—†ìŒ" -#: utils/misc/guc.c:1085 -msgid "Logs the duration of each completed SQL statement." -msgstr "SQL 명령 êµ¬ë¬¸ì˜ ì‹¤í–‰ì™„ë£Œ ì‹œê°„ì„ ê¸°ë¡í•¨" +#: utils/adt/ruleutils.c:4823 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "\"%s\" ë£°ì€ %d ì´ë²¤íЏ 형태를 ì§€ì›í•˜ì§€ 않습니다" -#: utils/misc/guc.c:1094 -msgid "Logs each query's parse tree." -msgstr "ê° ì¿¼ë¦¬ì˜ êµ¬ë¬¸ ë¶„ì„ íŠ¸ë¦¬ë¥¼ 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/selfuncs.c:5791 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "bytea 형ì‹ì—서는 대/소문ìžë¥¼ 구분하지 않는 ì¼ì¹˜ê°€ ì§€ì›ë˜ì§€ 않ìŒ" -#: utils/misc/guc.c:1103 -msgid "Logs each query's rewritten parse tree." -msgstr "ê° ì¿¼ë¦¬ì˜ ìž¬ìž‘ì„±ëœ êµ¬ë¬¸ ë¶„ì„ íŠ¸ë¦¬ë¥¼ 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/selfuncs.c:5893 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "bytea 형ì‹ì—서는 ì •ê·œì‹ ì¼ì¹˜ê°€ ì§€ì›ë˜ì§€ 않ìŒ" -#: utils/misc/guc.c:1112 -msgid "Logs each query's execution plan." -msgstr "ê° ì¿¼ë¦¬ì˜ ì‹¤í–‰ 계íšì„ 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s ì •ë°€ë„로 ìŒìˆ˜ë¥¼ 사용할 수 없습니다" -#: utils/misc/guc.c:1121 -msgid "Indents parse and plan tree displays." -msgstr "구문과 실행계íšì„ ë³´ì—¬ 줄때, 들여쓰기를 함." +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%s ì •ë°€ë„는 최대값(%d)으로 줄였습니다" -#: utils/misc/guc.c:1130 -msgid "Writes parser performance statistics to the server log." -msgstr "êµ¬ë¬¸ë¶„ì„ ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: \"%s\"" -#: utils/misc/guc.c:1139 -msgid "Writes planner performance statistics to the server log." -msgstr "실행계íšìž 성능 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 +#: utils/adt/timestamp.c:941 +#, c-format +msgid "date/time value \"%s\" is no longer supported" +msgstr "ë‚ ì§œ/시간 ê°’ \"%s\"ì€(는) ë” ì´ìƒ ì§€ì›ë˜ì§€ 않ìŒ" -#: utils/misc/guc.c:1148 -msgid "Writes executor performance statistics to the server log." -msgstr "ì‹¤í–‰ìž ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." +#: utils/adt/timestamp.c:362 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "타임스탬프(%d) ì •ë°€ë„는 %dì—서 %d 사ì´ì—¬ì•¼ 함" -#: utils/misc/guc.c:1157 -msgid "Writes cumulative performance statistics to the server log." -msgstr "ëˆ„ì  ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." +#: utils/adt/timestamp.c:484 +#, c-format +msgid "invalid input syntax for numeric time zone: \"%s\"" +msgstr "숫ìží˜• 타임 ì¡´ ìž…ë ¥ì— ë¬¸ë²• 오류가 있ìŒ: \"%s\"" -#: utils/misc/guc.c:1167 -msgid "" -"Logs system resource usage statistics (memory and CPU) on various B-tree " -"operations." -msgstr "다양한 B트리 ìž‘ì—…ì— ìžì›(메모리, CPU) 사용 통계를 기ë¡ì— 남기" +#: utils/adt/timestamp.c:486 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "숫ìží˜• 타임 ì¡´ 형ì‹ì€ 처ìŒì— \"-\" ë˜ëŠ” \"+\" 문ìžê°€ 있어야 합니다." -#: utils/misc/guc.c:1179 -msgid "Collects information about executing commands." -msgstr "명령 ì‹¤í–‰ì— ëŒ€í•œ 정보를 수집함" +#: utils/adt/timestamp.c:499 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "\"%s\" 숫ìží˜• 타임 ì¡´ 범위 벗어남" -#: utils/misc/guc.c:1180 -msgid "" -"Enables the collection of information on the currently executing command of " -"each session, along with the time at which that command began execution." -msgstr "" -"ê° ì„¸ì…˜ì—서 사용하고 있는 현재 실행 ì¤‘ì¸ ëª…ë ¹ì˜ ìˆ˜í–‰ 시간, 명령 ë‚´ìš©ë“±ì— ëŒ€" -"한 정보를 수집하ë„ë¡ í•¨" +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: %d-%02d-%02d %d:%02d:%02g" -#: utils/misc/guc.c:1190 -msgid "Collects statistics on database activity." -msgstr "ë°ì´í„°ë² ì´ìФ 활ë™ì— 대한 통계를 수집합니다." +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "타임스탬프 값으로 NaN ê°’ì„ ì§€ì •í•  수 ì—†ìŒ" -#: utils/misc/guc.c:1199 -msgid "Collects timing statistics for database I/O activity." -msgstr "ë°ì´í„°ë² ì´ìФ I/O 활ë™ì— 대한 통계를 수집합니다." +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "타임스탬프 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났ìŒ: \"%g\"" -#: utils/misc/guc.c:1209 -msgid "Updates the process title to show the active SQL command." -msgstr "활성 SQL ëª…ë ¹ì„ í‘œì‹œí•˜ë„ë¡ í”„ë¡œì„¸ìŠ¤ ì œëª©ì„ ì—…ë°ì´íŠ¸í•©ë‹ˆë‹¤." +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 +#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3013 +#: utils/adt/timestamp.c:3018 utils/adt/timestamp.c:3023 +#: utils/adt/timestamp.c:3073 utils/adt/timestamp.c:3080 +#: utils/adt/timestamp.c:3087 utils/adt/timestamp.c:3107 +#: utils/adt/timestamp.c:3114 utils/adt/timestamp.c:3121 +#: utils/adt/timestamp.c:3151 utils/adt/timestamp.c:3159 +#: utils/adt/timestamp.c:3203 utils/adt/timestamp.c:3630 +#: utils/adt/timestamp.c:3755 utils/adt/timestamp.c:4140 +#, c-format +msgid "interval out of range" +msgstr "ê°„ê²©ì´ ë²”ìœ„ë¥¼ 벗어남" -#: utils/misc/guc.c:1210 -msgid "" -"Enables updating of the process title every time a new SQL command is " -"received by the server." -msgstr "" -"서버가 새 SQL ëª…ë ¹ì„ ë°›ì„ ë•Œë§ˆë‹¤ 프로세스 ì œëª©ì´ ì—…ë°ì´íŠ¸ë  ìˆ˜ 있ë„ë¡ í•©ë‹ˆë‹¤." +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "ìž˜ëª»ëœ INTERVAL í˜•ì‹ í•œì •ìž" -#: utils/misc/guc.c:1223 -msgid "Starts the autovacuum subprocess." -msgstr "ìžë™ 청소 하위 프로세스를 실행함" +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d) ì •ë°€ë„로 ìŒìˆ˜ê°’ì´ ì˜¬ 수 없습니다" -#: utils/misc/guc.c:1233 -msgid "Generates debugging output for LISTEN and NOTIFY." -msgstr "LISTEN, NOTIFY 명령 ì‚¬ìš©ì„ ìœ„í•œ 디버깅 ì¶œë ¥ì„ ë§Œë“¦." +#: utils/adt/timestamp.c:1090 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d) ì •ë°€ë„는 허용 최대치(%d)로 ê°ì†Œ ë˜ì—ˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:1245 -msgid "Emits information about lock usage." -msgstr "잠금 사용 정보를 로그로 남김" +#: utils/adt/timestamp.c:1462 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "간격(%d) ì •ë°€ë„는 %dì—서 %d 사ì´ì—¬ì•¼ 함" -#: utils/misc/guc.c:1255 -msgid "Emits information about user lock usage." -msgstr "ì‚¬ìš©ìž ìž ê¸ˆ 사용 정보를 로그로 남김" +#: utils/adt/timestamp.c:2614 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "타임스탬프 ë¬´í•œê°’ì„ ì¶”ì¶œ í•  수 ì—†ìŒ" -#: utils/misc/guc.c:1265 -msgid "Emits information about lightweight lock usage." -msgstr "가벼운 잠금 사용 정보를 로그로 남김" +#: utils/adt/timestamp.c:3883 utils/adt/timestamp.c:4400 +#: utils/adt/timestamp.c:4567 utils/adt/timestamp.c:4588 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "\"%s\" timestamp ìœ ë‹›ì€ ì§€ì›í•˜ì§€ 않습니다" -#: utils/misc/guc.c:1275 -msgid "" -"Dumps information about all current locks when a deadlock timeout occurs." -msgstr "êµì°© 잠금 시간 제한 ìƒí™©ì´ ë°œìƒí•˜ë©´ ê·¸ ë•Œì˜ ëª¨ë“  잠금 정보를 보여줌" +#: utils/adt/timestamp.c:3897 utils/adt/timestamp.c:4354 +#: utils/adt/timestamp.c:4598 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "\"%s\" timestamp ìœ ë‹›ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" -#: utils/misc/guc.c:1287 -msgid "Logs long lock waits." -msgstr "긴 잠금 대기를 기ë¡í•©ë‹ˆë‹¤." +#: utils/adt/timestamp.c:4029 utils/adt/timestamp.c:4395 +#: utils/adt/timestamp.c:4768 utils/adt/timestamp.c:4790 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "\"%s\" 시간대 ìœ ë‹›ì´ ìžˆëŠ” timestamp ìžë£Œí˜•ì€ ì§€ì›í•˜ì§€ 않습니다" -#: utils/misc/guc.c:1297 -msgid "Logs the host name in the connection logs." -msgstr "ì—°ê²° 기ë¡ì—서 호스트 ì´ë¦„ì„ ê¸°ë¡í•¨." +#: utils/adt/timestamp.c:4046 utils/adt/timestamp.c:4349 +#: utils/adt/timestamp.c:4799 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "\"%s\" 시간대 ìœ ë‹›ì´ ìžˆëŠ” timestamp ê°’ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" -#: utils/misc/guc.c:1298 -msgid "" -"By default, connection logs only show the IP address of the connecting host. " -"If you want them to show the host name you can turn this on, but depending " -"on your host name resolution setup it might impose a non-negligible " -"performance penalty." +#: utils/adt/timestamp.c:4127 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "" -"ì´ ê¸°ëŠ¥ì€ ê¸°ë³¸ì ìœ¼ë¡œ 연결기ë¡ì—서 기본ì ìœ¼ë¡œ IP 주소만 기ë¡í•©ë‹ˆë‹¤. ì´ ê°’ì„ " -"true로 바꾼다면, ì´ IPì˜ í˜¸ìŠ¤íŠ¸ ì´ë¦„ì„ êµ¬í•´ì„œ ì´ ì´ë¦„ì„ ì‚¬ìš©í•©ë‹ˆë‹¤ ì´ê²ƒì˜ 성" -"ëŠ¥ì€ OSì˜ IPì—서 ì´ë¦„구하기 성능과 관계ë©ë‹ˆë‹¤." -#: utils/misc/guc.c:1309 -msgid "Causes subtables to be included by default in various commands." -msgstr "" -"다양한 명령들ì—서 기본ì ìœ¼ë¡œ ìƒì†ë˜ëŠ” í…Œì´ë¸”들 함께 사용할 것ì¸ì§€ 정함." +#: utils/adt/timestamp.c:4133 utils/adt/timestamp.c:4893 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "\"%s\" 유닛 간격(interval units)ì€ ì§€ì›í•˜ì§€ 않습니다" -#: utils/misc/guc.c:1318 -msgid "Encrypt passwords." -msgstr "암호를 암호화 해서 기ë¡í•¨" +#: utils/adt/timestamp.c:4149 utils/adt/timestamp.c:4916 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "\"%s\" 유닛 간격(interval units)ì„ ì²˜ë¦¬í•˜ì§€ 못했습니다" -#: utils/misc/guc.c:1319 -msgid "" -"When a password is specified in CREATE USER or ALTER USER without writing " -"either ENCRYPTED or UNENCRYPTED, this parameter determines whether the " -"password is to be encrypted." -msgstr "" -"CREATE USER ë˜ëŠ” ALTER USER 명령ì—서 ENCRYPTED ë˜ëŠ” UNENCRYPTED ì†ì„±ì„ 특별" -"히 지정하지 않았고 ì‚¬ìš©ìž ì•”í˜¸ë¥¼ ì§€ì •í–ˆì„ ë•Œ, ê·¸ 암호를 암호화 해서 저장할 것" -"ì¸ì§€ 아닌지를 지정함" +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: 트리거로 호출ë˜ì–´ì•¼ 함" -#: utils/misc/guc.c:1329 -msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." -msgstr "\"표현=NULL\" ì‹ì„ \"표현 IS NULL\"로 취급함." +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: ì—…ë°ì´íЏ 시 호출ë˜ì–´ì•¼ 함" -#: utils/misc/guc.c:1330 -msgid "" -"When turned on, expressions of the form expr = NULL (or NULL = expr) are " -"treated as expr IS NULL, that is, they return true if expr evaluates to the " -"null value, and false otherwise. The correct behavior of expr = NULL is to " -"always return null (unknown)." -msgstr "" -"표현 = NULL ì˜ ë°”ë¥¸ 처리는 í•­ìƒ null ê°’ì„ ë¦¬í„´í•´ì•¼í•˜ì§€ë§Œ, 편ì˜ì„±ì„ 위해서 " -"expr = NULL êµ¬ë¬¸ì„ expr IS NULL 구문으로 바꾸어서 처리하ë„ë¡ í•¨ì´ë ‡ê²Œí•˜ë©´, " -"윗 êµ¬ë¬¸ì€ true 를 리턴함" +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: ì—…ë°ì´íЏ ì „ì— í˜¸ì¶œë˜ì–´ì•¼ 함" -#: utils/misc/guc.c:1342 -msgid "Enables per-database user names." -msgstr "per-database ì‚¬ìš©ìž ì´ë¦„ 활성화." +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: ê° í–‰ì— ëŒ€í•´ 호출ë˜ì–´ì•¼ 함" -#: utils/misc/guc.c:1351 -msgid "Sets the default read-only status of new transactions." -msgstr "새로운 íŠ¸ëžœìž­ì…˜ì˜ ìƒíƒœë¥¼ 초기값으로 ì½ê¸°ì „용으로 설정합니다." +#: utils/adt/tsgistidx.c:100 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_inì´ êµ¬í˜„ë˜ì–´ 있지 않ìŒ" -#: utils/misc/guc.c:1360 -msgid "Sets the current transaction's read-only status." -msgstr "현재 íŠ¸ëžœìž­ì…•ì˜ ì½ê¸° ì „ìš© ìƒíƒœë¥¼ 지정합니다." +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "ë¶„ì„ ìž‘ì—…ì—서 사용한 ê±°ë¦¬ê°’ì€ %d 보다 í´ ìˆ˜ 없습니다" -#: utils/misc/guc.c:1370 -msgid "Sets the default deferrable status of new transactions." -msgstr "새 íŠ¸ëžœìž­ì…˜ì˜ ê¸°ë³¸ 지연 가능한 ìƒíƒœë¥¼ 지정" +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "tsqueryì— êµ¬ë¬¸ 오류가 있ìŒ: \"%s\"" -#: utils/misc/guc.c:1379 -msgid "" -"Whether to defer a read-only serializable transaction until it can be " -"executed with no possible serialization failures." -msgstr "" -"ì½ê¸° ì „ìš© ì§ë ¬í™” 가능한 íŠ¸ëžœìž­ì…˜ì´ ì§ë ¬ 처리ì—서 오류가 ì—†ì„ ë•Œê¹Œì§€ ê·¸ 트랜잭" -"ì…˜ì„ ì§€ì—°í•  것ì´ì§€ 결정함" +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "tsqueryì— í”¼ì—°ì‚°ìžê°€ ì—†ìŒ: \"%s\"" -#: utils/misc/guc.c:1389 -msgid "Enable row security." -msgstr "로우 단위 보안 ê¸°ëŠ¥ì„ í™œì„±í™”" +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "tsqueryì˜ ê°’ì´ ë„ˆë¬´ í¼: \"%s\"" -#: utils/misc/guc.c:1390 -msgid "When enabled, row security will be applied to all users." -msgstr "ì´ ê°’ì´ í™œì„±í™” ë˜ë©´ 로우 단위 보안 ê¸°ëŠ¥ì´ ëª¨ë“  ì‚¬ìš©ìž ëŒ€ìƒìœ¼ë¡œ ì ìš©ë¨" +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "tsqueryì˜ í”¼ì—°ì‚°ìžê°€ 너무 긺: \"%s\"" -#: utils/misc/guc.c:1398 -msgid "Check function bodies during CREATE FUNCTION." -msgstr "" -"CREATE FUNCTION 명령으로 함수를 만들 때, 함수 본문 ë¶€ë¶„ì˜ êµ¬ë¬¸ì„ ê²€ì‚¬í•©ë‹ˆë‹¤." +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "tsqueryì˜ ë‹¨ì–´ê°€ 너무 긺: \"%s\"" -#: utils/misc/guc.c:1407 -msgid "Enable input of NULL elements in arrays." -msgstr "ë°°ì—´ì— NULL 요소가 ìž…ë ¥ë  ìˆ˜ 있ë„ë¡ í•©ë‹ˆë‹¤." +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "í…스트 검색 ì¿¼ë¦¬ì— ì–´íœ˜ì†Œê°€ í¬í•¨ë˜ì–´ 있지 않ìŒ: \"%s\"" -#: utils/misc/guc.c:1408 -msgid "" -"When turned on, unquoted NULL in an array input value means a null value; " -"otherwise it is taken literally." -msgstr "" -"ì´ ê°’ì´ onì´ë©´ ë°°ì—´ ìž…ë ¥ ê°’ì— ë”°ì˜´í‘œ ì—†ì´ ìž…ë ¥ëœ NULLì´ null ê°’ì„ ì˜ë¯¸í•˜ê³ , " -"그렇지 않으면 ë¬¸ìž ê·¸ëŒ€ë¡œ 처리ë©ë‹ˆë‹¤." +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery 길ì´ê°€ 너무 ê¹ë‹ˆë‹¤" -#: utils/misc/guc.c:1418 -msgid "Create new tables with OIDs by default." -msgstr "기본ì ìœ¼ë¡œ OID를 사용하여 새 í…Œì´ë¸”ì„ ë§Œë“­ë‹ˆë‹¤." +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "í…스트 검색 ì¿¼ë¦¬ì— ì¤‘ì§€ 단어만 í¬í•¨ë˜ì–´ 있거나 어휘소가 í¬í•¨ë˜ì–´ 있지 않ìŒ, 무시ë¨" -#: utils/misc/guc.c:1427 -msgid "" -"Start a subprocess to capture stderr output and/or csvlogs into log files." -msgstr "" -"로그 ê¸°ë¡ í•˜ìœ„ 프로세스를 시작하여 stderr 출력 ë°/ë˜ëŠ” csvlog를 로그 파ì¼ì— " -"ì”니다." +#: utils/adt/tsquery_op.c:123 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "ë¶„ì„ ìž‘ì—…ì—서 사용한 ê±°ë¦¬ê°’ì€ %d 보다 작고 양수값만 사용할 수 있습니다" -#: utils/misc/guc.c:1436 -msgid "Truncate existing log files of same name during log rotation." -msgstr "로그 회전 중 ë™ì¼í•œ ì´ë¦„ì˜ ê¸°ì¡´ 로그 파ì¼ì„ ìžë¦…니다." +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite 쿼리는 ë‘ ê°œì˜ tsquery ì¹¼ëŸ¼ì„ ë°˜í™˜í•´ì•¼ 함" -#: utils/misc/guc.c:1447 -msgid "Emit information about resource usage in sorting." -msgstr "ì •ë ¬ 시 리소스 사용 정보를 내보냅니다." +#: utils/adt/tsrank.c:413 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "가중치 ë°°ì—´ì€ ì¼ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 함" -#: utils/misc/guc.c:1461 -msgid "Generate debugging output for synchronized scanning." -msgstr "ë™ê¸°í™”ëœ ìŠ¤ìº”ì„ ìœ„í•´ 디버깅 ì¶œë ¥ì„ ìƒì„±í•©ë‹ˆë‹¤." +#: utils/adt/tsrank.c:418 +#, c-format +msgid "array of weight is too short" +msgstr "가중치 ë°°ì—´ì´ ë„ˆë¬´ ì§§ìŒ" -#: utils/misc/guc.c:1476 -msgid "Enable bounded sorting using heap sort." -msgstr "íž™ ì •ë ¬ì„ í†µí•´ ì œí•œì  ì •ë ¬ì„ ì‚¬ìš©í•©ë‹ˆë‹¤." +#: utils/adt/tsrank.c:423 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "가중치 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: utils/misc/guc.c:1489 -msgid "Emit WAL-related debugging output." -msgstr "WAL 관련 디버깅 ì¶œë ¥ì„ ë‚´ë³´ëƒ…ë‹ˆë‹¤." +#: utils/adt/tsrank.c:432 utils/adt/tsrank.c:869 +#, c-format +msgid "weight out of range" +msgstr "가중치가 범위를 벗어남" -#: utils/misc/guc.c:1501 -msgid "Datetimes are integer based." -msgstr "datetime í˜•ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ 사용함" +#: utils/adt/tsvector.c:214 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "단어가 너무 긺(%ldë°”ì´íЏ, 최대 %ldë°”ì´íЏ)" -#: utils/misc/guc.c:1516 -msgid "" -"Sets whether Kerberos and GSSAPI user names should be treated as case-" -"insensitive." -msgstr "" -"Kerberos ë° GSSAPI ì‚¬ìš©ìž ì´ë¦„ì—서 대/소문ìžë¥¼ 구분하지 않ì„ì§€ 여부를 설정합" -"니다." +#: utils/adt/tsvector.c:221 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "문ìžì—´ì´ 너무 길어서 tsvectorì— ì‚¬ìš©í•  수 ì—†ìŒ(%ldë°”ì´íЏ, 최대 %ldë°”ì´íЏ)" -#: utils/misc/guc.c:1526 -msgid "Warn about backslash escapes in ordinary string literals." -msgstr "ì¼ë°˜ 문ìžì—´ ë¦¬í„°ëŸ´ì˜ ë°±ìŠ¬ëž˜ì‹œ ì´ìŠ¤ì¼€ì´í”„ì— ëŒ€í•´ 경고합니다." +#: utils/adt/tsvector_op.c:323 utils/adt/tsvector_op.c:610 +#: utils/adt/tsvector_op.c:778 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "어휘소 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: utils/misc/guc.c:1536 -msgid "Causes '...' strings to treat backslashes literally." -msgstr "'...' 문ìžì—´ì—서 백슬래시가 리터럴로 처리ë˜ë„ë¡ í•©ë‹ˆë‹¤." +#: utils/adt/tsvector_op.c:853 +#, c-format +msgid "weight array may not contain nulls" +msgstr "가중치 ë°°ì—´ì—는 nullì´ í¬í•¨ë˜ì§€ 않아야 함" -#: utils/misc/guc.c:1547 -msgid "Enable synchronized sequential scans." -msgstr "ë™ê¸°í™”ëœ ìˆœì°¨ì  ìŠ¤ìº”ì„ ì‚¬ìš©í•©ë‹ˆë‹¤." +#: utils/adt/tsvector_op.c:877 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "알 수 없는 가중치: \"%c\"" -#: utils/misc/guc.c:1557 -msgid "Allows connections and queries during recovery." -msgstr "복구 중ì—ì„œë„ ì ‘ì†ê³¼ 쿼리 ì‚¬ìš©ì„ í—ˆìš©í•¨" +#: utils/adt/tsvector_op.c:2314 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_stat 쿼리는 í•˜ë‚˜ì˜ tsvector ì¹¼ëŸ¼ì„ ë°˜í™˜í•´ì•¼ 함" -#: utils/misc/guc.c:1567 -msgid "" -"Allows feedback from a hot standby to the primary that will avoid query " -"conflicts." -msgstr "" -"ì½ê¸° ì „ìš© ë³´ì¡° 서버가 보내는 쿼리 ì¶©ëŒì„ 피하기 위한 í”¼ë“œë°±ì„ ì£¼ 서버가 ë°›ìŒ" +#: utils/adt/tsvector_op.c:2496 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "\"%s\" tsvector ì¹¼ëŸ¼ì´ ì—†ìŒ" -#: utils/misc/guc.c:1577 -msgid "Allows modifications of the structure of system tables." -msgstr "시스템 í…Œì´ë¸”ì˜ êµ¬ì¡°ë¥¼ 수정할 수 있ë„ë¡ í•©ë‹ˆë‹¤." +#: utils/adt/tsvector_op.c:2503 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ tsvector 형ì‹ì´ 아님" -#: utils/misc/guc.c:1588 -msgid "Disables reading from system indexes." -msgstr "시스템 ì¸ë±ìФ ì½ê¸°ë¥¼ 금지함" +#: utils/adt/tsvector_op.c:2515 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "\"%s\" 구성 ì¹¼ëŸ¼ì´ ì—†ìŒ" -#: utils/misc/guc.c:1589 -msgid "" -"It does not prevent updating the indexes, so it is safe to use. The worst " -"consequence is slowness." -msgstr "" -"ì´ ì„¤ì •ì´ í™œì„±í™” ë˜ì–´ë„ ê·¸ ì¸ë±ìŠ¤ëŠ” 갱신ë˜ì–´ 사용하는ë°ëŠ” 안전합니다. 하지" -"ë§Œ 서버가 ì „ì²´ì ìœ¼ë¡œ 늦어질 수 있습니다." +#: utils/adt/tsvector_op.c:2521 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ regconfig í˜•ì´ ì•„ë‹˜" -#: utils/misc/guc.c:1600 -msgid "" -"Enables backward compatibility mode for privilege checks on large objects." -msgstr "대형 ê°ì²´ì— 대한 ì ‘ê·¼ 권한 검사를 위한 하위 í˜¸í™˜ì„±ì´ ìžˆê²Œ 함" +#: utils/adt/tsvector_op.c:2528 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "\"%s\" 구성 ì¹¼ëŸ¼ì€ nullì´ ì•„ë‹ˆì–´ì•¼ 함" -#: utils/misc/guc.c:1601 -msgid "" -"Skips privilege checks when reading or modifying large objects, for " -"compatibility with PostgreSQL releases prior to 9.0." -msgstr "" -"PostgreSQL 9.0 ì´ì „ ë²„ì „ì˜ í˜¸í™˜ì„±ì„ ìœ„í•´ 대형 ê°ì²´ì— 대한 ì½ê¸°, 변경 시 ì ‘ê·¼ " -"권한 검사를 안 하ë„ë¡ ì„¤ì •í•¨" +#: utils/adt/tsvector_op.c:2541 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "\"%s\" í…스트 검색 구성 ì´ë¦„ì´ ìŠ¤í‚¤ë§ˆë¡œ 한정ë˜ì–´ì•¼ 함" -#: utils/misc/guc.c:1611 -msgid "" -"Emit a warning for constructs that changed meaning since PostgreSQL 9.4." -msgstr "PostgreSQL 9.4 버전까지 사용ë˜ì—ˆë˜ ìš°ì„  순위가 ì ìš©ë˜ë©´ 경고를 보여줌" +#: utils/adt/tsvector_op.c:2566 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "\"%s\" ì¹¼ëŸ¼ì€ ë¬¸ìží˜•ì´ ì•„ë‹˜" -#: utils/misc/guc.c:1621 -msgid "When generating SQL fragments, quote all identifiers." -msgstr "SQL êµ¬ë¬¸ì„ ë§Œë“¤ 때, 모든 ì‹ë³„ìžëŠ” 따옴표를 사용함" +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "tsvectorì— êµ¬ë¬¸ 오류가 있ìŒ: \"%s\"" -#: utils/misc/guc.c:1631 -msgid "Shows whether data checksums are turned on for this cluster." -msgstr "" +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "ì´ìŠ¤ì¼€ì´í”„ 문ìžê°€ ì—†ìŒ: \"%s\"" -#: utils/misc/guc.c:1642 -msgid "Add sequence number to syslog messages to avoid duplicate suppression." -msgstr "syslog 사용시 메시지 ì¤‘ë³µì„ ë°©ì§€í•˜ê¸° 위해 ì¼ë ¨ 번호를 매ê¹ë‹ˆë‹¤." +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "tsvectorì— ìž˜ëª»ëœ ìœ„ì¹˜ ì •ë³´ê°€ 있ìŒ: \"%s\"" -#: utils/misc/guc.c:1652 -msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." -msgstr "syslog 사용시 메시지를 한 ì¤„ì— 1024 ë°”ì´íŠ¸ë§Œ ì“°ë„ë¡ ë‚˜ëˆ•ë‹ˆë‹¤" +#: utils/adt/txid.c:135 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "%s 트랜잭션 ID는 ë¯¸ëž˜ì˜ ê²ƒìž…ë‹ˆë‹¤" -#: utils/misc/guc.c:1671 -msgid "" -"Forces a switch to the next xlog file if a new file has not been started " -"within N seconds." -msgstr "" -"새 파ì¼ì´ Nì´ˆ ë‚´ì— ì‹œìž‘ë˜ì§€ ì•Šì€ ê²½ìš° 강제로 ë‹¤ìŒ xlog 파ì¼ë¡œ 전환합니다." +#: utils/adt/txid.c:624 +#, c-format +msgid "invalid external txid_snapshot data" +msgstr "외부 txid_snapshot ê°’ì´ ìž˜ëª»ë¨" -#: utils/misc/guc.c:1682 -msgid "Waits N seconds on connection startup after authentication." -msgstr "ì—°ê²° 작업ì—서 ì¸ì¦ì´ ë난 ë’¤ Nì´ˆ 기다림" +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "%s ìžë£Œí˜•ì˜ ê¸¸ì´ëŠ” 최소 1 ì´ìƒì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: utils/misc/guc.c:1683 utils/misc/guc.c:2206 -msgid "This allows attaching a debugger to the process." -msgstr "ì´ë ‡ê²Œ 하면 디버거를 í”„ë¡œì„¸ìŠ¤ì— ì—°ê²°í•  수 있습니다." +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "%s ìžë£Œí˜•ì˜ ê¸¸ì´ëŠ” 최대 %d ì´í•˜ì—¬ì•¼í•©ë‹ˆë‹¤" -#: utils/misc/guc.c:1692 -msgid "Sets the default statistics target." -msgstr "기본 통계 대ìƒì„ 지정합니다." +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "비트 문ìžì—´ 길ì´ê°€ 최대치 (%d)를 초과했습니다" -#: utils/misc/guc.c:1693 -msgid "" -"This applies to table columns that have not had a column-specific target set " -"via ALTER TABLE SET STATISTICS." -msgstr "" -"특정 ì—´ì„ ì§€ì •í•˜ì§€ 않고 ALTER TABLE SET STATISTICS ëª…ë ¹ì„ ì‚¬ìš©í–ˆì„ ë•Œ, 통계 " -"대ìƒì´ ë  ì—´ì„ ì§€ì •í•©ë‹ˆë‹¤." +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "길ì´ê°€ %dì¸ ë¹„íŠ¸ 문ìžì—´ ìžë£ŒëŠ” bit(%d) ìžë£Œí˜•ì˜ ê¸¸ì´ì™€ ì¼ì¹˜í•˜ì§€ 않습니다" -#: utils/misc/guc.c:1702 -msgid "Sets the FROM-list size beyond which subqueries are not collapsed." -msgstr "" -"ì´ í¬ê¸°ë¥¼ 초과할 경우 하위 쿼리가 축소ë˜ì§€ 않는 FROM ëª©ë¡ í¬ê¸°ë¥¼ 설정합니다." +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" 문ìžëŠ” 2진수 문ìžê°€ 아닙니다" -#: utils/misc/guc.c:1704 -msgid "" -"The planner will merge subqueries into upper queries if the resulting FROM " -"list would have no more than this many items." -msgstr "" -"ê²°ê³¼ FROM 목ë¡ì— í¬í•¨ëœ í•­ëª©ì´ ì´ ê°œìˆ˜ë¥¼ 넘지 않는 경우 ê³„íš ê´€ë¦¬ìžê°€ 하" -"위 쿼리를 ìƒìœ„ ì¿¼ë¦¬ì— ë³‘í•©í•©ë‹ˆë‹¤." +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" 문ìžëŠ” 16진수 문ìžê°€ 아닙니다" -#: utils/misc/guc.c:1714 -msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." -msgstr "" -"ì´ í¬ê¸°ë¥¼ 초과할 경우 JOIN êµ¬ë¬¸ì´ ê²°í•©ë˜ì§€ 않는 FROM ëª©ë¡ í¬ê¸°ë¥¼ 설정합니다." +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 +#, c-format +msgid "invalid length in external bit string" +msgstr "외부 비트 문ìžì—´ì˜ 길ì´ê°€ 잘못ë˜ì—ˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:1716 -msgid "" -"The planner will flatten explicit JOIN constructs into lists of FROM items " -"whenever a list of no more than this many items would result." -msgstr "" -"ê²°ê³¼ 목ë¡ì— í¬í•¨ëœ í•­ëª©ì´ ì´ ê°œìˆ˜ë¥¼ 넘지 ì•Šì„ ë•Œë§ˆë‹¤ ê³„íš ê´€ë¦¬ìžê°€ 명시" -"ì  JOIN êµ¬ë¬¸ì„ FROM 항목 목ë¡ì— 결합합니다." +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "비트 문ìžì—´ì´ 너무 ê¹ë‹ˆë‹¤(해당 ìžë£Œí˜• bit varying(%d))" -#: utils/misc/guc.c:1726 -msgid "Sets the threshold of FROM items beyond which GEQO is used." -msgstr "" -"ì´ ìž„ê³„ê°’ì„ ì´ˆê³¼í•  경우 GEQOê°€ 사용ë˜ëŠ” FROM í•­ëª©ì˜ ìž„ê³„ê°’ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 +#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 +#: utils/adt/varlena.c:2979 +#, c-format +msgid "negative substring length not allowed" +msgstr "substringì—서 ìŒìˆ˜ 길ì´ëŠ” 허용하지 않ìŒ" -#: utils/misc/guc.c:1735 -msgid "GEQO: effort is used to set the default for other GEQO parameters." -msgstr "GEQO: 다른 GEQO 매개 ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì„ ì„¤ì •í•˜ëŠ” ë° ì‚¬ìš©ë©ë‹ˆë‹¤." +#: utils/adt/varbit.c:1226 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ë¡œ AND ì—°ì‚°ì„ í•  수 없습니다." -#: utils/misc/guc.c:1744 -msgid "GEQO: number of individuals in the population." -msgstr "GEQO: ëª¨ì§‘ë‹¨ì˜ ê°œì¸ ìˆ˜ìž…ë‹ˆë‹¤." +#: utils/adt/varbit.c:1268 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ë¡œ OR ì—°ì‚°ì„ í•  수 없습니다." -#: utils/misc/guc.c:1745 utils/misc/guc.c:1754 -msgid "Zero selects a suitable default value." -msgstr "0ì„ ì§€ì •í•˜ë©´ ì ì ˆí•œ 기본 ê°’ì´ ì„ íƒë©ë‹ˆë‹¤." +#: utils/adt/varbit.c:1315 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "서로 í¬ê¸°ê°€ 틀린 비트 문ìžì—´ì€ XOR ì—°ì‚°ì„ í•  수 없습니다." -#: utils/misc/guc.c:1753 -msgid "GEQO: number of iterations of the algorithm." -msgstr "GEQO: ì•Œê³ ë¦¬ì¦˜ì˜ ë°˜ë³µ 수입니다." +#: utils/adt/varbit.c:1803 utils/adt/varbit.c:1861 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "비트 %d ì¸ë±ìŠ¤ì˜ ë²”ìœ„ë¥¼ 벗어남 (0..%d)" -#: utils/misc/guc.c:1764 -msgid "Sets the time to wait on a lock before checking for deadlock." -msgstr "êµì°© ìƒíƒœë¥¼ 확ì¸í•˜ê¸° ì „ì— ìž ê¸ˆì„ ê¸°ë‹¤ë¦´ ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "새 ë¹„íŠ¸ê°’ì€ 0 ë˜ëŠ” 1 ì´ì–´ì•¼í•©ë‹ˆë‹¤" -#: utils/misc/guc.c:1775 -msgid "" -"Sets the maximum delay before canceling queries when a hot standby server is " -"processing archived WAL data." -msgstr "" -"ì½ê¸° ì „ìš© ë³´ì¡° 서버가 ì•„ì¹´ì´ë¸Œëœ WAL ìžë£Œë¥¼ 처리할 때, ì§€ì—°ë  ìˆ˜ 있는 최대 시" -"ê°„" +#: utils/adt/varchar.c:155 utils/adt/varchar.c:308 +#, c-format +msgid "value too long for type character(%d)" +msgstr "character(%d) ìžë£Œí˜•ì— ë„ˆë¬´ 긴 ìžë£Œë¥¼ 담으려고 합니다." -#: utils/misc/guc.c:1786 -msgid "" -"Sets the maximum delay before canceling queries when a hot standby server is " -"processing streamed WAL data." -msgstr "" -"ì½ê¸° ì „ìš© ë³´ì¡° 서버가 스트림 WAL ìžë£Œë¥¼ 처리할 때, ì§€ì—°ë  ìˆ˜ 있는 최대 시간" +#: utils/adt/varchar.c:470 utils/adt/varchar.c:623 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "character varying(%d) ìžë£Œí˜•ì— ë„ˆë¬´ 긴 ìžë£Œë¥¼ 담으려고 합니다." -#: utils/misc/guc.c:1797 -msgid "" -"Sets the maximum interval between WAL receiver status reports to the primary." -msgstr "주 서버로 WAL 수신기 ìƒíƒœë¥¼ 보고하는 최대 간격" +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "문ìžì—´ ë¹„êµ ìž‘ì—…ì— ì‚¬ìš©í•  정렬규칙(collation)ì„ ê²°ì •í•  수 ì—†ìŒ" -#: utils/misc/guc.c:1808 -msgid "Sets the maximum wait time to receive data from the primary." -msgstr "" -"주 서버ì—서 보낸 ìžë£Œë¥¼ 받기위해 기다릴 수 있는 최대 허용 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/adt/varlena.c:1472 utils/adt/varlena.c:1485 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "UTF-16 ì¸ì½”딩으로 문ìžì—´ì„ 변환할 수 ì—†ìŒ: 오류번호 %lu" -#: utils/misc/guc.c:1819 -msgid "Sets the maximum number of concurrent connections." -msgstr "최대 ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 지정합니다." +#: utils/adt/varlena.c:1500 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "유니코드 문ìžì—´ ë¹„êµ ì‹¤íŒ¨: %m" -#: utils/misc/guc.c:1829 -msgid "Sets the number of connection slots reserved for superusers." -msgstr "superuser ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 지정합니다." +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 +#, c-format +msgid "collation failed: %s" +msgstr "문ìžì—´ ì •ë ¬: %s" -#: utils/misc/guc.c:1843 -msgid "Sets the number of shared memory buffers used by the server." -msgstr "서버ì—서 사용할 공유 ë©”ëª¨ë¦¬ì˜ ê°œìˆ˜ë¥¼ 지정함" +#: utils/adt/varlena.c:2394 +#, c-format +msgid "sort key generation failed: %s" +msgstr "ì •ë ¬ 키 ìƒì„± 실패: %s" -#: utils/misc/guc.c:1854 -msgid "Sets the maximum number of temporary buffers used by each session." -msgstr "ê° ì„¸ì…˜ì—서 사용하는 임시 버í¼ì˜ 최대 개수를 지정" - -#: utils/misc/guc.c:1865 -msgid "Sets the TCP port the server listens on." -msgstr "TCP í¬íЏ 번호를 지정함." +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 +#: utils/adt/varlena.c:3158 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "%d ì¸ë±ìŠ¤ì˜ ë²”ìœ„ë¥¼ 벗어남, 0..%d" -#: utils/misc/guc.c:1875 -msgid "Sets the access permissions of the Unix-domain socket." -msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ 파ì¼ì˜ 액세스 ê¶Œí•œì„ ì§€ì •í•¨" +#: utils/adt/varlena.c:4201 +#, c-format +msgid "field position must be greater than zero" +msgstr "필드 위치 ê°’ì€ 0 보다 커야합니다" -#: utils/misc/guc.c:1876 -msgid "" -"Unix-domain sockets use the usual Unix file system permission set. The " -"parameter value is expected to be a numeric mode specification in the form " -"accepted by the chmod and umask system calls. (To use the customary octal " -"format the number must start with a 0 (zero).)" -msgstr "" -"Unix ë„ë©”ì¸ ì†Œì¼“ì€ ì¼ë°˜ì ì¸ Unix íŒŒì¼ ì‹œìŠ¤í…œ 권한 ì§‘í•©ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 매개 ë³€" -"수 ê°’ì€ chmod ë° umask 시스템 호출ì—서 수ë½ë˜ëŠ” í˜•íƒœì˜ ìˆ«ìž ëª¨ë“œ 지정ì´ì–´ì•¼ " -"합니다. (ì¼ë°˜ì ì¸ 8진수 형ì‹ì„ 사용하려면 숫ìžê°€ 0으로 시작해야 합니다.)" +#: utils/adt/varlena.c:5080 +#, c-format +msgid "unterminated format() type specifier" +msgstr "마무리 ì•ˆëœ format() 형 ì‹ë³„ìž" -#: utils/misc/guc.c:1890 -msgid "Sets the file permissions for log files." -msgstr "로그 파ì¼ì˜ íŒŒì¼ ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•©ë‹ˆë‹¤." +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "í•˜ë‚˜ì˜ \"%%\" 문ìžë¥¼ 표시하려면, \"%%%%\" 형태로 사용하세요" -#: utils/misc/guc.c:1891 -msgid "" -"The parameter value is expected to be a numeric mode specification in the " -"form accepted by the chmod and umask system calls. (To use the customary " -"octal format the number must start with a 0 (zero).)" -msgstr "" -"매개 변수 ê°’ì€ chmod ë° umask 시스템 호출ì—서 수ë½ë˜ëŠ” í˜•íƒœì˜ ìˆ«ìž ëª¨ë“œ 지정" -"ì´ì–´ì•¼ 합니다. (ì¼ë°˜ì ì¸ 8진수 형ì‹ì„ 사용하려면 숫ìžê°€ 0으로 시작해야 합니" -"다.)" +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "ì¸ì‹í•  수 없는 format() 형 ì‹ë³„ìž \"%c\"" -#: utils/misc/guc.c:1904 -msgid "Sets the maximum memory to be used for query workspaces." -msgstr "쿼리 ìž‘ì—…ê³µê°„ì„ ìœ„í•´ ì‚¬ìš©ë  ë©”ëª¨ë¦¬ì˜ ìµœëŒ€ê°’ì„ ì§€ì •í•¨." +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 +#, c-format +msgid "too few arguments for format()" +msgstr "format() ìž‘ì—…ì„ ìœ„í•œ ì¸ìžê°€ 너무 ì ìŒ" -#: utils/misc/guc.c:1905 -msgid "" -"This much memory can be used by each internal sort operation and hash table " -"before switching to temporary disk files." -msgstr "" -"임시 ë””ìŠ¤í¬ íŒŒì¼ë¡œ 전환하기 ì „ì— ê° ë‚´ë¶€ ì •ë ¬ 작업과 해시 í…Œì´ë¸”ì—서 ì´ í¬ê¸°" -"ì˜ ë©”ëª¨ë¦¬ë¥¼ 사용할 수 있습니다." +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 +#, c-format +msgid "number is out of range" +msgstr "수치 범위를 벗어남" -#: utils/misc/guc.c:1917 -msgid "Sets the maximum memory to be used for maintenance operations." -msgstr "관리 ìž‘ì—…ì„ ìœ„í•´ ì‚¬ìš©ë  ë©”ëª¨ë¦¬ì˜ ìµœëŒ€ê°’ì„ ì§€ì •í•¨." +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "format 함수ì—서 사용할 수 있는 ì¸ìž 위치 번호는 0ì´ ì•„ë‹ˆë¼, 1부터 시작합니다" -#: utils/misc/guc.c:1918 -msgid "This includes operations such as VACUUM and CREATE INDEX." -msgstr "ê´€ë¦¬ìž‘ì—…ì€ VACUUM, CREATE INDEX ê°™ì€ ìž‘ì—…ì„ ëœ»í•©ë‹ˆë‹¤." +#: utils/adt/varlena.c:5463 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "ë„“ì´ ì¸ìž ìœ„ì¹˜ê°’ì€ \"$\" 문ìžë¡œ ë나야 합니다" -#: utils/misc/guc.c:1928 -msgid "" -"Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "replacement selection ê¸°ëŠ¥ì„ ì´ìš©í•  최대 튜플 수" +#: utils/adt/varlena.c:5508 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "null ê°’ì€ SQL ì‹ë³„ìžë¡œ í¬ë©§ë  수 ì—†ìŒ" -#: utils/misc/guc.c:1929 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "ì´ íŠœí”Œ 수 보다 많으면, quicksort 를 사용함" +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "ntileì˜ ì¸ìžëŠ” 0보다 커야 함" -#: utils/misc/guc.c:1943 -msgid "Sets the maximum stack depth, in kilobytes." -msgstr "스íƒê¹Šì´(KB 단위) ìµœëŒ€ê°’ì„ ì§€ì •í•©ë‹ˆë‹¤." +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "nth_valueì˜ ì¸ìžëŠ” 0보다 커야 함" -#: utils/misc/guc.c:1954 -msgid "Limits the total size of all temporary files used by each process." -msgstr "ê° í”„ë¡œì„¸ìŠ¤ì—서 사용하는 모든 임시 파ì¼ì˜ ì´ í¬ê¸° 제한" +#: utils/adt/xml.c:220 +#, c-format +msgid "unsupported XML feature" +msgstr "ì§€ì›ë˜ì§€ 않는 XML 기능" -#: utils/misc/guc.c:1955 -msgid "-1 means no limit." -msgstr "-1ì€ ì œí•œ ì—†ìŒ" +#: utils/adt/xml.c:221 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ë ¤ë©´ libxml ì§€ì›ìœ¼ë¡œ 서버를 빌드해야 합니다." -#: utils/misc/guc.c:1965 -msgid "Vacuum cost for a page found in the buffer cache." -msgstr "ë²„í¼ ìºì‹œì— 있는 페ì´ì§€ì˜ 청소 비용입니다." +#: utils/adt/xml.c:222 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "--with-libxmlì„ ì‚¬ìš©í•˜ì—¬ PostgreSQLì„ ë‹¤ì‹œ 빌드해야 합니다." -#: utils/misc/guc.c:1975 -msgid "Vacuum cost for a page not found in the buffer cache." -msgstr "ë²„í¼ ìºì‹œì— 없는 페ì´ì§€ì˜ 청소 비용입니다." +#: utils/adt/xml.c:241 utils/mb/mbutils.c:512 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "\"%s\" ì¸ì½”딩 ì´ë¦„ì´ ìž˜ëª»ë¨" -#: utils/misc/guc.c:1985 -msgid "Vacuum cost for a page dirtied by vacuum." -msgstr "청소로 페ì´ì§€ 변경 시 부과ë˜ëŠ” 비용입니다." +#: utils/adt/xml.c:484 utils/adt/xml.c:489 +#, c-format +msgid "invalid XML comment" +msgstr "ìž˜ëª»ëœ XML 주ì„" -#: utils/misc/guc.c:1995 -msgid "Vacuum cost amount available before napping." -msgstr "청소가 중지ë˜ëŠ” 청소 비용 합계입니다." +#: utils/adt/xml.c:618 +#, c-format +msgid "not an XML document" +msgstr "XML 문서가 아님" -#: utils/misc/guc.c:2005 -msgid "Vacuum cost delay in milliseconds." -msgstr "청소 비용 지연(밀리초)입니다." +#: utils/adt/xml.c:777 utils/adt/xml.c:800 +#, c-format +msgid "invalid XML processing instruction" +msgstr "ìž˜ëª»ëœ XML 처리 명령" -#: utils/misc/guc.c:2016 -msgid "Vacuum cost delay in milliseconds, for autovacuum." -msgstr "ìžë™ ì²­ì†Œì— ëŒ€í•œ 청소 비용 지연(밀리초)입니다." +#: utils/adt/xml.c:778 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML 처리 명령 ëŒ€ìƒ ì´ë¦„ì€ \"%s\"ì¼ ìˆ˜ 없습니다." -#: utils/misc/guc.c:2027 -msgid "Vacuum cost amount available before napping, for autovacuum." -msgstr "ìžë™ ì²­ì†Œì— ëŒ€í•œ 청소가 중지ë˜ëŠ” 청소 비용 합계입니다." +#: utils/adt/xml.c:801 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML 처리 명령ì—는 \"?>\"를 í¬í•¨í•  수 없습니다." -#: utils/misc/guc.c:2037 -msgid "" -"Sets the maximum number of simultaneously open files for each server process." -msgstr "ê°ê°ì˜ 서버 프로세스ì—서 ë™ì‹œì— 열릴 수 있는 최대 íŒŒì¼ ê°¯ìˆ˜ë¥¼ 지정함." +#: utils/adt/xml.c:880 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidateê°€ 구현ë˜ì–´ 있지 않ìŒ" -#: utils/misc/guc.c:2050 -msgid "Sets the maximum number of simultaneously prepared transactions." -msgstr "ë™ì‹œì— ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ 최대 개수 지정" +#: utils/adt/xml.c:959 +#, c-format +msgid "could not initialize XML library" +msgstr "XML ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 초기화할 수 ì—†ìŒ" -#: utils/misc/guc.c:2061 -msgid "Sets the minimum OID of tables for tracking locks." -msgstr "잠금 ì¶”ì ì„ 위한 í…Œì´ë¸”ì˜ ìµœì†Œ OID 지정" +#: utils/adt/xml.c:960 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2ì— í˜¸í™˜ë˜ì§€ 않는 ë¬¸ìž ìžë£Œí˜• 있ìŒ: sizeof(char)=%u, sizeof(xmlChar)=%u" -#: utils/misc/guc.c:2062 -msgid "Is used to avoid output on system tables." -msgstr "" +#: utils/adt/xml.c:1046 +#, c-format +msgid "could not set up XML error handler" +msgstr "XML 오류 핸들러를 설정할 수 ì—†ìŒ" -#: utils/misc/guc.c:2071 -msgid "Sets the OID of the table with unconditionally lock tracing." -msgstr "" +#: utils/adt/xml.c:1047 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "ì´ ë¬¸ì œëŠ” PostgreSQL 서버를 만들 때 사용한 libxml2 í—¤ë” íŒŒì¼ì´ í˜¸í™˜ì„±ì´ ì—†ëŠ” 것 같습니다." -#: utils/misc/guc.c:2083 -msgid "Sets the maximum allowed duration of any statement." -msgstr "모든 ì¿¼ë¦¬ë¬¸ì— ì ìš©ë˜ëŠ” 허용ë˜ëŠ” 최대 수행시간" +#: utils/adt/xml.c:1797 +msgid "Invalid character value." +msgstr "ìž˜ëª»ëœ ë¬¸ìž ê°’ìž…ë‹ˆë‹¤." -#: utils/misc/guc.c:2084 utils/misc/guc.c:2095 utils/misc/guc.c:2106 -msgid "A value of 0 turns off the timeout." -msgstr "ì´ ê°’ì´ 0ì´ë©´ ì´ëŸ° ì œí•œì´ ì—†ìŒ." +#: utils/adt/xml.c:1800 +msgid "Space required." +msgstr "ê³µê°„ì´ í•„ìš”í•©ë‹ˆë‹¤." -#: utils/misc/guc.c:2094 -msgid "Sets the maximum allowed duration of any wait for a lock." -msgstr "모든 ìž ê¸ˆì— ì ìš©ë˜ëŠ” 기다리는 최대 대기 시간" +#: utils/adt/xml.c:1803 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "ë…립 ì‹¤í–‰í˜•ì€ 'yes' ë˜ëŠ” 'no'ë§Œ 허용합니다." -#: utils/misc/guc.c:2105 -msgid "Sets the maximum allowed duration of any idling transaction." -msgstr "idle-in-transaction ìƒíƒœë¡œ ìžˆì„ ìˆ˜ 있는 최대 시간" +#: utils/adt/xml.c:1806 +msgid "Malformed declaration: missing version." +msgstr "ì„ ì–¸ 형ì‹ì´ 잘못ë¨: ë²„ì „ì´ ëˆ„ë½ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:2116 -msgid "Minimum age at which VACUUM should freeze a table row." -msgstr "VACUUMì—서 í…Œì´ë¸” í–‰ì„ ë™ê²°í•  ë•Œê¹Œì§€ì˜ ìµœì†Œ 기간입니다." +#: utils/adt/xml.c:1809 +msgid "Missing encoding in text declaration." +msgstr "í…스트 ì„ ì–¸ì—서 ì¸ì½”ë”©ì´ ëˆ„ë½ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:2126 -msgid "Age at which VACUUM should scan whole table to freeze tuples." -msgstr "" -"VACUUMì—서 íŠœí”Œì„ ë™ê²°í•˜ê¸° 위해 ì „ì²´ í…Œì´ë¸”ì„ ìŠ¤ìº”í•  ë•Œê¹Œì§€ì˜ ê¸°ê°„ìž…ë‹ˆë‹¤." +#: utils/adt/xml.c:1812 +msgid "Parsing XML declaration: '?>' expected." +msgstr "XML ì„ ì–¸ 구문 ë¶„ì„ ì¤‘: '?>'ê°€ 필요합니다." -#: utils/misc/guc.c:2136 -msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." -msgstr "VACUUMì—서 í…Œì´ë¸” MultiXactId ë™ê²°í•  ë•Œê¹Œì§€ì˜ ìµœì†Œ 기간입니다." +#: utils/adt/xml.c:1815 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "ì¸ì‹í•  수 없는 libxml 오류 코드: %d." -#: utils/misc/guc.c:2146 -msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." -msgstr "" -"VACUUMì—서 íŠœí”Œì„ ë™ê²°í•˜ê¸° 위해 ì „ì²´ í…Œì´ë¸”ì„ ìŠ¤ìº”í•  ë•Œê¹Œì§€ì˜ ë©€í‹°íŠ¸ëžœìž­ì…˜ 기" -"간입니다." +#: utils/adt/xml.c:2090 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XMLì€ ë¬´í•œ ë‚ ì§œ ê°’ì„ ì§€ì›í•˜ì§€ 않습니다." -#: utils/misc/guc.c:2156 -msgid "" -"Number of transactions by which VACUUM and HOT cleanup should be deferred, " -"if any." -msgstr "" +#: utils/adt/xml.c:2112 utils/adt/xml.c:2139 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XMLì€ ë¬´í•œ 타임스탬프 ê°’ì„ ì§€ì›í•˜ì§€ 않습니다." -#: utils/misc/guc.c:2169 -msgid "Sets the maximum number of locks per transaction." -msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ì—서 사용할 수 있는 최대 잠금 횟수를 지정함." +#: utils/adt/xml.c:2551 +#, c-format +msgid "invalid query" +msgstr "ìž˜ëª»ëœ ì¿¼ë¦¬" -#: utils/misc/guc.c:2170 -msgid "" -"The shared lock table is sized on the assumption that at most " -"max_locks_per_transaction * max_connections distinct objects will need to be " -"locked at any one time." -msgstr "" -"공유 잠금 í…Œì´ë¸”ì€ í•œ ë²ˆì— ìž ê¶ˆì•¼ í•  고유 ê°ì²´ 수가 " -"max_locks_per_transaction * max_connections를 넘지 않는다는 가정 í•˜ì— í¬ê¸°ê°€ " -"지정ë©ë‹ˆë‹¤." +#: utils/adt/xml.c:3874 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "XML 네임스페ì´ìФ ë§¤í•‘ì— ì‚¬ìš©í•  ë°°ì—´ì´ ìž˜ëª»ë¨" -#: utils/misc/guc.c:2181 -msgid "Sets the maximum number of predicate locks per transaction." -msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ì—서 사용할 수 있는 최대 잠금 횟수를 지정함." +#: utils/adt/xml.c:3875 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "ì´ ë°°ì—´ì€ key, value로 êµ¬ì„±ëœ ë°°ì—´ì„ ìš”ì†Œë¡œ 하는 2ì°¨ì› ë°°ì—´ì´ì–´ì•¼ 합니다." -#: utils/misc/guc.c:2182 -msgid "" -"The shared predicate lock table is sized on the assumption that at most " -"max_pred_locks_per_transaction * max_connections distinct objects will need " -"to be locked at any one time." -msgstr "" -"공유 predicate 잠금 í…Œì´ë¸”ì€ í•œ ë²ˆì— ìž ê¶ˆì•¼ í•  고유 ê°ì²´ 수가 " -"max_pred_locks_per_transaction * max_connections를 넘지 않는다는 가정 í•˜ì— í¬" -"기가 지정ë©ë‹ˆë‹¤." +#: utils/adt/xml.c:3899 +#, c-format +msgid "empty XPath expression" +msgstr "XPath ì‹ì´ 비어 있ìŒ" -#: utils/misc/guc.c:2193 -msgid "Sets the maximum allowed time to complete client authentication." -msgstr "í´ë¼ì´ì–¸íЏ ì¸ì¦ì„ 완료할 수 있는 최대 허용 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/adt/xml.c:3951 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "네임스페ì´ìФ ì´ë¦„ ë° URI는 nullì¼ ìˆ˜ ì—†ìŒ" -#: utils/misc/guc.c:2205 -msgid "Waits N seconds on connection startup before authentication." -msgstr "ì¸ì¦ ì „ì— ì—°ê²°ì´ ì‹œìž‘ë˜ë„ë¡ Nì´ˆ ë™ì•ˆ 기다립니다." +#: utils/adt/xml.c:3958 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "ì´ë¦„ \"%s\" ë° URI \"%s\"ì„(를) 사용하여 XML 네임스페ì´ìŠ¤ë¥¼ 등ë¡í•  수 ì—†ìŒ" -#: utils/misc/guc.c:2216 -msgid "Sets the number of WAL files held for standby servers." -msgstr "대기 서버를 위해 보관하고 ìžˆì„ WAL íŒŒì¼ ê°œìˆ˜ 지정" +#: utils/adt/xml.c:4309 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "DEFAULT 네임스페ì´ìŠ¤ëŠ” ì§€ì›í•˜ì§€ 않습니다." -#: utils/misc/guc.c:2226 -msgid "Sets the minimum size to shrink the WAL to." -msgstr "WAL 최소 í¬ê¸°" +#: utils/adt/xml.c:4338 +#, c-format +msgid "row path filter must not be empty string" +msgstr "로우 경로 필터는 비어있으면 안ë©ë‹ˆë‹¤" -#: utils/misc/guc.c:2237 -msgid "Sets the WAL size that triggers a checkpoint." -msgstr "ì²´í¬í¬ì¸íЏ ìž‘ì—…ì„ í•  WAL í¬ê¸° 지정" +#: utils/adt/xml.c:4369 +#, c-format +msgid "column path filter must not be empty string" +msgstr "칼럼 경로 필터는 비어있으면 안ë©ë‹ˆë‹¤" -#: utils/misc/guc.c:2248 -msgid "Sets the maximum time between automatic WAL checkpoints." -msgstr "ìžë™ WAL ì²´í¬í¬ì¸íЏ 사ì´ì˜ 최대 ê°„ê²©ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/adt/xml.c:4555 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "칼럼 XPath 표현ì‹ì— ì‚¬ìš©ëœ ê²°ê³¼ê°€ 하나 ì´ìƒì˜ ê°’ì„ ì‚¬ìš©í•©ë‹ˆë‹¤" -#: utils/misc/guc.c:2259 -msgid "" -"Enables warnings if checkpoint segments are filled more frequently than this." -msgstr "지정 시간 ì•ˆì— ì²´í¬í¬ì¸íЏ ì¡°ê°ì´ ëª¨ë‘ ì±„ì›Œì§€ë©´ 경고를 냄" +# # nonun 부분 end +#: utils/cache/lsyscache.c:2630 utils/cache/lsyscache.c:2663 +#: utils/cache/lsyscache.c:2696 utils/cache/lsyscache.c:2729 +#, c-format +msgid "type %s is only a shell" +msgstr "%s 형ì‹ì€ ì…¸ì¼ ë¿ìž„" -#: utils/misc/guc.c:2261 -msgid "" -"Write a message to the server log if checkpoints caused by the filling of " -"checkpoint segment files happens more frequently than this number of " -"seconds. Zero turns off the warning." -msgstr "" -"ì²´í¬í¬ì¸íЏ ìž‘ì—…ì´ ì§€ê¸ˆ 지정한 시간(ì´ˆ)보다 ìžì£¼ ì²´í¬í¬ì¸íЏ 세그먼트 파ì¼ì— ë‚´" -"ìš©ì´ ê½‰ 차는 사태가 ë°œìƒí•˜ë©´ 경고 메시지를 서버 ë¡œê·¸ì— ë‚¨ê¹ë‹ˆë‹¤. ì´ ê°’ì„ 0으" -"로 지정하면 ì´ ê¸°ëŠ¥ ì—†ìŒ" +#: utils/cache/lsyscache.c:2635 +#, c-format +msgid "no input function available for type %s" +msgstr "%s ìžë£Œí˜•ì„ ìœ„í•œ ìž…ë ¥ 함수가 없습니다" -#: utils/misc/guc.c:2273 utils/misc/guc.c:2430 utils/misc/guc.c:2457 -msgid "" -"Number of pages after which previously performed writes are flushed to disk." -msgstr "" +#: utils/cache/lsyscache.c:2668 +#, c-format +msgid "no output function available for type %s" +msgstr "%s ìžë£Œí˜•ì„ ìœ„í•œ 출력 함수가 없습니다" -#: utils/misc/guc.c:2284 -msgid "Sets the number of disk-page buffers in shared memory for WAL." -msgstr "" -"WAL ê¸°ëŠ¥ì„ ìœ„í•´ 공유 메모리ì—서 사용할 ë””ìŠ¤í¬ íŽ˜ì´ì§€ ë²„í¼ ê°œìˆ˜ë¥¼ 지정함." +#: utils/cache/partcache.c:202 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "\"%s\" ì—°ì‚°ìž í´ëž˜ìФ(ì ‘ê·¼ 방법: %s)ì—는 %d ê°œì˜ ì§€ì› ì§€ì› í•¨ìˆ˜(해당 ìžë£Œí˜• %s)ê°€ 빠졌습니다" -#: utils/misc/guc.c:2295 -msgid "Time between WAL flushes performed in the WAL writer." -msgstr "WAL 기ë¡ìžê°€ 지정 시간 ë§Œí¼ ì‰¬ê³  쓰기 ìž‘ì—…ì„ ë°˜ë³µí•¨" +#: utils/cache/plancache.c:723 +#, c-format +msgid "cached plan must not change result type" +msgstr "ìºì‹œëœ 계íšì—서 ê²°ê³¼ 형ì‹ì„ 바꾸지 않아야 함" -#: utils/misc/guc.c:2306 -msgid "Amount of WAL written out by WAL writer that triggers a flush." -msgstr "" +#: utils/cache/relcache.c:5824 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜-ìºì‹œ 초기화 파ì¼ì„ 만들 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:2318 -msgid "Sets the maximum number of simultaneously running WAL sender processes." -msgstr "ë™ì‹œì— ìž‘ë™í•  WAL 송신 프로세스 최대 수 지정" +#: utils/cache/relcache.c:5826 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "어쨌든 계ì†í•˜ëŠ”ë°, 뭔가 잘못 ëœ ê²ƒì´ ìžˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:2329 -msgid "Sets the maximum number of simultaneously defined replication slots." -msgstr "ë™ì‹œì— 사용할 수 있는 복제 슬롯 최대 수 지정" +#: utils/cache/relcache.c:6180 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "\"%s\" ìºì‰¬ 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:2339 -msgid "Sets the maximum time to wait for WAL replication." -msgstr "WAL 복제를 위해 기다릴 최대 시간 설정" +#: utils/cache/relmapper.c:513 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "릴레ì´ì…˜ ë§µí•‘ì„ ë³€ê²½í•˜ëŠ” íŠ¸ëžœìž­ì…œì„ PREPAREí•  수 ì—†ìŒ" -#: utils/misc/guc.c:2350 -msgid "" -"Sets the delay in microseconds between transaction commit and flushing WAL " -"to disk." -msgstr "" -"트랜잭션과 트랜잭션 ë¡œê·¸ì˜ ì ìš© 사ì´ì˜ ê°„ê²©ì„ microsecond 단위로 지정함" +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 +#, c-format +msgid "could not open relation mapping file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:2362 -msgid "" -"Sets the minimum concurrent open transactions before performing commit_delay." -msgstr "commit_delay 처리하기 ì „ì— ìžˆëŠ” 최소 ë™ì‹œ ì—´ë ¤ 있는 트랜잭션 개수." - -#: utils/misc/guc.c:2373 -msgid "Sets the number of digits displayed for floating-point values." -msgstr "ë¶€ë™ì†Œìˆ˜í˜• ê°’ì„ í‘œê¸°í•  때 " +#: utils/cache/relmapper.c:669 +#, c-format +msgid "could not read relation mapping file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:2374 -msgid "" -"This affects real, double precision, and geometric data types. The parameter " -"value is added to the standard number of digits (FLT_DIG or DBL_DIG as " -"appropriate)." -msgstr "" -"ì´ ê°’ì€ real, duoble ë¶€ë™ ì†Œìˆ«ì ê³¼ 지리정보 ìžë£Œí˜•ì— ì˜í–¥ì„ ë¼ì¹©ë‹ˆë‹¤. ì´ ê°’" -"ì€ ì •ìˆ˜ì—¬ì•¼í•©ë‹ˆë‹¤(FLT_DIG or DBL_DIG as appropriate - 무슨 ë§ì¸ì§€)." +#: utils/cache/relmapper.c:680 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì— ìž˜ëª»ëœ ë°ì´í„°ê°€ 있습니다" -#: utils/misc/guc.c:2385 -msgid "Sets the minimum execution time above which statements will be logged." -msgstr "" -"ì´ ì‹œê°„ì„ ì´ˆê³¼í•  경우 ì¿¼ë¦¬ë¬¸ì„ ë¡œê·¸ë¡œ 남길 최소 실행 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/cache/relmapper.c:690 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì— ìž˜ëª»ëœ checksum ê°’ì´ ìžˆìŒ" -#: utils/misc/guc.c:2387 -msgid "Zero prints all queries. -1 turns this feature off." -msgstr "" -"0ì„ ì§€ì •í•˜ë©´ 모든 쿼리가 ì¸ì‡„ë©ë‹ˆë‹¤. -1ì„ ì§€ì •í•˜ë©´ ì´ ê¸°ëŠ¥ì´ í•´ì œë©ë‹ˆë‹¤." +#: utils/cache/relmapper.c:789 +#, c-format +msgid "could not write to relation mapping file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ 쓸 수 없습니다: %m" -#: utils/misc/guc.c:2397 -msgid "" -"Sets the minimum execution time above which autovacuum actions will be " -"logged." -msgstr "" -"ì´ ì‹œê°„ì„ ì´ˆê³¼í•  경우 ìžë™ 청소 작업 로그를 남길 최소 실행 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆ" -"다." +#: utils/cache/relmapper.c:804 +#, c-format +msgid "could not fsync relation mapping file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ fsync í•  수 ì—†ìŒ: %m" -#: utils/misc/guc.c:2399 -msgid "Zero prints all actions. -1 turns autovacuum logging off." -msgstr "" -"0ì„ ì§€ì •í•˜ë©´ 모든 ìž‘ì—…ì´ ì¸ì‡„ë©ë‹ˆë‹¤. -1ì„ ì§€ì •í•˜ë©´ ìžë™ 청소 기ë¡ì´ í•´ì œë©ë‹ˆ" -"다." +#: utils/cache/relmapper.c:811 +#, c-format +msgid "could not close relation mapping file \"%s\": %m" +msgstr "\"%s\" 릴레ì´ì…˜ 맵핑 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %m" -#: utils/misc/guc.c:2409 -msgid "Background writer sleep time between rounds." -msgstr "백그ë¼ìš´ë“œ 기ë¡ìžì˜ ìž ìžëŠ” 시간" +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 +#, c-format +msgid "record type has not been registered" +msgstr "레코드 형ì‹ì´ 등ë¡ë˜ì§€ 않았ìŒ" -#: utils/misc/guc.c:2420 -msgid "Background writer maximum number of LRU pages to flush per round." -msgstr "ë¼ìš´ë“œë‹¹ 플러시할 백그ë¼ìš´ë“œ 작성기 최대 LRU 페ì´ì§€ 수입니다." +#: utils/error/assert.c:34 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: ìž˜ëª»ëœ ì¸ìž\n" -#: utils/misc/guc.c:2443 -msgid "" -"Number of simultaneous requests that can be handled efficiently by the disk " -"subsystem." -msgstr "" -"ë””ìŠ¤í¬ í•˜ìœ„ 시스템ì—서 효율ì ìœ¼ë¡œ 처리할 수 있는 ë™ì‹œ 요청 수입니다." +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", 파ì¼: \"%s\", 줄: %d)\n" -#: utils/misc/guc.c:2444 -msgid "" -"For RAID arrays, this should be approximately the number of drive spindles " -"in the array." -msgstr "RAID ë°°ì—´ì˜ ê²½ìš° ì´ ê°’ì€ ëŒ€ëžµ ë°°ì—´ì˜ ë“œë¼ì´ë¸Œ 스핀들 수입니다." +#: utils/error/elog.c:322 utils/error/elog.c:1306 +#, c-format +msgid "error occurred at %s:%d before error message processing is available\n" +msgstr "오류 메시지 처리가 활성화 ë˜ê¸° ì „ì— %s:%d ì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤\n" -#: utils/misc/guc.c:2470 -msgid "Maximum number of concurrent worker processes." -msgstr "ë™ì‹œ ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ì˜ ìµœëŒ€ 수" +#: utils/error/elog.c:1889 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "stderr 로 사용하기 위해 \"%s\" íŒŒì¼ ë‹¤ì‹œ 열기 실패: %m" -#: utils/misc/guc.c:2480 -msgid "Automatic log file rotation will occur after N minutes." -msgstr "Në¶„ í›„ì— ìžë™ 로그 íŒŒì¼ íšŒì „ì´ ë°œìƒí•©ë‹ˆë‹¤." +#: utils/error/elog.c:1902 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "표준출력(stdout)으로 사용하기 위해 \"%s\" 파ì¼ì„ 여는 ë„중 실패: %m" -#: utils/misc/guc.c:2491 -msgid "Automatic log file rotation will occur after N kilobytes." -msgstr "N킬로바ì´íЏ í›„ì— ìžë™ 로그 íŒŒì¼ íšŒì „ì´ ë°œìƒí•©ë‹ˆë‹¤." +#: utils/error/elog.c:2394 utils/error/elog.c:2411 utils/error/elog.c:2427 +msgid "[unknown]" +msgstr "[알수없ìŒ]" -#: utils/misc/guc.c:2502 -msgid "Shows the maximum number of function arguments." -msgstr "함수 ì¸ìžì˜ 최대 갯수를 ë³´ì—¬ì¤ë‹ˆë‹¤" +#: utils/error/elog.c:2887 utils/error/elog.c:3190 utils/error/elog.c:3298 +msgid "missing error text" +msgstr "오류 ë‚´ìš©ì„ ëºë‹ˆë‹¤" -#: utils/misc/guc.c:2513 -msgid "Shows the maximum number of index keys." -msgstr "ì¸ë±ìФ í‚¤ì˜ ìµœëŒ€ê°œìˆ˜ë¥¼ ë³´ì—¬ì¤ë‹ˆë‹¤." +#: utils/error/elog.c:2890 utils/error/elog.c:2893 utils/error/elog.c:3301 +#: utils/error/elog.c:3304 +#, c-format +msgid " at character %d" +msgstr " %d 번째 ë¬¸ìž ë¶€ê·¼" -#: utils/misc/guc.c:2524 -msgid "Shows the maximum identifier length." -msgstr "최대 ì‹ë³„ìž ê¸¸ì´ë¥¼ 표시합니다." +#: utils/error/elog.c:2903 utils/error/elog.c:2910 +msgid "DETAIL: " +msgstr "ìƒì„¸ì •ë³´: " -#: utils/misc/guc.c:2535 -msgid "Shows the size of a disk block." -msgstr "ë””ìŠ¤í¬ ë¸”ë¡ì˜ í¬ê¸°ë¥¼ 표시합니다." +#: utils/error/elog.c:2917 +msgid "HINT: " +msgstr "힌트: " -#: utils/misc/guc.c:2546 -msgid "Shows the number of pages per disk file." -msgstr "ë””ìŠ¤í¬ íŒŒì¼ë‹¹ 페ì´ì§€ 수를 표시합니다." +#: utils/error/elog.c:2924 +msgid "QUERY: " +msgstr "쿼리:" -#: utils/misc/guc.c:2557 -msgid "Shows the block size in the write ahead log." -msgstr "미리 쓰기 ë¡œê·¸ì˜ ë¸”ë¡ í¬ê¸°ë¥¼ 표시합니다." +#: utils/error/elog.c:2931 +msgid "CONTEXT: " +msgstr "ë‚´ìš©: " -#: utils/misc/guc.c:2568 -msgid "" -"Sets the time to wait before retrying to retrieve WAL after a failed attempt." -msgstr "" +#: utils/error/elog.c:2941 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "위치: %s, %s:%d\n" -#: utils/misc/guc.c:2580 -msgid "Shows the number of pages per write ahead log segment." -msgstr "미리 쓰기 로그 세그먼트당 페ì´ì§€ 수를 표시합니다." +#: utils/error/elog.c:2948 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "위치: %s:%d\n" -#: utils/misc/guc.c:2593 -msgid "Time to sleep between autovacuum runs." -msgstr "ìžë™ 청소 실행 사ì´ì˜ 절전 모드 시간입니다." +#: utils/error/elog.c:2962 +msgid "STATEMENT: " +msgstr "명령 구문: " -#: utils/misc/guc.c:2603 -msgid "Minimum number of tuple updates or deletes prior to vacuum." -msgstr "청소 ì „ì˜ ìµœì†Œ 튜플 ì—…ë°ì´íЏ ë˜ëŠ” ì‚­ì œ 수입니다." +#. translator: This string will be truncated at 47 +#. characters expanded. +#: utils/error/elog.c:3419 +#, c-format +msgid "operating system error %d" +msgstr "ìš´ì˜ì²´ì œ 오류 %d" -#: utils/misc/guc.c:2612 -msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." -msgstr "통계 ì •ë³´ ìˆ˜ì§‘ì„ ìœ„í•œ 최소 튜플 삽입, ì—…ë°ì´íЏ ë˜ëŠ” ì‚­ì œ 수입니다." +#: utils/error/elog.c:3617 +msgid "DEBUG" +msgstr "디버그" -#: utils/misc/guc.c:2622 -msgid "" -"Age at which to autovacuum a table to prevent transaction ID wraparound." -msgstr "" -"트랜잭션 ID 겹침 방지를 위해 í…Œì´ë¸”ì— ëŒ€í•´ autovacuum ìž‘ì—…ì„ ìˆ˜í–‰í•  í…Œì´ë¸” 나" -"ì´ë¥¼ 지정합니다." +#: utils/error/elog.c:3621 +msgid "LOG" +msgstr "로그" -#: utils/misc/guc.c:2633 -msgid "" -"Multixact age at which to autovacuum a table to prevent multixact wraparound." -msgstr "" -"멀티 트랜잭션 ID 겹침 방지를 위해 í…Œì´ë¸”ì— ëŒ€í•´ autovacuum ìž‘ì—…ì„ ìˆ˜í–‰í•  트랜" -"ìž­ì…˜ 나ì´ë¥¼ 지정합니다." +#: utils/error/elog.c:3624 +msgid "INFO" +msgstr "ì •ë³´" -#: utils/misc/guc.c:2643 -msgid "" -"Sets the maximum number of simultaneously running autovacuum worker " -"processes." -msgstr "ë™ì‹œì— 작업할 수 있는 autovacuum ìž‘ì—…ìž ìµœëŒ€ 수 지정" +#: utils/error/elog.c:3627 +msgid "NOTICE" +msgstr "알림" -#: utils/misc/guc.c:2653 -msgid "Sets the maximum number of parallel processes per executor node." -msgstr "실행 노드당 최대 병렬 처리 수 지정" +#: utils/error/elog.c:3630 +msgid "WARNING" +msgstr "경고" -#: utils/misc/guc.c:2663 -msgid "Sets the maximum memory to be used by each autovacuum worker process." -msgstr "ê° autovacuum ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ê°€ 사용할 메모리 최대치" +#: utils/error/elog.c:3633 +msgid "ERROR" +msgstr "오류" -#: utils/misc/guc.c:2674 -msgid "" -"Time before a snapshot is too old to read pages changed after the snapshot " -"was taken." -msgstr "" +#: utils/error/elog.c:3636 +msgid "FATAL" +msgstr "치명ì ì˜¤ë¥˜" -#: utils/misc/guc.c:2675 -msgid "A value of -1 disables this feature." -msgstr "ì´ ê°’ì´ -1 ì´ë©´ ì´ ê¸°ëŠ¥ 사용 안함" +#: utils/error/elog.c:3639 +msgid "PANIC" +msgstr "ì†ìƒ" -#: utils/misc/guc.c:2685 -msgid "Time between issuing TCP keepalives." -msgstr "TCP ì—°ê²° 유지 실행 간격입니다." +#: utils/fmgr/dfmgr.c:121 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "\"%s\" 함수를 \"%s\" 파ì¼ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: utils/misc/guc.c:2686 utils/misc/guc.c:2697 -msgid "A value of 0 uses the system default." -msgstr "ì´ ê°’ì´ 0ì´ë©´ 시스템 기본 ê°’" +#: utils/fmgr/dfmgr.c:239 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 불러 올 수 ì—†ìŒ: %s" -#: utils/misc/guc.c:2696 -msgid "Time between TCP keepalive retransmits." -msgstr "TCP keepalive 시간 설정" +#: utils/fmgr/dfmgr.c:271 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: magic black ì—†ìŒ" -#: utils/misc/guc.c:2707 -msgid "SSL renegotiation is no longer supported; this can only be 0." -msgstr "" +#: utils/fmgr/dfmgr.c:273 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "확장 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 만들 때, PG_MODULE_MAGIC 매í¬ë¡œë¥¼ 사용해서 만드세요." -#: utils/misc/guc.c:2718 -msgid "Maximum number of TCP keepalive retransmits." -msgstr "TCP keepalive í™•ì¸ ìµœëŒ€ 횟수" +#: utils/fmgr/dfmgr.c:319 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: ë²„ì „ì´ í‹€ë¦¼" -#: utils/misc/guc.c:2719 -msgid "" -"This controls the number of consecutive keepalive retransmits that can be " -"lost before a connection is considered dead. A value of 0 uses the system " -"default." -msgstr "" -"ì´ ê°’ì€ ì—°ê²°ì´ ì¤‘ë‹¨ëœ ê²ƒìœ¼ë¡œ 간주ë˜ê¸° ì „ì— ì†ì‹¤ë  수 있는 ì—°ì† ì—°ê²° 유" -"ì§€ 재전송 수를 제어합니다. ê°’ 0ì„ ì§€ì •í•˜ë©´ 시스템 기본 ê°’ì´ ì‚¬ìš©ë©ë‹ˆë‹¤." +#: utils/fmgr/dfmgr.c:321 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "서버 버전 = %d, ë¼ì´ë¸ŒëŸ¬ë¦¬ 버전 %s." -#: utils/misc/guc.c:2730 -msgid "Sets the maximum allowed result for exact search by GIN." -msgstr "정확한 GIN 기준 ê²€ìƒ‰ì— í—ˆìš©ë˜ëŠ” 최대 ê²°ê³¼ 수를 설정합니다." +#: utils/fmgr/dfmgr.c:338 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "ì„œë²„ì˜ ê²½ìš° FUNC_MAX_ARGS = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." -#: utils/misc/guc.c:2741 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "ë””ìŠ¤í¬ ìºì‹œ í¬ê¸°ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ê°€ì •ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/fmgr/dfmgr.c:347 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "ì„œë²„ì˜ ê²½ìš° INDEX_MAX_KEYS = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." -#: utils/misc/guc.c:2742 -msgid "" -"That is, the portion of the kernel's disk cache that will be used for " -"PostgreSQL data files. This is measured in disk pages, which are normally 8 " -"kB each." -msgstr "" -"즉, PostgreSQL ë°ì´í„° 파ì¼ì— ì‚¬ìš©ë  ì»¤ë„ì˜ ë””ìŠ¤í¬ ìºì‹œ 부분입니다. ì´ ê°’" -"ì€ ë””ìŠ¤í¬ íŽ˜ì´ì§€ 단위로 측정ë˜ë©°, ì¼ë°˜ì ìœ¼ë¡œ ê°ê° 8KB입니다." +#: utils/fmgr/dfmgr.c:356 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "ì„œë²„ì˜ ê²½ìš° NAMEDATALEN = %dì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %dì´(ê°€) 있습니다." -#: utils/misc/guc.c:2754 -msgid "Sets the minimum size of relations to be considered for parallel scan." -msgstr "" +#: utils/fmgr/dfmgr.c:365 +#, c-format +msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +msgstr "ì„œë²„ì˜ ê²½ìš° FLOAT4PASSBYVAL = %sì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %sì´(ê°€) 있습니다." -#: utils/misc/guc.c:2766 -msgid "Shows the server version as an integer." -msgstr "서버 ë²„ì „ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ ë³´ì—¬ì¤ë‹ˆë‹¤" +#: utils/fmgr/dfmgr.c:374 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "ì„œë²„ì˜ ê²½ìš° FLOAT8PASSBYVAL = %sì¸ë° ë¼ì´ë¸ŒëŸ¬ë¦¬ì— %sì´(ê°€) 있습니다." -#: utils/misc/guc.c:2777 -msgid "Log the use of temporary files larger than this number of kilobytes." -msgstr "ì´ í‚¬ë¡œë°”ì´íЏ 수보다 í° ìž„ì‹œ 파ì¼ì˜ ì‚¬ìš©ì„ ê¸°ë¡í•©ë‹ˆë‹¤." +#: utils/fmgr/dfmgr.c:381 +msgid "Magic block has unexpected length or padding difference." +msgstr "ë§¤ì§ ë¸”ë¡ì— 예기치 ì•Šì€ ê¸¸ì´ ë˜ëŠ” 여백 ì°¨ì´ê°€ 있습니다." -#: utils/misc/guc.c:2778 -msgid "Zero logs all files. The default is -1 (turning this feature off)." -msgstr "" -"0ì„ ì§€ì •í•˜ë©´ 모든 파ì¼ì´ 기ë¡ë©ë‹ˆë‹¤. 기본 ê°’ì€ -1로, ì´ ê¸°ëŠ¥ì´ í•´ì œë©ë‹ˆë‹¤." +#: utils/fmgr/dfmgr.c:384 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ëŠ” 사용할 수 없습니다: magic black 틀림" -#: utils/misc/guc.c:2788 -msgid "Sets the size reserved for pg_stat_activity.query, in bytes." -msgstr "pg_stat_activity.queryì— ì˜ˆì•½ë˜ëŠ” í¬ê¸°(ë°”ì´íЏ)를 설정합니다." +#: utils/fmgr/dfmgr.c:548 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ ì‚¬ìš©ì´ ê¸ˆì§€ë˜ì–´ìžˆìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:2803 -msgid "Sets the maximum size of the pending list for GIN index." -msgstr "GIN ì¸ë±ìŠ¤ë¥¼ 위한 팬딩(pending) 목ë¡ì˜ 최대 í¬ê¸° 지정" +#: utils/fmgr/dfmgr.c:574 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "ë™ì  ë¼ì´ë¸ŒëŸ¬ë¦¬ 경로ì—서 ìž˜ëª»ëœ ë§¤í¬ë¡œ ì´ë¦„: %s" -#: utils/misc/guc.c:2823 -msgid "" -"Sets the planner's estimate of the cost of a sequentially fetched disk page." -msgstr "" -"순차ì ìœ¼ë¡œ 접근하는 ë””ìŠ¤í¬ íŽ˜ì´ì§€ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆ" -"다." +#: utils/fmgr/dfmgr.c:614 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "\"dynamic_library_path\" 매개 변수 값으로 길ì´ê°€ 0ì¸ ê°’ì„ ì‚¬ìš©í–ˆìŒ" -#: utils/misc/guc.c:2833 -msgid "" -"Sets the planner's estimate of the cost of a nonsequentially fetched disk " -"page." -msgstr "" -"비순차ì ìœ¼ë¡œ 접근하는 ë””ìŠ¤í¬ íŽ˜ì´ì§€ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆ" -"다." +#: utils/fmgr/dfmgr.c:633 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "\"dynamic_library_path\" 매개 변수 값으로 절대 경로를 사용할 수 ì—†ìŒ" -#: utils/misc/guc.c:2843 -msgid "Sets the planner's estimate of the cost of processing each tuple (row)." -msgstr "ê° íŠœí”Œ(í–‰)ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/fmgr/fmgr.c:236 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "\"%s\" ë‚´ë¶€ 함수를 ë‚´ë¶€ 검색 í…Œì´ë¸”ì—서 ì°¾ì„ ìˆ˜ 없습니다" -#: utils/misc/guc.c:2853 -msgid "" -"Sets the planner's estimate of the cost of processing each index entry " -"during an index scan." -msgstr "" -"실행 계íšê¸°ì˜ 비용 ê³„ì‚°ì— ì‚¬ìš©ë  ì¸ë±ìФ 스캔으로 ê° ì¸ë±ìФ í•­ëª©ì„ ì²˜ë¦¬í•˜ëŠ” 예" -"ìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/fmgr/fmgr.c:485 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "\"%s\" í•¨ìˆ˜ì˜ í•¨ìˆ˜ 정보를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: utils/misc/guc.c:2863 -msgid "" -"Sets the planner's estimate of the cost of processing each operator or " -"function call." +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." msgstr "" -"실행 계íšê¸°ì˜ 비용 ê³„ì‚°ì— ì‚¬ìš©ë  í•¨ìˆ˜ 호출ì´ë‚˜ ì—°ì‚°ìž ì—°ì‚° 처리하는 ì˜ˆìƒ ì²˜" -"리 ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/misc/guc.c:2873 -msgid "" -"Sets the planner's estimate of the cost of passing each tuple (row) from " -"worker to master backend." -msgstr "ê° íŠœí”Œ(í–‰)ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/fmgr/fmgr.c:505 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "_^_ %d 알수 없는 API ë²„ì „ì´ \"%s\" í•¨ìˆ˜ì— ì˜í•´ì„œ ë³´ê³ ë˜ì—ˆìŒ" -#: utils/misc/guc.c:2883 -msgid "" -"Sets the planner's estimate of the cost of starting up worker processes for " -"parallel query." -msgstr "" +#: utils/fmgr/fmgr.c:2210 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "%u OID 언어 유효성 검사 함수가 %u OID 프로시져 언어용으로 호출ë˜ì—ˆìŒ, ì›ëž˜ 언어는 %u" -#: utils/misc/guc.c:2894 -msgid "" -"Sets the planner's estimate of the fraction of a cursor's rows that will be " -"retrieved." -msgstr "ê²€ìƒ‰ë  ì»¤ì„œ í–‰ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¶„ìˆ˜ ê°’ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/fmgr/funcapi.c:358 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "\"%s\" í•¨ìˆ˜ì˜ ì‹¤ìž¬ 리턴 ìžë£Œí˜•ì„ ì•Œ 수 ì—†ìŒ, ì •ì˜ëœ 리턴 ìžë£Œí˜•: %s" -#: utils/misc/guc.c:2905 -msgid "GEQO: selective pressure within the population." -msgstr "GEQO: 모집단 ë‚´ì˜ ì„ íƒ ì••ë ¥ìž…ë‹ˆë‹¤." +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "alias 수가 ì—´ 수와 틀립니다" -#: utils/misc/guc.c:2915 -msgid "GEQO: seed for random path selection." -msgstr "GEQO: 무작위 경로 ì„ íƒì„ 위한 씨드" +#: utils/fmgr/funcapi.c:1429 +#, c-format +msgid "no column alias was provided" +msgstr "ì—´ ë³„ì¹­ì´ ì œê³µë˜ì§€ 않았ìŒ" -#: utils/misc/guc.c:2925 -msgid "Multiple of the average buffer usage to free per round." -msgstr "ë¼ìš´ë“œë‹¹ 해제할 í‰ê·  ë²„í¼ ì‚¬ìš©ì˜ ë°°ìˆ˜ìž…ë‹ˆë‹¤." +#: utils/fmgr/funcapi.c:1453 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "레코드를 리턴하는 함수를 위한 í–‰(row) 구성 정보를 구할 수 ì—†ìŒ" -#: utils/misc/guc.c:2935 -msgid "Sets the seed for random-number generation." -msgstr "난수 ìƒì„± ì†ë„를 설정합니다." +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "\"%s\" ë°ì´í„° 디렉터리 ì—†ìŒ" -#: utils/misc/guc.c:2946 -msgid "" -"Number of tuple updates or deletes prior to vacuum as a fraction of " -"reltuples." -msgstr "" -"vacuum ìž‘ì—…ì„ ì§„í–‰í•  update, delete ìž‘ì—…ëŸ‰ì„ ì „ì²´ ìžë£Œì— 대한 분수값으로 지정" -"합니다." +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" 디렉터리 ì½ê¸° 권한 ì—†ìŒ: %m" -#: utils/misc/guc.c:2955 -msgid "" -"Number of tuple inserts, updates, or deletes prior to analyze as a fraction " -"of reltuples." -msgstr "" -"통계 수집 ìž‘ì—…ì„ ì§„í–‰í•  insert, update, delete ìž‘ì—…ëŸ‰ì„ ì „ì²´ ìžë£Œì— 대한 분수" -"값으로 지정합니다." +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "지정한 \"%s\" ë°ì´í„° 디렉터리는 디렉터리가 아님" -#: utils/misc/guc.c:2965 -msgid "" -"Time spent flushing dirty buffers during checkpoint, as fraction of " -"checkpoint interval." -msgstr "" -"ì²´í¬í¬ì¸íЏ ë„중 ë³€ê²½ëœ ë²„í¼ í”ŒëŸ¬ì‹œì— ì‚¬ìš©ëœ ì‹œê°„ìœ¼ë¡œ, ì²´í¬í¬ì¸íЏ ê°„ê²©ì˜ " -"분수 값입니다." +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "\"%s\" ë°ì´í„° 디렉터리 소유주가 잘못 ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:2984 -msgid "Sets the shell command that will be called to archive a WAL file." -msgstr "WAL 파ì¼ì„ ì•„ì¹´ì´ë¹™í•˜ê¸° 위해 í˜¸ì¶œë  ì…¸ ëª…ë ¹ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "서버는 지정한 ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ì†Œìœ ì£¼ 권한으로 시작ë˜ì–´ì•¼í•©ë‹ˆë‹¤." -#: utils/misc/guc.c:2994 -msgid "Sets the client's character set encoding." -msgstr "í´ë¼ì´ì–¸íЏ ë¬¸ìž ì„¸íŠ¸ ì¸ì½”ë”©ì„ ì§€ì •í•¨" +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "\"%s\" ë°ì´í„° 디렉터리 ì ‘ê·¼ ê¶Œí•œì— ë¬¸ì œê°€ 있습니다." -#: utils/misc/guc.c:3005 -msgid "Controls information prefixed to each log line." -msgstr "ê° ë¡œê·¸ 줄 ì•žì— ì¶”ê°€í•  정보를 제어합니다." +#: utils/init/miscinit.c:159 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "액세스 ê¶Œí•œì€ u=rwx (0700) ë˜ëŠ” u=rwx,o=rx (0750) ê°’ì´ì–´ì•¼ 합니다." -#: utils/misc/guc.c:3006 -msgid "If blank, no prefix is used." -msgstr "비워 ë‘ë©´ ì ‘ë‘사가 사용ë˜ì§€ 않습니다." +#: utils/init/miscinit.c:218 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "\"%s\" ì´ë¦„ì˜ ë””ë ‰í„°ë¦¬ë¡œ ì´ë™í•  수 없습니다: %m" -#: utils/misc/guc.c:3015 -msgid "Sets the time zone to use in log messages." -msgstr "로그 ë©”ì‹œì§€ì— ì‚¬ìš©í•  표준 시간대를 설정합니다." +#: utils/init/miscinit.c:546 utils/misc/guc.c:6360 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "보안 제한 작업 ë‚´ì—서 \"%s\" 매개 변수를 설정할 수 ì—†ìŒ" -#: utils/misc/guc.c:3025 -msgid "Sets the display format for date and time values." -msgstr "날짜와 시간 ê°’ì„ ë‚˜íƒ€ë‚´ëŠ” ëª¨ì–‘ì„ ì§€ì •í•©ë‹ˆë‹¤." +#: utils/init/miscinit.c:607 +#, c-format +msgid "role with OID %u does not exist" +msgstr "%u OID ë¡¤ì´ ì—†ìŒ" -#: utils/misc/guc.c:3026 -msgid "Also controls interpretation of ambiguous date inputs." -msgstr "ë˜í•œ 모호한 ë‚ ì§œ ìž…ë ¥ì˜ í•´ì„ì„ ì œì–´í•©ë‹ˆë‹¤." +#: utils/init/miscinit.c:637 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "\"%s\" ë¡¤ì€ ì ‘ì†ì„ 허용하지 않ìŒ" -#: utils/misc/guc.c:3037 -msgid "Sets the default tablespace to create tables and indexes in." -msgstr "í…Œì´ë¸” ë° ì¸ë±ìŠ¤ë¥¼ 만들 기본 í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 설정합니다." +#: utils/init/miscinit.c:655 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "\"%s\" ë¡¤ì˜ ìµœëŒ€ ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 초과했습니다" -#: utils/misc/guc.c:3038 -msgid "An empty string selects the database's default tablespace." -msgstr "빈 문ìžì—´ì„ 지정하면 ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ í…Œì´ë¸”스페ì´ìŠ¤ê°€ ì„ íƒë©ë‹ˆë‹¤." +#: utils/init/miscinit.c:715 +#, c-format +msgid "permission denied to set session authorization" +msgstr "세션 ì¸ì¦ì„ 지정하기 위한 ê¶Œí•œì´ ì—†ìŒ" -#: utils/misc/guc.c:3048 -msgid "Sets the tablespace(s) to use for temporary tables and sort files." -msgstr "임시 í…Œì´ë¸” ë° ì •ë ¬ 파ì¼ì— 사용할 í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 설정합니다." +#: utils/init/miscinit.c:798 +#, c-format +msgid "invalid role OID: %u" +msgstr "ìž˜ëª»ëœ ë¡¤ OID: %u" -#: utils/misc/guc.c:3059 -msgid "Sets the path for dynamically loadable modules." -msgstr "ë™ì ìœ¼ë¡œ 불러올 수 있는 ëª¨ë“ˆë“¤ì´ ìžˆëŠ” 경로를 지정함." +#: utils/init/miscinit.c:852 +#, c-format +msgid "database system is shut down" +msgstr "ë°ì´í„°ë² ì´ìФ 시스템 서비스를 중지했습니다" -#: utils/misc/guc.c:3060 -msgid "" -"If a dynamically loadable module needs to be opened and the specified name " -"does not have a directory component (i.e., the name does not contain a " -"slash), the system will search this path for the specified file." -msgstr "" -"ë™ì ìœ¼ë¡œ 로드 가능한 ëª¨ë“ˆì„ ì—´ì–´ì•¼ í•˜ëŠ”ë° ì§€ì •í•œ ì´ë¦„ì— ë””ë ‰í„°ë¦¬ 구성 ìš”" -"소가 없는 경우(즉, ì´ë¦„ì— ìŠ¬ëž˜ì‹œê°€ ì—†ìŒ) ì‹œìŠ¤í…œì€ ì´ ê²½ë¡œì—서 지정한 파ì¼ì„ " -"검색합니다." +#: utils/init/miscinit.c:939 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파ì¼ì„ 만들 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3073 -msgid "Sets the location of the Kerberos server key file." -msgstr "Kerberos 서버 키 파ì¼ì˜ 위치를 지정함." +#: utils/init/miscinit.c:953 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "\"%s\" 잠금파ì¼ì„ ì—´ 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3084 -msgid "Sets the Bonjour service name." -msgstr "Bonjour 서비스 ì´ë¦„ì„ ì§€ì •" +#: utils/init/miscinit.c:960 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3096 -msgid "Shows the collation order locale." -msgstr "ë°ì´í„° ì •ë ¬ 순서 로케ì¼ì„ 표시합니다." +#: utils/init/miscinit.c:969 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "\"%s\" 잠금 파ì¼ì´ 비었ìŒ" -#: utils/misc/guc.c:3107 -msgid "Shows the character classification and case conversion locale." -msgstr "ë¬¸ìž ë¶„ë¥˜ ë° ëŒ€/ì†Œë¬¸ìž ë³€í™˜ 로케ì¼ì„ 표시합니다." +#: utils/init/miscinit.c:970 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "" -#: utils/misc/guc.c:3118 -msgid "Sets the language in which messages are displayed." -msgstr "보여질 메시지로 사용할 언어 지정." +#: utils/init/miscinit.c:1014 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "\"%s\" 잠금 파ì¼ì´ ì´ë¯¸ 있ìŒ" -#: utils/misc/guc.c:3128 -msgid "Sets the locale for formatting monetary amounts." -msgstr "통화금액 표현 ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." +#: utils/init/miscinit.c:1018 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "다른 postgres 프로그램(PID %d)ì´ \"%s\" ë°ì´í„° 디렉터리를 사용해서 실행중입니까?" -#: utils/misc/guc.c:3138 -msgid "Sets the locale for formatting numbers." -msgstr "ìˆ«ìž í‘œí˜„ ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." +#: utils/init/miscinit.c:1020 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "다른 postmaster 프로그램(PID %d)ì´ \"%s\" ë°ì´í„° 디렉터리를 사용해서 실행중입니까?" -#: utils/misc/guc.c:3148 -msgid "Sets the locale for formatting date and time values." -msgstr "날짜와 시간 ê°’ì„ í‘œí˜„í•  ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." +#: utils/init/miscinit.c:1023 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "다른 postgres 프로그램(PID %d)ì´ \"%s\" 소켓 파ì¼ì„ 사용해서 실행중입니까?" -#: utils/misc/guc.c:3158 -msgid "Lists shared libraries to preload into each backend." -msgstr "ê°ê°ì˜ ë°±ì—”ë“œì— ë¯¸ë¦¬ 불러올 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" +#: utils/init/miscinit.c:1025 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "다른 postmaster 프로그램(PID %d)ì´ \"%s\" 소켓 파ì¼ì„ 사용해서 실행중입니까?" -#: utils/misc/guc.c:3169 -msgid "Lists shared libraries to preload into server." -msgstr "ì„œë²„ì— ë¯¸ë¦¬ 불러올 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" +#: utils/init/miscinit.c:1061 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "미리 í™•ë³´ëœ ê³µìœ  메모리 ì˜ì—­ (%lu 키, %lu ID)ì´ ì—¬ì „ížˆ 사용중입니다" -#: utils/misc/guc.c:3180 -msgid "Lists unprivileged shared libraries to preload into each backend." -msgstr "" -"ê°ê°ì˜ ë°±ì—”ë“œì— ë¯¸ë¦¬ 불러올 접근제한 없는 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" +#: utils/init/miscinit.c:1064 +#, c-format +msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." +msgstr "확실하게 공유 메모리를 사용하는 다른 프로세스가 없다고 íŒë‹¨ë˜ë©´, 공유 메모리 ì˜ì—­ì„ 삭제하거나 \"%s\" 파ì¼ì„ 지우십시오." -#: utils/misc/guc.c:3191 -msgid "Sets the schema search order for names that are not schema-qualified." -msgstr "스키마로 한정ë˜ì§€ ì•Šì€ ì´ë¦„ì˜ ìŠ¤í‚¤ë§ˆ 검색 순서를 설정합니다." +#: utils/init/miscinit.c:1080 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "\"%s\" 옛 잠금 파ì¼ì„ 삭제할 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3203 -msgid "Sets the server (database) character set encoding." -msgstr "서버 ë¬¸ìž ì½”ë“œ 세트 ì¸ì½”딩 지정." +#: utils/init/miscinit.c:1082 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "그파ì¼ì€ 우연찮게 ì™¼ìª½ì„ ë„˜ì–´ê°„ 것(?) 같습지만, ì‚­ì œë  ìˆ˜ëŠ” 없습니다. ì§ì ‘ ì…¸ ëª…ë ¹ì„ ì´ìš©í•´ì„œ 파ì¼ì„ ì‚­ì œ 하고 다시 시ë„í•´ 보십시오. - ë‚´ìš© ì°¸ 거시기 하네" -#: utils/misc/guc.c:3215 -msgid "Shows the server version." -msgstr "서버 버전 ë³´ìž„." +#: utils/init/miscinit.c:1119 utils/init/miscinit.c:1133 +#: utils/init/miscinit.c:1144 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "\"%s\" 잠금 파ì¼ì— 쓸 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3227 -msgid "Sets the current role." -msgstr "현재 ë¡¤ì„ ì§€ì •" +#: utils/init/miscinit.c:1276 utils/init/miscinit.c:1419 utils/misc/guc.c:9201 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: utils/misc/guc.c:3239 -msgid "Sets the session user name." -msgstr "세션 ì‚¬ìš©ìž ì´ë¦„ 지정." +#: utils/init/miscinit.c:1407 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %m; 어째든 ê³„ì† ì§„í–‰í•¨" -#: utils/misc/guc.c:3250 -msgid "Sets the destination for server log output." -msgstr "서버 로그 ì¶œë ¥ì„ ìœ„í•œ 대ìƒì„ 지정합니다." +#: utils/init/miscinit.c:1432 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "\"%s\" 잠금 파ì¼ì— 있는 PID ê°’ì´ ì´ìƒí•©ë‹ˆë‹¤: 현재값 %ld, ì›ëž˜ê°’ %ld" -#: utils/misc/guc.c:3251 -msgid "" -"Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and " -"\"eventlog\", depending on the platform." -msgstr "" -"유효한 ê°’ì€ í”Œëž«í¼ì— ë”°ë¼ \"stderr\", \"syslog\", \"csvlog\" ë° \"eventlog" -"\"ì˜ ì¡°í•©ìž…ë‹ˆë‹¤." +#: utils/init/miscinit.c:1471 utils/init/miscinit.c:1487 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" ê°’ì€ ë°”ë¥¸ ë°ì´í„°ë””렉터리가 아닙니다" -#: utils/misc/guc.c:3262 -msgid "Sets the destination directory for log files." -msgstr "로그 파ì¼ì˜ ëŒ€ìƒ ë””ë ‰í„°ë¦¬ë¥¼ 설정합니다." +#: utils/init/miscinit.c:1473 +#, c-format +msgid "File \"%s\" is missing." +msgstr "\"%s\" 파ì¼ì´ 없습니다." -#: utils/misc/guc.c:3263 -msgid "Can be specified as relative to the data directory or as absolute path." -msgstr "ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ìƒëŒ€ 경로 ë˜ëŠ” 절대 경로로 지정할 수 있습니다." +#: utils/init/miscinit.c:1489 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "\"%s\" 파ì¼ì— ìž˜ëª»ëœ ìžë£Œê°€ 기ë¡ë˜ì–´ 있습니다." -#: utils/misc/guc.c:3273 -msgid "Sets the file name pattern for log files." -msgstr "로그 파ì¼ì˜ íŒŒì¼ ì´ë¦„ íŒ¨í„´ì„ ì„¤ì •í•©ë‹ˆë‹¤." +#: utils/init/miscinit.c:1491 +#, c-format +msgid "You might need to initdb." +msgstr "initdb ëª…ë ¹ì„ ì‹¤í–‰í•´ 새 í´ëŸ¬ìŠ¤í„°ë¥¼ 만들어야 í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:3284 -msgid "Sets the program name used to identify PostgreSQL messages in syslog." -msgstr "syslogì—서 구분할 PostgreSQL ë©”ì‹œì§€ì— ì‚¬ìš©ë  í”„ë¡œê·¸ëž¨ ì´ë¦„ì„ ì§€ì •." +#: utils/init/miscinit.c:1499 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "ì´ ë°ì´í„° 디렉터리는 PostgreSQL %s 버전으로 초기화 ë˜ì–´ìžˆëŠ”ë°, ì´ ì„œë²„ì˜ %s ë²„ì „ì€ ì´ ë²„ì „ê³¼ í˜¸í™˜ì„±ì´ ì—†ìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:3295 -msgid "" -"Sets the application name used to identify PostgreSQL messages in the event " -"log." -msgstr "" -"ì´ë²¤íЏ 로그ì—서 PostgreSQL 메시지 ì‹ë³„ìžë¡œ 사용할 ì‘용프로그램 ì´ë¦„ 지정" +#: utils/init/miscinit.c:1566 +#, c-format +msgid "loaded library \"%s\"" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ 로드 완료" -#: utils/misc/guc.c:3306 -msgid "Sets the time zone for displaying and interpreting time stamps." -msgstr "시간대(time zone)를 지정함." +#: utils/init/postinit.c:252 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "복제 ì—°ê²° ì¸ì¦: 사용ìž=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, 비트=%d, ì••ì¶•=%s)" -#: utils/misc/guc.c:3316 -msgid "Selects a file of time zone abbreviations." -msgstr "표준 시간대 약어 파ì¼ì„ ì„ íƒí•©ë‹ˆë‹¤." +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "off" +msgstr "off" -#: utils/misc/guc.c:3326 -msgid "Sets the current transaction's isolation level." -msgstr "현재 트랜잭션 ë…립성 수준(isolation level)ì„ ì§€ì •í•¨." +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "on" +msgstr "on" -#: utils/misc/guc.c:3337 -msgid "Sets the owning group of the Unix-domain socket." -msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì˜ ì†Œìœ ì£¼ë¥¼ 지정" +#: utils/init/postinit.c:261 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "복제 ì—°ê²° ì¸ì¦: 사용ìž=%s" -#: utils/misc/guc.c:3338 -msgid "" -"The owning user of the socket is always the user that starts the server." -msgstr "소켓 소유ìžëŠ” í•­ìƒ ì„œë²„ë¥¼ 시작하는 사용ìžìž…니다." +#: utils/init/postinit.c:269 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "ì—°ê²° ì¸ì¦: 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s SSL 활성화 (프로토콜=%s, 알고리즘=%s, 비트=%d, ì••ì¶•=%s)" -#: utils/misc/guc.c:3348 -msgid "Sets the directories where Unix-domain sockets will be created." -msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 디렉터리를 지정합니다." +#: utils/init/postinit.c:278 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "ì—°ê²° ì¸ì¦: 사용ìž=%s ë°ì´í„°ë² ì´ìФ=%s" -#: utils/misc/guc.c:3363 -msgid "Sets the host name or IP address(es) to listen to." -msgstr "서비스할 호스트ì´ë¦„ì´ë‚˜, IP를 지정함." +#: utils/init/postinit.c:310 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” pg_database í•­ëª©ì— ì—†ìŠµë‹ˆë‹¤" -#: utils/misc/guc.c:3378 -msgid "Sets the server's data directory." -msgstr "ì„œë²„ì˜ ë°ì´í„° 디렉터리 위치를 지정합니다." +#: utils/init/postinit.c:312 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "ë°ì´í„°ë² ì´ìФ OID %uì´(ê°€) 현재 \"%s\"ì— ì†í•´ 있는 것 같습니다." -#: utils/misc/guc.c:3389 -msgid "Sets the server's main configuration file." -msgstr "ì„œë²„ì˜ ê¸°ë³¸ 환경설정 íŒŒì¼ ê²½ë¡œë¥¼ 지정합니다." +#: utils/init/postinit.c:332 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ëŠ” 현재 ì ‘ì†ì„ 허용하지 않습니다" -#: utils/misc/guc.c:3400 -msgid "Sets the server's \"hba\" configuration file." -msgstr "ì„œë²„ì˜ \"hba\" 구성 파ì¼ì„ 설정합니다." - -#: utils/misc/guc.c:3411 -msgid "Sets the server's \"ident\" configuration file." -msgstr "ì„œë²„ì˜ \"ident\" 구성 파ì¼ì„ 설정합니다." - -#: utils/misc/guc.c:3422 -msgid "Writes the postmaster PID to the specified file." -msgstr "postmaster PIDê°€ 기ë¡ëœ 파ì¼ì˜ 경로를 지정합니다." - -#: utils/misc/guc.c:3433 -msgid "Location of the SSL server certificate file." -msgstr "서버 ì¸ì¦ì„œ íŒŒì¼ ìœ„ì¹˜ë¥¼ 지정함" - -#: utils/misc/guc.c:3443 -msgid "Location of the SSL server private key file." -msgstr "SSL 서버 ê°œì¸ í‚¤ 파ì¼ì˜ 위치를 지정함." - -#: utils/misc/guc.c:3453 -msgid "Location of the SSL certificate authority file." -msgstr "" - -#: utils/misc/guc.c:3463 -msgid "Location of the SSL certificate revocation list file." -msgstr "SSL ì¸ì¦ì„œ 파기 ëª©ë¡ íŒŒì¼ì˜ 위치" - -#: utils/misc/guc.c:3473 -msgid "Writes temporary statistics files to the specified directory." -msgstr "지정한 ë””ë ‰í„°ë¦¬ì— ìž„ì‹œ 통계 파ì¼ì„ ì”니다." - -#: utils/misc/guc.c:3484 -msgid "" -"Number of synchronous standbys and list of names of potential synchronous " -"ones." -msgstr "" - -#: utils/misc/guc.c:3495 -msgid "Sets default text search configuration." -msgstr "기본 í…스트 검색 êµ¬ì„±ì„ ì„¤ì •í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3505 -msgid "Sets the list of allowed SSL ciphers." -msgstr "허용ë˜ëŠ” SSL 암호 목ë¡ì„ 설정합니다." - -#: utils/misc/guc.c:3520 -msgid "Sets the curve to use for ECDH." -msgstr "ECDHì— ì‚¬ìš©í•  curve 설정" - -#: utils/misc/guc.c:3535 -msgid "Sets the application name to be reported in statistics and logs." -msgstr "" - -#: utils/misc/guc.c:3546 -msgid "Sets the name of the cluster, which is included in the process title." -msgstr "" - -#: utils/misc/guc.c:3566 -msgid "Sets whether \"\\'\" is allowed in string literals." -msgstr "문ìžì—´ì—서 \"\\'\" ë¬¸ìž ì‚¬ìš©ì„ í—ˆìš©í•  것ì¸ì§€ë¥¼ 정하세요" - -#: utils/misc/guc.c:3576 -msgid "Sets the output format for bytea." -msgstr "bytea ê°’ì˜ í‘œì‹œ 형ì‹ì„ 설정합니다." - -#: utils/misc/guc.c:3586 -msgid "Sets the message levels that are sent to the client." -msgstr "í´ë¼ì´ì–¸íЏ ì¸¡ì— ë³´ì—¬ì§ˆ 메시지 ìˆ˜ì¤€ì„ ì§€ì •í•¨." - -#: utils/misc/guc.c:3587 utils/misc/guc.c:3640 utils/misc/guc.c:3651 -#: utils/misc/guc.c:3717 -msgid "" -"Each level includes all the levels that follow it. The later the level, the " -"fewer messages are sent." -msgstr "" -"ê° ìˆ˜ì¤€ì—는 ì´ ìˆ˜ì¤€ ë’¤ì— ìžˆëŠ” 모든 ìˆ˜ì¤€ì´ í¬í•¨ë©ë‹ˆë‹¤. ìˆ˜ì¤€ì´ ë’¤ì— ìžˆì„수" -"ë¡ ì „ì†¡ë˜ëŠ” 메시지 수가 ì ìŠµë‹ˆë‹¤." - -#: utils/misc/guc.c:3597 -msgid "Enables the planner to use constraints to optimize queries." -msgstr "실행계íšê¸°ê°€ 쿼리 최ì í™” 작업ì—서 제약 ì¡°ê±´ì„ ì‚¬ìš©í•˜ë„ë¡ í•¨" - -#: utils/misc/guc.c:3598 -msgid "" -"Table scans will be skipped if their constraints guarantee that no rows " -"match the query." -msgstr "" -"제약 ì¡°ê±´ì— ì˜í•´ 쿼리와 ì¼ì¹˜í•˜ëŠ” í–‰ì´ ì—†ëŠ” 경우 í…Œì´ë¸” ìŠ¤ìº”ì„ ê±´ë„ˆëœë‹ˆ" -"다." - -#: utils/misc/guc.c:3608 -msgid "Sets the transaction isolation level of each new transaction." -msgstr "ê° ìƒˆ íŠ¸ëžœìž­ì…˜ì˜ íŠ¸ëžœìž­ì…˜ 격리 ìˆ˜ì¤€ì„ ì„¤ì •í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3618 -msgid "Sets the display format for interval values." -msgstr "간격 ê°’ì˜ í‘œì‹œ 형ì‹ì„ 설정합니다." - -#: utils/misc/guc.c:3629 -msgid "Sets the verbosity of logged messages." -msgstr "기ë¡ë˜ëŠ” ë©”ì‹œì§€ì˜ ìƒì„¸ ì •ë„를 지정합니다." - -#: utils/misc/guc.c:3639 -msgid "Sets the message levels that are logged." -msgstr "서버 ë¡œê·¸ì— ê¸°ë¡ë  메시지 ìˆ˜ì¤€ì„ ì§€ì •í•¨." - -#: utils/misc/guc.c:3650 -msgid "" -"Causes all statements generating error at or above this level to be logged." -msgstr "" -"오류가 있는 모든 쿼리문ì´ë‚˜ 지정한 로그 레벨 ì´ìƒì˜ ì¿¼ë¦¬ë¬¸ì„ ë¡œê·¸ë¡œ 남김" - -#: utils/misc/guc.c:3661 -msgid "Sets the type of statements logged." -msgstr "ì„œë²„ë¡œê·¸ì— ê¸°ë¡ë  구문 종류를 지정합니다." - -#: utils/misc/guc.c:3671 -msgid "Sets the syslog \"facility\" to be used when syslog enabled." -msgstr "syslog ê¸°ëŠ¥ì„ ì‚¬ìš©í•  때, 사용할 syslog \"facility\" ê°’ì„ ì§€ì •." - -#: utils/misc/guc.c:3686 -msgid "Sets the session's behavior for triggers and rewrite rules." -msgstr "트리거 ë° ë‹¤ì‹œ 쓰기 ê·œì¹™ì— ëŒ€í•œ ì„¸ì…˜ì˜ ë™ìž‘ì„ ì„¤ì •í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3696 -msgid "Sets the current transaction's synchronization level." -msgstr "현재 트랜잭션 격리 수준(isolation level)ì„ ì§€ì •í•¨." - -#: utils/misc/guc.c:3706 -msgid "Allows archiving of WAL files using archive_command." -msgstr "archive_command를 사용하여 WAL 파ì¼ì„ 따로 보관하ë„ë¡ ì„¤ì •í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3716 -msgid "Enables logging of recovery-related debugging information." -msgstr "복구 작업과 ê´€ë ¨ëœ ë””ë²„ê¹… 정보를 기ë¡í•˜ë„ë¡ í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3732 -msgid "Collects function-level statistics on database activity." -msgstr "ë°ì´í„°ë² ì´ìФ 활ë™ì— 대한 함수 수준 통계를 수집합니다." - -#: utils/misc/guc.c:3742 -msgid "Set the level of information written to the WAL." -msgstr "WALì— ì €ìž¥í•  ë‚´ìš© ìˆ˜ì¤€ì„ ì§€ì •í•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3752 -msgid "Selects the dynamic shared memory implementation used." -msgstr "사용할 ë™ì  공유 메모리 관리방ì‹ì„ ì„ íƒí•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3762 -msgid "Selects the method used for forcing WAL updates to disk." -msgstr "디스í¬ì— 대한 ê°•ì œ WAL ì—…ë°ì´íŠ¸ì— ì‚¬ìš©ë˜ëŠ” ë°©ë²•ì„ ì„ íƒí•©ë‹ˆë‹¤." - -#: utils/misc/guc.c:3772 -msgid "Sets how binary values are to be encoded in XML." -msgstr "XMLì—서 ë°”ì´ë„ˆë¦¬ ê°’ì´ ì¸ì½”딩ë˜ëŠ” ë°©ì‹ì„ 설정합니다." - -#: utils/misc/guc.c:3782 -msgid "" -"Sets whether XML data in implicit parsing and serialization operations is to " -"be considered as documents or content fragments." -msgstr "" -"ì•”ì‹œì  êµ¬ë¬¸ ë¶„ì„ ë° ì§ë ¬í™” ìž‘ì—…ì˜ XML ë°ì´í„°ë¥¼ 문서 ë˜ëŠ” ë‚´ìš© ì¡°ê°ìœ¼ë¡œ 간주할" -"ì§€ 여부를 설정합니다." - -#: utils/misc/guc.c:3793 -msgid "Use of huge pages on Linux." -msgstr "리눅스 huge 페ì´ì§€ 사용 여부" - -#: utils/misc/guc.c:3803 -msgid "Forces use of parallel query facilities." -msgstr "병렬 쿼리 ê¸°ëŠ¥ì„ í™œì„±í™”" - -#: utils/misc/guc.c:3804 -msgid "" -"If possible, run query using a parallel worker and with parallel " -"restrictions." -msgstr "" - -#: utils/misc/guc.c:4604 +#: utils/init/postinit.c:345 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ: %s\n" +msgid "permission denied for database \"%s\"" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 액세스 권한 ì—†ìŒ" -#: utils/misc/guc.c:4609 +#: utils/init/postinit.c:346 #, c-format -msgid "" -"Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" -msgstr "" -"initdb 명령ì´ë‚˜, pg_basebackup 명령으로 PostgreSQL ë°ì´í„° 디렉토리를 초기화 " -"하세요.\n" +msgid "User does not have CONNECT privilege." +msgstr "사용ìžì—게 CONNECT ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:4629 +#: utils/init/postinit.c:363 #, c-format -msgid "" -"%s does not know where to find the server configuration file.\n" -"You must specify the --config-file or -D invocation option or set the PGDATA " -"environment variable.\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФ 시스템 환경 설정 파ì¼ì„ 찾지 못했습니다.\n" -"ì§ì ‘ --config-file ë˜ëŠ” -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" -"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" -"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" +msgid "too many connections for database \"%s\"" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 최대 ì ‘ì†ìˆ˜ë¥¼ 초과했습니다" -#: utils/misc/guc.c:4648 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format -msgid "%s: could not access the server configuration file \"%s\": %s\n" -msgstr "%s: \"%s\" 환경 설정 파ì¼ì„ 접근할 수 없습니다: %s\n" +msgid "database locale is incompatible with operating system" +msgstr "ë°ì´í„°ë² ì´ìФ 로케ì¼ì´ ìš´ì˜ ì²´ì œì™€ 호환ë˜ì§€ 않ìŒ" -#: utils/misc/guc.c:4674 +#: utils/init/postinit.c:386 #, c-format -msgid "" -"%s does not know where to find the database system data.\n" -"This can be specified as \"data_directory\" in \"%s\", or by the -D " -"invocation option, or by the PGDATA environment variable.\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФ 시스템 ë°ì´í„° 디렉터리를 찾지 못했습니다.\n" -"\"%s\" 파ì¼ì—서 \"data_directory\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" -"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" -"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" -"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "ë°ì´í„°ë² ì´ìŠ¤ê°€ setlocale()ì—서 ì¸ì‹í•  수 없는 LC_COLLATE \"%s\"(으)로 초기화ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:4722 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format -msgid "" -"%s does not know where to find the \"hba\" configuration file.\n" -"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation " -"option, or by the PGDATA environment variable.\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ \"hba\" 환경설정파ì¼ì„ 찾지 못했습니다.\n" -"\"%s\" 파ì¼ì—서 \"hba_file\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" -"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" -"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" -"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" +msgid "Recreate the database with another locale or install the missing locale." +msgstr "다른 로케ì¼ë¡œ ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 다시 만들거나 누ë½ëœ 로케ì¼ì„ 설치하십시오." -#: utils/misc/guc.c:4745 +#: utils/init/postinit.c:393 #, c-format -msgid "" -"%s does not know where to find the \"ident\" configuration file.\n" -"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation " -"option, or by the PGDATA environment variable.\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ \"ident\" 환경설정파ì¼ì„ 찾지 못했습니다.\n" -"\"%s\" 파ì¼ì—서 \"ident_file\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" -"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" -"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" -"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "setlocale()ì—서 ì¸ì‹í•  수 없는 \"%s\" LC_CTYPE 값으로 ë°ì´í„°ë² ì´ìŠ¤ê°€ 초기화ë˜ì—ˆìŠµë‹ˆë‹¤." -#: utils/misc/guc.c:5419 utils/misc/guc.c:5466 -msgid "Value exceeds integer range." -msgstr "ê°’ì´ ì •ìˆ˜ 범위를 초과합니다." - -#: utils/misc/guc.c:5689 +#: utils/init/postinit.c:726 #, c-format -msgid "parameter \"%s\" requires a numeric value" -msgstr "\"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ì€ ìˆ«ìží˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." +msgid "no roles are defined in this database system" +msgstr "ì´ ë°ì´í„°ë² ì´ìФì—는 어떠한 롤 ì •ì˜ë„ 없습니다" -#: utils/misc/guc.c:5698 +#: utils/init/postinit.c:727 #, c-format -msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" -msgstr "" -"%g ê°’ì€ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ìœ¼ë¡œ 타당한 범위(%g .. %g)를 벗어났습니다." +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "ë‹¤ìŒ ëª…ë ¹ì„ ë¨¼ì € 실행하십시오: CREATE USER \"%s\" SUPERUSER;." -#: utils/misc/guc.c:5851 utils/misc/guc.c:7194 +#: utils/init/postinit.c:763 #, c-format -msgid "cannot set parameters during a parallel operation" -msgstr "병렬 작업 중ì—는 매개 변수를 설정할 수 ì—†ìŒ" +msgid "new replication connections are not allowed during database shutdown" +msgstr "ë°ì´í„°ë² ì´ìФ 중지 중ì—는 새로운 복제 ì—°ê²°ì„ í•  수 없습니다." -#: utils/misc/guc.c:5858 utils/misc/guc.c:6609 utils/misc/guc.c:6661 -#: utils/misc/guc.c:7022 utils/misc/guc.c:7782 utils/misc/guc.c:7950 -#: utils/misc/guc.c:9625 +#: utils/init/postinit.c:767 #, c-format -msgid "unrecognized configuration parameter \"%s\"" -msgstr "알 수 없는 환경 매개 변수 ì´ë¦„: \"%s\"" +msgid "must be superuser to connect during database shutdown" +msgstr "슈í¼ìœ ì €ë§Œ ë°ì´í„°ë² ì´ìФ 종료 ì¤‘ì— ì—°ê²°í•  수 있ìŒ" -#: utils/misc/guc.c:5873 utils/misc/guc.c:7034 +#: utils/init/postinit.c:777 #, c-format -msgid "parameter \"%s\" cannot be changed" -msgstr "\"%s\" 매개 변수는 ë³€ê²½ë  ìˆ˜ ì—†ìŒ" +msgid "must be superuser to connect in binary upgrade mode" +msgstr "슈í¼ìœ ì €ë§Œ ë°”ì´ë„ˆë¦¬ 업그레ì´ë“œ 모드 ì¤‘ì— ì—°ê²° í•  수 있ìŒ" -#: utils/misc/guc.c:5896 utils/misc/guc.c:6089 utils/misc/guc.c:6179 -#: utils/misc/guc.c:6269 utils/misc/guc.c:6377 utils/misc/guc.c:6472 -#: guc-file.l:351 +#: utils/init/postinit.c:791 #, c-format -msgid "parameter \"%s\" cannot be changed without restarting the server" -msgstr "\"%s\" 매개 변수는 서버 재실행 ì—†ì´ ì§€ê¸ˆ 변경 ë  ìˆ˜ ì—†ìŒ" +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "ë‚¨ì€ ì—°ê²° ìŠ¬ë¡¯ì€ non-replication 슈í¼ìœ ì € 연결용으로 남겨 놓았ìŒ" -#: utils/misc/guc.c:5906 +#: utils/init/postinit.c:801 #, c-format -msgid "parameter \"%s\" cannot be changed now" -msgstr "\"%s\" 매개 변수는 지금 변경 ë  ìˆ˜ ì—†ìŒ" +msgid "must be superuser or replication role to start walsender" +msgstr "superuser ë˜ëŠ” replication ê¶Œí•œì„ ê°€ì§„ 롤만 walsender 프로세스를 시작할 수 있ìŒ" -#: utils/misc/guc.c:5924 utils/misc/guc.c:5970 utils/misc/guc.c:9641 +#: utils/init/postinit.c:870 #, c-format -msgid "permission denied to set parameter \"%s\"" -msgstr "\"%s\" 매개 변수를 지정할 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤." +msgid "database %u does not exist" +msgstr "%u ë°ì´í„°ë² ì´ìŠ¤ê°€ ì—†ìŒ" -#: utils/misc/guc.c:5960 +#: utils/init/postinit.c:959 #, c-format -msgid "parameter \"%s\" cannot be set after connection start" -msgstr "\"%s\" 매개 ë³€ìˆ˜ê°’ì€ ì—°ê²° 시작한 ë’¤ì—는 변경할 수 없습니다" +msgid "It seems to have just been dropped or renamed." +msgstr "ì‚­ì œë˜ì—ˆê±°ë‚˜ ì´ë¦„ì´ ë°”ë€ ê²ƒ 같습니다." -#: utils/misc/guc.c:6008 +#: utils/init/postinit.c:977 #, c-format -msgid "cannot set parameter \"%s\" within security-definer function" -msgstr "보안 ì •ì˜ìž 함수 ë‚´ì—서 \"%s\" 매개 변수를 설정할 수 ì—†ìŒ" +msgid "The database subdirectory \"%s\" is missing." +msgstr "ë°ì´í„°ë² ì´ìФ ë””ë ‰í„°ë¦¬ì— \"%s\" 하위 디렉터리가 없습니다" -#: utils/misc/guc.c:6617 utils/misc/guc.c:6665 utils/misc/guc.c:7956 +#: utils/init/postinit.c:982 #, c-format -msgid "must be superuser to examine \"%s\"" -msgstr "\"%s\" 검사를 위해서는 superuser여야합니다" +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m" -#: utils/misc/guc.c:6731 +#: utils/mb/conv.c:488 utils/mb/conv.c:680 #, c-format -msgid "SET %s takes only one argument" -msgstr "SET %s ëª…ë ¹ì€ í•˜ë‚˜ì˜ ê°’ë§Œ 지정해야합니다" +msgid "invalid encoding number: %d" +msgstr "ìž˜ëª»ëœ ì¸ì½”딩 번호: %d" -#: utils/misc/guc.c:6982 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 #, c-format -msgid "must be superuser to execute ALTER SYSTEM command" -msgstr "슈í¼ìœ ì €ë§Œ ALTER SYSTEM ëª…ë ¹ì„ ì‹¤í–‰í•  수 있ìŒ" +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "%dì€(는) ISO 8859 ë¬¸ìž ì§‘í•©ì— ëŒ€í•œ 예기치 ì•Šì€ ì¸ì½”딩 IDìž„" -#: utils/misc/guc.c:7067 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 #, c-format -msgid "parameter value for ALTER SYSTEM must not contain a newline" -msgstr "" -"ALTER SYSTEM 명령으로 지정하는 매개 변수 ê°’ì—는 줄바꿈 문ìžê°€ 없어야 합니다" +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "%dì€(는) WIN ë¬¸ìž ì§‘í•©ì— ëŒ€í•œ 예기치 ì•Šì€ ì¸ì½”딩 IDìž„" -#: utils/misc/guc.c:7112 +#: utils/mb/encnames.c:473 #, c-format -msgid "could not parse contents of file \"%s\"" -msgstr "\"%s\" 파ì¼ì˜ ë‚´ìš©ì„ ë¶„ì„í•  수 ì—†ìŒ" +msgid "encoding \"%s\" not supported by ICU" +msgstr "\"%s\" ì¸ì½”ë”©ì€ ICU ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ" -#: utils/misc/guc.c:7270 +#: utils/mb/encnames.c:572 #, c-format -msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" -msgstr "SET LOCAL TRANSACTION SNAPSHOT ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" +msgid "encoding name too long" +msgstr "ì¸ì½”딩 ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤" -#: utils/misc/guc.c:7355 +#: utils/mb/mbutils.c:296 #, c-format -msgid "SET requires parameter name" -msgstr "SET ëª…ë ¹ì€ ë§¤ê°œ 변수 ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤" +msgid "conversion between %s and %s is not supported" +msgstr "%s ì¸ì½”딩과 %s ì¸ì½”딩 사ì´ì˜ ë³€í™˜ì€ ì§€ì›í•˜ì§€ 않습니다" -#: utils/misc/guc.c:7479 +#: utils/mb/mbutils.c:355 #, c-format -msgid "attempt to redefine parameter \"%s\"" -msgstr "\"%s\" 매개 변수를 다시 ì •ì˜í•˜ë ¤ê³  함" +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "\"%s\" ì¸ì½”ë”©ì„ \"%s\" ì¸ì½”딩으로 변환할 기본 변환규칙(conversion)ì´ ì—†ìŒ" -#: utils/misc/guc.c:9258 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format -msgid "parameter \"%s\" could not be set" -msgstr "\"%s\" 매개 변수는 설정할 수 ì—†ìŒ" +msgid "String of %d bytes is too long for encoding conversion." +msgstr "%dë°”ì´íŠ¸ì˜ ë¬¸ìžì—´ì€ 너무 길어서 ì¸ì½”딩 ê·œì¹™ì— ë§žì§€ 않습니다." -#: utils/misc/guc.c:9345 +#: utils/mb/mbutils.c:453 #, c-format -msgid "could not parse setting for parameter \"%s\"" -msgstr "지정한 \"%s\" 매개 ë³€ìˆ˜ê°’ì˜ êµ¬ë¬¸ë¶„ì„ì„ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤." +msgid "invalid source encoding name \"%s\"" +msgstr "\"%s\" ì›ë³¸ ì¸ì½”딩 ì´ë¦„ì´ íƒ€ë‹¹ì¹˜ 못함" -#: utils/misc/guc.c:9703 utils/misc/guc.c:9737 +#: utils/mb/mbutils.c:458 #, c-format -msgid "invalid value for parameter \"%s\": %d" -msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: %d" +msgid "invalid destination encoding name \"%s\"" +msgstr "\"%s\" ëŒ€ìƒ ì¸ì½”딩 ì´ë¦„ì´ íƒ€ë‹¹ì¹˜ 못함" -#: utils/misc/guc.c:9771 +#: utils/mb/mbutils.c:598 #, c-format -msgid "invalid value for parameter \"%s\": %g" -msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: %g" +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "\"%s\" ì¸ì½”딩ì—서 사용할 수 없는 ë°”ì´íЏ: 0x%02x" -#: utils/misc/guc.c:9961 +#: utils/mb/mbutils.c:940 #, c-format -msgid "" -"\"temp_buffers\" cannot be changed after any temporary tables have been " -"accessed in the session." -msgstr "" -"해당 세션ì—서 ì–´ë–¤ 임시 í…Œì´ë¸”ë„ ì‚¬ìš©í•˜ê³  있지 않아야 \"temp_buffers\" 설정" -"ì„ ë³€ê²½í•  수 있습니다." +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset 실패" -#: utils/misc/guc.c:9973 +#: utils/mb/wchar.c:2015 #, c-format -msgid "Bonjour is not supported by this build" -msgstr "Bonjour ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "\"%s\" ì¸ì½”딩ì—서 사용할 수 없는 문ìžê°€ 있ìŒ: %s" -#: utils/misc/guc.c:9986 +#: utils/mb/wchar.c:2048 #, c-format -msgid "SSL is not supported by this build" -msgstr "SSL ì ‘ì† ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "%s ë°”ì´íŠ¸ë¡œ ì¡°í•©ëœ ë¬¸ìž(ì¸ì½”딩: \"%s\")와 대ì‘ë˜ëŠ” ë¬¸ìž ì½”ë“œê°€ \"%s\" ì¸ì½”딩ì—는 없습니다" + +#: utils/misc/guc.c:571 +msgid "Ungrouped" +msgstr "소ì†ê·¸ë£¹ì—†ìŒ" + +#: utils/misc/guc.c:573 +msgid "File Locations" +msgstr "íŒŒì¼ ìœ„ì¹˜" + +#: utils/misc/guc.c:575 +msgid "Connections and Authentication" +msgstr "ì—°ê²°ê³¼ ì¸ì¦" + +#: utils/misc/guc.c:577 +msgid "Connections and Authentication / Connection Settings" +msgstr "ì—°ê²°ê³¼ ì¸ì¦ / ì—°ê²° 설정값" + +#: utils/misc/guc.c:579 +msgid "Connections and Authentication / Authentication" +msgstr "ì—°ê²°ê³¼ ì¸ì¦ / ì¸ì¦" + +#: utils/misc/guc.c:581 +msgid "Connections and Authentication / SSL" +msgstr "ì—°ê²°ê³¼ ì¸ì¦ / SSL" + +#: utils/misc/guc.c:583 +msgid "Resource Usage" +msgstr "ìžì› 사용량" + +#: utils/misc/guc.c:585 +msgid "Resource Usage / Memory" +msgstr "ìžì› 사용량 / 메모리" + +#: utils/misc/guc.c:587 +msgid "Resource Usage / Disk" +msgstr "ìžì› 사용량 / 디스í¬" + +#: utils/misc/guc.c:589 +msgid "Resource Usage / Kernel Resources" +msgstr "ìžì› 사용량 / ì»¤ë„ ìžì›" + +#: utils/misc/guc.c:591 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "ìžì› 사용량 / 비용기반 청소 지연" + +#: utils/misc/guc.c:593 +msgid "Resource Usage / Background Writer" +msgstr "ìžì› 사용량 / 백그ë¼ìš´ë“œ 쓰기" + +#: utils/misc/guc.c:595 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "ìžì› 사용량 / 비ë™ê¸° 기능" + +#: utils/misc/guc.c:597 +msgid "Write-Ahead Log" +msgstr "Write-Ahead 로그" + +#: utils/misc/guc.c:599 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead 로그 / 설정값" + +#: utils/misc/guc.c:601 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead 로그 / ì²´í¬í¬ì¸íЏ" + +#: utils/misc/guc.c:603 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead 로그 / ì•„ì¹´ì´ë¸Œ" + +#: utils/misc/guc.c:605 +msgid "Replication" +msgstr "복제" + +#: utils/misc/guc.c:607 +msgid "Replication / Sending Servers" +msgstr "복제 / 보내기 서버" + +#: utils/misc/guc.c:609 +msgid "Replication / Master Server" +msgstr "복제 / 주 서버" + +#: utils/misc/guc.c:611 +msgid "Replication / Standby Servers" +msgstr "복제 / 대기 서버" + +#: utils/misc/guc.c:613 +msgid "Replication / Subscribers" +msgstr "복제 / 구ë…" + +#: utils/misc/guc.c:615 +msgid "Query Tuning" +msgstr "쿼리 튜ë‹" + +#: utils/misc/guc.c:617 +msgid "Query Tuning / Planner Method Configuration" +msgstr "쿼리 íŠœë‹ / 실행계íšê¸° 메서드 설정" + +#: utils/misc/guc.c:619 +msgid "Query Tuning / Planner Cost Constants" +msgstr "쿼리 íŠœë‹ / 실행계íšê¸° 비용 ìƒìˆ˜" + +#: utils/misc/guc.c:621 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "쿼리 íŠœë‹ / ì¼ë°˜ì ì¸ 쿼리 최ì í™”기" + +#: utils/misc/guc.c:623 +msgid "Query Tuning / Other Planner Options" +msgstr "쿼리 íŠœë‹ / 기타 실행계íšê¸° 옵션들" + +#: utils/misc/guc.c:625 +msgid "Reporting and Logging" +msgstr "보고와 로그" + +#: utils/misc/guc.c:627 +msgid "Reporting and Logging / Where to Log" +msgstr "보고와 로그 / 로그 위치" + +#: utils/misc/guc.c:629 +msgid "Reporting and Logging / When to Log" +msgstr "보고와 로그 / 로그 시ì " + +#: utils/misc/guc.c:631 +msgid "Reporting and Logging / What to Log" +msgstr "보고와 로그 / 로그 ë‚´ìš©" + +#: utils/misc/guc.c:633 +msgid "Process Title" +msgstr "프로세스 제목" + +#: utils/misc/guc.c:635 +msgid "Statistics" +msgstr "통계" + +#: utils/misc/guc.c:637 +msgid "Statistics / Monitoring" +msgstr "통계 / 모니터ë§" + +#: utils/misc/guc.c:639 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "통계 / 쿼리 ë° ì¸ë±ìФ 사용 통계 수집기" + +#: utils/misc/guc.c:641 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:643 +msgid "Client Connection Defaults" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값" + +#: utils/misc/guc.c:645 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 구문 특성" + +#: utils/misc/guc.c:647 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 로케ì¼ê³¼ 출력양ì‹" + +#: utils/misc/guc.c:649 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ 미리 로딩" + +#: utils/misc/guc.c:651 +msgid "Client Connection Defaults / Other Defaults" +msgstr "í´ë¼ì´ì–¸íЏ ì—°ê²° 초기값 / 기타 초기값" + +#: utils/misc/guc.c:653 +msgid "Lock Management" +msgstr "잠금 관리" + +#: utils/misc/guc.c:655 +msgid "Version and Platform Compatibility" +msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„±" + +#: utils/misc/guc.c:657 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„± / ì´ì „ PostgreSQL 버전" + +#: utils/misc/guc.c:659 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "버전과 í”Œëž«í¼ í˜¸í™˜ì„± / 다른 플랫í¼ê³¼ í´ë¼ì´ì–¸íЏ" + +#: utils/misc/guc.c:661 +msgid "Error Handling" +msgstr "오류 처리" + +#: utils/misc/guc.c:663 +msgid "Preset Options" +msgstr "프리셋 옵션들" + +#: utils/misc/guc.c:665 +msgid "Customized Options" +msgstr "ì‚¬ìš©ìž ì •ì˜ ì˜µì…˜ë“¤" + +#: utils/misc/guc.c:667 +msgid "Developer Options" +msgstr "ê°œë°œìž ì˜µì…˜ë“¤" + +#: utils/misc/guc.c:721 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"B\", \"kB\", \"MB\",\"GB\", \"TB\" 입니다." + +#: utils/misc/guc.c:763 +msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "ì´ ë§¤ê°œ ë³€ìˆ˜ì— ìœ íš¨í•œ 단위는 \"ms\", \"s\", \"min\", \"h\", \"d\" 입니다." + +#: utils/misc/guc.c:822 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "실행계íšìžê°€ 순차ì -스캔(sequential-sca) 계íšì„ 사용함" + +#: utils/misc/guc.c:831 +msgid "Enables the planner's use of index-scan plans." +msgstr "실행계íšìžê°€ ì¸ë±ìФ-스캔 계íšì„ 사용함." + +#: utils/misc/guc.c:840 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "실행계íšìžê°€ ì¸ë±ìФ-ì „ìš©-íƒìƒ‰ 계íšì„ 사용함." + +#: utils/misc/guc.c:849 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "실행계íšê¸°ê°€ bitmap-scan 계íšì„ 사용하ë„ë¡ í•¨" + +#: utils/misc/guc.c:858 +msgid "Enables the planner's use of TID scan plans." +msgstr "실행계íšìžê°€ TID 스캔 계íšì„ 사용함" + +#: utils/misc/guc.c:867 +msgid "Enables the planner's use of explicit sort steps." +msgstr "실행계íšìžê°€ 명시 ì •ë ¬ 단계(explicit sort step)를 사용함" + +#: utils/misc/guc.c:876 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "실행계íšìžê°€ í•´ì‹œëœ ì§‘ê³„ 계íšì„ 사용함" + +#: utils/misc/guc.c:885 +msgid "Enables the planner's use of materialization." +msgstr "실행계íšìžê°€ materialization 계íšì„ 사용함" + +#: utils/misc/guc.c:894 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "실행계íšìžê°€ 근접순환 ì¡°ì¸(nested-loop join) 계íšì„ 사용함" + +#: utils/misc/guc.c:903 +msgid "Enables the planner's use of merge join plans." +msgstr "실행계íšìžê°€ 병합 ì¡°ì¸(merge join) 계íšì„ 사용함" + +#: utils/misc/guc.c:912 +msgid "Enables the planner's use of hash join plans." +msgstr "실행계íšìžê°€ 해시 ì¡°ì¸(hash join) 계íšì„ 사용함" + +#: utils/misc/guc.c:921 +msgid "Enables the planner's use of gather merge plans." +msgstr "실행계íšìžê°€ 병합 수집(gather merge) 계íšì„ 사용함" + +#: utils/misc/guc.c:930 +msgid "Enables partitionwise join." +msgstr "" + +#: utils/misc/guc.c:939 +msgid "Enables partitionwise aggregation and grouping." +msgstr "" + +#: utils/misc/guc.c:948 +msgid "Enables the planner's use of parallel append plans." +msgstr "실행계íšìžê°€ 병렬 추가 계íšì„ 사용함" + +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of parallel hash plans." +msgstr "실행계íšìžê°€ 병렬 해시 계íšì„ 사용함" + +#: utils/misc/guc.c:966 +msgid "Enable plan-time and run-time partition pruning." +msgstr "" + +#: utils/misc/guc.c:967 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "" + +#: utils/misc/guc.c:977 +msgid "Enables genetic query optimization." +msgstr "ìœ ì „ì  ì¿¼ë¦¬ 최ì í™”(GEQO)를 사용함" + +#: utils/misc/guc.c:978 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "ì´ ì•Œê³ ë¦¬ì¦˜ì€ ì‹¤í–‰ê³„íšê¸°ì˜ ê³¼ë„한 작업 ë¹„ìš©ì„ ë‚®ì¶¥ë‹ˆë‹¤" + +#: utils/misc/guc.c:988 +msgid "Shows whether the current user is a superuser." +msgstr "현재 사용ìžê°€ 슈í¼ìœ ì €ì¸ì§€ ë³´ì—¬ì¤ë‹ˆë‹¤." + +#: utils/misc/guc.c:998 +msgid "Enables advertising the server via Bonjour." +msgstr "Bonjour 서버 사용" + +#: utils/misc/guc.c:1007 +msgid "Collects transaction commit time." +msgstr "트랜잭션 커밋 ì‹œê°„ì„ ìˆ˜ì§‘í•¨" + +#: utils/misc/guc.c:1016 +msgid "Enables SSL connections." +msgstr "SSL ì—°ê²°ì„ ê°€ëŠ¥í•˜ê²Œ 함." + +#: utils/misc/guc.c:1025 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "" + +#: utils/misc/guc.c:1034 +msgid "Give priority to server ciphersuite order." +msgstr "SSL ì¸ì¦ 알고리즘 ìš°ì„  순위를 정함" + +#: utils/misc/guc.c:1043 +msgid "Forces synchronization of updates to disk." +msgstr "강제로 ë³€ê²½ëœ ë²„í¼ ìžë£Œë¥¼ 디스í¬ì™€ ë™ê¸°í™” 시킴." + +#: utils/misc/guc.c:1044 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "ì´ ì„œë²„ëŠ” fsync() 시스템 콜 ê¸°ëŠ¥ì„ ì—¬ëŸ¬ ê³³ì—서 사용할 것입니다. ì´ ê¸°ëŠ¥ì€ ë¬¼ë¦¬ì ìœ¼ë¡œ 디스í¬ì— ë³€ê²½ëœ ìžë£Œë¥¼ 즉ê°ì ìœ¼ë¡œ 기ë¡í•¨ì„ ì˜ë¯¸í•©ë‹ˆë‹¤. ì´ ê¸°ëŠ¥ì€ ì‹œìŠ¤í…œì˜ ë¹„ì •ìƒì ì¸ ë™ìž‘ì´ë‚˜, 하드웨어ì—서 오류가 ë°œìƒë˜ì—ˆì„ 경우ì—ë„ ìžë£Œë¥¼ 안전하게 지킬 수 있ë„ë¡ ë„와줄 것입니다." + +#: utils/misc/guc.c:1055 +msgid "Continues processing after a checksum failure." +msgstr "ì²´í¬ì„¬ 실패 후 처리 ê³„ì† í•¨" + +#: utils/misc/guc.c:1056 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "ì¼ë°˜ì ìœ¼ë¡œ ì†ìƒëœ 페ì´ì§€ í—¤ë”를 발견하게 ë˜ë©´, PostgreSQLì—서는 오류를 ë°œìƒí•˜ê³ , 현재 íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•©ë‹ˆë‹¤. ignore_checksum_failure ê°’ì„ true로 지정하면, ì´ëŸ° ì†ìƒëœ 페ì´ì§€ë¥¼ 발견하면, 경고 메시지를 보여주고, ê³„ì† ì§„í–‰í•©ë‹ˆë‹¤. ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•œë‹¤ í•¨ì€ ì„œë²„ ë¹„ì •ìƒ ì¢…ë£Œë‚˜ 기타 심ê°í•œ 문제가 ì¼ì–´ ë‚  수 있습니다. ì´ ì„¤ì •ì€ ë°ì´í„° í´ëŸ¬ìŠ¤í„°ì—서 ì²´í¬ì„¬ ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì–´ 있는 경우ì—ë§Œ ì˜í–¥ì„ 받습니다." + +#: utils/misc/guc.c:1070 +msgid "Continues processing past damaged page headers." +msgstr "ì†ìƒëœ ìžë£Œ í—¤ë” ë°œê²¬ì‹œ 작업 ì§„í–‰ 여부 ì„ íƒ" + +#: utils/misc/guc.c:1071 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "ì¼ë°˜ì ìœ¼ë¡œ ì†ìƒëœ 페ì´ì§€ í—¤ë”를 발견하게 ë˜ë©´, PostgreSQLì—서는 오류를 ë°œìƒí•˜ê³ , 현재 íŠ¸ëžœìž­ì…˜ì„ ì¤‘ì§€í•©ë‹ˆë‹¤. ì´ ê°’ì„ true로 지정하면, ì´ëŸ° ì†ìƒëœ 페ì´ì§€ë¥¼ 발견하면, 경고 메시지를 보여주고, ê·¸ 페ì´ì§€ì˜ í¬ê¸°ë¥¼ 0으로 만들고 ìž‘ì—…ì„ ê³„ì† ì§„í–‰í•©ë‹ˆë‹¤. ì´ ê¸°ëŠ¥ì„ ì‚¬ìš©í•œë‹¤ í•¨ì€ ì†ìƒëœ ìžë£Œë¥¼ 없애겠다는 ê²ƒì„ ì˜ë¯¸í•©ë‹ˆë‹¤. ì´ê²ƒì€ ê³§ 저장ë˜ì–´ìžˆëŠ” ìžë£Œê°€ ì‚­ì œ ë  ìˆ˜ë„ ìžˆìŒì„ ì˜ë¯¸í•˜ê¸°ë„ 합니다." + +#: utils/misc/guc.c:1084 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "ì²´í¬í¬ì¸íЏ 후 ì²˜ìŒ ìˆ˜ì •í•  때 ì „ì²´ 페ì´ì§€ë¥¼ WALì— ì”니다." + +#: utils/misc/guc.c:1085 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "ìš´ì˜ ì²´ì œê°€ ë¹„ì •ìƒ ì¢…ë£Œë˜ëŠ” 경우 처리 ì¤‘ì¸ íŽ˜ì´ì§€ 쓰기는 디스í¬ì— ì¼ë¶€ë§Œ 기ë¡ë  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. 복구 중 WALì— ì €ìž¥ëœ ë¡œìš° 변경 ë‚´ìš©ì´ ë¶€ì¡±í•˜ì—¬ 복구할 수 ì—†ì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤. ì´ ì˜µì…˜ì€ ì•ˆì „í•˜ê²Œ 복구가 가능하ë„ë¡ ì²´í¬í¬ì¸íЏ 후 ì²˜ìŒ ìˆ˜ì •í•œ 페ì´ì§€ëŠ” ê·¸ 페ì´ì§€ 전체를 WALì— ì”니다." + +#: utils/misc/guc.c:1098 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "ì²´í¬í¬ì¸íЏ 작업 후 ìžë£Œ 페ì´ì§€ì— 첫 ë³€ê²½ì´ ìžˆëŠ” 경우, WALì— ë³€ê²½ëœ ë‚´ìš©ë§Œ 기ë¡í•˜ëŠ” ê²ƒì´ ì•„ë‹ˆë¼, 해당 페ì´ì§€ 전체를 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1108 +msgid "Compresses full-page writes written in WAL file." +msgstr "WAL 파ì¼ì— 기ë¡ë˜ëŠ” ì „ì²´ 페ì´ì§€ë¥¼ 압축함" + +#: utils/misc/guc.c:1118 +msgid "Logs each checkpoint." +msgstr "ì²´í¬í¬ì¸íЏ 관련 정보를 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1127 +msgid "Logs each successful connection." +msgstr "ì—°ê²° 성공한 정보들 모ë‘를 기ë¡í•¨" + +#: utils/misc/guc.c:1136 +msgid "Logs end of a session, including duration." +msgstr "ê¸°ê°„ì„ í¬í•¨í•˜ì—¬ ì„¸ì…˜ì˜ ëì„ ê¸°ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1145 +msgid "Logs each replication command." +msgstr "복제 관련 작업 ë‚´ì—­ì„ ê¸°ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1154 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "서버가 assertion 검사 ê¸°ëŠ¥ì´ í™œì„±í™” ë˜ì–´ 실행ë˜ëŠ”ì§€ ë³´ì—¬ 줌" + +#: utils/misc/guc.c:1169 +msgid "Terminate session on any error." +msgstr "ì–´ë–¤ 오류가 ìƒê¸°ë©´ ì„¸ì…˜ì„ ì¢…ë£Œí•¨" + +#: utils/misc/guc.c:1178 +msgid "Reinitialize server after backend crash." +msgstr "백엔드가 ë¹„ì •ìƒ ì¢…ë£Œë˜ë©´ 서버를 재초기화함" + +#: utils/misc/guc.c:1188 +msgid "Logs the duration of each completed SQL statement." +msgstr "SQL 명령 êµ¬ë¬¸ì˜ ì‹¤í–‰ì™„ë£Œ ì‹œê°„ì„ ê¸°ë¡í•¨" + +#: utils/misc/guc.c:1197 +msgid "Logs each query's parse tree." +msgstr "ê° ì¿¼ë¦¬ì˜ êµ¬ë¬¸ ë¶„ì„ íŠ¸ë¦¬ë¥¼ 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1206 +msgid "Logs each query's rewritten parse tree." +msgstr "ê° ì¿¼ë¦¬ì˜ ìž¬ìž‘ì„±ëœ êµ¬ë¬¸ ë¶„ì„ íŠ¸ë¦¬ë¥¼ 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1215 +msgid "Logs each query's execution plan." +msgstr "ê° ì¿¼ë¦¬ì˜ ì‹¤í–‰ 계íšì„ 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1224 +msgid "Indents parse and plan tree displays." +msgstr "구문과 실행계íšì„ ë³´ì—¬ 줄때, 들여쓰기를 함." + +#: utils/misc/guc.c:1233 +msgid "Writes parser performance statistics to the server log." +msgstr "êµ¬ë¬¸ë¶„ì„ ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." + +#: utils/misc/guc.c:1242 +msgid "Writes planner performance statistics to the server log." +msgstr "실행계íšìž 성능 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." + +#: utils/misc/guc.c:1251 +msgid "Writes executor performance statistics to the server log." +msgstr "ì‹¤í–‰ìž ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." + +#: utils/misc/guc.c:1260 +msgid "Writes cumulative performance statistics to the server log." +msgstr "ëˆ„ì  ì„±ëŠ¥ 통계를 서버 ë¡œê·¸ì— ê¸°ë¡í•¨." + +#: utils/misc/guc.c:1270 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "다양한 B트리 ìž‘ì—…ì— ìžì›(메모리, CPU) 사용 통계를 기ë¡ì— 남기" + +#: utils/misc/guc.c:1282 +msgid "Collects information about executing commands." +msgstr "명령 ì‹¤í–‰ì— ëŒ€í•œ 정보를 수집함" + +#: utils/misc/guc.c:1283 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "ê° ì„¸ì…˜ì—서 사용하고 있는 현재 실행 ì¤‘ì¸ ëª…ë ¹ì˜ ìˆ˜í–‰ 시간, 명령 ë‚´ìš©ë“±ì— ëŒ€í•œ 정보를 수집하ë„ë¡ í•¨" + +#: utils/misc/guc.c:1293 +msgid "Collects statistics on database activity." +msgstr "ë°ì´í„°ë² ì´ìФ 활ë™ì— 대한 통계를 수집합니다." + +#: utils/misc/guc.c:1302 +msgid "Collects timing statistics for database I/O activity." +msgstr "ë°ì´í„°ë² ì´ìФ I/O 활ë™ì— 대한 통계를 수집합니다." + +#: utils/misc/guc.c:1312 +msgid "Updates the process title to show the active SQL command." +msgstr "활성 SQL ëª…ë ¹ì„ í‘œì‹œí•˜ë„ë¡ í”„ë¡œì„¸ìŠ¤ ì œëª©ì„ ì—…ë°ì´íŠ¸í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1313 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "서버가 새 SQL ëª…ë ¹ì„ ë°›ì„ ë•Œë§ˆë‹¤ 프로세스 ì œëª©ì´ ì—…ë°ì´íŠ¸ë  ìˆ˜ 있ë„ë¡ í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1326 +msgid "Starts the autovacuum subprocess." +msgstr "ìžë™ 청소 하위 프로세스를 실행함" + +#: utils/misc/guc.c:1336 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "LISTEN, NOTIFY 명령 ì‚¬ìš©ì„ ìœ„í•œ 디버깅 ì¶œë ¥ì„ ë§Œë“¦." + +#: utils/misc/guc.c:1348 +msgid "Emits information about lock usage." +msgstr "잠금 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1358 +msgid "Emits information about user lock usage." +msgstr "ì‚¬ìš©ìž ìž ê¸ˆ 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1368 +msgid "Emits information about lightweight lock usage." +msgstr "가벼운 잠금 사용 정보를 로그로 남김" + +#: utils/misc/guc.c:1378 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "êµì°© 잠금 시간 제한 ìƒí™©ì´ ë°œìƒí•˜ë©´ ê·¸ ë•Œì˜ ëª¨ë“  잠금 정보를 보여줌" + +#: utils/misc/guc.c:1390 +msgid "Logs long lock waits." +msgstr "긴 잠금 대기를 기ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1400 +msgid "Logs the host name in the connection logs." +msgstr "ì—°ê²° 기ë¡ì—서 호스트 ì´ë¦„ì„ ê¸°ë¡í•¨." + +#: utils/misc/guc.c:1401 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "ì´ ê¸°ëŠ¥ì€ ê¸°ë³¸ì ìœ¼ë¡œ 연결기ë¡ì—서 기본ì ìœ¼ë¡œ IP 주소만 기ë¡í•©ë‹ˆë‹¤. ì´ ê°’ì„ true로 바꾼다면, ì´ IPì˜ í˜¸ìŠ¤íŠ¸ ì´ë¦„ì„ êµ¬í•´ì„œ ì´ ì´ë¦„ì„ ì‚¬ìš©í•©ë‹ˆë‹¤ ì´ê²ƒì˜ ì„±ëŠ¥ì€ OSì˜ IPì—서 ì´ë¦„구하기 성능과 관계ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1412 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "\"표현=NULL\" ì‹ì„ \"표현 IS NULL\"로 취급함." + +#: utils/misc/guc.c:1413 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "표현 = NULL ì˜ ë°”ë¥¸ 처리는 í•­ìƒ null ê°’ì„ ë¦¬í„´í•´ì•¼í•˜ì§€ë§Œ, 편ì˜ì„±ì„ 위해서 expr = NULL êµ¬ë¬¸ì„ expr IS NULL 구문으로 바꾸어서 처리하ë„ë¡ í•¨ì´ë ‡ê²Œí•˜ë©´, 윗 êµ¬ë¬¸ì€ true 를 리턴함" + +#: utils/misc/guc.c:1425 +msgid "Enables per-database user names." +msgstr "per-database ì‚¬ìš©ìž ì´ë¦„ 활성화." + +#: utils/misc/guc.c:1434 +msgid "Sets the default read-only status of new transactions." +msgstr "새로운 íŠ¸ëžœìž­ì…˜ì˜ ìƒíƒœë¥¼ 초기값으로 ì½ê¸°ì „용으로 설정합니다." + +#: utils/misc/guc.c:1443 +msgid "Sets the current transaction's read-only status." +msgstr "현재 íŠ¸ëžœìž­ì…•ì˜ ì½ê¸° ì „ìš© ìƒíƒœë¥¼ 지정합니다." + +#: utils/misc/guc.c:1453 +msgid "Sets the default deferrable status of new transactions." +msgstr "새 íŠ¸ëžœìž­ì…˜ì˜ ê¸°ë³¸ 지연 가능한 ìƒíƒœë¥¼ 지정" + +#: utils/misc/guc.c:1462 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "ì½ê¸° ì „ìš© ì§ë ¬í™” 가능한 íŠ¸ëžœìž­ì…˜ì´ ì§ë ¬ 처리ì—서 오류가 ì—†ì„ ë•Œê¹Œì§€ ê·¸ íŠ¸ëžœìž­ì…˜ì„ ì§€ì—°í•  것ì´ì§€ 결정함" + +#: utils/misc/guc.c:1472 +msgid "Enable row security." +msgstr "로우 단위 보안 ê¸°ëŠ¥ì„ í™œì„±í™”" + +#: utils/misc/guc.c:1473 +msgid "When enabled, row security will be applied to all users." +msgstr "ì´ ê°’ì´ í™œì„±í™” ë˜ë©´ 로우 단위 보안 ê¸°ëŠ¥ì´ ëª¨ë“  ì‚¬ìš©ìž ëŒ€ìƒìœ¼ë¡œ ì ìš©ë¨" + +#: utils/misc/guc.c:1481 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "CREATE FUNCTION 명령으로 함수를 만들 때, 함수 본문 ë¶€ë¶„ì˜ êµ¬ë¬¸ì„ ê²€ì‚¬í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1490 +msgid "Enable input of NULL elements in arrays." +msgstr "ë°°ì—´ì— NULL 요소가 ìž…ë ¥ë  ìˆ˜ 있ë„ë¡ í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1491 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "ì´ ê°’ì´ onì´ë©´ ë°°ì—´ ìž…ë ¥ ê°’ì— ë”°ì˜´í‘œ ì—†ì´ ìž…ë ¥ëœ NULLì´ null ê°’ì„ ì˜ë¯¸í•˜ê³ , 그렇지 않으면 ë¬¸ìž ê·¸ëŒ€ë¡œ 처리ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1501 +msgid "Create new tables with OIDs by default." +msgstr "기본ì ìœ¼ë¡œ OID를 사용하여 새 í…Œì´ë¸”ì„ ë§Œë“­ë‹ˆë‹¤." + +#: utils/misc/guc.c:1510 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "로그 ê¸°ë¡ í•˜ìœ„ 프로세스를 시작하여 stderr 출력 ë°/ë˜ëŠ” csvlog를 로그 파ì¼ì— ì”니다." + +#: utils/misc/guc.c:1519 +msgid "Truncate existing log files of same name during log rotation." +msgstr "로그 회전 중 ë™ì¼í•œ ì´ë¦„ì˜ ê¸°ì¡´ 로그 파ì¼ì„ ìžë¦…니다." + +#: utils/misc/guc.c:1530 +msgid "Emit information about resource usage in sorting." +msgstr "ì •ë ¬ 시 리소스 사용 정보를 내보냅니다." + +#: utils/misc/guc.c:1544 +msgid "Generate debugging output for synchronized scanning." +msgstr "ë™ê¸°í™”ëœ ìŠ¤ìº”ì„ ìœ„í•´ 디버깅 ì¶œë ¥ì„ ìƒì„±í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1559 +msgid "Enable bounded sorting using heap sort." +msgstr "íž™ ì •ë ¬ì„ í†µí•´ ì œí•œì  ì •ë ¬ì„ ì‚¬ìš©í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1572 +msgid "Emit WAL-related debugging output." +msgstr "WAL 관련 디버깅 ì¶œë ¥ì„ ë‚´ë³´ëƒ…ë‹ˆë‹¤." + +#: utils/misc/guc.c:1584 +msgid "Datetimes are integer based." +msgstr "datetime í˜•ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ 사용함" + +#: utils/misc/guc.c:1595 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Kerberos ë° GSSAPI ì‚¬ìš©ìž ì´ë¦„ì—서 대/소문ìžë¥¼ 구분하지 않ì„ì§€ 여부를 설정합니다." + +#: utils/misc/guc.c:1605 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "ì¼ë°˜ 문ìžì—´ ë¦¬í„°ëŸ´ì˜ ë°±ìŠ¬ëž˜ì‹œ ì´ìŠ¤ì¼€ì´í”„ì— ëŒ€í•´ 경고합니다." + +#: utils/misc/guc.c:1615 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "'...' 문ìžì—´ì—서 백슬래시가 리터럴로 처리ë˜ë„ë¡ í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1626 +msgid "Enable synchronized sequential scans." +msgstr "ë™ê¸°í™”ëœ ìˆœì°¨ì  ìŠ¤ìº”ì„ ì‚¬ìš©í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1636 +msgid "Allows connections and queries during recovery." +msgstr "복구 중ì—ì„œë„ ì ‘ì†ê³¼ 쿼리 ì‚¬ìš©ì„ í—ˆìš©í•¨" + +#: utils/misc/guc.c:1646 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "ì½ê¸° ì „ìš© ë³´ì¡° 서버가 보내는 쿼리 ì¶©ëŒì„ 피하기 위한 í”¼ë“œë°±ì„ ì£¼ 서버가 ë°›ìŒ" + +#: utils/misc/guc.c:1656 +msgid "Allows modifications of the structure of system tables." +msgstr "시스템 í…Œì´ë¸”ì˜ êµ¬ì¡°ë¥¼ 수정할 수 있ë„ë¡ í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1667 +msgid "Disables reading from system indexes." +msgstr "시스템 ì¸ë±ìФ ì½ê¸°ë¥¼ 금지함" + +#: utils/misc/guc.c:1668 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "ì´ ì„¤ì •ì´ í™œì„±í™” ë˜ì–´ë„ ê·¸ ì¸ë±ìŠ¤ëŠ” 갱신ë˜ì–´ 사용하는ë°ëŠ” 안전합니다. 하지만 서버가 ì „ì²´ì ìœ¼ë¡œ 늦어질 수 있습니다." + +#: utils/misc/guc.c:1679 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "대형 ê°œì²´ì— ëŒ€í•œ ì ‘ê·¼ 권한 검사를 위한 하위 í˜¸í™˜ì„±ì´ ìžˆê²Œ 함" + +#: utils/misc/guc.c:1680 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "PostgreSQL 9.0 ì´ì „ ë²„ì „ì˜ í˜¸í™˜ì„±ì„ ìœ„í•´ 대형 ê°œì²´ì— ëŒ€í•œ ì½ê¸°, 변경 시 ì ‘ê·¼ 권한 검사를 안 하ë„ë¡ ì„¤ì •í•¨" + +#: utils/misc/guc.c:1690 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "PostgreSQL 9.4 버전까지 사용ë˜ì—ˆë˜ ìš°ì„  순위가 ì ìš©ë˜ë©´ 경고를 보여줌" + +#: utils/misc/guc.c:1700 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "SQL êµ¬ë¬¸ì„ ë§Œë“¤ 때, 모든 ì‹ë³„ìžëŠ” 따옴표를 사용함" + +#: utils/misc/guc.c:1710 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "" + +#: utils/misc/guc.c:1721 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "syslog 사용시 메시지 ì¤‘ë³µì„ ë°©ì§€í•˜ê¸° 위해 ì¼ë ¨ 번호를 매ê¹ë‹ˆë‹¤." + +#: utils/misc/guc.c:1731 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "syslog 사용시 메시지를 한 ì¤„ì— 1024 ë°”ì´íŠ¸ë§Œ ì“°ë„ë¡ ë‚˜ëˆ•ë‹ˆë‹¤" + +#: utils/misc/guc.c:1741 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" + +#: utils/misc/guc.c:1742 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" + +#: utils/misc/guc.c:1751 +msgid "Allow JIT compilation." +msgstr "" + +#: utils/misc/guc.c:1761 +msgid "Register JIT compiled function with debugger." +msgstr "" + +#: utils/misc/guc.c:1778 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "" + +#: utils/misc/guc.c:1789 +msgid "Allow JIT compilation of expressions." +msgstr "" + +#: utils/misc/guc.c:1800 +msgid "Register JIT compiled function with perf profiler." +msgstr "" + +#: utils/misc/guc.c:1817 +msgid "Allow JIT compilation of tuple deforming." +msgstr "" + +#: utils/misc/guc.c:1837 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "새 파ì¼ì´ Nì´ˆ ë‚´ì— ì‹œìž‘ë˜ì§€ ì•Šì€ ê²½ìš° 강제로 ë‹¤ìŒ WAL 파ì¼ë¡œ 전환합니다." + +#: utils/misc/guc.c:1848 +msgid "Waits N seconds on connection startup after authentication." +msgstr "ì—°ê²° 작업ì—서 ì¸ì¦ì´ ë난 ë’¤ Nì´ˆ 기다림" + +#: utils/misc/guc.c:1849 utils/misc/guc.c:2400 +msgid "This allows attaching a debugger to the process." +msgstr "ì´ë ‡ê²Œ 하면 디버거를 í”„ë¡œì„¸ìŠ¤ì— ì—°ê²°í•  수 있습니다." + +#: utils/misc/guc.c:1858 +msgid "Sets the default statistics target." +msgstr "기본 통계 대ìƒì„ 지정합니다." + +#: utils/misc/guc.c:1859 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "특정 ì¹¼ëŸ¼ì„ ì§€ì •í•˜ì§€ 않고 ALTER TABLE SET STATISTICS ëª…ë ¹ì„ ì‚¬ìš©í–ˆì„ ë•Œ, 통계 대ìƒì´ ë  ì¹¼ëŸ¼ì„ ì§€ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1868 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "ì´ í¬ê¸°ë¥¼ 초과할 경우 하위 쿼리가 축소ë˜ì§€ 않는 FROM ëª©ë¡ í¬ê¸°ë¥¼ 설정합니다." + +#: utils/misc/guc.c:1870 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "ê²°ê³¼ FROM 목ë¡ì— í¬í•¨ëœ í•­ëª©ì´ ì´ ê°œìˆ˜ë¥¼ 넘지 않는 경우 ê³„íš ê´€ë¦¬ìžê°€ 하위 쿼리를 ìƒìœ„ ì¿¼ë¦¬ì— ë³‘í•©í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1880 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "ì´ í¬ê¸°ë¥¼ 초과할 경우 JOIN êµ¬ë¬¸ì´ ê²°í•©ë˜ì§€ 않는 FROM ëª©ë¡ í¬ê¸°ë¥¼ 설정합니다." + +#: utils/misc/guc.c:1882 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "ê²°ê³¼ 목ë¡ì— í¬í•¨ëœ í•­ëª©ì´ ì´ ê°œìˆ˜ë¥¼ 넘지 ì•Šì„ ë•Œë§ˆë‹¤ ê³„íš ê´€ë¦¬ìžê°€ ëª…ì‹œì  JOIN êµ¬ë¬¸ì„ FROM 항목 목ë¡ì— 결합합니다." + +#: utils/misc/guc.c:1892 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "ì´ ìž„ê³„ê°’ì„ ì´ˆê³¼í•  경우 GEQOê°€ 사용ë˜ëŠ” FROM í•­ëª©ì˜ ìž„ê³„ê°’ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1901 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: 다른 GEQO 매개 ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì„ ì„¤ì •í•˜ëŠ” ë° ì‚¬ìš©ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1910 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: ëª¨ì§‘ë‹¨ì˜ ê°œì¸ ìˆ˜ìž…ë‹ˆë‹¤." + +#: utils/misc/guc.c:1911 utils/misc/guc.c:1920 +msgid "Zero selects a suitable default value." +msgstr "0ì„ ì§€ì •í•˜ë©´ ì ì ˆí•œ 기본 ê°’ì´ ì„ íƒë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1919 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: ì•Œê³ ë¦¬ì¦˜ì˜ ë°˜ë³µ 수입니다." + +#: utils/misc/guc.c:1930 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "êµì°© ìƒíƒœë¥¼ 확ì¸í•˜ê¸° ì „ì— ìž ê¸ˆì„ ê¸°ë‹¤ë¦´ ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1941 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "ì½ê¸° ì „ìš© ë³´ì¡° 서버가 ì•„ì¹´ì´ë¸Œëœ WAL ìžë£Œë¥¼ 처리할 때, ì§€ì—°ë  ìˆ˜ 있는 최대 시간" + +#: utils/misc/guc.c:1952 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "ì½ê¸° ì „ìš© ë³´ì¡° 서버가 스트림 WAL ìžë£Œë¥¼ 처리할 때, ì§€ì—°ë  ìˆ˜ 있는 최대 시간" + +#: utils/misc/guc.c:1963 +msgid "Sets the maximum interval between WAL receiver status reports to the primary." +msgstr "주 서버로 WAL 수신기 ìƒíƒœë¥¼ 보고하는 최대 간격" + +#: utils/misc/guc.c:1974 +msgid "Sets the maximum wait time to receive data from the primary." +msgstr "주 서버ì—서 보낸 ìžë£Œë¥¼ 받기위해 기다릴 수 있는 최대 허용 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:1985 +msgid "Sets the maximum number of concurrent connections." +msgstr "최대 ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 지정합니다." + +#: utils/misc/guc.c:1996 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "superuser ë™ì‹œ ì ‘ì†ìˆ˜ë¥¼ 지정합니다." + +#: utils/misc/guc.c:2010 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "서버ì—서 사용할 공유 ë©”ëª¨ë¦¬ì˜ ê°œìˆ˜ë¥¼ 지정함" + +#: utils/misc/guc.c:2021 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "ê° ì„¸ì…˜ì—서 사용하는 임시 버í¼ì˜ 최대 개수를 지정" + +#: utils/misc/guc.c:2032 +msgid "Sets the TCP port the server listens on." +msgstr "TCP í¬íЏ 번호를 지정함." + +#: utils/misc/guc.c:2042 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ 파ì¼ì˜ 액세스 ê¶Œí•œì„ ì§€ì •í•¨" + +#: utils/misc/guc.c:2043 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix ë„ë©”ì¸ ì†Œì¼“ì€ ì¼ë°˜ì ì¸ Unix íŒŒì¼ ì‹œìŠ¤í…œ 권한 ì§‘í•©ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 매개 변수 ê°’ì€ chmod ë° umask 시스템 호출ì—서 수ë½ë˜ëŠ” í˜•íƒœì˜ ìˆ«ìž ëª¨ë“œ 지정ì´ì–´ì•¼ 합니다. (ì¼ë°˜ì ì¸ 8진수 형ì‹ì„ 사용하려면 숫ìžê°€ 0으로 시작해야 합니다.)" + +#: utils/misc/guc.c:2057 +msgid "Sets the file permissions for log files." +msgstr "로그 파ì¼ì˜ íŒŒì¼ ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2058 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "매개 변수 ê°’ì€ chmod ë° umask 시스템 호출ì—서 수ë½ë˜ëŠ” í˜•íƒœì˜ ìˆ«ìž ëª¨ë“œ 지정ì´ì–´ì•¼ 합니다. (ì¼ë°˜ì ì¸ 8진수 형ì‹ì„ 사용하려면 숫ìžê°€ 0으로 시작해야 합니다.)" + +#: utils/misc/guc.c:2072 +msgid "Mode of the data directory." +msgstr "ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ëª¨ë“œ" + +#: utils/misc/guc.c:2073 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "매개 변수 ê°’ì€ chmod ë° umask 시스템 호출ì—서 수ë½ë˜ëŠ” í˜•íƒœì˜ ìˆ«ìž ëª¨ë“œ 지정ì´ì–´ì•¼ 합니다. (ì¼ë°˜ì ì¸ 8진수 형ì‹ì„ 사용하려면 숫ìžê°€ 0으로 시작해야 합니다.)" + +#: utils/misc/guc.c:2086 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "쿼리 ìž‘ì—…ê³µê°„ì„ ìœ„í•´ ì‚¬ìš©ë  ë©”ëª¨ë¦¬ì˜ ìµœëŒ€ê°’ì„ ì§€ì •í•¨." + +#: utils/misc/guc.c:2087 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "임시 ë””ìŠ¤í¬ íŒŒì¼ë¡œ 전환하기 ì „ì— ê° ë‚´ë¶€ ì •ë ¬ 작업과 해시 í…Œì´ë¸”ì—서 ì´ í¬ê¸°ì˜ 메모리를 사용할 수 있습니다." + +#: utils/misc/guc.c:2099 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "관리 ìž‘ì—…ì„ ìœ„í•´ ì‚¬ìš©ë  ë©”ëª¨ë¦¬ì˜ ìµœëŒ€ê°’ì„ ì§€ì •í•¨." + +#: utils/misc/guc.c:2100 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "ê´€ë¦¬ìž‘ì—…ì€ VACUUM, CREATE INDEX ê°™ì€ ìž‘ì—…ì„ ëœ»í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2115 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "스íƒê¹Šì´(KB 단위) ìµœëŒ€ê°’ì„ ì§€ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2126 +msgid "Limits the total size of all temporary files used by each process." +msgstr "ê° í”„ë¡œì„¸ìŠ¤ì—서 사용하는 모든 임시 파ì¼ì˜ ì´ í¬ê¸° 제한" + +#: utils/misc/guc.c:2127 +msgid "-1 means no limit." +msgstr "-1ì€ ì œí•œ ì—†ìŒ" + +#: utils/misc/guc.c:2137 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "ë²„í¼ ìºì‹œì— 있는 페ì´ì§€ì˜ 청소 비용입니다." + +#: utils/misc/guc.c:2147 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "ë²„í¼ ìºì‹œì— 없는 페ì´ì§€ì˜ 청소 비용입니다." + +#: utils/misc/guc.c:2157 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "청소로 페ì´ì§€ 변경 시 부과ë˜ëŠ” 비용입니다." + +#: utils/misc/guc.c:2167 +msgid "Vacuum cost amount available before napping." +msgstr "청소가 중지ë˜ëŠ” 청소 비용 합계입니다." + +#: utils/misc/guc.c:2177 +msgid "Vacuum cost delay in milliseconds." +msgstr "청소 비용 지연(밀리초)입니다." + +#: utils/misc/guc.c:2188 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "ìžë™ ì²­ì†Œì— ëŒ€í•œ 청소 비용 지연(밀리초)입니다." + +#: utils/misc/guc.c:2199 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "ìžë™ ì²­ì†Œì— ëŒ€í•œ 청소가 중지ë˜ëŠ” 청소 비용 합계입니다." + +#: utils/misc/guc.c:2209 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "ê°ê°ì˜ 서버 프로세스ì—서 ë™ì‹œì— 열릴 수 있는 최대 íŒŒì¼ ê°¯ìˆ˜ë¥¼ 지정함." + +#: utils/misc/guc.c:2222 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "ë™ì‹œì— ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ 최대 개수 지정" + +#: utils/misc/guc.c:2233 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "잠금 ì¶”ì ì„ 위한 í…Œì´ë¸”ì˜ ìµœì†Œ OID 지정" + +#: utils/misc/guc.c:2234 +msgid "Is used to avoid output on system tables." +msgstr "" + +#: utils/misc/guc.c:2243 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "" + +#: utils/misc/guc.c:2255 +msgid "Sets the maximum allowed duration of any statement." +msgstr "모든 ì¿¼ë¦¬ë¬¸ì— ì ìš©ë˜ëŠ” 허용ë˜ëŠ” 최대 수행시간" + +#: utils/misc/guc.c:2256 utils/misc/guc.c:2267 utils/misc/guc.c:2278 +msgid "A value of 0 turns off the timeout." +msgstr "ì´ ê°’ì´ 0ì´ë©´ ì´ëŸ° ì œí•œì´ ì—†ìŒ." + +#: utils/misc/guc.c:2266 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "모든 ìž ê¸ˆì— ì ìš©ë˜ëŠ” 기다리는 최대 대기 시간" + +#: utils/misc/guc.c:2277 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "idle-in-transaction ìƒíƒœë¡œ ìžˆì„ ìˆ˜ 있는 최대 시간" + +#: utils/misc/guc.c:2288 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "VACUUMì—서 í…Œì´ë¸” í–‰ì„ ë™ê²°í•  ë•Œê¹Œì§€ì˜ ìµœì†Œ 기간입니다." + +#: utils/misc/guc.c:2298 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "VACUUMì—서 íŠœí”Œì„ ë™ê²°í•˜ê¸° 위해 ì „ì²´ í…Œì´ë¸”ì„ ìŠ¤ìº”í•  ë•Œê¹Œì§€ì˜ ê¸°ê°„ìž…ë‹ˆë‹¤." + +#: utils/misc/guc.c:2308 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "VACUUMì—서 í…Œì´ë¸” MultiXactId ë™ê²°í•  ë•Œê¹Œì§€ì˜ ìµœì†Œ 기간입니다." + +#: utils/misc/guc.c:2318 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "VACUUMì—서 íŠœí”Œì„ ë™ê²°í•˜ê¸° 위해 ì „ì²´ í…Œì´ë¸”ì„ ìŠ¤ìº”í•  ë•Œê¹Œì§€ì˜ ë©€í‹°íŠ¸ëžœìž­ì…˜ 기간입니다." + +#: utils/misc/guc.c:2328 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "" + +#: utils/misc/guc.c:2341 +msgid "Sets the maximum number of locks per transaction." +msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ì—서 사용할 수 있는 최대 잠금 횟수를 지정함." + +#: utils/misc/guc.c:2342 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "공유 잠금 í…Œì´ë¸”ì€ í•œ ë²ˆì— ìž ê¶ˆì•¼ í•  고유 개체 수가 max_locks_per_transaction * max_connections를 넘지 않는다는 가정 í•˜ì— í¬ê¸°ê°€ 지정ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2353 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ì—서 사용할 수 있는 최대 잠금 횟수를 지정함." + +#: utils/misc/guc.c:2354 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "공유 predicate 잠금 í…Œì´ë¸”ì€ í•œ ë²ˆì— ìž ê¶ˆì•¼ í•  고유 개체 수가 max_pred_locks_per_transaction * max_connections를 넘지 않는다는 가정 í•˜ì— í¬ê¸°ê°€ 지정ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2365 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ì—서 사용할 수 있는 페ì´ì§€ì™€ íŠœí”Œì˜ ìµœëŒ€ìˆ˜ 지정함." + +#: utils/misc/guc.c:2366 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "" + +#: utils/misc/guc.c:2376 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "페ì´ì§€ë‹¹ 잠금 튜플 최대 수 지정." + +#: utils/misc/guc.c:2377 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "" + +#: utils/misc/guc.c:2387 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "í´ë¼ì´ì–¸íЏ ì¸ì¦ì„ 완료할 수 있는 최대 허용 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2399 +msgid "Waits N seconds on connection startup before authentication." +msgstr "ì¸ì¦ ì „ì— ì—°ê²°ì´ ì‹œìž‘ë˜ë„ë¡ Nì´ˆ ë™ì•ˆ 기다립니다." + +#: utils/misc/guc.c:2410 +msgid "Sets the number of WAL files held for standby servers." +msgstr "대기 서버를 위해 보관하고 ìžˆì„ WAL íŒŒì¼ ê°œìˆ˜ 지정" + +#: utils/misc/guc.c:2420 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "WAL 최소 í¬ê¸°" + +#: utils/misc/guc.c:2432 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "ì²´í¬í¬ì¸íЏ ìž‘ì—…ì„ í•  WAL í¬ê¸° 지정" + +#: utils/misc/guc.c:2444 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "ìžë™ WAL ì²´í¬í¬ì¸íЏ 사ì´ì˜ 최대 ê°„ê²©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2455 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "지정 시간 ì•ˆì— ì²´í¬í¬ì¸íЏ ì¡°ê°ì´ ëª¨ë‘ ì±„ì›Œì§€ë©´ 경고를 냄" + +#: utils/misc/guc.c:2457 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "ì²´í¬í¬ì¸íЏ ìž‘ì—…ì´ ì§€ê¸ˆ 지정한 시간(ì´ˆ)보다 ìžì£¼ ì²´í¬í¬ì¸íЏ 세그먼트 파ì¼ì— ë‚´ìš©ì´ ê½‰ 차는 사태가 ë°œìƒí•˜ë©´ 경고 메시지를 서버 ë¡œê·¸ì— ë‚¨ê¹ë‹ˆë‹¤. ì´ ê°’ì„ 0으로 지정하면 ì´ ê¸°ëŠ¥ ì—†ìŒ" + +#: utils/misc/guc.c:2469 utils/misc/guc.c:2626 utils/misc/guc.c:2653 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "" + +#: utils/misc/guc.c:2480 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "WAL ê¸°ëŠ¥ì„ ìœ„í•´ 공유 메모리ì—서 사용할 ë””ìŠ¤í¬ íŽ˜ì´ì§€ ë²„í¼ ê°œìˆ˜ë¥¼ 지정함." + +#: utils/misc/guc.c:2491 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "WAL 기ë¡ìžê°€ 지정 시간 ë§Œí¼ ì‰¬ê³  쓰기 ìž‘ì—…ì„ ë°˜ë³µí•¨" + +#: utils/misc/guc.c:2502 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "" + +#: utils/misc/guc.c:2514 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "ë™ì‹œì— ìž‘ë™í•  WAL 송신 프로세스 최대 수 지정" + +#: utils/misc/guc.c:2525 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "ë™ì‹œì— 사용할 수 있는 복제 슬롯 최대 수 지정" + +#: utils/misc/guc.c:2535 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "WAL 복제를 위해 기다릴 최대 시간 설정" + +#: utils/misc/guc.c:2546 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "트랜잭션과 트랜잭션 ë¡œê·¸ì˜ ì ìš© 사ì´ì˜ ê°„ê²©ì„ microsecond 단위로 지정함" + +#: utils/misc/guc.c:2558 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "commit_delay 처리하기 ì „ì— ìžˆëŠ” 최소 ë™ì‹œ ì—´ë ¤ 있는 트랜잭션 개수." + +#: utils/misc/guc.c:2569 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "ë¶€ë™ì†Œìˆ˜í˜• ê°’ì„ í‘œê¸°í•  때 " + +#: utils/misc/guc.c:2570 +msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." +msgstr "ì´ ê°’ì€ real, duoble ë¶€ë™ ì†Œìˆ«ì ê³¼ 지리정보 ìžë£Œí˜•ì— ì˜í–¥ì„ ë¼ì¹©ë‹ˆë‹¤. ì´ ê°’ì€ ì •ìˆ˜ì—¬ì•¼í•©ë‹ˆë‹¤(FLT_DIG or DBL_DIG as appropriate - 무슨 ë§ì¸ì§€)." + +#: utils/misc/guc.c:2581 +msgid "Sets the minimum execution time above which statements will be logged." +msgstr "ì´ ì‹œê°„ì„ ì´ˆê³¼í•  경우 ì¿¼ë¦¬ë¬¸ì„ ë¡œê·¸ë¡œ 남길 최소 실행 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2583 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "0ì„ ì§€ì •í•˜ë©´ 모든 쿼리가 ì¸ì‡„ë©ë‹ˆë‹¤. -1ì„ ì§€ì •í•˜ë©´ ì´ ê¸°ëŠ¥ì´ í•´ì œë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2593 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "ì´ ì‹œê°„ì„ ì´ˆê³¼í•  경우 ìžë™ 청소 작업 로그를 남길 최소 실행 ì‹œê°„ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2595 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "0ì„ ì§€ì •í•˜ë©´ 모든 ìž‘ì—…ì´ ì¸ì‡„ë©ë‹ˆë‹¤. -1ì„ ì§€ì •í•˜ë©´ ìžë™ 청소 기ë¡ì´ í•´ì œë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2605 +msgid "Background writer sleep time between rounds." +msgstr "백그ë¼ìš´ë“œ 기ë¡ìžì˜ ìž ìžëŠ” 시간" + +#: utils/misc/guc.c:2616 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "ë¼ìš´ë“œë‹¹ 플러시할 백그ë¼ìš´ë“œ 작성기 최대 LRU 페ì´ì§€ 수입니다." + +#: utils/misc/guc.c:2639 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "ë””ìŠ¤í¬ í•˜ìœ„ 시스템ì—서 효율ì ìœ¼ë¡œ 처리할 수 있는 ë™ì‹œ 요청 수입니다." + +#: utils/misc/guc.c:2640 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "RAID ë°°ì—´ì˜ ê²½ìš° ì´ ê°’ì€ ëŒ€ëžµ ë°°ì—´ì˜ ë“œë¼ì´ë¸Œ 스핀들 수입니다." + +#: utils/misc/guc.c:2666 +msgid "Maximum number of concurrent worker processes." +msgstr "ë™ì‹œ ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ì˜ ìµœëŒ€ 수" + +#: utils/misc/guc.c:2678 +msgid "Maximum number of logical replication worker processes." +msgstr "논리 복제 ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ì˜ ìµœëŒ€ 수" + +#: utils/misc/guc.c:2690 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "구ë…ì„ ìœ„í•œ í…Œì´ë¸” ë™ê¸°í™” 작업ìžì˜ 최대 수" + +#: utils/misc/guc.c:2700 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Në¶„ í›„ì— ìžë™ 로그 íŒŒì¼ íšŒì „ì´ ë°œìƒí•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2711 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "N킬로바ì´íЏ í›„ì— ìžë™ 로그 íŒŒì¼ íšŒì „ì´ ë°œìƒí•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2722 +msgid "Shows the maximum number of function arguments." +msgstr "함수 ì¸ìžì˜ 최대 갯수를 ë³´ì—¬ì¤ë‹ˆë‹¤" + +#: utils/misc/guc.c:2733 +msgid "Shows the maximum number of index keys." +msgstr "ì¸ë±ìФ í‚¤ì˜ ìµœëŒ€ê°œìˆ˜ë¥¼ ë³´ì—¬ì¤ë‹ˆë‹¤." + +#: utils/misc/guc.c:2744 +msgid "Shows the maximum identifier length." +msgstr "최대 ì‹ë³„ìž ê¸¸ì´ë¥¼ 표시합니다." + +#: utils/misc/guc.c:2755 +msgid "Shows the size of a disk block." +msgstr "ë””ìŠ¤í¬ ë¸”ë¡ì˜ í¬ê¸°ë¥¼ 표시합니다." + +#: utils/misc/guc.c:2766 +msgid "Shows the number of pages per disk file." +msgstr "ë””ìŠ¤í¬ íŒŒì¼ë‹¹ 페ì´ì§€ 수를 표시합니다." + +#: utils/misc/guc.c:2777 +msgid "Shows the block size in the write ahead log." +msgstr "미리 쓰기 ë¡œê·¸ì˜ ë¸”ë¡ í¬ê¸°ë¥¼ 표시합니다." + +#: utils/misc/guc.c:2788 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "" + +#: utils/misc/guc.c:2800 +msgid "Shows the size of write ahead log segments." +msgstr "미리 쓰기 로그 세그먼트당 페ì´ì§€ í¬ê¸°ë¥¼ 표시합니다." + +#: utils/misc/guc.c:2813 +msgid "Time to sleep between autovacuum runs." +msgstr "ìžë™ 청소 실행 사ì´ì˜ 절전 모드 시간입니다." + +#: utils/misc/guc.c:2823 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "청소 ì „ì˜ ìµœì†Œ 튜플 ì—…ë°ì´íЏ ë˜ëŠ” ì‚­ì œ 수입니다." + +#: utils/misc/guc.c:2832 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "통계 ì •ë³´ ìˆ˜ì§‘ì„ ìœ„í•œ 최소 튜플 삽입, ì—…ë°ì´íЏ ë˜ëŠ” ì‚­ì œ 수입니다." + +#: utils/misc/guc.c:2842 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "트랜잭션 ID 겹침 방지를 위해 í…Œì´ë¸”ì— ëŒ€í•´ autovacuum ìž‘ì—…ì„ ìˆ˜í–‰í•  í…Œì´ë¸” 나ì´ë¥¼ 지정합니다." + +#: utils/misc/guc.c:2853 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "멀티 트랜잭션 ID 겹침 방지를 위해 í…Œì´ë¸”ì— ëŒ€í•´ autovacuum ìž‘ì—…ì„ ìˆ˜í–‰í•  트랜잭션 나ì´ë¥¼ 지정합니다." + +#: utils/misc/guc.c:2863 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "ë™ì‹œì— 작업할 수 있는 autovacuum ìž‘ì—…ìž ìµœëŒ€ 수 지정" + +#: utils/misc/guc.c:2873 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "유지보수 작업ì—서 사용할 병렬 프로세스 최대 수를 지정" + +#: utils/misc/guc.c:2883 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "실행 노드당 최대 병렬 처리 수 지정" + +#: utils/misc/guc.c:2893 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "í•œë²ˆì— ìž‘ì—…í•  수 있는 병렬 ìž‘ì—…ìž ìµœëŒ€ 수 지정" + +#: utils/misc/guc.c:2903 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "ê° autovacuum ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ê°€ 사용할 메모리 최대치" + +#: utils/misc/guc.c:2914 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "" + +#: utils/misc/guc.c:2915 +msgid "A value of -1 disables this feature." +msgstr "ì´ ê°’ì´ -1 ì´ë©´ ì´ ê¸°ëŠ¥ 사용 안함" + +#: utils/misc/guc.c:2925 +msgid "Time between issuing TCP keepalives." +msgstr "TCP ì—°ê²° 유지 실행 간격입니다." + +#: utils/misc/guc.c:2926 utils/misc/guc.c:2937 +msgid "A value of 0 uses the system default." +msgstr "ì´ ê°’ì´ 0ì´ë©´ 시스템 기본 ê°’" + +#: utils/misc/guc.c:2936 +msgid "Time between TCP keepalive retransmits." +msgstr "TCP keepalive 시간 설정" + +#: utils/misc/guc.c:2947 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "" + +#: utils/misc/guc.c:2958 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "TCP keepalive í™•ì¸ ìµœëŒ€ 횟수" + +#: utils/misc/guc.c:2959 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "ì´ ê°’ì€ ì—°ê²°ì´ ì¤‘ë‹¨ëœ ê²ƒìœ¼ë¡œ 간주ë˜ê¸° ì „ì— ì†ì‹¤ë  수 있는 ì—°ì† ì—°ê²° 유지 재전송 수를 제어합니다. ê°’ 0ì„ ì§€ì •í•˜ë©´ 시스템 기본 ê°’ì´ ì‚¬ìš©ë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:2970 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "정확한 GIN 기준 ê²€ìƒ‰ì— í—ˆìš©ë˜ëŠ” 최대 ê²°ê³¼ 수를 설정합니다." + +#: utils/misc/guc.c:2981 +msgid "Sets the planner's assumption about the size of the disk cache." +msgstr "ë””ìŠ¤í¬ ìºì‹œ í¬ê¸°ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ê°€ì •ì„ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/misc/guc.c:9998 -#, c-format -msgid "Cannot enable parameter when \"log_statement_stats\" is true." -msgstr "\"log_statement_stats\" ê°’ì´ true ì¼ ë•ŒëŠ” ì´ ê°’ì„ í™œì„±í™”í•  수 없습니다" +#: utils/misc/guc.c:2982 +msgid "That is, the portion of the kernel's disk cache that will be used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "즉, PostgreSQL ë°ì´í„° 파ì¼ì— ì‚¬ìš©ë  ì»¤ë„ì˜ ë””ìŠ¤í¬ ìºì‹œ 부분입니다. ì´ ê°’ì€ ë””ìŠ¤í¬ íŽ˜ì´ì§€ 단위로 측정ë˜ë©°, ì¼ë°˜ì ìœ¼ë¡œ ê°ê° 8KB입니다." -#: utils/misc/guc.c:10010 -#, c-format -msgid "" -"Cannot enable \"log_statement_stats\" when \"log_parser_stats\", " -"\"log_planner_stats\", or \"log_executor_stats\" is true." +#: utils/misc/guc.c:2994 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "병렬 조회를 위한 최소 í…Œì´ë¸” ìžë£ŒëŸ‰ 지정" + +#: utils/misc/guc.c:2995 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." msgstr "" -"\"log_parser_stats\", \"log_planner_stats\", \"log_executor_stats\" 설정값들 " -"중 하나가 true ì¼ ë•ŒëŠ” \"log_statement_stats\" ì„¤ì •ì„ í™œì„±í™”í•  수 없습니다" -#: utils/misc/help_config.c:131 -#, c-format -msgid "internal error: unrecognized run-time parameter type\n" -msgstr "ë‚´ë¶€ 오류: 알 수 없는 실시간 서버 설정 변수\n" +#: utils/misc/guc.c:3005 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "병렬 조회를 위한 최소 ì¸ë±ìФ ìžë£ŒëŸ‰ 지정" -#: utils/misc/pg_config.c:61 -#, c-format -msgid "" -"query-specified return tuple and function return type are not compatible" +#: utils/misc/guc.c:3006 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." msgstr "" -#: utils/misc/rls.c:127 -#, c-format -msgid "query would be affected by row-level security policy for table \"%s\"" -msgstr "\"%s\" í…Œì´ë¸”ì˜ ë¡œìš° 단위 보안 ì •ì±…ì— ì˜í•´ 쿼리가 ì˜í–¥ì„ ë°›ìŒ" +#: utils/misc/guc.c:3017 +msgid "Shows the server version as an integer." +msgstr "서버 ë²„ì „ì„ ì •ìˆ˜í˜•ìœ¼ë¡œ ë³´ì—¬ì¤ë‹ˆë‹¤" -#: utils/misc/rls.c:129 -#, c-format -msgid "" -"To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW " -"LEVEL SECURITY." +#: utils/misc/guc.c:3028 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "ì´ í‚¬ë¡œë°”ì´íЏ 수보다 í° ìž„ì‹œ 파ì¼ì˜ ì‚¬ìš©ì„ ê¸°ë¡í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3029 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "0ì„ ì§€ì •í•˜ë©´ 모든 파ì¼ì´ 기ë¡ë©ë‹ˆë‹¤. 기본 ê°’ì€ -1로, ì´ ê¸°ëŠ¥ì´ í•´ì œë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3039 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "pg_stat_activity.queryì— ì˜ˆì•½ë˜ëŠ” í¬ê¸°(ë°”ì´íЏ)를 설정합니다." + +#: utils/misc/guc.c:3050 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "GIN ì¸ë±ìŠ¤ë¥¼ 위한 팬딩(pending) 목ë¡ì˜ 최대 í¬ê¸° 지정" + +#: utils/misc/guc.c:3070 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "순차ì ìœ¼ë¡œ 접근하는 ë””ìŠ¤í¬ íŽ˜ì´ì§€ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3080 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "비순차ì ìœ¼ë¡œ 접근하는 ë””ìŠ¤í¬ íŽ˜ì´ì§€ì— 대한 ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3090 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "ê° íŠœí”Œ(í–‰)ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3100 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "실행 계íšê¸°ì˜ 비용 ê³„ì‚°ì— ì‚¬ìš©ë  ì¸ë±ìФ 스캔으로 ê° ì¸ë±ìФ í•­ëª©ì„ ì²˜ë¦¬í•˜ëŠ” ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3110 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "실행 계íšê¸°ì˜ 비용 ê³„ì‚°ì— ì‚¬ìš©ë  í•¨ìˆ˜ 호출ì´ë‚˜ ì—°ì‚°ìž ì—°ì‚° 처리하는 ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3120 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "ê° íŠœí”Œ(í–‰)ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ì²˜ë¦¬ ë¹„ìš©ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3130 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "" -"í…Œì´ë¸” 소유주를 위해 ì •ì±…ì„ ë¹„í™œì„±í•˜ë ¤ë©´, ALTER TABLE NO FORCE ROW LEVEL " -"SECURITY ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”" -#: utils/misc/timeout.c:388 -#, c-format -msgid "cannot add more timeout reasons" -msgstr "시간 초과로 ë”ì´ìƒ 추가할 수 ì—†ìŒ" +#: utils/misc/guc.c:3141 +msgid "Perform JIT compilation if query is more expensive." +msgstr "" -#: utils/misc/tzparser.c:61 -#, c-format -msgid "" -"time zone abbreviation \"%s\" is too long (maximum %d characters) in time " -"zone file \"%s\", line %d" +#: utils/misc/guc.c:3142 +msgid "-1 disables JIT compilation." msgstr "" -"\"%s\" 타임 ì¡´ ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤(최대 %dìž) (\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 줄" -"ì— ìžˆìŒ)." -#: utils/misc/tzparser.c:73 -#, c-format -msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +#: utils/misc/guc.c:3151 +msgid "Optimize JITed functions if query is more expensive." msgstr "" -"%d 타임 ì¡´ 오프셋 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났습니다(\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 ì¤„ì— " -"있ìŒ)." -#: utils/misc/tzparser.c:112 -#, c-format -msgid "missing time zone abbreviation in time zone file \"%s\", line %d" -msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— time zone ìƒëžµí˜•ì´ ë¹ ì¡ŒìŒ" +#: utils/misc/guc.c:3152 +msgid "-1 disables optimization." +msgstr "-1 최ì í™” 비활성화" -#: utils/misc/tzparser.c:121 -#, c-format -msgid "missing time zone offset in time zone file \"%s\", line %d" -msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— time zone ì˜µì…‹ì´ ë¹ ì¡ŒìŒ" +#: utils/misc/guc.c:3161 +msgid "Perform JIT inlining if query is more expensive." +msgstr "" -#: utils/misc/tzparser.c:133 -#, c-format -msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +#: utils/misc/guc.c:3162 +msgid "-1 disables inlining." msgstr "" -"\"%s\" 표준 시간대 파ì¼ì˜ %d번째 줄ì—서 표준 시간대 오프셋 숫ìžê°€ 잘못ë¨" -#: utils/misc/tzparser.c:169 -#, c-format -msgid "invalid syntax in time zone file \"%s\", line %d" -msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— êµ¬ë¬¸ 오류" +#: utils/misc/guc.c:3171 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "ê²€ìƒ‰ë  ì»¤ì„œ í–‰ì— ëŒ€í•œ ê³„íš ê´€ë¦¬ìžì˜ ì˜ˆìƒ ë¶„ìˆ˜ ê°’ì„ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/misc/tzparser.c:237 -#, c-format -msgid "time zone abbreviation \"%s\" is multiply defined" -msgstr "표준 시간대 약어 \"%s\"ì€(는) 배수로 ì •ì˜ë¨" +#: utils/misc/guc.c:3182 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: 모집단 ë‚´ì˜ ì„ íƒ ì••ë ¥ìž…ë‹ˆë‹¤." + +#: utils/misc/guc.c:3192 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: 무작위 경로 ì„ íƒì„ 위한 씨드" + +#: utils/misc/guc.c:3202 +msgid "Multiple of the average buffer usage to free per round." +msgstr "ë¼ìš´ë“œë‹¹ 해제할 í‰ê·  ë²„í¼ ì‚¬ìš©ì˜ ë°°ìˆ˜ìž…ë‹ˆë‹¤." + +#: utils/misc/guc.c:3212 +msgid "Sets the seed for random-number generation." +msgstr "난수 ìƒì„± ì†ë„를 설정합니다." + +#: utils/misc/guc.c:3223 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "vacuum ìž‘ì—…ì„ ì§„í–‰í•  update, delete ìž‘ì—…ëŸ‰ì„ ì „ì²´ ìžë£Œì— 대한 분수값으로 지정합니다." + +#: utils/misc/guc.c:3232 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "통계 수집 ìž‘ì—…ì„ ì§„í–‰í•  insert, update, delete ìž‘ì—…ëŸ‰ì„ ì „ì²´ ìžë£Œì— 대한 분수값으로 지정합니다." + +#: utils/misc/guc.c:3242 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "ì²´í¬í¬ì¸íЏ ë„중 ë³€ê²½ëœ ë²„í¼ í”ŒëŸ¬ì‹œì— ì‚¬ìš©ëœ ì‹œê°„ìœ¼ë¡œ, ì²´í¬í¬ì¸íЏ ê°„ê²©ì˜ ë¶„ìˆ˜ 값입니다." + +#: utils/misc/guc.c:3252 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "" + +#: utils/misc/guc.c:3271 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "WAL 파ì¼ì„ ì•„ì¹´ì´ë¹™í•˜ê¸° 위해 í˜¸ì¶œë  ì…¸ ëª…ë ¹ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3281 +msgid "Sets the client's character set encoding." +msgstr "í´ë¼ì´ì–¸íЏ ë¬¸ìž ì„¸íŠ¸ ì¸ì½”ë”©ì„ ì§€ì •í•¨" + +#: utils/misc/guc.c:3292 +msgid "Controls information prefixed to each log line." +msgstr "ê° ë¡œê·¸ 줄 ì•žì— ì¶”ê°€í•  정보를 제어합니다." + +#: utils/misc/guc.c:3293 +msgid "If blank, no prefix is used." +msgstr "비워 ë‘ë©´ ì ‘ë‘사가 사용ë˜ì§€ 않습니다." + +#: utils/misc/guc.c:3302 +msgid "Sets the time zone to use in log messages." +msgstr "로그 ë©”ì‹œì§€ì— ì‚¬ìš©í•  표준 시간대를 설정합니다." + +#: utils/misc/guc.c:3312 +msgid "Sets the display format for date and time values." +msgstr "날짜와 시간 ê°’ì„ ë‚˜íƒ€ë‚´ëŠ” ëª¨ì–‘ì„ ì§€ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3313 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "ë˜í•œ 모호한 ë‚ ì§œ ìž…ë ¥ì˜ í•´ì„ì„ ì œì–´í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3324 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "í…Œì´ë¸” ë° ì¸ë±ìŠ¤ë¥¼ 만들 기본 í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 설정합니다." + +#: utils/misc/guc.c:3325 +msgid "An empty string selects the database's default tablespace." +msgstr "빈 문ìžì—´ì„ 지정하면 ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ í…Œì´ë¸”스페ì´ìŠ¤ê°€ ì„ íƒë©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3335 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "임시 í…Œì´ë¸” ë° ì •ë ¬ 파ì¼ì— 사용할 í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 설정합니다." + +#: utils/misc/guc.c:3346 +msgid "Sets the path for dynamically loadable modules." +msgstr "ë™ì ìœ¼ë¡œ 불러올 수 있는 ëª¨ë“ˆë“¤ì´ ìžˆëŠ” 경로를 지정함." + +#: utils/misc/guc.c:3347 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "ë™ì ìœ¼ë¡œ 로드 가능한 ëª¨ë“ˆì„ ì—´ì–´ì•¼ í•˜ëŠ”ë° ì§€ì •í•œ ì´ë¦„ì— ë””ë ‰í„°ë¦¬ 구성 요소가 없는 경우(즉, ì´ë¦„ì— ìŠ¬ëž˜ì‹œê°€ ì—†ìŒ) ì‹œìŠ¤í…œì€ ì´ ê²½ë¡œì—서 지정한 파ì¼ì„ 검색합니다." + +#: utils/misc/guc.c:3360 +msgid "Sets the location of the Kerberos server key file." +msgstr "Kerberos 서버 키 파ì¼ì˜ 위치를 지정함." + +#: utils/misc/guc.c:3371 +msgid "Sets the Bonjour service name." +msgstr "Bonjour 서비스 ì´ë¦„ì„ ì§€ì •" + +#: utils/misc/guc.c:3383 +msgid "Shows the collation order locale." +msgstr "ë°ì´í„° ì •ë ¬ 순서 로케ì¼ì„ 표시합니다." + +#: utils/misc/guc.c:3394 +msgid "Shows the character classification and case conversion locale." +msgstr "ë¬¸ìž ë¶„ë¥˜ ë° ëŒ€/ì†Œë¬¸ìž ë³€í™˜ 로케ì¼ì„ 표시합니다." + +#: utils/misc/guc.c:3405 +msgid "Sets the language in which messages are displayed." +msgstr "보여질 메시지로 사용할 언어 지정." + +#: utils/misc/guc.c:3415 +msgid "Sets the locale for formatting monetary amounts." +msgstr "통화금액 표현 ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." + +#: utils/misc/guc.c:3425 +msgid "Sets the locale for formatting numbers." +msgstr "ìˆ«ìž í‘œí˜„ ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." + +#: utils/misc/guc.c:3435 +msgid "Sets the locale for formatting date and time values." +msgstr "날짜와 시간 ê°’ì„ í‘œí˜„í•  ì–‘ì‹ìœ¼ë¡œ 사용할 ë¡œì¼€ì¼ ì§€ì •." + +#: utils/misc/guc.c:3445 +msgid "Lists shared libraries to preload into each backend." +msgstr "ê°ê°ì˜ ë°±ì—”ë“œì— ë¯¸ë¦¬ 불러올 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" + +#: utils/misc/guc.c:3456 +msgid "Lists shared libraries to preload into server." +msgstr "ì„œë²„ì— ë¯¸ë¦¬ 불러올 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" + +#: utils/misc/guc.c:3467 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "ê°ê°ì˜ ë°±ì—”ë“œì— ë¯¸ë¦¬ 불러올 접근제한 없는 공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 지정합니다" + +#: utils/misc/guc.c:3478 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "스키마로 한정ë˜ì§€ ì•Šì€ ì´ë¦„ì˜ ìŠ¤í‚¤ë§ˆ 검색 순서를 설정합니다." + +#: utils/misc/guc.c:3490 +msgid "Sets the server (database) character set encoding." +msgstr "서버 ë¬¸ìž ì½”ë“œ 세트 ì¸ì½”딩 지정." + +#: utils/misc/guc.c:3502 +msgid "Shows the server version." +msgstr "서버 버전 ë³´ìž„." + +#: utils/misc/guc.c:3514 +msgid "Sets the current role." +msgstr "현재 ë¡¤ì„ ì§€ì •" + +#: utils/misc/guc.c:3526 +msgid "Sets the session user name." +msgstr "세션 ì‚¬ìš©ìž ì´ë¦„ 지정." + +#: utils/misc/guc.c:3537 +msgid "Sets the destination for server log output." +msgstr "서버 로그 ì¶œë ¥ì„ ìœ„í•œ 대ìƒì„ 지정합니다." + +#: utils/misc/guc.c:3538 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "유효한 ê°’ì€ í”Œëž«í¼ì— ë”°ë¼ \"stderr\", \"syslog\", \"csvlog\" ë° \"eventlog\"ì˜ ì¡°í•©ìž…ë‹ˆë‹¤." + +#: utils/misc/guc.c:3549 +msgid "Sets the destination directory for log files." +msgstr "로그 파ì¼ì˜ ëŒ€ìƒ ë””ë ‰í„°ë¦¬ë¥¼ 설정합니다." + +#: utils/misc/guc.c:3550 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ìƒëŒ€ 경로 ë˜ëŠ” 절대 경로로 지정할 수 있습니다." + +#: utils/misc/guc.c:3560 +msgid "Sets the file name pattern for log files." +msgstr "로그 파ì¼ì˜ íŒŒì¼ ì´ë¦„ íŒ¨í„´ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3571 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "syslogì—서 구분할 PostgreSQL ë©”ì‹œì§€ì— ì‚¬ìš©ë  í”„ë¡œê·¸ëž¨ ì´ë¦„ì„ ì§€ì •." + +#: utils/misc/guc.c:3582 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "ì´ë²¤íЏ 로그ì—서 PostgreSQL 메시지 ì‹ë³„ìžë¡œ 사용할 ì‘용프로그램 ì´ë¦„ 지정" + +#: utils/misc/guc.c:3593 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "시간대(time zone)를 지정함." + +#: utils/misc/guc.c:3603 +msgid "Selects a file of time zone abbreviations." +msgstr "표준 시간대 약어 파ì¼ì„ ì„ íƒí•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3613 +msgid "Sets the current transaction's isolation level." +msgstr "현재 트랜잭션 ë…립성 수준(isolation level)ì„ ì§€ì •í•¨." + +#: utils/misc/guc.c:3624 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì˜ ì†Œìœ ì£¼ë¥¼ 지정" + +#: utils/misc/guc.c:3625 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "소켓 소유ìžëŠ” í•­ìƒ ì„œë²„ë¥¼ 시작하는 사용ìžìž…니다." + +#: utils/misc/guc.c:3635 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "유닉스 ë„ë©”ì¸ ì†Œì¼“ì„ ë§Œë“¤ 디렉터리를 지정합니다." + +#: utils/misc/guc.c:3650 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "서비스할 호스트ì´ë¦„ì´ë‚˜, IP를 지정함." + +#: utils/misc/guc.c:3665 +msgid "Sets the server's data directory." +msgstr "ì„œë²„ì˜ ë°ì´í„° 디렉터리 위치를 지정합니다." + +#: utils/misc/guc.c:3676 +msgid "Sets the server's main configuration file." +msgstr "ì„œë²„ì˜ ê¸°ë³¸ 환경설정 íŒŒì¼ ê²½ë¡œë¥¼ 지정합니다." + +#: utils/misc/guc.c:3687 +msgid "Sets the server's \"hba\" configuration file." +msgstr "ì„œë²„ì˜ \"hba\" 구성 파ì¼ì„ 설정합니다." + +#: utils/misc/guc.c:3698 +msgid "Sets the server's \"ident\" configuration file." +msgstr "ì„œë²„ì˜ \"ident\" 구성 파ì¼ì„ 설정합니다." + +#: utils/misc/guc.c:3709 +msgid "Writes the postmaster PID to the specified file." +msgstr "postmaster PIDê°€ 기ë¡ëœ 파ì¼ì˜ 경로를 지정합니다." + +#: utils/misc/guc.c:3720 +msgid "Location of the SSL server certificate file." +msgstr "서버 ì¸ì¦ì„œ íŒŒì¼ ìœ„ì¹˜ë¥¼ 지정함" + +#: utils/misc/guc.c:3730 +msgid "Location of the SSL server private key file." +msgstr "SSL 서버 ê°œì¸ í‚¤ 파ì¼ì˜ 위치를 지정함." + +#: utils/misc/guc.c:3740 +msgid "Location of the SSL certificate authority file." +msgstr "" + +#: utils/misc/guc.c:3750 +msgid "Location of the SSL certificate revocation list file." +msgstr "SSL ì¸ì¦ì„œ 파기 ëª©ë¡ íŒŒì¼ì˜ 위치" + +#: utils/misc/guc.c:3760 +msgid "Writes temporary statistics files to the specified directory." +msgstr "지정한 ë””ë ‰í„°ë¦¬ì— ìž„ì‹œ 통계 파ì¼ì„ ì”니다." + +#: utils/misc/guc.c:3771 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "" + +#: utils/misc/guc.c:3782 +msgid "Sets default text search configuration." +msgstr "기본 í…스트 검색 êµ¬ì„±ì„ ì„¤ì •í•©ë‹ˆë‹¤." + +#: utils/misc/guc.c:3792 +msgid "Sets the list of allowed SSL ciphers." +msgstr "허용ë˜ëŠ” SSL 암호 목ë¡ì„ 설정합니다." + +#: utils/misc/guc.c:3807 +msgid "Sets the curve to use for ECDH." +msgstr "ECDHì— ì‚¬ìš©í•  curve 설정" + +#: utils/misc/guc.c:3822 +msgid "Location of the SSL DH parameters file." +msgstr "SSL DH 매개 변수 파ì¼ì˜ 위치." -#: utils/misc/tzparser.c:239 -#, c-format -msgid "" -"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s" -"\", line %d." +#: utils/misc/guc.c:3833 +msgid "Command to obtain passphrases for SSL." msgstr "" -"\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 ì¤„ì— ìžˆëŠ” í•­ëª©ì´ \"%s\" 파ì¼ì˜ %d번째 ì¤„ì— ìžˆëŠ” " -"항목과 ì¶©ëŒí•©ë‹ˆë‹¤." -#: utils/misc/tzparser.c:301 -#, c-format -msgid "invalid time zone file name \"%s\"" -msgstr "ìž˜ëª»ëœ time zone íŒŒì¼ ì´ë¦„: \"%s\"" +#: utils/misc/guc.c:3843 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "" -#: utils/misc/tzparser.c:314 -#, c-format -msgid "time zone file recursion limit exceeded in file \"%s\"" -msgstr "\"%s\" 파ì¼ì—서 time zone íŒŒì¼ ìž¬ê·€í˜¸ì¶œ 최대치를 초과했ìŒ" +#: utils/misc/guc.c:3854 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "" -#: utils/misc/tzparser.c:353 utils/misc/tzparser.c:366 -#, c-format -msgid "could not read time zone file \"%s\": %m" -msgstr "\"%s\" time zone 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" +#: utils/misc/guc.c:3865 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "" -#: utils/misc/tzparser.c:376 -#, c-format -msgid "line is too long in time zone file \"%s\", line %d" -msgstr "\"%s\" 표준 시간대 파ì¼ì˜ %d번째 ì¤„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤." +#: utils/misc/guc.c:3866 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "" -#: utils/misc/tzparser.c:399 -#, c-format -msgid "@INCLUDE without file name in time zone file \"%s\", line %d" -msgstr "\"%s\" 표준 시간대 파ì¼ì˜ %d번째 ì¤„ì— íŒŒì¼ ì´ë¦„ì´ ì—†ëŠ” @INCLUDEê°€ 있ìŒ" +#: utils/misc/guc.c:3876 +msgid "JIT provider to use." +msgstr "" -#: utils/mmgr/aset.c:510 -#, c-format -msgid "Failed while creating memory context \"%s\"." -msgstr "\"%s\" 메모리 컨í…스트를 만드는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤." +#: utils/misc/guc.c:3896 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "문ìžì—´ì—서 \"\\'\" ë¬¸ìž ì‚¬ìš©ì„ í—ˆìš©í•  것ì¸ì§€ë¥¼ 정하세요" -#: utils/mmgr/mcxt.c:768 utils/mmgr/mcxt.c:803 utils/mmgr/mcxt.c:840 -#: utils/mmgr/mcxt.c:877 utils/mmgr/mcxt.c:911 utils/mmgr/mcxt.c:940 -#: utils/mmgr/mcxt.c:974 utils/mmgr/mcxt.c:1056 utils/mmgr/mcxt.c:1090 -#: utils/mmgr/mcxt.c:1139 -#, c-format -msgid "Failed on request of size %zu." -msgstr "í¬ê¸°ê°€ %zuì¸ ìš”ì²­ì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤." +#: utils/misc/guc.c:3906 +msgid "Sets the output format for bytea." +msgstr "bytea ê°’ì˜ í‘œì‹œ 형ì‹ì„ 설정합니다." -#: utils/mmgr/portalmem.c:207 -#, c-format -msgid "cursor \"%s\" already exists" -msgstr "\"%s\" ì´ë¦„ì˜ ì»¤ì„œê°€ ì´ë¯¸ 있ìŒ" +#: utils/misc/guc.c:3916 +msgid "Sets the message levels that are sent to the client." +msgstr "í´ë¼ì´ì–¸íЏ ì¸¡ì— ë³´ì—¬ì§ˆ 메시지 ìˆ˜ì¤€ì„ ì§€ì •í•¨." -#: utils/mmgr/portalmem.c:211 -#, c-format -msgid "closing existing cursor \"%s\"" -msgstr "ì´ë¯¸ 있는 \"%s\" 커서를 닫습니다" +#: utils/misc/guc.c:3917 utils/misc/guc.c:3970 utils/misc/guc.c:3981 +#: utils/misc/guc.c:4047 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "ê° ìˆ˜ì¤€ì—는 ì´ ìˆ˜ì¤€ ë’¤ì— ìžˆëŠ” 모든 ìˆ˜ì¤€ì´ í¬í•¨ë©ë‹ˆë‹¤. ìˆ˜ì¤€ì´ ë’¤ì— ìžˆì„ìˆ˜ë¡ ì „ì†¡ë˜ëŠ” 메시지 수가 ì ìŠµë‹ˆë‹¤." -#: utils/mmgr/portalmem.c:415 -#, c-format -msgid "portal \"%s\" cannot be run" -msgstr "\"%s\" portal 실행할 수 ì—†ìŒ" +#: utils/misc/guc.c:3927 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "실행계íšê¸°ê°€ 쿼리 최ì í™” 작업ì—서 제약 ì¡°ê±´ì„ ì‚¬ìš©í•˜ë„ë¡ í•¨" -#: utils/mmgr/portalmem.c:495 -#, c-format -msgid "cannot drop active portal \"%s\"" -msgstr "\"%s\" 활성 í¬í„¸ì„ 삭제할 수 ì—†ìŒ" +#: utils/misc/guc.c:3928 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "제약 ì¡°ê±´ì— ì˜í•´ 쿼리와 ì¼ì¹˜í•˜ëŠ” í–‰ì´ ì—†ëŠ” 경우 í…Œì´ë¸” ìŠ¤ìº”ì„ ê±´ë„ˆëœë‹ˆë‹¤." -#: utils/mmgr/portalmem.c:699 -#, c-format -msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" -msgstr "WITH HOLD 옵션으로 커서를 만든 íŠ¸ëžœìž­ì…˜ì„ PREPAREí•  수 ì—†ìŒ" +#: utils/misc/guc.c:3938 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "ê° ìƒˆ íŠ¸ëžœìž­ì…˜ì˜ íŠ¸ëžœìž­ì…˜ 격리 ìˆ˜ì¤€ì„ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/sort/logtape.c:226 -#, c-format -msgid "could not read block %ld of temporary file: %m" -msgstr "임시 파ì¼ì˜ %ld ë¸”ëŸ­ì„ ì½ì„ 수 ì—†ìŒ: %m" +#: utils/misc/guc.c:3948 +msgid "Sets the display format for interval values." +msgstr "간격 ê°’ì˜ í‘œì‹œ 형ì‹ì„ 설정합니다." -#: utils/sort/tuplesort.c:3402 -#, c-format -msgid "cannot have more than %d runs for an external sort" -msgstr "외부 ì •ë ¬ì„ ìœ„í•´ %d ê°œ ì´ìƒì˜ ëŸ°ì„ ë§Œë“¤ 수 ì—†ìŒ" +#: utils/misc/guc.c:3959 +msgid "Sets the verbosity of logged messages." +msgstr "기ë¡ë˜ëŠ” ë©”ì‹œì§€ì˜ ìƒì„¸ ì •ë„를 지정합니다." -#: utils/sort/tuplesort.c:4474 -#, c-format -msgid "could not create unique index \"%s\"" -msgstr "\"%s\" 고유 ì¸ë±ìŠ¤ë¥¼ 만들 수 ì—†ìŒ" +#: utils/misc/guc.c:3969 +msgid "Sets the message levels that are logged." +msgstr "서버 ë¡œê·¸ì— ê¸°ë¡ë  메시지 ìˆ˜ì¤€ì„ ì§€ì •í•¨." -#: utils/sort/tuplesort.c:4476 -#, c-format -msgid "Key %s is duplicated." -msgstr "%s 키가 중복ë¨" +#: utils/misc/guc.c:3980 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "오류가 있는 모든 쿼리문ì´ë‚˜ 지정한 로그 레벨 ì´ìƒì˜ ì¿¼ë¦¬ë¬¸ì„ ë¡œê·¸ë¡œ 남김" -#: utils/sort/tuplesort.c:4477 -#, c-format -msgid "Duplicate keys exist." -msgstr "ì¤‘ë³µëœ í‚¤ê°€ 있ìŒ" +#: utils/misc/guc.c:3991 +msgid "Sets the type of statements logged." +msgstr "ì„œë²„ë¡œê·¸ì— ê¸°ë¡ë  구문 종류를 지정합니다." -#: utils/sort/tuplestore.c:515 utils/sort/tuplestore.c:525 -#: utils/sort/tuplestore.c:852 utils/sort/tuplestore.c:956 -#: utils/sort/tuplestore.c:1020 utils/sort/tuplestore.c:1037 -#: utils/sort/tuplestore.c:1239 utils/sort/tuplestore.c:1304 -#: utils/sort/tuplestore.c:1313 -#, c-format -msgid "could not seek in tuplestore temporary file: %m" -msgstr "tuplestore 파ì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %m" +#: utils/misc/guc.c:4001 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "syslog ê¸°ëŠ¥ì„ ì‚¬ìš©í•  때, 사용할 syslog \"facility\" ê°’ì„ ì§€ì •." -#: utils/sort/tuplestore.c:1460 utils/sort/tuplestore.c:1533 -#: utils/sort/tuplestore.c:1539 -#, c-format -msgid "could not read from tuplestore temporary file: %m" -msgstr "tuplestore 임시 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" +#: utils/misc/guc.c:4016 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "트리거 ë° ë‹¤ì‹œ 쓰기 ê·œì¹™ì— ëŒ€í•œ ì„¸ì…˜ì˜ ë™ìž‘ì„ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/sort/tuplestore.c:1501 utils/sort/tuplestore.c:1506 -#: utils/sort/tuplestore.c:1512 -#, c-format -msgid "could not write to tuplestore temporary file: %m" -msgstr "tuplestore 임시 파ì¼ì„ 쓸 수 없습니다: %m" +#: utils/misc/guc.c:4026 +msgid "Sets the current transaction's synchronization level." +msgstr "현재 트랜잭션 격리 수준(isolation level)ì„ ì§€ì •í•¨." -#: utils/time/snapmgr.c:618 -#, c-format -msgid "The source transaction is not running anymore." -msgstr "소스 íŠ¸ëžœìž­ì…˜ì´ ë” ì´ìƒ 실행중ì´ì§€ 않ìŒ" +#: utils/misc/guc.c:4036 +msgid "Allows archiving of WAL files using archive_command." +msgstr "archive_command를 사용하여 WAL 파ì¼ì„ 따로 보관하ë„ë¡ ì„¤ì •í•©ë‹ˆë‹¤." -#: utils/time/snapmgr.c:1190 -#, c-format -msgid "cannot export a snapshot from a subtransaction" -msgstr "서브트랜잭션ì—서 ìŠ¤ëƒ…ìƒ·ì„ ë‚´ë³´ë‚¼ 수 ì—†ìŒ" +#: utils/misc/guc.c:4046 +msgid "Enables logging of recovery-related debugging information." +msgstr "복구 작업과 ê´€ë ¨ëœ ë””ë²„ê¹… 정보를 기ë¡í•˜ë„ë¡ í•©ë‹ˆë‹¤." -#: utils/time/snapmgr.c:1339 utils/time/snapmgr.c:1344 -#: utils/time/snapmgr.c:1349 utils/time/snapmgr.c:1364 -#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1374 -#: utils/time/snapmgr.c:1473 utils/time/snapmgr.c:1489 -#: utils/time/snapmgr.c:1514 -#, c-format -msgid "invalid snapshot data in file \"%s\"" -msgstr "\"%s\" 파ì¼ì— 유효하지 ì•Šì€ ìŠ¤ëƒ…ìƒ· ìžë£Œê°€ 있습니다" +#: utils/misc/guc.c:4062 +msgid "Collects function-level statistics on database activity." +msgstr "ë°ì´í„°ë² ì´ìФ 활ë™ì— 대한 함수 수준 통계를 수집합니다." -#: utils/time/snapmgr.c:1411 -#, c-format -msgid "SET TRANSACTION SNAPSHOT must be called before any query" -msgstr "쿼리보다 먼저 SET TRANSACTION SNAPSHOP ëª…ë ¹ì„ í˜¸ì¶œí•´ì•¼ 함" +#: utils/misc/guc.c:4072 +msgid "Set the level of information written to the WAL." +msgstr "WALì— ì €ìž¥í•  ë‚´ìš© ìˆ˜ì¤€ì„ ì§€ì •í•©ë‹ˆë‹¤." -#: utils/time/snapmgr.c:1420 -#, c-format -msgid "" -"a snapshot-importing transaction must have isolation level SERIALIZABLE or " -"REPEATABLE READ" -msgstr "" -"스냅샷 가져오기 íŠ¸ëžœìž­ì…˜ì€ ê·¸ 격리 ìˆ˜ì¤€ì´ SERIALIZABLE ë˜ëŠ” REPEATABLE READ " -"여야 함" +#: utils/misc/guc.c:4082 +msgid "Selects the dynamic shared memory implementation used." +msgstr "사용할 ë™ì  공유 메모리 관리방ì‹ì„ ì„ íƒí•©ë‹ˆë‹¤." -#: utils/time/snapmgr.c:1429 utils/time/snapmgr.c:1438 -#, c-format -msgid "invalid snapshot identifier: \"%s\"" -msgstr "ìž˜ëª»ëœ ìŠ¤ëƒ…ìƒ· ì‹ë³„ìž: \"%s\"" +#: utils/misc/guc.c:4092 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "디스í¬ì— 대한 ê°•ì œ WAL ì—…ë°ì´íŠ¸ì— ì‚¬ìš©ë˜ëŠ” ë°©ë²•ì„ ì„ íƒí•©ë‹ˆë‹¤." -#: utils/time/snapmgr.c:1527 -#, c-format -msgid "" -"a serializable transaction cannot import a snapshot from a non-serializable " -"transaction" -msgstr "" -"ì§ë ¬í™” 가능한 íŠ¸ëžœìž­ì…˜ì€ ì§ë ¬í™” 가능하지 ì•Šì€ íŠ¸ëžœìž­ì…˜ì—서 ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ " -"수 ì—†ìŒ" +#: utils/misc/guc.c:4102 +msgid "Sets how binary values are to be encoded in XML." +msgstr "XMLì—서 ë°”ì´ë„ˆë¦¬ ê°’ì´ ì¸ì½”딩ë˜ëŠ” ë°©ì‹ì„ 설정합니다." -#: utils/time/snapmgr.c:1531 -#, c-format -msgid "" -"a non-read-only serializable transaction cannot import a snapshot from a " -"read-only transaction" -msgstr "" -"ì½ê¸°-쓰기 ì§ë ¬í™”ëœ íŠ¸ëžœìž­ì…˜ì´ ì½ê¸° ì „ìš© íŠ¸ëžœìž­ì…˜ì˜ ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" +#: utils/misc/guc.c:4112 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "ì•”ì‹œì  êµ¬ë¬¸ ë¶„ì„ ë° ì§ë ¬í™” ìž‘ì—…ì˜ XML ë°ì´í„°ë¥¼ 문서 ë˜ëŠ” ë‚´ìš© ì¡°ê°ìœ¼ë¡œ 간주할지 여부를 설정합니다." -#: utils/time/snapmgr.c:1546 -#, c-format -msgid "cannot import a snapshot from a different database" -msgstr "서로 다른 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 대ìƒìœ¼ë¡œëŠ” ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" +#: utils/misc/guc.c:4123 +msgid "Use of huge pages on Linux or Windows." +msgstr "리눅스 ë˜ëŠ” Windows huge 페ì´ì§€ 사용 여부" -#: gram.y:1004 -#, c-format -msgid "unrecognized role option \"%s\"" -msgstr "ì¸ì‹í•  수 없는 롤 옵션 \"%s\"" +#: utils/misc/guc.c:4133 +msgid "Forces use of parallel query facilities." +msgstr "병렬 쿼리 ê¸°ëŠ¥ì„ í™œì„±í™”" -#: gram.y:1278 gram.y:1293 -#, c-format -msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +#: utils/misc/guc.c:4134 +msgid "If possible, run query using a parallel worker and with parallel restrictions." msgstr "" -"CREATE SCHEMA IF NOT EXISTS 구문ì—서는 스키마 ìš”ì†Œë“¤ì„ í¬í•¨í•  수 없습니다." -#: gram.y:1438 -#, c-format -msgid "current database cannot be changed" -msgstr "현재 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 바꿀 수 ì—†ìŒ" +#: utils/misc/guc.c:4143 +msgid "Encrypt passwords." +msgstr "암호를 암호화 해서 기ë¡í•¨" -#: gram.y:1562 -#, c-format -msgid "time zone interval must be HOUR or HOUR TO MINUTE" -msgstr "" -"지역시간대 간격(time zone interval) ê°’ì€ ì‹œ(HOUR) ë˜ëŠ” 시분(HOUR TO MINUTE) " -"ê°’ì´ì–´ì•¼í•©ë‹ˆë‹¤" +#: utils/misc/guc.c:4144 +msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +msgstr "CREATE USER ë˜ëŠ” ALTER USER 명령ì—서 ENCRYPTED ë˜ëŠ” UNENCRYPTED ì†ì„±ì„ 특별히 지정하지 않았고 ì‚¬ìš©ìž ì•”í˜¸ë¥¼ ì§€ì •í–ˆì„ ë•Œ, ê·¸ 암호를 암호화 해서 저장할 것ì¸ì§€ 아닌지를 지정함" -#: gram.y:2600 gram.y:2629 +#: utils/misc/guc.c:4946 #, c-format -msgid "STDIN/STDOUT not allowed with PROGRAM" -msgstr "PROGRAM 옵션과 STDIN/STDOUT ì˜µì…˜ì€ í•¨ê»˜ 쓸 수 없습니다" +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ: %s\n" -#: gram.y:2895 gram.y:2902 gram.y:10295 gram.y:10303 +#: utils/misc/guc.c:4951 #, c-format -msgid "GLOBAL is deprecated in temporary table creation" -msgstr "GLOBAL 예약어는 임시 í…Œì´ë¸” 만들기ì—서 ë” ì´ìƒ 사용하지 않습니다" - -#: gram.y:4809 -msgid "duplicate trigger events specified" -msgstr "중복 트리거 ì´ë²¤íŠ¸ê°€ 지정ë¨" +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "initdb 명령ì´ë‚˜, pg_basebackup 명령으로 PostgreSQL ë°ì´í„° 디렉터리를 초기화 하세요.\n" -#: gram.y:4909 +#: utils/misc/guc.c:4971 #, c-format -msgid "conflicting constraint properties" -msgstr "제약조건 ì†ì„±ì´ ì¶©ëŒí•¨" +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФ 시스템 환경 설정 파ì¼ì„ 찾지 못했습니다.\n" +"ì§ì ‘ --config-file ë˜ëŠ” -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" +"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" +"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" -#: gram.y:5041 +#: utils/misc/guc.c:4990 #, c-format -msgid "CREATE ASSERTION is not yet implemented" -msgstr "CREATE ASSERTION ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: \"%s\" 환경 설정 파ì¼ì„ 접근할 수 없습니다: %s\n" -#: gram.y:5057 +#: utils/misc/guc.c:5016 #, c-format -msgid "DROP ASSERTION is not yet implemented" -msgstr "CREATE ASSERTION ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФ 시스템 ë°ì´í„° 디렉터리를 찾지 못했습니다.\n" +"\"%s\" 파ì¼ì—서 \"data_directory\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" +"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" +"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" +"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" -#: gram.y:5403 +#: utils/misc/guc.c:5064 #, c-format -msgid "RECHECK is no longer required" -msgstr "RECHECK는 ë” ì´ìƒ 필요하지 않ìŒ" +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s í”„ë¡œê·¸ëž¨ì€ \"hba\" 환경설정파ì¼ì„ 찾지 못했습니다.\n" +"\"%s\" 파ì¼ì—서 \"hba_file\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" +"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" +"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" +"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" -#: gram.y:5404 +#: utils/misc/guc.c:5087 #, c-format -msgid "Update your data type." -msgstr "ìžë£Œí˜•ì„ ì—…ë°ì´íŠ¸í•˜ì‹­ì‹œì˜¤." +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s í”„ë¡œê·¸ëž¨ì€ \"ident\" 환경설정파ì¼ì„ 찾지 못했습니다.\n" +"\"%s\" 파ì¼ì—서 \"ident_file\" ê°’ì„ ì§€ì •í•˜ë“ ì§€,\n" +"ì§ì ‘ -D ì˜µì…˜ì„ ì´ìš©í•´ì„œ ë°ì´í„° 디렉터리를 지정하든지,\n" +"PGDATA ì´ë¦„ì˜ í™˜ê²½ 변수를 만들고 ê·¸ 값으로 해당 디렉터리를 지정한 ë’¤,\n" +"ì´ í”„ë¡œê·¸ëž¨ì„ ë‹¤ì‹œ 실행해 보십시오.\n" + +#: utils/misc/guc.c:5762 utils/misc/guc.c:5809 +msgid "Value exceeds integer range." +msgstr "ê°’ì´ ì •ìˆ˜ 범위를 초과합니다." -#: gram.y:6983 +#: utils/misc/guc.c:6032 #, c-format -msgid "aggregates cannot have output arguments" -msgstr "집계 함수는 output ì¸ìžë¥¼ 지정할 수 ì—†ìŒ" +msgid "parameter \"%s\" requires a numeric value" +msgstr "\"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ì€ ìˆ«ìží˜•ì´ì–´ì•¼í•©ë‹ˆë‹¤." -#: gram.y:8853 gram.y:8871 +#: utils/misc/guc.c:6041 #, c-format -msgid "WITH CHECK OPTION not supported on recursive views" -msgstr "WITH CHECK OPTION êµ¬ë¬¸ì€ ìž¬ê·€ì ì¸ ë·°ì—서 ì§€ì›í•˜ì§€ 않습니다" +msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g ê°’ì€ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’ìœ¼ë¡œ 타당한 범위(%g .. %g)를 벗어났습니다." -#: gram.y:9389 +#: utils/misc/guc.c:6194 utils/misc/guc.c:7564 #, c-format -msgid "unrecognized VACUUM option \"%s\"" -msgstr "ì¸ì‹í•  수 없는 VACUUM 옵션 \"%s\"" +msgid "cannot set parameters during a parallel operation" +msgstr "병렬 작업 중ì—는 매개 변수를 설정할 수 ì—†ìŒ" -#: gram.y:10403 +#: utils/misc/guc.c:6201 utils/misc/guc.c:6953 utils/misc/guc.c:7006 +#: utils/misc/guc.c:7057 utils/misc/guc.c:7393 utils/misc/guc.c:8160 +#: utils/misc/guc.c:8328 utils/misc/guc.c:10005 #, c-format -msgid "LIMIT #,# syntax is not supported" -msgstr "LIMIT #,# êµ¬ë¬¸ì€ ì§€ì›í•˜ì§€ 않습니다." +msgid "unrecognized configuration parameter \"%s\"" +msgstr "알 수 없는 환경 매개 변수 ì´ë¦„: \"%s\"" -#: gram.y:10404 +#: utils/misc/guc.c:6216 utils/misc/guc.c:7405 #, c-format -msgid "Use separate LIMIT and OFFSET clauses." -msgstr "LIMIT # OFFSET # êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." +msgid "parameter \"%s\" cannot be changed" +msgstr "\"%s\" 매개 변수는 ë³€ê²½ë  ìˆ˜ ì—†ìŒ" -#: gram.y:10667 gram.y:10692 +#: utils/misc/guc.c:6249 #, c-format -msgid "VALUES in FROM must have an alias" -msgstr "FROM ì•ˆì˜ VALUES는 반드시 aliasê°€ 있어야합니다" +msgid "parameter \"%s\" cannot be changed now" +msgstr "\"%s\" 매개 변수는 지금 변경 ë  ìˆ˜ ì—†ìŒ" -#: gram.y:10668 gram.y:10693 +#: utils/misc/guc.c:6267 utils/misc/guc.c:6314 utils/misc/guc.c:10021 #, c-format -msgid "For example, FROM (VALUES ...) [AS] foo." -msgstr "예, FROM (VALUES ...) [AS] foo." +msgid "permission denied to set parameter \"%s\"" +msgstr "\"%s\" 매개 변수를 지정할 ê¶Œí•œì´ ì—†ìŠµë‹ˆë‹¤." -#: gram.y:10673 gram.y:10698 +#: utils/misc/guc.c:6304 #, c-format -msgid "subquery in FROM must have an alias" -msgstr "FROM ì ˆ ë‚´ì˜ subquery ì—는 반드시 alias 를 가져야만 합니다" +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "\"%s\" 매개 ë³€ìˆ˜ê°’ì€ ì—°ê²° 시작한 ë’¤ì—는 변경할 수 없습니다" -#: gram.y:10674 gram.y:10699 +#: utils/misc/guc.c:6352 #, c-format -msgid "For example, FROM (SELECT ...) [AS] foo." -msgstr "예, FROM (SELECT ...) [AS] foo." +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "보안 ì •ì˜ìž 함수 ë‚´ì—서 \"%s\" 매개 변수를 설정할 수 ì—†ìŒ" -#: gram.y:11273 +#: utils/misc/guc.c:6961 utils/misc/guc.c:7011 utils/misc/guc.c:8335 #, c-format -msgid "precision for type float must be at least 1 bit" -msgstr "실수형 ìžë£Œì˜ ì •ë°€ë„ ê°’ìœ¼ë¡œëŠ” ì ì–´ë„ 1 bit ì´ìƒì„ 지정해야합니다." +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "\"%s\" 검사를 위한 pg_read_all_settingsì˜ ë§´ë²„ëŠ” superuser여야합니다" -#: gram.y:11282 +#: utils/misc/guc.c:7102 #, c-format -msgid "precision for type float must be less than 54 bits" -msgstr "실수형 ìžë£Œì˜ ì •ë°€ë„ ê°’ìœ¼ë¡œ 최대 54 bit 까지입니다." +msgid "SET %s takes only one argument" +msgstr "SET %s ëª…ë ¹ì€ í•˜ë‚˜ì˜ ê°’ë§Œ 지정해야합니다" -#: gram.y:11786 +#: utils/misc/guc.c:7353 #, c-format -msgid "wrong number of parameters on left side of OVERLAPS expression" -msgstr "OVERLAPS ì‹ì˜ ì™¼ìª½ì— ìžˆëŠ” 매개 변수 수가 잘못ë¨" +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "슈í¼ìœ ì €ë§Œ ALTER SYSTEM ëª…ë ¹ì„ ì‹¤í–‰í•  수 있ìŒ" -#: gram.y:11791 +#: utils/misc/guc.c:7438 #, c-format -msgid "wrong number of parameters on right side of OVERLAPS expression" -msgstr "OVERLAPS ì‹ì˜ ì˜¤ë¥¸ìª½ì— ìžˆëŠ” 매개 변수 수가 잘못ë¨" +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "ALTER SYSTEM 명령으로 지정하는 매개 변수 ê°’ì—는 줄바꿈 문ìžê°€ 없어야 합니다" -#: gram.y:11966 +#: utils/misc/guc.c:7483 #, c-format -msgid "UNIQUE predicate is not yet implemented" -msgstr "UNIQUE 술어는 ì•„ì§ êµ¬í˜„ë˜ì§€ 못했습니다" +msgid "could not parse contents of file \"%s\"" +msgstr "\"%s\" 파ì¼ì˜ ë‚´ìš©ì„ ë¶„ì„í•  수 ì—†ìŒ" -#: gram.y:12300 +#: utils/misc/guc.c:7640 #, c-format -msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" -msgstr "WITHIN GROUP 구문 안ì—서 ì¤‘ë³µëœ ORDER BY êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT ëª…ë ¹ì€ ì•„ì§ êµ¬í˜„ ë˜ì§€ 않았습니다" -#: gram.y:12305 +#: utils/misc/guc.c:7724 #, c-format -msgid "cannot use DISTINCT with WITHIN GROUP" -msgstr "DISTINCTê³¼ WITHIN GROUPì„ í•¨ê»˜ 쓸 수 없습니다" +msgid "SET requires parameter name" +msgstr "SET ëª…ë ¹ì€ ë§¤ê°œ 변수 ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤" -#: gram.y:12310 +#: utils/misc/guc.c:7857 #, c-format -msgid "cannot use VARIADIC with WITHIN GROUP" -msgstr "VARIADICê³¼ WITHIN GROUPì„ í•¨ê»˜ 쓸 수 없습니다" +msgid "attempt to redefine parameter \"%s\"" +msgstr "\"%s\" 매개 변수를 다시 ì •ì˜í•˜ë ¤ê³  함" -#: gram.y:12816 +#: utils/misc/guc.c:9638 #, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDINGì€ UNBOUNDED와 함께 사용해야 합니다" +msgid "parameter \"%s\" could not be set" +msgstr "\"%s\" 매개 변수는 설정할 수 ì—†ìŒ" -#: gram.y:12822 +#: utils/misc/guc.c:9725 #, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWINGì€ UNBOUNDED와 함께 사용해야 합니다" +msgid "could not parse setting for parameter \"%s\"" +msgstr "지정한 \"%s\" 매개 ë³€ìˆ˜ê°’ì˜ êµ¬ë¬¸ë¶„ì„ì„ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤." -#: gram.y:12849 gram.y:12872 +#: utils/misc/guc.c:10083 utils/misc/guc.c:10117 #, c-format -msgid "frame start cannot be UNBOUNDED FOLLOWING" -msgstr "프레임 ì‹œìž‘ì€ UNBOUNDED FOLLOWINGì¼ ìˆ˜ ì—†ìŒ" +msgid "invalid value for parameter \"%s\": %d" +msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: %d" -#: gram.y:12854 +#: utils/misc/guc.c:10151 #, c-format -msgid "frame starting from following row cannot end with current row" -msgstr "ë”°ë¼ì˜¤ëŠ” ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ í˜„ìž¬ ë¡œìš°ì˜ ëì¼ ìˆ˜ 없습니다" +msgid "invalid value for parameter \"%s\": %g" +msgstr "ìž˜ëª»ëœ \"%s\" 매개 ë³€ìˆ˜ì˜ ê°’: %g" -#: gram.y:12877 +#: utils/misc/guc.c:10421 #, c-format -msgid "frame end cannot be UNBOUNDED PRECEDING" -msgstr "프레임 ëì€ UNBOUNDED PRECEDINGì¼ ìˆ˜ ì—†ìŒ" +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "해당 세션ì—서 ì–´ë–¤ 임시 í…Œì´ë¸”ë„ ì‚¬ìš©í•˜ê³  있지 않아야 \"temp_buffers\" ì„¤ì •ì„ ë³€ê²½í•  수 있습니다." -#: gram.y:12883 +#: utils/misc/guc.c:10433 #, c-format -msgid "frame starting from current row cannot have preceding rows" -msgstr "현재 ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ ì„ í–‰í•˜ëŠ” 로우를 가질 수 없습니다" +msgid "Bonjour is not supported by this build" +msgstr "Bonjour ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." -#: gram.y:12890 +#: utils/misc/guc.c:10446 #, c-format -msgid "frame starting from following row cannot have preceding rows" -msgstr "ë”°ë¼ì˜¤ëŠ” ë¡œìš°ì˜ í”„ë ˆìž„ ì‹œìž‘ì€ ì„ í–‰í•˜ëŠ” 로우를 가질 수 없습니다" +msgid "SSL is not supported by this build" +msgstr "SSL ì ‘ì† ê¸°ëŠ¥ì„ ëº€ 채로 서버가 만들어졌습니다." -#: gram.y:13555 +#: utils/misc/guc.c:10458 #, c-format -msgid "type modifier cannot have parameter name" -msgstr "ìžë£Œí˜• 한정ìžëŠ” 매개 변수 ì´ë¦„ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "\"log_statement_stats\" ê°’ì´ true ì¼ ë•ŒëŠ” ì´ ê°’ì„ í™œì„±í™”í•  수 없습니다" -#: gram.y:13561 +#: utils/misc/guc.c:10470 #, c-format -msgid "type modifier cannot have ORDER BY" -msgstr "ìžë£Œí˜• 한정ìžëŠ” ORDER BY êµ¬ë¬¸ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "\"log_parser_stats\", \"log_planner_stats\", \"log_executor_stats\" 설정값들 중 하나가 true ì¼ ë•ŒëŠ” \"log_statement_stats\" ì„¤ì •ì„ í™œì„±í™”í•  수 없습니다" -#: gram.y:13625 gram.y:13631 +#: utils/misc/help_config.c:131 #, c-format -msgid "%s cannot be used as a role name here" -msgstr "%s ì´ë¦„ì€ ì—¬ê¸°ì„œ 롤 ì´ë¦„으로 사용할 수 ì—†ìŒ" - -#: gram.y:14253 gram.y:14442 -msgid "improper use of \"*\"" -msgstr "\"*\" ì‚¬ìš©ì´ ìž˜ëª»ë¨" +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "ë‚´ë¶€ 오류: 알 수 없는 실시간 서버 설정 변수\n" -#: gram.y:14506 +#: utils/misc/pg_config.c:60 #, c-format -msgid "" -"an ordered-set aggregate with a VARIADIC direct argument must have one " -"VARIADIC aggregated argument of the same data type" +msgid "query-specified return tuple and function return type are not compatible" msgstr "" -#: gram.y:14543 +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 #, c-format -msgid "multiple ORDER BY clauses not allowed" -msgstr "ì¤‘ë³µëœ ORDER BY êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" +msgid "calculated CRC checksum does not match value stored in file" +msgstr "ê³„ì‚°ëœ CRC ì²´í¬ì„¬ ê°’ì´ íŒŒì¼ì— ì €ìž¥ëœ ê°’ê³¼ 다름" -#: gram.y:14554 +#: utils/misc/pg_rusage.c:64 #, c-format -msgid "multiple OFFSET clauses not allowed" -msgstr "ì¤‘ë³µëœ OFFSET êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "" -#: gram.y:14563 +#: utils/misc/rls.c:127 #, c-format -msgid "multiple LIMIT clauses not allowed" -msgstr "ì¤‘ë³µëœ LIMIT êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "\"%s\" í…Œì´ë¸”ì˜ ë¡œìš° 단위 보안 ì •ì±…ì— ì˜í•´ 쿼리가 ì˜í–¥ì„ ë°›ìŒ" -#: gram.y:14572 +#: utils/misc/rls.c:129 #, c-format -msgid "multiple WITH clauses not allowed" -msgstr "ì¤‘ë³µëœ WITH ì ˆì€ í—ˆìš©í•˜ì§€ 않ìŒ" +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "í…Œì´ë¸” 소유주를 위해 ì •ì±…ì„ ë¹„í™œì„±í•˜ë ¤ë©´, ALTER TABLE NO FORCE ROW LEVEL SECURITY ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”" -#: gram.y:14764 +#: utils/misc/timeout.c:388 #, c-format -msgid "OUT and INOUT arguments aren't allowed in TABLE functions" -msgstr "OUT ë° INOUT ì¸ìžëŠ” TABLE í•¨ìˆ˜ì— ì‚¬ìš©í•  수 ì—†ìŒ" +msgid "cannot add more timeout reasons" +msgstr "시간 초과로 ë”ì´ìƒ 추가할 수 ì—†ìŒ" -#: gram.y:14865 +#: utils/misc/tzparser.c:61 #, c-format -msgid "multiple COLLATE clauses not allowed" -msgstr "ì¤‘ë³µëœ COLLATE êµ¬ë¬¸ì€ í—ˆìš©í•˜ì§€ 않습니다" +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "\"%s\" 타임 ì¡´ ì´ë¦„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤(최대 %dìž) (\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 ì¤„ì— ìžˆìŒ)." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14903 gram.y:14916 +#: utils/misc/tzparser.c:73 #, c-format -msgid "%s constraints cannot be marked DEFERRABLE" -msgstr "%s 제약조건ì—는 DEFERRABLE ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "%d 타임 ì¡´ 오프셋 ê°’ì´ ë²”ìœ„ë¥¼ 벗어났습니다(\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 ì¤„ì— ìžˆìŒ)." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14929 +#: utils/misc/tzparser.c:112 #, c-format -msgid "%s constraints cannot be marked NOT VALID" -msgstr "%s 제약조건ì—는 NOT VALID ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— time zone ìƒëžµí˜•ì´ ë¹ ì¡ŒìŒ" -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14942 +#: utils/misc/tzparser.c:121 #, c-format -msgid "%s constraints cannot be marked NO INHERIT" -msgstr "%s 제약조건ì—는 NO INHERIT ì˜µì…˜ì„ ì“¸ 수 ì—†ìŒ" +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— time zone ì˜µì…‹ì´ ë¹ ì¡ŒìŒ" -#: guc-file.l:314 +#: utils/misc/tzparser.c:133 #, c-format -msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" -msgstr "알 수 없는 환경 매개 변수 ì´ë¦„: \"%s\", 해당 파ì¼: \"%s\", 줄번호: %u" +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "\"%s\" 표준 시간대 파ì¼ì˜ %d번째 줄ì—서 표준 시간대 오프셋 숫ìžê°€ 잘못ë¨" -#: guc-file.l:387 +#: utils/misc/tzparser.c:169 #, c-format -msgid "parameter \"%s\" removed from configuration file, reset to default" -msgstr "환경설정 파ì¼ì— \"%s\" 매개 변수가 빠졌ìŒ, ì´ˆê¸°ê°’ì„ ì‚¬ìš©í•¨" +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone 파ì¼ì˜ %d번째 ì¤„ì— êµ¬ë¬¸ 오류" -#: guc-file.l:453 +#: utils/misc/tzparser.c:237 #, c-format -msgid "parameter \"%s\" changed to \"%s\"" -msgstr "\"%s\" 매개 변수 ê°’ì„ \"%s\"(으)로 바꿨ìŒ" +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "표준 시간대 약어 \"%s\"ì€(는) 배수로 ì •ì˜ë¨" -#: guc-file.l:495 +#: utils/misc/tzparser.c:239 #, c-format -msgid "configuration file \"%s\" contains errors" -msgstr "\"%s\" 환경 설정파ì¼ì— 오류가 있ìŒ" +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "\"%s\" 타임 ì¡´ 파ì¼ì˜ %d번째 ì¤„ì— ìžˆëŠ” í•­ëª©ì´ \"%s\" 파ì¼ì˜ %d번째 ì¤„ì— ìžˆëŠ” 항목과 ì¶©ëŒí•©ë‹ˆë‹¤." -#: guc-file.l:500 +#: utils/misc/tzparser.c:301 #, c-format -msgid "" -"configuration file \"%s\" contains errors; unaffected changes were applied" -msgstr "\"%s\" 환경 설정 파ì¼ì— 오류가 있어 새로 ë³€ê²½ë  ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤" +msgid "invalid time zone file name \"%s\"" +msgstr "ìž˜ëª»ëœ time zone íŒŒì¼ ì´ë¦„: \"%s\"" -#: guc-file.l:505 +#: utils/misc/tzparser.c:314 #, c-format -msgid "configuration file \"%s\" contains errors; no changes were applied" -msgstr "\"%s\" 환경 설정 파ì¼ì— 오류가 있어 아무 ì„¤ì •ë„ ë°˜ì˜ë˜ì§€ 않았습니다." +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "\"%s\" 파ì¼ì—서 time zone íŒŒì¼ ìž¬ê·€í˜¸ì¶œ 최대치를 초과했ìŒ" -#: guc-file.l:578 +#: utils/misc/tzparser.c:353 utils/misc/tzparser.c:366 #, c-format -msgid "" -"could not open configuration file \"%s\": maximum nesting depth exceeded" -msgstr "설정 íŒŒì¼ \"%s\"ì„ ì—´ 수 없습니다: 최대 디렉터리 깊ì´ë¥¼ 초과했ìŒ" +msgid "could not read time zone file \"%s\": %m" +msgstr "\"%s\" time zone 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: guc-file.l:605 +#: utils/misc/tzparser.c:376 #, c-format -msgid "skipping missing configuration file \"%s\"" -msgstr "\"%s\" 환경 설정파ì¼ì´ 없으나 건너뜀" +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "\"%s\" 표준 시간대 파ì¼ì˜ %d번째 ì¤„ì´ ë„ˆë¬´ ê¹ë‹ˆë‹¤." -#: guc-file.l:859 +#: utils/misc/tzparser.c:399 #, c-format -msgid "syntax error in file \"%s\" line %u, near end of line" -msgstr "\"%s\" íŒŒì¼ %u 줄 ë부분ì—서 구문 오류 있ìŒ" +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "\"%s\" 표준 시간대 파ì¼ì˜ %d번째 ì¤„ì— íŒŒì¼ ì´ë¦„ì´ ì—†ëŠ” @INCLUDEê°€ 있ìŒ" -#: guc-file.l:869 +#: utils/mmgr/aset.c:483 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format -msgid "syntax error in file \"%s\" line %u, near token \"%s\"" -msgstr "\"%s\" íŒŒì¼ %u 줄ì—서 구문 오류 있ìŒ, \"%s\" í† í° ë¶€ê·¼" +msgid "Failed while creating memory context \"%s\"." +msgstr "\"%s\" 메모리 컨í…스트를 만드는 ë™ì•ˆ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤." -#: guc-file.l:889 +#: utils/mmgr/dsa.c:518 utils/mmgr/dsa.c:1323 #, c-format -msgid "too many syntax errors found, abandoning file \"%s\"" -msgstr "구문 오류가 너무 많습니다. \"%s\" 파ì¼ì„ 무시합니다" +msgid "could not attach to dynamic shared area" +msgstr "ë™ì  공유 메모리 ì˜ì—­ì„ 할당할 수 ì—†ìŒ" -#: guc-file.l:941 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 #, c-format -msgid "could not open configuration directory \"%s\": %m" -msgstr "\"%s\" 환경 설정 디렉터리를 ì—´ 수 없습니다: %m" +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "í¬ê¸°ê°€ %zuì¸ ìš”ì²­ì—서 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. 해당 메모리 컨í…스트 \"%s\"" -#: repl_gram.y:260 repl_gram.y:292 +#: utils/mmgr/portalmem.c:187 #, c-format -msgid "invalid timeline %u" -msgstr "ìž˜ëª»ëœ íƒ€ìž„ë¼ì¸: %u" - -#: repl_scanner.l:120 -msgid "invalid streaming start location" -msgstr "ìž˜ëª»ëœ ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 위치" - -#: repl_scanner.l:171 scan.l:670 -msgid "unterminated quoted string" -msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ë¬¸ìžì—´" +msgid "cursor \"%s\" already exists" +msgstr "\"%s\" ì´ë¦„ì˜ ì»¤ì„œê°€ ì´ë¯¸ 있ìŒ" -#: repl_scanner.l:181 +#: utils/mmgr/portalmem.c:191 #, c-format -msgid "syntax error: unexpected character \"%s\"" -msgstr "구문 오류: \"%s\" 부근" +msgid "closing existing cursor \"%s\"" +msgstr "ì´ë¯¸ 있는 \"%s\" 커서를 닫습니다" -# # advance ë -#: scan.l:432 -msgid "unterminated /* comment" -msgstr "마무리 ì•ˆëœ /* 주ì„" +#: utils/mmgr/portalmem.c:398 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "\"%s\" portal 실행할 수 ì—†ìŒ" -#: scan.l:461 -msgid "unterminated bit string literal" -msgstr "마무리 ì•ˆëœ ë¹„íŠ¸ 문ìžì—´ 문ìž" +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "\"%s\" ì„ ì ëœ í¬í„¸ì„ 삭제할 수 ì—†ìŒ" -#: scan.l:482 -msgid "unterminated hexadecimal string literal" -msgstr "마무리 ì•ˆëœ 16진수 문ìžì—´ 문ìž" +#: utils/mmgr/portalmem.c:484 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "\"%s\" 활성 í¬í„¸ì„ 삭제할 수 ì—†ìŒ" -#: scan.l:532 +#: utils/mmgr/portalmem.c:729 #, c-format -msgid "unsafe use of string constant with Unicode escapes" -msgstr "유니코드 ì´ìŠ¤ì¼€ì´í”„와 함께 문ìžì—´ ìƒìˆ˜ë¥¼ 사용하는 ê²ƒì€ ì•ˆì „í•˜ì§€ 않ìŒ" +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "WITH HOLD 옵션으로 커서를 만든 íŠ¸ëžœìž­ì…˜ì„ PREPAREí•  수 ì—†ìŒ" -#: scan.l:533 +#: utils/mmgr/portalmem.c:1263 #, c-format -msgid "" -"String constants with Unicode escapes cannot be used when " -"standard_conforming_strings is off." +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" msgstr "" -"standard_conforming_strings = off ì¸ ê²½ìš° 문ìžì—´ ìƒìˆ˜ 표기ì—서 유니코드 ì´ìФ" -"ì¼€ì´í”„를 사용할 수 없습니다." -#: scan.l:579 scan.l:778 -msgid "invalid Unicode escape character" -msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ 문ìž" +#: utils/sort/logtape.c:276 +#, c-format +msgid "could not read block %ld of temporary file: %m" +msgstr "임시 파ì¼ì˜ %ld ë¸”ëŸ­ì„ ì½ì„ 수 ì—†ìŒ: %m" -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1338 -#: scan.l:1365 scan.l:1369 scan.l:1407 scan.l:1411 scan.l:1433 scan.l:1443 -msgid "invalid Unicode surrogate pair" -msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ 대리 ìŒ" +#: utils/sort/logtape.c:439 +#, c-format +msgid "could not determine size of temporary file \"%s\"" +msgstr "\"%s\" 임시 파ì¼ì˜ í¬ê¸°ë¥¼ 알 수 ì—†ìŒ" -#: scan.l:627 +#: utils/sort/sharedtuplestore.c:208 #, c-format -msgid "invalid Unicode escape" -msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ ê°’" +msgid "could not write to temporary file: %m" +msgstr "임시 파ì¼ì— 쓸 수 없습니다: %m" -#: scan.l:628 +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 #, c-format -msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." -msgstr "유니코드 ì´ìŠ¤ì¼€ì´í”„는 \\uXXXX ë˜ëŠ” \\UXXXXXXXX 형태여야 합니다." +msgid "could not read from shared tuplestore temporary file" +msgstr "tuplestore 임시 파ì¼ì„ ì½ì„ 수 ì—†ìŒ" -#: scan.l:639 +#: utils/sort/sharedtuplestore.c:492 #, c-format -msgid "unsafe use of \\' in a string literal" -msgstr "문ìžì—´ ì•ˆì— \\' ì‚¬ìš©ì´ ì•ˆì „í•˜ì§€ 않습니다" +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "ê³µìœ ëœ tuplestore 임시 파ì¼ì—서 예ìƒì¹˜ 못한 ì²­í¬" -#: scan.l:640 +#: utils/sort/tuplesort.c:2967 #, c-format -msgid "" -"Use '' to write quotes in strings. \\' is insecure in client-only encodings." -msgstr "" -"ìž‘ì€ ë”°ì˜´í‘œëŠ” '' 형태로 사용하십시오. \\' í‘œê¸°ë²•ì€ í´ë¼ì´ì–¸íЏ ì „ìš© ì¸ì½”딩ì—" -"서 안전하지 않습니다." +msgid "cannot have more than %d runs for an external sort" +msgstr "외부 ì •ë ¬ì„ ìœ„í•´ %d ê°œ ì´ìƒì˜ ëŸ°ì„ ë§Œë“¤ 수 ì—†ìŒ" -#: scan.l:715 -msgid "unterminated dollar-quoted string" -msgstr "마무리 ì•ˆëœ ë‹¬ëŸ¬-따옴표 ì•ˆì˜ ë¬¸ìžì—´" +#: utils/sort/tuplesort.c:4051 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "\"%s\" 고유 ì¸ë±ìŠ¤ë¥¼ 만들 수 ì—†ìŒ" -#: scan.l:732 scan.l:758 scan.l:773 -msgid "zero-length delimited identifier" -msgstr "길ì´ê°€ 0ì¸ êµ¬ë¶„ ì‹ë³„ìž" +#: utils/sort/tuplesort.c:4053 +#, c-format +msgid "Key %s is duplicated." +msgstr "%s 키가 중복ë¨" -#: scan.l:793 syncrep_scanner.l:84 -msgid "unterminated quoted identifier" -msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ì‹ë³„ìž" +#: utils/sort/tuplesort.c:4054 +#, c-format +msgid "Duplicate keys exist." +msgstr "ì¤‘ë³µëœ í‚¤ê°€ 있ìŒ" -# # nonun 부분 begin -#: scan.l:924 -msgid "operator too long" -msgstr "ì—°ì‚°ìžê°€ 너무 ê¹ë‹ˆë‹¤." +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file: %m" +msgstr "tuplestore 파ì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %m" -#. translator: %s is typically the translation of "syntax error" -#: scan.l:1078 +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 +#: utils/sort/tuplestore.c:1556 #, c-format -msgid "%s at end of input" -msgstr "%s, ìž…ë ¥ ë부분" +msgid "could not read from tuplestore temporary file: %m" +msgstr "tuplestore 임시 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %m" -#. translator: first %s is typically the translation of "syntax error" -#: scan.l:1086 +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 +#: utils/sort/tuplestore.c:1529 #, c-format -msgid "%s at or near \"%s\"" -msgstr "%s, \"%s\" 부근" +msgid "could not write to tuplestore temporary file: %m" +msgstr "tuplestore 임시 파ì¼ì„ 쓸 수 없습니다: %m" -#: scan.l:1252 scan.l:1284 -msgid "" -"Unicode escape values cannot be used for code point values above 007F when " -"the server encoding is not UTF8" -msgstr "" -"서버 ì¸ì½”ë”©ì´ UTF8ì´ ì•„ë‹Œ 경우 007F보다 í° ì½”ë“œ ì§€ì  ê°’ì—는 유니코드 ì´ìŠ¤ì¼€ì´" -"프 ê°’ì„ ì‚¬ìš©í•  수 ì—†ìŒ" +#: utils/time/snapmgr.c:622 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "소스 íŠ¸ëžœìž­ì…˜ì´ ë” ì´ìƒ 실행중ì´ì§€ 않ìŒ" -#: scan.l:1280 scan.l:1425 -msgid "invalid Unicode escape value" -msgstr "ìž˜ëª»ëœ ìœ ë‹ˆì½”ë“œ ì´ìŠ¤ì¼€ì´í”„ ê°’" +#: utils/time/snapmgr.c:1200 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "서브트랜잭션ì—서 ìŠ¤ëƒ…ìƒ·ì„ ë‚´ë³´ë‚¼ 수 ì—†ìŒ" -#: scan.l:1489 +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 +#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 +#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 +#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 +#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 #, c-format -msgid "nonstandard use of \\' in a string literal" -msgstr "문ìžì—´ ì•ˆì— ìžˆëŠ” \\' 문ìžëŠ” í‘œì¤€ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "invalid snapshot data in file \"%s\"" +msgstr "\"%s\" 파ì¼ì— 유효하지 ì•Šì€ ìŠ¤ëƒ…ìƒ· ìžë£Œê°€ 있습니다" -#: scan.l:1490 +#: utils/time/snapmgr.c:1456 #, c-format -msgid "" -"Use '' to write quotes in strings, or use the escape string syntax (E'...')." -msgstr "ìž‘ì€ ë”°ì˜´í‘œëŠ” '' 형태니, ì¸ìš©ë¶€í˜¸ 표기법(E'...') 형태로 사용하십시오." +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "쿼리보다 먼저 SET TRANSACTION SNAPSHOP ëª…ë ¹ì„ í˜¸ì¶œí•´ì•¼ 함" -#: scan.l:1499 +#: utils/time/snapmgr.c:1465 #, c-format -msgid "nonstandard use of \\\\ in a string literal" -msgstr "문ìžì—´ ì•ˆì— ìžˆëŠ” \\\\ 문ìžëŠ” í‘œì¤€ì´ ì•„ë‹™ë‹ˆë‹¤" +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "스냅샷 가져오기 íŠ¸ëžœìž­ì…˜ì€ ê·¸ 격리 ìˆ˜ì¤€ì´ SERIALIZABLE ë˜ëŠ” REPEATABLE READ 여야 함" -#: scan.l:1500 +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 #, c-format -msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." -msgstr "백슬래시 표기는 ì¸ìš©ë¶€í˜¸ 표기법으로 사용하세요, 예, E'\\\\'." +msgid "invalid snapshot identifier: \"%s\"" +msgstr "ìž˜ëª»ëœ ìŠ¤ëƒ…ìƒ· ì‹ë³„ìž: \"%s\"" -#: scan.l:1514 +#: utils/time/snapmgr.c:1573 #, c-format -msgid "nonstandard use of escape in a string literal" -msgstr "문ìžì—´ ì•ˆì— ë¹„í‘œì¤€ escape 문ìžë¥¼ 사용하고 있습니다" +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "ì§ë ¬í™” 가능한 íŠ¸ëžœìž­ì…˜ì€ ì§ë ¬í™” 가능하지 ì•Šì€ íŠ¸ëžœìž­ì…˜ì—서 ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" -#: scan.l:1515 +#: utils/time/snapmgr.c:1577 #, c-format -msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." -msgstr "ì¸ìš©ë¶€í˜¸ í‘œê¸°ë²•ì„ ì‚¬ìš©í•˜ì„¸ìš”, 예, E'\\r\\n'." +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "ì½ê¸°-쓰기 ì§ë ¬í™”ëœ íŠ¸ëžœìž­ì…˜ì´ ì½ê¸° ì „ìš© íŠ¸ëžœìž­ì…˜ì˜ ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" + +#: utils/time/snapmgr.c:1592 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "서로 다른 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 대ìƒìœ¼ë¡œëŠ” ìŠ¤ëƒ…ìƒ·ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" diff --git a/src/backend/po/ru.po b/src/backend/po/ru.po index a4ce728f18a..f69a96e2d7f 100644 --- a/src/backend/po/ru.po +++ b/src/backend/po/ru.po @@ -4,14 +4,14 @@ # Serguei A. Mokhov , 2001-2005. # Oleg Bartunov , 2004-2005. # Dmitriy Olshevskiy , 2014. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: postgres (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-04 04:08+0000\n" -"PO-Revision-Date: 2017-04-06 17:55+0300\n" +"POT-Creation-Date: 2019-05-04 06:52+0300\n" +"PO-Revision-Date: 2019-04-29 10:21+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -19,50 +19,59 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" -#: ../common/config_info.c:131 ../common/config_info.c:139 -#: ../common/config_info.c:147 ../common/config_info.c:155 -#: ../common/config_info.c:163 ../common/config_info.c:171 -#: ../common/config_info.c:179 ../common/config_info.c:187 -#: ../common/config_info.c:195 +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 msgid "not recorded" msgstr "не запиÑано" -#: ../common/controldata_utils.c:57 commands/copy.c:3042 -#: commands/extension.c:3325 utils/adt/genfile.c:135 +#: ../common/controldata_utils.c:58 commands/copy.c:3196 +#: commands/extension.c:3337 utils/adt/genfile.c:151 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %m" -#: ../common/controldata_utils.c:61 +#: ../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %s\n" -#: ../common/controldata_utils.c:71 access/transam/timeline.c:348 -#: access/transam/xlog.c:3381 access/transam/xlog.c:10756 -#: access/transam/xlog.c:10769 access/transam/xlog.c:11161 -#: access/transam/xlog.c:11204 access/transam/xlog.c:11243 -#: access/transam/xlog.c:11286 access/transam/xlogfuncs.c:667 -#: access/transam/xlogfuncs.c:686 commands/extension.c:3335 libpq/hba.c:499 -#: replication/logical/origin.c:658 replication/logical/origin.c:688 -#: replication/logical/reorderbuffer.c:3064 replication/walsender.c:498 -#: storage/file/copydir.c:178 utils/adt/genfile.c:152 utils/adt/misc.c:924 +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 +#: access/transam/xlog.c:3440 access/transam/xlog.c:10942 +#: access/transam/xlog.c:10955 access/transam/xlog.c:11380 +#: access/transam/xlog.c:11460 access/transam/xlog.c:11499 +#: access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 +#: access/transam/xlogfuncs.c:677 commands/extension.c:3347 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 +#: replication/logical/reorderbuffer.c:3308 replication/walsender.c:510 +#: storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 #, c-format msgid "could not read file \"%s\": %m" msgstr "не удалоÑÑŒ прочитать файл \"%s\": %m" -#: ../common/controldata_utils.c:74 +#: ../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\": %s\n" -#: ../common/controldata_utils.c:95 +#: ../common/controldata_utils.c:86 +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %d)" + +#: ../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %d)\n" + +#: ../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "неÑоответÑтвие порÑдка байт" -#: ../common/controldata_utils.c:97 +#: ../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -112,7 +121,7 @@ msgid "pclose failed: %s" msgstr "ошибка pclose: %s" #: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:182 ../port/path.c:632 #: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 #: utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 #: utils/misc/ps_status.c:217 @@ -171,42 +180,44 @@ msgstr "не удалоÑÑŒ прочитать каталог \"%s\": %s\n" msgid "could not close directory \"%s\": %s\n" msgstr "не удалоÑÑŒ закрыть каталог \"%s\": %s\n" -#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1264 access/transam/xlog.c:6347 -#: lib/stringinfo.c:300 libpq/auth.c:1063 libpq/auth.c:1428 libpq/auth.c:1496 -#: libpq/auth.c:2012 postmaster/bgworker.c:332 postmaster/bgworker.c:874 -#: postmaster/postmaster.c:2363 postmaster/postmaster.c:2385 -#: postmaster/postmaster.c:3935 postmaster/postmaster.c:4635 -#: postmaster/postmaster.c:4710 postmaster/postmaster.c:5379 -#: postmaster/postmaster.c:5660 -#: replication/libpqwalreceiver/libpqwalreceiver.c:251 -#: replication/logical/logical.c:168 storage/buffer/localbuf.c:436 -#: storage/file/fd.c:773 storage/file/fd.c:1201 storage/file/fd.c:1319 -#: storage/file/fd.c:2044 storage/ipc/procarray.c:1054 -#: storage/ipc/procarray.c:1542 storage/ipc/procarray.c:1549 -#: storage/ipc/procarray.c:1963 storage/ipc/procarray.c:2566 -#: utils/adt/formatting.c:1567 utils/adt/formatting.c:1685 -#: utils/adt/formatting.c:1804 utils/adt/pg_locale.c:468 -#: utils/adt/pg_locale.c:652 utils/adt/regexp.c:219 utils/adt/varlena.c:4552 -#: utils/adt/varlena.c:4573 utils/fmgr/dfmgr.c:216 utils/hash/dynahash.c:429 -#: utils/hash/dynahash.c:535 utils/hash/dynahash.c:1047 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3967 utils/misc/guc.c:3983 -#: utils/misc/guc.c:3996 utils/misc/guc.c:6945 utils/misc/tzparser.c:468 -#: utils/mmgr/aset.c:404 utils/mmgr/dsa.c:713 utils/mmgr/dsa.c:795 -#: utils/mmgr/mcxt.c:725 utils/mmgr/mcxt.c:760 utils/mmgr/mcxt.c:797 -#: utils/mmgr/mcxt.c:834 utils/mmgr/mcxt.c:868 utils/mmgr/mcxt.c:897 -#: utils/mmgr/mcxt.c:931 utils/mmgr/mcxt.c:982 utils/mmgr/mcxt.c:1016 -#: utils/mmgr/mcxt.c:1050 +#: ../common/psprintf.c:180 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1383 +#: access/transam/xlog.c:6482 lib/dshash.c:246 lib/stringinfo.c:277 +#: libpq/auth.c:1134 libpq/auth.c:1505 libpq/auth.c:1573 libpq/auth.c:2091 +#: postmaster/bgworker.c:337 postmaster/bgworker.c:907 +#: postmaster/postmaster.c:2391 postmaster/postmaster.c:2413 +#: postmaster/postmaster.c:3976 postmaster/postmaster.c:4684 +#: postmaster/postmaster.c:4759 postmaster/postmaster.c:5460 +#: postmaster/postmaster.c:5807 +#: replication/libpqwalreceiver/libpqwalreceiver.c:260 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:800 storage/file/fd.c:1239 storage/file/fd.c:1400 +#: storage/file/fd.c:2313 storage/ipc/procarray.c:1066 +#: storage/ipc/procarray.c:1554 storage/ipc/procarray.c:1561 +#: storage/ipc/procarray.c:1982 storage/ipc/procarray.c:2606 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 +#: utils/adt/formatting.c:1813 utils/adt/pg_locale.c:469 +#: utils/adt/pg_locale.c:633 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4240 utils/misc/guc.c:4256 utils/misc/guc.c:4269 +#: utils/misc/guc.c:7248 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 +#: utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 +#: utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 +#: utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 +#: utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 #, c-format msgid "out of memory" msgstr "нехватка памÑти" -#: ../common/relpath.c:59 +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "неверное Ð¸Ð¼Ñ ÑлоÑ" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "ДопуÑтимые имена Ñлоёв: \"main\", \"fsm\", \"vm\" и \"init\"." @@ -258,12 +269,17 @@ msgstr "не удалоÑÑŒ получить информацию о файле msgid "could not remove file or directory \"%s\": %s\n" msgstr "ошибка при удалении файла или каталога \"%s\": %s\n" +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "Ñлишком длинный пароль" + #: ../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "выÑÑнить Ñффективный идентификатор Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (%ld) не удалоÑÑŒ: %s" -#: ../common/username.c:45 libpq/auth.c:1959 +#: ../common/username.c:45 libpq/auth.c:2038 msgid "user does not exist" msgstr "пользователь не ÑущеÑтвует" @@ -392,183 +408,230 @@ msgid "could not check access token membership: error code %lu\n" msgstr "" "не удалоÑÑŒ проверить вхождение в маркере безопаÑноÑти (код ошибки: %lu)\n" -#: access/brin/brin.c:860 access/brin/brin.c:931 +#: access/brin/brin.c:200 +#, c-format +msgid "" +"request for BRIN range summarization for index \"%s\" page %u was not " +"recorded" +msgstr "" +"Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° раÑчёт Ñводки диапазона BRIN Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа \"%s\" Ñтраницы %u не был " +"запиÑан" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 +#: access/transam/xlog.c:10354 access/transam/xlog.c:10881 +#: access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 +#: access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 +#: access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 +#: access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "идёт процеÑÑ Ð²Ð¾ÑÑтановлениÑ" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "Функции ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ BRIN Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в процеÑÑе воÑÑтановлениÑ." + +#: access/brin/brin.c:886 access/brin/brin.c:963 #, c-format msgid "block number out of range: %s" msgstr "номер блока вне диапазона: %s" -#: access/brin/brin.c:883 access/brin/brin.c:954 +#: access/brin/brin.c:909 access/brin/brin.c:986 #, c-format msgid "\"%s\" is not a BRIN index" msgstr "\"%s\" - Ñто не Ð¸Ð½Ð´ÐµÐºÑ BRIN" -#: access/brin/brin.c:899 access/brin/brin.c:970 +#: access/brin/brin.c:925 access/brin/brin.c:1002 #, c-format msgid "could not open parent table of index %s" msgstr "не удалоÑÑŒ родительÑкую таблицу индекÑа %s" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:360 -#: access/brin/brin_pageops.c:826 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1381 access/nbtree/nbtinsert.c:678 +#: access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" msgstr "" -"размер Ñтроки индекÑа (%lu) больше предельного размера (%lu) (Ð¸Ð½Ð´ÐµÐºÑ \"%s\")" +"размер Ñтроки индекÑа (%zu) больше предельного размера (%zu) (Ð¸Ð½Ð´ÐµÐºÑ \"%s\")" -#: access/brin/brin_revmap.c:379 access/brin/brin_revmap.c:385 +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 #, c-format msgid "corrupted BRIN index: inconsistent range map" msgstr "иÑпорченный Ð¸Ð½Ð´ÐµÐºÑ BRIN: неÑоглаÑованноÑть в карте диапазонов" -#: access/brin/brin_revmap.c:401 +#: access/brin/brin_revmap.c:404 #, c-format msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" msgstr "" "в BRIN-индекÑе \"%s\" обнаружен оÑтавшийÑÑ ÐºÐ¾Ñ€Ñ‚ÐµÐ¶-меÑтозаполнитель, он " "удалÑетÑÑ" -#: access/brin/brin_revmap.c:597 +#: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "неожиданный тип Ñтраницы 0x%04X в BRIN-индекÑе \"%s\" (блок: %u)" -#: access/brin/brin_validate.c:116 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format msgid "" -"brin operator family \"%s\" contains function %s with invalid support number " -"%d" +"operator family \"%s\" of access method %s contains function %s with invalid " +"support number %d" msgstr "" -"ÑемейÑтво операторов brin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ опорным " -"номером %d" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит функцию %s Ñ " +"неправильным опорным номером %d" -#: access/brin/brin_validate.c:132 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format msgid "" -"brin operator family \"%s\" contains function %s with wrong signature for " -"support number %d" +"operator family \"%s\" of access method %s contains function %s with wrong " +"signature for support number %d" msgstr "" -"ÑемейÑтво операторов brin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит функцию %s Ñ " +"неподходÑщим объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" -#: access/brin/brin_validate.c:154 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 #, c-format msgid "" -"brin operator family \"%s\" contains operator %s with invalid strategy " -"number %d" +"operator family \"%s\" of access method %s contains operator %s with invalid " +"strategy number %d" msgstr "" -"ÑемейÑтво операторов brin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ номером " -"Ñтратегии %d" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит оператор %s Ñ " +"неправильным номером Ñтратегии %d" -#: access/brin/brin_validate.c:183 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:209 #, c-format msgid "" -"brin operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" +"operator family \"%s\" of access method %s contains invalid ORDER BY " +"specification for operator %s" msgstr "" -"ÑемейÑтво операторов brin \"%s\" Ñодержит некорректное определение ORDER BY " -"Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит некорректное " +"определение ORDER BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" -#: access/brin/brin_validate.c:196 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 #, c-format -msgid "brin operator family \"%s\" contains operator %s with wrong signature" +msgid "" +"operator family \"%s\" of access method %s contains operator %s with wrong " +"signature" msgstr "" -"ÑемейÑтво операторов brin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит оператор %s Ñ " +"неподходÑщим объÑвлением" -#: access/brin/brin_validate.c:234 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 #, c-format -msgid "brin operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "в ÑемейÑтве операторов brin \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" +msgid "" +"operator family \"%s\" of access method %s is missing operator(s) for types " +"%s and %s" +msgstr "" +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² " +"%s и %s" #: access/brin/brin_validate.c:244 #, c-format msgid "" -"brin operator family \"%s\" is missing support function(s) for types %s and " -"%s" +"operator family \"%s\" of access method %s is missing support function(s) " +"for types %s and %s" msgstr "" -"в ÑемейÑтве операторов brin \"%s\" нет опорных функций Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s нет опорных функций Ð´Ð»Ñ " +"типов %s и %s" -#: access/brin/brin_validate.c:257 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 #, c-format -msgid "brin operator class \"%s\" is missing operator(s)" -msgstr "в клаÑÑе операторов brin \"%s\" нет оператора(ов)" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "в клаÑÑе операторов \"%s\" метода доÑтупа %s нет оператора(ов)" -#: access/brin/brin_validate.c:268 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -msgid "brin operator class \"%s\" is missing support function %d" -msgstr "в клаÑÑе операторов brin \"%s\" нет опорной функции %d" +msgid "" +"operator class \"%s\" of access method %s is missing support function %d" +msgstr "в клаÑÑе операторов \"%s\" метода доÑтупа %s нет опорной функции %d" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1407 +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "чиÑло Ñтолбцов (%d) превышает предел (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "чиÑло Ñтолбцов индекÑа (%d) превышает предел (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:647 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "Ñтрока индекÑа требует байт: %zu, при макÑимуме: %zu" -#: access/common/printtup.c:290 tcop/fastpath.c:182 tcop/fastpath.c:544 -#: tcop/postgres.c:1732 +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1778 #, c-format msgid "unsupported format code: %d" msgstr "неподдерживаемый код формата: %d" -#: access/common/reloptions.c:540 +#: access/common/reloptions.c:568 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "превышен предел пользовательÑких типов релÑционных параметров" -#: access/common/reloptions.c:821 +#: access/common/reloptions.c:849 #, c-format msgid "RESET must not include values for parameters" msgstr "Ð’ RESET не должно передаватьÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ параметров" -#: access/common/reloptions.c:854 +#: access/common/reloptions.c:881 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "нераÑпознанное проÑтранÑтво имён параметров \"%s\"" -#: access/common/reloptions.c:1094 parser/parse_clause.c:270 +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "нераÑпознанный параметр \"%s\"" -#: access/common/reloptions.c:1124 +#: access/common/reloptions.c:1151 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "параметр \"%s\" указан неоднократно" -#: access/common/reloptions.c:1140 +#: access/common/reloptions.c:1167 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "неверное значение Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого параметра \"%s\": %s" -#: access/common/reloptions.c:1152 +#: access/common/reloptions.c:1179 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "неверное значение Ð´Ð»Ñ Ñ†ÐµÐ»Ð¾Ñ‡Ð¸Ñленного параметра \"%s\": %s" -#: access/common/reloptions.c:1158 access/common/reloptions.c:1178 +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "значение %s вне допуÑтимых пределов параметра \"%s\"" -#: access/common/reloptions.c:1160 +#: access/common/reloptions.c:1187 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "ДопуÑкаютÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ от \"%d\" до \"%d\"." -#: access/common/reloptions.c:1172 +#: access/common/reloptions.c:1199 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "неверное значение Ð´Ð»Ñ Ñ‡Ð¸Ñленного параметра \"%s\": %s" -#: access/common/reloptions.c:1180 +#: access/common/reloptions.c:1207 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "ДопуÑкаютÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ от \"%f\" до \"%f\"." @@ -585,7 +648,7 @@ msgid "" msgstr "" "ЧиÑло возвращённых Ñтолбцов (%d) не ÑоответÑтвует ожидаемому чиÑлу (%d)." -#: access/common/tupconvert.c:316 +#: access/common/tupconvert.c:329 #, c-format msgid "" "Attribute \"%s\" of type %s does not match corresponding attribute of type " @@ -593,13 +656,13 @@ msgid "" msgstr "" "Ðтрибут \"%s\" типа %s неÑовмеÑтим Ñ ÑоответÑтвующим атрибутом типа %s." -#: access/common/tupconvert.c:328 +#: access/common/tupconvert.c:341 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "Ðтрибут \"%s\" типа %s не ÑущеÑтвует в типе %s." -#: access/common/tupdesc.c:722 parser/parse_clause.c:816 -#: parser/parse_relation.c:1543 +#: access/common/tupdesc.c:837 parser/parse_clause.c:819 +#: parser/parse_relation.c:1539 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "Ñтолбец \"%s\" не может быть объÑвлен как SETOF" @@ -614,124 +677,63 @@ msgstr "Ñлишком длинный ÑпиÑок указателей" msgid "Reduce maintenance_work_mem." msgstr "Уменьшите maintenance_work_mem." -#: access/gin/ginentrypage.c:110 access/gist/gist.c:1363 -#: access/nbtree/nbtinsert.c:577 access/nbtree/nbtsort.c:488 -#: access/spgist/spgdoinsert.c:1933 -#, c-format -msgid "index row size %zu exceeds maximum %zu for index \"%s\"" -msgstr "" -"размер Ñтроки индекÑа (%zu) больше предельного размера (%zu) (Ð¸Ð½Ð´ÐµÐºÑ \"%s\")" - -#: access/gin/ginfast.c:991 access/transam/xlog.c:10178 -#: access/transam/xlog.c:10695 access/transam/xlogfuncs.c:295 -#: access/transam/xlogfuncs.c:322 access/transam/xlogfuncs.c:361 -#: access/transam/xlogfuncs.c:382 access/transam/xlogfuncs.c:403 -#: access/transam/xlogfuncs.c:473 access/transam/xlogfuncs.c:529 -#, c-format -msgid "recovery is in progress" -msgstr "идёт процеÑÑ Ð²Ð¾ÑÑтановлениÑ" - -#: access/gin/ginfast.c:992 +#: access/gin/ginfast.c:1019 #, c-format msgid "GIN pending list cannot be cleaned up during recovery." msgstr "Очередь запиÑей GIN Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‡Ð¸Ñтить в процеÑÑе воÑÑтановлениÑ." -#: access/gin/ginfast.c:999 +#: access/gin/ginfast.c:1026 #, c-format msgid "\"%s\" is not a GIN index" msgstr "\"%s\" - Ñто не Ð¸Ð½Ð´ÐµÐºÑ GIN" -#: access/gin/ginfast.c:1010 +#: access/gin/ginfast.c:1037 #, c-format msgid "cannot access temporary indexes of other sessions" msgstr "обращатьÑÑ Ðº временным индекÑам других ÑеанÑов нельзÑ" -#: access/gin/ginscan.c:405 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "" "Ñтарые GIN-индекÑÑ‹ не поддерживают Ñканирование вÑего индекÑа и поиÑк NULL" -#: access/gin/ginscan.c:406 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "Ð”Ð»Ñ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚Ðµ REINDEX INDEX \"%s\"." -#: access/gin/ginutil.c:134 executor/execExpr.c:1759 -#: utils/adt/arrayfuncs.c:3803 utils/adt/arrayfuncs.c:6325 -#: utils/adt/rowtypes.c:927 +#: access/gin/ginutil.c:138 executor/execExpr.c:1868 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 +#: utils/adt/rowtypes.c:935 #, c-format msgid "could not identify a comparison function for type %s" msgstr "не удалоÑÑŒ найти функцию ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" -#: access/gin/ginvalidate.c:93 -#, c-format -msgid "" -"gin operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит опорную процедуру %s Ñ Ð¼ÐµÐ¶Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð¹ " -"региÑтрацией" - -#: access/gin/ginvalidate.c:149 -#, c-format -msgid "" -"gin operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ опорным " -"номером %d" - -#: access/gin/ginvalidate.c:161 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format msgid "" -"gin operator family \"%s\" contains function %s with wrong signature for " -"support number %d" +"operator family \"%s\" of access method %s contains support function %s with " +"different left and right input types" msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит опорную функцию %s Ñ " +"межтиповой региÑтрацией" -#: access/gin/ginvalidate.c:180 +#: access/gin/ginvalidate.c:257 #, c-format msgid "" -"gin operator family \"%s\" contains operator %s with invalid strategy number " +"operator class \"%s\" of access method %s is missing support function %d or " "%d" msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ номером " -"Ñтратегии %d" - -#: access/gin/ginvalidate.c:193 -#, c-format -msgid "" -"gin operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит некорректное определение ORDER BY " -"Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" - -#: access/gin/ginvalidate.c:206 -#, c-format -msgid "gin operator family \"%s\" contains operator %s with wrong signature" -msgstr "" -"ÑемейÑтво операторов gin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" - -#: access/gin/ginvalidate.c:247 -#, c-format -msgid "gin operator class \"%s\" is missing support function %d" -msgstr "в клаÑÑе операторов gin \"%s\" нет опорной функции %d" - -#: access/gin/ginvalidate.c:257 -#, c-format -msgid "gin operator class \"%s\" is missing support function %d or %d" -msgstr "в клаÑÑе операторов gin \"%s\" нет опорной функции %d или %d" +"в клаÑÑе операторов \"%s\" метода доÑтупа %s нет опорной функции %d или %d" -#: access/gist/gist.c:706 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:717 access/gist/gistvacuum.c:258 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ñодержит внутренний кортеж, отмеченный как ошибочный" -#: access/gist/gist.c:708 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:719 access/gist/gistvacuum.c:260 #, c-format msgid "" "This is caused by an incomplete page split at crash recovery before " @@ -740,26 +742,26 @@ msgstr "" "Это вызвано неполным разделением Ñтраницы при воÑÑтановлении поÑле ÑÐ±Ð¾Ñ Ð² " "PostgreSQL до верÑии 9.1." -#: access/gist/gist.c:709 access/gist/gistutil.c:739 access/gist/gistutil.c:750 -#: access/gist/gistvacuum.c:261 access/hash/hashutil.c:240 -#: access/hash/hashutil.c:251 access/hash/hashutil.c:263 -#: access/hash/hashutil.c:284 access/nbtree/nbtpage.c:519 -#: access/nbtree/nbtpage.c:530 +#: access/gist/gist.c:720 access/gist/gistutil.c:759 +#: access/gist/gistutil.c:770 access/gist/gistvacuum.c:261 +#: access/hash/hashutil.c:241 access/hash/hashutil.c:252 +#: access/hash/hashutil.c:264 access/hash/hashutil.c:285 +#: access/nbtree/nbtpage.c:678 access/nbtree/nbtpage.c:689 #, c-format msgid "Please REINDEX it." msgstr "ПожалуйÑта, выполните REINDEX Ð´Ð»Ñ Ð½ÐµÐ³Ð¾." -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:252 #, c-format msgid "invalid value for \"buffering\" option" msgstr "неверное значение Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"buffering\"" -#: access/gist/gistbuild.c:251 +#: access/gist/gistbuild.c:253 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "ДопуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"on\", \"off\" и \"auto\"." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:231 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "не удалоÑÑŒ запиÑать блок %ld временного файла: %m" @@ -779,91 +781,43 @@ msgstr "" "разработчиками или попробуйте указать Ñтот Ñтолбец в команде CREATE INDEX " "вторым." -#: access/gist/gistutil.c:736 access/hash/hashutil.c:237 -#: access/nbtree/nbtpage.c:516 +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:675 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "в индекÑе \"%s\" неожиданно оказалаÑÑŒ Ð½ÑƒÐ»ÐµÐ²Ð°Ñ Ñтраница в блоке %u" -#: access/gist/gistutil.c:747 access/hash/hashutil.c:248 -#: access/hash/hashutil.c:260 access/nbtree/nbtpage.c:527 +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ñодержит иÑпорченную Ñтраницу в блоке %u" -#: access/gist/gistvalidate.c:93 -#, c-format -msgid "" -"gist operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит опорную процедуру %s Ñ Ð¼ÐµÐ¶Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð¹ " -"региÑтрацией" - -#: access/gist/gistvalidate.c:146 -#, c-format -msgid "" -"gist operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ опорным " -"номером %d" - -#: access/gist/gistvalidate.c:158 -#, c-format -msgid "" -"gist operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" - -#: access/gist/gistvalidate.c:178 -#, c-format -msgid "" -"gist operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ номером " -"Ñтратегии %d" - #: access/gist/gistvalidate.c:196 #, c-format msgid "" -"gist operator family \"%s\" contains unsupported ORDER BY specification for " -"operator %s" +"operator family \"%s\" of access method %s contains unsupported ORDER BY " +"specification for operator %s" msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит неподдерживаемое определение ORDER " -"BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит неподдерживаемое " +"определение ORDER BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" #: access/gist/gistvalidate.c:207 #, c-format msgid "" -"gist operator family \"%s\" contains incorrect ORDER BY opfamily " -"specification for operator %s" -msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит некорректное определение ORDER BY " -"Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" - -#: access/gist/gistvalidate.c:226 -#, c-format -msgid "gist operator family \"%s\" contains operator %s with wrong signature" +"operator family \"%s\" of access method %s contains incorrect ORDER BY " +"opfamily specification for operator %s" msgstr "" -"ÑемейÑтво операторов gist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" - -#: access/gist/gistvalidate.c:265 -#, c-format -msgid "gist operator class \"%s\" is missing support function %d" -msgstr "в клаÑÑе операторов gist \"%s\" нет опорной функции %d" +"ÑемейÑтво операторов \"%s\" метода доÑтупа %s Ñодержит некорректное " +"определение ORDER BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" -#: access/hash/hashinsert.c:82 +#: access/hash/hashinsert.c:83 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "размер Ñтроки индекÑа (%zu) больше предельного размера хеша (%zu)" -#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1937 -#: access/spgist/spgutils.c:708 +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:746 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "ЗначениÑ, не умещающиеÑÑ Ð² Ñтраницу буфера, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¾Ð¸Ð½Ð´ÐµÐºÑировать." @@ -873,231 +827,174 @@ msgstr "ЗначениÑ, не умещающиеÑÑ Ð² Ñтраницу буф msgid "invalid overflow block number %u" msgstr "неверный номер блока переполнениÑ: %u" -#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "в хеш-индекÑе \"%s\" не хватает Ñтраниц переполнениÑ" -#: access/hash/hashsearch.c:250 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "хеш-индекÑÑ‹ не поддерживают Ñканирование вÑего индекÑа" -#: access/hash/hashutil.c:276 +#: access/hash/hashutil.c:277 #, c-format msgid "index \"%s\" is not a hash index" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не ÑвлÑетÑÑ Ñ…ÐµÑˆ-индекÑом" -#: access/hash/hashutil.c:282 +#: access/hash/hashutil.c:283 #, c-format msgid "index \"%s\" has wrong hash version" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" имеет неправильную верÑию хеша" -#: access/hash/hashvalidate.c:99 -#, c-format -msgid "" -"hash operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит опорную процедуру %s Ñ Ð¼ÐµÐ¶Ñ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð¹ " -"региÑтрацией" - -#: access/hash/hashvalidate.c:114 -#, c-format -msgid "" -"hash operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" - -#: access/hash/hashvalidate.c:131 -#, c-format -msgid "" -"hash operator family \"%s\" contains function %s with invalid support number " -"%d" -msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ опорным " -"номером %d" - -#: access/hash/hashvalidate.c:152 -#, c-format -msgid "" -"hash operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ номером " -"Ñтратегии %d" - -#: access/hash/hashvalidate.c:165 +#: access/hash/hashvalidate.c:191 #, c-format msgid "" -"hash operator family \"%s\" contains invalid ORDER BY specification for " +"operator family \"%s\" of access method %s lacks support function for " "operator %s" msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит некорректное определение ORDER BY " +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s не хватает опорной функции " "Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" -#: access/hash/hashvalidate.c:178 -#, c-format -msgid "hash operator family \"%s\" contains operator %s with wrong signature" -msgstr "" -"ÑемейÑтво операторов hash \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" - -#: access/hash/hashvalidate.c:190 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "hash operator family \"%s\" lacks support function for operator %s" +msgid "" +"operator family \"%s\" of access method %s is missing cross-type operator(s)" msgstr "" -"в ÑемейÑтве операторов hash \"%s\" не хватает опорной функции Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° " -"%s" - -#: access/hash/hashvalidate.c:218 -#, c-format -msgid "hash operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "в ÑемейÑтве операторов hash \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s нет межтипового оператора(ов)" -#: access/hash/hashvalidate.c:232 -#, c-format -msgid "hash operator class \"%s\" is missing operator(s)" -msgstr "в клаÑÑе операторов hash \"%s\" нет оператора(ов)" - -#: access/hash/hashvalidate.c:248 -#, c-format -msgid "hash operator family \"%s\" is missing cross-type operator(s)" -msgstr "в ÑемейÑтве операторов hash \"%s\" нет межтипового оператора(ов)" - -#: access/heap/heapam.c:1293 access/heap/heapam.c:1321 -#: access/heap/heapam.c:1353 catalog/aclchk.c:1772 +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 +#: access/heap/heapam.c:1366 catalog/aclchk.c:1828 #, c-format msgid "\"%s\" is an index" msgstr "\"%s\" - Ñто индекÑ" -#: access/heap/heapam.c:1298 access/heap/heapam.c:1326 -#: access/heap/heapam.c:1358 catalog/aclchk.c:1779 commands/tablecmds.c:9557 -#: commands/tablecmds.c:12768 +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 +#: access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10846 +#: commands/tablecmds.c:14131 #, c-format msgid "\"%s\" is a composite type" msgstr "\"%s\" - Ñто ÑоÑтавной тип" -#: access/heap/heapam.c:2592 +#: access/heap/heapam.c:2645 #, c-format -msgid "cannot insert tuples during a parallel operation" -msgstr "вÑтавлÑть кортежи во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" +msgid "cannot insert tuples in a parallel worker" +msgstr "вÑтавлÑть кортежи в параллельном иÑполнителе нельзÑ" -#: access/heap/heapam.c:3042 +#: access/heap/heapam.c:3092 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "удалÑть кортежи во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/heap/heapam.c:3088 +#: access/heap/heapam.c:3138 #, c-format msgid "attempted to delete invisible tuple" msgstr "попытка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼Ð¾Ð³Ð¾ кортежа" -#: access/heap/heapam.c:3514 access/heap/heapam.c:6213 +#: access/heap/heapam.c:3572 access/heap/heapam.c:6409 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "изменÑть кортежи во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/heap/heapam.c:3661 +#: access/heap/heapam.c:3720 #, c-format msgid "attempted to update invisible tuple" msgstr "попытка Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼Ð¾Ð³Ð¾ кортежа" -#: access/heap/heapam.c:4936 access/heap/heapam.c:4974 -#: access/heap/heapam.c:5226 executor/execMain.c:2497 +#: access/heap/heapam.c:5085 access/heap/heapam.c:5123 +#: access/heap/heapam.c:5375 executor/execMain.c:2662 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "не удалоÑÑŒ получить блокировку Ñтроки в таблице \"%s\"" -#: access/heap/hio.c:322 access/heap/rewriteheap.c:666 +#: access/heap/hio.c:338 access/heap/rewriteheap.c:682 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "размер Ñтроки (%zu) превышает предел (%zu)" -#: access/heap/rewriteheap.c:926 +#: access/heap/rewriteheap.c:942 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "не удалоÑÑŒ запиÑать в файл \"%s\" (запиÑано байт: %d из %d): %m" -#: access/heap/rewriteheap.c:966 access/heap/rewriteheap.c:1183 -#: access/heap/rewriteheap.c:1282 access/transam/timeline.c:412 -#: access/transam/timeline.c:492 access/transam/xlog.c:3246 -#: access/transam/xlog.c:3414 replication/logical/snapbuild.c:1626 -#: replication/slot.c:1219 replication/slot.c:1306 storage/file/fd.c:631 -#: storage/file/fd.c:3180 storage/smgr/md.c:1044 storage/smgr/md.c:1277 -#: storage/smgr/md.c:1450 utils/misc/guc.c:6967 +#: access/heap/rewriteheap.c:982 access/heap/rewriteheap.c:1203 +#: access/heap/rewriteheap.c:1302 access/transam/timeline.c:411 +#: access/transam/timeline.c:490 access/transam/xlog.c:3307 +#: access/transam/xlog.c:3473 replication/logical/snapbuild.c:1652 +#: replication/slot.c:1313 replication/slot.c:1405 storage/file/fd.c:658 +#: storage/file/fd.c:3552 storage/smgr/md.c:1044 storage/smgr/md.c:1289 +#: storage/smgr/md.c:1463 utils/misc/guc.c:7270 #, c-format msgid "could not fsync file \"%s\": %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл \"%s\": %m" -#: access/heap/rewriteheap.c:1021 access/heap/rewriteheap.c:1141 -#: access/transam/timeline.c:315 access/transam/timeline.c:467 -#: access/transam/xlog.c:3199 access/transam/xlog.c:3352 -#: access/transam/xlog.c:10512 access/transam/xlog.c:10550 -#: access/transam/xlog.c:10935 postmaster/postmaster.c:4410 -#: replication/logical/origin.c:535 replication/slot.c:1171 -#: storage/file/copydir.c:162 storage/smgr/md.c:327 utils/time/snapmgr.c:1275 +#: access/heap/rewriteheap.c:1036 access/heap/rewriteheap.c:1155 +#: access/transam/timeline.c:314 access/transam/timeline.c:465 +#: access/transam/xlog.c:3261 access/transam/xlog.c:3411 +#: access/transam/xlog.c:10692 access/transam/xlog.c:10730 +#: access/transam/xlog.c:11133 postmaster/postmaster.c:4451 +#: replication/logical/origin.c:575 replication/slot.c:1262 +#: storage/file/copydir.c:167 storage/smgr/md.c:327 utils/time/snapmgr.c:1297 #, c-format msgid "could not create file \"%s\": %m" msgstr "Ñоздать файл \"%s\" не удалоÑÑŒ: %m" -#: access/heap/rewriteheap.c:1151 +#: access/heap/rewriteheap.c:1165 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "не удалоÑÑŒ обрезать файл \"%s\" до нужного размера (%u): %m" -#: access/heap/rewriteheap.c:1159 replication/walsender.c:478 -#: storage/smgr/md.c:1949 +#: access/heap/rewriteheap.c:1173 replication/walsender.c:490 +#: storage/smgr/md.c:1993 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "не удалоÑÑŒ перейти к концу файла \"%s\": %m" -#: access/heap/rewriteheap.c:1171 access/transam/timeline.c:370 -#: access/transam/timeline.c:405 access/transam/timeline.c:484 -#: access/transam/xlog.c:3235 access/transam/xlog.c:3405 -#: postmaster/postmaster.c:4420 postmaster/postmaster.c:4430 -#: replication/logical/origin.c:544 replication/logical/origin.c:580 -#: replication/logical/origin.c:596 replication/logical/snapbuild.c:1608 -#: replication/slot.c:1202 storage/file/copydir.c:191 -#: utils/init/miscinit.c:1240 utils/init/miscinit.c:1251 -#: utils/init/miscinit.c:1259 utils/misc/guc.c:6928 utils/misc/guc.c:6959 -#: utils/misc/guc.c:8811 utils/misc/guc.c:8825 utils/time/snapmgr.c:1280 -#: utils/time/snapmgr.c:1287 +#: access/heap/rewriteheap.c:1190 access/transam/timeline.c:369 +#: access/transam/timeline.c:404 access/transam/timeline.c:482 +#: access/transam/xlog.c:3293 access/transam/xlog.c:3464 +#: postmaster/postmaster.c:4461 postmaster/postmaster.c:4471 +#: replication/logical/origin.c:590 replication/logical/origin.c:635 +#: replication/logical/origin.c:657 replication/logical/snapbuild.c:1628 +#: replication/slot.c:1296 storage/file/copydir.c:208 +#: utils/init/miscinit.c:1345 utils/init/miscinit.c:1356 +#: utils/init/miscinit.c:1364 utils/misc/guc.c:7231 utils/misc/guc.c:7262 +#: utils/misc/guc.c:9124 utils/misc/guc.c:9138 utils/time/snapmgr.c:1302 +#: utils/time/snapmgr.c:1309 #, c-format msgid "could not write to file \"%s\": %m" msgstr "запиÑать в файл \"%s\" не удалоÑÑŒ: %m" -#: access/heap/rewriteheap.c:1257 access/transam/xlogarchive.c:113 -#: access/transam/xlogarchive.c:467 postmaster/postmaster.c:1239 -#: postmaster/syslogger.c:1371 replication/logical/origin.c:522 -#: replication/logical/reorderbuffer.c:2595 -#: replication/logical/reorderbuffer.c:2652 -#: replication/logical/snapbuild.c:1551 replication/logical/snapbuild.c:1938 -#: replication/slot.c:1279 storage/file/fd.c:682 storage/ipc/dsm.c:327 -#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1397 +#: access/heap/rewriteheap.c:1277 access/transam/xlogarchive.c:112 +#: access/transam/xlogarchive.c:459 postmaster/postmaster.c:1276 +#: postmaster/syslogger.c:1459 replication/logical/origin.c:563 +#: replication/logical/reorderbuffer.c:2814 +#: replication/logical/snapbuild.c:1570 replication/logical/snapbuild.c:1972 +#: replication/slot.c:1375 storage/file/fd.c:709 storage/file/fd.c:3152 +#: storage/file/fd.c:3214 storage/file/reinit.c:255 storage/ipc/dsm.c:315 +#: storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1410 +#: utils/time/snapmgr.c:1640 #, c-format msgid "could not remove file \"%s\": %m" msgstr "не удалоÑÑŒ Ñтереть файл \"%s\": %m" -#: access/heap/rewriteheap.c:1271 access/transam/timeline.c:111 -#: access/transam/timeline.c:236 access/transam/timeline.c:334 -#: access/transam/xlog.c:3175 access/transam/xlog.c:3296 -#: access/transam/xlog.c:3337 access/transam/xlog.c:3616 -#: access/transam/xlog.c:3694 access/transam/xlogutils.c:706 -#: postmaster/syslogger.c:1380 replication/basebackup.c:474 -#: replication/basebackup.c:1218 replication/logical/origin.c:651 -#: replication/logical/reorderbuffer.c:2113 -#: replication/logical/reorderbuffer.c:2361 -#: replication/logical/reorderbuffer.c:3044 -#: replication/logical/snapbuild.c:1600 replication/logical/snapbuild.c:1688 -#: replication/slot.c:1294 replication/walsender.c:471 -#: replication/walsender.c:2314 storage/file/copydir.c:155 -#: storage/file/fd.c:614 storage/file/fd.c:3092 storage/file/fd.c:3159 -#: storage/smgr/md.c:608 utils/error/elog.c:1879 utils/init/miscinit.c:1171 -#: utils/init/miscinit.c:1299 utils/init/miscinit.c:1376 utils/misc/guc.c:7187 -#: utils/misc/guc.c:7220 +#: access/heap/rewriteheap.c:1291 access/transam/timeline.c:111 +#: access/transam/timeline.c:236 access/transam/timeline.c:333 +#: access/transam/xlog.c:3238 access/transam/xlog.c:3356 +#: access/transam/xlog.c:3397 access/transam/xlog.c:3674 +#: access/transam/xlog.c:3752 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1482 replication/basebackup.c:517 +#: replication/basebackup.c:1391 replication/logical/origin.c:712 +#: replication/logical/reorderbuffer.c:2308 +#: replication/logical/reorderbuffer.c:2575 +#: replication/logical/reorderbuffer.c:3288 +#: replication/logical/snapbuild.c:1614 replication/logical/snapbuild.c:1714 +#: replication/slot.c:1390 replication/walsender.c:483 +#: replication/walsender.c:2415 storage/file/copydir.c:161 +#: storage/file/fd.c:641 storage/file/fd.c:3447 storage/file/fd.c:3531 +#: storage/smgr/md.c:608 utils/error/elog.c:1872 utils/init/miscinit.c:1269 +#: utils/init/miscinit.c:1404 utils/init/miscinit.c:1481 utils/misc/guc.c:7490 +#: utils/misc/guc.c:7522 #, c-format msgid "could not open file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл \"%s\": %m" @@ -1113,63 +1010,66 @@ msgid "index access method \"%s\" does not have a handler" msgstr "Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа индекÑа \"%s\" не задан обработчик" #: access/index/indexam.c:160 catalog/objectaddress.c:1223 -#: commands/indexcmds.c:1806 commands/tablecmds.c:247 -#: commands/tablecmds.c:12759 +#: commands/indexcmds.c:2293 commands/tablecmds.c:249 commands/tablecmds.c:273 +#: commands/tablecmds.c:14122 commands/tablecmds.c:15413 #, c-format msgid "\"%s\" is not an index" msgstr "\"%s\" - Ñто не индекÑ" -#: access/nbtree/nbtinsert.c:429 +#: access/nbtree/nbtinsert.c:530 #, c-format msgid "duplicate key value violates unique constraint \"%s\"" msgstr "повторÑющееÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ ключа нарушает ограничение уникальноÑти \"%s\"" -#: access/nbtree/nbtinsert.c:431 +#: access/nbtree/nbtinsert.c:532 #, c-format msgid "Key %s already exists." msgstr "Ключ \"%s\" уже ÑущеÑтвует." -#: access/nbtree/nbtinsert.c:498 +#: access/nbtree/nbtinsert.c:599 #, c-format msgid "failed to re-find tuple within index \"%s\"" msgstr "не удалоÑÑŒ повторно найти кортеж в индекÑе \"%s\"" -#: access/nbtree/nbtinsert.c:500 +#: access/nbtree/nbtinsert.c:601 #, c-format msgid "This may be because of a non-immutable index expression." msgstr "Возможно, Ñто вызвано переменной природой индекÑного выражениÑ." -#: access/nbtree/nbtinsert.c:580 access/nbtree/nbtsort.c:491 +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 #, c-format msgid "" "Values larger than 1/3 of a buffer page cannot be indexed.\n" "Consider a function index of an MD5 hash of the value, or use full text " "indexing." msgstr "" -"ЗначениÑ, занимающие больше 1/3 Ñтраницы буфера, не могут быть " -"индекÑированы.\n" +"ЗначениÑ, занимающие больше 1/3 Ñтраницы буфера, не могут быть индекÑированы." +"\n" "Возможно, вам Ñтоит применить Ð¸Ð½Ð´ÐµÐºÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ Ñ MD5-хешем Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ " "полнотекÑтовую индекÑацию." -#: access/nbtree/nbtpage.c:169 access/nbtree/nbtpage.c:372 -#: access/nbtree/nbtpage.c:459 parser/parse_utilcmd.c:1770 +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 +#: access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2054 #, c-format msgid "index \"%s\" is not a btree" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не ÑвлÑетÑÑ b-деревом" -#: access/nbtree/nbtpage.c:175 access/nbtree/nbtpage.c:378 -#: access/nbtree/nbtpage.c:465 +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 +#: access/nbtree/nbtpage.c:625 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" +msgid "" +"version mismatch in index \"%s\": file version %d, current version %d, " +"minimal supported version %d" msgstr "" -"неÑовпадение верÑии в индекÑе \"%s\": верÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð°: %d, верÑÐ¸Ñ ÐºÐ¾Ð´Ð°: %d" +"неÑовпадение верÑии в индекÑе \"%s\": верÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð°: %d, верÑÐ¸Ñ ÐºÐ¾Ð´Ð°: %d, " +"Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑиÑ: %d" -#: access/nbtree/nbtpage.c:1153 +#: access/nbtree/nbtpage.c:1320 #, c-format msgid "index \"%s\" contains a half-dead internal page" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ñодержит полумёртвую внутреннюю Ñтраницу" -#: access/nbtree/nbtpage.c:1155 +#: access/nbtree/nbtpage.c:1322 #, c-format msgid "" "This can be caused by an interrupted VACUUM in version 9.3 or older, before " @@ -1178,148 +1078,36 @@ msgstr "" "Причиной тому могло быть прерывание операции VACUUM в верÑии 9.3 или Ñтарее, " "до обновлениÑ. Этот Ð¸Ð½Ð´ÐµÐºÑ Ð½ÑƒÐ¶Ð½Ð¾ переÑтроить (REINDEX)." -#: access/nbtree/nbtvalidate.c:101 -#, c-format -msgid "" -"btree operator family \"%s\" contains function %s with invalid support " -"number %d" -msgstr "" -"ÑемейÑтво операторов btree \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ опорным " -"номером %d" - -#: access/nbtree/nbtvalidate.c:113 -#, c-format -msgid "" -"btree operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"ÑемейÑтво операторов btree \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" - -#: access/nbtree/nbtvalidate.c:133 -#, c-format -msgid "" -"btree operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"ÑемейÑтво операторов btree \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " -"номером Ñтратегии %d" - -#: access/nbtree/nbtvalidate.c:146 +#: access/nbtree/nbtvalidate.c:236 #, c-format msgid "" -"btree operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"ÑемейÑтво операторов btree \"%s\" Ñодержит некорректное определение ORDER BY " -"Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" - -#: access/nbtree/nbtvalidate.c:159 -#, c-format -msgid "btree operator family \"%s\" contains operator %s with wrong signature" +"operator family \"%s\" of access method %s is missing support function for " +"types %s and %s" msgstr "" -"ÑемейÑтво операторов btree \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s нет опорной функции Ð´Ð»Ñ " +"типов %s и %s" -#: access/nbtree/nbtvalidate.c:201 -#, c-format -msgid "btree operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "" -"в ÑемейÑтве операторов btree \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" - -#: access/nbtree/nbtvalidate.c:211 +#: access/spgist/spgutils.c:136 #, c-format msgid "" -"btree operator family \"%s\" is missing support function for types %s and %s" +"compress method must be defined when leaf type is different from input type" msgstr "" -"в ÑемейÑтве операторов btree \"%s\" нет опорных функций Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" - -#: access/nbtree/nbtvalidate.c:225 -#, c-format -msgid "btree operator class \"%s\" is missing operator(s)" -msgstr "в клаÑÑе операторов btree \"%s\" нет оператора(ов)" - -#: access/nbtree/nbtvalidate.c:242 -#, c-format -msgid "btree operator family \"%s\" is missing cross-type operator(s)" -msgstr "в ÑемейÑтве операторов btree \"%s\" нет межтипового оператора(ов)" +"метод ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть определён, когда тип лиÑтьев отличаетÑÑ Ð¾Ñ‚ входного " +"типа" -#: access/spgist/spgutils.c:705 +#: access/spgist/spgutils.c:743 #, c-format msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" msgstr "внутренний размер кортежа SP-GiST (%zu) превышает макÑимум (%zu)" -#: access/spgist/spgvalidate.c:93 -#, c-format -msgid "" -"spgist operator family \"%s\" contains support procedure %s with cross-type " -"registration" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит опорную процедуру %s Ñ " -"межтиповой региÑтрацией" - -#: access/spgist/spgvalidate.c:116 -#, c-format -msgid "" -"spgist operator family \"%s\" contains function %s with invalid support " -"number %d" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " -"опорным номером %d" - -#: access/spgist/spgvalidate.c:128 -#, c-format -msgid "" -"spgist operator family \"%s\" contains function %s with wrong signature for " -"support number %d" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" - -#: access/spgist/spgvalidate.c:147 -#, c-format -msgid "" -"spgist operator family \"%s\" contains operator %s with invalid strategy " -"number %d" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " -"номером Ñтратегии %d" - -#: access/spgist/spgvalidate.c:160 -#, c-format -msgid "" -"spgist operator family \"%s\" contains invalid ORDER BY specification for " -"operator %s" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит некорректное определение ORDER " -"BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" - -#: access/spgist/spgvalidate.c:173 -#, c-format -msgid "spgist operator family \"%s\" contains operator %s with wrong signature" -msgstr "" -"ÑемейÑтво операторов spgist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " -"объÑвлением" - -#: access/spgist/spgvalidate.c:201 -#, c-format -msgid "" -"spgist operator family \"%s\" is missing operator(s) for types %s and %s" -msgstr "" -"в ÑемейÑтве операторов spgist \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" - -#: access/spgist/spgvalidate.c:221 +#: access/spgist/spgvalidate.c:269 #, c-format msgid "" -"spgist operator family \"%s\" is missing support function %d for type %s" +"operator family \"%s\" of access method %s is missing support function %d " +"for type %s" msgstr "" -"в ÑемейÑтве операторов spgist \"%s\" отÑутÑтвует Ð¾Ð¿Ð¾Ñ€Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° " -"%s" - -#: access/spgist/spgvalidate.c:234 -#, c-format -msgid "spgist operator class \"%s\" is missing operator(s)" -msgstr "в клаÑÑе операторов spgist \"%s\" нет оператора(ов)" +"в ÑемейÑтве операторов \"%s\" метода доÑтупа %s нет опорной функции %d Ð´Ð»Ñ " +"типа %s" #: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 #, c-format @@ -1355,18 +1143,19 @@ msgid "" "wraparound data loss in database \"%s\"" msgstr "" "база данных не принимает команды, Ñоздающие новые MultiXactId, во избежание " -"потери данных из-за Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² базе данных \"%s\"" +"потери данных из-за Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ð² базе данных \"%s\"" #: access/transam/multixact.c:1002 access/transam/multixact.c:1009 #: access/transam/multixact.c:1033 access/transam/multixact.c:1042 #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." msgstr "" "Выполните очиÑтку (VACUUM) вÑей базы данных.\n" -"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые\n" -"подготовленные транзакции." +"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые " +"подготовленные транзакции и удалить неиÑпользуемые Ñлоты репликации." #: access/transam/multixact.c:1007 #, c-format @@ -1375,7 +1164,7 @@ msgid "" "wraparound data loss in database with OID %u" msgstr "" "база данных не принимает команды, Ñоздающие новые MultiXactId, во избежание " -"потери данных из-за Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð² базе данных Ñ OID %u" +"потери данных из-за Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ð² базе данных Ñ OID %u" #: access/transam/multixact.c:1028 access/transam/multixact.c:2318 #, c-format @@ -1471,19 +1260,19 @@ msgstr "" #: access/transam/multixact.c:1277 #, c-format msgid "MultiXactId %u does no longer exist -- apparent wraparound" -msgstr "MultiXactId %u прекратил ÑущеÑтвование: видимо, произошло наложение" +msgstr "MultiXactId %u прекратил ÑущеÑтвование: видимо, произошло зацикливание" #: access/transam/multixact.c:1285 #, c-format msgid "MultiXactId %u has not been created yet -- apparent wraparound" -msgstr "MultiXactId %u ещё не был Ñоздан: видимо, произошло наложение" +msgstr "MultiXactId %u ещё не был Ñоздан: видимо, произошло зацикливание" #: access/transam/multixact.c:2268 #, c-format msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "" -"предел Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ MultiXactId равен %u, иÑточник Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ - база данных Ñ " -"OID %u" +"предел Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ MultiXactId равен %u, иÑточник Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ - база данных " +"Ñ OID %u" #: access/transam/multixact.c:2323 access/transam/multixact.c:2332 #: access/transam/varsup.c:146 access/transam/varsup.c:153 @@ -1492,11 +1281,12 @@ msgstr "" msgid "" "To avoid a database shutdown, execute a database-wide VACUUM in that " "database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." msgstr "" "Во избежание Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ñ‹ данных выполните очиÑтку (VACUUM) вÑей базы.\n" -"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые\n" -"подготовленные транзакции." +"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые " +"подготовленные транзакции и удалить неиÑпользуемые Ñлоты репликации." #: access/transam/multixact.c:2602 #, c-format @@ -1509,13 +1299,13 @@ msgid "" "MultiXact member wraparound protections are disabled because oldest " "checkpointed MultiXact %u does not exist on disk" msgstr "" -"Защита от Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ‡Ð»ÐµÐ½Ð¾Ð² мультитранзакций отключена, так как ÑÑ‚Ð°Ñ€ÐµÐ¹ÑˆÐ°Ñ " +"Защита от Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‡Ð»ÐµÐ½Ð¾Ð² мультитранзакций отключена, так как ÑÑ‚Ð°Ñ€ÐµÐ¹ÑˆÐ°Ñ " "Ð¾Ñ‚Ð¼ÐµÑ‡ÐµÐ½Ð½Ð°Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %u не найдена на диÑке" #: access/transam/multixact.c:2628 #, c-format msgid "MultiXact member wraparound protections are now enabled" -msgstr "Защита от Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ ÑÐµÐ¹Ñ‡Ð°Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°" +msgstr "Защита от Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ ÑÐµÐ¹Ñ‡Ð°Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð°" #: access/transam/multixact.c:2631 #, c-format @@ -1546,78 +1336,88 @@ msgstr "" msgid "invalid MultiXactId: %u" msgstr "неверный MultiXactId: %u" -#: access/transam/parallel.c:592 +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "не удалоÑÑŒ инициализировать параллельный иÑполнитель" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть в журнале Ñервера." + +#: access/transam/parallel.c:849 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "postmaster завершилÑÑ Ð² процеÑÑе параллельной транзакции" -#: access/transam/parallel.c:777 +#: access/transam/parallel.c:1036 #, c-format msgid "lost connection to parallel worker" msgstr "потерÑно подключение к параллельному иÑполнителю" -#: access/transam/parallel.c:836 access/transam/parallel.c:838 +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 msgid "parallel worker" msgstr "параллельный иÑполнитель" -#: access/transam/parallel.c:977 +#: access/transam/parallel.c:1249 #, c-format msgid "could not map dynamic shared memory segment" msgstr "не удалоÑÑŒ отобразить динамичеÑкий Ñегмент разделÑемой памÑти" -#: access/transam/parallel.c:982 +#: access/transam/parallel.c:1254 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "неверное магичеÑкое чиÑло в динамичеÑком Ñегменте разделÑемой памÑти" -#: access/transam/slru.c:664 +#: access/transam/slru.c:668 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "файл \"%s\" не ÑущеÑтвует, ÑчитаетÑÑ Ð½ÑƒÐ»ÐµÐ²Ñ‹Ð¼" -#: access/transam/slru.c:903 access/transam/slru.c:909 -#: access/transam/slru.c:916 access/transam/slru.c:923 -#: access/transam/slru.c:930 access/transam/slru.c:937 +#: access/transam/slru.c:906 access/transam/slru.c:912 +#: access/transam/slru.c:919 access/transam/slru.c:926 +#: access/transam/slru.c:933 access/transam/slru.c:940 #, c-format msgid "could not access status of transaction %u" msgstr "не удалоÑÑŒ получить ÑоÑтоÑние транзакции %u" -#: access/transam/slru.c:904 +#: access/transam/slru.c:907 #, c-format msgid "Could not open file \"%s\": %m." msgstr "Ðе удалоÑÑŒ открыть файл \"%s\": %m." -#: access/transam/slru.c:910 +#: access/transam/slru.c:913 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "Ðе удалоÑÑŒ перемеÑтитьÑÑ Ð² файле \"%s\" к Ñмещению %u: %m." -#: access/transam/slru.c:917 +#: access/transam/slru.c:920 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "Ðе удалоÑÑŒ прочитать файл \"%s\" (по Ñмещению %u): %m." -#: access/transam/slru.c:924 +#: access/transam/slru.c:927 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "Ðе удалоÑÑŒ запиÑать в файл \"%s\" (по Ñмещению %u): %m." -#: access/transam/slru.c:931 +#: access/transam/slru.c:934 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "Ðе удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл \"%s\": %m." -#: access/transam/slru.c:938 +#: access/transam/slru.c:941 #, c-format msgid "Could not close file \"%s\": %m." msgstr "Ðе удалоÑÑŒ закрыть файл \"%s\": %m." -#: access/transam/slru.c:1195 +#: access/transam/slru.c:1198 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" -msgstr "не удалоÑÑŒ очиÑтить каталог \"%s\": видимо, произошло наложение" +msgstr "не удалоÑÑŒ очиÑтить каталог \"%s\": видимо, произошло зацикливание" -#: access/transam/slru.c:1250 access/transam/slru.c:1306 +#: access/transam/slru.c:1253 access/transam/slru.c:1309 #, c-format msgid "removing file \"%s\"" msgstr "удалÑетÑÑ Ñ„Ð°Ð¹Ð» \"%s\"" @@ -1634,8 +1434,8 @@ msgstr "ОжидаетÑÑ Ñ‡Ð¸Ñловой идентификатор лини #: access/transam/timeline.c:154 #, c-format -msgid "Expected a transaction log switchpoint location." -msgstr "ОжидаетÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ точки Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° транзакций." +msgid "Expected a write-ahead log switchpoint location." +msgstr "ОжидаетÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ точки Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° предзапиÑи." #: access/transam/timeline.c:158 #, c-format @@ -1658,72 +1458,72 @@ msgid "Timeline IDs must be less than child timeline's ID." msgstr "" "Идентификаторы линий времени должны быть меньше идентификатора линии-потомка." -#: access/transam/timeline.c:418 access/transam/timeline.c:498 -#: access/transam/xlog.c:3253 access/transam/xlog.c:3420 -#: access/transam/xlogfuncs.c:692 commands/copy.c:1751 -#: storage/file/copydir.c:206 +#: access/transam/timeline.c:417 access/transam/timeline.c:496 +#: access/transam/xlog.c:3314 access/transam/xlog.c:3479 +#: access/transam/xlogfuncs.c:683 commands/copy.c:1760 +#: storage/file/copydir.c:219 #, c-format msgid "could not close file \"%s\": %m" msgstr "не удалоÑÑŒ закрыть файл \"%s\": %m" -#: access/transam/timeline.c:580 +#: access/transam/timeline.c:578 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "в иÑтории Ñервера нет запрошенной линии времени %u" -#: access/transam/twophase.c:362 +#: access/transam/twophase.c:381 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "идентификатор транзакции \"%s\" Ñлишком длинный" -#: access/transam/twophase.c:369 +#: access/transam/twophase.c:388 #, c-format msgid "prepared transactions are disabled" msgstr "подготовленные транзакции отключены" -#: access/transam/twophase.c:370 +#: access/transam/twophase.c:389 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "УÑтановите ненулевое значение параметра max_prepared_transactions." -#: access/transam/twophase.c:389 +#: access/transam/twophase.c:408 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "идентификатор транзакции \"%s\" уже иÑпользуетÑÑ" -#: access/transam/twophase.c:398 +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 #, c-format msgid "maximum number of prepared transactions reached" msgstr "доÑтигнут предел чиÑла подготовленных транзакций" -#: access/transam/twophase.c:399 +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "Увеличьте параметр max_prepared_transactions (текущее значение %d)." -#: access/transam/twophase.c:539 +#: access/transam/twophase.c:586 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ \"%s\" занÑта" -#: access/transam/twophase.c:545 +#: access/transam/twophase.c:592 #, c-format msgid "permission denied to finish prepared transaction" msgstr "нет доÑтупа Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ð¾Ð¹ транзакции" -#: access/transam/twophase.c:546 +#: access/transam/twophase.c:593 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "" "Это разрешено только Ñуперпользователю и пользователю, подготовившему " "транзакцию." -#: access/transam/twophase.c:557 +#: access/transam/twophase.c:604 #, c-format msgid "prepared transaction belongs to another database" msgstr "Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑитÑÑ Ðº другой базе данных" -#: access/transam/twophase.c:558 +#: access/transam/twophase.c:605 #, c-format msgid "" "Connect to the database where the transaction was prepared to finish it." @@ -1732,74 +1532,74 @@ msgstr "" "подготовлена." # [SM]: TO REVIEW -#: access/transam/twophase.c:573 +#: access/transam/twophase.c:620 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "подготовленной транзакции Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð¼ \"%s\" нет" -#: access/transam/twophase.c:1042 +#: access/transam/twophase.c:1103 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "превышен предельный размер файла ÑоÑтоÑÐ½Ð¸Ñ 2PC" -#: access/transam/twophase.c:1160 +#: access/transam/twophase.c:1232 #, c-format msgid "could not open two-phase state file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\": %m" -#: access/transam/twophase.c:1177 +#: access/transam/twophase.c:1253 #, c-format msgid "could not stat two-phase state file \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о файле ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\": %m" -#: access/transam/twophase.c:1211 +#: access/transam/twophase.c:1292 #, c-format msgid "could not read two-phase state file \"%s\": %m" msgstr "не удалоÑÑŒ прочитать файл ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\": %m" -#: access/transam/twophase.c:1265 access/transam/xlog.c:6348 +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 #, c-format msgid "Failed while allocating a WAL reading processor." msgstr "Ðе удалоÑÑŒ размеÑтить обработчик журнала транзакций." -#: access/transam/twophase.c:1271 +#: access/transam/twophase.c:1390 #, c-format msgid "could not read two-phase state from WAL at %X/%X" msgstr "не удалоÑÑŒ прочитать ÑоÑтоÑние 2PC из WAL в позиции %X/%X" -#: access/transam/twophase.c:1279 +#: access/transam/twophase.c:1398 #, c-format msgid "expected two-phase state data is not present in WAL at %X/%X" msgstr "" "ожидаемые данные ÑоÑтоÑÐ½Ð¸Ñ Ð´Ð²ÑƒÑ…Ñ„Ð°Ð·Ð½Ð¾Ð¹ фикÑации отÑутÑтвуют в WAL в позиции " "%X/%X" -#: access/transam/twophase.c:1514 +#: access/transam/twophase.c:1636 #, c-format msgid "could not remove two-phase state file \"%s\": %m" msgstr "не удалоÑÑŒ Ñтереть файл ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\": %m" -#: access/transam/twophase.c:1544 +#: access/transam/twophase.c:1665 #, c-format msgid "could not recreate two-phase state file \"%s\": %m" msgstr "не удалоÑÑŒ переÑоздать файл ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\": %m" -#: access/transam/twophase.c:1555 access/transam/twophase.c:1563 +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 #, c-format msgid "could not write two-phase state file: %m" msgstr "не удалоÑÑŒ запиÑать в файл ÑоÑтоÑÐ½Ð¸Ñ 2PC: %m" -#: access/transam/twophase.c:1577 +#: access/transam/twophase.c:1712 #, c-format msgid "could not fsync two-phase state file: %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл ÑоÑтоÑÐ½Ð¸Ñ 2PC: %m" -#: access/transam/twophase.c:1584 +#: access/transam/twophase.c:1719 #, c-format msgid "could not close two-phase state file: %m" msgstr "не удалоÑÑŒ закрыть файл ÑоÑтоÑÐ½Ð¸Ñ 2PC: %m" -#: access/transam/twophase.c:1665 +#: access/transam/twophase.c:1807 #, c-format msgid "" "%u two-phase state file was written for a long-running prepared transaction" @@ -1812,27 +1612,40 @@ msgstr[1] "" msgstr[2] "" "Ð´Ð»Ñ Ð´Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ñ… подготовленных транзакций запиÑано файлов ÑоÑтоÑÐ½Ð¸Ñ 2PC: %u" -#: access/transam/twophase.c:1729 +#: access/transam/twophase.c:2036 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "воÑÑтановление подготовленной транзакции %u из разделÑемой памÑти" + +#: access/transam/twophase.c:2126 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "удаление уÑтаревшего файла ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" + +#: access/transam/twophase.c:2133 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "удаление из памÑти уÑтаревшего ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" + +#: access/transam/twophase.c:2146 #, c-format -msgid "removing future two-phase state file \"%s\"" -msgstr "удаление будущего файла ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\"" +msgid "removing future two-phase state file for transaction %u" +msgstr "удаление файла будущего ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" -#: access/transam/twophase.c:1745 access/transam/twophase.c:1756 -#: access/transam/twophase.c:1876 access/transam/twophase.c:1887 -#: access/transam/twophase.c:1964 +#: access/transam/twophase.c:2153 #, c-format -msgid "removing corrupt two-phase state file \"%s\"" -msgstr "удаление иÑпорченного файла ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\"" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "удаление из памÑти будущего ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" -#: access/transam/twophase.c:1865 access/transam/twophase.c:1953 +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 #, c-format -msgid "removing stale two-phase state file \"%s\"" -msgstr "удаление уÑтаревшего файла ÑоÑтоÑÐ½Ð¸Ñ 2PC \"%s\"" +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "удаление иÑпорченного файла ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" -#: access/transam/twophase.c:1971 +#: access/transam/twophase.c:2193 #, c-format -msgid "recovering prepared transaction %u" -msgstr "воÑÑтановление подготовленной транзакции %u" +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "удаление из памÑти иÑпорченного ÑоÑтоÑÐ½Ð¸Ñ 2PC Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u" #: access/transam/varsup.c:124 #, c-format @@ -1840,19 +1653,20 @@ msgid "" "database is not accepting commands to avoid wraparound data loss in database " "\"%s\"" msgstr "" -"база данных не принимает команды во избежание потери данных из-за Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ " -"в базе данных \"%s\"" +"база данных не принимает команды во избежание потери данных из-за " +"Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ в базе данных \"%s\"" #: access/transam/varsup.c:126 access/transam/varsup.c:133 #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." msgstr "" -"ОÑтановите управлÑющий процеÑÑ (postmaster) и выполните очиÑтку (VACUUM)\n" -"базы данных в однопользовательÑком режиме.\n" -"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые\n" -"подготовленные транзакции." +"ОÑтановите управлÑющий процеÑÑ (postmaster) и выполните очиÑтку (VACUUM) " +"базы данных в монопольном режиме.\n" +"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые " +"подготовленные транзакции и удалить неиÑпользуемые Ñлоты репликации." #: access/transam/varsup.c:131 #, c-format @@ -1860,8 +1674,8 @@ msgid "" "database is not accepting commands to avoid wraparound data loss in database " "with OID %u" msgstr "" -"база данных не принимает команды во избежание потери данных из-за Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ " -"в базе данных Ñ OID %u" +"база данных не принимает команды во избежание потери данных из-за " +"Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ в базе данных Ñ OID %u" #: access/transam/varsup.c:143 access/transam/varsup.c:402 #, c-format @@ -1879,202 +1693,210 @@ msgstr "" #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "" -"предел Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ID транзакций равен %u, иÑточник Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ - база данных " -"Ñ OID %u" +"предел Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ ID транзакций равен %u, иÑточник Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ - база " +"данных Ñ OID %u" -#: access/transam/xact.c:946 +#: access/transam/xact.c:960 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "в одной транзакции не может быть больше 2^32-2 команд" -#: access/transam/xact.c:1471 +#: access/transam/xact.c:1485 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "превышен предел чиÑла зафикÑированных подтранзакций (%d)" -#: access/transam/xact.c:2268 +#: access/transam/xact.c:2296 #, c-format msgid "cannot PREPARE a transaction that has operated on temporary tables" msgstr "" -"выполнить PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, оперирующей Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼Ð¸ таблицами, нельзÑ" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, оперирующей Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼Ð¸ таблицами" + +#: access/transam/xact.c:2308 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, оперирующей Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼Ð¸ объектами" -#: access/transam/xact.c:2278 +#: access/transam/xact.c:2318 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, Ñнимки которой ÑкÑпортированы" +#: access/transam/xact.c:2327 +#, c-format +msgid "" +"cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, задейÑтвующей процеÑÑÑ‹ логичеÑкой " +"репликации" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3163 +#: access/transam/xact.c:3212 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s не может выполнÑтьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ блока транзакции" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3173 +#: access/transam/xact.c:3222 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s не может выполнÑтьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ подтранзакции" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3183 +#: access/transam/xact.c:3232 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "" -"%s не может выполнÑтьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ функции или Ñтроки, включающей неÑколько " -"команд" +msgid "%s cannot be executed from a function" +msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñть внутри функции" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3254 +#: access/transam/xact.c:3301 access/transam/xact.c:3925 +#: access/transam/xact.c:3994 access/transam/xact.c:4105 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s может выполнÑтьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ внутри блоков транзакций" -#: access/transam/xact.c:3438 +#: access/transam/xact.c:3494 #, c-format msgid "there is already a transaction in progress" msgstr "Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ ÑƒÐ¶Ðµ выполнÑетÑÑ" -#: access/transam/xact.c:3606 access/transam/xact.c:3709 +#: access/transam/xact.c:3605 access/transam/xact.c:3675 +#: access/transam/xact.c:3784 #, c-format msgid "there is no transaction in progress" msgstr "нет незавершённой транзакции" -#: access/transam/xact.c:3617 +#: access/transam/xact.c:3686 #, c-format msgid "cannot commit during a parallel operation" msgstr "фикÑировать транзакции во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:3720 +#: access/transam/xact.c:3795 #, c-format msgid "cannot abort during a parallel operation" msgstr "прерывание во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций невозможно" -#: access/transam/xact.c:3762 +#: access/transam/xact.c:3889 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "определÑть точки ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:3829 +#: access/transam/xact.c:3976 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "выÑвобождать точки ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:3840 access/transam/xact.c:3892 -#: access/transam/xact.c:3898 access/transam/xact.c:3954 -#: access/transam/xact.c:4004 access/transam/xact.c:4010 +#: access/transam/xact.c:3986 access/transam/xact.c:4037 +#: access/transam/xact.c:4097 access/transam/xact.c:4146 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "точка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует" + +#: access/transam/xact.c:4043 access/transam/xact.c:4152 #, c-format -msgid "no such savepoint" -msgstr "нет такой точки ÑохранениÑ" +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "" +"точка ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ \"%s\" на текущем уровне точек ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ ÑущеÑтвует" -#: access/transam/xact.c:3942 +#: access/transam/xact.c:4085 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "откатитьÑÑ Ðº точке ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð²Ð¾ Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:4070 +#: access/transam/xact.c:4213 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "запуÑкать подтранзакции во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:4137 +#: access/transam/xact.c:4281 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "фикÑировать подтранзакции во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: access/transam/xact.c:4745 +#: access/transam/xact.c:4919 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "в одной транзакции не может быть больше 2^32-1 подтранзакций" -#: access/transam/xlog.c:2452 +#: access/transam/xlog.c:2492 #, c-format msgid "could not seek in log file %s to offset %u: %m" msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð² файле журнала %s к Ñмещению %u: %m" -#: access/transam/xlog.c:2474 +#: access/transam/xlog.c:2514 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "не удалоÑÑŒ запиÑать в файл журнала %s (Ñмещение: %u, длина: %zu): %m" -#: access/transam/xlog.c:2738 +#: access/transam/xlog.c:2792 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð° на %X/%X на линии времени %u" -#: access/transam/xlog.c:3385 +#: access/transam/xlog.c:3444 #, c-format msgid "not enough data in file \"%s\"" msgstr "недоÑтаточно данных в файле\"%s\"" -#: access/transam/xlog.c:3531 +#: access/transam/xlog.c:3589 #, c-format -msgid "could not open transaction log file \"%s\": %m" -msgstr "не удалоÑÑŒ открыть файл журнала транзакций \"%s\": %m" +msgid "could not open write-ahead log file \"%s\": %m" +msgstr "не удалоÑÑŒ открыть файл журнала предзапиÑи \"%s\": %m" -#: access/transam/xlog.c:3720 access/transam/xlog.c:5533 +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 #, c-format msgid "could not close log file %s: %m" msgstr "не удалоÑÑŒ закрыть файл журнала \"%s\": %m" -#: access/transam/xlog.c:3777 access/transam/xlogutils.c:701 -#: replication/walsender.c:2309 +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 +#: replication/walsender.c:2410 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "запрошенный Ñегмент WAL %s уже удалён" -#: access/transam/xlog.c:3837 access/transam/xlog.c:3912 -#: access/transam/xlog.c:4107 +#: access/transam/xlog.c:4051 #, c-format -msgid "could not open transaction log directory \"%s\": %m" -msgstr "не удалоÑÑŒ открыть каталог журнала транзакций \"%s\": %m" +msgid "recycled write-ahead log file \"%s\"" +msgstr "файл журнала предзапиÑи \"%s\" иÑпользуетÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾" -#: access/transam/xlog.c:3993 +#: access/transam/xlog.c:4063 #, c-format -msgid "recycled transaction log file \"%s\"" -msgstr "файл журнала транзакций \"%s\" иÑпользуетÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾" +msgid "removing write-ahead log file \"%s\"" +msgstr "файл журнала предзапиÑи \"%s\" удалÑетÑÑ" -#: access/transam/xlog.c:4005 -#, c-format -msgid "removing transaction log file \"%s\"" -msgstr "файл журнала транзакций \"%s\" удалÑетÑÑ" - -#: access/transam/xlog.c:4025 +#: access/transam/xlog.c:4083 #, c-format -msgid "could not rename old transaction log file \"%s\": %m" -msgstr "не удалоÑÑŒ переименовать Ñтарый файл журнала транзакций \"%s\": %m" +msgid "could not rename old write-ahead log file \"%s\": %m" +msgstr "не удалоÑÑŒ переименовать Ñтарый файл журнала предзапиÑи \"%s\": %m" -#: access/transam/xlog.c:4067 access/transam/xlog.c:4077 +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "требуемый каталог WAL \"%s\" не ÑущеÑтвует" -#: access/transam/xlog.c:4083 +#: access/transam/xlog.c:4141 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "ÑоздаётÑÑ Ð¾Ñ‚ÑутÑтвующий каталог WAL \"%s\"" -#: access/transam/xlog.c:4086 +#: access/transam/xlog.c:4144 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать отÑутÑтвующий каталог \"%s\": %m" -#: access/transam/xlog.c:4117 -#, c-format -msgid "removing transaction log backup history file \"%s\"" -msgstr "удалÑетÑÑ Ñ„Ð°Ð¹Ð» иÑтории ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð°: \"%s\"" - -#: access/transam/xlog.c:4198 +#: access/transam/xlog.c:4252 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "неожиданный ID линии времени %u в Ñегменте журнала %s, Ñмещение %u" -#: access/transam/xlog.c:4320 +#: access/transam/xlog.c:4380 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "" "Ð½Ð¾Ð²Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u не ÑвлÑетÑÑ Ð¾Ñ‚Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ линии времени ÑиÑтемы БД %u" -#: access/transam/xlog.c:4334 +#: access/transam/xlog.c:4394 #, c-format msgid "" "new timeline %u forked off current database system timeline %u before " @@ -2083,55 +1905,61 @@ msgstr "" "Ð½Ð¾Ð²Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u ответвилаÑÑŒ от текущей линии времени базы данных %u " "до текущей точки воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ %X/%X" -#: access/transam/xlog.c:4353 +#: access/transam/xlog.c:4413 #, c-format msgid "new target timeline is %u" msgstr "Ð½Ð¾Ð²Ð°Ñ Ñ†ÐµÐ»ÐµÐ²Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u" -#: access/transam/xlog.c:4428 +#: access/transam/xlog.c:4493 #, c-format msgid "could not create control file \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать файл \"%s\": %m" -#: access/transam/xlog.c:4440 access/transam/xlog.c:4666 +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 #, c-format msgid "could not write to control file: %m" msgstr "не удалоÑÑŒ запиÑать в файл pg_control: %m" -#: access/transam/xlog.c:4448 access/transam/xlog.c:4674 +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 #, c-format msgid "could not fsync control file: %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл pg_control: %m" -#: access/transam/xlog.c:4454 access/transam/xlog.c:4680 +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 #, c-format msgid "could not close control file: %m" msgstr "не удалоÑÑŒ закрыть файл pg_control: %m" -#: access/transam/xlog.c:4472 access/transam/xlog.c:4654 +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 #, c-format msgid "could not open control file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл \"%s\": %m" -#: access/transam/xlog.c:4479 +#: access/transam/xlog.c:4548 #, c-format msgid "could not read from control file: %m" msgstr "не удалоÑÑŒ прочитать файл pg_control: %m" -#: access/transam/xlog.c:4493 access/transam/xlog.c:4502 -#: access/transam/xlog.c:4526 access/transam/xlog.c:4533 -#: access/transam/xlog.c:4540 access/transam/xlog.c:4545 -#: access/transam/xlog.c:4552 access/transam/xlog.c:4559 -#: access/transam/xlog.c:4566 access/transam/xlog.c:4573 -#: access/transam/xlog.c:4580 access/transam/xlog.c:4587 -#: access/transam/xlog.c:4594 access/transam/xlog.c:4603 -#: access/transam/xlog.c:4610 access/transam/xlog.c:4619 -#: access/transam/xlog.c:4626 utils/init/miscinit.c:1397 +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "" +"не удалоÑÑŒ прочитать файл pg_control (прочитано байт: %d, ожидалоÑÑŒ: %d)" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 +#: access/transam/xlog.c:4599 access/transam/xlog.c:4606 +#: access/transam/xlog.c:4613 access/transam/xlog.c:4618 +#: access/transam/xlog.c:4625 access/transam/xlog.c:4632 +#: access/transam/xlog.c:4639 access/transam/xlog.c:4646 +#: access/transam/xlog.c:4653 access/transam/xlog.c:4660 +#: access/transam/xlog.c:4669 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4685 access/transam/xlog.c:4692 +#: utils/init/miscinit.c:1502 #, c-format msgid "database files are incompatible with server" msgstr "файлы базы данных не ÑовмеÑтимы Ñ Ñервером" -#: access/transam/xlog.c:4494 +#: access/transam/xlog.c:4567 #, c-format msgid "" "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), " @@ -2140,7 +1968,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ PG_CONTROL_VERSION %d (0x%08x), но " "Ñервер Ñкомпилирован Ñ PG_CONTROL_VERSION %d (0x%08x)." -#: access/transam/xlog.c:4498 +#: access/transam/xlog.c:4571 #, c-format msgid "" "This could be a problem of mismatched byte ordering. It looks like you need " @@ -2149,7 +1977,7 @@ msgstr "" "Возможно, проблема вызвана разным порÑдком байт. КажетÑÑ, вам надо выполнить " "initdb." -#: access/transam/xlog.c:4503 +#: access/transam/xlog.c:4576 #, c-format msgid "" "The database cluster was initialized with PG_CONTROL_VERSION %d, but the " @@ -2158,18 +1986,18 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ PG_CONTROL_VERSION %d, но Ñервер " "Ñкомпилирован Ñ PG_CONTROL_VERSION %d." -#: access/transam/xlog.c:4506 access/transam/xlog.c:4530 -#: access/transam/xlog.c:4537 access/transam/xlog.c:4542 +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 +#: access/transam/xlog.c:4610 access/transam/xlog.c:4615 #, c-format msgid "It looks like you need to initdb." msgstr "КажетÑÑ, вам надо выполнить initdb." -#: access/transam/xlog.c:4517 +#: access/transam/xlog.c:4590 #, c-format msgid "incorrect checksum in control file" msgstr "ошибка контрольной Ñуммы в файле pg_control" -#: access/transam/xlog.c:4527 +#: access/transam/xlog.c:4600 #, c-format msgid "" "The database cluster was initialized with CATALOG_VERSION_NO %d, but the " @@ -2178,7 +2006,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ CATALOG_VERSION_NO %d, но Ñервер " "Ñкомпилирован Ñ CATALOG_VERSION_NO %d." -#: access/transam/xlog.c:4534 +#: access/transam/xlog.c:4607 #, c-format msgid "" "The database cluster was initialized with MAXALIGN %d, but the server was " @@ -2187,7 +2015,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ MAXALIGN %d, но Ñервер " "Ñкомпилирован Ñ MAXALIGN %d." -#: access/transam/xlog.c:4541 +#: access/transam/xlog.c:4614 #, c-format msgid "" "The database cluster appears to use a different floating-point number format " @@ -2196,7 +2024,7 @@ msgstr "" "КажетÑÑ, в клаÑтере баз данных и в программе Ñервера иÑпользуютÑÑ Ñ€Ð°Ð·Ð½Ñ‹Ðµ " "форматы чиÑел Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой." -#: access/transam/xlog.c:4546 +#: access/transam/xlog.c:4619 #, c-format msgid "" "The database cluster was initialized with BLCKSZ %d, but the server was " @@ -2205,17 +2033,17 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ BLCKSZ %d, но Ñервер Ñкомпилирован " "Ñ BLCKSZ %d." -#: access/transam/xlog.c:4549 access/transam/xlog.c:4556 -#: access/transam/xlog.c:4563 access/transam/xlog.c:4570 -#: access/transam/xlog.c:4577 access/transam/xlog.c:4584 -#: access/transam/xlog.c:4591 access/transam/xlog.c:4598 -#: access/transam/xlog.c:4606 access/transam/xlog.c:4613 #: access/transam/xlog.c:4622 access/transam/xlog.c:4629 +#: access/transam/xlog.c:4636 access/transam/xlog.c:4643 +#: access/transam/xlog.c:4650 access/transam/xlog.c:4657 +#: access/transam/xlog.c:4664 access/transam/xlog.c:4672 +#: access/transam/xlog.c:4679 access/transam/xlog.c:4688 +#: access/transam/xlog.c:4695 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "КажетÑÑ, вам надо перекомпилировать Ñервер или выполнить initdb." -#: access/transam/xlog.c:4553 +#: access/transam/xlog.c:4626 #, c-format msgid "" "The database cluster was initialized with RELSEG_SIZE %d, but the server was " @@ -2224,7 +2052,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ RELSEG_SIZE %d, но Ñервер " "Ñкомпилирован Ñ RELSEG_SIZE %d." -#: access/transam/xlog.c:4560 +#: access/transam/xlog.c:4633 #, c-format msgid "" "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was " @@ -2233,16 +2061,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ XLOG_BLCKSZ %d, но Ñервер " "Ñкомпилирован Ñ XLOG_BLCKSZ %d." -#: access/transam/xlog.c:4567 -#, c-format -msgid "" -"The database cluster was initialized with XLOG_SEG_SIZE %d, but the server " -"was compiled with XLOG_SEG_SIZE %d." -msgstr "" -"КлаÑтер баз данных был инициализирован Ñ XLOG_SEG_SIZE %d, но Ñервер " -"Ñкомпилирован Ñ XLOG_SEG_SIZE %d." - -#: access/transam/xlog.c:4574 +#: access/transam/xlog.c:4640 #, c-format msgid "" "The database cluster was initialized with NAMEDATALEN %d, but the server was " @@ -2251,7 +2070,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ NAMEDATALEN %d, но Ñервер " "Ñкомпилирован Ñ NAMEDATALEN %d." -#: access/transam/xlog.c:4581 +#: access/transam/xlog.c:4647 #, c-format msgid "" "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server " @@ -2260,7 +2079,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ INDEX_MAX_KEYS %d, но Ñервер " "Ñкомпилирован Ñ INDEX_MAX_KEYS %d." -#: access/transam/xlog.c:4588 +#: access/transam/xlog.c:4654 #, c-format msgid "" "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the " @@ -2269,7 +2088,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ TOAST_MAX_CHUNK_SIZE %d, но Ñервер " "Ñкомпилирован Ñ TOAST_MAX_CHUNK_SIZE %d." -#: access/transam/xlog.c:4595 +#: access/transam/xlog.c:4661 #, c-format msgid "" "The database cluster was initialized with LOBLKSIZE %d, but the server was " @@ -2278,7 +2097,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ LOBLKSIZE %d, но Ñервер " "Ñкомпилирован Ñ LOBLKSIZE %d." -#: access/transam/xlog.c:4604 +#: access/transam/xlog.c:4670 #, c-format msgid "" "The database cluster was initialized without USE_FLOAT4_BYVAL but the server " @@ -2287,7 +2106,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован без USE_FLOAT4_BYVAL, но Ñервер " "Ñкомпилирован Ñ USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4611 +#: access/transam/xlog.c:4677 #, c-format msgid "" "The database cluster was initialized with USE_FLOAT4_BYVAL but the server " @@ -2296,7 +2115,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ USE_FLOAT4_BYVAL, но Ñервер " "Ñкомпилирован без USE_FLOAT4_BYVAL." -#: access/transam/xlog.c:4620 +#: access/transam/xlog.c:4686 #, c-format msgid "" "The database cluster was initialized without USE_FLOAT8_BYVAL but the server " @@ -2305,7 +2124,7 @@ msgstr "" "КлаÑтер баз данных был инициализирован без USE_FLOAT8_BYVAL, но Ñервер " "Ñкомпилирован Ñ USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4627 +#: access/transam/xlog.c:4693 #, c-format msgid "" "The database cluster was initialized with USE_FLOAT8_BYVAL but the server " @@ -2314,90 +2133,123 @@ msgstr "" "КлаÑтер баз данных был инициализирован Ñ USE_FLOAT8_BYVAL, но Ñервер был " "Ñкомпилирован без USE_FLOAT8_BYVAL." -#: access/transam/xlog.c:4983 +#: access/transam/xlog.c:4702 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the " +"control file specifies %d bytes" +msgstr[0] "" +"размер Ñегмента WAL должен задаватьÑÑ Ñтепенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управлÑющем файле указано значение: %d" +msgstr[1] "" +"размер Ñегмента WAL должен задаватьÑÑ Ñтепенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управлÑющем файле указано значение: %d" +msgstr[2] "" +"размер Ñегмента WAL должен задаватьÑÑ Ñтепенью 2 в интервале от 1 МБ до 1 " +"ГБ, но в управлÑющем файле указано значение: %d" + +#: access/transam/xlog.c:4714 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" должен быть минимум вдвое больше \"wal_segment_size\"" + +#: access/transam/xlog.c:4718 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" должен быть минимум вдвое больше \"wal_segment_size\"" + +#: access/transam/xlog.c:5105 #, c-format msgid "could not generate secret authorization token" msgstr "не удалоÑÑŒ Ñгенерировать Ñлучайное чиÑло Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸" -#: access/transam/xlog.c:5073 +#: access/transam/xlog.c:5195 #, c-format -msgid "could not write bootstrap transaction log file: %m" -msgstr "не удалоÑÑŒ запиÑать начальный файл журнала транзакций: %m" +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "не удалоÑÑŒ запиÑать начальный файл журнала предзапиÑи: %m" -#: access/transam/xlog.c:5081 +#: access/transam/xlog.c:5203 #, c-format -msgid "could not fsync bootstrap transaction log file: %m" -msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ начальный файл журнала транзакций: %m" +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "не удалоÑÑŒ ÑброÑить на диÑк начальный файл журнала предзапиÑи: %m" -#: access/transam/xlog.c:5087 +#: access/transam/xlog.c:5209 #, c-format -msgid "could not close bootstrap transaction log file: %m" -msgstr "не удалоÑÑŒ закрыть начальный файл журнала транзакций: %m" +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "не удалоÑÑŒ закрыть начальный файл журнала предзапиÑи: %m" -#: access/transam/xlog.c:5163 +#: access/transam/xlog.c:5291 #, c-format msgid "could not open recovery command file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл команд воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\": %m" -#: access/transam/xlog.c:5209 access/transam/xlog.c:5311 +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 #, c-format msgid "invalid value for recovery parameter \"%s\": \"%s\"" msgstr "неверное значение Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\": \"%s\"" -#: access/transam/xlog.c:5212 +#: access/transam/xlog.c:5340 #, c-format msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." msgstr "ДопуÑтимые значениÑ: \"pause\", \"promote\" и \"shutdown\"." -#: access/transam/xlog.c:5232 +#: access/transam/xlog.c:5360 #, c-format msgid "recovery_target_timeline is not a valid number: \"%s\"" msgstr "recovery_target_timeline не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым чиÑлом: \"%s\"" -#: access/transam/xlog.c:5249 +#: access/transam/xlog.c:5377 #, c-format msgid "recovery_target_xid is not a valid number: \"%s\"" msgstr "recovery_target_xid не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым чиÑлом: \"%s\"" -#: access/transam/xlog.c:5280 +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "значение recovery_target_time не предÑтавлÑет допуÑтимое времÑ: \"%s\"" + +#: access/transam/xlog.c:5420 #, c-format msgid "recovery_target_name is too long (maximum %d characters)" msgstr "длина recovery_target_name превышает предел (%d)" -#: access/transam/xlog.c:5314 +#: access/transam/xlog.c:5454 #, c-format msgid "The only allowed value is \"immediate\"." msgstr "ЕдинÑтвенное допуÑтимое значение: \"immediate\"." -#: access/transam/xlog.c:5327 access/transam/xlog.c:5338 -#: commands/extension.c:546 commands/extension.c:554 utils/misc/guc.c:5719 +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 +#: commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5997 #, c-format msgid "parameter \"%s\" requires a Boolean value" msgstr "параметр \"%s\" требует логичеÑкое значение" -#: access/transam/xlog.c:5373 +#: access/transam/xlog.c:5513 #, c-format msgid "parameter \"%s\" requires a temporal value" msgstr "параметр \"%s\" требует временное значение" -#: access/transam/xlog.c:5375 catalog/dependency.c:961 catalog/dependency.c:962 -#: catalog/dependency.c:968 catalog/dependency.c:969 catalog/dependency.c:980 -#: catalog/dependency.c:981 commands/tablecmds.c:946 commands/tablecmds.c:10017 -#: commands/user.c:1052 commands/view.c:505 libpq/auth.c:328 -#: replication/syncrep.c:1118 storage/lmgr/deadlock.c:1139 -#: storage/lmgr/proc.c:1313 utils/adt/acl.c:5248 utils/misc/guc.c:5741 -#: utils/misc/guc.c:5834 utils/misc/guc.c:9792 utils/misc/guc.c:9826 -#: utils/misc/guc.c:9860 utils/misc/guc.c:9894 utils/misc/guc.c:9929 +#: access/transam/xlog.c:5515 catalog/dependency.c:969 +#: catalog/dependency.c:970 catalog/dependency.c:976 catalog/dependency.c:977 +#: catalog/dependency.c:988 catalog/dependency.c:989 commands/tablecmds.c:1070 +#: commands/tablecmds.c:11306 commands/user.c:1064 commands/view.c:504 +#: libpq/auth.c:336 replication/syncrep.c:1162 storage/lmgr/deadlock.c:1139 +#: storage/lmgr/proc.c:1331 utils/adt/acl.c:5344 utils/misc/guc.c:6019 +#: utils/misc/guc.c:6112 utils/misc/guc.c:10102 utils/misc/guc.c:10136 +#: utils/misc/guc.c:10170 utils/misc/guc.c:10204 utils/misc/guc.c:10239 #, c-format msgid "%s" msgstr "%s" -#: access/transam/xlog.c:5382 +#: access/transam/xlog.c:5522 #, c-format msgid "unrecognized recovery parameter \"%s\"" msgstr "нераÑпознанный параметр воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\"" -#: access/transam/xlog.c:5393 +#: access/transam/xlog.c:5533 #, c-format msgid "" "recovery command file \"%s\" specified neither primary_conninfo nor " @@ -2406,7 +2258,7 @@ msgstr "" "в файле команд воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" не указан параметр primary_conninfo или " "restore_command" -#: access/transam/xlog.c:5395 +#: access/transam/xlog.c:5535 #, c-format msgid "" "The database server will regularly poll the pg_wal subdirectory to check for " @@ -2415,7 +2267,7 @@ msgstr "" "Сервер БД будет регулÑрно опрашивать подкаталог pg_wal и проверÑть " "ÑодержащиеÑÑ Ð² нём файлы." -#: access/transam/xlog.c:5402 +#: access/transam/xlog.c:5542 #, c-format msgid "" "recovery command file \"%s\" must specify restore_command when standby mode " @@ -2424,78 +2276,78 @@ msgstr "" "в файле команд воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" может отÑутÑтвовать restore_command, " "только еÑли Ñто резервный Ñервер" -#: access/transam/xlog.c:5423 +#: access/transam/xlog.c:5563 #, c-format msgid "standby mode is not supported by single-user servers" msgstr "" "режим резервного Ñервера не поддерживаетÑÑ Ð¾Ð´Ð½Ð¾Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑким Ñервером" -#: access/transam/xlog.c:5442 +#: access/transam/xlog.c:5582 #, c-format msgid "recovery target timeline %u does not exist" msgstr "Ñ†ÐµÐ»ÐµÐ²Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ %u не ÑущеÑтвует" -#: access/transam/xlog.c:5563 +#: access/transam/xlog.c:5703 #, c-format msgid "archive recovery complete" msgstr "воÑÑтановление архива завершено" -#: access/transam/xlog.c:5622 access/transam/xlog.c:5888 +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 #, c-format msgid "recovery stopping after reaching consistency" msgstr "" "воÑÑтановление оÑтанавливаетÑÑ Ð¿Ð¾Ñле доÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ ÑоглаÑованного ÑоÑтоÑниÑ" -#: access/transam/xlog.c:5643 +#: access/transam/xlog.c:5783 #, c-format -msgid "recovery stopping before WAL position (LSN) \"%X/%X\"" +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" msgstr "воÑÑтановление оÑтанавливаетÑÑ Ð¿ÐµÑ€ÐµÐ´ позицией в WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:5729 +#: access/transam/xlog.c:5869 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "" "воÑÑтановление оÑтанавливаетÑÑ Ð¿ÐµÑ€ÐµÐ´ фикÑированием транзакции %u, Ð²Ñ€ÐµÐ¼Ñ %s" -#: access/transam/xlog.c:5736 +#: access/transam/xlog.c:5876 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "" "воÑÑтановление оÑтанавливаетÑÑ Ð¿ÐµÑ€ÐµÐ´ прерыванием транзакции %u, Ð²Ñ€ÐµÐ¼Ñ %s" -#: access/transam/xlog.c:5782 +#: access/transam/xlog.c:5922 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "воÑÑтановление оÑтанавливаетÑÑ Ð² точке воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\", Ð²Ñ€ÐµÐ¼Ñ %s" -#: access/transam/xlog.c:5800 +#: access/transam/xlog.c:5940 #, c-format -msgid "recovery stopping after WAL position (LSN) \"%X/%X\"" +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" msgstr "воÑÑтановление оÑтанавливаетÑÑ Ð¿Ð¾Ñле позиции в WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:5868 +#: access/transam/xlog.c:6008 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "" "воÑÑтановление оÑтанавливаетÑÑ Ð¿Ð¾Ñле фикÑÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u, Ð²Ñ€ÐµÐ¼Ñ %s" -#: access/transam/xlog.c:5876 +#: access/transam/xlog.c:6016 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "" "воÑÑтановление оÑтанавливаетÑÑ Ð¿Ð¾Ñле Ð¿Ñ€ÐµÑ€Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ %u, Ð²Ñ€ÐµÐ¼Ñ %s" -#: access/transam/xlog.c:5916 +#: access/transam/xlog.c:6056 #, c-format msgid "recovery has paused" msgstr "воÑÑтановление приоÑтановлено" -#: access/transam/xlog.c:5917 +#: access/transam/xlog.c:6057 #, c-format msgid "Execute pg_wal_replay_resume() to continue." msgstr "Выполните pg_wal_replay_resume() Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ." -#: access/transam/xlog.c:6125 +#: access/transam/xlog.c:6265 #, c-format msgid "" "hot standby is not possible because %s = %d is a lower setting than on the " @@ -2504,12 +2356,12 @@ msgstr "" "режим горÑчего резерва невозможен, так как параметр %s = %d, меньше чем на " "главном Ñервере (на нём было значение %d)" -#: access/transam/xlog.c:6151 +#: access/transam/xlog.c:6291 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "WAL был Ñоздан Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ wal_level=minimal, возможна Ð¿Ð¾Ñ‚ÐµÑ€Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…" -#: access/transam/xlog.c:6152 +#: access/transam/xlog.c:6292 #, c-format msgid "" "This happens if you temporarily set wal_level=minimal without taking a new " @@ -2518,7 +2370,7 @@ msgstr "" "Это проиÑходит, еÑли вы на Ð²Ñ€ÐµÐ¼Ñ ÑƒÑтановили wal_level=minimal и не Ñделали " "резервную копию базу данных." -#: access/transam/xlog.c:6163 +#: access/transam/xlog.c:6303 #, c-format msgid "" "hot standby is not possible because wal_level was not set to \"replica\" or " @@ -2527,7 +2379,7 @@ msgstr "" "режим горÑчего резерва невозможен, так как на главном Ñервере уÑтановлен " "неподходÑщий wal_level (должен быть \"replica\" или выше)" -#: access/transam/xlog.c:6164 +#: access/transam/xlog.c:6304 #, c-format msgid "" "Either set wal_level to \"replica\" on the master, or turn off hot_standby " @@ -2536,32 +2388,32 @@ msgstr "" "Либо уÑтановите Ð´Ð»Ñ wal_level значение \"replica\" на главном Ñервере, либо " "выключите hot_standby здеÑÑŒ." -#: access/transam/xlog.c:6221 +#: access/transam/xlog.c:6356 #, c-format msgid "control file contains invalid data" msgstr "файл pg_control Ñодержит неверные данные" -#: access/transam/xlog.c:6227 +#: access/transam/xlog.c:6362 #, c-format msgid "database system was shut down at %s" msgstr "ÑиÑтема БД была выключена: %s" -#: access/transam/xlog.c:6232 +#: access/transam/xlog.c:6367 #, c-format msgid "database system was shut down in recovery at %s" msgstr "ÑиÑтема БД была выключена в процеÑÑе воÑÑтановлениÑ: %s" -#: access/transam/xlog.c:6236 +#: access/transam/xlog.c:6371 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "выключение ÑиÑтемы БД было прервано; поÑледний момент работы: %s" -#: access/transam/xlog.c:6240 +#: access/transam/xlog.c:6375 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "работа ÑиÑтемы БД была прервана во Ð²Ñ€ÐµÐ¼Ñ Ð²Ð¾ÑÑтановлениÑ: %s" -#: access/transam/xlog.c:6242 +#: access/transam/xlog.c:6377 #, c-format msgid "" "This probably means that some data is corrupted and you will have to use the " @@ -2570,14 +2422,14 @@ msgstr "" "Это Ñкорее вÑего означает, что некоторые данные повреждены и вам придётÑÑ " "воÑÑтановить БД из поÑледней резервной копии." -#: access/transam/xlog.c:6246 +#: access/transam/xlog.c:6381 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "" "работа ÑиÑтемы БД была прервана в процеÑÑе воÑÑтановлениÑ, Ð²Ñ€ÐµÐ¼Ñ Ð² журнале: " "%s" -#: access/transam/xlog.c:6248 +#: access/transam/xlog.c:6383 #, c-format msgid "" "If this has occurred more than once some data might be corrupted and you " @@ -2586,108 +2438,103 @@ msgstr "" "ЕÑли Ñто проиÑходит поÑтоÑнно, возможно, какие-то данные были иÑпорчены и " "Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтоит выбрать более раннюю точку." -#: access/transam/xlog.c:6252 +#: access/transam/xlog.c:6387 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "работа ÑиÑтемы БД была прервана; поÑледний момент работы: %s" -#: access/transam/xlog.c:6308 +#: access/transam/xlog.c:6443 #, c-format msgid "entering standby mode" msgstr "переход в режим резервного Ñервера" -#: access/transam/xlog.c:6311 +#: access/transam/xlog.c:6446 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "начинаетÑÑ Ð²Ð¾ÑÑтановление точки во времени до XID %u" -#: access/transam/xlog.c:6315 +#: access/transam/xlog.c:6450 #, c-format msgid "starting point-in-time recovery to %s" msgstr "начинаетÑÑ Ð²Ð¾ÑÑтановление точки во времени до %s" -#: access/transam/xlog.c:6319 +#: access/transam/xlog.c:6454 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "начинаетÑÑ Ð²Ð¾ÑÑтановление точки во времени до \"%s\"" -#: access/transam/xlog.c:6323 +#: access/transam/xlog.c:6458 #, c-format -msgid "starting point-in-time recovery to WAL position (LSN) \"%X/%X\"" +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" msgstr "" "начинаетÑÑ Ð²Ð¾ÑÑтановление точки во времени до позиции в WAL (LSN) \"%X/%X\"" -#: access/transam/xlog.c:6328 +#: access/transam/xlog.c:6463 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "" "начинаетÑÑ Ð²Ð¾ÑÑтановление точки во времени до первой точки ÑоглаÑованноÑти" -#: access/transam/xlog.c:6331 +#: access/transam/xlog.c:6466 #, c-format msgid "starting archive recovery" msgstr "начинаетÑÑ Ð²Ð¾ÑÑтановление архива" -#: access/transam/xlog.c:6382 access/transam/xlog.c:6510 +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 #, c-format msgid "checkpoint record is at %X/%X" msgstr "запиÑÑŒ о контрольной точке по Ñмещению %X/%X" -#: access/transam/xlog.c:6396 +#: access/transam/xlog.c:6534 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "не удалоÑÑŒ найти положение REDO, указанное запиÑью контрольной точки" -#: access/transam/xlog.c:6397 access/transam/xlog.c:6404 +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 #, c-format msgid "" "If you are not restoring from a backup, try removing the file \"%s/" "backup_label\"." msgstr "" -"ЕÑли вы не воÑÑтанавливаете БД из резервной копии, попробуйте удалить файл " -"\"%s/backup_label\"." +"ЕÑли вы не воÑÑтанавливаете БД из резервной копии, попробуйте удалить файл \"" +"%s/backup_label\"." -#: access/transam/xlog.c:6403 +#: access/transam/xlog.c:6541 #, c-format msgid "could not locate required checkpoint record" msgstr "не удалоÑÑŒ Ñчитать нужную запиÑÑŒ контрольной точки" -#: access/transam/xlog.c:6429 commands/tablespace.c:639 +#: access/transam/xlog.c:6567 commands/tablespace.c:641 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать ÑимволичеÑкую ÑÑылку \"%s\": %m" -#: access/transam/xlog.c:6461 access/transam/xlog.c:6467 +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "файл \"%s\" игнорируетÑÑ Ð²Ð²Ð¸Ð´Ñƒ отÑутÑÑ‚Ð²Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\"" -#: access/transam/xlog.c:6463 access/transam/xlog.c:11365 +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "Файл \"%s\" был переименован в \"%s\"." -#: access/transam/xlog.c:6469 +#: access/transam/xlog.c:6607 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "Ðе удалоÑÑŒ переименовать файл \"%s\" в \"%s\" (%m)." -#: access/transam/xlog.c:6520 access/transam/xlog.c:6535 +#: access/transam/xlog.c:6657 #, c-format msgid "could not locate a valid checkpoint record" msgstr "не удалоÑÑŒ Ñчитать правильную запиÑÑŒ контрольной точки" -#: access/transam/xlog.c:6529 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "иÑпользуетÑÑ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ контрольной точки по Ñмещению %X/%X" - -#: access/transam/xlog.c:6573 +#: access/transam/xlog.c:6695 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "в иÑтории Ñервера нет Ð¾Ñ‚Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð¾Ð¹ линии времени %u" -#: access/transam/xlog.c:6575 +#: access/transam/xlog.c:6697 #, c-format msgid "" "Latest checkpoint is at %X/%X on timeline %u, but in the history of the " @@ -2696,7 +2543,7 @@ msgstr "" "ПоÑледнÑÑ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ°: %X/%X на линии времени %u, но в иÑтории " "запрошенной линии времени Ñервер ответвилÑÑ Ñ Ñтой линии в %X/%X." -#: access/transam/xlog.c:6591 +#: access/transam/xlog.c:6713 #, c-format msgid "" "requested timeline %u does not contain minimum recovery point %X/%X on " @@ -2705,22 +2552,22 @@ msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u не Ñодержит минимальную точку воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ %X/" "%X на линии времени %u" -#: access/transam/xlog.c:6622 +#: access/transam/xlog.c:6744 #, c-format msgid "invalid next transaction ID" msgstr "неверный ID Ñледующей транзакции" -#: access/transam/xlog.c:6706 +#: access/transam/xlog.c:6839 #, c-format msgid "invalid redo in checkpoint record" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ REDO в контрольной точке" -#: access/transam/xlog.c:6717 +#: access/transam/xlog.c:6850 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ REDO в контрольной точке выключениÑ" -#: access/transam/xlog.c:6745 +#: access/transam/xlog.c:6878 #, c-format msgid "" "database system was not properly shut down; automatic recovery in progress" @@ -2728,19 +2575,19 @@ msgstr "" "ÑиÑтема БД была оÑтановлена нештатно; производитÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкое " "воÑÑтановление" -#: access/transam/xlog.c:6749 +#: access/transam/xlog.c:6882 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" msgstr "" "воÑÑтановление поÑле ÑÐ±Ð¾Ñ Ð½Ð°Ñ‡Ð¸Ð½Ð°ÐµÑ‚ÑÑ Ð½Ð° линии времени %u, Ñ†ÐµÐ»ÐµÐ²Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ " "времени: %u" -#: access/transam/xlog.c:6793 +#: access/transam/xlog.c:6925 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label Ñодержит данные, не ÑоглаÑованные Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð¼ pg_control" -#: access/transam/xlog.c:6794 +#: access/transam/xlog.c:6926 #, c-format msgid "" "This means that the backup is corrupted and you will have to use another " @@ -2749,44 +2596,44 @@ msgstr "" "Это означает, что Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð¿Ð¾Ð²Ñ€ÐµÐ¶Ð´ÐµÐ½Ð° и Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð‘Ð” " "придётÑÑ Ð¸Ñпользовать другую копию." -#: access/transam/xlog.c:6868 +#: access/transam/xlog.c:7017 #, c-format msgid "initializing for hot standby" msgstr "Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð»Ñ Ð³Ð¾Ñ€Ñчего резерва" -#: access/transam/xlog.c:7000 +#: access/transam/xlog.c:7149 #, c-format msgid "redo starts at %X/%X" msgstr "запиÑÑŒ REDO начинаетÑÑ Ñо ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %X/%X" -#: access/transam/xlog.c:7234 +#: access/transam/xlog.c:7383 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° оÑтановки воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´ÑˆÐµÑтвует ÑоглаÑованной точке " "воÑÑтановлениÑ" -#: access/transam/xlog.c:7272 +#: access/transam/xlog.c:7421 #, c-format msgid "redo done at %X/%X" msgstr "запиÑи REDO обработаны до ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %X/%X" -#: access/transam/xlog.c:7277 access/transam/xlog.c:9280 +#: access/transam/xlog.c:7426 #, c-format msgid "last completed transaction was at log time %s" msgstr "поÑледнÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±Ñ‹Ð»Ð° выполнена в %s" -#: access/transam/xlog.c:7286 +#: access/transam/xlog.c:7435 #, c-format msgid "redo is not required" msgstr "данные REDO не требуютÑÑ" -#: access/transam/xlog.c:7361 access/transam/xlog.c:7365 +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 #, c-format msgid "WAL ends before end of online backup" msgstr "WAL закончилÑÑ Ð±ÐµÐ· признака Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ" -#: access/transam/xlog.c:7362 +#: access/transam/xlog.c:7511 #, c-format msgid "" "All WAL generated while online backup was taken must be available at " @@ -2795,7 +2642,7 @@ msgstr "" "Ð’Ñе журналы WAL, Ñозданные во Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\", " "должны быть в наличии Ð´Ð»Ñ Ð²Ð¾ÑÑтановлениÑ." -#: access/transam/xlog.c:7366 +#: access/transam/xlog.c:7515 #, c-format msgid "" "Online backup started with pg_start_backup() must be ended with " @@ -2805,137 +2652,117 @@ msgstr "" "должно закончитьÑÑ pg_stop_backup(), и Ð´Ð»Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть " "доÑтупны вÑе журналы WAL." -#: access/transam/xlog.c:7369 +#: access/transam/xlog.c:7518 #, c-format msgid "WAL ends before consistent recovery point" msgstr "WAL закончилÑÑ Ð´Ð¾ ÑоглаÑованной точки воÑÑтановлениÑ" -#: access/transam/xlog.c:7396 +#: access/transam/xlog.c:7552 #, c-format msgid "selected new timeline ID: %u" msgstr "выбранный ID новой линии времени: %u" -#: access/transam/xlog.c:7825 +#: access/transam/xlog.c:7989 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "ÑоглаÑованное ÑоÑтоÑние воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтигнуто по Ñмещению %X/%X" -#: access/transam/xlog.c:8017 +#: access/transam/xlog.c:8181 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑылка на первичную контрольную точку в файле pg_control" -#: access/transam/xlog.c:8021 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑылка на вторичную контрольную точку в файле pg_control" - -#: access/transam/xlog.c:8025 +#: access/transam/xlog.c:8185 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑылка на контрольную точку в файле backup_label" -#: access/transam/xlog.c:8042 +#: access/transam/xlog.c:8202 #, c-format msgid "invalid primary checkpoint record" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ первичной контрольной точки" -#: access/transam/xlog.c:8046 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ вторичной контрольной точки" - -#: access/transam/xlog.c:8050 +#: access/transam/xlog.c:8206 #, c-format msgid "invalid checkpoint record" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ контрольной точки" -#: access/transam/xlog.c:8061 +#: access/transam/xlog.c:8217 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "неверный ID менеджера реÑурÑов в запиÑи первичной контрольной точки" -#: access/transam/xlog.c:8065 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "неверный ID менеджера реÑурÑов в запиÑи вторичной контрольной точки" - -#: access/transam/xlog.c:8069 +#: access/transam/xlog.c:8221 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "неверный ID менеджера реÑурÑов в запиÑи контрольной точки" -#: access/transam/xlog.c:8082 +#: access/transam/xlog.c:8234 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "неверные флаги xl_info в запиÑи первичной контрольной точки" -#: access/transam/xlog.c:8086 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "неверные флаги xl_info в запиÑи вторичной контрольной точки" - -#: access/transam/xlog.c:8090 +#: access/transam/xlog.c:8238 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "неверные флаги xl_info в запиÑи контрольной точки" -#: access/transam/xlog.c:8101 +#: access/transam/xlog.c:8249 #, c-format msgid "invalid length of primary checkpoint record" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи первичной контрольной точки" -#: access/transam/xlog.c:8105 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи вторичной контрольной точки" - -#: access/transam/xlog.c:8109 +#: access/transam/xlog.c:8253 #, c-format msgid "invalid length of checkpoint record" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи контрольной точки" -#: access/transam/xlog.c:8312 +#: access/transam/xlog.c:8459 #, c-format msgid "shutting down" msgstr "выключение" -#: access/transam/xlog.c:8620 +#: access/transam/xlog.c:8779 #, c-format -msgid "checkpoint skipped due to an idle system" +msgid "checkpoint skipped because system is idle" msgstr "ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° пропущена ввиду проÑÑ‚Ð¾Ñ ÑиÑтемы" -#: access/transam/xlog.c:8825 +#: access/transam/xlog.c:8984 #, c-format msgid "" -"concurrent transaction log activity while database system is shutting down" +"concurrent write-ahead log activity while database system is shutting down" msgstr "" "во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÑиÑтемы баз данных отмечена активноÑть в журнале " -"транзакций" +"предзапиÑи" -#: access/transam/xlog.c:9079 +#: access/transam/xlog.c:9241 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "" "Ñоздание точки перезапуÑка пропуÑкаетÑÑ, воÑÑтановление уже закончилоÑÑŒ" -#: access/transam/xlog.c:9102 +#: access/transam/xlog.c:9264 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "" "Ñоздание точки перезапуÑка пропуÑкаетÑÑ, она уже Ñоздана по Ñмещению %X/%X" -#: access/transam/xlog.c:9278 +#: access/transam/xlog.c:9431 #, c-format msgid "recovery restart point at %X/%X" msgstr "точка перезапуÑка воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ Ñмещению %X/%X" -#: access/transam/xlog.c:9414 +#: access/transam/xlog.c:9433 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "ПоÑледнÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð±Ñ‹Ð»Ð° выполнена в %s." + +#: access/transam/xlog.c:9567 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "точка воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" Ñоздана по Ñмещению %X/%X" -#: access/transam/xlog.c:9544 +#: access/transam/xlog.c:9705 #, c-format msgid "" "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint " @@ -2944,13 +2771,13 @@ msgstr "" "неожиданный ID предыдущей линии времени %u (ID текущей линии времени %u) в " "запиÑи контрольной точки" -#: access/transam/xlog.c:9553 +#: access/transam/xlog.c:9714 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "неожиданный ID линии времени %u (поÑле %u) в запиÑи контрольной точки" # skip-rule: capital-letter-first -#: access/transam/xlog.c:9569 +#: access/transam/xlog.c:9730 #, c-format msgid "" "unexpected timeline ID %u in checkpoint record, before reaching minimum " @@ -2959,79 +2786,79 @@ msgstr "" "неожиданный ID линии времени %u в запиÑи контрольной точки, до доÑÑ‚Ð¸Ð¶ÐµÐ½Ð¸Ñ " "минимальной к. Ñ‚. %X/%X на линии времени %u" -#: access/transam/xlog.c:9644 +#: access/transam/xlog.c:9806 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "" "резервное копирование \"на ходу\" было отменено, продолжить воÑÑтановление " "нельзÑ" -#: access/transam/xlog.c:9700 access/transam/xlog.c:9747 -#: access/transam/xlog.c:9770 +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 +#: access/transam/xlog.c:9941 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "" "неожиданный ID линии времени %u (должен быть %u) в запиÑи точки " "воÑÑтановлениÑ" -#: access/transam/xlog.c:10046 +#: access/transam/xlog.c:10222 #, c-format msgid "could not fsync log segment %s: %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ Ñегмент журнала %s: %m" -#: access/transam/xlog.c:10071 +#: access/transam/xlog.c:10247 #, c-format msgid "could not fsync log file %s: %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл журнала %s: %m" -#: access/transam/xlog.c:10079 +#: access/transam/xlog.c:10255 #, c-format msgid "could not fsync write-through log file %s: %m" msgstr "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл журнала Ñквозной запиÑи %s: %m" -#: access/transam/xlog.c:10088 +#: access/transam/xlog.c:10264 #, c-format msgid "could not fdatasync log file %s: %m" msgstr "" "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ данные (fdatasync) файла журнала %s: %m" -#: access/transam/xlog.c:10179 access/transam/xlog.c:10696 -#: access/transam/xlogfuncs.c:296 access/transam/xlogfuncs.c:323 -#: access/transam/xlogfuncs.c:362 access/transam/xlogfuncs.c:383 -#: access/transam/xlogfuncs.c:404 +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 +#: access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 +#: access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 +#: access/transam/xlogfuncs.c:395 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "Функции ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ WAL Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в процеÑÑе воÑÑтановлениÑ." -#: access/transam/xlog.c:10188 access/transam/xlog.c:10705 +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "" "Выбранный уровень WAL недоÑтаточен Ð´Ð»Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\"" -#: access/transam/xlog.c:10189 access/transam/xlog.c:10706 -#: access/transam/xlogfuncs.c:329 +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 +#: access/transam/xlogfuncs.c:320 #, c-format msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "УÑтановите wal_level \"replica\" или \"logical\" при запуÑке Ñервера." -#: access/transam/xlog.c:10194 +#: access/transam/xlog.c:10370 #, c-format msgid "backup label too long (max %d bytes)" msgstr "длина метки резервной копии превышает предел (%d байт)" -#: access/transam/xlog.c:10231 access/transam/xlog.c:10503 -#: access/transam/xlog.c:10541 +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 +#: access/transam/xlog.c:10721 #, c-format msgid "a backup is already in progress" msgstr "резервное копирование уже выполнÑетÑÑ" -#: access/transam/xlog.c:10232 +#: access/transam/xlog.c:10408 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "Выполните pg_stop_backup() и повторите операцию." -#: access/transam/xlog.c:10327 +#: access/transam/xlog.c:10504 #, c-format msgid "" "WAL generated with full_page_writes=off was replayed since last restartpoint" @@ -3039,7 +2866,7 @@ msgstr "" "ПоÑле поÑледней точки перезапуÑка был воÑпроизведён WAL, Ñозданный в режиме " "full_page_writes=off." -#: access/transam/xlog.c:10329 access/transam/xlog.c:10886 +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 #, c-format msgid "" "This means that the backup being taken on the standby is corrupt and should " @@ -3051,39 +2878,39 @@ msgstr "" "CHECKPOINT на главном Ñервере, а затем попробуйте резервное копирование \"на " "ходу\" ещё раз." -#: access/transam/xlog.c:10396 replication/basebackup.c:1096 -#: utils/adt/misc.c:497 +#: access/transam/xlog.c:10574 replication/basebackup.c:1232 +#: utils/adt/misc.c:517 #, c-format msgid "could not read symbolic link \"%s\": %m" msgstr "не удалоÑÑŒ прочитать ÑимволичеÑкую ÑÑылку \"%s\": %m" -#: access/transam/xlog.c:10403 replication/basebackup.c:1101 -#: utils/adt/misc.c:502 +#: access/transam/xlog.c:10581 replication/basebackup.c:1237 +#: utils/adt/misc.c:522 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "целевой путь ÑимволичеÑкой ÑÑылки \"%s\" Ñлишком длинный" -#: access/transam/xlog.c:10456 commands/tablespace.c:389 -#: commands/tablespace.c:551 replication/basebackup.c:1116 utils/adt/misc.c:510 +#: access/transam/xlog.c:10633 commands/tablespace.c:391 +#: commands/tablespace.c:553 replication/basebackup.c:1252 utils/adt/misc.c:530 #, c-format msgid "tablespaces are not supported on this platform" msgstr "табличные проÑтранÑтва не поддерживаютÑÑ Ð½Ð° Ñтой платформе" -#: access/transam/xlog.c:10497 access/transam/xlog.c:10535 -#: access/transam/xlog.c:10744 access/transam/xlogarchive.c:105 -#: access/transam/xlogarchive.c:264 commands/copy.c:1872 commands/copy.c:3052 -#: commands/extension.c:3314 commands/tablespace.c:780 -#: commands/tablespace.c:871 replication/basebackup.c:480 -#: replication/basebackup.c:548 replication/logical/snapbuild.c:1509 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2954 -#: storage/file/fd.c:3046 utils/adt/dbsize.c:70 utils/adt/dbsize.c:227 -#: utils/adt/dbsize.c:307 utils/adt/genfile.c:115 utils/adt/genfile.c:334 -#: guc-file.l:1001 +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 +#: access/transam/xlog.c:10930 access/transam/xlogarchive.c:104 +#: access/transam/xlogarchive.c:264 commands/copy.c:1890 commands/copy.c:3206 +#: commands/extension.c:3326 commands/tablespace.c:782 +#: commands/tablespace.c:873 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1528 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1752 +#: storage/file/fd.c:3132 storage/file/fd.c:3314 storage/file/fd.c:3399 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:131 utils/adt/genfile.c:382 guc-file.l:1003 #, c-format msgid "could not stat file \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о файле \"%s\": %m" -#: access/transam/xlog.c:10504 access/transam/xlog.c:10542 +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 #, c-format msgid "" "If you're sure there is no backup in progress, remove file \"%s\" and try " @@ -3092,37 +2919,38 @@ msgstr "" "ЕÑли вы Ñчитаете, что Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ резервном копировании неверна, удалите " "файл \"%s\" и попробуйте Ñнова." -#: access/transam/xlog.c:10521 access/transam/xlog.c:10559 -#: access/transam/xlog.c:10947 postmaster/syslogger.c:1391 -#: postmaster/syslogger.c:1404 +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 +#: access/transam/xlog.c:11150 postmaster/syslogger.c:1493 +#: postmaster/syslogger.c:1506 #, c-format msgid "could not write file \"%s\": %m" msgstr "не удалоÑÑŒ запиÑать файл \"%s\": %m" -#: access/transam/xlog.c:10721 +#: access/transam/xlog.c:10907 #, c-format msgid "exclusive backup not in progress" msgstr "монопольное резервное копирование не выполнÑетÑÑ" -#: access/transam/xlog.c:10748 +#: access/transam/xlog.c:10934 #, c-format msgid "a backup is not in progress" msgstr "резервное копирование не выполнÑетÑÑ" -#: access/transam/xlog.c:10821 access/transam/xlog.c:10834 -#: access/transam/xlog.c:11175 access/transam/xlog.c:11181 -#: access/transam/xlog.c:11265 access/transam/xlogfuncs.c:697 +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 +#: access/transam/xlog.c:11394 access/transam/xlog.c:11400 +#: access/transam/xlog.c:11448 access/transam/xlog.c:11521 +#: access/transam/xlogfuncs.c:688 #, c-format msgid "invalid data in file \"%s\"" msgstr "неверные данные в файле \"%s\"" -#: access/transam/xlog.c:10838 replication/basebackup.c:994 +#: access/transam/xlog.c:11037 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "" "дежурный Ñервер был повышен в процеÑÑе резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\"" -#: access/transam/xlog.c:10839 replication/basebackup.c:995 +#: access/transam/xlog.c:11038 replication/basebackup.c:1090 #, c-format msgid "" "This means that the backup being taken is corrupt and should not be used. " @@ -3131,7 +2959,7 @@ msgstr "" "Это означает, что ÑÐ¾Ð·Ð´Ð°Ð²Ð°ÐµÐ¼Ð°Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð¸Ñпорчена и иÑпользовать её не " "Ñледует. Попробуйте резервное копирование \"на ходу\" ещё раз." -#: access/transam/xlog.c:10884 +#: access/transam/xlog.c:11085 #, c-format msgid "" "WAL generated with full_page_writes=off was replayed during online backup" @@ -3139,7 +2967,7 @@ msgstr "" "Ð’ процеÑÑе резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\" был воÑпроизведён WAL, " "Ñозданный в режиме full_page_writes=off" -#: access/transam/xlog.c:10997 +#: access/transam/xlog.c:11205 #, c-format msgid "" "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" @@ -3147,16 +2975,16 @@ msgstr "" "очиÑтка в pg_stop_backup выполнена, ожидаютÑÑ Ñ‚Ñ€ÐµÐ±ÑƒÐµÐ¼Ñ‹Ðµ Ñегменты WAL Ð´Ð»Ñ " "архивации" -#: access/transam/xlog.c:11007 +#: access/transam/xlog.c:11215 #, c-format msgid "" -"pg_stop_backup still waiting for all required WAL segments to be archived " -"(%d seconds elapsed)" +"pg_stop_backup still waiting for all required WAL segments to be archived (" +"%d seconds elapsed)" msgstr "" "pg_stop_backup вÑÑ‘ ещё ждёт вÑе требуемые Ñегменты WAL Ð´Ð»Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ð¸ (прошло " "%d Ñек.)" -#: access/transam/xlog.c:11009 +#: access/transam/xlog.c:11217 #, c-format msgid "" "Check that your archive_command is executing properly. pg_stop_backup can " @@ -3167,13 +2995,13 @@ msgstr "" "можно отменить безопаÑно, но Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ Ð±Ð°Ð·Ñ‹ данных будет непригодна " "без вÑех Ñегментов WAL." -#: access/transam/xlog.c:11016 +#: access/transam/xlog.c:11224 #, c-format msgid "pg_stop_backup complete, all required WAL segments have been archived" msgstr "" "команда pg_stop_backup завершена, вÑе требуемые Ñегменты WAL заархивированы" -#: access/transam/xlog.c:11020 +#: access/transam/xlog.c:11228 #, c-format msgid "" "WAL archiving is not enabled; you must ensure that all required WAL segments " @@ -3182,66 +3010,86 @@ msgstr "" "Ð°Ñ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ñ WAL не наÑтроена; вы должны обеÑпечить копирование вÑех требуемых " "Ñегментов WAL другими ÑредÑтвами Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð¹ копии" +#: access/transam/xlog.c:11431 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ %s в файле \"%s\"" + +#: access/transam/xlog.c:11436 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "метка резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ %s в файле \"%s\"" + +#: access/transam/xlog.c:11449 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "Получен идентификатор линии времени %u, но ожидалÑÑ %u" + +#: access/transam/xlog.c:11453 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ резервной копии %u в файле \"%s\"" + #. translator: %s is a WAL record description -#: access/transam/xlog.c:11305 +#: access/transam/xlog.c:11561 #, c-format msgid "WAL redo at %X/%X for %s" msgstr "запиÑÑŒ REDO в WAL в позиции %X/%X Ð´Ð»Ñ %s" -#: access/transam/xlog.c:11354 +#: access/transam/xlog.c:11610 #, c-format msgid "online backup mode was not canceled" msgstr "режим ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\" не был отменён" -#: access/transam/xlog.c:11355 +#: access/transam/xlog.c:11611 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "Ðе удалоÑÑŒ переименовать файл \"%s\" в \"%s\": %m." -#: access/transam/xlog.c:11364 access/transam/xlog.c:11376 -#: access/transam/xlog.c:11386 +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 +#: access/transam/xlog.c:11642 #, c-format msgid "online backup mode canceled" msgstr "режим ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"на ходу\" отменён" -#: access/transam/xlog.c:11377 +#: access/transam/xlog.c:11633 #, c-format msgid "" "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "" "Файлы \"%s\" и \"%s\" были переименованы в \"%s\" и \"%s\", ÑоответÑтвенно." -#: access/transam/xlog.c:11387 +#: access/transam/xlog.c:11643 #, c-format msgid "" -"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to " -"\"%s\": %m." +"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"" +"%s\": %m." msgstr "" "Файл \"%s\" был переименован в \"%s\", но переименовать \"%s\" в \"%s\" не " "удалоÑÑŒ: %m." -#: access/transam/xlog.c:11509 access/transam/xlogutils.c:724 -#: replication/walreceiver.c:1006 replication/walsender.c:2326 +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 +#: replication/walreceiver.c:1019 replication/walsender.c:2427 #, c-format msgid "could not seek in log segment %s to offset %u: %m" msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð² Ñегменте журнала %s к Ñмещению %u: %m" -#: access/transam/xlog.c:11523 +#: access/transam/xlog.c:11785 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "не удалоÑÑŒ прочитать Ñегмент журнала %s, Ñмещение %u: %m" -#: access/transam/xlog.c:12012 +#: access/transam/xlog.c:12314 #, c-format msgid "received promote request" msgstr "получен Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ ÑтатуÑа" -#: access/transam/xlog.c:12025 +#: access/transam/xlog.c:12327 #, c-format msgid "trigger file found: %s" msgstr "найден файл триггера: %s" -#: access/transam/xlog.c:12034 +#: access/transam/xlog.c:12336 #, c-format msgid "could not stat trigger file \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о файле триггера \"%s\": %m" @@ -3256,7 +3104,7 @@ msgstr "файл архива \"%s\" имеет неправильный раз msgid "restored log file \"%s\" from archive" msgstr "файл журнала \"%s\" воÑÑтановлен из архива" -#: access/transam/xlogarchive.c:302 +#: access/transam/xlogarchive.c:297 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "воÑÑтановить файл \"%s\" из архива не удалоÑÑŒ: %s" @@ -3264,194 +3112,184 @@ msgstr "воÑÑтановить файл \"%s\" из архива не удал #. translator: First %s represents a recovery.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:414 +#: access/transam/xlogarchive.c:406 #, c-format msgid "%s \"%s\": %s" msgstr "%s \"%s\": %s" -#: access/transam/xlogarchive.c:457 postmaster/syslogger.c:1415 -#: replication/logical/snapbuild.c:1641 replication/slot.c:518 -#: replication/slot.c:1118 replication/slot.c:1232 storage/file/fd.c:642 -#: storage/file/fd.c:737 utils/time/snapmgr.c:1298 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1517 +#: replication/logical/snapbuild.c:1667 replication/slot.c:598 +#: replication/slot.c:1211 replication/slot.c:1326 storage/file/fd.c:669 +#: storage/file/fd.c:764 utils/time/snapmgr.c:1318 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "не удалоÑÑŒ переименовать файл \"%s\" в \"%s\": %m" -#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать файл ÑоÑтоÑÐ½Ð¸Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð° \"%s\": %m" -#: access/transam/xlogarchive.c:532 access/transam/xlogarchive.c:596 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "не удалоÑÑŒ запиÑать файл ÑоÑтоÑÐ½Ð¸Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð° \"%s\": %m" -#: access/transam/xlogfuncs.c:55 +#: access/transam/xlogfuncs.c:54 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "" "прерывание резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·-за Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ð±Ñлуживающего процеÑÑа " "до вызова pg_stop_backup" -#: access/transam/xlogfuncs.c:86 +#: access/transam/xlogfuncs.c:84 #, c-format msgid "a backup is already in progress in this session" msgstr "резервное копирование уже выполнÑетÑÑ Ð² Ñтом ÑеанÑе" -#: access/transam/xlogfuncs.c:92 commands/tablespace.c:703 -#: commands/tablespace.c:713 postmaster/postmaster.c:1434 -#: replication/basebackup.c:368 replication/basebackup.c:708 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2420 -#: storage/file/fd.c:3019 storage/ipc/dsm.c:301 utils/adt/genfile.c:440 -#: utils/adt/misc.c:410 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "не удалоÑÑŒ открыть каталог \"%s\": %m" - -#: access/transam/xlogfuncs.c:152 access/transam/xlogfuncs.c:233 +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 #, c-format msgid "non-exclusive backup in progress" msgstr "выполнÑетÑÑ Ð½Ðµ монопольное резервное копирование" -#: access/transam/xlogfuncs.c:153 access/transam/xlogfuncs.c:234 +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 #, c-format msgid "Did you mean to use pg_stop_backup('f')?" msgstr "ВероÑтно, подразумевалоÑÑŒ pg_stop_backup('f')?" -#: access/transam/xlogfuncs.c:204 commands/event_trigger.c:1453 -#: commands/event_trigger.c:2004 commands/extension.c:1891 -#: commands/extension.c:2000 commands/extension.c:2224 commands/prepare.c:721 -#: executor/execExpr.c:2088 executor/execSRF.c:686 executor/functions.c:1028 -#: foreign/foreign.c:488 libpq/hba.c:2560 replication/logical/launcher.c:762 -#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1384 -#: replication/slotfuncs.c:196 replication/walsender.c:3019 -#: utils/adt/jsonfuncs.c:1515 utils/adt/jsonfuncs.c:1645 -#: utils/adt/jsonfuncs.c:1833 utils/adt/jsonfuncs.c:1960 -#: utils/adt/jsonfuncs.c:2726 utils/adt/pgstatfuncs.c:456 -#: utils/adt/pgstatfuncs.c:557 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8520 -#: utils/mmgr/portalmem.c:1053 +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 +#: commands/event_trigger.c:2016 commands/extension.c:1902 +#: commands/extension.c:2011 commands/extension.c:2235 commands/prepare.c:722 +#: executor/execExpr.c:2209 executor/execSRF.c:715 executor/functions.c:1034 +#: foreign/foreign.c:488 libpq/hba.c:2603 replication/logical/launcher.c:1127 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1460 +#: replication/slotfuncs.c:200 replication/walsender.c:3206 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 +#: utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8833 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво, вызвана в контекÑте, где ему нет меÑта" -#: access/transam/xlogfuncs.c:208 commands/event_trigger.c:1457 -#: commands/event_trigger.c:2008 commands/extension.c:1895 -#: commands/extension.c:2004 commands/extension.c:2228 commands/prepare.c:725 -#: foreign/foreign.c:493 libpq/hba.c:2564 replication/logical/launcher.c:766 -#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1388 -#: replication/slotfuncs.c:200 replication/walsender.c:3023 -#: utils/adt/pgstatfuncs.c:460 utils/adt/pgstatfuncs.c:561 -#: utils/misc/guc.c:8524 utils/misc/pg_config.c:44 utils/mmgr/portalmem.c:1057 +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 +#: commands/event_trigger.c:2020 commands/extension.c:1906 +#: commands/extension.c:2015 commands/extension.c:2239 commands/prepare.c:726 +#: foreign/foreign.c:493 libpq/hba.c:2607 replication/logical/launcher.c:1131 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 +#: replication/slotfuncs.c:204 replication/walsender.c:3210 +#: utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 +#: utils/misc/guc.c:8837 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "требуетÑÑ Ñ€ÐµÐ¶Ð¸Ð¼ материализации, но он недопуÑтим в Ñтом контекÑте" -#: access/transam/xlogfuncs.c:250 +#: access/transam/xlogfuncs.c:241 #, c-format msgid "non-exclusive backup is not in progress" msgstr "немонопольное резервное копирование не выполнÑетÑÑ" -#: access/transam/xlogfuncs.c:251 +#: access/transam/xlogfuncs.c:242 #, c-format msgid "Did you mean to use pg_stop_backup('t')?" msgstr "ВероÑтно, подразумевалоÑÑŒ pg_stop_backup('t')?" -#: access/transam/xlogfuncs.c:328 +#: access/transam/xlogfuncs.c:319 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "Выбранный уровень WAL не доÑтаточен Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ воÑÑтановлениÑ" # well-spelled: Ñимв -#: access/transam/xlogfuncs.c:336 +#: access/transam/xlogfuncs.c:327 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "значение Ð´Ð»Ñ Ñ‚Ð¾Ñ‡ÐºÐ¸ воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ²Ñ‹ÑˆÐ°ÐµÑ‚ предел (%d Ñимв.)" -#: access/transam/xlogfuncs.c:474 +#: access/transam/xlogfuncs.c:465 #, c-format msgid "pg_walfile_name_offset() cannot be executed during recovery." msgstr "" "Функцию pg_walfile_name_offset() Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ во Ð²Ñ€ÐµÐ¼Ñ Ð²Ð¾ÑÑтановлениÑ." -#: access/transam/xlogfuncs.c:530 +#: access/transam/xlogfuncs.c:521 #, c-format msgid "pg_walfile_name() cannot be executed during recovery." msgstr "Функцию pg_walfile_name() Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ в процеÑÑе воÑÑтановлениÑ." -#: access/transam/xlogfuncs.c:550 access/transam/xlogfuncs.c:570 -#: access/transam/xlogfuncs.c:587 +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 +#: access/transam/xlogfuncs.c:578 #, c-format msgid "recovery is not in progress" msgstr "воÑÑтановление не выполнÑетÑÑ" -#: access/transam/xlogfuncs.c:551 access/transam/xlogfuncs.c:571 -#: access/transam/xlogfuncs.c:588 +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 +#: access/transam/xlogfuncs.c:579 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "" "Функции ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾ÑÑтановлением можно иÑпользовать только в процеÑÑе " "воÑÑтановлениÑ." -#: access/transam/xlogreader.c:276 +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "неверное Ñмещение запиÑи: %X/%X" -#: access/transam/xlogreader.c:284 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "по Ñмещению %X/%X запрошено продолжение запиÑи" -#: access/transam/xlogreader.c:325 access/transam/xlogreader.c:625 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи по Ñмещению %X/%X: ожидалоÑÑŒ %u, получено %u" -#: access/transam/xlogreader.c:340 +#: access/transam/xlogreader.c:363 #, c-format msgid "record length %u at %X/%X too long" msgstr "длина запиÑи %u по Ñмещению %X/%X Ñлишком велика" -#: access/transam/xlogreader.c:381 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "нет флага contrecord в позиции %X/%X" -#: access/transam/xlogreader.c:394 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° contrecord (%u) в позиции %X/%X" -#: access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:654 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "неверный ID менеджера реÑурÑов %u по Ñмещению %X/%X" -#: access/transam/xlogreader.c:647 access/transam/xlogreader.c:664 +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "запиÑÑŒ Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ ÑÑылкой назад %X/%X по Ñмещению %X/%X" -#: access/transam/xlogreader.c:701 +#: access/transam/xlogreader.c:722 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "" "Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма данных менеджера реÑурÑов в запиÑи по " "Ñмещению %X/%X" -#: access/transam/xlogreader.c:734 +#: access/transam/xlogreader.c:759 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "неверное магичеÑкое чиÑло %04X в Ñегменте журнала %s, Ñмещение %u" -#: access/transam/xlogreader.c:748 access/transam/xlogreader.c:799 +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "неверные информационные биты %04X в Ñегменте журнала %s, Ñмещение %u" -#: access/transam/xlogreader.c:774 +#: access/transam/xlogreader.c:799 #, c-format msgid "" "WAL file is from different database system: WAL file database system " @@ -3460,16 +3298,16 @@ msgstr "" "файл WAL принадлежит другой СУБД: в нём указан идентификатор ÑиÑтемы БД %s, " "а идентификатор ÑиÑтемы pg_control: %s" -#: access/transam/xlogreader.c:781 +#: access/transam/xlogreader.c:806 #, c-format msgid "" -"WAL file is from different database system: incorrect XLOG_SEG_SIZE in page " +"WAL file is from different database system: incorrect segment size in page " "header" msgstr "" -"файл WAL принадлежит другой СУБД: некорректный XLOG_SEG_SIZE в заголовке " +"файл WAL принадлежит другой СУБД: некорректный размер Ñегмента в заголовке " "Ñтраницы" -#: access/transam/xlogreader.c:787 +#: access/transam/xlogreader.c:812 #, c-format msgid "" "WAL file is from different database system: incorrect XLOG_BLCKSZ in page " @@ -3478,35 +3316,35 @@ msgstr "" "файл WAL принадлежит другой СУБД: некорректный XLOG_BLCKSZ в заголовке " "Ñтраницы" -#: access/transam/xlogreader.c:813 +#: access/transam/xlogreader.c:843 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "неожиданный pageaddr %X/%X в Ñегменте журнала %s, Ñмещение %u" -#: access/transam/xlogreader.c:838 +#: access/transam/xlogreader.c:868 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "" "нарушение поÑледовательноÑти ID линии времени %u (поÑле %u) в Ñегменте " "журнала %s, Ñмещение %u" -#: access/transam/xlogreader.c:1083 +#: access/transam/xlogreader.c:1113 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "идентификатор блока %u идёт не по порÑдку в позиции %X/%X" -#: access/transam/xlogreader.c:1106 +#: access/transam/xlogreader.c:1136 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA уÑтановлен, но данных в позиции %X/%X нет" -#: access/transam/xlogreader.c:1113 +#: access/transam/xlogreader.c:1143 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "" "BKPBLOCK_HAS_DATA не уÑтановлен, но длина данных равна %u в позиции %X/%X" -#: access/transam/xlogreader.c:1149 +#: access/transam/xlogreader.c:1179 #, c-format msgid "" "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " @@ -3515,21 +3353,21 @@ msgstr "" "BKPIMAGE_HAS_HOLE уÑтановлен, но Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑка заданы Ñмещение %u и длина %u " "при длине образа блока %u в позиции %X/%X" -#: access/transam/xlogreader.c:1165 +#: access/transam/xlogreader.c:1195 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "" "BKPIMAGE_HAS_HOLE не уÑтановлен, но Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑка заданы Ñмещение %u и длина " "%u в позиции %X/%X" -#: access/transam/xlogreader.c:1180 +#: access/transam/xlogreader.c:1210 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "" "BKPIMAGE_IS_COMPRESSED уÑтановлен, но длина образа блока равна %u в позиции " "%X/%X" -#: access/transam/xlogreader.c:1195 +#: access/transam/xlogreader.c:1225 #, c-format msgid "" "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " @@ -3538,50 +3376,56 @@ msgstr "" "ни BKPIMAGE_HAS_HOLE, ни BKPIMAGE_IS_COMPRESSED не уÑтановлены, но длина " "образа блока равна %u в позиции %X/%X" -#: access/transam/xlogreader.c:1211 +#: access/transam/xlogreader.c:1241 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "" "BKPBLOCK_SAME_REL уÑтановлен, но предыдущее значение не задано в позиции %X/" "%X" -#: access/transam/xlogreader.c:1223 +#: access/transam/xlogreader.c:1253 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "неверный идентификатор блока %u в позиции %X/%X" -#: access/transam/xlogreader.c:1291 +#: access/transam/xlogreader.c:1342 #, c-format msgid "record with invalid length at %X/%X" msgstr "запиÑÑŒ Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ длиной в позиции %X/%X" -#: access/transam/xlogreader.c:1380 +#: access/transam/xlogreader.c:1431 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "неверный Ñжатый образ в позиции %X/%X, блок %d" -#: access/transam/xlogutils.c:747 replication/walsender.c:2345 +#: access/transam/xlogutils.c:751 replication/walsender.c:2446 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "не удалоÑÑŒ прочитать Ñегмент журнала %s (Ñмещение %u, длина %lu): %m" -#: bootstrap/bootstrap.c:271 postmaster/postmaster.c:801 tcop/postgres.c:3495 +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "" +"Ð´Ð»Ñ -X требуетÑÑ Ñ‡Ð¸Ñло, равное Ñтепени двух, в интервале от 1 МБ до 1 ГБ" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:827 tcop/postgres.c:3581 #, c-format msgid "--%s requires a value" msgstr "Ð´Ð»Ñ --%s требуетÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ" -#: bootstrap/bootstrap.c:276 postmaster/postmaster.c:806 tcop/postgres.c:3500 +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:832 tcop/postgres.c:3586 #, c-format msgid "-c %s requires a value" msgstr "Ð´Ð»Ñ -c %s требуетÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ" -#: bootstrap/bootstrap.c:287 postmaster/postmaster.c:818 -#: postmaster/postmaster.c:831 +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:844 +#: postmaster/postmaster.c:857 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: bootstrap/bootstrap.c:296 +#: bootstrap/bootstrap.c:310 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: неверные аргументы командной Ñтроки\n" @@ -3633,184 +3477,192 @@ msgstr "Ð´Ð»Ñ Ñтолбца \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" были отоз msgid "not all privileges could be revoked for \"%s\"" msgstr "Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° \"%s\" были отозваны не вÑе права" -#: catalog/aclchk.c:455 catalog/aclchk.c:948 +#: catalog/aclchk.c:456 catalog/aclchk.c:995 #, c-format msgid "invalid privilege type %s for relation" msgstr "право %s неприменимо Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹" -#: catalog/aclchk.c:459 catalog/aclchk.c:952 +#: catalog/aclchk.c:460 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for sequence" msgstr "право %s неприменимо Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑтей" -#: catalog/aclchk.c:463 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "право %s неприменимо Ð´Ð»Ñ Ð±Ð°Ð· данных" -#: catalog/aclchk.c:467 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "право %s неприменимо Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°" -#: catalog/aclchk.c:471 catalog/aclchk.c:956 +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for function" msgstr "право %s неприменимо Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹" -#: catalog/aclchk.c:475 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "право %s неприменимо Ð´Ð»Ñ Ñзыков" -#: catalog/aclchk.c:479 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "право %s неприменимо Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов" -#: catalog/aclchk.c:483 catalog/aclchk.c:964 +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for schema" msgstr "право %s неприменимо Ð´Ð»Ñ Ñхем" -#: catalog/aclchk.c:487 +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "право %s неприменимо Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "право %s неприменимо Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "право %s неприменимо Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ñ‹Ñ… проÑтранÑтв" -#: catalog/aclchk.c:491 catalog/aclchk.c:960 +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 #, c-format msgid "invalid privilege type %s for type" msgstr "право %s неприменимо Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð°" -#: catalog/aclchk.c:495 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "право %s неприменимо Ð´Ð»Ñ Ð¾Ð±Ñ‘Ñ€Ñ‚Ð¾Ðº Ñторонних данных" -#: catalog/aclchk.c:499 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "право %s неприменимо Ð´Ð»Ñ Ñторонних Ñерверов" -#: catalog/aclchk.c:538 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "права Ð´Ð»Ñ Ñтолбцов применимы только к отношениÑм" -#: catalog/aclchk.c:696 catalog/aclchk.c:3926 catalog/aclchk.c:4708 -#: catalog/objectaddress.c:929 catalog/pg_largeobject.c:111 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 +#: catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 +#: storage/large_object/inv_api.c:284 #, c-format msgid "large object %u does not exist" msgstr "большой объект %u не ÑущеÑтвует" -#: catalog/aclchk.c:885 catalog/aclchk.c:894 commands/collationcmds.c:106 -#: commands/copy.c:1046 commands/copy.c:1066 commands/copy.c:1075 -#: commands/copy.c:1084 commands/copy.c:1093 commands/copy.c:1102 -#: commands/copy.c:1111 commands/copy.c:1120 commands/copy.c:1129 -#: commands/copy.c:1147 commands/copy.c:1163 commands/copy.c:1183 -#: commands/copy.c:1200 commands/dbcommands.c:155 commands/dbcommands.c:164 +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 +#: commands/copy.c:1063 commands/copy.c:1083 commands/copy.c:1092 +#: commands/copy.c:1101 commands/copy.c:1110 commands/copy.c:1119 +#: commands/copy.c:1128 commands/copy.c:1137 commands/copy.c:1146 +#: commands/copy.c:1164 commands/copy.c:1180 commands/copy.c:1200 +#: commands/copy.c:1217 commands/dbcommands.c:155 commands/dbcommands.c:164 #: commands/dbcommands.c:173 commands/dbcommands.c:182 #: commands/dbcommands.c:191 commands/dbcommands.c:200 #: commands/dbcommands.c:209 commands/dbcommands.c:218 #: commands/dbcommands.c:227 commands/dbcommands.c:1427 #: commands/dbcommands.c:1436 commands/dbcommands.c:1445 -#: commands/dbcommands.c:1454 commands/extension.c:1674 -#: commands/extension.c:1684 commands/extension.c:1694 -#: commands/extension.c:1704 commands/extension.c:2944 +#: commands/dbcommands.c:1454 commands/extension.c:1685 +#: commands/extension.c:1695 commands/extension.c:1705 +#: commands/extension.c:1715 commands/extension.c:2956 #: commands/foreigncmds.c:537 commands/foreigncmds.c:546 -#: commands/functioncmds.c:526 commands/functioncmds.c:643 -#: commands/functioncmds.c:652 commands/functioncmds.c:661 -#: commands/functioncmds.c:670 commands/functioncmds.c:2076 -#: commands/functioncmds.c:2084 commands/publicationcmds.c:89 -#: commands/publicationcmds.c:99 commands/publicationcmds.c:109 -#: commands/publicationcmds.c:119 commands/publicationcmds.c:129 -#: commands/publicationcmds.c:139 commands/sequence.c:1247 -#: commands/sequence.c:1256 commands/sequence.c:1265 commands/sequence.c:1274 -#: commands/sequence.c:1283 commands/sequence.c:1292 commands/sequence.c:1301 -#: commands/sequence.c:1310 commands/sequence.c:1319 -#: commands/subscriptioncmds.c:94 commands/subscriptioncmds.c:104 -#: commands/subscriptioncmds.c:114 commands/subscriptioncmds.c:124 -#: commands/subscriptioncmds.c:134 commands/subscriptioncmds.c:144 -#: commands/subscriptioncmds.c:153 commands/subscriptioncmds.c:163 -#: commands/typecmds.c:298 commands/typecmds.c:1375 commands/typecmds.c:1384 -#: commands/typecmds.c:1392 commands/typecmds.c:1400 commands/typecmds.c:1408 -#: commands/user.c:138 commands/user.c:161 commands/user.c:170 -#: commands/user.c:179 commands/user.c:188 commands/user.c:197 -#: commands/user.c:206 commands/user.c:215 commands/user.c:224 -#: commands/user.c:233 commands/user.c:242 commands/user.c:251 -#: commands/user.c:260 commands/user.c:547 commands/user.c:564 -#: commands/user.c:572 commands/user.c:580 commands/user.c:588 -#: commands/user.c:596 commands/user.c:604 commands/user.c:612 -#: commands/user.c:621 commands/user.c:629 commands/user.c:637 -#: replication/pgoutput/pgoutput.c:107 replication/pgoutput/pgoutput.c:128 -#: replication/walsender.c:797 replication/walsender.c:808 -#: replication/walsender.c:818 +#: commands/functioncmds.c:559 commands/functioncmds.c:684 +#: commands/functioncmds.c:693 commands/functioncmds.c:702 +#: commands/functioncmds.c:711 commands/functioncmds.c:2105 +#: commands/functioncmds.c:2113 commands/publicationcmds.c:92 +#: commands/sequence.c:1255 commands/sequence.c:1265 commands/sequence.c:1275 +#: commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 +#: commands/sequence.c:1315 commands/sequence.c:1325 commands/sequence.c:1335 +#: commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 +#: commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 +#: commands/subscriptioncmds.c:154 commands/subscriptioncmds.c:165 +#: commands/subscriptioncmds.c:179 commands/tablecmds.c:6303 +#: commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 +#: commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 +#: commands/user.c:134 commands/user.c:148 commands/user.c:157 +#: commands/user.c:166 commands/user.c:175 commands/user.c:184 +#: commands/user.c:193 commands/user.c:202 commands/user.c:211 +#: commands/user.c:220 commands/user.c:229 commands/user.c:238 +#: commands/user.c:247 commands/user.c:555 commands/user.c:563 +#: commands/user.c:571 commands/user.c:579 commands/user.c:587 +#: commands/user.c:595 commands/user.c:603 commands/user.c:611 +#: commands/user.c:620 commands/user.c:628 commands/user.c:636 +#: parser/parse_utilcmd.c:407 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 +#: replication/walsender.c:815 replication/walsender.c:825 #, c-format msgid "conflicting or redundant options" msgstr "конфликтующие или избыточные параметры" -#: catalog/aclchk.c:997 +#: catalog/aclchk.c:1052 #, c-format msgid "default privileges cannot be set for columns" msgstr "права по умолчанию Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ Ð´Ð»Ñ Ñтолбцов" -#: catalog/aclchk.c:1157 +#: catalog/aclchk.c:1212 #, c-format msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" msgstr "предложение IN SCHEMA Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в GRANT/REVOKE ON SCHEMAS" -#: catalog/aclchk.c:1521 catalog/objectaddress.c:1390 commands/analyze.c:390 -#: commands/copy.c:4671 commands/sequence.c:1625 commands/tablecmds.c:5530 -#: commands/tablecmds.c:5691 commands/tablecmds.c:5748 -#: commands/tablecmds.c:5862 commands/tablecmds.c:5916 -#: commands/tablecmds.c:6008 commands/tablecmds.c:6164 -#: commands/tablecmds.c:8385 commands/tablecmds.c:8661 -#: commands/tablecmds.c:9078 commands/trigger.c:739 parser/analyze.c:2308 -#: parser/parse_relation.c:2698 parser/parse_relation.c:2760 -#: parser/parse_target.c:1002 parser/parse_type.c:127 utils/adt/acl.c:2823 -#: utils/adt/ruleutils.c:2259 +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 +#: commands/copy.c:4826 commands/sequence.c:1690 commands/tablecmds.c:5949 +#: commands/tablecmds.c:6097 commands/tablecmds.c:6154 +#: commands/tablecmds.c:6228 commands/tablecmds.c:6322 +#: commands/tablecmds.c:6381 commands/tablecmds.c:6520 +#: commands/tablecmds.c:6602 commands/tablecmds.c:6694 +#: commands/tablecmds.c:6788 commands/tablecmds.c:9517 +#: commands/tablecmds.c:9811 commands/tablecmds.c:10292 commands/trigger.c:904 +#: parser/analyze.c:2343 parser/parse_relation.c:2735 +#: parser/parse_relation.c:2798 parser/parse_target.c:1030 +#: parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2465 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "Ñтолбец \"%s\" в таблице \"%s\" не ÑущеÑтвует" -#: catalog/aclchk.c:1787 catalog/objectaddress.c:1230 commands/sequence.c:1137 -#: commands/tablecmds.c:229 commands/tablecmds.c:12733 utils/adt/acl.c:2059 -#: utils/adt/acl.c:2089 utils/adt/acl.c:2121 utils/adt/acl.c:2153 -#: utils/adt/acl.c:2181 utils/adt/acl.c:2211 +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1128 +#: commands/tablecmds.c:231 commands/tablecmds.c:14095 utils/adt/acl.c:2076 +#: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 +#: utils/adt/acl.c:2198 utils/adt/acl.c:2228 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\" - Ñто не поÑледовательноÑть" -#: catalog/aclchk.c:1825 +#: catalog/aclchk.c:1881 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "" "Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑти \"%s\" применимы только права USAGE, SELECT и UPDATE" -#: catalog/aclchk.c:1842 +#: catalog/aclchk.c:1898 #, c-format msgid "invalid privilege type %s for table" msgstr "право %s неприменимо Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†" -#: catalog/aclchk.c:2008 +#: catalog/aclchk.c:2064 #, c-format msgid "invalid privilege type %s for column" msgstr "право %s неприменимо Ð´Ð»Ñ Ñтолбцов" -#: catalog/aclchk.c:2021 +#: catalog/aclchk.c:2077 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑти \"%s\" применимо только право SELECT" # TO REVIEW -#: catalog/aclchk.c:2603 +#: catalog/aclchk.c:2659 #, c-format msgid "language \"%s\" is not trusted" msgstr "Ñзык \"%s\" не ÑвлÑетÑÑ Ð´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼" -#: catalog/aclchk.c:2605 +#: catalog/aclchk.c:2661 #, c-format msgid "" "GRANT and REVOKE are not allowed on untrusted languages, because only " @@ -3819,410 +3671,500 @@ msgstr "" "GRANT и REVOKE не допуÑкаютÑÑ Ð´Ð»Ñ Ð½ÐµÐ´Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ñ… Ñзыков, так как иÑпользовать " "такие Ñзыки могут только Ñуперпользователи." -#: catalog/aclchk.c:3119 +#: catalog/aclchk.c:3175 #, c-format msgid "cannot set privileges of array types" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² маÑÑивов Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ права" -#: catalog/aclchk.c:3120 +#: catalog/aclchk.c:3176 #, c-format msgid "Set the privileges of the element type instead." msgstr "ВмеÑто Ñтого уÑтановите права Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° Ñлемента." -#: catalog/aclchk.c:3127 catalog/objectaddress.c:1520 commands/typecmds.c:3165 +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 #, c-format msgid "\"%s\" is not a domain" msgstr "\"%s\" - Ñто не домен" -#: catalog/aclchk.c:3247 +#: catalog/aclchk.c:3303 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "нераÑпознанное право: \"%s\"" -#: catalog/aclchk.c:3296 +#: catalog/aclchk.c:3364 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "нет доÑтупа к агрегату %s" + +#: catalog/aclchk.c:3367 #, c-format -msgid "permission denied for column %s" -msgstr "нет доÑтупа к Ñтолбцу %s" +msgid "permission denied for collation %s" +msgstr "нет доÑтупа к правилу Ñортировки %s" -#: catalog/aclchk.c:3298 +#: catalog/aclchk.c:3370 #, c-format -msgid "permission denied for relation %s" -msgstr "нет доÑтупа к отношению %s" +msgid "permission denied for column %s" +msgstr "нет доÑтупа к Ñтолбцу %s" -#: catalog/aclchk.c:3300 commands/sequence.c:599 commands/sequence.c:833 -#: commands/sequence.c:875 commands/sequence.c:916 commands/sequence.c:1671 -#: commands/sequence.c:1735 +#: catalog/aclchk.c:3373 #, c-format -msgid "permission denied for sequence %s" -msgstr "нет доÑтупа к поÑледовательноÑти %s" +msgid "permission denied for conversion %s" +msgstr "нет доÑтупа к преобразованию %s" -#: catalog/aclchk.c:3302 +#: catalog/aclchk.c:3376 #, c-format msgid "permission denied for database %s" msgstr "нет доÑтупа к базе данных %s" -#: catalog/aclchk.c:3304 +#: catalog/aclchk.c:3379 #, c-format -msgid "permission denied for function %s" -msgstr "нет доÑтупа к функции %s" +msgid "permission denied for domain %s" +msgstr "нет доÑтупа к домену %s" -#: catalog/aclchk.c:3306 +#: catalog/aclchk.c:3382 #, c-format -msgid "permission denied for operator %s" -msgstr "нет доÑтупа к оператору %s" +msgid "permission denied for event trigger %s" +msgstr "нет доÑтупа к Ñобытийному триггеру %s" -#: catalog/aclchk.c:3308 +#: catalog/aclchk.c:3385 #, c-format -msgid "permission denied for type %s" -msgstr "нет доÑтупа к типу %s" +msgid "permission denied for extension %s" +msgstr "нет доÑтупа к раÑширению %s" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "нет доÑтупа к обёртке Ñторонних данных %s" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "нет доÑтупа к Ñтороннему Ñерверу %s" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "нет доÑтупа к Ñторонней таблице %s" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "нет доÑтупа к функции %s" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "нет доÑтупа к индекÑу %s" -#: catalog/aclchk.c:3310 +#: catalog/aclchk.c:3403 #, c-format msgid "permission denied for language %s" msgstr "нет доÑтупа к Ñзыку %s" -#: catalog/aclchk.c:3312 +#: catalog/aclchk.c:3406 #, c-format msgid "permission denied for large object %s" msgstr "нет доÑтупа к большому объекту %s" -#: catalog/aclchk.c:3314 +#: catalog/aclchk.c:3409 #, c-format -msgid "permission denied for schema %s" -msgstr "нет доÑтупа к Ñхеме %s" +msgid "permission denied for materialized view %s" +msgstr "нет доÑтупа к материализованному предÑтавлению %s" -#: catalog/aclchk.c:3316 +#: catalog/aclchk.c:3412 #, c-format msgid "permission denied for operator class %s" msgstr "нет доÑтупа к клаÑÑу операторов %s" -#: catalog/aclchk.c:3318 +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "нет доÑтупа к оператору %s" + +#: catalog/aclchk.c:3418 #, c-format msgid "permission denied for operator family %s" msgstr "нет доÑтупа к ÑемейÑтву операторов %s" -#: catalog/aclchk.c:3320 +#: catalog/aclchk.c:3421 #, c-format -msgid "permission denied for collation %s" -msgstr "нет доÑтупа к правилу Ñортировки %s" +msgid "permission denied for policy %s" +msgstr "нет доÑтупа к политике %s" -#: catalog/aclchk.c:3322 +#: catalog/aclchk.c:3424 #, c-format -msgid "permission denied for conversion %s" -msgstr "нет доÑтупа к преобразованию %s" +msgid "permission denied for procedure %s" +msgstr "нет доÑтупа к процедуре %s" + +#: catalog/aclchk.c:3427 +#, c-format +msgid "permission denied for publication %s" +msgstr "нет доÑтупа к публикации %s" + +#: catalog/aclchk.c:3430 +#, c-format +msgid "permission denied for routine %s" +msgstr "нет доÑтупа к подпрограмме %s" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "нет доÑтупа к Ñхеме %s" + +#: catalog/aclchk.c:3436 commands/sequence.c:598 commands/sequence.c:832 +#: commands/sequence.c:874 commands/sequence.c:915 commands/sequence.c:1788 +#: commands/sequence.c:1852 +#, c-format +msgid "permission denied for sequence %s" +msgstr "нет доÑтупа к поÑледовательноÑти %s" + +#: catalog/aclchk.c:3439 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "нет доÑтупа к объекту ÑтатиÑтики %s" + +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "нет доÑтупа к подпиÑке %s" -#: catalog/aclchk.c:3324 +#: catalog/aclchk.c:3445 #, c-format -msgid "permission denied for statistics %s" -msgstr "нет доÑтупа к ÑтатиÑтике %s" +msgid "permission denied for table %s" +msgstr "нет доÑтупа к таблице %s" -#: catalog/aclchk.c:3326 +#: catalog/aclchk.c:3448 #, c-format msgid "permission denied for tablespace %s" msgstr "нет доÑтупа к табличному проÑтранÑтву %s" -#: catalog/aclchk.c:3328 +#: catalog/aclchk.c:3451 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "нет доÑтупа к конфигурации текÑтового поиÑка %s" + +#: catalog/aclchk.c:3454 #, c-format msgid "permission denied for text search dictionary %s" msgstr "нет доÑтупа к Ñловарю текÑтового поиÑка %s" -#: catalog/aclchk.c:3330 +#: catalog/aclchk.c:3457 #, c-format -msgid "permission denied for text search configuration %s" -msgstr "нет доÑтупа к конфигурации текÑтового поиÑка %s" +msgid "permission denied for type %s" +msgstr "нет доÑтупа к типу %s" -#: catalog/aclchk.c:3332 +#: catalog/aclchk.c:3460 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "нет доÑтупа к обёртке Ñторонних данных %s" +msgid "permission denied for view %s" +msgstr "нет доÑтупа к предÑтавлению %s" -#: catalog/aclchk.c:3334 +#: catalog/aclchk.c:3495 #, c-format -msgid "permission denied for foreign server %s" -msgstr "нет доÑтупа к Ñтороннему Ñерверу %s" +msgid "must be owner of aggregate %s" +msgstr "нужно быть владельцем агрегата %s" -#: catalog/aclchk.c:3336 +#: catalog/aclchk.c:3498 #, c-format -msgid "permission denied for event trigger %s" -msgstr "нет доÑтупа к Ñобытийному триггеру %s" +msgid "must be owner of collation %s" +msgstr "нужно быть владельцем правила Ñортировки %s" -#: catalog/aclchk.c:3338 +#: catalog/aclchk.c:3501 #, c-format -msgid "permission denied for extension %s" -msgstr "нет доÑтупа к раÑширению %s" +msgid "must be owner of conversion %s" +msgstr "нужно быть владельцем Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ %s" -#: catalog/aclchk.c:3340 +#: catalog/aclchk.c:3504 #, c-format -msgid "permission denied for publication %s" -msgstr "нет доÑтупа к публикации %s" +msgid "must be owner of database %s" +msgstr "нужно быть владельцем базы %s" -#: catalog/aclchk.c:3342 +#: catalog/aclchk.c:3507 #, c-format -msgid "permission denied for subscription %s" -msgstr "нет доÑтупа к подпиÑке %s" +msgid "must be owner of domain %s" +msgstr "нужно быть владельцем домена %s" -#: catalog/aclchk.c:3348 catalog/aclchk.c:3350 +#: catalog/aclchk.c:3510 #, c-format -msgid "must be owner of relation %s" -msgstr "нужно быть владельцем Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" +msgid "must be owner of event trigger %s" +msgstr "нужно быть владельцем Ñобытийного триггера %s" -#: catalog/aclchk.c:3352 +#: catalog/aclchk.c:3513 #, c-format -msgid "must be owner of sequence %s" -msgstr "нужно быть владельцем поÑледовательноÑти %s" +msgid "must be owner of extension %s" +msgstr "нужно быть владельцем раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ %s" -#: catalog/aclchk.c:3354 +#: catalog/aclchk.c:3516 #, c-format -msgid "must be owner of database %s" -msgstr "нужно быть владельцем базы %s" +msgid "must be owner of foreign-data wrapper %s" +msgstr "нужно быть владельцем обёртки Ñторонних данных %s" -#: catalog/aclchk.c:3356 +#: catalog/aclchk.c:3519 #, c-format -msgid "must be owner of function %s" -msgstr "нужно быть владельцем функции %s" +msgid "must be owner of foreign server %s" +msgstr "нужно быть \"владельцем\" Ñтороннего Ñервера %s" -#: catalog/aclchk.c:3358 +#: catalog/aclchk.c:3522 #, c-format -msgid "must be owner of operator %s" -msgstr "нужно быть владельцем оператора %s" +msgid "must be owner of foreign table %s" +msgstr "нужно быть владельцем Ñторонней таблицы %s" -#: catalog/aclchk.c:3360 +#: catalog/aclchk.c:3525 #, c-format -msgid "must be owner of type %s" -msgstr "нужно быть владельцем типа %s" +msgid "must be owner of function %s" +msgstr "нужно быть владельцем функции %s" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "нужно быть владельцем индекÑа %s" -#: catalog/aclchk.c:3362 +#: catalog/aclchk.c:3531 #, c-format msgid "must be owner of language %s" msgstr "нужно быть владельцем Ñзыка %s" -#: catalog/aclchk.c:3364 +#: catalog/aclchk.c:3534 #, c-format msgid "must be owner of large object %s" msgstr "нужно быть владельцем большого объекта %s" -#: catalog/aclchk.c:3366 +#: catalog/aclchk.c:3537 #, c-format -msgid "must be owner of schema %s" -msgstr "нужно быть владельцем Ñхемы %s" +msgid "must be owner of materialized view %s" +msgstr "нужно быть владельцем материализованного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ %s" -#: catalog/aclchk.c:3368 +#: catalog/aclchk.c:3540 #, c-format msgid "must be owner of operator class %s" msgstr "нужно быть владельцем клаÑÑа операторов %s" -#: catalog/aclchk.c:3370 +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "нужно быть владельцем оператора %s" + +#: catalog/aclchk.c:3546 #, c-format msgid "must be owner of operator family %s" msgstr "нужно быть владельцем ÑемейÑтва операторов %s" -#: catalog/aclchk.c:3372 +#: catalog/aclchk.c:3549 #, c-format -msgid "must be owner of collation %s" -msgstr "нужно быть владельцем правила Ñортировки %s" +msgid "must be owner of procedure %s" +msgstr "нужно быть владельцем процедуры %s" -#: catalog/aclchk.c:3374 +#: catalog/aclchk.c:3552 #, c-format -msgid "must be owner of conversion %s" -msgstr "нужно быть владельцем Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ %s" +msgid "must be owner of publication %s" +msgstr "нужно быть владельцем публикации %s" -#: catalog/aclchk.c:3376 +#: catalog/aclchk.c:3555 #, c-format -msgid "must be owner of statistics %s" -msgstr "нужно быть владельцем ÑтатиÑтики %s" +msgid "must be owner of routine %s" +msgstr "нужно быть владельцем подпрограммы %s" -#: catalog/aclchk.c:3378 +#: catalog/aclchk.c:3558 #, c-format -msgid "must be owner of tablespace %s" -msgstr "нужно быть владельцем табличного проÑтранÑтва %s" +msgid "must be owner of sequence %s" +msgstr "нужно быть владельцем поÑледовательноÑти %s" -#: catalog/aclchk.c:3380 +#: catalog/aclchk.c:3561 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "нужно быть владельцем ÑÐ»Ð¾Ð²Ð°Ñ€Ñ Ñ‚ÐµÐºÑтового поиÑка %s" +msgid "must be owner of subscription %s" +msgstr "нужно быть владельцем подпиÑки %s" -#: catalog/aclchk.c:3382 +#: catalog/aclchk.c:3564 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "нужно быть владельцем конфигурации текÑтового поиÑка %s" +msgid "must be owner of table %s" +msgstr "нужно быть владельцем таблицы %s" -#: catalog/aclchk.c:3384 +#: catalog/aclchk.c:3567 #, c-format -msgid "must be owner of foreign-data wrapper %s" -msgstr "нужно быть владельцем обёртки Ñторонних данных %s" +msgid "must be owner of type %s" +msgstr "нужно быть владельцем типа %s" -#: catalog/aclchk.c:3386 +#: catalog/aclchk.c:3570 #, c-format -msgid "must be owner of foreign server %s" -msgstr "нужно быть \"владельцем\" Ñтороннего Ñервера %s" +msgid "must be owner of view %s" +msgstr "нужно быть владельцем предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ %s" -#: catalog/aclchk.c:3388 +#: catalog/aclchk.c:3573 #, c-format -msgid "must be owner of event trigger %s" -msgstr "нужно быть владельцем Ñобытийного триггера %s" +msgid "must be owner of schema %s" +msgstr "нужно быть владельцем Ñхемы %s" -#: catalog/aclchk.c:3390 +#: catalog/aclchk.c:3576 #, c-format -msgid "must be owner of extension %s" -msgstr "нужно быть владельцем раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ %s" +msgid "must be owner of statistics object %s" +msgstr "нужно быть владельцем объекта ÑтатиÑтики %s" -#: catalog/aclchk.c:3392 +#: catalog/aclchk.c:3579 #, c-format -msgid "must be owner of publication %s" -msgstr "нужно быть владельцем публикации %s" +msgid "must be owner of tablespace %s" +msgstr "нужно быть владельцем табличного проÑтранÑтва %s" -#: catalog/aclchk.c:3394 +#: catalog/aclchk.c:3582 #, c-format -msgid "must be owner of subscription %s" -msgstr "нужно быть владельцем подпиÑки %s" +msgid "must be owner of text search configuration %s" +msgstr "нужно быть владельцем конфигурации текÑтового поиÑка %s" + +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "нужно быть владельцем ÑÐ»Ð¾Ð²Ð°Ñ€Ñ Ñ‚ÐµÐºÑтового поиÑка %s" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "нужно быть владельцем Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: catalog/aclchk.c:3436 +#: catalog/aclchk.c:3643 #, c-format msgid "permission denied for column \"%s\" of relation \"%s\"" msgstr "нет доÑтупа к Ñтолбцу \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" -#: catalog/aclchk.c:3559 catalog/aclchk.c:3567 +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 #, c-format msgid "attribute %d of relation with OID %u does not exist" msgstr "атрибут %d Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:3640 catalog/aclchk.c:4559 +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 #, c-format msgid "relation with OID %u does not exist" msgstr "отношение Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:3739 catalog/aclchk.c:4977 +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 #, c-format msgid "database with OID %u does not exist" msgstr "база данных Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:3793 catalog/aclchk.c:4637 tcop/fastpath.c:223 -#: utils/fmgr/fmgr.c:2117 +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2195 #, c-format msgid "function with OID %u does not exist" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:3847 catalog/aclchk.c:4663 +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 #, c-format msgid "language with OID %u does not exist" msgstr "Ñзык Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4011 catalog/aclchk.c:4735 +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 #, c-format msgid "schema with OID %u does not exist" msgstr "Ñхема Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4065 catalog/aclchk.c:4762 +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 #, c-format msgid "tablespace with OID %u does not exist" msgstr "табличное проÑтранÑтво Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4124 catalog/aclchk.c:4896 commands/foreigncmds.c:324 +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "обёртка Ñторонних данных Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4186 catalog/aclchk.c:4923 commands/foreigncmds.c:459 +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 #, c-format msgid "foreign server with OID %u does not exist" msgstr "Ñторонний Ñервер Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4246 catalog/aclchk.c:4585 utils/cache/typcache.c:238 +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 #, c-format msgid "type with OID %u does not exist" msgstr "тип Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4611 +#: catalog/aclchk.c:4816 #, c-format msgid "operator with OID %u does not exist" msgstr "оператор Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4788 +#: catalog/aclchk.c:4993 #, c-format msgid "operator class with OID %u does not exist" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4815 +#: catalog/aclchk.c:5020 #, c-format msgid "operator family with OID %u does not exist" msgstr "ÑемейÑтво операторов Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4842 +#: catalog/aclchk.c:5047 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "Ñловарь текÑтового поиÑка Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4869 +#: catalog/aclchk.c:5074 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:4950 commands/event_trigger.c:588 +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 #, c-format msgid "event trigger with OID %u does not exist" msgstr "Ñобытийный триггер Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5003 commands/collationcmds.c:319 +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 #, c-format msgid "collation with OID %u does not exist" msgstr "правило Ñортировки Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5029 +#: catalog/aclchk.c:5234 #, c-format msgid "conversion with OID %u does not exist" msgstr "преобразование Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5070 +#: catalog/aclchk.c:5275 #, c-format msgid "extension with OID %u does not exist" msgstr "раÑширение Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5097 commands/publicationcmds.c:760 +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 #, c-format msgid "publication with OID %u does not exist" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5123 commands/subscriptioncmds.c:943 +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 #, c-format msgid "subscription with OID %u does not exist" msgstr "подпиÑка Ñ OID %u не ÑущеÑтвует" -#: catalog/aclchk.c:5149 +#: catalog/aclchk.c:5354 #, c-format -msgid "statistics with OID %u do not exist" -msgstr "ÑтатиÑтика Ñ OID %u не ÑущеÑтвует" +msgid "statistics object with OID %u does not exist" +msgstr "объект ÑтатиÑтики Ñ OID %u не ÑущеÑтвует" -#: catalog/dependency.c:613 +#: catalog/dependency.c:611 #, c-format msgid "cannot drop %s because %s requires it" msgstr "удалить объект %s нельзÑ, так как он нужен объекту %s" -#: catalog/dependency.c:616 +#: catalog/dependency.c:614 #, c-format msgid "You can drop %s instead." msgstr "Однако можно удалить %s." -#: catalog/dependency.c:779 catalog/pg_shdepend.c:574 +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "удалить объект %s нельзÑ, так как он нужен ÑиÑтеме баз данных" -#: catalog/dependency.c:897 +#: catalog/dependency.c:905 #, c-format msgid "drop auto-cascades to %s" msgstr "удаление автоматичеÑки раÑпроÑтранÑетÑÑ Ð½Ð° объект %s" -#: catalog/dependency.c:909 catalog/dependency.c:918 +#: catalog/dependency.c:917 catalog/dependency.c:926 #, c-format msgid "%s depends on %s" msgstr "%s завиÑит от объекта %s" -#: catalog/dependency.c:930 catalog/dependency.c:939 +#: catalog/dependency.c:938 catalog/dependency.c:947 #, c-format msgid "drop cascades to %s" msgstr "удаление раÑпроÑтранÑетÑÑ Ð½Ð° объект %s" -#: catalog/dependency.c:947 catalog/pg_shdepend.c:685 +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 #, c-format msgid "" "\n" @@ -4240,24 +4182,24 @@ msgstr[2] "" "\n" "и ещё %d объектов (Ñм. ÑпиÑок в протоколе Ñервера)" -#: catalog/dependency.c:959 +#: catalog/dependency.c:967 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "удалить объект %s нельзÑ, так как от него завиÑÑÑ‚ другие объекты" -#: catalog/dependency.c:963 catalog/dependency.c:970 +#: catalog/dependency.c:971 catalog/dependency.c:978 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "Ð”Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð²Ð¸Ñимых объектов иÑпользуйте DROP ... CASCADE." -#: catalog/dependency.c:967 +#: catalog/dependency.c:975 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "" "удалить запрошенные объекты нельзÑ, так как от них завиÑÑÑ‚ другие объекты" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:976 +#: catalog/dependency.c:984 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" @@ -4265,76 +4207,77 @@ msgstr[0] "удаление раÑпроÑтранÑетÑÑ Ð½Ð° ещё %d об msgstr[1] "удаление раÑпроÑтранÑетÑÑ Ð½Ð° ещё %d объекта" msgstr[2] "удаление раÑпроÑтранÑетÑÑ Ð½Ð° ещё %d объектов" -#: catalog/dependency.c:1622 +#: catalog/dependency.c:1644 #, c-format msgid "constant of the type %s cannot be used here" msgstr "конÑтанту типа %s здеÑÑŒ иÑпользовать нельзÑ" -#: catalog/heap.c:283 +#: catalog/heap.c:286 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "нет прав Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\"" -#: catalog/heap.c:285 +#: catalog/heap.c:288 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "Изменение ÑиÑтемного каталога в текущем ÑоÑтоÑнии запрещено." -#: catalog/heap.c:421 commands/tablecmds.c:1619 commands/tablecmds.c:2122 -#: commands/tablecmds.c:5141 +#: catalog/heap.c:433 commands/tablecmds.c:1882 commands/tablecmds.c:2415 +#: commands/tablecmds.c:5516 #, c-format msgid "tables can have at most %d columns" msgstr "макÑимальное чиÑло Ñтолбцов в таблице: %d" -#: catalog/heap.c:438 commands/tablecmds.c:5399 +#: catalog/heap.c:452 commands/tablecmds.c:5812 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "Ð¸Ð¼Ñ Ñтолбца \"%s\" конфликтует Ñ ÑиÑтемным Ñтолбцом" -#: catalog/heap.c:454 +#: catalog/heap.c:468 #, c-format msgid "column name \"%s\" specified more than once" msgstr "Ð¸Ð¼Ñ Ñтолбца \"%s\" указано неоднократно" -#: catalog/heap.c:507 +#: catalog/heap.c:521 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "Ñтолбец \"%s\" имеет пÑевдотип %s" -#: catalog/heap.c:537 +#: catalog/heap.c:551 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "ÑоÑтавной тип %s не может Ñодержать ÑÐµÐ±Ñ Ð¶Ðµ" -#: catalog/heap.c:579 commands/createas.c:201 commands/createas.c:498 +#: catalog/heap.c:593 commands/createas.c:201 commands/createas.c:498 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "" "Ð´Ð»Ñ Ñтолбца \"%s\" Ñ Ñортируемым типом %s не удалоÑÑŒ получить правило " "Ñортировки" -#: catalog/heap.c:581 commands/createas.c:204 commands/createas.c:501 -#: commands/indexcmds.c:1136 commands/tablecmds.c:12999 commands/view.c:103 -#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1537 -#: utils/adt/formatting.c:1656 utils/adt/formatting.c:1775 utils/adt/like.c:184 -#: utils/adt/selfuncs.c:5506 utils/adt/varlena.c:1417 utils/adt/varlena.c:1860 +#: catalog/heap.c:595 commands/createas.c:204 commands/createas.c:501 +#: commands/indexcmds.c:1599 commands/tablecmds.c:14381 commands/view.c:105 +#: regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 +#: utils/adt/like.c:184 utils/adt/selfuncs.c:5812 utils/adt/varlena.c:1416 +#: utils/adt/varlena.c:1881 #, c-format msgid "Use the COLLATE clause to set the collation explicitly." msgstr "Задайте правило Ñортировки Ñвно в предложении COLLATE." -#: catalog/heap.c:1066 catalog/index.c:806 commands/tablecmds.c:2903 +#: catalog/heap.c:1084 catalog/index.c:876 commands/tablecmds.c:3177 #, c-format msgid "relation \"%s\" already exists" msgstr "отношение \"%s\" уже ÑущеÑтвует" -#: catalog/heap.c:1082 catalog/pg_type.c:410 catalog/pg_type.c:717 -#: commands/typecmds.c:239 commands/typecmds.c:788 commands/typecmds.c:1139 -#: commands/typecmds.c:1350 commands/typecmds.c:2106 +#: catalog/heap.c:1100 catalog/pg_type.c:417 catalog/pg_type.c:732 +#: commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 +#: commands/typecmds.c:1419 commands/typecmds.c:2174 #, c-format msgid "type \"%s\" already exists" msgstr "тип \"%s\" уже ÑущеÑтвует" -#: catalog/heap.c:1083 +#: catalog/heap.c:1101 #, c-format msgid "" "A relation has an associated type of the same name, so you must use a name " @@ -4343,42 +4286,43 @@ msgstr "" "С отношением уже ÑвÑзан тип Ñ Ñ‚Ð°ÐºÐ¸Ð¼ же именем; выберите имÑ, не " "конфликтующее Ñ ÑущеÑтвующими типами." -#: catalog/heap.c:1112 +#: catalog/heap.c:1130 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "значение OID кучи в pg_class не задано в режиме двоичного обновлениÑ" -#: catalog/heap.c:2078 +#: catalog/heap.c:2333 #, c-format msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" msgstr "" "добавить ограничение NO INHERIT к Ñекционированной таблице \"%s\" нельзÑ" -#: catalog/heap.c:2336 +#: catalog/heap.c:2598 #, c-format msgid "check constraint \"%s\" already exists" msgstr "ограничение-проверка \"%s\" уже ÑущеÑтвует" -#: catalog/heap.c:2504 catalog/pg_constraint.c:649 commands/tablecmds.c:6522 +#: catalog/heap.c:2768 catalog/index.c:890 catalog/pg_constraint.c:679 +#: commands/tablecmds.c:7164 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑущеÑтвует" -#: catalog/heap.c:2511 +#: catalog/heap.c:2775 #, c-format msgid "" "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "" "ограничение \"%s\" конфликтует Ñ Ð½ÐµÐ½Ð°Ñледуемым ограничением таблицы \"%s\"" -#: catalog/heap.c:2522 +#: catalog/heap.c:2786 #, c-format msgid "" "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" msgstr "" "ограничение \"%s\" конфликтует Ñ Ð½Ð°Ñледуемым ограничением таблицы \"%s\"" -#: catalog/heap.c:2532 +#: catalog/heap.c:2796 #, c-format msgid "" "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" @@ -4386,39 +4330,39 @@ msgstr "" "ограничение \"%s\" конфликтует Ñ Ð½ÐµÐ¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼ (NOT VALID) ограничением " "таблицы \"%s\"" -#: catalog/heap.c:2537 +#: catalog/heap.c:2801 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "ÑлиÑние Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ \"%s\" Ñ ÑƒÐ½Ð°Ñледованным определением" -#: catalog/heap.c:2653 +#: catalog/heap.c:2916 #, c-format msgid "cannot use column references in default expression" msgstr "в выражении по умолчанию Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° Ñтолбцы" -#: catalog/heap.c:2678 rewrite/rewriteHandler.c:1097 +#: catalog/heap.c:2941 rewrite/rewriteHandler.c:1163 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "Ñтолбец \"%s\" имеет тип %s, но тип Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию %s" -#: catalog/heap.c:2683 commands/prepare.c:384 parser/parse_node.c:430 -#: parser/parse_target.c:590 parser/parse_target.c:840 -#: parser/parse_target.c:850 rewrite/rewriteHandler.c:1102 +#: catalog/heap.c:2946 commands/prepare.c:384 parser/parse_node.c:430 +#: parser/parse_target.c:590 parser/parse_target.c:865 +#: parser/parse_target.c:875 rewrite/rewriteHandler.c:1168 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "Перепишите выражение или преобразуйте его тип." -#: catalog/heap.c:2730 +#: catalog/heap.c:2993 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "в ограничении-проверке можно ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на таблицу \"%s\"" -#: catalog/heap.c:3039 +#: catalog/heap.c:3243 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "неподдерживаемое Ñочетание внешнего ключа Ñ ON COMMIT" -#: catalog/heap.c:3040 +#: catalog/heap.c:3244 #, c-format msgid "" "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " @@ -4426,253 +4370,268 @@ msgid "" msgstr "" "Таблица \"%s\" ÑÑылаетÑÑ Ð½Ð° \"%s\", и Ð´Ð»Ñ Ð½Ð¸Ñ… задан разный режим ON COMMIT." -#: catalog/heap.c:3045 +#: catalog/heap.c:3249 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "опуÑтошить таблицу, на которую ÑÑылаетÑÑ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¹ ключ, нельзÑ" -#: catalog/heap.c:3046 +#: catalog/heap.c:3250 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "Таблица \"%s\" ÑÑылаетÑÑ Ð½Ð° \"%s\"." -#: catalog/heap.c:3048 +#: catalog/heap.c:3252 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "" "ОпуÑтошите таблицу \"%s\" параллельно или иÑпользуйте TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1541 parser/parse_utilcmd.c:1627 +#: catalog/index.c:233 parser/parse_utilcmd.c:1823 parser/parse_utilcmd.c:1910 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "таблица \"%s\" не может иметь неÑколько первичных ключей" -#: catalog/index.c:228 +#: catalog/index.c:251 #, c-format msgid "primary keys cannot be expressions" msgstr "первичные ключи не могут быть выражениÑми" -#: catalog/index.c:756 catalog/index.c:1174 +#: catalog/index.c:820 catalog/index.c:1291 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "" "пользовательÑкие индекÑÑ‹ в таблицах ÑиÑтемного каталога не поддерживаютÑÑ" -#: catalog/index.c:766 +#: catalog/index.c:830 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "" "параллельное Ñоздание индекÑа в таблицах ÑиÑтемного каталога не " "поддерживаетÑÑ" -#: catalog/index.c:784 +#: catalog/index.c:848 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать разделÑемые индекÑÑ‹ поÑле initdb" -#: catalog/index.c:798 commands/createas.c:250 commands/sequence.c:149 -#: parser/parse_utilcmd.c:197 +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 +#: parser/parse_utilcmd.c:205 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "отношение \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: catalog/index.c:834 +#: catalog/index.c:918 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "" "значение OID индекÑа в pg_class не задано в режиме двоичного обновлениÑ" -#: catalog/index.c:1435 +#: catalog/index.c:1566 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY должен быть первым дейÑтвием в транзакции" -#: catalog/index.c:2019 +#: catalog/index.c:2294 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "Ñоздание индекÑа \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" в непараллельном режиме" + +#: catalog/index.c:2299 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "Ñоздание индекÑа \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"" +msgid "" +"building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "" +"building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "" +"Ñоздание индекÑа \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" Ñ Ñ€Ð°Ñчётом на %d параллельного " +"иÑполнителÑ" +msgstr[1] "" +"Ñоздание индекÑа \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" Ñ Ñ€Ð°Ñчётом на %d параллельных " +"иÑполнителей" +msgstr[2] "" +"Ñоздание индекÑа \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" Ñ Ñ€Ð°Ñчётом на %d параллельных " +"иÑполнителей" -#: catalog/index.c:3331 +#: catalog/index.c:3688 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "переиндекÑировать временные таблицы других ÑеанÑов нельзÑ" -#: catalog/index.c:3462 +#: catalog/index.c:3820 #, c-format msgid "index \"%s\" was reindexed" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" был переÑтроен" -#: catalog/index.c:3464 commands/vacuumlazy.c:1356 commands/vacuumlazy.c:1432 -#: commands/vacuumlazy.c:1621 commands/vacuumlazy.c:1831 +#: catalog/index.c:3890 #, c-format -msgid "%s." -msgstr "%s." +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "" +"REINDEX Ð´Ð»Ñ Ñекционированных таблицы ещё не реализован, \"%s\" пропуÑкаетÑÑ" -#: catalog/namespace.c:234 catalog/namespace.c:432 catalog/namespace.c:526 -#: commands/trigger.c:4789 +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 +#: commands/trigger.c:5405 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "ÑÑылки между базами не реализованы: \"%s.%s.%s\"" -#: catalog/namespace.c:291 +#: catalog/namespace.c:306 #, c-format msgid "temporary tables cannot specify a schema name" msgstr "Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… таблиц Ð¸Ð¼Ñ Ñхемы не указываетÑÑ" -#: catalog/namespace.c:370 +#: catalog/namespace.c:387 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "не удалоÑÑŒ получить блокировку таблицы \"%s.%s\"" -#: catalog/namespace.c:375 commands/lockcmds.c:145 +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:248 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "не удалоÑÑŒ получить блокировку таблицы \"%s\"" -#: catalog/namespace.c:399 parser/parse_relation.c:1158 +#: catalog/namespace.c:420 parser/parse_relation.c:1158 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "отношение \"%s.%s\" не ÑущеÑтвует" -#: catalog/namespace.c:404 parser/parse_relation.c:1176 -#: parser/parse_relation.c:1184 utils/adt/regproc.c:1036 +#: catalog/namespace.c:425 parser/parse_relation.c:1171 +#: parser/parse_relation.c:1179 #, c-format msgid "relation \"%s\" does not exist" msgstr "отношение \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:472 catalog/namespace.c:2882 commands/extension.c:1462 -#: commands/extension.c:1468 +#: catalog/namespace.c:491 catalog/namespace.c:3008 commands/extension.c:1466 +#: commands/extension.c:1472 #, c-format msgid "no schema has been selected to create in" msgstr "Ñхема Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð² не выбрана" -#: catalog/namespace.c:624 catalog/namespace.c:637 +#: catalog/namespace.c:643 catalog/namespace.c:656 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "во временных Ñхемах других ÑеанÑов Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздавать отношениÑ" -#: catalog/namespace.c:628 +#: catalog/namespace.c:647 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "Ñоздавать временные Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ только во временных Ñхемах" -#: catalog/namespace.c:643 +#: catalog/namespace.c:662 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "во временных Ñхемах можно Ñоздавать только временные отношениÑ" -#: catalog/namespace.c:2138 +#: catalog/namespace.c:2200 #, c-format -msgid "statistics \"%s\" do not exist" -msgstr "ÑтатиÑтика \"%s\" не ÑущеÑтвует" +msgid "statistics object \"%s\" does not exist" +msgstr "объект ÑтатиÑтики \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2195 +#: catalog/namespace.c:2323 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "анализатор текÑтового поиÑка \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2321 +#: catalog/namespace.c:2449 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "Ñловарь текÑтового поиÑка \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2448 +#: catalog/namespace.c:2576 #, c-format msgid "text search template \"%s\" does not exist" msgstr "шаблон текÑтового поиÑка \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2574 commands/tsearchcmds.c:1185 -#: utils/cache/ts_cache.c:612 +#: catalog/namespace.c:2702 commands/tsearchcmds.c:1185 +#: utils/cache/ts_cache.c:616 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2687 parser/parse_expr.c:791 parser/parse_target.c:1192 +#: catalog/namespace.c:2815 parser/parse_expr.c:793 parser/parse_target.c:1220 #, c-format msgid "cross-database references are not implemented: %s" msgstr "ÑÑылки между базами не реализованы: %s" -#: catalog/namespace.c:2693 parser/parse_expr.c:798 parser/parse_target.c:1199 -#: gram.y:14221 gram.y:15642 +#: catalog/namespace.c:2821 parser/parse_expr.c:800 parser/parse_target.c:1227 +#: gram.y:14728 gram.y:16160 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "неверное полное Ð¸Ð¼Ñ (Ñлишком много компонентов): %s" -#: catalog/namespace.c:2824 +#: catalog/namespace.c:2951 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "перемещать объекты в/из внутренних Ñхем нельзÑ" -#: catalog/namespace.c:2830 +#: catalog/namespace.c:2957 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "перемещать объекты в/из Ñхем TOAST нельзÑ" -#: catalog/namespace.c:2903 commands/schemacmds.c:256 commands/schemacmds.c:334 -#: commands/tablecmds.c:891 +#: catalog/namespace.c:3029 commands/schemacmds.c:256 +#: commands/schemacmds.c:334 commands/tablecmds.c:1015 #, c-format msgid "schema \"%s\" does not exist" msgstr "Ñхема \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:2934 +#: catalog/namespace.c:3060 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "неверное Ð¸Ð¼Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ (Ñлишком много компонентов): %s" -#: catalog/namespace.c:3444 +#: catalog/namespace.c:3594 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "правило Ñортировки \"%s\" Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:3499 +#: catalog/namespace.c:3649 #, c-format msgid "conversion \"%s\" does not exist" msgstr "преобразование \"%s\" не ÑущеÑтвует" -#: catalog/namespace.c:3707 +#: catalog/namespace.c:3889 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "нет прав Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… таблиц в базе \"%s\"" -#: catalog/namespace.c:3723 +#: catalog/namespace.c:3905 #, c-format msgid "cannot create temporary tables during recovery" msgstr "Ñоздавать временные таблицы в процеÑÑе воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" -#: catalog/namespace.c:3729 +#: catalog/namespace.c:3911 #, c-format -msgid "cannot create temporary tables in parallel mode" -msgstr "Ñоздавать временные таблицы в параллельном режиме нельзÑ" +msgid "cannot create temporary tables during a parallel operation" +msgstr "Ñоздавать временные таблицы во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: catalog/namespace.c:3978 commands/tablespace.c:1169 commands/variable.c:64 -#: utils/misc/guc.c:9961 utils/misc/guc.c:10039 +#: catalog/namespace.c:4194 commands/tablespace.c:1171 commands/variable.c:64 +#: utils/misc/guc.c:10271 utils/misc/guc.c:10349 #, c-format msgid "List syntax is invalid." msgstr "Ошибка ÑинтакÑиÑа в ÑпиÑке." -#: catalog/objectaddress.c:1238 catalog/pg_publication.c:57 -#: commands/lockcmds.c:93 commands/policy.c:94 commands/policy.c:391 -#: commands/policy.c:480 commands/tablecmds.c:223 commands/tablecmds.c:265 -#: commands/tablecmds.c:1477 commands/tablecmds.c:4662 -#: commands/tablecmds.c:8501 +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 +#: commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1740 +#: commands/tablecmds.c:5011 commands/tablecmds.c:9635 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\" - Ñто не таблица" -#: catalog/objectaddress.c:1245 commands/tablecmds.c:235 -#: commands/tablecmds.c:4692 commands/tablecmds.c:12738 commands/view.c:141 +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 +#: commands/tablecmds.c:5041 commands/tablecmds.c:14100 commands/view.c:138 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\" - Ñто не предÑтавление" -#: catalog/objectaddress.c:1252 commands/matview.c:174 commands/tablecmds.c:241 -#: commands/tablecmds.c:12743 +#: catalog/objectaddress.c:1252 commands/matview.c:172 +#: commands/tablecmds.c:243 commands/tablecmds.c:14105 #, c-format msgid "\"%s\" is not a materialized view" msgstr "\"%s\" - Ñто не материализованное предÑтавление" -#: catalog/objectaddress.c:1259 commands/tablecmds.c:259 -#: commands/tablecmds.c:4695 commands/tablecmds.c:12748 +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 +#: commands/tablecmds.c:5044 commands/tablecmds.c:14110 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\" - Ñто не ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" @@ -4693,192 +4652,199 @@ msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "" "значение по умолчанию Ð´Ð»Ñ Ñтолбца \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует" -#: catalog/objectaddress.c:1509 commands/functioncmds.c:128 -#: commands/tablecmds.c:251 commands/typecmds.c:3233 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:794 utils/adt/acl.c:4357 -#: utils/adt/regproc.c:1227 +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 +#: commands/tablecmds.c:253 commands/typecmds.c:3324 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 #, c-format msgid "type \"%s\" does not exist" msgstr "тип \"%s\" не ÑущеÑтвует" -#: catalog/objectaddress.c:1626 +#: catalog/objectaddress.c:1628 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "оператор %d (%s, %s) из ÑемейÑтва %s не ÑущеÑтвует" -#: catalog/objectaddress.c:1657 +#: catalog/objectaddress.c:1659 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d (%s, %s) из ÑемейÑтва %s не ÑущеÑтвует" -#: catalog/objectaddress.c:1708 catalog/objectaddress.c:1734 +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "ÑопоÑтавление Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" на Ñервере \"%s\" не ÑущеÑтвует" -#: catalog/objectaddress.c:1723 commands/foreigncmds.c:428 -#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1377 +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 +#: commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 #: foreign/foreign.c:688 #, c-format msgid "server \"%s\" does not exist" msgstr "Ñервер \"%s\" не ÑущеÑтвует" -#: catalog/objectaddress.c:1790 +#: catalog/objectaddress.c:1792 #, c-format msgid "publication relation \"%s\" in publication \"%s\" does not exist" msgstr "публикуемое отношение \"%s\" в публикации \"%s\" не ÑущеÑтвует" -#: catalog/objectaddress.c:1852 +#: catalog/objectaddress.c:1854 #, c-format -msgid "unrecognized default ACL object type %c" -msgstr "нераÑпознанный тип объекта ACL по умолчанию: %c" +msgid "unrecognized default ACL object type \"%c\"" +msgstr "нераÑпознанный тип объекта ACL по умолчанию: \"%c\"" -#: catalog/objectaddress.c:1853 +#: catalog/objectaddress.c:1855 #, c-format -msgid "Valid object types are \"r\", \"S\", \"f\", \"T\" and \"s\"." -msgstr "ДопуÑтимые типы объектов: \"r\", \"S\", \"f\", \"T\" и \"s\"." +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "ДопуÑтимые типы объектов: \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." -#: catalog/objectaddress.c:1899 +#: catalog/objectaddress.c:1906 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "" "ACL по умолчанию Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" в Ñхеме \"%s\" Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° %s не " "ÑущеÑтвует" -#: catalog/objectaddress.c:1904 +#: catalog/objectaddress.c:1911 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "" "ACL по умолчанию Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" и Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° %s не ÑущеÑтвует" -#: catalog/objectaddress.c:1931 catalog/objectaddress.c:1989 -#: catalog/objectaddress.c:2044 +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 +#: catalog/objectaddress.c:2053 #, c-format msgid "name or argument lists may not contain nulls" msgstr "ÑпиÑки имён и аргументов не должны Ñодержать NULL" -#: catalog/objectaddress.c:1965 +#: catalog/objectaddress.c:1972 #, c-format msgid "unsupported object type \"%s\"" msgstr "неподдерживаемый тип объекта: \"%s\"" -#: catalog/objectaddress.c:1985 catalog/objectaddress.c:2003 -#: catalog/objectaddress.c:2141 +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 +#: catalog/objectaddress.c:2151 #, c-format msgid "name list length must be exactly %d" msgstr "длина ÑпиÑка имён должна быть равна %d" -#: catalog/objectaddress.c:2007 +#: catalog/objectaddress.c:2014 #, c-format msgid "large object OID may not be null" msgstr "OID большого объекта не может быть NULL" -#: catalog/objectaddress.c:2016 catalog/objectaddress.c:2077 -#: catalog/objectaddress.c:2084 +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 +#: catalog/objectaddress.c:2093 #, c-format msgid "name list length must be at least %d" msgstr "длина ÑпиÑка аргументов должна быть не меньше %d" -#: catalog/objectaddress.c:2070 catalog/objectaddress.c:2090 +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 #, c-format msgid "argument list length must be exactly %d" msgstr "длина ÑпиÑка аргументов должна быть равна %d" -#: catalog/objectaddress.c:2316 libpq/be-fsstubs.c:350 +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "нужно быть владельцем большого объекта %u" -#: catalog/objectaddress.c:2331 commands/functioncmds.c:1419 +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 #, c-format msgid "must be owner of type %s or type %s" msgstr "Ñто разрешено только владельцу типа %s или %s" -#: catalog/objectaddress.c:2381 catalog/objectaddress.c:2398 +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 #, c-format msgid "must be superuser" msgstr "требуютÑÑ Ð¿Ñ€Ð°Ð²Ð° ÑуперпользователÑ" -#: catalog/objectaddress.c:2388 +#: catalog/objectaddress.c:2402 #, c-format msgid "must have CREATEROLE privilege" msgstr "требуетÑÑ Ð¿Ñ€Ð°Ð²Ð¾ CREATEROLE" -#: catalog/objectaddress.c:2467 +#: catalog/objectaddress.c:2481 #, c-format msgid "unrecognized object type \"%s\"" msgstr "нераÑпознанный тип объекта \"%s\"" -#: catalog/objectaddress.c:2662 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 #, c-format -msgid " column %s" -msgstr " Ñтолбец %s" +msgid "column %s of %s" +msgstr "Ñтолбец %s Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: catalog/objectaddress.c:2668 +#: catalog/objectaddress.c:2704 #, c-format msgid "function %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s" -#: catalog/objectaddress.c:2673 +#: catalog/objectaddress.c:2709 #, c-format msgid "type %s" msgstr "тип %s" -#: catalog/objectaddress.c:2703 +#: catalog/objectaddress.c:2739 #, c-format msgid "cast from %s to %s" msgstr "приведение %s к %s" -#: catalog/objectaddress.c:2723 +#: catalog/objectaddress.c:2767 #, c-format msgid "collation %s" msgstr "правило Ñортировки %s" -#: catalog/objectaddress.c:2747 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 #, c-format msgid "constraint %s on %s" msgstr "ограничение %s в отношении %s" -#: catalog/objectaddress.c:2753 +#: catalog/objectaddress.c:2799 #, c-format msgid "constraint %s" msgstr "ограничение %s" -#: catalog/objectaddress.c:2770 +#: catalog/objectaddress.c:2826 #, c-format msgid "conversion %s" msgstr "преобразование %s" -#: catalog/objectaddress.c:2807 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 #, c-format -msgid "default for %s" -msgstr "значение по умолчанию, %s" +msgid "default value for %s" +msgstr "значение по умолчанию Ð´Ð»Ñ %s" -#: catalog/objectaddress.c:2816 +#: catalog/objectaddress.c:2874 #, c-format msgid "language %s" msgstr "Ñзык %s" -#: catalog/objectaddress.c:2821 +#: catalog/objectaddress.c:2879 #, c-format msgid "large object %u" msgstr "большой объект %u" -#: catalog/objectaddress.c:2826 +#: catalog/objectaddress.c:2884 #, c-format msgid "operator %s" msgstr "оператор %s" -#: catalog/objectaddress.c:2858 +#: catalog/objectaddress.c:2916 #, c-format msgid "operator class %s for access method %s" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² %s Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа %s" +#: catalog/objectaddress.c:2939 +#, c-format +msgid "access method %s" +msgstr "метод доÑтупа %s" + #. translator: %d is the operator strategy (a number), the #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2908 +#: catalog/objectaddress.c:2981 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "оператор %d (%s, %s) из ÑемейÑтва \"%s\": %s" @@ -4887,229 +4853,243 @@ msgstr "оператор %d (%s, %s) из ÑемейÑтва \"%s\": %s" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2958 +#: catalog/objectaddress.c:3031 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d (%s, %s) из ÑемейÑтва \"%s\": %s" -#: catalog/objectaddress.c:2998 -#, c-format -msgid "rule %s on " -msgstr "правило %s Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ: " - -#: catalog/objectaddress.c:3020 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 #, c-format -msgid "transform for %s language %s" -msgstr "преобразование Ð´Ð»Ñ %s, Ñзыка %s" +msgid "rule %s on %s" +msgstr "правило %s Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: catalog/objectaddress.c:3054 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 #, c-format -msgid "trigger %s on " -msgstr "триггер %s в отношении: " +msgid "trigger %s on %s" +msgstr "триггер %s в отношении %s" -#: catalog/objectaddress.c:3071 +#: catalog/objectaddress.c:3129 #, c-format msgid "schema %s" msgstr "Ñхема %s" -#: catalog/objectaddress.c:3084 +#: catalog/objectaddress.c:3152 +#, c-format +msgid "statistics object %s" +msgstr "объект ÑтатиÑтики %s" + +#: catalog/objectaddress.c:3179 #, c-format msgid "text search parser %s" msgstr "анализатор текÑтового поиÑка %s" -#: catalog/objectaddress.c:3099 +#: catalog/objectaddress.c:3205 #, c-format msgid "text search dictionary %s" msgstr "Ñловарь текÑтового поиÑка %s" -#: catalog/objectaddress.c:3114 +#: catalog/objectaddress.c:3231 #, c-format msgid "text search template %s" msgstr "шаблон текÑтового поиÑка %s" -#: catalog/objectaddress.c:3129 +#: catalog/objectaddress.c:3257 #, c-format msgid "text search configuration %s" msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка %s" -#: catalog/objectaddress.c:3137 +#: catalog/objectaddress.c:3266 #, c-format msgid "role %s" msgstr "роль %s" -#: catalog/objectaddress.c:3150 +#: catalog/objectaddress.c:3279 #, c-format msgid "database %s" msgstr "база данных %s" -#: catalog/objectaddress.c:3162 +#: catalog/objectaddress.c:3291 #, c-format msgid "tablespace %s" msgstr "табличное проÑтранÑтво %s" -#: catalog/objectaddress.c:3171 +#: catalog/objectaddress.c:3300 #, c-format msgid "foreign-data wrapper %s" msgstr "обёртка Ñторонних данных %s" -#: catalog/objectaddress.c:3180 +#: catalog/objectaddress.c:3309 #, c-format msgid "server %s" msgstr "Ñервер %s" -#: catalog/objectaddress.c:3208 +#: catalog/objectaddress.c:3337 #, c-format msgid "user mapping for %s on server %s" msgstr "ÑопоÑтавление Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s на Ñервере %s" -#: catalog/objectaddress.c:3243 +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "" +"права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… отношений, принадлежащих роли %s в Ñхеме %s" + +#: catalog/objectaddress.c:3386 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… отношений, принадлежащих роли %s" -#: catalog/objectaddress.c:3248 +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "" +"права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… поÑледовательноÑтей, принадлежащих роли %s в " +"Ñхеме %s" + +#: catalog/objectaddress.c:3396 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "" "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… поÑледовательноÑтей, принадлежащих роли %s" -#: catalog/objectaddress.c:3253 +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… функций, принадлежащих роли %s в Ñхеме %s" + +#: catalog/objectaddress.c:3406 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… функций, принадлежащих роли %s" -#: catalog/objectaddress.c:3258 +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… типов, принадлежащих роли %s в Ñхеме %s" + +#: catalog/objectaddress.c:3416 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… типов, принадлежащих роли %s" -#: catalog/objectaddress.c:3263 +#: catalog/objectaddress.c:3422 #, c-format msgid "default privileges on new schemas belonging to role %s" msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… Ñхем, принадлежащих роли %s" -#: catalog/objectaddress.c:3269 +#: catalog/objectaddress.c:3429 #, c-format -msgid "default privileges belonging to role %s" -msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… объектов, принадлежащих роли %s" +msgid "default privileges belonging to role %s in schema %s" +msgstr "" +"права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… объектов, принадлежащих роли %s в Ñхеме %s" -#: catalog/objectaddress.c:3277 +#: catalog/objectaddress.c:3433 #, c-format -msgid " in schema %s" -msgstr " в Ñхеме %s" +msgid "default privileges belonging to role %s" +msgstr "права по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… объектов, принадлежащих роли %s" -#: catalog/objectaddress.c:3294 +#: catalog/objectaddress.c:3451 #, c-format msgid "extension %s" msgstr "раÑширение %s" -#: catalog/objectaddress.c:3307 +#: catalog/objectaddress.c:3464 #, c-format msgid "event trigger %s" msgstr "Ñобытийный триггер %s" -#: catalog/objectaddress.c:3339 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 #, c-format -msgid "policy %s on " -msgstr "политика %s Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ " - -#: catalog/objectaddress.c:3357 -#, c-format -msgid "access method %s" -msgstr "метод доÑтупа %s" +msgid "policy %s on %s" +msgstr "политика %s Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: catalog/objectaddress.c:3365 +#: catalog/objectaddress.c:3510 #, c-format msgid "publication %s" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ %s" -#: catalog/objectaddress.c:3385 +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 #, c-format -msgid "publication table %s in publication %s" -msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° %s в публикации %s" +msgid "publication of %s in publication %s" +msgstr "публикуемое отношение %s в публикации %s" -#: catalog/objectaddress.c:3393 +#: catalog/objectaddress.c:3544 #, c-format msgid "subscription %s" msgstr "подпиÑка %s" -#: catalog/objectaddress.c:3453 +#: catalog/objectaddress.c:3562 +#, c-format +msgid "transform for %s language %s" +msgstr "преобразование Ð´Ð»Ñ %s, Ñзыка %s" + +#: catalog/objectaddress.c:3625 #, c-format msgid "table %s" msgstr "таблица %s" -#: catalog/objectaddress.c:3457 +#: catalog/objectaddress.c:3630 #, c-format msgid "index %s" msgstr "Ð¸Ð½Ð´ÐµÐºÑ %s" -#: catalog/objectaddress.c:3461 +#: catalog/objectaddress.c:3634 #, c-format msgid "sequence %s" msgstr "поÑледовательноÑть %s" -#: catalog/objectaddress.c:3465 +#: catalog/objectaddress.c:3638 #, c-format msgid "toast table %s" msgstr "TOAST-таблица %s" -#: catalog/objectaddress.c:3469 +#: catalog/objectaddress.c:3642 #, c-format msgid "view %s" msgstr "предÑтавление %s" -#: catalog/objectaddress.c:3473 +#: catalog/objectaddress.c:3646 #, c-format msgid "materialized view %s" msgstr "материализованное предÑтавление %s" -#: catalog/objectaddress.c:3477 +#: catalog/objectaddress.c:3650 #, c-format msgid "composite type %s" msgstr "ÑоÑтавной тип %s" -#: catalog/objectaddress.c:3481 +#: catalog/objectaddress.c:3654 #, c-format msgid "foreign table %s" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° %s" -#: catalog/objectaddress.c:3486 +#: catalog/objectaddress.c:3659 #, c-format msgid "relation %s" msgstr "отношение %s" -#: catalog/objectaddress.c:3523 +#: catalog/objectaddress.c:3696 #, c-format msgid "operator family %s for access method %s" msgstr "ÑемейÑтво операторов %s Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа %s" -#: catalog/objectaddress.c:4902 -#, c-format -msgid "%s in publication %s" -msgstr "%s в публикации %s" - -#: catalog/partition.c:741 -#, c-format -msgid "cannot create range partition with empty range" -msgstr "Ñоздать диапазонную Ñекцию Ñ Ð¿ÑƒÑтым диапазоном нельзÑ" - -#: catalog/partition.c:835 -#, c-format -msgid "partition \"%s\" would overlap partition \"%s\"" -msgstr "ÑÐµÐºÑ†Ð¸Ñ \"%s\" переÑекаетÑÑ Ñ Ñекцией \"%s\"" - -#: catalog/partition.c:943 catalog/partition.c:1092 commands/analyze.c:1446 -#: commands/tablecmds.c:8563 executor/execExprInterp.c:2814 -#: executor/execMain.c:3195 +#: catalog/partition.c:180 commands/analyze.c:1514 commands/indexcmds.c:929 +#: commands/tablecmds.c:942 commands/tablecmds.c:7904 +#: commands/tablecmds.c:9697 commands/tablecmds.c:14994 +#: commands/tablecmds.c:15521 executor/execExprInterp.c:3275 +#: executor/execMain.c:1940 executor/execMain.c:2019 executor/execMain.c:2067 +#: executor/execMain.c:2173 executor/execPartition.c:471 +#: executor/execPartition.c:531 executor/execPartition.c:647 +#: executor/execPartition.c:750 executor/execPartition.c:821 +#: executor/execPartition.c:1019 executor/nodeModifyTable.c:1859 msgid "could not convert row type" msgstr "не удалоÑÑŒ преобразовать тип Ñтроки" -#: catalog/partition.c:1729 -#, c-format -msgid "range partition key of row contains null" -msgstr "ключ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð¿Ð¾ диапазонам в Ñтроке таблицы Ñодержит NULL" - -#: catalog/pg_aggregate.c:125 +#: catalog/pg_aggregate.c:126 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" @@ -5117,12 +5097,12 @@ msgstr[0] "агрегатные функции допуÑкают не боль msgstr[1] "агрегатные функции допуÑкают не больше %d аргументов" msgstr[2] "агрегатные функции допуÑкают не больше %d аргументов" -#: catalog/pg_aggregate.c:148 catalog/pg_aggregate.c:158 +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 #, c-format msgid "cannot determine transition data type" msgstr "не удалоÑÑŒ определить переходный тип данных" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 #, c-format msgid "" "An aggregate using a polymorphic transition type must have at least one " @@ -5131,14 +5111,14 @@ msgstr "" "ÐÐ³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾Ñ€Ñ„Ð½Ñ‹Ð¹ переходный тип, должна иметь " "минимум один полиморфный аргумент." -#: catalog/pg_aggregate.c:172 +#: catalog/pg_aggregate.c:173 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "" "ÑÐ¾Ñ€Ñ‚Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð½ÐµÐ¿Ð¾ÑтоÑнными аргументами должна " "иÑпользовать тип VARIADIC ANY" -#: catalog/pg_aggregate.c:198 +#: catalog/pg_aggregate.c:199 #, c-format msgid "" "a hypothetical-set aggregate must have direct arguments matching its " @@ -5147,12 +5127,12 @@ msgstr "" "Ð³Ð¸Ð¿Ð¾Ñ‚ÐµÐ·Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° иметь непоÑредÑтвенные аргументы, " "ÑоответÑтвующие агрегатным" -#: catalog/pg_aggregate.c:245 catalog/pg_aggregate.c:289 +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 #, c-format msgid "return type of transition function %s is not %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° %s должна возвращать тип %s" -#: catalog/pg_aggregate.c:265 catalog/pg_aggregate.c:308 +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 #, c-format msgid "" "must not omit initial value when transition function is strict and " @@ -5161,54 +5141,53 @@ msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð¿ÑƒÑкать начальное значение, когда Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° объÑвлена как " "STRICT и переходный тип неÑовмеÑтим Ñ Ð²Ñ…Ð¾Ð´Ð½Ñ‹Ð¼ типом" -#: catalog/pg_aggregate.c:334 +#: catalog/pg_aggregate.c:335 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° %s должна возвращать тип %s" -#: catalog/pg_aggregate.c:351 executor/nodeWindowAgg.c:2294 +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 #, c-format msgid "" "strictness of aggregate's forward and inverse transition functions must match" msgstr "" "прÑÐ¼Ð°Ñ Ð¸ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ перехода агрегата должны иметь одинаковую ÑтрогоÑть" -#: catalog/pg_aggregate.c:395 catalog/pg_aggregate.c:545 +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "" "Ñ„Ð¸Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¼Ð¸ аргументами не должна объÑвлÑтьÑÑ ÐºÐ°Ðº " "ÑÑ‚Ñ€Ð¾Ð³Ð°Ñ (STRICT)" -#: catalog/pg_aggregate.c:425 +#: catalog/pg_aggregate.c:427 #, c-format msgid "return type of combine function %s is not %s" msgstr "ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s должна возвращать тип %s" -#: catalog/pg_aggregate.c:436 +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2947 #, c-format -msgid "" -"combine function with \"%s\" transition type must not be declared STRICT" +msgid "combine function with transition type %s must not be declared STRICT" msgstr "" -"ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼ типом \"%s\" не должна объÑвлÑтьÑÑ ÐºÐ°Ðº " +"ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼ типом %s не должна объÑвлÑтьÑÑ ÐºÐ°Ðº " "ÑÑ‚Ñ€Ð¾Ð³Ð°Ñ (STRICT)" -#: catalog/pg_aggregate.c:455 +#: catalog/pg_aggregate.c:458 #, c-format msgid "return type of serialization function %s is not %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñериализации %s должна возвращать тип %s" -#: catalog/pg_aggregate.c:475 +#: catalog/pg_aggregate.c:479 #, c-format msgid "return type of deserialization function %s is not %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´ÐµÑериализации %s должна возвращать тип %s" -#: catalog/pg_aggregate.c:491 catalog/pg_proc.c:243 catalog/pg_proc.c:250 +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 #, c-format msgid "cannot determine result data type" msgstr "не удалоÑÑŒ определить тип результата" -#: catalog/pg_aggregate.c:492 +#: catalog/pg_aggregate.c:496 #, c-format msgid "" "An aggregate returning a polymorphic type must have at least one polymorphic " @@ -5217,12 +5196,12 @@ msgstr "" "ÐÐ³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾Ñ€Ñ„Ð½Ñ‹Ð¹ тип, должна иметь минимум один " "полиморфный аргумент." -#: catalog/pg_aggregate.c:504 catalog/pg_proc.c:256 +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "небезопаÑное иÑпользование пÑевдотипа \"internal\"" -#: catalog/pg_aggregate.c:505 catalog/pg_proc.c:257 +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 #, c-format msgid "" "A function returning \"internal\" must have at least one \"internal\" " @@ -5231,7 +5210,7 @@ msgstr "" "ФункциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ \"internal\", должна иметь минимум один аргумент " "\"internal\"." -#: catalog/pg_aggregate.c:558 +#: catalog/pg_aggregate.c:562 #, c-format msgid "" "moving-aggregate implementation returns type %s, but plain implementation " @@ -5240,97 +5219,87 @@ msgstr "" "Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð²Ð¸Ð¶Ð¸Ð¼Ð¾Ð³Ð¾ агрегата возвращает тип %s, но проÑÑ‚Ð°Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ " "возвращает %s" -#: catalog/pg_aggregate.c:569 +#: catalog/pg_aggregate.c:573 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "" "оператор Ñортировки можно указать только Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ñ‹Ñ… функций Ñ Ð¾Ð´Ð½Ð¸Ð¼ " "аргументом" -#: catalog/pg_aggregate.c:810 commands/typecmds.c:1698 commands/typecmds.c:1749 -#: commands/typecmds.c:1780 commands/typecmds.c:1803 commands/typecmds.c:1824 -#: commands/typecmds.c:1851 commands/typecmds.c:1878 commands/typecmds.c:1955 -#: commands/typecmds.c:1997 parser/parse_func.c:365 parser/parse_func.c:394 -#: parser/parse_func.c:419 parser/parse_func.c:433 parser/parse_func.c:508 -#: parser/parse_func.c:519 parser/parse_func.c:1958 +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 +#: commands/typecmds.c:1817 commands/typecmds.c:1848 commands/typecmds.c:1871 +#: commands/typecmds.c:1892 commands/typecmds.c:1919 commands/typecmds.c:1946 +#: commands/typecmds.c:2023 commands/typecmds.c:2065 parser/parse_func.c:408 +#: parser/parse_func.c:437 parser/parse_func.c:462 parser/parse_func.c:476 +#: parser/parse_func.c:596 parser/parse_func.c:616 parser/parse_func.c:2086 #, c-format msgid "function %s does not exist" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не ÑущеÑтвует" -#: catalog/pg_aggregate.c:816 +#: catalog/pg_aggregate.c:825 #, c-format msgid "function %s returns a set" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s возвращает множеÑтво" -#: catalog/pg_aggregate.c:831 +#: catalog/pg_aggregate.c:840 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "" "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² Ñтой агрегатной функции Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s должна принимать " "VARIADIC ANY" -#: catalog/pg_aggregate.c:855 +#: catalog/pg_aggregate.c:864 #, c-format msgid "function %s requires run-time type coercion" msgstr "функции %s требуетÑÑ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ типов во Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ" -#: catalog/pg_collation.c:85 catalog/pg_collation.c:127 +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 #, c-format msgid "collation \"%s\" already exists, skipping" msgstr "правило Ñортировки \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: catalog/pg_collation.c:87 +#: catalog/pg_collation.c:94 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" msgstr "" "правило Ñортировки \"%s\" Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: catalog/pg_collation.c:95 catalog/pg_collation.c:134 +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 #, c-format msgid "collation \"%s\" already exists" msgstr "правило Ñортировки \"%s\" уже ÑущеÑтвует" -#: catalog/pg_collation.c:97 +#: catalog/pg_collation.c:104 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists" msgstr "правило Ñортировки \"%s\" Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\" уже ÑущеÑтвует" -#: catalog/pg_constraint.c:658 +#: catalog/pg_constraint.c:687 #, c-format msgid "constraint \"%s\" for domain %s already exists" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° %s уже ÑущеÑтвует" -#: catalog/pg_constraint.c:788 -#, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "таблица \"%s\" Ñодержит неÑколько ограничений Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" - -#: catalog/pg_constraint.c:800 +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" не ÑущеÑтвует" -#: catalog/pg_constraint.c:846 -#, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "домен \"%s\" Ñодержит неÑколько ограничений Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" - -#: catalog/pg_constraint.c:858 +#: catalog/pg_constraint.c:1056 #, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" -msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° \"%s\" не ÑущеÑтвует" +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° %s не ÑущеÑтвует" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:65 #, c-format msgid "conversion \"%s\" already exists" msgstr "преобразование \"%s\" уже ÑущеÑтвует" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:78 #, c-format msgid "default conversion for %s to %s already exists" msgstr "преобразование по умолчанию из %s в %s уже ÑущеÑтвует" -#: catalog/pg_depend.c:163 commands/extension.c:3213 +#: catalog/pg_depend.c:163 commands/extension.c:3225 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "%s уже отноÑитÑÑ Ðº раÑширению \"%s\"" @@ -5383,74 +5352,74 @@ msgstr "" msgid "schema \"%s\" already exists" msgstr "Ñхема \"%s\" уже ÑущеÑтвует" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:358 +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "Ð¸Ð¼Ñ \"%s\" недопуÑтимо Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð°" -#: catalog/pg_operator.c:367 +#: catalog/pg_operator.c:366 #, c-format msgid "only binary operators can have commutators" msgstr "коммутативную операцию можно определить только Ð´Ð»Ñ Ð±Ð¸Ð½Ð°Ñ€Ð½Ñ‹Ñ… операторов" -#: catalog/pg_operator.c:371 commands/operatorcmds.c:482 +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "" "функцию оценки ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ определить только Ð´Ð»Ñ Ð±Ð¸Ð½Ð°Ñ€Ð½Ñ‹Ñ… операторов" -#: catalog/pg_operator.c:375 +#: catalog/pg_operator.c:374 #, c-format msgid "only binary operators can merge join" msgstr "" "поддержку ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑлиÑнием можно обозначить только Ð´Ð»Ñ Ð±Ð¸Ð½Ð°Ñ€Ð½Ñ‹Ñ… операторов" -#: catalog/pg_operator.c:379 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can hash" msgstr "поддержку хеша можно обозначить только Ð´Ð»Ñ Ð±Ð¸Ð½Ð°Ñ€Ð½Ñ‹Ñ… операторов" -#: catalog/pg_operator.c:390 +#: catalog/pg_operator.c:389 #, c-format msgid "only boolean operators can have negators" msgstr "обратную операцию можно определить только Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑких операторов" -#: catalog/pg_operator.c:394 commands/operatorcmds.c:490 +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "" "функцию оценки Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ определить только Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑких операторов" -#: catalog/pg_operator.c:398 commands/operatorcmds.c:494 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "" "функцию оценки ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ определить только Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑких операторов" -#: catalog/pg_operator.c:402 +#: catalog/pg_operator.c:401 #, c-format msgid "only boolean operators can merge join" msgstr "" "поддержку ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑлиÑнием можно обозначить только Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑких " "операторов" -#: catalog/pg_operator.c:406 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can hash" msgstr "поддержку хеша можно обозначить только Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑких операторов" -#: catalog/pg_operator.c:418 +#: catalog/pg_operator.c:417 #, c-format msgid "operator %s already exists" msgstr "оператор %s уже ÑущеÑтвует" -#: catalog/pg_operator.c:612 +#: catalog/pg_operator.c:611 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "" "оператор не может быть обратным к Ñебе или ÑобÑтвенным оператором Ñортировки" -#: catalog/pg_proc.c:131 parser/parse_func.c:1982 parser/parse_func.c:2022 +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" @@ -5458,7 +5427,7 @@ msgstr[0] "функции не могут иметь больше %d аргум msgstr[1] "функции не могут иметь больше %d аргументов" msgstr[2] "функции не могут иметь больше %d аргументов" -#: catalog/pg_proc.c:244 +#: catalog/pg_proc.c:241 #, c-format msgid "" "A function returning a polymorphic type must have at least one polymorphic " @@ -5467,7 +5436,7 @@ msgstr "" "ФункциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾Ñ€Ñ„Ð½Ñ‹Ð¹ тип, должна иметь минимум один полиморфный " "аргумент." -#: catalog/pg_proc.c:251 +#: catalog/pg_proc.c:248 #, c-format msgid "" "A function returning \"anyrange\" must have at least one \"anyrange\" " @@ -5476,121 +5445,142 @@ msgstr "" "ФункциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ \"anyrange\", должна иметь минимум один аргумент " "\"anyrange\"." -#: catalog/pg_proc.c:269 -#, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "\"%s\" уже ÑвлÑетÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð¼ типа %s" - -#: catalog/pg_proc.c:400 +#: catalog/pg_proc.c:383 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð°Ð¼Ð¸ таких типов уже ÑущеÑтвует" -#: catalog/pg_proc.c:414 catalog/pg_proc.c:437 +#: catalog/pg_proc.c:393 +#, c-format +msgid "cannot change routine kind" +msgstr "тип подпрограммы изменить нельзÑ" + +#: catalog/pg_proc.c:395 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" — Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ." + +#: catalog/pg_proc.c:397 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" — функциÑ." + +#: catalog/pg_proc.c:399 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" — процедура." + +#: catalog/pg_proc.c:401 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\" — Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ." + +#: catalog/pg_proc.c:419 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "определить выходные параметры Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ñ‹ нельзÑ" + +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 #, c-format msgid "cannot change return type of existing function" msgstr "изменить тип возврата ÑущеÑтвующей функции нельзÑ" -#: catalog/pg_proc.c:415 catalog/pg_proc.c:439 catalog/pg_proc.c:482 -#: catalog/pg_proc.c:506 catalog/pg_proc.c:532 +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 +#: catalog/pg_proc.c:520 catalog/pg_proc.c:548 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "Сначала удалите функцию (DROP FUNCTION %s)." +msgid "Use %s %s first." +msgstr "Сначала выполните %s %s." -#: catalog/pg_proc.c:438 +#: catalog/pg_proc.c:447 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "Параметры OUT определÑÑŽÑ‚ другой тип Ñтроки." -#: catalog/pg_proc.c:480 +#: catalog/pg_proc.c:491 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "изменить Ð¸Ð¼Ñ Ð²Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ параметра \"%s\" нельзÑ" -#: catalog/pg_proc.c:505 +#: catalog/pg_proc.c:518 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "" "Ð´Ð»Ñ ÑущеÑтвующей функции Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ±Ñ€Ð°Ñ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð² по умолчанию" -#: catalog/pg_proc.c:531 +#: catalog/pg_proc.c:546 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "" "Ð´Ð»Ñ ÑущеÑтвующего Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° по умолчанию Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип данных" -#: catalog/pg_proc.c:544 -#, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "\"%s\" - Ñто Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" - -#: catalog/pg_proc.c:549 -#, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "\"%s\" - Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" - -#: catalog/pg_proc.c:557 -#, c-format -msgid "function \"%s\" is a window function" -msgstr "\"%s\" - Ñто Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" - -#: catalog/pg_proc.c:562 -#, c-format -msgid "function \"%s\" is not a window function" -msgstr "\"%s\" - Ñто не Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" - -#: catalog/pg_proc.c:768 +#: catalog/pg_proc.c:749 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "вÑтроенной функции \"%s\" нет" -#: catalog/pg_proc.c:866 +#: catalog/pg_proc.c:847 #, c-format msgid "SQL functions cannot return type %s" msgstr "SQL-функции не могут возвращать тип %s" -#: catalog/pg_proc.c:881 +#: catalog/pg_proc.c:862 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "SQL-функции не могут иметь аргументы типа %s" -#: catalog/pg_proc.c:968 executor/functions.c:1428 +#: catalog/pg_proc.c:950 executor/functions.c:1434 #, c-format msgid "SQL function \"%s\"" msgstr "SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\"" +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" - ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" + #: catalog/pg_publication.c:59 #, c-format +msgid "Adding partitioned tables to publications is not supported." +msgstr "Добавление Ñекционированных таблиц в публикации не поддерживаетÑÑ." + +#: catalog/pg_publication.c:60 +#, c-format +msgid "You can add the table partitions individually." +msgstr "Ðо вы можете добавить Ñекции таблицы по одной." + +#: catalog/pg_publication.c:68 +#, c-format msgid "Only tables can be added to publications." msgstr "Ð’ публикации можно добавлÑть только таблицы." -#: catalog/pg_publication.c:65 +#: catalog/pg_publication.c:74 #, c-format msgid "\"%s\" is a system table" msgstr "\"%s\" - Ñто ÑиÑÑ‚ÐµÐ¼Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: catalog/pg_publication.c:67 +#: catalog/pg_publication.c:76 #, c-format msgid "System tables cannot be added to publications." msgstr "СиÑтемные таблицы Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð»Ñть в публикации." -#: catalog/pg_publication.c:73 +#: catalog/pg_publication.c:82 #, c-format msgid "table \"%s\" cannot be replicated" msgstr "реплицировать таблицу \"%s\" нельзÑ" -#: catalog/pg_publication.c:75 +#: catalog/pg_publication.c:84 #, c-format msgid "Temporary and unlogged relations cannot be replicated." msgstr "Временные и нежурналируемые Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ поддерживают репликацию." -#: catalog/pg_publication.c:134 +#: catalog/pg_publication.c:175 #, c-format msgid "relation \"%s\" is already member of publication \"%s\"" msgstr "отношение \"%s\" уже включено в публикацию \"%s\"" -#: catalog/pg_publication.c:361 catalog/pg_publication.c:382 -#: commands/publicationcmds.c:430 commands/publicationcmds.c:729 +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 +#: commands/publicationcmds.c:415 commands/publicationcmds.c:716 #, c-format msgid "publication \"%s\" does not exist" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ \"%s\" не ÑущеÑтвует" @@ -5670,52 +5660,52 @@ msgstr "" "изменить владельца объектов, принадлежащих роли %s, нельзÑ, так как они " "нужны ÑиÑтеме баз данных" -#: catalog/pg_subscription.c:163 commands/subscriptioncmds.c:565 -#: commands/subscriptioncmds.c:734 commands/subscriptioncmds.c:912 +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 +#: commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 #, c-format msgid "subscription \"%s\" does not exist" msgstr "подпиÑка \"%s\" не ÑущеÑтвует" -#: catalog/pg_type.c:136 catalog/pg_type.c:452 +#: catalog/pg_type.c:135 catalog/pg_type.c:459 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "значение OID в pg_type не задано в режиме двоичного обновлениÑ" -#: catalog/pg_type.c:251 +#: catalog/pg_type.c:241 #, c-format msgid "invalid type internal size %d" msgstr "неверный внутренний размер типа: %d" -#: catalog/pg_type.c:267 catalog/pg_type.c:275 catalog/pg_type.c:283 -#: catalog/pg_type.c:292 +#: catalog/pg_type.c:257 catalog/pg_type.c:265 catalog/pg_type.c:273 +#: catalog/pg_type.c:282 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "" "выравнивание \"%c\" не подходит Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð°, передаваемого по значению (Ñ " "размером: %d)" -#: catalog/pg_type.c:299 +#: catalog/pg_type.c:289 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "внутренний размер %d не подходит Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð°, передаваемого по значению" -#: catalog/pg_type.c:308 catalog/pg_type.c:314 +#: catalog/pg_type.c:298 catalog/pg_type.c:304 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "выравнивание \"%c\" не подходит Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° переменной длины" -#: catalog/pg_type.c:322 +#: catalog/pg_type.c:312 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² поÑтоÑнного размера применим только режим Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ PLAIN" -#: catalog/pg_type.c:781 +#: catalog/pg_type.c:801 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "не удалоÑÑŒ Ñформировать Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð° маÑÑива Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° \"%s\"" -#: catalog/toasting.c:105 commands/indexcmds.c:395 commands/tablecmds.c:4674 -#: commands/tablecmds.c:12626 +#: catalog/toasting.c:105 commands/indexcmds.c:444 commands/tablecmds.c:5023 +#: commands/tablecmds.c:13988 #, c-format msgid "\"%s\" is not a table or materialized view" msgstr "\"%s\" - Ñто не таблица и не материализованное предÑтавление" @@ -5725,77 +5715,77 @@ msgstr "\"%s\" - Ñто не таблица и не материализован msgid "shared tables cannot be toasted after initdb" msgstr "в разделÑемые таблицы Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ TOAST поÑле initdb" -#: commands/aggregatecmds.c:157 +#: commands/aggregatecmds.c:166 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "гипотезирующими могут быть только Ñортирующие агрегатные функции" -#: commands/aggregatecmds.c:182 +#: commands/aggregatecmds.c:191 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "нераÑпознанный атрибут \"%s\" в определении агрегатной функции" -#: commands/aggregatecmds.c:192 +#: commands/aggregatecmds.c:201 #, c-format msgid "aggregate stype must be specified" msgstr "в определении агрегата требуетÑÑ stype" -#: commands/aggregatecmds.c:196 +#: commands/aggregatecmds.c:205 #, c-format msgid "aggregate sfunc must be specified" msgstr "в определении агрегата требуетÑÑ sfunc" -#: commands/aggregatecmds.c:208 +#: commands/aggregatecmds.c:217 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "в определении агрегата требуетÑÑ msfunc, еÑли указан mstype" -#: commands/aggregatecmds.c:212 +#: commands/aggregatecmds.c:221 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "в определении агрегата требуетÑÑ minvfunc, еÑли указан mstype" -#: commands/aggregatecmds.c:219 +#: commands/aggregatecmds.c:228 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "msfunc Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° не должна указыватьÑÑ Ð±ÐµÐ· mstype" -#: commands/aggregatecmds.c:223 +#: commands/aggregatecmds.c:232 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "minvfunc Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° не должна указыватьÑÑ Ð±ÐµÐ· mstype" -#: commands/aggregatecmds.c:227 +#: commands/aggregatecmds.c:236 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "mfinalfunc Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° не должна указыватьÑÑ Ð±ÐµÐ· mstype" -#: commands/aggregatecmds.c:231 +#: commands/aggregatecmds.c:240 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "msspace Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° не должна указыватьÑÑ Ð±ÐµÐ· mstype" -#: commands/aggregatecmds.c:235 +#: commands/aggregatecmds.c:244 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "minitcond Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° не должна указыватьÑÑ Ð±ÐµÐ· mstype" -#: commands/aggregatecmds.c:255 +#: commands/aggregatecmds.c:273 #, c-format msgid "aggregate input type must be specified" msgstr "в определении агрегата требуетÑÑ Ð²Ñ…Ð¾Ð´Ð½Ð¾Ð¹ тип" -#: commands/aggregatecmds.c:285 +#: commands/aggregatecmds.c:303 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "в определении агрегата Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ входного типа не нужен базовый тип" -#: commands/aggregatecmds.c:326 commands/aggregatecmds.c:367 +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "переходным типом агрегата не может быть %s" -#: commands/aggregatecmds.c:338 +#: commands/aggregatecmds.c:356 #, c-format msgid "" "serialization functions may be specified only when the aggregate transition " @@ -5804,19 +5794,26 @@ msgstr "" "функции Ñериализации могут задаватьÑÑ, только когда переходный тип данных " "агрегата - %s" -#: commands/aggregatecmds.c:348 +#: commands/aggregatecmds.c:366 #, c-format msgid "" "must specify both or neither of serialization and deserialization functions" msgstr "функции Ñериализации и деÑериализации должны задаватьÑÑ ÑовмеÑтно" -#: commands/aggregatecmds.c:413 commands/functioncmds.c:564 +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "" "параметр \"parallel\" должен иметь значение SAFE, RESTRICTED или UNSAFE" -#: commands/alter.c:84 commands/event_trigger.c:234 +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "" +"параметр \"%s\" должен иметь характериÑтику READ_ONLY, SHAREABLE или " +"READ_WRITE" + +#: commands/alter.c:84 commands/event_trigger.c:236 #, c-format msgid "event trigger \"%s\" already exists" msgstr "Ñобытийный триггер \"%s\" уже ÑущеÑтвует" @@ -5831,17 +5828,17 @@ msgstr "обёртка Ñторонних данных \"%s\" уже ÑÑƒÑ‰ÐµÑ msgid "server \"%s\" already exists" msgstr "Ñервер \"%s\" уже ÑущеÑтвует" -#: commands/alter.c:93 commands/proclang.c:367 +#: commands/alter.c:93 commands/proclang.c:363 #, c-format msgid "language \"%s\" already exists" msgstr "Ñзык \"%s\" уже ÑущеÑтвует" -#: commands/alter.c:96 commands/publicationcmds.c:189 +#: commands/alter.c:96 commands/publicationcmds.c:176 #, c-format msgid "publication \"%s\" already exists" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ \"%s\" уже ÑущеÑтвует" -#: commands/alter.c:99 commands/subscriptioncmds.c:308 +#: commands/alter.c:99 commands/subscriptioncmds.c:358 #, c-format msgid "subscription \"%s\" already exists" msgstr "подпиÑка \"%s\" уже ÑущеÑтвует" @@ -5853,8 +5850,8 @@ msgstr "преобразование \"%s\" уже ÑущеÑтвует в ÑÑ… #: commands/alter.c:126 #, c-format -msgid "statistics \"%s\" already exists in schema \"%s\"" -msgstr "ÑтатиÑтика \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "объект ÑтатиÑтики \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" #: commands/alter.c:130 #, c-format @@ -5881,7 +5878,7 @@ msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\" уже msgid "must be superuser to rename %s" msgstr "переименовать \"%s\" может только Ñуперпользователь" -#: commands/alter.c:677 +#: commands/alter.c:713 #, c-format msgid "must be superuser to set schema of %s" msgstr "Ð´Ð»Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñхемы объекта %s нужно быть Ñуперпользователем" @@ -5906,8 +5903,8 @@ msgstr "метод доÑтупа \"%s\" уже ÑущеÑтвует" msgid "must be superuser to drop access methods" msgstr "Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð² доÑтупа нужно быть Ñуперпользователем" -#: commands/amcmds.c:174 commands/indexcmds.c:163 commands/indexcmds.c:502 -#: commands/opclasscmds.c:363 commands/opclasscmds.c:777 +#: commands/amcmds.c:174 commands/indexcmds.c:174 commands/indexcmds.c:584 +#: commands/opclasscmds.c:364 commands/opclasscmds.c:778 #, c-format msgid "access method \"%s\" does not exist" msgstr "метод доÑтупа \"%s\" не ÑущеÑтвует" @@ -5917,77 +5914,87 @@ msgstr "метод доÑтупа \"%s\" не ÑущеÑтвует" msgid "handler function is not specified" msgstr "не указана функциÑ-обработчик" -#: commands/amcmds.c:262 commands/event_trigger.c:243 -#: commands/foreigncmds.c:487 commands/proclang.c:117 commands/proclang.c:289 -#: commands/trigger.c:538 parser/parse_clause.c:986 +#: commands/amcmds.c:262 commands/event_trigger.c:245 +#: commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 +#: commands/trigger.c:696 parser/parse_clause.c:990 #, c-format msgid "function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s должна возвращать тип %s" -#: commands/analyze.c:151 +#: commands/analyze.c:187 #, c-format msgid "skipping analyze of \"%s\" --- lock not available" msgstr "анализ \"%s\" пропуÑкаетÑÑ --- блокировка недоÑтупна" -#: commands/analyze.c:168 +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "анализ \"%s\" пропуÑкаетÑÑ --- Ñто отношение более не ÑущеÑтвует" + +#: commands/analyze.c:209 #, c-format msgid "skipping \"%s\" --- only superuser can analyze it" msgstr "" "\"%s\" пропуÑкаетÑÑ --- только Ñуперпользователь может анализировать Ñтот " "объект" -#: commands/analyze.c:172 +#: commands/analyze.c:213 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can analyze it" msgstr "" "\"%s\" пропуÑкаетÑÑ --- только Ñуперпользователь или владелец БД может " "анализировать Ñтот объект" -#: commands/analyze.c:176 +#: commands/analyze.c:217 #, c-format msgid "skipping \"%s\" --- only table or database owner can analyze it" msgstr "" "\"%s\" пропуÑкаетÑÑ --- только владелец таблицы или БД может анализировать " "Ñтот объект" -#: commands/analyze.c:236 +#: commands/analyze.c:275 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "\"%s\" пропуÑкаетÑÑ --- анализировать Ñту Ñтороннюю таблицу нельзÑ" -#: commands/analyze.c:253 +#: commands/analyze.c:292 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "" "\"%s\" пропуÑкаетÑÑ --- анализировать не таблицы или Ñпециальные ÑиÑтемные " "таблицы нельзÑ" -#: commands/analyze.c:334 +#: commands/analyze.c:373 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "анализируетÑÑ Ð´ÐµÑ€ÐµÐ²Ð¾ наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s.%s\"" -#: commands/analyze.c:339 +#: commands/analyze.c:378 #, c-format msgid "analyzing \"%s.%s\"" msgstr "анализируетÑÑ \"%s.%s\"" -#: commands/analyze.c:668 +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" указан неоднократно" + +#: commands/analyze.c:718 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "автоматичеÑкий анализ таблицы \"%s.%s.%s\"; нагрузка ÑиÑтемы: %s" -#: commands/analyze.c:1220 +#: commands/analyze.c:1288 #, c-format msgid "" "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead " "rows; %d rows in sample, %.0f estimated total rows" msgstr "" -"\"%s\": проÑканировано Ñтраниц: %d из %u, они Ñодержат \"живых\" Ñтрок: " -"%.0f, \"мёртвых\" Ñтрок: %.0f; Ñтрок в выборке: %d, примерное общее чиÑло " +"\"%s\": проÑканировано Ñтраниц: %d из %u, они Ñодержат \"живых\" Ñтрок: %." +"0f, \"мёртвых\" Ñтрок: %.0f; Ñтрок в выборке: %d, примерное общее чиÑло " "Ñтрок: %.0f" -#: commands/analyze.c:1300 +#: commands/analyze.c:1368 #, c-format msgid "" "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " @@ -5996,7 +6003,7 @@ msgstr "" "пропуÑкаетÑÑ Ð°Ð½Ð°Ð»Ð¸Ð· дерева наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s.%s\" --- Ñто дерево " "наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ Ñодержит дочерних таблиц" -#: commands/analyze.c:1398 +#: commands/analyze.c:1466 #, c-format msgid "" "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " @@ -6005,22 +6012,22 @@ msgstr "" "пропуÑкаетÑÑ Ð°Ð½Ð°Ð»Ð¸Ð· дерева наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s.%s\" --- Ñто дерево " "наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ Ñодержит анализируемых дочерних таблиц" -#: commands/async.c:555 +#: commands/async.c:558 #, c-format msgid "channel name cannot be empty" msgstr "Ð¸Ð¼Ñ ÐºÐ°Ð½Ð°Ð»Ð° не может быть пуÑтым" -#: commands/async.c:560 +#: commands/async.c:563 #, c-format msgid "channel name too long" msgstr "Ñлишком длинное Ð¸Ð¼Ñ ÐºÐ°Ð½Ð°Ð»Ð°" -#: commands/async.c:567 +#: commands/async.c:570 #, c-format msgid "payload string too long" msgstr "Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñтрока ÑообщениÑ-нагрузки" -#: commands/async.c:753 +#: commands/async.c:756 #, c-format msgid "" "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" @@ -6028,17 +6035,17 @@ msgstr "" "выполнить PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ð¼Ð¸ LISTEN, UNLISTEN или NOTIFY " "нельзÑ" -#: commands/async.c:856 +#: commands/async.c:859 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "Ñлишком много уведомлений в очереди NOTIFY" -#: commands/async.c:1486 +#: commands/async.c:1491 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "очередь NOTIFY заполнена на %.0f%%" -#: commands/async.c:1488 +#: commands/async.c:1493 #, c-format msgid "" "The server process with PID %d is among those with the oldest transactions." @@ -6046,7 +6053,7 @@ msgstr "" "Ð’ чиÑло Ñерверных процеÑÑов Ñ Ñамыми Ñтарыми транзакциÑми входит процеÑÑ Ñ " "PID %d." -#: commands/async.c:1491 +#: commands/async.c:1496 #, c-format msgid "" "The NOTIFY queue cannot be emptied until that process ends its current " @@ -6055,37 +6062,42 @@ msgstr "" "Очередь NOTIFY можно будет оÑвободить, только когда Ñтот процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ñ‚ " "текущую транзакцию." -#: commands/cluster.c:129 commands/cluster.c:364 +#: commands/cluster.c:129 commands/cluster.c:372 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "клаÑтеризовать временные таблицы других ÑеанÑов нельзÑ" -#: commands/cluster.c:159 +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "клаÑтеризовать Ñекционированную таблицу нельзÑ" + +#: commands/cluster.c:167 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "таблица \"%s\" ранее не клаÑтеризовалаÑÑŒ по какому-либо индекÑу" -#: commands/cluster.c:173 commands/tablecmds.c:9857 commands/tablecmds.c:11720 +#: commands/cluster.c:181 commands/tablecmds.c:11145 commands/tablecmds.c:13050 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" не ÑущеÑтвует" -#: commands/cluster.c:353 +#: commands/cluster.c:361 #, c-format msgid "cannot cluster a shared catalog" msgstr "клаÑтеризовать разделÑемый каталог нельзÑ" -#: commands/cluster.c:368 +#: commands/cluster.c:376 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "очищать временные таблицы других ÑеанÑов нельзÑ" -#: commands/cluster.c:431 commands/tablecmds.c:11730 +#: commands/cluster.c:439 commands/tablecmds.c:13060 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "\"%s\" не ÑвлÑетÑÑ Ð¸Ð½Ð´ÐµÐºÑом таблицы \"%s\"" -#: commands/cluster.c:439 +#: commands/cluster.c:447 #, c-format msgid "" "cannot cluster on index \"%s\" because access method does not support " @@ -6093,33 +6105,38 @@ msgid "" msgstr "" "клаÑÑ‚ÐµÑ€Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ индекÑу \"%s\" невозможна, её не поддерживает метод доÑтупа" -#: commands/cluster.c:451 +#: commands/cluster.c:459 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "клаÑтеризовать по чаÑтичному индекÑу \"%s\" нельзÑ" -#: commands/cluster.c:465 +#: commands/cluster.c:473 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÐºÐ»Ð°Ñтеризовать таблицу по неверному индекÑу \"%s\"" -#: commands/cluster.c:918 +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "пометить Ð¸Ð½Ð´ÐµÐºÑ ÐºÐ°Ðº клаÑтеризованный в Ñекционированной таблице нельзÑ" + +#: commands/cluster.c:938 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "клаÑÑ‚ÐµÑ€Ð¸Ð·Ð°Ñ†Ð¸Ñ \"%s.%s\" путём ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа \"%s\"" -#: commands/cluster.c:924 +#: commands/cluster.c:944 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "" "клаÑÑ‚ÐµÑ€Ð¸Ð·Ð°Ñ†Ð¸Ñ \"%s.%s\" путём поÑледовательного ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Ñортировки" -#: commands/cluster.c:929 commands/vacuumlazy.c:491 +#: commands/cluster.c:949 commands/vacuumlazy.c:505 #, c-format msgid "vacuuming \"%s.%s\"" msgstr "очиÑтка \"%s.%s\"" -#: commands/cluster.c:1084 +#: commands/cluster.c:1106 #, c-format msgid "" "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" @@ -6127,7 +6144,7 @@ msgstr "" "\"%s\": найдено удалÑемых верÑий Ñтрок: %.0f, неудалÑемых - %.0f, " "проÑмотрено Ñтраниц: %u" -#: commands/cluster.c:1088 +#: commands/cluster.c:1110 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -6136,93 +6153,84 @@ msgstr "" "Ð’ данный момент Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ \"мёртвых\" Ñтрок %.0f.\n" "%s." -#: commands/collationcmds.c:93 +#: commands/collationcmds.c:100 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "атрибут COLLATION \"%s\" не раÑпознан" -#: commands/collationcmds.c:152 +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "правило Ñортировки \"default\" Ð½ÐµÐ»ÑŒÐ·Ñ Ñкопировать" + +#: commands/collationcmds.c:172 #, c-format msgid "unrecognized collation provider: %s" msgstr "нераÑпознанный поÑтавщик правил Ñортировки: %s" -#: commands/collationcmds.c:161 +#: commands/collationcmds.c:181 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "необходимо указать параметр \"lc_collate\"" -#: commands/collationcmds.c:166 +#: commands/collationcmds.c:186 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "необходимо указать параметр \"lc_ctype\"" -#: commands/collationcmds.c:217 +#: commands/collationcmds.c:245 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "" "правило Ñортировки \"%s\" Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" -#: commands/collationcmds.c:228 +#: commands/collationcmds.c:256 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "правило Ñортировки \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" -#: commands/collationcmds.c:276 +#: commands/collationcmds.c:304 #, c-format msgid "changing version from %s to %s" msgstr "изменение верÑии Ñ %s на %s" -#: commands/collationcmds.c:291 +#: commands/collationcmds.c:319 #, c-format msgid "version has not changed" msgstr "верÑÐ¸Ñ Ð½Ðµ была изменена" -#: commands/collationcmds.c:382 +#: commands/collationcmds.c:450 #, c-format msgid "could not convert locale name \"%s\" to language tag: %s" msgstr "не удалоÑÑŒ получить из Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\" метку Ñзыка: %s" -#: commands/collationcmds.c:401 -#, c-format -msgid "could get display name for locale \"%s\": %s" -msgstr "не удалоÑÑŒ получить отображаемое название локали \"%s\": %s" - -#: commands/collationcmds.c:432 +#: commands/collationcmds.c:511 #, c-format msgid "must be superuser to import system collations" msgstr "" "импортировать ÑиÑтемные правила Ñортировки может только Ñуперпользователь" -#: commands/collationcmds.c:439 commands/copy.c:1835 commands/copy.c:3027 +#: commands/collationcmds.c:534 commands/copy.c:1844 commands/copy.c:3181 +#: libpq/be-secure-common.c:80 #, c-format msgid "could not execute command \"%s\": %m" msgstr "не удалоÑÑŒ выполнить команду \"%s\": %m" -#: commands/collationcmds.c:536 +#: commands/collationcmds.c:665 #, c-format msgid "no usable system locales were found" msgstr "пригодные ÑиÑтемные локали не найдены" -#: commands/collationcmds.c:544 utils/mb/encnames.c:473 -#, c-format -msgid "encoding \"%s\" not supported by ICU" -msgstr "ICU не поддерживает кодировку \"%s\"" - -#: commands/collationcmds.c:588 commands/collationcmds.c:609 -#, c-format -msgid "could not get keyword values for locale \"%s\": %s" -msgstr "не удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\": %s" - #: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 #: commands/dbcommands.c:1100 commands/dbcommands.c:1290 #: commands/dbcommands.c:1513 commands/dbcommands.c:1627 -#: commands/dbcommands.c:2043 utils/init/postinit.c:846 -#: utils/init/postinit.c:951 utils/init/postinit.c:968 +#: commands/dbcommands.c:2043 utils/init/postinit.c:855 +#: utils/init/postinit.c:960 utils/init/postinit.c:977 #, c-format msgid "database \"%s\" does not exist" msgstr "база данных \"%s\" не ÑущеÑтвует" -#: commands/comment.c:100 commands/seclabel.c:117 parser/parse_utilcmd.c:824 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 #, c-format msgid "" "\"%s\" is not a table, view, materialized view, composite type, or foreign " @@ -6231,12 +6239,12 @@ msgstr "" "\"%s\" - Ñто не таблица, предÑтавление, мат. предÑтавление, ÑоÑтавной тип " "или ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2715 +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" была вызвана не менеджером триггеров" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2724 +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð² триггере AFTER Ð´Ð»Ñ Ñтрок" @@ -6246,69 +6254,72 @@ msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð² тригг msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð´Ð»Ñ INSERT или UPDATE" -#: commands/conversioncmds.c:66 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "иÑÑ…Ð¾Ð´Ð½Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° \"%s\" не ÑущеÑтвует" -#: commands/conversioncmds.c:73 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "Ñ†ÐµÐ»ÐµÐ²Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° \"%s\" не ÑущеÑтвует" -#: commands/conversioncmds.c:87 +#: commands/conversioncmds.c:86 #, c-format msgid "encoding conversion function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ %s должна возвращать тип %s" -#: commands/copy.c:370 commands/copy.c:404 +#: commands/copy.c:374 commands/copy.c:408 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPY BINARY не поддерживает Ñтандартный вывод (stdout) и ввод (stdin)" -#: commands/copy.c:504 +#: commands/copy.c:508 #, c-format msgid "could not write to COPY program: %m" msgstr "не удалоÑÑŒ запиÑать в канал программы COPY: %m" -#: commands/copy.c:509 +#: commands/copy.c:513 #, c-format msgid "could not write to COPY file: %m" msgstr "не удалоÑÑŒ запиÑать в файл COPY: %m" -#: commands/copy.c:522 +#: commands/copy.c:526 #, c-format msgid "connection lost during COPY to stdout" msgstr "в процеÑÑе вывода данных COPY в stdout потерÑно Ñоединение" -#: commands/copy.c:566 +#: commands/copy.c:570 #, c-format msgid "could not read from COPY file: %m" msgstr "не удалоÑÑŒ прочитать файл COPY: %m" -#: commands/copy.c:582 commands/copy.c:603 commands/copy.c:607 -#: tcop/postgres.c:341 tcop/postgres.c:377 tcop/postgres.c:404 +#: commands/copy.c:588 commands/copy.c:609 commands/copy.c:613 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "неожиданный обрыв ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð¾Ð¼ при открытой транзакции" -#: commands/copy.c:620 +#: commands/copy.c:626 #, c-format msgid "COPY from stdin failed: %s" msgstr "ошибка при вводе данных COPY из stdin: %s" -#: commands/copy.c:636 +#: commands/copy.c:642 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "неожиданный тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ 0x%02X при вводе данных COPY из stdin" -#: commands/copy.c:798 +#: commands/copy.c:808 #, c-format -msgid "must be superuser to COPY to or from an external program" +msgid "" +"must be superuser or a member of the pg_execute_server_program role to COPY " +"to or from an external program" msgstr "" -"Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ COPY Ñ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¼Ð¸ программами нужно быть Ñуперпользователем" +"Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ COPY Ñ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¼Ð¸ программами нужно быть Ñуперпользователем " +"или членом роли pg_execute_server_program" -#: commands/copy.c:799 commands/copy.c:805 +#: commands/copy.c:809 commands/copy.c:818 commands/copy.c:825 #, c-format msgid "" "Anyone can COPY to stdout or from stdin. psql's \\copy command also works " @@ -6317,263 +6328,276 @@ msgstr "" "Ðе Ð¸Ð¼ÐµÑ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтративных прав, можно иÑпользовать COPY Ñ stdout и stdin (а " "также команду psql \\copy)." -#: commands/copy.c:804 +#: commands/copy.c:817 +#, c-format +msgid "" +"must be superuser or a member of the pg_read_server_files role to COPY from " +"a file" +msgstr "" +"Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ COPY Ñ Ñ‡Ñ‚ÐµÐ½Ð¸ÐµÐ¼ файла нужно быть Ñуперпользователем или членом " +"роли pg_read_server_files" + +#: commands/copy.c:824 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ COPY Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ нужно быть Ñуперпользователем" +msgid "" +"must be superuser or a member of the pg_write_server_files role to COPY to a " +"file" +msgstr "" +"Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ COPY Ñ Ð·Ð°Ð¿Ð¸Ñью в файл нужно быть Ñуперпользователем или " +"членом роли pg_write_server_files" -#: commands/copy.c:871 +#: commands/copy.c:887 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "COPY FROM не поддерживаетÑÑ Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ð¾Ð¹ на уровне Ñтрок." -#: commands/copy.c:872 +#: commands/copy.c:888 #, c-format msgid "Use INSERT statements instead." msgstr "ИÑпользуйте операторы INSERT." -#: commands/copy.c:1058 +#: commands/copy.c:1075 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "формат \"%s\" Ð´Ð»Ñ COPY не раÑпознан" -#: commands/copy.c:1138 commands/copy.c:1154 commands/copy.c:1169 -#: commands/copy.c:1191 +#: commands/copy.c:1155 commands/copy.c:1171 commands/copy.c:1186 +#: commands/copy.c:1208 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "аргументом параметра \"%s\" должен быть ÑпиÑок имён Ñтолбцов" -#: commands/copy.c:1206 +#: commands/copy.c:1223 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "аргументом параметра \"%s\" должно быть название допуÑтимой кодировки" -#: commands/copy.c:1213 commands/dbcommands.c:242 commands/dbcommands.c:1461 +#: commands/copy.c:1230 commands/dbcommands.c:242 commands/dbcommands.c:1461 #, c-format msgid "option \"%s\" not recognized" msgstr "параметр \"%s\" не раÑпознан" -#: commands/copy.c:1225 +#: commands/copy.c:1242 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "в режиме BINARY Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ DELIMITER" -#: commands/copy.c:1230 +#: commands/copy.c:1247 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "в режиме BINARY Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ NULL" -#: commands/copy.c:1252 +#: commands/copy.c:1269 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "разделитель Ð´Ð»Ñ COPY должен быть однобайтным Ñимволом" -#: commands/copy.c:1259 +#: commands/copy.c:1276 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "" "разделителем Ð´Ð»Ñ COPY не может быть Ñимвол новой Ñтроки или возврата каретки" -#: commands/copy.c:1265 +#: commands/copy.c:1282 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "" "предÑтавление NULL Ð´Ð»Ñ COPY не может включать Ñимвол новой Ñтроки или " "возврата каретки" -#: commands/copy.c:1282 +#: commands/copy.c:1299 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "\"%s\" не может быть разделителем Ð´Ð»Ñ COPY" -#: commands/copy.c:1288 +#: commands/copy.c:1305 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "COPY HEADER можно иÑпользовать только в режиме CSV" -#: commands/copy.c:1294 +#: commands/copy.c:1311 #, c-format msgid "COPY quote available only in CSV mode" msgstr "определить кавычки Ð´Ð»Ñ COPY можно только в режиме CSV" -#: commands/copy.c:1299 +#: commands/copy.c:1316 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "Ñимвол кавычек Ð´Ð»Ñ COPY должен быть однобайтным" -#: commands/copy.c:1304 +#: commands/copy.c:1321 #, c-format msgid "COPY delimiter and quote must be different" msgstr "Ñимвол кавычек Ð´Ð»Ñ COPY должен отличатьÑÑ Ð¾Ñ‚ разделителÑ" -#: commands/copy.c:1310 +#: commands/copy.c:1327 #, c-format msgid "COPY escape available only in CSV mode" msgstr "определить ÑпецÑимвол Ð´Ð»Ñ COPY можно только в режиме CSV" -#: commands/copy.c:1315 +#: commands/copy.c:1332 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "ÑпецÑимвол Ð´Ð»Ñ COPY должен быть однобайтным" -#: commands/copy.c:1321 +#: commands/copy.c:1338 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "параметр force quote Ð´Ð»Ñ COPY можно иÑпользовать только в режиме CSV" -#: commands/copy.c:1325 +#: commands/copy.c:1342 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "параметр force quote Ð´Ð»Ñ COPY можно иÑпользовать только Ñ COPY TO" -#: commands/copy.c:1331 +#: commands/copy.c:1348 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "" "параметр force not null Ð´Ð»Ñ COPY можно иÑпользовать только в режиме CSV" -#: commands/copy.c:1335 +#: commands/copy.c:1352 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "параметр force not null Ð´Ð»Ñ COPY можно иÑпользовать только Ñ COPY FROM" -#: commands/copy.c:1341 +#: commands/copy.c:1358 #, c-format msgid "COPY force null available only in CSV mode" msgstr "параметр force null Ð´Ð»Ñ COPY можно иÑпользовать только в режиме CSV" -#: commands/copy.c:1346 +#: commands/copy.c:1363 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "параметр force null Ð´Ð»Ñ COPY можно иÑпользовать только Ñ COPY FROM" -#: commands/copy.c:1352 +#: commands/copy.c:1369 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "разделитель Ð´Ð»Ñ COPY не должен приÑутÑтвовать в предÑтавлении NULL" -#: commands/copy.c:1359 +#: commands/copy.c:1376 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "Ñимвол кавычек в CSV не должен приÑутÑтвовать в предÑтавлении NULL" -#: commands/copy.c:1420 +#: commands/copy.c:1437 #, c-format msgid "table \"%s\" does not have OIDs" msgstr "таблица \"%s\" не Ñодержит OID" -#: commands/copy.c:1461 +#: commands/copy.c:1454 #, c-format msgid "COPY (query) WITH OIDS is not supported" msgstr "COPY (запроÑ) WITH OIDS не поддерживаетÑÑ" -#: commands/copy.c:1482 +#: commands/copy.c:1475 #, c-format msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "правила DO INSTEAD NOTHING не поддерживаютÑÑ Ñ COPY" -#: commands/copy.c:1496 +#: commands/copy.c:1489 #, c-format msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "уÑловные правила DO INSTEAD не поддерживаютÑÑ Ñ COPY" -#: commands/copy.c:1500 +#: commands/copy.c:1493 #, c-format msgid "DO ALSO rules are not supported for the COPY" msgstr "правила DO ALSO не поддерживаютÑÑ Ñ COPY" -#: commands/copy.c:1505 +#: commands/copy.c:1498 #, c-format msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "ÑоÑтавные правила DO INSTEAD не поддерживаютÑÑ Ñ COPY" -#: commands/copy.c:1515 +#: commands/copy.c:1508 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "COPY (SELECT INTO) не поддерживаетÑÑ" -#: commands/copy.c:1532 +#: commands/copy.c:1525 #, c-format msgid "COPY query must have a RETURNING clause" msgstr "в запроÑе COPY должно быть предложение RETURNING" -#: commands/copy.c:1560 +#: commands/copy.c:1553 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "отношение, задейÑтвованное в операторе COPY, изменилоÑÑŒ" -#: commands/copy.c:1618 +#: commands/copy.c:1612 #, c-format msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "Ñтолбец FORCE_QUOTE \"%s\" не фигурирует в COPY" -#: commands/copy.c:1640 +#: commands/copy.c:1635 #, c-format msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "Ñтолбец FORCE_NOT_NULL \"%s\" не фигурирует в COPY" -#: commands/copy.c:1662 +#: commands/copy.c:1658 #, c-format msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "Ñтолбец FORCE_NULL \"%s\" не фигурирует в COPY" -#: commands/copy.c:1727 +#: commands/copy.c:1724 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "не удалоÑÑŒ закрыть канал Ñообщений Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ командой: %m" -#: commands/copy.c:1731 +#: commands/copy.c:1739 #, c-format msgid "program \"%s\" failed" msgstr "Ñбой программы \"%s\"" -#: commands/copy.c:1781 +#: commands/copy.c:1790 #, c-format msgid "cannot copy from view \"%s\"" msgstr "копировать из предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: commands/copy.c:1783 commands/copy.c:1789 commands/copy.c:1795 -#: commands/copy.c:1806 +#: commands/copy.c:1792 commands/copy.c:1798 commands/copy.c:1804 +#: commands/copy.c:1815 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "Попробуйте вариацию COPY (SELECT ...) TO." -#: commands/copy.c:1787 +#: commands/copy.c:1796 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "копировать из материализованного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: commands/copy.c:1793 +#: commands/copy.c:1802 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "копировать из Ñторонней таблицы \"%s\" нельзÑ" -#: commands/copy.c:1799 +#: commands/copy.c:1808 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "копировать из поÑледовательноÑти \"%s\" нельзÑ" -#: commands/copy.c:1804 +#: commands/copy.c:1813 #, c-format msgid "cannot copy from partitioned table \"%s\"" msgstr "копировать из Ñекционированной таблицы \"%s\" нельзÑ" -#: commands/copy.c:1810 +#: commands/copy.c:1819 #, c-format msgid "cannot copy from non-table relation \"%s\"" msgstr "копировать из Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\", не ÑвлÑющегоÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹, нельзÑ" -#: commands/copy.c:1850 +#: commands/copy.c:1859 #, c-format msgid "relative path not allowed for COPY to file" msgstr "при выполнении COPY в файл Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ отноÑительный путь" -#: commands/copy.c:1862 +#: commands/copy.c:1880 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи: %m" -#: commands/copy.c:1865 +#: commands/copy.c:1883 #, c-format msgid "" "COPY TO instructs the PostgreSQL server process to write a file. You may " @@ -6583,74 +6607,74 @@ msgstr "" "Возможно, на Ñамом деле вам нужно клиентÑкое ÑредÑтво, например, \\copy в " "psql." -#: commands/copy.c:1878 commands/copy.c:3058 +#: commands/copy.c:1896 commands/copy.c:3212 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\" - Ñто каталог" -#: commands/copy.c:2201 +#: commands/copy.c:2222 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, Ñтрока %d, Ñтолбец %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, Ñтрока %s, Ñтолбец %s" -#: commands/copy.c:2205 commands/copy.c:2252 +#: commands/copy.c:2226 commands/copy.c:2273 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, Ñтрока %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, Ñтрока %s" -#: commands/copy.c:2216 +#: commands/copy.c:2237 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, Ñтрока %d, Ñтолбец %s: \"%s\"" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, Ñтрока %s, Ñтолбец %s: \"%s\"" -#: commands/copy.c:2224 +#: commands/copy.c:2245 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, Ñтрока %d, Ñтолбец %s: значение NULL" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, Ñтрока %s, Ñтолбец %s: значение NULL" -#: commands/copy.c:2246 +#: commands/copy.c:2267 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, Ñтрока %d: \"%s\"" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, Ñтрока %s: \"%s\"" -#: commands/copy.c:2340 +#: commands/copy.c:2363 #, c-format msgid "cannot copy to view \"%s\"" msgstr "копировать в предÑтавление \"%s\" нельзÑ" -#: commands/copy.c:2342 +#: commands/copy.c:2365 #, c-format msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." msgstr "" "Чтобы предÑтавление допуÑкало копирование данных в него, уÑтановите триггер " "INSTEAD OF INSERT." -#: commands/copy.c:2346 +#: commands/copy.c:2369 #, c-format msgid "cannot copy to materialized view \"%s\"" msgstr "копировать в материализованное предÑтавление \"%s\" нельзÑ" -#: commands/copy.c:2351 -#, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "копировать в Ñтороннюю таблицу \"%s\" нельзÑ" - -#: commands/copy.c:2356 +#: commands/copy.c:2374 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "копировать в поÑледовательноÑть \"%s\" нельзÑ" -#: commands/copy.c:2361 +#: commands/copy.c:2379 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "копировать в отношение \"%s\", не ÑвлÑющееÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹, нельзÑ" -#: commands/copy.c:2424 +#: commands/copy.c:2471 +#, c-format +msgid "cannot perform FREEZE on a partitioned table" +msgstr "выполнить FREEZE в Ñекционированной таблице нельзÑ" + +#: commands/copy.c:2486 #, c-format msgid "cannot perform FREEZE because of prior transaction activity" msgstr "выполнить FREEZE Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·-за предыдущей активноÑти в транзакции" -#: commands/copy.c:2430 +#: commands/copy.c:2492 #, c-format msgid "" "cannot perform FREEZE because the table was not created or truncated in the " @@ -6659,12 +6683,7 @@ msgstr "" "выполнить FREEZE нельзÑ, так как таблица не была Ñоздана или уÑечена в " "текущей подтранзакции" -#: commands/copy.c:2595 executor/nodeModifyTable.c:312 -#, c-format -msgid "cannot route inserted tuples to a foreign table" -msgstr "направить вÑтавлÑемые кортежи в Ñтороннюю таблицу нельзÑ" - -#: commands/copy.c:3045 +#: commands/copy.c:3199 #, c-format msgid "" "COPY FROM instructs the PostgreSQL server process to read a file. You may " @@ -6674,146 +6693,146 @@ msgstr "" "файла. Возможно, на Ñамом деле вам нужно клиентÑкое ÑредÑтво, например, " "\\copy в psql." -#: commands/copy.c:3078 +#: commands/copy.c:3232 #, c-format msgid "COPY file signature not recognized" msgstr "подпиÑÑŒ COPY-файла не раÑпознана" -#: commands/copy.c:3083 +#: commands/copy.c:3237 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "неверный заголовок файла COPY (отÑутÑтвуют флаги)" -#: commands/copy.c:3089 +#: commands/copy.c:3243 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "не раÑпознаны важные флаги в заголовке файла COPY" -#: commands/copy.c:3095 +#: commands/copy.c:3249 #, c-format msgid "invalid COPY file header (missing length)" msgstr "неверный заголовок файла COPY (отÑутÑтвует длина)" -#: commands/copy.c:3102 +#: commands/copy.c:3256 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "неверный заголовок файла COPY (Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°)" -#: commands/copy.c:3235 commands/copy.c:3942 commands/copy.c:4172 +#: commands/copy.c:3387 commands/copy.c:4096 commands/copy.c:4326 #, c-format msgid "extra data after last expected column" msgstr "лишние данные поÑле Ñодержимого поÑледнего Ñтолбца" -#: commands/copy.c:3245 +#: commands/copy.c:3397 #, c-format msgid "missing data for OID column" msgstr "нет данных Ð´Ð»Ñ Ñтолбца OID" -#: commands/copy.c:3251 +#: commands/copy.c:3403 #, c-format msgid "null OID in COPY data" msgstr "неверное значение OID (NULL) в данных COPY" -#: commands/copy.c:3261 commands/copy.c:3384 +#: commands/copy.c:3413 commands/copy.c:3537 #, c-format msgid "invalid OID in COPY data" msgstr "неверный OID в данных COPY" -#: commands/copy.c:3276 +#: commands/copy.c:3429 #, c-format msgid "missing data for column \"%s\"" msgstr "нет данных Ð´Ð»Ñ Ñтолбца \"%s\"" -#: commands/copy.c:3359 +#: commands/copy.c:3512 #, c-format msgid "received copy data after EOF marker" msgstr "поÑле маркера конца файла продолжаютÑÑ Ð´Ð°Ð½Ð½Ñ‹Ðµ COPY" -#: commands/copy.c:3366 +#: commands/copy.c:3519 #, c-format msgid "row field count is %d, expected %d" msgstr "количеÑтво полей в Ñтроке: %d, ожидалоÑÑŒ: %d" -#: commands/copy.c:3706 commands/copy.c:3723 +#: commands/copy.c:3860 commands/copy.c:3877 #, c-format msgid "literal carriage return found in data" msgstr "в данных обнаружен Ñвный возврат каретки" -#: commands/copy.c:3707 commands/copy.c:3724 +#: commands/copy.c:3861 commands/copy.c:3878 #, c-format msgid "unquoted carriage return found in data" msgstr "в данных обнаружен возврат каретки не в кавычках" -#: commands/copy.c:3709 commands/copy.c:3726 +#: commands/copy.c:3863 commands/copy.c:3880 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "ПредÑтавьте возврат каретки как \"\\r\"." -#: commands/copy.c:3710 commands/copy.c:3727 +#: commands/copy.c:3864 commands/copy.c:3881 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "Заключите возврат каретки в кавычки CSV." -#: commands/copy.c:3739 +#: commands/copy.c:3893 #, c-format msgid "literal newline found in data" msgstr "в данных обнаружен Ñвный Ñимвол новой Ñтроки" -#: commands/copy.c:3740 +#: commands/copy.c:3894 #, c-format msgid "unquoted newline found in data" msgstr "в данных обнаружен Ñвный Ñимвол новой Ñтроки не в кавычках" -#: commands/copy.c:3742 +#: commands/copy.c:3896 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "ПредÑтавьте Ñимвол новой Ñтроки как \"\\n\"." -#: commands/copy.c:3743 +#: commands/copy.c:3897 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "Заключите Ñимвол новой Ñтроки в кавычки CSV." -#: commands/copy.c:3789 commands/copy.c:3825 +#: commands/copy.c:3943 commands/copy.c:3979 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "маркер \"конец копии\" не ÑоответÑтвует предыдущему Ñтилю новой Ñтроки" -#: commands/copy.c:3798 commands/copy.c:3814 +#: commands/copy.c:3952 commands/copy.c:3968 #, c-format msgid "end-of-copy marker corrupt" msgstr "маркер \"конец копии\" иÑпорчен" -#: commands/copy.c:4256 +#: commands/copy.c:4410 #, c-format msgid "unterminated CSV quoted field" msgstr "незавершённое поле в кавычках CSV" -#: commands/copy.c:4333 commands/copy.c:4352 +#: commands/copy.c:4487 commands/copy.c:4506 #, c-format msgid "unexpected EOF in COPY data" msgstr "неожиданный конец данных COPY" -#: commands/copy.c:4342 +#: commands/copy.c:4496 #, c-format msgid "invalid field size" msgstr "неверный размер полÑ" -#: commands/copy.c:4365 +#: commands/copy.c:4519 #, c-format msgid "incorrect binary data format" msgstr "неверный двоичный формат данных" -#: commands/copy.c:4676 commands/indexcmds.c:1057 commands/tablecmds.c:1655 -#: commands/tablecmds.c:2150 commands/tablecmds.c:2573 -#: parser/parse_relation.c:3248 parser/parse_relation.c:3268 -#: utils/adt/tsvector_op.c:2561 +#: commands/copy.c:4831 commands/indexcmds.c:1484 commands/statscmds.c:206 +#: commands/tablecmds.c:1908 commands/tablecmds.c:2465 +#: commands/tablecmds.c:2846 parser/parse_relation.c:3288 +#: parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 #, c-format msgid "column \"%s\" does not exist" msgstr "Ñтолбец \"%s\" не ÑущеÑтвует" -#: commands/copy.c:4683 commands/tablecmds.c:1681 commands/trigger.c:748 -#: parser/parse_target.c:1018 parser/parse_target.c:1029 +#: commands/copy.c:4838 commands/tablecmds.c:1935 commands/trigger.c:913 +#: parser/parse_target.c:1046 parser/parse_target.c:1057 #, c-format msgid "column \"%s\" specified more than once" msgstr "Ñтолбец \"%s\" указан неоднократно" @@ -6848,8 +6867,8 @@ msgstr "%d не ÑвлÑетÑÑ Ð²ÐµÑ€Ð½Ñ‹Ð¼ кодом кодировки" msgid "%s is not a valid encoding name" msgstr "%s не ÑвлÑетÑÑ Ð²ÐµÑ€Ð½Ñ‹Ð¼ названием кодировки" -#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:289 -#: commands/user.c:665 +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 +#: commands/user.c:664 #, c-format msgid "invalid connection limit: %d" msgstr "неверный предел подключений: %d" @@ -6902,8 +6921,8 @@ msgid "" "new collation (%s) is incompatible with the collation of the template " "database (%s)" msgstr "" -"новое правило Ñортировки (%s) неÑовмеÑтимо Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð¾Ð¼ в шаблоне базы данных " -"(%s)" +"новое правило Ñортировки (%s) неÑовмеÑтимо Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð¾Ð¼ в шаблоне базы данных (" +"%s)" #: commands/dbcommands.c:403 #, c-format @@ -6920,8 +6939,8 @@ msgid "" "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database " "(%s)" msgstr "" -"новый параметр LC_CTYPE (%s) неÑовмеÑтим Ñ LC_CTYPE в шаблоне базы данных " -"(%s)" +"новый параметр LC_CTYPE (%s) неÑовмеÑтим Ñ LC_CTYPE в шаблоне базы данных (" +"%s)" #: commands/dbcommands.c:410 #, c-format @@ -6999,8 +7018,8 @@ msgstr "база \"%s\" иÑпользуетÑÑ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ‹Ð¼ Ñлотом #: commands/dbcommands.c:860 #, c-format -msgid "There is %d active slot" -msgid_plural "There are %d active slots" +msgid "There is %d active slot." +msgid_plural "There are %d active slots." msgstr[0] "Обнаружен %d активный Ñлот." msgstr[1] "Обнаружены %d активных Ñлота." msgstr[2] "Обнаружено %d активных Ñлотов." @@ -7057,8 +7076,8 @@ msgstr "" "проÑтранÑтво по умолчанию Ð´Ð»Ñ Ñтой базы данных." #: commands/dbcommands.c:1355 commands/dbcommands.c:1900 -#: commands/dbcommands.c:2104 commands/dbcommands.c:2158 -#: commands/tablespace.c:604 +#: commands/dbcommands.c:2104 commands/dbcommands.c:2159 +#: commands/tablespace.c:606 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "в Ñтаром каталоге базы данных \"%s\" могли оÑтатьÑÑ Ð½ÐµÐ½ÑƒÐ¶Ð½Ñ‹Ðµ файлы" @@ -7084,8 +7103,8 @@ msgid "" "There are %d other session(s) and %d prepared transaction(s) using the " "database." msgstr "" -"С Ñтой базой данных ÑвÑзаны другие ÑеанÑÑ‹ (%d) и подготовленные транзакции " -"(%d)." +"С Ñтой базой данных ÑвÑзаны другие ÑеанÑÑ‹ (%d) и подготовленные транзакции (" +"%d)." #: commands/dbcommands.c:1990 #, c-format @@ -7140,30 +7159,30 @@ msgstr "аргументом %s должно быть Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð°" msgid "invalid argument for %s: \"%s\"" msgstr "неверный аргумент Ð´Ð»Ñ %s: \"%s\"" -#: commands/dropcmds.c:104 commands/functioncmds.c:1200 -#: utils/adt/ruleutils.c:2355 +#: commands/dropcmds.c:99 commands/functioncmds.c:1212 +#: utils/adt/ruleutils.c:2563 #, c-format msgid "\"%s\" is an aggregate function" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" ÑвлÑетÑÑ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð¾Ð¹" -#: commands/dropcmds.c:106 +#: commands/dropcmds.c:101 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "ИÑпользуйте DROP AGGREGATE Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ñ‹Ñ… функций." -#: commands/dropcmds.c:157 commands/sequence.c:430 commands/tablecmds.c:2657 -#: commands/tablecmds.c:2808 commands/tablecmds.c:2851 -#: commands/tablecmds.c:12103 tcop/utility.c:1168 +#: commands/dropcmds.c:157 commands/sequence.c:440 commands/tablecmds.c:2930 +#: commands/tablecmds.c:3088 commands/tablecmds.c:3131 +#: commands/tablecmds.c:13433 tcop/utility.c:1170 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "отношение \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:896 +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1020 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "Ñхема \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:252 +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:254 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "тип \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" @@ -7185,8 +7204,8 @@ msgstr "преобразование \"%s\" не ÑущеÑтвует, проп #: commands/dropcmds.c:292 #, c-format -msgid "extended statistics \"%s\" do not exist, skipping" -msgstr "раÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ ÑтатиÑтика \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "объект ÑтатиÑтики \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" #: commands/dropcmds.c:299 #, c-format @@ -7213,73 +7232,83 @@ msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\" не msgid "extension \"%s\" does not exist, skipping" msgstr "раÑширение \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:334 +#: commands/dropcmds.c:335 #, c-format msgid "function %s(%s) does not exist, skipping" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s(%s) не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:346 +#: commands/dropcmds.c:348 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "процедура %s(%s) не ÑущеÑтвует, пропуÑкаетÑÑ" + +#: commands/dropcmds.c:361 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "подпрограмма %s(%s) не ÑущеÑтвует, пропуÑкаетÑÑ" + +#: commands/dropcmds.c:374 #, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s(%s) не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:358 +#: commands/dropcmds.c:387 #, c-format msgid "operator %s does not exist, skipping" msgstr "оператор %s не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:364 +#: commands/dropcmds.c:393 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "Ñзык \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:373 +#: commands/dropcmds.c:402 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "приведение %s к типу %s не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:382 +#: commands/dropcmds.c:411 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "преобразование Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s, Ñзыка \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:390 +#: commands/dropcmds.c:419 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr "триггер \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:399 +#: commands/dropcmds.c:428 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr "политика \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:406 +#: commands/dropcmds.c:435 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "Ñобытийный триггер \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:412 +#: commands/dropcmds.c:441 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr "правило \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:419 +#: commands/dropcmds.c:448 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "обёртка Ñторонних данных \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:423 +#: commands/dropcmds.c:452 #, c-format msgid "server \"%s\" does not exist, skipping" msgstr "Ñервер \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/dropcmds.c:432 +#: commands/dropcmds.c:461 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" msgstr "" "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" не ÑущеÑтвует Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\", пропуÑкаетÑÑ" -#: commands/dropcmds.c:444 +#: commands/dropcmds.c:473 #, c-format msgid "" "operator family \"%s\" does not exist for access method \"%s\", skipping" @@ -7287,215 +7316,215 @@ msgstr "" "ÑемейÑтво операторов \"%s\" не ÑущеÑтвует Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\", " "пропуÑкаетÑÑ" -#: commands/dropcmds.c:451 +#: commands/dropcmds.c:480 #, c-format msgid "publication \"%s\" does not exist, skipping" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/event_trigger.c:185 +#: commands/event_trigger.c:187 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "нет прав на Ñоздание Ñобытийного триггера \"%s\"" -#: commands/event_trigger.c:187 +#: commands/event_trigger.c:189 #, c-format msgid "Must be superuser to create an event trigger." msgstr "Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñобытийного триггера нужно быть Ñуперпользователем." -#: commands/event_trigger.c:196 +#: commands/event_trigger.c:198 #, c-format msgid "unrecognized event name \"%s\"" msgstr "нераÑпознанное Ð¸Ð¼Ñ ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ \"%s\"" -#: commands/event_trigger.c:213 +#: commands/event_trigger.c:215 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð° \"%s\"" -#: commands/event_trigger.c:268 +#: commands/event_trigger.c:270 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "значение фильтра \"%s\" неприемлемо Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ фильтра \"%s\"" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:274 commands/event_trigger.c:344 +#: commands/event_trigger.c:276 commands/event_trigger.c:346 #, c-format msgid "event triggers are not supported for %s" msgstr "Ð´Ð»Ñ %s Ñобытийные триггеры не поддерживаютÑÑ" -#: commands/event_trigger.c:367 +#: commands/event_trigger.c:369 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ„Ð¸Ð»ÑŒÑ‚Ñ€Ð° \"%s\" указана больше одного раза" -#: commands/event_trigger.c:514 commands/event_trigger.c:557 -#: commands/event_trigger.c:649 +#: commands/event_trigger.c:516 commands/event_trigger.c:559 +#: commands/event_trigger.c:651 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "Ñобытийный триггер \"%s\" не ÑущеÑтвует" -#: commands/event_trigger.c:618 +#: commands/event_trigger.c:620 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "нет прав на изменение владельца Ñобытийного триггера \"%s\"" -#: commands/event_trigger.c:620 +#: commands/event_trigger.c:622 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "Владельцем Ñобытийного триггера должен быть Ñуперпользователь." -#: commands/event_trigger.c:1446 +#: commands/event_trigger.c:1457 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%s можно вызывать только в Ñобытийной триггерной функции sql_drop" -#: commands/event_trigger.c:1566 commands/event_trigger.c:1587 +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%s можно вызывать только в Ñобытийной триггерной функции table_rewrite" -#: commands/event_trigger.c:1997 +#: commands/event_trigger.c:2009 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%s можно вызывать только в Ñобытийной триггерной функции" -#: commands/explain.c:194 +#: commands/explain.c:192 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "нераÑпознанное значение параметра EXPLAIN \"%s\": \"%s\"" -#: commands/explain.c:201 +#: commands/explain.c:199 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "нераÑпознанный параметр EXPLAIN: \"%s\"" -#: commands/explain.c:209 +#: commands/explain.c:207 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "параметр BUFFERS оператора EXPLAIN требует ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ ANALYZE" -#: commands/explain.c:218 +#: commands/explain.c:216 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "параметр TIMING оператора EXPLAIN требует ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ ANALYZE" -#: commands/extension.c:167 commands/extension.c:2902 +#: commands/extension.c:168 commands/extension.c:2914 #, c-format msgid "extension \"%s\" does not exist" msgstr "раÑширение \"%s\" не ÑущеÑтвует" -#: commands/extension.c:266 commands/extension.c:275 commands/extension.c:287 -#: commands/extension.c:297 +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 +#: commands/extension.c:298 #, c-format msgid "invalid extension name: \"%s\"" msgstr "неверное Ð¸Ð¼Ñ Ñ€Ð°ÑширениÑ: \"%s\"" -#: commands/extension.c:267 +#: commands/extension.c:268 #, c-format msgid "Extension names must not be empty." msgstr "Ð˜Ð¼Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ может быть пуÑтым." -#: commands/extension.c:276 +#: commands/extension.c:277 #, c-format msgid "Extension names must not contain \"--\"." msgstr "Ð˜Ð¼Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ может Ñодержать \"--\"." -#: commands/extension.c:288 +#: commands/extension.c:289 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "Ð˜Ð¼Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ может начинатьÑÑ Ð¸Ð»Ð¸ заканчиватьÑÑ Ñимволом \"-\"." -#: commands/extension.c:298 +#: commands/extension.c:299 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "Ð˜Ð¼Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ может Ñодержать разделители пути." -#: commands/extension.c:313 commands/extension.c:322 commands/extension.c:331 -#: commands/extension.c:341 +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 +#: commands/extension.c:342 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "неверный идентификатор верÑии раÑширениÑ: \"%s\"" -#: commands/extension.c:314 +#: commands/extension.c:315 #, c-format msgid "Version names must not be empty." msgstr "Идентификатор верÑии не может быть пуÑтым." -#: commands/extension.c:323 +#: commands/extension.c:324 #, c-format msgid "Version names must not contain \"--\"." msgstr "Идентификатор верÑии не может Ñодержать \"--\"." -#: commands/extension.c:332 +#: commands/extension.c:333 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "" "Идентификатор верÑии не может начинатьÑÑ Ð¸Ð»Ð¸ заканчиватьÑÑ Ñимволом \"-\"." -#: commands/extension.c:342 +#: commands/extension.c:343 #, c-format msgid "Version names must not contain directory separator characters." msgstr "Идентификатор верÑии не может Ñодержать разделители пути." -#: commands/extension.c:492 +#: commands/extension.c:493 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "не удалоÑÑŒ открыть управлÑющий файл раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\": %m" -#: commands/extension.c:514 commands/extension.c:524 +#: commands/extension.c:515 commands/extension.c:525 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "" "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ð²Ð°Ñ‚ÑŒ в дополнительном управлÑющем файле раÑширениÑ" -#: commands/extension.c:563 +#: commands/extension.c:564 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "неверное Ð¸Ð¼Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ %s" -#: commands/extension.c:577 +#: commands/extension.c:578 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "параметр \"%s\" должен Ñодержать ÑпиÑок имён раÑширений" -#: commands/extension.c:584 +#: commands/extension.c:585 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "нераÑпознанный параметр \"%s\" в файле \"%s\"" -#: commands/extension.c:593 +#: commands/extension.c:594 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "" "параметр \"schema\" не может быть указан вмеÑте Ñ \"relocatable\" = true" -#: commands/extension.c:757 +#: commands/extension.c:761 #, c-format msgid "" "transaction control statements are not allowed within an extension script" msgstr "в Ñкрипте раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ должно быть операторов ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñми" -#: commands/extension.c:803 +#: commands/extension.c:807 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "нет прав на Ñоздание раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/extension.c:805 +#: commands/extension.c:809 #, c-format msgid "Must be superuser to create this extension." msgstr "Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñтого раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½ÑƒÐ¶Ð½Ð¾ быть Ñуперпользователем." -#: commands/extension.c:809 +#: commands/extension.c:813 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "нет прав на изменение раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/extension.c:811 +#: commands/extension.c:815 #, c-format msgid "Must be superuser to update this extension." msgstr "Ð”Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñтого раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½ÑƒÐ¶Ð½Ð¾ быть Ñуперпользователем." -#: commands/extension.c:1093 +#: commands/extension.c:1097 #, c-format msgid "" "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" @@ -7503,73 +7532,73 @@ msgstr "" "Ð´Ð»Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\" не определён путь Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñ Ð²ÐµÑ€Ñии \"%s\" до верÑии " "\"%s\"" -#: commands/extension.c:1300 commands/extension.c:2963 +#: commands/extension.c:1304 commands/extension.c:2975 #, c-format msgid "version to install must be specified" msgstr "нужно указать верÑию Ð´Ð»Ñ ÑƒÑтановки" -#: commands/extension.c:1322 +#: commands/extension.c:1326 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "верÑÐ¸Ñ FROM должна отличатьÑÑ Ð¾Ñ‚ уÑтанавливаемой верÑии \"%s\"" -#: commands/extension.c:1387 +#: commands/extension.c:1391 #, c-format msgid "" -"extension \"%s\" has no installation script nor update path for version \"%s" -"\"" +"extension \"%s\" has no installation script nor update path for version \"" +"%s\"" msgstr "" "Ð´Ð»Ñ Ñ€Ð°ÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\" не определён путь уÑтановки или Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²ÐµÑ€Ñии " "\"%s\"" -#: commands/extension.c:1422 +#: commands/extension.c:1426 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "раÑширение \"%s\" должно уÑтанавливатьÑÑ Ð² Ñхему \"%s\"" -#: commands/extension.c:1575 +#: commands/extension.c:1586 #, c-format msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "выÑвлена цикличеÑÐºÐ°Ñ Ð·Ð°Ð²Ð¸ÑимоÑть между раÑширениÑми \"%s\" и \"%s\"" -#: commands/extension.c:1580 +#: commands/extension.c:1591 #, c-format msgid "installing required extension \"%s\"" msgstr "уÑтановка требуемого раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/extension.c:1604 +#: commands/extension.c:1615 #, c-format msgid "required extension \"%s\" is not installed" msgstr "требуемое раÑширение \"%s\" не уÑтановлено" -#: commands/extension.c:1607 +#: commands/extension.c:1618 #, c-format msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." msgstr "" "Выполните CREATE EXTENSION ... CASCADE, чтобы уÑтановить также требуемые " "раÑширениÑ." -#: commands/extension.c:1644 +#: commands/extension.c:1655 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "раÑширение \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/extension.c:1651 +#: commands/extension.c:1662 #, c-format msgid "extension \"%s\" already exists" msgstr "раÑширение \"%s\" уже ÑущеÑтвует" -#: commands/extension.c:1662 +#: commands/extension.c:1673 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "вложенные операторы CREATE EXTENSION не поддерживаютÑÑ" -#: commands/extension.c:1843 +#: commands/extension.c:1854 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "удалить раÑширение \"%s\" нельзÑ, так как Ñто модифицируемый объект" -#: commands/extension.c:2345 +#: commands/extension.c:2356 #, c-format msgid "" "pg_extension_config_dump() can only be called from an SQL script executed by " @@ -7578,17 +7607,17 @@ msgstr "" "функцию pg_extension_config_dump() можно вызывать только из SQL-Ñкрипта, " "запуÑкаемого в CREATE EXTENSION" -#: commands/extension.c:2357 +#: commands/extension.c:2368 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u не отноÑитÑÑ Ðº таблице" -#: commands/extension.c:2362 +#: commands/extension.c:2373 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "таблица \"%s\" не отноÑитÑÑ Ðº Ñозданному раÑширению" -#: commands/extension.c:2718 +#: commands/extension.c:2729 #, c-format msgid "" "cannot move extension \"%s\" into schema \"%s\" because the extension " @@ -7597,27 +7626,27 @@ msgstr "" "перемеÑтить раÑширение \"%s\" в Ñхему \"%s\" нельзÑ, так как оно Ñодержит " "Ñхему" -#: commands/extension.c:2758 commands/extension.c:2821 +#: commands/extension.c:2770 commands/extension.c:2833 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "раÑширение \"%s\" не поддерживает SET SCHEMA" -#: commands/extension.c:2823 +#: commands/extension.c:2835 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "объект %s не принадлежит Ñхеме раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/extension.c:2882 +#: commands/extension.c:2894 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "вложенные операторы ALTER EXTENSION не поддерживаютÑÑ" -#: commands/extension.c:2974 +#: commands/extension.c:2986 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "верÑÐ¸Ñ \"%s\" раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \"%s\" уже уÑтановлена" -#: commands/extension.c:3225 +#: commands/extension.c:3237 #, c-format msgid "" "cannot add schema \"%s\" to extension \"%s\" because the schema contains the " @@ -7626,12 +7655,12 @@ msgstr "" "добавить Ñхему \"%s\" к раÑширению \"%s\" нельзÑ, так как Ñхема Ñодержит " "раÑширение" -#: commands/extension.c:3253 +#: commands/extension.c:3265 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s не отноÑитÑÑ Ðº раÑширению \"%s\"" -#: commands/extension.c:3319 +#: commands/extension.c:3331 #, c-format msgid "file \"%s\" is too large" msgstr "файл \"%s\" Ñлишком большой" @@ -7722,216 +7751,231 @@ msgstr "" msgid "user mapping for \"%s\" already exists for server %s" msgstr "ÑопоÑтавление Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" Ð´Ð»Ñ Ñервера \"%s\" уже ÑущеÑтвует" -#: commands/foreigncmds.c:1278 commands/foreigncmds.c:1393 +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 #, c-format msgid "user mapping for \"%s\" does not exist for the server" msgstr "ÑопоÑтавление Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñервера не ÑущеÑтвует" -#: commands/foreigncmds.c:1380 +#: commands/foreigncmds.c:1384 #, c-format msgid "server does not exist, skipping" msgstr "Ñервер не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/foreigncmds.c:1398 +#: commands/foreigncmds.c:1402 #, c-format msgid "user mapping for \"%s\" does not exist for the server, skipping" msgstr "" "ÑопоÑтавление Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñервера не ÑущеÑтвует, " "пропуÑкаетÑÑ" -#: commands/foreigncmds.c:1549 foreign/foreign.c:357 +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "обёртка Ñторонних данных \"%s\" не имеет обработчика" -#: commands/foreigncmds.c:1555 +#: commands/foreigncmds.c:1559 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "обёртка Ñторонних данных \"%s\" не поддерживает IMPORT FOREIGN SCHEMA" -#: commands/foreigncmds.c:1658 +#: commands/foreigncmds.c:1662 #, c-format msgid "importing foreign table \"%s\"" msgstr "импорт Ñторонней таблицы \"%s\"" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:104 #, c-format msgid "SQL function cannot return shell type %s" msgstr "SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ðµ может возвращать тип-пуÑтышку %s" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:109 #, c-format msgid "return type %s is only a shell" msgstr "возвращаемый тип %s - лишь пуÑтышка" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:139 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð°-пуÑтышки \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ модификатор типа" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:145 #, c-format msgid "type \"%s\" is not yet defined" msgstr "тип \"%s\" ещё не определён" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:146 #, c-format msgid "Creating a shell type definition." msgstr "Создание Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð°-пуÑтышки." -#: commands/functioncmds.c:233 +#: commands/functioncmds.c:238 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ðµ может принимать значение типа-пуÑтышки %s" -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:244 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ðµ может принимать значение типа-пуÑтышки %s" -#: commands/functioncmds.c:244 +#: commands/functioncmds.c:249 #, c-format msgid "argument type %s is only a shell" msgstr "тип аргумента %s - лишь пуÑтышка" -#: commands/functioncmds.c:254 +#: commands/functioncmds.c:259 #, c-format msgid "type %s does not exist" msgstr "тип %s не ÑущеÑтвует" -#: commands/functioncmds.c:268 +#: commands/functioncmds.c:273 #, c-format msgid "aggregates cannot accept set arguments" msgstr "агрегатные функции не принимают в аргументах множеÑтва" -#: commands/functioncmds.c:272 +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "процедуры не принимают в аргументах множеÑтва" + +#: commands/functioncmds.c:281 #, c-format msgid "functions cannot accept set arguments" msgstr "функции не принимают аргументы-множеÑтва" -#: commands/functioncmds.c:282 +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "у процедур не может быть аргументов OUT" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "Ðргументы INOUT допуÑкаютÑÑ." + +#: commands/functioncmds.c:300 #, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "параметр VARIADIC должен быть поÑледним в ÑпиÑке входных параметров" -#: commands/functioncmds.c:310 +#: commands/functioncmds.c:330 #, c-format msgid "VARIADIC parameter must be an array" msgstr "параметр VARIADIC должен быть маÑÑивом" -#: commands/functioncmds.c:350 +#: commands/functioncmds.c:370 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "Ð¸Ð¼Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\" указано неоднократно" -#: commands/functioncmds.c:365 +#: commands/functioncmds.c:385 #, c-format msgid "only input parameters can have default values" msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию могут быть только у входных параметров" -#: commands/functioncmds.c:380 +#: commands/functioncmds.c:400 #, c-format msgid "cannot use table references in parameter default value" msgstr "в значениÑÑ… параметров по умолчанию Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° таблицы" -#: commands/functioncmds.c:404 +#: commands/functioncmds.c:424 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "" "входные параметры, Ñледующие за параметром Ñо значением по умолчанию, также " "должны иметь Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" -#: commands/functioncmds.c:700 +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "некорректный атрибут в определении процедуры" + +#: commands/functioncmds.c:747 #, c-format msgid "no function body specified" msgstr "не указано тело функции" -#: commands/functioncmds.c:710 +#: commands/functioncmds.c:757 #, c-format msgid "no language specified" msgstr "Ñзык не указан" -#: commands/functioncmds.c:735 commands/functioncmds.c:1241 +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 #, c-format msgid "COST must be positive" msgstr "значение COST должно быть положительным" -#: commands/functioncmds.c:743 commands/functioncmds.c:1249 +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 #, c-format msgid "ROWS must be positive" msgstr "значение ROWS должно быть положительным" -#: commands/functioncmds.c:784 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "нераÑпознанный атрибут функции \"%s\" --- игнорируетÑÑ" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:842 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "Ð´Ð»Ñ Ñзыка \"%s\" нужно только одно выражение AS" -#: commands/functioncmds.c:930 commands/functioncmds.c:2110 -#: commands/proclang.c:561 +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 +#: commands/proclang.c:557 #, c-format msgid "language \"%s\" does not exist" msgstr "Ñзык \"%s\" не ÑущеÑтвует" -#: commands/functioncmds.c:932 commands/functioncmds.c:2112 +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "Выполните CREATE LANGUAGE, чтобы загрузить Ñзык в базу данных." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Выполните CREATE EXTENSION, чтобы загрузить Ñзык в базу данных." -#: commands/functioncmds.c:967 commands/functioncmds.c:1233 +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 #, c-format msgid "only superuser can define a leakproof function" msgstr "" "только Ñуперпользователь может определить функцию Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð¼ LEAKPROOF" -#: commands/functioncmds.c:1009 +#: commands/functioncmds.c:1023 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "" "результат функции должен иметь тип %s (в ÑоответÑтвии Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ OUT)" -#: commands/functioncmds.c:1022 +#: commands/functioncmds.c:1036 #, c-format msgid "function result type must be specified" msgstr "необходимо указать тип результата функции" -#: commands/functioncmds.c:1076 commands/functioncmds.c:1253 +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "указание ROWS неприменимо, когда Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÐµÑ‚ не множеÑтво" -#: commands/functioncmds.c:1405 +#: commands/functioncmds.c:1440 #, c-format msgid "source data type %s is a pseudo-type" msgstr "иÑходный тип данных %s ÑвлÑетÑÑ Ð¿Ñевдотипом" -#: commands/functioncmds.c:1411 +#: commands/functioncmds.c:1446 #, c-format msgid "target data type %s is a pseudo-type" msgstr "целевой тип данных %s ÑвлÑетÑÑ Ð¿Ñевдотипом" -#: commands/functioncmds.c:1435 +#: commands/functioncmds.c:1470 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "" "приведение будет проигнорировано, так как иÑходные данные имеют тип домен" -#: commands/functioncmds.c:1440 +#: commands/functioncmds.c:1475 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "" "приведение будет проигнорировано, так как целевые данные имеют тип домен" -#: commands/functioncmds.c:1465 +#: commands/functioncmds.c:1500 #, c-format msgid "cast function must take one to three arguments" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° принимать от одного до трёх аргументов" -#: commands/functioncmds.c:1469 +#: commands/functioncmds.c:1504 #, c-format msgid "" "argument of cast function must match or be binary-coercible from source data " @@ -7940,17 +7984,17 @@ msgstr "" "аргумент функции Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ Ñовпадать или быть двоично-ÑовмеÑтимым Ñ " "иÑходным типом данных" -#: commands/functioncmds.c:1473 +#: commands/functioncmds.c:1508 #, c-format msgid "second argument of cast function must be type %s" msgstr "второй аргумент функции Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ иметь тип %s" -#: commands/functioncmds.c:1478 +#: commands/functioncmds.c:1513 #, c-format msgid "third argument of cast function must be type %s" msgstr "третий аргумент функции Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ иметь тип %s" -#: commands/functioncmds.c:1483 +#: commands/functioncmds.c:1518 #, c-format msgid "" "return data type of cast function must match or be binary-coercible to " @@ -7959,252 +8003,316 @@ msgstr "" "тип возвращаемых данных функции Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ Ñовпадать или быть двоично-" "ÑовмеÑтимым Ñ Ñ†ÐµÐ»ÐµÐ²Ñ‹Ð¼ типом данных" -#: commands/functioncmds.c:1494 +#: commands/functioncmds.c:1529 #, c-format msgid "cast function must not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ может быть изменчивой (volatile)" -#: commands/functioncmds.c:1499 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ может быть агрегатной" - -#: commands/functioncmds.c:1503 +#: commands/functioncmds.c:1534 #, c-format -msgid "cast function must not be a window function" -msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ может быть оконной" +msgid "cast function must be a normal function" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть обычной функцией" -#: commands/functioncmds.c:1507 +#: commands/functioncmds.c:1538 #, c-format msgid "cast function must not return a set" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ может возвращать множеÑтво" -#: commands/functioncmds.c:1533 +#: commands/functioncmds.c:1564 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ WITHOUT FUNCTION нужно быть Ñуперпользователем" -#: commands/functioncmds.c:1548 +#: commands/functioncmds.c:1579 #, c-format msgid "source and target data types are not physically compatible" msgstr "иÑходный и целевой типы данных не ÑовмеÑтимы физичеÑки" -#: commands/functioncmds.c:1563 +#: commands/functioncmds.c:1594 #, c-format msgid "composite data types are not binary-compatible" msgstr "ÑоÑтавные типы данных не ÑовмеÑтимы на двоичном уровне" -#: commands/functioncmds.c:1569 +#: commands/functioncmds.c:1600 #, c-format msgid "enum data types are not binary-compatible" msgstr "типы-перечиÑÐ»ÐµÐ½Ð¸Ñ Ð½Ðµ ÑовмеÑтимы на двоичном уровне" -#: commands/functioncmds.c:1575 +#: commands/functioncmds.c:1606 #, c-format msgid "array data types are not binary-compatible" msgstr "типы-маÑÑивы не ÑовмеÑтимы на двоичном уровне" -#: commands/functioncmds.c:1592 +#: commands/functioncmds.c:1623 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "типы-домены не могут ÑчитатьÑÑ Ð´Ð²Ð¾Ð¸Ñ‡Ð½Ð¾-ÑовмеÑтимыми" -#: commands/functioncmds.c:1602 +#: commands/functioncmds.c:1633 #, c-format msgid "source data type and target data type are the same" msgstr "иÑходный тип данных Ñовпадает Ñ Ñ†ÐµÐ»ÐµÐ²Ñ‹Ð¼" -#: commands/functioncmds.c:1635 +#: commands/functioncmds.c:1666 #, c-format msgid "cast from type %s to type %s already exists" msgstr "приведение типа %s к типу %s уже ÑущеÑтвует" -#: commands/functioncmds.c:1708 +#: commands/functioncmds.c:1739 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "приведение типа %s к типу %s не ÑущеÑтвует" -#: commands/functioncmds.c:1747 +#: commands/functioncmds.c:1778 #, c-format msgid "transform function must not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может быть изменчивой" -#: commands/functioncmds.c:1751 +#: commands/functioncmds.c:1782 #, c-format -msgid "transform function must not be an aggregate function" -msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может быть агрегатной" +msgid "transform function must be a normal function" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть обычной функцией" -#: commands/functioncmds.c:1755 -#, c-format -msgid "transform function must not be a window function" -msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может быть оконной" - -#: commands/functioncmds.c:1759 +#: commands/functioncmds.c:1786 #, c-format msgid "transform function must not return a set" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может возвращать множеÑтво" -#: commands/functioncmds.c:1763 +#: commands/functioncmds.c:1790 #, c-format msgid "transform function must take one argument" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° принимать один аргумент" -#: commands/functioncmds.c:1767 +#: commands/functioncmds.c:1794 #, c-format msgid "first argument of transform function must be type %s" msgstr "первый аргумент функции Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ иметь тип %s" -#: commands/functioncmds.c:1805 +#: commands/functioncmds.c:1832 #, c-format msgid "data type %s is a pseudo-type" msgstr "тип данных %s ÑвлÑетÑÑ Ð¿Ñевдотипом" -#: commands/functioncmds.c:1811 +#: commands/functioncmds.c:1838 #, c-format msgid "data type %s is a domain" msgstr "тип данных \"%s\" ÑвлÑетÑÑ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼" -#: commands/functioncmds.c:1851 +#: commands/functioncmds.c:1878 #, c-format msgid "return data type of FROM SQL function must be %s" msgstr "результат функции FROM SQL должен иметь тип %s" -#: commands/functioncmds.c:1877 +#: commands/functioncmds.c:1904 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "результат функции TO SQL должен иметь тип данных преобразованиÑ" -#: commands/functioncmds.c:1904 +#: commands/functioncmds.c:1931 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "преобразование Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s, Ñзыка \"%s\" уже ÑущеÑтвует" -#: commands/functioncmds.c:1993 +#: commands/functioncmds.c:2020 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "преобразование Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s, Ñзыка \"%s\" не ÑущеÑтвует" -#: commands/functioncmds.c:2044 +#: commands/functioncmds.c:2071 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s уже ÑущеÑтвует в Ñхеме \"%s\"" -#: commands/functioncmds.c:2097 +#: commands/functioncmds.c:2126 #, c-format msgid "no inline code specified" msgstr "нет внедрённого кода" -#: commands/functioncmds.c:2142 +#: commands/functioncmds.c:2172 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "Ñзык \"%s\" не поддерживает выполнение внедрённого кода" -#: commands/indexcmds.c:350 +#: commands/functioncmds.c:2284 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "процедуре Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргумента" +msgstr[1] "процедуре Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргументов" +msgstr[2] "процедуре Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргументов" + +#: commands/indexcmds.c:394 #, c-format msgid "must specify at least one column" msgstr "нужно указать минимум один Ñтолбец" -#: commands/indexcmds.c:354 +#: commands/indexcmds.c:398 #, c-format msgid "cannot use more than %d columns in an index" msgstr "чиÑло Ñтолбцов в индекÑе не может превышать %d" -#: commands/indexcmds.c:385 +#: commands/indexcmds.c:438 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "Ñоздать Ð¸Ð½Ð´ÐµÐºÑ Ð² Ñторонней таблице \"%s\" нельзÑ" -#: commands/indexcmds.c:390 +#: commands/indexcmds.c:463 #, c-format -msgid "cannot create index on partitioned table \"%s\"" -msgstr "Ñоздать Ð¸Ð½Ð´ÐµÐºÑ Ð² Ñекционированной таблице \"%s\" нельзÑ" +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "" +"Ñоздать Ð¸Ð½Ð´ÐµÐºÑ Ð² Ñекционированной таблице \"%s\" параллельным ÑпоÑобом нельзÑ" + +#: commands/indexcmds.c:468 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "" +"Ñоздать ограничение-иÑключение в Ñекционированной таблице \"%s\" нельзÑ" -#: commands/indexcmds.c:405 +#: commands/indexcmds.c:478 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "Ñоздавать индекÑÑ‹ во временных таблицах других ÑеанÑов нельзÑ" -#: commands/indexcmds.c:461 commands/tablecmds.c:579 commands/tablecmds.c:10165 +#: commands/indexcmds.c:543 commands/tablecmds.c:615 +#: commands/tablecmds.c:11454 commands/tablecmds.c:11588 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "" "в табличное проÑтранÑтво pg_global можно помеÑтить только разделÑемые таблицы" -#: commands/indexcmds.c:494 +#: commands/indexcmds.c:576 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "уÑтаревший метод доÑтупа \"rtree\" подменÑетÑÑ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð¼ \"gist\"" -#: commands/indexcmds.c:512 +#: commands/indexcmds.c:594 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "метод доÑтупа \"%s\" не поддерживает уникальные индекÑÑ‹" -#: commands/indexcmds.c:517 +#: commands/indexcmds.c:599 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "метод доÑтупа \"%s\" не поддерживает включаемые Ñтолбцы" + +#: commands/indexcmds.c:604 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "метод доÑтупа \"%s\" не поддерживает индекÑÑ‹ по многим Ñтолбцам" -#: commands/indexcmds.c:522 +#: commands/indexcmds.c:609 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "метод доÑтупа \"%s\" не поддерживает ограничениÑ-иÑключениÑ" -#: commands/indexcmds.c:594 commands/indexcmds.c:614 +#: commands/indexcmds.c:721 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "" +"неподдерживаемое ограничение \"%s\" Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸ÐµÐ¼ ключа ÑекционированиÑ" + +#: commands/indexcmds.c:723 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "" +"ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s не могут иÑпользоватьÑÑ, когда ключи ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°ÑŽÑ‚ " +"выражениÑ." + +#: commands/indexcmds.c:741 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "недоÑтаточно Ñтолбцов в определении Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s" + +#: commands/indexcmds.c:743 +#, c-format +msgid "" +"%s constraint on table \"%s\" lacks column \"%s\" which is part of the " +"partition key." +msgstr "" +"Ð’ ограничении %s таблицы \"%s\" не хватает Ñтолбца \"%s\", входÑщего в ключ " +"ÑекционированиÑ." + +#: commands/indexcmds.c:762 commands/indexcmds.c:782 #, c-format msgid "index creation on system columns is not supported" msgstr "Ñоздание индекÑа Ð´Ð»Ñ ÑиÑтемных Ñтолбцов не поддерживаетÑÑ" -#: commands/indexcmds.c:639 +#: commands/indexcmds.c:807 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%s %s ÑоздаÑÑ‚ неÑвный Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"" -#: commands/indexcmds.c:986 +#: commands/indexcmds.c:1413 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "функции в предикате индекÑа должны быть помечены как IMMUTABLE" -#: commands/indexcmds.c:1052 parser/parse_utilcmd.c:1946 +#: commands/indexcmds.c:1479 parser/parse_utilcmd.c:2237 +#: parser/parse_utilcmd.c:2361 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "указанный в ключе Ñтолбец \"%s\" не ÑущеÑтвует" -#: commands/indexcmds.c:1112 +#: commands/indexcmds.c:1503 parser/parse_utilcmd.c:1586 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð²Ð¾ включаемых Ñтолбцах не поддерживаютÑÑ" + +#: commands/indexcmds.c:1544 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "функции в индекÑном выражении должны быть помечены как IMMUTABLE" -#: commands/indexcmds.c:1135 +#: commands/indexcmds.c:1559 +#, c-format +msgid "including column does not support a collation" +msgstr "включаемые Ñтолбцы не поддерживают правила Ñортировки" + +#: commands/indexcmds.c:1563 +#, c-format +msgid "including column does not support an operator class" +msgstr "включаемые Ñтолбцы не поддерживают клаÑÑÑ‹ операторов" + +#: commands/indexcmds.c:1567 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "включаемые Ñтолбцы не поддерживают Ñортировку ASC/DESC" + +#: commands/indexcmds.c:1571 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "включаемые Ñтолбцы не поддерживают ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ NULLS FIRST/LAST" + +#: commands/indexcmds.c:1598 #, c-format msgid "could not determine which collation to use for index expression" msgstr "не удалоÑÑŒ определить правило Ñортировки Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑного выражениÑ" -#: commands/indexcmds.c:1143 commands/tablecmds.c:13006 commands/typecmds.c:831 -#: parser/parse_expr.c:2730 parser/parse_type.c:549 parser/parse_utilcmd.c:2873 -#: utils/adt/misc.c:661 +#: commands/indexcmds.c:1606 commands/tablecmds.c:14388 +#: commands/typecmds.c:833 parser/parse_expr.c:2772 parser/parse_type.c:549 +#: parser/parse_utilcmd.c:3392 utils/adt/misc.c:681 #, c-format msgid "collations are not supported by type %s" msgstr "тип %s не поддерживает Ñортировку (COLLATION)" -#: commands/indexcmds.c:1181 +#: commands/indexcmds.c:1644 #, c-format msgid "operator %s is not commutative" msgstr "оператор %s не коммутативен" -#: commands/indexcmds.c:1183 +#: commands/indexcmds.c:1646 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "" "Ð’ ограничениÑÑ…-иÑключениÑÑ… могут иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ коммутативные " "операторы." -#: commands/indexcmds.c:1209 +#: commands/indexcmds.c:1672 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "оператор \"%s\" не входит в ÑемейÑтво операторов \"%s\"" -#: commands/indexcmds.c:1212 +#: commands/indexcmds.c:1675 #, c-format msgid "" "The exclusion operator must be related to the index operator class for the " @@ -8213,24 +8321,24 @@ msgstr "" "Оператор иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ отноÑитьÑÑ Ðº клаÑÑу операторов " "индекÑа." -#: commands/indexcmds.c:1247 +#: commands/indexcmds.c:1710 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "метод доÑтупа \"%s\" не поддерживает Ñортировку ASC/DESC" -#: commands/indexcmds.c:1252 +#: commands/indexcmds.c:1715 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "метод доÑтупа \"%s\" не поддерживает параметр NULLS FIRST/LAST" -#: commands/indexcmds.c:1311 commands/typecmds.c:1928 +#: commands/indexcmds.c:1774 commands/typecmds.c:1996 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "" "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s не определён клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² по умолчанию Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° " "доÑтупа \"%s\"" -#: commands/indexcmds.c:1313 +#: commands/indexcmds.c:1776 #, c-format msgid "" "You must specify an operator class for the index or define a default " @@ -8239,56 +8347,72 @@ msgstr "" "Ð’Ñ‹ должны указать клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа или определить клаÑÑ " "операторов по умолчанию Ð´Ð»Ñ Ñтого типа данных." -#: commands/indexcmds.c:1342 commands/indexcmds.c:1350 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1805 commands/indexcmds.c:1813 +#: commands/opclasscmds.c:206 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" не ÑущеÑтвует" -#: commands/indexcmds.c:1363 commands/typecmds.c:1916 +#: commands/indexcmds.c:1826 commands/typecmds.c:1984 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" не принимает тип данных %s" -#: commands/indexcmds.c:1453 +#: commands/indexcmds.c:1916 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "" "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s определено неÑколько клаÑÑов операторов по умолчанию" -#: commands/indexcmds.c:1844 +#: commands/indexcmds.c:2331 #, c-format msgid "table \"%s\" has no indexes" msgstr "таблица \"%s\" не имеет индекÑов" -#: commands/indexcmds.c:1899 +#: commands/indexcmds.c:2386 #, c-format msgid "can only reindex the currently open database" msgstr "переиндекÑировать можно только текущую базу данных" -#: commands/indexcmds.c:1999 +#: commands/indexcmds.c:2504 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "таблица \"%s.%s\" переиндекÑирована" -#: commands/matview.c:181 +#: commands/indexcmds.c:2526 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "REINDEX Ð´Ð»Ñ Ñекционированных индекÑов ещё не реализован" + +#: commands/lockcmds.c:102 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "\"%s\" — не таблица и не предÑтавление" + +#: commands/lockcmds.c:234 rewrite/rewriteHandler.c:1942 +#: rewrite/rewriteHandler.c:3669 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "обнаружена беÑÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ€ÐµÐºÑƒÑ€ÑÐ¸Ñ Ð² правилах Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" + +#: commands/matview.c:179 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" msgstr "" "CONCURRENTLY Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать, когда материализованное предÑтавление не " "наполнено" -#: commands/matview.c:187 +#: commands/matview.c:185 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "параметры CONCURRENTLY и WITH NO DATA иÑключают друг друга" -#: commands/matview.c:257 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "обновить материализованное предÑтавление \"%s\" параллельно нельзÑ" -#: commands/matview.c:260 +#: commands/matview.c:247 #, c-format msgid "" "Create a unique index with no WHERE clause on one or more columns of the " @@ -8297,7 +8421,7 @@ msgstr "" "Создайте уникальный Ð¸Ð½Ð´ÐµÐºÑ Ð±ÐµÐ· Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ WHERE Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ или неÑкольких " "Ñтолбцов материализованного предÑтавлениÑ." -#: commands/matview.c:678 +#: commands/matview.c:645 #, c-format msgid "" "new data for materialized view \"%s\" contains duplicate rows without any " @@ -8306,232 +8430,251 @@ msgstr "" "новые данные Ð´Ð»Ñ Ð¼Ð°Ñ‚ÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" Ñодержат " "дублирующиеÑÑ Ñтроки (без учёта Ñтолбцов Ñ NULL)" -#: commands/matview.c:680 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "Строка: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "ÑемейÑтво операторов \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" не ÑущеÑтвует" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:265 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "ÑемейÑтво операторов \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" уже ÑущеÑтвует" -#: commands/opclasscmds.c:402 +#: commands/opclasscmds.c:403 #, c-format msgid "must be superuser to create an operator class" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ»Ð°ÑÑа операторов нужно быть Ñуперпользователем" -#: commands/opclasscmds.c:475 commands/opclasscmds.c:849 -#: commands/opclasscmds.c:973 +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 +#: commands/opclasscmds.c:974 #, c-format msgid "invalid operator number %d, must be between 1 and %d" -msgstr "неверный номер оператора (%d), должен быть между 1 и %d" +msgstr "неверный номер оператора (%d), требуетÑÑ Ñ‡Ð¸Ñло от 1 до %d" -#: commands/opclasscmds.c:519 commands/opclasscmds.c:893 -#: commands/opclasscmds.c:988 +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 +#: commands/opclasscmds.c:989 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "неверный номер процедуры (%d), должен быть между 1 и %d" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "неверный номер функции (%d), требуетÑÑ Ñ‡Ð¸Ñло от 1 до %d" -#: commands/opclasscmds.c:548 +#: commands/opclasscmds.c:549 #, c-format msgid "storage type specified more than once" msgstr "тип Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ð½ неоднократно" -#: commands/opclasscmds.c:575 +#: commands/opclasscmds.c:576 #, c-format msgid "" "storage type cannot be different from data type for access method \"%s\"" msgstr "" "тип Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ может отличатьÑÑ Ð¾Ñ‚ типа данных Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\"" -#: commands/opclasscmds.c:591 +#: commands/opclasscmds.c:592 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" уже ÑущеÑтвует" -#: commands/opclasscmds.c:619 +#: commands/opclasscmds.c:620 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "" "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" не удалоÑÑŒ Ñделать клаÑÑом по умолчанию Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" -#: commands/opclasscmds.c:622 +#: commands/opclasscmds.c:623 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "КлаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" уже ÑвлÑетÑÑ ÐºÐ»Ð°ÑÑом по умолчанию." -#: commands/opclasscmds.c:747 +#: commands/opclasscmds.c:748 #, c-format msgid "must be superuser to create an operator family" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑемейÑтва операторов нужно быть Ñуперпользователем" -#: commands/opclasscmds.c:803 +#: commands/opclasscmds.c:804 #, c-format msgid "must be superuser to alter an operator family" msgstr "Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑемейÑтва операторов нужно быть Ñуперпользователем" -#: commands/opclasscmds.c:858 +#: commands/opclasscmds.c:859 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "в ALTER OPERATOR FAMILY должны быть указаны типы аргументов оператора" -#: commands/opclasscmds.c:921 +#: commands/opclasscmds.c:922 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "в ALTER OPERATOR FAMILY Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ STORAGE" -#: commands/opclasscmds.c:1043 +#: commands/opclasscmds.c:1044 #, c-format msgid "one or two argument types must be specified" msgstr "нужно указать один или два типа аргументов" -#: commands/opclasscmds.c:1069 +#: commands/opclasscmds.c:1070 #, c-format msgid "index operators must be binary" msgstr "индекÑные операторы должны быть бинарными" -#: commands/opclasscmds.c:1088 +#: commands/opclasscmds.c:1089 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "метод доÑтупа \"%s\" не поддерживает Ñортирующие операторы" -#: commands/opclasscmds.c:1099 +#: commands/opclasscmds.c:1100 #, c-format msgid "index search operators must return boolean" msgstr "операторы поиÑка по индекÑу должны возвращать логичеÑкое значение" -#: commands/opclasscmds.c:1141 +#: commands/opclasscmds.c:1144 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "процедуры ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ btree должны иметь два аргумента" +msgid "btree comparison functions must have two arguments" +msgstr "функции ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ btree должны иметь два аргумента" -#: commands/opclasscmds.c:1145 +#: commands/opclasscmds.c:1148 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "процедуры ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ btree должны возвращать целое чиÑло" +msgid "btree comparison functions must return integer" +msgstr "функции ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ btree должны возвращать целое чиÑло" -#: commands/opclasscmds.c:1162 +#: commands/opclasscmds.c:1165 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "процедуры поддержки Ñортировки btree должны принимать тип \"internal\"" +msgid "btree sort support functions must accept type \"internal\"" +msgstr "опорные функции Ñортировки btree должны принимать тип \"internal\"" -#: commands/opclasscmds.c:1166 +#: commands/opclasscmds.c:1169 #, c-format -msgid "btree sort support procedures must return void" -msgstr "процедуры поддержки Ñортировки btree должны возвращать пуÑтое (void)" +msgid "btree sort support functions must return void" +msgstr "опорные функции Ñортировки btree должны возвращать пуÑтое (void)" -#: commands/opclasscmds.c:1178 +#: commands/opclasscmds.c:1180 #, c-format -msgid "hash procedures must have one argument" -msgstr "у хеш-процедур должен быть один аргумент" +msgid "btree in_range functions must have five arguments" +msgstr "функции in_range Ð´Ð»Ñ btree должны принимать пÑть аргументов" -#: commands/opclasscmds.c:1182 +#: commands/opclasscmds.c:1184 #, c-format -msgid "hash procedures must return integer" -msgstr "хеш-процедуры должны возвращать целое чиÑло" +msgid "btree in_range functions must return boolean" +msgstr "функции in_range Ð´Ð»Ñ btree должны возвращать логичеÑкое значение" -#: commands/opclasscmds.c:1206 +#: commands/opclasscmds.c:1203 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "" -"Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ñ‹ поддержки индекÑов должны быть указаны ÑвÑзанные типы данных" +msgid "hash function 1 must have one argument" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ 1 должна принимать один аргумент" + +#: commands/opclasscmds.c:1207 +#, c-format +msgid "hash function 1 must return integer" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ 1 должна возвращать целое чиÑло" + +#: commands/opclasscmds.c:1214 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ 2 должна принимать два аргумента" + +#: commands/opclasscmds.c:1218 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ 2 должна возвращать значение bigint" + +#: commands/opclasscmds.c:1243 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð¹ функции индекÑов должны быть указаны ÑвÑзанные типы данных" -#: commands/opclasscmds.c:1231 +#: commands/opclasscmds.c:1268 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "номер процедуры %d Ð´Ð»Ñ (%s,%s) дублируетÑÑ" +msgid "function number %d for (%s,%s) appears more than once" +msgstr "номер функции %d Ð´Ð»Ñ (%s,%s) дублируетÑÑ" -#: commands/opclasscmds.c:1238 +#: commands/opclasscmds.c:1275 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "номер оператора %d Ð´Ð»Ñ (%s,%s) дублируетÑÑ" -#: commands/opclasscmds.c:1287 +#: commands/opclasscmds.c:1324 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "оператор %d(%s,%s) уже ÑущеÑтвует в ÑемейÑтве \"%s\"" -#: commands/opclasscmds.c:1401 +#: commands/opclasscmds.c:1438 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d(%s,%s) уже ÑущеÑтвует в ÑемейÑтве операторов \"%s\"" -#: commands/opclasscmds.c:1489 +#: commands/opclasscmds.c:1526 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "оператор %d(%s,%s) не ÑущеÑтвует в ÑемейÑтве операторов \"%s\"" -#: commands/opclasscmds.c:1529 +#: commands/opclasscmds.c:1566 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %d(%s,%s) не ÑущеÑтвует в ÑемейÑтве операторов \"%s\"" -#: commands/opclasscmds.c:1659 +#: commands/opclasscmds.c:1696 #, c-format msgid "" -"operator class \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" +"operator class \"%s\" for access method \"%s\" already exists in schema \"" +"%s\"" msgstr "" -"клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" уже ÑущеÑтвует в Ñхеме \"%s" -"\"" +"клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" уже ÑущеÑтвует в Ñхеме \"" +"%s\"" -#: commands/opclasscmds.c:1682 +#: commands/opclasscmds.c:1719 #, c-format msgid "" -"operator family \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" +"operator family \"%s\" for access method \"%s\" already exists in schema \"" +"%s\"" msgstr "" "ÑемейÑтво операторов \"%s\" Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° доÑтупа \"%s\" уже ÑущеÑтвует в Ñхеме " "\"%s\"" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "аргументом оператора не может быть тип SETOF" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:454 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "атрибут оператора \"%s\" не раÑпознан" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "должна быть указана процедура оператора" +msgid "operator function must be specified" +msgstr "необходимо указать функцию оператора" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "необходимо указать левый и/или правый аргумент" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format msgid "restriction estimator function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ†ÐµÐ½ÐºÐ¸ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s должна возвращать тип %s" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format msgid "join estimator function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ†ÐµÐ½ÐºÐ¸ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ %s должна возвращать тип %s" -#: commands/operatorcmds.c:448 +#: commands/operatorcmds.c:451 #, c-format msgid "operator attribute \"%s\" cannot be changed" msgstr "атрибут оператора \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ" -#: commands/policy.c:87 commands/policy.c:397 commands/policy.c:486 -#: commands/tablecmds.c:1134 commands/tablecmds.c:1490 -#: commands/tablecmds.c:2467 commands/tablecmds.c:4644 -#: commands/tablecmds.c:6738 commands/tablecmds.c:12659 -#: commands/tablecmds.c:12694 commands/trigger.c:251 commands/trigger.c:1242 -#: commands/trigger.c:1351 rewrite/rewriteDefine.c:272 -#: rewrite/rewriteDefine.c:911 +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 +#: commands/tablecmds.c:1276 commands/tablecmds.c:1753 +#: commands/tablecmds.c:2740 commands/tablecmds.c:4993 +#: commands/tablecmds.c:7401 commands/tablecmds.c:14021 +#: commands/tablecmds.c:14056 commands/trigger.c:316 commands/trigger.c:1526 +#: commands/trigger.c:1635 rewrite/rewriteDefine.c:272 +#: rewrite/rewriteDefine.c:924 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "доÑтуп запрещён: \"%s\" - Ñто ÑиÑтемный каталог" @@ -8546,32 +8689,32 @@ msgstr "вÑе указанные роли, кроме PUBLIC, игнориру msgid "All roles are members of the PUBLIC role." msgstr "Роль PUBLIC включает в ÑÐµÐ±Ñ Ð²Ñе оÑтальные роли." -#: commands/policy.c:510 +#: commands/policy.c:514 #, c-format msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "роль \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ из политики \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" -#: commands/policy.c:716 +#: commands/policy.c:720 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "WITH CHECK Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к SELECT или DELETE" -#: commands/policy.c:725 commands/policy.c:1023 +#: commands/policy.c:729 commands/policy.c:1027 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "Ð´Ð»Ñ INSERT допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ выражение WITH CHECK" -#: commands/policy.c:798 commands/policy.c:1243 +#: commands/policy.c:802 commands/policy.c:1247 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "политика \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" уже ÑущеÑтвует" -#: commands/policy.c:995 commands/policy.c:1271 commands/policy.c:1343 +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "политика \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" не ÑущеÑтвует" -#: commands/policy.c:1013 +#: commands/policy.c:1017 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "Ð´Ð»Ñ SELECT, DELETE допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ выражение USING" @@ -8582,7 +8725,7 @@ msgid "invalid cursor name: must not be empty" msgstr "Ð¸Ð¼Ñ ÐºÑƒÑ€Ñора не может быть пуÑтым" #: commands/portalcmds.c:190 commands/portalcmds.c:244 -#: executor/execCurrent.c:67 utils/adt/xml.c:2459 utils/adt/xml.c:2626 +#: executor/execCurrent.c:69 utils/adt/xml.c:2577 utils/adt/xml.c:2747 #, c-format msgid "cursor \"%s\" does not exist" msgstr "курÑор \"%s\" не ÑущеÑтвует" @@ -8592,7 +8735,7 @@ msgstr "курÑор \"%s\" не ÑущеÑтвует" msgid "invalid statement name: must not be empty" msgstr "неверный оператор: Ð¸Ð¼Ñ Ð½Ðµ должно быть пуÑтым" -#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1355 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1399 #, c-format msgid "could not determine data type of parameter $%d" msgstr "не удалоÑÑŒ определить тип данных параметра $%d" @@ -8624,77 +8767,92 @@ msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "параметр $%d типа %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð²ÐµÑти к ожидаемому типу %s" # [SM]: TO REVIEW -#: commands/prepare.c:474 +#: commands/prepare.c:475 #, c-format msgid "prepared statement \"%s\" already exists" msgstr "подготовленный оператор \"%s\" уже ÑущеÑтвует" # [SM]: TO REVIEW -#: commands/prepare.c:513 +#: commands/prepare.c:514 #, c-format msgid "prepared statement \"%s\" does not exist" msgstr "подготовленный оператор \"%s\" не ÑущеÑтвует" -#: commands/proclang.c:87 +#: commands/proclang.c:86 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "" "вмеÑто параметров CREATE LANGUAGE иÑпользуетÑÑ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ pg_pltemplate" -#: commands/proclang.c:97 +#: commands/proclang.c:96 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð½Ð¾Ð³Ð¾ Ñзыка \"%s\" нужно быть Ñуперпользователем" -#: commands/proclang.c:252 +#: commands/proclang.c:248 #, c-format msgid "unsupported language \"%s\"" msgstr "неподдерживаемый Ñзык: \"%s\"" -#: commands/proclang.c:254 +#: commands/proclang.c:250 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "" "СпиÑок поддерживаемых Ñзыков ÑодержитÑÑ Ð² ÑиÑтемном каталоге pg_pltemplate." -#: commands/proclang.c:262 +#: commands/proclang.c:258 #, c-format msgid "must be superuser to create custom procedural language" msgstr "" "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ процедурного Ñзыка нужно быть Ñуперпользователем" -#: commands/proclang.c:281 commands/trigger.c:530 commands/typecmds.c:457 -#: commands/typecmds.c:474 +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 +#: commands/typecmds.c:471 #, c-format msgid "changing return type of function %s from %s to %s" msgstr "изменение типа возврата функции %s Ñ %s на %s" -#: commands/publicationcmds.c:179 +#: commands/publicationcmds.c:109 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "неверный ÑинтакÑÐ¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"publish\"" + +#: commands/publicationcmds.c:127 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "нераÑпознанное значение \"publish\": \"%s\"" + +#: commands/publicationcmds.c:133 +#, c-format +msgid "unrecognized publication parameter: %s" +msgstr "нераÑпознанный параметр репликации: %s" + +#: commands/publicationcmds.c:166 #, c-format msgid "must be superuser to create FOR ALL TABLES publication" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ вÑех таблиц нужно быть Ñуперпользователем" -#: commands/publicationcmds.c:351 +#: commands/publicationcmds.c:335 #, c-format msgid "publication \"%s\" is defined as FOR ALL TABLES" msgstr "Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ \"%s\" определена Ð´Ð»Ñ Ð²Ñех таблиц (FOR ALL TABLES)" -#: commands/publicationcmds.c:353 +#: commands/publicationcmds.c:337 #, c-format msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." msgstr "Ð’ публикации вÑех таблиц Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð»Ñть или удалÑть таблицы." -#: commands/publicationcmds.c:651 +#: commands/publicationcmds.c:638 #, c-format msgid "relation \"%s\" is not part of the publication" msgstr "отношение \"%s\" не включено в публикацию" -#: commands/publicationcmds.c:694 +#: commands/publicationcmds.c:681 #, c-format msgid "permission denied to change owner of publication \"%s\"" msgstr "нет прав на изменение владельца публикации \"%s\"" -#: commands/publicationcmds.c:696 +#: commands/publicationcmds.c:683 #, c-format msgid "The owner of a FOR ALL TABLES publication must be a superuser." msgstr "" @@ -8734,212 +8892,272 @@ msgstr "" msgid "security label provider \"%s\" is not loaded" msgstr "поÑтавщик меток безопаÑноÑти \"%s\" не загружен" -#: commands/sequence.c:135 +#: commands/sequence.c:138 #, c-format msgid "unlogged sequences are not supported" msgstr "нежурналируемые поÑледовательноÑти не поддерживаютÑÑ" -#: commands/sequence.c:698 +#: commands/sequence.c:697 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ nextval доÑтигла макÑимума Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑти \"%s\" (%s)" -#: commands/sequence.c:721 +#: commands/sequence.c:720 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ nextval доÑтигла минимума Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑти \"%s\" (%s)" -#: commands/sequence.c:839 +#: commands/sequence.c:838 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "" "текущее значение (currval) Ð´Ð»Ñ Ð¿Ð¾ÑледовательноÑти \"%s\" ещё не определено в " "Ñтом ÑеанÑе" -#: commands/sequence.c:858 commands/sequence.c:864 +#: commands/sequence.c:857 commands/sequence.c:863 #, c-format msgid "lastval is not yet defined in this session" msgstr "поÑледнее значение (lastval) ещё не определено в Ñтом ÑеанÑе" -#: commands/sequence.c:952 +#: commands/sequence.c:951 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "" "setval передано значение %s вне пределов поÑледовательноÑти \"%s\" (%s..%s)" -#: commands/sequence.c:1344 +#: commands/sequence.c:1348 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "неверное ÑвойÑтво поÑледовательноÑти SEQUENCE NAME" + +#: commands/sequence.c:1374 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "" +"типом Ñтолбца идентификации может быть только smallint, integer или bigint" + +#: commands/sequence.c:1375 #, c-format msgid "sequence type must be smallint, integer, or bigint" msgstr "" "типом поÑледовательноÑти может быть только smallint, integer или bigint" -#: commands/sequence.c:1356 +#: commands/sequence.c:1409 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT не может быть нулевым" -#: commands/sequence.c:1405 +#: commands/sequence.c:1462 #, c-format msgid "MAXVALUE (%s) is out of range for sequence data type %s" msgstr "MAXVALUE (%s) выходит за пределы типа данных поÑледовательноÑти (%s)" -#: commands/sequence.c:1442 +#: commands/sequence.c:1499 #, c-format msgid "MINVALUE (%s) is out of range for sequence data type %s" msgstr "MINVALUE (%s) выходит за пределы типа данных поÑледовательноÑти (%s)" -#: commands/sequence.c:1456 +#: commands/sequence.c:1513 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) должно быть меньше MAXVALUE (%s)" -#: commands/sequence.c:1481 +#: commands/sequence.c:1540 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "значение START (%s) не может быть меньше MINVALUE (%s)" -#: commands/sequence.c:1493 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "значение START (%s) не может быть больше MAXVALUE (%s)" -#: commands/sequence.c:1523 +#: commands/sequence.c:1582 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "значение RESTART (%s) не может быть меньше MINVALUE (%s)" -#: commands/sequence.c:1535 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "значение RESTART (%s) не может быть больше MAXVALUE (%s)" -#: commands/sequence.c:1550 +#: commands/sequence.c:1609 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "значение CACHE (%s) должно быть больше нулÑ" -#: commands/sequence.c:1582 +#: commands/sequence.c:1646 #, c-format msgid "invalid OWNED BY option" msgstr "неверное указание OWNED BY" # skip-rule: no-space-after-period -#: commands/sequence.c:1583 +#: commands/sequence.c:1647 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "Укажите OWNED BY таблица.Ñтолбец или OWNED BY NONE." -#: commands/sequence.c:1607 +#: commands/sequence.c:1672 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "указанный объект \"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹ или Ñторонней таблицей" -#: commands/sequence.c:1614 +#: commands/sequence.c:1679 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "" "поÑледовательноÑть должна иметь того же владельца, что и таблица, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ " "она ÑвÑзана" -#: commands/sequence.c:1618 +#: commands/sequence.c:1683 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "" "поÑледовательноÑть должна быть в той же Ñхеме, что и таблица, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ она " "ÑвÑзана" -#: commands/statscmds.c:88 +#: commands/sequence.c:1705 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "Ñменить владельца поÑледовательноÑти идентификации нельзÑ" + +#: commands/sequence.c:1706 commands/tablecmds.c:10836 +#: commands/tablecmds.c:13453 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "ПоÑледовательноÑть \"%s\" ÑвÑзана Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹ \"%s\"." + +#: commands/statscmds.c:93 commands/statscmds.c:102 #, c-format -msgid "statistics \"%s\" already exist, skipping" -msgstr "ÑтатиÑтика \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS можно указать только одно отношение" -#: commands/statscmds.c:95 +#: commands/statscmds.c:120 #, c-format -msgid "statistics \"%s\" already exist" -msgstr "ÑтатиÑтика \"%s\" уже ÑущеÑтвует" +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "" +"отношение \"%s\" - Ñто не таблица, не ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° и не " +"материализованное предÑтавление" + +#: commands/statscmds.c:163 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "объект ÑтатиÑтики \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/statscmds.c:105 +#: commands/statscmds.c:171 #, c-format -msgid "relation \"%s\" is not a table or materialized view" -msgstr "отношение \"%s\" - Ñто не таблица и не материализованное предÑтавление" +msgid "statistics object \"%s\" already exists" +msgstr "объект ÑтатиÑтики \"%s\" уже ÑущеÑтвует" -#: commands/statscmds.c:123 +#: commands/statscmds.c:193 commands/statscmds.c:199 #, c-format -msgid "column \"%s\" referenced in statistics does not exist" -msgstr "Ñтолбец \"%s\", указанный в ÑтатиÑтике, не ÑущеÑтвует" +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "в CREATE STATISTICS допуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ проÑтые ÑÑылки на Ñтолбцы" -#: commands/statscmds.c:131 +#: commands/statscmds.c:214 #, c-format -msgid "statistic creation on system columns is not supported" +msgid "statistics creation on system columns is not supported" msgstr "Ñоздание ÑтатиÑтики Ð´Ð»Ñ ÑиÑтемных Ñтолбцов не поддерживаетÑÑ" -#: commands/statscmds.c:138 +#: commands/statscmds.c:221 #, c-format -msgid "only scalar types can be used in extended statistics" -msgstr "в раÑширенной ÑтатиÑтике могут иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ÑкалÑрные типы" +msgid "" +"column \"%s\" cannot be used in statistics because its type %s has no " +"default btree operator class" +msgstr "" +"Ñтолбец \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в ÑтатиÑтике, так как Ð´Ð»Ñ ÐµÐ³Ð¾ типа %s не " +"определён клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² B-дерева по умолчанию" -#: commands/statscmds.c:144 +#: commands/statscmds.c:228 #, c-format -msgid "cannot have more than %d keys in statistics" -msgstr "в ÑтатиÑтике не может быть больше %d ключей" +msgid "cannot have more than %d columns in statistics" +msgstr "в ÑтатиÑтике не может быть больше %d Ñтолбцов" -#: commands/statscmds.c:159 +#: commands/statscmds.c:243 #, c-format -msgid "statistics require at least 2 columns" -msgstr "в ÑтатиÑтике должно быть минимум 2 Ñтолбца" +msgid "extended statistics require at least 2 columns" +msgstr "Ð´Ð»Ñ Ñ€Ð°Ñширенной ÑтатиÑтики требуютÑÑ Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼ 2 Ñтолбца" -#: commands/statscmds.c:176 +#: commands/statscmds.c:261 #, c-format msgid "duplicate column name in statistics definition" msgstr "повторÑющееÑÑ Ð¸Ð¼Ñ Ñтолбца в определении ÑтатиÑтики" -#: commands/statscmds.c:197 +#: commands/statscmds.c:289 #, c-format -msgid "unrecognized STATISTICS option \"%s\"" -msgstr "нераÑпознанное указание Ð´Ð»Ñ STATISTICS: \"%s\"" +msgid "unrecognized statistics kind \"%s\"" +msgstr "нераÑпознанный вид ÑтатиÑтики \"%s\"" -#: commands/subscriptioncmds.c:182 +#: commands/subscriptioncmds.c:187 #, c-format -msgid "noconnect and enabled are mutually exclusive options" -msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ noconnect и enabled ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" +msgid "unrecognized subscription parameter: %s" +msgstr "нераÑпознанный параметр подпиÑки: \"%s\"" -#: commands/subscriptioncmds.c:187 +#: commands/subscriptioncmds.c:200 +#, c-format +msgid "connect = false and enabled = true are mutually exclusive options" +msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ connect = false и enabled = true ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" + +#: commands/subscriptioncmds.c:205 +#, c-format +msgid "connect = false and create_slot = true are mutually exclusive options" +msgstr "" +"ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ connect = false и create_slot = true ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" + +#: commands/subscriptioncmds.c:210 +#, c-format +msgid "connect = false and copy_data = true are mutually exclusive options" +msgstr "" +"ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ connect = false и copy_data = true ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" + +#: commands/subscriptioncmds.c:227 +#, c-format +msgid "slot_name = NONE and enabled = true are mutually exclusive options" +msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ slot_name = NONE и enabled = true ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" + +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +msgstr "" +"ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ slot_name = NONE и create_slot = true ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" + +#: commands/subscriptioncmds.c:237 #, c-format -msgid "noconnect and create slot are mutually exclusive options" -msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ noconnect и create slot ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" +msgid "subscription with slot_name = NONE must also set enabled = false" +msgstr "" +"Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ slot_name = NONE необходимо также задать enabled = " +"false" -#: commands/subscriptioncmds.c:192 +#: commands/subscriptioncmds.c:242 #, c-format -msgid "noconnect and copy data are mutually exclusive options" -msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ noconnect и copy data ÑвлÑÑŽÑ‚ÑÑ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð¸Ñключающими" +msgid "subscription with slot_name = NONE must also set create_slot = false" +msgstr "" +"Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ slot_name = NONE необходимо также задать " +"create_slot = false" -#: commands/subscriptioncmds.c:239 +#: commands/subscriptioncmds.c:283 #, c-format msgid "publication name \"%s\" used more than once" msgstr "Ð¸Ð¼Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ \"%s\" иÑпользуетÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ð¾" -#: commands/subscriptioncmds.c:297 +#: commands/subscriptioncmds.c:347 #, c-format msgid "must be superuser to create subscriptions" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñок нужно быть Ñуперпользователем" -#: commands/subscriptioncmds.c:368 commands/subscriptioncmds.c:457 -#: replication/logical/tablesync.c:726 replication/logical/worker.c:1547 +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 +#: replication/logical/tablesync.c:856 replication/logical/worker.c:1722 #, c-format msgid "could not connect to the publisher: %s" msgstr "не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу публикации: %s" -#: commands/subscriptioncmds.c:382 +#: commands/subscriptioncmds.c:469 #, c-format msgid "created replication slot \"%s\" on publisher" msgstr "на Ñервере публикации Ñоздан Ñлот репликации \"%s\"" -#: commands/subscriptioncmds.c:409 -#, c-format -msgid "synchronized table states" -msgstr "ÑоÑтоÑние таблиц Ñинхронизировано" - -#: commands/subscriptioncmds.c:424 +#: commands/subscriptioncmds.c:486 #, c-format msgid "" "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... " @@ -8948,325 +9166,387 @@ msgstr "" "в подпиÑке отÑутÑтвуют таблицы, потребуетÑÑ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ ALTER SUBSCRIPTION ... " "REFRESH PUBLICATION, чтобы подпиÑатьÑÑ Ð½Ð° таблицы" -#: commands/subscriptioncmds.c:508 +#: commands/subscriptioncmds.c:576 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "таблица \"%s.%s\" добавлена в подпиÑку \"%s\"" + +#: commands/subscriptioncmds.c:600 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "таблица \"%s.%s\" удалена из подпиÑки \"%s\"" + +#: commands/subscriptioncmds.c:669 +#, c-format +msgid "cannot set slot_name = NONE for enabled subscription" +msgstr "Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ð¾Ð¹ подпиÑки Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ slot_name = NONE" + +#: commands/subscriptioncmds.c:703 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "включить подпиÑку, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ не задано Ð¸Ð¼Ñ Ñлота, нельзÑ" + +#: commands/subscriptioncmds.c:749 #, c-format -msgid "added subscription for table %s.%s" -msgstr "добавлена подпиÑка на таблицу %s.%s" +msgid "" +"ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "" +"ALTER SUBSCRIPTION Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸ÐµÐ¼ Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ñ‹Ñ… подпиÑок не допуÑкаетÑÑ" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "" +"Выполните ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." -#: commands/subscriptioncmds.c:534 +#: commands/subscriptioncmds.c:768 #, c-format -msgid "removed subscription for table %s.%s" -msgstr "удалена подпиÑка на таблицу %s.%s" +msgid "" +"ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESH Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ñ‘Ð½Ð½Ñ‹Ñ… подпиÑок не допуÑкаетÑÑ" -#: commands/subscriptioncmds.c:738 +#: commands/subscriptioncmds.c:847 #, c-format msgid "subscription \"%s\" does not exist, skipping" msgstr "подпиÑка \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/subscriptioncmds.c:820 +#: commands/subscriptioncmds.c:972 #, c-format msgid "" "could not connect to publisher when attempting to drop the replication slot " "\"%s\"" msgstr "" -"не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу публикации Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñлота репликации " -"\"%s\"" +"не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу публикации Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñлота репликации \"" +"%s\"" -#: commands/subscriptioncmds.c:822 commands/subscriptioncmds.c:833 -#: replication/logical/tablesync.c:775 replication/logical/tablesync.c:795 +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 +#: replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 #, c-format msgid "The error was: %s" msgstr "Произошла ошибка: %s" -#: commands/subscriptioncmds.c:831 +#: commands/subscriptioncmds.c:975 +#, c-format +msgid "" +"Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the " +"subscription from the slot." +msgstr "" +"ВоÑпользуйтеÑÑŒ ALTER SUBSCRIPTION ... SET (slot_name = NONE), чтобы отвÑзать " +"подпиÑку от Ñлота." + +#: commands/subscriptioncmds.c:986 #, c-format msgid "could not drop the replication slot \"%s\" on publisher" msgstr "Ñлот репликации \"%s\" на Ñервере публикации не был удалён" -#: commands/subscriptioncmds.c:836 +#: commands/subscriptioncmds.c:991 #, c-format msgid "dropped replication slot \"%s\" on publisher" msgstr "Ñлот репликации \"%s\" удалён на Ñервере репликации" -#: commands/subscriptioncmds.c:877 +#: commands/subscriptioncmds.c:1032 #, c-format msgid "permission denied to change owner of subscription \"%s\"" msgstr "нет прав на изменение владельца подпиÑки \"%s\"" -#: commands/subscriptioncmds.c:879 +#: commands/subscriptioncmds.c:1034 #, c-format -msgid "The owner of an subscription must be a superuser." +msgid "The owner of a subscription must be a superuser." msgstr "Владельцем подпиÑки должен быть Ñуперпользователь." -#: commands/subscriptioncmds.c:992 +#: commands/subscriptioncmds.c:1147 #, c-format msgid "could not receive list of replicated tables from the publisher: %s" msgstr "" "не удалоÑÑŒ получить ÑпиÑок реплицируемых таблиц Ñ Ñервера репликации: %s" -#: commands/tablecmds.c:221 commands/tablecmds.c:263 +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist" msgstr "таблица \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:222 commands/tablecmds.c:264 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 #, c-format msgid "table \"%s\" does not exist, skipping" msgstr "таблица \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#: commands/tablecmds.c:226 commands/tablecmds.c:268 msgid "Use DROP TABLE to remove a table." msgstr "Выполните DROP TABLE Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹." -#: commands/tablecmds.c:227 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist" msgstr "поÑледовательноÑть \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:230 #, c-format msgid "sequence \"%s\" does not exist, skipping" msgstr "поÑледовательноÑть \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:230 +#: commands/tablecmds.c:232 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "Выполните DROP SEQUENCE Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾ÑледовательноÑти." -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist" msgstr "предÑтавление \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:236 #, c-format msgid "view \"%s\" does not exist, skipping" msgstr "предÑтавление \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:236 +#: commands/tablecmds.c:238 msgid "Use DROP VIEW to remove a view." msgstr "Выполните DROP VIEW Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´ÑтавлениÑ." -#: commands/tablecmds.c:239 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "материализованное предÑтавление \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:242 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "материализованное предÑтавление \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:244 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "" "Выполните DROP MATERIALIZED VIEW Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¼Ð°Ñ‚ÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ " "предÑтавлениÑ." -#: commands/tablecmds.c:245 parser/parse_utilcmd.c:1698 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 +#: commands/tablecmds.c:15456 parser/parse_utilcmd.c:1982 #, c-format msgid "index \"%s\" does not exist" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:246 +#: commands/tablecmds.c:248 commands/tablecmds.c:272 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:250 commands/tablecmds.c:274 msgid "Use DROP INDEX to remove an index." msgstr "Выполните DROP INDEX Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа." -#: commands/tablecmds.c:253 +#: commands/tablecmds.c:255 #, c-format msgid "\"%s\" is not a type" msgstr "\"%s\" - Ñто не тип" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:256 msgid "Use DROP TYPE to remove a type." msgstr "Выполните DROP TYPE Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð°." -#: commands/tablecmds.c:257 commands/tablecmds.c:9064 -#: commands/tablecmds.c:11903 +#: commands/tablecmds.c:259 commands/tablecmds.c:10278 +#: commands/tablecmds.c:13233 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:258 +#: commands/tablecmds.c:260 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:260 +#: commands/tablecmds.c:262 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "Выполните DROP FOREIGN TABLE Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñторонней таблицы." -#: commands/tablecmds.c:519 +#: commands/tablecmds.c:555 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT можно иÑпользовать только Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… таблиц" -#: commands/tablecmds.c:547 +#: commands/tablecmds.c:583 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "" "в рамках операции Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми по безопаÑноÑти Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать временную " "таблицу" -#: commands/tablecmds.c:646 +#: commands/tablecmds.c:684 #, c-format msgid "cannot create table with OIDs as partition of table without OIDs" msgstr "Ñоздать таблицу Ñ OID в виде Ñекции таблицы без OID нельзÑ" -#: commands/tablecmds.c:764 parser/parse_utilcmd.c:3040 +#: commands/tablecmds.c:808 #, c-format msgid "\"%s\" is not partitioned" -msgstr "отношение \"%s\" не Ñекционировано" +msgstr "отношение \"%s\" не ÑвлÑетÑÑ Ñекционированным" + +#: commands/tablecmds.c:889 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "чиÑло Ñтолбцов в ключе ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может превышать %d" -#: commands/tablecmds.c:972 +#: commands/tablecmds.c:1096 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY не поддерживает удаление неÑкольких объектов" -#: commands/tablecmds.c:976 +#: commands/tablecmds.c:1100 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY не поддерживает режим CASCADE" -#: commands/tablecmds.c:1224 +#: commands/tablecmds.c:1399 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "опуÑтошить ÑобÑтвенно Ñекционированную таблицу нельзÑ" + +#: commands/tablecmds.c:1400 #, c-format -msgid "must truncate child tables too" -msgstr "опуÑтошатьÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ также и дочерние таблицы" +msgid "" +"Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions " +"directly." +msgstr "" +"Ðе указывайте ключевое Ñлово ONLY или выполните TRUNCATE ONLY " +"непоÑредÑтвенно Ð´Ð»Ñ Ñекций." -#: commands/tablecmds.c:1252 +#: commands/tablecmds.c:1469 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "опуÑтошение раÑпроÑтранÑетÑÑ Ð½Ð° таблицу %s" -#: commands/tablecmds.c:1500 +#: commands/tablecmds.c:1763 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "временные таблицы других ÑеанÑов Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð¿ÑƒÑтошить" -#: commands/tablecmds.c:1731 commands/tablecmds.c:10647 +#: commands/tablecmds.c:2004 commands/tablecmds.c:11984 #, c-format msgid "cannot inherit from partitioned table \"%s\"" msgstr "наÑледование от Ñекционированной таблицы \"%s\" не допуÑкаетÑÑ" -#: commands/tablecmds.c:1736 +#: commands/tablecmds.c:2009 #, c-format msgid "cannot inherit from partition \"%s\"" msgstr "наÑледование от Ñекции \"%s\" не допуÑкаетÑÑ" -#: commands/tablecmds.c:1744 parser/parse_utilcmd.c:1909 +#: commands/tablecmds.c:2017 parser/parse_utilcmd.c:2199 +#: parser/parse_utilcmd.c:2322 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "" "наÑледуемое отношение \"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹ или Ñторонней таблицей" -#: commands/tablecmds.c:1752 commands/tablecmds.c:10626 +#: commands/tablecmds.c:2029 +#, c-format +msgid "" +"cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"Ñоздать временное отношение в качеÑтве Ñекции поÑтоÑнного Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" " +"нельзÑ" + +#: commands/tablecmds.c:2038 commands/tablecmds.c:11963 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "временное отношение \"%s\" не может наÑледоватьÑÑ" -#: commands/tablecmds.c:1762 commands/tablecmds.c:10634 +#: commands/tablecmds.c:2048 commands/tablecmds.c:11971 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "наÑледование от временного Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð³Ð¾ ÑеанÑа невозможно" -#: commands/tablecmds.c:1779 commands/tablecmds.c:10745 +#: commands/tablecmds.c:2065 commands/tablecmds.c:12095 #, c-format msgid "relation \"%s\" would be inherited from more than once" msgstr "отношение \"%s\" наÑледуетÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ð¾" -#: commands/tablecmds.c:1827 +#: commands/tablecmds.c:2114 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "ÑлиÑние неÑкольких наÑледованных определений Ñтолбца \"%s\"" -#: commands/tablecmds.c:1835 +#: commands/tablecmds.c:2122 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "конфликт типов в наÑледованном Ñтолбце \"%s\"" -#: commands/tablecmds.c:1837 commands/tablecmds.c:1860 -#: commands/tablecmds.c:2065 commands/tablecmds.c:2089 -#: parser/parse_coerce.c:1650 parser/parse_coerce.c:1670 -#: parser/parse_coerce.c:1690 parser/parse_coerce.c:1736 -#: parser/parse_coerce.c:1775 parser/parse_param.c:218 +#: commands/tablecmds.c:2124 commands/tablecmds.c:2147 +#: commands/tablecmds.c:2352 commands/tablecmds.c:2382 +#: parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 +#: parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 +#: parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s и %s" -#: commands/tablecmds.c:1846 +#: commands/tablecmds.c:2133 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "конфликт правил Ñортировки в наÑледованном Ñтолбце \"%s\"" -#: commands/tablecmds.c:1848 commands/tablecmds.c:2077 -#: commands/tablecmds.c:5089 +#: commands/tablecmds.c:2135 commands/tablecmds.c:2364 +#: commands/tablecmds.c:5453 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\" и \"%s\"" -#: commands/tablecmds.c:1858 +#: commands/tablecmds.c:2145 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "конфликт параметров Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² наÑледованном Ñтолбце \"%s\"" -#: commands/tablecmds.c:1971 commands/tablecmds.c:8572 -#: parser/parse_utilcmd.c:993 parser/parse_utilcmd.c:1343 -#: parser/parse_utilcmd.c:1419 +#: commands/tablecmds.c:2258 commands/tablecmds.c:9706 +#: parser/parse_utilcmd.c:1116 parser/parse_utilcmd.c:1515 +#: parser/parse_utilcmd.c:1622 #, c-format msgid "cannot convert whole-row table reference" msgstr "преобразовать ÑÑылку на тип вÑей Ñтроки таблицы нельзÑ" -#: commands/tablecmds.c:1972 parser/parse_utilcmd.c:994 +#: commands/tablecmds.c:2259 parser/parse_utilcmd.c:1117 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "Ограничение \"%s\" ÑÑылаетÑÑ Ð½Ð° тип вÑей Ñтроки в таблице \"%s\"." -#: commands/tablecmds.c:2051 +#: commands/tablecmds.c:2338 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "ÑлиÑние Ñтолбца \"%s\" Ñ Ð½Ð°Ñледованным определением" -#: commands/tablecmds.c:2055 +#: commands/tablecmds.c:2342 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "перемещение и ÑлиÑние Ñтолбца \"%s\" Ñ Ð½Ð°Ñледуемым определением" -#: commands/tablecmds.c:2056 +#: commands/tablecmds.c:2343 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "" "Определённый пользователем Ñтолбец перемещён в позицию наÑледуемого Ñтолбца." -#: commands/tablecmds.c:2063 +#: commands/tablecmds.c:2350 #, c-format msgid "column \"%s\" has a type conflict" msgstr "конфликт типов в Ñтолбце \"%s\"" -#: commands/tablecmds.c:2075 +#: commands/tablecmds.c:2362 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "конфликт правил Ñортировки в Ñтолбце \"%s\"" -#: commands/tablecmds.c:2087 +#: commands/tablecmds.c:2380 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "конфликт параметров Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² Ñтолбце \"%s\"" -#: commands/tablecmds.c:2189 +#: commands/tablecmds.c:2483 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "Ñтолбец \"%s\" наÑледует конфликтующие Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" -#: commands/tablecmds.c:2191 +#: commands/tablecmds.c:2485 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "Ð”Ð»Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð»Ð¸ÐºÑ‚Ð° укажите желаемое значение по умолчанию." -#: commands/tablecmds.c:2238 +#: commands/tablecmds.c:2532 #, c-format msgid "" "check constraint name \"%s\" appears multiple times but with different " @@ -9275,12 +9555,12 @@ msgstr "" "Ð¸Ð¼Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ-проверки \"%s\" фигурирует неÑколько раз, но Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ " "выражениÑми" -#: commands/tablecmds.c:2437 +#: commands/tablecmds.c:2709 #, c-format msgid "cannot rename column of typed table" msgstr "переименовать Ñтолбец типизированной таблицы нельзÑ" -#: commands/tablecmds.c:2455 +#: commands/tablecmds.c:2728 #, c-format msgid "" "\"%s\" is not a table, view, materialized view, composite type, index, or " @@ -9289,37 +9569,37 @@ msgstr "" "\"%s\" - Ñто не таблица, предÑтавление, материализованное предÑтавление, " "ÑоÑтавной тип, Ð¸Ð½Ð´ÐµÐºÑ Ð¸Ð»Ð¸ ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:2549 +#: commands/tablecmds.c:2822 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "" "наÑледованный Ñтолбец \"%s\" должен быть также переименован в дочерних " "таблицах" -#: commands/tablecmds.c:2581 +#: commands/tablecmds.c:2854 #, c-format msgid "cannot rename system column \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ ÑиÑтемный Ñтолбец \"%s\"" -#: commands/tablecmds.c:2596 +#: commands/tablecmds.c:2869 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ наÑледованный Ñтолбец \"%s\"" -#: commands/tablecmds.c:2748 +#: commands/tablecmds.c:3021 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "" "наÑледуемое ограничение \"%s\" должно быть также переименовано в дочерних " "таблицах" -#: commands/tablecmds.c:2755 +#: commands/tablecmds.c:3028 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ наÑледованное ограничение \"%s\"" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2979 +#: commands/tablecmds.c:3254 #, c-format msgid "" "cannot %s \"%s\" because it is being used by active queries in this session" @@ -9328,112 +9608,121 @@ msgstr "" "запроÑами в данном ÑеанÑе" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2988 +#: commands/tablecmds.c:3264 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ %s \"%s\", так как Ñ Ñтим объектом ÑвÑзаны отложенные " "ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð²" -#: commands/tablecmds.c:4087 +#: commands/tablecmds.c:4412 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "перезапиÑать ÑиÑтемное отношение \"%s\" нельзÑ" -#: commands/tablecmds.c:4093 +#: commands/tablecmds.c:4418 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "перезапиÑать таблицу \"%s\", иÑпользуемую как таблицу каталога, нельзÑ" -#: commands/tablecmds.c:4103 +#: commands/tablecmds.c:4428 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "перезапиÑывать временные таблицы других ÑеанÑов нельзÑ" -#: commands/tablecmds.c:4379 +#: commands/tablecmds.c:4714 #, c-format msgid "rewriting table \"%s\"" msgstr "перезапиÑÑŒ таблицы \"%s\"" -#: commands/tablecmds.c:4383 +#: commands/tablecmds.c:4718 #, c-format msgid "verifying table \"%s\"" msgstr "проверка таблицы \"%s\"" -#: commands/tablecmds.c:4496 +#: commands/tablecmds.c:4834 #, c-format msgid "column \"%s\" contains null values" msgstr "Ñтолбец \"%s\" Ñодержит Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NULL" -#: commands/tablecmds.c:4511 commands/tablecmds.c:7843 +#: commands/tablecmds.c:4850 commands/tablecmds.c:8927 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "ограничение-проверку \"%s\" нарушает Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñтрока" -#: commands/tablecmds.c:4527 +#: commands/tablecmds.c:4868 +#, c-format +msgid "" +"updated partition constraint for default partition would be violated by some " +"row" +msgstr "" +"изменённое ограничение Ñекции Ð´Ð»Ñ Ñекции по умолчанию будет нарушено " +"некоторыми Ñтроками" + +#: commands/tablecmds.c:4872 #, c-format msgid "partition constraint is violated by some row" msgstr "ограничение Ñекции нарушает Ð½ÐµÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ñтрока" -#: commands/tablecmds.c:4665 commands/trigger.c:245 rewrite/rewriteDefine.c:266 -#: rewrite/rewriteDefine.c:906 +#: commands/tablecmds.c:5014 commands/trigger.c:310 +#: rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:919 #, c-format msgid "\"%s\" is not a table or view" msgstr "\"%s\" - Ñто не таблица и не предÑтавление" -#: commands/tablecmds.c:4668 commands/trigger.c:1236 commands/trigger.c:1342 +#: commands/tablecmds.c:5017 commands/trigger.c:1520 commands/trigger.c:1626 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "\"%s\" - Ñто не таблица, предÑтавление и не ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:4671 +#: commands/tablecmds.c:5020 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "" "\"%s\" - Ñто не таблица, предÑтавление, материализованное предÑтавление или " "индекÑ" -#: commands/tablecmds.c:4677 +#: commands/tablecmds.c:5026 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "\"%s\" - Ñто не таблица, материализованное предÑтавление или индекÑ" -#: commands/tablecmds.c:4680 +#: commands/tablecmds.c:5029 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "" "\"%s\" - Ñто не таблица, материализованное предÑтавление или ÑтороннÑÑ " "таблица" -#: commands/tablecmds.c:4683 +#: commands/tablecmds.c:5032 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "\"%s\" - Ñто не таблица и не ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:4686 +#: commands/tablecmds.c:5035 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "\"%s\" - Ñто не таблица, ÑоÑтавной тип или ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:4689 commands/tablecmds.c:5811 +#: commands/tablecmds.c:5038 commands/tablecmds.c:6456 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "" "\"%s\" - Ñто не таблица, материализованное предÑтавление, Ð¸Ð½Ð´ÐµÐºÑ Ð¸Ð»Ð¸ " "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:4699 +#: commands/tablecmds.c:5048 #, c-format msgid "\"%s\" is of the wrong type" msgstr "неправильный тип \"%s\"" -#: commands/tablecmds.c:4853 commands/tablecmds.c:4860 +#: commands/tablecmds.c:5223 commands/tablecmds.c:5230 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "" "изменить тип \"%s\" нельзÑ, так как он задейÑтвован в Ñтолбце \"%s.%s\"" -#: commands/tablecmds.c:4867 +#: commands/tablecmds.c:5237 #, c-format msgid "" "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" @@ -9441,188 +9730,313 @@ msgstr "" "изменить Ñтороннюю таблицу \"%s\" нельзÑ, так как Ñтолбец \"%s.%s\" " "задейÑтвует тип её Ñтроки" -#: commands/tablecmds.c:4874 +#: commands/tablecmds.c:5244 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "" "изменить таблицу \"%s\" нельзÑ, так как Ñтолбец \"%s.%s\" задейÑтвует тип её " "Ñтроки" -#: commands/tablecmds.c:4936 +#: commands/tablecmds.c:5298 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "изменить тип \"%s\", так как Ñто тип типизированной таблицы" -#: commands/tablecmds.c:4938 +#: commands/tablecmds.c:5300 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "" "Чтобы изменить также типизированные таблицы, выполните ALTER ... CASCADE." -#: commands/tablecmds.c:4982 +#: commands/tablecmds.c:5346 #, c-format msgid "type %s is not a composite type" msgstr "тип %s не ÑвлÑетÑÑ ÑоÑтавным" -#: commands/tablecmds.c:5008 +#: commands/tablecmds.c:5372 #, c-format msgid "cannot add column to typed table" msgstr "добавить Ñтолбец в типизированную таблицу нельзÑ" -#: commands/tablecmds.c:5052 +#: commands/tablecmds.c:5416 #, c-format msgid "cannot add column to a partition" msgstr "добавить Ñтолбец в Ñекцию нельзÑ" -#: commands/tablecmds.c:5081 commands/tablecmds.c:10871 +#: commands/tablecmds.c:5445 commands/tablecmds.c:12222 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "дочернÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" имеет другой тип Ð´Ð»Ñ Ñтолбца \"%s\"" -#: commands/tablecmds.c:5087 commands/tablecmds.c:10878 +#: commands/tablecmds.c:5451 commands/tablecmds.c:12229 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "" "дочернÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" имеет другое правило Ñортировки Ð´Ð»Ñ Ñтолбца \"%s\"" -#: commands/tablecmds.c:5097 +#: commands/tablecmds.c:5461 #, c-format msgid "child table \"%s\" has a conflicting \"%s\" column" msgstr "дочернÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" Ñодержит конфликтующий Ñтолбец \"%s\"" -#: commands/tablecmds.c:5108 +#: commands/tablecmds.c:5472 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "объединение определений Ñтолбца \"%s\" Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ° \"%s\"" -#: commands/tablecmds.c:5332 +#: commands/tablecmds.c:5496 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "" +"добавить Ñтолбец идентификации в таблицу, у которой еÑть дочерние, нельзÑ" + +#: commands/tablecmds.c:5745 #, c-format msgid "column must be added to child tables too" msgstr "Ñтолбец также должен быть добавлен к дочерним таблицам" -#: commands/tablecmds.c:5407 +#: commands/tablecmds.c:5820 #, c-format msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:5414 +#: commands/tablecmds.c:5827 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑущеÑтвует" -#: commands/tablecmds.c:5508 commands/tablecmds.c:8245 +#: commands/tablecmds.c:5925 commands/tablecmds.c:9386 +#, c-format +msgid "" +"cannot remove constraint from only the partitioned table when partitions " +"exist" +msgstr "" +"удалить ограничение только из Ñекционированной таблицы, когда ÑущеÑтвуют " +"Ñекции, нельзÑ" + +#: commands/tablecmds.c:5926 commands/tablecmds.c:6070 +#: commands/tablecmds.c:6854 commands/tablecmds.c:9387 #, c-format -msgid "constraint must be dropped from child tables too" -msgstr "ограничение также должно удалÑтьÑÑ Ð¸Ð· дочерних таблиц" +msgid "Do not specify the ONLY keyword." +msgstr "Ðе указывайте ключевое Ñлово ONLY." -#: commands/tablecmds.c:5539 commands/tablecmds.c:5700 -#: commands/tablecmds.c:5755 commands/tablecmds.c:5870 -#: commands/tablecmds.c:5924 commands/tablecmds.c:6016 -#: commands/tablecmds.c:8394 commands/tablecmds.c:9087 +#: commands/tablecmds.c:5958 commands/tablecmds.c:6106 +#: commands/tablecmds.c:6161 commands/tablecmds.c:6237 +#: commands/tablecmds.c:6331 commands/tablecmds.c:6390 +#: commands/tablecmds.c:6540 commands/tablecmds.c:6610 +#: commands/tablecmds.c:6702 commands/tablecmds.c:9526 +#: commands/tablecmds.c:10301 #, c-format msgid "cannot alter system column \"%s\"" msgstr "ÑиÑтемный Ñтолбец \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ" -#: commands/tablecmds.c:5575 +#: commands/tablecmds.c:5964 commands/tablecmds.c:6167 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" ÑвлÑетÑÑ Ñтолбцом идентификации" + +#: commands/tablecmds.c:6000 #, c-format msgid "column \"%s\" is in a primary key" msgstr "Ñтолбец \"%s\" входит в первичный ключ" -#: commands/tablecmds.c:5597 +#: commands/tablecmds.c:6022 #, c-format msgid "column \"%s\" is marked NOT NULL in parent table" msgstr "Ñтолбец \"%s\" в родительÑкой таблице помечен как NOT NULL" -#: commands/tablecmds.c:5622 +#: commands/tablecmds.c:6069 +#, c-format +msgid "" +"cannot add constraint to only the partitioned table when partitions exist" +msgstr "" +"добавить ограничение только в Ñекционированную таблицу, когда ÑущеÑтвуют " +"Ñекции, нельзÑ" + +#: commands/tablecmds.c:6169 #, c-format -msgid "column \"%s\" is in range partition key" -msgstr "Ñтолбец \"%s\" входит в ключ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð¿Ð¾ диапазонам" +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "ВмеÑто Ñтого выполните ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY." -#: commands/tablecmds.c:5669 commands/tablecmds.c:6655 +#: commands/tablecmds.c:6248 #, c-format -msgid "constraint must be added to child tables too" -msgstr "ограничение также должно быть добавлено к дочерним таблицам" +msgid "" +"column \"%s\" of relation \"%s\" must be declared NOT NULL before identity " +"can be added" +msgstr "" +"Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" должен быть объÑвлен как NOT NULL, чтобы его " +"можно было Ñделать Ñтолбцом идентификации" + +#: commands/tablecmds.c:6254 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑвлÑетÑÑ Ñтолбцом идентификации" + +#: commands/tablecmds.c:6260 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже имеет значение по умолчанию" + +#: commands/tablecmds.c:6337 commands/tablecmds.c:6398 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑвлÑетÑÑ Ñтолбцом идентификации" + +#: commands/tablecmds.c:6403 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "" +"Ñтолбец \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑвлÑетÑÑ Ñтолбцом идентификации, " +"пропуÑкаетÑÑ" + +#: commands/tablecmds.c:6468 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "по номеру можно ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на Ñтолбец в индекÑе" -#: commands/tablecmds.c:5843 +#: commands/tablecmds.c:6499 #, c-format msgid "statistics target %d is too low" -msgstr "целевое ограничение ÑтатиÑтики Ñлишком мало (%d)" +msgstr "ориентир ÑтатиÑтики Ñлишком мал (%d)" -#: commands/tablecmds.c:5851 +#: commands/tablecmds.c:6507 #, c-format msgid "lowering statistics target to %d" -msgstr "целевое ограничение ÑтатиÑтики ÑнижаетÑÑ Ð´Ð¾ %d" +msgstr "ориентир ÑтатиÑтики ÑнижаетÑÑ Ð´Ð¾ %d" + +#: commands/tablecmds.c:6530 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "Ñтолбец Ñ Ð½Ð¾Ð¼ÐµÑ€Ð¾Ð¼ %d Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует" + +#: commands/tablecmds.c:6549 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "изменить ÑтатиÑтику включённого Ñтолбца \"%s\" индекÑа \"%s\" нельзÑ" + +#: commands/tablecmds.c:6554 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "" +"изменить ÑтатиÑтику Ñтолбца \"%s\" (не выражениÑ) индекÑа \"%s\" нельзÑ" + +#: commands/tablecmds.c:6556 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "ВмеÑто Ñтого измените ÑтатиÑтику Ð´Ð»Ñ Ñтолбца в таблице." -#: commands/tablecmds.c:5996 +#: commands/tablecmds.c:6682 #, c-format msgid "invalid storage type \"%s\"" msgstr "неверный тип хранилища \"%s\"" -#: commands/tablecmds.c:6028 +#: commands/tablecmds.c:6714 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "тип данных Ñтолбца %s ÑовмеÑтим только Ñ Ñ…Ñ€Ð°Ð½Ð¸Ð»Ð¸Ñ‰ÐµÐ¼ PLAIN" -#: commands/tablecmds.c:6063 +#: commands/tablecmds.c:6749 #, c-format msgid "cannot drop column from typed table" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ñтолбец в типизированной таблице" -#: commands/tablecmds.c:6170 +#: commands/tablecmds.c:6794 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" msgstr "Ñтолбец \"%s\" в таблице\"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:6183 +#: commands/tablecmds.c:6807 #, c-format msgid "cannot drop system column \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ ÑиÑтемный Ñтолбец \"%s\"" -#: commands/tablecmds.c:6190 +#: commands/tablecmds.c:6814 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ наÑледованный Ñтолбец \"%s\"" -#: commands/tablecmds.c:6199 +#: commands/tablecmds.c:6825 #, c-format msgid "cannot drop column named in partition key" -msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ñтолбец, входÑщий в ключ разбиениÑ" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ñтолбец, входÑщий в ключ ÑекционированиÑ" -#: commands/tablecmds.c:6203 +#: commands/tablecmds.c:6829 #, c-format msgid "cannot drop column referenced in partition key expression" -msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ñтолбец, задейÑтвованный в выражении ключа разбиениÑ" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ Ñтолбец, задейÑтвованный в выражении ключа ÑекционированиÑ" + +#: commands/tablecmds.c:6853 +#, c-format +msgid "" +"cannot drop column from only the partitioned table when partitions exist" +msgstr "" +"удалить Ñтолбец только из Ñекционированной таблицы, когда ÑущеÑтвуют Ñекции, " +"нельзÑ" -#: commands/tablecmds.c:6227 +#: commands/tablecmds.c:7058 #, c-format -msgid "column must be dropped from child tables too" -msgstr "Ñтолбец также должен удалÑтьÑÑ Ð¸Ð· дочерних таблиц" +msgid "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned " +"tables" +msgstr "" +"ALTER TABLE / ADD CONSTRAINT USING INDEX не поддерживаетÑÑ Ñ " +"Ñекционированными таблицами" -#: commands/tablecmds.c:6443 +#: commands/tablecmds.c:7083 #, c-format msgid "" "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" msgstr "" "ALTER TABLE / ADD CONSTRAINT USING INDEX переименует Ð¸Ð½Ð´ÐµÐºÑ \"%s\" в \"%s\"" -#: commands/tablecmds.c:6726 +#: commands/tablecmds.c:7299 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "ограничение также должно быть добавлено к дочерним таблицам" + +#: commands/tablecmds.c:7372 #, c-format msgid "cannot reference partitioned table \"%s\"" msgstr "ÑÑылатьÑÑ Ð½Ð° Ñекционированную таблицу \"%s\" нельзÑ" -#: commands/tablecmds.c:6732 +#: commands/tablecmds.c:7380 +#, c-format +msgid "" +"cannot use ONLY for foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать ONLY Ð´Ð»Ñ Ñтороннего ключа в Ñекционированной таблице \"" +"%s\", ÑÑылающегоÑÑ Ð½Ð° отношение \"%s\"" + +#: commands/tablecmds.c:7386 +#, c-format +msgid "" +"cannot add NOT VALID foreign key on partitioned table \"%s\" referencing " +"relation \"%s\"" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñ‚ÑŒ Ñ Ñ…Ð°Ñ€Ð°ÐºÑ‚ÐµÑ€Ð¸Ñтикой NOT VALID Ñторонний ключ в " +"Ñекционированной таблице \"%s\", ÑÑылающийÑÑ Ð½Ð° отношение \"%s\"" + +#: commands/tablecmds.c:7389 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "" +"Эта функциональноÑть Ñ Ñекционированными таблицами пока не поддерживаетÑÑ." + +#: commands/tablecmds.c:7395 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "указанный объект \"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹" -#: commands/tablecmds.c:6755 +#: commands/tablecmds.c:7418 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "" "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð² поÑтоÑнных таблицах могут ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на поÑтоÑнные " "таблицы" -#: commands/tablecmds.c:6762 +#: commands/tablecmds.c:7425 #, c-format msgid "" "constraints on unlogged tables may reference only permanent or unlogged " @@ -9631,13 +10045,13 @@ msgstr "" "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð² нежурналируемых таблицах могут ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на поÑтоÑнные " "или нежурналируемые таблицы" -#: commands/tablecmds.c:6768 +#: commands/tablecmds.c:7431 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "" "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð¾ временных таблицах могут ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на временные таблицы" -#: commands/tablecmds.c:6772 +#: commands/tablecmds.c:7435 #, c-format msgid "" "constraints on temporary tables must involve temporary tables of this session" @@ -9645,33 +10059,33 @@ msgstr "" "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð¾ временных таблицах должны ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на временные " "таблицы текущего ÑеанÑа" -#: commands/tablecmds.c:6832 +#: commands/tablecmds.c:7495 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "чиÑло Ñтолбцов в иÑточнике и назначении внешнего ключа не Ñовпадает" -#: commands/tablecmds.c:6939 +#: commands/tablecmds.c:7602 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "ограничение внешнего ключа \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð¾Ð²Ð°Ñ‚ÑŒ" -#: commands/tablecmds.c:6942 +#: commands/tablecmds.c:7605 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "Столбцы ключа \"%s\" и \"%s\" имеют неÑовмеÑтимые типы: %s и %s." -#: commands/tablecmds.c:7148 commands/tablecmds.c:7314 -#: commands/tablecmds.c:8224 commands/tablecmds.c:8290 +#: commands/tablecmds.c:8227 commands/tablecmds.c:8392 +#: commands/tablecmds.c:9343 commands/tablecmds.c:9418 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "ограничение \"%s\" в таблице \"%s\" не ÑущеÑтвует" -#: commands/tablecmds.c:7154 +#: commands/tablecmds.c:8234 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "ограничение \"%s\" в таблице \"%s\" не ÑвлÑетÑÑ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¼ ключом" -#: commands/tablecmds.c:7321 +#: commands/tablecmds.c:8400 #, c-format msgid "" "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" @@ -9679,46 +10093,46 @@ msgstr "" "ограничение \"%s\" в таблице \"%s\" не ÑвлÑетÑÑ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¼ ключом или " "ограничением-проверкой" -#: commands/tablecmds.c:7390 +#: commands/tablecmds.c:8470 #, c-format msgid "constraint must be validated on child tables too" msgstr "ограничение также должно ÑоблюдатьÑÑ Ð² дочерних таблицах" -#: commands/tablecmds.c:7458 +#: commands/tablecmds.c:8538 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "Ñтолбец \"%s\", указанный в ограничении внешнего ключа, не ÑущеÑтвует" -#: commands/tablecmds.c:7463 +#: commands/tablecmds.c:8543 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "во внешнем ключе не может быть больше %d Ñтолбцов" -#: commands/tablecmds.c:7528 +#: commands/tablecmds.c:8608 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "" "иÑпользовать откладываемый первичный ключ в целевой внешней таблице \"%s\" " "нельзÑ" -#: commands/tablecmds.c:7545 +#: commands/tablecmds.c:8625 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "в целевой внешней таблице \"%s\" нет первичного ключа" -#: commands/tablecmds.c:7610 +#: commands/tablecmds.c:8690 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "в ÑпиÑке Ñтолбцов внешнего ключа не должно быть повторений" -#: commands/tablecmds.c:7704 +#: commands/tablecmds.c:8784 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "" "иÑпользовать откладываемое ограничение уникальноÑти в целевой внешней " "таблице \"%s\" нельзÑ" -#: commands/tablecmds.c:7709 +#: commands/tablecmds.c:8789 #, c-format msgid "" "there is no unique constraint matching given keys for referenced table \"%s\"" @@ -9726,43 +10140,44 @@ msgstr "" "в целевой внешней таблице \"%s\" нет Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ñти, " "ÑоответÑтвующего данным ключам" -#: commands/tablecmds.c:7876 +#: commands/tablecmds.c:8960 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "проверка Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа \"%s\"" -#: commands/tablecmds.c:8178 +#: commands/tablecmds.c:9299 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "удалить наÑледованное ограничение \"%s\" таблицы \"%s\" нельзÑ" -#: commands/tablecmds.c:8230 +#: commands/tablecmds.c:9349 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "ограничение \"%s\" в таблице \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablecmds.c:8378 +#: commands/tablecmds.c:9510 #, c-format msgid "cannot alter column type of typed table" msgstr "изменить тип Ñтолбца в типизированной таблице нельзÑ" -#: commands/tablecmds.c:8401 +#: commands/tablecmds.c:9533 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "изменить наÑледованный Ñтолбец \"%s\" нельзÑ" -#: commands/tablecmds.c:8410 +#: commands/tablecmds.c:9544 #, c-format msgid "cannot alter type of column named in partition key" -msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип Ñтолбца, ÑоÑтавлÑющего ключ разбиениÑ" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип Ñтолбца, ÑоÑтавлÑющего ключ ÑекционированиÑ" -#: commands/tablecmds.c:8414 +#: commands/tablecmds.c:9548 #, c-format msgid "cannot alter type of column referenced in partition key expression" msgstr "" -"Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип Ñтолбца, задейÑтвованного в выражении ключа разбиениÑ" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип Ñтолбца, задейÑтвованного в выражении ключа " +"ÑекционированиÑ" -#: commands/tablecmds.c:8464 +#: commands/tablecmds.c:9598 #, c-format msgid "" "result of USING clause for column \"%s\" cannot be cast automatically to " @@ -9770,223 +10185,234 @@ msgid "" msgstr "" "результат USING Ð´Ð»Ñ Ñтолбца \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки привеÑти к типу %s" -#: commands/tablecmds.c:8467 +#: commands/tablecmds.c:9601 #, c-format msgid "You might need to add an explicit cast." msgstr "Возможно, необходимо добавить Ñвное приведение." -#: commands/tablecmds.c:8471 +#: commands/tablecmds.c:9605 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "Ñтолбец \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки привеÑти к типу %s" # skip-rule: double-colons #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:8474 +#: commands/tablecmds.c:9608 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "Возможно, необходимо указать \"USING %s::%s\"." -#: commands/tablecmds.c:8573 +#: commands/tablecmds.c:9707 #, c-format msgid "USING expression contains a whole-row table reference." msgstr "Выражение USING ÑÑылаетÑÑ Ð½Ð° тип вÑей Ñтроки таблицы." -#: commands/tablecmds.c:8584 +#: commands/tablecmds.c:9718 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "" "тип наÑледованного Ñтолбца \"%s\" должен быть изменён и в дочерних таблицах" -#: commands/tablecmds.c:8671 +#: commands/tablecmds.c:9822 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ тип Ñтолбца \"%s\" дважды" -#: commands/tablecmds.c:8707 +#: commands/tablecmds.c:9858 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "" "значение по умолчанию Ð´Ð»Ñ Ñтолбца \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки привеÑти к " "типу %s" -#: commands/tablecmds.c:8833 +#: commands/tablecmds.c:9964 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "" "изменить тип Ñтолбца, задейÑтвованного в предÑтавлении или правиле, нельзÑ" -#: commands/tablecmds.c:8834 commands/tablecmds.c:8853 -#: commands/tablecmds.c:8871 +#: commands/tablecmds.c:9965 commands/tablecmds.c:9984 +#: commands/tablecmds.c:10002 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s завиÑит от Ñтолбца \"%s\"" -#: commands/tablecmds.c:8852 +#: commands/tablecmds.c:9983 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "изменить тип Ñтолбца, задейÑтвованного в определении триггера, нельзÑ" -#: commands/tablecmds.c:8870 +#: commands/tablecmds.c:10001 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "изменить тип Ñтолбца, задейÑтвованного в определении политики, нельзÑ" -#: commands/tablecmds.c:9527 +#: commands/tablecmds.c:10806 commands/tablecmds.c:10818 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "Ñменить владельца индекÑа \"%s\" нельзÑ" -#: commands/tablecmds.c:9529 +#: commands/tablecmds.c:10808 commands/tablecmds.c:10820 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "Однако возможно Ñменить владельца таблицы, Ñодержащей Ñтот индекÑ." -#: commands/tablecmds.c:9545 +#: commands/tablecmds.c:10834 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "Ñменить владельца поÑледовательноÑти \"%s\" нельзÑ" -#: commands/tablecmds.c:9547 commands/tablecmds.c:12122 -#, c-format -msgid "Sequence \"%s\" is linked to table \"%s\"." -msgstr "ПоÑледовательноÑть \"%s\" ÑвÑзана Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹ \"%s\"." - -#: commands/tablecmds.c:9559 commands/tablecmds.c:12769 +#: commands/tablecmds.c:10848 commands/tablecmds.c:14132 #, c-format msgid "Use ALTER TYPE instead." msgstr "ИÑпользуйте ALTER TYPE." -#: commands/tablecmds.c:9568 +#: commands/tablecmds.c:10857 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "" "\"%s\" - Ñто не таблица, TOAST-таблица, индекÑ, предÑтавление или " "поÑледовательноÑть" -#: commands/tablecmds.c:9909 +#: commands/tablecmds.c:11197 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "в одной инÑтрукции не может быть неÑколько подкоманд SET TABLESPACE" -#: commands/tablecmds.c:9983 +#: commands/tablecmds.c:11272 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "" "\"%s\" - Ñто не таблица, предÑтавление, материализованное предÑтавление, " "Ð¸Ð½Ð´ÐµÐºÑ Ð¸Ð»Ð¸ TOAST-таблица" -#: commands/tablecmds.c:10016 commands/view.c:504 +#: commands/tablecmds.c:11305 commands/view.c:503 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "" "WITH CHECK OPTION поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ð±Ð½Ð¾Ð²Ð»Ñемыми предÑтавлениÑми" -#: commands/tablecmds.c:10158 +#: commands/tablecmds.c:11447 #, c-format msgid "cannot move system relation \"%s\"" msgstr "перемеÑтить ÑиÑтемную таблицу \"%s\" нельзÑ" -#: commands/tablecmds.c:10174 +#: commands/tablecmds.c:11463 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "перемещать временные таблицы других ÑеанÑов нельзÑ" -#: commands/tablecmds.c:10310 +#: commands/tablecmds.c:11654 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "" "в табличных проÑтранÑтвах еÑть только таблицы, индекÑÑ‹ и материализованные " "предÑтавлениÑ" -#: commands/tablecmds.c:10322 +#: commands/tablecmds.c:11666 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "перемещать объекты в/из табличного проÑтранÑтва pg_global нельзÑ" -#: commands/tablecmds.c:10414 +#: commands/tablecmds.c:11759 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "" "обработка прерываетÑÑ Ð¸Ð·-за невозможноÑти заблокировать отношение \"%s.%s\"" -#: commands/tablecmds.c:10430 +#: commands/tablecmds.c:11775 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "в табличном проÑтранÑтве \"%s\" не найдены подходÑщие отношениÑ" -#: commands/tablecmds.c:10504 storage/buffer/bufmgr.c:915 +#: commands/tablecmds.c:11842 storage/buffer/bufmgr.c:915 #, c-format msgid "invalid page in block %u of relation %s" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñтраница в блоке %u Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: commands/tablecmds.c:10586 +#: commands/tablecmds.c:11922 #, c-format msgid "cannot change inheritance of typed table" msgstr "изменить наÑледование типизированной таблицы нельзÑ" -#: commands/tablecmds.c:10591 commands/tablecmds.c:11119 +#: commands/tablecmds.c:11927 commands/tablecmds.c:12470 #, c-format msgid "cannot change inheritance of a partition" msgstr "изменить наÑледование Ñекции нельзÑ" -#: commands/tablecmds.c:10596 +#: commands/tablecmds.c:11932 #, c-format msgid "cannot change inheritance of partitioned table" msgstr "изменить наÑледование Ñекционированной таблицы нельзÑ" -#: commands/tablecmds.c:10641 +#: commands/tablecmds.c:11978 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "наÑледование Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð³Ð¾ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð³Ð¾ ÑеанÑа невозможно" -#: commands/tablecmds.c:10654 +#: commands/tablecmds.c:11991 #, c-format msgid "cannot inherit from a partition" msgstr "наÑледование от Ñекции невозможно" -#: commands/tablecmds.c:10676 commands/tablecmds.c:13121 +#: commands/tablecmds.c:12013 commands/tablecmds.c:14716 #, c-format msgid "circular inheritance not allowed" msgstr "цикличеÑкое наÑледование недопуÑтимо" -#: commands/tablecmds.c:10677 commands/tablecmds.c:13122 +#: commands/tablecmds.c:12014 commands/tablecmds.c:14717 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\" уже ÑвлÑетÑÑ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð¼ \"%s\"." -#: commands/tablecmds.c:10685 +#: commands/tablecmds.c:12022 #, c-format msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" msgstr "таблица \"%s\" без OID не может наÑледоватьÑÑ Ð¾Ñ‚ таблицы \"%s\" Ñ OID" -#: commands/tablecmds.c:10889 +#: commands/tablecmds.c:12035 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "" +"триггер \"%s\" не позволÑет таблице \"%s\" Ñтать потомком в иерархии " +"наÑледованиÑ" + +#: commands/tablecmds.c:12037 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported in inheritance " +"hierarchies" +msgstr "" +"триггеры ROW Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ таблицами не поддерживаютÑÑ Ð² иерархиÑÑ… " +"наÑледованиÑ" + +#: commands/tablecmds.c:12240 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "Ñтолбец \"%s\" в дочерней таблице должен быть помечен как NOT NULL" -#: commands/tablecmds.c:10916 commands/tablecmds.c:10955 +#: commands/tablecmds.c:12267 commands/tablecmds.c:12306 #, c-format msgid "child table is missing column \"%s\"" msgstr "в дочерней таблице не хватает Ñтолбца \"%s\"" -#: commands/tablecmds.c:11043 +#: commands/tablecmds.c:12394 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "" -"дочернÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" Ñодержит другое определение ограничениÑ-проверки \"%s" -"\"" +"дочернÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" Ñодержит другое определение ограничениÑ-проверки \"" +"%s\"" -#: commands/tablecmds.c:11051 +#: commands/tablecmds.c:12402 #, c-format msgid "" -"constraint \"%s\" conflicts with non-inherited constraint on child table \"%s" -"\"" +"constraint \"%s\" conflicts with non-inherited constraint on child table \"" +"%s\"" msgstr "" "ограничение \"%s\" конфликтует Ñ Ð½ÐµÐ½Ð°Ñледуемым ограничением дочерней таблицы " "\"%s\"" -#: commands/tablecmds.c:11062 +#: commands/tablecmds.c:12413 #, c-format msgid "" "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" @@ -9994,81 +10420,81 @@ msgstr "" "ограничение \"%s\" конфликтует Ñ Ð½ÐµÐ¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ñ‹Ð¼ (NOT VALID) ограничением " "дочерней таблицы \"%s\"" -#: commands/tablecmds.c:11097 +#: commands/tablecmds.c:12448 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "в дочерней таблице не хватает Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/tablecmds.c:11213 +#: commands/tablecmds.c:12537 #, c-format msgid "relation \"%s\" is not a partition of relation \"%s\"" msgstr "отношение \"%s\" не ÑвлÑетÑÑ Ñекцией Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" -#: commands/tablecmds.c:11219 +#: commands/tablecmds.c:12543 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "отношение \"%s\" не ÑвлÑетÑÑ Ð¿Ñ€ÐµÐ´ÐºÐ¾Ð¼ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" -#: commands/tablecmds.c:11443 +#: commands/tablecmds.c:12769 #, c-format msgid "typed tables cannot inherit" msgstr "типизированные таблицы не могут наÑледоватьÑÑ" -#: commands/tablecmds.c:11474 +#: commands/tablecmds.c:12800 #, c-format msgid "table is missing column \"%s\"" msgstr "в таблице не хватает Ñтолбца \"%s\"" -#: commands/tablecmds.c:11484 +#: commands/tablecmds.c:12811 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "таблица Ñодержит Ñтолбец \"%s\", тогда как тип требует \"%s\"" -#: commands/tablecmds.c:11493 +#: commands/tablecmds.c:12820 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "таблица \"%s\" Ñодержит Ñтолбец \"%s\" другого типа" -#: commands/tablecmds.c:11506 +#: commands/tablecmds.c:12834 #, c-format msgid "table has extra column \"%s\"" msgstr "таблица Ñодержит лишний Ñтолбец \"%s\"" -#: commands/tablecmds.c:11557 +#: commands/tablecmds.c:12886 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\" - Ñто не Ñ‚Ð¸Ð¿Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:11738 +#: commands/tablecmds.c:13068 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "" "Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать неуникальный Ð¸Ð½Ð´ÐµÐºÑ \"%s\"" -#: commands/tablecmds.c:11744 +#: commands/tablecmds.c:13074 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "" -"Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать не непоÑредÑтвенный Ð¸Ð½Ð´ÐµÐºÑ \"%s" -"\"" +"Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать не непоÑредÑтвенный Ð¸Ð½Ð´ÐµÐºÑ \"" +"%s\"" -#: commands/tablecmds.c:11750 +#: commands/tablecmds.c:13080 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "" "Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð¸Ð½Ð´ÐµÐºÑ Ñ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸ÐµÐ¼ \"%s\"" -#: commands/tablecmds.c:11756 +#: commands/tablecmds.c:13086 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать чаÑтичный Ð¸Ð½Ð´ÐµÐºÑ \"%s\"" -#: commands/tablecmds.c:11762 +#: commands/tablecmds.c:13092 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать нерабочий Ð¸Ð½Ð´ÐµÐºÑ \"%s\"" -#: commands/tablecmds.c:11783 +#: commands/tablecmds.c:13113 #, c-format msgid "" "index \"%s\" cannot be used as replica identity because column %d is a " @@ -10077,7 +10503,7 @@ msgstr "" "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики, так как Ñтолбец " "%d - ÑиÑтемный" -#: commands/tablecmds.c:11790 +#: commands/tablecmds.c:13120 #, c-format msgid "" "index \"%s\" cannot be used as replica identity because column \"%s\" is " @@ -10086,13 +10512,13 @@ msgstr "" "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ реплики, так как Ñтолбец " "\"%s\" допуÑкает NULL" -#: commands/tablecmds.c:11983 +#: commands/tablecmds.c:13313 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "" "изменить ÑоÑтоÑние Ð¶ÑƒÑ€Ð½Ð°Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ %s нельзÑ, так как она временнаÑ" -#: commands/tablecmds.c:12007 +#: commands/tablecmds.c:13337 #, c-format msgid "" "cannot change table \"%s\" to unlogged because it is part of a publication" @@ -10100,12 +10526,12 @@ msgstr "" "таблицу \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ñделать нежурналируемой, так как она включена в " "публикацию" -#: commands/tablecmds.c:12009 +#: commands/tablecmds.c:13339 #, c-format msgid "Unlogged relations cannot be replicated." msgstr "Ðежурналируемые Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ поддерживают репликацию." -#: commands/tablecmds.c:12054 +#: commands/tablecmds.c:13384 #, c-format msgid "" "could not change table \"%s\" to logged because it references unlogged table " @@ -10114,7 +10540,7 @@ msgstr "" "не удалоÑÑŒ Ñделать таблицу \"%s\" журналируемой, так как она ÑÑылаетÑÑ Ð½Ð° " "нежурналируемую таблицу \"%s\"" -#: commands/tablecmds.c:12064 +#: commands/tablecmds.c:13394 #, c-format msgid "" "could not change table \"%s\" to unlogged because it references logged table " @@ -10123,22 +10549,22 @@ msgstr "" "не удалоÑÑŒ Ñделать таблицу \"%s\" нежурналируемой, так как она ÑÑылаетÑÑ Ð½Ð° " "журналируемую таблицу \"%s\"" -#: commands/tablecmds.c:12121 +#: commands/tablecmds.c:13452 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "перемеÑтить поÑледовательноÑть Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ в другую Ñхему нельзÑ" -#: commands/tablecmds.c:12227 +#: commands/tablecmds.c:13558 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "отношение \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" -#: commands/tablecmds.c:12753 +#: commands/tablecmds.c:14115 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\" - Ñто не ÑоÑтавной тип" -#: commands/tablecmds.c:12784 +#: commands/tablecmds.c:14147 #, c-format msgid "" "\"%s\" is not a table, view, materialized view, sequence, or foreign table" @@ -10146,52 +10572,77 @@ msgstr "" "\"%s\" - Ñто не таблица, предÑтавление, мат. предÑтавление, " "поÑледовательноÑть или ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/tablecmds.c:12815 +#: commands/tablecmds.c:14182 #, c-format msgid "unrecognized partitioning strategy \"%s\"" msgstr "нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s\"" -#: commands/tablecmds.c:12841 +#: commands/tablecmds.c:14190 #, c-format -msgid "column \"%s\" appears more than once in partition key" -msgstr "Ñтолбец \"%s\" фигурирует в ключе Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ð¾" +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ ÑпиÑку не поддерживает неÑколько Ñтолбцов" -#: commands/tablecmds.c:12889 +#: commands/tablecmds.c:14255 #, c-format msgid "column \"%s\" named in partition key does not exist" -msgstr "Ñтолбец \"%s\", упомÑнутый в ключе разбиениÑ, не ÑущеÑтвует" +msgstr "Ñтолбец \"%s\", упомÑнутый в ключе ÑекционированиÑ, не ÑущеÑтвует" -#: commands/tablecmds.c:12896 +#: commands/tablecmds.c:14262 #, c-format msgid "cannot use system column \"%s\" in partition key" -msgstr "ÑиÑтемный Ñтолбец \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в ключе разбиениÑ" +msgstr "ÑиÑтемный Ñтолбец \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в ключе ÑекционированиÑ" -#: commands/tablecmds.c:12954 +#: commands/tablecmds.c:14325 #, c-format msgid "functions in partition key expression must be marked IMMUTABLE" -msgstr "функции в выражении ключа Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть помечены как IMMUTABLE" +msgstr "" +"функции в выражении ключа ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть помечены как IMMUTABLE" -#: commands/tablecmds.c:12963 +#: commands/tablecmds.c:14342 #, c-format -msgid "cannot use constant expression as partition key" -msgstr "в качеÑтве ключа Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать конÑтантное выражение" +msgid "partition key expressions cannot contain whole-row references" +msgstr "" +"Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ могут Ñодержать ÑÑылки на кортеж целиком" -#: commands/tablecmds.c:12977 +#: commands/tablecmds.c:14349 #, c-format -msgid "partition key expressions cannot contain whole-row references" -msgstr "Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð½Ðµ могут Ñодержать ÑÑылки на кортеж целиком" +msgid "partition key expressions cannot contain system column references" +msgstr "" +"Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ¹ ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ могут Ñодержать ÑÑылки на ÑиÑтемный " +"Ñтолбец" + +#: commands/tablecmds.c:14359 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "" +"в качеÑтве ключа ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать конÑтантное выражение" -#: commands/tablecmds.c:12998 +#: commands/tablecmds.c:14380 #, c-format msgid "could not determine which collation to use for partition expression" -msgstr "не удалоÑÑŒ определить правило Ñортировки Ð´Ð»Ñ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ" +msgstr "не удалоÑÑŒ определить правило Ñортировки Ð´Ð»Ñ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ÑекционированиÑ" + +#: commands/tablecmds.c:14413 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "" +"Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s не определён клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ умолчанию" + +#: commands/tablecmds.c:14415 +#, c-format +msgid "" +"You must specify a hash operator class or define a default hash operator " +"class for the data type." +msgstr "" +"Ð’Ñ‹ должны указать клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ определить клаÑÑ " +"операторов Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ умолчанию Ð´Ð»Ñ Ñтого типа данных." -#: commands/tablecmds.c:13023 +#: commands/tablecmds.c:14419 #, c-format msgid "data type %s has no default btree operator class" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s не определён клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² B-дерева по умолчанию" -#: commands/tablecmds.c:13025 +#: commands/tablecmds.c:14421 #, c-format msgid "" "You must specify a btree operator class or define a default btree operator " @@ -10200,46 +10651,72 @@ msgstr "" "Ð’Ñ‹ должны указать клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² B-дерева или определить клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² " "B-дерева по умолчанию Ð´Ð»Ñ Ñтого типа данных." -#: commands/tablecmds.c:13072 +#: commands/tablecmds.c:14546 +#, c-format +msgid "" +"partition constraint for table \"%s\" is implied by existing constraints" +msgstr "" +"ограничение Ñекции Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" подразумеваетÑÑ ÑущеÑтвующими " +"ограничениÑми" + +#: commands/tablecmds.c:14550 partitioning/partbounds.c:621 +#: partitioning/partbounds.c:666 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" is implied by " +"existing constraints" +msgstr "" +"изменённое ограничение Ñекции Ð´Ð»Ñ Ñекции по умолчанию \"%s\" подразумеваетÑÑ " +"ÑущеÑтвующими ограничениÑми" + +#: commands/tablecmds.c:14656 #, c-format msgid "\"%s\" is already a partition" msgstr "\"%s\" уже ÑвлÑетÑÑ Ñекцией" -#: commands/tablecmds.c:13078 +#: commands/tablecmds.c:14662 #, c-format msgid "cannot attach a typed table as partition" msgstr "подключить типизированную таблицу в качеÑтве Ñекции нельзÑ" -#: commands/tablecmds.c:13094 +#: commands/tablecmds.c:14678 #, c-format msgid "cannot attach inheritance child as partition" msgstr "подключить потомок в иерархии наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² качеÑтве Ñекции нельзÑ" -#: commands/tablecmds.c:13108 +#: commands/tablecmds.c:14692 #, c-format msgid "cannot attach inheritance parent as partition" msgstr "подключить родитель в иерархии наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² качеÑтве Ñекции нельзÑ" -#: commands/tablecmds.c:13131 +#: commands/tablecmds.c:14726 +#, c-format +msgid "" +"cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "" +"подключить временное отношение в качеÑтве Ñекции поÑтоÑнного Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"" +"%s\" нельзÑ" + +#: commands/tablecmds.c:14734 #, c-format msgid "" "cannot attach a permanent relation as partition of temporary relation \"%s\"" msgstr "" -"подключить поÑтоÑнное отношение в качеÑтве Ñекции временного Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s" -"\" нельзÑ" +"подключить поÑтоÑнное отношение в качеÑтве Ñекции временного Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"" +"%s\" нельзÑ" -#: commands/tablecmds.c:13139 +#: commands/tablecmds.c:14742 #, c-format msgid "cannot attach as partition of temporary relation of another session" msgstr "подключить Ñекцию к временному отношению в другом ÑеанÑе нельзÑ" -#: commands/tablecmds.c:13146 +#: commands/tablecmds.c:14749 #, c-format msgid "cannot attach temporary relation of another session as partition" msgstr "" "подключить временное отношение из другого ÑеанÑа в качеÑтве Ñекции нельзÑ" -#: commands/tablecmds.c:13152 +#: commands/tablecmds.c:14755 #, c-format msgid "" "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with " @@ -10248,7 +10725,7 @@ msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ таблицу \"%s\" без OID в качеÑтве Ñекции таблицы \"%s\" Ñ " "OID" -#: commands/tablecmds.c:13160 +#: commands/tablecmds.c:14763 #, c-format msgid "" "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without " @@ -10257,353 +10734,432 @@ msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ таблицу \"%s\" Ñ OID в качеÑтве Ñекции таблицы \"%s\" без " "OID" -#: commands/tablecmds.c:13182 +#: commands/tablecmds.c:14785 #, c-format msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" msgstr "" "таблица \"%s\" Ñодержит Ñтолбец \"%s\", отÑутÑтвующий в родителе \"%s\"" -#: commands/tablecmds.c:13185 +#: commands/tablecmds.c:14788 #, c-format -msgid "New partition should contain only the columns present in parent." +msgid "The new partition may contain only the columns present in parent." msgstr "" -"ÐÐ¾Ð²Ð°Ñ ÑÐµÐºÑ†Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° Ñодержать только Ñтолбцы, имеющиеÑÑ Ð² родительÑкой " +"ÐÐ¾Ð²Ð°Ñ ÑÐµÐºÑ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ Ñодержать только Ñтолбцы, имеющиеÑÑ Ð² родительÑкой " "таблице." -#: commands/tablecmds.c:13357 +#: commands/tablecmds.c:14800 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "триггер \"%s\" не позволÑет Ñделать таблицу \"%s\" Ñекцией" + +#: commands/tablecmds.c:14802 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "триггеры ROW Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ таблицами Ð´Ð»Ñ Ñекций не поддерживаютÑÑ" + +#: commands/tablecmds.c:15490 commands/tablecmds.c:15509 +#: commands/tablecmds.c:15531 commands/tablecmds.c:15550 +#: commands/tablecmds.c:15605 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñоединить Ð¸Ð½Ð´ÐµÐºÑ \"%s\" в качеÑтве Ñекции индекÑа \"%s\"" + +#: commands/tablecmds.c:15493 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "Ð˜Ð½Ð´ÐµÐºÑ \"%s\" уже приÑоединён к другому индекÑу." + +#: commands/tablecmds.c:15512 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "Ð˜Ð½Ð´ÐµÐºÑ \"%s\" не ÑвлÑетÑÑ Ð¸Ð½Ð´ÐµÐºÑом какой-либо Ñекции таблицы \"%s\"." + +#: commands/tablecmds.c:15534 +#, c-format +msgid "The index definitions do not match." +msgstr "ÐžÐ¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑов не Ñовпадают." + +#: commands/tablecmds.c:15553 #, c-format msgid "" -"partition constraint for table \"%s\" is implied by existing constraints" +"The index \"%s\" belongs to a constraint in table \"%s\" but no constraint " +"exists for index \"%s\"." msgstr "" -"ограничение Ñекции Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" подразумеваетÑÑ ÑущеÑтвующими " -"ограничениÑми" +"Ð˜Ð½Ð´ÐµÐºÑ \"%s\" принадлежит ограничению в таблице \"%s\", но Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа \"" +"%s\" Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚." + +#: commands/tablecmds.c:15608 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "К Ñекции \"%s\" уже приÑоединён другой индекÑ." -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:623 replication/slot.c:1106 storage/file/copydir.c:47 +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:625 replication/slot.c:1199 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать каталог \"%s\": %m" -#: commands/tablespace.c:209 utils/adt/genfile.c:538 +#: commands/tablespace.c:210 utils/adt/genfile.c:581 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о каталоге \"%s\": %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "\"%s\" ÑущеÑтвует, но Ñто не каталог" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "нет прав на Ñоздание табличного проÑтранÑтва \"%s\"" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "Ð”Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ проÑтранÑтва нужно быть Ñуперпользователем." -#: commands/tablespace.c:267 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "в пути к табличному проÑтранÑтву не должно быть одинарных кавычек" -#: commands/tablespace.c:277 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "путь к табличному проÑтранÑтву должен быть абÑолютным" -#: commands/tablespace.c:288 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "путь к табличному проÑтранÑтву \"%s\" Ñлишком длинный" -#: commands/tablespace.c:295 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "табличное проÑтранÑтво не должно раÑполагатьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ каталога данных" -#: commands/tablespace.c:304 commands/tablespace.c:950 +#: commands/tablespace.c:306 commands/tablespace.c:952 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "неприемлемое Ð¸Ð¼Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ проÑтранÑтва: \"%s\"" -#: commands/tablespace.c:306 commands/tablespace.c:951 +#: commands/tablespace.c:308 commands/tablespace.c:953 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "ÐŸÑ€ÐµÑ„Ð¸ÐºÑ \"pg_\" зарезервирован Ð´Ð»Ñ ÑиÑтемных табличных проÑтранÑтв." -#: commands/tablespace.c:316 commands/tablespace.c:963 +#: commands/tablespace.c:318 commands/tablespace.c:965 #, c-format msgid "tablespace \"%s\" already exists" msgstr "табличное проÑтранÑтво \"%s\" уже ÑущеÑтвует" -#: commands/tablespace.c:428 commands/tablespace.c:933 -#: commands/tablespace.c:1013 commands/tablespace.c:1081 -#: commands/tablespace.c:1214 commands/tablespace.c:1414 +#: commands/tablespace.c:430 commands/tablespace.c:935 +#: commands/tablespace.c:1015 commands/tablespace.c:1083 +#: commands/tablespace.c:1216 commands/tablespace.c:1416 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "табличное проÑтранÑтво \"%s\" не ÑущеÑтвует" -#: commands/tablespace.c:434 +#: commands/tablespace.c:436 #, c-format msgid "tablespace \"%s\" does not exist, skipping" msgstr "табличное проÑтранÑтво \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tablespace.c:510 +#: commands/tablespace.c:512 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "табличное проÑтранÑтво \"%s\" не пуÑто" -#: commands/tablespace.c:582 +#: commands/tablespace.c:584 #, c-format msgid "directory \"%s\" does not exist" msgstr "каталог \"%s\" не ÑущеÑтвует" -#: commands/tablespace.c:583 +#: commands/tablespace.c:585 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "" "Создайте Ñтот каталог Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ проÑтранÑтва до перезапуÑка Ñервера." -#: commands/tablespace.c:588 +#: commands/tablespace.c:590 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "не удалоÑÑŒ уÑтановить права Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° \"%s\": %m" -#: commands/tablespace.c:618 +#: commands/tablespace.c:620 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "каталог \"%s\" уже иÑпользуетÑÑ ÐºÐ°Ðº табличное проÑтранÑтво" -#: commands/tablespace.c:742 commands/tablespace.c:755 -#: commands/tablespace.c:791 commands/tablespace.c:883 +#: commands/tablespace.c:705 commands/tablespace.c:715 +#: postmaster/postmaster.c:1477 storage/file/fd.c:2714 +#: storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 +#: utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "не удалоÑÑŒ открыть каталог \"%s\": %m" + +#: commands/tablespace.c:744 commands/tablespace.c:757 +#: commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3144 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "ошибка при удалении каталога \"%s\": %m" -#: commands/tablespace.c:804 commands/tablespace.c:892 +#: commands/tablespace.c:806 commands/tablespace.c:894 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "ошибка при удалении ÑимволичеÑкой ÑÑылки \"%s\": %m" -#: commands/tablespace.c:814 commands/tablespace.c:901 +#: commands/tablespace.c:816 commands/tablespace.c:903 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "\"%s\" - Ñто не каталог или ÑимволичеÑÐºÐ°Ñ ÑÑылка" -#: commands/tablespace.c:1086 +#: commands/tablespace.c:1088 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "Табличное проÑтранÑтво \"%s\" не ÑущеÑтвует." -#: commands/tablespace.c:1513 +#: commands/tablespace.c:1515 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "удалить каталоги табличного проÑтранÑтва %u не удалоÑÑŒ" -#: commands/tablespace.c:1515 +#: commands/tablespace.c:1517 #, c-format msgid "You can remove the directories manually if necessary." msgstr "При необходимоÑти вы можете удалить их вручную." -#: commands/trigger.c:187 +#: commands/trigger.c:207 commands/trigger.c:218 #, c-format msgid "\"%s\" is a table" msgstr "\"%s\" - Ñто таблица" -#: commands/trigger.c:189 +#: commands/trigger.c:209 commands/trigger.c:220 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "У таблиц не может быть триггеров INSTEAD OF." -#: commands/trigger.c:194 commands/trigger.c:360 +#: commands/trigger.c:237 #, c-format -msgid "\"%s\" is a partitioned table" -msgstr "\"%s\" - ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "" +"Ð’ Ñекционированных таблицах не может быть триггеров BEFORE / FOR EACH ROW." -#: commands/trigger.c:196 +#: commands/trigger.c:255 #, c-format -msgid "Partitioned tables cannot have ROW triggers." -msgstr "У Ñекционированных таблиц не может быть триггеров на уровне Ñтрок." +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "" +"Триггеры Ñекционированных таблиц не могут иÑпользовать переходные таблицы." -#: commands/trigger.c:207 commands/trigger.c:214 +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 #, c-format msgid "\"%s\" is a view" msgstr "\"%s\" - Ñто предÑтавление" -#: commands/trigger.c:209 +#: commands/trigger.c:269 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "У предÑтавлений не может быть Ñтроковых триггеров BEFORE/AFTER." -#: commands/trigger.c:216 +#: commands/trigger.c:276 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "У предÑтавлений не может быть триггеров TRUNCATE." -#: commands/trigger.c:224 commands/trigger.c:231 commands/trigger.c:238 +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 +#: commands/trigger.c:437 #, c-format msgid "\"%s\" is a foreign table" msgstr "\"%s\" - ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: commands/trigger.c:226 +#: commands/trigger.c:286 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "У Ñторонних таблиц не может быть триггеров INSTEAD OF." -#: commands/trigger.c:233 +#: commands/trigger.c:293 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "У Ñторонних таблиц не может быть триггеров TRUNCATE." -#: commands/trigger.c:240 +#: commands/trigger.c:305 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "У Ñторонних таблиц не может быть ограничивающих триггеров." -#: commands/trigger.c:303 +#: commands/trigger.c:380 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "триггеры TRUNCATE FOR EACH ROW не поддерживаютÑÑ" -#: commands/trigger.c:311 +#: commands/trigger.c:388 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "триггеры INSTEAD OF должны иметь тип FOR EACH ROW" -#: commands/trigger.c:315 +#: commands/trigger.c:392 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "триггеры INSTEAD OF неÑовмеÑтимы Ñ ÑƒÑловиÑми WHEN" -#: commands/trigger.c:319 +#: commands/trigger.c:396 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð² INSTEAD OF Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ ÑпиÑок Ñтолбцов" -#: commands/trigger.c:348 +#: commands/trigger.c:425 #, c-format msgid "ROW variable naming in the REFERENCING clause is not supported" msgstr "" "указание переменной типа кортеж в предложении REFERENCING не поддерживаетÑÑ" -#: commands/trigger.c:349 +#: commands/trigger.c:426 #, c-format msgid "Use OLD TABLE or NEW TABLE for naming transition tables." msgstr "ИÑпользуйте OLD TABLE или NEW TABLE Ð´Ð»Ñ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ñ… таблиц." -#: commands/trigger.c:362 +#: commands/trigger.c:439 #, c-format -msgid "Triggers on partitioned tables cannot have transition tables." +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Триггеры Ñторонних таблиц не могут иÑпользовать переходные таблицы." + +#: commands/trigger.c:446 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Триггеры предÑтавлений не могут иÑпользовать переходные таблицы." + +#: commands/trigger.c:466 +#, c-format +msgid "" +"ROW triggers with transition tables are not supported on inheritance children" msgstr "" -"Триггеры Ñекционированных таблиц не могут иÑпользовать переходные таблицы." +"триггеры ROW Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ таблицами Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ¾Ð² в иерархии наÑÐ»ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ " +"поддерживаютÑÑ" -#: commands/trigger.c:367 +#: commands/trigger.c:472 #, c-format msgid "transition table name can only be specified for an AFTER trigger" msgstr "Ð¸Ð¼Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ð¾Ð¹ таблицы можно задать только Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° AFTER" -#: commands/trigger.c:375 +#: commands/trigger.c:477 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "триггеры TRUNCATE Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ таблицами не поддерживаютÑÑ" + +#: commands/trigger.c:494 +#, c-format +msgid "" +"transition tables cannot be specified for triggers with more than one event" +msgstr "" +"переходные таблицы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð², назначаемых Ð´Ð»Ñ Ð½ÐµÑкольких " +"Ñобытий" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "переходные таблицы Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð² Ñо ÑпиÑками Ñтолбцов" + +#: commands/trigger.c:522 #, c-format msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" msgstr "NEW TABLE можно задать только Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð² INSERT или UPDATE" -#: commands/trigger.c:380 +#: commands/trigger.c:527 #, c-format msgid "NEW TABLE cannot be specified multiple times" msgstr "NEW TABLE Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ неÑколько раз" -#: commands/trigger.c:390 +#: commands/trigger.c:537 #, c-format msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" msgstr "OLD TABLE можно задать только Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð² DELETE или UPDATE" -#: commands/trigger.c:395 +#: commands/trigger.c:542 #, c-format msgid "OLD TABLE cannot be specified multiple times" msgstr "OLD TABLE Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ неÑколько раз" -#: commands/trigger.c:405 +#: commands/trigger.c:552 #, c-format msgid "OLD TABLE name and NEW TABLE name cannot be the same" msgstr "Ð¸Ð¼Ñ OLD TABLE не должно Ñовпадать Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ NEW TABLE" -#: commands/trigger.c:462 commands/trigger.c:475 +#: commands/trigger.c:614 commands/trigger.c:627 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "" "в уÑловии WHEN Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð½Ð¾Ð³Ð¾ триггера Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ " "Ñтолбцов" -#: commands/trigger.c:467 +#: commands/trigger.c:619 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "в уÑловии WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° INSERT Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ OLD" -#: commands/trigger.c:480 +#: commands/trigger.c:632 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "в уÑловии WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° DELETE Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NEW" -#: commands/trigger.c:485 +#: commands/trigger.c:637 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "" "в уÑловии WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° BEFORE Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° ÑиÑтемные Ñтолбцы NEW" -#: commands/trigger.c:650 commands/trigger.c:1421 +#: commands/trigger.c:810 commands/trigger.c:1705 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "триггер \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑущеÑтвует" -#: commands/trigger.c:946 +#: commands/trigger.c:1230 msgid "Found referenced table's UPDATE trigger." msgstr "Ðайден триггер UPDATE в главной таблице." -#: commands/trigger.c:947 +#: commands/trigger.c:1231 msgid "Found referenced table's DELETE trigger." msgstr "Ðайден триггер DELETE в главной таблице." -#: commands/trigger.c:948 +#: commands/trigger.c:1232 msgid "Found referencing table's trigger." msgstr "Ðайден триггер в подчинённой таблице." -#: commands/trigger.c:1057 commands/trigger.c:1073 +#: commands/trigger.c:1341 commands/trigger.c:1357 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "неполный набор триггеров Ð´Ð»Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ \"%s\" %s игнорируетÑÑ" -#: commands/trigger.c:1086 +#: commands/trigger.c:1370 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "преобразование набора триггеров в ограничение \"%s\" %s" -#: commands/trigger.c:1307 commands/trigger.c:1466 commands/trigger.c:1581 +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "триггер \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" не ÑущеÑтвует" -#: commands/trigger.c:1549 +#: commands/trigger.c:1833 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "нет доÑтупа: \"%s\" - Ñто ÑиÑтемный триггер" -#: commands/trigger.c:2104 +#: commands/trigger.c:2433 #, c-format msgid "trigger function %u returned null value" msgstr "Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %u вернула значение NULL" -#: commands/trigger.c:2165 commands/trigger.c:2371 commands/trigger.c:2582 -#: commands/trigger.c:2861 +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 +#: commands/trigger.c:3243 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "триггер BEFORE STATEMENT не может возвращать значение" -#: commands/trigger.c:2923 executor/nodeModifyTable.c:747 -#: executor/nodeModifyTable.c:1042 +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 +#: executor/nodeModifyTable.c:1244 #, c-format msgid "" "tuple to be updated was already modified by an operation triggered by the " @@ -10612,8 +11168,8 @@ msgstr "" "кортеж, который должен быть изменён, уже модифицирован в операции, вызванной " "текущей командой" -#: commands/trigger.c:2924 executor/nodeModifyTable.c:748 -#: executor/nodeModifyTable.c:1043 +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 +#: executor/nodeModifyTable.c:1245 #, c-format msgid "" "Consider using an AFTER trigger instead of a BEFORE trigger to propagate " @@ -10622,19 +11178,30 @@ msgstr "" "Возможно, Ð´Ð»Ñ Ñ€Ð°ÑпроÑÑ‚Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ в другие Ñтроки Ñледует иÑпользовать " "триггер AFTER вмеÑто BEFORE." -#: commands/trigger.c:2938 executor/execMain.c:2562 executor/nodeLockRows.c:216 -#: executor/nodeModifyTable.c:214 executor/nodeModifyTable.c:760 -#: executor/nodeModifyTable.c:1055 executor/nodeModifyTable.c:1221 +#: commands/trigger.c:3320 executor/execMain.c:2727 +#: executor/nodeLockRows.c:220 executor/nodeModifyTable.c:225 +#: executor/nodeModifyTable.c:769 executor/nodeModifyTable.c:1257 +#: executor/nodeModifyTable.c:1433 #, c-format msgid "could not serialize access due to concurrent update" msgstr "не удалоÑÑŒ Ñериализовать доÑтуп из-за параллельного изменениÑ" -#: commands/trigger.c:4841 +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 +#: executor/nodeLockRows.c:224 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update" +msgstr "" +"кортеж, подлежащий блокировке, был перемещён в другую Ñекцию в результате " +"параллельного изменениÑ" + +#: commands/trigger.c:5457 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "ограничение \"%s\" не ÑвлÑетÑÑ Ð¾Ñ‚ÐºÐ»Ð°Ð´Ñ‹Ð²Ð°ÐµÐ¼Ñ‹Ð¼" -#: commands/trigger.c:4864 +#: commands/trigger.c:5480 #, c-format msgid "constraint \"%s\" does not exist" msgstr "ограничение \"%s\" не ÑущеÑтвует" @@ -10715,67 +11282,67 @@ msgstr "указать и PARSER, и COPY одновременно нельзÑ" msgid "text search parser is required" msgstr "требуетÑÑ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°Ñ‚Ð¾Ñ€ текÑтового поиÑка" -#: commands/tsearchcmds.c:1266 +#: commands/tsearchcmds.c:1265 #, c-format msgid "token type \"%s\" does not exist" msgstr "тип фрагмента \"%s\" не ÑущеÑтвует" -#: commands/tsearchcmds.c:1487 +#: commands/tsearchcmds.c:1486 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "ÑопоÑтавление Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° фрагмента \"%s\" не ÑущеÑтвует" -#: commands/tsearchcmds.c:1493 +#: commands/tsearchcmds.c:1492 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "ÑопоÑтавление Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° фрагмента \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/tsearchcmds.c:1648 commands/tsearchcmds.c:1759 +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "неверный формат ÑпиÑка параметров: \"%s\"" -#: commands/typecmds.c:183 +#: commands/typecmds.c:180 #, c-format msgid "must be superuser to create a base type" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð³Ð¾ типа нужно быть Ñуперпользователем" -#: commands/typecmds.c:290 commands/typecmds.c:1414 +#: commands/typecmds.c:287 commands/typecmds.c:1483 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "атрибут типа \"%s\" не раÑпознан" -#: commands/typecmds.c:346 +#: commands/typecmds.c:343 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ñ‚Ð¸Ð¿Ð° \"%s\": допуÑтим только ASCII-Ñимвол" -#: commands/typecmds.c:365 +#: commands/typecmds.c:362 #, c-format msgid "array element type cannot be %s" msgstr "типом Ñлемента маÑÑива не может быть %s" -#: commands/typecmds.c:397 +#: commands/typecmds.c:394 #, c-format msgid "alignment \"%s\" not recognized" msgstr "тип Ð²Ñ‹Ñ€Ð°Ð²Ð½Ð¸Ð²Ð°Ð½Ð¸Ñ \"%s\" не раÑпознан" -#: commands/typecmds.c:414 +#: commands/typecmds.c:411 #, c-format msgid "storage \"%s\" not recognized" msgstr "неизвеÑÑ‚Ð½Ð°Ñ ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/typecmds.c:425 +#: commands/typecmds.c:422 #, c-format msgid "type input function must be specified" msgstr "необходимо указать функцию ввода типа" -#: commands/typecmds.c:429 +#: commands/typecmds.c:426 #, c-format msgid "type output function must be specified" msgstr "необходимо указать функцию вывода типа" -#: commands/typecmds.c:434 +#: commands/typecmds.c:431 #, c-format msgid "" "type modifier output function is useless without a type modifier input " @@ -10784,151 +11351,151 @@ msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° модификатора типа беÑполезна без функции ввода модификатора " "типа" -#: commands/typecmds.c:464 +#: commands/typecmds.c:461 #, c-format msgid "type input function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° типа %s должна возвращать тип %s" -#: commands/typecmds.c:481 +#: commands/typecmds.c:478 #, c-format msgid "type output function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° типа %s должна возвращать тип %s" -#: commands/typecmds.c:490 +#: commands/typecmds.c:487 #, c-format msgid "type receive function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° %s должна возвращать тип %s" -#: commands/typecmds.c:499 +#: commands/typecmds.c:496 #, c-format msgid "type send function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ типа %s должна возвращать тип %s" -#: commands/typecmds.c:564 +#: commands/typecmds.c:561 #, c-format msgid "type input function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° типа %s не должна быть изменчивой" -#: commands/typecmds.c:569 +#: commands/typecmds.c:566 #, c-format msgid "type output function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° типа %s не должна быть изменчивой" -#: commands/typecmds.c:574 +#: commands/typecmds.c:571 #, c-format msgid "type receive function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° %s не должна быть изменчивой" -#: commands/typecmds.c:579 +#: commands/typecmds.c:576 #, c-format msgid "type send function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²ÐºÐ¸ типа %s не должна быть изменчивой" -#: commands/typecmds.c:584 +#: commands/typecmds.c:581 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ð²Ð¾Ð´Ð° модификатора типа %s не должна быть изменчивой" -#: commands/typecmds.c:589 +#: commands/typecmds.c:586 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° модификатора типа %s не должна быть изменчивой" -#: commands/typecmds.c:811 +#: commands/typecmds.c:813 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "\"%s\" - неподходÑщий базовый тип Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð°" -#: commands/typecmds.c:897 +#: commands/typecmds.c:899 #, c-format msgid "multiple default expressions" msgstr "неоднократное определение Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° по умолчанию" -#: commands/typecmds.c:959 commands/typecmds.c:968 +#: commands/typecmds.c:961 commands/typecmds.c:970 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "конфликтующие Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ NULL/NOT NULL" -#: commands/typecmds.c:984 +#: commands/typecmds.c:986 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "" "ограничениÑ-проверки Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð² не могут иметь характериÑтики NO INHERIT" -#: commands/typecmds.c:993 commands/typecmds.c:2512 +#: commands/typecmds.c:995 commands/typecmds.c:2585 #, c-format msgid "unique constraints not possible for domains" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ñти невозможны Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð²" -#: commands/typecmds.c:999 commands/typecmds.c:2518 +#: commands/typecmds.c:1001 commands/typecmds.c:2591 #, c-format msgid "primary key constraints not possible for domains" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа невозможны Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð²" -#: commands/typecmds.c:1005 commands/typecmds.c:2524 +#: commands/typecmds.c:1007 commands/typecmds.c:2597 #, c-format msgid "exclusion constraints not possible for domains" msgstr "ограничениÑ-иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÐ²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñ‹ Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð²" -#: commands/typecmds.c:1011 commands/typecmds.c:2530 +#: commands/typecmds.c:1013 commands/typecmds.c:2603 #, c-format msgid "foreign key constraints not possible for domains" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½Ð¸Ñ… ключей невозможны Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð²" -#: commands/typecmds.c:1020 commands/typecmds.c:2539 +#: commands/typecmds.c:1022 commands/typecmds.c:2612 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "" "возможноÑть Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ‹Ñ… ограничений Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð² не поддерживаетÑÑ" -#: commands/typecmds.c:1284 utils/cache/typcache.c:1648 +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 #, c-format msgid "%s is not an enum" msgstr "\"%s\" не ÑвлÑетÑÑ Ð¿ÐµÑ€ÐµÑ‡Ð¸Ñлением" -#: commands/typecmds.c:1422 +#: commands/typecmds.c:1491 #, c-format msgid "type attribute \"subtype\" is required" msgstr "требуетÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ типа \"subtype\"" -#: commands/typecmds.c:1427 +#: commands/typecmds.c:1496 #, c-format msgid "range subtype cannot be %s" msgstr "%s не может быть подтипом диапазона" -#: commands/typecmds.c:1446 +#: commands/typecmds.c:1515 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "" "указано правило Ñортировки Ð´Ð»Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð°, но подтип не поддерживает " "Ñортировку" -#: commands/typecmds.c:1680 +#: commands/typecmds.c:1748 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "изменение типа аргумента функции %s Ñ \"opaque\" на \"cstring\"" -#: commands/typecmds.c:1731 +#: commands/typecmds.c:1799 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "изменение типа аргумента функции %s Ñ \"opaque\" на %s" -#: commands/typecmds.c:1830 +#: commands/typecmds.c:1898 #, c-format msgid "typmod_in function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ TYPMOD_IN %s должна возвращать тип %s" -#: commands/typecmds.c:1857 +#: commands/typecmds.c:1925 #, c-format msgid "typmod_out function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ TYPMOD_OUT %s должна возвращать тип %s" -#: commands/typecmds.c:1884 +#: commands/typecmds.c:1952 #, c-format msgid "type analyze function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð° типа %s должна возвращать тип %s" -#: commands/typecmds.c:1930 +#: commands/typecmds.c:1998 #, c-format msgid "" "You must specify an operator class for the range type or define a default " @@ -10937,364 +11504,394 @@ msgstr "" "Ð’Ñ‹ должны указать клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° диапазона или определить клаÑÑ " "операторов по умолчанию Ð´Ð»Ñ Ñтого подтипа." -#: commands/typecmds.c:1961 +#: commands/typecmds.c:2029 #, c-format msgid "range canonical function %s must return range type" msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ñ‡ÐµÑкого диапазона %s должна возвращать диапазон" -#: commands/typecmds.c:1967 +#: commands/typecmds.c:2035 #, c-format msgid "range canonical function %s must be immutable" msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ ÐºÐ°Ð½Ð¾Ð½Ð¸Ñ‡ÐµÑкого диапазона %s должна быть поÑтоÑнной " "(IMMUTABLE)" -#: commands/typecmds.c:2003 +#: commands/typecmds.c:2071 #, c-format msgid "range subtype diff function %s must return type %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð¸Ð¹ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð¸Ð¿Ð° диапазона (%s) должна возвращать тип %s" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2078 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ€Ð°Ð·Ð»Ð¸Ñ‡Ð¸Ð¹ Ð´Ð»Ñ Ð¿Ð¾Ð´Ñ‚Ð¸Ð¿Ð° диапазона (%s) должна быть поÑтоÑнной " "(IMMUTABLE)" -#: commands/typecmds.c:2037 +#: commands/typecmds.c:2105 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "значение OID маÑÑива в pg_type не задано в режиме двоичного обновлениÑ" -#: commands/typecmds.c:2340 +#: commands/typecmds.c:2410 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "Ñтолбец \"%s\" таблицы \"%s\" Ñодержит Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NULL" -#: commands/typecmds.c:2453 commands/typecmds.c:2636 +#: commands/typecmds.c:2524 commands/typecmds.c:2709 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° \"%s\" не ÑущеÑтвует" -#: commands/typecmds.c:2457 +#: commands/typecmds.c:2528 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/typecmds.c:2642 +#: commands/typecmds.c:2716 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "" "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° \"%s\" не ÑвлÑетÑÑ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸ÐµÐ¼-проверкой" -#: commands/typecmds.c:2747 +#: commands/typecmds.c:2822 #, c-format msgid "" "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "" "Ñтолбец \"%s\" таблицы \"%s\" Ñодержит значениÑ, нарушающие новое ограничение" -#: commands/typecmds.c:2960 commands/typecmds.c:3247 commands/typecmds.c:3434 +#: commands/typecmds.c:3050 commands/typecmds.c:3256 commands/typecmds.c:3338 +#: commands/typecmds.c:3525 #, c-format msgid "%s is not a domain" msgstr "\"%s\" - Ñто не домен" -#: commands/typecmds.c:2994 +#: commands/typecmds.c:3083 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "ограничение \"%s\" Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° \"%s\" уже ÑущеÑтвует" -#: commands/typecmds.c:3045 +#: commands/typecmds.c:3134 #, c-format msgid "cannot use table references in domain check constraint" msgstr "в ограничении-проверке Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð° Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° таблицы" -#: commands/typecmds.c:3177 commands/typecmds.c:3259 commands/typecmds.c:3551 +#: commands/typecmds.c:3268 commands/typecmds.c:3350 commands/typecmds.c:3642 #, c-format msgid "%s is a table's row type" msgstr "%s - Ñто тип Ñтрок таблицы" -#: commands/typecmds.c:3179 commands/typecmds.c:3261 commands/typecmds.c:3553 +#: commands/typecmds.c:3270 commands/typecmds.c:3352 commands/typecmds.c:3644 #, c-format msgid "Use ALTER TABLE instead." msgstr "Изменить его можно Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ ALTER TABLE." -#: commands/typecmds.c:3186 commands/typecmds.c:3268 commands/typecmds.c:3466 +#: commands/typecmds.c:3277 commands/typecmds.c:3359 commands/typecmds.c:3557 #, c-format msgid "cannot alter array type %s" msgstr "изменить тип маÑÑива \"%s\" нельзÑ" -#: commands/typecmds.c:3188 commands/typecmds.c:3270 commands/typecmds.c:3468 +#: commands/typecmds.c:3279 commands/typecmds.c:3361 commands/typecmds.c:3559 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "Однако можно изменить тип %s, что повлечёт изменение типа маÑÑива." -#: commands/typecmds.c:3536 +#: commands/typecmds.c:3627 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "тип \"%s\" уже ÑущеÑтвует в Ñхеме \"%s\"" -#: commands/user.c:154 +#: commands/user.c:141 #, c-format msgid "SYSID can no longer be specified" msgstr "SYSID уже не нужно указывать" -#: commands/user.c:308 +#: commands/user.c:295 #, c-format msgid "must be superuser to create superusers" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñуперпользователей нужно быть Ñуперпользователем" -#: commands/user.c:315 +#: commands/user.c:302 #, c-format msgid "must be superuser to create replication users" msgstr "Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹-репликаторов нужно быть Ñуперпользователем" -#: commands/user.c:322 commands/user.c:708 +#: commands/user.c:309 commands/user.c:707 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° bypassrls нужно быть Ñуперпользователем" -#: commands/user.c:329 +#: commands/user.c:316 #, c-format msgid "permission denied to create role" msgstr "нет прав Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ€Ð¾Ð»Ð¸" -#: commands/user.c:339 commands/user.c:1183 commands/user.c:1190 -#: utils/adt/acl.c:5246 utils/adt/acl.c:5252 gram.y:14386 gram.y:14421 +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 +#: utils/adt/acl.c:5342 utils/adt/acl.c:5348 gram.y:14893 gram.y:14931 #, c-format msgid "role name \"%s\" is reserved" msgstr "Ð¸Ð¼Ñ Ñ€Ð¾Ð»Ð¸ \"%s\" зарезервировано" -#: commands/user.c:341 commands/user.c:1185 commands/user.c:1192 +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 #, c-format msgid "Role names starting with \"pg_\" are reserved." msgstr "Имена ролей, начинающиеÑÑ Ñ \"pg_\", зарезервированы." -#: commands/user.c:353 commands/user.c:1198 +#: commands/user.c:340 commands/user.c:1210 #, c-format msgid "role \"%s\" already exists" msgstr "роль \"%s\" уже ÑущеÑтвует" -#: commands/user.c:426 +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "пуÑÑ‚Ð°Ñ Ñтрока не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым паролем; пароль ÑбраÑываетÑÑ" + +#: commands/user.c:437 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "значение OID в pg_authid не задано в режиме двоичного обновлениÑ" -#: commands/user.c:694 commands/user.c:903 commands/user.c:1437 -#: commands/user.c:1581 +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 +#: commands/user.c:1593 #, c-format msgid "must be superuser to alter superusers" msgstr "Ð´Ð»Ñ Ð¼Ð¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñуперпользователей нужно быть Ñуперпользователем" -#: commands/user.c:701 +#: commands/user.c:700 #, c-format msgid "must be superuser to alter replication users" msgstr "" "Ð´Ð»Ñ Ð¼Ð¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ пользователей-репликаторов нужно быть Ñуперпользователем" -#: commands/user.c:724 commands/user.c:911 +#: commands/user.c:723 commands/user.c:923 #, c-format msgid "permission denied" msgstr "нет доÑтупа" -#: commands/user.c:941 +#: commands/user.c:953 #, c-format msgid "must be superuser to alter settings globally" msgstr "Ð´Ð»Ñ Ð³Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð¾Ð³Ð¾ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð² нужно быть Ñуперпользователем" -#: commands/user.c:963 +#: commands/user.c:975 #, c-format msgid "permission denied to drop role" msgstr "нет прав Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñ€Ð¾Ð»Ð¸" -#: commands/user.c:987 +#: commands/user.c:999 #, c-format msgid "cannot use special role specifier in DROP ROLE" msgstr "иÑпользовать Ñпециальную роль в DROP ROLE нельзÑ" -#: commands/user.c:997 commands/user.c:1154 commands/variable.c:822 -#: commands/variable.c:894 utils/adt/acl.c:5104 utils/adt/acl.c:5151 -#: utils/adt/acl.c:5179 utils/adt/acl.c:5197 utils/init/miscinit.c:503 +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 +#: commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "роль \"%s\" не ÑущеÑтвует" -#: commands/user.c:1002 +#: commands/user.c:1014 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "роль \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" -#: commands/user.c:1014 commands/user.c:1018 +#: commands/user.c:1026 commands/user.c:1030 #, c-format msgid "current user cannot be dropped" msgstr "пользователь не может удалить Ñам ÑебÑ" -#: commands/user.c:1022 +#: commands/user.c:1034 #, c-format msgid "session user cannot be dropped" msgstr "Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑеанÑа Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ" -#: commands/user.c:1033 +#: commands/user.c:1045 #, c-format msgid "must be superuser to drop superusers" msgstr "Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñуперпользователей нужно быть Ñуперпользователем" -#: commands/user.c:1049 +#: commands/user.c:1061 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "роль \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ, так как еÑть завиÑÑщие от неё объекты" -#: commands/user.c:1170 +#: commands/user.c:1182 #, c-format msgid "session user cannot be renamed" msgstr "Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑеанÑа Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ñ‚ÑŒ" -#: commands/user.c:1174 +#: commands/user.c:1186 #, c-format msgid "current user cannot be renamed" msgstr "пользователь не может переименовать Ñам ÑебÑ" -#: commands/user.c:1208 +#: commands/user.c:1220 #, c-format msgid "must be superuser to rename superusers" msgstr "Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ñуперпользователей нужно быть Ñуперпользователем" -#: commands/user.c:1215 +#: commands/user.c:1227 #, c-format msgid "permission denied to rename role" msgstr "нет прав на переименование роли" -#: commands/user.c:1236 +#: commands/user.c:1248 #, c-format msgid "MD5 password cleared because of role rename" msgstr "в результате Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€Ð¾Ð»Ð¸ очищен MD5-хеш паролÑ" -#: commands/user.c:1296 +#: commands/user.c:1308 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "в GRANT/REVOKE ROLE Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ‚ÑŒ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñтолбцов" -#: commands/user.c:1334 +#: commands/user.c:1346 #, c-format msgid "permission denied to drop objects" msgstr "нет прав на удаление объектов" -#: commands/user.c:1361 commands/user.c:1370 +#: commands/user.c:1373 commands/user.c:1382 #, c-format msgid "permission denied to reassign objects" msgstr "нет прав Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð²" -#: commands/user.c:1445 commands/user.c:1589 +#: commands/user.c:1457 commands/user.c:1601 #, c-format msgid "must have admin option on role \"%s\"" msgstr "требуетÑÑ Ð¿Ñ€Ð°Ð²Ð¾ admin Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸ \"%s\"" -#: commands/user.c:1462 +#: commands/user.c:1474 #, c-format msgid "must be superuser to set grantor" msgstr "Ð´Ð»Ñ Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð° ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ нужно быть Ñуперпользователем" -#: commands/user.c:1487 +#: commands/user.c:1499 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "роль \"%s\" включена в роль \"%s\"" -#: commands/user.c:1502 +#: commands/user.c:1514 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "роль \"%s\" уже включена в роль \"%s\"" -#: commands/user.c:1611 +#: commands/user.c:1623 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "роль \"%s\" не включена в роль \"%s\"" -#: commands/vacuum.c:186 +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "еÑли задаётÑÑ ÑпиÑок Ñтолбцов, необходимо указать ANALYZE" + +#: commands/vacuum.c:203 #, c-format msgid "%s cannot be executed from VACUUM or ANALYZE" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ в ходе VACUUM или ANALYZE" -#: commands/vacuum.c:196 +#: commands/vacuum.c:213 #, c-format msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" msgstr "Параметр VACUUM DISABLE_PAGE_SKIPPING Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ FULL" -#: commands/vacuum.c:565 +#: commands/vacuum.c:657 #, c-format msgid "oldest xmin is far in the past" msgstr "Ñамый Ñтарый xmin далеко в прошлом" -#: commands/vacuum.c:566 +#: commands/vacuum.c:658 #, c-format -msgid "Close open transactions soon to avoid wraparound problems." +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or " +"drop stale replication slots." msgstr "" -"Скорее закройте открытые транзакции, чтобы избежать проблемы наложениÑ." +"Завершите открытые транзакции как можно быÑтрее во избежание проблемы " +"зацикливаниÑ.\n" +"Возможно, вам также придётÑÑ Ð·Ð°Ñ„Ð¸ÐºÑировать или откатить Ñтарые " +"подготовленные транзакции и удалить неиÑпользуемые Ñлоты репликации." -#: commands/vacuum.c:605 +#: commands/vacuum.c:698 #, c-format msgid "oldest multixact is far in the past" msgstr "Ñамый Ñтарый multixact далеко в прошлом" -#: commands/vacuum.c:606 +#: commands/vacuum.c:699 #, c-format msgid "" "Close open transactions with multixacts soon to avoid wraparound problems." msgstr "" "Скорее закройте открытые транзакции в мультитранзакциÑÑ…, чтобы избежать " -"проблемы наложениÑ." +"проблемы зацикливаниÑ." -#: commands/vacuum.c:1176 +#: commands/vacuum.c:1245 #, c-format msgid "some databases have not been vacuumed in over 2 billion transactions" msgstr "" "еÑть базы данных, которые не очищалиÑÑŒ на протÑжении более чем 2 миллиардов " "транзакций" -#: commands/vacuum.c:1177 +#: commands/vacuum.c:1246 #, c-format msgid "You might have already suffered transaction-wraparound data loss." -msgstr "Возможно, вы уже потерÑли данные в результате Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ID транзакций." +msgstr "" +"Возможно, вы уже потерÑли данные в результате Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ ID транзакций." -#: commands/vacuum.c:1306 +#: commands/vacuum.c:1418 #, c-format msgid "skipping vacuum of \"%s\" --- lock not available" msgstr "очиÑтка \"%s\" пропуÑкаетÑÑ --- блокировка недоÑтупна" -#: commands/vacuum.c:1332 +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "очиÑтка \"%s\" пропуÑкаетÑÑ --- Ñто отношение более не ÑущеÑтвует" + +#: commands/vacuum.c:1447 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "" "\"%s\" пропуÑкаетÑÑ --- только Ñуперпользователь может очиÑтить Ñту таблицу" -#: commands/vacuum.c:1336 +#: commands/vacuum.c:1451 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "" "пропуÑкаетÑÑ \"%s\" --- только Ñуперпользователь или владелец БД может " "очиÑтить Ñту таблицу" -#: commands/vacuum.c:1340 +#: commands/vacuum.c:1455 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "" "\"%s\" пропуÑкаетÑÑ --- только владелец базы данных или Ñтой таблицы может " "очиÑтить её" -#: commands/vacuum.c:1359 +#: commands/vacuum.c:1472 #, c-format msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" msgstr "" "\"%s\" пропуÑкаетÑÑ --- очищать не таблицы или Ñпециальные ÑиÑтемные таблицы " "нельзÑ" -#: commands/vacuumlazy.c:377 +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "" +"автоматичеÑÐºÐ°Ñ Ð°Ð³Ñ€ÐµÑÑÐ¸Ð²Ð½Ð°Ñ Ð¾Ñ‡Ð¸Ñтка таблицы \"%s.%s.%s\": Ñканирований " +"индекÑа: %d\n" + +#: commands/vacuumlazy.c:380 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" msgstr "" "автоматичеÑÐºÐ°Ñ Ð¾Ñ‡Ð¸Ñтка таблицы \"%s.%s.%s\": Ñканирований индекÑа: %d\n" -#: commands/vacuumlazy.c:382 +#: commands/vacuumlazy.c:386 #, c-format msgid "" "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" @@ -11302,7 +11899,7 @@ msgstr "" "Ñтраниц удалено: %u, оÑталоÑÑŒ: %u, пропущено закреплённых: %u, пропущено " "замороженных: %u\n" -#: commands/vacuumlazy.c:388 +#: commands/vacuumlazy.c:392 #, c-format msgid "" "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, " @@ -11311,46 +11908,51 @@ msgstr "" "верÑий Ñтрок: удалено: %.0f, оÑталоÑÑŒ: %.0f, «мёртвых», но ещё не подлежащих " "удалению: %.0f, Ñтарейший xmin: %u\n" -#: commands/vacuumlazy.c:394 +#: commands/vacuumlazy.c:398 #, c-format msgid "buffer usage: %d hits, %d misses, %d dirtied\n" msgstr "" "иÑпользование буфера: попаданий: %d, промахов: %d, «грÑзных» запиÑей: %d\n" -#: commands/vacuumlazy.c:398 +#: commands/vacuumlazy.c:402 #, c-format msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" msgstr "" "ÑреднÑÑ ÑкороÑть чтениÑ: %.3f МБ/Ñ, ÑреднÑÑ ÑкороÑть запиÑи: %.3f МБ/Ñ\n" -#: commands/vacuumlazy.c:400 +#: commands/vacuumlazy.c:404 #, c-format msgid "system usage: %s" msgstr "нагрузка ÑиÑтемы: %s" -#: commands/vacuumlazy.c:860 +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "агреÑÑÐ¸Ð²Ð½Ð°Ñ Ð¾Ñ‡Ð¸Ñтка \"%s.%s\"" + +#: commands/vacuumlazy.c:881 #, c-format msgid "relation \"%s\" page %u is uninitialized --- fixing" msgstr "" "в отношении \"%s\" не инициализирована Ñтраница %u --- ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ Ð¸ÑправлÑетÑÑ" -#: commands/vacuumlazy.c:1330 +#: commands/vacuumlazy.c:1417 #, c-format msgid "\"%s\": removed %.0f row versions in %u pages" msgstr "\"%s\": удалено верÑий Ñтрок: %.0f, обработано Ñтраниц: %u" -#: commands/vacuumlazy.c:1340 +#: commands/vacuumlazy.c:1427 #, c-format msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" msgstr "" "Ð’ данный момент Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐ´Ð°Ð»Ð¸Ñ‚ÑŒ \"мёртвых\" Ñтрок: %.0f, Ñтарейший xmin: %u\n" -#: commands/vacuumlazy.c:1342 +#: commands/vacuumlazy.c:1429 #, c-format msgid "There were %.0f unused item pointers.\n" msgstr "Ðайдено неиÑпользованных указателей: %.0f.\n" -#: commands/vacuumlazy.c:1344 +#: commands/vacuumlazy.c:1431 #, c-format msgid "Skipped %u page due to buffer pins, " msgid_plural "Skipped %u pages due to buffer pins, " @@ -11358,7 +11960,7 @@ msgstr[0] "Пропущено Ñтраниц, закреплённых в буф msgstr[1] "Пропущено Ñтраниц, закреплённых в буфере: %u," msgstr[2] "Пропущено Ñтраниц, закреплённых в буфере: %u," -#: commands/vacuumlazy.c:1348 +#: commands/vacuumlazy.c:1435 #, c-format msgid "%u frozen page.\n" msgid_plural "%u frozen pages.\n" @@ -11366,7 +11968,7 @@ msgstr[0] "замороженных Ñтраниц: %u.\n" msgstr[1] "замороженных Ñтраниц: %u.\n" msgstr[2] "замороженных Ñтраниц: %u.\n" -#: commands/vacuumlazy.c:1352 +#: commands/vacuumlazy.c:1439 #, c-format msgid "%u page is entirely empty.\n" msgid_plural "%u pages are entirely empty.\n" @@ -11374,7 +11976,12 @@ msgstr[0] "ПолноÑтью пуÑтых Ñтраниц: %u.\n" msgstr[1] "ПолноÑтью пуÑтых Ñтраниц: %u.\n" msgstr[2] "ПолноÑтью пуÑтых Ñтраниц: %u.\n" -#: commands/vacuumlazy.c:1360 +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 #, c-format msgid "" "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u " @@ -11383,22 +11990,22 @@ msgstr "" "\"%s\": найдено удалÑемых верÑий Ñтрок: %.0f, неудалÑемых - %.0f, обработано " "Ñтраниц: %u, вÑего Ñтраниц: %u" -#: commands/vacuumlazy.c:1429 +#: commands/vacuumlazy.c:1515 #, c-format msgid "\"%s\": removed %d row versions in %d pages" msgstr "\"%s\": удалено верÑий Ñтрок: %d, обработано Ñтраниц: %d" -#: commands/vacuumlazy.c:1618 +#: commands/vacuumlazy.c:1704 #, c-format msgid "scanned index \"%s\" to remove %d row versions" msgstr "проÑканирован Ð¸Ð½Ð´ÐµÐºÑ \"%s\", удалено верÑий Ñтрок: %d" -#: commands/vacuumlazy.c:1664 +#: commands/vacuumlazy.c:1756 #, c-format msgid "index \"%s\" now contains %.0f row versions in %u pages" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" теперь Ñодержит верÑий Ñтрок: %.0f, в Ñтраницах: %u" -#: commands/vacuumlazy.c:1668 +#: commands/vacuumlazy.c:1760 #, c-format msgid "" "%.0f index row versions were removed.\n" @@ -11409,22 +12016,22 @@ msgstr "" "Удалено индекÑных Ñтраниц: %u, пригодно Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð¾Ð³Ð¾ иÑпользованиÑ: %u.\n" "%s." -#: commands/vacuumlazy.c:1763 +#: commands/vacuumlazy.c:1855 #, c-format msgid "\"%s\": stopping truncate due to conflicting lock request" msgstr "\"%s\": оÑтановка уÑÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за конфликтующего запроÑа блокировки" -#: commands/vacuumlazy.c:1828 +#: commands/vacuumlazy.c:1920 #, c-format msgid "\"%s\": truncated %u to %u pages" msgstr "\"%s\": уÑечение (было Ñтраниц: %u, Ñтало: %u)" -#: commands/vacuumlazy.c:1893 +#: commands/vacuumlazy.c:1985 #, c-format msgid "\"%s\": suspending truncate due to conflicting lock request" msgstr "\"%s\": приоÑтановка уÑÐµÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за конфликтующего запроÑа блокировки" -#: commands/variable.c:165 utils/misc/guc.c:10001 utils/misc/guc.c:10063 +#: commands/variable.c:165 utils/misc/guc.c:10311 utils/misc/guc.c:10373 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "нераÑпознанное ключевое Ñлово: \"%s\"." @@ -11491,7 +12098,7 @@ msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "" "команда SET TRANSACTION ISOLATION LEVEL не должна вызыватьÑÑ Ð² подтранзакции" -#: commands/variable.c:571 storage/lmgr/predicate.c:1576 +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "иÑпользовать Ñериализуемый режим в горÑчем резерве нельзÑ" @@ -11526,8 +12133,8 @@ msgstr "Изменить клиентÑкую кодировку ÑÐµÐ¹Ñ‡Ð°Ñ Ð½ #: commands/variable.c:776 #, c-format -msgid "cannot change client_encoding in a parallel worker" -msgstr "изменить клиентÑкую кодировку в параллельном иÑполнителе нельзÑ" +msgid "cannot change client_encoding during a parallel operation" +msgstr "изменить клиентÑкую кодировку во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ð¾Ð¹ операции нельзÑ" #: commands/variable.c:912 #, c-format @@ -11544,120 +12151,116 @@ msgstr "неверное значение Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"check_opti msgid "Valid values are \"local\" and \"cascaded\"." msgstr "ДопуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"local\" и \"cascaded\"." -#: commands/view.c:101 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "" "не удалоÑÑŒ определить правило Ñортировки Ð´Ð»Ñ Ñтолбца предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\"" -#: commands/view.c:115 -#, c-format -msgid "view must have at least one column" -msgstr "в предÑтавлении должен быть минимум один Ñтолбец" - -#: commands/view.c:281 commands/view.c:293 +#: commands/view.c:280 commands/view.c:292 #, c-format msgid "cannot drop columns from view" msgstr "удалÑть Ñтолбцы из предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" -#: commands/view.c:298 +#: commands/view.c:297 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "изменить Ð¸Ð¼Ñ Ñтолбца \"%s\" на \"%s\" в предÑтавлении нельзÑ" -#: commands/view.c:306 +#: commands/view.c:305 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "изменить тип Ñтолбца предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" Ñ %s на %s нельзÑ" -#: commands/view.c:451 +#: commands/view.c:450 #, c-format msgid "views must not contain SELECT INTO" msgstr "предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ должны Ñодержать SELECT INTO" -#: commands/view.c:463 +#: commands/view.c:462 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ должны Ñодержать операторы, изменÑющие данные в WITH" -#: commands/view.c:533 +#: commands/view.c:532 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "в CREATE VIEW указано больше имён Ñтолбцов, чем Ñамих Ñтолбцов" -#: commands/view.c:541 +#: commands/view.c:540 #, c-format msgid "views cannot be unlogged because they do not have storage" msgstr "" "предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ могут быть нежурналируемыми, так как они нигде не хранÑÑ‚ÑÑ" -#: commands/view.c:555 +#: commands/view.c:554 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "предÑтавление \"%s\" будет Ñоздано как временное" -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:78 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "курÑор \"%s\" не отноÑитÑÑ Ðº запроÑу SELECT" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:84 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "курÑор \"%s\" ÑохранилÑÑ Ñ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰ÐµÐ¹ транзакции" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:116 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "в курÑоре \"%s\" неÑколько ÑÑылок FOR UPDATE/SHARE на таблицу \"%s\"" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:125 #, c-format msgid "" "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "в курÑоре \"%s\" нет ÑÑылки FOR UPDATE/SHARE на таблицу \"%s\"" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:135 executor/execCurrent.c:180 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "курÑор \"%s\" не указывает на Ñтроку" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:167 executor/execCurrent.c:226 +#: executor/execCurrent.c:238 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "" "Ð´Ð»Ñ ÐºÑƒÑ€Ñора \"%s\" не выполнÑетÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»Ñемое Ñканирование таблицы \"%s\"" -#: executor/execCurrent.c:231 executor/execExprInterp.c:1876 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 #, c-format msgid "" "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "" -"тип параметра %d (%s) не ÑоответÑтвует тому, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼ подготавливалÑÑ Ð¿Ð»Ð°Ð½ " -"(%s)" +"тип параметра %d (%s) не ÑоответÑтвует тому, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼ подготавливалÑÑ Ð¿Ð»Ð°Ð½ (" +"%s)" -#: executor/execCurrent.c:243 executor/execExprInterp.c:1888 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 #, c-format msgid "no value found for parameter %d" msgstr "не найдено значение параметра %d" -#: executor/execExpr.c:774 parser/parse_agg.c:764 +#: executor/execExpr.c:856 parser/parse_agg.c:794 #, c-format msgid "window function calls cannot be nested" msgstr "вложенные вызовы оконных функций недопуÑтимы" -#: executor/execExpr.c:1218 +#: executor/execExpr.c:1314 #, c-format msgid "target type is not an array" msgstr "целевой тип не ÑвлÑетÑÑ Ð¼Ð°ÑÑивом" -#: executor/execExpr.c:1541 +#: executor/execExpr.c:1647 #, c-format msgid "ROW() column has type %s instead of type %s" msgstr "Ñтолбец ROW() имеет тип %s, а должен - %s" -#: executor/execExpr.c:2061 executor/execSRF.c:668 parser/parse_func.c:116 -#: parser/parse_func.c:543 parser/parse_func.c:902 +#: executor/execExpr.c:2182 executor/execSRF.c:697 parser/parse_func.c:126 +#: parser/parse_func.c:640 parser/parse_func.c:1014 #, c-format msgid "cannot pass more than %d argument to a function" msgid_plural "cannot pass more than %d arguments to a function" @@ -11665,41 +12268,42 @@ msgstr[0] "функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргу msgstr[1] "функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргументов" msgstr[2] "функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‚ÑŒ больше %d аргументов" -#: executor/execExpr.c:2336 executor/execExpr.c:2342 -#: executor/execExprInterp.c:2187 utils/adt/array_userfuncs.c:484 -#: utils/adt/arrayfuncs.c:260 utils/adt/arrayfuncs.c:558 -#: utils/adt/arrayfuncs.c:1288 utils/adt/arrayfuncs.c:3361 -#: utils/adt/arrayfuncs.c:5241 utils/adt/arrayfuncs.c:5758 +#: executor/execExpr.c:2480 executor/execExpr.c:2486 +#: executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 +#: utils/adt/arrayfuncs.c:5820 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "чиÑло размерноÑтей маÑÑива (%d) превышает предел (%d)" -#: executor/execExprInterp.c:1548 +#: executor/execExprInterp.c:1879 #, c-format msgid "attribute %d of type %s has been dropped" msgstr "атрибут %d типа %s был удалён" -#: executor/execExprInterp.c:1554 +#: executor/execExprInterp.c:1885 #, c-format msgid "attribute %d of type %s has wrong type" msgstr "атрибут %d типа %s имеет неправильный тип" -#: executor/execExprInterp.c:1556 executor/execExprInterp.c:2473 +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 +#: executor/execExprInterp.c:2933 #, c-format msgid "Table has type %s, but query expects %s." msgstr "Ð’ таблице задан тип %s, а в запроÑе ожидаетÑÑ %s." -#: executor/execExprInterp.c:1966 +#: executor/execExprInterp.c:2374 #, c-format msgid "WHERE CURRENT OF is not supported for this table type" msgstr "WHERE CURRENT OF Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ† такого типа не поддерживаетÑÑ" -#: executor/execExprInterp.c:2165 +#: executor/execExprInterp.c:2591 #, c-format msgid "cannot merge incompatible arrays" msgstr "не удалоÑÑŒ объединить неÑовмеÑтимые маÑÑивы" -#: executor/execExprInterp.c:2166 +#: executor/execExprInterp.c:2592 #, c-format msgid "" "Array with element type %s cannot be included in ARRAY construct with " @@ -11708,7 +12312,7 @@ msgstr "" "МаÑÑив Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ Ñлементов %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ в конÑтрукцию ARRAY Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ " "Ñлементов %s." -#: executor/execExprInterp.c:2207 executor/execExprInterp.c:2237 +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 #, c-format msgid "" "multidimensional arrays must have array expressions with matching dimensions" @@ -11716,35 +12320,35 @@ msgstr "" "Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ñ… маÑÑивов должны задаватьÑÑ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÑоответÑтвующими " "размерноÑÑ‚Ñми" -#: executor/execExprInterp.c:2472 +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 #, c-format msgid "attribute %d has wrong type" msgstr "атрибут %d имеет неверный тип" -#: executor/execExprInterp.c:2581 +#: executor/execExprInterp.c:3042 #, c-format msgid "array subscript in assignment must not be null" msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ñлемента маÑÑива в приÑваивании не может быть NULL" -#: executor/execExprInterp.c:3004 utils/adt/domains.c:148 +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 #, c-format msgid "domain %s does not allow null values" msgstr "домен %s не допуÑкает Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ null" -#: executor/execExprInterp.c:3019 utils/adt/domains.c:183 +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 #, c-format msgid "value for domain %s violates check constraint \"%s\"" msgstr "значение домена %s нарушает ограничение-проверку \"%s\"" -#: executor/execExprInterp.c:3386 executor/execExprInterp.c:3403 -#: executor/execExprInterp.c:3505 executor/nodeModifyTable.c:96 -#: executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:123 -#: executor/nodeModifyTable.c:131 +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 +#: executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 +#: executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 +#: executor/nodeModifyTable.c:142 #, c-format msgid "table row type and query-specified row type do not match" msgstr "тип Ñтроки таблицы отличаетÑÑ Ð¾Ñ‚ типа Ñтроки-результата запроÑа" -#: executor/execExprInterp.c:3387 +#: executor/execExprInterp.c:3862 #, c-format msgid "Table row contains %d attribute, but query expects %d." msgid_plural "Table row contains %d attributes, but query expects %d." @@ -11752,14 +12356,14 @@ msgstr[0] "Строка таблицы Ñодержит %d атрибут, а в msgstr[1] "Строка таблицы Ñодержит %d атрибута, а в запроÑе ожидаетÑÑ %d." msgstr[2] "Строка таблицы Ñодержит %d атрибутов, а в запроÑе ожидаетÑÑ %d." -#: executor/execExprInterp.c:3404 executor/nodeModifyTable.c:107 +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 #, c-format msgid "Table has type %s at ordinal position %d, but query expects %s." msgstr "" "Ð’ таблице определён тип %s (номер Ñтолбца: %d), а в запроÑе предполагаетÑÑ " "%s." -#: executor/execExprInterp.c:3506 executor/execSRF.c:921 +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 #, c-format msgid "Physical storage mismatch on dropped attribute at ordinal position %d." msgstr "" @@ -11805,22 +12409,22 @@ msgstr "Ключ %s конфликтует Ñ ÑущеÑтвующим ключ msgid "Key conflicts with existing key." msgstr "Ключ конфликтует Ñ ÑƒÐ¶Ðµ ÑущеÑтвующим." -#: executor/execMain.c:1074 +#: executor/execMain.c:1116 #, c-format msgid "cannot change sequence \"%s\"" msgstr "поÑледовательноÑть \"%s\" изменить нельзÑ" -#: executor/execMain.c:1080 +#: executor/execMain.c:1122 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "TOAST-отношение \"%s\" изменить нельзÑ" -#: executor/execMain.c:1098 rewrite/rewriteHandler.c:2661 +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2879 #, c-format msgid "cannot insert into view \"%s\"" msgstr "вÑтавить данные в предÑтавление \"%s\" нельзÑ" -#: executor/execMain.c:1100 rewrite/rewriteHandler.c:2664 +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2882 #, c-format msgid "" "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or " @@ -11829,12 +12433,12 @@ msgstr "" "Чтобы предÑтавление допуÑкало добавление данных, уÑтановите триггер INSTEAD " "OF INSERT или безуÑловное правило ON INSERT DO INSTEAD." -#: executor/execMain.c:1106 rewrite/rewriteHandler.c:2669 +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2887 #, c-format msgid "cannot update view \"%s\"" msgstr "изменить данные в предÑтавлении \"%s\" нельзÑ" -#: executor/execMain.c:1108 rewrite/rewriteHandler.c:2672 +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2890 #, c-format msgid "" "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an " @@ -11843,12 +12447,12 @@ msgstr "" "Чтобы предÑтавление допуÑкало изменение данных, уÑтановите триггер INSTEAD " "OF UPDATE или безуÑловное правило ON UPDATE DO INSTEAD." -#: executor/execMain.c:1114 rewrite/rewriteHandler.c:2677 +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2895 #, c-format msgid "cannot delete from view \"%s\"" msgstr "удалить данные из предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: executor/execMain.c:1116 rewrite/rewriteHandler.c:2680 +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2898 #, c-format msgid "" "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an " @@ -11857,117 +12461,117 @@ msgstr "" "Чтобы предÑтавление допуÑкало удаление данных, уÑтановите триггер INSTEAD OF " "DELETE или безуÑловное правило ON DELETE DO INSTEAD." -#: executor/execMain.c:1127 +#: executor/execMain.c:1169 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "изменить материализованное предÑтавление \"%s\" нельзÑ" -#: executor/execMain.c:1139 +#: executor/execMain.c:1181 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "вÑтавлÑть данные в Ñтороннюю таблицу \"%s\" нельзÑ" -#: executor/execMain.c:1145 +#: executor/execMain.c:1187 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" не допуÑкает добавлениÑ" -#: executor/execMain.c:1152 +#: executor/execMain.c:1194 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "изменÑть данные в Ñторонней таблице \"%s\"" -#: executor/execMain.c:1158 +#: executor/execMain.c:1200 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" не допуÑкает изменениÑ" -#: executor/execMain.c:1165 +#: executor/execMain.c:1207 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "удалÑть данные из Ñторонней таблицы \"%s\" нельзÑ" -#: executor/execMain.c:1171 +#: executor/execMain.c:1213 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s\" не допуÑкает удалениÑ" -#: executor/execMain.c:1182 +#: executor/execMain.c:1224 #, c-format msgid "cannot change relation \"%s\"" msgstr "отношение \"%s\" изменить нельзÑ" -#: executor/execMain.c:1209 +#: executor/execMain.c:1251 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "блокировать Ñтроки в поÑледовательноÑти \"%s\" нельзÑ" -#: executor/execMain.c:1216 +#: executor/execMain.c:1258 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "блокировать Ñтроки в TOAST-отношении \"%s\" нельзÑ" -#: executor/execMain.c:1223 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "блокировать Ñтроки в предÑтавлении \"%s\" нельзÑ" -#: executor/execMain.c:1231 +#: executor/execMain.c:1273 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "блокировать Ñтроки в материализованном предÑтавлении \"%s\" нельзÑ" -#: executor/execMain.c:1240 executor/execMain.c:2796 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1282 executor/execMain.c:2974 +#: executor/nodeLockRows.c:136 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "блокировать Ñтроки в Ñторонней таблице \"%s\" нельзÑ" -#: executor/execMain.c:1246 +#: executor/execMain.c:1288 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "блокировать Ñтроки в отношении \"%s\" нельзÑ" -#: executor/execMain.c:1880 +#: executor/execMain.c:1959 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "нулевое значение в Ñтолбце \"%s\" нарушает ограничение NOT NULL" +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "Ð½Ð¾Ð²Ð°Ñ Ñтрока в отношении \"%s\" нарушает ограничение Ñекции" -#: executor/execMain.c:1882 executor/execMain.c:1916 executor/execMain.c:1946 -#: executor/execMain.c:2031 +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 +#: executor/execMain.c:2195 #, c-format msgid "Failing row contains %s." msgstr "ÐžÑˆÐ¸Ð±Ð¾Ñ‡Ð½Ð°Ñ Ñтрока Ñодержит %s." -#: executor/execMain.c:1914 +#: executor/execMain.c:2039 #, c-format -msgid "new row for relation \"%s\" violates check constraint \"%s\"" -msgstr "Ð½Ð¾Ð²Ð°Ñ Ñтрока в отношении \"%s\" нарушает ограничение-проверку \"%s\"" +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "нулевое значение в Ñтолбце \"%s\" нарушает ограничение NOT NULL" -#: executor/execMain.c:1944 +#: executor/execMain.c:2086 #, c-format -msgid "new row for relation \"%s\" violates partition constraint" -msgstr "Ð½Ð¾Ð²Ð°Ñ Ñтрока в отношении \"%s\" нарушает ограничение Ñекции" +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "Ð½Ð¾Ð²Ð°Ñ Ñтрока в отношении \"%s\" нарушает ограничение-проверку \"%s\"" -#: executor/execMain.c:2029 +#: executor/execMain.c:2193 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает ограничение-проверку Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\"" -#: executor/execMain.c:2039 +#: executor/execMain.c:2203 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "" -"Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает политику защиты на уровне Ñтрок \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s" -"\"" +"Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает политику защиты на уровне Ñтрок \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"" +"%s\"" -#: executor/execMain.c:2044 +#: executor/execMain.c:2208 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "" "Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает политику защиты на уровне Ñтрок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"" -#: executor/execMain.c:2051 +#: executor/execMain.c:2215 #, c-format msgid "" "new row violates row-level security policy \"%s\" (USING expression) for " @@ -11976,56 +12580,73 @@ msgstr "" "Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает политику защиты на уровне Ñтрок \"%s\" (выражение " "USING) Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"" -#: executor/execMain.c:2056 +#: executor/execMain.c:2220 #, c-format msgid "" -"new row violates row-level security policy (USING expression) for table \"%s" -"\"" +"new row violates row-level security policy (USING expression) for table \"" +"%s\"" msgstr "" "Ð½Ð¾Ð²Ð°Ñ Ñтрока нарушает политику защиты на уровне Ñтрок (выражение USING) Ð´Ð»Ñ " "таблицы \"%s\"" -#: executor/execMain.c:3257 +#: executor/execPartition.c:346 #, c-format msgid "no partition of relation \"%s\" found for row" msgstr "Ð´Ð»Ñ Ñтроки не найдена ÑÐµÐºÑ†Ð¸Ñ Ð² отношении \"%s\"" -#: executor/execMain.c:3259 +#: executor/execPartition.c:348 #, c-format msgid "Partition key of the failing row contains %s." -msgstr "Ключ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщей Ñтроки Ñодержит %s." +msgstr "Ключ ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщей Ñтроки Ñодержит %s." + +#: executor/execReplication.c:197 executor/execReplication.c:356 +#, c-format +msgid "" +"tuple to be locked was already moved to another partition due to concurrent " +"update, retrying" +msgstr "" +"кортеж, подлежащий блокировке, был перемещён в другую Ñекцию в результате " +"параллельного изменениÑ; Ñледует Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ°" -#: executor/execReplication.c:195 executor/execReplication.c:342 +#: executor/execReplication.c:201 executor/execReplication.c:360 #, c-format msgid "concurrent update, retrying" msgstr "параллельное изменение; Ñледует Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ°" -#: executor/execReplication.c:544 +#: executor/execReplication.c:257 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 +#: utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "не удалоÑÑŒ найти оператор равенÑтва Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" + +#: executor/execReplication.c:573 #, c-format msgid "" -"cannot update table \"%s\" because it does not have replica identity and " +"cannot update table \"%s\" because it does not have a replica identity and " "publishes updates" msgstr "" "изменение в таблице \"%s\" невозможно, так как в ней отÑутÑтвует " "идентификатор реплики, но она публикует изменениÑ" -#: executor/execReplication.c:546 +#: executor/execReplication.c:575 #, c-format msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." msgstr "" "Чтобы Ñта таблица поддерживала изменение, уÑтановите REPLICA IDENTITY, " "выполнив ALTER TABLE." -#: executor/execReplication.c:550 +#: executor/execReplication.c:579 #, c-format msgid "" -"cannot delete from table \"%s\" because it does not have replica identity " +"cannot delete from table \"%s\" because it does not have a replica identity " "and publishes deletes" msgstr "" "удаление из таблицы \"%s\" невозможно, так как в ней отÑутÑтвует " "идентификатор реплики, но она публикует удалениÑ" -#: executor/execReplication.c:552 +#: executor/execReplication.c:581 #, c-format msgid "" "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." @@ -12033,22 +12654,27 @@ msgstr "" "Чтобы Ñта таблица поддерживала удаление, уÑтановите REPLICA IDENTITY, " "выполнив ALTER TABLE." -#: executor/execSRF.c:307 +#: executor/execReplication.c:600 +#, c-format +msgid "logical replication target relation \"%s.%s\" is not a table" +msgstr "целевое отношение логичеÑкой репликации \"%s.%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹" + +#: executor/execSRF.c:308 #, c-format msgid "rows returned by function are not all of the same row type" msgstr "Ñтроки, возвращённые функцией, имеют разные типы" -#: executor/execSRF.c:355 executor/execSRF.c:619 +#: executor/execSRF.c:356 executor/execSRF.c:647 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "нарушение протокола табличной функции в режиме материализации" -#: executor/execSRF.c:362 executor/execSRF.c:637 +#: executor/execSRF.c:363 executor/execSRF.c:665 #, c-format msgid "unrecognized table-function returnMode: %d" msgstr "нераÑпознанный режим возврата табличной функции: %d" -#: executor/execSRF.c:839 +#: executor/execSRF.c:871 #, c-format msgid "" "function returning setof record called in context that cannot accept type " @@ -12057,12 +12683,12 @@ msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ SET OF, вызвана в контекÑте, не допуÑкающем " "Ñтот тип" -#: executor/execSRF.c:894 executor/execSRF.c:910 executor/execSRF.c:920 +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 #, c-format msgid "function return row and query-specified return row do not match" msgstr "тип результат функции отличаетÑÑ Ð¾Ñ‚ типа Ñтроки-результата запроÑа" -#: executor/execSRF.c:895 +#: executor/execSRF.c:927 #, c-format msgid "Returned row contains %d attribute, but query expects %d." msgid_plural "Returned row contains %d attributes, but query expects %d." @@ -12072,17 +12698,17 @@ msgstr[1] "" msgstr[2] "" "Ð’Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ñ‘Ð½Ð½Ð°Ñ Ñтрока Ñодержит %d атрибутов, но Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ð»Ð°Ð³Ð°ÐµÑ‚ %d." -#: executor/execSRF.c:911 +#: executor/execSRF.c:943 #, c-format msgid "Returned type %s at ordinal position %d, but query expects %s." msgstr "Возвращён тип %s (номер Ñтолбца: %d), а в запроÑе предполагаетÑÑ %s." -#: executor/execUtils.c:636 +#: executor/execUtils.c:687 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "материализованное предÑтавление \"%s\" не было наполнено" -#: executor/execUtils.c:638 +#: executor/execUtils.c:689 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "Примените команду REFRESH MATERIALIZED VIEW." @@ -12092,24 +12718,24 @@ msgstr "Примените команду REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "не удалоÑÑŒ определить фактичеÑкий тип аргумента, объÑвленного как %s" -#: executor/functions.c:519 +#: executor/functions.c:521 #, c-format msgid "cannot COPY to/from client in a SQL function" msgstr "в функции SQL Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ COPY Ñ ÑƒÑ‡Ð°Ñтием клиента" #. translator: %s is a SQL statement name -#: executor/functions.c:525 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в SQL-функции" #. translator: %s is a SQL statement name -#: executor/functions.c:533 executor/spi.c:1282 executor/spi.c:2066 +#: executor/functions.c:535 executor/spi.c:1439 executor/spi.c:2229 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в не изменчивой (volatile) функции" -#: executor/functions.c:653 +#: executor/functions.c:656 #, c-format msgid "" "could not determine actual result type for function declared to return type " @@ -12118,24 +12744,31 @@ msgstr "" "не удалоÑÑŒ определить фактичеÑкий тип результата Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ (в объÑвлении " "указан тип %s)" -#: executor/functions.c:1412 +#: executor/functions.c:1418 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\", оператор %d" -#: executor/functions.c:1438 +#: executor/functions.c:1444 #, c-format msgid "SQL function \"%s\" during startup" msgstr "SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" (при Ñтарте)" -#: executor/functions.c:1596 executor/functions.c:1633 -#: executor/functions.c:1645 executor/functions.c:1758 -#: executor/functions.c:1791 executor/functions.c:1821 +#: executor/functions.c:1537 +#, c-format +msgid "" +"calling procedures with output arguments is not supported in SQL functions" +msgstr "" +"вызов процедур Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ð¼Ð¸ аргументами в функциÑÑ… SQL не поддерживаетÑÑ" + +#: executor/functions.c:1657 executor/functions.c:1690 +#: executor/functions.c:1702 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "неÑовпадение типа возврата в функции (в объÑвлении указан тип %s)" -#: executor/functions.c:1598 +#: executor/functions.c:1659 #, c-format msgid "" "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." @@ -12143,240 +12776,288 @@ msgstr "" "ПоÑледним оператором в функции должен быть SELECT или INSERT/UPDATE/DELETE " "RETURNING." -#: executor/functions.c:1635 +#: executor/functions.c:1692 #, c-format msgid "Final statement must return exactly one column." msgstr "ПоÑледний оператор должен возвращать один Ñтолбец." -#: executor/functions.c:1647 +#: executor/functions.c:1704 #, c-format msgid "Actual return type is %s." msgstr "ФактичеÑкий тип возврата: %s." -#: executor/functions.c:1760 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "ПоÑледний оператор возвращает Ñлишком много Ñтолбцов." -#: executor/functions.c:1793 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "ПоÑледний оператор возвращает %s вмеÑто %s Ð´Ð»Ñ Ñтолбца %d." -#: executor/functions.c:1823 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "ПоÑледний оператор возвращает Ñлишком мало Ñтолбцов." -#: executor/functions.c:1872 +#: executor/functions.c:1940 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "Ð´Ð»Ñ SQL-функций тип возврата %s не поддерживаетÑÑ" -#: executor/nodeAgg.c:3468 +#: executor/nodeAgg.c:2806 parser/parse_agg.c:633 parser/parse_agg.c:663 #, c-format -msgid "combine function for aggregate %u must be declared as STRICT" -msgstr "" -"ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° %u должна объÑвлÑтьÑÑ ÐºÐ°Ðº ÑÑ‚Ñ€Ð¾Ð³Ð°Ñ (STRICT)" +msgid "aggregate function calls cannot be nested" +msgstr "вложенные вызовы агрегатных функций недопуÑтимы" -#: executor/nodeAgg.c:3513 executor/nodeWindowAgg.c:2278 +#: executor/nodeAgg.c:2992 executor/nodeWindowAgg.c:2822 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "" "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %u должна иметь ÑовмеÑтимые входной и переходный типы" -#: executor/nodeAgg.c:3567 parser/parse_agg.c:618 parser/parse_agg.c:648 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "вложенные вызовы агрегатных функций недопуÑтимы" - -#: executor/nodeCustom.c:142 executor/nodeCustom.c:153 +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 #, c-format msgid "custom scan \"%s\" does not support MarkPos" msgstr "неÑтандартное Ñканирование \"%s\" не поддерживает MarkPos" -#: executor/nodeHashjoin.c:760 executor/nodeHashjoin.c:790 +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð²Ð¾ временном файле хеш-ÑоединениÑ: %m" -#: executor/nodeHashjoin.c:825 executor/nodeHashjoin.c:831 +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "не удалоÑÑŒ запиÑать во временный файл хеш-ÑоединениÑ: %m" -#: executor/nodeHashjoin.c:872 executor/nodeHashjoin.c:882 +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "не удалоÑÑŒ прочитать временный файл хеш-ÑоединениÑ: %m" -#: executor/nodeIndexonlyscan.c:233 +#: executor/nodeIndexonlyscan.c:236 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "" "функции неточной диÑтанции не поддерживаютÑÑ Ð² Ñканировании только по индекÑу" -#: executor/nodeLimit.c:252 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSET не может быть отрицательным" -#: executor/nodeLimit.c:278 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMIT не может быть отрицательным" -#: executor/nodeMergejoin.c:1530 +#: executor/nodeMergejoin.c:1567 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "" "RIGHT JOIN поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ ÑƒÑловиÑми, допуÑкающими Ñоединение " "ÑлиÑнием" -#: executor/nodeMergejoin.c:1550 +#: executor/nodeMergejoin.c:1585 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "" "FULL JOIN поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ ÑƒÑловиÑми, допуÑкающими Ñоединение ÑлиÑнием" -#: executor/nodeModifyTable.c:97 +#: executor/nodeModifyTable.c:107 #, c-format msgid "Query has too many columns." msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÐµÑ‚ больше Ñтолбцов." -#: executor/nodeModifyTable.c:124 +#: executor/nodeModifyTable.c:135 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "" "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð²Ñ‹Ð´Ð°Ñ‘Ñ‚ значение Ð´Ð»Ñ ÑƒÐ´Ð°Ð»Ñ‘Ð½Ð½Ð¾Ð³Ð¾ Ñтолбца (Ñ Ð¿Ð¾Ñ€Ñдковым номером %d)." -#: executor/nodeModifyTable.c:132 +#: executor/nodeModifyTable.c:143 #, c-format msgid "Query has too few columns." msgstr "Ð—Ð°Ð¿Ñ€Ð¾Ñ Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÐµÑ‚ меньше Ñтолбцов." -#: executor/nodeModifyTable.c:1202 -#, c-format -msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" -msgstr "команда ON CONFLICT DO UPDATE не может менÑть Ñтроку повторно" - -#: executor/nodeModifyTable.c:1203 +#: executor/nodeModifyTable.c:773 #, c-format msgid "" -"Ensure that no rows proposed for insertion within the same command have " -"duplicate constrained values." +"tuple to be deleted was already moved to another partition due to concurrent " +"update" msgstr "" -"Проверьте, не Ñодержат ли Ñтроки, которые должна добавить команда, " -"дублирующиеÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ, подпадающие под ограничениÑ." +"кортеж, подлежащий удалению, был перемещён в другую Ñекцию в результате " +"параллельного изменениÑ" -#: executor/nodeSamplescan.c:298 +#: executor/nodeModifyTable.c:1085 #, c-format -msgid "TABLESAMPLE parameter cannot be null" -msgstr "параметр TABLESAMPLE не может быть NULL" +msgid "invalid ON UPDATE specification" +msgstr "неверное указание ON UPDATE" -#: executor/nodeSamplescan.c:310 +#: executor/nodeModifyTable.c:1086 #, c-format -msgid "TABLESAMPLE REPEATABLE parameter cannot be null" -msgstr "параметр TABLESAMPLE REPEATABLE не может быть NULL" - -#: executor/nodeSubplan.c:333 executor/nodeSubplan.c:372 -#: executor/nodeSubplan.c:1004 +msgid "" +"The result tuple would appear in a different partition than the original " +"tuple." +msgstr "" +"Результирующий кортеж окажетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰Ñ‘Ð½Ð½Ñ‹Ð¼ из Ñекции иÑходного кортежа в " +"другую." + +#: executor/nodeModifyTable.c:1261 +#, c-format +msgid "" +"tuple to be updated was already moved to another partition due to concurrent " +"update" +msgstr "" +"кортеж, подлежащий изменению, был перемещён в другую Ñекцию в результате " +"параллельного изменениÑ" + +#: executor/nodeModifyTable.c:1412 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "команда ON CONFLICT DO UPDATE не может менÑть Ñтроку повторно" + +#: executor/nodeModifyTable.c:1413 +#, c-format +msgid "" +"Ensure that no rows proposed for insertion within the same command have " +"duplicate constrained values." +msgstr "" +"Проверьте, не Ñодержат ли Ñтроки, которые должна добавить команда, " +"дублирующиеÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ, подпадающие под ограничениÑ." + +#: executor/nodeSamplescan.c:279 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "параметр TABLESAMPLE не может быть NULL" + +#: executor/nodeSamplescan.c:291 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "параметр TABLESAMPLE REPEATABLE не может быть NULL" + +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1136 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "Ð¿Ð¾Ð´Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð² выражении вернул больше одной Ñтроки" -#: executor/nodeTableFuncscan.c:365 +#: executor/nodeTableFuncscan.c:375 #, c-format msgid "namespace URI must not be null" msgstr "URI проÑтранÑтва имён должен быть не NULL" -#: executor/nodeTableFuncscan.c:376 +#: executor/nodeTableFuncscan.c:389 #, c-format msgid "row filter expression must not be null" msgstr "выражение отбора Ñтрок должно быть не NULL" -#: executor/nodeTableFuncscan.c:401 +#: executor/nodeTableFuncscan.c:415 #, c-format msgid "column filter expression must not be null" msgstr "выражение отбора Ñтолбца должно быть не NULL" -#: executor/nodeTableFuncscan.c:402 +#: executor/nodeTableFuncscan.c:416 #, c-format msgid "Filter for column \"%s\" is null." msgstr "Ð”Ð»Ñ Ñтолбца \"%s\" задано выражение NULL." -#: executor/nodeTableFuncscan.c:481 +#: executor/nodeTableFuncscan.c:506 #, c-format msgid "null is not allowed in column \"%s\"" msgstr "в Ñтолбце \"%s\" не допуÑкаетÑÑ NULL" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeWindowAgg.c:355 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÑ…Ð¾Ð´Ð° движимого агрегата не должна возвращать NULL" -#: executor/nodeWindowAgg.c:1621 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "Ñмещение начала рамки не может быть NULL" -#: executor/nodeWindowAgg.c:1634 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "Ñмещение начала рамки не может быть отрицательным" -#: executor/nodeWindowAgg.c:1646 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "Ñмещение конца рамки не может быть NULL" -#: executor/nodeWindowAgg.c:1659 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "Ñмещение конца рамки не может быть отрицательным" -#: executor/spi.c:197 +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "" +"Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не поддерживает иÑпользование в качеÑтве оконной " +"функции" + +#: executor/spi.c:233 executor/spi.c:280 +#, c-format +msgid "invalid transaction termination" +msgstr "неверное завершение транзакции" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "фикÑировать транзакцию при наличии активных подтранзакций нельзÑ" + +#: executor/spi.c:286 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "откатить транзакцию при наличии активных подтранзакций нельзÑ" + +#: executor/spi.c:334 #, c-format msgid "transaction left non-empty SPI stack" msgstr "поÑле транзакции оÑталÑÑ Ð½ÐµÐ¿ÑƒÑтой Ñтек SPI" -#: executor/spi.c:198 executor/spi.c:261 +#: executor/spi.c:335 executor/spi.c:398 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "Проверьте наличие вызова \"SPI_finish\"." -#: executor/spi.c:260 +#: executor/spi.c:397 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "поÑле подтранзакции оÑталÑÑ Ð½ÐµÐ¿ÑƒÑтой Ñтек SPI" -#: executor/spi.c:1143 +#: executor/spi.c:1300 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "не удалоÑÑŒ открыть план неÑкольких запроÑов как курÑор" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1148 +#: executor/spi.c:1305 #, c-format msgid "cannot open %s query as cursor" msgstr "не удалоÑÑŒ открыть Ð·Ð°Ð¿Ñ€Ð¾Ñ %s как курÑор" -#: executor/spi.c:1256 +#: executor/spi.c:1410 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE не поддерживаетÑÑ" -#: executor/spi.c:1257 parser/analyze.c:2445 +#: executor/spi.c:1411 parser/analyze.c:2480 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "Прокручиваемые курÑоры должны быть READ ONLY." -#: executor/spi.c:2371 +#: executor/spi.c:2551 #, c-format msgid "SQL statement \"%s\"" msgstr "SQL-оператор: \"%s\"" -#: executor/tqueue.c:317 +#: executor/tqueue.c:70 #, c-format msgid "could not send tuple to shared-memory queue" msgstr "не удалоÑÑŒ передать кортеж в очередь в разделÑемой памÑти" @@ -12396,189 +13077,259 @@ msgstr "неверный параметр \"%s\"" msgid "Valid options in this context are: %s" msgstr "Ð’ данном контекÑте допуÑтимы параметры: %s" -#: lib/stringinfo.c:301 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 +#: utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "нет доÑтупа к файлу \"%s\": %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "Ð²Ñ€ÐµÐ¼Ñ Ð²Ð½ÐµÐ´Ñ€ÐµÐ½Ð¸Ñ: %.3fs, оптимизации: %.3fs, выдачи: %.3fs" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "Ошибка при запроÑе памÑти DSA (%zu Б)." + +#: lib/stringinfo.c:278 #, c-format msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." msgstr "" "Ðе удалоÑÑŒ увеличить Ñтроковый буфер (в буфере байт: %d, требовалоÑÑŒ ещё %d)." -#: libpq/auth-scram.c:191 +#: libpq/auth-scram.c:249 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "клиент выбрал неверный механизм аутентификации SASL" + +#: libpq/auth-scram.c:270 libpq/auth-scram.c:510 libpq/auth-scram.c:519 +#, c-format +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "неверный проверочный код SCRAM Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"" + +#: libpq/auth-scram.c:281 #, c-format msgid "User \"%s\" does not have a valid SCRAM verifier." msgstr "У Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" нет подходÑщих данных Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ SCRAM." -#: libpq/auth-scram.c:246 +#: libpq/auth-scram.c:359 libpq/auth-scram.c:364 libpq/auth-scram.c:658 +#: libpq/auth-scram.c:666 libpq/auth-scram.c:777 libpq/auth-scram.c:787 +#: libpq/auth-scram.c:895 libpq/auth-scram.c:902 libpq/auth-scram.c:917 +#: libpq/auth-scram.c:932 libpq/auth-scram.c:946 libpq/auth-scram.c:964 +#: libpq/auth-scram.c:979 libpq/auth-scram.c:1265 libpq/auth-scram.c:1273 +#, c-format +msgid "malformed SCRAM message" +msgstr "неправильное Ñообщение SCRAM" + +#: libpq/auth-scram.c:360 #, c-format -msgid "malformed SCRAM message (empty message)" -msgstr "неправильное Ñообщение SCRAM (пуÑтое Ñодержимое)" +msgid "The message is empty." +msgstr "Сообщение пуÑтое." -#: libpq/auth-scram.c:250 +#: libpq/auth-scram.c:365 #, c-format -msgid "malformed SCRAM message (length mismatch)" -msgstr "неправильное Ñообщение SCRAM (Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°)" +msgid "Message length does not match input length." +msgstr "Длина ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð½Ðµ ÑоответÑтвует входной длине." -#: libpq/auth-scram.c:282 +#: libpq/auth-scram.c:397 #, c-format -msgid "invalid SCRAM response (nonce mismatch)" -msgstr "неверный ответ SCRAM (неÑовпадение проверочного кода)" +msgid "invalid SCRAM response" +msgstr "неверный ответ SCRAM" -#: libpq/auth-scram.c:355 +#: libpq/auth-scram.c:398 +#, c-format +msgid "Nonce does not match." +msgstr "Разовый код не Ñовпадает." + +#: libpq/auth-scram.c:472 #, c-format msgid "could not generate random salt" msgstr "не удалоÑÑŒ Ñгенерировать Ñлучайную Ñоль" -#: libpq/auth-scram.c:541 +#: libpq/auth-scram.c:659 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "ОжидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ \"%c\", но обнаружено \"%s\"." + +#: libpq/auth-scram.c:667 libpq/auth-scram.c:788 #, c-format -msgid "malformed SCRAM message (attribute '%c' expected, %s found)" -msgstr "неправильное Ñообщение SCRAM (ожидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ '%c', получено: %s)" +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "ОжидалÑÑ Ñимвол \"=\" Ð´Ð»Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° \"%c\"." -#: libpq/auth-scram.c:548 libpq/auth-scram.c:637 +#: libpq/auth-scram.c:778 #, c-format -msgid "malformed SCRAM message (expected = in attr %c)" -msgstr "неправильное Ñообщение SCRAM (в атрибуте %c ожидалоÑÑŒ =)" +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "ОжидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚, но обнаружен неправильный Ñимвол \"%s\"." -#: libpq/auth-scram.c:628 +#: libpq/auth-scram.c:896 libpq/auth-scram.c:918 #, c-format -msgid "malformed SCRAM message (attribute expected, invalid char %s found)" +msgid "" +"The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not " +"include channel binding data." msgstr "" -"неправильное Ñообщение SCRAM (ожидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚, получен некорректный Ñимвол " -"%s)" +"Клиент выбрал алгоритм SCRAM-SHA-256-PLUS, но в Ñообщении SCRAM отÑутÑтвуют " +"данные ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²." + +#: libpq/auth-scram.c:903 libpq/auth-scram.c:933 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "ОжидалаÑÑŒ запÑтаÑ, но обнаружен Ñимвол \"%s\"." + +#: libpq/auth-scram.c:924 +#, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "Ошибка ÑоглаÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² SCRAM" + +#: libpq/auth-scram.c:925 +#, c-format +msgid "" +"The client supports SCRAM channel binding but thinks the server does not. " +"However, this server does support channel binding." +msgstr "" +"Клиент поддерживает ÑвÑзывание каналов SCRAM, но полагает, что оно не " +"поддерживаетÑÑ Ñервером. Однако Ñервер тоже поддерживает ÑвÑзывание каналов." -#: libpq/auth-scram.c:750 +#: libpq/auth-scram.c:947 #, c-format -msgid "client requires SCRAM channel binding, but it is not supported" -msgstr "клиенту требуетÑÑ Ð¿Ñ€Ð¸Ð²Ñзка канала SCRAM, но она не поддерживаетÑÑ" +msgid "" +"The client selected SCRAM-SHA-256 without channel binding, but the SCRAM " +"message includes channel binding data." +msgstr "" +"Клиент выбрал алгоритм SCRAM-SHA-256 без ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð², но Ñообщение " +"SCRAM Ñодержит данные ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð²." -#: libpq/auth-scram.c:754 +#: libpq/auth-scram.c:958 #, c-format -msgid "malformed SCRAM message (unexpected channel-binding flag %s)" -msgstr "неправильное Ñообщение SCRAM (неожиданный флаг привÑзки канала %s)" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "неподдерживаемый тип ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² SCRAM \"%s\"" -#: libpq/auth-scram.c:760 +#: libpq/auth-scram.c:965 #, c-format -msgid "malformed SCRAM message (comma expected, got %s)" -msgstr "неправильное Ñообщение SCRAM (ожидалаÑÑŒ запÑтаÑ, получено: %s)" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Ðеожиданный флаг ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² \"%s\"." -#: libpq/auth-scram.c:770 +#: libpq/auth-scram.c:975 #, c-format msgid "client uses authorization identity, but it is not supported" msgstr "клиент передал идентификатор Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ð¸Ð¸, но Ñто не поддерживаетÑÑ" -#: libpq/auth-scram.c:774 +#: libpq/auth-scram.c:980 #, c-format -msgid "" -"malformed SCRAM message (unexpected attribute %s in client-first-message)" -msgstr "" -"неправильное Ñообщение SCRAM (неожиданный атрибут %s в первом Ñообщении " -"клиента)" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "Ðеожиданный атрибут \"%s\" в первом Ñообщении клиента." -#: libpq/auth-scram.c:790 +#: libpq/auth-scram.c:996 #, c-format -msgid "client requires mandatory SCRAM extension" -msgstr "клиент требует поддержки обÑзательного раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ SCRAM" +msgid "client requires an unsupported SCRAM extension" +msgstr "клиенту требуетÑÑ Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð¾Ðµ раÑширение SCRAM" -#: libpq/auth-scram.c:804 +#: libpq/auth-scram.c:1010 #, c-format msgid "non-printable characters in SCRAM nonce" msgstr "непечатаемые Ñимволы в разовом коде SCRAM" -#: libpq/auth-scram.c:921 +#: libpq/auth-scram.c:1127 #, c-format msgid "could not generate random nonce" msgstr "не удалоÑÑŒ Ñгенерировать разовый код" -#: libpq/auth-scram.c:989 +#: libpq/auth-scram.c:1231 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "ошибка проверки ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² SCRAM" + +#: libpq/auth-scram.c:1249 #, c-format msgid "unexpected SCRAM channel-binding attribute in client-final-message" msgstr "" -"неожиданный атрибут привÑзки канала в поÑледнем Ñообщении клиента SCRAM" +"неожиданный атрибут ÑвÑÐ·Ñ‹Ð²Ð°Ð½Ð¸Ñ ÐºÐ°Ð½Ð°Ð»Ð¾Ð² в поÑледнем Ñообщении клиента SCRAM" -#: libpq/auth-scram.c:1003 +#: libpq/auth-scram.c:1266 #, c-format -msgid "malformed SCRAM message (malformed proof in client-final-message" -msgstr "" -"неправильное Ñообщение SCRAM (некорректное подтверждение в поÑледнем " -"Ñообщении клиента)" +msgid "Malformed proof in client-final-message." +msgstr "Ðекорректное подтверждение в поÑледнем Ñообщении клиента." -#: libpq/auth-scram.c:1010 +#: libpq/auth-scram.c:1274 #, c-format -msgid "malformed SCRAM message (garbage at end of client-final-message)" -msgstr "" -"неправильное Ñообщение SCRAM (муÑор в конце поÑледнего ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°)" +msgid "Garbage found at the end of client-final-message." +msgstr "МуÑор в конце поÑледнего ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð°." -#: libpq/auth.c:274 +#: libpq/auth.c:282 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "" "пользователь \"%s\" не прошёл проверку подлинноÑти: не разрешённый компьютер" -#: libpq/auth.c:277 +#: libpq/auth.c:285 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (\"trust\")" -#: libpq/auth.c:280 +#: libpq/auth.c:288 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (Ident)" -#: libpq/auth.c:283 +#: libpq/auth.c:291 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (Peer)" -#: libpq/auth.c:288 +#: libpq/auth.c:296 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (по паролю)" -#: libpq/auth.c:293 +#: libpq/auth.c:301 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (GSSAPI)" -#: libpq/auth.c:296 +#: libpq/auth.c:304 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (SSPI)" -#: libpq/auth.c:299 +#: libpq/auth.c:307 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (PAM)" -#: libpq/auth.c:302 +#: libpq/auth.c:310 #, c-format msgid "BSD authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (BSD)" -#: libpq/auth.c:305 +#: libpq/auth.c:313 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (LDAP)" -#: libpq/auth.c:308 +#: libpq/auth.c:316 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (по Ñертификату)" -#: libpq/auth.c:311 +#: libpq/auth.c:319 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "пользователь \"%s\" не прошёл проверку подлинноÑти (RADIUS)" -#: libpq/auth.c:314 +#: libpq/auth.c:322 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "" "пользователь \"%s\" не прошёл проверку подлинноÑти: неверный метод проверки" -#: libpq/auth.c:318 +#: libpq/auth.c:326 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "Подключение ÑоответÑтвует Ñтроке %d в pg_hba.conf: \"%s\"" -#: libpq/auth.c:365 +#: libpq/auth.c:373 #, c-format msgid "" "client certificates can only be checked if a root certificate store is " @@ -12587,12 +13338,12 @@ msgstr "" "Ñертификаты клиентов могут проверÑтьÑÑ, только еÑли доÑтупно хранилище " "корневых Ñертификатов" -#: libpq/auth.c:376 +#: libpq/auth.c:384 #, c-format msgid "connection requires a valid client certificate" msgstr "Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ Ð³Ð¾Ð´Ð½Ñ‹Ð¹ Ñертификат клиента" -#: libpq/auth.c:409 +#: libpq/auth.c:417 #, c-format msgid "" "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" @@ -12600,31 +13351,31 @@ msgstr "" "pg_hba.conf отвергает подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸: компьютер \"%s\", " "пользователь \"%s\", \"%s\"" -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL off" msgstr "SSL выкл." -#: libpq/auth.c:411 libpq/auth.c:427 libpq/auth.c:485 libpq/auth.c:503 +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 msgid "SSL on" msgstr "SSL вкл." -#: libpq/auth.c:415 +#: libpq/auth.c:423 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "" "pg_hba.conf отвергает подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸: компьютер \"%s\", " "пользователь \"%s\"" -#: libpq/auth.c:424 +#: libpq/auth.c:432 #, c-format msgid "" -"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" -"\", %s" +"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"" +"%s\", %s" msgstr "" "pg_hba.conf отвергает подключение: компьютер \"%s\", пользователь \"%s\", " "база данных \"%s\", %s" -#: libpq/auth.c:431 +#: libpq/auth.c:439 #, c-format msgid "" "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" @@ -12632,46 +13383,46 @@ msgstr "" "pg_hba.conf отвергает подключение: компьютер \"%s\", пользователь \"%s\", " "база данных \"%s\"" -#: libpq/auth.c:460 +#: libpq/auth.c:468 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "" "IP-Ð°Ð´Ñ€ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° разрешаетÑÑ Ð² \"%s\", ÑоответÑтвует прÑмому преобразованию." -#: libpq/auth.c:463 +#: libpq/auth.c:471 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "" "IP-Ð°Ð´Ñ€ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° разрешаетÑÑ Ð² \"%s\", прÑмое преобразование не проверÑлоÑÑŒ." -#: libpq/auth.c:466 +#: libpq/auth.c:474 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "" "IP-Ð°Ð´Ñ€ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° разрешаетÑÑ Ð² \"%s\", Ñто не ÑоответÑтвует прÑмому " "преобразованию." -#: libpq/auth.c:469 +#: libpq/auth.c:477 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "" "Преобразовать Ð¸Ð¼Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ñкого компьютера \"%s\" в IP-Ð°Ð´Ñ€ÐµÑ Ð½Ðµ удалоÑÑŒ: %s." -#: libpq/auth.c:474 +#: libpq/auth.c:482 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "Получить Ð¸Ð¼Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° из IP-адреÑа клиента не удалоÑÑŒ: %s." -#: libpq/auth.c:483 +#: libpq/auth.c:491 #, c-format msgid "" -"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s" -"\", %s" +"no pg_hba.conf entry for replication connection from host \"%s\", user \"" +"%s\", %s" msgstr "" "в pg_hba.conf нет запиÑи, разрешающей подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñ " "компьютера \"%s\" Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", %s" -#: libpq/auth.c:490 +#: libpq/auth.c:498 #, c-format msgid "" "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" @@ -12679,31 +13430,36 @@ msgstr "" "в pg_hba.conf нет запиÑи, разрешающей подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñ " "компьютера \"%s\" Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"" -#: libpq/auth.c:500 +#: libpq/auth.c:508 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" msgstr "" -"в pg_hba.conf нет запиÑи Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° \"%s\", Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", базы " -"\"%s\", %s" +"в pg_hba.conf нет запиÑи Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° \"%s\", Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", базы \"" +"%s\", %s" -#: libpq/auth.c:508 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "" -"в pg_hba.conf нет запиÑи Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° \"%s\", Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", базы " -"\"%s\"" +"в pg_hba.conf нет запиÑи Ð´Ð»Ñ ÐºÐ¾Ð¼Ð¿ÑŒÑŽÑ‚ÐµÑ€Ð° \"%s\", Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", базы \"" +"%s\"" -#: libpq/auth.c:660 +#: libpq/auth.c:669 #, c-format msgid "expected password response, got message type %d" msgstr "ожидалÑÑ Ð¾Ñ‚Ð²ÐµÑ‚ Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼, но получено Ñообщение %d" -#: libpq/auth.c:688 +#: libpq/auth.c:697 #, c-format msgid "invalid password packet size" msgstr "неверный размер пакета Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼" -#: libpq/auth.c:818 libpq/hba.c:1322 +#: libpq/auth.c:715 +#, c-format +msgid "empty password returned by client" +msgstr "клиент возвратил пуÑтой пароль" + +#: libpq/auth.c:835 libpq/hba.c:1325 #, c-format msgid "" "MD5 authentication is not supported when \"db_user_namespace\" is enabled" @@ -12711,215 +13467,220 @@ msgstr "" "проверка подлинноÑти MD5 не поддерживаетÑÑ, когда включён режим " "\"db_user_namespace\"" -#: libpq/auth.c:824 +#: libpq/auth.c:841 #, c-format msgid "could not generate random MD5 salt" msgstr "не удалоÑÑŒ Ñгенерировать Ñлучайную Ñоль Ð´Ð»Ñ MD5" -#: libpq/auth.c:866 +#: libpq/auth.c:887 #, c-format msgid "SASL authentication is not supported in protocol version 2" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ SASL не поддерживаетÑÑ Ð² протоколе верÑии 2" -#: libpq/auth.c:904 +#: libpq/auth.c:920 #, c-format msgid "expected SASL response, got message type %d" msgstr "ожидалÑÑ Ð¾Ñ‚Ð²ÐµÑ‚ SASL, но получено Ñообщение %d" -#: libpq/auth.c:1041 +#: libpq/auth.c:1112 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "GSSAPI не поддерживаетÑÑ Ð² протоколе верÑии 2" -#: libpq/auth.c:1101 +#: libpq/auth.c:1172 #, c-format msgid "expected GSS response, got message type %d" msgstr "ожидалÑÑ Ð¾Ñ‚Ð²ÐµÑ‚ GSS, но получено Ñообщение %d" -#: libpq/auth.c:1163 +#: libpq/auth.c:1234 msgid "accepting GSS security context failed" msgstr "принÑть контекÑÑ‚ безопаÑноÑти GSS не удалоÑÑŒ" -#: libpq/auth.c:1189 +#: libpq/auth.c:1260 msgid "retrieving GSS user name failed" msgstr "получить Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ GSS не удалоÑÑŒ" -#: libpq/auth.c:1308 +#: libpq/auth.c:1385 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "SSPI не поддерживаетÑÑ Ð² протоколе верÑии 2" -#: libpq/auth.c:1323 +#: libpq/auth.c:1400 msgid "could not acquire SSPI credentials" msgstr "не удалоÑÑŒ получить удоÑтоверение SSPI" -#: libpq/auth.c:1341 +#: libpq/auth.c:1418 #, c-format msgid "expected SSPI response, got message type %d" msgstr "ожидалÑÑ Ð¾Ñ‚Ð²ÐµÑ‚ SSPI, но получено Ñообщение %d" -#: libpq/auth.c:1414 +#: libpq/auth.c:1491 msgid "could not accept SSPI security context" msgstr "принÑть контекÑÑ‚ безопаÑноÑти SSPI не удалоÑÑŒ" -#: libpq/auth.c:1476 +#: libpq/auth.c:1553 msgid "could not get token from SSPI security context" msgstr "не удалоÑÑŒ получить маркер из контекÑта безопаÑноÑти SSPI" -#: libpq/auth.c:1595 libpq/auth.c:1614 +#: libpq/auth.c:1672 libpq/auth.c:1691 #, c-format msgid "could not translate name" msgstr "не удалоÑÑŒ преобразовать имÑ" -#: libpq/auth.c:1627 +#: libpq/auth.c:1704 #, c-format msgid "realm name too long" msgstr "Ð¸Ð¼Ñ Ð¾Ð±Ð»Ð°Ñти Ñлишком длинное" -#: libpq/auth.c:1642 +#: libpq/auth.c:1719 #, c-format msgid "translated account name too long" msgstr "преобразованное Ð¸Ð¼Ñ ÑƒÑ‡Ñ‘Ñ‚Ð½Ð¾Ð¹ запиÑи Ñлишком длинное" -#: libpq/auth.c:1828 +#: libpq/auth.c:1905 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "не удалоÑÑŒ Ñоздать Ñокет Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу Ident: %m" -#: libpq/auth.c:1843 +#: libpq/auth.c:1920 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "не удалоÑÑŒ привÑзатьÑÑ Ðº локальному адреÑу \"%s\": %m" -#: libpq/auth.c:1855 +#: libpq/auth.c:1932 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу Ident по адреÑу \"%s\", порт %s: %m" -#: libpq/auth.c:1877 +#: libpq/auth.c:1954 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "" "не удалоÑÑŒ отправить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ñерверу Ident по адреÑу \"%s\", порт %s: %m" -#: libpq/auth.c:1894 +#: libpq/auth.c:1971 #, c-format msgid "" "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "" "не удалоÑÑŒ получить ответ от Ñервера Ident по адреÑу \"%s\", порт %s: %m" -#: libpq/auth.c:1904 +#: libpq/auth.c:1981 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "неверно форматированный ответ от Ñервера Ident: \"%s\"" -#: libpq/auth.c:1944 +#: libpq/auth.c:2021 #, c-format msgid "peer authentication is not supported on this platform" msgstr "проверка подлинноÑти peer в Ñтой ОС не поддерживаетÑÑ" -#: libpq/auth.c:1948 +#: libpq/auth.c:2025 #, c-format msgid "could not get peer credentials: %m" msgstr "не удалоÑÑŒ получить данные Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‡ÐµÑ€ÐµÐ· механизм peer: %m" -#: libpq/auth.c:1957 +#: libpq/auth.c:2036 #, c-format msgid "could not look up local user ID %ld: %s" msgstr "найти локального Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð¾ идентификатору (%ld) не удалоÑÑŒ: %s" -#: libpq/auth.c:2041 libpq/auth.c:2367 libpq/auth.c:2680 -#, c-format -msgid "empty password returned by client" -msgstr "клиент возвратил пуÑтой пароль" - -#: libpq/auth.c:2051 +#: libpq/auth.c:2124 #, c-format msgid "error from underlying PAM layer: %s" msgstr "ошибка в нижележащем Ñлое PAM: %s" -#: libpq/auth.c:2132 +#: libpq/auth.c:2193 #, c-format msgid "could not create PAM authenticator: %s" msgstr "не удалоÑÑŒ Ñоздать аутентификатор PAM: %s" -#: libpq/auth.c:2143 +#: libpq/auth.c:2204 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "ошибка в pam_set_item(PAM_USER): %s" -#: libpq/auth.c:2154 +#: libpq/auth.c:2236 #, c-format msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "ошибка в pam_set_item(PAM_RHOST): %s" -#: libpq/auth.c:2165 +#: libpq/auth.c:2248 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "ошибка в pam_set_item(PAM_CONV): %s" -#: libpq/auth.c:2176 +#: libpq/auth.c:2259 #, c-format msgid "pam_authenticate failed: %s" msgstr "ошибка в pam_authenticate: %s" -#: libpq/auth.c:2187 +#: libpq/auth.c:2270 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "ошибка в pam_acct_mgmt: %s" -#: libpq/auth.c:2198 +#: libpq/auth.c:2281 #, c-format msgid "could not release PAM authenticator: %s" msgstr "не удалоÑÑŒ оÑвободить аутентификатор PAM: %s" -#: libpq/auth.c:2263 -#, c-format -msgid "could not initialize LDAP: %m" -msgstr "не удалоÑÑŒ инициализировать LDAP: %m" - -#: libpq/auth.c:2266 +#: libpq/auth.c:2357 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "не удалоÑÑŒ инициализировать LDAP (код ошибки: %d)" -#: libpq/auth.c:2276 +#: libpq/auth.c:2406 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "не удалоÑÑŒ инициализировать LDAP: %s" + +#: libpq/auth.c:2416 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "протокол ldaps Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ библиотекой LDAP не поддерживаетÑÑ" + +#: libpq/auth.c:2424 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "не удалоÑÑŒ инициализировать LDAP: %m" + +#: libpq/auth.c:2434 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "не удалоÑÑŒ задать верÑию протокола LDAP: %s" -#: libpq/auth.c:2305 +#: libpq/auth.c:2465 #, c-format msgid "could not load wldap32.dll" msgstr "не удалоÑÑŒ загрузить wldap32.dll" -#: libpq/auth.c:2313 +#: libpq/auth.c:2473 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "не удалоÑÑŒ найти функцию _ldap_start_tls_sA в wldap32.dll" -#: libpq/auth.c:2314 +#: libpq/auth.c:2474 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "LDAP через SSL не поддерживаетÑÑ Ð² Ñтой ОС." -#: libpq/auth.c:2329 +#: libpq/auth.c:2489 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "не удалоÑÑŒ начать ÑÐµÐ°Ð½Ñ LDAP TLS: %s" -#: libpq/auth.c:2351 +#: libpq/auth.c:2552 #, c-format msgid "LDAP server not specified" msgstr "LDAP-Ñервер не определён" -#: libpq/auth.c:2404 +#: libpq/auth.c:2607 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "недопуÑтимый Ñимвол в имени Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ подлинноÑти LDAP" -#: libpq/auth.c:2419 +#: libpq/auth.c:2624 #, c-format msgid "" "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": " @@ -12928,28 +13689,28 @@ msgstr "" "не удалоÑÑŒ выполнить начальную привÑзку LDAP Ð´Ð»Ñ ldapbinddn \"%s\" на " "Ñервере \"%s\": %s" -#: libpq/auth.c:2443 +#: libpq/auth.c:2653 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "" "не удалоÑÑŒ выполнить LDAP-поиÑк по фильтру \"%s\" на Ñервере \"%s\": %s" -#: libpq/auth.c:2454 +#: libpq/auth.c:2667 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "в LDAP нет Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"" -#: libpq/auth.c:2455 +#: libpq/auth.c:2668 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "LDAP-поиÑк по фильтру \"%s\" на Ñервере \"%s\" не вернул результатов" -#: libpq/auth.c:2459 +#: libpq/auth.c:2672 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "пользователь LDAP \"%s\" не уникален" -#: libpq/auth.c:2460 +#: libpq/auth.c:2673 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." msgid_plural "" @@ -12958,7 +13719,7 @@ msgstr[0] "LDAP-поиÑк по фильтру \"%s\" на Ñервере \"%s\" msgstr[1] "LDAP-поиÑк по фильтру \"%s\" на Ñервере \"%s\" вернул %d запиÑи." msgstr[2] "LDAP-поиÑк по фильтру \"%s\" на Ñервере \"%s\" вернул %d запиÑей." -#: libpq/auth.c:2478 +#: libpq/auth.c:2693 #, c-format msgid "" "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" @@ -12966,19 +13727,24 @@ msgstr "" "не удалоÑÑŒ получить dn Ð´Ð»Ñ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ результата, ÑоответÑтвующего \"%s\" на " "Ñервере \"%s\": %s" -#: libpq/auth.c:2498 +#: libpq/auth.c:2714 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" msgstr "" -"не удалоÑÑŒ отвÑзатьÑÑ Ð¿Ð¾Ñле поиÑка Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" на Ñервере \"%s\": %s" +"не удалоÑÑŒ отвÑзатьÑÑ Ð¿Ð¾Ñле поиÑка Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" на Ñервере \"%s\"" -#: libpq/auth.c:2528 +#: libpq/auth.c:2745 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "" "ошибка при региÑтрации в LDAP Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" на Ñервере \"%s\": %s" -#: libpq/auth.c:2556 +#: libpq/auth.c:2774 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "ДиагноÑтика LDAP: %s" + +#: libpq/auth.c:2799 #, c-format msgid "" "certificate authentication failed for user \"%s\": client certificate " @@ -12987,218 +13753,205 @@ msgstr "" "ошибка проверки подлинноÑти Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" по Ñертификату: Ñертификат " "клиента не Ñодержит Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" -#: libpq/auth.c:2659 +#: libpq/auth.c:2902 #, c-format msgid "RADIUS server not specified" msgstr "RADIUS-Ñервер не определён" -#: libpq/auth.c:2666 +#: libpq/auth.c:2909 #, c-format msgid "RADIUS secret not specified" msgstr "Ñекрет RADIUS не определён" # well-spelled: Ñимв -#: libpq/auth.c:2687 +#: libpq/auth.c:2923 #, c-format msgid "" "RADIUS authentication does not support passwords longer than %d characters" msgstr "проверка подлинноÑти RADIUS не поддерживает пароли длиннее %d Ñимв." -#: libpq/auth.c:2784 libpq/hba.c:1873 +#: libpq/auth.c:3028 libpq/hba.c:1908 #, c-format msgid "could not translate RADIUS server name \"%s\" to address: %s" msgstr "не удалоÑÑŒ преобразовать Ð¸Ð¼Ñ Ñервера RADIUS \"%s\" в адреÑ: %s" -#: libpq/auth.c:2798 +#: libpq/auth.c:3042 #, c-format msgid "could not generate random encryption vector" msgstr "не удалоÑÑŒ Ñгенерировать Ñлучайный вектор шифрованиÑ" -#: libpq/auth.c:2832 +#: libpq/auth.c:3076 #, c-format msgid "could not perform MD5 encryption of password" msgstr "не удалоÑÑŒ вычиÑлить MD5-хеш паролÑ" -#: libpq/auth.c:2858 +#: libpq/auth.c:3102 #, c-format msgid "could not create RADIUS socket: %m" msgstr "не удалоÑÑŒ Ñоздать Ñокет RADIUS: %m" -#: libpq/auth.c:2880 +#: libpq/auth.c:3124 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "не удалоÑÑŒ привÑзатьÑÑ Ðº локальному Ñокету RADIUS: %m" -#: libpq/auth.c:2890 +#: libpq/auth.c:3134 #, c-format msgid "could not send RADIUS packet: %m" msgstr "не удалоÑÑŒ отправить пакет RADIUS: %m" -#: libpq/auth.c:2923 libpq/auth.c:2949 +#: libpq/auth.c:3167 libpq/auth.c:3193 #, c-format msgid "timeout waiting for RADIUS response from %s" msgstr "превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¾Ñ‚Ð²ÐµÑ‚Ð° RADIUS от %s" -#: libpq/auth.c:2942 +#: libpq/auth.c:3186 #, c-format msgid "could not check status on RADIUS socket: %m" msgstr "не удалоÑÑŒ проверить ÑоÑтоÑние Ñокета RADIUS: %m" -#: libpq/auth.c:2972 +#: libpq/auth.c:3216 #, c-format msgid "could not read RADIUS response: %m" msgstr "не удалоÑÑŒ прочитать ответ RADIUS: %m" -#: libpq/auth.c:2985 libpq/auth.c:2989 +#: libpq/auth.c:3229 libpq/auth.c:3233 #, c-format msgid "RADIUS response from %s was sent from incorrect port: %d" msgstr "ответ RADIUS от %s был отправлен Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð³Ð¾ порта: %d" -#: libpq/auth.c:2998 +#: libpq/auth.c:3242 #, c-format msgid "RADIUS response from %s too short: %d" msgstr "Ñлишком короткий ответ RADIUS от %s: %d" -#: libpq/auth.c:3005 +#: libpq/auth.c:3249 #, c-format msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" msgstr "в ответе RADIUS от %s иÑпорчена длина: %d (фактичеÑÐºÐ°Ñ Ð´Ð»Ð¸Ð½Ð° %d)" -#: libpq/auth.c:3013 +#: libpq/auth.c:3257 #, c-format msgid "RADIUS response from %s is to a different request: %d (should be %d)" msgstr "пришёл ответ RADIUS от %s на другой запроÑ: %d (ожидалÑÑ %d)" -#: libpq/auth.c:3038 +#: libpq/auth.c:3282 #, c-format msgid "could not perform MD5 encryption of received packet" msgstr "не удалоÑÑŒ вычиÑлить MD5 Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð½Ñтого пакета" -#: libpq/auth.c:3047 +#: libpq/auth.c:3291 #, c-format msgid "RADIUS response from %s has incorrect MD5 signature" msgstr "ответ RADIUS от %s Ñодержит неверную подпиÑÑŒ MD5" -#: libpq/auth.c:3065 +#: libpq/auth.c:3309 #, c-format msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" msgstr "ответ RADIUS от %s Ñодержит неверный код (%d) Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"" -#: libpq/be-fsstubs.c:132 libpq/be-fsstubs.c:163 libpq/be-fsstubs.c:197 -#: libpq/be-fsstubs.c:237 libpq/be-fsstubs.c:262 libpq/be-fsstubs.c:310 -#: libpq/be-fsstubs.c:333 libpq/be-fsstubs.c:581 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 #, c-format msgid "invalid large-object descriptor: %d" msgstr "неверный деÑкриптор большого объекта: %d" -#: libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:216 libpq/be-fsstubs.c:600 -#: libpq/be-fsstubs.c:788 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "нет доÑтупа к большому объекту %u" +msgid "large object descriptor %d was not opened for reading" +msgstr "деÑкриптор большого объекта %d не был открыт Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ" -#: libpq/be-fsstubs.c:203 libpq/be-fsstubs.c:587 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 #, c-format msgid "large object descriptor %d was not opened for writing" -msgstr "деÑкриптор большого объекта %d был открыт не Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи" +msgstr "деÑкриптор большого объекта %d не был открыт Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи" -#: libpq/be-fsstubs.c:245 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "" "результат lo_lseek Ð´Ð»Ñ Ð´ÐµÑкриптора большого объекта %d вне допуÑтимого " "диапазона" -#: libpq/be-fsstubs.c:318 +#: libpq/be-fsstubs.c:285 #, c-format msgid "lo_tell result out of range for large-object descriptor %d" msgstr "" "результат lo_tell Ð´Ð»Ñ Ð´ÐµÑкриптора большого объекта %d вне допуÑтимого " "диапазона" -#: libpq/be-fsstubs.c:455 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ lo_import() на Ñервере нужно быть Ñуперпользователем" - -#: libpq/be-fsstubs.c:456 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "ИÑпользовать lo_import() на Ñтороне клиента через libpq могут вÑе." - -#: libpq/be-fsstubs.c:469 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл Ñервера \"%s\": %m" -#: libpq/be-fsstubs.c:491 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "не удалоÑÑŒ прочитать файл Ñервера \"%s\": %m" -#: libpq/be-fsstubs.c:521 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ lo_export() на Ñервере нужно быть Ñуперпользователем" - -#: libpq/be-fsstubs.c:522 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "ИÑпользовать lo_export() на Ñтороне клиента через libpq могут вÑе." - -#: libpq/be-fsstubs.c:547 +#: libpq/be-fsstubs.c:511 #, c-format msgid "could not create server file \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать файл Ñервера \"%s\": %m" -#: libpq/be-fsstubs.c:559 +#: libpq/be-fsstubs.c:523 #, c-format msgid "could not write server file \"%s\": %m" msgstr "не удалоÑÑŒ запиÑать файл Ñервера \"%s\": %m" -#: libpq/be-fsstubs.c:813 +#: libpq/be-fsstubs.c:752 #, c-format msgid "large object read request is too large" msgstr "при чтении большого объекта запрошен чрезмерный размер" -#: libpq/be-fsstubs.c:855 utils/adt/genfile.c:212 utils/adt/genfile.c:253 +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 +#: utils/adt/genfile.c:306 #, c-format msgid "requested length cannot be negative" msgstr "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° не может быть отрицательной" -#: libpq/be-secure-openssl.c:197 +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 +#: storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 +#: storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 #, c-format -msgid "could not create SSL context: %s" -msgstr "не удалоÑÑŒ Ñоздать контекÑÑ‚ SSL: %s" +msgid "permission denied for large object %u" +msgstr "нет доÑтупа к большому объекту %u" -#: libpq/be-secure-openssl.c:225 +#: libpq/be-secure-common.c:91 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "не удалоÑÑŒ загрузить Ñертификат Ñервера \"%s\": %s" +msgid "could not read from command \"%s\": %m" +msgstr "не удалоÑÑŒ прочитать вывод команды \"%s\": %m" + +#: libpq/be-secure-common.c:109 +#, c-format +msgid "command \"%s\" failed" +msgstr "ошибка команды \"%s\"" -#: libpq/be-secure-openssl.c:234 +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "не удалоÑÑŒ обратитьÑÑ Ðº файлу закрытого ключа \"%s\": %m" -#: libpq/be-secure-openssl.c:243 +#: libpq/be-secure-common.c:148 #, c-format msgid "private key file \"%s\" is not a regular file" msgstr "файл закрытого ключа \"%s\" не ÑвлÑетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¼" -#: libpq/be-secure-openssl.c:258 +#: libpq/be-secure-common.c:163 #, c-format msgid "private key file \"%s\" must be owned by the database user or root" msgstr "" "файл закрытого ключа \"%s\" должен принадлежать пользователю, запуÑкающему " "Ñервер, или root" -#: libpq/be-secure-openssl.c:281 +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" msgstr "к файлу закрытого ключа \"%s\" имеют доÑтуп вÑе или группа" -#: libpq/be-secure-openssl.c:283 +#: libpq/be-secure-common.c:188 #, c-format msgid "" "File must have permissions u=rw (0600) or less if owned by the database " @@ -13208,157 +13961,199 @@ msgstr "" "он принадлежит пользователю Ñервера, либо u=rw,g=r (0640) или более Ñтрогие, " "еÑли он принадлежит root." -#: libpq/be-secure-openssl.c:300 +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "не удалоÑÑŒ Ñоздать контекÑÑ‚ SSL: %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "не удалоÑÑŒ загрузить Ñертификат Ñервера \"%s\": %s" + +#: libpq/be-secure-openssl.c:167 #, c-format msgid "" "private key file \"%s\" cannot be reloaded because it requires a passphrase" msgstr "" "файл закрытого ключа \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð³Ñ€ÑƒÐ·Ð¸Ñ‚ÑŒ, так как он защищён паролем" -#: libpq/be-secure-openssl.c:305 +#: libpq/be-secure-openssl.c:172 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "не удалоÑÑŒ загрузить файл закрытого ключа \"%s\": %s" -#: libpq/be-secure-openssl.c:314 +#: libpq/be-secure-openssl.c:181 #, c-format msgid "check of private key failed: %s" msgstr "ошибка при проверке закрытого ключа: %s" -#: libpq/be-secure-openssl.c:334 +#: libpq/be-secure-openssl.c:208 #, c-format msgid "could not set the cipher list (no valid ciphers available)" msgstr "не удалоÑÑŒ уÑтановить ÑпиÑок шифров (подходÑщие шифры отÑутÑтвуют)" -#: libpq/be-secure-openssl.c:352 +#: libpq/be-secure-openssl.c:226 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "не удалоÑÑŒ загрузить файл корневых Ñертификатов \"%s\": %s" -#: libpq/be-secure-openssl.c:379 +#: libpq/be-secure-openssl.c:253 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "файл Ñо ÑпиÑком отзыва Ñертификатов SSL \"%s\" игнорируетÑÑ" -#: libpq/be-secure-openssl.c:381 +#: libpq/be-secure-openssl.c:255 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "Библиотека SSL не поддерживает ÑпиÑки отзыва Ñертификатов." -#: libpq/be-secure-openssl.c:388 +#: libpq/be-secure-openssl.c:262 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "" "не удалоÑÑŒ загрузить файл Ñо ÑпиÑком отзыва Ñертификатов SSL \"%s\": %s" -#: libpq/be-secure-openssl.c:469 +#: libpq/be-secure-openssl.c:337 #, c-format msgid "could not initialize SSL connection: SSL context not set up" msgstr "" "инициализировать SSL-подключение не удалоÑÑŒ: контекÑÑ‚ SSL не уÑтановлен" -#: libpq/be-secure-openssl.c:477 +#: libpq/be-secure-openssl.c:345 #, c-format msgid "could not initialize SSL connection: %s" msgstr "инициализировать SSL-подключение не удалоÑÑŒ: %s" -#: libpq/be-secure-openssl.c:485 +#: libpq/be-secure-openssl.c:353 #, c-format msgid "could not set SSL socket: %s" msgstr "не удалоÑÑŒ Ñоздать SSL-Ñокет: %s" -#: libpq/be-secure-openssl.c:540 +#: libpq/be-secure-openssl.c:408 #, c-format msgid "could not accept SSL connection: %m" msgstr "не удалоÑÑŒ принÑть SSL-подключение: %m" -#: libpq/be-secure-openssl.c:544 libpq/be-secure-openssl.c:555 +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "не удалоÑÑŒ принÑть SSL-подключение: обрыв данных" -#: libpq/be-secure-openssl.c:549 +#: libpq/be-secure-openssl.c:417 #, c-format msgid "could not accept SSL connection: %s" msgstr "не удалоÑÑŒ принÑть SSL-подключение: %s" -#: libpq/be-secure-openssl.c:560 libpq/be-secure-openssl.c:699 -#: libpq/be-secure-openssl.c:759 +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 +#: libpq/be-secure-openssl.c:623 #, c-format msgid "unrecognized SSL error code: %d" msgstr "нераÑпознанный код ошибки SSL: %d" -#: libpq/be-secure-openssl.c:602 +#: libpq/be-secure-openssl.c:470 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "Ð˜Ð¼Ñ SSL-Ñертификата включает нулевой байт" -#: libpq/be-secure-openssl.c:613 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "SSL-подключение от \"%s\"" - -#: libpq/be-secure-openssl.c:690 libpq/be-secure-openssl.c:750 +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 #, c-format msgid "SSL error: %s" msgstr "ошибка SSL: %s" -#: libpq/be-secure-openssl.c:1179 +#: libpq/be-secure-openssl.c:788 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "не удалоÑÑŒ открыть файл параметров DH \"%s\": %m" + +#: libpq/be-secure-openssl.c:800 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "не удалоÑÑŒ загрузить файл параметров DH: %s" + +#: libpq/be-secure-openssl.c:810 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "неверные параметры DH: %s" + +#: libpq/be-secure-openssl.c:818 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "неверные параметры DH: p - не проÑтое чиÑло" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "" +"неверные параметры DH: нет подходÑщего генератора или небезопаÑное проÑтое " +"чиÑло" + +#: libpq/be-secure-openssl.c:981 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: не удалоÑÑŒ загрузить параметры DH" + +#: libpq/be-secure-openssl.c:989 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: не удалоÑÑŒ задать параметры DH: %s" + +#: libpq/be-secure-openssl.c:1013 #, c-format msgid "ECDH: unrecognized curve name: %s" msgstr "ECDH: нераÑпознанное Ð¸Ð¼Ñ ÐºÑ€Ð¸Ð²Ð¾Ð¹: %s" -#: libpq/be-secure-openssl.c:1188 +#: libpq/be-secure-openssl.c:1022 #, c-format msgid "ECDH: could not create key" msgstr "ECDH: не удалоÑÑŒ Ñоздать ключ" -#: libpq/be-secure-openssl.c:1216 +#: libpq/be-secure-openssl.c:1050 msgid "no SSL error reported" msgstr "нет ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибке SSL" -#: libpq/be-secure-openssl.c:1220 +#: libpq/be-secure-openssl.c:1054 #, c-format msgid "SSL error code %lu" msgstr "код ошибки SSL: %lu" -#: libpq/be-secure.c:188 libpq/be-secure.c:274 +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "SSL-подключение от \"%s\"" + +#: libpq/be-secure.c:196 libpq/be-secure.c:284 #, c-format msgid "terminating connection due to unexpected postmaster exit" msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за неожиданного Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ процеÑÑа" -#: libpq/crypt.c:51 +#: libpq/crypt.c:52 #, c-format msgid "Role \"%s\" does not exist." msgstr "Роль \"%s\" не ÑущеÑтвует." -#: libpq/crypt.c:61 +#: libpq/crypt.c:62 #, c-format msgid "User \"%s\" has no password assigned." msgstr "Пользователь \"%s\" не имеет паролÑ." -#: libpq/crypt.c:76 -#, c-format -msgid "User \"%s\" has an empty password." -msgstr "У Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" пуÑтой пароль." - -#: libpq/crypt.c:87 +#: libpq/crypt.c:80 #, c-format msgid "User \"%s\" has an expired password." msgstr "Срок Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" иÑтёк." -#: libpq/crypt.c:242 +#: libpq/crypt.c:182 #, c-format msgid "User \"%s\" has a password that cannot be used with MD5 authentication." msgstr "" "Пользователь \"%s\" имеет пароль, неподходÑщий Ð´Ð»Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ по MD5." -#: libpq/crypt.c:251 libpq/crypt.c:292 libpq/crypt.c:316 libpq/crypt.c:327 +#: libpq/crypt.c:206 libpq/crypt.c:247 libpq/crypt.c:271 #, c-format msgid "Password does not match for user \"%s\"." msgstr "Пароль не подходит Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"." -#: libpq/crypt.c:338 +#: libpq/crypt.c:290 #, c-format msgid "Password of user \"%s\" is in unrecognized format." msgstr "Пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" предÑтавлен в неизвеÑтном формате." @@ -13367,8 +14162,8 @@ msgstr "Пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" предÑтавлен в #, c-format msgid "authentication file token too long, skipping: \"%s\"" msgstr "" -"Ñлишком длинный Ñлемент в файле конфигурации безопаÑноÑти пропуÑкаетÑÑ: \"%s" -"\"" +"Ñлишком длинный Ñлемент в файле конфигурации безопаÑноÑти пропуÑкаетÑÑ: \"" +"%s\"" #: libpq/hba.c:407 #, c-format @@ -13382,335 +14177,340 @@ msgstr "" msgid "authentication file line too long" msgstr "Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñтрока в файле конфигурации безопаÑноÑти" -#: libpq/hba.c:510 libpq/hba.c:864 libpq/hba.c:884 libpq/hba.c:922 -#: libpq/hba.c:972 libpq/hba.c:986 libpq/hba.c:1008 libpq/hba.c:1017 -#: libpq/hba.c:1038 libpq/hba.c:1051 libpq/hba.c:1071 libpq/hba.c:1093 -#: libpq/hba.c:1105 libpq/hba.c:1161 libpq/hba.c:1181 libpq/hba.c:1195 -#: libpq/hba.c:1214 libpq/hba.c:1225 libpq/hba.c:1240 libpq/hba.c:1258 -#: libpq/hba.c:1274 libpq/hba.c:1286 libpq/hba.c:1323 libpq/hba.c:1364 -#: libpq/hba.c:1377 libpq/hba.c:1399 libpq/hba.c:1411 libpq/hba.c:1429 -#: libpq/hba.c:1479 libpq/hba.c:1518 libpq/hba.c:1529 libpq/hba.c:1546 -#: libpq/hba.c:1556 libpq/hba.c:1614 libpq/hba.c:1652 libpq/hba.c:1668 -#: libpq/hba.c:1767 libpq/hba.c:1856 libpq/hba.c:1875 libpq/hba.c:1904 -#: libpq/hba.c:1917 libpq/hba.c:1940 libpq/hba.c:1962 libpq/hba.c:1976 -#: tsearch/ts_locale.c:182 +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 +#: libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 +#: libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 +#: libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 +#: libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 libpq/hba.c:1367 +#: libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 +#: libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 +#: libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 +#: libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 +#: libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 +#: libpq/hba.c:1997 libpq/hba.c:2011 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "Ñтрока %d файла конфигурации \"%s\"" #. translator: the second %s is a list of auth methods -#: libpq/hba.c:862 +#: libpq/hba.c:865 #, c-format msgid "" "authentication option \"%s\" is only valid for authentication methods %s" msgstr "параметр проверки подлинноÑти \"%s\" допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð² %s" -#: libpq/hba.c:882 +#: libpq/hba.c:885 #, c-format msgid "authentication method \"%s\" requires argument \"%s\" to be set" msgstr "" "Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° проверки подлинноÑти \"%s\" требуетÑÑ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»Ð¸Ñ‚ÑŒ аргумент \"%s\"" -#: libpq/hba.c:910 +#: libpq/hba.c:913 #, c-format msgid "missing entry in file \"%s\" at end of line %d" msgstr "отÑутÑтвует запиÑÑŒ в файле \"%s\" в конце Ñтроки %d" -#: libpq/hba.c:921 +#: libpq/hba.c:924 #, c-format msgid "multiple values in ident field" msgstr "множеÑтвенные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² поле ident" -#: libpq/hba.c:970 +#: libpq/hba.c:973 #, c-format msgid "multiple values specified for connection type" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¾ неÑколько значений" -#: libpq/hba.c:971 +#: libpq/hba.c:974 #, c-format msgid "Specify exactly one connection type per line." msgstr "Определите в Ñтроке единÑтвенный тип подключениÑ." -#: libpq/hba.c:985 +#: libpq/hba.c:988 #, c-format msgid "local connections are not supported by this build" msgstr "локальные Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ðµ поддерживаютÑÑ Ð² Ñтой Ñборке" -#: libpq/hba.c:1006 +#: libpq/hba.c:1009 #, c-format msgid "hostssl record cannot match because SSL is disabled" msgstr "запиÑÑŒ Ñ hostssl недейÑтвительна, так как поддержка SSL отключена" -#: libpq/hba.c:1007 +#: libpq/hba.c:1010 #, c-format msgid "Set ssl = on in postgresql.conf." msgstr "УÑтановите ssl = on в postgresql.conf." -#: libpq/hba.c:1015 +#: libpq/hba.c:1018 #, c-format msgid "hostssl record cannot match because SSL is not supported by this build" msgstr "" "запиÑÑŒ Ñ hostssl недейÑтвительна, так как SSL не поддерживаетÑÑ Ð² Ñтой Ñборке" -#: libpq/hba.c:1016 +#: libpq/hba.c:1019 #, c-format msgid "Compile with --with-openssl to use SSL connections." -msgstr "Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ SSL Ñкомпилируйте posgresql Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ --with-openssl." +msgstr "Ð”Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ SSL Ñкомпилируйте postgresql Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ --with-openssl." -#: libpq/hba.c:1036 +#: libpq/hba.c:1039 #, c-format msgid "invalid connection type \"%s\"" msgstr "неверный тип Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ \"%s\"" -#: libpq/hba.c:1050 +#: libpq/hba.c:1053 #, c-format msgid "end-of-line before database specification" msgstr "конец Ñтроки перед определением базы данных" -#: libpq/hba.c:1070 +#: libpq/hba.c:1073 #, c-format msgid "end-of-line before role specification" msgstr "конец Ñтроки перед определением роли" -#: libpq/hba.c:1092 +#: libpq/hba.c:1095 #, c-format msgid "end-of-line before IP address specification" msgstr "конец Ñтроки перед определением IP-адреÑов" -#: libpq/hba.c:1103 +#: libpq/hba.c:1106 #, c-format msgid "multiple values specified for host address" msgstr "Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа узла указано неÑколько значений" -#: libpq/hba.c:1104 +#: libpq/hba.c:1107 #, c-format msgid "Specify one address range per line." msgstr "Определите в Ñтроке один диапазон адреÑов." -#: libpq/hba.c:1159 +#: libpq/hba.c:1162 #, c-format msgid "invalid IP address \"%s\": %s" msgstr "неверный IP-Ð°Ð´Ñ€ÐµÑ \"%s\": %s" -#: libpq/hba.c:1179 +#: libpq/hba.c:1182 #, c-format msgid "specifying both host name and CIDR mask is invalid: \"%s\"" msgstr "указать одновременно и Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð°, и маÑку CIDR нельзÑ: \"%s\"" -#: libpq/hba.c:1193 +#: libpq/hba.c:1196 #, c-format msgid "invalid CIDR mask in address \"%s\"" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¼Ð°Ñка CIDR в адреÑе \"%s\"" -#: libpq/hba.c:1212 +#: libpq/hba.c:1215 #, c-format msgid "end-of-line before netmask specification" msgstr "конец Ñтроки перед определением маÑки Ñети" -#: libpq/hba.c:1213 +#: libpq/hba.c:1216 #, c-format msgid "" "Specify an address range in CIDR notation, or provide a separate netmask." msgstr "" "Укажите диапазон адреÑов в формате CIDR или задайте отдельную маÑку Ñети." -#: libpq/hba.c:1224 +#: libpq/hba.c:1227 #, c-format msgid "multiple values specified for netmask" msgstr "Ð´Ð»Ñ Ñетевой маÑки указано неÑколько значений" -#: libpq/hba.c:1238 +#: libpq/hba.c:1241 #, c-format msgid "invalid IP mask \"%s\": %s" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¼Ð°Ñка IP \"%s\": %s" -#: libpq/hba.c:1257 +#: libpq/hba.c:1260 #, c-format msgid "IP address and mask do not match" msgstr "IP-Ð°Ð´Ñ€ÐµÑ Ð½Ðµ ÑоответÑтвует маÑке" -#: libpq/hba.c:1273 +#: libpq/hba.c:1276 #, c-format msgid "end-of-line before authentication method" msgstr "конец Ñтроки перед методом проверки подлинноÑти" -#: libpq/hba.c:1284 +#: libpq/hba.c:1287 #, c-format msgid "multiple values specified for authentication type" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° проверки подлинноÑти указано неÑколько значений" -#: libpq/hba.c:1285 +#: libpq/hba.c:1288 #, c-format msgid "Specify exactly one authentication type per line." msgstr "Определите в Ñтроке единÑтвенный тип проверки подлинноÑти." -#: libpq/hba.c:1362 +#: libpq/hba.c:1365 #, c-format msgid "invalid authentication method \"%s\"" msgstr "неверный метод проверки подлинноÑти \"%s\"" -#: libpq/hba.c:1375 +#: libpq/hba.c:1378 #, c-format msgid "invalid authentication method \"%s\": not supported by this build" msgstr "" "неверный метод проверки подлинноÑти \"%s\": не поддерживаетÑÑ Ð² Ñтой Ñборке" -#: libpq/hba.c:1398 +#: libpq/hba.c:1401 #, c-format msgid "gssapi authentication is not supported on local sockets" msgstr "проверка подлинноÑти gssapi Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… Ñокетов не поддерживаетÑÑ" -#: libpq/hba.c:1410 +#: libpq/hba.c:1413 #, c-format msgid "peer authentication is only supported on local sockets" msgstr "проверка подлинноÑти peer поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… Ñокетов" -#: libpq/hba.c:1428 +#: libpq/hba.c:1431 #, c-format msgid "cert authentication is only supported on hostssl connections" msgstr "" "проверка подлинноÑти cert поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ hostssl" -#: libpq/hba.c:1478 +#: libpq/hba.c:1481 #, c-format msgid "authentication option not in name=value format: %s" msgstr "параметр проверки подлинноÑти указан не в формате имÑ=значение: %s" -#: libpq/hba.c:1517 +#: libpq/hba.c:1522 #, c-format msgid "" -"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or " -"ldapurl together with ldapprefix" +"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, " +"ldapsearchfilter, or ldapurl together with ldapprefix" msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать ldapbasedn, ldapbinddn, ldapbindpasswd, " -"ldapsearchattribute или ldapurl вмеÑте Ñ ldapprefix" +"ldapsearchattribute, ldapsearchfilter или ldapurl вмеÑте Ñ ldapprefix" -#: libpq/hba.c:1528 +#: libpq/hba.c:1533 #, c-format msgid "" -"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix" -"\", or \"ldapsuffix\" to be set" +"authentication method \"ldap\" requires argument \"ldapbasedn\", " +"\"ldapprefix\", or \"ldapsuffix\" to be set" msgstr "" "Ð´Ð»Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° проверки подлинноÑти \"ldap\" требуетÑÑ ÑƒÑтановить аргументы " "\"ldapbasedn\" и \"ldapprefix\" или \"ldapsuffix\"" -#: libpq/hba.c:1545 +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать ldapsearchattribute вмеÑте Ñ ldapsearchfilter" + +#: libpq/hba.c:1566 #, c-format msgid "list of RADIUS servers cannot be empty" msgstr "ÑпиÑок Ñерверов RADIUS не может быть пуÑтым" -#: libpq/hba.c:1555 +#: libpq/hba.c:1576 #, c-format msgid "list of RADIUS secrets cannot be empty" msgstr "ÑпиÑок Ñекретов RADIUS не может быть пуÑтым" -#: libpq/hba.c:1608 +#: libpq/hba.c:1629 #, c-format -msgid "the number of %s (%i) must be 1 or the same as the number of %s (%i)" +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" msgstr "" -"количеÑтво Ñлементов %s (%i) должно равнÑтьÑÑ 1 или количеÑтву Ñлементов %s " -"(%i)" +"количеÑтво Ñлементов %s (%d) должно равнÑтьÑÑ 1 или количеÑтву Ñлементов %s (" +"%d)" -#: libpq/hba.c:1642 +#: libpq/hba.c:1663 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspi и cert" -#: libpq/hba.c:1651 +#: libpq/hba.c:1672 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "clientcert можно определить только в Ñтроках \"hostssl\"" -#: libpq/hba.c:1667 +#: libpq/hba.c:1688 #, c-format msgid "clientcert can not be set to 0 when using \"cert\" authentication" msgstr "" "clientcert Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÑтановить в 0 при иÑпользовании проверки подлинноÑти " "\"cert\"" -#: libpq/hba.c:1704 +#: libpq/hba.c:1725 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "не удалоÑÑŒ разобрать URL-Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": %s" -#: libpq/hba.c:1714 +#: libpq/hba.c:1736 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ñхема в URL-адреÑе LDAP: %s" -#: libpq/hba.c:1732 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "фильтры в URL-адреÑах LDAP не поддерживаютÑÑ" - -#: libpq/hba.c:1741 +#: libpq/hba.c:1760 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "URL-адреÑа LDAP не поддерживаютÑÑ Ð² Ñтой ОС" -#: libpq/hba.c:1766 +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "неверное значение ldapscheme: \"%s\"" + +#: libpq/hba.c:1796 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "неверный номер порта LDAP: \"%s\"" -#: libpq/hba.c:1807 libpq/hba.c:1814 +#: libpq/hba.c:1842 libpq/hba.c:1849 msgid "gssapi and sspi" msgstr "gssapi и sspi" -#: libpq/hba.c:1823 libpq/hba.c:1832 +#: libpq/hba.c:1858 libpq/hba.c:1867 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1854 +#: libpq/hba.c:1889 #, c-format msgid "could not parse RADIUS server list \"%s\"" msgstr "не удалоÑÑŒ разобрать ÑпиÑок Ñерверов RADIUS \"%s\"" -#: libpq/hba.c:1902 +#: libpq/hba.c:1937 #, c-format msgid "could not parse RADIUS port list \"%s\"" msgstr "не удалоÑÑŒ разобрать ÑпиÑок портов RADIUS \"%s\"" -#: libpq/hba.c:1916 +#: libpq/hba.c:1951 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "неверный номер порта RADIUS: \"%s\"" -#: libpq/hba.c:1938 +#: libpq/hba.c:1973 #, c-format msgid "could not parse RADIUS secret list \"%s\"" msgstr "не удалоÑÑŒ разобрать ÑпиÑок Ñекретов RADIUS \"%s\"" -#: libpq/hba.c:1960 +#: libpq/hba.c:1995 #, c-format msgid "could not parse RADIUS identifiers list \"%s\"" msgstr "не удалоÑÑŒ разобрать ÑпиÑок идентификаторов RADIUS \"%s\"" -#: libpq/hba.c:1974 +#: libpq/hba.c:2009 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "нераÑпознанное Ð¸Ð¼Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° проверки подлинноÑти: \"%s\"" -#: libpq/hba.c:2107 libpq/hba.c:2507 guc-file.l:593 +#: libpq/hba.c:2142 libpq/hba.c:2550 guc-file.l:595 #, c-format msgid "could not open configuration file \"%s\": %m" msgstr "открыть файл конфигурации \"%s\" не удалоÑÑŒ: %m" -#: libpq/hba.c:2158 +#: libpq/hba.c:2193 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "файл конфигурации \"%s\" не Ñодержит запиÑей" -#: libpq/hba.c:2663 +#: libpq/hba.c:2706 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "неверное регулÑрное выражение \"%s\": %s" -#: libpq/hba.c:2723 +#: libpq/hba.c:2766 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "ошибка при поиÑке по регулÑрному выражению Ð´Ð»Ñ \"%s\": %s" -#: libpq/hba.c:2742 +#: libpq/hba.c:2785 #, c-format msgid "" "regular expression \"%s\" has no subexpressions as requested by " @@ -13719,103 +14519,103 @@ msgstr "" "в регулÑрном выражении \"%s\" нет подвыражений, требуемых Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ñ‚Ð½Ð¾Ð¹ " "ÑÑылки в \"%s\"" -#: libpq/hba.c:2839 +#: libpq/hba.c:2882 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "" -"указанное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (%s) не Ñовпадает Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ прошедшего проверку " -"(%s)" +"указанное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (%s) не Ñовпадает Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ прошедшего проверку (" +"%s)" -#: libpq/hba.c:2859 +#: libpq/hba.c:2902 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "" "нет ÑоответÑÑ‚Ð²Ð¸Ñ Ð² файле ÑопоÑтавлений \"%s\" Ð´Ð»Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\", " "прошедшего проверку как \"%s\"" -#: libpq/hba.c:2892 +#: libpq/hba.c:2935 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл ÑопоÑтавлений пользователей \"%s\": %m" -#: libpq/pqcomm.c:201 +#: libpq/pqcomm.c:220 #, c-format msgid "could not set socket to nonblocking mode: %m" msgstr "не удалоÑÑŒ перевеÑти Ñокет в неблокирующий режим: %m" -#: libpq/pqcomm.c:355 +#: libpq/pqcomm.c:374 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" -msgstr "длина пути доменного Ñокета \"%s\" превышает предел (%d байт)" +msgstr "длина пути Unix-Ñокета \"%s\" превышает предел (%d байт)" -#: libpq/pqcomm.c:376 +#: libpq/pqcomm.c:395 #, c-format msgid "could not translate host name \"%s\", service \"%s\" to address: %s" msgstr "перевеÑти Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð° \"%s\", Ñлужбы \"%s\" в Ð°Ð´Ñ€ÐµÑ Ð½Ðµ удалоÑÑŒ: %s" -#: libpq/pqcomm.c:380 +#: libpq/pqcomm.c:399 #, c-format msgid "could not translate service \"%s\" to address: %s" msgstr "не удалоÑÑŒ перевеÑти Ð¸Ð¼Ñ Ñлужбы \"%s\" в адреÑ: %s" -#: libpq/pqcomm.c:407 +#: libpq/pqcomm.c:426 #, c-format msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" msgstr "" "не удалоÑÑŒ привÑзатьÑÑ ÐºÐ¾ вÑем запрошенным адреÑам: превышен предел " "MAXLISTEN (%d)" -#: libpq/pqcomm.c:416 +#: libpq/pqcomm.c:435 msgid "IPv4" msgstr "IPv4" -#: libpq/pqcomm.c:420 +#: libpq/pqcomm.c:439 msgid "IPv6" msgstr "IPv6" -#: libpq/pqcomm.c:425 +#: libpq/pqcomm.c:444 msgid "Unix" msgstr "Unix" -#: libpq/pqcomm.c:430 +#: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" msgstr "нераÑпознанное ÑемейÑтво адреÑов: %d" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:456 +#: libpq/pqcomm.c:475 #, c-format msgid "could not create %s socket for address \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать Ñокет %s Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа \"%s\": %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:482 +#: libpq/pqcomm.c:501 #, c-format msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" msgstr "ошибка в setsockopt(SO_REUSEADDR) Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа %s \"%s\": %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:499 +#: libpq/pqcomm.c:518 #, c-format msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" msgstr "ошибка в setsockopt(IPV6_V6ONLY) Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑа %s \"%s\": %m" #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:519 +#: libpq/pqcomm.c:538 #, c-format msgid "could not bind %s address \"%s\": %m" msgstr "не удалоÑÑŒ привÑзатьÑÑ Ðº адреÑу %s \"%s\": %m" -#: libpq/pqcomm.c:522 +#: libpq/pqcomm.c:541 #, c-format msgid "" "Is another postmaster already running on port %d? If not, remove socket file " "\"%s\" and retry." msgstr "" -"Возможно порт %d занÑÑ‚ другим процеÑÑом postmaster? ЕÑли нет, удалите файл " -"\"%s\" и повторите попытку." +"Возможно порт %d занÑÑ‚ другим процеÑÑом postmaster? ЕÑли нет, удалите файл \"" +"%s\" и повторите попытку." -#: libpq/pqcomm.c:525 +#: libpq/pqcomm.c:544 #, c-format msgid "" "Is another postmaster already running on port %d? If not, wait a few seconds " @@ -13825,94 +14625,94 @@ msgstr "" "попытку через неÑколько Ñекунд." #. translator: first %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:558 +#: libpq/pqcomm.c:577 #, c-format msgid "could not listen on %s address \"%s\": %m" msgstr "не удалоÑÑŒ привÑзатьÑÑ Ðº адреÑу %s \"%s\": %m" -#: libpq/pqcomm.c:567 +#: libpq/pqcomm.c:586 #, c-format msgid "listening on Unix socket \"%s\"" -msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð¸Ñ‘Ð¼Ð° подключений открыт Ñокет Unix \"%s\"" +msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð¸Ñ‘Ð¼Ð° подключений открыт Unix-Ñокет \"%s\"" #. translator: first %s is IPv4 or IPv6 -#: libpq/pqcomm.c:573 +#: libpq/pqcomm.c:592 #, c-format msgid "listening on %s address \"%s\", port %d" msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð¸Ñ‘Ð¼Ð° подключений по адреÑу %s \"%s\" открыт порт %d" -#: libpq/pqcomm.c:656 +#: libpq/pqcomm.c:675 #, c-format msgid "group \"%s\" does not exist" msgstr "группа \"%s\" не ÑущеÑтвует" -#: libpq/pqcomm.c:666 +#: libpq/pqcomm.c:685 #, c-format msgid "could not set group of file \"%s\": %m" msgstr "не удалоÑÑŒ уÑтановить группу Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\": %m" -#: libpq/pqcomm.c:677 +#: libpq/pqcomm.c:696 #, c-format msgid "could not set permissions of file \"%s\": %m" msgstr "не удалоÑÑŒ уÑтановить права доÑтупа Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\": %m" -#: libpq/pqcomm.c:707 +#: libpq/pqcomm.c:726 #, c-format msgid "could not accept new connection: %m" msgstr "не удалоÑÑŒ принÑть новое подключение: %m" -#: libpq/pqcomm.c:908 +#: libpq/pqcomm.c:927 #, c-format msgid "there is no client connection" msgstr "нет клиентÑкого подключениÑ" -#: libpq/pqcomm.c:959 libpq/pqcomm.c:1055 +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 #, c-format msgid "could not receive data from client: %m" msgstr "не удалоÑÑŒ получить данные от клиента: %m" -#: libpq/pqcomm.c:1200 tcop/postgres.c:3913 +#: libpq/pqcomm.c:1219 tcop/postgres.c:4020 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за потери Ñинхронизации протокола" -#: libpq/pqcomm.c:1266 +#: libpq/pqcomm.c:1285 #, c-format msgid "unexpected EOF within message length word" msgstr "неожиданный обрыв данных в Ñлове длины ÑообщениÑ" -#: libpq/pqcomm.c:1277 +#: libpq/pqcomm.c:1296 #, c-format msgid "invalid message length" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° ÑообщениÑ" -#: libpq/pqcomm.c:1299 libpq/pqcomm.c:1312 +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 #, c-format msgid "incomplete message from client" msgstr "неполное Ñообщение от клиента" -#: libpq/pqcomm.c:1445 +#: libpq/pqcomm.c:1464 #, c-format msgid "could not send data to client: %m" msgstr "не удалоÑÑŒ поÑлать данные клиенту: %m" -#: libpq/pqformat.c:437 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "в Ñообщении не оÑталоÑÑŒ данных" -#: libpq/pqformat.c:557 libpq/pqformat.c:575 libpq/pqformat.c:596 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 #, c-format msgid "insufficient data left in message" msgstr "недоÑтаточно данных оÑталоÑÑŒ в Ñообщении" -#: libpq/pqformat.c:637 libpq/pqformat.c:666 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñтрока в Ñообщении" -#: libpq/pqformat.c:682 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "неверный формат ÑообщениÑ" @@ -13996,7 +14796,7 @@ msgstr " -i включить ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ TCP/IP\n" #: main/main.c:340 #, c-format msgid " -k DIRECTORY Unix-domain socket location\n" -msgstr " -k КÐТÐЛОГ раÑположение доменных Ñокетов Unix\n" +msgstr " -k КÐТÐЛОГ раÑположение Unix-Ñокетов\n" #: main/main.c:342 #, c-format @@ -14167,8 +14967,8 @@ msgstr "" #: main/main.c:373 #, c-format msgid "" -" DBNAME database name (mandatory argument in bootstrapping " -"mode)\n" +" DBNAME database name (mandatory argument in bootstrapping mode)" +"\n" msgstr "" " ИМЯ_БД Ð¸Ð¼Ñ Ð±Ð°Ð·Ñ‹ данных (необходимо в режиме инициализации)\n" @@ -14237,14 +15037,14 @@ msgstr "раÑширенный тип узла \"%s\" уже ÑущеÑтвуе msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "методы раÑширенного узла \"%s\" не зарегиÑтрированы" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1844 -#: parser/parse_coerce.c:1872 parser/parse_coerce.c:1948 -#: parser/parse_expr.c:2089 parser/parse_func.c:598 parser/parse_oper.c:958 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "тип маÑÑива Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s не найден" -#: optimizer/path/joinrels.c:826 +#: optimizer/path/joinrels.c:831 #, c-format msgid "" "FULL JOIN is only supported with merge-joinable or hash-joinable join " @@ -14254,25 +15054,25 @@ msgstr "" "ÑлиÑнием или хеш-Ñоединение" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1200 +#: optimizer/plan/initsplan.c:1212 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s не может применÑтьÑÑ Ðº NULL-Ñодержащей Ñтороне внешнего ÑоединениÑ" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1542 parser/analyze.c:1622 parser/analyze.c:1819 -#: parser/analyze.c:2613 +#: optimizer/plan/planner.c:1802 parser/analyze.c:1655 parser/analyze.c:1854 +#: parser/analyze.c:2687 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%s неÑовмеÑтимо Ñ UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:2142 optimizer/plan/planner.c:4100 +#: optimizer/plan/planner.c:2374 optimizer/plan/planner.c:4093 #, c-format msgid "could not implement GROUP BY" msgstr "не удалоÑÑŒ реализовать GROUP BY" -#: optimizer/plan/planner.c:2143 optimizer/plan/planner.c:4101 -#: optimizer/plan/planner.c:4841 optimizer/prep/prepunion.c:928 +#: optimizer/plan/planner.c:2375 optimizer/plan/planner.c:4094 +#: optimizer/plan/planner.c:4837 optimizer/prep/prepunion.c:1080 #, c-format msgid "" "Some of the datatypes only support hashing, while others only support " @@ -14281,82 +15081,82 @@ msgstr "" "Одни типы данных поддерживают только хеширование, а другие - только " "Ñортировку." -#: optimizer/plan/planner.c:4840 +#: optimizer/plan/planner.c:4836 #, c-format msgid "could not implement DISTINCT" msgstr "не удалоÑÑŒ реализовать DISTINCT" -#: optimizer/plan/planner.c:5520 +#: optimizer/plan/planner.c:5519 #, c-format msgid "could not implement window PARTITION BY" msgstr "не удалоÑÑŒ реализовать PARTITION BY Ð´Ð»Ñ Ð¾ÐºÐ½Ð°" -#: optimizer/plan/planner.c:5521 +#: optimizer/plan/planner.c:5520 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "Столбцы, разбивающие окна, должны иметь Ñортируемые типы данных." -#: optimizer/plan/planner.c:5525 +#: optimizer/plan/planner.c:5524 #, c-format msgid "could not implement window ORDER BY" msgstr "не удалоÑÑŒ реализовать ORDER BY Ð´Ð»Ñ Ð¾ÐºÐ½Ð°" -#: optimizer/plan/planner.c:5526 +#: optimizer/plan/planner.c:5525 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "Столбцы, Ñортирующие окна, должны иметь Ñортируемые типы данных." -#: optimizer/plan/setrefs.c:413 +#: optimizer/plan/setrefs.c:414 #, c-format msgid "too many range table entries" msgstr "Ñлишком много Ñлементов RTE" -#: optimizer/prep/prepunion.c:483 +#: optimizer/prep/prepunion.c:544 #, c-format msgid "could not implement recursive UNION" msgstr "не удалоÑÑŒ реализовать рекурÑивный UNION" -#: optimizer/prep/prepunion.c:484 +#: optimizer/prep/prepunion.c:545 #, c-format msgid "All column datatypes must be hashable." msgstr "Ð’Ñе Ñтолбцы должны иметь хешируемые типы данных." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:927 +#: optimizer/prep/prepunion.c:1079 #, c-format msgid "could not implement %s" msgstr "не удалоÑÑŒ реализовать %s" -#: optimizer/util/clauses.c:4634 +#: optimizer/util/clauses.c:4923 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "Ð²Ð½ÐµÐ´Ñ€Ñ‘Ð½Ð½Ð°Ñ Ð² код SQL-Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\"" -#: optimizer/util/plancat.c:119 +#: optimizer/util/plancat.c:129 #, c-format msgid "cannot access temporary or unlogged relations during recovery" msgstr "" "обращатьÑÑ Ðº временным или нежурналируемым отношениÑм в процеÑÑе " "воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" -#: optimizer/util/plancat.c:619 +#: optimizer/util/plancat.c:653 #, c-format msgid "whole row unique index inference specifications are not supported" msgstr "" "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ñо ÑÑылкой на вÑÑŽ Ñтроку Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° уникального индекÑа не " "поддерживаютÑÑ" -#: optimizer/util/plancat.c:636 +#: optimizer/util/plancat.c:670 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "ограничению в ON CONFLICT не ÑоответÑтвует индекÑ" -#: optimizer/util/plancat.c:687 +#: optimizer/util/plancat.c:721 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" msgstr "ON CONFLICT DO UPDATE не поддерживаетÑÑ Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми-иÑключениÑми" -#: optimizer/util/plancat.c:792 +#: optimizer/util/plancat.c:826 #, c-format msgid "" "there is no unique or exclusion constraint matching the ON CONFLICT " @@ -14365,28 +15165,22 @@ msgstr "" "нет уникального Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ ограничениÑ-иÑключениÑ, ÑоответÑтвующего " "указанию ON CONFLICT" -#: parser/analyze.c:698 parser/analyze.c:1385 +#: parser/analyze.c:711 parser/analyze.c:1418 #, c-format msgid "VALUES lists must all be the same length" msgstr "ÑпиÑки VALUES должны иметь одинаковую длину" -#: parser/analyze.c:853 -#, c-format -msgid "ON CONFLICT clause is not supported with partitioned tables" -msgstr "" -"предложение ON CONFLICT Ñ Ñекционированными таблицами не поддерживаетÑÑ" - -#: parser/analyze.c:916 +#: parser/analyze.c:921 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT Ñодержит больше выражений, чем целевых Ñтолбцов" -#: parser/analyze.c:934 +#: parser/analyze.c:939 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT Ñодержит больше целевых Ñтолбцов, чем выражений" -#: parser/analyze.c:938 +#: parser/analyze.c:943 #, c-format msgid "" "The insertion source is a row expression containing the same number of " @@ -14395,29 +15189,29 @@ msgstr "" "ИÑточником данных ÑвлÑетÑÑ Ñтрока, Ð²ÐºÐ»ÑŽÑ‡Ð°ÑŽÑ‰Ð°Ñ Ñтолько же Ñтолбцов, Ñколько " "требуетÑÑ Ð´Ð»Ñ INSERT. Ð’Ñ‹ намеренно иÑпользовали Ñкобки?" -#: parser/analyze.c:1198 parser/analyze.c:1595 +#: parser/analyze.c:1229 parser/analyze.c:1628 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "SELECT ... INTO здеÑÑŒ не допуÑкаетÑÑ" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1527 parser/analyze.c:2792 +#: parser/analyze.c:1560 parser/analyze.c:2866 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть к VALUES" -#: parser/analyze.c:1746 +#: parser/analyze.c:1779 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "неверное предложение UNION/INTERSECT/EXCEPT ORDER BY" -#: parser/analyze.c:1747 +#: parser/analyze.c:1780 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "" "ДопуÑтимо иÑпользование только имён Ñтолбцов, но не выражений или функций." -#: parser/analyze.c:1748 +#: parser/analyze.c:1781 #, c-format msgid "" "Add the expression/function to every SELECT, or move the UNION into a FROM " @@ -14426,12 +15220,12 @@ msgstr "" "Добавьте выражение/функцию в каждый SELECT или перенеÑите UNION в " "предложение FROM." -#: parser/analyze.c:1809 +#: parser/analyze.c:1844 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO можно добавить только в первый SELECT в UNION/INTERSECT/EXCEPT" -#: parser/analyze.c:1881 +#: parser/analyze.c:1916 #, c-format msgid "" "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of " @@ -14440,155 +15234,155 @@ msgstr "" "оператор, ÑоÑтавлÑющий UNION/INTERSECT/EXCEPT, не может ÑÑылатьÑÑ Ð½Ð° другие " "Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ð° том же уровне запроÑа" -#: parser/analyze.c:1970 +#: parser/analyze.c:2005 #, c-format msgid "each %s query must have the same number of columns" msgstr "вÑе запроÑÑ‹ в %s должны возвращать одинаковое чиÑло Ñтолбцов" -#: parser/analyze.c:2363 +#: parser/analyze.c:2398 #, c-format msgid "RETURNING must have at least one column" msgstr "в RETURNING должен быть минимум один Ñтолбец" -#: parser/analyze.c:2404 +#: parser/analyze.c:2439 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "противоречивые ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ SCROLL и NO SCROLL" -#: parser/analyze.c:2423 +#: parser/analyze.c:2458 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSOR не может Ñодержать операторы, изменÑющие данные, в WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2431 +#: parser/analyze.c:2466 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %s не поддерживаетÑÑ" -#: parser/analyze.c:2434 +#: parser/analyze.c:2469 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "СохранÑемые курÑоры должны быть READ ONLY." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2442 +#: parser/analyze.c:2477 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %s не поддерживаетÑÑ" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2453 +#: parser/analyze.c:2488 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %s не поддерживаетÑÑ" -#: parser/analyze.c:2456 +#: parser/analyze.c:2491 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "ÐезавиÑимые курÑоры должны быть READ ONLY." -#: parser/analyze.c:2522 +#: parser/analyze.c:2557 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "" "в материализованных предÑтавлениÑÑ… не должны иÑпользоватьÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ñ‹, " "изменÑющие данные в WITH" -#: parser/analyze.c:2532 +#: parser/analyze.c:2567 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "" "в материализованных предÑтавлениÑÑ… не должны иÑпользоватьÑÑ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ðµ " "таблицы и предÑтавлениÑ" -#: parser/analyze.c:2542 +#: parser/analyze.c:2577 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "" "определÑть материализованные предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñо ÑвÑзанными параметрами нельзÑ" -#: parser/analyze.c:2554 +#: parser/analyze.c:2589 #, c-format msgid "materialized views cannot be UNLOGGED" msgstr "" "материализованные предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ðµ могут быть нежурналируемыми (UNLOGGED)" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2620 +#: parser/analyze.c:2694 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%s неÑовмеÑтимо Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ DISTINCT" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2627 +#: parser/analyze.c:2701 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%s неÑовмеÑтимо Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ GROUP BY" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2634 +#: parser/analyze.c:2708 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%s неÑовмеÑтимо Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ HAVING" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2641 +#: parser/analyze.c:2715 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%s неÑовмеÑтимо Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ñ‹Ð¼Ð¸ функциÑми" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2648 +#: parser/analyze.c:2722 #, c-format msgid "%s is not allowed with window functions" msgstr "%s неÑовмеÑтимо Ñ Ð¾ÐºÐ¾Ð½Ð½Ñ‹Ð¼Ð¸ функциÑми" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2655 +#: parser/analyze.c:2729 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "" "%s не допуÑкаетÑÑ Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñми, возвращающие множеÑтва, в ÑпиÑке результатов" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2734 +#: parser/analyze.c:2808 #, c-format msgid "%s must specify unqualified relation names" msgstr "Ð´Ð»Ñ %s нужно указывать неполные имена отношений" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2765 +#: parser/analyze.c:2839 #, c-format msgid "%s cannot be applied to a join" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к Ñоединению" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2774 +#: parser/analyze.c:2848 #, c-format msgid "%s cannot be applied to a function" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к функции" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2783 +#: parser/analyze.c:2857 #, c-format msgid "%s cannot be applied to a table function" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к табличной функции" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2801 +#: parser/analyze.c:2875 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к запроÑу WITH" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2810 +#: parser/analyze.c:2884 #, c-format msgid "%s cannot be applied to a named tuplestore" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ к именованному иÑточнику кортежей" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2827 +#: parser/analyze.c:2901 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "отношение \"%s\" в определении %s отÑутÑтвует в предложении FROM" @@ -14660,83 +15454,100 @@ msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в msgid "grouping operations are not allowed in window ROWS" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в указании ROWS Ð´Ð»Ñ Ð¾ÐºÐ½Ð°" -#: parser/parse_agg.c:454 +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в указании GROUPS Ð´Ð»Ñ Ð¾ÐºÐ½Ð°" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в указании GROUPS Ð´Ð»Ñ Ð¾ÐºÐ½Ð°" + +#: parser/parse_agg.c:461 msgid "aggregate functions are not allowed in check constraints" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в ограничениÑÑ…-проверках" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:463 msgid "grouping operations are not allowed in check constraints" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в ограничениÑÑ…-проверках" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:470 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… DEFAULT" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:472 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… DEFAULT" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:477 msgid "aggregate functions are not allowed in index expressions" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… индекÑов" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:479 msgid "grouping operations are not allowed in index expressions" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… индекÑов" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:484 msgid "aggregate functions are not allowed in index predicates" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в предикатах индекÑов" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:486 msgid "grouping operations are not allowed in index predicates" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в предикатах индекÑов" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:491 msgid "aggregate functions are not allowed in transform expressions" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… преобразований" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:493 msgid "grouping operations are not allowed in transform expressions" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… преобразований" -#: parser/parse_agg.c:491 +#: parser/parse_agg.c:498 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в параметрах EXECUTE" -#: parser/parse_agg.c:493 +#: parser/parse_agg.c:500 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в параметрах EXECUTE" -#: parser/parse_agg.c:498 +#: parser/parse_agg.c:505 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð²" -#: parser/parse_agg.c:500 +#: parser/parse_agg.c:507 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð²" -#: parser/parse_agg.c:505 -msgid "aggregate functions are not allowed in partition key expression" -msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражении ключа разбиениÑ" +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… ключа ÑекционированиÑ" -#: parser/parse_agg.c:507 -msgid "grouping operations are not allowed in partition key expression" -msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражении ключа разбиениÑ" +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "" +"операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… ключа ÑекционированиÑ" + +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в аргументах CALL" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в аргументах CALL" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:530 parser/parse_clause.c:1806 +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "агрегатные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в конÑтрукции %s" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:533 +#: parser/parse_agg.c:548 #, c-format msgid "grouping operations are not allowed in %s" msgstr "операции группировки Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в конÑтрукции %s" -#: parser/parse_agg.c:641 +#: parser/parse_agg.c:656 #, c-format msgid "" "outer-level aggregate cannot contain a lower-level variable in its direct " @@ -14745,83 +15556,104 @@ msgstr "" "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ÑƒÑ€Ð¾Ð²Ð½Ñ Ð½Ðµ может Ñодержать в Ñвоих аргументах " "переменные нижнего уровнÑ" -#: parser/parse_agg.c:712 +#: parser/parse_agg.c:735 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "" +"вызовы агрегатных функций не могут включать вызовы функций, возвращающих " +"множеÑтва" + +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 +#: parser/parse_func.c:866 +#, c-format +msgid "" +"You might be able to move the set-returning function into a LATERAL FROM " +"item." +msgstr "" +"ИÑправить Ñитуацию можно, перемеÑтив функцию, возвращающую множеÑтво, в " +"Ñлемент LATERAL FROM." + +#: parser/parse_agg.c:741 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "вызовы агрегатных функций не могут включать вызовы оконных функции" -#: parser/parse_agg.c:790 +#: parser/parse_agg.c:820 msgid "window functions are not allowed in JOIN conditions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… JOIN" -#: parser/parse_agg.c:797 +#: parser/parse_agg.c:827 msgid "window functions are not allowed in functions in FROM" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в функциÑÑ… во FROM" -#: parser/parse_agg.c:803 +#: parser/parse_agg.c:833 msgid "window functions are not allowed in policy expressions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… политик" -#: parser/parse_agg.c:815 +#: parser/parse_agg.c:846 msgid "window functions are not allowed in window definitions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в определении окна" -#: parser/parse_agg.c:847 +#: parser/parse_agg.c:878 msgid "window functions are not allowed in check constraints" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в ограничениÑÑ…-проверках" -#: parser/parse_agg.c:851 +#: parser/parse_agg.c:882 msgid "window functions are not allowed in DEFAULT expressions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… DEFAULT" -#: parser/parse_agg.c:854 +#: parser/parse_agg.c:885 msgid "window functions are not allowed in index expressions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… индекÑов" -#: parser/parse_agg.c:857 +#: parser/parse_agg.c:888 msgid "window functions are not allowed in index predicates" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в предикатах индекÑов" -#: parser/parse_agg.c:860 +#: parser/parse_agg.c:891 msgid "window functions are not allowed in transform expressions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… преобразований" -#: parser/parse_agg.c:863 +#: parser/parse_agg.c:894 msgid "window functions are not allowed in EXECUTE parameters" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в параметрах EXECUTE" -#: parser/parse_agg.c:866 +#: parser/parse_agg.c:897 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð²" -#: parser/parse_agg.c:869 -msgid "window functions are not allowed in partition key expression" -msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражении ключа разбиениÑ" +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… ключа ÑекционированиÑ" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в аргументах CALL" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:889 parser/parse_clause.c:1815 +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 #, c-format msgid "window functions are not allowed in %s" msgstr "оконные функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в конÑтрукции %s" -#: parser/parse_agg.c:923 parser/parse_clause.c:2649 +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 #, c-format msgid "window \"%s\" does not exist" msgstr "окно \"%s\" не ÑущеÑтвует" -#: parser/parse_agg.c:1008 +#: parser/parse_agg.c:1042 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "Ñлишком много наборов Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (при макÑимуме 4096)" -#: parser/parse_agg.c:1157 +#: parser/parse_agg.c:1191 #, c-format msgid "" "aggregate functions are not allowed in a recursive query's recursive term" msgstr "" "в рекурÑивной чаÑти рекурÑивного запроÑа агрегатные функции недопуÑтимы" -#: parser/parse_agg.c:1350 +#: parser/parse_agg.c:1384 #, c-format msgid "" "column \"%s.%s\" must appear in the GROUP BY clause or be used in an " @@ -14830,7 +15662,7 @@ msgstr "" "Ñтолбец \"%s.%s\" должен фигурировать в предложении GROUP BY или " "иÑпользоватьÑÑ Ð² агрегатной функции" -#: parser/parse_agg.c:1353 +#: parser/parse_agg.c:1387 #, c-format msgid "" "Direct arguments of an ordered-set aggregate must use only grouped columns." @@ -14838,13 +15670,13 @@ msgstr "" "ПрÑмые аргументы Ñортирующей агрегатной функции могут включать только " "группируемые Ñтолбцы." -#: parser/parse_agg.c:1358 +#: parser/parse_agg.c:1392 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "" "Ð¿Ð¾Ð´Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ñпользует негруппированный Ñтолбец \"%s.%s\" из внешнего запроÑа" -#: parser/parse_agg.c:1522 +#: parser/parse_agg.c:1556 #, c-format msgid "" "arguments to GROUPING must be grouping expressions of the associated query " @@ -14853,19 +15685,25 @@ msgstr "" "аргументами GROUPING должны быть Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ " "ÑоответÑтвующего ÑƒÑ€Ð¾Ð²Ð½Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа" -#: parser/parse_clause.c:192 +#: parser/parse_clause.c:199 #, c-format msgid "relation \"%s\" cannot be the target of a modifying statement" msgstr "отношение \"%s\" не может быть целевым в операторе, изменÑющем данные" -#: parser/parse_clause.c:651 +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "" +"функции, возвращающие множеÑтва, должны находитьÑÑ Ð½Ð° верхнем уровне FROM" + +#: parser/parse_clause.c:655 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "" "Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð¹ и той же функции Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ разные ÑпиÑки Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми " "Ñтолбцов" -#: parser/parse_clause.c:684 +#: parser/parse_clause.c:688 #, c-format msgid "" "ROWS FROM() with multiple functions cannot have a column definition list" @@ -14873,7 +15711,7 @@ msgstr "" "у ROWS FROM() Ñ Ð½ÐµÑколькими функциÑми не может быть ÑпиÑка Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми " "Ñтолбцов" -#: parser/parse_clause.c:685 +#: parser/parse_clause.c:689 #, c-format msgid "" "Put a separate column definition list for each function inside ROWS FROM()." @@ -14881,14 +15719,14 @@ msgstr "" "Добавьте отдельные ÑпиÑки Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми Ñтолбцов Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ функции в ROWS " "FROM()." -#: parser/parse_clause.c:691 +#: parser/parse_clause.c:695 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "" "у UNNEST() Ñ Ð½ÐµÑколькими аргументами не может быть ÑпиÑка Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми " "Ñтолбцов" -#: parser/parse_clause.c:692 +#: parser/parse_clause.c:696 #, c-format msgid "" "Use separate UNNEST() calls inside ROWS FROM(), and attach a column " @@ -14897,43 +15735,43 @@ msgstr "" "Ðапишите отдельные вызовы UNNEST() внутри ROWS FROM() и добавьте ÑпиÑок Ñ " "определениÑми Ñтолбцов к каждому." -#: parser/parse_clause.c:699 +#: parser/parse_clause.c:703 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "" "WITH ORDINALITY Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñо ÑпиÑком Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми Ñтолбцов" -#: parser/parse_clause.c:700 +#: parser/parse_clause.c:704 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "ПомеÑтите ÑпиÑок Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñми Ñтолбцов внутрь ROWS FROM()." -#: parser/parse_clause.c:804 +#: parser/parse_clause.c:807 #, c-format msgid "only one FOR ORDINALITY column is allowed" msgstr "FOR ORDINALITY допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñтолбца" -#: parser/parse_clause.c:865 +#: parser/parse_clause.c:868 #, c-format msgid "column name \"%s\" is not unique" msgstr "Ð¸Ð¼Ñ Ñтолбца \"%s\" не уникально" -#: parser/parse_clause.c:907 +#: parser/parse_clause.c:910 #, c-format msgid "namespace name \"%s\" is not unique" msgstr "Ð¸Ð¼Ñ Ð¿Ñ€Ð¾ÑтранÑтва имён \"%s\" не уникально" -#: parser/parse_clause.c:917 +#: parser/parse_clause.c:920 #, c-format msgid "only one default namespace is allowed" msgstr "допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ одно проÑтранÑтво имён по умолчанию" -#: parser/parse_clause.c:978 +#: parser/parse_clause.c:982 #, c-format msgid "tablesample method %s does not exist" msgstr "метод %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€ÐºÐ¸ не ÑущеÑтвует" -#: parser/parse_clause.c:1000 +#: parser/parse_clause.c:1004 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" @@ -14941,103 +15779,116 @@ msgstr[0] "метод %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€ÐºÐ¸ требует msgstr[1] "метод %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€ÐºÐ¸ требует аргументов: %d, получено: %d" msgstr[2] "метод %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€ÐºÐ¸ требует аргументов: %d, получено: %d" -#: parser/parse_clause.c:1034 +#: parser/parse_clause.c:1038 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "метод %s Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð±Ð¾Ñ€ÐºÐ¸ не поддерживает REPEATABLE" -#: parser/parse_clause.c:1196 +#: parser/parse_clause.c:1208 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "" "предложение TABLESAMPLE можно применÑть только к таблицам и " "материализованным предÑтавлениÑм" -#: parser/parse_clause.c:1366 +#: parser/parse_clause.c:1378 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "Ð¸Ð¼Ñ Ñтолбца \"%s\" фигурирует в предложении USING неоднократно" -#: parser/parse_clause.c:1381 +#: parser/parse_clause.c:1393 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "Ð¸Ð¼Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ Ñтолбца \"%s\" фигурирует в таблице Ñлева неоднократно" -#: parser/parse_clause.c:1390 +#: parser/parse_clause.c:1402 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "в таблице Ñлева нет Ñтолбца \"%s\", указанного в предложении USING" -#: parser/parse_clause.c:1404 +#: parser/parse_clause.c:1416 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "Ð¸Ð¼Ñ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ Ñтолбца \"%s\" фигурирует в таблице Ñправа неоднократно" -#: parser/parse_clause.c:1413 +#: parser/parse_clause.c:1425 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "в таблице Ñправа нет Ñтолбца \"%s\", указанного в предложении USING" -#: parser/parse_clause.c:1467 +#: parser/parse_clause.c:1479 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "Ñлишком много запиÑей в ÑпиÑке пÑевдонимов Ñтолбца \"%s\"" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1776 +#: parser/parse_clause.c:1788 #, c-format msgid "argument of %s must not contain variables" msgstr "аргумент %s не может Ñодержать переменные" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1941 +#: parser/parse_clause.c:1953 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "выражение %s \"%s\" неоднозначно" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1970 +#: parser/parse_clause.c:1982 #, c-format msgid "non-integer constant in %s" msgstr "не целочиÑÐ»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð½Ñтанта в %s" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1992 +#: parser/parse_clause.c:2004 #, c-format msgid "%s position %d is not in select list" msgstr "в ÑпиÑке выборки %s нет Ñлемента %d" -#: parser/parse_clause.c:2433 +#: parser/parse_clause.c:2445 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE имеет ограничение в 12 Ñлементов" -#: parser/parse_clause.c:2637 +#: parser/parse_clause.c:2651 #, c-format msgid "window \"%s\" is already defined" msgstr "окно \"%s\" уже определено" -#: parser/parse_clause.c:2698 +#: parser/parse_clause.c:2712 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "переопределить предложение PARTITION BY Ð´Ð»Ñ Ð¾ÐºÐ½Ð° \"%s\" нельзÑ" -#: parser/parse_clause.c:2710 +#: parser/parse_clause.c:2724 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "переопределить предложение ORDER BY Ð´Ð»Ñ Ð¾ÐºÐ½Ð° \"%s\" нельзÑ" -#: parser/parse_clause.c:2740 parser/parse_clause.c:2746 +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "Ñкопировать окно \"%s\", имеющее предложение рамки, нельзÑ" -#: parser/parse_clause.c:2748 +#: parser/parse_clause.c:2762 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "Уберите Ñкобки в предложении OVER." -#: parser/parse_clause.c:2814 +#: parser/parse_clause.c:2782 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "" +"Ð´Ð»Ñ RANGE Ñо Ñмещением PRECEDING/FOLLOWING требуетÑÑ Ñ€Ð¾Ð²Ð½Ð¾ один Ñтолбец в " +"ORDER BY" + +#: parser/parse_clause.c:2805 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° GROUPS требуетÑÑ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ ORDER BY" + +#: parser/parse_clause.c:2875 #, c-format msgid "" "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument " @@ -15046,68 +15897,68 @@ msgstr "" "Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð¾Ð¹ функции Ñ DISTINCT, Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ORDER BY должны быть в ÑпиÑке " "аргументов" -#: parser/parse_clause.c:2815 +#: parser/parse_clause.c:2876 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "" "в конÑтрукции SELECT DISTINCT Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ ORDER BY должны быть в ÑпиÑке выборки" -#: parser/parse_clause.c:2847 +#: parser/parse_clause.c:2908 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "агрегатной функции Ñ DISTINCT нужен минимум один аргумент" -#: parser/parse_clause.c:2848 +#: parser/parse_clause.c:2909 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "в SELECT DISTINCT нужен минимум один Ñтолбец" -#: parser/parse_clause.c:2914 parser/parse_clause.c:2946 +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "" "Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ SELECT DISTINCT ON должны ÑоответÑтвовать начальным выражениÑм " "ORDER BY" -#: parser/parse_clause.c:3024 +#: parser/parse_clause.c:3085 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ASC/DESC Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в ON CONFLICT" -#: parser/parse_clause.c:3030 +#: parser/parse_clause.c:3091 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "NULLS FIRST/LAST Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в ON CONFLICT" -#: parser/parse_clause.c:3110 +#: parser/parse_clause.c:3170 #, c-format msgid "" "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "" "в ON CONFLICT DO UPDATE требуетÑÑ Ð½Ð°Ð²Ð¾Ð´Ñщее указание или Ð¸Ð¼Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ" -#: parser/parse_clause.c:3111 +#: parser/parse_clause.c:3171 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "Ðапример: ON CONFLICT (имÑ_Ñтолбца)." -#: parser/parse_clause.c:3122 +#: parser/parse_clause.c:3182 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ON CONFLICT Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°Ð¼Ð¸ ÑиÑтемного каталога не поддерживаетÑÑ" -#: parser/parse_clause.c:3130 +#: parser/parse_clause.c:3190 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "" "ON CONFLICT не поддерживаетÑÑ Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\", Ñлужащей таблицей каталога" -#: parser/parse_clause.c:3256 +#: parser/parse_clause.c:3333 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "оператор %s не годитÑÑ Ð´Ð»Ñ Ñортировки" -#: parser/parse_clause.c:3258 +#: parser/parse_clause.c:3335 #, c-format msgid "" "Ordering operators must be \"<\" or \">\" members of btree operator families." @@ -15115,106 +15966,141 @@ msgstr "" "Операторы Ñортировки должны быть членами \"<\" или \">\" ÑемейÑтв операторов " "btree." -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2123 parser/parse_expr.c:2699 parser/parse_target.c:936 +#: parser/parse_clause.c:3646 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" +"RANGE Ñо Ñмещением PRECEDING/FOLLOWING не поддерживаетÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° Ñтолбца %s" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s " +"and offset type %s" +msgstr "" +"RANGE Ñо Ñмещением PRECEDING/FOLLOWING не поддерживаетÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° Ñтолбца %s " +"и типа ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Приведите значение ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ðº подходÑщему типу." + +#: parser/parse_clause.c:3660 +#, c-format +msgid "" +"RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for " +"column type %s and offset type %s" +msgstr "" +"RANGE Ñо Ñмещением PRECEDING/FOLLOWING допуÑкает неÑколько интерпретаций Ð´Ð»Ñ " +"типа Ñтолбца %s и типа ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ %s" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Приведите значение ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð² точноÑти к желаемому типу." + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:961 #, c-format msgid "cannot cast type %s to %s" msgstr "привеÑти тип %s к %s нельзÑ" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." msgstr "Во входных данных недоÑтаточно Ñтолбцов." -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "Ðе удалоÑÑŒ привеÑти тип %s к %s в Ñтолбце %d." -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." msgstr "Во входных данных больше Ñтолбцов." #. translator: first %s is name of a SQL construct, eg WHERE #. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1080 parser/parse_coerce.c:1128 +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format msgid "argument of %s must be type %s, not type %s" msgstr "аргумент конÑтрукции %s должен иметь тип %s, а не %s" #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1091 parser/parse_coerce.c:1140 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "аргумент конÑтрукции %s не должен возвращать множеÑтво" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1280 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "в конÑтрукции %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð±Ð¾Ð±Ñ‰Ð¸Ñ‚ÑŒ типы %s и %s" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1347 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "в конÑтрукции %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ тип %s в %s" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "аргументы, объÑвленные как \"anyelement\", должны быть однотипными" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "аргументы, объÑвленные как \"anyarray\", должны быть однотипными" -#: parser/parse_coerce.c:1689 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "аргументы, объÑвленные как \"anyrange\", должны быть однотипными" -#: parser/parse_coerce.c:1718 parser/parse_coerce.c:1933 -#: parser/parse_coerce.c:1967 +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 #, c-format msgid "argument declared %s is not an array but type %s" msgstr "аргумент, объÑвленный как \"%s\", оказалÑÑ Ð½Ðµ маÑÑивом, а типом %s" -#: parser/parse_coerce.c:1734 parser/parse_coerce.c:1773 +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 #, c-format msgid "argument declared %s is not consistent with argument declared %s" msgstr "аргумент, объÑвленный как \"%s\", не ÑоглаÑуетÑÑ Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð¾Ð¼ %s" -#: parser/parse_coerce.c:1756 parser/parse_coerce.c:1980 +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 #, c-format msgid "argument declared %s is not a range type but type %s" msgstr "аргумент, объÑвленный как \"%s\", имеет не диапазонный тип, а %s" -#: parser/parse_coerce.c:1794 +#: parser/parse_coerce.c:1865 #, c-format msgid "could not determine polymorphic type because input has type %s" msgstr "" "не удалоÑÑŒ определить полиморфный тип, так как входные аргументы имеют тип %s" -#: parser/parse_coerce.c:1805 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "" "в нарушение объÑÐ²Ð»ÐµÐ½Ð¸Ñ \"anynonarray\" ÑоответÑтвующий аргумент оказалÑÑ " "маÑÑивом: %s" -#: parser/parse_coerce.c:1815 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "" "в нарушение объÑÐ²Ð»ÐµÐ½Ð¸Ñ \"anyenum\" ÑоответÑтвующий аргумент оказалÑÑ Ð½Ðµ " "перечиÑлением: %s" -#: parser/parse_coerce.c:1855 parser/parse_coerce.c:1885 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "тип диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s не найден" @@ -15366,62 +16252,68 @@ msgstr "FOR UPDATE/SHARE в рекурÑивном запроÑе не подд msgid "recursive reference to query \"%s\" must not appear more than once" msgstr "рекурÑÐ¸Ð²Ð½Ð°Ñ ÑÑылка на Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" указана неоднократно" -#: parser/parse_expr.c:357 +#: parser/parse_expr.c:350 #, c-format msgid "DEFAULT is not allowed in this context" msgstr "DEFAULT не допуÑкаетÑÑ Ð² данном контекÑте" -#: parser/parse_expr.c:410 parser/parse_relation.c:3247 -#: parser/parse_relation.c:3267 +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 +#: parser/parse_relation.c:3307 #, c-format msgid "column %s.%s does not exist" msgstr "Ñтолбец %s.%s не ÑущеÑтвует" -#: parser/parse_expr.c:422 +#: parser/parse_expr.c:415 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "Ñтолбец \"%s\" не найден в типе данных %s" -#: parser/parse_expr.c:428 +#: parser/parse_expr.c:421 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "не удалоÑÑŒ идентифицировать Ñтолбец \"%s\" в типе запиÑи" # skip-rule: space-before-period -#: parser/parse_expr.c:434 +#: parser/parse_expr.c:427 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "" "запиÑÑŒ имени Ñтолбца .%s применена к типу %s, который не ÑвлÑетÑÑ ÑоÑтавным" -#: parser/parse_expr.c:464 parser/parse_target.c:722 +#: parser/parse_expr.c:458 parser/parse_target.c:728 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "раÑширение Ñтроки через \"*\" здеÑÑŒ не поддерживаетÑÑ" -#: parser/parse_expr.c:769 parser/parse_relation.c:689 -#: parser/parse_relation.c:789 parser/parse_target.c:1171 +#: parser/parse_expr.c:771 parser/parse_relation.c:689 +#: parser/parse_relation.c:789 parser/parse_target.c:1199 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "Ð½ÐµÐ¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñ‡Ð½Ð°Ñ ÑÑылка на Ñтолбец \"%s\"" -#: parser/parse_expr.c:825 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "параметр $%d не ÑущеÑтвует" -#: parser/parse_expr.c:1064 +#: parser/parse_expr.c:1070 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "Ð´Ð»Ñ NULLIF требуетÑÑ, чтобы оператор = возвращал логичеÑкое значение" -#: parser/parse_expr.c:1508 parser/parse_expr.c:1540 +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 +#, c-format +msgid "%s must not return a set" +msgstr "%s не должна возвращать множеÑтво" + +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 #, c-format msgid "number of columns does not match number of values" msgstr "чиÑло Ñтолбцов не равно чиÑлу значений" -#: parser/parse_expr.c:1554 +#: parser/parse_expr.c:1570 #, c-format msgid "" "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() " @@ -15430,193 +16322,223 @@ msgstr "" "иÑточником Ð´Ð»Ñ Ñлемента UPDATE Ñ Ð½ÐµÑколькими Ñтолбцами должен быть вложенный " "SELECT или выражение ROW()" -#: parser/parse_expr.c:1798 +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в конÑтрукции %s" + +#: parser/parse_expr.c:1825 msgid "cannot use subquery in check constraint" msgstr "в ограничении-проверке Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" -#: parser/parse_expr.c:1802 +#: parser/parse_expr.c:1829 msgid "cannot use subquery in DEFAULT expression" msgstr "в выражении DEFAULT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" -#: parser/parse_expr.c:1805 +#: parser/parse_expr.c:1832 msgid "cannot use subquery in index expression" msgstr "в индекÑном выражении Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" -#: parser/parse_expr.c:1808 +#: parser/parse_expr.c:1835 msgid "cannot use subquery in index predicate" msgstr "в предикате индекÑа Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" -#: parser/parse_expr.c:1811 +#: parser/parse_expr.c:1838 msgid "cannot use subquery in transform expression" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð¿Ð¾Ð´Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð² выражении преобразованиÑ" -#: parser/parse_expr.c:1814 +#: parser/parse_expr.c:1841 msgid "cannot use subquery in EXECUTE parameter" msgstr "в качеÑтве параметра EXECUTE Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑ" -#: parser/parse_expr.c:1817 +#: parser/parse_expr.c:1844 msgid "cannot use subquery in trigger WHEN condition" msgstr "в уÑловии WHEN Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" -#: parser/parse_expr.c:1820 +#: parser/parse_expr.c:1847 msgid "cannot use subquery in partition key expression" -msgstr "в выражении ключа Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" +msgstr "в выражении ключа ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑÑ‹" + +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "в качеÑтве аргумента CALL Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать подзапроÑ" -#: parser/parse_expr.c:1873 +#: parser/parse_expr.c:1903 #, c-format msgid "subquery must return only one column" msgstr "Ð¿Ð¾Ð´Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ вернуть только один Ñтолбец" -#: parser/parse_expr.c:1957 +#: parser/parse_expr.c:1987 #, c-format msgid "subquery has too many columns" msgstr "в подзапроÑе Ñлишком много Ñтолбцов" -#: parser/parse_expr.c:1962 +#: parser/parse_expr.c:1992 #, c-format msgid "subquery has too few columns" msgstr "в подзапроÑе недоÑтаточно Ñтолбцов" -#: parser/parse_expr.c:2063 +#: parser/parse_expr.c:2093 #, c-format msgid "cannot determine type of empty array" msgstr "тип пуÑтого маÑÑива определить нельзÑ" -#: parser/parse_expr.c:2064 +#: parser/parse_expr.c:2094 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "" "Приведите его к желаемому типу Ñвным образом, например ARRAY[]::integer[]." -#: parser/parse_expr.c:2078 +#: parser/parse_expr.c:2108 #, c-format msgid "could not find element type for data type %s" msgstr "не удалоÑÑŒ определить тип Ñлемента Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° данных %s" -#: parser/parse_expr.c:2353 +#: parser/parse_expr.c:2395 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "вмеÑто Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ XML-атрибута без имени должен указыватьÑÑ Ñтолбец" -#: parser/parse_expr.c:2354 +#: parser/parse_expr.c:2396 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "вмеÑто Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ XML-Ñлемента без имени должен указыватьÑÑ Ñтолбец" -#: parser/parse_expr.c:2369 +#: parser/parse_expr.c:2411 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "Ð¸Ð¼Ñ XML-атрибута \"%s\" указано неоднократно" -#: parser/parse_expr.c:2476 +#: parser/parse_expr.c:2518 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "привеÑти результат XMLSERIALIZE к типу %s нельзÑ" -#: parser/parse_expr.c:2772 parser/parse_expr.c:2967 +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 #, c-format msgid "unequal number of entries in row expressions" msgstr "разное чиÑло Ñлементов в Ñтроках" -#: parser/parse_expr.c:2782 +#: parser/parse_expr.c:2824 #, c-format msgid "cannot compare rows of zero length" msgstr "Ñтроки нулевой длины Ñравнивать нельзÑ" -#: parser/parse_expr.c:2806 +#: parser/parse_expr.c:2849 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "" "оператор ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ñтрок должен выдавать результат логичеÑкого типа, а не %s" -#: parser/parse_expr.c:2813 +#: parser/parse_expr.c:2856 #, c-format msgid "row comparison operator must not return a set" msgstr "оператор ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ñтрок не должен возвращать множеÑтво" -#: parser/parse_expr.c:2872 parser/parse_expr.c:2913 +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "не удалоÑÑŒ выбрать интерпретацию оператора ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ñтрок %s" -#: parser/parse_expr.c:2874 +#: parser/parse_expr.c:2917 #, c-format msgid "" "Row comparison operators must be associated with btree operator families." msgstr "" "Операторы ÑÑ€Ð°Ð²Ð½ÐµÐ½Ð¸Ñ Ñтрок должны быть ÑвÑзаны Ñ ÑемейÑтвом операторов btree." -#: parser/parse_expr.c:2915 +#: parser/parse_expr.c:2958 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "ОказалоÑÑŒ неÑколько равноценных кандидатур." -#: parser/parse_expr.c:3007 +#: parser/parse_expr.c:3051 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "" "Ð´Ð»Ñ IS DISTINCT FROM требуетÑÑ, чтобы оператор = возвращал логичеÑкое " "значение" -#: parser/parse_expr.c:3320 parser/parse_expr.c:3338 +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "" "приоритет операторов изменён: %s теперь имеет меньший приоритет, чем %s" -#: parser/parse_func.c:175 +#: parser/parse_func.c:185 #, c-format msgid "argument name \"%s\" used more than once" msgstr "Ð¸Ð¼Ñ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ð° \"%s\" иÑпользуетÑÑ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ð¾" -#: parser/parse_func.c:186 +#: parser/parse_func.c:196 #, c-format msgid "positional argument cannot follow named argument" msgstr "нумерованный аргумент не может Ñледовать за именованным аргументом" -#: parser/parse_func.c:271 +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "\"%s\" — не процедура" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Ð”Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° функции иÑпользуйте SELECT." + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "%s — процедура" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Ð”Ð»Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° процедуры иÑпользуйте CALL." + +#: parser/parse_func.c:306 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "выражение %s(*) недопуÑтимо, так как %s - не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:278 +#: parser/parse_func.c:313 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "в аргументах %s указан DISTINCT, но Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:284 +#: parser/parse_func.c:319 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "в аргументах %s указано WITHIN GROUP, но Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:290 +#: parser/parse_func.c:325 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "в аргументах %s указан ORDER BY, но Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:296 +#: parser/parse_func.c:331 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "в аргументах %s указан FILTER, но Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:302 +#: parser/parse_func.c:337 #, c-format msgid "" "OVER specified, but %s is not a window function nor an aggregate function" msgstr "" "вызов %s включает предложение OVER, но Ñто не Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ Ð¸ не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" -#: parser/parse_func.c:332 +#: parser/parse_func.c:375 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "Ð´Ð»Ñ Ñортирующего агрегата %s требуетÑÑ WITHIN GROUP" -#: parser/parse_func.c:338 +#: parser/parse_func.c:381 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "Ñортирующий агрегат %s не поддерживает OVER" -#: parser/parse_func.c:369 parser/parse_func.c:398 +#: parser/parse_func.c:412 parser/parse_func.c:441 #, c-format msgid "" "There is an ordered-set aggregate %s, but it requires %d direct arguments, " @@ -15625,7 +16547,7 @@ msgstr "" "ЕÑть Ñортирующий агрегат %s, но прÑмых аргументов у него должно быть %d, а " "не %d." -#: parser/parse_func.c:423 +#: parser/parse_func.c:466 #, c-format msgid "" "To use the hypothetical-set aggregate %s, the number of hypothetical direct " @@ -15635,7 +16557,7 @@ msgstr "" "гипотетичеÑких аргументов (%d) должно равнÑтьÑÑ Ñ‡Ð¸Ñлу Ñортируемых Ñтолбцов " "(здеÑÑŒ: %d)." -#: parser/parse_func.c:437 +#: parser/parse_func.c:480 #, c-format msgid "" "There is an ordered-set aggregate %s, but it requires at least %d direct " @@ -15644,27 +16566,41 @@ msgstr "" "ЕÑть Ñортирующий агрегат %s, но он требует минимум %d непоÑредÑтвенных " "аргументов." -#: parser/parse_func.c:456 +#: parser/parse_func.c:499 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s - не ÑÐ¾Ñ€Ñ‚Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ, WITHIN GROUP к ней неприменимо" -#: parser/parse_func.c:469 +#: parser/parse_func.c:512 #, c-format msgid "window function %s requires an OVER clause" msgstr "Ð´Ð»Ñ Ð¾ÐºÐ¾Ð½Ð½Ð¾Ð¹ функции %s требуетÑÑ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ OVER" -#: parser/parse_func.c:476 +#: parser/parse_func.c:519 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "Ð´Ð»Ñ Ð¾ÐºÐ¾Ð½Ð½Ð¾Ð¹ функции %s неприменимо WITHIN GROUP" -#: parser/parse_func.c:497 +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "процедура %s не уникальна" + +#: parser/parse_func.c:551 +#, c-format +msgid "" +"Could not choose a best candidate procedure. You might need to add explicit " +"type casts." +msgstr "" +"Ðе удалоÑÑŒ выбрать лучшую кандидатуру процедуры. Возможно, вам Ñледует " +"добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." + +#: parser/parse_func.c:557 #, c-format msgid "function %s is not unique" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не уникальна" -#: parser/parse_func.c:500 +#: parser/parse_func.c:560 #, c-format msgid "" "Could not choose a best candidate function. You might need to add explicit " @@ -15673,7 +16609,7 @@ msgstr "" "Ðе удалоÑÑŒ выбрать лучшую кандидатуру функции. Возможно, вам Ñледует " "добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." -#: parser/parse_func.c:511 +#: parser/parse_func.c:599 #, c-format msgid "" "No aggregate function matches the given name and argument types. Perhaps you " @@ -15684,7 +16620,21 @@ msgstr "" "Возможно, неверно раÑположено предложение ORDER BY - оно должно Ñледовать за " "вÑеми обычными аргументами функции." -#: parser/parse_func.c:522 +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "процедура %s не ÑущеÑтвует" + +#: parser/parse_func.c:610 +#, c-format +msgid "" +"No procedure matches the given name and argument types. You might need to " +"add explicit type casts." +msgstr "" +"Процедура Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ именем и типами аргументов не найдена. Возможно, вам " +"Ñледует добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." + +#: parser/parse_func.c:619 #, c-format msgid "" "No function matches the given name and argument types. You might need to add " @@ -15693,132 +16643,153 @@ msgstr "" "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ именем и типами аргументов не найдена. Возможно, вам " "Ñледует добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." -#: parser/parse_func.c:624 +#: parser/parse_func.c:721 #, c-format msgid "VARIADIC argument must be an array" msgstr "параметр VARIADIC должен быть маÑÑивом" -#: parser/parse_func.c:676 parser/parse_func.c:740 +#: parser/parse_func.c:773 parser/parse_func.c:837 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð±ÐµÐ· параметров должна вызыватьÑÑ Ñ‚Ð°Ðº: %s(*)" -#: parser/parse_func.c:683 +#: parser/parse_func.c:780 #, c-format msgid "aggregates cannot return sets" msgstr "агрегатные функции не могут возвращать множеÑтва" -#: parser/parse_func.c:698 +#: parser/parse_func.c:795 #, c-format msgid "aggregates cannot use named arguments" msgstr "у агрегатных функций не может быть именованных аргументов" -#: parser/parse_func.c:730 +#: parser/parse_func.c:827 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "предложение DISTINCT Ð´Ð»Ñ Ð¾ÐºÐ¾Ð½Ð½Ñ‹Ñ… функций не реализовано" -#: parser/parse_func.c:750 +#: parser/parse_func.c:847 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "агрегатное предложение ORDER BY Ð´Ð»Ñ Ð¾ÐºÐ¾Ð½Ð½Ñ‹Ñ… функций не реализовано" -#: parser/parse_func.c:759 +#: parser/parse_func.c:856 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "предложение FILTER Ð´Ð»Ñ Ð½Ðµ агрегатных оконных функций не реализовано" -#: parser/parse_func.c:765 +#: parser/parse_func.c:865 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "" +"вызовы оконных функций не могут включать вызовы функций, возвращающих " +"множеÑтва" + +#: parser/parse_func.c:873 #, c-format msgid "window functions cannot return sets" msgstr "оконные функции не могут возвращать множеÑтва" -#: parser/parse_func.c:1931 +#: parser/parse_func.c:2059 #, c-format msgid "function name \"%s\" is not unique" msgstr "Ð¸Ð¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ \"%s\" не уникально" -#: parser/parse_func.c:1933 +#: parser/parse_func.c:2061 #, c-format msgid "Specify the argument list to select the function unambiguously." msgstr "Задайте ÑпиÑок аргументов Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñ‡Ð½Ð¾Ð³Ð¾ выбора функции." -#: parser/parse_func.c:1943 +#: parser/parse_func.c:2071 #, c-format msgid "could not find a function named \"%s\"" msgstr "не удалоÑÑŒ найти функцию Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" -#: parser/parse_func.c:2045 +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s — не функциÑ" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "не удалоÑÑŒ найти процедуру Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" + +#: parser/parse_func.c:2198 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "не удалоÑÑŒ найти агрегат Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" + +#: parser/parse_func.c:2203 #, c-format msgid "aggregate %s(*) does not exist" msgstr "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s(*) не ÑущеÑтвует" -#: parser/parse_func.c:2050 +#: parser/parse_func.c:2208 #, c-format msgid "aggregate %s does not exist" msgstr "Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не ÑущеÑтвует" -#: parser/parse_func.c:2069 +#: parser/parse_func.c:2221 #, c-format msgid "function %s is not an aggregate" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" не ÑвлÑетÑÑ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð¾Ð¹" -#: parser/parse_func.c:2117 +#: parser/parse_func.c:2271 msgid "set-returning functions are not allowed in JOIN conditions" msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… JOIN" -#: parser/parse_func.c:2130 +#: parser/parse_func.c:2292 msgid "set-returning functions are not allowed in policy expressions" msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… политик" -#: parser/parse_func.c:2145 +#: parser/parse_func.c:2308 msgid "set-returning functions are not allowed in window definitions" msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в определении окна" -#: parser/parse_func.c:2183 +#: parser/parse_func.c:2346 msgid "set-returning functions are not allowed in check constraints" msgstr "" "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в ограничениÑÑ…-проверках" -#: parser/parse_func.c:2187 +#: parser/parse_func.c:2350 msgid "set-returning functions are not allowed in DEFAULT expressions" msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… DEFAULT" -#: parser/parse_func.c:2190 +#: parser/parse_func.c:2353 msgid "set-returning functions are not allowed in index expressions" msgstr "" "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… индекÑов" -#: parser/parse_func.c:2193 +#: parser/parse_func.c:2356 msgid "set-returning functions are not allowed in index predicates" msgstr "" "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в предикатах индекÑов" -#: parser/parse_func.c:2196 +#: parser/parse_func.c:2359 msgid "set-returning functions are not allowed in transform expressions" msgstr "" "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… преобразований" -#: parser/parse_func.c:2199 +#: parser/parse_func.c:2362 msgid "set-returning functions are not allowed in EXECUTE parameters" msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в параметрах EXECUTE" -#: parser/parse_func.c:2202 +#: parser/parse_func.c:2365 msgid "set-returning functions are not allowed in trigger WHEN conditions" msgstr "" "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в уÑловиÑÑ… WHEN Ð´Ð»Ñ " "триггеров" -#: parser/parse_func.c:2205 -msgid "set-returning functions are not allowed in partition key expression" +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" msgstr "" -"функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражении ключа разбиениÑ" +"функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в выражениÑÑ… ключа " +"ÑекционированиÑ" -#. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_func.c:2225 -#, c-format -msgid "set-returning functions are not allowed in %s" -msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в конÑтрукции %s" +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "функции, возвращающие множеÑтва, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть в аргументах CALL" #: parser/parse_node.c:87 #, c-format @@ -15841,8 +16812,8 @@ msgid "array assignment requires type %s but expression is of type %s" msgstr "" "Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ²Ð°Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¼Ð°ÑÑива требуетÑÑ Ñ‚Ð¸Ð¿ %s, однако выражение имеет тип %s" -#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:585 -#: utils/adt/regproc.c:605 utils/adt/regproc.c:789 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format msgid "operator does not exist: %s" msgstr "оператор не ÑущеÑтвует: %s" @@ -15852,14 +16823,6 @@ msgstr "оператор не ÑущеÑтвует: %s" msgid "Use an explicit ordering operator or modify the query." msgstr "ИÑпользуйте Ñвный оператор Ñортировки или измените запроÑ." -#: parser/parse_oper.c:228 utils/adt/array_userfuncs.c:794 -#: utils/adt/array_userfuncs.c:933 utils/adt/arrayfuncs.c:3639 -#: utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6039 -#: utils/adt/rowtypes.c:1167 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "не удалоÑÑŒ найти оператор равенÑтва Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" - #: parser/parse_oper.c:480 #, c-format msgid "operator requires run-time type coercion: %s" @@ -15879,33 +16842,42 @@ msgstr "" "Ðе удалоÑÑŒ выбрать лучшую кандидатуру оператора. Возможно, вам Ñледует " "добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." -#: parser/parse_oper.c:726 +#: parser/parse_oper.c:727 #, c-format msgid "" -"No operator matches the given name and argument type(s). You might need to " -"add explicit type casts." +"No operator matches the given name and argument type. You might need to add " +"an explicit type cast." +msgstr "" +"Оператор Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼ именем и типом аргумента не найден. Возможно, вам Ñледует " +"добавить Ñвное приведение типа." + +#: parser/parse_oper.c:729 +#, c-format +msgid "" +"No operator matches the given name and argument types. You might need to add " +"explicit type casts." msgstr "" "Оператор Ñ Ð´Ð°Ð½Ð½Ñ‹Ð¼Ð¸ именем и типами аргументов не найден. Возможно, вам " "Ñледует добавить Ñвные Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð¾Ð²." -#: parser/parse_oper.c:785 parser/parse_oper.c:903 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "оператор \"%s\" - лишь оболочка" -#: parser/parse_oper.c:891 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² ANY/ALL (Ñ Ð¼Ð°ÑÑивом) требуетÑÑ Ð¼Ð°ÑÑив Ñправа" -#: parser/parse_oper.c:933 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "" "Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð² ANY/ALL (Ñ Ð¼Ð°ÑÑивом) требуетÑÑ, чтобы оператор = возвращал " "логичеÑкое значение" -#: parser/parse_oper.c:938 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "" @@ -15932,12 +16904,12 @@ msgstr "ÑÑылка на таблицу %u неоднозначна" msgid "table name \"%s\" specified more than once" msgstr "Ð¸Ð¼Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" указано больше одного раза" -#: parser/parse_relation.c:446 parser/parse_relation.c:3187 +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "в Ñлементе Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ FROM Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑылка на таблицу \"%s\"" -#: parser/parse_relation.c:449 parser/parse_relation.c:3192 +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 #, c-format msgid "" "There is an entry for table \"%s\", but it cannot be referenced from this " @@ -15956,13 +16928,13 @@ msgstr "Ð”Ð»Ñ ÑÑылки LATERAL тип JOIN должен быть INNER ил msgid "system column \"%s\" reference in check constraint is invalid" msgstr "в ограничении-проверке указан недопуÑтимый ÑиÑтемный Ñтолбец \"%s\"" -#: parser/parse_relation.c:1086 parser/parse_relation.c:1371 -#: parser/parse_relation.c:1940 +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 +#: parser/parse_relation.c:1936 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "в таблице \"%s\" ÑодержитÑÑ Ñтолбцов: %d, но указано: %d" -#: parser/parse_relation.c:1178 +#: parser/parse_relation.c:1173 #, c-format msgid "" "There is a WITH item named \"%s\", but it cannot be referenced from this " @@ -15971,7 +16943,7 @@ msgstr "" "Ð’ WITH еÑть Ñлемент \"%s\", но на него Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð¸Ð· Ñтой чаÑти " "запроÑа." -#: parser/parse_relation.c:1180 +#: parser/parse_relation.c:1175 #, c-format msgid "" "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." @@ -15979,7 +16951,7 @@ msgstr "" "ИÑпользуйте WITH RECURSIVE или иÑключите ÑÑылки вперёд, переупорÑдочив " "Ñлементы WITH." -#: parser/parse_relation.c:1491 +#: parser/parse_relation.c:1486 #, c-format msgid "" "a column definition list is only allowed for functions returning \"record\"" @@ -15987,54 +16959,55 @@ msgstr "" "ÑпиÑок Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸ÐµÐ¼ Ñтолбцов может быть только у функций, возвращающих " "запиÑÑŒ" -#: parser/parse_relation.c:1500 +#: parser/parse_relation.c:1495 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "" "у функций, возвращающих запиÑÑŒ, должен быть ÑпиÑок Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸ÐµÐ¼ Ñтолбцов" -#: parser/parse_relation.c:1579 +#: parser/parse_relation.c:1575 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\", иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ð²Ð¾ FROM, возвращает неподдерживаемый тип %s" -#: parser/parse_relation.c:1768 +#: parser/parse_relation.c:1764 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "в ÑпиÑках VALUES \"%s\" ÑодержитÑÑ Ñтолбцов: %d, но указано: %d" -#: parser/parse_relation.c:1823 +#: parser/parse_relation.c:1819 #, c-format msgid "joins can have at most %d columns" msgstr "чиÑло Ñтолбцов в ÑоединениÑÑ… ограничено %d" -#: parser/parse_relation.c:1913 +#: parser/parse_relation.c:1909 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "в запроÑе \"%s\" в WITH нет Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ RETURNING" -#: parser/parse_relation.c:2808 parser/parse_relation.c:2971 +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 +#: parser/parse_relation.c:3011 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "Ñтолбец %d Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" не ÑущеÑтвует" -#: parser/parse_relation.c:3190 +#: parser/parse_relation.c:3230 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "Возможно, предполагалаÑÑŒ ÑÑылка на пÑевдоним таблицы \"%s\"." -#: parser/parse_relation.c:3198 +#: parser/parse_relation.c:3238 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "таблица \"%s\" отÑутÑтвует в предложении FROM" -#: parser/parse_relation.c:3250 +#: parser/parse_relation.c:3290 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "Возможно, предполагалаÑÑŒ ÑÑылка на Ñтолбец \"%s.%s\"." -#: parser/parse_relation.c:3252 +#: parser/parse_relation.c:3292 #, c-format msgid "" "There is a column named \"%s\" in table \"%s\", but it cannot be referenced " @@ -16043,14 +17016,14 @@ msgstr "" "Столбец \"%s\" еÑть в таблице \"%s\", но на него Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð¸Ð· Ñтой " "чаÑти запроÑа." -#: parser/parse_relation.c:3269 +#: parser/parse_relation.c:3309 #, c-format msgid "" "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "" "Возможно, предполагалаÑÑŒ ÑÑылка на Ñтолбец \"%s.%s\" или Ñтолбец \"%s.%s\"." -#: parser/parse_target.c:483 parser/parse_target.c:775 +#: parser/parse_target.c:483 parser/parse_target.c:790 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "приÑвоить значение ÑиÑтемному Ñтолбцу \"%s\" нельзÑ" @@ -16070,7 +17043,7 @@ msgstr "вложенному полю Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñвоить значе msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "Ñтолбец \"%s\" имеет тип %s, а выражение - %s" -#: parser/parse_target.c:759 +#: parser/parse_target.c:774 #, c-format msgid "" "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a " @@ -16079,7 +17052,7 @@ msgstr "" "приÑвоить значение полю \"%s\" Ñтолбца \"%s\" нельзÑ, так как тип %s не " "ÑвлÑетÑÑ ÑоÑтавным" -#: parser/parse_target.c:768 +#: parser/parse_target.c:783 #, c-format msgid "" "cannot assign to field \"%s\" of column \"%s\" because there is no such " @@ -16088,7 +17061,7 @@ msgstr "" "приÑвоить значение полю \"%s\" Ñтолбца \"%s\" нельзÑ, так как в типе данных " "%s нет такого Ñтолбца" -#: parser/parse_target.c:835 +#: parser/parse_target.c:860 #, c-format msgid "" "array assignment to \"%s\" requires type %s but expression is of type %s" @@ -16096,12 +17069,12 @@ msgstr "" "Ð´Ð»Ñ Ð¿Ñ€Ð¸ÑÐ²Ð°Ð¸Ð²Ð°Ð½Ð¸Ñ Ð¼Ð°ÑÑива полю \"%s\" требуетÑÑ Ñ‚Ð¸Ð¿ %s, однако выражение " "имеет тип %s" -#: parser/parse_target.c:845 +#: parser/parse_target.c:870 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "вложенное поле \"%s\" имеет тип %s, а выражение - %s" -#: parser/parse_target.c:1261 +#: parser/parse_target.c:1289 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "SELECT * должен ÑÑылатьÑÑ Ð½Ð° таблицы" @@ -16121,7 +17094,7 @@ msgstr "неправильное указание %%TYPE (Ñлишком мно msgid "type reference %s converted to %s" msgstr "ÑÑылка на тип %s преобразована в тип %s" -#: parser/parse_type.c:261 parser/parse_type.c:804 utils/cache/typcache.c:243 +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 #, c-format msgid "type \"%s\" is only a shell" msgstr "тип \"%s\" - лишь пуÑтышка" @@ -16136,170 +17109,166 @@ msgstr "у типа \"%s\" не может быть модификаторов" msgid "type modifiers must be simple constants or identifiers" msgstr "модификатором типа должна быть проÑÑ‚Ð°Ñ ÐºÐ¾Ð½Ñтанта или идентификатор" -#: parser/parse_type.c:670 parser/parse_type.c:769 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "неверное Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð° \"%s\"" -#: parser/parse_utilcmd.c:263 +#: parser/parse_utilcmd.c:272 #, c-format msgid "cannot create partitioned table as inheritance child" msgstr "Ñоздать Ñекционированную таблицу в виде потомка нельзÑ" -#: parser/parse_utilcmd.c:268 -#, c-format -msgid "cannot partition using more than %d columns" -msgstr "чиÑло Ñтолбцов в ключе ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может превышать %d" - -#: parser/parse_utilcmd.c:275 +#: parser/parse_utilcmd.c:448 #, c-format -msgid "cannot list partition using more than one column" -msgstr "Ñекционирование по ÑпиÑку возможно только Ñ Ð¾Ð´Ð½Ð¸Ð¼ Ñтолбцом" +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s ÑоздаÑÑ‚ поÑледовательноÑть \"%s\" Ð´Ð»Ñ Ñтолбца serial \"%s.%s\"" -#: parser/parse_utilcmd.c:413 +#: parser/parse_utilcmd.c:571 #, c-format msgid "array of serial is not implemented" msgstr "маÑÑивы Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ serial не реализованы" -#: parser/parse_utilcmd.c:461 -#, c-format -msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" -msgstr "%s ÑоздаÑÑ‚ поÑледовательноÑть \"%s\" Ð´Ð»Ñ Ñтолбца serial \"%s.%s\"" - -#: parser/parse_utilcmd.c:554 parser/parse_utilcmd.c:566 +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 #, c-format msgid "" "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "конфликт NULL/NOT NULL в объÑвлении Ñтолбца \"%s\" таблицы \"%s\"" -#: parser/parse_utilcmd.c:578 +#: parser/parse_utilcmd.c:671 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "" "Ð´Ð»Ñ Ñтолбца \"%s\" таблицы \"%s\" указано неÑколько значений по умолчанию" -#: parser/parse_utilcmd.c:595 parser/parse_utilcmd.c:704 +#: parser/parse_utilcmd.c:688 #, c-format -msgid "primary key constraints are not supported on foreign tables" -msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" +msgid "identity columns are not supported on typed tables" +msgstr "Ñтолбцы идентификации не поддерживаютÑÑ Ñ Ñ‚Ð¸Ð¿Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ñ‹Ð¼Ð¸ таблицами" + +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "Ñтолбцы идентификации не поддерживаютÑÑ Ñ ÑекциÑми" -#: parser/parse_utilcmd.c:601 parser/parse_utilcmd.c:710 +#: parser/parse_utilcmd.c:701 #, c-format -msgid "primary key constraints are not supported on partitioned tables" +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" msgstr "" -"Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" +"Ð´Ð»Ñ Ñтолбца \"%s\" таблицы \"%s\" ÑвойÑтво identity задано неоднократно" -#: parser/parse_utilcmd.c:610 parser/parse_utilcmd.c:720 +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 #, c-format -msgid "unique constraints are not supported on foreign tables" -msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ñти Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" +msgid "primary key constraints are not supported on foreign tables" +msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:616 parser/parse_utilcmd.c:726 +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 #, c-format -msgid "unique constraints are not supported on partitioned tables" -msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ñти Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" +msgid "unique constraints are not supported on foreign tables" +msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð¾Ñти Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:633 parser/parse_utilcmd.c:756 +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 #, c-format msgid "foreign key constraints are not supported on foreign tables" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:639 parser/parse_utilcmd.c:762 +#: parser/parse_utilcmd.c:778 #, c-format -msgid "foreign key constraints are not supported on partitioned tables" +msgid "both default and identity specified for column \"%s\" of table \"%s\"" msgstr "" -"Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" +"Ð´Ð»Ñ Ñтолбца \"%s\" таблицы \"%s\" задано и значение по умолчанию, и ÑвойÑтво " +"identity" -#: parser/parse_utilcmd.c:736 +#: parser/parse_utilcmd.c:843 #, c-format msgid "exclusion constraints are not supported on foreign tables" msgstr "ограничениÑ-иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñторонних таблиц не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:742 +#: parser/parse_utilcmd.c:849 #, c-format msgid "exclusion constraints are not supported on partitioned tables" msgstr "ограничениÑ-иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:812 +#: parser/parse_utilcmd.c:913 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKE при Ñоздании Ñторонних таблиц не поддерживаетÑÑ" -#: parser/parse_utilcmd.c:1344 parser/parse_utilcmd.c:1420 +#: parser/parse_utilcmd.c:1516 parser/parse_utilcmd.c:1623 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "Ð˜Ð½Ð´ÐµÐºÑ \"%s\" ÑÑылаетÑÑ Ð½Ð° тип вÑей Ñтроки таблицы." -#: parser/parse_utilcmd.c:1689 +#: parser/parse_utilcmd.c:1973 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr "в CREATE TABLE Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать ÑущеÑтвующий индекÑ" -#: parser/parse_utilcmd.c:1709 +#: parser/parse_utilcmd.c:1993 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" уже ÑвÑзан Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸ÐµÐ¼" -#: parser/parse_utilcmd.c:1717 +#: parser/parse_utilcmd.c:2001 #, c-format msgid "index \"%s\" does not belong to table \"%s\"" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не принадлежит таблице \"%s\"" -#: parser/parse_utilcmd.c:1724 +#: parser/parse_utilcmd.c:2008 #, c-format msgid "index \"%s\" is not valid" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" - нерабочий" -#: parser/parse_utilcmd.c:1730 +#: parser/parse_utilcmd.c:2014 #, c-format msgid "\"%s\" is not a unique index" msgstr "\"%s\" не ÑвлÑетÑÑ ÑƒÐ½Ð¸ÐºÐ°Ð»ÑŒÐ½Ñ‹Ð¼ индекÑом" -#: parser/parse_utilcmd.c:1731 parser/parse_utilcmd.c:1738 -#: parser/parse_utilcmd.c:1745 parser/parse_utilcmd.c:1815 +#: parser/parse_utilcmd.c:2015 parser/parse_utilcmd.c:2022 +#: parser/parse_utilcmd.c:2029 parser/parse_utilcmd.c:2101 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "" "Создать первичный ключ или ограничение уникальноÑти Ð´Ð»Ñ Ñ‚Ð°ÐºÐ¾Ð³Ð¾ индекÑа " "нельзÑ." -#: parser/parse_utilcmd.c:1737 +#: parser/parse_utilcmd.c:2021 #, c-format msgid "index \"%s\" contains expressions" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" Ñодержит выражениÑ" -#: parser/parse_utilcmd.c:1744 +#: parser/parse_utilcmd.c:2028 #, c-format msgid "\"%s\" is a partial index" msgstr "\"%s\" - чаÑтичный индекÑ" -#: parser/parse_utilcmd.c:1756 +#: parser/parse_utilcmd.c:2040 #, c-format msgid "\"%s\" is a deferrable index" msgstr "\"%s\" - откладываемый индекÑ" -#: parser/parse_utilcmd.c:1757 +#: parser/parse_utilcmd.c:2041 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "" "Создать не откладываемое ограничение на базе откладываемого индекÑа нельзÑ." -#: parser/parse_utilcmd.c:1814 +#: parser/parse_utilcmd.c:2100 #, c-format msgid "index \"%s\" does not have default sorting behavior" msgstr "Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа \"%s\" не определено поведение при Ñортировке по умолчанию" -#: parser/parse_utilcmd.c:1958 +#: parser/parse_utilcmd.c:2249 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "Ñтолбец \"%s\" фигурирует в первичном ключе дважды" -#: parser/parse_utilcmd.c:1964 +#: parser/parse_utilcmd.c:2255 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "Ñтолбец \"%s\" фигурирует в ограничении уникальноÑти дважды" -#: parser/parse_utilcmd.c:2173 +#: parser/parse_utilcmd.c:2578 #, c-format msgid "" "index expressions and predicates can refer only to the table being indexed" @@ -16307,17 +17276,17 @@ msgstr "" "индекÑные Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¸ предикаты могут ÑÑылатьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ на индекÑируемую " "таблицу" -#: parser/parse_utilcmd.c:2219 +#: parser/parse_utilcmd.c:2624 #, c-format msgid "rules on materialized views are not supported" msgstr "правила Ð´Ð»Ñ Ð¼Ð°Ñ‚ÐµÑ€Ð¸Ð°Ð»Ð¸Ð·Ð¾Ð²Ð°Ð½Ð½Ñ‹Ñ… предÑтавлений не поддерживаютÑÑ" -#: parser/parse_utilcmd.c:2280 +#: parser/parse_utilcmd.c:2685 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "в уÑловиÑÑ… WHERE Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° другие отношениÑ" -#: parser/parse_utilcmd.c:2352 +#: parser/parse_utilcmd.c:2757 #, c-format msgid "" "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE " @@ -16326,132 +17295,256 @@ msgstr "" "правила Ñ ÑƒÑловиÑми WHERE могут Ñодержать только дейÑÑ‚Ð²Ð¸Ñ SELECT, INSERT, " "UPDATE или DELETE" -#: parser/parse_utilcmd.c:2370 parser/parse_utilcmd.c:2469 -#: rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 +#: parser/parse_utilcmd.c:2775 parser/parse_utilcmd.c:2874 +#: rewrite/rewriteHandler.c:497 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "уÑловные операторы UNION/INTERSECT/EXCEPT не реализованы" -#: parser/parse_utilcmd.c:2388 +#: parser/parse_utilcmd.c:2793 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "в правиле ON SELECT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать OLD" -#: parser/parse_utilcmd.c:2392 +#: parser/parse_utilcmd.c:2797 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "в правиле ON SELECT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать NEW" -#: parser/parse_utilcmd.c:2401 +#: parser/parse_utilcmd.c:2806 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "в правиле ON INSERT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать OLD" -#: parser/parse_utilcmd.c:2407 +#: parser/parse_utilcmd.c:2812 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "в правиле ON DELETE Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать NEW" -#: parser/parse_utilcmd.c:2435 +#: parser/parse_utilcmd.c:2840 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "в запроÑе WITH Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° OLD" -#: parser/parse_utilcmd.c:2442 +#: parser/parse_utilcmd.c:2847 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "в запроÑе WITH Ð½ÐµÐ»ÑŒÐ·Ñ ÑÑылатьÑÑ Ð½Ð° NEW" -#: parser/parse_utilcmd.c:2766 +#: parser/parse_utilcmd.c:3285 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "предложение DEFERRABLE раÑположено неправильно" -#: parser/parse_utilcmd.c:2771 parser/parse_utilcmd.c:2786 +#: parser/parse_utilcmd.c:3290 parser/parse_utilcmd.c:3305 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "DEFERRABLE/NOT DEFERRABLE можно указать только один раз" -#: parser/parse_utilcmd.c:2781 +#: parser/parse_utilcmd.c:3300 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "предложение NOT DEFERRABLE раÑположено неправильно" -#: parser/parse_utilcmd.c:2794 parser/parse_utilcmd.c:2820 gram.y:5282 +#: parser/parse_utilcmd.c:3313 parser/parse_utilcmd.c:3339 gram.y:5547 #, c-format msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" msgstr "" "ограничение Ñ Ñ…Ð°Ñ€Ð°ÐºÑ‚ÐµÑ€Ð¸Ñтикой INITIALLY DEFERRED должно быть объÑвлено как " "DEFERRABLE" -#: parser/parse_utilcmd.c:2802 +#: parser/parse_utilcmd.c:3321 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "предложение INITIALLY DEFERRED раÑположено неправильно" -#: parser/parse_utilcmd.c:2807 parser/parse_utilcmd.c:2833 +#: parser/parse_utilcmd.c:3326 parser/parse_utilcmd.c:3352 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "INITIALLY IMMEDIATE/DEFERRED можно указать только один раз" -#: parser/parse_utilcmd.c:2828 +#: parser/parse_utilcmd.c:3347 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "предложение INITIALLY IMMEDIATE раÑположено неправильно" -#: parser/parse_utilcmd.c:3019 +#: parser/parse_utilcmd.c:3538 #, c-format msgid "" "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "в CREATE указана Ñхема (%s), Ð¾Ñ‚Ð»Ð¸Ñ‡Ð½Ð°Ñ Ð¾Ñ‚ Ñоздаваемой (%s)" -#: parser/parse_utilcmd.c:3085 +#: parser/parse_utilcmd.c:3572 #, c-format -msgid "invalid bound specification for a list partition" -msgstr "неправильное указание Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñекции по ÑпиÑку" +msgid "table \"%s\" is not partitioned" +msgstr "таблица \"%s\" не ÑвлÑетÑÑ Ñекционированной" + +#: parser/parse_utilcmd.c:3579 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не Ñекционирован" + +#: parser/parse_utilcmd.c:3613 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "у Ñекционированной по хешу таблицы не может быть Ñекции по умолчанию" + +#: parser/parse_utilcmd.c:3630 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "неправильное указание Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции" + +#: parser/parse_utilcmd.c:3636 partitioning/partbounds.c:2127 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "модуль Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции должен быть положительным целым" + +#: parser/parse_utilcmd.c:3643 partitioning/partbounds.c:2135 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "оÑтаток Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции должен быть меньше модулÑ" -#: parser/parse_utilcmd.c:3108 parser/parse_utilcmd.c:3208 -#: parser/parse_utilcmd.c:3235 +#: parser/parse_utilcmd.c:3655 #, c-format -msgid "specified value cannot be cast to type \"%s\" of column \"%s\"" -msgstr "указанное значение Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð²ÐµÑти к типу \"%s\" Ñтолбца \"%s\"" +msgid "invalid bound specification for a list partition" +msgstr "неправильное указание Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñекции по ÑпиÑку" -#: parser/parse_utilcmd.c:3147 +#: parser/parse_utilcmd.c:3711 #, c-format msgid "invalid bound specification for a range partition" msgstr "неправильное указание Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñекции по диапазону" -#: parser/parse_utilcmd.c:3155 +#: parser/parse_utilcmd.c:3717 #, c-format msgid "FROM must specify exactly one value per partitioning column" -msgstr "во FROM должно указыватьÑÑ Ñ€Ð¾Ð²Ð½Ð¾ одно значение Ð´Ð»Ñ Ñтолбца разбиениÑ" +msgstr "" +"во FROM должно указыватьÑÑ Ñ€Ð¾Ð²Ð½Ð¾ одно значение Ð´Ð»Ñ Ñекционирующего Ñтолбца" -#: parser/parse_utilcmd.c:3159 +#: parser/parse_utilcmd.c:3721 #, c-format msgid "TO must specify exactly one value per partitioning column" -msgstr "в TO должно указыватьÑÑ Ñ€Ð¾Ð²Ð½Ð¾ одно значение Ð´Ð»Ñ Ñтолбца разбиениÑ" +msgstr "" +"в TO должно указыватьÑÑ Ñ€Ð¾Ð²Ð½Ð¾ одно значение Ð´Ð»Ñ Ñекционирующего Ñтолбца" -#: parser/parse_utilcmd.c:3197 parser/parse_utilcmd.c:3224 +#: parser/parse_utilcmd.c:3768 parser/parse_utilcmd.c:3782 #, c-format msgid "cannot specify NULL in range bound" msgstr "указать NULL в диапазонном ограничении нельзÑ" +#: parser/parse_utilcmd.c:3829 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "за границей MAXVALUE могут Ñледовать только границы MAXVALUE" + +#: parser/parse_utilcmd.c:3836 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "за границей MINVALUE могут Ñледовать только границы MINVALUE" + +#: parser/parse_utilcmd.c:3867 parser/parse_utilcmd.c:3879 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "указанное значение Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð²ÐµÑти к типу %s Ñтолбца \"%s\"" + +#: parser/parse_utilcmd.c:3881 +#, c-format +msgid "The cast requires a non-immutable conversion." +msgstr "Ð”Ð»Ñ Ñтого Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ Ð½ÐµÐ¿Ð¾ÑтоÑнное преобразование." + +#: parser/parse_utilcmd.c:3882 +#, c-format +msgid "Try putting the literal value in single quotes." +msgstr "Попробуйте заключить буквальное значение в апоÑтрофы." + #: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "идентификатор \"%s\" будет уÑечён до \"%s\"" -#: port/pg_shmem.c:175 port/sysv_shmem.c:175 +#: partitioning/partbounds.c:331 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "ÑÐµÐºÑ†Ð¸Ñ \"%s\" конфликтует Ñ ÑущеÑтвующей Ñекцией по умолчанию \"%s\"" + +#: partitioning/partbounds.c:390 +#, c-format +msgid "" +"every hash partition modulus must be a factor of the next larger modulus" +msgstr "" +"модуль каждой хеш-Ñекции должен быть делителем модулей, превышающих его" + +#: partitioning/partbounds.c:486 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "Ð´Ð»Ñ Ñекции \"%s\" заданы границы, образующие пуÑтой диапазон" + +#: partitioning/partbounds.c:488 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Ð£ÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð½Ð¸Ð¶Ð½ÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° %s больше или равна верхней границе %s." + +#: partitioning/partbounds.c:585 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "ÑÐµÐºÑ†Ð¸Ñ \"%s\" переÑекаетÑÑ Ñ Ñекцией \"%s\"" + +#: partitioning/partbounds.c:685 +#, c-format +msgid "" +"skipped scanning foreign table \"%s\" which is a partition of default " +"partition \"%s\"" +msgstr "" +"пропущено Ñканирование Ñторонней таблицы \"%s\", ÑвлÑющейÑÑ Ñекцией Ñекции " +"по умолчанию \"%s\"" + +#: partitioning/partbounds.c:724 +#, c-format +msgid "" +"updated partition constraint for default partition \"%s\" would be violated " +"by some row" +msgstr "" +"изменённое ограничение Ñекции Ð´Ð»Ñ Ñекции по умолчанию \"%s\" будет нарушено " +"некоторыми Ñтроками" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "оÑтаток Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции должен быть неотрицательным целым" + +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹, Ñекционированной по хешу" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, c-format +msgid "" +"number of partitioning columns (%d) does not match number of partition keys " +"provided (%d)" +msgstr "" +"чиÑло Ñекционирующих Ñтолбцов (%d) не равно чиÑлу предÑтавленных ключей " +"ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ (%d)" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "" +"column %d of the partition key has type \"%s\", but supplied value is of " +"type \"%s\"" +msgstr "" +"Ñтолбец %d ключа ÑÐµÐºÑ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð¼ÐµÐµÑ‚ тип \"%s\", но Ð´Ð»Ñ Ð½ÐµÐ³Ð¾ передано " +"значение типа \"%s\"" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 #, c-format msgid "could not create shared memory segment: %m" msgstr "не удалоÑÑŒ Ñоздать Ñегмент разделÑемой памÑти: %m" -#: port/pg_shmem.c:176 port/sysv_shmem.c:176 +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "Ошибка в ÑиÑтемном вызове shmget(ключ=%lu, размер=%zu, 0%o)." -#: port/pg_shmem.c:180 port/sysv_shmem.c:180 +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory " @@ -16465,7 +17558,7 @@ msgstr "" "ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ наÑтройке разделÑемой памÑти ÑодержитÑÑ Ð² " "документации PostgreSQL." -#: port/pg_shmem.c:187 port/sysv_shmem.c:187 +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory " @@ -16480,7 +17573,7 @@ msgstr "" "ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ наÑтройке разделÑемой памÑти ÑодержитÑÑ Ð² " "документации PostgreSQL." -#: port/pg_shmem.c:193 port/sysv_shmem.c:193 +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 #, c-format msgid "" "This error does *not* mean that you have run out of disk space. It occurs " @@ -16492,17 +17585,17 @@ msgid "" msgstr "" "Эта ошибка ÐЕ означает, что на диÑке нет меÑта. ВероÑтнее вÑего, были занÑты " "вÑе доÑтупные ID разделÑемой памÑти (в Ñтом Ñлучае вам надо увеличить " -"параметр SHMMNI в Ñдре), либо превышен предельный размер разделÑемой " -"памÑти.\n" +"параметр SHMMNI в Ñдре), либо превышен предельный размер разделÑемой памÑти." +"\n" "ÐŸÐ¾Ð´Ñ€Ð¾Ð±Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ наÑтройке разделÑемой памÑти ÑодержитÑÑ Ð² " "документации PostgreSQL." -#: port/pg_shmem.c:483 port/sysv_shmem.c:483 +#: port/pg_shmem.c:553 port/sysv_shmem.c:553 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "не удалоÑÑŒ получить анонимную разделÑемую памÑть: %m" -#: port/pg_shmem.c:485 port/sysv_shmem.c:485 +#: port/pg_shmem.c:555 port/sysv_shmem.c:555 #, c-format msgid "" "This error usually means that PostgreSQL's request for a shared memory " @@ -16516,12 +17609,27 @@ msgstr "" "Б) можно Ñнизить иÑпользование разделÑемой памÑти, возможно, уменьшив " "shared_buffers или max_connections." -#: port/pg_shmem.c:551 port/sysv_shmem.c:551 port/win32_shmem.c:134 +#: port/pg_shmem.c:617 port/sysv_shmem.c:617 #, c-format msgid "huge pages not supported on this platform" msgstr "гигантÑкие Ñтраницы на Ñтой платформе не поддерживаютÑÑ" -#: port/pg_shmem.c:646 port/sysv_shmem.c:646 +#: port/pg_shmem.c:680 port/sysv_shmem.c:680 utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "" +"ранее выделенный блок разделÑемой памÑти (ключ %lu, ID %lu) по-прежнему " +"иÑпользуетÑÑ" + +#: port/pg_shmem.c:683 port/sysv_shmem.c:683 utils/init/miscinit.c:1071 +#, c-format +msgid "" +"Terminate any old server processes associated with data directory \"%s\"." +msgstr "" +"Завершите вÑе Ñтарые Ñерверные процеÑÑÑ‹, работающие Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ данных \"" +"%s\"." + +#: port/pg_shmem.c:734 port/sysv_shmem.c:734 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о каталоге данных \"%s\": %m" @@ -16631,22 +17739,61 @@ msgstr "не удалоÑÑŒ разблокировать Ñемафор (код msgid "could not try-lock semaphore: error code %lu" msgstr "не удалоÑÑŒ попытатьÑÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñемафор (код ошибки: %lu)" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "" +"не удалоÑÑŒ активировать право Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° блокировку Ñтраниц в памÑти: " +"код ошибки %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "Ошибка в ÑиÑтемном вызове %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "" +"не удалоÑÑŒ активировать право Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° блокировку Ñтраниц в памÑти" + +#: port/win32_shmem.c:176 +#, c-format +msgid "" +"Assign Lock Pages in Memory user right to the Windows user account which " +"runs PostgreSQL." +msgstr "" +"Ðазначьте право \"Блокировка Ñтраниц в памÑти\" учётной запиÑи пользователÑ, " +"иÑпользуемой Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "процеÑÑор не поддерживает большие Ñтраницы" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "отключение огромных Ñтраниц" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "не удалоÑÑŒ Ñоздать Ñегмент разделÑемой памÑти (код ошибки: %lu)" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:303 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "Ошибка в ÑиÑтемном вызове CreateFileMapping (размер=%zu, имÑ=%s)." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:328 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "ранее Ñозданный блок разделÑемой памÑти вÑÑ‘ ещё иÑпользуетÑÑ" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:329 #, c-format msgid "" "Check if there are any old server processes still running, and terminate " @@ -16654,83 +17801,83 @@ msgid "" msgstr "" "ЕÑли по-прежнему работают какие-то Ñтарые Ñерверные процеÑÑÑ‹, Ñнимите их." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:339 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "Ошибка в ÑиÑтемном вызове DuplicateHandle." -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:357 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "Ошибка в ÑиÑтемном вызове MapViewOfFileEx." -#: postmaster/autovacuum.c:416 +#: postmaster/autovacuum.c:406 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "породить процеÑÑ Ð·Ð°Ð¿ÑƒÑка автоочиÑтки не удалоÑÑŒ: %m" -#: postmaster/autovacuum.c:452 +#: postmaster/autovacuum.c:442 #, c-format msgid "autovacuum launcher started" msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка автоочиÑтки Ñоздан" -#: postmaster/autovacuum.c:838 +#: postmaster/autovacuum.c:832 #, c-format msgid "autovacuum launcher shutting down" msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка автоочиÑтки завершаетÑÑ" -#: postmaster/autovacuum.c:1500 +#: postmaster/autovacuum.c:1494 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "не удалоÑÑŒ породить рабочий процеÑÑ Ð°Ð²Ñ‚Ð¾Ð¾Ñ‡Ð¸Ñтки: %m" -#: postmaster/autovacuum.c:1706 +#: postmaster/autovacuum.c:1700 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "автоочиÑтка: обработка базы данных \"%s\"" # skip-rule: capital-letter-first -#: postmaster/autovacuum.c:2280 +#: postmaster/autovacuum.c:2269 #, c-format msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" msgstr "автоочиÑтка: удаление уÑтаревшей врем. таблицы \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2486 +#: postmaster/autovacuum.c:2498 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "автоматичеÑÐºÐ°Ñ Ð¾Ñ‡Ð¸Ñтка таблицы \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2489 +#: postmaster/autovacuum.c:2501 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "автоматичеÑкий анализ таблицы \"%s.%s.%s\"" -#: postmaster/autovacuum.c:2700 +#: postmaster/autovacuum.c:2694 #, c-format msgid "processing work entry for relation \"%s.%s.%s\"" msgstr "обработка рабочей запиÑи Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s.%s\"" -#: postmaster/autovacuum.c:3344 +#: postmaster/autovacuum.c:3273 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "автоочиÑтка не запущена из-за неправильной конфигурации" -#: postmaster/autovacuum.c:3345 +#: postmaster/autovacuum.c:3274 #, c-format msgid "Enable the \"track_counts\" option." msgstr "Включите параметр \"track_counts\"." -#: postmaster/bgworker.c:388 postmaster/bgworker.c:822 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð³Ð¾ процеÑÑа \"%s\"" -#: postmaster/bgworker.c:420 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "разрегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð³Ð¾ процеÑÑа \"%s\"" -#: postmaster/bgworker.c:564 +#: postmaster/bgworker.c:592 #, c-format msgid "" "background worker \"%s\": must attach to shared memory in order to request a " @@ -16739,7 +17886,7 @@ msgstr "" "фоновый процеÑÑ \"%s\" должен иметь доÑтуп к общей памÑти, чтобы запроÑить " "подключение к БД" -#: postmaster/bgworker.c:573 +#: postmaster/bgworker.c:601 #, c-format msgid "" "background worker \"%s\": cannot request database access if starting at " @@ -16748,24 +17895,32 @@ msgstr "" "фоновый процеÑÑ \"%s\" не может получить доÑтуп к БД, еÑли он запущен при " "Ñтарте главного процеÑÑа" -#: postmaster/bgworker.c:587 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" msgstr "фоновый процеÑÑ \"%s\": неправильный интервал перезапуÑка" -#: postmaster/bgworker.c:632 +#: postmaster/bgworker.c:630 +#, c-format +msgid "" +"background worker \"%s\": parallel workers may not be configured for restart" +msgstr "" +"фоновый процеÑÑ \"%s\": параллельные иÑполнители не могут быть наÑтроены Ð´Ð»Ñ " +"перезапуÑка" + +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "завершение фонового процеÑÑа \"%s\" по команде админиÑтратора" -#: postmaster/bgworker.c:830 +#: postmaster/bgworker.c:863 #, c-format msgid "" "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "" "фоновой процеÑÑ \"%s\" должен быть зарегиÑтрирован в shared_preload_libraries" -#: postmaster/bgworker.c:842 +#: postmaster/bgworker.c:875 #, c-format msgid "" "background worker \"%s\": only dynamic background workers can request " @@ -16774,12 +17929,12 @@ msgstr "" "фоновый процеÑÑ \"%s\": только динамичеÑкие фоновые процеÑÑÑ‹ могут " "запрашивать уведомление" -#: postmaster/bgworker.c:857 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" msgstr "Ñлишком много фоновых процеÑÑов" -#: postmaster/bgworker.c:858 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." msgid_plural "" @@ -16791,13 +17946,13 @@ msgstr[1] "" msgstr[2] "" "МакÑимально возможное чиÑло фоновых процеÑÑов при текущих параметрах: %d." -#: postmaster/bgworker.c:862 +#: postmaster/bgworker.c:895 #, c-format msgid "" "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "Возможно, Ñтоит увеличить параметр \"max_worker_processes\"." -#: postmaster/checkpointer.c:465 +#: postmaster/checkpointer.c:468 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" @@ -16805,67 +17960,62 @@ msgstr[0] "контрольные точки проиÑходÑÑ‚ Ñлишком msgstr[1] "контрольные точки проиÑходÑÑ‚ Ñлишком чаÑто (через %d Ñек.)" msgstr[2] "контрольные точки проиÑходÑÑ‚ Ñлишком чаÑто (через %d Ñек.)" -#: postmaster/checkpointer.c:469 +#: postmaster/checkpointer.c:472 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "Возможно, Ñтоит увеличить параметр \"max_wal_size\"." -#: postmaster/checkpointer.c:629 -#, c-format -msgid "transaction log switch forced (archive_timeout=%d)" -msgstr "принудительное переключение журнала транзакций (archive_timeout=%d)" - -#: postmaster/checkpointer.c:1088 +#: postmaster/checkpointer.c:1090 #, c-format msgid "checkpoint request failed" msgstr "Ñбой при запроÑе контрольной точки" -#: postmaster/checkpointer.c:1089 +#: postmaster/checkpointer.c:1091 #, c-format msgid "Consult recent messages in the server log for details." msgstr "Смотрите подробноÑти в протоколе Ñервера." -#: postmaster/checkpointer.c:1284 +#: postmaster/checkpointer.c:1286 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "очередь запроÑов fsync Ñжата (было запиÑей: %d, Ñтало: %d)" -#: postmaster/pgarch.c:149 +#: postmaster/pgarch.c:148 #, c-format msgid "could not fork archiver: %m" msgstr "не удалоÑÑŒ породить процеÑÑ Ð°Ñ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ð¸: %m" -#: postmaster/pgarch.c:457 +#: postmaster/pgarch.c:456 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "режим архивации включён, но команда архивации не задана" -#: postmaster/pgarch.c:485 +#: postmaster/pgarch.c:484 #, c-format msgid "" -"archiving transaction log file \"%s\" failed too many times, will try again " +"archiving write-ahead log file \"%s\" failed too many times, will try again " "later" msgstr "" -"заархивировать файл журнала транзакций \"%s\" не удалоÑÑŒ много раз подрÑд; " +"заархивировать файл журнала предзапиÑи \"%s\" не удалоÑÑŒ много раз подрÑд; " "ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° будет Ñделана позже" -#: postmaster/pgarch.c:588 +#: postmaster/pgarch.c:585 #, c-format msgid "archive command failed with exit code %d" msgstr "команда архивации завершилаÑÑŒ ошибкой Ñ ÐºÐ¾Ð´Ð¾Ð¼ %d" -#: postmaster/pgarch.c:590 postmaster/pgarch.c:600 postmaster/pgarch.c:607 -#: postmaster/pgarch.c:613 postmaster/pgarch.c:622 +#: postmaster/pgarch.c:587 postmaster/pgarch.c:597 postmaster/pgarch.c:604 +#: postmaster/pgarch.c:610 postmaster/pgarch.c:619 #, c-format msgid "The failed archive command was: %s" msgstr "Команда архивации Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹: %s" -#: postmaster/pgarch.c:597 +#: postmaster/pgarch.c:594 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "команда архивации была прервана иÑключением 0x%X" -#: postmaster/pgarch.c:599 postmaster/postmaster.c:3527 +#: postmaster/pgarch.c:596 postmaster/postmaster.c:3568 #, c-format msgid "" "See C include file \"ntstatus.h\" for a description of the hexadecimal value." @@ -16873,157 +18023,147 @@ msgstr "" "ОпиÑание Ñтого шеÑтнадцатеричного Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ñ‰Ð¸Ñ‚Ðµ во включаемом C-файле " "\"ntstatus.h\"" -#: postmaster/pgarch.c:604 +#: postmaster/pgarch.c:601 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "команда архивации завершена по Ñигналу %d: %s" -#: postmaster/pgarch.c:611 +#: postmaster/pgarch.c:608 #, c-format msgid "archive command was terminated by signal %d" msgstr "команда архивации завершена по Ñигналу %d" -#: postmaster/pgarch.c:620 +#: postmaster/pgarch.c:617 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "команда архивации завершилаÑÑŒ Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтным кодом ÑоÑтоÑÐ½Ð¸Ñ %d" -#: postmaster/pgarch.c:632 -#, c-format -msgid "archived transaction log file \"%s\"" -msgstr "файл архива журнала транзакций \"%s\"" - -#: postmaster/pgarch.c:681 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "не удалоÑÑŒ открыть каталог ÑоÑтоÑÐ½Ð¸Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð° \"%s\": %m" - -#: postmaster/pgstat.c:392 +#: postmaster/pgstat.c:395 #, c-format msgid "could not resolve \"localhost\": %s" msgstr "не удалоÑÑŒ разрешить \"localhost\": %s" -#: postmaster/pgstat.c:415 +#: postmaster/pgstat.c:418 #, c-format msgid "trying another address for the statistics collector" msgstr "проба другого адреÑа Ð´Ð»Ñ Ñборщика ÑтатиÑтики" -#: postmaster/pgstat.c:424 +#: postmaster/pgstat.c:427 #, c-format msgid "could not create socket for statistics collector: %m" msgstr "не удалоÑÑŒ Ñоздать Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:436 +#: postmaster/pgstat.c:439 #, c-format msgid "could not bind socket for statistics collector: %m" msgstr "не удалоÑÑŒ привÑзатьÑÑ Ðº Ñокету Ð´Ð»Ñ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:447 +#: postmaster/pgstat.c:450 #, c-format msgid "could not get address of socket for statistics collector: %m" msgstr "не удалоÑÑŒ получить Ð°Ð´Ñ€ÐµÑ Ñокета Ð´Ð»Ñ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:463 +#: postmaster/pgstat.c:466 #, c-format msgid "could not connect socket for statistics collector: %m" msgstr "не удалоÑÑŒ подключить Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:484 +#: postmaster/pgstat.c:487 #, c-format msgid "could not send test message on socket for statistics collector: %m" msgstr "" "не удалоÑÑŒ поÑлать теÑтовое Ñообщение в Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:510 +#: postmaster/pgstat.c:513 #, c-format msgid "select() failed in statistics collector: %m" msgstr "Ñбой select() в Ñборщике ÑтатиÑтики: %m" -#: postmaster/pgstat.c:525 +#: postmaster/pgstat.c:528 #, c-format msgid "test message did not get through on socket for statistics collector" msgstr "теÑтовое Ñообщение не прошло через Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики" -#: postmaster/pgstat.c:540 +#: postmaster/pgstat.c:543 #, c-format msgid "could not receive test message on socket for statistics collector: %m" msgstr "" "теÑтовое Ñообщение через Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики получить не удалоÑÑŒ: " "%m" -#: postmaster/pgstat.c:550 +#: postmaster/pgstat.c:553 #, c-format msgid "incorrect test message transmission on socket for statistics collector" msgstr "теÑтовое Ñообщение через Ñокет Ð´Ð»Ñ Ñборщика ÑтатиÑтики прошло неверно" -#: postmaster/pgstat.c:573 +#: postmaster/pgstat.c:576 #, c-format msgid "could not set statistics collector socket to nonblocking mode: %m" msgstr "" "не удалоÑÑŒ переключить Ñокет Ñборщика ÑтатиÑтики в неблокирующий режим: %m" -#: postmaster/pgstat.c:583 +#: postmaster/pgstat.c:615 #, c-format msgid "disabling statistics collector for lack of working socket" msgstr "Ñборщик ÑтатиÑтики отключаетÑÑ Ð¸Ð·-за нехватки рабочего Ñокета" -#: postmaster/pgstat.c:730 +#: postmaster/pgstat.c:762 #, c-format msgid "could not fork statistics collector: %m" msgstr "не удалоÑÑŒ породить процеÑÑ Ñборщика ÑтатиÑтики: %m" -#: postmaster/pgstat.c:1306 +#: postmaster/pgstat.c:1342 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "запрошен ÑÐ±Ñ€Ð¾Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтного Ñчётчика: \"%s\"" -#: postmaster/pgstat.c:1307 +#: postmaster/pgstat.c:1343 #, c-format msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "ДопуÑтимый Ñчётчик: \"archiver\" или \"bgwriter\"." -#: postmaster/pgstat.c:4246 +#: postmaster/pgstat.c:4366 #, c-format msgid "could not read statistics message: %m" msgstr "не удалоÑÑŒ прочитать Ñообщение ÑтатиÑтики: %m" -#: postmaster/pgstat.c:4578 postmaster/pgstat.c:4735 +#: postmaster/pgstat.c:4698 postmaster/pgstat.c:4855 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "не удалоÑÑŒ открыть временный файл ÑтатиÑтики \"%s\": %m" -#: postmaster/pgstat.c:4645 postmaster/pgstat.c:4780 +#: postmaster/pgstat.c:4765 postmaster/pgstat.c:4900 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "не удалоÑÑŒ запиÑать во временный файл ÑтатиÑтики \"%s\": %m" -#: postmaster/pgstat.c:4654 postmaster/pgstat.c:4789 +#: postmaster/pgstat.c:4774 postmaster/pgstat.c:4909 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "не удалоÑÑŒ закрыть временный файл ÑтатиÑтики \"%s\": %m" -#: postmaster/pgstat.c:4662 postmaster/pgstat.c:4797 +#: postmaster/pgstat.c:4782 postmaster/pgstat.c:4917 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "" "не удалоÑÑŒ переименовать временный файл ÑтатиÑтики из \"%s\" в \"%s\": %m" -#: postmaster/pgstat.c:4886 postmaster/pgstat.c:5071 postmaster/pgstat.c:5224 +#: postmaster/pgstat.c:5006 postmaster/pgstat.c:5212 postmaster/pgstat.c:5365 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл ÑтатиÑтики \"%s\": %m" -#: postmaster/pgstat.c:4898 postmaster/pgstat.c:4908 postmaster/pgstat.c:4918 -#: postmaster/pgstat.c:4939 postmaster/pgstat.c:4954 postmaster/pgstat.c:5008 -#: postmaster/pgstat.c:5083 postmaster/pgstat.c:5103 postmaster/pgstat.c:5121 -#: postmaster/pgstat.c:5137 postmaster/pgstat.c:5155 postmaster/pgstat.c:5171 -#: postmaster/pgstat.c:5236 postmaster/pgstat.c:5248 postmaster/pgstat.c:5260 -#: postmaster/pgstat.c:5285 postmaster/pgstat.c:5307 +#: postmaster/pgstat.c:5018 postmaster/pgstat.c:5028 postmaster/pgstat.c:5049 +#: postmaster/pgstat.c:5071 postmaster/pgstat.c:5086 postmaster/pgstat.c:5149 +#: postmaster/pgstat.c:5224 postmaster/pgstat.c:5244 postmaster/pgstat.c:5262 +#: postmaster/pgstat.c:5278 postmaster/pgstat.c:5296 postmaster/pgstat.c:5312 +#: postmaster/pgstat.c:5377 postmaster/pgstat.c:5389 postmaster/pgstat.c:5401 +#: postmaster/pgstat.c:5426 postmaster/pgstat.c:5448 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "файл ÑтатиÑтики \"%s\" иÑпорчен" -#: postmaster/pgstat.c:5436 +#: postmaster/pgstat.c:5577 #, c-format msgid "" "using stale statistics instead of current ones because stats collector is " @@ -17032,44 +18172,41 @@ msgstr "" "иÑпользуетÑÑ Ð¿Ñ€Ð¾ÑÑ€Ð¾Ñ‡ÐµÐ½Ð½Ð°Ñ ÑтатиÑтика вмеÑто текущей, так как Ñборщик " "ÑтатиÑтики не отвечает" -#: postmaster/pgstat.c:5763 +#: postmaster/pgstat.c:5904 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "таблица хеша базы данных иÑпорчена при очиÑтке --- прерывание" -#: postmaster/postmaster.c:692 +#: postmaster/postmaster.c:718 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s: неверный аргумент Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° -f: \"%s\"\n" -#: postmaster/postmaster.c:778 +#: postmaster/postmaster.c:804 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s: неверный аргумент Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° -t: \"%s\"\n" -#: postmaster/postmaster.c:829 +#: postmaster/postmaster.c:855 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s: неверный аргумент: \"%s\"\n" -#: postmaster/postmaster.c:868 +#: postmaster/postmaster.c:897 #, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" +msgid "" +"%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be " +"less than max_connections (%d)\n" msgstr "" -"%s: параметр superuser_reserved_connections должен быть меньше " -"max_connections\n" - -#: postmaster/postmaster.c:873 -#, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: параметр max_wal_senders должен быть меньше max_connections\n" +"%s: значение superuser_reserved_connections (%d) Ð¿Ð»ÑŽÑ max_wal_senders (%d) " +"должно быть меньше max_connections (%d)\n" -#: postmaster/postmaster.c:878 +#: postmaster/postmaster.c:904 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "Ðрхивацию WAL Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ, еÑли уÑтановлен wal_level \"minimal\"" -#: postmaster/postmaster.c:881 +#: postmaster/postmaster.c:907 #, c-format msgid "" "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or " @@ -17078,133 +18215,97 @@ msgstr "" "Ð”Ð»Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð¹ транÑлÑции WAL (max_wal_senders > 0) wal_level должен быть " "\"replica\" или \"logical\"" -#: postmaster/postmaster.c:889 +#: postmaster/postmaster.c:915 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s: ошибка в таблицах маркеров времени, требуетÑÑ Ð¸Ñправление\n" -#: postmaster/postmaster.c:992 postmaster/postmaster.c:1090 -#: utils/init/miscinit.c:1446 +#: postmaster/postmaster.c:1029 postmaster/postmaster.c:1127 +#: utils/init/miscinit.c:1551 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "неверный формат ÑпиÑка в параметре \"%s\"" -#: postmaster/postmaster.c:1023 +#: postmaster/postmaster.c:1060 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "не удалоÑÑŒ Ñоздать принимающий Ñокет Ð´Ð»Ñ \"%s\"" -#: postmaster/postmaster.c:1029 +#: postmaster/postmaster.c:1066 #, c-format msgid "could not create any TCP/IP sockets" msgstr "не удалоÑÑŒ Ñоздать Ñокеты TCP/IP" -#: postmaster/postmaster.c:1112 +#: postmaster/postmaster.c:1149 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" -msgstr "не удалоÑÑŒ Ñоздать доменный Ñокет в каталоге \"%s\"" +msgstr "не удалоÑÑŒ Ñоздать Unix-Ñокет в каталоге \"%s\"" -#: postmaster/postmaster.c:1118 +#: postmaster/postmaster.c:1155 #, c-format msgid "could not create any Unix-domain sockets" -msgstr "ни один доменный Ñокет Ñоздать не удалоÑÑŒ" +msgstr "ни один Unix-Ñокет Ñоздать не удалоÑÑŒ" -#: postmaster/postmaster.c:1130 +#: postmaster/postmaster.c:1167 #, c-format msgid "no socket created for listening" msgstr "отÑутÑтвуют принимающие Ñокеты" -#: postmaster/postmaster.c:1170 +#: postmaster/postmaster.c:1207 #, c-format msgid "could not create I/O completion port for child queue" msgstr "не удалоÑÑŒ Ñоздать порт Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð²Ð²Ð¾Ð´Ð°/вывода Ð´Ð»Ñ Ð¾Ñ‡ÐµÑ€ÐµÐ´Ð¸ потомков" -#: postmaster/postmaster.c:1199 +#: postmaster/postmaster.c:1236 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ поменÑть права Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ файла PID \"%s\": %s\n" -#: postmaster/postmaster.c:1203 +#: postmaster/postmaster.c:1240 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать внешний файл PID \"%s\": %s\n" -#: postmaster/postmaster.c:1260 +#: postmaster/postmaster.c:1297 #, c-format msgid "ending log output to stderr" msgstr "завершение вывода в stderr" -#: postmaster/postmaster.c:1261 +#: postmaster/postmaster.c:1298 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "Ð’ дальнейшем протокол будет выводитьÑÑ Ð² \"%s\"." -#: postmaster/postmaster.c:1287 utils/init/postinit.c:213 +#: postmaster/postmaster.c:1324 utils/init/postinit.c:214 #, c-format msgid "could not load pg_hba.conf" msgstr "не удалоÑÑŒ загрузить pg_hba.conf" -#: postmaster/postmaster.c:1313 +#: postmaster/postmaster.c:1350 #, c-format msgid "postmaster became multithreaded during startup" msgstr "процеÑÑ postmaster Ñтал многопоточным при запуÑке" -#: postmaster/postmaster.c:1314 +#: postmaster/postmaster.c:1351 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "УÑтановите в переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ LC_ALL правильную локаль." -#: postmaster/postmaster.c:1413 +#: postmaster/postmaster.c:1456 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s: подходÑщий иÑполнÑемый файл postgres не найден" -#: postmaster/postmaster.c:1436 utils/misc/tzparser.c:341 +#: postmaster/postmaster.c:1479 utils/misc/tzparser.c:341 #, c-format msgid "" -"This may indicate an incomplete PostgreSQL installation, or that the file " -"\"%s\" has been moved away from its proper location." +"This may indicate an incomplete PostgreSQL installation, or that the file \"" +"%s\" has been moved away from its proper location." msgstr "" "Возможно, PostgreSQL уÑтановлен не полноÑтью или файла \"%s\" нет в " "положенном меÑте." -#: postmaster/postmaster.c:1464 -#, c-format -msgid "data directory \"%s\" does not exist" -msgstr "каталог данных \"%s\" не ÑущеÑтвует" - -#: postmaster/postmaster.c:1469 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "не удалоÑÑŒ Ñчитать права на каталог \"%s\": %m" - -#: postmaster/postmaster.c:1477 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "указанный каталог данных \"%s\" не ÑущеÑтвует" - -#: postmaster/postmaster.c:1493 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "владелец каталога данных \"%s\" определён неверно" - -#: postmaster/postmaster.c:1495 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "" -"Сервер должен запуÑкать пользователь, ÑвлÑющийÑÑ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ каталога данных." - -#: postmaster/postmaster.c:1515 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "к каталогу данных \"%s\" имеют доÑтуп вÑе или группа" - -#: postmaster/postmaster.c:1517 -#, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "Права должны быть: u=rwx (0700)." - -#: postmaster/postmaster.c:1528 +#: postmaster/postmaster.c:1506 #, c-format msgid "" "%s: could not find the database system\n" @@ -17215,52 +18316,52 @@ msgstr "" "ОжидалоÑÑŒ найти её в каталоге \"%s\",\n" "но открыть файл \"%s\" не удалоÑÑŒ: %s\n" -#: postmaster/postmaster.c:1705 +#: postmaster/postmaster.c:1683 #, c-format msgid "select() failed in postmaster: %m" msgstr "Ñбой select() в postmaster'е: %m" -#: postmaster/postmaster.c:1856 +#: postmaster/postmaster.c:1838 #, c-format msgid "" "performing immediate shutdown because data directory lock file is invalid" msgstr "" "немедленное отключение из-за ошибочного файла блокировки каталога данных" -#: postmaster/postmaster.c:1934 postmaster/postmaster.c:1965 +#: postmaster/postmaster.c:1916 postmaster/postmaster.c:1947 #, c-format msgid "incomplete startup packet" msgstr "неполный Ñтартовый пакет" -#: postmaster/postmaster.c:1946 +#: postmaster/postmaster.c:1928 #, c-format msgid "invalid length of startup packet" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ñтартового пакета" -#: postmaster/postmaster.c:2004 +#: postmaster/postmaster.c:1986 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "не удалоÑÑŒ отправить ответ в процеÑÑе SSL-ÑоглаÑованиÑ: %m" -#: postmaster/postmaster.c:2033 +#: postmaster/postmaster.c:2012 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "" "неподдерживаемый протокол клиентÑкого Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ %u.%u; Ñервер поддерживает " "%u.0 - %u.%u" -#: postmaster/postmaster.c:2096 utils/misc/guc.c:5739 utils/misc/guc.c:5832 -#: utils/misc/guc.c:7133 utils/misc/guc.c:9889 utils/misc/guc.c:9923 +#: postmaster/postmaster.c:2076 utils/misc/guc.c:6017 utils/misc/guc.c:6110 +#: utils/misc/guc.c:7436 utils/misc/guc.c:10199 utils/misc/guc.c:10233 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "неверное значение Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\": \"%s\"" -#: postmaster/postmaster.c:2099 +#: postmaster/postmaster.c:2079 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "ДопуÑтимые значениÑ: \"false\", 0, \"true\", 1, \"database\"." -#: postmaster/postmaster.c:2119 +#: postmaster/postmaster.c:2109 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "" @@ -17286,382 +18387,394 @@ msgstr "ÑиÑтема баз данных оÑтанавливаетÑÑ" msgid "the database system is in recovery mode" msgstr "ÑиÑтема баз данных в режиме воÑÑтановлениÑ" -#: postmaster/postmaster.c:2221 storage/ipc/procarray.c:290 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:338 +#: postmaster/postmaster.c:2221 storage/ipc/procarray.c:292 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:346 #, c-format msgid "sorry, too many clients already" msgstr "извините, уже Ñлишком много клиентов" -#: postmaster/postmaster.c:2283 +#: postmaster/postmaster.c:2311 #, c-format msgid "wrong key in cancel request for process %d" msgstr "неправильный ключ в запроÑе на отмену процеÑÑа %d" -#: postmaster/postmaster.c:2291 +#: postmaster/postmaster.c:2319 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "процеÑÑ Ñ ÐºÐ¾Ð´Ð¾Ð¼ %d, полученным в запроÑе на отмену, не найден" -#: postmaster/postmaster.c:2502 +#: postmaster/postmaster.c:2530 #, c-format msgid "received SIGHUP, reloading configuration files" msgstr "получен SIGHUP, файлы конфигурации перезагружаютÑÑ" -#: postmaster/postmaster.c:2527 +#: postmaster/postmaster.c:2555 #, c-format msgid "pg_hba.conf was not reloaded" msgstr "pg_hba.conf не был перезагружен" -#: postmaster/postmaster.c:2531 +#: postmaster/postmaster.c:2559 #, c-format msgid "pg_ident.conf was not reloaded" msgstr "pg_ident.conf не был перезагружен" -#: postmaster/postmaster.c:2541 +#: postmaster/postmaster.c:2569 #, c-format msgid "SSL configuration was not reloaded" msgstr "ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ SSL не была перезагружена" -#: postmaster/postmaster.c:2589 +#: postmaster/postmaster.c:2617 #, c-format msgid "received smart shutdown request" msgstr "получен Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° \"вежливое\" выключение" -#: postmaster/postmaster.c:2644 +#: postmaster/postmaster.c:2675 #, c-format msgid "received fast shutdown request" msgstr "получен Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° быÑтрое выключение" -#: postmaster/postmaster.c:2674 +#: postmaster/postmaster.c:2708 #, c-format msgid "aborting any active transactions" msgstr "прерывание вÑех активных транзакций" -#: postmaster/postmaster.c:2708 +#: postmaster/postmaster.c:2742 #, c-format msgid "received immediate shutdown request" msgstr "получен Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° немедленное выключение" -#: postmaster/postmaster.c:2772 +#: postmaster/postmaster.c:2809 #, c-format msgid "shutdown at recovery target" msgstr "выключение при доÑтижении цели воÑÑтановлениÑ" -#: postmaster/postmaster.c:2788 postmaster/postmaster.c:2811 +#: postmaster/postmaster.c:2825 postmaster/postmaster.c:2848 msgid "startup process" msgstr "Ñтартовый процеÑÑ" -#: postmaster/postmaster.c:2791 +#: postmaster/postmaster.c:2828 #, c-format msgid "aborting startup due to startup process failure" msgstr "прерывание запуÑка из-за ошибки в Ñтартовом процеÑÑе" -#: postmaster/postmaster.c:2852 +#: postmaster/postmaster.c:2889 #, c-format msgid "database system is ready to accept connections" msgstr "ÑиÑтема БД готова принимать подключениÑ" -#: postmaster/postmaster.c:2871 +#: postmaster/postmaster.c:2910 msgid "background writer process" msgstr "процеÑÑ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð¹ запиÑи" -#: postmaster/postmaster.c:2925 +#: postmaster/postmaster.c:2964 msgid "checkpointer process" msgstr "процеÑÑ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… точек" -#: postmaster/postmaster.c:2941 +#: postmaster/postmaster.c:2980 msgid "WAL writer process" msgstr "процеÑÑ Ð·Ð°Ð¿Ð¸Ñи WAL" -#: postmaster/postmaster.c:2955 +#: postmaster/postmaster.c:2995 msgid "WAL receiver process" msgstr "процеÑÑ ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ WAL" -#: postmaster/postmaster.c:2970 +#: postmaster/postmaster.c:3010 msgid "autovacuum launcher process" msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка автоочиÑтки" -#: postmaster/postmaster.c:2985 +#: postmaster/postmaster.c:3025 msgid "archiver process" msgstr "процеÑÑ Ð°Ñ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ð¸" -#: postmaster/postmaster.c:3001 +#: postmaster/postmaster.c:3041 msgid "statistics collector process" msgstr "процеÑÑ Ñбора ÑтатиÑтики" -#: postmaster/postmaster.c:3015 +#: postmaster/postmaster.c:3055 msgid "system logger process" msgstr "процеÑÑ ÑиÑтемного протоколированиÑ" -#: postmaster/postmaster.c:3077 -msgid "worker process" -msgstr "рабочий процеÑÑ" +#: postmaster/postmaster.c:3117 +#, c-format +msgid "background worker \"%s\"" +msgstr "фоновый процеÑÑ \"%s\"" -#: postmaster/postmaster.c:3160 postmaster/postmaster.c:3180 -#: postmaster/postmaster.c:3187 postmaster/postmaster.c:3205 +#: postmaster/postmaster.c:3201 postmaster/postmaster.c:3221 +#: postmaster/postmaster.c:3228 postmaster/postmaster.c:3246 msgid "server process" msgstr "процеÑÑ Ñервера" -#: postmaster/postmaster.c:3259 +#: postmaster/postmaster.c:3300 #, c-format msgid "terminating any other active server processes" msgstr "завершение вÑех оÑтальных активных Ñерверных процеÑÑов" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3515 +#: postmaster/postmaster.c:3556 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) завершилÑÑ Ñ ÐºÐ¾Ð´Ð¾Ð¼ выхода %d" -#: postmaster/postmaster.c:3517 postmaster/postmaster.c:3528 -#: postmaster/postmaster.c:3539 postmaster/postmaster.c:3548 -#: postmaster/postmaster.c:3558 +#: postmaster/postmaster.c:3558 postmaster/postmaster.c:3569 +#: postmaster/postmaster.c:3580 postmaster/postmaster.c:3589 +#: postmaster/postmaster.c:3599 #, c-format msgid "Failed process was running: %s" msgstr "ЗавершившийÑÑ Ð¿Ñ€Ð¾Ñ†ÐµÑÑ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñл дейÑтвие: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3525 +#: postmaster/postmaster.c:3566 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) был прерван иÑключением 0x%X" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3535 +#: postmaster/postmaster.c:3576 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) был завершён по Ñигналу %d: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3546 +#: postmaster/postmaster.c:3587 #, c-format msgid "%s (PID %d) was terminated by signal %d" msgstr "%s (PID %d) был завершён по Ñигналу %d" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3556 +#: postmaster/postmaster.c:3597 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" msgstr "%s (PID %d) завершилÑÑ Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтным кодом ÑоÑтоÑÐ½Ð¸Ñ %d" -#: postmaster/postmaster.c:3743 +#: postmaster/postmaster.c:3780 #, c-format msgid "abnormal database system shutdown" msgstr "аварийное выключение ÑиÑтемы БД" -#: postmaster/postmaster.c:3783 +#: postmaster/postmaster.c:3820 #, c-format msgid "all server processes terminated; reinitializing" msgstr "вÑе Ñерверные процеÑÑÑ‹ завершены... переинициализациÑ" -#: postmaster/postmaster.c:3949 postmaster/postmaster.c:5343 -#: postmaster/postmaster.c:5649 +#: postmaster/postmaster.c:3990 postmaster/postmaster.c:5424 +#: postmaster/postmaster.c:5798 #, c-format msgid "could not generate random cancel key" msgstr "не удалоÑÑŒ Ñгенерировать Ñлучайный ключ отмены" -#: postmaster/postmaster.c:4003 +#: postmaster/postmaster.c:4044 #, c-format msgid "could not fork new process for connection: %m" msgstr "породить новый процеÑÑ Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ удалоÑÑŒ: %m" -#: postmaster/postmaster.c:4045 +#: postmaster/postmaster.c:4086 msgid "could not fork new process for connection: " msgstr "породить новый процеÑÑ Ð´Ð»Ñ ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ удалоÑÑŒ: " -#: postmaster/postmaster.c:4159 +#: postmaster/postmaster.c:4200 #, c-format msgid "connection received: host=%s port=%s" msgstr "принÑто подключение: узел=%s порт=%s" -#: postmaster/postmaster.c:4164 +#: postmaster/postmaster.c:4205 #, c-format msgid "connection received: host=%s" msgstr "принÑто подключение: узел=%s" -#: postmaster/postmaster.c:4449 +#: postmaster/postmaster.c:4490 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "запуÑтить Ñерверный процеÑÑ \"%s\" не удалоÑÑŒ: %m" -#: postmaster/postmaster.c:4792 +#: postmaster/postmaster.c:4643 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "" +"чиÑло повторных попыток Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ñемой памÑти доÑтигло предела" + +#: postmaster/postmaster.c:4644 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Это может быть вызвано антивируÑным ПО или механизмом ASLR." + +#: postmaster/postmaster.c:4855 #, c-format msgid "SSL configuration could not be loaded in child process" msgstr "не удалоÑÑŒ загрузить конфигурацию SSL в дочерний процеÑÑ" -#: postmaster/postmaster.c:4924 +#: postmaster/postmaster.c:4987 #, c-format msgid "Please report this to ." msgstr "" "ПожалуйÑта, напишите об Ñтой ошибке по адреÑу ." -#: postmaster/postmaster.c:5003 +#: postmaster/postmaster.c:5074 #, c-format msgid "database system is ready to accept read only connections" msgstr "ÑиÑтема БД готова к подключениÑм в режиме \"только чтение\"" -#: postmaster/postmaster.c:5271 +#: postmaster/postmaster.c:5352 #, c-format msgid "could not fork startup process: %m" msgstr "породить Ñтартовый процеÑÑ Ð½Ðµ удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5275 +#: postmaster/postmaster.c:5356 #, c-format msgid "could not fork background writer process: %m" msgstr "породить процеÑÑ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð¹ запиÑи не удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5279 +#: postmaster/postmaster.c:5360 #, c-format msgid "could not fork checkpointer process: %m" msgstr "породить процеÑÑ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… точек не удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5283 +#: postmaster/postmaster.c:5364 #, c-format msgid "could not fork WAL writer process: %m" msgstr "породить процеÑÑ Ð·Ð°Ð¿Ð¸Ñи WAL не удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5287 +#: postmaster/postmaster.c:5368 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "породить процеÑÑ ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ WAL не удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5291 +#: postmaster/postmaster.c:5372 #, c-format msgid "could not fork process: %m" msgstr "породить процеÑÑ Ð½Ðµ удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5460 postmaster/postmaster.c:5483 +#: postmaster/postmaster.c:5569 postmaster/postmaster.c:5592 #, c-format msgid "database connection requirement not indicated during registration" msgstr "" "при региÑтрации фонового процеÑÑа не указывалоÑÑŒ, что ему требуетÑÑ " "подключение к БД" -#: postmaster/postmaster.c:5467 postmaster/postmaster.c:5490 +#: postmaster/postmaster.c:5576 postmaster/postmaster.c:5599 #, c-format msgid "invalid processing mode in background worker" msgstr "неправильный режим обработки в фоновом процеÑÑе" -#: postmaster/postmaster.c:5542 +#: postmaster/postmaster.c:5671 #, c-format msgid "starting background worker process \"%s\"" msgstr "запуÑк фонового рабочего процеÑÑа \"%s\"" -#: postmaster/postmaster.c:5553 +#: postmaster/postmaster.c:5683 #, c-format msgid "could not fork worker process: %m" msgstr "породить рабочий процеÑÑ Ð½Ðµ удалоÑÑŒ: %m" -#: postmaster/postmaster.c:5950 +#: postmaster/postmaster.c:6119 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "" "продублировать Ñокет %d Ð´Ð»Ñ Ñерверного процеÑÑа не удалоÑÑŒ (код ошибки: %d)" -#: postmaster/postmaster.c:5982 +#: postmaster/postmaster.c:6151 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "Ñоздать наÑледуемый Ñокет не удалоÑÑŒ (код ошибки: %d)\n" -#: postmaster/postmaster.c:6011 +#: postmaster/postmaster.c:6180 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "открыть файл Ñерверных переменных \"%s\" не удалоÑÑŒ: %s\n" -#: postmaster/postmaster.c:6018 +#: postmaster/postmaster.c:6187 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "прочитать файл Ñерверных переменных \"%s\" не удалоÑÑŒ: %s\n" -#: postmaster/postmaster.c:6027 +#: postmaster/postmaster.c:6196 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "не удалоÑÑŒ Ñтереть файл \"%s\": %s\n" -#: postmaster/postmaster.c:6044 +#: postmaster/postmaster.c:6213 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "отобразить файл Ñерверных переменных не удалоÑÑŒ (код ошибки: %lu)\n" -#: postmaster/postmaster.c:6053 +#: postmaster/postmaster.c:6222 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "" -"отключить отображение файла Ñерверных переменных не удалоÑÑŒ (код ошибки: " -"%lu)\n" +"отключить отображение файла Ñерверных переменных не удалоÑÑŒ (код ошибки: %lu)" +"\n" -#: postmaster/postmaster.c:6060 +#: postmaster/postmaster.c:6229 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "" "закрыть указатель файла Ñерверных переменных не удалоÑÑŒ (код ошибки: %lu)\n" -#: postmaster/postmaster.c:6221 +#: postmaster/postmaster.c:6393 #, c-format msgid "could not read exit code for process\n" msgstr "прочитать код Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑа не удалоÑÑŒ\n" -#: postmaster/postmaster.c:6226 +#: postmaster/postmaster.c:6398 #, c-format msgid "could not post child completion status\n" msgstr "отправить ÑоÑтоÑние Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾Ð¼ÐºÐ° не удалоÑÑŒ\n" -#: postmaster/syslogger.c:452 postmaster/syslogger.c:1053 +#: postmaster/syslogger.c:471 postmaster/syslogger.c:1147 #, c-format msgid "could not read from logger pipe: %m" msgstr "не удалоÑÑŒ прочитать из канала протоколированиÑ: %m" -#: postmaster/syslogger.c:502 +#: postmaster/syslogger.c:521 #, c-format msgid "logger shutting down" msgstr "оÑтановка протоколированиÑ" -#: postmaster/syslogger.c:546 postmaster/syslogger.c:560 +#: postmaster/syslogger.c:565 postmaster/syslogger.c:579 #, c-format msgid "could not create pipe for syslog: %m" msgstr "не удалоÑÑŒ Ñоздать канал Ð´Ð»Ñ syslog: %m" -#: postmaster/syslogger.c:596 +#: postmaster/syslogger.c:630 #, c-format msgid "could not fork system logger: %m" msgstr "не удалоÑÑŒ породить процеÑÑ ÑиÑтемного протоколированиÑ: %m" -#: postmaster/syslogger.c:632 +#: postmaster/syslogger.c:666 #, c-format msgid "redirecting log output to logging collector process" msgstr "передача вывода в протокол процеÑÑу Ñбора протоколов" -#: postmaster/syslogger.c:633 +#: postmaster/syslogger.c:667 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "Ð’ дальнейшем протоколы будут выводитьÑÑ Ð² каталог \"%s\"." -#: postmaster/syslogger.c:641 +#: postmaster/syslogger.c:675 #, c-format msgid "could not redirect stdout: %m" msgstr "не удалоÑÑŒ перенаправить stdout: %m" -#: postmaster/syslogger.c:646 postmaster/syslogger.c:663 +#: postmaster/syslogger.c:680 postmaster/syslogger.c:697 #, c-format msgid "could not redirect stderr: %m" msgstr "не удалоÑÑŒ перенаправить stderr: %m" -#: postmaster/syslogger.c:1008 +#: postmaster/syslogger.c:1102 #, c-format msgid "could not write to log file: %s\n" msgstr "не удалоÑÑŒ запиÑать в файл протокола: %s\n" -#: postmaster/syslogger.c:1150 +#: postmaster/syslogger.c:1219 #, c-format msgid "could not open log file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл протокола \"%s\": %m" -#: postmaster/syslogger.c:1212 postmaster/syslogger.c:1256 +#: postmaster/syslogger.c:1281 postmaster/syslogger.c:1331 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "отключение автопрокрутки (чтобы включить, передайте SIGHUP)" @@ -17673,63 +18786,118 @@ msgstr "" "не удалоÑÑŒ определить, какое правило Ñортировки иÑпользовать Ð´Ð»Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрного " "выражениÑ" -#: replication/basebackup.c:303 +#: replication/basebackup.c:343 #, c-format msgid "could not stat control file \"%s\": %m" msgstr "не удалоÑÑŒ найти управлÑющий файл \"%s\": %m" -#: replication/basebackup.c:412 +#: replication/basebackup.c:450 #, c-format msgid "could not find any WAL files" msgstr "не удалоÑÑŒ найти ни одного файла WAL" -#: replication/basebackup.c:425 replication/basebackup.c:439 -#: replication/basebackup.c:448 +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 #, c-format msgid "could not find WAL file \"%s\"" msgstr "не удалоÑÑŒ найти файл WAL \"%s\"" -#: replication/basebackup.c:487 replication/basebackup.c:513 +#: replication/basebackup.c:530 replication/basebackup.c:558 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "неприемлемый размер файла WAL \"%s\"" -#: replication/basebackup.c:499 replication/basebackup.c:1228 +#: replication/basebackup.c:544 replication/basebackup.c:1536 #, c-format msgid "base backup could not send data, aborting backup" msgstr "" "в процеÑÑе базового резервного ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ удалоÑÑŒ передать данные, " "копирование прерываетÑÑ" -#: replication/basebackup.c:601 replication/basebackup.c:610 -#: replication/basebackup.c:619 replication/basebackup.c:628 -#: replication/basebackup.c:637 replication/basebackup.c:648 -#: replication/basebackup.c:665 +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "вÑего ошибок контрольных Ñумм: %s" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "при базовом резервном копировании выÑвлены ошибки контрольных Ñумм" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 #, c-format msgid "duplicate option \"%s\"" msgstr "повторÑющийÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ \"%s\"" -#: replication/basebackup.c:654 utils/misc/guc.c:5749 +#: replication/basebackup.c:717 utils/misc/guc.c:6027 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d вне диапазона, допуÑтимого Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\" (%d .. %d)" -#: replication/basebackup.c:928 replication/basebackup.c:1025 +#: replication/basebackup.c:991 replication/basebackup.c:1161 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "не удалоÑÑŒ получить информацию о файле или каталоге \"%s\": %m" -#: replication/basebackup.c:1180 +#: replication/basebackup.c:1316 #, c-format msgid "skipping special file \"%s\"" msgstr "Ñпециальный файл \"%s\" пропуÑкаетÑÑ" -#: replication/basebackup.c:1293 +#: replication/basebackup.c:1421 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "неверный номер Ñегмента %d в файле \"%s\"" + +#: replication/basebackup.c:1440 +#, c-format +msgid "" +"cannot verify checksum in file \"%s\", block %d: read buffer size %d and " +"page size %d differ" +msgstr "" +"не удалоÑÑŒ проверить контрольную Ñумму в файле \"%s\", блоке %d: размер " +"прочитанного буфера (%d) отличаетÑÑ Ð¾Ñ‚ размера Ñтраницы (%d)" + +#: replication/basebackup.c:1484 replication/basebackup.c:1500 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð² файле \"%s\": %m" + +#: replication/basebackup.c:1492 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "не удалоÑÑŒ заново прочитать блок %d файла \"%s\": %m" + +#: replication/basebackup.c:1516 +#, c-format +msgid "" +"checksum verification failed in file \"%s\", block %d: calculated %X but " +"expected %X" +msgstr "" +"ошибка контрольной Ñуммы в файле \"%s\", блоке %d: вычиÑлено значение %X, но " +"ожидалоÑÑŒ %X" + +#: replication/basebackup.c:1523 +#, c-format +msgid "" +"further checksum verification failures in file \"%s\" will not be reported" +msgstr "" +"о дальнейших ошибках контрольных Ñумм в файле \"%s\" ÑообщатьÑÑ Ð½Ðµ будет" + +#: replication/basebackup.c:1581 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "вÑего в файле \"%s\" обнаружено ошибок контрольных Ñумм: %d" + +#: replication/basebackup.c:1609 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "Ñлишком длинное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° tar: \"%s\"" -#: replication/basebackup.c:1298 +#: replication/basebackup.c:1614 #, c-format msgid "" "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" @@ -17737,17 +18905,17 @@ msgstr "" "цель ÑимволичеÑкой ÑÑылки Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° tar: Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\", " "цель \"%s\"" -#: replication/libpqwalreceiver/libpqwalreceiver.c:226 +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 #, c-format msgid "invalid connection string syntax: %s" msgstr "ошибочный ÑинтакÑÐ¸Ñ Ñтроки подключениÑ: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:250 +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 #, c-format msgid "could not parse connection string: %s" msgstr "не удалоÑÑŒ разобрать Ñтроку подключениÑ: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:300 +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 #, c-format msgid "" "could not receive database system identifier and timeline ID from the " @@ -17756,13 +18924,13 @@ msgstr "" "не удалоÑÑŒ получить идентификатор СУБД и код линии времени Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ " "Ñервера: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:311 -#: replication/libpqwalreceiver/libpqwalreceiver.c:515 +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 +#: replication/libpqwalreceiver/libpqwalreceiver.c:550 #, c-format msgid "invalid response from primary server" msgstr "неверный ответ главного Ñервера" -#: replication/libpqwalreceiver/libpqwalreceiver.c:312 +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 #, c-format msgid "" "Could not identify system: got %d rows and %d fields, expected %d rows and " @@ -17771,155 +18939,165 @@ msgstr "" "Ðе удалоÑÑŒ идентифицировать ÑиÑтему, получено Ñтрок: %d, полей: %d " "(ожидалоÑÑŒ: %d и %d (или более))." -#: replication/libpqwalreceiver/libpqwalreceiver.c:378 -#: replication/libpqwalreceiver/libpqwalreceiver.c:384 -#: replication/libpqwalreceiver/libpqwalreceiver.c:409 +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 +#: replication/libpqwalreceiver/libpqwalreceiver.c:416 +#: replication/libpqwalreceiver/libpqwalreceiver.c:441 #, c-format msgid "could not start WAL streaming: %s" msgstr "не удалоÑÑŒ начать транÑлÑцию WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:428 +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "не удалоÑÑŒ отправить главному Ñерверу Ñообщение о конце передачи: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:450 +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "неожиданный набор данных поÑле конца передачи" -#: replication/libpqwalreceiver/libpqwalreceiver.c:470 +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "ошибка при оÑтановке потоковой операции COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 #, c-format msgid "error reading result of streaming command: %s" msgstr "ошибка при чтении результата команды передачи: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:478 -#: replication/libpqwalreceiver/libpqwalreceiver.c:688 +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 +#: replication/libpqwalreceiver/libpqwalreceiver.c:741 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "неожиданный результат поÑле CommandComplete: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:504 +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "не удалоÑÑŒ получить файл иÑтории линии времени Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñервера: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:516 +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." msgstr "ОжидалÑÑ 1 кортеж Ñ 2 полÑми, однако получено кортежей: %d, полей: %d." -#: replication/libpqwalreceiver/libpqwalreceiver.c:663 -#: replication/libpqwalreceiver/libpqwalreceiver.c:701 -#: replication/libpqwalreceiver/libpqwalreceiver.c:707 +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 +#: replication/libpqwalreceiver/libpqwalreceiver.c:756 +#: replication/libpqwalreceiver/libpqwalreceiver.c:762 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "не удалоÑÑŒ извлечь данные из потока WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:726 +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 #, c-format msgid "could not send data to WAL stream: %s" msgstr "не удалоÑÑŒ отправить данные в поток WAL: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:775 +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 #, c-format msgid "could not create replication slot \"%s\": %s" msgstr "не удалоÑÑŒ Ñоздать Ñлот репликации \"%s\": %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:809 +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 #, c-format -msgid "invalid query responser" +msgid "invalid query response" msgstr "неверный ответ на запроÑ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:810 +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 #, c-format msgid "Expected %d fields, got %d fields." msgstr "ОжидалоÑÑŒ полей: %d, получено: %d." -#: replication/libpqwalreceiver/libpqwalreceiver.c:880 +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 #, c-format msgid "the query interface requires a database connection" msgstr "Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñа запроÑов требуетÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ к БД" -#: replication/libpqwalreceiver/libpqwalreceiver.c:911 +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 msgid "empty query" msgstr "пуÑтой запроÑ" -#: replication/logical/launcher.c:242 +#: replication/logical/launcher.c:310 #, c-format msgid "starting logical replication worker for subscription \"%s\"" msgstr "" "запуÑкаетÑÑ Ð¿Ñ€Ð¾Ñ†ÐµÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\"" -#: replication/logical/launcher.c:249 +#: replication/logical/launcher.c:317 #, c-format msgid "cannot start logical replication workers when max_replication_slots = 0" msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð¿ÑƒÑтить процеÑÑÑ‹-обработчики логичеÑкой репликации при " "max_replication_slots = 0" -#: replication/logical/launcher.c:273 +#: replication/logical/launcher.c:397 #, c-format -msgid "out of logical replication workers slots" +msgid "out of logical replication worker slots" msgstr "недоÑтаточно Ñлотов Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑов логичеÑкой репликации" -#: replication/logical/launcher.c:274 +#: replication/logical/launcher.c:398 #, c-format msgid "You might need to increase max_logical_replication_workers." msgstr "Возможно, Ñледует увеличить параметр max_logical_replication_workers." -#: replication/logical/launcher.c:315 +#: replication/logical/launcher.c:453 #, c-format -msgid "out of background workers slots" +msgid "out of background worker slots" msgstr "недоÑтаточно Ñлотов Ð´Ð»Ñ Ñ„Ð¾Ð½Ð¾Ð²Ñ‹Ñ… рабочих процеÑÑов" -#: replication/logical/launcher.c:316 +#: replication/logical/launcher.c:454 #, c-format msgid "You might need to increase max_worker_processes." msgstr "Возможно, Ñледует увеличить параметр max_worker_processes." -#: replication/logical/launcher.c:457 +#: replication/logical/launcher.c:661 #, c-format -msgid "logical replication worker slot %d already used by another worker" -msgstr "Ñлот обработчика логичеÑкой репликации %d уже занÑÑ‚ другим процеÑÑом" +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "" +"Ñлот обработчика логичеÑкой репликации %d пуÑÑ‚, подключитьÑÑ Ðº нему нельзÑ" -#: replication/logical/launcher.c:637 +#: replication/logical/launcher.c:670 #, c-format -msgid "logical replication launcher started" -msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка логичеÑкой репликации запущен" +msgid "" +"logical replication worker slot %d is already used by another worker, cannot " +"attach" +msgstr "" +"Ñлот обработчика логичеÑкой репликации %d уже занÑÑ‚ другим процеÑÑом, " +"подключитьÑÑ Ðº нему нельзÑ" -#: replication/logical/launcher.c:738 +#: replication/logical/launcher.c:988 #, c-format -msgid "logical replication launcher shutting down" -msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка логичеÑкой репликации оÑтановлен" +msgid "logical replication launcher started" +msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка логичеÑкой репликации запущен" -#: replication/logical/logical.c:83 +#: replication/logical/logical.c:90 #, c-format msgid "logical decoding requires wal_level >= logical" msgstr "Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:95 #, c-format msgid "logical decoding requires a database connection" msgstr "Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ðµ к БД" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:113 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "логичеÑкое декодирование Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в процеÑÑе воÑÑтановлениÑ" -#: replication/logical/logical.c:236 replication/logical/logical.c:348 +#: replication/logical/logical.c:255 replication/logical/logical.c:386 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "" "физичеÑкий Ñлот репликации Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого декодированиÑ" -#: replication/logical/logical.c:241 replication/logical/logical.c:353 +#: replication/logical/logical.c:260 replication/logical/logical.c:391 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "Ñлот репликации \"%s\" Ñоздан не в Ñтой базе данных" -#: replication/logical/logical.c:248 +#: replication/logical/logical.c:267 #, c-format msgid "" "cannot create logical replication slot in transaction that has performed " @@ -17927,29 +19105,29 @@ msgid "" msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздать логичеÑкий Ñлот репликации в транзакции, оÑущеÑтвлÑющей запиÑÑŒ" -#: replication/logical/logical.c:390 +#: replication/logical/logical.c:431 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "начинаетÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкое декодирование Ð´Ð»Ñ Ñлота \"%s\"" -#: replication/logical/logical.c:392 +#: replication/logical/logical.c:433 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "передача транзакций, фикÑируемых поÑле %X/%X, чтение WAL Ñ %X/%X" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Передача транзакций, фикÑируемых поÑле %X/%X, чтение WAL Ñ %X/%X." -#: replication/logical/logical.c:527 +#: replication/logical/logical.c:583 #, c-format msgid "" "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "" "Ñлот \"%s\", модуль вывода \"%s\", в обработчике %s, ÑвÑзанный LSN: %X/%X" -#: replication/logical/logical.c:534 +#: replication/logical/logical.c:590 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "Ñлот \"%s\", модуль вывода \"%s\", в обработчике %s" -#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "" @@ -17976,29 +19154,29 @@ msgstr "маÑÑив должен быть одномерным" msgid "array must not contain nulls" msgstr "маÑÑив не должен Ñодержать Ñлементы null" -#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2282 -#: utils/adt/jsonb.c:1357 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 +#: utils/adt/jsonb.c:1269 #, c-format msgid "array must have even number of elements" msgstr "в маÑÑиве должно быть чётное чиÑло Ñлементов" -#: replication/logical/logicalfuncs.c:268 +#: replication/logical/logicalfuncs.c:269 #, c-format msgid "" -"logical decoding output plugin \"%s\" produces binary output, but function " -"\"%s\" expects textual data" +"logical decoding output plugin \"%s\" produces binary output, but function \"" +"%s\" expects textual data" msgstr "" "модуль вывода логичеÑкого Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s\" выдаёт двоичные данные, но " "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" ожидает текÑтовые" -#: replication/logical/origin.c:180 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "" "запрашивать или модифицировать иÑточники репликации могут только " "Ñуперпользователи" -#: replication/logical/origin.c:185 +#: replication/logical/origin.c:190 #, c-format msgid "" "cannot query or manipulate replication origin when max_replication_slots = 0" @@ -18006,54 +19184,64 @@ msgstr "" "запрашивать или модифицировать иÑточники репликации при " "max_replication_slots = 0 нельзÑ" -#: replication/logical/origin.c:190 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "модифицировать иÑточники репликации во Ð²Ñ€ÐµÐ¼Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" -#: replication/logical/origin.c:314 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "иÑточник репликации \"%s\" не ÑущеÑтвует" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "найти Ñвободный OID Ð´Ð»Ñ Ð¸Ñточника репликации не удалоÑÑŒ" -#: replication/logical/origin.c:351 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "" "удалить иÑточник репликации Ñ OID %d нельзÑ, он иÑпользуетÑÑ Ð¿Ñ€Ð¾Ñ†ÐµÑÑом Ñ PID " "%d" -#: replication/logical/origin.c:664 +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "иÑточник репликации Ñ OID %u не ÑущеÑтвует" + +#: replication/logical/origin.c:725 #, c-format msgid "replication checkpoint has wrong magic %u instead of %u" msgstr "" "ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° репликации имеет неправильную Ñигнатуру (%u вмеÑто %u)" -#: replication/logical/origin.c:696 +#: replication/logical/origin.c:757 #, c-format msgid "could not read file \"%s\": read %d of %zu" msgstr "не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %zu)" -#: replication/logical/origin.c:705 +#: replication/logical/origin.c:766 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "" "не удалоÑÑŒ найти Ñвободную Ñчейку Ð´Ð»Ñ ÑоÑтоÑÐ½Ð¸Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸, увеличьте " "max_replication_slots" -#: replication/logical/origin.c:723 +#: replication/logical/origin.c:784 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "" "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма файла контрольной точки Ð´Ð»Ñ Ñлота репликации (%u " "вмеÑто %u)" -#: replication/logical/origin.c:847 +#: replication/logical/origin.c:908 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "иÑточник репликации Ñ OID %d уже занÑÑ‚ процеÑÑом Ñ PID %d" -#: replication/logical/origin.c:858 replication/logical/origin.c:1038 +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 #, c-format msgid "" "could not find free replication state slot for replication origin with OID %u" @@ -18061,39 +19249,34 @@ msgstr "" "не удалоÑÑŒ найти Ñвободный Ñлот ÑоÑтоÑÐ½Ð¸Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ð´Ð»Ñ Ð¸Ñточника " "репликации Ñ OID %u" -#: replication/logical/origin.c:860 replication/logical/origin.c:1040 -#: replication/slot.c:1437 +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 +#: replication/slot.c:1559 #, c-format msgid "Increase max_replication_slots and try again." msgstr "Увеличьте параметр max_replication_slots и повторите попытку." -#: replication/logical/origin.c:997 +#: replication/logical/origin.c:1065 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð½Ð°Ñтроить иÑточник репликации, когда он уже наÑтроен" -#: replication/logical/origin.c:1026 +#: replication/logical/origin.c:1094 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "идентификатор репликации %d уже занÑÑ‚ процеÑÑом Ñ PID %d" -#: replication/logical/origin.c:1072 replication/logical/origin.c:1267 -#: replication/logical/origin.c:1287 +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 +#: replication/logical/origin.c:1363 #, c-format msgid "no replication origin is configured" msgstr "ни один иÑточник репликации не наÑтроен" -#: replication/logical/relation.c:266 +#: replication/logical/relation.c:255 #, c-format msgid "logical replication target relation \"%s.%s\" does not exist" msgstr "целевое отношение логичеÑкой репликации \"%s.%s\" не ÑущеÑтвует" -#: replication/logical/relation.c:277 -#, c-format -msgid "logical replication target relation \"%s.%s\" is not a table" -msgstr "целевое отношение логичеÑкой репликации \"%s.%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹" - -#: replication/logical/relation.c:304 +#: replication/logical/relation.c:297 #, c-format msgid "" "logical replication target relation \"%s.%s\" is missing some replicated " @@ -18102,7 +19285,7 @@ msgstr "" "в целевом отношении логичеÑкой репликации (\"%s.%s\") отÑутÑтвуют некоторые " "реплицируемые Ñтолбцы" -#: replication/logical/relation.c:343 +#: replication/logical/relation.c:337 #, c-format msgid "" "logical replication target relation \"%s.%s\" uses system columns in REPLICA " @@ -18111,39 +19294,19 @@ msgstr "" "в целевом отношении логичеÑкой репликации (\"%s.%s\") в индекÑе REPLICA " "IDENTITY иÑпользуютÑÑ ÑиÑтемные Ñтолбцы" -#: replication/logical/relation.c:459 -#, c-format -msgid "builtin type %u not found" -msgstr "вÑтроенный тип %u не найден" - -#: replication/logical/relation.c:460 -#, c-format -msgid "" -"This can be caused by having publisher with higher major version than " -"subscriber" -msgstr "" -"Это может быть вызвано тем, что на Ñервере публикации уÑтановлена более " -"Ð½Ð¾Ð²Ð°Ñ Ð¾ÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ, чем на подпиÑчике" - -#: replication/logical/relation.c:492 -#, c-format -msgid "data type \"%s.%s\" required for logical replication does not exist" -msgstr "" -"тип данных \"%s.%s\", требуемый Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации, не ÑущеÑтвует" - -#: replication/logical/reorderbuffer.c:2288 +#: replication/logical/reorderbuffer.c:2507 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "не удалоÑÑŒ запиÑать в файл данных Ð´Ð»Ñ XID %u: %m" -#: replication/logical/reorderbuffer.c:2387 -#: replication/logical/reorderbuffer.c:2409 +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "не удалоÑÑŒ прочитать из файла подкачки буфера переÑортировки: %m" -#: replication/logical/reorderbuffer.c:2391 -#: replication/logical/reorderbuffer.c:2413 +#: replication/logical/reorderbuffer.c:2604 +#: replication/logical/reorderbuffer.c:2626 #, c-format msgid "" "could not read from reorderbuffer spill file: read %d instead of %u bytes" @@ -18151,19 +19314,24 @@ msgstr "" "не удалоÑÑŒ прочитать из файла подкачки буфера переÑортировки (прочитано " "байт: %d, требовалоÑÑŒ: %u)" -#: replication/logical/reorderbuffer.c:3071 +#: replication/logical/reorderbuffer.c:2849 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "файл \"%s\" при удалении pg_replslot/%s/*.xid не был удалён: %m" + +#: replication/logical/reorderbuffer.c:3315 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "" "не удалоÑÑŒ прочитать из файла \"%s\" (прочитано байт: %d, требовалоÑÑŒ: %d)" -#: replication/logical/snapbuild.c:564 +#: replication/logical/snapbuild.c:612 #, c-format msgid "initial slot snapshot too large" msgstr "изначальный Ñнимок Ñлота Ñлишком большой" # skip-rule: capital-letter-first -#: replication/logical/snapbuild.c:616 +#: replication/logical/snapbuild.c:666 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" msgid_plural "" @@ -18175,133 +19343,140 @@ msgstr[1] "" msgstr[2] "" "ÑкÑпортирован Ñнимок логичеÑкого декодированиÑ: \"%s\" (ид. транзакций: %u)" -#: replication/logical/snapbuild.c:935 replication/logical/snapbuild.c:1300 -#: replication/logical/snapbuild.c:1843 +#: replication/logical/snapbuild.c:1271 replication/logical/snapbuild.c:1364 +#: replication/logical/snapbuild.c:1878 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð¾Ñтиг точки ÑоглаÑованноÑти в %X/%X" -#: replication/logical/snapbuild.c:937 -#, c-format -msgid "Transaction ID %u finished; no more running transactions." -msgstr "Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %u завершена, больше активных транзакций нет." - -#: replication/logical/snapbuild.c:1302 +#: replication/logical/snapbuild.c:1273 #, c-format msgid "There are no running transactions." msgstr "Больше активных транзакций нет." -#: replication/logical/snapbuild.c:1364 +#: replication/logical/snapbuild.c:1315 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "" "процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого Ð´ÐµÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð°ÑˆÑ‘Ð» начальную Ñтартовую точку в %X/%X" +#: replication/logical/snapbuild.c:1317 replication/logical/snapbuild.c:1341 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Ожидание транзакций (примерно %d), Ñтарее %u до конца." + +#: replication/logical/snapbuild.c:1339 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "" +"при логичеÑком декодировании найдена Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° ÑоглаÑованноÑти в %X/%X" + #: replication/logical/snapbuild.c:1366 #, c-format -msgid "%u transaction needs to finish." -msgid_plural "%u transactions need to finish." -msgstr[0] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." -msgstr[1] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." -msgstr[2] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." +msgid "There are no old transactions anymore." +msgstr "Больше Ñтарых транзакций нет." -#: replication/logical/snapbuild.c:1711 replication/logical/snapbuild.c:1739 -#: replication/logical/snapbuild.c:1755 replication/logical/snapbuild.c:1771 +#: replication/logical/snapbuild.c:1740 replication/logical/snapbuild.c:1773 +#: replication/logical/snapbuild.c:1793 replication/logical/snapbuild.c:1812 #, c-format msgid "could not read file \"%s\", read %d of %d: %m" msgstr "не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %d): %m" -#: replication/logical/snapbuild.c:1717 +#: replication/logical/snapbuild.c:1747 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "" "файл ÑоÑтоÑÐ½Ð¸Ñ snapbuild \"%s\" имеет неправильную Ñигнатуру (%u вмеÑто %u)" -#: replication/logical/snapbuild.c:1722 +#: replication/logical/snapbuild.c:1753 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "" "файл ÑоÑтоÑÐ½Ð¸Ñ snapbuild \"%s\" имеет неправильную верÑию (%u вмеÑто %u)" -#: replication/logical/snapbuild.c:1784 +#: replication/logical/snapbuild.c:1825 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "" "в файле ÑоÑтоÑÐ½Ð¸Ñ snapbuild \"%s\" Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма (%u вмеÑто %u)" -#: replication/logical/snapbuild.c:1845 +#: replication/logical/snapbuild.c:1880 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "ЛогичеÑкое декодирование начнётÑÑ Ñ Ñохранённого Ñнимка." -#: replication/logical/snapbuild.c:1918 +#: replication/logical/snapbuild.c:1952 #, c-format msgid "could not parse file name \"%s\"" msgstr "не удалоÑÑŒ разобрать Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\"" -#: replication/logical/tablesync.c:128 +#: replication/logical/tablesync.c:138 #, c-format -msgid "logical replication synchronization worker finished processing" -msgstr "процеÑÑ Ñинхронизации логичеÑкой репликации закончил обработку" +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has finished" +msgstr "" +"процеÑÑ Ñинхронизации таблицы при логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\", " +"таблицы \"%s\" закончил обработку" -#: replication/logical/tablesync.c:566 +#: replication/logical/tablesync.c:685 #, c-format msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" msgstr "" "не удалоÑÑŒ получить информацию о таблице \"%s.%s\" Ñ Ñервера публикации: %s" -#: replication/logical/tablesync.c:572 +#: replication/logical/tablesync.c:691 #, c-format msgid "table \"%s.%s\" not found on publisher" msgstr "таблица \"%s.%s\" не найдена на Ñервере публикации" -#: replication/logical/tablesync.c:602 +#: replication/logical/tablesync.c:721 #, c-format msgid "could not fetch table info for table \"%s.%s\": %s" msgstr "не удалоÑÑŒ получить информацию о таблице \"%s.%s\": %s" -#: replication/logical/tablesync.c:671 +#: replication/logical/tablesync.c:791 #, c-format msgid "could not start initial contents copy for table \"%s.%s\": %s" msgstr "" "не удалоÑÑŒ начать копирование начального Ñодержимого таблицы \"%s.%s\": %s" -#: replication/logical/tablesync.c:774 +#: replication/logical/tablesync.c:904 #, c-format msgid "table copy could not start transaction on publisher" msgstr "" "при копировании таблицы не удалоÑÑŒ начать транзакцию на Ñервере публикации" -#: replication/logical/tablesync.c:794 +#: replication/logical/tablesync.c:926 #, c-format msgid "table copy could not finish transaction on publisher" msgstr "" "при копировании таблицы не удалоÑÑŒ завершить транзакцию на Ñервере публикации" -#: replication/logical/worker.c:282 +#: replication/logical/worker.c:307 #, c-format msgid "" -"processing remote data for replication target relation \"%s.%s\" column \"%s" -"\", remote type %s, local type %s" +"processing remote data for replication target relation \"%s.%s\" column \"" +"%s\", remote type %s, local type %s" msgstr "" "обработка внешних данных Ð´Ð»Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð³Ð¾ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ \"%s.%s\" Ñтолбца " "\"%s\", удалённый тип %s, локальный тип %s" -#: replication/logical/worker.c:483 +#: replication/logical/worker.c:528 #, c-format msgid "ORIGIN message sent out of order" msgstr "Ñообщение ORIGIN отправлено неумеÑтно" -#: replication/logical/worker.c:614 +#: replication/logical/worker.c:661 #, c-format msgid "" -"publisher does not send replica identity column expected by the logical " +"publisher did not send replica identity column expected by the logical " "replication target relation \"%s.%s\"" msgstr "" "Ñервер публикации не передал Ñтолбец идентификации реплики, ожидаемый Ð´Ð»Ñ " "целевого Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации \"%s.%s\"" -#: replication/logical/worker.c:621 +#: replication/logical/worker.c:668 #, c-format msgid "" "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY " @@ -18312,140 +19487,161 @@ msgstr "" "IDENTITY, ни ключа PRIMARY KEY, и публикуемое отношение не имеет " "характериÑтики REPLICA IDENTITY FULL" -#: replication/logical/worker.c:828 -#, c-format -msgid "" -"logical replication could not find row for delete in replication target %s" -msgstr "" -"при логичеÑкой репликации не удалоÑÑŒ найти Ñтроку Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð² целевом " -"отношении репликации %s" - -#: replication/logical/worker.c:895 +#: replication/logical/worker.c:1007 #, c-format -msgid "invalid logical replication message type %c" -msgstr "неверный тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации %c" +msgid "invalid logical replication message type \"%c\"" +msgstr "неверный тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации \"%c\"" -#: replication/logical/worker.c:1032 +#: replication/logical/worker.c:1148 #, c-format msgid "data stream from publisher has ended" msgstr "поток данных Ñ Ñервера публикации закончилÑÑ" -#: replication/logical/worker.c:1168 +#: replication/logical/worker.c:1307 #, c-format msgid "terminating logical replication worker due to timeout" -msgstr "завершение обработчика логичеÑкой репликации из-за таймаута" +msgstr "завершение обработчика логичеÑкой репликации из-за тайм-аута" -#: replication/logical/worker.c:1315 +#: replication/logical/worker.c:1455 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will stop because the " -"subscription was removed" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was removed" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " "оÑтановлен, так как подпиÑка была удалена" -#: replication/logical/worker.c:1330 +#: replication/logical/worker.c:1469 +#, c-format +msgid "" +"logical replication apply worker for subscription \"%s\" will stop because " +"the subscription was disabled" +msgstr "" +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"оÑтановлен, так как подпиÑка была отключена" + +#: replication/logical/worker.c:1483 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will restart because the " -"connection information was changed" +"logical replication apply worker for subscription \"%s\" will restart " +"because the connection information was changed" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " "перезапущен из-за Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸ о подключении" -#: replication/logical/worker.c:1345 +#: replication/logical/worker.c:1497 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will restart because " -"subscription was renamed" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription was renamed" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " "перезапущен, так как подпиÑка была переименована" -#: replication/logical/worker.c:1360 +#: replication/logical/worker.c:1514 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will restart because the " -"replication slot name was changed" +"logical replication apply worker for subscription \"%s\" will restart " +"because the replication slot name was changed" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " "перезапущен, так как было изменено Ð¸Ð¼Ñ Ñлота репликации" -#: replication/logical/worker.c:1375 +#: replication/logical/worker.c:1528 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will restart because " -"subscription's publications were changed" +"logical replication apply worker for subscription \"%s\" will restart " +"because subscription's publications were changed" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " "перезапущен из-за Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¹ подпиÑки" -#: replication/logical/worker.c:1391 +#: replication/logical/worker.c:1631 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will stop because the " -"subscription was disabled" +"logical replication apply worker for subscription %u will not start because " +"the subscription was removed during startup" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" будет " -"оÑтановлен, так как подпиÑка была отключена" +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки %u не будет запущен, " +"так как подпиÑка была удалена при Ñтарте" -#: replication/logical/worker.c:1483 +#: replication/logical/worker.c:1643 #, c-format msgid "" -"logical replication worker for subscription \"%s\" will not start because " -"the subscription was disabled during startup" +"logical replication apply worker for subscription \"%s\" will not start " +"because the subscription was disabled during startup" msgstr "" -"процеÑÑ-обработчик логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" не будет " +"применÑющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\" не будет " "запущен, так как подпиÑка была отключена при Ñтарте" -#: replication/pgoutput/pgoutput.c:113 +#: replication/logical/worker.c:1661 +#, c-format +msgid "" +"logical replication table synchronization worker for subscription \"%s\", " +"table \"%s\" has started" +msgstr "" +"процеÑÑ Ñинхронизации таблицы при логичеÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\", " +"таблицы \"%s\" запущен" + +#: replication/logical/worker.c:1665 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "" +"запуÑкаетÑÑ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñющий процеÑÑ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки \"%s\"" + +#: replication/logical/worker.c:1705 +#, c-format +msgid "subscription has no replication slot set" +msgstr "Ð´Ð»Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñки не задан Ñлот репликации" + +#: replication/pgoutput/pgoutput.c:117 #, c-format msgid "invalid proto_version" msgstr "неверное значение proto_version" -#: replication/pgoutput/pgoutput.c:118 +#: replication/pgoutput/pgoutput.c:122 #, c-format -msgid "proto_verson \"%s\" out of range" +msgid "proto_version \"%s\" out of range" msgstr "значение proto_verson \"%s\" вне диапазона" -#: replication/pgoutput/pgoutput.c:135 +#: replication/pgoutput/pgoutput.c:139 #, c-format msgid "invalid publication_names syntax" msgstr "неверный ÑинтакÑÐ¸Ñ publication_names" -#: replication/pgoutput/pgoutput.c:179 +#: replication/pgoutput/pgoutput.c:181 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or lower" msgstr "" "клиент передал proto_version=%d, но мы поддерживаем только протокол %d и ниже" -#: replication/pgoutput/pgoutput.c:185 +#: replication/pgoutput/pgoutput.c:187 #, c-format msgid "client sent proto_version=%d but we only support protocol %d or higher" msgstr "" "клиент передал proto_version=%d, но мы поддерживает только протокол %d и выше" -#: replication/pgoutput/pgoutput.c:191 +#: replication/pgoutput/pgoutput.c:193 #, c-format msgid "publication_names parameter missing" msgstr "отÑутÑтвует параметр publication_names" -#: replication/slot.c:181 +#: replication/slot.c:182 #, c-format msgid "replication slot name \"%s\" is too short" msgstr "Ð¸Ð¼Ñ Ñлота репликации \"%s\" Ñлишком короткое" -#: replication/slot.c:190 +#: replication/slot.c:191 #, c-format msgid "replication slot name \"%s\" is too long" msgstr "Ð¸Ð¼Ñ Ñлота репликации \"%s\" Ñлишком длинное" -#: replication/slot.c:203 +#: replication/slot.c:204 #, c-format msgid "replication slot name \"%s\" contains invalid character" msgstr "Ð¸Ð¼Ñ Ñлота репликации \"%s\" Ñодержит недопуÑтимый Ñимвол" -#: replication/slot.c:205 +#: replication/slot.c:206 #, c-format msgid "" "Replication slot names may only contain lower case letters, numbers, and the " @@ -18454,80 +19650,118 @@ msgstr "" "Ð˜Ð¼Ñ Ñлота репликации может Ñодержать только буквы в нижнем региÑтре, цифры и " "знак подчёркиваниÑ." -#: replication/slot.c:252 +#: replication/slot.c:253 #, c-format msgid "replication slot \"%s\" already exists" msgstr "Ñлот репликации \"%s\" уже ÑущеÑтвует" -#: replication/slot.c:262 +#: replication/slot.c:263 #, c-format msgid "all replication slots are in use" msgstr "иÑпользуютÑÑ Ð²Ñе Ñлоты репликации" -#: replication/slot.c:263 +#: replication/slot.c:264 #, c-format msgid "Free one or increase max_replication_slots." msgstr "ОÑвободите ненужные или увеличьте параметр max_replication_slots." -#: replication/slot.c:359 +#: replication/slot.c:387 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "Ñлот репликации \"%s\" не ÑущеÑтвует" -#: replication/slot.c:363 +#: replication/slot.c:398 replication/slot.c:948 #, c-format msgid "replication slot \"%s\" is active for PID %d" msgstr "Ñлот репликации \"%s\" занÑÑ‚ процеÑÑом Ñ PID %d" -#: replication/slot.c:549 replication/slot.c:1049 replication/slot.c:1398 +#: replication/slot.c:632 replication/slot.c:1141 replication/slot.c:1495 #, c-format msgid "could not remove directory \"%s\"" msgstr "ошибка при удалении каталога \"%s\"" -#: replication/slot.c:898 +#: replication/slot.c:983 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "" "Ñлоты репликации можно иÑпользовать, только еÑли max_replication_slots > 0" -#: replication/slot.c:903 +#: replication/slot.c:988 #, c-format msgid "replication slots can only be used if wal_level >= replica" msgstr "Ñлоты репликации можно иÑпользовать, только еÑли wal_level >= replica" -#: replication/slot.c:1328 replication/slot.c:1368 +#: replication/slot.c:1427 replication/slot.c:1467 #, c-format msgid "could not read file \"%s\", read %d of %u: %m" msgstr "не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %u): %m" -#: replication/slot.c:1337 +#: replication/slot.c:1436 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "" "файл Ñлота репликации \"%s\" имеет неправильную Ñигнатуру (%u вмеÑто %u)" -#: replication/slot.c:1344 +#: replication/slot.c:1443 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "файл ÑоÑтоÑÐ½Ð¸Ñ snapbuild \"%s\" имеет неподдерживаемую верÑию %u" -#: replication/slot.c:1351 +#: replication/slot.c:1450 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "у файла Ñлота репликации \"%s\" Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°: %u" -#: replication/slot.c:1383 +#: replication/slot.c:1482 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "" "в файле Ñлота репликации \"%s\" Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма (%u вмеÑто %u)" -#: replication/slot.c:1436 +#: replication/slot.c:1516 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "ÑущеÑтвует Ñлот логичеÑкой репликации \"%s\", но wal_level < logical" + +#: replication/slot.c:1518 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Смените wal_level на logical или более выÑокий уровень." + +#: replication/slot.c:1522 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "ÑущеÑтвует Ñлот физичеÑкой репликации \"%s\", но wal_level < replica" + +#: replication/slot.c:1524 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Смените wal_level на replica или более выÑокий уровень." + +#: replication/slot.c:1558 #, c-format msgid "too many replication slots active before shutdown" msgstr "перед завершением активно Ñлишком много Ñлотов репликации" -#: replication/syncrep.c:244 +#: replication/slotfuncs.c:490 +#, c-format +msgid "invalid target wal lsn" +msgstr "неверный целевой lsn" + +#: replication/slotfuncs.c:512 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "" +"продвинуть Ñлот репликации, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð³Ð¾ ранее не был зарезервирован WAL, " +"нельзÑ" + +#: replication/slotfuncs.c:528 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" +"продвинуть Ñлот репликации к позиции %X/%X нельзÑ, Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ: %X/%X" + +#: replication/syncrep.c:246 #, c-format msgid "" "canceling the wait for synchronous replication and terminating connection " @@ -18536,7 +19770,7 @@ msgstr "" "отмена Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ñинхронной репликации и закрытие ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ команде " "админиÑтратора" -#: replication/syncrep.c:245 replication/syncrep.c:262 +#: replication/syncrep.c:247 replication/syncrep.c:264 #, c-format msgid "" "The transaction has already committed locally, but might not have been " @@ -18545,148 +19779,148 @@ msgstr "" "Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ ÑƒÐ¶Ðµ была зафикÑирована локально, но возможно не была " "реплицирована на резервный Ñервер." -#: replication/syncrep.c:261 +#: replication/syncrep.c:263 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "отмена Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ñинхронной репликации по запроÑу пользователÑ" -#: replication/syncrep.c:392 +#: replication/syncrep.c:397 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "" "резервный Ñервер \"%s\" теперь имеет приоритет Ñинхронной репликации %u" -#: replication/syncrep.c:453 +#: replication/syncrep.c:460 #, c-format msgid "standby \"%s\" is now a synchronous standby with priority %u" msgstr "резервный Ñервер \"%s\" Ñтал Ñинхронным Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¾Ð¼ %u" -#: replication/syncrep.c:457 +#: replication/syncrep.c:464 #, c-format msgid "standby \"%s\" is now a candidate for quorum synchronous standby" msgstr "" "резервный Ñервер \"%s\" Ñтал кандидатом Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² кворум Ñинхронных " "резервных" -#: replication/syncrep.c:1120 +#: replication/syncrep.c:1164 #, c-format msgid "synchronous_standby_names parser failed" msgstr "ошибка при разборе synchronous_standby_names" -#: replication/syncrep.c:1126 +#: replication/syncrep.c:1170 #, c-format msgid "number of synchronous standbys (%d) must be greater than zero" msgstr "чиÑло Ñинхронных резервных Ñерверов (%d) должно быть больше нулÑ" -#: replication/walreceiver.c:168 +#: replication/walreceiver.c:169 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "завершение процеÑÑа ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° по команде админиÑтратора" -#: replication/walreceiver.c:301 +#: replication/walreceiver.c:309 #, c-format msgid "could not connect to the primary server: %s" msgstr "не удалоÑÑŒ подключитьÑÑ Ðº главному Ñерверу: %s" -#: replication/walreceiver.c:340 +#: replication/walreceiver.c:359 #, c-format msgid "database system identifier differs between the primary and standby" msgstr "идентификаторы СУБД на главном и резервном Ñерверах различаютÑÑ" -#: replication/walreceiver.c:341 +#: replication/walreceiver.c:360 #, c-format msgid "The primary's identifier is %s, the standby's identifier is %s." msgstr "Идентификатор на главном Ñервере: %s, на резервном: %s." -#: replication/walreceiver.c:352 +#: replication/walreceiver.c:371 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "" "поÑледнÑÑ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u на главном Ñервере отÑтаёт от воÑÑтанавливаемой " "линии времени %u" -#: replication/walreceiver.c:388 +#: replication/walreceiver.c:407 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "" "начало передачи журнала Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñервера, Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ð¸ %X/%X на линии времени " "%u" -#: replication/walreceiver.c:393 +#: replication/walreceiver.c:412 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "перезапуÑк передачи журнала Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ð¸ %X/%X на линии времени %u" -#: replication/walreceiver.c:422 +#: replication/walreceiver.c:441 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "продолжить передачу WAL нельзÑ, воÑÑтановление уже окончено" -#: replication/walreceiver.c:459 +#: replication/walreceiver.c:478 #, c-format msgid "replication terminated by primary server" msgstr "Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¿Ñ€ÐµÐºÑ€Ð°Ñ‰ÐµÐ½Ð° главным Ñервером" -#: replication/walreceiver.c:460 +#: replication/walreceiver.c:479 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "Ðа линии времени %u в %X/%X доÑтигнут конец журнала." -#: replication/walreceiver.c:555 +#: replication/walreceiver.c:574 #, c-format msgid "terminating walreceiver due to timeout" -msgstr "завершение приёма журнала из-за таймаута" +msgstr "завершение приёма журнала из-за тайм-аута" -#: replication/walreceiver.c:595 +#: replication/walreceiver.c:614 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "" "на главном Ñервере больше нет журналов Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð¾Ð¹ линии времени %u" -#: replication/walreceiver.c:610 replication/walreceiver.c:969 +#: replication/walreceiver.c:629 replication/walreceiver.c:982 #, c-format msgid "could not close log segment %s: %m" msgstr "не удалоÑÑŒ закрыть Ñегмент журнала %s: %m" -#: replication/walreceiver.c:735 +#: replication/walreceiver.c:754 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "загрузка файла иÑтории Ð´Ð»Ñ Ð»Ð¸Ð½Ð¸Ð¸ времени %u Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñервера" -#: replication/walreceiver.c:1023 +#: replication/walreceiver.c:1036 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "не удалоÑÑŒ запиÑать в Ñегмент журнала %s (Ñмещение %u, длина %lu): %m" -#: replication/walsender.c:482 +#: replication/walsender.c:494 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "не удалоÑÑŒ перейти к началу файла \"%s\": %m" -#: replication/walsender.c:523 +#: replication/walsender.c:535 #, c-format msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" msgstr "Команда IDENTIFY_SYSTEM не выполнÑлаÑÑŒ до START_REPLICATION" -#: replication/walsender.c:540 +#: replication/walsender.c:552 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "" "логичеÑкий Ñлот репликации Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ð´Ð»Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкой репликации" -#: replication/walsender.c:603 +#: replication/walsender.c:615 #, c-format msgid "" "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "" "в иÑтории Ñервера нет запрошенной начальной точки %X/%X на линии времени %u" -#: replication/walsender.c:607 +#: replication/walsender.c:619 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñтого Ñервера ответвилаÑÑŒ от линии времени %u в %X/%X." -#: replication/walsender.c:652 +#: replication/walsender.c:664 #, c-format msgid "" "requested starting point %X/%X is ahead of the WAL flush position of this " @@ -18695,7 +19929,7 @@ msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° %X/%X впереди позиции Ñброшенных данных журнала " "на Ñтом Ñервере (%X/%X)" -#: replication/walsender.c:885 +#: replication/walsender.c:893 #, c-format msgid "" "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a " @@ -18704,7 +19938,7 @@ msgstr "" "Команда CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT не должна вызыватьÑÑ " "внутри транзакции" -#: replication/walsender.c:892 +#: replication/walsender.c:902 #, c-format msgid "" "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" @@ -18712,7 +19946,7 @@ msgstr "" "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT должна вызыватьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ " "транзакции" -#: replication/walsender.c:897 +#: replication/walsender.c:907 #, c-format msgid "" "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ " @@ -18721,7 +19955,7 @@ msgstr "" "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT должна вызыватьÑÑ Ð² " "транзакции ÑƒÑ€Ð¾Ð²Ð½Ñ Ð¸Ð·Ð¾Ð»Ñции REPEATABLE READ" -#: replication/walsender.c:902 +#: replication/walsender.c:912 #, c-format msgid "" "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" @@ -18729,7 +19963,7 @@ msgstr "" "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT должна вызыватьÑÑ Ð¿ÐµÑ€ÐµÐ´ " "любыми другими запроÑами" -#: replication/walsender.c:907 +#: replication/walsender.c:917 #, c-format msgid "" "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a " @@ -18738,19 +19972,26 @@ msgstr "" "Команда CREATE_REPLICATION_SLOT ... USE_SNAPSHOT не должна вызыватьÑÑ Ð² " "подтранзакции" -#: replication/walsender.c:1050 +#: replication/walsender.c:1063 #, c-format msgid "terminating walsender process after promotion" msgstr "завершение процеÑÑа передачи журнала поÑле повышениÑ" -#: replication/walsender.c:1377 +#: replication/walsender.c:1448 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñть новые команды, пока процеÑÑ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ WAL находитÑÑ Ð² режиме " +"оÑтановки" + +#: replication/walsender.c:1481 #, c-format msgid "received replication command: %s" msgstr "получена команда репликации: %s" -#: replication/walsender.c:1416 tcop/fastpath.c:291 tcop/postgres.c:1003 -#: tcop/postgres.c:1313 tcop/postgres.c:1572 tcop/postgres.c:1977 -#: tcop/postgres.c:2345 tcop/postgres.c:2420 +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1033 +#: tcop/postgres.c:1357 tcop/postgres.c:1617 tcop/postgres.c:2023 +#: tcop/postgres.c:2396 tcop/postgres.c:2475 #, c-format msgid "" "current transaction is aborted, commands ignored until end of transaction " @@ -18758,43 +19999,45 @@ msgid "" msgstr "" "Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÑ€Ð²Ð°Ð½Ð°, команды до конца блока транзакции игнорируютÑÑ" -#: replication/walsender.c:1478 +#: replication/walsender.c:1565 #, c-format -msgid "not connected to database" -msgstr "нет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº базе данных" +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "" +"Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñть команды SQL в процеÑÑе, передающем WAL Ð´Ð»Ñ Ñ„Ð¸Ð·Ð¸Ñ‡ÐµÑкой " +"репликации" -#: replication/walsender.c:1518 replication/walsender.c:1534 +#: replication/walsender.c:1613 replication/walsender.c:1629 #, c-format msgid "unexpected EOF on standby connection" msgstr "неожиданный обрыв ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ñ‹Ð¼ Ñервером" -#: replication/walsender.c:1548 +#: replication/walsender.c:1643 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "" "поÑле CopyDone резервный Ñервер передал Ñообщение неожиданного типа \"%c\"" -#: replication/walsender.c:1586 +#: replication/walsender.c:1681 #, c-format msgid "invalid standby message type \"%c\"" msgstr "неверный тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ð¾Ð³Ð¾ Ñервера: \"%c\"" -#: replication/walsender.c:1627 +#: replication/walsender.c:1722 #, c-format msgid "unexpected message type \"%c\"" msgstr "неожиданный тип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ \"%c\"" -#: replication/walsender.c:1997 +#: replication/walsender.c:2100 #, c-format msgid "terminating walsender process due to replication timeout" -msgstr "завершение процеÑÑа передачи журнала из-за таймаута репликации" +msgstr "завершение процеÑÑа передачи журнала из-за тайм-аута репликации" -#: replication/walsender.c:2085 +#: replication/walsender.c:2184 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "резервный Ñервер \"%s\" нагнал главный" +msgid "\"%s\" has now caught up with upstream server" +msgstr "ведомый Ñервер \"%s\" нагнал ведущий" -#: replication/walsender.c:2192 +#: replication/walsender.c:2293 #, c-format msgid "" "number of requested standby connections exceeds max_wal_senders (currently " @@ -18803,7 +20046,7 @@ msgstr "" "чиÑло запрошенных подключений резервных Ñерверов превоÑходит max_wal_senders " "(ÑейчаÑ: %d)" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:967 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "правило \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" уже ÑущеÑтвует" @@ -18869,42 +20112,52 @@ msgstr "\"%s\" уже ÑвлÑетÑÑ Ð¿Ñ€ÐµÐ´Ñтавлением" msgid "view rule for \"%s\" must be named \"%s\"" msgstr "правило предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ \"%s\" должно называтьÑÑ \"%s\"" -#: rewrite/rewriteDefine.c:430 +#: rewrite/rewriteDefine.c:428 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "преобразовать Ñекционированную таблицу \"%s\" в предÑтавление нельзÑ" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "преобразовать Ñекцию \"%s\" в предÑтавление нельзÑ" + +#: rewrite/rewriteDefine.c:442 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как она не " "пуÑта1" -#: rewrite/rewriteDefine.c:438 +#: rewrite/rewriteDefine.c:450 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как она " "Ñодержит триггеры" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:452 #, c-format msgid "" "In particular, the table cannot be involved in any foreign key relationships." msgstr "" "Кроме того, таблица не может быть задейÑтвована в ÑÑылках по внешнему ключу." -#: rewrite/rewriteDefine.c:445 +#: rewrite/rewriteDefine.c:457 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как она имеет " "индекÑÑ‹" -#: rewrite/rewriteDefine.c:451 +#: rewrite/rewriteDefine.c:463 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как она имеет " "подчинённые таблицы" -#: rewrite/rewriteDefine.c:457 +#: rewrite/rewriteDefine.c:469 #, c-format msgid "" "could not convert table \"%s\" to a view because it has row security enabled" @@ -18912,7 +20165,7 @@ msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как Ð´Ð»Ñ Ð½ÐµÑ‘ " "включена защита на уровне Ñтрок" -#: rewrite/rewriteDefine.c:463 +#: rewrite/rewriteDefine.c:475 #, c-format msgid "" "could not convert table \"%s\" to a view because it has row security policies" @@ -18920,45 +20173,45 @@ msgstr "" "не удалоÑÑŒ преобразовать таблицу \"%s\" в предÑтавление, так как к ней " "применены политики защиты Ñтрок" -#: rewrite/rewriteDefine.c:490 +#: rewrite/rewriteDefine.c:502 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "в правиле Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ неÑколько ÑпиÑков RETURNING" -#: rewrite/rewriteDefine.c:495 +#: rewrite/rewriteDefine.c:507 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "ÑпиÑки RETURNING в уÑловных правилах не поддерживаютÑÑ" -#: rewrite/rewriteDefine.c:499 +#: rewrite/rewriteDefine.c:511 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "ÑпиÑки RETURNING поддерживаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в правилах INSTEAD" -#: rewrite/rewriteDefine.c:664 +#: rewrite/rewriteDefine.c:675 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "ÑпиÑок результата правила Ð´Ð»Ñ SELECT Ñодержит Ñлишком много Ñтолбцов" -#: rewrite/rewriteDefine.c:665 +#: rewrite/rewriteDefine.c:676 #, c-format msgid "RETURNING list has too many entries" msgstr "ÑпиÑок RETURNING Ñодержит Ñлишком много Ñтолбцов" -#: rewrite/rewriteDefine.c:692 +#: rewrite/rewriteDefine.c:703 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "" "преобразовать отношение, Ñодержащее удалённые Ñтолбцы, в предÑтавление нельзÑ" -#: rewrite/rewriteDefine.c:693 +#: rewrite/rewriteDefine.c:704 #, c-format msgid "" "cannot create a RETURNING list for a relation containing dropped columns" msgstr "" "Ñоздать ÑпиÑок RETURNING Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ, Ñодержащего удалённые Ñтолбцы, нельзÑ" -#: rewrite/rewriteDefine.c:699 +#: rewrite/rewriteDefine.c:710 #, c-format msgid "" "SELECT rule's target entry %d has different column name from column \"%s\"" @@ -18966,67 +20219,67 @@ msgstr "" "Ñлементу %d результата правила Ð´Ð»Ñ SELECT приÑвоено имÑ, отличное от имени " "Ñтолбца \"%s\"" -#: rewrite/rewriteDefine.c:701 +#: rewrite/rewriteDefine.c:712 #, c-format msgid "SELECT target entry is named \"%s\"." msgstr "Ð˜Ð¼Ñ Ñлемента результата SELECT: \"%s\"." -#: rewrite/rewriteDefine.c:710 +#: rewrite/rewriteDefine.c:721 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "" "Ñлемент %d результата правила Ð´Ð»Ñ SELECT имеет тип, отличный от типа Ñтолбца " "\"%s\"" -#: rewrite/rewriteDefine.c:712 +#: rewrite/rewriteDefine.c:723 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "Ñлемент %d ÑпиÑка RETURNING имеет тип, отличный от типа Ñтолбца \"%s\"" -#: rewrite/rewriteDefine.c:715 rewrite/rewriteDefine.c:739 +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "Элемент результата SELECT имеет тип %s, тогда как тип Ñтолбца - %s." -#: rewrite/rewriteDefine.c:718 rewrite/rewriteDefine.c:743 +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "Элемент ÑпиÑка RETURNING имеет тип %s, тогда как тип Ñтолбца - %s." -#: rewrite/rewriteDefine.c:734 +#: rewrite/rewriteDefine.c:745 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "" -"Ñлемент %d результата правила Ð´Ð»Ñ SELECT имеет размер, отличный от Ñтолбца " -"\"%s\"" +"Ñлемент %d результата правила Ð´Ð»Ñ SELECT имеет размер, отличный от Ñтолбца \"" +"%s\"" -#: rewrite/rewriteDefine.c:736 +#: rewrite/rewriteDefine.c:747 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "Ñлемент %d ÑпиÑка RETURNING имеет размер, отличный от Ñтолбца \"%s\"" -#: rewrite/rewriteDefine.c:753 +#: rewrite/rewriteDefine.c:764 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "ÑпиÑок результата правила Ð´Ð»Ñ SELECT Ñодержит недоÑтаточно Ñлементов" -#: rewrite/rewriteDefine.c:754 +#: rewrite/rewriteDefine.c:765 #, c-format msgid "RETURNING list has too few entries" msgstr "ÑпиÑок RETURNING Ñодержит недоÑтаточно Ñлементов" -#: rewrite/rewriteDefine.c:846 rewrite/rewriteDefine.c:958 +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 #: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "правило \"%s\" Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ\"%s\" не ÑущеÑтвует" -#: rewrite/rewriteDefine.c:977 +#: rewrite/rewriteDefine.c:990 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "переименовывать правило ON SELECT нельзÑ" -#: rewrite/rewriteHandler.c:541 +#: rewrite/rewriteHandler.c:540 #, c-format msgid "" "WITH query name \"%s\" appears in both a rule action and the query being " @@ -19035,92 +20288,108 @@ msgstr "" "Ð¸Ð¼Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа WITH \"%s\" оказалоÑÑŒ и в дейÑтвии правила, и в перепиÑываемом " "запроÑе" -#: rewrite/rewriteHandler.c:601 +#: rewrite/rewriteHandler.c:600 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "RETURNING можно определить только Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ правила" -#: rewrite/rewriteHandler.c:941 rewrite/rewriteHandler.c:959 +#: rewrite/rewriteHandler.c:809 #, c-format -msgid "multiple assignments to same column \"%s\"" -msgstr "многочиÑленные приÑÐ²Ð¾ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ñтолбцу \"%s\"" +msgid "cannot insert into column \"%s\"" +msgstr "вÑтавить данные в Ñтолбец \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:1735 rewrite/rewriteHandler.c:3349 +#: rewrite/rewriteHandler.c:810 rewrite/rewriteHandler.c:825 #, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "обнаружена беÑÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ€ÐµÐºÑƒÑ€ÑÐ¸Ñ Ð² правилах Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "" +"Столбец \"%s\" ÑвлÑетÑÑ Ñтолбцом идентификации Ñо ÑвойÑтвом GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:812 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Ð”Ð»Ñ Ð¿ÐµÑ€ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð¶Ð¸Ñ‚Ðµ OVERRIDING SYSTEM VALUE." + +#: rewrite/rewriteHandler.c:824 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "Ñтолбцу \"%s\" можно приÑвоить только значение DEFAULT" + +#: rewrite/rewriteHandler.c:986 rewrite/rewriteHandler.c:1004 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "многочиÑленные приÑÐ²Ð¾ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð¼Ñƒ Ñтолбцу \"%s\"" -#: rewrite/rewriteHandler.c:1820 +#: rewrite/rewriteHandler.c:2027 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "обнаружена беÑÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ€ÐµÐºÑƒÑ€ÑÐ¸Ñ Ð² политике Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\"" -#: rewrite/rewriteHandler.c:2137 +#: rewrite/rewriteHandler.c:2347 msgid "Junk view columns are not updatable." msgstr "Утилизируемые Ñтолбцы предÑтавлений не обновлÑÑŽÑ‚ÑÑ." -#: rewrite/rewriteHandler.c:2142 +#: rewrite/rewriteHandler.c:2352 msgid "" "View columns that are not columns of their base relation are not updatable." msgstr "" "Столбцы предÑтавлений, не ÑвлÑющиеÑÑ Ñтолбцами базовых отношений, не " "обновлÑÑŽÑ‚ÑÑ." -#: rewrite/rewriteHandler.c:2145 +#: rewrite/rewriteHandler.c:2355 msgid "View columns that refer to system columns are not updatable." msgstr "" "Столбцы предÑтавлений, ÑÑылающиеÑÑ Ð½Ð° ÑиÑтемные Ñтолбцы, не обновлÑÑŽÑ‚ÑÑ." -#: rewrite/rewriteHandler.c:2148 +#: rewrite/rewriteHandler.c:2358 msgid "View columns that return whole-row references are not updatable." msgstr "" "Столбцы предÑтавлений, возвращающие ÑÑылки на вÑÑŽ Ñтроку, не обновлÑÑŽÑ‚ÑÑ." -#: rewrite/rewriteHandler.c:2206 +#: rewrite/rewriteHandler.c:2419 msgid "Views containing DISTINCT are not automatically updatable." msgstr "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ DISTINCT не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2209 +#: rewrite/rewriteHandler.c:2422 msgid "Views containing GROUP BY are not automatically updatable." msgstr "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ GROUP BY не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2212 +#: rewrite/rewriteHandler.c:2425 msgid "Views containing HAVING are not automatically updatable." msgstr "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ HAVING не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2215 +#: rewrite/rewriteHandler.c:2428 msgid "" "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "" "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ UNION, INTERSECT или EXCEPT не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2218 +#: rewrite/rewriteHandler.c:2431 msgid "Views containing WITH are not automatically updatable." msgstr "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ WITH не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2221 +#: rewrite/rewriteHandler.c:2434 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "ПредÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ LIMIT или OFFSET не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2233 +#: rewrite/rewriteHandler.c:2446 msgid "Views that return aggregate functions are not automatically updatable." msgstr "" "ПредÑтавлениÑ, возвращающие агрегатные функции, не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2236 +#: rewrite/rewriteHandler.c:2449 msgid "Views that return window functions are not automatically updatable." msgstr "" "ПредÑтавлениÑ, возвращающие оконные функции, не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2239 +#: rewrite/rewriteHandler.c:2452 msgid "" "Views that return set-returning functions are not automatically updatable." msgstr "" "ПредÑтавлениÑ, возвращающие функции Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼-множеÑтвом, не обновлÑÑŽÑ‚ÑÑ " "автоматичеÑки." -#: rewrite/rewriteHandler.c:2246 rewrite/rewriteHandler.c:2250 -#: rewrite/rewriteHandler.c:2258 +#: rewrite/rewriteHandler.c:2459 rewrite/rewriteHandler.c:2463 +#: rewrite/rewriteHandler.c:2471 msgid "" "Views that do not select from a single table or view are not automatically " "updatable." @@ -19128,27 +20397,27 @@ msgstr "" "ПредÑтавлениÑ, выбирающие данные не из одной таблицы или предÑтавлениÑ, не " "обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2261 +#: rewrite/rewriteHandler.c:2474 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "ПредÑтавлениÑ, Ñодержащие TABLESAMPLE, не обновлÑÑŽÑ‚ÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки." -#: rewrite/rewriteHandler.c:2285 +#: rewrite/rewriteHandler.c:2498 msgid "Views that have no updatable columns are not automatically updatable." msgstr "" "ПредÑтавлениÑ, не Ñодержащие обновлÑемых Ñтолбцов, не обновлÑÑŽÑ‚ÑÑ " "автоматичеÑки." -#: rewrite/rewriteHandler.c:2737 +#: rewrite/rewriteHandler.c:2955 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "вÑтавить данные в Ñтолбец \"%s\" предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:2745 +#: rewrite/rewriteHandler.c:2963 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "изменить данные в Ñтолбце \"%s\" предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:3148 +#: rewrite/rewriteHandler.c:3433 #, c-format msgid "" "DO INSTEAD NOTHING rules are not supported for data-modifying statements in " @@ -19157,7 +20426,7 @@ msgstr "" "правила DO INSTEAD NOTHING не поддерживаютÑÑ Ð² операторах, изменÑющих " "данные, в WITH" -#: rewrite/rewriteHandler.c:3162 +#: rewrite/rewriteHandler.c:3447 #, c-format msgid "" "conditional DO INSTEAD rules are not supported for data-modifying statements " @@ -19166,13 +20435,13 @@ msgstr "" "уÑловные правила DO INSTEAD не поддерживаютÑÑ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð², изменÑющих " "данные, в WITH" -#: rewrite/rewriteHandler.c:3166 +#: rewrite/rewriteHandler.c:3451 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "" "правила DO ALSO не поддерживаютÑÑ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð², изменÑющих данные, в WITH" -#: rewrite/rewriteHandler.c:3171 +#: rewrite/rewriteHandler.c:3456 #, c-format msgid "" "multi-statement DO INSTEAD rules are not supported for data-modifying " @@ -19181,43 +20450,43 @@ msgstr "" "ÑоÑтавные правила DO INSTEAD не поддерживаютÑÑ Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð², изменÑющих " "данные, в WITH" -#: rewrite/rewriteHandler.c:3386 +#: rewrite/rewriteHandler.c:3706 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "выполнить INSERT RETURNING Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:3388 +#: rewrite/rewriteHandler.c:3708 #, c-format msgid "" "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "" "Ðеобходимо безуÑловное правило ON INSERT DO INSTEAD Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ RETURNING." -#: rewrite/rewriteHandler.c:3393 +#: rewrite/rewriteHandler.c:3713 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "выполнить UPDATE RETURNING Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:3395 +#: rewrite/rewriteHandler.c:3715 #, c-format msgid "" "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "" "Ðеобходимо безуÑловное правило ON UPDATE DO INSTEAD Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ RETURNING." -#: rewrite/rewriteHandler.c:3400 +#: rewrite/rewriteHandler.c:3720 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "выполнить DELETE RETURNING Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s\" нельзÑ" -#: rewrite/rewriteHandler.c:3402 +#: rewrite/rewriteHandler.c:3722 #, c-format msgid "" "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "" "Ðеобходимо безуÑловное правило ON DELETE DO INSTEAD Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ RETURNING." -#: rewrite/rewriteHandler.c:3420 +#: rewrite/rewriteHandler.c:3740 #, c-format msgid "" "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or " @@ -19226,7 +20495,7 @@ msgstr "" "INSERT c предложением ON CONFLICT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹, Ð´Ð»Ñ " "которой заданы правила INSERT или UPDATE" -#: rewrite/rewriteHandler.c:3477 +#: rewrite/rewriteHandler.c:3797 #, c-format msgid "" "WITH cannot be used in a query that is rewritten by rules into multiple " @@ -19245,7 +20514,7 @@ msgstr "уÑловные Ñлужебные операторы не реализ msgid "WHERE CURRENT OF on a view is not implemented" msgstr "уÑловие WHERE CURRENT OF Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ñтавлений не реализовано" -#: rewrite/rewriteManip.c:1434 +#: rewrite/rewriteManip.c:1503 #, c-format msgid "" "NEW variables in ON UPDATE rules cannot reference columns that are part of a " @@ -19280,48 +20549,48 @@ msgstr "нераÑпознанный параметр Snowball: \"%s\"" msgid "missing Language parameter" msgstr "отÑутÑтвует параметр Language" -#: statistics/extended_stats.c:228 +#: statistics/dependencies.c:534 #, c-format -msgid "" -"extended statistics could not be collected for column \"%s\" of relation %s." -"%s" -msgstr "" -"Ð´Ð»Ñ Ñтолбца \"%s\" Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s.%s Ð½ÐµÐ»ÑŒÐ·Ñ Ñобрать раÑширенную ÑтатиÑтику" +msgid "invalid zero-length item array in MVDependencies" +msgstr "недопуÑтимый маÑÑив нулевой длины в MVDependencies" + +#: statistics/dependencies.c:672 statistics/dependencies.c:725 +#: statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 +#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 +#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 +#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 +#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 +#: utils/adt/pseudotypes.c:393 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "значение типа %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ð²ÐµÑти" -#: statistics/extended_stats.c:232 +#: statistics/extended_stats.c:104 #, c-format -msgid "Consider ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" -msgstr "Попробуйте ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" +msgid "" +"statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "" +"объект ÑтатиÑтики \"%s.%s\" не может быть вычиÑлен Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\"" -#: statistics/mvdistinct.c:258 +#: statistics/mvdistinct.c:262 #, c-format msgid "invalid ndistinct magic %08x (expected %08x)" msgstr "неверное магичеÑкое чиÑло ndistinct: %08x (ожидалоÑÑŒ: %08x)" -#: statistics/mvdistinct.c:263 +#: statistics/mvdistinct.c:267 #, c-format msgid "invalid ndistinct type %d (expected %d)" msgstr "неверный тип ndistinct: %d (ожидалÑÑ: %d)" -#: statistics/mvdistinct.c:268 +#: statistics/mvdistinct.c:272 #, c-format msgid "invalid zero-length item array in MVNDistinct" msgstr "недопуÑтимый маÑÑив нулевой длины в MVNDistinct" -#: statistics/mvdistinct.c:277 -#, c-format -msgid "invalid MVNDistinct size %ld (expected at least %ld)" -msgstr "неправильный размер MVNDistinct: %ld (ожидалÑÑ Ð½Ðµ меньше %ld)" - -#: statistics/mvdistinct.c:337 statistics/mvdistinct.c:385 -#: utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 -#: utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 -#: utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 -#: utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 -#: utils/adt/pseudotypes.c:393 +#: statistics/mvdistinct.c:281 #, c-format -msgid "cannot accept a value of type %s" -msgstr "значение типа %s Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ð²ÐµÑти" +msgid "invalid MVNDistinct size %zd (expected at least %zd)" +msgstr "неправильный размер MVNDistinct: %zd (ожидалÑÑ Ð½Ðµ меньше %zd)" #: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 #, c-format @@ -19362,7 +20631,7 @@ msgstr "МножеÑтвенные Ñбои - возможно, поÑтоÑнн msgid "writing block %u of relation %s" msgstr "запиÑÑŒ блока %u Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %s" -#: storage/buffer/bufmgr.c:4356 +#: storage/buffer/bufmgr.c:4358 #, c-format msgid "snapshot too old" msgstr "Ñнимок Ñлишком Ñтар" @@ -19377,184 +20646,233 @@ msgstr "нет пуÑтого локального буфера" msgid "cannot access temporary tables during a parallel operation" msgstr "обращатьÑÑ Ðº временным таблицам во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: storage/file/fd.c:443 storage/file/fd.c:515 storage/file/fd.c:551 +#: storage/file/buffile.c:317 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "" +"не удалоÑÑŒ открыть временный файл \"%s\", входÑщий в BufFile \"%s\": %m" + +#: storage/file/buffile.c:814 +#, c-format +msgid "" +"could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "" +"не удалоÑÑŒ определить размер временного файла \"%s\", входÑщего в BufFile \"" +"%s\": %m" + +#: storage/file/fd.c:470 storage/file/fd.c:542 storage/file/fd.c:578 #, c-format msgid "could not flush dirty data: %m" msgstr "не удалоÑÑŒ ÑброÑить грÑзные данные: %m" -#: storage/file/fd.c:473 +#: storage/file/fd.c:500 #, c-format msgid "could not determine dirty data size: %m" msgstr "не удалоÑÑŒ определить размер грÑзных данных: %m" -#: storage/file/fd.c:525 +#: storage/file/fd.c:552 #, c-format msgid "could not munmap() while flushing data: %m" msgstr "ошибка в munmap() при ÑброÑе данных на диÑк: %m" -#: storage/file/fd.c:726 +#: storage/file/fd.c:753 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\" не удалоÑÑŒ Ñоздать ÑÑылку \"%s\": %m" -#: storage/file/fd.c:820 +#: storage/file/fd.c:847 #, c-format msgid "getrlimit failed: %m" msgstr "ошибка в getrlimit(): %m" -#: storage/file/fd.c:910 +#: storage/file/fd.c:937 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "недоÑтаточно деÑкрипторов файлов Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка Ñерверного процеÑÑа" -#: storage/file/fd.c:911 +#: storage/file/fd.c:938 #, c-format msgid "System allows %d, we need at least %d." msgstr "СиÑтема выделÑет: %d, а требуетÑÑ Ð¼Ð¸Ð½Ð¸Ð¼ÑƒÐ¼: %d." -#: storage/file/fd.c:952 storage/file/fd.c:2129 storage/file/fd.c:2222 -#: storage/file/fd.c:2370 +#: storage/file/fd.c:989 storage/file/fd.c:2398 storage/file/fd.c:2508 +#: storage/file/fd.c:2659 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "нехватка деÑкрипторов файлов: %m; оÑвободите их и повторите попытку" -#: storage/file/fd.c:1557 +#: storage/file/fd.c:1332 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "временный файл: путь \"%s\", размер %lu" -#: storage/file/fd.c:1760 +#: storage/file/fd.c:1464 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "не удалоÑÑŒ Ñоздать временный каталог \"%s\": %m" + +#: storage/file/fd.c:1471 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "не удалоÑÑŒ Ñоздать временный подкаталог \"%s\": %m" + +#: storage/file/fd.c:1664 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "не удалоÑÑŒ Ñоздать временный файл \"%s\": %m" + +#: storage/file/fd.c:1699 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "не удалоÑÑŒ открыть временный файл \"%s\": %m" + +#: storage/file/fd.c:1740 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð³Ð¾ файла \"%s\": %m" + +#: storage/file/fd.c:2029 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "размер временного файла превышает предел temp_file_limit (%d КБ)" -#: storage/file/fd.c:2105 storage/file/fd.c:2155 +#: storage/file/fd.c:2374 storage/file/fd.c:2433 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "превышен предел maxAllocatedDescs (%d) при попытке открыть файл \"%s\"" -#: storage/file/fd.c:2195 +#: storage/file/fd.c:2478 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "" "превышен предел maxAllocatedDescs (%d) при попытке выполнить команду \"%s\"" -#: storage/file/fd.c:2346 +#: storage/file/fd.c:2635 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "" "превышен предел maxAllocatedDescs (%d) при попытке открыть каталог \"%s\"" -#: storage/file/fd.c:2432 utils/adt/genfile.c:511 +#: storage/file/fd.c:2726 #, c-format msgid "could not read directory \"%s\": %m" msgstr "не удалоÑÑŒ прочитать каталог \"%s\": %m" -#: storage/ipc/dsm.c:364 +#: storage/file/fd.c:3158 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "в каталоге временных файлов обнаружен неумеÑтный файл: \"%s\"" + +#: storage/file/fd.c:3480 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "ошибка ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° \"%s\": %m" + +#: storage/file/sharedfileset.c:93 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "не удалоÑÑŒ подключитьÑÑ Ðº уже уничтоженному набору SharedFileSet" + +#: storage/ipc/dsm.c:351 #, c-format msgid "dynamic shared memory control segment is corrupt" msgstr "Ñегмент ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкой разделÑемой памÑтью иÑпорчен" -#: storage/ipc/dsm.c:411 +#: storage/ipc/dsm.c:398 #, c-format msgid "dynamic shared memory is disabled" msgstr "динамичеÑÐºÐ°Ñ Ñ€Ð°Ð·Ð´ÐµÐ»ÑÐµÐ¼Ð°Ñ Ð¿Ð°Ð¼Ñть отключена" -#: storage/ipc/dsm.c:412 +#: storage/ipc/dsm.c:399 #, c-format msgid "Set dynamic_shared_memory_type to a value other than \"none\"." msgstr "" "УÑтановите Ð´Ð»Ñ dynamic_shared_memory_type значение, отличное от \"none\"." -#: storage/ipc/dsm.c:432 +#: storage/ipc/dsm.c:419 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "Ñегмент ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкой разделÑемой памÑтью не в порÑдке" -#: storage/ipc/dsm.c:528 +#: storage/ipc/dsm.c:515 #, c-format msgid "too many dynamic shared memory segments" msgstr "Ñлишком много Ñегментов динамичеÑкой разделÑемой памÑти" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 -#: storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 -#: storage/ipc/dsm_impl.c:819 storage/ipc/dsm_impl.c:963 +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 +#: storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 +#: storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "не удалоÑÑŒ оÑвободить Ñегмент разделÑемой памÑти %s: %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 -#: storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:829 +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 +#: storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "ошибка при удалении Ñегмента разделÑемой памÑти \"%s\": %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:729 -#: storage/ipc/dsm_impl.c:843 +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 +#: storage/ipc/dsm_impl.c:904 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "не удалоÑÑŒ открыть Ñегмент разделÑемой памÑти \"%s\": %m" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 -#: storage/ipc/dsm_impl.c:774 storage/ipc/dsm_impl.c:867 +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 +#: storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "не удалоÑÑŒ обратитьÑÑ Ðº Ñегменту разделÑемой памÑти \"%s\": %m" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:886 -#: storage/ipc/dsm_impl.c:936 +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 +#: storage/ipc/dsm_impl.c:997 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "" "не удалоÑÑŒ изменить размер Ñегмента разделÑемой памÑти \"%s\" до %zu байт: %m" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 -#: storage/ipc/dsm_impl.c:750 storage/ipc/dsm_impl.c:987 +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 +#: storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "не удалоÑÑŒ отобразить Ñегмент разделÑемой памÑти \"%s\": %m" -#: storage/ipc/dsm_impl.c:515 +#: storage/ipc/dsm_impl.c:576 #, c-format msgid "could not get shared memory segment: %m" msgstr "не удалоÑÑŒ получить Ñегмент разделÑемой памÑти: %m" -#: storage/ipc/dsm_impl.c:714 +#: storage/ipc/dsm_impl.c:775 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать Ñегмент разделÑемой памÑти \"%s\": %m" -#: storage/ipc/dsm_impl.c:1029 storage/ipc/dsm_impl.c:1077 +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 #, c-format msgid "could not duplicate handle for \"%s\": %m" msgstr "не удалоÑÑŒ продублировать указатель Ð´Ð»Ñ \"%s\": %m" -#: storage/ipc/latch.c:780 +#: storage/ipc/latch.c:829 #, c-format msgid "epoll_ctl() failed: %m" msgstr "ошибка в epoll_ctl(): %m" -#: storage/ipc/latch.c:1009 +#: storage/ipc/latch.c:1060 #, c-format msgid "epoll_wait() failed: %m" msgstr "ошибка в epoll_wait(): %m" -#: storage/ipc/latch.c:1129 +#: storage/ipc/latch.c:1182 #, c-format msgid "poll() failed: %m" msgstr "ошибка в poll(): %m" -#: storage/ipc/latch.c:1287 -#, c-format -msgid "select() failed: %m" -msgstr "ошибка в select(): %m" - -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:189 storage/lmgr/lock.c:883 -#: storage/lmgr/lock.c:917 storage/lmgr/lock.c:2679 storage/lmgr/lock.c:4004 -#: storage/lmgr/lock.c:4069 storage/lmgr/lock.c:4361 -#: storage/lmgr/predicate.c:2318 storage/lmgr/predicate.c:2333 -#: storage/lmgr/predicate.c:3725 storage/lmgr/predicate.c:4868 -#: utils/hash/dynahash.c:1043 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 +#: storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 +#: storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 +#: storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 +#: storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "нехватка разделÑемой памÑти" @@ -19575,8 +20893,8 @@ msgid "" "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, " "actual %zu" msgstr "" -"размер запиÑи ShmemIndex не ÑоответÑтвует Ñтруктуре данных \"%s" -"\" (ожидалоÑÑŒ: %zu, фактичеÑки: %zu)" +"размер запиÑи ShmemIndex не ÑоответÑтвует Ñтруктуре данных \"%s\" " +"(ожидалоÑÑŒ: %zu, фактичеÑки: %zu)" #: storage/ipc/shmem.c:453 #, c-format @@ -19591,36 +20909,36 @@ msgstr "" msgid "requested shared memory size overflows size_t" msgstr "запрошенный размер разделÑемой памÑти не умещаетÑÑ Ð² size_t" -#: storage/ipc/standby.c:531 tcop/postgres.c:2970 +#: storage/ipc/standby.c:558 tcop/postgres.c:3056 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "" "выполнение оператора отменено из-за конфликта Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑом воÑÑтановлениÑ" -#: storage/ipc/standby.c:532 tcop/postgres.c:2277 +#: storage/ipc/standby.c:559 tcop/postgres.c:2329 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "" "Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ»Ð° к взаимоблокировке Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑом " "воÑÑтановлениÑ." -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:190 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "" "в запиÑи pg_largeobject Ð´Ð»Ñ OID %u, Ñтр. %d неверный размер Ð¿Ð¾Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… (%d)" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:271 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "неверные флаги Ð´Ð»Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð³Ð¾ объекта: %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:461 #, c-format msgid "invalid whence setting: %d" msgstr "неверное значение ориентира: %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:633 #, c-format msgid "invalid large object write request size: %d" msgstr "неверный размер запиÑи большого объекта: %d" @@ -19646,103 +20964,103 @@ msgstr "обнаружена взаимоблокировка" msgid "See server log for query details." msgstr "ПодробноÑти запроÑа Ñмотрите в протоколе Ñервера." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:767 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "при изменении кортежа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:770 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "при удалении кортежа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:773 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "при блокировке кортежа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:776 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "при блокировке изменённой верÑии (%u,%u) кортежа в отношении \"%s\"" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:779 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "при добавлении кортежа индекÑа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:782 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "при проверке уникальноÑти кортежа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:785 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "при перепроверке изменённого кортежа (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:788 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" msgstr "" "при проверке ограничениÑ-иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ¾Ñ€Ñ‚ÐµÐ¶Ð° (%u,%u) в отношении \"%s\"" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1008 #, c-format msgid "relation %u of database %u" msgstr "отношение %u базы данных %u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1014 #, c-format msgid "extension of relation %u of database %u" msgstr "раÑширение Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %u базы данных %u" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1020 #, c-format msgid "page %u of relation %u of database %u" msgstr "Ñтраница %u Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %u базы данных %u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1027 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "кортеж (%u,%u) Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ %u базы данных %u" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1035 #, c-format msgid "transaction %u" msgstr "Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %u" -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1040 #, c-format msgid "virtual transaction %d/%u" msgstr "Ð²Ð¸Ñ€Ñ‚ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1046 #, c-format msgid "speculative token %u of transaction %u" msgstr "ÑпекулÑтивный маркер %u транзакции %u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1052 #, c-format msgid "object %u of class %u of database %u" msgstr "объект %u клаÑÑа %u базы данных %u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1060 #, c-format msgid "user lock [%u,%u,%u]" msgstr "пользовательÑÐºÐ°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ° [%u,%u,%u]" -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1067 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "Ñ€ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ° [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1075 #, c-format msgid "unrecognized locktag type %d" msgstr "нераÑпознанный тип блокировки %d" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:740 #, c-format msgid "" "cannot acquire lock mode %s on database objects while recovery is in progress" @@ -19750,7 +21068,7 @@ msgstr "" "пока выполнÑетÑÑ Ð²Ð¾ÑÑтановление, Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ блокировку объектов базы " "данных в режиме %s" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:742 #, c-format msgid "" "Only RowExclusiveLock or less can be acquired on database objects during " @@ -19759,13 +21077,13 @@ msgstr "" "Ð’ процеÑÑе воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð² базы данных может быть получена " "только блокировка RowExclusiveLock или менее ÑильнаÑ." -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2680 -#: storage/lmgr/lock.c:4005 storage/lmgr/lock.c:4070 storage/lmgr/lock.c:4362 +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 +#: storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "Возможно, Ñледует увеличить параметр max_locks_per_transaction." -#: storage/lmgr/lock.c:3121 storage/lmgr/lock.c:3237 +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 #, c-format msgid "" "cannot PREPARE while holding both session-level and transaction-level locks " @@ -19774,12 +21092,12 @@ msgstr "" "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE, ÑƒÐ´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸ на уровне ÑеанÑа и на уровне " "транзакции Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ объекта" -#: storage/lmgr/predicate.c:676 +#: storage/lmgr/predicate.c:682 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "в пуле недоÑтаточно Ñлементов Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи о конфликте чтениÑ/запиÑи" -#: storage/lmgr/predicate.c:677 storage/lmgr/predicate.c:705 +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 #, c-format msgid "" "You might need to run fewer transactions at a time or increase " @@ -19788,7 +21106,7 @@ msgstr "" "Попробуйте уменьшить чиÑло транзакций в Ñекунду или увеличить параметр " "max_connections." -#: storage/lmgr/predicate.c:704 +#: storage/lmgr/predicate.c:710 #, c-format msgid "" "not enough elements in RWConflictPool to record a potential read/write " @@ -19797,32 +21115,18 @@ msgstr "" "в пуле недоÑтаточно Ñлементов Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи о потенциальном конфликте чтениÑ/" "запиÑи" -#: storage/lmgr/predicate.c:910 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "памÑть Ð´Ð»Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð»Ð¸ÐºÑ‚Ð¾Ð² Ñериализации практичеÑки иÑчерпана" - -#: storage/lmgr/predicate.c:911 -#, c-format -msgid "" -"There might be an idle transaction or a forgotten prepared transaction " -"causing this." -msgstr "" -"ВероÑтно, Ñта ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ Ð²Ñ‹Ð·Ð²Ð°Ð½Ð° забытой подготовленной транзакцией или " -"транзакцией, проÑтаивающей долгое времÑ." - -#: storage/lmgr/predicate.c:1538 +#: storage/lmgr/predicate.c:1515 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "откладываемый Ñнимок был небезопаÑен; пробуем более новый" -#: storage/lmgr/predicate.c:1577 +#: storage/lmgr/predicate.c:1604 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "" "Параметр \"default_transaction_isolation\" имеет значение \"serializable\"." -#: storage/lmgr/predicate.c:1578 +#: storage/lmgr/predicate.c:1605 #, c-format msgid "" "You can use \"SET default_transaction_isolation = 'repeatable read'\" to " @@ -19831,34 +21135,34 @@ msgstr "" "Чтобы изменить режим по умолчанию, выполните \"SET " "default_transaction_isolation = 'repeatable read'\"." -#: storage/lmgr/predicate.c:1617 +#: storage/lmgr/predicate.c:1645 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "транзакциÑ, Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñнимок, не должна быть READ ONLY DEFERRABLE" -#: storage/lmgr/predicate.c:1695 utils/time/snapmgr.c:617 -#: utils/time/snapmgr.c:623 +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 +#: utils/time/snapmgr.c:627 #, c-format msgid "could not import the requested snapshot" msgstr "не удалоÑÑŒ импортировать запрошенный Ñнимок" -#: storage/lmgr/predicate.c:1696 utils/time/snapmgr.c:624 +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %u уже не выполнÑетÑÑ." +msgid "The source process with PID %d is not running anymore." +msgstr "ИÑходный процеÑÑ Ñ PID %d уже не работает." -#: storage/lmgr/predicate.c:2319 storage/lmgr/predicate.c:2334 -#: storage/lmgr/predicate.c:3726 +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 +#: storage/lmgr/predicate.c:3763 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "" "Возможно, Ñледует увеличить значение параметра max_locks_per_transaction." -#: storage/lmgr/predicate.c:3880 storage/lmgr/predicate.c:3969 -#: storage/lmgr/predicate.c:3977 storage/lmgr/predicate.c:4016 -#: storage/lmgr/predicate.c:4255 storage/lmgr/predicate.c:4592 -#: storage/lmgr/predicate.c:4604 storage/lmgr/predicate.c:4646 -#: storage/lmgr/predicate.c:4684 +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 +#: storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 +#: storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 +#: storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 +#: storage/lmgr/predicate.c:4721 #, c-format msgid "" "could not serialize access due to read/write dependencies among transactions" @@ -19866,31 +21170,31 @@ msgstr "" "не удалоÑÑŒ Ñериализовать доÑтуп из-за завиÑимоÑтей чтениÑ/запиÑи между " "транзакциÑми" -#: storage/lmgr/predicate.c:3882 storage/lmgr/predicate.c:3971 -#: storage/lmgr/predicate.c:3979 storage/lmgr/predicate.c:4018 -#: storage/lmgr/predicate.c:4257 storage/lmgr/predicate.c:4594 -#: storage/lmgr/predicate.c:4606 storage/lmgr/predicate.c:4648 -#: storage/lmgr/predicate.c:4686 +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 +#: storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 +#: storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 +#: storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 +#: storage/lmgr/predicate.c:4723 #, c-format msgid "The transaction might succeed if retried." msgstr "Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ завершитьÑÑ ÑƒÑпешно при Ñледующей попытке." -#: storage/lmgr/proc.c:1300 +#: storage/lmgr/proc.c:1318 #, c-format msgid "Process %d waits for %s on %s." msgstr "ПроцеÑÑ %d ожидает в режиме %s блокировку %s." -#: storage/lmgr/proc.c:1311 +#: storage/lmgr/proc.c:1329 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "ÑнÑтие блокирующего процеÑÑа автоочиÑтки (PID %d)" -#: storage/lmgr/proc.c:1329 utils/adt/misc.c:269 +#: storage/lmgr/proc.c:1347 utils/adt/misc.c:270 #, c-format msgid "could not send signal to process %d: %m" msgstr "отправить Ñигнал процеÑÑу %d не удалоÑÑŒ: %m" -#: storage/lmgr/proc.c:1431 +#: storage/lmgr/proc.c:1449 #, c-format msgid "" "process %d avoided deadlock for %s on %s by rearranging queue order after " @@ -19899,7 +21203,7 @@ msgstr "" "процеÑÑ %d избежал взаимоблокировки, Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð² режиме %s блокировку \"%s\", " "изменив порÑдок очереди через %ld.%03d мÑ" -#: storage/lmgr/proc.c:1446 +#: storage/lmgr/proc.c:1464 #, c-format msgid "" "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" @@ -19907,19 +21211,19 @@ msgstr "" "процеÑÑ %d обнаружил взаимоблокировку, Ð¾Ð¶Ð¸Ð´Ð°Ñ Ð² режиме %s блокировку \"%s\" " "в течение %ld.%03d мÑ" -#: storage/lmgr/proc.c:1455 +#: storage/lmgr/proc.c:1473 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "" "процеÑÑ %d продолжает ожидать в режиме %s блокировку \"%s\" в течение %ld." "%03d мÑ" -#: storage/lmgr/proc.c:1462 +#: storage/lmgr/proc.c:1480 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "процеÑÑ %d получил в режиме %s блокировку \"%s\" через %ld.%03d мÑ" -#: storage/lmgr/proc.c:1478 +#: storage/lmgr/proc.c:1496 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "" @@ -19931,30 +21235,35 @@ msgid "page verification failed, calculated checksum %u but expected %u" msgstr "" "ошибка проверки Ñтраницы: получена ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма %u, а ожидалаÑÑŒ - %u" -#: storage/page/bufpage.c:213 storage/page/bufpage.c:505 -#: storage/page/bufpage.c:748 storage/page/bufpage.c:881 -#: storage/page/bufpage.c:977 storage/page/bufpage.c:1087 +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 +#: storage/page/bufpage.c:744 storage/page/bufpage.c:877 +#: storage/page/bufpage.c:973 storage/page/bufpage.c:1083 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "" "иÑпорченные указатели Ñтраницы: нижний = %u, верхний = %u, ÑпецоблаÑть = %u" -#: storage/page/bufpage.c:549 +#: storage/page/bufpage.c:529 #, c-format msgid "corrupted item pointer: %u" msgstr "иÑпорченный указатель Ñлемента: %u" -#: storage/page/bufpage.c:560 storage/page/bufpage.c:932 +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "иÑпорченный размер Ñлемента (общий размер: %u, доÑтупно: %u)" -#: storage/page/bufpage.c:767 storage/page/bufpage.c:905 -#: storage/page/bufpage.c:993 storage/page/bufpage.c:1103 +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 +#: storage/page/bufpage.c:1099 #, c-format msgid "corrupted item pointer: offset = %u, size = %u" msgstr "иÑпорченный указатель Ñлемента: Ñмещение = %u, размер = %u" +#: storage/page/bufpage.c:901 +#, c-format +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "иÑпорченный указатель Ñлемента: Ñмещение = %u, длина = %u" + #: storage/smgr/md.c:448 storage/smgr/md.c:974 #, c-format msgid "could not truncate file \"%s\": %m" @@ -20017,19 +21326,19 @@ msgstr "" msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "не удалоÑÑŒ обрезать файл \"%s\" до нужного чиÑла блоков (%u): %m" -#: storage/smgr/md.c:1282 +#: storage/smgr/md.c:1295 #, c-format msgid "could not fsync file \"%s\" but retrying: %m" msgstr "" "не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл \"%s\", поÑледует Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ°: %m" -#: storage/smgr/md.c:1445 +#: storage/smgr/md.c:1458 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "" "не удалоÑÑŒ отправить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ñинхронизации Ñ Ð¤Ð¡ (очередь запроÑов переполнена)" -#: storage/smgr/md.c:1914 +#: storage/smgr/md.c:1958 #, c-format msgid "" "could not open file \"%s\" (target block %u): previous segment is only %u " @@ -20038,105 +21347,105 @@ msgstr "" "не удалоÑÑŒ открыть файл file \"%s\" (целевой блок %u): недоÑтаточно блоков в " "предыдущем Ñегменте (вÑего %u)" -#: storage/smgr/md.c:1928 +#: storage/smgr/md.c:1972 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "не удалоÑÑŒ открыть файл file \"%s\" (целевой блок %u): %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:475 tcop/fastpath.c:605 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format msgid "invalid argument size %d in function call message" msgstr "неверный размер аргумента (%d) в Ñообщении вызова функции" -#: tcop/fastpath.c:319 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "вызов функции fastpath: \"%s\" (OID %u)" -#: tcop/fastpath.c:401 tcop/postgres.c:1175 tcop/postgres.c:1438 -#: tcop/postgres.c:1818 tcop/postgres.c:2036 +#: tcop/fastpath.c:389 tcop/postgres.c:1218 tcop/postgres.c:1482 +#: tcop/postgres.c:1864 tcop/postgres.c:2085 #, c-format msgid "duration: %s ms" msgstr "продолжительноÑть: %s мÑ" -#: tcop/fastpath.c:405 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "продолжительноÑть %s мÑ, вызов функции fastpath: \"%s\" (OID %u)" -#: tcop/fastpath.c:443 tcop/fastpath.c:570 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "" "Ñообщение вызова функции Ñодержит неверное чиÑло аргументов (%d, а требуетÑÑ " "%d)" -#: tcop/fastpath.c:451 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "" "Ñообщение вызова функции Ñодержит неверное чиÑло форматов (%d, а аргументов " "%d)" -#: tcop/fastpath.c:538 tcop/fastpath.c:621 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "неправильный формат двоичных данных в аргументе функции %d" -#: tcop/postgres.c:352 tcop/postgres.c:388 tcop/postgres.c:415 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "неожиданный обрыв ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð¾Ð¼" -#: tcop/postgres.c:438 tcop/postgres.c:450 tcop/postgres.c:461 -#: tcop/postgres.c:473 tcop/postgres.c:4313 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4408 #, c-format msgid "invalid frontend message type %d" msgstr "неправильный тип клиентÑкого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ %d" -#: tcop/postgres.c:944 +#: tcop/postgres.c:973 #, c-format msgid "statement: %s" msgstr "оператор: %s" -#: tcop/postgres.c:1180 +#: tcop/postgres.c:1223 #, c-format msgid "duration: %s ms statement: %s" msgstr "продолжительноÑть: %s мÑ, оператор: %s" -#: tcop/postgres.c:1230 +#: tcop/postgres.c:1273 #, c-format msgid "parse %s: %s" msgstr "разбор %s: %s" -#: tcop/postgres.c:1286 +#: tcop/postgres.c:1330 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "в подготовленный оператор Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñтавить неÑколько команд" -#: tcop/postgres.c:1443 +#: tcop/postgres.c:1487 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "продолжительноÑть: %s мÑ, разбор %s: %s" -#: tcop/postgres.c:1488 +#: tcop/postgres.c:1532 #, c-format msgid "bind %s to %s" msgstr "привÑзка %s к %s" # [SM]: TO REVIEW -#: tcop/postgres.c:1507 tcop/postgres.c:2326 +#: tcop/postgres.c:1551 tcop/postgres.c:2377 #, c-format msgid "unnamed prepared statement does not exist" msgstr "безымÑнный подготовленный оператор не ÑущеÑтвует" -#: tcop/postgres.c:1549 +#: tcop/postgres.c:1594 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "" "неверное чиÑло форматов параметров в Ñообщении Bind (%d, а параметров %d)" -#: tcop/postgres.c:1555 +#: tcop/postgres.c:1600 #, c-format msgid "" "bind message supplies %d parameters, but prepared statement \"%s\" requires " @@ -20145,88 +21454,88 @@ msgstr "" "в Ñообщении Bind передано неверное чиÑло параметров (%d, а подготовленный " "оператор \"%s\" требует %d)" -#: tcop/postgres.c:1725 +#: tcop/postgres.c:1771 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "неверный формат двоичных данных в параметре Bind %d" -#: tcop/postgres.c:1823 +#: tcop/postgres.c:1869 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "продолжительноÑть: %s мÑ, Ñообщение Bind %s%s%s: %s" -#: tcop/postgres.c:1871 tcop/postgres.c:2406 +#: tcop/postgres.c:1917 tcop/postgres.c:2461 #, c-format msgid "portal \"%s\" does not exist" msgstr "портал \"%s\" не ÑущеÑтвует" -#: tcop/postgres.c:1956 +#: tcop/postgres.c:2002 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1958 tcop/postgres.c:2044 +#: tcop/postgres.c:2004 tcop/postgres.c:2093 msgid "execute fetch from" msgstr "выборка из" -#: tcop/postgres.c:1959 tcop/postgres.c:2045 +#: tcop/postgres.c:2005 tcop/postgres.c:2094 msgid "execute" msgstr "выполнение" -#: tcop/postgres.c:2041 +#: tcop/postgres.c:2090 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "продолжительноÑть: %s Ð¼Ñ %s %s%s%s: %s" -#: tcop/postgres.c:2167 +#: tcop/postgres.c:2216 #, c-format msgid "prepare: %s" msgstr "подготовка: %s" -#: tcop/postgres.c:2230 +#: tcop/postgres.c:2282 #, c-format msgid "parameters: %s" msgstr "параметры: %s" -#: tcop/postgres.c:2249 +#: tcop/postgres.c:2301 #, c-format msgid "abort reason: recovery conflict" msgstr "причина прерываниÑ: конфликт при воÑÑтановлении" -#: tcop/postgres.c:2265 +#: tcop/postgres.c:2317 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "Пользователь удерживал фикÑатор разделÑемого буфера Ñлишком долго." -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2320 #, c-format msgid "User was holding a relation lock for too long." msgstr "Пользователь удерживал блокировку таблицы Ñлишком долго." -#: tcop/postgres.c:2271 +#: tcop/postgres.c:2323 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "" "Пользователь иÑпользовал табличное проÑтранÑтво, которое должно быть удалено." -#: tcop/postgres.c:2274 +#: tcop/postgres.c:2326 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "" "ЗапроÑу Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½ÑƒÐ¶Ð½Ð¾ было видеть верÑии Ñтрок, которые должны быть " "удалены." -#: tcop/postgres.c:2280 +#: tcop/postgres.c:2332 #, c-format msgid "User was connected to a database that must be dropped." msgstr "Пользователь был подключён к базе данных, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть удалена." -#: tcop/postgres.c:2589 +#: tcop/postgres.c:2657 #, c-format msgid "terminating connection because of crash of another server process" msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за краха другого Ñерверного процеÑÑа" -#: tcop/postgres.c:2590 +#: tcop/postgres.c:2658 #, c-format msgid "" "The postmaster has commanded this server process to roll back the current " @@ -20237,7 +21546,7 @@ msgstr "" "транзакцию и завершитьÑÑ, так как другой Ñерверный процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ " "аварийно и возможно разрушил разделÑемую памÑть." -#: tcop/postgres.c:2594 tcop/postgres.c:2898 +#: tcop/postgres.c:2662 tcop/postgres.c:2986 #, c-format msgid "" "In a moment you should be able to reconnect to the database and repeat your " @@ -20246,12 +21555,12 @@ msgstr "" "Ð’Ñ‹ Ñможете переподключитьÑÑ Ðº базе данных и повторить вашу команду Ñию " "минуту." -#: tcop/postgres.c:2680 +#: tcop/postgres.c:2744 #, c-format msgid "floating-point exception" msgstr "иÑключение в операции Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой" -#: tcop/postgres.c:2681 +#: tcop/postgres.c:2745 #, c-format msgid "" "An invalid floating-point operation was signaled. This probably means an out-" @@ -20261,62 +21570,72 @@ msgstr "" "оказалÑÑ Ð²Ð½Ðµ допуÑтимых рамок или произошла ошибка вычиÑлениÑ, например, " "деление на ноль." -#: tcop/postgres.c:2843 +#: tcop/postgres.c:2916 #, c-format msgid "canceling authentication due to timeout" -msgstr "отмена проверки подлинноÑти из-за таймаута" +msgstr "отмена проверки подлинноÑти из-за тайм-аута" -#: tcop/postgres.c:2847 +#: tcop/postgres.c:2920 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "прекращение процеÑÑа автоочиÑтки по команде админиÑтратора" -#: tcop/postgres.c:2853 tcop/postgres.c:2863 tcop/postgres.c:2896 +#: tcop/postgres.c:2924 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "завершение обработчика логичеÑкой репликации по команде админиÑтратора" + +#: tcop/postgres.c:2928 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "процеÑÑ Ð·Ð°Ð¿ÑƒÑка логичеÑкой репликации оÑтановлен" + +#: tcop/postgres.c:2941 tcop/postgres.c:2951 tcop/postgres.c:2984 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за конфликта Ñ Ð¿Ñ€Ð¾Ñ†ÐµÑÑом воÑÑтановлениÑ" -#: tcop/postgres.c:2869 +#: tcop/postgres.c:2957 #, c-format msgid "terminating connection due to administrator command" msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ команде админиÑтратора" -#: tcop/postgres.c:2879 +#: tcop/postgres.c:2967 #, c-format msgid "connection to client lost" msgstr "подключение к клиенту потерÑно" -#: tcop/postgres.c:2947 +#: tcop/postgres.c:3033 #, c-format msgid "canceling statement due to lock timeout" -msgstr "выполнение оператора отменено из-за таймаута блокировки" +msgstr "выполнение оператора отменено из-за тайм-аута блокировки" -#: tcop/postgres.c:2954 +#: tcop/postgres.c:3040 #, c-format msgid "canceling statement due to statement timeout" -msgstr "выполнение оператора отменено из-за таймаута" +msgstr "выполнение оператора отменено из-за тайм-аута" -#: tcop/postgres.c:2961 +#: tcop/postgres.c:3047 #, c-format msgid "canceling autovacuum task" msgstr "отмена задачи автоочиÑтки" -#: tcop/postgres.c:2984 +#: tcop/postgres.c:3070 #, c-format msgid "canceling statement due to user request" msgstr "выполнение оператора отменено по запроÑу пользователÑ" -#: tcop/postgres.c:2994 +#: tcop/postgres.c:3080 #, c-format msgid "terminating connection due to idle-in-transaction timeout" -msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за таймаута проÑÑ‚Ð¾Ñ Ð² транзакции" +msgstr "закрытие Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð·-за тайм-аута проÑÑ‚Ð¾Ñ Ð² транзакции" -#: tcop/postgres.c:3108 +#: tcop/postgres.c:3194 #, c-format msgid "stack depth limit exceeded" msgstr "превышен предел глубины Ñтека" -#: tcop/postgres.c:3109 +#: tcop/postgres.c:3195 #, c-format msgid "" "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " @@ -20326,12 +21645,12 @@ msgstr "" "КБ), предварительно убедившиÑÑŒ, что ОС предоÑтавлÑет доÑтаточный размер " "Ñтека." -#: tcop/postgres.c:3172 +#: tcop/postgres.c:3258 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "Значение \"max_stack_depth\" не должно превышать %ld КБ." -#: tcop/postgres.c:3174 +#: tcop/postgres.c:3260 #, c-format msgid "" "Increase the platform's stack depth limit via \"ulimit -s\" or local " @@ -20340,48 +21659,48 @@ msgstr "" "Увеличьте предел глубины Ñтека в ÑиÑтеме Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команды \"ulimit -s\" или " "Ñквивалента в вашей ОС." -#: tcop/postgres.c:3534 +#: tcop/postgres.c:3620 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "неверный аргумент командной Ñтроки Ð´Ð»Ñ Ñерверного процеÑÑа: %s" -#: tcop/postgres.c:3535 tcop/postgres.c:3541 +#: tcop/postgres.c:3621 tcop/postgres.c:3627 #, c-format msgid "Try \"%s --help\" for more information." msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\"." -#: tcop/postgres.c:3539 +#: tcop/postgres.c:3625 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: неверный аргумент командной Ñтроки: %s" -#: tcop/postgres.c:3601 +#: tcop/postgres.c:3687 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: не указаны ни база данных, ни пользователь" -#: tcop/postgres.c:4221 +#: tcop/postgres.c:4316 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "неверный подтип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ CLOSE: %d" -#: tcop/postgres.c:4256 +#: tcop/postgres.c:4351 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "неверный подтип ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ DESCRIBE: %d" -#: tcop/postgres.c:4334 +#: tcop/postgres.c:4429 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "вызовы функции fastpath не поддерживаютÑÑ Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸Ñ†Ð¸Ñ€ÑƒÑŽÑ‰Ð¸Ñ… Ñоединений" -#: tcop/postgres.c:4338 +#: tcop/postgres.c:4433 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "" "протокол раÑширенных запроÑов не поддерживаетÑÑ Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸Ñ†Ð¸Ñ€ÑƒÑŽÑ‰Ð¸Ñ… Ñоединений" -#: tcop/postgres.c:4508 +#: tcop/postgres.c:4610 #, c-format msgid "" "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s" @@ -20390,52 +21709,62 @@ msgstr "" "отключение: Ð²Ñ€ÐµÐ¼Ñ ÑеанÑа: %d:%02d:%02d.%03d пользователь=%s база данных=%s " "компьютер=%s%s%s" -#: tcop/pquery.c:646 +#: tcop/pquery.c:645 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "" "чиÑло форматов результатов в Ñообщении Bind (%d) не равно чиÑлу Ñтолбцов в " "запроÑе (%d)" -#: tcop/pquery.c:953 +#: tcop/pquery.c:952 #, c-format msgid "cursor can only scan forward" msgstr "курÑор может Ñканировать только вперёд" -#: tcop/pquery.c:954 +#: tcop/pquery.c:953 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "Добавьте в его объÑвление SCROLL, чтобы он мог перемещатьÑÑ Ð½Ð°Ð·Ð°Ð´." #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:242 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "в транзакции в режиме \"только чтение\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ %s" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:260 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "выполнить %s во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:279 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "выполнить %s во Ð²Ñ€ÐµÐ¼Ñ Ð²Ð¾ÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:297 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "в рамках операции Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми по безопаÑноÑти Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ %s" -#: tcop/utility.c:765 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" msgstr "Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ CHECKPOINT нужно быть Ñуперпользователем" +#: tcop/utility.c:1348 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "Ñоздать Ð¸Ð½Ð´ÐµÐºÑ Ð² Ñекционированной таблице \"%s\" нельзÑ" + +#: tcop/utility.c:1350 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "Таблица \"%s\" Ñодержит Ñекции, ÑвлÑющиеÑÑ Ñторонними таблицами." + #: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" @@ -20586,23 +21915,23 @@ msgstr "неверный флаг аффикÑов \"%s\" Ñо значение msgid "could not open dictionary file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл ÑÐ»Ð¾Ð²Ð°Ñ€Ñ \"%s\": %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "неверное регулÑрное выражение: %s" #: tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 -#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15212 gram.y:15229 +#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15730 gram.y:15747 #, c-format msgid "syntax error" msgstr "ошибка ÑинтакÑиÑа" -#: tsearch/spell.c:1161 tsearch/spell.c:1721 +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format msgid "invalid affix alias \"%s\"" msgstr "неверное указание аффикÑа \"%s\"" -#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1426 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл аффикÑов \"%s\": %m" @@ -20621,22 +21950,27 @@ msgstr "" msgid "invalid number of flag vector aliases" msgstr "неверное количеÑтво векторов флагов" -#: tsearch/spell.c:1542 +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "количеÑтво пÑевдонимов превышает заданное чиÑло %d" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "файл аффикÑов Ñодержит команды и в Ñтаром, и в новом Ñтиле" -#: tsearch/to_tsany.c:179 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "Ñтрока Ñлишком длинна Ð´Ð»Ñ tsvector (%d Б, при макÑимуме %d)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "Ñтрока %d файла конфигурации \"%s\": \"%s\"" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "преобразовать wchar_t в кодировку Ñервера не удалоÑÑŒ: %m" @@ -20663,386 +21997,386 @@ msgstr "неверное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° конфигурации текÑто msgid "could not open stop-word file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл Ñтоп-Ñлов \"%s\": %m" -#: tsearch/wparser.c:321 tsearch/wparser.c:408 tsearch/wparser.c:484 +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 #, c-format msgid "text search parser does not support headline creation" msgstr "анализатор текÑтового поиÑка не поддерживает Ñоздание выдержек" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "нераÑпознанный параметр функции выдержки: \"%s\"" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "Значение MinWords должно быть меньше MaxWords" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "Значение MinWords должно быть положительным" -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "Значение ShortWord должно быть >= 0" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "Значение MaxFragments должно быть >= 0" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:91 #, c-format msgid "identifier too long" msgstr "Ñлишком длинный идентификатор" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:92 #, c-format msgid "Identifier must be less than %d characters." msgstr "Идентификатор должен быть короче %d байт." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "нераÑпознанное ключевое Ñлово: \"%s\"" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "Ключевым Ñловом ACL должно быть \"group\" или \"user\"." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "отÑутÑтвует имÑ" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "За ключевыми Ñловами \"group\" или \"user\" должно Ñледовать имÑ." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "отÑутÑтвует знак \"=\"" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "неверный Ñимвол режима: должен быть один из \"%s\"" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "за знаком \"/\" должно Ñледовать имÑ" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "назначившим права ÑчитаетÑÑ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒ Ñ ID %u" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "МаÑÑив ACL Ñодержит неверный тип данных" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "МаÑÑивы ACL должны быть одномерными" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "МаÑÑивы ACL не должны Ñодержать Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ null" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "лишний муÑор в конце Ñпецификации ACL" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1213 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "привилегию Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð°Ð² Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐµÑ€Ð½ÑƒÑ‚ÑŒ тому, кто назначил её вам" -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1274 #, c-format msgid "dependent privileges exist" msgstr "ÑущеÑтвуют завиÑимые права" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1275 #, c-format msgid "Use CASCADE to revoke them too." msgstr "ИÑпользуйте CASCADE, чтобы отозвать и их." -#: utils/adt/acl.c:1520 +#: utils/adt/acl.c:1537 #, c-format msgid "aclinsert is no longer supported" msgstr "aclinsert больше не поддерживаетÑÑ" -#: utils/adt/acl.c:1530 +#: utils/adt/acl.c:1547 #, c-format msgid "aclremove is no longer supported" msgstr "aclremove больше не поддерживаетÑÑ" -#: utils/adt/acl.c:1616 utils/adt/acl.c:1670 +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "нераÑпознанный тип прав: \"%s\"" -#: utils/adt/acl.c:3410 utils/adt/regproc.c:125 utils/adt/regproc.c:146 -#: utils/adt/regproc.c:321 +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" не ÑущеÑтвует" -#: utils/adt/acl.c:4864 +#: utils/adt/acl.c:4959 #, c-format msgid "must be member of role \"%s\"" msgstr "нужно быть членом роли \"%s\"" -#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5848 -#: utils/adt/arrayfuncs.c:6159 utils/adt/arrayutils.c:93 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 +#: utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 #: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "размер маÑÑива превышает предел (%d)" -#: utils/adt/array_userfuncs.c:79 utils/adt/array_userfuncs.c:541 -#: utils/adt/array_userfuncs.c:621 utils/adt/json.c:1764 utils/adt/json.c:1859 -#: utils/adt/json.c:1897 utils/adt/jsonb.c:1127 utils/adt/jsonb.c:1156 -#: utils/adt/jsonb.c:1592 utils/adt/jsonb.c:1756 utils/adt/jsonb.c:1766 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 +#: utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 #, c-format msgid "could not determine input data type" msgstr "не удалоÑÑŒ определить тип входных данных" -#: utils/adt/array_userfuncs.c:84 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "тип входных данных не ÑвлÑетÑÑ Ð¼Ð°ÑÑивом" -#: utils/adt/array_userfuncs.c:132 utils/adt/array_userfuncs.c:186 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1228 utils/adt/float.c:1287 -#: utils/adt/float.c:3556 utils/adt/float.c:3572 utils/adt/int.c:608 -#: utils/adt/int.c:637 utils/adt/int.c:658 utils/adt/int.c:689 -#: utils/adt/int.c:722 utils/adt/int.c:744 utils/adt/int.c:892 -#: utils/adt/int.c:913 utils/adt/int.c:940 utils/adt/int.c:980 -#: utils/adt/int.c:1001 utils/adt/int.c:1028 utils/adt/int.c:1061 -#: utils/adt/int.c:1144 utils/adt/int8.c:1298 utils/adt/numeric.c:2953 -#: utils/adt/numeric.c:2962 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 -#: utils/adt/varlena.c:1054 utils/adt/varlena.c:2933 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1376 utils/adt/float.c:1464 +#: utils/adt/float.c:3765 utils/adt/float.c:3779 utils/adt/int.c:755 +#: utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 +#: utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 +#: utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 +#: utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 +#: utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 +#: utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 #, c-format msgid "integer out of range" msgstr "целое вне диапазона" -#: utils/adt/array_userfuncs.c:139 utils/adt/array_userfuncs.c:196 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "аргумент должен быть одномерным маÑÑивом или пуÑтым" -#: utils/adt/array_userfuncs.c:278 utils/adt/array_userfuncs.c:317 -#: utils/adt/array_userfuncs.c:354 utils/adt/array_userfuncs.c:383 -#: utils/adt/array_userfuncs.c:411 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "ÑоединÑть неÑовмеÑтимые маÑÑивы нельзÑ" -#: utils/adt/array_userfuncs.c:279 +#: utils/adt/array_userfuncs.c:274 #, c-format msgid "" "Arrays with element types %s and %s are not compatible for concatenation." msgstr "МаÑÑивы Ñ Ñлементами типов %s и %s неÑовмеÑтимы Ð´Ð»Ñ ÑоединениÑ." -#: utils/adt/array_userfuncs.c:318 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "МаÑÑивы Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð½Ð¾ÑÑ‚Ñми %d и %d неÑовмеÑтимы Ð´Ð»Ñ ÑоединениÑ." -#: utils/adt/array_userfuncs.c:355 +#: utils/adt/array_userfuncs.c:350 #, c-format msgid "" "Arrays with differing element dimensions are not compatible for " "concatenation." msgstr "МаÑÑивы Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ размерноÑÑ‚Ñми Ñлементов неÑовмеÑтимы Ð´Ð»Ñ ÑоединениÑ." -#: utils/adt/array_userfuncs.c:384 utils/adt/array_userfuncs.c:412 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "МаÑÑивы Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ размерноÑÑ‚Ñми неÑовмеÑтимы Ð´Ð»Ñ ÑоединениÑ." -#: utils/adt/array_userfuncs.c:480 utils/adt/arrayfuncs.c:1284 -#: utils/adt/arrayfuncs.c:3357 utils/adt/arrayfuncs.c:5754 -#, c-format -msgid "invalid number of dimensions: %d" -msgstr "неверное чиÑло размерноÑтей: %d" - -#: utils/adt/array_userfuncs.c:737 utils/adt/array_userfuncs.c:889 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "поиÑк Ñлементов в многомерных маÑÑивах не поддерживаетÑÑ" -#: utils/adt/array_userfuncs.c:761 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð½Ðµ может быть NULL" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" msgstr "ошибочный литерал маÑÑива: \"%s\"" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "За \"[\" должны Ñледовать Ñвно задаваемые размерноÑти маÑÑива." -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "ОтÑутÑтвует значение размерноÑти маÑÑива." -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "ПоÑле размерноÑтей маÑÑива отÑутÑтвует \"%s\"." -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "верхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° не может быть меньше нижней" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "Значение маÑÑива должно начинатьÑÑ Ñ \"{\" или ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð½Ð¾Ñти." -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." msgstr "Содержимое маÑÑива должно начинатьÑÑ Ñ \"{\"." -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "Указанные размерноÑти маÑÑива не ÑоответÑтвуют его Ñодержимому." -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2114 utils/adt/rangetypes.c:2122 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 +#: utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 #, c-format msgid "Unexpected end of input." msgstr "Ðеожиданный конец ввода." -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "Ðеожиданный знак \"%c\"." -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "Ðеожиданный Ñлемент маÑÑива." -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "Ðепарный знак \"%c\"." -#: utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "" "Ð”Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ñ… маÑÑивов должны задаватьÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ‹Ðµ маÑÑивы Ñ " "ÑоответÑтвующими размерноÑÑ‚Ñми." -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "МуÑор поÑле закрывающей фигурной Ñкобки." -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5816 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "неверное чиÑло размерноÑтей: %d" + +#: utils/adt/arrayfuncs.c:1308 #, c-format msgid "invalid array flags" msgstr "неверные флаги маÑÑива" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "неверный тип Ñлемента" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2651 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s нет функции ввода двоичных данных" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "неподходÑщий двоичный формат в Ñлементе маÑÑива %d" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2684 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s нет функции вывода двоичных данных" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "разрезание маÑÑивов поÑтоÑнной длины не поддерживаетÑÑ" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5740 -#: utils/adt/arrayfuncs.c:5766 utils/adt/arrayfuncs.c:5777 -#: utils/adt/json.c:2295 utils/adt/json.c:2370 utils/adt/jsonb.c:1370 -#: utils/adt/jsonb.c:1456 utils/adt/jsonfuncs.c:3496 utils/adt/jsonfuncs.c:3647 -#: utils/adt/jsonfuncs.c:3692 utils/adt/jsonfuncs.c:3739 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 +#: utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 +#: utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 +#: utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4295 +#: utils/adt/jsonfuncs.c:4446 utils/adt/jsonfuncs.c:4491 +#: utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "неверное чиÑло индекÑов маÑÑива" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð¼Ð°ÑÑива вне диапазона" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñвоить значение null Ñлементу маÑÑива фикÑированной длины" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñрезах маÑÑивов фикÑированной длины не поддерживаютÑÑ" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format msgid "array slice subscript must provide both boundaries" msgstr "в указании Ñреза маÑÑива должны быть заданы обе границы" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format msgid "" "When assigning to a slice of an empty array value, slice boundaries must be " @@ -21051,78 +22385,84 @@ msgstr "" "При приÑвоении значений Ñрезу в пуÑтом маÑÑиве, должны полноÑтью задаватьÑÑ " "обе границы." -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "иÑходный маÑÑив Ñлишком мал" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "Ñлемент маÑÑива null недопуÑтим в данном контекÑте" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4124 #, c-format msgid "cannot compare arrays of different element types" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ñравнивать маÑÑивы Ñ Ñлементами разных типов" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 +#: utils/adt/rangetypes.c:1317 #, c-format msgid "could not identify a hash function for type %s" msgstr "не удалоÑÑŒ найти функцию Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" -#: utils/adt/arrayfuncs.c:5154 +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "не удалоÑÑŒ найти функцию раÑширенного Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" + +#: utils/adt/arrayfuncs.c:5216 #, c-format msgid "data type %s is not an array type" msgstr "тип данных %s не ÑвлÑетÑÑ Ñ‚Ð¸Ð¿Ð¾Ð¼ маÑÑива" -#: utils/adt/arrayfuncs.c:5209 +#: utils/adt/arrayfuncs.c:5271 #, c-format msgid "cannot accumulate null arrays" msgstr "аккумулировать NULL-маÑÑивы нельзÑ" -#: utils/adt/arrayfuncs.c:5237 +#: utils/adt/arrayfuncs.c:5299 #, c-format msgid "cannot accumulate empty arrays" msgstr "аккумулировать пуÑтые маÑÑивы нельзÑ" -#: utils/adt/arrayfuncs.c:5266 utils/adt/arrayfuncs.c:5272 +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "аккумулировать маÑÑивы различной размерноÑти нельзÑ" -#: utils/adt/arrayfuncs.c:5638 utils/adt/arrayfuncs.c:5678 +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "маÑÑив размерноÑтей или маÑÑив нижних границ не может быть null" -#: utils/adt/arrayfuncs.c:5741 utils/adt/arrayfuncs.c:5767 +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 #, c-format msgid "Dimension array must be one dimensional." msgstr "МаÑÑив размерноÑтей должен быть одномерным." -#: utils/adt/arrayfuncs.c:5746 utils/adt/arrayfuncs.c:5772 +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 #, c-format msgid "dimension values cannot be null" msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð½Ð¾Ñтей не могут быть null" -#: utils/adt/arrayfuncs.c:5778 +#: utils/adt/arrayfuncs.c:5840 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "МаÑÑив нижних границ и маÑÑив размерноÑтей имеют разные размеры." -#: utils/adt/arrayfuncs.c:6024 +#: utils/adt/arrayfuncs.c:6086 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "удаление Ñлементов из многомерных маÑÑивов не поддерживаетÑÑ" -#: utils/adt/arrayfuncs.c:6301 +#: utils/adt/arrayfuncs.c:6363 #, c-format msgid "thresholds must be one-dimensional array" msgstr "границы должны задаватьÑÑ Ð¾Ð´Ð½Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ð¼ маÑÑивом" -#: utils/adt/arrayfuncs.c:6306 +#: utils/adt/arrayfuncs.c:6368 #, c-format msgid "thresholds array must not contain NULLs" msgstr "маÑÑив границ не должен Ñодержать NULL" @@ -21148,19 +22488,19 @@ msgid "encoding conversion from %s to ASCII not supported" msgstr "преобразование кодировки из %s в ASCII не поддерживаетÑÑ" #. translator: first %s is inet or cidr -#: utils/adt/bool.c:153 utils/adt/cash.c:278 utils/adt/datetime.c:3799 -#: utils/adt/float.c:244 utils/adt/float.c:318 utils/adt/float.c:342 -#: utils/adt/float.c:461 utils/adt/float.c:544 utils/adt/float.c:570 -#: utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 utils/adt/geo_ops.c:178 -#: utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 utils/adt/geo_ops.c:265 -#: utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 utils/adt/geo_ops.c:1356 -#: utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3430 utils/adt/geo_ops.c:4563 -#: utils/adt/geo_ops.c:4579 utils/adt/geo_ops.c:4586 utils/adt/mac.c:94 +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 +#: utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 +#: utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 +#: utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 +#: utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 +#: utils/adt/geo_ops.c:934 utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 +#: utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 +#: utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 #: utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 -#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1539 -#: utils/adt/network.c:58 utils/adt/numeric.c:593 utils/adt/numeric.c:620 -#: utils/adt/numeric.c:5488 utils/adt/numeric.c:5512 utils/adt/numeric.c:5536 -#: utils/adt/numeric.c:6338 utils/adt/numeric.c:6364 utils/adt/oid.c:44 +#: utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1542 +#: utils/adt/network.c:58 utils/adt/numeric.c:604 utils/adt/numeric.c:631 +#: utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 +#: utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 #: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 #: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 #: utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 @@ -21169,22 +22509,22 @@ msgstr "преобразование кодировки из %s в ASCII не п msgid "invalid input syntax for type %s: \"%s\"" msgstr "неверный ÑинтакÑÐ¸Ñ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s: \"%s\"" -#: utils/adt/cash.c:211 utils/adt/cash.c:238 utils/adt/cash.c:249 -#: utils/adt/cash.c:290 utils/adt/int8.c:114 utils/adt/numutils.c:75 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 #: utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format msgid "value \"%s\" is out of range for type %s" msgstr "значение \"%s\" вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" -#: utils/adt/cash.c:651 utils/adt/cash.c:701 utils/adt/cash.c:752 -#: utils/adt/cash.c:801 utils/adt/cash.c:853 utils/adt/cash.c:903 -#: utils/adt/float.c:855 utils/adt/float.c:919 utils/adt/float.c:3315 -#: utils/adt/float.c:3378 utils/adt/geo_ops.c:4093 utils/adt/int.c:704 -#: utils/adt/int.c:846 utils/adt/int.c:954 utils/adt/int.c:1043 -#: utils/adt/int.c:1082 utils/adt/int.c:1110 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6902 -#: utils/adt/numeric.c:7191 utils/adt/numeric.c:8204 utils/adt/timestamp.c:3186 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3526 +#: utils/adt/float.c:3589 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 +#: utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 +#: utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 +#: utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 +#: utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3238 #, c-format msgid "division by zero" msgstr "деление на ноль" @@ -21194,163 +22534,172 @@ msgstr "деление на ноль" msgid "\"char\" out of range" msgstr "значение \"char\" вне диапазона" -#: utils/adt/date.c:67 utils/adt/timestamp.c:94 utils/adt/varbit.c:53 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 #: utils/adt/varchar.c:46 #, c-format msgid "invalid type modifier" msgstr "неверный модификатор типа" -#: utils/adt/date.c:79 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "TIME(%d)%s: точноÑть должна быть неотрицательной" -#: utils/adt/date.c:85 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "TIME(%d)%s: точноÑть уменьшена до дозволенного макÑимума: %d" -#: utils/adt/date.c:146 utils/adt/datetime.c:1209 utils/adt/datetime.c:2117 +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "значение \"current\" Ð´Ð»Ñ Ð´Ð°Ñ‚Ñ‹/времени больше не поддерживаетÑÑ" -#: utils/adt/date.c:172 utils/adt/date.c:180 utils/adt/formatting.c:3558 -#: utils/adt/formatting.c:3567 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 +#: utils/adt/formatting.c:3615 #, c-format msgid "date out of range: \"%s\"" msgstr "дата вне диапазона: \"%s\"" -#: utils/adt/date.c:227 utils/adt/date.c:539 utils/adt/date.c:563 -#: utils/adt/xml.c:2085 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2197 #, c-format msgid "date out of range" msgstr "дата вне диапазона" -#: utils/adt/date.c:273 utils/adt/timestamp.c:563 +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "значение Ð¿Ð¾Ð»Ñ Ñ‚Ð¸Ð¿Ð° date вне диапазона: %d-%02d-%02d" -#: utils/adt/date.c:280 utils/adt/date.c:289 utils/adt/timestamp.c:569 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "дата вне диапазона: %d-%02d-%02d" -#: utils/adt/date.c:327 utils/adt/date.c:350 utils/adt/date.c:376 -#: utils/adt/date.c:1092 utils/adt/date.c:1138 utils/adt/date.c:1672 -#: utils/adt/date.c:1703 utils/adt/date.c:1732 utils/adt/date.c:2469 -#: utils/adt/datetime.c:1690 utils/adt/formatting.c:3433 -#: utils/adt/formatting.c:3465 utils/adt/formatting.c:3533 -#: utils/adt/json.c:1539 utils/adt/json.c:1561 utils/adt/jsonb.c:824 -#: utils/adt/jsonb.c:848 utils/adt/nabstime.c:456 utils/adt/nabstime.c:499 -#: utils/adt/nabstime.c:529 utils/adt/nabstime.c:572 utils/adt/timestamp.c:229 -#: utils/adt/timestamp.c:261 utils/adt/timestamp.c:691 -#: utils/adt/timestamp.c:700 utils/adt/timestamp.c:778 -#: utils/adt/timestamp.c:811 utils/adt/timestamp.c:2765 -#: utils/adt/timestamp.c:2786 utils/adt/timestamp.c:2799 -#: utils/adt/timestamp.c:2808 utils/adt/timestamp.c:2816 -#: utils/adt/timestamp.c:2871 utils/adt/timestamp.c:2894 -#: utils/adt/timestamp.c:2907 utils/adt/timestamp.c:2918 -#: utils/adt/timestamp.c:2926 utils/adt/timestamp.c:3482 -#: utils/adt/timestamp.c:3607 utils/adt/timestamp.c:3648 -#: utils/adt/timestamp.c:3729 utils/adt/timestamp.c:3775 -#: utils/adt/timestamp.c:3878 utils/adt/timestamp.c:4277 -#: utils/adt/timestamp.c:4376 utils/adt/timestamp.c:4386 -#: utils/adt/timestamp.c:4478 utils/adt/timestamp.c:4580 -#: utils/adt/timestamp.c:4590 utils/adt/timestamp.c:4822 -#: utils/adt/timestamp.c:4836 utils/adt/timestamp.c:4841 -#: utils/adt/timestamp.c:4855 utils/adt/timestamp.c:4900 -#: utils/adt/timestamp.c:4932 utils/adt/timestamp.c:4939 -#: utils/adt/timestamp.c:4972 utils/adt/timestamp.c:4976 -#: utils/adt/timestamp.c:5045 utils/adt/timestamp.c:5049 -#: utils/adt/timestamp.c:5063 utils/adt/timestamp.c:5097 utils/adt/xml.c:2107 -#: utils/adt/xml.c:2114 utils/adt/xml.c:2134 utils/adt/xml.c:2141 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 +#: utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 +#: utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 +#: utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:459 +#: utils/adt/nabstime.c:502 utils/adt/nabstime.c:532 utils/adt/nabstime.c:575 +#: utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 +#: utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 +#: utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 +#: utils/adt/timestamp.c:2817 utils/adt/timestamp.c:2838 +#: utils/adt/timestamp.c:2851 utils/adt/timestamp.c:2860 +#: utils/adt/timestamp.c:2868 utils/adt/timestamp.c:2923 +#: utils/adt/timestamp.c:2946 utils/adt/timestamp.c:2959 +#: utils/adt/timestamp.c:2970 utils/adt/timestamp.c:2978 +#: utils/adt/timestamp.c:3638 utils/adt/timestamp.c:3763 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3894 +#: utils/adt/timestamp.c:3940 utils/adt/timestamp.c:4043 +#: utils/adt/timestamp.c:4450 utils/adt/timestamp.c:4549 +#: utils/adt/timestamp.c:4559 utils/adt/timestamp.c:4651 +#: utils/adt/timestamp.c:4753 utils/adt/timestamp.c:4763 +#: utils/adt/timestamp.c:4995 utils/adt/timestamp.c:5009 +#: utils/adt/timestamp.c:5014 utils/adt/timestamp.c:5028 +#: utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5105 +#: utils/adt/timestamp.c:5112 utils/adt/timestamp.c:5145 +#: utils/adt/timestamp.c:5149 utils/adt/timestamp.c:5218 +#: utils/adt/timestamp.c:5222 utils/adt/timestamp.c:5236 +#: utils/adt/timestamp.c:5270 utils/adt/xml.c:2219 utils/adt/xml.c:2226 +#: utils/adt/xml.c:2246 utils/adt/xml.c:2253 #, c-format msgid "timestamp out of range" msgstr "timestamp вне диапазона" -#: utils/adt/date.c:514 +#: utils/adt/date.c:512 #, c-format msgid "cannot subtract infinite dates" msgstr "вычитать беÑконечные даты нельзÑ" -#: utils/adt/date.c:592 utils/adt/date.c:623 utils/adt/date.c:641 -#: utils/adt/date.c:2506 utils/adt/date.c:2516 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2633 utils/adt/date.c:2643 #, c-format msgid "date out of range for timestamp" msgstr "дата вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° timestamp" -#: utils/adt/date.c:1164 +#: utils/adt/date.c:1190 #, c-format msgid "cannot convert reserved abstime value to date" msgstr "преобразовать зарезервированное значение abstime в дату нельзÑ" -#: utils/adt/date.c:1182 utils/adt/date.c:1188 +#: utils/adt/date.c:1208 utils/adt/date.c:1214 #, c-format msgid "abstime out of range for date" msgstr "abstime вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° даты" -#: utils/adt/date.c:1301 utils/adt/date.c:2020 +#: utils/adt/date.c:1327 utils/adt/date.c:2091 #, c-format msgid "time out of range" msgstr "Ð²Ñ€ÐµÐ¼Ñ Ð²Ð½Ðµ диапазона" -#: utils/adt/date.c:1357 utils/adt/timestamp.c:588 +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "значение Ð¿Ð¾Ð»Ñ Ñ‚Ð¸Ð¿Ð° time вне диапазона: %d:%02d:%02g" -#: utils/adt/date.c:1907 utils/adt/date.c:1920 +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 +#: utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 +#: utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 +#: utils/adt/timestamp.c:3287 utils/adt/timestamp.c:3318 +#: utils/adt/timestamp.c:3349 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "неверное Ñмещение PRECEDING или FOLLOWING в оконной функции" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "\"времÑ\" Ñодержит нераÑпознанные единицы \"%s\"" -#: utils/adt/date.c:2028 +#: utils/adt/date.c:2099 #, c-format msgid "time zone displacement out of range" msgstr "Ñмещение чаÑового поÑÑа вне диапазона" -#: utils/adt/date.c:2601 utils/adt/date.c:2614 +#: utils/adt/date.c:2728 utils/adt/date.c:2741 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "\"Ð²Ñ€ÐµÐ¼Ñ Ñ Ñ‡Ð°Ñовым поÑÑом\" Ñодержит нераÑпознанные единицы \"%s\"" -#: utils/adt/date.c:2687 utils/adt/datetime.c:931 utils/adt/datetime.c:1848 -#: utils/adt/datetime.c:4636 utils/adt/timestamp.c:502 -#: utils/adt/timestamp.c:529 utils/adt/timestamp.c:4847 -#: utils/adt/timestamp.c:5055 +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 +#: utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 +#: utils/adt/timestamp.c:530 utils/adt/timestamp.c:5020 +#: utils/adt/timestamp.c:5228 #, c-format msgid "time zone \"%s\" not recognized" msgstr "чаÑовой поÑÑ \"%s\" не раÑпознан" -#: utils/adt/date.c:2719 utils/adt/timestamp.c:4889 utils/adt/timestamp.c:5086 +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5062 utils/adt/timestamp.c:5259 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "" "интервал \"%s\", задающий чаÑовой поÑÑ, не должен Ñодержать дней или меÑÑцев" -#: utils/adt/datetime.c:3772 utils/adt/datetime.c:3779 +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "значение Ð¿Ð¾Ð»Ñ Ñ‚Ð¸Ð¿Ð° date/time вне диапазона: \"%s\"" -#: utils/adt/datetime.c:3781 +#: utils/adt/datetime.c:3770 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "Возможно, вам нужно изменить наÑтройку \"datestyle\"." -#: utils/adt/datetime.c:3786 +#: utils/adt/datetime.c:3775 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "значение Ð¿Ð¾Ð»Ñ interval вне диапазона: \"%s\"" -#: utils/adt/datetime.c:3792 +#: utils/adt/datetime.c:3781 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "Ñмещение чаÑового поÑÑа вне диапазона: \"%s\"" -#: utils/adt/datetime.c:4638 +#: utils/adt/datetime.c:4627 #, c-format msgid "" "This time zone name appears in the configuration file for time zone " @@ -21364,28 +22713,23 @@ msgstr "" msgid "invalid Datum pointer" msgstr "неверный указатель Datum" -#: utils/adt/dbsize.c:116 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "не удалоÑÑŒ открыть каталог табличного проÑтранÑтва \"%s\": %m" - -#: utils/adt/dbsize.c:764 utils/adt/dbsize.c:832 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format msgid "invalid size: \"%s\"" msgstr "Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð°: \"%s\"" -#: utils/adt/dbsize.c:833 +#: utils/adt/dbsize.c:828 #, c-format msgid "Invalid size unit: \"%s\"." msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐµÐ´Ð¸Ð½Ð¸Ñ†Ð° Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ñ‹: \"%s\"." -#: utils/adt/dbsize.c:834 +#: utils/adt/dbsize.c:829 #, c-format msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "" "ДопуÑтимые единицы измерениÑ: \"bytes\", \"kB\", \"MB\", \"GB\" и \"TB\"." -#: utils/adt/domains.c:91 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "тип \"%s\" не ÑвлÑетÑÑ Ð´Ð¾Ð¼ÐµÐ½Ð¾Ð¼" @@ -21426,252 +22770,248 @@ msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "" "Входные данные лишены выравниваниÑ, обрезаны или повреждены иным образом." -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:785 -#: utils/adt/json.c:825 utils/adt/json.c:841 utils/adt/json.c:853 -#: utils/adt/json.c:863 utils/adt/json.c:914 utils/adt/json.c:946 -#: utils/adt/json.c:965 utils/adt/json.c:977 utils/adt/json.c:989 -#: utils/adt/json.c:1134 utils/adt/json.c:1148 utils/adt/json.c:1159 -#: utils/adt/json.c:1167 utils/adt/json.c:1175 utils/adt/json.c:1183 -#: utils/adt/json.c:1191 utils/adt/json.c:1199 utils/adt/json.c:1207 -#: utils/adt/json.c:1215 utils/adt/json.c:1245 utils/adt/varlena.c:296 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 #: utils/adt/varlena.c:337 #, c-format msgid "invalid input syntax for type %s" msgstr "неверный ÑинтакÑÐ¸Ñ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s" -#: utils/adt/enum.c:115 -#, c-format -msgid "unsafe use of new value \"%s\" of enum type %s" -msgstr "небезопаÑное иÑпользование нового Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"%s\" типа-перечиÑÐ»ÐµÐ½Ð¸Ñ %s" - -#: utils/adt/enum.c:118 -#, c-format -msgid "New enum values must be committed before they can be used." -msgstr "" -"Ðовые Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть зафикÑированы перед иÑпользованием." - -#: utils/adt/enum.c:136 utils/adt/enum.c:146 utils/adt/enum.c:204 -#: utils/adt/enum.c:214 +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 +#: utils/adt/enum.c:123 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "неверное значение Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ %s: \"%s\"" -#: utils/adt/enum.c:176 utils/adt/enum.c:242 utils/adt/enum.c:301 +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 #, c-format msgid "invalid internal value for enum: %u" msgstr "неверное внутреннее значение Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸ÑлениÑ: %u" -#: utils/adt/enum.c:461 utils/adt/enum.c:490 utils/adt/enum.c:530 -#: utils/adt/enum.c:550 +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 +#: utils/adt/enum.c:449 #, c-format msgid "could not determine actual enum type" msgstr "не удалоÑÑŒ определить фактичеÑкий тип перечиÑлениÑ" -#: utils/adt/enum.c:469 utils/adt/enum.c:498 +#: utils/adt/enum.c:368 utils/adt/enum.c:397 #, c-format msgid "enum %s contains no values" msgstr "перечиÑление %s не Ñодержит значений" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 +#: utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "тип %s не ÑвлÑетÑÑ ÑоÑтавным" + +#: utils/adt/float.c:55 #, c-format msgid "value out of range: overflow" msgstr "значение вне диапазона: переполнение" -#: utils/adt/float.c:63 +#: utils/adt/float.c:60 #, c-format msgid "value out of range: underflow" msgstr "значение вне диапазона: антипереполнение" -#: utils/adt/float.c:312 +#: utils/adt/float.c:309 #, c-format msgid "\"%s\" is out of range for type real" msgstr "\"%s\" вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° real" -#: utils/adt/float.c:537 +#: utils/adt/float.c:534 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "\"%s\" вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° double precision" -#: utils/adt/float.c:1246 utils/adt/float.c:1304 utils/adt/int.c:334 -#: utils/adt/int.c:760 utils/adt/int.c:789 utils/adt/int.c:810 -#: utils/adt/int.c:830 utils/adt/int.c:864 utils/adt/int.c:1159 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3050 utils/adt/numeric.c:3059 +#: utils/adt/float.c:1408 utils/adt/float.c:1496 utils/adt/int.c:332 +#: utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 +#: utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 +#: utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 #, c-format msgid "smallint out of range" msgstr "smallint вне диапазона" -#: utils/adt/float.c:1430 utils/adt/numeric.c:7624 +#: utils/adt/float.c:1622 utils/adt/numeric.c:7802 #, c-format msgid "cannot take square root of a negative number" msgstr "извлечь квадратный корень отрицательного чиÑла нельзÑ" -#: utils/adt/float.c:1472 utils/adt/numeric.c:2853 +#: utils/adt/float.c:1683 utils/adt/numeric.c:3017 #, c-format msgid "zero raised to a negative power is undefined" msgstr "ноль в отрицательной Ñтепени даёт неопределённоÑть" -#: utils/adt/float.c:1476 utils/adt/numeric.c:2859 +#: utils/adt/float.c:1687 utils/adt/numeric.c:3023 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "отрицательное чиÑло в дробной Ñтепени даёт комплекÑный результат" -#: utils/adt/float.c:1542 utils/adt/float.c:1572 utils/adt/numeric.c:7890 +#: utils/adt/float.c:1753 utils/adt/float.c:1783 utils/adt/numeric.c:8068 #, c-format msgid "cannot take logarithm of zero" msgstr "вычиÑлить логарифм Ð½ÑƒÐ»Ñ Ð½ÐµÐ»ÑŒÐ·Ñ" -#: utils/adt/float.c:1546 utils/adt/float.c:1576 utils/adt/numeric.c:7894 +#: utils/adt/float.c:1757 utils/adt/float.c:1787 utils/adt/numeric.c:8072 #, c-format msgid "cannot take logarithm of a negative number" msgstr "вычиÑлить логарифм отрицательного чиÑла нельзÑ" -#: utils/adt/float.c:1606 utils/adt/float.c:1636 utils/adt/float.c:1728 -#: utils/adt/float.c:1754 utils/adt/float.c:1781 utils/adt/float.c:1807 -#: utils/adt/float.c:1954 utils/adt/float.c:1989 utils/adt/float.c:2153 -#: utils/adt/float.c:2207 utils/adt/float.c:2271 utils/adt/float.c:2326 +#: utils/adt/float.c:1817 utils/adt/float.c:1847 utils/adt/float.c:1939 +#: utils/adt/float.c:1965 utils/adt/float.c:1992 utils/adt/float.c:2018 +#: utils/adt/float.c:2165 utils/adt/float.c:2200 utils/adt/float.c:2364 +#: utils/adt/float.c:2418 utils/adt/float.c:2482 utils/adt/float.c:2537 #, c-format msgid "input is out of range" msgstr "введённое значение вне диапазона" -#: utils/adt/float.c:3532 utils/adt/numeric.c:1493 +#: utils/adt/float.c:3743 utils/adt/numeric.c:1504 #, c-format msgid "count must be greater than zero" msgstr "Ñчётчик должен быть больше нулÑ" -#: utils/adt/float.c:3537 utils/adt/numeric.c:1500 +#: utils/adt/float.c:3748 utils/adt/numeric.c:1511 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "операнд, нижнÑÑ Ð¸ верхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ не могут быть NaN" -#: utils/adt/float.c:3543 +#: utils/adt/float.c:3754 #, c-format msgid "lower and upper bounds must be finite" msgstr "нижнÑÑ Ð¸ верхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ñ‹ должны быть конечными" -#: utils/adt/float.c:3581 utils/adt/numeric.c:1513 +#: utils/adt/float.c:3788 utils/adt/numeric.c:1524 #, c-format msgid "lower bound cannot equal upper bound" msgstr "нижнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° не может равнÑтьÑÑ Ð²ÐµÑ€Ñ…Ð½ÐµÐ¹" -#: utils/adt/formatting.c:493 +#: utils/adt/formatting.c:488 #, c-format msgid "invalid format specification for an interval value" msgstr "Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ ÑÐ¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° Ð´Ð»Ñ Ñ†ÐµÐ»Ð¾Ð³Ð¾ чиÑла" -#: utils/adt/formatting.c:494 +#: utils/adt/formatting.c:489 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "Интервалы не привÑзываютÑÑ Ðº определённым календарным датам." -#: utils/adt/formatting.c:1060 +#: utils/adt/formatting.c:1059 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "\"EEEE\" может быть только поÑледним шаблоном" -#: utils/adt/formatting.c:1068 +#: utils/adt/formatting.c:1067 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "\"9\" должна ÑтоÑть до \"PR\"" -#: utils/adt/formatting.c:1084 +#: utils/adt/formatting.c:1083 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "\"0\" должен ÑтоÑть до \"PR\"" -#: utils/adt/formatting.c:1111 +#: utils/adt/formatting.c:1110 #, c-format msgid "multiple decimal points" msgstr "многочиÑленные деÑÑтичные точки" -#: utils/adt/formatting.c:1115 utils/adt/formatting.c:1198 +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"V\" вмеÑте Ñ Ð´ÐµÑÑтичной точкой" -#: utils/adt/formatting.c:1127 +#: utils/adt/formatting.c:1126 #, c-format msgid "cannot use \"S\" twice" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"S\" дважды" -#: utils/adt/formatting.c:1131 +#: utils/adt/formatting.c:1130 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"S\" вмеÑте Ñ \"PL\"/\"MI\"/\"SG\"/\"PR\"" -#: utils/adt/formatting.c:1151 +#: utils/adt/formatting.c:1150 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"S\" вмеÑте Ñ \"MI\"" -#: utils/adt/formatting.c:1161 +#: utils/adt/formatting.c:1160 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"S\" вмеÑте Ñ \"PL\"" -#: utils/adt/formatting.c:1171 +#: utils/adt/formatting.c:1170 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"S\" вмеÑте Ñ \"SG\"" -#: utils/adt/formatting.c:1180 +#: utils/adt/formatting.c:1179 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"PR\" вмеÑте Ñ \"S\"/\"PL\"/\"MI\"/\"SG\"" -#: utils/adt/formatting.c:1206 +#: utils/adt/formatting.c:1205 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"EEEE\" дважды" -#: utils/adt/formatting.c:1212 +#: utils/adt/formatting.c:1211 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "\"EEEE\" неÑовмеÑтим Ñ Ð´Ñ€ÑƒÐ³Ð¸Ð¼Ð¸ форматами" -#: utils/adt/formatting.c:1213 +#: utils/adt/formatting.c:1212 #, c-format msgid "" "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "" "\"EEEE\" может иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ цифр и деÑÑтичной точки." -#: utils/adt/formatting.c:1402 +#: utils/adt/formatting.c:1392 #, c-format msgid "\"%s\" is not a number" msgstr "\"%s\" не ÑвлÑетÑÑ Ñ‡Ð¸Ñлом" -#: utils/adt/formatting.c:1472 +#: utils/adt/formatting.c:1470 #, c-format msgid "case conversion failed: %s" msgstr "преобразовать региÑтр не удалоÑÑŒ: %s" -#: utils/adt/formatting.c:1536 +#: utils/adt/formatting.c:1535 #, c-format msgid "could not determine which collation to use for lower() function" msgstr "" "не удалоÑÑŒ определить, какое правило Ñортировки иÑпользовать Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ " "lower()" -#: utils/adt/formatting.c:1655 +#: utils/adt/formatting.c:1657 #, c-format msgid "could not determine which collation to use for upper() function" msgstr "" "не удалоÑÑŒ определить, какое правило Ñортировки иÑпользовать Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ " "upper()" -#: utils/adt/formatting.c:1774 +#: utils/adt/formatting.c:1780 #, c-format msgid "could not determine which collation to use for initcap() function" msgstr "" "не удалоÑÑŒ определить, какое правило Ñортировки иÑпользовать Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ " "initcap()" -#: utils/adt/formatting.c:2136 +#: utils/adt/formatting.c:2148 #, c-format msgid "invalid combination of date conventions" msgstr "неверное Ñочетание Ñтилей дат" -#: utils/adt/formatting.c:2137 +#: utils/adt/formatting.c:2149 #, c-format msgid "" "Do not mix Gregorian and ISO week date conventions in a formatting template." @@ -21679,27 +23019,27 @@ msgstr "" "Ðе Ñмешивайте ГригорианÑкий Ñтиль дат (недель) Ñ ISO в одном шаблоне " "форматированиÑ." -#: utils/adt/formatting.c:2154 +#: utils/adt/formatting.c:2166 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "конфликтующие Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ \"%s\" в Ñтроке форматированиÑ" -#: utils/adt/formatting.c:2156 +#: utils/adt/formatting.c:2168 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "Это значение противоречит предыдущему значению Ð¿Ð¾Ð»Ñ Ñ‚Ð¾Ð³Ð¾ же типа." -#: utils/adt/formatting.c:2217 +#: utils/adt/formatting.c:2229 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "Ð²Ñ…Ð¾Ð´Ð½Ð°Ñ Ñтрока короче, чем требует поле Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s\"" -#: utils/adt/formatting.c:2219 +#: utils/adt/formatting.c:2231 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "ТребуетÑÑ Ñимволов: %d, а оÑталоÑÑŒ только %d." -#: utils/adt/formatting.c:2222 utils/adt/formatting.c:2236 +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 #, c-format msgid "" "If your source string is not fixed-width, try using the \"FM\" modifier." @@ -21707,286 +23047,283 @@ msgstr "" "ЕÑли Ð²Ñ…Ð¾Ð´Ð½Ð°Ñ Ñтрока имеет переменную длину, попробуйте иÑпользовать " "модификатор \"FM\"." -#: utils/adt/formatting.c:2232 utils/adt/formatting.c:2245 -#: utils/adt/formatting.c:2375 +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 +#: utils/adt/formatting.c:2387 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "неверное значение \"%s\" Ð´Ð»Ñ \"%s\"" -#: utils/adt/formatting.c:2234 +#: utils/adt/formatting.c:2246 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "Поле должно поглотить Ñимволов: %d, но удалоÑÑŒ разобрать только %d." -#: utils/adt/formatting.c:2247 +#: utils/adt/formatting.c:2259 #, c-format msgid "Value must be an integer." msgstr "Значение должно быть целым чиÑлом." -#: utils/adt/formatting.c:2252 +#: utils/adt/formatting.c:2264 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "значение \"%s\" во входной Ñтроке вне диапазона" -#: utils/adt/formatting.c:2254 +#: utils/adt/formatting.c:2266 #, c-format msgid "Value must be in the range %d to %d." msgstr "Значение должно быть в интервале %d..%d." -#: utils/adt/formatting.c:2377 +#: utils/adt/formatting.c:2389 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "" "Данное значение не ÑоответÑтвует ни одному из допуÑтимых значений Ð´Ð»Ñ Ñтого " "полÑ." -#: utils/adt/formatting.c:2562 utils/adt/formatting.c:2582 -#: utils/adt/formatting.c:2602 utils/adt/formatting.c:2622 -#: utils/adt/formatting.c:2641 utils/adt/formatting.c:2660 -#: utils/adt/formatting.c:2684 utils/adt/formatting.c:2702 -#: utils/adt/formatting.c:2720 utils/adt/formatting.c:2738 -#: utils/adt/formatting.c:2755 utils/adt/formatting.c:2772 +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 +#: utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 +#: utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 +#: utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 +#: utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 +#: utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 #, c-format msgid "localized string format value too long" msgstr "Ñлишком длинное значение формата локализованной Ñтроки" -#: utils/adt/formatting.c:3059 +#: utils/adt/formatting.c:3084 #, c-format msgid "formatting field \"%s\" is only supported in to_char" msgstr "поле Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s\" поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в функции to_char" -#: utils/adt/formatting.c:3170 +#: utils/adt/formatting.c:3209 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "ошибка ÑинтакÑиÑа в значении Ð´Ð»Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð° \"Y,YYY\"" -#: utils/adt/formatting.c:3676 +#: utils/adt/formatting.c:3724 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "Ñ‡Ð°Ñ \"%d\" не ÑоответÑтвует 12-чаÑовому формату времени" -#: utils/adt/formatting.c:3678 +#: utils/adt/formatting.c:3726 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "ИÑпользуйте 24-чаÑовой формат или передавайте чаÑÑ‹ от 1 до 12." -#: utils/adt/formatting.c:3784 +#: utils/adt/formatting.c:3832 #, c-format msgid "cannot calculate day of year without year information" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ñ€Ð°ÑÑчитать день года без информации о годе" -#: utils/adt/formatting.c:4651 +#: utils/adt/formatting.c:4737 #, c-format msgid "\"EEEE\" not supported for input" msgstr "\"EEEE\" не поддерживаетÑÑ Ð¿Ñ€Ð¸ вводе" -#: utils/adt/formatting.c:4663 +#: utils/adt/formatting.c:4749 #, c-format msgid "\"RN\" not supported for input" msgstr "\"RN\" не поддерживаетÑÑ Ð¿Ñ€Ð¸ вводе" -#: utils/adt/genfile.c:63 +#: utils/adt/genfile.c:79 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "ÑÑылка на родительÑкий каталог (\"..\") недопуÑтима" -#: utils/adt/genfile.c:74 +#: utils/adt/genfile.c:90 #, c-format msgid "absolute path not allowed" msgstr "абÑолютный путь недопуÑтим" -#: utils/adt/genfile.c:79 +#: utils/adt/genfile.c:95 #, c-format msgid "path must be in or below the current directory" msgstr "путь должен указывать в текущий или вложенный каталог" -#: utils/adt/genfile.c:126 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° Ñлишком велика" -#: utils/adt/genfile.c:143 +#: utils/adt/genfile.c:159 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð² файле \"%s\": %m" -#: utils/adt/genfile.c:201 utils/adt/genfile.c:242 -#, c-format -msgid "must be superuser to read files" -msgstr "читать файлы может только Ñуперпользователь" - -#: utils/adt/genfile.c:319 +#: utils/adt/genfile.c:219 #, c-format -msgid "must be superuser to get file information" -msgstr "получать информацию о файлах может только Ñуперпользователь" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "читать файлы, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ adminpack 1.0, может только Ñуперпользователь" -#: utils/adt/genfile.c:405 +#: utils/adt/genfile.c:220 #, c-format -msgid "must be superuser to get directory listings" -msgstr "читать Ñодержимое каталогов может только Ñуперпользователь" +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "" +"РаÑÑмотрите возможноÑть иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ pg_file_read(), включённой в " +"Ñдро." -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:939 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "неверное определение линии: A и B вдвоём не могут быть нулевыми" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:947 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "неверное определение линии: требуютÑÑ Ð´Ð²Ðµ различных точки" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3440 utils/adt/geo_ops.c:4253 -#: utils/adt/geo_ops.c:5181 +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 +#: utils/adt/geo_ops.c:5180 #, c-format msgid "too many points requested" msgstr "запрошено Ñлишком много точек" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1403 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "недопуÑтимое чиÑло точек во внешнем предÑтавлении типа \"path\"" -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2554 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"dist_lb\" не реализована" -#: utils/adt/geo_ops.c:3015 +#: utils/adt/geo_ops.c:3014 #, c-format msgid "function \"close_sl\" not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"close_sl\" не реализована" -#: utils/adt/geo_ops.c:3117 +#: utils/adt/geo_ops.c:3116 #, c-format msgid "function \"close_lb\" not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"close_lb\" не реализована" -#: utils/adt/geo_ops.c:3406 +#: utils/adt/geo_ops.c:3405 #, c-format msgid "cannot create bounding box for empty polygon" msgstr "поÑтроить окружающий прÑмоугольник Ð´Ð»Ñ Ð¿ÑƒÑтого многоугольника нельзÑ" -#: utils/adt/geo_ops.c:3487 +#: utils/adt/geo_ops.c:3486 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "недопуÑтимое чиÑло точек во внешнем предÑтавлении типа \"polygon\"" -#: utils/adt/geo_ops.c:4012 +#: utils/adt/geo_ops.c:4011 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"poly_distance\" не реализована" -#: utils/adt/geo_ops.c:4365 +#: utils/adt/geo_ops.c:4364 #, c-format msgid "function \"path_center\" not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"path_center\" не реализована" -#: utils/adt/geo_ops.c:4382 +#: utils/adt/geo_ops.c:4381 #, c-format msgid "open path cannot be converted to polygon" msgstr "открытый путь Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ во многоугольник" -#: utils/adt/geo_ops.c:4631 +#: utils/adt/geo_ops.c:4630 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "недопуÑтимый Ñ€Ð°Ð´Ð¸ÑƒÑ Ð²Ð¾ внешнем предÑтавлении типа \"circle\"" -#: utils/adt/geo_ops.c:5167 +#: utils/adt/geo_ops.c:5166 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "круг Ñ Ð½ÑƒÐ»ÐµÐ²Ñ‹Ð¼ радиуÑом Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ в многоугольник" -#: utils/adt/geo_ops.c:5172 +#: utils/adt/geo_ops.c:5171 #, c-format msgid "must request at least 2 points" msgstr "точек должно быть минимум 2" -#: utils/adt/geo_ops.c:5216 +#: utils/adt/geo_ops.c:5215 #, c-format msgid "cannot convert empty polygon to circle" msgstr "пуÑтой многоугольник Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ в круг" -#: utils/adt/int.c:162 +#: utils/adt/int.c:160 #, c-format msgid "int2vector has too many elements" msgstr "int2vector Ñодержит Ñлишком много Ñлементов" -#: utils/adt/int.c:237 +#: utils/adt/int.c:235 #, c-format msgid "invalid int2vector data" msgstr "неверные данные int2vector" -#: utils/adt/int.c:243 utils/adt/oid.c:215 utils/adt/oid.c:296 +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "oidvector Ñодержит Ñлишком много Ñлементов" -#: utils/adt/int.c:1347 utils/adt/int8.c:1460 utils/adt/numeric.c:1401 -#: utils/adt/timestamp.c:5148 utils/adt/timestamp.c:5229 +#: utils/adt/int.c:1379 utils/adt/int8.c:1325 utils/adt/numeric.c:1412 +#: utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5402 #, c-format msgid "step size cannot equal zero" msgstr "размер шага не может быть нулевым" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:105 -#, c-format -msgid "invalid input syntax for %s: \"%s\"" -msgstr "неверный ÑинтакÑÐ¸Ñ Ð´Ð»Ñ %s: \"%s\"" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:3005 +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 +#: utils/adt/numutils.c:105 +#, c-format +msgid "invalid input syntax for integer: \"%s\"" +msgstr "неверное значение Ð´Ð»Ñ Ñ†ÐµÐ»Ð¾Ð³Ð¾ чиÑла: \"%s\"" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 +#: utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 +#: utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 +#: utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 +#: utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 +#: utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 +#: utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 +#: utils/adt/int8.c:1227 utils/adt/int8.c:1269 utils/adt/numeric.c:3169 #: utils/adt/varbit.c:1655 #, c-format msgid "bigint out of range" msgstr "bigint вне диапазона" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1282 #, c-format msgid "OID out of range" msgstr "OID вне диапазона" -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "Символ Ñ ÐºÐ¾Ð´Ð¾Ð¼ 0x%02x необходимо Ñкранировать." -#: utils/adt/json.c:827 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "За \"\\u\" должны Ñледовать четыре шеÑтнадцатеричные цифры." -#: utils/adt/json.c:843 +#: utils/adt/json.c:844 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "" "Старшее Ñлово Ñуррогата Unicode не может Ñледовать за другим Ñтаршим Ñловом." -#: utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:916 -#: utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Младшее Ñлово Ñуррогата Unicode должно Ñледовать за Ñтаршим Ñловом." -#: utils/adt/json.c:879 utils/adt/json.c:902 +#: utils/adt/json.c:880 utils/adt/json.c:903 #, c-format msgid "unsupported Unicode escape sequence" msgstr "Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ ÑпецпоÑледовательноÑть Unicode" -#: utils/adt/json.c:880 +#: utils/adt/json.c:881 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000 Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ в текÑÑ‚." -#: utils/adt/json.c:903 +#: utils/adt/json.c:904 #, c-format msgid "" "Unicode escape values cannot be used for code point values above 007F when " @@ -21995,93 +23332,88 @@ msgstr "" "Спецкоды Unicode Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ выше 007F можно иÑпользовать только Ñ " "Ñерверной кодировкой UTF8." -#: utils/adt/json.c:948 utils/adt/json.c:966 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑпецпоÑледовательноÑть: \"\\%s\"." -#: utils/adt/json.c:1135 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "Ðеожиданный конец входной Ñтроки." -#: utils/adt/json.c:1149 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "ОжидалÑÑ ÐºÐ¾Ð½ÐµÑ† текÑта, но обнаружено продолжение \"%s\"." -#: utils/adt/json.c:1160 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "ОжидалоÑÑŒ значение JSON, но обнаружено \"%s\"." -#: utils/adt/json.c:1168 utils/adt/json.c:1216 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "ОжидалаÑÑŒ Ñтрока, но обнаружено \"%s\"." -#: utils/adt/json.c:1176 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "ОжидалÑÑ Ñлемент маÑÑива или \"]\", но обнаружено \"%s\"." -#: utils/adt/json.c:1184 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "ОжидалаÑÑŒ \",\" или \"]\", но обнаружено \"%s\"." -#: utils/adt/json.c:1192 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "ОжидалаÑÑŒ Ñтрока или \"}\", но обнаружено \"%s\"." -#: utils/adt/json.c:1200 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "ОжидалоÑÑŒ \":\", но обнаружено \"%s\"." -#: utils/adt/json.c:1208 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "ОжидалаÑÑŒ \",\" или \"}\", но обнаружено \"%s\"." -#: utils/adt/json.c:1246 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "Ошибочный Ñлемент текÑта \"%s\"." -#: utils/adt/json.c:1318 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "данные JSON, Ñтрока %d: %s%s%s" -#: utils/adt/json.c:1474 utils/adt/jsonb.c:725 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "" "значением ключа должен быть ÑкалÑÑ€ (не маÑÑив, композитный тип или json)" -#: utils/adt/json.c:2011 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 #, c-format -msgid "could not determine data type for argument 1" -msgstr "не удалоÑÑŒ определить тип данных аргумента 1" - -#: utils/adt/json.c:2021 -#, c-format -msgid "could not determine data type for argument 2" -msgstr "не удалоÑÑŒ определить тип данных аргумента 2" +msgid "could not determine data type for argument %d" +msgstr "не удалоÑÑŒ определить тип данных аргумента %d" -#: utils/adt/json.c:2045 utils/adt/jsonb.c:1782 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 #, c-format msgid "field name must not be null" msgstr "Ð¸Ð¼Ñ Ð¿Ð¾Ð»Ñ Ð½Ðµ может быть NULL" -#: utils/adt/json.c:2122 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 #, c-format msgid "argument list must have even number of elements" msgstr "в ÑпиÑке аргументов должно быть чётное чиÑло Ñлементов" -#: utils/adt/json.c:2123 +#: utils/adt/json.c:2195 #, c-format msgid "" "The arguments of json_build_object() must consist of alternating keys and " @@ -22089,70 +23421,98 @@ msgid "" msgstr "" "Ðргументы json_build_object() должны ÑоÑтоÑть из пар ключей и значений." -#: utils/adt/json.c:2147 utils/adt/json.c:2168 utils/adt/json.c:2227 -#, c-format -msgid "could not determine data type for argument %d" -msgstr "не удалоÑÑŒ определить тип данных аргумента %d" - -#: utils/adt/json.c:2153 +#: utils/adt/json.c:2210 #, c-format msgid "argument %d cannot be null" msgstr "аргумент %d не может быть NULL" -#: utils/adt/json.c:2154 +#: utils/adt/json.c:2211 #, c-format msgid "Object keys should be text." msgstr "Ключи объектов должны быть текÑтовыми." -#: utils/adt/json.c:2289 utils/adt/jsonb.c:1364 +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 #, c-format msgid "array must have two columns" msgstr "маÑÑив должен иметь два Ñтолбца" -#: utils/adt/json.c:2313 utils/adt/json.c:2397 utils/adt/jsonb.c:1388 -#: utils/adt/jsonb.c:1483 +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 +#: utils/adt/jsonb.c:1395 #, c-format msgid "null value not allowed for object key" msgstr "значение null не может быть ключом объекта" -#: utils/adt/json.c:2386 utils/adt/jsonb.c:1472 +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 #, c-format msgid "mismatched array dimensions" msgstr "неподходÑщие размерноÑти маÑÑива" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:258 #, c-format msgid "string too long to represent as jsonb string" msgstr "Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñтрока Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² виде Ñтроки jsonb" -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:259 #, c-format msgid "" "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "" "Из-за ограничений реализации Ñтроки jsonb не могут быть длиннее %d байт." -#: utils/adt/jsonb.c:1183 +#: utils/adt/jsonb.c:1147 #, c-format -msgid "invalid number of arguments: object must be matched key value pairs" +msgid "" +"The arguments of jsonb_build_object() must consist of alternating keys and " +"values." msgstr "" -"неверное чиÑло аргументов: объект должен ÑоÑтавлÑтьÑÑ Ð¸Ð· пар ключ-значение" +"Ðргументы json_build_object() должны ÑоÑтоÑть из перемежающихÑÑ ÐºÐ»ÑŽÑ‡ÐµÐ¹ и " +"значений." -#: utils/adt/jsonb.c:1196 +#: utils/adt/jsonb.c:1159 #, c-format msgid "argument %d: key must not be null" msgstr "аргумент %d: ключ не может быть NULL" -#: utils/adt/jsonb.c:1215 utils/adt/jsonb.c:1238 utils/adt/jsonb.c:1298 -#, c-format -msgid "argument %d: could not determine data type" -msgstr "аргумент %d: не удалоÑÑŒ определить тип данных" - -#: utils/adt/jsonb.c:1835 +#: utils/adt/jsonb.c:1747 #, c-format msgid "object keys must be strings" msgstr "ключи объектов должны быть Ñтроковыми" +#: utils/adt/jsonb.c:1910 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "привеÑти значение jsonb null к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1911 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "привеÑти Ñтроку jsonb к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1912 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "привеÑти чиÑловое значение jsonb к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1913 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "привеÑти логичеÑкое значение jsonb к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1914 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "привеÑти маÑÑив jsonb к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1915 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "привеÑти объект jsonb к типу %s нельзÑ" + +#: utils/adt/jsonb.c:1916 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "привеÑти маÑÑив или объект jsonb к типу %s нельзÑ" + #: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" @@ -22163,84 +23523,110 @@ msgstr "чиÑло пар объекта jsonb превышает предел ( msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "чиÑло Ñлементов маÑÑива jsonb превышает предел (%zu)" -#: utils/adt/jsonb_util.c:1526 utils/adt/jsonb_util.c:1546 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "общий размер Ñлементов маÑÑива jsonb превышает предел (%u байт)" -#: utils/adt/jsonb_util.c:1607 utils/adt/jsonb_util.c:1642 -#: utils/adt/jsonb_util.c:1662 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "общий размер Ñлементов объекта jsonb превышает предел (%u байт)" -#: utils/adt/jsonfuncs.c:337 utils/adt/jsonfuncs.c:502 -#: utils/adt/jsonfuncs.c:2089 utils/adt/jsonfuncs.c:2530 -#: utils/adt/jsonfuncs.c:3036 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 #, c-format msgid "cannot call %s on a scalar" msgstr "вызывать %s Ñо ÑкалÑром нельзÑ" -#: utils/adt/jsonfuncs.c:342 utils/adt/jsonfuncs.c:489 -#: utils/adt/jsonfuncs.c:2519 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "вызывать %s Ñ Ð¼Ð°ÑÑивом нельзÑ" -#: utils/adt/jsonfuncs.c:1405 utils/adt/jsonfuncs.c:1440 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "получить длину ÑкалÑра нельзÑ" -#: utils/adt/jsonfuncs.c:1409 utils/adt/jsonfuncs.c:1428 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "получить длину маÑÑива Ð´Ð»Ñ Ð½Ðµ маÑÑива нельзÑ" -#: utils/adt/jsonfuncs.c:1505 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "вызывать %s Ñ Ð½Ðµ объектом нельзÑ" -#: utils/adt/jsonfuncs.c:1523 utils/adt/jsonfuncs.c:2202 -#: utils/adt/jsonfuncs.c:2739 +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 #, c-format msgid "" "function returning record called in context that cannot accept type record" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ, вызвана в контекÑте, не допуÑкающем Ñтот тип" -#: utils/adt/jsonfuncs.c:1762 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "извлечь маÑÑив в виде объекта нельзÑ" -#: utils/adt/jsonfuncs.c:1774 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "извлечь ÑкалÑÑ€ нельзÑ" -#: utils/adt/jsonfuncs.c:1820 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "извлечь Ñлементы из ÑкалÑра нельзÑ" -#: utils/adt/jsonfuncs.c:1824 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "извлечь Ñлементы из объекта нельзÑ" -#: utils/adt/jsonfuncs.c:2076 utils/adt/jsonfuncs.c:2835 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format msgid "cannot call %s on a non-array" msgstr "вызывать %s Ñ Ð½Ðµ маÑÑивом нельзÑ" -#: utils/adt/jsonfuncs.c:2163 utils/adt/jsonfuncs.c:2715 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, c-format +msgid "expected JSON array" +msgstr "ожидалÑÑ Ð¼Ð°ÑÑив JSON" + +#: utils/adt/jsonfuncs.c:2334 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Проверьте значение ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2356 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Проверьте Ñлемент маÑÑива %s ключа \"%s\"." + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "Проверьте Ñлемент маÑÑива %s." + +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "неправильный маÑÑив JSON" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "первым аргументом %s должен быть кортеж" -#: utils/adt/jsonfuncs.c:2204 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format msgid "" "Try calling the function in the FROM clause using a column definition list." @@ -22248,69 +23634,92 @@ msgstr "" "Попробуйте вызвать Ñту функцию в предложении FROM, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÑпиÑок Ñ " "определениÑми Ñтолбцов." -#: utils/adt/jsonfuncs.c:2851 utils/adt/jsonfuncs.c:3018 +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 #, c-format msgid "argument of %s must be an array of objects" msgstr "аргументом %s должен быть маÑÑив объектов" -#: utils/adt/jsonfuncs.c:2875 +#: utils/adt/jsonfuncs.c:3764 #, c-format msgid "cannot call %s on an object" msgstr "вызывать %s Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð¼ нельзÑ" -#: utils/adt/jsonfuncs.c:3442 utils/adt/jsonfuncs.c:3501 -#: utils/adt/jsonfuncs.c:3581 +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 #, c-format msgid "cannot delete from scalar" msgstr "удаление из ÑкалÑра невозможно" -#: utils/adt/jsonfuncs.c:3586 +#: utils/adt/jsonfuncs.c:4385 #, c-format msgid "cannot delete from object using integer index" msgstr "удаление из объекта по чиÑловому индекÑу невозможно" -#: utils/adt/jsonfuncs.c:3652 utils/adt/jsonfuncs.c:3744 +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 #, c-format msgid "cannot set path in scalar" msgstr "задать путь в ÑкалÑре нельзÑ" -#: utils/adt/jsonfuncs.c:3697 +#: utils/adt/jsonfuncs.c:4496 #, c-format msgid "cannot delete path in scalar" msgstr "удалить путь в ÑкалÑре нельзÑ" -#: utils/adt/jsonfuncs.c:3867 +#: utils/adt/jsonfuncs.c:4666 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½ÐºÐ°Ñ‚ÐµÐ½Ð°Ñ†Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð² jsonb" -#: utils/adt/jsonfuncs.c:3901 +#: utils/adt/jsonfuncs.c:4700 #, c-format msgid "path element at position %d is null" msgstr "Ñлемент пути в позиции %d равен NULL" -#: utils/adt/jsonfuncs.c:3987 +#: utils/adt/jsonfuncs.c:4786 #, c-format msgid "cannot replace existing key" msgstr "заменить ÑущеÑтвующий ключ нельзÑ" -#: utils/adt/jsonfuncs.c:3988 +#: utils/adt/jsonfuncs.c:4787 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "Попробуйте применить функцию jsonb_set Ð´Ð»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ‹ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡Ð°." -#: utils/adt/jsonfuncs.c:4070 +#: utils/adt/jsonfuncs.c:4869 #, c-format msgid "path element at position %d is not an integer: \"%s\"" msgstr "Ñлемент пути в позиции %d - не целочиÑленный: \"%s\"" +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "неверный тип флага, допуÑкаютÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ маÑÑивы и ÑкалÑры" + +#: utils/adt/jsonfuncs.c:4995 +#, c-format +msgid "flag array element is not a string" +msgstr "Ñлемент маÑÑива флагов не ÑвлÑетÑÑ Ñтрокой" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "" +"Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and " +"\"all\"" +msgstr "" +"ДопуÑтимые значениÑ: \"string\", \"numeric\", \"boolean\", \"key\" и \"all\"" + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "неверный флаг в маÑÑиве флагов: \"%s\"" + # well-spelled: Ñимв #: utils/adt/levenshtein.c:133 #, c-format msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "длина аргумента levenshtein() превышает макÑимум (%d Ñимв.)" -#: utils/adt/like.c:183 utils/adt/selfuncs.c:5505 +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5811 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "не удалоÑÑŒ определить, какой порÑдок Ñортировки иÑпользовать Ð´Ð»Ñ ILIKE" @@ -22320,17 +23729,17 @@ msgstr "не удалоÑÑŒ определить, какой порÑдок Ñо msgid "LIKE pattern must not end with escape character" msgstr "шаблон LIKE не должен заканчиватьÑÑ Ð·Ð°Ñ‰Ð¸Ñ‚Ð½Ñ‹Ð¼ Ñимволом" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "неверный защитный Ñимвол" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "Защитный Ñимвол должен быть пуÑтым или ÑоÑтоÑть из одного байта." -#: utils/adt/lockfuncs.c:545 +#: utils/adt/lockfuncs.c:664 #, c-format msgid "cannot use advisory locks during a parallel operation" msgstr "" @@ -22342,32 +23751,32 @@ msgstr "" msgid "invalid octet value in \"macaddr\" value: \"%s\"" msgstr "неверный октет в значении типа macaddr: \"%s\"" -#: utils/adt/mac8.c:554 +#: utils/adt/mac8.c:563 #, c-format msgid "macaddr8 data out of range to convert to macaddr" msgstr "значение в macaddr8 не допуÑкает преобразование в macaddr" -#: utils/adt/mac8.c:555 +#: utils/adt/mac8.c:564 #, c-format msgid "" -"Only addresses that have FF and FE as values in the 4th and 5th bytes, from " -"the left, for example: XX-XX-XX-FF-FE-XX-XX-XX, are eligible to be converted " +"Only addresses that have FF and FE as values in the 4th and 5th bytes from " +"the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted " "from macaddr8 to macaddr." msgstr "" "Преобразование из macaddr8 в macaddr возможно только Ð´Ð»Ñ Ð°Ð´Ñ€ÐµÑов, Ñодержащих " -"FF и FE в 4-ом и 5-ом байтах Ñлева, например: XX-XX-XX-FF-FE-XX-XX-XX." +"FF и FE в 4-ом и 5-ом байтах Ñлева, например xx:xx:xx:ff:fe:xx:xx:xx." -#: utils/adt/misc.c:238 +#: utils/adt/misc.c:239 #, c-format msgid "PID %d is not a PostgreSQL server process" msgstr "PID %d не отноÑитÑÑ Ðº Ñерверному процеÑÑу PostgreSQL" -#: utils/adt/misc.c:289 +#: utils/adt/misc.c:290 #, c-format msgid "must be a superuser to cancel superuser query" msgstr "Ð´Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹ запроÑа ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½ÑƒÐ¶Ð½Ð¾ быть Ñуперпользователем" -#: utils/adt/misc.c:294 +#: utils/adt/misc.c:295 #, c-format msgid "" "must be a member of the role whose query is being canceled or member of " @@ -22376,12 +23785,12 @@ msgstr "" "необходимо быть членом роли, Ð·Ð°Ð¿Ñ€Ð¾Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ отменÑетÑÑ, или роли " "pg_signal_backend" -#: utils/adt/misc.c:313 +#: utils/adt/misc.c:314 #, c-format msgid "must be a superuser to terminate superuser process" msgstr "прерывать процеÑÑ ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ‚ только Ñуперпользователь" -#: utils/adt/misc.c:318 +#: utils/adt/misc.c:319 #, c-format msgid "" "must be a member of the role whose process is being terminated or member of " @@ -22390,94 +23799,108 @@ msgstr "" "необходимо быть членом роли, процеÑÑ ÐºÐ¾Ñ‚Ð¾Ñ€Ð¾Ð¹ прерываетÑÑ, или роли " "pg_signal_backend" -#: utils/adt/misc.c:335 +#: utils/adt/misc.c:336 #, c-format msgid "failed to send signal to postmaster: %m" msgstr "отправить Ñигнал процеÑÑу postmaster не удалоÑÑŒ: %m" #: utils/adt/misc.c:355 #, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "" +"прокручивать файлы протоколов, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ adminpack 1.0, может только " +"Ñуперпользователь" + +#: utils/adt/misc.c:356 +#, c-format +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "" +"РаÑÑмотрите возможноÑть иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ pg_logfile_rotate(), " +"включённой в Ñдро." + +#: utils/adt/misc.c:361 utils/adt/misc.c:381 +#, c-format msgid "rotation not possible because log collection not active" msgstr "прокрутка невозможна, так как протоколирование отключено" -#: utils/adt/misc.c:392 +#: utils/adt/misc.c:418 #, c-format msgid "global tablespace never has databases" msgstr "в табличном проÑтранÑтве global никогда не было баз данных" -#: utils/adt/misc.c:413 +#: utils/adt/misc.c:439 #, c-format msgid "%u is not a tablespace OID" msgstr "%u - Ñто не OID табличного проÑтранÑтва" -#: utils/adt/misc.c:606 +#: utils/adt/misc.c:626 msgid "unreserved" msgstr "не зарезервировано" -#: utils/adt/misc.c:610 +#: utils/adt/misc.c:630 msgid "unreserved (cannot be function or type name)" msgstr "не зарезервировано (но не может быть именем типа или функции)" -#: utils/adt/misc.c:614 +#: utils/adt/misc.c:634 msgid "reserved (can be function or type name)" msgstr "зарезервировано (но может быть именем типа или функции)" -#: utils/adt/misc.c:618 +#: utils/adt/misc.c:638 msgid "reserved" msgstr "зарезервировано" -#: utils/adt/misc.c:792 utils/adt/misc.c:806 utils/adt/misc.c:845 -#: utils/adt/misc.c:851 utils/adt/misc.c:857 utils/adt/misc.c:880 +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 +#: utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 #, c-format msgid "string is not a valid identifier: \"%s\"" msgstr "Ñтрока не ÑвлÑетÑÑ Ð´Ð¾Ð¿ÑƒÑтимым идентификатором: \"%s\"" -#: utils/adt/misc.c:794 +#: utils/adt/misc.c:814 #, c-format msgid "String has unclosed double quotes." msgstr "Ð’ Ñтроке не закрыты кавычки." -#: utils/adt/misc.c:808 +#: utils/adt/misc.c:828 #, c-format msgid "Quoted identifier must not be empty." msgstr "Идентификатор в кавычках не может быть пуÑтым." -#: utils/adt/misc.c:847 +#: utils/adt/misc.c:867 #, c-format msgid "No valid identifier before \".\"." msgstr "Перед \".\" нет допуÑтимого идентификатора." -#: utils/adt/misc.c:853 +#: utils/adt/misc.c:873 #, c-format msgid "No valid identifier after \".\"." msgstr "ПоÑле \".\" нет допуÑтимого идентификатора." -#: utils/adt/misc.c:914 +#: utils/adt/misc.c:934 #, c-format msgid "log format \"%s\" is not supported" msgstr "формат журнала \"%s\" не поддерживаетÑÑ" -#: utils/adt/misc.c:915 +#: utils/adt/misc.c:935 #, c-format msgid "The supported log formats are \"stderr\" and \"csvlog\"." msgstr "ПоддерживаютÑÑ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ñ‹ журналов \"stderr\" и \"csvlog\"." -#: utils/adt/nabstime.c:137 +#: utils/adt/nabstime.c:140 #, c-format msgid "invalid time zone name: \"%s\"" msgstr "неверное название чаÑового поÑÑа: \"%s\"" -#: utils/adt/nabstime.c:482 utils/adt/nabstime.c:555 +#: utils/adt/nabstime.c:485 utils/adt/nabstime.c:558 #, c-format msgid "cannot convert abstime \"invalid\" to timestamp" msgstr "преобразовать значение \"invalid\" типа abstime в timestamp нельзÑ" -#: utils/adt/nabstime.c:782 +#: utils/adt/nabstime.c:785 #, c-format msgid "invalid status in external \"tinterval\" value" msgstr "неверное ÑоÑтоÑние во внешнем предÑтавлении \"tinterval\"" -#: utils/adt/nabstime.c:852 +#: utils/adt/nabstime.c:855 #, c-format msgid "cannot convert reltime \"invalid\" to interval" msgstr "преобразовать значение \"invalid\" типа reltime в interval нельзÑ" @@ -22492,8 +23915,8 @@ msgstr "неверное значение cidr: \"%s\"" msgid "Value has bits set to right of mask." msgstr "Значение Ñодержит уÑтановленные биты правее маÑки." -#: utils/adt/network.c:111 utils/adt/network.c:582 utils/adt/network.c:607 -#: utils/adt/network.c:632 +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 +#: utils/adt/network.c:642 #, c-format msgid "could not format inet value: %m" msgstr "не удалоÑÑŒ отформатировать значение inet: %m" @@ -22526,109 +23949,114 @@ msgstr "неверное внешнее предÑтавление \"cidr\"" msgid "invalid mask length: %d" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° маÑки: %d" -#: utils/adt/network.c:650 +#: utils/adt/network.c:660 #, c-format msgid "could not format cidr value: %m" msgstr "не удалоÑÑŒ отформатировать значение cidr: %m" -#: utils/adt/network.c:883 +#: utils/adt/network.c:893 #, c-format msgid "cannot merge addresses from different families" msgstr "объединÑть адреÑа разных ÑемейÑтв нельзÑ" -#: utils/adt/network.c:1302 +#: utils/adt/network.c:1309 #, c-format msgid "cannot AND inet values of different sizes" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"И\" (AND) Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ inet разного размера" -#: utils/adt/network.c:1334 +#: utils/adt/network.c:1341 #, c-format msgid "cannot OR inet values of different sizes" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать \"ИЛИ\" (OR) Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ inet разного размера" -#: utils/adt/network.c:1395 utils/adt/network.c:1471 +#: utils/adt/network.c:1402 utils/adt/network.c:1478 #, c-format msgid "result is out of range" msgstr "результат вне диапазона" -#: utils/adt/network.c:1436 +#: utils/adt/network.c:1443 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ñ‡Ð¸Ñ‚Ð°Ñ‚ÑŒ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ inet разного размера" -#: utils/adt/numeric.c:819 +#: utils/adt/numeric.c:830 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "неверный знак во внешнем значении \"numeric\"" -#: utils/adt/numeric.c:825 +#: utils/adt/numeric.c:836 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "неверный порÑдок чиÑла во внешнем значении \"numeric\"" -#: utils/adt/numeric.c:834 +#: utils/adt/numeric.c:845 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð° во внешнем значении \"numeric\"" -#: utils/adt/numeric.c:1024 utils/adt/numeric.c:1038 +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "точноÑть NUMERIC %d должна быть между 1 и %d" -#: utils/adt/numeric.c:1029 +#: utils/adt/numeric.c:1040 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "порÑдок NUMERIC %d должен быть между 0 и точноÑтью (%d)" -#: utils/adt/numeric.c:1047 +#: utils/adt/numeric.c:1058 #, c-format msgid "invalid NUMERIC type modifier" msgstr "неверный модификатор типа NUMERIC" -#: utils/adt/numeric.c:1379 +#: utils/adt/numeric.c:1390 #, c-format msgid "start value cannot be NaN" msgstr "начальное значение не может быть NaN" -#: utils/adt/numeric.c:1384 +#: utils/adt/numeric.c:1395 #, c-format msgid "stop value cannot be NaN" msgstr "конечное значение не может быть NaN" -#: utils/adt/numeric.c:1394 +#: utils/adt/numeric.c:1405 #, c-format msgid "step size cannot be NaN" msgstr "размер шага не может быть NaN" -#: utils/adt/numeric.c:2589 utils/adt/numeric.c:5551 utils/adt/numeric.c:5996 -#: utils/adt/numeric.c:7700 utils/adt/numeric.c:8125 utils/adt/numeric.c:8240 -#: utils/adt/numeric.c:8313 +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 +#: utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 +#: utils/adt/numeric.c:8490 #, c-format msgid "value overflows numeric format" msgstr "значение переполнÑет формат numeric" -#: utils/adt/numeric.c:2931 +#: utils/adt/numeric.c:3095 #, c-format msgid "cannot convert NaN to integer" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ NaN в integer" -#: utils/adt/numeric.c:2997 +#: utils/adt/numeric.c:3161 #, c-format msgid "cannot convert NaN to bigint" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ NaN в bigint" -#: utils/adt/numeric.c:3042 +#: utils/adt/numeric.c:3206 #, c-format msgid "cannot convert NaN to smallint" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ NaN в smallint" -#: utils/adt/numeric.c:6066 +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ´Ñтавить беÑконечноÑть в numeric" + +#: utils/adt/numeric.c:6240 #, c-format msgid "numeric field overflow" msgstr "переполнение Ð¿Ð¾Ð»Ñ numeric" -#: utils/adt/numeric.c:6067 +#: utils/adt/numeric.c:6241 #, c-format msgid "" "A field with precision %d, scale %d must round to an absolute value less " @@ -22647,50 +24075,50 @@ msgstr "значение \"%s\" вне диапазона Ð´Ð»Ñ 8-битово msgid "invalid oidvector data" msgstr "неверные данные oidvector" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "запрошенный Ñимвол больше допуÑтимого" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "код запрошенного Ñимвола Ñлишком велик Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸: %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "запрошенный Ñимвол не подходит Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸: %d" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "Ñимвол не может быть null" -#: utils/adt/orderedsetaggs.c:426 utils/adt/orderedsetaggs.c:531 -#: utils/adt/orderedsetaggs.c:670 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "значение Ð¿ÐµÑ€Ñ†ÐµÐ½Ñ‚Ð¸Ð»Ñ %g лежит не в диапазоне 0..1" -#: utils/adt/pg_locale.c:1034 +#: utils/adt/pg_locale.c:1093 #, c-format msgid "Apply system library package updates." msgstr "Обновите пакет Ñ ÑиÑтемной библиотекой." -#: utils/adt/pg_locale.c:1239 +#: utils/adt/pg_locale.c:1308 #, c-format msgid "could not create locale \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать локаль \"%s\": %m" -#: utils/adt/pg_locale.c:1242 +#: utils/adt/pg_locale.c:1311 #, c-format msgid "" -"The operating system could not find any locale data for the locale name \"%s" -"\"." +"The operating system could not find any locale data for the locale name \"" +"%s\"." msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема не может найти данные локали Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"." -#: utils/adt/pg_locale.c:1339 +#: utils/adt/pg_locale.c:1412 #, c-format msgid "" "collations with different collate and ctype values are not supported on this " @@ -22699,37 +24127,44 @@ msgstr "" "правила Ñортировки Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ значениÑми collate и ctype не поддерживаютÑÑ Ð½Ð° " "Ñтой платформе" -#: utils/adt/pg_locale.c:1348 +#: utils/adt/pg_locale.c:1421 #, c-format msgid "collation provider LIBC is not supported on this platform" msgstr "поÑтавщик правил Ñортировки LIBC не поддерживаетÑÑ Ð½Ð° Ñтой платформе" -#: utils/adt/pg_locale.c:1361 utils/adt/pg_locale.c:1439 +#: utils/adt/pg_locale.c:1433 +#, c-format +msgid "" +"collations with different collate and ctype values are not supported by ICU" +msgstr "" +"ICU не поддерживает правила Ñортировки Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ значениÑми collate и ctype" + +#: utils/adt/pg_locale.c:1439 utils/adt/pg_locale.c:1527 #, c-format msgid "could not open collator for locale \"%s\": %s" msgstr "не удалоÑÑŒ открыть Ñортировщик Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\": %s" -#: utils/adt/pg_locale.c:1370 +#: utils/adt/pg_locale.c:1450 #, c-format msgid "ICU is not supported in this build" msgstr "ICU не поддерживаетÑÑ Ð² данной Ñборке" -#: utils/adt/pg_locale.c:1371 +#: utils/adt/pg_locale.c:1451 #, c-format msgid "You need to rebuild PostgreSQL using --with-icu." msgstr "Ðеобходимо перекомпилировать PostgreSQL Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ --with-icu." -#: utils/adt/pg_locale.c:1388 +#: utils/adt/pg_locale.c:1471 #, c-format msgid "collation \"%s\" has no actual version, but a version was specified" msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð° Ñортировки \"%s\", лишённого верÑии, была задана верÑиÑ" -#: utils/adt/pg_locale.c:1394 +#: utils/adt/pg_locale.c:1478 #, c-format msgid "collation \"%s\" has version mismatch" msgstr "неÑовпадение верÑии Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»Ð° Ñортировки \"%s\"" -#: utils/adt/pg_locale.c:1396 +#: utils/adt/pg_locale.c:1480 #, c-format msgid "" "The collation in the database was created using version %s, but the " @@ -22738,7 +24173,7 @@ msgstr "" "Правило Ñортировки в базе данных было Ñоздано Ñ Ð²ÐµÑ€Ñией %s, но Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ " "верÑÐ¸Ñ Ð¿Ñ€ÐµÐ´Ð¾ÑтавлÑет верÑию %s." -#: utils/adt/pg_locale.c:1399 +#: utils/adt/pg_locale.c:1483 #, c-format msgid "" "Rebuild all objects affected by this collation and run ALTER COLLATION %s " @@ -22748,27 +24183,27 @@ msgstr "" "ALTER COLLATION %s REFRESH VERSION либо Ñоберите PostgreSQL Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ " "верÑией библиотеки." -#: utils/adt/pg_locale.c:1479 +#: utils/adt/pg_locale.c:1567 #, c-format msgid "could not open ICU converter for encoding \"%s\": %s" msgstr "не удалоÑÑŒ открыть преобразователь ICU Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\": %s" -#: utils/adt/pg_locale.c:1499 +#: utils/adt/pg_locale.c:1598 utils/adt/pg_locale.c:1607 #, c-format msgid "ucnv_toUChars failed: %s" msgstr "ошибка ucnv_toUChars: %s" -#: utils/adt/pg_locale.c:1517 +#: utils/adt/pg_locale.c:1636 utils/adt/pg_locale.c:1645 #, c-format msgid "ucnv_fromUChars failed: %s" msgstr "ошибка ucnv_fromUChars: %s" -#: utils/adt/pg_locale.c:1689 +#: utils/adt/pg_locale.c:1817 #, c-format msgid "invalid multibyte character for locale" msgstr "неверный многобайтный Ñимвол Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸" -#: utils/adt/pg_locale.c:1690 +#: utils/adt/pg_locale.c:1818 #, c-format msgid "" "The server's LC_CTYPE locale is probably incompatible with the database " @@ -22776,13 +24211,13 @@ msgid "" msgstr "" "Параметр локали Ñервера LC_CTYPE, возможно, неÑовмеÑтим Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¾Ð¹ БД." -#: utils/adt/pg_upgrade_support.c:28 +#: utils/adt/pg_upgrade_support.c:29 #, c-format msgid "function can only be called when server is in binary upgrade mode" msgstr "" "функцию можно вызывать только когда Ñервер в режиме двоичного обновлениÑ" -#: utils/adt/pgstatfuncs.c:473 +#: utils/adt/pgstatfuncs.c:474 #, c-format msgid "invalid command name: \"%s\"" msgstr "неверное Ð¸Ð¼Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ‹: \"%s\"" @@ -22822,191 +24257,194 @@ msgstr "результат Ð²Ñ‹Ñ‡Ð¸Ñ‚Ð°Ð½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð² будет н msgid "result of range union would not be contiguous" msgstr "результат Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð´Ð¸Ð°Ð¿Ð°Ð·Ð¾Ð½Ð¾Ð² будет не непрерывным" -#: utils/adt/rangetypes.c:1533 +#: utils/adt/rangetypes.c:1597 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "нижнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° диапазона должна быть меньше или равна верхней" -#: utils/adt/rangetypes.c:1916 utils/adt/rangetypes.c:1929 -#: utils/adt/rangetypes.c:1943 +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 +#: utils/adt/rangetypes.c:2007 #, c-format msgid "invalid range bound flags" msgstr "неверные флаги границ диапазона" -#: utils/adt/rangetypes.c:1917 utils/adt/rangetypes.c:1930 -#: utils/adt/rangetypes.c:1944 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "ДопуÑтимые значениÑ: \"[]\", \"[)\", \"(]\" и \"()\"." -#: utils/adt/rangetypes.c:2009 utils/adt/rangetypes.c:2026 -#: utils/adt/rangetypes.c:2039 utils/adt/rangetypes.c:2057 -#: utils/adt/rangetypes.c:2068 utils/adt/rangetypes.c:2112 -#: utils/adt/rangetypes.c:2120 +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 +#: utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 +#: utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 +#: utils/adt/rangetypes.c:2184 #, c-format msgid "malformed range literal: \"%s\"" msgstr "ошибочный литерал диапазона: \"%s\"" -#: utils/adt/rangetypes.c:2011 +#: utils/adt/rangetypes.c:2075 #, c-format msgid "Junk after \"empty\" key word." msgstr "МуÑор поÑле ключевого Ñлова \"empty\"." -#: utils/adt/rangetypes.c:2028 +#: utils/adt/rangetypes.c:2092 #, c-format msgid "Missing left parenthesis or bracket." msgstr "ОтÑутÑтвует Ð»ÐµÐ²Ð°Ñ Ñкобка (ÐºÑ€ÑƒÐ³Ð»Ð°Ñ Ð¸Ð»Ð¸ квадратнаÑ)." -#: utils/adt/rangetypes.c:2041 +#: utils/adt/rangetypes.c:2105 #, c-format msgid "Missing comma after lower bound." msgstr "ОтÑутÑтвует запÑÑ‚Ð°Ñ Ð¿Ð¾Ñле нижней границы." -#: utils/adt/rangetypes.c:2059 +#: utils/adt/rangetypes.c:2123 #, c-format msgid "Too many commas." msgstr "Слишком много запÑтых." -#: utils/adt/rangetypes.c:2070 +#: utils/adt/rangetypes.c:2134 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "МуÑор поÑле правой Ñкобки." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1344 utils/adt/varlena.c:3941 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 #, c-format msgid "regular expression failed: %s" msgstr "ошибка в регулÑрном выражении: %s" # skip-rule: capital-letter-first # well-spelled: рег -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 #, c-format msgid "invalid regexp option: \"%c\"" msgstr "неверный Ñлемент рег. выражениÑ: \"%c\"" -#: utils/adt/regexp.c:862 +#: utils/adt/regexp.c:866 #, c-format msgid "regexp_match does not support the global option" msgstr "regexp_match не поддерживает глобальный поиÑк" -#: utils/adt/regexp.c:863 +#: utils/adt/regexp.c:867 #, c-format msgid "Use the regexp_matches function instead." msgstr "ВмеÑто неё иÑпользуйте функцию regexp_matches." -#: utils/adt/regexp.c:1163 +#: utils/adt/regexp.c:1049 +#, c-format +msgid "too many regular expression matches" +msgstr "Ñлишком много Ñовпадений Ð´Ð»Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрного выражениÑ" + +#: utils/adt/regexp.c:1244 #, c-format msgid "regexp_split_to_table does not support the global option" msgstr "regexp_split_to_table не поддерживает глобальный поиÑк" -#: utils/adt/regexp.c:1219 +#: utils/adt/regexp.c:1297 #, c-format msgid "regexp_split_to_array does not support the global option" msgstr "regexp_split_to_array не поддерживает глобальный поиÑк" -#: utils/adt/regproc.c:130 utils/adt/regproc.c:150 +#: utils/adt/regproc.c:106 #, c-format msgid "more than one function named \"%s\"" msgstr "Ð¸Ð¼Ñ \"%s\" имеют неÑколько функций" -#: utils/adt/regproc.c:589 utils/adt/regproc.c:609 +#: utils/adt/regproc.c:524 #, c-format msgid "more than one operator named %s" msgstr "Ð¸Ð¼Ñ %s имеют неÑколько операторов" -#: utils/adt/regproc.c:776 utils/adt/regproc.c:817 gram.y:7767 +#: utils/adt/regproc.c:691 utils/adt/regproc.c:732 gram.y:8181 #, c-format msgid "missing argument" msgstr "отÑутÑтвует аргумент" -#: utils/adt/regproc.c:777 utils/adt/regproc.c:818 gram.y:7768 +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8182 #, c-format msgid "Use NONE to denote the missing argument of a unary operator." msgstr "" "Чтобы обозначить отÑутÑтвующий аргумент унарного оператора, укажите NONE." -#: utils/adt/regproc.c:781 utils/adt/regproc.c:822 utils/adt/regproc.c:2008 -#: utils/adt/ruleutils.c:8790 utils/adt/ruleutils.c:8958 +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9133 utils/adt/ruleutils.c:9301 #, c-format msgid "too many arguments" msgstr "Ñлишком много аргументов" -#: utils/adt/regproc.c:782 utils/adt/regproc.c:823 +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 #, c-format msgid "Provide two argument types for operator." msgstr "ПредоÑтавьте Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° два типа аргументов." -#: utils/adt/regproc.c:1596 utils/adt/regproc.c:1620 utils/adt/regproc.c:1717 -#: utils/adt/regproc.c:1741 utils/adt/regproc.c:1843 utils/adt/regproc.c:1848 -#: utils/adt/varlena.c:3196 utils/adt/varlena.c:3201 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 #, c-format msgid "invalid name syntax" msgstr "ошибка ÑинтакÑиÑа в имени" -#: utils/adt/regproc.c:1906 +#: utils/adt/regproc.c:1763 #, c-format msgid "expected a left parenthesis" msgstr "ожидалаÑÑŒ Ð»ÐµÐ²Ð°Ñ Ñкобка" -#: utils/adt/regproc.c:1922 +#: utils/adt/regproc.c:1779 #, c-format msgid "expected a right parenthesis" msgstr "ожидалаÑÑŒ Ð¿Ñ€Ð°Ð²Ð°Ñ Ñкобка" -#: utils/adt/regproc.c:1941 +#: utils/adt/regproc.c:1798 #, c-format msgid "expected a type name" msgstr "ожидалоÑÑŒ Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð°" -#: utils/adt/regproc.c:1973 +#: utils/adt/regproc.c:1830 #, c-format msgid "improper type name" msgstr "ошибочное Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð°" -#: utils/adt/ri_triggers.c:314 utils/adt/ri_triggers.c:371 -#: utils/adt/ri_triggers.c:790 utils/adt/ri_triggers.c:1013 -#: utils/adt/ri_triggers.c:1169 utils/adt/ri_triggers.c:1350 -#: utils/adt/ri_triggers.c:1515 utils/adt/ri_triggers.c:1691 -#: utils/adt/ri_triggers.c:1871 utils/adt/ri_triggers.c:2062 -#: utils/adt/ri_triggers.c:2120 utils/adt/ri_triggers.c:2225 -#: utils/adt/ri_triggers.c:2402 gram.y:3594 +#: utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 +#: utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 +#: utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 +#: utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 +#: utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 gram.y:3815 #, c-format msgid "MATCH PARTIAL not yet implemented" msgstr "выражение MATCH PARTIAL ещё не реализовано" -#: utils/adt/ri_triggers.c:343 utils/adt/ri_triggers.c:2490 -#: utils/adt/ri_triggers.c:3315 +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 +#: utils/adt/ri_triggers.c:2774 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "" "INSERT или UPDATE в таблице \"%s\" нарушает ограничение внешнего ключа \"%s\"" -#: utils/adt/ri_triggers.c:346 utils/adt/ri_triggers.c:2493 +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL не позволÑет Ñмешивать в значении ключа null и не null." -#: utils/adt/ri_triggers.c:2732 +#: utils/adt/ri_triggers.c:2273 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð´Ð»Ñ INSERT" -#: utils/adt/ri_triggers.c:2738 +#: utils/adt/ri_triggers.c:2279 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð´Ð»Ñ UPDATE" -#: utils/adt/ri_triggers.c:2744 +#: utils/adt/ri_triggers.c:2285 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" должна запуÑкатьÑÑ Ð´Ð»Ñ DELETE" -#: utils/adt/ri_triggers.c:2767 +#: utils/adt/ri_triggers.c:2308 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° \"%s\" таблицы \"%s\" нет запиÑи pg_constraint" -#: utils/adt/ri_triggers.c:2769 +#: utils/adt/ri_triggers.c:2310 #, c-format msgid "" "Remove this referential integrity trigger and its mates, then do ALTER TABLE " @@ -23015,7 +24453,7 @@ msgstr "" "Удалите Ñтот триггер ÑÑылочной целоÑтноÑти и ÑвÑзанные объекты, а затем " "выполните ALTER TABLE ADD CONSTRAINT." -#: utils/adt/ri_triggers.c:3225 +#: utils/adt/ri_triggers.c:2621 #, c-format msgid "" "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave " @@ -23024,47 +24462,47 @@ msgstr "" "неожиданный результат запроÑа ÑÑылочной целоÑтноÑти к \"%s\" из Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ " "\"%s\" таблицы \"%s\"" -#: utils/adt/ri_triggers.c:3229 +#: utils/adt/ri_triggers.c:2625 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "Скорее вÑего Ñто вызвано правилом, перепиÑавшим запроÑ." -#: utils/adt/ri_triggers.c:3319 +#: utils/adt/ri_triggers.c:2778 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "Ключ (%s)=(%s) отÑутÑтвует в таблице \"%s\"." -#: utils/adt/ri_triggers.c:3322 +#: utils/adt/ri_triggers.c:2781 #, c-format msgid "Key is not present in table \"%s\"." msgstr "Ключ отÑутÑтвует в таблице \"%s\"." -#: utils/adt/ri_triggers.c:3328 +#: utils/adt/ri_triggers.c:2787 #, c-format msgid "" "update or delete on table \"%s\" violates foreign key constraint \"%s\" on " "table \"%s\"" msgstr "" -"UPDATE или DELETE в таблице \"%s\" нарушает ограничение внешнего ключа \"%s" -"\" таблицы \"%s\"" +"UPDATE или DELETE в таблице \"%s\" нарушает ограничение внешнего ключа \"" +"%s\" таблицы \"%s\"" -#: utils/adt/ri_triggers.c:3333 +#: utils/adt/ri_triggers.c:2792 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "Ðа ключ (%s)=(%s) вÑÑ‘ ещё еÑть ÑÑылки в таблице \"%s\"." -#: utils/adt/ri_triggers.c:3336 +#: utils/adt/ri_triggers.c:2795 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "Ðа ключ вÑÑ‘ ещё еÑть ÑÑылки в таблице \"%s\"." -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "ввод анонимных ÑоÑтавных типов не реализован" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 +#: utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 #, c-format msgid "malformed record literal: \"%s\"" msgstr "ошибка в литерале запиÑи: \"%s\"" @@ -23074,184 +24512,184 @@ msgstr "ошибка в литерале запиÑи: \"%s\"" msgid "Missing left parenthesis." msgstr "ОтÑутÑтвует Ð»ÐµÐ²Ð°Ñ Ñкобка." -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:185 #, c-format msgid "Too few columns." msgstr "Слишком мало Ñтолбцов." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:268 #, c-format msgid "Too many columns." msgstr "Слишком много Ñтолбцов." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:276 #, c-format msgid "Junk after right parenthesis." msgstr "МуÑор поÑле правой Ñкобки." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:530 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "неверное чиÑло Ñтолбцов: %d, ожидалоÑÑŒ: %d" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:558 #, c-format msgid "wrong data type: %u, expected %u" msgstr "неверный тип данных: %u, ожидалÑÑ %u" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:619 #, c-format msgid "improper binary format in record column %d" msgstr "неподходÑщий двоичный формат в Ñтолбце запиÑи %d" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 utils/adt/rowtypes.c:1396 -#: utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 +#: utils/adt/rowtypes.c:1413 utils/adt/rowtypes.c:1657 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "не удалоÑÑŒ Ñравнить различные типы Ñтолбцов %s и %s, Ñтолбец запиÑи %d" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 utils/adt/rowtypes.c:1529 -#: utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 +#: utils/adt/rowtypes.c:1508 utils/adt/rowtypes.c:1731 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "Ñравнивать типы запиÑей Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼ чиÑлом Ñтолбцов нельзÑ" -#: utils/adt/ruleutils.c:4565 +#: utils/adt/ruleutils.c:4824 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "правило \"%s\" имеет неподдерживаемый тип Ñобытий %d" -#: utils/adt/selfuncs.c:5490 +#: utils/adt/selfuncs.c:5796 #, c-format msgid "case insensitive matching not supported on type bytea" msgstr "региÑтронезавиÑимое Ñравнение не поддерживаетÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° bytea" -#: utils/adt/selfuncs.c:5592 +#: utils/adt/selfuncs.c:5898 #, c-format msgid "regular-expression matching not supported on type bytea" msgstr "Ñравнение Ñ Ñ€ÐµÐ³ÑƒÐ»Ñрными выражениÑми не поддерживаетÑÑ Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° bytea" -#: utils/adt/timestamp.c:106 +#: utils/adt/timestamp.c:107 #, c-format msgid "TIMESTAMP(%d)%s precision must not be negative" msgstr "TIMESTAMP(%d)%s: точноÑть должна быть неотрицательна" -#: utils/adt/timestamp.c:112 +#: utils/adt/timestamp.c:113 #, c-format msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "TIMESTAMP(%d)%s: точноÑть уменьшена до дозволенного макÑимума: %d" -#: utils/adt/timestamp.c:175 utils/adt/timestamp.c:415 +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 #, c-format msgid "timestamp out of range: \"%s\"" msgstr "timestamp вне диапазона: \"%s\"" -#: utils/adt/timestamp.c:193 utils/adt/timestamp.c:433 -#: utils/adt/timestamp.c:940 +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 +#: utils/adt/timestamp.c:941 #, c-format msgid "date/time value \"%s\" is no longer supported" msgstr "значение даты/времени \"%s\" более не поддерживаетÑÑ" -#: utils/adt/timestamp.c:361 +#: utils/adt/timestamp.c:362 #, c-format msgid "timestamp(%d) precision must be between %d and %d" msgstr "точноÑть timestamp(%d) должна быть между %d и %d" -#: utils/adt/timestamp.c:483 +#: utils/adt/timestamp.c:484 #, c-format msgid "invalid input syntax for numeric time zone: \"%s\"" msgstr "неверный ÑинтакÑÐ¸Ñ Ð´Ð»Ñ Ñ‡Ð¸Ñлового чаÑового поÑÑа: \"%s\"" -#: utils/adt/timestamp.c:485 +#: utils/adt/timestamp.c:486 #, c-format msgid "Numeric time zones must have \"-\" or \"+\" as first character." msgstr "" "ЗапиÑÑŒ чиÑлового чаÑового поÑÑа должна начинатьÑÑ Ñ Ñимвола \"-\" или \"+\"." -#: utils/adt/timestamp.c:498 +#: utils/adt/timestamp.c:499 #, c-format msgid "numeric time zone \"%s\" out of range" msgstr "чиÑловой чаÑовой поÑÑ \"%s\" вне диапазона" -#: utils/adt/timestamp.c:600 utils/adt/timestamp.c:610 -#: utils/adt/timestamp.c:618 +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 +#: utils/adt/timestamp.c:619 #, c-format msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" msgstr "timestamp вне диапазона: %d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:719 +#: utils/adt/timestamp.c:720 #, c-format msgid "timestamp cannot be NaN" msgstr "timestamp не может быть NaN" -#: utils/adt/timestamp.c:737 utils/adt/timestamp.c:749 +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 #, c-format msgid "timestamp out of range: \"%g\"" msgstr "timestamp вне диапазона: \"%g\"" -#: utils/adt/timestamp.c:934 utils/adt/timestamp.c:1504 -#: utils/adt/timestamp.c:1917 utils/adt/timestamp.c:2964 -#: utils/adt/timestamp.c:2969 utils/adt/timestamp.c:2974 -#: utils/adt/timestamp.c:3024 utils/adt/timestamp.c:3031 -#: utils/adt/timestamp.c:3038 utils/adt/timestamp.c:3058 -#: utils/adt/timestamp.c:3065 utils/adt/timestamp.c:3072 -#: utils/adt/timestamp.c:3102 utils/adt/timestamp.c:3110 -#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3477 -#: utils/adt/timestamp.c:3602 utils/adt/timestamp.c:3970 +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 +#: utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3016 +#: utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3026 +#: utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3083 +#: utils/adt/timestamp.c:3090 utils/adt/timestamp.c:3110 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3162 +#: utils/adt/timestamp.c:3206 utils/adt/timestamp.c:3633 +#: utils/adt/timestamp.c:3758 utils/adt/timestamp.c:4143 #, c-format msgid "interval out of range" msgstr "interval вне диапазона" -#: utils/adt/timestamp.c:1067 utils/adt/timestamp.c:1100 +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 #, c-format msgid "invalid INTERVAL type modifier" msgstr "неверный модификатор типа INTERVAL" -#: utils/adt/timestamp.c:1083 +#: utils/adt/timestamp.c:1084 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "INTERVAL(%d): точноÑть должна быть неотрицательна" -#: utils/adt/timestamp.c:1089 +#: utils/adt/timestamp.c:1090 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "INTERVAL(%d): точноÑть уменьшена до макÑимально возможной: %d" -#: utils/adt/timestamp.c:1461 +#: utils/adt/timestamp.c:1462 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "точноÑть interval(%d) должна быть между %d и %d" -#: utils/adt/timestamp.c:2565 +#: utils/adt/timestamp.c:2617 #, c-format msgid "cannot subtract infinite timestamps" msgstr "вычитать беÑконечные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ timestamp нельзÑ" -#: utils/adt/timestamp.c:3721 utils/adt/timestamp.c:4230 -#: utils/adt/timestamp.c:4397 utils/adt/timestamp.c:4418 +#: utils/adt/timestamp.c:3886 utils/adt/timestamp.c:4403 +#: utils/adt/timestamp.c:4570 utils/adt/timestamp.c:4591 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "единицы timestamp \"%s\" не поддерживаютÑÑ" -#: utils/adt/timestamp.c:3735 utils/adt/timestamp.c:4184 -#: utils/adt/timestamp.c:4428 +#: utils/adt/timestamp.c:3900 utils/adt/timestamp.c:4357 +#: utils/adt/timestamp.c:4601 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "единицы timestamp \"%s\" не раÑпознаны" -#: utils/adt/timestamp.c:3867 utils/adt/timestamp.c:4225 -#: utils/adt/timestamp.c:4598 utils/adt/timestamp.c:4620 +#: utils/adt/timestamp.c:4032 utils/adt/timestamp.c:4398 +#: utils/adt/timestamp.c:4771 utils/adt/timestamp.c:4793 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "единицы timestamp Ñ Ñ‡Ð°Ñовым поÑÑом \"%s\" не поддерживаютÑÑ" -#: utils/adt/timestamp.c:3884 utils/adt/timestamp.c:4179 -#: utils/adt/timestamp.c:4629 +#: utils/adt/timestamp.c:4049 utils/adt/timestamp.c:4352 +#: utils/adt/timestamp.c:4802 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "единицы timestamp Ñ Ñ‡Ð°Ñовым поÑÑом \"%s\" не раÑпознаны" -#: utils/adt/timestamp.c:3957 +#: utils/adt/timestamp.c:4130 #, c-format msgid "" "interval units \"%s\" not supported because months usually have fractional " @@ -23260,12 +24698,12 @@ msgstr "" "единицы интервала \"%s\" не поддерживаютÑÑ, так как в меÑÑцах дробное чиÑло " "недель" -#: utils/adt/timestamp.c:3963 utils/adt/timestamp.c:4723 +#: utils/adt/timestamp.c:4136 utils/adt/timestamp.c:4896 #, c-format msgid "interval units \"%s\" not supported" msgstr "единицы interval \"%s\" не поддерживаютÑÑ" -#: utils/adt/timestamp.c:3979 utils/adt/timestamp.c:4746 +#: utils/adt/timestamp.c:4152 utils/adt/timestamp.c:4919 #, c-format msgid "interval units \"%s\" not recognized" msgstr "единицы interval \"%s\" не раÑпознаны" @@ -23301,43 +24739,43 @@ msgstr "" msgid "gtsvector_in not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ gtsvector_in не реализована" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð²Ð¾ фразовом операторе должна быть не больше %d" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "ошибка ÑинтакÑиÑа в tsquery: \"%s\"" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "нет оператора в tsquery: \"%s\"" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "Ñлишком большое значение в tsquery: \"%s\"" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "Ñлишком длинный операнд в tsquery: \"%s\"" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "Ñлишком длинное Ñлово в tsquery: \"%s\"" -#: utils/adt/tsquery.c:642 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¿Ð¾Ð¸Ñка текÑта не Ñодержит лекÑемы: \"%s\"" -#: utils/adt/tsquery.c:653 utils/adt/tsquery_util.c:375 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "tsquery Ñлишком большой" @@ -23448,87 +24886,75 @@ msgstr "Ð¸Ð¼Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ текÑтового поиÑка \"%s\" msgid "column \"%s\" is not of a character type" msgstr "Ñтолбец \"%s\" имеет не Ñимвольный тип" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "ошибка ÑинтакÑиÑа в tsvector: \"%s\"" # skip-rule: capital-letter-first -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "нет Ñпец. Ñимвола \"%s\"" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ позиции в tsvector: \"%s\"" #: utils/adt/txid.c:135 #, c-format -msgid "transaction ID " -msgstr "идентификатор транзакции " +msgid "transaction ID %s is in the future" +msgstr "идентификатор транзакции %s отноÑитÑÑ Ðº будущему" #: utils/adt/txid.c:624 #, c-format msgid "invalid external txid_snapshot data" msgstr "неверное внешнее предÑтавление txid_snapshot" -#: utils/adt/txid.c:758 utils/adt/txid.c:779 -msgid "in progress" -msgstr "выполнÑетÑÑ" - -#: utils/adt/txid.c:760 -msgid "committed" -msgstr "зафикÑирована" - -#: utils/adt/txid.c:762 utils/adt/txid.c:777 -msgid "aborted" -msgstr "прервана" - -#: utils/adt/varbit.c:58 utils/adt/varchar.c:51 +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 #, c-format msgid "length for type %s must be at least 1" msgstr "длина Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° %s должна быть как минимум 1" -#: utils/adt/varbit.c:63 utils/adt/varchar.c:55 +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 #, c-format msgid "length for type %s cannot exceed %d" msgstr "длина Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð¸Ð¿Ð° %s не может превышать %d" -#: utils/adt/varbit.c:164 utils/adt/varbit.c:476 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "длина битовой Ñтроки превышает предел (%d)" -#: utils/adt/varbit.c:178 utils/adt/varbit.c:321 utils/adt/varbit.c:378 +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "длина битовой Ñтроки (%d) не ÑоответÑтвует типу bit(%d)" -#: utils/adt/varbit.c:200 utils/adt/varbit.c:512 +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "\"%c\" - не Ð´Ð²Ð¾Ð¸Ñ‡Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð°" -#: utils/adt/varbit.c:225 utils/adt/varbit.c:537 +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "\"%c\" - не шеÑÑ‚Ð½Ð°Ð´Ñ†Ð°Ñ‚ÐµÑ€Ð¸Ñ‡Ð½Ð°Ñ Ñ†Ð¸Ñ„Ñ€Ð°" -#: utils/adt/varbit.c:312 utils/adt/varbit.c:628 +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 #, c-format msgid "invalid length in external bit string" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° во внешней Ñтроке битов" -#: utils/adt/varbit.c:490 utils/adt/varbit.c:637 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "Ñтрока битов не умещаетÑÑ Ð² тип bit varying(%d)" -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:841 -#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2861 -#: utils/adt/varlena.c:2928 +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 +#: utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 +#: utils/adt/varlena.c:2979 #, c-format msgid "negative substring length not allowed" msgstr "подÑтрока должна иметь неотрицательную длину" @@ -23554,7 +24980,7 @@ msgstr "" msgid "bit index %d out of valid range (0..%d)" msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ð±Ð¸Ñ‚Ð° %d вне диапазона 0..%d" -#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3120 +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 #, c-format msgid "new bit must be 0 or 1" msgstr "значением бита должен быть 0 или 1" @@ -23569,7 +24995,7 @@ msgstr "значение не умещаетÑÑ Ð² тип character(%d)" msgid "value too long for type character varying(%d)" msgstr "значение не умещаетÑÑ Ð² тип character varying(%d)" -#: utils/adt/varlena.c:1416 utils/adt/varlena.c:1859 +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "" @@ -23586,63 +25012,63 @@ msgstr "не удалоÑÑŒ преобразовать Ñтроку в UTF-16 ( msgid "could not compare Unicode strings: %m" msgstr "не удалоÑÑŒ Ñравнить Ñтроки в Unicode: %m" -#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2139 +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 #, c-format msgid "collation failed: %s" msgstr "ошибка в библиотеке Ñортировки: %s" -#: utils/adt/varlena.c:2349 +#: utils/adt/varlena.c:2394 #, c-format msgid "sort key generation failed: %s" msgstr "не удалоÑÑŒ Ñгенерировать ключ Ñортировки: %s" -#: utils/adt/varlena.c:3006 utils/adt/varlena.c:3037 utils/adt/varlena.c:3072 -#: utils/adt/varlena.c:3108 +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 +#: utils/adt/varlena.c:3158 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "Ð¸Ð½Ð´ÐµÐºÑ %d вне диапазона 0..%d" -#: utils/adt/varlena.c:4037 +#: utils/adt/varlena.c:4201 #, c-format msgid "field position must be greater than zero" msgstr "Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð¿Ð¾Ð»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° быть больше нулÑ" -#: utils/adt/varlena.c:4916 +#: utils/adt/varlena.c:5080 #, c-format msgid "unterminated format() type specifier" msgstr "незавершённый Ñпецификатор типа format()" -#: utils/adt/varlena.c:4917 utils/adt/varlena.c:5051 utils/adt/varlena.c:5172 +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "Ð”Ð»Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ знака \"%%\" запишите \"%%%%\"." -#: utils/adt/varlena.c:5049 utils/adt/varlena.c:5170 +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 #, c-format msgid "unrecognized format() type specifier \"%c\"" msgstr "нераÑпознанный Ñпецификатор типа format(): \"%c\"" -#: utils/adt/varlena.c:5062 utils/adt/varlena.c:5119 +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 #, c-format msgid "too few arguments for format()" msgstr "мало аргументов Ð´Ð»Ñ format()" -#: utils/adt/varlena.c:5214 utils/adt/varlena.c:5397 +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 #, c-format msgid "number is out of range" msgstr "чиÑло вне диапазона" -#: utils/adt/varlena.c:5278 utils/adt/varlena.c:5306 +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "формат ÑÑылаетÑÑ Ð½Ð° аргумент 0, но аргументы нумеруютÑÑ Ñ 1" -#: utils/adt/varlena.c:5299 +#: utils/adt/varlena.c:5463 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "указание аргумента ширины должно оканчиватьÑÑ \"$\"" -#: utils/adt/varlena.c:5344 +#: utils/adt/varlena.c:5508 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ null Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ´Ñтавить в виде SQL-идентификатора" @@ -23657,73 +25083,73 @@ msgstr "аргумент ntile должен быть больше нулÑ" msgid "argument of nth_value must be greater than zero" msgstr "аргумент nth_value должен быть больше нулÑ" -#: utils/adt/xml.c:216 +#: utils/adt/xml.c:221 #, c-format msgid "unsupported XML feature" msgstr "XML-функции не поддерживаютÑÑ" -#: utils/adt/xml.c:217 +#: utils/adt/xml.c:222 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "Ð”Ð»Ñ Ñтой функциональноÑти в Ñервере не хватает поддержки libxml." -#: utils/adt/xml.c:218 +#: utils/adt/xml.c:223 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "Ðеобходимо перекомпилировать PostgreSQL Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ --with-libxml." -#: utils/adt/xml.c:237 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:242 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "неверное Ð¸Ð¼Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸: \"%s\"" -#: utils/adt/xml.c:480 utils/adt/xml.c:485 +#: utils/adt/xml.c:485 utils/adt/xml.c:490 #, c-format msgid "invalid XML comment" msgstr "ошибка в XML-комментарии" -#: utils/adt/xml.c:614 +#: utils/adt/xml.c:619 #, c-format msgid "not an XML document" msgstr "не XML-документ" -#: utils/adt/xml.c:773 utils/adt/xml.c:796 +#: utils/adt/xml.c:778 utils/adt/xml.c:801 #, c-format msgid "invalid XML processing instruction" msgstr "Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ XML-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ (PI)" -#: utils/adt/xml.c:774 +#: utils/adt/xml.c:779 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "назначением XML-инÑтрукции обработки (PI) не может быть \"%s\"." -#: utils/adt/xml.c:797 +#: utils/adt/xml.c:802 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "XML-инÑÑ‚Ñ€ÑƒÐºÑ†Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ (PI) не может Ñодержать \"?>\"." -#: utils/adt/xml.c:876 +#: utils/adt/xml.c:881 #, c-format msgid "xmlvalidate is not implemented" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ xmlvalidate не реализована" -#: utils/adt/xml.c:955 +#: utils/adt/xml.c:960 #, c-format msgid "could not initialize XML library" msgstr "не удалоÑÑŒ инициализировать библиотеку XML" -#: utils/adt/xml.c:956 +#: utils/adt/xml.c:961 #, c-format msgid "" "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "другой тип char в libxml2: sizeof(char)=%u, sizeof(xmlChar)=%u." -#: utils/adt/xml.c:1042 +#: utils/adt/xml.c:1047 #, c-format msgid "could not set up XML error handler" msgstr "не удалоÑÑŒ уÑтановить обработчик XML-ошибок" -#: utils/adt/xml.c:1043 +#: utils/adt/xml.c:1048 #, c-format msgid "" "This probably indicates that the version of libxml2 being used is not " @@ -23732,182 +25158,186 @@ msgstr "" "Возможно Ñто означает, что иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ libxml2 не ÑовмеÑтима Ñ " "заголовочными файлами libxml2, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼Ð¸ был Ñобран PostgreSQL." -#: utils/adt/xml.c:1793 +#: utils/adt/xml.c:1905 msgid "Invalid character value." msgstr "Ðеверный Ñимвол." -#: utils/adt/xml.c:1796 +#: utils/adt/xml.c:1908 msgid "Space required." msgstr "ТребуетÑÑ Ð¿Ñ€Ð¾Ð±ÐµÐ»." -#: utils/adt/xml.c:1799 +#: utils/adt/xml.c:1911 msgid "standalone accepts only 'yes' or 'no'." msgstr "значениÑми атрибута standalone могут быть только 'yes' и 'no'." -#: utils/adt/xml.c:1802 +#: utils/adt/xml.c:1914 msgid "Malformed declaration: missing version." msgstr "Ошибочное объÑвление: не указана верÑиÑ." -#: utils/adt/xml.c:1805 +#: utils/adt/xml.c:1917 msgid "Missing encoding in text declaration." msgstr "Ð’ объÑвлении не указана кодировка." -#: utils/adt/xml.c:1808 +#: utils/adt/xml.c:1920 msgid "Parsing XML declaration: '?>' expected." msgstr "Ошибка при разборе XML-объÑвлениÑ: ожидаетÑÑ '?>'." -#: utils/adt/xml.c:1811 +#: utils/adt/xml.c:1923 #, c-format msgid "Unrecognized libxml error code: %d." msgstr "ÐераÑпознанный код ошибки libxml: %d." -#: utils/adt/xml.c:2086 +#: utils/adt/xml.c:2198 #, c-format msgid "XML does not support infinite date values." msgstr "XML не поддерживает беÑконечноÑть в датах." -#: utils/adt/xml.c:2108 utils/adt/xml.c:2135 +#: utils/adt/xml.c:2220 utils/adt/xml.c:2247 #, c-format msgid "XML does not support infinite timestamp values." msgstr "XML не поддерживает беÑконечноÑть в timestamp." -#: utils/adt/xml.c:2538 +#: utils/adt/xml.c:2659 #, c-format msgid "invalid query" msgstr "неверный запроÑ" -#: utils/adt/xml.c:3857 +#: utils/adt/xml.c:3982 #, c-format msgid "invalid array for XML namespace mapping" msgstr "неправильный маÑÑив Ñ ÑопоÑтавлениÑми проÑтранÑтв имён XML" -#: utils/adt/xml.c:3858 +#: utils/adt/xml.c:3983 #, c-format msgid "" "The array must be two-dimensional with length of the second axis equal to 2." msgstr "МаÑÑив должен быть двухмерным и Ñодержать 2 Ñлемента по второй оÑи." -#: utils/adt/xml.c:3882 +#: utils/adt/xml.c:4007 #, c-format msgid "empty XPath expression" msgstr "пуÑтое выражение XPath" -#: utils/adt/xml.c:3926 +#: utils/adt/xml.c:4059 #, c-format msgid "neither namespace name nor URI may be null" msgstr "ни префикÑ, ни URI проÑтранÑтва имён не может быть null" -#: utils/adt/xml.c:3933 +#: utils/adt/xml.c:4066 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "" -"не удалоÑÑŒ зарегиÑтрировать проÑтранÑтво имён XML Ñ Ð¿Ñ€ÐµÑ„Ð¸ÐºÑом \"%s\" и URI " -"\"%s\"" +"не удалоÑÑŒ зарегиÑтрировать проÑтранÑтво имён XML Ñ Ð¿Ñ€ÐµÑ„Ð¸ÐºÑом \"%s\" и URI \"" +"%s\"" -#: utils/adt/xml.c:4287 +#: utils/adt/xml.c:4417 #, c-format msgid "DEFAULT namespace is not supported" msgstr "проÑтранÑтво имён DEFAULT не поддерживаетÑÑ" -#: utils/adt/xml.c:4316 +#: utils/adt/xml.c:4446 #, c-format msgid "row path filter must not be empty string" msgstr "путь отбираемых Ñтрок не должен быть пуÑтым" -#: utils/adt/xml.c:4347 +#: utils/adt/xml.c:4477 #, c-format msgid "column path filter must not be empty string" msgstr "путь отбираемого Ñтолбца не должен быть пуÑтым" -#: utils/adt/xml.c:4530 +#: utils/adt/xml.c:4663 #, c-format msgid "more than one value returned by column XPath expression" msgstr "выражение XPath, отбирающее Ñтолбец, возвратило более одного значениÑ" -#: utils/cache/lsyscache.c:2580 utils/cache/lsyscache.c:2613 -#: utils/cache/lsyscache.c:2646 utils/cache/lsyscache.c:2679 +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "тип %s - лишь оболочка" -#: utils/cache/lsyscache.c:2585 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s нет функции ввода" -#: utils/cache/lsyscache.c:2618 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° %s нет функции вывода" -#: utils/cache/plancache.c:722 +#: utils/cache/partcache.c:201 +#, c-format +msgid "" +"operator class \"%s\" of access method %s is missing support function %d for " +"type %s" +msgstr "" +"в клаÑÑе операторов \"%s\" метода доÑтупа %s нет опорной функции %d Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° " +"%s" + +#: utils/cache/plancache.c:723 #, c-format msgid "cached plan must not change result type" msgstr "в кешированном плане не должен изменÑтьÑÑ Ñ‚Ð¸Ð¿ результата" -#: utils/cache/relcache.c:5779 +#: utils/cache/relcache.c:5842 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "Ñоздать файл инициализации Ð´Ð»Ñ ÐºÐµÑˆÐ° отношений \"%s\" не удалоÑÑŒ: %m" -#: utils/cache/relcache.c:5781 +#: utils/cache/relcache.c:5844 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "Продолжаем вÑÑ‘ равно, Ñ…Ð¾Ñ‚Ñ Ñ‡Ñ‚Ð¾-то не так." -#: utils/cache/relcache.c:6051 +#: utils/cache/relcache.c:6198 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "не удалоÑÑŒ Ñтереть файл кеша \"%s\": %m" -#: utils/cache/relmapper.c:509 +#: utils/cache/relmapper.c:513 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "" "выполнить PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, изменившей ÑопоÑтавление отношений, нельзÑ" -#: utils/cache/relmapper.c:652 utils/cache/relmapper.c:754 +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 #, c-format msgid "could not open relation mapping file \"%s\": %m" msgstr "открыть файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" не удалоÑÑŒ: %m" -#: utils/cache/relmapper.c:666 +#: utils/cache/relmapper.c:669 #, c-format msgid "could not read relation mapping file \"%s\": %m" msgstr "прочитать файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" не удалоÑÑŒ: %m" -#: utils/cache/relmapper.c:677 +#: utils/cache/relmapper.c:680 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" Ñодержит неверные данные" -#: utils/cache/relmapper.c:687 +#: utils/cache/relmapper.c:690 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "ошибка контрольной Ñуммы в файле ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\"" -#: utils/cache/relmapper.c:788 +#: utils/cache/relmapper.c:789 #, c-format msgid "could not write to relation mapping file \"%s\": %m" msgstr "запиÑать в файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" не удалоÑÑŒ: %m" -#: utils/cache/relmapper.c:803 +#: utils/cache/relmapper.c:804 #, c-format msgid "could not fsync relation mapping file \"%s\": %m" msgstr "" "Ñинхронизировать файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" Ñ Ð¤Ð¡ не удалоÑÑŒ: %m" -#: utils/cache/relmapper.c:810 +#: utils/cache/relmapper.c:811 #, c-format msgid "could not close relation mapping file \"%s\": %m" msgstr "закрыть файл ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ð¹ \"%s\" не удалоÑÑŒ: %m" -#: utils/cache/typcache.c:1223 -#, c-format -msgid "type %s is not composite" -msgstr "тип %s не ÑвлÑетÑÑ ÑоÑтавным" - -#: utils/cache/typcache.c:1237 +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 #, c-format msgid "record type has not been registered" msgstr "тип запиÑи не зарегиÑтрирован" @@ -23922,207 +25352,202 @@ msgstr "ЛОВУШКÐ: ИÑключительное уÑловие: невер msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" msgstr "ЛОВУШКÐ: %s(\"%s\", файл: \"%s\", Ñтрока: %d)\n" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/error/elog.c:322 utils/error/elog.c:1304 #, c-format msgid "error occurred at %s:%d before error message processing is available\n" msgstr "" "в %s:%d произошла ошибка до готовноÑти подÑиÑтемы обработки Ñообщений\n" -#: utils/error/elog.c:1889 +#: utils/error/elog.c:1882 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" msgstr "открыть файл \"%s\" как stderr не удалоÑÑŒ: %m" -#: utils/error/elog.c:1902 +#: utils/error/elog.c:1895 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" msgstr "открыть файл \"%s\" как stdout не удалоÑÑŒ: %m" -#: utils/error/elog.c:2389 utils/error/elog.c:2406 utils/error/elog.c:2422 +#: utils/error/elog.c:2387 utils/error/elog.c:2404 utils/error/elog.c:2420 msgid "[unknown]" msgstr "[н/д]" -#: utils/error/elog.c:2882 utils/error/elog.c:3185 utils/error/elog.c:3293 +#: utils/error/elog.c:2880 utils/error/elog.c:3183 utils/error/elog.c:3291 msgid "missing error text" msgstr "отÑутÑтвует текÑÑ‚ ошибки" -#: utils/error/elog.c:2885 utils/error/elog.c:2888 utils/error/elog.c:3296 -#: utils/error/elog.c:3299 +#: utils/error/elog.c:2883 utils/error/elog.c:2886 utils/error/elog.c:3294 +#: utils/error/elog.c:3297 #, c-format msgid " at character %d" msgstr " (Ñимвол %d)" -#: utils/error/elog.c:2898 utils/error/elog.c:2905 +#: utils/error/elog.c:2896 utils/error/elog.c:2903 msgid "DETAIL: " msgstr "ПОДРОБÐОСТИ: " -#: utils/error/elog.c:2912 +#: utils/error/elog.c:2910 msgid "HINT: " msgstr "ПОДСКÐЗКÐ: " -#: utils/error/elog.c:2919 +#: utils/error/elog.c:2917 msgid "QUERY: " msgstr "ЗÐПРОС: " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2924 msgid "CONTEXT: " msgstr "КОÐТЕКСТ: " -#: utils/error/elog.c:2936 +#: utils/error/elog.c:2934 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "ПОЛОЖЕÐИЕ: %s, %s:%d\n" -#: utils/error/elog.c:2943 +#: utils/error/elog.c:2941 #, c-format msgid "LOCATION: %s:%d\n" msgstr "ПОЛОЖЕÐИЕ: %s:%d\n" -#: utils/error/elog.c:2957 +#: utils/error/elog.c:2955 msgid "STATEMENT: " msgstr "ОПЕРÐТОР: " #. translator: This string will be truncated at 47 #. characters expanded. -#: utils/error/elog.c:3414 +#: utils/error/elog.c:3412 #, c-format msgid "operating system error %d" msgstr "ошибка ОС %d" -#: utils/error/elog.c:3612 +#: utils/error/elog.c:3610 msgid "DEBUG" msgstr "ОТЛÐДКÐ" -#: utils/error/elog.c:3616 +#: utils/error/elog.c:3614 msgid "LOG" msgstr "СООБЩЕÐИЕ" -#: utils/error/elog.c:3619 +#: utils/error/elog.c:3617 msgid "INFO" msgstr "ИÐФОРМÐЦИЯ" -#: utils/error/elog.c:3622 +#: utils/error/elog.c:3620 msgid "NOTICE" msgstr "ЗÐМЕЧÐÐИЕ" -#: utils/error/elog.c:3625 +#: utils/error/elog.c:3623 msgid "WARNING" msgstr "ПРЕДУПРЕЖДЕÐИЕ" -#: utils/error/elog.c:3628 +#: utils/error/elog.c:3626 msgid "ERROR" msgstr "ОШИБКÐ" -#: utils/error/elog.c:3631 +#: utils/error/elog.c:3629 msgid "FATAL" msgstr "Ð’ÐЖÐО" -#: utils/error/elog.c:3634 +#: utils/error/elog.c:3632 msgid "PANIC" msgstr "ПÐÐИКÐ" -#: utils/fmgr/dfmgr.c:117 +#: utils/fmgr/dfmgr.c:121 #, c-format msgid "could not find function \"%s\" in file \"%s\"" msgstr "не удалоÑÑŒ найти функцию \"%s\" в файле \"%s\"" -#: utils/fmgr/dfmgr.c:196 utils/fmgr/dfmgr.c:413 utils/fmgr/dfmgr.c:461 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "нет доÑтупа к файлу \"%s\": %m" - -#: utils/fmgr/dfmgr.c:234 +#: utils/fmgr/dfmgr.c:239 #, c-format msgid "could not load library \"%s\": %s" msgstr "загрузить библиотеку \"%s\" не удалоÑÑŒ: %s" -#: utils/fmgr/dfmgr.c:266 +#: utils/fmgr/dfmgr.c:271 #, c-format msgid "incompatible library \"%s\": missing magic block" msgstr "неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° \"%s\": нет отличительного блока" -#: utils/fmgr/dfmgr.c:268 +#: utils/fmgr/dfmgr.c:273 #, c-format msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." msgstr "Внешние библиотеки должны иÑпользовать Ð¼Ð°ÐºÑ€Ð¾Ñ PG_MODULE_MAGIC." -#: utils/fmgr/dfmgr.c:314 +#: utils/fmgr/dfmgr.c:319 #, c-format msgid "incompatible library \"%s\": version mismatch" msgstr "неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° \"%s\": неÑовпадение верÑий" -#: utils/fmgr/dfmgr.c:316 +#: utils/fmgr/dfmgr.c:321 #, c-format msgid "Server is version %d, library is version %s." msgstr "ВерÑÐ¸Ñ Ñервера: %d, верÑÐ¸Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ¸: %s." -#: utils/fmgr/dfmgr.c:333 +#: utils/fmgr/dfmgr.c:338 #, c-format msgid "Server has FUNC_MAX_ARGS = %d, library has %d." msgstr "Ð’ Ñервере FUNC_MAX_ARGS = %d, в библиотеке: %d." -#: utils/fmgr/dfmgr.c:342 +#: utils/fmgr/dfmgr.c:347 #, c-format msgid "Server has INDEX_MAX_KEYS = %d, library has %d." msgstr "Ð’ Ñервере INDEX_MAX_KEYS = %d, в библиотеке: %d." -#: utils/fmgr/dfmgr.c:351 +#: utils/fmgr/dfmgr.c:356 #, c-format msgid "Server has NAMEDATALEN = %d, library has %d." msgstr "Ð’ Ñервере NAMEDATALEN = %d, в библиотеке: %d." -#: utils/fmgr/dfmgr.c:360 +#: utils/fmgr/dfmgr.c:365 #, c-format msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." msgstr "Ð’ Ñервере FLOAT4PASSBYVAL = %s, в библиотеке: %s." -#: utils/fmgr/dfmgr.c:369 +#: utils/fmgr/dfmgr.c:374 #, c-format msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." msgstr "Ð’ Ñервере FLOAT8PASSBYVAL = %s, в библиотеке: %s." -#: utils/fmgr/dfmgr.c:376 +#: utils/fmgr/dfmgr.c:381 msgid "Magic block has unexpected length or padding difference." msgstr "Отличительный блок имеет неверную длину или дополнен по-другому." -#: utils/fmgr/dfmgr.c:379 +#: utils/fmgr/dfmgr.c:384 #, c-format msgid "incompatible library \"%s\": magic block mismatch" msgstr "неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñ‚ÐµÐºÐ° \"%s\": неÑоответÑтвие отличительного блока" -#: utils/fmgr/dfmgr.c:543 +#: utils/fmgr/dfmgr.c:548 #, c-format msgid "access to library \"%s\" is not allowed" msgstr "доÑтуп к библиотеке \"%s\" не разрешён" -#: utils/fmgr/dfmgr.c:569 +#: utils/fmgr/dfmgr.c:574 #, c-format msgid "invalid macro name in dynamic library path: %s" msgstr "неправильный Ð¼Ð°ÐºÑ€Ð¾Ñ Ð² пути динамичеÑкой библиотеки: %s" -#: utils/fmgr/dfmgr.c:609 +#: utils/fmgr/dfmgr.c:614 #, c-format msgid "zero-length component in parameter \"dynamic_library_path\"" msgstr "параметр dynamic_library_path Ñодержит компонент нулевой длины" -#: utils/fmgr/dfmgr.c:628 +#: utils/fmgr/dfmgr.c:633 #, c-format msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "" "параметр dynamic_library_path Ñодержит компонент, не ÑвлÑющийÑÑ Ð°Ð±Ñолютным " "путём" -#: utils/fmgr/fmgr.c:239 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "внутренней функции \"%s\" нет во внутренней поиÑковой таблице" -#: utils/fmgr/fmgr.c:399 +#: utils/fmgr/fmgr.c:485 #, c-format msgid "could not find function information for function \"%s\"" msgstr "не удалоÑÑŒ найти информацию о функции \"%s\"" -#: utils/fmgr/fmgr.c:401 +#: utils/fmgr/fmgr.c:487 #, c-format msgid "" "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." @@ -24130,18 +25555,18 @@ msgstr "" "ФункциÑм, вызываемым из SQL, требуетÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ðµ объÑвление " "PG_FUNCTION_INFO_V1(имÑ_функции)." -#: utils/fmgr/fmgr.c:419 +#: utils/fmgr/fmgr.c:505 #, c-format msgid "unrecognized API version %d reported by info function \"%s\"" msgstr "" "верÑÐ¸Ñ API (%d), Ð²Ñ‹Ð´Ð°Ð½Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ функцией \"%s\", не поддерживаетÑÑ" -#: utils/fmgr/fmgr.c:2132 +#: utils/fmgr/fmgr.c:2210 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñзыковой проверки %u вызвана Ð´Ð»Ñ Ñзыка %u (а не %u)" -#: utils/fmgr/funcapi.c:354 +#: utils/fmgr/funcapi.c:358 #, c-format msgid "" "could not determine actual result type for function \"%s\" declared to " @@ -24150,84 +25575,120 @@ msgstr "" "не удалоÑÑŒ определить дейÑтвительный тип результата Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ \"%s\", " "объÑвленной как Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ñ‚Ð¸Ð¿ %s" -#: utils/fmgr/funcapi.c:1341 utils/fmgr/funcapi.c:1372 +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 #, c-format msgid "number of aliases does not match number of columns" msgstr "чиÑло пÑевдонимов не Ñовпадает Ñ Ñ‡Ð¸Ñлом Ñтолбцов" -#: utils/fmgr/funcapi.c:1366 +#: utils/fmgr/funcapi.c:1429 #, c-format msgid "no column alias was provided" msgstr "пÑевдоним Ñтолбца не указан" -#: utils/fmgr/funcapi.c:1390 +#: utils/fmgr/funcapi.c:1453 #, c-format msgid "could not determine row description for function returning record" msgstr "не удалоÑÑŒ определить опиÑание Ñтроки Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸, возвращающей запиÑÑŒ" -#: utils/init/miscinit.c:122 +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "каталог данных \"%s\" не ÑущеÑтвует" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "не удалоÑÑŒ Ñчитать права на каталог \"%s\": %m" + +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "указанный каталог данных \"%s\" не ÑущеÑтвует" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "владелец каталога данных \"%s\" определён неверно" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "" +"Сервер должен запуÑкать пользователь, ÑвлÑющийÑÑ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ каталога данных." + +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° данных \"%s\" уÑтановлены неправильные права доÑтупа" + +#: utils/init/miscinit.c:159 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "МаÑка прав должна быть u=rwx (0700) или u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:218 #, c-format msgid "could not change directory to \"%s\": %m" msgstr "не удалоÑÑŒ перейти в каталог \"%s\": %m" -#: utils/init/miscinit.c:450 utils/misc/guc.c:6095 +#: utils/init/miscinit.c:554 utils/misc/guc.c:6374 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "" "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ в рамках операции Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñми по " "безопаÑноÑти" -#: utils/init/miscinit.c:511 +#: utils/init/miscinit.c:615 #, c-format msgid "role with OID %u does not exist" msgstr "роль Ñ OID %u не ÑущеÑтвует" -#: utils/init/miscinit.c:541 +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸ \"%s\" вход запрещён" -#: utils/init/miscinit.c:559 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "Ñлишком много подключений Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸ \"%s\"" -#: utils/init/miscinit.c:619 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "нет прав Ð´Ð»Ñ Ñмены объекта авторизации в ÑеанÑе" -#: utils/init/miscinit.c:702 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "неверный OID роли: %u" -#: utils/init/miscinit.c:756 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "ÑиÑтема БД выключена" -#: utils/init/miscinit.c:843 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "не удалоÑÑŒ Ñоздать файл блокировки \"%s\": %m" -#: utils/init/miscinit.c:857 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "не удалоÑÑŒ открыть файл блокировки \"%s\": %m" -#: utils/init/miscinit.c:864 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "не удалоÑÑŒ прочитать файл блокировки \"%s\": %m" -#: utils/init/miscinit.c:873 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "файл блокировки \"%s\" пуÑÑ‚" -#: utils/init/miscinit.c:874 +#: utils/init/miscinit.c:978 #, c-format msgid "" "Either another server is starting, or the lock file is the remnant of a " @@ -24236,54 +25697,38 @@ msgstr "" "Либо ÑÐµÐ¹Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑкаетÑÑ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ Ñервер, либо Ñтот файл оÑталÑÑ Ð² результате " "ÑÐ±Ð¾Ñ Ð¿Ñ€Ð¸ предыдущем запуÑке." -#: utils/init/miscinit.c:921 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "файл блокировки \"%s\" уже ÑущеÑтвует" -#: utils/init/miscinit.c:925 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "Другой ÑкземплÑÑ€ postgres (PID %d) работает Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ данных \"%s\"?" -#: utils/init/miscinit.c:927 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "" "Другой ÑкземплÑÑ€ postmaster (PID %d) работает Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ данных \"%s\"?" -#: utils/init/miscinit.c:930 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "Другой ÑкземплÑÑ€ postgres (PID %d) иÑпользует файл Ñокета \"%s\"?" -#: utils/init/miscinit.c:932 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "Другой ÑкземплÑÑ€ postmaster (PID %d) иÑпользует файл Ñокета \"%s\"?" -#: utils/init/miscinit.c:968 -#, c-format -msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" -msgstr "" -"ранее выделенный блок разделÑемой памÑти (ключ %lu, ID %lu) по-прежнему " -"иÑпользуетÑÑ" - -#: utils/init/miscinit.c:971 -#, c-format -msgid "" -"If you're sure there are no old server processes still running, remove the " -"shared memory block or just delete the file \"%s\"." -msgstr "" -"ЕÑли вы уверены, что процеÑÑов Ñтарого Ñервера уже не оÑталоÑÑŒ, оÑвободите " -"Ñтот блок разделÑемой памÑти или проÑто удалите файл \"%s\"." - -#: utils/init/miscinit.c:987 +#: utils/init/miscinit.c:1084 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "не удалоÑÑŒ Ñтереть Ñтарый файл блокировки \"%s\": %m" -#: utils/init/miscinit.c:989 +#: utils/init/miscinit.c:1086 #, c-format msgid "" "The file seems accidentally left over, but it could not be removed. Please " @@ -24292,48 +25737,48 @@ msgstr "" "КажетÑÑ, файл ÑохранилÑÑ Ð¿Ð¾ ошибке, но удалить его не получилоÑÑŒ. " "ПожалуйÑта, удалите файл вручную и повторите попытку." -#: utils/init/miscinit.c:1026 utils/init/miscinit.c:1040 -#: utils/init/miscinit.c:1051 +#: utils/init/miscinit.c:1123 utils/init/miscinit.c:1137 +#: utils/init/miscinit.c:1148 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "не удалоÑÑŒ запиÑать файл блокировки \"%s\": %m" -#: utils/init/miscinit.c:1182 utils/init/miscinit.c:1318 utils/misc/guc.c:8902 +#: utils/init/miscinit.c:1280 utils/init/miscinit.c:1423 utils/misc/guc.c:9215 #, c-format msgid "could not read from file \"%s\": %m" msgstr "не удалоÑÑŒ прочитать файл \"%s\": %m" -#: utils/init/miscinit.c:1306 +#: utils/init/miscinit.c:1411 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "не удалоÑÑŒ открыть файл \"%s\": %m; ошибка игнорируетÑÑ" -#: utils/init/miscinit.c:1331 +#: utils/init/miscinit.c:1436 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "файл блокировки \"%s\" Ñодержит неверный PID: %ld вмеÑто %ld" -#: utils/init/miscinit.c:1370 utils/init/miscinit.c:1386 +#: utils/init/miscinit.c:1475 utils/init/miscinit.c:1491 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "\"%s\" не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ данных" -#: utils/init/miscinit.c:1372 +#: utils/init/miscinit.c:1477 #, c-format msgid "File \"%s\" is missing." msgstr "Файл \"%s\" отÑутÑтвует." -#: utils/init/miscinit.c:1388 +#: utils/init/miscinit.c:1493 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "Файл \"%s\" Ñодержит неприемлемые данные." -#: utils/init/miscinit.c:1390 +#: utils/init/miscinit.c:1495 #, c-format msgid "You might need to initdb." msgstr "Возможно, вам нужно выполнить initdb." -#: utils/init/miscinit.c:1398 +#: utils/init/miscinit.c:1503 #, c-format msgid "" "The data directory was initialized by PostgreSQL version %s, which is not " @@ -24342,83 +25787,83 @@ msgstr "" "Каталог данных инициализирован Ñервером PostgreSQL верÑии %s, не ÑовмеÑтимой " "Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ верÑией (%s)." -#: utils/init/miscinit.c:1469 +#: utils/init/miscinit.c:1570 #, c-format msgid "loaded library \"%s\"" msgstr "загружена библиотека \"%s\"" -#: utils/init/postinit.c:251 +#: utils/init/postinit.c:252 #, c-format msgid "" "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" +"%s, bits=%d, compression=%s)" msgstr "" "подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ авторизовано: пользователь=%s, SSL включён " -"(протокол=%s, шифр=%s, Ñжатие=%s)" +"(протокол=%s, шифр=%s, битов=%d, Ñжатие=%s)" -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "off" msgstr "выкл." -#: utils/init/postinit.c:253 utils/init/postinit.c:267 +#: utils/init/postinit.c:257 utils/init/postinit.c:274 msgid "on" msgstr "вкл." -#: utils/init/postinit.c:257 +#: utils/init/postinit.c:261 #, c-format msgid "replication connection authorized: user=%s" msgstr "подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ авторизовано: пользователь=%s" -#: utils/init/postinit.c:265 +#: utils/init/postinit.c:269 #, c-format msgid "" "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" +"%s, bits=%d, compression=%s)" msgstr "" "подключение авторизовано: пользователь=%s, база=%s, SSL включён (протокол=" -"%s, шифр=%s, Ñжатие=%s)" +"%s, шифр=%s, битов=%d, Ñжатие=%s)" -#: utils/init/postinit.c:271 +#: utils/init/postinit.c:278 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "подключение авторизовано: пользователь=%s, база=%s" -#: utils/init/postinit.c:303 +#: utils/init/postinit.c:310 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "база данных \"%s\" иÑчезла из pg_database" -#: utils/init/postinit.c:305 +#: utils/init/postinit.c:312 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "Похоже, базой данных Ñ OID %u теперь владеет \"%s\"." -#: utils/init/postinit.c:325 +#: utils/init/postinit.c:332 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "база \"%s\" не принимает Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² данный момент" -#: utils/init/postinit.c:338 +#: utils/init/postinit.c:345 #, c-format msgid "permission denied for database \"%s\"" msgstr "доÑтуп к базе \"%s\" запрещён" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:346 #, c-format msgid "User does not have CONNECT privilege." msgstr "Пользователь не имеет привилегии CONNECT." -#: utils/init/postinit.c:356 +#: utils/init/postinit.c:363 #, c-format msgid "too many connections for database \"%s\"" msgstr "Ñлишком много подключений к БД \"%s\"" -#: utils/init/postinit.c:378 utils/init/postinit.c:385 +#: utils/init/postinit.c:385 utils/init/postinit.c:392 #, c-format msgid "database locale is incompatible with operating system" msgstr "локаль БД неÑовмеÑтима Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¾Ð¹ ÑиÑтемой" -#: utils/init/postinit.c:379 +#: utils/init/postinit.c:386 #, c-format msgid "" "The database was initialized with LC_COLLATE \"%s\", which is not " @@ -24427,7 +25872,7 @@ msgstr "" "База данных была инициализирована Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ LC_COLLATE \"%s\", но ÑÐµÐ¹Ñ‡Ð°Ñ " "setlocale() не воÑпринимает его." -#: utils/init/postinit.c:381 utils/init/postinit.c:388 +#: utils/init/postinit.c:388 utils/init/postinit.c:395 #, c-format msgid "" "Recreate the database with another locale or install the missing locale." @@ -24435,7 +25880,7 @@ msgstr "" "ПереÑоздайте базу данных Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ локалью или уÑтановите поддержку нужной " "локали." -#: utils/init/postinit.c:386 +#: utils/init/postinit.c:393 #, c-format msgid "" "The database was initialized with LC_CTYPE \"%s\", which is not recognized " @@ -24444,36 +25889,36 @@ msgstr "" "База данных была инициализирована Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ LC_CTYPE \"%s\", но ÑÐµÐ¹Ñ‡Ð°Ñ " "setlocale() не воÑпринимает его." -#: utils/init/postinit.c:719 +#: utils/init/postinit.c:728 #, c-format msgid "no roles are defined in this database system" msgstr "в Ñтой ÑиÑтеме баз данных не Ñоздано ни одной роли" -#: utils/init/postinit.c:720 +#: utils/init/postinit.c:729 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "Ð’Ñ‹ должны немедленно выполнить CREATE USER \"%s\" CREATEUSER;." -#: utils/init/postinit.c:756 +#: utils/init/postinit.c:765 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "" "новые Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ не допуÑкаютÑÑ Ð² процеÑÑе оÑтановки БД" -#: utils/init/postinit.c:760 +#: utils/init/postinit.c:769 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "" "нужно быть Ñуперпользователем, чтобы подключитьÑÑ Ð² процеÑÑе оÑтановки БД" -#: utils/init/postinit.c:770 +#: utils/init/postinit.c:779 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "" "нужно быть Ñуперпользователем, чтобы подключитьÑÑ Ð² режиме двоичного " "обновлениÑ" -#: utils/init/postinit.c:784 +#: utils/init/postinit.c:793 #, c-format msgid "" "remaining connection slots are reserved for non-replication superuser " @@ -24482,34 +25927,34 @@ msgstr "" "оÑтавшиеÑÑ Ñлоты подключений зарезервированы Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ " "ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (не Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸)" -#: utils/init/postinit.c:794 +#: utils/init/postinit.c:803 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "" "Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑка процеÑÑа walsender требуетÑÑ Ñ€Ð¾Ð»ÑŒ репликации или права " "ÑуперпользователÑ" -#: utils/init/postinit.c:863 +#: utils/init/postinit.c:872 #, c-format msgid "database %u does not exist" -msgstr "база данных \"%u не ÑущеÑтвует" +msgstr "база данных %u не ÑущеÑтвует" -#: utils/init/postinit.c:952 +#: utils/init/postinit.c:961 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "Похоже, она только что была удалена или переименована." -#: utils/init/postinit.c:970 +#: utils/init/postinit.c:979 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "Подкаталог базы данных \"%s\" отÑутÑтвует." -#: utils/init/postinit.c:975 +#: utils/init/postinit.c:984 #, c-format msgid "could not access directory \"%s\": %m" msgstr "ошибка доÑтупа к каталогу \"%s\": %m" -#: utils/mb/conv.c:488 utils/mb/conv.c:679 +#: utils/mb/conv.c:488 utils/mb/conv.c:680 #, c-format msgid "invalid encoding number: %d" msgstr "неверный номер кодировки: %d" @@ -24526,44 +25971,49 @@ msgstr "неожиданный ID кодировки %d Ð´Ð»Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² Ñ msgid "unexpected encoding ID %d for WIN character sets" msgstr "неожиданный ID кодировки %d Ð´Ð»Ñ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð² Ñимволов WIN" +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "ICU не поддерживает кодировку \"%s\"" + #: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "Ñлишком длинное Ð¸Ð¼Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "преобразование %s <-> %s не поддерживаетÑÑ" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format msgid "" "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "" "Ñтандартной функции Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· кодировки \"%s\" в \"%s\" не ÑущеÑтвует" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "Строка из %d байт Ñлишком длинна Ð´Ð»Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "неверное Ð¸Ð¼Ñ Ð¸Ñходной кодировки: \"%s\"" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "неверное Ð¸Ð¼Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ результата: \"%s\"" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "недопуÑтимое байтовое значение Ð´Ð»Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ¸ \"%s\": 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "ошибка в bind_textdomain_codeset" @@ -24582,25 +26032,29 @@ msgstr "" "Ð´Ð»Ñ Ñимвола Ñ Ð¿Ð¾ÑледовательноÑтью байт %s из кодировки \"%s\" нет " "Ñквивалента в \"%s\"" -#: utils/misc/guc.c:574 +#: utils/misc/guc.c:572 msgid "Ungrouped" msgstr "Разное" -#: utils/misc/guc.c:576 +#: utils/misc/guc.c:574 msgid "File Locations" msgstr "РаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²" -#: utils/misc/guc.c:578 +#: utils/misc/guc.c:576 msgid "Connections and Authentication" msgstr "ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ аутентификациÑ" -#: utils/misc/guc.c:580 +#: utils/misc/guc.c:578 msgid "Connections and Authentication / Connection Settings" msgstr "ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ / Параметры подключений" +#: utils/misc/guc.c:580 +msgid "Connections and Authentication / Authentication" +msgstr "ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ / ÐутентификациÑ" + #: utils/misc/guc.c:582 -msgid "Connections and Authentication / Security and Authentication" -msgstr "ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ / БезопаÑноÑть и аутентификациÑ" +msgid "Connections and Authentication / SSL" +msgstr "ÐŸÐ¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ / SSL" #: utils/misc/guc.c:584 msgid "Resource Usage" @@ -24663,213 +26117,252 @@ msgid "Replication / Standby Servers" msgstr "Ð ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ / Резервные Ñерверы" #: utils/misc/guc.c:614 +msgid "Replication / Subscribers" +msgstr "Ð ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ / ПодпиÑчики" + +#: utils/misc/guc.c:616 msgid "Query Tuning" msgstr "ÐаÑтройка запроÑов" -#: utils/misc/guc.c:616 +#: utils/misc/guc.c:618 msgid "Query Tuning / Planner Method Configuration" msgstr "ÐаÑтройка запроÑов / ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð¾Ð² планировщика" -#: utils/misc/guc.c:618 +#: utils/misc/guc.c:620 msgid "Query Tuning / Planner Cost Constants" msgstr "ÐаÑтройка запроÑов / КонÑтанты ÑтоимоÑти Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ°" -#: utils/misc/guc.c:620 +#: utils/misc/guc.c:622 msgid "Query Tuning / Genetic Query Optimizer" msgstr "ÐаÑтройка запроÑов / ГенетичеÑкий оптимизатор запроÑов" -#: utils/misc/guc.c:622 +#: utils/misc/guc.c:624 msgid "Query Tuning / Other Planner Options" msgstr "ÐаÑтройка запроÑов / Другие параметры планировщика" -#: utils/misc/guc.c:624 +#: utils/misc/guc.c:626 msgid "Reporting and Logging" msgstr "Отчёты и протоколы" -#: utils/misc/guc.c:626 +#: utils/misc/guc.c:628 msgid "Reporting and Logging / Where to Log" msgstr "Отчёты и протоколы / Куда запиÑывать" -#: utils/misc/guc.c:628 +#: utils/misc/guc.c:630 msgid "Reporting and Logging / When to Log" msgstr "Отчёты и протоколы / Когда запиÑывать" -#: utils/misc/guc.c:630 +#: utils/misc/guc.c:632 msgid "Reporting and Logging / What to Log" msgstr "Отчёты и протоколы / Что запиÑывать" -#: utils/misc/guc.c:632 +#: utils/misc/guc.c:634 msgid "Process Title" msgstr "Заголовок процеÑÑа" -#: utils/misc/guc.c:634 +#: utils/misc/guc.c:636 msgid "Statistics" msgstr "СтатиÑтика" -#: utils/misc/guc.c:636 +#: utils/misc/guc.c:638 msgid "Statistics / Monitoring" msgstr "СтатиÑтика / Мониторинг" -#: utils/misc/guc.c:638 +#: utils/misc/guc.c:640 msgid "Statistics / Query and Index Statistics Collector" msgstr "СтатиÑтика / Сбор ÑтатиÑтики по запроÑам и индекÑам" -#: utils/misc/guc.c:640 +#: utils/misc/guc.c:642 msgid "Autovacuum" msgstr "ÐвтоочиÑтка" -#: utils/misc/guc.c:642 +#: utils/misc/guc.c:644 msgid "Client Connection Defaults" msgstr "Параметры клиентÑких ÑеанÑов по умолчанию" -#: utils/misc/guc.c:644 +#: utils/misc/guc.c:646 msgid "Client Connection Defaults / Statement Behavior" msgstr "Параметры клиентÑких подключений по умолчанию / Поведение команд" -#: utils/misc/guc.c:646 +#: utils/misc/guc.c:648 msgid "Client Connection Defaults / Locale and Formatting" msgstr "" "Параметры клиентÑких подключений по умолчанию / Ð¯Ð·Ñ‹ÐºÐ¾Ð²Ð°Ñ Ñреда и форматы" -#: utils/misc/guc.c:648 +#: utils/misc/guc.c:650 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "" "Параметры клиентÑких подключений по умолчанию / Предзагрузка разделÑемых " "библиотек" -#: utils/misc/guc.c:650 +#: utils/misc/guc.c:652 msgid "Client Connection Defaults / Other Defaults" msgstr "Параметры клиентÑких подключений по умолчанию / Другие параметры" -#: utils/misc/guc.c:652 +#: utils/misc/guc.c:654 msgid "Lock Management" msgstr "Управление блокировками" -#: utils/misc/guc.c:654 +#: utils/misc/guc.c:656 msgid "Version and Platform Compatibility" msgstr "СовмеÑтимоÑть Ñ Ñ€Ð°Ð·Ð½Ñ‹Ð¼Ð¸ верÑиÑми и платформами" -#: utils/misc/guc.c:656 +#: utils/misc/guc.c:658 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "ВерÑÐ¸Ñ Ð¸ ÑовмеÑтимоÑть платформ / Предыдущие верÑии PostgreSQL" -#: utils/misc/guc.c:658 +#: utils/misc/guc.c:660 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "ВерÑÐ¸Ñ Ð¸ ÑовмеÑтимоÑть платформ / Другие платформы и клиенты" -#: utils/misc/guc.c:660 +#: utils/misc/guc.c:662 msgid "Error Handling" msgstr "Обработка ошибок" -#: utils/misc/guc.c:662 +#: utils/misc/guc.c:664 msgid "Preset Options" msgstr "Предопределённые параметры" -#: utils/misc/guc.c:664 +#: utils/misc/guc.c:666 msgid "Customized Options" msgstr "ВнеÑиÑтемные параметры" -#: utils/misc/guc.c:666 +#: utils/misc/guc.c:668 msgid "Developer Options" msgstr "Параметры Ð´Ð»Ñ Ñ€Ð°Ð·Ñ€Ð°Ð±Ð¾Ñ‚Ñ‡Ð¸ÐºÐ¾Ð²" -#: utils/misc/guc.c:723 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." +#: utils/misc/guc.c:722 +msgid "" +"Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "" -"ДопуÑтимые единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого параметра - \"kB\", \"MB\", \"GB\" и " -"\"TB\"." +"ДопуÑтимые единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого параметра: \"B\", \"kB\", \"MB\", " +"\"GB\" и \"TB\"." -#: utils/misc/guc.c:750 +#: utils/misc/guc.c:764 msgid "" "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." msgstr "" "ДопуÑтимые единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñтого параметра - \"ms\", \"s\", \"min\", " "\"h\" и \"d\"." -#: utils/misc/guc.c:809 +#: utils/misc/guc.c:823 msgid "Enables the planner's use of sequential-scan plans." msgstr "" "Разрешает планировщику иÑпользовать планы поÑледовательного ÑканированиÑ." -#: utils/misc/guc.c:818 +#: utils/misc/guc.c:832 msgid "Enables the planner's use of index-scan plans." msgstr "Разрешает планировщику иÑпользовать планы ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ индекÑу." -#: utils/misc/guc.c:827 +#: utils/misc/guc.c:841 msgid "Enables the planner's use of index-only-scan plans." msgstr "Разрешает планировщику иÑпользовать планы ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ индекÑа." -#: utils/misc/guc.c:836 +#: utils/misc/guc.c:850 msgid "Enables the planner's use of bitmap-scan plans." msgstr "" "Разрешает планировщику иÑпользовать планы ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ битовой карте." -#: utils/misc/guc.c:845 +#: utils/misc/guc.c:859 msgid "Enables the planner's use of TID scan plans." msgstr "Разрешает планировщику иÑпользовать планы ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ TID." -#: utils/misc/guc.c:854 +#: utils/misc/guc.c:868 msgid "Enables the planner's use of explicit sort steps." msgstr "Разрешает планировщику иÑпользовать шаги Ñ Ñвной Ñортировкой." -#: utils/misc/guc.c:863 +#: utils/misc/guc.c:877 msgid "Enables the planner's use of hashed aggregation plans." msgstr "Разрешает планировщику иÑпользовать планы Ð°Ð³Ñ€ÐµÐ³Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ хешу." -#: utils/misc/guc.c:872 +#: utils/misc/guc.c:886 msgid "Enables the planner's use of materialization." msgstr "Разрешает планировщику иÑпользовать материализацию." -#: utils/misc/guc.c:881 +#: utils/misc/guc.c:895 msgid "Enables the planner's use of nested-loop join plans." msgstr "" "Разрешает планировщику иÑпользовать планы ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñ‹Ð¼Ð¸ циклами." -#: utils/misc/guc.c:890 +#: utils/misc/guc.c:904 msgid "Enables the planner's use of merge join plans." msgstr "Разрешает планировщику иÑпользовать планы ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑлиÑнием." -#: utils/misc/guc.c:899 +#: utils/misc/guc.c:913 msgid "Enables the planner's use of hash join plans." msgstr "Разрешает планировщику иÑпользовать планы ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ хешу." -#: utils/misc/guc.c:908 +#: utils/misc/guc.c:922 msgid "Enables the planner's use of gather merge plans." msgstr "Разрешает планировщику иÑпользовать планы Ñбора ÑлиÑнием." -#: utils/misc/guc.c:918 +#: utils/misc/guc.c:931 +msgid "Enables partitionwise join." +msgstr "Включает ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ ÑƒÑ‡Ñ‘Ñ‚Ð¾Ð¼ ÑекционированиÑ." + +#: utils/misc/guc.c:940 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Включает агрегирование и группировку Ñ ÑƒÑ‡Ñ‘Ñ‚Ð¾Ð¼ ÑекционированиÑ." + +#: utils/misc/guc.c:949 +msgid "Enables the planner's use of parallel append plans." +msgstr "Разрешает планировщику иÑпользовать планы параллельного добавлениÑ." + +#: utils/misc/guc.c:958 +msgid "Enables the planner's use of parallel hash plans." +msgstr "" +"Разрешает планировщику иÑпользовать планы параллельного ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ хешу." + +#: utils/misc/guc.c:967 +msgid "Enable plan-time and run-time partition pruning." +msgstr "" +"Включает уÑтранение Ñекций во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов." + +#: utils/misc/guc.c:968 +msgid "" +"Allows the query planner and executor to compare partition bounds to " +"conditions in the query to determine which partitions must be scanned." +msgstr "" +"Разрешает планировщику и иÑполнителю запроÑов ÑопоÑтавлÑть границы Ñекций Ñ " +"уÑловиÑми в запроÑе и выделÑть отдельные Ñекции Ð´Ð»Ñ ÑканированиÑ." + +#: utils/misc/guc.c:978 msgid "Enables genetic query optimization." msgstr "Включает генетичеÑкую оптимизацию запроÑов." -#: utils/misc/guc.c:919 +#: utils/misc/guc.c:979 msgid "This algorithm attempts to do planning without exhaustive searching." msgstr "Этот алгоритм пытаетÑÑ Ð¿Ð¾Ñтроить план без полного перебора." -#: utils/misc/guc.c:929 +#: utils/misc/guc.c:989 msgid "Shows whether the current user is a superuser." msgstr "Показывает, ÑвлÑетÑÑ Ð»Ð¸ текущий пользователь Ñуперпользователем." -#: utils/misc/guc.c:939 +#: utils/misc/guc.c:999 msgid "Enables advertising the server via Bonjour." msgstr "Включает объÑвление Ñервера поÑредÑтвом Bonjour." -#: utils/misc/guc.c:948 +#: utils/misc/guc.c:1008 msgid "Collects transaction commit time." msgstr "ЗапиÑывает Ð²Ñ€ÐµÐ¼Ñ Ñ„Ð¸ÐºÑации транзакций." -#: utils/misc/guc.c:957 +#: utils/misc/guc.c:1017 msgid "Enables SSL connections." msgstr "Разрешает SSL-подключениÑ." -#: utils/misc/guc.c:966 +#: utils/misc/guc.c:1026 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Также иÑпользовать ssl_passphrase_command при перезагрузке Ñервера." + +#: utils/misc/guc.c:1035 msgid "Give priority to server ciphersuite order." msgstr "Ðазначает более приоритетным набор шифров Ñервера." -#: utils/misc/guc.c:975 +#: utils/misc/guc.c:1044 msgid "Forces synchronization of updates to disk." msgstr "ÐŸÑ€Ð¸Ð½ÑƒÐ´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ изменений на диÑк." -#: utils/misc/guc.c:976 +#: utils/misc/guc.c:1045 msgid "" "The server will use the fsync() system call in several places to make sure " "that updates are physically written to disk. This insures that a database " @@ -24880,11 +26373,11 @@ msgstr "" "физичеÑкой запиÑи данных на диÑк. Это позволит привеÑти клаÑтер БД в " "целоÑтное ÑоÑтоÑние поÑле отказа ОС или оборудованиÑ." -#: utils/misc/guc.c:987 +#: utils/misc/guc.c:1056 msgid "Continues processing after a checksum failure." msgstr "Продолжает обработку при ошибке контрольной Ñуммы." -#: utils/misc/guc.c:988 +#: utils/misc/guc.c:1057 msgid "" "Detection of a checksum failure normally causes PostgreSQL to report an " "error, aborting the current transaction. Setting ignore_checksum_failure to " @@ -24898,11 +26391,11 @@ msgstr "" "что может привеÑти к ÑбоÑм или другим Ñерьёзным проблемам. Это имеет меÑто, " "только еÑли включён контроль целоÑтноÑти Ñтраниц." -#: utils/misc/guc.c:1002 +#: utils/misc/guc.c:1071 msgid "Continues processing past damaged page headers." msgstr "Продолжает обработку при повреждении заголовков Ñтраниц." -#: utils/misc/guc.c:1003 +#: utils/misc/guc.c:1072 msgid "" "Detection of a damaged page header normally causes PostgreSQL to report an " "error, aborting the current transaction. Setting zero_damaged_pages to true " @@ -24916,12 +26409,12 @@ msgstr "" "продолжит работу. Это приведёт к потере данных, а именно Ñтрок в " "повреждённой Ñтранице." -#: utils/misc/guc.c:1016 +#: utils/misc/guc.c:1085 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "" "ЗапиÑÑŒ полных Ñтраниц в WAL при первом изменении поÑле контрольной точки." -#: utils/misc/guc.c:1017 +#: utils/misc/guc.c:1086 msgid "" "A page write in process during an operating system crash might be only " "partially written to disk. During recovery, the row changes stored in WAL " @@ -24934,7 +26427,7 @@ msgstr "" "при первом изменении поÑле контрольной точки, что позволÑет полноÑтью " "воÑÑтановить данные." -#: utils/misc/guc.c:1030 +#: utils/misc/guc.c:1099 msgid "" "Writes full pages to WAL when first modified after a checkpoint, even for a " "non-critical modifications." @@ -24942,75 +26435,75 @@ msgstr "" "ЗапиÑÑŒ полных Ñтраниц в WAL при первом изменении поÑле контрольной точки, " "даже при некритичеÑких изменениÑÑ…." -#: utils/misc/guc.c:1040 +#: utils/misc/guc.c:1109 msgid "Compresses full-page writes written in WAL file." msgstr "Сжимать данные при запиÑи полных Ñтраниц в журнал." -#: utils/misc/guc.c:1050 +#: utils/misc/guc.c:1119 msgid "Logs each checkpoint." msgstr "Протоколировать каждую контрольную точку." -#: utils/misc/guc.c:1059 +#: utils/misc/guc.c:1128 msgid "Logs each successful connection." msgstr "Протоколировать уÑтанавливаемые ÑоединениÑ." -#: utils/misc/guc.c:1068 +#: utils/misc/guc.c:1137 msgid "Logs end of a session, including duration." msgstr "Протоколировать конец ÑеанÑа, Ð¾Ñ‚Ð¼ÐµÑ‡Ð°Ñ Ð´Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ñть." -#: utils/misc/guc.c:1077 +#: utils/misc/guc.c:1146 msgid "Logs each replication command." msgstr "Протоколировать каждую команду репликации." -#: utils/misc/guc.c:1086 +#: utils/misc/guc.c:1155 msgid "Shows whether the running server has assertion checks enabled." msgstr "Показывает, включены ли проверки иÑтинноÑти на работающем Ñервере." -#: utils/misc/guc.c:1101 +#: utils/misc/guc.c:1170 msgid "Terminate session on any error." msgstr "Завершать ÑеанÑÑ‹ при любой ошибке." -#: utils/misc/guc.c:1110 +#: utils/misc/guc.c:1179 msgid "Reinitialize server after backend crash." msgstr "ПерезапуÑкать ÑиÑтему БД при аварии Ñерверного процеÑÑа." -#: utils/misc/guc.c:1120 +#: utils/misc/guc.c:1189 msgid "Logs the duration of each completed SQL statement." msgstr "Протоколировать длительноÑть каждого выполненного SQL-оператора." -#: utils/misc/guc.c:1129 +#: utils/misc/guc.c:1198 msgid "Logs each query's parse tree." msgstr "Протоколировать дерево разбора Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ запроÑа." -#: utils/misc/guc.c:1138 +#: utils/misc/guc.c:1207 msgid "Logs each query's rewritten parse tree." msgstr "Протоколировать перезапиÑанное дерево разбора Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ запроÑа." -#: utils/misc/guc.c:1147 +#: utils/misc/guc.c:1216 msgid "Logs each query's execution plan." msgstr "Протоколировать план Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ запроÑа." -#: utils/misc/guc.c:1156 +#: utils/misc/guc.c:1225 msgid "Indents parse and plan tree displays." msgstr "ОтÑтупы при отображении деревьев разбора и плана запроÑов." -#: utils/misc/guc.c:1165 +#: utils/misc/guc.c:1234 msgid "Writes parser performance statistics to the server log." msgstr "ЗапиÑÑŒ ÑтатиÑтики разбора запроÑов в протокол Ñервера." -#: utils/misc/guc.c:1174 +#: utils/misc/guc.c:1243 msgid "Writes planner performance statistics to the server log." msgstr "ЗапиÑÑŒ ÑтатиÑтики Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² протокол Ñервера." -#: utils/misc/guc.c:1183 +#: utils/misc/guc.c:1252 msgid "Writes executor performance statistics to the server log." msgstr "ЗапиÑÑŒ ÑтатиÑтики Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов в протокол Ñервера." -#: utils/misc/guc.c:1192 +#: utils/misc/guc.c:1261 msgid "Writes cumulative performance statistics to the server log." msgstr "ЗапиÑÑŒ общей ÑтатиÑтики производительноÑти в протокол Ñервера." -#: utils/misc/guc.c:1202 +#: utils/misc/guc.c:1271 msgid "" "Logs system resource usage statistics (memory and CPU) on various B-tree " "operations." @@ -25018,11 +26511,11 @@ msgstr "" "ФикÑировать ÑтатиÑтику иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑиÑтемных реÑурÑов (памÑти и " "процеÑÑора) при различных операциÑÑ… Ñ b-деревом." -#: utils/misc/guc.c:1214 +#: utils/misc/guc.c:1283 msgid "Collects information about executing commands." msgstr "Собирает информацию о выполнÑющихÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ…." -#: utils/misc/guc.c:1215 +#: utils/misc/guc.c:1284 msgid "" "Enables the collection of information on the currently executing command of " "each session, along with the time at which that command began execution." @@ -25030,60 +26523,60 @@ msgstr "" "Включает Ñбор информации о командах, выполнÑющихÑÑ Ð²Ð¾ вÑех ÑеанÑах, а также " "Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿ÑƒÑка команды." -#: utils/misc/guc.c:1225 +#: utils/misc/guc.c:1294 msgid "Collects statistics on database activity." msgstr "Собирает ÑтатиÑтику активноÑти в БД." -#: utils/misc/guc.c:1234 +#: utils/misc/guc.c:1303 msgid "Collects timing statistics for database I/O activity." msgstr "Собирает ÑтатиÑтику по времени активноÑти ввода/вывода." -#: utils/misc/guc.c:1244 +#: utils/misc/guc.c:1313 msgid "Updates the process title to show the active SQL command." msgstr "Выводит в заголовок процеÑÑа активную SQL-команду." -#: utils/misc/guc.c:1245 +#: utils/misc/guc.c:1314 msgid "" "Enables updating of the process title every time a new SQL command is " "received by the server." msgstr "Отражает в заголовке процеÑÑа каждую SQL-команду, поÑтупающую Ñерверу." -#: utils/misc/guc.c:1258 +#: utils/misc/guc.c:1327 msgid "Starts the autovacuum subprocess." msgstr "ЗапуÑкает подпроцеÑÑ Ð°Ð²Ñ‚Ð¾Ð¾Ñ‡Ð¸Ñтки." -#: utils/misc/guc.c:1268 +#: utils/misc/guc.c:1337 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "Генерирует отладочные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ LISTEN и NOTIFY." -#: utils/misc/guc.c:1280 +#: utils/misc/guc.c:1349 msgid "Emits information about lock usage." msgstr "Выдавать информацию о применÑемых блокировках." -#: utils/misc/guc.c:1290 +#: utils/misc/guc.c:1359 msgid "Emits information about user lock usage." msgstr "Выдавать информацию о применÑемых пользовательÑких блокировках." -#: utils/misc/guc.c:1300 +#: utils/misc/guc.c:1369 msgid "Emits information about lightweight lock usage." msgstr "Выдавать информацию о применÑемых лёгких блокировках." -#: utils/misc/guc.c:1310 +#: utils/misc/guc.c:1379 msgid "" "Dumps information about all current locks when a deadlock timeout occurs." msgstr "" -"Выводить информацию обо вÑех текущих блокировках в Ñлучае таймаута при " +"Выводить информацию обо вÑех текущих блокировках в Ñлучае тайм-аута при " "взаимоблокировке." -#: utils/misc/guc.c:1322 +#: utils/misc/guc.c:1391 msgid "Logs long lock waits." msgstr "Протоколировать длительные Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð² блокировках." -#: utils/misc/guc.c:1332 +#: utils/misc/guc.c:1401 msgid "Logs the host name in the connection logs." msgstr "ЗапиÑывать Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð° в протоколы подключений." -#: utils/misc/guc.c:1333 +#: utils/misc/guc.c:1402 msgid "" "By default, connection logs only show the IP address of the connecting host. " "If you want them to show the host name you can turn this on, but depending " @@ -25095,11 +26588,11 @@ msgstr "" "параметр, но учтите, что Ñто может значительно повлиÑть на " "производительноÑть." -#: utils/misc/guc.c:1344 +#: utils/misc/guc.c:1413 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "Обрабатывать \"expr=NULL\" как \"expr IS NULL\"." -#: utils/misc/guc.c:1345 +#: utils/misc/guc.c:1414 msgid "" "When turned on, expressions of the form expr = NULL (or NULL = expr) are " "treated as expr IS NULL, that is, they return true if expr evaluates to the " @@ -25111,25 +26604,25 @@ msgstr "" "Ñовпадает Ñ NULL, и false в противном Ñлучае. По правилам expr = NULL вÑегда " "должно возвращать null (неопределённоÑть)." -#: utils/misc/guc.c:1357 +#: utils/misc/guc.c:1426 msgid "Enables per-database user names." msgstr "Включает ÑвÑзывание имён пользователей Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ данных." -#: utils/misc/guc.c:1366 +#: utils/misc/guc.c:1435 msgid "Sets the default read-only status of new transactions." msgstr "" "УÑтанавливает режим \"только чтение\" по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… транзакций." -#: utils/misc/guc.c:1375 +#: utils/misc/guc.c:1444 msgid "Sets the current transaction's read-only status." msgstr "УÑтанавливает режим \"только чтение\" Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ транзакции." -#: utils/misc/guc.c:1385 +#: utils/misc/guc.c:1454 msgid "Sets the default deferrable status of new transactions." msgstr "" "УÑтанавливает режим отложенного Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… транзакций." -#: utils/misc/guc.c:1394 +#: utils/misc/guc.c:1463 msgid "" "Whether to defer a read-only serializable transaction until it can be " "executed with no possible serialization failures." @@ -25137,25 +26630,25 @@ msgstr "" "ОпределÑет, откладывать ли Ñериализуемую транзакцию \"только чтение\" до " "момента, когда Ñбой Ñериализации будет иÑключён." -#: utils/misc/guc.c:1404 +#: utils/misc/guc.c:1473 msgid "Enable row security." msgstr "Включает защиту на уровне Ñтрок." -#: utils/misc/guc.c:1405 +#: utils/misc/guc.c:1474 msgid "When enabled, row security will be applied to all users." msgstr "" "Когда включена, защита на уровне Ñтрок раÑпроÑтранÑетÑÑ Ð½Ð° вÑех " "пользователей." -#: utils/misc/guc.c:1413 +#: utils/misc/guc.c:1482 msgid "Check function bodies during CREATE FUNCTION." msgstr "ПроверÑть тело функций в момент CREATE FUNCTION." -#: utils/misc/guc.c:1422 +#: utils/misc/guc.c:1491 msgid "Enable input of NULL elements in arrays." msgstr "Разрешать ввод Ñлементов NULL в маÑÑивах." -#: utils/misc/guc.c:1423 +#: utils/misc/guc.c:1492 msgid "" "When turned on, unquoted NULL in an array input value means a null value; " "otherwise it is taken literally." @@ -25163,68 +26656,68 @@ msgstr "" "Когда Ñтот параметр включён, NULL без кавычек при вводе в маÑÑив " "воÑпринимаетÑÑ ÐºÐ°Ðº значение NULL, иначе - как Ñтрока." -#: utils/misc/guc.c:1433 +#: utils/misc/guc.c:1502 msgid "Create new tables with OIDs by default." msgstr "По умолчанию Ñоздавать новые таблицы Ñо Ñтолбцом OID." -#: utils/misc/guc.c:1442 +#: utils/misc/guc.c:1511 msgid "" "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "" "ЗапуÑкает подпроцеÑÑ Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ stderr и/или csv-файлов и запиÑи в файлы " "протоколов." -#: utils/misc/guc.c:1451 +#: utils/misc/guc.c:1520 msgid "Truncate existing log files of same name during log rotation." msgstr "" "Очищать уже ÑущеÑтвующий файл Ñ Ñ‚ÐµÐ¼ же именем при прокручивании протокола." -#: utils/misc/guc.c:1462 +#: utils/misc/guc.c:1531 msgid "Emit information about resource usage in sorting." msgstr "Выдавать ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± иÑпользовании реÑурÑов при Ñортировке." -#: utils/misc/guc.c:1476 +#: utils/misc/guc.c:1545 msgid "Generate debugging output for synchronized scanning." msgstr "Выдавать отладочные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñинхронного ÑканированиÑ." -#: utils/misc/guc.c:1491 +#: utils/misc/guc.c:1560 msgid "Enable bounded sorting using heap sort." msgstr "" "Разрешить ограниченную Ñортировку Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸ÐµÐ¼ пирамидальной Ñортировки." -#: utils/misc/guc.c:1504 +#: utils/misc/guc.c:1573 msgid "Emit WAL-related debugging output." msgstr "Выдавать отладочные ÑообщениÑ, ÑвÑзанные Ñ WAL." -#: utils/misc/guc.c:1516 +#: utils/misc/guc.c:1585 msgid "Datetimes are integer based." msgstr "ЦелочиÑÐ»ÐµÐ½Ð½Ð°Ñ Ñ€ÐµÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð°Ñ‚Ñ‹/времени." -#: utils/misc/guc.c:1527 +#: utils/misc/guc.c:1596 msgid "" "Sets whether Kerberos and GSSAPI user names should be treated as case-" "insensitive." msgstr "" "Включает региÑтронезавиÑимую обработку имён пользователей Kerberos и GSSAPI." -#: utils/misc/guc.c:1537 +#: utils/misc/guc.c:1606 msgid "Warn about backslash escapes in ordinary string literals." msgstr "ÐŸÑ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ Ð¾ ÑпецÑимволах '\\' в обычных Ñтроках." -#: utils/misc/guc.c:1547 +#: utils/misc/guc.c:1616 msgid "Causes '...' strings to treat backslashes literally." msgstr "Включает буквальную обработку Ñимволов '\\' в Ñтроках '...'." -#: utils/misc/guc.c:1558 +#: utils/misc/guc.c:1627 msgid "Enable synchronized sequential scans." msgstr "Включить Ñинхронизацию поÑледовательного ÑканированиÑ." -#: utils/misc/guc.c:1568 +#: utils/misc/guc.c:1637 msgid "Allows connections and queries during recovery." msgstr "" "Разрешает принимать новые Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ запроÑÑ‹ в процеÑÑе воÑÑтановлениÑ." -#: utils/misc/guc.c:1578 +#: utils/misc/guc.c:1647 msgid "" "Allows feedback from a hot standby to the primary that will avoid query " "conflicts." @@ -25232,15 +26725,15 @@ msgstr "" "Разрешает обратную ÑвÑзь Ñервера горÑчего резерва Ñ Ð¾Ñновным Ð´Ð»Ñ " "Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð»Ð¸ÐºÑ‚Ð¾Ð² при длительных запроÑах." -#: utils/misc/guc.c:1588 +#: utils/misc/guc.c:1657 msgid "Allows modifications of the structure of system tables." msgstr "Разрешает модифицировать Ñтруктуру ÑиÑтемных таблиц." -#: utils/misc/guc.c:1599 +#: utils/misc/guc.c:1668 msgid "Disables reading from system indexes." msgstr "Запрещает иÑпользование ÑиÑтемных индекÑов." -#: utils/misc/guc.c:1600 +#: utils/misc/guc.c:1669 msgid "" "It does not prevent updating the indexes, so it is safe to use. The worst " "consequence is slowness." @@ -25248,14 +26741,14 @@ msgstr "" "При Ñтом индекÑÑ‹ продолжают обновлÑтьÑÑ, так что данное поведение безопаÑно. " "Худшее ÑледÑтвие - замедление." -#: utils/misc/guc.c:1611 +#: utils/misc/guc.c:1680 msgid "" "Enables backward compatibility mode for privilege checks on large objects." msgstr "" "Включает режим обратной ÑовмеÑтимоÑти при проверке привилегий Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… " "объектов." -#: utils/misc/guc.c:1612 +#: utils/misc/guc.c:1681 msgid "" "Skips privilege checks when reading or modifying large objects, for " "compatibility with PostgreSQL releases prior to 9.0." @@ -25263,35 +26756,73 @@ msgstr "" "ПропуÑкает проверки привилегий при чтении или изменении больших объектов " "(Ð´Ð»Ñ ÑовмеÑтимоÑти Ñ Ð²ÐµÑ€ÑиÑми PostgreSQL до 9.0)." -#: utils/misc/guc.c:1622 +#: utils/misc/guc.c:1691 msgid "" "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "" "Выдаёт предупреждение о конÑтрукциÑÑ…, поведение которых изменилоÑÑŒ поÑле " "PostgreSQL 9.4." -#: utils/misc/guc.c:1632 +#: utils/misc/guc.c:1701 msgid "When generating SQL fragments, quote all identifiers." msgstr "" "Ð“ÐµÐ½ÐµÑ€Ð¸Ñ€ÑƒÑ SQL-фрагменты, заключать вÑе идентификаторы в двойные кавычки." -#: utils/misc/guc.c:1642 +#: utils/misc/guc.c:1711 msgid "Shows whether data checksums are turned on for this cluster." msgstr "Показывает, включён ли в Ñтом клаÑтере контроль целоÑтноÑти данных." -#: utils/misc/guc.c:1653 +#: utils/misc/guc.c:1722 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "" "ДобавлÑть поÑледовательный номер в ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ syslog во избежание Ð¿Ð¾Ð´Ð°Ð²Ð»ÐµÐ½Ð¸Ñ " "повторов." -#: utils/misc/guc.c:1663 +#: utils/misc/guc.c:1732 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "" "Разбивать ÑообщениÑ, передаваемые в syslog, по Ñтрокам размером не больше " "1024 байт." -#: utils/misc/guc.c:1682 +#: utils/misc/guc.c:1742 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" +"ОпределÑет, будут ли узлы Ñбора и Ñбора ÑлиÑнием также выполнÑть подпланы." + +#: utils/misc/guc.c:1743 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" +"Должны ли узлы Ñбора также выполнÑть подпланы или только Ñобирать кортежи?" + +#: utils/misc/guc.c:1752 +msgid "Allow JIT compilation." +msgstr "Включить JIT-компилÑцию." + +#: utils/misc/guc.c:1762 +msgid "Register JIT compiled function with debugger." +msgstr "РегиÑтрировать JIT-Ñкомпилированные функции в отладчике." + +#: utils/misc/guc.c:1779 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Выводить битовый код LLVM Ð´Ð»Ñ Ð¾Ð±Ð»ÐµÐ³Ñ‡ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ð»Ð°Ð´ÐºÐ¸ JIT." + +#: utils/misc/guc.c:1790 +msgid "Allow JIT compilation of expressions." +msgstr "Включить JIT-компилÑцию выражений." + +#: utils/misc/guc.c:1801 +msgid "Register JIT compiled function with perf profiler." +msgstr "РегиÑтрировать JIT-компилируемые функции в профилировщике perf." + +#: utils/misc/guc.c:1818 +msgid "Allow JIT compilation of tuple deforming." +msgstr "Разрешить JIT-компилÑцию кода Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ñ€Ñ‚ÐµÐ¶ÐµÐ¹." + +#: utils/misc/guc.c:1829 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Продолжать работу поÑле ошибки при Ñохранении файлов данных на диÑке." + +#: utils/misc/guc.c:1847 msgid "" "Forces a switch to the next WAL file if a new file has not been started " "within N seconds." @@ -25299,33 +26830,33 @@ msgstr "" "Принудительно переключатьÑÑ Ð½Ð° Ñледующий файл WAL, еÑли начать новый файл за " "N Ñекунд не удалоÑÑŒ." -#: utils/misc/guc.c:1693 +#: utils/misc/guc.c:1858 msgid "Waits N seconds on connection startup after authentication." msgstr "Ждать N Ñекунд при подключении поÑле проверки подлинноÑти." -#: utils/misc/guc.c:1694 utils/misc/guc.c:2217 +#: utils/misc/guc.c:1859 utils/misc/guc.c:2410 msgid "This allows attaching a debugger to the process." msgstr "Это позволÑет подключить к процеÑÑу отладчик." -#: utils/misc/guc.c:1703 +#: utils/misc/guc.c:1868 msgid "Sets the default statistics target." -msgstr "УÑтанавливает целевое ограничение ÑтатиÑтики по умолчанию." +msgstr "УÑтанавливает ориентир ÑтатиÑтики по умолчанию." -#: utils/misc/guc.c:1704 +#: utils/misc/guc.c:1869 msgid "" "This applies to table columns that have not had a column-specific target set " "via ALTER TABLE SET STATISTICS." msgstr "" -"Это значение раÑпроÑтранÑетÑÑ Ð½Ð° Ñтолбцы таблицы, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… целевое " -"ограничение не задано Ñвно через ALTER TABLE SET STATISTICS." +"Это значение раÑпроÑтранÑетÑÑ Ð½Ð° Ñтолбцы таблицы, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… ориентир " +"ÑтатиÑтики не задан Ñвно через ALTER TABLE SET STATISTICS." -#: utils/misc/guc.c:1713 +#: utils/misc/guc.c:1878 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "" "Задаёт предел Ð´Ð»Ñ ÑпиÑка FROM, при превышении которого подзапроÑÑ‹ не " "ÑворачиваютÑÑ." -#: utils/misc/guc.c:1715 +#: utils/misc/guc.c:1880 msgid "" "The planner will merge subqueries into upper queries if the resulting FROM " "list would have no more than this many items." @@ -25333,13 +26864,13 @@ msgstr "" "Планировщик объединит вложенные запроÑÑ‹ Ñ Ð²Ð½ÐµÑˆÐ½Ð¸Ð¼Ð¸, еÑли в полученном ÑпиÑке " "FROM будет не больше заданного чиÑла Ñлементов." -#: utils/misc/guc.c:1725 +#: utils/misc/guc.c:1890 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "" "Задаёт предел Ð´Ð»Ñ ÑпиÑка FROM, при превышении которого конÑтрукции JOIN " "ÑохранÑÑŽÑ‚ÑÑ." -#: utils/misc/guc.c:1727 +#: utils/misc/guc.c:1892 msgid "" "The planner will flatten explicit JOIN constructs into lists of FROM items " "whenever a list of no more than this many items would result." @@ -25347,34 +26878,34 @@ msgstr "" "Планировщик будет ÑноÑить Ñвные конÑтрукции JOIN в ÑпиÑки FROM, пока в " "результирующем ÑпиÑке не больше заданного чиÑла Ñлементов." -#: utils/misc/guc.c:1737 +#: utils/misc/guc.c:1902 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "" "Задаёт предел Ð´Ð»Ñ ÑпиÑка FROM, при превышении которого применÑетÑÑ GEQO." -#: utils/misc/guc.c:1746 +#: utils/misc/guc.c:1911 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "" "GEQO: оценка уÑилий Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ, Ð·Ð°Ð´Ð°ÑŽÑ‰Ð°Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию Ð´Ð»Ñ " "других параметров GEQO." -#: utils/misc/guc.c:1755 +#: utils/misc/guc.c:1920 msgid "GEQO: number of individuals in the population." msgstr "GEQO: чиÑло оÑобей в популÑции." -#: utils/misc/guc.c:1756 utils/misc/guc.c:1765 +#: utils/misc/guc.c:1921 utils/misc/guc.c:1930 msgid "Zero selects a suitable default value." msgstr "При нуле выбираетÑÑ Ð¿Ð¾Ð´Ñ…Ð¾Ð´Ñщее значение по умолчанию." -#: utils/misc/guc.c:1764 +#: utils/misc/guc.c:1929 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: чиÑло итераций алгоритма." -#: utils/misc/guc.c:1775 +#: utils/misc/guc.c:1940 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "Задаёт интервал Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð² блокировке до проверки на взаимоблокировку." -#: utils/misc/guc.c:1786 +#: utils/misc/guc.c:1951 msgid "" "Sets the maximum delay before canceling queries when a hot standby server is " "processing archived WAL data." @@ -25382,7 +26913,7 @@ msgstr "" "Задаёт макÑимальную задержку до отмены запроÑа, когда Ñервер горÑчего " "резерва обрабатывает данные WAL из архива." -#: utils/misc/guc.c:1797 +#: utils/misc/guc.c:1962 msgid "" "Sets the maximum delay before canceling queries when a hot standby server is " "processing streamed WAL data." @@ -25390,58 +26921,58 @@ msgstr "" "Задаёт макÑимальную задержку до отмены запроÑа, когда Ñервер горÑчего " "резерва обрабатывает данные WAL из потока." -#: utils/misc/guc.c:1808 +#: utils/misc/guc.c:1973 msgid "" "Sets the maximum interval between WAL receiver status reports to the primary." msgstr "Задаёт макÑимальный интервал Ð´Ð»Ñ Ð¾Ñ‚Ñ‡Ñ‘Ñ‚Ð¾Ð² о ÑоÑтоÑнии получателей WAL." -#: utils/misc/guc.c:1819 +#: utils/misc/guc.c:1984 msgid "Sets the maximum wait time to receive data from the primary." msgstr "" "Задаёт предельное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñервера." -#: utils/misc/guc.c:1830 +#: utils/misc/guc.c:1995 msgid "Sets the maximum number of concurrent connections." msgstr "Задаёт макÑимально возможное чиÑло подключений." -#: utils/misc/guc.c:1840 +#: utils/misc/guc.c:2006 msgid "Sets the number of connection slots reserved for superusers." msgstr "" "ОпределÑет, Ñколько Ñлотов подключений забронировано Ð´Ð»Ñ Ñуперпользователей." -#: utils/misc/guc.c:1854 +#: utils/misc/guc.c:2020 msgid "Sets the number of shared memory buffers used by the server." msgstr "Задаёт количеÑтво буферов в разделÑемой памÑти, иÑпользуемых Ñервером." -#: utils/misc/guc.c:1865 +#: utils/misc/guc.c:2031 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "Задаёт предельное чиÑло временных буферов на один ÑеанÑ." -#: utils/misc/guc.c:1876 +#: utils/misc/guc.c:2042 msgid "Sets the TCP port the server listens on." msgstr "Задаёт TCP-порт Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñервера." -#: utils/misc/guc.c:1886 +#: utils/misc/guc.c:2052 msgid "Sets the access permissions of the Unix-domain socket." -msgstr "Задаёт права доÑтупа Ð´Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð½Ð¾Ð³Ð¾ Ñокета Unix." +msgstr "Задаёт права доÑтупа Ð´Ð»Ñ Unix-Ñокета." -#: utils/misc/guc.c:1887 +#: utils/misc/guc.c:2053 msgid "" "Unix-domain sockets use the usual Unix file system permission set. The " "parameter value is expected to be a numeric mode specification in the form " "accepted by the chmod and umask system calls. (To use the customary octal " "format the number must start with a 0 (zero).)" msgstr "" -"Ð”Ð»Ñ Ð´Ð¾Ð¼ÐµÐ½Ð½Ñ‹Ñ… Ñокетов иÑпользуетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¹ набор разрешений, как в файловых " +"Ð”Ð»Ñ Unix-Ñокетов иÑпользуетÑÑ Ð¾Ð±Ñ‹Ñ‡Ð½Ñ‹Ð¹ набор разрешений, как в файловых " "ÑиÑтемах Unix. Значение параметра указываетÑÑ Ð² чиÑловом виде, " "воÑпринимаемом ÑиÑтемными функциÑми chmod и umask. (Чтобы иÑпользовать " "привычный воÑьмеричный формат, добавьте в начало ноль (0).)" -#: utils/misc/guc.c:1901 +#: utils/misc/guc.c:2067 msgid "Sets the file permissions for log files." msgstr "Задаёт права доÑтупа к файлам протоколов." -#: utils/misc/guc.c:1902 +#: utils/misc/guc.c:2068 msgid "" "The parameter value is expected to be a numeric mode specification in the " "form accepted by the chmod and umask system calls. (To use the customary " @@ -25451,11 +26982,25 @@ msgstr "" "функциÑми chmod и umask. (Чтобы иÑпользовать привычный воÑьмеричный формат, " "добавьте в начало ноль (0).)" -#: utils/misc/guc.c:1915 +#: utils/misc/guc.c:2082 +msgid "Mode of the data directory." +msgstr "Режим каталога данных." + +#: utils/misc/guc.c:2083 +msgid "" +"The parameter value is a numeric mode specification in the form accepted by " +"the chmod and umask system calls. (To use the customary octal format the " +"number must start with a 0 (zero).)" +msgstr "" +"Значение параметра указываетÑÑ Ð² чиÑловом виде, воÑпринимаемом ÑиÑтемными " +"функциÑми chmod и umask. (Чтобы иÑпользовать привычный воÑьмеричный формат, " +"добавьте в начало ноль (0).)" + +#: utils/misc/guc.c:2096 msgid "Sets the maximum memory to be used for query workspaces." msgstr "Задаёт предельный объём памÑти Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ñ… проÑтранÑтв запроÑов." -#: utils/misc/guc.c:1916 +#: utils/misc/guc.c:2097 msgid "" "This much memory can be used by each internal sort operation and hash table " "before switching to temporary disk files." @@ -25463,131 +27008,120 @@ msgstr "" "Такой объём памÑти может иÑпользоватьÑÑ ÐºÐ°Ð¶Ð´Ð¾Ð¹ внутренней операцией " "Ñортировки и таблицей хешей до Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½Ð° временные файлы на диÑке." -#: utils/misc/guc.c:1928 +#: utils/misc/guc.c:2109 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "Задаёт предельный объём памÑти Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¹ по обÑлуживанию." -#: utils/misc/guc.c:1929 +#: utils/misc/guc.c:2110 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "ПодразумеваютÑÑ Ð² чаÑтноÑти операции VACUUM и CREATE INDEX." -#: utils/misc/guc.c:1939 -msgid "" -"Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "" -"Задаёт предельное чиÑло кортежей, Ñортируемое поÑредÑтвом алгоритма выбора Ñ " -"замещением." - -#: utils/misc/guc.c:1940 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "Когда кортежей больше Ñтого количеÑтва, будет применÑтьÑÑ quicksort." - -#: utils/misc/guc.c:1954 +#: utils/misc/guc.c:2125 msgid "Sets the maximum stack depth, in kilobytes." msgstr "Задаёт макÑимальную глубину Ñтека (в КБ)." -#: utils/misc/guc.c:1965 +#: utils/misc/guc.c:2136 msgid "Limits the total size of all temporary files used by each process." msgstr "" "Ограничивает общий размер вÑех временных файлов, доÑтупный Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ " "процеÑÑа." -#: utils/misc/guc.c:1966 +#: utils/misc/guc.c:2137 msgid "-1 means no limit." msgstr "-1 отключает ограничение." -#: utils/misc/guc.c:1976 +#: utils/misc/guc.c:2147 msgid "Vacuum cost for a page found in the buffer cache." msgstr "СтоимоÑть очиÑтки Ð´Ð»Ñ Ñтраницы, найденной в кеше." -#: utils/misc/guc.c:1986 +#: utils/misc/guc.c:2157 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "СтоимоÑть очиÑтки Ð´Ð»Ñ Ñтраницы, не найденной в кеше." -#: utils/misc/guc.c:1996 +#: utils/misc/guc.c:2167 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "СтоимоÑть очиÑтки Ð´Ð»Ñ Ñтраницы, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð½Ðµ была \"грÑзной\"." -#: utils/misc/guc.c:2006 +#: utils/misc/guc.c:2177 msgid "Vacuum cost amount available before napping." msgstr "Ð¡ÑƒÐ¼Ð¼Ð°Ñ€Ð½Ð°Ñ ÑтоимоÑть очиÑтки, при которой нужна передышка." -#: utils/misc/guc.c:2016 +#: utils/misc/guc.c:2187 msgid "Vacuum cost delay in milliseconds." msgstr "Задержка очиÑтки (в миллиÑекундах)." -#: utils/misc/guc.c:2027 +#: utils/misc/guc.c:2198 msgid "Vacuum cost delay in milliseconds, for autovacuum." msgstr "Задержка очиÑтки Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ñ‡Ð¸Ñтки (в миллиÑекундах)." -#: utils/misc/guc.c:2038 +#: utils/misc/guc.c:2209 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "" "Ð¡ÑƒÐ¼Ð¼Ð°Ñ€Ð½Ð°Ñ ÑтоимоÑть очиÑтки, при которой нужна передышка, Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ñ‡Ð¸Ñтки." -#: utils/misc/guc.c:2048 +#: utils/misc/guc.c:2219 msgid "" "Sets the maximum number of simultaneously open files for each server process." msgstr "" "Задаёт предельное чиÑло одновременно открытых файлов Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñерверного " "процеÑÑа." -#: utils/misc/guc.c:2061 +#: utils/misc/guc.c:2232 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "Задаёт предельное чиÑло одновременно подготовленных транзакций." -#: utils/misc/guc.c:2072 +#: utils/misc/guc.c:2243 msgid "Sets the minimum OID of tables for tracking locks." msgstr "Задаёт минимальный OID таблиц, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… отÑлеживаютÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¸." -#: utils/misc/guc.c:2073 +#: utils/misc/guc.c:2244 msgid "Is used to avoid output on system tables." msgstr "ПрименÑетÑÑ Ð´Ð»Ñ Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ ÑиÑтемных таблиц." -#: utils/misc/guc.c:2082 +#: utils/misc/guc.c:2253 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "Задаёт OID таблицы Ð´Ð»Ñ Ð±ÐµÐ·ÑƒÑловного отÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð¾Ðº." -#: utils/misc/guc.c:2094 +#: utils/misc/guc.c:2265 msgid "Sets the maximum allowed duration of any statement." msgstr "Задаёт предельную длительноÑть Ð´Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ оператора." -#: utils/misc/guc.c:2095 utils/misc/guc.c:2106 utils/misc/guc.c:2117 +#: utils/misc/guc.c:2266 utils/misc/guc.c:2277 utils/misc/guc.c:2288 msgid "A value of 0 turns off the timeout." -msgstr "Ðулевое значение отключает таймаут." +msgstr "Ðулевое значение отключает тайм-аут." -#: utils/misc/guc.c:2105 +#: utils/misc/guc.c:2276 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "Задаёт макÑимальную продолжительноÑть Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð¾Ðº." -#: utils/misc/guc.c:2116 +#: utils/misc/guc.c:2287 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "Задаёт предельно допуÑтимую длительноÑть Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñтаивающих транзакций." -#: utils/misc/guc.c:2127 +#: utils/misc/guc.c:2298 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "" "Минимальный возраÑÑ‚ Ñтрок таблицы, при котором VACUUM может их заморозить." -#: utils/misc/guc.c:2137 +#: utils/misc/guc.c:2308 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "" "ВозраÑÑ‚, при котором VACUUM должен Ñканировать вÑÑŽ таблицу Ñ Ñ†ÐµÐ»ÑŒÑŽ " "заморозить кортежи." -#: utils/misc/guc.c:2147 +#: utils/misc/guc.c:2318 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "" "Минимальный возраÑÑ‚, при котором VACUUM будет замораживать MultiXactId в " "Ñтроке таблицы." -#: utils/misc/guc.c:2157 +#: utils/misc/guc.c:2328 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "" "ВозраÑÑ‚ multixact, при котором VACUUM должен Ñканировать вÑÑŽ таблицу Ñ Ñ†ÐµÐ»ÑŒÑŽ " "заморозить кортежи." -#: utils/misc/guc.c:2167 +#: utils/misc/guc.c:2338 msgid "" "Number of transactions by which VACUUM and HOT cleanup should be deferred, " "if any." @@ -25595,11 +27129,11 @@ msgstr "" "ОпределÑет, на Ñколько транзакций Ñледует задержать Ñтарые Ñтроки, выполнÑÑ " "VACUUM или \"горÑчее\" обновление." -#: utils/misc/guc.c:2180 +#: utils/misc/guc.c:2351 msgid "Sets the maximum number of locks per transaction." msgstr "Задаёт предельное чиÑло блокировок на транзакцию." -#: utils/misc/guc.c:2181 +#: utils/misc/guc.c:2352 msgid "" "The shared lock table is sized on the assumption that at most " "max_locks_per_transaction * max_connections distinct objects will need to be " @@ -25609,11 +27143,11 @@ msgstr "" "один момент времени потребуетÑÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ не больше чем " "max_locks_per_transaction * max_connections различных объектов." -#: utils/misc/guc.c:2192 +#: utils/misc/guc.c:2363 msgid "Sets the maximum number of predicate locks per transaction." msgstr "Задаёт предельное чиÑло предикатных блокировок на транзакцию." -#: utils/misc/guc.c:2193 +#: utils/misc/guc.c:2364 msgid "" "The shared predicate lock table is sized on the assumption that at most " "max_pred_locks_per_transaction * max_connections distinct objects will need " @@ -25623,39 +27157,68 @@ msgstr "" "предположениÑ, что в один момент времени потребуетÑÑ Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ не больше " "чем max_pred_locks_per_transaction * max_connections различных объектов." -#: utils/misc/guc.c:2204 +#: utils/misc/guc.c:2375 +msgid "" +"Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "" +"Задаёт макÑимальное чиÑло Ñтраниц и кортежей, блокируемых предикатными " +"блокировками в одном отношении." + +#: utils/misc/guc.c:2376 +msgid "" +"If more than this total of pages and tuples in the same relation are locked " +"by a connection, those locks are replaced by a relation-level lock." +msgstr "" +"ЕÑли одним Ñоединением блокируетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñтого общего чиÑла Ñтраниц и " +"кортежей, Ñти блокировки заменÑÑŽÑ‚ÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¾Ð¹ на уровне отношениÑ." + +#: utils/misc/guc.c:2386 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "" +"Задаёт макÑимальное чиÑло кортежей, блокируемых предикатными блокировками в " +"одной Ñтранице." + +#: utils/misc/guc.c:2387 +msgid "" +"If more than this number of tuples on the same page are locked by a " +"connection, those locks are replaced by a page-level lock." +msgstr "" +"ЕÑли одним Ñоединением блокируетÑÑ Ð±Ð¾Ð»ÑŒÑˆÐµ Ñтого чиÑла кортежей на одной " +"Ñтранице, Ñти блокировки заменÑÑŽÑ‚ÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²ÐºÐ¾Ð¹ на уровне Ñтраницы." + +#: utils/misc/guc.c:2397 msgid "Sets the maximum allowed time to complete client authentication." msgstr "Ограничивает времÑ, за которое клиент должен пройти аутентификацию." -#: utils/misc/guc.c:2216 +#: utils/misc/guc.c:2409 msgid "Waits N seconds on connection startup before authentication." msgstr "Ждать N Ñекунд при подключении до проверки подлинноÑти." -#: utils/misc/guc.c:2227 +#: utils/misc/guc.c:2420 msgid "Sets the number of WAL files held for standby servers." msgstr "ОпределÑет, Ñколько файлов WAL нужно ÑохранÑть Ð´Ð»Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð½Ñ‹Ñ… Ñерверов." -#: utils/misc/guc.c:2237 +#: utils/misc/guc.c:2430 msgid "Sets the minimum size to shrink the WAL to." msgstr "Задаёт минимальный размер WAL при Ñжатии." -#: utils/misc/guc.c:2248 +#: utils/misc/guc.c:2442 msgid "Sets the WAL size that triggers a checkpoint." msgstr "Задаёт размер WAL, при котором инициируетÑÑ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ°." -#: utils/misc/guc.c:2259 +#: utils/misc/guc.c:2454 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "" "Задаёт макÑимальное Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÐ¶Ð´Ñƒ автоматичеÑкими контрольными точками WAL." -#: utils/misc/guc.c:2270 +#: utils/misc/guc.c:2465 msgid "" "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "" "Выдаёт предупреждениÑ, когда Ñегменты контрольных точек заполнÑÑŽÑ‚ÑÑ Ð·Ð° Ñто " "времÑ." -#: utils/misc/guc.c:2272 +#: utils/misc/guc.c:2467 msgid "" "Write a message to the server log if checkpoints caused by the filling of " "checkpoint segment files happens more frequently than this number of " @@ -25665,41 +27228,41 @@ msgstr "" "переполнением файлов Ñегментов, проиÑходÑÑ‚ за Ñтолько Ñекунд. Ðулевое " "значение отключает Ñти предупреждениÑ." -#: utils/misc/guc.c:2284 utils/misc/guc.c:2441 utils/misc/guc.c:2468 +#: utils/misc/guc.c:2479 utils/misc/guc.c:2636 utils/misc/guc.c:2664 msgid "" "Number of pages after which previously performed writes are flushed to disk." msgstr "" "ЧиÑло Ñтраниц, по доÑтижении которого ранее выполненные операции запиÑи " "ÑбраÑываютÑÑ Ð½Ð° диÑк." -#: utils/misc/guc.c:2295 +#: utils/misc/guc.c:2490 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "Задаёт чиÑло буферов диÑковых Ñтраниц в разделÑемой памÑти Ð´Ð»Ñ WAL." -#: utils/misc/guc.c:2306 +#: utils/misc/guc.c:2501 msgid "Time between WAL flushes performed in the WAL writer." msgstr "Задержка между ÑброÑом WAL в процеÑÑе, запиÑывающем WAL." -#: utils/misc/guc.c:2317 +#: utils/misc/guc.c:2512 msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "" "Объём WAL, обработанный пишущим WAL процеÑÑом, при котором инициируетÑÑ " "ÑÐ±Ñ€Ð¾Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° на диÑк." -#: utils/misc/guc.c:2329 +#: utils/misc/guc.c:2524 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "" "Задаёт предельное чиÑло одновременно работающих процеÑÑов передачи WAL." -#: utils/misc/guc.c:2340 +#: utils/misc/guc.c:2535 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "Задаёт предельное чиÑло одновременно ÑущеÑтвующих Ñлотов репликации." -#: utils/misc/guc.c:2350 +#: utils/misc/guc.c:2545 msgid "Sets the maximum time to wait for WAL replication." msgstr "Задаёт предельное Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ WAL." -#: utils/misc/guc.c:2361 +#: utils/misc/guc.c:2556 msgid "" "Sets the delay in microseconds between transaction commit and flushing WAL " "to disk." @@ -25707,18 +27270,18 @@ msgstr "" "Задаёт задержку в микроÑекундах между фикÑированием транзакций и ÑброÑом WAL " "на диÑк." -#: utils/misc/guc.c:2373 +#: utils/misc/guc.c:2568 msgid "" "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "" "Задаёт минимальное чиÑло одновременно открытых транзакций Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ " "commit_delay." -#: utils/misc/guc.c:2384 +#: utils/misc/guc.c:2579 msgid "Sets the number of digits displayed for floating-point values." msgstr "Задаёт чиÑло выводимых цифр Ð´Ð»Ñ Ñ‡Ð¸Ñел Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой." -#: utils/misc/guc.c:2385 +#: utils/misc/guc.c:2580 msgid "" "This affects real, double precision, and geometric data types. The parameter " "value is added to the standard number of digits (FLT_DIG or DBL_DIG as " @@ -25727,17 +27290,17 @@ msgstr "" "Этот параметр отноÑитÑÑ Ðº типам real, double и geometric. Значение параметра " "добавлÑетÑÑ Ðº Ñтандартному чиÑлу цифр (FLT_DIG или DBL_DIG)." -#: utils/misc/guc.c:2396 +#: utils/misc/guc.c:2591 msgid "Sets the minimum execution time above which statements will be logged." msgstr "" "Задаёт предельное Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð°, при превышении которого он " "фикÑируетÑÑ Ð² протоколе." -#: utils/misc/guc.c:2398 +#: utils/misc/guc.c:2593 msgid "Zero prints all queries. -1 turns this feature off." msgstr "При 0 протоколируютÑÑ Ð²Ñе запроÑÑ‹; -1 отключает Ñти ÑообщениÑ." -#: utils/misc/guc.c:2408 +#: utils/misc/guc.c:2603 msgid "" "Sets the minimum execution time above which autovacuum actions will be " "logged." @@ -25745,22 +27308,22 @@ msgstr "" "Задаёт предельное Ð²Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð°Ð²Ñ‚Ð¾Ð¾Ñ‡Ð¸Ñтки, при превышении которого Ñта " "Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ„Ð¸ÐºÑируетÑÑ Ð² протоколе." -#: utils/misc/guc.c:2410 +#: utils/misc/guc.c:2605 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "" "При 0 протоколируютÑÑ Ð²Ñе операции автоочиÑтки; -1 отключает Ñти ÑообщениÑ." -#: utils/misc/guc.c:2420 +#: utils/misc/guc.c:2615 msgid "Background writer sleep time between rounds." msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾ÑÑ‚Ð¾Ñ Ð² процеÑÑе фоновой запиÑи между подходами." -#: utils/misc/guc.c:2431 +#: utils/misc/guc.c:2626 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "" "МакÑимальное чиÑло LRU-Ñтраниц, ÑбраÑываемых за один подход, в процеÑÑе " "фоновой запиÑи." -#: utils/misc/guc.c:2454 +#: utils/misc/guc.c:2649 msgid "" "Number of simultaneous requests that can be handled efficiently by the disk " "subsystem." @@ -25768,100 +27331,100 @@ msgstr "" "ЧиÑло одновременных запроÑов, которые могут быть Ñффективно обработаны " "диÑковой подÑиÑтемой." -#: utils/misc/guc.c:2455 +#: utils/misc/guc.c:2650 msgid "" "For RAID arrays, this should be approximately the number of drive spindles " "in the array." msgstr "" "Ð”Ð»Ñ RAID-маÑÑивов Ñто примерно равно чиÑлу физичеÑких диÑков в маÑÑиве." -#: utils/misc/guc.c:2481 +#: utils/misc/guc.c:2677 msgid "Maximum number of concurrent worker processes." msgstr "Задаёт макÑимально возможное чиÑло рабочих процеÑÑов." -#: utils/misc/guc.c:2493 +#: utils/misc/guc.c:2689 msgid "Maximum number of logical replication worker processes." msgstr "" "Задаёт макÑимально возможное чиÑло рабочих процеÑÑов логичеÑкой репликации." -#: utils/misc/guc.c:2505 +#: utils/misc/guc.c:2701 msgid "Maximum number of table synchronization workers per subscription." msgstr "" "Задаёт макÑимально возможное чиÑло процеÑÑов Ñинхронизации таблиц Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð¹ " "подпиÑки." -#: utils/misc/guc.c:2515 +#: utils/misc/guc.c:2711 msgid "Automatic log file rotation will occur after N minutes." msgstr "ÐвтоматичеÑÐºÐ°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ° файла протокола через каждые N минут." -#: utils/misc/guc.c:2526 +#: utils/misc/guc.c:2722 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "" "ÐвтоматичеÑÐºÐ°Ñ Ð¿Ñ€Ð¾ÐºÑ€ÑƒÑ‚ÐºÐ° файла протокола при выходе за предел N килобайт." -#: utils/misc/guc.c:2537 +#: utils/misc/guc.c:2733 msgid "Shows the maximum number of function arguments." msgstr "Показывает макÑимально возможное чиÑло аргументов функций." -#: utils/misc/guc.c:2548 +#: utils/misc/guc.c:2744 msgid "Shows the maximum number of index keys." msgstr "Показывает макÑимально возможное чиÑло ключей в индекÑе." -#: utils/misc/guc.c:2559 +#: utils/misc/guc.c:2755 msgid "Shows the maximum identifier length." msgstr "Показывает макÑимально возможную длину идентификатора." -#: utils/misc/guc.c:2570 +#: utils/misc/guc.c:2766 msgid "Shows the size of a disk block." msgstr "Показывает размер диÑкового блока." -#: utils/misc/guc.c:2581 +#: utils/misc/guc.c:2777 msgid "Shows the number of pages per disk file." msgstr "Показывает чиÑло Ñтраниц в одном файле." -#: utils/misc/guc.c:2592 +#: utils/misc/guc.c:2788 msgid "Shows the block size in the write ahead log." msgstr "Показывает размер блока в журнале WAL." -#: utils/misc/guc.c:2603 +#: utils/misc/guc.c:2799 msgid "" "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "" "Задаёт Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¸ перед повторной попыткой Ð¾Ð±Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ðº WAL поÑле неудачи." -#: utils/misc/guc.c:2615 -msgid "Shows the number of pages per write ahead log segment." -msgstr "Показывает чиÑло Ñтраниц в одном Ñегменте журнала WAL." +#: utils/misc/guc.c:2811 +msgid "Shows the size of write ahead log segments." +msgstr "Показывает размер Ñегментов журнала предзапиÑи." -#: utils/misc/guc.c:2628 +#: utils/misc/guc.c:2824 msgid "Time to sleep between autovacuum runs." msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾ÑÑ‚Ð¾Ñ Ð¼ÐµÐ¶Ð´Ñƒ запуÑками автоочиÑтки." -#: utils/misc/guc.c:2638 +#: utils/misc/guc.c:2834 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "Минимальное чиÑло изменений или удалений кортежей, вызывающее очиÑтку." -#: utils/misc/guc.c:2647 +#: utils/misc/guc.c:2843 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "" "Минимальное чиÑло добавлений, изменений или удалений кортежей, вызывающее " "анализ." -#: utils/misc/guc.c:2657 +#: utils/misc/guc.c:2853 msgid "" "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "" "ВозраÑÑ‚, при котором необходима автоочиÑтка таблицы Ð´Ð»Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ " -"наложений ID транзакций." +"Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ ID транзакций." -#: utils/misc/guc.c:2668 +#: utils/misc/guc.c:2864 msgid "" "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "" "ВозраÑÑ‚ multixact, при котором необходима автоочиÑтка таблицы Ð´Ð»Ñ " -"Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ð¹ идентификаторов multixact." +"Ð¿Ñ€ÐµÐ´Ð¾Ñ‚Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ð·Ð°Ñ†Ð¸ÐºÐ»Ð¸Ð²Ð°Ð½Ð¸Ñ multixact." -#: utils/misc/guc.c:2678 +#: utils/misc/guc.c:2874 msgid "" "Sets the maximum number of simultaneously running autovacuum worker " "processes." @@ -25869,23 +27432,30 @@ msgstr "" "Задаёт предельное чиÑло одновременно выполнÑющихÑÑ Ñ€Ð°Ð±Ð¾Ñ‡Ð¸Ñ… процеÑÑов " "автоочиÑтки." -#: utils/misc/guc.c:2688 +#: utils/misc/guc.c:2884 +msgid "" +"Sets the maximum number of parallel processes per maintenance operation." +msgstr "" +"Задаёт макÑимальное чиÑло параллельных процеÑÑов на одну операцию " +"обÑлуживаниÑ." + +#: utils/misc/guc.c:2894 msgid "Sets the maximum number of parallel processes per executor node." msgstr "Задаёт макÑимальное чиÑло параллельных процеÑÑов на узел иÑполнителÑ." -#: utils/misc/guc.c:2698 +#: utils/misc/guc.c:2904 msgid "" -"Sets the maximum number of parallel workers than can be active at one time." +"Sets the maximum number of parallel workers that can be active at one time." msgstr "" "Задаёт макÑимальное чиÑло параллельных процеÑÑов, которые могут быть активны " "одновременно." -#: utils/misc/guc.c:2708 +#: utils/misc/guc.c:2914 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "" "Задаёт предельный объём памÑти Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ рабочего процеÑÑа автоочиÑтки." -#: utils/misc/guc.c:2719 +#: utils/misc/guc.c:2925 msgid "" "Time before a snapshot is too old to read pages changed after the snapshot " "was taken." @@ -25893,33 +27463,33 @@ msgstr "" "Срок, по иÑтечении которого Ñнимок ÑчитаетÑÑ Ñлишком Ñтарым Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ " "Ñтраниц, изменённых поÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñнимка." -#: utils/misc/guc.c:2720 +#: utils/misc/guc.c:2926 msgid "A value of -1 disables this feature." msgstr "Значение -1 отключает Ñто поведение." -#: utils/misc/guc.c:2730 +#: utils/misc/guc.c:2936 msgid "Time between issuing TCP keepalives." msgstr "Интервал между TCP-пакетами пульÑа (keep-alive)." -#: utils/misc/guc.c:2731 utils/misc/guc.c:2742 +#: utils/misc/guc.c:2937 utils/misc/guc.c:2948 msgid "A value of 0 uses the system default." msgstr "При нулевом значении дейÑтвует ÑиÑтемный параметр." -#: utils/misc/guc.c:2741 +#: utils/misc/guc.c:2947 msgid "Time between TCP keepalive retransmits." msgstr "Интервал между повторениÑми TCP-пакетов пульÑа (keep-alive)." -#: utils/misc/guc.c:2752 +#: utils/misc/guc.c:2958 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "" "Повторное ÑоглаÑование SSL более не поддерживаетÑÑ; единÑтвенное допуÑтимое " "значение - 0." -#: utils/misc/guc.c:2763 +#: utils/misc/guc.c:2969 msgid "Maximum number of TCP keepalive retransmits." msgstr "МакÑимальное чиÑло повторений TCP-пакетов пульÑа (keep-alive)." -#: utils/misc/guc.c:2764 +#: utils/misc/guc.c:2970 msgid "" "This controls the number of consecutive keepalive retransmits that can be " "lost before a connection is considered dead. A value of 0 uses the system " @@ -25929,29 +27499,30 @@ msgstr "" "прежде чем Ñоединение будет ÑчитатьÑÑ Ð¿Ñ€Ð¾Ð¿Ð°Ð²ÑˆÐ¸Ð¼. При нулевом значении " "дейÑтвует ÑиÑтемный параметр." -#: utils/misc/guc.c:2775 +#: utils/misc/guc.c:2981 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "Ограничивает результат точного поиÑка Ñ Ð¸Ñпользованием GIN." -#: utils/misc/guc.c:2786 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "ПодÑказывает планировщику примерный размер диÑкового кеша." +#: utils/misc/guc.c:2992 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "ПодÑказывает планировщику примерный общий размер кешей данных." -#: utils/misc/guc.c:2787 +#: utils/misc/guc.c:2993 msgid "" -"That is, the portion of the kernel's disk cache that will be used for " -"PostgreSQL data files. This is measured in disk pages, which are normally 8 " -"kB each." +"That is, the total size of the caches (kernel cache and shared buffers) used " +"for PostgreSQL data files. This is measured in disk pages, which are " +"normally 8 kB each." msgstr "" -"ПодразумеваетÑÑ Ñ‡Ð°Ñть диÑкового кеша в Ñдре ОС, которую займут файлы данных " -"PostgreSQL. Размер задаётÑÑ Ð² диÑковых Ñтраницах (обычно Ñто 8 КБ)." +"ПодразумеваетÑÑ Ð¾Ð±Ñ‰Ð¸Ð¹ размер кешей (кеша Ñдра и общих буферов), в которые " +"попадают файлы данных PostgreSQL. Размер задаётÑÑ Ð² диÑковых Ñтраницах " +"(обычно Ñто 8 КБ)." -#: utils/misc/guc.c:2799 +#: utils/misc/guc.c:3004 msgid "Sets the minimum amount of table data for a parallel scan." msgstr "" "Задаёт минимальный объём данных в таблице Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ ÑканированиÑ." -#: utils/misc/guc.c:2800 +#: utils/misc/guc.c:3005 msgid "" "If the planner estimates that it will read a number of table pages too small " "to reach this limit, a parallel scan will not be considered." @@ -25960,12 +27531,12 @@ msgstr "" "задано Ñтим ограничением, он иÑключает параллельное Ñканирование из " "раÑÑмотрениÑ." -#: utils/misc/guc.c:2810 +#: utils/misc/guc.c:3015 msgid "Sets the minimum amount of index data for a parallel scan." msgstr "" "Задаёт минимальный объём данных в индекÑе Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ð¾Ð³Ð¾ ÑканированиÑ." -#: utils/misc/guc.c:2811 +#: utils/misc/guc.c:3016 msgid "" "If the planner estimates that it will read a number of index pages too small " "to reach this limit, a parallel scan will not be considered." @@ -25974,35 +27545,35 @@ msgstr "" "задано Ñтим ограничением, он иÑключает параллельное Ñканирование из " "раÑÑмотрениÑ." -#: utils/misc/guc.c:2822 +#: utils/misc/guc.c:3027 msgid "Shows the server version as an integer." msgstr "Показывает верÑию Ñервера в виде целого чиÑла." -#: utils/misc/guc.c:2833 +#: utils/misc/guc.c:3038 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "" "ФикÑирует в протоколе превышение временными файлами заданного размера (в КБ)." -#: utils/misc/guc.c:2834 +#: utils/misc/guc.c:3039 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "" "При 0 отмечаютÑÑ Ð²Ñе файлы; при -1 Ñти ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡Ð°ÑŽÑ‚ÑÑ (по умолчанию)." -#: utils/misc/guc.c:2844 +#: utils/misc/guc.c:3049 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "Задаёт размер, резервируемый Ð´Ð»Ñ pg_stat_activity.query (в байтах)." -#: utils/misc/guc.c:2859 +#: utils/misc/guc.c:3060 msgid "Sets the maximum size of the pending list for GIN index." msgstr "Задаёт макÑимальный размер ÑпиÑка-очереди Ð´Ð»Ñ GIN-индекÑа." -#: utils/misc/guc.c:2879 +#: utils/misc/guc.c:3080 msgid "" "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти поÑледовательного Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñтраницы." -#: utils/misc/guc.c:2889 +#: utils/misc/guc.c:3090 msgid "" "Sets the planner's estimate of the cost of a nonsequentially fetched disk " "page." @@ -26010,13 +27581,13 @@ msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти непоÑледовательного Ñ‡Ñ‚ÐµÐ½Ð¸Ñ " "Ñтраницы." -#: utils/misc/guc.c:2899 +#: utils/misc/guc.c:3100 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти обработки каждого кортежа " "(Ñтроки)." -#: utils/misc/guc.c:2909 +#: utils/misc/guc.c:3110 msgid "" "Sets the planner's estimate of the cost of processing each index entry " "during an index scan." @@ -26024,7 +27595,7 @@ msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти обработки каждого Ñлемента " "индекÑа в процеÑÑе ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа." -#: utils/misc/guc.c:2919 +#: utils/misc/guc.c:3120 msgid "" "Sets the planner's estimate of the cost of processing each operator or " "function call." @@ -26032,7 +27603,7 @@ msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти обработки каждого оператора или " "вызова функции." -#: utils/misc/guc.c:2929 +#: utils/misc/guc.c:3130 msgid "" "Sets the planner's estimate of the cost of passing each tuple (row) from " "worker to master backend." @@ -26040,7 +27611,7 @@ msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти передачи каждого кортежа (Ñтроки) " "от рабочего процеÑÑа обÑлуживающему." -#: utils/misc/guc.c:2939 +#: utils/misc/guc.c:3140 msgid "" "Sets the planner's estimate of the cost of starting up worker processes for " "parallel query." @@ -26048,32 +27619,58 @@ msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир ÑтоимоÑти запуÑка рабочих процеÑÑов Ð´Ð»Ñ " "параллельного Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа." -#: utils/misc/guc.c:2950 +#: utils/misc/guc.c:3151 +msgid "Perform JIT compilation if query is more expensive." +msgstr "СтоимоÑть запроÑа, при превышении которой производитÑÑ JIT-компилÑциÑ." + +#: utils/misc/guc.c:3152 +msgid "-1 disables JIT compilation." +msgstr "-1 отключает JIT-компилÑцию." + +#: utils/misc/guc.c:3161 +msgid "Optimize JITed functions if query is more expensive." +msgstr "" +"СтоимоÑть запроÑа, при превышении которой оптимизируютÑÑ JIT-" +"Ñкомпилированные функции." + +#: utils/misc/guc.c:3162 +msgid "-1 disables optimization." +msgstr "-1 отключает оптимизацию." + +#: utils/misc/guc.c:3171 +msgid "Perform JIT inlining if query is more expensive." +msgstr "СтоимоÑть запроÑа, при которой выполнÑетÑÑ Ð²Ñтраивание JIT." + +#: utils/misc/guc.c:3172 +msgid "-1 disables inlining." +msgstr "-1 отключает вÑтраивание кода." + +#: utils/misc/guc.c:3181 msgid "" "Sets the planner's estimate of the fraction of a cursor's rows that will be " "retrieved." msgstr "" "Задаёт Ð´Ð»Ñ Ð¿Ð»Ð°Ð½Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ° ориентир доли требуемых Ñтрок курÑора в общем чиÑле." -#: utils/misc/guc.c:2961 +#: utils/misc/guc.c:3192 msgid "GEQO: selective pressure within the population." msgstr "GEQO: Ñелективное давление в популÑции." -#: utils/misc/guc.c:2971 +#: utils/misc/guc.c:3202 msgid "GEQO: seed for random path selection." msgstr "GEQO: отправное значение Ð´Ð»Ñ Ñлучайного выбора пути." -#: utils/misc/guc.c:2981 +#: utils/misc/guc.c:3212 msgid "Multiple of the average buffer usage to free per round." msgstr "" "Множитель Ð´Ð»Ñ Ñреднего чиÑла иÑпользованных буферов, определÑющий чиÑло " "буферов, оÑвобождаемых за один подход." -#: utils/misc/guc.c:2991 +#: utils/misc/guc.c:3222 msgid "Sets the seed for random-number generation." msgstr "Задаёт отправное значение Ð´Ð»Ñ Ð³ÐµÐ½ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° Ñлучайных чиÑел." -#: utils/misc/guc.c:3002 +#: utils/misc/guc.c:3233 msgid "" "Number of tuple updates or deletes prior to vacuum as a fraction of " "reltuples." @@ -26081,7 +27678,7 @@ msgstr "" "Отношение чиÑла обновлений или удалений кортежей к reltuples, определÑющее " "потребноÑть в очиÑтке." -#: utils/misc/guc.c:3011 +#: utils/misc/guc.c:3242 msgid "" "Number of tuple inserts, updates, or deletes prior to analyze as a fraction " "of reltuples." @@ -26089,7 +27686,7 @@ msgstr "" "Отношение чиÑла добавлений, обновлений или удалений кортежей к reltuples, " "определÑющее потребноÑть в анализе." -#: utils/misc/guc.c:3021 +#: utils/misc/guc.c:3252 msgid "" "Time spent flushing dirty buffers during checkpoint, as fraction of " "checkpoint interval." @@ -26097,53 +27694,60 @@ msgstr "" "Отношение продолжительноÑти ÑброÑа \"грÑзных\" буферов во Ð²Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð¾Ð¹ " "точки к интервалу контрольных точек." -#: utils/misc/guc.c:3040 +#: utils/misc/guc.c:3262 +msgid "" +"Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "" +"Отношение чиÑла добавлений кортежей к reltuples, определÑющее потребноÑть в " +"очиÑтке индекÑа." + +#: utils/misc/guc.c:3281 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "Задаёт команду оболочки, вызываемую Ð´Ð»Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ð¸ файла WAL." -#: utils/misc/guc.c:3050 +#: utils/misc/guc.c:3291 msgid "Sets the client's character set encoding." msgstr "Задаёт кодировку Ñимволов, иÑпользуемую клиентом." -#: utils/misc/guc.c:3061 +#: utils/misc/guc.c:3302 msgid "Controls information prefixed to each log line." msgstr "ОпределÑет Ñодержимое префикÑа каждой Ñтроки протокола." -#: utils/misc/guc.c:3062 +#: utils/misc/guc.c:3303 msgid "If blank, no prefix is used." msgstr "При пуÑтом значении Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ñ‚Ð°ÐºÐ¶Ðµ отÑутÑтвует." -#: utils/misc/guc.c:3071 +#: utils/misc/guc.c:3312 msgid "Sets the time zone to use in log messages." msgstr "Задаёт чаÑовой поÑÑ Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° времени в ÑообщениÑÑ… протокола." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3322 msgid "Sets the display format for date and time values." msgstr "УÑтанавливает формат вывода дат и времени." -#: utils/misc/guc.c:3082 +#: utils/misc/guc.c:3323 msgid "Also controls interpretation of ambiguous date inputs." msgstr "Также помогает разбирать неоднозначно заданные вводимые даты." -#: utils/misc/guc.c:3093 +#: utils/misc/guc.c:3334 msgid "Sets the default tablespace to create tables and indexes in." msgstr "" "Задаёт табличное проÑтранÑтво по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… таблиц и индекÑов." -#: utils/misc/guc.c:3094 +#: utils/misc/guc.c:3335 msgid "An empty string selects the database's default tablespace." msgstr "При пуÑтом значении иÑпользуетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ð¾Ðµ проÑтранÑтво базы данных." -#: utils/misc/guc.c:3104 +#: utils/misc/guc.c:3345 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "" "Задаёт табличное проÑтранÑтво(а) Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… таблиц и файлов Ñортировки." -#: utils/misc/guc.c:3115 +#: utils/misc/guc.c:3356 msgid "Sets the path for dynamically loadable modules." msgstr "Задаёт путь Ð´Ð»Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑки загружаемых модулей." -#: utils/misc/guc.c:3116 +#: utils/misc/guc.c:3357 msgid "" "If a dynamically loadable module needs to be opened and the specified name " "does not have a directory component (i.e., the name does not contain a " @@ -26153,79 +27757,79 @@ msgstr "" "указан путь (нет Ñимвола '/'), ÑиÑтема будет иÑкать Ñтот файл в заданном " "пути." -#: utils/misc/guc.c:3129 +#: utils/misc/guc.c:3370 msgid "Sets the location of the Kerberos server key file." msgstr "Задаёт размещение файла Ñ ÐºÐ»ÑŽÑ‡Ð¾Ð¼ Kerberos Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñервера." -#: utils/misc/guc.c:3140 +#: utils/misc/guc.c:3381 msgid "Sets the Bonjour service name." msgstr "Задаёт название Ñлужбы Bonjour." -#: utils/misc/guc.c:3152 +#: utils/misc/guc.c:3393 msgid "Shows the collation order locale." msgstr "Показывает правило Ñортировки." -#: utils/misc/guc.c:3163 +#: utils/misc/guc.c:3404 msgid "Shows the character classification and case conversion locale." msgstr "Показывает правило клаÑÑификации Ñимволов и Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ€ÐµÐ³Ð¸Ñтра." -#: utils/misc/guc.c:3174 +#: utils/misc/guc.c:3415 msgid "Sets the language in which messages are displayed." msgstr "Задаёт Ñзык выводимых Ñообщений." -#: utils/misc/guc.c:3184 +#: utils/misc/guc.c:3425 msgid "Sets the locale for formatting monetary amounts." msgstr "Задаёт локаль Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´ÐµÐ½ÐµÐ¶Ð½Ñ‹Ñ… Ñумм." -#: utils/misc/guc.c:3194 +#: utils/misc/guc.c:3435 msgid "Sets the locale for formatting numbers." msgstr "Задаёт локаль Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‡Ð¸Ñел." -#: utils/misc/guc.c:3204 +#: utils/misc/guc.c:3445 msgid "Sets the locale for formatting date and time values." msgstr "Задаёт локаль Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð°Ñ‚ и времени." -#: utils/misc/guc.c:3214 +#: utils/misc/guc.c:3455 msgid "Lists shared libraries to preload into each backend." msgstr "" "СпиÑок разделÑемых библиотек, заранее загружаемых в каждый обÑлуживающий " "процеÑÑ." -#: utils/misc/guc.c:3225 +#: utils/misc/guc.c:3466 msgid "Lists shared libraries to preload into server." msgstr "СпиÑок разделÑемых библиотек, заранее загружаемых в памÑть Ñервера." -#: utils/misc/guc.c:3236 +#: utils/misc/guc.c:3477 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "" "СпиÑок непривилегированных разделÑемых библиотек, заранее загружаемых в " "каждый обÑлуживающий процеÑÑ." -#: utils/misc/guc.c:3247 +#: utils/misc/guc.c:3488 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "Задаёт порÑдок проÑмотра Ñхемы при поиÑке неполных имён." -#: utils/misc/guc.c:3259 +#: utils/misc/guc.c:3500 msgid "Sets the server (database) character set encoding." msgstr "Задаёт кодировку Ñимволов Ñервера (баз данных)." -#: utils/misc/guc.c:3271 +#: utils/misc/guc.c:3512 msgid "Shows the server version." msgstr "Показывает верÑию Ñервера." -#: utils/misc/guc.c:3283 +#: utils/misc/guc.c:3524 msgid "Sets the current role." msgstr "Задаёт текущую роль." -#: utils/misc/guc.c:3295 +#: utils/misc/guc.c:3536 msgid "Sets the session user name." msgstr "Задаёт Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² ÑеанÑе." -#: utils/misc/guc.c:3306 +#: utils/misc/guc.c:3547 msgid "Sets the destination for server log output." msgstr "ОпределÑет, куда будет выводитьÑÑ Ð¿Ñ€Ð¾Ñ‚Ð¾ÐºÐ¾Ð» Ñервера." -#: utils/misc/guc.c:3307 +#: utils/misc/guc.c:3548 msgid "" "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and " "\"eventlog\", depending on the platform." @@ -26233,24 +27837,24 @@ msgstr "" "Значение может включать Ñочетание Ñлов \"stderr\", \"syslog\", \"csvlog\" и " "\"eventlog\", в завиÑимоÑти от платформы." -#: utils/misc/guc.c:3318 +#: utils/misc/guc.c:3559 msgid "Sets the destination directory for log files." msgstr "Задаёт целевой каталог Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð² протоколов." -#: utils/misc/guc.c:3319 +#: utils/misc/guc.c:3560 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "" "Путь может быть абÑолютным или указыватьÑÑ Ð¾Ñ‚Ð½Ð¾Ñительно каталога данных." -#: utils/misc/guc.c:3329 +#: utils/misc/guc.c:3570 msgid "Sets the file name pattern for log files." msgstr "Задаёт шаблон имени Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð² протоколов." -#: utils/misc/guc.c:3340 +#: utils/misc/guc.c:3581 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "Задаёт Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñообщений PostgreSQL в syslog." -#: utils/misc/guc.c:3351 +#: utils/misc/guc.c:3592 msgid "" "Sets the application name used to identify PostgreSQL messages in the event " "log." @@ -26258,113 +27862,121 @@ msgstr "" "Задаёт Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ Ñообщений PostgreSQL в журнале " "Ñобытий." -#: utils/misc/guc.c:3362 +#: utils/misc/guc.c:3603 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "" "Задаёт чаÑовой поÑÑ Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° и разбора Ñтрокового предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸." -#: utils/misc/guc.c:3372 +#: utils/misc/guc.c:3613 msgid "Selects a file of time zone abbreviations." msgstr "Выбирает файл Ñ Ñокращёнными названиÑми чаÑовых поÑÑов." -#: utils/misc/guc.c:3382 +#: utils/misc/guc.c:3623 msgid "Sets the current transaction's isolation level." msgstr "Задаёт текущий уровень изолÑции транзакций." -#: utils/misc/guc.c:3393 +#: utils/misc/guc.c:3634 msgid "Sets the owning group of the Unix-domain socket." -msgstr "Задаёт группу-владельца доменного Ñокета Unix." +msgstr "Задаёт группу-владельца Unix-Ñокета." -#: utils/misc/guc.c:3394 +#: utils/misc/guc.c:3635 msgid "" "The owning user of the socket is always the user that starts the server." msgstr "" "СобÑтвенно владельцем Ñокета вÑегда будет пользователь, запуÑкающий Ñервер." -#: utils/misc/guc.c:3404 +#: utils/misc/guc.c:3645 msgid "Sets the directories where Unix-domain sockets will be created." -msgstr "Задаёт каталоги, где будут ÑоздаватьÑÑ Ð´Ð¾Ð¼ÐµÐ½Ð½Ñ‹Ðµ Ñокеты Unix." +msgstr "Задаёт каталоги, где будут ÑоздаватьÑÑ Unix-Ñокеты." -#: utils/misc/guc.c:3419 +#: utils/misc/guc.c:3660 msgid "Sets the host name or IP address(es) to listen to." msgstr "Задаёт Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð° или IP-адреÑ(а) Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð²Ñзки." -#: utils/misc/guc.c:3434 +#: utils/misc/guc.c:3675 msgid "Sets the server's data directory." msgstr "ОпределÑет каталог данных Ñервера." -#: utils/misc/guc.c:3445 +#: utils/misc/guc.c:3686 msgid "Sets the server's main configuration file." msgstr "ОпределÑет оÑновной файл конфигурации Ñервера." -#: utils/misc/guc.c:3456 +#: utils/misc/guc.c:3697 msgid "Sets the server's \"hba\" configuration file." msgstr "Задаёт путь к файлу конфигурации \"hba\"." -#: utils/misc/guc.c:3467 +#: utils/misc/guc.c:3708 msgid "Sets the server's \"ident\" configuration file." msgstr "Задаёт путь к файлу конфигурации \"ident\"." -#: utils/misc/guc.c:3478 +#: utils/misc/guc.c:3719 msgid "Writes the postmaster PID to the specified file." msgstr "Файл, в который будет запиÑан код процеÑÑа postmaster." -#: utils/misc/guc.c:3489 +#: utils/misc/guc.c:3730 msgid "Location of the SSL server certificate file." msgstr "Размещение файла Ñертификата Ñервера Ð´Ð»Ñ SSL." -#: utils/misc/guc.c:3499 +#: utils/misc/guc.c:3740 msgid "Location of the SSL server private key file." msgstr "Размещение файла Ñ Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ñ‹Ð¼ ключом Ñервера Ð´Ð»Ñ SSL." -#: utils/misc/guc.c:3509 +#: utils/misc/guc.c:3750 msgid "Location of the SSL certificate authority file." msgstr "Размещение файла центра Ñертификации Ð´Ð»Ñ SSL." -#: utils/misc/guc.c:3519 +#: utils/misc/guc.c:3760 msgid "Location of the SSL certificate revocation list file." msgstr "Размещение файла Ñо ÑпиÑком отзыва Ñертификатов Ð´Ð»Ñ SSL." -#: utils/misc/guc.c:3529 +#: utils/misc/guc.c:3770 msgid "Writes temporary statistics files to the specified directory." msgstr "Каталог, в который будут запиÑыватьÑÑ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ðµ файлы ÑтатиÑтики." -#: utils/misc/guc.c:3540 +#: utils/misc/guc.c:3781 msgid "" "Number of synchronous standbys and list of names of potential synchronous " "ones." msgstr "" "КоличеÑтво потенциально Ñинхронных резервных Ñерверов и ÑпиÑок их имён." -#: utils/misc/guc.c:3551 +#: utils/misc/guc.c:3792 msgid "Sets default text search configuration." msgstr "Задаёт конфигурацию текÑтового поиÑка по умолчанию." -#: utils/misc/guc.c:3561 +#: utils/misc/guc.c:3802 msgid "Sets the list of allowed SSL ciphers." msgstr "Задаёт ÑпиÑок допуÑтимых алгоритмов ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð´Ð»Ñ SSL." -#: utils/misc/guc.c:3576 +#: utils/misc/guc.c:3817 msgid "Sets the curve to use for ECDH." msgstr "Задаёт кривую Ð´Ð»Ñ ECDH." -#: utils/misc/guc.c:3591 +#: utils/misc/guc.c:3832 +msgid "Location of the SSL DH parameters file." +msgstr "Размещение файла Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ SSL DH." + +#: utils/misc/guc.c:3843 +msgid "Command to obtain passphrases for SSL." +msgstr "Команда, позволÑÑŽÑ‰Ð°Ñ Ð¿Ð¾Ð»ÑƒÑ‡Ð¸Ñ‚ÑŒ пароль Ð´Ð»Ñ SSL." + +#: utils/misc/guc.c:3853 msgid "Sets the application name to be reported in statistics and logs." msgstr "" "Задаёт Ð¸Ð¼Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ, которое будет выводитьÑÑ Ð² ÑтатиÑтике и протоколах." -#: utils/misc/guc.c:3602 +#: utils/misc/guc.c:3864 msgid "Sets the name of the cluster, which is included in the process title." msgstr "Задаёт Ð¸Ð¼Ñ ÐºÐ»Ð°Ñтера, которое будет добавлÑтьÑÑ Ð² название процеÑÑа." -#: utils/misc/guc.c:3613 +#: utils/misc/guc.c:3875 msgid "" "Sets the WAL resource managers for which WAL consistency checks are done." msgstr "" "Задаёт перечень менеджеров реÑурÑов WAL, Ð´Ð»Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ñ… выполнÑÑŽÑ‚ÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ " "целоÑтноÑти WAL." -#: utils/misc/guc.c:3614 +#: utils/misc/guc.c:3876 msgid "" "Full-page images will be logged for all data blocks and cross-checked " "against the results of WAL replay." @@ -26372,20 +27984,24 @@ msgstr "" "При Ñтом в журнал будут запиÑыватьÑÑ Ð¾Ð±Ñ€Ð°Ð·Ñ‹ полных Ñтраниц Ð´Ð»Ñ Ð²Ñех блоков " "данных Ð´Ð»Ñ Ñверки Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð°Ð¼Ð¸ воÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ WAL." -#: utils/misc/guc.c:3633 +#: utils/misc/guc.c:3886 +msgid "JIT provider to use." +msgstr "ИÑпользуемый провайдер JIT." + +#: utils/misc/guc.c:3906 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "ОпределÑет, можно ли иÑпользовать \"\\'\" в текÑтовых Ñтроках." -#: utils/misc/guc.c:3643 +#: utils/misc/guc.c:3916 msgid "Sets the output format for bytea." msgstr "Задаёт формат вывода данных типа bytea." -#: utils/misc/guc.c:3653 +#: utils/misc/guc.c:3926 msgid "Sets the message levels that are sent to the client." msgstr "Ограничивает уровень Ñообщений, передаваемых клиенту." -#: utils/misc/guc.c:3654 utils/misc/guc.c:3707 utils/misc/guc.c:3718 -#: utils/misc/guc.c:3784 +#: utils/misc/guc.c:3927 utils/misc/guc.c:3980 utils/misc/guc.c:3991 +#: utils/misc/guc.c:4057 msgid "" "Each level includes all the levels that follow it. The later the level, the " "fewer messages are sent." @@ -26393,12 +28009,12 @@ msgstr "" "Каждый уровень включает вÑе поÑледующие. Чем выше уровень, тем меньше " "Ñообщений." -#: utils/misc/guc.c:3664 +#: utils/misc/guc.c:3937 msgid "Enables the planner to use constraints to optimize queries." msgstr "" "Разрешает планировщику оптимизировать запроÑÑ‹, полагаÑÑÑŒ на ограничениÑ." -#: utils/misc/guc.c:3665 +#: utils/misc/guc.c:3938 msgid "" "Table scans will be skipped if their constraints guarantee that no rows " "match the query." @@ -26406,76 +28022,76 @@ msgstr "" "Сканирование таблицы не будет выполнÑтьÑÑ, еÑли её Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð³Ð°Ñ€Ð°Ð½Ñ‚Ð¸Ñ€ÑƒÑŽÑ‚, " "что запроÑу не удовлетворÑÑŽÑ‚ никакие Ñтроки." -#: utils/misc/guc.c:3675 +#: utils/misc/guc.c:3948 msgid "Sets the transaction isolation level of each new transaction." msgstr "Задаёт уровень изолÑции транзакций Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… транзакций." -#: utils/misc/guc.c:3685 +#: utils/misc/guc.c:3958 msgid "Sets the display format for interval values." msgstr "Задаёт формат Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€ÐµÐ½Ð½Ð¸Ñ… значений." -#: utils/misc/guc.c:3696 +#: utils/misc/guc.c:3969 msgid "Sets the verbosity of logged messages." msgstr "Задаёт детализацию протоколируемых Ñообщений." -#: utils/misc/guc.c:3706 +#: utils/misc/guc.c:3979 msgid "Sets the message levels that are logged." msgstr "Ограничивает уровни протоколируемых Ñообщений." -#: utils/misc/guc.c:3717 +#: utils/misc/guc.c:3990 msgid "" "Causes all statements generating error at or above this level to be logged." msgstr "" "Включает протоколирование Ð´Ð»Ñ SQL-операторов, выполненных Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ Ñтого " "или большего уровнÑ." -#: utils/misc/guc.c:3728 +#: utils/misc/guc.c:4001 msgid "Sets the type of statements logged." msgstr "Задаёт тип протоколируемых операторов." -#: utils/misc/guc.c:3738 +#: utils/misc/guc.c:4011 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "Задаёт Ð¿Ð¾Ð»ÑƒÑ‡Ð°Ñ‚ÐµÐ»Ñ Ñообщений, отправлÑемых в syslog." -#: utils/misc/guc.c:3753 +#: utils/misc/guc.c:4026 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "" "Задаёт режим ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð¾Ð² и правил перезапиÑи Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑеанÑа." -#: utils/misc/guc.c:3763 +#: utils/misc/guc.c:4036 msgid "Sets the current transaction's synchronization level." msgstr "Задаёт уровень Ñинхронизации текущей транзакции." -#: utils/misc/guc.c:3773 +#: utils/misc/guc.c:4046 msgid "Allows archiving of WAL files using archive_command." msgstr "Разрешает архивацию файлов WAL командой archive_command." -#: utils/misc/guc.c:3783 +#: utils/misc/guc.c:4056 msgid "Enables logging of recovery-related debugging information." msgstr "" "Включает протоколирование отладочной информации, ÑвÑзанной Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸ÐµÐ¹." -#: utils/misc/guc.c:3799 +#: utils/misc/guc.c:4072 msgid "Collects function-level statistics on database activity." msgstr "Включает Ñбор ÑтатиÑтики активноÑти в БД на уровне функций." -#: utils/misc/guc.c:3809 +#: utils/misc/guc.c:4082 msgid "Set the level of information written to the WAL." msgstr "Задаёт уровень информации, запиÑываемой в WAL." -#: utils/misc/guc.c:3819 +#: utils/misc/guc.c:4092 msgid "Selects the dynamic shared memory implementation used." msgstr "Выбирает иÑпользуемую реализацию динамичеÑкой разделÑемой памÑти." -#: utils/misc/guc.c:3829 +#: utils/misc/guc.c:4102 msgid "Selects the method used for forcing WAL updates to disk." msgstr "Выбирает метод принудительной запиÑи изменений в WAL на диÑк." -#: utils/misc/guc.c:3839 +#: utils/misc/guc.c:4112 msgid "Sets how binary values are to be encoded in XML." msgstr "ОпределÑет, как должны кодироватьÑÑ Ð´Ð²Ð¾Ð¸Ñ‡Ð½Ñ‹Ðµ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð² XML." -#: utils/misc/guc.c:3849 +#: utils/misc/guc.c:4122 msgid "" "Sets whether XML data in implicit parsing and serialization operations is to " "be considered as documents or content fragments." @@ -26483,15 +28099,15 @@ msgstr "" "ОпределÑет, Ñледует ли раÑÑматривать XML-данные в неÑвных операциÑÑ… разбора " "и Ñериализации как документы или как фрагменты ÑодержаниÑ." -#: utils/misc/guc.c:3860 -msgid "Use of huge pages on Linux." -msgstr "Включает иÑпользование гигантÑких Ñтраниц в Linux." +#: utils/misc/guc.c:4133 +msgid "Use of huge pages on Linux or Windows." +msgstr "Включает иÑпользование гигантÑких Ñтраниц в Linux и в Windows." -#: utils/misc/guc.c:3870 +#: utils/misc/guc.c:4143 msgid "Forces use of parallel query facilities." msgstr "Принудительно включает режим параллельного Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñов." -#: utils/misc/guc.c:3871 +#: utils/misc/guc.c:4144 msgid "" "If possible, run query using a parallel worker and with parallel " "restrictions." @@ -26499,11 +28115,11 @@ msgstr "" "ЕÑли возможно, Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÑетÑÑ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ð¼Ð¸ иÑполнителÑми и Ñ " "ограничениÑми параллельноÑти." -#: utils/misc/guc.c:3880 +#: utils/misc/guc.c:4153 msgid "Encrypt passwords." msgstr "Шифровать пароли." -#: utils/misc/guc.c:3881 +#: utils/misc/guc.c:4154 msgid "" "When a password is specified in CREATE USER or ALTER USER without writing " "either ENCRYPTED or UNENCRYPTED, this parameter determines whether the " @@ -26512,12 +28128,12 @@ msgstr "" "Этот параметр определÑет, нужно ли шифровать пароли, заданные в CREATE USER " "или ALTER USER без ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ ENCRYPTED или UNENCRYPTED." -#: utils/misc/guc.c:4683 +#: utils/misc/guc.c:4956 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: ошибка доÑтупа к каталогу \"%s\": %s\n" -#: utils/misc/guc.c:4688 +#: utils/misc/guc.c:4961 #, c-format msgid "" "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" @@ -26525,7 +28141,7 @@ msgstr "" "ЗапуÑтите initdb или pg_basebackup Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ каталога данных " "PostgreSQL.\n" -#: utils/misc/guc.c:4708 +#: utils/misc/guc.c:4981 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" @@ -26536,12 +28152,12 @@ msgstr "" "Ð’Ñ‹ должны указать его раÑположение в параметре --config-file или -D, либо " "уÑтановить переменную Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: utils/misc/guc.c:4727 +#: utils/misc/guc.c:5000 #, c-format msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s не может открыть файл конфигурации Ñервера \"%s\": %s\n" -#: utils/misc/guc.c:4753 +#: utils/misc/guc.c:5026 #, c-format msgid "" "%s does not know where to find the database system data.\n" @@ -26552,7 +28168,7 @@ msgstr "" "Их раÑположение можно задать как значение \"data_directory\" в файле \"%s\", " "либо передать в параметре -D, либо уÑтановить переменную Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: utils/misc/guc.c:4801 +#: utils/misc/guc.c:5074 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" @@ -26563,7 +28179,7 @@ msgstr "" "Его раÑположение можно задать как значение \"hba_file\" в файле \"%s\", либо " "передать в параметре -D, либо уÑтановить переменную Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: utils/misc/guc.c:4824 +#: utils/misc/guc.c:5097 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" @@ -26574,129 +28190,129 @@ msgstr "" "Его раÑположение можно задать как значение \"ident_file\" в файле \"%s\", " "либо передать в параметре -D, либо уÑтановить переменную Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: utils/misc/guc.c:5498 utils/misc/guc.c:5545 +#: utils/misc/guc.c:5772 utils/misc/guc.c:5819 msgid "Value exceeds integer range." msgstr "Значение выходит за рамки целых чиÑел." -#: utils/misc/guc.c:5768 +#: utils/misc/guc.c:6046 #, c-format msgid "parameter \"%s\" requires a numeric value" msgstr "параметр \"%s\" требует чиÑловое значение" -#: utils/misc/guc.c:5777 +#: utils/misc/guc.c:6055 #, c-format msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" msgstr "%g вне диапазона, допуÑтимого Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\" (%g .. %g)" -#: utils/misc/guc.c:5930 utils/misc/guc.c:7276 +#: utils/misc/guc.c:6208 utils/misc/guc.c:7578 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "уÑтанавливать параметры во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð°Ñ€Ð°Ð»Ð»ÐµÐ»ÑŒÐ½Ñ‹Ñ… операций нельзÑ" -#: utils/misc/guc.c:5937 utils/misc/guc.c:6688 utils/misc/guc.c:6741 -#: utils/misc/guc.c:7104 utils/misc/guc.c:7863 utils/misc/guc.c:8031 -#: utils/misc/guc.c:9709 +#: utils/misc/guc.c:6215 utils/misc/guc.c:6967 utils/misc/guc.c:7020 +#: utils/misc/guc.c:7071 utils/misc/guc.c:7407 utils/misc/guc.c:8174 +#: utils/misc/guc.c:8342 utils/misc/guc.c:10019 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "нераÑпознанный параметр конфигурации: \"%s\"" -#: utils/misc/guc.c:5952 utils/misc/guc.c:7116 +#: utils/misc/guc.c:6230 utils/misc/guc.c:7419 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ" -#: utils/misc/guc.c:5975 utils/misc/guc.c:6168 utils/misc/guc.c:6258 -#: utils/misc/guc.c:6348 utils/misc/guc.c:6456 utils/misc/guc.c:6551 -#: guc-file.l:350 +#: utils/misc/guc.c:6253 utils/misc/guc.c:6447 utils/misc/guc.c:6537 +#: utils/misc/guc.c:6627 utils/misc/guc.c:6735 utils/misc/guc.c:6830 +#: guc-file.l:352 #, c-format msgid "parameter \"%s\" cannot be changed without restarting the server" msgstr "параметр \"%s\" изменÑетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при перезапуÑке Ñервера" -#: utils/misc/guc.c:5985 +#: utils/misc/guc.c:6263 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ ÑейчаÑ" -#: utils/misc/guc.c:6003 utils/misc/guc.c:6049 utils/misc/guc.c:9725 +#: utils/misc/guc.c:6281 utils/misc/guc.c:6328 utils/misc/guc.c:10035 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "нет прав Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\"" -#: utils/misc/guc.c:6039 +#: utils/misc/guc.c:6318 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ поÑле уÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑоединениÑ" -#: utils/misc/guc.c:6087 +#: utils/misc/guc.c:6366 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "" "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð´Ð°Ñ‚ÑŒ в функции Ñ ÐºÐ¾Ð½Ñ‚ÐµÐºÑтом безопаÑноÑти " "определившего" -#: utils/misc/guc.c:6696 utils/misc/guc.c:6746 utils/misc/guc.c:8038 +#: utils/misc/guc.c:6975 utils/misc/guc.c:7025 utils/misc/guc.c:8349 #, c-format msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" msgstr "" "прочитать \"%s\" может только Ñуперпользователь или член роли " "pg_read_all_settings" -#: utils/misc/guc.c:6813 +#: utils/misc/guc.c:7116 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s принимает только один аргумент" -#: utils/misc/guc.c:7064 +#: utils/misc/guc.c:7367 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" msgstr "выполнить команду ALTER SYSTEM может только Ñуперпользователь" -#: utils/misc/guc.c:7149 +#: utils/misc/guc.c:7452 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "значение параметра Ð´Ð»Ñ ALTER SYSTEM не должно быть многоÑтрочным" -#: utils/misc/guc.c:7194 +#: utils/misc/guc.c:7497 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "не удалоÑÑŒ разобрать Ñодержимое файла \"%s\"" -#: utils/misc/guc.c:7352 +#: utils/misc/guc.c:7654 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT не реализовано" -#: utils/misc/guc.c:7436 +#: utils/misc/guc.c:7738 #, c-format msgid "SET requires parameter name" msgstr "SET требует Ð¸Ð¼Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°" -#: utils/misc/guc.c:7560 +#: utils/misc/guc.c:7871 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "попытка переопределить параметр \"%s\"" -#: utils/misc/guc.c:9342 +#: utils/misc/guc.c:9652 #, c-format msgid "parameter \"%s\" could not be set" msgstr "параметр \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÑтановить" -#: utils/misc/guc.c:9429 +#: utils/misc/guc.c:9739 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "не удалоÑÑŒ разобрать значение параметра \"%s\"" -#: utils/misc/guc.c:9787 utils/misc/guc.c:9821 +#: utils/misc/guc.c:10097 utils/misc/guc.c:10131 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "неверное значение параметра \"%s\": %d" -#: utils/misc/guc.c:9855 +#: utils/misc/guc.c:10165 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "неверное значение параметра \"%s\": %g" -#: utils/misc/guc.c:10125 +#: utils/misc/guc.c:10449 #, c-format msgid "" "\"temp_buffers\" cannot be changed after any temporary tables have been " @@ -26705,59 +28321,75 @@ msgstr "" "параметр \"temp_buffers\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ поÑле Ð¾Ð±Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ Ðº временным " "таблицам в текущем ÑеанÑе." -#: utils/misc/guc.c:10137 +#: utils/misc/guc.c:10461 #, c-format msgid "Bonjour is not supported by this build" msgstr "Bonjour не поддерживаетÑÑ Ð² данной Ñборке" -#: utils/misc/guc.c:10150 +#: utils/misc/guc.c:10474 #, c-format msgid "SSL is not supported by this build" msgstr "SSL не поддерживаетÑÑ Ð² данной Ñборке" -#: utils/misc/guc.c:10162 +#: utils/misc/guc.c:10486 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "" "Этот параметр Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ, когда \"log_statement_stats\" равен true." -#: utils/misc/guc.c:10174 +#: utils/misc/guc.c:10498 #, c-format msgid "" "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", " "\"log_planner_stats\", or \"log_executor_stats\" is true." msgstr "" -"Параметр \"log_statement_stats\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ, когда \"log_parser_stats" -"\", \"log_planner_stats\" или \"log_executor_stats\" равны true." +"Параметр \"log_statement_stats\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð²ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ, когда " +"\"log_parser_stats\", \"log_planner_stats\" или \"log_executor_stats\" равны " +"true." + +#: utils/misc/guc.c:10714 +#, c-format +msgid "" +"effective_io_concurrency must be set to 0 on platforms that lack " +"posix_fadvise()" +msgstr "" +"значение effective_io_concurrency должно равнÑтьÑÑ 0 на платформах, где " +"отÑутÑтвует lack posix_fadvise()" #: utils/misc/help_config.c:131 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°: нераÑпознанный тип параметра времени выполнениÑ\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format msgid "" "query-specified return tuple and function return type are not compatible" msgstr "" "заданный в запроÑе кортеж результата неÑовмеÑтим Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ результата функции" -#: utils/misc/pg_controldata.c:58 utils/misc/pg_controldata.c:138 -#: utils/misc/pg_controldata.c:244 utils/misc/pg_controldata.c:311 +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 +#: utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 #, c-format msgid "calculated CRC checksum does not match value stored in file" msgstr "" "вычиÑÐ»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма (CRC) не ÑоответÑтвует значению, Ñохранённому " "в файле" -#: utils/misc/rls.c:128 +# well-spelled: пользов +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: пользов.: %d.%02d Ñ, ÑиÑтема: %d.%02d Ñ, прошло: %d.%02d Ñ" + +#: utils/misc/rls.c:127 #, c-format msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "" -"Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±ÑƒÐ´ÐµÑ‚ ограничен политикой безопаÑноÑти на уровне Ñтрок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ " -"\"%s\"" +"Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð±ÑƒÐ´ÐµÑ‚ ограничен политикой безопаÑноÑти на уровне Ñтрок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"" +"%s\"" -#: utils/misc/rls.c:130 +#: utils/misc/rls.c:129 #, c-format msgid "" "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW " @@ -26769,7 +28401,7 @@ msgstr "" #: utils/misc/timeout.c:388 #, c-format msgid "cannot add more timeout reasons" -msgstr "добавить другие причины таймаута нельзÑ" +msgstr "добавить другие причины тайм-аута нельзÑ" #: utils/misc/tzparser.c:61 #, c-format @@ -26820,8 +28452,8 @@ msgstr "краткое обозначение чаÑового поÑÑа \"%s\" #: utils/misc/tzparser.c:239 #, c-format msgid "" -"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s" -"\", line %d." +"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"" +"%s\", line %d." msgstr "" "ЗапиÑÑŒ в файле чаÑовых поÑÑов \"%s\", Ñтроке %d, противоречит запиÑи в файле " "\"%s\", Ñтроке %d." @@ -26852,80 +28484,102 @@ msgid "@INCLUDE without file name in time zone file \"%s\", line %d" msgstr "" "в @INCLUDE не указано Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° (файл чаÑовых поÑÑов \"%s\", Ñтрока %d)" -#: utils/mmgr/aset.c:405 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "Ошибка при Ñоздании контекÑта памÑти \"%s\"." -#: utils/mmgr/dsa.c:518 +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 #, c-format -msgid "could not attach to dsa_handle" -msgstr "не удалоÑÑŒ подключитьÑÑ Ðº dsa" +msgid "could not attach to dynamic shared area" +msgstr "не удалоÑÑŒ подключитьÑÑ Ðº динамичеÑкой разделÑемой облаÑти" -#: utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 #, c-format -msgid "Failed on DSA request of size %zu." -msgstr "Ошибка при запроÑе памÑти DSA (%zu Б)." +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Ошибка при запроÑе блока размером %zu в контекÑте памÑти \"%s\"." -#: utils/mmgr/dsa.c:1322 -#, c-format -msgid "could not attach to dsa_area" -msgstr "не удалоÑÑŒ подключитьÑÑ Ðº облаÑти dsa" - -#: utils/mmgr/mcxt.c:726 utils/mmgr/mcxt.c:761 utils/mmgr/mcxt.c:798 -#: utils/mmgr/mcxt.c:835 utils/mmgr/mcxt.c:869 utils/mmgr/mcxt.c:898 -#: utils/mmgr/mcxt.c:932 utils/mmgr/mcxt.c:983 utils/mmgr/mcxt.c:1017 -#: utils/mmgr/mcxt.c:1051 -#, c-format -msgid "Failed on request of size %zu." -msgstr "Ошибка при запроÑе памÑти (%zu Б)." - -#: utils/mmgr/portalmem.c:186 +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "курÑор \"%s\" уже ÑущеÑтвует" -#: utils/mmgr/portalmem.c:190 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "ÑущеÑтвующий курÑор (\"%s\") закрываетÑÑ" -#: utils/mmgr/portalmem.c:394 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "портал \"%s\" не может быть запущен" -#: utils/mmgr/portalmem.c:474 +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "удалить закреплённый портал \"%s\" нельзÑ" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "удалить активный портал \"%s\" нельзÑ" -#: utils/mmgr/portalmem.c:678 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, Ñоздавшей курÑор WITH HOLD" -#: utils/sort/logtape.c:252 +#: utils/mmgr/portalmem.c:1269 +#, c-format +msgid "" +"cannot perform transaction commands inside a cursor loop that is not read-" +"only" +msgstr "" +"транзакционные команды Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ñть внутри цикла Ñ ÐºÑƒÑ€Ñором, " +"производÑщим изменениÑ" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "не удалоÑÑŒ Ñчитать блок %ld временного файла: %m" -#: utils/sort/tuplesort.c:3066 +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "не удалоÑÑŒ запиÑать во временный файл: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "не удалоÑÑŒ прочитать файл общего временного хранилища кортежей" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "неожиданный фрагмент в файле общего временного хранилища кортежей" + +#: utils/sort/tuplesort.c:2967 #, c-format msgid "cannot have more than %d runs for an external sort" msgstr "чиÑло потоков данных Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ Ñортировки не может превышать %d" -#: utils/sort/tuplesort.c:4135 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "Ñоздать уникальный Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не удалоÑÑŒ" -#: utils/sort/tuplesort.c:4137 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "Ключ %s дублируетÑÑ." -#: utils/sort/tuplesort.c:4138 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "Данные Ñодержат дублирующиеÑÑ ÐºÐ»ÑŽÑ‡Ð¸." @@ -26951,31 +28605,32 @@ msgstr "не удалоÑÑŒ прочитать временный файл Ð¸Ñ msgid "could not write to tuplestore temporary file: %m" msgstr "не удалоÑÑŒ запиÑать во временный файл иÑточника кортежей: %m" -#: utils/time/snapmgr.c:618 +#: utils/time/snapmgr.c:622 #, c-format msgid "The source transaction is not running anymore." msgstr "ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ ÑƒÐ¶Ðµ не выполнÑетÑÑ." -#: utils/time/snapmgr.c:1190 +#: utils/time/snapmgr.c:1200 #, c-format msgid "cannot export a snapshot from a subtransaction" msgstr "ÑкÑпортировать Ñнимок из вложенной транзакции нельзÑ" -#: utils/time/snapmgr.c:1339 utils/time/snapmgr.c:1344 -#: utils/time/snapmgr.c:1349 utils/time/snapmgr.c:1364 -#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1374 -#: utils/time/snapmgr.c:1473 utils/time/snapmgr.c:1489 -#: utils/time/snapmgr.c:1514 +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 +#: utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 +#: utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 +#: utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 +#: utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 #, c-format msgid "invalid snapshot data in file \"%s\"" msgstr "неверные данные Ñнимка в файле \"%s\"" -#: utils/time/snapmgr.c:1411 +#: utils/time/snapmgr.c:1456 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "команда SET TRANSACTION SNAPSHOT должна выполнÑтьÑÑ Ð´Ð¾ запроÑов" -#: utils/time/snapmgr.c:1420 +#: utils/time/snapmgr.c:1465 #, c-format msgid "" "a snapshot-importing transaction must have isolation level SERIALIZABLE or " @@ -26984,12 +28639,12 @@ msgstr "" "транзакциÑ, Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñнимок, должна иметь уровень изолÑции SERIALIZABLE " "или REPEATABLE READ" -#: utils/time/snapmgr.c:1429 utils/time/snapmgr.c:1438 +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 #, c-format msgid "invalid snapshot identifier: \"%s\"" msgstr "неверный идентификатор Ñнимка: \"%s\"" -#: utils/time/snapmgr.c:1527 +#: utils/time/snapmgr.c:1573 #, c-format msgid "" "a serializable transaction cannot import a snapshot from a non-serializable " @@ -26997,7 +28652,7 @@ msgid "" msgstr "" "ÑÐµÑ€Ð¸Ð°Ð»Ð¸Ð·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð½Ðµ может импортировать Ñнимок из не Ñериализуемой" -#: utils/time/snapmgr.c:1531 +#: utils/time/snapmgr.c:1577 #, c-format msgid "" "a non-read-only serializable transaction cannot import a snapshot from a " @@ -27006,12 +28661,23 @@ msgstr "" "ÑÐµÑ€Ð¸Ð°Ð»Ð¸Ð·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð² режиме \"чтение-запиÑÑŒ\" не может импортировать " "Ñнимок из транзакции в режиме \"только чтение\"" -#: utils/time/snapmgr.c:1546 +#: utils/time/snapmgr.c:1592 #, c-format msgid "cannot import a snapshot from a different database" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ð¼Ð¿Ð¾Ñ€Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ñ‚ÑŒ Ñнимок из другой базы данных" -#: gram.y:1062 +#: gram.y:1026 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "вариант UNENCRYPTED PASSWORD более не поддерживаетÑÑ" + +#: gram.y:1027 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "" +"Удалите Ñлово UNENCRYPTED, чтобы Ñохранить пароль в зашифрованном виде." + +#: gram.y:1089 #, c-format msgid "unrecognized role option \"%s\"" msgstr "нераÑпознанный параметр роли \"%s\"" @@ -27021,238 +28687,258 @@ msgstr "нераÑпознанный параметр роли \"%s\"" msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" msgstr "CREATE SCHEMA IF NOT EXISTS не может включать Ñлементы Ñхемы" -#: gram.y:1496 +#: gram.y:1497 #, c-format msgid "current database cannot be changed" msgstr "Ñменить текущую базу данных нельзÑ" -#: gram.y:1620 +#: gram.y:1621 #, c-format msgid "time zone interval must be HOUR or HOUR TO MINUTE" msgstr "" "интервал, задающий чаÑовой поÑÑ, должен иметь точноÑть HOUR или HOUR TO " "MINUTE" -#: gram.y:2771 gram.y:2800 +#: gram.y:2139 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "номер Ñтолбца должен быть в диапазоне от 1 до %d" + +#: gram.y:2678 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "параметр поÑледовательноÑти \"%s\" здеÑÑŒ не поддерживаетÑÑ" + +#: gram.y:2707 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "модуль Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции указан неоднократно" + +#: gram.y:2716 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "оÑтаток Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции указан неоднократно" + +#: gram.y:2723 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "нераÑпознанное указание Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñ…ÐµÑˆ-Ñекции \"%s\"" + +#: gram.y:2731 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "необходимо указать модуль Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции" + +#: gram.y:2735 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "необходимо указать оÑтаток Ð´Ð»Ñ Ñ…ÐµÑˆ-Ñекции" + +#: gram.y:2987 gram.y:3016 #, c-format msgid "STDIN/STDOUT not allowed with PROGRAM" msgstr "ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ STDIN/STDOUT неÑовмеÑтимы Ñ PROGRAM" -#: gram.y:3110 gram.y:3117 gram.y:10994 gram.y:11002 +#: gram.y:3326 gram.y:3333 gram.y:11482 gram.y:11490 #, c-format msgid "GLOBAL is deprecated in temporary table creation" msgstr "указание GLOBAL при Ñоздании временных таблиц уÑтарело" -#: gram.y:5037 +#: gram.y:5297 #, c-format msgid "unrecognized row security option \"%s\"" msgstr "нераÑпознанный вариант политики безопаÑноÑти Ñтрок \"%s\"" -#: gram.y:5038 +#: gram.y:5298 #, c-format msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." msgstr "" "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÑŽÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ политики PERMISSIVE и RESTRICTIVE." -#: gram.y:5146 +#: gram.y:5406 msgid "duplicate trigger events specified" msgstr "ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° повторÑÑŽÑ‚ÑÑ" -#: gram.y:5289 +#: gram.y:5554 #, c-format msgid "conflicting constraint properties" msgstr "противоречащие характериÑтики ограничениÑ" -#: gram.y:5395 +#: gram.y:5660 #, c-format msgid "CREATE ASSERTION is not yet implemented" msgstr "оператор CREATE ASSERTION ещё не реализован" -#: gram.y:5410 +#: gram.y:5675 #, c-format msgid "DROP ASSERTION is not yet implemented" msgstr "оператор DROP ASSERTION ещё не реализован" -#: gram.y:5794 +#: gram.y:6055 #, c-format msgid "RECHECK is no longer required" msgstr "RECHECK более не требуетÑÑ" -#: gram.y:5795 +#: gram.y:6056 #, c-format msgid "Update your data type." msgstr "Обновите тип данных." -#: gram.y:7438 +#: gram.y:7793 #, c-format msgid "aggregates cannot have output arguments" msgstr "у агрегатных функций не может быть выходных аргументов" -#: gram.y:9263 -#, c-format -msgid "unrecognized option \"%s\"" -msgstr "нераÑпознанный параметр \"%s\"" - -#: gram.y:9588 gram.y:9606 +#: gram.y:10047 gram.y:10065 #, c-format msgid "WITH CHECK OPTION not supported on recursive views" msgstr "" "предложение WITH CHECK OPTION не поддерживаетÑÑ Ð´Ð»Ñ Ñ€ÐµÐºÑƒÑ€Ñивных предÑтавлений" -#: gram.y:10139 +#: gram.y:10562 #, c-format msgid "unrecognized VACUUM option \"%s\"" msgstr "нераÑпознанный параметр VACUUM: \"%s\"" -#: gram.y:11102 +#: gram.y:11590 #, c-format msgid "LIMIT #,# syntax is not supported" msgstr "ÑинтакÑÐ¸Ñ LIMIT #,# не поддерживаетÑÑ" -#: gram.y:11103 +#: gram.y:11591 #, c-format msgid "Use separate LIMIT and OFFSET clauses." msgstr "ИÑпользуйте отдельные Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ LIMIT и OFFSET." -#: gram.y:11384 gram.y:11409 +#: gram.y:11889 gram.y:11914 #, c-format msgid "VALUES in FROM must have an alias" msgstr "ÑпиÑок VALUES во FROM должен иметь пÑевдоним" -#: gram.y:11385 gram.y:11410 +#: gram.y:11890 gram.y:11915 #, c-format msgid "For example, FROM (VALUES ...) [AS] foo." msgstr "Ðапример, FROM (VALUES ...) [AS] foo." -#: gram.y:11390 gram.y:11415 +#: gram.y:11895 gram.y:11920 #, c-format msgid "subquery in FROM must have an alias" msgstr "Ð¿Ð¾Ð´Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²Ð¾ FROM должен иметь пÑевдоним" -#: gram.y:11391 gram.y:11416 +#: gram.y:11896 gram.y:11921 #, c-format msgid "For example, FROM (SELECT ...) [AS] foo." msgstr "Ðапример, FROM (SELECT ...) [AS] foo." -#: gram.y:11869 +#: gram.y:12374 #, c-format msgid "only one DEFAULT value is allowed" msgstr "допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ одно значение DEFAULT" -#: gram.y:11878 +#: gram.y:12383 #, c-format msgid "only one PATH value per column is allowed" msgstr "Ð´Ð»Ñ Ñтолбца допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ одно значение PATH" -#: gram.y:11887 +#: gram.y:12392 #, c-format msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" msgstr "" "конфликтующие или избыточные объÑÐ²Ð»ÐµÐ½Ð¸Ñ NULL/NOT NULL Ð´Ð»Ñ Ñтолбца \"%s\"" -#: gram.y:11896 +#: gram.y:12401 #, c-format msgid "unrecognized column option \"%s\"" msgstr "нераÑпознанный параметр Ñтолбца \"%s\"" -#: gram.y:12150 +#: gram.y:12655 #, c-format msgid "precision for type float must be at least 1 bit" msgstr "тип float должен иметь точноÑть минимум 1 бит" -#: gram.y:12159 +#: gram.y:12664 #, c-format msgid "precision for type float must be less than 54 bits" msgstr "тип float должен иметь точноÑть меньше 54 бит" -#: gram.y:12650 +#: gram.y:13155 #, c-format msgid "wrong number of parameters on left side of OVERLAPS expression" msgstr "неверное чиÑло параметров в левой чаÑти Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ OVERLAPS" -#: gram.y:12655 +#: gram.y:13160 #, c-format msgid "wrong number of parameters on right side of OVERLAPS expression" msgstr "неверное чиÑло параметров в правой чаÑти Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ OVERLAPS" -#: gram.y:12830 +#: gram.y:13335 #, c-format msgid "UNIQUE predicate is not yet implemented" msgstr "предикат UNIQUE ещё не реализован" -#: gram.y:13177 +#: gram.y:13682 #, c-format msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" msgstr "ORDER BY Ñ WITHIN GROUP можно указать только один раз" -#: gram.y:13182 +#: gram.y:13687 #, c-format msgid "cannot use DISTINCT with WITHIN GROUP" msgstr "DISTINCT Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ WITHIN GROUP" -#: gram.y:13187 +#: gram.y:13692 #, c-format msgid "cannot use VARIADIC with WITHIN GROUP" msgstr "VARIADIC Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ WITHIN GROUP" -#: gram.y:13613 -#, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "RANGE PRECEDING поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ UNBOUNDED" - -#: gram.y:13619 -#, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "RANGE FOLLOWING поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ UNBOUNDED" - -#: gram.y:13646 gram.y:13669 +#: gram.y:14145 gram.y:14168 #, c-format msgid "frame start cannot be UNBOUNDED FOLLOWING" msgstr "началом рамки не может быть UNBOUNDED FOLLOWING" -#: gram.y:13651 +#: gram.y:14150 #, c-format msgid "frame starting from following row cannot end with current row" msgstr "" "рамка, начинающаÑÑÑ Ñо Ñледующей Ñтроки, не может заканчиватьÑÑ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹" -#: gram.y:13674 +#: gram.y:14173 #, c-format msgid "frame end cannot be UNBOUNDED PRECEDING" msgstr "концом рамки не может быть UNBOUNDED PRECEDING" -#: gram.y:13680 +#: gram.y:14179 #, c-format msgid "frame starting from current row cannot have preceding rows" msgstr "" "рамка, начинающаÑÑÑ Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ Ñтроки, не может иметь предшеÑтвующих Ñтрок" -#: gram.y:13687 +#: gram.y:14186 #, c-format msgid "frame starting from following row cannot have preceding rows" msgstr "" "рамка, начинающаÑÑÑ Ñо Ñледующей Ñтроки, не может иметь предшеÑтвующих Ñтрок" -#: gram.y:14322 +#: gram.y:14829 #, c-format msgid "type modifier cannot have parameter name" msgstr "параметр функции-модификатора типа должен быть безымÑнным" -#: gram.y:14328 +#: gram.y:14835 #, c-format msgid "type modifier cannot have ORDER BY" msgstr "модификатор типа не может включать ORDER BY" -#: gram.y:14392 gram.y:14398 +#: gram.y:14900 gram.y:14907 #, c-format msgid "%s cannot be used as a role name here" msgstr "%s Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать здеÑÑŒ как Ð¸Ð¼Ñ Ñ€Ð¾Ð»Ð¸" -#: gram.y:15060 gram.y:15249 +#: gram.y:15578 gram.y:15767 msgid "improper use of \"*\"" msgstr "недопуÑтимое иÑпользование \"*\"" -#: gram.y:15313 +#: gram.y:15831 #, c-format msgid "" "an ordered-set aggregate with a VARIADIC direct argument must have one " @@ -27261,77 +28947,77 @@ msgstr "" "ÑÐ¾Ñ€Ñ‚Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ Ð½ÐµÐ¿Ð¾ÑредÑтвенным аргументом VARIADIC должна " "иметь один агрегатный аргумент VARIADIC того же типа данных" -#: gram.y:15350 +#: gram.y:15868 #, c-format msgid "multiple ORDER BY clauses not allowed" msgstr "ORDER BY можно указать только один раз" -#: gram.y:15361 +#: gram.y:15879 #, c-format msgid "multiple OFFSET clauses not allowed" msgstr "OFFSET можно указать только один раз" -#: gram.y:15370 +#: gram.y:15888 #, c-format msgid "multiple LIMIT clauses not allowed" msgstr "LIMIT можно указать только один раз" -#: gram.y:15379 +#: gram.y:15897 #, c-format msgid "multiple WITH clauses not allowed" msgstr "WITH можно указать только один раз" -#: gram.y:15583 +#: gram.y:16101 #, c-format msgid "OUT and INOUT arguments aren't allowed in TABLE functions" msgstr "в табличных функциÑÑ… не может быть аргументов OUT и INOUT" -#: gram.y:15684 +#: gram.y:16202 #, c-format msgid "multiple COLLATE clauses not allowed" msgstr "COLLATE можно указать только один раз" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15722 gram.y:15735 +#: gram.y:16240 gram.y:16253 #, c-format msgid "%s constraints cannot be marked DEFERRABLE" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s не могут иметь характериÑтики DEFERRABLE" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15748 +#: gram.y:16266 #, c-format msgid "%s constraints cannot be marked NOT VALID" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s не могут иметь характериÑтики NOT VALID" #. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:15761 +#: gram.y:16279 #, c-format msgid "%s constraints cannot be marked NO INHERIT" msgstr "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ %s не могут иметь характериÑтики NO INHERIT" -#: guc-file.l:313 +#: guc-file.l:315 #, c-format msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" msgstr "нераÑпознанный параметр конфигурации \"%s\" в файле \"%s\", Ñтроке %u" -#: guc-file.l:386 +#: guc-file.l:388 #, c-format msgid "parameter \"%s\" removed from configuration file, reset to default" msgstr "" "параметр \"%s\" удалён из файла конфигурации, он принимает значение по " "умолчанию" -#: guc-file.l:452 +#: guc-file.l:454 #, c-format msgid "parameter \"%s\" changed to \"%s\"" msgstr "параметр \"%s\" принÑл значение \"%s\"" -#: guc-file.l:494 +#: guc-file.l:496 #, c-format msgid "configuration file \"%s\" contains errors" msgstr "файл конфигурации \"%s\" Ñодержит ошибки" -#: guc-file.l:499 +#: guc-file.l:501 #, c-format msgid "" "configuration file \"%s\" contains errors; unaffected changes were applied" @@ -27339,76 +29025,76 @@ msgstr "" "файл конфигурации \"%s\" Ñодержит ошибки; были применены не завиÑимые " "изменениÑ" -#: guc-file.l:504 +#: guc-file.l:506 #, c-format msgid "configuration file \"%s\" contains errors; no changes were applied" msgstr "файл конфигурации \"%s\" Ñодержит ошибки; Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ были применены" -#: guc-file.l:577 +#: guc-file.l:579 #, c-format msgid "" "could not open configuration file \"%s\": maximum nesting depth exceeded" msgstr "" "открыть файл конфигурации \"%s\" не удалоÑÑŒ: превышен предел вложенноÑти" -#: guc-file.l:604 +#: guc-file.l:606 #, c-format msgid "skipping missing configuration file \"%s\"" msgstr "отÑутÑтвующий файл конфигурации \"%s\" пропуÑкаетÑÑ" -#: guc-file.l:858 +#: guc-file.l:860 #, c-format msgid "syntax error in file \"%s\" line %u, near end of line" msgstr "ошибка ÑинтакÑиÑа в файле \"%s\", в конце Ñтроки %u" -#: guc-file.l:868 +#: guc-file.l:870 #, c-format msgid "syntax error in file \"%s\" line %u, near token \"%s\"" msgstr "ошибка ÑинтакÑиÑа в файле \"%s\", в Ñтроке %u, Ñ€Ñдом Ñ \"%s\"" -#: guc-file.l:888 +#: guc-file.l:890 #, c-format msgid "too many syntax errors found, abandoning file \"%s\"" msgstr "" "обнаружено Ñлишком много ÑинтакÑичеÑких ошибок, обработка файла \"%s\" " "прекращаетÑÑ" -#: guc-file.l:940 +#: guc-file.l:942 #, c-format msgid "could not open configuration directory \"%s\": %m" msgstr "открыть каталог конфигурации \"%s\" не удалоÑÑŒ: %m" -#: repl_gram.y:320 repl_gram.y:352 +#: repl_gram.y:336 repl_gram.y:368 #, c-format msgid "invalid timeline %u" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u" -#: repl_scanner.l:125 +#: repl_scanner.l:129 msgid "invalid streaming start location" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° потока" -#: repl_scanner.l:176 scan.l:670 +#: repl_scanner.l:180 scan.l:683 msgid "unterminated quoted string" msgstr "Ð½ÐµÐ·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ñтрока в кавычках" -#: scan.l:432 +#: scan.l:445 msgid "unterminated /* comment" msgstr "незавершённый комментарий /*" -#: scan.l:461 +#: scan.l:474 msgid "unterminated bit string literal" msgstr "Ð¾Ð±Ð¾Ñ€Ð²Ð°Ð½Ð½Ð°Ñ Ð±Ð¸Ñ‚Ð¾Ð²Ð°Ñ Ñтрока" -#: scan.l:482 +#: scan.l:495 msgid "unterminated hexadecimal string literal" msgstr "Ð¾Ð±Ð¾Ñ€Ð²Ð°Ð½Ð½Ð°Ñ ÑˆÐµÑÑ‚Ð½Ð°Ð´Ñ†Ð°Ñ‚ÐµÑ€Ð¸Ñ‡Ð½Ð°Ñ Ñтрока" -#: scan.l:532 +#: scan.l:545 #, c-format msgid "unsafe use of string constant with Unicode escapes" msgstr "небезопаÑное иÑпользование Ñтроковой конÑтанты Ñо Ñпецкодами Unicode" -#: scan.l:533 +#: scan.l:546 #, c-format msgid "" "String constants with Unicode escapes cannot be used when " @@ -27417,31 +29103,31 @@ msgstr "" "Строки Ñо Ñпецкодами Unicode Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать, когда параметр " "standard_conforming_strings выключен." -#: scan.l:579 scan.l:778 +#: scan.l:592 scan.l:791 msgid "invalid Unicode escape character" msgstr "неверный Ñимвол Ñпецкода Unicode" -#: scan.l:605 scan.l:613 scan.l:621 scan.l:622 scan.l:623 scan.l:1337 -#: scan.l:1364 scan.l:1368 scan.l:1406 scan.l:1410 scan.l:1432 scan.l:1442 +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1379 +#: scan.l:1406 scan.l:1410 scan.l:1448 scan.l:1452 scan.l:1474 scan.l:1484 msgid "invalid Unicode surrogate pair" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑƒÑ€Ñ€Ð¾Ð³Ð°Ñ‚Ð½Ð°Ñ Ð¿Ð°Ñ€Ð° Unicode" -#: scan.l:627 +#: scan.l:640 #, c-format msgid "invalid Unicode escape" msgstr "неверный Ñпецкод Unicode" -#: scan.l:628 +#: scan.l:641 #, c-format msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." msgstr "Спецкоды Unicode должны иметь вид \\uXXXX или \\UXXXXXXXX." -#: scan.l:639 +#: scan.l:652 #, c-format msgid "unsafe use of \\' in a string literal" msgstr "небезопаÑное иÑпользование Ñимвола \\' в Ñтроке" -#: scan.l:640 +#: scan.l:653 #, c-format msgid "" "Use '' to write quotes in strings. \\' is insecure in client-only encodings." @@ -27449,35 +29135,35 @@ msgstr "" "ЗапиÑывайте апоÑтроф в Ñтроке в виде ''. ЗапиÑÑŒ \\' небезопаÑна Ð´Ð»Ñ " "иÑключительно клиентÑких кодировок." -#: scan.l:715 +#: scan.l:728 msgid "unterminated dollar-quoted string" msgstr "Ð½ÐµÐ·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ ÑпецÑтрока Ñ $" -#: scan.l:732 scan.l:758 scan.l:773 +#: scan.l:745 scan.l:771 scan.l:786 msgid "zero-length delimited identifier" msgstr "пуÑтой идентификатор в кавычках" -#: scan.l:793 syncrep_scanner.l:87 +#: scan.l:806 syncrep_scanner.l:91 msgid "unterminated quoted identifier" msgstr "незавершённый идентификатор в кавычках" -#: scan.l:924 +#: scan.l:969 msgid "operator too long" msgstr "Ñлишком длинный оператор" #. translator: %s is typically the translation of "syntax error" -#: scan.l:1077 +#: scan.l:1124 #, c-format msgid "%s at end of input" msgstr "%s в конце" #. translator: first %s is typically the translation of "syntax error" -#: scan.l:1085 +#: scan.l:1132 #, c-format msgid "%s at or near \"%s\"" msgstr "%s (примерное положение: \"%s\")" -#: scan.l:1251 scan.l:1283 +#: scan.l:1293 scan.l:1325 msgid "" "Unicode escape values cannot be used for code point values above 007F when " "the server encoding is not UTF8" @@ -27485,16 +29171,16 @@ msgstr "" "Спецкоды Unicode Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ð¹ выше 007F можно иÑпользовать только Ñ " "Ñерверной кодировкой UTF8" -#: scan.l:1279 scan.l:1424 +#: scan.l:1321 scan.l:1466 msgid "invalid Unicode escape value" msgstr "неверное значение Ñпецкода Unicode" -#: scan.l:1488 +#: scan.l:1530 #, c-format msgid "nonstandard use of \\' in a string literal" msgstr "неÑтандартное применение \\' в Ñтроке" -#: scan.l:1489 +#: scan.l:1531 #, c-format msgid "" "Use '' to write quotes in strings, or use the escape string syntax (E'...')." @@ -27502,27 +29188,627 @@ msgstr "" "ЗапиÑывайте апоÑтроф в Ñтроках в виде '' или иÑпользуйте ÑинтакÑÐ¸Ñ ÑпецÑтрок " "(E'...')." -#: scan.l:1498 +#: scan.l:1540 #, c-format msgid "nonstandard use of \\\\ in a string literal" msgstr "неÑтандартное применение \\\\ в Ñтроке" -#: scan.l:1499 +#: scan.l:1541 #, c-format msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." msgstr "" "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи обратных ÑлÑшей ÑинтакÑÐ¸Ñ ÑпецÑтрок, например E'\\\\'." -#: scan.l:1513 +#: scan.l:1555 #, c-format msgid "nonstandard use of escape in a string literal" msgstr "неÑтандартное иÑпользование ÑпецÑимвола в Ñтроке" -#: scan.l:1514 +#: scan.l:1556 #, c-format msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов ÑинтакÑÐ¸Ñ ÑпецÑтрок E'\\r\\n'." +#~ msgid "view must have at least one column" +#~ msgstr "в предÑтавлении должен быть минимум один Ñтолбец" + +#~ msgid "" +#~ "If you're sure there are no old server processes still running, remove " +#~ "the shared memory block or just delete the file \"%s\"." +#~ msgstr "" +#~ "ЕÑли вы уверены, что процеÑÑов Ñтарого Ñервера уже не оÑталоÑÑŒ, " +#~ "оÑвободите Ñтот блок разделÑемой памÑти или проÑто удалите файл \"%s\"." + +#~ msgid "" +#~ "cannot PREPARE a transaction that has operated on temporary namespace" +#~ msgstr "" +#~ "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ PREPARE Ð´Ð»Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸, оперирующей Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ð¼ " +#~ "проÑтранÑтвом имён" + +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "не удалоÑÑŒ открыть буферный файл \"%s\"" + +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "" +#~ "внешний ключ Ñекционированной таблицы \"%s\" не может добавлÑтьÑÑ Ñ ONLY" + +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "" +#~ "%s не может выполнÑтьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ функции или Ñтроки, включающей неÑколько " +#~ "команд" + +#~ msgid "no such savepoint" +#~ msgstr "нет такой точки ÑохранениÑ" + +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "не удалоÑÑŒ открыть каталог журнала предзапиÑи \"%s\": %m" + +#~ msgid "" +#~ "The database cluster was initialized with XLOG_SEG_SIZE %d, but the " +#~ "server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "" +#~ "КлаÑтер баз данных был инициализирован Ñ XLOG_SEG_SIZE %d, но Ñервер " +#~ "Ñкомпилирован Ñ XLOG_SEG_SIZE %d." + +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "иÑпользуетÑÑ Ð¿Ñ€ÐµÐ´Ñ‹Ð´ÑƒÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ контрольной точки по Ñмещению %X/%X" + +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑÑылка на вторичную контрольную точку в файле pg_control" + +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ вторичной контрольной точки" + +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "неверный ID менеджера реÑурÑов в запиÑи вторичной контрольной точки" + +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "неверные флаги xl_info в запиÑи вторичной контрольной точки" + +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° запиÑи вторичной контрольной точки" + +#~ msgid "" +#~ "WAL file is from different database system: incorrect XLOG_SEG_SIZE in " +#~ "page header" +#~ msgstr "" +#~ "файл WAL принадлежит другой СУБД: некорректный XLOG_SEG_SIZE в заголовке " +#~ "Ñтраницы" + +#~ msgid " in schema %s" +#~ msgstr " в Ñхеме %s" + +#~ msgid "%s in publication %s" +#~ msgstr "%s в публикации %s" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "таблица \"%s\" Ñодержит неÑколько ограничений Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "домен %s Ñодержит неÑколько ограничений Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ \"%s\"" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "\"%s\" уже ÑвлÑетÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð¾Ð¼ типа %s" + +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "\"%s\" - Ñто Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" + +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "\"%s\" - Ñто не Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" + +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "\"%s\" - Ñто не Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ" + +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ COPY Ñ Ñ„Ð°Ð¹Ð»Ð°Ð¼Ð¸ нужно быть Ñуперпользователем" + +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "копировать в Ñтороннюю таблицу \"%s\" нельзÑ" + +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "направить вÑтавлÑемые кортежи в Ñтороннюю таблицу нельзÑ" + +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "нераÑпознанный атрибут функции \"%s\" --- игнорируетÑÑ" + +#~ msgid "cast function must not be an aggregate function" +#~ msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ðµ может быть агрегатной" + +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ может быть агрегатной" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "неверный номер процедуры (%d), должен быть между 1 и %d" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "номер процедуры %d Ð´Ð»Ñ (%s,%s) дублируетÑÑ" + +#~ msgid "operator procedure must be specified" +#~ msgstr "должна быть указана процедура оператора" + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "Ñтолбец \"%s\" фигурирует в ключе Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð½ÐµÐ¾Ð´Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ð¾" + +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "" +#~ "Скорее закройте открытые транзакции, чтобы избежать проблемы наложениÑ." + +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "" +#~ "ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð¸Ñ€ÑƒÑŽÑ‰Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð»Ñ Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð° %u должна объÑвлÑтьÑÑ ÐºÐ°Ðº ÑÑ‚Ñ€Ð¾Ð³Ð°Ñ " +#~ "(STRICT)" + +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "клиенту требуетÑÑ Ð¿Ñ€Ð¸Ð²Ñзка канала SCRAM, но она не поддерживаетÑÑ" + +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "" +#~ "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ lo_import() на Ñервере нужно быть Ñуперпользователем" + +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "ИÑпользовать lo_import() на Ñтороне клиента через libpq могут вÑе." + +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "" +#~ "Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ lo_export() на Ñервере нужно быть Ñуперпользователем" + +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "ИÑпользовать lo_export() на Ñтороне клиента через libpq могут вÑе." + +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "" +#~ "предложение ON CONFLICT Ñ Ñекционированными таблицами не поддерживаетÑÑ" + +#~ msgid "primary key constraints are not supported on partitioned tables" +#~ msgstr "" +#~ "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ ключа Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" + +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "" +#~ "Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа Ð´Ð»Ñ Ñекционированных таблиц не поддерживаютÑÑ" + +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "не удалоÑÑŒ открыть каталог ÑоÑтоÑÐ½Ð¸Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð° \"%s\": %m" + +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s: параметр max_wal_senders должен быть меньше max_connections\n" + +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "к каталогу данных \"%s\" имеют доÑтуп вÑе или группа" + +#~ msgid "worker process" +#~ msgstr "рабочий процеÑÑ" + +#~ msgid "built-in type %u not found" +#~ msgstr "вÑтроенный тип %u не найден" + +#~ msgid "" +#~ "This can be caused by having a publisher with a higher PostgreSQL major " +#~ "version than the subscriber." +#~ msgstr "" +#~ "Это может быть вызвано тем, что на Ñервере публикации уÑтановлена более " +#~ "Ð½Ð¾Ð²Ð°Ñ Ð¾ÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ PostgreSQL, чем на подпиÑчике." + +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "" +#~ "тип данных \"%s.%s\", требуемый Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкой репликации, не ÑущеÑтвует" + +#~ msgid "" +#~ "logical replication could not find row for delete in replication target " +#~ "relation \"%s\"" +#~ msgstr "" +#~ "при логичеÑкой репликации не удалоÑÑŒ найти Ñтроку Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð² целевом " +#~ "отношении репликации \"%s\"" + +#~ msgid "memory for serializable conflict tracking is nearly exhausted" +#~ msgstr "" +#~ "памÑть Ð´Ð»Ñ Ð¾Ñ‚ÑÐ»ÐµÐ¶Ð¸Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾Ð½Ñ„Ð»Ð¸ÐºÑ‚Ð¾Ð² Ñериализации практичеÑки иÑчерпана" + +#~ msgid "" +#~ "There might be an idle transaction or a forgotten prepared transaction " +#~ "causing this." +#~ msgstr "" +#~ "ВероÑтно, Ñта ÑÐ¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ Ð²Ñ‹Ð·Ð²Ð°Ð½Ð° забытой подготовленной транзакцией или " +#~ "транзакцией, проÑтаивающей долгое времÑ." + +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "не удалоÑÑŒ открыть каталог табличного проÑтранÑтва \"%s\": %m" + +#~ msgid "must be superuser to get file information" +#~ msgstr "получать информацию о файлах может только Ñуперпользователь" + +#~ msgid "must be superuser to get directory listings" +#~ msgstr "читать Ñодержимое каталогов может только Ñуперпользователь" + +#~ msgid "" +#~ "Sets the maximum number of tuples to be sorted using replacement " +#~ "selection." +#~ msgstr "" +#~ "Задаёт предельное чиÑло кортежей, Ñортируемое поÑредÑтвом алгоритма " +#~ "выбора Ñ Ð·Ð°Ð¼ÐµÑ‰ÐµÐ½Ð¸ÐµÐ¼." + +#~ msgid "When more tuples than this are present, quicksort will be used." +#~ msgstr "" +#~ "Когда кортежей больше Ñтого количеÑтва, будет применÑтьÑÑ quicksort." + +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ UNBOUNDED" + +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING поддерживаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ UNBOUNDED" + +#~ msgid "invalid number of arguments: object must be matched key value pairs" +#~ msgstr "" +#~ "неверное чиÑло аргументов: объект должен ÑоÑтавлÑтьÑÑ Ð¸Ð· пар ключ-значение" + +#~ msgid "unsafe use of new value \"%s\" of enum type %s" +#~ msgstr "" +#~ "небезопаÑное иÑпользование нового Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"%s\" типа-перечиÑÐ»ÐµÐ½Ð¸Ñ %s" + +#~ msgid "New enum values must be committed before they can be used." +#~ msgstr "" +#~ "Ðовые Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÑ‡Ð¸ÑÐ»ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть зафикÑированы перед " +#~ "иÑпользованием." + +#~ msgid "invalid publish list" +#~ msgstr "неверный ÑпиÑок публикации" + +#~ msgid "column \"%s\" referenced in statistics does not exist" +#~ msgstr "Ñтолбец \"%s\", указанный в ÑтатиÑтике, не ÑущеÑтвует" + +#~ msgid "not connected to database" +#~ msgstr "нет Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº базе данных" + +#~ msgid "invalid input syntax for %s: \"%s\"" +#~ msgstr "неверный ÑинтакÑÐ¸Ñ Ð´Ð»Ñ %s: \"%s\"" + +#~ msgid "transaction ID " +#~ msgstr "идентификатор транзакции " + +#~ msgid "in progress" +#~ msgstr "выполнÑетÑÑ" + +#~ msgid "committed" +#~ msgstr "зафикÑирована" + +#~ msgid "aborted" +#~ msgstr "прервана" + +#~ msgid "could not get keyword values for locale \"%s\": %s" +#~ msgstr "не удалоÑÑŒ получить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\": %s" + +#~ msgid "index row size %lu exceeds maximum %lu for index \"%s\"" +#~ msgstr "" +#~ "размер Ñтроки индекÑа (%lu) больше предельного размера (%lu) (Ð¸Ð½Ð´ÐµÐºÑ \"" +#~ "%s\")" + +#~ msgid "" +#~ "brin operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов brin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "опорным номером %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов brin \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов brin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "номером Ñтратегии %d" + +#~ msgid "" +#~ "brin operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "ÑемейÑтво операторов brin \"%s\" Ñодержит некорректное определение ORDER " +#~ "BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" + +#~ msgid "" +#~ "brin operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "ÑемейÑтво операторов brin \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением" + +#~ msgid "brin operator class \"%s\" is missing support function %d" +#~ msgstr "в клаÑÑе операторов brin \"%s\" нет опорной функции %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains support procedure %s with cross-type " +#~ "registration" +#~ msgstr "" +#~ "ÑемейÑтво операторов gist \"%s\" Ñодержит опорную процедуру %s Ñ " +#~ "межтиповой региÑтрацией" + +#~ msgid "" +#~ "gist operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов gist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "опорным номером %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов gist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов gist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "номером Ñтратегии %d" + +#~ msgid "" +#~ "gist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "ÑемейÑтво операторов gist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением" + +#~ msgid "gist operator class \"%s\" is missing support function %d" +#~ msgstr "в клаÑÑе операторов gist \"%s\" нет опорной функции %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains support procedure %s with cross-type " +#~ "registration" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит опорную процедуру %s Ñ " +#~ "межтиповой региÑтрацией" + +#~ msgid "" +#~ "hash operator family \"%s\" contains function %s with wrong signature for " +#~ "support number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "опорным номером %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "номером Ñтратегии %d" + +#~ msgid "" +#~ "hash operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит некорректное определение ORDER " +#~ "BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" + +#~ msgid "" +#~ "hash operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "ÑемейÑтво операторов hash \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением" + +#~ msgid "" +#~ "hash operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в ÑемейÑтве операторов hash \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" + +#~ msgid "hash operator class \"%s\" is missing operator(s)" +#~ msgstr "в клаÑÑе операторов hash \"%s\" нет оператора(ов)" + +#~ msgid "" +#~ "btree operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов btree \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "опорным номером %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains function %s with wrong signature " +#~ "for support number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов btree \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов btree \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "номером Ñтратегии %d" + +#~ msgid "" +#~ "btree operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "ÑемейÑтво операторов btree \"%s\" Ñодержит некорректное определение ORDER " +#~ "BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" + +#~ msgid "" +#~ "btree operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "ÑемейÑтво операторов btree \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением" + +#~ msgid "" +#~ "btree operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в ÑемейÑтве операторов btree \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" + +#~ msgid "btree operator class \"%s\" is missing operator(s)" +#~ msgstr "в клаÑÑе операторов btree \"%s\" нет оператора(ов)" + +#~ msgid "btree operator family \"%s\" is missing cross-type operator(s)" +#~ msgstr "в ÑемейÑтве операторов btree \"%s\" нет межтипового оператора(ов)" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains support procedure %s with cross-" +#~ "type registration" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит опорную процедуру %s Ñ " +#~ "межтиповой региÑтрацией" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains function %s with invalid support " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "опорным номером %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains function %s with wrong signature " +#~ "for support number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит функцию %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением Ð´Ð»Ñ Ð¾Ð¿Ð¾Ñ€Ð½Ð¾Ð³Ð¾ номера %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains operator %s with invalid strategy " +#~ "number %d" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ñ‹Ð¼ " +#~ "номером Ñтратегии %d" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains invalid ORDER BY specification for " +#~ "operator %s" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит некорректное определение " +#~ "ORDER BY Ð´Ð»Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° %s" + +#~ msgid "" +#~ "spgist operator family \"%s\" contains operator %s with wrong signature" +#~ msgstr "" +#~ "ÑемейÑтво операторов spgist \"%s\" Ñодержит оператор %s Ñ Ð½ÐµÐ¿Ð¾Ð´Ñ…Ð¾Ð´Ñщим " +#~ "объÑвлением" + +#~ msgid "" +#~ "spgist operator family \"%s\" is missing operator(s) for types %s and %s" +#~ msgstr "" +#~ "в ÑемейÑтве операторов spgist \"%s\" нет оператора(ов) Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð¾Ð² %s и %s" + +#~ msgid "spgist operator class \"%s\" is missing operator(s)" +#~ msgstr "в клаÑÑе операторов spgist \"%s\" нет оператора(ов)" + +#~ msgid "cannot create temporary tables in parallel mode" +#~ msgstr "Ñоздавать временные таблицы в параллельном режиме нельзÑ" + +#~ msgid "cannot create range partition with empty range" +#~ msgstr "Ñоздать диапазонную Ñекцию Ñ Ð¿ÑƒÑтым диапазоном нельзÑ" + +#~ msgid "could get display name for locale \"%s\": %s" +#~ msgstr "не удалоÑÑŒ получить отображаемое название локали \"%s\": %s" + +#~ msgid "synchronized table states" +#~ msgstr "ÑоÑтоÑние таблиц Ñинхронизировано" + +#~ msgid "added subscription for table %s.%s" +#~ msgstr "добавлена подпиÑка на таблицу %s.%s" + +#~ msgid "removed subscription for table %s.%s" +#~ msgstr "удалена подпиÑка на таблицу %s.%s" + +#~ msgid "malformed SCRAM message (length mismatch)" +#~ msgstr "неправильное Ñообщение SCRAM (Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°)" + +#~ msgid "invalid SCRAM response (nonce mismatch)" +#~ msgstr "неверный ответ SCRAM (неÑовпадение проверочного кода)" + +#~ msgid "malformed SCRAM message (attribute '%c' expected, %s found)" +#~ msgstr "неправильное Ñообщение SCRAM (ожидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ '%c', получено: %s)" + +#~ msgid "malformed SCRAM message (expected = in attr %c)" +#~ msgstr "неправильное Ñообщение SCRAM (в атрибуте %c ожидалоÑÑŒ =)" + +#~ msgid "malformed SCRAM message (attribute expected, invalid char %s found)" +#~ msgstr "" +#~ "неправильное Ñообщение SCRAM (ожидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚, получен некорректный " +#~ "Ñимвол %s)" + +#~ msgid "malformed SCRAM message (comma expected, got %s)" +#~ msgstr "неправильное Ñообщение SCRAM (ожидалаÑÑŒ запÑтаÑ, получено: %s)" + +#~ msgid "User \"%s\" has an empty password." +#~ msgstr "У Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\" пуÑтой пароль." + +#~ msgid "cannot specify finite value after UNBOUNDED" +#~ msgstr "указать конечное значение поÑле UNBOUNDED нельзÑ" + +#~ msgid "could not determine data type for argument 1" +#~ msgstr "не удалоÑÑŒ определить тип данных аргумента 1" + +#~ msgid "could not determine data type for argument 2" +#~ msgstr "не удалоÑÑŒ определить тип данных аргумента 2" + +#~ msgid "argument %d: could not determine data type" +#~ msgstr "аргумент %d: не удалоÑÑŒ определить тип данных" + +#~ msgid "could not open transaction log file \"%s\": %m" +#~ msgstr "не удалоÑÑŒ открыть файл журнала транзакций \"%s\": %m" + +#~ msgid "removing transaction log backup history file \"%s\"" +#~ msgstr "удалÑетÑÑ Ñ„Ð°Ð¹Ð» иÑтории ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð°: \"%s\"" + +#~ msgid "range partition key of row contains null" +#~ msgstr "ключ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð¿Ð¾ диапазонам в Ñтроке таблицы Ñодержит NULL" + +#~ msgid "extended statistics \"%s\" do not exist, skipping" +#~ msgstr "раÑÑˆÐ¸Ñ€ÐµÐ½Ð½Ð°Ñ ÑтатиÑтика \"%s\" не ÑущеÑтвует, пропуÑкаетÑÑ" + +#~ msgid "only scalar types can be used in extended statistics" +#~ msgstr "в раÑширенной ÑтатиÑтике могут иÑпользоватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ ÑкалÑрные типы" + +#~ msgid "unrecognized STATISTICS option \"%s\"" +#~ msgstr "нераÑпознанное указание Ð´Ð»Ñ STATISTICS: \"%s\"" + +#~ msgid "must truncate child tables too" +#~ msgstr "опуÑтошатьÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ также и дочерние таблицы" + +#~ msgid "constraint must be dropped from child tables too" +#~ msgstr "ограничение также должно удалÑтьÑÑ Ð¸Ð· дочерних таблиц" + +#~ msgid "column \"%s\" is in range partition key" +#~ msgstr "Ñтолбец \"%s\" входит в ключ Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð¿Ð¾ диапазонам" + +#~ msgid "column must be dropped from child tables too" +#~ msgstr "Ñтолбец также должен удалÑтьÑÑ Ð¸Ð· дочерних таблиц" + +#~ msgid "transaction log switch forced (archive_timeout=%d)" +#~ msgstr "принудительное переключение журнала транзакций (archive_timeout=%d)" + +#~ msgid "archived transaction log file \"%s\"" +#~ msgstr "файл архива журнала транзакций \"%s\"" + +#~ msgid "Transaction ID %u finished; no more running transactions." +#~ msgstr "Ð¢Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ %u завершена, больше активных транзакций нет." + +#~ msgid "%u transaction needs to finish." +#~ msgid_plural "%u transactions need to finish." +#~ msgstr[0] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." +#~ msgstr[1] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." +#~ msgstr[2] "Ðеобходимо дождатьÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¹ (%u)." + +#~ msgid "Consider ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" +#~ msgstr "Попробуйте ALTER TABLE \"%s\".\"%s\" ALTER \"%s\" SET STATISTICS -1" + +#~ msgid "select() failed: %m" +#~ msgstr "ошибка в select(): %m" + +#~ msgid "could not attach to dsa_handle" +#~ msgstr "не удалоÑÑŒ подключитьÑÑ Ðº dsa" + +#~ msgid "unrecognized option \"%s\"" +#~ msgstr "нераÑпознанный параметр \"%s\"" + #~ msgid "could not remove old transaction log file \"%s\": %m" #~ msgstr "не удалоÑÑŒ Ñтереть Ñтарый файл журнала транзакций \"%s\": %m" @@ -27603,8 +29889,8 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ "хеш-индекÑÑ‹ не запиÑываютÑÑ Ð² журнал, иÑпользовать их не рекомендуетÑÑ" #~ msgid "" -#~ "changing return type of function %s from \"opaque\" to \"language_handler" -#~ "\"" +#~ "changing return type of function %s from \"opaque\" to " +#~ "\"language_handler\"" #~ msgstr "" #~ "тип возврата функции %s менÑетÑÑ Ñ \"opaque\" на \"language_handler\"" @@ -27692,11 +29978,8 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ "not enough shared memory for elements of data structure \"%s\" (%zu bytes " #~ "requested)" #~ msgstr "" -#~ "недоÑтаточно разделÑемой памÑти Ð´Ð»Ñ Ñлементов Ñтруктуры данных \"%s" -#~ "\" (запрошено байт: %zu)" - -#~ msgid "corrupted item pointer: offset = %u, length = %u" -#~ msgstr "иÑпорченный указатель Ñлемента: Ñмещение = %u, длина = %u" +#~ "недоÑтаточно разделÑемой памÑти Ð´Ð»Ñ Ñлементов Ñтруктуры данных \"%s\" " +#~ "(запрошено байт: %zu)" #~ msgid "invalid input syntax for type boolean: \"%s\"" #~ msgstr "неверное значение Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸Ñ‡ÐµÑкого типа: \"%s\"" @@ -27713,9 +29996,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" #~ msgstr "шаблоны формата \"TZ\"/\"tz\"/\"OF\" не поддерживаютÑÑ Ð² to_date" -#~ msgid "invalid input syntax for integer: \"%s\"" -#~ msgstr "неверное значение Ð´Ð»Ñ Ñ†ÐµÐ»Ð¾Ð³Ð¾ чиÑла: \"%s\"" - #~ msgid "value \"%s\" is out of range for type bigint" #~ msgstr "значение \"%s\" вне диапазона Ð´Ð»Ñ Ñ‚Ð¸Ð¿Ð° bigint" @@ -28017,9 +30297,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "must be superuser to signal the postmaster" #~ msgstr "Ñигнализировать процеÑÑу postmaster может только Ñуперпользователь" -#~ msgid "must be superuser to rotate log files" -#~ msgstr "прокрутить файлы протоколов может только Ñуперпользователь" - #~ msgid "argument for function \"exp\" too big" #~ msgstr "аргумент функции \"exp\" Ñлишком велик" @@ -28065,9 +30342,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "commit timestamp Xid oldest/newest: %u/%u" #~ msgstr "ÑтарейшаÑ/Ð½Ð¾Ð²ÐµÐ¹ÑˆÐ°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ñ Ð¼ÐµÑ‚ÐºÐ¾Ð¹ времени: %u/%u" -#~ msgid "Table %s is temporary." -#~ msgstr "Таблица %s - временнаÑ." - #~ msgid "cannot change status of table %s to logged" #~ msgstr "Ñделать таблицу %s журналируемой нельзÑ" @@ -28102,9 +30376,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "arg %d: key cannot be null" #~ msgstr "аргумент %d: ключ не может быть NULL" -#~ msgid "too many parallel workers already attached" -#~ msgstr "уже подключено Ñлишком много параллельных иÑполнителей" - #~ msgid "" #~ "\"%s\" is not a table, materialized view, composite type, or foreign table" #~ msgstr "" @@ -28216,8 +30487,8 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgstr "" #~ "автоматичеÑÐºÐ°Ñ Ð¾Ñ‡Ð¸Ñтка таблицы \"%s.%s.%s\": Ñканирований индекÑа: %d\n" #~ "Ñтраниц удалено: %d, оÑталоÑÑŒ: %d\n" -#~ "кортежей удалено: %.0f, оÑталоÑÑŒ: %.0f, мёртвых (но пока неудалÑемых): " -#~ "%.0f\n" +#~ "кортежей удалено: %.0f, оÑталоÑÑŒ: %.0f, мёртвых (но пока неудалÑемых): %." +#~ "0f\n" #~ "иÑпользование буфера: попаданий: %d, промахов: %d, загрÑзнено: %d\n" #~ "ÑреднÑÑ ÑкороÑть чтениÑ: %.3f МБ/Ñек, ÑреднÑÑ ÑкороÑть запиÑи: %.3f МБ/" #~ "Ñек\n" @@ -28323,9 +30594,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ "Задаёт макÑимальное раÑÑтоÑние в Ñегментах журнала между автоматичеÑкими " #~ "контрольными точками WAL." -#~ msgid "SET AUTOCOMMIT TO OFF is no longer supported" -#~ msgstr "SET AUTOCOMMIT TO OFF больше не поддерживаетÑÑ" - #~ msgid "assertion checking is not supported by this build" #~ msgstr "в данной Ñборке не поддерживаютÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ иÑтинноÑти" @@ -28416,9 +30684,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "could not seek to the end of file \"%s\": %m" #~ msgstr "не удалоÑÑŒ перейти к концу файла \"%s\": %m" -#~ msgid "could not unlink file \"%s\": %m" -#~ msgstr "ошибка при удалении файла \"%s\": %m" - #~ msgid "cannot call %s with null path elements" #~ msgstr "вызывать %s Ñ Ñлементами пути, равными NULL, нельзÑ" @@ -28480,9 +30745,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "%s: could not determine user name (GetUserName failed)\n" #~ msgstr "%s: не удалоÑÑŒ определить Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (ошибка в GetUserName)\n" -#~ msgid "too many column aliases specified for function %s" -#~ msgstr "Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ %s указано Ñлишком много названий Ñтолбцов" - #~ msgid "Expected 1 tuple with 3 fields, got %d tuples with %d fields." #~ msgstr "" #~ "ОжидалÑÑ 1 кортеж Ñ 3 полÑми, однако получено кортежей: %d, полей: %d." @@ -28501,9 +30763,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "cannot call json_object_keys on an array" #~ msgstr "вызывать json_object_keys Ñ Ð¼Ð°ÑÑивом нельзÑ" -#~ msgid "cannot call json_object_keys on a scalar" -#~ msgstr "вызывать json_object_keys Ñо ÑкалÑром нельзÑ" - #~ msgid "cannot call json_array_elements on a non-array" #~ msgstr "json_array_elements можно вызывать только Ð´Ð»Ñ Ð¼Ð°ÑÑива" @@ -28549,9 +30808,6 @@ msgstr "ИÑпользуйте Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи ÑпецÑимволов Ñи #~ msgid "window functions cannot use named arguments" #~ msgstr "у оконных функций не может быть именованных аргументов" -#~ msgid "invalid list syntax for \"listen_addresses\"" -#~ msgstr "неверный формат ÑпиÑка Ð´Ð»Ñ \"listen_addresses\"" - #~ msgid "invalid list syntax for \"unix_socket_directories\"" #~ msgstr "неверный формат ÑпиÑка Ð´Ð»Ñ \"unix_socket_directories\"" diff --git a/src/backend/po/sv.po b/src/backend/po/sv.po new file mode 100644 index 00000000000..04578042265 --- /dev/null +++ b/src/backend/po/sv.po @@ -0,0 +1,27083 @@ +# Swedish message translation file for postgresql +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. +# +# MÃ¥nga av termerna är tekniska termer som refererar till begrepp i SQL-satser och liknande. Om man +# översätter vissa av dessa sÃ¥ kommer det bli väldigt svÃ¥rt för användaren att förstÃ¥ vad vi menar. +# För mÃ¥nga av dessa har jag valt att behÃ¥lla det engelska ordet som ett begrepp. Det är en svÃ¥r +# balansgÃ¥ng. +# +# T.ex. ett integritetsvillkor som deklarerats med flaggan DEFERRABLE har jag i text som +# tar upp det lämnat kvar begreppet deferrable. T.ex: +# +# att ange deferrable för integritetsvillkor stöds inte för domäner +# +# PÃ¥ mÃ¥nga ställen är det svÃ¥rt att avgöra. Ta t.ex. integer som ibland refererar till typen integer och +# ibland refererar mer allmänt till heltal. +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-07 12:12+0000\n" +"PO-Revision-Date: 2019-06-07 23:23+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 +msgid "not recorded" +msgstr "ej sparad" + +#: ../common/controldata_utils.c:68 commands/copy.c:3547 +#: commands/extension.c:3341 utils/adt/genfile.c:153 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" + +#: ../common/controldata_utils.c:86 access/transam/timeline.c:347 +#: access/transam/twophase.c:1293 access/transam/xlog.c:3456 +#: access/transam/xlog.c:4603 access/transam/xlog.c:10779 +#: access/transam/xlog.c:10792 access/transam/xlog.c:11217 +#: access/transam/xlog.c:11297 access/transam/xlog.c:11336 +#: access/transam/xlog.c:11379 access/transam/xlogfuncs.c:663 +#: access/transam/xlogfuncs.c:682 commands/extension.c:3351 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3308 +#: replication/logical/snapbuild.c:1746 replication/logical/snapbuild.c:1788 +#: replication/logical/snapbuild.c:1816 replication/logical/snapbuild.c:1843 +#: replication/slot.c:1424 replication/slot.c:1465 replication/walsender.c:513 +#: storage/file/copydir.c:195 utils/adt/genfile.c:170 utils/adt/misc.c:753 +#: utils/cache/relmapper.c:741 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" + +#: ../common/controldata_utils.c:97 access/transam/twophase.c:1296 +#: access/transam/xlog.c:3461 access/transam/xlog.c:4608 +#: replication/logical/origin.c:722 replication/logical/origin.c:761 +#: replication/logical/snapbuild.c:1751 replication/logical/snapbuild.c:1793 +#: replication/logical/snapbuild.c:1821 replication/logical/snapbuild.c:1848 +#: replication/slot.c:1428 replication/slot.c:1469 replication/walsender.c:518 +#: utils/cache/relmapper.c:745 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" + +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:256 +#: access/heap/rewriteheap.c:1208 access/heap/rewriteheap.c:1310 +#: access/transam/timeline.c:377 access/transam/timeline.c:421 +#: access/transam/timeline.c:499 access/transam/twophase.c:1305 +#: access/transam/twophase.c:1728 access/transam/xlog.c:3328 +#: access/transam/xlog.c:3496 access/transam/xlog.c:3501 +#: access/transam/xlog.c:3798 access/transam/xlog.c:4573 +#: access/transam/xlog.c:5522 access/transam/xlogfuncs.c:688 +#: commands/copy.c:1815 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:535 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3366 +#: replication/logical/snapbuild.c:1658 replication/logical/snapbuild.c:1856 +#: replication/slot.c:1322 replication/slot.c:1476 replication/walsender.c:528 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:654 +#: storage/file/fd.c:3308 storage/file/fd.c:3411 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: ../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "byte-ordning stämmer inte" + +#: ../common/controldata_utils.c:197 access/heap/rewriteheap.c:1293 +#: access/transam/timeline.c:111 access/transam/timeline.c:236 +#: access/transam/timeline.c:333 access/transam/twophase.c:1249 +#: access/transam/xlog.c:3230 access/transam/xlog.c:3370 +#: access/transam/xlog.c:3411 access/transam/xlog.c:3609 +#: access/transam/xlog.c:3694 access/transam/xlog.c:3772 +#: access/transam/xlog.c:4593 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1489 replication/basebackup.c:517 +#: replication/basebackup.c:1394 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2308 +#: replication/logical/reorderbuffer.c:2575 +#: replication/logical/reorderbuffer.c:3288 +#: replication/logical/snapbuild.c:1613 replication/logical/snapbuild.c:1717 +#: replication/slot.c:1396 replication/walsender.c:486 +#: replication/walsender.c:2450 storage/file/copydir.c:161 +#: storage/file/fd.c:629 storage/file/fd.c:3295 storage/file/fd.c:3382 +#: storage/smgr/md.c:462 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1861 +#: utils/init/miscinit.c:1269 utils/init/miscinit.c:1404 +#: utils/init/miscinit.c:1481 utils/misc/guc.c:8060 utils/misc/guc.c:8092 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" + +#: ../common/controldata_utils.c:221 access/transam/twophase.c:1701 +#: access/transam/twophase.c:1710 access/transam/xlog.c:10536 +#: access/transam/xlog.c:10574 access/transam/xlog.c:10987 +#: access/transam/xlogfuncs.c:742 postmaster/syslogger.c:1500 +#: postmaster/syslogger.c:1513 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" + +#: ../common/controldata_utils.c:239 access/heap/rewriteheap.c:981 +#: access/heap/rewriteheap.c:1202 access/heap/rewriteheap.c:1304 +#: access/transam/timeline.c:415 access/transam/timeline.c:493 +#: access/transam/twophase.c:1722 access/transam/xlog.c:3321 +#: access/transam/xlog.c:3490 access/transam/xlog.c:4566 +#: access/transam/xlog.c:10054 access/transam/xlog.c:10080 +#: replication/logical/snapbuild.c:1651 replication/slot.c:1312 +#: replication/slot.c:1406 storage/file/fd.c:646 storage/file/fd.c:3403 +#: storage/smgr/md.c:885 storage/smgr/md.c:918 storage/sync/sync.c:395 +#: utils/cache/relmapper.c:885 utils/misc/guc.c:7840 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "kunde inte fsync:a fil \"%s\": %m" + +#: ../common/exec.c:138 ../common/exec.c:255 ../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../common/exec.c:157 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "ogiltig binär \"%s\"" + +#: ../common/exec.c:207 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "kunde inte läsa binär \"%s\"" + +#: ../common/exec.c:215 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "kunde inte hitta en \"%s\" att köra" + +#: ../common/exec.c:271 ../common/exec.c:310 utils/init/miscinit.c:220 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: ../common/exec.c:288 access/transam/xlog.c:10409 +#: replication/basebackup.c:1232 utils/adt/misc.c:324 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" + +#: ../common/exec.c:541 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../common/exec.c:670 ../common/exec.c:715 ../common/exec.c:807 +#: ../common/psprintf.c:143 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1394 access/transam/xlog.c:6346 +#: lib/dshash.c:246 lib/stringinfo.c:283 libpq/auth.c:1093 libpq/auth.c:1483 +#: libpq/auth.c:1551 libpq/auth.c:2069 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2454 +#: postmaster/postmaster.c:2476 postmaster/postmaster.c:4068 +#: postmaster/postmaster.c:4757 postmaster/postmaster.c:4832 +#: postmaster/postmaster.c:5509 postmaster/postmaster.c:5856 +#: replication/libpqwalreceiver/libpqwalreceiver.c:257 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:795 storage/file/fd.c:1191 storage/file/fd.c:1352 +#: storage/file/fd.c:2161 storage/ipc/procarray.c:1047 +#: storage/ipc/procarray.c:1542 storage/ipc/procarray.c:1549 +#: storage/ipc/procarray.c:1973 storage/ipc/procarray.c:2600 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1603 utils/adt/formatting.c:1726 +#: utils/adt/formatting.c:1850 utils/adt/pg_locale.c:473 +#: utils/adt/pg_locale.c:637 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4634 utils/misc/guc.c:4650 utils/misc/guc.c:4663 +#: utils/misc/guc.c:7818 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 +#: utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 +#: utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 +#: utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 +#: utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 +#, c-format +msgid "out of memory" +msgstr "slut pÃ¥ minne" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:145 ../port/path.c:632 +#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:176 +#: utils/misc/ps_status.c:184 utils/misc/ps_status.c:214 +#: utils/misc/ps_status.c:222 +#, c-format +msgid "out of memory\n" +msgstr "slut pÃ¥ minne\n" + +#: ../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../common/logging.c:195 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../common/relpath.c:58 +#, c-format +msgid "invalid fork name" +msgstr "ogiltigt fork-namn" + +#: ../common/relpath.c:59 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Giltiga fork-värden är \"main\", \"fsm\", \"vm\" och \"init\"." + +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "lösenorder är för lÃ¥ngt" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "kunde inte slÃ¥ upp effektivt användar-id %ld: %s" + +#: ../common/username.c:45 libpq/auth.c:2016 +msgid "user does not exist" +msgstr "användaren finns inte" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "misslyckad sökning efter användarnamn: felkod %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "kommandot är inte körbart" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "kommandot kan ej hittas" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "barnprocess avslutade med kod %d" + +#: ../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "barnprocess terminerades med avbrott 0x%X" + +#: ../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" + +#: ../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "barnprocess avslutade med okänd statuskod %d" + +#: ../port/chklocale.c:288 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "kunde inte bestämma kodning för teckentabell \"%s\"" + +#: ../port/chklocale.c:409 ../port/chklocale.c:415 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "kunde inte bestämma kodning för lokal \"%s\": teckentabellen är \"%s\"" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "kunde inte sätta knutpunkt (junction) för \"%s\": %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "kunde inte sätta knutpunkt (junktion) för \"%s\": %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "kunde inte hämta knutpunkt (junction) för \"%s\": %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "kunde inte hämta knutpunkt (junction) för \"%s\": %s\n" + +#: ../port/open.c:128 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "kunde inte öppna fil \"%s\": %s" + +#: ../port/open.c:129 +msgid "lock violation" +msgstr "lÃ¥s-överträdelse" + +#: ../port/open.c:129 +msgid "sharing violation" +msgstr "sharing-överträdelse" + +#: ../port/open.c:130 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "Fortsätter att försöka i 30 sekunder." + +#: ../port/open.c:131 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Du kan ha antivirus, backup eller liknande mjukvara som stör databassystemet" + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "kunde inte fastställa nuvarande arbetskatalog: %s\n" + +#: ../port/strerror.c:72 +#, c-format +msgid "operating system error %d" +msgstr "operativsystemfel %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "kunde inte hämta SID för Administratörsgrupp: felkod %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "kunde inte hämta SID för PowerUser-grupp: felkod %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "kunde inte kontrollera access-token-medlemskap: felkod %lu\n" + +#: access/brin/brin.c:204 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "förfrÃ¥gan efter BRIN-intervallsummering för index \"%s\" sida %u har inte spelats in" + +#: access/brin/brin.c:881 access/brin/brin.c:958 access/gin/ginfast.c:1041 +#: access/transam/xlog.c:10189 access/transam/xlog.c:10718 +#: access/transam/xlogfuncs.c:289 access/transam/xlogfuncs.c:316 +#: access/transam/xlogfuncs.c:355 access/transam/xlogfuncs.c:376 +#: access/transam/xlogfuncs.c:397 access/transam/xlogfuncs.c:467 +#: access/transam/xlogfuncs.c:524 +#, c-format +msgid "recovery is in progress" +msgstr "Ã¥terställning pÃ¥gÃ¥r" + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN-kontrollfunktioner kan inte köras under Ã¥terställning." + +#: access/brin/brin.c:890 access/brin/brin.c:967 +#, c-format +msgid "block number out of range: %s" +msgstr "blocknummer är utanför giltigt intervall: %s" + +#: access/brin/brin.c:913 access/brin/brin.c:990 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" är inte ett BRIN-index" + +#: access/brin/brin.c:929 access/brin/brin.c:1006 +#, c-format +msgid "could not open parent table of index %s" +msgstr "kunde inte öppna föräldratabell för index %s" + +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1445 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "indexradstorlek %zu överstiger maximum %zu för index \"%s\"" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "trasigt BRIN-index: inkonsistent intervall-map" + +#: access/brin/brin_revmap.c:404 +#, c-format +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "kvarlämnad platshÃ¥llartuple hittad i BRIN-index \"%s\", raderar" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr "oväntad sidtyp 0x%04X i BRIN-index \"%s\" block %u" + +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller funktion %s med ogiltigt supportnummer %d" + +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller funktion %s med felaktig signatur för supportnummer %d" + +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:197 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller operator %s med ogiltigt strateginummer %d" + +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:213 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller ogiltig ORDER BY-specifikatioon för operator %s" + +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:229 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller operator %s med felaktig signatur" + +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:256 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar operator(er) för typerna %s och %s" + +#: access/brin/brin_validate.c:244 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknas supportfunktion(er) för typerna %s och %s" + +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:289 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "operatorklass \"%s\" för accessmetoden %s saknar operator(er)" + +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "operatorklass \"%s\" för accessmetod %s saknar supportfunktion %d" + +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "antalet kolumner (%d) överskrider gränsen (%d)" + +#: access/common/indextuple.c:63 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "antalet indexerade kolumner (%d) överskrider gränsen (%d)" + +#: access/common/indextuple.c:179 access/spgist/spgutils.c:691 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "indexrad kräver %zu byte, maximal storlek är %zu" + +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1834 +#, c-format +msgid "unsupported format code: %d" +msgstr "ej stödd formatkod: %d" + +#: access/common/reloptions.c:582 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "överskriden gräns för användardefinierade relationsparametertyper" + +#: access/common/reloptions.c:863 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET fÃ¥r inte ha med värden pÃ¥ parametrar" + +#: access/common/reloptions.c:895 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "okänd parameternamnrymd \"%s\"" + +#: access/common/reloptions.c:932 utils/misc/guc.c:11746 +#, c-format +msgid "tables declared WITH OIDS are not supported" +msgstr "tabeller deklarerade med WITH OIDS stöds inte" + +#: access/common/reloptions.c:1150 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "okänd parameter \"%s\"" + +#: access/common/reloptions.c:1180 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "parameter \"%s\" angiven mer än en gÃ¥ng" + +#: access/common/reloptions.c:1196 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "ogiltigt värde för booleansk flagga \"%s\": \"%s\"" + +#: access/common/reloptions.c:1208 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "ogiltigt värde för heltalsflagga \"%s\": \"%s\"" + +#: access/common/reloptions.c:1214 access/common/reloptions.c:1234 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "värdet %s är utanför sitt intervall för flaggan \"%s\"" + +#: access/common/reloptions.c:1216 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Giltiga värden är mellan \"%d\" och \"%d\"." + +#: access/common/reloptions.c:1228 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "ogiltigt värde för flyttalsflagga \"%s\": %s" + +#: access/common/reloptions.c:1236 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Giltiga värden är mellan \"%f\" och \"%f\"." + +#: access/common/tupconvert.c:107 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Returnerad typ %s matchar inte förväntad type %s i kolumn %d." + +#: access/common/tupconvert.c:135 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "Antalet returnerade kolumner (%d) matchar inte förväntat antal kolumner (%d)." + +#: access/common/tupconvert.c:303 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "Attribut \"%s\" för typ %s matchar inte motsvarande attribut för typ %s." + +#: access/common/tupconvert.c:315 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "Attribut \"%s\" i typ %s finns inte i typ %s." + +#: access/common/tupdesc.c:842 parser/parse_clause.c:779 +#: parser/parse_relation.c:1578 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "kolumn \"%s\" kan inte deklareras som SETOF" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "post-listan är för lÃ¥ng" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "Minska maintenance_work_mem." + +#: access/gin/ginfast.c:1042 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "väntande GIN-lista kan inte städas upp under Ã¥terställning." + +#: access/gin/ginfast.c:1049 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" är inte ett GIN-index" + +#: access/gin/ginfast.c:1060 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "kan inte flytta temporära index tillhörande andra sessioner" + +#: access/gin/ginscan.c:402 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "gamla GIN-index stöder inte hela-index-scan eller sökningar efter null" + +#: access/gin/ginscan.c:403 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "För att fixa detta, kör REINDEX INDEX \"%s\"." + +#: access/gin/ginutil.c:139 executor/execExpr.c:1860 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6416 +#: utils/adt/rowtypes.c:936 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "kunde inte hitta nÃ¥gon jämförelsefunktion för typen %s" + +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "operatorfamilj \"%s\" för accessmetod %s innehÃ¥ller supportfunktion %s med olika vänster- och höger-inputtyper" + +#: access/gin/ginvalidate.c:257 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "operatorklass \"%s\" för accessmetod \"%s\" saknar supportfunktion %d eller %d" + +#: access/gist/gist.c:751 access/gist/gistvacuum.c:424 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "index \"%s\" innehÃ¥ller en inre tupel som är markerad ogiltig" + +#: access/gist/gist.c:753 access/gist/gistvacuum.c:426 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Detta orsakas av en inkomplett siduppdelning under krashÃ¥terställning körd innan uppdatering till PostgreSQL 9.1." + +#: access/gist/gist.c:754 access/gist/gistutil.c:787 access/gist/gistutil.c:798 +#: access/gist/gistvacuum.c:427 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:747 +#: access/nbtree/nbtpage.c:758 +#, c-format +msgid "Please REINDEX it." +msgstr "Var vänlig och kör REINDEX pÃ¥ det." + +#: access/gist/gistbuild.c:253 +#, c-format +msgid "invalid value for \"buffering\" option" +msgstr "ogiltigt argument till \"buffering\"-flaggan" + +#: access/gist/gistbuild.c:254 +#, c-format +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Giltiga värden är \"on\", \"off\" och \"auto\"." + +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 +#, c-format +msgid "could not write block %ld of temporary file: %m" +msgstr "kunde inte skriva block %ld i temporär fil: %m" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr "picksplit-metod för kolumn %d i index \"%s\" misslyckades" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "Indexet är inte optimalt. För att optimera det, kontakta en utvecklare eller försök använda kolumnen som det andra värdet i CREATE INDEX-kommandot." + +#: access/gist/gistutil.c:784 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:744 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "index \"%s\" innehÃ¥ller en oväntad nollställd sida vid block %u" + +#: access/gist/gistutil.c:795 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:755 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "index \"%s\" har en trasig sida vid block %u" + +#: access/gist/gistvalidate.c:196 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "operatorfamiljen \"%s\" för accessmetod %s innehÃ¥ller en ORDER BY som inte stöds för operator %s" + +#: access/gist/gistvalidate.c:207 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "operatorfamiljen \"%s\" för accessmetod %s innehÃ¥ller en inkorrekt ORDER BY \"opfamiily\"-specifikation för operator %s" + +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:992 utils/adt/varchar.c:1052 +#, c-format +msgid "could not determine which collation to use for string hashing" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för sträng-hashning" + +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:678 +#: commands/createas.c:207 commands/createas.c:491 commands/indexcmds.c:1697 +#: commands/tablecmds.c:15099 commands/view.c:105 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1571 utils/adt/formatting.c:1694 +#: utils/adt/formatting.c:1818 utils/adt/like.c:194 +#: utils/adt/like_support.c:965 utils/adt/varchar.c:734 utils/adt/varchar.c:993 +#: utils/adt/varchar.c:1053 utils/adt/varlena.c:1456 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Använd en COLLATE-klausul för att sätta jämförelsen explicit." + +#: access/hash/hashinsert.c:82 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "indexradstorlek %zu överstiger hash-maximum %zu" + +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:752 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Värden större än en buffert-sida kan inte indexeras." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "ogiltigt overflow-blocknummer %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr "slut pÃ¥ överspillsidor i hash-index \"%s\"" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "hash-index stöder inte hela-index-scans" + +#: access/hash/hashutil.c:277 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "index \"%s\" är inte ett hashträd" + +#: access/hash/hashutil.c:283 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "index \"%s\" har fel hash-version" + +#: access/hash/hashvalidate.c:191 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktion för operator %s" + +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar mellan-typ-operator(er)" + +#: access/heap/heapam.c:2077 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "kan inte lägga till tupler i en parellell arbetare" + +#: access/heap/heapam.c:2487 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "kan inte radera tupler under en parallell operation" + +#: access/heap/heapam.c:2533 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "försökte ta bort en osynlig tuple" + +#: access/heap/heapam.c:2954 access/heap/heapam.c:5711 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "kan inte uppdatera tupler under en parallell operation" + +#: access/heap/heapam.c:3087 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "försökte uppdatera en osynlig tuple" + +#: access/heap/heapam.c:4375 access/heap/heapam.c:4413 +#: access/heap/heapam.c:4670 access/heap/heapam_handler.c:454 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "kunde inte lÃ¥sa rad i relationen \"%s\"" + +#: access/heap/heapam_handler.c:405 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "tupel som skall lÃ¥sas har redan flyttats till en annan partition av en samtida uppdatering" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:681 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "raden är för stor: storlek %zu, maximal storlek %zu" + +#: access/heap/rewriteheap.c:941 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "kunde inte skriva till fil \"%s\", skrev %d av %d: %m." + +#: access/heap/rewriteheap.c:1035 access/heap/rewriteheap.c:1154 +#: access/transam/timeline.c:314 access/transam/timeline.c:468 +#: access/transam/xlog.c:3253 access/transam/xlog.c:3425 +#: access/transam/xlog.c:4545 access/transam/xlog.c:10527 +#: access/transam/xlog.c:10565 access/transam/xlog.c:10970 +#: access/transam/xlogfuncs.c:736 postmaster/postmaster.c:4524 +#: replication/logical/origin.c:575 replication/slot.c:1261 +#: storage/file/copydir.c:167 storage/smgr/md.c:204 utils/time/snapmgr.c:1299 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "kan inte skapa fil \"%s\": %m" + +#: access/heap/rewriteheap.c:1164 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u: %m" + +#: access/heap/rewriteheap.c:1172 replication/walsender.c:493 +#: storage/smgr/md.c:1245 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "kunde inte söka (seek) till slutet av filen \"%s\": %m" + +#: access/heap/rewriteheap.c:1189 access/transam/timeline.c:369 +#: access/transam/timeline.c:408 access/transam/timeline.c:485 +#: access/transam/xlog.c:3309 access/transam/xlog.c:3481 +#: access/transam/xlog.c:4557 postmaster/postmaster.c:4534 +#: postmaster/postmaster.c:4544 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1627 replication/slot.c:1295 +#: storage/file/copydir.c:207 utils/init/miscinit.c:1345 +#: utils/init/miscinit.c:1356 utils/init/miscinit.c:1364 utils/misc/guc.c:7801 +#: utils/misc/guc.c:7832 utils/misc/guc.c:9760 utils/misc/guc.c:9774 +#: utils/time/snapmgr.c:1304 utils/time/snapmgr.c:1311 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "kunde inte skriva till fil \"%s\": %m" + +#: access/heap/rewriteheap.c:1279 access/transam/twophase.c:1661 +#: access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:459 +#: postmaster/postmaster.c:1277 postmaster/syslogger.c:1466 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:2814 +#: replication/logical/snapbuild.c:1569 replication/logical/snapbuild.c:2011 +#: replication/slot.c:1381 storage/file/fd.c:704 storage/file/fd.c:3000 +#: storage/file/fd.c:3062 storage/file/reinit.c:255 storage/ipc/dsm.c:307 +#: storage/smgr/md.c:298 storage/smgr/md.c:354 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1644 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "kunde inte ta bort fil \"%s\": %m" + +#: access/heap/vacuumlazy.c:267 +#, c-format +msgid "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +msgstr "hoppar över redundant städning för att förhindra \"wraparound\" av tabell \"%s.%s.%s\"" + +#: access/heap/vacuumlazy.c:405 +#, c-format +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk aggressiv städning för att förhindra \"wraparound\" av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:410 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:412 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\": indexskanningar: %d\n" + +#: access/heap/vacuumlazy.c:419 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "sidor: %u borttagna, %u kvar, %u överhoppade pga pins, %u överhoppade frysta\n" + +#: access/heap/vacuumlazy.c:425 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "tupler: %.0f borttagna, %.0f kvar, %.0f är döda men ännu inte möjliga att ta bort, äldsta xmin: %u\n" + +#: access/heap/vacuumlazy.c:431 +#, c-format +msgid "buffer usage: %d hits, %d misses, %d dirtied\n" +msgstr "bufferanvändning: %d träffar, %d missar, %d nersmutsade\n" + +#: access/heap/vacuumlazy.c:435 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "snitt läshastighet: %.3f MB/s, snitt skrivhastighet: %.3f MB/s\n" + +#: access/heap/vacuumlazy.c:437 +#, c-format +msgid "system usage: %s" +msgstr "systemanvändning: %s" + +#: access/heap/vacuumlazy.c:533 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "aggressiv vaccum av \"%s.%s\"" + +#: access/heap/vacuumlazy.c:538 commands/cluster.c:910 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "kör vaccum pÃ¥ \"%s.%s\"" + +#: access/heap/vacuumlazy.c:1476 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%s\": tog bort %.0f radversioner i %u sidor" + +#: access/heap/vacuumlazy.c:1486 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f döda radversioner kan inte tas bort än, äldsta xmin: %u\n" + +#: access/heap/vacuumlazy.c:1488 +#, c-format +msgid "There were %.0f unused item identifiers.\n" +msgstr "Det fanns %.0f oanvända post-identifierare.\n" + +#: access/heap/vacuumlazy.c:1490 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Hoppade över %u sida pÃ¥ grund av fastnÃ¥lade buffrar, " +msgstr[1] "Hoppade över %u sidor pÃ¥ grund av fastnÃ¥lade buffrar, " + +#: access/heap/vacuumlazy.c:1494 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u frusen sida.\n" +msgstr[1] "%u frusna sidor.\n" + +#: access/heap/vacuumlazy.c:1498 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u sida är helt tom.\n" +msgstr[1] "%u sidor är helt tomma.\n" + +#: access/heap/vacuumlazy.c:1502 commands/indexcmds.c:3291 +#: commands/indexcmds.c:3309 +#, c-format +msgid "%s." +msgstr "%s." + +#: access/heap/vacuumlazy.c:1505 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%s\": hittade %.0f borttagbara, %.0f ej borttagbara radversioner i %u av %u sidor" + +#: access/heap/vacuumlazy.c:1574 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%s\": tog bort %d radversioner i %d sidor" + +#: access/heap/vacuumlazy.c:1765 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "genomsökte index \"%s\" och tog bort %d radversioner" + +#: access/heap/vacuumlazy.c:1818 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "index \"%s\" innehÃ¥ller nu %.0f radversioner i %u sidor" + +#: access/heap/vacuumlazy.c:1822 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f indexradversioner togs bort.\n" +"%u indexsidor har raderats, %u är nu Ã¥teranvändningsbara.\n" +"%s." + +#: access/heap/vacuumlazy.c:1920 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": stoppar trunkering pga konfliktande lÃ¥skrav" + +#: access/heap/vacuumlazy.c:1985 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": trunkerade %u till %u sidor" + +#: access/heap/vacuumlazy.c:2050 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": pausar trunkering pga konfliktande lÃ¥skrav" + +#: access/index/amapi.c:83 commands/amcmds.c:167 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "accessmetod \"%s\" har inte typ %s" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "indexaccessmetod \"%s\" har ingen hanterare" + +#: access/index/indexam.c:136 catalog/objectaddress.c:1259 +#: commands/indexcmds.c:2407 commands/tablecmds.c:248 commands/tablecmds.c:272 +#: commands/tablecmds.c:14806 commands/tablecmds.c:16138 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" är inte ett index" + +#: access/nbtree/nbtinsert.c:565 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "duplicerat nyckelvärde bryter mot unik-villkor \"%s\"" + +#: access/nbtree/nbtinsert.c:567 +#, c-format +msgid "Key %s already exists." +msgstr "Nyckeln %s existerar redan." + +#: access/nbtree/nbtinsert.c:638 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "misslyckades att Ã¥terfinna tuple i index \"%s\"" + +#: access/nbtree/nbtinsert.c:640 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Det kan bero pÃ¥ ett icke-immutable indexuttryck." + +#: access/nbtree/nbtpage.c:171 access/nbtree/nbtpage.c:359 +#: access/nbtree/nbtpage.c:572 parser/parse_utilcmd.c:2117 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "index \"%s\" är inte ett btree" + +#: access/nbtree/nbtpage.c:178 access/nbtree/nbtpage.c:366 +#: access/nbtree/nbtpage.c:579 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "versionsfel i index \"%s\": filversion %d, aktuell version %d, minsta supportade version %d" + +#: access/nbtree/nbtpage.c:1388 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "index \"%s\" innehÃ¥ller en halvdöd intern sida" + +#: access/nbtree/nbtpage.c:1390 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Detta kan ha orsakats av en avbruten VACUUM i version 9.3 eller äldre, innan uppdatering. Vänligen REINDEX:era det." + +#: access/nbtree/nbtutils.c:2563 +#, c-format +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "indexradstorlek %zu överstiger btree version %u maximum %zu för index \"%s\"" + +#: access/nbtree/nbtutils.c:2569 +#, c-format +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "Indexrad refererar tupel (%u,%u) i relation \"%s\"." + +#: access/nbtree/nbtutils.c:2573 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Värden större än 1/3 av en buffer-sida kan inte indexeras.\n" +"Kanske kan du använda ett funktionsindex av ett MD5-hashvärde istället\n" +"eller möjligen full-text-indexering." + +#: access/nbtree/nbtvalidate.c:236 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktioner för typerna %s och %s" + +#: access/spgist/spgutils.c:142 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "komprimeringsmetod mÃ¥ste definieras när lövtypen skiljer sig frÃ¥n indatatypen" + +#: access/spgist/spgutils.c:749 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST inre tuplestorlek %zu överstiger maximala %zu" + +#: access/spgist/spgvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "operatorfamilj \"%s\" för accessmetod %s saknar supportfunktion %d för typ %s" + +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1832 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" är ett index" + +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1839 commands/tablecmds.c:11617 commands/tablecmds.c:14815 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" är en composite-typ" + +#: access/table/tableam.c:236 +#, c-format +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "tid (%u, %u) är inte giltigt för relation \"%s\"" + +#: access/table/tableamapi.c:109 +#, c-format +msgid "%s cannot be empty." +msgstr "%s fÃ¥r inte vara tom." + +#: access/table/tableamapi.c:116 utils/misc/guc.c:11648 +#, c-format +msgid "%s is too long (maximum %d characters)." +msgstr "%s är för lÃ¥ng (maximalt %d tecken)." + +#: access/table/tableamapi.c:138 +#, c-format +msgid "table access method \"%s\" does not exist" +msgstr "tabellaccessmetod \"%s\" existerar inte" + +#: access/table/tableamapi.c:143 +#, c-format +msgid "Table access method \"%s\" does not exist." +msgstr "Tabellaccessmetod \"%s\" existerar inte." + +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "urvalsprocent mÃ¥ste vara mellan 0 och 100" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "kan inte hämta commit-tidsstämpel för transaktion %u" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "kunde inte hämta commit-tidsstämpeldata" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "Se till att konfigurationsparametern \"%s\" är satt pÃ¥ master-servern." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "Se till att konfigurationsparametern \"%s\" är satt." + +#: access/transam/multixact.c:1000 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "databasen tar inte emot kommandon som genererar nya MultiXactId:er för att förhinda dataförlust vid \"wraparound\" i databasen \"%s\"" + +#: access/transam/multixact.c:1002 access/transam/multixact.c:1009 +#: access/transam/multixact.c:1033 access/transam/multixact.c:1042 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Utför en hela databasen-VACUUM i den databasen.\n" +"Du kan ocksÃ¥ behöva commit:a eller rulla tillbaka gamla förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/multixact.c:1007 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "databasen tar inte emot kommandon som genererar nya MultiXactId:er för att förhinda dataförlust vid \"wraparound\" i databasen med OID %u" + +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "databasen \"%s\" mÃ¥ste städas innan ytterligare %u MultiXactId används" +msgstr[1] "databasen \"%s\" mÃ¥ste städas innan ytterligare %u MultiXactId:er används" + +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "databas med OID %u mÃ¥ste städas (vacuum) innan %u till MultiXactId används" +msgstr[1] "databas med OID %u mÃ¥ste städas (vacuum) innan %u till MultiXactId:er används" + +#: access/transam/multixact.c:1098 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "multixact \"members\"-gräns överskriden" + +#: access/transam/multixact.c:1099 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Detta kommando skapar en multixact med %u medlemmar, men Ã¥terstÃ¥ende utrymmer räcker bara till %u medlem." +msgstr[1] "Detta kommando skapar en multixact med %u medlemmar, men Ã¥terstÃ¥ende utrymmer räcker bara till %u medlemmar." + +#: access/transam/multixact.c:1104 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Kör en hela-databas-VACUUM i databas med OID %u med reducerade iställningar vacuum_multixact_freeze_min_age och vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1135 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "databas med OID %u mÃ¥ste städas innan %d mer multixact-medlem används" +msgstr[1] "databas med OID %u mÃ¥ste städas innan %d fler multixact-medlemmar används" + +#: access/transam/multixact.c:1140 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Kör en hela-databas-VACUUM i den databasen med reducerade inställningar för vacuum_multixact_freeze_min_age och vacuum_multixact_freeze_table_age." + +#: access/transam/multixact.c:1277 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u finns inte längre -- troligen en wraparound" + +#: access/transam/multixact.c:1285 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "MultiXactId %u har inte skapats än -- troligen en wraparound" + +#: access/transam/multixact.c:2268 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "MultiXactId wrap-gräns är %u, begränsad av databasen med OID %u" + +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"För att undvika att databasen stängs ner, utför en hela databas-VACCUM i den databasen.\n" +"Du kan ocksÃ¥ behöva commit:a eller rulla tillbaka gamla förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/multixact.c:2602 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "äldsta MultiXactId-medlemmen är vid offset %u" + +#: access/transam/multixact.c:2606 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "MultiXact-medlems wraparound-skydd är avslagen eftersom äldsta checkpoint:ade MultiXact %u inte finns pÃ¥ disk" + +#: access/transam/multixact.c:2628 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "MultiXact-medlems wraparound-skydd är nu pÃ¥slagen" + +#: access/transam/multixact.c:2631 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "MultiXact-medlems stoppgräns är nu %u baserad pÃ¥ MultiXact %u" + +#: access/transam/multixact.c:3011 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "äldsta MultiXact %u hittas inte, tidigast MultiXact %u, skippar trunkering" + +#: access/transam/multixact.c:3029 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "kan inte trunkera upp till %u eftersom den inte finns pÃ¥ disk, skippar trunkering" + +#: access/transam/multixact.c:3343 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "ogiltig MultiXactId: %u" + +#: access/transam/parallel.c:673 access/transam/parallel.c:792 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "parallell arbetare misslyckades med initiering" + +#: access/transam/parallel.c:674 access/transam/parallel.c:793 +#, c-format +msgid "More details may be available in the server log." +msgstr "Fler detaljer kan finnas i serverloggen." + +#: access/transam/parallel.c:854 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "postmaster avslutade under en parallell transaktion" + +#: access/transam/parallel.c:1041 +#, c-format +msgid "lost connection to parallel worker" +msgstr "tappad kopplingen till parallell arbetare" + +#: access/transam/parallel.c:1107 access/transam/parallel.c:1109 +msgid "parallel worker" +msgstr "parallell arbetare" + +#: access/transam/parallel.c:1259 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "kunde inte skapa dynamiskt delat minnessegment: %m" + +#: access/transam/parallel.c:1264 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "ogiltigt magiskt nummer i dynamiskt delat minnessegment" + +#: access/transam/slru.c:674 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "filen \"%s\" existerar inte, läses som nollor" + +#: access/transam/slru.c:912 access/transam/slru.c:918 +#: access/transam/slru.c:925 access/transam/slru.c:932 +#: access/transam/slru.c:939 access/transam/slru.c:946 +#, c-format +msgid "could not access status of transaction %u" +msgstr "kunde inte läsa status pÃ¥ transaktion %u" + +#: access/transam/slru.c:913 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "Kunde inte öppna fil \"%s\": %m." + +#: access/transam/slru.c:919 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "Kunde inte söka i fil \"%s\" till offset %u: %m." + +#: access/transam/slru.c:926 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "Kunde inte läsa frÃ¥n fil \"%s\" pÃ¥ offset %u: %m." + +#: access/transam/slru.c:933 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "Kunde inte skriva till fil \"%s\" pÃ¥ offset %u: %m." + +#: access/transam/slru.c:940 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "Kunde inte fsync:a fil \"%s\": %m." + +#: access/transam/slru.c:947 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "Kunde inte stänga fil \"%s\": %m." + +#: access/transam/slru.c:1204 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "Kunde inte trunkera katalog \"%s\": trolig wraparound" + +#: access/transam/slru.c:1259 access/transam/slru.c:1315 +#, c-format +msgid "removing file \"%s\"" +msgstr "tar bort fil \"%s\"" + +#: access/transam/timeline.c:148 access/transam/timeline.c:153 +#, c-format +msgid "syntax error in history file: %s" +msgstr "syntaxfel i history-fil: %s" + +#: access/transam/timeline.c:149 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Förväntade ett numeriskt tidslinje-ID." + +#: access/transam/timeline.c:154 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Förväntade en write-ahead-logg:s switchpoint-position." + +#: access/transam/timeline.c:158 +#, c-format +msgid "invalid data in history file: %s" +msgstr "felaktig data i history-fil: %s" + +#: access/transam/timeline.c:159 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Tidslinje-ID mÃ¥ste komma i en stigande sekvens." + +#: access/transam/timeline.c:179 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "felaktig data i history-fil \"%s\"" + +#: access/transam/timeline.c:180 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Tidslinje-ID:er mÃ¥ste vara mindre än barnens tidslinje-ID:er." + +#: access/transam/timeline.c:580 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "efterfrÃ¥gad tidslinje %u finns inte i denna servers historik" + +#: access/transam/twophase.c:382 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "transaktionsidentifierare \"%s\" är för lÃ¥ng" + +#: access/transam/twophase.c:389 +#, c-format +msgid "prepared transactions are disabled" +msgstr "förberedda transaktioner är avslagna" + +#: access/transam/twophase.c:390 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "Sätt max_prepared_transactions till ett ickenollvärde." + +#: access/transam/twophase.c:409 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "transaktionsidentifierare \"%s\" används redan" + +#: access/transam/twophase.c:418 access/transam/twophase.c:2420 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "maximalt antal förberedda transaktioner har uppnÃ¥tts" + +#: access/transam/twophase.c:419 access/transam/twophase.c:2421 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "Öka max_prepared_transactions (nu %d)." + +#: access/transam/twophase.c:587 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "förberedd transaktion med identifierare \"%s\" är upptagen" + +#: access/transam/twophase.c:593 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "rättighet saknas för att slutföra förberedd transaktion" + +#: access/transam/twophase.c:594 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "MÃ¥ste vara superanvändare eller den användare som förberedde transaktionen" + +#: access/transam/twophase.c:605 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "förberedda transaktionen tillhör en annan databas" + +#: access/transam/twophase.c:606 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "Anslut till databasen där transaktionen var förberedd för att slutföra den." + +#: access/transam/twophase.c:621 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "förberedd transaktion med identifierare \"%s\" finns inte" + +#: access/transam/twophase.c:1115 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "tvÃ¥fas-statusfilens maximala längd överskriden" + +#: access/transam/twophase.c:1261 access/transam/xlog.c:10512 +#: access/transam/xlog.c:10550 access/transam/xlog.c:10767 +#: access/transam/xlogarchive.c:104 access/transam/xlogarchive.c:264 +#: commands/copy.c:1945 commands/copy.c:3557 commands/extension.c:3330 +#: commands/tablespace.c:787 commands/tablespace.c:878 guc-file.l:1004 +#: replication/basebackup.c:343 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1527 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1703 +#: storage/file/fd.c:2980 storage/file/fd.c:3162 storage/file/fd.c:3247 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:133 utils/adt/genfile.c:386 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" + +#: access/transam/twophase.c:1269 +#, c-format +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "felaktig storlek pÃ¥ fil \"%s\": %zu byte" +msgstr[1] "felaktig storlek pÃ¥ fil \"%s\": %zu byte" + +#: access/transam/twophase.c:1278 +#, c-format +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "inkorrekt justering (alignment) av CRC-offset för fil \"%s\"" + +#: access/transam/twophase.c:1311 +#, c-format +msgid "invalid magic number stored in file \"%s\"" +msgstr "felaktigt magiskt nummer lagrat i fil \"%s\"" + +#: access/transam/twophase.c:1317 +#, c-format +msgid "invalid size stored in file \"%s\"" +msgstr "felaktig storlek lagrad i fil \"%s\"" + +#: access/transam/twophase.c:1329 +#, c-format +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "beräknad CRC-checksumma matchar inte värdet som är lagrat i filen \"%s\"" + +#: access/transam/twophase.c:1395 access/transam/xlog.c:6347 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "Millslyckades vid allokering av en WAL-läs-processor." + +#: access/transam/twophase.c:1401 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "kunde inte läsa tvÃ¥fas-status frÃ¥n WAL vid %X/%X" + +#: access/transam/twophase.c:1409 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "förväntad tvÃ¥fas-statusdata finns inte i WAL vid %X/%X" + +#: access/transam/twophase.c:1689 +#, c-format +msgid "could not recreate file \"%s\": %m" +msgstr "kan inte Ã¥terskapa fil \"%s\": %m" + +#: access/transam/twophase.c:1816 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "%u tvÃ¥fas-statusfil skrevs för lÃ¥ngkörande förberedd transkation" +msgstr[1] "%u tvÃ¥fas-statusfiler skrevs för lÃ¥ngkörande förberedda transaktioner" + +#: access/transam/twophase.c:2050 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "Ã¥terskapar förberedd transaktion %u frÃ¥n delat minne" + +#: access/transam/twophase.c:2141 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "tar bort död tvÃ¥fas-statusfil för transaktioon %u" + +#: access/transam/twophase.c:2148 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "tar bort död tvÃ¥fas-statusfil frÃ¥n minne för transaktion %u" + +#: access/transam/twophase.c:2161 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "tar bort framtida tvÃ¥fas-statusfil för transaktion %u" + +#: access/transam/twophase.c:2168 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "tar bort framtida tvÃ¥fas-statusfil frÃ¥n minne för transaktion %u" + +#: access/transam/twophase.c:2193 +#, c-format +msgid "corrupted two-phase state file for transaction %u" +msgstr "korrupt tvÃ¥fas-statusfil för transaktion %u" + +#: access/transam/twophase.c:2198 +#, c-format +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "korrupt tvÃ¥fas-status i minnet för transaktion %u" + +#: access/transam/varsup.c:127 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "databasen tar inte emot kommandon för att förhinda dataförlust vid \"wraparound\" i databasen \"%s\"" + +#: access/transam/varsup.c:129 access/transam/varsup.c:136 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Stoppa postmaster och städa (vacuum) den databasen i enanvändarläge.\n" +"Du kan ocksÃ¥ behöva commit:a eller rulla tillbaka förberedda transaktioner eller slänga gamla replikeringsslottar." + +#: access/transam/varsup.c:134 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "databasen tar inte emot kommandon för att förhinda dataförlust vid wraparound i databas med OID %u" + +#: access/transam/varsup.c:146 access/transam/varsup.c:444 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "databas \"%s\" mÃ¥ste städas (vacuum) inom %u transaktioner" + +#: access/transam/varsup.c:153 access/transam/varsup.c:451 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "databas med OID %u mÃ¥ste städas (vacuum) inom %u transaktioner" + +#: access/transam/varsup.c:409 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "transaktions-ID wrap-gräns är %u, begränsad av databas med OID %u" + +#: access/transam/xact.c:1027 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "kan inte ha mer än 2^32-2 kommandon i en transaktion" + +#: access/transam/xact.c:1552 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "maximalt antal commit:ade undertransaktioner (%d) överskridet" + +#: access/transam/xact.c:2377 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "kan inte göra PREPARE pÃ¥ en transaktion som har arbetat med temporära objekt" + +#: access/transam/xact.c:2387 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "kan inte göra PREPARE pÃ¥ en transaktion som har exporterade snapshots" + +#: access/transam/xact.c:2396 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "kan inte göra PREPARE pÃ¥ en transaktion som har förändrat logiska replikeringsarbetare" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3337 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s kan inte köras i ett transaktionsblock" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3347 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s kan inte köras i ett undertransaktionsblock" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3357 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s kan inte köras frÃ¥n en funktion" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3426 access/transam/xact.c:4062 +#: access/transam/xact.c:4131 access/transam/xact.c:4242 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s kan bara användas i transaktionsblock" + +#: access/transam/xact.c:3619 +#, c-format +msgid "there is already a transaction in progress" +msgstr "det är redan en transaktion igÃ¥ng" + +#: access/transam/xact.c:3730 access/transam/xact.c:3800 +#: access/transam/xact.c:3916 +#, c-format +msgid "there is no transaction in progress" +msgstr "ingen transaktion pÃ¥gÃ¥r" + +#: access/transam/xact.c:3811 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "kan inte commit:a under en parallell operation" + +#: access/transam/xact.c:3927 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "can inte avbryta under en parallell operation" + +#: access/transam/xact.c:4026 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "kan inte definiera sparpunkter under en parallell operation" + +#: access/transam/xact.c:4113 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "kan inte frigöra en sparpunkt under en parallell operation" + +#: access/transam/xact.c:4123 access/transam/xact.c:4174 +#: access/transam/xact.c:4234 access/transam/xact.c:4283 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr "sparpunkt \"%s\" existerar inte" + +#: access/transam/xact.c:4180 access/transam/xact.c:4289 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "sparpunkt \"%s\" finns inte inom aktuell sparpunktsnivÃ¥" + +#: access/transam/xact.c:4222 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "kan inte rulla tillbaka till sparpunkt under en parallell operation" + +#: access/transam/xact.c:4350 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "kan inte starta subtransaktioner under en parallell operation" + +#: access/transam/xact.c:4418 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "kan inte commit:a subtransaktioner undert en parallell operation" + +#: access/transam/xact.c:5056 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "kan inte ha mer än 2^32-1 subtransaktioner i en transaktion" + +#: access/transam/xlog.c:2507 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "kunde inte skriva till loggfil %s vid offset %u, längd %zu: %m" + +#: access/transam/xlog.c:2783 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "updaterade minsta Ã¥terställningspunkt till %X/%X pÃ¥ tidslinje %u" + +#: access/transam/xlog.c:3864 access/transam/xlogutils.c:703 +#: replication/walsender.c:2445 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "efterfrÃ¥gat WAL-segment %s har redan tagits bort" + +#: access/transam/xlog.c:4106 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "Ã¥teranvände write-ahead-loggfil \"%s\"" + +#: access/transam/xlog.c:4118 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "tar bort write-ahead-loggfil \"%s\"" + +#: access/transam/xlog.c:4138 +#, c-format +msgid "could not rename file \"%s\": %m" +msgstr "kunde inte byta namn pÃ¥ fil \"%s\": %m" + +#: access/transam/xlog.c:4180 access/transam/xlog.c:4190 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "krävd WAL-katalog \"%s\" finns inte" + +#: access/transam/xlog.c:4196 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "skapar saknad WAL-katalog \"%s\"" + +#: access/transam/xlog.c:4199 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "kunde inte skapa saknad katalog \"%s\": %m" + +#: access/transam/xlog.c:4304 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "oväntad tidslinje-ID %u i loggsegment %s, offset %u" + +#: access/transam/xlog.c:4432 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "ny tidslinje %u är inte ett barn till databasens systemtidslinje %u" + +#: access/transam/xlog.c:4446 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "ny tidslinje %u skapad frÃ¥n aktuella databasens systemtidslinje %u innan nuvarande Ã¥terställningspunkt %X/%X" + +#: access/transam/xlog.c:4465 +#, c-format +msgid "new target timeline is %u" +msgstr "ny mÃ¥ltidslinje är %u" + +#: access/transam/xlog.c:4624 access/transam/xlog.c:4633 +#: access/transam/xlog.c:4657 access/transam/xlog.c:4664 +#: access/transam/xlog.c:4671 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4683 access/transam/xlog.c:4690 +#: access/transam/xlog.c:4697 access/transam/xlog.c:4704 +#: access/transam/xlog.c:4711 access/transam/xlog.c:4718 +#: access/transam/xlog.c:4727 access/transam/xlog.c:4734 +#: access/transam/xlog.c:4743 access/transam/xlog.c:4750 +#: utils/init/miscinit.c:1502 +#, c-format +msgid "database files are incompatible with server" +msgstr "databasfilerna är inkompatibla med servern" + +#: access/transam/xlog.c:4625 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Databasklustret initierades med PG_CONTROL_VERSION %d (0x%08x), men servern kompilerades med PG_CONTROL_VERSION %d (0x%08x)." + +#: access/transam/xlog.c:4629 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Detta kan orsakas av en felaktig byte-ordning. Du behöver troligen köra initdb." + +#: access/transam/xlog.c:4634 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Databasklustret initierades med PG_CONTROL_VERSION %d, men servern kompilerades med PG_CONTROL_VERSION %d." + +#: access/transam/xlog.c:4637 access/transam/xlog.c:4661 +#: access/transam/xlog.c:4668 access/transam/xlog.c:4673 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Du behöver troligen köra initdb." + +#: access/transam/xlog.c:4648 +#, c-format +msgid "incorrect checksum in control file" +msgstr "ogiltig kontrollsumma kontrollfil" + +#: access/transam/xlog.c:4658 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Databasklustret initierades med CATALOG_VERSION_NO %d, men servern kompilerades med CATALOG_VERSION_NO %d." + +#: access/transam/xlog.c:4665 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Databasklustret initierades med MAXALIGN %d, men servern kompilerades med MAXALIGN %d." + +#: access/transam/xlog.c:4672 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Databasklustret verkar använda en annan flyttalsrepresentation än vad serverprogrammet gör." + +#: access/transam/xlog.c:4677 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Databasklustret initierades med BLCKSZ %d, men servern kompilerades med BLCKSZ %d." + +#: access/transam/xlog.c:4680 access/transam/xlog.c:4687 +#: access/transam/xlog.c:4694 access/transam/xlog.c:4701 +#: access/transam/xlog.c:4708 access/transam/xlog.c:4715 +#: access/transam/xlog.c:4722 access/transam/xlog.c:4730 +#: access/transam/xlog.c:4737 access/transam/xlog.c:4746 +#: access/transam/xlog.c:4753 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Det verkar som om du mÃ¥ste kompilera om eller köra initdb." + +#: access/transam/xlog.c:4684 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Databasklustret initierades med RELSEG_SIZE %d, men servern kompilerades med RELSEG_SIZE %d." + +#: access/transam/xlog.c:4691 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Databasklustret initierades med XLOG_BLCKSZ %d, men servern kompilerades med XLOG_BLCKSZ %d." + +#: access/transam/xlog.c:4698 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Databasklustret initierades med NAMEDATALEN %d, men servern kompilerades med NAMEDATALEN %d." + +#: access/transam/xlog.c:4705 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Databasklustret initierades med INDEX_MAX_KEYS %d, men servern kompilerades med INDEX_MAX_KEYS %d." + +#: access/transam/xlog.c:4712 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Databasklustret initierades med TOAST_MAX_CHUNK_SIZE %d, men servern kompilerades med TOAST_MAX_CHUNK_SIZE %d." + +#: access/transam/xlog.c:4719 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Databasklustret initierades med LOBLKSIZE %d, men servern kompilerades med LOBLKSIZE %d." + +#: access/transam/xlog.c:4728 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +msgstr "Databasklustret initierades utan USE_FLOAT4_BYVAL, men servern kompilerades med USE_FLOAT4_BYVAL." + +#: access/transam/xlog.c:4735 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +msgstr "Databasklustret initierades med USE_FLOAT4_BYVAL, men servern kompilerades utan USE_FLOAT4_BYVAL." + +#: access/transam/xlog.c:4744 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Databasklustret initierades utan USE_FLOAT8_BYVAL, men servern kompilerades med USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4751 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Databasklustret initierades med USE_FLOAT8_BYVAL, men servern kompilerades utan USE_FLOAT8_BYVAL." + +#: access/transam/xlog.c:4760 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte" +msgstr[1] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte" + +#: access/transam/xlog.c:4772 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" mÃ¥ste vara minst dubbla \"wal_segment_size\"" + +#: access/transam/xlog.c:4776 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" mÃ¥ste vara minst dubbla \"wal_segment_size\"" + +#: access/transam/xlog.c:5128 +#, c-format +msgid "could not generate secret authorization token" +msgstr "kunde inte generera hemligt auktorisationstoken" + +#: access/transam/xlog.c:5218 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "kunde inte skriva bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5226 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "kunde inte fsync:a bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5232 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "kunde inte stänga bootstrap-write-ahead-loggfil: %m" + +#: access/transam/xlog.c:5311 +#, c-format +msgid "using recovery command file \"%s\" is not supported" +msgstr "använda Ã¥terställningskommandofil \"%s\" stöds inte" + +#: access/transam/xlog.c:5376 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "standby-läge stöd inte av enanvändarservrar" + +#: access/transam/xlog.c:5393 +#, c-format +msgid "specified neither primary_conninfo nor restore_command" +msgstr "angav varken primary_conninfo eller restore_command" + +#: access/transam/xlog.c:5394 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "Databasservern kommer med jämna mellanrum att poll:a pg_wal-underkatalogen för att se om filer placerats där." + +#: access/transam/xlog.c:5402 +#, c-format +msgid "must specify restore_command when standby mode is not enabled" +msgstr "mÃ¥ste ange restore_command när standby-läge inte är pÃ¥slaget" + +#: access/transam/xlog.c:5428 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "Ã¥terställningsmÃ¥ltidslinje %u finns inte" + +#: access/transam/xlog.c:5555 +#, c-format +msgid "archive recovery complete" +msgstr "arkivÃ¥terställning klar" + +#: access/transam/xlog.c:5614 access/transam/xlog.c:5880 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "Ã¥terställning stoppad efter att ha uppnÃ¥tt konsistens" + +#: access/transam/xlog.c:5635 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "Ã¥terställning stoppad före WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5721 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "Ã¥terställning stoppad före commit av transaktion %u, tid %s" + +#: access/transam/xlog.c:5728 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "Ã¥terställning stoppad före abort av transaktion %u, tid %s" + +#: access/transam/xlog.c:5774 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "Ã¥terställning stoppad vid Ã¥terställningspunkt \"%s\", tid %s" + +#: access/transam/xlog.c:5792 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "Ã¥terställning stoppad efter WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:5860 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "Ã¥terställning stoppad efter commit av transaktion %u, tid %s" + +#: access/transam/xlog.c:5868 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "Ã¥terställning stoppad efter abort av transaktion %u, tid %s" + +#: access/transam/xlog.c:5908 +#, c-format +msgid "recovery has paused" +msgstr "Ã¥terställning har pausats" + +#: access/transam/xlog.c:5909 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Kör pg_wal_replay_resume() för att fortsätta." + +#: access/transam/xlog.c:6117 +#, c-format +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "hot standby är inte möjligt dÃ¥ %s = %d har ett lägre värde än pÃ¥ masterservern (dess värde var %d)" + +#: access/transam/xlog.c:6143 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "WAL genererades med wal_level=minimal, data kan saknas" + +#: access/transam/xlog.c:6144 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "Detta händer om du temporärt sätter wal_level=minimal utan att ta en ny basbackup." + +#: access/transam/xlog.c:6155 +#, c-format +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "hot standby är inte möjligt dÃ¥ wal_level inte satts till \"replica\" eller högre pÃ¥ masterservern" + +#: access/transam/xlog.c:6156 +#, c-format +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "Antingen sätt wal_level till \"replica\" pÃ¥ mastern eller stäng av hot_standby här." + +#: access/transam/xlog.c:6220 +#, c-format +msgid "control file contains invalid data" +msgstr "kontrollfil innehÃ¥ller ogiltig data" + +#: access/transam/xlog.c:6226 +#, c-format +msgid "database system was shut down at %s" +msgstr "databassystemet stängdes ner vid %s" + +#: access/transam/xlog.c:6231 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "databassystemet stängdes ner under Ã¥terställning vid %s" + +#: access/transam/xlog.c:6235 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "nedstängning av databasen avbröts; senast kända upptidpunkt vid %s" + +#: access/transam/xlog.c:6239 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "databassystemet avbröts under Ã¥terställning vid %s" + +#: access/transam/xlog.c:6241 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Det betyder troligen att en del data är förstörd och du behöver Ã¥terställa databasen frÃ¥n den senaste backup:en." + +#: access/transam/xlog.c:6245 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "databassystemet avbröts under Ã¥terställning vid loggtid %s" + +#: access/transam/xlog.c:6247 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Om detta har hänt mer än en gÃ¥ng sÃ¥ kan data vara korrupt och du kanske mÃ¥ste Ã¥terställa till ett tidigare Ã¥terställningsmÃ¥l." + +#: access/transam/xlog.c:6251 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "databassystemet avbröts; senast kända upptidpunkt vid %s" + +#: access/transam/xlog.c:6307 +#, c-format +msgid "entering standby mode" +msgstr "gÃ¥r in i standby-läge" + +#: access/transam/xlog.c:6310 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "startar point-in-time-Ã¥terställning till XID %u" + +#: access/transam/xlog.c:6314 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "startar point-in-time-Ã¥terställning till %s" + +#: access/transam/xlog.c:6318 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "startar point-in-time-Ã¥terställning till \"%s\"" + +#: access/transam/xlog.c:6322 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "startar point-in-time-Ã¥terställning till WAL-position (LSN) \"%X/%X\"" + +#: access/transam/xlog.c:6327 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "startar point-in-time-Ã¥terställning till tidigast konsistenta punkt" + +#: access/transam/xlog.c:6330 +#, c-format +msgid "starting archive recovery" +msgstr "Startar arkivÃ¥terställning" + +#: access/transam/xlog.c:6384 access/transam/xlog.c:6516 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "checkpoint-posten är vid %X/%X" + +#: access/transam/xlog.c:6398 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "kunde inte hitta redo-position refererad av checkpoint-post" + +#: access/transam/xlog.c:6399 access/transam/xlog.c:6409 +#, c-format +msgid "" +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" +"Om du Ã¥terställer frÃ¥n en backup, gör touch pÃ¥ \"%s/recovery.signal\" och lägg till\n" +"önskade Ã¥terställningsalternativ. Om du inte Ã¥terställer frÃ¥n en backup, försök ta\n" +"bort filen \"%s/backup_label\". Var försiktig: borttagning av \"%s/backup_label\"\n" +"kommer resultera i ett trasigt kluster om du Ã¥terställer frÃ¥n en backup." + +#: access/transam/xlog.c:6408 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "kunde inte hitta den checkpoint-post som krävs" + +#: access/transam/xlog.c:6437 commands/tablespace.c:646 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "kan inte skapa symbolisk länk \"%s\": %m" + +#: access/transam/xlog.c:6469 access/transam/xlog.c:6475 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "hoppar över fil \"%s\" dÃ¥ ingen fil \"%s\" finns" + +#: access/transam/xlog.c:6471 access/transam/xlog.c:11458 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "Filen \"%s\" döptes om till \"%s\"." + +#: access/transam/xlog.c:6477 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "Kunde inte döpa om fil \"%s\" till \"%s\": %m" + +#: access/transam/xlog.c:6528 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "kunde inte hitta en giltig checkpoint-post" + +#: access/transam/xlog.c:6566 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "efterfrÃ¥gad tidslinje %u är inte ett barn till denna servers historik" + +#: access/transam/xlog.c:6568 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "Senaste checkpoint är vid %X/%X pÃ¥ tidslinje %u, men i historiken för efterfrÃ¥gad tidslinje sÃ¥ avvek servern frÃ¥n den tidslinjen vid %X/%X." + +#: access/transam/xlog.c:6584 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "efterfÃ¥gan tidslinje %u innehÃ¥ller inte minimal Ã¥terställningspunkt %X/%X pÃ¥ tidslinje %u" + +#: access/transam/xlog.c:6615 +#, c-format +msgid "invalid next transaction ID" +msgstr "nästa transaktions-ID ogiltig" + +#: access/transam/xlog.c:6709 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "ogiltig redo i checkpoint-post" + +#: access/transam/xlog.c:6720 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "ogiltig redo-post i nedstängnings-checkpoint" + +#: access/transam/xlog.c:6748 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "databassystemet stängdes inte ned korrekt; automatisk Ã¥terställning pÃ¥gÃ¥r" + +#: access/transam/xlog.c:6752 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "krashÃ¥terställning startar i tidslinje %u och har mÃ¥ltidslinje %u" + +#: access/transam/xlog.c:6795 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label innehÃ¥ller data som inte stämmer med kontrollfil" + +#: access/transam/xlog.c:6796 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Det betyder att backup:en är trasig och du behöver använda en annan backup för att Ã¥terställa." + +#: access/transam/xlog.c:6887 +#, c-format +msgid "initializing for hot standby" +msgstr "initierar för hot standby" + +#: access/transam/xlog.c:7019 +#, c-format +msgid "redo starts at %X/%X" +msgstr "redo startar vid %X/%X" + +#: access/transam/xlog.c:7243 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "efterfrÃ¥gad Ã¥terställningsstoppunkt är före en konsistent Ã¥terställningspunkt" + +#: access/transam/xlog.c:7281 +#, c-format +msgid "redo done at %X/%X" +msgstr "redo gjord vid %X/%X" + +#: access/transam/xlog.c:7286 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "senaste kompletta transaktionen var vid loggtid %s" + +#: access/transam/xlog.c:7295 +#, c-format +msgid "redo is not required" +msgstr "redo behövs inte" + +#: access/transam/xlog.c:7370 access/transam/xlog.c:7374 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL slutar före sluttiden av online-backup:en" + +#: access/transam/xlog.c:7371 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Alla genererade WAL under tiden online-backup:en togs mÃ¥ste vara tillgängliga vid Ã¥terställning." + +#: access/transam/xlog.c:7375 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "Online-backup startad med pg_start_backup() mÃ¥ste avslutas med pg_stop_backup() och alla WAL fram till den punkten mÃ¥ste vara tillgängliga vid Ã¥terställning." + +#: access/transam/xlog.c:7378 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL avslutas innan konstistent Ã¥terställningspunkt" + +#: access/transam/xlog.c:7412 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "valt nytt tidslinje-ID: %u" + +#: access/transam/xlog.c:7849 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "konsistent Ã¥terställningstillstÃ¥nd uppnÃ¥tt vid %X/%X" + +#: access/transam/xlog.c:8041 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "ogiltig primär checkpoint-länk i kontrollfil" + +#: access/transam/xlog.c:8045 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "ogiltig checkpoint-länk i \"backup_label\"-fil" + +#: access/transam/xlog.c:8062 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "ogiltig primär checkpoint-post" + +#: access/transam/xlog.c:8066 +#, c-format +msgid "invalid checkpoint record" +msgstr "ogiltig checkpoint-post" + +#: access/transam/xlog.c:8077 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "ogiltig resurshanterar-ID i primär checkpoint-post" + +#: access/transam/xlog.c:8081 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "ogiltig resurshanterar-ID i checkpoint-post" + +#: access/transam/xlog.c:8094 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "ogiltig xl_info i primär checkpoint-post" + +#: access/transam/xlog.c:8098 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "ogiltig xl_info i checkpoint-post" + +#: access/transam/xlog.c:8109 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "ogiltig längd i primär checkpoint-post" + +#: access/transam/xlog.c:8113 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "ogiltig längd pÃ¥ checkpoint-post" + +#: access/transam/xlog.c:8293 +#, c-format +msgid "shutting down" +msgstr "stänger ner" + +#: access/transam/xlog.c:8613 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "checkpoint överhoppad pÃ¥ grund av att systemet är olastat" + +#: access/transam/xlog.c:8813 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "samtidig write-ahead-logg-aktivitet när databassystemet stängs ner" + +#: access/transam/xlog.c:9069 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "hoppar över omstartpunkt, Ã¥terställning har redan avslutats" + +#: access/transam/xlog.c:9092 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "hoppar över omstartpunkt, redan gjorde vid %X/%X" + +#: access/transam/xlog.c:9259 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "Ã¥terställningens omstartspunkt vid %X/%X" + +#: access/transam/xlog.c:9261 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Senaste kompletta transaktionen var vid loggtid %s" + +#: access/transam/xlog.c:9395 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "Ã¥terställningspunkt \"%s\" skapad vid %X/%X" + +#: access/transam/xlog.c:9536 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "oväntad föregÃ¥ende tidslinje-ID %u (nuvarande tidslinje-ID %u) i checkpoint-post" + +#: access/transam/xlog.c:9545 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "oväntad tidslinje-ID %u (efter %u) i checkpoint-post" + +#: access/transam/xlog.c:9561 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "oväntad tidslinje-ID %u i checkpoint-post, innan vi nÃ¥tt minimal Ã¥terställningspunkt %X/%X pÃ¥ tidslinje %u" + +#: access/transam/xlog.c:9637 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "online-backup avbröts, Ã¥terställning kan inte fortsätta" + +#: access/transam/xlog.c:9691 access/transam/xlog.c:9745 +#: access/transam/xlog.c:9768 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "oväntad tidslinje-ID %u (skall vara %u) i checkpoint-post" + +#: access/transam/xlog.c:10088 +#, c-format +msgid "could not fsync write-through file \"%s\": %m" +msgstr "kunde inte fsync:a skriv-igenom-loggfil \"%s\": %m" + +#: access/transam/xlog.c:10097 +#, c-format +msgid "could not fdatasync file \"%s\": %m" +msgstr "kunde inte fdatasync:a fil \"%s\": %m" + +#: access/transam/xlog.c:10190 access/transam/xlog.c:10719 +#: access/transam/xlogfuncs.c:290 access/transam/xlogfuncs.c:317 +#: access/transam/xlogfuncs.c:356 access/transam/xlogfuncs.c:377 +#: access/transam/xlogfuncs.c:398 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "WAL-kontrollfunktioner kan inte köras under Ã¥terställning." + +#: access/transam/xlog.c:10199 access/transam/xlog.c:10728 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "WAL-nivÃ¥ inte tillräcklig för att kunna skapa en online-backup" + +#: access/transam/xlog.c:10200 access/transam/xlog.c:10729 +#: access/transam/xlogfuncs.c:323 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "wal_level mÃ¥ste vara satt till \"replica\" eller \"logical\" vid serverstart." + +#: access/transam/xlog.c:10205 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "backup-etikett för lÃ¥ng (max %d byte)" + +#: access/transam/xlog.c:10242 access/transam/xlog.c:10518 +#: access/transam/xlog.c:10556 +#, c-format +msgid "a backup is already in progress" +msgstr "en backup är redan pÃ¥ gÃ¥ng" + +#: access/transam/xlog.c:10243 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "Kör pg_stop_backup() och försök igen." + +#: access/transam/xlog.c:10339 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "WAL skapad med full_page_writes=off har Ã¥terspelats sedab senaste omstartpunkten" + +#: access/transam/xlog.c:10341 access/transam/xlog.c:10924 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "Det betyder att backup:en som tas pÃ¥ standby:en är trasig och inte skall användas. SlÃ¥ pÃ¥ full_page_writes och kör CHECKPOINT pÃ¥ master och försök sedan ta en ny online-backup igen." + +#: access/transam/xlog.c:10416 replication/basebackup.c:1237 +#: utils/adt/misc.c:329 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "mÃ¥l för symbolisk länk \"%s\" är för lÃ¥ng" + +#: access/transam/xlog.c:10468 commands/tablespace.c:394 +#: commands/tablespace.c:558 replication/basebackup.c:1252 utils/adt/misc.c:337 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "tabellutrymmen stöds inte pÃ¥ denna plattform" + +#: access/transam/xlog.c:10519 access/transam/xlog.c:10557 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Om du är säker pÃ¥ att det inte pÃ¥gÃ¥r nÃ¥gon backup sÃ¥ ta bort filen \"%s\" och försök igen." + +#: access/transam/xlog.c:10744 +#, c-format +msgid "exclusive backup not in progress" +msgstr "exklusiv backup är inte pÃ¥ gÃ¥ng" + +#: access/transam/xlog.c:10771 +#, c-format +msgid "a backup is not in progress" +msgstr "ingen backup är pÃ¥ gÃ¥ng" + +#: access/transam/xlog.c:10857 access/transam/xlog.c:10870 +#: access/transam/xlog.c:11231 access/transam/xlog.c:11237 +#: access/transam/xlog.c:11285 access/transam/xlog.c:11358 +#: access/transam/xlogfuncs.c:693 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "felaktig data i fil \"%s\"" + +#: access/transam/xlog.c:10874 replication/basebackup.c:1089 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "standby:en befordrades under online-backup" + +#: access/transam/xlog.c:10875 replication/basebackup.c:1090 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Det betyder att backupen som tas är trasig och inte skall användas. Försök ta en ny online-backup." + +#: access/transam/xlog.c:10922 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "WAL skapad med full_page_writes=off Ã¥terspelades under online-backup" + +#: access/transam/xlog.c:11042 +#, c-format +msgid "base backup done, waiting for required WAL segments to be archived" +msgstr "base_backup klar, väntar pÃ¥ att de WAL-segment som krävs blir arkiverade" + +#: access/transam/xlog.c:11052 +#, c-format +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "väntar fortfarande pÃ¥ att alla krävda WAL-segments skall bli arkiverade (%d sekunder har gÃ¥tt)" + +#: access/transam/xlog.c:11054 +#, c-format +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "Kontrollera att ditt archive_command kör som det skall. Du kan avbryta denna backup pÃ¥ ett säkert sätt men databasbackup:en kommer inte vara användbart utan att alla WAL-segment finns." + +#: access/transam/xlog.c:11061 +#, c-format +msgid "all required WAL segments have been archived" +msgstr "alla krävda WAL-segments har arkiverats" + +#: access/transam/xlog.c:11065 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL-arkivering är inte pÃ¥slagen; du mÃ¥ste se till att alla krävda WAL-segment har kopierats pÃ¥ annat sätt för att backup:en skall vara komplett" + +#: access/transam/xlog.c:11268 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "backuptid %s i fil \"%s\"" + +#: access/transam/xlog.c:11273 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "backup-etikett %s i fil \"%s\"" + +#: access/transam/xlog.c:11286 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "Parsad tidslinje-ID är %u men förväntade sig %u" + +#: access/transam/xlog.c:11290 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "backuptidslinje %u i fil \"%s\"" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11398 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "WAL-redo vid %X/%X för %s" + +#: access/transam/xlog.c:11447 +#, c-format +msgid "online backup mode was not canceled" +msgstr "online backupläge har ej avbrutits" + +#: access/transam/xlog.c:11448 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "Filen \"%s\" kunde inte döpas om till \"%s\": %m." + +#: access/transam/xlog.c:11457 access/transam/xlog.c:11469 +#: access/transam/xlog.c:11479 +#, c-format +msgid "online backup mode canceled" +msgstr "online backupläge avbrutet" + +#: access/transam/xlog.c:11470 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "Filer \"%s\" och \"%s\" döptes om till \"%s\" och \"%s\", var för sig." + +#: access/transam/xlog.c:11480 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "Filen \"%s\" dötes om till \"%s\", men filen \"%s\" kunde inte döpas om till \"%s\": %m." + +#: access/transam/xlog.c:11613 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "kunde inte läsa frÃ¥n loggsegment %s, offset %u: %m" + +#: access/transam/xlog.c:11619 replication/walsender.c:2489 +#, c-format +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "kunde inte läsa frÃ¥n loggsegment %s, offset %u, läste %d av %zu" + +#: access/transam/xlog.c:12152 +#, c-format +msgid "received promote request" +msgstr "tog emot förfrÃ¥gan om befordring" + +#: access/transam/xlog.c:12165 +#, c-format +msgid "promote trigger file found: %s" +msgstr "utlösarfil för befordring hittad: %s" + +#: access/transam/xlog.c:12174 +#, c-format +msgid "could not stat promote trigger file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ utlösarfil för befordring \"%s\": %m" + +#: access/transam/xlogarchive.c:243 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "arkivfil \"%s\" har fel storlek: %lu istället för %lu" + +#: access/transam/xlogarchive.c:252 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "Ã¥terställd logfil \"%s\" frÃ¥n arkiv" + +#: access/transam/xlogarchive.c:297 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "kunde inte Ã¥terställa fil \"%s\" frÃ¥n arkiv: %s" + +#. translator: First %s represents a postgresql.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:406 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1524 +#: replication/logical/snapbuild.c:1670 replication/slot.c:598 +#: replication/slot.c:1210 replication/slot.c:1332 storage/file/fd.c:664 +#: storage/file/fd.c:759 utils/time/snapmgr.c:1320 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" + +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "kunde inte skapa arkiveringsstatusfil \"%s\": %m" + +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "kunde inte skriva arkiveringsstatusfil \"%s\": %m" + +#: access/transam/xlogfuncs.c:57 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "avbryter backup pÃ¥ grund av att backend:en stoppades innan pg_stop_backup anropades" + +#: access/transam/xlogfuncs.c:87 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "en backup är redan pÃ¥ gÃ¥ng i denna session" + +#: access/transam/xlogfuncs.c:145 access/transam/xlogfuncs.c:227 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "icke-exklusiv backup är pÃ¥ gÃ¥ng" + +#: access/transam/xlogfuncs.c:146 access/transam/xlogfuncs.c:228 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Menade du att använda pg_stop_backup('f')?" + +#: access/transam/xlogfuncs.c:198 commands/event_trigger.c:1473 +#: commands/event_trigger.c:2025 commands/extension.c:1908 +#: commands/extension.c:2017 commands/extension.c:2241 commands/prepare.c:712 +#: executor/execExpr.c:2201 executor/execSRF.c:720 executor/functions.c:1023 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1112 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1468 +#: replication/slotfuncs.c:236 replication/walsender.c:3245 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:458 +#: utils/adt/pgstatfuncs.c:563 utils/fmgr/funcapi.c:63 utils/misc/guc.c:9460 +#: utils/mmgr/portalmem.c:1134 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "en funktion som returnerar en mängd anropades i kontext som inte godtar en mängd" + +#: access/transam/xlogfuncs.c:202 commands/event_trigger.c:1477 +#: commands/event_trigger.c:2029 commands/extension.c:1912 +#: commands/extension.c:2021 commands/extension.c:2245 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1116 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1472 +#: replication/slotfuncs.c:240 replication/walsender.c:3249 +#: utils/adt/pgstatfuncs.c:462 utils/adt/pgstatfuncs.c:567 +#: utils/misc/guc.c:9464 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "materialiserat läge krävs, men stöds inte i detta kontext" + +#: access/transam/xlogfuncs.c:244 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "icke-exklusiv backup är inte pÃ¥ gÃ¥ng" + +#: access/transam/xlogfuncs.c:245 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Menade du att använda pg_stop_backup('t')?" + +#: access/transam/xlogfuncs.c:322 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "WAL-nivÃ¥n är inte tillräcklig för att skapa en Ã¥terställningspunkt" + +#: access/transam/xlogfuncs.c:330 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "värdet för lÃ¥ngt för en Ã¥terställningspunkt (maximalt %d tecken)" + +#: access/transam/xlogfuncs.c:468 access/transam/xlogfuncs.c:525 +#, c-format +msgid "%s cannot be executed during recovery." +msgstr "%s kan inte köras under Ã¥terställning" + +#: access/transam/xlogfuncs.c:546 access/transam/xlogfuncs.c:566 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 +#, c-format +msgid "recovery is not in progress" +msgstr "Ã¥terställning är inte i gÃ¥ng" + +#: access/transam/xlogfuncs.c:547 access/transam/xlogfuncs.c:567 +#: access/transam/xlogfuncs.c:584 access/transam/xlogfuncs.c:724 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Ã…terställningskontrollfunktioner kan bara köras under Ã¥terställning." + +#: access/transam/xlogfuncs.c:729 +#, c-format +msgid "\"wait_seconds\" cannot be negative or equal zero" +msgstr "\"wait_seconds\" kan inte vara negativ eller lika med noll" + +#: access/transam/xlogfuncs.c:749 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "misslyckades med att sända en signal till postmaster: %m" + +#: access/transam/xlogfuncs.c:776 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "servern befordrades inte inom %d sekunder" + +#: access/transam/xlogreader.c:299 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "ogiltig postoffset vid %X/%X" + +#: access/transam/xlogreader.c:307 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord är begärd vid %X/%X" + +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:645 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "ogiltig postlängd vid %X/%X: förväntade %u, fick %u" + +#: access/transam/xlogreader.c:372 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "postlängd %u vid %X/%X är för lÃ¥ng" + +#: access/transam/xlogreader.c:404 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "det finns ingen contrecord-flagga vid %X/%X" + +#: access/transam/xlogreader.c:417 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "ogiltig contrecord-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:653 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" + +#: access/transam/xlogreader.c:667 access/transam/xlogreader.c:684 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" + +#: access/transam/xlogreader.c:721 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" + +#: access/transam/xlogreader.c:758 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "felaktigt magiskt nummer %04X i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:772 access/transam/xlogreader.c:823 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "ogiltiga infobitar %04X i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:798 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: WAL-filens databassystemidentifierare är %s, pg_control databassystemidentifierare är %s" + +#: access/transam/xlogreader.c:805 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: inkorrekt segmentstorlek i sidhuvuid" + +#: access/transam/xlogreader.c:811 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvuid" + +#: access/transam/xlogreader.c:842 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "oväntad sidadress %X/%X i loggsegment %s, offset %u" + +# FIXME +#: access/transam/xlogreader.c:867 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "\"ej i sekvens\"-fel pÃ¥ tidslinje-ID %u (efter %u) i loggsegment %s, offset %u" + +#: access/transam/xlogreader.c:1112 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "\"ej i sekvens\"-block_id %u vid %X/%X" + +#: access/transam/xlogreader.c:1135 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA satt, men ingen data inkluderad vid %X/%X" + +#: access/transam/xlogreader.c:1142 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ej satt, men datalängd är %u vid %X/%X" + +#: access/transam/xlogreader.c:1178 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE satt, men hÃ¥loffset %u längd %u block-image-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1194 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ej satt, men hÃ¥loffset %u längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1209 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED satt, men block-image-längd %u vid %X/%X" + +#: access/transam/xlogreader.c:1224 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_IS_COMPRESSED satt, men block-image-längd är %u vid %X/%X" + +#: access/transam/xlogreader.c:1240 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL satt men ingen tidigare rel vid %X/%X" + +#: access/transam/xlogreader.c:1252 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "ogiltig block_id %u vid %X/%X" + +#: access/transam/xlogreader.c:1341 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "post med ogiltig längd vid %X/%X" + +#: access/transam/xlogreader.c:1430 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "ogiltig komprimerad image vid %X/%X, block %d" + +#: access/transam/xlogutils.c:727 replication/walreceiver.c:959 +#: replication/walsender.c:2462 +#, c-format +msgid "could not seek in log segment %s to offset %u: %m" +msgstr "kunde inte söka i loggsegment %s till offset %u: %m" + +#: access/transam/xlogutils.c:751 +#, c-format +msgid "could not read from log segment %s, offset %u, length %lu: %m" +msgstr "kunde inte läsa frÃ¥n loggsegment %s, offset %u, längd %lu: %m" + +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X kräver ett tvÃ¥potensvärde mellan 1 MB och 1 GB" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:821 tcop/postgres.c:3648 +#, c-format +msgid "--%s requires a value" +msgstr "--%s kräver ett värde" + +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:826 tcop/postgres.c:3653 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s kräver ett värde" + +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:838 +#: postmaster/postmaster.c:851 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: bootstrap/bootstrap.c:313 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: ogiltigt kommandoradsargument\n" + +#: catalog/aclchk.c:203 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "\"grant option\" kan bara ges till roller" + +#: catalog/aclchk.c:326 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "inga rättigheter givna för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:331 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "inga rättigheter gavs till \"%s\"" + +#: catalog/aclchk.c:339 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "inte alla rättigheter givna för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:344 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "inte alla rättigheter givna för \"%s\"" + +#: catalog/aclchk.c:355 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "inga rättigheter kunde tas tillbaka frÃ¥n kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:360 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "inga rättigheter kunde tas tillbaka frÃ¥n \"%s\"" + +#: catalog/aclchk.c:368 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "inte alla rättigheter kunde tas tillbaka frÃ¥n kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:373 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "inte alla rättigheter kunde tas tillbaka frÃ¥n \"%s\"" + +#: catalog/aclchk.c:456 catalog/aclchk.c:999 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "ogiltig privilegietyp %s för relation" + +#: catalog/aclchk.c:460 catalog/aclchk.c:1003 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "ogiltig privilegietyp %s för sekvens" + +#: catalog/aclchk.c:464 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "ogiltig privilegietyp %s för databas" + +#: catalog/aclchk.c:468 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "ogiltig privilegietyp %s för domän" + +#: catalog/aclchk.c:472 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "ogiltig privilegietyp %s för funktion" + +#: catalog/aclchk.c:476 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "ogiltig privilegietyp %s för sprÃ¥k" + +#: catalog/aclchk.c:480 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "ogiltig privilegietyp %s för stort objekt" + +#: catalog/aclchk.c:484 catalog/aclchk.c:1023 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "ogiltig privilegietyp %s för schema" + +#: catalog/aclchk.c:488 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "ogiltig rättighetstyp %s för procedur" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1015 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "ogiltig rättighetstyp %s för rutin" + +#: catalog/aclchk.c:496 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "ogiltig privilegietyp %s för tabellutrymme" + +#: catalog/aclchk.c:500 catalog/aclchk.c:1019 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "ogiltig privilegietyp %s för typ" + +#: catalog/aclchk.c:504 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "ogiltig privilegietyp %s för främmande data-omvandlare" + +#: catalog/aclchk.c:508 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "ogiltig privilegietyp %s för främmande server" + +#: catalog/aclchk.c:547 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "kolumnprivilegier är bara giltiga för relationer" + +#: catalog/aclchk.c:707 catalog/aclchk.c:4135 catalog/aclchk.c:4917 +#: catalog/objectaddress.c:964 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:283 +#, c-format +msgid "large object %u does not exist" +msgstr "stort objekt %u existerar inte" + +#: catalog/aclchk.c:936 catalog/aclchk.c:945 commands/collationcmds.c:117 +#: commands/copy.c:1140 commands/copy.c:1160 commands/copy.c:1169 +#: commands/copy.c:1178 commands/copy.c:1187 commands/copy.c:1196 +#: commands/copy.c:1205 commands/copy.c:1214 commands/copy.c:1232 +#: commands/copy.c:1248 commands/copy.c:1268 commands/copy.c:1285 +#: commands/dbcommands.c:156 commands/dbcommands.c:165 +#: commands/dbcommands.c:174 commands/dbcommands.c:183 +#: commands/dbcommands.c:192 commands/dbcommands.c:201 +#: commands/dbcommands.c:210 commands/dbcommands.c:219 +#: commands/dbcommands.c:228 commands/dbcommands.c:1429 +#: commands/dbcommands.c:1438 commands/dbcommands.c:1447 +#: commands/dbcommands.c:1456 commands/extension.c:1688 +#: commands/extension.c:1698 commands/extension.c:1708 +#: commands/extension.c:1718 commands/extension.c:2960 +#: commands/foreigncmds.c:543 commands/foreigncmds.c:552 +#: commands/functioncmds.c:568 commands/functioncmds.c:734 +#: commands/functioncmds.c:743 commands/functioncmds.c:752 +#: commands/functioncmds.c:761 commands/functioncmds.c:2193 +#: commands/functioncmds.c:2201 commands/publicationcmds.c:91 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:111 commands/subscriptioncmds.c:121 +#: commands/subscriptioncmds.c:131 commands/subscriptioncmds.c:141 +#: commands/subscriptioncmds.c:155 commands/subscriptioncmds.c:166 +#: commands/subscriptioncmds.c:180 commands/tablecmds.c:6501 +#: commands/typecmds.c:299 commands/typecmds.c:1428 commands/typecmds.c:1437 +#: commands/typecmds.c:1445 commands/typecmds.c:1453 commands/typecmds.c:1461 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:562 commands/user.c:570 +#: commands/user.c:578 commands/user.c:586 commands/user.c:594 +#: commands/user.c:602 commands/user.c:610 commands/user.c:618 +#: commands/user.c:627 commands/user.c:635 commands/user.c:643 +#: parser/parse_utilcmd.c:385 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:817 +#: replication/walsender.c:828 replication/walsender.c:838 +#, c-format +msgid "conflicting or redundant options" +msgstr "motstridiga eller redundanta inställningar" + +#: catalog/aclchk.c:1056 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "standardrättigheter kan inte sättas för kolumner" + +#: catalog/aclchk.c:1216 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "kan inte använda IN SCHEMA-klausul samtidigt som GRANT/REVOKE ON SCHEMAS" + +#: catalog/aclchk.c:1584 catalog/catalog.c:519 catalog/objectaddress.c:1426 +#: commands/analyze.c:383 commands/copy.c:5132 commands/sequence.c:1702 +#: commands/tablecmds.c:6043 commands/tablecmds.c:6201 +#: commands/tablecmds.c:6275 commands/tablecmds.c:6345 +#: commands/tablecmds.c:6426 commands/tablecmds.c:6520 +#: commands/tablecmds.c:6579 commands/tablecmds.c:6718 +#: commands/tablecmds.c:6800 commands/tablecmds.c:6892 +#: commands/tablecmds.c:6986 commands/tablecmds.c:10219 +#: commands/tablecmds.c:10534 commands/tablecmds.c:11050 commands/trigger.c:928 +#: parser/analyze.c:2330 parser/parse_relation.c:2788 +#: parser/parse_relation.c:2851 parser/parse_target.c:1031 +#: parser/parse_type.c:127 utils/adt/acl.c:2885 utils/adt/ruleutils.c:2511 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "kolumn \"%s\" i relation \"%s\" existerar inte" + +#: catalog/aclchk.c:1847 catalog/objectaddress.c:1266 commands/sequence.c:1140 +#: commands/tablecmds.c:230 commands/tablecmds.c:14779 utils/adt/acl.c:2075 +#: utils/adt/acl.c:2105 utils/adt/acl.c:2137 utils/adt/acl.c:2169 +#: utils/adt/acl.c:2197 utils/adt/acl.c:2227 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" är inte en sekvens" + +#: catalog/aclchk.c:1885 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "sekvensen \"%s\" stöder bara USAGE-, SELECT- och UPDATE-rättigheter" + +#: catalog/aclchk.c:1902 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "ogiltig rättighetstyp %s för tabell" + +#: catalog/aclchk.c:2068 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "ogitligt rättighetstyp %s för kolumn" + +#: catalog/aclchk.c:2081 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "sekvensen \"%s\" stöder bara kolumnrättigheten SELECT" + +#: catalog/aclchk.c:2663 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "sprÃ¥ket \"%s\" är inte betrott" + +#: catalog/aclchk.c:2665 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT och REVOKE är inte tillÃ¥tna pÃ¥ icke betrodda sprÃ¥k dÃ¥ bara superanvändare kan använda icke betrodda sprÃ¥k." + +#: catalog/aclchk.c:3179 +#, c-format +msgid "cannot set privileges of array types" +msgstr "kan inte sätta privilegier för array-typer" + +#: catalog/aclchk.c:3180 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Sätt rättigheter för elementtypen istället." + +#: catalog/aclchk.c:3187 catalog/objectaddress.c:1560 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" är inte en domän" + +#: catalog/aclchk.c:3307 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "okänd privilegietyp \"%s\"" + +#: catalog/aclchk.c:3368 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "rättighet saknas för aggregat %s" + +#: catalog/aclchk.c:3371 +#, c-format +msgid "permission denied for collation %s" +msgstr "rättighet saknas för jämförelse %s" + +#: catalog/aclchk.c:3374 +#, c-format +msgid "permission denied for column %s" +msgstr "rättighet saknas för kolumn %s" + +#: catalog/aclchk.c:3377 +#, c-format +msgid "permission denied for conversion %s" +msgstr "rättighet saknas för konvertering %s" + +#: catalog/aclchk.c:3380 +#, c-format +msgid "permission denied for database %s" +msgstr "rättighet saknas för databas %s" + +#: catalog/aclchk.c:3383 +#, c-format +msgid "permission denied for domain %s" +msgstr "rättighet saknas för domän %s" + +#: catalog/aclchk.c:3386 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "rättighet saknas för händelseutlösare %s" + +#: catalog/aclchk.c:3389 +#, c-format +msgid "permission denied for extension %s" +msgstr "rättighet saknas för utökning %s" + +#: catalog/aclchk.c:3392 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "rättighet saknas för främmande data-omvandlare %s" + +#: catalog/aclchk.c:3395 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "rättighet saknas för främmande server %s" + +#: catalog/aclchk.c:3398 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "rättighet saknas för främmande tabell %s" + +#: catalog/aclchk.c:3401 +#, c-format +msgid "permission denied for function %s" +msgstr "rättighet saknas för funktion %s" + +#: catalog/aclchk.c:3404 +#, c-format +msgid "permission denied for index %s" +msgstr "rättighet saknas för index %s" + +#: catalog/aclchk.c:3407 +#, c-format +msgid "permission denied for language %s" +msgstr "rättighet saknas för sprÃ¥k %s" + +#: catalog/aclchk.c:3410 +#, c-format +msgid "permission denied for large object %s" +msgstr "rättighet saknas för stort objekt %s" + +#: catalog/aclchk.c:3413 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "rättighet saknas för materialiserad vy %s" + +#: catalog/aclchk.c:3416 +#, c-format +msgid "permission denied for operator class %s" +msgstr "rättighet saknas för operatorklasss %s" + +#: catalog/aclchk.c:3419 +#, c-format +msgid "permission denied for operator %s" +msgstr "rättighet saknas för operator %s" + +#: catalog/aclchk.c:3422 +#, c-format +msgid "permission denied for operator family %s" +msgstr "rättighet saknas för operatorfamilj %s" + +#: catalog/aclchk.c:3425 +#, c-format +msgid "permission denied for policy %s" +msgstr "rättighet saknas för policy %s" + +#: catalog/aclchk.c:3428 +#, c-format +msgid "permission denied for procedure %s" +msgstr "rättighet saknas för procedur %s" + +#: catalog/aclchk.c:3431 +#, c-format +msgid "permission denied for publication %s" +msgstr "rättighet saknas för publicering %s" + +#: catalog/aclchk.c:3434 +#, c-format +msgid "permission denied for routine %s" +msgstr "rättighet saknas för rutin %s" + +#: catalog/aclchk.c:3437 +#, c-format +msgid "permission denied for schema %s" +msgstr "rättighet saknas för schema %s" + +#: catalog/aclchk.c:3440 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 +#, c-format +msgid "permission denied for sequence %s" +msgstr "rättighet saknas för sekvens %s" + +#: catalog/aclchk.c:3443 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "rättighet saknas för statistikobjekt %s" + +#: catalog/aclchk.c:3446 +#, c-format +msgid "permission denied for subscription %s" +msgstr "rättighet saknas för prenumeration %s" + +#: catalog/aclchk.c:3449 +#, c-format +msgid "permission denied for table %s" +msgstr "rättighet saknas för tabell %s" + +#: catalog/aclchk.c:3452 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "rättighet saknas för tabellutrymme %s" + +#: catalog/aclchk.c:3455 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "rättighet saknas för textsökkonfigurering %s" + +#: catalog/aclchk.c:3458 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "rättighet saknas för textsökordlista %s" + +#: catalog/aclchk.c:3461 +#, c-format +msgid "permission denied for type %s" +msgstr "rättighet saknas för typ %s" + +#: catalog/aclchk.c:3464 +#, c-format +msgid "permission denied for view %s" +msgstr "rättighet saknas för vy %s" + +#: catalog/aclchk.c:3499 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "mÃ¥ste vara ägaren till aggregatet %s" + +#: catalog/aclchk.c:3502 +#, c-format +msgid "must be owner of collation %s" +msgstr "mÃ¥ste vara ägaren till jämförelsen %s" + +#: catalog/aclchk.c:3505 +#, c-format +msgid "must be owner of conversion %s" +msgstr "mÃ¥ste vara ägaren till konverteringen %s" + +#: catalog/aclchk.c:3508 +#, c-format +msgid "must be owner of database %s" +msgstr "mÃ¥ste vara ägaren till databasen %s" + +#: catalog/aclchk.c:3511 +#, c-format +msgid "must be owner of domain %s" +msgstr "mÃ¥ste vara ägaren av domänen %s" + +#: catalog/aclchk.c:3514 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "mÃ¥ste vara ägaren till händelseutlösaren %s" + +#: catalog/aclchk.c:3517 +#, c-format +msgid "must be owner of extension %s" +msgstr "mÃ¥ste vara ägaren till utökningen %s" + +#: catalog/aclchk.c:3520 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "mÃ¥ste vara ägaren till främmande data-omvandlaren %s" + +#: catalog/aclchk.c:3523 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "mÃ¥ste vara ägaren till främmande servern %s" + +#: catalog/aclchk.c:3526 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "mÃ¥ste vara ägaren till främmande tabellen %s" + +#: catalog/aclchk.c:3529 +#, c-format +msgid "must be owner of function %s" +msgstr "mÃ¥ste vara ägaren till funktionen %s" + +#: catalog/aclchk.c:3532 +#, c-format +msgid "must be owner of index %s" +msgstr "mÃ¥ste vara ägaren till indexet %s" + +#: catalog/aclchk.c:3535 +#, c-format +msgid "must be owner of language %s" +msgstr "mÃ¥ste vara ägaren till sprÃ¥ket %s" + +#: catalog/aclchk.c:3538 +#, c-format +msgid "must be owner of large object %s" +msgstr "mÃ¥ste vara ägaren till stora objektet %s" + +#: catalog/aclchk.c:3541 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "mÃ¥ste vara ägaren till den materialiserade vyn %s" + +#: catalog/aclchk.c:3544 +#, c-format +msgid "must be owner of operator class %s" +msgstr "mÃ¥ste vara ägaren till operatorklassen %s" + +#: catalog/aclchk.c:3547 +#, c-format +msgid "must be owner of operator %s" +msgstr "mÃ¥ste vara ägaren till operatorn %s" + +#: catalog/aclchk.c:3550 +#, c-format +msgid "must be owner of operator family %s" +msgstr "mÃ¥ste vara ägaren till operatorfamiljen %s" + +#: catalog/aclchk.c:3553 +#, c-format +msgid "must be owner of procedure %s" +msgstr "mÃ¥ste vara ägaren till proceduren %s" + +#: catalog/aclchk.c:3556 +#, c-format +msgid "must be owner of publication %s" +msgstr "mÃ¥ste vara ägaren till publiceringen %s" + +#: catalog/aclchk.c:3559 +#, c-format +msgid "must be owner of routine %s" +msgstr "mÃ¥ste vara ägaren till rutinen %s" + +#: catalog/aclchk.c:3562 +#, c-format +msgid "must be owner of sequence %s" +msgstr "mÃ¥ste vara ägaren till sekvensen %s" + +#: catalog/aclchk.c:3565 +#, c-format +msgid "must be owner of subscription %s" +msgstr "mÃ¥ste vara ägaren till prenumerationen %s" + +#: catalog/aclchk.c:3568 +#, c-format +msgid "must be owner of table %s" +msgstr "mÃ¥ste vara ägaren till tabellen %s" + +#: catalog/aclchk.c:3571 +#, c-format +msgid "must be owner of type %s" +msgstr "mÃ¥ste vara ägaren till typen %s" + +#: catalog/aclchk.c:3574 +#, c-format +msgid "must be owner of view %s" +msgstr "mÃ¥ste vara ägaren till vyn %s" + +#: catalog/aclchk.c:3577 +#, c-format +msgid "must be owner of schema %s" +msgstr "mÃ¥ste vara ägaren till schemat %s" + +#: catalog/aclchk.c:3580 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "mÃ¥ste vara ägaren till statistikobjektet %s" + +#: catalog/aclchk.c:3583 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "mÃ¥ste vara ägaren till tabellutrymmet %s" + +#: catalog/aclchk.c:3586 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "mÃ¥ste vara ägaren till textsökkonfigurationen %s" + +#: catalog/aclchk.c:3589 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "mÃ¥ste vara ägaren till textsökordlistan %s" + +#: catalog/aclchk.c:3603 +#, c-format +msgid "must be owner of relation %s" +msgstr "mÃ¥ste vara ägaren till relationen %s" + +#: catalog/aclchk.c:3647 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "rättighet saknas för kolumn \"%s\" i relation \"%s\"" + +#: catalog/aclchk.c:3768 catalog/aclchk.c:3776 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "attribut %d i relation med OID %u existerar inte" + +#: catalog/aclchk.c:3849 catalog/aclchk.c:4768 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "relation med OID %u existerar inte" + +#: catalog/aclchk.c:3948 catalog/aclchk.c:5186 +#, c-format +msgid "database with OID %u does not exist" +msgstr "databas med OID %u finns inte" + +#: catalog/aclchk.c:4002 catalog/aclchk.c:4846 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2017 +#, c-format +msgid "function with OID %u does not exist" +msgstr "funktionen med OID %u existerar inte" + +#: catalog/aclchk.c:4056 catalog/aclchk.c:4872 +#, c-format +msgid "language with OID %u does not exist" +msgstr "sprÃ¥k med OID %u existerar inte" + +#: catalog/aclchk.c:4220 catalog/aclchk.c:4944 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "schema med OID %u existerar inte" + +#: catalog/aclchk.c:4274 catalog/aclchk.c:4971 utils/adt/genfile.c:637 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "tabellutrymme med OID %u finns inte" + +#: catalog/aclchk.c:4333 catalog/aclchk.c:5105 commands/foreigncmds.c:328 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "främmande data-omvandlare med OID %u finns inte" + +#: catalog/aclchk.c:4395 catalog/aclchk.c:5132 commands/foreigncmds.c:465 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "främmande server med OID %u finns inte" + +#: catalog/aclchk.c:4455 catalog/aclchk.c:4794 utils/cache/typcache.c:369 +#, c-format +msgid "type with OID %u does not exist" +msgstr "typ med OID %u existerar inte" + +#: catalog/aclchk.c:4820 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "operator med OID %u existerar inte" + +#: catalog/aclchk.c:4997 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "operatorklass med OID %u existerar inte" + +#: catalog/aclchk.c:5024 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "operatorfamilj med OID %u existerar inte" + +#: catalog/aclchk.c:5051 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "textsökordlista med OID %u existerar inte" + +#: catalog/aclchk.c:5078 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "textsökkonfiguration med OID %u existerar inte" + +#: catalog/aclchk.c:5159 commands/event_trigger.c:596 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "händelseutlösare med OID %u existerar inte" + +#: catalog/aclchk.c:5212 commands/collationcmds.c:366 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "jämförelse med OID %u existerar inte" + +#: catalog/aclchk.c:5238 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "konvertering med OID %u existerar inte" + +#: catalog/aclchk.c:5279 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "utökning med OID %u existerar inte" + +#: catalog/aclchk.c:5306 commands/publicationcmds.c:759 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "publicering med OID %u existerar inte" + +#: catalog/aclchk.c:5332 commands/subscriptioncmds.c:1121 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "prenumeration med OID %u existerar inte" + +#: catalog/aclchk.c:5358 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "statistikobjekt med OID %u finns inte" + +#: catalog/catalog.c:498 +#, c-format +msgid "must be superuser to call pg_nextoid()" +msgstr "mÃ¥ste vara superanvändare för att anropa pg_nextoid()" + +#: catalog/catalog.c:506 +#, c-format +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "pg_nextoid() kan bara användas pÃ¥ systemkataloger" + +#: catalog/catalog.c:511 parser/parse_utilcmd.c:2064 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "index \"%s\" tillhör inte tabell \"%s\"" + +#: catalog/catalog.c:528 +#, c-format +msgid "column \"%s\" is not of type oid" +msgstr "kolumnen \"%s\" är inte av typen oid" + +#: catalog/catalog.c:535 +#, c-format +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "index \"%s\" är inte indexet för kolumnen \"%s\"" + +#: catalog/dependency.c:808 catalog/dependency.c:1036 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "kan inte ta bort %s eftersom %s behöver den" + +#: catalog/dependency.c:810 catalog/dependency.c:1038 +#, c-format +msgid "You can drop %s instead." +msgstr "Du kan ta bort %s i stället." + +#: catalog/dependency.c:908 catalog/pg_shdepend.c:641 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "kan inte ta bort %s eftersom den krävs av databassystemet" + +#: catalog/dependency.c:1104 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "drop svämmar automatiskt över (cascades) till %s" + +#: catalog/dependency.c:1116 catalog/dependency.c:1125 +#, c-format +msgid "%s depends on %s" +msgstr "%s beror pÃ¥ %s" + +#: catalog/dependency.c:1137 catalog/dependency.c:1146 +#, c-format +msgid "drop cascades to %s" +msgstr "drop svämmar över (cascades) till %s" + +#: catalog/dependency.c:1154 catalog/pg_shdepend.c:770 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"och %d annat objekt (se serverloggen för en lista)" +msgstr[1] "" +"\n" +"och %d andra objekt (se serverloggen för en lista)" + +#: catalog/dependency.c:1166 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "kan inte ta bort %s eftersom andra objekt beror pÃ¥ den" + +#: catalog/dependency.c:1168 catalog/dependency.c:1169 +#: catalog/dependency.c:1175 catalog/dependency.c:1176 +#: catalog/dependency.c:1187 catalog/dependency.c:1188 +#: commands/tablecmds.c:1196 commands/tablecmds.c:12077 commands/user.c:1073 +#: commands/view.c:505 libpq/auth.c:333 replication/syncrep.c:1163 +#: storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1348 utils/adt/acl.c:5344 +#: utils/misc/guc.c:6576 utils/misc/guc.c:6612 utils/misc/guc.c:6682 +#: utils/misc/guc.c:10731 utils/misc/guc.c:10765 utils/misc/guc.c:10799 +#: utils/misc/guc.c:10833 utils/misc/guc.c:10868 utils/misc/guc.c:11613 +#: utils/misc/guc.c:11700 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1170 catalog/dependency.c:1177 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Använd DROP ... CASCADE för att ta bort de beroende objekten ocksÃ¥." + +#: catalog/dependency.c:1174 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "kan inte ta bort önskade objekt eftersom andra objekt beror pÃ¥ dem" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:1183 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "drop svämmar över (cascades) till %d andra objekt" +msgstr[1] "drop svämmar över (cascades) till %d andra objekt" + +#: catalog/dependency.c:1845 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "konstant av typen %s kan inte användas här" + +#: catalog/heap.c:332 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "rättighet saknas för att skapa \"%s.%s\"" + +#: catalog/heap.c:334 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "Systemkatalogändringar är för tillfället inte tillÃ¥tna." + +#: catalog/heap.c:502 commands/tablecmds.c:2047 commands/tablecmds.c:2564 +#: commands/tablecmds.c:5648 +#, c-format +msgid "tables can have at most %d columns" +msgstr "tabeller kan ha som mest %d kolumner" + +#: catalog/heap.c:520 commands/tablecmds.c:5933 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "kolumnnamn \"%s\" stÃ¥r i konflikt med ett systemkolumnnamn" + +#: catalog/heap.c:536 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "kolumnnamn \"%s\" angiven mer än en gÃ¥ng" + +#: catalog/heap.c:604 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "kolumn \"%s\" har pseudo-typ %s" + +#: catalog/heap.c:634 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "composite-typ %s kan inte vara en del av sig själv" + +#: catalog/heap.c:676 commands/createas.c:204 commands/createas.c:488 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "ingen jämförelse kunde härledas för kolumn \"%s\" med jämförelsetyp %s" + +#: catalog/heap.c:1122 catalog/index.c:819 commands/tablecmds.c:3331 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "relationen \"%s\" finns redan" + +#: catalog/heap.c:1138 catalog/pg_type.c:427 catalog/pg_type.c:749 +#: commands/typecmds.c:240 commands/typecmds.c:791 commands/typecmds.c:1191 +#: commands/typecmds.c:1403 commands/typecmds.c:2160 +#, c-format +msgid "type \"%s\" already exists" +msgstr "typen \"%s\" existerar redan" + +#: catalog/heap.c:1139 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "En relation har en associerad typ med samma namn sÃ¥ du mÃ¥ste använda ett namn som inte krockar med nÃ¥gon existerande typ." + +#: catalog/heap.c:1168 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "pg_class heap OID-värde är inte satt i binärt uppgraderingsläge" + +#: catalog/heap.c:2369 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "kan inte lägga till NO INHERIT-villkor till partitionerad tabell \"%s\"" + +#: catalog/heap.c:2639 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "check-villkor \"%s\" finns redan" + +#: catalog/heap.c:2809 catalog/index.c:833 catalog/pg_constraint.c:669 +#: commands/tablecmds.c:7326 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "integritetsvillkor \"%s\" för relation \"%s\" finns redan" + +#: catalog/heap.c:2816 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "villkor \"%s\" stÃ¥r i konflikt med icke-ärvt villkor pÃ¥ relation \"%s\"" + +#: catalog/heap.c:2827 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "villkor \"%s\" stÃ¥r i konflikt med ärvt villkor pÃ¥ relation \"%s\"" + +#: catalog/heap.c:2837 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "villkor \"%s\" stÃ¥r i konflikt med NOT VALID-villkor pÃ¥ relation \"%s\"" + +#: catalog/heap.c:2842 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "slÃ¥r samman villkor \"%s\" med ärvd definition" + +#: catalog/heap.c:2944 +#, c-format +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "kan inte använda genererad kolumn \"%s\" i kolumngenereringsuttryck" + +#: catalog/heap.c:2946 +#, c-format +msgid "A generated column cannot reference another generated column." +msgstr "En genererad kolumn kan inte referera till en annan genererad kolumn." + +#: catalog/heap.c:2998 +#, c-format +msgid "generation expression is not immutable" +msgstr "genereringsuttryck är inte immutable" + +#: catalog/heap.c:3026 rewrite/rewriteHandler.c:1189 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "kolumn \"%s\" har typ %s men default-uttryck har typen %s" + +#: catalog/heap.c:3031 commands/prepare.c:384 parser/parse_node.c:435 +#: parser/parse_target.c:591 parser/parse_target.c:866 +#: parser/parse_target.c:876 rewrite/rewriteHandler.c:1194 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Du mÃ¥ste skriva om eller typomvandla uttrycket." + +#: catalog/heap.c:3078 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "bara tabell \"%s\" kan refereras i check-villkoret" + +#: catalog/heap.c:3328 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "inget stöd för kombinationen ON COMMIT och främmande nyckel" + +#: catalog/heap.c:3329 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "Tabell \"%s\" refererar till \"%s\", men de har inte samma ON COMMIT-inställning." + +#: catalog/heap.c:3334 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "kan inte trunkera en tabell som refererars till i ett främmande nyckelvillkor" + +#: catalog/heap.c:3335 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "Tabell \"%s\" refererar till \"%s\"." + +#: catalog/heap.c:3337 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "Trunkera tabellen \"%s\" samtidigt, eller använd TRUNCATE ... CASCADE." + +#: catalog/index.c:219 parser/parse_utilcmd.c:1873 parser/parse_utilcmd.c:1972 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "multipla primärnycklar för tabell \"%s\" tillÃ¥ts inte" + +#: catalog/index.c:237 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "primärnycklar kan inte vara uttryck" + +#: catalog/index.c:254 +#, c-format +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "primärnyckelkolumn \"%s\" är inte markerad NOT NULL" + +#: catalog/index.c:763 catalog/index.c:1709 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "användardefinierade index pÃ¥ systemkatalogen är inte möjligt" + +#: catalog/index.c:773 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "samtida indexskapande pÃ¥ systemkatalogtabeller stöds inte" + +#: catalog/index.c:791 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "delade index kan inte skapas efter initdb" + +#: catalog/index.c:811 commands/createas.c:253 commands/sequence.c:154 +#: parser/parse_utilcmd.c:208 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "relationen \"%s\" finns redan, hoppar över" + +#: catalog/index.c:861 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "pg_class index OID-värde är inte satt i binärt uppgraderingsläge" + +#: catalog/index.c:1985 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY mÃ¥ste vara första operationen i transaktion" + +#: catalog/index.c:2682 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "bygger index \"%s\" pÃ¥ tabell \"%s\" seriellt" + +#: catalog/index.c:2687 +#, c-format +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "bygger index \"%s\" pÃ¥ tabell \"%s\" och efterfrÃ¥gar %d parallell arbetare" +msgstr[1] "bygger index \"%s\" pÃ¥ tabell \"%s\" och efterfrÃ¥gar %d parallella arbetare" + +#: catalog/index.c:3310 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "kan inte omindexera temporära tabeller som tillhör andra sessioner" + +#: catalog/index.c:3441 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "index \"%s\" omindexerades" + +#: catalog/index.c:3514 commands/indexcmds.c:2886 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "REINDEX pÃ¥ partitionerade tabeller är inte implementerat ännu, hoppar över \"%s\"" + +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 +#: commands/trigger.c:5396 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "referenser till andra databaser är inte implementerat: \"%s.%s.%s\"" + +#: catalog/namespace.c:306 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "temporära tabeller kan inte anges med ett schemanamn" + +#: catalog/namespace.c:387 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "kunde inte ta lÃ¥s pÃ¥ relationen \"%s.%s\"" + +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:249 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "kunde inte ta lÃ¥s pÃ¥ relationen \"%s\"" + +#: catalog/namespace.c:420 parser/parse_relation.c:1172 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "relationen \"%s.%s\" existerar inte" + +#: catalog/namespace.c:425 parser/parse_relation.c:1185 +#: parser/parse_relation.c:1193 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "relationen \"%s\" existerar inte" + +#: catalog/namespace.c:491 catalog/namespace.c:3009 commands/extension.c:1469 +#: commands/extension.c:1475 +#, c-format +msgid "no schema has been selected to create in" +msgstr "inget schema har valts för att skapa i" + +#: catalog/namespace.c:643 catalog/namespace.c:656 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "kan inte skapa relationer i temporära scheman som tillhör andra sessioner" + +#: catalog/namespace.c:647 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "kan inte skapa temporär relation i icke-temporärt schema" + +#: catalog/namespace.c:662 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "bara temporära relationer fÃ¥r skapas i temporära scheman" + +#: catalog/namespace.c:2201 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "statistikobjektet \"%s\" existerar inte" + +#: catalog/namespace.c:2324 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "textsökparser \"%s\" finns inte" + +#: catalog/namespace.c:2450 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "textsökkatalog \"%s\" finns inte" + +#: catalog/namespace.c:2577 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "textsökmall \"%s\" finns inte" + +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1197 +#: utils/cache/ts_cache.c:615 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "textsökkonfiguration \"%s\" finns inte" + +#: catalog/namespace.c:2816 parser/parse_expr.c:866 parser/parse_target.c:1221 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "referenser till andra databaser är inte implementerat: %s" + +#: catalog/namespace.c:2822 gram.y:14731 gram.y:16165 parser/parse_expr.c:873 +#: parser/parse_target.c:1228 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "ej korrekt kvalificerat namn (för mÃ¥nga namn med punkt): %s" + +#: catalog/namespace.c:2952 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "kan inte flytta objekt in eller ut frÃ¥n temporära scheman" + +#: catalog/namespace.c:2958 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "kan inte flytta objekt in eller ut frÃ¥n TOAST-schema" + +#: catalog/namespace.c:3031 commands/schemacmds.c:257 commands/schemacmds.c:337 +#: commands/tablecmds.c:1141 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "schema \"%s\" existerar inte" + +#: catalog/namespace.c:3062 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "ej korrekt relationsnamn (för mÃ¥nga namn med punkt): %s" + +#: catalog/namespace.c:3596 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "jämförelse \"%s\" för kodning \"%s\" finns inte" + +#: catalog/namespace.c:3651 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "konvertering \"%s\" finns inte" + +#: catalog/namespace.c:3891 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "rättighet saknas för att skapa temporära tabeller i databasen \"%s\"" + +#: catalog/namespace.c:3907 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "kan inte skapa temptabeller under Ã¥terställning" + +#: catalog/namespace.c:3913 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "kan inte skapa temporära tabeller under en parallell operation" + +#: catalog/namespace.c:4196 commands/tablespace.c:1186 commands/variable.c:64 +#: utils/misc/guc.c:10900 utils/misc/guc.c:10978 +#, c-format +msgid "List syntax is invalid." +msgstr "List-syntaxen är ogiltig." + +#: catalog/objectaddress.c:1274 catalog/pg_publication.c:66 +#: commands/policy.c:95 commands/policy.c:395 commands/policy.c:485 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 commands/tablecmds.c:1903 +#: commands/tablecmds.c:5152 commands/tablecmds.c:10337 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" är inte en tabell" + +#: catalog/objectaddress.c:1281 commands/tablecmds.c:236 +#: commands/tablecmds.c:5182 commands/tablecmds.c:14784 commands/view.c:138 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" är inte en vy" + +#: catalog/objectaddress.c:1288 commands/matview.c:175 commands/tablecmds.c:242 +#: commands/tablecmds.c:14789 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" är inte en materialiserad vy" + +#: catalog/objectaddress.c:1295 commands/tablecmds.c:260 +#: commands/tablecmds.c:5185 commands/tablecmds.c:14794 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" är inte en främmande tabell" + +#: catalog/objectaddress.c:1336 +#, c-format +msgid "must specify relation and object name" +msgstr "mÃ¥ste ange relation och objektnamn" + +#: catalog/objectaddress.c:1412 catalog/objectaddress.c:1465 +#, c-format +msgid "column name must be qualified" +msgstr "kolumnnamn mÃ¥ste vara kvalificerat" + +#: catalog/objectaddress.c:1512 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "standardvärde för kolumn \"%s\" i relation \"%s\" existerar inte" + +#: catalog/objectaddress.c:1549 commands/functioncmds.c:132 +#: commands/tablecmds.c:252 commands/typecmds.c:3321 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4451 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "typen \"%s\" existerar inte" + +#: catalog/objectaddress.c:1668 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "operator %d (%s, %s) för %s finns inte" + +#: catalog/objectaddress.c:1699 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "funktion %d (%s, %s) för %s finns inte" + +#: catalog/objectaddress.c:1750 catalog/objectaddress.c:1776 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "användarmappning för användare \"%s\" pÃ¥ server \"%s\" finns inte" + +#: catalog/objectaddress.c:1765 commands/foreigncmds.c:433 +#: commands/foreigncmds.c:1016 commands/foreigncmds.c:1396 +#: foreign/foreign.c:723 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "server \"%s\" finns inte" + +#: catalog/objectaddress.c:1832 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "publiceringsrelation \"%s\" i publicering \"%s\" finns inte" + +#: catalog/objectaddress.c:1894 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "okänd standard-ACL-objekttyp \"%c\"" + +#: catalog/objectaddress.c:1895 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Giltiga objekttyper är \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1946 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "standard ACL för användare \"%s\" i schema \"%s\" pÃ¥ %s finns inte" + +#: catalog/objectaddress.c:1951 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "standard ACL för användare \"%s\" pÃ¥ %s finns inte" + +#: catalog/objectaddress.c:1978 catalog/objectaddress.c:2036 +#: catalog/objectaddress.c:2093 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "namn eller argumentlistor fÃ¥r inte innehÃ¥lla null" + +#: catalog/objectaddress.c:2012 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "ej stöd för objekttyp \"%s\"" + +#: catalog/objectaddress.c:2032 catalog/objectaddress.c:2050 +#: catalog/objectaddress.c:2191 +#, c-format +msgid "name list length must be exactly %d" +msgstr "namnlistlängen mÃ¥ste vara exakt %d" + +#: catalog/objectaddress.c:2054 +#, c-format +msgid "large object OID may not be null" +msgstr "stort objekt-OID fÃ¥r inte vara null" + +#: catalog/objectaddress.c:2063 catalog/objectaddress.c:2126 +#: catalog/objectaddress.c:2133 +#, c-format +msgid "name list length must be at least %d" +msgstr "namnlistlängden mÃ¥ste vara minst %d" + +#: catalog/objectaddress.c:2119 catalog/objectaddress.c:2140 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "argumentlistans längd mÃ¥ste vara exakt %d" + +#: catalog/objectaddress.c:2370 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "mÃ¥ste vara ägaren till stort objekt %u" + +#: catalog/objectaddress.c:2385 commands/functioncmds.c:1535 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "mÃ¥ste vara ägaren till typ %s eller typ %s" + +#: catalog/objectaddress.c:2435 catalog/objectaddress.c:2452 +#, c-format +msgid "must be superuser" +msgstr "mÃ¥ste vara superanvändare" + +#: catalog/objectaddress.c:2442 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "mÃ¥ste ha rättigheten CREATEROLE" + +#: catalog/objectaddress.c:2521 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "okänd objekttyp \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2742 +#, c-format +msgid "column %s of %s" +msgstr "kolumn %s av %s" + +#: catalog/objectaddress.c:2752 +#, c-format +msgid "function %s" +msgstr "funktion %s" + +#: catalog/objectaddress.c:2757 +#, c-format +msgid "type %s" +msgstr "typ %s" + +#: catalog/objectaddress.c:2787 +#, c-format +msgid "cast from %s to %s" +msgstr "typomvandling frÃ¥n %s till %s" + +#: catalog/objectaddress.c:2815 +#, c-format +msgid "collation %s" +msgstr "jämförelse %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2841 +#, c-format +msgid "constraint %s on %s" +msgstr "villkor %s pÃ¥ %s" + +#: catalog/objectaddress.c:2847 +#, c-format +msgid "constraint %s" +msgstr "villkor %s" + +#: catalog/objectaddress.c:2874 +#, c-format +msgid "conversion %s" +msgstr "konvertering %s" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2913 +#, c-format +msgid "default value for %s" +msgstr "default-värde för %s" + +#: catalog/objectaddress.c:2922 +#, c-format +msgid "language %s" +msgstr "sprÃ¥k %s" + +#: catalog/objectaddress.c:2927 +#, c-format +msgid "large object %u" +msgstr "stort objekt %u" + +#: catalog/objectaddress.c:2932 +#, c-format +msgid "operator %s" +msgstr "operator %s" + +#: catalog/objectaddress.c:2964 +#, c-format +msgid "operator class %s for access method %s" +msgstr "operatorklass %s för accessmetod %s" + +#: catalog/objectaddress.c:2987 +#, c-format +msgid "access method %s" +msgstr "accessmetod %s" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:3029 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "operator %d (%s, %s) för %s: %s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3079 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "funktion %d (%s, %s) för %s: %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3123 +#, c-format +msgid "rule %s on %s" +msgstr "regel %s pÃ¥ %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3161 +#, c-format +msgid "trigger %s on %s" +msgstr "utlösare %s pÃ¥ %s" + +#: catalog/objectaddress.c:3177 +#, c-format +msgid "schema %s" +msgstr "schema %s" + +#: catalog/objectaddress.c:3200 +#, c-format +msgid "statistics object %s" +msgstr "statistikobjekt %s" + +#: catalog/objectaddress.c:3227 +#, c-format +msgid "text search parser %s" +msgstr "textsökparser %s" + +#: catalog/objectaddress.c:3253 +#, c-format +msgid "text search dictionary %s" +msgstr "textsökordlista %s" + +#: catalog/objectaddress.c:3279 +#, c-format +msgid "text search template %s" +msgstr "textsökmall %s" + +#: catalog/objectaddress.c:3305 +#, c-format +msgid "text search configuration %s" +msgstr "textsökkonfiguration %s" + +#: catalog/objectaddress.c:3314 +#, c-format +msgid "role %s" +msgstr "roll %s" + +#: catalog/objectaddress.c:3327 +#, c-format +msgid "database %s" +msgstr "databas %s" + +#: catalog/objectaddress.c:3339 +#, c-format +msgid "tablespace %s" +msgstr "tabellutrymme %s" + +#: catalog/objectaddress.c:3348 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "främmande data-omvandlare %s" + +#: catalog/objectaddress.c:3357 +#, c-format +msgid "server %s" +msgstr "server %s" + +#: catalog/objectaddress.c:3385 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "användarmappning för %s pÃ¥ server %s" + +#: catalog/objectaddress.c:3430 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "standardrättigheter för nya relationer som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3434 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "standardrättigheter för nya relationer som tillhör rollen %s" + +#: catalog/objectaddress.c:3440 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "standardrättigheter för nya sekvenser som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3444 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "standardrättigheter för nya sekvenser som tillhör rollen %s" + +#: catalog/objectaddress.c:3450 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "standardrättigheter för nya funktioner som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3454 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "standardrättigheter för nya funktioner som tillhör rollen %s" + +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "standardrättigheter för nya typer som tillhör rollen %s i schema %s" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "standardrättigheter för nya typer som tillhör rollen %s" + +#: catalog/objectaddress.c:3470 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr ".\n" +msgstr "" +"\n" +"Vänligen läs dokumentationen för en komplett lista av körningsinställningar\n" +"och hur man anger dem pÃ¥ kommandoraden eller i konfigurationsfilen.\n" +"\n" +"Rapportera buggar till .\n" + +#: main/main.c:391 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Att köra PostgreSQL-servern som \"root\" tillÃ¥ts inte.\n" +"Servern mÃ¥ste starts av ett icke priviligerat användare-ID för att förhindra\n" +"ev. säkehetsproblem. Se dokumentationen för mer information om hur man\n" +"startar servern pÃ¥ rätt sätt.\n" + +#: main/main.c:408 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: riktig och effektiv användar-ID mÃ¥ste matcha varandra\n" + +#: main/main.c:415 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"Det är inte tillÃ¥tet för en användare med administratörsrättigheter att köra\n" +"PostgreSQL.\n" +"Servern mÃ¥ste starts av ett icke priviligerat användare-ID för att förhindra\n" +"ev. säkehetsproblem. Se dokumentationen för mer information om hur man startar\n" +"servern pÃ¥ rätt sätt.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "utökningsbar nodtyp \"%s\" finns redan" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "ExtensibleNodeMethods \"%s\" har inte registerats" + +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2201 parser/parse_func.c:705 parser/parse_oper.c:967 +#, c-format +msgid "could not find array type for data type %s" +msgstr "kunde inte hitta array-typ för datatyp %s" + +#: optimizer/path/joinrels.c:833 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN stöds bara med villkor som är merge-joinbara eller hash-joinbara" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1195 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s kan inte appliceras pÃ¥ den nullbara sidan av en outer join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1912 parser/analyze.c:1644 parser/analyze.c:1842 +#: parser/analyze.c:2700 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s tillåẗs inte med UNION/INTERSECT/EXCEPT" + +#: optimizer/plan/planner.c:2498 optimizer/plan/planner.c:4152 +#, c-format +msgid "could not implement GROUP BY" +msgstr "kunde inte implementera GROUP BY" + +#: optimizer/plan/planner.c:2499 optimizer/plan/planner.c:4153 +#: optimizer/plan/planner.c:4891 optimizer/prep/prepunion.c:1042 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "NÃ¥gra av datatyperna stöder bara hash:ning medan andra bara stöder sortering." + +#: optimizer/plan/planner.c:4890 +#, c-format +msgid "could not implement DISTINCT" +msgstr "kunde inte implementera DISTINCT" + +#: optimizer/plan/planner.c:5625 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "kunde inte implementera fönster-PARTITION BY" + +#: optimizer/plan/planner.c:5626 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Fönsterpartitionskolumner mÃ¥sta ha en sorterbar datatyp." + +#: optimizer/plan/planner.c:5630 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "kunde inte implementera fönster-ORDER BY" + +#: optimizer/plan/planner.c:5631 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Fönsterordningskolumner mÃ¥ste ha en sorterbar datatyp." + +#: optimizer/plan/setrefs.c:424 +#, c-format +msgid "too many range table entries" +msgstr "för mÃ¥nga element i \"range table\"" + +#: optimizer/prep/prepunion.c:505 +#, c-format +msgid "could not implement recursive UNION" +msgstr "kunde inte implementera rekursiv UNION" + +#: optimizer/prep/prepunion.c:506 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Alla kolumndatatyper mÃ¥sta vara hash-bara." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1041 +#, c-format +msgid "could not implement %s" +msgstr "kunde inte implementera %s" + +#: optimizer/util/clauses.c:4781 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "SQL-funktion \"%s\" vid inline:ing" + +#: optimizer/util/plancat.c:130 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "kan inte accessa temporära eller ologgade relationer under Ã¥terställning" + +#: optimizer/util/plancat.c:650 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "inferens av unikt index för hel rad stöds inte" + +#: optimizer/util/plancat.c:667 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "villkor för ON CONFLICT-klausul har inget associerat index" + +#: optimizer/util/plancat.c:717 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE stöds inte med uteslutningsvillkor" + +#: optimizer/util/plancat.c:822 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "finns inget unik eller uteslutningsvillkor som matchar ON CONFLICT-specifikationen" + +#: parser/analyze.c:711 parser/analyze.c:1407 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VÄRDE-listor mÃ¥ste alla ha samma längd" + +#: parser/analyze.c:914 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT har fler uttryck än mÃ¥lkolumner" + +#: parser/analyze.c:932 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT har fler mÃ¥lkolumner än uttryck" + +#: parser/analyze.c:936 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "Imatningskällan är ett raduttryck som innehÃ¥ller samma antal kolumner som INSERT:en förväntade sig. Glömde du använda extra parenteser?" + +#: parser/analyze.c:1218 parser/analyze.c:1617 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO tillÃ¥ts inte här" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1549 parser/analyze.c:2879 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s kan inte appliceras pÃ¥ VÄRDEN" + +#: parser/analyze.c:1767 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "ogiltig UNION/INTERSECT/EXCEPT ORDER BY-klausul" + +#: parser/analyze.c:1768 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Bara kolumnnamn i resultatet kan användas, inte uttryck eller funktioner." + +#: parser/analyze.c:1769 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Lägg till uttrycket/funktionen till varje SELECT eller flytta UNION:en in i en FROM-klausul." + +#: parser/analyze.c:1832 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO tillÃ¥ts bara i den första SELECT i UNION/INTERSECT/EXCEPT" + +#: parser/analyze.c:1904 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "UNION/INTERSECT/EXCEPT-medlemssats kan inte referera till andra relationer pÃ¥ samma frÃ¥genivÃ¥" + +#: parser/analyze.c:1993 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "varje %s-frÃ¥ga mÃ¥ste ha samma antal kolumner" + +#: parser/analyze.c:2411 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING mÃ¥ste ha minst en kolumn" + +#: parser/analyze.c:2452 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "kan inte ange bÃ¥de SCROLL och NO SCROLL" + +#: parser/analyze.c:2471 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR fÃ¥r inte innehÃ¥lla datamodifierande satser i WITH" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2479 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s stöds inte" + +#: parser/analyze.c:2482 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "HÃ¥llbara markörer mÃ¥ste vara READ ONLY." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2490 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s stöds inte" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2501 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s stöds inte" + +#: parser/analyze.c:2504 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Okänsliga markörer mÃ¥ste vara READ ONLY." + +#: parser/analyze.c:2570 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "materialiserade vyer fÃ¥r inte innehÃ¥lla datamodifierande satser i WITH" + +#: parser/analyze.c:2580 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "materialiserade vyer fÃ¥r inte använda temporära tabeller eller vyer" + +#: parser/analyze.c:2590 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "materialiserade vyer kan inte defineras med bundna parametrar" + +#: parser/analyze.c:2602 +#, c-format +msgid "materialized views cannot be unlogged" +msgstr "materialiserad vyer kan inte vara ologgade" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2707 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s tillÃ¥ts inte med DISTINCT-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2714 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "%s tillÃ¥ts inte med GROUP BY-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2721 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "%s tillÃ¥ts inte med HAVING-klausul" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2728 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "%s tillÃ¥ts inte med aggregatfunktioner" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2735 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "%s tillÃ¥ts inte med fönsterfunktioner" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2742 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s tillÃ¥ts inte med mängdreturnerande funktioner i mÃ¥llistan" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2821 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s: mÃ¥ste ange okvalificerade relationsnamn" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2852 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s kan inte appliceras pÃ¥ en join" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2861 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s kan inte appliceras pÃ¥ en funktion" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2870 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s kan inte appliceras pÃ¥ tabellfunktion" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2888 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s kan inte appliceras pÃ¥ en WITH-frÃ¥ga" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2897 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s kan inte appliceras pÃ¥ en namngiven tupellagring" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2917 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "relationen \"%s\" i %s-klausul hittades inte i FROM-klausul" + +#: parser/parse_agg.c:220 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "kunde inte identifiera en jämförelseoperator för typ %s" + +#: parser/parse_agg.c:222 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "Aggregat med DISTINCT mÃ¥ste kunna sortera sina indata." + +#: parser/parse_agg.c:257 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING mÃ¥ste ha färre än 32 argument" + +#: parser/parse_agg.c:360 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "aggregatfunktioner tillÃ¥ts inte i JOIN-villkor" + +#: parser/parse_agg.c:362 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "gruppoperationer tillÃ¥ts inte i JOIN-villkor" + +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "aggregatfunktioner tillÃ¥ts inte i FROM-klausul pÃ¥ sin egen frÃ¥genivÃ¥" + +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "gruppoperationer tillÃ¥ts inte i FROM-klausul pÃ¥ sin egen frÃ¥genivÃ¥" + +#: parser/parse_agg.c:381 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "aggregatfunktioner tillÃ¥ts inte i funktioner i FROM" + +#: parser/parse_agg.c:383 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "gruppoperationer tillÃ¥ts inte i funktioner i FROM" + +#: parser/parse_agg.c:391 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i policyuttryck" + +#: parser/parse_agg.c:393 +msgid "grouping operations are not allowed in policy expressions" +msgstr "gruppoperationer tillÃ¥ts inte i policyuttryck" + +#: parser/parse_agg.c:410 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "aggregatfunktioner tillÃ¥ts inte i fönster-RANGE" + +#: parser/parse_agg.c:412 +msgid "grouping operations are not allowed in window RANGE" +msgstr "grupperingsoperationer tillÃ¥ts inte i fönster-RANGE" + +#: parser/parse_agg.c:417 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "aggregatfunktioner tillÃ¥ts inte i fönster-RADER" + +#: parser/parse_agg.c:419 +msgid "grouping operations are not allowed in window ROWS" +msgstr "grupperingsfunktioner tillÃ¥ts inte i fönster-RADER" + +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "aggregatfunktioner tillÃ¥ts inte i fönster-GROUPS" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "grupperingsfunktioner tillÃ¥ts inte i fönster-GROUPS" + +#: parser/parse_agg.c:460 +msgid "aggregate functions are not allowed in check constraints" +msgstr "aggregatfunktioner tillÃ¥ts inte i check-villkor" + +#: parser/parse_agg.c:462 +msgid "grouping operations are not allowed in check constraints" +msgstr "gruppoperationer tillÃ¥ts inte i check-villkor" + +#: parser/parse_agg.c:469 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:471 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "grupperingsoperationer tillÃ¥ts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:476 +msgid "aggregate functions are not allowed in index expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i indexuttryck" + +#: parser/parse_agg.c:478 +msgid "grouping operations are not allowed in index expressions" +msgstr "gruppoperationer tillÃ¥ts inte i indexuttryck" + +#: parser/parse_agg.c:483 +msgid "aggregate functions are not allowed in index predicates" +msgstr "aggregatfunktionsanrop tillÃ¥ts inte i indexpredikat" + +#: parser/parse_agg.c:485 +msgid "grouping operations are not allowed in index predicates" +msgstr "gruppoperationer tillÃ¥ts inte i indexpredikat" + +#: parser/parse_agg.c:490 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i transform-uttryck" + +#: parser/parse_agg.c:492 +msgid "grouping operations are not allowed in transform expressions" +msgstr "gruppoperationer tillÃ¥ts inte i transforme-uttryck" + +#: parser/parse_agg.c:497 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "aggregatfunktioner tillÃ¥ts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:499 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "gruppoperationer tillÃ¥ts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:504 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "aggregatfunktioner tillÃ¥ts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:506 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "gruppoperationer tillÃ¥ts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:511 +msgid "aggregate functions are not allowed in partition bound" +msgstr "aggregatfunktioner tillÃ¥ts inte i partitionsgräns" + +#: parser/parse_agg.c:513 +msgid "grouping operations are not allowed in partition bound" +msgstr "gruppoperationer tillÃ¥ts inte i partitionsgräns" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "gruppoperationer tillÃ¥ts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:526 +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "aggregatfunktioner tillÃ¥ts inte i kolumngenereringsuttryck" + +#: parser/parse_agg.c:528 +msgid "grouping operations are not allowed in column generation expressions" +msgstr "gruppoperationer tillÃ¥ts inte i kolumngenereringsuttryck" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "aggregatfunktioner tillÃ¥ts inte i CALL-argument" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "gruppoperationer tillÃ¥ts inte i CALL-argument" + +#: parser/parse_agg.c:542 +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "aggregatfunktioner tillÃ¥ts inte i COPY FROM WHERE-villkor" + +#: parser/parse_agg.c:544 +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "gruppoperationer tillÃ¥ts inte i COPY FROM WHERE-villkor" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:567 parser/parse_clause.c:1778 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "aggregatfunktioner tillÃ¥ts inte i %s" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:570 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "gruppoperationer tillÃ¥ts inte i %s" + +#: parser/parse_agg.c:678 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "yttre aggregat kan inte innehÃ¥lla inre variabel i sitt direkta argument" + +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "aggregatfunktionsanrop kan inte innehÃ¥lla mängdreturnerande funktionsanrop" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1839 parser/parse_expr.c:2328 +#: parser/parse_func.c:876 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "Du kanske kan flytta den mängdreturnerande funktionen in i en LATERAL FROM-konstruktion." + +#: parser/parse_agg.c:763 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "aggregatfunktionsanrop kan inte innehÃ¥lla fönsterfunktionanrop" + +#: parser/parse_agg.c:842 +msgid "window functions are not allowed in JOIN conditions" +msgstr "fönsterfunktioner tillÃ¥ts inte i JOIN-villkor" + +#: parser/parse_agg.c:849 +msgid "window functions are not allowed in functions in FROM" +msgstr "fönsterfunktioner tillÃ¥ts inte i funktioner i FROM" + +#: parser/parse_agg.c:855 +msgid "window functions are not allowed in policy expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i policy-uttryck" + +#: parser/parse_agg.c:868 +msgid "window functions are not allowed in window definitions" +msgstr "fönsterfunktioner tillÃ¥ts inte i fönsterdefinitioner" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in check constraints" +msgstr "fönsterfunktioner tillÃ¥ts inte i check-villkor" + +#: parser/parse_agg.c:904 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i DEFAULT-uttryck" + +#: parser/parse_agg.c:907 +msgid "window functions are not allowed in index expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i indexuttryck" + +#: parser/parse_agg.c:910 +msgid "window functions are not allowed in index predicates" +msgstr "fönsterfunktioner tillÃ¥ts inte i indexpredikat" + +#: parser/parse_agg.c:913 +msgid "window functions are not allowed in transform expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i transform-uttrycket" + +#: parser/parse_agg.c:916 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "fönsterfunktioner tillÃ¥ts inte i EXECUTE-parametrar" + +#: parser/parse_agg.c:919 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "fönsterfunktioner tillÃ¥ts inte i WHEN-utlösarvillkor" + +#: parser/parse_agg.c:922 +msgid "window functions are not allowed in partition bound" +msgstr "fönsterfunktioner tillÃ¥ts inte i partitiongräns" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i partitionsnyckeluttryck" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "fönsterfunktioner tillÃ¥ts inte i CALL-argument" + +#: parser/parse_agg.c:931 +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "fönsterfunktioner tillÃ¥ts inte i COPY FROM WHERE-villkor" + +#: parser/parse_agg.c:934 +msgid "window functions are not allowed in column generation expressions" +msgstr "fönsterfunktioner tillÃ¥ts inte i kolumngenereringsuttryck" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:954 parser/parse_clause.c:1787 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "fönsterfunktioner tillÃ¥ts inte i %s" + +#: parser/parse_agg.c:988 parser/parse_clause.c:2623 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "fönster \"%s\" finns inte" + +#: parser/parse_agg.c:1072 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "för mÃ¥nga grupperingsmängder (maximalt 4096)" + +#: parser/parse_agg.c:1212 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "aggregatfunktioner tillÃ¥ts inte i en rekursiv frÃ¥gas rekursiva term" + +#: parser/parse_agg.c:1405 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "kolumn \"%s.%s\" mÃ¥ste stÃ¥ med i GROUP BY-klausulen eller användas i en aggregatfunktion" + +#: parser/parse_agg.c:1408 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Direkta argument till en sorterad-mängd-aggregat fÃ¥r bara använda grupperade kolumner." + +#: parser/parse_agg.c:1413 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "underfrÃ¥ga använder ogrupperad kolumn \"%s.%s\" frÃ¥n yttre frÃ¥ga" + +#: parser/parse_agg.c:1577 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "argument till GROUPING mÃ¥ste vare grupputtryck pÃ¥ den tillhörande frÃ¥genivÃ¥n" + +#: parser/parse_clause.c:198 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "relationen \"%s\" kan inte vara mÃ¥let för en modifierande sats" + +#: parser/parse_clause.c:575 parser/parse_clause.c:603 parser/parse_func.c:2434 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "mängdreturnerande funktioner mÃ¥ste vara pÃ¥ toppnivÃ¥ i FROM" + +#: parser/parse_clause.c:615 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "multipla kolumndefinitionslistor tillÃ¥ts inte i samma funktion" + +#: parser/parse_clause.c:648 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "ROWS FROM() med multipla funktioner kan inte ha en kolumndefinitionslista" + +#: parser/parse_clause.c:649 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "Lägg till en separat kolumndefinitionslista för varje funktion inne i ROWS FROM()." + +#: parser/parse_clause.c:655 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "UNNEST() med multipla argument kan inte ha en kolumndefinitionslista" + +#: parser/parse_clause.c:656 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "Använd separata UNNEST()-anrop inne i ROWS FROM() och koppla en kolumndefinitionslista till varje." + +#: parser/parse_clause.c:663 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY kan inte användas tillsammans med en kolumndefinitionslista" + +#: parser/parse_clause.c:664 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Placera kolumndefinitionslistan inne i ROWS FROM()." + +#: parser/parse_clause.c:767 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "bara en FOR ORDINALITY-kolumn tillÃ¥ts" + +#: parser/parse_clause.c:828 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "kolumnnamn \"%s\" är inte unikt" + +#: parser/parse_clause.c:870 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "namespace-namn \"%s\" är inte unikt" + +#: parser/parse_clause.c:880 +#, c-format +msgid "only one default namespace is allowed" +msgstr "bara ett standard-namespace tillÃ¥ts" + +#: parser/parse_clause.c:942 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "tabellsamplingsmetod \"%s\" existerar inte" + +#: parser/parse_clause.c:964 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "tabellsamplingsmetod %s kräver %d argument, inte %d" +msgstr[1] "tabellsamplingsmetod %s kräver %d argument, inte %d" + +#: parser/parse_clause.c:998 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "tabellsamplingsmetod %s stöder inte REPEATABLE" + +#: parser/parse_clause.c:1168 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE-klausul kan bara appliceras pÃ¥ tabeller och materialiserade vyer" + +#: parser/parse_clause.c:1338 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "kolumnnamn \"%s\" angivet mer än en gÃ¥ng i USING-klausul" + +#: parser/parse_clause.c:1353 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "gemensamt kolumnnamn \"%s\" finns mer än en gÃ¥ng i vänstra tabellen" + +#: parser/parse_clause.c:1362 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "kolumn \"%s\" angiven i USING-klausul finns inte i den vänstra tabellen" + +#: parser/parse_clause.c:1376 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "gemensamt kolumnnamn \"%s\" finns mer än en gÃ¥ng i högra tabellen" + +#: parser/parse_clause.c:1385 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "kolumn \"%s\" angiven i USING-klausul finns inte i den högra tabellen" + +#: parser/parse_clause.c:1439 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "kolumnaliaslista för \"%s\" har för mÃ¥nga element" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1748 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "argumentet till %s fÃ¥r inte innehÃ¥lla variabler" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1913 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\" är tvetydig" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1942 +#, c-format +msgid "non-integer constant in %s" +msgstr "ej heltalskonstant i %s" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1964 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s-position %d finns inte i select-listan" + +#: parser/parse_clause.c:2405 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE är begränsad till 12 element" + +#: parser/parse_clause.c:2611 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "fönster \"%s\" är redan definierad" + +#: parser/parse_clause.c:2672 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "kan inte övertrumfa PARTITION BY-klausul för fönster \"%s\"" + +#: parser/parse_clause.c:2684 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "kan inte övertrumfa ORDER BY-klausul för fönster \"%s\"" + +#: parser/parse_clause.c:2714 parser/parse_clause.c:2720 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "kan inte kopiera fönster \"%s\" dÃ¥ det har en fönsterramklausul" + +#: parser/parse_clause.c:2722 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Ta bort parenteserna i denna OVER-klausul." + +#: parser/parse_clause.c:2742 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "RANGE med offset PRECEDING/FOLLOWING kräver exakt en ORDER BY-kolumn" + +#: parser/parse_clause.c:2765 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS-läge kräver en ORDER BY-klausul" + +#: parser/parse_clause.c:2835 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "i ett aggregat med DISTINCT sÃ¥ mÃ¥ste ORDER BY-uttryck finnas i argumentlistan" + +#: parser/parse_clause.c:2836 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "i SELECT DISTINCT sÃ¥ mÃ¥ste ORDER BY-uttryck finnas i select-listan" + +#: parser/parse_clause.c:2868 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "ett aggregat med DISTINCT mÃ¥ste ha minst ett argument" + +#: parser/parse_clause.c:2869 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT mÃ¥ste ha minst en kolumn" + +#: parser/parse_clause.c:2935 parser/parse_clause.c:2967 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "SELECT DISTINCT ON-uttrycken mÃ¥ste matcha de initiala ORDER BY-uttrycken" + +#: parser/parse_clause.c:3045 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ASC/DESC tillÃ¥ts inte i ON CONFLICT-klausul" + +#: parser/parse_clause.c:3051 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "NULLS FIRST/LAST tillÃ¥ts inte i ON CONFLICT-klausul" + +#: parser/parse_clause.c:3130 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE kräver inferensangivelse eller villkorsnamn" + +#: parser/parse_clause.c:3131 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Till exempel, ON CONFLICT (kolumnnamn)." + +#: parser/parse_clause.c:3142 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT stöds inte för systemkatalogtabeller" + +#: parser/parse_clause.c:3150 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT stöds inte pÃ¥ tabell \"%s\" som används som katalogtabell" + +#: parser/parse_clause.c:3293 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "operator %s är inte en giltig sorteringsoperator" + +#: parser/parse_clause.c:3295 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Sorteringsoperationer mÃ¥ste vara \"<\"- eller \">\"-medlemmar i btree-operatorfamiljer." + +#: parser/parse_clause.c:3606 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING stöds inte för kolumntyp %s" + +#: parser/parse_clause.c:3612 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING stöd inte av kolumntyp %s och offset-typ %s" + +#: parser/parse_clause.c:3615 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "Typomvandla offset-värdet till lämplig typ." + +#: parser/parse_clause.c:3620 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "RANGE med offset PRECEDING/FOLLOWING har multipla tolkingar för kolumntyp %s och offset-typ %s" + +#: parser/parse_clause.c:3623 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "Typomvandla offset-värdet till exakt den önskade typen." + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2235 parser/parse_expr.c:2823 parser/parse_target.c:962 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "kan inte omvandla typ %s till %s" + +#: parser/parse_coerce.c:1063 +#, c-format +msgid "Input has too few columns." +msgstr "Indata har för fÃ¥ kolumner" + +#: parser/parse_coerce.c:1081 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "Kan inte typomvandla typ %s till %s i kolumn %d." + +#: parser/parse_coerce.c:1096 +#, c-format +msgid "Input has too many columns." +msgstr "Indata har för mÃ¥nga kolumner" + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "argumentet till %s mÃ¥ste vara av typ %s, inte av typ %s" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 +#, c-format +msgid "argument of %s must not return a set" +msgstr "argumentet till %s fÃ¥r inte returnera en mängd" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1351 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%s typer %s och %s matchar inte" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1418 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s kan inte konvertera typ %s till %s" + +#: parser/parse_coerce.c:1720 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "argument deklarerade som \"anyelement\" är inte alla likadana" + +#: parser/parse_coerce.c:1740 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "argument deklarerade \"anyarray\" är inte alla likadana" + +#: parser/parse_coerce.c:1760 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "argument deklarerade \"anyrange\" är inte alla likadana" + +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "argumentet deklarerad %s är inte en array utan typ %s" + +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "argument deklarerad %s är inte konsistent med argument deklarerad %s" + +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "argumentet deklarerad %s är inte en intervalltyp utan typ %s" + +#: parser/parse_coerce.c:1865 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "kunde inte bestämma en polymorf typ dÃ¥ indata har typ %s" + +#: parser/parse_coerce.c:1876 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "typen som matchar anynonarray är en array-typ: %s" + +#: parser/parse_coerce.c:1886 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "typen som matchar anyenum är inte en enum-typ: %s" + +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 +#, c-format +msgid "could not find range type for data type %s" +msgstr "kunde inte hitta intervalltyp för datatyp %s" + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 +#: parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "jämförelser (collation) matchar inte mellan implicita jämförelser \"%s\" och \"%s\"" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 +#: parser/parse_collate.c:984 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "Du kan välja jämförelse genom att applicera en COLLATE-klausul till ett eller bÃ¥da uttrycken." + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "jämförelser (collation) matchar inte mellan explicita jämförelser \"%s\" och \"%s\"" + +#: parser/parse_cte.c:42 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas inom dess ickerekursiva term" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas i en subfrÃ¥ga" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas i en outer join" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas i en INTERSECT" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas i en EXCEPT" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "WITH-frÃ¥genamn \"%s\" angivet mer än en gÃ¥ng" + +#: parser/parse_cte.c:264 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "WITH-klausul som innehÃ¥ller en datamodifierande sats mÃ¥ste vara pÃ¥ toppnivÃ¥" + +#: parser/parse_cte.c:313 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "rekursiv frÃ¥ga \"%s\" kolumn %d har typ %s i den ickerekursiva termen med typ %s totalt sett" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Typomvandla utdatan för den ickerekursiva termen till korrekt typ." + +#: parser/parse_cte.c:324 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "rekursiv frÃ¥ga \"%s\" kolumn %d har jämförelse (collation) \"%s\" i en icke-rekursiv term men jämförelse \"%s\" totalt sett" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Använd en COLLATE-klausul för att sätta jämförelse för den icke-rekursiva termen." + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "WITH-frÃ¥ga \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "ömsesidig rekursion mellan WITH-poster är inte implementerat" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "rekursiv frÃ¥ga \"%s\" fÃ¥r inte innehÃ¥lla datamodifierande satser" + +#: parser/parse_cte.c:658 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "rekursiv frÃ¥ga \"%s\" är inte pÃ¥ formen icke-rekursiv-term UNION [ALL] rekursiv-term" + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "ORDER BY i en rekursiv frÃ¥ga är inte implementerat" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "OFFSET i en rekursiv frÃ¥ga är inte implementerat" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "LIMIT i en rekursiv frÃ¥ga är inte implementerat" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "FOR UPDATE/SHARE i en rekursiv frÃ¥ga är inte implementerat" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "rekursiv referens till frÃ¥ga \"%s\" fÃ¥r inte finnas med mer än en gÃ¥ng" + +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "DEFAULT tillÃ¥ts inte i detta kontext" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3352 +#: parser/parse_relation.c:3372 +#, c-format +msgid "column %s.%s does not exist" +msgstr "kolumnen %s.%s finns inte" + +#: parser/parse_expr.c:414 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "kolumn \"%s\" fanns inte i datatypen %s" + +#: parser/parse_expr.c:420 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "kunde inte hitta kolumnen \"%s\" i record-datatyp" + +#: parser/parse_expr.c:426 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr "kolumnotation .%s använd pÃ¥ typ %s som inte är en sammanslagen typ" + +#: parser/parse_expr.c:457 parser/parse_target.c:729 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "radexpansion via \"*\" stöds inte här" + +#: parser/parse_expr.c:578 +msgid "cannot use column reference in DEFAULT expression" +msgstr "kan inte använda kolumnreferenser i DEFAULT-uttryck" + +#: parser/parse_expr.c:581 +msgid "cannot use column reference in partition bound expression" +msgstr "kan inte använda kolumnreferenser i partitionsgränsuttryck" + +#: parser/parse_expr.c:844 parser/parse_relation.c:692 +#: parser/parse_relation.c:803 parser/parse_target.c:1200 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "kolumnreferens \"%s\" är tvetydig" + +#: parser/parse_expr.c:900 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "det finns ingen parameter $%d" + +#: parser/parse_expr.c:1143 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "NULLIF kräver att =-operatorn returnerar boolean" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1149 parser/parse_expr.c:3139 +#, c-format +msgid "%s must not return a set" +msgstr "%s fÃ¥r inte returnera en mängd" + +#: parser/parse_expr.c:1597 parser/parse_expr.c:1629 +#, c-format +msgid "number of columns does not match number of values" +msgstr "antalet kolumner matchar inte antalet värden" + +#: parser/parse_expr.c:1643 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "källa till en multiple-kolumn-UPDATE-post mÃ¥ste vara en sub-SELECT eller ROW()-uttryck" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1837 parser/parse_expr.c:2326 parser/parse_func.c:2550 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i %s" + +#: parser/parse_expr.c:1898 +msgid "cannot use subquery in check constraint" +msgstr "kan inte använda subfrÃ¥ga i check-villkor" + +#: parser/parse_expr.c:1902 +msgid "cannot use subquery in DEFAULT expression" +msgstr "kan inte använda underfrÃ¥ga i DEFAULT-uttryck" + +#: parser/parse_expr.c:1905 +msgid "cannot use subquery in index expression" +msgstr "kan inte använda subfrÃ¥ga i indexuttryck" + +#: parser/parse_expr.c:1908 +msgid "cannot use subquery in index predicate" +msgstr "kan inte använda subfrÃ¥ga i indexpredikat" + +#: parser/parse_expr.c:1911 +msgid "cannot use subquery in transform expression" +msgstr "kan inte använda underfrÃ¥ga i transformeringsuttrycket" + +#: parser/parse_expr.c:1914 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "kan inte använda subfrÃ¥ga i EXECUTE-parameter" + +#: parser/parse_expr.c:1917 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "kan inte använda subfrÃ¥ga i utlösares WHEN-villkor" + +#: parser/parse_expr.c:1920 +msgid "cannot use subquery in partition bound" +msgstr "kan inte använda underfrÃ¥ga i partitionsgräns" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in partition key expression" +msgstr "kan inte använda underfrÃ¥ga i partitionsnyckeluttryck" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in CALL argument" +msgstr "kan inte använda subfrÃ¥ga i CALL-argument" + +#: parser/parse_expr.c:1929 +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "kan inte använda subfrÃ¥ga i COPY FROM WHERE-villkor" + +#: parser/parse_expr.c:1932 +msgid "cannot use subquery in column generation expression" +msgstr "kan inte använda subfrÃ¥ga i kolumngenereringsuttryck" + +#: parser/parse_expr.c:1985 +#, c-format +msgid "subquery must return only one column" +msgstr "underfrÃ¥ga kan bara returnera en kolumn" + +#: parser/parse_expr.c:2069 +#, c-format +msgid "subquery has too many columns" +msgstr "underfrÃ¥ga har för mÃ¥nga kolumner" + +#: parser/parse_expr.c:2074 +#, c-format +msgid "subquery has too few columns" +msgstr "underfrÃ¥ga har för fÃ¥ kolumner" + +#: parser/parse_expr.c:2175 +#, c-format +msgid "cannot determine type of empty array" +msgstr "kan inte bestämma typen av en tom array" + +#: parser/parse_expr.c:2176 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "Typomvandla explicit till den önskade typen, till exempel ARRAY[]::integer[]." + +#: parser/parse_expr.c:2190 +#, c-format +msgid "could not find element type for data type %s" +msgstr "kunde inte hitta elementtyp för datatyp %s" + +#: parser/parse_expr.c:2477 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "onamnat XML-attributvärde mÃ¥ste vara en kolumnreferens" + +#: parser/parse_expr.c:2478 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "onamnat XML-elementvärde mÃ¥ste vara en kolumnreferens" + +#: parser/parse_expr.c:2493 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "XML-attributnamn \"%s\" finns med mer än en gÃ¥ng" + +#: parser/parse_expr.c:2600 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "kan inte typomvandla XMLSERIALIZE-resultat till %s" + +#: parser/parse_expr.c:2896 parser/parse_expr.c:3092 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "olika antal element i raduttryck" + +#: parser/parse_expr.c:2906 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "kan inte jämföra rader med längden noll" + +#: parser/parse_expr.c:2931 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "operator för radjämförelse mÃ¥ste resultera i typen boolean, inte %s" + +#: parser/parse_expr.c:2938 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "radjämförelseoperator fÃ¥r inte returnera en mängd" + +#: parser/parse_expr.c:2997 parser/parse_expr.c:3038 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "kunde inte lista ut tolkning av radjämförelseoperator %s" + +#: parser/parse_expr.c:2999 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Radjämförelseoperatorer mÃ¥ste vara associerade med btreee-operatorfamiljer." + +#: parser/parse_expr.c:3040 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Det finns flera lika sannolika kandidater." + +#: parser/parse_expr.c:3133 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "IS DISTINCT FROM kräver att operatorn = ger tillbaka en boolean" + +#: parser/parse_expr.c:3452 parser/parse_expr.c:3470 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "operator-precedence-ändring: %s har nu lägre precedence än %s" + +#: parser/parse_func.c:195 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "argumentnamn \"%s\" angivet mer än en gÃ¥ng" + +#: parser/parse_func.c:206 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "positionella argument kan inte komma efter namngivna argument" + +#: parser/parse_func.c:288 parser/parse_func.c:2253 +#, c-format +msgid "%s is not a procedure" +msgstr "%s är inte en procedur" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a function, use SELECT." +msgstr "För att anropa en funktion, använd SELECT." + +#: parser/parse_func.c:298 +#, c-format +msgid "%s is a procedure" +msgstr "\"%s\" är en procedur" + +#: parser/parse_func.c:302 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "För att anropa en procedur, använd CALL" + +#: parser/parse_func.c:316 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) angivet, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:323 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:329 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:335 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:341 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER angiven, men %s är inte en aggregatfunktion" + +#: parser/parse_func.c:347 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER angiven, men %s är inte en fönsterfunktion eller en aggregatfunktion" + +#: parser/parse_func.c:385 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "WITHIN GROUP krävs för sorterad-mängd-aggregat %s" + +#: parser/parse_func.c:391 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "DISTINCT stöds inte för sorterad-mängd-aggregat %s" + +#: parser/parse_func.c:422 parser/parse_func.c:451 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "Det finns ett sorterad-mängd-aggregat %s, men det kräver %d direkta argument, inte %d." + +#: parser/parse_func.c:476 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "För att använda hypotetiskt mängdaggregat %s sÃ¥ mÃ¥ste antalet direkta hypotetiska argument (här %d) matcha antalet sorteringskolumner (här %d)." + +#: parser/parse_func.c:490 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "Det finns ett sorterad-mängd-aggregat %s, men det kräver minst %d direkta argument." + +#: parser/parse_func.c:509 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s är inte en sorterad-mängd-aggregat, sÃ¥ den kan inte ha WITHIN GROUP" + +#: parser/parse_func.c:522 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "fönsterfunktion %s kräver en OVER-klausul" + +#: parser/parse_func.c:529 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "fönsterfunktion %s kan inte ha en WITHIN GROUP" + +#: parser/parse_func.c:558 +#, c-format +msgid "procedure %s is not unique" +msgstr "proceduren \"%s\" är inte unik" + +#: parser/parse_func.c:561 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatprocedur. Du behöver troligen lägga till en explicit typomvandling." + +#: parser/parse_func.c:567 +#, c-format +msgid "function %s is not unique" +msgstr "funktionen %s är inte unik" + +#: parser/parse_func.c:570 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatfunktion: Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:609 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Ingen aggregatfunktion matchar det givna namnet och argumenttyperna. Kanske har du placerat ORDER BY pÃ¥ fel plats; ORDER BY mÃ¥ste komma efter alla vanliga argument till aggregatet." + +#: parser/parse_func.c:617 parser/parse_func.c:2296 +#, c-format +msgid "procedure %s does not exist" +msgstr "proceduren \"%s\" finns inte" + +#: parser/parse_func.c:620 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen procedur matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:629 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen funktion matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_func.c:731 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC-argument mÃ¥ste vara en array" + +#: parser/parse_func.c:783 parser/parse_func.c:847 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) mÃ¥ste användas för att anropa en parameterlös aggregatfunktion" + +#: parser/parse_func.c:790 +#, c-format +msgid "aggregates cannot return sets" +msgstr "aggregat kan inte returnera mängder" + +#: parser/parse_func.c:805 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "aggregat kan inte använda namngivna argument" + +#: parser/parse_func.c:837 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "DISTINCT är inte implementerad för fönsterfunktioner" + +#: parser/parse_func.c:857 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "aggregat-ORDER BY är inte implementerat för fönsterfunktioner" + +#: parser/parse_func.c:866 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "FILTER är inte implementerat för icke-aggregat-fönsterfunktioner" + +#: parser/parse_func.c:875 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "fönsterfunktioner kan inte innehÃ¥lla funtionsanrop till funktioner som returnerar mängder" + +#: parser/parse_func.c:883 +#, c-format +msgid "window functions cannot return sets" +msgstr "fönsterfunktioner kan inte returnera mängder" + +#: parser/parse_func.c:2134 parser/parse_func.c:2325 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "kunde inte hitta funktion med namn \"%s\"" + +#: parser/parse_func.c:2148 parser/parse_func.c:2343 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "funktionsnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2150 parser/parse_func.c:2345 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "Ange argumentlistan för att välja funktionen entydigt." + +#: parser/parse_func.c:2194 +#, c-format +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "procedurer kan inte ha mer än %d argument" +msgstr[1] "procedurer kan inte ha mer än %d argument" + +#: parser/parse_func.c:2243 +#, c-format +msgid "%s is not a function" +msgstr "%s är inte en funktion" + +#: parser/parse_func.c:2263 +#, c-format +msgid "function %s is not an aggregate" +msgstr "funktionen %s är inte en aggregatfunktion" + +#: parser/parse_func.c:2291 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "kunde inte hitta en procedur med namn \"%s\"" + +#: parser/parse_func.c:2305 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "kunde inte hitta ett aggregat med namn \"%s\"" + +#: parser/parse_func.c:2310 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "aggregatfunktion %s(*) existerar inte" + +#: parser/parse_func.c:2315 +#, c-format +msgid "aggregate %s does not exist" +msgstr "aggregatfunktion %s existerar inte" + +#: parser/parse_func.c:2350 +#, c-format +msgid "procedure name \"%s\" is not unique" +msgstr "procedurnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2352 +#, c-format +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "Ange argumentlistan för att välja proceduren entydigt." + +#: parser/parse_func.c:2357 +#, c-format +msgid "aggregate name \"%s\" is not unique" +msgstr "aggregatnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2359 +#, c-format +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "Ange argumentlistan för att välja aggregatet entydigt." + +#: parser/parse_func.c:2364 +#, c-format +msgid "routine name \"%s\" is not unique" +msgstr "rutinnamn \"%s\" är inte unikt" + +#: parser/parse_func.c:2366 +#, c-format +msgid "Specify the argument list to select the routine unambiguously." +msgstr "Ange argumentlistan för att välja rutinen entydigt." + +#: parser/parse_func.c:2421 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i JOIN-villkor" + +#: parser/parse_func.c:2442 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i policy-uttryck" + +#: parser/parse_func.c:2458 +msgid "set-returning functions are not allowed in window definitions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i fönsterdefinitioner" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in check constraints" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i check-villkor" + +#: parser/parse_func.c:2500 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i DEFAULT-uttryck" + +#: parser/parse_func.c:2503 +msgid "set-returning functions are not allowed in index expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i indexuttryck" + +#: parser/parse_func.c:2506 +msgid "set-returning functions are not allowed in index predicates" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i indexpredukat" + +#: parser/parse_func.c:2509 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i transformuttryck" + +#: parser/parse_func.c:2512 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i EXECUTE-parametrar" + +#: parser/parse_func.c:2515 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i WHEN-utlösarvillkor" + +#: parser/parse_func.c:2518 +msgid "set-returning functions are not allowed in partition bound" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i partitionsgräns" + +#: parser/parse_func.c:2521 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i partitionsnyckeluttryck" + +#: parser/parse_func.c:2524 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i CALL-argument" + +#: parser/parse_func.c:2527 +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i COPY FROM WHERE-villkor" + +#: parser/parse_func.c:2530 +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "mängdreturnerande funktioner tillÃ¥ts inte i kolumngenereringsuttryck" + +#: parser/parse_node.c:87 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "mÃ¥llista kan ha som mest %d poster" + +#: parser/parse_node.c:257 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "kan inte indexera typ %s dÃ¥ det inte är en array" + +#: parser/parse_node.c:363 parser/parse_node.c:400 +#, c-format +msgid "array subscript must have type integer" +msgstr "arrayindex mÃ¥ste ha typen integer" + +#: parser/parse_node.c:431 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "array-tilldelning kräver typ %s men uttrycket har typ %s" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 +#, c-format +msgid "operator does not exist: %s" +msgstr "operator existerar inte: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Använd en explicit ordningsoperator eller ändra frÃ¥gan." + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "operator kräver run-time-typomvandling: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "operatorn är inte unik: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "Kunde inte välja en bästa kandidatoperator. Du behöver troligen lägga till en explicit typomvandling." + +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Ingen operator matchar det angivna namnet och argumenttyp. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Ingen operator matchar det angivna namnet och argumenttyperna. Du kan behöva lägga till explicita typomvandlingar." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "operator är bara en skaltyp: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) kräver en array pÃ¥ höger sida" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) kräver att operatorn returnerar en boolean" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) kräver att operatorn inte returnerar en mängd" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "inkonsistenta typer härledda för parameter $%d" + +#: parser/parse_relation.c:179 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "tabellreferens \"%s\" är tvetydig" + +#: parser/parse_relation.c:223 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "tabellreferens %u är tvetydig" + +#: parser/parse_relation.c:422 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "tabellnamn \"%s\" angivet mer än en gÃ¥ng" + +#: parser/parse_relation.c:449 parser/parse_relation.c:3292 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "ogiltig referens till FROM-klausulpost för tabell \"%s\"" + +#: parser/parse_relation.c:452 parser/parse_relation.c:3297 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en post för tabell \"%s\" men den kan inte refereras till frÃ¥n denna del av frÃ¥gan." + +#: parser/parse_relation.c:454 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "JOIN-typen mÃ¥ste vara INNER eller LEFT för att fungera med LATERAL." + +#: parser/parse_relation.c:730 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "systemkolumn \"%s\" som refereras till i check-villkor är ogiltigt" + +#: parser/parse_relation.c:741 +#, c-format +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "kan inte använda systemkolumn \"%s\" i kolumngenereringsuttryck" + +#: parser/parse_relation.c:1100 parser/parse_relation.c:1404 +#: parser/parse_relation.c:1985 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "tabell \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_relation.c:1187 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en WITH-post med namn \"%s\" men den kan inte refereras till frÃ¥n denna del av frÃ¥gan." + +#: parser/parse_relation.c:1189 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "Använd WITH RECURSIVE eller ändra ordning pÃ¥ WITH-posterna för att ta bort framÃ¥t-referenser." + +#: parser/parse_relation.c:1525 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "en kolumndefinitionslista tillÃ¥ts bara för funktioner som returnerar \"record\"" + +#: parser/parse_relation.c:1534 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "en kolumndefinitionslista krävs för funktioner som returnerar \"record\"" + +#: parser/parse_relation.c:1620 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "funktion \"%s\" i FROM har en icke stödd returtyp %s" + +#: parser/parse_relation.c:1811 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "VALUES-lista \"%s\" har %d kolumner tillgängliga men %d kolumner angivna" + +#: parser/parse_relation.c:1867 +#, c-format +msgid "joins can have at most %d columns" +msgstr "joins kan ha som mest %d kolumner" + +#: parser/parse_relation.c:1958 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "WITH-frÃ¥ga \"%s\" har ingen RETURNING-klausul" + +#: parser/parse_relation.c:2899 parser/parse_relation.c:2937 +#: parser/parse_relation.c:2946 parser/parse_relation.c:3072 +#: parser/parse_relation.c:3082 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "kolumn %d i relation \"%s\" finns inte" + +#: parser/parse_relation.c:3295 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Kanske tänkte du referera till tabellaliaset \"%s\"." + +#: parser/parse_relation.c:3303 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "saknar FROM-klausulpost för tabell \"%s\"" + +#: parser/parse_relation.c:3355 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Kanske tänkte du referera trill kolumnen \"%s.%s\"." + +#: parser/parse_relation.c:3357 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "Det finns en kolumn med namn \"%s\" i tabell \"%s\" men den kan inte refereras till frÃ¥n denna del av frÃ¥gan." + +#: parser/parse_relation.c:3374 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Kanske tänkte du referera till kolumnen \"%s.%s\" eller kolumnen \"%s.%s\"." + +#: parser/parse_target.c:484 parser/parse_target.c:791 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "kan inte skriva till systemkolumn \"%s\"" + +#: parser/parse_target.c:512 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "kan inte sätta ett array-element till DEFAULT" + +#: parser/parse_target.c:517 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "kan inte sätta ett underfält till DEFAULT" + +#: parser/parse_target.c:586 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "kolumn \"%s\" har typ %s men uttrycket är av typ %s" + +#: parser/parse_target.c:775 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "kan inte tilldela till fält \"%s\" i kolumn \"%s\" dÃ¥ dess typ %s inte är en composit-typ" + +#: parser/parse_target.c:784 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "kan inte tilldela till fält \"%s\" i kolumn \"%s\" dÃ¥ det inte finns nÃ¥gon sÃ¥dan kolumn i datatypen %s" + +#: parser/parse_target.c:861 +#, c-format +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "array-tilldelning till \"%s\" kräver typ %s men uttrycket har typ %s" + +#: parser/parse_target.c:871 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "underfält \"%s\" har typ %s men uttrycket har typ %s" + +#: parser/parse_target.c:1290 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT * utan tabeller angivna är inte giltigt" + +#: parser/parse_type.c:83 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "dÃ¥lig %%TYPE-referens (för fÃ¥r punktade namn): %s" + +#: parser/parse_type.c:105 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "dÃ¥lig %%TYPE-referens (för mÃ¥nga punktade namn): %s" + +#: parser/parse_type.c:140 +#, c-format +msgid "type reference %s converted to %s" +msgstr "typreferens %s konverterad till %s" + +#: parser/parse_type.c:261 parser/parse_type.c:840 utils/cache/typcache.c:374 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "typ \"%s\" är bara ett skal" + +#: parser/parse_type.c:346 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "typmodifierare tillÃ¥ts inte för typ \"%s\"" + +#: parser/parse_type.c:388 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "typmodifierare mÃ¥ste vare enkla konstanter eller identifierare" + +#: parser/parse_type.c:704 parser/parse_type.c:803 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "ogiltigt typnamn \"%s\"" + +#: parser/parse_utilcmd.c:263 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "kan inte skapa partitionerad tabell som barnarv" + +#: parser/parse_utilcmd.c:426 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s kommer skapa en implicit sekvens \"%s\" för \"serial\"-kolumnen \"%s.%s\"" + +#: parser/parse_utilcmd.c:550 +#, c-format +msgid "array of serial is not implemented" +msgstr "array med serial är inte implementerat" + +#: parser/parse_utilcmd.c:627 parser/parse_utilcmd.c:639 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "motstridiga NULL/NOT NULL-villkor för kolumnen \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:651 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "multipla default-värden angivna för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:668 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "identitetskolumner stöds inte pÃ¥ typade tabeller" + +#: parser/parse_utilcmd.c:672 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "identitetskolumner stöds inte för partitioner" + +#: parser/parse_utilcmd.c:681 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "multipla identitetspecifikationer för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:700 +#, c-format +msgid "generated columns are not supported on typed tables" +msgstr "genererade kolumner stöds inte pÃ¥ typade tabeller" + +#: parser/parse_utilcmd.c:704 +#, c-format +msgid "generated columns are not supported on partitions" +msgstr "genererade kolumner stöds inte för partitioner" + +#: parser/parse_utilcmd.c:709 +#, c-format +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "multipla genereringsklausuler angivna för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:727 parser/parse_utilcmd.c:842 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "primärnyckelvillkor stöds inte pÃ¥ främmande tabeller" + +#: parser/parse_utilcmd.c:736 parser/parse_utilcmd.c:852 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "unika villkor stöds inte pÃ¥ främmande tabeller" + +#: parser/parse_utilcmd.c:781 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "bÃ¥de default och identity angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:789 +#, c-format +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "bÃ¥de default och genereringsuttryck angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:797 +#, c-format +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "bÃ¥de identity och genereringsuttryck angiven för kolumn \"%s\" i tabell \"%s\"" + +#: parser/parse_utilcmd.c:862 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "uteslutningsvillkor stöds inte pÃ¥ främmande tabeller" + +#: parser/parse_utilcmd.c:868 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "uteslutningsvillkor stöds inte för partitionerade tabeller" + +#: parser/parse_utilcmd.c:932 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "LIKE stöds inte för att skapa främmande tabeller" + +#: parser/parse_utilcmd.c:1064 +#, c-format +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "Genereringsuttryck för kolumn \"%s\" innehÃ¥ller en hela-raden-referens pÃ¥ tabellen \"%s\"." + +#: parser/parse_utilcmd.c:1563 parser/parse_utilcmd.c:1670 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "Index \"%s\" innehÃ¥ller en hela-raden-referens." + +#: parser/parse_utilcmd.c:2036 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "kan inte använda ett existerande index i CREATE TABLE" + +#: parser/parse_utilcmd.c:2056 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "index \"%s\" är redan associerad med ett villkor" + +#: parser/parse_utilcmd.c:2071 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "index \"%s\" är inte giltigt" + +#: parser/parse_utilcmd.c:2077 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" är inte ett unikt index" + +#: parser/parse_utilcmd.c:2078 parser/parse_utilcmd.c:2085 +#: parser/parse_utilcmd.c:2092 parser/parse_utilcmd.c:2163 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "Kan inte skapa en primärnyckel eller ett unikt villkor med hjälp av ett sÃ¥dant index." + +#: parser/parse_utilcmd.c:2084 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "index \"%s\" innehÃ¥ller uttryck" + +#: parser/parse_utilcmd.c:2091 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" är ett partiellt index" + +#: parser/parse_utilcmd.c:2103 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" är ett \"deferrable\" index" + +#: parser/parse_utilcmd.c:2104 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "Kan inte skapa ett icke-\"deferrable\" integritetsvillkor frÃ¥n ett \"deferrable\" index." + +#: parser/parse_utilcmd.c:2162 +#, c-format +msgid "index \"%s\" column number %d does not have default sorting behavior" +msgstr "index \"%s\" kolumn nummer %d har ingen standard för sorteringsbeteende" + +#: parser/parse_utilcmd.c:2319 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "kolumn \"%s\" finns med tvÃ¥ gÃ¥nger i primära nyckel-villkoret" + +#: parser/parse_utilcmd.c:2325 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "kolumn \"%s\" finns med tvÃ¥ gÃ¥nger i unique-villkoret" + +#: parser/parse_utilcmd.c:2676 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "indexuttryck och predikat kan bara referera till tabellen som indexeras" + +#: parser/parse_utilcmd.c:2722 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "regler pÃ¥ materialiserade vyer stöds inte" + +#: parser/parse_utilcmd.c:2785 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "WHERE-villkor i regel kan inte innehÃ¥lla referenser till andra relationer" + +#: parser/parse_utilcmd.c:2859 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "regler med WHERE-villkor kan bara innehÃ¥lla SELECT-, INSERT-, UPDATE- eller DELETE-handlingar" + +#: parser/parse_utilcmd.c:2877 parser/parse_utilcmd.c:2976 +#: rewrite/rewriteHandler.c:501 rewrite/rewriteManip.c:1015 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "UNION-/INTERSECT-/EXCEPT-satser med villkor är inte implementerat" + +#: parser/parse_utilcmd.c:2895 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECT-regel kan inte använda OLD" + +#: parser/parse_utilcmd.c:2899 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECT-regel kan inte använda NEW" + +#: parser/parse_utilcmd.c:2908 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERT-regel kan inte använda OLD" + +#: parser/parse_utilcmd.c:2914 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETE-regel kan inte använda NEW" + +#: parser/parse_utilcmd.c:2942 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "kan inte referera till OLD i WITH-frÃ¥ga" + +#: parser/parse_utilcmd.c:2949 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "kan inte referera till NEW i WITH-frÃ¥ga" + +#: parser/parse_utilcmd.c:3407 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "felplacerad DEFERRABLE-klausul" + +#: parser/parse_utilcmd.c:3412 parser/parse_utilcmd.c:3427 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "multipla DEFERRABLE/NOT DEFERRABLE-klausuler tillÃ¥ts inte" + +#: parser/parse_utilcmd.c:3422 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "felplacerad NOT DEFERRABLE-klausul" + +#: parser/parse_utilcmd.c:3443 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "felplacerad INITIALLY DEFERRED-klausul" + +#: parser/parse_utilcmd.c:3448 parser/parse_utilcmd.c:3474 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "multipla INITIALLY IMMEDIATE/DEFERRED-klausuler tillÃ¥ts inte" + +#: parser/parse_utilcmd.c:3469 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "felplacerad klausul INITIALLY IMMEDIATE" + +#: parser/parse_utilcmd.c:3660 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE anger ett schema (%s) som skiljer sig frÃ¥n det som skapas (%s)" + +#: parser/parse_utilcmd.c:3694 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "tabell \"%s\" är inte partitionerad" + +#: parser/parse_utilcmd.c:3701 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "index \"%s\" är inte partitionerad" + +#: parser/parse_utilcmd.c:3735 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "en hash-partitionerad tabell fÃ¥r inte ha en standardpartition" + +#: parser/parse_utilcmd.c:3752 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "ogiltig gränsangivelse för hash-partition" + +#: parser/parse_utilcmd.c:3758 partitioning/partbounds.c:2802 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "modulo för hash-partition vara ett positivt integer" + +#: parser/parse_utilcmd.c:3765 partitioning/partbounds.c:2810 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "rest för hash-partition mÃ¥ste vara lägre än modulo" + +#: parser/parse_utilcmd.c:3778 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "ogiltig gränsangivelse för listpartition" + +#: parser/parse_utilcmd.c:3831 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "ogiltig gränsangivelse för range-partition" + +#: parser/parse_utilcmd.c:3837 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM mÃ¥ste ge exakt ett värde per partitionerande kolumn" + +#: parser/parse_utilcmd.c:3841 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO mÃ¥ste ge exakt ett värde per partitionerande kolumn" + +#: parser/parse_utilcmd.c:3955 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "kan inte ange NULL i range-gräns" + +#: parser/parse_utilcmd.c:4004 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "varje gräns efter MAXVALUE mÃ¥ste ocksÃ¥ vara MAXVALUE" + +#: parser/parse_utilcmd.c:4011 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "varje gräns efter MINVALUE mÃ¥ste ocksÃ¥ vara MINVALUE" + +#: parser/parse_utilcmd.c:4046 +#, c-format +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "jämförelse (collation) av partitioneringsgränsvärde \"%s\" matchar inte partitioneringsnyckelns jämförelse \"%s\"" + +#: parser/parse_utilcmd.c:4063 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "angivet värde kan inte typomvandlas till typ %s för kolumn \"%s\"" + +#: parser/scansup.c:204 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "identifierare \"%s\" kommer trunkeras till \"%s\"" + +#: partitioning/partbounds.c:959 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "partition \"%s\" stÃ¥r i konflikt med existerande default-partition \"%s\"" + +#: partitioning/partbounds.c:1018 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "varje hash-partition-modulo mÃ¥ste vara en faktror av näste högre modulo" + +#: partitioning/partbounds.c:1114 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "tom intervallsgräns angiven för partition \"%s\"" + +#: partitioning/partbounds.c:1116 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Angiven lägre gräns %s är större än eller lika med övre gräns %s." + +#: partitioning/partbounds.c:1213 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "partition \"%s\" skulle överlappa partition \"%s\"" + +#: partitioning/partbounds.c:1311 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "hoppade över skanning av främmand tabell \"%s\" som er en partition för standardpartitionen \"%s\"" + +#: partitioning/partbounds.c:1348 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "uppdaterat partitionsintegritetsvillkor för standardpartition \"%s\" skulle brytas mot av nÃ¥gon rad" + +#: partitioning/partbounds.c:2806 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "rest för hash-partition mÃ¥ste vara ett icke-negativt heltal" + +#: partitioning/partbounds.c:2833 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" är inte en hash-partitionerad tabell" + +#: partitioning/partbounds.c:2844 partitioning/partbounds.c:2961 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "antalet partitioneringskolumner (%d) stämmer inte med antalet partioneringsnycklas som angivits (%d)" + +#: partitioning/partbounds.c:2866 partitioning/partbounds.c:2898 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "kolumn %d i partitioneringsnyckeln har typ \"%s\" men använt värde har typ \"%s\"" + +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "kunde inte skapa delat minnessegment: %m" + +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Misslyckade systemanropet var semget(key=%lu, size=%zu, 0%o)." + +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder vanligen att PostgreSQLs begäran av delat minnessegment överskred kärnans SHMMAX-parameter eller möjligen att det är lägre än kärnans SHMMIN-parameter.\n" +"PostgreSQLs dokumentation innehÃ¥ller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 +#, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder vanligen att PostgreSQLs begäran av delat minnessegment överskred kärnans SHMALL-parameter. Du kan behöva rekonfigurera kärnan med ett större SHMALL.\n" +"PostgreSQLs dokumentation innehÃ¥ller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Felet betyder *inte* att diskutrymmet tagit slut. Felet sker aningen om alla tillgängliga ID-nummer för delat minne tagit slut och dÃ¥ behöver du öka kärnans SHMMNI-parameter eller för att systemets totala gräns för delat minne ha nÃ¥tts.\n" +"PostgreSQLs dokumentation innehÃ¥ller mer information om konfigueration av delat minne." + +#: port/pg_shmem.c:577 port/sysv_shmem.c:577 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "kunde inte mappa anonymt delat minne: %m" + +#: port/pg_shmem.c:579 port/sysv_shmem.c:579 +#, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "Detta fel betyder vanligtvis att PostgreSQL:s begäran av delat minnessegment överskrider mängden tillgängligt minne, swap eller stora sidor. För att minska begärd storlek (nu %zu byte) minska PostgreSQL:s användning av delat minne t.ex. genom att dra ner pÃ¥ shared_buffers eller max_connections." + +#: port/pg_shmem.c:639 port/sysv_shmem.c:639 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "stora sidor stöds inte pÃ¥ denna plattform" + +#: port/pg_shmem.c:700 port/sysv_shmem.c:700 utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "redan existerande delat minnesblock (nyckel %lu, ID %lu) används fortfarande" + +#: port/pg_shmem.c:703 port/sysv_shmem.c:703 utils/init/miscinit.c:1071 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "Stäng ner gamla serverprocesser som hör ihop med datakatalogen \"%s\"." + +#: port/pg_shmem.c:754 port/sysv_shmem.c:754 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ datakatalog \"%s\": %m" + +#: port/sysv_sema.c:123 +#, c-format +msgid "could not create semaphores: %m" +msgstr "kan inte skapa semafor: %m" + +#: port/sysv_sema.c:124 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Misslyckade systemanropet var semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:128 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "Detta fel betyder *inte* att disken blivit full. Detta fel kommer när systemgränsen för maximalt antal semaforvektorer (SEMMNI) överskridits eller när systemets globala maximum för semaforer (SEMMNS) överskridits. Du behöver öka respektive kernel-parameter. Alternativt kan du minska PostgreSQL:s användning av semaforer genom att dra ner pÃ¥ parametern max_connections. PostgreSQL:s dokumentation innehÃ¥ller mer information om hur du konfigurerar systemet för PostgreSQL." + +#: port/sysv_sema.c:158 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Du kan behöva öka kärnans SEMVMX-värde till minst %d. Se PostgreSQL:s dokumentation för mer information." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "kunde inte ladda dbghelp.dll, kan inte skiva krash-dump\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "kunde inte ladda behövda funktioner i dbghelp.dll, kan inte skriva krash-dump\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "kunde inte öppna krashdumpfil \"%s\" för skrivning: felkod %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "skrev krashdump till fil \"%s\".\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "kunde inte skriva krashdump till fil \"%s\": felkod %lu\n" + +#: port/win32/signal.c:196 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "kunde inte skapa signallyssnarrör (pipe) för PID %d: felkod %lu" + +#: port/win32/signal.c:277 port/win32/signal.c:309 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "kunde inte skapa signallyssnar-pipe: felkod %lu; försöker igen\n" + +#: port/win32/signal.c:320 +#, c-format +msgid "could not create signal dispatch thread: error code %lu\n" +msgstr "kunde inte skapa signal-dispatch-trÃ¥d: felkod %lu\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "kan inte skapa semafor: felkod %lu" + +#: port/win32_sema.c:181 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "kunde inte lÃ¥sa semafor: felkod %lu" + +#: port/win32_sema.c:201 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "kunde inte lÃ¥sa upp semafor: felkod %lu" + +#: port/win32_sema.c:231 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "kunde inte utföra \"try-lock\" pÃ¥ semafor: felkod %lu" + +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "kunde inte aktivera användarrättigheten \"Lock Pages in Memory\": felkod %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "Misslyckat systemanrop var %s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "kunde inte aktivera användarrättigheten \"Lock Pages in Memory\"" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "Tilldela användarrättigheten \"Lock Pages in Memory\" till Windows-användarkontot som kör PostgreSQL." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "processorn stöder inte stora sidor" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "stänger av stora sidor" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "kunde inte skapa delat minnessegment: felkod %lu" + +#: port/win32_shmem.c:303 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Misslyckade systemanropet var CreateFileMapping(size=%zu, name=%s)." + +#: port/win32_shmem.c:328 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "redan existerande delat minnesblock används fortfarande" + +#: port/win32_shmem.c:329 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Kontrollera om det finns nÃ¥gra gamla serverprocesser som fortfarande kör och stäng ner dem." + +#: port/win32_shmem.c:339 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Misslyckat systemanrop var DuplicateHandle." + +#: port/win32_shmem.c:357 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Misslyckat systemanrop var MapViewOfFileEx." + +#: postmaster/autovacuum.c:405 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "kunde inte starta autovacuum-process: %m" + +#: postmaster/autovacuum.c:441 +#, c-format +msgid "autovacuum launcher started" +msgstr "autovacuum-startare startad" + +#: postmaster/autovacuum.c:819 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "autovacuum-startare stänger ner" + +#: postmaster/autovacuum.c:1481 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "kunde inte starta autovacuum-arbetsprocess: %m" + +#: postmaster/autovacuum.c:1687 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "autovacuum: processar databas \"%s\"" + +#: postmaster/autovacuum.c:2256 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: slänger övergiven temptabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2485 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "automatisk vacuum av tabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2488 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "automatisk analys av tabell \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "processar arbetspost för relation \"%s.%s.%s\"" + +#: postmaster/autovacuum.c:3262 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "autovacuum har inte startats pÃ¥ grund av en felkonfigurering" + +#: postmaster/autovacuum.c:3263 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "SlÃ¥ pÃ¥ flaggan \"track_counts\"." + +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "registrerar bakgrundsarbetare \"%s\"" + +#: postmaster/bgworker.c:427 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "avregistrerar bakgrundsarbetare \"%s\"" + +#: postmaster/bgworker.c:592 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "bakgrundsarbetare \"%s\": mÃ¥ste ansluta till delat minne för att kunna fÃ¥ en databasanslutning" + +#: postmaster/bgworker.c:601 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "bakgrundsarbetare \"%s\" kan inte fÃ¥ databasaccess om den startar när postmaster startar" + +#: postmaster/bgworker.c:615 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "bakgrundsarbetare \"%s\": ogiltigt omstartsintervall" + +#: postmaster/bgworker.c:630 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "bakgrundsarbetare \"%s\": parallella arbetare kan inte konfigureras för omstart" + +#: postmaster/bgworker.c:674 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "terminerar bakgrundsarbetare \"%s\" pga administratörskommando" + +#: postmaster/bgworker.c:863 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "bakgrundsarbetare \"%s\": mÃ¥ste vara registrerad i shared_preload_libraries" + +#: postmaster/bgworker.c:875 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "bakgrundsarbetare \"%s\": bara dynamiska bakgrundsarbetare kan be om notifiering" + +#: postmaster/bgworker.c:890 +#, c-format +msgid "too many background workers" +msgstr "för mÃ¥nga bakgrundsarbetare" + +#: postmaster/bgworker.c:891 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "Upp till %d bakgrundsarbetare kan registreras med nuvarande inställning." +msgstr[1] "Upp till %d bakgrundsarbetare kan registreras med nuvarande inställning." + +#: postmaster/bgworker.c:895 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "Överväg att öka konfigurationsparametern \"max_worker_processes\"." + +#: postmaster/checkpointer.c:458 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "checkpoint:s sker för ofta (%d sekund emellan)" +msgstr[1] "checkpoint:s sker för ofta (%d sekunder emellan)" + +#: postmaster/checkpointer.c:462 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "Överväg att öka konfigurationsparametern \"max_wal_size\"." + +#: postmaster/checkpointer.c:1081 +#, c-format +msgid "checkpoint request failed" +msgstr "checkpoint-behgäran misslyckades" + +#: postmaster/checkpointer.c:1082 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Se senaste meddelanden i serverloggen för mer information." + +#: postmaster/checkpointer.c:1267 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "minskade fsync-kön frÃ¥n %d poster till %d poster" + +#: postmaster/pgarch.c:159 +#, c-format +msgid "could not fork archiver: %m" +msgstr "kunde inte fork():a arkiveraren: %m" + +#: postmaster/pgarch.c:470 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode är pÃ¥slagen, men ändÃ¥ är archive_command inte satt" + +#: postmaster/pgarch.c:492 +#, c-format +msgid "removed orphan archive status file \"%s\"" +msgstr "tog bort övergiven arkivstatusfil \"%s\": %m" + +#: postmaster/pgarch.c:502 +#, c-format +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "borttagning av övergiven arkivstatusfil \"%s\" misslyckades för mÃ¥nga gÃ¥nger, kommer försöka igen senare" + +#: postmaster/pgarch.c:538 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "arkivering av write-ahead-logg-fil \"%s\" misslyckades för mÃ¥nga gÃ¥nger, kommer försöka igen senare" + +#: postmaster/pgarch.c:639 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "arkiveringskommando misslyckades med felkod %d" + +#: postmaster/pgarch.c:641 postmaster/pgarch.c:651 postmaster/pgarch.c:657 +#: postmaster/pgarch.c:666 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Det misslyckade arkiveringskommandot var: %s" + +#: postmaster/pgarch.c:648 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "arkiveringskommandot terminerades med avbrott 0x%X" + +#: postmaster/pgarch.c:650 postmaster/postmaster.c:3669 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Se C-include-fil \"ntstatus.h\" för en beskrivning av det hexdecimala värdet." + +#: postmaster/pgarch.c:655 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "arkiveringskommandot terminerades av signal %d: %s" + +#: postmaster/pgarch.c:664 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "arkiveringskommandot avslutade med okänd statuskod %d" + +#: postmaster/pgstat.c:396 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "kunde inte slÃ¥ upp \"localhost\": %s" + +#: postmaster/pgstat.c:419 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "försöker med en annan adress till statistikinsamlare" + +#: postmaster/pgstat.c:428 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "kunde inte skapa uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:440 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "kunde inte göra bind pÃ¥ uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:451 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "kunde inte fÃ¥ adress till uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:467 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "kunde inte ansluta uttag (socket) för statistikinsamlare: %m" + +#: postmaster/pgstat.c:488 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "kunde inte skicka testmeddelande till uttag (socket) för statistikinsamlaren: %m" + +#: postmaster/pgstat.c:514 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "select() misslyckades i statistikinsamlaren: %m" + +#: postmaster/pgstat.c:529 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "testmeddelande kom inte igenom pÃ¥ uttag (socket) för statistikinsamlare" + +#: postmaster/pgstat.c:544 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "kunde inte ta emot testmeddelande pÃ¥ uttag (socket) för statistikinsamlaren: %m" + +#: postmaster/pgstat.c:554 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "inkorrekt överföring av testmeddelande pÃ¥ uttag (socket) till statistikinsamlare" + +#: postmaster/pgstat.c:577 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "kunde inte sätta statistikinsamlarens uttag (socket) till ickeblockerande läge: %m" + +#: postmaster/pgstat.c:616 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "stänger av statistikinsamlare dÃ¥ arbetsuttag (socket) saknas" + +#: postmaster/pgstat.c:763 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "kunde inte fork():a statistikinsamlaren: %m" + +#: postmaster/pgstat.c:1347 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "okänt Ã¥terställningsmÃ¥l \"%s\"" + +#: postmaster/pgstat.c:1348 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "MÃ¥let mÃ¥ste vara \"archiver\" eller \"bgwriter\"." + +#: postmaster/pgstat.c:4534 +#, c-format +msgid "could not read statistics message: %m" +msgstr "kunde inte läsa statistikmeddelande: %m" + +#: postmaster/pgstat.c:4875 postmaster/pgstat.c:5032 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "kunde inte öppna temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4942 postmaster/pgstat.c:5077 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "kunde inte skriva temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4951 postmaster/pgstat.c:5086 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "kunde inte stänga temporär statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:4959 postmaster/pgstat.c:5094 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om temporär statistikfil \"%s\" till \"%s\": %m" + +#: postmaster/pgstat.c:5183 postmaster/pgstat.c:5389 postmaster/pgstat.c:5542 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "kunde inte öppna statistikfil \"%s\": %m" + +#: postmaster/pgstat.c:5195 postmaster/pgstat.c:5205 postmaster/pgstat.c:5226 +#: postmaster/pgstat.c:5248 postmaster/pgstat.c:5263 postmaster/pgstat.c:5326 +#: postmaster/pgstat.c:5401 postmaster/pgstat.c:5421 postmaster/pgstat.c:5439 +#: postmaster/pgstat.c:5455 postmaster/pgstat.c:5473 postmaster/pgstat.c:5489 +#: postmaster/pgstat.c:5554 postmaster/pgstat.c:5566 postmaster/pgstat.c:5578 +#: postmaster/pgstat.c:5603 postmaster/pgstat.c:5625 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "korrupt statistikfil \"%s\"" + +#: postmaster/pgstat.c:5754 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "använder gammal statistik istället för aktuell data dÃ¥ statistikinsamlaren inte svarar" + +#: postmaster/pgstat.c:6081 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "databasens hashtabell har blivit korrupt vid uppstädning --- avbryter" + +#: postmaster/postmaster.c:712 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: ogiltigt argument till flagga -f: \"%s\"\n" + +#: postmaster/postmaster.c:798 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: ogiltigt argument till flagga -t: \"%s\"\n" + +#: postmaster/postmaster.c:849 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: ogiltigt argument: \"%s\"\n" + +#: postmaster/postmaster.c:891 +#, c-format +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) mÃ¥ste vara mindre än max_connections (%d)\n" + +#: postmaster/postmaster.c:898 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "WAL-arkivering kan inte slÃ¥s pÃ¥ när wal_level är \"minimal\"" + +#: postmaster/postmaster.c:901 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL-strömning (max_wal_senders > 0) kräver wal_level \"replica\" eller \"logical\"" + +#: postmaster/postmaster.c:909 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: ogiltiga datumtokentabeller, det behöver lagas\n" + +#: postmaster/postmaster.c:998 +#, c-format +msgid "starting %s" +msgstr "startar %s" + +#: postmaster/postmaster.c:1027 postmaster/postmaster.c:1125 +#: utils/init/miscinit.c:1551 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "ogiltigt listsyntax för parameter \"%s\"" + +#: postmaster/postmaster.c:1058 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "kunde inte skapa lyssnande uttag (socket) för \"%s\"" + +#: postmaster/postmaster.c:1064 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "kunde inte skapa TCP/IP-uttag (socket)" + +#: postmaster/postmaster.c:1147 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "kunde inte skapa unix-domän-uttag (socket) i katalog \"%s\"" + +#: postmaster/postmaster.c:1153 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "kunde inte skapa nÃ¥got Unix-domän-uttag (socket)" + +#: postmaster/postmaster.c:1165 +#, c-format +msgid "no socket created for listening" +msgstr "inget uttag (socket) skapat för lyssnande" + +#: postmaster/postmaster.c:1205 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "kunde inte skapa \"I/O completion port\" för barnkö" + +#: postmaster/postmaster.c:1234 +#, c-format +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: kunde inte ändra rättigheter pÃ¥ extern PID-fil \"%s\": %s\n" + +#: postmaster/postmaster.c:1238 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: kunde inte skriva extern PID-fil \"%s\": %s\n" + +#: postmaster/postmaster.c:1298 +#, c-format +msgid "ending log output to stderr" +msgstr "avslutar loggutmatning till stderr" + +#: postmaster/postmaster.c:1299 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "Framtida loggutmatning kommer gÃ¥ till logg-destination \"%s\"." + +#: postmaster/postmaster.c:1325 utils/init/postinit.c:216 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "kunde inte ladda pg_hba.conf" + +#: postmaster/postmaster.c:1351 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "postmaster blev flertrÃ¥dad under uppstart" + +#: postmaster/postmaster.c:1352 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "Sätt omgivningsvariabeln LC_ALL till en giltig lokal." + +#: postmaster/postmaster.c:1453 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: kunde inte hitta matchande postgres-binär" + +#: postmaster/postmaster.c:1476 utils/misc/tzparser.c:341 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "Detta tyder pÃ¥ en inkomplett PostgreSQL-installation alternativt att filen \"%s\" har flyttats bort frÃ¥n sin korrekta plats." + +#: postmaster/postmaster.c:1503 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: kunde inte hitta databassystemet\n" +"Förväntade mig att hitta det i katalogen \"%s\",\n" +"men kunde inte öppna filen \"%s\": %s\n" + +#: postmaster/postmaster.c:1680 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "select() misslyckades i postmaster: %m" + +#: postmaster/postmaster.c:1835 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "stänger ner omedelbart dÃ¥ datakatalogens lÃ¥sfil är ogiltig" + +#: postmaster/postmaster.c:1934 postmaster/postmaster.c:1965 +#, c-format +msgid "incomplete startup packet" +msgstr "ofullständigt startuppaket" + +#: postmaster/postmaster.c:1946 +#, c-format +msgid "invalid length of startup packet" +msgstr "ogiltig längd pÃ¥ startuppaket" + +#: postmaster/postmaster.c:2004 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "misslyckades att skicka SSL-förhandlingssvar: %m" + +#: postmaster/postmaster.c:2031 +#, c-format +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "misslyckades att skicka GSSAPI-förhandlingssvar: %m" + +#: postmaster/postmaster.c:2056 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "inget stöd för framändans protokoll %u.%u: servern stödjer %u.0 till %u.%u" + +#: postmaster/postmaster.c:2120 utils/misc/guc.c:6574 utils/misc/guc.c:6610 +#: utils/misc/guc.c:6680 utils/misc/guc.c:8006 utils/misc/guc.c:10828 +#: utils/misc/guc.c:10862 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "ogiltigt värde för parameter \"%s\": \"%s\"" + +#: postmaster/postmaster.c:2123 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "Giltiga värden är: \"false\", 0, \"true\", 1, \"database\"." + +#: postmaster/postmaster.c:2168 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "ogiltig startpaketlayout: förväntade en terminator som sista byte" + +#: postmaster/postmaster.c:2206 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "inget PostgreSQL-användarnamn angivet i startuppaketet" + +#: postmaster/postmaster.c:2265 +#, c-format +msgid "the database system is starting up" +msgstr "databassystemet startar upp" + +#: postmaster/postmaster.c:2270 +#, c-format +msgid "the database system is shutting down" +msgstr "databassystemet stänger ner" + +#: postmaster/postmaster.c:2275 +#, c-format +msgid "the database system is in recovery mode" +msgstr "databassystemet är Ã¥terställningsläge" + +#: postmaster/postmaster.c:2280 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:363 +#, c-format +msgid "sorry, too many clients already" +msgstr "ledsen, för mÃ¥nga klienter" + +#: postmaster/postmaster.c:2370 +#, c-format +msgid "wrong key in cancel request for process %d" +msgstr "fel nyckel i avbrytbegäran för process %d" + +#: postmaster/postmaster.c:2382 +#, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "PID %d i avbrytbegäran matchade inte nÃ¥gon process" + +#: postmaster/postmaster.c:2629 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "mottog SIGHUP, läser om konfigurationsfiler" + +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2655 postmaster/postmaster.c:2659 +#, c-format +msgid "%s was not reloaded" +msgstr "%s laddades inte om" + +#: postmaster/postmaster.c:2669 +#, c-format +msgid "SSL configuration was not reloaded" +msgstr "SSL-konfiguration laddades inte om" + +#: postmaster/postmaster.c:2717 +#, c-format +msgid "received smart shutdown request" +msgstr "tog emot förfrÃ¥gan om att stänga ner smart" + +#: postmaster/postmaster.c:2775 +#, c-format +msgid "received fast shutdown request" +msgstr "tog emot förfrÃ¥gan om att stänga ner snabbt" + +#: postmaster/postmaster.c:2808 +#, c-format +msgid "aborting any active transactions" +msgstr "avbryter aktiva transaktioner" + +#: postmaster/postmaster.c:2842 +#, c-format +msgid "received immediate shutdown request" +msgstr "mottog begäran för omedelbar nedstängning" + +#: postmaster/postmaster.c:2909 +#, c-format +msgid "shutdown at recovery target" +msgstr "nedstängs vid Ã¥terställningsmÃ¥l" + +#: postmaster/postmaster.c:2925 postmaster/postmaster.c:2948 +msgid "startup process" +msgstr "uppstartprocess" + +#: postmaster/postmaster.c:2928 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "avbryter uppstart pÃ¥ grund av fel i startprocessen" + +#: postmaster/postmaster.c:2989 +#, c-format +msgid "database system is ready to accept connections" +msgstr "databassystemet är redo att ta emot anslutningar" + +#: postmaster/postmaster.c:3010 +msgid "background writer process" +msgstr "bakgrundsskrivarprocess" + +#: postmaster/postmaster.c:3064 +msgid "checkpointer process" +msgstr "checkpoint-process" + +#: postmaster/postmaster.c:3080 +msgid "WAL writer process" +msgstr "WAL-skrivarprocess" + +#: postmaster/postmaster.c:3095 +msgid "WAL receiver process" +msgstr "WAL-mottagarprocess" + +#: postmaster/postmaster.c:3110 +msgid "autovacuum launcher process" +msgstr "autovacuum-startprocess" + +#: postmaster/postmaster.c:3125 +msgid "archiver process" +msgstr "arkiveringsprocess" + +#: postmaster/postmaster.c:3141 +msgid "statistics collector process" +msgstr "statistikinsamlingsprocess" + +#: postmaster/postmaster.c:3155 +msgid "system logger process" +msgstr "system-logg-process" + +#: postmaster/postmaster.c:3217 +#, c-format +msgid "background worker \"%s\"" +msgstr "bakgrundsarbetare \"%s\"" + +#: postmaster/postmaster.c:3301 postmaster/postmaster.c:3321 +#: postmaster/postmaster.c:3328 postmaster/postmaster.c:3346 +msgid "server process" +msgstr "serverprocess" + +#: postmaster/postmaster.c:3400 +#, c-format +msgid "terminating any other active server processes" +msgstr "avslutar andra aktiva serverprocesser" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3656 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) avslutade med felkod %d" + +#: postmaster/postmaster.c:3658 postmaster/postmaster.c:3670 +#: postmaster/postmaster.c:3680 postmaster/postmaster.c:3691 +#, c-format +msgid "Failed process was running: %s" +msgstr "Misslyckad process körde: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3667 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) terminerades av avbrott 0x%X" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3677 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) terminerades av signal %d: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3689 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) avslutade med okänd status %d" + +#: postmaster/postmaster.c:3872 +#, c-format +msgid "abnormal database system shutdown" +msgstr "ej normal databasnedstängning" + +#: postmaster/postmaster.c:3912 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "alla serverprocesser är avslutade; initierar pÃ¥ nytt" + +#: postmaster/postmaster.c:4082 postmaster/postmaster.c:5473 +#: postmaster/postmaster.c:5847 +#, c-format +msgid "could not generate random cancel key" +msgstr "kunde inte skapa slumpad avbrytningsnyckel" + +#: postmaster/postmaster.c:4136 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "kunde inte fork():a ny process for uppkoppling: %m" + +#: postmaster/postmaster.c:4178 +msgid "could not fork new process for connection: " +msgstr "kunde inte fork():a ny process for uppkoppling: " + +#: postmaster/postmaster.c:4288 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "ansluting mottagen: värd=%s port=%s" + +#: postmaster/postmaster.c:4293 +#, c-format +msgid "connection received: host=%s" +msgstr "ansluting mottagen: värd=%s" + +#: postmaster/postmaster.c:4563 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "kunde inte köra serverprocess \"%s\": %m" + +#: postmaster/postmaster.c:4716 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "ger upp efter för mÃ¥nga försök att reservera delat minne" + +#: postmaster/postmaster.c:4717 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Detta kan orsakas av ASLR eller antivirusprogram." + +#: postmaster/postmaster.c:4928 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "SSL-konfigurering kunde inte laddas i barnprocess" + +#: postmaster/postmaster.c:5060 +#, c-format +msgid "Please report this to ." +msgstr "Vänligen rapportera detta till ." + +#: postmaster/postmaster.c:5147 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "databassystemet är redo att ta emot read-only-anslutningar" + +#: postmaster/postmaster.c:5401 +#, c-format +msgid "could not fork startup process: %m" +msgstr "kunde inte starta startup-processen: %m" + +#: postmaster/postmaster.c:5405 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "kunde inte starta process för bakgrundsskrivare: %m" + +#: postmaster/postmaster.c:5409 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "kunde inte fork:a bakgrundsprocess: %m" + +#: postmaster/postmaster.c:5413 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "kunde inte fork:a WAL-skrivprocess: %m" + +#: postmaster/postmaster.c:5417 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "kunde inte fork:a WAL-mottagarprocess: %m" + +#: postmaster/postmaster.c:5421 +#, c-format +msgid "could not fork process: %m" +msgstr "kunde inte fork:a process: %m" + +#: postmaster/postmaster.c:5618 postmaster/postmaster.c:5641 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "krav pÃ¥ databasanslutning fanns inte med vid registering" + +#: postmaster/postmaster.c:5625 postmaster/postmaster.c:5648 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "ogiltigt processläge i bakgrundsarbetare" + +#: postmaster/postmaster.c:5720 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "startar bakgrundsarbetarprocess \"%s\"" + +#: postmaster/postmaster.c:5732 +#, c-format +msgid "could not fork worker process: %m" +msgstr "kunde inte starta (fork) arbetarprocess: %m" + +#: postmaster/postmaster.c:6168 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "kunde inte duplicera uttag (socket) %d för att använda i backend: felkod %d" + +#: postmaster/postmaster.c:6200 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "kunde inte skapa ärvt uttag (socket): felkod %d\n" + +#: postmaster/postmaster.c:6229 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "kunde inte öppna bakändans variabelfil \"%s\": %s\n" + +#: postmaster/postmaster.c:6236 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "kunde inte läsa frÃ¥n bakändans variabelfil \"%s\": %s\n" + +#: postmaster/postmaster.c:6245 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "kunde inte ta bort fil \"%s\": %s\n" + +#: postmaster/postmaster.c:6262 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "kunde inte mappa in vy för bakgrundsvariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6271 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "kunde inte avmappa vy för bakgrundsvariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6278 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "kunde inte stänga \"handle\" till backend:ens parametervariabler: felkod %lu\n" + +#: postmaster/postmaster.c:6442 +#, c-format +msgid "could not read exit code for process\n" +msgstr "kunde inte läsa avslutningskod för process\n" + +#: postmaster/postmaster.c:6447 +#, c-format +msgid "could not post child completion status\n" +msgstr "kunde inte skicka barnets avslutningsstatus\n" + +#: postmaster/syslogger.c:480 postmaster/syslogger.c:1154 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "kunde inte läsa frÃ¥n loggrör (pipe): %m" + +#: postmaster/syslogger.c:528 +#, c-format +msgid "logger shutting down" +msgstr "loggaren stänger ner" + +#: postmaster/syslogger.c:572 postmaster/syslogger.c:586 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "kunde inte skapa rör (pipe) för syslog: %m" + +#: postmaster/syslogger.c:637 +#, c-format +msgid "could not fork system logger: %m" +msgstr "kunde inte fork:a systemloggaren: %m" + +#: postmaster/syslogger.c:673 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "omdirigerar loggutmatning till logginsamlingsprocess" + +#: postmaster/syslogger.c:674 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Framtida loggutmatning kommer dyka upp i katalog \"%s\"." + +#: postmaster/syslogger.c:682 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "kunde inte omdirigera stdout: %m" + +#: postmaster/syslogger.c:687 postmaster/syslogger.c:704 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "kunde inte omdirigera stderr: %m" + +#: postmaster/syslogger.c:1109 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "kunde inte skriva till loggfil: %s\n" + +#: postmaster/syslogger.c:1226 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "kunde inte öppna loggfil \"%s\": %m" + +#: postmaster/syslogger.c:1288 postmaster/syslogger.c:1338 +#, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "stänger av automatisk rotation (använd SIGHUP för att slÃ¥ pÃ¥ igen)" + +#: regex/regc_pg_locale.c:262 +#, c-format +msgid "could not determine which collation to use for regular expression" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för reguljära uttryck" + +#: regex/regc_pg_locale.c:269 +#, c-format +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för reguljära uttryck" + +#: repl_gram.y:336 repl_gram.y:368 +#, c-format +msgid "invalid timeline %u" +msgstr "ogiltig tidslinje %u" + +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "ogiltig startposition för strömning" + +#: repl_scanner.l:180 scan.l:703 +msgid "unterminated quoted string" +msgstr "icketerminerad citerad sträng" + +#: replication/basebackup.c:450 +#, c-format +msgid "could not find any WAL files" +msgstr "kunde inte hitta nÃ¥gra WAL-filer" + +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "kunde inte hitta WAL-fil \"%s\"" + +#: replication/basebackup.c:530 replication/basebackup.c:558 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "oväntad WAL-filstorlek \"%s\"" + +#: replication/basebackup.c:544 replication/basebackup.c:1539 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "basbackup kunde inte skicka data, avbryter backup" + +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "totalt %s verifieringsfel av checksumma" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "misslyckad verifiering av checksumma under basbackup" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "duplicerad flagga \"%s\"" + +#: replication/basebackup.c:717 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d är utanför giltigt intervall för parameter \"%s\" (%d .. %d)" + +#: replication/basebackup.c:991 replication/basebackup.c:1161 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "kunde inte ta status pÃ¥ fil eller katalog \"%s\": %m" + +#: replication/basebackup.c:1316 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "hoppar över specialfil \"%s\"" + +#: replication/basebackup.c:1424 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "ogiltigt segmentnummer %d i fil \"%s\"" + +#: replication/basebackup.c:1443 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "kan inte verifiera checksumma i fil \"%s\", block %d: läsbufferstorlek %d och sidstorlek %d skiljer sig Ã¥t" + +#: replication/basebackup.c:1487 replication/basebackup.c:1503 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "kunde inte gör fseek i fil \"%s\": %m" + +#: replication/basebackup.c:1495 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "kunde inte läsa tillbaka block %d i fil \"%s\": %m" + +#: replication/basebackup.c:1519 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "checksumkontroll misslyckades i fil \"%s\", block %d: beräknade %X men förväntade %X" + +#: replication/basebackup.c:1526 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "ytterligare kontroller av checksummor i fil \"%s\" kommer inte rapporteras" + +#: replication/basebackup.c:1584 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "filen \"%s\" har totalt %d kontrollerade felaktiga checksummor" + +#: replication/basebackup.c:1615 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "filnamnet är för lÃ¥ngt för tar-format: \"%s\"" + +#: replication/basebackup.c:1620 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "mÃ¥l för symbolisk länk är för lÃ¥ngt för tar-format: filnamn \"%s\", mÃ¥l \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:232 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "ogiltig anslutningssträngsyntax %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 +#, c-format +msgid "could not parse connection string: %s" +msgstr "kunde inte parsa anslutningssträng: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:328 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "kunde inte hämta databassystemidentifierare och tidslinje-ID frÃ¥n primära servern: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:339 +#: replication/libpqwalreceiver/libpqwalreceiver.c:557 +#, c-format +msgid "invalid response from primary server" +msgstr "ogiltigt svar frÃ¥n primär server" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:340 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "Kunde inte identifiera system: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:413 +#: replication/libpqwalreceiver/libpqwalreceiver.c:419 +#: replication/libpqwalreceiver/libpqwalreceiver.c:444 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "kunde inte starta WAL-strömning: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:467 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "kunde inte skicka meddelandet end-of-streaming till primären: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:489 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "oväntad resultatmängd efter end-of-streaming" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:503 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "fel vid nestängning av strömmande COPY: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:512 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "fel vid läsning av resultat frÃ¥n strömmningskommando: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:520 +#: replication/libpqwalreceiver/libpqwalreceiver.c:754 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "oväntat resultat efter CommandComplete: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:546 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "kan inte ta emot fil med tidslinjehistorik frÃ¥n primära servern: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:558 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "Förväntade 1 tupel med 2 fält, fick %d tupler med %d fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:718 +#: replication/libpqwalreceiver/libpqwalreceiver.c:769 +#: replication/libpqwalreceiver/libpqwalreceiver.c:775 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "kunde inte ta emot data frÃ¥n WAL-ström: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "kunde inte skicka data till WAL-ström: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:843 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "kunde inte skapa replikeringsslot \"%s\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:877 +#, c-format +msgid "invalid query response" +msgstr "ogiltigt frÃ¥gerespons" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "Förväntade %d fält, fick %d fält." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:947 +#, c-format +msgid "the query interface requires a database connection" +msgstr "frÃ¥geinterface:et kräver en databasanslutning" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:978 +msgid "empty query" +msgstr "tom frÃ¥ga" + +#: replication/logical/launcher.c:307 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "startar logisk replikeringsarbetare för prenumeration \"%s\"" + +#: replication/logical/launcher.c:314 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "kan inte starta logisk replikeringsarbetare när max_replication_slots = 0" + +#: replication/logical/launcher.c:394 +#, c-format +msgid "out of logical replication worker slots" +msgstr "slut pÃ¥ logiska replikeringsarbetarslots" + +#: replication/logical/launcher.c:395 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "Du kan behöva öka max_logical_replication_workers." + +#: replication/logical/launcher.c:450 +#, c-format +msgid "out of background worker slots" +msgstr "slut pÃ¥ bakgrundsarbetarslots" + +#: replication/logical/launcher.c:451 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "Du kan behöva öka max_worker_processes." + +#: replication/logical/launcher.c:650 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "logisk replikeringsarbetarslot %d är tom, kan inte ansluta" + +#: replication/logical/launcher.c:659 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "logiisk replikeringsarbetarslot %d används redan av en annan arbetare, kan inte ansluta" + +#: replication/logical/launcher.c:977 +#, c-format +msgid "logical replication launcher started" +msgstr "logisk replikeringsstartare startad" + +#: replication/logical/logical.c:90 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "logisk avkodning kräver wal_level >= logical" + +#: replication/logical/logical.c:95 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "logisk avkodning kräver en databasanslutning" + +#: replication/logical/logical.c:113 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "logisk avkodning kan inte användas under Ã¥terställning" + +#: replication/logical/logical.c:258 replication/logical/logical.c:396 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "kan inte använda fysisk replikeringsslot för logisk avkodning" + +#: replication/logical/logical.c:263 replication/logical/logical.c:401 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "replikeringsslot \"%s\" har inte skapats i denna databasen" + +#: replication/logical/logical.c:270 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "kan inte skapa logisk replikeringsslot i transaktion som redan har utfört skrivningar" + +#: replication/logical/logical.c:441 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "startar logisk avkodning för slot \"%s\"" + +#: replication/logical/logical.c:443 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "Strömmar transaktioner commit:ade efter %X/%X, läser WAL frÃ¥n %X/%X" + +#: replication/logical/logical.c:593 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "slot \"%s\", utdata-plugin \"%s\", i callback:en %s, associerad LSN %X/%X" + +#: replication/logical/logical.c:600 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "slot \"%s\", utdata-plugin \"%s\", i callback:en %s" + +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:34 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "mÃ¥ste vara superanvändare eller replikeringsroll för att använda replikeringsslottar" + +#: replication/logical/logicalfuncs.c:153 +#, c-format +msgid "slot name must not be null" +msgstr "slot-namn fÃ¥r inte vara null" + +#: replication/logical/logicalfuncs.c:169 +#, c-format +msgid "options array must not be null" +msgstr "flagg-array fÃ¥r inte vara null" + +#: replication/logical/logicalfuncs.c:200 +#, c-format +msgid "array must be one-dimensional" +msgstr "array:en mÃ¥ste vara endimensionell" + +#: replication/logical/logicalfuncs.c:206 +#, c-format +msgid "array must not contain nulls" +msgstr "array:en fÃ¥r inte innehÃ¥lla null" + +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2312 +#: utils/adt/jsonb.c:1282 +#, c-format +msgid "array must have even number of elements" +msgstr "array:en mÃ¥ste ha ett jämnt antal element" + +#: replication/logical/logicalfuncs.c:269 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "utdata-plugin \"%s\" för logisk avkodning producerar binär utdata men funktionen \"%s\" förväntar sig textdata" + +#: replication/logical/origin.c:185 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "bara superanvändare kan läsa eller ändra replikeringskällor" + +#: replication/logical/origin.c:190 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "kan inte se eller ändra replikeringskällor när max_replication_slots = 0" + +#: replication/logical/origin.c:195 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "kan inte ändra replikeringskällor under tiden Ã¥terställning sker" + +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "replikeringskälla \"%s\" finns inte" + +#: replication/logical/origin.c:321 +#, c-format +msgid "could not find free replication origin OID" +msgstr "kunde inte hitta ledig replikering-origin-OID" + +#: replication/logical/origin.c:369 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "kunde inte slänga replikeringskälla med OID %d som används av PID %d" + +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "replikeringskälla med OID %u finns inte" + +#: replication/logical/origin.c:729 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "replikeringscheckpoint har fel magiskt tal %u istället för %u" + +#: replication/logical/origin.c:770 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "kunde inte hitta ledig replikeringsplats, öka max_replication_slots" + +#: replication/logical/origin.c:788 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "replikeringsslot-checkpoint har felaktig kontrollsumma %u, förväntade %u" + +#: replication/logical/origin.c:916 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "replikeringskälla med OID %d är redan aktiv för PID %d" + +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "kunde inte hitta ledig replikerings-state-slot för replikerings-origin med OID %u" + +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1564 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "Öka max_replication_slots och försök igen." + +#: replication/logical/origin.c:1073 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "kan inte ställa in replikeringskälla när en redan är inställd" + +#: replication/logical/origin.c:1102 +#, c-format +msgid "replication identifier %d is already active for PID %d" +msgstr "replikeringsidentifierare %d är redan aktiv för PID %d" + +#: replication/logical/origin.c:1153 replication/logical/origin.c:1351 +#: replication/logical/origin.c:1371 +#, c-format +msgid "no replication origin is configured" +msgstr "ingen replikeringskälla är konfigurerad" + +#: replication/logical/relation.c:255 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "logisk replikeringsmÃ¥lrelation \"%s.%s\" finns inte" + +#: replication/logical/relation.c:297 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "logisk replikeringsmÃ¥lrelation \"%s.%s\" saknar nÃ¥gra replikerade kolumner" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "logisk replikeringsmÃ¥lrelation \"%s.%s\" använder systemkolumner i REPLICA IDENTITY-index" + +#: replication/logical/reorderbuffer.c:2507 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "kunde inte skriva till datafil för XID %u: %m" + +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 +#, c-format +msgid "could not read from reorderbuffer spill file: %m" +msgstr "kunde inte läsa frÃ¥n reorderbuffer spill-fil: %m" + +#: replication/logical/reorderbuffer.c:2604 +#: replication/logical/reorderbuffer.c:2626 +#, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "kunde inte läsa frÃ¥n reorderbuffer spill-fil: läste %d istället för %u byte" + +#: replication/logical/reorderbuffer.c:2849 +#, c-format +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "kunde inte radera fil \"%s\" vid borttagning av pg_replslot/%s/xid*: %m" + +#: replication/logical/reorderbuffer.c:3315 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "kunde inte läsa frÃ¥n fil \"%s\": läste %d istället för %d byte" + +#: replication/logical/snapbuild.c:611 +#, c-format +msgid "initial slot snapshot too large" +msgstr "initialt slot-snapshot är för stort" + +#: replication/logical/snapbuild.c:665 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "exporterade logisk avkodnings-snapshot: \"%s\" med %u transaktions-ID" +msgstr[1] "exporterade logisk avkodnings-snapshot: \"%s\" med %u transaktions-ID" + +#: replication/logical/snapbuild.c:1270 replication/logical/snapbuild.c:1363 +#: replication/logical/snapbuild.c:1917 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "logisk avkodning hittade konsistent punkt vid %X/%X" + +#: replication/logical/snapbuild.c:1272 +#, c-format +msgid "There are no running transactions." +msgstr "Det finns inga körande transaktioner." + +#: replication/logical/snapbuild.c:1314 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "logisk avkodning hittade initial startpunkt vid %X/%X" + +#: replication/logical/snapbuild.c:1316 replication/logical/snapbuild.c:1340 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "Väntar pÃ¥ att transaktioner (cirka %d) äldre än %u skall gÃ¥ klart." + +#: replication/logical/snapbuild.c:1338 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "logisk avkodning hittade initial konsistent punkt vid %X/%X" + +#: replication/logical/snapbuild.c:1365 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Det finns inte längre nÃ¥gra gamla transaktioner." + +#: replication/logical/snapbuild.c:1759 +#, c-format +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "snapbuild-state-fil \"%s\" har fel magiskt tal: %u istället för %u" + +#: replication/logical/snapbuild.c:1765 +#, c-format +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "snapbuild-state-fil \"%s\" har en ej stödd version: %u istället för %u" + +#: replication/logical/snapbuild.c:1864 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "checksumma stämmer inte för snapbuild-state-fil \"%s\": är %u, skall vara %u" + +#: replication/logical/snapbuild.c:1919 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "Logisk avkodning kommer starta med sparat snapshot." + +#: replication/logical/snapbuild.c:1991 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "kunde inte parsa filnamn \"%s\"" + +#: replication/logical/tablesync.c:139 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "logisk replikerings tabellsynkroniseringsarbetare för prenumeration \"%s\", tabell \"%s\" är klar" + +#: replication/logical/tablesync.c:672 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "kunde inte hämta tabellinfo för tabell \"%s.%s\" frÃ¥n publicerare: %s" + +#: replication/logical/tablesync.c:678 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "tabell \"%s.%s\" hittades inte hos publicerare" + +#: replication/logical/tablesync.c:710 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "kunde inte hämta tabellinfo för tabell \"%s.%s\": %s" + +#: replication/logical/tablesync.c:780 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "kunde inte starta initial innehÃ¥llskopiering för tabell \"%s.%s\": %s" + +#: replication/logical/tablesync.c:894 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "tabellkopiering kunde inte starta transaktion pÃ¥ publiceraren" + +#: replication/logical/tablesync.c:916 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "tabellkopiering kunde inte slutföra transaktion pÃ¥ publiceraren" + +#: replication/logical/worker.c:290 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "processar fjärrdata för replikeringsmÃ¥lrelation \"%s.%s\" kolumn \"%s\", fjärrtyp %s, lokal typ %s" + +#: replication/logical/worker.c:511 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "ORIGIN-meddelande skickat i fel ordning" + +#: replication/logical/worker.c:645 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "publicerare skickade inte identitetskolumn för replika som förväntades av den logiska replikeringens mÃ¥lrelation \"%s.%s\"" + +#: replication/logical/worker.c:652 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "logisk replikeringsmÃ¥lrelation \"%s.%s\" har varken REPLICA IDENTITY-index eller PRIMARY KEY och den publicerade relationen har inte REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:993 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "ogiltig logisk replikeringsmeddelandetyp \"%c\"" + +#: replication/logical/worker.c:1134 +#, c-format +msgid "data stream from publisher has ended" +msgstr "dataströmmen frÃ¥n publiceraren har avslutats" + +#: replication/logical/worker.c:1289 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "avslutar logisk replikeringsarbetare pÃ¥ grund av timeout" + +#: replication/logical/worker.c:1437 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer stoppa dÃ¥ prenumerationen har tagits bort" + +#: replication/logical/worker.c:1451 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer stoppa dÃ¥ prenumerationen har stängts av" + +#: replication/logical/worker.c:1465 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om dÃ¥ uppkopplingsinformationen ändrats" + +#: replication/logical/worker.c:1479 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om dÃ¥ prenumerationen bytt namn" + +#: replication/logical/worker.c:1496 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om dÃ¥ replikeringsslotten bytt namn" + +#: replication/logical/worker.c:1510 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer starta om dÃ¥ prenumerationens publiceringar ändrats" + +#: replication/logical/worker.c:1614 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration %u kommer inte starta dÃ¥ prenumerationen togs bort under uppstart" + +#: replication/logical/worker.c:1626 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" kommer inte starta dÃ¥ prenumerationen stänges av under uppstart" + +#: replication/logical/worker.c:1644 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "logisk replikerings tabellsynkroniseringsarbetare för prenumeration \"%s\", tabell \"%s\" har startat" + +#: replication/logical/worker.c:1648 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "logisk replikerings uppspelningsarbetare för prenumeration \"%s\" har startat" + +#: replication/logical/worker.c:1687 +#, c-format +msgid "subscription has no replication slot set" +msgstr "prenumeration har ingen replikeringsslot angiven" + +#: replication/pgoutput/pgoutput.c:117 +#, c-format +msgid "invalid proto_version" +msgstr "ogiltig proto_version" + +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\" är utanför giltigt intervall" + +#: replication/pgoutput/pgoutput.c:139 +#, c-format +msgid "invalid publication_names syntax" +msgstr "ogiltig publication_names-syntax" + +#: replication/pgoutput/pgoutput.c:181 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "klienten skickade proto_version=%d men vi stöder bara protokoll %d eller lägre" + +#: replication/pgoutput/pgoutput.c:187 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "klienten skickade proto_version=%d men vi stöder bara protokoll %d eller högre" + +#: replication/pgoutput/pgoutput.c:193 +#, c-format +msgid "publication_names parameter missing" +msgstr "saknar parameter publication_names" + +#: replication/slot.c:182 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "replikeringsslotnamn \"%s\" är för kort" + +#: replication/slot.c:191 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "replikeringsslotnamn \"%s\" är för lÃ¥ngt" + +#: replication/slot.c:204 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "replikeringsslotnamn \"%s\" innehÃ¥ller ogiltiga tecken" + +#: replication/slot.c:206 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Replikeringsslotnamn fÃ¥r bara innehÃ¥lla smÃ¥ bokstäver, nummer och understreck." + +#: replication/slot.c:253 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "replikeringsslot \"%s\" finns redan" + +#: replication/slot.c:263 +#, c-format +msgid "all replication slots are in use" +msgstr "alla replikeringsslots används" + +#: replication/slot.c:264 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Frigör en eller öka max_replication_slots." + +#: replication/slot.c:387 replication/slotfuncs.c:663 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "replikeringsslot \"%s\" existerar inte" + +#: replication/slot.c:398 replication/slot.c:947 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "replikeringsslot \"%s\" är aktiv för PID %d" + +#: replication/slot.c:631 replication/slot.c:1139 replication/slot.c:1499 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "kunde inte ta bort katalog \"%s\"" + +#: replication/slot.c:982 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "replikeringsslots kan bara användas om max_replication_slots > 0" + +#: replication/slot.c:987 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "replikeringsslots kan bara användas om wal_level >= replica" + +#: replication/slot.c:1437 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "replikeringsslotfil \"%s\" har fel magiskt nummer: %u istället för %u" + +#: replication/slot.c:1444 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "replikeringsslotfil \"%s\" har en icke stödd version %u" + +#: replication/slot.c:1451 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "replikeringsslotfil \"%s\" har felaktig längd %u" + +#: replication/slot.c:1487 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "kontrollsummefel för replikeringsslot-fil \"%s\": är %u, skall vara %u" + +#: replication/slot.c:1521 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "logisk replikeringsslot \"%s\" finns men wal_level < replica" + +#: replication/slot.c:1523 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "Ändra wal_level till logical eller högre." + +#: replication/slot.c:1527 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "fysisk replikeringsslot \"%s\" finns men wal_level < replica" + +#: replication/slot.c:1529 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "Ändra wal_level till replica eller högre." + +#: replication/slot.c:1563 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "för mÃ¥nga aktiva replikeringsslottar innan nerstängning" + +#: replication/slotfuncs.c:526 +#, c-format +msgid "invalid target wal lsn" +msgstr "ogiltig mÃ¥l-lsn för wal" + +#: replication/slotfuncs.c:548 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "kan inte flytta fram replikeringsslot som inte en tidigare reserverad WAL" + +#: replication/slotfuncs.c:564 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "kan inte flytta fram replikeringsslot till %X/%X, minimum är %X/%X" + +#: replication/slotfuncs.c:670 +#, c-format +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "kan inte kopiera fysisk replikeringsslot \"%s\" som en logisk replikeringsslot" + +#: replication/slotfuncs.c:672 +#, c-format +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "kan inte kopiera logisk replikeringsslot \"%s\" som en fysisk replikeringsslot" + +#: replication/slotfuncs.c:681 +#, c-format +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "kan inte kopiera en replikeringsslot som inte tidigare har reserverat WAL" + +#: replication/slotfuncs.c:746 +#, c-format +msgid "could not copy replication slot \"%s\"" +msgstr "kunde inte kopiera replikeringsslot \"%s\"" + +#: replication/slotfuncs.c:748 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "Källreplikeringsslotten ändrades pÃ¥ ett inkompatibelt sätt under copy-operationen." + +#: replication/syncrep.c:248 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "avbryter väntan pÃ¥ synkron replikering samt avslutar anslutning pÃ¥ grund av ett administratörskommando" + +#: replication/syncrep.c:249 replication/syncrep.c:266 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "Transaktionen har redan commit:ats lokalt men har kanske inte replikerats till standby:en." + +#: replication/syncrep.c:265 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "avbryter väntan pÃ¥ synkron replikering efter användarens önskemÃ¥l" + +#: replication/syncrep.c:398 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "standby \"%s\" har nu synkron standby-prioritet %u" + +#: replication/syncrep.c:461 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "standby \"%s\" är nu en synkron standby med prioritet %u" + +#: replication/syncrep.c:465 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "standby \"%s\" är nu en kvorumkandidat för synkron standby" + +#: replication/syncrep.c:1165 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names-parser misslyckades" + +#: replication/syncrep.c:1171 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "antal synkrona standbys (%d) mÃ¥ste vara fler än noll" + +#: replication/walreceiver.c:160 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "avslutar wal-mottagarprocessen pÃ¥ grund av ett administratörskommando" + +#: replication/walreceiver.c:276 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "kunde inte ansluta till primärserver: %s" + +#: replication/walreceiver.c:322 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "databassystemets identifierare skiljer sig Ã¥t mellan primären och standby:en" + +#: replication/walreceiver.c:323 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Primärens identifierare är %s, standby:ens identifierare är %s." + +#: replication/walreceiver.c:333 +#, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "högsta tidslinjen %u i primären är efter Ã¥terställningstidslinjen %u" + +#: replication/walreceiver.c:369 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "startade strömning av WAL frÃ¥n primären vid %X/%X pÃ¥ tidslinje %u" + +#: replication/walreceiver.c:374 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "Ã¥terstartade WAL-strömning vid %X/%X pÃ¥ tidslinje %u" + +#: replication/walreceiver.c:403 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "kan inte fortsätta WAL-strömning, Ã¥terställning har redan avslutats" + +#: replication/walreceiver.c:440 +#, c-format +msgid "replication terminated by primary server" +msgstr "replikering avslutad av primär server" + +#: replication/walreceiver.c:441 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "Slut pÃ¥ WAL nÃ¥dd pÃ¥ tidslinje %u vid %X/%X." + +#: replication/walreceiver.c:529 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "avslutar wal-mottagare pÃ¥ grund av timeout" + +#: replication/walreceiver.c:567 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "primär server har ingen mer WAL pÃ¥ efterfrÃ¥gad tidslinje %u" + +#: replication/walreceiver.c:582 replication/walreceiver.c:922 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "kunde inte stänga loggsegment %s: %m" + +#: replication/walreceiver.c:700 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "hämtar tidslinjehistorikfil för tidslinje %u frÃ¥n primära servern" + +#: replication/walreceiver.c:976 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "kunde inte skriva till loggfilsegment %s pÃ¥ offset %u, längd %lu: %m" + +#: replication/walsender.c:497 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "kunde inte söka till början av filen \"%s\": %m" + +#: replication/walsender.c:548 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM har inte körts före START_REPLICATION" + +#: replication/walsender.c:565 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "kan inte använda logisk replikeringsslot för fysisk replikering" + +#: replication/walsender.c:628 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "efterfrÃ¥gad startpunkt %X/%X pÃ¥ tidslinje %u finns inte i denna servers historik" + +#: replication/walsender.c:632 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "Denna servers historik delade sig frÃ¥n tidslinje %u vid %X/%X." + +#: replication/walsender.c:677 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "efterfrÃ¥gad startpunkt %X/%X är längre fram än denna servers flush:ade WAL-skrivposition %X/%X" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:907 +#, c-format +msgid "%s must not be called inside a transaction" +msgstr "%s fÃ¥r inte anropas i en transaktion" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:917 +#, c-format +msgid "%s must be called inside a transaction" +msgstr "%s mÃ¥ste anropas i en transaktion" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:923 +#, c-format +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "%s mÃ¥ste anropas i transaktions REPEATABLE READ-isolationsläge" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:929 +#, c-format +msgid "%s must be called before any query" +msgstr "%s mÃ¥ste anropas innan nÃ¥gon frÃ¥ga" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:935 +#, c-format +msgid "%s must not be called in a subtransaction" +msgstr "%s fÃ¥r inte anropas i en undertransaktion" + +#: replication/walsender.c:1082 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "stänger ner walsender-process efter promovering" + +#: replication/walsender.c:1453 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "kan inte utföra nya kommandon när WAL-sändare är i stopp-läge" + +#: replication/walsender.c:1486 +#, c-format +msgid "received replication command: %s" +msgstr "tog emot replikeringskommando: %s" + +#: replication/walsender.c:1502 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1426 tcop/postgres.c:1684 tcop/postgres.c:2077 +#: tcop/postgres.c:2463 tcop/postgres.c:2542 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "aktuella transaktionen har avbrutits, alla kommandon ignoreras tills slutet pÃ¥ transaktionen" + +#: replication/walsender.c:1570 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "kan inte köra SQL-kommandon i WAL-sändare för fysisk replikering" + +#: replication/walsender.c:1618 replication/walsender.c:1634 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "oväntat EOF frÃ¥n standby-anslutning" + +#: replication/walsender.c:1648 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "oväntat standby-meddelandetyp \"%c\" efter att vi tagit emot CopyDone" + +#: replication/walsender.c:1686 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "ogiltigt standby-meddelandetyp \"%c\"" + +#: replication/walsender.c:1727 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "oväntad meddelandetyp \"%c\"" + +#: replication/walsender.c:2145 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "avslutar walsender-process pÃ¥ grund av replikerings-timeout" + +#: replication/walsender.c:2222 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "\"%s\" har nu kommit ikapp servern uppströms" + +#: replication/walsender.c:2481 +#, c-format +msgid "could not read from log segment %s, offset %u, length %zu: %m" +msgstr "kunde inte läsa frÃ¥n loggsegment %s, offset %u, längd %zu: %m" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "regel \"%s\" för relation \"%s\" existerar redan" + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "regelhandlingar pÃ¥ OLD är inte implementerat" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use views or triggers instead." +msgstr "Använd vyer eller utlösare (trigger) istället." + +#: rewrite/rewriteDefine.c:306 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "regelhandlingar pÃ¥ NEW är inte implementerat" + +#: rewrite/rewriteDefine.c:307 +#, c-format +msgid "Use triggers instead." +msgstr "Använd utlösare (trigger) istället." + +#: rewrite/rewriteDefine.c:320 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "INSTEAD NOTHING-regler pÃ¥ SELECT är inte implementerat ännu" + +#: rewrite/rewriteDefine.c:321 +#, c-format +msgid "Use views instead." +msgstr "Använd vyer istället." + +#: rewrite/rewriteDefine.c:329 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "flera regelhandlingar pÃ¥ SELECT är inte implementerat" + +#: rewrite/rewriteDefine.c:339 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "regler pÃ¥ SELECT mÃ¥ste ha handlingen INSTEAD SELECT" + +#: rewrite/rewriteDefine.c:347 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "regler pÃ¥ SELECT fÃ¥r inte innehÃ¥lla datamodifierande satser i WITH" + +#: rewrite/rewriteDefine.c:355 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "händelsebegränsningar är inte implementerat för regler pÃ¥ SELECT" + +#: rewrite/rewriteDefine.c:382 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" är redan en vy" + +#: rewrite/rewriteDefine.c:406 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "vy-regel (rule) för \"%s\" mÃ¥ste ha namnet \"%s\"" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "kan inte konvertera partitionerad tabell \"%s\" till en vy" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "kan inte konvertera partition \"%s\" till en vy" + +#: rewrite/rewriteDefine.c:449 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "kunde inte konvertera tabell \"%s\" till en vy dÃ¥ den inte är tom" + +#: rewrite/rewriteDefine.c:458 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "kunde inte konvertera tabell \"%s\" till en vy dÃ¥ den har utlösare" + +#: rewrite/rewriteDefine.c:460 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "Mer specifikt, tabellen kan inte vare inblandad i främmande-nyckelberoenden." + +#: rewrite/rewriteDefine.c:465 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har index" + +#: rewrite/rewriteDefine.c:471 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "kunde inte konvertera tabell \"%s\" till en vy dÃ¥ den har barntabeller" + +#: rewrite/rewriteDefine.c:477 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har radsäkerhet pÃ¥slagen" + +#: rewrite/rewriteDefine.c:483 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "kunde inte konvertera tabell \"%s\" till en vy eftersom den har radsäkerhetspolicy" + +#: rewrite/rewriteDefine.c:510 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "kan inte ha flera RETURNING-listor i en regel" + +#: rewrite/rewriteDefine.c:515 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "RETURNING-listor stöds inte i villkorade regler" + +#: rewrite/rewriteDefine.c:519 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "RETURNING-listor stöds inte i icke-INSTEAD-regler" + +#: rewrite/rewriteDefine.c:683 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "SELECT-regelns mÃ¥llista har för mÃ¥nga poster" + +#: rewrite/rewriteDefine.c:684 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNING-lista har för mÃ¥nga element" + +#: rewrite/rewriteDefine.c:711 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "kan inte konvertera en relation som har borttagna kolumner till en vy" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "kan inte skapa en RETURNING-lista för relationer som innehÃ¥ller borttagna kolumner" + +#: rewrite/rewriteDefine.c:718 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECT-regels mÃ¥lpost %d har ett annat kolumnnamn än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:720 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT-mÃ¥lpost har namn \"%s\"." + +#: rewrite/rewriteDefine.c:729 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECT-regels mÃ¥lpot %d har en annan typ än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:731 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNING-listans post %d har en annan typ än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT-mÃ¥lpost har typ %s men kolumnen har typ %s." + +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNING-listpost har typ %s men kolumnen har typ %s." + +#: rewrite/rewriteDefine.c:753 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECT-regelns mÃ¥lpost %d har en annan storlek än kolumnen \"%s\"" + +#: rewrite/rewriteDefine.c:755 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNING-listpost %d har en annan storlek än kolumnen\"%s\"" + +#: rewrite/rewriteDefine.c:772 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "SELECT-regels mÃ¥llista har för fÃ¥ element" + +#: rewrite/rewriteDefine.c:773 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNING-lista har för fÃ¥ element" + +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 +#: rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "regel \"%s\" för relation \"%s\" existerar inte" + +#: rewrite/rewriteDefine.c:999 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "byta namn pÃ¥ en ON SELECT-regel tillÃ¥ts inte" + +#: rewrite/rewriteHandler.c:544 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "WITH-frÃ¥genamn \"%s\" finns bÃ¥de i en regelhändelse och i frÃ¥gan som skrivs om" + +#: rewrite/rewriteHandler.c:604 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "kan inte ha RETURNING-listor i multipla regler" + +#: rewrite/rewriteHandler.c:813 rewrite/rewriteHandler.c:825 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "kan inte sätta in i kolumn \"%s\"" + +#: rewrite/rewriteHandler.c:814 rewrite/rewriteHandler.c:836 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "Kolumn \"%s\" är en identitetskolumn definierad som GENERATED ALWAYS." + +#: rewrite/rewriteHandler.c:816 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "Använd OVERRIDING SYSTEM VALUE för att överskugga." + +#: rewrite/rewriteHandler.c:835 rewrite/rewriteHandler.c:842 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "kolumn \"%s\" kan bara uppdateras till DEFAULT" + +#: rewrite/rewriteHandler.c:1011 rewrite/rewriteHandler.c:1029 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "flera tilldelningar till samma kolumn \"%s\"" + +#: rewrite/rewriteHandler.c:2059 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "oändlig rekursion detekterad i policy för relation \"%s\"" + +#: rewrite/rewriteHandler.c:2379 +msgid "Junk view columns are not updatable." +msgstr "Skräpkolumner i vy är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2384 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "Vykolumner som inte är kolumner i dess basrelation är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2387 +msgid "View columns that refer to system columns are not updatable." +msgstr "Vykolumner som refererar till systemkolumner är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2390 +msgid "View columns that return whole-row references are not updatable." +msgstr "Vykolumner som returnerar hel-rad-referenser är inte uppdateringsbara." + +#: rewrite/rewriteHandler.c:2451 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "Vyer som innehÃ¥ller DISTINCT är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2454 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "Vyer som innehÃ¥ller GROUP BY är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2457 +msgid "Views containing HAVING are not automatically updatable." +msgstr "Vyer som innehÃ¥ller HAVING är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "Vyer som innehÃ¥ller UNION, INTERSECT eller EXCEPT är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2463 +msgid "Views containing WITH are not automatically updatable." +msgstr "Vyer som innehÃ¥ller WITH är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2466 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "Vyer som innehÃ¥ller LIMIT eller OFFSET är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2478 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Vyer som returnerar aggregatfunktioner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2481 +msgid "Views that return window functions are not automatically updatable." +msgstr "Vyer som returnerar fönsterfunktioner uppdateras inte automatiskt." + +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Vyer som returnerar mängd-returnerande funktioner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2491 rewrite/rewriteHandler.c:2495 +#: rewrite/rewriteHandler.c:2503 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Vyer som inte läser frÃ¥n en ensam tabell eller vy är inte automatiskt uppdateringsbar." + +#: rewrite/rewriteHandler.c:2506 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "Vyer som innehÃ¥ller TABLESAMPLE är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2530 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Vyer som inte har nÃ¥gra uppdateringsbara kolumner är inte automatiskt uppdateringsbara." + +#: rewrite/rewriteHandler.c:2987 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "kan inte insert:a i kolumn \"%s\" i vy \"%s\"" + +#: rewrite/rewriteHandler.c:2995 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "kan inte uppdatera kolumn \"%s\" i view \"%s\"" + +#: rewrite/rewriteHandler.c:3471 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "DO INSTEAD NOTHING-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3485 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "villkorliga DO INSTEAD-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3489 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "DO ALSO-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3494 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "fler-satsiga DO INSTEAD-regler stöds inte för datamodifierande satser i WITH" + +#: rewrite/rewriteHandler.c:3744 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "kan inte utföra INSERT RETURNING pÃ¥ relation \"%s\"" + +#: rewrite/rewriteHandler.c:3746 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON INSERT DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3751 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "kan inte utföra UPDATE RETURNING pÃ¥ relation \"%s\"" + +#: rewrite/rewriteHandler.c:3753 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON UPDATE DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3758 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "kan inte utföra DELETE RETURNING pÃ¥ relation \"%s\"" + +#: rewrite/rewriteHandler.c:3760 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Du behöver en villkorslös ON DELETE DO INSTEAD-regel med en RETURNING-klausul." + +#: rewrite/rewriteHandler.c:3778 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT med ON CONFLICT-klausul kan inte användas med tabell som har INSERT- eller UPDATE-regler" + +#: rewrite/rewriteHandler.c:3835 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "WITH kan inte användas i en frÃ¥ga där regler skrivit om den till flera olika frÃ¥gor" + +#: rewrite/rewriteManip.c:1003 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "villkorliga hjälpsatser är inte implementerat" + +#: rewrite/rewriteManip.c:1169 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "WHERE CURRENT OF för en vy är inte implementerat" + +#: rewrite/rewriteManip.c:1503 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "NEW-variabler i ON UPDATE-regler kan inte referera till kolumner som är del av en multiple uppdatering i subjektets UPDATE-kommando" + +#: scan.l:463 +msgid "unterminated /* comment" +msgstr "ej avslutad /*-kommentar" + +#: scan.l:494 +msgid "unterminated bit string literal" +msgstr "ej avslutad bitsträngslitteral" + +#: scan.l:515 +msgid "unterminated hexadecimal string literal" +msgstr "ej avslutad hexadecimal stränglitteral" + +#: scan.l:565 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "osäker användning av strängkonstand med Unicode-escape:r" + +#: scan.l:566 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "Strängkonstanter som innehÃ¥ller Unicode-escapesekvenser kan inte användas när standard_conforming_strings är av." + +#: scan.l:612 scan.l:811 +msgid "invalid Unicode escape character" +msgstr "ogiltigt Unicode-escape-tecken" + +#: scan.l:638 scan.l:646 scan.l:654 scan.l:655 scan.l:656 scan.l:1400 +#: scan.l:1427 scan.l:1431 scan.l:1469 scan.l:1473 scan.l:1495 scan.l:1505 +msgid "invalid Unicode surrogate pair" +msgstr "ogiltigt Unicode-surrogatpar" + +#: scan.l:660 +#, c-format +msgid "invalid Unicode escape" +msgstr "ogiltig Unicode-escapesekvens" + +#: scan.l:661 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicode-escapesekvenser mÃ¥ste vara \\uXXXX eller \\UXXXXXXXX." + +#: scan.l:672 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "osäker användning av \\' i stränglitteral" + +#: scan.l:673 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Använd '' för att inkludera ett enkelcitattecken i en sträng. \\' är inte säkert i klient-teckenkodning." + +#: scan.l:748 +msgid "unterminated dollar-quoted string" +msgstr "icke terminerad dollarciterad sträng" + +#: scan.l:765 scan.l:791 scan.l:806 +msgid "zero-length delimited identifier" +msgstr "noll-längds avdelad identifierare" + +#: scan.l:826 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "icke terminerad citerad identifierare" + +#: scan.l:989 +msgid "operator too long" +msgstr "operatorn är för lÃ¥ng" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1141 +#, c-format +msgid "%s at end of input" +msgstr "%s vid slutet av indatan" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1149 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s vid eller nära \"%s\"" + +#: scan.l:1314 scan.l:1346 +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +msgstr "Unicode-escape-värden kan inte användas för kodpunkter över 007F när serverkodningen inte är UTF8" + +#: scan.l:1342 scan.l:1487 +msgid "invalid Unicode escape value" +msgstr "ogiltigt Unicode-escapevärde" + +#: scan.l:1551 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "ickestandard användning av \\' i stränglitteral" + +#: scan.l:1552 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Använd '' för att skriva citattecken i strängar eller använd escape-strängsyntac (E'...')." + +#: scan.l:1561 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "ickestandard användning av \\\\ i strängslitteral" + +#: scan.l:1562 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Använd escape-strängsyntax för bakstreck, dvs. E'\\\\'." + +#: scan.l:1576 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "ickestandard användning av escape i stränglitteral" + +#: scan.l:1577 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Använd escape-strängsyntax, dvs E'\\r\\n'." + +#: snowball/dict_snowball.c:197 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "det finns ingen Snowball-stemmer för sprÃ¥k \"%s\" och kodning \"%s\"" + +#: snowball/dict_snowball.c:220 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "multipla StoppOrd-parametrar" + +#: snowball/dict_snowball.c:229 +#, c-format +msgid "multiple Language parameters" +msgstr "multipla parametrar \"Language\"" + +#: snowball/dict_snowball.c:236 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "okänd Snowball-parameter: \"%s\"" + +#: snowball/dict_snowball.c:244 +#, c-format +msgid "missing Language parameter" +msgstr "saknar parameter \"Language\"" + +#: statistics/dependencies.c:673 statistics/dependencies.c:726 +#: statistics/mcv.c:1310 statistics/mcv.c:1341 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:94 +#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 +#: utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 +#: utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 +#: utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "kan inte acceptera ett värde av type %s" + +#: statistics/extended_stats.c:119 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "statistikobjekt \"%s.%s\" kunde inte beräknas för relation \"%s.%s\"" + +#: statistics/mcv.c:1166 utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "en funktion med post som värde anropades i sammanhang där poster inte kan godtagas." + +#: storage/buffer/bufmgr.c:545 storage/buffer/bufmgr.c:658 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "fÃ¥r inte röra temporära tabeller som tillhör andra sessioner" + +#: storage/buffer/bufmgr.c:814 +#, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "oväntad data efter EOF i block %u för relation %s" + +#: storage/buffer/bufmgr.c:816 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Detta beteende har observerats med buggiga kärnor; fundera pÃ¥ att uppdatera ditt system." + +#: storage/buffer/bufmgr.c:914 +#, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "felaktig sida i block %u för relation %s; nollställer sidan" + +#: storage/buffer/bufmgr.c:4056 +#, c-format +msgid "could not write block %u of %s" +msgstr "kunde inte skriva block %u av %s" + +#: storage/buffer/bufmgr.c:4058 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Multipla fel --- skrivfelet kan vara permanent." + +#: storage/buffer/bufmgr.c:4079 storage/buffer/bufmgr.c:4098 +#, c-format +msgid "writing block %u of relation %s" +msgstr "skriver block %u i relation %s" + +#: storage/buffer/bufmgr.c:4401 +#, c-format +msgid "snapshot too old" +msgstr "snapshot för gammal" + +#: storage/buffer/localbuf.c:199 +#, c-format +msgid "no empty local buffer available" +msgstr "ingen tom lokal buffer tillgänglig" + +#: storage/buffer/localbuf.c:427 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "kan inte komma Ã¥t temporära tabeller under en parallell operation" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\" frÃ¥n BufFile \"%s\": %m" + +#: storage/file/buffile.c:796 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "kunde inte bestämma storlek pÃ¥ temporär fil \"%s\" frÃ¥n BufFile \"%s\": %m" + +#: storage/file/fd.c:458 storage/file/fd.c:530 storage/file/fd.c:566 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "kunde inte flush:a smutsig data: %m" + +#: storage/file/fd.c:488 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "kunde inte lista ut storlek pÃ¥ smutsig data: %m" + +#: storage/file/fd.c:540 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "kunde inte göra munmap() vid flush:ning av data: %m" + +#: storage/file/fd.c:748 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "kunde inte länka fil \"%s\" till \"%s\": %m" + +#: storage/file/fd.c:842 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit misslyckades: %m" + +#: storage/file/fd.c:932 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "otillräckligt antal fildeskriptorer tillgängligt för att starta serverprocessen" + +#: storage/file/fd.c:933 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Systemet tillÃ¥ter %d, vi behöver minst %d." + +#: storage/file/fd.c:984 storage/file/fd.c:2246 storage/file/fd.c:2356 +#: storage/file/fd.c:2507 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "slut pÃ¥ fildeskriptorer: %m; frigör och försök igen" + +#: storage/file/fd.c:1284 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "temporär fil: sökväg \"%s\", storlek %lu" + +#: storage/file/fd.c:1415 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "kunde inte skapa temporär katalog \"%s\": %m" + +#: storage/file/fd.c:1422 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "kunde inte skapa temporär underkatalog \"%s\": %m" + +#: storage/file/fd.c:1615 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "kan inte skapa temporär fil \"%s\": %m" + +#: storage/file/fd.c:1650 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\": %m" + +# unlink refererar till unix-funktionen unlink() sÃ¥ den översätter vi inte +#: storage/file/fd.c:1691 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "kunde inte unlink:a temporär fil \"%s\": %m" + +#: storage/file/fd.c:1955 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "storlek pÃ¥ temporär fil överskrider temp_file_limit (%dkB)" + +#: storage/file/fd.c:2222 storage/file/fd.c:2281 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att öppna fil \"%s\"" + +#: storage/file/fd.c:2326 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att köra kommando \"%s\"" + +#: storage/file/fd.c:2483 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "överskred maxAllocatedDescs (%d) vid försök att öppna katalog \"%s\"" + +#: storage/file/fd.c:2574 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" + +#: storage/file/fd.c:3006 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "oväntad fil hittades i katalogen för temporära filer: \"%s\"" + +#: storage/file/fd.c:3331 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "kunde inte göra rmdir pÃ¥ katalogen \"%s\": %m" + +#: storage/file/sharedfileset.c:95 +#, c-format +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "kunde inte koppla till en SharedFileSet som redan tagits bort" + +#: storage/ipc/dsm.c:343 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "dynamiskt delat minnes kontrollsegment är korrupt" + +#: storage/ipc/dsm.c:404 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "dynamiskt delat minnes kontrollsegment är inte giltigt" + +#: storage/ipc/dsm.c:500 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "för mÃ¥nga dynamiska delade minnessegment" + +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:517 +#: storage/ipc/dsm_impl.c:621 storage/ipc/dsm_impl.c:792 +#, c-format +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "kunde inte avmappa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:527 +#: storage/ipc/dsm_impl.c:631 storage/ipc/dsm_impl.c:802 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "kunde inte ta bort delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:702 +#: storage/ipc/dsm_impl.c:816 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "kunde inte öppna delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:285 storage/ipc/dsm_impl.c:543 +#: storage/ipc/dsm_impl.c:747 storage/ipc/dsm_impl.c:840 +#, c-format +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:311 storage/ipc/dsm_impl.c:891 +#, c-format +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "kunde inte ändra storlek pÃ¥ delat minnessegment \"%s\" till %zu byte: %m" + +#: storage/ipc/dsm_impl.c:332 storage/ipc/dsm_impl.c:564 +#: storage/ipc/dsm_impl.c:723 storage/ipc/dsm_impl.c:913 +#, c-format +msgid "could not map shared memory segment \"%s\": %m" +msgstr "kunde inte mappa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:499 +#, c-format +msgid "could not get shared memory segment: %m" +msgstr "kunde inte hämta delat minnessegment: %m" + +#: storage/ipc/dsm_impl.c:687 +#, c-format +msgid "could not create shared memory segment \"%s\": %m" +msgstr "kunde inte skapa delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:924 +#, c-format +msgid "could not close shared memory segment \"%s\": %m" +msgstr "kunde inte stänga delat minnessegment \"%s\": %m" + +#: storage/ipc/dsm_impl.c:963 storage/ipc/dsm_impl.c:1011 +#, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "kunde inte duplicera handle för \"%s\": %m" + +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:860 storage/ipc/latch.c:1093 storage/ipc/latch.c:1219 +#, c-format +msgid "%s failed: %m" +msgstr "%s misslyckades: %m" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:929 +#: storage/lmgr/lock.c:967 storage/lmgr/lock.c:2754 storage/lmgr/lock.c:4084 +#: storage/lmgr/lock.c:4149 storage/lmgr/lock.c:4441 +#: storage/lmgr/predicate.c:2404 storage/lmgr/predicate.c:2419 +#: storage/lmgr/predicate.c:3918 storage/lmgr/predicate.c:5075 +#: utils/hash/dynahash.c:1065 +#, c-format +msgid "out of shared memory" +msgstr "slut pÃ¥ delat minne" + +#: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "slut pÃ¥ delat minne (%zu byte efterfrÃ¥gat)" + +#: storage/ipc/shmem.c:421 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "kunde inte skapa ShmemIndex-post för datastrukturen \"%s\"" + +#: storage/ipc/shmem.c:436 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "ShmemIndex-poststorlek är fel för datastruktur \"%s\": förväntade %zu var %zu" + +#: storage/ipc/shmem.c:453 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "otillräckligt delat minne för datastruktur \"%s\" (efterfrÃ¥gade %zu byte)" + +#: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "efterfrÃ¥gad delat minnesstorlek överskrider size_t" + +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d är inte en PostgreSQL serverprocess" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1364 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "kunde inte skicka signal till process %d: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "mÃ¥ste vara superanvändare för att avbryta superanvändares frÃ¥ga" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "mÃ¥ste vara medlem i den roll vars frÃ¥ga hÃ¥ller pÃ¥ att avbrytas eller medlem i pg_signal_backend" + +#: storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "mÃ¥ste vara superanvändare för stoppa superanvändares process" + +#: storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "mÃ¥ste vara medlem i den roll vars process hÃ¥ller pÃ¥ att avslutas eller medlem i pg_signal_backend" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "mÃ¥ste vara superanvändare för att rotera loggfiler med adminpack 1.0" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:223 +#, c-format +msgid "Consider using %s, which is part of core, instead." +msgstr "Du kanske kan använda %s istället som är en del av core." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "rotering är inte möjligt dÃ¥ logginsamling inte är aktiverad" + +#: storage/ipc/standby.c:558 tcop/postgres.c:3123 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "avbryter sats pÃ¥ grund av konflikt med Ã¥terställning" + +#: storage/ipc/standby.c:559 tcop/postgres.c:2397 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "Användartransaktion orsakade deadlock för buffer vid Ã¥terställning." + +#: storage/large_object/inv_api.c:189 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "pg_largeobject-post för OID %u, sida %d har ogiltig datafältstorlek %d" + +#: storage/large_object/inv_api.c:270 +#, c-format +msgid "invalid flags for opening a large object: %d" +msgstr "ogiltiga flaggor för att öppna stort objekt: %d" + +#: storage/large_object/inv_api.c:460 +#, c-format +msgid "invalid whence setting: %d" +msgstr "ogiltig whence-inställning: %d" + +#: storage/large_object/inv_api.c:632 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "ogiltig storlek för stort objects skrivningbegäran: %d" + +#: storage/lmgr/deadlock.c:1109 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Process %d väntar pÃ¥ %s för %s; blockerad av process %d." + +#: storage/lmgr/deadlock.c:1128 +#, c-format +msgid "Process %d: %s" +msgstr "Process %d: %s" + +#: storage/lmgr/deadlock.c:1137 +#, c-format +msgid "deadlock detected" +msgstr "deadlock upptäckt" + +#: storage/lmgr/deadlock.c:1140 +#, c-format +msgid "See server log for query details." +msgstr "Se server-logg för frÃ¥gedetaljer." + +#: storage/lmgr/lmgr.c:815 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "vid uppdatering av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:818 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "vid borttagning av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:821 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "vid lÃ¥sning av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:824 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "vid lÃ¥sning av uppdaterad version (%u,%u) av tupel i relation \"%s\"" + +#: storage/lmgr/lmgr.c:827 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "vid insättning av indextupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:830 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "vid kontroll av unikhet av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:833 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "vid Ã¥terkontroll av uppdaterad tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:836 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "vid kontroll av uteslutningsvillkor av tupel (%u,%u) i relation \"%s\"" + +#: storage/lmgr/lmgr.c:1093 +#, c-format +msgid "relation %u of database %u" +msgstr "relation %u i databasen %u" + +#: storage/lmgr/lmgr.c:1099 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "utökning av relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1105 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "sida %u i relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1112 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "tuple (%u,%u) i relation %u i databas %u" + +#: storage/lmgr/lmgr.c:1120 +#, c-format +msgid "transaction %u" +msgstr "transaktion %u" + +#: storage/lmgr/lmgr.c:1125 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "vituell transaktion %d/%u" + +#: storage/lmgr/lmgr.c:1131 +#, c-format +msgid "speculative token %u of transaction %u" +msgstr "spekulativ token %u för transaktion %u" + +#: storage/lmgr/lmgr.c:1137 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "objekt %u av klass %u i databas %u" + +#: storage/lmgr/lmgr.c:1145 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "användarlÃ¥s [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1152 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "rÃ¥dgivande lÃ¥s [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1160 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "okänd lÃ¥setikettyp %d" + +#: storage/lmgr/lock.c:764 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "kan inte ta lÃ¥släge %s pÃ¥ databasobjekt när Ã¥terställning pÃ¥gÃ¥r" + +#: storage/lmgr/lock.c:766 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "Bara RowExclusiveLock eller lägre kan tas pÃ¥ databasobjekt under Ã¥terställning." + +#: storage/lmgr/lock.c:930 storage/lmgr/lock.c:968 storage/lmgr/lock.c:2755 +#: storage/lmgr/lock.c:4085 storage/lmgr/lock.c:4150 storage/lmgr/lock.c:4442 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "Du kan behöva öka parametern max_locks_per_transaction." + +#: storage/lmgr/lock.c:3201 storage/lmgr/lock.c:3317 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "kan inte göra PREPARE samtidigt som vi hÃ¥ller lÃ¥s pÃ¥ sessionsnivÃ¥ och transaktionsnivÃ¥ för samma objekt" + +#: storage/lmgr/predicate.c:703 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "ej tillräckligt med element i RWConflictPool för att spara ner en läs/skriv-konflikt" + +#: storage/lmgr/predicate.c:704 storage/lmgr/predicate.c:732 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "Du kan behöva köra färre samtidiga transaktioner eller öka max_connections." + +#: storage/lmgr/predicate.c:731 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "ej tillräckligt med element i RWConflictPool för att spara ner en potentiell läs/skriv-konflikt" + +#: storage/lmgr/predicate.c:1538 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "deferrable-snapshot var osäklert; försöker med ett nytt" + +#: storage/lmgr/predicate.c:1627 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "\"default_transaction_isolation\" är satt till \"serializable\"." + +#: storage/lmgr/predicate.c:1628 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Du kan använda \"SET default_transaction_isolation = 'repeatable read'\" för att ändra standardvärdet." + +#: storage/lmgr/predicate.c:1679 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "en snapshot-importerande transaktion fÃ¥r inte vara READ ONLY DEFERRABLE" + +#: storage/lmgr/predicate.c:1758 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 +#, c-format +msgid "could not import the requested snapshot" +msgstr "kunde inte importera efterfrÃ¥gat snapshot" + +#: storage/lmgr/predicate.c:1759 utils/time/snapmgr.c:630 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "Källprocessen med PID %d kör inte längre." + +#: storage/lmgr/predicate.c:2405 storage/lmgr/predicate.c:2420 +#: storage/lmgr/predicate.c:3919 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "Du kan behöva öka parametern max_pred_locks_per_transaction." + +#: storage/lmgr/predicate.c:4075 storage/lmgr/predicate.c:4164 +#: storage/lmgr/predicate.c:4172 storage/lmgr/predicate.c:4211 +#: storage/lmgr/predicate.c:4454 storage/lmgr/predicate.c:4791 +#: storage/lmgr/predicate.c:4803 storage/lmgr/predicate.c:4846 +#: storage/lmgr/predicate.c:4884 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "kunde inte serialisera Ã¥tkomst pÃ¥ grund av läs/skriv-beroenden bland transaktionerna" + +#: storage/lmgr/predicate.c:4077 storage/lmgr/predicate.c:4166 +#: storage/lmgr/predicate.c:4174 storage/lmgr/predicate.c:4213 +#: storage/lmgr/predicate.c:4456 storage/lmgr/predicate.c:4793 +#: storage/lmgr/predicate.c:4805 storage/lmgr/predicate.c:4848 +#: storage/lmgr/predicate.c:4886 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Transaktionen kan lyckas om den körs igen." + +#: storage/lmgr/proc.c:359 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "antalet efterfrÃ¥gade standby-anslutningar överskrider max_wal_senders (nu %d)" + +#: storage/lmgr/proc.c:1335 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "Process %d väntar pÃ¥ %s för %s." + +#: storage/lmgr/proc.c:1346 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "skickar avbryt till blockerande autovacuum-PID %d" + +#: storage/lmgr/proc.c:1466 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "process %d undvek deadlock pÃ¥ %s för %s genom att kasta om köordningen efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1481 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "process %d upptäckte deadlock medan den väntade pÃ¥ %s för %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1490 +#, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "process %d väntar fortfarande pÃ¥ %s för %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1497 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "process %d fick %s pÃ¥ %s efter %ld.%03d ms" + +#: storage/lmgr/proc.c:1513 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "process %d misslyckades att ta %s pÃ¥ %s efter %ld.%03d ms" + +#: storage/page/bufpage.c:152 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "sidverifiering misslyckades, beräknade kontrollsumma %u men förväntade %u" + +#: storage/page/bufpage.c:216 storage/page/bufpage.c:510 +#: storage/page/bufpage.c:747 storage/page/bufpage.c:880 +#: storage/page/bufpage.c:976 storage/page/bufpage.c:1086 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "korrupta sidpekare: lägre = %u, övre = %u, special = %u" + +#: storage/page/bufpage.c:532 +#, c-format +msgid "corrupted line pointer: %u" +msgstr "korrupt radpekare: %u" + +#: storage/page/bufpage.c:559 storage/page/bufpage.c:931 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "trasiga postlängder: totalt %u, tillgänglig plats %u" + +#: storage/page/bufpage.c:766 storage/page/bufpage.c:904 +#: storage/page/bufpage.c:992 storage/page/bufpage.c:1102 +#, c-format +msgid "corrupted line pointer: offset = %u, size = %u" +msgstr "korrupt radpekare: offset = %u, storlek = %u" + +#: storage/smgr/md.c:320 storage/smgr/md.c:815 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "kunde inte trunkera fil \"%s\": %m" + +#: storage/smgr/md.c:394 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "kan inte utöka fil \"%s\" utöver %u block" + +#: storage/smgr/md.c:409 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "kunde inte utöka fil \"%s\": %m" + +#: storage/smgr/md.c:411 storage/smgr/md.c:418 storage/smgr/md.c:698 +#, c-format +msgid "Check free disk space." +msgstr "Kontrollera ledigt diskutrymme." + +#: storage/smgr/md.c:415 +#, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "kunde inte utöka fil \"%s\": skrev bara %d av %d byte vid block %u" + +#: storage/smgr/md.c:619 +#, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "kunde inte läsa block %u i fil \"%s\": %m" + +#: storage/smgr/md.c:635 +#, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "kunde inte läsa block %u i fil \"%s\": läste bara %d av %d byte" + +#: storage/smgr/md.c:689 +#, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "kunde inte skriva block %u i fil \"%s\": %m" + +#: storage/smgr/md.c:694 +#, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "kunde inte skriva block %u i fil \"%s\": skrev bara %d av %d byte" + +#: storage/smgr/md.c:786 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "kunde inte trunkera fil \"%s\" till %u block: den är bara %u block nu" + +#: storage/smgr/md.c:841 +#, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u block: %m" + +#: storage/smgr/md.c:913 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "kunde inte skicka vidare fsync-förfrÃ¥gan dÃ¥ kön för förfrÃ¥gningar är full" + +#: storage/smgr/md.c:1210 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "kunde inte öppna fil \"%s\" (mÃ¥lblock %u): föregÃ¥ende segment är bara %u block" + +#: storage/smgr/md.c:1224 +#, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "kunde inte öppna fil \"%s\" (mÃ¥lblock %u): %m" + +#: storage/sync/sync.c:400 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "kunde inte fsync:a fil \"%s\" men försöker igen: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "ogiltig argumentstorlek %d i funktionsaropsmeddelande" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "fastpath funktionsanrop: \"%s\" (OID %u)" + +#: tcop/fastpath.c:389 tcop/postgres.c:1288 tcop/postgres.c:1551 +#: tcop/postgres.c:1918 tcop/postgres.c:2139 +#, c-format +msgid "duration: %s ms" +msgstr "varaktighet %s ms" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "varaktighet: %s ms fastpath funktionsanrop: \"%s\" (OID %u)" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "meddelande för funktionsanrop innehÃ¥ller %d argument men funktionen kräver %d" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "meddelande för funktioonsanrop innehÃ¥ller %d argumentformat men %d argument" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "inkorrekt binärt dataformat i funktionsargument %d" + +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "oväntat EOF frÃ¥n klienten" + +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4473 +#, c-format +msgid "invalid frontend message type %d" +msgstr "ogiltig frontend-meddelandetyp %d" + +#: tcop/postgres.c:1043 +#, c-format +msgid "statement: %s" +msgstr "sats: %s" + +#: tcop/postgres.c:1293 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "varaktighet: %s ms sats: %s" + +#: tcop/postgres.c:1343 +#, c-format +msgid "parse %s: %s" +msgstr "parse %s: %s" + +#: tcop/postgres.c:1400 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "kan inte stoppa in multipla kommandon i en förberedd sats" + +#: tcop/postgres.c:1556 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "varaktighet: %s ms parse %s: %s" + +#: tcop/postgres.c:1601 +#, c-format +msgid "bind %s to %s" +msgstr "bind %s till %s" + +#: tcop/postgres.c:1620 tcop/postgres.c:2444 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "förberedd sats utan namn existerar inte" + +#: tcop/postgres.c:1661 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "bind-meddelande har %d parameterformat men %d parametrar" + +#: tcop/postgres.c:1667 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "bind-meddelande ger %d parametrar men förberedd sats \"%s\" kräver %d" + +#: tcop/postgres.c:1827 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "inkorrekt binärdataformat i bind-parameter %d" + +#: tcop/postgres.c:1923 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "varaktighet: %s ms bind %s%s%s: %s" + +#: tcop/postgres.c:1971 tcop/postgres.c:2528 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "portal \"%s\" existerar inte" + +#: tcop/postgres.c:2056 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2058 tcop/postgres.c:2147 +msgid "execute fetch from" +msgstr "kör hämtning frÃ¥n" + +#: tcop/postgres.c:2059 tcop/postgres.c:2148 +msgid "execute" +msgstr "kör" + +#: tcop/postgres.c:2144 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "varaktighet: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2285 +#, c-format +msgid "prepare: %s" +msgstr "prepare: %s" + +#: tcop/postgres.c:2350 +#, c-format +msgid "parameters: %s" +msgstr "parametrar: %s" + +#: tcop/postgres.c:2369 +#, c-format +msgid "abort reason: recovery conflict" +msgstr "abortskäl: Ã¥terställningskonflikt" + +#: tcop/postgres.c:2385 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "Användaren höll delad bufferfastlÃ¥sning för länge." + +#: tcop/postgres.c:2388 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "Användare höll ett relationslÃ¥s för länge." + +#: tcop/postgres.c:2391 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "Användaren använde eller har använt ett tablespace som tagits bort." + +#: tcop/postgres.c:2394 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "AnvändarfrÃ¥gan kan ha behövt se radversioner som har tagits bort." + +#: tcop/postgres.c:2400 +#, c-format +msgid "User was connected to a database that must be dropped." +msgstr "Användare var ansluten till databas som mÃ¥ste slängas." + +#: tcop/postgres.c:2724 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "avbryter anslutning pÃ¥ grund av en krash i en annan serverprocess" + +#: tcop/postgres.c:2725 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Postmastern har sagt Ã¥t denna serverprocess att rulla tillbaka den aktuella transaktionen och avsluta dÃ¥ en annan process har avslutats onormalt och har eventuellt trasat sönder delat minne." + +#: tcop/postgres.c:2729 tcop/postgres.c:3053 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "Du kan strax Ã¥teransluta till databasen och upprepa kommandot." + +#: tcop/postgres.c:2811 +#, c-format +msgid "floating-point exception" +msgstr "flyttalsavbrott" + +#: tcop/postgres.c:2812 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "En ogiltig flyttalsoperation har signalerats. Detta beror troligen pÃ¥ ett resultat som är utanför giltigt intervall eller en ogiltig operation sÃ¥ som division med noll." + +#: tcop/postgres.c:2983 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "avbryter autentisering pÃ¥ grund av timeout" + +#: tcop/postgres.c:2987 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "avslutar autovacuum-process pÃ¥ grund av ett administratörskommando" + +#: tcop/postgres.c:2991 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "avslutar logisk replikeringsarbetare pÃ¥ grund av ett administratörskommando" + +#: tcop/postgres.c:2995 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "logisk replikeringsuppstartare stänger ner" + +#: tcop/postgres.c:3008 tcop/postgres.c:3018 tcop/postgres.c:3051 +#, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "avslutar anslutning pÃ¥ grund av konflikt med Ã¥terställning" + +#: tcop/postgres.c:3024 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "avslutar anslutning pÃ¥ grund av ett administratörskommando" + +#: tcop/postgres.c:3034 +#, c-format +msgid "connection to client lost" +msgstr "anslutning till klient har brutits" + +#: tcop/postgres.c:3100 +#, c-format +msgid "canceling statement due to lock timeout" +msgstr "avbryter sats pÃ¥ grund av lÃ¥s-timeout" + +#: tcop/postgres.c:3107 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "avbryter sats pÃ¥ grund av sats-timeout" + +#: tcop/postgres.c:3114 +#, c-format +msgid "canceling autovacuum task" +msgstr "avbryter autovacuum-uppgift" + +#: tcop/postgres.c:3137 +#, c-format +msgid "canceling statement due to user request" +msgstr "avbryter sats pÃ¥ användares begäran" + +#: tcop/postgres.c:3147 +#, c-format +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "terminerar anslutning pÃ¥ grund av idle-in-transaction-timeout" + +#: tcop/postgres.c:3261 +#, c-format +msgid "stack depth limit exceeded" +msgstr "maximalt stackdjup överskridet" + +#: tcop/postgres.c:3262 +#, c-format +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "Öka konfigurationsparametern \"max_stack_depth\" (nu %dkB) efter att ha undersökt att plattformens gräns för stackdjup är tillräcklig." + +#: tcop/postgres.c:3325 +#, c-format +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\" fÃ¥r ej överskrida %ldkB." + +#: tcop/postgres.c:3327 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "Öka plattformens stackdjupbegränsning via \"ulimit -s\" eller motsvarande." + +#: tcop/postgres.c:3687 +#, c-format +msgid "invalid command-line argument for server process: %s" +msgstr "ogiltigt kommandoradsargument för serverprocess: %s" + +#: tcop/postgres.c:3688 tcop/postgres.c:3694 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Försök med \"%s --help\" för mer information." + +#: tcop/postgres.c:3692 +#, c-format +msgid "%s: invalid command-line argument: %s" +msgstr "%s: ogiltigt kommandoradsargument: %s" + +#: tcop/postgres.c:3754 +#, c-format +msgid "%s: no database nor user name specified" +msgstr "%s: ingen databas eller användarnamn angivet" + +#: tcop/postgres.c:4381 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "ogiltig subtyp %d för CLOSE-meddelande" + +#: tcop/postgres.c:4416 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "ogiltig subtyp %d för DESCRIBE-meddelande" + +#: tcop/postgres.c:4494 +#, c-format +msgid "fastpath function calls not supported in a replication connection" +msgstr "fastpath-funktionsanrop stöds inte i en replikeringsanslutning" + +#: tcop/postgres.c:4498 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "utökat frÃ¥geprotokoll stöds inte i en replikeringsanslutning" + +#: tcop/postgres.c:4675 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "nedkoppling: sessionstid: %d:%02d:%02d.%03d användare=%s databas=%s värd=%s%s%s" + +#: tcop/pquery.c:642 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "bind-meddelande har %d resultatformat men frÃ¥gan har %d kolumner" + +#: tcop/pquery.c:949 +#, c-format +msgid "cursor can only scan forward" +msgstr "markör kan bara hoppa framÃ¥t" + +#: tcop/pquery.c:950 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Deklarera den med flaggan SCROLL för att kunna traversera bakÃ¥t." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:245 +#, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "kan inte köra %s i read-only-transaktion" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:263 +#, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "kan inte köra %s under parallell operation" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:282 +#, c-format +msgid "cannot execute %s during recovery" +msgstr "kan inte köra %s under Ã¥terställning" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:300 +#, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "kan inte köra %s inom säkerhetsbegränsad operation" + +#: tcop/utility.c:760 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "mÃ¥ste vara superanvändare för att göra CHECKPOINT" + +#: tcop/utility.c:1353 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "kan inte skapa index för partitionerad tabell \"%s\"" + +#: tcop/utility.c:1355 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "Tabell \"%s\" innehÃ¥ller partitioner som är främmande tabeller." + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 +#, c-format +msgid "multiple DictFile parameters" +msgstr "multipla DictFile-parametrar" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "multipla AffFile-parametrar" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "okänd Ispell-parameter: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "saknar AffFile-parameter" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing DictFile parameter" +msgstr "saknar DictFile-parameter" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "multipla Accept-parametrar" + +#: tsearch/dict_simple.c:66 +#, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "okänd parameter för \"simple dictionary\": \"%s\"" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "okänd synonymparameter: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "saknar Synonym-prameter" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "kunde inte öppna synonymfil \"%s\": %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "kunde inte öppna synonymordboksfil \"%s\": %m" + +#: tsearch/dict_thesaurus.c:212 +#, c-format +msgid "unexpected delimiter" +msgstr "oväntad avdelare" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "oväntat slut pÃ¥ raden eller lexem" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "oväntat slut pÃ¥ raden" + +#: tsearch/dict_thesaurus.c:297 +#, c-format +msgid "too many lexemes in thesaurus entry" +msgstr "för mÃ¥nga lexem i synonymordbokspost" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "synonymordbokens exempelord \"%s\" känns inte igen av underordbok (regel %d)" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "synonymordbokens exempelord \"%s\" är ett stoppord (regel %d)" + +#: tsearch/dict_thesaurus.c:430 +#, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Använd \"?\" för att representera ett stoppord i en exempelfras." + +#: tsearch/dict_thesaurus.c:576 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "synonymordbokens ersättningsord \"%s\" är ett stoppord (regel %d)" + +#: tsearch/dict_thesaurus.c:583 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "synonymordbokens ersättningsord \"%s\" känns inte igen av underordbok (regel %d)" + +#: tsearch/dict_thesaurus.c:595 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "synonymordbokens ersättningsfras är tim (regel %d)" + +#: tsearch/dict_thesaurus.c:633 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "multipla ordboksparametrar" + +#: tsearch/dict_thesaurus.c:640 +#, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "okänd synonymordboksparameter: \"%s\"" + +#: tsearch/dict_thesaurus.c:652 +#, c-format +msgid "missing Dictionary parameter" +msgstr "saknar ordlistparameter" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 +#: tsearch/spell.c:1034 +#, c-format +msgid "invalid affix flag \"%s\"" +msgstr "ogiltig affix-flagga \"%s\"" + +#: tsearch/spell.c:384 tsearch/spell.c:1038 +#, c-format +msgid "affix flag \"%s\" is out of range" +msgstr "affix-flaggan \"%s\" är utanför giltigt intervall" + +#: tsearch/spell.c:414 +#, c-format +msgid "invalid character in affix flag \"%s\"" +msgstr "ogiltigt tecken i affix-flagga \"%s\"" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "ogiltig affix-flagga \"%s\" med flaggvärdet \"long\"" + +#: tsearch/spell.c:522 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "kunde inte öppna ordboksfil \"%s\": %m" + +#: tsearch/spell.c:740 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "ogiltigt reguljärt uttryck: %s" + +#: tsearch/spell.c:1161 tsearch/spell.c:1726 +#, c-format +msgid "invalid affix alias \"%s\"" +msgstr "ogiltigt affix-alias \"%s\"" + +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "kunde inte öppna affix-fil \"%s\": %m" + +#: tsearch/spell.c:1265 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell-ordbok stöder bara flaggorna \"default\", \"long\" och \"num\"" + +#: tsearch/spell.c:1309 +#, c-format +msgid "invalid number of flag vector aliases" +msgstr "ogiltigt antal alias i flaggvektor" + +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "antalet alias överskriver angivet antal %d" + +#: tsearch/spell.c:1547 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "affix-fil innehÃ¥ller kommandon pÃ¥ gammalt och nytt format" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1132 +#, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "strängen är för lÃ¥ng för tsvector (%d byte, max %d byte)" + +#: tsearch/ts_locale.c:185 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "rad %d i konfigureringsfil \"%s\": \"%s\"" + +#: tsearch/ts_locale.c:302 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "konvertering frÃ¥n wchar_t till serverkodning misslyckades: %m" + +#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:566 +#: tsearch/ts_parse.c:573 +#, c-format +msgid "word is too long to be indexed" +msgstr "ordet är för lÃ¥ngt för att indexeras" + +#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:567 +#: tsearch/ts_parse.c:574 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "Ord längre än %d tecken hoppas över." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "ogiltigt filnamn \"%s\" till textsökkonfiguration" + +#: tsearch/ts_utils.c:83 +#, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "kunde inte öppna stoppordsfil \"%s\": %m" + +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 +#, c-format +msgid "text search parser does not support headline creation" +msgstr "textsökparsern stöder inte skapande av rubriker" + +#: tsearch/wparser_def.c:2486 +#, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "okänd rubrikparameter: \"%s\"" + +#: tsearch/wparser_def.c:2495 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords skall vara mindre än MaxWords" + +#: tsearch/wparser_def.c:2499 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords skall vara positiv" + +#: tsearch/wparser_def.c:2503 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord skall vara >= 0" + +#: tsearch/wparser_def.c:2507 +#, c-format +msgid "MaxFragments should be >= 0" +msgstr "MaxFragments skall vara >= 0" + +#: utils/adt/acl.c:171 utils/adt/name.c:93 +#, c-format +msgid "identifier too long" +msgstr "identifieraren för lÃ¥ng" + +#: utils/adt/acl.c:172 utils/adt/name.c:94 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Identifierare mÃ¥ste vara mindre än %d tecken." + +#: utils/adt/acl.c:258 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "okänt nyckelord: \"%s\"" + +#: utils/adt/acl.c:259 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL-nyckelord mÃ¥ste vara \"group\" eller \"user\"." + +#: utils/adt/acl.c:264 +#, c-format +msgid "missing name" +msgstr "namn saknas" + +#: utils/adt/acl.c:265 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "Ett namn mÃ¥ste följa efter nyckelorden \"group\" resp. \"user\"." + +#: utils/adt/acl.c:271 +#, c-format +msgid "missing \"=\" sign" +msgstr "saknar \"=\"-tecken" + +#: utils/adt/acl.c:324 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "ogiltigt lägestecken: mÃ¥ste vara en av \"%s\"" + +#: utils/adt/acl.c:346 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "ett namn mÃ¥ste följa pÃ¥ tecknet \"/\"" + +#: utils/adt/acl.c:354 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "sätter fullmaktsgivaranvändar-ID till standardvärdet %u" + +#: utils/adt/acl.c:545 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL-array innehÃ¥ller fel datatyp" + +#: utils/adt/acl.c:549 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL-array:er mÃ¥ste vara endimensionella" + +#: utils/adt/acl.c:553 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL-array:er fÃ¥r inte innehÃ¥lla null-värden" + +#: utils/adt/acl.c:577 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "skräp vid slutet av ACL-angivelse" + +#: utils/adt/acl.c:1212 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "fullmaksgivarflaggor kan inte ges tillbaka till den som givit det till dig" + +#: utils/adt/acl.c:1273 +#, c-format +msgid "dependent privileges exist" +msgstr "det finns beroende privilegier" + +#: utils/adt/acl.c:1274 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Använd CASCADE för att Ã¥terkalla dem med." + +#: utils/adt/acl.c:1536 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert stöds inte länge" + +#: utils/adt/acl.c:1546 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove stöds inte längre" + +#: utils/adt/acl.c:1632 utils/adt/acl.c:1686 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "okänd privilegietyp: \"%s\"" + +#: utils/adt/acl.c:3486 utils/adt/regproc.c:102 utils/adt/regproc.c:277 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "funktionen \"%s\" finns inte" + +#: utils/adt/acl.c:4958 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "mÃ¥ste vara medlem i rollen \"%s\"" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5909 +#: utils/adt/arrayfuncs.c:6250 utils/adt/arrayutils.c:93 +#: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "array-storlek överskrider maximalt tillÃ¥tna (%d)" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1094 utils/adt/jsonb.c:1123 +#: utils/adt/jsonb.c:1517 utils/adt/jsonb.c:1681 utils/adt/jsonb.c:1691 +#, c-format +msgid "could not determine input data type" +msgstr "kan inte bestämma indatatyp" + +#: utils/adt/array_userfuncs.c:85 +#, c-format +msgid "input data type is not an array" +msgstr "indatatyp är inte en array" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1220 utils/adt/float.c:1308 +#: utils/adt/float.c:3883 utils/adt/float.c:3897 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int8.c:1167 utils/adt/numeric.c:1565 +#: utils/adt/numeric.c:3240 utils/adt/varbit.c:1183 utils/adt/varbit.c:1585 +#: utils/adt/varlena.c:1075 utils/adt/varlena.c:3362 +#, c-format +msgid "integer out of range" +msgstr "heltal utanför giltigt intervall" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "argumentet mÃ¥ste vara tomt eller en endimensionell array" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "kan inte konkatenera inkompatibla arrayer" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Array:er med elementtyper %s och %s är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Array:er med dimensioner %d och %d är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Array:er med olika elementdimensioner är inte kompatibla för sammaslagning." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Array:er med olika dimensioner fungerar inte vid konkatenering." + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, c-format +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "sökning efter element i en multidimensionell array stöds inte" + +#: utils/adt/array_userfuncs.c:686 +#, c-format +msgid "initial position must not be null" +msgstr "initiala positionen fÃ¥r ej vara null" + +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "felaktig array-literal: \"%s\"" + +#: utils/adt/arrayfuncs.c:270 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "\"[\" mÃ¥ste införa explicit angivna array-dimensioner." + +#: utils/adt/arrayfuncs.c:284 +#, c-format +msgid "Missing array dimension value." +msgstr "Saknar värde i array-dimension." + +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 +#, c-format +msgid "Missing \"%s\" after array dimensions." +msgstr "Saknar \"%s\" efter array-dimensioner." + +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "övre gränsen kan inte vara lägre än undre gränsen" + +#: utils/adt/arrayfuncs.c:317 +#, c-format +msgid "Array value must start with \"{\" or dimension information." +msgstr "Array-värde mÃ¥ste starta med \"{\" eller dimensionsinformation" + +#: utils/adt/arrayfuncs.c:346 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "Array-innehÃ¥ll mÃ¥ste starta med \"{\"." + +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#, c-format +msgid "Specified array dimensions do not match array contents." +msgstr "Angivna array-dimensioner matchar inte array-innehÃ¥llet." + +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2179 utils/adt/rangetypes.c:2187 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 +#, c-format +msgid "Unexpected end of input." +msgstr "oväntat slut pÃ¥ indata." + +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 +#, c-format +msgid "Unexpected \"%c\" character." +msgstr "oväntat tecken \"%c\"." + +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 +#, c-format +msgid "Unexpected array element." +msgstr "Oväntat array-element." + +#: utils/adt/arrayfuncs.c:590 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "Icke matchat tecken \"%c\"." + +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 +#, c-format +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "Flerdimensionella array:er mÃ¥ste ha underarray:er med matchande dimensioner." + +#: utils/adt/arrayfuncs.c:675 +#, c-format +msgid "Junk after closing right brace." +msgstr "Skräp efter avslutande höger parentes." + +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5815 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "felaktigt antal dimensioner: %d" + +#: utils/adt/arrayfuncs.c:1308 +#, c-format +msgid "invalid array flags" +msgstr "ogiltiga array-flaggor" + +#: utils/adt/arrayfuncs.c:1316 +#, c-format +msgid "wrong element type" +msgstr "fel elementtyp" + +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2725 +#, c-format +msgid "no binary input function available for type %s" +msgstr "ingen binär indatafunktion finns för typen %s" + +#: utils/adt/arrayfuncs.c:1506 +#, c-format +msgid "improper binary format in array element %d" +msgstr "felaktigt binärt format i array-element %d" + +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2758 +#, c-format +msgid "no binary output function available for type %s" +msgstr "det saknas en binär output-funktion för typen %s" + +#: utils/adt/arrayfuncs.c:2065 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "slice av fixlängd-array är inte implementerat" + +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5801 +#: utils/adt/arrayfuncs.c:5827 utils/adt/arrayfuncs.c:5838 +#: utils/adt/json.c:2325 utils/adt/json.c:2400 utils/adt/jsonb.c:1295 +#: utils/adt/jsonb.c:1381 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 +#, c-format +msgid "wrong number of array subscripts" +msgstr "fel antal array-indexeringar" + +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 +#, c-format +msgid "array subscript out of range" +msgstr "array-index utanför giltigt omrÃ¥de" + +#: utils/adt/arrayfuncs.c:2253 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "kan inte tilldela null-värde till ett element i en array med fast längd" + +#: utils/adt/arrayfuncs.c:2808 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "uppdatering av slice pÃ¥ fixlängd-array är inte implementerat" + +#: utils/adt/arrayfuncs.c:2839 +#, c-format +msgid "array slice subscript must provide both boundaries" +msgstr "array-slice-index mÃ¥ste inkludera bÃ¥da gränser" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "Vid tilldelning till en slice av en tom array sÃ¥ mÃ¥ste slice-gränserna anges" + +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 +#, c-format +msgid "source array too small" +msgstr "käll-array för liten" + +#: utils/adt/arrayfuncs.c:3499 +#, c-format +msgid "null array element not allowed in this context" +msgstr "null-element i arrayer stöds inte i detta kontext" + +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4123 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "kan inte jämföra arrayer med olika elementtyper" + +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 +#, c-format +msgid "could not identify a hash function for type %s" +msgstr "kunde inte hitta en hash-funktion för typ %s" + +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "kunde inte hitta en utökad hash-funktion för typ %s" + +#: utils/adt/arrayfuncs.c:5215 +#, c-format +msgid "data type %s is not an array type" +msgstr "datatypen %s är inte en arraytyp" + +#: utils/adt/arrayfuncs.c:5270 +#, c-format +msgid "cannot accumulate null arrays" +msgstr "kan inte ackumulera null-array:er" + +#: utils/adt/arrayfuncs.c:5298 +#, c-format +msgid "cannot accumulate empty arrays" +msgstr "kan inte ackumulera tomma array:er" + +#: utils/adt/arrayfuncs.c:5327 utils/adt/arrayfuncs.c:5333 +#, c-format +msgid "cannot accumulate arrays of different dimensionality" +msgstr "kan inte ackumulera arrayer med olika dimensioner" + +#: utils/adt/arrayfuncs.c:5699 utils/adt/arrayfuncs.c:5739 +#, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "dimensionsarray eller undre gränsarray kan inte vara null" + +#: utils/adt/arrayfuncs.c:5802 utils/adt/arrayfuncs.c:5828 +#, c-format +msgid "Dimension array must be one dimensional." +msgstr "Dimensionsarray mÃ¥ste vara endimensionell." + +#: utils/adt/arrayfuncs.c:5807 utils/adt/arrayfuncs.c:5833 +#, c-format +msgid "dimension values cannot be null" +msgstr "dimensionsvärden kan inte vara null" + +#: utils/adt/arrayfuncs.c:5839 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "Undre arraygräns har annan storlek än dimensionsarray." + +#: utils/adt/arrayfuncs.c:6115 +#, c-format +msgid "removing elements from multidimensional arrays is not supported" +msgstr "borttagning av element frÃ¥n en multidimensionell array stöds inte" + +#: utils/adt/arrayfuncs.c:6392 +#, c-format +msgid "thresholds must be one-dimensional array" +msgstr "gränsvärden mÃ¥ste vara en endimensionell array" + +#: utils/adt/arrayfuncs.c:6397 +#, c-format +msgid "thresholds array must not contain NULLs" +msgstr "gränsvärdesarray fÃ¥r inte innehÃ¥lla NULLL-värden" + +#: utils/adt/arrayutils.c:209 +#, c-format +msgid "typmod array must be type cstring[]" +msgstr "typmod-array mÃ¥ste ha typ cstring[]" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "typmod-array mÃ¥ste vara endimensionell" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "typmod-arrayen fÃ¥r inte innehÃ¥lla null-värden" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "kodningskonvertering frÃ¥n %s till ASCII stöds inte" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3787 +#: utils/adt/float.c:168 utils/adt/float.c:252 utils/adt/float.c:276 +#: utils/adt/float.c:390 utils/adt/float.c:474 utils/adt/float.c:501 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3360 utils/adt/geo_ops.c:4526 +#: utils/adt/geo_ops.c:4541 utils/adt/geo_ops.c:4548 utils/adt/int8.c:128 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:74 utils/adt/numeric.c:607 +#: utils/adt/numeric.c:634 utils/adt/numeric.c:5806 utils/adt/numeric.c:5830 +#: utils/adt/numeric.c:5854 utils/adt/numeric.c:6684 utils/adt/numeric.c:6710 +#: utils/adt/numutils.c:52 utils/adt/numutils.c:62 utils/adt/numutils.c:106 +#: utils/adt/numutils.c:182 utils/adt/numutils.c:258 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:43 utils/adt/pg_lsn.c:49 utils/adt/tid.c:73 +#: utils/adt/tid.c:81 utils/adt/tid.c:89 utils/adt/timestamp.c:495 +#: utils/adt/txid.c:410 utils/adt/uuid.c:136 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "ogiltig indatasyntax för type %s: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:120 utils/adt/numutils.c:76 +#: utils/adt/numutils.c:83 utils/adt/numutils.c:176 utils/adt/numutils.c:252 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 +#, c-format +msgid "value \"%s\" is out of range for type %s" +msgstr "värdet \"%s\" är utanför giltigt intervall för typen %s" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/int.c:824 utils/adt/int.c:940 utils/adt/int.c:1020 +#: utils/adt/int.c:1082 utils/adt/int.c:1120 utils/adt/int.c:1148 +#: utils/adt/int8.c:595 utils/adt/int8.c:653 utils/adt/int8.c:853 +#: utils/adt/int8.c:933 utils/adt/int8.c:995 utils/adt/int8.c:1075 +#: utils/adt/numeric.c:7248 utils/adt/numeric.c:7537 utils/adt/numeric.c:8549 +#: utils/adt/timestamp.c:3279 +#, c-format +msgid "division by zero" +msgstr "division med noll" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\" utanför sitt intervall" + +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:55 +#: utils/adt/varchar.c:49 +#, c-format +msgid "invalid type modifier" +msgstr "ogiltig typmodifierare" + +#: utils/adt/date.c:77 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s-precisionen fÃ¥r inte vara negativ" + +#: utils/adt/date.c:83 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s-precisionen reducerad till maximalt tillÃ¥tna, %d" + +#: utils/adt/date.c:144 utils/adt/datetime.c:1192 utils/adt/datetime.c:2103 +#, c-format +msgid "date/time value \"current\" is no longer supported" +msgstr "datum/tid-värde \"current\" stöds inte längre" + +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3733 +#: utils/adt/formatting.c:3742 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "datum utanför giltigt intervall \"%s\"" + +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2228 +#, c-format +msgid "date out of range" +msgstr "datum utanför giltigt intervall" + +#: utils/adt/date.c:271 utils/adt/timestamp.c:575 +#, c-format +msgid "date field value out of range: %d-%02d-%02d" +msgstr "datumfältvärde utanför giltigt omrÃ¥de: %d-%02d-%02d" + +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:581 +#, c-format +msgid "date out of range: %d-%02d-%02d" +msgstr "datum utanför giltigt omrÃ¥de: %d-%02d-%02d" + +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1665 +#: utils/adt/date.c:1696 utils/adt/date.c:1725 utils/adt/date.c:2557 +#: utils/adt/datetime.c:1676 utils/adt/formatting.c:3599 +#: utils/adt/formatting.c:3631 utils/adt/formatting.c:3708 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/timestamp.c:230 +#: utils/adt/timestamp.c:262 utils/adt/timestamp.c:703 +#: utils/adt/timestamp.c:712 utils/adt/timestamp.c:790 +#: utils/adt/timestamp.c:823 utils/adt/timestamp.c:2858 +#: utils/adt/timestamp.c:2879 utils/adt/timestamp.c:2892 +#: utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2909 +#: utils/adt/timestamp.c:2964 utils/adt/timestamp.c:2987 +#: utils/adt/timestamp.c:3000 utils/adt/timestamp.c:3011 +#: utils/adt/timestamp.c:3019 utils/adt/timestamp.c:3679 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3845 +#: utils/adt/timestamp.c:3935 utils/adt/timestamp.c:3979 +#: utils/adt/timestamp.c:4082 utils/adt/timestamp.c:4566 +#: utils/adt/timestamp.c:4665 utils/adt/timestamp.c:4675 +#: utils/adt/timestamp.c:4767 utils/adt/timestamp.c:4869 +#: utils/adt/timestamp.c:4879 utils/adt/timestamp.c:5099 +#: utils/adt/timestamp.c:5113 utils/adt/timestamp.c:5118 +#: utils/adt/timestamp.c:5132 utils/adt/timestamp.c:5165 +#: utils/adt/timestamp.c:5214 utils/adt/timestamp.c:5221 +#: utils/adt/timestamp.c:5254 utils/adt/timestamp.c:5258 +#: utils/adt/timestamp.c:5327 utils/adt/timestamp.c:5331 +#: utils/adt/timestamp.c:5345 utils/adt/timestamp.c:5379 utils/adt/xml.c:2250 +#: utils/adt/xml.c:2257 utils/adt/xml.c:2277 utils/adt/xml.c:2284 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp utanför giltigt intervall" + +#: utils/adt/date.c:512 +#, c-format +msgid "cannot subtract infinite dates" +msgstr "kan inte subtrahera oändliga datum" + +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2594 utils/adt/date.c:2604 +#, c-format +msgid "date out of range for timestamp" +msgstr "datum utanför filtigt omrÃ¥de för timestamp" + +#: utils/adt/date.c:1278 utils/adt/date.c:2052 +#, c-format +msgid "time out of range" +msgstr "time utanför giltigt intervall" + +#: utils/adt/date.c:1334 utils/adt/timestamp.c:600 +#, c-format +msgid "time field value out of range: %d:%02d:%02g" +msgstr "time-värde utanför giltigt omrÃ¥de: %d:%02d:%02g" + +#: utils/adt/date.c:1854 utils/adt/date.c:2356 utils/adt/float.c:1046 +#: utils/adt/float.c:1115 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:494 utils/adt/numeric.c:2203 +#: utils/adt/timestamp.c:3328 utils/adt/timestamp.c:3359 +#: utils/adt/timestamp.c:3390 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "ogiltig föregÃ¥ende eller efterföljande storlek i fönsterfunktion" + +#: utils/adt/date.c:1939 utils/adt/date.c:1952 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "känner inte igen \"time\"-enhet \"%s\"" + +#: utils/adt/date.c:2060 +#, c-format +msgid "time zone displacement out of range" +msgstr "tidszonförskjutning utanför giltigt intervall" + +#: utils/adt/date.c:2689 utils/adt/date.c:2702 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "känner inte igen \"time with time zone\" enhet \"%s\"" + +#: utils/adt/date.c:2775 utils/adt/datetime.c:914 utils/adt/datetime.c:1834 +#: utils/adt/datetime.c:4631 utils/adt/timestamp.c:514 +#: utils/adt/timestamp.c:541 utils/adt/timestamp.c:4165 +#: utils/adt/timestamp.c:5124 utils/adt/timestamp.c:5337 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "tidszon \"%s\" känns inte igen" + +#: utils/adt/date.c:2807 utils/adt/timestamp.c:5154 utils/adt/timestamp.c:5368 +#, c-format +msgid "interval time zone \"%s\" must not include months or days" +msgstr "intervalltidszonen \"%s\" kan inte inkludera mÃ¥nader eller Ã¥r" + +#: utils/adt/datetime.c:3760 utils/adt/datetime.c:3767 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "datum/tid-värde utanför giltigt omrÃ¥de: \"%s\"" + +#: utils/adt/datetime.c:3769 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Du kanske behöver en annan inställning av variabeln \"datestyle\"." + +#: utils/adt/datetime.c:3774 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "intervall-värde utanför giltigt omrÃ¥de: \"%s\"" + +#: utils/adt/datetime.c:3780 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "tidszonförskjutning itanför sitt intervall: \"%s\"" + +#: utils/adt/datetime.c:4633 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "Detta tidszonsnamn finns i konfigurationsfilen för tidszonsförkortning \"%s\"." + +#: utils/adt/datum.c:88 utils/adt/datum.c:100 +#, c-format +msgid "invalid Datum pointer" +msgstr "ogiltigt Datum-pekare" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, c-format +msgid "invalid size: \"%s\"" +msgstr "ogiltig storlek: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, c-format +msgid "Invalid size unit: \"%s\"." +msgstr "Ogiltig storleksenhet: \"%s\"." + +#: utils/adt/dbsize.c:829 +#, c-format +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Giltiga enheter är \"bytes\", \"kB\", \"MB\", \"GB\" och \"TB\"." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "typen %s är inte en domän" + +#: utils/adt/encode.c:55 utils/adt/encode.c:91 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "okänd kodning: \"%s\"" + +#: utils/adt/encode.c:150 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "ogiltigt hexdecimal siffra: \"%c\"" + +#: utils/adt/encode.c:178 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "ogiltig hexadecimal data: udda antal siffror" + +#: utils/adt/encode.c:295 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "oväntat \"=\" vid avkodning av base64-sekvens" + +#: utils/adt/encode.c:307 +#, c-format +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "ogiltig symbol \"%c\" vid avkodning av base64-sekvens" + +#: utils/adt/encode.c:327 +#, c-format +msgid "invalid base64 end sequence" +msgstr "ogiltig base64-slutsekvens" + +#: utils/adt/encode.c:328 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "Indata saknar paddning, är trunkerad eller är trasig pÃ¥ annat sätt." + +#: utils/adt/enum.c:100 +#, c-format +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "osäker användning av nytt värde \"%s\" i enum typ %s" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "Nya enum-värden mÃ¥ste commit:as innan de kan användas." + +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "ogiltigt indata-värde för enum %s: \"%s\"" + +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "ogiltigt internt värde för enum: %u" + +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 +#, c-format +msgid "could not determine actual enum type" +msgstr "kunde inte bestämma den verkliga enum-typen" + +#: utils/adt/enum.c:454 utils/adt/enum.c:483 +#, c-format +msgid "enum %s contains no values" +msgstr "enum %s innehÃ¥ller inga värden" + +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1574 utils/cache/typcache.c:1730 +#: utils/cache/typcache.c:1860 utils/fmgr/funcapi.c:415 +#, c-format +msgid "type %s is not composite" +msgstr "typen %s är inte composite" + +#: utils/adt/float.c:246 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "\"%s\" är utanför giltigt intervall för typen real" + +#: utils/adt/float.c:466 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "\"%s\" är utanför giltigt intervall för typen double precision" + +#: utils/adt/float.c:1252 utils/adt/float.c:1340 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1188 utils/adt/numeric.c:3358 utils/adt/numeric.c:3367 +#, c-format +msgid "smallint out of range" +msgstr "smallint utanför sitt intervall" + +#: utils/adt/float.c:1466 utils/adt/numeric.c:7970 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "kan inte ta kvadratroten av ett negativt tal" + +#: utils/adt/float.c:1527 utils/adt/numeric.c:3138 +#, c-format +msgid "zero raised to a negative power is undefined" +msgstr "noll upphöjt med ett negativt tal är odefinierat" + +#: utils/adt/float.c:1531 utils/adt/numeric.c:3144 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "ett negativt tal upphöjt i en icke-negativ potens ger ett komplext resultat" + +#: utils/adt/float.c:1597 utils/adt/float.c:1627 utils/adt/numeric.c:8236 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "kan inte ta logartimen av noll" + +#: utils/adt/float.c:1601 utils/adt/float.c:1631 utils/adt/numeric.c:8240 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "kan inte ta logaritmen av ett negativt tal" + +#: utils/adt/float.c:1661 utils/adt/float.c:1691 utils/adt/float.c:1783 +#: utils/adt/float.c:1809 utils/adt/float.c:1836 utils/adt/float.c:1862 +#: utils/adt/float.c:2009 utils/adt/float.c:2044 utils/adt/float.c:2208 +#: utils/adt/float.c:2262 utils/adt/float.c:2326 utils/adt/float.c:2381 +#: utils/adt/float.c:2569 utils/adt/float.c:2594 +#, c-format +msgid "input is out of range" +msgstr "indata är utanför giltigt intervall" + +#: utils/adt/float.c:2662 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "setseed-parameter %g är utanför giltigt intervall [-1,1]" + +#: utils/adt/float.c:2880 utils/adt/float.c:2956 utils/adt/float.c:3179 +#, c-format +msgid "value out of range: overflow" +msgstr "värde utanför giltigt intervall: overflow" + +#: utils/adt/float.c:3861 utils/adt/numeric.c:1515 +#, c-format +msgid "count must be greater than zero" +msgstr "antal mÃ¥ste vara större än noll" + +#: utils/adt/float.c:3866 utils/adt/numeric.c:1522 +#, c-format +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "operand, lägre gräns och övre gräns kan inte vara NaN" + +#: utils/adt/float.c:3872 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "lägre och övre gräns mÃ¥ste vara ändliga" + +#: utils/adt/float.c:3906 utils/adt/numeric.c:1535 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "lägre gräns kan inte vara samma som övre gräns" + +#: utils/adt/formatting.c:504 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "ogiltig formatspecifikation för ett intervallvärdei" + +#: utils/adt/formatting.c:505 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "Intervaller är inte kopplade till specifika kalenderdatum." + +#: utils/adt/formatting.c:1086 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "\"EEEE\" mÃ¥ste vara det sista mönstret som används" + +#: utils/adt/formatting.c:1094 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\" mÃ¥ste vara före \"PR\"" + +#: utils/adt/formatting.c:1110 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\" mÃ¥ste vara före \"PR\"" + +#: utils/adt/formatting.c:1137 +#, c-format +msgid "multiple decimal points" +msgstr "multipla decimalpunkter" + +#: utils/adt/formatting.c:1141 utils/adt/formatting.c:1224 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "kan inte använda \"V\" ach decimalpunkt tillsammans" + +#: utils/adt/formatting.c:1153 +#, c-format +msgid "cannot use \"S\" twice" +msgstr "kan inte använda \"S\" tvÃ¥ gÃ¥nger" + +#: utils/adt/formatting.c:1157 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "kan inte använda \"S\" och \"PL\"/\"MI\"/\"SG\"/\"PR\" tillsammans" + +#: utils/adt/formatting.c:1177 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "kan inte använda \"S\" och \"MI\" tillsammans." + +#: utils/adt/formatting.c:1187 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "kan inte använda \"S\" och \"PL\" tillsammans." + +#: utils/adt/formatting.c:1197 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "kan inte använda \"S\" och \"SG\" tillsammans." + +#: utils/adt/formatting.c:1206 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "kan inte använda \"PR\" och \"S\"/\"PL\"/\"MI\"/\"SG\" tillsammans." + +#: utils/adt/formatting.c:1232 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "kan inte använda \"EEEE\" tvÃ¥ gÃ¥nger" + +#: utils/adt/formatting.c:1238 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "\"EEEE\" är inkompatibel med andra format" + +#: utils/adt/formatting.c:1239 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "\"EEEE\" fÃ¥r bara användas tillsammans med siffror- och decimalpunkts-mönster." + +#: utils/adt/formatting.c:1426 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\" är inte ett nummer" + +#: utils/adt/formatting.c:1504 +#, c-format +msgid "case conversion failed: %s" +msgstr "case-konvertering misslyckades: %s" + +#: utils/adt/formatting.c:1569 utils/adt/formatting.c:1692 +#: utils/adt/formatting.c:1816 +#, c-format +msgid "could not determine which collation to use for %s function" +msgstr "kunde inte bestämma jämförelse (collation) för funktionen %s" + +#: utils/adt/formatting.c:2185 +#, c-format +msgid "invalid combination of date conventions" +msgstr "ogiltig kombination av datumkonventioner" + +#: utils/adt/formatting.c:2186 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "Blanda inte datumkonventionerna Gregoriansk och ISO-veckor i formatteringsmall." + +#: utils/adt/formatting.c:2203 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "värden för \"%s\" i formatsträng stÃ¥r i konflikt med varandra" + +#: utils/adt/formatting.c:2205 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "Detta värde motsäger en tidigare inställning för samma fälttyp." + +#: utils/adt/formatting.c:2266 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "källsträngen är för kort för formatfält \"%s\"" + +#: utils/adt/formatting.c:2268 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Fältet kräver %d tecken men bara %d Ã¥terstÃ¥r." + +#: utils/adt/formatting.c:2271 utils/adt/formatting.c:2285 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "Om din källsträng inte är av fast längd sÃ¥ testa med modifieraren \"FM\"." + +#: utils/adt/formatting.c:2281 utils/adt/formatting.c:2294 +#: utils/adt/formatting.c:2424 +#, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "ogiltigt värde \"%s\" för \"%s\"" + +#: utils/adt/formatting.c:2283 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "Fältet kräver %d tecken men bara %d kunde parsas." + +#: utils/adt/formatting.c:2296 +#, c-format +msgid "Value must be an integer." +msgstr "Värdet mÃ¥ste vara ett heltal." + +#: utils/adt/formatting.c:2301 +#, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "värdet för \"%s\" i källsträng är utanför giltigt intervall" + +#: utils/adt/formatting.c:2303 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Värdet mÃ¥ste vara i intervallet %d till %d." + +#: utils/adt/formatting.c:2426 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "Det givna värdet matchar inget av de tillÃ¥tna värdena för detta fält." + +#: utils/adt/formatting.c:2624 utils/adt/formatting.c:2644 +#: utils/adt/formatting.c:2664 utils/adt/formatting.c:2684 +#: utils/adt/formatting.c:2703 utils/adt/formatting.c:2722 +#: utils/adt/formatting.c:2746 utils/adt/formatting.c:2764 +#: utils/adt/formatting.c:2782 utils/adt/formatting.c:2800 +#: utils/adt/formatting.c:2817 utils/adt/formatting.c:2834 +#, c-format +msgid "localized string format value too long" +msgstr "lokaliserat strängformatvärde är för lÃ¥ngt" + +#: utils/adt/formatting.c:3176 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "formateringsfält \"%s\" stöds bara i to_char" + +#: utils/adt/formatting.c:3317 +#, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "ogiltig indatasträng för \"Y,YYY\"" + +#: utils/adt/formatting.c:3851 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "timmen \"%d\" är ogiltigt för en 12-timmars-klocka" + +#: utils/adt/formatting.c:3853 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Använd en 24-timmars-klocka eller ange en timme mellan 1 och 12." + +#: utils/adt/formatting.c:3959 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "kan inte beräkna dag pÃ¥ Ã¥ret utan Ã¥rsinformation" + +#: utils/adt/formatting.c:4866 +#, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"EEEE\" stöds inte för indata" + +#: utils/adt/formatting.c:4878 +#, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" stöds inte för indata" + +#: utils/adt/genfile.c:81 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "referens till föräldrakatalog (\"..\") tillÃ¥ts inte" + +#: utils/adt/genfile.c:92 +#, c-format +msgid "absolute path not allowed" +msgstr "absolut sökväg tillÃ¥ts inte" + +#: utils/adt/genfile.c:97 +#, c-format +msgid "path must be in or below the current directory" +msgstr "sökväg mÃ¥ste vara i eller under den aktuella katalogen" + +#: utils/adt/genfile.c:144 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "efterfrÃ¥gad längd är för lÃ¥ng" + +#: utils/adt/genfile.c:161 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "kunde inte söka (seek) i fil \"%s\": %m" + +#: utils/adt/genfile.c:221 +#, c-format +msgid "must be superuser to read files with adminpack 1.0" +msgstr "mÃ¥ste vara superanvändare för att läsa filer med adminpack 1.0" + +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 +#, c-format +msgid "invalid line specification: A and B cannot both be zero" +msgstr "ogiltig radangivelse: A och B kan inte bÃ¥da vara noll" + +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "ogiltig linjeangivelse: mÃ¥ste vara tvÃ¥ enskilda punkter" + +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3370 utils/adt/geo_ops.c:4238 +#: utils/adt/geo_ops.c:5129 +#, c-format +msgid "too many points requested" +msgstr "för mÃ¥nga punkter efterfrÃ¥gade" + +#: utils/adt/geo_ops.c:1461 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "ogiltigt antal punkter i externt \"path\"-värde" + +#: utils/adt/geo_ops.c:2459 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "funktionen \"dist_lb\" är inte implementerad" + +#: utils/adt/geo_ops.c:2859 +#, c-format +msgid "function \"close_sl\" not implemented" +msgstr "funktionen \"close_sl\" är inte implementerad" + +#: utils/adt/geo_ops.c:3006 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "funktionen \"close_lb\" är inte implementerad" + +#: utils/adt/geo_ops.c:3417 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "ogiltigt antal punkter i ett externt \"polygon\"-värde" + +#: utils/adt/geo_ops.c:3953 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "funktionen \"poly_distance\" är inte implementerad" + +#: utils/adt/geo_ops.c:4330 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "funktionen \"path_center\" är inte implementerad" + +#: utils/adt/geo_ops.c:4347 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "öppen väg kan inte konverteras till en polygon" + +#: utils/adt/geo_ops.c:4594 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "ogiltig radie i ett externt cirkelvärde" + +#: utils/adt/geo_ops.c:5115 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "kan inte konvertera en cirkel med radie noll till en polygon" + +#: utils/adt/geo_ops.c:5120 +#, c-format +msgid "must request at least 2 points" +msgstr "mÃ¥ste efterfrÃ¥ga minst 2 punkter" + +#: utils/adt/int.c:164 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector har för mÃ¥nga element" + +#: utils/adt/int.c:239 +#, c-format +msgid "invalid int2vector data" +msgstr "ogiltig int2vector-data" + +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector har för mÃ¥nga element" + +#: utils/adt/int.c:1383 utils/adt/int8.c:1328 utils/adt/numeric.c:1423 +#: utils/adt/timestamp.c:5430 utils/adt/timestamp.c:5511 +#, c-format +msgid "step size cannot equal zero" +msgstr "stegstorleken kan inte vara noll" + +#: utils/adt/int8.c:529 utils/adt/int8.c:552 utils/adt/int8.c:566 +#: utils/adt/int8.c:580 utils/adt/int8.c:611 utils/adt/int8.c:635 +#: utils/adt/int8.c:690 utils/adt/int8.c:704 utils/adt/int8.c:728 +#: utils/adt/int8.c:741 utils/adt/int8.c:810 utils/adt/int8.c:824 +#: utils/adt/int8.c:838 utils/adt/int8.c:869 utils/adt/int8.c:891 +#: utils/adt/int8.c:905 utils/adt/int8.c:919 utils/adt/int8.c:952 +#: utils/adt/int8.c:966 utils/adt/int8.c:980 utils/adt/int8.c:1011 +#: utils/adt/int8.c:1033 utils/adt/int8.c:1047 utils/adt/int8.c:1061 +#: utils/adt/int8.c:1230 utils/adt/int8.c:1272 utils/adt/numeric.c:3313 +#: utils/adt/varbit.c:1665 +#, c-format +msgid "bigint out of range" +msgstr "bigint utanför sitt intervall" + +#: utils/adt/int8.c:1285 +#, c-format +msgid "OID out of range" +msgstr "OID utanför sitt intervall" + +#: utils/adt/json.c:787 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "Tecken med värde 0x%02x mÃ¥ste escape:as." + +#: utils/adt/json.c:828 +#, c-format +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"\\u\" mÃ¥ste följas av fyra hexdecimala siffror." + +#: utils/adt/json.c:949 utils/adt/json.c:967 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "Escape-sekvens \"\\%s\" är ogiltig." + +#: utils/adt/json.c:1136 +#, c-format +msgid "The input string ended unexpectedly." +msgstr "Indatasträngen avslutades oväntat." + +#: utils/adt/json.c:1150 +#, c-format +msgid "Expected end of input, but found \"%s\"." +msgstr "Förväntade slut pÃ¥ indata, men hittade \"%s\"." + +#: utils/adt/json.c:1161 +#, c-format +msgid "Expected JSON value, but found \"%s\"." +msgstr "Förväntade JSON-värde, men hittade \"%s\"." + +#: utils/adt/json.c:1169 utils/adt/json.c:1217 +#, c-format +msgid "Expected string, but found \"%s\"." +msgstr "Förväntade sträng, men hittade \"%s\"." + +#: utils/adt/json.c:1177 +#, c-format +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "Färväntade array-element eller \"]\", men hittade \"%s\"." + +#: utils/adt/json.c:1185 +#, c-format +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "Förväntade \",\" eller \"]\", men hittade \"%s\"." + +#: utils/adt/json.c:1193 +#, c-format +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "Färväntade sträng eller \"}\", men hittade \"%s\"." + +#: utils/adt/json.c:1201 +#, c-format +msgid "Expected \":\", but found \"%s\"." +msgstr "Förväntade sig \":\" men hittade \"%s\"." + +#: utils/adt/json.c:1209 +#, c-format +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "Förväntade sig \",\" eller \"}\" men hittade \"%s\"." + +#: utils/adt/json.c:1247 +#, c-format +msgid "Token \"%s\" is invalid." +msgstr "Token \"%s\" är ogiltig." + +#: utils/adt/json.c:1319 +#, c-format +msgid "JSON data, line %d: %s%s%s" +msgstr "JSON-data, rad %d: %s%s%s" + +#: utils/adt/json.c:1475 utils/adt/jsonb.c:739 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "nyckelvärde mÃ¥ste vara skalär, inte array, composite eller json" + +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1549 +#, c-format +msgid "could not determine data type for argument %d" +msgstr "kunde inte lista ut datatypen för argument %d" + +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1707 +#, c-format +msgid "field name must not be null" +msgstr "fältnamnet fÃ¥r inte vara null" + +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1157 +#, c-format +msgid "argument list must have even number of elements" +msgstr "argumentlistan mÃ¥ste ha ett jämt antal element" + +#. translator: %s is a SQL function name +#: utils/adt/json.c:2196 utils/adt/jsonb.c:1159 +#, c-format +msgid "The arguments of %s must consist of alternating keys and values." +msgstr "Argumenten till %s mÃ¥ste bestÃ¥ av varannan nyckel och varannat värde." + +#: utils/adt/json.c:2212 +#, c-format +msgid "argument %d cannot be null" +msgstr "argument %d kan inte vara null" + +#: utils/adt/json.c:2213 +#, c-format +msgid "Object keys should be text." +msgstr "Objektnycklar skall vara text." + +#: utils/adt/json.c:2319 utils/adt/jsonb.c:1289 +#, c-format +msgid "array must have two columns" +msgstr "array:en mÃ¥ste ha tvÃ¥ kolumner" + +#: utils/adt/json.c:2343 utils/adt/json.c:2427 utils/adt/jsonb.c:1313 +#: utils/adt/jsonb.c:1408 +#, c-format +msgid "null value not allowed for object key" +msgstr "null-värde tillÃ¥ts inte som objektnyckel" + +#: utils/adt/json.c:2416 utils/adt/jsonb.c:1397 +#, c-format +msgid "mismatched array dimensions" +msgstr "array-dimensionerna stämmer inte" + +#: utils/adt/jsonb.c:269 +#, c-format +msgid "string too long to represent as jsonb string" +msgstr "strängen är för lÃ¥ng för att representeras som en jsonb-sträng" + +#: utils/adt/jsonb.c:270 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "PÃ¥ grund av en implementationsbegränsning sÃ¥ kan jsonb-strängar inte överstiga %d byte." + +#: utils/adt/jsonb.c:1172 +#, c-format +msgid "argument %d: key must not be null" +msgstr "argument %d: nyckeln fÃ¥r inte vara null" + +#: utils/adt/jsonb.c:1760 +#, c-format +msgid "object keys must be strings" +msgstr "objektnycklar mÃ¥ste vara strängar" + +#: utils/adt/jsonb.c:1923 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "kan inte typomvandla jsonb-null till type %s" + +#: utils/adt/jsonb.c:1924 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "kan inte typomvandla jsonb-sträng till typ %s" + +#: utils/adt/jsonb.c:1925 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "kan inte typomvandla jsonb-numeric till typ %s" + +#: utils/adt/jsonb.c:1926 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "kan inte typomvandla jsonb-boolean till typ %s" + +#: utils/adt/jsonb.c:1927 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "kan inte typomvandla jsonb-array till typ %s" + +#: utils/adt/jsonb.c:1928 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "kan inte typomvandla jsonb-objekt till typ %s" + +#: utils/adt/jsonb.c:1929 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "kan inte typomvandla jsonb-array eller objekt till typ %s" + +#: utils/adt/jsonb_util.c:657 +#, c-format +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "antalet jsonb-objektpar överskrider det maximalt tillÃ¥tna (%zu)" + +#: utils/adt/jsonb_util.c:698 +#, c-format +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "antalet jsonb-array-element överskrider det maximalt tillÃ¥tna (%zu)" + +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 +#, c-format +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "total storlek pÃ¥ elementen i jsonb-array överskrider maximala %u byte" + +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "total storlek pÃ¥ element i jsonb-objekt överskrider maximum pÃ¥ %u byte" + +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 +#, c-format +msgid "cannot call %s on a scalar" +msgstr "kan inte anropa %s pÃ¥ en skalär" + +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 +#, c-format +msgid "cannot call %s on an array" +msgstr "kan inte anropa %s pÃ¥ en array" + +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 +#, c-format +msgid "cannot get array length of a scalar" +msgstr "kan inte hämta array-längd pÃ¥ skalär" + +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 +#, c-format +msgid "cannot get array length of a non-array" +msgstr "kan inte hämta array-längd pÃ¥ icke-array" + +#: utils/adt/jsonfuncs.c:1691 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "kan inte anropa %s pÃ¥ ett icke-objekt" + +#: utils/adt/jsonfuncs.c:1949 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "kan inte dekonstruera en array som ett objekt" + +#: utils/adt/jsonfuncs.c:1961 +#, c-format +msgid "cannot deconstruct a scalar" +msgstr "kan inte dekonstruera en skalär" + +#: utils/adt/jsonfuncs.c:2007 +#, c-format +msgid "cannot extract elements from a scalar" +msgstr "kan inte extrahera element frÃ¥n en skalär" + +#: utils/adt/jsonfuncs.c:2011 +#, c-format +msgid "cannot extract elements from an object" +msgstr "kan inte extrahera element frÃ¥n ett objekt" + +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 +#, c-format +msgid "cannot call %s on a non-array" +msgstr "kan inte anropa %s pÃ¥ icke-array" + +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, c-format +msgid "expected JSON array" +msgstr "förväntade JSON-array" + +#: utils/adt/jsonfuncs.c:2334 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "Se värdetypen för nyckel \"%s\"" + +#: utils/adt/jsonfuncs.c:2356 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "Se array-element %s för nyckel \"%s\"." + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "Se array-element %s." + +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "felaktig JSON-array" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 +#, c-format +msgid "first argument of %s must be a row type" +msgstr "första argumentet till %s mÃ¥ste vara en radtyp" + +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 +#, c-format +msgid "Try calling the function in the FROM clause using a column definition list." +msgstr "Försök att anropa funktionen i FROM-klausulen med en kolumndefinitionslista." + +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 +#, c-format +msgid "argument of %s must be an array of objects" +msgstr "argumentet till %s mÃ¥ste vara en array med objekt" + +#: utils/adt/jsonfuncs.c:3764 +#, c-format +msgid "cannot call %s on an object" +msgstr "kan inte anropa %s pÃ¥ ett objekt" + +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 +#, c-format +msgid "cannot delete from scalar" +msgstr "kan inte radera frÃ¥n en skalär" + +#: utils/adt/jsonfuncs.c:4385 +#, c-format +msgid "cannot delete from object using integer index" +msgstr "kan inte radera frÃ¥n objekt genom att använda heltalsindex" + +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 +#, c-format +msgid "cannot set path in scalar" +msgstr "kan inte sätta sökväg i skalär" + +#: utils/adt/jsonfuncs.c:4496 +#, c-format +msgid "cannot delete path in scalar" +msgstr "kan inte radera sökväg i skalär" + +#: utils/adt/jsonfuncs.c:4666 +#, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "ogiltig sammanslagning av jsonb-objekt" + +#: utils/adt/jsonfuncs.c:4700 +#, c-format +msgid "path element at position %d is null" +msgstr "sökvägselement vid position %d är null" + +#: utils/adt/jsonfuncs.c:4786 +#, c-format +msgid "cannot replace existing key" +msgstr "kan inte ersätta befintlig nyckel" + +#: utils/adt/jsonfuncs.c:4787 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "Försök använda funktionen jsonb_set för att ersätta nyckelvärde." + +#: utils/adt/jsonfuncs.c:4869 +#, c-format +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "sökvägselement vid position %d är inte ett heltal: \"%s\"" + +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "fel flaggtyp, bara array:er och skalärer tillÃ¥ts" + +#: utils/adt/jsonfuncs.c:4995 +#, c-format +msgid "flag array element is not a string" +msgstr "flaggelement i arrayen är inte en sträng" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "Möjliga värden är: \"string\", \"numeric\", \"boolean\", \"key\" samt \"all\"." + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "fel flagga i flagg-array: \"%s\"" + +#: utils/adt/jsonpath.c:360 +#, c-format +msgid "@ is not allowed in root expressions" +msgstr "@ är inte tillÃ¥ten i rotuttryck" + +#: utils/adt/jsonpath.c:366 +#, c-format +msgid "LAST is allowed only in array subscripts" +msgstr "LAST tillÃ¥ts bara i array-indexeringar" + +#: utils/adt/jsonpath_exec.c:342 +#, c-format +msgid "single boolean result is expected" +msgstr "förväntade ett booleanskt resultat" + +#: utils/adt/jsonpath_exec.c:490 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "\"variabel\"-argumentet är inte ett objekt" + +#: utils/adt/jsonpath_exec.c:491 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "Jsonpath-parametrar skall kodas som nyckel-värde-par av \"variabel\"-objekt." + +#: utils/adt/jsonpath_exec.c:607 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "JSON-objekt innehÃ¥ller inte nyckeln \"%s\"" + +#: utils/adt/jsonpath_exec.c:619 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "jsonpaths medlemsväljare kan bara appliceras pÃ¥ ett objekt" + +#: utils/adt/jsonpath_exec.c:648 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "jsonpaths arrayväljare med wildcard kan bara applcieras pÃ¥ en array" + +#: utils/adt/jsonpath_exec.c:696 +#, c-format +msgid "jsonpath array subscript is out of bounds" +msgstr "jsonpaths array-index är utanför giltigt omrÃ¥de" + +#: utils/adt/jsonpath_exec.c:753 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "jsonpaths arrayväljare kan bara appliceras pÃ¥ en array" + +#: utils/adt/jsonpath_exec.c:807 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "jsonpaths medlemsväljare med wildcard kan bara appliceras pÃ¥ ett objekt" + +#: utils/adt/jsonpath_exec.c:937 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "jsonpaths elementmetod .%s() lkan bara applicerar pÃ¥ en array" + +#: utils/adt/jsonpath_exec.c:991 utils/adt/jsonpath_exec.c:1012 +#: utils/adt/jsonpath_exec.c:1695 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "jsonpaths elementmetod .%s() kan bara appliceras pÃ¥ ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1025 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "jsonpaths elementmetod .%s() kan bara applicerar pÃ¥ en sträng eller ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1509 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "vänster operand pÃ¥ jsonpath-operator %s är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1516 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "höger operand pÃ¥ jsonpath-operator %s är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1584 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "operand till unär jsonpath-operator %s är inte ett numeriskt värde" + +#: utils/adt/jsonpath_exec.c:1754 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "jsonpaths elementmetod .%s() kan bara appliceras pÃ¥ ett objekt" + +#: utils/adt/jsonpath_exec.c:1937 +#, c-format +msgid "could not find jsonpath variable \"%s\"" +msgstr "kunde inte hitta jsonpath-variabel \"%s\"" + +#: utils/adt/jsonpath_exec.c:2097 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "jsonpaths array-index är inte ett ensamt numeriskt värde" + +#: utils/adt/jsonpath_exec.c:2109 +#, c-format +msgid "jsonpath array subscript is out of integer range" +msgstr "jsonpaths array-index är utanför giltigt interval för integer" + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "levenshtein-argument överskrider maximala längden pÃ¥ %d tecken" + +#: utils/adt/like.c:160 +#, c-format +msgid "nondeterministic collations are not supported for LIKE" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för LIKE" + +#: utils/adt/like.c:193 utils/adt/like_support.c:964 +#, c-format +msgid "could not determine which collation to use for ILIKE" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för ILIKE" + +#: utils/adt/like.c:201 +#, c-format +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för ILIKE" + +#: utils/adt/like_match.c:107 utils/adt/like_match.c:167 +#, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "LIKE-mönster för inte sluta med ett escape-tecken" + +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 +#, c-format +msgid "invalid escape string" +msgstr "ogiltig escape-sträng" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "Escape-sträng mÃ¥ste vara tom eller ett tecken." + +#: utils/adt/like_support.c:949 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "matchning utan skiftlägeskänslighet stöds inte för typen bytea" + +#: utils/adt/like_support.c:1051 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "matching med reguljär-uttryck stöds inte för typen bytea" + +#: utils/adt/lockfuncs.c:664 +#, c-format +msgid "cannot use advisory locks during a parallel operation" +msgstr "kan inte använda rÃ¥dgivande lÃ¥s vid en parallell operation" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "ogiltigt oktet-värde i \"macaddr\"-värde: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8-data utanför giltigt intervall för att konverteras till macaddr" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "Bara adresser som har FF och FE som värden i 4:e och 5:e byten frÃ¥n vänster, till exempel xx:xx:xx:ff:fe:xx:xx:xx, är möjliga att konvertera frÃ¥n macaddr8 till macaddr." + +#: utils/adt/misc.c:225 +#, c-format +msgid "global tablespace never has databases" +msgstr "globala tablespace:t innehÃ¥ller aldrig databaser" + +#: utils/adt/misc.c:246 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u är inte ett tabelespace-OID" + +#: utils/adt/misc.c:435 +msgid "unreserved" +msgstr "oreserverad" + +#: utils/adt/misc.c:439 +msgid "unreserved (cannot be function or type name)" +msgstr "ej reserverad (kan inte vara funktion eller typnamn)" + +#: utils/adt/misc.c:443 +msgid "reserved (can be function or type name)" +msgstr "reserverad (kan vara funktion eller typnamn)" + +#: utils/adt/misc.c:447 +msgid "reserved" +msgstr "reserverad" + +#: utils/adt/misc.c:621 utils/adt/misc.c:635 utils/adt/misc.c:674 +#: utils/adt/misc.c:680 utils/adt/misc.c:686 utils/adt/misc.c:709 +#, c-format +msgid "string is not a valid identifier: \"%s\"" +msgstr "sträng är inte en giltig identifierare: \"%s\"" + +#: utils/adt/misc.c:623 +#, c-format +msgid "String has unclosed double quotes." +msgstr "Sträng har ej avslutade dubbla citattecken." + +#: utils/adt/misc.c:637 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Citerad identifierare fÃ¥r inte vara tom." + +#: utils/adt/misc.c:676 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "Ingen giltig indentifierare innan \".\"." + +#: utils/adt/misc.c:682 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "Ingen giltig identifierare efter \".\"." + +#: utils/adt/misc.c:743 +#, c-format +msgid "log format \"%s\" is not supported" +msgstr "loggformat \"%s\" stöds inte" + +#: utils/adt/misc.c:744 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "Loggformat som stöds är \"stderr\" och \"csvlog\"." + +#: utils/adt/network.c:85 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "ogiltigt cidr-värde: \"%s\"" + +#: utils/adt/network.c:86 utils/adt/network.c:216 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Värdet har bitar till höger om masken." + +#: utils/adt/network.c:127 utils/adt/network.c:800 utils/adt/network.c:825 +#: utils/adt/network.c:850 +#, c-format +msgid "could not format inet value: %m" +msgstr "kunde inte formattera inet-värde: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:184 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "ogiltig adressfamilj i externt \"%s\"-värde" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:191 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "ogiltig bitar i externt \"%s\"-värde" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:200 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "ogiltig längd i extern \"%s\"-värde" + +#: utils/adt/network.c:215 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "ogiltigt externt \"cidr\"-värde" + +#: utils/adt/network.c:311 utils/adt/network.c:334 +#, c-format +msgid "invalid mask length: %d" +msgstr "ogiltig masklängd: %d" + +#: utils/adt/network.c:868 +#, c-format +msgid "could not format cidr value: %m" +msgstr "kunde inte formattera \"cidr\"-värde: %m" + +#: utils/adt/network.c:1101 +#, c-format +msgid "cannot merge addresses from different families" +msgstr "kan inte slÃ¥ samman adresser frÃ¥n olika familjer" + +#: utils/adt/network.c:1517 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "kan inte AND:a inet-värden av olika storlek" + +#: utils/adt/network.c:1549 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "kan inte OR:a inet-värden av olika storlek" + +#: utils/adt/network.c:1610 utils/adt/network.c:1686 +#, c-format +msgid "result is out of range" +msgstr "resultatet är utanför giltigt intervall" + +#: utils/adt/network.c:1651 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "kan inte subtrahera inet-värden av olika storlek" + +#: utils/adt/numeric.c:833 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "ogiltigt tecken i externt \"numric\"-värde" + +#: utils/adt/numeric.c:839 +#, c-format +msgid "invalid scale in external \"numeric\" value" +msgstr "ogiltig skala i externt \"numeric\"-värde" + +#: utils/adt/numeric.c:848 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "felaktig siffra i externt numeriskt (\"numeric\") värde " + +#: utils/adt/numeric.c:1046 utils/adt/numeric.c:1060 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "Precisionen %d för NUMERIC mÃ¥ste vara mellan 1 och %d" + +#: utils/adt/numeric.c:1051 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "Skalan %d för NUMERIC mÃ¥ste vara mellan 0 och precisionen %d" + +#: utils/adt/numeric.c:1069 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "ogiltig typmodifierare för NUMERIC" + +#: utils/adt/numeric.c:1401 +#, c-format +msgid "start value cannot be NaN" +msgstr "startvärde fÃ¥r inte vara NaN" + +#: utils/adt/numeric.c:1406 +#, c-format +msgid "stop value cannot be NaN" +msgstr "stoppvärde fÃ¥r inte vara NaN" + +#: utils/adt/numeric.c:1416 +#, c-format +msgid "step size cannot be NaN" +msgstr "stegstorlek fÃ¥r inte vara NaN" + +#: utils/adt/numeric.c:2857 utils/adt/numeric.c:5869 utils/adt/numeric.c:6324 +#: utils/adt/numeric.c:8046 utils/adt/numeric.c:8471 utils/adt/numeric.c:8585 +#: utils/adt/numeric.c:8658 +#, c-format +msgid "value overflows numeric format" +msgstr "overflow pÃ¥ värde i formatet numeric" + +#: utils/adt/numeric.c:3222 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "kan inte konvertera NaN till ett integer" + +#: utils/adt/numeric.c:3305 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "kan inte konvertera NaN till ett bigint" + +#: utils/adt/numeric.c:3350 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "kan inte konvertera NaN till ett smallint" + +#: utils/adt/numeric.c:3387 utils/adt/numeric.c:3458 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "kan inte konvertera oändlighet till numeric" + +#: utils/adt/numeric.c:6408 +#, c-format +msgid "numeric field overflow" +msgstr "overflow i numeric-fält" + +#: utils/adt/numeric.c:6409 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "Ett fält med precision %d, skala %d mÃ¥ste avrundas till ett absolut värde mindre än %s%d." + +#: utils/adt/numutils.c:90 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "värdet \"%s\" är utanför intervallet för ett 8-bitars heltal" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "ogiltig oidvector-data" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "efterfrÃ¥gat tecken är för stort" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "efterfrÃ¥gat tecken är för stort för kodning: %d" + +#: utils/adt/oracle_compat.c:987 +#, c-format +msgid "requested character not valid for encoding: %d" +msgstr "efterfrÃ¥gat tecken är inte giltigt för kodning: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "nolltecken tillÃ¥ts inte" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "percentil-värde %g är inte mellan 0 och 1" + +#: utils/adt/pg_locale.c:1097 +#, c-format +msgid "Apply system library package updates." +msgstr "Applicera paketuppdateringar för systembibliotek." + +#: utils/adt/pg_locale.c:1312 +#, c-format +msgid "could not create locale \"%s\": %m" +msgstr "kunde inte skapa locale \"%s\": %m" + +#: utils/adt/pg_locale.c:1315 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "Operativsystemet kunde inte hitta nÃ¥gon lokaldata för lokalnamnet \"%s\"." + +#: utils/adt/pg_locale.c:1417 +#, c-format +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "jämförelser (collations) med olika collate- och ctype-värden stöds inte pÃ¥ denna plattform" + +#: utils/adt/pg_locale.c:1426 +#, c-format +msgid "collation provider LIBC is not supported on this platform" +msgstr "leverantören LIBC för jämförelse (collation) stöds inte pÃ¥ denna plattform" + +#: utils/adt/pg_locale.c:1438 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "jämförelser (collation) med olika collate- och ctype-värden stöds inte av ICU" + +#: utils/adt/pg_locale.c:1444 utils/adt/pg_locale.c:1535 +#: utils/adt/pg_locale.c:1753 +#, c-format +msgid "could not open collator for locale \"%s\": %s" +msgstr "kunde inte öppna jämförelse för lokal \"%s\": %s" + +#: utils/adt/pg_locale.c:1458 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU stöds inte av detta bygge" + +#: utils/adt/pg_locale.c:1459 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "Du behöver bygga om PostgreSQL med --with-icu." + +#: utils/adt/pg_locale.c:1479 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "jämförelse (collation) \"%s\" har ingen version men en version angavs" + +#: utils/adt/pg_locale.c:1486 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "jämförelse (collation) \"%s\" har en version som inte matchar" + +#: utils/adt/pg_locale.c:1488 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Jämförelsen (collation) i databasen har skapats med version %s men operativsystemet har version %s." + +#: utils/adt/pg_locale.c:1491 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "Bygg om alla objekt som pÃ¥verkas av denna jämförelse (collation) och kör ALTER COLLATION %s REFRESH VERSION eller bygg PostgreSQL med rätt bibliotekversion." + +#: utils/adt/pg_locale.c:1575 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "kunde inte öppna ICU-konverterare för kodning \"%s\": %s" + +#: utils/adt/pg_locale.c:1606 utils/adt/pg_locale.c:1615 +#: utils/adt/pg_locale.c:1644 utils/adt/pg_locale.c:1654 +#, c-format +msgid "%s failed: %s" +msgstr "%s misslyckades: %s" + +#: utils/adt/pg_locale.c:1926 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "ogiltigt multibyte-tecken för lokalen" + +#: utils/adt/pg_locale.c:1927 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "Serverns LC_CTYPE-lokal är troligen inkompatibel med databasens teckenkodning." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "funktionen kan bara anropas när servern är i binärt uppgraderingsläge" + +#: utils/adt/pgstatfuncs.c:479 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "ogiltigt kommandonamn: \"%s\"" + +#: utils/adt/pseudotypes.c:247 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "kan inte acceptera ett värde av typen shell" + +#: utils/adt/pseudotypes.c:260 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "kan inte visa ett värde av typen shell" + +#: utils/adt/pseudotypes.c:350 utils/adt/pseudotypes.c:376 +#, c-format +msgid "cannot output a value of type %s" +msgstr "kan inte mata ut ett värde av typ %s" + +#: utils/adt/pseudotypes.c:403 +#, c-format +msgid "cannot display a value of type %s" +msgstr "kan inte visa ett värde av typ %s" + +#: utils/adt/rangetypes.c:406 +#, c-format +msgid "range constructor flags argument must not be null" +msgstr "konstruktorflaggargument till range fÃ¥r inte vara null" + +#: utils/adt/rangetypes.c:993 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "resultatet av range-skillnad skulle inte vara angränsande" + +#: utils/adt/rangetypes.c:1054 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "resultatet av range-union skulle inte vara angränsande" + +#: utils/adt/rangetypes.c:1598 +#, c-format +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "lägre gräns för range mÃ¥ste vara lägre eller lika med övre gräns för range" + +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 +#, c-format +msgid "invalid range bound flags" +msgstr "ogiltig gränsflagga för range" + +#: utils/adt/rangetypes.c:1982 utils/adt/rangetypes.c:1995 +#: utils/adt/rangetypes.c:2009 +#, c-format +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Giltiga värden är \"[]\", \"[)\", \"(]\" och \"()\"." + +#: utils/adt/rangetypes.c:2074 utils/adt/rangetypes.c:2091 +#: utils/adt/rangetypes.c:2104 utils/adt/rangetypes.c:2122 +#: utils/adt/rangetypes.c:2133 utils/adt/rangetypes.c:2177 +#: utils/adt/rangetypes.c:2185 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "trasig range-litteral: \"%s\"" + +#: utils/adt/rangetypes.c:2076 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "Skräp efter nyckelordet \"empty\"." + +#: utils/adt/rangetypes.c:2093 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Saknar vänster parentes eller hakparentes." + +#: utils/adt/rangetypes.c:2106 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Saknar komma efter lägre gräns." + +#: utils/adt/rangetypes.c:2124 +#, c-format +msgid "Too many commas." +msgstr "För mÃ¥nga komman." + +#: utils/adt/rangetypes.c:2135 +#, c-format +msgid "Junk after right parenthesis or bracket." +msgstr "Skräp efter höger parentes eller hakparentes." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1490 utils/adt/varlena.c:4476 +#, c-format +msgid "regular expression failed: %s" +msgstr "reguljärt uttryck misslyckades: %s" + +#: utils/adt/regexp.c:426 +#, c-format +msgid "invalid regular expression option: \"%c\"" +msgstr "ogiltigt flagga till reguljärt uttryck: \"%c\"" + +#: utils/adt/regexp.c:838 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "Regulart uttryck i SQL fÃ¥r inte innehÃ¥lla mer än tvÃ¥ dubbelcitat-escape-separatorer" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:924 utils/adt/regexp.c:1307 utils/adt/regexp.c:1362 +#, c-format +msgid "%s does not support the \"global\" option" +msgstr "%s stöder inte \"global\"-flaggan" + +#: utils/adt/regexp.c:926 +#, c-format +msgid "Use the regexp_matches function instead." +msgstr "Använd regexp_matches-funktionen istället." + +#: utils/adt/regexp.c:1108 +#, c-format +msgid "too many regular expression matches" +msgstr "för mÃ¥nga reguljära uttryck matchar" + +#: utils/adt/regproc.c:106 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "mer än en funktion med namn %s" + +#: utils/adt/regproc.c:524 +#, c-format +msgid "more than one operator named %s" +msgstr "mer än en operator med namn %s" + +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9210 utils/adt/ruleutils.c:9378 +#, c-format +msgid "too many arguments" +msgstr "för mÃ¥nga argument" + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Ange tvÃ¥ argumenttyper för operatorn." + +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3625 utils/adt/varlena.c:3630 +#, c-format +msgid "invalid name syntax" +msgstr "ogiltig namnsyntax" + +#: utils/adt/regproc.c:1763 +#, c-format +msgid "expected a left parenthesis" +msgstr "förväntade en vänsterparentes" + +#: utils/adt/regproc.c:1779 +#, c-format +msgid "expected a right parenthesis" +msgstr "förväntade en högreparentes" + +#: utils/adt/regproc.c:1798 +#, c-format +msgid "expected a type name" +msgstr "förväntade ett typnamn" + +#: utils/adt/regproc.c:1830 +#, c-format +msgid "improper type name" +msgstr "olämpligt typnamn" + +#: utils/adt/ri_triggers.c:298 utils/adt/ri_triggers.c:1534 +#: utils/adt/ri_triggers.c:2465 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "insert eller update pÃ¥ tabell \"%s\" bryter mot främmande nyckel-villkoret \"%s\"" + +#: utils/adt/ri_triggers.c:301 utils/adt/ri_triggers.c:1537 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL tillÃ¥ter inte att man blandar null och icke-null-värden." + +#: utils/adt/ri_triggers.c:1932 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "funktionen \"%s\" mÃ¥ste köras för INSERT" + +#: utils/adt/ri_triggers.c:1938 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "funktionen \"%s\" mÃ¥ste köras för UPDATE" + +#: utils/adt/ri_triggers.c:1944 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "funktionen \"%s\" mÃ¥ste köras för DELETE" + +#: utils/adt/ri_triggers.c:1967 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "ingen pg_constraint-post för utlösare \"%s\" pÃ¥ tabell \"%s\"" + +#: utils/adt/ri_triggers.c:1969 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Ta bort denna utlösare för referensiell integritet och dess kollegor, gör sen ALTER TABLE ADD CONSTRAINT." + +#: utils/adt/ri_triggers.c:2291 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "referentiell integritetsfrÃ¥ga pÃ¥ \"%s\" frÃ¥n villkor \"%s\" pÃ¥ \"%s\" gav oväntat resultat" + +#: utils/adt/ri_triggers.c:2295 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Detta beror troligen pÃ¥ att en regel har skrivit om frÃ¥gan." + +#: utils/adt/ri_triggers.c:2456 +#, c-format +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "borttagning av partition \"%s\" bryter mot främmande nyckel-villkoret \"%s\"" + +#: utils/adt/ri_triggers.c:2459 +#, c-format +msgid "Key (%s)=(%s) still referenced from table \"%s\"." +msgstr "Nyckeln (%s)=(%s) refereras fortfarande till frÃ¥n tabell \"%s\"." + +#: utils/adt/ri_triggers.c:2469 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "Nyckel (%s)=(%s) finns inte i tabellen \"%s\"." + +#: utils/adt/ri_triggers.c:2472 +#, c-format +msgid "Key is not present in table \"%s\"." +msgstr "Nyckeln finns inte i tabellen \"%s\"." + +#: utils/adt/ri_triggers.c:2478 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "update eller delete pÃ¥ tabell \"%s\" bryter mot främmande nyckel-villkoret \"%s\" för tabell \"%s\"" + +#: utils/adt/ri_triggers.c:2483 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "Nyckeln (%s)=(%s) refereras fortfarande till frÃ¥n tabell \"%s\"." + +#: utils/adt/ri_triggers.c:2486 +#, c-format +msgid "Key is still referenced from table \"%s\"." +msgstr "Nyckel refereras fortfarande till frÃ¥n tabell \"%s\"." + +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "inläsning av annonym composite-typ är inte implementerat" + +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "felaktig postliteral: \"%s\"" + +#: utils/adt/rowtypes.c:157 +#, c-format +msgid "Missing left parenthesis." +msgstr "Saknar vänster parentes" + +#: utils/adt/rowtypes.c:186 +#, c-format +msgid "Too few columns." +msgstr "För fÃ¥ kolumner." + +#: utils/adt/rowtypes.c:269 +#, c-format +msgid "Too many columns." +msgstr "För mÃ¥nga kolumner." + +#: utils/adt/rowtypes.c:277 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Skräp efter höger parentes" + +#: utils/adt/rowtypes.c:531 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "fel antal kolumner: %d, förväntade %d" + +#: utils/adt/rowtypes.c:559 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "fel datatyp: %u, förväntade %u" + +#: utils/adt/rowtypes.c:620 +#, c-format +msgid "improper binary format in record column %d" +msgstr "felaktigt binärt format i postkolumn %d" + +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1155 utils/adt/rowtypes.c:1414 +#: utils/adt/rowtypes.c:1658 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "kan inte jämföra olika kolumntyper %s och %s vid postkolumn %d" + +#: utils/adt/rowtypes.c:1000 utils/adt/rowtypes.c:1226 +#: utils/adt/rowtypes.c:1509 utils/adt/rowtypes.c:1694 +#, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "kan inte jämföra record-typer med olika antal kolumner" + +#: utils/adt/ruleutils.c:4885 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "regel \"%s\" har en icke stödd händelsetyp %d" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "prceision för TIMESTAMP(%d)%s kan inte vara negativ" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "precision för TIMESTAMP(%d)%s reducerad till högsta tillÃ¥tna, %d" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:427 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp utanför giltigt intervall: \"%s\"" + +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:445 +#: utils/adt/timestamp.c:952 +#, c-format +msgid "date/time value \"%s\" is no longer supported" +msgstr "datum/tid-värde \"%s\" stöds inte längre" + +#: utils/adt/timestamp.c:373 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "timestamp(%d)-precision mÃ¥ste vara mellan %d och %d" + +#: utils/adt/timestamp.c:497 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "Numeriska tidszoner mÃ¥ste ha \"-\" eller \"+\" som sitt första tecken." + +#: utils/adt/timestamp.c:510 +#, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "numerisk tidszon \"%s\" utanför giltigt intervall" + +#: utils/adt/timestamp.c:612 utils/adt/timestamp.c:622 +#: utils/adt/timestamp.c:630 +#, c-format +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp utanför giltigt intervall: %d-%02d-%02d %d:%02d:%02g" + +#: utils/adt/timestamp.c:731 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp kan inte vara NaN" + +#: utils/adt/timestamp.c:749 utils/adt/timestamp.c:761 +#, c-format +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp utanför giltigt intervall: \"%g\"" + +#: utils/adt/timestamp.c:946 utils/adt/timestamp.c:1526 +#: utils/adt/timestamp.c:1959 utils/adt/timestamp.c:3057 +#: utils/adt/timestamp.c:3062 utils/adt/timestamp.c:3067 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3131 utils/adt/timestamp.c:3151 +#: utils/adt/timestamp.c:3158 utils/adt/timestamp.c:3165 +#: utils/adt/timestamp.c:3195 utils/adt/timestamp.c:3203 +#: utils/adt/timestamp.c:3247 utils/adt/timestamp.c:3674 +#: utils/adt/timestamp.c:3799 utils/adt/timestamp.c:4259 +#, c-format +msgid "interval out of range" +msgstr "interval utanför giltigt intervall" + +#: utils/adt/timestamp.c:1079 utils/adt/timestamp.c:1112 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "ogitligt modifierare för typen INTERVAL" + +#: utils/adt/timestamp.c:1095 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d)-precision kan inte vara negativ" + +#: utils/adt/timestamp.c:1101 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d)-precision reducerad till maximalt tillÃ¥tna, %d" + +#: utils/adt/timestamp.c:1483 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "interval(%d)-precision mÃ¥ste vara mellan %d och %d" + +#: utils/adt/timestamp.c:2658 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "kan inte subtrahera oändliga tider (timestamp)" + +#: utils/adt/timestamp.c:3927 utils/adt/timestamp.c:4519 +#: utils/adt/timestamp.c:4686 utils/adt/timestamp.c:4707 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "timestamp-enhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:3941 utils/adt/timestamp.c:4473 +#: utils/adt/timestamp.c:4717 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "timestamp-enhet \"%s\" känns inte igen" + +#: utils/adt/timestamp.c:4071 utils/adt/timestamp.c:4514 +#: utils/adt/timestamp.c:4887 utils/adt/timestamp.c:4909 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "timestamp with time zone, enhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:4088 utils/adt/timestamp.c:4468 +#: utils/adt/timestamp.c:4918 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "timestamp with time zone, enhet \"%s\" känns inte igen" + +#: utils/adt/timestamp.c:4246 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "intervallenhet \"%s\" stöds inte dÃ¥ mÃ¥nader typiskt har veckor pÃ¥ brÃ¥kform" + +#: utils/adt/timestamp.c:4252 utils/adt/timestamp.c:5012 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "intervallenhet \"%s\" stöds inte" + +#: utils/adt/timestamp.c:4268 utils/adt/timestamp.c:5035 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "intervallenhet \"%s\" känns inte igen" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "suppress_redundant_updates_trigger: mÃ¥ste anropas som utlösare" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "suppress_redundant_updates_trigger: mÃ¥ste anropas vid update" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "suppress_redundant_updates_trigger: mÃ¥ste anropas innan update" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "suppress_redundant_updates_trigger: mÃ¥ste anropas för varje rad" + +#: utils/adt/tsgistidx.c:81 +#, c-format +msgid "gtsvector_in not implemented" +msgstr "gtsvector_in är inte implementerad" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "distans i frasoperator skall inte vara större än %d" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 +#, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "syntaxfel i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:334 +#, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "ingen operand i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "värdet är för stort i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "operanden är för lÃ¥ng i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "ord för lÃ¥ngt i tsquery: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "textsökfrÃ¥ga innehÃ¥ller inte lexem: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, c-format +msgid "tsquery is too large" +msgstr "tsquery är för stor" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "textsökfrÃ¥ga innehÃ¥ller bara stoppord eller innehÃ¥ller inga lexem, hoppar över" + +#: utils/adt/tsquery_op.c:123 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "distans i frasoperator skall vara icke-negativ och mindre än %d" + +#: utils/adt/tsquery_rewrite.c:321 +#, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "ts_rewrite-frÃ¥ga mÃ¥ste returnera tvÃ¥ tsquery-kolumner" + +#: utils/adt/tsrank.c:413 +#, c-format +msgid "array of weight must be one-dimensional" +msgstr "array med vikter mÃ¥ste vara endimensionell" + +#: utils/adt/tsrank.c:418 +#, c-format +msgid "array of weight is too short" +msgstr "array med vikter är för kort" + +#: utils/adt/tsrank.c:423 +#, c-format +msgid "array of weight must not contain nulls" +msgstr "array med vikter fÃ¥r inte innehÃ¥lla null-värden" + +#: utils/adt/tsrank.c:432 utils/adt/tsrank.c:869 +#, c-format +msgid "weight out of range" +msgstr "vikten är utanför giltigt intervall" + +#: utils/adt/tsvector.c:214 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "ordet är för lÃ¥ngt (%ld byte, max %ld byte)" + +#: utils/adt/tsvector.c:221 +#, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "strängen är för lÃ¥ng för tsvector (%ld byte, max %ld byte)" + +#: utils/adt/tsvector_op.c:321 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:776 +#, c-format +msgid "lexeme array may not contain nulls" +msgstr "lexem-array:en fÃ¥r inte innehÃ¥lla null-värden" + +#: utils/adt/tsvector_op.c:851 +#, c-format +msgid "weight array may not contain nulls" +msgstr "vikt-array:en fÃ¥r inte innehÃ¥lla null-värden" + +#: utils/adt/tsvector_op.c:875 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "okänd vikt: \"%c\"" + +#: utils/adt/tsvector_op.c:2312 +#, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "ts_stat-frÃ¥gan mÃ¥ste returnera en tsvector-kolumn" + +#: utils/adt/tsvector_op.c:2494 +#, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "tsvector-kolumnen \"%s\" existerar inte" + +#: utils/adt/tsvector_op.c:2501 +#, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "kolumnen \"%s\" är inte av typen tsvector" + +#: utils/adt/tsvector_op.c:2513 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "konfigurationskolumnen \"%s\" existerar inte" + +#: utils/adt/tsvector_op.c:2519 +#, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "kolumn \"%s\" har inte regconfig-typ" + +#: utils/adt/tsvector_op.c:2526 +#, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "konfigurationskolumn \"%s\" fÃ¥r inte vara null" + +#: utils/adt/tsvector_op.c:2539 +#, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "Textsökkonfigurationsnamn \"%s\" mÃ¥ste vara angivet med schema" + +#: utils/adt/tsvector_op.c:2564 +#, c-format +msgid "column \"%s\" is not of a character type" +msgstr "kolumnen \"%s\" är inte av typen character" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "syntaxfel i tsvector: \"%s\"" + +#: utils/adt/tsvector_parser.c:200 +#, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "det finns inget escape-tecken: \"%s\"" + +#: utils/adt/tsvector_parser.c:318 +#, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "fel positionsinfo i tsvector: \"%s\"" + +#: utils/adt/txid.c:140 +#, c-format +msgid "transaction ID %s is in the future" +msgstr "transaktions-ID %s är frÃ¥n framtiden" + +#: utils/adt/txid.c:629 +#, c-format +msgid "invalid external txid_snapshot data" +msgstr "ogiltig extern txid_snapshot-data" + +#: utils/adt/varbit.c:60 utils/adt/varchar.c:54 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "längden för typ %s mÃ¥ste vara minst 1" + +#: utils/adt/varbit.c:65 utils/adt/varchar.c:58 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "längden för typ %s kan inte överstiga %d" + +#: utils/adt/varbit.c:166 utils/adt/varbit.c:478 utils/adt/varbit.c:984 +#, c-format +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "bitstränglängden överskrider det maximalt tillÃ¥tna (%d)" + +#: utils/adt/varbit.c:180 utils/adt/varbit.c:323 utils/adt/varbit.c:380 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "bitsträngslängden %d matchar inte typen bit(%d)" + +#: utils/adt/varbit.c:202 utils/adt/varbit.c:514 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" är inte en giltig binär siffra" + +#: utils/adt/varbit.c:227 utils/adt/varbit.c:539 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" är inte en giltig hexdecimal siffra" + +#: utils/adt/varbit.c:314 utils/adt/varbit.c:630 +#, c-format +msgid "invalid length in external bit string" +msgstr "ogiltig längd pÃ¥ extern bitsträng" + +#: utils/adt/varbit.c:492 utils/adt/varbit.c:639 utils/adt/varbit.c:742 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "bitsträngen för lÃ¥ng för typen bit varying(%d)" + +#: utils/adt/varbit.c:1077 utils/adt/varbit.c:1179 utils/adt/varlena.c:863 +#: utils/adt/varlena.c:927 utils/adt/varlena.c:1071 utils/adt/varlena.c:3291 +#: utils/adt/varlena.c:3358 +#, c-format +msgid "negative substring length not allowed" +msgstr "negativ substräng-läng tillÃ¥ts inte" + +#: utils/adt/varbit.c:1236 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "kan inte AND:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1278 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "kan inte OR:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1325 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "kan inte XOR:a bitsträngar av olika storlek" + +#: utils/adt/varbit.c:1813 utils/adt/varbit.c:1871 +#, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "bitindex %d utanför giltigt intervall (0..%d)" + +#: utils/adt/varbit.c:1822 utils/adt/varlena.c:3549 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "nya biten mÃ¥ste vara 0 eller 1" + +#: utils/adt/varchar.c:158 utils/adt/varchar.c:311 +#, c-format +msgid "value too long for type character(%d)" +msgstr "värdet för lÃ¥ngt för typen character (%d)" + +#: utils/adt/varchar.c:473 utils/adt/varchar.c:635 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "värdet för lÃ¥ngt för typen character varying(%d)" + +#: utils/adt/varchar.c:733 utils/adt/varlena.c:1455 +#, c-format +msgid "could not determine which collation to use for string comparison" +msgstr "kunde inte bestämma vilken jämförelse (collation) som skall användas för strängjämförelse" + +#: utils/adt/varchar.c:1122 utils/adt/varchar.c:1232 utils/adt/varlena.c:3024 +#: utils/adt/varlena.c:3134 +#, c-format +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för operatorklass \"%s\"" + +#: utils/adt/varlena.c:1165 utils/adt/varlena.c:1889 +#, c-format +msgid "nondeterministic collations are not supported for substring searches" +msgstr "ickedeterministiska jämförelser (collation) stöds inte för substrängsökningar" + +#: utils/adt/varlena.c:1548 utils/adt/varlena.c:1561 +#, c-format +msgid "could not convert string to UTF-16: error code %lu" +msgstr "kunde inte konvertera sträng till UTF-16: felkod %lu" + +#: utils/adt/varlena.c:1576 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "kunde inte jämföra Unicode-strängar: %m" + +#: utils/adt/varlena.c:1627 utils/adt/varlena.c:2341 +#, c-format +msgid "collation failed: %s" +msgstr "jämförelse misslyckades: %s" + +#: utils/adt/varlena.c:2549 +#, c-format +msgid "sort key generation failed: %s" +msgstr "generering av sorteringsnyckel misslyckades: %s" + +#: utils/adt/varlena.c:3435 utils/adt/varlena.c:3466 utils/adt/varlena.c:3501 +#: utils/adt/varlena.c:3537 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "index %d utanför giltigt intervall, 0..%d" + +#: utils/adt/varlena.c:4573 +#, c-format +msgid "field position must be greater than zero" +msgstr "fältpositionen mÃ¥ste vara större än noll" + +#: utils/adt/varlena.c:5439 +#, c-format +msgid "unterminated format() type specifier" +msgstr "icketerminerad typangivelse för format()" + +#: utils/adt/varlena.c:5440 utils/adt/varlena.c:5574 utils/adt/varlena.c:5695 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "För ett ensamt \"%%\" använd \"%%%%\"." + +#: utils/adt/varlena.c:5572 utils/adt/varlena.c:5693 +#, c-format +msgid "unrecognized format() type specifier \"%c\"" +msgstr "okänd typspecifierare \"%c\" för format()" + +#: utils/adt/varlena.c:5585 utils/adt/varlena.c:5642 +#, c-format +msgid "too few arguments for format()" +msgstr "för fÃ¥ argument till format()" + +#: utils/adt/varlena.c:5738 utils/adt/varlena.c:5920 +#, c-format +msgid "number is out of range" +msgstr "numret är utanför giltigt intervall" + +#: utils/adt/varlena.c:5801 utils/adt/varlena.c:5829 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "formatet anger argument 0 men argumenten är numrerade frÃ¥n 1" + +#: utils/adt/varlena.c:5822 +#, c-format +msgid "width argument position must be ended by \"$\"" +msgstr "argumentposition för bredd mÃ¥ste avslutas med \"$\"" + +#: utils/adt/varlena.c:5867 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "null-värden kan inte formatteras som SQL-identifierare" + +#: utils/adt/windowfuncs.c:243 +#, c-format +msgid "argument of ntile must be greater than zero" +msgstr "argumentet till ntile mÃ¥ste vara större än noll" + +#: utils/adt/windowfuncs.c:465 +#, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "argumentet till nth_value mÃ¥ste vara större än noll" + +#: utils/adt/xml.c:222 +#, c-format +msgid "unsupported XML feature" +msgstr "ej stödd XML-finess" + +#: utils/adt/xml.c:223 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Denna funktionalitet kräver att servern byggts med libxml-support." + +#: utils/adt/xml.c:224 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "Du behöver bygga om PostgreSQL med flaggan --with-libxml." + +#: utils/adt/xml.c:243 utils/mb/mbutils.c:512 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "ogiltigt kodningsnamn \"%s\"" + +#: utils/adt/xml.c:486 utils/adt/xml.c:491 +#, c-format +msgid "invalid XML comment" +msgstr "ogiltigt XML-kommentar" + +#: utils/adt/xml.c:620 +#, c-format +msgid "not an XML document" +msgstr "inget XML-dokument" + +#: utils/adt/xml.c:779 utils/adt/xml.c:802 +#, c-format +msgid "invalid XML processing instruction" +msgstr "ogiltig XML-processinstruktion" + +#: utils/adt/xml.c:780 +#, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML-processinstruktions mÃ¥lnamn kan inte vara \"%s\"." + +#: utils/adt/xml.c:803 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML-processinstruktion kan inte innehÃ¥lla \"?>\"." + +#: utils/adt/xml.c:882 +#, c-format +msgid "xmlvalidate is not implemented" +msgstr "xmlvalidate är inte implementerat" + +#: utils/adt/xml.c:961 +#, c-format +msgid "could not initialize XML library" +msgstr "kunde inte initiera XML-bibliotek" + +#: utils/adt/xml.c:962 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 har inkompatibel char-typ: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1048 +#, c-format +msgid "could not set up XML error handler" +msgstr "kunde inte ställa in XML-felhanterare" + +#: utils/adt/xml.c:1049 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "Detta tyder pÃ¥ att libxml2-versionen som används inte är kompatibel med libxml2-header-filerna som PostgreSQL byggts med." + +#: utils/adt/xml.c:1936 +msgid "Invalid character value." +msgstr "Ogiltigt teckenvärde." + +#: utils/adt/xml.c:1939 +msgid "Space required." +msgstr "Mellanslag krävs." + +#: utils/adt/xml.c:1942 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "standalone tillÃ¥ter bara 'yes' eller 'no'." + +#: utils/adt/xml.c:1945 +msgid "Malformed declaration: missing version." +msgstr "Felaktig deklaration: saknar version." + +#: utils/adt/xml.c:1948 +msgid "Missing encoding in text declaration." +msgstr "Saknar kodning i textdeklaration." + +#: utils/adt/xml.c:1951 +msgid "Parsing XML declaration: '?>' expected." +msgstr "Parsar XML-deklaration: förväntade sig '?>'" + +#: utils/adt/xml.c:1954 +#, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "Okänd libxml-felkod: %d." + +#: utils/adt/xml.c:2229 +#, c-format +msgid "XML does not support infinite date values." +msgstr "XML stöder inte oändliga datumvärden." + +#: utils/adt/xml.c:2251 utils/adt/xml.c:2278 +#, c-format +msgid "XML does not support infinite timestamp values." +msgstr "XML stöder inte oändliga timestamp-värden." + +#: utils/adt/xml.c:2690 +#, c-format +msgid "invalid query" +msgstr "ogiltig frÃ¥ga" + +#: utils/adt/xml.c:4037 +#, c-format +msgid "invalid array for XML namespace mapping" +msgstr "ogiltig array till XML-namnrymdmappning" + +#: utils/adt/xml.c:4038 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "Arrayen mÃ¥ste vara tvÃ¥dimensionell där längden pÃ¥ andra axeln är 2." + +#: utils/adt/xml.c:4062 +#, c-format +msgid "empty XPath expression" +msgstr "tomt XPath-uttryck" + +#: utils/adt/xml.c:4114 +#, c-format +msgid "neither namespace name nor URI may be null" +msgstr "varken namnrymdnamn eller URI fÃ¥r vara null" + +#: utils/adt/xml.c:4121 +#, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "kunde inte registrera XML-namnrymd med namn \"%s\" och URL \"%s\"" + +#: utils/adt/xml.c:4472 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "namnrymden DEFAULT stöds inte" + +#: utils/adt/xml.c:4501 +#, c-format +msgid "row path filter must not be empty string" +msgstr "sökvägsfilter för rad fÃ¥r inte vara tomma strängen" + +#: utils/adt/xml.c:4532 +#, c-format +msgid "column path filter must not be empty string" +msgstr "sokvägsfilter för kolumn fÃ¥r inte vara tomma strängen" + +#: utils/adt/xml.c:4682 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "mer än ett värde returnerades frÃ¥n kolumns XPath-uttryck" + +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 +#, c-format +msgid "type %s is only a shell" +msgstr "typ %s är bara en skaltyp" + +#: utils/cache/lsyscache.c:2659 +#, c-format +msgid "no input function available for type %s" +msgstr "ingen inläsningsfunktion finns för typ %s" + +#: utils/cache/lsyscache.c:2692 +#, c-format +msgid "no output function available for type %s" +msgstr "ingen utmatningsfunktion finns för typ %s" + +#: utils/cache/partcache.c:195 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "operatorklass \"%s\" för accessmetod %s saknar supportfunktion %d för typ %s" + +#: utils/cache/plancache.c:718 +#, c-format +msgid "cached plan must not change result type" +msgstr "cache:ad plan fÃ¥r inte ändra resultattyp" + +#: utils/cache/relcache.c:5751 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "kunde inte skapa initieringsfil \"%s\" för relations-cache: %m" + +#: utils/cache/relcache.c:5753 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Fortsätter ändÃ¥, trots att nÃ¥got är fel." + +#: utils/cache/relcache.c:6107 +#, c-format +msgid "could not remove cache file \"%s\": %m" +msgstr "kunde inte ta bort cache-fil \"%s\": %m" + +#: utils/cache/relmapper.c:531 +#, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "kan inte göra PREPARE pÃ¥ en transaktion som ändrat relationsmappningen" + +#: utils/cache/relmapper.c:761 +#, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "relationsmappningsfilen \"%s\" innehÃ¥ller ogiltig data" + +#: utils/cache/relmapper.c:771 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "relationsmappningsfilen \"%s\" innehÃ¥ller en felaktig checksumma" + +#: utils/cache/typcache.c:1634 utils/fmgr/funcapi.c:420 +#, c-format +msgid "record type has not been registered" +msgstr "posttypen har inte registrerats" + +#: utils/error/assert.c:34 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: fel argument\n" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", Fil: \"%s\", Rad: %d)\n" + +#: utils/error/elog.c:319 utils/error/elog.c:1293 +#, c-format +msgid "error occurred at %s:%d before error message processing is available\n" +msgstr "fel uppstod vid %s:%d innan processning av felmeddelande är tillgängligt\n" + +#: utils/error/elog.c:1871 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "kunde inte Ã¥teröppna filen \"%s\" som stderr: %m" + +#: utils/error/elog.c:1884 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "kunde inte Ã¥teröppna filen \"%s\" som stdout: %m" + +#: utils/error/elog.c:2376 utils/error/elog.c:2393 utils/error/elog.c:2409 +msgid "[unknown]" +msgstr "[okänd]" + +#: utils/error/elog.c:2869 utils/error/elog.c:3172 utils/error/elog.c:3280 +msgid "missing error text" +msgstr "saknar feltext" + +#: utils/error/elog.c:2872 utils/error/elog.c:2875 utils/error/elog.c:3283 +#: utils/error/elog.c:3286 +#, c-format +msgid " at character %d" +msgstr " vid tecken %d" + +#: utils/error/elog.c:2885 utils/error/elog.c:2892 +msgid "DETAIL: " +msgstr "DETALJ: " + +#: utils/error/elog.c:2899 +msgid "HINT: " +msgstr "TIPS: " + +#: utils/error/elog.c:2906 +msgid "QUERY: " +msgstr "FRÃ…GA: " + +#: utils/error/elog.c:2913 +msgid "CONTEXT: " +msgstr "KONTEXT: " + +#: utils/error/elog.c:2923 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "PLATS: %s, %s:%d\n" + +#: utils/error/elog.c:2930 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "PLATS: %s:%d\n" + +#: utils/error/elog.c:2944 +msgid "STATEMENT: " +msgstr "SATS: " + +#: utils/error/elog.c:3333 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3337 +msgid "LOG" +msgstr "LOGG" + +#: utils/error/elog.c:3340 +msgid "INFO" +msgstr "INFO" + +#: utils/error/elog.c:3343 +msgid "NOTICE" +msgstr "NOTIS" + +#: utils/error/elog.c:3346 +msgid "WARNING" +msgstr "VARNING" + +#: utils/error/elog.c:3349 +msgid "ERROR" +msgstr "FEL" + +#: utils/error/elog.c:3352 +msgid "FATAL" +msgstr "FATALT" + +#: utils/error/elog.c:3355 +msgid "PANIC" +msgstr "PANIK" + +#: utils/fmgr/dfmgr.c:130 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "kunde inte hitta funktionen \"%s\" i filen \"%s\"" + +#: utils/fmgr/dfmgr.c:247 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "kunde inte ladda länkbibliotek \"%s\": %s" + +#: utils/fmgr/dfmgr.c:279 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "inkompatibelt bibliotek \"%s\": saknar magiskt block" + +#: utils/fmgr/dfmgr.c:281 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "Utökningsbibliotek krävs för att använda macro:t PG_MODULE_MAGIC." + +#: utils/fmgr/dfmgr.c:327 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "inkompatibelt bibliotek \"%s\": versionen stämmer inte" + +#: utils/fmgr/dfmgr.c:329 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Servern är version %d, biblioteket är version %s." + +#: utils/fmgr/dfmgr.c:346 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Servern har FUNC_MAX_ARGS = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:355 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Servern har INDEX_MAX_KEYS = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:364 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Servern har NAMEDATALEN = %d, biblioteket har %d." + +#: utils/fmgr/dfmgr.c:373 +#, c-format +msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +msgstr "Servern har FLOAT4PASSBYVAL = %s, biblioteket har %s." + +#: utils/fmgr/dfmgr.c:382 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Servern har FLOAT8PASSBYVAL = %s, biblioteket har %s." + +#: utils/fmgr/dfmgr.c:389 +msgid "Magic block has unexpected length or padding difference." +msgstr "Magiskt block har oväntad längd eller annan paddning." + +#: utils/fmgr/dfmgr.c:392 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "inkompatibelt bibliotek \"%s\": magiskt block matchar inte" + +#: utils/fmgr/dfmgr.c:556 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "Ã¥tkomst till biblioteket \"%s\" tillÃ¥ts inte" + +#: utils/fmgr/dfmgr.c:582 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "ogiltigt macro-namn i dynamisk biblioteksökväg: %s" + +#: utils/fmgr/dfmgr.c:622 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "komponent med längden noll i parameter \"dynamic_library_path\"" + +#: utils/fmgr/dfmgr.c:641 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "komponent som inte är en absolut sökväg i parameter \"dynamic_library_path\"" + +#: utils/fmgr/fmgr.c:236 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "interna funktionen \"%s\" finns inte i den interna uppslagstabellen" + +#: utils/fmgr/fmgr.c:485 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "kunde inte hitta funktionsinformation för funktion \"%s\"" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "SQL-anropbara funktioner kräver en medföljande PG_FUNCTION_INFO_V1(funknamn)." + +#: utils/fmgr/fmgr.c:505 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "okänd API-version %d rapporterad av infofunktion \"%s\"" + +#: utils/fmgr/fmgr.c:2032 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "sprÃ¥kvalideringsfunktion %u anropad för sprÃ¥k %u istället för %u" + +#: utils/fmgr/funcapi.c:343 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "kunde inte bestämma resultattyp för funktion \"%s\" som deklarerats att returnera typ %s" + +#: utils/fmgr/funcapi.c:1388 utils/fmgr/funcapi.c:1420 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "antalet alias matchar inte antalet kolumner" + +#: utils/fmgr/funcapi.c:1414 +#, c-format +msgid "no column alias was provided" +msgstr "inget kolumnalias angivet" + +#: utils/fmgr/funcapi.c:1438 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "kunde inte fÃ¥ radbeskrivning för funktion som returnerar en record" + +#: utils/init/miscinit.c:110 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "databaskatalogen \"%s\" existerar inte" + +#: utils/init/miscinit.c:115 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %m" + +#: utils/init/miscinit.c:123 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "angiven datakatalog \"%s\" är inte en katalog" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "datakatalogen \"%s\" har fel ägare" + +#: utils/init/miscinit.c:141 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Servern mÃ¥ste startas av den användare som äger datakatalogen." + +#: utils/init/miscinit.c:159 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "datakatalogen \"%s\" har felaktiga rättigheter" + +#: utils/init/miscinit.c:161 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Rättigheterna skall vara u=rwx (0700) eller u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:547 utils/misc/guc.c:6944 +#, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "kan inte sätta parameter \"%s\" frÃ¥n en säkerhetsbegränsad operation" + +#: utils/init/miscinit.c:615 +#, c-format +msgid "role with OID %u does not exist" +msgstr "roll med OID %u existerar inte" + +#: utils/init/miscinit.c:645 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr "roll \"%s\" tillÃ¥ts inte logga in" + +#: utils/init/miscinit.c:663 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "för mÃ¥nga uppkopplingar för roll \"%s\"" + +#: utils/init/miscinit.c:723 +#, c-format +msgid "permission denied to set session authorization" +msgstr "rättighet saknas för att sätta sessionsauktorisation" + +#: utils/init/miscinit.c:806 +#, c-format +msgid "invalid role OID: %u" +msgstr "ogiltigt roll-OID: %u" + +#: utils/init/miscinit.c:860 +#, c-format +msgid "database system is shut down" +msgstr "databassystemet är nedstängt" + +#: utils/init/miscinit.c:947 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "kan inte skapa lÃ¥sfil \"%s\": %m" + +#: utils/init/miscinit.c:961 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "kunde inte öppna lÃ¥sfil \"%s\": %m" + +#: utils/init/miscinit.c:968 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "kunde inte läsa lÃ¥sfil \"%s\": %m" + +#: utils/init/miscinit.c:977 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "lÃ¥sfilen \"%s\" är tom" + +#: utils/init/miscinit.c:978 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "Antingen startar en annan server eller sÃ¥ är lÃ¥sfilen kvar frÃ¥n en tidigare serverkrash vid uppstart." + +#: utils/init/miscinit.c:1022 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "lÃ¥sfil med namn \"%s\" finns redan" + +#: utils/init/miscinit.c:1026 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "Kör en annan postgres (PID %d) i datakatalogen \"%s\"?" + +#: utils/init/miscinit.c:1028 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "Kör en annan postmaster (PID %d) i datakatalogen \"%s\"?" + +#: utils/init/miscinit.c:1031 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "Använder en annan postgres (PID %d) uttagesfilen (socket) \"%s\"?" + +#: utils/init/miscinit.c:1033 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "Använder en annan postmaster (PID %d) uttagesfilen (socket) \"%s\"?" + +#: utils/init/miscinit.c:1084 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "kunde inte ta bort gammal lÃ¥sfil \"%s\": %m" + +#: utils/init/miscinit.c:1086 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "Filen verkar ha lämnats kvar av misstag, men kan inte tas bort. Ta bort den för hand och försök igen.>" + +#: utils/init/miscinit.c:1123 utils/init/miscinit.c:1137 +#: utils/init/miscinit.c:1148 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "kunde inte skriva lÃ¥sfil \"%s\": %m" + +#: utils/init/miscinit.c:1280 utils/init/miscinit.c:1423 utils/misc/guc.c:9851 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "kunde inte läsa frÃ¥n fil \"%s\": %m" + +#: utils/init/miscinit.c:1411 +#, c-format +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "kunde inte öppna fil \"%s\": %m: fortsätter ändÃ¥" + +#: utils/init/miscinit.c:1436 +#, c-format +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "lÃ¥sfil \"%s\" innehÃ¥ller fel PID: %ld istället för %ld" + +#: utils/init/miscinit.c:1475 utils/init/miscinit.c:1491 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" är inte en giltigt datakatalog" + +#: utils/init/miscinit.c:1477 +#, c-format +msgid "File \"%s\" is missing." +msgstr "Filen \"%s\" saknas." + +#: utils/init/miscinit.c:1493 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "Filen \"%s\" innehÃ¥ller inte giltig data." + +#: utils/init/miscinit.c:1495 +#, c-format +msgid "You might need to initdb." +msgstr "Du kan behöva köra initdb." + +#: utils/init/miscinit.c:1503 +#, c-format +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "Datakatalogen har skapats av PostgreSQL version %s, som inte är kompatibel med version %s." + +#: utils/init/miscinit.c:1570 +#, c-format +msgid "loaded library \"%s\"" +msgstr "laddat bibliotek \"%s\"" + +#: utils/init/postinit.c:255 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "replikeringsanslutning auktoriserad: användare=%s application_name=%s SSL pÃ¥slagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "off" +msgstr "av" + +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 +msgid "on" +msgstr "pÃ¥" + +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "replikeringsanslutning auktoriserad: användare=%s SSL pÃ¥slagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:272 +#, c-format +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "replikeringsanslutning auktoriserad: användare=%s application_name=%s" + +#: utils/init/postinit.c:275 +#, c-format +msgid "replication connection authorized: user=%s" +msgstr "replikeringsanslutning auktoriserad: användare=%s" + +#: utils/init/postinit.c:284 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "anslutning auktoriserad: användare=%s databas=%s application_name=%s SSL pÃ¥slagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:290 +#, c-format +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "anslutning auktoriserad: användare=%s databas=%s SSL pÃ¥slagen (protokoll=%s, krypto=%s, bitar=%d, komprimering=%s)" + +#: utils/init/postinit.c:300 +#, c-format +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "anslutning auktoriserad: användare=%s databas=%s application_name=%s" + +#: utils/init/postinit.c:302 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "anslutning auktoriserad: användare=%s databas=%s" + +#: utils/init/postinit.c:334 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "databasen \"%s\" har försvunnit frÃ¥n pg_database" + +#: utils/init/postinit.c:336 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "Databasen med OID %u verkar nu höra till \"%s\"." + +#: utils/init/postinit.c:356 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "databasen \"%s\" tar för närvarande inte emot uppkopplingar" + +#: utils/init/postinit.c:369 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "rättighet saknas för databas \"%s\"" + +#: utils/init/postinit.c:370 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Användaren har inte rättigheten CONNECT." + +#: utils/init/postinit.c:387 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "för mÃ¥nga uppkopplingar till databasen \"%s\"" + +#: utils/init/postinit.c:409 utils/init/postinit.c:416 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "databaslokalen är inkompatibel med operativsystemet" + +#: utils/init/postinit.c:410 +#, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "Databasen initierades med LC_COLLATE \"%s\" vilket inte känns igen av setlocale()." + +#: utils/init/postinit.c:412 utils/init/postinit.c:419 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "Ã…terskapa databasen med en annan lokal eller installera den saknade lokalen." + +#: utils/init/postinit.c:417 +#, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "Databasen initierades med LC_CTYPE \"%s\", vilket inte känns igen av setlocale()." + +#: utils/init/postinit.c:764 +#, c-format +msgid "no roles are defined in this database system" +msgstr "inga roller är definierade i detta databassystem" + +#: utils/init/postinit.c:765 +#, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Du borde direkt köra CREATE USER \"%s\" SUPERUSER;." + +#: utils/init/postinit.c:801 +#, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "nya replikeringsanslutningar tillÃ¥ts inte under databasnedstängning" + +#: utils/init/postinit.c:805 +#, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "mÃ¥ste vara superanvändare för att ansluta när databasen hÃ¥ller pÃ¥ att stängas ner" + +#: utils/init/postinit.c:815 +#, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "mÃ¥ste vara superanvändare för att ansluta i binärt uppgraderingsläger" + +#: utils/init/postinit.c:828 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "resterande anslutningsslottar är reserverade för superanvändaranslutningar utan replikering" + +#: utils/init/postinit.c:838 +#, c-format +msgid "must be superuser or replication role to start walsender" +msgstr "mÃ¥ste vara superanvändare eller replikeringsroll för att starta \"walsender\"" + +#: utils/init/postinit.c:907 +#, c-format +msgid "database %u does not exist" +msgstr "databasen %u existerar inte" + +#: utils/init/postinit.c:996 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Det verkar precis ha tagits bort eller döpts om." + +#: utils/init/postinit.c:1014 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Databasens underbibliotek \"%s\" saknas." + +#: utils/init/postinit.c:1019 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "kunde inte komma Ã¥t katalog \"%s\": %m" + +#: utils/mb/conv.c:488 utils/mb/conv.c:680 +#, c-format +msgid "invalid encoding number: %d" +msgstr "ogiltigt kodningsnummer: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "oväntat kodnings-ID %d för ISO 8859-teckenuppsättningarna" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "oväntat kodnings-ID %d för WIN-teckenuppsättningarna" + +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "kodning \"%s\" stöds inte av ICU" + +#: utils/mb/encnames.c:572 +#, c-format +msgid "encoding name too long" +msgstr "kodningsnamnet är för lÃ¥ngt" + +#: utils/mb/mbutils.c:296 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "konvertering mellan %s och %s stöds inte" + +#: utils/mb/mbutils.c:355 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "standardkonverteringsfunktion för kodning \"%s\" till \"%s\" finns inte" + +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "Sträng pÃ¥ %d byte är för lÃ¥ng för kodningskonvertering." + +#: utils/mb/mbutils.c:453 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "ogiltigt källkodningsnamn \"%s\"" + +#: utils/mb/mbutils.c:458 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "ogiltigt mÃ¥lkodningsnamn \"%s\"" + +#: utils/mb/mbutils.c:598 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "ogiltigt byte-sekvens för kodning \"%s\": 0x%02x\"" + +#: utils/mb/mbutils.c:940 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset misslyckades" + +#: utils/mb/wchar.c:2033 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "ogiltigt byte-sekvens för kodning \"%s\": %s" + +#: utils/mb/wchar.c:2066 +#, c-format +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "tecken med byte-sekvens %s i kodning \"%s\" har inget motsvarande i kodning \"%s\"" + +#: utils/misc/guc.c:636 +msgid "Ungrouped" +msgstr "Ej grupperad" + +#: utils/misc/guc.c:638 +msgid "File Locations" +msgstr "Filplatser" + +#: utils/misc/guc.c:640 +msgid "Connections and Authentication" +msgstr "Uppkopplingar och Autentisering" + +#: utils/misc/guc.c:642 +msgid "Connections and Authentication / Connection Settings" +msgstr "Uppkopplingar och Autentisering / Uppkopplingsinställningar" + +#: utils/misc/guc.c:644 +msgid "Connections and Authentication / Authentication" +msgstr "Uppkopplingar och Autentisering / Autentisering" + +#: utils/misc/guc.c:646 +msgid "Connections and Authentication / SSL" +msgstr "Uppkopplingar och Autentisering / SSL" + +#: utils/misc/guc.c:648 +msgid "Resource Usage" +msgstr "Resursanvändning" + +#: utils/misc/guc.c:650 +msgid "Resource Usage / Memory" +msgstr "Resursanvändning / Minne" + +#: utils/misc/guc.c:652 +msgid "Resource Usage / Disk" +msgstr "Resursanvändning / Disk" + +#: utils/misc/guc.c:654 +msgid "Resource Usage / Kernel Resources" +msgstr "Resursanvändning / Kärnresurser" + +#: utils/misc/guc.c:656 +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Resursanvändning / Kostnadsbaserad Vacuum-fördröjning" + +#: utils/misc/guc.c:658 +msgid "Resource Usage / Background Writer" +msgstr "Resursanvändning / Bakgrundskrivare" + +#: utils/misc/guc.c:660 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Resursanvändning / Asynkront beteende" + +#: utils/misc/guc.c:662 +msgid "Write-Ahead Log" +msgstr "Write-Ahead Log" + +#: utils/misc/guc.c:664 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead Log / Inställningar" + +#: utils/misc/guc.c:666 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead Log / Checkpoint:er" + +#: utils/misc/guc.c:668 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead Log / Arkivering" + +#: utils/misc/guc.c:670 +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead Log / Ã…terställning frÃ¥n arkiv" + +#: utils/misc/guc.c:672 +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead Log / Ã…terställningsmÃ¥l" + +#: utils/misc/guc.c:674 +msgid "Replication" +msgstr "Replikering" + +#: utils/misc/guc.c:676 +msgid "Replication / Sending Servers" +msgstr "Replilering / Skickande servrar" + +#: utils/misc/guc.c:678 +msgid "Replication / Master Server" +msgstr "Replikering / Master-server" + +#: utils/misc/guc.c:680 +msgid "Replication / Standby Servers" +msgstr "Replikering / Standby-servrar" + +#: utils/misc/guc.c:682 +msgid "Replication / Subscribers" +msgstr "Replikering / Prenumeranter" + +#: utils/misc/guc.c:684 +msgid "Query Tuning" +msgstr "FrÃ¥geoptimering" + +#: utils/misc/guc.c:686 +msgid "Query Tuning / Planner Method Configuration" +msgstr "FrÃ¥geoptimering / Planeringsmetodinställningar" + +#: utils/misc/guc.c:688 +msgid "Query Tuning / Planner Cost Constants" +msgstr "FrÃ¥geoptimering / Plannerarens kostnadskonstanter" + +#: utils/misc/guc.c:690 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "FrÃ¥geoptimering / Genetisk frÃ¥geoptimerare" + +#: utils/misc/guc.c:692 +msgid "Query Tuning / Other Planner Options" +msgstr "FrÃ¥geoptimering / Andra planeringsinställningar" + +#: utils/misc/guc.c:694 +msgid "Reporting and Logging" +msgstr "Rapportering och loggning" + +#: utils/misc/guc.c:696 +msgid "Reporting and Logging / Where to Log" +msgstr "Rapportering och loggning / Logga var?" + +#: utils/misc/guc.c:698 +msgid "Reporting and Logging / When to Log" +msgstr "Rapportering och loggning / Logga när?" + +#: utils/misc/guc.c:700 +msgid "Reporting and Logging / What to Log" +msgstr "Rapportering och loggning / Logga vad?" + +#: utils/misc/guc.c:702 +msgid "Process Title" +msgstr "Processtitel" + +#: utils/misc/guc.c:704 +msgid "Statistics" +msgstr "Statistik" + +#: utils/misc/guc.c:706 +msgid "Statistics / Monitoring" +msgstr "Statistik / Övervakning" + +#: utils/misc/guc.c:708 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "Statistik / Insamlare av frÃ¥ge- och index-statistik" + +#: utils/misc/guc.c:710 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:712 +msgid "Client Connection Defaults" +msgstr "Standard för klientanslutning" + +#: utils/misc/guc.c:714 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "Standard för klientanslutning / Satsbeteende" + +#: utils/misc/guc.c:716 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "Standard för klientanslutning / Lokal och formattering" + +#: utils/misc/guc.c:718 +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "Standard för klientanslutning / Förladdning av delat bibliotek" + +#: utils/misc/guc.c:720 +msgid "Client Connection Defaults / Other Defaults" +msgstr "Standard för klientanslutning / Övriga standardvärden" + +#: utils/misc/guc.c:722 +msgid "Lock Management" +msgstr "LÃ¥shantering" + +#: utils/misc/guc.c:724 +msgid "Version and Platform Compatibility" +msgstr "Version och plattformskompabilitet" + +#: utils/misc/guc.c:726 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Version och plattformskompabilitet / Tidigare PostrgreSQL-versioner" + +#: utils/misc/guc.c:728 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Version och plattformskompabilitet / Andra plattformar och klienter" + +#: utils/misc/guc.c:730 +msgid "Error Handling" +msgstr "Felhantering" + +#: utils/misc/guc.c:732 +msgid "Preset Options" +msgstr "Förinställningsflaggor" + +#: utils/misc/guc.c:734 +msgid "Customized Options" +msgstr "Ändrade flaggor" + +#: utils/misc/guc.c:736 +msgid "Developer Options" +msgstr "Utvecklarflaggor" + +#: utils/misc/guc.c:788 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Giltiga enheter för denna parameter är \"B\", \"kB\", \"MB\", \"GB\" och \"TB\"." + +#: utils/misc/guc.c:825 +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Giltiga enheter för denna parameter är \"us\", \"ms\", \"s\", \"min\", \"h\" och \"d\"." + +#: utils/misc/guc.c:887 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Aktiverar planerarens användning av planer med sekvensiell skanning." + +#: utils/misc/guc.c:897 +msgid "Enables the planner's use of index-scan plans." +msgstr "Aktiverar planerarens användning av planer med indexskanning." + +#: utils/misc/guc.c:907 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Aktiverar planerarens användning av planer med skanning av enbart index." + +#: utils/misc/guc.c:917 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Aktiverar planerarens användning av planer med bitmapskanning." + +#: utils/misc/guc.c:927 +msgid "Enables the planner's use of TID scan plans." +msgstr "Aktiverar planerarens användning av planer med TID-skanning." + +#: utils/misc/guc.c:937 +msgid "Enables the planner's use of explicit sort steps." +msgstr "SlÃ¥r pÃ¥ planerarens användning av explicita sorteringssteg." + +#: utils/misc/guc.c:947 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Aktiverar planerarens användning av planer med hash-aggregering" + +#: utils/misc/guc.c:957 +msgid "Enables the planner's use of materialization." +msgstr "Aktiverar planerarens användning av materialisering." + +#: utils/misc/guc.c:967 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Aktiverar planerarens användning av planer med nästlad loop-join," + +#: utils/misc/guc.c:977 +msgid "Enables the planner's use of merge join plans." +msgstr "Aktiverar planerarens användning av merge-join-planer." + +#: utils/misc/guc.c:987 +msgid "Enables the planner's use of hash join plans." +msgstr "Aktiverar planerarens användning av hash-join-planer." + +#: utils/misc/guc.c:997 +msgid "Enables the planner's use of gather merge plans." +msgstr "Aktiverar planerarens användning av planer med gather-merge." + +#: utils/misc/guc.c:1007 +msgid "Enables partitionwise join." +msgstr "Aktiverar join per partition." + +#: utils/misc/guc.c:1017 +msgid "Enables partitionwise aggregation and grouping." +msgstr "Aktiverar aggregering och gruppering per partition." + +#: utils/misc/guc.c:1027 +msgid "Enables the planner's use of parallel append plans." +msgstr "Aktiverar planerarens användning av planer med parallell append." + +#: utils/misc/guc.c:1037 +msgid "Enables the planner's use of parallel hash plans." +msgstr "Aktiverar planerarens användning av planer med parallell hash." + +#: utils/misc/guc.c:1047 +msgid "Enable plan-time and run-time partition pruning." +msgstr "Aktiverar partitionsbeskärning vid planering och vid körning." + +#: utils/misc/guc.c:1048 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "TillÃ¥ter att frÃ¥geplaneraren och exekveraren jämför partitionsgränser med villkor i frÃ¥gan för att bestämma vilka partitioner som skall skannas." + +#: utils/misc/guc.c:1059 +msgid "Enables genetic query optimization." +msgstr "Aktiverar genetisk frÃ¥geoptimering." + +#: utils/misc/guc.c:1060 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Denna algoritm försöker utföra planering utan fullständig sökning." + +#: utils/misc/guc.c:1071 +msgid "Shows whether the current user is a superuser." +msgstr "Visar om den aktuella användaren är en superanvändare." + +#: utils/misc/guc.c:1081 +msgid "Enables advertising the server via Bonjour." +msgstr "Aktiverar annonsering av servern via Bonjour." + +#: utils/misc/guc.c:1090 +msgid "Collects transaction commit time." +msgstr "Samlar in tid för transaktions-commit." + +#: utils/misc/guc.c:1099 +msgid "Enables SSL connections." +msgstr "TillÃ¥ter SSL-anslutningar." + +#: utils/misc/guc.c:1108 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "Använd ssl_passphrase_command även vid server-reload." + +#: utils/misc/guc.c:1117 +msgid "Give priority to server ciphersuite order." +msgstr "Ge prioritet till serverns ordning av kryptometoder." + +#: utils/misc/guc.c:1126 +msgid "Forces synchronization of updates to disk." +msgstr "Tvingar synkronisering av uppdateringar till disk." + +#: utils/misc/guc.c:1127 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "Servern kommer använda systemanropet fsync() pÃ¥ ett antal platser för att se till att uppdateringar fysiskt skrivs till disk. Detta för att säkerställa att databasklustret kan starta i ett konsistent tillstÃ¥nd efter en operativsystemkrash eller hÃ¥rdvarukrash." + +#: utils/misc/guc.c:1138 +msgid "Continues processing after a checksum failure." +msgstr "Fortsätter processande efter checksummefel." + +#: utils/misc/guc.c:1139 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "Normalt vid detektion av checksummefel sÃ¥ rapporterar PostgreSQL felet och avbryter den aktuella transaktionen. Sätts ignore_checksum_failure till true sÃ¥ kommer systemet hoppa över felet (men fortfarande rapportera en varning). Detta beteende kan orsaka krasher eller andra allvarliga problem. Detta pÃ¥verkas bara om checksummor är pÃ¥slaget." + +#: utils/misc/guc.c:1153 +msgid "Continues processing past damaged page headers." +msgstr "Fortsätter processande efter trasiga sidhuvuden." + +#: utils/misc/guc.c:1154 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "Normalt vid detektion av trasiga sidhuvuden sÃ¥ rapporterar PostgreSQL felet och avbryter den aktuella transaktionen. Sätts zero_damaged_pages till true sÃ¥ kommer systemet istället rapportera en varning, nollställa den trasiga sidan samt fortsätta processa. Detta kommer förstöra data (alla rader i den trasiga sidan)." + +#: utils/misc/guc.c:1167 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Skriver fulla sidor till WAL första gÃ¥ngen de ändras efter en checkpoint." + +#: utils/misc/guc.c:1168 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "En sidskrivning som sker vid en operativsystemkrash kan bli delvis utskriven till disk. Under Ã¥terställning sÃ¥ kommer radändringar i WAL:en inte vara tillräckligt för att Ã¥terställa datan. Denna flagga skriver ut sidor först efter att en WAL-checkpoint gjorts vilket gör att full Ã¥terställning kan ske." + +#: utils/misc/guc.c:1181 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "Skriver fulla sidor till WAL första gÃ¥ngen de ändras efter en checkpoint, även för ickekritiska ändringar." + +#: utils/misc/guc.c:1191 +msgid "Compresses full-page writes written in WAL file." +msgstr "Komprimerar skrivning av hela sidor som skrivs i WAL-fil." + +#: utils/misc/guc.c:1201 +msgid "Writes zeroes to new WAL files before first use." +msgstr "Skriv nollor till nya WAL-filer innan första användning." + +#: utils/misc/guc.c:1211 +msgid "Recycles WAL files by renaming them." +msgstr "Ã…teranvänder WAL-filer genom att byta namn pÃ¥ dem." + +#: utils/misc/guc.c:1221 +msgid "Logs each checkpoint." +msgstr "Logga varje checkpoint." + +#: utils/misc/guc.c:1230 +msgid "Logs each successful connection." +msgstr "Logga varje lyckad anslutning." + +#: utils/misc/guc.c:1239 +msgid "Logs end of a session, including duration." +msgstr "Loggar slut pÃ¥ session, inklusive längden." + +#: utils/misc/guc.c:1248 +msgid "Logs each replication command." +msgstr "Loggar alla replikeringskommanon." + +#: utils/misc/guc.c:1257 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Visar om den körande servern har assert-kontroller pÃ¥slagna." + +#: utils/misc/guc.c:1272 +msgid "Terminate session on any error." +msgstr "Avbryt sessionen vid fel." + +#: utils/misc/guc.c:1281 +msgid "Reinitialize server after backend crash." +msgstr "Ã…terinitiera servern efter en backend-krash." + +#: utils/misc/guc.c:1291 +msgid "Logs the duration of each completed SQL statement." +msgstr "Loggar tiden för varje avslutad SQL-sats." + +#: utils/misc/guc.c:1300 +msgid "Logs each query's parse tree." +msgstr "Loggar alla frÃ¥gors parse-träd." + +#: utils/misc/guc.c:1309 +msgid "Logs each query's rewritten parse tree." +msgstr "Logga alla frÃ¥gors omskrivet parse-träd." + +#: utils/misc/guc.c:1318 +msgid "Logs each query's execution plan." +msgstr "Logga alla frÃ¥gors körningsplan." + +#: utils/misc/guc.c:1327 +msgid "Indents parse and plan tree displays." +msgstr "Indentera parse och planeringsträdutskrifter" + +#: utils/misc/guc.c:1336 +msgid "Writes parser performance statistics to the server log." +msgstr "Skriver parserns prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1345 +msgid "Writes planner performance statistics to the server log." +msgstr "Skriver planerarens prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1354 +msgid "Writes executor performance statistics to the server log." +msgstr "Skrivere exekverarens prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1363 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Skriver ackumulerad prestandastatistik till serverloggen." + +#: utils/misc/guc.c:1373 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Loggar statisik för användning av systemresurser (minne och CPU) för olika B-tree-operationer." + +#: utils/misc/guc.c:1385 +msgid "Collects information about executing commands." +msgstr "Samla information om körda kommanon." + +#: utils/misc/guc.c:1386 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "SlÃ¥r pÃ¥ insamling av information om det nu körande kommandot för varje session, tillsammans med klockslaget när det kommandot började köra." + +#: utils/misc/guc.c:1396 +msgid "Collects statistics on database activity." +msgstr "Samla in statistik om databasaktivitet." + +#: utils/misc/guc.c:1405 +msgid "Collects timing statistics for database I/O activity." +msgstr "Samla in timingstatistik om databasens I/O-aktivitet." + +#: utils/misc/guc.c:1415 +msgid "Updates the process title to show the active SQL command." +msgstr "Uppdaterar processtitel till att visa aktivt SQL-kommando." + +#: utils/misc/guc.c:1416 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "SlÃ¥r pÃ¥ uppdatering av processtiteln varje gÃ¥ng ett nytt SQL-kommando tas emot av servern." + +#: utils/misc/guc.c:1429 +msgid "Starts the autovacuum subprocess." +msgstr "Starta autovacuum-barnprocess." + +#: utils/misc/guc.c:1439 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "Skapar debug-output för LISTEN och NOTIFY." + +#: utils/misc/guc.c:1451 +msgid "Emits information about lock usage." +msgstr "Visar information om lÃ¥sanvändning." + +#: utils/misc/guc.c:1461 +msgid "Emits information about user lock usage." +msgstr "Visar information om användares lÃ¥sanvändning." + +#: utils/misc/guc.c:1471 +msgid "Emits information about lightweight lock usage." +msgstr "Visar information om lättviktig lÃ¥sanvändning." + +#: utils/misc/guc.c:1481 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Dumpar information om alla aktuella lÃ¥s när en deadlock-timeout sker." + +#: utils/misc/guc.c:1493 +msgid "Logs long lock waits." +msgstr "Loggar lÃ¥nga väntetider pÃ¥ lÃ¥s." + +#: utils/misc/guc.c:1503 +msgid "Logs the host name in the connection logs." +msgstr "Loggar hostnamnet i anslutningsloggen." + +#: utils/misc/guc.c:1504 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "Som standard visar anslutningsloggen bara IP-adressen för den anslutande värden. Om du vill att värdnamnet skall visas sÃ¥ kan du slÃ¥ pÃ¥ detta men beroende pÃ¥ hur uppsättningen av namnuppslag är gjored sÃ¥ kan detta ha en markant prestandapÃ¥verkan." + +#: utils/misc/guc.c:1515 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "Tolkar \"uttryck=NULL\" som \"uttryck IS NULL\"." + +#: utils/misc/guc.c:1516 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Om pÃ¥slagen sÃ¥ kommer uttryck pÃ¥ formen uttryck = NULL (eller NULL = uttryck) att behandlas som uttryck IS NULL, det vill säga returnera true om uttryck evalueras till värdet null eller evalueras till false annars. Det korrekta beteendet för uttryck = NULL är att alltid returnera null (okänt)." + +#: utils/misc/guc.c:1528 +msgid "Enables per-database user names." +msgstr "Aktiverar användarnamn per databas." + +#: utils/misc/guc.c:1537 +msgid "Sets the default read-only status of new transactions." +msgstr "Ställer in standard read-only-status för nya transaktioner." + +#: utils/misc/guc.c:1546 +msgid "Sets the current transaction's read-only status." +msgstr "Ställer in nuvarande transaktions read-only-status." + +#: utils/misc/guc.c:1556 +msgid "Sets the default deferrable status of new transactions." +msgstr "Ställer in standard deferrable-status för nya transaktioner." + +#: utils/misc/guc.c:1565 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "Bestämmer om en serialiserbar transaktion för läsning kommer fördröjas tills den kan köras utan serialiseringsfel." + +#: utils/misc/guc.c:1575 +msgid "Enable row security." +msgstr "Aktiverar radsäkerhet." + +#: utils/misc/guc.c:1576 +msgid "When enabled, row security will be applied to all users." +msgstr "Om aktiv sÃ¥ kommer radsäkerhet användas för alla användare." + +#: utils/misc/guc.c:1584 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "Kontrollera funktionskroppen vid CREATE FUNCTION." + +#: utils/misc/guc.c:1593 +msgid "Enable input of NULL elements in arrays." +msgstr "Aktiverar inmatning av NULL-element i arrayer." + +#: utils/misc/guc.c:1594 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Om pÃ¥slagen sÃ¥ kommer ej citerade NULL i indatavärden för en array betyda värdet null, annars tolkas det bokstavligt." + +#: utils/misc/guc.c:1610 +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "WITH OIDS stöds inte längre; denna kan bara vara false." + +#: utils/misc/guc.c:1620 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "Starta en subprocess för att fÃ¥nga output frÃ¥n stderr och/eller csv-loggar till loggfiler." + +#: utils/misc/guc.c:1629 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Trunkera existerande loggfiler med samma namn under loggrotering." + +#: utils/misc/guc.c:1640 +msgid "Emit information about resource usage in sorting." +msgstr "Skicka ut information om resursanvändning vid sortering." + +#: utils/misc/guc.c:1654 +msgid "Generate debugging output for synchronized scanning." +msgstr "Generera debug-output för synkroniserad skanning." + +#: utils/misc/guc.c:1669 +msgid "Enable bounded sorting using heap sort." +msgstr "SlÃ¥r pÃ¥ begränsad sortering med heap-sort." + +#: utils/misc/guc.c:1682 +msgid "Emit WAL-related debugging output." +msgstr "Skicka ut WAL-relaterad debug-data." + +#: utils/misc/guc.c:1694 +msgid "Datetimes are integer based." +msgstr "Datetime är heltalsbaserad" + +#: utils/misc/guc.c:1705 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Bestämmer om Kerberos- och GSSAPI-användarnamn skall tolkas skiftlägesokänsligt." + +#: utils/misc/guc.c:1715 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Varna om backÃ¥tstreck-escape i vanliga stränglitteraler." + +#: utils/misc/guc.c:1725 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "Gör att '...'-stängar tolkar bakÃ¥tstreck bokstavligt." + +#: utils/misc/guc.c:1736 +msgid "Enable synchronized sequential scans." +msgstr "SlÃ¥ pÃ¥ synkroniserad sekvensiell skanning." + +#: utils/misc/guc.c:1746 +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "Ställer in om man skall inkludera eller exkludera transaktion för Ã¥terställningmÃ¥l." + +#: utils/misc/guc.c:1756 +msgid "Allows connections and queries during recovery." +msgstr "TillÃ¥t anslutningar och frÃ¥gor under Ã¥terställning." + +#: utils/misc/guc.c:1766 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "TillÃ¥ter feedback frÃ¥n en hot standby till primären för att undvika frÃ¥gekonflikter." + +#: utils/misc/guc.c:1776 +msgid "Allows modifications of the structure of system tables." +msgstr "TillÃ¥ter strukturförändringar av systemtabeller." + +#: utils/misc/guc.c:1787 +msgid "Disables reading from system indexes." +msgstr "Stänger av läsning frÃ¥n systemindex." + +#: utils/misc/guc.c:1788 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "Det förhindrar inte uppdatering av index sÃ¥ det är helt säkert att använda. Det värsta som kan hända är att det är lÃ¥ngsamt." + +#: utils/misc/guc.c:1799 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "SlÃ¥r pÃ¥ bakÃ¥tkompabilitetsläge för rättighetskontroller pÃ¥ stora objekt." + +#: utils/misc/guc.c:1800 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "Hoppar över rättighetskontroller vid läsning eller modifiering av stora objekt, för kompabilitet med PostgreSQL-releaser innan 9.0." + +#: utils/misc/guc.c:1810 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "Skicka ut varning för konstruktioner som ändrat semantik sedan PostgreSQL 9.4." + +#: utils/misc/guc.c:1820 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "När SQL-fragment genereras sÃ¥ citera alla identifierare." + +#: utils/misc/guc.c:1830 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Visar om datachecksummor är pÃ¥slagna för detta kluster." + +#: utils/misc/guc.c:1841 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "Lägg till sekvensnummer till syslog-meddelanden för att undvika att duplikat tas bort." + +#: utils/misc/guc.c:1851 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "Dela meddelanden som skickas till syslog till egna rader och begränsa till 1024 byte." + +#: utils/misc/guc.c:1861 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "Bestämmer om \"Gather\" och \"Gather Merge\" ocksÃ¥ exekverar subplaner." + +#: utils/misc/guc.c:1862 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "Skall gather-noder ocksÃ¥ exekvera subplaner eller bara samla in tupler?" + +#: utils/misc/guc.c:1872 +msgid "Allow JIT compilation." +msgstr "TillÃ¥t JIT-kompilering." + +#: utils/misc/guc.c:1883 +msgid "Register JIT compiled function with debugger." +msgstr "Registrera JIT-kompilerad funktion hos debuggern." + +#: utils/misc/guc.c:1900 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "Skriv ut LLVM-bitkod för att möjliggöra JIT-debuggning." + +#: utils/misc/guc.c:1911 +msgid "Allow JIT compilation of expressions." +msgstr "TillÃ¥t JIT-kompilering av uttryck." + +#: utils/misc/guc.c:1922 +msgid "Register JIT compiled function with perf profiler." +msgstr "Registrera JIT-kompilerad funktion med perf-profilerare." + +#: utils/misc/guc.c:1939 +msgid "Allow JIT compilation of tuple deforming." +msgstr "TillÃ¥t JIT-kompilering av tupeluppdelning." + +#: utils/misc/guc.c:1950 +msgid "Whether to continue running after a failure to sync data files." +msgstr "Hurvida vi skall fortsätta efter ett fel att synka datafiler." + +#: utils/misc/guc.c:1968 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "Tvingar byte till nästa WAL-fil om en ny fil inte har startats inom N sekunder." + +#: utils/misc/guc.c:1979 +msgid "Waits N seconds on connection startup after authentication." +msgstr "Väntar N sekunder vid anslutningsstart efter authentisering." + +#: utils/misc/guc.c:1980 utils/misc/guc.c:2526 +msgid "This allows attaching a debugger to the process." +msgstr "Detta tillÃ¥ter att man ansluter en debugger till processen." + +#: utils/misc/guc.c:1989 +msgid "Sets the default statistics target." +msgstr "Sätter standardstatistikmÃ¥let." + +#: utils/misc/guc.c:1990 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "Detta gäller tabellkolumner som inte har ett kolumnspecifikt mÃ¥l satt med ALTER TABLE SET STATISTICS." + +#: utils/misc/guc.c:1999 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "Sätter en övre gräns pÃ¥ FROM-listans storlek där subfrÃ¥gor slÃ¥s isär." + +#: utils/misc/guc.c:2001 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "Planeraren kommer slÃ¥ samman subfrÃ¥gor med yttre frÃ¥gor om den resulterande FROM-listan inte har fler än sÃ¥ här mÃ¥nga poster." + +#: utils/misc/guc.c:2012 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "Sätter en övre gräns pÃ¥ FROM-listans storlek där JOIN-konstruktioner plattas till." + +#: utils/misc/guc.c:2014 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "Planeraren kommer platta till explicita JOIN-konstruktioner till listor av FROM-poster när resultatet blir en lista med max sÃ¥ här mÃ¥nga poster." + +#: utils/misc/guc.c:2025 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "Sätter en undre gräns pÃ¥ antal FROM-poster när GEQO används." + +#: utils/misc/guc.c:2035 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: effort används som standard för andra GEQO-parametrar." + +#: utils/misc/guc.c:2045 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: antal individer i populationen." + +#: utils/misc/guc.c:2046 utils/misc/guc.c:2056 +msgid "Zero selects a suitable default value." +msgstr "Noll väljer ett lämpligt standardvärde." + +#: utils/misc/guc.c:2055 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: antal iterationer för algoritmen." + +#: utils/misc/guc.c:2067 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Sätter tiden som väntas pÃ¥ ett lÃ¥s innan kontroll av deadlock sker." + +#: utils/misc/guc.c:2078 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "Sätter maximal fördröjning innan frÃ¥gor avbryts när en \"hot standby\"-server processar arkiverad WAL-data." + +#: utils/misc/guc.c:2089 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "Sätter maximal fördröjning innan frÃ¥gor avbryts när en \"hot stanby\"-server processar strömmad WAL-data." + +#: utils/misc/guc.c:2100 +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "Ställer in minsta fördröjning för att applicera ändringar under Ã¥terställning." + +#: utils/misc/guc.c:2111 +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." +msgstr "Sätter maximalt intervall mellan statusrapporter till skickande server frÃ¥n WAL-mottagaren." + +#: utils/misc/guc.c:2122 +msgid "Sets the maximum wait time to receive data from the sending server." +msgstr "Sätter maximal väntetid för att ta emot data frÃ¥n skickande server." + +#: utils/misc/guc.c:2133 +msgid "Sets the maximum number of concurrent connections." +msgstr "Sätter maximalt antal samtidiga anslutningar." + +#: utils/misc/guc.c:2144 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Sätter antalet anslutningsslottar som reserverats för superanvändare." + +#: utils/misc/guc.c:2158 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Sätter antalet delade minnesbuffrar som används av servern." + +#: utils/misc/guc.c:2169 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Sätter maximalt antal temporära buffertar som används per session." + +#: utils/misc/guc.c:2180 +msgid "Sets the TCP port the server listens on." +msgstr "Sätter TCP-porten som servern lyssnar pÃ¥." + +#: utils/misc/guc.c:2190 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Sätter accessrättigheter för Unix-domainuttag (socket)." + +#: utils/misc/guc.c:2191 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unixdomänuttag (socket) använder unix vanliga filsystemsrättigheter. Parametervärdet förväntas vara en numerisk rättighetsangivelse sÃ¥ som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet sÃ¥ mÃ¥ste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2205 +msgid "Sets the file permissions for log files." +msgstr "Sätter filrättigheter för loggfiler." + +#: utils/misc/guc.c:2206 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Parametervärdet förväntas vara en numerisk rättighetsangivelse sÃ¥ som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet sÃ¥ mÃ¥ste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2220 +msgid "Mode of the data directory." +msgstr "Läge för datakatalog." + +#: utils/misc/guc.c:2221 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Parametervärdet är en numerisk rättighetsangivelse sÃ¥ som accepteras av systemanropen chmod och umask. (För att använda det vanliga oktala formatet sÃ¥ mÃ¥ste numret börja med 0 (noll).)" + +#: utils/misc/guc.c:2234 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Sätter maximalt minne som används för frÃ¥gors arbetsyta." + +#: utils/misc/guc.c:2235 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "SÃ¥ här mycket minne kan användas av varje intern sorteringsoperation resp. hash-tabell innan temporära filer pÃ¥ disk börjar användas." + +#: utils/misc/guc.c:2247 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Sätter det maximala minnet som fÃ¥r användas för underhÃ¥llsoperationer." + +#: utils/misc/guc.c:2248 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Detta inkluderar operationer som VACUUM och CREATE INDEX." + +#: utils/misc/guc.c:2263 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Sätter det maximala stackdjupet, i kilobyte." + +#: utils/misc/guc.c:2274 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Begränsar den totala storleken för alla temporära filer som används i en process." + +#: utils/misc/guc.c:2275 +msgid "-1 means no limit." +msgstr "-1 betyder ingen gräns." + +#: utils/misc/guc.c:2285 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Vacuum-kostnad för en sida som hittas i buffer-cache:n." + +#: utils/misc/guc.c:2295 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Vacuum-kostnad för en sida som inte hittas i buffer-cache:n." + +#: utils/misc/guc.c:2305 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Vacuum-kostnad för sidor som smutsats ner vid städning." + +#: utils/misc/guc.c:2315 +msgid "Vacuum cost amount available before napping." +msgstr "Vacuum-kostnad kvar innan pausande." + +#: utils/misc/guc.c:2325 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Vacuum-kostnad kvar innan pausande, för autovacuum." + +#: utils/misc/guc.c:2335 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Sätter det maximala antalet filer som en serverprocess kan ha öppna pÃ¥ en gÃ¥ng." + +#: utils/misc/guc.c:2348 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Sätter det maximala antalet förberedda transaktioner man fÃ¥r ha pÃ¥ en gÃ¥ng." + +#: utils/misc/guc.c:2359 +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Sätter minsta tabell-OID för spÃ¥rning av lÃ¥s." + +#: utils/misc/guc.c:2360 +msgid "Is used to avoid output on system tables." +msgstr "Används för att undvika utdata för systemtabeller." + +#: utils/misc/guc.c:2369 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "Sätter OID för tabellen med ovillkorlig lÃ¥sspÃ¥rning." + +#: utils/misc/guc.c:2381 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Sätter den maximala tiden som en sats fÃ¥r köra." + +#: utils/misc/guc.c:2382 utils/misc/guc.c:2393 utils/misc/guc.c:2404 +msgid "A value of 0 turns off the timeout." +msgstr "Värdet 0 stänger av timeout:en." + +#: utils/misc/guc.c:2392 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Sätter den maximala tiden som man fÃ¥r vänta pÃ¥ ett lÃ¥s." + +#: utils/misc/guc.c:2403 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "Sätter den maximala tiden som en transaktion tillÃ¥s vara \"idle\"." + +#: utils/misc/guc.c:2414 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "Minimal Ã¥lder där VACUUM skall frysa en tabellrad." + +#: utils/misc/guc.c:2424 +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "Ã…lder där VACUUM skall skanna hela tabellen för att frysa tupler." + +#: utils/misc/guc.c:2434 +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "Minsta Ã¥lder där VACUUM skall frysa en MultiXactId i en tabellrad." + +#: utils/misc/guc.c:2444 +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "Multixact-Ã¥lder där VACUUM skall skanna hela tabellen för att frysa tupler." + +#: utils/misc/guc.c:2454 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "Antalet transaktioner som VACUUM och HOT-städning skall fördröjas (om nÃ¥gon)." + +#: utils/misc/guc.c:2467 +msgid "Sets the maximum number of locks per transaction." +msgstr "Sätter det maximala antalet lÃ¥s per transaktion." + +#: utils/misc/guc.c:2468 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Den delade lÃ¥stabellen har storlek efter antagandet att maximalt max_locks_per_transaction * max_connections olika objekt kommer behöva lÃ¥sas vid en tidpunkt." + +#: utils/misc/guc.c:2479 +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Sätter det maximala antalet predikatlÃ¥s per transaktion." + +#: utils/misc/guc.c:2480 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Den delade predikatlÃ¥stabellen har storlek efter antagandet att maximalt max_pred_locks_per_transaction * max_connections olika objekt kommer behöva lÃ¥sas vid en tidpunkt." + +#: utils/misc/guc.c:2491 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Sätter det maximala antalet predikatlÃ¥sta sidor och tupler per relation." + +#: utils/misc/guc.c:2492 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Om fler än detta totala antal sidor och tupler för samma relation är lÃ¥sta av en anslutning sÃ¥ ersätts dessa lÃ¥s med ett lÃ¥s pÃ¥ relationen." + +#: utils/misc/guc.c:2502 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Sätter det maximala antalet predikatlÃ¥sta tupler per sida." + +#: utils/misc/guc.c:2503 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Om fler än detta antal tupler pÃ¥ samma sida är lÃ¥sta av en anslutning sÃ¥ ersätts dessa lÃ¥s med ett lÃ¥s pÃ¥ sidan." + +#: utils/misc/guc.c:2513 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "Sätter maximalt tillÃ¥ten tid att slutföra klientautentisering." + +#: utils/misc/guc.c:2525 +msgid "Waits N seconds on connection startup before authentication." +msgstr "Väntar N sekunder efter anslutning innan autentisering." + +#: utils/misc/guc.c:2536 +msgid "Sets the number of WAL files held for standby servers." +msgstr "Sätter antal WAL-filer som sparas för standby-servrar." + +#: utils/misc/guc.c:2546 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "Sätter maximal storlek som WAL kan krympas till." + +#: utils/misc/guc.c:2558 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Sätter WAL-storlek som utlöser en checkpoint." + +#: utils/misc/guc.c:2570 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Sätter maximal tid mellan tvÃ¥ automatiska WAL-checkpoint:er." + +#: utils/misc/guc.c:2581 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "SlÃ¥r pÃ¥ varning om checkpoint-segment fylls oftare än det här." + +#: utils/misc/guc.c:2583 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Skriv ett meddelande i serverloggen om checkpoint:er som orsakas av fulla checkpoint-segmentfiler händer oftare än detta antal sekunder. Noll stänger av varningen." + +#: utils/misc/guc.c:2595 utils/misc/guc.c:2753 utils/misc/guc.c:2782 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "Antal sidor varefter tidigare skrivningar flush:as till disk." + +#: utils/misc/guc.c:2606 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "Sätter antal buffrar för disksidor i delat minne för WAL." + +#: utils/misc/guc.c:2617 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "Tid mellan WAL-flush:ar utförda i WAL-skrivaren." + +#: utils/misc/guc.c:2628 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "Mängden WAL utskrivna av WAL-skrivaren som utlöser en flush." + +#: utils/misc/guc.c:2639 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Sätter maximalt antal samtidigt körande WAL-sändarprocesser." + +#: utils/misc/guc.c:2650 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Sätter maximalt antal samtidigt definierade replikeringsslottar." + +#: utils/misc/guc.c:2660 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "Sätter maximal tid att vänta pÃ¥ WAL-replikering." + +#: utils/misc/guc.c:2671 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Sätter fördröjning i mikrosekunder mellan transaktions-commit ochj flush:ning av WAL till disk." + +#: utils/misc/guc.c:2683 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "Sätter minsta antal samtida öppna transaktioner innan vi utför en commit_delay." + +#: utils/misc/guc.c:2694 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Sätter antal siffror som visas för flyttalsvärden." + +#: utils/misc/guc.c:2695 +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "Detta pÃ¥verkar real, double precision och geometriska datatyper. Noll eller negativt parametervärde läggs till standard antal siffror (FLT_DIG eller DBL_DIG respektive). Ett värde större än noll väljer ett exakt utmatningsläge." + +#: utils/misc/guc.c:2707 +msgid "Sets the minimum execution time above which statements will be logged." +msgstr "Sätter minimal körtid där lÃ¥ngsammare satser kommer loggas." + +#: utils/misc/guc.c:2709 +msgid "Zero prints all queries, subject to log_statement_sample_rate. -1 turns this feature off." +msgstr "Noll skriver ut alla frÃ¥gor (enligt log_statement_sample_rate). -1 stänger av denna finess." + +#: utils/misc/guc.c:2720 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Sätter minimal körtid där lÃ¥ngsammare autovacuum-operationer kommer loggas." + +#: utils/misc/guc.c:2722 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Noll skriver ut alla operationer. -1 stänger av autovacuum." + +#: utils/misc/guc.c:2732 +msgid "Background writer sleep time between rounds." +msgstr "Bakgrundsskrivarens sleep-tid mellan körningar." + +#: utils/misc/guc.c:2743 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Bakgrundsskrivarens maximala antal LRU-sidor som flush:as per omgång." + +#: utils/misc/guc.c:2766 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Antal samtidiga förfrågningar som kan effektivt kan hanteras av disksystemet." + +#: utils/misc/guc.c:2767 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "För RAID-array:er så borde det vara ungerfär så många som antalet spindlar i array:en." + +#: utils/misc/guc.c:2795 +msgid "Maximum number of concurrent worker processes." +msgstr "Maximalt antal samtidiga arbetsprocesser." + +#: utils/misc/guc.c:2807 +msgid "Maximum number of logical replication worker processes." +msgstr "Maximalt antal arbetsprocesser för logisk replikering." + +#: utils/misc/guc.c:2819 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Maximalt antal tabellsynkroniseringsarbetare per prenumeration." + +#: utils/misc/guc.c:2829 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Automatisk loggfilsrotering kommer ske efter N minuter." + +#: utils/misc/guc.c:2840 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "Automatisk loggfilsrotering kommer ske efter N kilobyte." + +#: utils/misc/guc.c:2851 +msgid "Shows the maximum number of function arguments." +msgstr "Visar maximalt antal funktionsargument." + +#: utils/misc/guc.c:2862 +msgid "Shows the maximum number of index keys." +msgstr "Visar maximalt antal indexnycklar." + +#: utils/misc/guc.c:2873 +msgid "Shows the maximum identifier length." +msgstr "Visar den maximala identifierarlängden." + +#: utils/misc/guc.c:2884 +msgid "Shows the size of a disk block." +msgstr "Visar storleken på ett diskblock." + +#: utils/misc/guc.c:2895 +msgid "Shows the number of pages per disk file." +msgstr "Visar antal sidor per diskfil." + +#: utils/misc/guc.c:2906 +msgid "Shows the block size in the write ahead log." +msgstr "Visar blockstorleken i the write-ahead-loggen." + +#: utils/misc/guc.c:2917 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "Sätter väntetiden innan databasen försöker ta emot WAL efter ett misslyckat försök." + +#: utils/misc/guc.c:2929 +msgid "Shows the size of write ahead log segments." +msgstr "Visar storleken på write-ahead-log-segment." + +#: utils/misc/guc.c:2942 +msgid "Time to sleep between autovacuum runs." +msgstr "Tid att sova mellan körningar av autovacuum." + +#: utils/misc/guc.c:2952 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Minst antal tupel-uppdateringar eller raderingar innan vacuum." + +#: utils/misc/guc.c:2961 +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Minsta antal tupel-insert, -update eller -delete innan analyze." + +#: utils/misc/guc.c:2971 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "Ålder då autovacuum körs på en tabell för att förhindra wrapaound på transaktions-ID." + +#: utils/misc/guc.c:2982 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "Ålder på multixact då autovacuum körs på en tabell för att förhindra wrapaound på multixact." + +#: utils/misc/guc.c:2992 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Sätter maximalt antal samtidigt körande arbetsprocesser för autovacuum." + +#: utils/misc/guc.c:3002 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Sätter maximalt antal parallella processer per underhållsoperation." + +#: utils/misc/guc.c:3012 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Sätter maximalt antal parallella processer per exekveringsnod." + +#: utils/misc/guc.c:3023 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Sätter maximalt antal parallella arbetare som kan vara aktiva på en gång." + +#: utils/misc/guc.c:3034 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Sätter maximalt minne som kan användas av varje arbetsprocess för autovacuum." + +#: utils/misc/guc.c:3045 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "Tid innan ett snapshot är för gammalt för att läsa sidor som ändrats efter snapshot:en tagits." + +#: utils/misc/guc.c:3046 +msgid "A value of -1 disables this feature." +msgstr "Värdet -1 stänger av denna funktion." + +#: utils/misc/guc.c:3056 +msgid "Time between issuing TCP keepalives." +msgstr "Tid mellan skickande av TCP-keepalive." + +#: utils/misc/guc.c:3057 utils/misc/guc.c:3068 utils/misc/guc.c:3192 +msgid "A value of 0 uses the system default." +msgstr "Värdet 0 anger systemets standardvärde." + +#: utils/misc/guc.c:3067 +msgid "Time between TCP keepalive retransmits." +msgstr "Tid mellan omsändning av TCP-keepalive." + +#: utils/misc/guc.c:3078 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSL-förhandling stöds inte längre; denna kan bara vara 0." + +#: utils/misc/guc.c:3089 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "Maximalt antal omsändningar av TCP-keepalive." + +#: utils/misc/guc.c:3090 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Detta bestämmer antalet keepalive-omsändingar i rad som kan försvinna innan en anslutning anses vara död. Värdet 0 betyder systemstandardvärdet." + +#: utils/misc/guc.c:3101 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "Sätter maximalt tillåtna resultat för exakt sökning med GIN." + +#: utils/misc/guc.c:3112 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Sätter planerarens antagande om totala storleken på datacachen." + +#: utils/misc/guc.c:3113 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Det är totala storleken på cachen (kernelcache och delade buffertar) som användas för PostgreSQLs datafiler. Det mäts i disksidor som normalt är 8 kb styck." + +#: utils/misc/guc.c:3124 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Sätter minsta mängd tabelldata för en parallell skanning." + +#: utils/misc/guc.c:3125 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Om planeraren beräknar att den kommer läsa för få tabellsidor för att nå denna gräns så kommer den inte försöka med en parallell skanning." + +#: utils/misc/guc.c:3135 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Anger minimala mängden indexdata för en parallell scan." + +#: utils/misc/guc.c:3136 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Om planeraren beräknar att den kommer läsa för få indexsidor för att nå denna gräns så kommer den inte försöka med en parallell skanning." + +#: utils/misc/guc.c:3147 +msgid "Shows the server version as an integer." +msgstr "Visar serverns version som ett heltal." + +#: utils/misc/guc.c:3158 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Logga användning av temporära filer som är större än detta antal kilobyte." + +#: utils/misc/guc.c:3159 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "Noll loggar alla filer. Standard är -1 (stänger av denna finess)." + +#: utils/misc/guc.c:3169 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "Ställer in storleken reserverad för pg_stat_activity.query, i byte." + +#: utils/misc/guc.c:3180 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "Sätter maximal storlek på väntelistan för GIN-index." + +#: utils/misc/guc.c:3191 +msgid "TCP user timeout." +msgstr "Användartimeout för TCP." + +#: utils/misc/guc.c:3211 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Ställer in planerarens estimat av kostnaden för att hämta en disksida sekvensiellt." + +#: utils/misc/guc.c:3222 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Ställer in planerarens estimat av kostnaden för att hämta en disksida icke-sekvensiellt." + +#: utils/misc/guc.c:3233 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Ställer in planerarens estimat av kostnaden för att processa varje tupel (rad)." + +#: utils/misc/guc.c:3244 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Sätter planerarens kostnadsuppskattning för att processa varje indexpost under en indexskanning." + +#: utils/misc/guc.c:3255 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Sätter planerarens kostnadsuppskattning för att processa varje operator- eller funktions-anrop." + +#: utils/misc/guc.c:3266 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "Sätter planerarens kostnadsuppskattning för att skicka varje tupel (rad) från en arbetare till huvud-backend:en. " + +#: utils/misc/guc.c:3277 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Sätter planerarens kostnadsuppskattning för att starta upp en arbetsprocess för en parallell fråga." + +#: utils/misc/guc.c:3289 +msgid "Perform JIT compilation if query is more expensive." +msgstr "Utför JIT-kompilering om frågan är dyrare." + +#: utils/misc/guc.c:3290 +msgid "-1 disables JIT compilation." +msgstr "-1 stänger av JIT-kompilering." + +#: utils/misc/guc.c:3300 +msgid "Optimize JITed functions if query is more expensive." +msgstr "Optimera JIT-funktioner om frågan är dyrare." + +#: utils/misc/guc.c:3301 +msgid "-1 disables optimization." +msgstr "-1 stänger av optimering." + +#: utils/misc/guc.c:3311 +msgid "Perform JIT inlining if query is more expensive." +msgstr "Utför JIT-\"inlining\" om frågan är dyrare." + +#: utils/misc/guc.c:3312 +msgid "-1 disables inlining." +msgstr "-1 stänger av \"inlining\"" + +#: utils/misc/guc.c:3322 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Sätter planerarens uppskattning av hur stor del av markörens rader som kommer hämtas. " + +#: utils/misc/guc.c:3334 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: selektionstryck inom populationen." + +#: utils/misc/guc.c:3345 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: slumptalsfrö för val av slumpad sökväg." + +#: utils/misc/guc.c:3356 +msgid "Multiple of the average buffer usage to free per round." +msgstr "Multipel av genomsnittlig bufferanvändning som frias per runda." + +#: utils/misc/guc.c:3366 +msgid "Sets the seed for random-number generation." +msgstr "Sätter fröet för slumptalsgeneratorn." + +#: utils/misc/guc.c:3377 +msgid "Vacuum cost delay in milliseconds." +msgstr "Städkostfördröjning i millisekunder." + +#: utils/misc/guc.c:3388 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Städkostfördröjning i millisekunder, för autovacuum." + +#: utils/misc/guc.c:3399 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Antalet tupeluppdateringar eller borttagningar innan vacuum relativt reltuples." + +#: utils/misc/guc.c:3408 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Antalet tupelinsättningar, uppdateringar eller borttagningar innan analyze relativt reltuples." + +#: utils/misc/guc.c:3418 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "Tid lagd på att flusha nedsmutsade buffrar vid checkpoint relativt checkpoint-intervallet." + +#: utils/misc/guc.c:3428 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Antal tupelinsättningar innan indexuppstädning relativt reltuples." + +#: utils/misc/guc.c:3438 +msgid "Fraction of statements exceeding log_min_duration_statement to be logged." +msgstr "Bråkdel av satser överskrider log_min_duration_statement som skall loggas." + +#: utils/misc/guc.c:3439 +msgid "If you only want a sample, use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "Om du bara vill ha ett urval, använd ett värde mellan 0.0 (logga aldrig) och 1.0 (logga alltid)." + +#: utils/misc/guc.c:3449 +msgid "Set the fraction of transactions to log for new transactions." +msgstr "Ställer in bråkdel av transaktioner som skall loggas av nya transaktioner." + +#: utils/misc/guc.c:3450 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." +msgstr "Loggar all satser från en bråkdel av transaktionerna. Använd ett värde mellan 0.0 (logga aldrig) till 1.0 (logga all satser i alla transaktioner)." + +#: utils/misc/guc.c:3470 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "Sätter shell-kommandot som kommer anropas för att arkivera en WAL-fil." + +#: utils/misc/guc.c:3480 +msgid "Sets the shell command that will retrieve an archived WAL file." +msgstr "Sätter shell-kommandot som kommer få en arkiverad WAL-fil." + +#: utils/misc/guc.c:3490 +msgid "Sets the shell command that will be executed at every restart point." +msgstr "Sätter shell-kommandot som kommer anropas vid varje omstartspunkt." + +#: utils/misc/guc.c:3500 +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "Sätter shell-kommandot som kommer anropas en gång i slutet av en återställning." + +#: utils/misc/guc.c:3510 +msgid "Specifies the timeline to recovery into." +msgstr "Anger tidslinjen att återställa till." + +#: utils/misc/guc.c:3520 +msgid "Set to 'immediate' to end recovery as soon as a consistent state is reached." +msgstr "Sätt till 'immediate' för att avsluta återställning så snart ett konsistent tillstånd uppnås." + +#: utils/misc/guc.c:3529 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "Sätter transaktions-ID som återställning kommer gå till." + +#: utils/misc/guc.c:3538 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "Sätter tidsstämpel som återställning kommer gå till." + +#: utils/misc/guc.c:3547 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "Sätter namngiven återställningspunkt som återställning kommer gå till." + +#: utils/misc/guc.c:3556 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "Sätter LSN för write-ahead-logg-position som återställning kommer få till." + +#: utils/misc/guc.c:3566 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "Anger ett filnamn vars närvaro gör att återställning avslutas i en standby." + +#: utils/misc/guc.c:3576 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "Sätter anslutningssträng som anvönds för att ansluta till skickande server." + +#: utils/misc/guc.c:3587 +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "Sätter namnet på replikeringsslotten som skall användas av den skickande servern." + +#: utils/misc/guc.c:3597 +msgid "Sets the client's character set encoding." +msgstr "Ställer in klientens teckenkodning." + +#: utils/misc/guc.c:3608 +msgid "Controls information prefixed to each log line." +msgstr "Styr information prefixat till varje loggrad." + +#: utils/misc/guc.c:3609 +msgid "If blank, no prefix is used." +msgstr "Om tom så används inget prefix." + +#: utils/misc/guc.c:3618 +msgid "Sets the time zone to use in log messages." +msgstr "Sätter tidszonen som används i loggmeddelanden." + +#: utils/misc/guc.c:3628 +msgid "Sets the display format for date and time values." +msgstr "Sätter displayformat för datum och tidvärden." + +#: utils/misc/guc.c:3629 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Styr också tolkning av tvetydig datumindata." + +#: utils/misc/guc.c:3640 +msgid "Sets the default table access method for new tables." +msgstr "Ställer in standard tabellaccessmetod för nya tabeller." + +#: utils/misc/guc.c:3651 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "Ställer in standard tabellutrymme där tabeller och index skapas." + +#: utils/misc/guc.c:3652 +msgid "An empty string selects the database's default tablespace." +msgstr "En tom sträng väljer databasens standardtabellutrymme." + +#: utils/misc/guc.c:3662 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Ställer in tablespace för temporära tabeller och sorteringsfiler." + +#: utils/misc/guc.c:3673 +msgid "Sets the path for dynamically loadable modules." +msgstr "Sätter sökvägen till dynamiskt laddade moduler." + +#: utils/misc/guc.c:3674 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Om en dynamiskt laddad modul behöver öppnas och det angivna namnet inte har en katalogkomponent (dvs, namnet inte innehåller snedstreck) så kommer systemet använda denna sökväg för filen." + +#: utils/misc/guc.c:3687 +msgid "Sets the location of the Kerberos server key file." +msgstr "Ställer in platsen för Kerberos servernyckelfil." + +#: utils/misc/guc.c:3698 +msgid "Sets the Bonjour service name." +msgstr "Sätter Bonjour-tjänstens namn." + +#: utils/misc/guc.c:3710 +msgid "Shows the collation order locale." +msgstr "Visar lokal för jämförelseordning." + +#: utils/misc/guc.c:3721 +msgid "Shows the character classification and case conversion locale." +msgstr "Visar lokal för teckenklassificering samt skiftlägeskonvertering." + +#: utils/misc/guc.c:3732 +msgid "Sets the language in which messages are displayed." +msgstr "Sätter språket som meddelanden visas i." + +#: utils/misc/guc.c:3742 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Sätter lokalen för att formattera monetära belopp." + +#: utils/misc/guc.c:3752 +msgid "Sets the locale for formatting numbers." +msgstr "Ställer in lokalen för att formattera nummer." + +#: utils/misc/guc.c:3762 +msgid "Sets the locale for formatting date and time values." +msgstr "Sätter lokalen för att formattera datum och tider." + +#: utils/misc/guc.c:3772 +msgid "Lists shared libraries to preload into each backend." +msgstr "Listar delade bibliotek som skall förladdas i varje backend." + +#: utils/misc/guc.c:3783 +msgid "Lists shared libraries to preload into server." +msgstr "Listar delade bibliotek som skall förladdas i servern." + +#: utils/misc/guc.c:3794 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Listar ej priviligerade delade bibliotek som förladdas in i varje backend." + +#: utils/misc/guc.c:3805 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Sätter schemats sökordning för namn som inte är schema-prefixade." + +#: utils/misc/guc.c:3817 +msgid "Sets the server (database) character set encoding." +msgstr "Ställer in serverns (databasens) teckenkodning." + +#: utils/misc/guc.c:3829 +msgid "Shows the server version." +msgstr "Visar serverversionen" + +#: utils/misc/guc.c:3841 +msgid "Sets the current role." +msgstr "Ställer in den aktiva rollen." + +#: utils/misc/guc.c:3853 +msgid "Sets the session user name." +msgstr "Sätter sessionens användarnamn." + +#: utils/misc/guc.c:3864 +msgid "Sets the destination for server log output." +msgstr "Sätter serverloggens destination." + +#: utils/misc/guc.c:3865 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Giltiga värden är kombinationer av \"stderr\", \"syslog\", \"csvlog\" och \"eventlog\", beroende på plattform." + +#: utils/misc/guc.c:3876 +msgid "Sets the destination directory for log files." +msgstr "Sätter destinationskatalogen för loggfiler." + +#: utils/misc/guc.c:3877 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Kan anges relativt datakatalogen eller som en absolut sökväg." + +#: utils/misc/guc.c:3887 +msgid "Sets the file name pattern for log files." +msgstr "Sätter filnamnsmallen för loggfiler." + +#: utils/misc/guc.c:3898 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Sätter programnamnet som används för att identifiera PostgreSQLs meddelanden i syslog." + +#: utils/misc/guc.c:3909 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Sätter applikationsnamnet som används för att identifiera PostgreSQLs meddelanden i händelseloggen." + +#: utils/misc/guc.c:3920 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Ställer in tidszon för visande och tolkande av tidsstämplar." + +#: utils/misc/guc.c:3930 +msgid "Selects a file of time zone abbreviations." +msgstr "Väljer en fil för tidszonsförkortningar." + +#: utils/misc/guc.c:3940 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Sätter ägande grupp för Unix-domainuttaget (socket)." + +#: utils/misc/guc.c:3941 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Ägaren av uttaget (socker) är alltid användaren som startar servern." + +#: utils/misc/guc.c:3951 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Ställer in kataloger där Unix-domän-uttag (socket) kommer skapas." + +#: utils/misc/guc.c:3966 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Sätter värdnamn eller IP-adress(er) att lyssna på." + +#: utils/misc/guc.c:3981 +msgid "Sets the server's data directory." +msgstr "Ställer in serverns datakatalog." + +#: utils/misc/guc.c:3992 +msgid "Sets the server's main configuration file." +msgstr "Sätter serverns huvudkonfigurationsfil." + +#: utils/misc/guc.c:4003 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Sätter serverns \"hba\"-konfigurationsfil." + +#: utils/misc/guc.c:4014 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Sätter serverns \"ident\"-konfigurationsfil." + +#: utils/misc/guc.c:4025 +msgid "Writes the postmaster PID to the specified file." +msgstr "Skriver postmaster-PID till angiven fil." + +#: utils/misc/guc.c:4036 +msgid "Name of the SSL library." +msgstr "Namn på SSL-biblioteket." + +#: utils/misc/guc.c:4051 +msgid "Location of the SSL server certificate file." +msgstr "Plats för serverns SSL-certifikatfil." + +#: utils/misc/guc.c:4061 +msgid "Location of the SSL server private key file." +msgstr "Plats för serverns privata SSL-nyckelfil." + +#: utils/misc/guc.c:4071 +msgid "Location of the SSL certificate authority file." +msgstr "Plats för SSL-certifikats auktoritetsfil." + +#: utils/misc/guc.c:4081 +msgid "Location of the SSL certificate revocation list file." +msgstr "Plats för SSL-certifikats återkallningsfil." + +#: utils/misc/guc.c:4091 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Skriver temporära statistikfiler till angiven katalog." + +#: utils/misc/guc.c:4102 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Antalet synkrona standby och en lista med namn på potentiellt synkrona sådana." + +#: utils/misc/guc.c:4113 +msgid "Sets default text search configuration." +msgstr "Ställer in standard textsökkonfiguration." + +#: utils/misc/guc.c:4123 +msgid "Sets the list of allowed SSL ciphers." +msgstr "Ställer in listan med tillåtna SSL-krypton." + +#: utils/misc/guc.c:4138 +msgid "Sets the curve to use for ECDH." +msgstr "Ställer in kurvan att använda för ECDH." + +#: utils/misc/guc.c:4153 +msgid "Location of the SSL DH parameters file." +msgstr "Plats för SSL DH-parameterfil." + +#: utils/misc/guc.c:4164 +msgid "Command to obtain passphrases for SSL." +msgstr "Kommando för att hämta lösenfraser för SSL." + +#: utils/misc/guc.c:4174 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "Sätter applikationsnamn som rapporteras i statistik och loggar." + +#: utils/misc/guc.c:4185 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Sätter namnet på klustret som inkluderas i processtiteln." + +#: utils/misc/guc.c:4196 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "Sätter WAL-resurshanterare som WAL-konsistenskontoller görs med." + +#: utils/misc/guc.c:4197 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "Hela sidkopior kommer loggas för alla datablock och kontrolleras mot resultatet av en WAL-uppspelning." + +#: utils/misc/guc.c:4207 +msgid "JIT provider to use." +msgstr "JIT-leverantör som används." + +#: utils/misc/guc.c:4227 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Ställer in hurvida \"\\'\" tillåts i sträng-literaler." + +#: utils/misc/guc.c:4237 +msgid "Sets the output format for bytea." +msgstr "Ställer in output-format för bytea." + +#: utils/misc/guc.c:4247 +msgid "Sets the message levels that are sent to the client." +msgstr "Ställer in meddelandenivåer som skickas till klienten." + +#: utils/misc/guc.c:4248 utils/misc/guc.c:4313 utils/misc/guc.c:4324 +#: utils/misc/guc.c:4400 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Varje nivå inkluderar de efterföljande nivåerna. Ju senare nivå destå färre meddlanden skickas." + +#: utils/misc/guc.c:4258 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Slår på planerarens användning av integritetsvillkor för att optimera frågor." + +#: utils/misc/guc.c:4259 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Tabellskanningar kommer hoppas över om dess integritetsvillkor garanterar att inga rader komma matchas av frågan." + +#: utils/misc/guc.c:4270 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Ställer in isolationsnivån för nya transaktioner." + +#: utils/misc/guc.c:4280 +msgid "Sets the current transaction's isolation level." +msgstr "Sätter den aktuella transaktionsisolationsnivån." + +#: utils/misc/guc.c:4291 +msgid "Sets the display format for interval values." +msgstr "Ställer in visningsformat för intervallvärden." + +#: utils/misc/guc.c:4302 +msgid "Sets the verbosity of logged messages." +msgstr "Ställer in pratighet för loggade meddelanden." + +#: utils/misc/guc.c:4312 +msgid "Sets the message levels that are logged." +msgstr "Ställer in meddelandenivåer som loggas." + +#: utils/misc/guc.c:4323 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Gör att alla satser som genererar fel vid eller över denna nivå kommer loggas." + +#: utils/misc/guc.c:4334 +msgid "Sets the type of statements logged." +msgstr "Ställer in vilken sorts satser som loggas." + +#: utils/misc/guc.c:4344 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Ställer in syslog-\"facility\" som används när syslog är påslagen." + +#: utils/misc/guc.c:4359 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Sätter sessionens beteende för utlösare och omskrivningsregler." + +#: utils/misc/guc.c:4369 +msgid "Sets the current transaction's synchronization level." +msgstr "Ställer in den nuvarande transaktionens synkroniseringsnivå." + +#: utils/misc/guc.c:4379 +msgid "Allows archiving of WAL files using archive_command." +msgstr "Tillåter arkivering av WAL-filer med hjälp av archive_command." + +#: utils/misc/guc.c:4389 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "Sätter handling som skall utföras när återställningsmål nås." + +#: utils/misc/guc.c:4399 +msgid "Enables logging of recovery-related debugging information." +msgstr "Slår på loggning av återställningsrelaterad debug-information." + +#: utils/misc/guc.c:4415 +msgid "Collects function-level statistics on database activity." +msgstr "Samlar in statistik på funktionsnivå över databasaktivitet." + +#: utils/misc/guc.c:4425 +msgid "Set the level of information written to the WAL." +msgstr "Ställer in mängden information som skrivs till WAL." + +#: utils/misc/guc.c:4435 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Väljer implementation som används för dynamiskt delat minne." + +#: utils/misc/guc.c:4445 +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "Väljer implementation för delat minne som används för det delade minnets huvudregionen." + +#: utils/misc/guc.c:4455 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "Väljer metod för att tvinga WAL-uppdateringar till disk." + +#: utils/misc/guc.c:4465 +msgid "Sets how binary values are to be encoded in XML." +msgstr "Ställer in hur binära värden kodas i XML." + +#: utils/misc/guc.c:4475 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Sätter hurvida XML-data vid implicit parsning och serialiseringsoperationer ses som dokument eller innehållsfragment." + +#: utils/misc/guc.c:4486 +msgid "Use of huge pages on Linux or Windows." +msgstr "Använd stora sidor på Linux resp. Windows." + +#: utils/misc/guc.c:4496 +msgid "Forces use of parallel query facilities." +msgstr "Tvingar användning av parallella frågefinesser." + +#: utils/misc/guc.c:4497 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Om det är möjligt så kör fråga med en parallell arbetare och med parallella begränsningar." + +#: utils/misc/guc.c:4507 +msgid "Encrypt passwords." +msgstr "Kryptera lösenord." + +#: utils/misc/guc.c:4508 +msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +msgstr "När ett lösenord anges i CREATE USER eller ALTER USER utan man skrivit varken ENCRYPTED eller UNENCRYPTED så bestämmer denna parameter om lösenordet kommer krypteras." + +#: utils/misc/guc.c:4519 +msgid "Controls the planner's selection of custom or generic plan." +msgstr "Styr planerarens användning av egendefinierad eller generell plan." + +#: utils/misc/guc.c:4520 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "Preparerade satser kan ha egendefinierade och generella planer och planeraren kommer försöka välja den som är bäst. Detta kan anges att övertrumfa standardbeteendet." + +#: utils/misc/guc.c:4532 +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "Sätter minsta SSL/TLS-protokollversion som skall användas." + +#: utils/misc/guc.c:4544 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "Sätter högsta SSL/TLS-protokollversion som skall användas." + +#: utils/misc/guc.c:5367 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: kunde inte komma åt katalogen \"%s\": %s\n" + +#: utils/misc/guc.c:5372 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Kör initdb eller pg_basebackup för att initiera en PostgreSQL-datakatalog.\n" + +#: utils/misc/guc.c:5392 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var servens konfigurationsfil är.\n" +"Du måste ange flaggan --config-file eller -D alternativt sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5411 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: har inte åtkomst till serverns konfigureringsfil \"%s\": %s\n" + +#: utils/misc/guc.c:5437 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var databasens systemdata är.\n" +"Det kan anges med \"data_directory\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5485 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var \"hba\"-konfigurationsfilen är.\n" +"Detta kan anges som \"hba_file\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:5508 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s vet inte var \"ident\"-konfigurationsfilen är.\n" +"Detta kan anges som \"ident_file\" i \"%s\" eller med flaggan -D alternativt genom att sätta omgivningsvariabeln PGDATA.\n" + +#: utils/misc/guc.c:6350 +msgid "Value exceeds integer range." +msgstr "Värde överskriver heltalsintervall." + +#: utils/misc/guc.c:6586 +#, c-format +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d%s%s är utanför giltigt intervall för parameter \"%s\" (%d .. %d)" + +#: utils/misc/guc.c:6622 +#, c-format +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "%g%s%s är utanför giltigt intervall för parameter \"%s\" (%g .. %g)" + +#: utils/misc/guc.c:6778 utils/misc/guc.c:8148 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "kan inte sätta parametrar under en parallell operation" + +#: utils/misc/guc.c:6785 utils/misc/guc.c:7537 utils/misc/guc.c:7590 +#: utils/misc/guc.c:7641 utils/misc/guc.c:7977 utils/misc/guc.c:8744 +#: utils/misc/guc.c:9010 utils/misc/guc.c:10648 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "okänd konfigurationsparameter \"%s\"" + +#: utils/misc/guc.c:6800 utils/misc/guc.c:7989 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "parameter \"%s\" kan inte ändras" + +#: utils/misc/guc.c:6833 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "parameter \"%s\" kan inte ändras nu" + +#: utils/misc/guc.c:6851 utils/misc/guc.c:6898 utils/misc/guc.c:10664 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "rättighet saknas för att sätta parameter \"%s\"" + +#: utils/misc/guc.c:6888 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "parameter \"%s\" kan inte ändras efter uppkopplingen startats" + +#: utils/misc/guc.c:6936 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "kan inte sätta parameter \"%s\" inom en security-definer-funktion" + +#: utils/misc/guc.c:7545 utils/misc/guc.c:7595 utils/misc/guc.c:9017 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "måste vara superanvändare eller medlem i pg_read_all_settings för att undersöka \"%s\"" + +#: utils/misc/guc.c:7686 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s tar bara ett argument" + +#: utils/misc/guc.c:7937 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "måste vara superanvändare för att köra kommandot ALTER SYSTEM" + +#: utils/misc/guc.c:8022 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "parametervärde till ALTER SYSTEM kan inte innehålla nyradstecken" + +#: utils/misc/guc.c:8067 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "kunde inte parsa innehållet i fil \"%s\"" + +#: utils/misc/guc.c:8224 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT är inte implementerat ännu" + +#: utils/misc/guc.c:8308 +#, c-format +msgid "SET requires parameter name" +msgstr "SET kräver ett parameternamn" + +#: utils/misc/guc.c:8441 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "försök att omdefiniera parameter \"%s\"" + +#: utils/misc/guc.c:10281 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "parameter \"%s\" kunde inte sättas" + +#: utils/misc/guc.c:10368 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "kunde inte tolka inställningen för parameter \"%s\"" + +#: utils/misc/guc.c:10726 utils/misc/guc.c:10760 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "ogiltigt värde för parameter \"%s\": %d" + +#: utils/misc/guc.c:10794 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "ogiltigt värde för parameter \"%s\": %g" + +#: utils/misc/guc.c:11064 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "\"temp_buffers\" kan inte ändras efter att man använt temporära tabeller i sessionen." + +#: utils/misc/guc.c:11076 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour stöds inte av detta bygge" + +#: utils/misc/guc.c:11089 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL stöds inte av detta bygge" + +#: utils/misc/guc.c:11101 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "Kan inte slå på parameter när \"log_statement_stats\" är satt." + +#: utils/misc/guc.c:11113 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "Kan inte slå på \"log_statement_stats\" när \"log_parser_stats\", \"log_planner_stats\" eller \"log_executor_stats\" är satta." + +#: utils/misc/guc.c:11357 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "effective_io_concurrency måste sättas till 0 på plattformar som saknar posix_fadvise()." + +#: utils/misc/guc.c:11471 +#, c-format +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline är inte ett giltigt nummer." + +#: utils/misc/guc.c:11511 +#, c-format +msgid "multiple recovery targets specified" +msgstr "multipla återställningsmål angivna" + +#: utils/misc/guc.c:11512 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." +msgstr "Som mest en av recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time och recovery_target_xid kan sättas." + +#: utils/misc/guc.c:11520 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "Det enda tillåtna värdet är \"immediate\"." + +#: utils/misc/help_config.c:130 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "internt fel: okänd parametertyp\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "fråge-angiven typ för retur-tupel och funktions returtyp är inte kompatibla" + +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:242 utils/misc/pg_controldata.c:309 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "beräknad CRC-checksumma matchar inte värdet som är lagrat i fil" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: användare: %d.%02d s, system: %d.%02d s, förflutit: %d.%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "frågan påverkas av radsäkerhetspolicyn för tabell \"%s\"" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "För att slå av policyn för tabellens ägare, använd ALTER TABLE NO FORCE ROW LEVEL SECURITY." + +#: utils/misc/timeout.c:388 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "kan inte lägga till fler timeoutskäl" + +#: utils/misc/tzparser.c:61 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "tidszonförkortningen \"%s\" är för lång (max %d tecken) i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:73 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "tidszonoffset %d är otanför giltigt intervall i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:112 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "tidszonförkortning saknas i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:121 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "tidszonoffset saknas i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:133 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "felaktigt nummer för tidszonsoffset i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:169 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "felaktig syntax i tidszonfilen \"%s\", rad %d" + +#: utils/misc/tzparser.c:237 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "tidszonförkortningen \"%s\" är definierad flera gånger" + +#: utils/misc/tzparser.c:239 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "Post i tidszonfilen \"%s\", rad %d, står i konflikt med post i filen \"%s\", rad %d." + +#: utils/misc/tzparser.c:301 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "ogiltigt tidszonfilnamn: \"%s\"" + +#: utils/misc/tzparser.c:314 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "tidszonfilens rekursiva maxtak överskridet i filen \"%s\"" + +#: utils/misc/tzparser.c:353 utils/misc/tzparser.c:366 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "kunde inte läsa tidszonfil \"%s\": %m" + +#: utils/misc/tzparser.c:376 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "raden är för lång i tidszonfil \"%s\", rad %d" + +#: utils/misc/tzparser.c:399 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "@INCLUDE utan filnamn i tidszonfil \"%s\", rad %d" + +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Misslyckades vid skapande av minneskontext \"%s\"." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "kunde inte ansluta till dynamisk delad area" + +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "Misslyckades med förfrågan av storlek %zu i minneskontext \"%s\"." + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "markör \"%s\" finns redan" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "stänger existerande markör \"%s\"" + +#: utils/mmgr/portalmem.c:398 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "portal \"%s\" kan inte köras" + +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "kan inte ta bort fastsatt portal \"%s\"" + +#: utils/mmgr/portalmem.c:484 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "kan inte ta bort aktiv portal \"%s\"" + +#: utils/mmgr/portalmem.c:729 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "kan inte göra PREPARE på en transaktion som skapat en markör med WITH HOLD" + +#: utils/mmgr/portalmem.c:1269 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "kan inte utföra transaktionskommandon i en markörloop som inte är read-only" + +#: utils/sort/logtape.c:276 +#, c-format +msgid "could not read block %ld of temporary file: %m" +msgstr "kunde inte läsa block %ld av temporärfil: %m" + +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "kunde inte skriva till temporär fil: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "kunde inte läsa från delad temporär lagringsfil för tupler" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "oväntad chunk i delad temporär lagringsfil för tupler" + +#: utils/sort/tuplesort.c:2967 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "kan inte ha mer än %d körningar för en extern sortering" + +#: utils/sort/tuplesort.c:4051 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "kunde inte skapa unikt index \"%s\"" + +#: utils/sort/tuplesort.c:4053 +#, c-format +msgid "Key %s is duplicated." +msgstr "Nyckeln %s är duplicerad." + +#: utils/sort/tuplesort.c:4054 +#, c-format +msgid "Duplicate keys exist." +msgstr "Duplicerade nycklar existerar." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file: %m" +msgstr "kunde inte söka i temporär lagringsfil för tupler: %m" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 +#: utils/sort/tuplestore.c:1556 +#, c-format +msgid "could not read from tuplestore temporary file: %m" +msgstr "kunde inte läsa från temporär lagringsfil för tupler: %m" + +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 +#: utils/sort/tuplestore.c:1529 +#, c-format +msgid "could not write to tuplestore temporary file: %m" +msgstr "kunde inte skriva till temporär lagringsfil för tupler: %m" + +#: utils/time/snapmgr.c:624 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Källtransaktionen kör inte längre." + +#: utils/time/snapmgr.c:1202 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "kan inte exportera ett snapshot från en subtransaktion" + +#: utils/time/snapmgr.c:1361 utils/time/snapmgr.c:1366 +#: utils/time/snapmgr.c:1371 utils/time/snapmgr.c:1386 +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1411 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1523 +#: utils/time/snapmgr.c:1539 utils/time/snapmgr.c:1564 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "ogiltig snapshot-data i fil \"%s\"" + +#: utils/time/snapmgr.c:1458 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT måste anropas innan någon fråga" + +#: utils/time/snapmgr.c:1467 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "en snapshot-importerande transaktion måste ha isoleringsnivå SERIALIZABLE eller REPEATABLE READ" + +#: utils/time/snapmgr.c:1476 utils/time/snapmgr.c:1485 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "ogiltig snapshot-identifierare: \"%s\"" + +#: utils/time/snapmgr.c:1577 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "en serialiserbar transaktion kan inte importera ett snapshot från en icke-serialiserbar transaktion" + +#: utils/time/snapmgr.c:1581 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "en serialiserbar transaktion som inte är read-only kan inte importera en snapshot från en read-only-transaktion." + +#: utils/time/snapmgr.c:1596 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "kan inte importera en snapshot från en annan databas" + +#~ msgid "invalid zero-length item array in MVDependencies" +#~ msgstr "ogiltig array med storlek noll i MVDependencies" + +#~ msgid "invalid ndistinct magic %08x (expected %08x)" +#~ msgstr "ogiltig magiskt värde %08x för ndistinct (förväntade %08x)" + +#~ msgid "invalid ndistinct type %d (expected %d)" +#~ msgstr "ogiltig typ %d för ndistinct (förväntade %d)" + +#~ msgid "invalid zero-length item array in MVNDistinct" +#~ msgstr "ogiltig array med storlek noll i MVNDistinct" + +#~ msgid "invalid MVNDistinct size %zd (expected at least %zd)" +#~ msgstr "ogiltig MVNDistinct-storlek %zd (förväntade minst %zd)" + +#~ msgid "corrupted line pointer: offset = %u, length = %u" +#~ msgstr "korrupt radpekare: offset = %u, längd = %u" + +#~ msgid "%.0f tuples and %.0f item identifiers are left as dead.\n" +#~ msgstr "%.0f tupler och %.0f post-identifierare lämnades som döda.\n" + +#~ msgid "default_table_access_method is too long (maximum %d characters)." +#~ msgstr "default_table_access_method är för lång (maximalt %d tecken)" + +#~ msgid "index %s does not belong to table %s" +#~ msgstr "index %s tillhör inte tabell %s" + +#~ msgid "attribute %s does not exists" +#~ msgstr "attributet %s existerar inte" + +#~ msgid "attribute %s is not of type oid" +#~ msgstr "attribut %s är inte av typen oid" + +#~ msgid "server does not exist, skipping" +#~ msgstr "servern finns inte, hoppar över" + +#~ msgid "cannot specify default tablespace for partitioned relation" +#~ msgstr "kan inte ange standard tabellutrymme för partitionerad relation" + +#~ msgid "concurrent reindex is not supported for catalog relations" +#~ msgstr "omindexering utan lås stöds inte för katalogrelationer" + +#~ msgid "invalid ON DELETE action for foreign key constraint containing generated column" +#~ msgstr "ogiltig ON DELETE-aktion för främmande nyckelvillkor som innehåller genererad kolumn" + +#~ msgid "foreign keys constraints are not supported on foreign tables" +#~ msgstr "främmande nyckel-villkor stöds inte för främmande tabeller" + +#~ msgid "bad jsonpath representation" +#~ msgstr "felaktig jsonpath-representation" + +#~ msgid "expression should return a singleton boolean" +#~ msgstr "uttrycket skall returnera en singelton-boolean" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa fil \"%s\": %s\n" + +#~ msgid "could not read file \"%s\": read %d of %d" +#~ msgstr "kunde inte läsa fil \"%s\": läste %d av %d" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "%s: kunde inte läsa fil \"%s\": läste %d av %d\n" + +#~ msgid "" +#~ "WARNING: possible byte ordering mismatch\n" +#~ "The byte ordering used to store the pg_control file might not match the one\n" +#~ "used by this program. In that case the results below would be incorrect, and\n" +#~ "the PostgreSQL installation would be incompatible with this data directory.\n" +#~ msgstr "" +#~ "VARNING: möjligt fel i talordning\n" +#~ "Den endian-ordning med vilken pg_control lagrar filer passar kanske\n" +#~ "inte detta program. I så fall kan nedanstående utfall vara oriktigt\n" +#~ "och det installerade PostgreSQL vara oförenligt med databaskatalogen.\n" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "kunde inte identifiera aktuell katalog: %s" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" + +#~ msgid "pclose failed: %s" +#~ msgstr "pclose misslyckades: %s" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: kunde ta status på filen \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\": %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: kunde inte utföra fsync på filen \"%s\": %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: kunde inte döpa om fil \"%s\" till \"%s\": %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "kunde inte stänga katalog \"%s\": %s\n" + +#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +#~ msgstr "%s: VARNING: \"Restricted Token\" stöds inte av plattformen.\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: kunde inte öppna process-token: felkod %lu\n" + +#~ msgid "%s: could not allocate SIDs: error code %lu\n" +#~ msgstr "%s: kunde inte tilldela SID: felkod %lu\n" + +#~ msgid "%s: could not create restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte skapa begränsat token: felkod %lu\n" + +#~ msgid "%s: could not start process for command \"%s\": error code %lu\n" +#~ msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" + +#~ msgid "%s: could not re-execute with restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte köra igen med begränsat token: felkod %lu\n" + +#~ msgid "%s: could not get exit code from subprocess: error code %lu\n" +#~ msgstr "%s: kunde inte hämta statuskod för underprocess: felkod %lu\n" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "kunde inte ta status på fil eller katalog \"%s\": %s\n" + +#~ msgid "could not remove file or directory \"%s\": %s\n" +#~ msgstr "kunde inte ta bort fil eller katalog \"%s\": %s\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "barnprocess terminerades av signal %s" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "barnprocess terminerades av signal %d" + +#~ msgid "unrecognized error %d" +#~ msgstr "okänt fel: %d" + +#~ msgid "could not open two-phase state file \"%s\": %m" +#~ msgstr "kunde inte öppna tvåfas-statusfil \"%s\": %m" + +#~ msgid "could not stat two-phase state file \"%s\": %m" +#~ msgstr "kunde inte göra stat() på tvåfas-statusfil \"%s\": %m" + +#~ msgid "could not read two-phase state file \"%s\": %m" +#~ msgstr "kunde inte läsa tvåfas-statusfil \"%s\": %m" + +#~ msgid "could not remove two-phase state file \"%s\": %m" +#~ msgstr "kunde inte ta bort tvåfas-statusfil \"%s\": %m" + +#~ msgid "could not recreate two-phase state file \"%s\": %m" +#~ msgstr "kunde inte återskapa tvåfas-statusfil \"%s\": %m" + +#~ msgid "could not write two-phase state file: %m" +#~ msgstr "kunde inte skriva tvåfas-statusfil: %m" + +#~ msgid "could not fsync two-phase state file: %m" +#~ msgstr "kunde inte fsync:a tvåfas-statusfil %m" + +#~ msgid "could not close two-phase state file: %m" +#~ msgstr "kunde inte stänga tvåfas-statusfil: %m" + +#~ msgid "cannot PREPARE a transaction that has operated on temporary tables" +#~ msgstr "kan inte göra PREPARE på en transaktion som har arbetat med temporära tabeller" + +#~ msgid "could not seek in log file %s to offset %u: %m" +#~ msgstr "kunde inte söka i loggfil %s till offset %u: %m" + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "otillräckligt med data i fil \"%s\"" + +#~ msgid "could not open write-ahead log file \"%s\": %m" +#~ msgstr "kunde inte öppna write-ahead-logg-fil \"%s\": %m" + +#~ msgid "could not close log file %s: %m" +#~ msgstr "kunde inte stänga loggfil %s: %m" + +#~ msgid "could not rename old write-ahead log file \"%s\": %m" +#~ msgstr "kunde inte döpa om gammal write-ahead-loggfil \"%s\": %m" + +#~ msgid "could not create control file \"%s\": %m" +#~ msgstr "kunde inte skapa kontrollfil \"%s\": %m" + +#~ msgid "could not write to control file: %m" +#~ msgstr "kunde inte skriva till kontrollfil: %m" + +#~ msgid "could not fsync control file: %m" +#~ msgstr "kunde inte fsync:a kontrollfil: %m" + +#~ msgid "could not close control file: %m" +#~ msgstr "kunde inte stänga kontrollfil: %m" + +#~ msgid "could not open control file \"%s\": %m" +#~ msgstr "kunde inte öppna kontrollfil \"%s\": %m" + +#~ msgid "could not read from control file: %m" +#~ msgstr "kunde inte läsa från kontrollfil: %m" + +#~ msgid "could not read from control file: read %d bytes, expected %d" +#~ msgstr "kunde inte läsa från kontrollfil: läste %d byte, förväntade %d" + +#~ msgid "could not open recovery command file \"%s\": %m" +#~ msgstr "kunde inte öppna återställningskommandofil \"%s\": %m" + +#~ msgid "invalid value for recovery parameter \"%s\": \"%s\"" +#~ msgstr "ogiltigt värde för återställningsparameter \"%s\": \"%s\"" + +#~ msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." +#~ msgstr "Giltiga värden är \"pause\", \"promote\" och \"shutdown\"." + +#~ msgid "recovery_target_xid is not a valid number: \"%s\"" +#~ msgstr "recovery_target_xid är inte ett giltigt nummer: \"%s\"" + +#~ msgid "recovery_target_time is not a valid timestamp: \"%s\"" +#~ msgstr "recovery_target_time är inte en giltigt tidstämpel: \"%s\"" + +#~ msgid "parameter \"%s\" requires a temporal value" +#~ msgstr "parameter \"%s\" kräver ett temporärt värde" + +#~ msgid "unrecognized recovery parameter \"%s\"" +#~ msgstr "okänd återställningsparameter \"%s\"" + +#~ msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." +#~ msgstr "Om du inte hålller på att återställa från en backup, försök med att ta bort filen \"%s/backup_label\"." + +#~ msgid "could not fsync log segment %s: %m" +#~ msgstr "kunde inte fsync:a loggsegment %s: %m" + +#~ msgid "could not fsync log file %s: %m" +#~ msgstr "kunde inte fsync:a loggfil %s: %m" + +#~ msgid "could not fdatasync log file %s: %m" +#~ msgstr "kunde inte fdatasync:a loggfil %s: %m" + +#~ msgid "pg_walfile_name_offset() cannot be executed during recovery." +#~ msgstr "pg_walfile_name_offset() kan inte köras under återställnng." + +#~ msgid "pg_walfile_name() cannot be executed during recovery." +#~ msgstr "pg_walfile_name() kan inte köras under återställning." + +#~ msgid "shared tables cannot be toasted after initdb" +#~ msgstr "delade tabeller kan inte toast:as efter initdb" + +#~ msgid "table \"%s\" does not have OIDs" +#~ msgstr "tabell \"%s\" har inte OID:er" + +#~ msgid "missing data for OID column" +#~ msgstr "saknar data för OID-kolumn" + +#~ msgid "null OID in COPY data" +#~ msgstr "null OID i COPY-data" + +#~ msgid "invalid OID in COPY data" +#~ msgstr "ogiltig OID i COPY-data" + +#~ msgid "\"%s\" is not a table or a view" +#~ msgstr "\"%s\" är inte en tabell eller vy" + +#~ msgid "cannot create table with OIDs as partition of table without OIDs" +#~ msgstr "kan inte skapa tabell med OID:er som partition till tabell utan OID:er" + +#~ msgid "child table \"%s\" has a conflicting \"%s\" column" +#~ msgstr "barntabell \"%s\" har en motstridig kolumn \"%s\"" + +#~ msgid "cannot add constraint to only the partitioned table when partitions exist" +#~ msgstr "kan inte lägga till villkor bara till den partitionerade tabellen när partitioner existerar" + +#~ msgid "cannot reference partitioned table \"%s\"" +#~ msgstr "kan inte referera partitionerad tabell \"%s\"" + +#~ msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +#~ msgstr "tabell\"%s\" utan OID:er kan inte ärva från tabell \"%s\" med OID:er" + +#~ msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +#~ msgstr "kan inte ansluta tabell\"%s\" utan OID:er som partition till tabell \"%s\" med OID:er" + +#~ msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" +#~ msgstr "kan inte ansluta tabell\"%s\" med OID:er som partition till tabell \"%s\" utan OID:er" + +#~ msgid "relation \"%s\" page %u is uninitialized --- fixing" +#~ msgstr "relation \"%s\" sida %u är inte initierad --- fixar" + +#~ msgid "logical replication target relation \"%s.%s\" is not a table" +#~ msgstr "logisk replikerings målrelation \"%s.%s\" är inte en tabell" + +#~ msgid "tuple to be deleted was already moved to another partition due to concurrent update" +#~ msgstr "tupel som skall raderas har redan flyttats till en annan partition på grund av samtidig update" + +#~ msgid "tuple to be updated was already moved to another partition due to concurrent update" +#~ msgstr "tupel som skall uppdateras hade redan flyttats till en annan partition på grund av samtidig update" + +#~ msgid "DROP ASSERTION is not yet implemented" +#~ msgstr "DROP ASSERTION är inte implementerat ännu" + +#~ msgid "The cast requires a non-immutable conversion." +#~ msgstr "Typomvandligen kräver en icke-immuterbar konvertering." + +#~ msgid "Try putting the literal value in single quotes." +#~ msgstr "Försöka att sätta literalen inom enkelcitattecken." + +#~ msgid "archive command was terminated by signal %d" +#~ msgstr "arkiveringskommandot terminerades av signal %d" + +#~ msgid "%s (PID %d) was terminated by signal %d" +#~ msgstr "%s (PID %d) terminerades av signal %d" + +#~ msgid "could not stat control file \"%s\": %m" +#~ msgstr "kunde inte göra stat() på kontrollfil \"%s\": %m" + +#~ msgid "could not read file \"%s\", read %d of %d: %m" +#~ msgstr "kunde inte läsa fil \"%s\": läste %d av %d: %m" + +#~ msgid "could not read file \"%s\", read %d of %u: %m" +#~ msgstr "kunde inte läsa fil \"%s\": läste %d av %u: %m" + +#~ msgid "dynamic shared memory is disabled" +#~ msgstr "dynamiskt delat minne är avstängt" + +#~ msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +#~ msgstr "Sätt dynamic_shared_memory_type till ett annat värde än \"none\"." + +#~ msgid "epoll_ctl() failed: %m" +#~ msgstr "epoll_ctl() misslyckades: %m" + +#~ msgid "epoll_wait() failed: %m" +#~ msgstr "epoll_wait() misslyckades: %m" + +#~ msgid "poll() failed: %m" +#~ msgstr "poll() misslyckades: %m" + +#~ msgid "could not seek to block %u in file \"%s\": %m" +#~ msgstr "kunde inte söka (seek) till block %u i fil \"%s\": %m" + +#~ msgid "cannot convert reserved abstime value to date" +#~ msgstr "kan inte konvertera reserverat abstime-värde till date" + +#~ msgid "abstime out of range for date" +#~ msgstr "abstime utanför giltigt område för date" + +#~ msgid "value out of range: underflow" +#~ msgstr "värde utanför giltigt intervall: underflow" + +#~ msgid "could not determine which collation to use for upper() function" +#~ msgstr "kunde inte bestämma jämförelse (collation) för funktionen upper()" + +#~ msgid "could not determine which collation to use for initcap() function" +#~ msgstr "kunde inte bestämma jämförelse (collation) för funktionen initcap()" + +#~ msgid "cannot create bounding box for empty polygon" +#~ msgstr "kan inte skapa en omslutande box för en tom polygon" + +#~ msgid "cannot convert empty polygon to circle" +#~ msgstr "kan inte konvertera en tom polygon till en cirkel" + +#~ msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +#~ msgstr "Argumenten till jsonb_build_object() måste bestå av varannan nyckel och varannat värde." + +#~ msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +#~ msgstr "Överväg att använda pg_logfile_rotate() istället vilken är en del av \"core\"." + +#~ msgid "invalid time zone name: \"%s\"" +#~ msgstr "ogiltigt tidszon-namn: \"%s\"" + +#~ msgid "cannot convert abstime \"invalid\" to timestamp" +#~ msgstr "kan inte konvertera abstime \"invalid\" till timestamp" + +#~ msgid "invalid status in external \"tinterval\" value" +#~ msgstr "ogitlig status i externt \"tinterval\"-värde" + +#~ msgid "cannot convert reltime \"invalid\" to interval" +#~ msgstr "kan inte konvertera reltime \"invalid\" till interval" + +#~ msgid "invalid input syntax for numeric time zone: \"%s\"" +#~ msgstr "felaktig indatasyntax för numerisk tidszon: \"%s\"" + +#~ msgid "could not open relation mapping file \"%s\": %m" +#~ msgstr "kunde inte öppna relationsmappningsfil \"%s\": %m" + +#~ msgid "could not read relation mapping file \"%s\": %m" +#~ msgstr "kunde inte läsa relationsmappningsfil \"%s\": %m" + +#~ msgid "could not write to relation mapping file \"%s\": %m" +#~ msgstr "kunde inte skriva till relationsmappningsfilen \"%s\": %m" + +#~ msgid "could not fsync relation mapping file \"%s\": %m" +#~ msgstr "kunde inte fsync:a relationsmappningsfilen \"%s\": %m" + +#~ msgid "could not close relation mapping file \"%s\": %m" +#~ msgstr "kunde inte stänga relationsmappningsfilen \"%s\": %m" + +#~ msgid "Create new tables with OIDs by default." +#~ msgstr "Skapa nya tabeller med OID:er som standard." + +#~ msgid "parameter \"%s\" requires a numeric value" +#~ msgstr "parameter \"%s\" kräver ett numeriskt värde" + +#~ msgid "view must have at least one column" +#~ msgstr "en vy måste ha minst en kolumn" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "tabellen \"%s\" har flera integritetsvillkor med namn \"%s\"" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "domänen %s har flera villkor med namn \"%s\"" + +#~ msgid "included columns must not intersect with key columns" +#~ msgstr "inkluderaede kolumner får inte överlappa med nyckelkolumner" + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "kolumn \"%s\" angivet mer än en gång i partitioneringsnyckel" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "\"%s\" är redan ett attribut med typ %s" + +#~ msgid "channel binding type \"tls-server-end-point\" is not supported by this build" +#~ msgstr "kanalbindningstyp \"tls-server-end-point\" stöds inte av detta bygge" + +#~ msgid "client requires SCRAM channel binding, but it is not supported" +#~ msgstr "klient kräver SCRAM-kanalbindning, men det stöds inte" + +#~ msgid "operator procedure must be specified" +#~ msgstr "operatorprocedur måste anges" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "procedurnummer %d för (%s,%s) finns med mer än en gång" + +#~ msgid "hash procedure 1 must have one argument" +#~ msgstr "hash-procedur 1 måste ha ett argument" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "ogiltigt procedurnummer %d, måste vara mellan 1 och %d" + +#~ msgid "foreign key referencing partitioned table \"%s\" must not be ONLY" +#~ msgstr "främmande nyckel som refererar till partitionerad tabell \"%s\" får inte vara ONLY" + +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "kunde inte öppna BufFile \"%s\"" + +#~ msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." +#~ msgstr "Om du är säker på att ingen gammal serverprocess forfarande kör, så ta bort det delade minnesblocket eller radera helt enkelt filen \"%s\"." + +#~ msgid "regexp_split_to_array does not support the global option" +#~ msgstr "regexp_split_to_array stöder inte global-flaggan" + +#~ msgid "regexp_split_to_table does not support the global option" +#~ msgstr "regexp_split_to_table stöder inte global-flaggan" + +#~ msgid "invalid regexp option: \"%c\"" +#~ msgstr "ogiltig regexp-flagga: \"%c\"" + +#~ msgid "ucnv_fromUChars failed: %s" +#~ msgstr "ucnv_fromUChars misslyckades: %s" + +#~ msgid "ucnv_toUChars failed: %s" +#~ msgstr "ucnv_toUChars misslyckades: %s" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT får inte anropas i en subtransaktion" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT måste anropas innan någon fråga" + +#~ msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT måste anropas i en transaktion" + +#~ msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +#~ msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT får inte anropas i en transaktion" + +#~ msgid "pg_ident.conf was not reloaded" +#~ msgstr "pg_ident.conf laddades inte om" + +#~ msgid "data type %s has no default btree operator class" +#~ msgstr "datatyp %s har ingen default btree-operatorklass" + +#~ msgid "data type %s has no default hash operator class" +#~ msgstr "datatyp %s har ingen default hash-operatorklass" + +#~ msgid "subscription with slot_name = NONE must also set create_slot = false" +#~ msgstr "prenumeration med slot_name = NONE måste också sätta create_slot = false" + +#~ msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +#~ msgstr "slot_name = NONE och create_slot = true är ömsesidigt uteslutna flaggor" + +#~ msgid "slot_name = NONE and enabled = true are mutually exclusive options" +#~ msgstr "slot_name = NONE och enabled = true är ömsesidigt uteslutna flaggor" + +#~ msgid "connect = false and copy_data = true are mutually exclusive options" +#~ msgstr "connect = false och copy_data = true är ömsesidigt uteslutna flaggor" + +#~ msgid "connect = false and create_slot = true are mutually exclusive options" +#~ msgstr "connect = false och create_slot = true är ömsesidigt uteslutna flaggor" + +#~ msgid "default_table_access_method may not be empty." +#~ msgstr "default_table_access_method får inte vara tom." + +#~ msgid "only heap AM is supported" +#~ msgstr "bara heap-AM stöds" diff --git a/src/backend/po/tr.po b/src/backend/po/tr.po new file mode 100644 index 00000000000..a85931e0d9e --- /dev/null +++ b/src/backend/po/tr.po @@ -0,0 +1,27304 @@ +# translation of postgres-tr.po to Turkish +# Nicolai Tufar , 2002-2006. +# Devrim GUNDUZ , 2003, 2004, 2005, 2006. +# Abdullah GÜLNER 2017, 2018, 2019. +msgid "" +msgstr "" +"Project-Id-Version: postgres-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2019-02-07 07:43+0000\n" +"PO-Revision-Date: 2019-04-01 17:44+0300\n" +"Last-Translator: Abdullah Gülner <>\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: /home/ntufar/pg/pgsql/src/backend\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-SearchPath-0: /home/ntufar/pg/pgsql/src/backend\n" + +#: ../common/config_info.c:130 ../common/config_info.c:138 ../common/config_info.c:146 ../common/config_info.c:154 ../common/config_info.c:162 ../common/config_info.c:170 ../common/config_info.c:178 ../common/config_info.c:186 ../common/config_info.c:194 +msgid "not recorded" +msgstr "kayıtlı değil" + +#: ../common/controldata_utils.c:58 commands/copy.c:3196 commands/extension.c:3337 utils/adt/genfile.c:151 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" dosyası, okunmak için açılamadı: %m" + +#: ../common/controldata_utils.c:62 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: \"%s\" dosyası, okunmak için açılamadı: %s\n" + +#: ../common/controldata_utils.c:75 access/transam/timeline.c:347 access/transam/xlog.c:3440 access/transam/xlog.c:10942 access/transam/xlog.c:10955 access/transam/xlog.c:11380 access/transam/xlog.c:11460 access/transam/xlog.c:11499 access/transam/xlog.c:11542 access/transam/xlogfuncs.c:658 access/transam/xlogfuncs.c:677 commands/extension.c:3347 libpq/hba.c:499 +#: replication/logical/origin.c:719 replication/logical/origin.c:749 replication/logical/reorderbuffer.c:3304 replication/walsender.c:510 storage/file/copydir.c:195 utils/adt/genfile.c:168 utils/adt/misc.c:944 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" dosyası okuma hatası: %m" + +#: ../common/controldata_utils.c:78 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: \"%s\" dosyası okunamadı: %s\n" + +#: ../common/controldata_utils.c:86 +#, c-format +msgid "could not read file \"%s\": read %d of %d" +msgstr "\"%1$s\" dosyası okuma hatası, %3$d nin %2$d si okundu" + +#: ../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%1$s: \"%2$s\" dosyası okuma hatası: %4$d nin %3$d si okundu\n" + +#: ../common/controldata_utils.c:112 +msgid "byte ordering mismatch" +msgstr "byte sıralama uyuşmazlığı" + +#: ../common/controldata_utils.c:114 +#, c-format +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory.\n" +msgstr "" +"UYARI: olası bayt sıralama uyumsuzluğu\n" +"pg_control dosyasını saklamak için kullanılan bayt sıralaması, bu program\n" +"tarafından kullanılan sıralama ile uyuşmayabilir. Bu durumda aşağıdaki\n" +"sonuçlar yanlış olacak ve PostgreSQL kurulumu bu veri dizini ile uyumsuz\n" +"olacaktır.\n" + +#: ../common/exec.c:127 ../common/exec.c:241 ../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "geçerli dizin belirlenemedi: %s" + +#: ../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "\"%s\" ikili dosyası geçersiz" + +#: ../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili dosyası okunamıyor" + +#: ../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "çalıştırılacak \"%s\" bulunamadı" + +#: ../common/exec.c:257 ../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "çalışma dizini \"%s\" olarak değiştirilemedi: %s" + +#: ../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "sembolik link \"%s\" okuma hatası" + +#: ../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "pclose başarısız oldu: %s" + +#: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 ../common/fe_memutils.c:98 ../common/psprintf.c:182 ../port/path.c:632 ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:171 utils/misc/ps_status.c:179 utils/misc/ps_status.c:209 utils/misc/ps_status.c:217 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../common/file_utils.c:82 ../common/file_utils.c:186 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\" dosyasının durumu görüntülenemiyor (stat): %s\n" + +#: ../common/file_utils.c:162 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: \"%s\" dizini açılamadı: %s\n" + +#: ../common/file_utils.c:198 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: \"%s\" dizini okunamadı: %s\n" + +#: ../common/file_utils.c:231 ../common/file_utils.c:291 ../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: \"%s\" dosyası açılamadı: %s\n" + +#: ../common/file_utils.c:304 ../common/file_utils.c:376 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: \"%s\" dosyası fsync işlemi başarısız: %s\n" + +#: ../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: \"%s\" dosyasının adı \"%s\" olarak değiştirilemedi: %s\n" + +#: ../common/pgfnames.c:45 +#, c-format +msgid "could not open directory \"%s\": %s\n" +msgstr "\"%s\" dizini açılamıyor: %s\n" + +#: ../common/pgfnames.c:72 +#, c-format +msgid "could not read directory \"%s\": %s\n" +msgstr "\"%s\" dizini okunamıyor: %s\n" + +#: ../common/pgfnames.c:84 +#, c-format +msgid "could not close directory \"%s\": %s\n" +msgstr "\"%s\" dizini kapatılamadı: %s\n" + +#: ../common/psprintf.c:180 ../port/path.c:630 ../port/path.c:668 ../port/path.c:685 access/transam/twophase.c:1383 access/transam/xlog.c:6482 lib/dshash.c:246 lib/stringinfo.c:277 libpq/auth.c:1134 libpq/auth.c:1505 libpq/auth.c:1573 libpq/auth.c:2091 postmaster/bgworker.c:337 postmaster/bgworker.c:907 postmaster/postmaster.c:2390 postmaster/postmaster.c:2412 postmaster/postmaster.c:3979 +#: postmaster/postmaster.c:4687 postmaster/postmaster.c:4762 postmaster/postmaster.c:5454 postmaster/postmaster.c:5791 replication/libpqwalreceiver/libpqwalreceiver.c:260 replication/logical/logical.c:179 storage/buffer/localbuf.c:436 storage/file/fd.c:781 storage/file/fd.c:1220 storage/file/fd.c:1381 storage/file/fd.c:2294 storage/ipc/procarray.c:1066 storage/ipc/procarray.c:1554 +#: storage/ipc/procarray.c:1561 storage/ipc/procarray.c:1982 storage/ipc/procarray.c:2606 utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 utils/adt/formatting.c:1568 utils/adt/formatting.c:1690 utils/adt/formatting.c:1813 utils/adt/pg_locale.c:468 utils/adt/pg_locale.c:652 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:221 utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 utils/misc/guc.c:4240 utils/misc/guc.c:4256 utils/misc/guc.c:4269 utils/misc/guc.c:7244 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 utils/mmgr/dsa.c:714 utils/mmgr/dsa.c:796 utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 +#: utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 +#, c-format +msgid "out of memory" +msgstr "yetersiz bellek" + +#: ../common/relpath.c:58 +#, c-format +msgid "invalid fork name" +msgstr "geçersiz çatal (fork) adı" + +#: ../common/relpath.c:59 +#, c-format +msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." +msgstr "Geçerli çatal (fork) adları: \"main\", \"fsm\", \"vm\", and \"init\"." + +#: ../common/restricted_token.c:68 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: UYARI: bu platformda restricted token oluşturulamıyor\n" + +#: ../common/restricted_token.c:77 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: process token açma başarısız: hata kodu %lu\n" + +#: ../common/restricted_token.c:90 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: SIDler ayrılamıyor (allocate): Hata kodu %lu\n" + +#: ../common/restricted_token.c:110 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: restricted token oluşturulamıyor: hata kodu %lu\n" + +#: ../common/restricted_token.c:132 +#, c-format +msgid "%s: could not start process for command \"%s\": error code %lu\n" +msgstr "%s: \"%s\" komutu için işlem (process) başlatılamadı: Hata kodu %lu\n" + +#: ../common/restricted_token.c:170 +#, c-format +msgid "%s: could not re-execute with restricted token: error code %lu\n" +msgstr "%s: restricted token ile tekrar çalıştırılamadı (re-execute): hata kodu %lu\n" + +#: ../common/restricted_token.c:186 +#, c-format +msgid "%s: could not get exit code from subprocess: error code %lu\n" +msgstr "%s: alt-işlemden çıkış kodu alınamadı: hata kodu %lu\n" + +#: ../common/rmtree.c:77 +#, c-format +msgid "could not stat file or directory \"%s\": %s\n" +msgstr "\"%s\" dosya ya da dizini bulunamadı: %s\n" + +#: ../common/rmtree.c:104 ../common/rmtree.c:121 +#, c-format +msgid "could not remove file or directory \"%s\": %s\n" +msgstr "\"%s\" dosya ya da dizin silme hatası: %s\n" + +#: ../common/saslprep.c:1093 +#, c-format +msgid "password too long" +msgstr "parola fazla uzun" + +#: ../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "geçerli kullanıcı ID si bulunamadı %ld: %s" + +#: ../common/username.c:45 libpq/auth.c:2038 +msgid "user does not exist" +msgstr "kullanıcı mevcut değil" + +#: ../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "kullanıcı adı arama başarısız: hata kodu %lu" + +#: ../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "komut çalıştırılabilir değil" + +#: ../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "komut bulunamadı" + +#: ../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "alt süreç %d kodu ile sonlandı" + +#: ../common/wait_error.c:61 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "alt süreç 0x%X exception tarafından sonlandırıldı" + +#: ../common/wait_error.c:71 +#, c-format +msgid "child process was terminated by signal %s" +msgstr "alt süreç %s sinyali tarafından sonlandırıldı" + +#: ../common/wait_error.c:75 +#, c-format +msgid "child process was terminated by signal %d" +msgstr "alt süreç %d sinyali tarafından sonlandırıldı" + +#: ../common/wait_error.c:80 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "alt süreç beklenmeyen status kodu ile sonlandırıldı %d" + +#: ../port/chklocale.c:288 +#, c-format +msgid "could not determine encoding for codeset \"%s\"" +msgstr "\"%s\" kod kümesi için kodlama (encoding) belirlenemedi" + +#: ../port/chklocale.c:409 ../port/chklocale.c:415 +#, c-format +msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" +msgstr "\"%s\" yerel ayarları için kodlama (encoding) belirlenemdi: kod-kümesi \"%s\" dir" + +#: ../port/dirmod.c:218 +#, c-format +msgid "could not set junction for \"%s\": %s" +msgstr "\"%s\" için junction ayarlanamadı: %s" + +#: ../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\" için junction ayarlanamadı: %s\n" + +#: ../port/dirmod.c:295 +#, c-format +msgid "could not get junction for \"%s\": %s" +msgstr "\"%s\" için junction bulunamadı: %s" + +#: ../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\" için junction bulunamadıı: %s\n" + +#: ../port/open.c:111 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "\"%s\" dosyası açılamıyor: %s" + +#: ../port/open.c:112 +msgid "lock violation" +msgstr "kilit (lock) çakışması" + +#: ../port/open.c:112 +msgid "sharing violation" +msgstr "paylaşım çakışması" + +#: ../port/open.c:113 +#, c-format +msgid "Continuing to retry for 30 seconds." +msgstr "30 saniyede bir denemeye devam ediliyor." + +#: ../port/open.c:114 +#, c-format +msgid "You might have antivirus, backup, or similar software interfering with the database system." +msgstr "Veritabanı sistemi ile etkileşen antivirüs, yedekleme yada benzeri yazılımlar olabilir." + +#: ../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "geçerli dizin belirlenemedi: %s\n" + +#: ../port/strerror.c:25 +#, c-format +msgid "unrecognized error %d" +msgstr "bilinmeyen hata %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "Administrators grubunun SID numarası alınamadı: hata kodu %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "PowerUsers grubunun SID numarası alınamadı: %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "access token üyeliği kontrol edilemedi: hata kodu %lu\n" + +#: access/brin/brin.c:200 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "\"%s\" indeksi %u sayfası için BRIN aralık özetleme talebi kaydedilmedi" + +#: access/brin/brin.c:877 access/brin/brin.c:954 access/gin/ginfast.c:1018 access/transam/xlog.c:10354 access/transam/xlog.c:10881 access/transam/xlogfuncs.c:286 access/transam/xlogfuncs.c:313 access/transam/xlogfuncs.c:352 access/transam/xlogfuncs.c:373 access/transam/xlogfuncs.c:394 access/transam/xlogfuncs.c:464 access/transam/xlogfuncs.c:520 +#, c-format +msgid "recovery is in progress" +msgstr "kurtarma sürüyor" + +#: access/brin/brin.c:878 access/brin/brin.c:955 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "BRIN kontrol fonksiyonları kurtarma sırasında çalıştırılamaz." + +#: access/brin/brin.c:886 access/brin/brin.c:963 +#, c-format +msgid "block number out of range: %s" +msgstr "blok sayısı aralık dışında: %s" + +#: access/brin/brin.c:909 access/brin/brin.c:986 +#, c-format +msgid "\"%s\" is not a BRIN index" +msgstr "\"%s\" bir BRIN indeksi değildir" + +#: access/brin/brin.c:925 access/brin/brin.c:1002 +#, c-format +msgid "could not open parent table of index %s" +msgstr "%s indeksinin ana talosu açılamadı" + +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 access/gist/gist.c:1381 access/nbtree/nbtinsert.c:678 access/nbtree/nbtsort.c:830 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "indeks satır boyutu %zu, azami %zu 'yi aşmaktadır (\"%s\" indeksi için)" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "bozuk BRIN indeksi: tutarsız aralık haritası" + +#: access/brin/brin_revmap.c:404 +#, c-format +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "\"%s\" BRIN indeksinde placeholder tuple kaldığı tespit edildi, siliniyor" + +#: access/brin/brin_revmap.c:601 +#, c-format +msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" +msgstr " 0x%04X beklenmedik sayfa türü (\"%s\" BRIN indeksinde), blok %u" + +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "%2$s erişim yönteminin \"%1$s\" operatör ailesi, %4$d geçersiz destek numaralı %3$s fonksiyonunu içermektedir" + +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 +#, c-format +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "%2$s erişim yönteminin \"%1$s\" operatör ailesi, %4$d destek numarası için yanlış imzalı %3$s fonksiyonunu içermektedir" + +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:196 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "%2$s erişim yönteminin \"%1$s\" operatör ailesi, %4$d geçersiz strateji numaralı %3$s fonksiyonunu içermektedir" + +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 access/spgist/spgvalidate.c:209 +#, c-format +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "%2$s erişim yöntemi için kullanılacak \"%1$s\" operator ailesi %3$s operatörü için geçersiz ORDER BY tanımlaması içermektedir" + +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:222 +#, c-format +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "%2$s erişim yönteminin \"%1$s\" operatör ailesi, yanlış imzalı %3$s operatörünü içermektedir" + +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:249 +#, c-format +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operator ailesinin%3$s ve %4$s tipleri için operatör eksiği var" + +#: access/brin/brin_validate.c:244 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operator ailesinin%3$s ve %4$s tipleri için destek fonksiyonu eksiği var" + +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:282 +#, c-format +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "%2$s erişim metodu için \"%1$s\" operator sınıfının operator eksiği var" + +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 access/gist/gistvalidate.c:266 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operator sınıfında %3$d destek fonksiyonu eksik" + +#: access/common/heaptuple.c:1080 access/common/heaptuple.c:1796 +#, c-format +msgid "number of columns (%d) exceeds limit (%d)" +msgstr "kolonların sayısı (%d), (%d) sınırını aşıyor" + +#: access/common/indextuple.c:63 +#, c-format +msgid "number of index columns (%d) exceeds limit (%d)" +msgstr "indeks kolonlarının sayısı (%d), (%d) sınırını aşıyor" + +#: access/common/indextuple.c:179 access/spgist/spgutils.c:685 +#, c-format +msgid "index row requires %zu bytes, maximum size is %zu" +msgstr "index satırının%zu byte'a gereksinmesi var, ancak en büyük byte büyüklüğü: %zu" + +#: access/common/printtup.c:365 tcop/fastpath.c:180 tcop/fastpath.c:530 tcop/postgres.c:1778 +#, c-format +msgid "unsupported format code: %d" +msgstr "desteklenmeyen biçim kodu: %d" + +#: access/common/reloptions.c:568 +#, c-format +msgid "user-defined relation parameter types limit exceeded" +msgstr "kullanıcı tanımlı ilişki (relation) parametre türü sınırı aşıldı" + +#: access/common/reloptions.c:849 +#, c-format +msgid "RESET must not include values for parameters" +msgstr "RESET, parametre için değer içermemeli" + +#: access/common/reloptions.c:881 +#, c-format +msgid "unrecognized parameter namespace \"%s\"" +msgstr "\"%s\" tanınmayan parametre ad uzayı (namespace)" + +#: access/common/reloptions.c:1121 parser/parse_clause.c:277 +#, c-format +msgid "unrecognized parameter \"%s\"" +msgstr "\"%s\" tanınmayan parametre" + +#: access/common/reloptions.c:1151 +#, c-format +msgid "parameter \"%s\" specified more than once" +msgstr "\"%s\" parametresi birden fazla kez belirtilmiştir" + +#: access/common/reloptions.c:1167 +#, c-format +msgid "invalid value for boolean option \"%s\": %s" +msgstr "\"%s\" boolean seçeneği için geçersiz değer: \"%s\"" + +#: access/common/reloptions.c:1179 +#, c-format +msgid "invalid value for integer option \"%s\": %s" +msgstr "\"%s\" tamsayı seçeneği için geçersiz değer: %s" + +#: access/common/reloptions.c:1185 access/common/reloptions.c:1205 +#, c-format +msgid "value %s out of bounds for option \"%s\"" +msgstr "%s değeri, \"%s\" seçeneği için sınırların dışındadır" + +#: access/common/reloptions.c:1187 +#, c-format +msgid "Valid values are between \"%d\" and \"%d\"." +msgstr "Geçerli değerler \"%d\" ile \"%d\" arasındadır." + +#: access/common/reloptions.c:1199 +#, c-format +msgid "invalid value for floating point option \"%s\": %s" +msgstr "\"%s\" kayan nokta (floating point) seçeneği için geçersiz değer: %s" + +#: access/common/reloptions.c:1207 +#, c-format +msgid "Valid values are between \"%f\" and \"%f\"." +msgstr "Geçerli değerler \"%f\" ve \"%f\" arasındadır." + +#: access/common/tupconvert.c:108 +#, c-format +msgid "Returned type %s does not match expected type %s in column %d." +msgstr "Dönen tür (%s) beklenen tür (%s) ile eşleşmiyor (%d sütununda)" + +#: access/common/tupconvert.c:136 +#, c-format +msgid "Number of returned columns (%d) does not match expected column count (%d)." +msgstr "Dönen kolonların sayısı (%d) beklenen kolon sayısı (%d) ile eşleşmiyor." + +#: access/common/tupconvert.c:329 +#, c-format +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." +msgstr "%2s türünün \"%1s\" niteliği uyan %3s türünün niteliğiyle eşleşmiyor." + +#: access/common/tupconvert.c:341 +#, c-format +msgid "Attribute \"%s\" of type %s does not exist in type %s." +msgstr "%2s tipinin \"%1s\" niteliği %s tipinde bulunmaz." + +#: access/common/tupdesc.c:837 parser/parse_clause.c:819 parser/parse_relation.c:1539 +#, c-format +msgid "column \"%s\" cannot be declared SETOF" +msgstr "\"%s\" kolonu SETOF olarak bildirilemez" + +#: access/gin/ginbulk.c:44 +#, c-format +msgid "posting list is too long" +msgstr "posting listesi fazla uzun" + +#: access/gin/ginbulk.c:45 +#, c-format +msgid "Reduce maintenance_work_mem." +msgstr "maintenance_work_mem değerini düşürün." + +#: access/gin/ginfast.c:1019 +#, c-format +msgid "GIN pending list cannot be cleaned up during recovery." +msgstr "Kurtarma sırasında GIN bekleyen listesi silinemez." + +#: access/gin/ginfast.c:1026 +#, c-format +msgid "\"%s\" is not a GIN index" +msgstr "\"%s\" bir GIN indeksi değildir" + +#: access/gin/ginfast.c:1037 +#, c-format +msgid "cannot access temporary indexes of other sessions" +msgstr "diğer oturumların geçici indexlerine erişilemez" + +#: access/gin/ginscan.c:402 +#, c-format +msgid "old GIN indexes do not support whole-index scans nor searches for nulls" +msgstr "eski GIN indeksleri tam index taramasını ya da null değerler için aramayı desteklememektedir" + +#: access/gin/ginscan.c:403 +#, c-format +msgid "To fix this, do REINDEX INDEX \"%s\"." +msgstr "Bunu düzeltmek için, REINDEX INDEX \"%s\" yapın." + +#: access/gin/ginutil.c:138 executor/execExpr.c:1868 utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6387 utils/adt/rowtypes.c:935 +#, c-format +msgid "could not identify a comparison function for type %s" +msgstr "%s tipi için karşılaştırma fonksiyonu bulunamadı" + +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 +#, c-format +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "\"%2$s\" erişim yönteminin %1$s operatör ailesi, farklı sol ve sağ girdi tipleri olan %3$s destek fonksiyonunu içeriyor" + +#: access/gin/ginvalidate.c:257 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "\"%2s\" erişim yöntemi için kullanılacak %1s operatör sınıfının %1d ya da %2d destek fonksiyonu eksik" + +#: access/gist/gist.c:717 access/gist/gistvacuum.c:258 +#, c-format +msgid "index \"%s\" contains an inner tuple marked as invalid" +msgstr "\"%s\" indeksi geçersiz olarak işaretlenmiş bir iç tuple içeriyor" + +#: access/gist/gist.c:719 access/gist/gistvacuum.c:260 +#, c-format +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." +msgstr "Bunun sebebi PostgreSQL 9.1'e terfiden önce yaşanmış bir çökme sonrası kurtarma sırasındaki tamamlanmamış bir page split'dir." + +#: access/gist/gist.c:720 access/gist/gistutil.c:759 access/gist/gistutil.c:770 access/gist/gistvacuum.c:261 access/hash/hashutil.c:241 access/hash/hashutil.c:252 access/hash/hashutil.c:264 access/hash/hashutil.c:285 access/nbtree/nbtpage.c:678 access/nbtree/nbtpage.c:689 +#, c-format +msgid "Please REINDEX it." +msgstr "Lütfen onu REINDEX'leyin." + +#: access/gist/gistbuild.c:252 +#, c-format +msgid "invalid value for \"buffering\" option" +msgstr "\"buffering\" seçeneği için geçersiz değer" + +#: access/gist/gistbuild.c:253 +#, c-format +msgid "Valid values are \"on\", \"off\", and \"auto\"." +msgstr "Geçerli değerler: \"on\", \"off\", ve \"auto\"." + +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 +#, c-format +msgid "could not write block %ld of temporary file: %m" +msgstr "geçici dosyasının %ld bloku yazılamıyor: %m" + +#: access/gist/gistsplit.c:446 +#, c-format +msgid "picksplit method for column %d of index \"%s\" failed" +msgstr " %d kolonu için (%s\" indeksinin) picksplit metodu başarısız oldu" + +#: access/gist/gistsplit.c:448 +#, c-format +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "İndeks en uygun durumda değil. Optimize etmek için bir geliştirici ile bağlantı kurun, ya da kolonu CREATE INDEX komutunda ikinci olarak kullanmayı deneyin." + +#: access/gist/gistutil.c:756 access/hash/hashutil.c:238 access/nbtree/nbtpage.c:675 +#, c-format +msgid "index \"%s\" contains unexpected zero page at block %u" +msgstr "\"%s\" indexnde %u bloğunda beklenmeyen boş sayfa" + +#: access/gist/gistutil.c:767 access/hash/hashutil.c:249 access/hash/hashutil.c:261 access/nbtree/nbtpage.c:686 +#, c-format +msgid "index \"%s\" contains corrupted page at block %u" +msgstr "\"%s\" indexnde %u bloğunda bozuk sayfa" + +#: access/gist/gistvalidate.c:196 +#, c-format +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "\"%2$s\" erişim yönteminin \"%1$s\" operator ailesi \"%3$s\" operatörü için desteklenmeyen ORDER BY tanımlaması içeriyor" + +#: access/gist/gistvalidate.c:207 +#, c-format +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "%2$s erişim yöntemi için kullanılacak \"%1$s\" operator ailesi %3$s operatörü için yanlış ORDER BY opfamily spesifikasyonu içermektedir." + +#: access/hash/hashinsert.c:83 +#, c-format +msgid "index row size %zu exceeds hash maximum %zu" +msgstr "index satır boyutu %zu, %zu olan en yüksek hash boyutunu aşmaktadır" + +#: access/hash/hashinsert.c:85 access/spgist/spgdoinsert.c:1961 access/spgist/spgutils.c:746 +#, c-format +msgid "Values larger than a buffer page cannot be indexed." +msgstr "Bir buffer sayfası boyutundan yüksek değerler indekslenemz." + +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "Geçersiz taşma (overflow) blok numarası: %u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:463 +#, c-format +msgid "out of overflow pages in hash index \"%s\"" +msgstr " \"%s\" hash indexi içinde sayfa taşması hatası" + +#: access/hash/hashsearch.c:315 +#, c-format +msgid "hash indexes do not support whole-index scans" +msgstr "hash indexler tüm index taramasını desteklememektedir" + +#: access/hash/hashutil.c:277 +#, c-format +msgid "index \"%s\" is not a hash index" +msgstr "\"%s\" indexi bir hash indexi değildir" + +#: access/hash/hashutil.c:283 +#, c-format +msgid "index \"%s\" has wrong hash version" +msgstr "\"%s\" indexi yanlış hash sürümüne sahiptir" + +#: access/hash/hashvalidate.c:191 +#, c-format +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operator ailesi %3$s operatörü için destek fonksiyonuna sahip değil" + +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 +#, c-format +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "\"%2$s\" erişim metodu için \"%1$s\" operatör ailesinde çapraz-tür (cross-type) operatör(ler) eksik" + +#: access/heap/heapam.c:1304 access/heap/heapam.c:1333 access/heap/heapam.c:1366 catalog/aclchk.c:1828 +#, c-format +msgid "\"%s\" is an index" +msgstr "\"%s\" bir indextir" + +#: access/heap/heapam.c:1309 access/heap/heapam.c:1338 access/heap/heapam.c:1371 catalog/aclchk.c:1835 commands/tablecmds.c:10822 commands/tablecmds.c:14107 +#, c-format +msgid "\"%s\" is a composite type" +msgstr "\"%s\" bir birleşik tiptir" + +#: access/heap/heapam.c:2645 +#, c-format +msgid "cannot insert tuples in a parallel worker" +msgstr "paralel worker içine tuple eklenemez (insert)" + +#: access/heap/heapam.c:3092 +#, c-format +msgid "cannot delete tuples during a parallel operation" +msgstr "paralel işlem sırasında tuple silinemez (delete)" + +#: access/heap/heapam.c:3138 +#, c-format +msgid "attempted to delete invisible tuple" +msgstr "görünmez tuple silinmeye teşebbüs edildi" + +#: access/heap/heapam.c:3572 access/heap/heapam.c:6409 +#, c-format +msgid "cannot update tuples during a parallel operation" +msgstr "paralel işlem sırasında tuple güncellenemez (update)" + +#: access/heap/heapam.c:3720 +#, c-format +msgid "attempted to update invisible tuple" +msgstr "görünmez tuple güncellenmeye teşebbüs edildi" + +#: access/heap/heapam.c:5085 access/heap/heapam.c:5123 access/heap/heapam.c:5375 executor/execMain.c:2662 +#, c-format +msgid "could not obtain lock on row in relation \"%s\"" +msgstr "\"%s\" tablosundaki satır için lock alınamadı" + +#: access/heap/hio.c:338 access/heap/rewriteheap.c:682 +#, c-format +msgid "row is too big: size %zu, maximum size %zu" +msgstr "satır çok büyük: boyutu %zu, olabileceği en fazla boyut %zu" + +#: access/heap/rewriteheap.c:942 +#, c-format +msgid "could not write to file \"%s\", wrote %d of %d: %m" +msgstr "\"%s\" dosyasına yazma başarısız, %d'nin %d'si yazılabildi: %m" + +#: access/heap/rewriteheap.c:982 access/heap/rewriteheap.c:1203 access/heap/rewriteheap.c:1302 access/transam/timeline.c:411 access/transam/timeline.c:490 access/transam/xlog.c:3307 access/transam/xlog.c:3473 replication/logical/snapbuild.c:1648 replication/slot.c:1313 replication/slot.c:1405 storage/file/fd.c:639 storage/file/fd.c:3533 storage/smgr/md.c:1044 storage/smgr/md.c:1289 +#: storage/smgr/md.c:1463 utils/misc/guc.c:7266 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" dosyası fsync hatası: %m" + +#: access/heap/rewriteheap.c:1036 access/heap/rewriteheap.c:1155 access/transam/timeline.c:314 access/transam/timeline.c:465 access/transam/xlog.c:3261 access/transam/xlog.c:3411 access/transam/xlog.c:10692 access/transam/xlog.c:10730 access/transam/xlog.c:11133 postmaster/postmaster.c:4454 replication/logical/origin.c:575 replication/slot.c:1262 storage/file/copydir.c:167 +#: storage/smgr/md.c:327 utils/time/snapmgr.c:1297 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "\"%s\" dosyası oluşturulamıyor: %m" + +#: access/heap/rewriteheap.c:1165 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "%s dosyası %u'ya küçültülemedi: %m" + +#: access/heap/rewriteheap.c:1173 replication/walsender.c:490 storage/smgr/md.c:1999 +#, c-format +msgid "could not seek to end of file \"%s\": %m" +msgstr "\"%s\" dosyası ilerleme hatası (seek): %m" + +#: access/heap/rewriteheap.c:1190 access/transam/timeline.c:369 access/transam/timeline.c:404 access/transam/timeline.c:482 access/transam/xlog.c:3293 access/transam/xlog.c:3464 postmaster/postmaster.c:4464 postmaster/postmaster.c:4474 replication/logical/origin.c:590 replication/logical/origin.c:635 replication/logical/origin.c:657 replication/logical/snapbuild.c:1624 +#: replication/slot.c:1296 storage/file/copydir.c:208 utils/init/miscinit.c:1349 utils/init/miscinit.c:1360 utils/init/miscinit.c:1368 utils/misc/guc.c:7227 utils/misc/guc.c:7258 utils/misc/guc.c:9120 utils/misc/guc.c:9134 utils/time/snapmgr.c:1302 utils/time/snapmgr.c:1309 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "\"%s\" dosyası yazma hatası: %m" + +#: access/heap/rewriteheap.c:1277 access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:459 postmaster/postmaster.c:1275 postmaster/syslogger.c:1456 replication/logical/origin.c:563 replication/logical/reorderbuffer.c:2810 replication/logical/snapbuild.c:1567 replication/logical/snapbuild.c:1966 replication/slot.c:1375 storage/file/fd.c:690 storage/file/fd.c:3133 +#: storage/file/fd.c:3195 storage/file/reinit.c:255 storage/ipc/dsm.c:315 storage/smgr/md.c:426 storage/smgr/md.c:475 storage/smgr/md.c:1410 utils/time/snapmgr.c:1640 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "\"%s\" dosyası silinemedi: %m" + +#: access/heap/rewriteheap.c:1291 access/transam/timeline.c:111 access/transam/timeline.c:236 access/transam/timeline.c:333 access/transam/xlog.c:3238 access/transam/xlog.c:3356 access/transam/xlog.c:3397 access/transam/xlog.c:3674 access/transam/xlog.c:3752 access/transam/xlogutils.c:708 postmaster/syslogger.c:1465 replication/basebackup.c:517 replication/basebackup.c:1391 +#: replication/logical/origin.c:712 replication/logical/reorderbuffer.c:2304 replication/logical/reorderbuffer.c:2571 replication/logical/reorderbuffer.c:3284 replication/logical/snapbuild.c:1610 replication/logical/snapbuild.c:1710 replication/slot.c:1390 replication/walsender.c:483 replication/walsender.c:2412 storage/file/copydir.c:161 storage/file/fd.c:622 storage/file/fd.c:3428 +#: storage/file/fd.c:3512 storage/smgr/md.c:608 utils/error/elog.c:1872 utils/init/miscinit.c:1273 utils/init/miscinit.c:1408 utils/init/miscinit.c:1485 utils/misc/guc.c:7486 utils/misc/guc.c:7518 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: access/index/amapi.c:83 commands/amcmds.c:163 +#, c-format +msgid "access method \"%s\" is not of type %s" +msgstr "\"%s\" erişim metodu %s tipinde değil" + +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "\"%s\" indeks erişim metodunun bir işleyicisi (handler) yok" + +#: access/index/indexam.c:160 catalog/objectaddress.c:1223 commands/indexcmds.c:2282 commands/tablecmds.c:249 commands/tablecmds.c:273 commands/tablecmds.c:14098 commands/tablecmds.c:15391 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" bir index değildir" + +#: access/nbtree/nbtinsert.c:530 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "tekrar eden kayıt, \"%s\" tekil kısıtlamasını ihlal etmektedir" + +#: access/nbtree/nbtinsert.c:532 +#, c-format +msgid "Key %s already exists." +msgstr "\"%s\" anahtarı zaten mevcut" + +#: access/nbtree/nbtinsert.c:599 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "\"%s\" indeksi içinde tuple tekrar bulma başarısız oldu" + +#: access/nbtree/nbtinsert.c:601 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "Bu sabit olmayan bir indeks ifadesinden kaynaklanıyor olabilir." + +#: access/nbtree/nbtinsert.c:681 access/nbtree/nbtsort.c:833 +#, c-format +msgid "" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"Bir buffer sayfasının boyutunun 1/3'ni geçen değerler indekslenemez.\n" +"Yerine değerinin MD5 hash'ı değeri üzerinde function index ya da full text indexing kullanabilirisiniz." + +#: access/nbtree/nbtpage.c:318 access/nbtree/nbtpage.c:529 access/nbtree/nbtpage.c:618 parser/parse_utilcmd.c:2054 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "\"%s\" indexi btree değildir." + +#: access/nbtree/nbtpage.c:325 access/nbtree/nbtpage.c:536 access/nbtree/nbtpage.c:625 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "\"%s\" indexinde sürüm uyuşmazlığı: dosya sürümü %d, güncel sürüm %d, asgari desteklenen sürüm %d" + +#: access/nbtree/nbtpage.c:1320 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "\"%s\" indeksi yarı-ölü dahili sayfa içeriyor" + +#: access/nbtree/nbtpage.c:1322 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "Buna 9.3 ya da önceki bir sürümde kesilmiş bir VACUUM sebep olmuş olabilir. Lütfen REINDEX yapınız." + +#: access/nbtree/nbtvalidate.c:236 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operator ailesinde %3$s ve %4$s tipleri için destek fonksiyonu eksik" + +#: access/spgist/spgutils.c:136 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "sıkıştırma yöntemi, yaprak (leaf) tipi girdi tipinden farklı iken sıkıştırma yöntemi tanımlanmalı" + +#: access/spgist/spgutils.c:743 +#, c-format +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GIST dahili satır (inner tuple) boyutu %zu, %zu olan en yüksek değeri aşmaktadır" + +#: access/spgist/spgvalidate.c:269 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "\"%2$s\" erişim yönteminin \"%1$s\" operator ailesinde %4$s tipi için %3$d destek fonksiyonu eksik" + +#: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 +#, c-format +msgid "sample percentage must be between 0 and 100" +msgstr "örnek yüzdesi 0 ve 100 arasında olmalı" + +#: access/transam/commit_ts.c:295 +#, c-format +msgid "cannot retrieve commit timestamp for transaction %u" +msgstr "%u işlemi (transaction) için commit timestamp alınamıyor" + +#: access/transam/commit_ts.c:393 +#, c-format +msgid "could not get commit timestamp data" +msgstr "commit timestamp verisi alınamadı" + +#: access/transam/commit_ts.c:395 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set on the master server." +msgstr "\"%s\" konfigürasyon parametresinin ana (master) sunucuda ayarlandığından emin olunuz." + +#: access/transam/commit_ts.c:397 +#, c-format +msgid "Make sure the configuration parameter \"%s\" is set." +msgstr "\"%s\" konfigürasyon parametresinin ayarlandığından emin olun." + +#: access/transam/multixact.c:1000 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "\"%s\" veritabanı wraparound veri kaybı tehlikesini önlemek için yeni MultiXactIds oluşturan komutları kabul etmiyor" + +#: access/transam/multixact.c:1002 access/transam/multixact.c:1009 access/transam/multixact.c:1033 access/transam/multixact.c:1042 +#, c-format +msgid "" +"Execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Bu veritabanında database-wide VACUUM çalıştırın.\n" +"Ayrıca eski prepared transaction'ları commit ya da roll back etmeniz, veya eski replikasyon slotlarını silmeniz gerekebilir." + +#: access/transam/multixact.c:1007 +#, c-format +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "veritabanı, %u OID'li veritabanında wraparound veri kaybı tehlikesini önlemek için yeni MultiXactId oluşturan bağlantıları kabul etmemektedir" + +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 +#, c-format +msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "\"%s\" veritabanına %u ilave MultiXactId kullanılmadan önce vacuum işlemi uygulanmalıdır" +msgstr[1] "\"%s\" veritabanına %u ilave MultiXactId kullanılmadan önce vacuum işlemi uygulanmalıdır" + +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 +#, c-format +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgstr[0] "%u OID'li veritabanına %u ilave MultiXactId kullanılmadan önce vacuum işlemi uygulanmalıdır" +msgstr[1] "%u OID'li veritabanına %u ilave MultiXactId kullanılmadan önce vacuum işlemi uygulanmalıdır" + +#: access/transam/multixact.c:1098 +#, c-format +msgid "multixact \"members\" limit exceeded" +msgstr "multixact \"members\" sınırı aşıldı" + +#: access/transam/multixact.c:1099 +#, c-format +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "Bu komut %u üyeli bir multixact oluşturacaktı, fakat kalan boş alan sadece %u üye alır." +msgstr[1] "Bu komut %u üyeli bir multixact oluşturacaktı, fakat kalan boş alan sadece %u üye alır." + +#: access/transam/multixact.c:1104 +#, c-format +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "%u OID'li veritabanında düşürülmüş vacuum_multixact_freeze_min_age ve vacuum_multixact_freeze_table_age ayarlarıyla database-wide VACUUM çalıştırın." + +#: access/transam/multixact.c:1135 +#, c-format +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" +msgstr[0] "%u OID'li veritabanına %d ilave multixact member kullanılmadan önce vacuum işlemi uygulanmalıdır" +msgstr[1] "%u OID'li veritabanına %d ilave multixact member kullanılmadan önce vacuum işlemi uygulanmalıdır" + +#: access/transam/multixact.c:1140 +#, c-format +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "Bu veritabanında düşürülmüş vacuum_multixact_freeze_min_age ve vacuum_multixact_freeze_table_age ayarlarıyla veritabanı çapında bir VACUUM uygulayın." + +#: access/transam/multixact.c:1277 +#, c-format +msgid "MultiXactId %u does no longer exist -- apparent wraparound" +msgstr "MultiXactId %u artık yok -- apparent wraparound" + +#: access/transam/multixact.c:1285 +#, c-format +msgid "MultiXactId %u has not been created yet -- apparent wraparound" +msgstr "%u MultiXactId henüz oluşturulmadı -- apparent wraparound durumu" + +#: access/transam/multixact.c:2268 +#, c-format +msgid "MultiXactId wrap limit is %u, limited by database with OID %u" +msgstr "%2$u OID'li veritabanının MultiXactID wrap limiti %1$u" + +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 access/transam/varsup.c:146 access/transam/varsup.c:153 access/transam/varsup.c:405 access/transam/varsup.c:412 +#, c-format +msgid "" +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Veritabanı kapanmasını önlemek için bu veritabanında database-wide VACUUM çalıştırın.\n" +"Ayrıca prepared transaction'ları commit ya da roll back etmeniz, veya eski replikasyon slotlarını silmeniz gerekebilir." + +#: access/transam/multixact.c:2602 +#, c-format +msgid "oldest MultiXactId member is at offset %u" +msgstr "en eski MultiXactId üyesi %u göreli konumunda (offset)" + +#: access/transam/multixact.c:2606 +#, c-format +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "MultiXact üye wraparound korumaları devre dışı, çünkü denetim noktasından geçmiş (checkpointed) en eski %u MultiXact diskte bulunmuyor" + +#: access/transam/multixact.c:2628 +#, c-format +msgid "MultiXact member wraparound protections are now enabled" +msgstr "MultiXact üye wraparound korumaları artık devrede" + +#: access/transam/multixact.c:2631 +#, c-format +msgid "MultiXact member stop limit is now %u based on MultiXact %u" +msgstr "MultiXact üye durma sınırı %2u MultiXact'a dayalı %1u 'dir" + +#: access/transam/multixact.c:3011 +#, c-format +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgstr "en eski %u MultiXact ı bulunamadı, en erken MultiXact %u, silme (truncation) atlanıyor" + +#: access/transam/multixact.c:3029 +#, c-format +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" +msgstr "%u Multixact'ına kadar silme (truncate) yapılamıyor çünkü diskte bulunmuyor, silme atlanıyor" + +#: access/transam/multixact.c:3355 +#, c-format +msgid "invalid MultiXactId: %u" +msgstr "geçersiz MultiXactId: %u" + +#: access/transam/parallel.c:664 access/transam/parallel.c:787 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "paralel worker ilklendirmesi başarısız" + +#: access/transam/parallel.c:665 access/transam/parallel.c:788 +#, c-format +msgid "More details may be available in the server log." +msgstr "Sunucu logunda daha fazla detay bulunabilir." + +#: access/transam/parallel.c:849 +#, c-format +msgid "postmaster exited during a parallel transaction" +msgstr "paralel işlem (transaction) sırasında postmaster çıktı" + +#: access/transam/parallel.c:1036 +#, c-format +msgid "lost connection to parallel worker" +msgstr "paralel worker bağlantısı koptu" + +#: access/transam/parallel.c:1102 access/transam/parallel.c:1104 +msgid "parallel worker" +msgstr "paralel worker" + +#: access/transam/parallel.c:1249 +#, c-format +msgid "could not map dynamic shared memory segment" +msgstr "dynamic shared memory kesimi (segment) eşleştirilemedi" + +#: access/transam/parallel.c:1254 +#, c-format +msgid "invalid magic number in dynamic shared memory segment" +msgstr "dinamik shared memory kesiminde (segment) geçersiz magic numarası" + +#: access/transam/slru.c:668 +#, c-format +msgid "file \"%s\" doesn't exist, reading as zeroes" +msgstr "\"%s\" dosyası mevcut değilr, sıfırlarla dolu dosya olarak okunuyor" + +#: access/transam/slru.c:906 access/transam/slru.c:912 access/transam/slru.c:919 access/transam/slru.c:926 access/transam/slru.c:933 access/transam/slru.c:940 +#, c-format +msgid "could not access status of transaction %u" +msgstr "%u transactionunun durumuna erişilemiyor." + +#: access/transam/slru.c:907 +#, c-format +msgid "Could not open file \"%s\": %m." +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: access/transam/slru.c:913 +#, c-format +msgid "Could not seek in file \"%s\" to offset %u: %m." +msgstr "\"%s\" dosyası, offset %u imleç değiştirme hatası: %m" + +#: access/transam/slru.c:920 +#, c-format +msgid "Could not read from file \"%s\" at offset %u: %m." +msgstr "\"%s\" dosyası, offset %u okuma hatası: %m" + +#: access/transam/slru.c:927 +#, c-format +msgid "Could not write to file \"%s\" at offset %u: %m." +msgstr "\"%s\" dosyası, offset %u yazma hatası: %m" + +#: access/transam/slru.c:934 +#, c-format +msgid "Could not fsync file \"%s\": %m." +msgstr "\"%s\" dosyası fsync hatası: %m." + +#: access/transam/slru.c:941 +#, c-format +msgid "Could not close file \"%s\": %m." +msgstr "\"%s\" dosyası kapatılamıyor: %m" + +#: access/transam/slru.c:1198 +#, c-format +msgid "could not truncate directory \"%s\": apparent wraparound" +msgstr "\"%s\" dizini küçültülemedi: başa sarma durumuna rastlandı" + +#: access/transam/slru.c:1253 access/transam/slru.c:1309 +#, c-format +msgid "removing file \"%s\"" +msgstr "\"%s\" dosyası siliniyor" + +#: access/transam/timeline.c:148 access/transam/timeline.c:153 +#, c-format +msgid "syntax error in history file: %s" +msgstr "%s geçmiş dosyasında sözdizimi hatası" + +#: access/transam/timeline.c:149 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Sayısal timeline ID bekleniyordu." + +#: access/transam/timeline.c:154 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Bir write-ahead log geçiş noktası (switchpoint) lokasyonu bekleniyordu " + +#: access/transam/timeline.c:158 +#, c-format +msgid "invalid data in history file: %s" +msgstr "geçmiş dosyasında geçersiz veri: %s" + +#: access/transam/timeline.c:159 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Timeline ID daima artan sırayla olmalıdır." + +#: access/transam/timeline.c:179 +#, c-format +msgid "invalid data in history file \"%s\"" +msgstr "\"%s\" geçmiş dosyasında geçersiz veri" + +#: access/transam/timeline.c:180 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "timeline ID, child timeline ID'sinden daha düşük olmalıdır." + +#: access/transam/timeline.c:417 access/transam/timeline.c:496 access/transam/xlog.c:3314 access/transam/xlog.c:3479 access/transam/xlogfuncs.c:683 commands/copy.c:1760 storage/file/copydir.c:219 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" dosyası kapatılamıyor: %m" + +#: access/transam/timeline.c:578 +#, c-format +msgid "requested timeline %u is not in this server's history" +msgstr "talep edilmiş timeline %u bu sunucunun geçmişinde (history) bulunmuyor" + +#: access/transam/twophase.c:381 +#, c-format +msgid "transaction identifier \"%s\" is too long" +msgstr "transaction identifier \"%s\" çok uzun" + +#: access/transam/twophase.c:388 +#, c-format +msgid "prepared transactions are disabled" +msgstr "prepared transactionlar devre dışıdır" + +#: access/transam/twophase.c:389 +#, c-format +msgid "Set max_prepared_transactions to a nonzero value." +msgstr "max_prepared_transactions'ı sıfırdan farklı bir değere ayarlayın" + +#: access/transam/twophase.c:408 +#, c-format +msgid "transaction identifier \"%s\" is already in use" +msgstr "\"%s\" transaction identifier kullanılmaktadır" + +#: access/transam/twophase.c:417 access/transam/twophase.c:2435 +#, c-format +msgid "maximum number of prepared transactions reached" +msgstr "En çok olabilecek prepared transaction sayısına ulaşılmıştır." + +#: access/transam/twophase.c:418 access/transam/twophase.c:2436 +#, c-format +msgid "Increase max_prepared_transactions (currently %d)." +msgstr "max_prepared_transactions parametresini artırın (şu an: %d)." + +#: access/transam/twophase.c:586 +#, c-format +msgid "prepared transaction with identifier \"%s\" is busy" +msgstr "identifier \"%s\" olan hazırlanmış transaction meşguldur" + +#: access/transam/twophase.c:592 +#, c-format +msgid "permission denied to finish prepared transaction" +msgstr "prepared transaction bitirmede erişim hatası" + +#: access/transam/twophase.c:593 +#, c-format +msgid "Must be superuser or the user that prepared the transaction." +msgstr "Superuser veya ğreparet transaction oluşturan kullanıcısı olmalısınız." + +#: access/transam/twophase.c:604 +#, c-format +msgid "prepared transaction belongs to another database" +msgstr "prepared transaction başka bir veritabanına aittir" + +#: access/transam/twophase.c:605 +#, c-format +msgid "Connect to the database where the transaction was prepared to finish it." +msgstr "İşlemini bitirmek için transaction prepare işlemi yapıldığı veritabanına bağlanın." + +#: access/transam/twophase.c:620 +#, c-format +msgid "prepared transaction with identifier \"%s\" does not exist" +msgstr "identifier \"%s\" olan hazırlanmış transaction mevcut değil" + +#: access/transam/twophase.c:1103 +#, c-format +msgid "two-phase state file maximum length exceeded" +msgstr "two-phase state dosyası azami uzunluğu aşıldı" + +#: access/transam/twophase.c:1232 +#, c-format +msgid "could not open two-phase state file \"%s\": %m" +msgstr "\"%s\" two-phase state dosyası açma hatası: %m" + +#: access/transam/twophase.c:1253 +#, c-format +msgid "could not stat two-phase state file \"%s\": %m" +msgstr "\"%s\" two-phase state dosyası stat hatası: %m" + +#: access/transam/twophase.c:1292 +#, c-format +msgid "could not read two-phase state file \"%s\": %m" +msgstr "\"%s\" two-phase state dosyası okuma hatası: %m" + +#: access/transam/twophase.c:1384 access/transam/xlog.c:6483 +#, c-format +msgid "Failed while allocating a WAL reading processor." +msgstr "WAL reading processor ayırma işlemi sırasında hata oluştu." + +#: access/transam/twophase.c:1390 +#, c-format +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "%X/%X 'de WAL 'dan two-phase state okunamadı" + +#: access/transam/twophase.c:1398 +#, c-format +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "beklenen two-phase state verisi %X/%X 'de WAL içinde bulunmuyor." + +#: access/transam/twophase.c:1636 +#, c-format +msgid "could not remove two-phase state file \"%s\": %m" +msgstr "\"%s\" two-phase state dosyası silinemedi: %m" + +#: access/transam/twophase.c:1665 +#, c-format +msgid "could not recreate two-phase state file \"%s\": %m" +msgstr "\"%s\" two-phase state dosyası yeniden oluşturulamadı: %m" + +#: access/transam/twophase.c:1682 access/transam/twophase.c:1695 +#, c-format +msgid "could not write two-phase state file: %m" +msgstr "two-phase state dosyası yazma hatası: %m" + +#: access/transam/twophase.c:1712 +#, c-format +msgid "could not fsync two-phase state file: %m" +msgstr "two-phase state dosyası fsync hatası: %m" + +#: access/transam/twophase.c:1719 +#, c-format +msgid "could not close two-phase state file: %m" +msgstr "two-phase state dosyası kapatma hatası: %m" + +#: access/transam/twophase.c:1807 +#, c-format +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "uzun-süren bir prepared transaction için %u two-phase state dosyası yazıldı" +msgstr[1] "uzun-süren prepared transaction'lar için %u two-phase state dosyaları yazıldı" + +#: access/transam/twophase.c:2036 +#, c-format +msgid "recovering prepared transaction %u from shared memory" +msgstr "%u prepared transaction, shared memory'den kurtarılıyor" + +#: access/transam/twophase.c:2126 +#, c-format +msgid "removing stale two-phase state file for transaction %u" +msgstr "%u işlemi (transaction) için eskimiş two-phase state dosyası kaldırılıyor" + +#: access/transam/twophase.c:2133 +#, c-format +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "%u işlemi (transaction) için eskimiş two-phase state dosyası hafızadan kaldırılıyor" + +#: access/transam/twophase.c:2146 +#, c-format +msgid "removing future two-phase state file for transaction %u" +msgstr "%u işlemi (transaction) için geleceğe dönük two-phase state dosyası kaldırılıyor" + +#: access/transam/twophase.c:2153 +#, c-format +msgid "removing future two-phase state from memory for transaction %u" +msgstr "%u işlemi için geleceğe dönük two-phase state dosyası hafızadan kaldırılıyor" + +#: access/transam/twophase.c:2167 access/transam/twophase.c:2186 +#, c-format +msgid "removing corrupt two-phase state file for transaction %u" +msgstr "%u işlemi (transaction) için hasar görmüş two-phase state dosyası kaldırılıyor" + +#: access/transam/twophase.c:2193 +#, c-format +msgid "removing corrupt two-phase state from memory for transaction %u" +msgstr "%u işlemi (transaction) için hasar görmüş two-phase state dosyası hafızadan kaldırılıyor" + +#: access/transam/varsup.c:124 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" +msgstr "\"%s\" veritabanı wraparound ve veri kaybı tehlikesini önlemek için bağlantıları kabul etmmemktedir" + +#: access/transam/varsup.c:126 access/transam/varsup.c:133 +#, c-format +msgid "" +"Stop the postmaster and vacuum that database in single-user mode.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Postmaster sürecini durdurun ve o veritabanına tek-kullanıcı modunda vacuum uygulayın.\n" +"Ayrıca hazırlanmış işlemleri (prepared transaction) commit ya da roll back etmeniz, veya eski replikasyon slotlarını silmeniz gerekebilir." + +#: access/transam/varsup.c:131 +#, c-format +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" +msgstr "%u OID'li veritabanı wraparound ve veri kaybı tehlikesini önlemek için bağlantıları kabul etmemektedir" + +#: access/transam/varsup.c:143 access/transam/varsup.c:402 +#, c-format +msgid "database \"%s\" must be vacuumed within %u transactions" +msgstr "\"%s\" veritabanına transaction sayısı %u geçmeden vacuum işlemi uygulanmalıdır" + +#: access/transam/varsup.c:150 access/transam/varsup.c:409 +#, c-format +msgid "database with OID %u must be vacuumed within %u transactions" +msgstr "%u OID'li veritabanına transaction sayısı %u geçmeden vacuum işlemi uygulanmalıdır" + +#: access/transam/varsup.c:367 +#, c-format +msgid "transaction ID wrap limit is %u, limited by database with OID %u" +msgstr "%2$u OID'li veritabanın transaction ID wrap limiti %1$u" + +#: access/transam/xact.c:960 +#, c-format +msgid "cannot have more than 2^32-2 commands in a transaction" +msgstr "bir transaction içinde 2^32-2 komuttan fazla olamaz" + +#: access/transam/xact.c:1485 +#, c-format +msgid "maximum number of committed subtransactions (%d) exceeded" +msgstr "Azami committed subtransaction sayısına (%d) aşılmıştır" + +#: access/transam/xact.c:2296 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary tables" +msgstr "geçici tablolarda işlem yapmış transaction'a PREPARE yapılamaz" + +#: access/transam/xact.c:2308 +#, c-format +msgid "cannot PREPARE a transaction that has operated on temporary namespace" +msgstr "geçici ad-uzayında işlem yapmış transaction'a PREPARE yapılamaz" + +#: access/transam/xact.c:2318 +#, c-format +msgid "cannot PREPARE a transaction that has exported snapshots" +msgstr "dışa aktarılmış snapshot'ları olan transaction'a PREPARE yapılamaz" + +#: access/transam/xact.c:2327 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "manipulated logical replication worker'ları olan transaction'a PREPARE yapılamaz" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3212 +#, c-format +msgid "%s cannot run inside a transaction block" +msgstr "%s bir transaction bloğu içinde çalışamaz" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3222 +#, c-format +msgid "%s cannot run inside a subtransaction" +msgstr "%s bir subtransaction içinde çalışamaz" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3232 +#, c-format +msgid "%s cannot be executed from a function" +msgstr "%s bir fonksiyonun içinden çalıştırılamaz" + +#. translator: %s represents an SQL statement name +#: access/transam/xact.c:3301 access/transam/xact.c:3925 access/transam/xact.c:3994 access/transam/xact.c:4105 +#, c-format +msgid "%s can only be used in transaction blocks" +msgstr "%s sadece transaction bloğu içinde kullanılabilir" + +#: access/transam/xact.c:3494 +#, c-format +msgid "there is already a transaction in progress" +msgstr "bir transaction zaten başlatılmıştır" + +#: access/transam/xact.c:3605 access/transam/xact.c:3675 access/transam/xact.c:3784 +#, c-format +msgid "there is no transaction in progress" +msgstr "çalışan bir transaction yok" + +#: access/transam/xact.c:3686 +#, c-format +msgid "cannot commit during a parallel operation" +msgstr "paralel işlem sırasında commit yapılamaz" + +#: access/transam/xact.c:3795 +#, c-format +msgid "cannot abort during a parallel operation" +msgstr "paralel işlem sırasında durdurulamaz (abort)" + +#: access/transam/xact.c:3889 +#, c-format +msgid "cannot define savepoints during a parallel operation" +msgstr "paralel işlem sırasında savepoint'ler tanımlanamaz" + +#: access/transam/xact.c:3976 +#, c-format +msgid "cannot release savepoints during a parallel operation" +msgstr "paralel işlem sırasında savepoint'ler release edilemez" + +#: access/transam/xact.c:3986 access/transam/xact.c:4037 access/transam/xact.c:4097 access/transam/xact.c:4146 +#, c-format +msgid "savepoint \"%s\" does not exist" +msgstr " \"%s\" savepoint'i mevcut değil" + +#: access/transam/xact.c:4043 access/transam/xact.c:4152 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "\"%s\" savepoint'i mevcut savepoint seviyesi içinde yok" + +#: access/transam/xact.c:4085 +#, c-format +msgid "cannot rollback to savepoints during a parallel operation" +msgstr "paralel işlem sırasında savepoint'lere rollback yapılamaz" + +#: access/transam/xact.c:4213 +#, c-format +msgid "cannot start subtransactions during a parallel operation" +msgstr "paralel işlem sırasında subttransaction'lar başlatılamaz" + +#: access/transam/xact.c:4281 +#, c-format +msgid "cannot commit subtransactions during a parallel operation" +msgstr "paralel işlem sırasında subtransaction'lar commit edilemez" + +#: access/transam/xact.c:4919 +#, c-format +msgid "cannot have more than 2^32-1 subtransactions in a transaction" +msgstr "bir transaction içinde 2^32-1 subtransactiondan fazla olamaz" + +#: access/transam/xlog.c:2492 +#, c-format +msgid "could not seek in log file %s to offset %u: %m" +msgstr "%s log dosyasında %u offset'ine kadar ilerlenemedi (seek): %m" + +#: access/transam/xlog.c:2514 +#, c-format +msgid "could not write to log file %s at offset %u, length %zu: %m" +msgstr "%s kayıt (log) dosyasına yazılamadı, offset %u, uzunluk %zu: %m" + +#: access/transam/xlog.c:2792 +#, c-format +msgid "updated min recovery point to %X/%X on timeline %u" +msgstr "min yeniden kurtarma noktası %u zaman çizelgesinde (timeline) %X/%X değerine güncellendi" + +#: access/transam/xlog.c:3444 +#, c-format +msgid "not enough data in file \"%s\"" +msgstr "\"%s\" dosyasında yetersiz veri" + +#: access/transam/xlog.c:3589 +#, c-format +msgid "could not open write-ahead log file \"%s\": %m" +msgstr "\"%s\" kayıt (write-ahead log) dosyası açma hatası: %m" + +#: access/transam/xlog.c:3778 access/transam/xlog.c:5673 +#, c-format +msgid "could not close log file %s: %m" +msgstr "%s kayıt (log) dosyası kapatılamıyor: %m" + +#: access/transam/xlog.c:3844 access/transam/xlogutils.c:703 replication/walsender.c:2407 +#, c-format +msgid "requested WAL segment %s has already been removed" +msgstr "Beklenen %s WAL segmenti daha önceden kaldırıldı" + +#: access/transam/xlog.c:4051 +#, c-format +msgid "recycled write-ahead log file \"%s\"" +msgstr "\"%s\" kayıt (write-ahead log) dosyası yeniden kullanımda" + +#: access/transam/xlog.c:4063 +#, c-format +msgid "removing write-ahead log file \"%s\"" +msgstr "\"%s\" kayıt (write-ahead log) dosyası kaldırılıyor" + +#: access/transam/xlog.c:4083 +#, c-format +msgid "could not rename old write-ahead log file \"%s\": %m" +msgstr "\"%s\" kayıt (write-ahead log) dosyasının adı değiştirilemedi : %m" + +#: access/transam/xlog.c:4125 access/transam/xlog.c:4135 +#, c-format +msgid "required WAL directory \"%s\" does not exist" +msgstr "talep edilen WAL dizini \"%s\" mevcut değil" + +#: access/transam/xlog.c:4141 +#, c-format +msgid "creating missing WAL directory \"%s\"" +msgstr "eksik %s WAL dizini yaratılıyor... " + +#: access/transam/xlog.c:4144 +#, c-format +msgid "could not create missing directory \"%s\": %m" +msgstr "Eksik olan \"%s\" dizini oluşturulamadı: %m" + +#: access/transam/xlog.c:4252 +#, c-format +msgid "unexpected timeline ID %u in log segment %s, offset %u" +msgstr "beklenmeyen timeline ID %u: kayıt (log) segmenti %s, offset %u" + +#: access/transam/xlog.c:4380 +#, c-format +msgid "new timeline %u is not a child of database system timeline %u" +msgstr "yeni timeline %u veritabanı sistem timeline %u için geçerli bir alt (child) timeline değildir" + +#: access/transam/xlog.c:4394 +#, c-format +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "yeni %u zaman-çizelgesi (timeline) şimdiki %u veritabanı sistem zaman-çizelgesinden şimdiki %X/%X kurtarma noktasından önce çatallanmıştır" + +#: access/transam/xlog.c:4413 +#, c-format +msgid "new target timeline is %u" +msgstr "yeni hedef timeline %u dir" + +#: access/transam/xlog.c:4493 +#, c-format +msgid "could not create control file \"%s\": %m" +msgstr "kontrol dosyası \"%s\" oluşturma hatası: %m" + +#: access/transam/xlog.c:4505 access/transam/xlog.c:4759 +#, c-format +msgid "could not write to control file: %m" +msgstr "kontrol dosyası yazma hatası: %m" + +#: access/transam/xlog.c:4513 access/transam/xlog.c:4767 +#, c-format +msgid "could not fsync control file: %m" +msgstr "kontrol dosyası fsync hatası: %m" + +#: access/transam/xlog.c:4519 access/transam/xlog.c:4773 +#, c-format +msgid "could not close control file: %m" +msgstr "kontrol dosyası kapatma hatası: %m" + +#: access/transam/xlog.c:4538 access/transam/xlog.c:4747 +#, c-format +msgid "could not open control file \"%s\": %m" +msgstr "kontrol dosyası \"%s\" açma hatası: %m" + +#: access/transam/xlog.c:4548 +#, c-format +msgid "could not read from control file: %m" +msgstr "kontrol dosyasından okuma hatası: %m" + +#: access/transam/xlog.c:4551 +#, c-format +msgid "could not read from control file: read %d bytes, expected %d" +msgstr "kontrol dosyasından okuma hatası: %d bayt okundu, beklenen %d" + +#: access/transam/xlog.c:4566 access/transam/xlog.c:4575 access/transam/xlog.c:4599 access/transam/xlog.c:4606 access/transam/xlog.c:4613 access/transam/xlog.c:4618 access/transam/xlog.c:4625 access/transam/xlog.c:4632 access/transam/xlog.c:4639 access/transam/xlog.c:4646 access/transam/xlog.c:4653 access/transam/xlog.c:4660 access/transam/xlog.c:4669 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4685 access/transam/xlog.c:4692 utils/init/miscinit.c:1506 +#, c-format +msgid "database files are incompatible with server" +msgstr "veri dosyaları veritabanı sunucusu ile uyumlu değildir" + +#: access/transam/xlog.c:4567 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "Veritabanı clusteri PG_CONTROL_VERSION %d (0x%08x) ile ilklendirilmiştir, ancak sunucu PG_CONTROL_VERSION %d (0x%08x) ile derlenmiştir. " + +#: access/transam/xlog.c:4571 +#, c-format +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." +msgstr "Bunun nedeni eşleşmeyen bayt sıralaması olabilir. initdb yapmanız gerekebilir." + +#: access/transam/xlog.c:4576 +#, c-format +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "Veritabanı clusteri PG_CONTROL_VERSION %d ile ilklendirilmiştir, ancak sunucu PG_CONTROL_VERSION %d ile derlenmiştir." + +#: access/transam/xlog.c:4579 access/transam/xlog.c:4603 access/transam/xlog.c:4610 access/transam/xlog.c:4615 +#, c-format +msgid "It looks like you need to initdb." +msgstr "Durumu düzeltmek için initdb çalıştırın." + +#: access/transam/xlog.c:4590 +#, c-format +msgid "incorrect checksum in control file" +msgstr "kontrol dosyasında geçersiz checksum" + +#: access/transam/xlog.c:4600 +#, c-format +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "Veritabanı clusteri CATALOG_VERSION_NO %d ile ilklendirilmiştir, ancak sunucu CATALOG_VERSION_NO %d ile derlenmiştir." + +#: access/transam/xlog.c:4607 +#, c-format +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "Veritabanı clusteri MAXALIGN %d ile ilklendirilmiştir, ancak sunucu MAXALIGN %d ile derlenmiştir." + +#: access/transam/xlog.c:4614 +#, c-format +msgid "The database cluster appears to use a different floating-point number format than the server executable." +msgstr "Veritabanı dosyaları, sunucu programından farklı ondalık sayı biçimini kullanıyor." + +#: access/transam/xlog.c:4619 +#, c-format +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." +msgstr "Veritabanı clusteri BLCKSZ %d ile ilklendirilmiştir, ancak sunucu BLCKSZ %d ile derlenmiştir." + +#: access/transam/xlog.c:4622 access/transam/xlog.c:4629 access/transam/xlog.c:4636 access/transam/xlog.c:4643 access/transam/xlog.c:4650 access/transam/xlog.c:4657 access/transam/xlog.c:4664 access/transam/xlog.c:4672 access/transam/xlog.c:4679 access/transam/xlog.c:4688 access/transam/xlog.c:4695 +#, c-format +msgid "It looks like you need to recompile or initdb." +msgstr "Sistemi yeniden derlemeniz veya initdb çalıştırmanız gerekmetedir." + +#: access/transam/xlog.c:4626 +#, c-format +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "Veritabanı clusteri RELSEG_SIZE %d ile ilklendirilmiştir, ancak sunucu RELSEG_SIZE %d ile derlenmiştir." + +#: access/transam/xlog.c:4633 +#, c-format +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "Veritabanı clusteri XLOG_BLCKSZ %d ile ilklendirilmiştir, ancak sunucu XLOG_BLCKSZ %d ile derlenmiştir." + +#: access/transam/xlog.c:4640 +#, c-format +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "Veritabanı clusteri NAMEDATALEN %d ile ilklendirilmiştir, ancak sunucu NAMEDATALEN %d ile derlenmiştir." + +#: access/transam/xlog.c:4647 +#, c-format +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "Veritabanı clusteri INDEX_MAX_KEYS %d ile ilklendirilmiştir, ancak sunucu INDEX_MAX_KEYS %d ile derlenmiştir." + +#: access/transam/xlog.c:4654 +#, c-format +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "Veritabanı clusteri TOAST_MAX_CHUNK_SIZE %d ile ilklendirilmiştir, ancak sunucu TOAST_MAX_CHUNK_SIZE %d ile derlenmiştir." + +#: access/transam/xlog.c:4661 +#, c-format +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "Veritabanı clusteri LOBLKSIZE %d ile ilklendirilmiştir, ancak sunucu LOBLKSIZE %d ile derlenmiştir." + +#: access/transam/xlog.c:4670 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +msgstr "Veritabanı kümesi USE_FLOAT4_BYVAL'sız ilklendirilmemiştir, ancak sunucu USE_FLOAT4_BYVAL ile derlenmiştir." + +#: access/transam/xlog.c:4677 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +msgstr "Veritabanı clusteri USE_FLOAT4_BYVAL ile ilklendirilmiştir, ancak sunucu USE_FLOAT4_BYVAL'sız derlenmiştir." + +#: access/transam/xlog.c:4686 +#, c-format +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "Veritabanı clusteri USE_FLOAT8_BYVAL'sız ilklendirilmiştir, ancak sunucu USE_FLOAT8_BYVAL ile derlenmiştir." + +#: access/transam/xlog.c:4693 +#, c-format +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "Veritabanı clusteri USE_FLOAT8_BYVAL ile ilklendirilmiştir, ancak sunucu USE_FLOAT8_BYVAL'sız derlenmiştir." + +#: access/transam/xlog.c:4702 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir değer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir" +msgstr[1] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir değer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir" + +#: access/transam/xlog.c:4714 +#, c-format +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\" değeri \"wal_segment_size\" değerinin en az iki katı olmalıdır" + +#: access/transam/xlog.c:4718 +#, c-format +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\" değeri \"wal_segment_size\" değerinin en az iki katı olmalıdır" + +#: access/transam/xlog.c:5105 +#, c-format +msgid "could not generate secret authorization token" +msgstr "gizli authorization token üretilemedi" + +#: access/transam/xlog.c:5195 +#, c-format +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "bootstrap kayıt (write-ahead log) dosyasına yazılamadı: %m" + +#: access/transam/xlog.c:5203 +#, c-format +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "bootstrap kayıt (write-ahead log) dosyası fsync başarısız: %m" + +#: access/transam/xlog.c:5209 +#, c-format +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "bootstrap kayıt (write-ahead log) dosyası kapatılamadı: %m" + +#: access/transam/xlog.c:5291 +#, c-format +msgid "could not open recovery command file \"%s\": %m" +msgstr "recovery command dosyası \"%s\" açılamıyor: %m" + +#: access/transam/xlog.c:5337 access/transam/xlog.c:5451 +#, c-format +msgid "invalid value for recovery parameter \"%s\": \"%s\"" +msgstr "\"%s\" kurtarma parametresi için geçersiz değer: \"%s\"" + +#: access/transam/xlog.c:5340 +#, c-format +msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." +msgstr "Geçerli değerler: \"pause\", \"promote\", ve \"shutdown\"." + +#: access/transam/xlog.c:5360 +#, c-format +msgid "recovery_target_timeline is not a valid number: \"%s\"" +msgstr "recovery_target_timeline geçerli sayısal bir değer değildir: \"%s\"" + +#: access/transam/xlog.c:5377 +#, c-format +msgid "recovery_target_xid is not a valid number: \"%s\"" +msgstr "recovery_target_xid geçerli sayısal bir değer değildir: \"%s\"" + +#: access/transam/xlog.c:5397 +#, c-format +msgid "recovery_target_time is not a valid timestamp: \"%s\"" +msgstr "recovery_target_time geçerli bir zaman damgası değildir: \"%s\"" + +#: access/transam/xlog.c:5420 +#, c-format +msgid "recovery_target_name is too long (maximum %d characters)" +msgstr "çok uzun recovery_target_name değeri (azami %d karakter)" + +#: access/transam/xlog.c:5454 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "İzin verilen tek değer \"immediate\"dir." + +#: access/transam/xlog.c:5467 access/transam/xlog.c:5478 commands/extension.c:547 commands/extension.c:555 utils/misc/guc.c:5993 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "\"%s\" seçeneği boolean değerini alır" + +#: access/transam/xlog.c:5513 +#, c-format +msgid "parameter \"%s\" requires a temporal value" +msgstr "\"%s\" seçeneği temporal değeri alır" + +#: access/transam/xlog.c:5515 catalog/dependency.c:969 catalog/dependency.c:970 catalog/dependency.c:976 catalog/dependency.c:977 catalog/dependency.c:988 catalog/dependency.c:989 commands/tablecmds.c:1072 commands/tablecmds.c:11282 commands/user.c:1064 commands/view.c:509 libpq/auth.c:336 replication/syncrep.c:1162 storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1331 +#: utils/adt/acl.c:5344 utils/misc/guc.c:6015 utils/misc/guc.c:6108 utils/misc/guc.c:10098 utils/misc/guc.c:10132 utils/misc/guc.c:10166 utils/misc/guc.c:10200 utils/misc/guc.c:10235 +#, c-format +msgid "%s" +msgstr "%s" + +#: access/transam/xlog.c:5522 +#, c-format +msgid "unrecognized recovery parameter \"%s\"" +msgstr "\"%s\" tanınmayan recovery parametresi" + +#: access/transam/xlog.c:5533 +#, c-format +msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" +msgstr "\"%s\"recovery komut dosyasında ne primary_conninfo ne de restore_command değeri belirtilmiştir" + +#: access/transam/xlog.c:5535 +#, c-format +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "Veritabanı sunucusu yerleştirilen dosyaları kontrol etmek için pg_wal alt dizinini düzenli olarakyoklayacaktır (poll)." + +#: access/transam/xlog.c:5542 +#, c-format +msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" +msgstr "standby kipi etkinleştirilmediğinde \"%s\"recovery komut dosyasında restore_command değeri belirtilmelidir" + +#: access/transam/xlog.c:5563 +#, c-format +msgid "standby mode is not supported by single-user servers" +msgstr "tek-kullanıcılı (single-user) sunucularda standby kipi desteklenmemektedir" + +#: access/transam/xlog.c:5582 +#, c-format +msgid "recovery target timeline %u does not exist" +msgstr "recovery_target_timeline %u mevcut değil" + +#: access/transam/xlog.c:5703 +#, c-format +msgid "archive recovery complete" +msgstr "archive recovery tamamlandı" + +#: access/transam/xlog.c:5762 access/transam/xlog.c:6028 +#, c-format +msgid "recovery stopping after reaching consistency" +msgstr "kurtarma işlemi, tutarlı hale (consistency) erişilmesinden sonra duruyor" + +#: access/transam/xlog.c:5783 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "kurtarma işlemi , \"%X/%X\" WAL konumundan önce duruyor" + +#: access/transam/xlog.c:5869 +#, c-format +msgid "recovery stopping before commit of transaction %u, time %s" +msgstr "kurtarma işlemi %u transactionunun, %s zamanında commit edilmesinden önce durdu" + +#: access/transam/xlog.c:5876 +#, c-format +msgid "recovery stopping before abort of transaction %u, time %s" +msgstr "kurtarma işlemi %u transactionunun, %s zamanında iptal edilmesinden önce duruyor" + +#: access/transam/xlog.c:5922 +#, c-format +msgid "recovery stopping at restore point \"%s\", time %s" +msgstr "kurtarma işlemi, \"%s\" geri yükleme noktasında duruyor, zaman %s" + +#: access/transam/xlog.c:5940 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "kurtarma işlemi , \"%X/%X\" WAL konumundan sonra duruyor" + +#: access/transam/xlog.c:6008 +#, c-format +msgid "recovery stopping after commit of transaction %u, time %s" +msgstr "kurtarma işlemi %u transactionunun, %s zamanında commit edilmesinden sonra durdu" + +#: access/transam/xlog.c:6016 +#, c-format +msgid "recovery stopping after abort of transaction %u, time %s" +msgstr "kurtarma işlemi %u transactionunun, %s zamanında iptal edilmesinden sonra duruyor" + +#: access/transam/xlog.c:6056 +#, c-format +msgid "recovery has paused" +msgstr "kurtarma duraklatıldı" + +#: access/transam/xlog.c:6057 +#, c-format +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "Devam etmek için pg_wal_replay_resume() çalıştırınız." + +#: access/transam/xlog.c:6265 +#, c-format +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "%s = %d , ana sunucudakinden daha düşük bir ayar olduğundan (değeri %d idi) hot standby mümkün değildir." + +#: access/transam/xlog.c:6291 +#, c-format +msgid "WAL was generated with wal_level=minimal, data may be missing" +msgstr "WAL, wal_level=minimal ile üretildi, veri kaybı olmuş olabilir" + +#: access/transam/xlog.c:6292 +#, c-format +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "Bu, yeni bir \"base\" yedek almadan geçici olarak wal_level=minimal olarak değiştirirseniz gerçekleşir." + +#: access/transam/xlog.c:6303 +#, c-format +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "Ana sunucudaki wal_level seçeneği \"replica\" ya da daha üstü olarak ayarlanmadığı için hot standby devreye alınamaz." + +#: access/transam/xlog.c:6304 +#, c-format +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "Ya ana sunucuda (master) wal_level'ı \"replica\" ya ayarlayın, ya da burada hot_standby seçeneğini \"off\" yapın." + +#: access/transam/xlog.c:6356 +#, c-format +msgid "control file contains invalid data" +msgstr "kontrol dosyası geçersiz veri içeriyor" + +#: access/transam/xlog.c:6362 +#, c-format +msgid "database system was shut down at %s" +msgstr "veritabanı sunucusu %s tarihinde kapatıldı" + +#: access/transam/xlog.c:6367 +#, c-format +msgid "database system was shut down in recovery at %s" +msgstr "veritabanı sunucusu %s tarihinde kurtarma sırasında kapatıldı" + +#: access/transam/xlog.c:6371 +#, c-format +msgid "database system shutdown was interrupted; last known up at %s" +msgstr "veritabanı kapatma işlemi iptal edildi; bilinen en son çalışma zamanı %s" + +#: access/transam/xlog.c:6375 +#, c-format +msgid "database system was interrupted while in recovery at %s" +msgstr "%s'da recovery sırasında veritabanı sistemi durduruldu" + +#: access/transam/xlog.c:6377 +#, c-format +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." +msgstr "Büyük ihtimalle veri bozulmuştur, kurtarmak için en son yedeğinizi kullanın." + +#: access/transam/xlog.c:6381 +#, c-format +msgid "database system was interrupted while in recovery at log time %s" +msgstr "log time %s'da recovery sırasında veritabanı sistemi kesildi" + +#: access/transam/xlog.c:6383 +#, c-format +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "Bu hata birden fazla kere meydana geldiyse, veri bozulmuş olabilir. Bu durumda daha erken tarihli kurtarma hedefinini belirtmelisiniz." + +#: access/transam/xlog.c:6387 +#, c-format +msgid "database system was interrupted; last known up at %s" +msgstr "veritabanı sunucusu durdurulmuştur; bilinen en son çalışma zamanı %s" + +#: access/transam/xlog.c:6443 +#, c-format +msgid "entering standby mode" +msgstr "bekleme (standby) moduna giriyor" + +#: access/transam/xlog.c:6446 +#, c-format +msgid "starting point-in-time recovery to XID %u" +msgstr "%u XID'ye geri getirme (point-in-time recovery) başlatılıyor" + +#: access/transam/xlog.c:6450 +#, c-format +msgid "starting point-in-time recovery to %s" +msgstr "%s'ye geri getirme (point-in-time recovery) başlatılıyor" + +#: access/transam/xlog.c:6454 +#, c-format +msgid "starting point-in-time recovery to \"%s\"" +msgstr "\"%s\"e geri getirme (point-in-time recovery) başlatılıyor" + +#: access/transam/xlog.c:6458 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "WAL konumu (LSN) \"%X/%X\"e geri getirme (point-in-time recovery) başlatılıyor" + +#: access/transam/xlog.c:6463 +#, c-format +msgid "starting point-in-time recovery to earliest consistent point" +msgstr "en erken tutarlı noktaya geri getirme (point-in-time recovery) başlatılıyor" + +#: access/transam/xlog.c:6466 +#, c-format +msgid "starting archive recovery" +msgstr "arşivden geri getirme başlatılıyor" + +#: access/transam/xlog.c:6520 access/transam/xlog.c:6645 +#, c-format +msgid "checkpoint record is at %X/%X" +msgstr "checkpoint kaydı %X/%X noktasındadır" + +#: access/transam/xlog.c:6534 +#, c-format +msgid "could not find redo location referenced by checkpoint record" +msgstr "checkpoint kaydının gösterdiği redo konumu bulunamadı" + +#: access/transam/xlog.c:6535 access/transam/xlog.c:6542 +#, c-format +msgid "If you are not restoring from a backup, try removing the file \"%s/backup_label\"." +msgstr "Yedekten geri almıyorsanız, \"%s/backup_label\" dosyasını silmeyi deneyin." + +#: access/transam/xlog.c:6541 +#, c-format +msgid "could not locate required checkpoint record" +msgstr "istenilen checkpoint kaydı bulunamadı" + +#: access/transam/xlog.c:6567 commands/tablespace.c:641 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" oluşturma hatası: %m" + +#: access/transam/xlog.c:6599 access/transam/xlog.c:6605 +#, c-format +msgid "ignoring file \"%s\" because no file \"%s\" exists" +msgstr "\"%s\" diye ir dosya dosyası bulunmadığından \"%s\" dosyası yok sayılıyor" + +#: access/transam/xlog.c:6601 access/transam/xlog.c:11621 +#, c-format +msgid "File \"%s\" was renamed to \"%s\"." +msgstr "\"%s\" dosyası \"%s\" olarak yeniden adlandırıldı." + +#: access/transam/xlog.c:6607 +#, c-format +msgid "Could not rename file \"%s\" to \"%s\": %m." +msgstr "\"%s\" den \"%s\" e ad değiştirme hatası: %m." + +#: access/transam/xlog.c:6657 +#, c-format +msgid "could not locate a valid checkpoint record" +msgstr "geçerli checkpoint kaydı bulunamıyor" + +#: access/transam/xlog.c:6695 +#, c-format +msgid "requested timeline %u is not a child of this server's history" +msgstr "talep edilmiş timeline %u bu sunucunun geçmişi (history) için geçerli bir alt (child) timeline değildir" + +#: access/transam/xlog.c:6697 +#, c-format +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "En son checkpoint %X/%X 'tedir (%u zaman-çizelgesinde (timeline)), fakat talep edilen zaman çizelgesinin geçmişinde, sunucu o zaman çizelgesinden %X/%X 'te çatallanmıştır." + +#: access/transam/xlog.c:6713 +#, c-format +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" +msgstr "talep edilmiş %u zaman çizelgesi %X/%X asgari kurtarma noktasını içermiyor (%u zaman-çizelgesinde)" + +#: access/transam/xlog.c:6744 +#, c-format +msgid "invalid next transaction ID" +msgstr "sıradaki transaction ID geçersiz" + +#: access/transam/xlog.c:6839 +#, c-format +msgid "invalid redo in checkpoint record" +msgstr "checkpoint kaydındaki redo geçersizdir" + +#: access/transam/xlog.c:6850 +#, c-format +msgid "invalid redo record in shutdown checkpoint" +msgstr "shutdown checkpointteki redo kaydı geçersizdir" + +#: access/transam/xlog.c:6878 +#, c-format +msgid "database system was not properly shut down; automatic recovery in progress" +msgstr "veritabanı düzgün kapatılmamış; otomatik kurtarma işlemi sürüyor" + +#: access/transam/xlog.c:6882 +#, c-format +msgid "crash recovery starts in timeline %u and has target timeline %u" +msgstr "çökmeden kurtarma %u zaman çizelgesinde başlar ve %u hedef zaman çizelgesi vardır." + +#: access/transam/xlog.c:6925 +#, c-format +msgid "backup_label contains data inconsistent with control file" +msgstr "backup_label kontrol dosyası ile tutarsız veri içeriyor" + +#: access/transam/xlog.c:6926 +#, c-format +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." +msgstr "Bu, yedek dosyasının bozuk olduğu anlamına gelir ve kurtarma için başka bir yedek kullanmalısınız." + +#: access/transam/xlog.c:7017 +#, c-format +msgid "initializing for hot standby" +msgstr "hot standby için ilklendiriyor" + +#: access/transam/xlog.c:7149 +#, c-format +msgid "redo starts at %X/%X" +msgstr "redo başlangıcı %X/%X" + +#: access/transam/xlog.c:7383 +#, c-format +msgid "requested recovery stop point is before consistent recovery point" +msgstr "talep edilen kurtarma durma noktası tutarlı (consistent) kurtarma noktasından öncedir" + +#: access/transam/xlog.c:7421 +#, c-format +msgid "redo done at %X/%X" +msgstr "redo bitişi %X/%X" + +#: access/transam/xlog.c:7426 +#, c-format +msgid "last completed transaction was at log time %s" +msgstr "son tamamlanan transaction %s kayıt zamanındaydı" + +#: access/transam/xlog.c:7435 +#, c-format +msgid "redo is not required" +msgstr "redo işlemi gerekmiyor" + +#: access/transam/xlog.c:7510 access/transam/xlog.c:7514 +#, c-format +msgid "WAL ends before end of online backup" +msgstr "WAL, online yedeğin bitişinden önce sona eriyor" + +#: access/transam/xlog.c:7511 +#, c-format +msgid "All WAL generated while online backup was taken must be available at recovery." +msgstr "Online backup sırasında oluşmuş olan tüm WAL kurtarma sırasında hazır olmalıdır." + +#: access/transam/xlog.c:7515 +#, c-format +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "pg_start_backup() ile başlamış olan online yedek pg_stop_backup() ile bitirilmelidir, ve bu ana kadarki bütün WAL kurtarma sırasında hazır olmalıdır." + +#: access/transam/xlog.c:7518 +#, c-format +msgid "WAL ends before consistent recovery point" +msgstr "WAL tutarlı kurtarma noktasından önce sona ermektedir." + +#: access/transam/xlog.c:7552 +#, c-format +msgid "selected new timeline ID: %u" +msgstr "seçili yeni timeline ID: %u" + +#: access/transam/xlog.c:7989 +#, c-format +msgid "consistent recovery state reached at %X/%X" +msgstr "%X/%X 'de tutarlı kurtarma haline ulaşılmıştır" + +#: access/transam/xlog.c:8181 +#, c-format +msgid "invalid primary checkpoint link in control file" +msgstr "kontrol dosyasındaki ana checkpoint bağlantısı geçersiz" + +#: access/transam/xlog.c:8185 +#, c-format +msgid "invalid checkpoint link in backup_label file" +msgstr "backup_label dosyasındaki checkpoint linki geçersiz" + +#: access/transam/xlog.c:8202 +#, c-format +msgid "invalid primary checkpoint record" +msgstr "birincil checkpoint kaydı geçersiz" + +#: access/transam/xlog.c:8206 +#, c-format +msgid "invalid checkpoint record" +msgstr "geçersiz checkpoint kaydı" + +#: access/transam/xlog.c:8217 +#, c-format +msgid "invalid resource manager ID in primary checkpoint record" +msgstr "birincil checkpoint kaydındaki resource manager ID geçersiz" + +#: access/transam/xlog.c:8221 +#, c-format +msgid "invalid resource manager ID in checkpoint record" +msgstr "checkpoint kaydındaki resource manager ID geçersiz" + +#: access/transam/xlog.c:8234 +#, c-format +msgid "invalid xl_info in primary checkpoint record" +msgstr "primary checkpoint kaydındaki xl_info geçersiz" + +#: access/transam/xlog.c:8238 +#, c-format +msgid "invalid xl_info in checkpoint record" +msgstr "checkpoint kaydındaki xl_info geçersiz" + +#: access/transam/xlog.c:8249 +#, c-format +msgid "invalid length of primary checkpoint record" +msgstr "birincil checkpoint kaydının uzunluğu geçersiz" + +#: access/transam/xlog.c:8253 +#, c-format +msgid "invalid length of checkpoint record" +msgstr "checkpoint kaydın uzunluğu geçersiz" + +#: access/transam/xlog.c:8459 +#, c-format +msgid "shutting down" +msgstr "kapanıyor" + +#: access/transam/xlog.c:8779 +#, c-format +msgid "checkpoint skipped because system is idle" +msgstr "sistem boşta olduğundan checkpoint atlandı" + +#: access/transam/xlog.c:8984 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "veritabanının kapanması sırasında eşzamanlı kayıt (write-ahead log) hareketi" + +#: access/transam/xlog.c:9241 +#, c-format +msgid "skipping restartpoint, recovery has already ended" +msgstr "restartpoint (yeniden başlama noktası) atlanıyor, kurtarma zaten sona erdi" + +#: access/transam/xlog.c:9264 +#, c-format +msgid "skipping restartpoint, already performed at %X/%X" +msgstr "restartpoint (yeniden başlama noktası) atlanıyor, %X/%X de zaten gerçekleştirildi" + +#: access/transam/xlog.c:9431 +#, c-format +msgid "recovery restart point at %X/%X" +msgstr "kurtarma yeniden başlangıç noktası: %X/%X" + +#: access/transam/xlog.c:9433 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "Son tamamlanan transaction %s kayıt zamanındaydı." + +#: access/transam/xlog.c:9567 +#, c-format +msgid "restore point \"%s\" created at %X/%X" +msgstr "\"%s\" kurtarma noktası (restore point) %X/%X de oluşturumuş" + +#: access/transam/xlog.c:9705 +#, c-format +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" +msgstr "checkpoint kaydındaki beklenmeyen zaman çizelgesi ID %u (şimdiki zaman çizelgesi ID si %u)" + +#: access/transam/xlog.c:9714 +#, c-format +msgid "unexpected timeline ID %u (after %u) in checkpoint record" +msgstr "checkpoint kaydındaki beklenmeyen timeline ID %u (%u'dan sonra)" + +#: access/transam/xlog.c:9730 +#, c-format +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "checkpoint kaydındaki beklenmeyen zaman çizelgesi ID'si %u, asgari kurtarma noktası %X/%X'e varmadan önce (%u zaman çizelgesinde)" + +#: access/transam/xlog.c:9806 +#, c-format +msgid "online backup was canceled, recovery cannot continue" +msgstr "çevrimiçi yedek iptal edildi, kurtarma devam edemiyor" + +#: access/transam/xlog.c:9862 access/transam/xlog.c:9918 access/transam/xlog.c:9941 +#, c-format +msgid "unexpected timeline ID %u (should be %u) in checkpoint record" +msgstr "checkpoint kaydındaki beklenmeyen timeline ID %u (%u olmalıydı)" + +#: access/transam/xlog.c:10222 +#, c-format +msgid "could not fsync log segment %s: %m" +msgstr "%s log segmenti, fsync yapılamıyor: %m" + +#: access/transam/xlog.c:10247 +#, c-format +msgid "could not fsync log file %s: %m" +msgstr "%s dosyası fsync hatası: %m" + +#: access/transam/xlog.c:10255 +#, c-format +msgid "could not fsync write-through log file %s: %m" +msgstr "write-through log dosyası %s, fsync yapılamıyor: %m" + +#: access/transam/xlog.c:10264 +#, c-format +msgid "could not fdatasync log file %s: %m" +msgstr "kayıt dosyası %s, fdatasync yapılamıyor: %m" + +#: access/transam/xlog.c:10355 access/transam/xlog.c:10882 access/transam/xlogfuncs.c:287 access/transam/xlogfuncs.c:314 access/transam/xlogfuncs.c:353 access/transam/xlogfuncs.c:374 access/transam/xlogfuncs.c:395 +#, c-format +msgid "WAL control functions cannot be executed during recovery." +msgstr "WAL kontrol fonksiyonları kurtarma sırasında çalıştırılamaz." + +#: access/transam/xlog.c:10364 access/transam/xlog.c:10891 +#, c-format +msgid "WAL level not sufficient for making an online backup" +msgstr "WAL seviyesi online yedek almak için yeterli değil" + +#: access/transam/xlog.c:10365 access/transam/xlog.c:10892 access/transam/xlogfuncs.c:320 +#, c-format +msgid "wal_level must be set to \"replica\" or \"logical\" at server start." +msgstr "sunucu başlangıcında wal_level \"replica\" ya da \"logical\" olarak ayarlanmalı." + +#: access/transam/xlog.c:10370 +#, c-format +msgid "backup label too long (max %d bytes)" +msgstr "yedek etiketi çok uzun (en fazla %d bayt)" + +#: access/transam/xlog.c:10407 access/transam/xlog.c:10683 access/transam/xlog.c:10721 +#, c-format +msgid "a backup is already in progress" +msgstr "bir backup işlemi zaten aktif" + +#: access/transam/xlog.c:10408 +#, c-format +msgid "Run pg_stop_backup() and try again." +msgstr "pg_stop_backup() çalıştırıp yeniden deneyin." + +#: access/transam/xlog.c:10504 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" +msgstr "full-page_writes=off ile oluşturulan WAL, son başlatma (restart) noktasından beri oynatıldı" + +#: access/transam/xlog.c:10506 access/transam/xlog.c:11087 +#, c-format +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "Bu, standby sunucudan alınan yedeğin bozulduğu ve kullanılmaması gerektiği anlamına gelir. full_page_writes'ı etkinleştirin ve master sunucu üzerinde CHECKPOINT çalıştırın, sonra tekrar bir çevrimiçi yedek almayı deneyin." + +#: access/transam/xlog.c:10574 replication/basebackup.c:1232 utils/adt/misc.c:517 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" okuma hatası: %m" + +#: access/transam/xlog.c:10581 replication/basebackup.c:1237 utils/adt/misc.c:522 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "symbolic link \"%s\" hedefi çok uzun" + +#: access/transam/xlog.c:10633 commands/tablespace.c:391 commands/tablespace.c:553 replication/basebackup.c:1252 utils/adt/misc.c:530 +#, c-format +msgid "tablespaces are not supported on this platform" +msgstr "bu platformda tablespace desteklenmiyor" + +#: access/transam/xlog.c:10677 access/transam/xlog.c:10715 access/transam/xlog.c:10930 access/transam/xlogarchive.c:104 access/transam/xlogarchive.c:264 commands/copy.c:1890 commands/copy.c:3206 commands/extension.c:3326 commands/tablespace.c:782 commands/tablespace.c:873 guc-file.l:1004 replication/basebackup.c:523 replication/basebackup.c:593 replication/logical/snapbuild.c:1525 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1733 storage/file/fd.c:3113 storage/file/fd.c:3295 storage/file/fd.c:3380 utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 utils/adt/genfile.c:131 utils/adt/genfile.c:382 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" dosyası durumlanamadı: %m" + +#: access/transam/xlog.c:10684 access/transam/xlog.c:10722 +#, c-format +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." +msgstr "Eğer bir backup sürecinin şu an çalışmadığından eminseniz, \"%s\" dosyasını kaldırın ve yeniden deneyin." + +#: access/transam/xlog.c:10701 access/transam/xlog.c:10739 access/transam/xlog.c:11150 postmaster/syslogger.c:1476 postmaster/syslogger.c:1489 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" dosyasına yazma hatası: %m" + +#: access/transam/xlog.c:10907 +#, c-format +msgid "exclusive backup not in progress" +msgstr "şu an exclusive backup süreci çalışmıyor" + +#: access/transam/xlog.c:10934 +#, c-format +msgid "a backup is not in progress" +msgstr "şu an backup süreci çalışmıyor" + +#: access/transam/xlog.c:11020 access/transam/xlog.c:11033 access/transam/xlog.c:11394 access/transam/xlog.c:11400 access/transam/xlog.c:11448 access/transam/xlog.c:11521 access/transam/xlogfuncs.c:688 +#, c-format +msgid "invalid data in file \"%s\"" +msgstr "\"%s\" dosyasında geçersiz veri" + +#: access/transam/xlog.c:11037 replication/basebackup.c:1089 +#, c-format +msgid "the standby was promoted during online backup" +msgstr "standby, online backup sırasında promote edildi" + +#: access/transam/xlog.c:11038 replication/basebackup.c:1090 +#, c-format +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." +msgstr "Bu, alınan yedeğin bozuk olduğu ve kullanılmaması gerektiği anlamına gelir. Başka bir oline yedek alın." + +#: access/transam/xlog.c:11085 +#, c-format +msgid "WAL generated with full_page_writes=off was replayed during online backup" +msgstr "full_page_writes=off ile oluşturulan WAL, çevrimiçi yedek sırasında oynatıldı" + +#: access/transam/xlog.c:11205 +#, c-format +msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" +msgstr "pg_stop_backup temizliği yapıldı, gereken WAL segmentlerinin arşivlenmesi bekleniyor." + +#: access/transam/xlog.c:11215 +#, c-format +msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgstr "pg_stop_backup hala gereken tüm WAL segmentlerinin arşivlenmesinin bitmesini bekliyor (%d saniyedir devam ediyor)" + +#: access/transam/xlog.c:11217 +#, c-format +msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." +msgstr "archive_comand'in düzgün çalıştığını kontrol ediniz. pg_stop_backup güvenli bir şekilde iptal eilebiliyor, fakat veritabanı yedeği tüm WAL segmentleri olmadan kullanılamaz." + +#: access/transam/xlog.c:11224 +#, c-format +msgid "pg_stop_backup complete, all required WAL segments have been archived" +msgstr "pg_stop_bakup tamamlandı, gerekli tüm WAl segmentleri arşivlendi" + +#: access/transam/xlog.c:11228 +#, c-format +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "WAL arşivlemesi etkileştirilmemiş; yedeğin tamamlanması için gerekli tüm WAL segmentlerinin diğer yollarla kopyalandığından emin olun" + +#: access/transam/xlog.c:11431 +#, c-format +msgid "backup time %s in file \"%s\"" +msgstr "\"%2$s\" dosyasında yedek zamanı %1$s" + +#: access/transam/xlog.c:11436 +#, c-format +msgid "backup label %s in file \"%s\"" +msgstr "\"%2$s\" dosyasında yedek etiketi %1$s" + +#: access/transam/xlog.c:11449 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "Çözümlenen zaman çizelgesi (timeline) ID değeri %u, beklenen ise %u" + +#: access/transam/xlog.c:11453 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "\"%2$s\" dosyasında yedek zaman çizelgesi (timeline) %1$u" + +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11561 +#, c-format +msgid "WAL redo at %X/%X for %s" +msgstr "%X/%X 'de %s için WAL redo" + +#: access/transam/xlog.c:11610 +#, c-format +msgid "online backup mode was not canceled" +msgstr "çevrimiçi yedek modu iptal edilmedi" + +#: access/transam/xlog.c:11611 +#, c-format +msgid "File \"%s\" could not be renamed to \"%s\": %m." +msgstr "\"%s\" den \"%s\" e ad değiştirme hatası: %m" + +#: access/transam/xlog.c:11620 access/transam/xlog.c:11632 access/transam/xlog.c:11642 +#, c-format +msgid "online backup mode canceled" +msgstr "çevrimiçi yedekleme modu iptal edildi" + +#: access/transam/xlog.c:11633 +#, c-format +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgstr "\"%s\" ve \"%s\" dosyalarının isimleri sırasıyla \"%s\" ve \"%s\" olarak değiştirildi." + +#: access/transam/xlog.c:11643 +#, c-format +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." +msgstr "\"%s\" dosya adı \"%s\" olarak değiştirildi, fakat \"%s\" dosya adı \"%s\" olarak değiştirilemedi: %m." + +#: access/transam/xlog.c:11769 access/transam/xlogutils.c:727 replication/walreceiver.c:1019 replication/walsender.c:2424 +#, c-format +msgid "could not seek in log segment %s to offset %u: %m" +msgstr "kayıt dosyası %s, offset %u imleç ilerleme hatası: %m" + +#: access/transam/xlog.c:11785 +#, c-format +msgid "could not read from log segment %s, offset %u: %m" +msgstr "log segment'i %s, offset %u okuma başarısız: %m" + +#: access/transam/xlog.c:12314 +#, c-format +msgid "received promote request" +msgstr "terfi (promote) isteği alındı" + +#: access/transam/xlog.c:12327 +#, c-format +msgid "trigger file found: %s" +msgstr "trigger dosyası bulundu: %s" + +#: access/transam/xlog.c:12336 +#, c-format +msgid "could not stat trigger file \"%s\": %m" +msgstr "\"%s\" dosyası durumlanamadı (stat): %m" + +#: access/transam/xlogarchive.c:243 +#, c-format +msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgstr "\"%s\" arşiv dosyası yanlış boyuta sahip: %lu yerine %lu olmalıydı." + +#: access/transam/xlogarchive.c:252 +#, c-format +msgid "restored log file \"%s\" from archive" +msgstr "\"%s\" log dosyası arşivden geri yüklendi" + +#: access/transam/xlogarchive.c:297 +#, c-format +msgid "could not restore file \"%s\" from archive: %s" +msgstr "\"%s\" dosyası arşivden geri yüklenemiyor: %s" + +#. translator: First %s represents a recovery.conf parameter name like +#. "recovery_end_command", the 2nd is the value of that parameter, the +#. third an already translated error message. +#: access/transam/xlogarchive.c:406 +#, c-format +msgid "%s \"%s\": %s" +msgstr "%s \"%s\": %s" + +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1500 replication/logical/snapbuild.c:1663 replication/slot.c:598 replication/slot.c:1211 replication/slot.c:1326 storage/file/fd.c:650 storage/file/fd.c:745 utils/time/snapmgr.c:1318 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" -- \"%s\" ad değiştirme hatası: %m" + +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 +#, c-format +msgid "could not create archive status file \"%s\": %m" +msgstr "\"%s\" arşiv durum dosyası oluşturulamadı: %m" + +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 +#, c-format +msgid "could not write archive status file \"%s\": %m" +msgstr "\"%s\" arşiv durum dosyası yazılamadı: %m" + +#: access/transam/xlogfuncs.c:54 +#, c-format +msgid "aborting backup due to backend exiting before pg_stop_backup was called" +msgstr "pg_stop_backup çağrılmadan önce backend süreci sona erdiğinden yedekleme durduruluyor" + +#: access/transam/xlogfuncs.c:84 +#, c-format +msgid "a backup is already in progress in this session" +msgstr "bu oturumda (session) bir backup işlemi zaten aktif" + +#: access/transam/xlogfuncs.c:142 access/transam/xlogfuncs.c:224 +#, c-format +msgid "non-exclusive backup in progress" +msgstr "non-exclusive backup devam etmekte" + +#: access/transam/xlogfuncs.c:143 access/transam/xlogfuncs.c:225 +#, c-format +msgid "Did you mean to use pg_stop_backup('f')?" +msgstr "Kullanmak istediğiniz pg_stop_backup('f') mıdır?" + +#: access/transam/xlogfuncs.c:195 commands/event_trigger.c:1464 commands/event_trigger.c:2016 commands/extension.c:1902 commands/extension.c:2011 commands/extension.c:2235 commands/prepare.c:722 executor/execExpr.c:2209 executor/execSRF.c:715 executor/functions.c:1034 foreign/foreign.c:488 libpq/hba.c:2603 replication/logical/launcher.c:1127 replication/logical/logicalfuncs.c:176 +#: replication/logical/origin.c:1460 replication/slotfuncs.c:200 replication/walsender.c:3203 utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:457 utils/adt/pgstatfuncs.c:558 utils/fmgr/funcapi.c:62 utils/misc/guc.c:8829 utils/mmgr/portalmem.c:1134 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "set değerini kabul etmediği ortamda set değeri alan fonksiyon çağırılmış" + +#: access/transam/xlogfuncs.c:199 commands/event_trigger.c:1468 commands/event_trigger.c:2020 commands/extension.c:1906 commands/extension.c:2015 commands/extension.c:2239 commands/prepare.c:726 foreign/foreign.c:493 libpq/hba.c:2607 replication/logical/launcher.c:1131 replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1464 replication/slotfuncs.c:204 +#: replication/walsender.c:3207 utils/adt/pgstatfuncs.c:461 utils/adt/pgstatfuncs.c:562 utils/misc/guc.c:8833 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 +#, c-format +msgid "materialize mode required, but it is not allowed in this context" +msgstr "materialize mode gerekir ancak bu bağlamda kullanılamaz" + +#: access/transam/xlogfuncs.c:241 +#, c-format +msgid "non-exclusive backup is not in progress" +msgstr "non-exclusive backup süreci çalışmıyor" + +#: access/transam/xlogfuncs.c:242 +#, c-format +msgid "Did you mean to use pg_stop_backup('t')?" +msgstr "Kullanmak istediğiniz pg_stop_backup('t') mıdır?" + +#: access/transam/xlogfuncs.c:319 +#, c-format +msgid "WAL level not sufficient for creating a restore point" +msgstr "WAL seviyesi, bir geri yükleme noktası (restore point) oluşturmak için yeterli değil" + +#: access/transam/xlogfuncs.c:327 +#, c-format +msgid "value too long for restore point (maximum %d characters)" +msgstr "geri yükleme noktası (restore point) için değer çok uzun (azami %d karakter)" + +#: access/transam/xlogfuncs.c:465 +#, c-format +msgid "pg_walfile_name_offset() cannot be executed during recovery." +msgstr "pg_walfile_name_offset() kurtarma aşamasında çalıştırılamaz." + +#: access/transam/xlogfuncs.c:521 +#, c-format +msgid "pg_walfile_name() cannot be executed during recovery." +msgstr "pg_walfile_name() kurtarma aşamasında çalıştırılamaz." + +#: access/transam/xlogfuncs.c:541 access/transam/xlogfuncs.c:561 access/transam/xlogfuncs.c:578 +#, c-format +msgid "recovery is not in progress" +msgstr "kurtarma devam etmiyor" + +#: access/transam/xlogfuncs.c:542 access/transam/xlogfuncs.c:562 access/transam/xlogfuncs.c:579 +#, c-format +msgid "Recovery control functions can only be executed during recovery." +msgstr "Kurtarma kontrol fonksiyonları sadece kurtarma sırasında çalıştırılabilirler." + +#: access/transam/xlogreader.c:299 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%X adresinde geçersiz kayıt offseti" + +#: access/transam/xlogreader.c:307 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord %X/%X tarafından talep edilmiştir" + +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:646 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%X adresinde geçersiz kayıt uzunluğu: istenen %u, alınan %u" + +#: access/transam/xlogreader.c:363 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$X adresinde çok büyük kayıt uzunluğu: %1$u " + +#: access/transam/xlogreader.c:404 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%X de contrecord bayrağı (flag) bulunmuyor" + +#: access/transam/xlogreader.c:417 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "%X/%X adresinde geçersiz %u contrecord uzunluğu" + +#: access/transam/xlogreader.c:654 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$X adresinde geçersiz resource manager ID %1$u" + +#: access/transam/xlogreader.c:668 access/transam/xlogreader.c:685 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "geçersiz incorrect prev-link olan kayıt: %X/%X at %X/%X" + +#: access/transam/xlogreader.c:722 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "resoource manager data checksum %X/%X kaydında geçersiz" + +#: access/transam/xlogreader.c:759 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "%04X geçersiz tanııtım kodu; %s kayıt segmentinde, offset %u" + +#: access/transam/xlogreader.c:773 access/transam/xlogreader.c:824 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "%04X geçersiz info bits; %s kayıt segmentinde, offset %u" + +#: access/transam/xlogreader.c:799 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL dosyası farklı veritabanı sisteminden: WAL dosya veritabanı sistem tanımlayıcı %s, pg_control veritabanı sistem tanımlayıcı %s" + +#: access/transam/xlogreader.c:806 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış segment boyutu değeri" + +#: access/transam/xlogreader.c:812 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış XLOG_BLCKSZ değeri" + +#: access/transam/xlogreader.c:843 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "beklenmeyen pageaddr %X/%X: log segmenti %s, offset %u" + +#: access/transam/xlogreader.c:868 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "sıra dışı timeline ID %u (%u'dan sonra), bulunduğu log segmenti %s, offset %u" + +#: access/transam/xlogreader.c:1113 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "%X/%X deki %u block_id değeri bozuk" + +#: access/transam/xlogreader.c:1136 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ayarlandı, fakat %X/%X de veri yok" + +#: access/transam/xlogreader.c:1143 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ayarlanmadı, fakat veri uzunluğu %u (%X/%x de)" + +#: access/transam/xlogreader.c:1179 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ayarlandı, fakat hole offset %u uzunluk %u blok image uzunluğu %u (%X/%X de)" + +#: access/transam/xlogreader.c:1195 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ayarlanmadı, fakat hole offset %u uzunluk %u (%X/%X de)" + +#: access/transam/xlogreader.c:1210 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED ayarlandı, fakat block image uzunluğu %u (%X/%X de)" + +#: access/transam/xlogreader.c:1225 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ve BKPIMAGE_IS_COMPRESSED ayarlanmadı, fakat block image uzunluğu %u (%X/%X de)" + +#: access/transam/xlogreader.c:1241 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL ayarlandı fakat %X/%X de önceki rel yok" + +#: access/transam/xlogreader.c:1253 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%X/%X adresinde %u block_id geçersiz" + +#: access/transam/xlogreader.c:1342 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%X adresinde geçersiz uzunlukta kayıt" + +#: access/transam/xlogreader.c:1431 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%X adresinde (blok %d), geçersiz compressed image" + +#: access/transam/xlogutils.c:751 replication/walsender.c:2443 +#, c-format +msgid "could not read from log segment %s, offset %u, length %lu: %m" +msgstr "log segmenti %s, offset %u, uzunluk %lu okuma hatası: %m" + +#: bootstrap/bootstrap.c:268 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X 1MB ve 1GB arasında 2 nin üsü bir değer gerektirmektedir" + +#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:826 tcop/postgres.c:3581 +#, c-format +msgid "--%s requires a value" +msgstr "--%s bir değer gerektirir" + +#: bootstrap/bootstrap.c:290 postmaster/postmaster.c:831 tcop/postgres.c:3586 +#, c-format +msgid "-c %s requires a value" +msgstr "-c %s bir değer gerektirir" + +#: bootstrap/bootstrap.c:301 postmaster/postmaster.c:843 postmaster/postmaster.c:856 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: bootstrap/bootstrap.c:310 +#, c-format +msgid "%s: invalid command-line arguments\n" +msgstr "%s: geçersiz komut satırı parametresi\n" + +#: catalog/aclchk.c:203 +#, c-format +msgid "grant options can only be granted to roles" +msgstr "grant opsiyonu, sadece rollere atanabilir" + +#: catalog/aclchk.c:326 +#, c-format +msgid "no privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "\"%2s\" nesnesinin \"%1s\" sütunu için hiçbir hak verilemedi" + +#: catalog/aclchk.c:331 +#, c-format +msgid "no privileges were granted for \"%s\"" +msgstr "\"%s\" nesnesine hiçbir hak verilemedi" + +#: catalog/aclchk.c:339 +#, c-format +msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" +msgstr "\"%2s\" nesnesinin \"%s\" sütununa bazı haklar verilemedi" + +#: catalog/aclchk.c:344 +#, c-format +msgid "not all privileges were granted for \"%s\"" +msgstr "\"%s\" nesnesine bazı hakları verilemedi" + +#: catalog/aclchk.c:355 +#, c-format +msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "\"%2s\" nesnesinin \"%1s\" sütunundan hiçbir hakkı geri alınamadı" + +#: catalog/aclchk.c:360 +#, c-format +msgid "no privileges could be revoked for \"%s\"" +msgstr "\"%s\" nesnesinin hiçbir hakkı geri alınamadı" + +#: catalog/aclchk.c:368 +#, c-format +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunundan bazı hakları geri alınamadı" + +#: catalog/aclchk.c:373 +#, c-format +msgid "not all privileges could be revoked for \"%s\"" +msgstr "\"%s\" nesnesinin bazı hakları geri alınamadı" + +#: catalog/aclchk.c:456 catalog/aclchk.c:995 +#, c-format +msgid "invalid privilege type %s for relation" +msgstr "nesne için geçersiz hak tipi %s" + +#: catalog/aclchk.c:460 catalog/aclchk.c:999 +#, c-format +msgid "invalid privilege type %s for sequence" +msgstr "sequence için geçersiz hak tipi %s" + +#: catalog/aclchk.c:464 +#, c-format +msgid "invalid privilege type %s for database" +msgstr "veritabanı için geçersiz hak tipi %s" + +#: catalog/aclchk.c:468 +#, c-format +msgid "invalid privilege type %s for domain" +msgstr "domain için geçersiz hak tipi %s" + +#: catalog/aclchk.c:472 catalog/aclchk.c:1003 +#, c-format +msgid "invalid privilege type %s for function" +msgstr "fonksiyon için geçersiz hak tipi %s" + +#: catalog/aclchk.c:476 +#, c-format +msgid "invalid privilege type %s for language" +msgstr "dil için geçersiz hak tipi %s" + +#: catalog/aclchk.c:480 +#, c-format +msgid "invalid privilege type %s for large object" +msgstr "büyük nesne (large object) için geçersiz hak tipi %s" + +#: catalog/aclchk.c:484 catalog/aclchk.c:1019 +#, c-format +msgid "invalid privilege type %s for schema" +msgstr "şema için geçersiz hak tipi %s" + +#: catalog/aclchk.c:488 catalog/aclchk.c:1007 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "procedure için geçersiz hak tipi %s" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "routine için geçersiz hak tipi %s" + +#: catalog/aclchk.c:496 +#, c-format +msgid "invalid privilege type %s for tablespace" +msgstr "tablespace için geçersiz hak tipi %s" + +#: catalog/aclchk.c:500 catalog/aclchk.c:1015 +#, c-format +msgid "invalid privilege type %s for type" +msgstr "tip (type) için geçersiz hak tipi %s" + +#: catalog/aclchk.c:504 +#, c-format +msgid "invalid privilege type %s for foreign-data wrapper" +msgstr "foreign-data-wrapper için geçersiz hak tipi %s" + +#: catalog/aclchk.c:508 +#, c-format +msgid "invalid privilege type %s for foreign server" +msgstr "uzak (foreign) sunucu için geçersiz hak tipi %s" + +#: catalog/aclchk.c:547 +#, c-format +msgid "column privileges are only valid for relations" +msgstr "sütun hakları sadece nesneler (relation) için geçerlidir" + +#: catalog/aclchk.c:707 catalog/aclchk.c:4131 catalog/aclchk.c:4913 catalog/objectaddress.c:928 catalog/pg_largeobject.c:111 storage/large_object/inv_api.c:284 +#, c-format +msgid "large object %u does not exist" +msgstr "large object %u mevcut değil" + +#: catalog/aclchk.c:932 catalog/aclchk.c:941 commands/collationcmds.c:113 commands/copy.c:1063 commands/copy.c:1083 commands/copy.c:1092 commands/copy.c:1101 commands/copy.c:1110 commands/copy.c:1119 commands/copy.c:1128 commands/copy.c:1137 commands/copy.c:1146 commands/copy.c:1164 commands/copy.c:1180 commands/copy.c:1200 commands/copy.c:1217 commands/dbcommands.c:155 +#: commands/dbcommands.c:164 commands/dbcommands.c:173 commands/dbcommands.c:182 commands/dbcommands.c:191 commands/dbcommands.c:200 commands/dbcommands.c:209 commands/dbcommands.c:218 commands/dbcommands.c:227 commands/dbcommands.c:1427 commands/dbcommands.c:1436 commands/dbcommands.c:1445 commands/dbcommands.c:1454 commands/extension.c:1685 commands/extension.c:1695 +#: commands/extension.c:1705 commands/extension.c:1715 commands/extension.c:2956 commands/foreigncmds.c:537 commands/foreigncmds.c:546 commands/functioncmds.c:559 commands/functioncmds.c:684 commands/functioncmds.c:693 commands/functioncmds.c:702 commands/functioncmds.c:711 commands/functioncmds.c:2105 commands/functioncmds.c:2113 commands/publicationcmds.c:92 commands/sequence.c:1255 +#: commands/sequence.c:1265 commands/sequence.c:1275 commands/sequence.c:1285 commands/sequence.c:1295 commands/sequence.c:1305 commands/sequence.c:1315 commands/sequence.c:1325 commands/sequence.c:1335 commands/subscriptioncmds.c:110 commands/subscriptioncmds.c:120 commands/subscriptioncmds.c:130 commands/subscriptioncmds.c:140 commands/subscriptioncmds.c:154 +#: commands/subscriptioncmds.c:165 commands/subscriptioncmds.c:179 commands/tablecmds.c:6296 commands/typecmds.c:295 commands/typecmds.c:1444 commands/typecmds.c:1453 commands/typecmds.c:1461 commands/typecmds.c:1469 commands/typecmds.c:1477 commands/user.c:134 commands/user.c:148 commands/user.c:157 commands/user.c:166 commands/user.c:175 commands/user.c:184 commands/user.c:193 +#: commands/user.c:202 commands/user.c:211 commands/user.c:220 commands/user.c:229 commands/user.c:238 commands/user.c:247 commands/user.c:555 commands/user.c:563 commands/user.c:571 commands/user.c:579 commands/user.c:587 commands/user.c:595 commands/user.c:603 commands/user.c:611 commands/user.c:620 commands/user.c:628 commands/user.c:636 parser/parse_utilcmd.c:407 +#: replication/pgoutput/pgoutput.c:111 replication/pgoutput/pgoutput.c:132 replication/walsender.c:804 replication/walsender.c:815 replication/walsender.c:825 +#, c-format +msgid "conflicting or redundant options" +msgstr "çakışan veya artık opsiyon" + +#: catalog/aclchk.c:1052 +#, c-format +msgid "default privileges cannot be set for columns" +msgstr "varsayılan haklar sütunlar için ayarlanamaz" + +#: catalog/aclchk.c:1212 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "GRANT/REVOKE ON SCHEMAS ifadesi kullanılırken IN SCHEMA kullanılamaz" + +#: catalog/aclchk.c:1576 catalog/objectaddress.c:1390 commands/analyze.c:433 commands/copy.c:4826 commands/sequence.c:1690 commands/tablecmds.c:5942 commands/tablecmds.c:6090 commands/tablecmds.c:6147 commands/tablecmds.c:6221 commands/tablecmds.c:6315 commands/tablecmds.c:6374 commands/tablecmds.c:6513 commands/tablecmds.c:6595 commands/tablecmds.c:6687 commands/tablecmds.c:6781 +#: commands/tablecmds.c:9495 commands/tablecmds.c:9789 commands/tablecmds.c:10270 commands/trigger.c:904 parser/analyze.c:2343 parser/parse_relation.c:2735 parser/parse_relation.c:2798 parser/parse_target.c:1030 parser/parse_type.c:127 utils/adt/acl.c:2886 utils/adt/ruleutils.c:2466 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist" +msgstr "\"%s\" kolonu \"%s\" tablosunda mevcut değil" + +#: catalog/aclchk.c:1843 catalog/objectaddress.c:1230 commands/sequence.c:1128 commands/tablecmds.c:231 commands/tablecmds.c:14071 utils/adt/acl.c:2076 utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 utils/adt/acl.c:2198 utils/adt/acl.c:2228 +#, c-format +msgid "\"%s\" is not a sequence" +msgstr "\"%s\" bir sıra (sequence) değildir" + +#: catalog/aclchk.c:1881 +#, c-format +msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" +msgstr "\"%s\" sırası (sequence) sadece USAGE, SELECT, ve UPDATE haklarını desteklemektedir" + +#: catalog/aclchk.c:1898 +#, c-format +msgid "invalid privilege type %s for table" +msgstr "tablo için geçersiz hak tipi %s" + +#: catalog/aclchk.c:2064 +#, c-format +msgid "invalid privilege type %s for column" +msgstr "sütun için geçersiz hak tipi %s" + +#: catalog/aclchk.c:2077 +#, c-format +msgid "sequence \"%s\" only supports SELECT column privileges" +msgstr "\"%s\" sırası (sequence) sadece USAGE, SELECT, ve UPDATE desteklemektedir" + +#: catalog/aclchk.c:2659 +#, c-format +msgid "language \"%s\" is not trusted" +msgstr "\"%s\" dili güvenilir bir dil değildir" + +#: catalog/aclchk.c:2661 +#, c-format +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "GRANT ve REVOKE'a güvenilmeyen dillerde izin verilmez, çünkü güvenilmeyen dilleri sadece superuser kullanabilir." + +#: catalog/aclchk.c:3175 +#, c-format +msgid "cannot set privileges of array types" +msgstr "dizi (array) tiplerinin hakları ayarlanamaz" + +#: catalog/aclchk.c:3176 +#, c-format +msgid "Set the privileges of the element type instead." +msgstr "Onun yerine öğe tipinin haklarını ayarlayın." + +#: catalog/aclchk.c:3183 catalog/objectaddress.c:1520 +#, c-format +msgid "\"%s\" is not a domain" +msgstr "\"%s\" bir domain değildir" + +#: catalog/aclchk.c:3303 +#, c-format +msgid "unrecognized privilege type \"%s\"" +msgstr "bilinmeyen hak türü \"%s\"" + +#: catalog/aclchk.c:3364 +#, c-format +msgid "permission denied for aggregate %s" +msgstr "%s toplamına (aggregate) erişim engellendi" + +#: catalog/aclchk.c:3367 +#, c-format +msgid "permission denied for collation %s" +msgstr "%s karşılaştırmasına (collation) erişim engellendi" + +#: catalog/aclchk.c:3370 +#, c-format +msgid "permission denied for column %s" +msgstr "%s sütununa erişim engellendi" + +#: catalog/aclchk.c:3373 +#, c-format +msgid "permission denied for conversion %s" +msgstr "%s dönüşümüne erişim engellendi" + +#: catalog/aclchk.c:3376 +#, c-format +msgid "permission denied for database %s" +msgstr "%s veritabanına erişim engellendi" + +#: catalog/aclchk.c:3379 +#, c-format +msgid "permission denied for domain %s" +msgstr "%s domain'ine erişim engellendi" + +#: catalog/aclchk.c:3382 +#, c-format +msgid "permission denied for event trigger %s" +msgstr "%s olay tetikleyicisine erişim izni verilmedi" + +#: catalog/aclchk.c:3385 +#, c-format +msgid "permission denied for extension %s" +msgstr "%s uzantısına erişim engellendi" + +#: catalog/aclchk.c:3388 +#, c-format +msgid "permission denied for foreign-data wrapper %s" +msgstr "%s foreign-data wrapper 'ına erişim engellendi" + +#: catalog/aclchk.c:3391 +#, c-format +msgid "permission denied for foreign server %s" +msgstr "%s uzak (foreign) sunucusuna erişim engellendi" + +#: catalog/aclchk.c:3394 +#, c-format +msgid "permission denied for foreign table %s" +msgstr "%s uzak (foreign) tablosuna erişim engellendi" + +#: catalog/aclchk.c:3397 +#, c-format +msgid "permission denied for function %s" +msgstr "%s fonksiyonuna erişim engellendi" + +#: catalog/aclchk.c:3400 +#, c-format +msgid "permission denied for index %s" +msgstr "%s indeksine erişim engellendi" + +#: catalog/aclchk.c:3403 +#, c-format +msgid "permission denied for language %s" +msgstr "%s diline erişim engellendi" + +#: catalog/aclchk.c:3406 +#, c-format +msgid "permission denied for large object %s" +msgstr "%s büyük nesnesine (large obj.)erişim engellendi" + +#: catalog/aclchk.c:3409 +#, c-format +msgid "permission denied for materialized view %s" +msgstr "%s maddileştirilmiş görünümüne (materialized view) erişim engellendi" + +#: catalog/aclchk.c:3412 +#, c-format +msgid "permission denied for operator class %s" +msgstr "%s operatör sınıfına erişim engellendi" + +#: catalog/aclchk.c:3415 +#, c-format +msgid "permission denied for operator %s" +msgstr "%s operatorüne erişim engellendi" + +#: catalog/aclchk.c:3418 +#, c-format +msgid "permission denied for operator family %s" +msgstr "%s operator ailesine erişim engellendi" + +#: catalog/aclchk.c:3421 +#, c-format +msgid "permission denied for policy %s" +msgstr "%s ilkesine (policy) erişim engellendi" + +#: catalog/aclchk.c:3424 +#, c-format +msgid "permission denied for procedure %s" +msgstr "%s prosedürüne erişim engellendi" + +#: catalog/aclchk.c:3427 +#, c-format +msgid "permission denied for publication %s" +msgstr "%s yayınına (publication) erişim engellendi" + +#: catalog/aclchk.c:3430 +#, c-format +msgid "permission denied for routine %s" +msgstr "%s yordamına erişim engellendi" + +#: catalog/aclchk.c:3433 +#, c-format +msgid "permission denied for schema %s" +msgstr "%s şemasına erişim engellendi" + +#: catalog/aclchk.c:3436 commands/sequence.c:598 commands/sequence.c:832 commands/sequence.c:874 commands/sequence.c:915 commands/sequence.c:1788 commands/sequence.c:1852 +#, c-format +msgid "permission denied for sequence %s" +msgstr "%s sequence'ine erişim izni verilmedi" + +#: catalog/aclchk.c:3439 +#, c-format +msgid "permission denied for statistics object %s" +msgstr "%s istatistik nesnesine erişim engellendi" + +#: catalog/aclchk.c:3442 +#, c-format +msgid "permission denied for subscription %s" +msgstr "%s aboneliğine (subscription) erişim engellendi" + +#: catalog/aclchk.c:3445 +#, c-format +msgid "permission denied for table %s" +msgstr "%s tablosuna erişim engellendi" + +#: catalog/aclchk.c:3448 +#, c-format +msgid "permission denied for tablespace %s" +msgstr "%s tablespace'ine erişim engellendi" + +#: catalog/aclchk.c:3451 +#, c-format +msgid "permission denied for text search configuration %s" +msgstr "%s metin arama yapılandırmasına erişim engellendi" + +#: catalog/aclchk.c:3454 +#, c-format +msgid "permission denied for text search dictionary %s" +msgstr "%s metin arama sözlüğüne erişim engellendi" + +#: catalog/aclchk.c:3457 +#, c-format +msgid "permission denied for type %s" +msgstr "%s tipine erişim engellendi" + +#: catalog/aclchk.c:3460 +#, c-format +msgid "permission denied for view %s" +msgstr "%s görünümüne erişim engellendi" + +#: catalog/aclchk.c:3495 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "%s toplamının (aggregate) sahibi olmalısınız" + +#: catalog/aclchk.c:3498 +#, c-format +msgid "must be owner of collation %s" +msgstr "%s karşılaştırmasının (collation) sahibi olmalısınız" + +#: catalog/aclchk.c:3501 +#, c-format +msgid "must be owner of conversion %s" +msgstr "%s dönüşümünün sahibi olmalısınız" + +#: catalog/aclchk.c:3504 +#, c-format +msgid "must be owner of database %s" +msgstr "%s veritabanının sahibi olmalısınız" + +#: catalog/aclchk.c:3507 +#, c-format +msgid "must be owner of domain %s" +msgstr "%s domain'inin sahibi olmalısınız" + +#: catalog/aclchk.c:3510 +#, c-format +msgid "must be owner of event trigger %s" +msgstr "%s olay tetikleyicisinin sahibi olmalısınız" + +#: catalog/aclchk.c:3513 +#, c-format +msgid "must be owner of extension %s" +msgstr "%s uzantısının sahibi olmalısınız" + +#: catalog/aclchk.c:3516 +#, c-format +msgid "must be owner of foreign-data wrapper %s" +msgstr "%s uzak-veri (foreign-data) wrapper'inin sahibi olmalısınız" + +#: catalog/aclchk.c:3519 +#, c-format +msgid "must be owner of foreign server %s" +msgstr "%s uzak (foreign) sunucusunun sahibi olmalısınız" + +#: catalog/aclchk.c:3522 +#, c-format +msgid "must be owner of foreign table %s" +msgstr "%s uzak (foreign) tablosunun sahibi olmalısınız" + +#: catalog/aclchk.c:3525 +#, c-format +msgid "must be owner of function %s" +msgstr "%s fonksiyonunun sahibi olmalısınız" + +#: catalog/aclchk.c:3528 +#, c-format +msgid "must be owner of index %s" +msgstr "%s indeksinin sahibi olmalısınız" + +#: catalog/aclchk.c:3531 +#, c-format +msgid "must be owner of language %s" +msgstr "%s dilinin sahibi olmalısınız" + +#: catalog/aclchk.c:3534 +#, c-format +msgid "must be owner of large object %s" +msgstr "%s büyük nesnesinin sahibi olmalısınız" + +#: catalog/aclchk.c:3537 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "%s maddileştirilmiş görünümünün sahibi olmalısınız" + +#: catalog/aclchk.c:3540 +#, c-format +msgid "must be owner of operator class %s" +msgstr "%s operatör sınıfının sahibi olmalısınız" + +#: catalog/aclchk.c:3543 +#, c-format +msgid "must be owner of operator %s" +msgstr "%s operatörünün sahibi olmalısınız" + +#: catalog/aclchk.c:3546 +#, c-format +msgid "must be owner of operator family %s" +msgstr "%s operator ailesinin sahibi olmalısınız" + +#: catalog/aclchk.c:3549 +#, c-format +msgid "must be owner of procedure %s" +msgstr "%s prosedürünün sahibi olmalısınız" + +#: catalog/aclchk.c:3552 +#, c-format +msgid "must be owner of publication %s" +msgstr "%s yayınının (publication) sahibi olmalısınız" + +#: catalog/aclchk.c:3555 +#, c-format +msgid "must be owner of routine %s" +msgstr "%s yordamının (routine) sahibi olmalısınız" + +#: catalog/aclchk.c:3558 +#, c-format +msgid "must be owner of sequence %s" +msgstr "%s sequence'ın sahibi olmalısınız" + +#: catalog/aclchk.c:3561 +#, c-format +msgid "must be owner of subscription %s" +msgstr "%s aboneliğinin (subscription) sahibi olmalısınız" + +#: catalog/aclchk.c:3564 +#, c-format +msgid "must be owner of table %s" +msgstr "%s tablosunun sahibi olmalısınız" + +#: catalog/aclchk.c:3567 +#, c-format +msgid "must be owner of type %s" +msgstr "%s tipinin sahibi olmalısınız" + +#: catalog/aclchk.c:3570 +#, c-format +msgid "must be owner of view %s" +msgstr "%s görünümünün sahibi olmalısınız" + +#: catalog/aclchk.c:3573 +#, c-format +msgid "must be owner of schema %s" +msgstr "%s şemasının sahibi olmalısınız" + +#: catalog/aclchk.c:3576 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "%s istatistik nesnesinin sahibi olmalısınız" + +#: catalog/aclchk.c:3579 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "%s tablespace'inin sahibi olmalısınız" + +#: catalog/aclchk.c:3582 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "%s metin arama sözlüğünün sahibi olmalısınız" + +#: catalog/aclchk.c:3585 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "%s metin arama sözlüğünün sahibi olmalısınız" + +#: catalog/aclchk.c:3599 +#, c-format +msgid "must be owner of relation %s" +msgstr "%s nesnesinin sahibi olmalısınız" + +#: catalog/aclchk.c:3643 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütununa erişim engellendi" + +#: catalog/aclchk.c:3764 catalog/aclchk.c:3772 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "%2$u OID'li nesnenin %1$d niteliği mevcut değil" + +#: catalog/aclchk.c:3845 catalog/aclchk.c:4764 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "%u OID'li nesne mevcut değil" + +#: catalog/aclchk.c:3944 catalog/aclchk.c:5182 +#, c-format +msgid "database with OID %u does not exist" +msgstr "%u OID'li veritabanı mevcut değil" + +#: catalog/aclchk.c:3998 catalog/aclchk.c:4842 tcop/fastpath.c:221 utils/fmgr/fmgr.c:2195 +#, c-format +msgid "function with OID %u does not exist" +msgstr "%u OID'li fonksiyon mevcut değil" + +#: catalog/aclchk.c:4052 catalog/aclchk.c:4868 +#, c-format +msgid "language with OID %u does not exist" +msgstr "%u OID'li dil mevcut değil" + +#: catalog/aclchk.c:4216 catalog/aclchk.c:4940 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "%u OID'li şema mevcut değil" + +#: catalog/aclchk.c:4270 catalog/aclchk.c:4967 +#, c-format +msgid "tablespace with OID %u does not exist" +msgstr "%u OID'li tablespace mevcut değil" + +#: catalog/aclchk.c:4329 catalog/aclchk.c:5101 commands/foreigncmds.c:324 +#, c-format +msgid "foreign-data wrapper with OID %u does not exist" +msgstr "%u OID'li uzak-veri wrapper'i mevcut değil" + +#: catalog/aclchk.c:4391 catalog/aclchk.c:5128 commands/foreigncmds.c:459 +#, c-format +msgid "foreign server with OID %u does not exist" +msgstr "%u OID'li uzak (foreign) sunucu mevcut değil" + +#: catalog/aclchk.c:4451 catalog/aclchk.c:4790 utils/cache/typcache.c:368 +#, c-format +msgid "type with OID %u does not exist" +msgstr "%u OID'li tip mevcut değil" + +#: catalog/aclchk.c:4816 +#, c-format +msgid "operator with OID %u does not exist" +msgstr "%u OID'li operatör mevcut değil" + +#: catalog/aclchk.c:4993 +#, c-format +msgid "operator class with OID %u does not exist" +msgstr "%u OID'li operatör sınıfı mevcut değil" + +#: catalog/aclchk.c:5020 +#, c-format +msgid "operator family with OID %u does not exist" +msgstr "OID'i %u olan operatör mevcut değil" + +#: catalog/aclchk.c:5047 +#, c-format +msgid "text search dictionary with OID %u does not exist" +msgstr "%u OID'li metin arama sözlüğü mevcut değil" + +#: catalog/aclchk.c:5074 +#, c-format +msgid "text search configuration with OID %u does not exist" +msgstr "%u OID'li metin arama sözlüğü mevcut değil" + +#: catalog/aclchk.c:5155 commands/event_trigger.c:590 +#, c-format +msgid "event trigger with OID %u does not exist" +msgstr "%u OID'li olay tetikleyicisi mevcut değil" + +#: catalog/aclchk.c:5208 commands/collationcmds.c:347 +#, c-format +msgid "collation with OID %u does not exist" +msgstr "%u OID'li karşılaştırma (collation) mevcut değil" + +#: catalog/aclchk.c:5234 +#, c-format +msgid "conversion with OID %u does not exist" +msgstr "%u OID'li dönüşüm mevcut değil" + +#: catalog/aclchk.c:5275 +#, c-format +msgid "extension with OID %u does not exist" +msgstr "%u OID'li uzantı mevcut değil" + +#: catalog/aclchk.c:5302 commands/publicationcmds.c:747 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "%u OID'li yayın (publiation) mevcut değil" + +#: catalog/aclchk.c:5328 commands/subscriptioncmds.c:1098 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "%u OID'li abonelik (subscription) mevcut değil" + +#: catalog/aclchk.c:5354 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "%u OID'li istatistik nesnesi mevcut değil" + +#: catalog/dependency.c:611 +#, c-format +msgid "cannot drop %s because %s requires it" +msgstr "%s tarafından kullanıldığı için %s kaldırılamıyor" + +#: catalog/dependency.c:614 +#, c-format +msgid "You can drop %s instead." +msgstr "Onun yerine %s nesnesini kaldırabilirsiniz." + +#: catalog/dependency.c:787 catalog/pg_shdepend.c:574 +#, c-format +msgid "cannot drop %s because it is required by the database system" +msgstr "veritabanı sistemi tarafından kullanıldığı için %s kaldırılamıyor" + +#: catalog/dependency.c:905 +#, c-format +msgid "drop auto-cascades to %s" +msgstr "drop, auto-cascade neticesinde %s nesnesine varıyor" + +#: catalog/dependency.c:917 catalog/dependency.c:926 +#, c-format +msgid "%s depends on %s" +msgstr "%s, %s nesnesine bağlıdır" + +#: catalog/dependency.c:938 catalog/dependency.c:947 +#, c-format +msgid "drop cascades to %s" +msgstr "kaldırma işlemi , cascade neticesinde %s' nesnesine varıyor" + +#: catalog/dependency.c:955 catalog/pg_shdepend.c:685 +#, c-format +msgid "" +"\n" +"and %d other object (see server log for list)" +msgid_plural "" +"\n" +"and %d other objects (see server log for list)" +msgstr[0] "" +"\n" +"ve daha %d diğer nesne (liste için sunucu log dosyasına bakın)" +msgstr[1] "" +"\n" +"ve daha %d diğer nesne (liste için sunucu log dosyasına bakın)" + +#: catalog/dependency.c:967 +#, c-format +msgid "cannot drop %s because other objects depend on it" +msgstr "diğer nesnelerin ona bağlı olması nedeniyle %s kaldırılamıyor" + +#: catalog/dependency.c:971 catalog/dependency.c:978 +#, c-format +msgid "Use DROP ... CASCADE to drop the dependent objects too." +msgstr "Bağlı nesneleri de kaldırmak için DROP ... CASCADE kullanın." + +#: catalog/dependency.c:975 +#, c-format +msgid "cannot drop desired object(s) because other objects depend on them" +msgstr "istenen nesne(ler) kaldırılamıyor çünkü ona(onlara) bağlı başka nesneler mevcut" + +#. translator: %d always has a value larger than 1 +#: catalog/dependency.c:984 +#, c-format +msgid "drop cascades to %d other object" +msgid_plural "drop cascades to %d other objects" +msgstr[0] "kaldırma işlemi , %d diğer nesneye varıyor (cascade)" +msgstr[1] "kaldırma işlemi , %d diğer nesneye varıyor (cascade)" + +#: catalog/dependency.c:1644 +#, c-format +msgid "constant of the type %s cannot be used here" +msgstr "%s tipindeki sabit burada kullanılamaz" + +#: catalog/heap.c:286 +#, c-format +msgid "permission denied to create \"%s.%s\"" +msgstr "\"%s.%s\" oluşturulmasına izin verilmedi" + +#: catalog/heap.c:288 +#, c-format +msgid "System catalog modifications are currently disallowed." +msgstr "System catalog değişikliklerine şu anda izin verilmiyor." + +#: catalog/heap.c:433 commands/tablecmds.c:1884 commands/tablecmds.c:2417 commands/tablecmds.c:5509 +#, c-format +msgid "tables can have at most %d columns" +msgstr "bir tablo en fazla %d sütun içerebilir" + +#: catalog/heap.c:452 commands/tablecmds.c:5805 +#, c-format +msgid "column name \"%s\" conflicts with a system column name" +msgstr "\"%s\" kolon adı sistem kolonu ile çakışmaktadır" + +#: catalog/heap.c:468 +#, c-format +msgid "column name \"%s\" specified more than once" +msgstr "\"%s\" kolon adı birden fazla belirtilmiş" + +#: catalog/heap.c:521 +#, c-format +msgid "column \"%s\" has pseudo-type %s" +msgstr "\"%s\" sütunu %s pseudo-tipine sahip" + +#: catalog/heap.c:551 +#, c-format +msgid "composite type %s cannot be made a member of itself" +msgstr "%s birleşik (composite) tipi kendisinin bir üyesi olamaz" + +#: catalog/heap.c:593 commands/createas.c:201 commands/createas.c:498 +#, c-format +msgid "no collation was derived for column \"%s\" with collatable type %s" +msgstr "%2$s collatable tipli \"%1$s\" sütunundan hiç karşılaştırma (collation) türetilmemiş" + +#: catalog/heap.c:595 commands/createas.c:204 commands/createas.c:501 commands/indexcmds.c:1588 commands/tablecmds.c:14357 commands/view.c:105 regex/regc_pg_locale.c:263 utils/adt/formatting.c:1536 utils/adt/formatting.c:1658 utils/adt/formatting.c:1781 utils/adt/like.c:184 utils/adt/selfuncs.c:5807 utils/adt/varlena.c:1416 utils/adt/varlena.c:1881 +#, c-format +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "Karşılaştırmayı açıkça (explicitly) belirlemek için COLLATE ibaresini kullanın." + +#: catalog/heap.c:1084 catalog/index.c:876 commands/tablecmds.c:3179 +#, c-format +msgid "relation \"%s\" already exists" +msgstr "\"%s\" nesnesi zaten mevcut" + +#: catalog/heap.c:1100 catalog/pg_type.c:417 catalog/pg_type.c:732 commands/typecmds.c:236 commands/typecmds.c:787 commands/typecmds.c:1186 commands/typecmds.c:1419 commands/typecmds.c:2174 +#, c-format +msgid "type \"%s\" already exists" +msgstr "\"%s\" tipi zaten mevcut" + +#: catalog/heap.c:1101 +#, c-format +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "Aynı adı taşıyan bir nesneye ilişkili veri tipi mevcuttur, başka bir ad seçmelisiniz." + +#: catalog/heap.c:1130 +#, c-format +msgid "pg_class heap OID value not set when in binary upgrade mode" +msgstr "binary upgrade moudunda iken pg_class yığın OID değeri belirlenmemiş" + +#: catalog/heap.c:2333 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş (partitioned) tablosuna NO INHERIT kısıtlaması eklenemiyor" + +#: catalog/heap.c:2598 +#, c-format +msgid "check constraint \"%s\" already exists" +msgstr "\"%s\"check constraint'i zaten mevcut" + +#: catalog/heap.c:2768 catalog/index.c:890 catalog/pg_constraint.c:679 commands/tablecmds.c:7157 +#, c-format +msgid "constraint \"%s\" for relation \"%s\" already exists" +msgstr "\"%s\" constraint 'i \"%s\" nesnesi için zaten mevcut" + +#: catalog/heap.c:2775 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgstr "\"%s\" kısıtlaması (constraint) \"%s\" nesnesi üzerindeki kalıtsal olmayan kısıtlamayla çakışıyor" + +#: catalog/heap.c:2786 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "\"%s\" kısıtlaması (constraint) \"%s\" nesnesi üzerindeki kalıtsal kısıtlamayla çakışıyor" + +#: catalog/heap.c:2796 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "\"%s\" kısıtlaması (constraint) \"%s\" nesnesi üzerindeki NOT VALID kısıtlamasıyla çakışıyor" + +#: catalog/heap.c:2801 +#, c-format +msgid "merging constraint \"%s\" with inherited definition" +msgstr "\"%s\" kısıtlaması miras alınan tanımı ile birleştiriliyor" + +#: catalog/heap.c:2916 +#, c-format +msgid "cannot use column references in default expression" +msgstr "defaul ifadesinde sütun referansı kullanılamaz" + +#: catalog/heap.c:2941 rewrite/rewriteHandler.c:1177 +#, c-format +msgid "column \"%s\" is of type %s but default expression is of type %s" +msgstr "\"%s\" kolonunun tipi %s'dır, ancak öntanımlı ifadenin tipi %s'dir." + +#: catalog/heap.c:2946 commands/prepare.c:384 parser/parse_node.c:430 parser/parse_target.c:590 parser/parse_target.c:865 parser/parse_target.c:875 rewrite/rewriteHandler.c:1182 +#, c-format +msgid "You will need to rewrite or cast the expression." +msgstr "Bu ifadeyi yinden yazmalı ya da sonucunu cast etmelisiniz." + +#: catalog/heap.c:2993 +#, c-format +msgid "only table \"%s\" can be referenced in check constraint" +msgstr "check constraint içerisinde sadece \"%s\" tablosu kullanılabilir" + +#: catalog/heap.c:3243 +#, c-format +msgid "unsupported ON COMMIT and foreign key combination" +msgstr "desteklenmeyen ON COMMIT ve foreign key birleştirmesi" + +#: catalog/heap.c:3244 +#, c-format +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." +msgstr "\"%s\" tablosu \"%s\" tablosuna başvuruyor ancak ikisi aynı ON COMMIT ayarına sahip değildir." + +#: catalog/heap.c:3249 +#, c-format +msgid "cannot truncate a table referenced in a foreign key constraint" +msgstr "ikincil anahtar bütünlük kısıtlamasının refere ettiği tabloyu truncate edemezsiniz" + +#: catalog/heap.c:3250 +#, c-format +msgid "Table \"%s\" references \"%s\"." +msgstr "\"%s\" tablosu \"%s\" tablosuna başvuruyor." + +#: catalog/heap.c:3252 +#, c-format +msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." +msgstr "\"%s\" tablosuna da truncate işlemi uygulayın, veya TRUNCATE ... CASCADE işlemi kullanın." + +#: catalog/index.c:233 parser/parse_utilcmd.c:1823 parser/parse_utilcmd.c:1910 +#, c-format +msgid "multiple primary keys for table \"%s\" are not allowed" +msgstr "\"%s\" tablosunda birden çok birincil anahtara izin verilmez" + +#: catalog/index.c:251 +#, c-format +msgid "primary keys cannot be expressions" +msgstr "birincil anahtar bir ifade olamaz" + +#: catalog/index.c:820 catalog/index.c:1291 +#, c-format +msgid "user-defined indexes on system catalog tables are not supported" +msgstr "sistem katalog tabloları üzerinde kullanıcı tanımlı index oluşturulamaz" + +#: catalog/index.c:830 +#, c-format +msgid "concurrent index creation on system catalog tables is not supported" +msgstr "sistem katalog tabloları üzerinde koşutzamanlı index oluşturma işlemi yapılamaz" + +#: catalog/index.c:848 +#, c-format +msgid "shared indexes cannot be created after initdb" +msgstr "initdb işleminden sonra shared indeks oluşturulamaz" + +#: catalog/index.c:868 commands/createas.c:250 commands/sequence.c:152 parser/parse_utilcmd.c:205 +#, c-format +msgid "relation \"%s\" already exists, skipping" +msgstr "\"%s\" nesnesi zaten mevcut, atlanıyor" + +#: catalog/index.c:918 +#, c-format +msgid "pg_class index OID value not set when in binary upgrade mode" +msgstr "binary upgrade modunda iken pg_class indeks OID değeri belirlenmemiş" + +#: catalog/index.c:1566 +#, c-format +msgid "DROP INDEX CONCURRENTLY must be first action in transaction" +msgstr "DROP INDEX CONCURRENTLY işlemdeki (transaction) ilk eylem olmalı" + +#: catalog/index.c:2295 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "\"%2$s\" tablosu üzerinde \"%1$s\" indeksi seri olarak (serially) oluşturuluyor" + +#: catalog/index.c:2300 +#, c-format +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "\"%2$s\" tablosu üzerinde \"%1$s\" indeksi %3$d paralel worker'ı için talep ile oluşturuluyor" +msgstr[1] "\"%2$s\" tablosu üzerinde \"%1$s\" indeksi %3$d paralel worker'ları için talep ile oluşturuluyor" + +#: catalog/index.c:3689 +#, c-format +msgid "cannot reindex temporary tables of other sessions" +msgstr "diğer oturumların geçici tabloları yeniden indexlenemez" + +#: catalog/index.c:3820 +#, c-format +msgid "index \"%s\" was reindexed" +msgstr "\"%s\" indeksi yeniden indekslenmiştir" + +#: catalog/index.c:3891 +#, c-format +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "bölümlenmiş tabloların REINDEX işlemi implement edilmemiştir, \"%s\" atlanıyor" + +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 commands/trigger.c:5397 +#, c-format +msgid "cross-database references are not implemented: \"%s.%s.%s\"" +msgstr "veritabanı-arası referanslar oluşturulamaz: \"%s.%s.%s\"" + +#: catalog/namespace.c:306 +#, c-format +msgid "temporary tables cannot specify a schema name" +msgstr "geçici tablolarda şema adı belirtilemez" + +#: catalog/namespace.c:387 +#, c-format +msgid "could not obtain lock on relation \"%s.%s\"" +msgstr "\"%s.%s\" nesnesi için kilit alınamadı" + +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:248 +#, c-format +msgid "could not obtain lock on relation \"%s\"" +msgstr "\"%s\" tablosu için kilit alınamadı" + +#: catalog/namespace.c:420 parser/parse_relation.c:1158 +#, c-format +msgid "relation \"%s.%s\" does not exist" +msgstr "\"%s.%s\" nesnesi mevcut değil" + +#: catalog/namespace.c:425 parser/parse_relation.c:1171 parser/parse_relation.c:1179 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "\"%s\" nesnesi mevcut değil" + +#: catalog/namespace.c:491 catalog/namespace.c:3008 commands/extension.c:1466 commands/extension.c:1472 +#, c-format +msgid "no schema has been selected to create in" +msgstr "oluşturma işlemi için şema adı belirtimemiş" + +#: catalog/namespace.c:643 catalog/namespace.c:656 +#, c-format +msgid "cannot create relations in temporary schemas of other sessions" +msgstr "başka oturumların geçici şemalarında nesne oluşturulamaz" + +#: catalog/namespace.c:647 +#, c-format +msgid "cannot create temporary relation in non-temporary schema" +msgstr "geçici olmayan şemada geçici nesne oluşturulamaz" + +#: catalog/namespace.c:662 +#, c-format +msgid "only temporary relations may be created in temporary schemas" +msgstr "geçici şemalarda sadece geçici nesneler oluşturulabilir" + +#: catalog/namespace.c:2200 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "\"%s\" istatistik nesnesi mevcut değil" + +#: catalog/namespace.c:2323 +#, c-format +msgid "text search parser \"%s\" does not exist" +msgstr "\"%s\" metin arama ayrıştırıcısı mevcut değil" + +#: catalog/namespace.c:2449 +#, c-format +msgid "text search dictionary \"%s\" does not exist" +msgstr "\"%s\" metin arama sözlüğü mevcut değil" + +#: catalog/namespace.c:2576 +#, c-format +msgid "text search template \"%s\" does not exist" +msgstr "\"%s\" metin arama şablonu mevcut değil" + +#: catalog/namespace.c:2702 commands/tsearchcmds.c:1185 utils/cache/ts_cache.c:616 +#, c-format +msgid "text search configuration \"%s\" does not exist" +msgstr "\"%s\" metin arama sözlüğü mevcut değil" + +#: catalog/namespace.c:2815 parser/parse_expr.c:793 parser/parse_target.c:1220 +#, c-format +msgid "cross-database references are not implemented: %s" +msgstr "veritabanı-arası referanslar oluşturulamaz: %s" + +#: catalog/namespace.c:2821 gram.y:14708 gram.y:16140 parser/parse_expr.c:800 parser/parse_target.c:1227 +#, c-format +msgid "improper qualified name (too many dotted names): %s" +msgstr "geçersiz qualified adı (çok fazla noktalı isim): %s" + +#: catalog/namespace.c:2951 +#, c-format +msgid "cannot move objects into or out of temporary schemas" +msgstr "geçici şemasına nesleri aktarılamaz ve içinden alınamaz" + +#: catalog/namespace.c:2957 +#, c-format +msgid "cannot move objects into or out of TOAST schema" +msgstr "TOAST şemasına nesleri aktarılamaz ve içinden alınamaz" + +#: catalog/namespace.c:3029 commands/schemacmds.c:256 commands/schemacmds.c:334 commands/tablecmds.c:1017 +#, c-format +msgid "schema \"%s\" does not exist" +msgstr "\"%s\" şeması mevcut değil" + +#: catalog/namespace.c:3060 +#, c-format +msgid "improper relation name (too many dotted names): %s" +msgstr "geçersiz nesne adı (çok fazla noktalı isim): %s" + +#: catalog/namespace.c:3594 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" does not exist" +msgstr "\"%2$s\" kodlaması (encoding) için \"%1$s\" karşılaştırması (collation) mevcut değil" + +#: catalog/namespace.c:3649 +#, c-format +msgid "conversion \"%s\" does not exist" +msgstr "\"%s\" dönüşümü mevcut değil" + +#: catalog/namespace.c:3889 +#, c-format +msgid "permission denied to create temporary tables in database \"%s\"" +msgstr "\"%s\" veritabanında geçici veritabanı oluşturma izni yok" + +#: catalog/namespace.c:3905 +#, c-format +msgid "cannot create temporary tables during recovery" +msgstr "kurtarma sırasında geçici tablo oluşturulamıyor" + +#: catalog/namespace.c:3911 +#, c-format +msgid "cannot create temporary tables during a parallel operation" +msgstr "bir paralel işlem sırasında geçici tablo oluşturulamıyor" + +#: catalog/namespace.c:4194 commands/tablespace.c:1171 commands/variable.c:64 utils/misc/guc.c:10267 utils/misc/guc.c:10345 +#, c-format +msgid "List syntax is invalid." +msgstr "Liste sözdizimi geçerli değil." + +#: catalog/objectaddress.c:1238 catalog/pg_publication.c:66 commands/policy.c:94 commands/policy.c:394 commands/policy.c:484 commands/tablecmds.c:225 commands/tablecmds.c:267 commands/tablecmds.c:1742 commands/tablecmds.c:5004 commands/tablecmds.c:9613 +#, c-format +msgid "\"%s\" is not a table" +msgstr "\"%s\" bir tablo değildir" + +#: catalog/objectaddress.c:1245 commands/tablecmds.c:237 commands/tablecmds.c:5034 commands/tablecmds.c:14076 commands/view.c:143 +#, c-format +msgid "\"%s\" is not a view" +msgstr "\"%s\" bir view değildir" + +#: catalog/objectaddress.c:1252 commands/matview.c:172 commands/tablecmds.c:243 commands/tablecmds.c:14081 +#, c-format +msgid "\"%s\" is not a materialized view" +msgstr "\"%s\" bir maddileştirilmiş görünüm (materialized view) değildir" + +#: catalog/objectaddress.c:1259 commands/tablecmds.c:261 commands/tablecmds.c:5037 commands/tablecmds.c:14086 +#, c-format +msgid "\"%s\" is not a foreign table" +msgstr "\"%s\" bir uzak (foreign) tablo değildir" + +#: catalog/objectaddress.c:1300 +#, c-format +msgid "must specify relation and object name" +msgstr "ilişki (relation) ve nesne adı belirtmelisiniz" + +#: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 +#, c-format +msgid "column name must be qualified" +msgstr "sütun adı nitelendirilmeli" + +#: catalog/objectaddress.c:1472 +#, c-format +msgid "default value for column \"%s\" of relation \"%s\" does not exist" +msgstr "\"%2$s\" ilişkisinin \"%1$s\" sütunu için varsayılan değer mevcut değil" + +#: catalog/objectaddress.c:1509 commands/functioncmds.c:133 commands/tablecmds.c:253 commands/typecmds.c:3324 parser/parse_type.c:226 parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4452 +#, c-format +msgid "type \"%s\" does not exist" +msgstr "\"%s\" tipi mevcut değil" + +#: catalog/objectaddress.c:1628 +#, c-format +msgid "operator %d (%s, %s) of %s does not exist" +msgstr "%4$s nin %1$d operatörü (%2$s,%3$s) mevcut değil" + +#: catalog/objectaddress.c:1659 +#, c-format +msgid "function %d (%s, %s) of %s does not exist" +msgstr "%4$s'nin %1$d fonksiyonu (%2$s,%3$s) mevcut değildir" + +#: catalog/objectaddress.c:1710 catalog/objectaddress.c:1736 +#, c-format +msgid "user mapping for user \"%s\" on server \"%s\" does not exist" +msgstr "\"%2$s\" sunucusu üzerinde \"%1$s\" kullanıcısı için kullanıcı eşleştirme mevcut değil" + +#: catalog/objectaddress.c:1725 commands/foreigncmds.c:428 commands/foreigncmds.c:1004 commands/foreigncmds.c:1381 foreign/foreign.c:688 +#, c-format +msgid "server \"%s\" does not exist" +msgstr "\"%s\" sunucusu mevcut değil" + +#: catalog/objectaddress.c:1792 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "\"%2$s\" yayınında (publication) \"%1$s\" yayın ilişkisi (relation) mevcut değil" + +#: catalog/objectaddress.c:1854 +#, c-format +msgid "unrecognized default ACL object type \"%c\"" +msgstr "bilinmeyen varsayılan ACL nesne tipi \"%c\"" + +#: catalog/objectaddress.c:1855 +#, c-format +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "Geçerli nesne tipleri şunlardır: \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." + +#: catalog/objectaddress.c:1906 +#, c-format +msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" +msgstr "%3$s üzerinde \"%2$s\" şemasında \"%1$s\" kullanıcısı için varsayılan ACL mevcut değil" + +#: catalog/objectaddress.c:1911 +#, c-format +msgid "default ACL for user \"%s\" on %s does not exist" +msgstr "%2$s üzerinde \"%1$s\" kullanıcısı için varsayılan ACL mevcut değil" + +#: catalog/objectaddress.c:1938 catalog/objectaddress.c:1996 catalog/objectaddress.c:2053 +#, c-format +msgid "name or argument lists may not contain nulls" +msgstr "isim veya argüman listeleri null kayıtları içeremez" + +#: catalog/objectaddress.c:1972 +#, c-format +msgid "unsupported object type \"%s\"" +msgstr "desteklenmeyen veri tipi \"%s\"" + +#: catalog/objectaddress.c:1992 catalog/objectaddress.c:2010 catalog/objectaddress.c:2151 +#, c-format +msgid "name list length must be exactly %d" +msgstr "isim listesi uzunluğu tam olarak %d olmalı" + +#: catalog/objectaddress.c:2014 +#, c-format +msgid "large object OID may not be null" +msgstr "large object OID'si null olamaz" + +#: catalog/objectaddress.c:2023 catalog/objectaddress.c:2086 catalog/objectaddress.c:2093 +#, c-format +msgid "name list length must be at least %d" +msgstr "isim listesi uzunluğu en az %d olmalı" + +#: catalog/objectaddress.c:2079 catalog/objectaddress.c:2100 +#, c-format +msgid "argument list length must be exactly %d" +msgstr "argüman listesi uzunluğu tam olarak %d olmalı" + +#: catalog/objectaddress.c:2330 libpq/be-fsstubs.c:321 +#, c-format +msgid "must be owner of large object %u" +msgstr "%u large objectinin saibi olmalı" + +#: catalog/objectaddress.c:2345 commands/functioncmds.c:1454 +#, c-format +msgid "must be owner of type %s or type %s" +msgstr "%s veya %s tiplerinin sahibi olmalısınız" + +#: catalog/objectaddress.c:2395 catalog/objectaddress.c:2412 +#, c-format +msgid "must be superuser" +msgstr "superuser olmak gerekiyor" + +#: catalog/objectaddress.c:2402 +#, c-format +msgid "must have CREATEROLE privilege" +msgstr "CREATEROLE yetkisi gerekiyor" + +#: catalog/objectaddress.c:2481 +#, c-format +msgid "unrecognized object type \"%s\"" +msgstr "bilinmeyen nesne tipi \"%s\"" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2694 +#, c-format +msgid "column %s of %s" +msgstr "%2$s'nin %1$s sütunu" + +#: catalog/objectaddress.c:2704 +#, c-format +msgid "function %s" +msgstr "%s fonksiyonu" + +#: catalog/objectaddress.c:2709 +#, c-format +msgid "type %s" +msgstr "%s tipi" + +#: catalog/objectaddress.c:2739 +#, c-format +msgid "cast from %s to %s" +msgstr "%s tipi %s tipine cast" + +#: catalog/objectaddress.c:2767 +#, c-format +msgid "collation %s" +msgstr "Sıralama %s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2793 +#, c-format +msgid "constraint %s on %s" +msgstr "%2$s üzerinde %1$s kısıtlaması" + +#: catalog/objectaddress.c:2799 +#, c-format +msgid "constraint %s" +msgstr "%s constraint" + +#: catalog/objectaddress.c:2826 +#, c-format +msgid "conversion %s" +msgstr "%s dönüşümünü" + +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2865 +#, c-format +msgid "default value for %s" +msgstr "%s için varsayılan değer" + +#: catalog/objectaddress.c:2874 +#, c-format +msgid "language %s" +msgstr "%s dili" + +#: catalog/objectaddress.c:2879 +#, c-format +msgid "large object %u" +msgstr "%u large objecti" + +#: catalog/objectaddress.c:2884 +#, c-format +msgid "operator %s" +msgstr "%s operatoru" + +#: catalog/objectaddress.c:2916 +#, c-format +msgid "operator class %s for access method %s" +msgstr "%2$s erişim yöntemi için %1$s erişim metodu" + +#: catalog/objectaddress.c:2939 +#, c-format +msgid "access method %s" +msgstr "%s erişim yöntemi" + +#. translator: %d is the operator strategy (a number), the +#. first two %s's are data type names, the third %s is the +#. description of the operator family, and the last %s is the +#. textual form of the operator with arguments. +#: catalog/objectaddress.c:2981 +#, c-format +msgid "operator %d (%s, %s) of %s: %s" +msgstr "%4$s'nin %1$d operatorü (%2$s, %3$s): %5$s" + +#. translator: %d is the function number, the first two %s's +#. are data type names, the third %s is the description of the +#. operator family, and the last %s is the textual form of the +#. function with arguments. +#: catalog/objectaddress.c:3031 +#, c-format +msgid "function %d (%s, %s) of %s: %s" +msgstr "%4$s'nin %1$d fonksiyonu (%2$s, %3$s): %5$s" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3075 +#, c-format +msgid "rule %s on %s" +msgstr "%2$s üzerinde %1$s kuralı (rule)" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3113 +#, c-format +msgid "trigger %s on %s" +msgstr "%2$s üzerinde %1$s triggeri" + +#: catalog/objectaddress.c:3129 +#, c-format +msgid "schema %s" +msgstr "%s şeması" + +#: catalog/objectaddress.c:3152 +#, c-format +msgid "statistics object %s" +msgstr "%s istatistik nesnesi" + +#: catalog/objectaddress.c:3179 +#, c-format +msgid "text search parser %s" +msgstr "metin arama ayrıştırıcısı %s" + +#: catalog/objectaddress.c:3205 +#, c-format +msgid "text search dictionary %s" +msgstr "metin arama sözlüğü %s" + +#: catalog/objectaddress.c:3231 +#, c-format +msgid "text search template %s" +msgstr "metin arama şablonu %s" + +#: catalog/objectaddress.c:3257 +#, c-format +msgid "text search configuration %s" +msgstr "%s metin arama yapılandırması" + +#: catalog/objectaddress.c:3266 +#, c-format +msgid "role %s" +msgstr "%s rolü" + +#: catalog/objectaddress.c:3279 +#, c-format +msgid "database %s" +msgstr "%s veritabanı" + +#: catalog/objectaddress.c:3291 +#, c-format +msgid "tablespace %s" +msgstr "%s tablespace" + +#: catalog/objectaddress.c:3300 +#, c-format +msgid "foreign-data wrapper %s" +msgstr "%s foreign-data wrapper" + +#: catalog/objectaddress.c:3309 +#, c-format +msgid "server %s" +msgstr "sunucu %s" + +#: catalog/objectaddress.c:3337 +#, c-format +msgid "user mapping for %s on server %s" +msgstr "%2$s sunucusu üzerinde %1$s için kullanıcı eşleştirmesi" + +#: catalog/objectaddress.c:3382 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "%2$s şemasında %1$s rolünün yeni ilişkilerde (relation) varsayılan yetkileri" + +#: catalog/objectaddress.c:3386 +#, c-format +msgid "default privileges on new relations belonging to role %s" +msgstr "%s rolünün yeni ilişkilerde (relation) varsayılan yetkileri" + +#: catalog/objectaddress.c:3392 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "%2$s şemasında %1$s rolünün yeni sıralarda (sequence) varsayılan yetkileri" + +#: catalog/objectaddress.c:3396 +#, c-format +msgid "default privileges on new sequences belonging to role %s" +msgstr "%s rolünün yeni sıralarda (sequence) varsayılan yetkileri" + +#: catalog/objectaddress.c:3402 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "%2$s şemasında %1$s rolünün yeni fonksiyonlarda varsayılan yetkileri" + +#: catalog/objectaddress.c:3406 +#, c-format +msgid "default privileges on new functions belonging to role %s" +msgstr "%s rolünün yeni fonksiyonlarda varsayılan yetkileri" + +#: catalog/objectaddress.c:3412 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "%2$s şemasında %1$s rolünün yeni tiplerde varsayılan yetkileri" + +#: catalog/objectaddress.c:3416 +#, c-format +msgid "default privileges on new types belonging to role %s" +msgstr "%s rolünün yeni tiplerde varsayılan yetkileri" + +#: catalog/objectaddress.c:3422 +#, c-format +msgid "default privileges on new schemas belonging to role %s" +msgstr "%s rolünün yeni şemalarda varsayılan yetkileri" + +#: catalog/objectaddress.c:3429 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "%2$s şemasında %1$s rolünün varsayılan yetkileri" + +#: catalog/objectaddress.c:3433 +#, c-format +msgid "default privileges belonging to role %s" +msgstr "%s rolünün varsayılan yetkileri" + +#: catalog/objectaddress.c:3451 +#, c-format +msgid "extension %s" +msgstr "%s uzantısı" + +#: catalog/objectaddress.c:3464 +#, c-format +msgid "event trigger %s" +msgstr "%s olay tetikleyicisi (trigger)" + +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3500 +#, c-format +msgid "policy %s on %s" +msgstr "%2$s üzerinde %1$s politikası" + +#: catalog/objectaddress.c:3510 +#, c-format +msgid "publication %s" +msgstr "%s yayını (publication)" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3535 +#, c-format +msgid "publication of %s in publication %s" +msgstr "%2$s yayınında (publication) %1$s nesnesinin yayını" + +#: catalog/objectaddress.c:3544 +#, c-format +msgid "subscription %s" +msgstr "%s aboneliği (subsciption)" + +#: catalog/objectaddress.c:3562 +#, c-format +msgid "transform for %s language %s" +msgstr "%s için dönüşüm, dil %s" + +#: catalog/objectaddress.c:3625 +#, c-format +msgid "table %s" +msgstr "%s tablosu" + +#: catalog/objectaddress.c:3630 +#, c-format +msgid "index %s" +msgstr "%s indeksi" + +#: catalog/objectaddress.c:3634 +#, c-format +msgid "sequence %s" +msgstr "%s sequence" + +#: catalog/objectaddress.c:3638 +#, c-format +msgid "toast table %s" +msgstr "%s toast tablosu" + +#: catalog/objectaddress.c:3642 +#, c-format +msgid "view %s" +msgstr "%s view" + +#: catalog/objectaddress.c:3646 +#, c-format +msgid "materialized view %s" +msgstr "%s maddeleştirilmiş görünümü (materialized view)" + +#: catalog/objectaddress.c:3650 +#, c-format +msgid "composite type %s" +msgstr "%s composite type" + +#: catalog/objectaddress.c:3654 +#, c-format +msgid "foreign table %s" +msgstr "%s uzak tablosu" + +#: catalog/objectaddress.c:3659 +#, c-format +msgid "relation %s" +msgstr "%s nesnesi" + +#: catalog/objectaddress.c:3696 +#, c-format +msgid "operator family %s for access method %s" +msgstr "%2$s erişim yöntemi için %1$s operatörü " + +#: catalog/partition.c:180 commands/analyze.c:1514 commands/indexcmds.c:928 commands/tablecmds.c:944 commands/tablecmds.c:7897 commands/tablecmds.c:9675 commands/tablecmds.c:14970 commands/tablecmds.c:15499 executor/execExprInterp.c:3275 executor/execMain.c:1940 executor/execMain.c:2019 executor/execMain.c:2067 executor/execMain.c:2173 executor/execPartition.c:462 +#: executor/execPartition.c:522 executor/execPartition.c:638 executor/execPartition.c:741 executor/execPartition.c:812 executor/execPartition.c:1010 executor/nodeModifyTable.c:1859 +msgid "could not convert row type" +msgstr "satır tipi dönüştürülemedi," + +#: catalog/pg_aggregate.c:126 +#, c-format +msgid "aggregates cannot have more than %d argument" +msgid_plural "aggregates cannot have more than %d arguments" +msgstr[0] "toplamların (aggregate) argüman sayısı %d sayısından fazla olamaz" +msgstr[1] "toplamların (aggregate) argüman sayısı %d sayısından fazla olamaz" + +#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#, c-format +msgid "cannot determine transition data type" +msgstr "geçiş veri tipi belirlenemedi" + +#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 +#, c-format +msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." +msgstr "Polymorphic kullanan aggregateler bu en az birer polymorphic argüman içermelidir." + +#: catalog/pg_aggregate.c:173 +#, c-format +msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" +msgstr "" + +#: catalog/pg_aggregate.c:199 +#, c-format +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" +msgstr "" + +#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 +#, c-format +msgid "return type of transition function %s is not %s" +msgstr "%s geçiş fonksiyonunun tipi %s değildir" + +#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 +#, c-format +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" +msgstr "geçiş fonksiyonu strict olduğunda ve giriş parametresinin tipi uyumsuz olduğunda başlangıç değeri mutlaka verilmelidir" + +#: catalog/pg_aggregate.c:335 +#, c-format +msgid "return type of inverse transition function %s is not %s" +msgstr "%s ters geçiş fonksiyonunun tipi %s değildir" + +#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2838 +#, c-format +msgid "strictness of aggregate's forward and inverse transition functions must match" +msgstr "" + +#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:549 +#, c-format +msgid "final function with extra arguments must not be declared STRICT" +msgstr "ekstra argümanlı final fonksiyonu STRICT olarak tanımlanmamalı" + +#: catalog/pg_aggregate.c:427 +#, c-format +msgid "return type of combine function %s is not %s" +msgstr "%s birleştirme fonksiyonunun tipi %s değildir" + +#: catalog/pg_aggregate.c:439 executor/nodeAgg.c:2943 +#, c-format +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "%s geçiş tipli birleştirme fonksiyonu STRICT olarak tanımlanmamalı" + +#: catalog/pg_aggregate.c:458 +#, c-format +msgid "return type of serialization function %s is not %s" +msgstr "%s serialization fonksiyonunun dönüş tipi %s değil" + +#: catalog/pg_aggregate.c:479 +#, c-format +msgid "return type of deserialization function %s is not %s" +msgstr "%s deserialization fonksiyonunun dönüş tipi %s değil" + +#: catalog/pg_aggregate.c:495 catalog/pg_proc.c:240 catalog/pg_proc.c:247 +#, c-format +msgid "cannot determine result data type" +msgstr "sonuç veri tipi belirlenemiyor" + +#: catalog/pg_aggregate.c:496 +#, c-format +msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." +msgstr "Polymorphic döndüren aggregateler bu en az birer polymorphic argüman içermelidir." + +#: catalog/pg_aggregate.c:508 catalog/pg_proc.c:253 +#, c-format +msgid "unsafe use of pseudo-type \"internal\"" +msgstr "\"internal\" pseudo-type'ın tehlikeli kullanışı" + +#: catalog/pg_aggregate.c:509 catalog/pg_proc.c:254 +#, c-format +msgid "A function returning \"internal\" must have at least one \"internal\" argument." +msgstr "\"internal\" döndüren fonksiyonlar bu tiplerden en az bir argüman \"internal\" olmalıdır." + +#: catalog/pg_aggregate.c:562 +#, c-format +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" +msgstr "hareketli-toplam (aggregate) uygulaması %s tipini döndürür, fakat düz uygulama %s tipini döndürür" + +#: catalog/pg_aggregate.c:573 +#, c-format +msgid "sort operator can only be specified for single-argument aggregates" +msgstr "sort işletmeni sadece tek argümanlı aggregate işin belirtilebilir" + +#: catalog/pg_aggregate.c:819 commands/typecmds.c:1766 commands/typecmds.c:1817 commands/typecmds.c:1848 commands/typecmds.c:1871 commands/typecmds.c:1892 commands/typecmds.c:1919 commands/typecmds.c:1946 commands/typecmds.c:2023 commands/typecmds.c:2065 parser/parse_func.c:408 parser/parse_func.c:437 parser/parse_func.c:462 parser/parse_func.c:476 parser/parse_func.c:596 +#: parser/parse_func.c:616 parser/parse_func.c:2086 +#, c-format +msgid "function %s does not exist" +msgstr "%s fonksiyonu mevcut değildir" + +#: catalog/pg_aggregate.c:825 +#, c-format +msgid "function %s returns a set" +msgstr "%s fonksiyonu bir küme döndürüyor" + +#: catalog/pg_aggregate.c:840 +#, c-format +msgid "function %s must accept VARIADIC ANY to be used in this aggregate" +msgstr "%s fonksiyonu bu toplamda (aggregate) kullanılmak için VARIADIC ANY kabul etmelidir" + +#: catalog/pg_aggregate.c:864 +#, c-format +msgid "function %s requires run-time type coercion" +msgstr "%s fonksiyonu çalışma zamanı tipi zorlaması gerektirir" + +#: catalog/pg_collation.c:92 catalog/pg_collation.c:139 +#, c-format +msgid "collation \"%s\" already exists, skipping" +msgstr "\"%s\" karşılaştırması zaten mevcut, atlanıyor" + +#: catalog/pg_collation.c:94 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "\"%2$s\" kodlaması için \"%1$s\" karşılaştırması zaten mevcut, atlanıyor" + +#: catalog/pg_collation.c:102 catalog/pg_collation.c:146 +#, c-format +msgid "collation \"%s\" already exists" +msgstr "\"%s\" karşılaştırması zaten mevcut" + +#: catalog/pg_collation.c:104 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "\"%2$s\" kodlaması için \"%1$s\" karşılaştırması zaten mevcut" + +#: catalog/pg_constraint.c:687 +#, c-format +msgid "constraint \"%s\" for domain %s already exists" +msgstr "\"%2$s\" etki alanı (domain) için \"%1$s\" kısıtlaması zaten mevcut" + +#: catalog/pg_constraint.c:874 catalog/pg_constraint.c:967 +#, c-format +msgid "constraint \"%s\" for table \"%s\" does not exist" +msgstr "\"%2$s\" tablosu için \"%1$s\" kısıtlaması mevcut değil" + +#: catalog/pg_constraint.c:1056 +#, c-format +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "\"%2$s\" etki alanı (domain) için \"%1$s\" bütünlük kısıtlaması mevcut değil" + +#: catalog/pg_conversion.c:65 +#, c-format +msgid "conversion \"%s\" already exists" +msgstr "conversion \"%s\" zaten mevcut" + +#: catalog/pg_conversion.c:78 +#, c-format +msgid "default conversion for %s to %s already exists" +msgstr "%s'dan %s'a öntanımlı dönüşüm zaten mevcut" + +#: catalog/pg_depend.c:163 commands/extension.c:3225 +#, c-format +msgid "%s is already a member of extension \"%s\"" +msgstr "\"%s\" zaten \"%s\" uzantısına dahildir" + +#: catalog/pg_depend.c:322 +#, c-format +msgid "cannot remove dependency on %s because it is a system object" +msgstr "sistem nesnesi tarafından kullanıldığı için %s kaldırılamıyor" + +#: catalog/pg_enum.c:115 catalog/pg_enum.c:201 catalog/pg_enum.c:488 +#, c-format +msgid "invalid enum label \"%s\"" +msgstr "Geçersiz enum etiketi: \"%s\"" + +#: catalog/pg_enum.c:116 catalog/pg_enum.c:202 catalog/pg_enum.c:489 +#, c-format +msgid "Labels must be %d characters or less." +msgstr "Etiketler %d karakter ya da daha az olmalıdır." + +#: catalog/pg_enum.c:230 +#, c-format +msgid "enum label \"%s\" already exists, skipping" +msgstr "\"%s\" enum etiketi zaten mevcut, atlanıyor" + +#: catalog/pg_enum.c:237 catalog/pg_enum.c:532 +#, c-format +msgid "enum label \"%s\" already exists" +msgstr "\"%s\" enum etiketi zaten mevcut" + +#: catalog/pg_enum.c:292 catalog/pg_enum.c:527 +#, c-format +msgid "\"%s\" is not an existing enum label" +msgstr "\"%s\" mevcut bir enum etiketi değildir" + +#: catalog/pg_enum.c:350 +#, c-format +msgid "pg_enum OID value not set when in binary upgrade mode" +msgstr "binary upgrade modunda iken pg_enum OID değeri belirlenmemiş" + +#: catalog/pg_enum.c:360 +#, c-format +msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" +msgstr "ALTER TYPE ADD BEFORE/AFTER binary upgrade ile uyumsuzdur" + +#: catalog/pg_namespace.c:63 commands/schemacmds.c:264 +#, c-format +msgid "schema \"%s\" already exists" +msgstr "\"%s\" şeması zaten mevcut" + +#: catalog/pg_operator.c:218 catalog/pg_operator.c:357 +#, c-format +msgid "\"%s\" is not a valid operator name" +msgstr "\"%s\" geçerli bir operatör adı değildir" + +#: catalog/pg_operator.c:366 +#, c-format +msgid "only binary operators can have commutators" +msgstr "sadece ikili işlemler bir commutator'a sahip olabilirler" + +#: catalog/pg_operator.c:370 commands/operatorcmds.c:485 +#, c-format +msgid "only binary operators can have join selectivity" +msgstr "sadece ikili operatörler join selectivity'sine sahip olabilirler" + +#: catalog/pg_operator.c:374 +#, c-format +msgid "only binary operators can merge join" +msgstr "sadece ikili işlemler merge join edebilirler" + +#: catalog/pg_operator.c:378 +#, c-format +msgid "only binary operators can hash" +msgstr "sadece ikili işlemler hash edebilirler" + +#: catalog/pg_operator.c:389 +#, c-format +msgid "only boolean operators can have negators" +msgstr "sadece boolean operatörleri olumsuzlayıcı ile kullanılabilir" + +#: catalog/pg_operator.c:393 commands/operatorcmds.c:493 +#, c-format +msgid "only boolean operators can have restriction selectivity" +msgstr "sadece boolean operatörler kısıtlama seçiciliğine sahip olabilirler" + +#: catalog/pg_operator.c:397 commands/operatorcmds.c:497 +#, c-format +msgid "only boolean operators can have join selectivity" +msgstr "sadece boolean operatörler join seçiciliğine sahip olabilirler" + +#: catalog/pg_operator.c:401 +#, c-format +msgid "only boolean operators can merge join" +msgstr "sadece boolean operatörler merge join edebilirler" + +#: catalog/pg_operator.c:405 +#, c-format +msgid "only boolean operators can hash" +msgstr "sadece boolean operatörler hash edebilirler" + +#: catalog/pg_operator.c:417 +#, c-format +msgid "operator %s already exists" +msgstr "%s operatörü zaten mevcut" + +#: catalog/pg_operator.c:611 +#, c-format +msgid "operator cannot be its own negator or sort operator" +msgstr "bir işlem, kendisinin zıttı veya kendisinin sort operatörü olamaz" + +#: catalog/pg_proc.c:128 parser/parse_func.c:2122 +#, c-format +msgid "functions cannot have more than %d argument" +msgid_plural "functions cannot have more than %d arguments" +msgstr[0] "bir fonksiyonun arguman sayısı %d sayısından büyük olamaz" +msgstr[1] "bir fonksiyonun arguman sayısı %d sayısından büyük olamaz" + +#: catalog/pg_proc.c:241 +#, c-format +msgid "A function returning a polymorphic type must have at least one polymorphic argument." +msgstr "Polymorphic tipini döndüren fonksiyonlar en az bir polymorphic argüman içermelidir." + +#: catalog/pg_proc.c:248 +#, c-format +msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." +msgstr "\"anyrange\" döndüren fonksiyonlar en az bir \"anyrange\" argümana sahip olmalıdır." + +#: catalog/pg_proc.c:383 +#, c-format +msgid "function \"%s\" already exists with same argument types" +msgstr "\"%s\" fonksiyonu aynı argüman veri tipleriyle zaten mevcut" + +#: catalog/pg_proc.c:393 +#, c-format +msgid "cannot change routine kind" +msgstr "yordam (routine) türü değiştirilemiyor" + +#: catalog/pg_proc.c:395 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" bir toplam (aggregate) fonksiyonudur" + +#: catalog/pg_proc.c:397 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" bir fonksiyondur" + +#: catalog/pg_proc.c:399 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" bir prosedürdür." + +#: catalog/pg_proc.c:401 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\", bir pencere (window) fonksiyonudur" + +#: catalog/pg_proc.c:419 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "bir prosedürün çıktı parametreleri olup olmadığı değiştirilemez" + +#: catalog/pg_proc.c:420 catalog/pg_proc.c:446 +#, c-format +msgid "cannot change return type of existing function" +msgstr "var olan bir fonksiyonun döndürme tipi değiştirilemez" + +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:422 catalog/pg_proc.c:449 catalog/pg_proc.c:494 catalog/pg_proc.c:520 catalog/pg_proc.c:548 +#, c-format +msgid "Use %s %s first." +msgstr "Önce %s %s kullanın." + +#: catalog/pg_proc.c:447 +#, c-format +msgid "Row type defined by OUT parameters is different." +msgstr "OUT parametresinde tanımlanmış Row veri tipi farklıdır." + +#: catalog/pg_proc.c:491 +#, c-format +msgid "cannot change name of input parameter \"%s\"" +msgstr "\"%s\" girdi parametresinin ismi değiştirilemez" + +#: catalog/pg_proc.c:518 +#, c-format +msgid "cannot remove parameter defaults from existing function" +msgstr "var olan bir fonksiyonda parametre varsayılanları kaldırılamaz" + +#: catalog/pg_proc.c:546 +#, c-format +msgid "cannot change data type of existing parameter default value" +msgstr "var olan bir fonksiyonun varsayılan değer veri tipi değiştirilemez" + +#: catalog/pg_proc.c:749 +#, c-format +msgid "there is no built-in function named \"%s\"" +msgstr "\"%s\" adlı gömülü bir fonksiyon yok" + +#: catalog/pg_proc.c:847 +#, c-format +msgid "SQL functions cannot return type %s" +msgstr "SQL fonksiyonları %s tipini dündüremezler" + +#: catalog/pg_proc.c:862 +#, c-format +msgid "SQL functions cannot have arguments of type %s" +msgstr "SQL fonksiyonları %s tipinde argümana sahip olamaz" + +#: catalog/pg_proc.c:950 executor/functions.c:1434 +#, c-format +msgid "SQL function \"%s\"" +msgstr " \"%s\" SQL fonksiyonu" + +#: catalog/pg_publication.c:57 commands/trigger.c:235 commands/trigger.c:253 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" bölümlenmiş bir tablodur" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Adding partitioned tables to publications is not supported." +msgstr "Bölümlenmiş tabloların yayınlara (publication) eklenmesi desteklenmiyor." + +#: catalog/pg_publication.c:60 +#, c-format +msgid "You can add the table partitions individually." +msgstr "Tablo bölümlerini ayrı ayrı ekleyebilirsiniz." + +#: catalog/pg_publication.c:68 +#, c-format +msgid "Only tables can be added to publications." +msgstr "Yayınlara (publicaion) sadece tablolar eklenebilir." + +#: catalog/pg_publication.c:74 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" bir sistem tablosudur" + +#: catalog/pg_publication.c:76 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "Sistem tabloları yayınlara eklenemez" + +#: catalog/pg_publication.c:82 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "\"%s\" tablosu replike edilemiyor" + +#: catalog/pg_publication.c:84 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "Geçici ve loglanmayan ilişkiler (relation) replike edilemez." + +#: catalog/pg_publication.c:175 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "\"%s\" ilişkisi zaten \"%s\" yayınına dahildir" + +#: catalog/pg_publication.c:403 catalog/pg_publication.c:424 commands/publicationcmds.c:415 commands/publicationcmds.c:716 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "\"%s\" yayını mevcut değil" + +#: catalog/pg_shdepend.c:692 +#, c-format +msgid "" +"\n" +"and objects in %d other database (see server log for list)" +msgid_plural "" +"\n" +"and objects in %d other databases (see server log for list)" +msgstr[0] "" +"\n" +"ve %d başka veritabanında nesneler (liste için sunucu log dosyasına bakın)" +msgstr[1] "" +"\n" +"ve %d başka veritabanında nesneler (liste için sunucu log dosyasına bakın)" + +#: catalog/pg_shdepend.c:998 +#, c-format +msgid "role %u was concurrently dropped" +msgstr "%u rolü eşzamanlı kaldırıldı" + +#: catalog/pg_shdepend.c:1017 +#, c-format +msgid "tablespace %u was concurrently dropped" +msgstr "%u tablespace eşzamanlı kaldırıldı" + +#: catalog/pg_shdepend.c:1032 +#, c-format +msgid "database %u was concurrently dropped" +msgstr "%u veritabanı eşzamanlı kaldırıldı" + +#: catalog/pg_shdepend.c:1077 +#, c-format +msgid "owner of %s" +msgstr "%s nesnesinin sahibi" + +#: catalog/pg_shdepend.c:1079 +#, c-format +msgid "privileges for %s" +msgstr "%s için yetkiler" + +#: catalog/pg_shdepend.c:1081 +#, c-format +msgid "target of %s" +msgstr "%s 'nin hedefi" + +#. translator: %s will always be "database %s" +#: catalog/pg_shdepend.c:1089 +#, c-format +msgid "%d object in %s" +msgid_plural "%d objects in %s" +msgstr[0] "%2$s veritabanında %1$d nesne" +msgstr[1] "%2$s veritabanında %1$d nesne" + +#: catalog/pg_shdepend.c:1200 +#, c-format +msgid "cannot drop objects owned by %s because they are required by the database system" +msgstr "veritabanı sistemi tarafından ihtiyaç duyulduğu için %s kaldırılamıyor" + +#: catalog/pg_shdepend.c:1315 +#, c-format +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" +msgstr "veritabanı sistemi tarafından ihtiyaç duyulduğu için %s 'nin sahibi olduğu nesnelerin sahipliği tekrar atanamıyor" + +#: catalog/pg_subscription.c:176 commands/subscriptioncmds.c:633 commands/subscriptioncmds.c:843 commands/subscriptioncmds.c:1067 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "\"%s\" aboneliği mevcut değil" + +#: catalog/pg_type.c:135 catalog/pg_type.c:459 +#, c-format +msgid "pg_type OID value not set when in binary upgrade mode" +msgstr "binary upgrade modda pg_type OID değeri ayarlanmamış" + +#: catalog/pg_type.c:241 +#, c-format +msgid "invalid type internal size %d" +msgstr "tip dahili boyutu geçersiz :%d" + +#: catalog/pg_type.c:257 catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:282 +#, c-format +msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" +msgstr "%2$d boyutundaki passed-by-value tipi için \"%1$c\" hizalanması (alignment) geçersizdir" + +#: catalog/pg_type.c:289 +#, c-format +msgid "internal size %d is invalid for passed-by-value type" +msgstr "passed-by-value tipler için %d dahili boyutu geçersizdir" + +#: catalog/pg_type.c:298 catalog/pg_type.c:304 +#, c-format +msgid "alignment \"%c\" is invalid for variable-length type" +msgstr "passed-by-value tipler için \"%c\" hizalanması (alignment) geçersizdir" + +#: catalog/pg_type.c:312 +#, c-format +msgid "fixed-size types must have storage PLAIN" +msgstr "sabit-boyutlu tipler PLAIN storage özelliği ile tanımlanmalıdır" + +#: catalog/pg_type.c:801 +#, c-format +msgid "could not form array type name for type \"%s\"" +msgstr "\"%s\" tipi için array tipi bulunamıyor" + +#: catalog/toasting.c:105 commands/indexcmds.c:443 commands/tablecmds.c:5016 commands/tablecmds.c:13964 +#, c-format +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\" bir tablo veya maddileştirilmiş görünüm değildir" + +#: catalog/toasting.c:158 +#, c-format +msgid "shared tables cannot be toasted after initdb" +msgstr "initdb işleminden sonra paylaşılmış tablolar toast edilemez" + +#: commands/aggregatecmds.c:166 +#, c-format +msgid "only ordered-set aggregates can be hypothetical" +msgstr "sadece ordered-set toplamları (aggregates) hypothetical olabilir" + +#: commands/aggregatecmds.c:191 +#, c-format +msgid "aggregate attribute \"%s\" not recognized" +msgstr "aggregate parametresi \"%s\" tanınmıyor" + +#: commands/aggregatecmds.c:201 +#, c-format +msgid "aggregate stype must be specified" +msgstr "aggregate stype belirtilmelidir" + +#: commands/aggregatecmds.c:205 +#, c-format +msgid "aggregate sfunc must be specified" +msgstr "aggregate sfunc belirtilmelidir" + +#: commands/aggregatecmds.c:217 +#, c-format +msgid "aggregate msfunc must be specified when mstype is specified" +msgstr "mstype belirtildiği zaman aggregate msfunc belirtilmelidir" + +#: commands/aggregatecmds.c:221 +#, c-format +msgid "aggregate minvfunc must be specified when mstype is specified" +msgstr "mstype belirtildiği zaman aggregate minvfunc belirtilmelidir" + +#: commands/aggregatecmds.c:228 +#, c-format +msgid "aggregate msfunc must not be specified without mstype" +msgstr "mstype olmadan aggregate msfunc belirtilmemelidir" + +#: commands/aggregatecmds.c:232 +#, c-format +msgid "aggregate minvfunc must not be specified without mstype" +msgstr "mstype olmadan aggregate minvfunc belirtilmemelidir" + +#: commands/aggregatecmds.c:236 +#, c-format +msgid "aggregate mfinalfunc must not be specified without mstype" +msgstr "mstype olmadan aggregate mfinalfunc belirtilmemelidir" + +#: commands/aggregatecmds.c:240 +#, c-format +msgid "aggregate msspace must not be specified without mstype" +msgstr "mstype olmadan aggregate msspace belirtilmemelidir" + +#: commands/aggregatecmds.c:244 +#, c-format +msgid "aggregate minitcond must not be specified without mstype" +msgstr "mstype olmadan aggregate minitcond belirtilmemelidir" + +#: commands/aggregatecmds.c:273 +#, c-format +msgid "aggregate input type must be specified" +msgstr "aggregate girdi veri tipi belirtilmelidir" + +#: commands/aggregatecmds.c:303 +#, c-format +msgid "basetype is redundant with aggregate input type specification" +msgstr "aggregate input type specification ile basetype gereksizdir" + +#: commands/aggregatecmds.c:344 commands/aggregatecmds.c:385 +#, c-format +msgid "aggregate transition data type cannot be %s" +msgstr "aggregate transaction veri tipi %s olamaz" + +#: commands/aggregatecmds.c:356 +#, c-format +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "serialization fonksiyonları sadece toplam (aggregate) geçiş veri tipi %s ise belirtilebilir." + +#: commands/aggregatecmds.c:366 +#, c-format +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "serialization ve deserialization fonksiyonları ya ikisi birlikte tanımlanmalı ya da hiçbiri tanımlanmamalı" + +#: commands/aggregatecmds.c:431 commands/functioncmds.c:604 +#, c-format +msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" +msgstr "\"parallel\" parametresi SAFE, RESTRICTED veya UNSAFE olmalı" + +#: commands/aggregatecmds.c:486 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "\"%s\" parametresi READ_ONLY, SHAREABLE, veya READ_WRITE olmalıdır" + +#: commands/alter.c:84 commands/event_trigger.c:236 +#, c-format +msgid "event trigger \"%s\" already exists" +msgstr "\"%s\" olay tetikleyicisi zaten mevcut" + +#: commands/alter.c:87 commands/foreigncmds.c:595 +#, c-format +msgid "foreign-data wrapper \"%s\" already exists" +msgstr "\"%s\" uzak-veri wrapper'i zaten mevcut" + +#: commands/alter.c:90 commands/foreigncmds.c:898 +#, c-format +msgid "server \"%s\" already exists" +msgstr "\"%s\" sunucusu zaten mevcut" + +#: commands/alter.c:93 commands/proclang.c:363 +#, c-format +msgid "language \"%s\" already exists" +msgstr "\"%s\" dili zaten mevcut" + +#: commands/alter.c:96 commands/publicationcmds.c:176 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "\"%s\" yayını (publication) zaten mevcut" + +#: commands/alter.c:99 commands/subscriptioncmds.c:358 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "\"%s\" aboneliği (subscription) zaten mevcut" + +#: commands/alter.c:122 +#, c-format +msgid "conversion \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" dönüşümü zaten \"%s\" şemasında mevcuttur" + +#: commands/alter.c:126 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" istatistik nesnesi zaten \"%s\" şemasında mevcuttur" + +#: commands/alter.c:130 +#, c-format +msgid "text search parser \"%s\" already exists in schema \"%s\"" +msgstr " \"%s\" metin arama ayrıştırıcısı zaten \"%s\" şemasında mevcut" + +#: commands/alter.c:134 +#, c-format +msgid "text search dictionary \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" metin arama sözlüğü zaten \"%s\" şemasında mevcut" + +#: commands/alter.c:138 +#, c-format +msgid "text search template \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" metin arama şablonu zaten \"%s\" şemasında mevcut" + +#: commands/alter.c:142 +#, c-format +msgid "text search configuration \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" metin arama yapılandırması zaten \"%s\" şemasında mevcut" + +#: commands/alter.c:216 +#, c-format +msgid "must be superuser to rename %s" +msgstr "\"%s\" değişkeninin ismini değiştirmek için superuser haklarına sahip olmalısınız" + +#: commands/alter.c:713 +#, c-format +msgid "must be superuser to set schema of %s" +msgstr "%s nin şemasını ayarlamak için superuser olmalısınız" + +#: commands/amcmds.c:58 +#, c-format +msgid "permission denied to create access method \"%s\"" +msgstr "erişim yöntemi \"%s\" oluşturma hatası" + +#: commands/amcmds.c:60 +#, c-format +msgid "Must be superuser to create an access method." +msgstr "Erişim yöntemi oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/amcmds.c:68 +#, c-format +msgid "access method \"%s\" already exists" +msgstr "\"%s\" erişim metodu zaten mevcut" + +#: commands/amcmds.c:123 +#, c-format +msgid "must be superuser to drop access methods" +msgstr "erişim yöntemlerini silmek (drop) için superuser olmalısınız" + +#: commands/amcmds.c:174 commands/indexcmds.c:173 commands/indexcmds.c:583 commands/opclasscmds.c:364 commands/opclasscmds.c:778 +#, c-format +msgid "access method \"%s\" does not exist" +msgstr "\"%s\" erişim metodu mevcut değil" + +#: commands/amcmds.c:250 +#, c-format +msgid "handler function is not specified" +msgstr "işleyici (handler) fonksiyon tanımlanmamış" + +#: commands/amcmds.c:262 commands/event_trigger.c:245 commands/foreigncmds.c:487 commands/proclang.c:116 commands/proclang.c:285 commands/trigger.c:696 parser/parse_clause.c:990 +#, c-format +msgid "function %s must return type %s" +msgstr "%s fonksiyonu %s tipini döndürmeli" + +#: commands/analyze.c:187 +#, c-format +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "\"%s\" için analyze atlanıyor --- kilit kullanılabilir değil" + +#: commands/analyze.c:192 +#, c-format +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "\"%s\" için analyze atlanıyor --- nesne artık mevcut değil" + +#: commands/analyze.c:209 +#, c-format +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "\"%s\" atlanıyor --- sadece superuser onu analiz edebilir" + +#: commands/analyze.c:213 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "\"%s\" atlanıyor --- sadece süper kullanıcı ve veritabanı sahibi onu analiz edebilir" + +#: commands/analyze.c:217 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "\"%s\" atlanıyor --- sadece tablo ve veritabanı sahibi onu analiz edebilir" + +#: commands/analyze.c:275 +#, c-format +msgid "skipping \"%s\" --- cannot analyze this foreign table" +msgstr "\"%s\" atlanıyor --- bu uzak tablo analiz edilemiyor" + +#: commands/analyze.c:292 +#, c-format +msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" +msgstr "\"%s\" atlanıyor --- tablo-olmayan nesneler ya da özel sistem tabloları analiz edilemez" + +#: commands/analyze.c:373 +#, c-format +msgid "analyzing \"%s.%s\" inheritance tree" +msgstr "\"%s.%s\" miras ağacı analiz ediliyor" + +#: commands/analyze.c:378 +#, c-format +msgid "analyzing \"%s.%s\"" +msgstr "\"%s.%s\" analiz ediliyor" + +#: commands/analyze.c:438 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "\"%s\" kolonu \"%s\" tablosunda birden fazla kez görünüyor" + +#: commands/analyze.c:718 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" +msgstr "\"%s.%s.%s\" tablosunun automatic analyze; system kullanımı: %s" + +#: commands/analyze.c:1288 +#, c-format +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "\"%1$s\": %4$.0f canlı ve %5$.0f ölü satırı olan; örneklemede %6$d satır olan, %7$.0f tahmini toplam satır içeren %3$u sayfadan %2$d sayfa taranmıştır" + +#: commands/analyze.c:1368 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" +msgstr "\"%s.%s\" miras ağacının analizi atlanıyor --- bu miras ağacı hiç alt tablo içermiyor" + +#: commands/analyze.c:1466 +#, c-format +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" +msgstr "\"%s.%s\" miras ağacının analizi atlanıyor --- bu miras ağacı hiç analiz edilebilir alt tablo içermiyor" + +#: commands/async.c:558 +#, c-format +msgid "channel name cannot be empty" +msgstr "kanal adı boş olamaz" + +#: commands/async.c:563 +#, c-format +msgid "channel name too long" +msgstr "kanal adı çok uzun" + +#: commands/async.c:570 +#, c-format +msgid "payload string too long" +msgstr "payload dizgisi fazla uzun" + +#: commands/async.c:756 +#, c-format +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgstr "LISTEN, UNLISTEN veya NOTIFY yürütmüş işlem (transaction) PREPARE edilemez" + +#: commands/async.c:859 +#, c-format +msgid "too many notifications in the NOTIFY queue" +msgstr "NOTIFY kuyruğunda çok fazla bildirim" + +#: commands/async.c:1491 +#, c-format +msgid "NOTIFY queue is %.0f%% full" +msgstr "NOTIFY kuyruğu %.0f%% dolu" + +#: commands/async.c:1493 +#, c-format +msgid "The server process with PID %d is among those with the oldest transactions." +msgstr "%d PID'li sunucu süreci en eski işlemliler (transaction) arasında" + +#: commands/async.c:1496 +#, c-format +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." +msgstr "O süreç şimdiki işlemini (transaction) bitirene kadar NOTIFY kuyruğu boşaltılamaz." + +#: commands/cluster.c:129 commands/cluster.c:372 +#, c-format +msgid "cannot cluster temporary tables of other sessions" +msgstr "diğer oturumların geçici tabloları üzerinde cluster yapılamaz" + +#: commands/cluster.c:137 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "bölümlendirilmiş bir tablo üzerinde cluster uygulanamaz" + +#: commands/cluster.c:167 +#, c-format +msgid "there is no previously clustered index for table \"%s\"" +msgstr "\"%s\" tablosunda daha önce cluster edilmiş index yoktur" + +#: commands/cluster.c:181 commands/tablecmds.c:11121 commands/tablecmds.c:13026 +#, c-format +msgid "index \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\"indexi, \"%s\" tablosunda mevcut değil" + +#: commands/cluster.c:361 +#, c-format +msgid "cannot cluster a shared catalog" +msgstr "paylaşılan katalog cluster edilemiyor" + +#: commands/cluster.c:376 +#, c-format +msgid "cannot vacuum temporary tables of other sessions" +msgstr "diğer oturumların geçici tabloları vacuum edilemez" + +#: commands/cluster.c:439 commands/tablecmds.c:13036 +#, c-format +msgid "\"%s\" is not an index for table \"%s\"" +msgstr "\"%s\", \"%s\" tablosunun indexi değildir" + +#: commands/cluster.c:447 +#, c-format +msgid "cannot cluster on index \"%s\" because access method does not support clustering" +msgstr "\"%s\" indexin erişim yöntemi clustering desteklemediği için cluster yapılamaz" + +#: commands/cluster.c:459 +#, c-format +msgid "cannot cluster on partial index \"%s\"" +msgstr "\"%s\" partial index üzerinde cluster yapılamaz" + +#: commands/cluster.c:473 +#, c-format +msgid "cannot cluster on invalid index \"%s\"" +msgstr "\"%s\" geçersiz indexi üzerinde cluster işlemi yapılamaz" + +#: commands/cluster.c:497 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "bölümlenmiş tabloda index clustered olarak işaretlenemez" + +#: commands/cluster.c:938 +#, c-format +msgid "clustering \"%s.%s\" using index scan on \"%s\"" +msgstr "\"%s.%s\" cluster ediliyor (\"%s\" üzerinde indeks taraması kullanılarak)" + +#: commands/cluster.c:944 +#, c-format +msgid "clustering \"%s.%s\" using sequential scan and sort" +msgstr "ardışık tarama ve sıralama kullanılarak \"%s.%s\" cluster ediliyor " + +#: commands/cluster.c:949 commands/vacuumlazy.c:505 +#, c-format +msgid "vacuuming \"%s.%s\"" +msgstr "\"%s.%s\" veritabanına vacuum yapılıyor" + +#: commands/cluster.c:1106 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "\"%s\": bulunan %.0f kaldırılabilen, %.0f sabit satır sürümleri, toplam %u sayfa" + +#: commands/cluster.c:1110 +#, c-format +msgid "" +"%.0f dead row versions cannot be removed yet.\n" +"%s." +msgstr "" +"%.0f ölü satır sürümleri henüz kaldırılamıyor.\n" +"%s." + +#: commands/collationcmds.c:100 +#, c-format +msgid "collation attribute \"%s\" not recognized" +msgstr "\"%s\" karşılaştırma özniteliği tanınmamaktadır" + +#: commands/collationcmds.c:142 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "karşılaştırma (collation) \"varsayılan\"ı kopyalanamaz" + +#: commands/collationcmds.c:172 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "bilinmeyen karşılaştırma (collation) sağlayıcısı. %s" + +#: commands/collationcmds.c:181 +#, c-format +msgid "parameter \"lc_collate\" must be specified" +msgstr "\"lc_collate\" parametresi belirtilmelidir" + +#: commands/collationcmds.c:186 +#, c-format +msgid "parameter \"lc_ctype\" must be specified" +msgstr "\"lc_ctype\" parametresi belirtilmelidir" + +#: commands/collationcmds.c:245 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" +msgstr "\"%2$s\" kodlaması için \"%1$s\" karşılaştırması (collation) zaten \"%3$s\" şemasında mevcuttur" + +#: commands/collationcmds.c:256 +#, c-format +msgid "collation \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" karşılaştırması (collation) zaten \"%s\" şemasında mevcuttur" + +#: commands/collationcmds.c:304 +#, c-format +msgid "changing version from %s to %s" +msgstr "sürüm %s 'den tipi %s 'ye değiştiriliyor" + +#: commands/collationcmds.c:319 +#, c-format +msgid "version has not changed" +msgstr "sürüm değiştirilmedi" + +#: commands/collationcmds.c:450 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr " \"%s\" yerel ayar adı dil etiketine dönüştürlemedi: %s" + +#: commands/collationcmds.c:511 +#, c-format +msgid "must be superuser to import system collations" +msgstr "sistem karşılaştırmalarını (collation) içeri aktarmak için superuser olmalısınız" + +#: commands/collationcmds.c:534 commands/copy.c:1844 commands/copy.c:3181 libpq/be-secure-common.c:80 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" komutu yürütülemedi: %m" + +#: commands/collationcmds.c:665 +#, c-format +msgid "no usable system locales were found" +msgstr "kullanılabilir sistem yerelleri bulunamadı" + +#: commands/comment.c:61 commands/dbcommands.c:808 commands/dbcommands.c:996 commands/dbcommands.c:1100 commands/dbcommands.c:1290 commands/dbcommands.c:1513 commands/dbcommands.c:1627 commands/dbcommands.c:2043 utils/init/postinit.c:853 utils/init/postinit.c:958 utils/init/postinit.c:975 +#, c-format +msgid "database \"%s\" does not exist" +msgstr "\"%s\" veritabanı mevcut değil" + +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:925 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" +msgstr "\"%s\" bir tablo, görünüm, maddileştirilmiş görünüm, birleşik tip ya da uzak tablo değildir" + +#: commands/constraint.c:60 utils/adt/ri_triggers.c:2256 +#, c-format +msgid "function \"%s\" was not called by trigger manager" +msgstr "\"%s\" fonksiyonu trigger yöneticisi tarafından çağırılmamıştır" + +#: commands/constraint.c:67 utils/adt/ri_triggers.c:2265 +#, c-format +msgid "function \"%s\" must be fired AFTER ROW" +msgstr "\"%s\" fonksiyonu AFTER ROW olarak çalıştırılmalıdır" + +#: commands/constraint.c:81 +#, c-format +msgid "function \"%s\" must be fired for INSERT or UPDATE" +msgstr "\"%s\" fonksiyonu INSERT veya UPDATE için çalıştırılmalıdır" + +#: commands/conversioncmds.c:65 +#, c-format +msgid "source encoding \"%s\" does not exist" +msgstr "\"%s\" kaynak dil kodlaması mevcut değil" + +#: commands/conversioncmds.c:72 +#, c-format +msgid "destination encoding \"%s\" does not exist" +msgstr "\"%s\" hedef dil kodlaması mevcut değil" + +#: commands/conversioncmds.c:86 +#, c-format +msgid "encoding conversion function %s must return type %s" +msgstr "%s kodlama dönüşüm fonksiyonu %s tipini döndürmelidir" + +#: commands/copy.c:374 commands/copy.c:408 +#, c-format +msgid "COPY BINARY is not supported to stdout or from stdin" +msgstr "stdin'den stdout'e COPY BINARY desteklenmemektedir" + +#: commands/copy.c:508 +#, c-format +msgid "could not write to COPY program: %m" +msgstr "COPY programına yazma hatası: %m" + +#: commands/copy.c:513 +#, c-format +msgid "could not write to COPY file: %m" +msgstr "COPY dosyasına yazma hatası: %m" + +#: commands/copy.c:526 +#, c-format +msgid "connection lost during COPY to stdout" +msgstr "stdout akımına COPY işlemi sırasında bağlantı kesildi" + +#: commands/copy.c:570 +#, c-format +msgid "could not read from COPY file: %m" +msgstr "COPY dosyasından okuma hatası: %m" + +#: commands/copy.c:588 commands/copy.c:609 commands/copy.c:613 tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 +#, c-format +msgid "unexpected EOF on client connection with an open transaction" +msgstr "açık işlemi (transaction) olan istemci bağlantısında beklenmeyen EOF" + +#: commands/copy.c:626 +#, c-format +msgid "COPY from stdin failed: %s" +msgstr "stdin'den COPY başarısız: %s" + +#: commands/copy.c:642 +#, c-format +msgid "unexpected message type 0x%02X during COPY from stdin" +msgstr "stdin akımından COPY işlemi sırasında beklenmeyen mesaj tipi 0x%02X" + +#: commands/copy.c:808 +#, c-format +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "dış programa veya dış programdan COPY işlemi yapmak için superuser ya da pg_execute_server_program rolünün bir üyesi olmalısınız" + +#: commands/copy.c:809 commands/copy.c:818 commands/copy.c:825 +#, c-format +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "Stdout'e ve stdin'e her kullanıcı COPY işlemi yapabilir. Ayrıca her kullanıcı psql'in \\copy komutunu kullanabilir." + +#: commands/copy.c:817 +#, c-format +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "bir dosyadan COPY yapmak için superuser ya da pg_read_server_files rolüne üye olmalısınız" + +#: commands/copy.c:824 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "bir dosyaya COPY yapmak için superuser ya da pg_write_server_files rolüne üye olmalısınız" + +#: commands/copy.c:887 +#, c-format +msgid "COPY FROM not supported with row-level security" +msgstr "COPY FROM satır-seviyesi güvenliğiyle desteklenmiyor" + +#: commands/copy.c:888 +#, c-format +msgid "Use INSERT statements instead." +msgstr "Bunun yerine INSERT ifadeleri kullanın." + +#: commands/copy.c:1075 +#, c-format +msgid "COPY format \"%s\" not recognized" +msgstr "COPY formatı \"%s\" tanınmamaktadır" + +#: commands/copy.c:1155 commands/copy.c:1171 commands/copy.c:1186 commands/copy.c:1208 +#, c-format +msgid "argument to option \"%s\" must be a list of column names" +msgstr "\"%s\" seçeneği için argüman bir sütun isimleri listesi olmalıdır" + +#: commands/copy.c:1223 +#, c-format +msgid "argument to option \"%s\" must be a valid encoding name" +msgstr "%s seçeneği için argüman geçerli bir kodlama ismi olmalıdır" + +#: commands/copy.c:1230 commands/dbcommands.c:242 commands/dbcommands.c:1461 +#, c-format +msgid "option \"%s\" not recognized" +msgstr "\"%s\" seçeneği tanımlanamadı" + +#: commands/copy.c:1242 +#, c-format +msgid "cannot specify DELIMITER in BINARY mode" +msgstr "BINARY biçiminde DELIMITER belirtilemez" + +#: commands/copy.c:1247 +#, c-format +msgid "cannot specify NULL in BINARY mode" +msgstr "BINARY biçiminde NULL belirtilemez" + +#: commands/copy.c:1269 +#, c-format +msgid "COPY delimiter must be a single one-byte character" +msgstr "COPY ayıracı bir baytlık tek bir karakter olmalıdır" + +#: commands/copy.c:1276 +#, c-format +msgid "COPY delimiter cannot be newline or carriage return" +msgstr "COPY ayıracı yeni satır ya da satırbaşı karakteri olamaz" + +#: commands/copy.c:1282 +#, c-format +msgid "COPY null representation cannot use newline or carriage return" +msgstr "COPY null betimlemesi yeni satır veya satırbaşı karakteri kullanamaz" + +#: commands/copy.c:1299 +#, c-format +msgid "COPY delimiter cannot be \"%s\"" +msgstr "COPY ayıracı \"%s\" olamaz" + +#: commands/copy.c:1305 +#, c-format +msgid "COPY HEADER available only in CSV mode" +msgstr "COPY HEADER sadece CSV modunda geçerli" + +#: commands/copy.c:1311 +#, c-format +msgid "COPY quote available only in CSV mode" +msgstr "COPY quote sadece CSV modunda etkin" + +#: commands/copy.c:1316 +#, c-format +msgid "COPY quote must be a single one-byte character" +msgstr "COPY quote bir baytlık tek bir karakter olmalıdır" + +#: commands/copy.c:1321 +#, c-format +msgid "COPY delimiter and quote must be different" +msgstr "COPY ayıracı ve alıntısı farklı olmalı" + +#: commands/copy.c:1327 +#, c-format +msgid "COPY escape available only in CSV mode" +msgstr "COPY escape sadece CSV modunda kullanılabilir" + +#: commands/copy.c:1332 +#, c-format +msgid "COPY escape must be a single one-byte character" +msgstr "COPY escape bir baytlık tek bir karakter olmalıdır" + +#: commands/copy.c:1338 +#, c-format +msgid "COPY force quote available only in CSV mode" +msgstr "COPY force quote sadece CSV modunda kullanılabilir" + +#: commands/copy.c:1342 +#, c-format +msgid "COPY force quote only available using COPY TO" +msgstr "COPY force quote sadece COPY TO içerisinde kullanılabilir" + +#: commands/copy.c:1348 +#, c-format +msgid "COPY force not null available only in CSV mode" +msgstr "COPY force not null sadece CSV modunda kullanılabilir" + +#: commands/copy.c:1352 +#, c-format +msgid "COPY force not null only available using COPY FROM" +msgstr "COPY force not null only sadece COPY FROM içerisinde kullanılabilir" + +#: commands/copy.c:1358 +#, c-format +msgid "COPY force null available only in CSV mode" +msgstr "COPY force null sadece CSV modunda kullanılabilir" + +#: commands/copy.c:1363 +#, c-format +msgid "COPY force null only available using COPY FROM" +msgstr "COPY force null sadece COPY FROM içerisinde kullanılabilir" + +#: commands/copy.c:1369 +#, c-format +msgid "COPY delimiter must not appear in the NULL specification" +msgstr "NULL tanımında COPY ayracı belirtilmemelidir" + +#: commands/copy.c:1376 +#, c-format +msgid "CSV quote character must not appear in the NULL specification" +msgstr "NULL tanımında CVS quote ayracı belirtilmemelidir" + +#: commands/copy.c:1437 +#, c-format +msgid "table \"%s\" does not have OIDs" +msgstr "\"%s\" tablosunda OID yoktur" + +#: commands/copy.c:1454 +#, c-format +msgid "COPY (query) WITH OIDS is not supported" +msgstr "COPY (sorgu) WITH OIDS desteklenmemektedir" + +#: commands/copy.c:1475 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for COPY" +msgstr "DO INSTEAD NOTHING kuralları COPY için desteklenmemektedir" + +#: commands/copy.c:1489 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for COPY" +msgstr "şartlı DO INSTEAD kuralları COPY için desteklenmemektedir" + +#: commands/copy.c:1493 +#, c-format +msgid "DO ALSO rules are not supported for the COPY" +msgstr "DO ALSO kuralları COPY için desteklenmemektedir" + +#: commands/copy.c:1498 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for COPY" +msgstr "çok-ifadeli DO INSTEAD kuralları COPY için desteklenmemektedir" + +#: commands/copy.c:1508 +#, c-format +msgid "COPY (SELECT INTO) is not supported" +msgstr "COPY (SELECT INTO) desteklenmemektedir" + +#: commands/copy.c:1525 +#, c-format +msgid "COPY query must have a RETURNING clause" +msgstr "COPY sorgusunun bir RETURNING ifadesi olmalıdır" + +#: commands/copy.c:1553 +#, c-format +msgid "relation referenced by COPY statement has changed" +msgstr "COPY ifadesi tarafından referans edilen ilişki (relation) değişmiş" + +#: commands/copy.c:1612 +#, c-format +msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" +msgstr "FORCE_QUOTE sütunu \"%s\" COPY tarafından referans edilmemiştir" + +#: commands/copy.c:1635 +#, c-format +msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NOT_NULL sütunu \"%s\" COPY tarafından referans edilmemiştir" + +#: commands/copy.c:1658 +#, c-format +msgid "FORCE_NULL column \"%s\" not referenced by COPY" +msgstr "FORCE_NULL sütunu \"%s\" COPY tarafından referans edilmemiştir" + +#: commands/copy.c:1724 libpq/be-secure-common.c:102 +#, c-format +msgid "could not close pipe to external command: %m" +msgstr "dış komuta doğru olan pipe kapatılamadı: %m" + +#: commands/copy.c:1739 +#, c-format +msgid "program \"%s\" failed" +msgstr "\"%s\" programı başarısız oldu" + +#: commands/copy.c:1790 +#, c-format +msgid "cannot copy from view \"%s\"" +msgstr "\"%s\" view'undan kopyalanamıyor" + +#: commands/copy.c:1792 commands/copy.c:1798 commands/copy.c:1804 commands/copy.c:1815 +#, c-format +msgid "Try the COPY (SELECT ...) TO variant." +msgstr "COPY (SELECT ...) TO variant deyimini deneyin." + +#: commands/copy.c:1796 +#, c-format +msgid "cannot copy from materialized view \"%s\"" +msgstr "\"%s\" maddeleştirilmiş görünümünden kopyalanamıyor" + +#: commands/copy.c:1802 +#, c-format +msgid "cannot copy from foreign table \"%s\"" +msgstr "\"%s\" uzak tablosundan kopyalanamıyor" + +#: commands/copy.c:1808 +#, c-format +msgid "cannot copy from sequence \"%s\"" +msgstr "\"%s\" sequence'inden kopyalanamıyor" + +#: commands/copy.c:1813 +#, c-format +msgid "cannot copy from partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosundan kopyalanamıyor" + +#: commands/copy.c:1819 +#, c-format +msgid "cannot copy from non-table relation \"%s\"" +msgstr "\"%s\" tablo olmayan nesnesinden copy yapılamıyor" + +#: commands/copy.c:1859 +#, c-format +msgid "relative path not allowed for COPY to file" +msgstr "COPY işlemi ile dosyaya yazarken dosyanın tam yolunu belirtmelisiniz" + +#: commands/copy.c:1880 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "\"%s\" dosyası, yazmak için açılamadı: %m" + +#: commands/copy.c:1883 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO PostgreSQL sunucu sürecine bir dosyaya yazma talimatı veriyor. psql'in \\copy 'si gibi bir istemci-tarafı aracını kullanmayı düşünebilirsiniz." + +#: commands/copy.c:1896 commands/copy.c:3212 +#, c-format +msgid "\"%s\" is a directory" +msgstr "\"%s\" bir dizindir" + +#: commands/copy.c:2222 +#, c-format +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, satır %s, sütun %s" + +#: commands/copy.c:2226 commands/copy.c:2273 +#, c-format +msgid "COPY %s, line %s" +msgstr "COPY %s, satır %s" + +#: commands/copy.c:2237 +#, c-format +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, satır %s, sütun %s: \"%s\"" + +#: commands/copy.c:2245 +#, c-format +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, satır %s, sütun %s: null girişi" + +#: commands/copy.c:2267 +#, c-format +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, satır %s: \"%s\"" + +#: commands/copy.c:2363 +#, c-format +msgid "cannot copy to view \"%s\"" +msgstr "\"%s\" view'ina kopyalanamıyor" + +#: commands/copy.c:2365 +#, c-format +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "Bir görünüme kopyalamayı etkinleştirmek için, bir INSTEAD OF INSERT tetikleyicisi oluşturulmalı." + +#: commands/copy.c:2369 +#, c-format +msgid "cannot copy to materialized view \"%s\"" +msgstr "\"%s\" maddeleştirilmiş görünümüne kopyalanamıyor" + +#: commands/copy.c:2374 +#, c-format +msgid "cannot copy to sequence \"%s\"" +msgstr "\"%s\" sequence'ine kopyalanamıyor" + +#: commands/copy.c:2379 +#, c-format +msgid "cannot copy to non-table relation \"%s\"" +msgstr "tablo olmayan \"%s\" nesnesi kopyalanamaz" + +#: commands/copy.c:2471 +#, c-format +msgid "cannot perform FREEZE on a partitioned table" +msgstr "bölümlendirilmiş bir tablo üzerinde FREEZE gerçekleştirilemez" + +#: commands/copy.c:2486 +#, c-format +msgid "cannot perform FREEZE because of prior transaction activity" +msgstr "önceki işlem (transaction) etkinliğinden dolayı FREEZE gerçekleştirilemiyor" + +#: commands/copy.c:2492 +#, c-format +msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" +msgstr "tablo oluşturulmadığı ya da geçerli alt-işlemde (subtransaction) boşaltıldığı (truncate) için FREEZE gerçekleştirilemiyor" + +#: commands/copy.c:3199 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROM PostgreSQL sunucu sürecine bir dosyayı okuma talimatı veriyor. psql'in \\copy 'si gibi bir istemci-tarafı aracını kullanmayı düşünebilirsiniz." + +#: commands/copy.c:3232 +#, c-format +msgid "COPY file signature not recognized" +msgstr "COPY dosya imzası tanınmamaktadır" + +#: commands/copy.c:3237 +#, c-format +msgid "invalid COPY file header (missing flags)" +msgstr "COPY dosya başlığı geçersiz (flagler eksik)" + +#: commands/copy.c:3243 +#, c-format +msgid "unrecognized critical flags in COPY file header" +msgstr "COPY dosya başlığında tanınmayan flag" + +#: commands/copy.c:3249 +#, c-format +msgid "invalid COPY file header (missing length)" +msgstr "COPY dosya başlığı geçersiz (uzunluklar eksik)" + +#: commands/copy.c:3256 +#, c-format +msgid "invalid COPY file header (wrong length)" +msgstr "geçersiz COPY dosya başlığı (yanlış uzunluk)" + +#: commands/copy.c:3387 commands/copy.c:4096 commands/copy.c:4326 +#, c-format +msgid "extra data after last expected column" +msgstr "son beklenen sütundan sonra fazladan veri bulundu" + +#: commands/copy.c:3397 +#, c-format +msgid "missing data for OID column" +msgstr "OID sütunu için veri eksik" + +#: commands/copy.c:3403 +#, c-format +msgid "null OID in COPY data" +msgstr "COPY verisinde null OID" + +#: commands/copy.c:3413 commands/copy.c:3537 +#, c-format +msgid "invalid OID in COPY data" +msgstr "COPY verisinde geçersiz OID" + +#: commands/copy.c:3429 +#, c-format +msgid "missing data for column \"%s\"" +msgstr "\"%s\" sütunu için veri eksik" + +#: commands/copy.c:3512 +#, c-format +msgid "received copy data after EOF marker" +msgstr "EOF işaretleyicisinden sonra copy data alındı" + +#: commands/copy.c:3519 +#, c-format +msgid "row field count is %d, expected %d" +msgstr "satır alanı sayısı %d, beklenen %d" + +#: commands/copy.c:3860 commands/copy.c:3877 +#, c-format +msgid "literal carriage return found in data" +msgstr "veride satır sonu karakterine rastlanmıştır" + +#: commands/copy.c:3861 commands/copy.c:3878 +#, c-format +msgid "unquoted carriage return found in data" +msgstr "veride tırnak içine alınmamış satır sonu karakterine rastlanmıştır" + +#: commands/copy.c:3863 commands/copy.c:3880 +#, c-format +msgid "Use \"\\r\" to represent carriage return." +msgstr "Satır sonu karakteri için \"\\r\" kullanın." + +#: commands/copy.c:3864 commands/copy.c:3881 +#, c-format +msgid "Use quoted CSV field to represent carriage return." +msgstr "Satır sonu karakteri için tırnak içine alınmış CSV alanı kullanın." + +#: commands/copy.c:3893 +#, c-format +msgid "literal newline found in data" +msgstr "veri içerisinde yeni satır karakteri bulundu" + +#: commands/copy.c:3894 +#, c-format +msgid "unquoted newline found in data" +msgstr "veri içerisinde tırnak içine alınmamış satırbaşı" + +#: commands/copy.c:3896 +#, c-format +msgid "Use \"\\n\" to represent newline." +msgstr "Yeni satır karakteri için \"\\n\" kullanın." + +#: commands/copy.c:3897 +#, c-format +msgid "Use quoted CSV field to represent newline." +msgstr "Yeni satır belirtmek için tırnak içine alınmış CSV kullanın" + +#: commands/copy.c:3943 commands/copy.c:3979 +#, c-format +msgid "end-of-copy marker does not match previous newline style" +msgstr "end-of-copy göstergesi önceki yeni satır stiline uymuyor" + +#: commands/copy.c:3952 commands/copy.c:3968 +#, c-format +msgid "end-of-copy marker corrupt" +msgstr "end-of-copy göstergesi zarar görmüş" + +#: commands/copy.c:4410 +#, c-format +msgid "unterminated CSV quoted field" +msgstr "sonlandırılmamış CSV quoted alanı" + +#: commands/copy.c:4487 commands/copy.c:4506 +#, c-format +msgid "unexpected EOF in COPY data" +msgstr "COPY verisinde beklenmeyen dosya sonu" + +#: commands/copy.c:4496 +#, c-format +msgid "invalid field size" +msgstr "geçersiz alan boyutu" + +#: commands/copy.c:4519 +#, c-format +msgid "incorrect binary data format" +msgstr "ikili veri biçimi hatası" + +#: commands/copy.c:4831 commands/indexcmds.c:1473 commands/statscmds.c:206 commands/tablecmds.c:1910 commands/tablecmds.c:2467 commands/tablecmds.c:2848 parser/parse_relation.c:3288 parser/parse_relation.c:3308 utils/adt/tsvector_op.c:2561 +#, c-format +msgid "column \"%s\" does not exist" +msgstr "\"%s\" sütunu mevcut değil" + +#: commands/copy.c:4838 commands/tablecmds.c:1937 commands/trigger.c:913 parser/parse_target.c:1046 parser/parse_target.c:1057 +#, c-format +msgid "column \"%s\" specified more than once" +msgstr "\"%s\" sütunu birden fazla belirtilmiş" + +#: commands/createas.c:213 commands/createas.c:509 +#, c-format +msgid "too many column names were specified" +msgstr "çok fazla sütun ismi belirtilmiş" + +#: commands/createas.c:550 +#, c-format +msgid "policies not yet implemented for this command" +msgstr "bu komut için politikalar henüz implemente edilmemiştir" + +#: commands/dbcommands.c:235 +#, c-format +msgid "LOCATION is not supported anymore" +msgstr "LOCATION artık desteklenmiyor" + +#: commands/dbcommands.c:236 +#, c-format +msgid "Consider using tablespaces instead." +msgstr "Onun yerine tablespace kullanabilirsiniz." + +#: commands/dbcommands.c:262 utils/adt/ascii.c:145 +#, c-format +msgid "%d is not a valid encoding code" +msgstr "%d geçerli bir dil kodlaması değildir" + +#: commands/dbcommands.c:273 utils/adt/ascii.c:127 +#, c-format +msgid "%s is not a valid encoding name" +msgstr "%s geçerli bir dil kodlaması adı değildir" + +#: commands/dbcommands.c:292 commands/dbcommands.c:1494 commands/user.c:276 commands/user.c:664 +#, c-format +msgid "invalid connection limit: %d" +msgstr "geçersiz bağlantı sayısı sınırı: %d" + +#: commands/dbcommands.c:311 +#, c-format +msgid "permission denied to create database" +msgstr "veritabanı oluşturma izin verilmedi." + +#: commands/dbcommands.c:334 +#, c-format +msgid "template database \"%s\" does not exist" +msgstr "\"%s\" şablon veritabanı mevcut değil" + +#: commands/dbcommands.c:346 +#, c-format +msgid "permission denied to copy database \"%s\"" +msgstr "\"%s\" veritabanını kopyalama engellendi" + +#: commands/dbcommands.c:362 +#, c-format +msgid "invalid server encoding %d" +msgstr "%d sunucu dil kodlaması geçersiz" + +#: commands/dbcommands.c:368 commands/dbcommands.c:373 +#, c-format +msgid "invalid locale name: \"%s\"" +msgstr "geçersiz yerel ayar adı: \"%s\"" + +#: commands/dbcommands.c:393 +#, c-format +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" +msgstr "yeni (%s) dil kodlaması şablon (template) veritabanının dil kodlaması (%s) ile uyumlu değil" + +#: commands/dbcommands.c:396 +#, c-format +msgid "Use the same encoding as in the template database, or use template0 as template." +msgstr "Şablon veritabanındakiyle aynı dil kodlamasını kullanın veya şablon olarak template0 kullanın." + +#: commands/dbcommands.c:401 +#, c-format +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" +msgstr "yeni (%s) karşılaştırması (collation) şablon veritabanının karşılaştırmasıyla (%s) uyumlu değil" + +#: commands/dbcommands.c:403 +#, c-format +msgid "Use the same collation as in the template database, or use template0 as template." +msgstr "Şablon veritabanındakiyle aynı karşılaştırmayı (collation) kullanın veya şablon olarak template0 kullanın." + +#: commands/dbcommands.c:408 +#, c-format +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" +msgstr "yeni LC_TYPE (%s) şablon (template) veritabanının LC_TYPE (%s) ile uyumsuz" + +#: commands/dbcommands.c:410 +#, c-format +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." +msgstr "Ya şablon veritabanındaki ile aynı LC_TYPE kullanın, ya da şablon olarak template0'ı kullanın." + +#: commands/dbcommands.c:432 commands/dbcommands.c:1146 +#, c-format +msgid "pg_global cannot be used as default tablespace" +msgstr "pg_global öntanımlı tablespace olarak kullanılamaz" + +#: commands/dbcommands.c:458 +#, c-format +msgid "cannot assign new default tablespace \"%s\"" +msgstr "yeni varsayılan tablespace \"%s\" atanamıyor" + +#: commands/dbcommands.c:460 +#, c-format +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." +msgstr "Bir çakışma var, çünkü \"%s\" veritabanının bulunduğu tablespace içinde başka tablolar var." + +#: commands/dbcommands.c:480 commands/dbcommands.c:1016 +#, c-format +msgid "database \"%s\" already exists" +msgstr "\"%s\" veritabanı zaten mevcut" + +#: commands/dbcommands.c:494 +#, c-format +msgid "source database \"%s\" is being accessed by other users" +msgstr "\"%s\" kaynak veritabanı başka bir kullanıcı tarafından kullanılmaktadır" + +#: commands/dbcommands.c:736 commands/dbcommands.c:751 +#, c-format +msgid "encoding \"%s\" does not match locale \"%s\"" +msgstr "\"%s\" dil kodlaması, \"%s\" sunucu yereli ile eşleşmiyor" + +#: commands/dbcommands.c:739 +#, c-format +msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." +msgstr "Seçilen LC_TYPE ayarı, \"%s\" dil kodlamasını gerektirir." + +#: commands/dbcommands.c:754 +#, c-format +msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." +msgstr "Sunucunun LC_COLLATE yerel ayarı, %s dil kodlamasını gerektirir." + +#: commands/dbcommands.c:815 +#, c-format +msgid "database \"%s\" does not exist, skipping" +msgstr "\"%s\" veritabanı mevcut değil, atlanıyor" + +#: commands/dbcommands.c:839 +#, c-format +msgid "cannot drop a template database" +msgstr "template veritabanı kaldırılamaz" + +#: commands/dbcommands.c:845 +#, c-format +msgid "cannot drop the currently open database" +msgstr "şu anda açık olan veritabanı kaldırılamaz" + +#: commands/dbcommands.c:858 +#, c-format +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "\"%s\" veritabanı aktif bir mantıksal replikasyon slot'u tarafından kullanılıyor" + +#: commands/dbcommands.c:860 +#, c-format +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "%d aktif slot mevcut." +msgstr[1] "%d aktif slot mevcut." + +#: commands/dbcommands.c:874 commands/dbcommands.c:1038 commands/dbcommands.c:1168 +#, c-format +msgid "database \"%s\" is being accessed by other users" +msgstr "\"%s\" veritabanına başka kullanıcılar tarafından erişilmektedir" + +#: commands/dbcommands.c:887 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "\"%s\" veritabanı mantıksal replikasyon aboneliği tarafından kullanılıyor" + +#: commands/dbcommands.c:889 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "%d abonelik (subscription) var" +msgstr[1] "%d abonelik (subscription) var" + +#: commands/dbcommands.c:1007 +#, c-format +msgid "permission denied to rename database" +msgstr "veritabanı adı değiştirilmesine izin verilmedi" + +#: commands/dbcommands.c:1027 +#, c-format +msgid "current database cannot be renamed" +msgstr "geçerli veritabanının adını değiştirilemez" + +#: commands/dbcommands.c:1124 +#, c-format +msgid "cannot change the tablespace of the currently open database" +msgstr "şu anda açık olan veritabanında tablespace değişikliği yapılamaz" + +#: commands/dbcommands.c:1227 +#, c-format +msgid "some relations of database \"%s\" are already in tablespace \"%s\"" +msgstr "\"%s\" veritabanının bazı nesneleri zaten \"%s\" tablespace'indedir " + +#: commands/dbcommands.c:1229 +#, c-format +msgid "You must move them back to the database's default tablespace before using this command." +msgstr "Bu komutu kullanmadan önce onları veritabanının varsayılan tablespace'ine geri taşımalısınız." + +#: commands/dbcommands.c:1355 commands/dbcommands.c:1900 commands/dbcommands.c:2104 commands/dbcommands.c:2159 commands/tablespace.c:606 +#, c-format +msgid "some useless files may be left behind in old database directory \"%s\"" +msgstr "\"%s\" eski veritabanı dizininde bazı gereksiz dosyalar kalabilir" + +#: commands/dbcommands.c:1475 +#, c-format +msgid "option \"%s\" cannot be specified with other options" +msgstr "\"%s\" seçeneği diğer seçeneklerle beraber belirtilemez" + +#: commands/dbcommands.c:1530 +#, c-format +msgid "cannot disallow connections for current database" +msgstr "geçerli veritabanı için bağlantılara izin vermemek mümkün değil " + +#: commands/dbcommands.c:1667 +#, c-format +msgid "permission denied to change owner of database" +msgstr "veritabanı sahipliğini değiştirilmesine izin verilmedi" + +#: commands/dbcommands.c:1987 +#, c-format +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." +msgstr "Veritabanını kullanan %d başka oturum ve %d hazırlanmış işlem (transaction) var." + +#: commands/dbcommands.c:1990 +#, c-format +msgid "There is %d other session using the database." +msgid_plural "There are %d other sessions using the database." +msgstr[0] "Veritabanını kullanan %d başka oturum var." +msgstr[1] "Veritabanını kullanan %d başka oturum var." + +#: commands/dbcommands.c:1995 +#, c-format +msgid "There is %d prepared transaction using the database." +msgid_plural "There are %d prepared transactions using the database." +msgstr[0] "Veritabanını kullanan %d hazırlanmış işlem (transaction) var." +msgstr[1] "Veritabanını kullanan %d hazırlanmış işlem (transaction) var." + +#: commands/define.c:54 commands/define.c:228 commands/define.c:260 commands/define.c:288 commands/define.c:334 +#, c-format +msgid "%s requires a parameter" +msgstr "%s bir parametre gerektirir" + +#: commands/define.c:90 commands/define.c:101 commands/define.c:195 commands/define.c:213 +#, c-format +msgid "%s requires a numeric value" +msgstr "%s seçeneği sayısal değer gerektirir" + +#: commands/define.c:157 +#, c-format +msgid "%s requires a Boolean value" +msgstr "%s, bir Boolean değeri gerektirir" + +#: commands/define.c:171 commands/define.c:180 commands/define.c:297 +#, c-format +msgid "%s requires an integer value" +msgstr "%s bir tamsayı gerektirir" + +#: commands/define.c:242 +#, c-format +msgid "argument of %s must be a name" +msgstr "%s için argüman bir ad olmalıdır" + +#: commands/define.c:272 +#, c-format +msgid "argument of %s must be a type name" +msgstr "%s argümanı tip adı olmalıdır" + +#: commands/define.c:318 +#, c-format +msgid "invalid argument for %s: \"%s\"" +msgstr "%s için geçersiz argüman: \"%s\"" + +#: commands/dropcmds.c:99 commands/functioncmds.c:1212 utils/adt/ruleutils.c:2564 +#, c-format +msgid "\"%s\" is an aggregate function" +msgstr "\"%s\" fonksiyonu bir aggregate fonksiyonudur" + +#: commands/dropcmds.c:101 +#, c-format +msgid "Use DROP AGGREGATE to drop aggregate functions." +msgstr "Aggregate fonksiyonunı kaldırmak içim DROP AGGREGATE kullanın." + +#: commands/dropcmds.c:157 commands/sequence.c:440 commands/tablecmds.c:2932 commands/tablecmds.c:3090 commands/tablecmds.c:3133 commands/tablecmds.c:13409 tcop/utility.c:1163 +#, c-format +msgid "relation \"%s\" does not exist, skipping" +msgstr "\"%s\" nesnesi mevcut değil, atlanıyor" + +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1022 +#, c-format +msgid "schema \"%s\" does not exist, skipping" +msgstr "\"%s\" şeması mevcut değil, atlanıyor" + +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:254 +#, c-format +msgid "type \"%s\" does not exist, skipping" +msgstr "\"%s\" tipi mevcut değil, atlanıyor" + +#: commands/dropcmds.c:256 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "\"%s\" erişim metodu mevcut değil, atlanıyor" + +#: commands/dropcmds.c:274 +#, c-format +msgid "collation \"%s\" does not exist, skipping" +msgstr "\"%s\" karşılaştırması (collation) mevcut değil, atlanıyor" + +#: commands/dropcmds.c:281 +#, c-format +msgid "conversion \"%s\" does not exist, skipping" +msgstr "\"%s\" dönüşümü mevcut değil, atlanıyor" + +#: commands/dropcmds.c:292 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "\"%s\" istatistik nesnesi mevcut değil, atlanıyor" + +#: commands/dropcmds.c:299 +#, c-format +msgid "text search parser \"%s\" does not exist, skipping" +msgstr " \"%s\" metin arama ayrıştırıcısı mevcut değil, atlanıyor" + +#: commands/dropcmds.c:306 +#, c-format +msgid "text search dictionary \"%s\" does not exist, skipping" +msgstr "\"%s\" metin arama sözlüğü mevcut değil, atlanıyor" + +#: commands/dropcmds.c:313 +#, c-format +msgid "text search template \"%s\" does not exist, skipping" +msgstr "\"%s\" metin arama şablonu mevcut değil, atlanıyor" + +#: commands/dropcmds.c:320 +#, c-format +msgid "text search configuration \"%s\" does not exist, skipping" +msgstr "\"%s\" metin arama yapılandırması mevcut değil, atlanıyor" + +#: commands/dropcmds.c:325 +#, c-format +msgid "extension \"%s\" does not exist, skipping" +msgstr "\"%s\" uzantısı mevcut değil, atlanıyor" + +#: commands/dropcmds.c:335 +#, c-format +msgid "function %s(%s) does not exist, skipping" +msgstr "%s(%s) fonksiyonu mevcut değil, atlanıyor" + +#: commands/dropcmds.c:348 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "%s(%s) prosedürü mevcut değil, atlanıyor" + +#: commands/dropcmds.c:361 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "%s(%s) yordamı (routine) mevcut değil, atlanıyor" + +#: commands/dropcmds.c:374 +#, c-format +msgid "aggregate %s(%s) does not exist, skipping" +msgstr "aggregate %s(%s) mevcut değil, atlanıyor" + +#: commands/dropcmds.c:387 +#, c-format +msgid "operator %s does not exist, skipping" +msgstr "%s operatorü mevcut değil, atlanıyor" + +#: commands/dropcmds.c:393 +#, c-format +msgid "language \"%s\" does not exist, skipping" +msgstr "\"%s\" dili mevcut değil, atlanıyor" + +#: commands/dropcmds.c:402 +#, c-format +msgid "cast from type %s to type %s does not exist, skipping" +msgstr "%s tipinden %s tipine cast mevcut değildir, atlanıyor" + +#: commands/dropcmds.c:411 +#, c-format +msgid "transform for type %s language \"%s\" does not exist, skipping" +msgstr "\"%2$s\" dilinde %1$s tipi için dönüşüm mevcut değil, atlanıyor" + +#: commands/dropcmds.c:419 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "\"%s\" tetikleyicisi \"%s\" tablosunda mevcut değil, atlanıyor" + +#: commands/dropcmds.c:428 +#, c-format +msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "\"%s\" politikası \"%s\" tablosunda mevcut değil, atlanıyor" + +#: commands/dropcmds.c:435 +#, c-format +msgid "event trigger \"%s\" does not exist, skipping" +msgstr "\"%s\" olay tetikleyicisi mevcut değil, atlanıyor" + +#: commands/dropcmds.c:441 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" +msgstr "\"%s\" rule'ü \"%s\" tablosunda mevcut değil ... atlanıyor" + +#: commands/dropcmds.c:448 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist, skipping" +msgstr "\"%s\" uzak-veri wrapper'i mevcut değil, atlanıyor" + +#: commands/dropcmds.c:452 +#, c-format +msgid "server \"%s\" does not exist, skipping" +msgstr "\"%s\" sunucusu mevcut değil, atlanıyor" + +#: commands/dropcmds.c:461 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" +msgstr "\"%s\" operatör sınıfı, \"%s\" erişim yöntemi için mevcut değil, atlanıyor" + +#: commands/dropcmds.c:473 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" +msgstr "\"%s\" operatör ailesi, \"%s\" erişim yöntemi için mevcut değil, atlanıyor" + +#: commands/dropcmds.c:480 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "\"%s\" yayını mevcut değil, atlanıyor" + +#: commands/event_trigger.c:187 +#, c-format +msgid "permission denied to create event trigger \"%s\"" +msgstr "\"%s\" olay tetikleyici oluşturma izni yok" + +#: commands/event_trigger.c:189 +#, c-format +msgid "Must be superuser to create an event trigger." +msgstr "Olay tetikleyici oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/event_trigger.c:198 +#, c-format +msgid "unrecognized event name \"%s\"" +msgstr "bilinmeyen olay adı: \"%s\"" + +#: commands/event_trigger.c:215 +#, c-format +msgid "unrecognized filter variable \"%s\"" +msgstr "tanınmayan filtre değişkeni: \"%s\"" + +#: commands/event_trigger.c:270 +#, c-format +msgid "filter value \"%s\" not recognized for filter variable \"%s\"" +msgstr "\"%s\" filtre değeri, \"%s\" filtre değişkeni için tanınmıyor" + +#. translator: %s represents an SQL statement name +#: commands/event_trigger.c:276 commands/event_trigger.c:346 +#, c-format +msgid "event triggers are not supported for %s" +msgstr "%s için olay tetikleyiciler desteklenmemektedir" + +#: commands/event_trigger.c:369 +#, c-format +msgid "filter variable \"%s\" specified more than once" +msgstr "\"%s\" filtre değişkeni birden fazla kez belirtilmiştir" + +#: commands/event_trigger.c:516 commands/event_trigger.c:559 commands/event_trigger.c:651 +#, c-format +msgid "event trigger \"%s\" does not exist" +msgstr "\"%s\" olay tetikleyicisi mevcut değil" + +#: commands/event_trigger.c:620 +#, c-format +msgid "permission denied to change owner of event trigger \"%s\"" +msgstr "\"%s\" olay tetikleyicisinin sahibinin değiştirilmesine izin verilmedi" + +#: commands/event_trigger.c:622 +#, c-format +msgid "The owner of an event trigger must be a superuser." +msgstr "Bir olay tetikleyicinin sahibi superuser olmalı" + +#: commands/event_trigger.c:1457 +#, c-format +msgid "%s can only be called in a sql_drop event trigger function" +msgstr "%s sadece bir sql-drop olay tetikleyici fonksiyonu içinde çağrılabilir" + +#: commands/event_trigger.c:1577 commands/event_trigger.c:1598 +#, c-format +msgid "%s can only be called in a table_rewrite event trigger function" +msgstr "%s sadece bir table-rewrite olay tetikleyici fonksiyonu içinde çağrılabilir" + +#: commands/event_trigger.c:2009 +#, c-format +msgid "%s can only be called in an event trigger function" +msgstr "%s sadece bir olay tetikleyici fonksiyonu içinde çağrılabilir" + +#: commands/explain.c:192 +#, c-format +msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" +msgstr "\"%s\" EXPLAIN seçeneği için tanınmayan değer: \"%s\"" + +#: commands/explain.c:199 +#, c-format +msgid "unrecognized EXPLAIN option \"%s\"" +msgstr "tanımsız EXPLAIN seçeneği \"%s\"" + +#: commands/explain.c:207 +#, c-format +msgid "EXPLAIN option BUFFERS requires ANALYZE" +msgstr "\"BUFFERS\" EXPLAIN seçeneği ANALYZE gerektirir " + +#: commands/explain.c:216 +#, c-format +msgid "EXPLAIN option TIMING requires ANALYZE" +msgstr "\"TIMING\" EXPLAIN seçeneği ANALYZE gerektirir" + +#: commands/extension.c:168 commands/extension.c:2914 +#, c-format +msgid "extension \"%s\" does not exist" +msgstr "\"%s\" uzantısı mevcut değil" + +#: commands/extension.c:267 commands/extension.c:276 commands/extension.c:288 commands/extension.c:298 +#, c-format +msgid "invalid extension name: \"%s\"" +msgstr "geçersiz uzantı adı: \"%s\"" + +#: commands/extension.c:268 +#, c-format +msgid "Extension names must not be empty." +msgstr "Uzantı adları boş olmamalıdır." + +#: commands/extension.c:277 +#, c-format +msgid "Extension names must not contain \"--\"." +msgstr "Uzantı adları \"--\" içermemelidir." + +#: commands/extension.c:289 +#, c-format +msgid "Extension names must not begin or end with \"-\"." +msgstr "Uzantı adları \"-\" ile başlamamalı veya bitmemelidir." + +#: commands/extension.c:299 +#, c-format +msgid "Extension names must not contain directory separator characters." +msgstr "Uzantı adları dizin ayırıcı karakterler içermemelidir." + +#: commands/extension.c:314 commands/extension.c:323 commands/extension.c:332 commands/extension.c:342 +#, c-format +msgid "invalid extension version name: \"%s\"" +msgstr "geçersiz uzantı sürüm adı: \"%s\"" + +#: commands/extension.c:315 +#, c-format +msgid "Version names must not be empty." +msgstr "Sürüm adları boş olmamalıdır." + +#: commands/extension.c:324 +#, c-format +msgid "Version names must not contain \"--\"." +msgstr "Sürüm adları \"--\" içermemelidir." + +#: commands/extension.c:333 +#, c-format +msgid "Version names must not begin or end with \"-\"." +msgstr "Sürüm adları \"-\" ile başlamamalı veya bitmemelidir." + +#: commands/extension.c:343 +#, c-format +msgid "Version names must not contain directory separator characters." +msgstr "Sürüm adları dizin ayırıcı karakterler ile bitmemelidir." + +#: commands/extension.c:493 +#, c-format +msgid "could not open extension control file \"%s\": %m" +msgstr "uzantı kontrol dosyası \"%s\" açma hatası: %m" + +#: commands/extension.c:515 commands/extension.c:525 +#, c-format +msgid "parameter \"%s\" cannot be set in a secondary extension control file" +msgstr "\"%s\" parametresi ikincil bir uzantı kontrol dosyası içinde belirtilemez" + +#: commands/extension.c:564 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\" geçerli bir dil kodlaması adı değildir" + +#: commands/extension.c:578 +#, c-format +msgid "parameter \"%s\" must be a list of extension names" +msgstr "\"%s\" parametresi uzantı adlarından oluşan bir liste olmalıdır" + +#: commands/extension.c:585 +#, c-format +msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgstr "\"%2$s\" dosyası içinde tanınmayan parametre \"%1$s\" " + +#: commands/extension.c:594 +#, c-format +msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" +msgstr " \"relocatable\" evet ise \"schema\" parametresi belirtilemez" + +#: commands/extension.c:761 +#, c-format +msgid "transaction control statements are not allowed within an extension script" +msgstr "işlem (transaction) denetim ifadeleri bir uzantı betiğinde kullanılamaz" + +#: commands/extension.c:807 +#, c-format +msgid "permission denied to create extension \"%s\"" +msgstr "uzantı \"%s\" oluşturma hatası" + +#: commands/extension.c:809 +#, c-format +msgid "Must be superuser to create this extension." +msgstr "Uzantı oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/extension.c:813 +#, c-format +msgid "permission denied to update extension \"%s\"" +msgstr "uzantı \"%s\" güncelleme hatası" + +#: commands/extension.c:815 +#, c-format +msgid "Must be superuser to update this extension." +msgstr "Uzantı güncellemek için superuser haklarına sahip olmalısınız." + +#: commands/extension.c:1097 +#, c-format +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgstr "\"%s\" uzantısının \"%s\" sürümünden \"%s\" sürümüne güncelleme yolu yok" + +#: commands/extension.c:1304 commands/extension.c:2975 +#, c-format +msgid "version to install must be specified" +msgstr "kurulacak sürüm belirtilmelidir" + +#: commands/extension.c:1326 +#, c-format +msgid "FROM version must be different from installation target version \"%s\"" +msgstr "FROM sürümü, kurulum hedef sürümü %s 'den farklı olmalıdır" + +#: commands/extension.c:1391 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "\"%s\" uzantısının \"%s\" sürümü için kurulum betiği ya da güncelleme yolu yok" + +#: commands/extension.c:1426 +#, c-format +msgid "extension \"%s\" must be installed in schema \"%s\"" +msgstr "\"%s\" uzantısı \"%s\" şemasında kurulmalıdır" + +#: commands/extension.c:1586 +#, c-format +msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" +msgstr "\"%s\" ve \"%s\" uzantıları arasında döngüsel bağımlılık tespit edildi" + +#: commands/extension.c:1591 +#, c-format +msgid "installing required extension \"%s\"" +msgstr "gerekli uzantı \"%s\" kuruluyor" + +#: commands/extension.c:1615 +#, c-format +msgid "required extension \"%s\" is not installed" +msgstr " gerekli uzantı \"%s\" kurulmamış" + +#: commands/extension.c:1618 +#, c-format +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "Gerekli uzantıları da kurmak için CREATE EXTENSION ... CASCADE kullanın" + +#: commands/extension.c:1655 +#, c-format +msgid "extension \"%s\" already exists, skipping" +msgstr "\"%s\" uzantısı zaten mevcut, atlanıyor" + +#: commands/extension.c:1662 +#, c-format +msgid "extension \"%s\" already exists" +msgstr "\"%s\" uzantısı zaten mevcut" + +#: commands/extension.c:1673 +#, c-format +msgid "nested CREATE EXTENSION is not supported" +msgstr "iç içe (nested) CREATE EXTENSION desteklenmiyor" + +#: commands/extension.c:1854 +#, c-format +msgid "cannot drop extension \"%s\" because it is being modified" +msgstr "şu anda değiştirildiğinden \"%s\" uzantısı kaldırılamıyor " + +#: commands/extension.c:2356 +#, c-format +msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" +msgstr "pg_extension_config_dump() sadece CREATE EXTENSION tarafından çalıştırılan bir SQL betiğinden çağrılabilir" + +#: commands/extension.c:2368 +#, c-format +msgid "OID %u does not refer to a table" +msgstr "%u OID'si bir tabloya ait değil" + +#: commands/extension.c:2373 +#, c-format +msgid "table \"%s\" is not a member of the extension being created" +msgstr "\"%s\" tablosu, oluşturulan uzantının bir üyesi değil" + +#: commands/extension.c:2729 +#, c-format +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" +msgstr "\"%s\" uzantısı \"%s\" şemasına taşınamıyor çünkü uzantı şemayı içeriyor" + +#: commands/extension.c:2770 commands/extension.c:2833 +#, c-format +msgid "extension \"%s\" does not support SET SCHEMA" +msgstr "\"%s\" uzantısı SET SCHEMA'yı desteklemiyor" + +#: commands/extension.c:2835 +#, c-format +msgid "%s is not in the extension's schema \"%s\"" +msgstr "\"%s\" uzantının şeması \"%s\" içinde değil" + +#: commands/extension.c:2894 +#, c-format +msgid "nested ALTER EXTENSION is not supported" +msgstr "iç içe (nested) ALTER EXTENSION desteklenmiyor" + +#: commands/extension.c:2986 +#, c-format +msgid "version \"%s\" of extension \"%s\" is already installed" +msgstr "\"%2$s\" uzantısının \"%1$s\" sürümü zaten kurulmuş" + +#: commands/extension.c:3237 +#, c-format +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" +msgstr "\"%s\" şeması \"%s\" uzantısına eklenemiyor çünkü şema uzantıyı içeriyor" + +#: commands/extension.c:3265 +#, c-format +msgid "%s is not a member of extension \"%s\"" +msgstr "%s, \"%s\" uzantısına dahil değildir" + +#: commands/extension.c:3331 +#, c-format +msgid "file \"%s\" is too large" +msgstr "\"%s\" dosyası çok büyük" + +#: commands/foreigncmds.c:150 commands/foreigncmds.c:159 +#, c-format +msgid "option \"%s\" not found" +msgstr "\"%s\" seçeneği bulunamadı" + +#: commands/foreigncmds.c:169 +#, c-format +msgid "option \"%s\" provided more than once" +msgstr "\"%s\" seçeneği birden fazla belirtilmiş" + +#: commands/foreigncmds.c:223 commands/foreigncmds.c:231 +#, c-format +msgid "permission denied to change owner of foreign-data wrapper \"%s\"" +msgstr "%s uzak-veri wrapper'inin sahibinin değiştirilmesine izin verilmedi" + +#: commands/foreigncmds.c:225 +#, c-format +msgid "Must be superuser to change owner of a foreign-data wrapper." +msgstr "Uzak-veri wrapperinin sahibini değiştirmek için superuser haklarına sahip olmalısınız." + +#: commands/foreigncmds.c:233 +#, c-format +msgid "The owner of a foreign-data wrapper must be a superuser." +msgstr "Bir uzak-veri wrapper'inin sahibi superuser olmalı." + +#: commands/foreigncmds.c:291 commands/foreigncmds.c:706 foreign/foreign.c:667 +#, c-format +msgid "foreign-data wrapper \"%s\" does not exist" +msgstr "\"%s\" uzak-veri wrapper'i mevcut değil" + +#: commands/foreigncmds.c:582 +#, c-format +msgid "permission denied to create foreign-data wrapper \"%s\"" +msgstr "\"%s\" uzak-veri wrapper'inin oluşturulmasına izin verilmedi" + +#: commands/foreigncmds.c:584 +#, c-format +msgid "Must be superuser to create a foreign-data wrapper." +msgstr "Uzak-veri wrapper'i oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/foreigncmds.c:696 +#, c-format +msgid "permission denied to alter foreign-data wrapper \"%s\"" +msgstr "\"%s\" uzak-veri wrapper'inin değiştirilmesine izin verilmedi" + +#: commands/foreigncmds.c:698 +#, c-format +msgid "Must be superuser to alter a foreign-data wrapper." +msgstr "Uzak-veri wrapper'ini değiştirmek için superuser haklarına sahip olmalısınız." + +#: commands/foreigncmds.c:729 +#, c-format +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" +msgstr "uzak-veri wrapper'inini işleyicisini değiştirmek mevcut uzak tabloların davranışını değiştirebilir" + +#: commands/foreigncmds.c:744 +#, c-format +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" +msgstr "uzak-veri wrapper'i doğrulayıcısını değiştirmek bağlı nesne seçeneklerinin geçersiz olmasına sebep olabilir" + +#: commands/foreigncmds.c:890 +#, c-format +msgid "server \"%s\" already exists, skipping" +msgstr "\"%s\" sunucusu zaten mevcut, atlanıyor" + +#: commands/foreigncmds.c:1175 +#, c-format +msgid "user mapping for \"%s\" already exists for server %s, skipping" +msgstr "%2$s sunucusu için \"%1$s\" kullanıcı eşleştirmesi zaten mevcut, atlanıyor" + +#: commands/foreigncmds.c:1185 +#, c-format +msgid "user mapping for \"%s\" already exists for server %s" +msgstr "%2$s sunucusu için \"%1$s\" kullanıcı eşleştirmesi zaten mevcut" + +#: commands/foreigncmds.c:1282 commands/foreigncmds.c:1397 +#, c-format +msgid "user mapping for \"%s\" does not exist for the server" +msgstr "sunucu için \"%s\" kullanıcı eşleştirmesi mevcut değil" + +#: commands/foreigncmds.c:1384 +#, c-format +msgid "server does not exist, skipping" +msgstr "sunucu mevcut değil, atlanıyor" + +#: commands/foreigncmds.c:1402 +#, c-format +msgid "user mapping for \"%s\" does not exist for the server, skipping" +msgstr "sunucu için \"%s\" kullanıcı eşleştirmesi mevcut değil, atlanıyor" + +#: commands/foreigncmds.c:1553 foreign/foreign.c:357 +#, c-format +msgid "foreign-data wrapper \"%s\" has no handler" +msgstr "\"%s\" uzak-veri wrapper'inin işleyicisi yok" + +#: commands/foreigncmds.c:1559 +#, c-format +msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" +msgstr "\"%s\" uzak-veri wrapper'i IMPORT FOREIGN SCHEMA'yı desteklemiyor" + +#: commands/foreigncmds.c:1662 +#, c-format +msgid "importing foreign table \"%s\"" +msgstr "\"%s\" uzak tablosu içeri alınıyor" + +#: commands/functioncmds.c:104 +#, c-format +msgid "SQL function cannot return shell type %s" +msgstr "SQL fonksiyonu %s shell tipini döndüremiyor" + +#: commands/functioncmds.c:109 +#, c-format +msgid "return type %s is only a shell" +msgstr "return type %s is only a shell" + +#: commands/functioncmds.c:139 parser/parse_type.c:337 +#, c-format +msgid "type modifier cannot be specified for shell type \"%s\"" +msgstr "\"%s\" kabuk tipi için tip değiştiricisi beliritilemez" + +#: commands/functioncmds.c:145 +#, c-format +msgid "type \"%s\" is not yet defined" +msgstr "\"%s\" tipi henüz tanımlanmamış" + +#: commands/functioncmds.c:146 +#, c-format +msgid "Creating a shell type definition." +msgstr "Kabuk tip tanımı yaratılıyor." + +#: commands/functioncmds.c:238 +#, c-format +msgid "SQL function cannot accept shell type %s" +msgstr "SQL fonksiyonu %s shell tipini alamaz" + +#: commands/functioncmds.c:244 +#, c-format +msgid "aggregate cannot accept shell type %s" +msgstr "toplam (aggregate) %s shell tipini alamaz" + +#: commands/functioncmds.c:249 +#, c-format +msgid "argument type %s is only a shell" +msgstr "\"%s\" argümanı sadece bir kabuktur" + +#: commands/functioncmds.c:259 +#, c-format +msgid "type %s does not exist" +msgstr "%s tipi mevcut değil" + +#: commands/functioncmds.c:273 +#, c-format +msgid "aggregates cannot accept set arguments" +msgstr "toplamlar (aggregate) set kabul edemez" + +#: commands/functioncmds.c:277 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "prosedürler küme argümanları kabul edemez" + +#: commands/functioncmds.c:281 +#, c-format +msgid "functions cannot accept set arguments" +msgstr "fonksiyonlar küme argümanlarını kabul etmez" + +#: commands/functioncmds.c:289 +#, c-format +msgid "procedures cannot have OUT arguments" +msgstr "prosedürlerin OUT argümanları olamaz" + +#: commands/functioncmds.c:290 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "INOUT argümanlarına izin var." + +#: commands/functioncmds.c:300 +#, c-format +msgid "VARIADIC parameter must be the last input parameter" +msgstr "VARIADIC parametresi, girdi parametrelerinin sonuncusu olmalıdır" + +#: commands/functioncmds.c:330 +#, c-format +msgid "VARIADIC parameter must be an array" +msgstr "VARIADIC parametresi bir dizi (array) olmalıdır" + +#: commands/functioncmds.c:370 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "\"%s\" parametresi birden fazla kez kullanılmıştır" + +#: commands/functioncmds.c:385 +#, c-format +msgid "only input parameters can have default values" +msgstr "sadece girdi parametreleri varsayılan değere sahip olabilirler" + +#: commands/functioncmds.c:400 +#, c-format +msgid "cannot use table references in parameter default value" +msgstr "parametre varsayılan değerlerinde tablo referansı kullanılamaz" + +#: commands/functioncmds.c:424 +#, c-format +msgid "input parameters after one with a default value must also have defaults" +msgstr "varsayılan değerli bir girdi parametresinden sonra gelenlerin de varsayılan değeri olmalıdır" + +#: commands/functioncmds.c:566 commands/functioncmds.c:716 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "prosedür tanımında geçersiz nitelik (attribute)" + +#: commands/functioncmds.c:747 +#, c-format +msgid "no function body specified" +msgstr "fonksiyon gövdesi yok" + +#: commands/functioncmds.c:757 +#, c-format +msgid "no language specified" +msgstr "dil belirtilmemiş" + +#: commands/functioncmds.c:782 commands/functioncmds.c:1256 +#, c-format +msgid "COST must be positive" +msgstr "COST pozitif olmalıdır" + +#: commands/functioncmds.c:790 commands/functioncmds.c:1264 +#, c-format +msgid "ROWS must be positive" +msgstr "ROWS pozitif olmalıdır" + +#: commands/functioncmds.c:842 +#, c-format +msgid "only one AS item needed for language \"%s\"" +msgstr "\"%s\" dili için sadece bir AS öğe lazım" + +#: commands/functioncmds.c:937 commands/functioncmds.c:2139 commands/proclang.c:557 +#, c-format +msgid "language \"%s\" does not exist" +msgstr "\"%s\" dili mevcut değil" + +#: commands/functioncmds.c:939 commands/functioncmds.c:2141 +#, c-format +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "Veritabana yeni bir dil eklemek için CREATE LANGUAGE kullanın." + +#: commands/functioncmds.c:974 commands/functioncmds.c:1248 +#, c-format +msgid "only superuser can define a leakproof function" +msgstr "sadece superuser bir leakproof fonksiyon tanımlayabilir" + +#: commands/functioncmds.c:1023 +#, c-format +msgid "function result type must be %s because of OUT parameters" +msgstr "OUT parametresinde belirtildiği gibi fonksiyon sonuç tipi %s olmalıdır" + +#: commands/functioncmds.c:1036 +#, c-format +msgid "function result type must be specified" +msgstr "fonksiyonun döndürme tipi belirtilmelidir" + +#: commands/functioncmds.c:1088 commands/functioncmds.c:1268 +#, c-format +msgid "ROWS is not applicable when function does not return a set" +msgstr "fonksiyonu bir set döndürmediğinde ROWS kullanılamaz" + +#: commands/functioncmds.c:1440 +#, c-format +msgid "source data type %s is a pseudo-type" +msgstr "kaynak veri tipi %s bir pseudo-type'dir" + +#: commands/functioncmds.c:1446 +#, c-format +msgid "target data type %s is a pseudo-type" +msgstr "hedef veri tipi %s bir pseudo-type'dir" + +#: commands/functioncmds.c:1470 +#, c-format +msgid "cast will be ignored because the source data type is a domain" +msgstr "kaynak veri tipi bir domain olduğundan dönüştürme (cast) yok sayılacak" + +#: commands/functioncmds.c:1475 +#, c-format +msgid "cast will be ignored because the target data type is a domain" +msgstr "hedef veri tipi bir domain olduğundan dönüştürme (cast) yok sayılacak" + +#: commands/functioncmds.c:1500 +#, c-format +msgid "cast function must take one to three arguments" +msgstr "cast fonksiyonu birden üçe kadar parametre alabilir" + +#: commands/functioncmds.c:1504 +#, c-format +msgid "argument of cast function must match or be binary-coercible from source data type" +msgstr "dönüştürme (cast) fonksiyonunun argümanları eşleşmeli ya da kaynak veri tipinden binary-coercible olmalıdır" + +#: commands/functioncmds.c:1508 +#, c-format +msgid "second argument of cast function must be type %s" +msgstr "dönüştürme (cast) fonksiyonunun ikinci argümanı %s tipinde olmalıdır" + +#: commands/functioncmds.c:1513 +#, c-format +msgid "third argument of cast function must be type %s" +msgstr "dönüştürme (cast) fonksiyonunun üçüncü parametresi %s tipinde olmalıdır" + +#: commands/functioncmds.c:1518 +#, c-format +msgid "return data type of cast function must match or be binary-coercible to target data type" +msgstr "dönüştürme (cast) fonksiyonunun döndürme tipi eşleşmeli ya da hedef veri tipine binary-coercible olmalıdır" + +#: commands/functioncmds.c:1529 +#, c-format +msgid "cast function must not be volatile" +msgstr "cast fonksiyonu volatile olmamalıdır" + +#: commands/functioncmds.c:1534 +#, c-format +msgid "cast function must be a normal function" +msgstr "cast fonksiyonu normal bir fonksiyon olmalıdır" + +#: commands/functioncmds.c:1538 +#, c-format +msgid "cast function must not return a set" +msgstr "cast fonksiyonu bir set döndürmemelidir" + +#: commands/functioncmds.c:1564 +#, c-format +msgid "must be superuser to create a cast WITHOUT FUNCTION" +msgstr "cast WITHOUT FUNCTION oluşturmak için superuser olmalısınız" + +#: commands/functioncmds.c:1579 +#, c-format +msgid "source and target data types are not physically compatible" +msgstr "kaynak ve hedef veri tipleri fiziksel olarak uyumsuz" + +#: commands/functioncmds.c:1594 +#, c-format +msgid "composite data types are not binary-compatible" +msgstr "birleşik veri tipleri ikili-uyumlu değil" + +#: commands/functioncmds.c:1600 +#, c-format +msgid "enum data types are not binary-compatible" +msgstr "enum veri tipleri ikili-uyumlu değil" + +#: commands/functioncmds.c:1606 +#, c-format +msgid "array data types are not binary-compatible" +msgstr "dizi (array) veri tipleri ikili-uyumlu değil" + +#: commands/functioncmds.c:1623 +#, c-format +msgid "domain data types must not be marked binary-compatible" +msgstr "domain veri tipleri ikili-uyumlu olarak işaretlenmemelidir" + +#: commands/functioncmds.c:1633 +#, c-format +msgid "source data type and target data type are the same" +msgstr "kaynak ve hedef veri tipleri aynı" + +#: commands/functioncmds.c:1666 +#, c-format +msgid "cast from type %s to type %s already exists" +msgstr "%s tipinden %s tipini cast etme zaten mevcut" + +#: commands/functioncmds.c:1739 +#, c-format +msgid "cast from type %s to type %s does not exist" +msgstr "%s tipinden %s tipine cast mevcut değildir" + +#: commands/functioncmds.c:1778 +#, c-format +msgid "transform function must not be volatile" +msgstr "dönüştürme fonksiyonu volatil olmamalıdır" + +#: commands/functioncmds.c:1782 +#, c-format +msgid "transform function must be a normal function" +msgstr "dönüştürme fonksiyonu normal bir fonksiyon olmalıdır" + +#: commands/functioncmds.c:1786 +#, c-format +msgid "transform function must not return a set" +msgstr "dönüştürme fonksiyonu bir küme döndürmemelidir" + +#: commands/functioncmds.c:1790 +#, c-format +msgid "transform function must take one argument" +msgstr "dönüştürme fonksiyonu bir argüman almalıdır" + +#: commands/functioncmds.c:1794 +#, c-format +msgid "first argument of transform function must be type %s" +msgstr "dönüştürme fonksiyonunun ilk argümanı %s tipinde olmalıdır" + +#: commands/functioncmds.c:1832 +#, c-format +msgid "data type %s is a pseudo-type" +msgstr "%s veri tipi bir pseudo-type'dir" + +#: commands/functioncmds.c:1838 +#, c-format +msgid "data type %s is a domain" +msgstr "%s veri tipi bir domain'dir" + +#: commands/functioncmds.c:1878 +#, c-format +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQL fonksiyonunun dönüş tipi %s olmalı" + +#: commands/functioncmds.c:1904 +#, c-format +msgid "return data type of TO SQL function must be the transform data type" +msgstr "TO SQL fonksiyonunun dönüş tipi dönüştürme 8transform) veri tipi olmalıdır" + +#: commands/functioncmds.c:1931 +#, c-format +msgid "transform for type %s language \"%s\" already exists" +msgstr "\"%2$s\" dili, %1$s tipi için dönüştürme zaten mevcut" + +#: commands/functioncmds.c:2020 +#, c-format +msgid "transform for type %s language \"%s\" does not exist" +msgstr "\"%2$s\" dili, %1$s tipi için dönüştürme mevcut değil" + +#: commands/functioncmds.c:2071 +#, c-format +msgid "function %s already exists in schema \"%s\"" +msgstr "%s fonksiyonu \"%s\" şemasında zaten mevcut" + +#: commands/functioncmds.c:2126 +#, c-format +msgid "no inline code specified" +msgstr "inline kod belirtilmemiş" + +#: commands/functioncmds.c:2172 +#, c-format +msgid "language \"%s\" does not support inline code execution" +msgstr "\"%s\" dili inline kod çalıştırmayı desteklemiyor" + +#: commands/functioncmds.c:2284 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "bir prosedüre %d sayısından fazla argüman gönderilemez" +msgstr[1] "bir prosedüre %d sayısından fazla argüman gönderilemez" + +#: commands/indexcmds.c:393 +#, c-format +msgid "must specify at least one column" +msgstr "en az bir sütun belirtmelisiniz" + +#: commands/indexcmds.c:397 +#, c-format +msgid "cannot use more than %d columns in an index" +msgstr "bir index içinde %d sayısından fazla sütun kullanılamaz" + +#: commands/indexcmds.c:437 +#, c-format +msgid "cannot create index on foreign table \"%s\"" +msgstr "\"%s\" uzak tablosunda indeks oluşturulamıyor" + +#: commands/indexcmds.c:462 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "\"%s\" bölümlenmiş tablosu üzerinde indeks eş zamanlı olarak oluşturulamıyor" + +#: commands/indexcmds.c:467 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosu üzerinde hariç tutma kısıtlamaları oluşturulamıyor" + +#: commands/indexcmds.c:477 +#, c-format +msgid "cannot create indexes on temporary tables of other sessions" +msgstr "başka oturumların geçici tablolarına üzerinde indeks oluşturulamaz" + +#: commands/indexcmds.c:542 commands/tablecmds.c:617 commands/tablecmds.c:11430 commands/tablecmds.c:11564 +#, c-format +msgid "only shared relations can be placed in pg_global tablespace" +msgstr "pg_global tablo aralığına sadece paylaşımlı sensne konulabilir" + +#: commands/indexcmds.c:575 +#, c-format +msgid "substituting access method \"gist\" for obsolete method \"rtree\"" +msgstr "artık kullanılmayan \"rtree\" yöntemi yerine \"gist\" yöntemi kullanılacak" + +#: commands/indexcmds.c:593 +#, c-format +msgid "access method \"%s\" does not support unique indexes" +msgstr "\"%s\" erişim yöntemi tekil indexleri desteklemiyor" + +#: commands/indexcmds.c:598 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "\"%s\" erişim yöntemi dahil edilen desteklemiyor" + +#: commands/indexcmds.c:603 +#, c-format +msgid "access method \"%s\" does not support multicolumn indexes" +msgstr "\"%s\" erişim yöntemi çoklu sütun indexleri desteklemiyor" + +#: commands/indexcmds.c:608 +#, c-format +msgid "access method \"%s\" does not support exclusion constraints" +msgstr "\"%s\" erişim yöntemi hariç tutma kısıtlamalarını desteklemiyor" + +#: commands/indexcmds.c:720 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "bölümleme anahtarı tanımyla desteklenmeyen %s kısıtlaması" + +#: commands/indexcmds.c:722 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "bölümleme anahtarları expression içerdiğinde %s kısıtlamaları kullanılamaz" + +#: commands/indexcmds.c:740 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "%s kısıtlama tanımında yetersiz sayıda sütun" + +#: commands/indexcmds.c:742 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "\"%2$s\" tablosu üzerindeki %1$s kısıtlamasında bölümleme anahtarının bir parçası olan \"%3$s\" sütunu eksik" + +#: commands/indexcmds.c:761 commands/indexcmds.c:781 +#, c-format +msgid "index creation on system columns is not supported" +msgstr "sistem sütunları üzerinde indeks oluşturma desteklenmiyor" + +#: commands/indexcmds.c:806 +#, c-format +msgid "%s %s will create implicit index \"%s\" for table \"%s\"" +msgstr "%1$s %2$s \"%4$s\" tablosu için \"%3$s\" indexi oluşturulacaktır" + +#: commands/indexcmds.c:1402 +#, c-format +msgid "functions in index predicate must be marked IMMUTABLE" +msgstr "index yüklemindeki kullanılacak fonksiyon IMMUTABLE olarak tanımlanmaıldır" + +#: commands/indexcmds.c:1468 parser/parse_utilcmd.c:2237 parser/parse_utilcmd.c:2361 +#, c-format +msgid "column \"%s\" named in key does not exist" +msgstr "anahtar tanımında belirtilen \"%s\" sütunu mevcut değil" + +#: commands/indexcmds.c:1492 parser/parse_utilcmd.c:1586 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "dahil edilen (included) sütunlarda expression'lar desteklenmemektedir" + +#: commands/indexcmds.c:1533 +#, c-format +msgid "functions in index expression must be marked IMMUTABLE" +msgstr "index ifadesinde kullanılacak fonksiyon IMMUTABLE olarak tanımlanmaıldır" + +#: commands/indexcmds.c:1548 +#, c-format +msgid "including column does not support a collation" +msgstr "sütun dahil etme bir collation desteklememektedir" + +#: commands/indexcmds.c:1552 +#, c-format +msgid "including column does not support an operator class" +msgstr "sütun dahil etme bir operatör sınıfı desteklememektedir" + +#: commands/indexcmds.c:1556 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "sütun dahil etme ASC/DESC desteklemiyor" + +#: commands/indexcmds.c:1560 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "sütun dahil etme NULLS FIRST/LAST desteklemiyor" + +#: commands/indexcmds.c:1587 +#, c-format +msgid "could not determine which collation to use for index expression" +msgstr "indeks ifadesi için hangi karşılaştırma (collation) kullanılacağı belirlenemedi" + +#: commands/indexcmds.c:1595 commands/tablecmds.c:14364 commands/typecmds.c:833 parser/parse_expr.c:2772 parser/parse_type.c:549 parser/parse_utilcmd.c:3392 utils/adt/misc.c:681 +#, c-format +msgid "collations are not supported by type %s" +msgstr "%s veri tipinde collation desteklenmemektedir" + +#: commands/indexcmds.c:1633 +#, c-format +msgid "operator %s is not commutative" +msgstr "%s operatörü değiştirilebilir (commutative) değil" + +#: commands/indexcmds.c:1635 +#, c-format +msgid "Only commutative operators can be used in exclusion constraints." +msgstr "hariç tutma kısıtlaması içerisinde sadece değiştirilebilir (commutative) operatörler kullanılabilir" + +#: commands/indexcmds.c:1661 +#, c-format +msgid "operator %s is not a member of operator family \"%s\"" +msgstr "%s operatörü, \"%s\" operatör ailesine dahil değil" + +#: commands/indexcmds.c:1664 +#, c-format +msgid "The exclusion operator must be related to the index operator class for the constraint." +msgstr "Hariç tutma operatörü kısıtlama için olan indeks operatör sınıfıyla ilişkili olmalıdır" + +#: commands/indexcmds.c:1699 +#, c-format +msgid "access method \"%s\" does not support ASC/DESC options" +msgstr "\"%s\" erişim yöntemi ASC/DESC desteklemiyor" + +#: commands/indexcmds.c:1704 +#, c-format +msgid "access method \"%s\" does not support NULLS FIRST/LAST options" +msgstr "\"%s\" erişim yöntemi NULLS FIRST/LAST desteklemiyor" + +#: commands/indexcmds.c:1763 commands/typecmds.c:1996 +#, c-format +msgid "data type %s has no default operator class for access method \"%s\"" +msgstr "%s veri tipinin \"%s\" erişim yöntemi için varsayılan operator sınıfı mevcut değil" + +#: commands/indexcmds.c:1765 +#, c-format +msgid "You must specify an operator class for the index or define a default operator class for the data type." +msgstr "Bu index için operator class belirtmeli veya bu veri tipi için varsayılan operator class tanımlamalısınız." + +#: commands/indexcmds.c:1794 commands/indexcmds.c:1802 commands/opclasscmds.c:206 +#, c-format +msgid "operator class \"%s\" does not exist for access method \"%s\"" +msgstr "\"%s\" erişim yöntemi için \"%s\" operatör sınıfı mevcut değil" + +#: commands/indexcmds.c:1815 commands/typecmds.c:1984 +#, c-format +msgid "operator class \"%s\" does not accept data type %s" +msgstr "\"%s\" operator sınıfı, %s veri tipini kabul etmiyor" + +#: commands/indexcmds.c:1905 +#, c-format +msgid "there are multiple default operator classes for data type %s" +msgstr "%s veri tipi için birden fazla varsayılan operator sınıfı mevcuttur" + +#: commands/indexcmds.c:2320 +#, c-format +msgid "table \"%s\" has no indexes" +msgstr "\"%s\" tablosunda hiçbir index yok" + +#: commands/indexcmds.c:2375 +#, c-format +msgid "can only reindex the currently open database" +msgstr "ancak açık olan veritabanı üzerinde reindex işlemi yapılabilir" + +#: commands/indexcmds.c:2493 +#, c-format +msgid "table \"%s.%s\" was reindexed" +msgstr "\"%s.%s\" tablosu yeniden indexlenmiştir" + +#: commands/indexcmds.c:2515 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "bölümlenmiş indeksler için REINDEX henüz uygulanmamıştır" + +#: commands/lockcmds.c:102 +#, c-format +msgid "\"%s\" is not a table or a view" +msgstr "\"%s\" bir tablo veya görünüm (view) değildir" + +#: commands/lockcmds.c:234 rewrite/rewriteHandler.c:1836 rewrite/rewriteHandler.c:3532 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "\"%s\" tablosuna bağlı rule'de sonsuz özyineleme bulundu" + +#: commands/matview.c:179 +#, c-format +msgid "CONCURRENTLY cannot be used when the materialized view is not populated" +msgstr "maddileştirilmiş görünüm doldurulmamışsa CONCURRENTLY kullanılamaz" + +#: commands/matview.c:185 +#, c-format +msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" +msgstr "CONCURRENTLY ve WITH NO DATA seçenekleri birlikte kullanılamaz" + +#: commands/matview.c:244 +#, c-format +msgid "cannot refresh materialized view \"%s\" concurrently" +msgstr "\"%s\" maddileştirilmiş görünümü eş zamanlı olarak yenilenemiyor" + +#: commands/matview.c:247 +#, c-format +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." +msgstr "Maddileştirilmiş görünümün bir ya da daha fazla sütunu üzerinde WHERE ibaresi olmayan bir unique index oluşturun." + +#: commands/matview.c:645 +#, c-format +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" +msgstr "\"%s\" maddileştirilmiş görünümü için yeni veri null sütunu olmayan birbirinin aynı (duplicate) satırlar içeriyor" + +#: commands/matview.c:647 +#, c-format +msgid "Row: %s" +msgstr "Satır: %s" + +#: commands/opclasscmds.c:127 +#, c-format +msgid "operator family \"%s\" does not exist for access method \"%s\"" +msgstr "\"%s\" erişim yöntemi için \"%s\" operatör sınıfı mevcut değil" + +#: commands/opclasscmds.c:265 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists" +msgstr "\"%2$s\" erişim metodu için \"%1$s\" operatör sınıfı zaten mevcut" + +#: commands/opclasscmds.c:403 +#, c-format +msgid "must be superuser to create an operator class" +msgstr "operator sınıfı yaratmak için superuser olmalısınız" + +#: commands/opclasscmds.c:476 commands/opclasscmds.c:850 commands/opclasscmds.c:974 +#, c-format +msgid "invalid operator number %d, must be between 1 and %d" +msgstr "%d geçersiz operatör numarası, 0 ile %d arasında olmalıdır" + +#: commands/opclasscmds.c:520 commands/opclasscmds.c:894 commands/opclasscmds.c:989 +#, c-format +msgid "invalid function number %d, must be between 1 and %d" +msgstr "geçersiz fonksiyon numarası %d, 1 ile %d arasında olmalıdır" + +#: commands/opclasscmds.c:549 +#, c-format +msgid "storage type specified more than once" +msgstr "depolama tipi birden fazla kez belirtilmiştir" + +#: commands/opclasscmds.c:576 +#, c-format +msgid "storage type cannot be different from data type for access method \"%s\"" +msgstr "depolama yötemi erişim metodu \"%s\" ile aynı olmalıdır" + +#: commands/opclasscmds.c:592 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists" +msgstr "\"%2$s\" erişim metodu için \"%1$s\" operator sınıfı zaten mevcut" + +#: commands/opclasscmds.c:620 +#, c-format +msgid "could not make operator class \"%s\" be default for type %s" +msgstr "%2$s veri tipinie \"%1$s\" operator sınıfı varsayılan olarak atanamıyor" + +#: commands/opclasscmds.c:623 +#, c-format +msgid "Operator class \"%s\" already is the default." +msgstr "\"%s\" operatör sınıfı zaten varsayılandır." + +#: commands/opclasscmds.c:748 +#, c-format +msgid "must be superuser to create an operator family" +msgstr "operator sınıfı oluşturmak için superuser olmalısınız" + +#: commands/opclasscmds.c:804 +#, c-format +msgid "must be superuser to alter an operator family" +msgstr "operator sınıfı değiştirmek için superuser olmalısınız" + +#: commands/opclasscmds.c:859 +#, c-format +msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" +msgstr "operator argument tipleri ALTER OPERATOR FAMILY işleminde belirtilmelidir" + +#: commands/opclasscmds.c:922 +#, c-format +msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" +msgstr "ALTER OPERATOR FAMILY işleminde STORAGE kullanılamaz" + +#: commands/opclasscmds.c:1044 +#, c-format +msgid "one or two argument types must be specified" +msgstr "bir veya iki argüman türü belirtilmelidir" + +#: commands/opclasscmds.c:1070 +#, c-format +msgid "index operators must be binary" +msgstr "index işletmenleri ikili olmalıdır" + +#: commands/opclasscmds.c:1089 +#, c-format +msgid "access method \"%s\" does not support ordering operators" +msgstr "\"%s\" erişim yöntemi sıralama operatörlerini desteklemiyor" + +#: commands/opclasscmds.c:1100 +#, c-format +msgid "index search operators must return boolean" +msgstr "indeks arama işletmenleri boolean veri tipini döndürmeli" + +#: commands/opclasscmds.c:1144 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "btree kıyaslama fonksiyonları iki argüman almalıdır" + +#: commands/opclasscmds.c:1148 +#, c-format +msgid "btree comparison functions must return integer" +msgstr "btree kıyaslama fonksiyonları tamsayı döndürmelidir" + +#: commands/opclasscmds.c:1165 +#, c-format +msgid "btree sort support functions must accept type \"internal\"" +msgstr "btree sıralama destek fonksiyonları \"internal\" veri tipini almalıdır" + +#: commands/opclasscmds.c:1169 +#, c-format +msgid "btree sort support functions must return void" +msgstr "btree sıralama destek fonksiyonları void döndürmelidir" + +#: commands/opclasscmds.c:1180 +#, c-format +msgid "btree in_range functions must have five arguments" +msgstr "btree in-range fonksiyonları beş argüman almalıdır" + +#: commands/opclasscmds.c:1184 +#, c-format +msgid "btree in_range functions must return boolean" +msgstr "btree in-range fonksiyonları boolean döndürmelidir" + +#: commands/opclasscmds.c:1203 +#, c-format +msgid "hash function 1 must have one argument" +msgstr "hash fonksiyonu 1, bir argüman almalıdır" + +#: commands/opclasscmds.c:1207 +#, c-format +msgid "hash function 1 must return integer" +msgstr "hash fonksiyonu 1, tamsayı dönmelidir" + +#: commands/opclasscmds.c:1214 +#, c-format +msgid "hash function 2 must have two arguments" +msgstr "hash fonksiyonu 2, iki argüman almalıdır" + +#: commands/opclasscmds.c:1218 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "hash fonksiyonu 2, bigint dönmelidir" + +#: commands/opclasscmds.c:1243 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "index destek fonksiyonu için ilgili veri tipleri belirtilmelidir" + +#: commands/opclasscmds.c:1268 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "(%2$s,%3$s) için %1$d fonksiyon numarasına birden fazla kez rastlanıyor" + +#: commands/opclasscmds.c:1275 +#, c-format +msgid "operator number %d for (%s,%s) appears more than once" +msgstr "(%2$s,%3$s) için %1$d operatör numarasına birden fazla kez rastlanıyor" + +#: commands/opclasscmds.c:1324 +#, c-format +msgid "operator %d(%s,%s) already exists in operator family \"%s\"" +msgstr "\"%4$s\" operatör ailesinde %1$d(%2$s,%3$s) operatörü zaten mevcuttur" + +#: commands/opclasscmds.c:1438 +#, c-format +msgid "function %d(%s,%s) already exists in operator family \"%s\"" +msgstr "\"%4$s\" operatör ailesinde %1$d(%2$s,%3$s) fonksiyonu zaten mevcuttur" + +#: commands/opclasscmds.c:1526 +#, c-format +msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "\"%4$s\" operatör ailesinde %1$d(%2$s,%3$s) operatörü mevcut değil" + +#: commands/opclasscmds.c:1566 +#, c-format +msgid "function %d(%s,%s) does not exist in operator family \"%s\"" +msgstr "\"%4$s\" operatör ailesinde %1$d(%2$s,%3$s) fonksiyonu mevcut değil" + +#: commands/opclasscmds.c:1696 +#, c-format +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operatör sınıfı \"%3$s\" şemasında zaten mevcut" + +#: commands/opclasscmds.c:1719 +#, c-format +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" +msgstr "\"%2$s\" erişim yöntemi için kullanılacak \"%1$s\" operatör ailesi \"%3$s\" şemasında zaten mevcut" + +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 +#, c-format +msgid "SETOF type not allowed for operator argument" +msgstr "operatör argümanı SETOF tipinde olamaz" + +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 +#, c-format +msgid "operator attribute \"%s\" not recognized" +msgstr "\"%s\" operatör özniteliği tanınmamaktadır" + +#: commands/operatorcmds.c:165 +#, c-format +msgid "operator function must be specified" +msgstr "operatör fonksiyonu belirtilmelidir" + +#: commands/operatorcmds.c:176 +#, c-format +msgid "at least one of leftarg or rightarg must be specified" +msgstr "en az bir tane leftarg veya rightarg belirtilmelidir" + +#: commands/operatorcmds.c:280 +#, c-format +msgid "restriction estimator function %s must return type %s" +msgstr "%s restriction estimator fonksiyonu %s tipi döndürmelidir" + +#: commands/operatorcmds.c:326 +#, c-format +msgid "join estimator function %s must return type %s" +msgstr "%s join estimator fonksiyonu %s tipini döndürmelidir" + +#: commands/operatorcmds.c:451 +#, c-format +msgid "operator attribute \"%s\" cannot be changed" +msgstr "\"%s\" operatör özniteliği değiştirilemiyor" + +#: commands/policy.c:87 commands/policy.c:400 commands/policy.c:490 commands/tablecmds.c:1278 commands/tablecmds.c:1755 commands/tablecmds.c:2742 commands/tablecmds.c:4986 commands/tablecmds.c:7394 commands/tablecmds.c:13997 commands/tablecmds.c:14032 commands/trigger.c:316 commands/trigger.c:1526 commands/trigger.c:1635 rewrite/rewriteDefine.c:272 rewrite/rewriteDefine.c:924 +#, c-format +msgid "permission denied: \"%s\" is a system catalog" +msgstr "erişim engellendi: \"%s\" bir sistem kataloğudur" + +#: commands/policy.c:170 +#, c-format +msgid "ignoring specified roles other than PUBLIC" +msgstr "PUBLIC dışındaki belirtilen roller yok sayılıyor" + +#: commands/policy.c:171 +#, c-format +msgid "All roles are members of the PUBLIC role." +msgstr "Bütün roller PUBLIC rolünün üyesidir." + +#: commands/policy.c:514 +#, c-format +msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" +msgstr "\"%1$s\" rolü \"%3$s\" üzerindeki \"%2$s\" ilkesinden (policy) kaldırılamıyor" + +#: commands/policy.c:720 +#, c-format +msgid "WITH CHECK cannot be applied to SELECT or DELETE" +msgstr "WITH CHECK , SELECT veya DELETE komutlarına uygulanamaz" + +#: commands/policy.c:729 commands/policy.c:1027 +#, c-format +msgid "only WITH CHECK expression allowed for INSERT" +msgstr "INSERT için sadece WITH CHECK ifadesine izin verilir" + +#: commands/policy.c:802 commands/policy.c:1247 +#, c-format +msgid "policy \"%s\" for table \"%s\" already exists" +msgstr "\"%s\" ilkesi (policy), \"%s\" tablosu için zaten mevcut" + +#: commands/policy.c:999 commands/policy.c:1275 commands/policy.c:1347 +#, c-format +msgid "policy \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\"ilkesi (policy), \"%s\" tablosunda mevcut değil" + +#: commands/policy.c:1017 +#, c-format +msgid "only USING expression allowed for SELECT, DELETE" +msgstr "SELECT, DELETE için sadece USING ifadesine izin verilir" + +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 +#, c-format +msgid "invalid cursor name: must not be empty" +msgstr "geçersiz imleç adı: boş olmamalıdır" + +#: commands/portalcmds.c:190 commands/portalcmds.c:244 executor/execCurrent.c:69 utils/adt/xml.c:2469 utils/adt/xml.c:2639 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "\"%s\" imleci mevcut değil" + +#: commands/prepare.c:75 +#, c-format +msgid "invalid statement name: must not be empty" +msgstr "geçersiz deyim adı: boş olmamalıdır" + +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1399 +#, c-format +msgid "could not determine data type of parameter $%d" +msgstr "$%d parametrenin veri tipini belirlenemiyor" + +#: commands/prepare.c:159 +#, c-format +msgid "utility statements cannot be prepared" +msgstr "yardımcı program statementları hazırlanamaz" + +#: commands/prepare.c:269 commands/prepare.c:274 +#, c-format +msgid "prepared statement is not a SELECT" +msgstr "hazırlanmış (prepared) sorgu SELECT değildir" + +#: commands/prepare.c:342 +#, c-format +msgid "wrong number of parameters for prepared statement \"%s\"" +msgstr "\"%s\" hazırlanmış sorgusunda parametre sayısı fazla" + +#: commands/prepare.c:344 +#, c-format +msgid "Expected %d parameters but got %d." +msgstr "%d beklenirken %d alındı." + +#: commands/prepare.c:380 +#, c-format +msgid "parameter $%d of type %s cannot be coerced to the expected type %s" +msgstr "%2$s tipinde $%1$d parametresi %3$s beklenen tipine zorla dönüştürülemez" + +#: commands/prepare.c:475 +#, c-format +msgid "prepared statement \"%s\" already exists" +msgstr "\"%s\" hazırlanmış sorgusu zaten mevcut" + +#: commands/prepare.c:514 +#, c-format +msgid "prepared statement \"%s\" does not exist" +msgstr "hazırlanmış sorgu \"%s\" mevcut değil" + +#: commands/proclang.c:86 +#, c-format +msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" +msgstr "CREATE LANGUAGE parametrelerin yerinde pg_pltemplate bilgisi kullanılacaktır" + +#: commands/proclang.c:96 +#, c-format +msgid "must be superuser to create procedural language \"%s\"" +msgstr "\"%s\" yordamsal dilini oluşturmak için superuser olmalısınız" + +#: commands/proclang.c:248 +#, c-format +msgid "unsupported language \"%s\"" +msgstr "\"%s\" dili desteklenmiyor" + +#: commands/proclang.c:250 +#, c-format +msgid "The supported languages are listed in the pg_pltemplate system catalog." +msgstr "Testeklenen dillerin listesi pg_pltemplate sistem cataloğunda bulunmaktadır." + +#: commands/proclang.c:258 +#, c-format +msgid "must be superuser to create custom procedural language" +msgstr "özel yordamsal dil oluşturmak için superuser olmalısınız" + +#: commands/proclang.c:277 commands/trigger.c:688 commands/typecmds.c:454 commands/typecmds.c:471 +#, c-format +msgid "changing return type of function %s from %s to %s" +msgstr "%s fonksiyonunun döndürme değeri %s den %s ye değiştiriliyor" + +#: commands/publicationcmds.c:109 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\" seçeneği için geçersiz liste sözdizimi" + +#: commands/publicationcmds.c:127 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "tanınmayan \"publish\" değeri: \"%s\"" + +#: commands/publicationcmds.c:133 +#, c-format +msgid "unrecognized publication parameter: %s" +msgstr "tanınmayan yayın (publication) parametresi: %s" + +#: commands/publicationcmds.c:166 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "FOR ALL TABLES yayını (publication) oluşturmak için superuser olmalısınız" + +#: commands/publicationcmds.c:335 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "\"%s\" yayını (publication) FOR ALL TABLES olarak tanımlanmıştır" + +#: commands/publicationcmds.c:337 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "FOR ALL TABLES yayınlarında (publication) tablo ekleme çıkarma yapılamaz" + +#: commands/publicationcmds.c:638 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "\"%s\" ilişkisi (relation) yayına (publication) dahil değildir" + +#: commands/publicationcmds.c:681 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "\"%s\" yayınının (publication) sahipliğinin değiştirilmesine izin verilmedi" + +#: commands/publicationcmds.c:683 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLES yayınının (publication) sahibi superuser olmalıdır" + +#: commands/schemacmds.c:106 commands/schemacmds.c:280 +#, c-format +msgid "unacceptable schema name \"%s\"" +msgstr "\"%s\" kabul edilemez şema adı" + +#: commands/schemacmds.c:107 commands/schemacmds.c:281 +#, c-format +msgid "The prefix \"pg_\" is reserved for system schemas." +msgstr "\"pg_\" ön eki, sistem şemaları için ayrılmıştır." + +#: commands/schemacmds.c:121 +#, c-format +msgid "schema \"%s\" already exists, skipping" +msgstr "\"%s\" şeması zaten mevcut, atlanıyor" + +#: commands/seclabel.c:60 +#, c-format +msgid "no security label providers have been loaded" +msgstr "hiç security label provider yüklenmemiş" + +#: commands/seclabel.c:64 +#, c-format +msgid "must specify provider when multiple security label providers have been loaded" +msgstr "çoklu security label provider yüklendiğinde provider belirtilmeli" + +#: commands/seclabel.c:82 +#, c-format +msgid "security label provider \"%s\" is not loaded" +msgstr "\"%s\" security label provider yüklenmemiş" + +#: commands/sequence.c:138 +#, c-format +msgid "unlogged sequences are not supported" +msgstr "loglanmayan sıralar (sequence) desteklenmiyor" + +#: commands/sequence.c:697 +#, c-format +msgid "nextval: reached maximum value of sequence \"%s\" (%s)" +msgstr "nextval: sequence en yüksek değerine ulaşmıştır \"%s\" (%s)" + +#: commands/sequence.c:720 +#, c-format +msgid "nextval: reached minimum value of sequence \"%s\" (%s)" +msgstr "nextval: sequence en düşük değerine ulaşmıştır \"%s\" (%s)" + +#: commands/sequence.c:838 +#, c-format +msgid "currval of sequence \"%s\" is not yet defined in this session" +msgstr "bu oturumda \"%s\" sequence'i için currval henüz tanımlanmamıştır" + +#: commands/sequence.c:857 commands/sequence.c:863 +#, c-format +msgid "lastval is not yet defined in this session" +msgstr "bu otumda lastval daha tanımlanmadı" + +#: commands/sequence.c:951 +#, c-format +msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" +msgstr "setval: %s değeri kapsam dışıdır, sequence \"%s\" (%s..%s)" + +#: commands/sequence.c:1348 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "geçersiz sıra (sequence) seçeneği SEQUENCE NAME" + +#: commands/sequence.c:1374 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "identity sütun tipi smallint, integer ya da bigint olmalı" + +#: commands/sequence.c:1375 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "sıra (sequence) tipi smallint, integer ya da bigint olmalı" + +#: commands/sequence.c:1409 +#, c-format +msgid "INCREMENT must not be zero" +msgstr "INCREMENT sıfır olamaz" + +#: commands/sequence.c:1462 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "%2$s sıra (sequence) veri tipi için MAXVALUE (%1$s) kapsam dışı bir değer" + +#: commands/sequence.c:1499 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "%2$s sıra (sequence) veri tipi için MINVALUE (%1$s) kapsam dışı bir değer" + +#: commands/sequence.c:1513 +#, c-format +msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" +msgstr "MINVALUE (%s), MAXVALUE (%s) değerinden küçük olmalıdır" + +#: commands/sequence.c:1540 +#, c-format +msgid "START value (%s) cannot be less than MINVALUE (%s)" +msgstr "START değeri (%s) MINVALUE değerinden (%s) küçük olamaz" + +#: commands/sequence.c:1552 +#, c-format +msgid "START value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "START değeri (%s) MAXVALUE değerinden (%s) büyük olamaz" + +#: commands/sequence.c:1582 +#, c-format +msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" +msgstr "RESTART değeri (%s) MINVALUE değerinden (%s) küçük olamaz" + +#: commands/sequence.c:1594 +#, c-format +msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" +msgstr "RESTART değeri (%s) MAXVALUE değerinden (%s) büyük olamaz" + +#: commands/sequence.c:1609 +#, c-format +msgid "CACHE (%s) must be greater than zero" +msgstr "CACHE (%s) sıfırdan büyük olmalıdır" + +#: commands/sequence.c:1646 +#, c-format +msgid "invalid OWNED BY option" +msgstr "geçersiz OWNED BY seçeneği" + +#: commands/sequence.c:1647 +#, c-format +msgid "Specify OWNED BY table.column or OWNED BY NONE." +msgstr "OWNED BY table.column veya OWNED BY NONE belirtin." + +#: commands/sequence.c:1672 +#, c-format +msgid "referenced relation \"%s\" is not a table or foreign table" +msgstr " rerefans edilen \"%s\" ilişkisi (relation) bir tablo veya uzak (foreign) tablo değildir" + +#: commands/sequence.c:1679 +#, c-format +msgid "sequence must have same owner as table it is linked to" +msgstr "sequence ait olduğu tablo ile aynı kullanıcıya sahip olmalıdır" + +#: commands/sequence.c:1683 +#, c-format +msgid "sequence must be in same schema as table it is linked to" +msgstr "sequence ait olduğu tablonun bulunduğu şemada bulunmalıdır" + +#: commands/sequence.c:1705 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "identity sequence'in sahibi değiştirilemez" + +#: commands/sequence.c:1706 commands/tablecmds.c:10812 commands/tablecmds.c:13429 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "\"%s\" sequence'i, \"%s\" tablosuna bağlıdır" + +#: commands/statscmds.c:93 commands/statscmds.c:102 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS içinde sadece bir tek ilişki (relation) yer alabilir" + +#: commands/statscmds.c:120 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "\"%s\" ilişkisi (relation) tablo, uzak tablo ya da maddileştirilmiş görünüm değildir" + +#: commands/statscmds.c:163 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "\"%s\" istatistik nesnesi zaten mevcut, atlanıyor" + +#: commands/statscmds.c:171 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "\"%s\" istatistik nesnesi zaten mevcut" + +#: commands/statscmds.c:193 commands/statscmds.c:199 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "CREATE STATISTICS içinde sadece basit sütun referansları yer alabilir" + +#: commands/statscmds.c:214 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "sistem sütunları üzerinde istatistik oluşturma desteklenmiyor" + +#: commands/statscmds.c:221 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "\"%s\" sütunu istatistikler içinde kullanılamaz çünkü %s tipinde ve bu tipin varsayılan btree operatör sınıfı yok" + +#: commands/statscmds.c:228 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "istatistikler içinde %d sayısından fazla sütun kullanılamaz" + +#: commands/statscmds.c:243 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "genişletilmiş istatistikler en az 2 sütun gerektirir" + +#: commands/statscmds.c:261 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "istatistik tanımında tekrar eden (duplicate) sütun adı" + +#: commands/statscmds.c:289 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "tanınmayan istatistik türü \"%s\"" + +#: commands/subscriptioncmds.c:187 +#, c-format +msgid "unrecognized subscription parameter: %s" +msgstr "tanınmayan abonelik (subsciption) parametresi: %s" + +#: commands/subscriptioncmds.c:200 +#, c-format +msgid "connect = false and enabled = true are mutually exclusive options" +msgstr "connect = false ve enabled = true seçenekleri karşılıklı olarak münhasırdır" + +#: commands/subscriptioncmds.c:205 +#, c-format +msgid "connect = false and create_slot = true are mutually exclusive options" +msgstr "connect = false ve create_slot = true seçenekleri karşılıklı olarak münhasırdır" + +#: commands/subscriptioncmds.c:210 +#, c-format +msgid "connect = false and copy_data = true are mutually exclusive options" +msgstr "connect = false ve copy_data = true seçenekleri karşılıklı olarak münhasırdır" + +#: commands/subscriptioncmds.c:227 +#, c-format +msgid "slot_name = NONE and enabled = true are mutually exclusive options" +msgstr "slot_name = NONE ve enabled = true seçenekleri karşılıklı olarak münhasırdır" + +#: commands/subscriptioncmds.c:232 +#, c-format +msgid "slot_name = NONE and create_slot = true are mutually exclusive options" +msgstr "slot_name = NONE ve create_slot = true seçenekleri karşılıklı olarak münhasırdır" + +#: commands/subscriptioncmds.c:237 +#, c-format +msgid "subscription with slot_name = NONE must also set enabled = false" +msgstr "slot_name = NONE seçenekli abonelik (subscription), enabled = false seçeneğini de ayarlamalıdır" + +#: commands/subscriptioncmds.c:242 +#, c-format +msgid "subscription with slot_name = NONE must also set create_slot = false" +msgstr "slot_name = NONE seçenekli abonelik (subscription), enabled = false seçeneğini de ayarlamalıdır" + +#: commands/subscriptioncmds.c:283 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "\"%s\" yayın (publication) adı birden fazla kez kullanılmıştır" + +#: commands/subscriptioncmds.c:347 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "abonelik oluşturmak için superuser olmalısınız" + +#: commands/subscriptioncmds.c:427 commands/subscriptioncmds.c:520 replication/logical/tablesync.c:856 replication/logical/worker.c:1722 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "yayıncıya (publisher) bağlanılamadı: %s" + +#: commands/subscriptioncmds.c:469 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "yayıncı (publisher) üzerinde \"%s\" replikasyon slot'u oluşturuldu" + +#: commands/subscriptioncmds.c:486 +#, c-format +msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" +msgstr "tablolar dahil edilmemiş, aboneliğe dahil etmek için ALTER SUBSCRIPTION ... REFRESH PUBLICATION çalıştırmanız gerek" + +#: commands/subscriptioncmds.c:576 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "\"%s.%s\" tablosu \"%s\" aboneliğine eklendi" + +#: commands/subscriptioncmds.c:600 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "\"%s.%s\" tablosu \"%s\" aboneliğinden çıkarıldı" + +#: commands/subscriptioncmds.c:669 +#, c-format +msgid "cannot set slot_name = NONE for enabled subscription" +msgstr "etkinleştirilmiş bir abonelik için slot_name = NONE ayarlanamaz" + +#: commands/subscriptioncmds.c:703 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "slot adı olmayan bir abonelik etkinleştirilemez" + +#: commands/subscriptioncmds.c:749 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "etkisizleştirilmiş abonelikler için ALTER SUBSCRIPTION with refresh kullanılamaz" + +#: commands/subscriptioncmds.c:750 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false) kullanın" + +#: commands/subscriptioncmds.c:768 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "etkisizleştirilmiş abonelikler için ALTER SUBSCRIPTION ... REFRESH kullanılamaz" + +#: commands/subscriptioncmds.c:847 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "\"%s\" aboneliği mevcut değil, atlanıyor" + +#: commands/subscriptioncmds.c:972 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "\"%s\" replikasyon slot'u silinmeye çalışılırken yayıncıya (publisher) bağlanılamadı" + +#: commands/subscriptioncmds.c:974 commands/subscriptioncmds.c:988 replication/logical/tablesync.c:905 replication/logical/tablesync.c:927 +#, c-format +msgid "The error was: %s" +msgstr "Alınan hata: %s" + +#: commands/subscriptioncmds.c:975 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." +msgstr "abonelik (subscription) ve slot ilişkisini sonlandırmak için ALTER SUBSCRIPTION ... SET (slot_name = NONE) kullanın" + +#: commands/subscriptioncmds.c:986 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "yayıncı (publisher) üzerindeki \"%s\" replikasyon slot'u silinemedi" + +#: commands/subscriptioncmds.c:991 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "yayıncı (publisher) üzerindeki \"%s\" replikasyon slot'u silindi" + +#: commands/subscriptioncmds.c:1032 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "\"%s\" aboneliğinin (subscription) sahipliğinin değiştirilmesine izin verilmedi" + +#: commands/subscriptioncmds.c:1034 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "Aboneliğin (subscription) sahibi superuser olmalı." + +#: commands/subscriptioncmds.c:1147 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "Yayıncıdan (publisher) kopyalanan (replicated) tabloların listesi alınamadı: %s" + +#: commands/tablecmds.c:223 commands/tablecmds.c:265 +#, c-format +msgid "table \"%s\" does not exist" +msgstr "tablo \"%s\" mevcut değil" + +#: commands/tablecmds.c:224 commands/tablecmds.c:266 +#, c-format +msgid "table \"%s\" does not exist, skipping" +msgstr "tablo \"%s\" mevcut değil, atlanıyor" + +#: commands/tablecmds.c:226 commands/tablecmds.c:268 +msgid "Use DROP TABLE to remove a table." +msgstr "Bir tabloyu kaldırmak için DROP TABLE KULLANIN." + +#: commands/tablecmds.c:229 +#, c-format +msgid "sequence \"%s\" does not exist" +msgstr "sequence \"%s\" mevcut değil" + +#: commands/tablecmds.c:230 +#, c-format +msgid "sequence \"%s\" does not exist, skipping" +msgstr "sequence \"%s\" mevcut değil, atlanıyor" + +#: commands/tablecmds.c:232 +msgid "Use DROP SEQUENCE to remove a sequence." +msgstr "Bir sequence kaldırmak için DROP SEQUENCE kullanın." + +#: commands/tablecmds.c:235 +#, c-format +msgid "view \"%s\" does not exist" +msgstr "view \"%s\" mevcut değil" + +#: commands/tablecmds.c:236 +#, c-format +msgid "view \"%s\" does not exist, skipping" +msgstr "view \"%s\" mevcut değil, atlanıyor" + +#: commands/tablecmds.c:238 +msgid "Use DROP VIEW to remove a view." +msgstr "Bir view kaldırmak için DROP VIEW kullanın." + +#: commands/tablecmds.c:241 +#, c-format +msgid "materialized view \"%s\" does not exist" +msgstr " \"%s\" maddileştirilmiş görünümü mevcut değil" + +#: commands/tablecmds.c:242 +#, c-format +msgid "materialized view \"%s\" does not exist, skipping" +msgstr " \"%s\" maddileştirilmiş görünümü mevcut değil, atlanıyor" + +#: commands/tablecmds.c:244 +msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." +msgstr "Bir maddileştirilmiş görünümü kaldırmak için DROP MATERIALIZED VIEW kullanın." + +#: commands/tablecmds.c:247 commands/tablecmds.c:271 commands/tablecmds.c:15434 parser/parse_utilcmd.c:1982 +#, c-format +msgid "index \"%s\" does not exist" +msgstr "\"%s\" indexi mevcut değil" + +#: commands/tablecmds.c:248 commands/tablecmds.c:272 +#, c-format +msgid "index \"%s\" does not exist, skipping" +msgstr "\"%s\" indexi mevcut değil, atlanıyor" + +#: commands/tablecmds.c:250 commands/tablecmds.c:274 +msgid "Use DROP INDEX to remove an index." +msgstr "Bir index kaldırmak için DROP INDEX kullanın." + +#: commands/tablecmds.c:255 +#, c-format +msgid "\"%s\" is not a type" +msgstr "\"%s\" bir tip değildir" + +#: commands/tablecmds.c:256 +msgid "Use DROP TYPE to remove a type." +msgstr "Bir tipi kaldırmak için DROP TYPE kullanın." + +#: commands/tablecmds.c:259 commands/tablecmds.c:10256 commands/tablecmds.c:13209 +#, c-format +msgid "foreign table \"%s\" does not exist" +msgstr "uzak (foreign) tablo \"%s\" mevcut değil" + +#: commands/tablecmds.c:260 +#, c-format +msgid "foreign table \"%s\" does not exist, skipping" +msgstr "uzak (foreign) tablo \"%s\" mevcut değil, atlanıyor" + +#: commands/tablecmds.c:262 +msgid "Use DROP FOREIGN TABLE to remove a foreign table." +msgstr "Bir uzak tabloyu kaldırmak için DROP FOREIGN TABLE KULLANIN." + +#: commands/tablecmds.c:557 +#, c-format +msgid "ON COMMIT can only be used on temporary tables" +msgstr "ON COMMIT sadece geçici tablolarda kullanılabilir" + +#: commands/tablecmds.c:585 +#, c-format +msgid "cannot create temporary table within security-restricted operation" +msgstr "güvenlik-kıstlamalı bir işlem içinde geçici (temporary) tablo oluşturulamaz" + +#: commands/tablecmds.c:686 +#, c-format +msgid "cannot create table with OIDs as partition of table without OIDs" +msgstr "OID'siz bir tablonun bölümü (partition) olarak OID'li bir tablo oluşturulamaz" + +#: commands/tablecmds.c:810 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\" bölümlendirilmemiş" + +#: commands/tablecmds.c:891 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "bölümleme (partitioning) için %d sayısından fazla sütun kullanılamaz" + +#: commands/tablecmds.c:1098 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" +msgstr "DROP INDEX CONCURRENTLY, çoklu nesne silinmesini desteklemiyor" + +#: commands/tablecmds.c:1102 +#, c-format +msgid "DROP INDEX CONCURRENTLY does not support CASCADE" +msgstr "DROP INDEX CONCURRENTLY, CASCADE desteklemiyor" + +#: commands/tablecmds.c:1401 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "bölümlendirilmiş bir tablo üzerinde truncate only yapılamaz" + +#: commands/tablecmds.c:1402 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "Ya ONLY anahtar-kelimesini kullanmayın, ya da doğrudan bölümlerin (partition) üzerinde TRUNCATE ONLY uygulayın." + +#: commands/tablecmds.c:1471 +#, c-format +msgid "truncate cascades to table \"%s\"" +msgstr "truncate işlemi , cascade neticesinde %s' tablosuna varıyor" + +#: commands/tablecmds.c:1765 +#, c-format +msgid "cannot truncate temporary tables of other sessions" +msgstr "diğer oturumların geçici tablolarını truncate edemezsiniz" + +#: commands/tablecmds.c:2006 commands/tablecmds.c:11960 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosundan inherit yapılamaz" + +#: commands/tablecmds.c:2011 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "\"%s\" bölümünden (partition) inherit yapılamaz" + +#: commands/tablecmds.c:2019 parser/parse_utilcmd.c:2199 parser/parse_utilcmd.c:2322 +#, c-format +msgid "inherited relation \"%s\" is not a table or foreign table" +msgstr "miras alınan \"%s\" nesnesi bir tablo veya uzak (foreign) tablo değildir" + +#: commands/tablecmds.c:2031 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "geçici bir nesne \"%s\" kalıcı nesnesine bölümleme olarak oluşturulamaz" + +#: commands/tablecmds.c:2040 commands/tablecmds.c:11939 +#, c-format +msgid "cannot inherit from temporary relation \"%s\"" +msgstr "\"%s\" geçici nesnesinden inherit yapılamaz" + +#: commands/tablecmds.c:2050 commands/tablecmds.c:11947 +#, c-format +msgid "cannot inherit from temporary relation of another session" +msgstr "başka bir oturumun geçici nesnesinden inherit yapılamaz" + +#: commands/tablecmds.c:2067 commands/tablecmds.c:12071 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "\"%s\" ilişkisi birden fazla miras alınmış" + +#: commands/tablecmds.c:2116 +#, c-format +msgid "merging multiple inherited definitions of column \"%s\"" +msgstr "\"%s\" sütununun birden fazla miras alınmış tanımı birleştiriliyor" + +#: commands/tablecmds.c:2124 +#, c-format +msgid "inherited column \"%s\" has a type conflict" +msgstr "miras alınan \"%s\" sütunu tip çakışması yaşıyor" + +#: commands/tablecmds.c:2126 commands/tablecmds.c:2149 commands/tablecmds.c:2354 commands/tablecmds.c:2384 parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 parser/parse_coerce.c:1846 parser/parse_param.c:218 +#, c-format +msgid "%s versus %s" +msgstr "%s versus %s" + +#: commands/tablecmds.c:2135 +#, c-format +msgid "inherited column \"%s\" has a collation conflict" +msgstr "miras alınan \"%s\" sütunu karşılaştırma (collation) çakışması yaşıyor" + +#: commands/tablecmds.c:2137 commands/tablecmds.c:2366 commands/tablecmds.c:5446 +#, c-format +msgid "\"%s\" versus \"%s\"" +msgstr "\"%s\" ye karşı \"%s\"" + +#: commands/tablecmds.c:2147 +#, c-format +msgid "inherited column \"%s\" has a storage parameter conflict" +msgstr "miras alınan \"%s\" sütunu storage parametresi çakışması yaşıyor" + +#: commands/tablecmds.c:2260 commands/tablecmds.c:9684 parser/parse_utilcmd.c:1116 parser/parse_utilcmd.c:1515 parser/parse_utilcmd.c:1622 +#, c-format +msgid "cannot convert whole-row table reference" +msgstr "bütün-satır tablo referansı dönüştürülemez" + +#: commands/tablecmds.c:2261 parser/parse_utilcmd.c:1117 +#, c-format +msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "\"%s\" kısıtlaması, \"%s\" tablosuna bütün-satır referansı içeriyor." + +#: commands/tablecmds.c:2340 +#, c-format +msgid "merging column \"%s\" with inherited definition" +msgstr "\"%s\" sütunu miras alınan tanımı ile birleştiriliyor" + +#: commands/tablecmds.c:2344 +#, c-format +msgid "moving and merging column \"%s\" with inherited definition" +msgstr "\"%s\" sütunu taşınıyor ve miras alınan tanımı ile birleştiriliyor" + +#: commands/tablecmds.c:2345 +#, c-format +msgid "User-specified column moved to the position of the inherited column." +msgstr "Kullanıcı-tanımlı sütun miras alınan sütun pozisyonuna taşındı." + +#: commands/tablecmds.c:2352 +#, c-format +msgid "column \"%s\" has a type conflict" +msgstr "\"%s\" sütununda tip çakışması" + +#: commands/tablecmds.c:2364 +#, c-format +msgid "column \"%s\" has a collation conflict" +msgstr "\"%s\" sütununda karşılaştırma (collation) çakışması" + +#: commands/tablecmds.c:2382 +#, c-format +msgid "column \"%s\" has a storage parameter conflict" +msgstr "\"%s\" sütununda storage parametresi çakışması" + +#: commands/tablecmds.c:2485 +#, c-format +msgid "column \"%s\" inherits conflicting default values" +msgstr "\"%s\" sütunu çakışan değerleri inherit ediyor" + +#: commands/tablecmds.c:2487 +#, c-format +msgid "To resolve the conflict, specify a default explicitly." +msgstr "Çakışmayı çözmek için varsayılan değeri açıkca belirtin." + +#: commands/tablecmds.c:2534 +#, c-format +msgid "check constraint name \"%s\" appears multiple times but with different expressions" +msgstr "\"%s\" check kısıtlaması birçok kez ve farklı anlatımla mevcuttur" + +#: commands/tablecmds.c:2711 +#, c-format +msgid "cannot rename column of typed table" +msgstr "belirtilen tablonun sütunu yeniden isimlendirilemiyor" + +#: commands/tablecmds.c:2730 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" +msgstr "\"%s\" bir tablo, görünüm, maddileştirilmiş görünüm, karma tip, indeks ya da uzak tablo değildir" + +#: commands/tablecmds.c:2824 +#, c-format +msgid "inherited column \"%s\" must be renamed in child tables too" +msgstr "miras alınan \"%s\" kolonunun adı alt tablolarda da değiştirilmelidir" + +#: commands/tablecmds.c:2856 +#, c-format +msgid "cannot rename system column \"%s\"" +msgstr "\"%s\" sistem sütununun adı değiştirilemez" + +#: commands/tablecmds.c:2871 +#, c-format +msgid "cannot rename inherited column \"%s\"" +msgstr "miras alınan \"%s\" sütununun adı değiştirilemez" + +#: commands/tablecmds.c:3023 +#, c-format +msgid "inherited constraint \"%s\" must be renamed in child tables too" +msgstr "miras alınan \"%s\" kısıtlamasının adı alt tablolarda da değiştirilmelidir" + +#: commands/tablecmds.c:3030 +#, c-format +msgid "cannot rename inherited constraint \"%s\"" +msgstr "miras alınan \"%s\" kısıtlamasının adı değiştirilemez" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3256 +#, c-format +msgid "cannot %s \"%s\" because it is being used by active queries in this session" +msgstr "%s \"%s\" için yapılamıyor; çünkü bu oturumda aktif sorgular tarafından kullanılmaktadır" + +#. translator: first %s is a SQL command, eg ALTER TABLE +#: commands/tablecmds.c:3266 +#, c-format +msgid "cannot %s \"%s\" because it has pending trigger events" +msgstr "%s \"%s\" için yapılamıyor; çünkü bekleyen trigger olayları bulunmakta" + +#: commands/tablecmds.c:4414 +#, c-format +msgid "cannot rewrite system relation \"%s\"" +msgstr "\"%s\" sistem tablosu yeniden yazılamaz" + +#: commands/tablecmds.c:4420 +#, c-format +msgid "cannot rewrite table \"%s\" used as a catalog table" +msgstr "katalog tablosu olarak kullanılan \"%s\" tablosu yeniden yazılamıyor" + +#: commands/tablecmds.c:4430 +#, c-format +msgid "cannot rewrite temporary tables of other sessions" +msgstr "diğer oturumların geçici tabloları yeniden yazılamaz" + +#: commands/tablecmds.c:4707 +#, c-format +msgid "rewriting table \"%s\"" +msgstr "\"%s\" dosyası yeniden yazılıyor" + +#: commands/tablecmds.c:4711 +#, c-format +msgid "verifying table \"%s\"" +msgstr "\"%s\" tablosu doğrulanıyor" + +#: commands/tablecmds.c:4827 +#, c-format +msgid "column \"%s\" contains null values" +msgstr "\"%s\" sütunu null değerleri içermektedir" + +#: commands/tablecmds.c:4843 commands/tablecmds.c:8905 +#, c-format +msgid "check constraint \"%s\" is violated by some row" +msgstr "\"%s\" bütünlük kısıtlaması bir(kaç) satır tarafından ihlal edilmiş" + +#: commands/tablecmds.c:4861 +#, c-format +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "varsayılan bölüm için güncellenmiş bölümleme kısıtlaması bir(kaç) satır tarafından ihlal edilmiş olur" + +#: commands/tablecmds.c:4865 +#, c-format +msgid "partition constraint is violated by some row" +msgstr "bölümleme kısıtlaması bir(kaç) satır tarafından ihlal edilmiş" + +#: commands/tablecmds.c:5007 commands/trigger.c:310 rewrite/rewriteDefine.c:266 rewrite/rewriteDefine.c:919 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\" bir tablo veya view değildir" + +#: commands/tablecmds.c:5010 commands/trigger.c:1520 commands/trigger.c:1626 +#, c-format +msgid "\"%s\" is not a table, view, or foreign table" +msgstr "\"%s\" bir tablo, görünüm veya uzak tablo değildir" + +#: commands/tablecmds.c:5013 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, or index" +msgstr "\"%s\" bir tablo, görünüm, maddileştirilmiş görünüm veya indeks değildir" + +#: commands/tablecmds.c:5019 +#, c-format +msgid "\"%s\" is not a table, materialized view, or index" +msgstr "\"%s\" bir tablo, maddileştirilmiş görünüm veya indeks değildir" + +#: commands/tablecmds.c:5022 +#, c-format +msgid "\"%s\" is not a table, materialized view, or foreign table" +msgstr "\"%s\" bir tablo, maddileştirilmiş görünüm, veya uzak tablo değildir" + +#: commands/tablecmds.c:5025 +#, c-format +msgid "\"%s\" is not a table or foreign table" +msgstr "\"%s\" bir tablo veya uzak tablo değil" + +#: commands/tablecmds.c:5028 +#, c-format +msgid "\"%s\" is not a table, composite type, or foreign table" +msgstr "\"%s\" bir tablo, bileşik tip veya uzak tablo değildir" + +#: commands/tablecmds.c:5031 commands/tablecmds.c:6449 +#, c-format +msgid "\"%s\" is not a table, materialized view, index, or foreign table" +msgstr "\"%s\" bir tablo, maddileştrilmiş görünüm, indeks, veya uzak tablo değildir" + +#: commands/tablecmds.c:5041 +#, c-format +msgid "\"%s\" is of the wrong type" +msgstr "\"%s\" yanlış tiptedir" + +#: commands/tablecmds.c:5216 commands/tablecmds.c:5223 +#, c-format +msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" +msgstr "\"%s\" tipi değiştirilemez; çünkü \"%s.%s\" sütunu onu kullanıyor " + +#: commands/tablecmds.c:5230 +#, c-format +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "\"%s\" uzak tablosu değiştirilemez çünkü \"%s.%s\" sütunu onun satır tipini kullanıyor" + +#: commands/tablecmds.c:5237 +#, c-format +msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" +msgstr "\"%2$s\".\"%3$s\" sütunu onun row type veri tipini kullandığı için \"%1$s\" foreign tablosu değiştirilemez" + +#: commands/tablecmds.c:5291 +#, c-format +msgid "cannot alter type \"%s\" because it is the type of a typed table" +msgstr "\"%s\" tipi değiştirilemiyor çünkü tipli bir tablonun tipidir" + +#: commands/tablecmds.c:5293 +#, c-format +msgid "Use ALTER ... CASCADE to alter the typed tables too." +msgstr "Tipli tabloları da değiştirmek için ALTER ... CASCADE kullanın." + +#: commands/tablecmds.c:5339 +#, c-format +msgid "type %s is not a composite type" +msgstr "%s tipi bileşik bir tip değildir" + +#: commands/tablecmds.c:5365 +#, c-format +msgid "cannot add column to typed table" +msgstr "tipli tabloya sütun eklenemez" + +#: commands/tablecmds.c:5409 +#, c-format +msgid "cannot add column to a partition" +msgstr "bir bölüme (partition) sütun eklenemez" + +#: commands/tablecmds.c:5438 commands/tablecmds.c:12198 +#, c-format +msgid "child table \"%s\" has different type for column \"%s\"" +msgstr "\"%s\" alt tablosundaki \"%s\" sütununun tipi farklıdır" + +#: commands/tablecmds.c:5444 commands/tablecmds.c:12205 +#, c-format +msgid "child table \"%s\" has different collation for column \"%s\"" +msgstr "\"%s\" alt tablosundaki \"%s\" sütununun karşılaştırması (collation) farklıdır" + +#: commands/tablecmds.c:5454 +#, c-format +msgid "child table \"%s\" has a conflicting \"%s\" column" +msgstr "\"%s\" alt tablosu çakışan bir \"%s\" sütununa sahip" + +#: commands/tablecmds.c:5465 +#, c-format +msgid "merging definition of column \"%s\" for child \"%s\"" +msgstr "\"%s\" sütunun tanımı \"%s\" alt tablo için birleştiriliyor" + +#: commands/tablecmds.c:5489 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "alt tabloları olan bir tabloya özyinelemeli olarak identity sütunu eklenemez" + +#: commands/tablecmds.c:5738 +#, c-format +msgid "column must be added to child tables too" +msgstr "sütun, alt tablolarana da eklenmelidir" + +#: commands/tablecmds.c:5813 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists, skipping" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu zaten mevcut, atlanıyor" + +#: commands/tablecmds.c:5820 +#, c-format +msgid "column \"%s\" of relation \"%s\" already exists" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu zaten mevcut" + +#: commands/tablecmds.c:5918 commands/tablecmds.c:9364 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "bölümler (partition) mevcutken bir kısıtlama sadece bölümlenmiş tablodan kaldırılamaz" + +#: commands/tablecmds.c:5919 commands/tablecmds.c:6063 commands/tablecmds.c:6847 commands/tablecmds.c:9365 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ONLY anahtar kelimesini belirtmeyiniz." + +#: commands/tablecmds.c:5951 commands/tablecmds.c:6099 commands/tablecmds.c:6154 commands/tablecmds.c:6230 commands/tablecmds.c:6324 commands/tablecmds.c:6383 commands/tablecmds.c:6533 commands/tablecmds.c:6603 commands/tablecmds.c:6695 commands/tablecmds.c:9504 commands/tablecmds.c:10279 +#, c-format +msgid "cannot alter system column \"%s\"" +msgstr "\"%s\" sistem sütunu değiştirilemez" + +#: commands/tablecmds.c:5957 commands/tablecmds.c:6160 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu bir identity sütunudur" + +#: commands/tablecmds.c:5993 +#, c-format +msgid "column \"%s\" is in a primary key" +msgstr "\"%s\" sütunu bir birincil anahtardır" + +#: commands/tablecmds.c:6015 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "\"%s\" sütunu ana tabloda NOT NULL olarak işaretlenmiştir" + +#: commands/tablecmds.c:6062 +#, c-format +msgid "cannot add constraint to only the partitioned table when partitions exist" +msgstr "bölümler (partition) mevcutken bir kısıtlama sadece bölümlenmiş tabloya eklenemez" + +#: commands/tablecmds.c:6162 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "Onun yerine ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY kullanın." + +#: commands/tablecmds.c:6241 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu identity özelliği eklenmeden önce NOT NULL olarak tanımlanmalı" + +#: commands/tablecmds.c:6247 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu zaten bir identity sütunu" + +#: commands/tablecmds.c:6253 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütununun zaten varsayılan değeri var" + +#: commands/tablecmds.c:6330 commands/tablecmds.c:6391 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu bir identity sütunu değil" + +#: commands/tablecmds.c:6396 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "\"%2$s\" nesnesinin \"%1$s\" sütunu bir identity değil, atlanıyor" + +#: commands/tablecmds.c:6461 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "index-sütunu olmayan bir sütuna numarasıyla referans verilemez" + +#: commands/tablecmds.c:6492 +#, c-format +msgid "statistics target %d is too low" +msgstr "statistics target %d çok düşüktür" + +#: commands/tablecmds.c:6500 +#, c-format +msgid "lowering statistics target to %d" +msgstr "statistics target, %d değerine düşürülmektedir" + +#: commands/tablecmds.c:6523 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "\"%2$s\" tablosunun %1$d sayılı sütunu mevcut değil" + +#: commands/tablecmds.c:6542 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "\"%2$s\" indeksinin \"%1$s\" dahil edilmiş sütunu üzerindeki istatistikler değiştirilemiyor" + +#: commands/tablecmds.c:6547 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "\"%2$s\" indeksinin \"%1$s\" non-expression sütunu üzerindeki istatistikler değiştirilemiyor" + +#: commands/tablecmds.c:6549 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "Bunun yerine tablo sütunu üzerindeki istatistiği değiştirin." + +#: commands/tablecmds.c:6675 +#, c-format +msgid "invalid storage type \"%s\"" +msgstr "geçersiz saklama tipi \"%s\"" + +#: commands/tablecmds.c:6707 +#, c-format +msgid "column data type %s can only have storage PLAIN" +msgstr "%s sütün veri tipleri sadece PLAIN depolama yöntemini kullanabilir" + +#: commands/tablecmds.c:6742 +#, c-format +msgid "cannot drop column from typed table" +msgstr "tipli tablodan sütun silinemiyor" + +#: commands/tablecmds.c:6787 +#, c-format +msgid "column \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "\"%s\" kolonu \"%s\" nesnesinde mevcut değil, atlanıyor" + +#: commands/tablecmds.c:6800 +#, c-format +msgid "cannot drop system column \"%s\"" +msgstr "\"%s\" sistem sütunu kaldırılamaz" + +#: commands/tablecmds.c:6807 +#, c-format +msgid "cannot drop inherited column \"%s\"" +msgstr "miras alınan \"%s\" sütunu kaldırılamaz" + +#: commands/tablecmds.c:6818 +#, c-format +msgid "cannot drop column named in partition key" +msgstr "bölümleme anahtarında geçen sütun silinemiyor" + +#: commands/tablecmds.c:6822 +#, c-format +msgid "cannot drop column referenced in partition key expression" +msgstr "bölümleme anahtarında referans verilen sütun silinemiyor" + +#: commands/tablecmds.c:6846 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "bölümler (partition) mevcutken bir sütun yalnızca bölümlenmiş tablodan silinemez" + +#: commands/tablecmds.c:7051 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX ibölümlenmiş tablolarda desteklenmiyor" + +#: commands/tablecmds.c:7076 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX indeksin adını \"%s\" den \"%s\" ye değiştirecek" + +#: commands/tablecmds.c:7292 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "kısıtlama, alt tablolara da eklenmelidir" + +#: commands/tablecmds.c:7365 +#, c-format +msgid "cannot reference partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosuna referans edilemez" + +#: commands/tablecmds.c:7373 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosu üzerinde indeks eş zamanlı olarak oluşturulamıyor" + +#: commands/tablecmds.c:7379 +#, fuzzy, c-format +#| msgid "cannot rewrite system relation \"%s\"" +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "\"%s\" sistem tablosu yeniden yazılamaz" + +#: commands/tablecmds.c:7382 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "Bu özellik henüz bölümlenmiş tablolarda desteklenmiyor." + +#: commands/tablecmds.c:7388 +#, c-format +msgid "referenced relation \"%s\" is not a table" +msgstr " rerefans edilen \"%s\" nesnesi bir tablo değildir" + +#: commands/tablecmds.c:7411 +#, c-format +msgid "constraints on permanent tables may reference only permanent tables" +msgstr "kalıcı tablolar üzerindeki kısıtlamalar sadece kalıcı tablolara referans edebilir" + +#: commands/tablecmds.c:7418 +#, c-format +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" +msgstr "loglanmayan tablolar üzerindeki kısıtlamalar sadece kalıcı veya loglanmayan tablolara referans edebilir" + +#: commands/tablecmds.c:7424 +#, c-format +msgid "constraints on temporary tables may reference only temporary tables" +msgstr "geçici tablolar üzerindeki kısıtlamalar sadece geçici tablolara referans edebilir" + +#: commands/tablecmds.c:7428 +#, c-format +msgid "constraints on temporary tables must involve temporary tables of this session" +msgstr "geçici tablolar üzerindeki kısıtlamalar bu oturumun geçici tablolarını kapsamalıdır" + +#: commands/tablecmds.c:7488 +#, c-format +msgid "number of referencing and referenced columns for foreign key disagree" +msgstr "foreign key'in referans eden ve referans edilen sütun sayısı uyuşmuyor" + +#: commands/tablecmds.c:7595 +#, c-format +msgid "foreign key constraint \"%s\" cannot be implemented" +msgstr "\"%s\" foreign key constrain oluşturulamaz" + +#: commands/tablecmds.c:7598 +#, c-format +msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." +msgstr "\"%s\" ve \"%s\" anahtar sütunların tipi farklı: %s ve %s." + +#: commands/tablecmds.c:8205 commands/tablecmds.c:8370 commands/tablecmds.c:9321 commands/tablecmds.c:9396 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist" +msgstr "\"%s\" kısıtlaması \"%s\" nesnesinde mevcut değil" + +#: commands/tablecmds.c:8212 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" +msgstr "\"%2$s\" nesnesinin \"%1$s\" kısıtlaması bir uzak anahtar kısıtlaması değil" + +#: commands/tablecmds.c:8378 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgstr "\"%2$s\" nesnesinin \"%1$s\" kısıtlaması bir uzak anahtar veya kontrol kısıtlaması değil" + +#: commands/tablecmds.c:8448 +#, c-format +msgid "constraint must be validated on child tables too" +msgstr "kısıtlama alt tablolarda da geçerlenmeli" + +#: commands/tablecmds.c:8516 +#, c-format +msgid "column \"%s\" referenced in foreign key constraint does not exist" +msgstr "foreign key kısıtlaması tarafından referans edilen sütun \"%s\" mevcut değil" + +#: commands/tablecmds.c:8521 +#, c-format +msgid "cannot have more than %d keys in a foreign key" +msgstr "foreign key kısıtlamasında %d'dan fazla anahtar olamaz" + +#: commands/tablecmds.c:8586 +#, c-format +msgid "cannot use a deferrable primary key for referenced table \"%s\"" +msgstr "referans edilen \"%s\" tablosunda ertelenebilir (deferrable) primary key kullanılamaz" + +#: commands/tablecmds.c:8603 +#, c-format +msgid "there is no primary key for referenced table \"%s\"" +msgstr "referans edilen \"%s\" tablosunda primary key mevcut değil" + +#: commands/tablecmds.c:8668 +#, c-format +msgid "foreign key referenced-columns list must not contain duplicates" +msgstr "foreign key referans verilen sütunlar listesi mükerrer kayıt içermemeli" + +#: commands/tablecmds.c:8762 +#, c-format +msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" +msgstr "referans edilen \"%s\" tablosunda ertelenebilir (deferrable) unique kısıtlaması kullanılamaz" + +#: commands/tablecmds.c:8767 +#, c-format +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" +msgstr "\"%s\" referans edilen tablosunda belirtilen anahtarlara uyan bir unique constraint yok" + +#: commands/tablecmds.c:8938 +#, c-format +msgid "validating foreign key constraint \"%s\"" +msgstr "\"%s\" uzak anahtar bütünlük kısıtlamaları geçerleniyor" + +#: commands/tablecmds.c:9277 +#, c-format +msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" +msgstr "\"%2$s\" nesnesinin miras alınan \"%1$s\" kısıtlaması kaldırılamaz" + +#: commands/tablecmds.c:9327 +#, c-format +msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" +msgstr "\"%2$s\" nesnesinin \"%1$s\" kısıtlaması mevcut değil, atlanıyor" + +#: commands/tablecmds.c:9488 +#, c-format +msgid "cannot alter column type of typed table" +msgstr "tipli (typed) tablonun sütun tipi değiştirilemiyor" + +#: commands/tablecmds.c:9511 +#, c-format +msgid "cannot alter inherited column \"%s\"" +msgstr "miras alınan \"%s\" kolonu değiştirilemez" + +#: commands/tablecmds.c:9522 +#, c-format +msgid "cannot alter type of column named in partition key" +msgstr "bölümleme anahtarında geçen sütun tipi değiştirilemiyor" + +#: commands/tablecmds.c:9526 +#, c-format +msgid "cannot alter type of column referenced in partition key expression" +msgstr "bölümleme anahtarı ifadesinde referans verilen sütunun tipi değiştirilemiyor" + +#: commands/tablecmds.c:9576 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" sütunu için USING ibaresinin sonucu otomatik olarak %s tipine dönüştürülemez" + +#: commands/tablecmds.c:9579 +#, c-format +msgid "You might need to add an explicit cast." +msgstr "Belirgin (explicit) bir dönüştürme eklemeniz gerekebilir." + +#: commands/tablecmds.c:9583 +#, c-format +msgid "column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" sütunu otomatik olarak %s tipine dönüştürülemez" + +#. translator: USING is SQL, don't translate it +#: commands/tablecmds.c:9586 +#, c-format +msgid "You might need to specify \"USING %s::%s\"." +msgstr "\"USING %s::%s\" tanımlamanız gerekebilir." + +#: commands/tablecmds.c:9685 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "USING ifadesi bütün-satır tablo referansı içeriyor." + +#: commands/tablecmds.c:9696 +#, c-format +msgid "type of inherited column \"%s\" must be changed in child tables too" +msgstr "\"%s\" inherinted sütununların tipi çocuk tablolarında da değiştirilmelidir" + +#: commands/tablecmds.c:9800 +#, c-format +msgid "cannot alter type of column \"%s\" twice" +msgstr "\"%s\" sütununun tipini iki kez değiştirilemez" + +#: commands/tablecmds.c:9836 +#, c-format +msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgstr "\"%s\" sütunun varsayılan tipi otomatik olarak \"%s\" tipine dönüştürülemez" + +#: commands/tablecmds.c:9942 +#, c-format +msgid "cannot alter type of a column used by a view or rule" +msgstr "view veya rule tarafından kullanılan sütunun tipi değiştirilemedi" + +#: commands/tablecmds.c:9943 commands/tablecmds.c:9962 commands/tablecmds.c:9980 +#, c-format +msgid "%s depends on column \"%s\"" +msgstr "%s sütunu \"%s\" sütununa bağlıdır" + +#: commands/tablecmds.c:9961 +#, c-format +msgid "cannot alter type of a column used in a trigger definition" +msgstr "bir tetikleyici tanımında kullanılan sütunun tipi değiştirilemiyor" + +#: commands/tablecmds.c:9979 +#, c-format +msgid "cannot alter type of a column used in a policy definition" +msgstr "bir politika tanımında kullanılan sütunun tipi değiştirilemiyor" + +#: commands/tablecmds.c:10782 commands/tablecmds.c:10794 +#, c-format +msgid "cannot change owner of index \"%s\"" +msgstr "\"%s\" indeksinin sahibi değiştirilemez" + +#: commands/tablecmds.c:10784 commands/tablecmds.c:10796 +#, c-format +msgid "Change the ownership of the index's table, instead." +msgstr "Bunun yerine indeksin bağlı oldüğü tablonun sahipliğini değiştirin." + +#: commands/tablecmds.c:10810 +#, c-format +msgid "cannot change owner of sequence \"%s\"" +msgstr "\"%s\" sequence'in sahibi değiştirilemez" + +#: commands/tablecmds.c:10824 commands/tablecmds.c:14108 +#, c-format +msgid "Use ALTER TYPE instead." +msgstr "Yerine ALTER TYPE kullanın." + +#: commands/tablecmds.c:10833 +#, c-format +msgid "\"%s\" is not a table, view, sequence, or foreign table" +msgstr "\"%s\" bir tablo, görünüm, sıra veya uzak tablo değildir" + +#: commands/tablecmds.c:11173 +#, c-format +msgid "cannot have multiple SET TABLESPACE subcommands" +msgstr "birden fazla SET TABLESPACE alt komutu veremezsiniz" + +#: commands/tablecmds.c:11248 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" +msgstr "\"%s\" bir tablo, görünüm, maddileştirilmiş görünüm, indeks veya TOAST tablosu değildir" + +#: commands/tablecmds.c:11281 commands/view.c:508 +#, c-format +msgid "WITH CHECK OPTION is supported only on automatically updatable views" +msgstr "WITH CHECK OPTION sadece otomatik olarak güncellenebilir görünümlerde destekleniyor" + +#: commands/tablecmds.c:11423 +#, c-format +msgid "cannot move system relation \"%s\"" +msgstr "\"%s\" sistem nesnesi taşınamaz" + +#: commands/tablecmds.c:11439 +#, c-format +msgid "cannot move temporary tables of other sessions" +msgstr "diğer oturumların geçici tabloları taşınamaz" + +#: commands/tablecmds.c:11630 +#, c-format +msgid "only tables, indexes, and materialized views exist in tablespaces" +msgstr "tablespace içinde sadece tablolar, indeksler ve maddileştirilmiş görünümler bulunur" + +#: commands/tablecmds.c:11642 +#, c-format +msgid "cannot move relations in to or out of pg_global tablespace" +msgstr "pg_global tablespace içine veya dışına nesne taşınamaz" + +#: commands/tablecmds.c:11735 +#, c-format +msgid "aborting because lock on relation \"%s.%s\" is not available" +msgstr "iptal ediliyor çünkü \"%s.%s\" nesnesi üzerinde kilit mevcut değil" + +#: commands/tablecmds.c:11751 +#, c-format +msgid "no matching relations in tablespace \"%s\" found" +msgstr "\"%s\" tablespace'i içinde eşleşen nesne bulunmuyor" + +#: commands/tablecmds.c:11818 storage/buffer/bufmgr.c:915 +#, c-format +msgid "invalid page in block %u of relation %s" +msgstr "%2$s nesnesinin %1$u bloğunda geçersiz sayfa " + +#: commands/tablecmds.c:11898 +#, c-format +msgid "cannot change inheritance of typed table" +msgstr "tipli (typed) tablonun kalıtı değiştirilemez" + +#: commands/tablecmds.c:11903 commands/tablecmds.c:12446 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "bir bölümlemenin kalıtı değiştirilemez" + +#: commands/tablecmds.c:11908 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "bölümlenmiş tablonun kalıtı değiştirilemez" + +#: commands/tablecmds.c:11954 +#, c-format +msgid "cannot inherit to temporary relation of another session" +msgstr "başka bir oturumun geçici nesnesine inherit edemez" + +#: commands/tablecmds.c:11967 +#, c-format +msgid "cannot inherit from a partition" +msgstr "bir bölümlemeden inherit yapılamaz" + +#: commands/tablecmds.c:11989 commands/tablecmds.c:14692 +#, c-format +msgid "circular inheritance not allowed" +msgstr "çevrimsel inheritance yapısına izin verilmemektedir" + +#: commands/tablecmds.c:11990 commands/tablecmds.c:14693 +#, c-format +msgid "\"%s\" is already a child of \"%s\"." +msgstr "\"%s\" zaten \"%s\" nesnesinin alt nesnesidir" + +#: commands/tablecmds.c:11998 +#, c-format +msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" +msgstr "OID olmayan \"%s\" tablosu, OID olan \"%s\" tablosu inherit edemez" + +#: commands/tablecmds.c:12011 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "\"%s\" triggeri \"%s\" tablosunun bir kalıt altı (inheritance child) olmasını engelliyor" + +#: commands/tablecmds.c:12013 +#, c-format +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" +msgstr "geçiş tablolu ROW tetikleyiciler kalıt hiyerarşilerinde desteklenmiyor" + +#: commands/tablecmds.c:12216 +#, c-format +msgid "column \"%s\" in child table must be marked NOT NULL" +msgstr "alt tablosundaki \"%s\" sütunu NOT NULL olmalıdır" + +#: commands/tablecmds.c:12243 commands/tablecmds.c:12282 +#, c-format +msgid "child table is missing column \"%s\"" +msgstr "alt tablosunda \"%s\" sütunu eksiktir" + +#: commands/tablecmds.c:12370 +#, c-format +msgid "child table \"%s\" has different definition for check constraint \"%s\"" +msgstr "\"%s\" alt tablosunda \"%s\" kontrol kısıtlaması için farklı bir tanım mevcut" + +#: commands/tablecmds.c:12378 +#, c-format +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" +msgstr "\"%s\" kısıtlaması \"%s\" alt tablosu üzerindeki kalıtsal olmayan kısıtlamayla çakışıyor" + +#: commands/tablecmds.c:12389 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "\"%s\" kısıtlaması \"%s\" alt tablosu üzerindeki NOT VALID kısıtlamasıyla çakışıyor" + +#: commands/tablecmds.c:12424 +#, c-format +msgid "child table is missing constraint \"%s\"" +msgstr "alt tablosunda \"%s\" kısıtlama eksiktir" + +#: commands/tablecmds.c:12513 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "\"%s\" nesnesi \"%s\" nesnesinin bir bölümü (partition) değildir" + +#: commands/tablecmds.c:12519 +#, c-format +msgid "relation \"%s\" is not a parent of relation \"%s\"" +msgstr "\"%s\" nesnesi \"%s\" nesnesinin üst nesnesi değildir" + +#: commands/tablecmds.c:12745 +#, c-format +msgid "typed tables cannot inherit" +msgstr "" +"tipli (typed) tablolar inherit\n" +" edemez" + +#: commands/tablecmds.c:12776 +#, c-format +msgid "table is missing column \"%s\"" +msgstr "tabloda \"%s\" sütunu eksiktir" + +#: commands/tablecmds.c:12787 +#, c-format +msgid "table has column \"%s\" where type requires \"%s\"" +msgstr "tabloda \"%s\" sütunu mevcut oysa tipi \"%s\" gerektirmekte" + +#: commands/tablecmds.c:12796 +#, c-format +msgid "table \"%s\" has different type for column \"%s\"" +msgstr "\"%s\" tablosunda \"%s\" sütununun tipi farklı" + +#: commands/tablecmds.c:12810 +#, c-format +msgid "table has extra column \"%s\"" +msgstr "tabloda ilave olarak \"%s\" sütunu mevcut" + +#: commands/tablecmds.c:12862 +#, c-format +msgid "\"%s\" is not a typed table" +msgstr "\"%s\" tipli (typed) bir tablo değildir" + +#: commands/tablecmds.c:13044 +#, c-format +msgid "cannot use non-unique index \"%s\" as replica identity" +msgstr "replika özdeşliği olarak \"%s\" non-unique indeksi kullanılamaz" + +#: commands/tablecmds.c:13050 +#, c-format +msgid "cannot use non-immediate index \"%s\" as replica identity" +msgstr "replika özdeşliği olarak \"%s\" non-immediate indeksi kullanılamaz" + +#: commands/tablecmds.c:13056 +#, c-format +msgid "cannot use expression index \"%s\" as replica identity" +msgstr "replika özdeşliği olarak \"%s\" expression indeksi kullanılamaz" + +#: commands/tablecmds.c:13062 +#, c-format +msgid "cannot use partial index \"%s\" as replica identity" +msgstr "replika özdeşliği olarak \"%s\" partial indeksi kullanılamaz" + +#: commands/tablecmds.c:13068 +#, c-format +msgid "cannot use invalid index \"%s\" as replica identity" +msgstr "replika özdeşliği olarak \"%s\" geçersiz indeksi kullanılamaz" + +#: commands/tablecmds.c:13089 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" +msgstr "\"%s\" indeksi replika özdeşliği olarak kullanılamaz çünkü %d sütunu bir sistem sütunudur" + +#: commands/tablecmds.c:13096 +#, c-format +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" +msgstr "\"%s\" indeksi replika özdeşliği olarak kullanılamaz çünkü \"%s\" sütunu null değer alabilir" + +#: commands/tablecmds.c:13289 +#, c-format +msgid "cannot change logged status of table \"%s\" because it is temporary" +msgstr "\"%s\" tablosu geçici olduğundan loglanma durumu değiştirilemez" + +#: commands/tablecmds.c:13313 +#, c-format +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "\"%s\" tablosu loglanmayan olarak değiştirlemez çünkü bir yayının parçasıdır" + +#: commands/tablecmds.c:13315 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "Loglanmayan nesneler replike edilemez." + +#: commands/tablecmds.c:13360 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" +msgstr "\"%s\" tablosu loglanan olarak değiştirilemedi çünkü \"%s\" loglanmayan tablosuna referans veriyor " + +#: commands/tablecmds.c:13370 +#, c-format +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" +msgstr "\"%s\" tablosu loglanmayan olarak değiştirilemedi çünkü \"%s\" loglanan tablosuna referans veriyor " + +#: commands/tablecmds.c:13428 +#, c-format +msgid "cannot move an owned sequence into another schema" +msgstr "sahipliği belli olan sequence başka bir şemaya taşınamaz" + +#: commands/tablecmds.c:13534 +#, c-format +msgid "relation \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" nesnesi zaten \"%s\" şemasında mevcuttur" + +#: commands/tablecmds.c:14091 +#, c-format +msgid "\"%s\" is not a composite type" +msgstr "\"%s\" bir birleşik tip değildir" + +#: commands/tablecmds.c:14123 +#, c-format +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgstr "\"%s\" bir tablo, görünüm, maddileştirilmiş görünüm, sıra veya uzak tablo değildir" + +#: commands/tablecmds.c:14158 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "bilinmeyen bölümlemem stratejisi \"%s\"" + +#: commands/tablecmds.c:14166 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "\"list\" bölümleme stratejisi birden fazla sütunla kullanılamaz" + +#: commands/tablecmds.c:14231 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "bölümleme anahtarı tanımında belirtilen \"%s\" sütunu mevcut değil" + +#: commands/tablecmds.c:14238 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "\"%s\" sistem sütunu bölümleme anahtarında kullanılamaz" + +#: commands/tablecmds.c:14301 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "bölümleme anahtarı ifadesinde kullanılacak fonksiyon IMMUTABLE olarak tanımlanmaıldır" + +#: commands/tablecmds.c:14318 +#, c-format +msgid "partition key expressions cannot contain whole-row references" +msgstr "bölümleme anahtarı ifadeleri bütün-satır referansları içeremez" + +#: commands/tablecmds.c:14325 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "bölümleme anahtarı ifadeleri sistem sütunu referansları içeremez" + +#: commands/tablecmds.c:14335 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "bölümleme anahtarı olarak sabir ifade kullanılamaz" + +#: commands/tablecmds.c:14356 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "bölümleme ifadesi için hangi karşılaştırmanın kullanılacağı tespit edilemedi" + +#: commands/tablecmds.c:14389 +#, c-format +msgid "data type %s has no default hash operator class" +msgstr "%s veri tipinin varsayılan hash operatör sınıfı yok" + +#: commands/tablecmds.c:14391 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "Bir hash operatör sınıfı belirtmeli veya bu veri tipi için varsayılan hash operatör sınıfı tanımlamalısınız." + +#: commands/tablecmds.c:14395 +#, c-format +msgid "data type %s has no default btree operator class" +msgstr "%s veri tipinin varsayılan btree operatör sınıfı yok" + +#: commands/tablecmds.c:14397 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "Bir btree operatör sınıfı belirtmeli veya bu veri tipi için varsayılan btree operatör sınıfı tanımlamalısınız." + +#: commands/tablecmds.c:14522 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "mevcut kısıtlamalar (constraint) \"%s\" tablosu için bölümleme kısıtını da içermektedir" + +#: commands/tablecmds.c:14526 partitioning/partbounds.c:621 partitioning/partbounds.c:666 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "\"% s\" varsayılan bölümü için güncellenmiş bölüm kısıtı, mevcut kısıtlamaların gereğidir" + +#: commands/tablecmds.c:14632 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" zaten bir bölümlemedir (partition)" + +#: commands/tablecmds.c:14638 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "bir tipli (typed) tablo bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14654 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "kalıt altı (inheritance child) bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14668 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "kalıt üstü (inheritance parent) bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14702 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "geçici bir nesne \"%s\" kalıcı nesnesine bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14710 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "kalıcı bir nesne \"%s\" geçici nesnesine bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14718 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "başka bir oturumun geçici nesnesinin bölümlemesi olarak eklenemez" + +#: commands/tablecmds.c:14725 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "başka bir oturumun geçici nesnesi bölümleme olarak eklenemez" + +#: commands/tablecmds.c:14731 +#, c-format +msgid "cannot attach table \"%s\" without OIDs as partition of table \"%s\" with OIDs" +msgstr "OID olmayan \"%s\" tablosu, OID olan \"%s\" tablosunun bölümlemesi olarak eklenemez" + +#: commands/tablecmds.c:14739 +#, c-format +msgid "cannot attach table \"%s\" with OIDs as partition of table \"%s\" without OIDs" +msgstr "OID olan \"%s\" tablosu, OID olmayan \"%s\" tablosunun bölümlemesi olarak eklenemez" + +#: commands/tablecmds.c:14761 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "\"%s\" tablosundaki \"%s\" sütunu \"%s\" üst nesnesinde (parent) bulunmuyor" + +#: commands/tablecmds.c:14764 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "Yeni bölümleme sadece üst nesnede mevcut sütunları içerebilir" + +#: commands/tablecmds.c:14776 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "\"%s\" tetikleyicisi \"%s\" tablosunun bölümleme olmasını engelliyor" + +#: commands/tablecmds.c:14778 commands/trigger.c:462 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "geçiş tablolu ROW tetikleyiciler bölümlemelerde desteklenmiyor" + +#: commands/tablecmds.c:15468 commands/tablecmds.c:15487 commands/tablecmds.c:15509 commands/tablecmds.c:15528 commands/tablecmds.c:15584 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "\"%s\" indeksi, \"%s\" indeksinin bölümlemesi olarak eklenemez" + +#: commands/tablecmds.c:15471 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "\"%s\" indeksi zaten başka bir indekse eklenmiş." + +#: commands/tablecmds.c:15490 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "\"%s\" indeksi \"%s\" tablosunun herhangi bir bölümlemesi üzerinde bir indeks değildir." + +#: commands/tablecmds.c:15512 +#, c-format +msgid "The index definitions do not match." +msgstr "İndeks tanımları eşleşmemektedir." + +#: commands/tablecmds.c:15531 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "\"%s\" indeksi, \"%s\" tablosundaki bir kısıtlamaya ait fakat \"%s\" indeksi için herhangi bir kısıtlama mevcut değil." + +#: commands/tablecmds.c:15587 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "\"%s\" bölümü (partition) için başka bir indeks zaten eklenmiştir." + +#: commands/tablespace.c:163 commands/tablespace.c:180 commands/tablespace.c:191 commands/tablespace.c:199 commands/tablespace.c:625 replication/slot.c:1199 storage/file/copydir.c:47 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" dizini oluşturulamadı: %m" + +#: commands/tablespace.c:210 utils/adt/genfile.c:581 +#, c-format +msgid "could not stat directory \"%s\": %m" +msgstr "\"%s\" dizinine erişilemedi: %m" + +#: commands/tablespace.c:219 +#, c-format +msgid "\"%s\" exists but is not a directory" +msgstr "\"%s\" mevcuttur ancak bir dizin değildir" + +#: commands/tablespace.c:250 +#, c-format +msgid "permission denied to create tablespace \"%s\"" +msgstr "tablespace \"%s\" oluşturma hatası" + +#: commands/tablespace.c:252 +#, c-format +msgid "Must be superuser to create a tablespace." +msgstr "Tablespace oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/tablespace.c:268 +#, c-format +msgid "tablespace location cannot contain single quotes" +msgstr "tablespace yeri adında tek tırnak bulunamaz" + +#: commands/tablespace.c:278 +#, c-format +msgid "tablespace location must be an absolute path" +msgstr "tablespace yeri gosteren ifade tam bir mutlak yol olmalıdır" + +#: commands/tablespace.c:290 +#, c-format +msgid "tablespace location \"%s\" is too long" +msgstr "tablespace yeri \"%s\" çok uzun" + +#: commands/tablespace.c:297 +#, c-format +msgid "tablespace location should not be inside the data directory" +msgstr "tablespace yeri veri dizini içinde olmamalıdır" + +#: commands/tablespace.c:306 commands/tablespace.c:952 +#, c-format +msgid "unacceptable tablespace name \"%s\"" +msgstr "\"%s\" tablespace adı kabul edilemez" + +#: commands/tablespace.c:308 commands/tablespace.c:953 +#, c-format +msgid "The prefix \"pg_\" is reserved for system tablespaces." +msgstr "\"pg_\" ön eki, sistem tablespaceler için ayrılmıştır." + +#: commands/tablespace.c:318 commands/tablespace.c:965 +#, c-format +msgid "tablespace \"%s\" already exists" +msgstr "tablespace \"%s\" zaten mevcut" + +#: commands/tablespace.c:430 commands/tablespace.c:935 commands/tablespace.c:1015 commands/tablespace.c:1083 commands/tablespace.c:1216 commands/tablespace.c:1416 +#, c-format +msgid "tablespace \"%s\" does not exist" +msgstr "\"%s\" tablespace'i mevcut değil" + +#: commands/tablespace.c:436 +#, c-format +msgid "tablespace \"%s\" does not exist, skipping" +msgstr "tabloaralığı \"%s\" mevcut değil, atlanıyor" + +#: commands/tablespace.c:512 +#, c-format +msgid "tablespace \"%s\" is not empty" +msgstr "\"%s\" tablespace boş değil" + +#: commands/tablespace.c:584 +#, c-format +msgid "directory \"%s\" does not exist" +msgstr "\"%s\" dizini mevcut değil" + +#: commands/tablespace.c:585 +#, c-format +msgid "Create this directory for the tablespace before restarting the server." +msgstr "Sunucuyu yeniden başlatmadan önce tablespace için bu dizini oluşturun." + +#: commands/tablespace.c:590 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "dizin \"%s\" için erişim hakları ayarlanamadı: %m" + +#: commands/tablespace.c:620 +#, c-format +msgid "directory \"%s\" already in use as a tablespace" +msgstr "\"%s\" dizini tablespace olarak kullanımda" + +#: commands/tablespace.c:705 commands/tablespace.c:715 postmaster/postmaster.c:1476 storage/file/fd.c:2695 storage/file/reinit.c:122 utils/adt/genfile.c:483 utils/adt/genfile.c:554 utils/adt/misc.c:436 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" dizini açılamıyor: %m" + +#: commands/tablespace.c:744 commands/tablespace.c:757 commands/tablespace.c:793 commands/tablespace.c:885 storage/file/fd.c:3125 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "\"%s\" dizini silme hatası: %m" + +#: commands/tablespace.c:806 commands/tablespace.c:894 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" kaldırma hatası: %m" + +#: commands/tablespace.c:816 commands/tablespace.c:903 +#, c-format +msgid "\"%s\" is not a directory or symbolic link" +msgstr "\"%s\" bir dizin ya da sembolik link değildir" + +#: commands/tablespace.c:1088 +#, c-format +msgid "Tablespace \"%s\" does not exist." +msgstr "\"%s\" tablespace'i mevcut değil." + +#: commands/tablespace.c:1515 +#, c-format +msgid "directories for tablespace %u could not be removed" +msgstr "%u tablespace'inin dizinleri kaldırılamadı" + +#: commands/tablespace.c:1517 +#, c-format +msgid "You can remove the directories manually if necessary." +msgstr "Gerekirse dizinleri elle kendiniz kaldırabilirsiniz." + +#: commands/trigger.c:207 commands/trigger.c:218 +#, c-format +msgid "\"%s\" is a table" +msgstr "\"%s\" bir tablodur" + +#: commands/trigger.c:209 commands/trigger.c:220 +#, c-format +msgid "Tables cannot have INSTEAD OF triggers." +msgstr "Tabloların INSTEAD OF tetikleyicileri olamaz." + +#: commands/trigger.c:237 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "Bölümlenmiş tabloların BEFORE / FOR EACH ROW tetikleyicileri (trigger) olamaz." + +#: commands/trigger.c:255 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "Bölümlenmiş tablolar üzerindeki tetikleyicilerin geçiş tabloları olamaz." + +#: commands/trigger.c:267 commands/trigger.c:274 commands/trigger.c:444 +#, c-format +msgid "\"%s\" is a view" +msgstr "\"%s\" bir görünümdür" + +#: commands/trigger.c:269 +#, c-format +msgid "Views cannot have row-level BEFORE or AFTER triggers." +msgstr "Görünümlerin (view) satır-seviyesi BEFORE veya AFTER tetikleyicileri olamaz." + +#: commands/trigger.c:276 +#, c-format +msgid "Views cannot have TRUNCATE triggers." +msgstr "Görünümlerin TRUNCATE tetikleyicileri olamaz." + +#: commands/trigger.c:284 commands/trigger.c:291 commands/trigger.c:303 commands/trigger.c:437 +#, c-format +msgid "\"%s\" is a foreign table" +msgstr "\"%s\" bir uzak tablodur" + +#: commands/trigger.c:286 +#, c-format +msgid "Foreign tables cannot have INSTEAD OF triggers." +msgstr "Uzak tabloların INSTEAD OF tetikleyicileri olamaz" + +#: commands/trigger.c:293 +#, c-format +msgid "Foreign tables cannot have TRUNCATE triggers." +msgstr "Uzak tabloların TRUNCATE tetikleyicileri olamaz" + +#: commands/trigger.c:305 +#, c-format +msgid "Foreign tables cannot have constraint triggers." +msgstr "Uzak tabloların kısıtlama tetikleyicileri olamaz" + +#: commands/trigger.c:380 +#, c-format +msgid "TRUNCATE FOR EACH ROW triggers are not supported" +msgstr "TRUNCATE FOR EACH ROW tetikleyicileri desteklenmiyor" + +#: commands/trigger.c:388 +#, c-format +msgid "INSTEAD OF triggers must be FOR EACH ROW" +msgstr "INSTEAD OF tetikleyicileri FOR EACH ROW olmalı" + +#: commands/trigger.c:392 +#, c-format +msgid "INSTEAD OF triggers cannot have WHEN conditions" +msgstr "INSTEAD OF tetikleyicilerinin WHEN şartı olamaz" + +#: commands/trigger.c:396 +#, c-format +msgid "INSTEAD OF triggers cannot have column lists" +msgstr "INSTEAD OF tetikleyicilerinin sütun listesi olamaz" + +#: commands/trigger.c:425 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "REFERENCING ibaresinde ROW değişkeni adlandırması desteklenmiyor" + +#: commands/trigger.c:426 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "Geçiş tablolarını adlandırırken OLD TABLE veya NEW TABLE kullanınız." + +#: commands/trigger.c:439 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "Uzak tablolar üzerindeki tetikleyicilerin geçiş tabloları olamaz." + +#: commands/trigger.c:446 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "Görünümler üzerindeki tetikleyicilerin geçiş tabloları olamaz." + +#: commands/trigger.c:466 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "Geçiş tablolu ROW tetikleyiciler kalıt altı (inheritance children) nesnelerde desteklenmiyor" + +#: commands/trigger.c:472 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "geçiş tablosu adı sadece bir AFTER tetikleyici için tanımlanabiir" + +#: commands/trigger.c:477 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "geçiş tablolu TRUNCATE tetikleyiciler desteklenmiyor" + +#: commands/trigger.c:494 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "geçiş tabloları birden fazla event'i olan tetikleyiciler için tanımlanamaz" + +#: commands/trigger.c:505 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "geçiş tabloları sütun listeli tetikleyiciler için tanımlanamaz" + +#: commands/trigger.c:522 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "NEW TABLE sadece bir INSERT veya UPDATE tetikleyici için tanımlanabilir" + +#: commands/trigger.c:527 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "NEW TABLE birden fazla kez tanımlanamaz" + +#: commands/trigger.c:537 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "OLD TABLE sadece bir DELETE veya UPDATE tetikleyici için tanımlanabilir" + +#: commands/trigger.c:542 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "OLD TABLE birden fazla kez tanımlanamaz" + +#: commands/trigger.c:552 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "OLD TABLE adı ve NEW TABLE adı aynı olamaz" + +#: commands/trigger.c:614 commands/trigger.c:627 +#, c-format +msgid "statement trigger's WHEN condition cannot reference column values" +msgstr "ifade tetikleyicinin WHEN şartı sütun değerlerine referans veremez" + +#: commands/trigger.c:619 +#, c-format +msgid "INSERT trigger's WHEN condition cannot reference OLD values" +msgstr "INSERT tetikleyicisinin WHEN şartı OLD değerlere referans veremez" + +#: commands/trigger.c:632 +#, c-format +msgid "DELETE trigger's WHEN condition cannot reference NEW values" +msgstr "DELETE tetikleyicisinin WHEN şartı NEW değerlere referans veremez" + +#: commands/trigger.c:637 +#, c-format +msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgstr "BEFORE tetikleyicinin WHEN şartı NEW sistem sütunlarına referans veremez" + +#: commands/trigger.c:810 commands/trigger.c:1705 +#, c-format +msgid "trigger \"%s\" for relation \"%s\" already exists" +msgstr "\"%2$s\" nesnesi için \"%1$s\" tetikleyicisi (trigger) zaten mevcut" + +#: commands/trigger.c:1230 +msgid "Found referenced table's UPDATE trigger." +msgstr "Başvurulan tablonun UPDATE tetikleyicisi bulundu." + +#: commands/trigger.c:1231 +msgid "Found referenced table's DELETE trigger." +msgstr "Başvurulan tablonun DELETE tetikleyicisi bulundu." + +#: commands/trigger.c:1232 +msgid "Found referencing table's trigger." +msgstr "Başvurulan tablonun tetikleyicisi bulundu." + +#: commands/trigger.c:1341 commands/trigger.c:1357 +#, c-format +msgid "ignoring incomplete trigger group for constraint \"%s\" %s" +msgstr "\"%s\" %s kısıtlamasına ait eksik tetikleyicisi yok sayılıyor" + +#: commands/trigger.c:1370 +#, c-format +msgid "converting trigger group into constraint \"%s\" %s" +msgstr "tetikleyicisi grubu \"%s\" %s kısıtlamasına dönüştürülüyor" + +#: commands/trigger.c:1591 commands/trigger.c:1750 commands/trigger.c:1886 +#, c-format +msgid "trigger \"%s\" for table \"%s\" does not exist" +msgstr "\"%s\" triggeri \"%s\" tablosunda mevcut değil" + +#: commands/trigger.c:1833 +#, c-format +msgid "permission denied: \"%s\" is a system trigger" +msgstr "erişim engellendi: \"%s\" bir sistem tetikleyicisidir" + +#: commands/trigger.c:2433 +#, c-format +msgid "trigger function %u returned null value" +msgstr "%u trigger fonksiyonu null değerini döndürdü" + +#: commands/trigger.c:2499 commands/trigger.c:2714 commands/trigger.c:2953 commands/trigger.c:3243 +#, c-format +msgid "BEFORE STATEMENT trigger cannot return a value" +msgstr "BEFORE STATEMENT tetikleyicisi bir değer döndüremez" + +#: commands/trigger.c:3305 executor/nodeModifyTable.c:756 executor/nodeModifyTable.c:1244 +#, c-format +msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgstr "güncellenecek (update) satır geçerli komut tarafından tetiklenen bir operasyon tarafından zaten değiştirilmiş" + +#: commands/trigger.c:3306 executor/nodeModifyTable.c:757 executor/nodeModifyTable.c:1245 +#, c-format +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." +msgstr "değişiklikleri diğer satırlara aksettirmek için BEFORE yerine AFTER tetikleyici kullanmayı düşünün" + +#: commands/trigger.c:3320 executor/execMain.c:2727 executor/nodeLockRows.c:220 executor/nodeModifyTable.c:225 executor/nodeModifyTable.c:769 executor/nodeModifyTable.c:1257 executor/nodeModifyTable.c:1433 +#, c-format +msgid "could not serialize access due to concurrent update" +msgstr "eşzamanlı update nedeniyle erişim sıralanamıyor" + +#: commands/trigger.c:3324 executor/execMain.c:2731 executor/execMain.c:2806 executor/nodeLockRows.c:224 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "kilitlenecek satır eş zamanlı bir güncelleme dolayısıyla zaten başka bir bölüme (partition) taşınmış" + +#: commands/trigger.c:5449 +#, c-format +msgid "constraint \"%s\" is not deferrable" +msgstr "\"%s\" constrainti ertelenebilir constraint değildir" + +#: commands/trigger.c:5472 +#, c-format +msgid "constraint \"%s\" does not exist" +msgstr "constraint \"%s\" mevcut değil" + +#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:679 +#, c-format +msgid "function %s should return type %s" +msgstr "%s fonksiyonu %s tipini döndürmeli" + +#: commands/tsearchcmds.c:192 +#, c-format +msgid "must be superuser to create text search parsers" +msgstr "metin arama ayrıştırıcısı yaratmak için superuser olmalısınız" + +#: commands/tsearchcmds.c:240 +#, c-format +msgid "text search parser parameter \"%s\" not recognized" +msgstr "\"%s\" metin arama ayrıştırıcısı tanımlanamadı" + +#: commands/tsearchcmds.c:250 +#, c-format +msgid "text search parser start method is required" +msgstr "metin arama ayrışırıcısının start metodu eksiktir" + +#: commands/tsearchcmds.c:255 +#, c-format +msgid "text search parser gettoken method is required" +msgstr "metin arama ayrışırıcısının gettoken metodu eksiktir" + +#: commands/tsearchcmds.c:260 +#, c-format +msgid "text search parser end method is required" +msgstr "metin arama ayrışırıcısının end metodu eksiktir" + +#: commands/tsearchcmds.c:265 +#, c-format +msgid "text search parser lextypes method is required" +msgstr "metin arama ayrışırıcısının lextypes metodu eksiktir" + +#: commands/tsearchcmds.c:384 +#, c-format +msgid "text search template \"%s\" does not accept options" +msgstr "\"%s\" metin arama şeması seçenek kabul etmiyor" + +#: commands/tsearchcmds.c:458 +#, c-format +msgid "text search template is required" +msgstr "metin arama şablonu eksiktir" + +#: commands/tsearchcmds.c:746 +#, c-format +msgid "must be superuser to create text search templates" +msgstr "metin arama şablonu yaratmak için superuser olmalısınız" + +#: commands/tsearchcmds.c:783 +#, c-format +msgid "text search template parameter \"%s\" not recognized" +msgstr "metin araama şablonu parametresi \"%s\" tanınmıyor" + +#: commands/tsearchcmds.c:793 +#, c-format +msgid "text search template lexize method is required" +msgstr "metin arama şablonun lexsize metodu eksiktir" + +#: commands/tsearchcmds.c:1000 +#, c-format +msgid "text search configuration parameter \"%s\" not recognized" +msgstr "\"%s\"metin arama yapılandırma parametresi bulunamadı" + +#: commands/tsearchcmds.c:1007 +#, c-format +msgid "cannot specify both PARSER and COPY options" +msgstr "hem PARSER hem de COPY seçenekleri belirtilemez" + +#: commands/tsearchcmds.c:1043 +#, c-format +msgid "text search parser is required" +msgstr "metin arama ayrıştırıcısı eksiktir" + +#: commands/tsearchcmds.c:1265 +#, c-format +msgid "token type \"%s\" does not exist" +msgstr "\"%s\" token tipi mevcut değil" + +#: commands/tsearchcmds.c:1486 +#, c-format +msgid "mapping for token type \"%s\" does not exist" +msgstr "\"%s\" token tipi için eşleştirme mevcut değil" + +#: commands/tsearchcmds.c:1492 +#, c-format +msgid "mapping for token type \"%s\" does not exist, skipping" +msgstr "\"%s\" token tipi için eşleştirme mevcut değil, atlanıyor" + +#: commands/tsearchcmds.c:1647 commands/tsearchcmds.c:1758 +#, c-format +msgid "invalid parameter list format: \"%s\"" +msgstr "geçersiz parametre liste biçimi: \"%s\"" + +#: commands/typecmds.c:180 +#, c-format +msgid "must be superuser to create a base type" +msgstr "base tip oluşturmak için superuser haklarına sahip olmalısınız." + +#: commands/typecmds.c:287 commands/typecmds.c:1483 +#, c-format +msgid "type attribute \"%s\" not recognized" +msgstr "\"%s\" type attribute bulunamadı" + +#: commands/typecmds.c:343 +#, c-format +msgid "invalid type category \"%s\": must be simple ASCII" +msgstr "geçersiz tip kategorisi \"%s\": basit ASCII olmalı" + +#: commands/typecmds.c:362 +#, c-format +msgid "array element type cannot be %s" +msgstr "array element veri tipi %s olamaz" + +#: commands/typecmds.c:394 +#, c-format +msgid "alignment \"%s\" not recognized" +msgstr "\"%s\" hizalanması (alignment) tanınmamaktadır" + +#: commands/typecmds.c:411 +#, c-format +msgid "storage \"%s\" not recognized" +msgstr "storage \"%s\" tanınmamaktadır" + +#: commands/typecmds.c:422 +#, c-format +msgid "type input function must be specified" +msgstr "tipin giriş fonksiyonu belirtilmelidir" + +#: commands/typecmds.c:426 +#, c-format +msgid "type output function must be specified" +msgstr "tipin çıkış fonksiyonu belirtilmelidir" + +#: commands/typecmds.c:431 +#, c-format +msgid "type modifier output function is useless without a type modifier input function" +msgstr "type modifier input function olmadan type modifier output function kullanmak anlamsızdır" + +#: commands/typecmds.c:461 +#, c-format +msgid "type input function %s must return type %s" +msgstr " %s type input function %s tipini döndürmelidir" + +#: commands/typecmds.c:478 +#, c-format +msgid "type output function %s must return type %s" +msgstr " %s type output function %s tipini döndürmelidir" + +#: commands/typecmds.c:487 +#, c-format +msgid "type receive function %s must return type %s" +msgstr " %s type receive function %s tipini döndürmelidir" + +#: commands/typecmds.c:496 +#, c-format +msgid "type send function %s must return type %s" +msgstr " %s type send function %s tipini döndürmelidir" + +#: commands/typecmds.c:561 +#, c-format +msgid "type input function %s should not be volatile" +msgstr "%s type input fonksiyonu volatil olmamalıdır" + +#: commands/typecmds.c:566 +#, c-format +msgid "type output function %s should not be volatile" +msgstr "%s type output fonksiyonu volatil olmamalıdır" + +#: commands/typecmds.c:571 +#, c-format +msgid "type receive function %s should not be volatile" +msgstr " %s type receive fonksiyonu volatil olmamalıdır" + +#: commands/typecmds.c:576 +#, c-format +msgid "type send function %s should not be volatile" +msgstr "%s type send fonksiyonu volatil olmamalıdır" + +#: commands/typecmds.c:581 +#, c-format +msgid "type modifier input function %s should not be volatile" +msgstr "%s type modifier input fonksiyonu volatile olmamalıdır" + +#: commands/typecmds.c:586 +#, c-format +msgid "type modifier output function %s should not be volatile" +msgstr "%s type modifier output fonksiyonu volatil olmamalıdır" + +#: commands/typecmds.c:813 +#, c-format +msgid "\"%s\" is not a valid base type for a domain" +msgstr "\"%s\" tipi bir domain için geçerli bir tip değildir" + +#: commands/typecmds.c:899 +#, c-format +msgid "multiple default expressions" +msgstr "birden fazla varsayılan ifade" + +#: commands/typecmds.c:961 commands/typecmds.c:970 +#, c-format +msgid "conflicting NULL/NOT NULL constraints" +msgstr "çakışan NULL/NOT NULL constraint" + +#: commands/typecmds.c:986 +#, c-format +msgid "check constraints for domains cannot be marked NO INHERIT" +msgstr "domain'ler için kontrol kısıtlamaları NO INHERIT olarak belirtilemez" + +#: commands/typecmds.c:995 commands/typecmds.c:2585 +#, c-format +msgid "unique constraints not possible for domains" +msgstr "domain'ler için unique constraint kullanılamaz" + +#: commands/typecmds.c:1001 commands/typecmds.c:2591 +#, c-format +msgid "primary key constraints not possible for domains" +msgstr "domain'ler için primary key constraint kullanılamaz" + +#: commands/typecmds.c:1007 commands/typecmds.c:2597 +#, c-format +msgid "exclusion constraints not possible for domains" +msgstr "domain'ler için exclusion constraint kullanılamaz" + +#: commands/typecmds.c:1013 commands/typecmds.c:2603 +#, c-format +msgid "foreign key constraints not possible for domains" +msgstr "domain'ler için foreign key constraint kullanılamaz" + +#: commands/typecmds.c:1022 commands/typecmds.c:2612 +#, c-format +msgid "specifying constraint deferrability not supported for domains" +msgstr "constraint ertelenebirliği domainlerde belirtilemez" + +#: commands/typecmds.c:1353 utils/cache/typcache.c:2319 +#, c-format +msgid "%s is not an enum" +msgstr "" +"%s bir enum\n" +" değildir" + +#: commands/typecmds.c:1491 +#, c-format +msgid "type attribute \"subtype\" is required" +msgstr "tip niteliği \"alttip\" (subtype) belirtilmesi gerekiyor" + +#: commands/typecmds.c:1496 +#, c-format +msgid "range subtype cannot be %s" +msgstr "aralık (range) alttipi %s olamaz" + +#: commands/typecmds.c:1515 +#, c-format +msgid "range collation specified but subtype does not support collation" +msgstr "aralık karşılaştırması belirtilmiş fakat alttip karşılaştırmayı desteklemiyor" + +#: commands/typecmds.c:1748 +#, c-format +msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" +msgstr "%s fonksiyonunun argümanı \"opaque\"tan \"cstring\"e değiştiriliyor" + +#: commands/typecmds.c:1799 +#, c-format +msgid "changing argument type of function %s from \"opaque\" to %s" +msgstr "%s fonksiyonunun argümanı \"opaque\"tan \"%s\"e değiştiriliyor" + +#: commands/typecmds.c:1898 +#, c-format +msgid "typmod_in function %s must return type %s" +msgstr " %s typmod_in fonksiyonu %s tipini döndürmelidir" + +#: commands/typecmds.c:1925 +#, c-format +msgid "typmod_out function %s must return type %s" +msgstr "%s typmod_out fonksiyonu %s tipini döndürmelidir" + +#: commands/typecmds.c:1952 +#, c-format +msgid "type analyze function %s must return type %s" +msgstr "%s tip analiz fonksiyonu %s tipini döndürmelidir" + +#: commands/typecmds.c:1998 +#, c-format +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." +msgstr "Aralık tipi için operator sınıfı belirtmeli veya alttipi için varsayılan operator sınıfı tanımlamalısınız." + +#: commands/typecmds.c:2029 +#, c-format +msgid "range canonical function %s must return range type" +msgstr " %s aralık (range) canonical fonksiyonu aralık tipini döndürmelidir" + +#: commands/typecmds.c:2035 +#, c-format +msgid "range canonical function %s must be immutable" +msgstr "%s aralık (range) canonical fonksiyonu immutable olmalıdır" + +#: commands/typecmds.c:2071 +#, c-format +msgid "range subtype diff function %s must return type %s" +msgstr "%s range subtype diff fonksiyonu %s tipini döndürmelidir" + +#: commands/typecmds.c:2078 +#, c-format +msgid "range subtype diff function %s must be immutable" +msgstr "%s range subtype diff fonksiyonu immutable olmalıdır" + +#: commands/typecmds.c:2105 +#, c-format +msgid "pg_type array OID value not set when in binary upgrade mode" +msgstr "binary upgrade modda pg_type dizi OID değeri ayarlanmamış" + +#: commands/typecmds.c:2410 +#, c-format +msgid "column \"%s\" of table \"%s\" contains null values" +msgstr "\"%2$s\" tablosunun \"%1$s\" sütununda null değerler mevcut" + +#: commands/typecmds.c:2524 commands/typecmds.c:2709 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist" +msgstr "\"%2$s\" domain'in \"%1$s\" kısıtlaması mevcut değil" + +#: commands/typecmds.c:2528 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" +msgstr "\"%2$s\" domain'in \"%1$s\" kısıtlaması mevcut değil, atlanıyor" + +#: commands/typecmds.c:2716 +#, c-format +msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" +msgstr "\"%2$s\" domain'in \"%1$s\" kısıtlaması bir kontrol kısıtlaması değil" + +#: commands/typecmds.c:2822 +#, c-format +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgstr "\"%2$s\" tablosunun \"%1$s\" sütununda yeni constrainti ihlal eden değerler mevcut" + +#: commands/typecmds.c:3050 commands/typecmds.c:3256 commands/typecmds.c:3338 commands/typecmds.c:3525 +#, c-format +msgid "%s is not a domain" +msgstr "%s bir domain değildir" + +#: commands/typecmds.c:3083 +#, c-format +msgid "constraint \"%s\" for domain \"%s\" already exists" +msgstr "\"%2$s\" domain için \"%1$s\" constraint için zaten mevcut" + +#: commands/typecmds.c:3134 +#, c-format +msgid "cannot use table references in domain check constraint" +msgstr "domain check constraintte tablo referansları kullanılamaz" + +#: commands/typecmds.c:3268 commands/typecmds.c:3350 commands/typecmds.c:3642 +#, c-format +msgid "%s is a table's row type" +msgstr "%s bir tablo satır tipidir" + +#: commands/typecmds.c:3270 commands/typecmds.c:3352 commands/typecmds.c:3644 +#, c-format +msgid "Use ALTER TABLE instead." +msgstr "Bunun yerine ALTER TABLE kullanın." + +#: commands/typecmds.c:3277 commands/typecmds.c:3359 commands/typecmds.c:3557 +#, c-format +msgid "cannot alter array type %s" +msgstr "%s array tipi değiştirilemez" + +#: commands/typecmds.c:3279 commands/typecmds.c:3361 commands/typecmds.c:3559 +#, c-format +msgid "You can alter type %s, which will alter the array type as well." +msgstr "%s tipini değiştirebilirsiniz, aynı zamanda array type de değiştirilecektir." + +#: commands/typecmds.c:3627 +#, c-format +msgid "type \"%s\" already exists in schema \"%s\"" +msgstr "\"%s\" tipi zaten \"%s\" şemasında mevcuttur" + +#: commands/user.c:141 +#, c-format +msgid "SYSID can no longer be specified" +msgstr "SYSID artık belirtilemez" + +#: commands/user.c:295 +#, c-format +msgid "must be superuser to create superusers" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: commands/user.c:302 +#, c-format +msgid "must be superuser to create replication users" +msgstr "replikasyon kullanıcılarını oluşturmak için superuser olmalısınız" + +#: commands/user.c:309 commands/user.c:707 +#, c-format +msgid "must be superuser to change bypassrls attribute" +msgstr "bypassrls niteliğini değiştirmek için superuser haklarına sahip olmalısınız." + +#: commands/user.c:316 +#, c-format +msgid "permission denied to create role" +msgstr "rol oluşturılmasına izin verilmedi." + +#: commands/user.c:326 commands/user.c:1195 commands/user.c:1202 gram.y:14873 gram.y:14911 utils/adt/acl.c:5342 utils/adt/acl.c:5348 +#, c-format +msgid "role name \"%s\" is reserved" +msgstr "\"%s\" rol adı sistem tarafından kullanılmaktadır" + +#: commands/user.c:328 commands/user.c:1197 commands/user.c:1204 +#, c-format +msgid "Role names starting with \"pg_\" are reserved." +msgstr "\"pg_\" ile başlayan rol adları sistem için ayrılmıştır" + +#: commands/user.c:340 commands/user.c:1210 +#, c-format +msgid "role \"%s\" already exists" +msgstr "\"%s\" rolü zaten mevcut" + +#: commands/user.c:406 commands/user.c:816 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "boş string geçerli bir parola değildir, parola temizleniyor" + +#: commands/user.c:437 +#, c-format +msgid "pg_authid OID value not set when in binary upgrade mode" +msgstr "biary upgrade modundayken pg_authid OID değeri ayarlanmamış" + +#: commands/user.c:693 commands/user.c:915 commands/user.c:1449 commands/user.c:1593 +#, c-format +msgid "must be superuser to alter superusers" +msgstr "superuserleri değiştirmek için superuser olmalısınız" + +#: commands/user.c:700 +#, c-format +msgid "must be superuser to alter replication users" +msgstr "replikasyon kullanıcılarını değiştirmek için superuser olmalısınız" + +#: commands/user.c:723 commands/user.c:923 +#, c-format +msgid "permission denied" +msgstr "erişim engellendi" + +#: commands/user.c:953 +#, c-format +msgid "must be superuser to alter settings globally" +msgstr "ayarları evrensel olarak değiştirmek için superuser olmalısınız" + +#: commands/user.c:975 +#, c-format +msgid "permission denied to drop role" +msgstr "rol kaldırılmasına izin verilmedi" + +#: commands/user.c:999 +#, c-format +msgid "cannot use special role specifier in DROP ROLE" +msgstr "DROP ROLE içinde özel rol belirtici kullanılamaz" + +#: commands/user.c:1009 commands/user.c:1166 commands/variable.c:822 commands/variable.c:894 utils/adt/acl.c:5199 utils/adt/acl.c:5246 utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 +#, c-format +msgid "role \"%s\" does not exist" +msgstr "\"%s\" rolü mevcut değil" + +#: commands/user.c:1014 +#, c-format +msgid "role \"%s\" does not exist, skipping" +msgstr "rol \"%s\" mevcut değil, atlanıyor" + +#: commands/user.c:1026 commands/user.c:1030 +#, c-format +msgid "current user cannot be dropped" +msgstr "geçerli kullanıcı kaldıramaz" + +#: commands/user.c:1034 +#, c-format +msgid "session user cannot be dropped" +msgstr "oturum kullanıcısı kaldıramaz" + +#: commands/user.c:1045 +#, c-format +msgid "must be superuser to drop superusers" +msgstr "superuser kullanıcıları drop etmek için superuser olmalısınız" + +#: commands/user.c:1061 +#, c-format +msgid "role \"%s\" cannot be dropped because some objects depend on it" +msgstr "diğer nesnelerin ona bağlı olması nedeniyle \"%s\" rolü kaldırılamıyor" + +#: commands/user.c:1182 +#, c-format +msgid "session user cannot be renamed" +msgstr "oturum kullanıcısının adı değiştirilemez" + +#: commands/user.c:1186 +#, c-format +msgid "current user cannot be renamed" +msgstr "geçerli kullanıcının adı değiştirilemez" + +#: commands/user.c:1220 +#, c-format +msgid "must be superuser to rename superusers" +msgstr "superuser kullanıcıların adlarını değiştirmek için superuser olmalısınız" + +#: commands/user.c:1227 +#, c-format +msgid "permission denied to rename role" +msgstr "rol adını değiştirilmesine izin verilmedi" + +#: commands/user.c:1248 +#, c-format +msgid "MD5 password cleared because of role rename" +msgstr "rol adı değiştirildiği için MD5 şifresi sıfırlanmıştır" + +#: commands/user.c:1308 +#, c-format +msgid "column names cannot be included in GRANT/REVOKE ROLE" +msgstr "GRANT/REVOKE/ROLE içinde sütun adları dahil edilemez" + +#: commands/user.c:1346 +#, c-format +msgid "permission denied to drop objects" +msgstr "nesne düşürülmesine izin verilmedi" + +#: commands/user.c:1373 commands/user.c:1382 +#, c-format +msgid "permission denied to reassign objects" +msgstr "nesne sahipliğini değiştirmeye izin verilmedi" + +#: commands/user.c:1457 commands/user.c:1601 +#, c-format +msgid "must have admin option on role \"%s\"" +msgstr "\"%s\" rolünde admin opsiyonuna sahip olmalıdır" + +#: commands/user.c:1474 +#, c-format +msgid "must be superuser to set grantor" +msgstr "atama etkisine sahipliğini dağıtmak için superuser olmalısınız" + +#: commands/user.c:1499 +#, c-format +msgid "role \"%s\" is a member of role \"%s\"" +msgstr "\"%s\" rolü, \"%s\" rolüne dahildir" + +#: commands/user.c:1514 +#, c-format +msgid "role \"%s\" is already a member of role \"%s\"" +msgstr "\"%s\" rolü zaten \"%s\" rolüne dahildir" + +#: commands/user.c:1623 +#, c-format +msgid "role \"%s\" is not a member of role \"%s\"" +msgstr "\"%s\" rolü, \"%s\" rolüne dahil değildir" + +#: commands/vacuum.c:111 +#, c-format +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "bir sütun listesi verildiği zaman ANALAYZE seçeneği belirtilmelidir" + +#: commands/vacuum.c:203 +#, c-format +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "%s, VACUUM veya ANALYZE 'dan çalıştırılamaz" + +#: commands/vacuum.c:213 +#, c-format +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "DISABLE_PAGE_SKIPPING VACUUM seçeneği FULL ile kullanılamaz" + +#: commands/vacuum.c:657 +#, c-format +msgid "oldest xmin is far in the past" +msgstr "en eski xmin uzun zaman önce yaratılmıştır" + +#: commands/vacuum.c:658 +#, c-format +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"Başa sarma (wraparound) probleminden kaçınmak için açık işlemleri (transaction) kapatın.\n" +"Ayrıca eski prepared transaction'ları commit ya da roll back etmeniz, veya eski replikasyon slotlarını kaldırmanız gerekebilir." + +#: commands/vacuum.c:698 +#, c-format +msgid "oldest multixact is far in the past" +msgstr "en eski multixact çok uzun zaman önce yaratılmıştır" + +#: commands/vacuum.c:699 +#, c-format +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "Başa dönme sorununu yaşamamak için multixactlı aktif transactionları kapatın." + +#: commands/vacuum.c:1245 +#, c-format +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "bazı veritabanlaı iki milyarı aşkın transaction vacuum işlemi yapılmadan işlemişler" + +#: commands/vacuum.c:1246 +#, c-format +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "transaction-wraparound veri kaybını zaten yaşamış olabilirsiniz." + +#: commands/vacuum.c:1418 +#, c-format +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "\"%s\"nin vacuum'u atlanıyor --- kilit kullanılabilir değil" + +#: commands/vacuum.c:1423 +#, c-format +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "\"%s\"nin vacuum'u atlanıyor --- nesne artık mevcut değil" + +#: commands/vacuum.c:1447 +#, c-format +msgid "skipping \"%s\" --- only superuser can vacuum it" +msgstr "\"%s\" atlanıyor --- sadece superuser onu vacuum edebilir" + +#: commands/vacuum.c:1451 +#, c-format +msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" +msgstr "\"%s\" atlanıyor --- sadece superuser veya veritabanı sahibi onu vacuum edebilir" + +#: commands/vacuum.c:1455 +#, c-format +msgid "skipping \"%s\" --- only table or database owner can vacuum it" +msgstr "\"%s\" atlanıyor --- sadece tablo veya veritabanı sahibi onu vacuum edebilir" + +#: commands/vacuum.c:1472 +#, c-format +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "\"%s\" atlanıyor --- tablo harici nesneler ve sistem tablolaları vacuum edilemez" + +#: commands/vacuumlazy.c:378 +#, c-format +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "\"%s.%s.%s\" tablosunun otomatik agresif vacuum'u: indeks taramaları :%d\n" + +#: commands/vacuumlazy.c:380 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "\"%s.%s.%s\" tablosunun otomatik vacuum'u: indeks taramaları :%d\n" + +#: commands/vacuumlazy.c:386 +#, c-format +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "sayfalar (page): %u kaldırıldı, %u duruyor, %u pinler dolayısıyla atlanan, %u frozen atlanan\n" + +#: commands/vacuumlazy.c:392 +#, c-format +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "satırlar (tuple): %.0f kaldırıldı, %.0f duruyor, %.0f ölü fakat henüz kaldırılabilir olmayan, en eski xmin: %u\n" + +#: commands/vacuumlazy.c:398 +#, c-format +msgid "buffer usage: %d hits, %d misses, %d dirtied\n" +msgstr "buffer kullanımı: %d isabet, %d kaçan, %d kirli\n" + +#: commands/vacuumlazy.c:402 +#, c-format +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "ort. okuma hızı: %.3f MB/s, ort. yazma hızı: %.3f MB/s\n" + +#: commands/vacuumlazy.c:404 +#, c-format +msgid "system usage: %s" +msgstr "sistem kullanımı: %s" + +#: commands/vacuumlazy.c:500 +#, c-format +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "\"%s.%s\" agresif olarak vacuum ediliyor" + +#: commands/vacuumlazy.c:881 +#, c-format +msgid "relation \"%s\" page %u is uninitialized --- fixing" +msgstr "\"%s\" nesnesi, %u, sayfası sıfırlanmamış --- düzeltiyorum" + +#: commands/vacuumlazy.c:1417 +#, c-format +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%1$s\": %3$u sayfada %2$.0f satır sürümü kaldırılmış" + +#: commands/vacuumlazy.c:1427 +#, c-format +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f ölü satır sürümü şu an kaldırılamıyor, en eski xmin: %u\n" + +#: commands/vacuumlazy.c:1429 +#, c-format +msgid "There were %.0f unused item pointers.\n" +msgstr "%.0f kullanılmayan item pointeri vardı.\n" + +#: commands/vacuumlazy.c:1431 +#, c-format +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "Buffer pin'lerinden dolayı %u sayfa atlandı," +msgstr[1] "Buffer pin'lerinden dolayı %u sayfa atlandı," + +#: commands/vacuumlazy.c:1435 +#, c-format +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u dondurulmuş (frozen) sayfa.\n" +msgstr[1] "%u dondurulmuş (frozen) sayfa.\n" + +#: commands/vacuumlazy.c:1439 +#, c-format +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u sayfa tamamen boş.\n" +msgstr[1] "%u sayfa tamamen boş.\n" + +#: commands/vacuumlazy.c:1443 +#, c-format +msgid "%s." +msgstr "%s." + +#: commands/vacuumlazy.c:1446 +#, c-format +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%1$s\": bulunan %2$.0f kaldırılabilen, %3$.0f sabit satır sürümleri, toplam %5$u sayfanın %4$u i" + +#: commands/vacuumlazy.c:1515 +#, c-format +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%1$s\": %3$d sayfada %2$d satır sürümü kaldırılmış" + +#: commands/vacuumlazy.c:1704 +#, c-format +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "\"%s\" indeksi tarandı, %d satır sürümü kaldırıldı" + +#: commands/vacuumlazy.c:1756 +#, c-format +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "\"%s\" indexi %.0f satır sürümü, %u sayfa" + +#: commands/vacuumlazy.c:1760 +#, c-format +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"%.0f index sürüm satırı kaldırıldı.\n" +"%u index sayfası silindi, %u şu an kullanılabilir.\n" +"%s" + +#: commands/vacuumlazy.c:1855 +#, c-format +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\": çakışan kilit isteğinden dolayı \"truncate\" durduruluyor" + +#: commands/vacuumlazy.c:1920 +#, c-format +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": %u sayfadan %u sayfaya düşürülmüştür" + +#: commands/vacuumlazy.c:1985 +#, c-format +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\": çakışan kilit isteğinden dolayı \"truncate\" askıya alınıyor (suspend)" + +#: commands/variable.c:165 utils/misc/guc.c:10307 utils/misc/guc.c:10369 +#, c-format +msgid "Unrecognized key word: \"%s\"." +msgstr "Anahtar kelime anlaşılamıyor: \"%s\"." + +#: commands/variable.c:177 +#, c-format +msgid "Conflicting \"datestyle\" specifications." +msgstr "Çakışan \"datestyle\" tanımları." + +#: commands/variable.c:299 +#, c-format +msgid "Cannot specify months in time zone interval." +msgstr "Saat dilimi aralığında aylar tanımlanamıyor." + +#: commands/variable.c:305 +#, c-format +msgid "Cannot specify days in time zone interval." +msgstr "Saat dilimi aralığında günler belirtilemiyor." + +#: commands/variable.c:343 commands/variable.c:425 +#, c-format +msgid "time zone \"%s\" appears to use leap seconds" +msgstr "\"%s\" zaman dilimi artış saniyeleri kullanmaktadır" + +#: commands/variable.c:345 commands/variable.c:427 +#, c-format +msgid "PostgreSQL does not support leap seconds." +msgstr "PostgreSQL, artış saniyeleri desteklememektedir." + +#: commands/variable.c:354 +#, c-format +msgid "UTC timezone offset is out of range." +msgstr "UTC saat dilimi kaydırma (offset) değeri aralık dışında." + +#: commands/variable.c:494 +#, c-format +msgid "cannot set transaction read-write mode inside a read-only transaction" +msgstr "salt okunur transaction içinde okuma-yazma moduna ayarlanamıyor" + +#: commands/variable.c:501 +#, c-format +msgid "transaction read-write mode must be set before any query" +msgstr "transaction okuma-yazma modu bir sorgudan daha önce ayarlanmalıdır" + +#: commands/variable.c:508 +#, c-format +msgid "cannot set transaction read-write mode during recovery" +msgstr "kurtarma sırasında transaction okuma-yazma modu ayarlanamıyor" + +#: commands/variable.c:557 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" +msgstr "bir sorgudan önce SET TRANSACTION ISOLATION LEVEL çağırılmalıdır" + +#: commands/variable.c:564 +#, c-format +msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" +msgstr "subtransaction içinde SET TRANSACTION ISOLATION LEVEL çağırılmamalıdır" + +#: commands/variable.c:571 storage/lmgr/predicate.c:1603 +#, c-format +msgid "cannot use serializable mode in a hot standby" +msgstr "hot standby'da serializable mode kullanılamaz" + +#: commands/variable.c:572 +#, c-format +msgid "You can use REPEATABLE READ instead." +msgstr "Onun yerine REPEATABLE READ kullanabilirsiniz." + +#: commands/variable.c:620 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgstr "SET TRANSACTION [NOT] DEFERRABLE bir alt işlem (subtransaction) içinde çağırılamaz" + +#: commands/variable.c:626 +#, c-format +msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" +msgstr "SET TRANSACTION [NOT] DEFERRABLE herhangi bir sorgudan önce çağırılmalıdır" + +#: commands/variable.c:708 +#, c-format +msgid "Conversion between %s and %s is not supported." +msgstr "%s ile %s arasında conversion desteklenmemektedir." + +#: commands/variable.c:715 +#, c-format +msgid "Cannot change \"client_encoding\" now." +msgstr "Şu anda \"client-encoding\" değiştirilemiyor." + +#: commands/variable.c:776 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "paralel işlem sırasında client_encoding değiştirilemez." + +#: commands/variable.c:912 +#, c-format +msgid "permission denied to set role \"%s\"" +msgstr "\"%s\" rolü ayarlanması engellendi" + +#: commands/view.c:54 +#, c-format +msgid "invalid value for \"check_option\" option" +msgstr "\"check_option\" seçeneği için geçersiz değer" + +#: commands/view.c:55 +#, c-format +msgid "Valid values are \"local\" and \"cascaded\"." +msgstr "Geçerli değerler \"local\" ve \"cascaded\"." + +#: commands/view.c:103 +#, c-format +msgid "could not determine which collation to use for view column \"%s\"" +msgstr "\"%s\" view sütunu için hangi collation kullanılacağı belirlenemedi" + +#: commands/view.c:117 +#, c-format +msgid "view must have at least one column" +msgstr "viewda en az bir sütun olmalıdır" + +#: commands/view.c:285 commands/view.c:297 +#, c-format +msgid "cannot drop columns from view" +msgstr "view'den sütun silinemez" + +#: commands/view.c:302 +#, c-format +msgid "cannot change name of view column \"%s\" to \"%s\"" +msgstr "view sütunu \"%s\" den \"%s\" e ad değiştirme hatası" + +#: commands/view.c:310 +#, c-format +msgid "cannot change data type of view column \"%s\" from %s to %s" +msgstr "\"%s\" view sütununun tipi %s'den %s'ye değiştirilemiyor" + +#: commands/view.c:455 +#, c-format +msgid "views must not contain SELECT INTO" +msgstr "görünüm (view) içerisinde SELECT INTO kullanılamaz" + +#: commands/view.c:467 +#, c-format +msgid "views must not contain data-modifying statements in WITH" +msgstr "görünümler WITH içinde veri değiştiren ifadeler bulundurmamalı" + +#: commands/view.c:537 +#, c-format +msgid "CREATE VIEW specifies more column names than columns" +msgstr "CREATE VIEW sütun sayısından çok sütün adı belirtmektedir" + +#: commands/view.c:545 +#, c-format +msgid "views cannot be unlogged because they do not have storage" +msgstr "veri saklamadıkları için görünümlerin (view) loglama durumu değiştirilemez" + +#: commands/view.c:559 +#, c-format +msgid "view \"%s\" will be a temporary view" +msgstr "\"%s\" view, bir geçeci view olacaktır" + +#: executor/execCurrent.c:78 +#, c-format +msgid "cursor \"%s\" is not a SELECT query" +msgstr "\"%s\" imleci SELECT sorgusu değil" + +#: executor/execCurrent.c:84 +#, c-format +msgid "cursor \"%s\" is held from a previous transaction" +msgstr "önceki işlemden \"%s\" cursoru tutulmaktadır" + +#: executor/execCurrent.c:116 +#, c-format +msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" +msgstr "\"%s\" cursor'ında, \"%s\" tablosuna çoklu FOR UPDATE/SHARE referansı bulunuyor" + +#: executor/execCurrent.c:125 +#, c-format +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgstr "\"%s\" cursor'ında, \"%s\" tablosuna FOR UPDATE/SHARE referansı bulunmuyor" + +#: executor/execCurrent.c:135 executor/execCurrent.c:180 +#, c-format +msgid "cursor \"%s\" is not positioned on a row" +msgstr " \"%s\" imleci (cursor) bir satıra konumlandırılmamış" + +#: executor/execCurrent.c:167 executor/execCurrent.c:226 executor/execCurrent.c:238 +#, c-format +msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" +msgstr "\"%s\" imleci (cursor) \"%s\" tablosunun basit güncellenebilir bir taraması (scan) değildir" + +#: executor/execCurrent.c:280 executor/execExprInterp.c:2284 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "%d parametresinin tipi (%s) planın hazırlandığı andakiyle (%s) uyuşmuyor" + +#: executor/execCurrent.c:292 executor/execExprInterp.c:2296 +#, c-format +msgid "no value found for parameter %d" +msgstr "%d parametresi içim değer bulunamadı" + +#: executor/execExpr.c:856 parser/parse_agg.c:794 +#, c-format +msgid "window function calls cannot be nested" +msgstr "window fonksiyon çağırmaları içiçe olamaz" + +#: executor/execExpr.c:1314 +#, c-format +msgid "target type is not an array" +msgstr "hedef tipi array değildir" + +#: executor/execExpr.c:1647 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW() sütünü %2$s yerine %1$s tipine sahip" + +#: executor/execExpr.c:2182 executor/execSRF.c:697 parser/parse_func.c:126 parser/parse_func.c:640 parser/parse_func.c:1014 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "bir fonksiyona %d sayısından fazla argüman gönderilemez" +msgstr[1] "bir fonksiyona %d sayısından fazla argüman gönderilemez" + +#: executor/execExpr.c:2480 executor/execExpr.c:2486 executor/execExprInterp.c:2613 utils/adt/arrayfuncs.c:261 utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5303 utils/adt/arrayfuncs.c:5820 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "dizin boyut sayısı (%d), izin verilern en yüksek değerini (%d) aşmaktadır" + +#: executor/execExprInterp.c:1879 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "attribute %d (%s tipinin) çıkarıldı (drop)" + +#: executor/execExprInterp.c:1885 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "attribute %d (%s tipinin) yanlış tipe sahiptir" + +#: executor/execExprInterp.c:1887 executor/execExprInterp.c:2886 executor/execExprInterp.c:2933 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "Tablonun tipi %s iken, sorgu %s beklemektedir." + +#: executor/execExprInterp.c:2374 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "Bu tablo tipi için WHERE CURRENT OF desteklenmemektedir" + +#: executor/execExprInterp.c:2591 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "uyumsuz dizinleri birleştirilemez" + +#: executor/execExprInterp.c:2592 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "%s öğe tipi olan dizin, %s öğe tipi olan dizin ile aynı ARRAY içine eklenemez" + +#: executor/execExprInterp.c:2633 executor/execExprInterp.c:2663 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "çok boyutlu dizinler boyut sayısı kadar dizin ifade sayısına sahip olmalıdırlar" + +#: executor/execExprInterp.c:2885 executor/execExprInterp.c:2932 +#, c-format +msgid "attribute %d has wrong type" +msgstr "attribute %d yanlış tipe sahiptir" + +#: executor/execExprInterp.c:3042 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "atamada array subscript null olamaz" + +#: executor/execExprInterp.c:3475 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "%s domaini null değerleri almamaktadır" + +#: executor/execExprInterp.c:3490 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "%s domaine kaydedilecek değer \"%s\" check kısıtlamasını desteklememektedir" + +#: executor/execExprInterp.c:3861 executor/execExprInterp.c:3878 executor/execExprInterp.c:3980 executor/nodeModifyTable.c:106 executor/nodeModifyTable.c:117 executor/nodeModifyTable.c:134 executor/nodeModifyTable.c:142 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "sorgu-tanımlı sonuç satırı ve tablonun sonuç satırı uyuşmamaktadır" + +#: executor/execExprInterp.c:3862 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "Sorgu, döndürülen satırın %2$d sütundan oluşmasını beklerken, %1$d sütun geldi." +msgstr[1] "Sorgu, döndürülen satırın %2$d sütundan oluşmasını beklerken, %1$d sütun geldi." + +#: executor/execExprInterp.c:3879 executor/nodeModifyTable.c:118 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "Sorgu, %2$d adresine döndürme tipi %1$s iken, %3$s bekliyor." + +#: executor/execExprInterp.c:3981 executor/execSRF.c:953 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "%d adresinde düşürülmüş sütunda fiziksel saklam uyuşmazlığı." + +#: executor/execIndexing.c:543 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" +msgstr "ON CONFLICT ertelenebilir unique kısıtlamalarını/exclusion kısıtlamalarını belirleyici olarak desteklemiyor" + +#: executor/execIndexing.c:818 +#, c-format +msgid "could not create exclusion constraint \"%s\"" +msgstr "\"%s\" eclusion kıstılaması (constraint) oluşturulamadı" + +#: executor/execIndexing.c:821 +#, c-format +msgid "Key %s conflicts with key %s." +msgstr "%s anahtarı, %s anahtarı ile uyuşmuyor." + +#: executor/execIndexing.c:823 +#, c-format +msgid "Key conflicts exist." +msgstr "Anahtar uyuşmazlıkları mevcut." + +#: executor/execIndexing.c:829 +#, c-format +msgid "conflicting key value violates exclusion constraint \"%s\"" +msgstr "uyuşmayan kayıt, \"%s\" exclusion kısıtlamasını ihlal etmektedir" + +#: executor/execIndexing.c:832 +#, c-format +msgid "Key %s conflicts with existing key %s." +msgstr "%s anahtarı, mevcut %s anahtarıyla uyuşmuyor." + +#: executor/execIndexing.c:834 +#, c-format +msgid "Key conflicts with existing key." +msgstr "Anahtar mevcut anahtarla uyuşmuyor." + +#: executor/execMain.c:1116 +#, c-format +msgid "cannot change sequence \"%s\"" +msgstr "\"%s\" sequence değiştirilemez" + +#: executor/execMain.c:1122 +#, c-format +msgid "cannot change TOAST relation \"%s\"" +msgstr "\"%s\" TOAST objesi değiştirilemez" + +#: executor/execMain.c:1140 rewrite/rewriteHandler.c:2773 +#, c-format +msgid "cannot insert into view \"%s\"" +msgstr "\"%s\" view yazma hatası" + +#: executor/execMain.c:1142 rewrite/rewriteHandler.c:2776 +#, c-format +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "View'e kayıt eklemeyi (insert) etkinleştirmek için, INSTEAD OF INSERT trigger'ı ya da şartsız bir ON INSERT DO INSTEAD kuralı oluşturun." + +#: executor/execMain.c:1148 rewrite/rewriteHandler.c:2781 +#, c-format +msgid "cannot update view \"%s\"" +msgstr "\"%s\" view'i değiştirilemiyor" + +#: executor/execMain.c:1150 rewrite/rewriteHandler.c:2784 +#, c-format +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "View'de kayıt güncellemeyi (update) etkinleştirmek için, INSTEAD OF UPDATE trigger'ı ya da şartsız bir ON UPDATE DO INSTEAD kuralı oluşturun." + +#: executor/execMain.c:1156 rewrite/rewriteHandler.c:2789 +#, c-format +msgid "cannot delete from view \"%s\"" +msgstr "\"%s\" view'i silme hatası" + +#: executor/execMain.c:1158 rewrite/rewriteHandler.c:2792 +#, c-format +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "View'den silme işlemini etkinleştirmek için, INSTEAD OF DELETE veya şartsız bir ON DELETE DO INSTEAD kuralı oluşturun." + +#: executor/execMain.c:1169 +#, c-format +msgid "cannot change materialized view \"%s\"" +msgstr "\"%s\" materialized view'i değiştirilemiyor" + +#: executor/execMain.c:1181 +#, c-format +msgid "cannot insert into foreign table \"%s\"" +msgstr "\"%s\" foreign tablosuna insert yapılamıyor" + +#: executor/execMain.c:1187 +#, c-format +msgid "foreign table \"%s\" does not allow inserts" +msgstr "\"%s\" foreign tablosu insert işlemine izin vermiyor" + +#: executor/execMain.c:1194 +#, c-format +msgid "cannot update foreign table \"%s\"" +msgstr "\"%s\" foreign tablosu güncellenemiyor (update)" + +#: executor/execMain.c:1200 +#, c-format +msgid "foreign table \"%s\" does not allow updates" +msgstr "%s foreign tablosu güncellemelere (update) izin vermiyor" + +#: executor/execMain.c:1207 +#, c-format +msgid "cannot delete from foreign table \"%s\"" +msgstr "\"%s\" foreign tablosundan silme işlemi yapılamıyor" + +#: executor/execMain.c:1213 +#, c-format +msgid "foreign table \"%s\" does not allow deletes" +msgstr "\"%s\" foreign tablosu silme işlemlerine izin vermiyor" + +#: executor/execMain.c:1224 +#, c-format +msgid "cannot change relation \"%s\"" +msgstr "\"%s\" nesnesi değiştirilemiyor" + +#: executor/execMain.c:1251 +#, c-format +msgid "cannot lock rows in sequence \"%s\"" +msgstr "\"%s\" sequence'inde satırlar kilitlenemiyor" + +#: executor/execMain.c:1258 +#, c-format +msgid "cannot lock rows in TOAST relation \"%s\"" +msgstr "\"%s\" TOAST nesnesinde satırlar kilitlenemiyor değiştirilemez" + +#: executor/execMain.c:1265 +#, c-format +msgid "cannot lock rows in view \"%s\"" +msgstr "\"%s\" view'indeki satırlar kilitlenemiyor" + +#: executor/execMain.c:1273 +#, c-format +msgid "cannot lock rows in materialized view \"%s\"" +msgstr "\"%s\" materialized view'indeki satırlar kilitlenemiyor" + +#: executor/execMain.c:1282 executor/execMain.c:2974 executor/nodeLockRows.c:136 +#, c-format +msgid "cannot lock rows in foreign table \"%s\"" +msgstr "\"%s\" foreign tablosundaki satırlar kilitlenemiyor" + +#: executor/execMain.c:1288 +#, c-format +msgid "cannot lock rows in relation \"%s\"" +msgstr "\"%s\" nesnesindeki satırlar için lock alınamadı" + +#: executor/execMain.c:1959 +#, c-format +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "\"%s\" tablosuna girilen yeni satır, bölümleme (partition) kısıtlamasını ihlal ediyor" + +#: executor/execMain.c:1961 executor/execMain.c:2041 executor/execMain.c:2088 executor/execMain.c:2195 +#, c-format +msgid "Failing row contains %s." +msgstr "Hata veren satır %s içeriyor." + +#: executor/execMain.c:2039 +#, c-format +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "\"%s\" sütununda null değeri not-null kısıtlamasını ihlal ediyor" + +#: executor/execMain.c:2086 +#, c-format +msgid "new row for relation \"%s\" violates check constraint \"%s\"" +msgstr "\"%s\" tablosuna girilen yeni satır \"%s\" check kısıtlamasını ihlal ediyor" + +#: executor/execMain.c:2193 +#, c-format +msgid "new row violates check option for view \"%s\"" +msgstr "\"%s\" tablosuna girilen yeni satır check opsiyonunu ihlal ediyor" + +#: executor/execMain.c:2203 +#, c-format +msgid "new row violates row-level security policy \"%s\" for table \"%s\"" +msgstr "yeni kayıt, \"%2$s\" tablosunun satır-seviyesi güvenlik politikasını \"%1$s\" ihlal ediyor" + +#: executor/execMain.c:2208 +#, c-format +msgid "new row violates row-level security policy for table \"%s\"" +msgstr "yeni kayıt, \"%s\" tablosunun satır-seviyesi güvenlik politikasını ihlal ediyor" + +#: executor/execMain.c:2215 +#, c-format +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" +msgstr "yeni kayıt, \"%2$s\" tablosunun \"%1$s\" satır-seviyesi güvenlik politikasını (USING ifadesi) ihlal ediyor" + +#: executor/execMain.c:2220 +#, c-format +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" +msgstr "yeni kayıt, \"%s\" tablosunun satır-seviyesi güvenlik politikasını (USING ifadesi) ihlal ediyor" + +#: executor/execPartition.c:337 +#, c-format +msgid "no partition of relation \"%s\" found for row" +msgstr "satır için \"%s\" nesnesinde partition bulunmuyor" + +#: executor/execPartition.c:339 +#, c-format +msgid "Partition key of the failing row contains %s." +msgstr "Başarısız olan satırda bölümleme anahtarı %s içeriyor." + +#: executor/execReplication.c:197 executor/execReplication.c:356 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "kilitlenecek satır eş zamanlı bir güncelleme dolayısıyla zaten başka bir bölüme (partition) taşınmış, tekrar deneniyor" + +#: executor/execReplication.c:201 executor/execReplication.c:360 +#, c-format +msgid "concurrent update, retrying" +msgstr "eşzamanlı güncelleme, tekrar deneniyor" + +#: executor/execReplication.c:257 parser/parse_oper.c:228 utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4141 utils/adt/arrayfuncs.c:6101 utils/adt/rowtypes.c:1179 +#, c-format +msgid "could not identify an equality operator for type %s" +msgstr "%s tipi için eşitleme işlemi bulunamadı " + +#: executor/execReplication.c:573 +#, c-format +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "\"%s\" tablosunda bir replika özdeşliği (identity) bulunmadığı ve güncellemeleri yayınladığı (publish) için güncelleme (update) yapılamadı" + +#: executor/execReplication.c:575 +#, c-format +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Tablonun güncellemeyi etkinleştirmek için ALTER TABLE kullanarak REPLICA IDENTITY'sini ayarlayın." + +#: executor/execReplication.c:579 +#, c-format +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "\"%s\" tablosunda bir replica özdeşliği bulunmadığı ve silme işlemlerini yayınladığı (publish) için silme yapılamadı" + +#: executor/execReplication.c:581 +#, c-format +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "Tabloda silmeyi etkinleştirmek için, ALTER TABLE kullanarak REPLICA IDENTITY'sini ayarlayın." + +#: executor/execReplication.c:600 +#, c-format +msgid "logical replication target relation \"%s.%s\" is not a table" +msgstr "mantıksal replikasyon hedef nesnesi \"%s.%s\" bir tablo değildir" + +#: executor/execSRF.c:308 +#, c-format +msgid "rows returned by function are not all of the same row type" +msgstr "fonksiyon tarafından döndürülen satırların tamamı aynı satır tipinde değil" + +#: executor/execSRF.c:356 executor/execSRF.c:647 +#, c-format +msgid "table-function protocol for materialize mode was not followed" +msgstr "materialize biçimi için table-function protokolü izlenmemiş" + +#: executor/execSRF.c:363 executor/execSRF.c:665 +#, c-format +msgid "unrecognized table-function returnMode: %d" +msgstr "belinmeyen table-function returnMode: %d" + +#: executor/execSRF.c:871 +#, c-format +msgid "function returning setof record called in context that cannot accept type record" +msgstr "RECORD tipi kabul edemeyen bağlamda çağırılan ve SETOF RECORD döndüren fonksiyon" + +#: executor/execSRF.c:926 executor/execSRF.c:942 executor/execSRF.c:952 +#, c-format +msgid "function return row and query-specified return row do not match" +msgstr "sorgu-tanımlı sonuç satırı ve gerçek sonuç satırı uyuşmamaktadır" + +#: executor/execSRF.c:927 +#, c-format +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "Sorgu, döndürülen satırın %2$d sütundan oluşmasını beklerken, %1$d sütun geldi." +msgstr[1] "Sorgu, döndürülen satırın %2$d sütundan oluşmasını beklerken, %1$d sütun geldi." + +#: executor/execSRF.c:943 +#, c-format +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "Sorgu, %2$d adresine döndürme tipi %1$s iken, %3$s bekliyor." + +#: executor/execUtils.c:687 +#, c-format +msgid "materialized view \"%s\" has not been populated" +msgstr "\"%s\" materialized view'i doldurulmamış" + +#: executor/execUtils.c:689 +#, c-format +msgid "Use the REFRESH MATERIALIZED VIEW command." +msgstr "REFRESH MATERIALIZED VIEW komutunu kullanın." + +#: executor/functions.c:225 +#, c-format +msgid "could not determine actual type of argument declared %s" +msgstr "tipi %s olarak tanımlanmış fonksiyonun parametresinin gerçek döndürme tipi belirlenememektedir" + +#: executor/functions.c:521 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "Bir SQL fonksiyonunda istemciye ya da istemciden COPY çalıştırılamaz" + +#. translator: %s is a SQL statement name +#: executor/functions.c:527 +#, c-format +msgid "%s is not allowed in a SQL function" +msgstr "%s, bir SQL fonksiyonunda yer alamaz" + +#. translator: %s is a SQL statement name +#: executor/functions.c:535 executor/spi.c:1422 executor/spi.c:2212 +#, c-format +msgid "%s is not allowed in a non-volatile function" +msgstr "non-volatile fonksiyonda %s kullanılamaz" + +#: executor/functions.c:656 +#, c-format +msgid "could not determine actual result type for function declared to return type %s" +msgstr "geri döndürme tipi %s olarak tanımlanmış fonksiyonun gerçek döndürme tipi belirlenememektedir" + +#: executor/functions.c:1418 +#, c-format +msgid "SQL function \"%s\" statement %d" +msgstr "\"%s\" SQL fonksiyonu, %d komutu" + +#: executor/functions.c:1444 +#, c-format +msgid "SQL function \"%s\" during startup" +msgstr "başlangıç sırasında \"%s\" SQL fonksiyonu" + +#: executor/functions.c:1537 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "SQL fonksiyonlarında çıktı argümanları olan prosedürlerin çağrılması desteklenmemektedir" + +#: executor/functions.c:1657 executor/functions.c:1690 executor/functions.c:1702 executor/functions.c:1826 executor/functions.c:1859 executor/functions.c:1889 +#, c-format +msgid "return type mismatch in function declared to return %s" +msgstr "%s dönüşlü bildirilmiş işlevde return deyimin tipi uyumsuz" + +#: executor/functions.c:1659 +#, c-format +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgstr "Fonksiyonun son ifadesi SELECT ya da INSERT/UPDATE/DELETE RETURNING olmalıdır." + +#: executor/functions.c:1692 +#, c-format +msgid "Final statement must return exactly one column." +msgstr "Son ifade tam bir satır döndürmelidir." + +#: executor/functions.c:1704 +#, c-format +msgid "Actual return type is %s." +msgstr "Asıl döndürme tipi %s." + +#: executor/functions.c:1828 +#, c-format +msgid "Final statement returns too many columns." +msgstr "Son ifade fazla satır döndürüyor." + +#: executor/functions.c:1861 +#, c-format +msgid "Final statement returns %s instead of %s at column %d." +msgstr "Son ifade %3$d sütununda %2$s yerine %1$s döndürüyor." + +#: executor/functions.c:1891 +#, c-format +msgid "Final statement returns too few columns." +msgstr "Son ifade çok az sütun döndürüyor." + +#: executor/functions.c:1940 +#, c-format +msgid "return type %s is not supported for SQL functions" +msgstr "SQL fonksiyonların içinde %s dönüş tipi desteklenmemektedir" + +#: executor/nodeAgg.c:2802 parser/parse_agg.c:633 parser/parse_agg.c:663 +#, c-format +msgid "aggregate function calls cannot be nested" +msgstr "aggregate fonksiyon çağırmaları içiçe olamaz" + +#: executor/nodeAgg.c:2988 executor/nodeWindowAgg.c:2822 +#, c-format +msgid "aggregate %u needs to have compatible input type and transition type" +msgstr "%u aggregate fonksiyonu uyumlu giriş ve geçiş tiplerine sahip olmalıdır" + +#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 +#, c-format +msgid "custom scan \"%s\" does not support MarkPos" +msgstr "\"%s\" özel taramasının (custom scan) MarkPos desteği yoktur." + +#: executor/nodeHashjoin.c:1040 executor/nodeHashjoin.c:1070 +#, c-format +msgid "could not rewind hash-join temporary file: %m" +msgstr "geçici hash-join dosyasına başa alma işlemi başarısız: %m" + +#: executor/nodeHashjoin.c:1228 executor/nodeHashjoin.c:1234 +#, c-format +msgid "could not write to hash-join temporary file: %m" +msgstr "geçici hash-join dosyasına yazma başarısız: %m" + +#: executor/nodeHashjoin.c:1275 executor/nodeHashjoin.c:1285 +#, c-format +msgid "could not read from hash-join temporary file: %m" +msgstr "geçici hash-join dosyasına okuma başarısız: %m" + +#: executor/nodeIndexonlyscan.c:236 +#, c-format +msgid "lossy distance functions are not supported in index-only scans" +msgstr "index-only taramalarda (scan) lossy distance fonksiyonları desteklenmemektedir" + +#: executor/nodeLimit.c:264 +#, c-format +msgid "OFFSET must not be negative" +msgstr "OFFSET negatif olmamalıdır" + +#: executor/nodeLimit.c:290 +#, c-format +msgid "LIMIT must not be negative" +msgstr "LIMIT negatif sayı olmamalı" + +#: executor/nodeMergejoin.c:1567 +#, c-format +msgid "RIGHT JOIN is only supported with merge-joinable join conditions" +msgstr "RIGHT JOIN ancak merge-join işlemine uygun şartlarında desteklenmektedir" + +#: executor/nodeMergejoin.c:1585 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable join conditions" +msgstr "FULL JOIN ancak merge-join işlemine uygun şartlarında desteklenmektedir" + +#: executor/nodeModifyTable.c:107 +#, c-format +msgid "Query has too many columns." +msgstr "Sorgu (query) çok fazla sütuna sahip." + +#: executor/nodeModifyTable.c:135 +#, c-format +msgid "Query provides a value for a dropped column at ordinal position %d." +msgstr "Sorgu %d sıralı konumundaki düşürülmüş bir sütun için değer içermektedir" + +#: executor/nodeModifyTable.c:143 +#, c-format +msgid "Query has too few columns." +msgstr "Sorgunun (query) sütun sayısı yetersiz" + +#: executor/nodeModifyTable.c:773 +#, c-format +msgid "tuple to be deleted was already moved to another partition due to concurrent update" +msgstr "silinecek satır eş zamanlı bir güncelleme dolayısıyla zaten başka bir bölüme (partiton) taşınmış" + +#: executor/nodeModifyTable.c:1085 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "geçersiz ON UPDATE tanımlaması" + +#: executor/nodeModifyTable.c:1086 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "Sonuç satırı orjinal satırdan farklı bir bölümde (partition) görünecek" + +#: executor/nodeModifyTable.c:1261 +#, c-format +msgid "tuple to be updated was already moved to another partition due to concurrent update" +msgstr "güncellenecek satır eş zamanlı bir güncelleme dolayısıyla zaten başka bir bölüme (partiton) taşınmış" + +#: executor/nodeModifyTable.c:1412 +#, c-format +msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" +msgstr "ON CONFLICT DO UPDATE komutu satırı ikinci bir kez daha etkileyemez" + +#: executor/nodeModifyTable.c:1413 +#, c-format +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." +msgstr "Eklemek üzere önerilen, aynı komutun içindeki hiçbir satırın, bir kısıtlamayı ihlal eden mükerrer değerleri olmadığından emin olun." + +#: executor/nodeSamplescan.c:279 +#, c-format +msgid "TABLESAMPLE parameter cannot be null" +msgstr "TABLESAMPLE parametresi null olamaz" + +#: executor/nodeSamplescan.c:291 +#, c-format +msgid "TABLESAMPLE REPEATABLE parameter cannot be null" +msgstr "TABLESAMPLE REPEATABLE parametresi null olamaz" + +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 executor/nodeSubplan.c:1127 +#, c-format +msgid "more than one row returned by a subquery used as an expression" +msgstr "ifade içinde kullanılan alt sorgusu birden fazla satır döndürüldü" + +#: executor/nodeTableFuncscan.c:375 +#, c-format +msgid "namespace URI must not be null" +msgstr "namespace URI değeri null olmamalı" + +#: executor/nodeTableFuncscan.c:389 +#, c-format +msgid "row filter expression must not be null" +msgstr "row filter ifadesi null olmamalı" + +#: executor/nodeTableFuncscan.c:415 +#, c-format +msgid "column filter expression must not be null" +msgstr "colun filter ifadesi null olmamalı" + +#: executor/nodeTableFuncscan.c:416 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "\"%s\" sütunu için filtre null" + +#: executor/nodeTableFuncscan.c:506 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr " \"%s\" sütununda null değerine izin verilmez" + +#: executor/nodeWindowAgg.c:355 +#, c-format +msgid "moving-aggregate transition function must not return null" +msgstr "hareketli-toplam (moving aggregate) geçiş fonksiyonu null döndürmemelidir" + +#: executor/nodeWindowAgg.c:2057 +#, c-format +msgid "frame starting offset must not be null" +msgstr "frame starting offset null olmamalı" + +#: executor/nodeWindowAgg.c:2070 +#, c-format +msgid "frame starting offset must not be negative" +msgstr "frame starting offset negatif olmamalı" + +#: executor/nodeWindowAgg.c:2082 +#, c-format +msgid "frame ending offset must not be null" +msgstr "frame ending offset null olmamalı" + +#: executor/nodeWindowAgg.c:2095 +#, c-format +msgid "frame ending offset must not be negative" +msgstr "frame ending offset negatif olmamalı" + +#: executor/nodeWindowAgg.c:2738 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "%s aggregate fonksiyonu bir window fonksiyonu olarak kullanımı desteklememektedir" + +#: executor/spi.c:233 executor/spi.c:272 +#, c-format +msgid "invalid transaction termination" +msgstr "geçersiz işlem (transaction) sonlandırma" + +#: executor/spi.c:247 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "bir alt işlem (subtransaction) aktifken commit yapılamaz" + +#: executor/spi.c:278 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "bir alt işlem (subtransaction) aktifken rollback yapılamaz" + +#: executor/spi.c:317 +#, c-format +msgid "transaction left non-empty SPI stack" +msgstr "transaction boş olamayan SPI stack bıraktı" + +#: executor/spi.c:318 executor/spi.c:381 +#, c-format +msgid "Check for missing \"SPI_finish\" calls." +msgstr "Atlanan \"SPI_finish\" çağırılarına bakın." + +#: executor/spi.c:380 +#, c-format +msgid "subtransaction left non-empty SPI stack" +msgstr "subtransaction left non-empty SPI stack" + +#: executor/spi.c:1283 +#, c-format +msgid "cannot open multi-query plan as cursor" +msgstr "multi-query plan imleç olarak açılmıyor" + +#. translator: %s is name of a SQL command, eg INSERT +#: executor/spi.c:1288 +#, c-format +msgid "cannot open %s query as cursor" +msgstr "%s sorgusu sorgusunu imleç olarak açılmıyor" + +#: executor/spi.c:1393 +#, c-format +msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" +msgstr "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE desteklenmiyor" + +#: executor/spi.c:1394 parser/analyze.c:2480 +#, c-format +msgid "Scrollable cursors must be READ ONLY." +msgstr "Scrollable cursorkar READ ONLY olmalıdır." + +#: executor/spi.c:2534 +#, c-format +msgid "SQL statement \"%s\"" +msgstr "SQL deyimi: \"%s\"" + +#: executor/tqueue.c:70 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "satır shared memory kuyruğuna (queue) gönderilemedi" + +#: foreign/foreign.c:188 +#, c-format +msgid "user mapping not found for \"%s\"" +msgstr "\"%s\" için kullanıcı eşleştirme yok" + +#: foreign/foreign.c:640 +#, c-format +msgid "invalid option \"%s\"" +msgstr "geeçersiz seçenek \"%s\"" + +#: foreign/foreign.c:641 +#, c-format +msgid "Valid options in this context are: %s" +msgstr "Bu bağlamda geçerli seçenekler: %s" + +#: gram.y:1026 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD artık desteklenmiyor" + +#: gram.y:1027 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "Onun yerine parolayı şifreli halde saklamak için UNENCRYPTED ibaresini kaldırın." + +#: gram.y:1089 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "tanımsız rol seçeneği \"%s\"" + +#: gram.y:1336 gram.y:1351 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTS şema elemanları içeremez" + +#: gram.y:1496 +#, c-format +msgid "current database cannot be changed" +msgstr "geçerli veritabanı değiştirilemez" + +#: gram.y:1620 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "zaman dilimi aralığı HOUR veya HOUR TO MINUTE olmalıdır" + +#: gram.y:2138 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "sütun numarası 1 - %d aralığında olmalı" + +#: gram.y:2677 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "\"%s\" sequence seçeneği burada desteklenmiyor" + +#: gram.y:2706 +#, fuzzy, c-format +#| msgid "option \"%s\" provided more than once" +msgid "modulus for hash partition provided more than once" +msgstr "\"%s\" seçeneği birden fazla belirtilmiş" + +#: gram.y:2715 +#, fuzzy, c-format +#| msgid "option \"%s\" provided more than once" +msgid "remainder for hash partition provided more than once" +msgstr "\"%s\" seçeneği birden fazla belirtilmiş" + +#: gram.y:2722 +#, fuzzy, c-format +#| msgid "unrecognized exception condition \"%s\"" +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "tanımlanamayan exception durumu \"%s\"" + +#: gram.y:2730 +#, fuzzy, c-format +#| msgid "type output function must be specified" +msgid "modulus for hash partition must be specified" +msgstr "tipin çıkış fonksiyonu belirtilmelidir" + +#: gram.y:2734 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "hash partition için kalan (remainder) belirtilmelidir" + +#: gram.y:2986 gram.y:3015 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "PROGRAM ile STDIN/STDOUT kullanımına izin verilmez" + +#: gram.y:3325 gram.y:3332 gram.y:11462 gram.y:11470 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "geçici (temporary) tablu oluştururken GLOBAL kullanımdan kaldırıldı" + +#: gram.y:3814 utils/adt/ri_triggers.c:308 utils/adt/ri_triggers.c:365 utils/adt/ri_triggers.c:853 utils/adt/ri_triggers.c:1013 utils/adt/ri_triggers.c:1198 utils/adt/ri_triggers.c:1419 utils/adt/ri_triggers.c:1654 utils/adt/ri_triggers.c:1712 utils/adt/ri_triggers.c:1817 utils/adt/ri_triggers.c:1997 +#, c-format +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL implemente edilmemiştir" + +#: gram.y:5296 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "tanımlanamayan satır güvenlik seçeneği \"%s\"" + +#: gram.y:5297 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "Şu anda sadece PERMISSIVE ve RESTRICTIVE tarzı desteklenemektedir." + +#: gram.y:5405 +msgid "duplicate trigger events specified" +msgstr "tekrarlı (duplicate) trigger event'ler belirtilmiştir" + +#: gram.y:5546 parser/parse_utilcmd.c:3313 parser/parse_utilcmd.c:3339 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "INITIALLY DEFERRED olarak tanımlanan kısıtlayıcı DEFERRABLE özelliğine sahip olmalıdır" + +#: gram.y:5553 +#, c-format +msgid "conflicting constraint properties" +msgstr "çakışan kısıtlama (constraint) özellikleri" + +#: gram.y:5659 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION implemente edilmemiştir" + +#: gram.y:5674 +#, c-format +msgid "DROP ASSERTION is not yet implemented" +msgstr "DROP ASSERTION implemente edilmemiştir" + +#: gram.y:6054 +#, c-format +msgid "RECHECK is no longer required" +msgstr "RECHECK artık gerekmemektedir" + +#: gram.y:6055 +#, c-format +msgid "Update your data type." +msgstr "Veri tipinizi güncelleyin." + +#: gram.y:7791 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "toplamların (aggregate) çıktı argümanları olamaz" + +#: gram.y:8179 utils/adt/regproc.c:691 utils/adt/regproc.c:732 +#, c-format +msgid "missing argument" +msgstr "argüman eksik" + +#: gram.y:8180 utils/adt/regproc.c:692 utils/adt/regproc.c:733 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "Unary operator'un bir argümanı eksik olduğunu göstermek için NONE kullanın" + +#: gram.y:10045 gram.y:10063 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "WITH CHECK OPTION recursive görünümlerde (view) desteklenmemektedir" + +#: gram.y:10560 +#, c-format +msgid "unrecognized VACUUM option \"%s\"" +msgstr "tanımsız VACUUM seçeneği \"%s\"" + +#: gram.y:11570 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "LIMIT #,# sözdizimi desteklenmemektedir" + +#: gram.y:11571 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "Ayrı LIMIT ve OFFSET ifadeleri kullanın." + +#: gram.y:11869 gram.y:11894 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "FROM öğesindeki VALUES'ler bir alias almalıdır" + +#: gram.y:11870 gram.y:11895 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "Örneğin, FROM (VALUES ...) [AS] birşey." + +#: gram.y:11875 gram.y:11900 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "FROM öğesindeki subquery bir aliası almalıdır" + +#: gram.y:11876 gram.y:11901 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "Örneğin, FROM (SELECT ...) [AS] birşey." + +#: gram.y:12354 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "sadece tek bir DEFAULT değere izin verilmektedir" + +#: gram.y:12363 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "sütun aşına sadece tek bir PATH değerine izin verilmektedir" + +#: gram.y:12372 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "\"%s\" sütunu için çelişen ya da gereksiz (redundant) NULL/NOT NULL tanımları" + +#: gram.y:12381 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "tanımlanamayan sütun seçeneği \"%s\"" + +#: gram.y:12635 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "float veri tipinin kesinliği en az 1 bit olmalıdır" + +#: gram.y:12644 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "float veri tipinin kesinliği ne çok 54 bit olabilir" + +#: gram.y:13135 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPS ifadesinin sol tarafında yanlış parametre sayısı kullanılmış" + +#: gram.y:13140 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPS ifadesinin sağ tarafında yanlış parametre sayısı kullanılmış" + +#: gram.y:13315 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "UNIQUE predicate implemente edilmemiştir" + +#: gram.y:13662 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "WITHIN GROUP ile birden çok ORDER BY ifadesi kullanılamaz" + +#: gram.y:13667 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "WITHIN GROUP ile DISTINCT kullanılamaz" + +#: gram.y:13672 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "WITHIN GROUP ile VARIADIC kullanılamaz" + +#: gram.y:14125 gram.y:14148 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "frame başlangıcı (start) UNBOUNDED FOLLOWING olamaz" + +#: gram.y:14130 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "takibeden satırdan başlayan frame geçerli (current) satırla bitemez" + +#: gram.y:14153 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "frame sonu UNBOUNDED PRECEDING olamaz" + +#: gram.y:14159 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "geçerli (current) satırdan başlayan frame önceki satırları içeremez" + +#: gram.y:14166 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "takibeden satırdan başlayan frame önceki satırları içeremez" + +#: gram.y:14809 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "tip değiştirici (type modifier) parametre adına sahip olamaz" + +#: gram.y:14815 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "tip değiştirici (type modifier) ORDER BY içeremez" + +#: gram.y:14880 gram.y:14887 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "%s burada bir rol adı olarak kullanılamaz" + +#: gram.y:15558 gram.y:15747 +msgid "improper use of \"*\"" +msgstr "\"*\"'nin geçersiz kullanımı" + +#: gram.y:15710 gram.y:15727 tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 +#, c-format +msgid "syntax error" +msgstr "söz dizim hatası " + +#: gram.y:15811 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "" + +#: gram.y:15848 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "birden çok ORDER BY ifadesi kullanılamaz" + +#: gram.y:15859 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "birden fazla OFFSET ifadesi desteklenmemektedir" + +#: gram.y:15868 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "birden çok LIMIT ifadesi kullanılamaz" + +#: gram.y:15877 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "birden çok WITH ifadesi kullanılamaz" + +#: gram.y:16081 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "TABLE fonksiyonlarında OUT Ve INOUT argümanlarına izin verilmez" + +#: gram.y:16182 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "birden çok COLLATE ifadesi kullanılamaz" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16220 gram.y:16233 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "\"%s\" constrainti ertelenebilir (DEFERRABLE) olarak tanımlanamaz" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16246 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "\"%s\" constrainti NOT VALID olarak tanımlanamaz" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16259 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "\"%s\" constrainti NO INHERIT olarak tanımlanamz" + +#: guc-file.l:316 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "\"%2$s\" dosyası %3$u satırında \"%1$s\" bilinmeyen konfigurasyon parametresi" + +#: guc-file.l:353 utils/misc/guc.c:6249 utils/misc/guc.c:6443 utils/misc/guc.c:6533 utils/misc/guc.c:6623 utils/misc/guc.c:6731 utils/misc/guc.c:6826 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "\"%s\" parametresi sunucuyu yeniden başlatmadan değiştirilemez" + +#: guc-file.l:389 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "\"%s\" parametresi yapılandırma dosyasından çıkarıldı, varsayılana sıfırla" + +#: guc-file.l:455 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "\"%s\" parametresi \"%s\" olarak değiştirildi" + +#: guc-file.l:497 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "\"%s\" yapılandırma dosyasında hatalar var" + +#: guc-file.l:502 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "\"%s\" yapılandırma dosyasında hatalar var; etkilenmeyen değişiklikler uygulandı" + +#: guc-file.l:507 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "\"%s\" yapılandırma dosyasında hatalar var; değişiklikler uygulanmadı" + +#: guc-file.l:580 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "yapılandırma dosyası \"%s\" açılamadı: en yüksek içiçe yuvalama derinliği aşılmıştır" + +#: guc-file.l:596 libpq/hba.c:2142 libpq/hba.c:2550 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "yapılandırma dosyası \"%s\" açılamadı: %m" + +#: guc-file.l:607 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "eksik \"%s\" yapılandırma dosyası atlanıyor" + +#: guc-file.l:861 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "\"%s\" dosyasının %u. satırında satır sonunda sözdizimi hatası" + +#: guc-file.l:871 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "\"%s\" dosyasının %u. satırında, \"%s\" ifadesi yakınında sözdizimi hatası" + +#: guc-file.l:891 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "çok fazla sözdizimi hatası bulundu, \"%s\" dosyası bırakılıyor (abandon)" + +#: guc-file.l:943 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "yapılandırma dizini \"%s\" açılamadı: %m" + +#: jit/jit.c:208 utils/fmgr/dfmgr.c:201 utils/fmgr/dfmgr.c:418 utils/fmgr/dfmgr.c:466 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "\"%s\" dosyası erişim hatası: %m" + +#: jit/llvm/llvmjit.c:598 +#, c-format +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "" + +#: lib/dshash.c:247 utils/mmgr/dsa.c:715 utils/mmgr/dsa.c:797 +#, c-format +msgid "Failed on DSA request of size %zu." +msgstr "%zu boyutu DSA isteği başarısız" + +#: lib/stringinfo.c:278 +#, c-format +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "%d bayt uzunluğunda olan satır arabelleği %d bayt ile uzatılamıyor." + +#: libpq/auth-scram.c:251 +#, c-format +msgid "client selected an invalid SASL authentication mechanism" +msgstr "istemci geçersiz bir kimlik doğrulama mekanizması seçti" + +#: libpq/auth-scram.c:272 libpq/auth-scram.c:512 libpq/auth-scram.c:521 +#, c-format +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "\"%s\" kullanıcısı için geçersiz SCRAM doğrulayıcısı" + +#: libpq/auth-scram.c:283 +#, c-format +msgid "User \"%s\" does not have a valid SCRAM verifier." +msgstr "\"%s\" kullancısının geçerli bir SCRAM doğrulayıcısı yok." + +#: libpq/auth-scram.c:361 libpq/auth-scram.c:366 libpq/auth-scram.c:660 libpq/auth-scram.c:668 libpq/auth-scram.c:779 libpq/auth-scram.c:789 libpq/auth-scram.c:897 libpq/auth-scram.c:904 libpq/auth-scram.c:919 libpq/auth-scram.c:934 libpq/auth-scram.c:948 libpq/auth-scram.c:966 libpq/auth-scram.c:981 libpq/auth-scram.c:1267 libpq/auth-scram.c:1275 +#, c-format +msgid "malformed SCRAM message" +msgstr "kusurlu SCRAM mesajı" + +#: libpq/auth-scram.c:362 +#, c-format +msgid "The message is empty." +msgstr "Mesaj boş." + +#: libpq/auth-scram.c:367 +#, c-format +msgid "Message length does not match input length." +msgstr "Mesaj uzunluğu girdi uzunluğuyla uyuşmuyor." + +#: libpq/auth-scram.c:399 +#, c-format +msgid "invalid SCRAM response" +msgstr "geçersiz SCRAM karşılığı" + +#: libpq/auth-scram.c:400 +#, c-format +msgid "Nonce does not match." +msgstr "Nonce eşleşmiyor." + +#: libpq/auth-scram.c:474 +#, c-format +msgid "could not generate random salt" +msgstr "rastgele tuz (salt) oluşturulamadı" + +#: libpq/auth-scram.c:661 +#, c-format +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "\"%c\" niteliği bekleniyordu fakat \"%s\" bulundu." + +#: libpq/auth-scram.c:669 libpq/auth-scram.c:790 +#, c-format +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "\"%c\" niteliği için \"=\" karakteri bekleniyordu." + +#: libpq/auth-scram.c:780 +#, c-format +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "Nitelik bekleniyordu, fakat geçersiz karakter bulundu \"%s\"." + +#: libpq/auth-scram.c:898 libpq/auth-scram.c:920 +#, c-format +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "" + +#: libpq/auth-scram.c:905 libpq/auth-scram.c:935 +#, c-format +msgid "Comma expected, but found character \"%s\"." +msgstr "Virgül bekleniyordu, fakat \"%s\" karakteri bulundu." + +#: libpq/auth-scram.c:926 +#, fuzzy, c-format +msgid "SCRAM channel binding negotiation error" +msgstr "SCRAM channel binding anlaşması hatası" + +#: libpq/auth-scram.c:927 +#, c-format +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "" + +#: libpq/auth-scram.c:949 +#, c-format +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "" + +#: libpq/auth-scram.c:960 +#, fuzzy, c-format +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "desteklenmeyen SCRAM channel-binding tipi \"%s\"" + +#: libpq/auth-scram.c:967 +#, c-format +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "Beklenmeyen channel-binding bayrağı (flag) \"%s\"." + +#: libpq/auth-scram.c:977 +#, c-format +msgid "client uses authorization identity, but it is not supported" +msgstr "istemci yetkilendirme kimliği kullanıyor, fakat bu desteklenmiyor" + +#: libpq/auth-scram.c:982 +#, c-format +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "istemci ilk mesajında beklenmeyen özellik \"%s\"" + +#: libpq/auth-scram.c:998 +#, c-format +msgid "client requires an unsupported SCRAM extension" +msgstr "istemci desteklenmeyen bir SCRAM uzantısı gerektiriyor" + +#: libpq/auth-scram.c:1012 +#, c-format +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM nonce'sinde gösterilemeyen karakterler" + +#: libpq/auth-scram.c:1129 +#, c-format +msgid "could not generate random nonce" +msgstr "rastgele nonce oluşturulamadı" + +#: libpq/auth-scram.c:1233 +#, c-format +msgid "SCRAM channel binding check failed" +msgstr "SCRAM channel binding kontrolü başarısız oldu" + +#: libpq/auth-scram.c:1251 +#, c-format +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "istemci son mesajında (client-final-message) beklenmeyen SCRAM channel-binding özelliği" + +#: libpq/auth-scram.c:1268 +#, c-format +msgid "Malformed proof in client-final-message." +msgstr "Müşteri son mesajında hatalı biçimlenmiş kanıt." + +#: libpq/auth-scram.c:1276 +#, c-format +msgid "Garbage found at the end of client-final-message." +msgstr "Client-final-message sonunda anlamsız değer (garbage)." + +#: libpq/auth.c:282 +#, c-format +msgid "authentication failed for user \"%s\": host rejected" +msgstr "\"%s\" kullanıcısı için kimlik doğrulaması başarısız oldu: adres geçerli değil" + +#: libpq/auth.c:285 +#, c-format +msgid "\"trust\" authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için \"trust\" kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:288 +#, c-format +msgid "Ident authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için Ident kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:291 +#, c-format +msgid "Peer authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için peer kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:296 +#, c-format +msgid "password authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için şifre doğrulaması başarısız oldu" + +#: libpq/auth.c:301 +#, c-format +msgid "GSSAPI authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için GSSPI kimlik doğrulaması başarısız" + +#: libpq/auth.c:304 +#, c-format +msgid "SSPI authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için SSPI kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:307 +#, c-format +msgid "PAM authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için PAM kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:310 +#, c-format +msgid "BSD authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için BSD kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:313 +#, c-format +msgid "LDAP authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için LDAP kimlik doğrulaması başarısız" + +#: libpq/auth.c:316 +#, c-format +msgid "certificate authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için sertifika kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:319 +#, c-format +msgid "RADIUS authentication failed for user \"%s\"" +msgstr "\"%s\" kullanıcısı için RADIUS kimlik doğrulaması başarısız oldu" + +#: libpq/auth.c:322 +#, c-format +msgid "authentication failed for user \"%s\": invalid authentication method" +msgstr "\"%s\" kullanıcısının kimlik doğrulaması başarısız: geçersiz kimlik doğrulama yöntemi" + +#: libpq/auth.c:326 +#, c-format +msgid "Connection matched pg_hba.conf line %d: \"%s\"" +msgstr "Bağlantı pg_hba.conf %d satırıyla eşleşti: \"%s\"" + +#: libpq/auth.c:373 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "istemci sertifikaları ancak eğer bir kök sertifika deposu mevcutsa kontrol edilebilir" + +#: libpq/auth.c:384 +#, c-format +msgid "connection requires a valid client certificate" +msgstr "bağlantı, geçerli bir istemci sertifikasına gereksinim duyuyor." + +#: libpq/auth.c:417 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgstr "pg_hba.conf \"%s\" istemcisinden \"%s\" kullanıcısı ile gelen replikasyon bağlantısını reddetti, %s" + +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 +msgid "SSL off" +msgstr "SSL etkisiz" + +#: libpq/auth.c:419 libpq/auth.c:435 libpq/auth.c:493 libpq/auth.c:511 +msgid "SSL on" +msgstr "SSL etkin" + +#: libpq/auth.c:423 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" +msgstr "pg_hba.conf \"%s\" istemcisinden \"%s\" kullanıcısı ile gelen replikasyon bağlantısını reddetti" + +#: libpq/auth.c:432 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf \"%s\" istemcisinden \"%s\" kullanıcısı ile \"%s\" veritabanına gelen replikasyon bağlantısını reddetti, %s" + +#: libpq/auth.c:439 +#, c-format +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgstr "pg_hba.conf \"%s\" istemcisinden \"%s\" kullanıcısı ile \"%s\" veritabanına gelen replikasyon bağlantısını reddetti" + +#: libpq/auth.c:468 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup matches." +msgstr "İstemci IP adresi \"%s\"ye çözüldü, forward lookup eşleşiyor." + +#: libpq/auth.c:471 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup not checked." +msgstr "İstemci IP adresi \"%s\"ye çözüldü, forward lookup kontrol edilmedi." + +#: libpq/auth.c:474 +#, c-format +msgid "Client IP address resolved to \"%s\", forward lookup does not match." +msgstr "İstemci IP adresi \"%s\"ye çözüldü, forward lookup eşleşmiyor." + +#: libpq/auth.c:477 +#, c-format +msgid "Could not translate client host name \"%s\" to IP address: %s." +msgstr "\"%s\" istemci makine adı IP adresine çevirilemedi: %s." + +#: libpq/auth.c:482 +#, c-format +msgid "Could not resolve client IP address to a host name: %s." +msgstr "İstemci IP adresi bir makine adına çözülemedi: %s." + +#: libpq/auth.c:491 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" +msgstr "\"%s\" istemcisinden \"%s\" kullanıcısı ile gelen replikasyon bağlantısı için pg_hba.conf girdisi yok, %s" + +#: libpq/auth.c:498 +#, c-format +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgstr " \"%s\" istemcisinden \"%s\" kullanıcısı ile gelen replikasyon bağlantısı için pg_hba.conf girdisi yok." + +#: libpq/auth.c:508 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "\"%s\" adresi, \"%s\" kullanıcısı, \"%s\" veritabanı için pg_hba.conf içinde bir tanım yok, %s" + +#: libpq/auth.c:516 +#, c-format +msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" +msgstr "\"%s\" adresi, \"%s\" kullanıcısı, \"%s\" veritabanı için pg_hba.conf içinde bir tanım yok" + +#: libpq/auth.c:669 +#, c-format +msgid "expected password response, got message type %d" +msgstr "cevap olarak şifre beklenirken, %d mesaj tipi alındı" + +#: libpq/auth.c:697 +#, c-format +msgid "invalid password packet size" +msgstr "geçersiz password paket boyutu" + +#: libpq/auth.c:715 +#, c-format +msgid "empty password returned by client" +msgstr "istemci boş şifre gönderdi" + +#: libpq/auth.c:835 libpq/hba.c:1325 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "\"db_user_namespace\" etkinken MD5 yetkilendirmesi desteklenmemektedir" + +#: libpq/auth.c:841 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "rastgele MD5 tuzu oluşturulamadı" + +#: libpq/auth.c:887 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "SASL kimlik doğrulaması protokol sürüm 2'de desteklenmiyor" + +#: libpq/auth.c:920 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "SASL cevabı bekleniyordu, %d mesaj tipi alındı" + +#: libpq/auth.c:1112 +#, c-format +msgid "GSSAPI is not supported in protocol version 2" +msgstr "GSSAPI protokol 2'de desteklenmiyor" + +#: libpq/auth.c:1172 +#, c-format +msgid "expected GSS response, got message type %d" +msgstr "beklenen GSS yanıtı, %d mesaj tipi alındı" + +#: libpq/auth.c:1234 +msgid "accepting GSS security context failed" +msgstr "GSS security context kabul işlemi başarısızdır" + +#: libpq/auth.c:1260 +msgid "retrieving GSS user name failed" +msgstr "GSS user name eğişimi başarısızdır" + +#: libpq/auth.c:1385 +#, c-format +msgid "SSPI is not supported in protocol version 2" +msgstr "SSPI protokol 2'de desteklenmiyor" + +#: libpq/auth.c:1400 +msgid "could not acquire SSPI credentials" +msgstr "SSPI kimlik bilgileri alınamadı: %m" + +#: libpq/auth.c:1418 +#, c-format +msgid "expected SSPI response, got message type %d" +msgstr "SSPI yanıtı bekleniyordu, %d mesaj tipi alındı" + +#: libpq/auth.c:1491 +msgid "could not accept SSPI security context" +msgstr "SSPI güvenlik içeriği kabul edilemedi" + +#: libpq/auth.c:1553 +msgid "could not get token from SSPI security context" +msgstr "SSPI güvenlik bağlamından token alınamadı" + +#: libpq/auth.c:1672 libpq/auth.c:1691 +#, c-format +msgid "could not translate name" +msgstr "isim dönüştürülemedi" + +#: libpq/auth.c:1704 +#, c-format +msgid "realm name too long" +msgstr "alan (realm) adı çok uzun" + +#: libpq/auth.c:1719 +#, c-format +msgid "translated account name too long" +msgstr "dönüştürülen hesap ismi çok uzun" + +#: libpq/auth.c:1905 +#, c-format +msgid "could not create socket for Ident connection: %m" +msgstr "Ident bağlantısı için socket oluşturma hatası: %m" + +#: libpq/auth.c:1920 +#, c-format +msgid "could not bind to local address \"%s\": %m" +msgstr "\"%s\" yerel adresine bind hatası: %m" + +#: libpq/auth.c:1932 +#, c-format +msgid "could not connect to Ident server at address \"%s\", port %s: %m" +msgstr "\"%s\" adresi %s portunda Ident sunucusuna bağlanma hatası: %m" + +#: libpq/auth.c:1954 +#, c-format +msgid "could not send query to Ident server at address \"%s\", port %s: %m" +msgstr "\"%s\" adresi %s portunda Ident sunucusuna istek gönderme hatası: %m" + +#: libpq/auth.c:1971 +#, c-format +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" +msgstr "\"%s\" adresi %s portunda Ident sunucusundan cevap alma hatası: %m" + +#: libpq/auth.c:1981 +#, c-format +msgid "invalidly formatted response from Ident server: \"%s\"" +msgstr "Ident sunucusundan biçimlendirilmiş cevap bağlanma hatası:\"%s\"" + +#: libpq/auth.c:2021 +#, c-format +msgid "peer authentication is not supported on this platform" +msgstr "peer kimlik doğrulaması bu platformda desteklenmiyor" + +#: libpq/auth.c:2025 +#, c-format +msgid "could not get peer credentials: %m" +msgstr "karşı tarafın kimlik bilgileri alınamadı: %m" + +#: libpq/auth.c:2036 +#, c-format +msgid "could not look up local user ID %ld: %s" +msgstr "yerel kullanıcı ID %ld bulunamadı: %s" + +#: libpq/auth.c:2124 +#, c-format +msgid "error from underlying PAM layer: %s" +msgstr "PAM katmanında hata: %s" + +#: libpq/auth.c:2193 +#, c-format +msgid "could not create PAM authenticator: %s" +msgstr "PAM authenticator oluşturulamıyor: %s" + +#: libpq/auth.c:2204 +#, c-format +msgid "pam_set_item(PAM_USER) failed: %s" +msgstr "pam_set_item(PAM_USER) başarısız: %s" + +#: libpq/auth.c:2236 +#, c-format +msgid "pam_set_item(PAM_RHOST) failed: %s" +msgstr "pam_set_item(PAM_RHOST) başarısız: %s" + +#: libpq/auth.c:2248 +#, c-format +msgid "pam_set_item(PAM_CONV) failed: %s" +msgstr "pam_set_item(PAM_CONV) başarısız: %s" + +#: libpq/auth.c:2259 +#, c-format +msgid "pam_authenticate failed: %s" +msgstr "pam_authenticate başarısız: %s" + +#: libpq/auth.c:2270 +#, c-format +msgid "pam_acct_mgmt failed: %s" +msgstr "pam_acct_mgmt başarısız: %s" + +#: libpq/auth.c:2281 +#, c-format +msgid "could not release PAM authenticator: %s" +msgstr "PAM authenticator bırakma başarısız: %s" + +#: libpq/auth.c:2357 +#, c-format +msgid "could not initialize LDAP: error code %d" +msgstr "LDAP ilklendirilemiyor: hata kodu %d" + +#: libpq/auth.c:2406 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "LDAP ilklendirilemedi: %s" + +#: libpq/auth.c:2416 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "bu LDAP kütüphanesiyle ldaps desteklenmiyor" + +#: libpq/auth.c:2424 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "LDAP ilklendirilemiyor: %m" + +#: libpq/auth.c:2434 +#, c-format +msgid "could not set LDAP protocol version: %s" +msgstr "LDAP protokol sürümü ayarlanamadı: %s" + +#: libpq/auth.c:2465 +#, c-format +msgid "could not load wldap32.dll" +msgstr "wldap32.dll yüklenemedi" + +#: libpq/auth.c:2473 +#, c-format +msgid "could not load function _ldap_start_tls_sA in wldap32.dll" +msgstr "wldap32.dll kütüphanesinden _ldap_start_tls_sA fonksiyonu yüklenemedi." + +#: libpq/auth.c:2474 +#, c-format +msgid "LDAP over SSL is not supported on this platform." +msgstr "Bu platformda SSL üzerinde LDAP bu ortamda desteklenmemektedir." + +#: libpq/auth.c:2489 +#, c-format +msgid "could not start LDAP TLS session: %s" +msgstr "LDAP TLS oturumu başlatma bşarısız: %s" + +#: libpq/auth.c:2552 +#, c-format +msgid "LDAP server not specified" +msgstr "LDAP sunucu belirtilmedi" + +#: libpq/auth.c:2607 +#, c-format +msgid "invalid character in user name for LDAP authentication" +msgstr "LDAP yetkilendirmesi için kullanıcı adında geçersiz karakter" + +#: libpq/auth.c:2624 +#, c-format +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" +msgstr "\"%2$s\" sunucusunda \"%1$s\" ldapbinddn için ilk LDAP bind gerçekleştirilemedi: %3$s" + +#: libpq/auth.c:2653 +#, c-format +msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" +msgstr "\"%s\" filtresi için \"%s\" sunucusunda LDAP araması başarısız: %s" + +#: libpq/auth.c:2667 +#, c-format +msgid "LDAP user \"%s\" does not exist" +msgstr "\"%s\" LDAP kullanıcısı mevcut değil" + +#: libpq/auth.c:2668 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." +msgstr "\"%s\" filtresi için \"%s\" sunucusunda LDAP araması hiç kayıt döndürmedi." + +#: libpq/auth.c:2672 +#, c-format +msgid "LDAP user \"%s\" is not unique" +msgstr "\"%s\" LDAP kullanıcısı tek değil" + +#: libpq/auth.c:2673 +#, c-format +msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgstr[0] "\"%s\" filtresi için \"%s\" sunucusunda LDAP araması %d kayıt döndürdü." +msgstr[1] "\"%s\" filtresi için \"%s\" sunucusunda LDAP araması %d kayıt döndürdü." + +#: libpq/auth.c:2693 +#, fuzzy, c-format +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgstr "\"%s\" sunucusu hakkında bilgi alınamadı: %s\n" + +#: libpq/auth.c:2714 +#, fuzzy, c-format +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "\"%s\" kullanıcısının \"%s\" sunucusunda LDAP oturumu açma başarısız: hata kodu %d" + +#: libpq/auth.c:2745 +#, c-format +msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" +msgstr "\"%s\" kullanıcısının \"%s\" sunucusunda LDAP oturumu açma başarısız: %s" + +#: libpq/auth.c:2774 +#, c-format +msgid "LDAP diagnostics: %s" +msgstr "LDAP tanılaması: %s" + +#: libpq/auth.c:2799 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" +msgstr "\"%s\" kullanıcısının sertifika kimlik doğrulaması başarısız: istemci sertifikası kullanıcı adı içermiyor" + +#: libpq/auth.c:2902 +#, c-format +msgid "RADIUS server not specified" +msgstr "RADIUS sunucusu belirtilmedi" + +#: libpq/auth.c:2909 +#, c-format +msgid "RADIUS secret not specified" +msgstr "RADIUS parolası belirtilmedi" + +#: libpq/auth.c:2923 +#, c-format +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS yetkilendirmesi %d karakterden uzun parolaları desteklememektedir" + +#: libpq/auth.c:3028 libpq/hba.c:1908 +#, c-format +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "\"%s\" RADIUS sunucu adı adrese çevirilemedi: %s" + +#: libpq/auth.c:3042 +#, c-format +msgid "could not generate random encryption vector" +msgstr "rastgele şifreleme vektörü oluşturulamadı" + +#: libpq/auth.c:3076 +#, c-format +msgid "could not perform MD5 encryption of password" +msgstr "parolanın MD5 şifrelemesi gerçekleştirilemedi" + +#: libpq/auth.c:3102 +#, c-format +msgid "could not create RADIUS socket: %m" +msgstr "RADIUS soketi yaratılamadı: %m" + +#: libpq/auth.c:3124 +#, c-format +msgid "could not bind local RADIUS socket: %m" +msgstr "yerel RADIUS soketine bağlanılamadı: %m" + +#: libpq/auth.c:3134 +#, c-format +msgid "could not send RADIUS packet: %m" +msgstr "RADIUS paketi gönderilemedi: %m" + +#: libpq/auth.c:3167 libpq/auth.c:3193 +#, c-format +msgid "timeout waiting for RADIUS response from %s" +msgstr "%s den RADIUS cevabı beklenirken zaman aşımı oldu" + +#: libpq/auth.c:3186 +#, c-format +msgid "could not check status on RADIUS socket: %m" +msgstr "RADIUS soketindeki durum kontrol edilemedi: %m" + +#: libpq/auth.c:3216 +#, c-format +msgid "could not read RADIUS response: %m" +msgstr "RADIUS cevabı okunamadı: %m" + +#: libpq/auth.c:3229 libpq/auth.c:3233 +#, c-format +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "%s'den gelen RADIUS cevabı yanlış porttan gönderilmiş: %d" + +#: libpq/auth.c:3242 +#, c-format +msgid "RADIUS response from %s too short: %d" +msgstr "%s den gelen RADIUS cevabı çok kısa: %d" + +#: libpq/auth.c:3249 +#, c-format +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "%s'den gelen RADIUS cevabı hatalı uzunlukta: %d (gerçek uzunluk %d) " + +#: libpq/auth.c:3257 +#, c-format +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "%s'den gelen RADIUS cevabı başka bir isteğin karşılığı: %d (%d olmalıydı)" + +#: libpq/auth.c:3282 +#, c-format +msgid "could not perform MD5 encryption of received packet" +msgstr "alınan paketin MD5 şifrelemesi gerçekleştirilemedi" + +#: libpq/auth.c:3291 +#, c-format +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "%s'den alınan RADIUS cevabının MD5 imzası yanlış" + +#: libpq/auth.c:3309 +#, c-format +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "\"%3$s\" kullanıcısı %1$s'den gelen RADIUS cevabının kodu (%2$d) geçersiz" + +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:545 +#, c-format +msgid "invalid large-object descriptor: %d" +msgstr "geçersiz large-object descriptor: %d" + +#: libpq/be-fsstubs.c:161 +#, c-format +msgid "large object descriptor %d was not opened for reading" +msgstr "%d large object descriptor yazmak için açılmadı" + +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:552 +#, c-format +msgid "large object descriptor %d was not opened for writing" +msgstr "%d large object descriptor yazmak için açılmadı" + +#: libpq/be-fsstubs.c:212 +#, c-format +msgid "lo_lseek result out of range for large-object descriptor %d" +msgstr "%d büyük-nesne açıklayıcı (large-object descriptor) için lo_lseek sonucu aralık dışında" + +#: libpq/be-fsstubs.c:285 +#, c-format +msgid "lo_tell result out of range for large-object descriptor %d" +msgstr "%d büyük-nesne açıklayıcı (large-object descriptor) için lo_tell sonucu aralık dışında" + +#: libpq/be-fsstubs.c:432 +#, c-format +msgid "could not open server file \"%s\": %m" +msgstr "\"%s\" sunucu dosyası açma hatası: %m" + +#: libpq/be-fsstubs.c:454 +#, c-format +msgid "could not read server file \"%s\": %m" +msgstr "\"%s\" sunucu dosyası okuma hatası: %m" + +#: libpq/be-fsstubs.c:511 +#, c-format +msgid "could not create server file \"%s\": %m" +msgstr "\"%s\" sunucu dosyası oluşturma hatası: %m" + +#: libpq/be-fsstubs.c:523 +#, c-format +msgid "could not write server file \"%s\": %m" +msgstr "\"%s\" sunucu dosyası yazma hatası: %m" + +#: libpq/be-fsstubs.c:752 +#, c-format +msgid "large object read request is too large" +msgstr "büyük nesne okuma isteği (request) çok büyük" + +#: libpq/be-fsstubs.c:794 utils/adt/genfile.c:231 utils/adt/genfile.c:270 utils/adt/genfile.c:306 +#, c-format +msgid "requested length cannot be negative" +msgstr "istenilen uzunluk negatif olamaz" + +#: libpq/be-fsstubs.c:847 storage/large_object/inv_api.c:296 storage/large_object/inv_api.c:308 storage/large_object/inv_api.c:512 storage/large_object/inv_api.c:623 storage/large_object/inv_api.c:813 +#, c-format +msgid "permission denied for large object %u" +msgstr "%u büyük nesnesi için erişim izni reddedildi" + +#: libpq/be-secure-common.c:91 +#, c-format +msgid "could not read from command \"%s\": %m" +msgstr "\"%s\" komutundan okuma hatası: %m" + +#: libpq/be-secure-common.c:109 +#, c-format +msgid "command \"%s\" failed" +msgstr "\"%s\" komutu başarısız oldu" + +#: libpq/be-secure-common.c:139 +#, c-format +msgid "could not access private key file \"%s\": %m" +msgstr "private key dosyası \"%s\" okunamıyor: %m" + +#: libpq/be-secure-common.c:148 +#, c-format +msgid "private key file \"%s\" is not a regular file" +msgstr "\"%s\" özel anahtar (private key) dosyası düzgün bir dosya değildir" + +#: libpq/be-secure-common.c:163 +#, c-format +msgid "private key file \"%s\" must be owned by the database user or root" +msgstr "\"%s\" özel anahtar (private key) dosyasının sahibi veritabanı kullanıcısı ya da root olmalı" + +#: libpq/be-secure-common.c:186 +#, c-format +msgid "private key file \"%s\" has group or world access" +msgstr "\"%s\" özel anahtar dosyası gruba ve herkese erişime açıktır" + +#: libpq/be-secure-common.c:188 +#, c-format +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "Eğer sahibi veritabanı kullanıcısıysa dosyanın izinleri u=rw (0600) ya da daha az olmalı, eğer sahibi root ise izinleri u=rw,g=r (0640) veya daha az olmalı" + +#: libpq/be-secure-openssl.c:104 +#, c-format +msgid "could not create SSL context: %s" +msgstr "SSL context oluşturma hatası: %s" + +#: libpq/be-secure-openssl.c:147 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "sunucu srtifika dosyası \"%s\" yükleme başarısız: %s" + +#: libpq/be-secure-openssl.c:167 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "\"%s\" özel anahtar dosyası tekrar yüklenemiyor çünkü parola gerektiriyor " + +#: libpq/be-secure-openssl.c:172 +#, c-format +msgid "could not load private key file \"%s\": %s" +msgstr "private key dosyası \"%s\" okunamıyor: %s" + +#: libpq/be-secure-openssl.c:181 +#, c-format +msgid "check of private key failed: %s" +msgstr "private key denetlemesi başarısız: %s" + +#: libpq/be-secure-openssl.c:208 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "şifre listesi ayarlanamadı (geçerli şifre bulunmuyor)" + +#: libpq/be-secure-openssl.c:226 +#, c-format +msgid "could not load root certificate file \"%s\": %s" +msgstr "ana sertifika dosyası \"%s\" okunaıyor: %s" + +#: libpq/be-secure-openssl.c:253 +#, c-format +msgid "SSL certificate revocation list file \"%s\" ignored" +msgstr "SSL feshedilmiş sertifika dosyası \"%s\" yoksayıldı" + +#: libpq/be-secure-openssl.c:255 +#, c-format +msgid "SSL library does not support certificate revocation lists." +msgstr "SSL kütühanesi feshedilmiş sertifika listelerini desteklememektedir." + +#: libpq/be-secure-openssl.c:262 +#, c-format +msgid "could not load SSL certificate revocation list file \"%s\": %s" +msgstr "\"%s\" SSL sertifika iptal listesi dosyası yüklenemedi: %s" + +#: libpq/be-secure-openssl.c:337 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "SSL bağlantısı oluşturulamıyor: SSL bağlamı (context) ayarlanmamış" + +#: libpq/be-secure-openssl.c:345 +#, c-format +msgid "could not initialize SSL connection: %s" +msgstr "SSL bağlantısı oluşturulamıyor: %s" + +#: libpq/be-secure-openssl.c:353 +#, c-format +msgid "could not set SSL socket: %s" +msgstr "SSL socket kurulamıyor: %s" + +#: libpq/be-secure-openssl.c:408 +#, c-format +msgid "could not accept SSL connection: %m" +msgstr "SSL bağlantı alınamıyor: %m" + +#: libpq/be-secure-openssl.c:412 libpq/be-secure-openssl.c:423 +#, c-format +msgid "could not accept SSL connection: EOF detected" +msgstr "SSL bağlantı alınamıyor: EOF algılandı" + +#: libpq/be-secure-openssl.c:417 +#, c-format +msgid "could not accept SSL connection: %s" +msgstr "SSL bağlantı alınamıyor: %s" + +#: libpq/be-secure-openssl.c:428 libpq/be-secure-openssl.c:559 libpq/be-secure-openssl.c:623 +#, c-format +msgid "unrecognized SSL error code: %d" +msgstr "bilinmeyen SSL hata kodu: %d" + +#: libpq/be-secure-openssl.c:470 +#, c-format +msgid "SSL certificate's common name contains embedded null" +msgstr "SSL sertifikasının yaygın ismi embedded null içeriyor" + +#: libpq/be-secure-openssl.c:548 libpq/be-secure-openssl.c:607 +#, c-format +msgid "SSL error: %s" +msgstr "SSL hatası: %s" + +#: libpq/be-secure-openssl.c:788 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "\"%s\" DH parametre dosyası açma hatası: %m" + +#: libpq/be-secure-openssl.c:800 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "DH parametre dosyası yüklenemedi: %s" + +#: libpq/be-secure-openssl.c:810 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "geçersiz DH parametreleri: %s" + +#: libpq/be-secure-openssl.c:818 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "geçersiz DH parametreleri: p birincil değil" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "" + +#: libpq/be-secure-openssl.c:981 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: DH parametreleri yüklenemedi" + +#: libpq/be-secure-openssl.c:989 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: DH parametreleri ayarlanamadı: %s" + +#: libpq/be-secure-openssl.c:1013 +#, c-format +msgid "ECDH: unrecognized curve name: %s" +msgstr "ECDH: bilinmeyen curve adı: %s" + +#: libpq/be-secure-openssl.c:1022 +#, c-format +msgid "ECDH: could not create key" +msgstr "ECDH: anahtar oluşturulamadı" + +#: libpq/be-secure-openssl.c:1050 +msgid "no SSL error reported" +msgstr "SSL hata yok" + +#: libpq/be-secure-openssl.c:1054 +#, c-format +msgid "SSL error code %lu" +msgstr "SSL hata kodu: %lu" + +#: libpq/be-secure.c:119 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "\"%s\" adresinden SSL bağşantısı" + +#: libpq/be-secure.c:196 libpq/be-secure.c:284 +#, c-format +msgid "terminating connection due to unexpected postmaster exit" +msgstr "beklenmeyen postmaster çıkışı sonrası bağlantı kesiliyor" + +#: libpq/crypt.c:51 +#, c-format +msgid "Role \"%s\" does not exist." +msgstr "\"%s\" rolü mevcut değil." + +#: libpq/crypt.c:61 +#, c-format +msgid "User \"%s\" has no password assigned." +msgstr "\"%s\" kullanıcısına parola atanmamış." + +#: libpq/crypt.c:79 +#, c-format +msgid "User \"%s\" has an expired password." +msgstr "\"%s\" kullanıcısının parolasının süresi dolmuş" + +#: libpq/crypt.c:173 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "\"%s\" kullanıcısının parolası MD5 yetkilendirmesi ile kullanılamayan bir parolası var" + +#: libpq/crypt.c:197 libpq/crypt.c:238 libpq/crypt.c:262 +#, c-format +msgid "Password does not match for user \"%s\"." +msgstr "Parola \"%s\" kullanıcısıyla eşleşmiyor." + +#: libpq/crypt.c:281 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "\"%s\" kullanıcısının parolası bilinmeyen bir formattadır." + +#: libpq/hba.c:235 +#, c-format +msgid "authentication file token too long, skipping: \"%s\"" +msgstr "authentication file token uzunluğu sınırı aşmaktadır, esgeçiliyor: \"%s\"" + +#: libpq/hba.c:407 +#, c-format +msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" +msgstr "ikincil kimlik doğrulama dosyası \"@%s\", \"%s\" olarak açılamadı: %m" + +#: libpq/hba.c:509 +#, c-format +msgid "authentication file line too long" +msgstr "yetkilendirme dosya satır uzunluğu çok fazla" + +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1011 libpq/hba.c:1020 libpq/hba.c:1041 libpq/hba.c:1054 libpq/hba.c:1074 libpq/hba.c:1096 libpq/hba.c:1108 libpq/hba.c:1164 libpq/hba.c:1184 libpq/hba.c:1198 libpq/hba.c:1217 libpq/hba.c:1228 libpq/hba.c:1243 libpq/hba.c:1261 libpq/hba.c:1277 libpq/hba.c:1289 libpq/hba.c:1326 +#: libpq/hba.c:1367 libpq/hba.c:1380 libpq/hba.c:1402 libpq/hba.c:1414 libpq/hba.c:1432 libpq/hba.c:1482 libpq/hba.c:1523 libpq/hba.c:1534 libpq/hba.c:1550 libpq/hba.c:1567 libpq/hba.c:1577 libpq/hba.c:1635 libpq/hba.c:1673 libpq/hba.c:1689 libpq/hba.c:1779 libpq/hba.c:1797 libpq/hba.c:1891 libpq/hba.c:1910 libpq/hba.c:1939 libpq/hba.c:1952 libpq/hba.c:1975 libpq/hba.c:1997 +#: libpq/hba.c:2011 tsearch/ts_locale.c:190 +#, c-format +msgid "line %d of configuration file \"%s\"" +msgstr "%d . satıri \"%s\" yapılandırma dosyasında" + +#. translator: the second %s is a list of auth methods +#: libpq/hba.c:865 +#, c-format +msgid "authentication option \"%s\" is only valid for authentication methods %s" +msgstr "\"%s\" yetkilendirme seçeneği sadece şu yetkilendirme yöntemleri için geçerlidir: %s" + +#: libpq/hba.c:885 +#, c-format +msgid "authentication method \"%s\" requires argument \"%s\" to be set" +msgstr "\"%s\" yetkilendirme yöntemi \"%s\" argümanının belirtilmesini gerektiriyor" + +#: libpq/hba.c:913 +#, c-format +msgid "missing entry in file \"%s\" at end of line %d" +msgstr "\"%s\" dosyasında %d satırın sonunda eksik giriş" + +#: libpq/hba.c:924 +#, c-format +msgid "multiple values in ident field" +msgstr "ident alanında birden fazla değer" + +#: libpq/hba.c:973 +#, c-format +msgid "multiple values specified for connection type" +msgstr "bağlantı tipi için birden fazla değer belirtilmiş" + +#: libpq/hba.c:974 +#, c-format +msgid "Specify exactly one connection type per line." +msgstr "Satır başına tam olarak bir bağlantı tipi belirtin." + +#: libpq/hba.c:988 +#, c-format +msgid "local connections are not supported by this build" +msgstr "yerel bağlantılar bu yapılandırma tarafından desteklenmiyor." + +#: libpq/hba.c:1009 +#, c-format +msgid "hostssl record cannot match because SSL is disabled" +msgstr "hostssl kaydı eşleşemiyor çünkü SSL devre dışı bırakılmış" + +#: libpq/hba.c:1010 +#, c-format +msgid "Set ssl = on in postgresql.conf." +msgstr "postgresql.conf dosyasında ssl = on olarak ayarlayınız." + +#: libpq/hba.c:1018 +#, c-format +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "hostssl kaydı eşleşemiyor çünkü SSL bu yapılandırma tarafından desteklenmiyor" + +#: libpq/hba.c:1019 +#, c-format +msgid "Compile with --with-openssl to use SSL connections." +msgstr "SSL bağlantısı kullanabilmek için --with-openssl ile derleyiniz." + +#: libpq/hba.c:1039 +#, c-format +msgid "invalid connection type \"%s\"" +msgstr "geçersiz bağlantı tipi \"%s\"" + +#: libpq/hba.c:1053 +#, c-format +msgid "end-of-line before database specification" +msgstr "veritabanı tanımlamasından önce satır-sonu " + +#: libpq/hba.c:1073 +#, c-format +msgid "end-of-line before role specification" +msgstr "rol tanımlamasından önce satır-sonu" + +#: libpq/hba.c:1095 +#, c-format +msgid "end-of-line before IP address specification" +msgstr "IP adres tanımlamasından önce satır-sonu" + +#: libpq/hba.c:1106 +#, c-format +msgid "multiple values specified for host address" +msgstr "makine adresi için birden fazla değer belirtilmiş" + +#: libpq/hba.c:1107 +#, c-format +msgid "Specify one address range per line." +msgstr "Satır aşına bir adres aralığı belirtiniz." + +#: libpq/hba.c:1162 +#, c-format +msgid "invalid IP address \"%s\": %s" +msgstr "geçersiz IP adresi \"%s\": %s" + +#: libpq/hba.c:1182 +#, c-format +msgid "specifying both host name and CIDR mask is invalid: \"%s\"" +msgstr "hem makine adı hem de CIDR mask tanımlama geçersizdir: \"%s\"" + +#: libpq/hba.c:1196 +#, c-format +msgid "invalid CIDR mask in address \"%s\"" +msgstr "\"%s\" adresinde geçersiz CIDR maskesi" + +#: libpq/hba.c:1215 +#, c-format +msgid "end-of-line before netmask specification" +msgstr "netmask tanımlamasından önce satır-sonu" + +#: libpq/hba.c:1216 +#, c-format +msgid "Specify an address range in CIDR notation, or provide a separate netmask." +msgstr "" + +#: libpq/hba.c:1227 +#, c-format +msgid "multiple values specified for netmask" +msgstr "netmask için birden fazla değer belirtilmiş" + +#: libpq/hba.c:1241 +#, c-format +msgid "invalid IP mask \"%s\": %s" +msgstr "geçersiz IP maskesi \"%s\" : %s" + +#: libpq/hba.c:1260 +#, c-format +msgid "IP address and mask do not match" +msgstr "IP adresi ve maske uyuşmamaktadır" + +#: libpq/hba.c:1276 +#, c-format +msgid "end-of-line before authentication method" +msgstr "yetkilendirme yönteminden önce satır sonu" + +#: libpq/hba.c:1287 +#, c-format +msgid "multiple values specified for authentication type" +msgstr "kimlik denetleme için birden fazla değer belirtilmiş" + +#: libpq/hba.c:1288 +#, c-format +msgid "Specify exactly one authentication type per line." +msgstr "Satır başına tek bir kimlik denetleme tipi belirtin." + +#: libpq/hba.c:1365 +#, c-format +msgid "invalid authentication method \"%s\"" +msgstr "geçersiz yetkilendirme yöntemi\"%s\"" + +#: libpq/hba.c:1378 +#, c-format +msgid "invalid authentication method \"%s\": not supported by this build" +msgstr "geçersiz kimlik denetleme yöntemi \"%s\": bu yapılandırmada desteklenmiyor" + +#: libpq/hba.c:1401 +#, c-format +msgid "gssapi authentication is not supported on local sockets" +msgstr "yerel soketlerde gssapi kimlik denetlemesi desteklenmemektedir" + +#: libpq/hba.c:1413 +#, c-format +msgid "peer authentication is only supported on local sockets" +msgstr "peer kimlik denetimi sadece yerel soketlerde desteklenmektedir" + +#: libpq/hba.c:1431 +#, c-format +msgid "cert authentication is only supported on hostssl connections" +msgstr "cert kimlik denetlemesi sadece hostssl bağlantılarında desteklenmektedir" + +#: libpq/hba.c:1481 +#, c-format +msgid "authentication option not in name=value format: %s" +msgstr "kimlik denetlemesi seçeneği isim=değer formatında değil: %s" + +#: libpq/hba.c:1522 +#, c-format +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter veya ldapurl, ldapprefix ile birlikte kullanılamaz" + +#: libpq/hba.c:1533 +#, c-format +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "\"ldap\" kimlik denetleme yöntemi \"ldapbasedn\", \"ldapprefix\", veya \"ldapsuffix\" argümanlarının ayarlanmasını gerektiriyor" + +#: libpq/hba.c:1549 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "ldapsearchattribute, ldapsearchfilter ile birlikte kullanılamaz" + +#: libpq/hba.c:1566 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUS sunucuları listesi boş olamaz" + +#: libpq/hba.c:1576 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUS parolaları listesi boş olamaz" + +#: libpq/hba.c:1629 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "%s sayısı (%d) 1 ya da %s sayısıyla (%d) aynı olmalıdır" + +#: libpq/hba.c:1663 +msgid "ident, peer, gssapi, sspi, and cert" +msgstr "ident, peer, gssapi, sspi ve cert" + +#: libpq/hba.c:1672 +#, c-format +msgid "clientcert can only be configured for \"hostssl\" rows" +msgstr "clientcert sadece \"hostssl\" satırları için yapılandırılabilir" + +#: libpq/hba.c:1688 +#, c-format +msgid "clientcert can not be set to 0 when using \"cert\" authentication" +msgstr "\"cert\" kimlik denetimi kullanıldığında clientcert 0 olarak ayarlanamaz" + +#: libpq/hba.c:1725 +#, c-format +msgid "could not parse LDAP URL \"%s\": %s" +msgstr "LDAP URL'si \"%s\" ayrıştırılamadı : %s" + +#: libpq/hba.c:1736 +#, c-format +msgid "unsupported LDAP URL scheme: %s" +msgstr "desteklenmeyen LDAP URL düzeni (scheme): %s" + +#: libpq/hba.c:1760 +#, c-format +msgid "LDAP URLs not supported on this platform" +msgstr "Bu platformda LDAP URL'leri desteklenmiyor" + +#: libpq/hba.c:1778 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "geçersiz ldapscheme değeri: \"%s\"" + +#: libpq/hba.c:1796 +#, c-format +msgid "invalid LDAP port number: \"%s\"" +msgstr "geçersiz LDAP port numarası: \"%s\"" + +#: libpq/hba.c:1842 libpq/hba.c:1849 +msgid "gssapi and sspi" +msgstr "gssapi ve sspi" + +#: libpq/hba.c:1858 libpq/hba.c:1867 +msgid "sspi" +msgstr "sspi" + +#: libpq/hba.c:1889 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "RADIUS sunucu listesi ayrıştırılamadı \"%s\"" + +#: libpq/hba.c:1937 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "RADIUS kapı (port) listesi ayrıştırılamadı \"%s\"" + +#: libpq/hba.c:1951 +#, c-format +msgid "invalid RADIUS port number: \"%s\"" +msgstr "Geçersiz RADIUS port numarası: \"%s\"" + +#: libpq/hba.c:1973 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "RADIUS parola listesi \"%s\" ayrıştırılamadı" + +#: libpq/hba.c:1995 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "RADIUS tanımlayıcı listesi \"%s\" ayrıştırılamadı" + +#: libpq/hba.c:2009 +#, c-format +msgid "unrecognized authentication option name: \"%s\"" +msgstr "bilinmeyen kimlik denetimi seçeneği ismi: \"%s\"" + +#: libpq/hba.c:2193 +#, c-format +msgid "configuration file \"%s\" contains no entries" +msgstr "\"%s\" yapılandırma dosyasında hiç kayıt yok" + +#: libpq/hba.c:2706 +#, c-format +msgid "invalid regular expression \"%s\": %s" +msgstr "geçersiz düzenli ifade \"%s\" : %s" + +#: libpq/hba.c:2766 +#, c-format +msgid "regular expression match for \"%s\" failed: %s" +msgstr "\"%s\" için düzenli ifade eşleşmesi başarısız: %s" + +#: libpq/hba.c:2785 +#, c-format +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" +msgstr "" + +#: libpq/hba.c:2882 +#, c-format +msgid "provided user name (%s) and authenticated user name (%s) do not match" +msgstr "sağlanmış kullanıcı adı (%s) ve kimlik denetimi yapılmış kullanıcı adı (%s) eşleşmiyor" + +#: libpq/hba.c:2902 +#, c-format +msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" +msgstr "\"%3$s\" olarak yetkilendirilmiş \"%2$s\" kullanıcısı için \"%1$s\" usermap'inde eşleşme yok" + +#: libpq/hba.c:2935 +#, c-format +msgid "could not open usermap file \"%s\": %m" +msgstr "usermap dosyası \"%s\" açılamadı: %m" + +#: libpq/pqcomm.c:220 +#, c-format +msgid "could not set socket to nonblocking mode: %m" +msgstr "socket, non-blocking mode'a ayarlanamadı: %m" + +#: libpq/pqcomm.c:374 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" +msgstr "Unix-alan socket yolu \"%s\" fazla uzun (azami %d bayt)" + +#: libpq/pqcomm.c:395 +#, c-format +msgid "could not translate host name \"%s\", service \"%s\" to address: %s" +msgstr "host adı \"%s\", hizmet \"%s\" adrese çevirilemedi: %s" + +#: libpq/pqcomm.c:399 +#, c-format +msgid "could not translate service \"%s\" to address: %s" +msgstr "\"%s\" servesi adrese çevirilemedi: %s" + +#: libpq/pqcomm.c:426 +#, c-format +msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" +msgstr "tüm istenilen adreslerine bind hatası: MAXLISTEN(%d) sınırı aşılmıştır" + +#: libpq/pqcomm.c:435 +msgid "IPv4" +msgstr "IPv4" + +#: libpq/pqcomm.c:439 +msgid "IPv6" +msgstr "IPv6" + +#: libpq/pqcomm.c:444 +msgid "Unix" +msgstr "Unix" + +#: libpq/pqcomm.c:449 +#, c-format +msgid "unrecognized address family %d" +msgstr "bilinmeyen adres ailesi %d" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:475 +#, c-format +msgid "could not create %s socket for address \"%s\": %m" +msgstr "%s adresi \"%s\" için socket oluşturulamadı: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:501 +#, c-format +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%s adresi \"%s\" için setsockopt(SO_REUSEADDR) başarısız : %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:518 +#, c-format +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%s adresi \"%s\" içinsetsockopt(IPV6_V6ONLY) başarısız: %m" + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:538 +#, c-format +msgid "could not bind %s address \"%s\": %m" +msgstr "%s adresi \"%s\" ye bind hatası: %m" + +#: libpq/pqcomm.c:541 +#, c-format +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "Başka bir postmaster %d portunda çalışıyor mu? Değil ise \"%s\" socket dosyasını kaldırın ve yeniden deneyin." + +#: libpq/pqcomm.c:544 +#, c-format +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "Başka bir postmaster %d portunda çalışıyor mu? Değil ise birkaç saniye bekleyin ve yeniden deneyin." + +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:577 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "%s adresi \"%s\" den dinleyemedi: %m" + +#: libpq/pqcomm.c:586 +#, c-format +msgid "listening on Unix socket \"%s\"" +msgstr "\"%s\" Unix socket'inden dinliyor" + +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:592 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "%s adresi \"%s\" den dinliyor, port %d " + +#: libpq/pqcomm.c:675 +#, c-format +msgid "group \"%s\" does not exist" +msgstr "\"%s\" grubu mevcut değil" + +#: libpq/pqcomm.c:685 +#, c-format +msgid "could not set group of file \"%s\": %m" +msgstr "\"%s\" dosyasının grup atama hatası: %m" + +#: libpq/pqcomm.c:696 +#, c-format +msgid "could not set permissions of file \"%s\": %m" +msgstr "\"%s\" dosyasının erişim hakklarını atanamıyor: %m" + +#: libpq/pqcomm.c:726 +#, c-format +msgid "could not accept new connection: %m" +msgstr "yeni bağlantı alma hatası: %m" + +#: libpq/pqcomm.c:927 +#, c-format +msgid "there is no client connection" +msgstr "istemci bağlantısı bulunmuyor" + +#: libpq/pqcomm.c:978 libpq/pqcomm.c:1074 +#, c-format +msgid "could not receive data from client: %m" +msgstr "istemciden veri alınamamıştır: %m" + +#: libpq/pqcomm.c:1219 tcop/postgres.c:4020 +#, c-format +msgid "terminating connection because protocol synchronization was lost" +msgstr "protokol senkronizasyonu kaybolduğundan bağlantı sonlandırılıyor" + +#: libpq/pqcomm.c:1285 +#, c-format +msgid "unexpected EOF within message length word" +msgstr "mesaj uzunluk verisinde beklenmeyen EOF (dosya sonu)" + +#: libpq/pqcomm.c:1296 +#, c-format +msgid "invalid message length" +msgstr "mesaj uzunluğu yanlıştır" + +#: libpq/pqcomm.c:1318 libpq/pqcomm.c:1331 +#, c-format +msgid "incomplete message from client" +msgstr "istemciden alınan mesaj eksik" + +#: libpq/pqcomm.c:1464 +#, c-format +msgid "could not send data to client: %m" +msgstr "istemci sürecine sinyal gönderme başarısız: %m" + +#: libpq/pqformat.c:406 +#, c-format +msgid "no data left in message" +msgstr "mesajda başka veri kalmadı" + +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:566 +#, c-format +msgid "insufficient data left in message" +msgstr "mesajda yetersiz veri kaldı" + +#: libpq/pqformat.c:597 libpq/pqformat.c:626 +#, c-format +msgid "invalid string in message" +msgstr "mesajda geçersiz satır" + +#: libpq/pqformat.c:642 +#, c-format +msgid "invalid message format" +msgstr "geçersiz mesaj biçimi" + +#: main/main.c:264 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "%s: WSAStartup başarısız: %d\n" + +#: main/main.c:328 +#, c-format +msgid "" +"%s is the PostgreSQL server.\n" +"\n" +msgstr "" +"%s bir PostgreSQL suncusudur.\n" +"\n" + +#: main/main.c:329 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"kullanım:\n" +" %s [OPTION]...\n" +"\n" + +#: main/main.c:330 +#, c-format +msgid "Options:\n" +msgstr "Seçenekler:\n" + +#: main/main.c:331 +#, c-format +msgid " -B NBUFFERS number of shared buffers\n" +msgstr " -B NBUFFERS shared buffer sayısı\n" + +#: main/main.c:332 +#, c-format +msgid " -c NAME=VALUE set run-time parameter\n" +msgstr " -c NAME=VALUE çalıştırma zamanı parametresini ayarla\n" + +#: main/main.c:333 +#, c-format +msgid " -C NAME print value of run-time parameter, then exit\n" +msgstr " -C NAME çalıştırma zamanı parametre değerini göster ve çık\n" + +#: main/main.c:334 +#, c-format +msgid " -d 1-5 debugging level\n" +msgstr " -d 1-5 debug düzeyi\n" + +#: main/main.c:335 +#, c-format +msgid " -D DATADIR database directory\n" +msgstr " -D DATADIR veritabanı dizini\n" + +#: main/main.c:336 +#, c-format +msgid " -e use European date input format (DMY)\n" +msgstr " -e tarih veri girişi için Avrupa biçimini kullan (DMY)\n" + +#: main/main.c:337 +#, c-format +msgid " -F turn fsync off\n" +msgstr " -F fsync etkisizleştir\n" + +#: main/main.c:338 +#, c-format +msgid " -h HOSTNAME host name or IP address to listen on\n" +msgstr " -h HOSTNAME dinlenecek makine adı ve IP adresi\n" + +#: main/main.c:339 +#, c-format +msgid " -i enable TCP/IP connections\n" +msgstr " -i TCP/IP bağlantılarına izin ver\n" + +#: main/main.c:340 +#, c-format +msgid " -k DIRECTORY Unix-domain socket location\n" +msgstr " -k DIRECTORY Unix-domain socket yeri\n" + +#: main/main.c:342 +#, c-format +msgid " -l enable SSL connections\n" +msgstr " -l SSL bağlantıları etkinleştir\n" + +#: main/main.c:344 +#, c-format +msgid " -N MAX-CONNECT maximum number of allowed connections\n" +msgstr " -N MAX-CONNECT izin verilen azami bağlantı sayısı\n" + +#: main/main.c:345 +#, c-format +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o OPTIONS her sunucu sürecine \"OPTIONS\" parametresini ilet (artık kullanılmamaktadır)\n" + +#: main/main.c:346 +#, c-format +msgid " -p PORT port number to listen on\n" +msgstr " -p PORT dinlenecek port numarası\n" + +#: main/main.c:347 +#, c-format +msgid " -s show statistics after each query\n" +msgstr " -s her sorgudan sonra istatistikleri göster\n" + +#: main/main.c:348 +#, c-format +msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" +msgstr " -S WORK-MEM alfabetik sıralama işlemi için kullanılacak bellek (kilobayt bazında)\n" + +#: main/main.c:349 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V,--version sürüm numarasını yaz ve çık\n" + +#: main/main.c:350 +#, c-format +msgid " --NAME=VALUE set run-time parameter\n" +msgstr " --NAME=VALUE çalıştırma zamanı parametresini ayarla\n" + +#: main/main.c:351 +#, c-format +msgid " --describe-config describe configuration parameters, then exit\n" +msgstr " --describe-config ayar parametresini açıklama ve çık\n" + +#: main/main.c:352 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?,--help bu yardımı göster ve çık\n" + +#: main/main.c:354 +#, c-format +msgid "" +"\n" +"Developer options:\n" +msgstr "" +"\n" +"Program geliştirici Seçenekleri:\n" + +#: main/main.c:355 +#, c-format +msgid " -f s|i|n|m|h forbid use of some plan types\n" +msgstr " -f s|i|n|m|h bazı plan yöntemlerinin kullanımı yasakla\n" + +#: main/main.c:356 +#, c-format +msgid " -n do not reinitialize shared memory after abnormal exit\n" +msgstr " -n normal olmayan sonladırmadan sonra shared memory yeniden sıfırlamayı engelle\n" + +#: main/main.c:357 +#, c-format +msgid " -O allow system table structure changes\n" +msgstr " -O sistem tablolarının yapı değişikliğine izin ver\n" + +#: main/main.c:358 +#, c-format +msgid " -P disable system indexes\n" +msgstr " -P sistem indekslerini etkisizleştir\n" + +#: main/main.c:359 +#, c-format +msgid " -t pa|pl|ex show timings after each query\n" +msgstr " -t pa|pl|ex her sorgudan sonra harcanan zamanı göster\n" + +#: main/main.c:360 +#, c-format +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T biri sonlandığında tüm backend süreçlerine SIGSTOP mesajını gönder\n" + +#: main/main.c:361 +#, c-format +msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" +msgstr " -W NUM debuggerin başlanması için NUM saniye bekle\n" + +#: main/main.c:363 +#, c-format +msgid "" +"\n" +"Options for single-user mode:\n" +msgstr "" +"\n" +"Tek-kullanıcı modu seçenekleri:\n" + +#: main/main.c:364 +#, c-format +msgid " --single selects single-user mode (must be first argument)\n" +msgstr " --single tek-kullanıcı modunu seçer (ilk argüman olmalı)\n" + +#: main/main.c:365 +#, c-format +msgid " DBNAME database name (defaults to user name)\n" +msgstr " DBNAME veritabanı adı (varsayılan kullanıcı adı)\n" + +#: main/main.c:366 +#, c-format +msgid " -d 0-5 override debugging level\n" +msgstr " -d 0-5 hata ayıklama seviyesini değiştir\n" + +#: main/main.c:367 +#, c-format +msgid " -E echo statement before execution\n" +msgstr " -E çalıştırmadan önce sorguyu ekrana yaz\n" + +#: main/main.c:368 +#, c-format +msgid " -j do not use newline as interactive query delimiter\n" +msgstr " -j yeni satır işaretini sorgunun sonu olarak algılama\n" + +#: main/main.c:369 main/main.c:374 +#, c-format +msgid " -r FILENAME send stdout and stderr to given file\n" +msgstr " -r FILENAME stdout ve stderr çıktılarını belirtilen dosyaya gönder\n" + +#: main/main.c:371 +#, c-format +msgid "" +"\n" +"Options for bootstrapping mode:\n" +msgstr "" +"\n" +"Bootstrapping biçimi seçenekleri:\n" + +#: main/main.c:372 +#, c-format +msgid " --boot selects bootstrapping mode (must be first argument)\n" +msgstr " --boot bootstrapping modunu seçer (mutlaka ilk argüman olmalı)\n" + +#: main/main.c:373 +#, c-format +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" +msgstr " DBNAME veritabanı adı (bootstrapping biçimi için zorunlu argüman)\n" + +#: main/main.c:375 +#, c-format +msgid " -x NUM internal use\n" +msgstr " -x NUM dahili kullanım\n" + +#: main/main.c:377 +#, c-format +msgid "" +"\n" +"Please read the documentation for the complete list of run-time\n" +"configuration settings and how to set them on the command line or in\n" +"the configuration file.\n" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Çalıştırma zamanı parametrelerin tam listesi için ve onların komut \n" +"satırı ve ayarlar dosyasında nasıl belirleyeceğinizi tam açıklaması için\n" +"lütfen dokümanlara başvurun.\n" +"\n" +"Hata raporları adresine iletin.\n" + +#: main/main.c:391 +#, c-format +msgid "" +"\"root\" execution of the PostgreSQL server is not permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromise. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"PostgreSQL'in, \"root\" kullanıcı olarak çalıştırılmasını tavsiye edilmememktedir.\n" +"Olası güvenilik açığı önlemek için, sunucu, sistem yönetici olmayan\n" +"bir kullanıcı ID ile çalıştırılmalıdır. Sunucunun doğru başlatılması\n" +"konusunda daha fazla bilgi için PostgreSQL dökümanlara bakın.\n" + +#: main/main.c:408 +#, c-format +msgid "%s: real and effective user IDs must match\n" +msgstr "%s: gerçek ve etkin kullanıcı ID'leri birbirine uymalıdır\n" + +#: main/main.c:415 +#, c-format +msgid "" +"Execution of PostgreSQL by a user with administrative permissions is not\n" +"permitted.\n" +"The server must be started under an unprivileged user ID to prevent\n" +"possible system security compromises. See the documentation for\n" +"more information on how to properly start the server.\n" +msgstr "" +"PostgreSQL, sistem yöneticisi haklarına sahip kullanıcısı tarafından çalıştırılamaz.\n" +"Olası güvenilik açığı önlemek için, sunucu, sistem yönetici olmayan bir kullanıcı ID\n" +"ile çalıştırılmalıdır. Sunucunun doğru başlatılması konusunda daha fazla bilgi\n" +"için dökümanlara bakın.\n" + +#: nodes/extensible.c:66 +#, c-format +msgid "extensible node type \"%s\" already exists" +msgstr "\"%s\" genişletilebilir düğüm (node) tipi zaten mevcut" + +#: nodes/extensible.c:114 +#, c-format +msgid "ExtensibleNodeMethods \"%s\" was not registered" +msgstr "\"%s\" ExtensibleNodeMethods kayıtlı değil" + +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 parser/parse_expr.c:2119 parser/parse_func.c:695 parser/parse_oper.c:967 +#, c-format +msgid "could not find array type for data type %s" +msgstr "%s veri tipi için array tipi bulunamıyor" + +#: optimizer/path/joinrels.c:839 +#, c-format +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" +msgstr "FULL JOIN ancak merge-join veya hash-join işlemine uygun şartlarda desteklenmektedir" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/initsplan.c:1212 +#, c-format +msgid "%s cannot be applied to the nullable side of an outer join" +msgstr "%s outer join'in null olabilecek tarafına uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: optimizer/plan/planner.c:1768 parser/analyze.c:1655 parser/analyze.c:1854 parser/analyze.c:2687 +#, c-format +msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" +msgstr "%s UNION/INTERSECT/EXCEPT ile kullanılamaz" + +#: optimizer/plan/planner.c:2340 optimizer/plan/planner.c:4061 +#, c-format +msgid "could not implement GROUP BY" +msgstr "GROUP BY yapılamadı" + +#: optimizer/plan/planner.c:2341 optimizer/plan/planner.c:4062 optimizer/plan/planner.c:4805 optimizer/prep/prepunion.c:1080 +#, c-format +msgid "Some of the datatypes only support hashing, while others only support sorting." +msgstr "Bazı veri tipleri sadece hashing işlemini desteklerken, diğerleri sadece sorting işlemini destekler." + +#: optimizer/plan/planner.c:4804 +#, c-format +msgid "could not implement DISTINCT" +msgstr "DISTINCT yapılamadı" + +#: optimizer/plan/planner.c:5487 +#, c-format +msgid "could not implement window PARTITION BY" +msgstr "window PARTITION BY yapılamadı" + +#: optimizer/plan/planner.c:5488 +#, c-format +msgid "Window partitioning columns must be of sortable datatypes." +msgstr "Window partitioning kolonları sıralanabilen (sortable) veri tiplerinden olmalı." + +#: optimizer/plan/planner.c:5492 +#, c-format +msgid "could not implement window ORDER BY" +msgstr "window ORDER BY yapılamadı" + +#: optimizer/plan/planner.c:5493 +#, c-format +msgid "Window ordering columns must be of sortable datatypes." +msgstr "Window ordering sütunları sıralanabilen (sortable) veri tiplerinden olmalı" + +#: optimizer/plan/setrefs.c:414 +#, c-format +msgid "too many range table entries" +msgstr "çok fazla aralık tablosu (range table) girişi" + +#: optimizer/prep/prepunion.c:544 +#, c-format +msgid "could not implement recursive UNION" +msgstr "recursive UNION yapılamadı" + +#: optimizer/prep/prepunion.c:545 +#, c-format +msgid "All column datatypes must be hashable." +msgstr "Bütün kolon veri tipleri hash edilebilir olmalı." + +#. translator: %s is UNION, INTERSECT, or EXCEPT +#: optimizer/prep/prepunion.c:1079 +#, c-format +msgid "could not implement %s" +msgstr "%s yapılamadı" + +#: optimizer/util/clauses.c:4924 +#, c-format +msgid "SQL function \"%s\" during inlining" +msgstr "satır içine alınma işlemi sırasında \"%s\" SQL fonksiyonu" + +#: optimizer/util/plancat.c:127 +#, c-format +msgid "cannot access temporary or unlogged relations during recovery" +msgstr "kurtarma sırasında geçici ya da loglanmayan ilişkilere (relation) erişilemiyor" + +#: optimizer/util/plancat.c:651 +#, c-format +msgid "whole row unique index inference specifications are not supported" +msgstr "bütü satır unique indeks inference tanımlamaları desteklenmiyor" + +#: optimizer/util/plancat.c:668 +#, c-format +msgid "constraint in ON CONFLICT clause has no associated index" +msgstr "ON CONFLICT ibaresindeki kısıtlamanın ilişkili bir indeksi yok" + +#: optimizer/util/plancat.c:719 +#, c-format +msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" +msgstr "ON CONFLICT DO UPDATE, hariç tutma kısıtlamaları (exclusion constraints) ile desteklenmiyor" + +#: optimizer/util/plancat.c:824 +#, c-format +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" +msgstr "ON CONFLICT tanımlamasıyla eşleşen bir unique ya da exclusion kısıtlaması (constraint) yok" + +#: parser/analyze.c:711 parser/analyze.c:1418 +#, c-format +msgid "VALUES lists must all be the same length" +msgstr "VALUES listesi eşit uzunlukta olmalıdır" + +#: parser/analyze.c:921 +#, c-format +msgid "INSERT has more expressions than target columns" +msgstr "INSERT, hedef sütun sayısından çok ifade bulundurmaktadır" + +#: parser/analyze.c:939 +#, c-format +msgid "INSERT has more target columns than expressions" +msgstr "INSERT, ifade sayısından çok hedef sütun bulundurmaktadır" + +#: parser/analyze.c:943 +#, c-format +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "Ekleme kaynağı INSERT tarafından beklenen sayıyla aynı sayıda sütun içeren bir satır ifadesi. Fazladan parantezleri yanlışlıkla mı kullandınız?" + +#: parser/analyze.c:1229 parser/analyze.c:1628 +#, c-format +msgid "SELECT ... INTO is not allowed here" +msgstr "SELECT ... INTO burada kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:1560 parser/analyze.c:2866 +#, c-format +msgid "%s cannot be applied to VALUES" +msgstr "%s ifadesi VALUES kısmına uygulanamaz" + +#: parser/analyze.c:1779 +#, c-format +msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" +msgstr "geçersiz UNION/INTERSECT/EXCEPT ORDER BY ifadesi" + +#: parser/analyze.c:1780 +#, c-format +msgid "Only result column names can be used, not expressions or functions." +msgstr "Sadece sonuç sütun aldarı kullanılabilir, ifade veya fonksiyon kullanılamaz." + +#: parser/analyze.c:1781 +#, c-format +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." +msgstr "Bu ifade/fonksiyonu ger SELECT içine yerleştirin ya da FROM ifadesine UNION ekleyin." + +#: parser/analyze.c:1844 +#, c-format +msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" +msgstr "INTO, sadece UNION/INTERSECT/EXCEPT işleminin ilk SELECT ifadesinde kullanılabilir" + +#: parser/analyze.c:1916 +#, c-format +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" +msgstr "UNION/INTERSECT/EXCEPT öğesinin üye somutu aynı seviyedeki diğer tabloya erişilemez" + +#: parser/analyze.c:2005 +#, c-format +msgid "each %s query must have the same number of columns" +msgstr "her %s sorgusu ayını sütun sayısına sahip olmalıdır" + +#: parser/analyze.c:2398 +#, c-format +msgid "RETURNING must have at least one column" +msgstr "RETURNING 'de en az bir sütun olmalıdır" + +#: parser/analyze.c:2439 +#, c-format +msgid "cannot specify both SCROLL and NO SCROLL" +msgstr "hem SCROLL hem de NO SCROLL aynı yerde kullanılamaz" + +#: parser/analyze.c:2458 +#, c-format +msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" +msgstr "DECLARE CURSOR, WITH içinde veri değiştirme ifadeleri içermemelidir" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2466 +#, c-format +msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" +msgstr "DECLARE CURSOR WITH HOLD ... %s desteklenmiyor" + +#: parser/analyze.c:2469 +#, c-format +msgid "Holdable cursors must be READ ONLY." +msgstr "Holdable imleçler READ ONLY olmalıdır." + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2477 +#, c-format +msgid "DECLARE SCROLL CURSOR ... %s is not supported" +msgstr "DECLARE SCROLL CURSOR ... %s desteklenmiyor" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2488 +#, c-format +msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" +msgstr "DECLARE INSENSITIVE CURSOR ... %s desteklenmiyor" + +#: parser/analyze.c:2491 +#, c-format +msgid "Insensitive cursors must be READ ONLY." +msgstr "Insensitive cursorlar READ ONLY olmalıdır." + +#: parser/analyze.c:2557 +#, c-format +msgid "materialized views must not use data-modifying statements in WITH" +msgstr "materialized view'ler WITH içinde veri değiştirme ifadeleri kullanmamalıdır" + +#: parser/analyze.c:2567 +#, c-format +msgid "materialized views must not use temporary tables or views" +msgstr "madileştirilmiş görünümler geçici tablo veya görünümler kullanmamalıdır" + +#: parser/analyze.c:2577 +#, c-format +msgid "materialized views may not be defined using bound parameters" +msgstr "materialized view'ler bound parametrelerle tanımlanamaz" + +#: parser/analyze.c:2589 +#, c-format +msgid "materialized views cannot be UNLOGGED" +msgstr "materialized view'ler UNLOGGED olamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2694 +#, c-format +msgid "%s is not allowed with DISTINCT clause" +msgstr "%s ifadesinde DISTINCT kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2701 +#, c-format +msgid "%s is not allowed with GROUP BY clause" +msgstr "GROUP BY ifadesinde %s kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2708 +#, c-format +msgid "%s is not allowed with HAVING clause" +msgstr "HAVING ifadesinde %s kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2715 +#, c-format +msgid "%s is not allowed with aggregate functions" +msgstr "Toplam (aggregate) fonksiyonlarıyla %s kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2722 +#, c-format +msgid "%s is not allowed with window functions" +msgstr "window fonksiyonlarıyla %s kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2729 +#, c-format +msgid "%s is not allowed with set-returning functions in the target list" +msgstr "%s küme dönen (set-returning) fonksiyonlarla, hedef listesi içinde kullanılamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2808 +#, c-format +msgid "%s must specify unqualified relation names" +msgstr "%s unqualified ilişki (relation) adlarını belirtmelidir" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2839 +#, c-format +msgid "%s cannot be applied to a join" +msgstr "%s bir \"join\"e uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2848 +#, c-format +msgid "%s cannot be applied to a function" +msgstr "%s, bir fonksiyona uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2857 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%s, bir tablo fonksiyonuna uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2875 +#, c-format +msgid "%s cannot be applied to a WITH query" +msgstr "%s, bir WITH sorgusuna uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2884 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%s, bir \"named tuplestore\"a uygulanamaz" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2901 +#, c-format +msgid "relation \"%s\" in %s clause not found in FROM clause" +msgstr "%2s ifadesinde belirtilen \"%1s\" tablosu FROM ifadesinde bulunamadı" + +#: parser/parse_agg.c:221 parser/parse_oper.c:222 +#, c-format +msgid "could not identify an ordering operator for type %s" +msgstr "%s tipi için sırama işlemi bulunamadı" + +#: parser/parse_agg.c:223 +#, c-format +msgid "Aggregates with DISTINCT must be able to sort their inputs." +msgstr "DISTINCT'li toplamlar (aggregate) girdilerini sıralayabilmelidir." + +#: parser/parse_agg.c:258 +#, c-format +msgid "GROUPING must have fewer than 32 arguments" +msgstr "GROUPING 32'den az argüman içermelidir" + +#: parser/parse_agg.c:361 +msgid "aggregate functions are not allowed in JOIN conditions" +msgstr "JOIN ifadesinde aggregate fonksiyonları kullanılamaz" + +#: parser/parse_agg.c:363 +msgid "grouping operations are not allowed in JOIN conditions" +msgstr "JOIN ifadesinde gruplama işlemleri kullanılamaz" + +#: parser/parse_agg.c:375 +msgid "aggregate functions are not allowed in FROM clause of their own query level" +msgstr "toplam (aggregate) fonksiyonlarına kendileriyle aynı sorgu seviyesindeki FROM ibarelerinde izin verilmez" + +#: parser/parse_agg.c:377 +msgid "grouping operations are not allowed in FROM clause of their own query level" +msgstr "gruplama işlemlerine kendileriyle aynı sorgu seviyesindeki FROM ibarelerinde izin verilmez" + +#: parser/parse_agg.c:382 +msgid "aggregate functions are not allowed in functions in FROM" +msgstr "aggregate fonksiyonlar fonksiyonların FROM kısmında kullanılamaz" + +#: parser/parse_agg.c:384 +msgid "grouping operations are not allowed in functions in FROM" +msgstr "gruplama işlemleri fonksiyonların FROM kısmında kullanılamaz" + +#: parser/parse_agg.c:392 +msgid "aggregate functions are not allowed in policy expressions" +msgstr "aggregate fonksiyonlar policy expression'larda kullanılamaz" + +#: parser/parse_agg.c:394 +msgid "grouping operations are not allowed in policy expressions" +msgstr "gruplama işlemleri policy expression'larda kullanılamaz" + +#: parser/parse_agg.c:411 +msgid "aggregate functions are not allowed in window RANGE" +msgstr "window RANGE de aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:413 +msgid "grouping operations are not allowed in window RANGE" +msgstr "window RANGE de gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:418 +msgid "aggregate functions are not allowed in window ROWS" +msgstr "window ROWS da aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:420 +msgid "grouping operations are not allowed in window ROWS" +msgstr "window ROWS da gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:425 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "window GROUPS da aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:427 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "window GROUPS da gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:461 +msgid "aggregate functions are not allowed in check constraints" +msgstr "check constraint içinde aggregate fonksiyon kullanılamaz" + +#: parser/parse_agg.c:463 +msgid "grouping operations are not allowed in check constraints" +msgstr "check constraint içinde gruplama işlemleri kullanılamaz" + +#: parser/parse_agg.c:470 +msgid "aggregate functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT ifadelerde aggregate fonksiyonlar kullanılamaz" + +#: parser/parse_agg.c:472 +msgid "grouping operations are not allowed in DEFAULT expressions" +msgstr "DEFAULT ifadelerde gruplama işlemleri kullanılamaz" + +#: parser/parse_agg.c:477 +msgid "aggregate functions are not allowed in index expressions" +msgstr "indeks ifadelerinde aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:479 +msgid "grouping operations are not allowed in index expressions" +msgstr "indeks ifadelerinde gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:484 +msgid "aggregate functions are not allowed in index predicates" +msgstr "indeks yüklemlerinde (predicate) aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:486 +msgid "grouping operations are not allowed in index predicates" +msgstr "indeks yüklemlerinde (predicate) gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:491 +msgid "aggregate functions are not allowed in transform expressions" +msgstr "transform ifadesinde aggregate fonksiyon kullanılamaz" + +#: parser/parse_agg.c:493 +msgid "grouping operations are not allowed in transform expressions" +msgstr "transform ifadesinde gruplama işlemleri kullanılamaz" + +#: parser/parse_agg.c:498 +msgid "aggregate functions are not allowed in EXECUTE parameters" +msgstr "EXECUTE parametrelerinde aggregate fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:500 +msgid "grouping operations are not allowed in EXECUTE parameters" +msgstr "EXECUTE parametresinde gruplama işlemlerine izin verilmez " + +#: parser/parse_agg.c:505 +msgid "aggregate functions are not allowed in trigger WHEN conditions" +msgstr "trigger WHEN şart ifadelerinde aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:507 +msgid "grouping operations are not allowed in trigger WHEN conditions" +msgstr "trigger WHEN şart ifadelerinde gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:512 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "bölümleme anahtarı (partition key) ifadelerinde aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:514 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "bölümleme anahtarı (partition key) ifadelerinde gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:520 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "CALL argümanlarında aggregate fonksiyon kullanılamaz" + +#: parser/parse_agg.c:522 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALL argümanlarında gruplama işlemlerine izin verilmez " + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:545 parser/parse_clause.c:1818 +#, c-format +msgid "aggregate functions are not allowed in %s" +msgstr "%s içinde aggregate fonksiyonlara izin verilmez" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:548 +#, c-format +msgid "grouping operations are not allowed in %s" +msgstr "%s içinde gruplama işlemlerine izin verilmez" + +#: parser/parse_agg.c:656 +#, c-format +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" +msgstr "dış seviye toplamı (aggregate) direk argümanları içinde daha düşük seviye bir değişken içeremez" + +#: parser/parse_agg.c:735 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "aggregate fonksiyon çağırmaları küme dönen (set returning) fonksiyon çağırmaları içeremez" + +#: parser/parse_agg.c:736 parser/parse_expr.c:1766 parser/parse_expr.c:2246 parser/parse_func.c:866 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "" + +#: parser/parse_agg.c:741 +#, c-format +msgid "aggregate function calls cannot contain window function calls" +msgstr "aggregate fonksiyon çağırmaları window fonksiyon çağırmaları içeremez" + +#: parser/parse_agg.c:820 +msgid "window functions are not allowed in JOIN conditions" +msgstr "JOIN ifadesinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:827 +msgid "window functions are not allowed in functions in FROM" +msgstr "FROM içindeki fonksiyonlarda window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:833 +msgid "window functions are not allowed in policy expressions" +msgstr "policy ifadelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:846 +msgid "window functions are not allowed in window definitions" +msgstr "window tanımlarında window fonksiyonlarına izin erilmez" + +#: parser/parse_agg.c:878 +msgid "window functions are not allowed in check constraints" +msgstr "check kısıtlamalarında (constraint) window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:882 +msgid "window functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT ifadelerde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:885 +msgid "window functions are not allowed in index expressions" +msgstr "indeks ifadelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:888 +msgid "window functions are not allowed in index predicates" +msgstr "indeks yüklemlerinde (predicate) window fonksiyonlarına izin erilmez" + +#: parser/parse_agg.c:891 +msgid "window functions are not allowed in transform expressions" +msgstr "transform ifadelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:894 +msgid "window functions are not allowed in EXECUTE parameters" +msgstr "EXECUTE parametrelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:897 +msgid "window functions are not allowed in trigger WHEN conditions" +msgstr "trigger WHEN şart ifadelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:900 +msgid "window functions are not allowed in partition key expressions" +msgstr "bölümleme anahtarı (partition key) ifadelerinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:903 +msgid "window functions are not allowed in CALL arguments" +msgstr "CALL argümanlarında window fonksiyonlarına izin verilmez" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_agg.c:923 parser/parse_clause.c:1827 +#, c-format +msgid "window functions are not allowed in %s" +msgstr "%s içinde window fonksiyonlarına izin verilmez" + +#: parser/parse_agg.c:957 parser/parse_clause.c:2663 +#, c-format +msgid "window \"%s\" does not exist" +msgstr "\"%s\" window'u mevcut değil" + +#: parser/parse_agg.c:1042 +#, c-format +msgid "too many grouping sets present (maximum 4096)" +msgstr "çok fazla gruplama kümesi (grouping set) mevcut (azami 4096)" + +#: parser/parse_agg.c:1191 +#, c-format +msgid "aggregate functions are not allowed in a recursive query's recursive term" +msgstr "bir özyinelemeli sorgunun özyinelemeli teriminde (term) aggregate fonksiyonlara izin verilmez" + +#: parser/parse_agg.c:1384 +#, c-format +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" +msgstr "aggregate fonksiyonu kullanmak için \"%s.%s\" sütununu GROUP BY listesine eklemelisiniz" + +#: parser/parse_agg.c:1387 +#, c-format +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." +msgstr "Bir ordered-set aggregate'in direkt argümanları sadece gruplandırılmış kolonlar kullanmalı" + +#: parser/parse_agg.c:1392 +#, c-format +msgid "subquery uses ungrouped column \"%s.%s\" from outer query" +msgstr "subquery, dış sorgusundan \"%s.%s\" gruplandırılanmamış sütunu kullanıyor" + +#: parser/parse_agg.c:1556 +#, c-format +msgid "arguments to GROUPING must be grouping expressions of the associated query level" +msgstr "GROUPING argümanları, ilişkili sorgu seviyesinin gruplama ifadeleri olmalıdır" + +#: parser/parse_clause.c:199 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "\"%s\" nesnesi (relation) bir modifying statement'ın hedefi olamaz" + +#: parser/parse_clause.c:615 parser/parse_clause.c:643 parser/parse_func.c:2284 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "küme dönen fonksiyonlar FROM'un en üst seviyesinde görünmelidir" + +#: parser/parse_clause.c:655 +#, c-format +msgid "multiple column definition lists are not allowed for the same function" +msgstr "aynı fonksiyon için çoklu sütun tanım listelerine izin verilmez" + +#: parser/parse_clause.c:688 +#, c-format +msgid "ROWS FROM() with multiple functions cannot have a column definition list" +msgstr "çok sayıda fonksiyonlu ROWS FROM() 'un bir sütun tanımlama listesi olamaz" + +#: parser/parse_clause.c:689 +#, c-format +msgid "Put a separate column definition list for each function inside ROWS FROM()." +msgstr "ROWS FROM() içindeki her sütun için ayrı bir sütun tanımlama listesi oluşturun." + +#: parser/parse_clause.c:695 +#, c-format +msgid "UNNEST() with multiple arguments cannot have a column definition list" +msgstr "çok sayıda argümanlı UNNEST() 'in bir sütun tanımlama listesi olamaz" + +#: parser/parse_clause.c:696 +#, c-format +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." +msgstr "ROWS FROM() içinde ayrı UNNEST() çağrıları kulanın, ve her birine bir sütun tanım listesi ekleyin" + +#: parser/parse_clause.c:703 +#, c-format +msgid "WITH ORDINALITY cannot be used with a column definition list" +msgstr "WITH ORDINALITY bir sütun tanımlama listesi ile kullanılamaz" + +#: parser/parse_clause.c:704 +#, c-format +msgid "Put the column definition list inside ROWS FROM()." +msgstr "Sütun tanımlama listesini ROWS FROM() içine yerleştirin." + +#: parser/parse_clause.c:807 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "sadece bir FOR ORDINALITY sütununa izin verilir" + +#: parser/parse_clause.c:868 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "\"%s\" sütun adı biricik (unique) değildir" + +#: parser/parse_clause.c:910 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "\"%s\" namespace adı biricik (unique) değildir" + +#: parser/parse_clause.c:920 +#, c-format +msgid "only one default namespace is allowed" +msgstr "sadece bir varsayılan namespace'e zzin verilir" + +#: parser/parse_clause.c:982 +#, c-format +msgid "tablesample method %s does not exist" +msgstr "%s tablesample metodu mevcut değil" + +#: parser/parse_clause.c:1004 +#, c-format +msgid "tablesample method %s requires %d argument, not %d" +msgid_plural "tablesample method %s requires %d arguments, not %d" +msgstr[0] "%s tablesample metodunun %2d değil, %1d argümanı olmalı" +msgstr[1] "%s tablesample metodunun %2d değil, %1d argümanı olmalı" + +#: parser/parse_clause.c:1038 +#, c-format +msgid "tablesample method %s does not support REPEATABLE" +msgstr "%s tablesample metodu REPEATABLE'ı desteklemez" + +#: parser/parse_clause.c:1208 +#, c-format +msgid "TABLESAMPLE clause can only be applied to tables and materialized views" +msgstr "TABLESAMPLE ibaresi sadece tablo ve materialized view'lere uygulanabilir" + +#: parser/parse_clause.c:1378 +#, c-format +msgid "column name \"%s\" appears more than once in USING clause" +msgstr "USING ifadesinde \"%s\" sütun adı birden fazla kez rastlanıyor" + +#: parser/parse_clause.c:1393 +#, c-format +msgid "common column name \"%s\" appears more than once in left table" +msgstr "sol tablosunda \"%s\" sütun adı birden fazla kez rastlanıyor" + +#: parser/parse_clause.c:1402 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in left table" +msgstr "USING ifadesinde belirtilen \"%s\" sütunu sol tablosunda bulunmamaktadır" + +#: parser/parse_clause.c:1416 +#, c-format +msgid "common column name \"%s\" appears more than once in right table" +msgstr "\"%s\" sütun adı sağ tavblosunda birden fazla kez rastlanmaktadır" + +#: parser/parse_clause.c:1425 +#, c-format +msgid "column \"%s\" specified in USING clause does not exist in right table" +msgstr "USING ifadesinde kullaınılan \"%s\" sütunu sağ tablosunda mevcut değildir" + +#: parser/parse_clause.c:1479 +#, c-format +msgid "column alias list for \"%s\" has too many entries" +msgstr "\"%s\" için sütun alias listesinde gereğinden fazla öğe var" + +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_clause.c:1788 +#, c-format +msgid "argument of %s must not contain variables" +msgstr "%s ifadesinin argümanı değişken bulundurmamalıdır" + +#. translator: first %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1953 +#, c-format +msgid "%s \"%s\" is ambiguous" +msgstr "%s \"%s\" iki anlamlıdır (ambiguous)" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:1982 +#, c-format +msgid "non-integer constant in %s" +msgstr "%s içinde tamsayı olamayan bir sabit" + +#. translator: %s is name of a SQL construct, eg ORDER BY +#: parser/parse_clause.c:2004 +#, c-format +msgid "%s position %d is not in select list" +msgstr "%s ifadesi, %d konumundaki select listesinde değildir" + +#: parser/parse_clause.c:2445 +#, c-format +msgid "CUBE is limited to 12 elements" +msgstr "CUBE 12 elemanla sınırlıdır" + +#: parser/parse_clause.c:2651 +#, c-format +msgid "window \"%s\" is already defined" +msgstr "\"%s\" window'u zaten tanımlıdır" + +#: parser/parse_clause.c:2712 +#, c-format +msgid "cannot override PARTITION BY clause of window \"%s\"" +msgstr "\"%s\" window'unun PARTITION BY ibaresi geçersiz kılınamaz (override)" + +#: parser/parse_clause.c:2724 +#, c-format +msgid "cannot override ORDER BY clause of window \"%s\"" +msgstr "\"%s\" window'unun ORDER BY ibaresi geçersiz kılınamaz (override)" + +#: parser/parse_clause.c:2754 parser/parse_clause.c:2760 +#, c-format +msgid "cannot copy window \"%s\" because it has a frame clause" +msgstr "\"%s\" window'u kopyalanamaz çünkü bir frame cümleciği içeriyor" + +#: parser/parse_clause.c:2762 +#, c-format +msgid "Omit the parentheses in this OVER clause." +msgstr "Bu OVER ifadesindeki parantezleri çıkarın" + +#: parser/parse_clause.c:2782 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "" + +#: parser/parse_clause.c:2805 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS modu bir ORDER BY ibaresi gerektiriyor" + +#: parser/parse_clause.c:2875 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "DISTINCT'li bir toplamda, argüman listesinde ORDER BY ifadeleri bulunmalıdır" + +#: parser/parse_clause.c:2876 +#, c-format +msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" +msgstr "SELECT DISTINCE sorgusunda ORDER BY select listesinde bulunmalıdır" + +#: parser/parse_clause.c:2908 +#, c-format +msgid "an aggregate with DISTINCT must have at least one argument" +msgstr "DISTINCT 'li bir toplamda (aggregate) en az bir argüman bulunmalıdır" + +#: parser/parse_clause.c:2909 +#, c-format +msgid "SELECT DISTINCT must have at least one column" +msgstr "SELECT DISTINCT kullanımında en az bir sütun olmalıdır" + +#: parser/parse_clause.c:2975 parser/parse_clause.c:3007 +#, c-format +msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" +msgstr "SELECT DISTINCT ON ifadesi, ORDER BY ifadelerine uymak zorundadır" + +#: parser/parse_clause.c:3085 +#, c-format +msgid "ASC/DESC is not allowed in ON CONFLICT clause" +msgstr "ON CONFLICT ifadelerinde ASC/DESC kabul edilmemektedir" + +#: parser/parse_clause.c:3091 +#, c-format +msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" +msgstr "ON CONFLICT ifadelerinde NULLS FIRST/LAST kabul edilmemektedir" + +#: parser/parse_clause.c:3170 +#, c-format +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgstr "ON CONFLICT DO UPDATE, inference tanımlaması ya da kısıtlama (constraint) adı gerektirir" + +#: parser/parse_clause.c:3171 +#, c-format +msgid "For example, ON CONFLICT (column_name)." +msgstr "Örnek, ON CONFLICT(sutun_adi)" + +#: parser/parse_clause.c:3182 +#, c-format +msgid "ON CONFLICT is not supported with system catalog tables" +msgstr "ON CONFLICT, sistem kataloğu tablolarıyla desteklenmiyor" + +#: parser/parse_clause.c:3190 +#, c-format +msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" +msgstr "ON CONFLICT, katalog tablosu olarak kullanılan \"%s\" tablosunda desteklenmiyor" + +#: parser/parse_clause.c:3333 +#, c-format +msgid "operator %s is not a valid ordering operator" +msgstr "%s geçerli bir sıralama operatör adı değildir" + +#: parser/parse_clause.c:3335 +#, c-format +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." +msgstr "Ordering operators must be \"<\" or \">\" members of btree operator families." + +#: parser/parse_clause.c:3646 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "" + +#: parser/parse_clause.c:3652 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "" + +#: parser/parse_clause.c:3655 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "" + +#: parser/parse_clause.c:3660 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "" + +#: parser/parse_clause.c:3663 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "" + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 parser/parse_expr.c:2153 parser/parse_expr.c:2741 parser/parse_target.c:961 +#, c-format +msgid "cannot cast type %s to %s" +msgstr "%s tipi %s tipine dökülemiyor" + +#: parser/parse_coerce.c:1063 +#, c-format +msgid "Input has too few columns." +msgstr "Girişte sütun sayısı azdır." + +#: parser/parse_coerce.c:1081 +#, c-format +msgid "Cannot cast type %s to %s in column %d." +msgstr "%3$d sütununda %1$s tipi %2$s tipine dökülemiyor." + +#: parser/parse_coerce.c:1096 +#, c-format +msgid "Input has too many columns." +msgstr "Giriş çok fazla sütun içeriyor." + +#. translator: first %s is name of a SQL construct, eg WHERE +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 +#, c-format +msgid "argument of %s must be type %s, not type %s" +msgstr "%s'ın argümanı %s değil, %s tipinde olamalıdır" + +#. translator: %s is name of a SQL construct, eg WHERE +#. translator: %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 +#, c-format +msgid "argument of %s must not return a set" +msgstr "%s'ın argümanları set veri tipini döndüremez" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1351 +#, c-format +msgid "%s types %s and %s cannot be matched" +msgstr "%s tipleri %s ve %s bir araya gelemez" + +#. translator: first %s is name of a SQL construct, eg CASE +#: parser/parse_coerce.c:1418 +#, c-format +msgid "%s could not convert type %s to %s" +msgstr "%s %s tipi %s tipime dönüştürülemiyor" + +#: parser/parse_coerce.c:1720 +#, c-format +msgid "arguments declared \"anyelement\" are not all alike" +msgstr "\"anyelement\" olarak tanımlanan argümanlar birbirine benzemiyor" + +#: parser/parse_coerce.c:1740 +#, c-format +msgid "arguments declared \"anyarray\" are not all alike" +msgstr "\"anyarray\" olarak tanımlanan argümanlar birbirine benzemiyor" + +#: parser/parse_coerce.c:1760 +#, c-format +msgid "arguments declared \"anyrange\" are not all alike" +msgstr "\"anyrange\" olarak tanımlanan argümanlar birbirine benzemiyor" + +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 parser/parse_coerce.c:2038 +#, c-format +msgid "argument declared %s is not an array but type %s" +msgstr "%s olarak tanımlanmış argüman bir dizi (array) değil, %s tipidir" + +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 +#, c-format +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "%s olarak tanımlanmış parametre %s olarak tanımlanmış argümanla tutarlı değildir" + +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 +#, c-format +msgid "argument declared %s is not a range type but type %s" +msgstr "%s olarak tanımlanmış argüman bir aralık (range) tipi değil, %s tipidir" + +#: parser/parse_coerce.c:1865 +#, c-format +msgid "could not determine polymorphic type because input has type %s" +msgstr "girdi %s tipinde olduğu için polymorphic tipi belirlenemedi" + +#: parser/parse_coerce.c:1876 +#, c-format +msgid "type matched to anynonarray is an array type: %s" +msgstr "anynonarray ile eşleştirilen tip bir array tipidir: %s" + +#: parser/parse_coerce.c:1886 +#, c-format +msgid "type matched to anyenum is not an enum type: %s" +msgstr "anyenum ile eşleştirilen tip bir enum tipi değildir: %s" + +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 +#, c-format +msgid "could not find range type for data type %s" +msgstr "%s veri tipi için aralık (range) tipi bulunamıyor" + +#: parser/parse_collate.c:228 parser/parse_collate.c:475 parser/parse_collate.c:981 +#, c-format +msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" +msgstr "\"%s\" ve \"%s\" örtük collation'ları arasında collation uyumsuzluğu" + +#: parser/parse_collate.c:231 parser/parse_collate.c:478 parser/parse_collate.c:984 +#, c-format +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." +msgstr "COLLATE cümleciğini ifadelerin birine ya da ikisine birden uygulayarak sıralamac (collation) seçebilirsiniz." + +#: parser/parse_collate.c:831 +#, c-format +msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" +msgstr "\"%s\" ve \"%s\" collation'ları arasında uyumsuzluk" + +#: parser/parse_cte.c:42 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" +msgstr "" + +#: parser/parse_cte.c:44 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within a subquery" +msgstr "bir subquery içinde \"%s\" sorgusuna recursive referans bulunmamalıdır" + +#: parser/parse_cte.c:46 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within an outer join" +msgstr "bir outer join içinde \"%s\" sorgusuna recursive referans bulunmamalıdır" + +#: parser/parse_cte.c:48 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within INTERSECT" +msgstr "INTERSECT içinde \"%s\" sorgusuna recursive referans bulunmamalıdır" + +#: parser/parse_cte.c:50 +#, c-format +msgid "recursive reference to query \"%s\" must not appear within EXCEPT" +msgstr "EXCEPT içinde \"%s\" sorgusuna recursive referans bulunmamalıdır" + +#: parser/parse_cte.c:132 +#, c-format +msgid "WITH query name \"%s\" specified more than once" +msgstr "\"%s\" WITH sorgu adı birden fazla kez belirtilmiştir" + +#: parser/parse_cte.c:264 +#, c-format +msgid "WITH clause containing a data-modifying statement must be at the top level" +msgstr "veri değiştiren ifade içeren bir WITH cümleciği en üst seviyede olmalıdır" + +#: parser/parse_cte.c:313 +#, c-format +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" +msgstr "" + +#: parser/parse_cte.c:319 +#, c-format +msgid "Cast the output of the non-recursive term to the correct type." +msgstr "Özyinelemeli olmayan terimin çıktısını doğru tipe dönüştürün" + +#: parser/parse_cte.c:324 +#, c-format +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "" + +#: parser/parse_cte.c:328 +#, c-format +msgid "Use the COLLATE clause to set the collation of the non-recursive term." +msgstr "Özyinelemeli olmayan terimin (non-recursive-term) karşılaştırma ayarı için COLLATE ifadesini kullanın." + +#: parser/parse_cte.c:418 +#, c-format +msgid "WITH query \"%s\" has %d columns available but %d columns specified" +msgstr "\"%s\" WITH sorgusunda %d sütun bulunmakta ancak %d sütun belirtilmiş" + +#: parser/parse_cte.c:598 +#, c-format +msgid "mutual recursion between WITH items is not implemented" +msgstr "WITH ögeleri arasındaki karşılıklı özyineleme implement edilmemiş" + +#: parser/parse_cte.c:650 +#, c-format +msgid "recursive query \"%s\" must not contain data-modifying statements" +msgstr "\"%s\" recursive sorgusu veri değiştiren (data modifying) ifade içermemelidir" + +#: parser/parse_cte.c:658 +#, c-format +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" +msgstr "\"%s\" özyinelemeli sorgusu özyinelemeli olmayan terim UNION (ALL) özyinelemeli terim formuna sahip değil " + +#: parser/parse_cte.c:702 +#, c-format +msgid "ORDER BY in a recursive query is not implemented" +msgstr "recursive sorguda ORDER BY implemente edilmemiştir" + +#: parser/parse_cte.c:708 +#, c-format +msgid "OFFSET in a recursive query is not implemented" +msgstr "recursive sorguda OFFSET implemente edilmemiştir" + +#: parser/parse_cte.c:714 +#, c-format +msgid "LIMIT in a recursive query is not implemented" +msgstr "recursive sorguda LIMIT implemente edilmemiş" + +#: parser/parse_cte.c:720 +#, c-format +msgid "FOR UPDATE/SHARE in a recursive query is not implemented" +msgstr "recursive sorgu üzerinde FOR UPDATE/SHARE implemente edilmemiştir" + +#: parser/parse_cte.c:777 +#, c-format +msgid "recursive reference to query \"%s\" must not appear more than once" +msgstr "\"%s\" sorgusuna recursive referans birden fazla olmamamlı" + +#: parser/parse_expr.c:350 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "bu durumda DEFAULT kabul edilmemektedir" + +#: parser/parse_expr.c:403 parser/parse_relation.c:3287 parser/parse_relation.c:3307 +#, c-format +msgid "column %s.%s does not exist" +msgstr "%s.%s sütunu mevcut değil" + +#: parser/parse_expr.c:415 +#, c-format +msgid "column \"%s\" not found in data type %s" +msgstr "%2$s veri tipinde \"%1$s\" sütunu bulunamadı" + +#: parser/parse_expr.c:421 +#, c-format +msgid "could not identify column \"%s\" in record data type" +msgstr "record veri tipinde \"%s\" sütunu bulunamamış" + +#: parser/parse_expr.c:427 +#, c-format +msgid "column notation .%s applied to type %s, which is not a composite type" +msgstr ".%s sütün tanım biçimi %s tipine uygulanmış; bu tip, bir composite tipi değildir" + +#: parser/parse_expr.c:458 parser/parse_target.c:728 +#, c-format +msgid "row expansion via \"*\" is not supported here" +msgstr "\"*\" ile satır genişlemesi (row expansion) burada desteklenmiyor" + +#: parser/parse_expr.c:771 parser/parse_relation.c:689 parser/parse_relation.c:789 parser/parse_target.c:1199 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "\"%s\" sütun referansı iki anlamlı" + +#: parser/parse_expr.c:827 parser/parse_param.c:110 parser/parse_param.c:142 parser/parse_param.c:199 parser/parse_param.c:298 +#, c-format +msgid "there is no parameter $%d" +msgstr "$%d parametresi yoktur" + +#: parser/parse_expr.c:1070 +#, c-format +msgid "NULLIF requires = operator to yield boolean" +msgstr "boolean değerini almak için NULLIF, = işlemini kullanmalıdır" + +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1076 parser/parse_expr.c:3057 +#, c-format +msgid "%s must not return a set" +msgstr "%s bir küme döndürmemeli" + +#: parser/parse_expr.c:1524 parser/parse_expr.c:1556 +#, c-format +msgid "number of columns does not match number of values" +msgstr "değer sayısı sayısı ile kolon satısı eşleşmiyor" + +#: parser/parse_expr.c:1570 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "çoklu sütun UPDATE'i için kaynak bir sub-SELECT ya da ROW() ifadesi olmalı" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1764 parser/parse_expr.c:2244 parser/parse_func.c:2391 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "%s içinde küme dönen fonksiyonlara izin verilmez" + +#: parser/parse_expr.c:1825 +msgid "cannot use subquery in check constraint" +msgstr "check constraint içinde subquery kullanılamaz" + +#: parser/parse_expr.c:1829 +msgid "cannot use subquery in DEFAULT expression" +msgstr "DEFAULT ifadesinde subquery kullanılamaz" + +#: parser/parse_expr.c:1832 +msgid "cannot use subquery in index expression" +msgstr "index ifadesinde subquery kullanılamaz" + +#: parser/parse_expr.c:1835 +msgid "cannot use subquery in index predicate" +msgstr "index tanımında subquery kullanılamaz" + +#: parser/parse_expr.c:1838 +msgid "cannot use subquery in transform expression" +msgstr "transform ifadesinde set kullanılamaz" + +#: parser/parse_expr.c:1841 +msgid "cannot use subquery in EXECUTE parameter" +msgstr "EXECUTE parametresinde subquery kullanılamaz" + +#: parser/parse_expr.c:1844 +msgid "cannot use subquery in trigger WHEN condition" +msgstr "trigger WHEN şart ifadesinde içinde subquery kullanılamaz" + +#: parser/parse_expr.c:1847 +msgid "cannot use subquery in partition key expression" +msgstr "partition key ifadesinde subquery kullanılamaz" + +#: parser/parse_expr.c:1850 +msgid "cannot use subquery in CALL argument" +msgstr "CALL argümanında subquery kullanılamaz" + +#: parser/parse_expr.c:1903 +#, c-format +msgid "subquery must return only one column" +msgstr "subquery, bir tane sütun getirmelidir" + +#: parser/parse_expr.c:1987 +#, c-format +msgid "subquery has too many columns" +msgstr "subquery çok fazla sütuna sahip" + +#: parser/parse_expr.c:1992 +#, c-format +msgid "subquery has too few columns" +msgstr "subquery'de yetersiz sütun sayısı" + +#: parser/parse_expr.c:2093 +#, c-format +msgid "cannot determine type of empty array" +msgstr "boş dizi'nin (array) tipi belirlenemiyor" + +#: parser/parse_expr.c:2094 +#, c-format +msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." +msgstr "İstenen tipe açık olarak belirterek dönüştürün, mesela ARRAY[]::integer[]." + +#: parser/parse_expr.c:2108 +#, c-format +msgid "could not find element type for data type %s" +msgstr "%s veri tipi için element tipi bulunamıyor" + +#: parser/parse_expr.c:2395 +#, c-format +msgid "unnamed XML attribute value must be a column reference" +msgstr "isimsiz XML attribute değeri bir sütun referansı olmalıdır" + +#: parser/parse_expr.c:2396 +#, c-format +msgid "unnamed XML element value must be a column reference" +msgstr "isimsiz XML öğesi bir sütun referansı olmalıdır" + +#: parser/parse_expr.c:2411 +#, c-format +msgid "XML attribute name \"%s\" appears more than once" +msgstr "\"%s\" XML attrıbute adı birden fazla kez belirtilmiştir" + +#: parser/parse_expr.c:2518 +#, c-format +msgid "cannot cast XMLSERIALIZE result to %s" +msgstr "XMLSERIALIZE sonucu %s tipine dönüştürülemiyor (cast)" + +#: parser/parse_expr.c:2814 parser/parse_expr.c:3010 +#, c-format +msgid "unequal number of entries in row expressions" +msgstr "satır ifadelerınde farklı öğe sayısı" + +#: parser/parse_expr.c:2824 +#, c-format +msgid "cannot compare rows of zero length" +msgstr "sıfır uzunluklu satırlar karşılaştırılamaz" + +#: parser/parse_expr.c:2849 +#, c-format +msgid "row comparison operator must yield type boolean, not type %s" +msgstr "satır karşılaştırma operatörü %s tipini değil, boolean tipini döndürmelidir" + +#: parser/parse_expr.c:2856 +#, c-format +msgid "row comparison operator must not return a set" +msgstr "satır karşılaştırma operatörü set döndürmemelidir" + +#: parser/parse_expr.c:2915 parser/parse_expr.c:2956 +#, c-format +msgid "could not determine interpretation of row comparison operator %s" +msgstr "%s satır karşılaştırma operatörünün youmlaması tespit edilemedi" + +#: parser/parse_expr.c:2917 +#, c-format +msgid "Row comparison operators must be associated with btree operator families." +msgstr "Satır karşılaştırma operatörleri btree sınıf operatörleri ile ilişilmelidir" + +#: parser/parse_expr.c:2958 +#, c-format +msgid "There are multiple equally-plausible candidates." +msgstr "Birden fazla uygun aday vardır." + +#: parser/parse_expr.c:3051 +#, c-format +msgid "IS DISTINCT FROM requires = operator to yield boolean" +msgstr "boolean değerini almak için IS DISTINCT FROM, = işlemini kullanmalıdır" + +#: parser/parse_expr.c:3370 parser/parse_expr.c:3388 +#, c-format +msgid "operator precedence change: %s is now lower precedence than %s" +msgstr "operatör öncelik değişikliği: %s şimdi %s den daha düşük bir öncelikte" + +#: parser/parse_func.c:185 +#, c-format +msgid "argument name \"%s\" used more than once" +msgstr "\"%s\" argüman adı birden fazla belirtilmiş" + +#: parser/parse_func.c:196 +#, c-format +msgid "positional argument cannot follow named argument" +msgstr "named argümanın ardından positional argüman gelemez" + +#: parser/parse_func.c:278 parser/parse_func.c:2184 +#, c-format +msgid "%s is not a procedure" +msgstr "\"%s\" bir prosedür değildir" + +#: parser/parse_func.c:282 +#, c-format +msgid "To call a function, use SELECT." +msgstr "Bir fonksiyon çağırmak için SELECT kullanın." + +#: parser/parse_func.c:288 +#, c-format +msgid "%s is a procedure" +msgstr "\"%s\" bir prosedürdür." + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "Bir prosedür çağırmak için CALL kullanın." + +#: parser/parse_func.c:306 +#, c-format +msgid "%s(*) specified, but %s is not an aggregate function" +msgstr "%s(*) belirtilmiş, ancak %s bir aggregate fonksiyonu değildir" + +#: parser/parse_func.c:313 +#, c-format +msgid "DISTINCT specified, but %s is not an aggregate function" +msgstr "DISTINCT belirtilmiş, ancak %s bir aggregate fonksiyonu değildir" + +#: parser/parse_func.c:319 +#, c-format +msgid "WITHIN GROUP specified, but %s is not an aggregate function" +msgstr "WITHIN GROUP belirtilmiş, ancak %s bir aggregate fonksiyonu değildir" + +#: parser/parse_func.c:325 +#, c-format +msgid "ORDER BY specified, but %s is not an aggregate function" +msgstr "ORDER BY belirtilmiş, ancak %s bir aggregate fonksiyonu değildir" + +#: parser/parse_func.c:331 +#, c-format +msgid "FILTER specified, but %s is not an aggregate function" +msgstr "FILTER belirtilmiş, ancak %s bir aggregate fonksiyonu değildir" + +#: parser/parse_func.c:337 +#, c-format +msgid "OVER specified, but %s is not a window function nor an aggregate function" +msgstr "OVER belirtilmiş, ancak %s bir window fonksiyonu ya da aggregate fonksiyonu değildir" + +#: parser/parse_func.c:375 +#, c-format +msgid "WITHIN GROUP is required for ordered-set aggregate %s" +msgstr "%s ordered-set aggregate'i için WITHIN GROUP kullanımı gerekiyor" + +#: parser/parse_func.c:381 +#, c-format +msgid "OVER is not supported for ordered-set aggregate %s" +msgstr "%s ordered-set aggregate'i için OVER desteklenmiyor." + +#: parser/parse_func.c:412 parser/parse_func.c:441 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." +msgstr "Bir sıralı-küme aggregate'i %s mevcut, fakat %d direk argüman gerekiyor %d değil" + +#: parser/parse_func.c:466 +#, c-format +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "Hypothetical-set aggregate %s kullanmak için , hypothetical direkt argümanların sayısı ( burada %d) sıralama sütunlarının sayısıyla (burada %d) eşleşmeli" + +#: parser/parse_func.c:480 +#, c-format +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." +msgstr "Bir sıralı-küme aggregate'i %s mevcut, fakat en azından %d direk argüman gerekiyor" + +#: parser/parse_func.c:499 +#, c-format +msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" +msgstr "%s bir sıralı-küme aggregate'i değil, o yüzden WITHIN GROUP ile kullanılamaz" + +#: parser/parse_func.c:512 +#, c-format +msgid "window function %s requires an OVER clause" +msgstr "%s window fonksiyonu bir OVER cümleciği gerektiriyor" + +#: parser/parse_func.c:519 +#, c-format +msgid "window function %s cannot have WITHIN GROUP" +msgstr "%s window fonksiyonu WITHIN GROUP ile kullanılamaz" + +#: parser/parse_func.c:548 +#, c-format +msgid "procedure %s is not unique" +msgstr "\"%s\" prosedürü biricik (unique) değil" + +#: parser/parse_func.c:551 +#, fuzzy, c-format +#| msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "En iyi aday işlem seçilememiş. Explicit type cast eklemeniz gerekebilir." + +#: parser/parse_func.c:557 +#, c-format +msgid "function %s is not unique" +msgstr "%s fonksiyonu benzersiz değildir" + +#: parser/parse_func.c:560 +#, c-format +msgid "Could not choose a best candidate function. You might need to add explicit type casts." +msgstr "En iyi aday fonksiyon seçilememiş. Explicit type cast eklemeniz gerekebilir." + +#: parser/parse_func.c:599 +#, c-format +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "Verilmiş ad ve argüman tiplerine uyan fonksiyon bulunamamış. ORDER BY 'ın yeri yanlış olabilir. ORDER BY aggregate'in bütün normal argümanlarından sonra gelmeli" + +#: parser/parse_func.c:607 parser/parse_func.c:2172 +#, c-format +msgid "procedure %s does not exist" +msgstr "\"%s\" prosedürü mevcut değil" + +#: parser/parse_func.c:610 +#, fuzzy, c-format +#| msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "Verilen ad ve argüman tiplerine uyan işlem bulunamadı. Explicit type cast'ler eklemeniz gerekebilir." + +#: parser/parse_func.c:619 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." +msgstr "Verilmiş ad ve argüman tiplerine uyan fonksiyon bulunamamış. Explicit type cast eklemeniz gerekebilir." + +#: parser/parse_func.c:721 +#, c-format +msgid "VARIADIC argument must be an array" +msgstr "VARIADIC argüman bir dizi (array) olmalıdır" + +#: parser/parse_func.c:773 parser/parse_func.c:837 +#, c-format +msgid "%s(*) must be used to call a parameterless aggregate function" +msgstr "%s(*) olmadan parametre olmayan aggregate çağırılamaz" + +#: parser/parse_func.c:780 +#, c-format +msgid "aggregates cannot return sets" +msgstr "aggregate set söndüremez" + +#: parser/parse_func.c:795 +#, c-format +msgid "aggregates cannot use named arguments" +msgstr "aggregate'ler named argüman kullanamaz" + +#: parser/parse_func.c:827 +#, c-format +msgid "DISTINCT is not implemented for window functions" +msgstr "window fonksiyonları için DISTINCT implement edilmemiştir" + +#: parser/parse_func.c:847 +#, c-format +msgid "aggregate ORDER BY is not implemented for window functions" +msgstr "window fonksiyonları için aggregate ORDER BY implement edilmemiştir" + +#: parser/parse_func.c:856 +#, c-format +msgid "FILTER is not implemented for non-aggregate window functions" +msgstr "aggregate olmayan window fonksiyonları için FILTER implement edilmemiştir" + +#: parser/parse_func.c:865 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "window fonksiyon çağırmaları küme dönen fonksiyon çağırmaları içeremez" + +#: parser/parse_func.c:873 +#, c-format +msgid "window functions cannot return sets" +msgstr "window fonksiyonları küme döndüremez" + +#: parser/parse_func.c:2059 +#, c-format +msgid "function name \"%s\" is not unique" +msgstr "%s fonksiyon adı biricik (unique) değildir" + +#: parser/parse_func.c:2061 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "fonksiyonu açık ve kesin olarak seçebilmek için argüman listesini belitriniz" + +#: parser/parse_func.c:2071 +#, c-format +msgid "could not find a function named \"%s\"" +msgstr "\"%s\" isimli bir fonksiyon bulunamadı" + +#: parser/parse_func.c:2153 +#, c-format +msgid "%s is not a function" +msgstr "%s bir fonksiyon değildir" + +#: parser/parse_func.c:2167 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "\"%s\" isimli bir prosedür bulunamadı" + +#: parser/parse_func.c:2198 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "\"%s\" isimli bir aggregate bulunamadı" + +#: parser/parse_func.c:2203 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "aggregate %s(*) mevcut değil" + +#: parser/parse_func.c:2208 +#, c-format +msgid "aggregate %s does not exist" +msgstr "aggregate %s mevcut değil" + +#: parser/parse_func.c:2221 +#, c-format +msgid "function %s is not an aggregate" +msgstr "%s fonksiyonu bir aggregate değildir" + +#: parser/parse_func.c:2271 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "JOIN ifadesinde küme-dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2292 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "policy ifadelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2308 +msgid "set-returning functions are not allowed in window definitions" +msgstr "window tanımlarında küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2346 +msgid "set-returning functions are not allowed in check constraints" +msgstr "check kısıtlamalarında (constraint) küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2350 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "DEFAULT ifadelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2353 +msgid "set-returning functions are not allowed in index expressions" +msgstr "İNDEX ifadelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2356 +msgid "set-returning functions are not allowed in index predicates" +msgstr "indeks yüklemlerinde (predicate) küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2359 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "transform ifadesinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2362 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "EXECUTE parametrelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2365 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "trigger WHEN şart ifadelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2368 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "bölümleme anahtarı (partition key) ifadelerinde küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_func.c:2371 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "CALL argümanlarında küme dönen fonksiyonlar kullanılamaz" + +#: parser/parse_node.c:87 +#, c-format +msgid "target lists can have at most %d entries" +msgstr "hedef listesi en fazla %d kayıt içerebilir" + +#: parser/parse_node.c:256 +#, c-format +msgid "cannot subscript type %s because it is not an array" +msgstr "%s tipi bir array olmadığı için ona subscript yapılamaz " + +#: parser/parse_node.c:358 parser/parse_node.c:395 +#, c-format +msgid "array subscript must have type integer" +msgstr "array subscript tamsyı tipinde olmalıdır" + +#: parser/parse_node.c:426 +#, c-format +msgid "array assignment requires type %s but expression is of type %s" +msgstr "array ataması %s tipini gerektirmektedir ancak ifade %s tipindedir" + +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 utils/adt/regproc.c:704 +#, c-format +msgid "operator does not exist: %s" +msgstr "operator mevcut değil: %s" + +#: parser/parse_oper.c:224 +#, c-format +msgid "Use an explicit ordering operator or modify the query." +msgstr "Sıralama işlemini açıkça belirtin veya sorguda değişiklik yapın" + +#: parser/parse_oper.c:480 +#, c-format +msgid "operator requires run-time type coercion: %s" +msgstr "işlem, çalışma zamanı tip zola değiştirmeyi gerektiriri: %s" + +#: parser/parse_oper.c:716 +#, c-format +msgid "operator is not unique: %s" +msgstr "operator eşsiz değildir: %s" + +#: parser/parse_oper.c:718 +#, c-format +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." +msgstr "En iyi aday işlem seçilememiş. Explicit type cast eklemeniz gerekebilir." + +#: parser/parse_oper.c:727 +#, c-format +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "Verilen ad ve argüman tipine uyan operatör bulunamadı. Bir explicit type cast eklemeniz gerekebilir." + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." +msgstr "Verilen ad ve argüman tiplerine uyan işlem bulunamadı. Explicit type cast'ler eklemeniz gerekebilir." + +#: parser/parse_oper.c:790 parser/parse_oper.c:912 +#, c-format +msgid "operator is only a shell: %s" +msgstr "operatör sadece bir shell: %s" + +#: parser/parse_oper.c:900 +#, c-format +msgid "op ANY/ALL (array) requires array on right side" +msgstr "op ANY/ALL (array) sağ tarafta bir array gerektiri" + +#: parser/parse_oper.c:942 +#, c-format +msgid "op ANY/ALL (array) requires operator to yield boolean" +msgstr "op ANY/ALL (array) operatorun boolean tipinde değer getirilmesi gerekir" + +#: parser/parse_oper.c:947 +#, c-format +msgid "op ANY/ALL (array) requires operator not to return a set" +msgstr "op ANY/ALL (array) operatorun set tipinde değer getirilmesi gerekir" + +#: parser/parse_param.c:216 +#, c-format +msgid "inconsistent types deduced for parameter $%d" +msgstr "$%d parametresi için geçersiz tip bulundu" + +#: parser/parse_relation.c:176 +#, c-format +msgid "table reference \"%s\" is ambiguous" +msgstr "\"%s\" tablo referanslı iki anlamlı" + +#: parser/parse_relation.c:220 +#, c-format +msgid "table reference %u is ambiguous" +msgstr "%u tablo referanslı iki anlamlı" + +#: parser/parse_relation.c:419 +#, c-format +msgid "table name \"%s\" specified more than once" +msgstr "\"%s\" tablo adı birden fazla kez belirtilmiştir" + +#: parser/parse_relation.c:446 parser/parse_relation.c:3227 +#, c-format +msgid "invalid reference to FROM-clause entry for table \"%s\"" +msgstr "FROM öğesinde \"%s\" tablo öğesine geçersiz başvuru" + +#: parser/parse_relation.c:449 parser/parse_relation.c:3232 +#, c-format +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\" tablosu için kayıt var ama sorgunun bu kısmaından bu tablo erişilemez." + +#: parser/parse_relation.c:451 +#, c-format +msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." +msgstr "Bir LATERAL referans için birleştiren JOIN tipi INNER ya da LEFT olmalı." + +#: parser/parse_relation.c:727 +#, c-format +msgid "system column \"%s\" reference in check constraint is invalid" +msgstr "check kısıtlaması (constraint) tarafından referans edilen sistem sütunu \"%s\" geçersiz" + +#: parser/parse_relation.c:1086 parser/parse_relation.c:1366 parser/parse_relation.c:1936 +#, c-format +msgid "table \"%s\" has %d columns available but %d columns specified" +msgstr "\"%s\" tablosuna %d sütun bulunmakta ancak sorguda %d sütun belirtilmiş" + +#: parser/parse_relation.c:1173 +#, c-format +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%s\" isimli bir WITH nesnesi var, ama sorgunun bu kısmından ona erişilemez." + +#: parser/parse_relation.c:1175 +#, c-format +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgstr "WITH RECURSIVE kullanın ya da ileri (forward) referansları ortadan kaldırmak için WITH maddelerini tekrar sıralayın." + +#: parser/parse_relation.c:1486 +#, c-format +msgid "a column definition list is only allowed for functions returning \"record\"" +msgstr "sütun tanım listesi, sadece \"record\" veri tipini döndüren fonksiyonlarda kullanılır" + +#: parser/parse_relation.c:1495 +#, c-format +msgid "a column definition list is required for functions returning \"record\"" +msgstr "sütun tanım listesi,\"record\" veri tipini döndüren fonksiyonlarda kullanılmalıdır" + +#: parser/parse_relation.c:1575 +#, c-format +msgid "function \"%s\" in FROM has unsupported return type %s" +msgstr "FROM ifadesinde kullanılan \"%s\" fonksiyonu %s desteklenmeyen döndürme tipini kullanıyor" + +#: parser/parse_relation.c:1764 +#, c-format +msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" +msgstr "\"%s\" VALUES lıstesinde %d sütun varken %d sütun belirtilmiştir" + +#: parser/parse_relation.c:1819 +#, c-format +msgid "joins can have at most %d columns" +msgstr "birleştirmeler (join) en fazla %d sütun içerebilir" + +#: parser/parse_relation.c:1909 +#, c-format +msgid "WITH query \"%s\" does not have a RETURNING clause" +msgstr "\"%s\" WITH sorgusunun bir RETURNING cümleciği yok" + +#: parser/parse_relation.c:2846 parser/parse_relation.c:2884 parser/parse_relation.c:3011 +#, c-format +msgid "column %d of relation \"%s\" does not exist" +msgstr "\"%2$s\" tablosunun %1$d kolonu mevcut değil" + +#: parser/parse_relation.c:3230 +#, c-format +msgid "Perhaps you meant to reference the table alias \"%s\"." +msgstr "Belki tablonun arma adını \"%s\" kullanmak istediniz" + +#: parser/parse_relation.c:3238 +#, c-format +msgid "missing FROM-clause entry for table \"%s\"" +msgstr "\"%s\" tablo öğesinde FROM öğesi eksik" + +#: parser/parse_relation.c:3290 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\"." +msgstr "Belki \"%s.%s\" sütununu kullanmak istediniz" + +#: parser/parse_relation.c:3292 +#, c-format +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "\"%2$s\" tablosunda \"%1$s\" diye bir sütun var, ama sorgunun bu kısmından ona erişilemez." + +#: parser/parse_relation.c:3309 +#, c-format +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgstr "Belki \"%s.%s\" sütununu ya da \"%s.%s\" sütununu kullanmak istediniz" + +#: parser/parse_target.c:483 parser/parse_target.c:790 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "\"%s\" sistem sütununa veri atanamıyor" + +#: parser/parse_target.c:511 +#, c-format +msgid "cannot set an array element to DEFAULT" +msgstr "array öğesine DEFAULT değeri atanamıyor" + +#: parser/parse_target.c:516 +#, c-format +msgid "cannot set a subfield to DEFAULT" +msgstr "subfield, DEFAULT değeri alamaz" + +#: parser/parse_target.c:585 +#, c-format +msgid "column \"%s\" is of type %s but expression is of type %s" +msgstr "\"%s\" sütunu %s tipinde ancak ifade %s tipindedir" + +#: parser/parse_target.c:774 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "%3$s composite tipi olmadığı için \"%2$s\" sütununun \"%1$s\" alanına atama başarısız" + +#: parser/parse_target.c:783 +#, c-format +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "%3$s veri tipi olmadığı için \"%2$s\" sütununun \"%1$s\" alanına atama başarısız" + +#: parser/parse_target.c:860 +#, c-format +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" +msgstr "\"%s\" alanına atama işlemi %s veri tipini gerektirmektedir ancak %s veri tipi alınmış" + +#: parser/parse_target.c:870 +#, c-format +msgid "subfield \"%s\" is of type %s but expression is of type %s" +msgstr "\"%s\" subfield %s tipinde ancak ifade %s tipindedir" + +#: parser/parse_target.c:1289 +#, c-format +msgid "SELECT * with no tables specified is not valid" +msgstr "SELECT *, tablo tanımı olmadan geçersizdir" + +#: parser/parse_type.c:83 +#, c-format +msgid "improper %%TYPE reference (too few dotted names): %s" +msgstr "geçersiz %%TYPE başvurusu (çok az noktalı isim): %s" + +#: parser/parse_type.c:105 +#, c-format +msgid "improper %%TYPE reference (too many dotted names): %s" +msgstr "geçersiz %%TYPE başvurusu (çok fazla noktalı isim): %s" + +#: parser/parse_type.c:140 +#, c-format +msgid "type reference %s converted to %s" +msgstr "type reference %s'dan %s'a çevirilmiş" + +#: parser/parse_type.c:261 parser/parse_type.c:838 utils/cache/typcache.c:373 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "\"%s\" tipi bir shelldir" + +#: parser/parse_type.c:346 +#, c-format +msgid "type modifier is not allowed for type \"%s\"" +msgstr "\"%s\" veri tipi için tip niteliyicisi kullanılamaz" + +#: parser/parse_type.c:388 +#, c-format +msgid "type modifiers must be simple constants or identifiers" +msgstr "tip modifier'lar basit sabitler (constant) veya tanıtıcılar (identifier) olmalıdır" + +#: parser/parse_type.c:704 parser/parse_type.c:803 +#, c-format +msgid "invalid type name \"%s\"" +msgstr "tip adı \"%s\" geçersiz" + +#: parser/parse_utilcmd.c:272 +#, c-format +msgid "cannot create partitioned table as inheritance child" +msgstr "kalıt altı (inheritance child) olarak bölümlenmiş tablo oluşturulamaz" + +#: parser/parse_utilcmd.c:448 +#, c-format +msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" +msgstr "%s, \"%s.%s\" serial sütunu için \"%s\" örtülü sequence oluşturacaktır" + +#: parser/parse_utilcmd.c:571 +#, c-format +msgid "array of serial is not implemented" +msgstr "seri dizisi (array of serial) implement edilmemiştir" + +#: parser/parse_utilcmd.c:647 parser/parse_utilcmd.c:659 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgstr "\"%2$s\" tablosunda \"%1$s\" sütunu için çelişen NULL/NOT NULL tanımları" + +#: parser/parse_utilcmd.c:671 +#, c-format +msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgstr "\"%2$s\" tablosunun \"%1$s\" sütunu için birden fazla varsayılan değer verilmiştir" + +#: parser/parse_utilcmd.c:688 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "tipli tablolarda özdeşlik (identity) sütunları desteklenmiyor" + +#: parser/parse_utilcmd.c:692 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "bölümlerde (partition) özdeşlik (identity) sütunları desteklenmiyor" + +#: parser/parse_utilcmd.c:701 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "\"%2$s\" tablosunun \"%1$s\" sütunu için birden fazla özdeşlik tanımlaması (identity specification) verilmiştir" + +#: parser/parse_utilcmd.c:724 parser/parse_utilcmd.c:823 +#, c-format +msgid "primary key constraints are not supported on foreign tables" +msgstr "foreign tablolarda primary key kısıtlamaları (constraint) desteklenmiyor" + +#: parser/parse_utilcmd.c:733 parser/parse_utilcmd.c:833 +#, c-format +msgid "unique constraints are not supported on foreign tables" +msgstr "foreign tablolarda unique kısıtlamaları (constraint) desteklenmiyor" + +#: parser/parse_utilcmd.c:750 parser/parse_utilcmd.c:863 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "foreign tablolarda foreign key kısıtlamaları (constraint) desteklenmiyor" + +#: parser/parse_utilcmd.c:778 +#, c-format +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "\"%2$s\" tablosunun \"%1$s\" sütunu için hem varsayılan değer hem de özdeşlik (identity) tanımlanmıştır" + +#: parser/parse_utilcmd.c:843 +#, c-format +msgid "exclusion constraints are not supported on foreign tables" +msgstr "foreign tablolarda exclusion kısıtlamaları (constraint) desteklenmiyor" + +#: parser/parse_utilcmd.c:849 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "bölümlenmiş (partitioned) tablolarda exclusion kısıtlamaları (constraint) desteklenmiyor" + +#: parser/parse_utilcmd.c:913 +#, c-format +msgid "LIKE is not supported for creating foreign tables" +msgstr "foreign tablo oluştururken LIKE desteklenmiyor" + +#: parser/parse_utilcmd.c:1516 parser/parse_utilcmd.c:1623 +#, c-format +msgid "Index \"%s\" contains a whole-row table reference." +msgstr "\"%s\" indeksi bir bütün satır tablo referansı (whole-row table reference) içeriyor" + +#: parser/parse_utilcmd.c:1973 +#, c-format +msgid "cannot use an existing index in CREATE TABLE" +msgstr "CREATE TABLE içinde mevcut bir index kullanılamaz" + +#: parser/parse_utilcmd.c:1993 +#, c-format +msgid "index \"%s\" is already associated with a constraint" +msgstr "\"%s\" indeksi zaten bir kısıtlama (constrait) ile ilişkilendirilmiş" + +#: parser/parse_utilcmd.c:2001 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "\"%s\" indeksi \"%s\" tablosuna ait değil" + +#: parser/parse_utilcmd.c:2008 +#, c-format +msgid "index \"%s\" is not valid" +msgstr "\"%s\" indeksi geçersiz" + +#: parser/parse_utilcmd.c:2014 +#, c-format +msgid "\"%s\" is not a unique index" +msgstr "\"%s\" bir unique indeks değildir" + +#: parser/parse_utilcmd.c:2015 parser/parse_utilcmd.c:2022 parser/parse_utilcmd.c:2029 parser/parse_utilcmd.c:2101 +#, c-format +msgid "Cannot create a primary key or unique constraint using such an index." +msgstr "öyle bir indeks kullanılarak primary key ya da unique kısıtlaması (constraint) oluşturulamaz" + +#: parser/parse_utilcmd.c:2021 +#, c-format +msgid "index \"%s\" contains expressions" +msgstr "\"%s\" indeksi ifadeler (expression) içeriyor" + +#: parser/parse_utilcmd.c:2028 +#, c-format +msgid "\"%s\" is a partial index" +msgstr "\"%s\" kısmi (partial) bir indekstir" + +#: parser/parse_utilcmd.c:2040 +#, c-format +msgid "\"%s\" is a deferrable index" +msgstr "\"%s\" ertelenebilir (deferrable) bir indekstir" + +#: parser/parse_utilcmd.c:2041 +#, c-format +msgid "Cannot create a non-deferrable constraint using a deferrable index." +msgstr "ertelenebilir (deferrable) bir indeks kullanarak ertelenebilir olmayan (non-deferrable) bir kısıtlama (constraint) oluşturulamaz" + +#: parser/parse_utilcmd.c:2100 +#, c-format +msgid "index \"%s\" does not have default sorting behavior" +msgstr "\"%s\" indeksinin varsayılan bir sıralama davranışı (sorting behavior) yok" + +#: parser/parse_utilcmd.c:2249 +#, c-format +msgid "column \"%s\" appears twice in primary key constraint" +msgstr "\"%s\" sütunu primary key kısıtlamasında iki rastlanıyor" + +#: parser/parse_utilcmd.c:2255 +#, c-format +msgid "column \"%s\" appears twice in unique constraint" +msgstr "\"%s\" sütunu unique kısıtlamasında iki kez rastlanıyor" + +#: parser/parse_utilcmd.c:2578 +#, c-format +msgid "index expressions and predicates can refer only to the table being indexed" +msgstr "index ifade ve yüklemler sadece indexlenen tabloyu referans edebilirler" + +#: parser/parse_utilcmd.c:2624 +#, c-format +msgid "rules on materialized views are not supported" +msgstr "materialized view'ler üzerinde kurallar (rule) desteklenmiyor" + +#: parser/parse_utilcmd.c:2685 +#, c-format +msgid "rule WHERE condition cannot contain references to other relations" +msgstr "rule tanımının WHERE öğesinde başka tablolara referans içermemelidir" + +#: parser/parse_utilcmd.c:2757 +#, c-format +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" +msgstr "rule tanımının WHERE öğesinde sadece SELECT, INSERT, UPDATE veya DELETE işlemi bulunabilir" + +#: parser/parse_utilcmd.c:2775 parser/parse_utilcmd.c:2874 rewrite/rewriteHandler.c:498 rewrite/rewriteManip.c:1015 +#, c-format +msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" +msgstr "conditional UNION/INTERSECT/EXCEPT komutları empemente edilmemiş" + +#: parser/parse_utilcmd.c:2793 +#, c-format +msgid "ON SELECT rule cannot use OLD" +msgstr "ON SELECT rule OLD tanımını kullanamaz" + +#: parser/parse_utilcmd.c:2797 +#, c-format +msgid "ON SELECT rule cannot use NEW" +msgstr "ON SELECT rule NEW tanımını kullanamaz" + +#: parser/parse_utilcmd.c:2806 +#, c-format +msgid "ON INSERT rule cannot use OLD" +msgstr "ON INSERT rule OLD tanımını kullanamaz" + +#: parser/parse_utilcmd.c:2812 +#, c-format +msgid "ON DELETE rule cannot use NEW" +msgstr "ON DELETE rule NEW tanımını kullanamaz" + +#: parser/parse_utilcmd.c:2840 +#, c-format +msgid "cannot refer to OLD within WITH query" +msgstr "WITH sorgusu içinde OLD'a refer edilemez" + +#: parser/parse_utilcmd.c:2847 +#, c-format +msgid "cannot refer to NEW within WITH query" +msgstr "WITH sorgusu içinde NEW'e refer edilemez" + +#: parser/parse_utilcmd.c:3285 +#, c-format +msgid "misplaced DEFERRABLE clause" +msgstr "DEFERRABLE ifadesi burada kullanılamaz" + +#: parser/parse_utilcmd.c:3290 parser/parse_utilcmd.c:3305 +#, c-format +msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" +msgstr "birden fazla DEFERRABLE/NOT DEFERRABLE tanımına izin verilmez" + +#: parser/parse_utilcmd.c:3300 +#, c-format +msgid "misplaced NOT DEFERRABLE clause" +msgstr "NOT DEFERRABLE yanlış yerde kullanılmış" + +#: parser/parse_utilcmd.c:3321 +#, c-format +msgid "misplaced INITIALLY DEFERRED clause" +msgstr "INITIALLY DEFERRED yanlış yerde kullanılmış" + +#: parser/parse_utilcmd.c:3326 parser/parse_utilcmd.c:3352 +#, c-format +msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" +msgstr "birden fazla INITIALLY IMMEDIATE/DEFERRED kullanılamaz" + +#: parser/parse_utilcmd.c:3347 +#, c-format +msgid "misplaced INITIALLY IMMEDIATE clause" +msgstr "INITIALLY IMMEDIATE yanlış yerde kullanılmış" + +#: parser/parse_utilcmd.c:3538 +#, c-format +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" +msgstr "CREATE işleminin belirttiği şema (%s) yaratılacak (%s) olanından farklı" + +#: parser/parse_utilcmd.c:3572 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "\"%s\" tablosu bölümlendirilmemiş" + +#: parser/parse_utilcmd.c:3579 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "\"%s\" indeksi bölümlendirilmemiş" + +#: parser/parse_utilcmd.c:3613 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "bir hash-bölümlenmiş tablonun varsayılan bölmesi olamaz" + +#: parser/parse_utilcmd.c:3630 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "hash bölümlemesi (list partition) için geçersiz sınır tanımlaması" + +#: parser/parse_utilcmd.c:3636 partitioning/partbounds.c:2127 +#, fuzzy, c-format +#| msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgid "modulus for hash partition must be a positive integer" +msgstr "%s: süre pozitif bir tamsayı olmalı (süre \"%d\" dir)\n" + +#: parser/parse_utilcmd.c:3643 partitioning/partbounds.c:2135 +#, fuzzy, c-format +#| msgid "precision for type float must be less than 54 bits" +msgid "remainder for hash partition must be less than modulus" +msgstr "float veri tipinin kesinliği ne çok 54 bit olabilir" + +#: parser/parse_utilcmd.c:3655 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "liste bölümlemesi (list partition) için geçersiz sınır tanımlaması" + +#: parser/parse_utilcmd.c:3711 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "aralık bölümlemesi (range partition) için geçersiz sınır tanımlaması" + +#: parser/parse_utilcmd.c:3717 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM, bölümleme sütunu başına tam olarak \"bir\" değer belirtmeli" + +#: parser/parse_utilcmd.c:3721 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO, bölümleme sütunu başına tam olarak \"bir\" değer belirtmeli" + +#: parser/parse_utilcmd.c:3768 parser/parse_utilcmd.c:3782 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "aralık sınırı tanımlanırken NULL değer girilemez" + +#: parser/parse_utilcmd.c:3829 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "MAXVALUE ardından gelen her sınır aynı şekilde MAXVALUE olmalı" + +#: parser/parse_utilcmd.c:3836 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "MINVALUE ardından gelen her sınır aynı şekilde MINVALUE olmalı" + +#: parser/parse_utilcmd.c:3867 parser/parse_utilcmd.c:3879 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "belirtilen değer %s tipine dönüştürülemez (\"%s\" sütunu için)" + +#: parser/parse_utilcmd.c:3881 +#, fuzzy, c-format +#| msgid "operator requires run-time type coercion: %s" +msgid "The cast requires a non-immutable conversion." +msgstr "işlem, çalışma zamanı tip zola değiştirmeyi gerektiriri: %s" + +#: parser/parse_utilcmd.c:3882 +#, c-format +msgid "Try putting the literal value in single quotes." +msgstr "Değeri tek tırnak içinde yazmayı deneyiniz." + +#: parser/scansup.c:204 +#, c-format +msgid "identifier \"%s\" will be truncated to \"%s\"" +msgstr "\"%s tanımlayıcısı (identifier) \"%s\" ye truncate edilecektir" + +#: partitioning/partbounds.c:331 +#, c-format +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "\"%s\" bölümü (partition) mevcut \"%s\" varsayılan bölümüyle çakışıyor" + +#: partitioning/partbounds.c:390 +#, c-format +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "" + +#: partitioning/partbounds.c:486 +#, c-format +msgid "empty range bound specified for partition \"%s\"" +msgstr "%s bölümü (partition) için boş aralık sınırı belirtilmiş" + +#: partitioning/partbounds.c:488 +#, c-format +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "Belirtilen %s alt sınırı %s üst sınırından büyük ya da eşit" + +#: partitioning/partbounds.c:585 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "\"%s\" bölümü (partition) \"%s\" bölümüyle çakışıyor" + +#: partitioning/partbounds.c:685 +#, fuzzy, c-format +#| msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "\"%s\" nesnesi \"%s\" nesnesinin bir bölümü (partition) değildir" + +#: partitioning/partbounds.c:724 +#, fuzzy, c-format +#| msgid "partition constraint is violated by some row" +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "bölümleme kısıtlaması bir(kaç) satır tarafından ihlal edilmiş" + +#: partitioning/partbounds.c:2131 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "" + +#: partitioning/partbounds.c:2158 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" bir hash bölümlenmiş tablo değildir" + +#: partitioning/partbounds.c:2169 partitioning/partbounds.c:2285 +#, fuzzy, c-format +#| msgid "number of columns does not match number of values" +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "değer sayısı sayısı ile kolon satısı eşleşmiyor" + +#: partitioning/partbounds.c:2189 partitioning/partbounds.c:2221 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "" + +#: port/pg_shmem.c:196 port/sysv_shmem.c:196 +#, c-format +msgid "could not create shared memory segment: %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: port/pg_shmem.c:197 port/sysv_shmem.c:197 +#, c-format +msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." +msgstr "Başarısız sistem çağrısı: shmget(key=%lu, size=%zu, 0%o)." + +#: port/pg_shmem.c:201 port/sysv_shmem.c:201 +#, fuzzy, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Bu hata genellikle PostgreSQL'in shared kullanımı boş takas alanını aştığı zaman ortaya çıkıyor. İstenilen bellek bouytu (şu an %lu bayt) düşürmek için, PostgreSQL'in shared_buffers (şu an %d) ve/veya max_connections (şu an %d) parametrelerini düşürün.\n" +"PostgreSQL dokümanlarında shared memory yapılandırması hakkında daha fazla bilgi bulabilirsiniz." + +#: port/pg_shmem.c:208 port/sysv_shmem.c:208 +#, fuzzy, c-format +msgid "" +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Bu hata genellikle PostgreSQL'in shared kullanımı boş takas alanını aştığı zaman ortaya çıkıyor. İstenilen bellek bouytu (şu an %lu bayt) düşürmek için, PostgreSQL'in shared_buffers (şu an %d) ve/veya max_connections (şu an %d) parametrelerini düşürün.\n" +"PostgreSQL dokümanlarında shared memory yapılandırması hakkında daha fazla bilgi bulabilirsiniz." + +#: port/pg_shmem.c:214 port/sysv_shmem.c:214 +#, fuzzy, c-format +#| msgid "" +#| "This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached. If you cannot increase the shared memory limit, reduce PostgreSQL's shared memory request (currently %lu " +#| "bytes), by reducing its shared_buffers parameter (currently %d) and/or its max_connections parameter (currently %d).\n" +#| "The PostgreSQL documentation contains more information about shared memory configuration." +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." +msgstr "" +"Bu hata mesajı yeterli boş disk alanı kalmadığı anlamına gelmiyor . Bu durum, tüm shared memory ID alınmış olduğu zamanda -- ki bu durumda SHMMNI parametresinin değerleri yükseltmelisiniz; ya da sistemin shared memory sınırına ulaşıldığı zamanda oluşur. Shared memory sınırını yükseltemezseniz, PostgreSQL sisteminin shared memory tüketimini (şu an %lu bayt) shared_buffers (şu an %d) ve/" +"veya max_connections parametresini (şu an %d) düşürerek azaltabilirsiniz.\n" +"PostgreSQL belgelerinde bu konu ile ilgili daha ayrıntılı açıklama ve yapılandırma hakkında bilgileri bulabilirsiniz." + +#: port/pg_shmem.c:505 port/sysv_shmem.c:505 +#, c-format +msgid "could not map anonymous shared memory: %m" +msgstr "anonim shared memory eşlenemedi (map): %m" + +#: port/pg_shmem.c:507 port/sysv_shmem.c:507 +#, fuzzy, c-format +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "" +"Bu hata genellikle PostgreSQL'in shared kullanımı boş takas alanını aştığı zaman ortaya çıkıyor. İstenilen bellek bouytu (şu an %lu bayt) düşürmek için, PostgreSQL'in shared_buffers (şu an %d) ve/veya max_connections (şu an %d) parametrelerini düşürün.\n" +"PostgreSQL dokümanlarında shared memory yapılandırması hakkında daha fazla bilgi bulabilirsiniz." + +#: port/pg_shmem.c:573 port/sysv_shmem.c:573 +#, c-format +msgid "huge pages not supported on this platform" +msgstr "bu platformda çok büyük sayfalar desteklenmiyor" + +#: port/pg_shmem.c:668 port/sysv_shmem.c:668 +#, c-format +msgid "could not stat data directory \"%s\": %m" +msgstr "\"%s\" veri dizin hakkında bilgi alınamadı: %m" + +#: port/sysv_sema.c:123 +#, c-format +msgid "could not create semaphores: %m" +msgstr "semaphores oluşturma hatası: %m" + +#: port/sysv_sema.c:124 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "Başarısız çağrı: semget(%lu, %d, 0%o)." + +#: port/sysv_sema.c:128 +#, fuzzy, c-format +#| msgid "" +#| "This error does *not* mean that you have run out of disk space.\n" +#| "It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter (currently %d).\n" +#| "The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections " +"parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"Bu hata mesajı yeterli boş disk alanı kalmadığı anlamına gelmiyor .\n" +"Bu durum, sistemin semaphore set (SEMMNI) veya semaphore (SEMMNS) sayı sınırlaması aşmasında meydana gelmektedir. Belirtilen parametrelerin değerleri yükseltmelisiniz. Başka seçeneğiniz ise PostgerSQL sisteminin semaphore tütekitimini max_connections parametresini şu an %d) düşürerek azaltabilirsiniz.\n" +"PostgreSQL dokümanlarında bu konu ile ilgili daha ayrıntılı açıklama ve konfigurasyon hakkında bilgileri bulabilirsiniz." + +#: port/sysv_sema.c:158 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "Kernel SEMVMX değerini en az %d değerine kadar çıkartmalısınız. Daha fazla bilgi için PostgreSQL dokümanlarına bakın." + +#: port/win32/crashdump.c:121 +#, c-format +msgid "could not load dbghelp.dll, cannot write crash dump\n" +msgstr "dbghelp.dll yüklenemedi, çökme dökümü (crash dump) yazılamıyor\n" + +#: port/win32/crashdump.c:129 +#, c-format +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgstr "dbghelp.dll içindeki gerekli fonksiyonlar yüklenemedi, çökme dökümü (crash dump) yazılamıyor\n" + +#: port/win32/crashdump.c:160 +#, c-format +msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" +msgstr "\"%s\" çökme dökümü (crash dump) dosyası, yazmak için açılamadı: hata kodu %lu\n" + +#: port/win32/crashdump.c:167 +#, c-format +msgid "wrote crash dump to file \"%s\"\n" +msgstr "çökme dökümü (crash dump) \"%s\" dosyasına yazıldı\n" + +#: port/win32/crashdump.c:169 +#, c-format +msgid "could not write crash dump to file \"%s\": error code %lu\n" +msgstr "çökme dökümü (crash dump), \"%s\" dosyasına yazılamadı: hata kodu %lu\n" + +#: port/win32/signal.c:194 +#, c-format +msgid "could not create signal listener pipe for PID %d: error code %lu" +msgstr "%d PID için signal listener pipe oluşturulamadı: hata kodu %lu" + +#: port/win32/signal.c:274 port/win32/signal.c:306 +#, c-format +msgid "could not create signal listener pipe: error code %lu; retrying\n" +msgstr "signal listener pipe oluşturulamadı: hata kodu %lu; yeniden deneniyor\n" + +#: port/win32/signal.c:317 +#, c-format +msgid "could not create signal dispatch thread: error code %lu\n" +msgstr "signal dispatch thread oluşturulamıyor: hata kodu %lu\n" + +#: port/win32_sema.c:104 +#, c-format +msgid "could not create semaphore: error code %lu" +msgstr "semaphore oluşturma hatası: hata kodu %lu" + +#: port/win32_sema.c:181 +#, c-format +msgid "could not lock semaphore: error code %lu" +msgstr "lock semaphore başarısız: hata kodu %lu" + +#: port/win32_sema.c:201 +#, c-format +msgid "could not unlock semaphore: error code %lu" +msgstr "unlock semaphore başarısız: hata kodu %lu" + +#: port/win32_sema.c:231 +#, c-format +msgid "could not try-lock semaphore: error code %lu" +msgstr "try-lock semaphore başarısız: hata kodu %lu" + +#: port/win32_shmem.c:122 port/win32_shmem.c:130 port/win32_shmem.c:142 port/win32_shmem.c:157 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: error code %lu" +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "shared memory segment oluşturulamıyor: hata kodu %lu" + +#: port/win32_shmem.c:123 port/win32_shmem.c:131 port/win32_shmem.c:143 port/win32_shmem.c:158 +#, c-format +msgid "Failed system call was %s." +msgstr "Başarısız sistem çağrısı: %s." + +#: port/win32_shmem.c:153 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not enable Lock Pages in Memory user right" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: port/win32_shmem.c:154 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "" + +#: port/win32_shmem.c:210 +#, c-format +msgid "the processor does not support large pages" +msgstr "işlemci büyük sayfaları (large page) desteklememektedir." + +#: port/win32_shmem.c:212 port/win32_shmem.c:217 +#, c-format +msgid "disabling huge pages" +msgstr "çok büyük sayfalar (huge page) etkisiz hale getiriliyor" + +#: port/win32_shmem.c:279 port/win32_shmem.c:315 port/win32_shmem.c:333 +#, c-format +msgid "could not create shared memory segment: error code %lu" +msgstr "shared memory segment oluşturulamıyor: hata kodu %lu" + +#: port/win32_shmem.c:280 +#, c-format +msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." +msgstr "Başarısız sistem çağrısı: CreateFileMapping(size=%zu, name=%s)" + +#: port/win32_shmem.c:305 +#, c-format +msgid "pre-existing shared memory block is still in use" +msgstr "daha önce tanımlanmış shared memory bloğu hala kullanılmaktadır" + +#: port/win32_shmem.c:306 +#, c-format +msgid "Check if there are any old server processes still running, and terminate them." +msgstr "Hala çalışan sunucu süreçleri bulun ve varsa sonlandırın." + +#: port/win32_shmem.c:316 +#, c-format +msgid "Failed system call was DuplicateHandle." +msgstr "Başarısız sistem çağrısı: DuplicateHandle." + +#: port/win32_shmem.c:334 +#, c-format +msgid "Failed system call was MapViewOfFileEx." +msgstr "Başarısız sistem çağrısı: MapViewOfFileEx." + +#: postmaster/autovacuum.c:406 +#, c-format +msgid "could not fork autovacuum launcher process: %m" +msgstr "vacuum süreci fork edilemedi: %m" + +#: postmaster/autovacuum.c:442 +#, c-format +msgid "autovacuum launcher started" +msgstr "otomatik vacuum başlatma süreci çalıştırıldı" + +#: postmaster/autovacuum.c:832 +#, c-format +msgid "autovacuum launcher shutting down" +msgstr "otomatik vacuum başlatma süreci kapatılıyor" + +#: postmaster/autovacuum.c:1494 +#, c-format +msgid "could not fork autovacuum worker process: %m" +msgstr "Otomatik vakum worker süreci fork edilemedi: %m" + +#: postmaster/autovacuum.c:1700 +#, c-format +msgid "autovacuum: processing database \"%s\"" +msgstr "autovacuum: \"%s\" veritabanı işleniyor" + +#: postmaster/autovacuum.c:2269 +#, c-format +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: \"%s.%s.%s\" orphan temp siliniyor" + +#: postmaster/autovacuum.c:2498 +#, c-format +msgid "automatic vacuum of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" tablosunun otomatik vacuum'u" + +#: postmaster/autovacuum.c:2501 +#, c-format +msgid "automatic analyze of table \"%s.%s.%s\"" +msgstr "\"%s.%s.%s\" tablosunun otomatik analizi" + +#: postmaster/autovacuum.c:2694 +#, fuzzy, c-format +#| msgid "permission denied for relation %s" +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "%s nesnesine erişim engellendi" + +#: postmaster/autovacuum.c:3273 +#, c-format +msgid "autovacuum not started because of misconfiguration" +msgstr "geçersiz ayarlarından dolayı autovacuum çalıştırılamadı" + +#: postmaster/autovacuum.c:3274 +#, c-format +msgid "Enable the \"track_counts\" option." +msgstr "\"track_counts\" seçeneği etkinleştir." + +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 +#, c-format +msgid "registering background worker \"%s\"" +msgstr "\"%s\" background worker'ı kaydediliyor (register)" + +#: postmaster/bgworker.c:427 +#, c-format +msgid "unregistering background worker \"%s\"" +msgstr "\"%s\" background worker'ı unregister ediliyor" + +#: postmaster/bgworker.c:592 +#, c-format +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" +msgstr "" + +#: postmaster/bgworker.c:601 +#, c-format +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "" + +#: postmaster/bgworker.c:615 +#, c-format +msgid "background worker \"%s\": invalid restart interval" +msgstr "background worker \"%s\": geçersiz yeniden başlatma süresi (interval)" + +#: postmaster/bgworker.c:630 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "background worker \"%s\": paralel worker'lar yeniden başlatma için yapılandırılamayabilr" + +#: postmaster/bgworker.c:674 +#, c-format +msgid "terminating background worker \"%s\" due to administrator command" +msgstr "yönetici talimatı doğrultusunda \"%s\" background worker'ı sonlandırılıyor" + +#: postmaster/bgworker.c:863 +#, c-format +msgid "background worker \"%s\": must be registered in shared_preload_libraries" +msgstr "background worker \"%s\": shared_preload_libraries de kayıtlı olmalı" + +#: postmaster/bgworker.c:875 +#, c-format +msgid "background worker \"%s\": only dynamic background workers can request notification" +msgstr "" + +#: postmaster/bgworker.c:890 +#, c-format +msgid "too many background workers" +msgstr "çok fazla background worker " + +#: postmaster/bgworker.c:891 +#, c-format +msgid "Up to %d background worker can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." +msgstr[0] "" +msgstr[1] "" + +#: postmaster/bgworker.c:895 +#, c-format +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." +msgstr "\"max_worker_processes\" yapılandırma parametresini artırmayı düşünün." + +#: postmaster/checkpointer.c:464 +#, c-format +msgid "checkpoints are occurring too frequently (%d second apart)" +msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" +msgstr[0] "checkpoint işlemi çok sık gerçekleşiyor (%d saniye aralıkla)" +msgstr[1] "checkpoint işlemi çok sık gerçekleşiyor (%d saniye aralıkla)" + +#: postmaster/checkpointer.c:468 +#, c-format +msgid "Consider increasing the configuration parameter \"max_wal_size\"." +msgstr "\"max_wal_size\" yapılandırma parametresini artırmayı düşünün." + +#: postmaster/checkpointer.c:1082 +#, c-format +msgid "checkpoint request failed" +msgstr "checkpoint isteği başarısız" + +#: postmaster/checkpointer.c:1083 +#, c-format +msgid "Consult recent messages in the server log for details." +msgstr "Ayrıntılar için sunucu günlük dosyasına bakın." + +#: postmaster/checkpointer.c:1278 +#, c-format +msgid "compacted fsync request queue from %d entries to %d entries" +msgstr "" + +#: postmaster/pgarch.c:148 +#, c-format +msgid "could not fork archiver: %m" +msgstr "archiver başlatılamadı: %m" + +#: postmaster/pgarch.c:456 +#, c-format +msgid "archive_mode enabled, yet archive_command is not set" +msgstr "archive_mode aktiftir, ancak archive_command ayarlanmadı" + +#: postmaster/pgarch.c:484 +#, c-format +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "\"%s\" write-ahead log dosyasının arşivlenmesi bir çok kez başarısız oldu, sonra tekrar denenecek" + +#: postmaster/pgarch.c:585 +#, c-format +msgid "archive command failed with exit code %d" +msgstr "arşiv komutu başarısız. Döndürülen kod: %d" + +#: postmaster/pgarch.c:587 postmaster/pgarch.c:597 postmaster/pgarch.c:604 postmaster/pgarch.c:610 postmaster/pgarch.c:619 +#, c-format +msgid "The failed archive command was: %s" +msgstr "Başarısız arşiv komuyu: %s" + +#: postmaster/pgarch.c:594 +#, c-format +msgid "archive command was terminated by exception 0x%X" +msgstr "arşiv süreç 0x%X exception tarafından sonlandırıldı" + +#: postmaster/pgarch.c:596 postmaster/postmaster.c:3567 +#, c-format +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgstr "Bu hex değerin tanımlaması için \"ntstatus.h\" C dahil etme dosyasına bakın." + +#: postmaster/pgarch.c:601 +#, c-format +msgid "archive command was terminated by signal %d: %s" +msgstr "arşiv komutu %d sinyali tarafından sonlandırıldı: %s" + +#: postmaster/pgarch.c:608 +#, c-format +msgid "archive command was terminated by signal %d" +msgstr "arşiv komutu %d sinyali tarafından sonlandırıldı" + +#: postmaster/pgarch.c:617 +#, c-format +msgid "archive command exited with unrecognized status %d" +msgstr "arşiv komutu beklenmeyen durum ile sonlandırıldı %d" + +#: postmaster/pgstat.c:395 +#, c-format +msgid "could not resolve \"localhost\": %s" +msgstr "\"localhost\" adresi çözümlenemedi: %s" + +#: postmaster/pgstat.c:418 +#, c-format +msgid "trying another address for the statistics collector" +msgstr "istatistik toplayıcı süreci için başka bir adres deneniyor" + +#: postmaster/pgstat.c:427 +#, c-format +msgid "could not create socket for statistics collector: %m" +msgstr "istatistik toplayıcı soket oluşturma hatası: %m" + +#: postmaster/pgstat.c:439 +#, c-format +msgid "could not bind socket for statistics collector: %m" +msgstr "istatistik toplayıcı soket bind hatası: %m" + +#: postmaster/pgstat.c:450 +#, c-format +msgid "could not get address of socket for statistics collector: %m" +msgstr "istatistik toplayıcı sürecinin soket adresi alınamadı: %m" + +#: postmaster/pgstat.c:466 +#, c-format +msgid "could not connect socket for statistics collector: %m" +msgstr "istatistik toplayıcı soket bağlama hatası: %m" + +#: postmaster/pgstat.c:487 +#, c-format +msgid "could not send test message on socket for statistics collector: %m" +msgstr "istatistik toplayıcı sürecine test mesajı gönderme hatası: %m" + +#: postmaster/pgstat.c:513 +#, c-format +msgid "select() failed in statistics collector: %m" +msgstr "istatistik toplayıcı sürecinde select() hatası: %m" + +#: postmaster/pgstat.c:528 +#, c-format +msgid "test message did not get through on socket for statistics collector" +msgstr "istatistik toplayıcı sürecine test mesajı gönderilemedi" + +#: postmaster/pgstat.c:543 +#, c-format +msgid "could not receive test message on socket for statistics collector: %m" +msgstr "istatistik toplayıcı süreci deneme mesajı alma hatası: %m" + +#: postmaster/pgstat.c:553 +#, c-format +msgid "incorrect test message transmission on socket for statistics collector" +msgstr "istatistik toplayıcı soket aracılığı ile mesaj gönderme hatası" + +#: postmaster/pgstat.c:576 +#, c-format +msgid "could not set statistics collector socket to nonblocking mode: %m" +msgstr "istatistik toplayıcı soketi nonblocking durumuna getirilemedi: %m" + +#: postmaster/pgstat.c:615 +#, c-format +msgid "disabling statistics collector for lack of working socket" +msgstr "çalışan socket olmadığından istatistik toplayıcı iptal edildi" + +#: postmaster/pgstat.c:762 +#, c-format +msgid "could not fork statistics collector: %m" +msgstr "istatistik toplayıcı başlatılamıyor: %m" + +#: postmaster/pgstat.c:1342 +#, c-format +msgid "unrecognized reset target: \"%s\"" +msgstr "bilinmeyen reset hedefi: \"%s\"" + +#: postmaster/pgstat.c:1343 +#, c-format +msgid "Target must be \"archiver\" or \"bgwriter\"." +msgstr "Hedef \"archiver\" veya \"bgwriter\" olmalıdır." + +#: postmaster/pgstat.c:4362 +#, c-format +msgid "could not read statistics message: %m" +msgstr "istatistik mesajı okunamadı: %m" + +#: postmaster/pgstat.c:4694 postmaster/pgstat.c:4851 +#, c-format +msgid "could not open temporary statistics file \"%s\": %m" +msgstr "geçici istatistik dosyası \"%s\" açılamıyor: %m" + +#: postmaster/pgstat.c:4761 postmaster/pgstat.c:4896 +#, c-format +msgid "could not write temporary statistics file \"%s\": %m" +msgstr "geçici istatistik dosyasına \"%s\" yazılamıyor: %m" + +#: postmaster/pgstat.c:4770 postmaster/pgstat.c:4905 +#, c-format +msgid "could not close temporary statistics file \"%s\": %m" +msgstr "geçici istatistik dosyası \"%s\" açılamıyor: %m" + +#: postmaster/pgstat.c:4778 postmaster/pgstat.c:4913 +#, c-format +msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" +msgstr "geçici istatistik dosyasının adı değiştirilemiyor eski: \"%s\" yeni: \"%s\": %m" + +#: postmaster/pgstat.c:5002 postmaster/pgstat.c:5208 postmaster/pgstat.c:5361 +#, c-format +msgid "could not open statistics file \"%s\": %m" +msgstr "istatistik dosyası \"%s\" açılamadı: %m" + +#: postmaster/pgstat.c:5014 postmaster/pgstat.c:5024 postmaster/pgstat.c:5045 postmaster/pgstat.c:5067 postmaster/pgstat.c:5082 postmaster/pgstat.c:5145 postmaster/pgstat.c:5220 postmaster/pgstat.c:5240 postmaster/pgstat.c:5258 postmaster/pgstat.c:5274 postmaster/pgstat.c:5292 postmaster/pgstat.c:5308 postmaster/pgstat.c:5373 postmaster/pgstat.c:5385 postmaster/pgstat.c:5397 +#: postmaster/pgstat.c:5422 postmaster/pgstat.c:5444 +#, c-format +msgid "corrupted statistics file \"%s\"" +msgstr "bozuk istatistik dosyası \"%s\"" + +#: postmaster/pgstat.c:5573 +#, c-format +msgid "using stale statistics instead of current ones because stats collector is not responding" +msgstr "istatistik toplayıcı (stats collector) cevap vermediği için güncelleri yerine eski istatistikler kullanılıyor " + +#: postmaster/pgstat.c:5900 +#, c-format +msgid "database hash table corrupted during cleanup --- abort" +msgstr "veritabanı hash tablosu temizleme sırasında bozulmuş --- iptal" + +#: postmaster/postmaster.c:717 +#, c-format +msgid "%s: invalid argument for option -f: \"%s\"\n" +msgstr "%s: -f seçeneği için geçersiz parametre: \"%s\"\n" + +#: postmaster/postmaster.c:803 +#, c-format +msgid "%s: invalid argument for option -t: \"%s\"\n" +msgstr "%s: -t seçeneği için geçersiz parametre: \"%s\"\n" + +#: postmaster/postmaster.c:854 +#, c-format +msgid "%s: invalid argument: \"%s\"\n" +msgstr "%s: geçersiz parametre: \"%s\"\n" + +#: postmaster/postmaster.c:896 +#, c-format +msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) ve max_wal_senders (%d) değerlerinin toplamı max_connections parametresinden (%d) küçük olmalıdır\n" + +#: postmaster/postmaster.c:903 +#, c-format +msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" +msgstr "wal_level \"minimal\" olduğu için WAL arşivlemesi etkinleştirilemiyor" + +#: postmaster/postmaster.c:906 +#, c-format +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL streaming (max_wal_senders > 0) wal_level parametresinin \"replica\" veya \"logical\" olmasını gerektirir" + +#: postmaster/postmaster.c:914 +#, c-format +msgid "%s: invalid datetoken tables, please fix\n" +msgstr "%s: datetoken tabloları bozuk, lütfen düzeltin\n" + +#: postmaster/postmaster.c:1028 postmaster/postmaster.c:1126 utils/init/miscinit.c:1555 +#, c-format +msgid "invalid list syntax in parameter \"%s\"" +msgstr "\"%s\" parametresinde geçersiz liste söz dizimi" + +#: postmaster/postmaster.c:1059 +#, c-format +msgid "could not create listen socket for \"%s\"" +msgstr "\"%s\" için dinleme soketi oluşturulamadı" + +#: postmaster/postmaster.c:1065 +#, c-format +msgid "could not create any TCP/IP sockets" +msgstr "hiç bir TCP/IP soketi oluşturulamadı" + +#: postmaster/postmaster.c:1148 +#, c-format +msgid "could not create Unix-domain socket in directory \"%s\"" +msgstr "\"%s\" dizininde Unix-domain soketi oluşturulamadı" + +#: postmaster/postmaster.c:1154 +#, c-format +msgid "could not create any Unix-domain sockets" +msgstr "hiç bir UNIX-domain soketi oluşturulamadı" + +#: postmaster/postmaster.c:1166 +#, c-format +msgid "no socket created for listening" +msgstr "dinleme için hiç soket oluşturulamadı" + +#: postmaster/postmaster.c:1206 +#, c-format +msgid "could not create I/O completion port for child queue" +msgstr "alt kuyruk için I/O completion port'u oluşturulamadı" + +#: postmaster/postmaster.c:1235 +#, fuzzy, c-format +#| msgid "%s: could not change permissions of directory \"%s\": %s\n" +msgid "%s: could not change permissions of external PID file \"%s\": %s\n" +msgstr "%s: \"%s\" dizininin erişim haklarını değiştirilemiyor: %s\n" + +#: postmaster/postmaster.c:1239 +#, c-format +msgid "%s: could not write external PID file \"%s\": %s\n" +msgstr "%s: harici PID dosyası \"%s\" yazılamadı: %s\n" + +#: postmaster/postmaster.c:1296 +#, c-format +msgid "ending log output to stderr" +msgstr "" + +#: postmaster/postmaster.c:1297 +#, c-format +msgid "Future log output will go to log destination \"%s\"." +msgstr "" + +#: postmaster/postmaster.c:1323 utils/init/postinit.c:214 +#, c-format +msgid "could not load pg_hba.conf" +msgstr "pg_hba.conf yüklenemedi" + +#: postmaster/postmaster.c:1349 +#, c-format +msgid "postmaster became multithreaded during startup" +msgstr "" + +#: postmaster/postmaster.c:1350 +#, c-format +msgid "Set the LC_ALL environment variable to a valid locale." +msgstr "" + +#: postmaster/postmaster.c:1455 +#, c-format +msgid "%s: could not locate matching postgres executable" +msgstr "%s: uygun postgres çalıştırma dosysı bulunamadı" + +#: postmaster/postmaster.c:1478 utils/misc/tzparser.c:341 +#, c-format +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "" + +#: postmaster/postmaster.c:1505 +#, c-format +msgid "" +"%s: could not find the database system\n" +"Expected to find it in the directory \"%s\",\n" +"but could not open file \"%s\": %s\n" +msgstr "" +"%s: veritabanı sistemi bulamamaktadır.\n" +"\"%s\" klasöründe arama yapılmıştır,\n" +"ancak \"%s\" dosyası bulunamamıştır: %s\n" + +#: postmaster/postmaster.c:1682 +#, c-format +msgid "select() failed in postmaster: %m" +msgstr "postmaster içinde select() başarısız: %m" + +#: postmaster/postmaster.c:1837 +#, c-format +msgid "performing immediate shutdown because data directory lock file is invalid" +msgstr "" + +#: postmaster/postmaster.c:1915 postmaster/postmaster.c:1946 +#, c-format +msgid "incomplete startup packet" +msgstr "başlatma paketi eksik" + +#: postmaster/postmaster.c:1927 +#, c-format +msgid "invalid length of startup packet" +msgstr "başlatma paketinin uzunluğu geçirsiz" + +#: postmaster/postmaster.c:1985 +#, c-format +msgid "failed to send SSL negotiation response: %m" +msgstr "SSL görüşme cevabı gönderme başarısız: %m" + +#: postmaster/postmaster.c:2011 +#, c-format +msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" +msgstr "frontend protokolü %u.%u desteklenememktedir: sunucunun desteklediği protokolleri %u.0 ila %u.%u arasında" + +#: postmaster/postmaster.c:2075 utils/misc/guc.c:6013 utils/misc/guc.c:6106 utils/misc/guc.c:7432 utils/misc/guc.c:10195 utils/misc/guc.c:10229 +#, c-format +msgid "invalid value for parameter \"%s\": \"%s\"" +msgstr "\"%s\" seçeneği için geçersiz değer: \"%s\"" + +#: postmaster/postmaster.c:2078 +#, c-format +msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." +msgstr "" + +#: postmaster/postmaster.c:2108 +#, c-format +msgid "invalid startup packet layout: expected terminator as last byte" +msgstr "geçersiz startup packet düzeni: son bayt bir sonlandırıcı olmalıdır" + +#: postmaster/postmaster.c:2146 +#, c-format +msgid "no PostgreSQL user name specified in startup packet" +msgstr "başlatma paketinde PostgreSQL kullanıcı adı belirtilmemiştir" + +#: postmaster/postmaster.c:2205 +#, c-format +msgid "the database system is starting up" +msgstr "veritabanı başlatılıyor" + +#: postmaster/postmaster.c:2210 +#, c-format +msgid "the database system is shutting down" +msgstr "veritabanı kapatılıyor" + +#: postmaster/postmaster.c:2215 +#, c-format +msgid "the database system is in recovery mode" +msgstr "veritabanı kurtarma modundadır" + +#: postmaster/postmaster.c:2220 storage/ipc/procarray.c:292 storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:346 +#, c-format +msgid "sorry, too many clients already" +msgstr "üzgünüm, istemci sayısı çok fazla" + +#: postmaster/postmaster.c:2310 +#, fuzzy, c-format +msgid "wrong key in cancel request for process %d" +msgstr "%d sürecinin iptal isteminde geçersiz anahtar" + +#: postmaster/postmaster.c:2318 +#, fuzzy, c-format +msgid "PID %d in cancel request did not match any process" +msgstr "%d sürecinin iptal isteminde geçersiz pid" + +#: postmaster/postmaster.c:2529 +#, c-format +msgid "received SIGHUP, reloading configuration files" +msgstr "SIGHUP sinyali alınmıştır, yapılandırma dosyaları yeniden okunuyor" + +#: postmaster/postmaster.c:2554 +#, fuzzy, c-format +#| msgid "pg_hba.conf not reloaded" +msgid "pg_hba.conf was not reloaded" +msgstr "pg_hba.conf yeniden yüklenmedi" + +#: postmaster/postmaster.c:2558 +#, fuzzy, c-format +#| msgid "pg_hba.conf not reloaded" +msgid "pg_ident.conf was not reloaded" +msgstr "pg_hba.conf yeniden yüklenmedi" + +#: postmaster/postmaster.c:2568 +#, fuzzy, c-format +#| msgid "text search configuration parameter \"%s\" not recognized" +msgid "SSL configuration was not reloaded" +msgstr "\"%s\"metin arama yapılandırma parametresi bulunamadı" + +#: postmaster/postmaster.c:2616 +#, c-format +msgid "received smart shutdown request" +msgstr "akıllı kapatma isteği alındı" + +#: postmaster/postmaster.c:2674 +#, c-format +msgid "received fast shutdown request" +msgstr "hızlı kapatma isteği alındı" + +#: postmaster/postmaster.c:2707 +#, c-format +msgid "aborting any active transactions" +msgstr "aktif transactionlar iptal ediliyor" + +#: postmaster/postmaster.c:2741 +#, c-format +msgid "received immediate shutdown request" +msgstr "immediate shutdown isteği alındı" + +#: postmaster/postmaster.c:2808 +#, fuzzy, c-format +#| msgid "shut down in recovery" +msgid "shutdown at recovery target" +msgstr "kurtarma modunda kapatma" + +#: postmaster/postmaster.c:2824 postmaster/postmaster.c:2847 +msgid "startup process" +msgstr "başlatma süreci" + +#: postmaster/postmaster.c:2827 +#, c-format +msgid "aborting startup due to startup process failure" +msgstr "başlatma süreci hatası nedeniyle başlatma süreci durdurulmuştır" + +#: postmaster/postmaster.c:2888 +#, c-format +msgid "database system is ready to accept connections" +msgstr "veritabanı sunucusu bağlantı kabul etmeye hazır" + +#: postmaster/postmaster.c:2909 +msgid "background writer process" +msgstr "background writer süreci" + +#: postmaster/postmaster.c:2963 +msgid "checkpointer process" +msgstr "checkpointer süreci" + +#: postmaster/postmaster.c:2979 +msgid "WAL writer process" +msgstr "WAL yazma süreci" + +#: postmaster/postmaster.c:2994 +msgid "WAL receiver process" +msgstr "WAL alıcı süreci" + +#: postmaster/postmaster.c:3009 +msgid "autovacuum launcher process" +msgstr "otomatik vacuum başlatma süreci" + +#: postmaster/postmaster.c:3024 +msgid "archiver process" +msgstr "arşivleyici süreci" + +#: postmaster/postmaster.c:3040 +msgid "statistics collector process" +msgstr "istatistik toplama süreci" + +#: postmaster/postmaster.c:3054 +msgid "system logger process" +msgstr "logger süreci" + +#: postmaster/postmaster.c:3116 +#, fuzzy, c-format +#| msgid "registering background worker \"%s\"" +msgid "background worker \"%s\"" +msgstr "\"%s\" background worker'ı kaydediliyor (register)" + +#: postmaster/postmaster.c:3200 postmaster/postmaster.c:3220 postmaster/postmaster.c:3227 postmaster/postmaster.c:3245 +msgid "server process" +msgstr "sunucu süreci" + +#: postmaster/postmaster.c:3299 +#, c-format +msgid "terminating any other active server processes" +msgstr "diğer aktif sunucu süreçleri durduruluyor" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3555 +#, c-format +msgid "%s (PID %d) exited with exit code %d" +msgstr "%s (PID %d) exit code %d ile sonlandı" + +#: postmaster/postmaster.c:3557 postmaster/postmaster.c:3568 postmaster/postmaster.c:3579 postmaster/postmaster.c:3588 postmaster/postmaster.c:3598 +#, c-format +msgid "Failed process was running: %s" +msgstr "Başarısız olan sürecin çalıştırdığı: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3565 +#, c-format +msgid "%s (PID %d) was terminated by exception 0x%X" +msgstr "%s (PID %d) 0x%X exception tarafından sonlandırıldı" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3575 +#, c-format +msgid "%s (PID %d) was terminated by signal %d: %s" +msgstr "%s (PID %d) %d sinyali tarafından sonlandırıldı: %s" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3586 +#, c-format +msgid "%s (PID %d) was terminated by signal %d" +msgstr "%s (PID %d) %d sinyali tarafından sonlandırıldı" + +#. translator: %s is a noun phrase describing a child process, such as +#. "server process" +#: postmaster/postmaster.c:3596 +#, c-format +msgid "%s (PID %d) exited with unrecognized status %d" +msgstr "%s (PID %d) tanınmayan status kodu ile sonlandırıldı %d" + +#: postmaster/postmaster.c:3783 +#, c-format +msgid "abnormal database system shutdown" +msgstr "veritabanı sistemi olağandışı kapandı" + +#: postmaster/postmaster.c:3823 +#, c-format +msgid "all server processes terminated; reinitializing" +msgstr "tüm sunucu süreçleri durduruldu; yeniden ilklendiriliyor" + +#: postmaster/postmaster.c:3993 postmaster/postmaster.c:5418 postmaster/postmaster.c:5782 +#, c-format +msgid "could not generate random cancel key" +msgstr "rasgele iptal anahtarı oluşturulamıyor" + +#: postmaster/postmaster.c:4047 +#, c-format +msgid "could not fork new process for connection: %m" +msgstr "bağlantı için yeni süreç başlatılamadı: %m" + +#: postmaster/postmaster.c:4089 +msgid "could not fork new process for connection: " +msgstr "bağlantı için yeni süreç başlatılamadı:" + +#: postmaster/postmaster.c:4203 +#, c-format +msgid "connection received: host=%s port=%s" +msgstr "bağlantı alındı: istemci=%s port=%s" + +#: postmaster/postmaster.c:4208 +#, c-format +msgid "connection received: host=%s" +msgstr "bağlantı alındı: istemci=%s" + +#: postmaster/postmaster.c:4493 +#, c-format +msgid "could not execute server process \"%s\": %m" +msgstr "\"%s\" sunucu süreci başlatma hatası: %m" + +#: postmaster/postmaster.c:4646 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "shared memory ayırmak için çok fazla sayıda deneme yapıldı, artık bırakılıyor" + +#: postmaster/postmaster.c:4647 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "Buna ASLR ya da antivirüs yazılımı sebep oluyor olabilir." + +#: postmaster/postmaster.c:4858 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "Alt süreçte SSl konfigürasyonu yüklenemiyor" + +#: postmaster/postmaster.c:4990 +#, c-format +msgid "Please report this to ." +msgstr "Bunu lütfen adresine bildiriniz." + +#: postmaster/postmaster.c:5077 +#, c-format +msgid "database system is ready to accept read only connections" +msgstr "veritabanı sunucusu salt okunur bağlantı kabul etmeye hazır" + +#: postmaster/postmaster.c:5346 +#, c-format +msgid "could not fork startup process: %m" +msgstr "başlatma süreci fork edilemedi: %m" + +#: postmaster/postmaster.c:5350 +#, c-format +msgid "could not fork background writer process: %m" +msgstr "background writer süreci başlatılamadı: %m" + +#: postmaster/postmaster.c:5354 +#, c-format +msgid "could not fork checkpointer process: %m" +msgstr "checkpointer süreci başlatılamadı: %m" + +#: postmaster/postmaster.c:5358 +#, c-format +msgid "could not fork WAL writer process: %m" +msgstr "WAL yazıcı süreci başlatılamadı: %m" + +#: postmaster/postmaster.c:5362 +#, c-format +msgid "could not fork WAL receiver process: %m" +msgstr "WAL alıcı süreci başlatılamadı: %m" + +#: postmaster/postmaster.c:5366 +#, c-format +msgid "could not fork process: %m" +msgstr "süreç başlatma hatası: %m" + +#: postmaster/postmaster.c:5553 postmaster/postmaster.c:5576 +#, c-format +msgid "database connection requirement not indicated during registration" +msgstr "kayıt sırasında belirtilmemiş veritabanı bağlantısı gereksinimi" + +#: postmaster/postmaster.c:5560 postmaster/postmaster.c:5583 +#, c-format +msgid "invalid processing mode in background worker" +msgstr "background worker'da geçersiz işleme kipi" + +#: postmaster/postmaster.c:5655 +#, c-format +msgid "starting background worker process \"%s\"" +msgstr "\"%s\" background worker süreci başlatılıyor" + +#: postmaster/postmaster.c:5667 +#, c-format +msgid "could not fork worker process: %m" +msgstr "worker süreci başlatılamadı: %m" + +#: postmaster/postmaster.c:6100 +#, c-format +msgid "could not duplicate socket %d for use in backend: error code %d" +msgstr "backend içinde kullanılacak duplicate socket %d oluşturulamadı: hata kodu %d" + +#: postmaster/postmaster.c:6132 +#, c-format +msgid "could not create inherited socket: error code %d\n" +msgstr "inherited socket oluşturulamıyor: hata kodu %d\n" + +#: postmaster/postmaster.c:6161 +#, c-format +msgid "could not open backend variables file \"%s\": %s\n" +msgstr "\"%s\" backend değişkenler dosyası açılamıyor: %s\n" + +#: postmaster/postmaster.c:6168 +#, c-format +msgid "could not read from backend variables file \"%s\": %s\n" +msgstr "\"%s\" backend parametreler dosyasından okunamıyor: %s\n" + +#: postmaster/postmaster.c:6177 +#, c-format +msgid "could not remove file \"%s\": %s\n" +msgstr "\"%s\" dosyası silinemedi: %s\n" + +#: postmaster/postmaster.c:6194 +#, c-format +msgid "could not map view of backend variables: error code %lu\n" +msgstr "backend değişkenleri map view hatası: hata kodu: %lu\n" + +#: postmaster/postmaster.c:6203 +#, c-format +msgid "could not unmap view of backend variables: error code %lu\n" +msgstr "backend değişkenleri unmap view hatası: hata kodu: %lu\n" + +#: postmaster/postmaster.c:6210 +#, c-format +msgid "could not close handle to backend parameter variables: error code %lu\n" +msgstr "backend parameter değişkenler tanıtıcısı kapatılamadı: hata kodu %lu\n" + +#: postmaster/postmaster.c:6371 +#, c-format +msgid "could not read exit code for process\n" +msgstr "Sürecin çıkış kodu okunamadı\n" + +#: postmaster/postmaster.c:6376 +#, c-format +msgid "could not post child completion status\n" +msgstr "alt süreç tamamlanma durumu gönderilemedi\n" + +#: postmaster/syslogger.c:470 postmaster/syslogger.c:1146 +#, c-format +msgid "could not read from logger pipe: %m" +msgstr "logger pipe'dan okunamadı: %m" + +#: postmaster/syslogger.c:520 +#, c-format +msgid "logger shutting down" +msgstr "loglama süreci kapatılıyor" + +#: postmaster/syslogger.c:564 postmaster/syslogger.c:578 +#, c-format +msgid "could not create pipe for syslog: %m" +msgstr "syslog için pipe oluşturulamadı: %m" + +#: postmaster/syslogger.c:629 +#, c-format +msgid "could not fork system logger: %m" +msgstr "sistem loglayıcı başlatma hatası: %m" + +#: postmaster/syslogger.c:665 +#, c-format +msgid "redirecting log output to logging collector process" +msgstr "log çıktısı logging collector sürecine yönlendiriliyor" + +#: postmaster/syslogger.c:666 +#, c-format +msgid "Future log output will appear in directory \"%s\"." +msgstr "Gelecekteki log çıktısı \"%s\" dizininde görünecek." + +#: postmaster/syslogger.c:674 +#, c-format +msgid "could not redirect stdout: %m" +msgstr "stdout yönlendirilmesi yapılamadı: %m" + +#: postmaster/syslogger.c:679 postmaster/syslogger.c:696 +#, c-format +msgid "could not redirect stderr: %m" +msgstr "stderr yönlendirilmesi yapılamadı: %m" + +#: postmaster/syslogger.c:1101 +#, c-format +msgid "could not write to log file: %s\n" +msgstr "log dosyası yazma hatası: %s\n" + +#: postmaster/syslogger.c:1218 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" log dosyası açılamadı: %m" + +#: postmaster/syslogger.c:1280 postmaster/syslogger.c:1330 +#, fuzzy, c-format +msgid "disabling automatic rotation (use SIGHUP to re-enable)" +msgstr "otomatik dönüşüm etkisiz (yeniden yetkilendirmek için SIGHUP kullanın)" + +#: regex/regc_pg_locale.c:262 +#, fuzzy, c-format +#| msgid "could not determine row description for function returning record" +msgid "could not determine which collation to use for regular expression" +msgstr "veri satırı döndüren fonksiyon için satır açıklaması bulunamadı" + +#: repl_gram.y:336 repl_gram.y:368 +#, c-format +msgid "invalid timeline %u" +msgstr "geçersiz zaman çizelgesi %u" + +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "geçersiz streaming başlama lokasyonu" + +#: repl_scanner.l:180 scan.l:683 +msgid "unterminated quoted string" +msgstr "sonuçlandırılmamış tırnakla sınırlandırılmış satır" + +#: replication/basebackup.c:343 +#, c-format +msgid "could not stat control file \"%s\": %m" +msgstr "kontrol dosyası \"%s\" durumu görüntülenemedi (stat): %m" + +#: replication/basebackup.c:450 +#, c-format +msgid "could not find any WAL files" +msgstr "hiç WAL dosyası bulunamadı" + +#: replication/basebackup.c:464 replication/basebackup.c:479 replication/basebackup.c:488 +#, c-format +msgid "could not find WAL file \"%s\"" +msgstr "\"%s\" WAL dosyası açılamadı" + +#: replication/basebackup.c:530 replication/basebackup.c:558 +#, c-format +msgid "unexpected WAL file size \"%s\"" +msgstr "beklenmeyen WAL dosya boyutu \"%s\"" + +#: replication/basebackup.c:544 replication/basebackup.c:1536 +#, c-format +msgid "base backup could not send data, aborting backup" +msgstr "base backup veri gönderemedi, yedek durduruluyor (abort)" + +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "%s toplam sağlama (checksum) doğrulama hatası" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "base backup sırasında sağlama toplamı (checksum) doğrulama hataları" + +#: replication/basebackup.c:664 replication/basebackup.c:673 replication/basebackup.c:682 replication/basebackup.c:691 replication/basebackup.c:700 replication/basebackup.c:711 replication/basebackup.c:728 replication/basebackup.c:737 +#, c-format +msgid "duplicate option \"%s\"" +msgstr "\"%s\" seçeneği, çift" + +#: replication/basebackup.c:717 utils/misc/guc.c:6023 +#, c-format +msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d değeri, \"%s\" parametresi için geçerli aralığın dışındadır (%d .. %d)" + +#: replication/basebackup.c:991 replication/basebackup.c:1161 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\" dosya ya da dizininin durumu görüntülenemedi (stat): %m" + +#: replication/basebackup.c:1316 +#, c-format +msgid "skipping special file \"%s\"" +msgstr "\"%s\" özel dosyası atlanıyor" + +#: replication/basebackup.c:1421 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "\"%2$s\" dosyasında geçersiz segment numarası %1$d" + +#: replication/basebackup.c:1440 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "" + +#: replication/basebackup.c:1484 replication/basebackup.c:1500 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "\"%s\" dosyasında fseek yapılamadı: %m" + +#: replication/basebackup.c:1492 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "\"%2$s\" dosyasının %1$d bloğu tekrar okunamadı (reread): %3$m" + +#: replication/basebackup.c:1516 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "\"%s\" dosyasında sağlama toplamı doğrulaması başarısız oldu, blok %d,: hesaplanan %X fakat beklenen %X" + +#: replication/basebackup.c:1523 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "" + +#: replication/basebackup.c:1581 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "\"%s\" dosyasında %d sağlama toplama hatası mevcut" + +#: replication/basebackup.c:1609 +#, c-format +msgid "file name too long for tar format: \"%s\"" +msgstr "tar biçimi için dosya adı çok uzun: \"%s\"" + +#: replication/basebackup.c:1614 +#, c-format +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgstr "tar biçimi için sembolik link hedefi çok uzun: dosya adı \"%s\", hedef \"%s\"" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:235 +#, c-format +msgid "invalid connection string syntax: %s" +msgstr "Geçersiz bağlantı dizesi (conn string) sözdizimi: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:259 +#, c-format +msgid "could not parse connection string: %s" +msgstr "bağlantı dizesi (conn string) ayrıştırılamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:332 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" +msgstr "Birincil (primary) sunucudan veritabanı system identifier ve timeline ID'si alınamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:343 replication/libpqwalreceiver/libpqwalreceiver.c:550 +#, c-format +msgid "invalid response from primary server" +msgstr "birincil (primary) sunucudan geçersiz yanıt" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:344 +#, c-format +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." +msgstr "Sistem belirlenemdi: %d satır ve %d alan alındı, beklenen %d satır ve %d veya daha fazla alan." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:410 replication/libpqwalreceiver/libpqwalreceiver.c:416 replication/libpqwalreceiver/libpqwalreceiver.c:441 +#, c-format +msgid "could not start WAL streaming: %s" +msgstr "WAL streaming başlatılamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:460 +#, c-format +msgid "could not send end-of-streaming message to primary: %s" +msgstr "Birincil (primary) sunucuya end-of-streaming mesajı gönderilemedi: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:482 +#, c-format +msgid "unexpected result set after end-of-streaming" +msgstr "end-of-streaming sonrası beklenmedik sonuç kümesi" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:496 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "streaming COPY kapatılırken hata oluştu: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:505 +#, c-format +msgid "error reading result of streaming command: %s" +msgstr "streaming komutunun sonucu okunurken hata oluştu: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:513 replication/libpqwalreceiver/libpqwalreceiver.c:741 +#, c-format +msgid "unexpected result after CommandComplete: %s" +msgstr "CommandComplete sonrası beklenmedik sonuç: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:539 +#, c-format +msgid "could not receive timeline history file from the primary server: %s" +msgstr "birincil (primary) sunucudan timeline history dosyası alınamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:551 +#, c-format +msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." +msgstr "2 alanlı bir satır bekleniyordu, %d satır %d tane alanla geldi." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:705 replication/libpqwalreceiver/libpqwalreceiver.c:756 replication/libpqwalreceiver/libpqwalreceiver.c:762 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "Sunucudan WAL stream alınamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:781 +#, c-format +msgid "could not send data to WAL stream: %s" +msgstr "WAL stream'ine veri gönderilemedi: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:830 +#, c-format +msgid "could not create replication slot \"%s\": %s" +msgstr "\"%s\" replication slot'u oluşturulamadı: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:864 +#, c-format +msgid "invalid query response" +msgstr "geçersiz sorgu cevabı" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:865 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "%d alan bekleniyordu, %d alan geldi." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:934 +#, c-format +msgid "the query interface requires a database connection" +msgstr "sorgu arabirimi (query interface) bir veritabanı bağlantısı gerektirir" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:965 +msgid "empty query" +msgstr "boş sorgu" + +#: replication/logical/launcher.c:310 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "\"%s\" aboneliği için mantıksal repliksyon worker'ı başlatılıyor" + +#: replication/logical/launcher.c:317 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "" + +#: replication/logical/launcher.c:397 +#, c-format +msgid "out of logical replication worker slots" +msgstr "" + +#: replication/logical/launcher.c:398 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "max_logical_replication_workers değerini artırmanız gerekebilir." + +#: replication/logical/launcher.c:453 +#, c-format +msgid "out of background worker slots" +msgstr "background worker slot'ları dışında " + +#: replication/logical/launcher.c:454 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "max_worker_processes değerini artırmanız gerekebilir." + +#: replication/logical/launcher.c:661 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "" + +#: replication/logical/launcher.c:670 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "" + +#: replication/logical/launcher.c:988 +#, c-format +msgid "logical replication launcher started" +msgstr "mantıksal replikasyon başlatma süreci çalıştırıldı" + +#: replication/logical/logical.c:90 +#, c-format +msgid "logical decoding requires wal_level >= logical" +msgstr "mantıksal kod çözme wal_level >= logical gerektirir" + +#: replication/logical/logical.c:95 +#, c-format +msgid "logical decoding requires a database connection" +msgstr "mantıksal kod çözme bir veritabanı bağlantısı gerektirir" + +#: replication/logical/logical.c:113 +#, c-format +msgid "logical decoding cannot be used while in recovery" +msgstr "kurtarma sırasında mantıksal kod çözme kullanılamaz" + +#: replication/logical/logical.c:255 replication/logical/logical.c:386 +#, c-format +msgid "cannot use physical replication slot for logical decoding" +msgstr "fiziksel replikasyon slot'u mantıksal kod çözme için kullanılamaz" + +#: replication/logical/logical.c:260 replication/logical/logical.c:391 +#, c-format +msgid "replication slot \"%s\" was not created in this database" +msgstr "\"%s\" replikasyon slot'u bu veritabanında oluşturulumamış" + +#: replication/logical/logical.c:267 +#, c-format +msgid "cannot create logical replication slot in transaction that has performed writes" +msgstr "" + +#: replication/logical/logical.c:431 +#, c-format +msgid "starting logical decoding for slot \"%s\"" +msgstr "\"%s\" slot'u için mantıksal kod çözme başlatılıyor" + +#: replication/logical/logical.c:433 +#, c-format +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "" + +#: replication/logical/logical.c:583 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgstr "" + +#: replication/logical/logical.c:590 +#, c-format +msgid "slot \"%s\", output plugin \"%s\", in the %s callback" +msgstr "" + +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:35 +#, c-format +msgid "must be superuser or replication role to use replication slots" +msgstr "replikasyon slot'larını kullanmak için superuser veya replikasyon rolü olmalısınız" + +#: replication/logical/logicalfuncs.c:153 +#, c-format +msgid "slot name must not be null" +msgstr "slot adı null olmamalı" + +#: replication/logical/logicalfuncs.c:169 +#, c-format +msgid "options array must not be null" +msgstr "seçenekler dizisi (optionns array) null olmamalı" + +#: replication/logical/logicalfuncs.c:200 +#, c-format +msgid "array must be one-dimensional" +msgstr "dizi (array) tek boyutlu olmalıdır" + +#: replication/logical/logicalfuncs.c:206 +#, c-format +msgid "array must not contain nulls" +msgstr "array null içermemeli" + +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2310 utils/adt/jsonb.c:1269 +#, c-format +msgid "array must have even number of elements" +msgstr "dizinin (array) çift sayıda elemanı olmalı" + +#: replication/logical/logicalfuncs.c:269 +#, c-format +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" +msgstr "" + +#: replication/logical/origin.c:185 +#, c-format +msgid "only superusers can query or manipulate replication origins" +msgstr "replikasyon orijinlerini sadece superuser'lar sorgulayabilir ya da değiştirebilir" + +#: replication/logical/origin.c:190 +#, c-format +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" +msgstr "max_replication_slot = 0 iken replikasyon orijini sorgulanamaz ve değiştirilemez" + +#: replication/logical/origin.c:195 +#, c-format +msgid "cannot manipulate replication origins during recovery" +msgstr "kurtarma sırasında replikasyon orijinleri değiştirilemez" + +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "\"%s\" replikasyon orijini mevcut değil" + +#: replication/logical/origin.c:321 +#, c-format +msgid "could not find free replication origin OID" +msgstr "serbest replikasyon orijini OID'si bulunamadı" + +#: replication/logical/origin.c:369 +#, c-format +msgid "could not drop replication origin with OID %d, in use by PID %d" +msgstr "%d OID'li replikasyon orijini silinemedi, %d PID tarafından kullanılıyor " + +#: replication/logical/origin.c:461 +#, c-format +msgid "replication origin with OID %u does not exist" +msgstr "%u OID'li replikasyon orijini mevcut değil" + +#: replication/logical/origin.c:725 +#, c-format +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "replikasyon kontrol noktası (checkpoint) yanlış magic %2$u yerine %1$u " + +#: replication/logical/origin.c:757 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%1$s\" dosyası okuma hatası: %3$zu nun %2$d si okundu" + +#: replication/logical/origin.c:766 +#, c-format +msgid "could not find free replication state, increase max_replication_slots" +msgstr "" + +#: replication/logical/origin.c:784 +#, c-format +msgid "replication slot checkpoint has wrong checksum %u, expected %u" +msgstr "replikasyon slotu kontrol noktasının sağlama toplamı %u yanlış, beklenen %u" + +#: replication/logical/origin.c:908 +#, c-format +msgid "replication origin with OID %d is already active for PID %d" +msgstr "" + +#: replication/logical/origin.c:919 replication/logical/origin.c:1106 +#, c-format +msgid "could not find free replication state slot for replication origin with OID %u" +msgstr "%u OID'li replikasyon orijini için serbest replikasyon durum slot'u bulunamadı" + +#: replication/logical/origin.c:921 replication/logical/origin.c:1108 replication/slot.c:1559 +#, c-format +msgid "Increase max_replication_slots and try again." +msgstr "max_replication_slots değerini artırıp yeniden deneyin." + +#: replication/logical/origin.c:1065 +#, c-format +msgid "cannot setup replication origin when one is already setup" +msgstr "zaten bir replikasyon orijini ayarlanmışsa başka bir tane ayarlanamaz" + +#: replication/logical/origin.c:1094 +#, c-format +msgid "replication identifier %d is already active for PID %d" +msgstr "%d replikasyon tanımlayıcısı zaten %d PID için aktif" + +#: replication/logical/origin.c:1145 replication/logical/origin.c:1343 replication/logical/origin.c:1363 +#, c-format +msgid "no replication origin is configured" +msgstr "yapılandırılmış bir replikasyon orijini yok" + +#: replication/logical/relation.c:255 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "\"%s.%s\" mantıksal replikasyon hedef nesnesi mevcut değil" + +#: replication/logical/relation.c:297 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "" + +#: replication/logical/reorderbuffer.c:2503 +#, c-format +msgid "could not write to data file for XID %u: %m" +msgstr "%u XID için veri dosyasına yazılamadı: %m" + +#: replication/logical/reorderbuffer.c:2596 replication/logical/reorderbuffer.c:2618 +#, fuzzy, c-format +#| msgid "could not read from control file: %m" +msgid "could not read from reorderbuffer spill file: %m" +msgstr "kontrol dosyasından okuma hatası: %m" + +#: replication/logical/reorderbuffer.c:2600 replication/logical/reorderbuffer.c:2622 +#, fuzzy, c-format +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloku okunamıyor: %6$d bayttan sadece %5$d bayt okundu" + +#: replication/logical/reorderbuffer.c:2845 +#, fuzzy, c-format +#| msgid "could not read file \"%s\", read %d of %d: %m" +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgstr "\"%1$s\" dosyası okuma hatası, %3$d nin %2$d si okundu : %4$m" + +#: replication/logical/reorderbuffer.c:3311 +#, c-format +msgid "could not read from file \"%s\": read %d instead of %d bytes" +msgstr "\"%1$s\" dosyası okunamadı: %3$d bayttan sadece %2$d bayt okundu" + +#: replication/logical/snapbuild.c:612 +#, c-format +msgid "initial slot snapshot too large" +msgstr "" + +#: replication/logical/snapbuild.c:664 +#, c-format +msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgstr[0] "" +msgstr[1] "" + +#: replication/logical/snapbuild.c:1269 replication/logical/snapbuild.c:1362 replication/logical/snapbuild.c:1872 +#, c-format +msgid "logical decoding found consistent point at %X/%X" +msgstr "" + +#: replication/logical/snapbuild.c:1271 +#, c-format +msgid "There are no running transactions." +msgstr "Çalışan işlem (transaction ) yok." + +#: replication/logical/snapbuild.c:1313 +#, c-format +msgid "logical decoding found initial starting point at %X/%X" +msgstr "" + +#: replication/logical/snapbuild.c:1315 replication/logical/snapbuild.c:1339 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "" + +#: replication/logical/snapbuild.c:1337 +#, c-format +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "" + +#: replication/logical/snapbuild.c:1364 +#, c-format +msgid "There are no old transactions anymore." +msgstr "Artık hiç eski işlem (transaction) yok." + +#: replication/logical/snapbuild.c:1736 replication/logical/snapbuild.c:1767 replication/logical/snapbuild.c:1787 replication/logical/snapbuild.c:1806 +#, c-format +msgid "could not read file \"%s\", read %d of %d: %m" +msgstr "\"%1$s\" dosyası okuma hatası, %3$d nin %2$d si okundu : %4$m" + +#: replication/logical/snapbuild.c:1742 +#, fuzzy, c-format +#| msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%s\" arşiv dosyası yanlış boyuta sahip: %lu yerine %lu olmalıydı." + +#: replication/logical/snapbuild.c:1747 +#, fuzzy, c-format +#| msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" +msgstr "\"%s\" arşiv dosyası yanlış boyuta sahip: %lu yerine %lu olmalıydı." + +#: replication/logical/snapbuild.c:1819 +#, c-format +msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" +msgstr "" + +#: replication/logical/snapbuild.c:1874 +#, c-format +msgid "Logical decoding will begin using saved snapshot." +msgstr "" + +#: replication/logical/snapbuild.c:1946 +#, c-format +msgid "could not parse file name \"%s\"" +msgstr "\"%s\" dosya adı ayrıştırılamadı" + +#: replication/logical/tablesync.c:138 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "" + +#: replication/logical/tablesync.c:685 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "\"%s.%s\" tablosu için yayıncıdan (publisher) tablo bilgisi alınamadı: %s" + +#: replication/logical/tablesync.c:691 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "\"%s.%s\" tablosu yayıncıda (publisher) bulunamadı" + +#: replication/logical/tablesync.c:721 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "\"%s.%s\" tablosu için tablo bilgisi alınamadı: %s" + +#: replication/logical/tablesync.c:791 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "\"%s.%s\" tablosu için ilk içerik kopyalaması başlatılamadı: %s" + +#: replication/logical/tablesync.c:904 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "tablo kopyalama yayıncı üzerinde işlem (transaction) başlatamadı" + +#: replication/logical/tablesync.c:926 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "tablo kopyalama yayıncı üzerinde işlem (transaction) tamamlayamadı" + +#: replication/logical/worker.c:307 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "" + +#: replication/logical/worker.c:528 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "" + +#: replication/logical/worker.c:661 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "" + +#: replication/logical/worker.c:668 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "" + +#: replication/logical/worker.c:1007 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "geçersiz mantıksal replikasyon mesaj tipi \"%c\"" + +#: replication/logical/worker.c:1148 +#, c-format +msgid "data stream from publisher has ended" +msgstr "yayıncıdan (publisher) veri akışı sona erdi" + +#: replication/logical/worker.c:1307 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "zamanaşımı nedeniyle mantıksal replikasyon worker sonlandırılıyor" + +#: replication/logical/worker.c:1455 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "" + +#: replication/logical/worker.c:1469 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "" + +#: replication/logical/worker.c:1483 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "" + +#: replication/logical/worker.c:1497 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "" + +#: replication/logical/worker.c:1514 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "" + +#: replication/logical/worker.c:1528 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "" + +#: replication/logical/worker.c:1631 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "" + +#: replication/logical/worker.c:1643 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "" + +#: replication/logical/worker.c:1661 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "" + +#: replication/logical/worker.c:1665 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "" + +#: replication/logical/worker.c:1705 +#, c-format +msgid "subscription has no replication slot set" +msgstr "abonelik için herhangi bir replikasyon slot kümesi tanımlanmamış" + +#: replication/pgoutput/pgoutput.c:117 +#, c-format +msgid "invalid proto_version" +msgstr "geçersiz proto_version" + +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\" aralık dışındadır" + +#: replication/pgoutput/pgoutput.c:139 +#, c-format +msgid "invalid publication_names syntax" +msgstr "geçersiz publication_names sözdizimi" + +#: replication/pgoutput/pgoutput.c:181 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "istemci, proto_version=%d gönderdi fakat desteklenen protokol %d veya daha altıdır" + +#: replication/pgoutput/pgoutput.c:187 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "istemci, proto_version=%d gönderdi fakat desteklenen protokol %d veya daha üstüdür" + +#: replication/pgoutput/pgoutput.c:193 +#, c-format +msgid "publication_names parameter missing" +msgstr "publication_names parametresi eksik" + +#: replication/slot.c:182 +#, c-format +msgid "replication slot name \"%s\" is too short" +msgstr "\"%s\" replikasyon slot adı çok kısa" + +#: replication/slot.c:191 +#, c-format +msgid "replication slot name \"%s\" is too long" +msgstr "\"%s\" replikasyon slot adı çok uzun" + +#: replication/slot.c:204 +#, c-format +msgid "replication slot name \"%s\" contains invalid character" +msgstr "\"%s\" replikasyon slot adı geçersiz karakter içeriyor" + +#: replication/slot.c:206 +#, c-format +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." +msgstr "Replikasyon slot adları sadece küçük harf, sayı ve alt çizgi karakteri içerebilir." + +#: replication/slot.c:253 +#, c-format +msgid "replication slot \"%s\" already exists" +msgstr "\"%s\" replikasyon slot'u zaten mevcut" + +#: replication/slot.c:263 +#, c-format +msgid "all replication slots are in use" +msgstr "bütün replikasyon slot'ları kullanımda" + +#: replication/slot.c:264 +#, c-format +msgid "Free one or increase max_replication_slots." +msgstr "Bir slotu boşaltın ya da max_replication_slots değerini artırın." + +#: replication/slot.c:387 +#, c-format +msgid "replication slot \"%s\" does not exist" +msgstr "\"%s\" replikasyon slot'u mevcut değil" + +#: replication/slot.c:398 replication/slot.c:948 +#, c-format +msgid "replication slot \"%s\" is active for PID %d" +msgstr "PID %2$d için \"%1$s\" replikasyon slot'u aktif" + +#: replication/slot.c:632 replication/slot.c:1141 replication/slot.c:1495 +#, c-format +msgid "could not remove directory \"%s\"" +msgstr "\"%s\" dizini silinemedi" + +#: replication/slot.c:983 +#, c-format +msgid "replication slots can only be used if max_replication_slots > 0" +msgstr "replikasyon slot'u kullanabilmek için max_replication_slots > 0 olmalı" + +#: replication/slot.c:988 +#, c-format +msgid "replication slots can only be used if wal_level >= replica" +msgstr "replikasyon slot'u kullanabilmek için wal_level >= replica olmalı" + +#: replication/slot.c:1427 replication/slot.c:1467 +#, c-format +msgid "could not read file \"%s\", read %d of %u: %m" +msgstr "\"%1$s\" dosyası okuma hatası, %3$u 'nun %2$d si okundu: %4$m" + +#: replication/slot.c:1436 +#, c-format +msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" +msgstr "\"%1$s\" replikasyon slot dosyası yanlış magic numarasına sahip: %3$u yerine %2$u olmalıydı." + +#: replication/slot.c:1443 +#, c-format +msgid "replication slot file \"%s\" has unsupported version %u" +msgstr "\"%s\" replikasyon slot dosyası desteklenmeyen sürüme sahip %u" + +#: replication/slot.c:1450 +#, c-format +msgid "replication slot file \"%s\" has corrupted length %u" +msgstr "\"%s\" replikasyon slot dosyasınun uzunluğu bozuk %u" + +#: replication/slot.c:1482 +#, c-format +msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" +msgstr "\"%s\" replikasyon slot dosyasında sağlama toplamı (checksum) uyuşmazlığı: %u yerine %u olmalıydı" + +#: replication/slot.c:1516 +#, fuzzy, c-format +#| msgid "logical decoding requires wal_level >= logical" +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "mantıksal kod çözme wal_level >= logical gerektirir" + +#: replication/slot.c:1518 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "" + +#: replication/slot.c:1522 +#, fuzzy, c-format +#| msgid "replication slots can only be used if wal_level >= replica" +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "replikasyon slot'u kullanabilmek için wal_level >= replica olmalı" + +#: replication/slot.c:1524 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "" + +#: replication/slot.c:1558 +#, c-format +msgid "too many replication slots active before shutdown" +msgstr "kapatma öncesinde çok fazla aktif replikasyon slot'u var" + +#: replication/slotfuncs.c:490 +#, c-format +msgid "invalid target wal lsn" +msgstr "geçersiz hedef wal lsn'i" + +#: replication/slotfuncs.c:512 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "" + +#: replication/slotfuncs.c:528 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "" + +#: replication/syncrep.c:246 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" +msgstr "yönetici talimatı doğrultusunda senkron replikasyon için bekleme iptal ediliyor ve bağlantı sonlandırılıyor" + +#: replication/syncrep.c:247 replication/syncrep.c:264 +#, c-format +msgid "The transaction has already committed locally, but might not have been replicated to the standby." +msgstr "İşlem (transaction) yerel olarak commit edildi, fakat henüz yedek sunucuya (standby) replike edilmemiş olabilir." + +#: replication/syncrep.c:263 +#, c-format +msgid "canceling wait for synchronous replication due to user request" +msgstr "kullanıcı isteği ile senkron replikasyon için bekleme iptal edildi" + +#: replication/syncrep.c:397 +#, c-format +msgid "standby \"%s\" now has synchronous standby priority %u" +msgstr "" + +#: replication/syncrep.c:460 +#, c-format +msgid "standby \"%s\" is now a synchronous standby with priority %u" +msgstr "" + +#: replication/syncrep.c:464 +#, c-format +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "" + +#: replication/syncrep.c:1164 +#, c-format +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names ayrıştırıcısı başarısız oldu" + +#: replication/syncrep.c:1170 +#, c-format +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "senkron yedeklerin sayısı (%d) sıfırdan büyük olmalı" + +#: replication/walreceiver.c:169 +#, c-format +msgid "terminating walreceiver process due to administrator command" +msgstr "yönetici talimatı doğrultusunda walreceiver süreci sonlandırılıyor" + +#: replication/walreceiver.c:309 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "birincil (primary) sunucuya bağlanılamadı: %s" + +#: replication/walreceiver.c:359 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "veritabanı sistem tanımlayıcı (identifier) birincil (primary) ve yedek (standby) arasında farklılık gösteriyor" + +#: replication/walreceiver.c:360 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "Birincil olanın tanımlayıcısı %s, yedeğin tanımlayıcısı %s." + +#: replication/walreceiver.c:371 +#, fuzzy, c-format +msgid "highest timeline %u of the primary is behind recovery timeline %u" +msgstr "talep edilmiş timeline %u veritabanı sistem timeline %u için geçerli bir timeline değildir" + +#: replication/walreceiver.c:407 +#, c-format +msgid "started streaming WAL from primary at %X/%X on timeline %u" +msgstr "" + +#: replication/walreceiver.c:412 +#, c-format +msgid "restarted WAL streaming at %X/%X on timeline %u" +msgstr "%3$u zaman çielgesinde %1$X/%2$X konumunda WAL streaming yeniden başlatıldı" + +#: replication/walreceiver.c:441 +#, c-format +msgid "cannot continue WAL streaming, recovery has already ended" +msgstr "WAL streaming devam edemiyor, kurtarma zaten sona erdi" + +#: replication/walreceiver.c:478 +#, c-format +msgid "replication terminated by primary server" +msgstr "replikasyon birincil sunucu tarafından sonlandırıldı" + +#: replication/walreceiver.c:479 +#, c-format +msgid "End of WAL reached on timeline %u at %X/%X." +msgstr "%u zaman çizelgesinde %X/%X konumunda WAL sonuna ulaşıldı." + +#: replication/walreceiver.c:574 +#, c-format +msgid "terminating walreceiver due to timeout" +msgstr "zamanaşımı dolayısıyla walreceiver süreci sonlandırılıyor" + +#: replication/walreceiver.c:614 +#, c-format +msgid "primary server contains no more WAL on requested timeline %u" +msgstr "birincil sunucu talep edilen %u zaman çizelgesinde başka WAL bulundurmuyor" + +#: replication/walreceiver.c:629 replication/walreceiver.c:982 +#, c-format +msgid "could not close log segment %s: %m" +msgstr "%s log segmenti kapatılamadı: %m" + +#: replication/walreceiver.c:754 +#, c-format +msgid "fetching timeline history file for timeline %u from primary server" +msgstr "birincil sunucudan %u zaman çizelgesi için zaman çizelgesi geçmiş dosyası alınıyor" + +#: replication/walreceiver.c:1036 +#, c-format +msgid "could not write to log segment %s at offset %u, length %lu: %m" +msgstr "%s kayıt (log) segmentine yazılamadı, offset %u, uzunluk %lu: %m" + +#: replication/walsender.c:494 +#, c-format +msgid "could not seek to beginning of file \"%s\": %m" +msgstr "\"%s\" dosyasının başlangıcına ilerleme hatası: %m" + +#: replication/walsender.c:535 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM, START_REPLICATION öncesinde çalıştırılmamış" + +#: replication/walsender.c:552 +#, c-format +msgid "cannot use a logical replication slot for physical replication" +msgstr "mantıksal replikasyon slot'u fiziksel replikasyon için kullanılamaz" + +#: replication/walsender.c:615 +#, c-format +msgid "requested starting point %X/%X on timeline %u is not in this server's history" +msgstr "" + +#: replication/walsender.c:619 +#, c-format +msgid "This server's history forked from timeline %u at %X/%X." +msgstr "" + +#: replication/walsender.c:664 +#, c-format +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" +msgstr "" + +#: replication/walsender.c:893 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT must not be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT bir transaction içinde çağırılmamalıdır" + +#: replication/walsender.c:902 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called inside a transaction" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT bir transaction içinde çağırılmalıdır" + +#: replication/walsender.c:907 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" +msgstr "" + +#: replication/walsender.c:912 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called before any query" +msgstr "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT bir sorgudan önce çağırılmalıdır" + +#: replication/walsender.c:917 +#, c-format +msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must not be called in a subtransaction" +msgstr " CREATE_REPLICATION_SLOT ... USE_SNAPSHOT bir subtransaction içinde çağırılmamalıdır" + +#: replication/walsender.c:1063 +#, c-format +msgid "terminating walsender process after promotion" +msgstr "yükseltme (promotion) sonrası walsender süreci sonlandırılıyor" + +#: replication/walsender.c:1448 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "WAL sender durma modunda iken yeni komutlar çalıştırılamaz" + +#: replication/walsender.c:1481 +#, c-format +msgid "received replication command: %s" +msgstr "replikasyon komutu alındı: %s" + +#: replication/walsender.c:1497 tcop/fastpath.c:279 tcop/postgres.c:1033 tcop/postgres.c:1357 tcop/postgres.c:1617 tcop/postgres.c:2023 tcop/postgres.c:2396 tcop/postgres.c:2475 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "geçerli transaction durduruldu, transaction blokunun sonuna kadar komutlar yok sayılacak" + +#: replication/walsender.c:1562 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "" + +#: replication/walsender.c:1610 replication/walsender.c:1626 +#, c-format +msgid "unexpected EOF on standby connection" +msgstr "yedek (standby) bağlantısında beklenmeyen EOF" + +#: replication/walsender.c:1640 +#, c-format +msgid "unexpected standby message type \"%c\", after receiving CopyDone" +msgstr "" + +#: replication/walsender.c:1678 +#, c-format +msgid "invalid standby message type \"%c\"" +msgstr "geçersiz yedek (standby) mesaj tipi \"%c\"" + +#: replication/walsender.c:1719 +#, c-format +msgid "unexpected message type \"%c\"" +msgstr "beklenmeyen mesaj tipi \"%c\"" + +#: replication/walsender.c:2097 +#, c-format +msgid "terminating walsender process due to replication timeout" +msgstr "replikasyon zamanaşımı dolayısıyla walsender süreci sonlandırılıyor" + +#: replication/walsender.c:2181 +#, c-format +msgid "\"%s\" has now caught up with upstream server" +msgstr "" + +#: replication/walsender.c:2290 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "talep edilen yedek (standby) bağlantı sayısı max_wal_senders değerini (şu anda %d) aşmakta" + +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:980 +#, c-format +msgid "rule \"%s\" for relation \"%s\" already exists" +msgstr "\"%s\" kuralı(rule), \"%s\" nesnesi için zaten mevcut" + +#: rewrite/rewriteDefine.c:296 +#, c-format +msgid "rule actions on OLD are not implemented" +msgstr "OLD için rule eylemleri implement edilmemiş" + +#: rewrite/rewriteDefine.c:297 +#, c-format +msgid "Use views or triggers instead." +msgstr "Bunun yerine view veya trigger kullanın." + +#: rewrite/rewriteDefine.c:301 +#, c-format +msgid "rule actions on NEW are not implemented" +msgstr "NEW için rule eylemleri implement edilmemiş" + +#: rewrite/rewriteDefine.c:302 +#, c-format +msgid "Use triggers instead." +msgstr "Bunun yerine lütfen triggerleri kullanın." + +#: rewrite/rewriteDefine.c:315 +#, c-format +msgid "INSTEAD NOTHING rules on SELECT are not implemented" +msgstr "SELECT üzerinde INSTEAD NOTHING rule implement edilmemiştir" + +#: rewrite/rewriteDefine.c:316 +#, c-format +msgid "Use views instead." +msgstr "Lütfen yerine viewları kullanın" + +#: rewrite/rewriteDefine.c:324 +#, c-format +msgid "multiple actions for rules on SELECT are not implemented" +msgstr "SELECT rule'ler için birden fazla eylem tanımlanma implement edilmemiştir" + +#: rewrite/rewriteDefine.c:334 +#, c-format +msgid "rules on SELECT must have action INSTEAD SELECT" +msgstr "SELECT rule tanımları INSTEAD SELECT öğesini taşımak zorundadır" + +#: rewrite/rewriteDefine.c:342 +#, c-format +msgid "rules on SELECT must not contain data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteDefine.c:350 +#, c-format +msgid "event qualifications are not implemented for rules on SELECT" +msgstr "SELECT rule'ler için olay tanımları implement edilmemiştir" + +#: rewrite/rewriteDefine.c:377 +#, c-format +msgid "\"%s\" is already a view" +msgstr "\"%s\" zanten bir view'dur" + +#: rewrite/rewriteDefine.c:401 +#, c-format +msgid "view rule for \"%s\" must be named \"%s\"" +msgstr "rule \"%s\" için view'nun adını \"%s\" olarak değiştirilmelidir" + +#: rewrite/rewriteDefine.c:428 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "\"%s\" bölümlenmiş tablosu bir görünüme dönüştürülemez" + +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "\"%s\" bölümü (partition) bir görünüme dönüştürülemez" + +#: rewrite/rewriteDefine.c:442 +#, c-format +msgid "could not convert table \"%s\" to a view because it is not empty" +msgstr "\"%s\" tablosu boş olmadığı için vew'a çevirilemedi" + +#: rewrite/rewriteDefine.c:450 +#, c-format +msgid "could not convert table \"%s\" to a view because it has triggers" +msgstr "\"%s\" tablosuna bağlı trigger bulunduğu için vew'a çevirilemedi" + +#: rewrite/rewriteDefine.c:452 +#, c-format +msgid "In particular, the table cannot be involved in any foreign key relationships." +msgstr "Özellikle, tablo, foreign key ilişkilerinde kullanılamaz." + +#: rewrite/rewriteDefine.c:457 +#, c-format +msgid "could not convert table \"%s\" to a view because it has indexes" +msgstr "\"%s\" tablosuna bağlı index bulunduğu için vew'a çevirilemedi" + +#: rewrite/rewriteDefine.c:463 +#, c-format +msgid "could not convert table \"%s\" to a view because it has child tables" +msgstr "\"%s\" tablosuna bağlı çöcuk tabloları bulunduğu için vew'a çevirilemedi" + +#: rewrite/rewriteDefine.c:469 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security enabled" +msgstr "satır güvenliği etkin olduğundan \"%s\" tablosu görünüme (view) çevirilemedi" + +#: rewrite/rewriteDefine.c:475 +#, c-format +msgid "could not convert table \"%s\" to a view because it has row security policies" +msgstr "satır güvenlik politikaları olduğundan \"%s\" tablosu görünüme (view) çevirilemedi" + +#: rewrite/rewriteDefine.c:502 +#, c-format +msgid "cannot have multiple RETURNING lists in a rule" +msgstr "bir rule içinde birden fazla RETURNING listesi olamaz" + +#: rewrite/rewriteDefine.c:507 +#, c-format +msgid "RETURNING lists are not supported in conditional rules" +msgstr "şartlı rule içinde RETURNING listeleri kullanılamaz" + +#: rewrite/rewriteDefine.c:511 +#, c-format +msgid "RETURNING lists are not supported in non-INSTEAD rules" +msgstr "non-INSTEAD rule içinde RETURNING listeleri kullanılamaz" + +#: rewrite/rewriteDefine.c:675 +#, c-format +msgid "SELECT rule's target list has too many entries" +msgstr "SELECT rule'un hedef öğesi listesinin öğe sayısı fazladır" + +#: rewrite/rewriteDefine.c:676 +#, c-format +msgid "RETURNING list has too many entries" +msgstr "RETURNING listesinde çok fazla öğe vardır" + +#: rewrite/rewriteDefine.c:703 +#, c-format +msgid "cannot convert relation containing dropped columns to view" +msgstr "cannot convert relation containing dropped columns to view" + +#: rewrite/rewriteDefine.c:704 +#, fuzzy, c-format +#| msgid "cannot convert relation containing dropped columns to view" +msgid "cannot create a RETURNING list for a relation containing dropped columns" +msgstr "cannot convert relation containing dropped columns to view" + +#: rewrite/rewriteDefine.c:710 +#, c-format +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" +msgstr "SELECT rule'un hedef öğesi %d sütun \"%s\"'dan farklı bir sütun ismine sahip" + +#: rewrite/rewriteDefine.c:712 +#, c-format +msgid "SELECT target entry is named \"%s\"." +msgstr "SELECT hedef öğesi \"%s\" olarak isimlendirilmiş" + +#: rewrite/rewriteDefine.c:721 +#, c-format +msgid "SELECT rule's target entry %d has different type from column \"%s\"" +msgstr "SELECT rule'un hedef öğesi %d sütun \"%s\"'dan farklı bir tipe sahip" + +#: rewrite/rewriteDefine.c:723 +#, c-format +msgid "RETURNING list's entry %d has different type from column \"%s\"" +msgstr "RETURNING listesinin %d öğesi \"%s\" sütunun tipinden farklı" + +#: rewrite/rewriteDefine.c:726 rewrite/rewriteDefine.c:750 +#, c-format +msgid "SELECT target entry has type %s, but column has type %s." +msgstr "SELECT hedef öğesi %s tipinde, fakat sütun %s tipinde." + +#: rewrite/rewriteDefine.c:729 rewrite/rewriteDefine.c:754 +#, c-format +msgid "RETURNING list entry has type %s, but column has type %s." +msgstr "RETURNING listesinin öğesi \"%s\" tipinde, fakat sütun tipi %s." + +#: rewrite/rewriteDefine.c:745 +#, c-format +msgid "SELECT rule's target entry %d has different size from column \"%s\"" +msgstr "SELECT rule'un hedef öğesi %d sütun \"%s\"'dan farklı bir boyuta sahip" + +#: rewrite/rewriteDefine.c:747 +#, c-format +msgid "RETURNING list's entry %d has different size from column \"%s\"" +msgstr "RETURNING listesinin %d öğesi \"%s\" sütunun boyutundan farklı" + +#: rewrite/rewriteDefine.c:764 +#, c-format +msgid "SELECT rule's target list has too few entries" +msgstr "SELECT rule'un hedef listesi gereğinden az öğeye sahip" + +#: rewrite/rewriteDefine.c:765 +#, c-format +msgid "RETURNING list has too few entries" +msgstr "RETURNING ifadesinde çok az öğe vardır" + +#: rewrite/rewriteDefine.c:857 rewrite/rewriteDefine.c:971 rewrite/rewriteSupport.c:109 +#, c-format +msgid "rule \"%s\" for relation \"%s\" does not exist" +msgstr "\"%s\" rule'u \"%s\" tablosunda mevcut değil" + +#: rewrite/rewriteDefine.c:990 +#, c-format +msgid "renaming an ON SELECT rule is not allowed" +msgstr "bir ON SELECT kuralının yeniden adlandırılmasına izin verilmez" + +#: rewrite/rewriteHandler.c:541 +#, c-format +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" +msgstr "" + +#: rewrite/rewriteHandler.c:601 +#, c-format +msgid "cannot have RETURNING lists in multiple rules" +msgstr "RETURNING tümcesi, birden fazla rule içinde kullanılamaz" + +#: rewrite/rewriteHandler.c:823 +#, c-format +msgid "cannot insert into column \"%s\"" +msgstr "\"%s\" sütununa insert edilemiyor" + +#: rewrite/rewriteHandler.c:824 rewrite/rewriteHandler.c:839 +#, c-format +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "" + +#: rewrite/rewriteHandler.c:826 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "" + +#: rewrite/rewriteHandler.c:838 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "\"%s\" sütunu sadece DEFAULT olarak güncellenebilir" + +#: rewrite/rewriteHandler.c:1000 rewrite/rewriteHandler.c:1018 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "aynı sütun \"%s\" için birden fazla değer atama" + +#: rewrite/rewriteHandler.c:1921 +#, c-format +msgid "infinite recursion detected in policy for relation \"%s\"" +msgstr "\"%s\" tablosuna bağlı politikada sonsuz özyineleme bulundu" + +#: rewrite/rewriteHandler.c:2241 +msgid "Junk view columns are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2246 +msgid "View columns that are not columns of their base relation are not updatable." +msgstr "" + +#: rewrite/rewriteHandler.c:2249 +msgid "View columns that refer to system columns are not updatable." +msgstr "Sistem sütunlarına referans veren görünüm (view) sütunları güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2252 +msgid "View columns that return whole-row references are not updatable." +msgstr "Tam-satır referansları döndüren görünüm (view) sütunları güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2313 +msgid "Views containing DISTINCT are not automatically updatable." +msgstr "DISTINCT içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2316 +msgid "Views containing GROUP BY are not automatically updatable." +msgstr "GROUP BY içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2319 +msgid "Views containing HAVING are not automatically updatable." +msgstr "HAVING içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2322 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +msgstr "UNION, INTERSECT veya EXCEPT içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2325 +msgid "Views containing WITH are not automatically updatable." +msgstr "WITH içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2328 +msgid "Views containing LIMIT or OFFSET are not automatically updatable." +msgstr "LIMIT veya OFFSET içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2340 +msgid "Views that return aggregate functions are not automatically updatable." +msgstr "Toplam (aggregate) fonksiyonları döndüren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2343 +msgid "Views that return window functions are not automatically updatable." +msgstr "Window fonksiyonları döndüren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2346 +msgid "Views that return set-returning functions are not automatically updatable." +msgstr "Küme döndüren fonksiyon döndüren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2353 rewrite/rewriteHandler.c:2357 rewrite/rewriteHandler.c:2365 +msgid "Views that do not select from a single table or view are not automatically updatable." +msgstr "Tek bir tablo veya görünümden (view) select yapmayan görünümler otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2368 +msgid "Views containing TABLESAMPLE are not automatically updatable." +msgstr "TABLESAMPLE içeren görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2392 +msgid "Views that have no updatable columns are not automatically updatable." +msgstr "Güncellenebilir sütunu olmayan görünümler (view) otomatik olarak güncellenebilir değildir." + +#: rewrite/rewriteHandler.c:2849 +#, c-format +msgid "cannot insert into column \"%s\" of view \"%s\"" +msgstr "\"%2$s\" görünümünün (view) \"%1$s\" sütununa eklenemiyor (insert)" + +#: rewrite/rewriteHandler.c:2857 +#, c-format +msgid "cannot update column \"%s\" of view \"%s\"" +msgstr "\"%2$s\" görünümünün (view) \"%1$s\" sütunu güncellenemiyor (update)" + +#: rewrite/rewriteHandler.c:3327 +#, c-format +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3341 +#, c-format +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3345 +#, c-format +msgid "DO ALSO rules are not supported for data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3350 +#, c-format +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" +msgstr "" + +#: rewrite/rewriteHandler.c:3569 +#, c-format +msgid "cannot perform INSERT RETURNING on relation \"%s\"" +msgstr "\"%s\" nesnesinde INSERT RETURNING yapılamaz" + +#: rewrite/rewriteHandler.c:3571 +#, c-format +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING tümcesi olan ON INSERT DO INSTEAD rule gerekmektedir" + +#: rewrite/rewriteHandler.c:3576 +#, c-format +msgid "cannot perform UPDATE RETURNING on relation \"%s\"" +msgstr "\"%s\" nesnesinde UPDATE RETURNING yapılamaz" + +#: rewrite/rewriteHandler.c:3578 +#, c-format +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgstr "RETURNING tümcesi olan ON UPDATE DO INSTEAD rule gerekmektedir" + +#: rewrite/rewriteHandler.c:3583 +#, c-format +msgid "cannot perform DELETE RETURNING on relation \"%s\"" +msgstr "\"%s\" nesnesi üzerinde DELETE RETURNING işlemi yapılamaz" + +#: rewrite/rewriteHandler.c:3585 +#, c-format +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgstr "Bunu yapmak için şartsız RETURNING tümcesi olan ON DELETE DO INSTEAD rule gerekmetedir." + +#: rewrite/rewriteHandler.c:3603 +#, c-format +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" +msgstr "INSERT with ON CONFLICT ibaresi INSERT veya UPDATE kuralları (rule) olan bir tablo ile kullanılamaz" + +#: rewrite/rewriteHandler.c:3660 +#, c-format +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" +msgstr "" + +#: rewrite/rewriteManip.c:1003 +#, c-format +msgid "conditional utility statements are not implemented" +msgstr "conditional utility statements implement edilmemiş" + +#: rewrite/rewriteManip.c:1169 +#, c-format +msgid "WHERE CURRENT OF on a view is not implemented" +msgstr "view üzerinde WHERE CURRENT OF implement edilmemiştir" + +#: rewrite/rewriteManip.c:1503 +#, c-format +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "" + +#: scan.l:445 +msgid "unterminated /* comment" +msgstr "/* açıklama sonlandırılmamış" + +#: scan.l:474 +msgid "unterminated bit string literal" +msgstr "sonuçlandırılmamış bit string literal" + +#: scan.l:495 +msgid "unterminated hexadecimal string literal" +msgstr "sonuçlandırılmamış hexadecimal string literal" + +#: scan.l:545 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "" + +#: scan.l:546 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "" + +#: scan.l:592 scan.l:791 +msgid "invalid Unicode escape character" +msgstr "Unicode kaçış (escape) karakteri geçersiz" + +#: scan.l:618 scan.l:626 scan.l:634 scan.l:635 scan.l:636 scan.l:1380 scan.l:1407 scan.l:1411 scan.l:1449 scan.l:1453 scan.l:1475 scan.l:1485 +#, fuzzy +msgid "invalid Unicode surrogate pair" +msgstr "geçersiz end sequence" + +#: scan.l:640 +#, c-format +msgid "invalid Unicode escape" +msgstr "geçersiz Unicode kaçışı (escape)" + +#: scan.l:641 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicode kaçışları (escape) \\uXXXX veya \\UXXXXXXXX olmalıdır." + +#: scan.l:652 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "string literal içinde güvenli olmayan \\' kullanımı" + +#: scan.l:653 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "Satır içinde tırnak yazmak için iki tek tırnak ('') kullanın. İstemci baslı kodlamalarda (\\') kullanımı güvenli değildir." + +#: scan.l:728 +msgid "unterminated dollar-quoted string" +msgstr "sonlandırılmamış dolar işaretiyle sınırlandırılmış satır" + +#: scan.l:745 scan.l:771 scan.l:786 +msgid "zero-length delimited identifier" +msgstr "sınırlandırılmış tanım sıfır uzunluklu" + +#: scan.l:806 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "sonlandırılmamış tırnakla sınırlandırılmış tanımlayıcı" + +#: scan.l:969 +msgid "operator too long" +msgstr "operator fazla uzun" + +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1125 +#, c-format +msgid "%s at end of input" +msgstr "giriş sonuna %s" + +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1133 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "\"%2$s\" yerinde %1$s" + +#: scan.l:1294 scan.l:1326 +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +msgstr "" + +#: scan.l:1322 scan.l:1467 +msgid "invalid Unicode escape value" +msgstr "geçersiz Unicode kaçış (escape) değeri" + +#: scan.l:1531 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "string literal içinde standart olmayan \\' kullanımı" + +#: scan.l:1532 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "Satır içinde tırnak yazmak için ya iki tek tırnak ('') ya da escape kullanın (E'...')." + +#: scan.l:1541 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "string literal içinde standart olmayan \\\\ kullanımı" + +#: scan.l:1542 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "Ters taksim için escape satır sözdizimini kullanın, örneğin, E'\\\\'." + +#: scan.l:1556 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "string literal içinde standart olmayan escape kullanımı" + +#: scan.l:1557 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "Escape için standart sözdizimini kullanın, örneğin, E'\\r\\n'." + +#: snowball/dict_snowball.c:177 +#, c-format +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "\"%s\" dili ve \"%s\" kodlaması için Snowball stemmer mevcut değildir" + +#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:74 tsearch/dict_simple.c:49 +#, c-format +msgid "multiple StopWords parameters" +msgstr "birden fazla StopWords parametresi" + +#: snowball/dict_snowball.c:209 +#, c-format +msgid "multiple Language parameters" +msgstr "çoklu Language parametreleri" + +#: snowball/dict_snowball.c:216 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "tanımlanmamış Snowball parametresi: \"%s\" " + +#: snowball/dict_snowball.c:224 +#, c-format +msgid "missing Language parameter" +msgstr "eksik Language parametresi" + +#: statistics/dependencies.c:534 +#, c-format +msgid "invalid zero-length item array in MVDependencies" +msgstr "" + +#: statistics/dependencies.c:672 statistics/dependencies.c:725 statistics/mvdistinct.c:341 statistics/mvdistinct.c:394 utils/adt/pseudotypes.c:94 utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 +#, c-format +msgid "cannot accept a value of type %s" +msgstr "%s tipinde değer alınamaz" + +#: statistics/extended_stats.c:104 +#, c-format +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "" + +#: statistics/mvdistinct.c:262 +#, c-format +msgid "invalid ndistinct magic %08x (expected %08x)" +msgstr "" + +#: statistics/mvdistinct.c:267 +#, fuzzy, c-format +#| msgid "wrong data type: %u, expected %u" +msgid "invalid ndistinct type %d (expected %d)" +msgstr "yanlış veri tipi: %u beklenirken %u alındı" + +#: statistics/mvdistinct.c:272 +#, fuzzy, c-format +#| msgid "invalid length in external bit string" +msgid "invalid zero-length item array in MVNDistinct" +msgstr "external bit string uzunuğu geçersiz" + +#: statistics/mvdistinct.c:281 +#, c-format +msgid "invalid MVNDistinct size %zd (expected at least %zd)" +msgstr "" + +#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 +#, c-format +msgid "cannot access temporary tables of other sessions" +msgstr "diğer oturumların geçici tablolarına erişilemez" + +#: storage/buffer/bufmgr.c:807 +#, fuzzy, c-format +msgid "unexpected data beyond EOF in block %u of relation %s" +msgstr "\"%2$s\" nesnesinin %1$u bloğunda dosya sonundan sonra beklenmeyen veri" + +#: storage/buffer/bufmgr.c:809 +#, c-format +msgid "This has been seen to occur with buggy kernels; consider updating your system." +msgstr "Bu durum bazı eski çekirdeklerde meydana gelebilir. Yeni kernellerde bu düzeltilmiştir." + +#: storage/buffer/bufmgr.c:907 +#, fuzzy, c-format +msgid "invalid page in block %u of relation %s; zeroing out page" +msgstr "\"%2$s\" tablosunun %1$u bloğunda geçersiz sayfa başlığı; sayfa sıfırlanıyor" + +#: storage/buffer/bufmgr.c:4013 +#, c-format +msgid "could not write block %u of %s" +msgstr "%2$s nin %1$u bloğuna yazılamadı" + +#: storage/buffer/bufmgr.c:4015 +#, c-format +msgid "Multiple failures --- write error might be permanent." +msgstr "Çoklu hata --- yazma hatası kalıcı olabilir." + +#: storage/buffer/bufmgr.c:4036 storage/buffer/bufmgr.c:4055 +#, c-format +msgid "writing block %u of relation %s" +msgstr "%2$s tablosunun %1$u bloğuna yazılıyor" + +#: storage/buffer/bufmgr.c:4358 +#, c-format +msgid "snapshot too old" +msgstr "snapshot çok eski" + +#: storage/buffer/localbuf.c:199 +#, c-format +msgid "no empty local buffer available" +msgstr "boş yerel arabellek bulunamadı" + +#: storage/buffer/localbuf.c:427 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "bir paralel işlem sırasında geçici tablolara erişilemiyor" + +#: storage/file/buffile.c:317 +#, fuzzy, c-format +#| msgid "could not open temporary file \"%s\": %m" +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "\"%s\" geçici dosya açılamıyor: %m" + +#: storage/file/buffile.c:814 +#, fuzzy, c-format +#| msgid "could not determine size of temporary file \"%s\"" +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "\"%s\" geçici dosyasının boyutu belirlenemedi" + +#: storage/file/fd.c:451 storage/file/fd.c:523 storage/file/fd.c:559 +#, c-format +msgid "could not flush dirty data: %m" +msgstr "kirli veri temizlenemedi (flush): %m" + +#: storage/file/fd.c:481 +#, c-format +msgid "could not determine dirty data size: %m" +msgstr "kirli veri boyutu belirlenemedi: %m" + +#: storage/file/fd.c:533 +#, c-format +msgid "could not munmap() while flushing data: %m" +msgstr "veri temizlenirken (flush) munmap() yapılamadı: %m" + +#: storage/file/fd.c:734 +#, c-format +msgid "could not link file \"%s\" to \"%s\": %m" +msgstr "\"%s\" dosyası \"%s\" dosyasına bağlanamadı: %m" + +#: storage/file/fd.c:828 +#, c-format +msgid "getrlimit failed: %m" +msgstr "getrlimit başarısız oldu: %m" + +#: storage/file/fd.c:918 +#, c-format +msgid "insufficient file descriptors available to start server process" +msgstr "sunucu sürecini başlatmak için yetersiz dosya belirteçleri" + +#: storage/file/fd.c:919 +#, c-format +msgid "System allows %d, we need at least %d." +msgstr "Sistem %d dosya belirtecine izin veriyor, PostgreSQL en az %d istiyor." + +#: storage/file/fd.c:970 storage/file/fd.c:2379 storage/file/fd.c:2489 storage/file/fd.c:2640 +#, c-format +msgid "out of file descriptors: %m; release and retry" +msgstr "dosya belirteçleri kullanımda: %m; serbest bırakın ve yeniden kullanın" + +#: storage/file/fd.c:1313 +#, c-format +msgid "temporary file: path \"%s\", size %lu" +msgstr "geçici dosya: yol \"%s\", boyut %lu" + +#: storage/file/fd.c:1445 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "\"%s\" geçici dizini oluşturulamadı: %m" + +#: storage/file/fd.c:1452 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "\"%s\" geçici alt dizini oluşturulamadı: %m" + +#: storage/file/fd.c:1645 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "\"%s\" geçici dosyası oluşturma hatası: %m" + +#: storage/file/fd.c:1680 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "\"%s\" geçici dosya açılamıyor: %m" + +#: storage/file/fd.c:1721 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "\"%s\" geçici dosyası unlink edilemiyor: %m" + +#: storage/file/fd.c:2010 +#, c-format +msgid "temporary file size exceeds temp_file_limit (%dkB)" +msgstr "geçici dosya boyutu temp_file_limit (%dkB) sınırını aşmaktadır " + +#: storage/file/fd.c:2355 storage/file/fd.c:2414 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" +msgstr "\"%2$s\" dosyası açılmaya çalışılırken maxAllocatedDescs (%1$d) aşıldı" + +#: storage/file/fd.c:2459 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" +msgstr "\"%2$s\" komutu yürütülmeye çalışılırken maxAllocatedDescs (%1$d) aşıldı" + +#: storage/file/fd.c:2616 +#, c-format +msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" +msgstr "\"%2$s\" dizini açılmaya çalışılırken maxAllocatedDescs (%1$d) aşıldı" + +#: storage/file/fd.c:2707 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: storage/file/fd.c:3139 +#, c-format +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "geçici dosyalar dizininde beklenmeyen dosya bulundu: \"%s\"" + +#: storage/file/fd.c:3461 +#, c-format +msgid "could not rmdir directory \"%s\": %m" +msgstr "\"%s\" dizini silinemedi (rmdir): %m" + +#: storage/file/sharedfileset.c:93 +#, fuzzy, c-format +#| msgid "could not attach to dynamic shared area" +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "dinamik paylaşımlı alana (shared area) eklenemedi (attach)" + +#: storage/ipc/dsm.c:351 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "dinamik paylaşılan hafıza kontrol segmenti bozuk" + +#: storage/ipc/dsm.c:398 +#, c-format +msgid "dynamic shared memory is disabled" +msgstr "dinamik paylaşılana hafıza devre dışı bırakılmış" + +#: storage/ipc/dsm.c:399 +#, c-format +msgid "Set dynamic_shared_memory_type to a value other than \"none\"." +msgstr "dynamic_shared_memory_type değerini \"none\" haricinde bir değere ayarlayın." + +#: storage/ipc/dsm.c:419 +#, c-format +msgid "dynamic shared memory control segment is not valid" +msgstr "dinamik paylaşılan hafıza kontrol segmenti geçerli değil" + +#: storage/ipc/dsm.c:515 +#, c-format +msgid "too many dynamic shared memory segments" +msgstr "çok fazla dinamik paylaşılan hafıza kontrol segmenti mevcut" + +#: storage/ipc/dsm_impl.c:264 storage/ipc/dsm_impl.c:373 storage/ipc/dsm_impl.c:594 storage/ipc/dsm_impl.c:709 storage/ipc/dsm_impl.c:880 storage/ipc/dsm_impl.c:1024 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not unmap shared memory segment \"%s\": %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:274 storage/ipc/dsm_impl.c:604 storage/ipc/dsm_impl.c:719 storage/ipc/dsm_impl.c:890 +#, c-format +msgid "could not remove shared memory segment \"%s\": %m" +msgstr "\"%s\" shared memory segment'i kaldırılamadı: %m" + +#: storage/ipc/dsm_impl.c:295 storage/ipc/dsm_impl.c:790 storage/ipc/dsm_impl.c:904 +#, c-format +msgid "could not open shared memory segment \"%s\": %m" +msgstr "\"%s\" shared memory segment'i açılamadı: %m" + +#: storage/ipc/dsm_impl.c:319 storage/ipc/dsm_impl.c:620 storage/ipc/dsm_impl.c:835 storage/ipc/dsm_impl.c:928 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not stat shared memory segment \"%s\": %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:347 storage/ipc/dsm_impl.c:947 storage/ipc/dsm_impl.c:997 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:397 storage/ipc/dsm_impl.c:641 storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:1048 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not map shared memory segment \"%s\": %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:576 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not get shared memory segment: %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:775 +#, fuzzy, c-format +#| msgid "could not create shared memory segment: %m" +msgid "could not create shared memory segment \"%s\": %m" +msgstr "shared memory segment oluşturulamıyor: %m" + +#: storage/ipc/dsm_impl.c:1090 storage/ipc/dsm_impl.c:1138 +#, fuzzy, c-format +msgid "could not duplicate handle for \"%s\": %m" +msgstr "\"%s\" dosyası oluşturulamıyor: %m" + +#: storage/ipc/latch.c:829 +#, c-format +msgid "epoll_ctl() failed: %m" +msgstr "epoll_ctl() başarısız oldu: %m" + +#: storage/ipc/latch.c:1060 +#, c-format +msgid "epoll_wait() failed: %m" +msgstr "epoll_wait() başarısız oldu: %m" + +#: storage/ipc/latch.c:1182 +#, c-format +msgid "poll() failed: %m" +msgstr "poll() başarısız oldu: %m" + +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:905 storage/lmgr/lock.c:943 storage/lmgr/lock.c:2730 storage/lmgr/lock.c:4055 storage/lmgr/lock.c:4120 storage/lmgr/lock.c:4412 storage/lmgr/predicate.c:2355 storage/lmgr/predicate.c:2370 storage/lmgr/predicate.c:3762 storage/lmgr/predicate.c:4905 utils/hash/dynahash.c:1065 +#, c-format +msgid "out of shared memory" +msgstr "shared memory yetersiz" + +#: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 +#, c-format +msgid "out of shared memory (%zu bytes requested)" +msgstr "shared memory yetersiz (%zu bayt talep edildi)" + +#: storage/ipc/shmem.c:421 +#, c-format +msgid "could not create ShmemIndex entry for data structure \"%s\"" +msgstr "\"%s\" veri tipi için ShmemIndex girdisi oluşturulamıyor" + +#: storage/ipc/shmem.c:436 +#, c-format +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "\"%s\" veri yapısı için ShmemIndex kayıt boyutu yanlış: %zu beklenen, gerçekleşen %zu" + +#: storage/ipc/shmem.c:453 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "\"%s\" veri yapısı için shared memory yeterli değildir (%zu bayt talep edildi)" + +#: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 +#, c-format +msgid "requested shared memory size overflows size_t" +msgstr "istenilen shared memory boyutu size_t tipini aşıyor" + +#: storage/ipc/standby.c:558 tcop/postgres.c:3056 +#, c-format +msgid "canceling statement due to conflict with recovery" +msgstr "kurtarma işlemi ile çakışmadan dolayı sorgu iptal ediliyor" + +#: storage/ipc/standby.c:559 tcop/postgres.c:2329 +#, c-format +msgid "User transaction caused buffer deadlock with recovery." +msgstr "" + +#: storage/large_object/inv_api.c:190 +#, c-format +msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" +msgstr "" + +#: storage/large_object/inv_api.c:271 +#, fuzzy, c-format +#| msgid "invalid OID for large object (%u)\n" +msgid "invalid flags for opening a large object: %d" +msgstr "(%u) large objecti için geçersiz OID\n" + +#: storage/large_object/inv_api.c:461 +#, fuzzy, c-format +#| msgid "invalid escape string" +msgid "invalid whence setting: %d" +msgstr "escape satırı geçersiz" + +#: storage/large_object/inv_api.c:633 +#, c-format +msgid "invalid large object write request size: %d" +msgstr "geçersiz large-object yazma isteği boyutu: %d" + +#: storage/lmgr/deadlock.c:1109 +#, c-format +msgid "Process %d waits for %s on %s; blocked by process %d." +msgstr "Process %d waits for %s on %s; blocked by process %d." + +#: storage/lmgr/deadlock.c:1128 +#, c-format +msgid "Process %d: %s" +msgstr "Süreç %d: %s" + +#: storage/lmgr/deadlock.c:1137 +#, c-format +msgid "deadlock detected" +msgstr "çıkmaz (deadlock) durumu saptandı" + +#: storage/lmgr/deadlock.c:1140 +#, c-format +msgid "See server log for query details." +msgstr "Sorgu ayrıntıları için sunucu kayıt dosyasına bakın." + +#: storage/lmgr/lmgr.c:767 +#, c-format +msgid "while updating tuple (%u,%u) in relation \"%s\"" +msgstr "\"%3$s\" nesnesindeki (%1$u,%2$u) satırı güncellenirken" + +#: storage/lmgr/lmgr.c:770 +#, c-format +msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgstr "\"%3$s\" nesnesindeki (%1$u,%2$u) satırı silinirken" + +#: storage/lmgr/lmgr.c:773 +#, c-format +msgid "while locking tuple (%u,%u) in relation \"%s\"" +msgstr "\"%3$s\" nesnesindeki (%1$u,%2$u) satırı kilitlenirken" + +#: storage/lmgr/lmgr.c:776 +#, c-format +msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" +msgstr "\"%3$s\" nesnesindeki (%1$u,%2$u) satırının güncellenmiş sürümü kilitlenirken " + +#: storage/lmgr/lmgr.c:779 +#, c-format +msgid "while inserting index tuple (%u,%u) in relation \"%s\"" +msgstr "\"%3$s\" nesnesindeki (%1$u,%2$u) indeks satırı eklenirken (insert)" + +#: storage/lmgr/lmgr.c:782 +#, c-format +msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" +msgstr "" + +#: storage/lmgr/lmgr.c:785 +#, c-format +msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" +msgstr "" + +#: storage/lmgr/lmgr.c:788 +#, c-format +msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" +msgstr "" + +#: storage/lmgr/lmgr.c:1008 +#, c-format +msgid "relation %u of database %u" +msgstr "%2$u veritabanının %1$u nesnesi" + +#: storage/lmgr/lmgr.c:1014 +#, c-format +msgid "extension of relation %u of database %u" +msgstr "%u nesnesinin uzantısı %u veritabanına aittir" + +#: storage/lmgr/lmgr.c:1020 +#, c-format +msgid "page %u of relation %u of database %u" +msgstr "%u sayfası %u nesnesinindir ve %u veritabanındadır" + +#: storage/lmgr/lmgr.c:1027 +#, c-format +msgid "tuple (%u,%u) of relation %u of database %u" +msgstr "(%u,%u) satırı %u nesnesinindir ve %u veritabanındadır" + +#: storage/lmgr/lmgr.c:1035 +#, c-format +msgid "transaction %u" +msgstr "transaction %u" + +#: storage/lmgr/lmgr.c:1040 +#, c-format +msgid "virtual transaction %d/%u" +msgstr "sanal transaction %d/%u" + +#: storage/lmgr/lmgr.c:1046 +#, fuzzy, c-format +#| msgid "could not access status of transaction %u" +msgid "speculative token %u of transaction %u" +msgstr "%u transactionunun durumuna erişilemiyor." + +#: storage/lmgr/lmgr.c:1052 +#, c-format +msgid "object %u of class %u of database %u" +msgstr "%u nesnesi %u sınıfındandır ve %u veritabanındadır" + +#: storage/lmgr/lmgr.c:1060 +#, c-format +msgid "user lock [%u,%u,%u]" +msgstr "user lock [%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1067 +#, c-format +msgid "advisory lock [%u,%u,%u,%u]" +msgstr "advisory lock [%u,%u,%u,%u]" + +#: storage/lmgr/lmgr.c:1075 +#, c-format +msgid "unrecognized locktag type %d" +msgstr "bilinmeyen locktag tipi %d" + +#: storage/lmgr/lock.c:740 +#, c-format +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" +msgstr "" + +#: storage/lmgr/lock.c:742 +#, c-format +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." +msgstr "" + +#: storage/lmgr/lock.c:906 storage/lmgr/lock.c:944 storage/lmgr/lock.c:2731 storage/lmgr/lock.c:4056 storage/lmgr/lock.c:4121 storage/lmgr/lock.c:4413 +#, c-format +msgid "You might need to increase max_locks_per_transaction." +msgstr "max_locks_per_transaction değerini artırmanız gerekebilir." + +#: storage/lmgr/lock.c:3172 storage/lmgr/lock.c:3288 +#, c-format +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" +msgstr "" + +#: storage/lmgr/predicate.c:682 +#, c-format +msgid "not enough elements in RWConflictPool to record a read/write conflict" +msgstr "" + +#: storage/lmgr/predicate.c:683 storage/lmgr/predicate.c:711 +#, c-format +msgid "You might need to run fewer transactions at a time or increase max_connections." +msgstr "" + +#: storage/lmgr/predicate.c:710 +#, c-format +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" +msgstr "" + +#: storage/lmgr/predicate.c:1515 +#, c-format +msgid "deferrable snapshot was unsafe; trying a new one" +msgstr "" + +#: storage/lmgr/predicate.c:1604 +#, c-format +msgid "\"default_transaction_isolation\" is set to \"serializable\"." +msgstr "\"default_transaction_isolation\" değeri \"serializable\" olarak ayarlı." + +#: storage/lmgr/predicate.c:1605 +#, c-format +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "Varsayılan değeri değiştirmek için \"SET default_transaction_isolation = 'repeatable read'\" ." + +#: storage/lmgr/predicate.c:1645 +#, c-format +msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" +msgstr "" + +#: storage/lmgr/predicate.c:1725 utils/time/snapmgr.c:621 utils/time/snapmgr.c:627 +#, c-format +msgid "could not import the requested snapshot" +msgstr "talep edilen snapshot içeri aktarılamadı (import)" + +#: storage/lmgr/predicate.c:1726 utils/time/snapmgr.c:628 +#, c-format +msgid "The source process with PID %d is not running anymore." +msgstr "%d PID'li kaynak süreç artık çalışmıyor." + +#: storage/lmgr/predicate.c:2356 storage/lmgr/predicate.c:2371 storage/lmgr/predicate.c:3763 +#, c-format +msgid "You might need to increase max_pred_locks_per_transaction." +msgstr "max_pred_locks_per_transaction değerini artırmanız gerekebilir." + +#: storage/lmgr/predicate.c:3917 storage/lmgr/predicate.c:4006 storage/lmgr/predicate.c:4014 storage/lmgr/predicate.c:4053 storage/lmgr/predicate.c:4292 storage/lmgr/predicate.c:4629 storage/lmgr/predicate.c:4641 storage/lmgr/predicate.c:4683 storage/lmgr/predicate.c:4721 +#, c-format +msgid "could not serialize access due to read/write dependencies among transactions" +msgstr "işlemler (transaction) arasındaki okuma/yazma bağımlılıkları nedeniyle erişim serialize edilemiyor" + +#: storage/lmgr/predicate.c:3919 storage/lmgr/predicate.c:4008 storage/lmgr/predicate.c:4016 storage/lmgr/predicate.c:4055 storage/lmgr/predicate.c:4294 storage/lmgr/predicate.c:4631 storage/lmgr/predicate.c:4643 storage/lmgr/predicate.c:4685 storage/lmgr/predicate.c:4723 +#, c-format +msgid "The transaction might succeed if retried." +msgstr "Tekrar denenirse işlem (transaction) başarılı olabilir." + +#: storage/lmgr/proc.c:1318 +#, c-format +msgid "Process %d waits for %s on %s." +msgstr "%1$d süreci %3$s üzerindeki %2$s için bekliyor." + +#: storage/lmgr/proc.c:1329 +#, c-format +msgid "sending cancel to blocking autovacuum PID %d" +msgstr "%d PID'li bloklayan autovacuum'a iptal gönderiliyor" + +#: storage/lmgr/proc.c:1347 utils/adt/misc.c:270 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "%d sürecine sinyal gönderme başarısız: %m" + +#: storage/lmgr/proc.c:1449 +#, c-format +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "%d süreci %s işlemi %s nesnesi için kaynak kilitlenmesini önledi bunun için %ld.%03d milisaniye bekledikten sonra sırada bekleyen işlemler yeniden düzenlendi" + +#: storage/lmgr/proc.c:1464 +#, c-format +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgstr "%d süreci %s nesnesini %s işlemi için beklerken %ld.%03d milisaniye sonra deadlock tespit etti" + +#: storage/lmgr/proc.c:1473 +#, fuzzy, c-format +msgid "process %d still waiting for %s on %s after %ld.%03d ms" +msgstr "Process %d waits for %s on %s; blocked by process %d." + +#: storage/lmgr/proc.c:1480 +#, c-format +msgid "process %d acquired %s on %s after %ld.%03d ms" +msgstr "process %d acquired %s on %s after %ld.%03d ms" + +#: storage/lmgr/proc.c:1496 +#, c-format +msgid "process %d failed to acquire %s on %s after %ld.%03d ms" +msgstr "process %d failed to acquire %s on %s after %ld.%03d ms" + +#: storage/page/bufpage.c:151 +#, c-format +msgid "page verification failed, calculated checksum %u but expected %u" +msgstr "sayfa doğrulaması başarısız oldu, sağlama toplamı %u olarak hesaplandı fakat %u bekleniyordu" + +#: storage/page/bufpage.c:213 storage/page/bufpage.c:507 storage/page/bufpage.c:744 storage/page/bufpage.c:877 storage/page/bufpage.c:973 storage/page/bufpage.c:1083 +#, c-format +msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" +msgstr "bozuk sayfa göstergesi: lower = %u, upper = %u, special = %u" + +#: storage/page/bufpage.c:529 +#, c-format +msgid "corrupted item pointer: %u" +msgstr "nesne imleyici bozuk: %u" + +#: storage/page/bufpage.c:556 storage/page/bufpage.c:928 +#, c-format +msgid "corrupted item lengths: total %u, available space %u" +msgstr "bozuk öğe uzunluğu: toplam %u, boş alan %u" + +#: storage/page/bufpage.c:763 storage/page/bufpage.c:989 storage/page/bufpage.c:1099 +#, c-format +msgid "corrupted item pointer: offset = %u, size = %u" +msgstr "bozuk öğe göstergisi: offset = %u, size = %u" + +#: storage/page/bufpage.c:901 +#, c-format +msgid "corrupted item pointer: offset = %u, length = %u" +msgstr "bozuk öğe göstergesi: offset = %u, uzunluk = %u" + +#: storage/smgr/md.c:448 storage/smgr/md.c:974 +#, c-format +msgid "could not truncate file \"%s\": %m" +msgstr "\"%s\" dosyası küçültülemedi (truncate): %m" + +#: storage/smgr/md.c:515 +#, c-format +msgid "cannot extend file \"%s\" beyond %u blocks" +msgstr "\"%s\" dosyası %u bloktan fazla genişletilemiyor" + +#: storage/smgr/md.c:537 storage/smgr/md.c:754 storage/smgr/md.c:830 +#, fuzzy, c-format +msgid "could not seek to block %u in file \"%s\": %m" +msgstr "\"%s\" dosyası ilerleme hatası: %m" + +#: storage/smgr/md.c:545 +#, c-format +msgid "could not extend file \"%s\": %m" +msgstr "\"%s\" dosyası genişletilemiyor: %m" + +#: storage/smgr/md.c:547 storage/smgr/md.c:554 storage/smgr/md.c:857 +#, c-format +msgid "Check free disk space." +msgstr "Boş disk alanını kontrol edin" + +#: storage/smgr/md.c:551 +#, fuzzy, c-format +msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" +msgstr "%1$u/%2$u/%3$u nesnesi büyütme hatası: %6$u bloğunda %4$d bayttan sadece %5$d bayt yazıldı" + +#: storage/smgr/md.c:772 +#, fuzzy, c-format +msgid "could not read block %u in file \"%s\": %m" +msgstr "\"%s\" lock dosyası okuma hatası: %m" + +#: storage/smgr/md.c:788 +#, fuzzy, c-format +msgid "could not read block %u in file \"%s\": read only %d of %d bytes" +msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloku okunamıyor: %6$d bayttan sadece %5$d bayt okundu" + +#: storage/smgr/md.c:848 +#, fuzzy, c-format +msgid "could not write block %u in file \"%s\": %m" +msgstr "\"%s\" lock dosyası yazma hatası: %m" + +#: storage/smgr/md.c:853 +#, fuzzy, c-format +msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" +msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloku yazılamıyor: %6$d bayttan sadece %5$d bayt yazıldı" + +#: storage/smgr/md.c:945 +#, fuzzy, c-format +msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" +msgstr "%u/%u/%u nesnesi %u blokuna kadar kesilemiyor: nesnenin boyutu %u blok olarak ayarlandı" + +#: storage/smgr/md.c:1000 +#, fuzzy, c-format +msgid "could not truncate file \"%s\" to %u blocks: %m" +msgstr "%s ilişkisi to %u bloğa küçültülemedi: %m" + +#: storage/smgr/md.c:1295 +#, c-format +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "\"%s\" dosyası fsync edilemedi, fakat tekrar deneniyor: %m" + +#: storage/smgr/md.c:1458 +#, c-format +msgid "could not forward fsync request because request queue is full" +msgstr "" + +#: storage/smgr/md.c:1964 +#, fuzzy, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "segment %u, nesne%u/%u/%u (hedef blok %u) açılamıyor: %m" + +#: storage/smgr/md.c:1978 +#, fuzzy, c-format +msgid "could not open file \"%s\" (target block %u): %m" +msgstr "segment %u, nesne%u/%u/%u (hedef blok %u) açılamıyor: %m" + +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 +#, c-format +msgid "invalid argument size %d in function call message" +msgstr "fonksiyon çağırma mesajında geçersiz argüman boyutu %d" + +#: tcop/fastpath.c:307 +#, c-format +msgid "fastpath function call: \"%s\" (OID %u)" +msgstr "fastpath function çağırımı: \"%s\" OID %u" + +#: tcop/fastpath.c:389 tcop/postgres.c:1218 tcop/postgres.c:1482 tcop/postgres.c:1864 tcop/postgres.c:2085 +#, c-format +msgid "duration: %s ms" +msgstr "süre: %s milisaniye" + +#: tcop/fastpath.c:393 +#, c-format +msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" +msgstr "süre: %s milisaniye fastpath function call: \"%s\" OID %u" + +#: tcop/fastpath.c:429 tcop/fastpath.c:556 +#, c-format +msgid "function call message contains %d arguments but function requires %d" +msgstr "fonksiyon çağırısına %d argüman bulunmakta ancak fonkiyon %d argüman istemektedir" + +#: tcop/fastpath.c:437 +#, c-format +msgid "function call message contains %d argument formats but %d arguments" +msgstr "fonksiyon çağırma mesajı %d argüman biçimi ve %d argüman içeriyor" + +#: tcop/fastpath.c:524 tcop/fastpath.c:607 +#, c-format +msgid "incorrect binary data format in function argument %d" +msgstr "%d fonksiyon argümanında geçersiz ikili veri" + +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 +#, c-format +msgid "unexpected EOF on client connection" +msgstr "istemci bağlantısında beklenmeyen EOF" + +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 tcop/postgres.c:480 tcop/postgres.c:4408 +#, c-format +msgid "invalid frontend message type %d" +msgstr "geçersiz frontend mesaj tipi %d" + +#: tcop/postgres.c:973 +#, c-format +msgid "statement: %s" +msgstr "komut: %s" + +#: tcop/postgres.c:1223 +#, c-format +msgid "duration: %s ms statement: %s" +msgstr "süre: %s milisaniye komut: %s" + +#: tcop/postgres.c:1273 +#, c-format +msgid "parse %s: %s" +msgstr "parse %s: %s" + +#: tcop/postgres.c:1330 +#, c-format +msgid "cannot insert multiple commands into a prepared statement" +msgstr "önceden hazırlanmış komuta çoklu komut eklenemez" + +#: tcop/postgres.c:1487 +#, c-format +msgid "duration: %s ms parse %s: %s" +msgstr "süre: %s milisaniye parse %s: %s" + +#: tcop/postgres.c:1532 +#, c-format +msgid "bind %s to %s" +msgstr "bind %s to %s" + +#: tcop/postgres.c:1551 tcop/postgres.c:2377 +#, c-format +msgid "unnamed prepared statement does not exist" +msgstr "ismi verilmemiş hazırlamış komut mevcut değil" + +#: tcop/postgres.c:1594 +#, c-format +msgid "bind message has %d parameter formats but %d parameters" +msgstr "bind mesajı %d argüman biçimi ve %d argüman içeriyor" + +#: tcop/postgres.c:1600 +#, c-format +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" +msgstr "bind mesajı %d parametre veriyor ancak \"%s\" hazırlanmış deymi %d gerektirir" + +#: tcop/postgres.c:1771 +#, c-format +msgid "incorrect binary data format in bind parameter %d" +msgstr "bind parametresinde geçersiz ikili veri %d" + +#: tcop/postgres.c:1869 +#, c-format +msgid "duration: %s ms bind %s%s%s: %s" +msgstr "süre: %s milisaniye bind %s%s%s: %s" + +#: tcop/postgres.c:1917 tcop/postgres.c:2461 +#, c-format +msgid "portal \"%s\" does not exist" +msgstr "portal \"%s\" mevcut değildir" + +#: tcop/postgres.c:2002 +#, c-format +msgid "%s %s%s%s: %s" +msgstr "%s %s%s%s: %s" + +#: tcop/postgres.c:2004 tcop/postgres.c:2093 +msgid "execute fetch from" +msgstr "execute fetch from" + +#: tcop/postgres.c:2005 tcop/postgres.c:2094 +msgid "execute" +msgstr "execute" + +#: tcop/postgres.c:2090 +#, c-format +msgid "duration: %s ms %s %s%s%s: %s" +msgstr "süre: %s ms %s %s%s%s: %s" + +#: tcop/postgres.c:2216 +#, c-format +msgid "prepare: %s" +msgstr "prepare: %s" + +#: tcop/postgres.c:2282 +#, c-format +msgid "parameters: %s" +msgstr "%s parametresi" + +#: tcop/postgres.c:2301 +#, fuzzy, c-format +msgid "abort reason: recovery conflict" +msgstr "archive recovery tamamlandı" + +#: tcop/postgres.c:2317 +#, c-format +msgid "User was holding shared buffer pin for too long." +msgstr "" + +#: tcop/postgres.c:2320 +#, c-format +msgid "User was holding a relation lock for too long." +msgstr "" + +#: tcop/postgres.c:2323 +#, c-format +msgid "User was or might have been using tablespace that must be dropped." +msgstr "" + +#: tcop/postgres.c:2326 +#, c-format +msgid "User query might have needed to see row versions that must be removed." +msgstr "" + +#: tcop/postgres.c:2332 +#, fuzzy, c-format +msgid "User was connected to a database that must be dropped." +msgstr "%s: veritabanına bağlı değil\n" + +#: tcop/postgres.c:2657 +#, c-format +msgid "terminating connection because of crash of another server process" +msgstr "diğer aktif sunucu sürecinin durması nedeniyle bağlantı kapatılmıştır" + +#: tcop/postgres.c:2658 +#, c-format +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Başka bir sürecin olağan dışı çıkışı nedeniyle shared memory bozulmuş ihtimali var. Dolayısıyla tüm süreçlerine tüm aktif işlemlerini rollback edip çıkmak komutu verilmiş." + +#: tcop/postgres.c:2662 tcop/postgres.c:2986 +#, c-format +msgid "In a moment you should be able to reconnect to the database and repeat your command." +msgstr "Birkaç saniye sonra veritabana bağlanıp işlemlerinize devam edebilirsiniz." + +#: tcop/postgres.c:2744 +#, c-format +msgid "floating-point exception" +msgstr "gerçel sayı istisnası" + +#: tcop/postgres.c:2745 +#, c-format +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." +msgstr "Geçersiz floating-point işlemi sinyali alındı. Bu, matematiksel sıfıra bölme gibi geçersiz işlem ya da kapsam dışı sonucun göstergesidir." + +#: tcop/postgres.c:2916 +#, c-format +msgid "canceling authentication due to timeout" +msgstr "zamanaşımı nedeniyle yetkilendirme iptal edildi" + +#: tcop/postgres.c:2920 +#, c-format +msgid "terminating autovacuum process due to administrator command" +msgstr "yönetici talimatı doğrultusunda autovacuum süreci sonlandırılıyor" + +#: tcop/postgres.c:2924 +#, fuzzy, c-format +#| msgid "terminating connection due to administrator command" +msgid "terminating logical replication worker due to administrator command" +msgstr "yönetici talimatı doğrultusunda bağlantı kesildi" + +#: tcop/postgres.c:2928 +#, fuzzy, c-format +#| msgid "autovacuum launcher shutting down" +msgid "logical replication launcher shutting down" +msgstr "otomatik vacuum başlatma süreci kapatılıyor" + +#: tcop/postgres.c:2941 tcop/postgres.c:2951 tcop/postgres.c:2984 +#, fuzzy, c-format +msgid "terminating connection due to conflict with recovery" +msgstr "yönetici talimatı doğrultusunda bağlantı kesildi" + +#: tcop/postgres.c:2957 +#, c-format +msgid "terminating connection due to administrator command" +msgstr "yönetici talimatı doğrultusunda bağlantı kesildi" + +#: tcop/postgres.c:2967 +#, fuzzy, c-format +#| msgid "connection to server was lost\n" +msgid "connection to client lost" +msgstr "sunucuya bağlantı kesildi\n" + +#: tcop/postgres.c:3033 +#, fuzzy, c-format +#| msgid "canceling statement due to statement timeout" +msgid "canceling statement due to lock timeout" +msgstr "sorgu zaman aşımına uğradı ve iptal edildi" + +#: tcop/postgres.c:3040 +#, c-format +msgid "canceling statement due to statement timeout" +msgstr "sorgu zaman aşımına uğradı ve iptal edildi" + +#: tcop/postgres.c:3047 +#, c-format +msgid "canceling autovacuum task" +msgstr "autovacuum görevi iptal ediliyor" + +#: tcop/postgres.c:3070 +#, c-format +msgid "canceling statement due to user request" +msgstr "kullanıcı isteği ile sorgu iptal edildi" + +#: tcop/postgres.c:3080 +#, fuzzy, c-format +#| msgid "terminating connection due to administrator command" +msgid "terminating connection due to idle-in-transaction timeout" +msgstr "yönetici talimatı doğrultusunda bağlantı kesildi" + +#: tcop/postgres.c:3194 +#, c-format +msgid "stack depth limit exceeded" +msgstr "stack derinliği sınırı aşıldı" + +#: tcop/postgres.c:3195 +#, fuzzy, c-format +#| msgid "Increase the configuration parameter \"max_stack_depth\", after ensuring the platform's stack depth limit is adequate." +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "İşletim sisteminin stack derinliğinin yeterli olduğundan emin olarak \"max_stack_depth\" konfigurasyon parametresini artırın." + +#: tcop/postgres.c:3258 +#, fuzzy, c-format +#| msgid "\"max_stack_depth\" must not exceed %ldkB" +msgid "\"max_stack_depth\" must not exceed %ldkB." +msgstr "\"max_stack_depth\" parametresi %ldkB açmamalıdır" + +#: tcop/postgres.c:3260 +#, c-format +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." +msgstr "İşletim sisteminin stack derinliği \"ulimit -s\" veya benzeri komutu ile arttırın." + +#: tcop/postgres.c:3620 +#, fuzzy, c-format +#| msgid "invalid command-line arguments for server process" +msgid "invalid command-line argument for server process: %s" +msgstr "sunucu süreci için geçersiz komut satırı parametreleri" + +#: tcop/postgres.c:3621 tcop/postgres.c:3627 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Daha fazla bilgi için \"%s --help\" yazın." + +#: tcop/postgres.c:3625 +#, fuzzy, c-format +#| msgid "%s: invalid command-line arguments" +msgid "%s: invalid command-line argument: %s" +msgstr "%s: komut satırı parametresi yanlış" + +#: tcop/postgres.c:3687 +#, c-format +msgid "%s: no database nor user name specified" +msgstr ":%s: ne veritabanı ne de kullanıcı adı belirtilmemiştir" + +#: tcop/postgres.c:4316 +#, c-format +msgid "invalid CLOSE message subtype %d" +msgstr "geçersiz CLOSE mesaj alt tipi %d" + +#: tcop/postgres.c:4351 +#, c-format +msgid "invalid DESCRIBE message subtype %d" +msgstr "geçersiz DESCRIBE mesaj alt tipi %d" + +#: tcop/postgres.c:4429 +#, fuzzy, c-format +#| msgid "cast function must not be an aggregate function" +msgid "fastpath function calls not supported in a replication connection" +msgstr "cast fonksiyonu aggregate olmamalıdır" + +#: tcop/postgres.c:4433 +#, c-format +msgid "extended query protocol not supported in a replication connection" +msgstr "" + +#: tcop/postgres.c:4610 +#, c-format +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" +msgstr "bağlantı bitti: oturum zamanı: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" + +#: tcop/pquery.c:645 +#, c-format +msgid "bind message has %d result formats but query has %d columns" +msgstr "bind mesajı ında %d sonuç biçimi verilmişken sorguda %d sütun belirtilmiş" + +#: tcop/pquery.c:952 +#, c-format +msgid "cursor can only scan forward" +msgstr "cursor sadece ileri doğru gidebilir" + +#: tcop/pquery.c:953 +#, c-format +msgid "Declare it with SCROLL option to enable backward scan." +msgstr "Geriye gitmesini sağlamak için SCROLL seçeneği ile bildirin." + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:245 +#, fuzzy, c-format +msgid "cannot execute %s in a read-only transaction" +msgstr "salt okunur transaction içinde okuma-yazma moduna ayarlanamıyor" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:263 +#, fuzzy, c-format +msgid "cannot execute %s during a parallel operation" +msgstr "sorgu çalıştırılamadı" + +#. translator: %s is name of a SQL command, eg CREATE +#: tcop/utility.c:282 +#, fuzzy, c-format +msgid "cannot execute %s during recovery" +msgstr "sorgu çalıştırılamadı" + +#. translator: %s is name of a SQL command, eg PREPARE +#: tcop/utility.c:300 +#, fuzzy, c-format +msgid "cannot execute %s within security-restricted operation" +msgstr "var olan bir fonksiyonun döndürme tipi değiştirilemez" + +#: tcop/utility.c:760 +#, c-format +msgid "must be superuser to do CHECKPOINT" +msgstr "CHECKPOINT yapmak için superuser olmalısınız" + +#: tcop/utility.c:1341 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "\"%s\" bölümlenmiş tablosu üzerinde indeks oluşturulamıyor" + +#: tcop/utility.c:1343 +#, fuzzy, c-format +#| msgid "\"%s\" is not a foreign table" +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "\"%s\" bir uzak (foreign) tablo değildir" + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 +#, c-format +msgid "multiple DictFile parameters" +msgstr "mükerrer DictFile parametre" + +#: tsearch/dict_ispell.c:63 +#, c-format +msgid "multiple AffFile parameters" +msgstr "çoklu AffFile parametresi" + +#: tsearch/dict_ispell.c:82 +#, c-format +msgid "unrecognized Ispell parameter: \"%s\"" +msgstr "tanımlanmayan ispell parametresi: \"%s\"" + +#: tsearch/dict_ispell.c:96 +#, c-format +msgid "missing AffFile parameter" +msgstr "ekisk AffFile parametresi" + +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:648 +#, c-format +msgid "missing DictFile parameter" +msgstr "eksik DictFile parametresi" + +#: tsearch/dict_simple.c:58 +#, c-format +msgid "multiple Accept parameters" +msgstr "çoklu Accept parametreleri" + +#: tsearch/dict_simple.c:66 +#, fuzzy, c-format +msgid "unrecognized simple dictionary parameter: \"%s\"" +msgstr "\"%s\" tanınmayan recovery parametresi" + +#: tsearch/dict_synonym.c:118 +#, c-format +msgid "unrecognized synonym parameter: \"%s\"" +msgstr "tanımlanmamış eş anlamlılık parametresi: \"%s\"" + +#: tsearch/dict_synonym.c:125 +#, c-format +msgid "missing Synonyms parameter" +msgstr "eksik Synonyms parametresi" + +#: tsearch/dict_synonym.c:132 +#, c-format +msgid "could not open synonym file \"%s\": %m" +msgstr "\"%s\" eşanlamlılar dosyası açılamıyor: %m" + +#: tsearch/dict_thesaurus.c:179 +#, c-format +msgid "could not open thesaurus file \"%s\": %m" +msgstr "\"%s\" eşanlamlılar dosyası açılamadı: %m" + +#: tsearch/dict_thesaurus.c:212 +#, fuzzy, c-format +msgid "unexpected delimiter" +msgstr "beklenmeyen dosya sonu\n" + +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 +#, c-format +msgid "unexpected end of line or lexeme" +msgstr "beklenmeyen satır sonu ya da sözlükbirimi" + +#: tsearch/dict_thesaurus.c:287 +#, c-format +msgid "unexpected end of line" +msgstr "beklenmeyen satır sonu" + +#: tsearch/dict_thesaurus.c:297 +#, fuzzy, c-format +#| msgid "too many levels in nested structure/union definition" +msgid "too many lexemes in thesaurus entry" +msgstr "içiçe gelmiş yapı/birleşme tanımında çok fazla seviye" + +#: tsearch/dict_thesaurus.c:421 +#, c-format +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" + +#: tsearch/dict_thesaurus.c:427 +#, c-format +msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" +msgstr "" + +#: tsearch/dict_thesaurus.c:430 +#, fuzzy, c-format +msgid "Use \"?\" to represent a stop word within a sample phrase." +msgstr "Satır sonu karakteri için \"\\r\" kullanın." + +#: tsearch/dict_thesaurus.c:576 +#, c-format +msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" +msgstr "" + +#: tsearch/dict_thesaurus.c:583 +#, c-format +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgstr "" + +#: tsearch/dict_thesaurus.c:595 +#, c-format +msgid "thesaurus substitute phrase is empty (rule %d)" +msgstr "" + +#: tsearch/dict_thesaurus.c:633 +#, c-format +msgid "multiple Dictionary parameters" +msgstr "çoklu Dil parametreleri" + +#: tsearch/dict_thesaurus.c:640 +#, fuzzy, c-format +msgid "unrecognized Thesaurus parameter: \"%s\"" +msgstr "\"%s\" tanınmayan parametre" + +#: tsearch/dict_thesaurus.c:652 +#, c-format +msgid "missing Dictionary parameter" +msgstr "eksik Sözlük parametresi" + +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 tsearch/spell.c:1034 +#, fuzzy, c-format +#| msgid "invalid data in file \"%s\"" +msgid "invalid affix flag \"%s\"" +msgstr "\"%s\" dosyasında geçersiz veri" + +#: tsearch/spell.c:384 tsearch/spell.c:1038 +#, fuzzy, c-format +#| msgid "value \"%s\" is out of range for type oid" +msgid "affix flag \"%s\" is out of range" +msgstr "oid tipi için \"%s\" değeri sıra dışıdır" + +#: tsearch/spell.c:414 +#, fuzzy, c-format +#| msgid "invalid data in file \"%s\"" +msgid "invalid character in affix flag \"%s\"" +msgstr "\"%s\" dosyasında geçersiz veri" + +#: tsearch/spell.c:434 +#, c-format +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "" + +#: tsearch/spell.c:522 +#, c-format +msgid "could not open dictionary file \"%s\": %m" +msgstr "\"%s\" sözlük dosyası açılamadı: %m" + +#: tsearch/spell.c:740 utils/adt/regexp.c:208 +#, c-format +msgid "invalid regular expression: %s" +msgstr "regular expression geçersiz: %s" + +#: tsearch/spell.c:1161 tsearch/spell.c:1726 +#, fuzzy, c-format +#| msgid "invalid cidr value: \"%s\"" +msgid "invalid affix alias \"%s\"" +msgstr "cidr değeri geçersiz: \"%s\"" + +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 +#, c-format +msgid "could not open affix file \"%s\": %m" +msgstr "\"%s\" affix dosyası açılamıyor: %m" + +#: tsearch/spell.c:1265 +#, c-format +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "" + +#: tsearch/spell.c:1309 +#, fuzzy, c-format +#| msgid "invalid column number %d for table \"%s\"\n" +msgid "invalid number of flag vector aliases" +msgstr "\"%2$s\" tablosu için geçersiz sütun numarası %1$d\n" + +#: tsearch/spell.c:1332 +#, fuzzy, c-format +#| msgid "number of aliases does not match number of columns" +msgid "number of aliases exceeds specified number %d" +msgstr "Takma adların sayısı ile kolon satısı eşleşmiyor" + +#: tsearch/spell.c:1547 +#, c-format +msgid "affix file contains both old-style and new-style commands" +msgstr "" + +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1134 +#, fuzzy, c-format +msgid "string is too long for tsvector (%d bytes, max %d bytes)" +msgstr "dizgi tsvector için çok uzun" + +#: tsearch/ts_locale.c:185 +#, c-format +msgid "line %d of configuration file \"%s\": \"%s\"" +msgstr "" + +#: tsearch/ts_locale.c:302 +#, c-format +msgid "conversion from wchar_t to server encoding failed: %m" +msgstr "wchar_t'den sunucu dil kodlamasına dönüşüm başarısız oldu: %m" + +#: tsearch/ts_parse.c:390 tsearch/ts_parse.c:397 tsearch/ts_parse.c:566 tsearch/ts_parse.c:573 +#, c-format +msgid "word is too long to be indexed" +msgstr "sözcük indexlenebilmek için çok uzun" + +#: tsearch/ts_parse.c:391 tsearch/ts_parse.c:398 tsearch/ts_parse.c:567 tsearch/ts_parse.c:574 +#, c-format +msgid "Words longer than %d characters are ignored." +msgstr "%d harften fazla sözcükler gözardı ediliyor." + +#: tsearch/ts_utils.c:51 +#, c-format +msgid "invalid text search configuration file name \"%s\"" +msgstr "geçersiz metin arama yapılandırma dosyası adı: \"%s\"" + +#: tsearch/ts_utils.c:83 +#, fuzzy, c-format +msgid "could not open stop-word file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 +#, fuzzy, c-format +msgid "text search parser does not support headline creation" +msgstr "\"%s\" tablespace'i mevcut değil" + +#: tsearch/wparser_def.c:2486 +#, fuzzy, c-format +msgid "unrecognized headline parameter: \"%s\"" +msgstr "\"%s\" tanınmayan parametre" + +#: tsearch/wparser_def.c:2495 +#, c-format +msgid "MinWords should be less than MaxWords" +msgstr "MinWords değeri MaxWords değerinden az olmalı" + +#: tsearch/wparser_def.c:2499 +#, c-format +msgid "MinWords should be positive" +msgstr "MinWords pozitif olmalıdır" + +#: tsearch/wparser_def.c:2503 +#, c-format +msgid "ShortWord should be >= 0" +msgstr "ShortWord >=0 olmalı" + +#: tsearch/wparser_def.c:2507 +#, fuzzy, c-format +msgid "MaxFragments should be >= 0" +msgstr "ShortWord >=0 olmalı" + +#: utils/adt/acl.c:171 utils/adt/name.c:91 +#, c-format +msgid "identifier too long" +msgstr "tanımlayıcı fazla uzun" + +#: utils/adt/acl.c:172 utils/adt/name.c:92 +#, c-format +msgid "Identifier must be less than %d characters." +msgstr "Tamılayıcı %d karakterden daha küçük olmalı." + +#: utils/adt/acl.c:258 +#, c-format +msgid "unrecognized key word: \"%s\"" +msgstr "anahtar kelimesi anlaşılamıyor: \"%s\"" + +#: utils/adt/acl.c:259 +#, c-format +msgid "ACL key word must be \"group\" or \"user\"." +msgstr "ACL anahtar kelimesi \"group\" veya \"user\" olmalıdır." + +#: utils/adt/acl.c:264 +#, c-format +msgid "missing name" +msgstr "isim eksik" + +#: utils/adt/acl.c:265 +#, c-format +msgid "A name must follow the \"group\" or \"user\" key word." +msgstr "\"group\" veya \"user\" anahter kelimesini isim izlemelidir." + +#: utils/adt/acl.c:271 +#, c-format +msgid "missing \"=\" sign" +msgstr "\"=\" işareti eksik" + +#: utils/adt/acl.c:324 +#, c-format +msgid "invalid mode character: must be one of \"%s\"" +msgstr "geçersiz biçim karakteri: şunlardan biri olmalıdır: \"%s\"" + +#: utils/adt/acl.c:346 +#, c-format +msgid "a name must follow the \"/\" sign" +msgstr "\"/\" karakterini bir isim izlemelidir" + +#: utils/adt/acl.c:354 +#, c-format +msgid "defaulting grantor to user ID %u" +msgstr "varsayılan bağışlayıcı kullanıcı ID %u" + +#: utils/adt/acl.c:545 +#, c-format +msgid "ACL array contains wrong data type" +msgstr "ACL array yanlış veri tipini içermektedir" + +#: utils/adt/acl.c:549 +#, c-format +msgid "ACL arrays must be one-dimensional" +msgstr "ACL array tek boyutlu olmalıdır" + +#: utils/adt/acl.c:553 +#, c-format +msgid "ACL arrays must not contain null values" +msgstr "ACL array null kayıtları içeremez" + +#: utils/adt/acl.c:577 +#, c-format +msgid "extra garbage at the end of the ACL specification" +msgstr "ACL tanımının sonunda fuzuli karakterler" + +#: utils/adt/acl.c:1213 +#, c-format +msgid "grant options cannot be granted back to your own grantor" +msgstr "grant seçenekleri kendi kendine verilemez" + +#: utils/adt/acl.c:1274 +#, c-format +msgid "dependent privileges exist" +msgstr "bağlı haklar mevcut" + +#: utils/adt/acl.c:1275 +#, c-format +msgid "Use CASCADE to revoke them too." +msgstr "Onları da geri almak için CASCADE kullanın." + +#: utils/adt/acl.c:1537 +#, c-format +msgid "aclinsert is no longer supported" +msgstr "aclinsert artık desteklenmemktedir" + +#: utils/adt/acl.c:1547 +#, c-format +msgid "aclremove is no longer supported" +msgstr "aclremove artık desteklenmemktedir" + +#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 +#, c-format +msgid "unrecognized privilege type: \"%s\"" +msgstr "bilinmeyen hak türü: \"%s\"" + +#: utils/adt/acl.c:3487 utils/adt/regproc.c:102 utils/adt/regproc.c:277 +#, c-format +msgid "function \"%s\" does not exist" +msgstr "\"%s\" fonksiyonu mevcut değil" + +#: utils/adt/acl.c:4959 +#, c-format +msgid "must be member of role \"%s\"" +msgstr "\"%s\" rolüne dahil olmalıdır" + +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5910 utils/adt/arrayfuncs.c:6221 utils/adt/arrayutils.c:93 utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 +#, c-format +msgid "array size exceeds the maximum allowed (%d)" +msgstr "dizin boyutu izin verilern en yüksek değerini (%d) aşmaktadır" + +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 utils/adt/json.c:1962 utils/adt/jsonb.c:1083 utils/adt/jsonb.c:1112 utils/adt/jsonb.c:1504 utils/adt/jsonb.c:1668 utils/adt/jsonb.c:1678 +#, c-format +msgid "could not determine input data type" +msgstr "giriş veri tipleri belirlenemedi" + +#: utils/adt/array_userfuncs.c:85 +#, fuzzy, c-format +#| msgid "target type is not an array" +msgid "input data type is not an array" +msgstr "hedef tipi array değildir" + +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1376 utils/adt/float.c:1464 utils/adt/float.c:3765 utils/adt/float.c:3779 utils/adt/int.c:755 utils/adt/int.c:777 utils/adt/int.c:791 utils/adt/int.c:805 utils/adt/int.c:836 utils/adt/int.c:857 utils/adt/int.c:974 utils/adt/int.c:988 utils/adt/int.c:1002 utils/adt/int.c:1035 +#: utils/adt/int.c:1049 utils/adt/int.c:1063 utils/adt/int.c:1094 utils/adt/int.c:1176 utils/adt/int8.c:1164 utils/adt/numeric.c:3117 utils/adt/numeric.c:3126 utils/adt/varbit.c:1173 utils/adt/varbit.c:1575 utils/adt/varlena.c:1053 utils/adt/varlena.c:2983 +#, c-format +msgid "integer out of range" +msgstr "integer sıra dışıdır" + +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 +#, c-format +msgid "argument must be empty or one-dimensional array" +msgstr "argüman boş veya tek boyutlu dizi olmalıdır" + +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 utils/adt/array_userfuncs.c:406 +#, c-format +msgid "cannot concatenate incompatible arrays" +msgstr "uyumsuz arrayları birleştirilemez" + +#: utils/adt/array_userfuncs.c:274 +#, c-format +msgid "Arrays with element types %s and %s are not compatible for concatenation." +msgstr "Öğe tipleri %s ve %s olan dizileri bitiştirmede kullanılamaz." + +#: utils/adt/array_userfuncs.c:313 +#, c-format +msgid "Arrays of %d and %d dimensions are not compatible for concatenation." +msgstr "Bitiştirmede %d ve %d boyutlu dizileri kullanılamaz." + +#: utils/adt/array_userfuncs.c:350 +#, c-format +msgid "Arrays with differing element dimensions are not compatible for concatenation." +msgstr "Bitiştirmede öğeleri farklı boyutlu olan dizileri kullanılamaz." + +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 +#, c-format +msgid "Arrays with differing dimensions are not compatible for concatenation." +msgstr "Bitiştirmede farklı boyutlu dizileri kullanılamaz." + +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 +#, fuzzy, c-format +#| msgid "multidimensional arrays are not supported" +msgid "searching for elements in multidimensional arrays is not supported" +msgstr "çok boyutlu diziler desteklenmiyor" + +#: utils/adt/array_userfuncs.c:686 +#, fuzzy, c-format +#| msgid "FOREACH expression must not be null" +msgid "initial position must not be null" +msgstr "FOREACH ifadesi NULL olamaz" + +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 +#, c-format +msgid "malformed array literal: \"%s\"" +msgstr "array literal bozuk: \"%s\"" + +#: utils/adt/arrayfuncs.c:270 +#, c-format +msgid "\"[\" must introduce explicitly-specified array dimensions." +msgstr "" + +#: utils/adt/arrayfuncs.c:284 +#, fuzzy, c-format +#| msgid "missing dimension value" +msgid "Missing array dimension value." +msgstr "boyut değeri eksik" + +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 +#, fuzzy, c-format +#| msgid "missing \"]\" in array dimensions" +msgid "Missing \"%s\" after array dimensions." +msgstr "array tanımında \"]\" eksik" + +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 +#, c-format +msgid "upper bound cannot be less than lower bound" +msgstr "üst sınır alt sınırından düşük olamaz" + +#: utils/adt/arrayfuncs.c:317 +#, fuzzy, c-format +#| msgid "array value must start with \"{\" or dimension information" +msgid "Array value must start with \"{\" or dimension information." +msgstr "array değeri ya \"{\" ile ya da boyut bilgisi ile başlamalıdır" + +#: utils/adt/arrayfuncs.c:346 +#, c-format +msgid "Array contents must start with \"{\"." +msgstr "" + +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 +#, fuzzy, c-format +#| msgid "array dimensions incompatible with array literal" +msgid "Specified array dimensions do not match array contents." +msgstr "array boyutları array değişmezi ile uyumsuz" + +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 utils/adt/rangetypes.c:2178 utils/adt/rangetypes.c:2186 utils/adt/rowtypes.c:209 utils/adt/rowtypes.c:217 +#, c-format +msgid "Unexpected end of input." +msgstr "Beklenmeyen girdi sonu." + +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 +#, fuzzy, c-format +#| msgid "unexpected \"=\"" +msgid "Unexpected \"%c\" character." +msgstr "beklenmeyen \"=\"" + +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 +#, fuzzy, c-format +#| msgid "expected a type name" +msgid "Unexpected array element." +msgstr "tür ismi beklenir" + +#: utils/adt/arrayfuncs.c:590 +#, c-format +msgid "Unmatched \"%c\" character." +msgstr "" + +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 +#, fuzzy, c-format +#| msgid "multidimensional arrays must have array expressions with matching dimensions" +msgid "Multidimensional arrays must have sub-arrays with matching dimensions." +msgstr "çok boyutlu dizinler boyut sayısı kadar dizin ifade sayısına sahip olmalıdırlar" + +#: utils/adt/arrayfuncs.c:675 +#, fuzzy, c-format +#| msgid "Junk after right parenthesis." +msgid "Junk after closing right brace." +msgstr "Sağ parantezden sonra süprüntü." + +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 utils/adt/arrayfuncs.c:5816 +#, c-format +msgid "invalid number of dimensions: %d" +msgstr "boyut sayısı geçersiz: %d" + +#: utils/adt/arrayfuncs.c:1308 +#, c-format +msgid "invalid array flags" +msgstr "array flags geçersiz" + +#: utils/adt/arrayfuncs.c:1316 +#, c-format +msgid "wrong element type" +msgstr "element tipi yanlış" + +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:334 utils/cache/lsyscache.c:2725 +#, c-format +msgid "no binary input function available for type %s" +msgstr "%s tipi için ikili giriş fonksiyonu mevcut değil" + +#: utils/adt/arrayfuncs.c:1506 +#, c-format +msgid "improper binary format in array element %d" +msgstr "%d dizi öğesi için geçersiz ikili biçimi" + +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:339 utils/cache/lsyscache.c:2758 +#, c-format +msgid "no binary output function available for type %s" +msgstr "%s tipi için ikili çıkış fonksiyonu mevcut değil" + +#: utils/adt/arrayfuncs.c:2065 +#, c-format +msgid "slices of fixed-length arrays not implemented" +msgstr "sabit-uzunluklu dizinlerin dilimleri implemente edilmemiş" + +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5802 utils/adt/arrayfuncs.c:5828 utils/adt/arrayfuncs.c:5839 utils/adt/json.c:2323 utils/adt/json.c:2398 utils/adt/jsonb.c:1282 utils/adt/jsonb.c:1368 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 +#, c-format +msgid "wrong number of array subscripts" +msgstr "array subscript sayısı yanlış" + +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 +#, c-format +msgid "array subscript out of range" +msgstr "array subscript kapsam dsışıdır" + +#: utils/adt/arrayfuncs.c:2253 +#, c-format +msgid "cannot assign null value to an element of a fixed-length array" +msgstr "sabit uzunluklu array elementine null değeri atanamaz" + +#: utils/adt/arrayfuncs.c:2808 +#, c-format +msgid "updates on slices of fixed-length arrays not implemented" +msgstr "sabit-uzunluklu dizinlerin dilimleri üzerinde update implemente edilmemiş" + +#: utils/adt/arrayfuncs.c:2839 +#, fuzzy, c-format +#| msgid "array subscript must have type integer" +msgid "array slice subscript must provide both boundaries" +msgstr "array subscript tamsyı tipinde olmalıdır" + +#: utils/adt/arrayfuncs.c:2840 +#, c-format +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." +msgstr "" + +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 +#, c-format +msgid "source array too small" +msgstr "kaynak array küçük" + +#: utils/adt/arrayfuncs.c:3499 +#, c-format +msgid "null array element not allowed in this context" +msgstr "bu ortamda null array elementi kabul edilmemektedir" + +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 utils/adt/arrayfuncs.c:4124 +#, c-format +msgid "cannot compare arrays of different element types" +msgstr "farklı öğe tipli dizinleri karşılaştırılamaz" + +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1253 utils/adt/rangetypes.c:1317 +#, fuzzy, c-format +#| msgid "could not identify a comparison function for type %s" +msgid "could not identify a hash function for type %s" +msgstr "%s tipi için karşılaştırma fonksiyonu bulunamadı" + +#: utils/adt/arrayfuncs.c:4040 +#, fuzzy, c-format +#| msgid "could not identify a comparison function for type %s" +msgid "could not identify an extended hash function for type %s" +msgstr "%s tipi için karşılaştırma fonksiyonu bulunamadı" + +#: utils/adt/arrayfuncs.c:5216 +#, fuzzy, c-format +#| msgid "target type is not an array" +msgid "data type %s is not an array type" +msgstr "hedef tipi array değildir" + +#: utils/adt/arrayfuncs.c:5271 +#, fuzzy, c-format +#| msgid "cannot concatenate incompatible arrays" +msgid "cannot accumulate null arrays" +msgstr "uyumsuz arrayları birleştirilemez" + +#: utils/adt/arrayfuncs.c:5299 +#, fuzzy, c-format +#| msgid "cannot concatenate incompatible arrays" +msgid "cannot accumulate empty arrays" +msgstr "uyumsuz arrayları birleştirilemez" + +#: utils/adt/arrayfuncs.c:5328 utils/adt/arrayfuncs.c:5334 +#, fuzzy, c-format +#| msgid "cannot compare arrays of different element types" +msgid "cannot accumulate arrays of different dimensionality" +msgstr "farklı öğe tipli dizinleri karşılaştırılamaz" + +#: utils/adt/arrayfuncs.c:5700 utils/adt/arrayfuncs.c:5740 +#, fuzzy, c-format +msgid "dimension array or low bound array cannot be null" +msgstr "oturum kullanıcısının adı değiştirilemez" + +#: utils/adt/arrayfuncs.c:5803 utils/adt/arrayfuncs.c:5829 +#, fuzzy, c-format +msgid "Dimension array must be one dimensional." +msgstr "typmod array tek boyutlu olmalıdır" + +#: utils/adt/arrayfuncs.c:5808 utils/adt/arrayfuncs.c:5834 +#, fuzzy, c-format +msgid "dimension values cannot be null" +msgstr "oturum kullanıcısının adı değiştirilemez" + +#: utils/adt/arrayfuncs.c:5840 +#, c-format +msgid "Low bound array has different size than dimensions array." +msgstr "" + +#: utils/adt/arrayfuncs.c:6086 +#, fuzzy, c-format +#| msgid "multidimensional arrays are not supported" +msgid "removing elements from multidimensional arrays is not supported" +msgstr "çok boyutlu diziler desteklenmiyor" + +#: utils/adt/arrayfuncs.c:6363 +#, fuzzy, c-format +#| msgid "argument must be empty or one-dimensional array" +msgid "thresholds must be one-dimensional array" +msgstr "argüman boş veya tek boyutlu dizi olmalıdır" + +#: utils/adt/arrayfuncs.c:6368 +#, fuzzy, c-format +#| msgid "typmod array must not contain nulls" +msgid "thresholds array must not contain NULLs" +msgstr "typmod array null kayıtları içeremez" + +#: utils/adt/arrayutils.c:209 +#, fuzzy, c-format +msgid "typmod array must be type cstring[]" +msgstr "typmod array tamsyı tipinde olmalıdır" + +#: utils/adt/arrayutils.c:214 +#, c-format +msgid "typmod array must be one-dimensional" +msgstr "typmod array tek boyutlu olmalıdır" + +#: utils/adt/arrayutils.c:219 +#, c-format +msgid "typmod array must not contain nulls" +msgstr "typmod array null kayıtları içeremez" + +#: utils/adt/ascii.c:76 +#, c-format +msgid "encoding conversion from %s to ASCII not supported" +msgstr "%s karakter tipinden ASCII karakter tipine dönüştürme desteklenmiyor" + +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3788 utils/adt/float.c:241 utils/adt/float.c:315 utils/adt/float.c:339 utils/adt/float.c:458 utils/adt/float.c:541 utils/adt/float.c:567 utils/adt/geo_ops.c:155 utils/adt/geo_ops.c:165 utils/adt/geo_ops.c:177 utils/adt/geo_ops.c:209 utils/adt/geo_ops.c:254 utils/adt/geo_ops.c:264 utils/adt/geo_ops.c:934 +#: utils/adt/geo_ops.c:1320 utils/adt/geo_ops.c:1355 utils/adt/geo_ops.c:1363 utils/adt/geo_ops.c:3429 utils/adt/geo_ops.c:4562 utils/adt/geo_ops.c:4578 utils/adt/geo_ops.c:4585 utils/adt/mac.c:94 utils/adt/mac8.c:93 utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 utils/adt/mac8.c:221 utils/adt/nabstime.c:1542 utils/adt/network.c:58 utils/adt/numeric.c:604 +#: utils/adt/numeric.c:631 utils/adt/numeric.c:5662 utils/adt/numeric.c:5686 utils/adt/numeric.c:5710 utils/adt/numeric.c:6516 utils/adt/numeric.c:6542 utils/adt/oid.c:44 utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:50 utils/adt/tid.c:72 utils/adt/tid.c:80 utils/adt/tid.c:88 utils/adt/txid.c:405 utils/adt/uuid.c:136 +#, c-format +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "%s tipi için geçersiz giriş sözdizimi: \"%s\"" + +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 utils/adt/cash.c:290 utils/adt/int8.c:117 utils/adt/numutils.c:75 utils/adt/numutils.c:82 utils/adt/oid.c:70 utils/adt/oid.c:109 +#, fuzzy, c-format +#| msgid "value \"%s\" is out of range for type oid" +msgid "value \"%s\" is out of range for type %s" +msgstr "oid tipi için \"%s\" değeri sıra dışıdır" + +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 utils/adt/float.c:852 utils/adt/float.c:916 utils/adt/float.c:3526 utils/adt/float.c:3589 utils/adt/geo_ops.c:4092 utils/adt/int.c:820 utils/adt/int.c:936 utils/adt/int.c:1016 utils/adt/int.c:1078 utils/adt/int.c:1116 utils/adt/int.c:1144 utils/adt/int8.c:592 +#: utils/adt/int8.c:650 utils/adt/int8.c:850 utils/adt/int8.c:930 utils/adt/int8.c:992 utils/adt/int8.c:1072 utils/adt/numeric.c:7080 utils/adt/numeric.c:7369 utils/adt/numeric.c:8381 utils/adt/timestamp.c:3238 +#, c-format +msgid "division by zero" +msgstr "sıfırla bölüm" + +#: utils/adt/char.c:169 +#, c-format +msgid "\"char\" out of range" +msgstr "\"char\" sıra dışıdır" + +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:54 utils/adt/varchar.c:46 +#, c-format +msgid "invalid type modifier" +msgstr "tip belirteci geçersiz" + +#: utils/adt/date.c:77 +#, c-format +msgid "TIME(%d)%s precision must not be negative" +msgstr "TIME(%d)%s kesinliği sıfırdan küçük olamaz" + +#: utils/adt/date.c:83 +#, c-format +msgid "TIME(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIME(%d)%s kesinliği en yüksek değerine (%d) kadar düşürüldü" + +#: utils/adt/date.c:144 utils/adt/datetime.c:1193 utils/adt/datetime.c:2104 +#, c-format +msgid "date/time value \"current\" is no longer supported" +msgstr "\"current\" tarih/saat değeri artık desteklenmiyor" + +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3606 utils/adt/formatting.c:3615 +#, c-format +msgid "date out of range: \"%s\"" +msgstr "date kapsam dışıdır: \"%s\"" + +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 utils/adt/xml.c:2089 +#, c-format +msgid "date out of range" +msgstr "date kapsam dışı" + +#: utils/adt/date.c:271 utils/adt/timestamp.c:564 +#, fuzzy, c-format +#| msgid "date/time field value out of range: \"%s\"" +msgid "date field value out of range: %d-%02d-%02d" +msgstr "date/time alan değieri kapsam dışıdır: \"%s\"" + +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:570 +#, fuzzy, c-format +#| msgid "date out of range: \"%s\"" +msgid "date out of range: %d-%02d-%02d" +msgstr "date kapsam dışıdır: \"%s\"" + +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1704 utils/adt/date.c:1735 utils/adt/date.c:1764 utils/adt/date.c:2596 utils/adt/datetime.c:1677 utils/adt/formatting.c:3472 utils/adt/formatting.c:3504 utils/adt/formatting.c:3581 utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/nabstime.c:459 +#: utils/adt/nabstime.c:502 utils/adt/nabstime.c:532 utils/adt/nabstime.c:575 utils/adt/timestamp.c:230 utils/adt/timestamp.c:262 utils/adt/timestamp.c:692 utils/adt/timestamp.c:701 utils/adt/timestamp.c:779 utils/adt/timestamp.c:812 utils/adt/timestamp.c:2817 utils/adt/timestamp.c:2838 utils/adt/timestamp.c:2851 utils/adt/timestamp.c:2860 utils/adt/timestamp.c:2868 +#: utils/adt/timestamp.c:2923 utils/adt/timestamp.c:2946 utils/adt/timestamp.c:2959 utils/adt/timestamp.c:2970 utils/adt/timestamp.c:2978 utils/adt/timestamp.c:3638 utils/adt/timestamp.c:3763 utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3894 utils/adt/timestamp.c:3940 utils/adt/timestamp.c:4043 utils/adt/timestamp.c:4450 utils/adt/timestamp.c:4549 utils/adt/timestamp.c:4559 +#: utils/adt/timestamp.c:4651 utils/adt/timestamp.c:4753 utils/adt/timestamp.c:4763 utils/adt/timestamp.c:4995 utils/adt/timestamp.c:5009 utils/adt/timestamp.c:5014 utils/adt/timestamp.c:5028 utils/adt/timestamp.c:5073 utils/adt/timestamp.c:5105 utils/adt/timestamp.c:5112 utils/adt/timestamp.c:5145 utils/adt/timestamp.c:5149 utils/adt/timestamp.c:5218 utils/adt/timestamp.c:5222 +#: utils/adt/timestamp.c:5236 utils/adt/timestamp.c:5270 utils/adt/xml.c:2111 utils/adt/xml.c:2118 utils/adt/xml.c:2138 utils/adt/xml.c:2145 +#, c-format +msgid "timestamp out of range" +msgstr "timestamp sıra dışıdır" + +#: utils/adt/date.c:512 +#, fuzzy, c-format +msgid "cannot subtract infinite dates" +msgstr "sonsuz timestap veri tipi üzerinde çıkarma işlemi yapılamaz" + +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 utils/adt/date.c:2633 utils/adt/date.c:2643 +#, c-format +msgid "date out of range for timestamp" +msgstr "timestamp için tarih aralık dışıdır" + +#: utils/adt/date.c:1190 +#, c-format +msgid "cannot convert reserved abstime value to date" +msgstr "ayrılmış abstime değeri tarihe çevrilemez" + +#: utils/adt/date.c:1208 utils/adt/date.c:1214 +#, fuzzy, c-format +#| msgid "date out of range for timestamp" +msgid "abstime out of range for date" +msgstr "timestamp için tarih aralık dışıdır" + +#: utils/adt/date.c:1327 utils/adt/date.c:2091 +#, c-format +msgid "time out of range" +msgstr "time kapsam dışı" + +#: utils/adt/date.c:1383 utils/adt/timestamp.c:589 +#, fuzzy, c-format +#| msgid "date/time field value out of range: \"%s\"" +msgid "time field value out of range: %d:%02d:%02g" +msgstr "date/time alan değieri kapsam dışıdır: \"%s\"" + +#: utils/adt/date.c:1893 utils/adt/date.c:2395 utils/adt/float.c:1202 utils/adt/float.c:1271 utils/adt/int.c:612 utils/adt/int.c:659 utils/adt/int.c:694 utils/adt/int8.c:491 utils/adt/numeric.c:2189 utils/adt/timestamp.c:3287 utils/adt/timestamp.c:3318 utils/adt/timestamp.c:3349 +#, fuzzy, c-format +#| msgid "window functions are not allowed in window definitions" +msgid "invalid preceding or following size in window function" +msgstr "window tanımlarında window fonksiyonlarına izin erilmez" + +#: utils/adt/date.c:1978 utils/adt/date.c:1991 +#, c-format +msgid "\"time\" units \"%s\" not recognized" +msgstr "\"time\" birimi \"%s\" tanınmadı" + +#: utils/adt/date.c:2099 +#, fuzzy, c-format +msgid "time zone displacement out of range" +msgstr "yer değiştirme değeri kapsam dışında: \"%s\"" + +#: utils/adt/date.c:2728 utils/adt/date.c:2741 +#, c-format +msgid "\"time with time zone\" units \"%s\" not recognized" +msgstr "\"%s\" birimi \"time with time zone\" veri tipi için tanımlı değildir" + +#: utils/adt/date.c:2814 utils/adt/datetime.c:915 utils/adt/datetime.c:1835 utils/adt/datetime.c:4625 utils/adt/timestamp.c:503 utils/adt/timestamp.c:530 utils/adt/timestamp.c:5020 utils/adt/timestamp.c:5228 +#, c-format +msgid "time zone \"%s\" not recognized" +msgstr "time zone \"%s\" tanınmadı" + +#: utils/adt/date.c:2846 utils/adt/timestamp.c:5062 utils/adt/timestamp.c:5259 +#, fuzzy, c-format +#| msgid "interval time zone \"%s\" must not specify month" +msgid "interval time zone \"%s\" must not include months or days" +msgstr "\"%s\" interval time zone ayı belirtmemelidir" + +#: utils/adt/datetime.c:3761 utils/adt/datetime.c:3768 +#, c-format +msgid "date/time field value out of range: \"%s\"" +msgstr "date/time alan değieri kapsam dışıdır: \"%s\"" + +#: utils/adt/datetime.c:3770 +#, c-format +msgid "Perhaps you need a different \"datestyle\" setting." +msgstr "Mutemelen farklı \"datestyle\" ayarınıza gerek var." + +#: utils/adt/datetime.c:3775 +#, c-format +msgid "interval field value out of range: \"%s\"" +msgstr "interval alan değeri kapsam dışında: \"%s\"" + +#: utils/adt/datetime.c:3781 +#, c-format +msgid "time zone displacement out of range: \"%s\"" +msgstr "yer değiştirme değeri kapsam dışında: \"%s\"" + +#: utils/adt/datetime.c:4627 +#, c-format +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." +msgstr "" + +#: utils/adt/datum.c:86 utils/adt/datum.c:98 +#, c-format +msgid "invalid Datum pointer" +msgstr "geçersiz Datum pointer" + +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 +#, fuzzy, c-format +#| msgid "invalid cidr value: \"%s\"" +msgid "invalid size: \"%s\"" +msgstr "cidr değeri geçersiz: \"%s\"" + +#: utils/adt/dbsize.c:828 +#, fuzzy, c-format +#| msgid "invalid time zone name: \"%s\"" +msgid "Invalid size unit: \"%s\"." +msgstr "geçersiz zaman dilimi adı: \"%s\"" + +#: utils/adt/dbsize.c:829 +#, fuzzy, c-format +#| msgid "Valid units for this parameter are \"kB\", \"MB\", and \"GB\"." +msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Bu parametre için geçerli birimler \"kB\", \"MB\" ve \"GB\" 'dır." + +#: utils/adt/domains.c:92 +#, c-format +msgid "type %s is not a domain" +msgstr "%s tipi bir domain değildir" + +#: utils/adt/encode.c:55 utils/adt/encode.c:91 +#, c-format +msgid "unrecognized encoding: \"%s\"" +msgstr "tanınmayan kodlama adı \"%s\"" + +#: utils/adt/encode.c:150 +#, c-format +msgid "invalid hexadecimal digit: \"%c\"" +msgstr "onaltılık rakam \"%c\" geçersiz" + +#: utils/adt/encode.c:178 +#, c-format +msgid "invalid hexadecimal data: odd number of digits" +msgstr "geçersiz hexadecimal veri: rakam sayısı tektir" + +#: utils/adt/encode.c:295 +#, c-format +msgid "unexpected \"=\" while decoding base64 sequence" +msgstr "" + +#: utils/adt/encode.c:307 +#, fuzzy, c-format +#| msgid "invalid source encoding name \"%s\"" +msgid "invalid symbol \"%c\" while decoding base64 sequence" +msgstr "geçersiz kaynak dil kodlaması adı \"%s\"" + +#: utils/adt/encode.c:327 +#, fuzzy, c-format +#| msgid "invalid end sequence" +msgid "invalid base64 end sequence" +msgstr "geçersiz end sequence" + +#: utils/adt/encode.c:328 +#, c-format +msgid "Input data is missing padding, is truncated, or is otherwise corrupted." +msgstr "" + +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:296 utils/adt/varlena.c:337 +#, fuzzy, c-format +#| msgid "invalid input syntax for type %s: \"%s\"" +msgid "invalid input syntax for type %s" +msgstr "%s tipi için geçersiz giriş sözdizimi: \"%s\"" + +#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 utils/adt/enum.c:123 +#, c-format +msgid "invalid input value for enum %s: \"%s\"" +msgstr "%s enum tipi için geçersiz değer: \"%s\"" + +#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:207 +#, c-format +msgid "invalid internal value for enum: %u" +msgstr "enum için geçersiz iç değer: %u" + +#: utils/adt/enum.c:360 utils/adt/enum.c:389 utils/adt/enum.c:429 utils/adt/enum.c:449 +#, c-format +msgid "could not determine actual enum type" +msgstr "gerçek enum veri tipli belirlenemiyor" + +#: utils/adt/enum.c:368 utils/adt/enum.c:397 +#, fuzzy, c-format +#| msgid "column \"%s\" contains null values" +msgid "enum %s contains no values" +msgstr "\"%s\" sütunu null değerleri içermektedir" + +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 utils/cache/typcache.c:1563 utils/cache/typcache.c:1719 utils/cache/typcache.c:1849 utils/fmgr/funcapi.c:430 +#, c-format +msgid "type %s is not composite" +msgstr "%s tipi composite değildir" + +#: utils/adt/float.c:55 +#, c-format +msgid "value out of range: overflow" +msgstr "değer kapsam dışıdır: overflow" + +#: utils/adt/float.c:60 +#, c-format +msgid "value out of range: underflow" +msgstr "değer kapsam dışıdır: underflow" + +#: utils/adt/float.c:309 +#, c-format +msgid "\"%s\" is out of range for type real" +msgstr "real tipi için kapsam dışı bir değer \"%s\"" + +#: utils/adt/float.c:534 +#, c-format +msgid "\"%s\" is out of range for type double precision" +msgstr "double precision tipi için kapsam dışı bir değer \"%s\"" + +#: utils/adt/float.c:1408 utils/adt/float.c:1496 utils/adt/int.c:332 utils/adt/int.c:870 utils/adt/int.c:892 utils/adt/int.c:906 utils/adt/int.c:920 utils/adt/int.c:952 utils/adt/int.c:1190 utils/adt/int8.c:1185 utils/adt/numeric.c:3214 utils/adt/numeric.c:3223 +#, c-format +msgid "smallint out of range" +msgstr "smallint sıra dışıdır" + +#: utils/adt/float.c:1622 utils/adt/numeric.c:7802 +#, c-format +msgid "cannot take square root of a negative number" +msgstr "sıfırdan küçük sayıdan kare kökü alınamaz" + +#: utils/adt/float.c:1683 utils/adt/numeric.c:3017 +#, fuzzy, c-format +msgid "zero raised to a negative power is undefined" +msgstr "sıfırın sıfır katı belirsiz" + +#: utils/adt/float.c:1687 utils/adt/numeric.c:3023 +#, c-format +msgid "a negative number raised to a non-integer power yields a complex result" +msgstr "" + +#: utils/adt/float.c:1753 utils/adt/float.c:1783 utils/adt/numeric.c:8068 +#, c-format +msgid "cannot take logarithm of zero" +msgstr "sıfırın logaritması hesaplanamaz" + +#: utils/adt/float.c:1757 utils/adt/float.c:1787 utils/adt/numeric.c:8072 +#, c-format +msgid "cannot take logarithm of a negative number" +msgstr "sıfırdan küçük sayıdan logaritması alınamaz" + +#: utils/adt/float.c:1817 utils/adt/float.c:1847 utils/adt/float.c:1939 utils/adt/float.c:1965 utils/adt/float.c:1992 utils/adt/float.c:2018 utils/adt/float.c:2165 utils/adt/float.c:2200 utils/adt/float.c:2364 utils/adt/float.c:2418 utils/adt/float.c:2482 utils/adt/float.c:2537 +#, c-format +msgid "input is out of range" +msgstr "giriş sıra dısışıdır" + +#: utils/adt/float.c:3743 utils/adt/numeric.c:1504 +#, c-format +msgid "count must be greater than zero" +msgstr "sayısı sıfırdan büyük olmalı" + +#: utils/adt/float.c:3748 utils/adt/numeric.c:1511 +#, fuzzy, c-format +#| msgid "operand, lower bound and upper bound cannot be NaN" +msgid "operand, lower bound, and upper bound cannot be NaN" +msgstr "işlenenin alt ve üst sınırı NaN olamaz" + +#: utils/adt/float.c:3754 +#, c-format +msgid "lower and upper bounds must be finite" +msgstr "alt ve üst sınırları sonsuz olamaz" + +#: utils/adt/float.c:3788 utils/adt/numeric.c:1524 +#, c-format +msgid "lower bound cannot equal upper bound" +msgstr "alt sınır üst sınırı ile eşit olamaz" + +#: utils/adt/formatting.c:488 +#, c-format +msgid "invalid format specification for an interval value" +msgstr "interval değer biçimi yanlış" + +#: utils/adt/formatting.c:489 +#, c-format +msgid "Intervals are not tied to specific calendar dates." +msgstr "interval belli takvim tarihlerine bağlı değildir." + +#: utils/adt/formatting.c:1059 +#, c-format +msgid "\"EEEE\" must be the last pattern used" +msgstr "" + +#: utils/adt/formatting.c:1067 +#, c-format +msgid "\"9\" must be ahead of \"PR\"" +msgstr "\"9\", \"PR\"'dan önce olmalıdır" + +#: utils/adt/formatting.c:1083 +#, c-format +msgid "\"0\" must be ahead of \"PR\"" +msgstr "\"0\", \"PR\"'dan önce olmalıdır" + +#: utils/adt/formatting.c:1110 +#, c-format +msgid "multiple decimal points" +msgstr "birden fazla ondalık ayraç" + +#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 +#, c-format +msgid "cannot use \"V\" and decimal point together" +msgstr "\"V\" ve ondalık virgül bir arada kullanılamaz" + +#: utils/adt/formatting.c:1126 +#, fuzzy, c-format +msgid "cannot use \"S\" twice" +msgstr "\"S\" ve \"MI\" birlikte kullanılamaz" + +#: utils/adt/formatting.c:1130 +#, c-format +msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" +msgstr "\"S\" ve \"PL\"/\"MI\"/\"SG\"/\"PR\" bir arada kullanılamaz" + +#: utils/adt/formatting.c:1150 +#, c-format +msgid "cannot use \"S\" and \"MI\" together" +msgstr "\"S\" ve \"MI\" birlikte kullanılamaz" + +#: utils/adt/formatting.c:1160 +#, c-format +msgid "cannot use \"S\" and \"PL\" together" +msgstr "\"S\" ve \"PL\" birlikte kullanılamaz" + +#: utils/adt/formatting.c:1170 +#, c-format +msgid "cannot use \"S\" and \"SG\" together" +msgstr "\"S\" ve \"SG\" birlikte kullanılamaz" + +#: utils/adt/formatting.c:1179 +#, c-format +msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" +msgstr "\"PR\" ve \"S\"/\"PL\"/\"MI\"/\"SG\" bir arada kullanılamaz" + +#: utils/adt/formatting.c:1205 +#, c-format +msgid "cannot use \"EEEE\" twice" +msgstr "\"EEEE\" iki defa kullanılamaz" + +#: utils/adt/formatting.c:1211 +#, c-format +msgid "\"EEEE\" is incompatible with other formats" +msgstr "" + +#: utils/adt/formatting.c:1212 +#, c-format +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." +msgstr "" + +#: utils/adt/formatting.c:1392 +#, c-format +msgid "\"%s\" is not a number" +msgstr "\"%s\" bir sayı değildir" + +#: utils/adt/formatting.c:1470 +#, fuzzy, c-format +#| msgid "regular expression failed: %s" +msgid "case conversion failed: %s" +msgstr "regular expression başarısız: %s" + +#: utils/adt/formatting.c:1535 +#, fuzzy, c-format +#| msgid "could not determine actual return type for polymorphic function \"%s\"" +msgid "could not determine which collation to use for lower() function" +msgstr "\"%s\" polimorfik fonksiyonunun asıl dönüşdeğeri belirlenemedi" + +#: utils/adt/formatting.c:1657 +#, fuzzy, c-format +#| msgid "could not determine actual return type for polymorphic function \"%s\"" +msgid "could not determine which collation to use for upper() function" +msgstr "\"%s\" polimorfik fonksiyonunun asıl dönüşdeğeri belirlenemedi" + +#: utils/adt/formatting.c:1780 +#, fuzzy, c-format +#| msgid "could not determine actual return type for polymorphic function \"%s\"" +msgid "could not determine which collation to use for initcap() function" +msgstr "\"%s\" polimorfik fonksiyonunun asıl dönüşdeğeri belirlenemedi" + +#: utils/adt/formatting.c:2148 +#, fuzzy, c-format +msgid "invalid combination of date conventions" +msgstr "geçersiz bağlantı seçeneği \"%s\"\n" + +#: utils/adt/formatting.c:2149 +#, c-format +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." +msgstr "" + +#: utils/adt/formatting.c:2166 +#, c-format +msgid "conflicting values for \"%s\" field in formatting string" +msgstr "" + +#: utils/adt/formatting.c:2168 +#, c-format +msgid "This value contradicts a previous setting for the same field type." +msgstr "" + +#: utils/adt/formatting.c:2229 +#, c-format +msgid "source string too short for \"%s\" formatting field" +msgstr "" + +#: utils/adt/formatting.c:2231 +#, c-format +msgid "Field requires %d characters, but only %d remain." +msgstr "Alan %d karakter gerektiriyor, ama %d kaldı." + +#: utils/adt/formatting.c:2234 utils/adt/formatting.c:2248 +#, c-format +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." +msgstr "" + +#: utils/adt/formatting.c:2244 utils/adt/formatting.c:2257 utils/adt/formatting.c:2387 +#, fuzzy, c-format +msgid "invalid value \"%s\" for \"%s\"" +msgstr "%s için geçersiz değer" + +#: utils/adt/formatting.c:2246 +#, c-format +msgid "Field requires %d characters, but only %d could be parsed." +msgstr "" + +#: utils/adt/formatting.c:2259 +#, c-format +msgid "Value must be an integer." +msgstr "Değer tamsayı olmalıdır." + +#: utils/adt/formatting.c:2264 +#, fuzzy, c-format +msgid "value for \"%s\" in source string is out of range" +msgstr "oid tipi için \"%s\" değeri sıra dışıdır" + +#: utils/adt/formatting.c:2266 +#, c-format +msgid "Value must be in the range %d to %d." +msgstr "Değer %d ile %d arasında olmalı." + +#: utils/adt/formatting.c:2389 +#, c-format +msgid "The given value did not match any of the allowed values for this field." +msgstr "" + +#: utils/adt/formatting.c:2587 utils/adt/formatting.c:2607 utils/adt/formatting.c:2627 utils/adt/formatting.c:2647 utils/adt/formatting.c:2666 utils/adt/formatting.c:2685 utils/adt/formatting.c:2709 utils/adt/formatting.c:2727 utils/adt/formatting.c:2745 utils/adt/formatting.c:2763 utils/adt/formatting.c:2780 utils/adt/formatting.c:2797 +#, fuzzy, c-format +msgid "localized string format value too long" +msgstr "operator fazla uzun" + +#: utils/adt/formatting.c:3084 +#, c-format +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "" + +#: utils/adt/formatting.c:3209 +#, fuzzy, c-format +msgid "invalid input string for \"Y,YYY\"" +msgstr "uuid tipi için geçersiz söz dizimi: \"%s\"" + +#: utils/adt/formatting.c:3724 +#, c-format +msgid "hour \"%d\" is invalid for the 12-hour clock" +msgstr "\"%d\" saati 12-saat formatı için geçersiz" + +#: utils/adt/formatting.c:3726 +#, c-format +msgid "Use the 24-hour clock, or give an hour between 1 and 12." +msgstr "Ya 24-saat modunu kullanın, ya da 1-12 arasında bir saat verin." + +#: utils/adt/formatting.c:3832 +#, c-format +msgid "cannot calculate day of year without year information" +msgstr "yıl bilgisi olmadan yılın günü hesaplanamaz" + +#: utils/adt/formatting.c:4737 +#, fuzzy, c-format +msgid "\"EEEE\" not supported for input" +msgstr "\"E\" desteklenmiyor" + +#: utils/adt/formatting.c:4749 +#, fuzzy, c-format +msgid "\"RN\" not supported for input" +msgstr "\"RN\" desteklenmiyor" + +#: utils/adt/genfile.c:79 +#, c-format +msgid "reference to parent directory (\"..\") not allowed" +msgstr "(\"..\") ile üst dizin referansı yapılamaz" + +#: utils/adt/genfile.c:90 +#, c-format +msgid "absolute path not allowed" +msgstr "absolute path kullanılamaz" + +#: utils/adt/genfile.c:95 +#, c-format +msgid "path must be in or below the current directory" +msgstr "" + +#: utils/adt/genfile.c:142 utils/adt/oracle_compat.c:185 utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 utils/adt/oracle_compat.c:1054 +#, c-format +msgid "requested length too large" +msgstr "istenen uzunluk çok büyük" + +#: utils/adt/genfile.c:159 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "\"%s\" dosyası ilerleme hatası: %m" + +#: utils/adt/genfile.c:219 +#, fuzzy, c-format +#| msgid "must be superuser to read files" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "dosyaları okumak için superuser olmalısınız" + +#: utils/adt/genfile.c:220 +#, fuzzy, c-format +#| msgid "Consider using tablespaces instead." +msgid "Consider using pg_file_read(), which is part of core, instead." +msgstr "Onun yerine tablespace kullanabilirsiniz." + +#: utils/adt/geo_ops.c:939 +#, fuzzy, c-format +#| msgid "interval specification not allowed here" +msgid "invalid line specification: A and B cannot both be zero" +msgstr "aralık belirtimine burada izin verilmiyor" + +#: utils/adt/geo_ops.c:947 +#, c-format +msgid "invalid line specification: must be two distinct points" +msgstr "" + +#: utils/adt/geo_ops.c:1341 utils/adt/geo_ops.c:3439 utils/adt/geo_ops.c:4252 utils/adt/geo_ops.c:5180 +#, c-format +msgid "too many points requested" +msgstr "sayı içindeki ondalık nokta sayısı çok fazla" + +#: utils/adt/geo_ops.c:1403 +#, c-format +msgid "invalid number of points in external \"path\" value" +msgstr "dış \"path\" değerinde geçersiz nokta sayısı" + +#: utils/adt/geo_ops.c:2554 +#, c-format +msgid "function \"dist_lb\" not implemented" +msgstr "\"dist_lb\" fonksiyonu implemente edilmemiştir" + +#: utils/adt/geo_ops.c:3014 +#, fuzzy, c-format +#| msgid "function \"close_lb\" not implemented" +msgid "function \"close_sl\" not implemented" +msgstr "\"close_lb\" fonksiyonu implemente edilmemiştir" + +#: utils/adt/geo_ops.c:3116 +#, c-format +msgid "function \"close_lb\" not implemented" +msgstr "\"close_lb\" fonksiyonu implemente edilmemiştir" + +#: utils/adt/geo_ops.c:3405 +#, c-format +msgid "cannot create bounding box for empty polygon" +msgstr "boş polygon için bounding box oluşturulamaz" + +#: utils/adt/geo_ops.c:3486 +#, c-format +msgid "invalid number of points in external \"polygon\" value" +msgstr "dış \"polygon\" değerinde geçersiz nokta sayısı" + +#: utils/adt/geo_ops.c:4011 +#, c-format +msgid "function \"poly_distance\" not implemented" +msgstr "\"poly_distance\" fonksiyonu implement edilmemiş" + +#: utils/adt/geo_ops.c:4364 +#, c-format +msgid "function \"path_center\" not implemented" +msgstr "\"path_center\" fonksiyonu implement edilmemiş" + +#: utils/adt/geo_ops.c:4381 +#, c-format +msgid "open path cannot be converted to polygon" +msgstr "open path, polygon veri tipine dönüştürülemez" + +#: utils/adt/geo_ops.c:4630 +#, c-format +msgid "invalid radius in external \"circle\" value" +msgstr "\"circle\" değerin dış yarıçap değeri geçersiz" + +#: utils/adt/geo_ops.c:5166 +#, c-format +msgid "cannot convert circle with radius zero to polygon" +msgstr "yarıçapı sıfır olan daire polygon'a çevrilemez" + +#: utils/adt/geo_ops.c:5171 +#, c-format +msgid "must request at least 2 points" +msgstr "en az iki nokta istemelidir" + +#: utils/adt/geo_ops.c:5215 +#, c-format +msgid "cannot convert empty polygon to circle" +msgstr "boş polygon daireye çevrilemez" + +#: utils/adt/int.c:160 +#, c-format +msgid "int2vector has too many elements" +msgstr "int2vector çok fazla öğesine sahip" + +#: utils/adt/int.c:235 +#, c-format +msgid "invalid int2vector data" +msgstr "geçersiz int2vector verisi" + +#: utils/adt/int.c:241 utils/adt/oid.c:215 utils/adt/oid.c:296 +#, c-format +msgid "oidvector has too many elements" +msgstr "oidvector çok fazla öğesine sahiptir" + +#: utils/adt/int.c:1379 utils/adt/int8.c:1325 utils/adt/numeric.c:1412 utils/adt/timestamp.c:5321 utils/adt/timestamp.c:5402 +#, c-format +msgid "step size cannot equal zero" +msgstr "step boyutu sıfır olamaz" + +#: utils/adt/int8.c:125 utils/adt/numutils.c:51 utils/adt/numutils.c:61 utils/adt/numutils.c:105 +#, c-format +msgid "invalid input syntax for integer: \"%s\"" +msgstr "integer için geçersiz sözdizimi:\"%s\"" + +#: utils/adt/int8.c:526 utils/adt/int8.c:549 utils/adt/int8.c:563 utils/adt/int8.c:577 utils/adt/int8.c:608 utils/adt/int8.c:632 utils/adt/int8.c:687 utils/adt/int8.c:701 utils/adt/int8.c:725 utils/adt/int8.c:738 utils/adt/int8.c:807 utils/adt/int8.c:821 utils/adt/int8.c:835 utils/adt/int8.c:866 utils/adt/int8.c:888 utils/adt/int8.c:902 utils/adt/int8.c:916 utils/adt/int8.c:949 +#: utils/adt/int8.c:963 utils/adt/int8.c:977 utils/adt/int8.c:1008 utils/adt/int8.c:1030 utils/adt/int8.c:1044 utils/adt/int8.c:1058 utils/adt/int8.c:1227 utils/adt/int8.c:1269 utils/adt/numeric.c:3169 utils/adt/varbit.c:1655 +#, c-format +msgid "bigint out of range" +msgstr "biginit değeri sıra dışıdır" + +#: utils/adt/int8.c:1282 +#, c-format +msgid "OID out of range" +msgstr "OID kapsam dışıdır" + +#: utils/adt/json.c:787 +#, c-format +msgid "Character with value 0x%02x must be escaped." +msgstr "" + +#: utils/adt/json.c:828 +#, fuzzy, c-format +#| msgid "\"%c\" is not a valid hexadecimal digit" +msgid "\"\\u\" must be followed by four hexadecimal digits." +msgstr "\"%c\" geçerli bir onaltılı rakamı değildir" + +#: utils/adt/json.c:844 +#, c-format +msgid "Unicode high surrogate must not follow a high surrogate." +msgstr "" + +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 utils/adt/json.c:979 utils/adt/json.c:991 +#, c-format +msgid "Unicode low surrogate must follow a high surrogate." +msgstr "" + +#: utils/adt/json.c:880 utils/adt/json.c:903 +#, fuzzy, c-format +msgid "unsupported Unicode escape sequence" +msgstr "geçersiz end sequence" + +#: utils/adt/json.c:881 +#, fuzzy, c-format +#| msgid "open path cannot be converted to polygon" +msgid "\\u0000 cannot be converted to text." +msgstr "open path, polygon veri tipine dönüştürülemez" + +#: utils/adt/json.c:904 +#, c-format +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." +msgstr "" + +#: utils/adt/json.c:949 utils/adt/json.c:967 +#, c-format +msgid "Escape sequence \"\\%s\" is invalid." +msgstr "" + +#: utils/adt/json.c:1136 +#, c-format +msgid "The input string ended unexpectedly." +msgstr "" + +#: utils/adt/json.c:1150 +#, fuzzy, c-format +#| msgid "Unexpected end of input." +msgid "Expected end of input, but found \"%s\"." +msgstr "Beklenmeyen girdi sonu." + +#: utils/adt/json.c:1161 +#, fuzzy, c-format +#| msgid "expected \"@\", found \"%s\"" +msgid "Expected JSON value, but found \"%s\"." +msgstr "\"@\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1169 utils/adt/json.c:1217 +#, fuzzy, c-format +#| msgid "expected \"@\", found \"%s\"" +msgid "Expected string, but found \"%s\"." +msgstr "\"@\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1177 +#, fuzzy, c-format +#| msgid "expected \"@\" or \"://\", found \"%s\"" +msgid "Expected array element or \"]\", but found \"%s\"." +msgstr "\"@\" or \"://\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1185 +#, fuzzy, c-format +#| msgid "expected \"@\" or \"://\", found \"%s\"" +msgid "Expected \",\" or \"]\", but found \"%s\"." +msgstr "\"@\" or \"://\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1193 +#, fuzzy, c-format +#| msgid "expected \"@\" or \"://\", found \"%s\"" +msgid "Expected string or \"}\", but found \"%s\"." +msgstr "\"@\" or \"://\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1201 +#, fuzzy, c-format +#| msgid "expected \"://\", found \"%s\"" +msgid "Expected \":\", but found \"%s\"." +msgstr "\"://\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1209 +#, fuzzy, c-format +#| msgid "expected \"@\" or \"://\", found \"%s\"" +msgid "Expected \",\" or \"}\", but found \"%s\"." +msgstr "\"@\" or \"://\" bekleniyordu; \"%s\" bulundu" + +#: utils/adt/json.c:1247 +#, fuzzy, c-format +#| msgid "File \"%s\" is missing." +msgid "Token \"%s\" is invalid." +msgstr "\"%s\" dosyası eksik." + +#: utils/adt/json.c:1319 +#, fuzzy, c-format +#| msgid "COPY %s, line %d: \"%s\"" +msgid "JSON data, line %d: %s%s%s" +msgstr "COPY %s, satır %d: \"%s\"" + +#: utils/adt/json.c:1475 utils/adt/jsonb.c:728 +#, c-format +msgid "key value must be scalar, not array, composite, or json" +msgstr "" + +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1564 +#, fuzzy, c-format +#| msgid "could not determine data type of parameter $%d" +msgid "could not determine data type for argument %d" +msgstr "$%d parametrenin veri tipini belirlenemiyor" + +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1694 +#, fuzzy, c-format +msgid "field name must not be null" +msgstr "\"%s\" sütunu mevcut değil" + +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1146 +#, fuzzy, c-format +#| msgid "each %s query must have the same number of columns" +msgid "argument list must have even number of elements" +msgstr "her %s sorgusu ayını sütun sayısına sahip olmalıdır" + +#: utils/adt/json.c:2195 +#, c-format +msgid "The arguments of json_build_object() must consist of alternating keys and values." +msgstr "" + +#: utils/adt/json.c:2210 +#, fuzzy, c-format +msgid "argument %d cannot be null" +msgstr "oturum kullanıcısının adı değiştirilemez" + +#: utils/adt/json.c:2211 +#, c-format +msgid "Object keys should be text." +msgstr "" + +#: utils/adt/json.c:2317 utils/adt/jsonb.c:1276 +#, fuzzy, c-format +#| msgid "view must have at least one column" +msgid "array must have two columns" +msgstr "viewda en az bir sütun olmalıdır" + +#: utils/adt/json.c:2341 utils/adt/json.c:2425 utils/adt/jsonb.c:1300 utils/adt/jsonb.c:1395 +#, fuzzy, c-format +#| msgid "null array element not allowed in this context" +msgid "null value not allowed for object key" +msgstr "bu ortamda null array elementi kabul edilmemektedir" + +#: utils/adt/json.c:2414 utils/adt/jsonb.c:1384 +#, fuzzy, c-format +#| msgid "mismatched parentheses" +msgid "mismatched array dimensions" +msgstr "eşlenmemiş parantezler" + +#: utils/adt/jsonb.c:258 +#, fuzzy, c-format +#| msgid "bit string too long for type bit varying(%d)" +msgid "string too long to represent as jsonb string" +msgstr "bit varying(%d) tipi için bit string çok uzun" + +#: utils/adt/jsonb.c:259 +#, c-format +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgstr "" + +#: utils/adt/jsonb.c:1147 +#, c-format +msgid "The arguments of jsonb_build_object() must consist of alternating keys and values." +msgstr "" + +#: utils/adt/jsonb.c:1159 +#, fuzzy, c-format +msgid "argument %d: key must not be null" +msgstr "\"%s\" sütunu mevcut değil" + +#: utils/adt/jsonb.c:1747 +#, c-format +msgid "object keys must be strings" +msgstr "" + +#: utils/adt/jsonb.c:1910 +#, fuzzy, c-format +#| msgid "cannot accept a value of type any" +msgid "cannot cast jsonb null to type %s" +msgstr "any tipinde değer alınamaz" + +#: utils/adt/jsonb.c:1911 +#, fuzzy, c-format +#| msgid "cannot cast type %s to %s" +msgid "cannot cast jsonb string to type %s" +msgstr "%s tipi %s tipine dökülemiyor" + +#: utils/adt/jsonb.c:1912 +#, fuzzy, c-format +#| msgid "cannot accept a value of type any" +msgid "cannot cast jsonb numeric to type %s" +msgstr "any tipinde değer alınamaz" + +#: utils/adt/jsonb.c:1913 +#, fuzzy, c-format +#| msgid "cannot accept a value of type any" +msgid "cannot cast jsonb boolean to type %s" +msgstr "any tipinde değer alınamaz" + +#: utils/adt/jsonb.c:1914 +#, fuzzy, c-format +#| msgid "cannot alter array type %s" +msgid "cannot cast jsonb array to type %s" +msgstr "%s array tipi değiştirilemez" + +#: utils/adt/jsonb.c:1915 +#, fuzzy, c-format +#| msgid "cannot accept a value of type any" +msgid "cannot cast jsonb object to type %s" +msgstr "any tipinde değer alınamaz" + +#: utils/adt/jsonb.c:1916 +#, fuzzy, c-format +#| msgid "cannot alter array type %s" +msgid "cannot cast jsonb array or object to type %s" +msgstr "%s array tipi değiştirilemez" + +#: utils/adt/jsonb_util.c:657 +#, fuzzy, c-format +#| msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" +msgstr "dizin boyut sayısı (%d), izin verilern en yüksek değerini (%d) aşmaktadır" + +#: utils/adt/jsonb_util.c:698 +#, fuzzy, c-format +#| msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" +msgstr "dizin boyut sayısı (%d), izin verilern en yüksek değerini (%d) aşmaktadır" + +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 +#, fuzzy, c-format +#| msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgid "total size of jsonb array elements exceeds the maximum of %u bytes" +msgstr "dizin boyut sayısı (%d), izin verilern en yüksek değerini (%d) aşmaktadır" + +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 utils/adt/jsonb_util.c:1705 +#, c-format +msgid "total size of jsonb object elements exceeds the maximum of %u bytes" +msgstr "" + +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 +#, fuzzy, c-format +#| msgid "cannot cast type %s to %s" +msgid "cannot call %s on a scalar" +msgstr "%s tipi %s tipine dökülemiyor" + +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 +#, fuzzy, c-format +#| msgid "cannot accept a value of type anyarray" +msgid "cannot call %s on an array" +msgstr "anyarray tipinde değer alınamaz" + +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 +#, fuzzy, c-format +#| msgid "cannot set an array element to DEFAULT" +msgid "cannot get array length of a scalar" +msgstr "array öğesine DEFAULT değeri atanamıyor" + +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 +#, fuzzy, c-format +msgid "cannot get array length of a non-array" +msgstr "anyarray tipinde değer alınamaz" + +#: utils/adt/jsonfuncs.c:1691 +#, c-format +msgid "cannot call %s on a non-object" +msgstr "" + +#: utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 utils/adt/jsonfuncs.c:3621 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "tip kaydı içermeyen alanda çağırılan ve kayıt döndüren fonksiyon" + +#: utils/adt/jsonfuncs.c:1949 +#, c-format +msgid "cannot deconstruct an array as an object" +msgstr "" + +#: utils/adt/jsonfuncs.c:1961 +#, fuzzy, c-format +#| msgid "cannot convert NaN to smallint" +msgid "cannot deconstruct a scalar" +msgstr "NaN tipinden smallint tipine dönüştürme hatası" + +#: utils/adt/jsonfuncs.c:2007 +#, fuzzy, c-format +#| msgid "cannot delete from a view" +msgid "cannot extract elements from a scalar" +msgstr "view silme hatası" + +#: utils/adt/jsonfuncs.c:2011 +#, fuzzy, c-format +#| msgid "cannot delete from a view" +msgid "cannot extract elements from an object" +msgstr "view silme hatası" + +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 +#, fuzzy, c-format +msgid "cannot call %s on a non-array" +msgstr "anyarray tipinde değer alınamaz" + +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, fuzzy, c-format +#| msgid "expected a type name" +msgid "expected JSON array" +msgstr "tür ismi beklenir" + +#: utils/adt/jsonfuncs.c:2334 +#, fuzzy, c-format +#| msgid "date/time field value out of range: \"%s\"" +msgid "See the value of key \"%s\"." +msgstr "date/time alan değieri kapsam dışıdır: \"%s\"" + +#: utils/adt/jsonfuncs.c:2356 +#, fuzzy, c-format +#| msgid "array element type cannot be %s" +msgid "See the array element %s of key \"%s\"." +msgstr "array element veri tipi %s olamaz" + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "" + +#: utils/adt/jsonfuncs.c:2397 +#, fuzzy, c-format +#| msgid "malformed array literal: \"%s\"" +msgid "malformed JSON array" +msgstr "array literal bozuk: \"%s\"" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 +#, fuzzy, c-format +#| msgid "argument of %s must be a type name" +msgid "first argument of %s must be a row type" +msgstr "%s argümanı tip adı olmalıdır" + +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 +#, c-format +msgid "Try calling the function in the FROM clause using a column definition list." +msgstr "" + +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 +#, fuzzy, c-format +#| msgid "argument of %s must be a name" +msgid "argument of %s must be an array of objects" +msgstr "%s için argüman bir ad olmalıdır" + +#: utils/adt/jsonfuncs.c:3764 +#, c-format +msgid "cannot call %s on an object" +msgstr "" + +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 utils/adt/jsonfuncs.c:4380 +#, fuzzy, c-format +#| msgid "cannot delete from a view" +msgid "cannot delete from scalar" +msgstr "view silme hatası" + +#: utils/adt/jsonfuncs.c:4385 +#, fuzzy, c-format +#| msgid "cannot delete from a view" +msgid "cannot delete from object using integer index" +msgstr "view silme hatası" + +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 +#, fuzzy, c-format +#| msgid "cannot insert into a view" +msgid "cannot set path in scalar" +msgstr "view yazma hatası" + +#: utils/adt/jsonfuncs.c:4496 +#, fuzzy, c-format +#| msgid "cannot delete from a view" +msgid "cannot delete path in scalar" +msgstr "view silme hatası" + +#: utils/adt/jsonfuncs.c:4666 +#, fuzzy, c-format +msgid "invalid concatenation of jsonb objects" +msgstr "geçersiz bağlantı seçeneği \"%s\"\n" + +#: utils/adt/jsonfuncs.c:4700 +#, c-format +msgid "path element at position %d is null" +msgstr "" + +#: utils/adt/jsonfuncs.c:4786 +#, fuzzy, c-format +#| msgid "cannot reopen stdin\n" +msgid "cannot replace existing key" +msgstr "stdin açılamıyor\n" + +#: utils/adt/jsonfuncs.c:4787 +#, c-format +msgid "Try using the function jsonb_set to replace key value." +msgstr "" + +#: utils/adt/jsonfuncs.c:4869 +#, fuzzy, c-format +#| msgid "plpy.prepare: type name at ordinal position %d is not a string" +msgid "path element at position %d is not an integer: \"%s\"" +msgstr "plpy.prepare: %d sıra posizyonundaki veri tipi dizi değil" + +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "" + +#: utils/adt/jsonfuncs.c:4995 +#, fuzzy, c-format +#| msgid "array element type cannot be %s" +msgid "flag array element is not a string" +msgstr "array element veri tipi %s olamaz" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, c-format +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgstr "" + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "" + +#: utils/adt/levenshtein.c:133 +#, c-format +msgid "levenshtein argument exceeds maximum length of %d characters" +msgstr "" + +#: utils/adt/like.c:183 utils/adt/selfuncs.c:5806 +#, fuzzy, c-format +#| msgid "could not determine input data type" +msgid "could not determine which collation to use for ILIKE" +msgstr "giriş veri tipleri belirlenemedi" + +#: utils/adt/like_match.c:107 utils/adt/like_match.c:167 +#, fuzzy, c-format +msgid "LIKE pattern must not end with escape character" +msgstr "$%d parametresi yoktur" + +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 +#, c-format +msgid "invalid escape string" +msgstr "escape satırı geçersiz" + +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 +#, c-format +msgid "Escape string must be empty or one character." +msgstr "Kaçış dizisi boş veya bir karakter olmalıdır." + +#: utils/adt/lockfuncs.c:664 +#, c-format +msgid "cannot use advisory locks during a parallel operation" +msgstr "" + +#: utils/adt/mac.c:102 +#, c-format +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "\"macaddr\" içinde geçersiz octet değeri: \"%s\"" + +#: utils/adt/mac8.c:563 +#, c-format +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "" + +#: utils/adt/mac8.c:564 +#, c-format +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "" + +#: utils/adt/misc.c:239 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d bir PostgreSQL sunucu süreci değildir" + +#: utils/adt/misc.c:290 +#, fuzzy, c-format +#| msgid "must be superuser to create superusers" +msgid "must be a superuser to cancel superuser query" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: utils/adt/misc.c:295 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "" + +#: utils/adt/misc.c:314 +#, fuzzy, c-format +#| msgid "must be superuser to create superusers" +msgid "must be a superuser to terminate superuser process" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: utils/adt/misc.c:319 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "" + +#: utils/adt/misc.c:336 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "postmaster sürecine sinyal gönderme başarısız: %m" + +#: utils/adt/misc.c:355 +#, fuzzy, c-format +#| msgid "must be superuser to rotate log files" +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "log dosyaları göndürmek için superuser olmalısınız" + +#: utils/adt/misc.c:356 +#, fuzzy, c-format +#| msgid "Consider using tablespaces instead." +msgid "Consider using pg_logfile_rotate(), which is part of core, instead." +msgstr "Onun yerine tablespace kullanabilirsiniz." + +#: utils/adt/misc.c:361 utils/adt/misc.c:381 +#, fuzzy, c-format +msgid "rotation not possible because log collection not active" +msgstr "log direction etkin olmadıpından rotation yapılamaz" + +#: utils/adt/misc.c:418 +#, c-format +msgid "global tablespace never has databases" +msgstr "global tablespace, database bulunduramaz" + +#: utils/adt/misc.c:439 +#, c-format +msgid "%u is not a tablespace OID" +msgstr "%u OID tablespace değildir" + +#: utils/adt/misc.c:626 +msgid "unreserved" +msgstr "ayrılmamış" + +#: utils/adt/misc.c:630 +#, fuzzy +msgid "unreserved (cannot be function or type name)" +msgstr "geçerli kullanıcının adı değiştirilemez" + +#: utils/adt/misc.c:634 +msgid "reserved (can be function or type name)" +msgstr "" + +#: utils/adt/misc.c:638 +msgid "reserved" +msgstr "ayrılmış" + +#: utils/adt/misc.c:812 utils/adt/misc.c:826 utils/adt/misc.c:865 utils/adt/misc.c:871 utils/adt/misc.c:877 utils/adt/misc.c:900 +#, fuzzy, c-format +#| msgid "recovery_target_xid is not a valid number: \"%s\"" +msgid "string is not a valid identifier: \"%s\"" +msgstr "recovery_target_xid geçerli sayısal bir değer değildir: \"%s\"" + +#: utils/adt/misc.c:814 +#, c-format +msgid "String has unclosed double quotes." +msgstr "Dizede kapatılmamış çift tırnak mevcut." + +#: utils/adt/misc.c:828 +#, c-format +msgid "Quoted identifier must not be empty." +msgstr "Tırnak içine alınmış tanımlayıcı boş olmamalıdır." + +#: utils/adt/misc.c:867 +#, c-format +msgid "No valid identifier before \".\"." +msgstr "" + +#: utils/adt/misc.c:873 +#, c-format +msgid "No valid identifier after \".\"." +msgstr "" + +#: utils/adt/misc.c:934 +#, fuzzy, c-format +#| msgid "interval units \"%s\" not supported" +msgid "log format \"%s\" is not supported" +msgstr "interval birimi \"%s\" desteklenmemektedir" + +#: utils/adt/misc.c:935 +#, c-format +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "" + +#: utils/adt/nabstime.c:140 +#, c-format +msgid "invalid time zone name: \"%s\"" +msgstr "geçersiz zaman dilimi adı: \"%s\"" + +#: utils/adt/nabstime.c:485 utils/adt/nabstime.c:558 +#, c-format +msgid "cannot convert abstime \"invalid\" to timestamp" +msgstr "abstime \"invalid\" interval tipine dönüştürülemiyor" + +#: utils/adt/nabstime.c:785 +#, c-format +msgid "invalid status in external \"tinterval\" value" +msgstr "harici \"tinterval\" değerinin durumu geçirsiz" + +#: utils/adt/nabstime.c:855 +#, c-format +msgid "cannot convert reltime \"invalid\" to interval" +msgstr "reltime \"invalid\" değeri interval'a dönüştürülemiyor" + +#: utils/adt/network.c:69 +#, c-format +msgid "invalid cidr value: \"%s\"" +msgstr "cidr değeri geçersiz: \"%s\"" + +#: utils/adt/network.c:70 utils/adt/network.c:200 +#, c-format +msgid "Value has bits set to right of mask." +msgstr "Değerin maskenin sğında fazladan bitler var." + +#: utils/adt/network.c:111 utils/adt/network.c:592 utils/adt/network.c:617 utils/adt/network.c:642 +#, c-format +msgid "could not format inet value: %m" +msgstr "inet değeri biçimlendirilemiyor: %m" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:168 +#, c-format +msgid "invalid address family in external \"%s\" value" +msgstr "dış \"%s\" değerinde geçersiz address family" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:175 +#, c-format +msgid "invalid bits in external \"%s\" value" +msgstr "harici \"%s\" değerinin bitleri geçirsiz" + +#. translator: %s is inet or cidr +#: utils/adt/network.c:184 +#, c-format +msgid "invalid length in external \"%s\" value" +msgstr "harici \"%s\" değerinin uzunluğu geçirsiz" + +#: utils/adt/network.c:199 +#, c-format +msgid "invalid external \"cidr\" value" +msgstr "geçersiz harici \"cidr\" değeri" + +#: utils/adt/network.c:295 utils/adt/network.c:318 +#, c-format +msgid "invalid mask length: %d" +msgstr "geçersiz mask uzunluğu: %d" + +#: utils/adt/network.c:660 +#, c-format +msgid "could not format cidr value: %m" +msgstr "cidr değeri biçimlendirilemiyor: %m" + +#: utils/adt/network.c:893 +#, fuzzy, c-format +#| msgid "cannot OR inet values of different sizes" +msgid "cannot merge addresses from different families" +msgstr "farklı uzunluğa sahip inet değerleri üzerinde OR işlemi yapılamaz" + +#: utils/adt/network.c:1309 +#, c-format +msgid "cannot AND inet values of different sizes" +msgstr "farklı uzunluğa sahip inet değerleri üzerinde AND işlemi yapılamaz" + +#: utils/adt/network.c:1341 +#, c-format +msgid "cannot OR inet values of different sizes" +msgstr "farklı uzunluğa sahip inet değerleri üzerinde OR işlemi yapılamaz" + +#: utils/adt/network.c:1402 utils/adt/network.c:1478 +#, c-format +msgid "result is out of range" +msgstr "sonuç sıra dsışıdır" + +#: utils/adt/network.c:1443 +#, c-format +msgid "cannot subtract inet values of different sizes" +msgstr "farklı uzunluğa sahip inet değerleri üzerinde eksilme işlemi yapılamaz" + +#: utils/adt/numeric.c:830 +#, c-format +msgid "invalid sign in external \"numeric\" value" +msgstr "harici \"numeric\" değerinin eksi işareti geçirsiz" + +#: utils/adt/numeric.c:836 +#, fuzzy, c-format +#| msgid "invalid length in external \"numeric\" value" +msgid "invalid scale in external \"numeric\" value" +msgstr "harici \"numeric\" değerinin uzunluğu geçirsiz" + +#: utils/adt/numeric.c:845 +#, c-format +msgid "invalid digit in external \"numeric\" value" +msgstr "harici \"numeric\" değerinin rakamı geçirsiz" + +#: utils/adt/numeric.c:1035 utils/adt/numeric.c:1049 +#, c-format +msgid "NUMERIC precision %d must be between 1 and %d" +msgstr "NUMERIC precision %d, 1 ile %d arasında olmalıdır" + +#: utils/adt/numeric.c:1040 +#, c-format +msgid "NUMERIC scale %d must be between 0 and precision %d" +msgstr "NUMERIC %d ölçüsü 0 ile %d kesinliği arasında olmalıdır" + +#: utils/adt/numeric.c:1058 +#, c-format +msgid "invalid NUMERIC type modifier" +msgstr "geçersiz NUMERIC tipi niteleyicisi" + +#: utils/adt/numeric.c:1390 +#, fuzzy, c-format +#| msgid "timestamp cannot be NaN" +msgid "start value cannot be NaN" +msgstr "timestamp NaN olamaz" + +#: utils/adt/numeric.c:1395 +#, fuzzy, c-format +#| msgid "timestamp cannot be NaN" +msgid "stop value cannot be NaN" +msgstr "timestamp NaN olamaz" + +#: utils/adt/numeric.c:1405 +#, fuzzy, c-format +#| msgid "step size cannot equal zero" +msgid "step size cannot be NaN" +msgstr "step boyutu sıfır olamaz" + +#: utils/adt/numeric.c:2736 utils/adt/numeric.c:5725 utils/adt/numeric.c:6170 utils/adt/numeric.c:7878 utils/adt/numeric.c:8303 utils/adt/numeric.c:8417 utils/adt/numeric.c:8490 +#, c-format +msgid "value overflows numeric format" +msgstr "değer, numerik biçiminin kapsamını taşımaktadır" + +#: utils/adt/numeric.c:3095 +#, c-format +msgid "cannot convert NaN to integer" +msgstr "NaN tipinden integer tipine dönüştürme hatası" + +#: utils/adt/numeric.c:3161 +#, c-format +msgid "cannot convert NaN to bigint" +msgstr "NaN tipinden bigint tipine dönüştürme hatası" + +#: utils/adt/numeric.c:3206 +#, c-format +msgid "cannot convert NaN to smallint" +msgstr "NaN tipinden smallint tipine dönüştürme hatası" + +#: utils/adt/numeric.c:3243 utils/adt/numeric.c:3314 +#, fuzzy, c-format +#| msgid "cannot convert NaN to integer" +msgid "cannot convert infinity to numeric" +msgstr "NaN tipinden integer tipine dönüştürme hatası" + +#: utils/adt/numeric.c:6240 +#, c-format +msgid "numeric field overflow" +msgstr "numerik alan kapsamını taşımaktadır" + +#: utils/adt/numeric.c:6241 +#, c-format +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." +msgstr "%d duyarlı, %d ölçekli bir alan %s%d'den daha az mutlak değere yuvarlanabilmelidir." + +#: utils/adt/numutils.c:89 +#, c-format +msgid "value \"%s\" is out of range for 8-bit integer" +msgstr "8-bir integer tipi için \"%s\" değeri kapsam dışıdır" + +#: utils/adt/oid.c:290 +#, c-format +msgid "invalid oidvector data" +msgstr "geçersiz oidvector verisi" + +#: utils/adt/oracle_compat.c:896 +#, c-format +msgid "requested character too large" +msgstr "istenen karakter çok büyük" + +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 +#, c-format +msgid "requested character too large for encoding: %d" +msgstr "Belirtilen karakter dil kodlaması için çok büyük: %d" + +#: utils/adt/oracle_compat.c:987 +#, fuzzy, c-format +#| msgid "requested character too large for encoding: %d" +msgid "requested character not valid for encoding: %d" +msgstr "Belirtilen karakter dil kodlaması için çok büyük: %d" + +#: utils/adt/oracle_compat.c:1001 +#, c-format +msgid "null character not permitted" +msgstr "null karaktere izin verilmez" + +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 utils/adt/orderedsetaggs.c:684 +#, c-format +msgid "percentile value %g is not between 0 and 1" +msgstr "" + +#: utils/adt/pg_locale.c:1034 +#, c-format +msgid "Apply system library package updates." +msgstr "" + +#: utils/adt/pg_locale.c:1249 +#, fuzzy, c-format +#| msgid "could not create lock file \"%s\": %m" +msgid "could not create locale \"%s\": %m" +msgstr "\"%s\" lock dosyası oluşturma hatası: %m" + +#: utils/adt/pg_locale.c:1252 +#, c-format +msgid "The operating system could not find any locale data for the locale name \"%s\"." +msgstr "" + +#: utils/adt/pg_locale.c:1353 +#, fuzzy, c-format +#| msgid "tablespaces are not supported on this platform" +msgid "collations with different collate and ctype values are not supported on this platform" +msgstr "bu platformda tablespace desteklenmiyor" + +#: utils/adt/pg_locale.c:1362 +#, fuzzy, c-format +#| msgid "LDAP over SSL is not supported on this platform." +msgid "collation provider LIBC is not supported on this platform" +msgstr "Bu platformda SSL üzerinde LDAP bu ortamda desteklenmemektedir." + +#: utils/adt/pg_locale.c:1374 +#, c-format +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "" + +#: utils/adt/pg_locale.c:1380 utils/adt/pg_locale.c:1468 +#, fuzzy, c-format +#| msgid "could not open control file \"%s\": %m" +msgid "could not open collator for locale \"%s\": %s" +msgstr "kontrol dosyası \"%s\" açma hatası: %m" + +#: utils/adt/pg_locale.c:1391 +#, c-format +msgid "ICU is not supported in this build" +msgstr "ICU bu yapılandırmada desteklenmiyor" + +#: utils/adt/pg_locale.c:1392 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "PostgreSQL'i --with-icu seçeneği ile yeniden derlemeniz gerekiyor." + +#: utils/adt/pg_locale.c:1412 +#, c-format +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "" + +#: utils/adt/pg_locale.c:1419 +#, c-format +msgid "collation \"%s\" has version mismatch" +msgstr "\"%s\" karşılaştırmasında (collation) sürüm uyuşmazlığı mevcut" + +#: utils/adt/pg_locale.c:1421 +#, c-format +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "Veritabanındaki collation %s sürümüyle oluşturulmuş, fakat işletim sistem %s sürümünü sağlıyor." + +#: utils/adt/pg_locale.c:1424 +#, c-format +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "" + +#: utils/adt/pg_locale.c:1508 +#, c-format +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "\"%s\" dil kodlaması için ICU dönüştürücü açılamadı: %s" + +#: utils/adt/pg_locale.c:1539 utils/adt/pg_locale.c:1548 +#, c-format +msgid "ucnv_toUChars failed: %s" +msgstr "ucnv_toUChars başarısız oldu: %s" + +#: utils/adt/pg_locale.c:1577 utils/adt/pg_locale.c:1586 +#, c-format +msgid "ucnv_fromUChars failed: %s" +msgstr "ucnv_fromUChars başarısız oldu: %s" + +#: utils/adt/pg_locale.c:1758 +#, c-format +msgid "invalid multibyte character for locale" +msgstr "karakter kapsamı için geçersiz isimler" + +#: utils/adt/pg_locale.c:1759 +#, c-format +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "Sunucunun LC_TYPE yerel ayarı veritabanı kodlaması ile uyumsuz." + +#: utils/adt/pg_upgrade_support.c:29 +#, c-format +msgid "function can only be called when server is in binary upgrade mode" +msgstr "" + +#: utils/adt/pgstatfuncs.c:474 +#, c-format +msgid "invalid command name: \"%s\"" +msgstr "geçersiz komut adı: \"%s\"" + +#: utils/adt/pseudotypes.c:247 +#, c-format +msgid "cannot accept a value of a shell type" +msgstr "shell tipinde değer alınamaz" + +#: utils/adt/pseudotypes.c:260 +#, c-format +msgid "cannot display a value of a shell type" +msgstr "shell tipinde değer gösterilemez" + +#: utils/adt/pseudotypes.c:350 utils/adt/pseudotypes.c:376 +#, c-format +msgid "cannot output a value of type %s" +msgstr "%s tipinde bir değer çıktı olamaz" + +#: utils/adt/pseudotypes.c:403 +#, c-format +msgid "cannot display a value of type %s" +msgstr "%s tipinde bir değer gösterilemez" + +#: utils/adt/rangetypes.c:405 +#, fuzzy, c-format +msgid "range constructor flags argument must not be null" +msgstr "atamada array subscript null olamaz" + +#: utils/adt/rangetypes.c:992 +#, c-format +msgid "result of range difference would not be contiguous" +msgstr "" + +#: utils/adt/rangetypes.c:1053 +#, c-format +msgid "result of range union would not be contiguous" +msgstr "" + +#: utils/adt/rangetypes.c:1597 +#, fuzzy, c-format +#| msgid "lower bound cannot equal upper bound" +msgid "range lower bound must be less than or equal to range upper bound" +msgstr "alt sınır üst sınırı ile eşit olamaz" + +#: utils/adt/rangetypes.c:1980 utils/adt/rangetypes.c:1993 utils/adt/rangetypes.c:2007 +#, c-format +msgid "invalid range bound flags" +msgstr "geçersiz aralık sınır bayrakları (range bound flags)" + +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 utils/adt/rangetypes.c:2008 +#, fuzzy, c-format +#| msgid "Valid values are between \"%d\" and \"%d\"." +msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." +msgstr "Geçerli değerler \"%d\" ile \"%d\" arasındadır." + +#: utils/adt/rangetypes.c:2073 utils/adt/rangetypes.c:2090 utils/adt/rangetypes.c:2103 utils/adt/rangetypes.c:2121 utils/adt/rangetypes.c:2132 utils/adt/rangetypes.c:2176 utils/adt/rangetypes.c:2184 +#, c-format +msgid "malformed range literal: \"%s\"" +msgstr "aralık (range) literali bozuk: \"%s\"" + +#: utils/adt/rangetypes.c:2075 +#, c-format +msgid "Junk after \"empty\" key word." +msgstr "" + +#: utils/adt/rangetypes.c:2092 +#, c-format +msgid "Missing left parenthesis or bracket." +msgstr "Sol parantez veya köşeli ayraç eksik." + +#: utils/adt/rangetypes.c:2105 +#, c-format +msgid "Missing comma after lower bound." +msgstr "Alt sınırdan sonra virgül eksik." + +#: utils/adt/rangetypes.c:2123 +#, c-format +msgid "Too many commas." +msgstr "Çok fazla virgül var." + +#: utils/adt/rangetypes.c:2134 +#, fuzzy, c-format +#| msgid "Junk after right parenthesis." +msgid "Junk after right parenthesis or bracket." +msgstr "Sağ parantezden sonra süprüntü." + +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1424 utils/adt/varlena.c:4105 +#, c-format +msgid "regular expression failed: %s" +msgstr "regular expression başarısız: %s" + +#: utils/adt/regexp.c:426 +#, fuzzy, c-format +msgid "invalid regexp option: \"%c\"" +msgstr "geçersiz regexp seçeneği: %c" + +#: utils/adt/regexp.c:866 +#, fuzzy, c-format +#| msgid "regexp_split does not support the global option" +msgid "regexp_match does not support the global option" +msgstr "regexp_split, global seçeneği desteklemez" + +#: utils/adt/regexp.c:867 +#, fuzzy, c-format +#| msgid "Use the @@@ operator instead." +msgid "Use the regexp_matches function instead." +msgstr "Bunun yerine @@@ operatörünü kullanın." + +#: utils/adt/regexp.c:1049 +#, fuzzy, c-format +#| msgid "regular expression failed: %s" +msgid "too many regular expression matches" +msgstr "regular expression başarısız: %s" + +#: utils/adt/regexp.c:1244 +#, fuzzy, c-format +#| msgid "regexp_split does not support the global option" +msgid "regexp_split_to_table does not support the global option" +msgstr "regexp_split, global seçeneği desteklemez" + +#: utils/adt/regexp.c:1297 +#, fuzzy, c-format +#| msgid "regexp_split does not support the global option" +msgid "regexp_split_to_array does not support the global option" +msgstr "regexp_split, global seçeneği desteklemez" + +#: utils/adt/regproc.c:106 +#, c-format +msgid "more than one function named \"%s\"" +msgstr "birden fazla \"%s\" adlı fonksiyon var" + +#: utils/adt/regproc.c:524 +#, c-format +msgid "more than one operator named %s" +msgstr "birden fazla \"%s\" adlı operatör var" + +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 utils/adt/ruleutils.c:9134 utils/adt/ruleutils.c:9302 +#, c-format +msgid "too many arguments" +msgstr "çok fazla argüman" + +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 +#, c-format +msgid "Provide two argument types for operator." +msgstr "Operatör için iki argüman tipi sağlayın." + +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 utils/adt/varlena.c:3246 utils/adt/varlena.c:3251 +#, c-format +msgid "invalid name syntax" +msgstr "isim sözdizimi geçersiz" + +#: utils/adt/regproc.c:1763 +#, c-format +msgid "expected a left parenthesis" +msgstr "sol parantez beklenir" + +#: utils/adt/regproc.c:1779 +#, c-format +msgid "expected a right parenthesis" +msgstr "sağ parantez beklenir" + +#: utils/adt/regproc.c:1798 +#, c-format +msgid "expected a type name" +msgstr "tür ismi beklenir" + +#: utils/adt/regproc.c:1830 +#, c-format +msgid "improper type name" +msgstr "tür ismi geçersiz" + +#: utils/adt/ri_triggers.c:337 utils/adt/ri_triggers.c:2085 utils/adt/ri_triggers.c:2767 +#, c-format +msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgstr "\"%s\" tablosu üzende işlem \"%s\" foreign key constrainti ihlal ediyor" + +#: utils/adt/ri_triggers.c:340 utils/adt/ri_triggers.c:2088 +#, c-format +msgid "MATCH FULL does not allow mixing of null and nonnull key values." +msgstr "MATCH FULL, null ve nonnull anahtar değerlerinin bir arada kullanımına izin vermez." + +#: utils/adt/ri_triggers.c:2273 +#, c-format +msgid "function \"%s\" must be fired for INSERT" +msgstr "\"%s\" fonksiyonu INSERT için çalıştırılmalıdır" + +#: utils/adt/ri_triggers.c:2279 +#, c-format +msgid "function \"%s\" must be fired for UPDATE" +msgstr "\"%s\" fonksiyonu UPDATE için çalıştırılmalıdır" + +#: utils/adt/ri_triggers.c:2285 +#, c-format +msgid "function \"%s\" must be fired for DELETE" +msgstr "\"%s\" fonksiyonu DELETE için çalıştırılmalıdır" + +#: utils/adt/ri_triggers.c:2308 +#, c-format +msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" +msgstr "\"%2$s\" tablosunun \"%1$s\" triggeri için pg_constraint girişi yoktur" + +#: utils/adt/ri_triggers.c:2310 +#, c-format +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "Bu ve diğer bütünlük kısıtlamaları ladırın, ardından ALTER TABLE ADD CONSTRAINT komutuyla yeni kısıtlama ekleyin." + +#: utils/adt/ri_triggers.c:2614 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "\"%3$s\" tablosu üzerinde \"%2$s\" bütünük kısıtlamasından \"%1$s\" nesnesini sorgulayan sorgu beklenmeyen bir sonuç getirdi" + +#: utils/adt/ri_triggers.c:2618 +#, c-format +msgid "This is most likely due to a rule having rewritten the query." +msgstr "Bu durum muhtemelen sorguyu değiştiren rule yüzünden meydana gelmiştir." + +#: utils/adt/ri_triggers.c:2771 +#, c-format +msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgstr "\"%3$s\" tablosunda (%1$s)=(%2$s) anahtarı mevcut değildir." + +#: utils/adt/ri_triggers.c:2774 +#, fuzzy, c-format +#| msgid "Key (%s)=(%s) is not present in table \"%s\"." +msgid "Key is not present in table \"%s\"." +msgstr "\"%3$s\" tablosunda (%1$s)=(%2$s) anahtarı mevcut değildir." + +#: utils/adt/ri_triggers.c:2780 +#, c-format +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" +msgstr "\"%1$s\" tablosu üzerinde yapılan update veya delete işlemi \"%3$s\" tablosunun \"%2$s\" bütünlük kısıtlamasını ihlal ediyor" + +#: utils/adt/ri_triggers.c:2785 +#, c-format +msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgstr "(%s)=(%s) anahtarı \"%s\" tablosundan hala referans edilmektedir." + +#: utils/adt/ri_triggers.c:2788 +#, fuzzy, c-format +#| msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgid "Key is still referenced from table \"%s\"." +msgstr "(%s)=(%s) anahtarı \"%s\" tablosundan hala referans edilmektedir." + +#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:481 +#, c-format +msgid "input of anonymous composite types is not implemented" +msgstr "anonymous composite veri girişi implemente edilmemiş" + +#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:184 utils/adt/rowtypes.c:207 utils/adt/rowtypes.c:215 utils/adt/rowtypes.c:267 utils/adt/rowtypes.c:275 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "hatalı değer: \"%s\"" + +#: utils/adt/rowtypes.c:156 +#, c-format +msgid "Missing left parenthesis." +msgstr "Sol parantez eksik." + +#: utils/adt/rowtypes.c:185 +#, c-format +msgid "Too few columns." +msgstr "Sütun sayısı yetersiz." + +#: utils/adt/rowtypes.c:268 +#, c-format +msgid "Too many columns." +msgstr "Çok fazla sütun." + +#: utils/adt/rowtypes.c:276 +#, c-format +msgid "Junk after right parenthesis." +msgstr "Sağ parantezden sonra süprüntü." + +#: utils/adt/rowtypes.c:530 +#, c-format +msgid "wrong number of columns: %d, expected %d" +msgstr "geçersiz sütun sayısı: %2$d yerine %1$d" + +#: utils/adt/rowtypes.c:558 +#, c-format +msgid "wrong data type: %u, expected %u" +msgstr "yanlış veri tipi: %u beklenirken %u alındı" + +#: utils/adt/rowtypes.c:619 +#, c-format +msgid "improper binary format in record column %d" +msgstr "%d kayıt sütununda uygunsuz ikili biçimi" + +#: utils/adt/rowtypes.c:910 utils/adt/rowtypes.c:1154 utils/adt/rowtypes.c:1413 utils/adt/rowtypes.c:1657 +#, c-format +msgid "cannot compare dissimilar column types %s and %s at record column %d" +msgstr "" + +#: utils/adt/rowtypes.c:999 utils/adt/rowtypes.c:1225 utils/adt/rowtypes.c:1508 utils/adt/rowtypes.c:1731 +#, fuzzy, c-format +msgid "cannot compare record types with different numbers of columns" +msgstr "farklı öğe tipli dizinleri karşılaştırılamaz" + +#: utils/adt/ruleutils.c:4825 +#, c-format +msgid "rule \"%s\" has unsupported event type %d" +msgstr "\"%s\" rule desteklenmeyen veri tipine sahip %d" + +#: utils/adt/selfuncs.c:5791 +#, c-format +msgid "case insensitive matching not supported on type bytea" +msgstr "bytea veri tipi için büyük ve küçük harf duyarsız karşılaştırma desteklenmemektedir" + +#: utils/adt/selfuncs.c:5893 +#, c-format +msgid "regular-expression matching not supported on type bytea" +msgstr "bytea tipi için regular-expression karşılaştırma desteklenmemektedir" + +#: utils/adt/timestamp.c:107 +#, c-format +msgid "TIMESTAMP(%d)%s precision must not be negative" +msgstr "TIMESTAMP(%d)%s kesinliği sıfırdan küçük olamaz" + +#: utils/adt/timestamp.c:113 +#, c-format +msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" +msgstr "TIMESTAMP(%d)%s kesinliği en yüksek değerine (%d) kadar düşürüldü" + +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:416 +#, c-format +msgid "timestamp out of range: \"%s\"" +msgstr "timestamp kapsam dışıdır: \"%s\"" + +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:434 utils/adt/timestamp.c:941 +#, c-format +msgid "date/time value \"%s\" is no longer supported" +msgstr "\"%s\" tarih/saat değeri artık desteklenemektedir" + +#: utils/adt/timestamp.c:362 +#, c-format +msgid "timestamp(%d) precision must be between %d and %d" +msgstr "timestamp(%d) kesinliği %d ile %d arasında olmalıdır" + +#: utils/adt/timestamp.c:484 +#, fuzzy, c-format +#| msgid "invalid input syntax for type numeric: \"%s\"" +msgid "invalid input syntax for numeric time zone: \"%s\"" +msgstr "numeric tipi için geçersiz biçim: \"%s\"" + +#: utils/adt/timestamp.c:486 +#, c-format +msgid "Numeric time zones must have \"-\" or \"+\" as first character." +msgstr "" + +#: utils/adt/timestamp.c:499 +#, fuzzy, c-format +msgid "numeric time zone \"%s\" out of range" +msgstr "yer değiştirme değeri kapsam dışında: \"%s\"" + +#: utils/adt/timestamp.c:601 utils/adt/timestamp.c:611 utils/adt/timestamp.c:619 +#, fuzzy, c-format +#| msgid "timestamp out of range: \"%s\"" +msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" +msgstr "timestamp kapsam dışıdır: \"%s\"" + +#: utils/adt/timestamp.c:720 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "timestamp NaN olamaz" + +#: utils/adt/timestamp.c:738 utils/adt/timestamp.c:750 +#, fuzzy, c-format +#| msgid "timestamp out of range: \"%s\"" +msgid "timestamp out of range: \"%g\"" +msgstr "timestamp kapsam dışıdır: \"%s\"" + +#: utils/adt/timestamp.c:935 utils/adt/timestamp.c:1505 utils/adt/timestamp.c:1918 utils/adt/timestamp.c:3016 utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3026 utils/adt/timestamp.c:3076 utils/adt/timestamp.c:3083 utils/adt/timestamp.c:3090 utils/adt/timestamp.c:3110 utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 utils/adt/timestamp.c:3154 utils/adt/timestamp.c:3162 +#: utils/adt/timestamp.c:3206 utils/adt/timestamp.c:3633 utils/adt/timestamp.c:3758 utils/adt/timestamp.c:4143 +#, c-format +msgid "interval out of range" +msgstr "interval sonuç sıra dışıdır" + +#: utils/adt/timestamp.c:1068 utils/adt/timestamp.c:1101 +#, c-format +msgid "invalid INTERVAL type modifier" +msgstr "geçersiz INTERVAL tipi niteleyicisi" + +#: utils/adt/timestamp.c:1084 +#, c-format +msgid "INTERVAL(%d) precision must not be negative" +msgstr "INTERVAL(%d) kesinliği sıfırdan küçük olamaz" + +#: utils/adt/timestamp.c:1090 +#, c-format +msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" +msgstr "INTERVAL(%d) kesinliği izin verilen en yüksek değere (%d) düşürülmüştür" + +#: utils/adt/timestamp.c:1462 +#, c-format +msgid "interval(%d) precision must be between %d and %d" +msgstr "interval(%d) kesinliği %d ile %d arasında olmalıdır" + +#: utils/adt/timestamp.c:2617 +#, c-format +msgid "cannot subtract infinite timestamps" +msgstr "sonsuz timestap veri tipi üzerinde çıkarma işlemi yapılamaz" + +#: utils/adt/timestamp.c:3886 utils/adt/timestamp.c:4403 utils/adt/timestamp.c:4570 utils/adt/timestamp.c:4591 +#, c-format +msgid "timestamp units \"%s\" not supported" +msgstr "interval birimi \"%s\" desteklenmemektedir" + +#: utils/adt/timestamp.c:3900 utils/adt/timestamp.c:4357 utils/adt/timestamp.c:4601 +#, c-format +msgid "timestamp units \"%s\" not recognized" +msgstr "\"%s\" timestamp birimleri geçersiz" + +#: utils/adt/timestamp.c:4032 utils/adt/timestamp.c:4398 utils/adt/timestamp.c:4771 utils/adt/timestamp.c:4793 +#, c-format +msgid "timestamp with time zone units \"%s\" not supported" +msgstr "\"%s\" timestamp with time zone değerleri desteklenmemektedir" + +#: utils/adt/timestamp.c:4049 utils/adt/timestamp.c:4352 utils/adt/timestamp.c:4802 +#, c-format +msgid "timestamp with time zone units \"%s\" not recognized" +msgstr "\"%s\" timestamp with time zone değerleri tanınmamaktadır" + +#: utils/adt/timestamp.c:4130 +#, c-format +msgid "interval units \"%s\" not supported because months usually have fractional weeks" +msgstr "" + +#: utils/adt/timestamp.c:4136 utils/adt/timestamp.c:4896 +#, c-format +msgid "interval units \"%s\" not supported" +msgstr "interval birimi \"%s\" desteklenmemektedir" + +#: utils/adt/timestamp.c:4152 utils/adt/timestamp.c:4919 +#, c-format +msgid "interval units \"%s\" not recognized" +msgstr "\"%s\" interval birimleri geçersiz" + +#: utils/adt/trigfuncs.c:42 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called as trigger" +msgstr "" + +#: utils/adt/trigfuncs.c:48 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called on update" +msgstr "" + +#: utils/adt/trigfuncs.c:54 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called before update" +msgstr "" + +#: utils/adt/trigfuncs.c:60 +#, c-format +msgid "suppress_redundant_updates_trigger: must be called for each row" +msgstr "" + +#: utils/adt/tsgistidx.c:100 +#, c-format +msgid "gtsvector_in not implemented" +msgstr " gtsvector_in henüz implemente edilmemiştir" + +#: utils/adt/tsquery.c:200 +#, c-format +msgid "distance in phrase operator should not be greater than %d" +msgstr "" + +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 utils/adt/tsvector_parser.c:133 +#, fuzzy, c-format +msgid "syntax error in tsquery: \"%s\"" +msgstr "%s geçmiş dosyasında sözdizimi hatası" + +#: utils/adt/tsquery.c:334 +#, fuzzy, c-format +msgid "no operand in tsquery: \"%s\"" +msgstr "operator eşsiz değildir: %s" + +#: utils/adt/tsquery.c:568 +#, c-format +msgid "value is too big in tsquery: \"%s\"" +msgstr "tsquery'deki değer çok büyük: \"%s\"" + +#: utils/adt/tsquery.c:573 +#, fuzzy, c-format +msgid "operand is too long in tsquery: \"%s\"" +msgstr "operator eşsiz değildir: %s" + +#: utils/adt/tsquery.c:601 +#, c-format +msgid "word is too long in tsquery: \"%s\"" +msgstr "tsquery'deki sözcük çok uzun: \"%s\"" + +#: utils/adt/tsquery.c:870 +#, c-format +msgid "text-search query doesn't contain lexemes: \"%s\"" +msgstr "metin arama sorgusu lexeme içermiyor: \"%s\"" + +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 +#, fuzzy, c-format +#| msgid "requested length too large" +msgid "tsquery is too large" +msgstr "istenen uzunluk çok büyük" + +#: utils/adt/tsquery_cleanup.c:407 +#, c-format +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" +msgstr "" + +#: utils/adt/tsquery_op.c:123 +#, c-format +msgid "distance in phrase operator should be non-negative and less than %d" +msgstr "" + +#: utils/adt/tsquery_rewrite.c:321 +#, fuzzy, c-format +msgid "ts_rewrite query must return two tsquery columns" +msgstr "subquery, bir tane sütun getirmelidir" + +#: utils/adt/tsrank.c:413 +#, fuzzy, c-format +msgid "array of weight must be one-dimensional" +msgstr "ACL array tek boyutlu olmalıdır" + +#: utils/adt/tsrank.c:418 +#, c-format +msgid "array of weight is too short" +msgstr "" + +#: utils/adt/tsrank.c:423 +#, fuzzy, c-format +msgid "array of weight must not contain nulls" +msgstr "array null kayıtları içeremez" + +#: utils/adt/tsrank.c:432 utils/adt/tsrank.c:869 +#, c-format +msgid "weight out of range" +msgstr "ağırlık değeri sıra dışıdır" + +#: utils/adt/tsvector.c:214 +#, c-format +msgid "word is too long (%ld bytes, max %ld bytes)" +msgstr "sözcük çok uzun (%ld byte, en fazla %ld byte)" + +#: utils/adt/tsvector.c:221 +#, fuzzy, c-format +msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" +msgstr "dizgi tsvector için çok uzun" + +#: utils/adt/tsvector_op.c:323 utils/adt/tsvector_op.c:610 utils/adt/tsvector_op.c:778 +#, fuzzy, c-format +#| msgid "typmod array must not contain nulls" +msgid "lexeme array may not contain nulls" +msgstr "typmod array null kayıtları içeremez" + +#: utils/adt/tsvector_op.c:853 +#, fuzzy, c-format +#| msgid "typmod array must not contain nulls" +msgid "weight array may not contain nulls" +msgstr "typmod array null kayıtları içeremez" + +#: utils/adt/tsvector_op.c:877 +#, fuzzy, c-format +#| msgid "unrecognized encoding: \"%s\"" +msgid "unrecognized weight: \"%c\"" +msgstr "tanınmayan kodlama adı \"%s\"" + +#: utils/adt/tsvector_op.c:2314 +#, fuzzy, c-format +msgid "ts_stat query must return one tsvector column" +msgstr "subquery, bir tane sütun getirmelidir" + +#: utils/adt/tsvector_op.c:2496 +#, fuzzy, c-format +msgid "tsvector column \"%s\" does not exist" +msgstr "\"%s\" sütunu mevcut değil" + +#: utils/adt/tsvector_op.c:2503 +#, fuzzy, c-format +msgid "column \"%s\" is not of tsvector type" +msgstr "\"%s\" sütunu \"%s\" tipine dönüştürülemez" + +#: utils/adt/tsvector_op.c:2515 +#, c-format +msgid "configuration column \"%s\" does not exist" +msgstr "\"%s\" yapılandırma kolonu mevcut değil" + +#: utils/adt/tsvector_op.c:2521 +#, fuzzy, c-format +msgid "column \"%s\" is not of regconfig type" +msgstr "%2$s veri tipinde \"%1$s\" sütunu bulunamadı" + +#: utils/adt/tsvector_op.c:2528 +#, fuzzy, c-format +msgid "configuration column \"%s\" must not be null" +msgstr "\"%s\" sütunu mevcut değil" + +#: utils/adt/tsvector_op.c:2541 +#, fuzzy, c-format +msgid "text search configuration name \"%s\" must be schema-qualified" +msgstr "Şema belirtilmediği takdirde isimlerin hangi şemalarda aranacağını belirtir." + +#: utils/adt/tsvector_op.c:2566 +#, fuzzy, c-format +msgid "column \"%s\" is not of a character type" +msgstr "oid tipi için \"%s\" değeri sıra dışıdır" + +#: utils/adt/tsvector_parser.c:134 +#, c-format +msgid "syntax error in tsvector: \"%s\"" +msgstr "tsvector yazım hatası: \"%s\"" + +#: utils/adt/tsvector_parser.c:200 +#, fuzzy, c-format +msgid "there is no escaped character: \"%s\"" +msgstr "$%d parametresi yoktur" + +#: utils/adt/tsvector_parser.c:318 +#, fuzzy, c-format +msgid "wrong position info in tsvector: \"%s\"" +msgstr "%s ifadesi, %d terinde select listesinde değildir" + +#: utils/adt/txid.c:135 +#, fuzzy, c-format +#| msgid "function %s is not unique" +msgid "transaction ID %s is in the future" +msgstr "%s fonksiyonu benzersiz değildir" + +#: utils/adt/txid.c:624 +#, fuzzy, c-format +#| msgid "invalid external \"cidr\" value" +msgid "invalid external txid_snapshot data" +msgstr "geçersiz harici \"cidr\" değeri" + +#: utils/adt/varbit.c:59 utils/adt/varchar.c:51 +#, c-format +msgid "length for type %s must be at least 1" +msgstr "%s tipinin uzunluğu en az 1 olmalıdır" + +#: utils/adt/varbit.c:64 utils/adt/varchar.c:55 +#, c-format +msgid "length for type %s cannot exceed %d" +msgstr "%s tipin uzunluğu %d değerini aşamaz" + +#: utils/adt/varbit.c:165 utils/adt/varbit.c:477 utils/adt/varbit.c:974 +#, fuzzy, c-format +#| msgid "array size exceeds the maximum allowed (%d)" +msgid "bit string length exceeds the maximum allowed (%d)" +msgstr "dizin boyutu izin verilern en yüksek değerini (%d) aşmaktadır" + +#: utils/adt/varbit.c:179 utils/adt/varbit.c:322 utils/adt/varbit.c:379 +#, c-format +msgid "bit string length %d does not match type bit(%d)" +msgstr "%d bit string uzunluğu bit tipi (%d) ile uyuşmamaktadır" + +#: utils/adt/varbit.c:201 utils/adt/varbit.c:513 +#, c-format +msgid "\"%c\" is not a valid binary digit" +msgstr "\"%c\" geçerli bir ikili rakamı değildir" + +#: utils/adt/varbit.c:226 utils/adt/varbit.c:538 +#, c-format +msgid "\"%c\" is not a valid hexadecimal digit" +msgstr "\"%c\" geçerli bir onaltılı rakamı değildir" + +#: utils/adt/varbit.c:313 utils/adt/varbit.c:629 +#, c-format +msgid "invalid length in external bit string" +msgstr "external bit string uzunuğu geçersiz" + +#: utils/adt/varbit.c:491 utils/adt/varbit.c:638 utils/adt/varbit.c:732 +#, c-format +msgid "bit string too long for type bit varying(%d)" +msgstr "bit varying(%d) tipi için bit string çok uzun" + +#: utils/adt/varbit.c:1067 utils/adt/varbit.c:1169 utils/adt/varlena.c:841 utils/adt/varlena.c:905 utils/adt/varlena.c:1049 utils/adt/varlena.c:2912 utils/adt/varlena.c:2979 +#, c-format +msgid "negative substring length not allowed" +msgstr "dıfırdan küçük altatır uzunluğuna izin verilmiyor" + +#: utils/adt/varbit.c:1226 +#, c-format +msgid "cannot AND bit strings of different sizes" +msgstr "farklı uzunluğa sahip bit stringler üzerinde AND işlemi yapılamaz" + +#: utils/adt/varbit.c:1268 +#, c-format +msgid "cannot OR bit strings of different sizes" +msgstr "farklı uzunluğa sahip bit stringler üzerinde OR işlemi yapılamaz" + +#: utils/adt/varbit.c:1315 +#, c-format +msgid "cannot XOR bit strings of different sizes" +msgstr "farklı uzunluğa sahip bit stringler üzerinde XOR işlemi yapılamaz" + +#: utils/adt/varbit.c:1803 utils/adt/varbit.c:1861 +#, fuzzy, c-format +msgid "bit index %d out of valid range (0..%d)" +msgstr "%d indexi geçerli kapsamın dışındadır: 0..%d" + +#: utils/adt/varbit.c:1812 utils/adt/varlena.c:3170 +#, c-format +msgid "new bit must be 0 or 1" +msgstr "yeni bit 0 veya 1 olmalıdır" + +#: utils/adt/varchar.c:155 utils/adt/varchar.c:308 +#, c-format +msgid "value too long for type character(%d)" +msgstr "character(%d) veri tipi için değer çok uzun" + +#: utils/adt/varchar.c:470 utils/adt/varchar.c:623 +#, c-format +msgid "value too long for type character varying(%d)" +msgstr "varying(%d) veri tipi için çok uzun" + +#: utils/adt/varlena.c:1415 utils/adt/varlena.c:1880 +#, fuzzy, c-format +#| msgid "could not determine interpretation of row comparison operator %s" +msgid "could not determine which collation to use for string comparison" +msgstr "%s satır karşılaştırma operatörünün youmlaması tespit edilemedi" + +#: utils/adt/varlena.c:1472 utils/adt/varlena.c:1485 +#, fuzzy, c-format +#| msgid "could not convert string to UTF-16: error %lu" +msgid "could not convert string to UTF-16: error code %lu" +msgstr "satır, UTF-16 kodlamasanıa çevrilemedi: %lu" + +#: utils/adt/varlena.c:1500 +#, c-format +msgid "could not compare Unicode strings: %m" +msgstr "Unicode satırları karşılaştırılamadı: %m" + +#: utils/adt/varlena.c:1555 utils/adt/varlena.c:2176 +#, fuzzy, c-format +#| msgid "%s: database creation failed: %s" +msgid "collation failed: %s" +msgstr "%s: veritabanı yaratma başarısız oldu: %s" + +#: utils/adt/varlena.c:2394 +#, fuzzy, c-format +#| msgid "%s: database creation failed: %s" +msgid "sort key generation failed: %s" +msgstr "%s: veritabanı yaratma başarısız oldu: %s" + +#: utils/adt/varlena.c:3056 utils/adt/varlena.c:3087 utils/adt/varlena.c:3122 utils/adt/varlena.c:3158 +#, c-format +msgid "index %d out of valid range, 0..%d" +msgstr "%d indexi geçerli kapsamın dışındadır: 0..%d" + +#: utils/adt/varlena.c:4201 +#, c-format +msgid "field position must be greater than zero" +msgstr "alan yeri sıfırdan büyük olmalıdır" + +#: utils/adt/varlena.c:5080 +#, fuzzy, c-format +#| msgid "unterminated quoted identifier" +msgid "unterminated format() type specifier" +msgstr "sonuçlandırılmamış tırnakla sınırlandırılmış tanım" + +#: utils/adt/varlena.c:5081 utils/adt/varlena.c:5215 utils/adt/varlena.c:5336 +#, c-format +msgid "For a single \"%%\" use \"%%%%\"." +msgstr "" + +#: utils/adt/varlena.c:5213 utils/adt/varlena.c:5334 +#, fuzzy, c-format +#| msgid "unrecognized data type name \"%s\"" +msgid "unrecognized format() type specifier \"%c\"" +msgstr "tanımlanmayan veri tipi adı \"%s\"" + +#: utils/adt/varlena.c:5226 utils/adt/varlena.c:5283 +#, fuzzy, c-format +#| msgid "too few arguments on line %d" +msgid "too few arguments for format()" +msgstr "%d. satırda yetersiz argüman sayısı" + +#: utils/adt/varlena.c:5379 utils/adt/varlena.c:5561 +#, fuzzy, c-format +#| msgid "input is out of range" +msgid "number is out of range" +msgstr "giriş sıra dısışıdır" + +#: utils/adt/varlena.c:5442 utils/adt/varlena.c:5470 +#, c-format +msgid "format specifies argument 0, but arguments are numbered from 1" +msgstr "" + +#: utils/adt/varlena.c:5463 +#, fuzzy, c-format +#| msgid "third argument of cast function must be type boolean" +msgid "width argument position must be ended by \"$\"" +msgstr "cast fonksiyonunun üçüncü parametresi boolean tipinde olmalıdır" + +#: utils/adt/varlena.c:5508 +#, c-format +msgid "null values cannot be formatted as an SQL identifier" +msgstr "" + +#: utils/adt/windowfuncs.c:243 +#, fuzzy, c-format +msgid "argument of ntile must be greater than zero" +msgstr "sayısı sıfırdan büyük olmalı" + +#: utils/adt/windowfuncs.c:465 +#, fuzzy, c-format +msgid "argument of nth_value must be greater than zero" +msgstr "sayısı sıfırdan büyük olmalı" + +#: utils/adt/xml.c:220 +#, c-format +msgid "unsupported XML feature" +msgstr "desteklenmeyen XML özelliği" + +#: utils/adt/xml.c:221 +#, c-format +msgid "This functionality requires the server to be built with libxml support." +msgstr "Bu özellik sunucunun libxml desteği ile derlenmesini gerektirir." + +#: utils/adt/xml.c:222 +#, c-format +msgid "You need to rebuild PostgreSQL using --with-libxml." +msgstr "PostgreSQL'i --with-libxml seçeneği ile yeniden derlemeniz gerekiyor." + +#: utils/adt/xml.c:241 utils/mb/mbutils.c:512 +#, c-format +msgid "invalid encoding name \"%s\"" +msgstr "geçersiz dil kodlaması adı \"%s\"" + +#: utils/adt/xml.c:484 utils/adt/xml.c:489 +#, c-format +msgid "invalid XML comment" +msgstr "XML açıklaması geçersiz" + +#: utils/adt/xml.c:618 +#, c-format +msgid "not an XML document" +msgstr "XML dokümanı değildir" + +#: utils/adt/xml.c:777 utils/adt/xml.c:800 +#, c-format +msgid "invalid XML processing instruction" +msgstr "geçersiz XML işleme komutu" + +#: utils/adt/xml.c:778 +#, fuzzy, c-format +msgid "XML processing instruction target name cannot be \"%s\"." +msgstr "XML işleme komut hedefi \"xml\" ile başlayamaz." + +#: utils/adt/xml.c:801 +#, c-format +msgid "XML processing instruction cannot contain \"?>\"." +msgstr "XML işleme komutu \"?>\" içeremez." + +#: utils/adt/xml.c:880 +#, fuzzy, c-format +msgid "xmlvalidate is not implemented" +msgstr "UNIQUE predicate implemente edilmemiştir" + +#: utils/adt/xml.c:959 +#, c-format +msgid "could not initialize XML library" +msgstr "XML kütühanesi ilklendirilemedi" + +#: utils/adt/xml.c:960 +#, c-format +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgstr "libxml2 kütüphanesi uyumsuz karakter veri tipine sahiptir: sizeof(char)=%u, sizeof(xmlChar)=%u." + +#: utils/adt/xml.c:1046 +#, fuzzy, c-format +#| msgid "could not create semaphore: error code %d" +msgid "could not set up XML error handler" +msgstr "semaphore oluşturma hatası: hata kodu %d" + +#: utils/adt/xml.c:1047 +#, c-format +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "" + +#: utils/adt/xml.c:1797 +msgid "Invalid character value." +msgstr "geçersiz karakter değeri" + +#: utils/adt/xml.c:1800 +msgid "Space required." +msgstr "Boşluk gerekiyor." + +#: utils/adt/xml.c:1803 +msgid "standalone accepts only 'yes' or 'no'." +msgstr "" + +#: utils/adt/xml.c:1806 +msgid "Malformed declaration: missing version." +msgstr "" + +#: utils/adt/xml.c:1809 +msgid "Missing encoding in text declaration." +msgstr "" + +#: utils/adt/xml.c:1812 +msgid "Parsing XML declaration: '?>' expected." +msgstr "" + +#: utils/adt/xml.c:1815 +#, fuzzy, c-format +msgid "Unrecognized libxml error code: %d." +msgstr "bilinmeyen SSL hata kodu: %d" + +#: utils/adt/xml.c:2090 +#, fuzzy, c-format +msgid "XML does not support infinite date values." +msgstr "NULLIF, set argümanları desteklememektedir" + +#: utils/adt/xml.c:2112 utils/adt/xml.c:2139 +#, fuzzy, c-format +msgid "XML does not support infinite timestamp values." +msgstr "sonsuz timestap veri tipi üzerinde çıkarma işlemi yapılamaz" + +#: utils/adt/xml.c:2551 +#, c-format +msgid "invalid query" +msgstr "geçersiz sorgu" + +#: utils/adt/xml.c:3874 +#, fuzzy, c-format +msgid "invalid array for XML namespace mapping" +msgstr "namespace eşlemi için geçersiz dizi verilmiştir" + +#: utils/adt/xml.c:3875 +#, c-format +msgid "The array must be two-dimensional with length of the second axis equal to 2." +msgstr "" + +#: utils/adt/xml.c:3899 +#, c-format +msgid "empty XPath expression" +msgstr "boş XPath ifadesi" + +#: utils/adt/xml.c:3951 +#, fuzzy, c-format +msgid "neither namespace name nor URI may be null" +msgstr "ne isim ne de URI, NULL olamaz" + +#: utils/adt/xml.c:3958 +#, fuzzy, c-format +msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" +msgstr "prefix=\"%s\" ve href=\"%s\" olan ad XML namespace oluştutulamaz" + +#: utils/adt/xml.c:4309 +#, fuzzy, c-format +#| msgid "LIMIT #,# syntax is not supported" +msgid "DEFAULT namespace is not supported" +msgstr "LIMIT #,# sözdizimi desteklenmemektedir" + +#: utils/adt/xml.c:4338 +#, c-format +msgid "row path filter must not be empty string" +msgstr "" + +#: utils/adt/xml.c:4369 +#, c-format +msgid "column path filter must not be empty string" +msgstr "" + +#: utils/adt/xml.c:4555 +#, fuzzy, c-format +#| msgid "more than one row returned by a subquery used as an expression" +msgid "more than one value returned by column XPath expression" +msgstr "ifade içinde kullanılan alt sorgusu birden fazla satır döndürüldü" + +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 +#, c-format +msgid "type %s is only a shell" +msgstr "%s tipi sadece bir shell" + +#: utils/cache/lsyscache.c:2659 +#, c-format +msgid "no input function available for type %s" +msgstr "%s tipi için giriş fonksiyonu mevcut değil" + +#: utils/cache/lsyscache.c:2692 +#, c-format +msgid "no output function available for type %s" +msgstr "%s tipi için çıkış fonksiyonu mevcut değil" + +#: utils/cache/partcache.c:202 +#, fuzzy, c-format +#| msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "\"%2s\" erişim yöntemi için kullanılacak %1s operator sınıfının %1d ya da %2d destek fonksiyonu eksik" + +#: utils/cache/plancache.c:723 +#, c-format +msgid "cached plan must not change result type" +msgstr "önbelleğe alınmış plan sonuç tipini değiştiremez" + +#: utils/cache/relcache.c:5800 +#, c-format +msgid "could not create relation-cache initialization file \"%s\": %m" +msgstr "relation-cache tanımlama dosyası \"%s\" açılamadı: %m" + +#: utils/cache/relcache.c:5802 +#, c-format +msgid "Continuing anyway, but there's something wrong." +msgstr "Devam ediyorum, ama bu işlem yanlıştır." + +#: utils/cache/relcache.c:6156 +#, fuzzy, c-format +#| msgid "could not remove file \"%s\": %m" +msgid "could not remove cache file \"%s\": %m" +msgstr "\"%s\" dosyası silinemedi: %m" + +#: utils/cache/relmapper.c:513 +#, fuzzy, c-format +msgid "cannot PREPARE a transaction that modified relation mapping" +msgstr "geçeci tablolarda işlem yapmış transaction'a PREPARE yapılamaz" + +#: utils/cache/relmapper.c:655 utils/cache/relmapper.c:755 +#, fuzzy, c-format +msgid "could not open relation mapping file \"%s\": %m" +msgstr "yeni kayıt dosyası \"%s\" açma hatası: %m" + +#: utils/cache/relmapper.c:669 +#, fuzzy, c-format +msgid "could not read relation mapping file \"%s\": %m" +msgstr "\"%s\" dosyasından okuma hatası: %m" + +#: utils/cache/relmapper.c:680 +#, fuzzy, c-format +msgid "relation mapping file \"%s\" contains invalid data" +msgstr "kontrol dosyası geçersiz veri içeriyor" + +#: utils/cache/relmapper.c:690 +#, c-format +msgid "relation mapping file \"%s\" contains incorrect checksum" +msgstr "" + +#: utils/cache/relmapper.c:789 +#, fuzzy, c-format +msgid "could not write to relation mapping file \"%s\": %m" +msgstr "geçici dosyasına \"%s\" yazma başarısız: %m" + +#: utils/cache/relmapper.c:804 +#, fuzzy, c-format +msgid "could not fsync relation mapping file \"%s\": %m" +msgstr "\"%s\" günlük dosyası oluşturma hatası: %m" + +#: utils/cache/relmapper.c:811 +#, fuzzy, c-format +msgid "could not close relation mapping file \"%s\": %m" +msgstr "\"%s\" dosyası ilerleme hatası: %m" + +#: utils/cache/typcache.c:1623 utils/fmgr/funcapi.c:435 +#, c-format +msgid "record type has not been registered" +msgstr "kayıt tipi tecil edilmemiştir" + +#: utils/error/assert.c:34 +#, c-format +msgid "TRAP: ExceptionalCondition: bad arguments\n" +msgstr "TRAP: ExceptionalCondition: hatalı argümanlar\n" + +#: utils/error/assert.c:37 +#, c-format +msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" +msgstr "TRAP: %s(\"%s\", Dosya: \"%s\", Satır: %d)\n" + +#: utils/error/elog.c:322 utils/error/elog.c:1304 +#, c-format +msgid "error occurred at %s:%d before error message processing is available\n" +msgstr "" + +#: utils/error/elog.c:1882 +#, c-format +msgid "could not reopen file \"%s\" as stderr: %m" +msgstr "\"%s\" dosyası stderr olarak yeiden açılamadı: %m" + +#: utils/error/elog.c:1895 +#, c-format +msgid "could not reopen file \"%s\" as stdout: %m" +msgstr "\"%s\" dosyası stdout olarak yeiden açılamadı: %m" + +#: utils/error/elog.c:2387 utils/error/elog.c:2404 utils/error/elog.c:2420 +msgid "[unknown]" +msgstr "[bilinmeyen]" + +#: utils/error/elog.c:2880 utils/error/elog.c:3183 utils/error/elog.c:3291 +msgid "missing error text" +msgstr "hata mesajı eksik" + +#: utils/error/elog.c:2883 utils/error/elog.c:2886 utils/error/elog.c:3294 utils/error/elog.c:3297 +#, c-format +msgid " at character %d" +msgstr " %d karakterinde " + +#: utils/error/elog.c:2896 utils/error/elog.c:2903 +msgid "DETAIL: " +msgstr "AYRINTI:" + +#: utils/error/elog.c:2910 +msgid "HINT: " +msgstr "İPUCU:" + +#: utils/error/elog.c:2917 +msgid "QUERY: " +msgstr "SORGU:" + +#: utils/error/elog.c:2924 +msgid "CONTEXT: " +msgstr "ORTAM:" + +#: utils/error/elog.c:2934 +#, c-format +msgid "LOCATION: %s, %s:%d\n" +msgstr "YER: %s, %s:%d\n" + +#: utils/error/elog.c:2941 +#, c-format +msgid "LOCATION: %s:%d\n" +msgstr "YER: %s:%d\n" + +#: utils/error/elog.c:2955 +msgid "STATEMENT: " +msgstr "KOMUT: " + +#. translator: This string will be truncated at 47 +#. characters expanded. +#: utils/error/elog.c:3412 +#, c-format +msgid "operating system error %d" +msgstr "işletim sistemi hatası: %d" + +#: utils/error/elog.c:3610 +msgid "DEBUG" +msgstr "DEBUG" + +#: utils/error/elog.c:3614 +msgid "LOG" +msgstr "LOG" + +#: utils/error/elog.c:3617 +msgid "INFO" +msgstr "BİLGİ" + +#: utils/error/elog.c:3620 +msgid "NOTICE" +msgstr "NOT" + +#: utils/error/elog.c:3623 +msgid "WARNING" +msgstr "UYARI" + +#: utils/error/elog.c:3626 +msgid "ERROR" +msgstr "HATA" + +#: utils/error/elog.c:3629 +msgid "FATAL" +msgstr "ÖLÜMCÜL (FATAL)" + +#: utils/error/elog.c:3632 +msgid "PANIC" +msgstr "KRİTİK" + +#: utils/fmgr/dfmgr.c:121 +#, c-format +msgid "could not find function \"%s\" in file \"%s\"" +msgstr "\"%2$s\" dosyasında \"%1$s\" fonksiyonu bulunamadı" + +#: utils/fmgr/dfmgr.c:239 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" kütüphanesi yüklenemedi: %s" + +#: utils/fmgr/dfmgr.c:271 +#, c-format +msgid "incompatible library \"%s\": missing magic block" +msgstr "uyumsuz kütüphane \"%s\": magic block eksik" + +#: utils/fmgr/dfmgr.c:273 +#, c-format +msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." +msgstr "extension kütüphaneleri PG_MODULE_MAGIC makrosunu kullanmak zorundadır." + +#: utils/fmgr/dfmgr.c:319 +#, c-format +msgid "incompatible library \"%s\": version mismatch" +msgstr "uyumsuz kütüphane \"%s\": sürüm uyuşmazlığı" + +#: utils/fmgr/dfmgr.c:321 +#, c-format +msgid "Server is version %d, library is version %s." +msgstr "Sunucu sürümü: %d, kütüphane sürümü: %s." + +#: utils/fmgr/dfmgr.c:338 +#, c-format +msgid "Server has FUNC_MAX_ARGS = %d, library has %d." +msgstr "Sunucuda FUNC_MAX_ARGS = %d, kütüphanede %d." + +#: utils/fmgr/dfmgr.c:347 +#, c-format +msgid "Server has INDEX_MAX_KEYS = %d, library has %d." +msgstr "Sunucuda INDEX_MAX_KEYS = %d, kütüphanede %d." + +#: utils/fmgr/dfmgr.c:356 +#, c-format +msgid "Server has NAMEDATALEN = %d, library has %d." +msgstr "Sunucuda NAMEDATALEN = %d, kütüphanede %d." + +#: utils/fmgr/dfmgr.c:365 +#, c-format +msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." +msgstr "Sunucuda FLOAT4PASSBYVAL = %s, kütüphanede %s." + +#: utils/fmgr/dfmgr.c:374 +#, c-format +msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." +msgstr "Sunucuda FLOAT8PASSBYVAL = %s, kütüphanede %s." + +#: utils/fmgr/dfmgr.c:381 +msgid "Magic block has unexpected length or padding difference." +msgstr "" + +#: utils/fmgr/dfmgr.c:384 +#, c-format +msgid "incompatible library \"%s\": magic block mismatch" +msgstr "uyumsuz kütüphane \"%s\": magic block uyumsuz" + +#: utils/fmgr/dfmgr.c:548 +#, c-format +msgid "access to library \"%s\" is not allowed" +msgstr "\"%s\" kütüphanesine erişim engellendi" + +#: utils/fmgr/dfmgr.c:574 +#, c-format +msgid "invalid macro name in dynamic library path: %s" +msgstr "dinamik kütüphane yolunda geçersiz makro adı: %s" + +#: utils/fmgr/dfmgr.c:614 +#, c-format +msgid "zero-length component in parameter \"dynamic_library_path\"" +msgstr "\"dynamic_library_path\" parametresinde sıfır uzunluklu bileşen" + +#: utils/fmgr/dfmgr.c:633 +#, c-format +msgid "component in parameter \"dynamic_library_path\" is not an absolute path" +msgstr "\"dynamic_library_path\" parametresine bileşen kesin bir yol değildir" + +#: utils/fmgr/fmgr.c:236 +#, c-format +msgid "internal function \"%s\" is not in internal lookup table" +msgstr "\"%s\" dahili fonksiyonu, dahili referans tablosunda yer almamaktadır" + +#: utils/fmgr/fmgr.c:485 +#, c-format +msgid "could not find function information for function \"%s\"" +msgstr "\"%s\" fonksiyonu için bilgi bulunamadı" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "" + +#: utils/fmgr/fmgr.c:505 +#, c-format +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "\"%2$s\" bilgi fonksiyonu tarafından bildirilen API versioynu %1$d tanımlı değildir" + +#: utils/fmgr/fmgr.c:2210 +#, c-format +msgid "language validation function %u called for language %u instead of %u" +msgstr "" + +#: utils/fmgr/funcapi.c:358 +#, c-format +msgid "could not determine actual result type for function \"%s\" declared to return type %s" +msgstr "geri döndürme tipi %2$s olarak tanımlanmış \"%1$s\" fonksiyonunun gerçek döndürme tipi belirlenememektedir" + +#: utils/fmgr/funcapi.c:1403 utils/fmgr/funcapi.c:1435 +#, c-format +msgid "number of aliases does not match number of columns" +msgstr "Takma adların sayısı ile kolon satısı eşleşmiyor" + +#: utils/fmgr/funcapi.c:1429 +#, c-format +msgid "no column alias was provided" +msgstr "kolon takma adı verilmedi" + +#: utils/fmgr/funcapi.c:1453 +#, c-format +msgid "could not determine row description for function returning record" +msgstr "veri satırı döndüren fonksiyon için satır açıklaması bulunamadı" + +#: utils/init/miscinit.c:108 +#, c-format +msgid "data directory \"%s\" does not exist" +msgstr "veritabanı deizini \"%s\" mevcut değil" + +#: utils/init/miscinit.c:113 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" dizininin erişim haklarını okunamıyor: %m" + +#: utils/init/miscinit.c:121 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "belirtilen veri dizini \"%s\" bir dizin değil" + +#: utils/init/miscinit.c:137 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "\"%s\" veritabanı dizininin erişim hakları yanlıştır" + +#: utils/init/miscinit.c:139 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "Sunucu, veri dizini sahip kullanıcı tarafından başlatılmalıdır." + +#: utils/init/miscinit.c:157 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "\"%s\" veri dizininin erişim hakları yanlıştır" + +#: utils/init/miscinit.c:159 +#, fuzzy, c-format +#| msgid "Permissions should be u=rwx (0700)." +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "Erişim hakları u=rwx (0700) olmalıdır." + +#: utils/init/miscinit.c:218 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "çalışma dizini \"%s\" olarak değiştirilemedi: %m" + +#: utils/init/miscinit.c:554 utils/misc/guc.c:6370 +#, fuzzy, c-format +msgid "cannot set parameter \"%s\" within security-restricted operation" +msgstr "var olan bir fonksiyonun döndürme tipi değiştirilemez" + +#: utils/init/miscinit.c:615 +#, c-format +msgid "role with OID %u does not exist" +msgstr "OID %u olan rol mevcut değil" + +#: utils/init/miscinit.c:645 +#, c-format +msgid "role \"%s\" is not permitted to log in" +msgstr " \"%s\" rolünun sisteme giriş hakkı yoktur" + +#: utils/init/miscinit.c:663 +#, c-format +msgid "too many connections for role \"%s\"" +msgstr "\"%s\" rol bağlantı sayısı aşılmıştır" + +#: utils/init/miscinit.c:723 +#, c-format +msgid "permission denied to set session authorization" +msgstr "oturum kimli doğrulama işlemine izin verilmemiş" + +#: utils/init/miscinit.c:806 +#, c-format +msgid "invalid role OID: %u" +msgstr "geçersiz rol OID: %u" + +#: utils/init/miscinit.c:860 +#, c-format +msgid "database system is shut down" +msgstr "veritabanı sistemi kapandı" + +#: utils/init/miscinit.c:947 +#, c-format +msgid "could not create lock file \"%s\": %m" +msgstr "\"%s\" lock dosyası oluşturma hatası: %m" + +#: utils/init/miscinit.c:961 +#, c-format +msgid "could not open lock file \"%s\": %m" +msgstr "\"%s\" lock dosyası okuma hatası: %m" + +#: utils/init/miscinit.c:968 +#, c-format +msgid "could not read lock file \"%s\": %m" +msgstr "\"%s\" lock dosyası okuma hatası: %m" + +#: utils/init/miscinit.c:977 +#, c-format +msgid "lock file \"%s\" is empty" +msgstr "\"%s\" kilit (lock) dosyası boştur" + +#: utils/init/miscinit.c:978 +#, c-format +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "" + +#: utils/init/miscinit.c:1022 +#, c-format +msgid "lock file \"%s\" already exists" +msgstr "\"%s\" lock dosyası zaten mevcuttur" + +#: utils/init/miscinit.c:1026 +#, c-format +msgid "Is another postgres (PID %d) running in data directory \"%s\"?" +msgstr "\"%2$s\" veritabanı dizini kullanarak PID %1$d olan başka bir istemci süreci çalışmakta mıdır?" + +#: utils/init/miscinit.c:1028 +#, c-format +msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" +msgstr "\"%2$s\" veritabanı dizini kullanarak PID %1$d olan başka bir sunucu çalışmakta mıdır?" + +#: utils/init/miscinit.c:1031 +#, c-format +msgid "Is another postgres (PID %d) using socket file \"%s\"?" +msgstr "\"%2$s\" kullanarak kullanarak PID %1$d olan başka bir istemci süreci çalışmakta mıdır?" + +#: utils/init/miscinit.c:1033 +#, c-format +msgid "Is another postmaster (PID %d) using socket file \"%s\"?" +msgstr "\"%2$s\" kullanarak kullanarak PID %1$d olan başka bir sunucu çalışmakta mıdır?" + +#: utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "daha önce tanımlanmış shared memory blok (key %lu, ID %lu) hala kullanılmaktadır" + +#: utils/init/miscinit.c:1072 +#, fuzzy, c-format +msgid "If you're sure there are no old server processes still running, remove the shared memory block or just delete the file \"%s\"." +msgstr "Eğer eski sunucunun sürecicinin çalımadığından emin iseniz, shared memory bloku \"ipcclean\", \"ipcrm\" komutları ile kaldırın ya da \"%s\" dosyasını silin." + +#: utils/init/miscinit.c:1088 +#, c-format +msgid "could not remove old lock file \"%s\": %m" +msgstr "\"%s\" lock dosyası silinemiyor: %m" + +#: utils/init/miscinit.c:1090 +#, c-format +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." +msgstr "Dosya yanlışlıkla eski süreç tarafından bırakılmış ve kaldırılamıyor. Lütfen onu elle silin ve tekrar deneyin." + +#: utils/init/miscinit.c:1127 utils/init/miscinit.c:1141 utils/init/miscinit.c:1152 +#, c-format +msgid "could not write lock file \"%s\": %m" +msgstr "\"%s\" lock dosyası yazma hatası: %m" + +#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1427 utils/misc/guc.c:9211 +#, c-format +msgid "could not read from file \"%s\": %m" +msgstr "\"%s\" dosyasından okuma hatası: %m" + +#: utils/init/miscinit.c:1415 +#, fuzzy, c-format +#| msgid "could not open file \"%s\": %m" +msgid "could not open file \"%s\": %m; continuing anyway" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: utils/init/miscinit.c:1440 +#, fuzzy, c-format +#| msgid "archive file \"%s\" has wrong size: %lu instead of %lu" +msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" +msgstr "\"%s\" arşiv dosyası yanlış boyuta sahip: %lu yerine %lu olmalıydı." + +#: utils/init/miscinit.c:1479 utils/init/miscinit.c:1495 +#, c-format +msgid "\"%s\" is not a valid data directory" +msgstr "\"%s\" geçerli bir veritabanı dizini değildir" + +#: utils/init/miscinit.c:1481 +#, c-format +msgid "File \"%s\" is missing." +msgstr "\"%s\" dosyası eksik." + +#: utils/init/miscinit.c:1497 +#, c-format +msgid "File \"%s\" does not contain valid data." +msgstr "\"%s\" dosyası geçerli bilgi içermiyor." + +#: utils/init/miscinit.c:1499 +#, c-format +msgid "You might need to initdb." +msgstr "initdb yapmanız gerekebilir." + +#: utils/init/miscinit.c:1507 +#, fuzzy, c-format +#| msgid "The data directory was initialized by PostgreSQL version %ld.%ld, which is not compatible with this version %s." +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "Veri dizini PostgreSQL %ld.%ld sürümü tarafından oluşturulmuştur ve kullandığınız %s sürümü ile uyumlu değildir." + +#: utils/init/miscinit.c:1574 +#, c-format +msgid "loaded library \"%s\"" +msgstr "\"%s\" kütüphanesi yüklendi" + +#: utils/init/postinit.c:252 +#, fuzzy, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "bağlantı tanımı: kullanıcı=%s veritabanı=%s" + +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "off" +msgstr "kapalı" + +#: utils/init/postinit.c:257 utils/init/postinit.c:274 +msgid "on" +msgstr "açık" + +#: utils/init/postinit.c:261 +#, fuzzy, c-format +msgid "replication connection authorized: user=%s" +msgstr "bağlantı tanımı: kullanıcı=%s veritabanı=%s" + +#: utils/init/postinit.c:269 +#, fuzzy, c-format +#| msgid "connection authorized: user=%s database=%s" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "bağlantı tanımı: kullanıcı=%s veritabanı=%s" + +#: utils/init/postinit.c:278 +#, c-format +msgid "connection authorized: user=%s database=%s" +msgstr "bağlantı tanımı: kullanıcı=%s veritabanı=%s" + +#: utils/init/postinit.c:310 +#, c-format +msgid "database \"%s\" has disappeared from pg_database" +msgstr "\"%s\" veritabanı pg_database tablosundan yok olmuş" + +#: utils/init/postinit.c:312 +#, c-format +msgid "Database OID %u now seems to belong to \"%s\"." +msgstr "OID %u olan veritabanı \"%s\" kullanıcıya aittir." + +#: utils/init/postinit.c:332 +#, c-format +msgid "database \"%s\" is not currently accepting connections" +msgstr "\"%s\" veritabanı şu anda bağlatı kabul etmiyor" + +#: utils/init/postinit.c:345 +#, c-format +msgid "permission denied for database \"%s\"" +msgstr "\"%s\" veritabanına erişim engellendi" + +#: utils/init/postinit.c:346 +#, c-format +msgid "User does not have CONNECT privilege." +msgstr "Kullanicinin CONNECT yetkisi verilmemiştir." + +#: utils/init/postinit.c:363 +#, c-format +msgid "too many connections for database \"%s\"" +msgstr "\"%s\" veritabanı bağlantı sayısı aşılmıştır" + +#: utils/init/postinit.c:385 utils/init/postinit.c:392 +#, c-format +msgid "database locale is incompatible with operating system" +msgstr "veritabanı yereli işletim sistemi ile uyumlu değildir" + +#: utils/init/postinit.c:386 +#, fuzzy, c-format +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "Veritabanı LC_COLLATE \"%s\", ile ilklendirilmiştir, ancak setlocale() bu yereli tanımamaktadır.." + +#: utils/init/postinit.c:388 utils/init/postinit.c:395 +#, c-format +msgid "Recreate the database with another locale or install the missing locale." +msgstr "" + +#: utils/init/postinit.c:393 +#, fuzzy, c-format +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "Veritabanı LC_CTYPE \"%s\", ile ilklendirilmiştir, ancak setlocale() bunu tanımamaktadır.." + +#: utils/init/postinit.c:726 +#, c-format +msgid "no roles are defined in this database system" +msgstr "bu veritabanı sisteminde tanımlanmış rol bulunamadı" + +#: utils/init/postinit.c:727 +#, fuzzy, c-format +msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." +msgstr "Hemen CREATE USER \"%s\" CREATEUSER; komutunu çalıştırmalısınız." + +#: utils/init/postinit.c:763 +#, fuzzy, c-format +msgid "new replication connections are not allowed during database shutdown" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: utils/init/postinit.c:767 +#, fuzzy, c-format +msgid "must be superuser to connect during database shutdown" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: utils/init/postinit.c:777 +#, fuzzy, c-format +msgid "must be superuser to connect in binary upgrade mode" +msgstr "superuser kullanıcısını oluşturmak için superuser olmalısınız" + +#: utils/init/postinit.c:791 +#, c-format +msgid "remaining connection slots are reserved for non-replication superuser connections" +msgstr "kalan bağlantı sayısı, replikasyon dışındaki superuser bağlantıları için ayrıldı" + +#: utils/init/postinit.c:801 +#, fuzzy, c-format +#| msgid "must be superuser to start walsender" +msgid "must be superuser or replication role to start walsender" +msgstr "walsender sürecini başlatmak için superuser olmak gereklidir" + +#: utils/init/postinit.c:870 +#, c-format +msgid "database %u does not exist" +msgstr "%u veritabanı mevcut değil" + +#: utils/init/postinit.c:959 +#, c-format +msgid "It seems to have just been dropped or renamed." +msgstr "Az önce kaldırılmış veya adını değiştirilmiştir." + +#: utils/init/postinit.c:977 +#, c-format +msgid "The database subdirectory \"%s\" is missing." +msgstr "Veritabanı alt dizini \"%s\" eksik." + +#: utils/init/postinit.c:982 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" dizine erişim hatası: %m" + +#: utils/mb/conv.c:488 utils/mb/conv.c:680 +#, c-format +msgid "invalid encoding number: %d" +msgstr "kodlama numarası geçersiz: %d" + +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 +#, c-format +msgid "unexpected encoding ID %d for ISO 8859 character sets" +msgstr "ISO-8859 karakter kümesi için beklemnmeyen kodlama ID %d" + +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 +#, c-format +msgid "unexpected encoding ID %d for WIN character sets" +msgstr "WIN karakter kümeleri için beklemnmeyen kodlama ID %d" + +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "\"%s\" kodlaması ICU tarafından desteklenmemektedir" + +#: utils/mb/encnames.c:572 +#, c-format +msgid "encoding name too long" +msgstr "kodlama ismi çok uzun" + +#: utils/mb/mbutils.c:296 +#, c-format +msgid "conversion between %s and %s is not supported" +msgstr "%s ile %s arasında conversion desteklenmemektedir" + +#: utils/mb/mbutils.c:355 +#, c-format +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgstr "\"%s\" kodlamasından \"%s\" varsayılan kodlamasına dönüştürme fonksiyonu mevcut değildir" + +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 +#, c-format +msgid "String of %d bytes is too long for encoding conversion." +msgstr "" + +#: utils/mb/mbutils.c:453 +#, c-format +msgid "invalid source encoding name \"%s\"" +msgstr "geçersiz kaynak dil kodlaması adı \"%s\"" + +#: utils/mb/mbutils.c:458 +#, c-format +msgid "invalid destination encoding name \"%s\"" +msgstr "geçersiz hedef dil kodlaması adı \"%s\"" + +#: utils/mb/mbutils.c:598 +#, c-format +msgid "invalid byte value for encoding \"%s\": 0x%02x" +msgstr "\"%s\" dil kodlaması için geçersiz bayt değeri: 0x%02x" + +#: utils/mb/mbutils.c:940 +#, c-format +msgid "bind_textdomain_codeset failed" +msgstr "bind_textdomain_codeset başarısız oldu" + +#: utils/mb/wchar.c:2015 +#, c-format +msgid "invalid byte sequence for encoding \"%s\": %s" +msgstr "\"%s\" dil kodlaması için geçersiz bayt dizisi: %s" + +#: utils/mb/wchar.c:2048 +#, fuzzy, c-format +#| msgid "character 0x%s of encoding \"%s\" has no equivalent in \"%s\"" +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" +msgstr "\"%2$s\" kodlamasının 0x%1$s karakterinin \"%3$s\" kodlamasında karşılığı yoktur" + +#: utils/misc/guc.c:572 +msgid "Ungrouped" +msgstr "Diğer" + +#: utils/misc/guc.c:574 +msgid "File Locations" +msgstr "Dosya Konumları" + +#: utils/misc/guc.c:576 +msgid "Connections and Authentication" +msgstr "Bağlantı ve Kimlik Doğrulamaları" + +#: utils/misc/guc.c:578 +msgid "Connections and Authentication / Connection Settings" +msgstr "Bağlantılar ve Kimlik Doğrulaması/ Bağlantı Ayarları" + +#: utils/misc/guc.c:580 +msgid "Connections and Authentication / Authentication" +msgstr "Bağlantılar ve Kimlik Doğrulaması / Kimlik Doğrulaması" + +#: utils/misc/guc.c:582 +msgid "Connections and Authentication / SSL" +msgstr "Bağlantılar ve Kimlik Doğrulaması / SSL" + +#: utils/misc/guc.c:584 +msgid "Resource Usage" +msgstr "Kaynak Kullanımı" + +#: utils/misc/guc.c:586 +msgid "Resource Usage / Memory" +msgstr "Kaynak Kullanımı / Bellek" + +#: utils/misc/guc.c:588 +msgid "Resource Usage / Disk" +msgstr "Kaynak Kullanımı / Disk" + +#: utils/misc/guc.c:590 +msgid "Resource Usage / Kernel Resources" +msgstr "Kaynak Kullanımı / Kernel Kaynakları" + +#: utils/misc/guc.c:592 +#, fuzzy +msgid "Resource Usage / Cost-Based Vacuum Delay" +msgstr "Kaynak Kullanımı / Boş Alan Haritası" + +#: utils/misc/guc.c:594 +msgid "Resource Usage / Background Writer" +msgstr "Kaynak Kullanımı / Background Writer" + +#: utils/misc/guc.c:596 +msgid "Resource Usage / Asynchronous Behavior" +msgstr "Kaynak Kullanımı / Asenkron davranış" + +#: utils/misc/guc.c:598 +msgid "Write-Ahead Log" +msgstr "Write-Ahead Log" + +#: utils/misc/guc.c:600 +msgid "Write-Ahead Log / Settings" +msgstr "Write-Ahead Log / Ayarlar" + +#: utils/misc/guc.c:602 +msgid "Write-Ahead Log / Checkpoints" +msgstr "Write-Ahead Log / Checkpoints" + +#: utils/misc/guc.c:604 +msgid "Write-Ahead Log / Archiving" +msgstr "Write-Ahead Log / Arşivleme" + +#: utils/misc/guc.c:606 +#, fuzzy +msgid "Replication" +msgstr "Hedef" + +#: utils/misc/guc.c:608 +msgid "Replication / Sending Servers" +msgstr "" + +#: utils/misc/guc.c:610 +msgid "Replication / Master Server" +msgstr "" + +#: utils/misc/guc.c:612 +#, fuzzy +#| msgid "Write-Ahead Log / Standby Servers" +msgid "Replication / Standby Servers" +msgstr "Write-Ahead Log / Standby sunucuları" + +#: utils/misc/guc.c:614 +#, fuzzy +msgid "Replication / Subscribers" +msgstr "Hedef" + +#: utils/misc/guc.c:616 +msgid "Query Tuning" +msgstr "Sorgu Performans Ayarları" + +#: utils/misc/guc.c:618 +msgid "Query Tuning / Planner Method Configuration" +msgstr "Sorgu Ayarları / Planlayıcı Metot Yapılandırması" + +#: utils/misc/guc.c:620 +msgid "Query Tuning / Planner Cost Constants" +msgstr "Sorgu Ayarları / Planlayıcı Cost Değişkenleri" + +#: utils/misc/guc.c:622 +msgid "Query Tuning / Genetic Query Optimizer" +msgstr "Sorgu Ayarları / Genetik Sorgu Optimizatörü" + +#: utils/misc/guc.c:624 +msgid "Query Tuning / Other Planner Options" +msgstr "Sorgu Ayarları / Planner'in Diğer Seçenekleri" + +#: utils/misc/guc.c:626 +msgid "Reporting and Logging" +msgstr "Raporlama ve Loglama" + +#: utils/misc/guc.c:628 +msgid "Reporting and Logging / Where to Log" +msgstr "Raporlama ve Günlük / Günlük Yeri" + +#: utils/misc/guc.c:630 +msgid "Reporting and Logging / When to Log" +msgstr "Raporlama ve Günlük / Günlük Tutma Zamanı" + +#: utils/misc/guc.c:632 +msgid "Reporting and Logging / What to Log" +msgstr "Reporting and Logging / Günlük İçeriği" + +#: utils/misc/guc.c:634 +msgid "Process Title" +msgstr "" + +#: utils/misc/guc.c:636 +msgid "Statistics" +msgstr "İstatistikler" + +#: utils/misc/guc.c:638 +msgid "Statistics / Monitoring" +msgstr "İstatistikler / Denetlemeler" + +#: utils/misc/guc.c:640 +msgid "Statistics / Query and Index Statistics Collector" +msgstr "İstatistikler / Sorgu ve İndeks İstatistik Toplayıcı" + +#: utils/misc/guc.c:642 +msgid "Autovacuum" +msgstr "Autovacuum" + +#: utils/misc/guc.c:644 +msgid "Client Connection Defaults" +msgstr "İstemci Bağlantı Varsayılanları" + +#: utils/misc/guc.c:646 +msgid "Client Connection Defaults / Statement Behavior" +msgstr "İstemci Bağlantı Varsayılan Seçenekleri / Deyim Davranışı" + +#: utils/misc/guc.c:648 +msgid "Client Connection Defaults / Locale and Formatting" +msgstr "İstemci Bağlantı Varsayılan Seçenekleri / Yerelleştirme ve Biçimlendirme" + +#: utils/misc/guc.c:650 +#, fuzzy +#| msgid "Client Connection Defaults / Locale and Formatting" +msgid "Client Connection Defaults / Shared Library Preloading" +msgstr "İstemci Bağlantı Varsayılan Seçenekleri / Yerelleştirme ve Biçimlendirme" + +#: utils/misc/guc.c:652 +msgid "Client Connection Defaults / Other Defaults" +msgstr "İstemci Bağlantısı Varsayılan Değerler / Diğer Varsayılanlar" + +#: utils/misc/guc.c:654 +msgid "Lock Management" +msgstr "Lock Yönetimi" + +#: utils/misc/guc.c:656 +msgid "Version and Platform Compatibility" +msgstr "Sürüm ve Platform Uyumluluğu" + +#: utils/misc/guc.c:658 +msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" +msgstr "Sürüm ve Platform Uyumluluğu / Önceki PostgreSQL Sürümleri" + +#: utils/misc/guc.c:660 +msgid "Version and Platform Compatibility / Other Platforms and Clients" +msgstr "Sürüm ve Platform Uyumluluğu / Diğer Platform ve İstemci" + +#: utils/misc/guc.c:662 +msgid "Error Handling" +msgstr "Hata İşleme" + +#: utils/misc/guc.c:664 +msgid "Preset Options" +msgstr "Önceden Tanımlanmış Seçenekler" + +#: utils/misc/guc.c:666 +msgid "Customized Options" +msgstr "Özel Ayarlar" + +#: utils/misc/guc.c:668 +msgid "Developer Options" +msgstr "Program geliştirici Seçenekleri" + +#: utils/misc/guc.c:722 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "Bu parametre için geçerli birimler \"B\", \"kB\", \"MB\", \"GB\" ve \"TB\" 'dır." + +#: utils/misc/guc.c:764 +msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgstr "Bu parametre için geçerli birimler: \"ms\", \"s\", \"min\", \"h\", ve \"d\"." + +#: utils/misc/guc.c:823 +msgid "Enables the planner's use of sequential-scan plans." +msgstr "Planlayıcının sequential-scan planları kullanmaya izin ver." + +#: utils/misc/guc.c:832 +msgid "Enables the planner's use of index-scan plans." +msgstr "Planlayıcının index-scan planları kullanmaya izin ver." + +#: utils/misc/guc.c:841 +msgid "Enables the planner's use of index-only-scan plans." +msgstr "Planlayıcının index-only-scan planları kullanmasına izin verir." + +#: utils/misc/guc.c:850 +msgid "Enables the planner's use of bitmap-scan plans." +msgstr "Planlayıcının bitmap-scan planları kullanmaya izin veriyor." + +#: utils/misc/guc.c:859 +msgid "Enables the planner's use of TID scan plans." +msgstr "Planlayıcının TID scan planları kullanmaya izin ver." + +#: utils/misc/guc.c:868 +msgid "Enables the planner's use of explicit sort steps." +msgstr "Planlayıcının açık sıralama adımlarını kullanmaya izin ver." + +#: utils/misc/guc.c:877 +msgid "Enables the planner's use of hashed aggregation plans." +msgstr "Planlayıcının hashed aggregatin planlarını kullanmaya izin ver." + +#: utils/misc/guc.c:886 +msgid "Enables the planner's use of materialization." +msgstr "Planlayıcının maddileştirme (materialization) kullanmasına izin verir." + +#: utils/misc/guc.c:895 +msgid "Enables the planner's use of nested-loop join plans." +msgstr "Planlayıcının nested-loop planları kullanmaya izin ver." + +#: utils/misc/guc.c:904 +msgid "Enables the planner's use of merge join plans." +msgstr "Planlayıcının merge join planları kullanmaya izin ver." + +#: utils/misc/guc.c:913 +msgid "Enables the planner's use of hash join plans." +msgstr "Planlayıcının hash join planları kullanmaya izin ver." + +#: utils/misc/guc.c:922 +#, fuzzy +#| msgid "Enables the planner's use of merge join plans." +msgid "Enables the planner's use of gather merge plans." +msgstr "Planlayıcının merge join planları kullanmaya izin ver." + +#: utils/misc/guc.c:931 +msgid "Enables partitionwise join." +msgstr "" + +#: utils/misc/guc.c:940 +msgid "Enables partitionwise aggregation and grouping." +msgstr "" + +#: utils/misc/guc.c:949 +#, fuzzy +#| msgid "Enables the planner's use of merge join plans." +msgid "Enables the planner's use of parallel append plans." +msgstr "Planlayıcının merge join planları kullanmaya izin ver." + +#: utils/misc/guc.c:958 +#, fuzzy +#| msgid "Enables the planner's use of hash join plans." +msgid "Enables the planner's use of parallel hash plans." +msgstr "Planlayıcının hash join planları kullanmaya izin ver." + +#: utils/misc/guc.c:967 +msgid "Enable plan-time and run-time partition pruning." +msgstr "" + +#: utils/misc/guc.c:968 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "" + +#: utils/misc/guc.c:978 +msgid "Enables genetic query optimization." +msgstr "Genetic query optimization algoritmasını etkinleştiriyor." + +#: utils/misc/guc.c:979 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "Bu algoritma planlamayı, tam bir arama yapılamadan yapmayı deniyor." + +#: utils/misc/guc.c:989 +msgid "Shows whether the current user is a superuser." +msgstr "Geçerli kullanıcının superuser olup olmadığını gösterir" + +#: utils/misc/guc.c:999 +msgid "Enables advertising the server via Bonjour." +msgstr "Bonjour ile sunucunun duyurulmasını etkinleştirir." + +#: utils/misc/guc.c:1008 +msgid "Collects transaction commit time." +msgstr "İşlem (transaction) commit zamanını toplar." + +#: utils/misc/guc.c:1017 +msgid "Enables SSL connections." +msgstr "SSL bağlantıları etkinleştiriyor." + +#: utils/misc/guc.c:1026 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "" + +#: utils/misc/guc.c:1035 +msgid "Give priority to server ciphersuite order." +msgstr "Sunucu ciphersuite sırasına öncelik ver." + +#: utils/misc/guc.c:1044 +msgid "Forces synchronization of updates to disk." +msgstr "Disk göncellemelerin anuyumlu olmasını zorluyor" + +#: utils/misc/guc.c:1045 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "Sunucu, güncellemelerin fiziksel olarak diske yazılmasına emin olmak için fsync() sistem fonksiyonunu kullanıyor. Bu, işletim sistemi veya donanımın çöküşünden sonra veritabanı cluster'in tutarlı bir duruma kurtarılmasını garantiliyor." + +#: utils/misc/guc.c:1056 +msgid "Continues processing after a checksum failure." +msgstr "Bir sağlama (checksum) hatasından sonra işlemeye devam eder." + +#: utils/misc/guc.c:1057 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "" +"Bozuk bir sayfanın tespiti genellikle PostgreSQL'in geçerli işlemi (transaction) durdurup hata mesajı vermesine yol açar. ignore_checksum_failure parametresi true olarak ayarlamak sistemin hataya aldırmadan (yine de bir uyarı raporlayarak), işlemeye devam etmesine sebep olur. Bu davranış çökmelere ve başka ciddi sorunlara sebep olabilir. Yalnızca sağlamalar (checksum) etkinse bir " +"etkisi olur." + +#: utils/misc/guc.c:1071 +msgid "Continues processing past damaged page headers." +msgstr "Bozulmuş sayfa başlıkları atlayarak işlemeye devam ediyor." + +#: utils/misc/guc.c:1072 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "Bozuk bir sayfanın algılanması genellikle PostgreSQL'in hatanın raporlaması ve geçerli transactionun durdururlmasına yol açıyor. zero_damaged_pages parametresine true atayınca, sistem bir uyarı raporlayıp, hatalı sayfayı sıfırlayıp işlemeye devam etmesine sebep oluyor. Bu davranış, bozuk sayfadaki tüm satırları silecektir." + +#: utils/misc/guc.c:1085 +msgid "Writes full pages to WAL when first modified after a checkpoint." +msgstr "Checkpoint sonrasında ilk değiştirildiğinde sayfayı tamamiyle WAL loguna yazıyor." + +#: utils/misc/guc.c:1086 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "İşletim sistemi çöktüğü anda sayfa diske yazması işlemi gerçekleştiriyorsa, sayfa, sadece kısmen yazılmış olabilir. Dolayısıyla kurtarma sırasında WAL içinde kaydedilmiş satır değişiklikleri yetersiz olabilir. Bu seçenek, sayfaları, checkpoint işleminden sonra ilk değiştirildiğinde sadece değişikliği değil, tam sayfayı WAL loguna yazıyor böylece tam bir kurtarmaya olanak tanıyor." + +#: utils/misc/guc.c:1099 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "Checkpoint sonrasında ilk değiştirildiğinde-kritik olmayan değişiklikler için dahi- sayfayı tamamıyla WAL loguna yazar." + +#: utils/misc/guc.c:1109 +msgid "Compresses full-page writes written in WAL file." +msgstr "WAL dosyasına yazılan full-page write'ları sıkıştırır" + +#: utils/misc/guc.c:1119 +msgid "Logs each checkpoint." +msgstr "Her checkpoint işlemini kaydeder" + +#: utils/misc/guc.c:1128 +msgid "Logs each successful connection." +msgstr "Her başarılı bağlantıyı günlüğüne kaydediyor." + +#: utils/misc/guc.c:1137 +msgid "Logs end of a session, including duration." +msgstr "Outum sonu ve toplam zamanı günlüğüne kaydediyor." + +#: utils/misc/guc.c:1146 +msgid "Logs each replication command." +msgstr "Her replikasyon komutunu loglar" + +#: utils/misc/guc.c:1155 +msgid "Shows whether the running server has assertion checks enabled." +msgstr "Çalışan sunucunun onaylama kontrollerinin (assertion check) etkin olup olmadığını gösterir." + +#: utils/misc/guc.c:1170 +msgid "Terminate session on any error." +msgstr "Harhangi bir hatada oturumu sonlandır." + +#: utils/misc/guc.c:1179 +msgid "Reinitialize server after backend crash." +msgstr "Arka uç (backend) çökmesinden sonra sunucuyu tekrar başlat." + +#: utils/misc/guc.c:1189 +msgid "Logs the duration of each completed SQL statement." +msgstr "Tamamlanmış her SQL sorgusunun süresini günlüğüne kaydediyor." + +#: utils/misc/guc.c:1198 +msgid "Logs each query's parse tree." +msgstr "Her sorgunun ayrıştırma ağacını (parse tree) loglar." + +#: utils/misc/guc.c:1207 +msgid "Logs each query's rewritten parse tree." +msgstr "Her sorgunun yeniden yazılan ayrıştırma ağacını (parse tree) loglar." + +#: utils/misc/guc.c:1216 +msgid "Logs each query's execution plan." +msgstr "Her sorgunun çalışma planını loglar" + +#: utils/misc/guc.c:1225 +msgid "Indents parse and plan tree displays." +msgstr "Ayrıştırma ve plan ağaçları girintili yazıyor." + +#: utils/misc/guc.c:1234 +msgid "Writes parser performance statistics to the server log." +msgstr "Ayrıştırıcı perfomans istatistiklerinin sunucu günlüğüne yazıyor." + +#: utils/misc/guc.c:1243 +msgid "Writes planner performance statistics to the server log." +msgstr "Planlayıcı perfomans istatistiklerinin sunucu günlüğüne yazıyor." + +#: utils/misc/guc.c:1252 +msgid "Writes executor performance statistics to the server log." +msgstr "Yürütücü perfomans istatistiklerinin sunucu günlüğüne yazıyor." + +#: utils/misc/guc.c:1261 +msgid "Writes cumulative performance statistics to the server log." +msgstr "Birikimli perfomans istatistiklerinin sunucu günlüğüne yazıyor." + +#: utils/misc/guc.c:1271 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." +msgstr "Çeşitli B-tree işlemlerinde sistem kaynağı kullanım istatistiklerini (bellek ve CPU) loglar." + +#: utils/misc/guc.c:1283 +msgid "Collects information about executing commands." +msgstr "Yürütülen komutların istatistik bilgilerini topluyor." + +#: utils/misc/guc.c:1284 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." +msgstr "Her oturumunun şu anda yürütülen komutlarının bilgi ve komutun başlatma zamanı toplamayı etkinleştir." + +#: utils/misc/guc.c:1294 +msgid "Collects statistics on database activity." +msgstr "Veritabanı etkinliği sırasında istatistikleri toplar." + +#: utils/misc/guc.c:1303 +msgid "Collects timing statistics for database I/O activity." +msgstr "Veritabanı G/Ç (I/O) etkinliği için zamanlama istatistiklerini toplar." + +#: utils/misc/guc.c:1313 +msgid "Updates the process title to show the active SQL command." +msgstr "Sürecin başlığında işlemede olan SQL komutu gösterilecek." + +#: utils/misc/guc.c:1314 +msgid "Enables updating of the process title every time a new SQL command is received by the server." +msgstr "Sunucu tarafından her yeni SQL komutu alındığında sürecin başlığı güncellenecektir." + +#: utils/misc/guc.c:1327 +msgid "Starts the autovacuum subprocess." +msgstr "Otomatik vacuum alt sürecini başlatıyor." + +#: utils/misc/guc.c:1337 +msgid "Generates debugging output for LISTEN and NOTIFY." +msgstr "LISTEN ve NOTIFY için hata ayıklama çıkışını üretiyor." + +#: utils/misc/guc.c:1349 +msgid "Emits information about lock usage." +msgstr "Kilit kullanımı hakkında bilgi verir." + +#: utils/misc/guc.c:1359 +msgid "Emits information about user lock usage." +msgstr "Kullanıcı kilit kullanımı hakkında bilgi verir." + +#: utils/misc/guc.c:1369 +msgid "Emits information about lightweight lock usage." +msgstr "Hafif (lightweight) kilit kullanımı hakkında bilgi verir." + +#: utils/misc/guc.c:1379 +msgid "Dumps information about all current locks when a deadlock timeout occurs." +msgstr "Kilitlenme zaman aşımı (deadlock timeout) meydana geldiğinde tüm mevcut kilitler hakkında bilgi verir." + +#: utils/misc/guc.c:1391 +msgid "Logs long lock waits." +msgstr "Çok uzun sürek lock işlemlerini kaydeder." + +#: utils/misc/guc.c:1401 +msgid "Logs the host name in the connection logs." +msgstr "Bağlantı günlüğünde makine adını kaydediyor." + +#: utils/misc/guc.c:1402 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "Vasayılan ayarında bağlantı günlüğünde sadece IP adresi yazılıyor. Eğer makine adının de kaydedilmesini istiyorsanız bu ayarı açın ancak bu durumda maine adı çözümlemesi küçük bir performans düşüşüne sebep olacaktır." + +#: utils/misc/guc.c:1413 +msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." +msgstr "\"expr=NULL\" ifadesini \"expr IS NULL\" olarak yorumlanıyor." + +#: utils/misc/guc.c:1414 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "Çık ise, expr = NULL (veya NULL = expr) şeklindeki ifadeler xpr IS NULL olarak algılanıyor, yani expr eğer null sonuç veriyorsa true, aksi taktirde false sonuçu getiriyor. Doğru davranış ise exp = NULL ifadesinin her zamn null döndürmesidir." + +#: utils/misc/guc.c:1426 +msgid "Enables per-database user names." +msgstr "Veritabanı bazlı kullanıcı isimlerini etkinleştiriyor." + +#: utils/misc/guc.c:1435 +msgid "Sets the default read-only status of new transactions." +msgstr "Yeni transactionlar için salt okunur durumunu ayarlıyor." + +#: utils/misc/guc.c:1444 +msgid "Sets the current transaction's read-only status." +msgstr "Geçerli transactionlar için salt okunur durumunu ayarlıyor." + +#: utils/misc/guc.c:1454 +msgid "Sets the default deferrable status of new transactions." +msgstr "Yeni işlemler (transaction) için varsayılan ertelenebilme (deferrable) durumunu ayarlar." + +#: utils/misc/guc.c:1463 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "" + +#: utils/misc/guc.c:1473 +msgid "Enable row security." +msgstr "Satır güvenliğini etkinleştir." + +#: utils/misc/guc.c:1474 +msgid "When enabled, row security will be applied to all users." +msgstr "Etkinleştirildiğinde satır güvenliği tüm kullanıcılara uygulanır." + +#: utils/misc/guc.c:1482 +msgid "Check function bodies during CREATE FUNCTION." +msgstr "CREATE FUNCTION sırasında fonksiyon gövdelerini kontrol ediyor." + +#: utils/misc/guc.c:1491 +msgid "Enable input of NULL elements in arrays." +msgstr "Arrayların çıktılarında NULL elemntlerinin yansıtmasını etkinleştir." + +#: utils/misc/guc.c:1492 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "Açık olduğunda, array girdisinde tırnak içinde alınmamış NULL değeri null anlamına gelir; aksi takdirde değer, olduğu gibi kabul edilir." + +#: utils/misc/guc.c:1502 +msgid "Create new tables with OIDs by default." +msgstr "Varsayılan olarak yeni tabloları OID ile oluştur." + +#: utils/misc/guc.c:1511 +#, fuzzy +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." +msgstr "stderr çıktısını günlük dosyasın kaydetmek için bir alt sürecini çalıştırıyor" + +#: utils/misc/guc.c:1520 +msgid "Truncate existing log files of same name during log rotation." +msgstr "Günlük dosyaları döndürme sırasında aynı isimle var olan günlük dosyaları kesiyor." + +#: utils/misc/guc.c:1531 +msgid "Emit information about resource usage in sorting." +msgstr "Alfabetik sıralama sırasında kaynak kullanımı hakkında bilgi ver." + +#: utils/misc/guc.c:1545 +msgid "Generate debugging output for synchronized scanning." +msgstr "Senkronize tarama için hata ayıklama çıktısı üret." + +#: utils/misc/guc.c:1560 +msgid "Enable bounded sorting using heap sort." +msgstr "Heap sort kullanarak sınırlı sıralamayı etkinleştir." + +#: utils/misc/guc.c:1573 +msgid "Emit WAL-related debugging output." +msgstr "WAL ile ilgili hata ayıklama çıktısını yayıyor." + +#: utils/misc/guc.c:1585 +msgid "Datetimes are integer based." +msgstr "Datetime veri tipleri tam sayı bazlıdır" + +#: utils/misc/guc.c:1596 +#, fuzzy +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." +msgstr "Kerberos kullanıcı adları büyük ve küçük harf duyarıl olup olmayacağını belirtiyor." + +#: utils/misc/guc.c:1606 +msgid "Warn about backslash escapes in ordinary string literals." +msgstr "Standart satırlarında ters taksimler kullanıldığında uyar." + +#: utils/misc/guc.c:1616 +msgid "Causes '...' strings to treat backslashes literally." +msgstr "'...' satırları ters taksimleri olduğu gibi algılmasını belirtiyor." + +#: utils/misc/guc.c:1627 +msgid "Enable synchronized sequential scans." +msgstr "Senkronize sequential-scan'leri etkinleştir." + +#: utils/misc/guc.c:1637 +msgid "Allows connections and queries during recovery." +msgstr "Kurtarma sırasında bağlantı ve sorgulara izin verir." + +#: utils/misc/guc.c:1647 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." +msgstr "Sorgu çatışmalarını önlemek üzere hot-standby'dan birincil sunucuya geri bildirime izin verir." + +#: utils/misc/guc.c:1657 +msgid "Allows modifications of the structure of system tables." +msgstr "Sistem tablolarının yapısının değiştirilmesine izin veriyor" + +#: utils/misc/guc.c:1668 +msgid "Disables reading from system indexes." +msgstr "Sistem indekslerinden okumayı engeller." + +#: utils/misc/guc.c:1669 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." +msgstr "Indekslerinin değiştirmesini engellemediği için zarasızdır. En kötü sonuç yavaşlamadır." + +#: utils/misc/guc.c:1680 +msgid "Enables backward compatibility mode for privilege checks on large objects." +msgstr "" + +#: utils/misc/guc.c:1681 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "" + +#: utils/misc/guc.c:1691 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +msgstr "PostgreSQL 9.4'ten bu yana anlam değiştiren yapılar (construct) için bir uyarı yayınla." + +#: utils/misc/guc.c:1701 +msgid "When generating SQL fragments, quote all identifiers." +msgstr "SQL parçaları oluşturuken, bütün tanımlayıcıları (identifier) tırnak içerisine alın." + +#: utils/misc/guc.c:1711 +msgid "Shows whether data checksums are turned on for this cluster." +msgstr "Bu küme üzerinde veri sağlama toplamlarının açık olup olmadığını gösterir." + +#: utils/misc/guc.c:1722 +msgid "Add sequence number to syslog messages to avoid duplicate suppression." +msgstr "" + +#: utils/misc/guc.c:1732 +msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." +msgstr "" + +#: utils/misc/guc.c:1742 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "" + +#: utils/misc/guc.c:1743 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "" + +#: utils/misc/guc.c:1752 +msgid "Allow JIT compilation." +msgstr "JIT derlemeye izin verir." + +#: utils/misc/guc.c:1762 +msgid "Register JIT compiled function with debugger." +msgstr "" + +#: utils/misc/guc.c:1779 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "" + +#: utils/misc/guc.c:1790 +msgid "Allow JIT compilation of expressions." +msgstr "İfadelerin (expression) JIT derlemesine izin verir." + +#: utils/misc/guc.c:1801 +msgid "Register JIT compiled function with perf profiler." +msgstr "" + +#: utils/misc/guc.c:1818 +msgid "Allow JIT compilation of tuple deforming." +msgstr "" + +#: utils/misc/guc.c:1829 +msgid "Whether to continue running after a failure to sync data files." +msgstr "" + +#: utils/misc/guc.c:1847 +#, fuzzy +#| msgid "Forces a switch to the next xlog file if a new file has not been started within N seconds." +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "yeni xlog dosyası N saniye olşmamışsa log switch yapılacaktır" + +#: utils/misc/guc.c:1858 +msgid "Waits N seconds on connection startup after authentication." +msgstr "İstemci kimlik doğrulamasından sonra N saniye bekiyor." + +#: utils/misc/guc.c:1859 utils/misc/guc.c:2410 +msgid "This allows attaching a debugger to the process." +msgstr "Hata ayıklayıcının bağlanmasına izin veriyor." + +#: utils/misc/guc.c:1868 +msgid "Sets the default statistics target." +msgstr "Varsayılan istatistik hedefi ayarlıyor." + +#: utils/misc/guc.c:1869 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." +msgstr "ALTER TABLE SET STATISTICS komutuyla sütun bazlı hedef ayarlanmamışsa bu seçenek uygulanır." + +#: utils/misc/guc.c:1878 +msgid "Sets the FROM-list size beyond which subqueries are not collapsed." +msgstr "FROM listesi bu boyuttan büyükse alt sorguları araltılmayacaktır." + +#: utils/misc/guc.c:1880 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "FROM listesinde bu değerinden az öğe varse, planlayıcı alt sorgularını üst sorgu ile birleştirecek." + +#: utils/misc/guc.c:1890 +msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." +msgstr "FROM listesi uzunluğu bu değerden büyükse JOIN ifadeler düzleştirilmeyecektir." + +#: utils/misc/guc.c:1892 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "Listede bu değerden daha çok nesne olursa, planlayıcısı belirlenmiş JOIN ifadeleri FROM nesnelerin listesine çevirecektir." + +#: utils/misc/guc.c:1902 +msgid "Sets the threshold of FROM items beyond which GEQO is used." +msgstr "FROM öğe sayısı bu eşiği geçince GEQO kullanılacaktır." + +#: utils/misc/guc.c:1911 +msgid "GEQO: effort is used to set the default for other GEQO parameters." +msgstr "GEQO: diğer GEQO parametreleri ayarlam için effort kullanılıyor." + +#: utils/misc/guc.c:1920 +msgid "GEQO: number of individuals in the population." +msgstr "GEQO: nüfusun içinde kişi sayısı." + +#: utils/misc/guc.c:1921 utils/misc/guc.c:1930 +msgid "Zero selects a suitable default value." +msgstr "Sıfır ise uygun bir varsayılan değer atanıyor." + +#: utils/misc/guc.c:1929 +msgid "GEQO: number of iterations of the algorithm." +msgstr "GEQO: algoritm döngü sayısı." + +#: utils/misc/guc.c:1940 +msgid "Sets the time to wait on a lock before checking for deadlock." +msgstr "Bir lock üzerinde deadlock kontrolü yapmadan geçmesi gereken süreyi bielirtiyor." + +#: utils/misc/guc.c:1951 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." +msgstr "" + +#: utils/misc/guc.c:1962 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "" + +#: utils/misc/guc.c:1973 +msgid "Sets the maximum interval between WAL receiver status reports to the primary." +msgstr "" + +#: utils/misc/guc.c:1984 +msgid "Sets the maximum wait time to receive data from the primary." +msgstr "Birincil (sunucu)dan veri almak için azami bekleme zamanını belirler." + +#: utils/misc/guc.c:1995 +msgid "Sets the maximum number of concurrent connections." +msgstr "Maksimum bağlantı sayısını ayarlıyor." + +#: utils/misc/guc.c:2006 +msgid "Sets the number of connection slots reserved for superusers." +msgstr "Superuser için rezerve edilmiş bağlantı sayısını ayarlıyor." + +#: utils/misc/guc.c:2020 +msgid "Sets the number of shared memory buffers used by the server." +msgstr "Sunucu tarafıundan kullanılacak shared memory arabellek sayısını ayarlıyor." + +#: utils/misc/guc.c:2031 +msgid "Sets the maximum number of temporary buffers used by each session." +msgstr "Her oturumun kullanabileceği en yüksek geçici buffer sayısı" + +#: utils/misc/guc.c:2042 +msgid "Sets the TCP port the server listens on." +msgstr "Sunucun dinleyeceği TCP port numarasını ayarlıyor." + +#: utils/misc/guc.c:2052 +msgid "Sets the access permissions of the Unix-domain socket." +msgstr "Unix-domain socket erişim haklarını ayarlıyor." + +#: utils/misc/guc.c:2053 +#, fuzzy +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix-domain yvaları, standart Unix dosya sistemi izin altyapısını kullanıyor. Parametresi chmod ve umask sistem çağırılarının kabul edeceği biçimde numerik bir değerdir. (Sekizli sayı sistemi ile bir değer girecekseniz onu 0 (sıfır) ile başlatmalısınız.)" + +#: utils/misc/guc.c:2067 +msgid "Sets the file permissions for log files." +msgstr "Log dosyaları için dosya izinlerini ayarlar." + +#: utils/misc/guc.c:2068 +#, fuzzy +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix-domain yvaları, standart Unix dosya sistemi izin altyapısını kullanıyor. Parametresi chmod ve umask sistem çağırılarının kabul edeceği biçimde numerik bir değerdir. (Sekizli sayı sistemi ile bir değer girecekseniz onu 0 (sıfır) ile başlatmalısınız.)" + +#: utils/misc/guc.c:2082 +msgid "Mode of the data directory." +msgstr "Veri dizininin kipi (mode)." + +#: utils/misc/guc.c:2083 +#, fuzzy +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix-domain yvaları, standart Unix dosya sistemi izin altyapısını kullanıyor. Parametresi chmod ve umask sistem çağırılarının kabul edeceği biçimde numerik bir değerdir. (Sekizli sayı sistemi ile bir değer girecekseniz onu 0 (sıfır) ile başlatmalısınız.)" + +#: utils/misc/guc.c:2096 +msgid "Sets the maximum memory to be used for query workspaces." +msgstr "Sorgu çalışma alanları için kullanılacak en büyük bellek boyutu belirliyor." + +#: utils/misc/guc.c:2097 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "Geçici disk dosyalarına başvurmadan dahili sort ve hash tablo işlemleirinin kullanabileceği bellek boyutu ayarlar." + +#: utils/misc/guc.c:2109 +msgid "Sets the maximum memory to be used for maintenance operations." +msgstr "Bakım işlemleri için kullanılacak en büyük bellek boyutu belirler." + +#: utils/misc/guc.c:2110 +msgid "This includes operations such as VACUUM and CREATE INDEX." +msgstr "Bu değer VACUUM ve CREATE INDEX gibi işlemleri için de geçerlidir." + +#: utils/misc/guc.c:2125 +msgid "Sets the maximum stack depth, in kilobytes." +msgstr "Kilobay olarak en büyük yığın boyutu ayarlar." + +#: utils/misc/guc.c:2136 +msgid "Limits the total size of all temporary files used by each process." +msgstr "Her süreç tarafından kullanılan bütün geçici dosyaların toplam boyutunu sınırlar." + +#: utils/misc/guc.c:2137 +msgid "-1 means no limit." +msgstr "-1 sınır olmadığı anlamındadır." + +#: utils/misc/guc.c:2147 +msgid "Vacuum cost for a page found in the buffer cache." +msgstr "Buffer cache içinde bulunan bir sayfanın vacuum işleme masrafı." + +#: utils/misc/guc.c:2157 +msgid "Vacuum cost for a page not found in the buffer cache." +msgstr "Buffer cache içinde bulunamayan bir sayfanın vacuum işleme masrafı." + +#: utils/misc/guc.c:2167 +msgid "Vacuum cost for a page dirtied by vacuum." +msgstr "Vacuum tarafında değiştirilecek sayfanın işleme masrafı." + +#: utils/misc/guc.c:2177 +msgid "Vacuum cost amount available before napping." +msgstr "Vacuum işleminin uyku durumuna geçmeden önce ne kadar işlem yapması. Yani bir geçişte ne kadar işlem yapacağı." + +#: utils/misc/guc.c:2187 +msgid "Vacuum cost delay in milliseconds." +msgstr "Vacuum işleminin milisaniye değeri." + +#: utils/misc/guc.c:2198 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "Vacuum işleminin masrafının milisaniye değeri (autovacuum için)." + +#: utils/misc/guc.c:2209 +msgid "Vacuum cost amount available before napping, for autovacuum." +msgstr "Vacuum işleminin uyku durumuna geçmeden önce ne kadar işlem yapması. Yani bir geçişte ne kadar işlem yapacağı." + +#: utils/misc/guc.c:2219 +msgid "Sets the maximum number of simultaneously open files for each server process." +msgstr "Her sunucu sürecinin içi aynı anda olabilecek en büyük açık dosya sayısı." + +#: utils/misc/guc.c:2232 +msgid "Sets the maximum number of simultaneously prepared transactions." +msgstr "Aynı zamanda olabilecek en çok prepared transaction sayısı." + +#: utils/misc/guc.c:2243 +#, fuzzy +#| msgid "Sets the maximum number of locks per transaction." +msgid "Sets the minimum OID of tables for tracking locks." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2244 +msgid "Is used to avoid output on system tables." +msgstr "Sistem tablolarında çıktı oluşmasından kaçınmak için kullanılır." + +#: utils/misc/guc.c:2253 +msgid "Sets the OID of the table with unconditionally lock tracing." +msgstr "" + +#: utils/misc/guc.c:2265 +msgid "Sets the maximum allowed duration of any statement." +msgstr "Bir sorgunun en çok çalışma zamanı." + +#: utils/misc/guc.c:2266 utils/misc/guc.c:2277 utils/misc/guc.c:2288 +msgid "A value of 0 turns off the timeout." +msgstr "0 (sıfır) değeri, zaman aşımını kapatıyor." + +#: utils/misc/guc.c:2276 +msgid "Sets the maximum allowed duration of any wait for a lock." +msgstr "Bir kilit için azami izin verilen süreyi belirler." + +#: utils/misc/guc.c:2287 +msgid "Sets the maximum allowed duration of any idling transaction." +msgstr "Boşta bekleyen (idling) bir işlem (transaction) için azami izin verilen süreyi belirler." + +#: utils/misc/guc.c:2298 +msgid "Minimum age at which VACUUM should freeze a table row." +msgstr "VACUUM, satırın üzerinde freeze işlemi yapabilecek yaşlılık süresi." + +#: utils/misc/guc.c:2308 +#, fuzzy +msgid "Age at which VACUUM should scan whole table to freeze tuples." +msgstr "VACUUM, satırın üzerinde freeze işlemi yapabilecek yaşlılık süresi." + +#: utils/misc/guc.c:2318 +#, fuzzy +#| msgid "Minimum age at which VACUUM should freeze a table row." +msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." +msgstr "VACUUM, satırın üzerinde freeze işlemi yapabilecek yaşlılık süresi." + +#: utils/misc/guc.c:2328 +#, fuzzy +msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." +msgstr "VACUUM, satırın üzerinde freeze işlemi yapabilecek yaşlılık süresi." + +#: utils/misc/guc.c:2338 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." +msgstr "" + +#: utils/misc/guc.c:2351 +msgid "Sets the maximum number of locks per transaction." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2352 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Bu tablonun boyutu, max_locks_per_transaction * max_connections kadar ayrı nesneye bir anda kilit uygulamaya gerektiğini göz önünde bulundurarak ayarlanır." + +#: utils/misc/guc.c:2363 +#, fuzzy +#| msgid "Sets the maximum number of locks per transaction." +msgid "Sets the maximum number of predicate locks per transaction." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2364 +#, fuzzy +#| msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "Bu tablonun boyutu, max_locks_per_transaction * max_connections kadar ayrı nesneye bir anda kilit uygulamaya gerektiğini göz önünde bulundurarak ayarlanır." + +#: utils/misc/guc.c:2375 +#, fuzzy +#| msgid "Sets the maximum number of locks per transaction." +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2376 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "Eğer aynı tabloda bu toplamdan fazla sayfa ve satır bir bağlantı tarafından kilitlenmişse, o kilitler bir tablo-seviyesi kilidiyle değiştirilir." + +#: utils/misc/guc.c:2386 +#, fuzzy +#| msgid "Sets the maximum number of locks per transaction." +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2387 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "Eğer aynı sayfada (page) bu kadardan fazla satır bir bağlantı tarafından kilitlenmişse, o kilitler bir sayfa-seviyesi kilidiyle değiştirilir." + +#: utils/misc/guc.c:2397 +msgid "Sets the maximum allowed time to complete client authentication." +msgstr "İstemci kimlik doğrulamasını yapmak için zaman sınırı ayarlar." + +#: utils/misc/guc.c:2409 +msgid "Waits N seconds on connection startup before authentication." +msgstr "İstemci kimlik doğrulamasından önce N saniye bekiyor." + +#: utils/misc/guc.c:2420 +msgid "Sets the number of WAL files held for standby servers." +msgstr "Yedek (standby) sunucular için kullanılacak WAL dosyalarının sayısını ayarlıyor." + +#: utils/misc/guc.c:2430 +msgid "Sets the minimum size to shrink the WAL to." +msgstr "WAL'ın küçültüleceği asgari boyutu belirler." + +#: utils/misc/guc.c:2442 +msgid "Sets the WAL size that triggers a checkpoint." +msgstr "Checkpoint tetikleyecek WAL boyutunu ayarlar." + +#: utils/misc/guc.c:2454 +msgid "Sets the maximum time between automatic WAL checkpoints." +msgstr "Otomatic WAL denetim noktaları (checkpoint) arasında geçecek zaman dilimi." + +#: utils/misc/guc.c:2465 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." +msgstr "Eğer log denetim noktası (checkpoint) bu değerden daha sık oluyorsa günlüğüne bir not düş." + +#: utils/misc/guc.c:2467 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "Checkpoint segment dosyaların dolması nedeniyle denetim noktası (checkpoint) olayı bu değerdeki saniye sayısından daha sık oluyorsa sunucu günlük dosyasına not düş. Sıfır ise bu uyarıyı kapat." + +#: utils/misc/guc.c:2479 utils/misc/guc.c:2636 utils/misc/guc.c:2664 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "" + +#: utils/misc/guc.c:2490 +msgid "Sets the number of disk-page buffers in shared memory for WAL." +msgstr "WAL için shared memory arabellek disk-sayfa sayısı." + +#: utils/misc/guc.c:2501 +msgid "Time between WAL flushes performed in the WAL writer." +msgstr "WAL writerda gerçekleştirilen WAL flush'ları arasında geçen zaman." + +#: utils/misc/guc.c:2512 +msgid "Amount of WAL written out by WAL writer that triggers a flush." +msgstr "" + +#: utils/misc/guc.c:2524 +msgid "Sets the maximum number of simultaneously running WAL sender processes." +msgstr "Aynı anda çalışacak WAL gönderici süreç sayısını ayarlıyor." + +#: utils/misc/guc.c:2535 +msgid "Sets the maximum number of simultaneously defined replication slots." +msgstr "Aynı anda mevcut olabilecek azami replikasyon slotu sayısını belirler." + +#: utils/misc/guc.c:2545 +msgid "Sets the maximum time to wait for WAL replication." +msgstr "WAL replikasyonu için beklenecek azami süreyi ayarlar." + +#: utils/misc/guc.c:2556 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." +msgstr "Transaction commit ile WAL dosyaların diske yazılması arasında milisaniye olarak gecikme süresi ayarlar." + +#: utils/misc/guc.c:2568 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." +msgstr "commit_delay uygulamadan önce en az bu değer koşutzamanlı transaction olacak." + +#: utils/misc/guc.c:2579 +msgid "Sets the number of digits displayed for floating-point values." +msgstr "Floating-point değerlerinde gösterilecek rakam asyısı ayarlar." + +#: utils/misc/guc.c:2580 +msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." +msgstr "Bu ayar, real, double precision ve geometrik veri tiplerinde klullanılır. Bu değer, standart rakam sayısına eklenmektedir (FLT_DIG veya DBL_DIG)." + +#: utils/misc/guc.c:2591 +msgid "Sets the minimum execution time above which statements will be logged." +msgstr "Bu süreden uzun süre çalışacak sorgular log dosyasına yazılacaktır." + +#: utils/misc/guc.c:2593 +msgid "Zero prints all queries. -1 turns this feature off." +msgstr "Sıfır tüm sorguları print eder. -1 bu özelliği devre dışı bırakır." + +#: utils/misc/guc.c:2603 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "Autovacuum bu süreden çok zaman alırsa, eylemleri ayda alınacaktır." + +#: utils/misc/guc.c:2605 +msgid "Zero prints all actions. -1 turns autovacuum logging off." +msgstr "Sıfır tüm eylemleri yazdırır. -1 autovacuum loglamasını kapatır." + +#: utils/misc/guc.c:2615 +msgid "Background writer sleep time between rounds." +msgstr "Background writer'in seferleri arasında hareketsiz kalacağı zaman süresi." + +#: utils/misc/guc.c:2626 +msgid "Background writer maximum number of LRU pages to flush per round." +msgstr "Her seferinde background writer'in diske yazaçağı LRU sayfaların maximum sayısı." + +#: utils/misc/guc.c:2649 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." +msgstr "Disk alt sistemi tarafından verimli bir şekilde işlenebilecek eşzamanlı istek sayısı." + +#: utils/misc/guc.c:2650 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." +msgstr "RAID dizileri için bu yaklaşık olarak dizideki sürücü okuyucu kafa sayısı kadar olmalıdır." + +#: utils/misc/guc.c:2677 +msgid "Maximum number of concurrent worker processes." +msgstr "Azami eşzamanlı işçi (worker) süreci sayısı." + +#: utils/misc/guc.c:2689 +msgid "Maximum number of logical replication worker processes." +msgstr "Azami mantıksal (logical) replikasyon işçi (worker) süreci sayısı." + +#: utils/misc/guc.c:2701 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "Abonelik başına azami tablo senkronizasyon işçi (worker) sayısı." + +#: utils/misc/guc.c:2711 +msgid "Automatic log file rotation will occur after N minutes." +msgstr "Otomatik log dosya değişimi N dakikada bir gerçekleşecek." + +#: utils/misc/guc.c:2722 +msgid "Automatic log file rotation will occur after N kilobytes." +msgstr "Otomatik log dosya değişimi (rotasyon) N kilobayttan sonra gerçekleşecek." + +#: utils/misc/guc.c:2733 +msgid "Shows the maximum number of function arguments." +msgstr "Fonksiyon argünamlarının olabileceği en büyük sayısını gösteriyor." + +#: utils/misc/guc.c:2744 +msgid "Shows the maximum number of index keys." +msgstr "İndeks değerlerinin olabileceği en büyük sayısını gösteriyor." + +#: utils/misc/guc.c:2755 +msgid "Shows the maximum identifier length." +msgstr "Bır tanıtıcının en maximum uzunluğunu gösteriyor." + +#: utils/misc/guc.c:2766 +msgid "Shows the size of a disk block." +msgstr "Bir disk blokunun boyutunu gösteriyor." + +#: utils/misc/guc.c:2777 +msgid "Shows the number of pages per disk file." +msgstr "Disk dosyası başına sayfa sayısını gösterir." + +#: utils/misc/guc.c:2788 +msgid "Shows the block size in the write ahead log." +msgstr "Write ahead log'u içindeki blok boyutunu gösterir." + +#: utils/misc/guc.c:2799 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." +msgstr "" + +#: utils/misc/guc.c:2811 +msgid "Shows the size of write ahead log segments." +msgstr "Write ahead log segmentlerinin boyutunu gösterir." + +#: utils/misc/guc.c:2824 +msgid "Time to sleep between autovacuum runs." +msgstr "Autovacuum çalıştırmaları arasında bekleme zamanı." + +#: utils/misc/guc.c:2834 +msgid "Minimum number of tuple updates or deletes prior to vacuum." +msgstr "Vacuum işleminin başlaması için gereken düşük tuple update veya deleta sayısı." + +#: utils/misc/guc.c:2843 +#, fuzzy +#| msgid "Minimum number of tuple inserts, updates or deletes prior to analyze." +msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." +msgstr "Analyze işleminin başlaması için gereken düşük tuple insert, update veya deleta sayısı." + +#: utils/misc/guc.c:2853 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgstr "ID sarımı önemek için autovacuum yapılacağı yaşlılık değeri." + +#: utils/misc/guc.c:2864 +#, fuzzy +#| msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." +msgstr "ID sarımı önemek için autovacuum yapılacağı yaşlılık değeri." + +#: utils/misc/guc.c:2874 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." +msgstr "Aynı anda çalışacak autovacuum süreç sayısını ayarlıyor." + +#: utils/misc/guc.c:2884 +#, fuzzy +#| msgid "Sets the maximum number of locks per transaction." +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "Bir transaction içinde en yüksek olabilecek kilit sayısı." + +#: utils/misc/guc.c:2894 +msgid "Sets the maximum number of parallel processes per executor node." +msgstr "Yürütücü düğüm (executor node) başına azami paralel süreç sayısını belirler." + +#: utils/misc/guc.c:2904 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "Bir anda aktif olabilecek azami (maks.) paralel işçi sayısını ayarlar." + +#: utils/misc/guc.c:2914 +msgid "Sets the maximum memory to be used by each autovacuum worker process." +msgstr "Her bir oto-vakum işçi süreci tarafından kullanılacak azami (maks.) bellek boyutunu ayarlar." + +#: utils/misc/guc.c:2925 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." +msgstr "" + +#: utils/misc/guc.c:2926 +msgid "A value of -1 disables this feature." +msgstr "-1 değeri bu özelliği devre dışı bırakır." + +#: utils/misc/guc.c:2936 +msgid "Time between issuing TCP keepalives." +msgstr "TCP keepalive göndermelerin arasında saniye sayısı." + +#: utils/misc/guc.c:2937 utils/misc/guc.c:2948 +msgid "A value of 0 uses the system default." +msgstr "0 (sıfır) değeri, sistem varsayılan değeri etkinleştirir." + +#: utils/misc/guc.c:2947 +msgid "Time between TCP keepalive retransmits." +msgstr "TCP keepalive yeniden göndermelerin arasında saniye sayısı." + +#: utils/misc/guc.c:2958 +msgid "SSL renegotiation is no longer supported; this can only be 0." +msgstr "SSL renegotiation artık desteklenmiyor; bu sadece 0 olabilir." + +#: utils/misc/guc.c:2969 +msgid "Maximum number of TCP keepalive retransmits." +msgstr "En yüksek TCP keepalive gönderme sayısı." + +#: utils/misc/guc.c:2970 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "Keepalive açıkken, bir bağlantının kopmuş olmasını sayılamadan gönderilecek mükerrer paket sayısı. 0 (sıfır) değeri sistemdeki varsayılan eğerini alıyor." + +#: utils/misc/guc.c:2981 +msgid "Sets the maximum allowed result for exact search by GIN." +msgstr "GIN sorgulaması için izin verilen en yüksek sonuç sayısı." + +#: utils/misc/guc.c:2992 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "Veri önbelleklerinin (data cache) toplam boyutu hakkında planner'in tahmini değerini belirtiyor." + +#: utils/misc/guc.c:2993 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "Yani, PostgreSQL veri dosyaları için kullanılacak önbelleklerin (kernel cache ve shared buffers) toplam boyutu. Bu değer, disk sayfa (page) birimleriyle ölçülür, genellikle her biri 8 kilobayttır." + +#: utils/misc/guc.c:3004 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "Parale scan için asgari tablo verisi boyutunu belirler." + +#: utils/misc/guc.c:3005 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Eğer planlayıcı bu sınırın çok altında bir tablo sayfa sayısı okuyacağını kestirirse, bir paralel taramaya (scan) yönelmeyecektir." + +#: utils/misc/guc.c:3015 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "Bir paralel tarama için asgari (min) indeks veri miktarını ayarlar." + +#: utils/misc/guc.c:3016 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "Eğer planlayıcı bu sınırın çok altında bir indeks sayfa sayısı okuyacağını kestirirse, bir paralel taramaya (scan) yönelmeyecektir." + +#: utils/misc/guc.c:3027 +msgid "Shows the server version as an integer." +msgstr "Sunucunun sürümünü tamsayı olarak gösteriyor." + +#: utils/misc/guc.c:3038 +msgid "Log the use of temporary files larger than this number of kilobytes." +msgstr "Bu kadar kilobayttan büyük geçici dosya kullanıldığında log tutuyor." + +#: utils/misc/guc.c:3039 +msgid "Zero logs all files. The default is -1 (turning this feature off)." +msgstr "Sifir, tüm dosyaları logluyor. Varsayılan değer -1 (bu özellik kapalıdır)." + +#: utils/misc/guc.c:3049 +msgid "Sets the size reserved for pg_stat_activity.query, in bytes." +msgstr "pg_stat_activity.query için ayrılan boyutu ayarlar (bayt olarak)." + +#: utils/misc/guc.c:3060 +msgid "Sets the maximum size of the pending list for GIN index." +msgstr "GIN indeksi için olan bekleme (pending) listesinin azami boyutunu ayarlar." + +#: utils/misc/guc.c:3080 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." +msgstr "Dıskten sırayla sayfa okuması için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3090 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." +msgstr "Nonsequential disk page getirme işlemlerin tahmini zamanı belirtiyor." + +#: utils/misc/guc.c:3100 +msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgstr "Bir satır işlemek için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3110 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." +msgstr "Bir index taraması sırasında indexin her satırının taramasını yapmak için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3120 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." +msgstr "Bir operator veya fonksiyon çağırımı yapmak için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3130 +#, fuzzy +#| msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." +msgstr "Bir satır işlemek için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3140 +#, fuzzy +#| msgid "Sets the planner's estimate of the cost of processing each tuple (row)." +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." +msgstr "Bir satır işlemek için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3151 +msgid "Perform JIT compilation if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3152 +msgid "-1 disables JIT compilation." +msgstr "-1 JIT derlemeyi devre dışı bırakır" + +#: utils/misc/guc.c:3161 +msgid "Optimize JITed functions if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3162 +msgid "-1 disables optimization." +msgstr "-1 değeri optimizasyonu devre dışı bırakır." + +#: utils/misc/guc.c:3171 +msgid "Perform JIT inlining if query is more expensive." +msgstr "" + +#: utils/misc/guc.c:3172 +msgid "-1 disables inlining." +msgstr "" + +#: utils/misc/guc.c:3181 +#, fuzzy +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." +msgstr "Bir satır işlemek için harcanacak işlem zamanı tahminini belirtiyor." + +#: utils/misc/guc.c:3192 +msgid "GEQO: selective pressure within the population." +msgstr "GEQO: selective pressure within the population. Oha be, query'yi mi optimize ediyoruz, piliç mi yetiştiriyoruz, yuh." + +#: utils/misc/guc.c:3202 +msgid "GEQO: seed for random path selection." +msgstr "GEQO: Random path seçimi için seed değeri." + +#: utils/misc/guc.c:3212 +#, fuzzy +msgid "Multiple of the average buffer usage to free per round." +msgstr "Her seferinde background writer'in diske yazaçağı LRU bufferlerin yüzdesi." + +#: utils/misc/guc.c:3222 +msgid "Sets the seed for random-number generation." +msgstr "Random-number üretimi için seed değerini belirtiyor." + +#: utils/misc/guc.c:3233 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." +msgstr "Vacuum işleminin başlaması için en düşük tuple update ve delete sayısı (reltuple bölümü olarak)." + +#: utils/misc/guc.c:3242 +#, fuzzy +#| msgid "Number of tuple inserts, updates or deletes prior to analyze as a fraction of reltuples." +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." +msgstr "Analyze işleminin başlaması için en düşük tuple insert, update ve delete sayısı (retuple bölümü olarak)." + +#: utils/misc/guc.c:3252 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "" + +#: utils/misc/guc.c:3262 +#, fuzzy +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "Vacuum işleminin başlaması için en düşük tuple update ve delete sayısı (reltuple bölümü olarak)." + +#: utils/misc/guc.c:3281 +msgid "Sets the shell command that will be called to archive a WAL file." +msgstr "WAL dosyasını arşivlemek için çağırılacak kabuk komutunu ayarlıyor ." + +#: utils/misc/guc.c:3291 +msgid "Sets the client's character set encoding." +msgstr "İstemci karakter kodlamasını belirtiyor." + +#: utils/misc/guc.c:3302 +msgid "Controls information prefixed to each log line." +msgstr "Log satırlarının başlarına eklenecek bilgiyi ayarlıyor." + +#: utils/misc/guc.c:3303 +msgid "If blank, no prefix is used." +msgstr "Boş ise ön ek kullanlmayacak." + +#: utils/misc/guc.c:3312 +msgid "Sets the time zone to use in log messages." +msgstr "Log mesajlarında kullanılacak saat dilimini belirliyor." + +#: utils/misc/guc.c:3322 +msgid "Sets the display format for date and time values." +msgstr "Tarih ve zaman girişleri için biçim maskesini belirtiyor." + +#: utils/misc/guc.c:3323 +msgid "Also controls interpretation of ambiguous date inputs." +msgstr "Ayrıca belirsiz tarih girişinin yorumlamasını belirtiyor." + +#: utils/misc/guc.c:3334 +msgid "Sets the default tablespace to create tables and indexes in." +msgstr "İndeksleri oluşturma işemi için varsayılan tablespace ayarlıyor" + +#: utils/misc/guc.c:3335 +msgid "An empty string selects the database's default tablespace." +msgstr "Boş değer, veritabanının varsayılan tablespace'ı seçmektedir." + +#: utils/misc/guc.c:3345 +msgid "Sets the tablespace(s) to use for temporary tables and sort files." +msgstr "Geçici tablolar ve sıralama dosyaları için kullanılacak talespace(ler)i belirliyor." + +#: utils/misc/guc.c:3356 +msgid "Sets the path for dynamically loadable modules." +msgstr "Dinamik yüklenebilen modülleri arama dizinlerini belirtiyor." + +#: utils/misc/guc.c:3357 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "Bir dinamik kütüphane açmak gerektiğinde dosya adında dizin kısmı yoksa (dosya adın içinde taksim kararkteri yoksa), sistem, kütüphaneleri bulmak için bu dizinleri arayacak." + +#: utils/misc/guc.c:3370 +msgid "Sets the location of the Kerberos server key file." +msgstr "Kerberos server key dosyasının yerini belirtiyor." + +#: utils/misc/guc.c:3381 +msgid "Sets the Bonjour service name." +msgstr "Bonjour servisi adını belirtiyor." + +#: utils/misc/guc.c:3393 +msgid "Shows the collation order locale." +msgstr "Alfabetik sıralamasında kullanılacak locale ayarı gösteriyor." + +#: utils/misc/guc.c:3404 +msgid "Shows the character classification and case conversion locale." +msgstr "Karakter sınıflandırılması ve büyük/küçük çevirme işlemlerinde kullanıcak locale ayarı gösteriyor." + +#: utils/misc/guc.c:3415 +msgid "Sets the language in which messages are displayed." +msgstr "Mesajlarda kullanılacak dili belirtiyor." + +#: utils/misc/guc.c:3425 +msgid "Sets the locale for formatting monetary amounts." +msgstr "Parasal değerlerinin biçimlendirilmesinde kullanılacak locale ayarını belirtiyor." + +#: utils/misc/guc.c:3435 +msgid "Sets the locale for formatting numbers." +msgstr "Sayısal deÄŸerlerinin biçimlendirilmesinde kullanılacak locale ayarını belirtiyor." + +#: utils/misc/guc.c:3445 +msgid "Sets the locale for formatting date and time values." +msgstr "Tarih ve zaman deÄŸerlerinin biçimlendirilmesinde kullanılacak locale ayarını belirtiyor." + +#: utils/misc/guc.c:3455 +msgid "Lists shared libraries to preload into each backend." +msgstr "Her sunucuya yüklenenecek ortak kütüphaneleri gösteriyor." + +#: utils/misc/guc.c:3466 +msgid "Lists shared libraries to preload into server." +msgstr "Sunucuya yüklenmiÅŸ ortak kütüphaneleri gösteriyor." + +#: utils/misc/guc.c:3477 +msgid "Lists unprivileged shared libraries to preload into each backend." +msgstr "Her sunucuya yüklenenecek ayrıcalıksız (unprivileged) ortak kütüphaneleri gösteriyor." + +#: utils/misc/guc.c:3488 +msgid "Sets the schema search order for names that are not schema-qualified." +msgstr "Åžema belirtilmediÄŸi takdirde isimlerin hangi ÅŸemalarda aranacağını belirtir." + +#: utils/misc/guc.c:3500 +msgid "Sets the server (database) character set encoding." +msgstr "Sunucu (veritabanı) karakter seti kodlamasını belirtiyor." + +#: utils/misc/guc.c:3512 +msgid "Shows the server version." +msgstr "Sunucunun sürümünü gösteriyor." + +#: utils/misc/guc.c:3524 +msgid "Sets the current role." +msgstr "Geçerli rolü belirtiyor." + +#: utils/misc/guc.c:3536 +msgid "Sets the session user name." +msgstr "Oturum açan kullanıcının ismini gösterir." + +#: utils/misc/guc.c:3547 +msgid "Sets the destination for server log output." +msgstr "Log dosyaları için hedef dizini belirtiyor." + +#: utils/misc/guc.c:3548 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "Geçerli deÄŸerler, platforma baÄŸlı olarak: \"stderr\", \"syslog\", \"csvlog\" ve \"eventlog\" kombinasyonlarıdır." + +#: utils/misc/guc.c:3559 +msgid "Sets the destination directory for log files." +msgstr "Log dosyaları için hedef dizini belirtiyor." + +#: utils/misc/guc.c:3560 +msgid "Can be specified as relative to the data directory or as absolute path." +msgstr "Bu deÄŸer hem veri dizininden göreceli hem de tam yol olabilir." + +#: utils/misc/guc.c:3570 +msgid "Sets the file name pattern for log files." +msgstr "Log dosyaları için kulanılacak ÅŸablonu belirtiyor." + +#: utils/misc/guc.c:3581 +msgid "Sets the program name used to identify PostgreSQL messages in syslog." +msgstr "Syslog içinde PostgreSQL mesajlarının kaynak olacağı program adını belirtiyor." + +#: utils/misc/guc.c:3592 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." +msgstr "Event log içinde PostgreSQL mesajlarını belirleyecek uygulama adını belirtiyor." + +#: utils/misc/guc.c:3603 +msgid "Sets the time zone for displaying and interpreting time stamps." +msgstr "Time stamp veri tipini çıktısında kullanılacak zaman dilimi belirtiyor." + +#: utils/misc/guc.c:3613 +msgid "Selects a file of time zone abbreviations." +msgstr "Timezone kısaltmaların olduÄŸu dosyayı seçer." + +#: utils/misc/guc.c:3623 +msgid "Sets the current transaction's isolation level." +msgstr "Transaction isolation level belirtiyor." + +#: utils/misc/guc.c:3634 +msgid "Sets the owning group of the Unix-domain socket." +msgstr "Unix-domain socket grup sahipliÄŸini belirtiyor." + +#: utils/misc/guc.c:3635 +msgid "The owning user of the socket is always the user that starts the server." +msgstr "Socket sahibi her zamn sunucu çalıştıran kullanıcıdır." + +#: utils/misc/guc.c:3645 +msgid "Sets the directories where Unix-domain sockets will be created." +msgstr "Unix-domain socket'lerin oluÅŸturulacağı dizinleri belirtiyor." + +#: utils/misc/guc.c:3660 +msgid "Sets the host name or IP address(es) to listen to." +msgstr "Dinlenecek host adı veya IP adresleri belirtiyor." + +#: utils/misc/guc.c:3675 +msgid "Sets the server's data directory." +msgstr "Sunucusunun veri dizini belirtiyor." + +#: utils/misc/guc.c:3686 +msgid "Sets the server's main configuration file." +msgstr "Sunucunun ana konfigorasyon dosyasının yerini belirtiyor." + +#: utils/misc/guc.c:3697 +msgid "Sets the server's \"hba\" configuration file." +msgstr "Sunucusunun \"hba\" konfigurasyon dosyasını belirtiyor." + +#: utils/misc/guc.c:3708 +msgid "Sets the server's \"ident\" configuration file." +msgstr "Sunucusunun \"ident\" konfigurasyon dosyasını belirtiyor." + +#: utils/misc/guc.c:3719 +msgid "Writes the postmaster PID to the specified file." +msgstr "Postmaster PID numarası belirtilen dosyaya yazar." + +#: utils/misc/guc.c:3730 +msgid "Location of the SSL server certificate file." +msgstr "SSL sunucu sertifikası dosyası yeri." + +#: utils/misc/guc.c:3740 +msgid "Location of the SSL server private key file." +msgstr "SSL sunucu private anahtar dosyası yeri." + +#: utils/misc/guc.c:3750 +msgid "Location of the SSL certificate authority file." +msgstr "SSL sertifika otoritesi dosyasının yeri." + +#: utils/misc/guc.c:3760 +msgid "Location of the SSL certificate revocation list file." +msgstr "SSL sertifikası iptal listesi dosyası yeri." + +#: utils/misc/guc.c:3770 +msgid "Writes temporary statistics files to the specified directory." +msgstr "Geçici istatistik dosyalarını belirtilen dizine yazar." + +#: utils/misc/guc.c:3781 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." +msgstr "Senkron standby'ların sayısı ve potansiyel senkron olanların isim listesi." + +#: utils/misc/guc.c:3792 +msgid "Sets default text search configuration." +msgstr "Öntanımlı metin arama yapıkandırmasını ayarlar. " + +#: utils/misc/guc.c:3802 +msgid "Sets the list of allowed SSL ciphers." +msgstr "İzin verilen SSL ÅŸifreleme algoritmaların listesini ayarlıyor." + +#: utils/misc/guc.c:3817 +msgid "Sets the curve to use for ECDH." +msgstr "ECDH için kullanılacak curve deÄŸerini ayarlar." + +#: utils/misc/guc.c:3832 +msgid "Location of the SSL DH parameters file." +msgstr "SSL DH parametre dosyasının yeri." + +#: utils/misc/guc.c:3843 +msgid "Command to obtain passphrases for SSL." +msgstr "SSL için parolaları alma komutu." + +#: utils/misc/guc.c:3853 +msgid "Sets the application name to be reported in statistics and logs." +msgstr "İstatistik ve loglarda raporlanacak uygulama ismini ayarlar." + +#: utils/misc/guc.c:3864 +msgid "Sets the name of the cluster, which is included in the process title." +msgstr "Süreç baÅŸlığında yer alan kümenin (cluster), ismini ayarlar." + +#: utils/misc/guc.c:3875 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "WAL tutarlılık kontrollerinin yapıldığı WAl kaynak yöneticilerini ayarlar." + +#: utils/misc/guc.c:3876 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "" + +#: utils/misc/guc.c:3886 +msgid "JIT provider to use." +msgstr "Kullanılacak JIT saÄŸlayıcısı." + +#: utils/misc/guc.c:3906 +msgid "Sets whether \"\\'\" is allowed in string literals." +msgstr "Satır deÄŸiÅŸmezlerde \"\\'\" ifadesine izin verilip verilmeyeceÄŸini belirtiyor." + +#: utils/misc/guc.c:3916 +msgid "Sets the output format for bytea." +msgstr "Bytea için çıktı formatını belirtiyor." + +#: utils/misc/guc.c:3926 +msgid "Sets the message levels that are sent to the client." +msgstr "İstemciye yollancak mesaj düzeylerini belirtiyor." + +#: utils/misc/guc.c:3927 utils/misc/guc.c:3980 utils/misc/guc.c:3991 utils/misc/guc.c:4057 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." +msgstr "Her düzey kendisinden daha büyük düzeyleri de kapsıyor. Düzey ne kadar yüksek ise o kadar az mesaj yollanıyor." + +#: utils/misc/guc.c:3937 +msgid "Enables the planner to use constraints to optimize queries." +msgstr "Planlayıcının sorgularını optimize etmek için constraints kullanmasına izin verir." + +#: utils/misc/guc.c:3938 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." +msgstr "Constraint'leri tarafından sorguya hiçbir satırın uymayacağı garantilenirse table scan yapılmayacaktır." + +#: utils/misc/guc.c:3948 +msgid "Sets the transaction isolation level of each new transaction." +msgstr "Her yeni transaction için transaction isolation level belirtiypr." + +#: utils/misc/guc.c:3958 +msgid "Sets the display format for interval values." +msgstr "Zaman aralığı deÄŸerleri için görüntüleme formatını ayarlar." + +#: utils/misc/guc.c:3969 +msgid "Sets the verbosity of logged messages." +msgstr "Log mesajlarının ayrıntı düzei belirtiyor." + +#: utils/misc/guc.c:3979 +msgid "Sets the message levels that are logged." +msgstr "Log dosyasına yazılacak mesajlarının düzeylerini belirtiyor." + +#: utils/misc/guc.c:3990 +msgid "Causes all statements generating error at or above this level to be logged." +msgstr "Belirtilen ya da daha üst düzeyde hata yaratan komutlarının gol dosyasına yazılacağına sebep olur." + +#: utils/misc/guc.c:4001 +msgid "Sets the type of statements logged." +msgstr "Log dosyasına yazılacak komutların tipini belirtiyor." + +#: utils/misc/guc.c:4011 +msgid "Sets the syslog \"facility\" to be used when syslog enabled." +msgstr "Syslog aktif durumunda kullanılacak syslog \"facility\" deÄŸerini belirtiyor." + +#: utils/misc/guc.c:4026 +msgid "Sets the session's behavior for triggers and rewrite rules." +msgstr "Oturumun trigger ve rewrite rule davranışını belirtiyor." + +#: utils/misc/guc.c:4036 +msgid "Sets the current transaction's synchronization level." +msgstr "Geçerli iÅŸlemin (transaction) senkronizasyon seviyesini ayarlar." + +#: utils/misc/guc.c:4046 +msgid "Allows archiving of WAL files using archive_command." +msgstr "WAL dosyalarının archive_command kullanarak arÅŸivlenmesine izin verir." + +#: utils/misc/guc.c:4056 +msgid "Enables logging of recovery-related debugging information." +msgstr "Kurtarma ile ilgili hata ayıklama bilgisinin loglanmasını etkinleÅŸtirir." + +#: utils/misc/guc.c:4072 +msgid "Collects function-level statistics on database activity." +msgstr "Veritabanı etkinliÄŸi sırasında fonksiyon seviyesi istatistikleri toplar." + +#: utils/misc/guc.c:4082 +msgid "Set the level of information written to the WAL." +msgstr "WAL'a yazılacak bilgi detay seviyesini ayarla." + +#: utils/misc/guc.c:4092 +msgid "Selects the dynamic shared memory implementation used." +msgstr "Dinamik paylaşılan bellek (shared memory) uygulaması seçimini yapar." + +#: utils/misc/guc.c:4102 +msgid "Selects the method used for forcing WAL updates to disk." +msgstr "WAL deÄŸikliklerinin diske yazılış yöntemini belirtiyor." + +#: utils/misc/guc.c:4112 +msgid "Sets how binary values are to be encoded in XML." +msgstr "İkili deÄŸerlerin XML içinde nasıl kodlanacağını belirtiyor." + +#: utils/misc/guc.c:4122 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." +msgstr "Ayrıştırma ve serialization iÅŸlemlerde XML veri birer document mi yoksa conten fragment olarak mı sayılacağını belirtiyor." + +#: utils/misc/guc.c:4133 +msgid "Use of huge pages on Linux or Windows." +msgstr "Linux veya Windows'ta çok büyük (huge) sayfaların kullanımı." + +#: utils/misc/guc.c:4143 +msgid "Forces use of parallel query facilities." +msgstr "Paralel sorgu imkanlarının kullanımına zorlar." + +#: utils/misc/guc.c:4144 +msgid "If possible, run query using a parallel worker and with parallel restrictions." +msgstr "Mümkünse, sorguyu bir paralel worker kullanarak ve paralel kısıtlamalarıyla çalıştırın." + +#: utils/misc/guc.c:4153 +msgid "Encrypt passwords." +msgstr "Parolaları ÅŸifrele." + +#: utils/misc/guc.c:4154 +msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +msgstr "CREATE USER veya ALTER USER komutunda ÅŸifre verilmiÅŸ ancak ENCRYPTED veya UNENCRYPTED verilmemiÅŸ ise bu parametre ÅŸifrenin ÅŸifrelenmiÅŸ olyp olmayacağını belirtiyor." + +#: utils/misc/guc.c:4956 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: \"%s\" dizine eriÅŸim hatası: %s\n" + +#: utils/misc/guc.c:4961 +#, c-format +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgstr "Bir PostgreSQL veri dizinini ilklendirmek için initdb ya da pg_basebackup çalıştırınız.\n" + +#: utils/misc/guc.c:4981 +#, c-format +msgid "" +"%s does not know where to find the server configuration file.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" +msgstr "" +"%s, gereken konfigurasyon dosyasını bulamamaktadır.\n" +"Bu dosyanın --config-file veya -D baÅŸlatma parametresi veya PGDATA enviroment deÄŸiÅŸkeni ile belirtilebilir.\n" + +#: utils/misc/guc.c:5000 +#, c-format +msgid "%s: could not access the server configuration file \"%s\": %s\n" +msgstr "%s: sunucu konfigurasyon dosyasına \"%s\" eriÅŸilemiyor: %s\n" + +#: utils/misc/guc.c:5026 +#, c-format +msgid "" +"%s does not know where to find the database system data.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s, greken veritabanı dosyaları bulamamaktadır.\n" +"Dizinin yeri \"%s\" dosyasında \"data_directory\" deÄŸiÅŸkeninde, -D baÅŸlatma parametresi veya PGDATA enviroment deÄŸiÅŸkeni ile belirtilebilir.\n" + +#: utils/misc/guc.c:5074 +#, c-format +msgid "" +"%s does not know where to find the \"hba\" configuration file.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s, greken \"hba\" konfigurasyon dosyasını bulamamaktadır.\n" +"Bu dosyanın yeri \"%s\" dosyasında \"hba_file\" deÄŸiÅŸkeninde, -D baÅŸlatma parametresi veya PGDATA enviroment deÄŸiÅŸkeni ile belirtilebilir.\n" + +#: utils/misc/guc.c:5097 +#, c-format +msgid "" +"%s does not know where to find the \"ident\" configuration file.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" +msgstr "" +"%s, greken \"ident\" konfigurasyon dosyasını bulamamaktadır.\n" +"Bu dosyanın yeri \"%s\" dosyasında \"ident_file\" deÄŸiÅŸkeninde, baÅŸlatma parametresi -D veya PGDATA enviroment deÄŸiÅŸkeni ile belirtilebilir.\n" + +#: utils/misc/guc.c:5772 utils/misc/guc.c:5819 +msgid "Value exceeds integer range." +msgstr "DeÄŸer tamsayı aralığını aşıyor." + +#: utils/misc/guc.c:6042 +#, c-format +msgid "parameter \"%s\" requires a numeric value" +msgstr "\"%s\" seçeneÄŸi sayısal deÄŸer gerektirir." + +#: utils/misc/guc.c:6051 +#, c-format +msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" +msgstr "\"%2$s\" parametresi için %1$g deÄŸer sıra dışıdır (%3$g .. %4$g)" + +#: utils/misc/guc.c:6204 utils/misc/guc.c:7574 +#, c-format +msgid "cannot set parameters during a parallel operation" +msgstr "paralel iÅŸlem sırasında parametreler ayarlanamaz" + +#: utils/misc/guc.c:6211 utils/misc/guc.c:6963 utils/misc/guc.c:7016 utils/misc/guc.c:7067 utils/misc/guc.c:7403 utils/misc/guc.c:8170 utils/misc/guc.c:8338 utils/misc/guc.c:10015 +#, c-format +msgid "unrecognized configuration parameter \"%s\"" +msgstr "\"%s\" bilinmeyen konfigurasyon parametresi" + +#: utils/misc/guc.c:6226 utils/misc/guc.c:7415 +#, c-format +msgid "parameter \"%s\" cannot be changed" +msgstr "\"%s\" parametresi deÄŸiÅŸtirilemez" + +#: utils/misc/guc.c:6259 +#, c-format +msgid "parameter \"%s\" cannot be changed now" +msgstr "\"%s\" parametresi ÅŸu anda deÄŸiÅŸtirilemez" + +#: utils/misc/guc.c:6277 utils/misc/guc.c:6324 utils/misc/guc.c:10031 +#, c-format +msgid "permission denied to set parameter \"%s\"" +msgstr "\"%s\" parametresi deÄŸiÅŸtirmek için eriÅŸim hatası" + +#: utils/misc/guc.c:6314 +#, c-format +msgid "parameter \"%s\" cannot be set after connection start" +msgstr "\"%s\" parametresi baÄŸlantı baÅŸlatıldıktan sonra deÄŸiÅŸtirilemez" + +#: utils/misc/guc.c:6362 +#, c-format +msgid "cannot set parameter \"%s\" within security-definer function" +msgstr "security definer fonksiyonu içinde \"%s\" parametresi ayarlanamaz" + +#: utils/misc/guc.c:6971 utils/misc/guc.c:7021 utils/misc/guc.c:8345 +#, c-format +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "\"%s\" deÄŸiÅŸkeninin deÄŸerini sorgulamak için superuser ya da pg_read_all_settings rolüne üye olmalısınız" + +#: utils/misc/guc.c:7112 +#, c-format +msgid "SET %s takes only one argument" +msgstr "SET %s tek bir argüman alır" + +#: utils/misc/guc.c:7363 +#, c-format +msgid "must be superuser to execute ALTER SYSTEM command" +msgstr "ALTER SYSTEM Komutunu çalıştırmak için superuser olmalısınız" + +#: utils/misc/guc.c:7448 +#, c-format +msgid "parameter value for ALTER SYSTEM must not contain a newline" +msgstr "ALTER SYSTEM için parametre deÄŸeri yeni satır (newline) içermemeli" + +#: utils/misc/guc.c:7493 +#, c-format +msgid "could not parse contents of file \"%s\"" +msgstr "\"%s\" dosyasının içeriÄŸi ayrıştırılamadı (parse)" + +#: utils/misc/guc.c:7650 +#, c-format +msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" +msgstr "SET LOCAL TRANSACTION SNAPSHOT implemente edilmemiÅŸtir" + +#: utils/misc/guc.c:7734 +#, c-format +msgid "SET requires parameter name" +msgstr "SET komutu patametre adını gerektirir" + +#: utils/misc/guc.c:7867 +#, c-format +msgid "attempt to redefine parameter \"%s\"" +msgstr "\"%s\" parametresinin yeniden tanımlanma denemesi" + +#: utils/misc/guc.c:9648 +#, c-format +msgid "parameter \"%s\" could not be set" +msgstr "\"%s\" parametresi ayarlanamaz" + +#: utils/misc/guc.c:9735 +#, c-format +msgid "could not parse setting for parameter \"%s\"" +msgstr "\"%s\" parametresi için verilen deÄŸer çözümlenemiyor" + +#: utils/misc/guc.c:10093 utils/misc/guc.c:10127 +#, c-format +msgid "invalid value for parameter \"%s\": %d" +msgstr "\"%s\" seçeneÄŸi için geçersiz deÄŸer: %d" + +#: utils/misc/guc.c:10161 +#, c-format +msgid "invalid value for parameter \"%s\": %g" +msgstr "\"%s\" seçeneÄŸi için geçersiz deÄŸer: %g" + +#: utils/misc/guc.c:10445 +#, c-format +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "oturumda herhangi bir geçici (temporary) tabloya eriÅŸildikten sonra \"temp_buffers\" deÄŸiÅŸtirilemez." + +#: utils/misc/guc.c:10457 +#, c-format +msgid "Bonjour is not supported by this build" +msgstr "Bonjour bu yapılandırma tarafından desteklenmiyor." + +#: utils/misc/guc.c:10470 +#, c-format +msgid "SSL is not supported by this build" +msgstr "SSL bu yapılandırma tarafından desteklenmiyor." + +#: utils/misc/guc.c:10482 +#, c-format +msgid "Cannot enable parameter when \"log_statement_stats\" is true." +msgstr "\"log_statement_stats\" true iken parametre etkinleÅŸtirilemez" + +#: utils/misc/guc.c:10494 +#, c-format +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "\"log_parser_stats\", \"log_planner_stats\", veya \"log_executor_stats\" deÄŸerleri true iken \"log_statement_stats\" etkinleÅŸtirilemez" + +#: utils/misc/guc.c:10710 +#, c-format +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgstr "" + +#: utils/misc/help_config.c:131 +#, c-format +msgid "internal error: unrecognized run-time parameter type\n" +msgstr "dahili hata: tanınmayan çalıştırma zamanı parametre tipi\n" + +#: utils/misc/pg_config.c:60 +#, c-format +msgid "query-specified return tuple and function return type are not compatible" +msgstr "sorgu tarafından belirtilen dönüş satırı ve fonksiyon dönüş tipi birbiriyle uyumlu deÄŸil" + +#: utils/misc/pg_controldata.c:59 utils/misc/pg_controldata.c:137 utils/misc/pg_controldata.c:241 utils/misc/pg_controldata.c:308 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "hesaplanan CRC saÄŸlaması (checksum) dosyada saklanan deÄŸerden farklı" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU: kullanıcı: %d.%02d s, sistem: %d.%02d s, geçen: %d.%02d s" + +#: utils/misc/rls.c:127 +#, c-format +msgid "query would be affected by row-level security policy for table \"%s\"" +msgstr "sorgu \"%s\" tablosunun satır seviyesi güvenlik politikasından (row-level securit policy) etkilenebilir" + +#: utils/misc/rls.c:129 +#, c-format +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." +msgstr "Tablonun sahibi için olan politikayı (policy) devre dışı bırakmak için, ALTER TABLE NO FORCE ROW LEVEL SECURITY kullanın." + +#: utils/misc/timeout.c:388 +#, c-format +msgid "cannot add more timeout reasons" +msgstr "daha fazla zaman aşımı (timeout) sebebi eklenemez" + +#: utils/misc/tzparser.c:61 +#, c-format +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" +msgstr "\"%3$s\" timezone dosyasında, %4$d satırında, timezone kısaltması \"%1$s\" çok uzundur (en çok %2$d karakter olabilr) " + +#: utils/misc/tzparser.c:73 +#, c-format +msgid "time zone offset %d is out of range in time zone file \"%s\", line %d" +msgstr "\"%2$s\" timezone dosyasında, %3$d satırında, %1$d timezone offset kapsam dışıdır" + +#: utils/misc/tzparser.c:112 +#, c-format +msgid "missing time zone abbreviation in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone dosyasında, %d satırında time zone kısaltması eksik" + +#: utils/misc/tzparser.c:121 +#, c-format +msgid "missing time zone offset in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone dosyasında, %d satırında time zone offset eksik" + +#: utils/misc/tzparser.c:133 +#, c-format +msgid "invalid number for time zone offset in time zone file \"%s\", line %d" +msgstr "\"%s\" timezone dosyasında, %d satırında, time zone offset için geçersiz numara" + +#: utils/misc/tzparser.c:169 +#, c-format +msgid "invalid syntax in time zone file \"%s\", line %d" +msgstr "\"%s\" time zone dosyasında, %d satırında söz dizimi hatası" + +#: utils/misc/tzparser.c:237 +#, c-format +msgid "time zone abbreviation \"%s\" is multiply defined" +msgstr "\"%s\" time zone kısaltması birden çok kez tanımlanmış" + +#: utils/misc/tzparser.c:239 +#, c-format +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." +msgstr "\"%s\" timezone dosyasının %d. satırı, \"%s\" timezone dosyasının %d. satırı ile çakışmaktadır." + +#: utils/misc/tzparser.c:301 +#, c-format +msgid "invalid time zone file name \"%s\"" +msgstr "geçersiz zaman dilimi dosyası adı: \"%s\"" + +#: utils/misc/tzparser.c:314 +#, c-format +msgid "time zone file recursion limit exceeded in file \"%s\"" +msgstr "\"%s\" dosyasında derinlik sınırı aşılmıştır. (DİKKAT: Bu hatayı gördüyseniz pgsql-hackers@postgresql.org listesine rapor gönderin)" + +#: utils/misc/tzparser.c:353 utils/misc/tzparser.c:366 +#, c-format +msgid "could not read time zone file \"%s\": %m" +msgstr "\"%s\" time zone dosyası okuma hatası: %m" + +#: utils/misc/tzparser.c:376 +#, c-format +msgid "line is too long in time zone file \"%s\", line %d" +msgstr "\"%s\" timezone dosyası, %d satırında, satır çok uzundur" + +#: utils/misc/tzparser.c:399 +#, c-format +msgid "@INCLUDE without file name in time zone file \"%s\", line %d" +msgstr "\"%s\" saat dilimi (timezone) dosyası, %d satırında dosya adı içermeyen @INCLUDE " + +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 +#, c-format +msgid "Failed while creating memory context \"%s\"." +msgstr "Memory content \"%s\" oluÅŸturma baÅŸarısız." + +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1325 +#, c-format +msgid "could not attach to dynamic shared area" +msgstr "dinamik paylaşımlı alana (shared area) eklenemedi (attach)" + +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 utils/mmgr/mcxt.c:1134 +#, fuzzy, c-format +#| msgid "Failed on request of size %zu." +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "%zu boyutu isteÄŸi baÅŸarısız" + +#: utils/mmgr/portalmem.c:187 +#, c-format +msgid "cursor \"%s\" already exists" +msgstr "cursor \"%s\" zaten mevcut" + +#: utils/mmgr/portalmem.c:191 +#, c-format +msgid "closing existing cursor \"%s\"" +msgstr "var olan cursor \"%s\" kapatılıyor" + +#: utils/mmgr/portalmem.c:398 +#, c-format +msgid "portal \"%s\" cannot be run" +msgstr "\"%s\" portal'i çalıştırılamıyor" + +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "\"%s\" iÄŸnelenmiÅŸ (pinned) portal'i silinemiyor" + +#: utils/mmgr/portalmem.c:484 +#, c-format +msgid "cannot drop active portal \"%s\"" +msgstr "\"%s\" aktif portal'i silinemiyor" + +#: utils/mmgr/portalmem.c:729 +#, c-format +msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" +msgstr "WITH HOLD imleci oluÅŸturan transaction PREPARE edilemedi" + +#: utils/mmgr/portalmem.c:1263 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "salt-okunur olmayan bir cursor döngüsü içinde iÅŸlem (transaction) komutları gerçekleÅŸtirilemez" + +#: utils/sort/logtape.c:276 +#, c-format +msgid "could not read block %ld of temporary file: %m" +msgstr "geçici dosyasının %ld bloku okunamıyor: %m" + +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "geçici dosyaya yazma baÅŸarısız: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "paylaşılan tuplestore geçici dosyasından okuma baÅŸarısız: %m" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "paylaşılan tuplestore geçici dosyasında beklenmeyen yığın (chunk): %m" + +#: utils/sort/tuplesort.c:2967 +#, c-format +msgid "cannot have more than %d runs for an external sort" +msgstr "harici sıralama için %d den fazla çalıştırma (run) olamaz" + +#: utils/sort/tuplesort.c:4051 +#, c-format +msgid "could not create unique index \"%s\"" +msgstr "\"%s\" tekil (unique) indeksi yaratılamadı" + +#: utils/sort/tuplesort.c:4053 +#, c-format +msgid "Key %s is duplicated." +msgstr "%s anahtarı (key) çoÄŸaltılmış (duplicated)." + +#: utils/sort/tuplesort.c:4054 +#, c-format +msgid "Duplicate keys exist." +msgstr "Tekrar eden (duplicate) anahtarlar var." + +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 utils/sort/tuplestore.c:1330 +#, c-format +msgid "could not seek in tuplestore temporary file: %m" +msgstr "tuplestore geçici dosyası ilerleme (seek) hatası: %m" + +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 utils/sort/tuplestore.c:1556 +#, c-format +msgid "could not read from tuplestore temporary file: %m" +msgstr "tuplestore geçici dosyasından okuma baÅŸarısız: %m" + +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 utils/sort/tuplestore.c:1529 +#, c-format +msgid "could not write to tuplestore temporary file: %m" +msgstr "tuplestore geçici dosyasına yazma baÅŸarısız: %m" + +#: utils/time/snapmgr.c:622 +#, c-format +msgid "The source transaction is not running anymore." +msgstr "Kaynak iÅŸlem (transaction) artık çalışmıyor." + +#: utils/time/snapmgr.c:1200 +#, c-format +msgid "cannot export a snapshot from a subtransaction" +msgstr "bir subtransaction dan dışarıya snapshot aktarılamaz (export)" + +#: utils/time/snapmgr.c:1359 utils/time/snapmgr.c:1364 utils/time/snapmgr.c:1369 utils/time/snapmgr.c:1384 utils/time/snapmgr.c:1389 utils/time/snapmgr.c:1394 utils/time/snapmgr.c:1409 utils/time/snapmgr.c:1414 utils/time/snapmgr.c:1419 utils/time/snapmgr.c:1519 utils/time/snapmgr.c:1535 utils/time/snapmgr.c:1560 +#, c-format +msgid "invalid snapshot data in file \"%s\"" +msgstr "\"%s\" dosyasında geçersiz snapshot verisi" + +#: utils/time/snapmgr.c:1456 +#, c-format +msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgstr "bir sorgudan önce SET TRANSACTION SNAPSHOT çağırılmalıdır" + +#: utils/time/snapmgr.c:1465 +#, c-format +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "içe snapshot aktaran bir iÅŸlemin (transaction) izolasyon seviyesi (isolation level) SERIALIZABLE ya da REPEATABLE READ olmalı" + +#: utils/time/snapmgr.c:1474 utils/time/snapmgr.c:1483 +#, c-format +msgid "invalid snapshot identifier: \"%s\"" +msgstr "geçersiz snapshot tanımlayıcı: \"%s\" " + +#: utils/time/snapmgr.c:1573 +#, c-format +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" +msgstr "serializable bir iÅŸlem (transaction) non-serializable bir iÅŸlemden snapshot içeri aktaramaz (import)" + +#: utils/time/snapmgr.c:1577 +#, c-format +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" +msgstr "salt-okunur olmayan bir iÅŸlem (transaction) salt-okunur bir iÅŸlemden snapshot " + +#: utils/time/snapmgr.c:1592 +#, c-format +msgid "cannot import a snapshot from a different database" +msgstr "farklı bir veritabanından snapshot içeri aktarılamaz (import)" + +#~ msgid "included columns must not intersect with key columns" +#~ msgstr "dahil edilen (included) sütunlar anahtar sütunlarla kesiÅŸmemelidir" + +#~ msgid "column \"%s\" appears more than once in partition key" +#~ msgstr "\"%s\" sütununa bölümleme anahtarında birden fazla kez rastlanmaktadır" + +#~ msgid "could not create two-phase state file \"%s\": %m" +#~ msgstr "\"%s\" two-phase state dosyası oluÅŸturulamadı: %m" + +#~ msgid "two-phase state file for transaction %u is corrupt" +#~ msgstr "%u transaction için two-phase state dosyası hasar görmüştür" + +#~ msgid "could not fsync two-phase state file \"%s\": %m" +#~ msgstr "\"%s\" two-phase state dosyası fsync hatası: %m" + +#~ msgid "could not close two-phase state file \"%s\": %m" +#~ msgstr "two-phase state dosyası \"%s\" kapatılamıyor: %m" + +#~ msgid "could not open file \"%s\" (log file %u, segment %u): %m" +#~ msgstr "\"%s\" dosyası (log dosyası %u, segment %u) açma hatası: %m" + +#~ msgid "could not link file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" +#~ msgstr "\"%s\" dosyası \"%s\" dosyasına baÄŸlanamıyor (log dosyası %u, segment %u sıfırlama iÅŸlemi): %m" + +#~ msgid "could not rename file \"%s\" to \"%s\" (initialization of log file %u, segment %u): %m" +#~ msgstr "\"%s\" dosyası \"%s\" dosyasına taşınamıyor (log dosyası %u, segment %u ilklendirme iÅŸlemi): %m" + +#~ msgid "%s \"%s\": return code %d" +#~ msgstr "%s \"%s\": dönüş kodu %d" + +#, fuzzy +#~ msgid "could not remove old transaction log file \"%s\": %m" +#~ msgstr "\"%s\" lock dosyası silinemiyor: %m" + +#~ msgid "removing transaction log backup history file \"%s\"" +#~ msgstr "\"%s\" transaction kayıt yedek dosyası kaldırılıyor" + +#~ msgid "incorrect hole size in record at %X/%X" +#~ msgstr "%X/%X adresinde geçersiz boÅŸluk boyutu" + +#~ msgid "incorrect total length in record at %X/%X" +#~ msgstr "%X/%X adresinde geçersiz toplam uzunluk" + +#~ msgid "invalid xlog switch record at %X/%X" +#~ msgstr "%X/%X adresinde geçersiz xlog switch kaydı" + +#~ msgid "there is no contrecord flag in log file %u, segment %u, offset %u" +#~ msgstr "kayıt dosyası %u, segment %u, offset %u adresinde contrecord bulunamadı" + +#~ msgid "invalid contrecord length %u in log file %u, segment %u, offset %u" +#~ msgstr "kayıt dosyası %2$u, segment %3$u, offset %4$u adresinde contrecord fazla uzun %1$u" + +#~ msgid "Incorrect XLOG_SEG_SIZE in page header." +#~ msgstr "Sayfa baÅŸlığında geçersiz XLOG_SEG_SIZE." + +#~ msgid "Incorrect XLOG_BLCKSZ in page header." +#~ msgstr "Sayfa baÅŸlığında geçersiz XLOG_BLCKSZ." + +#~ msgid "The database cluster was initialized without HAVE_INT64_TIMESTAMP but the server was compiled with HAVE_INT64_TIMESTAMP." +#~ msgstr "Veritabanı clusteri HAVE_INT64_TIMESTAMP olmadan ilklendirilmiÅŸtir, ancak sunucu HAVE_INT64_TIMESTAMP ile derlenmiÅŸtir." + +#~ msgid "The database cluster was initialized with HAVE_INT64_TIMESTAMP but the server was compiled without HAVE_INT64_TIMESTAMP." +#~ msgstr "Veritabanı clusteri HAVE_INT64_TIMESTAMP ile ilklendirilmiÅŸtir, ancak sunucu HAVE_INT64_TIMESTAMP olmadan derlenmiÅŸtir." + +#~ msgid "restore_command = '%s'" +#~ msgstr "restore_command = '%s'" + +#, fuzzy +#~ msgid "archive_cleanup_command = '%s'" +#~ msgstr "restore_command = '%s'" + +#~ msgid "recovery_target_timeline = latest" +#~ msgstr "recovery_target_timeline = latest" + +#~ msgid "recovery_target_xid = %u" +#~ msgstr "recovery_target_xid = %u" + +#~ msgid "recovery_target_time = '%s'" +#~ msgstr "recovery_target_time = '%s'" + +#~ msgid "recovery_target_inclusive = %s" +#~ msgstr "recovery_target_inclusive = %s" + +#~ msgid "standby_mode = '%s'" +#~ msgstr "bekleme_modu = '%s'" + +#~ msgid "primary_conninfo = '%s'" +#~ msgstr "primary_conninfo = '%s'" + +#, fuzzy +#~ msgid "trigger_file = '%s'" +#~ msgstr "recovery_target_time = '%s'" + +#~ msgid "syntax error in recovery command file: %s" +#~ msgstr "%s recovery komut dosyasında sözdizimi hatası " + +#~ msgid "Lines should have the format parameter = 'value'." +#~ msgstr "Satırların biçimi şöyle olmalıdır: parametre = 'deÄŸer'." + +#~ msgid "redo record is at %X/%X; shutdown %s" +#~ msgstr "redo kaydı %X/%X; kapatma %s" + +#~ msgid "next transaction ID: %u/%u; next OID: %u" +#~ msgstr "sıradaki transaction ID: %u/%u; sıradaki OID: %u" + +#, fuzzy +#~ msgid "oldest unfrozen transaction ID: %u, in database %u" +#~ msgstr "%u nesnesinin uzantısı %u veritabanına aittir" + +#~ msgid "must be superuser to run a backup" +#~ msgstr "yedeklemeyi gerçekleÅŸtirmek için superuser haklarına sahip olmalısınız" + +#~ msgid "must be superuser to switch transaction log files" +#~ msgstr "transaction log dosyaları deÄŸiÅŸtirmek için superuser olmalısınız" + +#~ msgid "xlog redo %s" +#~ msgstr "xlog redo %s" + +#~ msgid "index \"%s\" needs VACUUM or REINDEX to finish crash recovery" +#~ msgstr "crash recovery bitirmesi için \"%s\" indeksin VACUUM veya REINDEX iÅŸleminden geçmesi gerekir" + +#~ msgid "index \"%s\" needs VACUUM FULL or REINDEX to finish crash recovery" +#~ msgstr "crash recovery bitirmesi için \"%s\" indeksin VACUUM FULL veya REINDEX iÅŸleminden geçmesi gerekir" + +#~ msgid "index %u/%u/%u needs VACUUM FULL or REINDEX to finish crash recovery" +#~ msgstr "crash recovery bitirmesi için %u/%u/%u indeksin VACUUM FULL veya REINDEX iÅŸleminden geçmesi gerekir" + +#~ msgid "Incomplete insertion detected during crash replay." +#~ msgstr "Crash replay sırasında tamamlanmamış insert tespit edildi." + +#~ msgid "streaming replication successfully connected to primary" +#~ msgstr "streaming replication baÅŸarılı olarak ana sunucuya baÄŸlandı" + +#~ msgid "socket not open" +#~ msgstr "soket açık deÄŸil" + +#~ msgid "recovery is still in progress, can't accept WAL streaming connections" +#~ msgstr "kurtarma iÅŸlemi devam ediyor, WAL streaming baÄŸlantıları kabul edilemiyor" + +#~ msgid "invalid standby query string: %s" +#~ msgstr "geçersiz standby sorgu katarı: %s" + +#, fuzzy +#~ msgid "invalid standby handshake message type %d" +#~ msgstr "geçersiz frontend mesaj tipi %d" + +#~ msgid "could not determine input data types" +#~ msgstr "giriÅŸ veri tipleri belirlenemiyor" + +#~ msgid "neither input type is an array" +#~ msgstr "giriÅŸ tiplerinin hiçbiri array deÄŸildir" + +#~ msgid "missing assignment operator" +#~ msgstr "atama iÅŸlemi eksik" + +#, fuzzy +#~ msgid "wrong range of array subscripts" +#~ msgstr "array subscript sayısı yanlış" + +#~ msgid "invalid input syntax for type boolean: \"%s\"" +#~ msgstr "boolean tipi için geçersiz giriÅŸ siz dizimi: \"%s\"" + +#~ msgid "invalid input syntax for type money: \"%s\"" +#~ msgstr "money tipi için geçersiz giriÅŸ siz dizimi: \"%s\"" + +#~ msgid "\"interval\" time zone \"%s\" not valid" +#~ msgstr "\"%s\" \"interval\" saat dilim geçersizdir" + +#~ msgid "invalid symbol" +#~ msgstr "geçersiz sembol" + +#~ msgid "invalid input syntax for type bytea" +#~ msgstr "bytea giriÅŸ tipi için geçersiz söz dizimi" + +#~ msgid "invalid input syntax for type real: \"%s\"" +#~ msgstr "real tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type double precision: \"%s\"" +#~ msgstr "double precision tipi için geçersiz biçim: \"%s\"" + +#, fuzzy +#~ msgid "\"TZ\"/\"tz\" format patterns are not supported in to_date" +#~ msgstr "bu platformda tablespace desteklenmiyor" + +#~ msgid "inconsistent use of year %04d and \"BC\"" +#~ msgstr "tutarsız %04d tıl ve \"BC\" tanımının kullanımı" + +#~ msgid "could not format \"path\" value" +#~ msgstr "\"path\" deÄŸeri biçimlendirilemiyor" + +#~ msgid "invalid input syntax for type box: \"%s\"" +#~ msgstr "box tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type line: \"%s\"" +#~ msgstr "line tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type path: \"%s\"" +#~ msgstr "path tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type point: \"%s\"" +#~ msgstr "point tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type lseg: \"%s\"" +#~ msgstr "lseg tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type polygon: \"%s\"" +#~ msgstr "polygon tipi için geçersiz biçim: \"%s\"" + +#~ msgid "invalid input syntax for type circle: \"%s\"" +#~ msgstr "circle tipi için geçersiz biçim: \"%s\"" + +#~ msgid "could not format \"circle\" value" +#~ msgstr "\"circle\" deÄŸeri biçimlendirilemedi" + +#~ msgid "value \"%s\" is out of range for type bigint" +#~ msgstr "bigint tipi için \"%s\" deÄŸeri kapsam dışıdır" + +#~ msgid "invalid input syntax for type macaddr: \"%s\"" +#~ msgstr "macaddr tipi için geçersiz biçim: \"%s\"" + +#~ msgid "must be superuser to signal other server processes" +#~ msgstr "diÄŸer aktif sunucu süreçlerine sinyal göndermek için superuser olmanız lazım" + +#~ msgid "must be superuser to signal the postmaster" +#~ msgstr "postmaster süreçlerine sinyal göndermek için superuser olmanız lazım" + +#~ msgid "invalid input syntax for type tinterval: \"%s\"" +#~ msgstr "interval tipi için geçersiz biçim: \"%s\"" + +#~ msgid "argument for function \"exp\" too big" +#~ msgstr "\"exp\" fonksiyonu için argüman fazla büyük" + +#~ msgid "value \"%s\" is out of range for type integer" +#~ msgstr "integer tipi için \"%s\" deÄŸeri kapsam dışıdır" + +#~ msgid "value \"%s\" is out of range for type smallint" +#~ msgstr "smallint tipi için \"%s\" deÄŸeri kapsam dışıdır" + +#~ msgid "invalid input syntax for type oid: \"%s\"" +#~ msgstr "oid tipi için geçersiz biçim: \"%s\"" + +#~ msgid "cannot accept a value of type anyenum" +#~ msgstr "anyenum tipinde deÄŸer alınamaz" + +#~ msgid "cannot accept a value of type trigger" +#~ msgstr "trigger tipinde deÄŸer alınamaz" + +#~ msgid "cannot display a value of type trigger" +#~ msgstr "trigger tipinde deÄŸer gösterilemez" + +#~ msgid "cannot accept a value of type language_handler" +#~ msgstr "language_handler tipinde deÄŸer alınamaz" + +#~ msgid "cannot display a value of type language_handler" +#~ msgstr "language_handler tipinde deÄŸer gösterilemez" + +#~ msgid "cannot accept a value of type internal" +#~ msgstr "internal tipinde deÄŸer alınamaz" + +#~ msgid "cannot display a value of type internal" +#~ msgstr "internal tipinde deÄŸer gösterilemez" + +#~ msgid "cannot accept a value of type opaque" +#~ msgstr "opaque tipinde deÄŸer alınamaz" + +#~ msgid "cannot display a value of type opaque" +#~ msgstr "opaque tipinde deÄŸer gösterilemez" + +#~ msgid "cannot accept a value of type anyelement" +#~ msgstr "anyelement tipinde deÄŸer alınamaz" + +#~ msgid "cannot display a value of type anyelement" +#~ msgstr "anyelement tipinde deÄŸer gösterilemez" + +#, fuzzy +#~ msgid "cannot display a value of type anynonarray" +#~ msgstr "any tipinde deÄŸer gösterilemez" + +#~ msgid "No rows were found in \"%s\"." +#~ msgstr "\"%s\" içinde tahsis edilebilir bir girdi yok." + +#~ msgid "invalid input syntax for type tid: \"%s\"" +#~ msgstr "tid veri tipi için geersiz söz dizimi: \"%s\"" + +#~ msgid "could not convert to time zone \"%s\"" +#~ msgstr "\"%s\" zaman dilimine dönüştürülemedi" + +#~ msgid "invalid input syntax for uuid: \"%s\"" +#~ msgstr "uuid tipi için geçersiz söz dizimi: \"%s\"" + +#~ msgid "Perhaps out of disk space?" +#~ msgstr "Disk dolu mu?" + +#~ msgid "Write-Ahead Log / Streaming Replication" +#~ msgstr "Write-Ahead Log / Streaming Replication" + +#~ msgid "Sets immediate fsync at commit." +#~ msgstr "commit iÅŸleminde anlık fsync gönderimini ayarlar." + +#~ msgid "Runs the server silently." +#~ msgstr "Sunucusunu sessiz biçimde çalıştır." + +#~ msgid "If this parameter is set, the server will automatically run in the background and any controlling terminals are dissociated." +#~ msgstr "Bu parametre ayarlı ise, sunucu süreci, arka planda çalışacak ve sürecine baÄŸlı tüm uçbirimlerin iliÅŸkileri kesilecektir." + +#~ msgid "Turns on various assertion checks." +#~ msgstr "ÇeÅŸitli ısrar hata kontrollerini açıyor." + +#~ msgid "This is a debugging aid." +#~ msgstr "Bu bir debug yardımı." + +#~ msgid "No description available." +#~ msgstr "Açıklama yok." + +#~ msgid "Causes subtables to be included by default in various commands." +#~ msgstr "ÇeÅŸitli komutlara varsayılan olarak alt tabloların eklenmesine sebep olacak." + +#~ msgid "This parameter doesn't do anything." +#~ msgstr "Bu parametre bir ÅŸey yapmıyor." + +#~ msgid "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-vintage clients." +#~ msgstr "Bu ayar 7.3 istemcilerin göndereceÄŸi SET AUTOCOMMIT TO ON komutunu doÄŸru yorumlamak için konulmuÅŸtır." + +#~ msgid "Sets the maximum distance in log segments between automatic WAL checkpoints." +#~ msgstr "Otomatic WAL denetim noktaları (checkpoint) arasında katedilecek log segment saytısı." + +#, fuzzy +#~ msgid "WAL writer sleep time between WAL flushes." +#~ msgstr "Background writer'in seferleri arasında hareketsiz kalacağı zaman süresi." + +#, fuzzy +#~ msgid "WAL sender sleep time between WAL replications." +#~ msgstr "Background writer'in seferleri arasında hareketsiz kalacağı zaman süresi." + +#~ msgid "Sets the name of the Kerberos service." +#~ msgstr "Kerberos sevice adını belirtiyor." + +#~ msgid "Sets the list of known custom variable classes." +#~ msgstr "Bilinen custom variable classes listesini belirtiyor." + +#~ msgid "invalid list syntax for parameter \"log_destination\"" +#~ msgstr "\"log_destination\" parametresi için dözdizimi geçersiz" + +#~ msgid "unrecognized \"log_destination\" key word: \"%s\"" +#~ msgstr "\"log_destination\" anahtar kelimesi tanımlanamıyor: \"%s\"" + +#~ msgid "time zone offset %d is not a multiple of 900 sec (15 min) in time zone file \"%s\", line %d" +#~ msgstr "\"%2$s\" timezone dosyasında, %3$d satırında, %1$d timezone offset 900 san. (15 dk.) veya katları deÄŸildir" + +#~ msgid "function %u has too many arguments (%d, maximum is %d)" +#~ msgstr "%u fonksiyonu çok fazla argümana sahip (%d, en yüksek ise %d)" + +#, fuzzy +#~ msgid "multibyte flag character is not allowed" +#~ msgstr "birden çok LIMIT ifadesi kullanılamaz" + +#~ msgid "invalid privilege type USAGE for table" +#~ msgstr "tablo için geçersiz hak tipi kullanımı" + +#~ msgid "uncataloged table %s" +#~ msgstr "%s katalog edilemeiÅŸ tablo" + +#~ msgid "column \"%s\" has type \"unknown\"" +#~ msgstr "\"%s\" sütunu \"unknown\" tipine sahip" + +#~ msgid "Proceeding with relation creation anyway." +#~ msgstr "Nesne oluÅŸturmasına yine de devam edilmektedir." + +#, fuzzy +#~ msgid "cannot drop \"%s\" because it is being used by active queries in this session" +#~ msgstr "\"%s\" tablosu ÅŸu anda aktif sorgular tarafından kullanılmaktadır" + +#~ msgid "default expression must not return a set" +#~ msgstr "öntanımlı ifade küme döndürmelidir" + +#~ msgid "cannot use subquery in default expression" +#~ msgstr "öntanımlı ifadede subquery kullanılamaz" + +#~ msgid "cannot use aggregate function in default expression" +#~ msgstr "öntanımlı ifadede aggregate fonksiyonu kullanılamaz" + +#, fuzzy +#~ msgid "cannot use window function in default expression" +#~ msgstr "öntanımlı ifadede aggregate fonksiyonu kullanılamaz" + +#, fuzzy +#~ msgid "cannot use window function in check constraint" +#~ msgstr "check constraint içinde aggregate function kullanılamaz" + +#~ msgid "clustering \"%s.%s\"" +#~ msgstr "\"%s.%s\" CLUSTER ediliyor" + +#~ msgid "cannot cluster on index \"%s\" because access method does not handle null values" +#~ msgstr "\"%s\" indexin eriÅŸim yöntemi null deÄŸerleri desteklemediÄŸi için cluster yapılamaz" + +#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL, or use ALTER TABLE ... SET WITHOUT CLUSTER to remove the cluster specification from the table." +#~ msgstr "Bunu önlemek için \"%s\" sütunu NOT NULL yaparak ya da tablodan cluser tanımlarını kaldırmak için ALTER TABLE ... SET WITHOUT CLUSTER kullanabilirsiniz." + +#~ msgid "You might be able to work around this by marking column \"%s\" NOT NULL." +#~ msgstr "\"%s\" sütununu NOT NULL olarak tanımlamakla bu sorunu çözebilirsiniz" + +#~ msgid "cannot cluster on expressional index \"%s\" because its index access method does not handle null values" +#~ msgstr "\"%s\" ifadesel indexin eriÅŸim yöntemi null deÄŸerleri desteklemediÄŸi için cluster yapılamaz" + +#, fuzzy +#~ msgid "\"%s\" is not a table, view, or composite type" +#~ msgstr "\"%s\" bir tablo, view veya sequence deÄŸildir" + +#~ msgid "database name cannot be qualified" +#~ msgstr "veritabanı ismi geçerli deÄŸil" + +#~ msgid "tablespace name cannot be qualified" +#~ msgstr "tablespace adı geçerli deÄŸil" + +#~ msgid "must be member of role \"%s\" to comment upon it" +#~ msgstr "\"%s\" rolüne açıklama eklemek için bu role dahil olmalısınız" + +#~ msgid "schema name cannot be qualified" +#~ msgstr "ÅŸema ismi geçerli deÄŸil" + +#~ msgid "rule \"%s\" does not exist" +#~ msgstr "\"%s\" rule'u mevcut deÄŸil" + +#~ msgid "there are multiple rules named \"%s\"" +#~ msgstr "\"%s\" adını taşıyan birden fazla rule mevcut" + +#~ msgid "Specify a relation name as well as a rule name." +#~ msgstr "Rule adının yanında nesne adını da belirtin." + +#~ msgid "language name cannot be qualified" +#~ msgstr "dil ismi geçerli deÄŸil" + +#~ msgid "must be superuser to comment on procedural language" +#~ msgstr "bir yordamsal dile açıklama eklemek için superuser olmalısınız" + +#~ msgid "must be superuser to comment on text search parser" +#~ msgstr "metin arama ayrıştırıcısına açıklama eklemek için superuser olmalısınız" + +#~ msgid "must be superuser to comment on text search template" +#~ msgstr "bir metin arama ÅŸablonuna açıklama eklemek için superuser olmalısınız" + +#, fuzzy +#~ msgid "permission denied to drop foreign-data wrapper \"%s\"" +#~ msgstr "\"%s\" veritabanını kopyalama engellendi" + +#, fuzzy +#~ msgid "Must be superuser to drop a foreign-data wrapper." +#~ msgstr "Tablespace oluÅŸturmak için superuser haklarına sahip olmalısınız." + +#, fuzzy +#~ msgid "cannot use subquery in parameter default value" +#~ msgstr "EXECUTE parametresinde subquery kullanılamaz" + +#, fuzzy +#~ msgid "cannot use aggregate function in parameter default value" +#~ msgstr "EXECUTE parametresinde aggregate fonksiyon kullanılamaz" + +#, fuzzy +#~ msgid "cannot use window function in parameter default value" +#~ msgstr "EXECUTE parametresinde aggregate fonksiyon kullanılamaz" + +#~ msgid "removing built-in function \"%s\"" +#~ msgstr "gömülü \"%s\" fonksiyonu kaldırılıyor" + +#~ msgid "Use ALTER AGGREGATE to rename aggregate functions." +#~ msgstr "Aggregate fonksiyonunun adını deÄŸiÅŸtirmek içim ALTER AGGREGATE kullanın." + +#~ msgid "Use ALTER AGGREGATE to change owner of aggregate functions." +#~ msgstr "Aggregate fonksiyonunun sahibini deÄŸiÅŸtirmek içim ALTER AGGREGATE kullanın." + +#~ msgid "function \"%s\" is already in schema \"%s\"" +#~ msgstr "\"%s\" fonksiyonu \"%s\" ÅŸemasında zaten mevcut" + +#~ msgid "function \"%s\" already exists in schema \"%s\"" +#~ msgstr "\"%s\" fonksiyonu \"%s\" ÅŸemasında zaten mevcut" + +#~ msgid "cannot use aggregate in index predicate" +#~ msgstr "index tanımında aggregate kullanılamaz" + +#~ msgid "=> is deprecated as an operator name" +#~ msgstr "=> geçerli bir operatör adı deÄŸildir" + +#~ msgid "could not reposition held cursor" +#~ msgstr "tutulan cursorun yerini deÄŸiÅŸtirilemez" + +#, fuzzy +#~ msgid "cannot use window function in EXECUTE parameter" +#~ msgstr "EXECUTE parametresinde aggregate fonksiyon kullanılamaz" + +#~ msgid "function %s must return type \"language_handler\"" +#~ msgstr "%s fonksiyonunun döndürme tipi \"language_handler\" olmalıdır" + +#~ msgid "changing return type of function %s from \"opaque\" to \"language_handler\"" +#~ msgstr "%s fonksiyonunun döndürme tipi \"opaque\"'dan \"language_handler\"'e deÄŸiÅŸtiriliyor" + +#~ msgid "cannot reference temporary table from permanent table constraint" +#~ msgstr "sürekli tablo kısıtlayıcısından geçici tablo referans edilemez" + +#~ msgid "cannot reference permanent table from temporary table constraint" +#~ msgstr "geçeci tablo kısıtlayıcısından sürekli tablo referans edilemez" + +#~ msgid "transform expression must not return a set" +#~ msgstr "transform ifadesi bir set döndürmemelidir" + +#, fuzzy +#~ msgid "cannot use window function in transform expression" +#~ msgstr "transform ifadesinde aggregate function kullanılamaz" + +#~ msgid "tablespace %u is not empty" +#~ msgstr "%u tablespace boÅŸ deÄŸil" + +#, fuzzy +#~ msgid "cannot use window function in trigger WHEN condition" +#~ msgstr "WHERE ÅŸart ifadelerinde aggregate function kullanılamaz" + +#~ msgid "changing return type of function %s from \"opaque\" to \"trigger\"" +#~ msgstr "%s fonksiyonunun döndürme deÄŸeri \"opaque\"tan \"trigger\"e deÄŸiÅŸtiriliyor" + +#~ msgid "function %s must return type \"trigger\"" +#~ msgstr "%s fonksiyonu \"trigger\" tipini döndürmelidir" + +#~ msgid "trigger \"%s\" for table \"%s\" does not exist, skipping" +#~ msgstr "\"%s\" triggeri \"%s\" tablosunda mevcut deÄŸil, atlanıyor" + +#~ msgid "must be superuser to drop text search parsers" +#~ msgstr "metin arama ayrıştırıcısını kaldırmak için superuser olmalısınız" + +#~ msgid "must be superuser to rename text search parsers" +#~ msgstr "metin arama ayrıştırıcısını yeniden adlandırmak için superuser olmalısınız" + +#~ msgid "must be superuser to rename text search templates" +#~ msgstr "metin arama ÅŸablolarının adını deÄŸiÅŸtirmek için superuser olmalısınız" + +#~ msgid "must be superuser to drop text search templates" +#~ msgstr "metin arama ÅŸablonlarını kaldırmak için superuser olmalısınız" + +#~ msgid "changing return type of function %s from \"opaque\" to \"cstring\"" +#~ msgstr "%s fonksiyonunun döndürme deÄŸeri \"opaque\"tan \"cstring\"e deÄŸiÅŸtiriliyor" + +#~ msgid "type output function %s must return type \"cstring\"" +#~ msgstr "%s type output fonksiyonu \"cstring\" döndürmelidir" + +#~ msgid "type send function %s must return type \"bytea\"" +#~ msgstr "%s type send fonksiyonu \"cstring\" döndürmelidir" + +#~ msgid "typmod_in function %s must return type \"integer\"" +#~ msgstr "%s typmod_in fonksiyonu \"trigger\" tipini döndürmelidir" + +#~ msgid "type %s is already in schema \"%s\"" +#~ msgstr "%s tipi \"%s\" ÅŸemasında zaten mevcut" + +#, fuzzy +#~ msgid "database \"%s\" not found" +#~ msgstr "time zone \"%s\" tanınmadı" + +#~ msgid "" +#~ "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +#~ "pages: %d removed, %d remain\n" +#~ "tuples: %.0f removed, %.0f remain\n" +#~ "system usage: %s" +#~ msgstr "" +#~ "\"%s.%s.%s\" tablosunun automatic vacuumu: index scans: %d\n" +#~ "pages: %d removed, %d remain\n" +#~ "tuples: %.0f removed, %.0f remain\n" +#~ "system kullanımı: %s" + +#~ msgid "invalid list syntax for parameter \"datestyle\"" +#~ msgstr "\"datestyle\" parametresi için list sözdizimi geçersiz" + +#~ msgid "unrecognized \"datestyle\" key word: \"%s\"" +#~ msgstr "\"datestyle\" anahtar kelimesi bulunamadı: \"%s\"" + +#~ msgid "invalid interval value for time zone: month not allowed" +#~ msgstr "zaman dilimi için geçersiz aralık deÄŸeri: ay belirtilemez" + +#~ msgid "invalid interval value for time zone: day not allowed" +#~ msgstr "zaman dilimi için geçersiz aralık deÄŸeri: gün ayarlanamaz" + +#~ msgid "functions and operators can take at most one set argument" +#~ msgstr "fonksiyon ve operator en çok bir tane set parametresi alabiliyorlar" + +#~ msgid "function returning set of rows cannot return null value" +#~ msgstr "satır seti döndüren fonksiyon null deÄŸerini döndüremez" + +#~ msgid "IS DISTINCT FROM does not support set arguments" +#~ msgstr "IS DISTINCT FROM ifadesi set parametreleri desteklememektedir" + +#~ msgid "op ANY/ALL (array) does not support set arguments" +#~ msgstr "op ANY/ALL (array) set parametreleri desteklememektedir" + +#~ msgid "NULLIF does not support set arguments" +#~ msgstr "NULLIF, set argümanları desteklememektedir" + +#~ msgid "%s: setsysinfo failed: %s\n" +#~ msgstr "%s: setsysinfo baÅŸarısız: %s\n" + +#~ msgid " -A 1|0 enable/disable run-time assert checking\n" +#~ msgstr " -A 1|0 run-time assert kontrolü etkinleÅŸtir/etkisizleÅŸtir\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardım ekranını yaz ve çık\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini yaz ve çık\n" + +#~ msgid "%s: invalid effective UID: %d\n" +#~ msgstr "%s: aktif UID %d geçersizidir\n" + +#~ msgid "%s: could not determine user name (GetUserName failed)\n" +#~ msgstr "%s: kullanıcı adı belirlenemedi (GetUserName baÅŸarısız)\n" + +#~ msgid "Kerberos 5 authentication failed for user \"%s\"" +#~ msgstr "\"%s\" kullanıcısı için Kerberos 5 kimlik doÄŸrulaması baÅŸarısız oldu" + +#~ msgid "missing or erroneous pg_hba.conf file" +#~ msgstr "Eksik ya da hatalı pg_hba.conf dosyası" + +#~ msgid "See server log for details." +#~ msgstr "Ayrıntılar için sunucu loguna bakın." + +#~ msgid "could not enable credential reception: %m" +#~ msgstr "kimlik doÄŸrulama alımı etkinleÅŸtirmesi baÅŸarısız: %m" + +#~ msgid "received password packet" +#~ msgstr "password paketi alınmıştır" + +#~ msgid "Kerberos initialization returned error %d" +#~ msgstr "Kerberos oluÅŸturma hatası %d" + +#~ msgid "Kerberos keytab resolving returned error %d" +#~ msgstr "Kerberos keytab resolving hatası %d" + +#~ msgid "Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d" +#~ msgstr "Kerberos sname_to_principal(\"%s\", \"%s\") hatası: %d" + +#~ msgid "Kerberos recvauth returned error %d" +#~ msgstr "Kerberos recvauth hatası %d" + +#~ msgid "Kerberos unparse_name returned error %d" +#~ msgstr "Kerberos unparse_name hatası %d" + +#~ msgid "SSPI error %x" +#~ msgstr "SSPI hatası: %x" + +#~ msgid "%s (%x)" +#~ msgstr "%s (%x)" + +#~ msgid "local user with ID %d does not exist" +#~ msgstr "yerel kullanıcı ID %d mevcut deÄŸildir" + +#, fuzzy +#~ msgid "could not get effective UID from peer credentials: %m" +#~ msgstr "karşı tarafın kimlik bilgileri alınamadı: %m" + +#~ msgid "Ident authentication is not supported on local connections on this platform" +#~ msgstr "bu platformda yerel baÄŸlantılarda Ident kimlik doÄŸrulaması desteklenmemektedir" + +#, fuzzy +#~ msgid "LDAP search failed for filter \"%s\" on server \"%s\": user is not unique (%ld matches)" +#~ msgstr "\"%s\" kullanıcısının \"%s\" sunucusunda LDAP oturumu açma baÅŸarısız: hata kodu %d" + +#~ msgid "SSL renegotiation failure" +#~ msgstr "SSL yeniden görüşme hatası" + +#~ msgid "SSL failed to send renegotiation request" +#~ msgstr "SSL görüşme cevabı gönderme baÅŸarısız" + +#~ msgid "Permissions should be u=rw (0600) or less." +#~ msgstr "İzinler u=rw (0600) ya da daha az olmalıdır." + +#, fuzzy +#~ msgid "could not access root certificate file \"%s\": %m" +#~ msgstr "ana sertifika dosyası \"%s\" okunaıyor: %s" + +#~ msgid "SSL certificate revocation list file \"%s\" not found, skipping: %s" +#~ msgstr "SSL feshedilmiÅŸ sertifika dosyası \"%s\" bulunmadı, atlanıyor: %s" + +#~ msgid "Certificates will not be checked against revocation list." +#~ msgstr "Sertifikalar, feshedilmiÅŸ sertifika listeleri ile karşılaÅŸtırmayacaktır." + +#, fuzzy +#~ msgid "Make sure the root.crt file is present and readable." +#~ msgstr "kök sertifikasının mevcut ve okunabilir olduÄŸundan emin olun" + +#~ msgid "could not create %s socket: %m" +#~ msgstr "%s: socket oluÅŸturma hatası: %m" + +#~ msgid "could not bind %s socket: %m" +#~ msgstr "%s socket bind hatası: %m" + +#, fuzzy +#~ msgid "could not set socket to blocking mode: %m" +#~ msgstr "soket engelleme moduna ayarlanamadı: %s\n" + +#~ msgid "INSERT ... SELECT cannot specify INTO" +#~ msgstr "INSERT ... SELECT ifadesinde INTO öğesi kullanılamaz" + +#~ msgid "VALUES must not contain OLD or NEW references" +#~ msgstr "VALUES kısmında OLD veya NEW baÅŸvurular bulunmamalıdır" + +#~ msgid "Use SELECT ... UNION ALL ... instead." +#~ msgstr "Onun yerine SELECT ... UNION ALL ... kullanın" + +#~ msgid "cannot use aggregate function in VALUES" +#~ msgstr "VALUES kısmında aggregate fonksiyonları kullanılamaz" + +#~ msgid "cannot use window function in VALUES" +#~ msgstr "VALUES iÅŸleminde window fonksiyonu kullanılamaz" + +#~ msgid "DEFAULT can only appear in a VALUES list within INSERT" +#~ msgstr "DEFAUL sadece INSERT içinde yer alan VALUES listesinde yer alabilir" + +#~ msgid "CREATE TABLE AS specifies too many column names" +#~ msgstr "CREATE TABLE AS iÅŸleminde belirtilen sütun sayısı çok fazla" + +#~ msgid "cannot use aggregate function in UPDATE" +#~ msgstr "UPDATE parametresinde aggregate fonksiyon kullanılamaz" + +#~ msgid "cannot use window function in UPDATE" +#~ msgstr "UPDATE iÅŸleminde window fonksiyonu kullanılamaz" + +#~ msgid "cannot use aggregate function in RETURNING" +#~ msgstr "RETURNING parametresinde aggregate fonksiyon kullanılamaz" + +#, fuzzy +#~ msgid "cannot use window function in RETURNING" +#~ msgstr "RETURNING parametresinde aggregate fonksiyon kullanılamaz" + +#~ msgid "RETURNING cannot contain references to other relations" +#~ msgstr "RETURNING, baÅŸka nesnelere baÅŸvuru içeremez" + +#~ msgid "DECLARE CURSOR cannot specify INTO" +#~ msgstr "DECLARE CURSOR tanımında INTO kullanılamaz" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with GROUP BY clause" +#~ msgstr "SELECT FOR UPDATE/SHARE ifadesinde GROUP BY kullanılamaz" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with HAVING clause" +#~ msgstr "SELECT FOR UPDATE/SHARE ifadesinde HAVING kullanılamaz" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with aggregate functions" +#~ msgstr "aggregate fonskiyonlarinda SELECT FOR UPDATE/SHARE kullanılamaz" + +#, fuzzy +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed with window functions" +#~ msgstr "aggregate fonskiyonlarinda SELECT FOR UPDATE/SHARE kullanılamaz" + +#~ msgid "aggregates not allowed in WHERE clause" +#~ msgstr "WHERE ifadesinde aggregate kullanılamaz" + +#~ msgid "window functions not allowed in GROUP BY clause" +#~ msgstr "GROUP BY ifadesinde window fonksiyonları kullanılamaz" + +#~ msgid "JOIN/ON clause refers to \"%s\", which is not part of JOIN" +#~ msgstr "JOIN/ON ifadesi, JOIN parçası olmayan \"%s\" öğesine referans etmektedir" + +#~ msgid "subquery in FROM cannot have SELECT INTO" +#~ msgstr "FROM ifadesindeki subquery içerisinde SELECT INTO kullanılamaz" + +#~ msgid "subquery in FROM cannot refer to other relations of same query level" +#~ msgstr "FROM öğesinde subquery ifadesi aynı seviyedeki diÄŸer tabloya eriÅŸemez" + +#~ msgid "function expression in FROM cannot refer to other relations of same query level" +#~ msgstr "FROM öğesinde fonksiyon ifadesi aynı seviyedeki diÄŸer tabloya eriÅŸemez" + +#, fuzzy +#~ msgid "cannot use window function in function expression in FROM" +#~ msgstr "FROM ifadesinin fonksiyon ifadesinde aggregate fonksiyonu kullanılamaz" + +#, fuzzy +#~ msgid "argument of %s must not contain aggregate functions" +#~ msgstr "%s ifadesinin argüanı aggregate bulundurmamalıdır" + +#, fuzzy +#~ msgid "argument of %s must not contain window functions" +#~ msgstr "%s ifadesinin argüanı deÄŸiÅŸlen bulundurmamalıdır" + +#, fuzzy +#~ msgid "cannot override frame clause of window \"%s\"" +#~ msgstr "\"%s\" sistem sütununun adı deÄŸiÅŸtirilemez" + +#~ msgid "argument of %s must be type boolean, not type %s" +#~ msgstr "%s'ın argümanları %s deÄŸil, boolean tipinde olamalıdır" + +#, fuzzy +#~ msgid "subquery in WITH cannot have SELECT INTO" +#~ msgstr "FROM ifadesindeki subquery içerisinde SELECT INTO kullanılamaz" + +#~ msgid "arguments of row IN must all be row expressions" +#~ msgstr "IN satırında argümanlar birer satır ifadesi olmalıdır" + +#~ msgid "subquery must return a column" +#~ msgstr "subquery, sütün döndürmeli" + +#, fuzzy +#~ msgid "window functions cannot use named arguments" +#~ msgstr "SQL fonksiyonları %s tipini dündüremezler" + +#~ msgid "index expression cannot return a set" +#~ msgstr "index ifadesi set tipi döndüremez" + +#~ msgid "cannot use aggregate function in rule WHERE condition" +#~ msgstr "WHERE ÅŸart ifadelerinde aggregate function kullanılamaz" + +#, fuzzy +#~ msgid "cannot use window function in rule WHERE condition" +#~ msgstr "WHERE ÅŸart ifadelerinde aggregate function kullanılamaz" + +#, fuzzy +#~ msgid "interval precision specified twice" +#~ msgstr "interval(%d) kesinliÄŸi %d ile %d arasında olmalıdır" + +#~ msgid "CREATE TABLE AS cannot specify INTO" +#~ msgstr "CREATE TABLE AS iÅŸleminde INTO kullanılamaz" + +#~ msgid "column name list not allowed in CREATE TABLE / AS EXECUTE" +#~ msgstr "CREATE TABLE / AS EXECUTE iÅŸleminde sütun isim listesi verilmez" + +#~ msgid "could not open process token: error code %d\n" +#~ msgstr "open process token açma baÅŸarısız: hata kodu %d\n" + +#~ msgid "" +#~ "This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently %lu bytes), reduce PostgreSQL's shared_buffers parameter (currently %d) and/or its max_connections parameter (currently %d).\n" +#~ "If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter, in which case raising the request size or reconfiguring SHMMIN is called for.\n" +#~ "The PostgreSQL documentation contains more information about shared memory configuration." +#~ msgstr "" +#~ "Bu hata, PostgreSQL'in shared memory isteÄŸinin çekirdeÄŸin SHMMAX parametresinde verilen deÄŸerinin aşıldığını gösteriyor. İstenilen bellek boyutunu düşürebilir ya da çekirdeÄŸi daha büyük bir SHMMAX parametresi ile yeniden yapılandırabilirsiniz. İstenilen bellek boyutunu (ÅŸu an %lu bayt) düşürmek için PostgreSQL'in shared_buffers parametresini (ÅŸu an %d) ve/veya max_connections (ÅŸu an " +#~ "%d) parametrelerini düşürebilirsiniz.\n" +#~ " EÄŸer istenilen bellek boyutu zaten küçük ise, çekirdeÄŸin SHMMIN parametresinden düşük olabilir; bu durumda istenilen bellek boyutunu SHMMIN deÄŸerine kadar büyütmeniz ya da SHMMIN deÄŸerini düşürmeniz gerekli.PostgreSQL belgelerinde shared memory yapılandırılması hakkında daha fazla bilgi bulabilirsiniz." + +#, fuzzy +#~ msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" +#~ msgstr "autovacuum: \"%s\" veritabanı iÅŸleniyor" + +#~ msgid "transaction log switch forced (archive_timeout=%d)" +#~ msgstr "transaction log switch forced (archive_timeout=%d)" + +#~ msgid "transaction log file \"%s\" could not be archived: too many failures" +#~ msgstr "transaction log dosyası \"%s\" arÅŸivlenemedi: çok fazla baÅŸarısız iÅŸlem" + +#~ msgid "archived transaction log file \"%s\"" +#~ msgstr "arÅŸivlenen transaction kayıt dosyası \"%s\"" + +#~ msgid "must be superuser to reset statistics counters" +#~ msgstr "istatistik sayaçlarını sadece veritabanı superuserı sıfırlayabilir" + +#~ msgid "poll() failed in statistics collector: %m" +#~ msgstr "istatistik toplayıcı sürecinde poll() hatası: %m" + +#~ msgid "WAL archival (archive_mode=on) requires wal_level \"archive\" or \"hot_standby\"" +#~ msgstr "WAL arÅŸivlemesi (archive_mode=on) wal_level parametresinin deÄŸerinin \"archive\" ya da \"hot_standby\" olmasını gerektirir" + +#, fuzzy +#~ msgid "%s: could not open log file \"%s/%s\": %s\n" +#~ msgstr "%s: \"%s\" kayıti dosyası açılamıyor: %s\n" + +#~ msgid "%s: could not fork background process: %s\n" +#~ msgstr "%s: artalan süreci baÅŸlatma hatası: %s\n" + +#~ msgid "%s: could not dissociate from controlling TTY: %s\n" +#~ msgstr "%s: control TTY ile baÄŸlantı kesilemiyor: %s\n" + +#~ msgid "select() failed in logger process: %m" +#~ msgstr "logger süreci içerisinde select() hatası: %m" + +#~ msgid "could not create log file \"%s\": %m" +#~ msgstr "\"%s\" günlük dosyası oluÅŸturma hatası: %m" + +#~ msgid "You need an unconditional ON INSERT DO INSTEAD rule." +#~ msgstr "ON INSERT DO INSTEAD rule gerekmektedir." + +#~ msgid "You need an unconditional ON DELETE DO INSTEAD rule." +#~ msgstr "ON DELETE DO INSTEAD rule gerekmektedir." + +#~ msgid "large object %u was not opened for writing" +#~ msgstr "large object %u yazmak için açılamadı" + +#~ msgid "large object %u was already dropped" +#~ msgstr "%u large objecti zaten kaldırıldı" + +#~ msgid "Not enough memory for reassigning the prepared transaction's locks." +#~ msgstr "Hazırlanmış transaction'un lock'ları yeniden atanması için yeterli bellek yok." + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" + +#~ msgid "mapped win32 error code %lu to %d" +#~ msgstr "%lu win32 hata kodu %d koduna adreslendi" + +#~ msgid "unrecognized win32 error code: %lu" +#~ msgstr "bilinmeyen win32 hata kodu: %lu" + +#~ msgid "unsupported PAM conversation %d/%s" +#~ msgstr "desteklenmeyen PAM iletiÅŸimi %d/%s" + +#, fuzzy +#~ msgid "usermap \"%s\"" +#~ msgstr " \"%s\" kullanıcısı" + +#~ msgid "binary value is out of range for type bigint" +#~ msgstr "bigint tipi için deÄŸer kapsam dışındadır" + +#~ msgid "WAL file SYSID is %s, pg_control SYSID is %s" +#~ msgstr "WAL dosyası SYSID %s, pg_control SYSID %s" + +#, fuzzy +#~ msgid "parameter \"recovery_target_inclusive\" requires a Boolean value" +#~ msgstr "\"%s\" seçeneÄŸi boolean deÄŸerini alır" + +#~ msgid "WAL archiving is not active" +#~ msgstr "WAL arÅŸivleme etkin deÄŸil" + +#~ msgid "archive_mode must be enabled at server start." +#~ msgstr "archive_mode sunucu baÅŸlatıldığında etkinleÅŸtirilmedir." + +#~ msgid "archive_command must be defined before online backups can be made safely." +#~ msgstr "online yedekleme güvenilir bir biçimde çalışması için, önce archive_command tanımlayın." + +#~ msgid "index row size %lu exceeds btree maximum, %lu" +#~ msgstr "%lu index satır boyutu, btree indexi için %lu olan en büyük satır büyüklüğünü aÅŸmaktadır" + +#~ msgid "This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by \"client_encoding\"." +#~ msgstr "Bu hata ayrıca bayt sırasının sunucunun beklediÄŸi kodlamada olmadığı zaman meydana gelmektedir. İstemci dil kodlaması \"client_encoding\" seçeneÄŸi ile ayarlanmaktadır." + +#~ msgid "Table contains duplicated values." +#~ msgstr "Tabloda mukerrer deÄŸerler mevcut." + +#~ msgid "Automatically adds missing table references to FROM clauses." +#~ msgstr "FROM tümcesine eksik tabloları ekliyor." + +#~ msgid "Sets the regular expression \"flavor\"." +#~ msgstr "\"flavor\" regular expression belirtiyor." + +#, fuzzy +#~ msgid "attempted change of parameter \"%s\" ignored" +#~ msgstr "\"%s\" parametresinin yeniden tanımlanma denemesi" + +#, fuzzy +#~ msgid "This parameter cannot be changed after server start." +#~ msgstr "\"%s\" parametresi, sunucu baÅŸlatıldıktan sonra deÄŸiÅŸtirilemez" + +#~ msgid "invalid database name \"%s\"" +#~ msgstr "geçersiz veritabanı adı \"%s\"" + +#~ msgid "invalid role name \"%s\"" +#~ msgstr "geçirsiz rol adı \"%s\"" + +#~ msgid "invalid role password \"%s\"" +#~ msgstr "geçersiz rol ÅŸifresi \"%s\"" + +#~ msgid "connection limit exceeded for non-superusers" +#~ msgstr "superuser olmayan kullanıcı baÄŸlantı sayısı sınırı aşıldı" + +#~ msgid "Not safe to send CSV data\n" +#~ msgstr "CSV verisini göndermek güvenli deÄŸil\n" + +#~ msgid "transaction is read-only" +#~ msgstr "transaction salt okunurdur" + +#~ msgid "shared index \"%s\" can only be reindexed in stand-alone mode" +#~ msgstr "\"%s\" shared indexe sadece stand-alone modunda reindex iÅŸlemi uygulanabilir" + +#~ msgid "cannot specify CSV in BINARY mode" +#~ msgstr "BINARY biçiminde CSV belirtilemez" + +#~ msgid "shared table \"%s\" can only be reindexed in stand-alone mode" +#~ msgstr "\"%s\" ortak tablosuna sadece stand-alone modunda reindex iÅŸlemi uygulanabilir" + +#~ msgid "cannot truncate system relation \"%s\"" +#~ msgstr "sistem tablosu \"%s\" truncate edilemez" + +#~ msgid "directory \"%s\" is not empty" +#~ msgstr "\"%s\"dizini boÅŸ deÄŸildir" + +#, fuzzy +#~ msgid "relation \"%s\" TID %u/%u: XMIN_COMMITTED not set for transaction %u --- cannot shrink relation" +#~ msgstr "\"%s\" tablosu TID %u/%u: InsertTransactionInProgress %u --- nesne küçültülemiyor" + +#, fuzzy +#~ msgid "relation \"%s\" TID %u/%u: dead HOT-updated tuple --- cannot shrink relation" +#~ msgstr "\"%s\" tablosu TID %u/%u: InsertTransactionInProgress %u --- nesne küçültülemiyor" + +#~ msgid "relation \"%s\" TID %u/%u: InsertTransactionInProgress %u --- cannot shrink relation" +#~ msgstr "\"%s\" tablosu TID %u/%u: InsertTransactionInProgress %u --- nesne küçültülemiyor" + +#~ msgid "relation \"%s\" TID %u/%u: DeleteTransactionInProgress %u --- cannot shrink relation" +#~ msgstr "\"%s\" tablosu TID %u/%u: DeleteTransactionInProgress %u --- nesne küçültülemiyor" + +#~ msgid "" +#~ "%.0f dead row versions cannot be removed yet.\n" +#~ "Nonremovable row versions range from %lu to %lu bytes long.\n" +#~ "There were %.0f unused item pointers.\n" +#~ "Total free space (including removable row versions) is %.0f bytes.\n" +#~ "%u pages are or will become empty, including %u at the end of the table.\n" +#~ "%u pages containing %.0f free bytes are potential move destinations.\n" +#~ "%s." +#~ msgstr "" +#~ "%.0f ölü satır şımdilik kaldırılamıyor.\n" +#~ "Kaldırılamayacak satır sürümleri %lu ile %lu bayt uzunukta.\n" +#~ "%.0f öğe göstergesi kullanılmadı.\n" +#~ "Topleam boÅŸ alan (kaldırılacak satır sürümleri dahil) %.0f bayttır.\n" +#~ "%u sayfa boÅŸ ya da boÅŸaltılacak, tablonun sonunda %u tane buna dahildir.\n" +#~ "%u sayfa toplam %.0f boÅŸ bayt içeriÄŸi ile potansiyel taşıma hedefidir.\n" +#~ "%s." + +#~ msgid "\"%s\": moved %u row versions, truncated %u to %u pages" +#~ msgstr "\"%s\": %u satır sürümü taşınmış, %u sayfa sayısından %u sayfaya düşürülmüştür" + +#~ msgid "" +#~ "%u index pages have been deleted, %u are currently reusable.\n" +#~ "%s." +#~ msgstr "" +#~ "%u index sayfası silinmiÅŸ, %u kullanılabilir.\n" +#~ "%s." + +#~ msgid "index \"%s\" contains %.0f row versions, but table contains %.0f row versions" +#~ msgstr "\"%s\" indexi %.0f satır sürümü içeriyor, ancak tablo %.0f satır sürümü içeriyor" + +#~ msgid "Rebuild the index with REINDEX." +#~ msgstr "REINDEX iÅŸlemiyle index yeniden oluÅŸturuluyor." + +#~ msgid "cannot set session authorization within security-definer function" +#~ msgstr "security-definer fonksiyonlarında oturum yetkilendirilmesi yapılamıyor." + +#, fuzzy +#~ msgid "SELECT FOR UPDATE/SHARE is not supported within a query with multiple result relations" +#~ msgstr "inheritance sorgulamalar için SELECT FOR UPDATE/SHARE desteklenmemektedir" + +#, fuzzy +#~ msgid "could not remove relation %s: %m" +#~ msgstr "nesne %u/%u/%u kaldırma hatası: %m" + +#, fuzzy +#~ msgid "could not remove segment %u of relation %s: %m" +#~ msgstr "segment %u, nesne %u/%u/%u kaldırılamıyor: %m" + +#, fuzzy +#~ msgid "could not seek to block %u of relation %s: %m" +#~ msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloÄŸuna arama hatası: %5$m" + +#, fuzzy +#~ msgid "could not extend relation %s: %m" +#~ msgstr "nesne %u/%u/%u geniÅŸletme hatası: %m" + +#, fuzzy +#~ msgid "could not read block %u of relation %s: %m" +#~ msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloku okunamıyor: %5$m" + +#, fuzzy +#~ msgid "could not write block %u of relation %s: %m" +#~ msgstr "%2$u/%3$u/%4$u nesnesinin %1$u bloku yazılamıyor: %5$m" + +#, fuzzy +#~ msgid "could not open segment %u of relation %s: %m" +#~ msgstr "segment %u, nesne %u/%u/%u açma yapılamıyor: %m" + +#, fuzzy +#~ msgid "could not fsync segment %u of relation %s: %m" +#~ msgstr "log dosyası segment %u, nesne %u/%u/%u fsync yapılamıyor: %m" + +#, fuzzy +#~ msgid "could not fsync segment %u of relation %s but retrying: %m" +#~ msgstr "segment %u, nesne %u/%u/%u fsync yapılamıyor: %m" + +#, fuzzy +#~ msgid "could not seek to end of segment %u of relation %s: %m" +#~ msgstr "segment %u, nesne %u/%u/%u arama yapılamıyor: %m" + +#~ msgid "SELECT FOR UPDATE/SHARE is not allowed in subqueries" +#~ msgstr "subquery sorgusunda SELECT FOR UPDATE/SHARE kullanılamaz" + +#~ msgid "adding missing FROM-clause entry for table \"%s\"" +#~ msgstr "\"%s\" tablo öğesinde eksik FROM öğesi ekleniyor" + +#, fuzzy +#~ msgid "frame start at CURRENT ROW is not implemented" +#~ msgstr "view üzerinde WHERE CURRENT OF implement edilmemiÅŸtir" + +#~ msgid "OLD used in query that is not in a rule" +#~ msgstr "rule olmayan sorgusunda OLD kullanıldı" + +#~ msgid "NEW used in query that is not in a rule" +#~ msgstr "rule olmayan sorgusunda NEW kullanıldı" + +#~ msgid "not enough shared memory for background writer" +#~ msgstr "arka planı writer için shared memory yeterli deÄŸildir" + +#, fuzzy +#~ msgid "database system is in consistent recovery mode" +#~ msgstr "veritabanı kurtarma modundadır" + +#~ msgid "multiple DELETE events specified" +#~ msgstr "birden fazla DELETE olayı belirtilmiÅŸtir" + +#~ msgid "multiple UPDATE events specified" +#~ msgstr "birden fazla UPDATE olayı belirtilmiÅŸtir" + +#, fuzzy +#~ msgid "multiple TRUNCATE events specified" +#~ msgstr "birden fazla UPDATE olayı belirtilmiÅŸtir" + +#~ msgid "could not create XPath object" +#~ msgstr "XPath nesnesi oluÅŸturulamadı" + +#~ msgid "fillfactor=%d is out of range (should be between %d and 100)" +#~ msgstr "fillfactor=%d kapsam dışıdır (%d ile 100 arasında olmalıdır)" + +#~ msgid "GIN index does not support search with void query" +#~ msgstr "GIN dizini boÅŸ bir sorguyla aramayı desteklemiyor" + +#~ msgid "invalid LC_CTYPE setting" +#~ msgstr "geçersiz LC_TYPE ayarı" + +#~ msgid "The database cluster was initialized with LOCALE_NAME_BUFLEN %d, but the server was compiled with LOCALE_NAME_BUFLEN %d." +#~ msgstr "Veritabanı clusteri LOCALE_NAME_BUFLEN %d ile ilklendirilmiÅŸtir, ancak sunucu LOCALE_NAME_BUFLEN %d ile derlenmiÅŸtir." + +#~ msgid "It looks like you need to initdb or install locale support." +#~ msgstr "Yerel desteÄŸini kurmanız ya da initdb çalıştırmanız gerekmektedir." + +#~ msgid "log_restartpoints = %s" +#~ msgstr "log_restartpoints = %s" + +#~ msgid "syntax error: cannot back up" +#~ msgstr "sözdizimi hatası: geri diilemiyor" + +#~ msgid "syntax error; also virtual memory exhausted" +#~ msgstr "sözdizimi hatası; ayrıca sanal bellek de dolmuÅŸtur" + +#~ msgid "parser stack overflow" +#~ msgstr "parser stack overflow" + +#~ msgid "failed to drop all objects depending on %s" +#~ msgstr "%s nesnesine baÄŸlı nesnelerinin kaldırma iÅŸlemi baÅŸarısız oldu" + +#~ msgid "there are objects dependent on %s" +#~ msgstr "%s nesnesine baÄŸlı nesneler var." + +#~ msgid "could not remove database directory \"%s\"" +#~ msgstr "\"%s\" veritabanı dizini kaldırılamıyor" + +#~ msgid "multiple constraints named \"%s\" were dropped" +#~ msgstr "\"%s\" adlı birden fazla constraint drop edilmiÅŸ" + +#~ msgid "constraint definition for check constraint \"%s\" does not match" +#~ msgstr "check kısıtlamasının \"%s\" kısıtlama tanımı uyuÅŸmamaktadır" + +#~ msgid "relation \"%s.%s\" contains more than \"max_fsm_pages\" pages with useful free space" +#~ msgstr "\"%s.%s\" nesnesi \"max_fsm_pages\" paramteresinde belirtilmiÅŸ sayısının üzerinde kullanılabilecek boÅŸ alan içeriyor" + +#~ msgid "cannot change number of columns in view" +#~ msgstr "view içerisinde sütun sayısı deÄŸiÅŸtirilemez" + +#~ msgid "unexpected Kerberos user name received from client (received \"%s\", expected \"%s\")" +#~ msgstr "İstemciden beklenmeyen Kerberos kullanıcı adı alınmış (alınan \"%s\", beklenen \"%s\")" + +#~ msgid "Kerberos 5 not implemented on this server" +#~ msgstr "Kerberos 5 bu sunucuda desteklenmemektedir" + +#~ msgid "GSSAPI not implemented on this server" +#~ msgstr "GSSAPI bu sunucuda desteklenmemektedir" + +#, fuzzy +#~ msgid "could not acquire SSPI credentials handle" +#~ msgstr "karşı tarafın kimlik bilgileri alınamadı: %m" + +#, fuzzy +#~ msgid "could not get security token from context" +#~ msgstr "SSL context oluÅŸturma hatası: %s" + +#~ msgid "unsafe permissions on private key file \"%s\"" +#~ msgstr "private key dosyası \"%s\" sakıncalı eriÅŸim haklarına sahip" + +#~ msgid "File must be owned by the database user and must have no permissions for \"group\" or \"other\"." +#~ msgstr "Dosya, veritabanı sahibi kullanıcısına ait olmalı ve \"group\" ya da \"other\" kullanıcılarına eriÅŸim hakları verilmemelidir." + +#~ msgid "cannot use authentication method \"crypt\" because password is MD5-encrypted" +#~ msgstr "ÅŸifreler MD5 algoritması ile ÅŸifrelenmiÅŸ olduÄŸu için \"crypt\" kimlik doÄŸrulama yöntemi kullanılamıyor" + +#~ msgid "invalid entry in file \"%s\" at line %d, token \"%s\"" +#~ msgstr "\"%s\" dosyasında %d satırında, \"%s\" simgesinde geçersiz giriÅŸ" + +#~ msgid "missing field in file \"%s\" at end of line %d" +#~ msgstr "\"%s\" dosyasında %d satırın sonunda eksik alan" + +#~ msgid "cannot use Ident authentication without usermap field" +#~ msgstr "usermap fiels olmadan Ident kimlik doÄŸrulaması kullanılamıyor" + +#~ msgid "Ident protocol identifies remote user as \"%s\"" +#~ msgstr "Ident protokolü uzak kullanıcısını \"%s\" olarak tanıtıyor" + +#~ msgid "missing FROM-clause entry in subquery for table \"%s\"" +#~ msgstr "\"%s\" tablosu için subquery tanımında FROM öğesi eksik" + +#~ msgid "adding missing FROM-clause entry in subquery for table \"%s\"" +#~ msgstr "\"%s\" tablosu için subquery tanımında eksik FROM öğesi ekleniyor" + +#~ msgid "could not set statistics collector timer: %m" +#~ msgstr "statistics collector zamanlayıcısı ayarlama hatası: %m" + +#~ msgid "insufficient shared memory for free space map" +#~ msgstr "free space map için yetersiz shared memory" + +#~ msgid "max_fsm_pages must exceed max_fsm_relations * %d" +#~ msgstr "max_fsm_pages deÄŸeri, max_fsm_relations * %d deÄŸerinden büyük olmalıdır" + +#~ msgid "free space map contains %d pages in %d relations" +#~ msgstr "free space map %2$d nesnede %1$d sayfa içermektedir" + +#~ msgid "" +#~ "A total of %.0f page slots are in use (including overhead).\n" +#~ "%.0f page slots are required to track all free space.\n" +#~ "Current limits are: %d page slots, %d relations, using %.0f kB." +#~ msgstr "" +#~ "Toplam %.0f sayfa slotu kullanılmıştır (overhead dahildir).\n" +#~ "BoÅŸ alanı takip etmek için %.0f sayfa slotuna ihtiyaç duyulmaktadır.\n" +#~ "Åžu anki kimitleri: %d sayfa slotu, %d nesne, toplam: %.0f kB." + +#~ msgid "max_fsm_relations(%d) equals the number of relations checked" +#~ msgstr "max_fsm_relations(%d) equals the number of relations checked" + +#~ msgid "You have at least %d relations. Consider increasing the configuration parameter \"max_fsm_relations\"." +#~ msgstr "Nesne sayısı: %d. \"max_fsm_relations\" yapılandırma parametresini arttırmaya deneyebilirsiniz." + +#~ msgid "number of page slots needed (%.0f) exceeds max_fsm_pages (%d)" +#~ msgstr "ihtiyaç duyulan page slot sayısı (%.0f), max_fsm_pages (%d) parametresini aÅŸmaktadır" + +#~ msgid "Consider increasing the configuration parameter \"max_fsm_pages\" to a value over %.0f." +#~ msgstr "\"max_fsm_pages\" yapılandırma parametresini %.0f deÄŸerine kadar yükseltmeyi deneyebilirsiniz." + +#, fuzzy +#~ msgid "could not fsync relation %u/%u/%u: %m" +#~ msgstr "nesne %u/%u/%u açma hatası: %m" + +#~ msgid "unexpected delimiter at line %d of thesaurus file \"%s\"" +#~ msgstr "\"%2$s\" thesaurus dosyasında %1$d satırında beklenmeyen sınırlayıcı." + +#~ msgid "unexpected end of line or lexeme at line %d of thesaurus file \"%s\"" +#~ msgstr "%d numaralı satırda, \"%s\" sözlük dosyasında, beklenmeyen satır sonu ya da sözcükbirim" + +#, fuzzy +#~ msgid "unexpected end of line at line %d of thesaurus file \"%s\"" +#~ msgstr "\"%2$s\" nesnesinin %1$u bloÄŸunda dosya sonundan sonra beklenmeyen veri" + +#~ msgid "not unique \"S\"" +#~ msgstr "\"S\" tek deÄŸildir" + +#~ msgid "\"TZ\"/\"tz\" not supported" +#~ msgstr "\"TZ\"/\"tz\" desteklenmiyor" + +#~ msgid "January" +#~ msgstr "Ocak" + +#~ msgid "February" +#~ msgstr "Åžubat" + +#~ msgid "March" +#~ msgstr "Mart" + +#~ msgid "April" +#~ msgstr "Nisan" + +#~ msgid "May" +#~ msgstr "Mayıs" + +#~ msgid "June" +#~ msgstr "Haziran" + +#~ msgid "July" +#~ msgstr "Temmuz" + +#~ msgid "August" +#~ msgstr "AÄŸustos" + +#~ msgid "September" +#~ msgstr "Eylül" + +#~ msgid "October" +#~ msgstr "Ekim" + +#~ msgid "November" +#~ msgstr "Kasım" + +#~ msgid "December" +#~ msgstr "Aralık" + +#~ msgid "Jan" +#~ msgstr "Oca" + +#~ msgid "Feb" +#~ msgstr "Åžub" + +#~ msgid "Mar" +#~ msgstr "Mar" + +#~ msgid "Apr" +#~ msgstr "Nis" + +#~ msgid "S:May" +#~ msgstr "S:May" + +#~ msgid "Jun" +#~ msgstr "Haz" + +#~ msgid "Jul" +#~ msgstr "Tem" + +#~ msgid "Aug" +#~ msgstr "AuÄŸ" + +#~ msgid "Sep" +#~ msgstr "Eyl" + +#~ msgid "Oct" +#~ msgstr "Eki" + +#~ msgid "Nov" +#~ msgstr "Kas" + +#~ msgid "Dec" +#~ msgstr "Ara" + +#~ msgid "Sunday" +#~ msgstr "Pazar" + +#~ msgid "Monday" +#~ msgstr "Pazartesi" + +#~ msgid "Tuesday" +#~ msgstr "Salı" + +#~ msgid "Wednesday" +#~ msgstr "ÇarÅŸamba" + +#~ msgid "Thursday" +#~ msgstr "PerÅŸembe" + +#~ msgid "Friday" +#~ msgstr "Cuma" + +#~ msgid "Saturday" +#~ msgstr "Cumartesi" + +#~ msgid "Sun" +#~ msgstr "Pz" + +#~ msgid "Mon" +#~ msgstr "Pzt" + +#~ msgid "Tue" +#~ msgstr "Sal" + +#~ msgid "Wed" +#~ msgstr "Çar" + +#~ msgid "Thu" +#~ msgstr "PrÅŸ" + +#~ msgid "Fri" +#~ msgstr "Cum" + +#~ msgid "Sat" +#~ msgstr "Cmt" + +#~ msgid "AM/PM hour must be between 1 and 12" +#~ msgstr "AM/PM saati 1 ile 12 arasında olmalıdır" + +#~ msgid "UTF-16 to UTF-8 translation failed: %lu" +#~ msgstr "UTF-16'dan UTF-8'e dönüştürme hatası: %lu" + +#~ msgid "cannot calculate week number without year information" +#~ msgstr "yıl bilgisi olmadan haftanın günü hesaplanamaz" + +#~ msgid "query requires full scan, which is not supported by GIN indexes" +#~ msgstr "sorgu tam tarama gerektiriyor; ancak GIN indexler bunu desteklemez" + +#~ msgid "@@ operator does not support lexeme weight restrictions in GIN index searches" +#~ msgstr "@@ operatörü GIN index aramalarında sözcükbirim ağırlık kısıtlamalarını desteklemez" + +#~ msgid "Prints the parse tree to the server log." +#~ msgstr "Ayrıştırma aÄŸacını sunucu günlüğüne yazıyor." + +#~ msgid "Prints the parse tree after rewriting to server log." +#~ msgstr "Ayrıştırma aÄŸacını rewrite ilmeinden sonra sunucu günlüğüne yazıyor." + +#~ msgid "Prints the execution plan to server log." +#~ msgstr "Yürütme planını sunucu günlüğüne yazıyor." + +#~ msgid "Uses the indented output format for EXPLAIN VERBOSE." +#~ msgstr "EXPLAIN VERBOSE için girintili çıktı biçimini kullanıyor." + +#~ msgid "Sets the maximum number of tables and indexes for which free space is tracked." +#~ msgstr "BoÅŸ alanı takibi yapılacak tabloların en büyük sayısı." + +#~ msgid "Sets the maximum number of disk pages for which free space is tracked." +#~ msgstr "BoÅŸ alanı takibi yapılacak disk sayfaların en büyük sayısı." + +#~ msgid "Valid values are ON, OFF, and SAFE_ENCODING." +#~ msgstr "Geçerli deÄŸerler: ON, OFF ve SAFE_ENCODING." + +#~ msgid "Each SQL transaction has an isolation level, which can be either \"read uncommitted\", \"read committed\", \"repeatable read\", or \"serializable\"." +#~ msgstr "Her SQL transaction bir isolation level'e sahiptir, geçerli deÄŸerler: \"read uncommitted\", \"read committed\", \"repeatable read\", \"serializable\"." + +#, fuzzy +#~ msgid "Each session can be either \"origin\", \"replica\", or \"local\"." +#~ msgstr "Bir oturum \"origin\", \"replica\" veya \"local\" olabilir." + +#, fuzzy +#~ msgid "Sets realm to match Kerberos and GSSAPI users against." +#~ msgstr "Kerberos sevice adını belirtiyor." + +#~ msgid "Sets the hostname of the Kerberos server." +#~ msgstr "Kerberos sunucusunun bilgisayar adını belirtiyor." + +#~ msgid "This can be set to advanced, extended, or basic." +#~ msgstr "Bu deÄŸer ÅŸunlardan biri olabilir: advanced, extended, or basic." + +#~ msgid "Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7." +#~ msgstr "Geçerli deÄŸerler: LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7." + +#~ msgid "Valid values are BASE64 and HEX." +#~ msgstr "Geçerli deÄŸerler: BASE64 ve HEX." + +#~ msgid "Valid values are DOCUMENT and CONTENT." +#~ msgstr "Geçerli deÄŸerler: DOCUMENT ve CONTENT." + +#~ msgid "Valid values are DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Each level includes all the levels that follow it." +#~ msgstr "Geçerli deÄŸerler: DEBUG5, DEBUG4, DEBUG3, DEBUG2, DEBUG1, INFO, NOTICE, WARNING, ERROR, LOG, FATAL, and PANIC. Her düzey kendisinden daha büyük düzeyleri de kapsıyor." + +#~ msgid "All SQL statements that cause an error of the specified level or a higher level are logged." +#~ msgstr "Belirtilen ya da daha üst düzeyde hata yaratan SQL sorguları loglanacaktır." + +#, fuzzy +#~ msgid "invalid value for parameter \"%s\": \"%d\"" +#~ msgstr "\"%s\" seçeneÄŸi için geçersiz deÄŸer: \"%s\"" + +#~ msgid "%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n" +#~ msgstr "%s: buffer sayısı (-B), izin verilen baÄŸlantı sayısından (-N) en az iki kat daha büyük ve 16'dan daha küçük olmamalıdır\n" + +#, fuzzy +#~ msgid "invalid regis pattern: \"%s\"" +#~ msgstr "geçirsiz rol adı \"%s\"" + +#, fuzzy +#~ msgid "Sets the maximum number of tuples to be sorted using replacement selection." +#~ msgstr "Her oturumun kullanabileceÄŸi en yüksek geçici buffer sayısı" + +#~ msgid "must be superuser to get directory listings" +#~ msgstr "dizindeki dosya listesini görmek için superuser olmalısınız" + +#~ msgid "must be superuser to get file information" +#~ msgstr "dosya bilgisini almak için superuser olmalısınız" + +#~ msgid "could not open tablespace directory \"%s\": %m" +#~ msgstr "\"%s\" tablespace dizini açılamıyor: %m" + +#~ msgid "data type \"%s.%s\" required for logical replication does not exist" +#~ msgstr "\"mantıksal replikasyon için gereken \"%s.%s\" veri tipi mevcut deÄŸil" + +#~ msgid "built-in type %u not found" +#~ msgstr "%u dahili tipi bulunamadı" + +#~ msgid "worker process" +#~ msgstr "worker süreci" + +#~ msgid "data directory \"%s\" has group or world access" +#~ msgstr "veritabanı dizini \"%s\" gruba ve herkese eriÅŸime açıktır" + +#~ msgid "%s: max_wal_senders must be less than max_connections\n" +#~ msgstr "%s: max.wal.senders parametresi, max_connections parametresinden küçük olmalıdır\n" + +#~ msgid "could not open archive status directory \"%s\": %m" +#~ msgstr "arÅŸiv durum dizini \"%s\" açılamıyor: %m" + +#~ msgid "foreign key constraints are not supported on partitioned tables" +#~ msgstr "bölümlenmiÅŸ (partitioned) tablolarda primary key kısıtlamaları (constraint) desteklenmiyor" + +#~ msgid "primary key constraints are not supported on partitioned tables" +#~ msgstr "bölümlenmiÅŸ (partitioned) tablolarda primary key kısıtlamaları (constraint) desteklenmiyor" + +#~ msgid "ON CONFLICT clause is not supported with partitioned tables" +#~ msgstr "ON CONFLICT ibaresi bölümlenmiÅŸ (partitioned) tablolarla desteklenmiyor" + +#~ msgid "Anyone can use the client-side lo_export() provided by libpq." +#~ msgstr "Libpq kütüphanesinin saÄŸladığı istemci-tarafı lo_export() herkes kullanabilir." + +#~ msgid "must be superuser to use server-side lo_export()" +#~ msgstr "sunucu tarafı lo_export() kullanmak için superuser olmalısınız" + +#~ msgid "Anyone can use the client-side lo_import() provided by libpq." +#~ msgstr "Libpq kütüphanesinin saÄŸladığı istemci-tarafı lo_import() herkes kullanabilir." + +#~ msgid "must be superuser to use server-side lo_import()" +#~ msgstr "sunucu tarafı lo_import() kullanmak için superuser olmalısınız" + +#~ msgid "RANGE FOLLOWING is only supported with UNBOUNDED" +#~ msgstr "RANGE FOLLOWING sadece UNBOUNDED ile desteklenmektedir" + +#~ msgid "RANGE PRECEDING is only supported with UNBOUNDED" +#~ msgstr "RANGE PRECEDING sadece UNBOUNDED ile desteklenmektedir" + +#~ msgid "combine function for aggregate %u must be declared as STRICT" +#~ msgstr "%u toplamı (aggregate) için birleÅŸtirme (combine) fonksiyonu STRICT olarak bildirilmeli (declare)" + +#~ msgid "Close open transactions soon to avoid wraparound problems." +#~ msgstr "BaÅŸa dönme sorununu yaÅŸamamak için aktif transactionları kapatın." + +#~ msgid "transform function must not be an aggregate function" +#~ msgstr "dönüştürme fonksiyonu toplam (aggregate) fonksiyonu olmamalıdır" + +#~ msgid "cast function must not be an aggregate function" +#~ msgstr "cast fonksiyonu aggregate olmamalıdır" + +#~ msgid "unrecognized function attribute \"%s\" ignored" +#~ msgstr "tanınmayan fonksiyon yarametresi \"%s\" yoksayıldı" + +#~ msgid "cannot route inserted tuples to a foreign table" +#~ msgstr "eklenen satırlar bir uzak tabloya yönlendirilemiyor" + +#~ msgid "cannot copy to foreign table \"%s\"" +#~ msgstr "\"%s\" uzak tablosuna kopyalanamıyor" + +#~ msgid "must be superuser to COPY to or from a file" +#~ msgstr "bir dosyadan veya bir dosyaya COPY iÅŸlemi yapmak için superuser haklarına sahip olmalısınız" + +#~ msgid "function \"%s\" is not a window function" +#~ msgstr "%s fonksiyonu bir pencere (window) fonksiyonu deÄŸildir" + +#~ msgid "function \"%s\" is not an aggregate function" +#~ msgstr "\"%s\" fonksiyonu bir toplam (aggregate) fonksiyonu deÄŸildir" + +#~ msgid "function \"%s\" is an aggregate function" +#~ msgstr "\"%s\" fonksiyonu bir toplam (aggregate) fonksiyonudur" + +#~ msgid "\"%s\" is already an attribute of type %s" +#~ msgstr "\"%s\" zanten %s tipinin özelliÄŸidir" + +#~ msgid "%s in publication %s" +#~ msgstr "%2$s yayınında %1$s" + +#~ msgid " in schema %s" +#~ msgstr "%s ÅŸeması içinde" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış XLOG_SEG_SIZE deÄŸeri" + +#~ msgid "invalid length of secondary checkpoint record" +#~ msgstr "ikincil checkpoint kaydının uzunluÄŸu geçersiz" + +#~ msgid "invalid xl_info in secondary checkpoint record" +#~ msgstr "ikincil checkpoint kaydındaki xl_info geçersiz" + +#~ msgid "invalid resource manager ID in secondary checkpoint record" +#~ msgstr "ikincil checkpoint kaydındaki resource manager ID geçersiz" + +#~ msgid "invalid secondary checkpoint record" +#~ msgstr "ikincil checkpoint kaydı geçersiz" + +#~ msgid "invalid secondary checkpoint link in control file" +#~ msgstr "kontrol dosyasındaki ikincil checkpoint baÄŸlantısı geçersiz" + +#~ msgid "using previous checkpoint record at %X/%X" +#~ msgstr "%X/%X adresindeki eski checkpoint kaydı kullanılıyor" + +#~ msgid "The database cluster was initialized with XLOG_SEG_SIZE %d, but the server was compiled with XLOG_SEG_SIZE %d." +#~ msgstr "Veritabanı clusteri XLOG_SEG_SIZE %d ile ilklendirilmiÅŸtir, ancak sunucu XLOG_SEG_SIZE %d ile derlenmiÅŸtir." + +#~ msgid "could not open write-ahead log directory \"%s\": %m" +#~ msgstr "\"%s\" kayıt (write-ahead log) dizini açılamıyor: %m" + +#~ msgid "no such savepoint" +#~ msgstr "böyle bir savepoint bulunamadı" + +#~ msgid "%s cannot be executed from a function or multi-command string" +#~ msgstr "%s bir fonksiyonun veya çoklu komut satırından içinden çalıştırılamaz" + +#~ msgid "could not open BufFile \"%s\"" +#~ msgstr "\"%s\" BufFile dosyası açılamadı" + +#~ msgid "operator procedure must be specified" +#~ msgstr "operatör yordamı belirtilmelidir" + +#~ msgid "procedure number %d for (%s,%s) appears more than once" +#~ msgstr "%d (%s, %s) yordam numarasına birden fazla kez rastlanıyor" + +#~ msgid "hash procedure 1 must have one argument" +#~ msgstr "hash prosedürü 1, bir argüman almalıdır" + +#~ msgid "invalid procedure number %d, must be between 1 and %d" +#~ msgstr "%d geçersiz procedure numarası, 0 ile %d arasında olmalıdır" + +#~ msgid "domain %s has multiple constraints named \"%s\"" +#~ msgstr "\"%s\" etki alanı (domain) birden fazla \"%s\" adlı kısıtlamaya sahip" + +#~ msgid "table \"%s\" has multiple constraints named \"%s\"" +#~ msgstr "\"%s\" tablosu birden fazla \"%s\" adlı constrainte sahip" diff --git a/src/backend/po/zh_CN.po b/src/backend/po/zh_CN.po index 1e6934a7a54..78bad7f729f 100644 --- a/src/backend/po/zh_CN.po +++ b/src/backend/po/zh_CN.po @@ -3,12 +3,12 @@ # msgid "" msgstr "" -"Project-Id-Version: postgres (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:43+0000\n" -"PO-Revision-Date: 2016-06-12 15:34+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Chinese (Simplified)\n" +"Project-Id-Version: postgres (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:09+0000\n" +"PO-Revision-Date: 2019-05-15 18:21+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -16,120 +16,197 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.5.7\n" -#: ../common/config_info.c:131 ../common/config_info.c:139 -#: ../common/config_info.c:147 ../common/config_info.c:155 -#: ../common/config_info.c:163 ../common/config_info.c:171 -#: ../common/config_info.c:179 ../common/config_info.c:187 -#: ../common/config_info.c:195 -#| msgid "not recorded\n" +#: ../common/config_info.c:130 ../common/config_info.c:138 +#: ../common/config_info.c:146 ../common/config_info.c:154 +#: ../common/config_info.c:162 ../common/config_info.c:170 +#: ../common/config_info.c:178 ../common/config_info.c:186 +#: ../common/config_info.c:194 msgid "not recorded" msgstr "没有被记录" -#: ../common/controldata_utils.c:52 commands/copy.c:2798 -#: commands/extension.c:3120 utils/adt/genfile.c:134 +#: ../common/controldata_utils.c:68 commands/copy.c:3544 +#: commands/extension.c:3341 utils/adt/genfile.c:153 #, c-format msgid "could not open file \"%s\" for reading: %m" msgstr "为了读å–, 无法打开文件 \"%s\": %m" -#: ../common/controldata_utils.c:56 -#, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: 为了读å–, 无法打开文件 \"%s\": %s\n" - -#: ../common/controldata_utils.c:66 access/transam/timeline.c:346 -#: access/transam/xlog.c:3193 access/transam/xlog.c:10338 -#: access/transam/xlog.c:10351 access/transam/xlog.c:10714 -#: access/transam/xlog.c:10757 access/transam/xlog.c:10796 -#: access/transam/xlog.c:10839 access/transam/xlogfuncs.c:666 -#: access/transam/xlogfuncs.c:685 commands/extension.c:3130 -#: replication/logical/origin.c:665 replication/logical/origin.c:695 -#: replication/logical/reorderbuffer.c:3077 replication/walsender.c:499 -#: storage/file/copydir.c:176 utils/adt/genfile.c:151 +#: ../common/controldata_utils.c:86 access/transam/timeline.c:347 +#: access/transam/twophase.c:1293 access/transam/xlog.c:3456 +#: access/transam/xlog.c:4603 access/transam/xlog.c:10779 +#: access/transam/xlog.c:10792 access/transam/xlog.c:11217 +#: access/transam/xlog.c:11297 access/transam/xlog.c:11336 +#: access/transam/xlog.c:11379 access/transam/xlogfuncs.c:663 +#: access/transam/xlogfuncs.c:682 commands/extension.c:3351 libpq/hba.c:499 +#: replication/logical/origin.c:717 replication/logical/origin.c:753 +#: replication/logical/reorderbuffer.c:3308 +#: replication/logical/snapbuild.c:1746 replication/logical/snapbuild.c:1788 +#: replication/logical/snapbuild.c:1816 replication/logical/snapbuild.c:1843 +#: replication/slot.c:1424 replication/slot.c:1465 replication/walsender.c:513 +#: storage/file/copydir.c:195 utils/adt/genfile.c:170 utils/adt/misc.c:753 +#: utils/cache/relmapper.c:741 #, c-format msgid "could not read file \"%s\": %m" msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %m" -#: ../common/controldata_utils.c:69 +#: ../common/controldata_utils.c:97 access/transam/twophase.c:1296 +#: access/transam/xlog.c:3461 access/transam/xlog.c:4608 +#: replication/logical/origin.c:722 replication/logical/origin.c:761 +#: replication/logical/snapbuild.c:1751 replication/logical/snapbuild.c:1793 +#: replication/logical/snapbuild.c:1821 replication/logical/snapbuild.c:1848 +#: replication/slot.c:1428 replication/slot.c:1469 replication/walsender.c:518 +#: utils/cache/relmapper.c:745 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %s\n" - -#: ../common/controldata_utils.c:86 -msgid "calculated CRC checksum does not match value stored in file" -msgstr "计算得到的 CRC 校验与存储在文件中的值ä¸åŒ¹é…" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "æ— æ³•è¯»å–æ–‡ä»¶\"%1$s\":读å–了%3$zu中的%2$d" -#: ../common/controldata_utils.c:88 +#: ../common/controldata_utils.c:112 ../common/controldata_utils.c:256 +#: access/heap/rewriteheap.c:1208 access/heap/rewriteheap.c:1310 +#: access/transam/timeline.c:377 access/transam/timeline.c:421 +#: access/transam/timeline.c:499 access/transam/twophase.c:1305 +#: access/transam/twophase.c:1728 access/transam/xlog.c:3328 +#: access/transam/xlog.c:3496 access/transam/xlog.c:3501 +#: access/transam/xlog.c:3798 access/transam/xlog.c:4573 +#: access/transam/xlog.c:5522 access/transam/xlogfuncs.c:688 +#: commands/copy.c:1815 libpq/be-fsstubs.c:462 libpq/be-fsstubs.c:535 +#: replication/logical/origin.c:655 replication/logical/origin.c:794 +#: replication/logical/reorderbuffer.c:3366 +#: replication/logical/snapbuild.c:1658 replication/logical/snapbuild.c:1856 +#: replication/slot.c:1322 replication/slot.c:1476 replication/walsender.c:528 +#: storage/file/copydir.c:218 storage/file/copydir.c:223 storage/file/fd.c:654 +#: storage/file/fd.c:3308 storage/file/fd.c:3411 utils/cache/relmapper.c:753 +#: utils/cache/relmapper.c:892 #, c-format -msgid "" -"WARNING: Calculated CRC checksum does not match value stored in file.\n" -"Either the file is corrupt, or it has a different layout than this program\n" -"is expecting. The results below are untrustworthy.\n" -"\n" -msgstr "" -"警告: 计算出æ¥çš„CRC校验值与已ä¿å­˜åœ¨æ–‡ä»¶ä¸­çš„值ä¸åŒ¹é….\n" -"䏿˜¯æ–‡ä»¶å了,就是设计与程åºçš„æœŸæœ›å€¼ä¸åŒ.\n" -"下é¢çš„结果是ä¸å¯é çš„.\n" -"\n" +msgid "could not close file \"%s\": %m" +msgstr "无法关闭文件 \"%s\": %m" -#: ../common/controldata_utils.c:97 -#| msgid "%s: encoding mismatch\n" +#: ../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "字节排åºä¸åŒ¹é…" -#: ../common/controldata_utils.c:99 +#: ../common/controldata_utils.c:197 access/heap/rewriteheap.c:1293 +#: access/transam/timeline.c:111 access/transam/timeline.c:236 +#: access/transam/timeline.c:333 access/transam/twophase.c:1249 +#: access/transam/xlog.c:3230 access/transam/xlog.c:3370 +#: access/transam/xlog.c:3411 access/transam/xlog.c:3609 +#: access/transam/xlog.c:3694 access/transam/xlog.c:3772 +#: access/transam/xlog.c:4593 access/transam/xlogutils.c:708 +#: postmaster/syslogger.c:1489 replication/basebackup.c:517 +#: replication/basebackup.c:1394 replication/logical/origin.c:707 +#: replication/logical/reorderbuffer.c:2308 +#: replication/logical/reorderbuffer.c:2575 +#: replication/logical/reorderbuffer.c:3288 +#: replication/logical/snapbuild.c:1613 replication/logical/snapbuild.c:1717 +#: replication/slot.c:1396 replication/walsender.c:486 +#: replication/walsender.c:2450 storage/file/copydir.c:161 +#: storage/file/fd.c:629 storage/file/fd.c:3295 storage/file/fd.c:3382 +#: storage/smgr/md.c:462 utils/cache/relmapper.c:724 +#: utils/cache/relmapper.c:836 utils/error/elog.c:1861 +#: utils/init/miscinit.c:1269 utils/init/miscinit.c:1404 +#: utils/init/miscinit.c:1481 utils/misc/guc.c:8060 utils/misc/guc.c:8092 #, c-format -msgid "" -"WARNING: possible byte ordering mismatch\n" -"The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, " -"and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" -msgstr "" -"警告: å¯èƒ½å­—节顺åºä¸åŒ¹é…\n" -"用于存储文件pg_control的字节顺åºå¯èƒ½ä¸Žç¨‹åºä½¿ç”¨çš„ä¸åŒ¹é…\n" -"åœ¨é‚£ç§æƒ…å†µä¸‹ç»“æžœå°†ä¼šæ˜¯ä¸æ­£ç¡®çš„,并且所安装的PostgreSQL\n" -"将会与这个数æ®ç›®å½•ä¸å…¼å®¹\n" +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" + +#: ../common/controldata_utils.c:221 access/transam/twophase.c:1701 +#: access/transam/twophase.c:1710 access/transam/xlog.c:10536 +#: access/transam/xlog.c:10574 access/transam/xlog.c:10987 +#: access/transam/xlogfuncs.c:742 postmaster/syslogger.c:1500 +#: postmaster/syslogger.c:1513 utils/cache/relmapper.c:870 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "无法写入文件 \"%s\": %m" -#: ../common/exec.c:127 ../common/exec.c:241 ../common/exec.c:284 +#: ../common/controldata_utils.c:239 access/heap/rewriteheap.c:981 +#: access/heap/rewriteheap.c:1202 access/heap/rewriteheap.c:1304 +#: access/transam/timeline.c:415 access/transam/timeline.c:493 +#: access/transam/twophase.c:1722 access/transam/xlog.c:3321 +#: access/transam/xlog.c:3490 access/transam/xlog.c:4566 +#: access/transam/xlog.c:10054 access/transam/xlog.c:10080 +#: replication/logical/snapbuild.c:1651 replication/slot.c:1312 +#: replication/slot.c:1406 storage/file/fd.c:646 storage/file/fd.c:3403 +#: storage/smgr/md.c:885 storage/smgr/md.c:918 storage/sync/sync.c:395 +#: utils/cache/relmapper.c:885 utils/misc/guc.c:7840 #, c-format -msgid "could not identify current directory: %s" +msgid "could not fsync file \"%s\": %m" +msgstr "无法 fsync 文件 \"%s\": %m" + +#: ../common/exec.c:138 ../common/exec.c:255 ../common/exec.c:301 +#, fuzzy, c-format +#| msgid "could not identify current directory: %s" +msgid "could not identify current directory: %m" msgstr "无法确认当å‰ç›®å½•: %s" # command.c:122 -#: ../common/exec.c:146 +#: ../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "æ— æ•ˆçš„äºŒè¿›åˆ¶ç  \"%s\"" # command.c:1103 -#: ../common/exec.c:195 +#: ../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "无法读å–äºŒè¿›åˆ¶ç  \"%s\"" -#: ../common/exec.c:202 +#: ../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "未能找到一个 \"%s\" æ¥æ‰§è¡Œ" -#: ../common/exec.c:257 ../common/exec.c:293 +#: ../common/exec.c:271 ../common/exec.c:310 utils/init/miscinit.c:220 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "无法跳转到目录 \"%s\" 中: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "无法跳转到目录 \"%s\" 中: %m" -#: ../common/exec.c:272 +#: ../common/exec.c:288 access/transam/xlog.c:10409 +#: replication/basebackup.c:1232 utils/adt/misc.c:324 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "无法读å–符å·é“¾æŽ¥ \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "无法读å–符å·é“¾æŽ¥ \"%s\": %m" -#: ../common/exec.c:523 -#, c-format -msgid "pclose failed: %s" +#: ../common/exec.c:541 +#, fuzzy, c-format +#| msgid "pclose failed: %s" +msgid "pclose failed: %m" msgstr "pclose调用失败: %s" +#: ../common/exec.c:670 ../common/exec.c:715 ../common/exec.c:807 +#: ../common/psprintf.c:143 ../port/path.c:630 ../port/path.c:668 +#: ../port/path.c:685 access/transam/twophase.c:1394 access/transam/xlog.c:6346 +#: lib/dshash.c:246 lib/stringinfo.c:283 libpq/auth.c:1093 libpq/auth.c:1483 +#: libpq/auth.c:1551 libpq/auth.c:2069 postmaster/bgworker.c:337 +#: postmaster/bgworker.c:907 postmaster/postmaster.c:2454 +#: postmaster/postmaster.c:2476 postmaster/postmaster.c:4068 +#: postmaster/postmaster.c:4757 postmaster/postmaster.c:4832 +#: postmaster/postmaster.c:5509 postmaster/postmaster.c:5856 +#: replication/libpqwalreceiver/libpqwalreceiver.c:257 +#: replication/logical/logical.c:179 storage/buffer/localbuf.c:436 +#: storage/file/fd.c:795 storage/file/fd.c:1191 storage/file/fd.c:1352 +#: storage/file/fd.c:2161 storage/ipc/procarray.c:1047 +#: storage/ipc/procarray.c:1542 storage/ipc/procarray.c:1549 +#: storage/ipc/procarray.c:1973 storage/ipc/procarray.c:2600 +#: utils/adt/cryptohashes.c:45 utils/adt/cryptohashes.c:65 +#: utils/adt/formatting.c:1603 utils/adt/formatting.c:1726 +#: utils/adt/formatting.c:1850 utils/adt/pg_locale.c:473 +#: utils/adt/pg_locale.c:637 utils/adt/regexp.c:223 utils/fmgr/dfmgr.c:229 +#: utils/hash/dynahash.c:448 utils/hash/dynahash.c:557 +#: utils/hash/dynahash.c:1069 utils/mb/mbutils.c:365 utils/mb/mbutils.c:698 +#: utils/misc/guc.c:4634 utils/misc/guc.c:4650 utils/misc/guc.c:4663 +#: utils/misc/guc.c:7818 utils/misc/tzparser.c:468 utils/mmgr/aset.c:484 +#: utils/mmgr/dsa.c:701 utils/mmgr/dsa.c:723 utils/mmgr/dsa.c:804 +#: utils/mmgr/generation.c:249 utils/mmgr/mcxt.c:796 utils/mmgr/mcxt.c:832 +#: utils/mmgr/mcxt.c:870 utils/mmgr/mcxt.c:908 utils/mmgr/mcxt.c:944 +#: utils/mmgr/mcxt.c:975 utils/mmgr/mcxt.c:1011 utils/mmgr/mcxt.c:1063 +#: utils/mmgr/mcxt.c:1098 utils/mmgr/mcxt.c:1133 utils/mmgr/slab.c:239 +#, c-format +msgid "out of memory" +msgstr "内存用尽" + #: ../common/fe_memutils.c:35 ../common/fe_memutils.c:75 -#: ../common/fe_memutils.c:98 ../common/psprintf.c:181 ../port/path.c:632 -#: ../port/path.c:670 ../port/path.c:687 +#: ../common/fe_memutils.c:98 ../common/psprintf.c:145 ../port/path.c:632 +#: ../port/path.c:670 ../port/path.c:687 utils/misc/ps_status.c:176 +#: utils/misc/ps_status.c:184 utils/misc/ps_status.c:214 +#: utils/misc/ps_status.c:222 #, c-format msgid "out of memory\n" msgstr "内存溢出\n" @@ -140,164 +217,88 @@ msgstr "内存溢出\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "无法å¤åˆ¶ç©ºæŒ‡é’ˆ (内部错误)\n" -#: ../common/pgfnames.c:45 -#, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "无法打开目录 \"%s\": %s\n" - -#: ../common/pgfnames.c:72 -#, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "无法读å–目录 \"%s\": %s\n" - -#: ../common/pgfnames.c:84 -#, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "无法关闭目录 \"%s\": %s\n" - -#: ../common/psprintf.c:179 ../port/path.c:630 ../port/path.c:668 -#: ../port/path.c:685 access/transam/twophase.c:1261 -#: access/transam/xlog.c:6069 lib/stringinfo.c:258 libpq/auth.c:847 -#: libpq/auth.c:1210 libpq/auth.c:1278 libpq/auth.c:1794 -#: postmaster/bgworker.c:289 postmaster/bgworker.c:797 -#: postmaster/postmaster.c:2323 postmaster/postmaster.c:2354 -#: postmaster/postmaster.c:3886 postmaster/postmaster.c:4576 -#: postmaster/postmaster.c:4644 postmaster/postmaster.c:5343 -#: postmaster/postmaster.c:5596 replication/logical/logical.c:170 -#: storage/buffer/localbuf.c:422 storage/file/fd.c:729 storage/file/fd.c:1126 -#: storage/file/fd.c:1244 storage/file/fd.c:1916 storage/ipc/procarray.c:1060 -#: storage/ipc/procarray.c:1546 storage/ipc/procarray.c:1553 -#: storage/ipc/procarray.c:1967 storage/ipc/procarray.c:2570 -#: utils/adt/formatting.c:1523 utils/adt/formatting.c:1643 -#: utils/adt/formatting.c:1764 utils/adt/regexp.c:219 utils/adt/varlena.c:4440 -#: utils/adt/varlena.c:4461 utils/fmgr/dfmgr.c:216 utils/hash/dynahash.c:431 -#: utils/hash/dynahash.c:537 utils/hash/dynahash.c:1049 utils/mb/mbutils.c:376 -#: utils/mb/mbutils.c:709 utils/misc/guc.c:3885 utils/misc/guc.c:3901 -#: utils/misc/guc.c:3914 utils/misc/guc.c:6859 utils/misc/tzparser.c:470 -#: utils/mmgr/aset.c:505 utils/mmgr/mcxt.c:770 utils/mmgr/mcxt.c:805 -#: utils/mmgr/mcxt.c:842 utils/mmgr/mcxt.c:879 utils/mmgr/mcxt.c:913 -#: utils/mmgr/mcxt.c:942 utils/mmgr/mcxt.c:976 utils/mmgr/mcxt.c:1058 -#: utils/mmgr/mcxt.c:1092 utils/mmgr/mcxt.c:1141 +#: ../common/logging.c:188 #, c-format -msgid "out of memory" -msgstr "内存用尽" +msgid "fatal: " +msgstr "" -#: ../common/relpath.c:59 +#: ../common/logging.c:195 +#, fuzzy, c-format +#| msgid "SSL error: %s" +msgid "error: " +msgstr "SSL 错误: %s" + +#: ../common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "" + +#: ../common/relpath.c:58 #, c-format msgid "invalid fork name" msgstr "无效分支åç§°" -#: ../common/relpath.c:60 +#: ../common/relpath.c:59 #, c-format msgid "Valid fork names are \"main\", \"fsm\", \"vm\", and \"init\"." msgstr "有效的分支å称是 \"main\", \"fsm\", \"vm\"å’Œ\"init\"." -#: ../common/restricted_token.c:68 -#, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: WARNING: 无法为该平å°åˆ›å»ºå—é™åˆ¶çš„令牌\n" - -#: ../common/restricted_token.c:77 -#, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s:无法打开进程令牌 (token): é”™è¯¯ç  %lu\n" - -#: ../common/restricted_token.c:90 -#, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: 无法分é…SID: é”™è¯¯ç  %lu\n" - -#: ../common/restricted_token.c:110 -#, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: 无法创建å—é™ä»¤ç‰Œ: 错误ç ä¸º %lu\n" - -#: ../common/restricted_token.c:132 -#, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: 无法为命令 \"%s\"创建进程: é”™è¯¯ç  %lu\n" - -#: ../common/restricted_token.c:170 -#, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: 无法使用å—é™ä»¤ç‰Œå†æ¬¡æ‰§è¡Œ: é”™è¯¯ç  %lu\n" - -#: ../common/restricted_token.c:186 -#, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: 无法从å­è¿›ç¨‹å¾—到退出ç : é”™è¯¯ç  %lu\n" - -#: ../common/rmtree.c:77 -#, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "æ— æ³•èŽ·å–æ–‡ä»¶æˆ–目录\"%s\"的状æ€: %s\n" - -#: ../common/rmtree.c:104 ../common/rmtree.c:121 +#: ../common/saslprep.c:1093 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "无法删除目录 \"%s\": %s\n" +msgid "password too long" +msgstr "密ç å¤ªé•¿" -#: ../common/username.c:45 +#: ../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "无法找到有效的用户ID %ld: %s" -#: ../common/username.c:47 libpq/auth.c:1741 +#: ../common/username.c:45 libpq/auth.c:2016 msgid "user does not exist" msgstr "用户ä¸å­˜åœ¨" -#: ../common/username.c:62 +#: ../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ç”¨æˆ·åæŸ¥æ‰¾å¤±è´¥ï¼šé”™è¯¯ä»£ç æ˜¯%lu" -#: ../common/wait_error.c:47 +#: ../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "命令无法执行" -#: ../common/wait_error.c:51 +#: ../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "命令没有找到" -#: ../common/wait_error.c:56 +#: ../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "å­è¿›ç¨‹å·²é€€å‡º, 退出ç ä¸º %d" -#: ../common/wait_error.c:63 +#: ../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "å­è¿›ç¨‹è¢«ä¾‹å¤–(exception) 0x%X 终止" -#: ../common/wait_error.c:73 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %s 终止" - -#: ../common/wait_error.c:77 -#, c-format -msgid "child process was terminated by signal %d" +#: ../common/wait_error.c:66 +#, fuzzy, c-format +#| msgid "child process was terminated by signal %d" +msgid "child process was terminated by signal %d: %s" msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %d 终止" -#: ../common/wait_error.c:82 +#: ../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "å­è¿›ç¨‹å·²é€€å‡º, æœªçŸ¥çŠ¶æ€ %d" -#: ../port/chklocale.c:259 +#: ../port/chklocale.c:288 #, c-format msgid "could not determine encoding for codeset \"%s\"" msgstr "无法确定字符集的编ç \"%s\"" -#: ../port/chklocale.c:260 ../port/chklocale.c:389 -#: postmaster/postmaster.c:4876 -#, c-format -msgid "Please report this to ." -msgstr "è¯·å‘ å‘é€æŠ¥å‘Š." - -#: ../port/chklocale.c:381 ../port/chklocale.c:387 +#: ../port/chklocale.c:409 ../port/chklocale.c:415 #, c-format msgid "could not determine encoding for locale \"%s\": codeset is \"%s\"" msgstr "无法确定语言环境\"%s\"的编ç : 代ç é›†æ˜¯\"%s\"" @@ -323,29 +324,27 @@ msgid "could not get junction for \"%s\": %s\n" msgstr "æ— æ³•å¾—åˆ°è”æŽ¥ \"%s\": %s\n" # fe-lobj.c:400 fe-lobj.c:483 -#: ../port/open.c:112 +#: ../port/open.c:128 #, c-format msgid "could not open file \"%s\": %s" msgstr "无法打开文件 \"%s\": %s" -#: ../port/open.c:113 +#: ../port/open.c:129 msgid "lock violation" msgstr "é”冲çª" -#: ../port/open.c:113 +#: ../port/open.c:129 msgid "sharing violation" msgstr "共享冲çª" -#: ../port/open.c:114 +#: ../port/open.c:130 #, c-format msgid "Continuing to retry for 30 seconds." msgstr "ç»§ç»­é‡æ–°å°è¯•30ç§’" -#: ../port/open.c:115 +#: ../port/open.c:131 #, c-format -msgid "" -"You might have antivirus, backup, or similar software interfering with the " -"database system." +msgid "You might have antivirus, backup, or similar software interfering with the database system." msgstr "您å¯èƒ½æœ‰å病毒,备份或类似的软件与数æ®åº“系统冲çª" #: ../port/path.c:654 @@ -353,317 +352,332 @@ msgstr "您å¯èƒ½æœ‰å病毒,备份或类似的软件与数æ®åº“ç³»ç»Ÿå†²çª msgid "could not get current working directory: %s\n" msgstr "无法得到当å‰å·¥ä½œç›®å½•: %s\n" -#: ../port/strerror.c:25 +#: ../port/strerror.c:72 #, c-format -msgid "unrecognized error %d" -msgstr "未知的 SSL 错误ç : %d" +msgid "operating system error %d" +msgstr "æ“作系统错误 %d" + +#: ../port/win32security.c:62 +#, c-format +msgid "could not get SID for Administrators group: error code %lu\n" +msgstr "无法获å–管ç†å‘˜ç»„çš„SID : é”™è¯¯ç  %lu\n" + +#: ../port/win32security.c:72 +#, c-format +msgid "could not get SID for PowerUsers group: error code %lu\n" +msgstr "无法获å–PowerUsers组的SID:错误代ç %lu\n" + +#: ../port/win32security.c:80 +#, c-format +msgid "could not check access token membership: error code %lu\n" +msgstr "无法检查访问令牌æˆå‘˜èº«ä»½: é”™è¯¯ç  %lu\n" + +#: access/brin/brin.c:204 +#, c-format +msgid "request for BRIN range summarization for index \"%s\" page %u was not recorded" +msgstr "未记录对索引\"%s\"页%uçš„BRIN范围摘è¦çš„请求" + +#: access/brin/brin.c:881 access/brin/brin.c:958 access/gin/ginfast.c:1041 +#: access/transam/xlog.c:10189 access/transam/xlog.c:10718 +#: access/transam/xlogfuncs.c:289 access/transam/xlogfuncs.c:316 +#: access/transam/xlogfuncs.c:355 access/transam/xlogfuncs.c:376 +#: access/transam/xlogfuncs.c:397 access/transam/xlogfuncs.c:467 +#: access/transam/xlogfuncs.c:524 +#, c-format +msgid "recovery is in progress" +msgstr "æ¢å¤æ“作正在进行中" + +#: access/brin/brin.c:882 access/brin/brin.c:959 +#, c-format +msgid "BRIN control functions cannot be executed during recovery." +msgstr "在æ¢å¤æœŸé—´æ— æ³•执行BRIN控制函数" + +#: access/brin/brin.c:890 access/brin/brin.c:967 +#, c-format +msgid "block number out of range: %s" +msgstr "å—å·è¶…出范围: %s" -#: access/brin/brin.c:817 +#: access/brin/brin.c:913 access/brin/brin.c:990 #, c-format -#| msgid "\"%s\" is not an index" msgid "\"%s\" is not a BRIN index" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ª BRIN 索引" -#: access/brin/brin.c:833 +#: access/brin/brin.c:929 access/brin/brin.c:1006 #, c-format -#| msgid "could not open two-phase state file \"%s\": %m" msgid "could not open parent table of index %s" msgstr "无法打开索引 %s 的父表" -#: access/brin/brin_pageops.c:76 access/brin/brin_pageops.c:369 -#: access/brin/brin_pageops.c:844 +#: access/brin/brin_pageops.c:77 access/brin/brin_pageops.c:363 +#: access/brin/brin_pageops.c:844 access/gin/ginentrypage.c:110 +#: access/gist/gist.c:1445 access/spgist/spgdoinsert.c:1957 +#, c-format +msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgstr "ç´¢å¼•è¡Œçš„å¤§å° %1$zu 超过了索引\"%3$s\"所å…许的最大值%2$zu" + +#: access/brin/brin_revmap.c:382 access/brin/brin_revmap.c:388 +#, c-format +msgid "corrupted BRIN index: inconsistent range map" +msgstr "æŸåçš„BRIN索引:范围映射ä¸ä¸€è‡´" + +#: access/brin/brin_revmap.c:404 #, c-format -msgid "index row size %lu exceeds maximum %lu for index \"%s\"" -msgstr "索引行的大å°%1$lu超过了索引\"%3$s\"的最大值%2$lu" +msgid "leftover placeholder tuple detected in BRIN index \"%s\", deleting" +msgstr "在BRIN索引\"%s\"中检测到剩余的å ä½ç¬¦å…ƒç»„,正在删除" -#: access/brin/brin_revmap.c:456 +#: access/brin/brin_revmap.c:601 #, c-format msgid "unexpected page type 0x%04X in BRIN index \"%s\" block %u" msgstr "æ„æ–™ä¹‹å¤–的页类型0x%04X出现在BRIN索引\"%s\"çš„å—%u中" -#: access/brin/brin_validate.c:115 +#: access/brin/brin_validate.c:116 access/gin/ginvalidate.c:149 +#: access/gist/gistvalidate.c:146 access/hash/hashvalidate.c:132 +#: access/nbtree/nbtvalidate.c:110 access/spgist/spgvalidate.c:165 #, c-format -msgid "brin opfamily %s contains function %s with invalid support number %d" -msgstr "brin opfamily %s 包å«çš„函数 %s 具有无效的支æŒå· %d" +msgid "operator family \"%s\" of access method %s contains function %s with invalid support number %d" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %4$d 的函数 %3$s" -#: access/brin/brin_validate.c:131 +#: access/brin/brin_validate.c:132 access/gin/ginvalidate.c:161 +#: access/gist/gistvalidate.c:158 access/hash/hashvalidate.c:115 +#: access/nbtree/nbtvalidate.c:122 access/spgist/spgvalidate.c:177 #, c-format -msgid "" -"brin opfamily %s contains function %s with wrong signature for support " -"number %d" -msgstr "brin opfamily %s 包å«çš„函数 %s 具有错误的支æŒå·ç­¾å %d" +msgid "operator family \"%s\" of access method %s contains function %s with wrong signature for support number %d" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"包å«çš„函数 %3$s 对支æŒç¼–å· %4$d 具有错误的签å" -#: access/brin/brin_validate.c:153 +#: access/brin/brin_validate.c:154 access/gin/ginvalidate.c:180 +#: access/gist/gistvalidate.c:178 access/hash/hashvalidate.c:153 +#: access/nbtree/nbtvalidate.c:142 access/spgist/spgvalidate.c:197 #, c-format -msgid "brin opfamily %s contains operator %s with invalid strategy number %d" -msgstr "brin opfamily %s 包å«çš„æ“ä½œç¬¦ %s å…·æœ‰æ— æ•ˆçš„ç­–ç•¥å· %d" +msgid "operator family \"%s\" of access method %s contains operator %s with invalid strategy number %d" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %4$d çš„æ“作符 %3$s" -#: access/brin/brin_validate.c:182 +#: access/brin/brin_validate.c:183 access/gin/ginvalidate.c:193 +#: access/hash/hashvalidate.c:166 access/nbtree/nbtvalidate.c:155 +#: access/spgist/spgvalidate.c:213 #, c-format -msgid "" -"brin opfamily %s contains invalid ORDER BY specification for operator %s" -msgstr "brin opfamily %s 包å«çš„æ“ä½œç¬¦ %s 的无效 ORDER BY 说明" +msgid "operator family \"%s\" of access method %s contains invalid ORDER BY specification for operator %s" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"åŒ…å«æ“作符 %3$s 的无效 ORDER BY 声明" -#: access/brin/brin_validate.c:195 +#: access/brin/brin_validate.c:196 access/gin/ginvalidate.c:206 +#: access/gist/gistvalidate.c:226 access/hash/hashvalidate.c:179 +#: access/nbtree/nbtvalidate.c:168 access/spgist/spgvalidate.c:229 #, c-format -msgid "brin opfamily %s contains operator %s with wrong signature" -msgstr "brin opfamily %s 包å«çš„æ“ä½œç¬¦ %s 具有错误的签å" +msgid "operator family \"%s\" of access method %s contains operator %s with wrong signature" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %3$s" -#: access/brin/brin_validate.c:233 +#: access/brin/brin_validate.c:234 access/hash/hashvalidate.c:219 +#: access/nbtree/nbtvalidate.c:226 access/spgist/spgvalidate.c:256 #, c-format -msgid "brin opfamily %s is missing operator(s) for types %s and %s" -msgstr "brin opfamily %s 中缺少用于类型 %s å’Œ %s çš„æ“作符" +msgid "operator family \"%s\" of access method %s is missing operator(s) for types %s and %s" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"缺少类型 %3$s å’Œ %4$s çš„æ“作符" -#: access/brin/brin_validate.c:243 +#: access/brin/brin_validate.c:244 #, c-format -msgid "brin opfamily %s is missing support function(s) for types %s and %s" -msgstr "brin opfamily %s 中缺少用于类型 %s å’Œ %s 的支æŒå‡½æ•°" +msgid "operator family \"%s\" of access method %s is missing support function(s) for types %s and %s" +msgstr "访问方法%2$sçš„è¿ç®—符æ—\"%1$s\"中缺少用于类型 %3$s å’Œ %4$s 的支æŒå‡½æ•°" -#: access/brin/brin_validate.c:256 +#: access/brin/brin_validate.c:257 access/hash/hashvalidate.c:233 +#: access/nbtree/nbtvalidate.c:250 access/spgist/spgvalidate.c:289 #, c-format -msgid "brin opclass %s is missing operator(s)" -msgstr "brin opclass %s 缺少æ“作符" +msgid "operator class \"%s\" of access method %s is missing operator(s)" +msgstr "访问方法 %2$s æ“作符表 \"%1$s\" 缺少è¿ç®—符" -#: access/brin/brin_validate.c:267 +#: access/brin/brin_validate.c:268 access/gin/ginvalidate.c:247 +#: access/gist/gistvalidate.c:266 #, c-format -#| msgid "return type %s is not supported for SQL functions" -msgid "brin opclass %s is missing support function %d" -msgstr "brin opclass %s 缺少支æŒå‡½æ•° %d" +msgid "operator class \"%s\" of access method %s is missing support function %d" +msgstr "访问方法 %2$s æ“作符表 \"%1$s\"缺少支æŒå‡½æ•° %3$d" -#: access/common/heaptuple.c:708 access/common/heaptuple.c:1339 +#: access/common/heaptuple.c:1036 access/common/heaptuple.c:1371 #, c-format msgid "number of columns (%d) exceeds limit (%d)" msgstr "字段个数 (%d) 超出é™åˆ¶ (%d)" -#: access/common/indextuple.c:60 +#: access/common/indextuple.c:63 #, c-format msgid "number of index columns (%d) exceeds limit (%d)" msgstr "索引字段个数 (%d) 超出é™åˆ¶ (%d)" -#: access/common/indextuple.c:176 access/spgist/spgutils.c:646 +#: access/common/indextuple.c:179 access/spgist/spgutils.c:691 #, c-format msgid "index row requires %zu bytes, maximum size is %zu" msgstr "ç´¢å¼•è¡Œéœ€è¦ %zu 字节, 最大值为 %zu" -#: access/common/printtup.c:294 tcop/fastpath.c:182 tcop/fastpath.c:544 -#: tcop/postgres.c:1721 +#: access/common/printtup.c:369 tcop/fastpath.c:180 tcop/fastpath.c:530 +#: tcop/postgres.c:1834 #, c-format msgid "unsupported format code: %d" msgstr "䏿”¯æŒçš„æ ¼å¼ä»£ç : %d" -#: access/common/reloptions.c:488 +#: access/common/reloptions.c:582 #, c-format msgid "user-defined relation parameter types limit exceeded" msgstr "ç”¨æˆ·å®šä¹‰çš„å…³ç³»å‚æ•°ç±»åž‹è¶…过é™åˆ¶" -#: access/common/reloptions.c:770 +#: access/common/reloptions.c:863 #, c-format msgid "RESET must not include values for parameters" msgstr "RESET中ä¸èƒ½åŒ…å«å‚数的值" -#: access/common/reloptions.c:803 +#: access/common/reloptions.c:895 #, c-format msgid "unrecognized parameter namespace \"%s\"" msgstr "æœªè¯†åˆ«çš„å‚æ•°å‘½å空间 \"%s\"" -#: access/common/reloptions.c:1045 parser/parse_clause.c:281 +#: access/common/reloptions.c:932 utils/misc/guc.c:11746 +#, fuzzy, c-format +#| msgid "COPY (query) WITH OIDS is not supported" +msgid "tables declared WITH OIDS are not supported" +msgstr "䏿”¯æŒ COPY (query) WITH OIDS" + +#: access/common/reloptions.c:1150 #, c-format msgid "unrecognized parameter \"%s\"" msgstr "æœªè¯†åˆ«çš„å‚æ•° \"%s\"" -#: access/common/reloptions.c:1075 +#: access/common/reloptions.c:1180 #, c-format msgid "parameter \"%s\" specified more than once" msgstr "表å \"%s\" 被指定多次" -#: access/common/reloptions.c:1091 +#: access/common/reloptions.c:1196 #, c-format msgid "invalid value for boolean option \"%s\": %s" msgstr "布尔选项\"%s\"的值无效:%s" -#: access/common/reloptions.c:1103 +#: access/common/reloptions.c:1208 #, c-format msgid "invalid value for integer option \"%s\": %s" msgstr "傿•° \"%s\" 的值无效: \"%s\"" -#: access/common/reloptions.c:1109 access/common/reloptions.c:1129 +#: access/common/reloptions.c:1214 access/common/reloptions.c:1234 #, c-format msgid "value %s out of bounds for option \"%s\"" msgstr "值 %s超出了选项\"%s\"的范围" -#: access/common/reloptions.c:1111 +#: access/common/reloptions.c:1216 #, c-format msgid "Valid values are between \"%d\" and \"%d\"." msgstr "有效值在\"%d\"å’Œ\"%d\"之间." -#: access/common/reloptions.c:1123 +#: access/common/reloptions.c:1228 #, c-format msgid "invalid value for floating point option \"%s\": %s" msgstr "浮点数类型选项\"%s\"的值无效:%s" -#: access/common/reloptions.c:1131 +#: access/common/reloptions.c:1236 #, c-format msgid "Valid values are between \"%f\" and \"%f\"." msgstr "有效值在 \"%f\"å’Œ \"%f\"之间" -#: access/common/tupconvert.c:108 +#: access/common/tupconvert.c:107 #, c-format msgid "Returned type %s does not match expected type %s in column %d." msgstr "在第%3$d列中返回类型%1$s与期望的类型%2$sä¸åŒ¹é…." -#: access/common/tupconvert.c:136 +#: access/common/tupconvert.c:135 #, c-format -msgid "" -"Number of returned columns (%d) does not match expected column count (%d)." +msgid "Number of returned columns (%d) does not match expected column count (%d)." msgstr "所返回列的数é‡(%d)与所期望列的数é‡(%d)ä¸åŒ¹é…." -#: access/common/tupconvert.c:241 +#: access/common/tupconvert.c:303 #, c-format -msgid "" -"Attribute \"%s\" of type %s does not match corresponding attribute of type " -"%s." +msgid "Attribute \"%s\" of type %s does not match corresponding attribute of type %s." msgstr "类型%2$s的属性\"%1$s\"与对应类型%3$s的属性ä¸åŒ¹é…。" -#: access/common/tupconvert.c:253 +#: access/common/tupconvert.c:315 #, c-format msgid "Attribute \"%s\" of type %s does not exist in type %s." msgstr "类型%2$s的属性\"%1$s\"在类型%3$s中ä¸å­˜åœ¨." -#: access/common/tupdesc.c:635 parser/parse_relation.c:1517 +#: access/common/tupdesc.c:842 parser/parse_clause.c:779 +#: parser/parse_relation.c:1578 #, c-format msgid "column \"%s\" cannot be declared SETOF" msgstr "字段 \"%s\" ä¸èƒ½è¢«å£°æ˜Žä¸º SETOF" #: access/gin/ginbulk.c:44 #, c-format -#| msgid "payload string too long" msgid "posting list is too long" msgstr "ä½ç½®åˆ—表太长" #: access/gin/ginbulk.c:45 #, c-format -msgid "Reduce maintenance_work_mem" +msgid "Reduce maintenance_work_mem." msgstr "å‡å° maintenance_work_mem" -#: access/gin/ginentrypage.c:109 access/gist/gist.c:1354 -#: access/nbtree/nbtinsert.c:575 access/nbtree/nbtsort.c:488 -#: access/spgist/spgdoinsert.c:1915 -#, c-format -msgid "index row size %zu exceeds maximum %zu for index \"%s\"" -msgstr "ç´¢å¼•è¡Œçš„å¤§å° %1$zu 超过了索引\"%3$s\"所å…许的最大值%2$zu" - -#: access/gin/ginfast.c:979 access/transam/xlog.c:9795 -#: access/transam/xlog.c:10266 access/transam/xlogfuncs.c:294 -#: access/transam/xlogfuncs.c:321 access/transam/xlogfuncs.c:360 -#: access/transam/xlogfuncs.c:381 access/transam/xlogfuncs.c:402 -#: access/transam/xlogfuncs.c:472 access/transam/xlogfuncs.c:528 -#, c-format -msgid "recovery is in progress" -msgstr "æ¢å¤æ“作正在进行中" - -#: access/gin/ginfast.c:980 +#: access/gin/ginfast.c:1042 #, c-format -#| msgid "WAL control functions cannot be executed during recovery." msgid "GIN pending list cannot be cleaned up during recovery." msgstr "在æ¢å¤æœŸé—´ä¸èƒ½æ¸…ç† GIN 待处ç†åˆ—表。" -#: access/gin/ginfast.c:987 +#: access/gin/ginfast.c:1049 #, c-format -#| msgid "\"%s\" is not an index" msgid "\"%s\" is not a GIN index" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ª GIN 索引" -#: access/gin/ginfast.c:998 +#: access/gin/ginfast.c:1060 #, c-format -#| msgid "cannot access temporary tables of other sessions" msgid "cannot access temporary indexes of other sessions" msgstr "ä¸èƒ½è®¿é—®å…¶ä»–会è¯çš„临时索引" -#: access/gin/ginscan.c:409 +#: access/gin/ginscan.c:402 #, c-format msgid "old GIN indexes do not support whole-index scans nor searches for nulls" msgstr "è€çš„GINç´¢å¼•ä¸æ”¯æŒå®Œæ•´ç´¢å¼• (whole-index) 扫æï¼Œä¹Ÿä¸æ”¯æŒnull值æœç´¢" -#: access/gin/ginscan.c:410 +#: access/gin/ginscan.c:403 #, c-format msgid "To fix this, do REINDEX INDEX \"%s\"." msgstr "è¦è§£å†³æ­¤é—®é¢˜, 坿‰§è¡ŒREINDEX INDEX \"%s\"." -#: access/gin/ginvalidate.c:92 -#, c-format -msgid "" -"gin opfamily %s contains support procedure %s with cross-type registration" -msgstr "gin opfamily %s 包å«çš„æ”¯æŒè¿‡ç¨‹ %s 被注册在多ç§ç±»åž‹ä¸­" - -#: access/gin/ginvalidate.c:148 -#, c-format -msgid "gin opfamily %s contains function %s with invalid support number %d" -msgstr "gin opfamily %1$s 包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %3$d 的函数 %2$s" - -#: access/gin/ginvalidate.c:160 -#, c-format -msgid "" -"gin opfamily %s contains function %s with wrong signature for support number " -"%d" -msgstr "gin opfamily %1$s 包å«çš„函数 %2$s 对支æŒç¼–å· %3$d 具有错误的签å" - -#: access/gin/ginvalidate.c:179 -#, c-format -msgid "gin opfamily %s contains operator %s with invalid strategy number %d" -msgstr "gin opfamily %1$s 包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %3$d çš„æ“作符 %2$s" - -#: access/gin/ginvalidate.c:192 +#: access/gin/ginutil.c:139 executor/execExpr.c:1860 +#: utils/adt/arrayfuncs.c:3789 utils/adt/arrayfuncs.c:6416 +#: utils/adt/rowtypes.c:936 #, c-format -msgid "gin opfamily %s contains invalid ORDER BY specification for operator %s" -msgstr "gin opfamily %s åŒ…å«æ“作符 %s 的无效 ORDER BY 声明" - -#: access/gin/ginvalidate.c:205 -#, c-format -msgid "gin opfamily %s contains operator %s with wrong signature" -msgstr "gin opfamily %s 包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %s" +msgid "could not identify a comparison function for type %s" +msgstr "无法为类型 %s 确认一个比对函数" -#: access/gin/ginvalidate.c:246 +#: access/gin/ginvalidate.c:93 access/gist/gistvalidate.c:93 +#: access/hash/hashvalidate.c:99 access/spgist/spgvalidate.c:99 #, c-format -msgid "gin opclass %s is missing support function %d" -msgstr "gin opclass %s 缺少支æŒå‡½æ•° %d" +msgid "operator family \"%s\" of access method %s contains support function %s with different left and right input types" +msgstr "访问方法%2$sçš„è¿ç®—ç¬¦æ— \"%1$s\"åŒ…å«æ”¯æŒå‡½æ•°%3$s,具有ä¸åŒçš„å·¦å³è¾“入类型" -#: access/gin/ginvalidate.c:256 +#: access/gin/ginvalidate.c:257 #, c-format -msgid "gin opclass %s is missing support function %d or %d" -msgstr "gin opclass %s 缺少支æŒå‡½æ•° %d 或 %d" +msgid "operator class \"%s\" of access method %s is missing support function %d or %d" +msgstr "访问方法%2$sçš„è¿ç®—符类 \"%1$s\"缺少支æŒå‡½æ•° %3$d 或 %4$d" -#: access/gist/gist.c:692 access/gist/gistvacuum.c:258 +#: access/gist/gist.c:751 access/gist/gistvacuum.c:424 #, c-format msgid "index \"%s\" contains an inner tuple marked as invalid" msgstr "索引\"%s\"åŒ…å«æ— æ•ˆçš„内部元组" -#: access/gist/gist.c:694 access/gist/gistvacuum.c:260 +#: access/gist/gist.c:753 access/gist/gistvacuum.c:426 #, c-format -msgid "" -"This is caused by an incomplete page split at crash recovery before " -"upgrading to PostgreSQL 9.1." +msgid "This is caused by an incomplete page split at crash recovery before upgrading to PostgreSQL 9.1." msgstr "这是在å‡çº§åˆ°PostgreSQL 9.1之剿‰§è¡Œç¾é𾿢夿—¶ä¸å®Œå…¨çš„页分裂引起的." -#: access/gist/gist.c:695 access/gist/gistutil.c:735 -#: access/gist/gistutil.c:746 access/gist/gistvacuum.c:261 -#: access/hash/hashutil.c:172 access/hash/hashutil.c:183 -#: access/hash/hashutil.c:195 access/hash/hashutil.c:216 -#: access/nbtree/nbtpage.c:518 access/nbtree/nbtpage.c:529 +#: access/gist/gist.c:754 access/gist/gistutil.c:787 access/gist/gistutil.c:798 +#: access/gist/gistvacuum.c:427 access/hash/hashutil.c:241 +#: access/hash/hashutil.c:252 access/hash/hashutil.c:264 +#: access/hash/hashutil.c:285 access/nbtree/nbtpage.c:747 +#: access/nbtree/nbtpage.c:758 #, c-format msgid "Please REINDEX it." msgstr "请é‡å»ºç´¢å¼• (REINDEX)." -#: access/gist/gistbuild.c:249 +#: access/gist/gistbuild.c:253 #, c-format msgid "invalid value for \"buffering\" option" msgstr "\"buffering\"选项值无效" -#: access/gist/gistbuild.c:250 +#: access/gist/gistbuild.c:254 #, c-format msgid "Valid values are \"on\", \"off\", and \"auto\"." msgstr "有效值为\"on\", \"off\", 或 \"auto\"之一." -#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:209 +#: access/gist/gistbuildbuffers.c:778 utils/sort/logtape.c:255 #, c-format msgid "could not write block %ld of temporary file: %m" msgstr "æ— æ³•å†™å…¥ä¸´æ—¶æ–‡ä»¶å— %ld: %m" @@ -675,472 +689,482 @@ msgstr "为索引\"%2$s\"的第%1$d列执行picksplit方法失败" #: access/gist/gistsplit.c:448 #, c-format -msgid "" -"The index is not optimal. To optimize it, contact a developer, or try to use " -"the column as the second one in the CREATE INDEX command." -msgstr "" -"索引没有优化.为了优化索引,请è”系开å‘人员,或者在CREATE INDEX命令中å°è¯•在这一列" -"上创建第二个索引." +msgid "The index is not optimal. To optimize it, contact a developer, or try to use the column as the second one in the CREATE INDEX command." +msgstr "索引没有优化.为了优化索引,请è”系开å‘人员,或者在CREATE INDEX命令中å°è¯•在这一列上创建第二个索引." -#: access/gist/gistutil.c:732 access/hash/hashutil.c:169 -#: access/nbtree/nbtpage.c:515 +#: access/gist/gistutil.c:784 access/hash/hashutil.c:238 +#: access/nbtree/nbtpage.c:744 #, c-format msgid "index \"%s\" contains unexpected zero page at block %u" msgstr "索引\"%s\"在å—%uä¸ŠåŒ…å«æœªæœŸæœ›çš„零页" -#: access/gist/gistutil.c:743 access/hash/hashutil.c:180 -#: access/hash/hashutil.c:192 access/nbtree/nbtpage.c:526 +#: access/gist/gistutil.c:795 access/hash/hashutil.c:249 +#: access/hash/hashutil.c:261 access/nbtree/nbtpage.c:755 #, c-format msgid "index \"%s\" contains corrupted page at block %u" msgstr "索引\"%s\"在å—%u上包å«å·²æŸå的页" -#: access/gist/gistvalidate.c:92 -#, c-format -msgid "" -"gist opfamily %s contains support procedure %s with cross-type registration" -msgstr "gist opfamily %s 包å«å…·æœ‰è·¨ç±»åž‹æ³¨å†Œçš„æ”¯æŒè¿‡ç¨‹ %s" - -#: access/gist/gistvalidate.c:145 -#, c-format -msgid "gist opfamily %s contains function %s with invalid support number %d" -msgstr "gist opfamily %1$s 包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %3$d 的函数 %2$s" - -#: access/gist/gistvalidate.c:157 +#: access/gist/gistvalidate.c:196 #, c-format -msgid "" -"gist opfamily %s contains function %s with wrong signature for support " -"number %d" -msgstr "gist opfamily %1$s 包å«çš„函数 %2$s 对支æŒç¼–å· %3$d 具有错误的签å" - -#: access/gist/gistvalidate.c:177 -#, c-format -msgid "gist opfamily %s contains operator %s with invalid strategy number %d" -msgstr "gist opfamily %1$s 包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %3$d çš„æ“作符 %2$s" - -#: access/gist/gistvalidate.c:195 -#, c-format -msgid "" -"gist opfamily %s contains unsupported ORDER BY specification for operator %s" -msgstr "gist opfamily %s åŒ…å«æ“作符 %s çš„ä¸æ”¯æŒçš„ ORDER BY 声明" +msgid "operator family \"%s\" of access method %s contains unsupported ORDER BY specification for operator %s" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\"åŒ…å«æ“作符 %3$s çš„ä¸æ”¯æŒçš„ ORDER BY 声明" -#: access/gist/gistvalidate.c:206 +#: access/gist/gistvalidate.c:207 #, c-format -msgid "" -"gist opfamily %s contains incorrect ORDER BY opfamily specification for " -"operator %s" -msgstr "gist opfamily %s åŒ…å«æ“作符 %s çš„ä¸æ­£ç¡®çš„ ORDER BY opfamily 声明" +msgid "operator family \"%s\" of access method %s contains incorrect ORDER BY opfamily specification for operator %s" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\"åŒ…å«æ“作符 %3$s çš„ä¸æ­£ç¡®çš„ ORDER BY opfamily 声明" -#: access/gist/gistvalidate.c:225 -#, c-format -msgid "gist opfamily %s contains operator %s with wrong signature" -msgstr "gist opfamily %s 包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %s" +#: access/hash/hashfunc.c:255 access/hash/hashfunc.c:311 +#: utils/adt/varchar.c:992 utils/adt/varchar.c:1052 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for string comparison" +msgid "could not determine which collation to use for string hashing" +msgstr "æ— æ³•ç¡®å®šå­—ç¬¦ä¸²æ¯”è¾ƒä¸­ä½¿ç”¨å“ªç§æŽ’åºè§„则" -#: access/gist/gistvalidate.c:264 +#: access/hash/hashfunc.c:256 access/hash/hashfunc.c:312 catalog/heap.c:678 +#: commands/createas.c:207 commands/createas.c:491 commands/indexcmds.c:1697 +#: commands/tablecmds.c:15089 commands/view.c:105 regex/regc_pg_locale.c:263 +#: utils/adt/formatting.c:1571 utils/adt/formatting.c:1694 +#: utils/adt/formatting.c:1818 utils/adt/like.c:194 +#: utils/adt/like_support.c:965 utils/adt/varchar.c:734 utils/adt/varchar.c:993 +#: utils/adt/varchar.c:1053 utils/adt/varlena.c:1456 #, c-format -msgid "gist opclass %s is missing support function %d" -msgstr "gist opclass %s 缺少支æŒå‡½æ•° %d" +msgid "Use the COLLATE clause to set the collation explicitly." +msgstr "使用COLLATEå­å¥æ¥æ˜¾ç¤ºè®¾ç½®æŽ’åºè§„则." -#: access/hash/hashinsert.c:69 +#: access/hash/hashinsert.c:82 #, c-format msgid "index row size %zu exceeds hash maximum %zu" msgstr "ç´¢å¼•è¡Œå¤§å° %zu 超过散列最大值 %zu" -#: access/hash/hashinsert.c:71 access/spgist/spgdoinsert.c:1919 -#: access/spgist/spgutils.c:707 +#: access/hash/hashinsert.c:84 access/spgist/spgdoinsert.c:1961 +#: access/spgist/spgutils.c:752 #, c-format msgid "Values larger than a buffer page cannot be indexed." msgstr "大于一个缓冲页的值无法用于创建索引." -#: access/hash/hashovfl.c:548 +#: access/hash/hashovfl.c:87 +#, c-format +msgid "invalid overflow block number %u" +msgstr "无效的溢出å—ç¼–å·%u" + +#: access/hash/hashovfl.c:283 access/hash/hashpage.c:453 #, c-format msgid "out of overflow pages in hash index \"%s\"" msgstr "散列索引 \"%s\" 中页溢出" -#: access/hash/hashsearch.c:153 +#: access/hash/hashsearch.c:315 #, c-format msgid "hash indexes do not support whole-index scans" msgstr "æ•£åˆ—ç´¢å¼•ä¸æ”¯æŒå®Œæ•´ç´¢å¼• (whole-index) 扫æ" -#: access/hash/hashutil.c:208 +#: access/hash/hashutil.c:277 #, c-format msgid "index \"%s\" is not a hash index" msgstr "索引 \"%s\" 䏿˜¯ä¸€ä¸ªæ•£åˆ—索引" -#: access/hash/hashutil.c:214 +#: access/hash/hashutil.c:283 #, c-format msgid "index \"%s\" has wrong hash version" msgstr "索引 \"%s\" 有错误的散列版本" -#: access/hash/hashvalidate.c:98 -#, c-format -msgid "" -"hash opfamily %s contains support procedure %s with cross-type registration" -msgstr "hash opfamily %s 包å«å…·æœ‰è·¨ç±»åž‹æ³¨å†Œçš„æ”¯æŒè¿‡ç¨‹ %s" - -#: access/hash/hashvalidate.c:113 -#, c-format -msgid "" -"hash opfamily %s contains function %s with wrong signature for support " -"number %d" -msgstr "hash opfamily %1$s 包å«çš„函数 %2$s 对支æŒç¼–å· %3$d 具有错误的签å" - -#: access/hash/hashvalidate.c:130 -#, c-format -msgid "hash opfamily %s contains function %s with invalid support number %d" -msgstr "hash opfamily %1$s 包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %3$d 的函数 %2$s" - -#: access/hash/hashvalidate.c:151 -#, c-format -msgid "hash opfamily %s contains operator %s with invalid strategy number %d" -msgstr "hash opfamily %1$s 包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %3$d çš„æ“作符 %2$s" - -#: access/hash/hashvalidate.c:164 -#, c-format -msgid "" -"hash opfamily %s contains invalid ORDER BY specification for operator %s" -msgstr "hash opfamily %s åŒ…å«æ“作符 %s 的无效 ORDER BY 声明" - -#: access/hash/hashvalidate.c:177 -#, c-format -msgid "hash opfamily %s contains operator %s with wrong signature" -msgstr "hash opfamily %s 包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %s" - -#: access/hash/hashvalidate.c:189 -#, c-format -msgid "hash opfamily %s lacks support function for operator %s" -msgstr "hash opfamily %s 缺少æ“作符 %s 的支æŒå‡½æ•°" - -#: access/hash/hashvalidate.c:217 -#, c-format -msgid "hash opfamily %s is missing operator(s) for types %s and %s" -msgstr "hash opfamily %s 缺少类型 %s å’Œ %s çš„æ“作符" - -#: access/hash/hashvalidate.c:231 +#: access/hash/hashvalidate.c:191 #, c-format -msgid "hash opclass %s is missing operator(s)" -msgstr "hash opclass %s 缺少æ“作符" +msgid "operator family \"%s\" of access method %s lacks support function for operator %s" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\"缺少æ“作符 %3$s 的支æŒå‡½æ•°" -#: access/hash/hashvalidate.c:247 +#: access/hash/hashvalidate.c:249 access/nbtree/nbtvalidate.c:266 #, c-format -msgid "hash opfamily %s is missing cross-type operator(s)" -msgstr "hash opclass %s 缺少跨类型æ“作符" +msgid "operator family \"%s\" of access method %s is missing cross-type operator(s)" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\"缺少跨类型æ“作符" -#: access/heap/heapam.c:1137 access/heap/heapam.c:1189 +#: access/heap/heapam.c:1304 #, c-format -msgid "cannot access temporary tables during a parallel operation" -msgstr "ä¸èƒ½åœ¨å¹¶è¡Œæ“作期间访问临时表" - -#: access/heap/heapam.c:1306 access/heap/heapam.c:1334 -#: access/heap/heapam.c:1366 catalog/aclchk.c:1755 -#, c-format -msgid "\"%s\" is an index" -msgstr "\"%s\" 是一个索引" - -#: access/heap/heapam.c:1311 access/heap/heapam.c:1339 -#: access/heap/heapam.c:1371 catalog/aclchk.c:1762 commands/tablecmds.c:8986 -#: commands/tablecmds.c:12044 -#, c-format -msgid "\"%s\" is a composite type" -msgstr "\"%s\" 为混和类型" +msgid "only heap AM is supported" +msgstr "" -#: access/heap/heapam.c:2580 +#: access/heap/heapam.c:2077 #, c-format -msgid "cannot insert tuples during a parallel operation" +msgid "cannot insert tuples in a parallel worker" msgstr "无法在并行æ“作期间æ’入元组" -#: access/heap/heapam.c:3030 +#: access/heap/heapam.c:2487 #, c-format msgid "cannot delete tuples during a parallel operation" msgstr "无法在并行æ“作期间删除元组" -#: access/heap/heapam.c:3076 +#: access/heap/heapam.c:2533 #, c-format msgid "attempted to delete invisible tuple" msgstr "试图删除ä¸å¯è§å…ƒç»„" -#: access/heap/heapam.c:3503 access/heap/heapam.c:6063 +#: access/heap/heapam.c:2954 access/heap/heapam.c:5711 #, c-format msgid "cannot update tuples during a parallel operation" msgstr "无法在并行æ“作期间更新元组" -#: access/heap/heapam.c:3625 +#: access/heap/heapam.c:3087 #, c-format msgid "attempted to update invisible tuple" msgstr "试图更新ä¸å¯è§å…ƒç»„" -#: access/heap/heapam.c:4884 access/heap/heapam.c:4922 -#: access/heap/heapam.c:5145 executor/execMain.c:2304 +#: access/heap/heapam.c:4375 access/heap/heapam.c:4413 +#: access/heap/heapam.c:4670 access/heap/heapam_handler.c:454 #, c-format msgid "could not obtain lock on row in relation \"%s\"" msgstr "无法在关系 \"%s\"中的记录上获得é”" -#: access/heap/hio.c:325 access/heap/rewriteheap.c:666 +#: access/heap/heapam_handler.c:405 +#, c-format +msgid "tuple to be locked was already moved to another partition due to concurrent update" +msgstr "ç”±äºŽåŒæ—¶æ›´æ–°ï¼Œè¦é”定的元组已移动到å¦ä¸€ä¸ªåˆ†åŒº" + +#: access/heap/hio.c:345 access/heap/rewriteheap.c:681 #, c-format msgid "row is too big: size %zu, maximum size %zu" msgstr "行太大: 尺寸 %zu, 最大值 %zu" -#: access/heap/rewriteheap.c:925 +#: access/heap/rewriteheap.c:941 #, c-format msgid "could not write to file \"%s\", wrote %d of %d: %m" msgstr "无法往文件 \"%s\" åç§»é‡ %d, %d 写入: %m" -#: access/heap/rewriteheap.c:965 access/heap/rewriteheap.c:1177 -#: access/heap/rewriteheap.c:1274 access/transam/timeline.c:407 -#: access/transam/timeline.c:483 access/transam/xlog.c:3060 -#: access/transam/xlog.c:3222 replication/logical/snapbuild.c:1607 -#: replication/slot.c:1077 replication/slot.c:1162 storage/file/fd.c:624 -#: storage/file/fd.c:3052 storage/smgr/md.c:1031 storage/smgr/md.c:1262 -#: storage/smgr/md.c:1435 utils/misc/guc.c:6881 -#, c-format -msgid "could not fsync file \"%s\": %m" -msgstr "无法 fsync 文件 \"%s\": %m" - -#: access/heap/rewriteheap.c:1020 access/heap/rewriteheap.c:1140 -#: access/transam/timeline.c:315 access/transam/timeline.c:461 -#: access/transam/xlog.c:3016 access/transam/xlog.c:3165 -#: access/transam/xlog.c:10124 access/transam/xlog.c:10162 -#: access/transam/xlog.c:10489 postmaster/postmaster.c:4351 -#: replication/logical/origin.c:542 replication/slot.c:1034 -#: storage/file/copydir.c:162 storage/smgr/md.c:320 utils/time/snapmgr.c:1175 +#: access/heap/rewriteheap.c:1035 access/heap/rewriteheap.c:1154 +#: access/transam/timeline.c:314 access/transam/timeline.c:468 +#: access/transam/xlog.c:3253 access/transam/xlog.c:3425 +#: access/transam/xlog.c:4545 access/transam/xlog.c:10527 +#: access/transam/xlog.c:10565 access/transam/xlog.c:10970 +#: access/transam/xlogfuncs.c:736 postmaster/postmaster.c:4524 +#: replication/logical/origin.c:575 replication/slot.c:1261 +#: storage/file/copydir.c:167 storage/smgr/md.c:204 utils/time/snapmgr.c:1299 #, c-format msgid "could not create file \"%s\": %m" msgstr "无法创建文件 \"%s\": %m" -#: access/heap/rewriteheap.c:1149 +#: access/heap/rewriteheap.c:1164 #, c-format msgid "could not truncate file \"%s\" to %u: %m" msgstr "无法将文件\"%s\"截断为%u:%m" -#: access/heap/rewriteheap.c:1156 replication/walsender.c:481 -#: storage/smgr/md.c:1847 +#: access/heap/rewriteheap.c:1172 replication/walsender.c:493 +#: storage/smgr/md.c:1245 #, c-format msgid "could not seek to end of file \"%s\": %m" msgstr "无法查找到文件\"%s\"的末端: %m" -#: access/heap/rewriteheap.c:1167 access/transam/timeline.c:367 -#: access/transam/timeline.c:401 access/transam/timeline.c:477 -#: access/transam/xlog.c:3051 access/transam/xlog.c:3215 -#: postmaster/postmaster.c:4361 postmaster/postmaster.c:4371 -#: replication/logical/origin.c:551 replication/logical/origin.c:587 -#: replication/logical/origin.c:603 replication/logical/snapbuild.c:1591 -#: replication/slot.c:1063 storage/file/copydir.c:187 -#: utils/init/miscinit.c:1228 utils/init/miscinit.c:1237 -#: utils/init/miscinit.c:1244 utils/misc/guc.c:6842 utils/misc/guc.c:6873 -#: utils/misc/guc.c:8715 utils/misc/guc.c:8729 utils/time/snapmgr.c:1180 -#: utils/time/snapmgr.c:1187 +#: access/heap/rewriteheap.c:1189 access/transam/timeline.c:369 +#: access/transam/timeline.c:408 access/transam/timeline.c:485 +#: access/transam/xlog.c:3309 access/transam/xlog.c:3481 +#: access/transam/xlog.c:4557 postmaster/postmaster.c:4534 +#: postmaster/postmaster.c:4544 replication/logical/origin.c:587 +#: replication/logical/origin.c:629 replication/logical/origin.c:648 +#: replication/logical/snapbuild.c:1627 replication/slot.c:1295 +#: storage/file/copydir.c:207 utils/init/miscinit.c:1345 +#: utils/init/miscinit.c:1356 utils/init/miscinit.c:1364 utils/misc/guc.c:7801 +#: utils/misc/guc.c:7832 utils/misc/guc.c:9760 utils/misc/guc.c:9774 +#: utils/time/snapmgr.c:1304 utils/time/snapmgr.c:1311 #, c-format msgid "could not write to file \"%s\": %m" msgstr "无法写入文件 \"%s\": %m" -#: access/heap/rewriteheap.c:1250 access/transam/xlog.c:10356 -#: access/transam/xlogarchive.c:114 access/transam/xlogarchive.c:468 -#: replication/logical/origin.c:529 replication/logical/reorderbuffer.c:2611 -#: replication/logical/reorderbuffer.c:2668 -#: replication/logical/snapbuild.c:1535 replication/logical/snapbuild.c:1910 -#: replication/slot.c:1136 storage/ipc/dsm.c:326 storage/smgr/md.c:420 -#: storage/smgr/md.c:469 storage/smgr/md.c:1382 +#: access/heap/rewriteheap.c:1279 access/transam/twophase.c:1661 +#: access/transam/xlogarchive.c:112 access/transam/xlogarchive.c:459 +#: postmaster/postmaster.c:1277 postmaster/syslogger.c:1466 +#: replication/logical/origin.c:563 replication/logical/reorderbuffer.c:2814 +#: replication/logical/snapbuild.c:1569 replication/logical/snapbuild.c:2011 +#: replication/slot.c:1381 storage/file/fd.c:704 storage/file/fd.c:3000 +#: storage/file/fd.c:3062 storage/file/reinit.c:255 storage/ipc/dsm.c:307 +#: storage/smgr/md.c:298 storage/smgr/md.c:354 storage/sync/sync.c:210 +#: utils/time/snapmgr.c:1644 #, c-format msgid "could not remove file \"%s\": %m" msgstr "无法删除文件 \"%s\": %m" -#: access/heap/rewriteheap.c:1264 access/transam/timeline.c:111 -#: access/transam/timeline.c:236 access/transam/timeline.c:334 -#: access/transam/xlog.c:2992 access/transam/xlog.c:3109 -#: access/transam/xlog.c:3150 access/transam/xlog.c:3423 -#: access/transam/xlog.c:3501 access/transam/xlogutils.c:705 -#: replication/basebackup.c:401 replication/basebackup.c:1162 -#: replication/logical/origin.c:658 replication/logical/reorderbuffer.c:2141 -#: replication/logical/reorderbuffer.c:2381 -#: replication/logical/reorderbuffer.c:3059 -#: replication/logical/snapbuild.c:1584 replication/logical/snapbuild.c:1668 -#: replication/slot.c:1151 replication/walsender.c:474 -#: replication/walsender.c:2104 storage/file/copydir.c:155 -#: storage/file/fd.c:607 storage/file/fd.c:2964 storage/file/fd.c:3031 -#: storage/smgr/md.c:602 utils/error/elog.c:1870 utils/init/miscinit.c:1163 -#: utils/init/miscinit.c:1284 utils/init/miscinit.c:1362 utils/misc/guc.c:7101 -#: utils/misc/guc.c:7134 -#, c-format -msgid "could not open file \"%s\": %m" -msgstr "无法打开文件 \"%s\": %m" +#: access/heap/vacuumlazy.c:267 +#, fuzzy, c-format +#| msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgid "skipping redundant vacuum to prevent wraparound of table \"%s.%s.%s\"" +msgstr "autovacuum: 正在删除é—留的临时表\"%s.%s.%s\"" -#: access/index/amapi.c:69 commands/amcmds.c:164 -#, c-format -#| msgid "access method \"%s\" does not exist" -msgid "access method \"%s\" is not of type %s" -msgstr "访问方法 \"%s\" 䏿˜¯ç±»åž‹ %s çš„" +#: access/heap/vacuumlazy.c:405 +#, fuzzy, c-format +#| msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgid "automatic aggressive vacuum to prevent wraparound of table \"%s.%s.%s\": index scans: %d\n" +msgstr "自动积æžçš„æ¸…ç†è¡¨\"%s.%s.%s\":索引扫æï¼š%d\n" -#: access/index/amapi.c:78 +#: access/heap/vacuumlazy.c:410 #, c-format -#| msgid "access method \"%s\" does not exist" -msgid "index access method \"%s\" does not have a handler" -msgstr "索引访问方法 \"%s\" 没有处ç†å™¨" +msgid "automatic aggressive vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "自动积æžçš„æ¸…ç†è¡¨\"%s.%s.%s\":索引扫æï¼š%d\n" -#: access/index/indexam.c:155 catalog/objectaddress.c:1196 -#: commands/indexcmds.c:1799 commands/tablecmds.c:241 -#: commands/tablecmds.c:12035 +#: access/heap/vacuumlazy.c:412 #, c-format -msgid "\"%s\" is not an index" -msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç´¢å¼•" +msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" +msgstr "自动清ç†è¡¨\"%s.%s.%s\":索引扫æï¼š%d\n" -#: access/nbtree/nbtinsert.c:427 +#: access/heap/vacuumlazy.c:419 #, c-format -msgid "duplicate key value violates unique constraint \"%s\"" -msgstr "é‡å¤é”®è¿å唯一约æŸ\"%s\"" +msgid "pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" +msgstr "页é¢ï¼š%u 被移除,%u ä¿ç•™ï¼Œ%u 由于被å ç”¨è€Œè·³è¿‡ï¼Œ%u 被跳过的已被冻结\n" -#: access/nbtree/nbtinsert.c:429 +#: access/heap/vacuumlazy.c:425 #, c-format -msgid "Key %s already exists." -msgstr "键值\"%s\" å·²ç»å­˜åœ¨" +msgid "tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable, oldest xmin: %u\n" +msgstr "元组:%.0f被移除,%.0fä¿ç•™ï¼Œ%.0få·²ç»æ­»äº¡ä½†è¿˜ä¸èƒ½è¢«ç§»é™¤,最è€xmin: %u\n" -#: access/nbtree/nbtinsert.c:496 +#: access/heap/vacuumlazy.c:431 #, c-format -msgid "failed to re-find tuple within index \"%s\"" -msgstr "在索引\"%s\"䏭釿–°å¯»æ‰¾å…ƒç»„失败" +msgid "buffer usage: %d hits, %d misses, %d dirtied\n" +msgstr "缓冲区使用:%d次命中,%d次失效,%d次è„\n" -#: access/nbtree/nbtinsert.c:498 +#: access/heap/vacuumlazy.c:435 #, c-format -msgid "This may be because of a non-immutable index expression." -msgstr "è¿™å¯èƒ½æ˜¯ç”±äºŽä¸€ä¸ªéžä¸å¯æ”¹å˜çš„索引表达å¼å¼•èµ·çš„" +msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" +msgstr "å¹³å‡è¯»å–率:%.3f MB/s,平å‡å†™å…¥çŽ‡ï¼š%.3f MB/s\n" -#: access/nbtree/nbtinsert.c:578 access/nbtree/nbtsort.c:491 +#: access/heap/vacuumlazy.c:437 #, c-format -msgid "" -"Values larger than 1/3 of a buffer page cannot be indexed.\n" -"Consider a function index of an MD5 hash of the value, or use full text " -"indexing." -msgstr "" -"值大于缓冲页的1/3,ä¸èƒ½å»ºç´¢å¼•.\n" -"请考虑这个值MD5哈希函数索引,或者使用全文索引." +msgid "system usage: %s" +msgstr "系统用法:%s" -#: access/nbtree/nbtpage.c:168 access/nbtree/nbtpage.c:371 -#: access/nbtree/nbtpage.c:458 parser/parse_utilcmd.c:1715 +#: access/heap/vacuumlazy.c:533 #, c-format -msgid "index \"%s\" is not a btree" -msgstr "索引 \"%s\" 䏿˜¯ä¸€ä¸ª btree" +msgid "aggressively vacuuming \"%s.%s\"" +msgstr "æ­£åœ¨ç§¯æžæ¸…ç†\"%s.%s\"" -#: access/nbtree/nbtpage.c:174 access/nbtree/nbtpage.c:377 -#: access/nbtree/nbtpage.c:464 +#: access/heap/vacuumlazy.c:538 commands/cluster.c:910 #, c-format -msgid "version mismatch in index \"%s\": file version %d, code version %d" -msgstr "在索引 \"%s\" 中版本ä¸åŒ¹é…: 文件版本 %d, 代ç ç‰ˆæœ¬ %d" +msgid "vacuuming \"%s.%s\"" +msgstr "æ­£åœ¨æ¸…ç† (vacuum) \"%s.%s\"" -#: access/nbtree/nbtpage.c:1152 +#: access/heap/vacuumlazy.c:1476 #, c-format -msgid "index \"%s\" contains a half-dead internal page" -msgstr "索引 \"%s\" 包å«ä¸€ä¸ªåŠæ­»çš„内部页." +msgid "\"%s\": removed %.0f row versions in %u pages" +msgstr "\"%1$s\": 在%3$u页中已删除%2$.0f行版本å·" -#: access/nbtree/nbtpage.c:1154 +#: access/heap/vacuumlazy.c:1486 #, c-format -msgid "" -"This can be caused by an interrupted VACUUM in version 9.3 or older, before " -"upgrade. Please REINDEX it." -msgstr "" -"å¯èƒ½æ˜¯ç”±äºŽå‡çº§ä¹‹å‰, 使用了9.3或者更è€çš„版本里的VACUUM命令并产生中断造æˆçš„. 请" -"为它é‡å»ºç´¢å¼•." +msgid "%.0f dead row versions cannot be removed yet, oldest xmin: %u\n" +msgstr "%.0f的死亡行版本还ä¸èƒ½è¢«ç§»é™¤,最è€çš„xmin: %u\n" -#: access/nbtree/nbtvalidate.c:100 -#, c-format -msgid "btree opfamily %s contains function %s with invalid support number %d" -msgstr "btree opfamily %1$s 包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %3$d 的函数 %2$s" +#: access/heap/vacuumlazy.c:1488 +#, fuzzy, c-format +#| msgid "There were %.0f unused item pointers.\n" +msgid "There were %.0f unused item identifiers.\n" +msgstr "有%.0f个未用的项指针。\n" -#: access/nbtree/nbtvalidate.c:112 +#: access/heap/vacuumlazy.c:1490 #, c-format -msgid "" -"btree opfamily %s contains function %s with wrong signature for support " -"number %d" -msgstr "btree opfamily %1$s 包å«çš„函数 %2$s 对支æŒç¼–å· %3$d 具有错误的签å" +msgid "Skipped %u page due to buffer pins, " +msgid_plural "Skipped %u pages due to buffer pins, " +msgstr[0] "由于缓冲区å ç”¨è€Œè·³è¿‡%u个页é¢," -#: access/nbtree/nbtvalidate.c:132 +#: access/heap/vacuumlazy.c:1494 #, c-format -msgid "btree opfamily %s contains operator %s with invalid strategy number %d" -msgstr "btree opfamily %1$s 包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %3$d çš„æ“作符 %2$s" +msgid "%u frozen page.\n" +msgid_plural "%u frozen pages.\n" +msgstr[0] "%u个冻结页é¢.\n" -#: access/nbtree/nbtvalidate.c:145 +#: access/heap/vacuumlazy.c:1498 #, c-format -msgid "" -"btree opfamily %s contains invalid ORDER BY specification for operator %s" -msgstr "btree opfamily %s åŒ…å«æ“作符 %s 的无效 ORDER BY 声明" +msgid "%u page is entirely empty.\n" +msgid_plural "%u pages are entirely empty.\n" +msgstr[0] "%u 个页é¢å®Œå…¨ä¸ºç©ºã€‚\n" -#: access/nbtree/nbtvalidate.c:158 +#: access/heap/vacuumlazy.c:1502 commands/indexcmds.c:3276 +#: commands/indexcmds.c:3294 #, c-format -msgid "btree opfamily %s contains operator %s with wrong signature" -msgstr "btree opfamily %s 包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %s" +msgid "%s." +msgstr "%s" -#: access/nbtree/nbtvalidate.c:200 +#: access/heap/vacuumlazy.c:1505 #, c-format -msgid "btree opfamily %s is missing operator(s) for types %s and %s" -msgstr "btree opfamily %s 缺少类型 %s å’Œ %s çš„æ“作符" +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages" +msgstr "\"%1$s\": 在超出%5$u页的%4$u中找到å¯åˆ é™¤ç‰ˆæœ¬å·%2$.0f, ä¸å¯åˆ é™¤çš„版本å·%3$.0f" -#: access/nbtree/nbtvalidate.c:210 +#: access/heap/vacuumlazy.c:1574 #, c-format -msgid "btree opfamily %s is missing support function for types %s and %s" -msgstr "btree opfamily %s 缺少类型 %s å’Œ %s 的支æŒå‡½æ•°" +msgid "\"%s\": removed %d row versions in %d pages" +msgstr "\"%1$s\": 在%3$d个页中已删除%2$d记录版本" -#: access/nbtree/nbtvalidate.c:224 +#: access/heap/vacuumlazy.c:1765 #, c-format -msgid "btree opclass %s is missing operator(s)" -msgstr "btree opclass %s 缺少æ“作符" +msgid "scanned index \"%s\" to remove %d row versions" +msgstr "扫æç´¢å¼•\"%s\"æ¥åˆ é™¤%d记录版本" -#: access/nbtree/nbtvalidate.c:241 +#: access/heap/vacuumlazy.c:1818 #, c-format -msgid "btree opfamily %s is missing cross-type operator(s)" -msgstr "btree opfamily %s 缺少跨类型æ“作符" +msgid "index \"%s\" now contains %.0f row versions in %u pages" +msgstr "索引\"%1$s\"在%3$u个页中包å«äº†è¡Œç‰ˆæœ¬å·%2$.0f" -#: access/spgist/spgutils.c:704 +#: access/heap/vacuumlazy.c:1822 #, c-format -msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" -msgstr "SP-GiST内部元组大å°%zu超出最大值%zu" +msgid "" +"%.0f index row versions were removed.\n" +"%u index pages have been deleted, %u are currently reusable.\n" +"%s." +msgstr "" +"索引行版本%.0f被删除.\n" +"%u个索引页已ç»è¢«åˆ é™¤,%u当å‰å¯é‡ç”¨.\n" +"%s." -#: access/spgist/spgvalidate.c:92 +#: access/heap/vacuumlazy.c:1920 #, c-format -msgid "" -"spgist opfamily %s contains support procedure %s with cross-type registration" -msgstr "spgist opfamily %s 包å«å…·æœ‰è·¨ç±»åž‹æ³¨å†Œçš„æ”¯æŒè¿‡ç¨‹ %s" +msgid "\"%s\": stopping truncate due to conflicting lock request" +msgstr "\"%s\":由于与é”请求相冲çªï¼Œåœæ­¢æˆªæ–­æ“作" -#: access/spgist/spgvalidate.c:115 +#: access/heap/vacuumlazy.c:1985 #, c-format -msgid "spgist opfamily %s contains function %s with invalid support number %d" -msgstr "spgist opfamily %1$s 包å«å…·æœ‰æ— æ•ˆæ”¯æŒç¼–å· %3$d 的函数 %2$s" +msgid "\"%s\": truncated %u to %u pages" +msgstr "\"%s\": å°†%u截断到%u pages" -#: access/spgist/spgvalidate.c:127 +#: access/heap/vacuumlazy.c:2050 #, c-format -msgid "" -"spgist opfamily %s contains function %s with wrong signature for support " -"number %d" -msgstr "spgist opfamily %1$s 包å«çš„函数 %2$s 对支æŒç¼–å· %3$d 具有错误的签å" +msgid "\"%s\": suspending truncate due to conflicting lock request" +msgstr "\"%s\":由于与é”请求相冲çªï¼Œæš‚åœæˆªæ–­æ“作" -#: access/spgist/spgvalidate.c:146 +#: access/index/amapi.c:83 commands/amcmds.c:167 #, c-format -msgid "spgist opfamily %s contains operator %s with invalid strategy number %d" -msgstr "spgist opfamily %1$s 包å«å…·æœ‰æ— æ•ˆç­–ç•¥ç¼–å· %3$d çš„æ“作符 %2$s" +msgid "access method \"%s\" is not of type %s" +msgstr "访问方法 \"%s\" 䏿˜¯ç±»åž‹ %s çš„" -#: access/spgist/spgvalidate.c:159 +#: access/index/amapi.c:99 +#, c-format +msgid "index access method \"%s\" does not have a handler" +msgstr "索引访问方法 \"%s\" 没有处ç†å™¨" + +#: access/index/indexam.c:136 catalog/objectaddress.c:1259 +#: commands/indexcmds.c:2407 commands/tablecmds.c:248 commands/tablecmds.c:272 +#: commands/tablecmds.c:14796 commands/tablecmds.c:16128 +#, c-format +msgid "\"%s\" is not an index" +msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç´¢å¼•" + +#: access/nbtree/nbtinsert.c:565 +#, c-format +msgid "duplicate key value violates unique constraint \"%s\"" +msgstr "é‡å¤é”®è¿å唯一约æŸ\"%s\"" + +#: access/nbtree/nbtinsert.c:567 +#, c-format +msgid "Key %s already exists." +msgstr "键值\"%s\" å·²ç»å­˜åœ¨" + +#: access/nbtree/nbtinsert.c:638 +#, c-format +msgid "failed to re-find tuple within index \"%s\"" +msgstr "在索引\"%s\"䏭釿–°å¯»æ‰¾å…ƒç»„失败" + +#: access/nbtree/nbtinsert.c:640 +#, c-format +msgid "This may be because of a non-immutable index expression." +msgstr "è¿™å¯èƒ½æ˜¯ç”±äºŽä¸€ä¸ªéžä¸å¯æ”¹å˜çš„索引表达å¼å¼•èµ·çš„" + +#: access/nbtree/nbtpage.c:171 access/nbtree/nbtpage.c:359 +#: access/nbtree/nbtpage.c:572 parser/parse_utilcmd.c:2117 +#, c-format +msgid "index \"%s\" is not a btree" +msgstr "索引 \"%s\" 䏿˜¯ä¸€ä¸ª btree" + +#: access/nbtree/nbtpage.c:178 access/nbtree/nbtpage.c:366 +#: access/nbtree/nbtpage.c:579 +#, c-format +msgid "version mismatch in index \"%s\": file version %d, current version %d, minimal supported version %d" +msgstr "在索引 \"%s\" 中版本ä¸åŒ¹é…: 文件版本 %d, 当å‰ç‰ˆæœ¬%d,最低支æŒç‰ˆæœ¬%d" + +#: access/nbtree/nbtpage.c:1388 +#, c-format +msgid "index \"%s\" contains a half-dead internal page" +msgstr "索引 \"%s\" 包å«ä¸€ä¸ªåŠæ­»çš„内部页." + +#: access/nbtree/nbtpage.c:1390 +#, c-format +msgid "This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it." +msgstr "å¯èƒ½æ˜¯ç”±äºŽå‡çº§ä¹‹å‰, 使用了9.3或者更è€çš„版本里的VACUUM命令并产生中断造æˆçš„. 请为它é‡å»ºç´¢å¼•." + +#: access/nbtree/nbtutils.c:2563 +#, fuzzy, c-format +#| msgid "index row size %zu exceeds maximum %zu for index \"%s\"" +msgid "index row size %zu exceeds btree version %u maximum %zu for index \"%s\"" +msgstr "ç´¢å¼•è¡Œçš„å¤§å° %1$zu 超过了索引\"%3$s\"所å…许的最大值%2$zu" + +#: access/nbtree/nbtutils.c:2569 +#, fuzzy, c-format +#| msgid "while deleting tuple (%u,%u) in relation \"%s\"" +msgid "Index row references tuple (%u,%u) in relation \"%s\"." +msgstr "当删除关系\"%3$s\"的元组(%1$u, %2$u)æ—¶" + +#: access/nbtree/nbtutils.c:2573 #, c-format msgid "" -"spgist opfamily %s contains invalid ORDER BY specification for operator %s" -msgstr "spgist opfamily %s åŒ…å«æ“作符 %s 的无效 ORDER BY 声明" +"Values larger than 1/3 of a buffer page cannot be indexed.\n" +"Consider a function index of an MD5 hash of the value, or use full text indexing." +msgstr "" +"值大于缓冲页的1/3,ä¸èƒ½å»ºç´¢å¼•.\n" +"请考虑这个值MD5哈希函数索引,或者使用全文索引." + +#: access/nbtree/nbtvalidate.c:236 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function for types %s and %s" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\" 缺少类型 %3$s å’Œ %4$s 的支æŒå‡½æ•°" + +#: access/spgist/spgutils.c:142 +#, c-format +msgid "compress method must be defined when leaf type is different from input type" +msgstr "当å¶ç±»åž‹ä¸Žè¾“入类型ä¸åŒæ—¶ï¼Œå¿…须定义压缩方法" -#: access/spgist/spgvalidate.c:172 +#: access/spgist/spgutils.c:749 #, c-format -msgid "spgist opfamily %s contains operator %s with wrong signature" -msgstr "spgist opfamily %s 包å«å…·æœ‰é”™è¯¯ç­¾åçš„æ“作符 %s" +msgid "SP-GiST inner tuple size %zu exceeds maximum %zu" +msgstr "SP-GiST内部元组大å°%zu超出最大值%zu" + +#: access/spgist/spgvalidate.c:276 +#, c-format +msgid "operator family \"%s\" of access method %s is missing support function %d for type %s" +msgstr "访问方法%1$sçš„è¿ç®—符æ—\"%2$s\"缺少类型 %4$s 的支æŒå‡½æ•° %3$d" -#: access/spgist/spgvalidate.c:200 +#: access/table/table.c:49 access/table/table.c:78 access/table/table.c:111 +#: catalog/aclchk.c:1832 #, c-format -msgid "spgist opfamily %s is missing operator(s) for types %s and %s" -msgstr "spgist opfamily %s 缺少类型 %s å’Œ %s çš„æ“作符" +msgid "\"%s\" is an index" +msgstr "\"%s\" 是一个索引" -#: access/spgist/spgvalidate.c:220 +#: access/table/table.c:54 access/table/table.c:83 access/table/table.c:116 +#: catalog/aclchk.c:1839 commands/tablecmds.c:11607 commands/tablecmds.c:14805 #, c-format -msgid "spgist opfamily %s is missing support function %d for type %s" -msgstr "spgist opfamily %1$s 缺少类型 %3$s 的支æŒå‡½æ•° %2$d" +msgid "\"%s\" is a composite type" +msgstr "\"%s\" 为混和类型" -#: access/spgist/spgvalidate.c:233 +#: access/table/tableam.c:236 +#, fuzzy, c-format +#| msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgid "tid (%u, %u) is not valid for relation \"%s\"" +msgstr "关系\"%s\"䏿˜¯å…³ç³»\"%s\"的分区" + +#: access/table/tableamapi.c:109 #, c-format -msgid "spgist opclass %s is missing operator(s)" -msgstr "spgist opclass %s 缺少æ“作符" +msgid "default_table_access_method may not be empty." +msgstr "" + +#: access/table/tableamapi.c:115 utils/misc/guc.c:11648 +#, fuzzy, c-format +#| msgid "recovery_target_name is too long (maximum %d characters)" +msgid "%s is too long (maximum %d characters)." +msgstr "recovery_target_name 值超长 (最大长度为 %d 个字符)" + +#: access/table/tableamapi.c:137 +#, fuzzy, c-format +#| msgid "access method \"%s\" does not exist" +msgid "table access method \"%s\" does not exist" +msgstr "è®¿é—®æ–¹å¼ \"%s\" ä¸å­˜åœ¨" + +#: access/table/tableamapi.c:142 +#, fuzzy, c-format +#| msgid "access method \"%s\" does not exist" +msgid "Table access method \"%s\" does not exist." +msgstr "è®¿é—®æ–¹å¼ \"%s\" ä¸å­˜åœ¨" -#: access/tablesample/bernoulli.c:152 access/tablesample/system.c:156 +#: access/tablesample/bernoulli.c:148 access/tablesample/system.c:152 #, c-format msgid "sample percentage must be between 0 and 100" msgstr "采样百分率必须ä½äºŽ0å’Œ100之间" @@ -1150,63 +1174,51 @@ msgstr "采样百分率必须ä½äºŽ0å’Œ100之间" msgid "cannot retrieve commit timestamp for transaction %u" msgstr "无法检索到事务%uçš„æäº¤æ—¶é—´æˆ³" -#: access/transam/commit_ts.c:385 +#: access/transam/commit_ts.c:393 #, c-format msgid "could not get commit timestamp data" msgstr "无法得到æäº¤æ—¶é—´æˆ³æ•°æ®" -#: access/transam/commit_ts.c:387 +#: access/transam/commit_ts.c:395 #, c-format -#| msgid "Make sure the configuration parameter \"%s\" is set." -msgid "" -"Make sure the configuration parameter \"%s\" is set on the master server." +msgid "Make sure the configuration parameter \"%s\" is set on the master server." msgstr "ç¡®ä¿åœ¨ä¸»æœåŠ¡å™¨ä¸Šé…ç½®å‚æ•° \"%s\" å·²ç»è¢«è®¾ç½®ã€‚" -#: access/transam/commit_ts.c:389 libpq/hba.c:1441 +#: access/transam/commit_ts.c:397 #, c-format msgid "Make sure the configuration parameter \"%s\" is set." msgstr "ç¡®ä¿é…ç½®å‚æ•°\"%s\"å·²ç»è¢«è®¾ç½®ã€‚" #: access/transam/multixact.c:1000 #, c-format -msgid "" -"database is not accepting commands that generate new MultiXactIds to avoid " -"wraparound data loss in database \"%s\"" -msgstr "" -"æ•°æ®åº“没有接收产生新的MultiXactIds的命令æ¥é¿å…在数æ®åº“\"%s\"中的é‡å æ•°æ®æŸå¤±" +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database \"%s\"" +msgstr "æ•°æ®åº“没有接收产生新的MultiXactIds的命令æ¥é¿å…在数æ®åº“\"%s\"中的é‡å æ•°æ®æŸå¤±" #: access/transam/multixact.c:1002 access/transam/multixact.c:1009 #: access/transam/multixact.c:1033 access/transam/multixact.c:1042 #, c-format msgid "" "Execute a database-wide VACUUM in that database.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "在数æ®åº“中执行数æ®åº“范围的VACUUM.\n" -"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好的事务." +"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好的事务, 或者删除旧的å¤åˆ¶æ§½." #: access/transam/multixact.c:1007 #, c-format -msgid "" -"database is not accepting commands that generate new MultiXactIds to avoid " -"wraparound data loss in database with OID %u" -msgstr "" -"æ•°æ®åº“没有接å—产生新的MultiXactIds的命令æ¥é¿å…在带有OID为%u的数æ®åº“中的é‡å æ•°" -"æ®æŸå¤±" +msgid "database is not accepting commands that generate new MultiXactIds to avoid wraparound data loss in database with OID %u" +msgstr "æ•°æ®åº“没有接å—产生新的MultiXactIds的命令æ¥é¿å…在带有OID为%u的数æ®åº“中的é‡å æ•°æ®æŸå¤±" -#: access/transam/multixact.c:1028 access/transam/multixact.c:2317 +#: access/transam/multixact.c:1028 access/transam/multixact.c:2318 #, c-format msgid "database \"%s\" must be vacuumed before %u more MultiXactId is used" -msgid_plural "" -"database \"%s\" must be vacuumed before %u more MultiXactIds are used" +msgid_plural "database \"%s\" must be vacuumed before %u more MultiXactIds are used" msgstr[0] "æ•°æ®åº“ \"%s\"必须在è¿è¡Œ%u个事务å‰è¿›è¡Œæ¸…ç†(vacuume)." -#: access/transam/multixact.c:1037 access/transam/multixact.c:2326 +#: access/transam/multixact.c:1037 access/transam/multixact.c:2327 #, c-format -msgid "" -"database with OID %u must be vacuumed before %u more MultiXactId is used" -msgid_plural "" -"database with OID %u must be vacuumed before %u more MultiXactIds are used" +msgid "database with OID %u must be vacuumed before %u more MultiXactId is used" +msgid_plural "database with OID %u must be vacuumed before %u more MultiXactIds are used" msgstr[0] "带有OID为%u的数æ®åº“必须在%u个MultiXactIds使用å‰è¿›è¡Œæ¸…ç†(vacuume)." #: access/transam/multixact.c:1098 @@ -1216,186 +1228,170 @@ msgstr "超过多事务\"æˆå‘˜\"é™åˆ¶" #: access/transam/multixact.c:1099 #, c-format -msgid "" -"This command would create a multixact with %u members, but the remaining " -"space is only enough for %u member." -msgid_plural "" -"This command would create a multixact with %u members, but the remaining " -"space is only enough for %u members." -msgstr[0] "" -"这个命令将创建一个具有%uæˆå‘˜çš„多事务,但是剩余的空间åªèƒ½ç”¨äºŽ%u个æˆå‘˜ã€‚" +msgid "This command would create a multixact with %u members, but the remaining space is only enough for %u member." +msgid_plural "This command would create a multixact with %u members, but the remaining space is only enough for %u members." +msgstr[0] "这个命令将创建一个具有%uæˆå‘˜çš„多事务,但是剩余的空间åªèƒ½ç”¨äºŽ%u个æˆå‘˜ã€‚" #: access/transam/multixact.c:1104 #, c-format -msgid "" -"Execute a database-wide VACUUM in database with OID %u with reduced " -"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " -"settings." -msgstr "" -"在具有缩å‡vacuum_multixact_freeze_min_ageå’Œvacuum_multixact_freeze_table_age" -"设置的数æ®åº“(OID是%u)中执行一次数æ®åº“范围的VACUUM。" +msgid "Execute a database-wide VACUUM in database with OID %u with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "在具有缩å‡vacuum_multixact_freeze_min_ageå’Œvacuum_multixact_freeze_table_age设置的数æ®åº“(OID是%u)中执行一次数æ®åº“范围的VACUUM。" #: access/transam/multixact.c:1135 #, c-format -msgid "" -"database with OID %u must be vacuumed before %d more multixact member is used" -msgid_plural "" -"database with OID %u must be vacuumed before %d more multixact members are " -"used" +msgid "database with OID %u must be vacuumed before %d more multixact member is used" +msgid_plural "database with OID %u must be vacuumed before %d more multixact members are used" msgstr[0] "OID为%u的数æ®åº“必须在%d以上个多事务æˆå‘˜è¢«ä½¿ç”¨å‰è¿›è¡Œæ¸…ç†ï¼ˆVACUUM)" #: access/transam/multixact.c:1140 #, c-format -msgid "" -"Execute a database-wide VACUUM in that database with reduced " -"vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age " -"settings." -msgstr "" -"在具有缩å‡vacuum_multixact_freeze_min_ageå’Œvacuum_multixact_freeze_table_age" -"设置的数æ®åº“中执行一次数æ®åº“范围的VACUUM。" +msgid "Execute a database-wide VACUUM in that database with reduced vacuum_multixact_freeze_min_age and vacuum_multixact_freeze_table_age settings." +msgstr "在具有缩å‡vacuum_multixact_freeze_min_ageå’Œvacuum_multixact_freeze_table_age设置的数æ®åº“中执行一次数æ®åº“范围的VACUUM。" -#: access/transam/multixact.c:1278 +#: access/transam/multixact.c:1277 #, c-format msgid "MultiXactId %u does no longer exist -- apparent wraparound" msgstr "MultiXactId的值%uä¸å†ä½¿ç”¨ -- 明显是回å·äº†" -#: access/transam/multixact.c:1286 +#: access/transam/multixact.c:1285 #, c-format msgid "MultiXactId %u has not been created yet -- apparent wraparound" msgstr "MultiXactId %u还没被创建 -- 有明显的é‡å " -#: access/transam/multixact.c:2267 +#: access/transam/multixact.c:2268 #, c-format msgid "MultiXactId wrap limit is %u, limited by database with OID %u" msgstr "MultiXactIdçš„å°è£…é™åˆ¶æ˜¯%u, é™åˆ¶äºŽOID为%u的数æ®åº“." -#: access/transam/multixact.c:2322 access/transam/multixact.c:2331 -#: access/transam/varsup.c:146 access/transam/varsup.c:153 -#: access/transam/varsup.c:384 access/transam/varsup.c:391 +#: access/transam/multixact.c:2323 access/transam/multixact.c:2332 +#: access/transam/varsup.c:149 access/transam/varsup.c:156 +#: access/transam/varsup.c:447 access/transam/varsup.c:454 #, c-format msgid "" -"To avoid a database shutdown, execute a database-wide VACUUM in that " -"database.\n" -"You might also need to commit or roll back old prepared transactions." +"To avoid a database shutdown, execute a database-wide VACUUM in that database.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "为了é¿å…关闭数æ®åº“,需è¦åœ¨æ•°æ®åº“中执行数æ®åº“范围的VACUUM.\n" -"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好的事务." +"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好的事务,或者删除旧的å¤åˆ¶æ§½." -#: access/transam/multixact.c:2601 +#: access/transam/multixact.c:2602 #, c-format msgid "oldest MultiXactId member is at offset %u" msgstr "最旧的 MultiXactId æˆå‘˜ä½äºŽåç§»é‡%u" -#: access/transam/multixact.c:2605 +#: access/transam/multixact.c:2606 #, c-format -msgid "" -"MultiXact member wraparound protections are disabled because oldest " -"checkpointed MultiXact %u does not exist on disk" -msgstr "" -"多事务æˆå‘˜å›žå·ä¿æŠ¤è¢«ç¦ç”¨ï¼Œå› ä¸ºæœ€æ—§çš„被åšè¿‡æ£€æŸ¥ç‚¹çš„多事务%u在ç£ç›˜ä¸Šä¸å­˜åœ¨" +msgid "MultiXact member wraparound protections are disabled because oldest checkpointed MultiXact %u does not exist on disk" +msgstr "多事务æˆå‘˜å›žå·ä¿æŠ¤è¢«ç¦ç”¨ï¼Œå› ä¸ºæœ€æ—§çš„被åšè¿‡æ£€æŸ¥ç‚¹çš„多事务%u在ç£ç›˜ä¸Šä¸å­˜åœ¨" -#: access/transam/multixact.c:2627 +#: access/transam/multixact.c:2628 #, c-format msgid "MultiXact member wraparound protections are now enabled" msgstr "多事务æˆå‘˜å›žå·ä¿æŠ¤çŽ°åœ¨è¢«å¯ç”¨ã€‚" -#: access/transam/multixact.c:2629 +#: access/transam/multixact.c:2631 #, c-format msgid "MultiXact member stop limit is now %u based on MultiXact %u" msgstr "多事务æˆå‘˜åœæ­¢é™åˆ¶çŽ°åœ¨æ˜¯%u,这是基于多事务%u得出的" -#: access/transam/multixact.c:3009 +#: access/transam/multixact.c:3011 #, c-format -msgid "" -"oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" +msgid "oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation" msgstr "没有找到最旧的多事务%u,最新的多事务是%u,跳过截断" -#: access/transam/multixact.c:3027 +#: access/transam/multixact.c:3029 #, c-format -msgid "" -"cannot truncate up to MultiXact %u because it does not exist on disk, " -"skipping truncation" +msgid "cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation" msgstr "无法一直截断到多事务%u,因为它在ç£ç›˜ä¸Šä¸å­˜åœ¨ï¼Œè·³è¿‡æˆªæ–­" -#: access/transam/multixact.c:3353 +#: access/transam/multixact.c:3343 #, c-format msgid "invalid MultiXactId: %u" msgstr "无效的MultiXactId:%u" -#: access/transam/parallel.c:581 +#: access/transam/parallel.c:673 access/transam/parallel.c:792 +#, c-format +msgid "parallel worker failed to initialize" +msgstr "并行工作进程åˆå§‹åŒ–失败" + +#: access/transam/parallel.c:674 access/transam/parallel.c:793 +#, c-format +msgid "More details may be available in the server log." +msgstr "有关详细信æ¯ï¼Œè¯·å‚阅æœåŠ¡å™¨æ—¥å¿—." + +#: access/transam/parallel.c:854 #, c-format msgid "postmaster exited during a parallel transaction" msgstr "在并行æ“作期间postmaster退出" # fe-exec.c:745 -#: access/transam/parallel.c:739 +#: access/transam/parallel.c:1041 #, c-format msgid "lost connection to parallel worker" msgstr "并行工作者进程的连接丢失" -#: access/transam/parallel.c:914 +#: access/transam/parallel.c:1107 access/transam/parallel.c:1109 +msgid "parallel worker" +msgstr "并行工作者进程" + +#: access/transam/parallel.c:1259 #, c-format msgid "could not map dynamic shared memory segment" msgstr "无法映射动æ€å…±äº«å†…存段" -#: access/transam/parallel.c:919 +#: access/transam/parallel.c:1264 #, c-format msgid "invalid magic number in dynamic shared memory segment" msgstr "动æ€å…±äº«å†…å­˜æ®µä¸­æœ‰éžæ³•magicå·" -#: access/transam/parallel.c:1084 -#, c-format -msgid "parallel worker, PID %d" -msgstr "并行工作者进程,PID为%d" - -#: access/transam/slru.c:665 +#: access/transam/slru.c:674 #, c-format msgid "file \"%s\" doesn't exist, reading as zeroes" msgstr "文件 \"%s\" ä¸å­˜åœ¨, å‡è®¾è¯»å–了 0 字节" -#: access/transam/slru.c:895 access/transam/slru.c:901 -#: access/transam/slru.c:908 access/transam/slru.c:915 -#: access/transam/slru.c:922 access/transam/slru.c:929 +#: access/transam/slru.c:912 access/transam/slru.c:918 +#: access/transam/slru.c:925 access/transam/slru.c:932 +#: access/transam/slru.c:939 access/transam/slru.c:946 #, c-format msgid "could not access status of transaction %u" msgstr "无法处ç†äº‹ç‰© %u 的状æ€" -#: access/transam/slru.c:896 +#: access/transam/slru.c:913 #, c-format msgid "Could not open file \"%s\": %m." msgstr "无法打开文件 \"%s\": %m" -#: access/transam/slru.c:902 +#: access/transam/slru.c:919 #, c-format msgid "Could not seek in file \"%s\" to offset %u: %m." msgstr "无法在文件 \"%s\" åç§»é‡ %u 查找: %m" -#: access/transam/slru.c:909 +#: access/transam/slru.c:926 #, c-format msgid "Could not read from file \"%s\" at offset %u: %m." msgstr "无法从文件 \"%s\" åç§»é‡ %u 读å–: %m" -#: access/transam/slru.c:916 +#: access/transam/slru.c:933 #, c-format msgid "Could not write to file \"%s\" at offset %u: %m." msgstr "无法往文件 \"%s\" åç§»é‡ %u 写入: %m" -#: access/transam/slru.c:923 +#: access/transam/slru.c:940 #, c-format msgid "Could not fsync file \"%s\": %m." msgstr "无法在文件 \"%s\"上执行系统调用fsync: %m" -#: access/transam/slru.c:930 +#: access/transam/slru.c:947 #, c-format msgid "Could not close file \"%s\": %m." msgstr "无法关闭文件 \"%s\": %m" -#: access/transam/slru.c:1185 +#: access/transam/slru.c:1204 #, c-format msgid "could not truncate directory \"%s\": apparent wraparound" msgstr "无法清空目录\"%s\": 有明显的é‡å " -#: access/transam/slru.c:1240 access/transam/slru.c:1296 +#: access/transam/slru.c:1259 access/transam/slru.c:1315 #, c-format msgid "removing file \"%s\"" msgstr "删除文件 \"%s\"" @@ -1413,8 +1409,8 @@ msgstr "期望一个数字 timeline ID." # sql_help.h:105 #: access/transam/timeline.c:154 #, c-format -msgid "Expected a transaction log switchpoint location." -msgstr "期望一个事务日志切æ¢ç‚¹ä½ç½®." +msgid "Expected a write-ahead log switchpoint location." +msgstr "期望一个预写日志切æ¢ç‚¹ä½ç½®." #: access/transam/timeline.c:158 #, c-format @@ -1436,2393 +1432,2310 @@ msgstr "åŽ†å²æ–‡ä»¶ \"%s\" 中存在无效数æ®" msgid "Timeline IDs must be less than child timeline's ID." msgstr "Timeline ID å¿…é¡»å°äºŽå­ timeline çš„ ID." -#: access/transam/timeline.c:412 access/transam/timeline.c:488 -#: access/transam/xlog.c:3066 access/transam/xlog.c:3227 -#: access/transam/xlogfuncs.c:691 commands/copy.c:1671 -#: storage/file/copydir.c:201 -#, c-format -msgid "could not close file \"%s\": %m" -msgstr "无法关闭文件 \"%s\": %m" - -#: access/transam/timeline.c:570 +#: access/transam/timeline.c:580 #, c-format msgid "requested timeline %u is not in this server's history" msgstr "æœåŠ¡å™¨ä¸Šæ²¡æœ‰èµ·å§‹æ—¶é—´è¡¨ %u" -#: access/transam/twophase.c:363 +#: access/transam/twophase.c:382 #, c-format msgid "transaction identifier \"%s\" is too long" msgstr "事务标示符 \"%s\" 太长" # large_obj.c:55 -#: access/transam/twophase.c:370 +#: access/transam/twophase.c:389 #, c-format msgid "prepared transactions are disabled" msgstr "ç¦ç”¨å·²å‡†å¤‡å¥½çš„事务" -#: access/transam/twophase.c:371 +#: access/transam/twophase.c:390 #, c-format msgid "Set max_prepared_transactions to a nonzero value." msgstr "å°†max_prepared_transactions设置为一个éžé›¶å€¼" -#: access/transam/twophase.c:390 +#: access/transam/twophase.c:409 #, c-format msgid "transaction identifier \"%s\" is already in use" msgstr "事务标示符\"%s\"å·²ç»åœ¨ä½¿ç”¨" -#: access/transam/twophase.c:399 +#: access/transam/twophase.c:418 access/transam/twophase.c:2420 #, c-format msgid "maximum number of prepared transactions reached" msgstr "å·²ç»è¾¾åˆ°å·²å‡†å¤‡å¥½äº‹åŠ¡çš„æœ€å¤§æ•°é‡" -#: access/transam/twophase.c:400 +#: access/transam/twophase.c:419 access/transam/twophase.c:2421 #, c-format msgid "Increase max_prepared_transactions (currently %d)." msgstr "增加max_prepared_transactions的值(当å‰å€¼æ˜¯%d)." -#: access/transam/twophase.c:539 +#: access/transam/twophase.c:587 #, c-format msgid "prepared transaction with identifier \"%s\" is busy" msgstr "标示符为\"%s\"的事务处于ç¹å¿™çжæ€." -#: access/transam/twophase.c:545 +#: access/transam/twophase.c:593 #, c-format msgid "permission denied to finish prepared transaction" msgstr "完æˆå·²å‡†å¤‡å¥½äº‹åŠ¡çš„æƒé™ä¸å¤Ÿ" -#: access/transam/twophase.c:546 +#: access/transam/twophase.c:594 #, c-format msgid "Must be superuser or the user that prepared the transaction." msgstr "必须是超级用户或者是准备好事务的用户" -#: access/transam/twophase.c:557 +#: access/transam/twophase.c:605 #, c-format msgid "prepared transaction belongs to another database" msgstr "已准备好的事务属于å¦ä¸€ä¸ªæ•°æ®åº“" -#: access/transam/twophase.c:558 +#: access/transam/twophase.c:606 #, c-format -msgid "" -"Connect to the database where the transaction was prepared to finish it." +msgid "Connect to the database where the transaction was prepared to finish it." msgstr "连接到带有准备好完æˆäº‹åŠ¡çš„æ•°æ®åº“" -#: access/transam/twophase.c:573 +#: access/transam/twophase.c:621 #, c-format msgid "prepared transaction with identifier \"%s\" does not exist" msgstr "带有标示符\"%s\" 已准备好事务ä¸å­˜åœ¨" -#: access/transam/twophase.c:1042 +#: access/transam/twophase.c:1115 #, c-format msgid "two-phase state file maximum length exceeded" msgstr "è¶…è¿‡ä¸¤é˜¶æ®µçŠ¶æ€æ–‡ä»¶çš„æœ€å¤§é•¿åº¦" -#: access/transam/twophase.c:1160 +#: access/transam/twophase.c:1261 access/transam/xlog.c:10512 +#: access/transam/xlog.c:10550 access/transam/xlog.c:10767 +#: access/transam/xlogarchive.c:104 access/transam/xlogarchive.c:264 +#: commands/copy.c:1945 commands/copy.c:3554 commands/extension.c:3330 +#: commands/tablespace.c:787 commands/tablespace.c:878 +#: replication/basebackup.c:343 replication/basebackup.c:523 +#: replication/basebackup.c:593 replication/logical/snapbuild.c:1527 +#: storage/file/copydir.c:68 storage/file/copydir.c:107 storage/file/fd.c:1703 +#: storage/file/fd.c:2980 storage/file/fd.c:3162 storage/file/fd.c:3247 +#: utils/adt/dbsize.c:70 utils/adt/dbsize.c:222 utils/adt/dbsize.c:302 +#: utils/adt/genfile.c:133 utils/adt/genfile.c:386 guc-file.l:1004 #, c-format -msgid "could not open two-phase state file \"%s\": %m" -msgstr "无法打开两阶段æäº¤çŠ¶æ€æ–‡ä»¶\"%s\": %m" +msgid "could not stat file \"%s\": %m" +msgstr "æ— æ³•å–æ–‡ä»¶ \"%s\" 的状æ€: %m" -#: access/transam/twophase.c:1177 -#, c-format -msgid "could not stat two-phase state file \"%s\": %m" -msgstr "无法获å–两阶段æäº¤çŠ¶æ€æ–‡ä»¶ \"%s\" 的状æ€: %m" +#: access/transam/twophase.c:1269 +#, fuzzy, c-format +#| msgid "could not write to file \"%s\": %m" +msgid "incorrect size of file \"%s\": %zu byte" +msgid_plural "incorrect size of file \"%s\": %zu bytes" +msgstr[0] "无法写入文件 \"%s\": %m" -#: access/transam/twophase.c:1209 +#: access/transam/twophase.c:1278 #, c-format -msgid "could not read two-phase state file \"%s\": %m" -msgstr "无法读å–两阶段æäº¤çŠ¶æ€æ–‡ä»¶ \"%s\": %m" +msgid "incorrect alignment of CRC offset for file \"%s\"" +msgstr "" -#: access/transam/twophase.c:1262 access/transam/xlog.c:6070 -#, c-format -msgid "Failed while allocating an XLog reading processor." -msgstr "分é…XLog读å–处ç†å™¨å¤±è´¥." +#: access/transam/twophase.c:1311 +#, fuzzy, c-format +#| msgid "invalid segment number %d in file \"%s\"" +msgid "invalid magic number stored in file \"%s\"" +msgstr "文件\"%2$s\"中的段å·%1$d无效" -#: access/transam/twophase.c:1268 -#, c-format -#| msgid "could not read two-phase state file \"%s\": %m" -msgid "could not read two-phase state from xlog at %X/%X" -msgstr "无法从 %X/%X ä½ç½®çš„ xlog 读å–两阶段状æ€" +#: access/transam/twophase.c:1317 +#, fuzzy, c-format +#| msgid "invalid data in file \"%s\"" +msgid "invalid size stored in file \"%s\"" +msgstr "文件 \"%s\" 中存在无效数æ®" -#: access/transam/twophase.c:1276 -#, c-format -msgid "expected two-phase state data is not present in xlog at %X/%X" -msgstr "é¢„æœŸçš„ä¸¤é˜¶æ®µçŠ¶æ€æ•°æ®æ²¡æœ‰å‡ºçŽ°åœ¨ xlog çš„ %X/%X ä½ç½®ä¸Š" +#: access/transam/twophase.c:1329 +#, fuzzy, c-format +#| msgid "calculated CRC checksum does not match value stored in file" +msgid "calculated CRC checksum does not match value stored in file \"%s\"" +msgstr "计算得到的 CRC 校验与存储在文件中的值ä¸åŒ¹é…" -#: access/transam/twophase.c:1512 +#: access/transam/twophase.c:1395 access/transam/xlog.c:6347 #, c-format -msgid "could not remove two-phase state file \"%s\": %m" -msgstr "无法删除两阶段æäº¤çŠ¶æ€æ–‡ä»¶\"%s\": %m" +msgid "Failed while allocating a WAL reading processor." +msgstr "分é…WAL读å–处ç†å™¨å¤±è´¥." -#: access/transam/twophase.c:1542 +#: access/transam/twophase.c:1401 #, c-format -msgid "could not recreate two-phase state file \"%s\": %m" -msgstr "æ— æ³•é‡æ–°åˆ›å»ºä¸¤é˜¶æ®µæäº¤çŠ¶æ€æ–‡ä»¶ \"%s\": %m" +msgid "could not read two-phase state from WAL at %X/%X" +msgstr "无法从 %X/%X ä½ç½®çš„ WAL 读å–两阶段状æ€" -#: access/transam/twophase.c:1551 access/transam/twophase.c:1558 +#: access/transam/twophase.c:1409 #, c-format -msgid "could not write two-phase state file: %m" -msgstr "无法对两阶段æäº¤çŠ¶æ€æ–‡ä»¶è¿›è¡Œå†™æ“作: %m" +msgid "expected two-phase state data is not present in WAL at %X/%X" +msgstr "é¢„æœŸçš„ä¸¤é˜¶æ®µçŠ¶æ€æ•°æ®æ²¡æœ‰å‡ºçŽ°åœ¨ WAL çš„ %X/%X ä½ç½®ä¸Š" -#: access/transam/twophase.c:1570 -#, c-format -msgid "could not fsync two-phase state file: %m" -msgstr "无法在两阶段æäº¤çŠ¶æ€æ–‡ä»¶ä¸Šæ‰§è¡Œç³»ç»Ÿè°ƒç”¨fsync: %m" +#: access/transam/twophase.c:1689 +#, fuzzy, c-format +#| msgid "could not create file \"%s\": %m" +msgid "could not recreate file \"%s\": %m" +msgstr "无法创建文件 \"%s\": %m" -#: access/transam/twophase.c:1576 +#: access/transam/twophase.c:1816 #, c-format -msgid "could not close two-phase state file: %m" -msgstr "无法关闭两阶段æäº¤çŠ¶æ€æ–‡ä»¶: %m" +msgid "%u two-phase state file was written for a long-running prepared transaction" +msgid_plural "%u two-phase state files were written for long-running prepared transactions" +msgstr[0] "为长时间è¿è¡Œçš„准备好事务写了 %u ä¸ªä¸¤é˜¶æ®µçŠ¶æ€æ–‡ä»¶" -#: access/transam/twophase.c:1651 +#: access/transam/twophase.c:2050 #, c-format -msgid "" -"%u two-phase state files were written for long-running prepared transactions" -msgstr "为长时间è¿è¡Œçš„准备好事务写了 %u ä¸ªä¸¤é˜¶æ®µçŠ¶æ€æ–‡ä»¶" +msgid "recovering prepared transaction %u from shared memory" +msgstr "正在从共享内存中æ¢å¤å·²å‡†å¤‡äº‹åŠ¡%u" -#: access/transam/twophase.c:1712 +#: access/transam/twophase.c:2141 #, c-format -msgid "removing future two-phase state file \"%s\"" -msgstr "删除å¯èƒ½äº§ç”Ÿçš„两阶段æäº¤çŠ¶æ€æ–‡ä»¶ \"%s\"" +msgid "removing stale two-phase state file for transaction %u" +msgstr "正在删除事务%u无用的两阶段æäº¤çŠ¶æ€æ–‡ä»¶" -#: access/transam/twophase.c:1728 access/transam/twophase.c:1739 -#: access/transam/twophase.c:1858 access/transam/twophase.c:1869 -#: access/transam/twophase.c:1943 +#: access/transam/twophase.c:2148 #, c-format -msgid "removing corrupt two-phase state file \"%s\"" -msgstr "删除已æŸå的两阶段æäº¤çŠ¶æ€æ–‡ä»¶\"%s\"" +msgid "removing stale two-phase state from memory for transaction %u" +msgstr "正在从内存中删除事务%u的无用的两阶段æäº¤çжæ€" -#: access/transam/twophase.c:1847 access/transam/twophase.c:1932 +#: access/transam/twophase.c:2161 #, c-format -msgid "removing stale two-phase state file \"%s\"" -msgstr "正在删除无用的两阶段æäº¤çŠ¶æ€æ–‡ä»¶\"%s\"" +msgid "removing future two-phase state file for transaction %u" +msgstr "正在删除事务%u的未æ¥ä¸¤é˜¶æ®µçŠ¶æ€æ–‡ä»¶" -#: access/transam/twophase.c:1950 +#: access/transam/twophase.c:2168 #, c-format -msgid "recovering prepared transaction %u" -msgstr "正在æ¢å¤å·²å‡†å¤‡äº‹åŠ¡%u" +msgid "removing future two-phase state from memory for transaction %u" +msgstr "正在从内存中删除事务%u的未æ¥ä¸¤é˜¶æ®µæäº¤çжæ€" + +#: access/transam/twophase.c:2193 +#, fuzzy, c-format +#| msgid "removing corrupt two-phase state file for transaction %u" +msgid "corrupted two-phase state file for transaction %u" +msgstr "正在删除事务%uå·²æŸå的两阶段æäº¤çŠ¶æ€æ–‡ä»¶" + +#: access/transam/twophase.c:2198 +#, fuzzy, c-format +#| msgid "removing corrupt two-phase state from memory for transaction %u" +msgid "corrupted two-phase state in memory for transaction %u" +msgstr "正在从内存中删除事务%uå·²æŸå的两阶段æäº¤çжæ€" -#: access/transam/varsup.c:124 +#: access/transam/varsup.c:127 #, c-format -msgid "" -"database is not accepting commands to avoid wraparound data loss in database " -"\"%s\"" +msgid "database is not accepting commands to avoid wraparound data loss in database \"%s\"" msgstr "æ•°æ®åº“没有接收命令æ¥é¿å…在数æ®åº“\"%s\"中的é‡å æ•°æ®æŸå¤±" -#: access/transam/varsup.c:126 access/transam/varsup.c:133 +#: access/transam/varsup.c:129 access/transam/varsup.c:136 #, c-format msgid "" "Stop the postmaster and vacuum that database in single-user mode.\n" -"You might also need to commit or roll back old prepared transactions." +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." msgstr "" "åœæ­¢postmaster进程,然åŽåœ¨å•用户模å¼ä¸‹æ¸…ç†æ•°æ®åº“.\n" -"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好事务." +"您也å¯èƒ½éœ€è¦æäº¤æˆ–回滚旧的已准备好事务,或者旧的å¤åˆ¶æ§½." -#: access/transam/varsup.c:131 +#: access/transam/varsup.c:134 #, c-format -msgid "" -"database is not accepting commands to avoid wraparound data loss in database " -"with OID %u" +msgid "database is not accepting commands to avoid wraparound data loss in database with OID %u" msgstr "æ•°æ®åº“没有接å—命令æ¥é¿å…在带有OID为%u的数æ®åº“中的é‡å æ•°æ®æŸå¤±" -#: access/transam/varsup.c:143 access/transam/varsup.c:381 +#: access/transam/varsup.c:146 access/transam/varsup.c:444 #, c-format msgid "database \"%s\" must be vacuumed within %u transactions" msgstr "æ•°æ®åº“ \"%s\"在è¿è¡Œ%u个事务中进行清ç†(vacuume)." -#: access/transam/varsup.c:150 access/transam/varsup.c:388 +#: access/transam/varsup.c:153 access/transam/varsup.c:451 #, c-format msgid "database with OID %u must be vacuumed within %u transactions" msgstr "带有OID为%u的数æ®åº“必须在%u个事务中进行清ç†(vacuume)." -#: access/transam/varsup.c:346 +#: access/transam/varsup.c:409 #, c-format msgid "transaction ID wrap limit is %u, limited by database with OID %u" msgstr "事务IDçš„å°è£…é™åˆ¶æ˜¯%u, 由带有OID为%u的数æ®åº“é™åˆ¶." -#: access/transam/xact.c:943 +#: access/transam/xact.c:1027 #, c-format msgid "cannot have more than 2^32-2 commands in a transaction" msgstr "一个事物中拥有最多ä¸èƒ½è¶…过 2^32-2 个命令" -#: access/transam/xact.c:1453 +#: access/transam/xact.c:1552 #, c-format msgid "maximum number of committed subtransactions (%d) exceeded" msgstr "超过已æäº¤å­äº‹åŠ¡çš„æœ€å¤§æ•°é‡(%d)" -#: access/transam/xact.c:2249 +#: access/transam/xact.c:2377 #, c-format -msgid "cannot PREPARE a transaction that has operated on temporary tables" -msgstr "无法在一个已ç»åœ¨ä¸´æ—¶è¡¨ä¸Šæ“作的事务上执行PREPAREæ“作" +msgid "cannot PREPARE a transaction that has operated on temporary objects" +msgstr "无法在一个已ç»åœ¨ä¸´æ—¶å¯¹è±¡ä¸Šæ“作的事务上执行PREPAREæ“作" -#: access/transam/xact.c:2259 +#: access/transam/xact.c:2387 #, c-format msgid "cannot PREPARE a transaction that has exported snapshots" msgstr "无法在一个已ç»å¯¼å‡ºå¿«ç…§çš„事务上执行PREPAREæ“作" +#: access/transam/xact.c:2396 +#, c-format +msgid "cannot PREPARE a transaction that has manipulated logical replication workers" +msgstr "无法在已æ“作逻辑å¤åˆ¶çš„事务上执行PREPAREæ“作" + #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3141 +#: access/transam/xact.c:3337 #, c-format msgid "%s cannot run inside a transaction block" msgstr "%s 无法在事物å—中è¿è¡Œ" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3151 +#: access/transam/xact.c:3347 #, c-format msgid "%s cannot run inside a subtransaction" msgstr "%s 无法在一个å­äº‹ç‰©ä¸­è¿è¡Œ" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3161 +#: access/transam/xact.c:3357 #, c-format -msgid "%s cannot be executed from a function or multi-command string" -msgstr "%s 无法从函数或包å«å¤šæ¡å‘½ä»¤çš„字符串中执行." +msgid "%s cannot be executed from a function" +msgstr "%s 无法从函数执行" #. translator: %s represents an SQL statement name -#: access/transam/xact.c:3232 +#: access/transam/xact.c:3426 access/transam/xact.c:4062 +#: access/transam/xact.c:4131 access/transam/xact.c:4242 #, c-format msgid "%s can only be used in transaction blocks" msgstr "%s åªèƒ½åœ¨äº‹åŠ¡å—中使用" -#: access/transam/xact.c:3416 +#: access/transam/xact.c:3619 #, c-format msgid "there is already a transaction in progress" msgstr "å·²ç»æœ‰ä¸€ä¸ªäº‹ç‰©åœ¨è¿è¡Œä¸­" -#: access/transam/xact.c:3584 access/transam/xact.c:3687 +#: access/transam/xact.c:3730 access/transam/xact.c:3800 +#: access/transam/xact.c:3916 #, c-format msgid "there is no transaction in progress" msgstr "没有事物在è¿è¡Œä¸­" -#: access/transam/xact.c:3595 +#: access/transam/xact.c:3811 #, c-format msgid "cannot commit during a parallel operation" msgstr "并行æ“作期间无法æäº¤" -#: access/transam/xact.c:3698 +#: access/transam/xact.c:3927 #, c-format msgid "cannot abort during a parallel operation" msgstr "在并行æ“作期间无法中止" -#: access/transam/xact.c:3740 +#: access/transam/xact.c:4026 #, c-format msgid "cannot define savepoints during a parallel operation" msgstr "在并行æ“作期间无法定义ä¿å­˜ç‚¹" -#: access/transam/xact.c:3807 +#: access/transam/xact.c:4113 #, c-format msgid "cannot release savepoints during a parallel operation" msgstr "在并行æ“作期间ä¸èƒ½é‡Šæ”¾ä¿å­˜ç‚¹" -#: access/transam/xact.c:3818 access/transam/xact.c:3870 -#: access/transam/xact.c:3876 access/transam/xact.c:3932 -#: access/transam/xact.c:3982 access/transam/xact.c:3988 +#: access/transam/xact.c:4123 access/transam/xact.c:4174 +#: access/transam/xact.c:4234 access/transam/xact.c:4283 #, c-format -msgid "no such savepoint" -msgstr "没有这个ä¿å­˜ç‚¹" +msgid "savepoint \"%s\" does not exist" +msgstr "ä¿å­˜ç‚¹\"%s\"ä¸å­˜åœ¨" -#: access/transam/xact.c:3920 +#: access/transam/xact.c:4180 access/transam/xact.c:4289 +#, c-format +msgid "savepoint \"%s\" does not exist within current savepoint level" +msgstr "当å‰ä¿å­˜ç‚¹çº§åˆ«ä¸­ä¸å­˜åœ¨ä¿å­˜ç‚¹\"%s\"" + +#: access/transam/xact.c:4222 #, c-format msgid "cannot rollback to savepoints during a parallel operation" msgstr "在并行æ“作期间无法回滚到ä¿å­˜ç‚¹" -#: access/transam/xact.c:4048 +#: access/transam/xact.c:4350 #, c-format msgid "cannot start subtransactions during a parallel operation" msgstr "在并行æ“作期间ä¸èƒ½å¼€å§‹å­äº‹åŠ¡" -#: access/transam/xact.c:4115 +#: access/transam/xact.c:4418 #, c-format msgid "cannot commit subtransactions during a parallel operation" msgstr "在并行æ“作期间ä¸èƒ½æäº¤å­äº‹åŠ¡" -#: access/transam/xact.c:4723 +#: access/transam/xact.c:5056 #, c-format msgid "cannot have more than 2^32-1 subtransactions in a transaction" msgstr "在一个事物中ä¸å¯ä»¥è¶…过有 2^32-1 个å­äº‹ç‰©" -#: access/transam/xlog.c:2272 -#, c-format -msgid "could not seek in log file %s to offset %u: %m" -msgstr "无法在日志文件 \"%s\" ä¸­å®šä½ %u: %m" - -#: access/transam/xlog.c:2292 +#: access/transam/xlog.c:2507 #, c-format msgid "could not write to log file %s at offset %u, length %zu: %m" msgstr "无法在åç§»é‡ %2$u,长度 %3$zu写入日志文件%1$s: %4$m" -#: access/transam/xlog.c:2555 +#: access/transam/xlog.c:2783 #, c-format msgid "updated min recovery point to %X/%X on timeline %u" msgstr "在时间点%3$uä¸Šå°†æœ€å°æ¢å¤ç‚¹æ›´æ–°åˆ°%1$X/%2$X" -#: access/transam/xlog.c:3197 -#, c-format -msgid "not enough data in file \"%s\"" -msgstr "文件 \"%s\" 中的数æ®ä¸è¶³" - -#: access/transam/xlog.c:3338 -#, c-format -msgid "could not open transaction log file \"%s\": %m" -msgstr "无法打开事务日志文件 \"%s\": %m" - -#: access/transam/xlog.c:3527 access/transam/xlog.c:5300 -#, c-format -msgid "could not close log file %s: %m" -msgstr "无法关闭日志文件 %s: %m" - -#: access/transam/xlog.c:3584 access/transam/xlogutils.c:700 -#: replication/walsender.c:2099 +#: access/transam/xlog.c:3864 access/transam/xlogutils.c:703 +#: replication/walsender.c:2445 #, c-format msgid "requested WAL segment %s has already been removed" msgstr "æ‰€è¦æ±‚çš„WAL段%så·²ç»è¢«åˆ é™¤" -#: access/transam/xlog.c:3644 access/transam/xlog.c:3719 -#: access/transam/xlog.c:3917 -#, c-format -msgid "could not open transaction log directory \"%s\": %m" -msgstr "无法打开事务日志目录 \"%s\": %m" - -#: access/transam/xlog.c:3800 -#, c-format -msgid "recycled transaction log file \"%s\"" -msgstr "回收事务日志文件 \"%s\"" - -#: access/transam/xlog.c:3812 +#: access/transam/xlog.c:4106 #, c-format -msgid "removing transaction log file \"%s\"" -msgstr "删除事务日志文件 \"%s\"" +msgid "recycled write-ahead log file \"%s\"" +msgstr "回收预写日志文件 \"%s\"" -#: access/transam/xlog.c:3832 +#: access/transam/xlog.c:4118 #, c-format -msgid "could not rename old transaction log file \"%s\": %m" -msgstr "无法é‡å‘½å旧的事务日志文件\"%s\": %m" +msgid "removing write-ahead log file \"%s\"" +msgstr "删除预写日志文件 \"%s\"" -#: access/transam/xlog.c:3844 -#, c-format -msgid "could not remove old transaction log file \"%s\": %m" -msgstr "无法删除旧的事务日志文件 \"%s\": %m" +#: access/transam/xlog.c:4138 +#, fuzzy, c-format +#| msgid "could not remove file \"%s\": %m" +msgid "could not rename file \"%s\": %m" +msgstr "无法删除文件 \"%s\": %m" -#: access/transam/xlog.c:3877 access/transam/xlog.c:3887 +#: access/transam/xlog.c:4180 access/transam/xlog.c:4190 #, c-format msgid "required WAL directory \"%s\" does not exist" msgstr "所需è¦çš„WAL目录 \"%s\" ä¸å­˜åœ¨" -#: access/transam/xlog.c:3893 +#: access/transam/xlog.c:4196 #, c-format msgid "creating missing WAL directory \"%s\"" msgstr "正在创建丢失的WAL目录\"%s\"" -#: access/transam/xlog.c:3896 +#: access/transam/xlog.c:4199 #, c-format msgid "could not create missing directory \"%s\": %m" msgstr "无法创建丢失的目录 \"%s\": %m" -#: access/transam/xlog.c:3927 -#, c-format -msgid "removing transaction log backup history file \"%s\"" -msgstr "æ­£åœ¨åˆ é™¤äº‹åŠ¡æ—¥å¿—å¤‡ä»½åŽ†å²æ–‡ä»¶ \"%s\"" - -#: access/transam/xlog.c:4008 +#: access/transam/xlog.c:4304 #, c-format msgid "unexpected timeline ID %u in log segment %s, offset %u" msgstr "日志段%2$s,åç§»%3$u出现æ„外的时间点ID %1$u" -#: access/transam/xlog.c:4130 +#: access/transam/xlog.c:4432 #, c-format msgid "new timeline %u is not a child of database system timeline %u" msgstr "新的时间线%uä¸é™„属于数æ®åº“系统时间线%u" -#: access/transam/xlog.c:4144 +#: access/transam/xlog.c:4446 #, c-format -msgid "" -"new timeline %u forked off current database system timeline %u before " -"current recovery point %X/%X" -msgstr "" -"åœ¨å½“å‰æ¢å¤ç‚¹%3$X/%4$X之å‰, 新的时间点%1$u脱离了当å‰èŒ…的数æ®åº“系统时间点%2$u" +msgid "new timeline %u forked off current database system timeline %u before current recovery point %X/%X" +msgstr "åœ¨å½“å‰æ¢å¤ç‚¹%3$X/%4$X之å‰, 新的时间点%1$u脱离了当å‰èŒ…的数æ®åº“系统时间点%2$u" -#: access/transam/xlog.c:4163 +#: access/transam/xlog.c:4465 #, c-format msgid "new target timeline is %u" msgstr "新的目标时间线为%u" -#: access/transam/xlog.c:4243 -#, c-format -msgid "could not create control file \"%s\": %m" -msgstr "无法创建控制文件 \"%s\": %m" - -#: access/transam/xlog.c:4254 access/transam/xlog.c:4490 -#, c-format -msgid "could not write to control file: %m" -msgstr "无法写入控制文件: %m" - -#: access/transam/xlog.c:4260 access/transam/xlog.c:4496 -#, c-format -msgid "could not fsync control file: %m" -msgstr "无法 fsync 控制文件: %m" - -#: access/transam/xlog.c:4265 access/transam/xlog.c:4501 -#, c-format -msgid "could not close control file: %m" -msgstr "无法关闭控制文件: %m" - -#: access/transam/xlog.c:4283 access/transam/xlog.c:4479 -#, c-format -msgid "could not open control file \"%s\": %m" -msgstr "无法打开控制文件 \"%s\": %m" - -#: access/transam/xlog.c:4289 -#, c-format -msgid "could not read from control file: %m" -msgstr "æ— æ³•è¯»å–æŽ§åˆ¶æ–‡ä»¶: %m" - -#: access/transam/xlog.c:4302 access/transam/xlog.c:4311 -#: access/transam/xlog.c:4335 access/transam/xlog.c:4342 -#: access/transam/xlog.c:4349 access/transam/xlog.c:4354 -#: access/transam/xlog.c:4361 access/transam/xlog.c:4368 -#: access/transam/xlog.c:4375 access/transam/xlog.c:4382 -#: access/transam/xlog.c:4389 access/transam/xlog.c:4396 -#: access/transam/xlog.c:4403 access/transam/xlog.c:4412 -#: access/transam/xlog.c:4419 access/transam/xlog.c:4428 -#: access/transam/xlog.c:4435 access/transam/xlog.c:4444 -#: access/transam/xlog.c:4451 utils/init/miscinit.c:1380 +#: access/transam/xlog.c:4624 access/transam/xlog.c:4633 +#: access/transam/xlog.c:4657 access/transam/xlog.c:4664 +#: access/transam/xlog.c:4671 access/transam/xlog.c:4676 +#: access/transam/xlog.c:4683 access/transam/xlog.c:4690 +#: access/transam/xlog.c:4697 access/transam/xlog.c:4704 +#: access/transam/xlog.c:4711 access/transam/xlog.c:4718 +#: access/transam/xlog.c:4727 access/transam/xlog.c:4734 +#: access/transam/xlog.c:4743 access/transam/xlog.c:4750 +#: utils/init/miscinit.c:1502 #, c-format msgid "database files are incompatible with server" msgstr "æ•°æ®åº“文件和æœåС噍ä¸å…¼å®¹" -#: access/transam/xlog.c:4303 +#: access/transam/xlog.c:4625 #, c-format -msgid "" -"The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), " -"but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." -msgstr "" -"æ•°æ®åº“集群是以 PG_CONTROL_VERSION %d (0x%08x)åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ " -"PG_CONTROL_VERSION %d (0x%08x)编译的." +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d (0x%08x), but the server was compiled with PG_CONTROL_VERSION %d (0x%08x)." +msgstr "æ•°æ®åº“集群是以 PG_CONTROL_VERSION %d (0x%08x)åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ PG_CONTROL_VERSION %d (0x%08x)编译的." -#: access/transam/xlog.c:4307 +#: access/transam/xlog.c:4629 #, c-format -msgid "" -"This could be a problem of mismatched byte ordering. It looks like you need " -"to initdb." +msgid "This could be a problem of mismatched byte ordering. It looks like you need to initdb." msgstr "这是一个字节顺åºä¸åŒ¹é…的问题.您需è¦è¿è¡Œinitdb." -#: access/transam/xlog.c:4312 +#: access/transam/xlog.c:4634 #, c-format -msgid "" -"The database cluster was initialized with PG_CONTROL_VERSION %d, but the " -"server was compiled with PG_CONTROL_VERSION %d." -msgstr "" -"æ•°æ®åº“集群是以 PG_CONTROL_VERSION %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ " -"PG_CONTROL_VERSION %d 编译的." +msgid "The database cluster was initialized with PG_CONTROL_VERSION %d, but the server was compiled with PG_CONTROL_VERSION %d." +msgstr "æ•°æ®åº“集群是以 PG_CONTROL_VERSION %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ PG_CONTROL_VERSION %d 编译的." -#: access/transam/xlog.c:4315 access/transam/xlog.c:4339 -#: access/transam/xlog.c:4346 access/transam/xlog.c:4351 +#: access/transam/xlog.c:4637 access/transam/xlog.c:4661 +#: access/transam/xlog.c:4668 access/transam/xlog.c:4673 #, c-format msgid "It looks like you need to initdb." msgstr "看上去, 你需è¦åˆå§‹åŒ–æ•°æ®åº“." -#: access/transam/xlog.c:4326 +#: access/transam/xlog.c:4648 #, c-format msgid "incorrect checksum in control file" msgstr "æŽ§åˆ¶æ–‡ä»¶çš„æ ¡éªŒå€¼ä¸æ­£ç¡®" -#: access/transam/xlog.c:4336 +#: access/transam/xlog.c:4658 #, c-format -msgid "" -"The database cluster was initialized with CATALOG_VERSION_NO %d, but the " -"server was compiled with CATALOG_VERSION_NO %d." -msgstr "" -"æ•°æ®åº“簇是以 CATALOG_VERSION_NO %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ " -"CATALOG_VERSION_NO %d 编译的." +msgid "The database cluster was initialized with CATALOG_VERSION_NO %d, but the server was compiled with CATALOG_VERSION_NO %d." +msgstr "æ•°æ®åº“簇是以 CATALOG_VERSION_NO %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ CATALOG_VERSION_NO %d 编译的." -#: access/transam/xlog.c:4343 +#: access/transam/xlog.c:4665 #, c-format -msgid "" -"The database cluster was initialized with MAXALIGN %d, but the server was " -"compiled with MAXALIGN %d." -msgstr "" -"æ•°æ®åº“集群是以 MAXALIGN%d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ NAMEDATALEN %d 编译的." +msgid "The database cluster was initialized with MAXALIGN %d, but the server was compiled with MAXALIGN %d." +msgstr "æ•°æ®åº“集群是以 MAXALIGN%d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ NAMEDATALEN %d 编译的." -#: access/transam/xlog.c:4350 +#: access/transam/xlog.c:4672 #, c-format -msgid "" -"The database cluster appears to use a different floating-point number format " -"than the server executable." +msgid "The database cluster appears to use a different floating-point number format than the server executable." msgstr "æ•°æ®åº“集群在使用与æœåŠ¡å™¨æ‰§è¡Œéƒ¨åˆ†ä¸åŒçš„æµ®ç‚¹æ•°æ ¼å¼" -#: access/transam/xlog.c:4355 +#: access/transam/xlog.c:4677 #, c-format -msgid "" -"The database cluster was initialized with BLCKSZ %d, but the server was " -"compiled with BLCKSZ %d." +msgid "The database cluster was initialized with BLCKSZ %d, but the server was compiled with BLCKSZ %d." msgstr "æ•°æ®åº“簇是以 BLCKSZ %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ BLCKSZ %d 编译的." -#: access/transam/xlog.c:4358 access/transam/xlog.c:4365 -#: access/transam/xlog.c:4372 access/transam/xlog.c:4379 -#: access/transam/xlog.c:4386 access/transam/xlog.c:4393 -#: access/transam/xlog.c:4400 access/transam/xlog.c:4407 -#: access/transam/xlog.c:4415 access/transam/xlog.c:4422 -#: access/transam/xlog.c:4431 access/transam/xlog.c:4438 -#: access/transam/xlog.c:4447 access/transam/xlog.c:4454 +#: access/transam/xlog.c:4680 access/transam/xlog.c:4687 +#: access/transam/xlog.c:4694 access/transam/xlog.c:4701 +#: access/transam/xlog.c:4708 access/transam/xlog.c:4715 +#: access/transam/xlog.c:4722 access/transam/xlog.c:4730 +#: access/transam/xlog.c:4737 access/transam/xlog.c:4746 +#: access/transam/xlog.c:4753 #, c-format msgid "It looks like you need to recompile or initdb." msgstr "看上去, 你需è¦é‡æ–°ç¼–译或åˆå§‹åŒ–æ•°æ®åº“." -#: access/transam/xlog.c:4362 -#, c-format -msgid "" -"The database cluster was initialized with RELSEG_SIZE %d, but the server was " -"compiled with RELSEG_SIZE %d." -msgstr "" -"æ•°æ®åº“簇是以 RELSEG_SIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ RELSEG_SIZE %d 编译的." - -#: access/transam/xlog.c:4369 -#, c-format -msgid "" -"The database cluster was initialized with XLOG_BLCKSZ %d, but the server was " -"compiled with XLOG_BLCKSZ %d." -msgstr "" -"æ•°æ®åº“集群是以 XLOG_BLCKSZ %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ XLOG_BLCKSZ %d 编译" -"çš„." - -#: access/transam/xlog.c:4376 -#, c-format -msgid "" -"The database cluster was initialized with XLOG_SEG_SIZE %d, but the server " -"was compiled with XLOG_SEG_SIZE %d." -msgstr "" -"æ•°æ®åº“簇是以 XLOG_SEG_SIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ XLOG_SEG_SIZE %d 编译" -"çš„." - -#: access/transam/xlog.c:4383 -#, c-format -msgid "" -"The database cluster was initialized with NAMEDATALEN %d, but the server was " -"compiled with NAMEDATALEN %d." -msgstr "" -"æ•°æ®åº“簇是以 NAMEDATALEN %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ NAMEDATALEN %d 编译的." - -#: access/transam/xlog.c:4390 -#, c-format -msgid "" -"The database cluster was initialized with INDEX_MAX_KEYS %d, but the server " -"was compiled with INDEX_MAX_KEYS %d." -msgstr "" -"æ•°æ®åº“集群是以 INDEX_MAX_KEYS %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ INDEX_MAX_KEYS " -"%d 编译的." - -#: access/transam/xlog.c:4397 -#, c-format -msgid "" -"The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the " -"server was compiled with TOAST_MAX_CHUNK_SIZE %d." -msgstr "" -"æ•°æ®åº“集群是以 TOAST_MAX_CHUNK_SIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ " -"TOAST_MAX_CHUNK_SIZE %d 编译的." - -#: access/transam/xlog.c:4404 -#, c-format -msgid "" -"The database cluster was initialized with LOBLKSIZE %d, but the server was " -"compiled with LOBLKSIZE %d." -msgstr "" -"æ•°æ®åº“簇是以 LOBLKSIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ LOBLKSIZE %d 编译的." - -#: access/transam/xlog.c:4413 +#: access/transam/xlog.c:4684 #, c-format -msgid "" -"The database cluster was initialized without HAVE_INT64_TIMESTAMP but the " -"server was compiled with HAVE_INT64_TIMESTAMP." -msgstr "" -"æ•°æ®åº“ç°‡åˆå§‹åŒ–时没有定义 HAVE_INT64_TIMESTAMP, 但是 æœåŠ¡å™¨ç¼–è¯‘æ—¶å®šä¹‰äº† " -"HAVE_INT64_TIMESTAMP." - -#: access/transam/xlog.c:4420 -#, c-format -msgid "" -"The database cluster was initialized with HAVE_INT64_TIMESTAMP but the " -"server was compiled without HAVE_INT64_TIMESTAMP." -msgstr "" -"æ•°æ®åº“ç°‡åˆå§‹åŒ–时定义了 HAVE_INT64_TIMESTAMP, 但是 æœåŠ¡å™¨ç¼–è¯‘æ—¶æ²¡æœ‰å®šä¹‰ " -"HAVE_INT64_TIMESTAMP." +msgid "The database cluster was initialized with RELSEG_SIZE %d, but the server was compiled with RELSEG_SIZE %d." +msgstr "æ•°æ®åº“簇是以 RELSEG_SIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ RELSEG_SIZE %d 编译的." -#: access/transam/xlog.c:4429 +#: access/transam/xlog.c:4691 #, c-format -msgid "" -"The database cluster was initialized without USE_FLOAT4_BYVAL but the server " -"was compiled with USE_FLOAT4_BYVAL." -msgstr "" -"æ•°æ®åº“集群在åˆå§‹åŒ–时没带有USE_FLOAT4_BYVAL选项, 但是æœåŠ¡å™¨æ˜¯ä»¥" -"USE_FLOAT4_BYVAL选项编译的." +msgid "The database cluster was initialized with XLOG_BLCKSZ %d, but the server was compiled with XLOG_BLCKSZ %d." +msgstr "æ•°æ®åº“集群是以 XLOG_BLCKSZ %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ XLOG_BLCKSZ %d 编译的." -#: access/transam/xlog.c:4436 +#: access/transam/xlog.c:4698 #, c-format -msgid "" -"The database cluster was initialized with USE_FLOAT4_BYVAL but the server " -"was compiled without USE_FLOAT4_BYVAL." -msgstr "" -"æ•°æ®åº“集群是以USE_FLOAT4_BYVAL åˆå§‹åŒ–çš„, 但是æœåŠ¡å™¨æ˜¯ä»¥USE_FLOAT4_BYVAL编译" -"çš„." +msgid "The database cluster was initialized with NAMEDATALEN %d, but the server was compiled with NAMEDATALEN %d." +msgstr "æ•°æ®åº“簇是以 NAMEDATALEN %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ NAMEDATALEN %d 编译的." -#: access/transam/xlog.c:4445 +#: access/transam/xlog.c:4705 #, c-format -msgid "" -"The database cluster was initialized without USE_FLOAT8_BYVAL but the server " -"was compiled with USE_FLOAT8_BYVAL." -msgstr "" -"æ•°æ®åº“集群在åˆå§‹åŒ–时没有带有 USE_FLOAT8_BYVAL, 但是æœåŠ¡å™¨æ˜¯ä»¥ " -"USE_FLOAT8_BYVAL编译的." +msgid "The database cluster was initialized with INDEX_MAX_KEYS %d, but the server was compiled with INDEX_MAX_KEYS %d." +msgstr "æ•°æ®åº“集群是以 INDEX_MAX_KEYS %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ INDEX_MAX_KEYS %d 编译的." -#: access/transam/xlog.c:4452 +#: access/transam/xlog.c:4712 #, c-format -msgid "" -"The database cluster was initialized with USE_FLOAT8_BYVAL but the server " -"was compiled without USE_FLOAT8_BYVAL." -msgstr "" -"æ•°æ®åº“集群是以USE_FLOAT8_BYVALåˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ²¡æœ‰ä»¥USE_FLOAT8_BYVALç¼–" -"译." +msgid "The database cluster was initialized with TOAST_MAX_CHUNK_SIZE %d, but the server was compiled with TOAST_MAX_CHUNK_SIZE %d." +msgstr "æ•°æ®åº“集群是以 TOAST_MAX_CHUNK_SIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ TOAST_MAX_CHUNK_SIZE %d 编译的." -#: access/transam/xlog.c:4875 +#: access/transam/xlog.c:4719 #, c-format -msgid "could not write bootstrap transaction log file: %m" -msgstr "无法写入 bootstrap 事务日志文件: %m" +msgid "The database cluster was initialized with LOBLKSIZE %d, but the server was compiled with LOBLKSIZE %d." +msgstr "æ•°æ®åº“簇是以 LOBLKSIZE %d åˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ˜¯ä»¥ LOBLKSIZE %d 编译的." -#: access/transam/xlog.c:4881 +#: access/transam/xlog.c:4728 #, c-format -msgid "could not fsync bootstrap transaction log file: %m" -msgstr "æ— æ³•åŒæ­¥ (fsync) 事务日志文件: %m" +msgid "The database cluster was initialized without USE_FLOAT4_BYVAL but the server was compiled with USE_FLOAT4_BYVAL." +msgstr "æ•°æ®åº“集群在åˆå§‹åŒ–时没带有USE_FLOAT4_BYVAL选项, 但是æœåŠ¡å™¨æ˜¯ä»¥USE_FLOAT4_BYVAL选项编译的." -#: access/transam/xlog.c:4886 +#: access/transam/xlog.c:4735 #, c-format -msgid "could not close bootstrap transaction log file: %m" -msgstr "无法关闭 bootstrap 事务日志文件: %m" +msgid "The database cluster was initialized with USE_FLOAT4_BYVAL but the server was compiled without USE_FLOAT4_BYVAL." +msgstr "æ•°æ®åº“集群是以USE_FLOAT4_BYVAL åˆå§‹åŒ–çš„, 但是æœåŠ¡å™¨æ˜¯ä»¥USE_FLOAT4_BYVAL编译的." -#: access/transam/xlog.c:4961 +#: access/transam/xlog.c:4744 #, c-format -msgid "could not open recovery command file \"%s\": %m" -msgstr "无法打开æ¢å¤å‘½ä»¤æ–‡ä»¶ \"%s\": %m" +msgid "The database cluster was initialized without USE_FLOAT8_BYVAL but the server was compiled with USE_FLOAT8_BYVAL." +msgstr "æ•°æ®åº“集群在åˆå§‹åŒ–时没有带有 USE_FLOAT8_BYVAL, 但是æœåŠ¡å™¨æ˜¯ä»¥ USE_FLOAT8_BYVAL编译的." -#: access/transam/xlog.c:5007 access/transam/xlog.c:5090 +#: access/transam/xlog.c:4751 #, c-format -msgid "invalid value for recovery parameter \"%s\": \"%s\"" -msgstr "æ¢å¤å‚æ•° \"%s\" 的值无效:\"%s\"" +msgid "The database cluster was initialized with USE_FLOAT8_BYVAL but the server was compiled without USE_FLOAT8_BYVAL." +msgstr "æ•°æ®åº“集群是以USE_FLOAT8_BYVALåˆå§‹åŒ–çš„, 但是 æœåŠ¡å™¨æ²¡æœ‰ä»¥USE_FLOAT8_BYVAL编译." -#: access/transam/xlog.c:5010 +#: access/transam/xlog.c:4760 #, c-format -msgid "Valid values are \"pause\", \"promote\", and \"shutdown\"." -msgstr "有效值为\"pause\"ã€\"promote\"å’Œ\"shutdown\"。" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL段大å°å¿…须是1 MB到1 GB之间的2的幂,但控制文件指定了%d字节" -#: access/transam/xlog.c:5029 +#: access/transam/xlog.c:4772 #, c-format -msgid "recovery_target_timeline is not a valid number: \"%s\"" -msgstr "recovery_target_timeline 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ•°å­—: \"%s\"" +msgid "\"min_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"min_wal_size\"必须至少是\"wal_segment_size\"的两å€" -#: access/transam/xlog.c:5045 +#: access/transam/xlog.c:4776 #, c-format -msgid "recovery_target_xid is not a valid number: \"%s\"" -msgstr "recovery_target_xid 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ•°å­—: \"%s\"" +msgid "\"max_wal_size\" must be at least twice \"wal_segment_size\"" +msgstr "\"max_wal_size\"必须至少是\"wal_segment_size\"的两å€" -#: access/transam/xlog.c:5076 +#: access/transam/xlog.c:5128 #, c-format -msgid "recovery_target_name is too long (maximum %d characters)" -msgstr "recovery_target_name 值超长 (最大长度为 %d 个字符)" +msgid "could not generate secret authorization token" +msgstr "æ— æ³•ç”Ÿæˆæœºå¯†æŽˆæƒä»¤ç‰Œ" -#: access/transam/xlog.c:5093 +#: access/transam/xlog.c:5218 #, c-format -msgid "The only allowed value is \"immediate\"." -msgstr "唯一有效的值是\"immediate\"." +msgid "could not write bootstrap write-ahead log file: %m" +msgstr "无法写入 bootstrap 预写日志文件: %m" -#: access/transam/xlog.c:5106 access/transam/xlog.c:5117 -#: commands/extension.c:533 commands/extension.c:541 utils/misc/guc.c:5637 +#: access/transam/xlog.c:5226 #, c-format -msgid "parameter \"%s\" requires a Boolean value" -msgstr "傿•° \"%s\" 需è¦ä¸€ä¸ªå¸ƒå°”值" +msgid "could not fsync bootstrap write-ahead log file: %m" +msgstr "æ— æ³•åŒæ­¥ (fsync) 预写日志文件: %m" -#: access/transam/xlog.c:5152 +#: access/transam/xlog.c:5232 #, c-format -msgid "parameter \"%s\" requires a temporal value" -msgstr "傿•° \"%s\" 需è¦ä¸€ä¸ªä¸´æ—¶å€¼" +msgid "could not close bootstrap write-ahead log file: %m" +msgstr "无法关闭 bootstrap 预写日志文件: %m" -#: access/transam/xlog.c:5154 catalog/dependency.c:991 -#: catalog/dependency.c:992 catalog/dependency.c:998 catalog/dependency.c:999 -#: catalog/dependency.c:1010 catalog/dependency.c:1011 -#: catalog/objectaddress.c:1100 commands/tablecmds.c:795 -#: commands/tablecmds.c:9447 commands/user.c:1045 commands/view.c:482 -#: libpq/auth.c:304 storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1276 -#: utils/adt/acl.c:5281 utils/misc/guc.c:5659 utils/misc/guc.c:5752 -#: utils/misc/guc.c:9686 utils/misc/guc.c:9720 utils/misc/guc.c:9754 -#: utils/misc/guc.c:9788 utils/misc/guc.c:9823 -#, c-format -msgid "%s" -msgstr "%s" +#: access/transam/xlog.c:5311 +#, fuzzy, c-format +#| msgid "log format \"%s\" is not supported" +msgid "using recovery command file \"%s\" is not supported" +msgstr "䏿”¯æŒæ—¥å¿—æ ¼å¼\"%s\"" -#: access/transam/xlog.c:5160 +#: access/transam/xlog.c:5376 #, c-format -msgid "unrecognized recovery parameter \"%s\"" -msgstr "未认å¯çš„æ¢å¤å‚æ•° \"%s\"" +msgid "standby mode is not supported by single-user servers" +msgstr "å•用户æœåС噍䏿”¯æŒå¾…机模å¼" -#: access/transam/xlog.c:5171 -#, c-format -msgid "" -"recovery command file \"%s\" specified neither primary_conninfo nor " -"restore_command" -msgstr "" -"æ¢å¤å‘½ä»¤æ–‡ä»¶ \"%s\" 既没有指定restore_command,也没有指定primary_conninfo" +#: access/transam/xlog.c:5393 +#, fuzzy, c-format +#| msgid "recovery command file \"%s\" specified neither primary_conninfo nor restore_command" +msgid "specified neither primary_conninfo nor restore_command" +msgstr "æ¢å¤å‘½ä»¤æ–‡ä»¶ \"%s\" 既没有指定restore_command,也没有指定primary_conninfo" -#: access/transam/xlog.c:5173 +#: access/transam/xlog.c:5394 #, c-format -msgid "" -"The database server will regularly poll the pg_xlog subdirectory to check " -"for files placed there." -msgstr "æ•°æ®æœåŠ¡å™¨å°†ä¼šé€šè¿‡å®šæœŸè½®è¯¢pg_xlogå­ç›®å½•æ¥æ£€æŸ¥æ”¾åœ¨è¿™é‡Œçš„æ–‡ä»¶ã€‚" +msgid "The database server will regularly poll the pg_wal subdirectory to check for files placed there." +msgstr "æ•°æ®æœåŠ¡å™¨å°†ä¼šé€šè¿‡å®šæœŸè½®è¯¢pg_walå­ç›®å½•æ¥æ£€æŸ¥æ”¾åœ¨è¿™é‡Œçš„æ–‡ä»¶ã€‚" -#: access/transam/xlog.c:5179 -#, c-format -msgid "" -"recovery command file \"%s\" must specify restore_command when standby mode " -"is not enabled" -msgstr "" -"当没有å¯ç”¨å¤‡ä»½æ¨¡å¼çš„æ—¶å€™æ¢å¤å‘½ä»¤æ–‡ä»¶ \"%s\" 必须指定 restore_command的值" +#: access/transam/xlog.c:5402 +#, fuzzy, c-format +#| msgid "recovery command file \"%s\" must specify restore_command when standby mode is not enabled" +msgid "must specify restore_command when standby mode is not enabled" +msgstr "当没有å¯ç”¨å¤‡ä»½æ¨¡å¼çš„æ—¶å€™æ¢å¤å‘½ä»¤æ–‡ä»¶ \"%s\" 必须指定 restore_command的值" -#: access/transam/xlog.c:5209 +#: access/transam/xlog.c:5428 #, c-format msgid "recovery target timeline %u does not exist" msgstr "æ¢å¤ç›®æ ‡çš„æ—¶é—´çº¿ %u ä¸å­˜åœ¨" -#: access/transam/xlog.c:5330 +#: access/transam/xlog.c:5555 #, c-format msgid "archive recovery complete" msgstr "å½’æ¡£æ¢å¤å®Œæ¯•" -#: access/transam/xlog.c:5389 access/transam/xlog.c:5617 +#: access/transam/xlog.c:5614 access/transam/xlog.c:5880 #, c-format msgid "recovery stopping after reaching consistency" msgstr "è¾¾åˆ°ä¸€è‡´æ€§å‰æ¢å¤åœæ­¢" -#: access/transam/xlog.c:5477 +#: access/transam/xlog.c:5635 +#, c-format +msgid "recovery stopping before WAL location (LSN) \"%X/%X\"" +msgstr "æ¢å¤åœæ­¢åœ¨WALä½ç½®(LSN) \"%X/%X\"之å‰" + +#: access/transam/xlog.c:5721 #, c-format msgid "recovery stopping before commit of transaction %u, time %s" msgstr "æ¢å¤åœæ­¢åœ¨äº‹ç‰© %u æäº¤ä¹‹å‰, æ—¶é—´ %s" -#: access/transam/xlog.c:5484 +#: access/transam/xlog.c:5728 #, c-format msgid "recovery stopping before abort of transaction %u, time %s" msgstr "æ¢å¤åœæ­¢åœ¨äº‹ç‰© %u 中断之å‰, æ—¶é—´ %s" -#: access/transam/xlog.c:5529 +#: access/transam/xlog.c:5774 #, c-format msgid "recovery stopping at restore point \"%s\", time %s" msgstr "æ¢å¤åœæ­¢åœ¨æ¢å¤ç‚¹ \"%s\", æ—¶é—´ %s" -#: access/transam/xlog.c:5597 +#: access/transam/xlog.c:5792 +#, c-format +msgid "recovery stopping after WAL location (LSN) \"%X/%X\"" +msgstr "æ¢å¤åœæ­¢åœ¨WALä½ç½®(LSN) \"%X/%X\"之åŽ" + +#: access/transam/xlog.c:5860 #, c-format msgid "recovery stopping after commit of transaction %u, time %s" msgstr "æ¢å¤åœæ­¢åœ¨äº‹ç‰© %u æäº¤ä¹‹åŽ, æ—¶é—´ %s" -#: access/transam/xlog.c:5605 +#: access/transam/xlog.c:5868 #, c-format msgid "recovery stopping after abort of transaction %u, time %s" msgstr "æ¢å¤åœæ­¢åœ¨äº‹ç‰© %u 中断之åŽ, æ—¶é—´ %s" -#: access/transam/xlog.c:5644 +#: access/transam/xlog.c:5908 #, c-format msgid "recovery has paused" msgstr "æ¢å¤æ“作已暂åœ" -#: access/transam/xlog.c:5645 +#: access/transam/xlog.c:5909 #, c-format -msgid "Execute pg_xlog_replay_resume() to continue." -msgstr "执行 pg_xlog_replay_resume() 以继续." +msgid "Execute pg_wal_replay_resume() to continue." +msgstr "执行 pg_wal_replay_resume() 以继续." -#: access/transam/xlog.c:5852 +#: access/transam/xlog.c:6117 #, c-format -msgid "" -"hot standby is not possible because %s = %d is a lower setting than on the " -"master server (its value was %d)" -msgstr "" -"在备用点无法实施热备æ“作,因为%s = %d这个设置低于在主æœåŠ¡å™¨çš„è®¾ç½®ï¼ˆå®ƒçš„å€¼" -"是%d)" +msgid "hot standby is not possible because %s = %d is a lower setting than on the master server (its value was %d)" +msgstr "在备用点无法实施热备æ“作,因为%s = %d这个设置低于在主æœåŠ¡å™¨çš„è®¾ç½®ï¼ˆå®ƒçš„å€¼æ˜¯%d)" -#: access/transam/xlog.c:5878 +#: access/transam/xlog.c:6143 #, c-format msgid "WAL was generated with wal_level=minimal, data may be missing" msgstr "WAL文件由wal_level=minimalçš„è®¾ç½®è€Œäº§ç”Ÿï¼Œè¿™ç§æƒ…况下数æ®å¯èƒ½ä¼šä¸¢å¤±" -#: access/transam/xlog.c:5879 +#: access/transam/xlog.c:6144 #, c-format -msgid "" -"This happens if you temporarily set wal_level=minimal without taking a new " -"base backup." -msgstr "" -"å‘ç”Ÿè¿™ç§æƒ…况是因为您临时将wal_level设置为minimal,è€Œæ²¡æœ‰åŒæ—¶è¿›è¡ŒåŸºç¡€å¤‡ä»½" +msgid "This happens if you temporarily set wal_level=minimal without taking a new base backup." +msgstr "å‘ç”Ÿè¿™ç§æƒ…况是因为您临时将wal_level设置为minimal,è€Œæ²¡æœ‰åŒæ—¶è¿›è¡ŒåŸºç¡€å¤‡ä»½" -#: access/transam/xlog.c:5890 +#: access/transam/xlog.c:6155 #, c-format -#| msgid "" -#| "hot standby is not possible because wal_level was not set to \"hot_standby" -#| "\" or higher on the master server" -msgid "" -"hot standby is not possible because wal_level was not set to \"replica\" or " -"higher on the master server" -msgstr "" -"无法实施热åŽå¤‡ï¼Œå› ä¸ºåœ¨ä¸»æœåŠ¡å™¨ä¸Š wal_level 没有被设置为 \"replica\" 或更高的" -"值" +msgid "hot standby is not possible because wal_level was not set to \"replica\" or higher on the master server" +msgstr "无法实施热åŽå¤‡ï¼Œå› ä¸ºåœ¨ä¸»æœåŠ¡å™¨ä¸Š wal_level 没有被设置为 \"replica\" 或更高的值" -#: access/transam/xlog.c:5891 +#: access/transam/xlog.c:6156 #, c-format -#| msgid "" -#| "Either set wal_level to \"hot_standby\" on the master, or turn off " -#| "hot_standby here." -msgid "" -"Either set wal_level to \"replica\" on the master, or turn off hot_standby " -"here." -msgstr "" -"è¦ä¹ˆåœ¨ä¸»æœåŠ¡å™¨ä¸ŠæŠŠ wal_level 设置为\"replica\" ,è¦ä¹ˆåœ¨è¿™é‡ŒæŠŠ hot_standby å…³" -"闭。" +msgid "Either set wal_level to \"replica\" on the master, or turn off hot_standby here." +msgstr "è¦ä¹ˆåœ¨ä¸»æœåŠ¡å™¨ä¸ŠæŠŠ wal_level 设置为\"replica\" ,è¦ä¹ˆåœ¨è¿™é‡ŒæŠŠ hot_standby 关闭。" -#: access/transam/xlog.c:5948 +#: access/transam/xlog.c:6220 #, c-format msgid "control file contains invalid data" msgstr "æŽ§åˆ¶æ–‡ä»¶åŒ…å«æ— æ•ˆçš„æ•°æ®" -#: access/transam/xlog.c:5954 +#: access/transam/xlog.c:6226 #, c-format msgid "database system was shut down at %s" msgstr "æ•°æ®åº“上次关闭时间为 %s" -#: access/transam/xlog.c:5959 +#: access/transam/xlog.c:6231 #, c-format msgid "database system was shut down in recovery at %s" msgstr "在%s,数æ®åº“在æ¢å¤ä¸­å…³é—­" -#: access/transam/xlog.c:5963 +#: access/transam/xlog.c:6235 #, c-format msgid "database system shutdown was interrupted; last known up at %s" msgstr "æ•°æ®åº“系统关闭æ“作被中断;上一次已知的è¿è¡Œæ˜¯åœ¨%s" -#: access/transam/xlog.c:5967 +#: access/transam/xlog.c:6239 #, c-format msgid "database system was interrupted while in recovery at %s" msgstr "æ¢å¤æ—¶, æ•°æ®åº“系统在 %s 被中断" -#: access/transam/xlog.c:5969 +#: access/transam/xlog.c:6241 #, c-format -msgid "" -"This probably means that some data is corrupted and you will have to use the " -"last backup for recovery." +msgid "This probably means that some data is corrupted and you will have to use the last backup for recovery." msgstr "è¿™æ„味ç€ä¸€äº›æ•°æ®è¢«æ¯å, ä½ å°†ä¸å¾—ä¸ä½¿ç”¨æœ€æ–°çš„备份æ¢å¤." -#: access/transam/xlog.c:5973 +#: access/transam/xlog.c:6245 #, c-format msgid "database system was interrupted while in recovery at log time %s" msgstr "当日志时间%s进行æ¢å¤æ—¶ï¼Œæ•°æ®åº“系统被中断" -#: access/transam/xlog.c:5975 +#: access/transam/xlog.c:6247 #, c-format -msgid "" -"If this has occurred more than once some data might be corrupted and you " -"might need to choose an earlier recovery target." -msgstr "" -"如果这ç§çŽ°è±¡å¤šæ¬¡å‘生,那么表示数æ®å¯èƒ½å·²ç»æŸå,您å¯èƒ½éœ€è¦é€‰æ‹©æ›´æ—©ä¸€ç‚¹çš„æ¢å¤" -"目标" +msgid "If this has occurred more than once some data might be corrupted and you might need to choose an earlier recovery target." +msgstr "如果这ç§çŽ°è±¡å¤šæ¬¡å‘生,那么表示数æ®å¯èƒ½å·²ç»æŸå,您å¯èƒ½éœ€è¦é€‰æ‹©æ›´æ—©ä¸€ç‚¹çš„æ¢å¤ç›®æ ‡" -#: access/transam/xlog.c:5979 +#: access/transam/xlog.c:6251 #, c-format msgid "database system was interrupted; last known up at %s" msgstr "æ•°æ®åº“系统中断;上一次的å¯åŠ¨æ—¶é—´æ˜¯åœ¨%s" -#: access/transam/xlog.c:6035 +#: access/transam/xlog.c:6307 #, c-format msgid "entering standby mode" msgstr "正在进入备用模å¼" -#: access/transam/xlog.c:6038 +#: access/transam/xlog.c:6310 #, c-format msgid "starting point-in-time recovery to XID %u" msgstr "开始执行到XID %u的基于时间点æ¢å¤" -#: access/transam/xlog.c:6042 +#: access/transam/xlog.c:6314 #, c-format msgid "starting point-in-time recovery to %s" msgstr "开始执行到%s的基于时间点æ¢å¤" -#: access/transam/xlog.c:6046 +#: access/transam/xlog.c:6318 #, c-format msgid "starting point-in-time recovery to \"%s\"" msgstr "开始执行到基于时间点æ¢å¤çš„æ—¶é—´ç‚¹\"%s\"" -#: access/transam/xlog.c:6050 +#: access/transam/xlog.c:6322 +#, c-format +msgid "starting point-in-time recovery to WAL location (LSN) \"%X/%X\"" +msgstr "开始执行到基于时间点æ¢å¤åˆ°WALä½ç½®(LSN) \"%X/%X\"" + +#: access/transam/xlog.c:6327 #, c-format msgid "starting point-in-time recovery to earliest consistent point" msgstr "开始执行到最早一致点的基于时间点æ¢å¤" -#: access/transam/xlog.c:6053 +#: access/transam/xlog.c:6330 #, c-format msgid "starting archive recovery" msgstr "开始归档æ¢å¤" -#: access/transam/xlog.c:6097 access/transam/xlog.c:6225 +#: access/transam/xlog.c:6384 access/transam/xlog.c:6516 #, c-format msgid "checkpoint record is at %X/%X" msgstr "checkpoint 记录ä½ç½®åœ¨ %X/%X" -#: access/transam/xlog.c:6111 +#: access/transam/xlog.c:6398 #, c-format msgid "could not find redo location referenced by checkpoint record" msgstr "无法找到checkpoint 记录对应的é‡åšæ—¥å¿—ä½ç½®" -#: access/transam/xlog.c:6112 access/transam/xlog.c:6119 +#: access/transam/xlog.c:6399 access/transam/xlog.c:6409 #, c-format msgid "" -"If you are not restoring from a backup, try removing the file \"%s/" -"backup_label\"." -msgstr "å¦‚æžœä½ ä¸æ˜¯ä»Žå¤‡ä»½æ¢å¤, 请删除 \"%s/backup_label\"." +"If you are restoring from a backup, touch \"%s/recovery.signal\" and add required recovery options.\n" +"If you are not restoring from a backup, try removing the file \"%s/backup_label\".\n" +"Be careful: removing \"%s/backup_label\" will result in a corrupt cluster if restoring from a backup." +msgstr "" -#: access/transam/xlog.c:6118 +#: access/transam/xlog.c:6408 #, c-format msgid "could not locate required checkpoint record" msgstr "无法找到需è¦çš„ checkpoint 记录" -#: access/transam/xlog.c:6144 commands/tablespace.c:645 +#: access/transam/xlog.c:6437 commands/tablespace.c:646 #, c-format msgid "could not create symbolic link \"%s\": %m" msgstr "无法创建符å·é“¾æŽ¥ \"%s\": %m" -#: access/transam/xlog.c:6176 +#: access/transam/xlog.c:6469 access/transam/xlog.c:6475 #, c-format msgid "ignoring file \"%s\" because no file \"%s\" exists" msgstr "忽略文件\"%s\",因为ä¸å­˜åœ¨æ–‡ä»¶\"%s\"" -#: access/transam/xlog.c:6178 access/transam/xlog.c:10918 +#: access/transam/xlog.c:6471 access/transam/xlog.c:11458 #, c-format msgid "File \"%s\" was renamed to \"%s\"." msgstr "文件\"%s\" è¢«é‡æ–°å‘½å为\"%s\"。" -#: access/transam/xlog.c:6182 -#, c-format -msgid "ignoring \"%s\" file because no \"%s\" file exists" -msgstr "忽略\"%s\"文件,因为ä¸å­˜åœ¨\"%s\"文件" - -#: access/transam/xlog.c:6184 +#: access/transam/xlog.c:6477 #, c-format msgid "Could not rename file \"%s\" to \"%s\": %m." msgstr "无法把文件\"%s\"é‡å‘½å为\"%s\":%m。" -#: access/transam/xlog.c:6235 access/transam/xlog.c:6250 +#: access/transam/xlog.c:6528 #, c-format msgid "could not locate a valid checkpoint record" msgstr "无法找到一个有效的 checkpoint 记录" -#: access/transam/xlog.c:6244 -#, c-format -msgid "using previous checkpoint record at %X/%X" -msgstr "使用在 %X/%X çš„å‰ä¸€ä¸ª checkpoint 记录" - -#: access/transam/xlog.c:6288 +#: access/transam/xlog.c:6566 #, c-format msgid "requested timeline %u is not a child of this server's history" msgstr "æ‰€è¦æ±‚的时间线%uä¸åœ¨æœåŠ¡å™¨çš„åŽ†å²æ—¶é—´çº¿é‡Œ" -#: access/transam/xlog.c:6290 +#: access/transam/xlog.c:6568 #, c-format -msgid "" -"Latest checkpoint is at %X/%X on timeline %u, but in the history of the " -"requested timeline, the server forked off from that timeline at %X/%X." -msgstr "" -"最近的检查点ä½äºŽ%X/%X,时间点为%u, ä½†æ˜¯åœ¨è¯·æ±‚çš„åŽ†å²æ—¶é—´ç‚¹ä¸­ï¼ŒæœåŠ¡å™¨ç«¯åœ¨é‚£ä¸ªæ—¶" -"间点会产生分支%X/%X." +msgid "Latest checkpoint is at %X/%X on timeline %u, but in the history of the requested timeline, the server forked off from that timeline at %X/%X." +msgstr "最近的检查点ä½äºŽ%X/%X,时间点为%u, ä½†æ˜¯åœ¨è¯·æ±‚çš„åŽ†å²æ—¶é—´ç‚¹ä¸­ï¼ŒæœåŠ¡å™¨ç«¯åœ¨é‚£ä¸ªæ—¶é—´ç‚¹ä¼šäº§ç”Ÿåˆ†æ”¯%X/%X." -#: access/transam/xlog.c:6306 +#: access/transam/xlog.c:6584 #, c-format -msgid "" -"requested timeline %u does not contain minimum recovery point %X/%X on " -"timeline %u" +msgid "requested timeline %u does not contain minimum recovery point %X/%X on timeline %u" msgstr "æ‰€è¦æ±‚的时间线%uä¸åŒ…嫿œ€å°æ¢å¤ç‚¹%X/%X,在时间线%u处" -#: access/transam/xlog.c:6337 +#: access/transam/xlog.c:6615 #, c-format msgid "invalid next transaction ID" msgstr "无效的下一个事务 ID" -#: access/transam/xlog.c:6420 +#: access/transam/xlog.c:6709 #, c-format msgid "invalid redo in checkpoint record" msgstr "在检查点记录中无效的redoæ“作" -#: access/transam/xlog.c:6431 +#: access/transam/xlog.c:6720 #, c-format msgid "invalid redo record in shutdown checkpoint" msgstr "在关闭检查点中的redo记录无效" -#: access/transam/xlog.c:6459 +#: access/transam/xlog.c:6748 #, c-format -msgid "" -"database system was not properly shut down; automatic recovery in progress" +msgid "database system was not properly shut down; automatic recovery in progress" msgstr "æ•°æ®åº“系统没有正确的关闭; 处于自动æ¢å¤çжæ€ä¸­" -#: access/transam/xlog.c:6463 +#: access/transam/xlog.c:6752 #, c-format msgid "crash recovery starts in timeline %u and has target timeline %u" msgstr "崩溃æ¢å¤å¼€å§‹äºŽæ—¶é—´çº¿%u, 目标时间线是%u" -#: access/transam/xlog.c:6507 +#: access/transam/xlog.c:6795 #, c-format msgid "backup_label contains data inconsistent with control file" msgstr "backup_label 包å«äº†ä¸ŽæŽ§åˆ¶æ–‡ä»¶ä¸ä¸€è‡´çš„æ•°æ®" -#: access/transam/xlog.c:6508 +#: access/transam/xlog.c:6796 #, c-format -msgid "" -"This means that the backup is corrupted and you will have to use another " -"backup for recovery." +msgid "This means that the backup is corrupted and you will have to use another backup for recovery." msgstr "è¿™æ„味ç€ä¸€äº›æ•°æ®å¤‡ä»½å·²æ¯å, ä½ å°†ä¸å¾—ä¸ä½¿ç”¨åˆ«çš„备份进行æ¢å¤." -#: access/transam/xlog.c:6582 +#: access/transam/xlog.c:6887 #, c-format msgid "initializing for hot standby" msgstr "正在为热备进行åˆå§‹åŒ–" -#: access/transam/xlog.c:6714 +#: access/transam/xlog.c:7019 #, c-format msgid "redo starts at %X/%X" msgstr "redo 在 %X/%X 开始" -#: access/transam/xlog.c:6939 +#: access/transam/xlog.c:7243 #, c-format msgid "requested recovery stop point is before consistent recovery point" msgstr "æ‰€è¦æ±‚çš„æ¢å¤åœæ­¢ç‚¹åœ¨ä¸€è‡´æ€§æ¢å¤ç‚¹ä¹‹å‰" -#: access/transam/xlog.c:6977 +#: access/transam/xlog.c:7281 #, c-format msgid "redo done at %X/%X" msgstr "redo 在 %X/%X 完æˆ" -#: access/transam/xlog.c:6982 access/transam/xlog.c:8906 +#: access/transam/xlog.c:7286 #, c-format msgid "last completed transaction was at log time %s" msgstr "上一次完æˆäº‹åŠ¡æ˜¯åœ¨æ—¥å¿—æ—¶é—´%s完æˆçš„." -#: access/transam/xlog.c:6991 +#: access/transam/xlog.c:7295 #, c-format msgid "redo is not required" msgstr "ä¸éœ€è¦ redo" -#: access/transam/xlog.c:7066 access/transam/xlog.c:7070 +#: access/transam/xlog.c:7370 access/transam/xlog.c:7374 #, c-format msgid "WAL ends before end of online backup" msgstr "è”æœºå¤‡ä»½ç»ˆæ­¢ä¹‹å‰ï¼ŒWALå·²ç»ç»ˆæ­¢" -#: access/transam/xlog.c:7067 +#: access/transam/xlog.c:7371 #, c-format -msgid "" -"All WAL generated while online backup was taken must be available at " -"recovery." +msgid "All WAL generated while online backup was taken must be available at recovery." msgstr "æ‰€æœ‰è”æœºå¤‡ä»½æ—¶äº§ç”Ÿçš„WAL日志在æ¢å¤æ—¶å¿…须存在." -#: access/transam/xlog.c:7071 +#: access/transam/xlog.c:7375 #, c-format -msgid "" -"Online backup started with pg_start_backup() must be ended with " -"pg_stop_backup(), and all WAL up to that point must be available at recovery." -msgstr "" -"ç”±pg_start_backup()å‘èµ·çš„è”æœºå¤‡ä»½å¿…须通过调用pg_stop_backup()æ¥ç»ˆæ­¢, 并且到那" -"一刻为止所有的WAL日志在æ¢å¤æ—¶å¿…须存在." +msgid "Online backup started with pg_start_backup() must be ended with pg_stop_backup(), and all WAL up to that point must be available at recovery." +msgstr "ç”±pg_start_backup()å‘èµ·çš„è”æœºå¤‡ä»½å¿…须通过调用pg_stop_backup()æ¥ç»ˆæ­¢, 并且到那一刻为止所有的WAL日志在æ¢å¤æ—¶å¿…须存在." -#: access/transam/xlog.c:7074 +#: access/transam/xlog.c:7378 #, c-format msgid "WAL ends before consistent recovery point" msgstr "在一致性æ¢å¤ç‚¹å‰ç»“æŸWAL" -#: access/transam/xlog.c:7101 +#: access/transam/xlog.c:7412 #, c-format msgid "selected new timeline ID: %u" msgstr "已选择的新时间线ID:%u" -#: access/transam/xlog.c:7512 +#: access/transam/xlog.c:7849 #, c-format msgid "consistent recovery state reached at %X/%X" msgstr "在%X/%X上已到达一致性æ¢å¤çжæ€" -#: access/transam/xlog.c:7703 +#: access/transam/xlog.c:8041 #, c-format msgid "invalid primary checkpoint link in control file" msgstr "在控制文件中无效的主 checkpoint 链接" -#: access/transam/xlog.c:7707 -#, c-format -msgid "invalid secondary checkpoint link in control file" -msgstr "在控制文件中无效的次 checkpoint 链接" - -#: access/transam/xlog.c:7711 +#: access/transam/xlog.c:8045 #, c-format msgid "invalid checkpoint link in backup_label file" msgstr "在 backup_label 文件中无效的 checkpoint 链接" -#: access/transam/xlog.c:7728 +#: access/transam/xlog.c:8062 #, c-format msgid "invalid primary checkpoint record" msgstr "无效的主 checkpoint 记录" -#: access/transam/xlog.c:7732 -#, c-format -msgid "invalid secondary checkpoint record" -msgstr "无效的次 checkpoint 记录" - -#: access/transam/xlog.c:7736 +#: access/transam/xlog.c:8066 #, c-format msgid "invalid checkpoint record" msgstr "无效的 checkpoint 记录" -#: access/transam/xlog.c:7747 +#: access/transam/xlog.c:8077 #, c-format msgid "invalid resource manager ID in primary checkpoint record" msgstr "在主 checkpoint 记录中的无效资æºç®¡ç†å™¨ ID" -#: access/transam/xlog.c:7751 -#, c-format -msgid "invalid resource manager ID in secondary checkpoint record" -msgstr "在次 checkpoint 记录中的无效资æºç®¡ç†å™¨ ID" - -#: access/transam/xlog.c:7755 +#: access/transam/xlog.c:8081 #, c-format msgid "invalid resource manager ID in checkpoint record" msgstr "在 checkpoint 记录中的无效资æºç®¡ç†å™¨ ID" -#: access/transam/xlog.c:7767 +#: access/transam/xlog.c:8094 #, c-format msgid "invalid xl_info in primary checkpoint record" msgstr "在主 checkpoint 记录中无效的 xl_info" -#: access/transam/xlog.c:7771 -#, c-format -msgid "invalid xl_info in secondary checkpoint record" -msgstr "在次 checkpoint 记录中无效的 xl_info" - -#: access/transam/xlog.c:7775 +#: access/transam/xlog.c:8098 #, c-format msgid "invalid xl_info in checkpoint record" msgstr "在 checkpoint 记录中无效的 xl_info" -#: access/transam/xlog.c:7786 +#: access/transam/xlog.c:8109 #, c-format msgid "invalid length of primary checkpoint record" msgstr "无效的主 checkpoint 记录长度" -#: access/transam/xlog.c:7790 -#, c-format -msgid "invalid length of secondary checkpoint record" -msgstr "无效的次 checkpoint 记录长度" - -#: access/transam/xlog.c:7794 +#: access/transam/xlog.c:8113 #, c-format msgid "invalid length of checkpoint record" msgstr "无效的 checkpoint 记录长度" -#: access/transam/xlog.c:7962 +#: access/transam/xlog.c:8293 #, c-format msgid "shutting down" msgstr "正在关闭" -#: access/transam/xlog.c:8475 +#: access/transam/xlog.c:8613 #, c-format -msgid "" -"concurrent transaction log activity while database system is shutting down" -msgstr "当数æ®åº“正在关闭时, 仿œ‰æ´»è·ƒçš„å¹¶å‘事物日志" +msgid "checkpoint skipped because system is idle" +msgstr "由于系统空闲,跳过了检查点" + +#: access/transam/xlog.c:8813 +#, c-format +msgid "concurrent write-ahead log activity while database system is shutting down" +msgstr "当数æ®åº“正在关闭时, 仿œ‰æ´»è·ƒçš„å¹¶å‘预写日志" -#: access/transam/xlog.c:8726 +#: access/transam/xlog.c:9069 #, c-format msgid "skipping restartpoint, recovery has already ended" msgstr "æ­£åœ¨è·³è¿‡é‡æ–°å¯åŠ¨ç‚¹, æ¢å¤å·²ç»ç»“æŸ" -#: access/transam/xlog.c:8749 +#: access/transam/xlog.c:9092 #, c-format msgid "skipping restartpoint, already performed at %X/%X" msgstr "è·³è¿‡é‡æ–°å¯åŠ¨ç‚¹ï¼Œå®ƒå·²ç»åœ¨%X/%X上执行了." -#: access/transam/xlog.c:8904 +#: access/transam/xlog.c:9259 #, c-format msgid "recovery restart point at %X/%X" msgstr "æ¢å¤å¾—釿–°å¯åŠ¨ç‚¹æ˜¯åœ¨%X/%X开始" -#: access/transam/xlog.c:9037 +#: access/transam/xlog.c:9261 +#, c-format +msgid "Last completed transaction was at log time %s." +msgstr "上一次完æˆäº‹åŠ¡æ˜¯åœ¨æ—¥å¿—æ—¶é—´%s完æˆçš„." + +#: access/transam/xlog.c:9395 #, c-format msgid "restore point \"%s\" created at %X/%X" msgstr "æ¢å¤ç‚¹\"%s\",创建于%X/%X" -#: access/transam/xlog.c:9167 +#: access/transam/xlog.c:9536 #, c-format -msgid "" -"unexpected previous timeline ID %u (current timeline ID %u) in checkpoint " -"record" +msgid "unexpected previous timeline ID %u (current timeline ID %u) in checkpoint record" msgstr "在检查点记录中出现未期望的时间线ID%u(当剿—¶é—´çº¿%u)" -#: access/transam/xlog.c:9176 +#: access/transam/xlog.c:9545 #, c-format msgid "unexpected timeline ID %u (after %u) in checkpoint record" msgstr "在检查点记录中出现未期望的时间线ID%u(在%u之åŽ)" -#: access/transam/xlog.c:9192 +#: access/transam/xlog.c:9561 #, c-format -msgid "" -"unexpected timeline ID %u in checkpoint record, before reaching minimum " -"recovery point %X/%X on timeline %u" -msgstr "" -"åœ¨è¾¾åˆ°æœ€å°æ¢å¤ç‚¹%2$X/%3$X之å‰ï¼Œæ—¶é—´ç‚¹%4$u处,在检查点记录中出现æ„外的时间点" -"ID %1$u" +msgid "unexpected timeline ID %u in checkpoint record, before reaching minimum recovery point %X/%X on timeline %u" +msgstr "åœ¨è¾¾åˆ°æœ€å°æ¢å¤ç‚¹%2$X/%3$X之å‰ï¼Œæ—¶é—´ç‚¹%4$u处,在检查点记录中出现æ„外的时间点ID %1$u" -#: access/transam/xlog.c:9263 +#: access/transam/xlog.c:9637 #, c-format msgid "online backup was canceled, recovery cannot continue" msgstr "在线备份æ“ä½œå·²å–æ¶ˆï¼Œæ¢å¤æ“作无法继续" -#: access/transam/xlog.c:9319 access/transam/xlog.c:9366 -#: access/transam/xlog.c:9389 +#: access/transam/xlog.c:9691 access/transam/xlog.c:9745 +#: access/transam/xlog.c:9768 #, c-format msgid "unexpected timeline ID %u (should be %u) in checkpoint record" msgstr "在检查点记录中出现未期望的时间线ID%u(应该是%u)" -#: access/transam/xlog.c:9664 -#, c-format -msgid "could not fsync log segment %s: %m" -msgstr "æ— æ³•åŒæ­¥ (fsync) 日志段 %s: %m" - -#: access/transam/xlog.c:9688 -#, c-format -msgid "could not fsync log file %s: %m" -msgstr "无法 fsync 日志文件 %s: %m" - -#: access/transam/xlog.c:9696 -#, c-format -msgid "could not fsync write-through log file %s: %m" +#: access/transam/xlog.c:10088 +#, fuzzy, c-format +#| msgid "could not fsync write-through log file %s: %m" +msgid "could not fsync write-through file \"%s\": %m" msgstr "æ— æ³•åŒæ­¥ (fsync) 写入日志文件%s: %m" -#: access/transam/xlog.c:9705 -#, c-format -msgid "could not fdatasync log file %s: %m" -msgstr "æ— æ³•åŒæ­¥ (fdatasync) 日志文件 %s: %m" +#: access/transam/xlog.c:10097 +#, fuzzy, c-format +#| msgid "could not fsync file \"%s\": %m" +msgid "could not fdatasync file \"%s\": %m" +msgstr "无法 fsync 文件 \"%s\": %m" -#: access/transam/xlog.c:9796 access/transam/xlog.c:10267 -#: access/transam/xlogfuncs.c:295 access/transam/xlogfuncs.c:322 -#: access/transam/xlogfuncs.c:361 access/transam/xlogfuncs.c:382 -#: access/transam/xlogfuncs.c:403 +#: access/transam/xlog.c:10190 access/transam/xlog.c:10719 +#: access/transam/xlogfuncs.c:290 access/transam/xlogfuncs.c:317 +#: access/transam/xlogfuncs.c:356 access/transam/xlogfuncs.c:377 +#: access/transam/xlogfuncs.c:398 #, c-format msgid "WAL control functions cannot be executed during recovery." msgstr "在æ¢å¤æœŸé—´æ— æ³•执行WAL控制函数" -#: access/transam/xlog.c:9805 access/transam/xlog.c:10276 +#: access/transam/xlog.c:10199 access/transam/xlog.c:10728 #, c-format msgid "WAL level not sufficient for making an online backup" msgstr "WAL的级别ä¸èƒ½æ»¡è¶³åœ¨çº¿å¤‡ä»½çš„è¦æ±‚" -#: access/transam/xlog.c:9806 access/transam/xlog.c:10277 -#: access/transam/xlogfuncs.c:328 +#: access/transam/xlog.c:10200 access/transam/xlog.c:10729 +#: access/transam/xlogfuncs.c:323 #, c-format -#| msgid "" -#| "wal_level must be set to \"archive\", \"hot_standby\", or \"logical\" at " -#| "server start." msgid "wal_level must be set to \"replica\" or \"logical\" at server start." msgstr "wal_level 必须在æœåС噍å¯åŠ¨çš„æ—¶å€™è¢«è®¾ç½®ä¸º \"replica\" 或 \"logical\"。" -#: access/transam/xlog.c:9811 +#: access/transam/xlog.c:10205 #, c-format msgid "backup label too long (max %d bytes)" msgstr "备份标签åè¶…é•¿(最大为%d字节)" -#: access/transam/xlog.c:9843 access/transam/xlog.c:10115 -#: access/transam/xlog.c:10153 +#: access/transam/xlog.c:10242 access/transam/xlog.c:10518 +#: access/transam/xlog.c:10556 #, c-format msgid "a backup is already in progress" msgstr "一个备份已ç»åœ¨è¿è¡Œä¸­" -#: access/transam/xlog.c:9844 +#: access/transam/xlog.c:10243 #, c-format msgid "Run pg_stop_backup() and try again." msgstr "è¿è¡Œpg_stop_backup(),然åŽé‡æ–°å°è¯•一次." -#: access/transam/xlog.c:9939 +#: access/transam/xlog.c:10339 #, c-format -msgid "" -"WAL generated with full_page_writes=off was replayed since last restartpoint" +msgid "WAL generated with full_page_writes=off was replayed since last restartpoint" msgstr "使用full_page_writes=off产生的WAL日志自最åŽä¸€æ¬¡é‡å¯ç‚¹ï¼Œå·²ç»é‡åšäº†" -#: access/transam/xlog.c:9941 access/transam/xlog.c:10440 -#, c-format -msgid "" -"This means that the backup being taken on the standby is corrupt and should " -"not be used. Enable full_page_writes and run CHECKPOINT on the master, and " -"then try an online backup again." -msgstr "" -"è¿™æ„味ç€å¤‡ç”¨èŠ‚ç‚¹ä¸Šçš„å¤‡ä»½å·²ç»æŸå,ä¸åº”该使用。å¯ç”¨ full_page_writes并在主节点" -"上è¿è¡ŒCHECKPOINT,然åŽå†è¯•ç€æ‰§è¡Œè”机备份." - -#: access/transam/xlog.c:10008 replication/basebackup.c:1038 -#: utils/adt/misc.c:498 +#: access/transam/xlog.c:10341 access/transam/xlog.c:10924 #, c-format -msgid "could not read symbolic link \"%s\": %m" -msgstr "无法读å–符å·é“¾æŽ¥ \"%s\": %m" +msgid "This means that the backup being taken on the standby is corrupt and should not be used. Enable full_page_writes and run CHECKPOINT on the master, and then try an online backup again." +msgstr "è¿™æ„味ç€å¤‡ç”¨èŠ‚ç‚¹ä¸Šçš„å¤‡ä»½å·²ç»æŸå,ä¸åº”该使用。å¯ç”¨ full_page_writes并在主节点上è¿è¡ŒCHECKPOINT,然åŽå†è¯•ç€æ‰§è¡Œè”机备份." -#: access/transam/xlog.c:10015 replication/basebackup.c:1043 -#: utils/adt/misc.c:503 +#: access/transam/xlog.c:10416 replication/basebackup.c:1237 +#: utils/adt/misc.c:329 #, c-format msgid "symbolic link \"%s\" target is too long" msgstr "符å·é“¾æŽ¥ \"%s\" 目标超长" -#: access/transam/xlog.c:10068 commands/tablespace.c:395 -#: commands/tablespace.c:557 replication/basebackup.c:1059 -#: utils/adt/misc.c:511 +#: access/transam/xlog.c:10468 commands/tablespace.c:394 +#: commands/tablespace.c:558 replication/basebackup.c:1252 utils/adt/misc.c:337 #, c-format msgid "tablespaces are not supported on this platform" msgstr "在此平å°ä¸Šä¸æ”¯æŒè¡¨ç©ºé—´" -#: access/transam/xlog.c:10109 access/transam/xlog.c:10147 -#: access/transam/xlog.c:10326 access/transam/xlogarchive.c:106 -#: access/transam/xlogarchive.c:265 commands/copy.c:1778 commands/copy.c:2804 -#: commands/extension.c:3109 commands/tablespace.c:786 -#: commands/tablespace.c:877 guc-file.l:1003 replication/basebackup.c:407 -#: replication/basebackup.c:475 replication/logical/snapbuild.c:1493 -#: storage/file/copydir.c:72 storage/file/copydir.c:115 storage/file/fd.c:2826 -#: storage/file/fd.c:2918 utils/adt/dbsize.c:70 utils/adt/dbsize.c:220 -#: utils/adt/dbsize.c:300 utils/adt/genfile.c:114 utils/adt/genfile.c:333 +#: access/transam/xlog.c:10519 access/transam/xlog.c:10557 #, c-format -msgid "could not stat file \"%s\": %m" -msgstr "æ— æ³•å–æ–‡ä»¶ \"%s\" 的状æ€: %m" - -#: access/transam/xlog.c:10116 access/transam/xlog.c:10154 -#, c-format -msgid "" -"If you're sure there is no backup in progress, remove file \"%s\" and try " -"again." +msgid "If you're sure there is no backup in progress, remove file \"%s\" and try again." msgstr "如果你确认没有其他备份进程在è¿è¡Œ, 删除文件 \"%s\", ç„¶åŽé‡è¯•." -#: access/transam/xlog.c:10133 access/transam/xlog.c:10171 -#: access/transam/xlog.c:10501 -#, c-format -msgid "could not write file \"%s\": %m" -msgstr "无法写入文件 \"%s\": %m" - -#: access/transam/xlog.c:10290 +#: access/transam/xlog.c:10744 #, c-format -#| msgid "a backup is not in progress" msgid "exclusive backup not in progress" msgstr "排除备份ä¸åœ¨è¿è¡Œä¸­" -#: access/transam/xlog.c:10330 +#: access/transam/xlog.c:10771 #, c-format msgid "a backup is not in progress" msgstr "没有备份在è¿è¡Œä¸­" -#: access/transam/xlog.c:10375 access/transam/xlog.c:10388 -#: access/transam/xlog.c:10728 access/transam/xlog.c:10734 -#: access/transam/xlog.c:10818 access/transam/xlogfuncs.c:696 +#: access/transam/xlog.c:10857 access/transam/xlog.c:10870 +#: access/transam/xlog.c:11231 access/transam/xlog.c:11237 +#: access/transam/xlog.c:11285 access/transam/xlog.c:11358 +#: access/transam/xlogfuncs.c:693 #, c-format msgid "invalid data in file \"%s\"" msgstr "文件 \"%s\" 中存在无效数æ®" -#: access/transam/xlog.c:10392 replication/basebackup.c:936 +#: access/transam/xlog.c:10874 replication/basebackup.c:1089 #, c-format msgid "the standby was promoted during online backup" msgstr "è”æœºå¤‡ä»½æœŸé—´ï¼Œå¤‡ç”¨èŠ‚ç‚¹å·²æå‡ä¸ºä¸»èŠ‚ç‚¹" -#: access/transam/xlog.c:10393 replication/basebackup.c:937 +#: access/transam/xlog.c:10875 replication/basebackup.c:1090 #, c-format -msgid "" -"This means that the backup being taken is corrupt and should not be used. " -"Try taking another online backup." +msgid "This means that the backup being taken is corrupt and should not be used. Try taking another online backup." msgstr "è¿™æ„味ç€å¤‡ç”¨èŠ‚ç‚¹ä¸Šçš„å¤‡ä»½å·²ç»æŸå,ä¸åº”该使用. 请å°è¯•冿¬¡æ‰§è¡Œè”机备份." -#: access/transam/xlog.c:10438 +#: access/transam/xlog.c:10922 #, c-format -msgid "" -"WAL generated with full_page_writes=off was replayed during online backup" +msgid "WAL generated with full_page_writes=off was replayed during online backup" msgstr "ç”±full_page_writes=off产生的WALæ—¥å¿—åœ¨è”æœºå¤‡ä»½æœŸé—´å·²ç»å®Œæˆé‡åš" -#: access/transam/xlog.c:10550 -#, c-format -msgid "" -"pg_stop_backup cleanup done, waiting for required WAL segments to be archived" +#: access/transam/xlog.c:11042 +#, fuzzy, c-format +#| msgid "pg_stop_backup cleanup done, waiting for required WAL segments to be archived" +msgid "base backup done, waiting for required WAL segments to be archived" msgstr "pg_stop_backupå‘½ä»¤æ‰€æ‰§è¡Œçš„æ¸…ç†æ“作已完æˆï¼Œæ­£åœ¨ç­‰å¾…æ‰€è¦æ±‚çš„WAL段归档" -#: access/transam/xlog.c:10560 -#, c-format -msgid "" -"pg_stop_backup still waiting for all required WAL segments to be archived " -"(%d seconds elapsed)" +#: access/transam/xlog.c:11052 +#, fuzzy, c-format +#| msgid "pg_stop_backup still waiting for all required WAL segments to be archived (%d seconds elapsed)" +msgid "still waiting for all required WAL segments to be archived (%d seconds elapsed)" msgstr "pg_stop_backup在等待所有需è¦çš„WAL段归档(已过去%dç§’)" -#: access/transam/xlog.c:10562 +#: access/transam/xlog.c:11054 +#, fuzzy, c-format +#| msgid "Check that your archive_command is executing properly. pg_stop_backup can be canceled safely, but the database backup will not be usable without all the WAL segments." +msgid "Check that your archive_command is executing properly. You can safely cancel this backup, but the database backup will not be usable without all the WAL segments." +msgstr "è¯·æ£€æŸ¥æ‚¨çš„å½’æ¡£å‘½ä»¤æ˜¯å¦æ­£ç¡®æ‰§è¡Œã€‚pg_stop_backup命令å¯ä»¥å®‰å…¨é€€å‡ºï¼Œä½†æ˜¯å¦‚果没有所有需è¦çš„WAL段,数æ®åº“备份将无法使用." + +#: access/transam/xlog.c:11061 +#, fuzzy, c-format +#| msgid "pg_stop_backup complete, all required WAL segments have been archived" +msgid "all required WAL segments have been archived" +msgstr "pg_stop_backup 执行完æˆï¼Œæ‰€æœ‰éœ€è¦çš„WAL段都已ç»å½’档完æˆã€‚" + +#: access/transam/xlog.c:11065 #, c-format -msgid "" -"Check that your archive_command is executing properly. pg_stop_backup can " -"be canceled safely, but the database backup will not be usable without all " -"the WAL segments." -msgstr "" -"è¯·æ£€æŸ¥æ‚¨çš„å½’æ¡£å‘½ä»¤æ˜¯å¦æ­£ç¡®æ‰§è¡Œã€‚pg_stop_backup命令å¯ä»¥å®‰å…¨é€€å‡ºï¼Œä½†æ˜¯å¦‚果没有" -"所有需è¦çš„WAL段,数æ®åº“备份将无法使用." +msgid "WAL archiving is not enabled; you must ensure that all required WAL segments are copied through other means to complete the backup" +msgstr "没有å¯ç”¨WALå½’æ¡£ï¼›æ‚¨å¿…é¡»ç¡®ä¿æ‰€æœ‰çš„WAL段已通过其他的方法拷è´ï¼Œè¿™æ ·æ‰èƒ½å®Œæˆå¤‡ä»½" -#: access/transam/xlog.c:10569 +#: access/transam/xlog.c:11268 #, c-format -msgid "pg_stop_backup complete, all required WAL segments have been archived" -msgstr "pg_stop_backup 执行完æˆï¼Œæ‰€æœ‰éœ€è¦çš„WAL段都已ç»å½’档完æˆã€‚" +msgid "backup time %s in file \"%s\"" +msgstr "文件 \"%2$s\"中的备份时间%1$s" -#: access/transam/xlog.c:10573 +#: access/transam/xlog.c:11273 #, c-format -msgid "" -"WAL archiving is not enabled; you must ensure that all required WAL segments " -"are copied through other means to complete the backup" -msgstr "" -"没有å¯ç”¨WALå½’æ¡£ï¼›æ‚¨å¿…é¡»ç¡®ä¿æ‰€æœ‰çš„WAL段已通过其他的方法拷è´ï¼Œè¿™æ ·æ‰èƒ½å®Œæˆå¤‡ä»½" +msgid "backup label %s in file \"%s\"" +msgstr "文件 \"%2$s\"中的备份标签%1$s" + +#: access/transam/xlog.c:11286 +#, c-format +msgid "Timeline ID parsed is %u, but expected %u" +msgstr "è§£æžçš„æ—¶é—´çº¿ID为%u,但应为%u" + +#: access/transam/xlog.c:11290 +#, c-format +msgid "backup timeline %u in file \"%s\"" +msgstr "文件\"%2$s\"中的备份时间线%1$u" -#. translator: %s is an XLog record description -#: access/transam/xlog.c:10858 +#. translator: %s is a WAL record description +#: access/transam/xlog.c:11398 #, c-format -#| msgid "xlog redo %s" -msgid "xlog redo at %X/%X for %s" -msgstr "%3$s xlog é‡åšåœ¨ %1$X/%2$X ä½ç½®" +msgid "WAL redo at %X/%X for %s" +msgstr "%3$s WAL é‡åšåœ¨ %1$X/%2$X ä½ç½®" -#: access/transam/xlog.c:10907 +#: access/transam/xlog.c:11447 #, c-format msgid "online backup mode was not canceled" msgstr "åœ¨çº¿å¤‡ä»½æ¨¡å¼æ²¡æœ‰å–消" -#: access/transam/xlog.c:10908 +#: access/transam/xlog.c:11448 #, c-format msgid "File \"%s\" could not be renamed to \"%s\": %m." msgstr "文件\"%s\"ä¸èƒ½è¢«é‡å‘½å为\"%s\":%m。" -#: access/transam/xlog.c:10917 access/transam/xlog.c:10929 -#: access/transam/xlog.c:10939 +#: access/transam/xlog.c:11457 access/transam/xlog.c:11469 +#: access/transam/xlog.c:11479 #, c-format msgid "online backup mode canceled" msgstr "在线备份模å¼å·²å–消" -#: access/transam/xlog.c:10930 +#: access/transam/xlog.c:11470 #, c-format -msgid "" -"Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." +msgid "Files \"%s\" and \"%s\" were renamed to \"%s\" and \"%s\", respectively." msgstr "文件\"%s\"å’Œ\"%s\"分别被é‡å‘½å为\"%s\"å’Œ\"%s\"。" -#: access/transam/xlog.c:10940 +#: access/transam/xlog.c:11480 #, c-format -msgid "" -"File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to " -"\"%s\": %m." +msgid "File \"%s\" was renamed to \"%s\", but file \"%s\" could not be renamed to \"%s\": %m." msgstr "文件\"%s\"被é‡å‘½å为\"%s\",但文件\"%s\"无法被é‡å‘½å为\"%s\":%m。" -#: access/transam/xlog.c:11062 access/transam/xlogutils.c:723 -#: replication/walreceiver.c:973 replication/walsender.c:2116 -#, c-format -msgid "could not seek in log segment %s to offset %u: %m" -msgstr "无法在日志段%s中查找, åç§»é‡ %u: %m" - -#: access/transam/xlog.c:11074 +#: access/transam/xlog.c:11613 #, c-format msgid "could not read from log segment %s, offset %u: %m" msgstr "无法从日志段%s中读å–åç§»é‡ %u: %m" -#: access/transam/xlog.c:11548 +#: access/transam/xlog.c:11619 replication/walsender.c:2489 +#, fuzzy, c-format +#| msgid "could not read from log segment %s, offset %u: %m" +msgid "could not read from log segment %s, offset %u: read %d of %zu" +msgstr "无法从日志段%s中读å–åç§»é‡ %u: %m" + +#: access/transam/xlog.c:12152 #, c-format msgid "received promote request" msgstr "æŽ¥æ”¶åˆ°ææˆ–请求" -#: access/transam/xlog.c:11561 -#, c-format -msgid "trigger file found: %s" +#: access/transam/xlog.c:12165 +#, fuzzy, c-format +#| msgid "trigger file found: %s" +msgid "promote trigger file found: %s" msgstr "已找到触å‘器文件:%s" -#: access/transam/xlog.c:11570 -#, c-format -msgid "could not stat trigger file \"%s\": %m" +#: access/transam/xlog.c:12174 +#, fuzzy, c-format +#| msgid "could not stat trigger file \"%s\": %m" +msgid "could not stat promote trigger file \"%s\": %m" msgstr "无法统计触å‘器文件 \"%s\": %m" -#: access/transam/xlogarchive.c:244 +#: access/transam/xlogarchive.c:243 #, c-format msgid "archive file \"%s\" has wrong size: %lu instead of %lu" msgstr "归档文件\"%s\"大å°é”™è¯¯:应该是%luè€Œä¸æ˜¯%lu" -#: access/transam/xlogarchive.c:253 +#: access/transam/xlogarchive.c:252 #, c-format msgid "restored log file \"%s\" from archive" msgstr "从归档中æ¢å¤æ—¥å¿—文件 \"%s\"" -#: access/transam/xlogarchive.c:303 +#: access/transam/xlogarchive.c:297 #, c-format msgid "could not restore file \"%s\" from archive: %s" msgstr "无法从归档文件%2$s中æ¢å¤æ–‡ä»¶ \"%1$s\"" -#. translator: First %s represents a recovery.conf parameter name like +#. translator: First %s represents a postgresql.conf parameter name like #. "recovery_end_command", the 2nd is the value of that parameter, the #. third an already translated error message. -#: access/transam/xlogarchive.c:415 +#: access/transam/xlogarchive.c:406 #, c-format msgid "%s \"%s\": %s" msgstr "%s \"%s\": %s" -#: access/transam/xlogarchive.c:458 replication/logical/snapbuild.c:1621 -#: replication/slot.c:470 replication/slot.c:981 replication/slot.c:1089 -#: storage/file/fd.c:635 storage/file/fd.c:693 utils/time/snapmgr.c:1198 +#: access/transam/xlogarchive.c:449 postmaster/syslogger.c:1524 +#: replication/logical/snapbuild.c:1670 replication/slot.c:598 +#: replication/slot.c:1210 replication/slot.c:1332 storage/file/fd.c:664 +#: storage/file/fd.c:759 utils/time/snapmgr.c:1320 #, c-format msgid "could not rename file \"%s\" to \"%s\": %m" msgstr "无法把文件 \"%s\" é‡å‘½å为 \"%s\": %m" -#: access/transam/xlogarchive.c:525 access/transam/xlogarchive.c:589 +#: access/transam/xlogarchive.c:516 access/transam/xlogarchive.c:580 #, c-format msgid "could not create archive status file \"%s\": %m" msgstr "æ— æ³•åˆ›å»ºå½’æ¡£çŠ¶æ€æ–‡ä»¶ \"%s\": %m" -#: access/transam/xlogarchive.c:533 access/transam/xlogarchive.c:597 +#: access/transam/xlogarchive.c:524 access/transam/xlogarchive.c:588 #, c-format msgid "could not write archive status file \"%s\": %m" msgstr "æ— æ³•å†™å…¥å½’æ¡£çŠ¶æ€æ–‡ä»¶ \"%s\": %m" -#: access/transam/xlogfuncs.c:58 +#: access/transam/xlogfuncs.c:57 #, c-format msgid "aborting backup due to backend exiting before pg_stop_backup was called" msgstr "由于åŽç«¯åœ¨ pg_stop_backup 被调用å‰é€€å‡ºè€Œä¸­æ–­å¤‡ä»½" -#: access/transam/xlogfuncs.c:88 +#: access/transam/xlogfuncs.c:87 #, c-format -#| msgid "a backup is already in progress" msgid "a backup is already in progress in this session" msgstr "这个会è¯ä¸­å·²ç»æœ‰ä¸€ä¸ªå¤‡ä»½åœ¨è¿è¡Œä¸­" -#: access/transam/xlogfuncs.c:94 commands/tablespace.c:709 -#: commands/tablespace.c:719 postmaster/postmaster.c:1395 -#: replication/basebackup.c:295 replication/basebackup.c:635 -#: storage/file/copydir.c:53 storage/file/copydir.c:96 storage/file/fd.c:2292 -#: storage/file/fd.c:2891 storage/ipc/dsm.c:300 utils/adt/genfile.c:439 -#: utils/adt/misc.c:411 utils/misc/tzparser.c:339 -#, c-format -msgid "could not open directory \"%s\": %m" -msgstr "无法打开目录 \"%s\": %m" - -#: access/transam/xlogfuncs.c:155 access/transam/xlogfuncs.c:229 +#: access/transam/xlogfuncs.c:145 access/transam/xlogfuncs.c:227 #, c-format -#| msgid "a backup is not in progress" msgid "non-exclusive backup in progress" msgstr "éžæŽ’é™¤å¤‡ä»½åœ¨è¿è¡Œä¸­" -#: access/transam/xlogfuncs.c:156 access/transam/xlogfuncs.c:230 +#: access/transam/xlogfuncs.c:146 access/transam/xlogfuncs.c:228 #, c-format -msgid "did you mean to use pg_stop_backup('f')?" +msgid "Did you mean to use pg_stop_backup('f')?" msgstr "你是想使用 pg_stop_backup('f') å—?" -#: access/transam/xlogfuncs.c:200 commands/event_trigger.c:1449 -#: commands/event_trigger.c:2000 commands/extension.c:1728 -#: commands/extension.c:1837 commands/extension.c:2030 commands/prepare.c:702 -#: executor/execQual.c:1757 executor/execQual.c:1782 executor/execQual.c:2157 -#: executor/execQual.c:5386 executor/functions.c:1024 foreign/foreign.c:598 -#: replication/logical/logicalfuncs.c:175 replication/logical/origin.c:1391 -#: replication/slotfuncs.c:189 replication/walsender.c:2761 -#: utils/adt/jsonfuncs.c:1483 utils/adt/jsonfuncs.c:1615 -#: utils/adt/jsonfuncs.c:1805 utils/adt/jsonfuncs.c:1934 -#: utils/adt/jsonfuncs.c:2702 utils/adt/pgstatfuncs.c:552 -#: utils/adt/pgstatfuncs.c:653 utils/fmgr/funcapi.c:61 utils/misc/guc.c:8424 -#: utils/mmgr/portalmem.c:1064 +#: access/transam/xlogfuncs.c:198 commands/event_trigger.c:1473 +#: commands/event_trigger.c:2025 commands/extension.c:1908 +#: commands/extension.c:2017 commands/extension.c:2241 commands/prepare.c:712 +#: executor/execExpr.c:2201 executor/execSRF.c:720 executor/functions.c:1023 +#: foreign/foreign.c:520 libpq/hba.c:2666 replication/logical/launcher.c:1112 +#: replication/logical/logicalfuncs.c:176 replication/logical/origin.c:1468 +#: replication/slotfuncs.c:236 replication/walsender.c:3245 +#: utils/adt/jsonfuncs.c:1701 utils/adt/jsonfuncs.c:1832 +#: utils/adt/jsonfuncs.c:2020 utils/adt/jsonfuncs.c:2147 +#: utils/adt/jsonfuncs.c:3576 utils/adt/pgstatfuncs.c:458 +#: utils/adt/pgstatfuncs.c:563 utils/fmgr/funcapi.c:63 utils/misc/guc.c:9460 +#: utils/mmgr/portalmem.c:1134 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "在ä¸èƒ½æŽ¥å—使用集åˆçš„环境中调用set-valued函数" -#: access/transam/xlogfuncs.c:204 commands/event_trigger.c:1453 -#: commands/event_trigger.c:2004 commands/extension.c:1732 -#: commands/extension.c:1841 commands/extension.c:2034 commands/prepare.c:706 -#: foreign/foreign.c:603 replication/logical/logicalfuncs.c:179 -#: replication/logical/origin.c:1395 replication/slotfuncs.c:193 -#: replication/walsender.c:2765 utils/adt/pgstatfuncs.c:556 -#: utils/adt/pgstatfuncs.c:657 utils/misc/guc.c:8428 utils/misc/pg_config.c:44 -#: utils/mmgr/portalmem.c:1068 +#: access/transam/xlogfuncs.c:202 commands/event_trigger.c:1477 +#: commands/event_trigger.c:2029 commands/extension.c:1912 +#: commands/extension.c:2021 commands/extension.c:2245 commands/prepare.c:716 +#: foreign/foreign.c:525 libpq/hba.c:2670 replication/logical/launcher.c:1116 +#: replication/logical/logicalfuncs.c:180 replication/logical/origin.c:1472 +#: replication/slotfuncs.c:240 replication/walsender.c:3249 +#: utils/adt/pgstatfuncs.c:462 utils/adt/pgstatfuncs.c:567 +#: utils/misc/guc.c:9464 utils/misc/pg_config.c:43 utils/mmgr/portalmem.c:1138 #, c-format msgid "materialize mode required, but it is not allowed in this context" msgstr "è¦æ±‚使用物化模å¼ï¼Œä½†æ˜¯åœ¨è¿™ç§çŽ¯å¢ƒä¸‹ä¸å…许使用." -#: access/transam/xlogfuncs.c:247 +#: access/transam/xlogfuncs.c:244 #, c-format -#| msgid "a backup is not in progress" msgid "non-exclusive backup is not in progress" msgstr "éžæŽ’é™¤å¤‡ä»½ä¸åœ¨è¿è¡Œä¸­" -#: access/transam/xlogfuncs.c:248 +#: access/transam/xlogfuncs.c:245 #, c-format -msgid "did you mean to use pg_stop_backup('t')?" +msgid "Did you mean to use pg_stop_backup('t')?" msgstr "你是想使用 pg_stop_backup('t') å—?" -#: access/transam/xlogfuncs.c:327 +#: access/transam/xlogfuncs.c:322 #, c-format msgid "WAL level not sufficient for creating a restore point" msgstr "WAL的级别ä¸èƒ½æ»¡è¶³åˆ›å»ºæ¢å¤ç‚¹çš„è¦æ±‚" -#: access/transam/xlogfuncs.c:335 +#: access/transam/xlogfuncs.c:330 #, c-format msgid "value too long for restore point (maximum %d characters)" msgstr "æ¢å¤ç‚¹å€¼è¶…é•¿(最大%d个字符)" -#: access/transam/xlogfuncs.c:473 -#, c-format -msgid "pg_xlogfile_name_offset() cannot be executed during recovery." -msgstr "在æ¢å¤è¿‡ç¨‹ä¸­ä¸èƒ½æ‰§è¡Œpg_xlogfile_name_offset()" - -#: access/transam/xlogfuncs.c:529 -#, c-format -msgid "pg_xlogfile_name() cannot be executed during recovery." -msgstr "在æ¢å¤è¿‡ç¨‹ä¸­æ— æ³•执行pg_xlogfile_name() " +#: access/transam/xlogfuncs.c:468 access/transam/xlogfuncs.c:525 +#, fuzzy, c-format +#| msgid "cannot execute %s during recovery" +msgid "%s cannot be executed during recovery." +msgstr "无法在æ¢å¤æœŸé—´æ‰§è¡Œ%s" -#: access/transam/xlogfuncs.c:549 access/transam/xlogfuncs.c:569 -#: access/transam/xlogfuncs.c:586 +#: access/transam/xlogfuncs.c:546 access/transam/xlogfuncs.c:566 +#: access/transam/xlogfuncs.c:583 access/transam/xlogfuncs.c:723 #, c-format msgid "recovery is not in progress" msgstr "æ¢å¤æ“作没在进行中" -#: access/transam/xlogfuncs.c:550 access/transam/xlogfuncs.c:570 -#: access/transam/xlogfuncs.c:587 +#: access/transam/xlogfuncs.c:547 access/transam/xlogfuncs.c:567 +#: access/transam/xlogfuncs.c:584 access/transam/xlogfuncs.c:724 #, c-format msgid "Recovery control functions can only be executed during recovery." msgstr "在æ¢å¤æœŸé—´æ— æ³•执行æ¢å¤æŽ§åˆ¶å‡½æ•°" -#: access/transam/xlogreader.c:285 +#: access/transam/xlogfuncs.c:729 +#, c-format +msgid "\"wait_seconds\" cannot be negative or equal zero" +msgstr "" + +#: access/transam/xlogfuncs.c:749 storage/ipc/signalfuncs.c:164 +#, c-format +msgid "failed to send signal to postmaster: %m" +msgstr "无法å‘é€ä¿¡å·åˆ°postmaster进程: %m" + +#: access/transam/xlogfuncs.c:776 +#, c-format +msgid "server did not promote within %d seconds" +msgstr "" + +#: access/transam/xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "%X/%X处有无效记录åç§»é‡" -#: access/transam/xlogreader.c:293 +#: access/transam/xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "%X/%Xä½ç½®å¤„è¦æ±‚继续记录" -#: access/transam/xlogreader.c:334 access/transam/xlogreader.c:633 +#: access/transam/xlogreader.c:348 access/transam/xlogreader.c:645 #, c-format -#| msgid "invalid record length at %X/%X" msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "%X/%X 处的记录长度ä¸åˆæ³•ï¼šæƒ³è¦ %u,但得到的是 %u" -#: access/transam/xlogreader.c:349 +#: access/transam/xlogreader.c:372 #, c-format msgid "record length %u at %X/%X too long" msgstr "%2$X/%3$X处的记录长度%1$u太长" -#: access/transam/xlogreader.c:390 +#: access/transam/xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "在%X/%X处没有继续记录标志" -#: access/transam/xlogreader.c:403 +#: access/transam/xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "在%2$X/%3$X处的继续记录长度%1$uä¸åˆæ³•" -#: access/transam/xlogreader.c:641 +#: access/transam/xlogreader.c:653 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "在%2$X/%3$X处的资æºç®¡ç†å™¨ID%1$uä¸åˆæ³•" -#: access/transam/xlogreader.c:655 access/transam/xlogreader.c:672 +#: access/transam/xlogreader.c:667 access/transam/xlogreader.c:684 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "å…·æœ‰ä¸æ­£ç¡®å‘å‰é“¾æŽ¥%X/%X的记录出现在%X/%X" -#: access/transam/xlogreader.c:709 +#: access/transam/xlogreader.c:721 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "在%X/%X处的记录中的资æºç®¡ç†å™¨æ•°æ®æ ¡éªŒå’Œä¸æ­£ç¡®" -#: access/transam/xlogreader.c:742 +#: access/transam/xlogreader.c:758 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "日志段%2$sã€åç§»é‡%3$u中的magicå·%1$04X无效" -#: access/transam/xlogreader.c:756 access/transam/xlogreader.c:807 +#: access/transam/xlogreader.c:772 access/transam/xlogreader.c:823 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "日志段%2$sã€åç§»é‡%3$u中的infoä½%1$04X无效" -#: access/transam/xlogreader.c:782 +#: access/transam/xlogreader.c:798 #, c-format -msgid "" -"WAL file is from different database system: WAL file database system " -"identifier is %s, pg_control database system identifier is %s" -msgstr "" -"WAL文件æ¥è‡ªäºŽä¸åŒçš„æ•°æ®åº“系统:WAL文件数æ®åº“系统标识符为%s,pg_controlæ•°æ®åº“" -"标识符为%s" +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL文件æ¥è‡ªäºŽä¸åŒçš„æ•°æ®åº“系统:WAL文件数æ®åº“系统标识符为%s,pg_controlæ•°æ®åº“标识符为%s" -#: access/transam/xlogreader.c:789 +#: access/transam/xlogreader.c:805 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_SEG_SIZE in page " -"header" -msgstr "WAL文件æ¥è‡ªäºŽä¸åŒçš„æ•°æ®åº“系统:页头部中的XLOG_SEG_SIZE䏿­£ç¡®" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL文件æ¥è‡ªäºŽä¸åŒçš„æ•°æ®åº“系统:页头部中的段大å°ä¸æ­£ç¡®" -#: access/transam/xlogreader.c:795 +#: access/transam/xlogreader.c:811 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " -"header" +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "WAL文件æ¥è‡ªäºŽä¸åŒçš„æ•°æ®åº“系统:页头部中的XLOG_BLCKSZ䏿­£ç¡®" -#: access/transam/xlogreader.c:821 +#: access/transam/xlogreader.c:842 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "日志段%3$sã€åç§»%4$u出现æ„外的pageaddr %1$X/%2$X" -#: access/transam/xlogreader.c:846 +#: access/transam/xlogreader.c:867 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "日志段%3$sã€åç§»%4$u出现失åºçš„æ—¶é—´çº¿ID %1$u(在%2$u之åŽï¼‰" -#: access/transam/xlogreader.c:1053 +#: access/transam/xlogreader.c:1112 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "ä¹±åºçš„block_id %uä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1075 +#: access/transam/xlogreader.c:1135 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA已设置,但是在%X/%X没有包括数æ®" -#: access/transam/xlogreader.c:1082 +#: access/transam/xlogreader.c:1142 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA没有被设置,但是数æ®é•¿åº¦ä¸º%u,它ä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1115 +#: access/transam/xlogreader.c:1178 #, c-format -msgid "" -"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " -"%X/%X" -msgstr "" -"BKPIMAGE_HAS_HOLE被设置,但是洞å移为%u,长度为%uï¼Œå—æ˜ åƒé•¿åº¦ä¸º%u,它ä½äºŽ%X/" -"%X" +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE被设置,但是洞å移为%u,长度为%uï¼Œå—æ˜ åƒé•¿åº¦ä¸º%u,它ä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1131 +#: access/transam/xlogreader.c:1194 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE没有被设置,但是洞å移为%u,长度为%u,它ä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1146 +#: access/transam/xlogreader.c:1209 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSEDè¢«è®¾ç½®ï¼Œä½†æ˜¯å—æ˜ åƒé•¿åº¦æ˜¯%u,它ä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1161 +#: access/transam/xlogreader.c:1224 #, c-format -msgid "" -"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " -"length is %u at %X/%X" -msgstr "" -"既没有设置BKPIMAGE_HAS_HOLE也没有设置BKPIMAGE_IS_COMPRESSEDï¼Œä½†æ˜¯å—æ˜ åƒé•¿åº¦" -"是%u,它ä½äºŽ%X/%X" +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "既没有设置BKPIMAGE_HAS_HOLE也没有设置BKPIMAGE_IS_COMPRESSEDï¼Œä½†æ˜¯å—æ˜ åƒé•¿åº¦æ˜¯%u,它ä½äºŽ%X/%X" -#: access/transam/xlogreader.c:1177 +#: access/transam/xlogreader.c:1240 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "设置了BKPBLOCK_SAME_REL,但是在%X/%Xä½ç½®æ²¡æœ‰è®°å½•å…ˆå‰çš„关系" -#: access/transam/xlogreader.c:1189 +#: access/transam/xlogreader.c:1252 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "%2$X/%3$X处的block_id %1$u无效" -#: access/transam/xlogreader.c:1254 +#: access/transam/xlogreader.c:1341 #, c-format msgid "record with invalid length at %X/%X" msgstr "在%X/%X处的记录的长度无效" -#: access/transam/xlogreader.c:1343 +#: access/transam/xlogreader.c:1430 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "在%X/%Xã€å—%d处有无效压缩映åƒ" -#: access/transam/xlogutils.c:744 replication/walsender.c:2133 +#: access/transam/xlogutils.c:727 replication/walreceiver.c:959 +#: replication/walsender.c:2462 +#, c-format +msgid "could not seek in log segment %s to offset %u: %m" +msgstr "无法在日志段%s中查找, åç§»é‡ %u: %m" + +#: access/transam/xlogutils.c:751 #, c-format msgid "could not read from log segment %s, offset %u, length %lu: %m" msgstr "无法在日志段%s,åç§»é‡ä¸º%u, 长度为%luçš„ä½ç½®ä¸Šè¿›è¡Œè¯»æ“作: %m" -#: bootstrap/bootstrap.c:269 postmaster/postmaster.c:785 tcop/postgres.c:3488 +#: bootstrap/bootstrap.c:271 +#, c-format +msgid "-X requires a power of two value between 1 MB and 1 GB" +msgstr "-X需è¦ä¸¤ä¸ªä»‹äºŽ1 MBå’Œ1 GB之间的2的幂次方" + +#: bootstrap/bootstrap.c:288 postmaster/postmaster.c:821 tcop/postgres.c:3648 #, c-format msgid "--%s requires a value" msgstr "--%s 需è¦ä¸€ä¸ªå€¼" -#: bootstrap/bootstrap.c:274 postmaster/postmaster.c:790 tcop/postgres.c:3493 +#: bootstrap/bootstrap.c:293 postmaster/postmaster.c:826 tcop/postgres.c:3653 #, c-format msgid "-c %s requires a value" msgstr "-c %s 需è¦ä¸€ä¸ªå€¼" -#: bootstrap/bootstrap.c:285 postmaster/postmaster.c:802 -#: postmaster/postmaster.c:815 +#: bootstrap/bootstrap.c:304 postmaster/postmaster.c:838 +#: postmaster/postmaster.c:851 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "请用 \"%s --help\" èŽ·å–æ›´å¤šçš„ä¿¡æ¯.\n" -#: bootstrap/bootstrap.c:294 +#: bootstrap/bootstrap.c:313 #, c-format msgid "%s: invalid command-line arguments\n" msgstr "%s: æ— æ•ˆçš„å‘½ä»¤è¡Œå‚æ•°\n" -#: catalog/aclchk.c:193 +#: catalog/aclchk.c:203 #, c-format msgid "grant options can only be granted to roles" msgstr "grant 选项åªèƒ½ç”¨äºŽä¸ªä½“用户上" -#: catalog/aclchk.c:316 +#: catalog/aclchk.c:326 #, c-format msgid "no privileges were granted for column \"%s\" of relation \"%s\"" msgstr "没有为关系\"%2$s\"的列\"%1$s\"授予相应的æƒé™" -#: catalog/aclchk.c:321 +#: catalog/aclchk.c:331 #, c-format msgid "no privileges were granted for \"%s\"" msgstr "没有为\"%s\"授予æƒé™" -#: catalog/aclchk.c:329 +#: catalog/aclchk.c:339 #, c-format msgid "not all privileges were granted for column \"%s\" of relation \"%s\"" msgstr "没有为关系\"%2$s\"的列\"%1$s\"授予所有æƒé™" -#: catalog/aclchk.c:334 +#: catalog/aclchk.c:344 #, c-format msgid "not all privileges were granted for \"%s\"" msgstr "没有为\"%s\"授予所有的æƒé™" -#: catalog/aclchk.c:345 +#: catalog/aclchk.c:355 #, c-format msgid "no privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "ä¸èƒ½ä»Žå…³ç³»\"%2$s\"的列\"%1$s\"上撤销æƒé™" -#: catalog/aclchk.c:350 +#: catalog/aclchk.c:360 #, c-format msgid "no privileges could be revoked for \"%s\"" msgstr "ä¸èƒ½ä¸º\"%s\"撤销æƒé™" -#: catalog/aclchk.c:358 +#: catalog/aclchk.c:368 #, c-format -msgid "" -"not all privileges could be revoked for column \"%s\" of relation \"%s\"" +msgid "not all privileges could be revoked for column \"%s\" of relation \"%s\"" msgstr "ä¸èƒ½ä»Žå…³ç³»\"%2$s\"的列\"%1$s\"上撤销所有æƒé™" -#: catalog/aclchk.c:363 +#: catalog/aclchk.c:373 #, c-format msgid "not all privileges could be revoked for \"%s\"" msgstr "ä¸èƒ½ä¸º\"%s\"撤销所有æƒé™" -#: catalog/aclchk.c:448 catalog/aclchk.c:940 +#: catalog/aclchk.c:456 catalog/aclchk.c:999 #, c-format msgid "invalid privilege type %s for relation" msgstr "关系的æƒé™ç±»åž‹%s无效" -#: catalog/aclchk.c:452 catalog/aclchk.c:944 +#: catalog/aclchk.c:460 catalog/aclchk.c:1003 #, c-format msgid "invalid privilege type %s for sequence" msgstr "åºåˆ—çš„æƒé™ç±»åž‹ %s 无效" -#: catalog/aclchk.c:456 +#: catalog/aclchk.c:464 #, c-format msgid "invalid privilege type %s for database" msgstr "无效的数æ®åº“æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:460 +#: catalog/aclchk.c:468 #, c-format msgid "invalid privilege type %s for domain" msgstr "域的æƒé™ç±»åž‹%s无效" -#: catalog/aclchk.c:464 catalog/aclchk.c:948 +#: catalog/aclchk.c:472 catalog/aclchk.c:1007 #, c-format msgid "invalid privilege type %s for function" msgstr "无效的函数æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:468 +#: catalog/aclchk.c:476 #, c-format msgid "invalid privilege type %s for language" msgstr "无效的语言æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:472 +#: catalog/aclchk.c:480 #, c-format msgid "invalid privilege type %s for large object" msgstr "用于大对象的无效æƒé™ç±»åž‹%s" -#: catalog/aclchk.c:476 +#: catalog/aclchk.c:484 catalog/aclchk.c:1023 #, c-format msgid "invalid privilege type %s for schema" msgstr "æ— æ•ˆçš„æ¨¡å¼æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:480 +#: catalog/aclchk.c:488 catalog/aclchk.c:1011 +#, c-format +msgid "invalid privilege type %s for procedure" +msgstr "程åºçš„æƒé™ç±»åž‹ %s无效" + +#: catalog/aclchk.c:492 catalog/aclchk.c:1015 +#, c-format +msgid "invalid privilege type %s for routine" +msgstr "routineçš„æƒé™ç±»åž‹%s无效" + +#: catalog/aclchk.c:496 #, c-format msgid "invalid privilege type %s for tablespace" msgstr "无效的表空间æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:484 catalog/aclchk.c:952 +#: catalog/aclchk.c:500 catalog/aclchk.c:1019 #, c-format msgid "invalid privilege type %s for type" msgstr "类型的æƒé™ç±»åž‹ %s无效" -#: catalog/aclchk.c:488 +#: catalog/aclchk.c:504 #, c-format msgid "invalid privilege type %s for foreign-data wrapper" msgstr "外部数æ®å°è£…器的æƒé™ç±»åž‹ %s 无效" -#: catalog/aclchk.c:492 +#: catalog/aclchk.c:508 #, c-format msgid "invalid privilege type %s for foreign server" msgstr "外部æœåŠ¡å™¨çš„æƒé™ç±»åž‹%s无效" -#: catalog/aclchk.c:531 +#: catalog/aclchk.c:547 #, c-format msgid "column privileges are only valid for relations" msgstr "列æƒé™åªå¯¹å…³ç³»æœ‰æ•ˆ" -#: catalog/aclchk.c:690 catalog/aclchk.c:3921 catalog/aclchk.c:4698 -#: catalog/objectaddress.c:873 catalog/pg_largeobject.c:113 -#: storage/large_object/inv_api.c:291 +#: catalog/aclchk.c:707 catalog/aclchk.c:4135 catalog/aclchk.c:4917 +#: catalog/objectaddress.c:964 catalog/pg_largeobject.c:116 +#: storage/large_object/inv_api.c:283 #, c-format msgid "large object %u does not exist" msgstr "大对象 %u ä¸å­˜åœ¨" -#: catalog/aclchk.c:877 catalog/aclchk.c:885 commands/collationcmds.c:92 -#: commands/copy.c:1008 commands/copy.c:1026 commands/copy.c:1034 -#: commands/copy.c:1042 commands/copy.c:1050 commands/copy.c:1058 -#: commands/copy.c:1066 commands/copy.c:1074 commands/copy.c:1082 -#: commands/copy.c:1098 commands/copy.c:1112 commands/copy.c:1131 -#: commands/copy.c:1146 commands/dbcommands.c:155 commands/dbcommands.c:163 -#: commands/dbcommands.c:171 commands/dbcommands.c:179 -#: commands/dbcommands.c:187 commands/dbcommands.c:195 -#: commands/dbcommands.c:203 commands/dbcommands.c:211 -#: commands/dbcommands.c:219 commands/dbcommands.c:1397 -#: commands/dbcommands.c:1405 commands/dbcommands.c:1413 -#: commands/dbcommands.c:1421 commands/extension.c:1218 -#: commands/extension.c:1226 commands/extension.c:1234 -#: commands/extension.c:1242 commands/extension.c:2760 -#: commands/foreigncmds.c:539 commands/foreigncmds.c:548 -#: commands/functioncmds.c:533 commands/functioncmds.c:649 -#: commands/functioncmds.c:657 commands/functioncmds.c:665 -#: commands/functioncmds.c:673 commands/functioncmds.c:2085 -#: commands/functioncmds.c:2093 commands/sequence.c:1189 -#: commands/sequence.c:1197 commands/sequence.c:1205 commands/sequence.c:1213 -#: commands/sequence.c:1221 commands/sequence.c:1229 commands/sequence.c:1237 -#: commands/sequence.c:1245 commands/typecmds.c:295 commands/typecmds.c:1382 -#: commands/typecmds.c:1391 commands/typecmds.c:1399 commands/typecmds.c:1407 -#: commands/typecmds.c:1415 commands/user.c:139 commands/user.c:156 -#: commands/user.c:164 commands/user.c:172 commands/user.c:180 -#: commands/user.c:188 commands/user.c:196 commands/user.c:204 -#: commands/user.c:212 commands/user.c:220 commands/user.c:228 -#: commands/user.c:236 commands/user.c:244 commands/user.c:537 -#: commands/user.c:549 commands/user.c:557 commands/user.c:565 -#: commands/user.c:573 commands/user.c:581 commands/user.c:589 -#: commands/user.c:597 commands/user.c:606 commands/user.c:614 -#: commands/user.c:622 +#: catalog/aclchk.c:936 catalog/aclchk.c:945 commands/collationcmds.c:117 +#: commands/copy.c:1140 commands/copy.c:1160 commands/copy.c:1169 +#: commands/copy.c:1178 commands/copy.c:1187 commands/copy.c:1196 +#: commands/copy.c:1205 commands/copy.c:1214 commands/copy.c:1232 +#: commands/copy.c:1248 commands/copy.c:1268 commands/copy.c:1285 +#: commands/dbcommands.c:156 commands/dbcommands.c:165 +#: commands/dbcommands.c:174 commands/dbcommands.c:183 +#: commands/dbcommands.c:192 commands/dbcommands.c:201 +#: commands/dbcommands.c:210 commands/dbcommands.c:219 +#: commands/dbcommands.c:228 commands/dbcommands.c:1429 +#: commands/dbcommands.c:1438 commands/dbcommands.c:1447 +#: commands/dbcommands.c:1456 commands/extension.c:1688 +#: commands/extension.c:1698 commands/extension.c:1708 +#: commands/extension.c:1718 commands/extension.c:2960 +#: commands/foreigncmds.c:543 commands/foreigncmds.c:552 +#: commands/functioncmds.c:568 commands/functioncmds.c:734 +#: commands/functioncmds.c:743 commands/functioncmds.c:752 +#: commands/functioncmds.c:761 commands/functioncmds.c:2193 +#: commands/functioncmds.c:2201 commands/publicationcmds.c:91 +#: commands/sequence.c:1267 commands/sequence.c:1277 commands/sequence.c:1287 +#: commands/sequence.c:1297 commands/sequence.c:1307 commands/sequence.c:1317 +#: commands/sequence.c:1327 commands/sequence.c:1337 commands/sequence.c:1347 +#: commands/subscriptioncmds.c:111 commands/subscriptioncmds.c:121 +#: commands/subscriptioncmds.c:131 commands/subscriptioncmds.c:141 +#: commands/subscriptioncmds.c:155 commands/subscriptioncmds.c:166 +#: commands/subscriptioncmds.c:180 commands/tablecmds.c:6491 +#: commands/typecmds.c:299 commands/typecmds.c:1428 commands/typecmds.c:1437 +#: commands/typecmds.c:1445 commands/typecmds.c:1453 commands/typecmds.c:1461 +#: commands/user.c:133 commands/user.c:147 commands/user.c:156 +#: commands/user.c:165 commands/user.c:174 commands/user.c:183 +#: commands/user.c:192 commands/user.c:201 commands/user.c:210 +#: commands/user.c:219 commands/user.c:228 commands/user.c:237 +#: commands/user.c:246 commands/user.c:562 commands/user.c:570 +#: commands/user.c:578 commands/user.c:586 commands/user.c:594 +#: commands/user.c:602 commands/user.c:610 commands/user.c:618 +#: commands/user.c:627 commands/user.c:635 commands/user.c:643 +#: parser/parse_utilcmd.c:385 replication/pgoutput/pgoutput.c:111 +#: replication/pgoutput/pgoutput.c:132 replication/walsender.c:817 +#: replication/walsender.c:828 replication/walsender.c:838 #, c-format msgid "conflicting or redundant options" msgstr "é€‰é¡¹å†²çªæˆ–过多" -#: catalog/aclchk.c:985 +#: catalog/aclchk.c:1056 #, c-format msgid "default privileges cannot be set for columns" msgstr "æ— æ³•ä¸ºåˆ—è®¾ç½®ç¼ºçœæƒé™" -#: catalog/aclchk.c:1501 catalog/objectaddress.c:1390 commands/analyze.c:378 -#: commands/copy.c:4423 commands/sequence.c:1491 commands/tablecmds.c:5199 -#: commands/tablecmds.c:5305 commands/tablecmds.c:5365 -#: commands/tablecmds.c:5478 commands/tablecmds.c:5535 -#: commands/tablecmds.c:5629 commands/tablecmds.c:5725 -#: commands/tablecmds.c:7877 commands/tablecmds.c:8082 -#: commands/tablecmds.c:8502 commands/trigger.c:642 parser/analyze.c:2160 -#: parser/parse_relation.c:2542 parser/parse_relation.c:2604 -#: parser/parse_target.c:940 parser/parse_type.c:127 utils/adt/acl.c:2840 -#: utils/adt/ruleutils.c:1862 +#: catalog/aclchk.c:1216 +#, c-format +msgid "cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS" +msgstr "在使用GRANT/REVOKE ON SCHEMASæ—¶ä¸èƒ½ä½¿ç”¨IN SCHEMAå­å¥" + +#: catalog/aclchk.c:1584 catalog/catalog.c:519 catalog/objectaddress.c:1426 +#: commands/analyze.c:383 commands/copy.c:5129 commands/sequence.c:1702 +#: commands/tablecmds.c:6033 commands/tablecmds.c:6191 +#: commands/tablecmds.c:6265 commands/tablecmds.c:6335 +#: commands/tablecmds.c:6416 commands/tablecmds.c:6510 +#: commands/tablecmds.c:6569 commands/tablecmds.c:6708 +#: commands/tablecmds.c:6790 commands/tablecmds.c:6882 +#: commands/tablecmds.c:6976 commands/tablecmds.c:10209 +#: commands/tablecmds.c:10524 commands/tablecmds.c:11040 commands/trigger.c:928 +#: parser/analyze.c:2330 parser/parse_relation.c:2788 +#: parser/parse_relation.c:2851 parser/parse_target.c:1031 +#: parser/parse_type.c:127 utils/adt/acl.c:2885 utils/adt/ruleutils.c:2511 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist" msgstr "关系 \"%2$s\" çš„ \"%1$s\" 字段ä¸å­˜åœ¨" -#: catalog/aclchk.c:1770 catalog/objectaddress.c:1203 commands/sequence.c:1078 -#: commands/tablecmds.c:223 commands/tablecmds.c:12009 utils/adt/acl.c:2076 -#: utils/adt/acl.c:2106 utils/adt/acl.c:2138 utils/adt/acl.c:2170 -#: utils/adt/acl.c:2198 utils/adt/acl.c:2228 +#: catalog/aclchk.c:1847 catalog/objectaddress.c:1266 commands/sequence.c:1140 +#: commands/tablecmds.c:230 commands/tablecmds.c:14769 utils/adt/acl.c:2075 +#: utils/adt/acl.c:2105 utils/adt/acl.c:2137 utils/adt/acl.c:2169 +#: utils/adt/acl.c:2197 utils/adt/acl.c:2227 #, c-format msgid "\"%s\" is not a sequence" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªåºåˆ—" -#: catalog/aclchk.c:1808 +#: catalog/aclchk.c:1885 #, c-format msgid "sequence \"%s\" only supports USAGE, SELECT, and UPDATE privileges" msgstr "åºåˆ—\"%s\"åªæ”¯æŒæƒé™USAGE, SELECT å’ŒUPDATE" -#: catalog/aclchk.c:1825 +#: catalog/aclchk.c:1902 #, c-format -msgid "invalid privilege type USAGE for table" -msgstr "表的æƒé™ç±»åž‹ USAGE 无效" +msgid "invalid privilege type %s for table" +msgstr "无效的表æƒé™ç±»åž‹ %s" -#: catalog/aclchk.c:1993 +#: catalog/aclchk.c:2068 #, c-format msgid "invalid privilege type %s for column" msgstr "列的æƒé™ç±»åž‹%s无效" -#: catalog/aclchk.c:2006 +#: catalog/aclchk.c:2081 #, c-format msgid "sequence \"%s\" only supports SELECT column privileges" msgstr "åºåˆ—\"%s\"åªæ”¯æŒåœ¨åˆ—上的SELECTæƒé™" -#: catalog/aclchk.c:2600 +#: catalog/aclchk.c:2663 #, c-format msgid "language \"%s\" is not trusted" msgstr "语言 \"%s\" ä¸å¯ä¿¡" -#: catalog/aclchk.c:2602 +#: catalog/aclchk.c:2665 #, c-format -msgid "Only superusers can use untrusted languages." -msgstr "åªæœ‰è¶…级用户å¯ä»¥ä½¿ç”¨éžä¿¡ä»»è¯­è¨€." +msgid "GRANT and REVOKE are not allowed on untrusted languages, because only superusers can use untrusted languages." +msgstr "在ä¸å—信任的语言中,GRANTå’ŒREVOKEä¸å…è®¸è¢«ä½¿ç”¨ï¼Œå› ä¸ºåªæœ‰è¶…级用户æ‰èƒ½ä½¿ç”¨ä¸å—信任的语言." -#: catalog/aclchk.c:3127 +#: catalog/aclchk.c:3179 #, c-format msgid "cannot set privileges of array types" msgstr "ä¸èƒ½è®¾ç½®æ•°ç»„类型的æƒé™" -#: catalog/aclchk.c:3128 +#: catalog/aclchk.c:3180 #, c-format msgid "Set the privileges of the element type instead." msgstr "设置元素类型的æƒé™." -#: catalog/aclchk.c:3135 catalog/objectaddress.c:1523 commands/typecmds.c:3146 +#: catalog/aclchk.c:3187 catalog/objectaddress.c:1560 #, c-format msgid "\"%s\" is not a domain" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªåŸŸ" -#: catalog/aclchk.c:3258 +#: catalog/aclchk.c:3307 #, c-format msgid "unrecognized privilege type \"%s\"" msgstr "未知的æƒé™ç±»åž‹: \"%s\"" -#: catalog/aclchk.c:3307 +#: catalog/aclchk.c:3368 #, c-format -msgid "permission denied for column %s" -msgstr "访问列 %s çš„æƒé™ä¸å¤Ÿ" +msgid "permission denied for aggregate %s" +msgstr "对èšåˆ %s æƒé™ä¸å¤Ÿ" + +#: catalog/aclchk.c:3371 +#, c-format +msgid "permission denied for collation %s" +msgstr "对排åºè§„则 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3309 +#: catalog/aclchk.c:3374 #, c-format -msgid "permission denied for relation %s" -msgstr "对关系 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for column %s" +msgstr "访问列 %s çš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3311 commands/sequence.c:561 commands/sequence.c:786 -#: commands/sequence.c:828 commands/sequence.c:865 commands/sequence.c:1543 +#: catalog/aclchk.c:3377 #, c-format -msgid "permission denied for sequence %s" -msgstr "对于åºåˆ— %s, æƒé™ä¸å¤Ÿ" +msgid "permission denied for conversion %s" +msgstr "对编ç è½¬æ¢ %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3313 +#: catalog/aclchk.c:3380 #, c-format msgid "permission denied for database %s" msgstr "对数æ®åº“ %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3315 +#: catalog/aclchk.c:3383 #, c-format -msgid "permission denied for function %s" -msgstr "对函数 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for domain %s" +msgstr "访问域 %s çš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3317 +#: catalog/aclchk.c:3386 #, c-format -msgid "permission denied for operator %s" -msgstr "对æ“作符 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for event trigger %s" +msgstr "事件触å‘器 %s, æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3319 +#: catalog/aclchk.c:3389 #, c-format -msgid "permission denied for type %s" -msgstr "对类型 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for extension %s" +msgstr "对扩展 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3321 +#: catalog/aclchk.c:3392 #, c-format -msgid "permission denied for language %s" -msgstr "对语言 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for foreign-data wrapper %s" +msgstr "访问外部数æ®å°è£…器 %s çš„æƒé™ä¸è¶³" -#: catalog/aclchk.c:3323 +#: catalog/aclchk.c:3395 #, c-format -msgid "permission denied for large object %s" -msgstr "在大对象%s上的æƒé™ä¸å¤Ÿ" +msgid "permission denied for foreign server %s" +msgstr "访问外部æœåС噍%sçš„æƒé™ä¸è¶³" -#: catalog/aclchk.c:3325 +#: catalog/aclchk.c:3398 #, c-format -msgid "permission denied for schema %s" -msgstr "å¯¹æ¨¡å¼ %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for foreign table %s" +msgstr "访问外部表%sçš„æƒé™ä¸è¶³" -#: catalog/aclchk.c:3327 +#: catalog/aclchk.c:3401 #, c-format -msgid "permission denied for operator class %s" -msgstr "对æ“作符表 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for function %s" +msgstr "对函数 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3329 +#: catalog/aclchk.c:3404 #, c-format -msgid "permission denied for operator family %s" -msgstr "对于æ“作符表%sçš„æƒé™ä¸å¤Ÿ" +msgid "permission denied for index %s" +msgstr "对索引 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3331 +#: catalog/aclchk.c:3407 #, c-format -msgid "permission denied for collation %s" -msgstr "对排åºè§„则 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for language %s" +msgstr "对语言 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3333 +#: catalog/aclchk.c:3410 #, c-format -msgid "permission denied for conversion %s" -msgstr "对编ç è½¬æ¢ %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for large object %s" +msgstr "在大对象%s上的æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3335 +#: catalog/aclchk.c:3413 #, c-format -msgid "permission denied for tablespace %s" -msgstr "对表空间 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for materialized view %s" +msgstr "对物化视图 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3337 +#: catalog/aclchk.c:3416 #, c-format -msgid "permission denied for text search dictionary %s" -msgstr "访问文本æœç´¢å­—å…¸%sçš„æƒé™ä¸å¤Ÿ" +msgid "permission denied for operator class %s" +msgstr "对æ“作符表 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3339 +#: catalog/aclchk.c:3419 #, c-format -msgid "permission denied for text search configuration %s" -msgstr "访问文本æœç´¢é…ç½®%sçš„æƒé™ä¸è¶³" +msgid "permission denied for operator %s" +msgstr "对æ“作符 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3341 +#: catalog/aclchk.c:3422 #, c-format -msgid "permission denied for foreign-data wrapper %s" -msgstr "访问外部数æ®å°è£…器 %s çš„æƒé™ä¸è¶³" +msgid "permission denied for operator family %s" +msgstr "对于æ“作符表%sçš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3343 +#: catalog/aclchk.c:3425 #, c-format -msgid "permission denied for foreign server %s" -msgstr "访问外部æœåС噍%sçš„æƒé™ä¸è¶³" +msgid "permission denied for policy %s" +msgstr "对策略 %s çš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3345 +#: catalog/aclchk.c:3428 #, c-format -msgid "permission denied for event trigger %s" -msgstr "事件触å‘器 %s, æƒé™ä¸å¤Ÿ" +msgid "permission denied for procedure %s" +msgstr "对过程 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3347 +#: catalog/aclchk.c:3431 #, c-format -msgid "permission denied for extension %s" -msgstr "对扩展 %s æƒé™ä¸å¤Ÿ" +msgid "permission denied for publication %s" +msgstr "对å‘布 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3353 catalog/aclchk.c:3355 +#: catalog/aclchk.c:3434 #, c-format -msgid "must be owner of relation %s" -msgstr "必须是关系 %s 的属主" +msgid "permission denied for routine %s" +msgstr "对routine %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3357 +#: catalog/aclchk.c:3437 #, c-format -msgid "must be owner of sequence %s" -msgstr "必须是åºåˆ— %s 的属主" +msgid "permission denied for schema %s" +msgstr "å¯¹æ¨¡å¼ %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3359 +#: catalog/aclchk.c:3440 commands/sequence.c:610 commands/sequence.c:844 +#: commands/sequence.c:886 commands/sequence.c:927 commands/sequence.c:1800 +#: commands/sequence.c:1864 #, c-format -msgid "must be owner of database %s" -msgstr "必须是数æ®åº“ %s 的属主" +msgid "permission denied for sequence %s" +msgstr "对于åºåˆ— %s, æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3361 +#: catalog/aclchk.c:3443 #, c-format -msgid "must be owner of function %s" -msgstr "必须是函数 %s 的属主" +msgid "permission denied for statistics object %s" +msgstr "在统计信æ¯å¯¹è±¡ %s上的æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3363 +#: catalog/aclchk.c:3446 #, c-format -msgid "must be owner of operator %s" -msgstr "必须是æ“作符 %s 的属主" +msgid "permission denied for subscription %s" +msgstr "对订阅 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3365 +#: catalog/aclchk.c:3449 #, c-format -msgid "must be owner of type %s" -msgstr "必须是类型 %s 的属主" +msgid "permission denied for table %s" +msgstr "对表 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3367 +#: catalog/aclchk.c:3452 #, c-format -msgid "must be owner of language %s" -msgstr "必须是语言 %s 的属主" +msgid "permission denied for tablespace %s" +msgstr "对表空间 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3369 +#: catalog/aclchk.c:3455 #, c-format -msgid "must be owner of large object %s" -msgstr "必须是大对象%s的属主" +msgid "permission denied for text search configuration %s" +msgstr "访问文本æœç´¢é…ç½®%sçš„æƒé™ä¸è¶³" -#: catalog/aclchk.c:3371 +#: catalog/aclchk.c:3458 #, c-format -msgid "must be owner of schema %s" -msgstr "å¿…é¡»æ˜¯æ¨¡å¼ %s 的属主" +msgid "permission denied for text search dictionary %s" +msgstr "访问文本æœç´¢å­—å…¸%sçš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3373 +#: catalog/aclchk.c:3461 #, c-format -msgid "must be owner of operator class %s" -msgstr "必须是æ“作符表 %s 的属主" +msgid "permission denied for type %s" +msgstr "对类型 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3375 +#: catalog/aclchk.c:3464 #, c-format -msgid "must be owner of operator family %s" -msgstr "必须是æ“ä½œç¬¦é›†åˆ %s 的属主" +msgid "permission denied for view %s" +msgstr "对视图 %s æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3377 +#: catalog/aclchk.c:3499 +#, c-format +msgid "must be owner of aggregate %s" +msgstr "必须是èšåˆ %s 的属主" + +#: catalog/aclchk.c:3502 #, c-format msgid "must be owner of collation %s" msgstr "必须是排åºè§„则 %s 的属主" -#: catalog/aclchk.c:3379 +#: catalog/aclchk.c:3505 #, c-format msgid "must be owner of conversion %s" msgstr "必须是编ç è½¬æ¢ %s 的属主" -#: catalog/aclchk.c:3381 +#: catalog/aclchk.c:3508 #, c-format -msgid "must be owner of tablespace %s" -msgstr "必须是表空间 %s 的属主" +msgid "must be owner of database %s" +msgstr "必须是数æ®åº“ %s 的属主" -# describe.c:1549 -#: catalog/aclchk.c:3383 +#: catalog/aclchk.c:3511 #, c-format -msgid "must be owner of text search dictionary %s" -msgstr "必须是文本æœå¯»å­—å…¸%s的属主" +msgid "must be owner of domain %s" +msgstr "必须是域 %s 的属主" -# describe.c:97 -#: catalog/aclchk.c:3385 +#: catalog/aclchk.c:3514 #, c-format -msgid "must be owner of text search configuration %s" -msgstr "必须是文本æœç´¢é…ç½®%s的属主" +msgid "must be owner of event trigger %s" +msgstr "必须是事件触å‘器 %s 的属主" + +#: catalog/aclchk.c:3517 +#, c-format +msgid "must be owner of extension %s" +msgstr "必须是扩展 %s 的属主" -#: catalog/aclchk.c:3387 +#: catalog/aclchk.c:3520 #, c-format msgid "must be owner of foreign-data wrapper %s" msgstr "必须是外部数æ®å°è£…器 %s 的属主" -#: catalog/aclchk.c:3389 +#: catalog/aclchk.c:3523 #, c-format msgid "must be owner of foreign server %s" msgstr "必须是外部æœåС噍 %s 的属主" -#: catalog/aclchk.c:3391 +#: catalog/aclchk.c:3526 #, c-format -msgid "must be owner of event trigger %s" -msgstr "必须是事件触å‘器 %s 的属主" +msgid "must be owner of foreign table %s" +msgstr "必须是外部表 %s 的属主" -#: catalog/aclchk.c:3393 +#: catalog/aclchk.c:3529 #, c-format -msgid "must be owner of extension %s" -msgstr "必须是扩展 %s 的属主" +msgid "must be owner of function %s" +msgstr "必须是函数 %s 的属主" -#: catalog/aclchk.c:3435 +#: catalog/aclchk.c:3532 #, c-format -msgid "permission denied for column \"%s\" of relation \"%s\"" -msgstr "访问关系\"%2$s\"的列\"%1$s\"çš„æƒé™ä¸å¤Ÿ" +msgid "must be owner of index %s" +msgstr "必须是索引 %s 的属主" -#: catalog/aclchk.c:3554 catalog/aclchk.c:3562 +#: catalog/aclchk.c:3535 #, c-format -msgid "attribute %d of relation with OID %u does not exist" -msgstr "带有OID为%2$u的关系的属性%1$dä¸å­˜åœ¨" +msgid "must be owner of language %s" +msgstr "必须是语言 %s 的属主" -#: catalog/aclchk.c:3635 catalog/aclchk.c:4549 +#: catalog/aclchk.c:3538 #, c-format -msgid "relation with OID %u does not exist" -msgstr "OID 为 %u 的关系ä¸å­˜åœ¨" +msgid "must be owner of large object %s" +msgstr "必须是大对象%s的属主" + +#: catalog/aclchk.c:3541 +#, c-format +msgid "must be owner of materialized view %s" +msgstr "必须是物化视图 %s 的属主" + +#: catalog/aclchk.c:3544 +#, c-format +msgid "must be owner of operator class %s" +msgstr "必须是æ“作符表 %s 的属主" + +#: catalog/aclchk.c:3547 +#, c-format +msgid "must be owner of operator %s" +msgstr "必须是æ“作符 %s 的属主" + +#: catalog/aclchk.c:3550 +#, c-format +msgid "must be owner of operator family %s" +msgstr "必须是æ“ä½œç¬¦é›†åˆ %s 的属主" + +#: catalog/aclchk.c:3553 +#, c-format +msgid "must be owner of procedure %s" +msgstr "必须是过程 %s 的属主" + +#: catalog/aclchk.c:3556 +#, c-format +msgid "must be owner of publication %s" +msgstr "必须是å‘布 %s 的属主" + +#: catalog/aclchk.c:3559 +#, c-format +msgid "must be owner of routine %s" +msgstr "必须是routine %s 的属主" + +#: catalog/aclchk.c:3562 +#, c-format +msgid "must be owner of sequence %s" +msgstr "必须是åºåˆ— %s 的属主" + +#: catalog/aclchk.c:3565 +#, c-format +msgid "must be owner of subscription %s" +msgstr "必须是订阅 %s 的属主" + +#: catalog/aclchk.c:3568 +#, c-format +msgid "must be owner of table %s" +msgstr "必须是表 %s 的属主" + +#: catalog/aclchk.c:3571 +#, c-format +msgid "must be owner of type %s" +msgstr "必须是类型 %s 的属主" + +#: catalog/aclchk.c:3574 +#, c-format +msgid "must be owner of view %s" +msgstr "必须是视图 %s 的属主" + +#: catalog/aclchk.c:3577 +#, c-format +msgid "must be owner of schema %s" +msgstr "å¿…é¡»æ˜¯æ¨¡å¼ %s 的属主" + +#: catalog/aclchk.c:3580 +#, c-format +msgid "must be owner of statistics object %s" +msgstr "必须是统计信æ¯å¯¹è±¡ %s的属主" + +#: catalog/aclchk.c:3583 +#, c-format +msgid "must be owner of tablespace %s" +msgstr "必须是表空间 %s 的属主" + +# describe.c:97 +#: catalog/aclchk.c:3586 +#, c-format +msgid "must be owner of text search configuration %s" +msgstr "必须是文本æœç´¢é…ç½®%s的属主" + +# describe.c:1549 +#: catalog/aclchk.c:3589 +#, c-format +msgid "must be owner of text search dictionary %s" +msgstr "必须是文本æœå¯»å­—å…¸%s的属主" + +#: catalog/aclchk.c:3603 +#, c-format +msgid "must be owner of relation %s" +msgstr "必须是关系 %s 的属主" + +#: catalog/aclchk.c:3647 +#, c-format +msgid "permission denied for column \"%s\" of relation \"%s\"" +msgstr "访问关系\"%2$s\"的列\"%1$s\"çš„æƒé™ä¸å¤Ÿ" -#: catalog/aclchk.c:3734 catalog/aclchk.c:4967 +#: catalog/aclchk.c:3768 catalog/aclchk.c:3776 +#, c-format +msgid "attribute %d of relation with OID %u does not exist" +msgstr "带有OID为%2$u的关系的属性%1$dä¸å­˜åœ¨" + +#: catalog/aclchk.c:3849 catalog/aclchk.c:4768 +#, c-format +msgid "relation with OID %u does not exist" +msgstr "OID 为 %u 的关系ä¸å­˜åœ¨" + +#: catalog/aclchk.c:3948 catalog/aclchk.c:5186 #, c-format msgid "database with OID %u does not exist" msgstr "OID 为 %u 的数æ®åº“ä¸å­˜åœ¨" -#: catalog/aclchk.c:3788 catalog/aclchk.c:4627 tcop/fastpath.c:223 +#: catalog/aclchk.c:4002 catalog/aclchk.c:4846 tcop/fastpath.c:221 +#: utils/fmgr/fmgr.c:2017 #, c-format msgid "function with OID %u does not exist" msgstr "OID 为 %u 的函数ä¸å­˜åœ¨" -#: catalog/aclchk.c:3842 catalog/aclchk.c:4653 +#: catalog/aclchk.c:4056 catalog/aclchk.c:4872 #, c-format msgid "language with OID %u does not exist" msgstr "OID 为 %u 的语言ä¸å­˜åœ¨" -#: catalog/aclchk.c:4006 catalog/aclchk.c:4725 +#: catalog/aclchk.c:4220 catalog/aclchk.c:4944 #, c-format msgid "schema with OID %u does not exist" msgstr "OID 为 %u 的模å¼ä¸å­˜åœ¨" -#: catalog/aclchk.c:4060 catalog/aclchk.c:4752 +#: catalog/aclchk.c:4274 catalog/aclchk.c:4971 utils/adt/genfile.c:637 #, c-format msgid "tablespace with OID %u does not exist" msgstr "OID 为 %u 的表空间ä¸å­˜åœ¨" -#: catalog/aclchk.c:4118 catalog/aclchk.c:4886 commands/foreigncmds.c:325 +#: catalog/aclchk.c:4333 catalog/aclchk.c:5105 commands/foreigncmds.c:328 #, c-format msgid "foreign-data wrapper with OID %u does not exist" msgstr "带有OID为%u的外部数æ®å°è£…器(foreign-data wrapper)ä¸å­˜åœ¨" -#: catalog/aclchk.c:4179 catalog/aclchk.c:4913 commands/foreigncmds.c:461 +#: catalog/aclchk.c:4395 catalog/aclchk.c:5132 commands/foreigncmds.c:465 #, c-format msgid "foreign server with OID %u does not exist" msgstr "带有OID为%u的外部æœåС噍ä¸å­˜åœ¨" -#: catalog/aclchk.c:4238 catalog/aclchk.c:4252 catalog/aclchk.c:4575 +#: catalog/aclchk.c:4455 catalog/aclchk.c:4794 utils/cache/typcache.c:369 #, c-format msgid "type with OID %u does not exist" msgstr "OID 为 %u 的类型ä¸å­˜åœ¨" -#: catalog/aclchk.c:4601 +#: catalog/aclchk.c:4820 #, c-format msgid "operator with OID %u does not exist" msgstr "OID 为 %u çš„æ“作符ä¸å­˜åœ¨" -#: catalog/aclchk.c:4778 +#: catalog/aclchk.c:4997 #, c-format msgid "operator class with OID %u does not exist" msgstr "OID 为 %u çš„æ“作符表ä¸å­˜åœ¨" -#: catalog/aclchk.c:4805 +#: catalog/aclchk.c:5024 #, c-format msgid "operator family with OID %u does not exist" msgstr "OID 为 %u çš„æ“作符表ä¸å­˜åœ¨" -#: catalog/aclchk.c:4832 +#: catalog/aclchk.c:5051 #, c-format msgid "text search dictionary with OID %u does not exist" msgstr "带有OID为%u的文本æœç´¢å­—å…¸ä¸å­˜åœ¨" -#: catalog/aclchk.c:4859 +#: catalog/aclchk.c:5078 #, c-format msgid "text search configuration with OID %u does not exist" msgstr "带有OID为%u的文本æœç´¢é…ç½®ä¸å­˜åœ¨" -#: catalog/aclchk.c:4940 commands/event_trigger.c:587 +#: catalog/aclchk.c:5159 commands/event_trigger.c:596 #, c-format msgid "event trigger with OID %u does not exist" msgstr "OID 为 %u 的事件触å‘器ä¸å­˜åœ¨" -#: catalog/aclchk.c:4993 +#: catalog/aclchk.c:5212 commands/collationcmds.c:366 #, c-format msgid "collation with OID %u does not exist" msgstr "OID 为 %u 的排åºè§„则ä¸å­˜åœ¨" -#: catalog/aclchk.c:5019 +#: catalog/aclchk.c:5238 #, c-format msgid "conversion with OID %u does not exist" msgstr "OID 为 %u 的编ç è½¬æ¢ä¸å­˜åœ¨" -#: catalog/aclchk.c:5060 +#: catalog/aclchk.c:5279 #, c-format msgid "extension with OID %u does not exist" msgstr "OID 为 %u 的扩展ä¸å­˜åœ¨" -#: catalog/dependency.c:646 +#: catalog/aclchk.c:5306 commands/publicationcmds.c:759 +#, c-format +msgid "publication with OID %u does not exist" +msgstr "OID 为 %u çš„å‘布ä¸å­˜åœ¨" + +#: catalog/aclchk.c:5332 commands/subscriptioncmds.c:1121 +#, c-format +msgid "subscription with OID %u does not exist" +msgstr "OID 为 %u 的订阅ä¸å­˜åœ¨" + +#: catalog/aclchk.c:5358 +#, c-format +msgid "statistics object with OID %u does not exist" +msgstr "OID 为 %u 的统计信æ¯å¯¹è±¡ä¸å­˜åœ¨" + +#: catalog/catalog.c:498 +#, fuzzy, c-format +#| msgid "must be superuser to set grantor" +msgid "must be superuser to call pg_nextoid()" +msgstr "åªæœ‰è¶…级用户能设置授æƒè€…" + +#: catalog/catalog.c:506 +#, fuzzy, c-format +#| msgid "ON COMMIT can only be used on temporary tables" +msgid "pg_nextoid() can only be used on system catalogs" +msgstr "ON COMMIT åªèƒ½è¢«ç”¨äºŽä¸´æ—¶è¡¨" + +#: catalog/catalog.c:511 parser/parse_utilcmd.c:2064 +#, c-format +msgid "index \"%s\" does not belong to table \"%s\"" +msgstr "索引 \"%s\" ä¸å±žäºŽè¡¨\"%s\"" + +#: catalog/catalog.c:528 +#, fuzzy, c-format +#| msgid "column \"%s\" is not of tsvector type" +msgid "column \"%s\" is not of type oid" +msgstr "列\"%s\"ä¸å±žäºŽtsvector类型" + +#: catalog/catalog.c:535 +#, fuzzy, c-format +#| msgid "\"%s\" is not an index for table \"%s\"" +msgid "index \"%s\" is not the index for column \"%s\"" +msgstr "对于表 \"%2$s\" \"%1$s\" 䏿˜¯ä¸€ä¸ªç´¢å¼•" + +#: catalog/dependency.c:808 catalog/dependency.c:1036 #, c-format msgid "cannot drop %s because %s requires it" msgstr "无法删除 %s, 因为 %s 需è¦å®ƒ" -#: catalog/dependency.c:649 +#: catalog/dependency.c:810 catalog/dependency.c:1038 #, c-format msgid "You can drop %s instead." msgstr "您也å¯ä»¥åˆ é™¤ %s 代替." -#: catalog/dependency.c:811 catalog/pg_shdepend.c:576 +#: catalog/dependency.c:908 catalog/pg_shdepend.c:641 #, c-format msgid "cannot drop %s because it is required by the database system" msgstr "无法删除 %s, 因为它是数æ®åº“系统所需è¦çš„" -#: catalog/dependency.c:927 +#: catalog/dependency.c:1104 #, c-format msgid "drop auto-cascades to %s" msgstr "自动递归删除 %s" -#: catalog/dependency.c:939 catalog/dependency.c:948 +#: catalog/dependency.c:1116 catalog/dependency.c:1125 #, c-format msgid "%s depends on %s" msgstr "%s 倚赖于 %s" -#: catalog/dependency.c:960 catalog/dependency.c:969 +#: catalog/dependency.c:1137 catalog/dependency.c:1146 #, c-format msgid "drop cascades to %s" msgstr "递归删除 %s" -#: catalog/dependency.c:977 catalog/pg_shdepend.c:687 +#: catalog/dependency.c:1154 catalog/pg_shdepend.c:770 #, c-format msgid "" "\n" @@ -3834,258 +3747,280 @@ msgstr[0] "" "\n" "%d个其它对象(相关列表å‚è§æœåŠ¡å™¨æ—¥å¿—)" -#: catalog/dependency.c:989 +#: catalog/dependency.c:1166 #, c-format msgid "cannot drop %s because other objects depend on it" msgstr "无法删除 %s 因为有其它对象倚赖它" -#: catalog/dependency.c:993 catalog/dependency.c:1000 +#: catalog/dependency.c:1168 catalog/dependency.c:1169 +#: catalog/dependency.c:1175 catalog/dependency.c:1176 +#: catalog/dependency.c:1187 catalog/dependency.c:1188 +#: commands/tablecmds.c:1192 commands/tablecmds.c:12067 commands/user.c:1073 +#: commands/view.c:505 libpq/auth.c:333 replication/syncrep.c:1163 +#: storage/lmgr/deadlock.c:1139 storage/lmgr/proc.c:1348 utils/adt/acl.c:5344 +#: utils/misc/guc.c:6576 utils/misc/guc.c:6612 utils/misc/guc.c:6682 +#: utils/misc/guc.c:10731 utils/misc/guc.c:10765 utils/misc/guc.c:10799 +#: utils/misc/guc.c:10833 utils/misc/guc.c:10868 utils/misc/guc.c:11613 +#: utils/misc/guc.c:11700 +#, c-format +msgid "%s" +msgstr "%s" + +#: catalog/dependency.c:1170 catalog/dependency.c:1177 #, c-format msgid "Use DROP ... CASCADE to drop the dependent objects too." msgstr "使用 DROP .. CASCADE 把倚赖对象一并删除." -#: catalog/dependency.c:997 +#: catalog/dependency.c:1174 #, c-format msgid "cannot drop desired object(s) because other objects depend on them" msgstr "无法删除希望的对象,因为有其它对象倚赖它" #. translator: %d always has a value larger than 1 -#: catalog/dependency.c:1006 +#: catalog/dependency.c:1183 #, c-format msgid "drop cascades to %d other object" msgid_plural "drop cascades to %d other objects" msgstr[0] "串è”删除%d个其它对象" -#: catalog/dependency.c:1634 +#: catalog/dependency.c:1845 #, c-format -msgid "constant of the type \"regrole\" cannot be used here" -msgstr "ä¸èƒ½åœ¨è¿™é‡Œä½¿ç”¨ç±»åž‹\"regrole\"的常é‡" +msgid "constant of the type %s cannot be used here" +msgstr "ä¸èƒ½åœ¨è¿™é‡Œä½¿ç”¨ç±»åž‹%s" -#: catalog/heap.c:277 +#: catalog/heap.c:332 #, c-format msgid "permission denied to create \"%s.%s\"" msgstr "创建 \"%s.%s\" æƒé™ä¸å¤Ÿ" -#: catalog/heap.c:279 +#: catalog/heap.c:334 #, c-format msgid "System catalog modifications are currently disallowed." msgstr "系统表修改是ä¸è¢«åŒæ—¶å…许的" -#: catalog/heap.c:414 commands/tablecmds.c:1438 commands/tablecmds.c:1895 -#: commands/tablecmds.c:4821 +#: catalog/heap.c:502 commands/tablecmds.c:2043 commands/tablecmds.c:2554 +#: commands/tablecmds.c:5638 #, c-format msgid "tables can have at most %d columns" msgstr "表最多å¯ä»¥æœ‰ %d 个字段" -#: catalog/heap.c:431 commands/tablecmds.c:5082 +#: catalog/heap.c:520 commands/tablecmds.c:5923 #, c-format msgid "column name \"%s\" conflicts with a system column name" msgstr "字段å \"%s\" 与系统字段å冲çª" -#: catalog/heap.c:447 +#: catalog/heap.c:536 #, c-format msgid "column name \"%s\" specified more than once" msgstr "字段åç§°\"%s\" 被定义多次" -#: catalog/heap.c:497 -#, c-format -msgid "column \"%s\" has type \"unknown\"" -msgstr "字段 \"%s\" 类型为 \"未知\"" - -#: catalog/heap.c:498 -#, c-format -msgid "Proceeding with relation creation anyway." -msgstr "继续关系的创建." - -#: catalog/heap.c:511 +#: catalog/heap.c:604 #, c-format msgid "column \"%s\" has pseudo-type %s" msgstr "字段 \"%s\" 有伪类型 %s" -#: catalog/heap.c:541 +#: catalog/heap.c:634 #, c-format msgid "composite type %s cannot be made a member of itself" msgstr "æ··åˆç±»åž‹ %s çš„æˆå‘˜ä¸èƒ½ä¸ºè‡ªèº«" -#: catalog/heap.c:583 commands/createas.c:373 +#: catalog/heap.c:676 commands/createas.c:204 commands/createas.c:488 #, c-format msgid "no collation was derived for column \"%s\" with collatable type %s" msgstr "没有æ¥è‡ªåˆ— \"%s\"的排åºè§„åˆ™å¸¦æœ‰å¯æŽ’åºç±»åž‹ %s" -#: catalog/heap.c:585 commands/createas.c:375 commands/indexcmds.c:1132 -#: commands/view.c:116 regex/regc_pg_locale.c:262 utils/adt/formatting.c:1514 -#: utils/adt/formatting.c:1566 utils/adt/formatting.c:1634 -#: utils/adt/formatting.c:1686 utils/adt/formatting.c:1755 -#: utils/adt/formatting.c:1819 utils/adt/like.c:213 utils/adt/selfuncs.c:5330 -#: utils/adt/varlena.c:1421 utils/adt/varlena.c:1826 -#, c-format -msgid "Use the COLLATE clause to set the collation explicitly." -msgstr "使用COLLATEå­å¥æ¥æ˜¾ç¤ºè®¾ç½®æŽ’åºè§„则." - -#: catalog/heap.c:1066 catalog/index.c:792 commands/tablecmds.c:2622 +#: catalog/heap.c:1122 catalog/index.c:819 commands/tablecmds.c:3321 #, c-format msgid "relation \"%s\" already exists" msgstr "关系 \"%s\" å·²ç»å­˜åœ¨" -#: catalog/heap.c:1082 catalog/pg_type.c:412 catalog/pg_type.c:722 -#: commands/typecmds.c:237 commands/typecmds.c:784 commands/typecmds.c:1135 -#: commands/typecmds.c:1357 commands/typecmds.c:2113 +#: catalog/heap.c:1138 catalog/pg_type.c:427 catalog/pg_type.c:749 +#: commands/typecmds.c:240 commands/typecmds.c:791 commands/typecmds.c:1191 +#: commands/typecmds.c:1403 commands/typecmds.c:2160 #, c-format msgid "type \"%s\" already exists" msgstr "类型 \"%s\" å·²ç»å­˜åœ¨" -#: catalog/heap.c:1083 +#: catalog/heap.c:1139 #, c-format -msgid "" -"A relation has an associated type of the same name, so you must use a name " -"that doesn't conflict with any existing type." -msgstr "" -"关系和与它相关è”的类型å称相åŒ,所以ä¸èƒ½ä½¿ç”¨ä¸Žä»»ä½•已存在类型å称相冲çªçš„åç§°." +msgid "A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type." +msgstr "关系和与它相关è”的类型å称相åŒ,所以ä¸èƒ½ä½¿ç”¨ä¸Žä»»ä½•已存在类型å称相冲çªçš„åç§°." -#: catalog/heap.c:1111 +#: catalog/heap.c:1168 #, c-format msgid "pg_class heap OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_class的堆OID值" -#: catalog/heap.c:2289 +#: catalog/heap.c:2369 +#, c-format +msgid "cannot add NO INHERIT constraint to partitioned table \"%s\"" +msgstr "无法å‘分区表\"%s\"添加NO INHERIT约æŸ" + +#: catalog/heap.c:2639 #, c-format msgid "check constraint \"%s\" already exists" msgstr "æ£€æŸ¥çº¦æŸ \"%s\" å·²ç»å­˜åœ¨" -#: catalog/heap.c:2442 catalog/pg_constraint.c:654 commands/tablecmds.c:6070 +#: catalog/heap.c:2809 catalog/index.c:833 catalog/pg_constraint.c:669 +#: commands/tablecmds.c:7316 #, c-format msgid "constraint \"%s\" for relation \"%s\" already exists" msgstr "关系 \"%2$s\" çš„çº¦æŸ \"%1$s\" å·²ç»å­˜åœ¨" -#: catalog/heap.c:2452 +#: catalog/heap.c:2816 #, c-format -msgid "" -"constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" +msgid "constraint \"%s\" conflicts with non-inherited constraint on relation \"%s\"" msgstr "关系\"%2$s\"上的约æŸ\"%1$s\"与éžç»§æ‰¿çº¦æŸç›¸å†²çª" -#: catalog/heap.c:2466 +#: catalog/heap.c:2827 +#, c-format +msgid "constraint \"%s\" conflicts with inherited constraint on relation \"%s\"" +msgstr "关系\"%2$s\"上的约æŸ\"%1$s\"与继承约æŸç›¸å†²çª" + +#: catalog/heap.c:2837 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on relation \"%s\"" +msgstr "关系\"%2$s\"上的约æŸ\"%1$s\"与NOT VALID约æŸç›¸å†²çª" + +#: catalog/heap.c:2842 #, c-format msgid "merging constraint \"%s\" with inherited definition" msgstr "正在åˆå¹¶å¸¦æœ‰å·²ç»§æ‰¿å®šä¹‰çš„约æŸ\"%s\" " -#: catalog/heap.c:2559 -#, c-format -msgid "cannot use column references in default expression" -msgstr "在默认的表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­—段关è”" +#: catalog/heap.c:2944 +#, fuzzy, c-format +#| msgid "cannot use system column \"%s\" in partition key" +msgid "cannot use generated column \"%s\" in column generation expression" +msgstr "无法在分区键中使用系统列\"%s\"" -#: catalog/heap.c:2570 +#: catalog/heap.c:2946 #, c-format -msgid "default expression must not return a set" -msgstr "默认表达å¼ä¸èƒ½è¿”回一个组åˆ" +msgid "A generated column cannot reference another generated column." +msgstr "" + +#: catalog/heap.c:2998 +#, fuzzy, c-format +#| msgid "referenced relation \"%s\" is not a table" +msgid "generation expression is not immutable" +msgstr "å…³è”的关系 \"%s\" 䏿˜¯ä¸€ä¸ªè¡¨" -#: catalog/heap.c:2589 rewrite/rewriteHandler.c:1084 +#: catalog/heap.c:3026 rewrite/rewriteHandler.c:1189 #, c-format msgid "column \"%s\" is of type %s but default expression is of type %s" msgstr "字段 \"%s\" 类型是 %s, 但默认表达å¼ç±»åž‹æ˜¯ %s" -#: catalog/heap.c:2594 commands/prepare.c:374 parser/parse_node.c:428 -#: parser/parse_target.c:528 parser/parse_target.c:778 -#: parser/parse_target.c:788 rewrite/rewriteHandler.c:1089 +#: catalog/heap.c:3031 commands/prepare.c:384 parser/parse_node.c:435 +#: parser/parse_target.c:591 parser/parse_target.c:866 +#: parser/parse_target.c:876 rewrite/rewriteHandler.c:1194 #, c-format msgid "You will need to rewrite or cast the expression." msgstr "你需è¦é‡å†™æˆ–转æ¢è¡¨è¾¾å¼" -#: catalog/heap.c:2641 +#: catalog/heap.c:3078 #, c-format msgid "only table \"%s\" can be referenced in check constraint" msgstr "在检查约æŸä¸­åªæœ‰è¡¨ \"%s\" 能被关è”çš„" -#: catalog/heap.c:2881 +#: catalog/heap.c:3328 #, c-format msgid "unsupported ON COMMIT and foreign key combination" msgstr "䏿”¯æŒON COMMIT和外键一åŒä½¿ç”¨" -#: catalog/heap.c:2882 +#: catalog/heap.c:3329 #, c-format -msgid "" -"Table \"%s\" references \"%s\", but they do not have the same ON COMMIT " -"setting." +msgid "Table \"%s\" references \"%s\", but they do not have the same ON COMMIT setting." msgstr "表 \"%s\"引用表\"%s\",但是它们没有相åŒçš„ON COMMIT设置." -#: catalog/heap.c:2887 +#: catalog/heap.c:3334 #, c-format msgid "cannot truncate a table referenced in a foreign key constraint" msgstr "在一个外键约æŸä¸­æ— æ³•删除 (truncate) 一个表的关è”" -#: catalog/heap.c:2888 +#: catalog/heap.c:3335 #, c-format msgid "Table \"%s\" references \"%s\"." msgstr "表\"%s\" 引用\"%s\"." -#: catalog/heap.c:2890 +#: catalog/heap.c:3337 #, c-format msgid "Truncate table \"%s\" at the same time, or use TRUNCATE ... CASCADE." msgstr "åŒæ—¶æˆªæ–­è¡¨\"%s\" ,或者使用TRUNCATE ... CASCADE." -#: catalog/index.c:210 parser/parse_utilcmd.c:1486 parser/parse_utilcmd.c:1572 +#: catalog/index.c:219 parser/parse_utilcmd.c:1873 parser/parse_utilcmd.c:1972 #, c-format msgid "multiple primary keys for table \"%s\" are not allowed" msgstr "对表 \"%s\" 指定多个主键是ä¸å…许的" -#: catalog/index.c:228 +#: catalog/index.c:237 #, c-format msgid "primary keys cannot be expressions" msgstr "主键ä¸èƒ½æ˜¯è¡¨è¾¾å¼" -#: catalog/index.c:742 catalog/index.c:1160 +#: catalog/index.c:254 +#, fuzzy, c-format +#| msgid "column \"%s\" is marked NOT NULL in parent table" +msgid "primary key column \"%s\" is not marked NOT NULL" +msgstr "列\"%s\"在父表中标记为NOT NULL" + +#: catalog/index.c:763 catalog/index.c:1709 #, c-format msgid "user-defined indexes on system catalog tables are not supported" msgstr "在系统表上用户定义的索引是ä¸è¢«æ”¯æŒçš„" -#: catalog/index.c:752 +#: catalog/index.c:773 #, c-format msgid "concurrent index creation on system catalog tables is not supported" msgstr "䏿”¯æŒåœ¨ç³»ç»Ÿç›®å½•è¡¨ä¸ŠåŒæ—¶åˆ›å»ºç´¢å¼•" -#: catalog/index.c:770 +#: catalog/index.c:791 #, c-format msgid "shared indexes cannot be created after initdb" msgstr "在 initdb 之åŽ, ä¸èƒ½åˆ›å»ºå…±äº«ç´¢å¼•" -#: catalog/index.c:784 commands/createas.c:100 commands/sequence.c:141 -#: parser/parse_utilcmd.c:192 +#: catalog/index.c:811 commands/createas.c:253 commands/sequence.c:154 +#: parser/parse_utilcmd.c:208 #, c-format msgid "relation \"%s\" already exists, skipping" msgstr "关系 \"%s\" å·²ç»å­˜åœ¨, 跳过" -#: catalog/index.c:820 +#: catalog/index.c:861 #, c-format msgid "pg_class index OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_class的索引OID值" -#: catalog/index.c:1422 +#: catalog/index.c:1985 #, c-format msgid "DROP INDEX CONCURRENTLY must be first action in transaction" msgstr "DROP INDEX CONCURRENTLY在一个事务当中必须是最先执行" -#: catalog/index.c:2004 +#: catalog/index.c:2682 +#, c-format +msgid "building index \"%s\" on table \"%s\" serially" +msgstr "为表 \"%2$s\" 串行的建立索引\"%1$s\"" + +#: catalog/index.c:2687 #, c-format -msgid "building index \"%s\" on table \"%s\"" -msgstr "为表 \"%2$s\" 建立索引\"%1$s\"" +msgid "building index \"%s\" on table \"%s\" with request for %d parallel worker" +msgid_plural "building index \"%s\" on table \"%s\" with request for %d parallel workers" +msgstr[0] "为表 \"%2$s\" 建立索引\"%1$s\",请求%3$d个并行工作线程" -#: catalog/index.c:3315 +#: catalog/index.c:3310 #, c-format msgid "cannot reindex temporary tables of other sessions" msgstr "ä¸èƒ½é‡æ–°åˆ›å»ºå…¶ä»–会è¯çš„临时表上的索引" -#: catalog/index.c:3440 +#: catalog/index.c:3441 #, c-format msgid "index \"%s\" was reindexed" msgstr "索引\"%s\"å·²è¢«é‡æ–°ç´¢å¼•" -#: catalog/index.c:3442 commands/vacuumlazy.c:1323 commands/vacuumlazy.c:1399 -#: commands/vacuumlazy.c:1588 commands/vacuumlazy.c:1789 +#: catalog/index.c:3514 commands/indexcmds.c:2871 #, c-format -msgid "%s." -msgstr "%s" +msgid "REINDEX of partitioned tables is not yet implemented, skipping \"%s\"" +msgstr "åˆ†åŒºè¡¨çš„é‡æ–°ç´¢å¼•尚未实现,跳过\"%s\"" -#: catalog/namespace.c:249 catalog/namespace.c:447 catalog/namespace.c:541 -#: commands/trigger.c:4527 +#: catalog/namespace.c:249 catalog/namespace.c:453 catalog/namespace.c:545 +#: commands/trigger.c:5396 #, c-format msgid "cross-database references are not implemented: \"%s.%s.%s\"" msgstr "未实现跨数æ®åº“å…³è”: \"%s.%s.%s\"" @@ -4095,387 +4030,368 @@ msgstr "未实现跨数æ®åº“å…³è”: \"%s.%s.%s\"" msgid "temporary tables cannot specify a schema name" msgstr "临时表ä¸èƒ½æŒ‡å®šæ¨¡å¼åç§°" -#: catalog/namespace.c:385 +#: catalog/namespace.c:387 #, c-format msgid "could not obtain lock on relation \"%s.%s\"" msgstr "无法在关系 \"%s.%s\" 上获得é”" -#: catalog/namespace.c:390 commands/lockcmds.c:146 +#: catalog/namespace.c:392 commands/lockcmds.c:162 commands/lockcmds.c:249 #, c-format msgid "could not obtain lock on relation \"%s\"" msgstr "无法在关系 \"%s\" 上获得é”" -#: catalog/namespace.c:414 parser/parse_relation.c:1137 +#: catalog/namespace.c:420 parser/parse_relation.c:1172 #, c-format msgid "relation \"%s.%s\" does not exist" msgstr "关系 \"%s.%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:419 parser/parse_relation.c:1150 -#: parser/parse_relation.c:1158 utils/adt/regproc.c:1034 +#: catalog/namespace.c:425 parser/parse_relation.c:1185 +#: parser/parse_relation.c:1193 #, c-format msgid "relation \"%s\" does not exist" msgstr "关系 \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:487 catalog/namespace.c:2841 commands/extension.c:1382 -#: commands/extension.c:1388 +#: catalog/namespace.c:491 catalog/namespace.c:3009 commands/extension.c:1469 +#: commands/extension.c:1475 #, c-format msgid "no schema has been selected to create in" msgstr "创建中没有选择模å¼" -#: catalog/namespace.c:639 catalog/namespace.c:652 +#: catalog/namespace.c:643 catalog/namespace.c:656 #, c-format msgid "cannot create relations in temporary schemas of other sessions" msgstr "ä¸èƒ½åœ¨å…¶ä»–会è¯çš„临时方案上创建关系" -#: catalog/namespace.c:643 +#: catalog/namespace.c:647 #, c-format msgid "cannot create temporary relation in non-temporary schema" msgstr "ä¸èƒ½åœ¨éžä¸´æ—¶æ–¹æ¡ˆä¸Šåˆ›å»ºä¸´æ—¶å…³ç³»" -#: catalog/namespace.c:658 +#: catalog/namespace.c:662 #, c-format msgid "only temporary relations may be created in temporary schemas" msgstr "临时方案里åªèƒ½åˆ›å»ºä¸´æ—¶å…³ç³»" -#: catalog/namespace.c:2154 +#: catalog/namespace.c:2201 +#, c-format +msgid "statistics object \"%s\" does not exist" +msgstr "统计信æ¯å¯¹è±¡ \"%s\" ä¸å­˜åœ¨" + +#: catalog/namespace.c:2324 #, c-format msgid "text search parser \"%s\" does not exist" msgstr "文本æœç´¢è§£æžå™¨ \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:2280 +#: catalog/namespace.c:2450 #, c-format msgid "text search dictionary \"%s\" does not exist" msgstr "文本æœç´¢å­—å…¸ \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:2407 +#: catalog/namespace.c:2577 #, c-format msgid "text search template \"%s\" does not exist" msgstr "文本æœç´¢æ¨¡ç‰ˆ \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:2533 commands/tsearchcmds.c:1197 -#: utils/cache/ts_cache.c:613 +#: catalog/namespace.c:2703 commands/tsearchcmds.c:1197 +#: utils/cache/ts_cache.c:615 #, c-format msgid "text search configuration \"%s\" does not exist" msgstr "文本æœå¯»é…ç½® \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:2646 parser/parse_expr.c:789 parser/parse_target.c:1130 +#: catalog/namespace.c:2816 parser/parse_expr.c:866 parser/parse_target.c:1221 #, c-format msgid "cross-database references are not implemented: %s" msgstr "未实现跨数æ®åº“å…³è”: %s" -#: catalog/namespace.c:2652 gram.y:13434 gram.y:14791 parser/parse_expr.c:796 -#: parser/parse_target.c:1137 +#: catalog/namespace.c:2822 parser/parse_expr.c:873 parser/parse_target.c:1228 +#: gram.y:14731 gram.y:16165 #, c-format msgid "improper qualified name (too many dotted names): %s" msgstr "ä¸åˆé€‚çš„æ¡ä»¶åç§° (å字中太多的点符å·): %s" -#: catalog/namespace.c:2783 +#: catalog/namespace.c:2952 #, c-format msgid "cannot move objects into or out of temporary schemas" msgstr "无法将对象移入或移出临时模å¼" -#: catalog/namespace.c:2789 +#: catalog/namespace.c:2958 #, c-format msgid "cannot move objects into or out of TOAST schema" msgstr "无法将对象移入或移出TOAST模å¼" -#: catalog/namespace.c:2862 commands/schemacmds.c:242 -#: commands/schemacmds.c:321 commands/tablecmds.c:740 +#: catalog/namespace.c:3031 commands/schemacmds.c:257 commands/schemacmds.c:337 +#: commands/tablecmds.c:1137 #, c-format msgid "schema \"%s\" does not exist" msgstr "æ¨¡å¼ \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:2893 +#: catalog/namespace.c:3062 #, c-format msgid "improper relation name (too many dotted names): %s" msgstr "ä¸åˆé€‚的关系åç§° (å字中太多的点符å·): %s" -#: catalog/namespace.c:3358 +#: catalog/namespace.c:3596 #, c-format msgid "collation \"%s\" for encoding \"%s\" does not exist" msgstr "ç¼–ç  \"%2$s\" 中的排åºè§„则 \"%1$s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:3413 +#: catalog/namespace.c:3651 #, c-format msgid "conversion \"%s\" does not exist" msgstr "ç¼–ç è½¬æ¢ \"%s\" ä¸å­˜åœ¨" -#: catalog/namespace.c:3621 +#: catalog/namespace.c:3891 #, c-format msgid "permission denied to create temporary tables in database \"%s\"" msgstr "ä¸å…许在数æ®åº“ \"%s\" 中创建临时表" -#: catalog/namespace.c:3637 +#: catalog/namespace.c:3907 #, c-format msgid "cannot create temporary tables during recovery" msgstr "ä¸èƒ½åœ¨æ¢å¤è¿‡ç¨‹ä¸­åˆ›å»ºä¸´æ—¶è¡¨" -#: catalog/namespace.c:3643 +#: catalog/namespace.c:3913 #, c-format -msgid "cannot create temporary tables in parallel mode" -msgstr "并行模å¼ä¸­ä¸èƒ½åˆ›å»ºä¸´æ—¶è¡¨" +msgid "cannot create temporary tables during a parallel operation" +msgstr "在并行æ“作期间无法创建临时表" -#: catalog/namespace.c:3887 commands/tablespace.c:1177 commands/variable.c:63 -#: utils/misc/guc.c:9853 +#: catalog/namespace.c:4196 commands/tablespace.c:1186 commands/variable.c:64 +#: utils/misc/guc.c:10900 utils/misc/guc.c:10978 #, c-format msgid "List syntax is invalid." msgstr "列表语法无效." -#: catalog/objectaddress.c:1065 -#| msgid "schema name cannot be qualified" -msgid "access method name cannot be qualified" -msgstr "ä¸èƒ½é™å®šè®¿é—®æ–¹æ³•åç§°" - -#: catalog/objectaddress.c:1068 -msgid "database name cannot be qualified" -msgstr "ä¸èƒ½é™å®šæ•°æ®åº“åç§°" - -#: catalog/objectaddress.c:1071 commands/extension.c:2506 -#, c-format -msgid "extension name cannot be qualified" -msgstr "扩展åä¸åˆæ ¼" - -#: catalog/objectaddress.c:1074 -msgid "tablespace name cannot be qualified" -msgstr "ä¸èƒ½é™å®šè¡¨ç©ºé—´åç§°" - -#: catalog/objectaddress.c:1077 -msgid "role name cannot be qualified" -msgstr "ä¸èƒ½é™å®šè§’色åç§°" - -#: catalog/objectaddress.c:1080 -msgid "schema name cannot be qualified" -msgstr "ä¸èƒ½é™å®šæ¨¡å¼åç§°" - -#: catalog/objectaddress.c:1083 -msgid "language name cannot be qualified" -msgstr "ä¸èƒ½é™å®šlanguageåç§°" - -#: catalog/objectaddress.c:1086 -msgid "foreign-data wrapper name cannot be qualified" -msgstr "foreign-dataåŒ…è£…å™¨åæ— æ³•é™å®š" - -#: catalog/objectaddress.c:1089 -msgid "server name cannot be qualified" -msgstr "无法é™å®šæœåС噍å" - -#: catalog/objectaddress.c:1092 -msgid "event trigger name cannot be qualified" -msgstr "事件触å‘噍命志 æ³•确定" - -#: catalog/objectaddress.c:1210 commands/lockcmds.c:94 commands/policy.c:94 -#: commands/policy.c:389 commands/policy.c:478 commands/tablecmds.c:217 -#: commands/tablecmds.c:1299 commands/tablecmds.c:4348 -#: commands/tablecmds.c:7979 +#: catalog/objectaddress.c:1274 catalog/pg_publication.c:66 +#: commands/policy.c:95 commands/policy.c:395 commands/policy.c:485 +#: commands/tablecmds.c:224 commands/tablecmds.c:266 commands/tablecmds.c:1899 +#: commands/tablecmds.c:5142 commands/tablecmds.c:10327 #, c-format msgid "\"%s\" is not a table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨" -#: catalog/objectaddress.c:1217 commands/tablecmds.c:229 -#: commands/tablecmds.c:4378 commands/tablecmds.c:12014 commands/view.c:155 +#: catalog/objectaddress.c:1281 commands/tablecmds.c:236 +#: commands/tablecmds.c:5172 commands/tablecmds.c:14774 commands/view.c:138 #, c-format msgid "\"%s\" is not a view" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè§†å›¾" -#: catalog/objectaddress.c:1224 commands/matview.c:174 -#: commands/tablecmds.c:235 commands/tablecmds.c:12019 +#: catalog/objectaddress.c:1288 commands/matview.c:175 commands/tablecmds.c:242 +#: commands/tablecmds.c:14779 #, c-format msgid "\"%s\" is not a materialized view" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç‰©åŒ–视图" -#: catalog/objectaddress.c:1231 commands/tablecmds.c:253 -#: commands/tablecmds.c:4381 commands/tablecmds.c:12024 +#: catalog/objectaddress.c:1295 commands/tablecmds.c:260 +#: commands/tablecmds.c:5175 commands/tablecmds.c:14784 #, c-format msgid "\"%s\" is not a foreign table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªå¤–部表" -#: catalog/objectaddress.c:1376 catalog/objectaddress.c:1429 +#: catalog/objectaddress.c:1336 +#, c-format +msgid "must specify relation and object name" +msgstr "必须指定关系和对象åç§°" + +#: catalog/objectaddress.c:1412 catalog/objectaddress.c:1465 #, c-format msgid "column name must be qualified" msgstr "ä¸èƒ½é™å®šåˆ—åç§°" -#: catalog/objectaddress.c:1472 +#: catalog/objectaddress.c:1512 #, c-format msgid "default value for column \"%s\" of relation \"%s\" does not exist" msgstr "关系\"%2$s\"的列\"%1$s\"的默认值ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1512 commands/functioncmds.c:128 -#: commands/tablecmds.c:245 commands/typecmds.c:3214 parser/parse_type.c:226 -#: parser/parse_type.c:255 parser/parse_type.c:795 utils/adt/acl.c:4374 -#: utils/adt/regproc.c:1225 +#: catalog/objectaddress.c:1549 commands/functioncmds.c:132 +#: commands/tablecmds.c:252 commands/typecmds.c:3321 parser/parse_type.c:226 +#: parser/parse_type.c:255 parser/parse_type.c:828 utils/adt/acl.c:4451 #, c-format msgid "type \"%s\" does not exist" msgstr "类型 \"%s\" ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1629 +#: catalog/objectaddress.c:1668 #, c-format msgid "operator %d (%s, %s) of %s does not exist" msgstr "%4$sçš„æ“作符%1$d (%2$s,%3$s)ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1658 +#: catalog/objectaddress.c:1699 #, c-format msgid "function %d (%s, %s) of %s does not exist" msgstr "%4$s的函数%1$d (%2$s, %3$s)ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1707 catalog/objectaddress.c:1733 +#: catalog/objectaddress.c:1750 catalog/objectaddress.c:1776 #, c-format msgid "user mapping for user \"%s\" on server \"%s\" does not exist" msgstr "用户\"%s\"在æœåС噍\"%s\"上的用户映射ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1722 commands/foreigncmds.c:430 -#: commands/foreigncmds.c:997 commands/foreigncmds.c:1372 -#: foreign/foreign.c:798 +#: catalog/objectaddress.c:1765 commands/foreigncmds.c:433 +#: commands/foreigncmds.c:1016 commands/foreigncmds.c:1396 +#: foreign/foreign.c:723 #, c-format msgid "server \"%s\" does not exist" msgstr "æœåС噍\"%s\" ä¸å­˜åœ¨" -#: catalog/objectaddress.c:1794 +#: catalog/objectaddress.c:1832 +#, c-format +msgid "publication relation \"%s\" in publication \"%s\" does not exist" +msgstr "å‘布关系\"%s\"在å‘布\"%s\"中ä¸å­˜åœ¨" + +#: catalog/objectaddress.c:1894 #, c-format -msgid "unrecognized default ACL object type %c" -msgstr "无法识别的默认ACL对象类型%c" +msgid "unrecognized default ACL object type \"%c\"" +msgstr "无法识别的默认ACL对象类型\"%c\"" -#: catalog/objectaddress.c:1795 +#: catalog/objectaddress.c:1895 #, c-format -msgid "Valid object types are \"r\", \"S\", \"f\", and \"T\"." -msgstr "有效的对象类型为\"r\"ã€\"S\"ã€\"f\"å’Œ\"T\"。" +msgid "Valid object types are \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." +msgstr "有效的对象类型为 \"%c\", \"%c\", \"%c\", \"%c\", \"%c\"." -#: catalog/objectaddress.c:1841 +#: catalog/objectaddress.c:1946 #, c-format msgid "default ACL for user \"%s\" in schema \"%s\" on %s does not exist" msgstr "模å¼\"%2$s\"中用户\"%1$s\"在%3$s上的默认ACLä¸å­˜åœ¨" -#: catalog/objectaddress.c:1846 +#: catalog/objectaddress.c:1951 #, c-format msgid "default ACL for user \"%s\" on %s does not exist" msgstr "用户\"%s\"在%s上的默认ACLä¸å­˜åœ¨" -#: catalog/objectaddress.c:1873 catalog/objectaddress.c:1929 -#: catalog/objectaddress.c:1984 +#: catalog/objectaddress.c:1978 catalog/objectaddress.c:2036 +#: catalog/objectaddress.c:2093 #, c-format msgid "name or argument lists may not contain nulls" msgstr "åç§°æˆ–è€…å‚æ•°åˆ—表ä¸èƒ½åŒ…å«ç©ºå€¼" -#: catalog/objectaddress.c:1905 +#: catalog/objectaddress.c:2012 #, c-format msgid "unsupported object type \"%s\"" msgstr "䏿”¯æŒçš„对象类型\"%s\"" -#: catalog/objectaddress.c:1925 catalog/objectaddress.c:1943 +#: catalog/objectaddress.c:2032 catalog/objectaddress.c:2050 +#: catalog/objectaddress.c:2191 #, c-format msgid "name list length must be exactly %d" msgstr "å字列表的长度必须正好是 %d" -#: catalog/objectaddress.c:1947 +#: catalog/objectaddress.c:2054 #, c-format msgid "large object OID may not be null" msgstr "大对象OIDä¸èƒ½ä¸ºç©º" -#: catalog/objectaddress.c:1956 catalog/objectaddress.c:2016 -#: catalog/objectaddress.c:2023 +#: catalog/objectaddress.c:2063 catalog/objectaddress.c:2126 +#: catalog/objectaddress.c:2133 #, c-format msgid "name list length must be at least %d" msgstr "å称列表的长度必须至少为%d" -#: catalog/objectaddress.c:2009 catalog/objectaddress.c:2029 +#: catalog/objectaddress.c:2119 catalog/objectaddress.c:2140 #, c-format msgid "argument list length must be exactly %d" msgstr "傿•°åˆ—表的长度必须正好为%d" -#: catalog/objectaddress.c:2165 libpq/be-fsstubs.c:352 +#: catalog/objectaddress.c:2370 libpq/be-fsstubs.c:321 #, c-format msgid "must be owner of large object %u" msgstr "必须是大对象%u的属主" -#: catalog/objectaddress.c:2180 commands/functioncmds.c:1426 +#: catalog/objectaddress.c:2385 commands/functioncmds.c:1535 #, c-format msgid "must be owner of type %s or type %s" msgstr "åªèƒ½æ˜¯ç±»åž‹ %s 或 %s 的所由者" -#: catalog/objectaddress.c:2220 catalog/objectaddress.c:2237 +#: catalog/objectaddress.c:2435 catalog/objectaddress.c:2452 #, c-format msgid "must be superuser" msgstr "必须是超级用户" -#: catalog/objectaddress.c:2227 +#: catalog/objectaddress.c:2442 #, c-format msgid "must have CREATEROLE privilege" msgstr "必须拥有CREATEROLEæƒé™." -#: catalog/objectaddress.c:2307 +#: catalog/objectaddress.c:2521 #, c-format msgid "unrecognized object type \"%s\"" msgstr "无法识别的对象类型\"%s\"" -#: catalog/objectaddress.c:2502 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2742 #, c-format -msgid " column %s" -msgstr " 字段 %s" +msgid "column %s of %s" +msgstr "%2$s的列%1$s" -#: catalog/objectaddress.c:2508 +#: catalog/objectaddress.c:2752 #, c-format msgid "function %s" msgstr "函数 %s" -#: catalog/objectaddress.c:2513 +#: catalog/objectaddress.c:2757 #, c-format msgid "type %s" msgstr "类型 %s" -#: catalog/objectaddress.c:2543 +#: catalog/objectaddress.c:2787 #, c-format msgid "cast from %s to %s" msgstr "%s 转æ¢ä¸º %s" -#: catalog/objectaddress.c:2563 +#: catalog/objectaddress.c:2815 #, c-format msgid "collation %s" msgstr "排åºè§„则 %s" -#: catalog/objectaddress.c:2587 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:2841 #, c-format msgid "constraint %s on %s" msgstr "在%2$s上的约æŸ%1$s " -#: catalog/objectaddress.c:2593 +#: catalog/objectaddress.c:2847 #, c-format msgid "constraint %s" msgstr "çº¦æŸ %s" -#: catalog/objectaddress.c:2610 +#: catalog/objectaddress.c:2874 #, c-format msgid "conversion %s" msgstr "ç¼–ç è½¬æ¢ %s" -#: catalog/objectaddress.c:2647 +#. translator: %s is typically "column %s of table %s" +#: catalog/objectaddress.c:2913 #, c-format -msgid "default for %s" -msgstr "%s的缺çœ" +msgid "default value for %s" +msgstr "%s的缺çœå€¼" -#: catalog/objectaddress.c:2656 +#: catalog/objectaddress.c:2922 #, c-format msgid "language %s" msgstr "语言 %s" -#: catalog/objectaddress.c:2661 +#: catalog/objectaddress.c:2927 #, c-format msgid "large object %u" msgstr "大对象 %u " -#: catalog/objectaddress.c:2666 +#: catalog/objectaddress.c:2932 #, c-format msgid "operator %s" msgstr "æ“作符 %s" -#: catalog/objectaddress.c:2698 +#: catalog/objectaddress.c:2964 #, c-format msgid "operator class %s for access method %s" msgstr "å¤„ç†æ–¹æ³• %s çš„æ“作符类 %s" +#: catalog/objectaddress.c:2987 +#, c-format +msgid "access method %s" +msgstr "访问方法 %s" + #. translator: %d is the operator strategy (a number), the #. first two %s's are data type names, the third %s is the #. description of the operator family, and the last %s is the #. textual form of the operator with arguments. -#: catalog/objectaddress.c:2748 +#: catalog/objectaddress.c:3029 #, c-format msgid "operator %d (%s, %s) of %s: %s" msgstr "%5$s: %4$s中的æ“作符%1$d (%2$s,%3$s)" @@ -4484,587 +4400,706 @@ msgstr "%5$s: %4$s中的æ“作符%1$d (%2$s,%3$s)" #. are data type names, the third %s is the description of the #. operator family, and the last %s is the textual form of the #. function with arguments. -#: catalog/objectaddress.c:2798 +#: catalog/objectaddress.c:3079 #, c-format msgid "function %d (%s, %s) of %s: %s" msgstr "%4$s: %5$s 的函数%1$d (%2$s, %3$s)" -#: catalog/objectaddress.c:2838 -#, c-format -msgid "rule %s on " -msgstr "规则 %s 在 " - -#: catalog/objectaddress.c:2860 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3123 #, c-format -msgid "transform for %s language %s" -msgstr "用于把%s转æ¢åˆ°è¯­è¨€%s的转æ¢" +msgid "rule %s on %s" +msgstr "规则 %s 在 %s" -#: catalog/objectaddress.c:2894 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3161 #, c-format -msgid "trigger %s on " -msgstr "触å‘器 %s 在 " +msgid "trigger %s on %s" +msgstr "触å‘器 %s 在 %s" -#: catalog/objectaddress.c:2911 +#: catalog/objectaddress.c:3177 #, c-format msgid "schema %s" msgstr "æ¨¡å¼ %s" -#: catalog/objectaddress.c:2924 +#: catalog/objectaddress.c:3200 +#, c-format +msgid "statistics object %s" +msgstr "统计信æ¯å¯¹è±¡%s" + +#: catalog/objectaddress.c:3227 #, c-format msgid "text search parser %s" msgstr "文本æœå¯»è§£æžå™¨ %s" # sql_help.h:301 -#: catalog/objectaddress.c:2939 +#: catalog/objectaddress.c:3253 #, c-format msgid "text search dictionary %s" msgstr "文本æœå¯»å­—å…¸ %s" # describe.c:1753 -#: catalog/objectaddress.c:2954 +#: catalog/objectaddress.c:3279 #, c-format msgid "text search template %s" msgstr "文本æœå¯»æ¨¡ç‰ˆ %s" -#: catalog/objectaddress.c:2969 +#: catalog/objectaddress.c:3305 #, c-format msgid "text search configuration %s" msgstr "文本æœå¯»é…ç½® %s" -#: catalog/objectaddress.c:2977 +#: catalog/objectaddress.c:3314 #, c-format msgid "role %s" msgstr "角色 %s" -#: catalog/objectaddress.c:2990 +#: catalog/objectaddress.c:3327 #, c-format msgid "database %s" msgstr "æ•°æ®åº“ %s" # describe.c:1342 -#: catalog/objectaddress.c:3002 +#: catalog/objectaddress.c:3339 #, c-format msgid "tablespace %s" msgstr "表空间 %s" -#: catalog/objectaddress.c:3011 +#: catalog/objectaddress.c:3348 #, c-format msgid "foreign-data wrapper %s" msgstr "外部数æ®å°è£…器 %s" -#: catalog/objectaddress.c:3020 +#: catalog/objectaddress.c:3357 #, c-format msgid "server %s" msgstr "æœåС噍 %s" -#: catalog/objectaddress.c:3048 +#: catalog/objectaddress.c:3385 #, c-format msgid "user mapping for %s on server %s" msgstr "%s在æœåС噍%s上的用户映射" -#: catalog/objectaddress.c:3083 +#: catalog/objectaddress.c:3430 +#, c-format +msgid "default privileges on new relations belonging to role %s in schema %s" +msgstr "åœ¨æ¨¡å¼ %2$sä¸Šï¼Œåœ¨æ–°çš„å…³ç³»ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%1$s" + +#: catalog/objectaddress.c:3434 #, c-format msgid "default privileges on new relations belonging to role %s" msgstr "åœ¨æ–°çš„å…³ç³»ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%s" -#: catalog/objectaddress.c:3088 +#: catalog/objectaddress.c:3440 +#, c-format +msgid "default privileges on new sequences belonging to role %s in schema %s" +msgstr "åœ¨æ¨¡å¼ %2$s上,在新的åºåˆ—ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%1$s" + +#: catalog/objectaddress.c:3444 #, c-format msgid "default privileges on new sequences belonging to role %s" msgstr "在新的åºåˆ—ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%s" -#: catalog/objectaddress.c:3093 +#: catalog/objectaddress.c:3450 +#, c-format +msgid "default privileges on new functions belonging to role %s in schema %s" +msgstr "åœ¨æ¨¡å¼ %2$sä¸Šï¼Œåœ¨æ–°çš„å‡½æ•°ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%1$s" + +#: catalog/objectaddress.c:3454 #, c-format msgid "default privileges on new functions belonging to role %s" msgstr "åœ¨æ–°çš„å‡½æ•°ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%s" -#: catalog/objectaddress.c:3098 +#: catalog/objectaddress.c:3460 +#, c-format +msgid "default privileges on new types belonging to role %s in schema %s" +msgstr "对属于角色%s(在模å¼%s中)的新类型的默认æƒé™" + +#: catalog/objectaddress.c:3464 #, c-format msgid "default privileges on new types belonging to role %s" msgstr "åœ¨æ–°ç±»åž‹ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色 %s" -#: catalog/objectaddress.c:3104 +#: catalog/objectaddress.c:3470 #, c-format -msgid "default privileges belonging to role %s" -msgstr "ç¼ºçœæƒé™å±žäºŽè§’色%s" +msgid "default privileges on new schemas belonging to role %s" +msgstr "在新的模å¼ä¸Šçš„ç¼ºçœæƒé™å±žäºŽè§’色%s" + +#: catalog/objectaddress.c:3477 +#, c-format +msgid "default privileges belonging to role %s in schema %s" +msgstr "在模å¼%2$sä¸Šï¼Œç¼ºçœæƒé™å±žäºŽè§’色%1$s" -#: catalog/objectaddress.c:3112 +#: catalog/objectaddress.c:3481 #, c-format -msgid " in schema %s" -msgstr "在模å¼%s中" +msgid "default privileges belonging to role %s" +msgstr "ç¼ºçœæƒé™å±žäºŽè§’色%s" -#: catalog/objectaddress.c:3129 +#: catalog/objectaddress.c:3499 #, c-format msgid "extension %s" msgstr "扩展 %s" # describe.c:1549 -#: catalog/objectaddress.c:3142 +#: catalog/objectaddress.c:3512 #, c-format msgid "event trigger %s" msgstr "事件触å‘器%s" -#: catalog/objectaddress.c:3174 +#. translator: second %s is, e.g., "table %s" +#: catalog/objectaddress.c:3548 #, c-format -msgid "policy %s on " -msgstr "ç­–ç•¥%s在 " +msgid "policy %s on %s" +msgstr "ç­–ç•¥%s在 %s上" -#: catalog/objectaddress.c:3192 +#: catalog/objectaddress.c:3558 #, c-format -#| msgid "access method \"%s\" does not exist" -msgid "access method %s" -msgstr "访问方法 %s" +msgid "publication %s" +msgstr "å‘布 %s" + +#. translator: first %s is, e.g., "table %s" +#: catalog/objectaddress.c:3584 +#, c-format +msgid "publication of %s in publication %s" +msgstr "在å‘布%s中å‘布%s" -#: catalog/objectaddress.c:3252 +#: catalog/objectaddress.c:3593 +#, c-format +msgid "subscription %s" +msgstr "订阅 %s" + +#: catalog/objectaddress.c:3612 +#, c-format +msgid "transform for %s language %s" +msgstr "用于把%s转æ¢åˆ°è¯­è¨€%s的转æ¢" + +#: catalog/objectaddress.c:3675 #, c-format msgid "table %s" msgstr "表 %s" -#: catalog/objectaddress.c:3256 +#: catalog/objectaddress.c:3680 #, c-format msgid "index %s" msgstr "索引 %s" -#: catalog/objectaddress.c:3260 +#: catalog/objectaddress.c:3684 #, c-format msgid "sequence %s" msgstr "åºåˆ— %s" -#: catalog/objectaddress.c:3264 +#: catalog/objectaddress.c:3688 #, c-format msgid "toast table %s" msgstr "toast 表 %s" -#: catalog/objectaddress.c:3268 +#: catalog/objectaddress.c:3692 #, c-format msgid "view %s" msgstr "视图 %s" -#: catalog/objectaddress.c:3272 +#: catalog/objectaddress.c:3696 #, c-format msgid "materialized view %s" msgstr "物化视图 %s" -#: catalog/objectaddress.c:3276 +#: catalog/objectaddress.c:3700 #, c-format msgid "composite type %s" msgstr "å¤åˆç±»åž‹ %s" -#: catalog/objectaddress.c:3280 +#: catalog/objectaddress.c:3704 #, c-format msgid "foreign table %s" msgstr "外部表 %s" -#: catalog/objectaddress.c:3285 +#: catalog/objectaddress.c:3709 #, c-format msgid "relation %s" msgstr "关系 %s" -#: catalog/objectaddress.c:3322 +#: catalog/objectaddress.c:3746 #, c-format msgid "operator family %s for access method %s" msgstr "访问方法 %2$s çš„æ“作符类 %1$s" -#: catalog/pg_aggregate.c:126 +#: catalog/partition.c:214 commands/analyze.c:1353 commands/indexcmds.c:1092 +#: commands/tablecmds.c:1068 commands/tablecmds.c:8114 +#: commands/tablecmds.c:8257 commands/tablecmds.c:8448 +#: commands/tablecmds.c:8585 commands/tablecmds.c:10389 +#: commands/tablecmds.c:15681 commands/tablecmds.c:16236 +#: executor/execExprInterp.c:3303 executor/execMain.c:1865 +#: executor/execMain.c:1951 executor/execMain.c:2001 executor/execMain.c:2109 +#: executor/execPartition.c:590 executor/execPartition.c:650 +#: executor/execPartition.c:794 executor/execPartition.c:908 +#: executor/execPartition.c:941 executor/execPartition.c:1046 +#: executor/nodeModifyTable.c:1963 +msgid "could not convert row type" +msgstr "无法转æ¢è®°å½•类型" + +#: catalog/pg_aggregate.c:129 #, c-format msgid "aggregates cannot have more than %d argument" msgid_plural "aggregates cannot have more than %d arguments" msgstr[0] "èšé›†å‡½æ•°çš„傿•°ä¸èƒ½å¤šäºŽ%d个" -#: catalog/pg_aggregate.c:149 catalog/pg_aggregate.c:159 +#: catalog/pg_aggregate.c:152 catalog/pg_aggregate.c:162 #, c-format msgid "cannot determine transition data type" msgstr "æ— æ³•ç¡®å®šè½¬æ¢æ•°æ®ç±»åž‹" -#: catalog/pg_aggregate.c:150 catalog/pg_aggregate.c:160 +#: catalog/pg_aggregate.c:153 catalog/pg_aggregate.c:163 #, c-format -msgid "" -"An aggregate using a polymorphic transition type must have at least one " -"polymorphic argument." +msgid "An aggregate using a polymorphic transition type must have at least one polymorphic argument." msgstr "使用多æ€è½¬æ¢ç±»åž‹çš„èšåˆå‡½æ•°å¿…须至少有一个多æ€çš„傿•°" -#: catalog/pg_aggregate.c:173 +#: catalog/pg_aggregate.c:176 #, c-format msgid "a variadic ordered-set aggregate must use VARIADIC type ANY" msgstr "一个å¯å˜æœ‰åºé›†èšé›†å¿…须使用å¯å˜ç±»åž‹ANY" -#: catalog/pg_aggregate.c:199 +#: catalog/pg_aggregate.c:202 #, c-format -msgid "" -"a hypothetical-set aggregate must have direct arguments matching its " -"aggregated arguments" +msgid "a hypothetical-set aggregate must have direct arguments matching its aggregated arguments" msgstr "一个判定集èšé›†çš„ç›´æŽ¥å‚æ•°å¿…须与它的èšé›†å‚数相匹é…" -#: catalog/pg_aggregate.c:246 catalog/pg_aggregate.c:290 +#: catalog/pg_aggregate.c:249 catalog/pg_aggregate.c:293 #, c-format msgid "return type of transition function %s is not %s" msgstr "转æ¢å‡½æ•°çš„返回类型 %s 䏿˜¯ %s" -#: catalog/pg_aggregate.c:266 catalog/pg_aggregate.c:309 +#: catalog/pg_aggregate.c:269 catalog/pg_aggregate.c:312 #, c-format -msgid "" -"must not omit initial value when transition function is strict and " -"transition type is not compatible with input type" +msgid "must not omit initial value when transition function is strict and transition type is not compatible with input type" msgstr "当转æ¢å‡½æ•°æ˜¯å—é™åˆ¶çš„并且转æ¢ç±»åž‹ä¸Žè¾“入类型ä¸å…¼å®¹æ—¶ï¼Œä¸èƒ½å¿½ç•¥åˆå§‹åŒ–值" -#: catalog/pg_aggregate.c:335 +#: catalog/pg_aggregate.c:338 #, c-format msgid "return type of inverse transition function %s is not %s" msgstr "逆å‘转æ¢å‡½æ•°çš„返回类型 %s 䏿˜¯ %s" -#: catalog/pg_aggregate.c:352 executor/nodeWindowAgg.c:2305 +#: catalog/pg_aggregate.c:355 executor/nodeWindowAgg.c:2851 #, c-format -msgid "" -"strictness of aggregate's forward and inverse transition functions must match" +msgid "strictness of aggregate's forward and inverse transition functions must match" msgstr "èšé›†å‡½æ•°çš„æ­£å‘和逆å‘转æ¢å‡½æ•°å¿…须匹é…" -#: catalog/pg_aggregate.c:396 catalog/pg_aggregate.c:547 +#: catalog/pg_aggregate.c:399 catalog/pg_aggregate.c:552 #, c-format msgid "final function with extra arguments must not be declared STRICT" msgstr "另傿•°çš„终止函数ä¸èƒ½å®šä¹‰ä¸ºSTRICT" -#: catalog/pg_aggregate.c:426 +#: catalog/pg_aggregate.c:430 #, c-format -#| msgid "return type of transition function %s is not %s" msgid "return type of combine function %s is not %s" msgstr "组åˆå‡½æ•° %s çš„è¿”å›žç±»åž‹ä¸æ˜¯ %s" -#: catalog/pg_aggregate.c:437 +#: catalog/pg_aggregate.c:442 executor/nodeAgg.c:2973 #, c-format -#| msgid "final function with extra arguments must not be declared STRICT" -msgid "" -"combine function with \"%s\" transition type must not be declared STRICT" -msgstr "带有 \"%s\" 转移类型的组åˆå‡½æ•°ä¸èƒ½è¢«å£°æ˜Žä¸º STRICT" +msgid "combine function with transition type %s must not be declared STRICT" +msgstr "转æ¢ç±»åž‹ä¸º%s的组åˆå‡½æ•°ä¸èƒ½å£°æ˜Žä¸ºSTRICT" -#: catalog/pg_aggregate.c:457 +#: catalog/pg_aggregate.c:461 #, c-format -#| msgid "return type of transition function %s is not %s" msgid "return type of serialization function %s is not %s" msgstr "åºåˆ—化函数 %s çš„è¿”å›žç±»åž‹ä¸æ˜¯ %s" -#: catalog/pg_aggregate.c:477 +#: catalog/pg_aggregate.c:482 #, c-format -#| msgid "return type of transition function %s is not %s" msgid "return type of deserialization function %s is not %s" msgstr "ååºåˆ—化函数 %s çš„è¿”å›žç±»åž‹ä¸æ˜¯ %s" -#: catalog/pg_aggregate.c:493 catalog/pg_proc.c:246 catalog/pg_proc.c:253 +#: catalog/pg_aggregate.c:498 catalog/pg_proc.c:243 catalog/pg_proc.c:250 #, c-format msgid "cannot determine result data type" msgstr "无法确定结构数æ®ç±»åž‹" -#: catalog/pg_aggregate.c:494 +#: catalog/pg_aggregate.c:499 #, c-format -msgid "" -"An aggregate returning a polymorphic type must have at least one polymorphic " -"argument." +msgid "An aggregate returning a polymorphic type must have at least one polymorphic argument." msgstr "使用多æ€ç±»åž‹çš„èšåˆå‡½æ•°å¿…须至少有一个多æ€çš„傿•°" -#: catalog/pg_aggregate.c:506 catalog/pg_proc.c:259 +#: catalog/pg_aggregate.c:511 catalog/pg_proc.c:256 #, c-format msgid "unsafe use of pseudo-type \"internal\"" msgstr "使用伪类型\"internal\"的方å¼ä¸å®‰å…¨" -#: catalog/pg_aggregate.c:507 catalog/pg_proc.c:260 +#: catalog/pg_aggregate.c:512 catalog/pg_proc.c:257 #, c-format -msgid "" -"A function returning \"internal\" must have at least one \"internal\" " -"argument." +msgid "A function returning \"internal\" must have at least one \"internal\" argument." msgstr "返回\"internal\"类型结果的函数必须至少有一个\"internal\" ç±»åž‹çš„å‚æ•°" -#: catalog/pg_aggregate.c:560 +#: catalog/pg_aggregate.c:565 #, c-format -msgid "" -"moving-aggregate implementation returns type %s, but plain implementation " -"returns type %s" +msgid "moving-aggregate implementation returns type %s, but plain implementation returns type %s" msgstr "moving-aggregate的实现返回类型为%s, 但是普通的实现返回类型为%s" -#: catalog/pg_aggregate.c:571 +#: catalog/pg_aggregate.c:576 #, c-format msgid "sort operator can only be specified for single-argument aggregates" msgstr "åªèƒ½ä¸ºå•䏀傿•°çš„èšåˆå‡½æ•°è€Œå®šä¹‰æŽ’åºæ“作符." -#: catalog/pg_aggregate.c:816 commands/typecmds.c:1705 -#: commands/typecmds.c:1756 commands/typecmds.c:1787 commands/typecmds.c:1810 -#: commands/typecmds.c:1831 commands/typecmds.c:1858 commands/typecmds.c:1885 -#: commands/typecmds.c:1962 commands/typecmds.c:2004 parser/parse_func.c:364 -#: parser/parse_func.c:393 parser/parse_func.c:418 parser/parse_func.c:432 -#: parser/parse_func.c:507 parser/parse_func.c:518 parser/parse_func.c:1921 +#: catalog/pg_aggregate.c:703 catalog/pg_proc.c:396 +#, c-format +msgid "cannot change routine kind" +msgstr "无法改å˜å¸¸è§„ç§ç±»" + +#: catalog/pg_aggregate.c:705 +#, fuzzy, c-format +#| msgid "\"%s\" is an aggregate function." +msgid "\"%s\" is an ordinary aggregate function." +msgstr "\"%s\" 是一个èšåˆå‡½æ•°" + +#: catalog/pg_aggregate.c:707 +#, fuzzy, c-format +#| msgid "\"%s\" is an aggregate function." +msgid "\"%s\" is an ordered-set aggregate." +msgstr "\"%s\" 是一个èšåˆå‡½æ•°" + +#: catalog/pg_aggregate.c:709 +#, c-format +msgid "\"%s\" is a hypothetical-set aggregate." +msgstr "" + +#: catalog/pg_aggregate.c:714 +#, fuzzy, c-format +#| msgid "cannot change inheritance of a partition" +msgid "cannot change number of direct args of an aggregate function" +msgstr "无法更改分区的继承" + +#: catalog/pg_aggregate.c:869 commands/functioncmds.c:665 +#: commands/typecmds.c:1751 commands/typecmds.c:1802 commands/typecmds.c:1833 +#: commands/typecmds.c:1856 commands/typecmds.c:1877 commands/typecmds.c:1904 +#: commands/typecmds.c:1931 commands/typecmds.c:2008 commands/typecmds.c:2050 +#: parser/parse_func.c:418 parser/parse_func.c:447 parser/parse_func.c:472 +#: parser/parse_func.c:486 parser/parse_func.c:606 parser/parse_func.c:626 +#: parser/parse_func.c:2139 parser/parse_func.c:2330 #, c-format msgid "function %s does not exist" msgstr "函数 %s ä¸å­˜åœ¨" -#: catalog/pg_aggregate.c:822 +#: catalog/pg_aggregate.c:875 #, c-format msgid "function %s returns a set" msgstr "函数 %s 返回一个组åˆ" -#: catalog/pg_aggregate.c:837 +#: catalog/pg_aggregate.c:890 #, c-format msgid "function %s must accept VARIADIC ANY to be used in this aggregate" msgstr "函数%s必须接å—VARIADIC ANY类型,用于èšé›†å‡½æ•°ä¸­" -#: catalog/pg_aggregate.c:861 +#: catalog/pg_aggregate.c:914 #, c-format msgid "function %s requires run-time type coercion" msgstr "函数 %s 需è¦è¿è¡Œæ—¶ç±»åž‹å¼ºåˆ¶" -#: catalog/pg_collation.c:77 +#: catalog/pg_collation.c:93 catalog/pg_collation.c:140 #, c-format -msgid "collation \"%s\" for encoding \"%s\" already exists" -msgstr "ç¼–ç  \"%2$s\" 的排åºè§„则 \"%1$s\" å·²ç»å­˜åœ¨" +msgid "collation \"%s\" already exists, skipping" +msgstr "排åºè§„则 \"%s\" å·²ç»å­˜åœ¨, 跳过" + +#: catalog/pg_collation.c:95 +#, c-format +msgid "collation \"%s\" for encoding \"%s\" already exists, skipping" +msgstr "ç¼–ç \"%2$s\"的排åºè§„则\"%1$s\"å·²ç»å­˜åœ¨ï¼Œè·³è¿‡" -#: catalog/pg_collation.c:91 +#: catalog/pg_collation.c:103 catalog/pg_collation.c:147 #, c-format msgid "collation \"%s\" already exists" msgstr "排åºè§„则 \"%s\" å·²ç»å­˜åœ¨" -#: catalog/pg_constraint.c:663 +#: catalog/pg_collation.c:105 #, c-format -msgid "constraint \"%s\" for domain %s already exists" -msgstr "域 %2$s çš„çº¦æŸ \"%1$s\" å·²ç»å­˜åœ¨" +msgid "collation \"%s\" for encoding \"%s\" already exists" +msgstr "ç¼–ç  \"%2$s\" 的排åºè§„则 \"%1$s\" å·²ç»å­˜åœ¨" -#: catalog/pg_constraint.c:797 +#: catalog/pg_constraint.c:677 #, c-format -msgid "table \"%s\" has multiple constraints named \"%s\"" -msgstr "表 \"%s\" 有多个å为 \"%s\" 的约æŸ" +msgid "constraint \"%s\" for domain %s already exists" +msgstr "域 %2$s çš„çº¦æŸ \"%1$s\" å·²ç»å­˜åœ¨" -#: catalog/pg_constraint.c:809 +#: catalog/pg_constraint.c:875 catalog/pg_constraint.c:968 #, c-format msgid "constraint \"%s\" for table \"%s\" does not exist" msgstr "表 \"%2$s\" çš„ \"%1$s\" 约æŸä¸å­˜åœ¨" -#: catalog/pg_constraint.c:855 -#, c-format -msgid "domain \"%s\" has multiple constraints named \"%s\"" -msgstr "域 \"%s\" 有多个å为 \"%s\" 的约æŸ" - -#: catalog/pg_constraint.c:867 +#: catalog/pg_constraint.c:1057 #, c-format -msgid "constraint \"%s\" for domain \"%s\" does not exist" -msgstr "域 \"%2$s\" çš„ \"%1$s\" 约æŸä¸å­˜åœ¨" +msgid "constraint \"%s\" for domain %s does not exist" +msgstr "域 %2$s çš„ \"%1$s\" 约æŸä¸å­˜åœ¨" -#: catalog/pg_conversion.c:66 +#: catalog/pg_conversion.c:67 #, c-format msgid "conversion \"%s\" already exists" msgstr "ç¼–ç è½¬æ¢ \"%s\" å·²ç»å­˜åœ¨" -#: catalog/pg_conversion.c:79 +#: catalog/pg_conversion.c:80 #, c-format msgid "default conversion for %s to %s already exists" msgstr "默认的 %s 到 %s 的转æ¢å·²ç»å­˜åœ¨" -#: catalog/pg_depend.c:165 commands/extension.c:3028 +#: catalog/pg_depend.c:162 commands/extension.c:3229 #, c-format msgid "%s is already a member of extension \"%s\"" msgstr "\"%s\" å·²ç»æ˜¯æ‰©å±•\"%s\"çš„æˆå‘˜" -#: catalog/pg_depend.c:324 +#: catalog/pg_depend.c:489 #, c-format msgid "cannot remove dependency on %s because it is a system object" msgstr "无法删除在%s上的ä¾èµ–关系,因为它是一个系统对象" -#: catalog/pg_enum.c:115 catalog/pg_enum.c:202 +#: catalog/pg_enum.c:128 catalog/pg_enum.c:231 catalog/pg_enum.c:526 #, c-format msgid "invalid enum label \"%s\"" msgstr "无效的枚举类型标签 \"%s\"" -#: catalog/pg_enum.c:116 catalog/pg_enum.c:203 +#: catalog/pg_enum.c:129 catalog/pg_enum.c:232 catalog/pg_enum.c:527 #, c-format msgid "Labels must be %d characters or less." msgstr "标签必需为 %d 个字符或更少" -#: catalog/pg_enum.c:231 +#: catalog/pg_enum.c:260 #, c-format msgid "enum label \"%s\" already exists, skipping" msgstr "枚举标签 \"%s\" å·²ç»å­˜åœ¨, 跳过" -#: catalog/pg_enum.c:238 +#: catalog/pg_enum.c:267 catalog/pg_enum.c:570 #, c-format msgid "enum label \"%s\" already exists" msgstr "枚举标签 \"%s\" å·²ç»å­˜åœ¨" -#: catalog/pg_enum.c:293 +#: catalog/pg_enum.c:322 catalog/pg_enum.c:565 #, c-format msgid "\"%s\" is not an existing enum label" msgstr "枚举标签\"%s\" ä¸å­˜åœ¨" -#: catalog/pg_enum.c:349 +#: catalog/pg_enum.c:380 #, c-format msgid "pg_enum OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_enum OID值" -#: catalog/pg_enum.c:359 +#: catalog/pg_enum.c:390 #, c-format msgid "ALTER TYPE ADD BEFORE/AFTER is incompatible with binary upgrade" msgstr "ALTER TYPE ADD BEFORE/AFTER与二进制å‡çº§ä¸å…¼å®¹" -#: catalog/pg_namespace.c:61 commands/schemacmds.c:250 +#: catalog/pg_namespace.c:64 commands/schemacmds.c:266 #, c-format msgid "schema \"%s\" already exists" msgstr "æ¨¡å¼ \"%s\" å·²ç»å­˜åœ¨" -#: catalog/pg_operator.c:219 catalog/pg_operator.c:360 +#: catalog/pg_operator.c:219 catalog/pg_operator.c:361 #, c-format msgid "\"%s\" is not a valid operator name" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ“ä½œç¬¦åç§°" -#: catalog/pg_operator.c:369 +#: catalog/pg_operator.c:370 #, c-format msgid "only binary operators can have commutators" msgstr "åªæœ‰äºŒè¿›åˆ¶æ“ä½œç¬¦èƒ½æœ‰äº¤æ¢ (commutators)" -#: catalog/pg_operator.c:373 commands/operatorcmds.c:485 +#: catalog/pg_operator.c:374 commands/operatorcmds.c:485 #, c-format msgid "only binary operators can have join selectivity" msgstr "åªæœ‰äºŒè¿›åˆ¶æ“作符能有å¯é€‰æ‹©æ€§è”åˆ" -#: catalog/pg_operator.c:377 +#: catalog/pg_operator.c:378 #, c-format msgid "only binary operators can merge join" msgstr "åªæœ‰äºŒè¿›åˆ¶æ“作符å¯ä»¥åˆå¹¶è”åˆ" -#: catalog/pg_operator.c:381 +#: catalog/pg_operator.c:382 #, c-format msgid "only binary operators can hash" msgstr "åªæœ‰äºŒè¿›åˆ¶æ“作符å¯ä»¥æ•£åˆ—" -#: catalog/pg_operator.c:392 +#: catalog/pg_operator.c:393 #, c-format msgid "only boolean operators can have negators" msgstr "åªæœ‰å¸ƒå°”类型的æ“作符能够具有负å·." -#: catalog/pg_operator.c:396 commands/operatorcmds.c:493 +#: catalog/pg_operator.c:397 commands/operatorcmds.c:493 #, c-format msgid "only boolean operators can have restriction selectivity" msgstr "åªæœ‰å¸ƒå°”类型æ“作能够具有é™åˆ¶é€‰æ‹©æ€§" -#: catalog/pg_operator.c:400 commands/operatorcmds.c:497 +#: catalog/pg_operator.c:401 commands/operatorcmds.c:497 #, c-format msgid "only boolean operators can have join selectivity" msgstr "åªæœ‰å¸ƒå°”类型æ“作能够具有连接选择性" -#: catalog/pg_operator.c:404 +#: catalog/pg_operator.c:405 #, c-format msgid "only boolean operators can merge join" msgstr "åªæœ‰å¸ƒå°”类型æ“作符å¯ä»¥è¿›è¡Œåˆå¹¶è”åˆæ“作" -#: catalog/pg_operator.c:408 +#: catalog/pg_operator.c:409 #, c-format msgid "only boolean operators can hash" msgstr "åªæœ‰å¸ƒå°”æ“作符å¯ä»¥è¿›è¡Œæ•£åˆ—æ“作" -#: catalog/pg_operator.c:420 +#: catalog/pg_operator.c:421 #, c-format msgid "operator %s already exists" msgstr "æ“作符 %s å·²ç»å­˜åœ¨" -#: catalog/pg_operator.c:617 +#: catalog/pg_operator.c:621 #, c-format msgid "operator cannot be its own negator or sort operator" msgstr "æ“作符ä¸èƒ½å¦å®šè‡ªå·±æˆ–者排åºåˆ†ç±»æ“作符" -#: catalog/pg_proc.c:134 parser/parse_func.c:1945 parser/parse_func.c:1985 +#: catalog/pg_proc.c:131 parser/parse_func.c:2201 #, c-format msgid "functions cannot have more than %d argument" msgid_plural "functions cannot have more than %d arguments" msgstr[0] "å‡½æ•°çš„å‚æ•°ä¸èƒ½å¤šäºŽ%d个" -#: catalog/pg_proc.c:247 +#: catalog/pg_proc.c:244 #, c-format -msgid "" -"A function returning a polymorphic type must have at least one polymorphic " -"argument." +msgid "A function returning a polymorphic type must have at least one polymorphic argument." msgstr "返回一个多æ€ç±»åž‹çš„函数必须至少有一个多æ€å‚æ•°" -#: catalog/pg_proc.c:254 +#: catalog/pg_proc.c:251 #, c-format -msgid "" -"A function returning \"anyrange\" must have at least one \"anyrange\" " -"argument." +msgid "A function returning \"anyrange\" must have at least one \"anyrange\" argument." msgstr "返回\"anyrange\"类型结果的函数必须至少有一个\"anyrange\" ç±»åž‹çš„å‚æ•°" -#: catalog/pg_proc.c:272 -#, c-format -msgid "\"%s\" is already an attribute of type %s" -msgstr "\"%s\" å·²ç»æ˜¯ç±»åž‹ %s 的一个属性" - -#: catalog/pg_proc.c:403 +#: catalog/pg_proc.c:386 #, c-format msgid "function \"%s\" already exists with same argument types" msgstr "带相åŒå‚数类型的函数 \"%s\" å·²ç»å­˜åœ¨" -#: catalog/pg_proc.c:417 catalog/pg_proc.c:440 +#: catalog/pg_proc.c:398 +#, c-format +msgid "\"%s\" is an aggregate function." +msgstr "\"%s\" 是一个èšåˆå‡½æ•°" + +#: catalog/pg_proc.c:400 +#, c-format +msgid "\"%s\" is a function." +msgstr "\"%s\" 是一个函数" + +#: catalog/pg_proc.c:402 +#, c-format +msgid "\"%s\" is a procedure." +msgstr "\"%s\" 是一个程åº" + +#: catalog/pg_proc.c:404 +#, c-format +msgid "\"%s\" is a window function." +msgstr "\"%s\"是一个窗å£å‡½æ•°." + +#: catalog/pg_proc.c:424 +#, c-format +msgid "cannot change whether a procedure has output parameters" +msgstr "无法更改过程是å¦å…·æœ‰è¾“å‡ºå‚æ•°" + +#: catalog/pg_proc.c:425 catalog/pg_proc.c:455 #, c-format msgid "cannot change return type of existing function" msgstr "ä¸èƒ½æ”¹å˜å·²ç»å­˜åœ¨çš„函数的返回值类型" -#: catalog/pg_proc.c:418 catalog/pg_proc.c:442 catalog/pg_proc.c:485 -#: catalog/pg_proc.c:509 catalog/pg_proc.c:536 +#. translator: first %s is DROP FUNCTION, DROP PROCEDURE or DROP +#. AGGREGATE +#. +#. translator: first %s is DROP FUNCTION or DROP PROCEDURE +#: catalog/pg_proc.c:431 catalog/pg_proc.c:458 catalog/pg_proc.c:503 +#: catalog/pg_proc.c:529 catalog/pg_proc.c:557 #, c-format -msgid "Use DROP FUNCTION %s first." -msgstr "请先使用 DROP FUNCTION %s." +msgid "Use %s %s first." +msgstr "请先使用 %s %s." -#: catalog/pg_proc.c:441 +#: catalog/pg_proc.c:456 #, c-format msgid "Row type defined by OUT parameters is different." msgstr "ç”±OUT模å¼å‚数定义的记录类型ä¸åŒ" -#: catalog/pg_proc.c:483 +#: catalog/pg_proc.c:500 #, c-format msgid "cannot change name of input parameter \"%s\"" msgstr "无法改å˜è¾“入傿•°\"%s\"çš„åç§°" -#: catalog/pg_proc.c:508 +#: catalog/pg_proc.c:527 #, c-format msgid "cannot remove parameter defaults from existing function" msgstr "ä¸èƒ½ä»Žå·²å­˜åœ¨çš„函数ç§åˆ é™¤å‚数缺正值" -#: catalog/pg_proc.c:535 +#: catalog/pg_proc.c:555 #, c-format msgid "cannot change data type of existing parameter default value" msgstr "ä¸èƒ½æ”¹å˜å·²ç»å­˜åœ¨å‚数缺çœå€¼çš„æ•°æ®ç±»åž‹" -#: catalog/pg_proc.c:548 -#, c-format -msgid "function \"%s\" is an aggregate function" -msgstr "函数\"%s\" 是一个èšåˆå‡½æ•°" - -#: catalog/pg_proc.c:553 -#, c-format -msgid "function \"%s\" is not an aggregate function" -msgstr "函数 \"%s\" 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" - -#: catalog/pg_proc.c:561 -#, c-format -msgid "function \"%s\" is a window function" -msgstr "函数\"%s\"是一个窗å£å‡½æ•°" - -#: catalog/pg_proc.c:566 -#, c-format -msgid "function \"%s\" is not a window function" -msgstr "函数 \"%s\" 䏿˜¯ä¸€ä¸ªçª—å£å‡½æ•°" - -#: catalog/pg_proc.c:774 +#: catalog/pg_proc.c:772 #, c-format msgid "there is no built-in function named \"%s\"" msgstr "没有å为 \"%s\" 的内建函数" -#: catalog/pg_proc.c:872 +#: catalog/pg_proc.c:870 #, c-format msgid "SQL functions cannot return type %s" msgstr "SQL 函数无法返回 %s 类型" -#: catalog/pg_proc.c:887 +#: catalog/pg_proc.c:885 #, c-format msgid "SQL functions cannot have arguments of type %s" msgstr "SQL 函数ä¸èƒ½æœ‰ %s ç±»åž‹çš„å‚æ•°" -#: catalog/pg_proc.c:973 executor/functions.c:1424 +#: catalog/pg_proc.c:973 executor/functions.c:1423 #, c-format msgid "SQL function \"%s\"" msgstr "SQL 函数 \"%s\"" -#: catalog/pg_shdepend.c:694 +#: catalog/pg_publication.c:57 commands/trigger.c:238 commands/trigger.c:256 +#, c-format +msgid "\"%s\" is a partitioned table" +msgstr "\"%s\" 是一个分区表" + +#: catalog/pg_publication.c:59 +#, c-format +msgid "Adding partitioned tables to publications is not supported." +msgstr "䏿”¯æŒå°†åˆ†åŒºè¡¨æ·»åŠ åˆ°å‘布中." + +#: catalog/pg_publication.c:60 +#, c-format +msgid "You can add the table partitions individually." +msgstr "å¯ä»¥å•独添加表分区." + +#: catalog/pg_publication.c:68 +#, c-format +msgid "Only tables can be added to publications." +msgstr "åªæœ‰è¡¨å¯ä»¥æ·»åŠ åˆ°å‘布中." + +#: catalog/pg_publication.c:74 +#, c-format +msgid "\"%s\" is a system table" +msgstr "\"%s\" 是一个系统表" + +#: catalog/pg_publication.c:76 +#, c-format +msgid "System tables cannot be added to publications." +msgstr "无法将系统表添加到å‘布中." + +#: catalog/pg_publication.c:82 +#, c-format +msgid "table \"%s\" cannot be replicated" +msgstr "无法å¤åˆ¶è¡¨\"%s\"" + +#: catalog/pg_publication.c:84 +#, c-format +msgid "Temporary and unlogged relations cannot be replicated." +msgstr "无法å¤åˆ¶ä¸´æ—¶å…³ç³»å’ŒæœªåŠ è½½å…³ç³»." + +#: catalog/pg_publication.c:182 +#, c-format +msgid "relation \"%s\" is already member of publication \"%s\"" +msgstr "关系\"%s\"å·²ç»æ˜¯å‘布 \"%s\"çš„æˆå‘˜" + +#: catalog/pg_publication.c:418 catalog/pg_publication.c:440 +#: commands/publicationcmds.c:422 commands/publicationcmds.c:727 +#, c-format +msgid "publication \"%s\" does not exist" +msgstr "å‘布 \"%s\" ä¸å­˜åœ¨" + +#: catalog/pg_shdepend.c:777 #, c-format msgid "" "\n" @@ -5076,510 +5111,460 @@ msgstr[0] "" "\n" "对象在 %d 个其它数æ®åº“中" -#: catalog/pg_shdepend.c:1006 +#: catalog/pg_shdepend.c:1083 #, c-format msgid "role %u was concurrently dropped" msgstr "角色%uè¢«åŒæ—¶åˆ é™¤" -#: catalog/pg_shdepend.c:1025 +#: catalog/pg_shdepend.c:1102 #, c-format msgid "tablespace %u was concurrently dropped" msgstr "表空间 %u è¢«åŒæ—¶åˆ é™¤" -#: catalog/pg_shdepend.c:1040 +#: catalog/pg_shdepend.c:1117 #, c-format msgid "database %u was concurrently dropped" msgstr "æ•°æ®åº“ %u è¢«åŒæ—¶åˆ é™¤" -#: catalog/pg_shdepend.c:1085 +#: catalog/pg_shdepend.c:1162 #, c-format msgid "owner of %s" msgstr "%s的属主" -#: catalog/pg_shdepend.c:1087 +#: catalog/pg_shdepend.c:1164 #, c-format msgid "privileges for %s" msgstr "%sçš„æƒé™" -#: catalog/pg_shdepend.c:1089 +#: catalog/pg_shdepend.c:1166 #, c-format msgid "target of %s" msgstr "%s的目标" #. translator: %s will always be "database %s" -#: catalog/pg_shdepend.c:1097 +#: catalog/pg_shdepend.c:1174 #, c-format msgid "%d object in %s" msgid_plural "%d objects in %s" msgstr[0] "在%2$s中的%1$d个对象" -#: catalog/pg_shdepend.c:1208 +#: catalog/pg_shdepend.c:1285 #, c-format -msgid "" -"cannot drop objects owned by %s because they are required by the database " -"system" +msgid "cannot drop objects owned by %s because they are required by the database system" msgstr "无法删除由%s所拥有的对象, 因为数æ®åº“系统需è¦è¿™äº›å¯¹è±¡" -#: catalog/pg_shdepend.c:1323 +#: catalog/pg_shdepend.c:1408 #, c-format -msgid "" -"cannot reassign ownership of objects owned by %s because they are required " -"by the database system" +msgid "cannot reassign ownership of objects owned by %s because they are required by the database system" msgstr "无法å†åˆ†é…ç”±%s所拥有的对象, 因为数æ®åº“系统需è¦è¿™äº›å¯¹è±¡" -#: catalog/pg_type.c:136 catalog/pg_type.c:454 +#: catalog/pg_subscription.c:177 commands/subscriptioncmds.c:648 +#: commands/subscriptioncmds.c:862 commands/subscriptioncmds.c:1089 +#, c-format +msgid "subscription \"%s\" does not exist" +msgstr "订阅\"%s\"ä¸å­˜åœ¨" + +#: catalog/pg_type.c:131 catalog/pg_type.c:467 #, c-format msgid "pg_type OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_type OID值" -#: catalog/pg_type.c:253 +#: catalog/pg_type.c:249 #, c-format msgid "invalid type internal size %d" msgstr "æ— æ•ˆç±»åž‹å†…éƒ¨å¤§å° %d" -#: catalog/pg_type.c:269 catalog/pg_type.c:277 catalog/pg_type.c:285 -#: catalog/pg_type.c:294 +#: catalog/pg_type.c:265 catalog/pg_type.c:273 catalog/pg_type.c:281 +#: catalog/pg_type.c:290 #, c-format msgid "alignment \"%c\" is invalid for passed-by-value type of size %d" msgstr "坹齿–¹å¼ \"%c\"对于大å°ä¸º%dçš„passed-by-value 类型是无效的" -#: catalog/pg_type.c:301 +#: catalog/pg_type.c:297 #, c-format msgid "internal size %d is invalid for passed-by-value type" msgstr "internal å¤§å° %d 对于 passed-by-value 类型是无效的" -#: catalog/pg_type.c:310 catalog/pg_type.c:316 +#: catalog/pg_type.c:306 catalog/pg_type.c:312 #, c-format msgid "alignment \"%c\" is invalid for variable-length type" msgstr "坹齿–¹å¼ \"%c\"对于大å°ä¸ºå¯å˜é•¿åº¦çš„类型是无效的" -#: catalog/pg_type.c:324 +#: catalog/pg_type.c:320 #, c-format msgid "fixed-size types must have storage PLAIN" msgstr "固定大å°ç±»åž‹å¿…需有明确的存储" -#: catalog/pg_type.c:789 +#: catalog/pg_type.c:818 #, c-format msgid "could not form array type name for type \"%s\"" msgstr "无法为类型\"%s\"æ¥å½¢æˆæ•°ç»„类型åç§°" -#: catalog/toasting.c:105 commands/indexcmds.c:389 commands/tablecmds.c:4360 -#: commands/tablecmds.c:11902 +#: catalog/storage.c:344 storage/buffer/bufmgr.c:922 #, c-format -msgid "\"%s\" is not a table or materialized view" -msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨æˆ–物化视图" +msgid "invalid page in block %u of relation %s" +msgstr "关系 \"%2$s\" ä¸­çš„å— %1$u 存在无效的页" -#: catalog/toasting.c:158 +#: catalog/toasting.c:106 commands/indexcmds.c:585 commands/tablecmds.c:5154 +#: commands/tablecmds.c:14640 #, c-format -msgid "shared tables cannot be toasted after initdb" -msgstr "在 initdb 之åŽ, ä¸å¯ä»¥ toasted 共享表" +msgid "\"%s\" is not a table or materialized view" +msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨æˆ–物化视图" -#: commands/aggregatecmds.c:161 +#: commands/aggregatecmds.c:171 #, c-format msgid "only ordered-set aggregates can be hypothetical" msgstr "åªæœ‰æœ‰åºé›†èšç„¦å‡½æ•°å¯ç”¨è¢«ç”¨äºŽåˆ¤å®š" -#: commands/aggregatecmds.c:188 +#: commands/aggregatecmds.c:196 #, c-format msgid "aggregate attribute \"%s\" not recognized" msgstr "èšé›†å±žæ€§ \"%s\" ä¸è¢«è®¤å¯" -#: commands/aggregatecmds.c:198 +#: commands/aggregatecmds.c:206 #, c-format msgid "aggregate stype must be specified" msgstr "èšé›† stype 必须指定" -#: commands/aggregatecmds.c:202 +#: commands/aggregatecmds.c:210 #, c-format msgid "aggregate sfunc must be specified" msgstr "èšé›† sfunc 必须指定" -#: commands/aggregatecmds.c:214 +#: commands/aggregatecmds.c:222 #, c-format msgid "aggregate msfunc must be specified when mstype is specified" msgstr "当mstype指定了的时候, èšé›† sfunc 必须指定" -#: commands/aggregatecmds.c:218 +#: commands/aggregatecmds.c:226 #, c-format msgid "aggregate minvfunc must be specified when mstype is specified" msgstr "当mstype指定了的时候, èšé›† minvfunc 必须指定" -#: commands/aggregatecmds.c:225 +#: commands/aggregatecmds.c:233 #, c-format msgid "aggregate msfunc must not be specified without mstype" msgstr "当mstype没被指定时, èšé›† msfunc 也ä¸èƒ½æŒ‡å®š" -#: commands/aggregatecmds.c:229 +#: commands/aggregatecmds.c:237 #, c-format msgid "aggregate minvfunc must not be specified without mstype" msgstr "没有mstype, å°±ä¸èƒ½æŒ‡å®šèšé›†minvfunc" -#: commands/aggregatecmds.c:233 +#: commands/aggregatecmds.c:241 #, c-format msgid "aggregate mfinalfunc must not be specified without mstype" msgstr "没有mstype, å°±ä¸èƒ½æŒ‡å®šèšé›† mfinalfunc" -#: commands/aggregatecmds.c:237 +#: commands/aggregatecmds.c:245 #, c-format msgid "aggregate msspace must not be specified without mstype" msgstr "没有指定mstype,就ä¸èƒ½æŒ‡å®šèšé›†msspace" -#: commands/aggregatecmds.c:241 +#: commands/aggregatecmds.c:249 #, c-format msgid "aggregate minitcond must not be specified without mstype" msgstr "没有指定mstype,就ä¸èƒ½æŒ‡å®šminitcond" -#: commands/aggregatecmds.c:261 +#: commands/aggregatecmds.c:278 #, c-format msgid "aggregate input type must be specified" msgstr "必须指定èšåˆå‡½æ•°çš„è¾“å…¥å‚æ•°ç±»åž‹" -#: commands/aggregatecmds.c:291 +#: commands/aggregatecmds.c:308 #, c-format msgid "basetype is redundant with aggregate input type specification" msgstr "如果带有èšåˆå‡½æ•°è¾“入类型定义,那么基类型定义就是冗余的." -#: commands/aggregatecmds.c:332 commands/aggregatecmds.c:421 +#: commands/aggregatecmds.c:349 commands/aggregatecmds.c:390 #, c-format msgid "aggregate transition data type cannot be %s" msgstr "èšé›†è½¬æ¢æ•°æ®ç±»åž‹ä¸èƒ½ä¸º %s" -#: commands/aggregatecmds.c:347 -#, c-format -msgid "" -"a serialization type must only be specified when the aggregate transition " -"data type is \"%s\"" -msgstr "åªæœ‰å½“èšé›†è½¬ç§»æ•°æ®ç±»åž‹æ˜¯ \"%s\" 时,æ‰å¿…须指定一个åºåˆ—化类型" - -#: commands/aggregatecmds.c:356 -#, c-format -#| msgid "aggregate transition data type cannot be %s" -msgid "aggregate serialization data type cannot be %s" -msgstr "èšé›†åºåˆ—化数æ®ç±»åž‹ä¸èƒ½æ˜¯ %s" - -#: commands/aggregatecmds.c:369 +#: commands/aggregatecmds.c:361 #, c-format -#| msgid "aggregate transition data type cannot be %s" -msgid "aggregate serialization type cannot be \"%s\"" -msgstr "èšé›†åºåˆ—化类型ä¸èƒ½æ˜¯ %s" +msgid "serialization functions may be specified only when the aggregate transition data type is %s" +msgstr "åªæœ‰å½“èšé›†è½¬ç§»æ•°æ®ç±»åž‹æ˜¯%s时,æ‰èƒ½æŒ‡å®šåºåˆ—化函数" -#: commands/aggregatecmds.c:380 +#: commands/aggregatecmds.c:371 #, c-format -#| msgid "aggregate minvfunc must be specified when mstype is specified" -msgid "" -"aggregate serialization function must be specified when serialization type " -"is specified" -msgstr "当åºåˆ—化类型被指定时必须指定èšé›†åºåˆ—化函数" - -#: commands/aggregatecmds.c:385 -#, c-format -#| msgid "aggregate minvfunc must be specified when mstype is specified" -msgid "" -"aggregate deserialization function must be specified when serialization type " -"is specified" -msgstr "当åºåˆ—化类型被指定时必须指定èšé›†ååºåˆ—化函数" - -#: commands/aggregatecmds.c:396 -#, c-format -msgid "must specify serialization type when specifying serialization function" -msgstr "在指定åºåˆ—化函数时必须指定åºåˆ—化类型" - -#: commands/aggregatecmds.c:402 -#, c-format -msgid "" -"must specify serialization type when specifying deserialization function" -msgstr "在指定ååºåˆ—化函数时必须指定åºåˆ—化类型" +msgid "must specify both or neither of serialization and deserialization functions" +msgstr "å¿…é¡»åŒæ—¶æŒ‡å®šåºåˆ—化和ååºåˆ—åŒ–å‡½æ•°æˆ–ä¸¤è€…éƒ½ä¸æŒ‡å®š" -#: commands/aggregatecmds.c:467 commands/functioncmds.c:570 +#: commands/aggregatecmds.c:436 commands/functioncmds.c:613 #, c-format msgid "parameter \"parallel\" must be SAFE, RESTRICTED, or UNSAFE" msgstr "傿•° \"parallel\" 必须为 SAFEã€RESTRICTED 或者 UNSAFE" -#: commands/alter.c:80 commands/event_trigger.c:231 +#: commands/aggregatecmds.c:492 +#, c-format +msgid "parameter \"%s\" must be READ_ONLY, SHAREABLE, or READ_WRITE" +msgstr "傿•°\"%s\"必须为READ_ONLYã€SHAREABLE或READ_WRITE" + +#: commands/alter.c:85 commands/event_trigger.c:237 #, c-format msgid "event trigger \"%s\" already exists" msgstr "事件触å‘器 \"%s\" å·²ç»å­˜åœ¨" -#: commands/alter.c:83 commands/foreigncmds.c:597 +#: commands/alter.c:88 commands/foreigncmds.c:601 #, c-format msgid "foreign-data wrapper \"%s\" already exists" msgstr "外部数æ®å°è£…器\"%s\"å·²ç»å­˜åœ¨" -#: commands/alter.c:86 commands/foreigncmds.c:890 +#: commands/alter.c:91 commands/foreigncmds.c:907 #, c-format msgid "server \"%s\" already exists" msgstr "æœåС噍 \"%s\" å·²ç»å­˜åœ¨" -#: commands/alter.c:89 commands/proclang.c:366 +#: commands/alter.c:94 commands/proclang.c:368 #, c-format msgid "language \"%s\" already exists" msgstr "语言 \"%s\" å·²ç»å­˜åœ¨" -#: commands/alter.c:112 +#: commands/alter.c:97 commands/publicationcmds.c:176 +#, c-format +msgid "publication \"%s\" already exists" +msgstr "å‘布 \"%s\" å·²ç»å­˜åœ¨" + +#: commands/alter.c:100 commands/subscriptioncmds.c:369 +#, c-format +msgid "subscription \"%s\" already exists" +msgstr "订阅 \"%s\" å·²ç»å­˜åœ¨" + +#: commands/alter.c:123 #, c-format msgid "conversion \"%s\" already exists in schema \"%s\"" msgstr "çº¦æŸ \"%s\" å·²ç»å­˜åœ¨äºŽæ¨¡å¼ \"%s\" 中" -#: commands/alter.c:116 +#: commands/alter.c:127 +#, c-format +msgid "statistics object \"%s\" already exists in schema \"%s\"" +msgstr "在模å¼\"%2$s\"中已ç»å­˜åœ¨ç»Ÿè®¡ä¿¡æ¯å¯¹è±¡\"%1$s\"" + +#: commands/alter.c:131 #, c-format msgid "text search parser \"%s\" already exists in schema \"%s\"" msgstr "文本æœç´¢è§£æžå™¨\"%s\"已存在于方案\"%s\"中" -#: commands/alter.c:120 +#: commands/alter.c:135 #, c-format msgid "text search dictionary \"%s\" already exists in schema \"%s\"" msgstr "文本æœç´¢å­—å…¸\"%s\" å·²ç»å­˜åœ¨äºŽæ–¹æ¡ˆ\"%s\"中" -#: commands/alter.c:124 +#: commands/alter.c:139 #, c-format msgid "text search template \"%s\" already exists in schema \"%s\"" msgstr "文本æœç´¢æ¨¡æ¿\"%s\" å·²ç»å­˜åœ¨äºŽæ–¹æ¡ˆ\"%s\"中" -#: commands/alter.c:128 +#: commands/alter.c:143 #, c-format msgid "text search configuration \"%s\" already exists in schema \"%s\"" msgstr "文本æœç´¢é…ç½®\"%s\"已存在于方案\"%s\"中" -#: commands/alter.c:202 +#: commands/alter.c:217 #, c-format msgid "must be superuser to rename %s" msgstr "必须为超级用户æ‰èƒ½è¿›è¡Œé‡å‘½å\"%s\" " -#: commands/alter.c:656 +#: commands/alter.c:714 #, c-format msgid "must be superuser to set schema of %s" msgstr "åªæœ‰è¶…级用户能设置%s的模å¼" -#: commands/amcmds.c:58 +#: commands/amcmds.c:59 #, c-format -#| msgid "permission denied to create tablespace \"%s\"" msgid "permission denied to create access method \"%s\"" msgstr "æƒé™ä¸å…许创建访问方法 \"%s\"" -#: commands/amcmds.c:60 +#: commands/amcmds.c:61 #, c-format -#| msgid "Must be superuser to create a tablespace." msgid "Must be superuser to create an access method." msgstr "åªæœ‰è¶…级用户能创建访问方法。" -#: commands/amcmds.c:68 +#: commands/amcmds.c:70 #, c-format -#| msgid "access method \"%s\" does not exist" msgid "access method \"%s\" already exists" msgstr "访问方法 \"%s\" 已存在" -#: commands/amcmds.c:124 +#: commands/amcmds.c:127 #, c-format -#| msgid "must be superuser to drop superusers" msgid "must be superuser to drop access methods" msgstr "åªæœ‰è¶…级用户å¯ä»¥åˆ é™¤è®¿é—®æ–¹æ³•" -#: commands/amcmds.c:175 commands/indexcmds.c:164 commands/indexcmds.c:495 -#: commands/opclasscmds.c:365 commands/opclasscmds.c:790 +#: commands/amcmds.c:178 commands/indexcmds.c:187 commands/indexcmds.c:730 +#: commands/opclasscmds.c:372 commands/opclasscmds.c:791 #, c-format msgid "access method \"%s\" does not exist" msgstr "è®¿é—®æ–¹å¼ \"%s\" ä¸å­˜åœ¨" -#: commands/amcmds.c:251 +#: commands/amcmds.c:267 #, c-format -#| msgid "no function body specified" msgid "handler function is not specified" msgstr "没有指定处ç†å™¨å‡½æ•°" -#: commands/amcmds.c:263 commands/event_trigger.c:240 -#: commands/foreigncmds.c:489 commands/proclang.c:117 commands/proclang.c:288 -#: commands/trigger.c:441 parser/parse_clause.c:761 +#: commands/amcmds.c:288 commands/event_trigger.c:246 +#: commands/foreigncmds.c:493 commands/proclang.c:115 commands/proclang.c:287 +#: commands/trigger.c:719 parser/parse_clause.c:950 #, c-format -#| msgid "function %s should return type %s" msgid "function %s must return type %s" msgstr "函数 %s 必须返回类型 %s" -#: commands/analyze.c:145 -#, c-format -msgid "skipping analyze of \"%s\" --- lock not available" -msgstr "跳过对 \"%s\"çš„åˆ†æž --- 锿— æ³•得到" - -#: commands/analyze.c:162 -#, c-format -msgid "skipping \"%s\" --- only superuser can analyze it" -msgstr "忽略 \"%s\" --- åªæœ‰è¶…级用户能够分æžå®ƒ" - -#: commands/analyze.c:166 -#, c-format -msgid "skipping \"%s\" --- only superuser or database owner can analyze it" -msgstr "忽略 \"%s\" --- åªæœ‰è¶…级用户或数æ®åº“的属主能够分æžå®ƒ" - -#: commands/analyze.c:170 -#, c-format -msgid "skipping \"%s\" --- only table or database owner can analyze it" -msgstr "忽略 \"%s\" --- åªæœ‰è¡¨æˆ–æ•°æ®åº“的属主能够分æžå®ƒ" - -#: commands/analyze.c:230 +#: commands/analyze.c:225 #, c-format msgid "skipping \"%s\" --- cannot analyze this foreign table" msgstr "忽略 \"%s\" --- 无法分æžè¯¥å¤–部表" -#: commands/analyze.c:241 +#: commands/analyze.c:242 #, c-format msgid "skipping \"%s\" --- cannot analyze non-tables or special system tables" msgstr "忽略 \"%s\" --- 无法分æžéžè¡¨æˆ–特殊的系统表" -#: commands/analyze.c:320 +#: commands/analyze.c:323 #, c-format msgid "analyzing \"%s.%s\" inheritance tree" msgstr "æ­£åœ¨åˆ†æž \"%s.%s\"继承树" -#: commands/analyze.c:325 +#: commands/analyze.c:328 #, c-format msgid "analyzing \"%s.%s\"" msgstr "æ­£åœ¨åˆ†æž \"%s.%s\"" -#: commands/analyze.c:651 +#: commands/analyze.c:388 +#, c-format +msgid "column \"%s\" of relation \"%s\" appears more than once" +msgstr "关系 \"%2$s\" çš„ \"%1$s\" 字段出现多次" + +#: commands/analyze.c:668 #, c-format msgid "automatic analyze of table \"%s.%s.%s\" system usage: %s" msgstr "自动分æžè¡¨ \"%s.%s.%s\"的系统使用情况: %s" -#: commands/analyze.c:1207 +#: commands/analyze.c:1127 #, c-format -msgid "" -"\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead " -"rows; %d rows in sample, %.0f estimated total rows" -msgstr "" -"\"%1$s\": å·²ç»æ‰«æäº†%3$u页的%2$d, 包å«%4$.0få¯ç”¨çš„记录和%5$.0fä¸èƒ½ç”¨çš„记录; " -"在示例中有%6$dæ¡è®°å½•,估算所有记录为%7$.0f ." +msgid "\"%s\": scanned %d of %u pages, containing %.0f live rows and %.0f dead rows; %d rows in sample, %.0f estimated total rows" +msgstr "\"%1$s\": å·²ç»æ‰«æäº†%3$u页的%2$d, 包å«%4$.0få¯ç”¨çš„记录和%5$.0fä¸èƒ½ç”¨çš„记录; 在示例中有%6$dæ¡è®°å½•,估算所有记录为%7$.0f ." -#: commands/analyze.c:1286 +#: commands/analyze.c:1207 #, c-format -msgid "" -"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " -"contains no child tables" +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no child tables" msgstr "跳过\"%s.%s\"ç»§æ‰¿æ ‘çš„åˆ†æž --- 这个继承树ä¸åŒ…å«å­è¡¨" -#: commands/analyze.c:1375 +#: commands/analyze.c:1305 #, c-format -msgid "" -"skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree " -"contains no analyzable child tables" +msgid "skipping analyze of \"%s.%s\" inheritance tree --- this inheritance tree contains no analyzable child tables" msgstr "跳过\"%s.%s\"ç»§æ‰¿æ ‘çš„åˆ†æž --- 这个继承树包å«ä¸å¯åˆ†æžçš„å­è¡¨" -#: commands/analyze.c:1423 executor/execQual.c:2922 -msgid "could not convert row type" -msgstr "无法转æ¢è®°å½•类型" - -#: commands/async.c:558 +#: commands/async.c:557 #, c-format msgid "channel name cannot be empty" msgstr "通é“åç§°ä¸èƒ½ä¸ºç©º" -#: commands/async.c:563 +#: commands/async.c:562 #, c-format msgid "channel name too long" msgstr "通é“å称太长" -#: commands/async.c:570 +#: commands/async.c:569 #, c-format msgid "payload string too long" msgstr "æµé‡è´Ÿè½½å­—符串太长" -#: commands/async.c:756 +#: commands/async.c:755 #, c-format -msgid "" -"cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" +msgid "cannot PREPARE a transaction that has executed LISTEN, UNLISTEN, or NOTIFY" msgstr "æ— æ³•åœ¨ä¸€ä¸ªå·²ç»æ‰§è¡Œäº†LISTEN或UNLISTENã€NOTIFYæ“作的事务上执行PREPARE" -#: commands/async.c:859 +#: commands/async.c:858 #, c-format msgid "too many notifications in the NOTIFY queue" msgstr "在NOTIFY队列中的通知太多了" -#: commands/async.c:1489 +#: commands/async.c:1490 #, c-format msgid "NOTIFY queue is %.0f%% full" msgstr "NOTIFY队列达到了%.0f%%的容é‡" -#: commands/async.c:1491 +#: commands/async.c:1492 #, c-format -msgid "" -"The server process with PID %d is among those with the oldest transactions." +msgid "The server process with PID %d is among those with the oldest transactions." msgstr "带有PID为%dçš„æœåŠ¡å™¨è¿›ç¨‹åœ¨é‚£äº›å¸¦æœ‰æœ€è€äº‹åŠ¡çš„è¿›ç¨‹ä¸­ã€‚" -#: commands/async.c:1494 +#: commands/async.c:1495 #, c-format -msgid "" -"The NOTIFY queue cannot be emptied until that process ends its current " -"transaction." +msgid "The NOTIFY queue cannot be emptied until that process ends its current transaction." msgstr "在进程结æŸå®ƒæ‰€å¤„ç†çš„当å‰äº‹åŠ¡å‰, NOTIFY队列ä¸èƒ½ä¸ºç©º." -#: commands/cluster.c:129 commands/cluster.c:366 +#: commands/cluster.c:126 commands/cluster.c:388 #, c-format msgid "cannot cluster temporary tables of other sessions" msgstr "无法为其它会è¯çš„临时表建簇" -#: commands/cluster.c:159 +#: commands/cluster.c:134 +#, c-format +msgid "cannot cluster a partitioned table" +msgstr "无法对分区表进行群集" + +#: commands/cluster.c:164 #, c-format msgid "there is no previously clustered index for table \"%s\"" msgstr "在表 \"%s\" 中未找到先å‰å»ºç°‡çš„索引" -#: commands/cluster.c:173 commands/tablecmds.c:9288 commands/tablecmds.c:11004 +#: commands/cluster.c:178 commands/tablecmds.c:11906 commands/tablecmds.c:13708 #, c-format msgid "index \"%s\" for table \"%s\" does not exist" msgstr "表 \"%2$s\" çš„ \"%1$s\" 索引ä¸å­˜åœ¨" -#: commands/cluster.c:355 +#: commands/cluster.c:377 #, c-format msgid "cannot cluster a shared catalog" msgstr "无法在共享目录视图上进行èšç°‡æ“作" -#: commands/cluster.c:370 +#: commands/cluster.c:392 #, c-format msgid "cannot vacuum temporary tables of other sessions" msgstr "无法对其它会è¯çš„ä¸´æ—¶è¡¨è¿›è¡Œæ¸…ç†æ“作" -#: commands/cluster.c:433 commands/tablecmds.c:11014 +#: commands/cluster.c:458 commands/tablecmds.c:13718 #, c-format msgid "\"%s\" is not an index for table \"%s\"" msgstr "对于表 \"%2$s\" \"%1$s\" 䏿˜¯ä¸€ä¸ªç´¢å¼•" -#: commands/cluster.c:441 +#: commands/cluster.c:466 #, c-format -msgid "" -"cannot cluster on index \"%s\" because access method does not support " -"clustering" +msgid "cannot cluster on index \"%s\" because access method does not support clustering" msgstr "无法在索引\"%s\"进行èšç°‡æ“ä½œï¼Œå› ä¸ºè®¿é—®æ–¹æ³•ä¸æ”¯æŒè¿›è¡Œèšç°‡æ“作" -#: commands/cluster.c:453 +#: commands/cluster.c:478 #, c-format msgid "cannot cluster on partial index \"%s\"" msgstr "无法在部分索引 \"%s\"上进行èšç°‡æ“作" -#: commands/cluster.c:467 +#: commands/cluster.c:492 #, c-format msgid "cannot cluster on invalid index \"%s\"" msgstr "无法在无效索引\"%s\"进行èšç°‡æ“作" -#: commands/cluster.c:920 +#: commands/cluster.c:516 +#, c-format +msgid "cannot mark index clustered in partitioned table" +msgstr "无法在分区表中标记èšé›†ç´¢å¼•" + +#: commands/cluster.c:899 #, c-format msgid "clustering \"%s.%s\" using index scan on \"%s\"" msgstr "ç°‡ \"%s.%s\" 正在 \"%s\"进行索引扫æ" -#: commands/cluster.c:926 +#: commands/cluster.c:905 #, c-format msgid "clustering \"%s.%s\" using sequential scan and sort" msgstr "ç°‡ \"%s.%s\"æ­£åœ¨è¿›è¡Œé¡ºåºæ‰«æå’ŒæŽ’åº" -#: commands/cluster.c:931 commands/vacuumlazy.c:476 -#, c-format -msgid "vacuuming \"%s.%s\"" -msgstr "æ­£åœ¨æ¸…ç† (vacuum) \"%s.%s\"" - -#: commands/cluster.c:1090 +#: commands/cluster.c:936 #, c-format -msgid "" -"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" -msgstr "" -"\"%1$s\": 在%4$u个页中找到%2$.0f个å¯åˆ é™¤è¡Œç‰ˆæœ¬ï¼Œ%3$.0fä¸å¯åˆ é™¤çš„行版本." +msgid "\"%s\": found %.0f removable, %.0f nonremovable row versions in %u pages" +msgstr "\"%1$s\": 在%4$u个页中找到%2$.0f个å¯åˆ é™¤è¡Œç‰ˆæœ¬ï¼Œ%3$.0fä¸å¯åˆ é™¤çš„行版本." -#: commands/cluster.c:1094 +#: commands/cluster.c:940 #, c-format msgid "" "%.0f dead row versions cannot be removed yet.\n" @@ -5588,860 +5573,893 @@ msgstr "" "%.0f 死行版本å·ä»ä¸èƒ½ç§»é™¤.\n" "%s." -#: commands/collationcmds.c:80 +#: commands/collationcmds.c:104 #, c-format msgid "collation attribute \"%s\" not recognized" msgstr "无法识别排åºè§„则属性 \"%s\"" -#: commands/collationcmds.c:125 +#: commands/collationcmds.c:147 +#, c-format +msgid "collation \"default\" cannot be copied" +msgstr "无法å¤åˆ¶æŽ’åºè§„则\"default\"" + +#: commands/collationcmds.c:180 +#, c-format +msgid "unrecognized collation provider: %s" +msgstr "无法识别的排åºè§„则æä¾›ç¨‹åº: %s" + +#: commands/collationcmds.c:189 #, c-format msgid "parameter \"lc_collate\" must be specified" msgstr "傿•°\"lc_collate\" 必须指定" -#: commands/collationcmds.c:130 +#: commands/collationcmds.c:194 #, c-format msgid "parameter \"lc_ctype\" must be specified" msgstr "傿•°\"lc_ctype\"必须指定" -#: commands/collationcmds.c:166 +# fe-auth.c:640 +#: commands/collationcmds.c:204 +#, fuzzy, c-format +#| msgid "peer authentication is not supported on this platform" +msgid "nondeterministic collations not supported with this provider" +msgstr "对等认è¯åœ¨è¿™ä¸ªå¹³å°ä¸Šä¸æ”¯æŒ" + +#: commands/collationcmds.c:264 #, c-format msgid "collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"" msgstr "在模å¼\"%3$s\"中已ç»å­˜åœ¨å¯¹åº”于编ç \"%2$s\"的排åºè§„则\"%1$s\"" -#: commands/collationcmds.c:177 +#: commands/collationcmds.c:275 #, c-format msgid "collation \"%s\" already exists in schema \"%s\"" msgstr "在模å¼\"%2$s\"中已ç»å­˜åœ¨æŽ’åºè§„则\"%1$s\"" -#: commands/comment.c:62 commands/dbcommands.c:797 commands/dbcommands.c:962 -#: commands/dbcommands.c:1067 commands/dbcommands.c:1257 -#: commands/dbcommands.c:1477 commands/dbcommands.c:1594 -#: commands/dbcommands.c:2011 utils/init/postinit.c:842 -#: utils/init/postinit.c:944 utils/init/postinit.c:961 +#: commands/collationcmds.c:323 +#, c-format +msgid "changing version from %s to %s" +msgstr "将版本从%s更改为%s" + +#: commands/collationcmds.c:338 +#, c-format +msgid "version has not changed" +msgstr "版本未更改" + +#: commands/collationcmds.c:469 +#, c-format +msgid "could not convert locale name \"%s\" to language tag: %s" +msgstr "无法将区域设置åç§°\"%s\"转æ¢ä¸ºè¯­è¨€æ ‡è®°: %s" + +#: commands/collationcmds.c:530 +#, c-format +msgid "must be superuser to import system collations" +msgstr "必须是超级用户æ‰èƒ½å¯¼å…¥ç³»ç»ŸæŽ’åºè§„则" + +#: commands/collationcmds.c:553 commands/copy.c:1899 commands/copy.c:3529 +#: libpq/be-secure-common.c:80 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "无法执行命令 \"%s\": %m" + +# describe.c:1542 +#: commands/collationcmds.c:684 +#, c-format +msgid "no usable system locales were found" +msgstr "没有找到å¯ç”¨çš„系统本地化åç§°" + +#: commands/comment.c:61 commands/dbcommands.c:810 commands/dbcommands.c:998 +#: commands/dbcommands.c:1102 commands/dbcommands.c:1292 +#: commands/dbcommands.c:1515 commands/dbcommands.c:1629 +#: commands/dbcommands.c:2046 utils/init/postinit.c:890 +#: utils/init/postinit.c:995 utils/init/postinit.c:1012 #, c-format msgid "database \"%s\" does not exist" msgstr "æ•°æ®åº“ \"%s\" ä¸å­˜åœ¨" -#: commands/comment.c:101 commands/seclabel.c:116 parser/parse_utilcmd.c:768 +#: commands/comment.c:101 commands/seclabel.c:117 parser/parse_utilcmd.c:944 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, composite type, or foreign " -"table" +msgid "\"%s\" is not a table, view, materialized view, composite type, or foreign table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨,物化视图,组åˆç±»åž‹æˆ–者外部表" -#: commands/constraint.c:60 utils/adt/ri_triggers.c:2717 +#: commands/constraint.c:63 utils/adt/ri_triggers.c:1915 #, c-format msgid "function \"%s\" was not called by trigger manager" msgstr "函数 \"%s\" 没有被触å‘器管ç†å™¨è°ƒç”¨" -#: commands/constraint.c:67 utils/adt/ri_triggers.c:2726 +#: commands/constraint.c:70 utils/adt/ri_triggers.c:1924 #, c-format msgid "function \"%s\" must be fired AFTER ROW" msgstr "函数 \"%s\"必须为AFTER ROW触å‘" -#: commands/constraint.c:81 +#: commands/constraint.c:84 #, c-format msgid "function \"%s\" must be fired for INSERT or UPDATE" msgstr "函数 \"%s\"必须为INSERT或UPDATEæ“作触å‘" -#: commands/conversioncmds.c:67 +#: commands/conversioncmds.c:65 #, c-format msgid "source encoding \"%s\" does not exist" msgstr "æºç¼–ç  \"%s\" ä¸å­˜åœ¨" -#: commands/conversioncmds.c:74 +#: commands/conversioncmds.c:72 #, c-format msgid "destination encoding \"%s\" does not exist" msgstr "ç›®æ ‡ç¼–ç  \"%s\" ä¸å­˜åœ¨" -#: commands/conversioncmds.c:88 +#: commands/conversioncmds.c:86 #, c-format -#| msgid "encoding conversion function %s must return type \"void\"" msgid "encoding conversion function %s must return type %s" msgstr "ç¼–ç è½¬æ¢å‡½æ•° %s 必须返回类型 %s" -#: commands/copy.c:362 commands/copy.c:374 commands/copy.c:408 -#: commands/copy.c:420 +#: commands/copy.c:428 commands/copy.c:462 #, c-format msgid "COPY BINARY is not supported to stdout or from stdin" msgstr "COPOY BINARY 䏿”¯æŒè¾“出到标准输出或æ¥è‡ªæ ‡å‡†è¾“å…¥" -#: commands/copy.c:520 +#: commands/copy.c:562 #, c-format msgid "could not write to COPY program: %m" msgstr "无法写入 COPY 程åº: %m" -#: commands/copy.c:525 +#: commands/copy.c:567 #, c-format msgid "could not write to COPY file: %m" msgstr "无法写入 COPY 文件: %m" -#: commands/copy.c:538 +#: commands/copy.c:580 #, c-format msgid "connection lost during COPY to stdout" msgstr "COPY åˆ°æ ‡å‡†è¾“å‡ºçš„è¿‡ç¨‹ä¸­è”æŽ¥ä¸­æ–­" -#: commands/copy.c:579 +#: commands/copy.c:624 #, c-format msgid "could not read from COPY file: %m" msgstr "无法从COPY命令中文件进行读æ“作: %m" -#: commands/copy.c:595 commands/copy.c:616 commands/copy.c:620 -#: tcop/postgres.c:341 tcop/postgres.c:377 tcop/postgres.c:404 +#: commands/copy.c:642 commands/copy.c:663 commands/copy.c:667 +#: tcop/postgres.c:348 tcop/postgres.c:384 tcop/postgres.c:411 #, c-format msgid "unexpected EOF on client connection with an open transaction" msgstr "在客户端连接上的已打开事务中出现æ„外 EOF" -#: commands/copy.c:633 +#: commands/copy.c:680 #, c-format msgid "COPY from stdin failed: %s" msgstr "从标准输入上 COPY 失败: %s" -#: commands/copy.c:649 +#: commands/copy.c:696 #, c-format msgid "unexpected message type 0x%02X during COPY from stdin" msgstr "æ„外的信æ¯ç±»åž‹ 0x%02X, 在标准输入上 COPY 的过程中" -#: commands/copy.c:806 +#: commands/copy.c:863 #, c-format -msgid "must be superuser to COPY to or from an external program" -msgstr "å¿…é¡»æˆä¸ºè¶…级用户æ‰èƒ½ COPY åˆ°å¤–éƒ¨ç¨‹åºæˆ–者从外部程åºè¿›è¡ŒCOPY" +msgid "must be superuser or a member of the pg_execute_server_program role to COPY to or from an external program" +msgstr "必须是超级用户或pg_execute_server_program角色的æˆå‘˜æ‰èƒ½ COPY åˆ°å¤–éƒ¨ç¨‹åºæˆ–者从外部程åºè¿›è¡ŒCOPY" -#: commands/copy.c:807 commands/copy.c:813 +#: commands/copy.c:864 commands/copy.c:873 commands/copy.c:880 #, c-format -msgid "" -"Anyone can COPY to stdout or from stdin. psql's \\copy command also works " -"for anyone." -msgstr "" -"任何人å¯ä»¥ COPY 到标准输出或æ¥è‡ªæ ‡å‡†è¾“入的 COPY. 任何人也å¯ä»¥ä½¿ç”¨ Psql çš„ " -"\\copy 命令." +msgid "Anyone can COPY to stdout or from stdin. psql's \\copy command also works for anyone." +msgstr "任何人å¯ä»¥ COPY 到标准输出或æ¥è‡ªæ ‡å‡†è¾“入的 COPY. 任何人也å¯ä»¥ä½¿ç”¨ Psql çš„ \\copy 命令." -#: commands/copy.c:812 +#: commands/copy.c:872 #, c-format -msgid "must be superuser to COPY to or from a file" -msgstr "å¿…é¡»æˆä¸ºè¶…级用户æ‰èƒ½ COPY 到文件或从文件 COPY" +msgid "must be superuser or a member of the pg_read_server_files role to COPY from a file" +msgstr "必须是超级用户或pg_read_server_files角色的æˆå‘˜æ‰èƒ½ä»Žä¸€ä¸ªæ–‡ä»¶COPY" -#: commands/copy.c:878 +#: commands/copy.c:879 +#, c-format +msgid "must be superuser or a member of the pg_write_server_files role to COPY to a file" +msgstr "必须是超级用户或pg_write_server_files角色的æˆå‘˜æ‰èƒ½COPY到一个文件" + +#: commands/copy.c:963 #, c-format msgid "COPY FROM not supported with row-level security" msgstr "åœ¨è¡Œçº§å®‰å…¨æ€§ä¸‹ä¸æ”¯æŒCOPY FROM" -#: commands/copy.c:879 +#: commands/copy.c:964 #, c-format msgid "Use INSERT statements instead." msgstr "请使用INSERT语å¥ä»£æ›¿ã€‚" -#: commands/copy.c:1019 +#: commands/copy.c:1152 #, c-format msgid "COPY format \"%s\" not recognized" msgstr "没有识别COPY命令的格å¼\"%s\"" -#: commands/copy.c:1090 commands/copy.c:1104 commands/copy.c:1118 -#: commands/copy.c:1138 +#: commands/copy.c:1223 commands/copy.c:1239 commands/copy.c:1254 +#: commands/copy.c:1276 #, c-format msgid "argument to option \"%s\" must be a list of column names" msgstr "选项 \"%s\"çš„å‚æ•°å¿…须是一个包å«åˆ—å的列表" -#: commands/copy.c:1151 +#: commands/copy.c:1291 #, c-format msgid "argument to option \"%s\" must be a valid encoding name" msgstr "选项 \"%s\"çš„å‚æ•°å¿…须是一个有效的编ç å" -#: commands/copy.c:1157 commands/dbcommands.c:232 commands/dbcommands.c:1427 +#: commands/copy.c:1298 commands/dbcommands.c:243 commands/dbcommands.c:1463 #, c-format msgid "option \"%s\" not recognized" msgstr "未识别选项\"%s\"" -#: commands/copy.c:1168 +#: commands/copy.c:1310 #, c-format msgid "cannot specify DELIMITER in BINARY mode" msgstr "在 BINARY 模å¼ä¸­ä½ ä¸èƒ½æŒ‡å®š DELIMITER" -#: commands/copy.c:1173 +#: commands/copy.c:1315 #, c-format msgid "cannot specify NULL in BINARY mode" msgstr "在 BINARY 模å¼ä¸­ä½ ä¸èƒ½æŒ‡å®š NULL" -#: commands/copy.c:1195 +#: commands/copy.c:1337 #, c-format msgid "COPY delimiter must be a single one-byte character" msgstr "COPY命令中 的分隔符必需是å•字节字符" -#: commands/copy.c:1202 +#: commands/copy.c:1344 #, c-format msgid "COPY delimiter cannot be newline or carriage return" msgstr "COPY 命令中的分隔符ä¸èƒ½ä½¿æ–°è¡Œæˆ–回车符" -#: commands/copy.c:1208 +#: commands/copy.c:1350 #, c-format msgid "COPY null representation cannot use newline or carriage return" msgstr "在COPY命令中空表达å¼ä¸­ä¸èƒ½ä½¿ç”¨æ–°è¡Œæˆ–æ¢è¡Œå›žè½¦." -#: commands/copy.c:1225 +#: commands/copy.c:1367 #, c-format msgid "COPY delimiter cannot be \"%s\"" msgstr "COPY命令中的分隔符ä¸èƒ½ä¸º\"%s\"" -#: commands/copy.c:1231 +#: commands/copy.c:1373 #, c-format msgid "COPY HEADER available only in CSV mode" msgstr "åªåœ¨CSV 模å¼ä¸­æ‰èƒ½ä½¿ç”¨COPY HEADER命令" -#: commands/copy.c:1237 +#: commands/copy.c:1379 #, c-format msgid "COPY quote available only in CSV mode" msgstr "åªæœ‰åœ¨CSV模å¼ä¸­æ‰èƒ½åœ¨COPY命令中使用引å·" -#: commands/copy.c:1242 +#: commands/copy.c:1384 #, c-format msgid "COPY quote must be a single one-byte character" msgstr "在COPY命令中的引å·å¿…须是å•字节字符" -#: commands/copy.c:1247 +#: commands/copy.c:1389 #, c-format msgid "COPY delimiter and quote must be different" msgstr "COPY命令中的分隔符和引å·ä¸èƒ½ä¸€æ ·." -#: commands/copy.c:1253 +#: commands/copy.c:1395 #, c-format msgid "COPY escape available only in CSV mode" msgstr "COPY 转义 (escape) åªåœ¨ CSV 模å¼ä¸­æœ‰æ•ˆ" -#: commands/copy.c:1258 +#: commands/copy.c:1400 #, c-format msgid "COPY escape must be a single one-byte character" msgstr "在COPY命令中的转义字符必须是å•个å•字节字符" -#: commands/copy.c:1264 +#: commands/copy.c:1406 #, c-format msgid "COPY force quote available only in CSV mode" msgstr "åªæœ‰åœ¨CSV模å¼ä¸­æ‰èƒ½åœ¨COPY命令中进行强制引用æ“作" -#: commands/copy.c:1268 +#: commands/copy.c:1410 #, c-format msgid "COPY force quote only available using COPY TO" msgstr "åªæœ‰ä½¿ç”¨COPY TO命令时, COPY强制引用æ“ä½œæ‰æœ‰æ•ˆ" -#: commands/copy.c:1274 +#: commands/copy.c:1416 #, c-format msgid "COPY force not null available only in CSV mode" msgstr "åªæœ‰åœ¨CSV模å¼ä¸­å¼ºåˆ¶ä¸ä¸ºç©ºçš„COPYå‘½ä»¤æ‰æœ‰æ•ˆ" -#: commands/copy.c:1278 +#: commands/copy.c:1420 #, c-format msgid "COPY force not null only available using COPY FROM" msgstr "åªæœ‰åœ¨ä½¿ç”¨COPY FROM命令时,在COPY命令中的强制ä¸å¯ä¸ºç©ºçš„æ“ä½œæ‰æœ‰æ•ˆ" -#: commands/copy.c:1284 +#: commands/copy.c:1426 #, c-format msgid "COPY force null available only in CSV mode" msgstr "åªæœ‰åœ¨CSV模å¼ä¸­å¼ºåˆ¶ä¸ºç©ºçš„COPYå‘½ä»¤æ‰æœ‰æ•ˆ" -#: commands/copy.c:1289 +#: commands/copy.c:1431 #, c-format msgid "COPY force null only available using COPY FROM" msgstr "åªæœ‰åœ¨ä½¿ç”¨COPY FROM命令时,在COPY命令中的强制为空的æ“ä½œæ‰æœ‰æ•ˆ" -#: commands/copy.c:1295 +#: commands/copy.c:1437 #, c-format msgid "COPY delimiter must not appear in the NULL specification" msgstr "COPY分隔符ä¸èƒ½å‡ºçްNULL定义中" -#: commands/copy.c:1302 +#: commands/copy.c:1444 #, c-format msgid "CSV quote character must not appear in the NULL specification" msgstr "CSV引用字符ä¸èƒ½å‡ºçŽ°åœ¨NULL定义中." -#: commands/copy.c:1365 -#, c-format -msgid "table \"%s\" does not have OIDs" -msgstr "表 \"%s\" 没有 OID" - -#: commands/copy.c:1382 +#: commands/copy.c:1530 #, c-format -#| msgid "COPY (SELECT) WITH OIDS is not supported" -msgid "COPY (query) WITH OIDS is not supported" -msgstr "䏿”¯æŒ COPY (query) WITH OIDS" - -#: commands/copy.c:1402 -#, c-format -#| msgid "" -#| "DO INSTEAD NOTHING rules are not supported for data-modifying statements " -#| "in WITH" msgid "DO INSTEAD NOTHING rules are not supported for COPY" msgstr "对 COPY 语å¥ä¸æ”¯æŒ DO INSTEAD NOTHING 规则" -#: commands/copy.c:1416 +#: commands/copy.c:1544 #, c-format -#| msgid "" -#| "conditional DO INSTEAD rules are not supported for data-modifying " -#| "statements in WITH" msgid "conditional DO INSTEAD rules are not supported for COPY" msgstr "对 COPY 语å¥ä¸æ”¯æŒæœ‰æ¡ä»¶çš„ DO INSTEAD 规则" -#: commands/copy.c:1420 +#: commands/copy.c:1548 #, c-format -#| msgid "" -#| "DO ALSO rules are not supported for data-modifying statements in WITH" msgid "DO ALSO rules are not supported for the COPY" msgstr "对 COPY 语å¥ä¸æ”¯æŒ DO ALSO 规则" -#: commands/copy.c:1425 +#: commands/copy.c:1553 #, c-format -#| msgid "" -#| "multi-statement DO INSTEAD rules are not supported for data-modifying " -#| "statements in WITH" msgid "multi-statement DO INSTEAD rules are not supported for COPY" msgstr "对 COPY 语å¥ä¸æ”¯æŒå¤šè¯­å¥ DO INSTEAD 规则" -#: commands/copy.c:1435 +#: commands/copy.c:1563 #, c-format msgid "COPY (SELECT INTO) is not supported" msgstr "䏿”¯æŒä½¿ç”¨COPY (SELECT INTO)命令." -#: commands/copy.c:1452 +#: commands/copy.c:1580 #, c-format -#| msgid "WITH query \"%s\" does not have a RETURNING clause" msgid "COPY query must have a RETURNING clause" msgstr "COPY 查询必须有 RETURNING å­å¥" -#: commands/copy.c:1480 +#: commands/copy.c:1608 #, c-format msgid "relation referenced by COPY statement has changed" msgstr "COPY语å¥å¼•ç”¨çš„å…³ç³»å·²ç»æ”¹å˜" -#: commands/copy.c:1538 +#: commands/copy.c:1667 #, c-format -#| msgid "FORCE QUOTE column \"%s\" not referenced by COPY" msgid "FORCE_QUOTE column \"%s\" not referenced by COPY" msgstr "FORCE_QUOTE 列 \"%s\" 没有被 COPY 引用" -#: commands/copy.c:1560 +#: commands/copy.c:1690 #, c-format -#| msgid "FORCE NOT NULL column \"%s\" not referenced by COPY" msgid "FORCE_NOT_NULL column \"%s\" not referenced by COPY" msgstr "FORCE_NOT_NULL 列 \"%s\" 没有被 COPY 引用" -#: commands/copy.c:1582 +#: commands/copy.c:1713 #, c-format -#| msgid "FORCE NULL column \"%s\" not referenced by COPY" msgid "FORCE_NULL column \"%s\" not referenced by COPY" msgstr "FORCE_NULL 列 \"%s\" 没有被 COPY 引用" -#: commands/copy.c:1647 +#: commands/copy.c:1779 libpq/be-secure-common.c:102 #, c-format msgid "could not close pipe to external command: %m" msgstr "无法为外部命令: %m关闭管é“" -#: commands/copy.c:1651 +#: commands/copy.c:1794 #, c-format msgid "program \"%s\" failed" msgstr "程åº\"%s\"失败" -#: commands/copy.c:1701 +#: commands/copy.c:1845 #, c-format msgid "cannot copy from view \"%s\"" msgstr "ä¸å¯ä»¥ä»Žè§†å›¾ \"%s\" æ‹·è´" -#: commands/copy.c:1703 commands/copy.c:1709 commands/copy.c:1715 +#: commands/copy.c:1847 commands/copy.c:1853 commands/copy.c:1859 +#: commands/copy.c:1870 #, c-format msgid "Try the COPY (SELECT ...) TO variant." msgstr "å°è¯•ä¸åŒå½¢å¼çš„COPY (SELECT ...) TO命令" -#: commands/copy.c:1707 +#: commands/copy.c:1851 #, c-format msgid "cannot copy from materialized view \"%s\"" msgstr "ä¸å¯ä»¥ä»Žç‰©åŒ–视图 \"%s\" æ‹·è´" -#: commands/copy.c:1713 +#: commands/copy.c:1857 #, c-format msgid "cannot copy from foreign table \"%s\"" msgstr "ä¸å¯ä»¥ä»Žå¤–部表 \"%s\" æ‹·è´" -#: commands/copy.c:1719 +#: commands/copy.c:1863 #, c-format msgid "cannot copy from sequence \"%s\"" msgstr "ä¸å¯ä»¥ä»Žåºåˆ— \"%s\" æ‹·è´" -#: commands/copy.c:1724 +#: commands/copy.c:1868 #, c-format -msgid "cannot copy from non-table relation \"%s\"" -msgstr "ä¸å¯ä»¥ä»Žéžè¡¨å…³ç³» \"%s\" æ‹·è´" +msgid "cannot copy from partitioned table \"%s\"" +msgstr "ä¸å¯ä»¥ä»Žåˆ†åŒºè¡¨ \"%s\" æ‹·è´" -#: commands/copy.c:1749 commands/copy.c:2787 +#: commands/copy.c:1874 #, c-format -msgid "could not execute command \"%s\": %m" -msgstr "无法执行命令 \"%s\": %m" +msgid "cannot copy from non-table relation \"%s\"" +msgstr "ä¸å¯ä»¥ä»Žéžè¡¨å…³ç³» \"%s\" æ‹·è´" -#: commands/copy.c:1764 +#: commands/copy.c:1914 #, c-format msgid "relative path not allowed for COPY to file" msgstr "COPY 到文件ä¸å…许相对路径" -#: commands/copy.c:1772 +#: commands/copy.c:1935 #, c-format msgid "could not open file \"%s\" for writing: %m" msgstr "为了写入, 无法打开文件 \"%s\": %m" -#: commands/copy.c:1784 commands/copy.c:2810 +#: commands/copy.c:1938 +#, c-format +msgid "COPY TO instructs the PostgreSQL server process to write a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY TO指示PostgreSQLæœåŠ¡å™¨è¿›ç¨‹å†™å…¥æ–‡ä»¶ã€‚æ‚¨å¯èƒ½éœ€è¦å®¢æˆ·ç«¯å·¥å…·ï¼Œå¦‚psqlçš„\\copy。" + +#: commands/copy.c:1951 commands/copy.c:3560 #, c-format msgid "\"%s\" is a directory" msgstr "\"%s\" 是一个目录" -#: commands/copy.c:2109 +#: commands/copy.c:2253 #, c-format -msgid "COPY %s, line %d, column %s" -msgstr "COPY %s, 行 %d, 列 %s" +msgid "COPY %s, line %s, column %s" +msgstr "COPY %s, 行 %s, 列 %s" -#: commands/copy.c:2113 commands/copy.c:2160 +#: commands/copy.c:2257 commands/copy.c:2304 #, c-format -msgid "COPY %s, line %d" -msgstr "COPY %s, 行 %d" +msgid "COPY %s, line %s" +msgstr "COPY %s, 行 %s" -#: commands/copy.c:2124 +#: commands/copy.c:2268 #, c-format -msgid "COPY %s, line %d, column %s: \"%s\"" -msgstr "COPY %s, 行 %d, 列 %s: \"%s\"" +msgid "COPY %s, line %s, column %s: \"%s\"" +msgstr "COPY %s, 行 %s, 列 %s: \"%s\"" -#: commands/copy.c:2132 +#: commands/copy.c:2276 #, c-format -msgid "COPY %s, line %d, column %s: null input" -msgstr "COPY %s, 行 %d, 列 %s: 空的输入" +msgid "COPY %s, line %s, column %s: null input" +msgstr "COPY %s, 行 %s, 列 %s: 空的输入" -#: commands/copy.c:2154 +#: commands/copy.c:2298 #, c-format -msgid "COPY %s, line %d: \"%s\"" -msgstr "COPY %s, 行 %d: \"%s\"" +msgid "COPY %s, line %s: \"%s\"" +msgstr "COPY %s, 行 %s: \"%s\"" -#: commands/copy.c:2238 +#: commands/copy.c:2692 #, c-format msgid "cannot copy to view \"%s\"" msgstr "ä¸å¯ä»¥æ‹·è´åˆ°è§†å›¾ \"%s\"" -#: commands/copy.c:2243 +#: commands/copy.c:2694 #, c-format -msgid "cannot copy to materialized view \"%s\"" -msgstr "ä¸å¯ä»¥æ‹·è´åˆ°ç‰©åŒ–视图 \"%s\"" +msgid "To enable copying to a view, provide an INSTEAD OF INSERT trigger." +msgstr "å¯ç”¨å‘è§†å›¾æ‹·è´æ“作, è¦æä¾›INSTEAD OF INSERT触å‘器." -#: commands/copy.c:2248 +#: commands/copy.c:2698 #, c-format -msgid "cannot copy to foreign table \"%s\"" -msgstr "ä¸å¯ä»¥æ‹·è´åˆ°å¤–部表 \"%s\"" +msgid "cannot copy to materialized view \"%s\"" +msgstr "ä¸å¯ä»¥æ‹·è´åˆ°ç‰©åŒ–视图 \"%s\"" -#: commands/copy.c:2253 +#: commands/copy.c:2703 #, c-format msgid "cannot copy to sequence \"%s\"" msgstr "ä¸å¯ä»¥æ‹·è´åˆ°åºåˆ— \"%s\"" -#: commands/copy.c:2258 +#: commands/copy.c:2708 #, c-format msgid "cannot copy to non-table relation \"%s\"" msgstr "ä¸å¯ä»¥æ‹·è´åˆ°éžè¡¨å…³ç³» \"%s\"" -#: commands/copy.c:2321 -#, c-format -msgid "cannot perform FREEZE because of prior transaction activity" +#: commands/copy.c:2796 +#, fuzzy, c-format +#| msgid "cannot perform FREEZE on a partitioned table" +msgid "cannot perform COPY FREEZE on a partitioned table" +msgstr "在分区表上无法执行FREEZEæ“作" + +#: commands/copy.c:2811 +#, fuzzy, c-format +#| msgid "cannot perform FREEZE because of prior transaction activity" +msgid "cannot perform COPY FREEZE because of prior transaction activity" msgstr "由于å‰ä¸€ä¸ªäº‹åŠ¡æ˜¯æ´»åŠ¨çš„ï¼Œæ— æ³•æ‰§è¡ŒFREEZEæ“作" -#: commands/copy.c:2327 -#, c-format -msgid "" -"cannot perform FREEZE because the table was not created or truncated in the " -"current subtransaction" +#: commands/copy.c:2817 +#, fuzzy, c-format +#| msgid "cannot perform FREEZE because the table was not created or truncated in the current subtransaction" +msgid "cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction" msgstr "当å‰å­äº‹åŠ¡ä¸­ï¼Œå› ä¸ºè¡¨æœªå»ºæˆ–è¢«æˆªçŸ­ï¼Œæ— æ³•æ‰§è¡ŒFREEZEæ“作" -#: commands/copy.c:2830 +#: commands/copy.c:3547 +#, c-format +msgid "COPY FROM instructs the PostgreSQL server process to read a file. You may want a client-side facility such as psql's \\copy." +msgstr "COPY FROM指示PostgreSQLæœåŠ¡å™¨è¿›ç¨‹è¯»å–æ–‡ä»¶ã€‚您å¯èƒ½éœ€è¦å®¢æˆ·ç«¯å·¥å…·ï¼Œå¦‚psqlçš„\\copy" + +#: commands/copy.c:3575 #, c-format msgid "COPY file signature not recognized" msgstr "文件签字ä¸è¢«è®¤å¯" -#: commands/copy.c:2835 +#: commands/copy.c:3580 #, c-format msgid "invalid COPY file header (missing flags)" msgstr "无效的 COPY 文件头 (缺少标志)" -#: commands/copy.c:2841 +#: commands/copy.c:3584 +#, fuzzy, c-format +#| msgid "invalid COPY file header (wrong length)" +msgid "invalid COPY file header (WITH OIDS)" +msgstr "无效的 COPY 文件头 (错误长度)" + +#: commands/copy.c:3589 #, c-format msgid "unrecognized critical flags in COPY file header" msgstr "在 COPY 文件头有ä¸è®¤å¯çš„å±é™©æ ‡å¿—" -#: commands/copy.c:2847 +#: commands/copy.c:3595 #, c-format msgid "invalid COPY file header (missing length)" msgstr "无效的 COPY 文件头 (缺少长度)" -#: commands/copy.c:2854 +#: commands/copy.c:3602 #, c-format msgid "invalid COPY file header (wrong length)" msgstr "无效的 COPY 文件头 (错误长度)" -#: commands/copy.c:2987 commands/copy.c:3694 commands/copy.c:3924 +#: commands/copy.c:3721 commands/copy.c:4386 commands/copy.c:4616 #, c-format msgid "extra data after last expected column" msgstr "æœ€åŽæœŸæœ›å­—æ®µåŽæœ‰é¢å¤–æ•°æ®" -#: commands/copy.c:2997 -#, c-format -msgid "missing data for OID column" -msgstr "OID列丢失数æ®" - -#: commands/copy.c:3003 -#, c-format -msgid "null OID in COPY data" -msgstr "在 COPY æ•°æ®ä¸­æ²¡æœ‰ OID" - -#: commands/copy.c:3013 commands/copy.c:3136 -#, c-format -msgid "invalid OID in COPY data" -msgstr "在 COPY æ•°æ®ä¸­æ— æ•ˆçš„ OID" - -#: commands/copy.c:3028 +#: commands/copy.c:3735 #, c-format msgid "missing data for column \"%s\"" msgstr "字段 \"%s\" 缺少数æ®" -#: commands/copy.c:3111 +#: commands/copy.c:3818 #, c-format msgid "received copy data after EOF marker" msgstr "在EOFæ ‡å¿—åŽæ”¶åˆ°äº†å¤åˆ¶æ•°æ®" -#: commands/copy.c:3118 +#: commands/copy.c:3825 #, c-format msgid "row field count is %d, expected %d" msgstr "元组字段计数是 %d, 期望计数是 %d" -#: commands/copy.c:3458 commands/copy.c:3475 +#: commands/copy.c:4145 commands/copy.c:4162 #, c-format msgid "literal carriage return found in data" msgstr "在数æ®ä¸­æ‰¾åˆ°äº†æ–‡å­—的回车æ¢è¡Œç¬¦" -#: commands/copy.c:3459 commands/copy.c:3476 +#: commands/copy.c:4146 commands/copy.c:4163 #, c-format msgid "unquoted carriage return found in data" msgstr "在数æ®ä¸­æ‰¾åˆ°äº†æœªç”¨å¼•å·å¼•èµ·æ¥çš„回车æ¢è¡Œç¬¦" -#: commands/copy.c:3461 commands/copy.c:3478 +#: commands/copy.c:4148 commands/copy.c:4165 #, c-format msgid "Use \"\\r\" to represent carriage return." msgstr "使用\"\\r\"æ¥ä»£è¡¨æ¢è¡Œå›žè½¦" -#: commands/copy.c:3462 commands/copy.c:3479 +#: commands/copy.c:4149 commands/copy.c:4166 #, c-format msgid "Use quoted CSV field to represent carriage return." msgstr "使用以引å·å¼•èµ·æ¥çš„CSV字段代表æ¢è¡Œå›žè½¦." -#: commands/copy.c:3491 +#: commands/copy.c:4178 #, c-format msgid "literal newline found in data" msgstr "在数æ®ä¸­æ‰¾åˆ°äº†æ–‡å­—å½¢å¼çš„æ–°è¡Œ" -#: commands/copy.c:3492 +#: commands/copy.c:4179 #, c-format msgid "unquoted newline found in data" msgstr "在数æ®ä¸­æ‰¾åˆ°äº†æœªç”¨å¼•å·å¼•èµ·æ¥çš„æ–°è¡Œ" -#: commands/copy.c:3494 +#: commands/copy.c:4181 #, c-format msgid "Use \"\\n\" to represent newline." msgstr "使用 \"\\n\" 表示新行." -#: commands/copy.c:3495 +#: commands/copy.c:4182 #, c-format msgid "Use quoted CSV field to represent newline." msgstr "使用用引å·å› èµ·æ¥çš„CSV字段æ¥è¡¨ç¤ºæ–°è¡Œ." -#: commands/copy.c:3541 commands/copy.c:3577 +#: commands/copy.c:4228 commands/copy.c:4264 #, c-format msgid "end-of-copy marker does not match previous newline style" msgstr "end-of-copy标示ä¸åŒ¹é…å…ˆå‰çš„æ–°æ•°æ®è¡Œçš„风格." -#: commands/copy.c:3550 commands/copy.c:3566 +#: commands/copy.c:4237 commands/copy.c:4253 #, c-format msgid "end-of-copy marker corrupt" msgstr "copyå‘½ä»¤ç»“æŸæ ‡è®°æŸå" -#: commands/copy.c:4008 +#: commands/copy.c:4700 #, c-format msgid "unterminated CSV quoted field" msgstr "CSV 引å·åŸŸæ²¡æœ‰ç»“æŸ" -#: commands/copy.c:4085 commands/copy.c:4104 +#: commands/copy.c:4777 commands/copy.c:4796 #, c-format msgid "unexpected EOF in COPY data" msgstr "在 COPY æ•°æ®ä¸­æ„外的 EOF" -#: commands/copy.c:4094 +#: commands/copy.c:4786 #, c-format msgid "invalid field size" msgstr "无效字段尺寸" -#: commands/copy.c:4117 +#: commands/copy.c:4809 #, c-format msgid "incorrect binary data format" msgstr "䏿­£ç¡®çš„äºŒè¿›åˆ¶æ•°æ®æ ¼å¼" -#: commands/copy.c:4428 commands/indexcmds.c:1053 commands/tablecmds.c:1463 -#: commands/tablecmds.c:2290 parser/parse_relation.c:3084 -#: parser/parse_relation.c:3104 utils/adt/tsvector_op.c:2222 +#: commands/copy.c:5117 +#, fuzzy, c-format +#| msgid "column \"%s\" has a type conflict" +msgid "column \"%s\" is a generated column" +msgstr "属性 \"%s\" 类型冲çª" + +#: commands/copy.c:5119 +#, c-format +msgid "Generated columns cannot be used in COPY." +msgstr "" + +#: commands/copy.c:5134 commands/indexcmds.c:1582 commands/statscmds.c:210 +#: commands/tablecmds.c:2069 commands/tablecmds.c:2604 +#: commands/tablecmds.c:2983 parser/parse_relation.c:3353 +#: parser/parse_relation.c:3373 utils/adt/tsvector_op.c:2559 #, c-format msgid "column \"%s\" does not exist" msgstr "字段 \"%s\" ä¸å­˜åœ¨" -#: commands/copy.c:4435 commands/tablecmds.c:1489 commands/trigger.c:651 -#: parser/parse_target.c:956 parser/parse_target.c:967 +#: commands/copy.c:5141 commands/tablecmds.c:2096 commands/trigger.c:937 +#: parser/parse_target.c:1047 parser/parse_target.c:1058 #, c-format msgid "column \"%s\" specified more than once" msgstr "字段 \"%s\" 被指定多次" -#: commands/createas.c:383 +#: commands/createas.c:216 commands/createas.c:499 #, c-format msgid "too many column names were specified" msgstr "指定了太多的列å" -#: commands/createas.c:452 +#: commands/createas.c:541 #, c-format msgid "policies not yet implemented for this command" msgstr "还没有为该命令实现策略" -#: commands/dbcommands.c:226 +#: commands/dbcommands.c:236 #, c-format msgid "LOCATION is not supported anymore" msgstr "ä¸å†æ”¯æŒ LOCATION" -#: commands/dbcommands.c:227 +#: commands/dbcommands.c:237 #, c-format msgid "Consider using tablespaces instead." msgstr "考虑使用表空间代替." -#: commands/dbcommands.c:251 utils/adt/ascii.c:144 +#: commands/dbcommands.c:263 utils/adt/ascii.c:145 #, c-format msgid "%d is not a valid encoding code" msgstr "%d 是一个无效编ç " -#: commands/dbcommands.c:261 utils/adt/ascii.c:126 +#: commands/dbcommands.c:274 utils/adt/ascii.c:127 #, c-format msgid "%s is not a valid encoding name" msgstr "%s 是一个无效编ç åå­—" # fe-connect.c:2558 -#: commands/dbcommands.c:279 commands/dbcommands.c:1458 commands/user.c:272 -#: commands/user.c:650 +#: commands/dbcommands.c:293 commands/dbcommands.c:1496 commands/user.c:275 +#: commands/user.c:671 #, c-format msgid "invalid connection limit: %d" msgstr "无效的连接é™åˆ¶:%d" -#: commands/dbcommands.c:298 +#: commands/dbcommands.c:312 #, c-format msgid "permission denied to create database" msgstr "创建数æ®åº“æƒé™ä¸å¤Ÿ" -#: commands/dbcommands.c:321 +#: commands/dbcommands.c:335 #, c-format msgid "template database \"%s\" does not exist" msgstr "template æ•°æ®åº“ \"%s\" ä¸å­˜åœ¨" -#: commands/dbcommands.c:333 +#: commands/dbcommands.c:347 #, c-format msgid "permission denied to copy database \"%s\"" msgstr "æ‹·è´æ•°æ®åº“ \"%s\" æƒé™ä¸å¤Ÿ" -#: commands/dbcommands.c:349 +#: commands/dbcommands.c:363 #, c-format msgid "invalid server encoding %d" msgstr "无效æœåŠ¡å™¨ç¼–ç  %d" -#: commands/dbcommands.c:355 commands/dbcommands.c:360 +#: commands/dbcommands.c:369 commands/dbcommands.c:374 #, c-format msgid "invalid locale name: \"%s\"" msgstr "无效的语言环境åç§°: \"%s\"" -#: commands/dbcommands.c:380 +#: commands/dbcommands.c:394 #, c-format -msgid "" -"new encoding (%s) is incompatible with the encoding of the template database " -"(%s)" +msgid "new encoding (%s) is incompatible with the encoding of the template database (%s)" msgstr "新的编ç (%s)ä¸Žæ¨¡æ¿æ•°æ®åº“(%s)的编ç ä¸å…¼å®¹" -#: commands/dbcommands.c:383 +#: commands/dbcommands.c:397 #, c-format -msgid "" -"Use the same encoding as in the template database, or use template0 as " -"template." +msgid "Use the same encoding as in the template database, or use template0 as template." msgstr "在模版数æ®åº“中使用åŒä¸€ç¼–ç ï¼Œæˆ–者使用template0作为模版." -#: commands/dbcommands.c:388 +#: commands/dbcommands.c:402 #, c-format -msgid "" -"new collation (%s) is incompatible with the collation of the template " -"database (%s)" +msgid "new collation (%s) is incompatible with the collation of the template database (%s)" msgstr "新的排åºè§„则(%s)与模版数æ®åº“(%s)中的排åºè§„则ä¸å…¼å®¹" -#: commands/dbcommands.c:390 +#: commands/dbcommands.c:404 #, c-format -msgid "" -"Use the same collation as in the template database, or use template0 as " -"template." +msgid "Use the same collation as in the template database, or use template0 as template." msgstr "在模版数æ®åº“中使用åŒä¸€æŽ’åºè§„则,或者使用template0作为模版." -#: commands/dbcommands.c:395 +#: commands/dbcommands.c:409 #, c-format -msgid "" -"new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database " -"(%s)" +msgid "new LC_CTYPE (%s) is incompatible with the LC_CTYPE of the template database (%s)" msgstr "æ–°çš„LC_CTYPE (%s)与模版数æ®åº“(%s)中的LC_CTYPEä¸å…¼å®¹." -#: commands/dbcommands.c:397 +#: commands/dbcommands.c:411 #, c-format -msgid "" -"Use the same LC_CTYPE as in the template database, or use template0 as " -"template." +msgid "Use the same LC_CTYPE as in the template database, or use template0 as template." msgstr "在模版数æ®åº“中使用åŒä¸€LC_CTYPE,或者使用template0作为模版." -#: commands/dbcommands.c:419 commands/dbcommands.c:1113 +#: commands/dbcommands.c:433 commands/dbcommands.c:1148 #, c-format msgid "pg_global cannot be used as default tablespace" msgstr "pg_globalä¸èƒ½ä½œä¸ºç¼ºçœè¡¨ç©ºé—´ä½¿ç”¨" -#: commands/dbcommands.c:445 +#: commands/dbcommands.c:459 #, c-format msgid "cannot assign new default tablespace \"%s\"" msgstr "æ— æ³•åˆ†é…æ–°çš„默认表空间 \"%s\"" -#: commands/dbcommands.c:447 +#: commands/dbcommands.c:461 #, c-format -msgid "" -"There is a conflict because database \"%s\" already has some tables in this " -"tablespace." +msgid "There is a conflict because database \"%s\" already has some tables in this tablespace." msgstr "此处有冲çª, 因为数æ®åº“ \"%s\" å·²ç»æœ‰ä¸€äº›è¡¨åœ¨æ­¤è¡¨ç©ºé—´ä¸­." -#: commands/dbcommands.c:467 commands/dbcommands.c:982 +#: commands/dbcommands.c:481 commands/dbcommands.c:1018 #, c-format msgid "database \"%s\" already exists" msgstr "æ•°æ®åº“ \"%s\" å·²ç»å­˜åœ¨" -#: commands/dbcommands.c:481 +#: commands/dbcommands.c:495 #, c-format msgid "source database \"%s\" is being accessed by other users" msgstr "å…¶ä»–ç”¨æˆ·æ­£åœ¨ä½¿ç”¨æºæ•°æ®åº“ \"%s\"" -#: commands/dbcommands.c:726 commands/dbcommands.c:741 +#: commands/dbcommands.c:738 commands/dbcommands.c:753 #, c-format msgid "encoding \"%s\" does not match locale \"%s\"" msgstr "ç¼–ç  \"%s\"与本地化环境\"%s\"ä¸åŒ¹é…" -#: commands/dbcommands.c:729 +#: commands/dbcommands.c:741 #, c-format msgid "The chosen LC_CTYPE setting requires encoding \"%s\"." msgstr "所选择的LC_CTYPE设置需è¦ç¼–ç \"%s\"." -#: commands/dbcommands.c:744 +#: commands/dbcommands.c:756 #, c-format msgid "The chosen LC_COLLATE setting requires encoding \"%s\"." msgstr "所选择的 LC_COLLATE设置需è¦ç¼–ç \"%s\"." -#: commands/dbcommands.c:804 +#: commands/dbcommands.c:817 #, c-format msgid "database \"%s\" does not exist, skipping" msgstr "æ•°æ®åº“ \"%s\" ä¸å­˜åœ¨,跳过" -#: commands/dbcommands.c:828 +#: commands/dbcommands.c:841 #, c-format msgid "cannot drop a template database" msgstr "æ— æ³•åˆ é™¤æ¨¡æ¿æ•°æ®åº“" -#: commands/dbcommands.c:834 +#: commands/dbcommands.c:847 #, c-format msgid "cannot drop the currently open database" msgstr "无法删除当å‰ä½¿ç”¨çš„æ•°æ®åº“" -#: commands/dbcommands.c:844 +#: commands/dbcommands.c:860 #, c-format -msgid "database \"%s\" is used by a logical replication slot" -msgstr "æ•°æ®åº“\"%s\"被一个逻辑å¤åˆ¶æ§½ä½¿ç”¨" +msgid "database \"%s\" is used by an active logical replication slot" +msgstr "æ•°æ®åº“\"%s\"被一个活动的逻辑å¤åˆ¶æ§½ä½¿ç”¨" -#: commands/dbcommands.c:846 +#: commands/dbcommands.c:862 #, c-format -msgid "There is %d slot, %d of them active." -msgid_plural "There are %d slots, %d of them active." -msgstr[0] "有%d个槽,其中%d个是活动的." +msgid "There is %d active slot." +msgid_plural "There are %d active slots." +msgstr[0] "有%dä¸ªæ´»åŠ¨æ’æ§½." -#: commands/dbcommands.c:860 commands/dbcommands.c:1004 -#: commands/dbcommands.c:1135 +#: commands/dbcommands.c:876 commands/dbcommands.c:1040 +#: commands/dbcommands.c:1170 #, c-format msgid "database \"%s\" is being accessed by other users" msgstr "其他用户正在使用数æ®åº“ \"%s\"" -#: commands/dbcommands.c:973 +#: commands/dbcommands.c:889 +#, c-format +msgid "database \"%s\" is being used by logical replication subscription" +msgstr "逻辑å¤åˆ¶è®¢é˜…正在使用数æ®åº“\"%s\"" + +#: commands/dbcommands.c:891 +#, c-format +msgid "There is %d subscription." +msgid_plural "There are %d subscriptions." +msgstr[0] "有%d个订阅." + +#: commands/dbcommands.c:1009 #, c-format msgid "permission denied to rename database" msgstr "é‡å‘½åæ•°æ®åº“æƒé™ä¸å¤Ÿ" -#: commands/dbcommands.c:993 +#: commands/dbcommands.c:1029 #, c-format msgid "current database cannot be renamed" msgstr "ä¸èƒ½å¯¹å½“剿•°æ®åº“进行改å" -#: commands/dbcommands.c:1091 +#: commands/dbcommands.c:1126 #, c-format msgid "cannot change the tablespace of the currently open database" msgstr "无法改å˜å½“å‰å·²æ‰“开数æ®åº“的表空间" -#: commands/dbcommands.c:1194 +#: commands/dbcommands.c:1229 #, c-format msgid "some relations of database \"%s\" are already in tablespace \"%s\"" msgstr "在表空间 \"%2$s\"中已ç»å­˜å‚¨äº†æ•°æ®åº“\"%1$s\"中的一些关系了" -#: commands/dbcommands.c:1196 +#: commands/dbcommands.c:1231 #, c-format -msgid "" -"You must move them back to the database's default tablespace before using " -"this command." +msgid "You must move them back to the database's default tablespace before using this command." msgstr "在使用这æ¡å‘½ä»¤å‰ï¼Œæ‚¨å¿…须把它们移动回数æ®åº“的缺çœè¡¨ç©ºé—´" -#: commands/dbcommands.c:1325 commands/dbcommands.c:1868 -#: commands/dbcommands.c:2072 commands/dbcommands.c:2120 -#: commands/tablespace.c:610 +#: commands/dbcommands.c:1356 commands/dbcommands.c:1902 +#: commands/dbcommands.c:2107 commands/dbcommands.c:2162 +#: commands/tablespace.c:611 #, c-format msgid "some useless files may be left behind in old database directory \"%s\"" msgstr "在原先的数æ®åº“目录\"%s\"å¯èƒ½ç•™ä¸‹äº†ä¸€äº›æ— ç”¨çš„æ–‡ä»¶" -#: commands/dbcommands.c:1440 +#: commands/dbcommands.c:1477 #, c-format msgid "option \"%s\" cannot be specified with other options" msgstr "选项\"%s\"ä¸èƒ½å’Œå…¶ä»–选项一起指定" # command.c:981 -#: commands/dbcommands.c:1494 +#: commands/dbcommands.c:1533 #, c-format msgid "cannot disallow connections for current database" msgstr "æ— æ³•ç¦æ­¢åˆ°å½“剿•°æ®åº“的连接" -#: commands/dbcommands.c:1634 +#: commands/dbcommands.c:1669 #, c-format msgid "permission denied to change owner of database" msgstr "æ”¹å˜æ•°æ®åº“属主的æƒé™ä¸å¤Ÿ" -#: commands/dbcommands.c:1955 +#: commands/dbcommands.c:1990 #, c-format -msgid "" -"There are %d other session(s) and %d prepared transaction(s) using the " -"database." +msgid "There are %d other session(s) and %d prepared transaction(s) using the database." msgstr "这里有%d个其它的会è¯å’Œ%d个已准备好的事务正在使用数æ®åº“." -#: commands/dbcommands.c:1958 +#: commands/dbcommands.c:1993 #, c-format msgid "There is %d other session using the database." msgid_plural "There are %d other sessions using the database." msgstr[0] "那里有%dä¸ªå…¶å®ƒä¼šè¯æ­£åœ¨ä½¿ç”¨æ•°æ®åº“." -#: commands/dbcommands.c:1963 +#: commands/dbcommands.c:1998 #, c-format msgid "There is %d prepared transaction using the database." msgid_plural "There are %d prepared transactions using the database." msgstr[0] "那里有%d个已准备好的事务正在使用数æ®åº“." #: commands/define.c:54 commands/define.c:228 commands/define.c:260 -#: commands/define.c:288 +#: commands/define.c:288 commands/define.c:334 #, c-format msgid "%s requires a parameter" msgstr "%s 需è¦ä¸€ä¸ªå‚æ•°" @@ -6477,1145 +6495,1307 @@ msgstr "%s çš„å‚æ•°å¿…需是一个类型å" msgid "invalid argument for %s: \"%s\"" msgstr "%s çš„æ— æ•ˆå‚æ•°: \"%s\"" -#: commands/dropcmds.c:112 commands/functioncmds.c:1203 -#: utils/adt/ruleutils.c:1957 +#: commands/dropcmds.c:99 commands/functioncmds.c:1272 +#: utils/adt/ruleutils.c:2609 #, c-format msgid "\"%s\" is an aggregate function" msgstr "\"%s\" 是一个èšåˆå‡½æ•°" -#: commands/dropcmds.c:114 +#: commands/dropcmds.c:101 #, c-format msgid "Use DROP AGGREGATE to drop aggregate functions." msgstr "使用 DROP AGGREGATE 删除一个èšåˆå‡½æ•°." -#: commands/dropcmds.c:165 commands/sequence.c:424 commands/tablecmds.c:2377 -#: commands/tablecmds.c:2528 commands/tablecmds.c:2570 -#: commands/tablecmds.c:11379 tcop/utility.c:1119 +#: commands/dropcmds.c:157 commands/sequence.c:447 commands/tablecmds.c:3067 +#: commands/tablecmds.c:3225 commands/tablecmds.c:3270 +#: commands/tablecmds.c:14087 tcop/utility.c:1174 #, c-format msgid "relation \"%s\" does not exist, skipping" msgstr "关系 \"%s\" ä¸å­˜åœ¨ï¼Œå¿½ç•¥" -#: commands/dropcmds.c:195 commands/dropcmds.c:292 commands/tablecmds.c:745 +#: commands/dropcmds.c:187 commands/dropcmds.c:286 commands/tablecmds.c:1142 #, c-format msgid "schema \"%s\" does not exist, skipping" msgstr "æ¨¡å¼ \"%s\" ä¸å­˜åœ¨" -#: commands/dropcmds.c:237 commands/dropcmds.c:272 commands/tablecmds.c:246 +#: commands/dropcmds.c:227 commands/dropcmds.c:266 commands/tablecmds.c:253 #, c-format msgid "type \"%s\" does not exist, skipping" msgstr "类型 \"%s\" ä¸å­˜åœ¨" -#: commands/dropcmds.c:280 +#: commands/dropcmds.c:256 +#, c-format +msgid "access method \"%s\" does not exist, skipping" +msgstr "è®¿é—®æ–¹å¼ \"%s\" ä¸å­˜åœ¨, 跳过" + +#: commands/dropcmds.c:274 #, c-format msgid "collation \"%s\" does not exist, skipping" msgstr "排åºè§„则 \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:287 +#: commands/dropcmds.c:281 #, c-format msgid "conversion \"%s\" does not exist, skipping" msgstr "ç¼–ç è½¬æ¢ \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:298 +#: commands/dropcmds.c:292 +#, c-format +msgid "statistics object \"%s\" does not exist, skipping" +msgstr "统计信æ¯å¯¹è±¡ \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" + +#: commands/dropcmds.c:299 #, c-format msgid "text search parser \"%s\" does not exist, skipping" msgstr "文本æœç´¢è§£æžå™¨\"%s\"ä¸å­˜åœ¨,跳过" -#: commands/dropcmds.c:305 +#: commands/dropcmds.c:306 #, c-format msgid "text search dictionary \"%s\" does not exist, skipping" msgstr "文本æœç´¢å­—å…¸ \"%s\" ä¸å­˜åœ¨,跳过" -#: commands/dropcmds.c:312 +#: commands/dropcmds.c:313 #, c-format msgid "text search template \"%s\" does not exist, skipping" msgstr "文本æœç´¢æ¨¡æ¿\"%s\"ä¸å­˜åœ¨,跳过" -#: commands/dropcmds.c:319 +#: commands/dropcmds.c:320 #, c-format msgid "text search configuration \"%s\" does not exist, skipping" msgstr "文本æœå¯»é…ç½® \"%s\"ä¸å­˜åœ¨,跳过" -#: commands/dropcmds.c:324 +#: commands/dropcmds.c:325 #, c-format msgid "extension \"%s\" does not exist, skipping" msgstr "扩展 \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:331 +#: commands/dropcmds.c:335 #, c-format msgid "function %s(%s) does not exist, skipping" msgstr "函数 %s(%s) ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:340 +#: commands/dropcmds.c:348 +#, c-format +msgid "procedure %s(%s) does not exist, skipping" +msgstr "过程 %s(%s) ä¸å­˜åœ¨,跳过" + +#: commands/dropcmds.c:361 +#, c-format +msgid "routine %s(%s) does not exist, skipping" +msgstr "routine %s(%s) ä¸å­˜åœ¨ï¼Œè·³è¿‡" + +#: commands/dropcmds.c:374 #, c-format msgid "aggregate %s(%s) does not exist, skipping" msgstr "èšåˆå‡½æ•° %s(%s) ä¸å­˜åœ¨,跳过" -#: commands/dropcmds.c:349 +#: commands/dropcmds.c:387 #, c-format msgid "operator %s does not exist, skipping" msgstr "æ“作符 %sä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:354 +#: commands/dropcmds.c:393 #, c-format msgid "language \"%s\" does not exist, skipping" msgstr "语言 \"%s\" ä¸å­˜åœ¨" -#: commands/dropcmds.c:363 +#: commands/dropcmds.c:402 #, c-format msgid "cast from type %s to type %s does not exist, skipping" msgstr "从类型 %s 到类型 %s 的类型转æ¢ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:372 +#: commands/dropcmds.c:411 #, c-format msgid "transform for type %s language \"%s\" does not exist, skipping" msgstr "用于类型%sã€è¯­è¨€\"%s\"的转æ¢ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:380 +#: commands/dropcmds.c:419 #, c-format msgid "trigger \"%s\" for relation \"%s\" does not exist, skipping" msgstr "关系 \"%2$s\"的触å‘器\"%1$s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:389 +#: commands/dropcmds.c:428 #, c-format msgid "policy \"%s\" for relation \"%s\" does not exist, skipping" msgstr "关系\"%2$s\"的策略\"%1$s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:396 +#: commands/dropcmds.c:435 #, c-format msgid "event trigger \"%s\" does not exist, skipping" msgstr "事件触å‘器 \"%s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡ " -#: commands/dropcmds.c:402 +#: commands/dropcmds.c:441 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist, skipping" msgstr "关系 \"%2$s\"的规则\"%1$s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:409 +#: commands/dropcmds.c:448 #, c-format msgid "foreign-data wrapper \"%s\" does not exist, skipping" msgstr "外部数æ®å°è£…器\"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:413 +#: commands/dropcmds.c:452 commands/foreigncmds.c:1400 #, c-format msgid "server \"%s\" does not exist, skipping" -msgstr "æœåС噍 \"%s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡ " +msgstr "æœåС噍 \"%s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/dropcmds.c:422 +#: commands/dropcmds.c:461 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\", skipping" msgstr "å¤„ç†æ–¹æ³• \"%2$s\" çš„æ“作符类 \"%1$s\" ä¸å­˜åœ¨, 跳过" -#: commands/dropcmds.c:434 +#: commands/dropcmds.c:473 #, c-format -msgid "" -"operator family \"%s\" does not exist for access method \"%s\", skipping" +msgid "operator family \"%s\" does not exist for access method \"%s\", skipping" msgstr "访问方法\"%2$s\"çš„æ“作符表 \"%1$s\" ä¸å­˜åœ¨, 跳过" -#: commands/event_trigger.c:182 +#: commands/dropcmds.c:480 +#, c-format +msgid "publication \"%s\" does not exist, skipping" +msgstr "å‘布 \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" + +#: commands/event_trigger.c:188 #, c-format msgid "permission denied to create event trigger \"%s\"" msgstr "创建事件触å‘器 \"%s\" æƒé™ä¸å¤Ÿ" -#: commands/event_trigger.c:184 +#: commands/event_trigger.c:190 #, c-format msgid "Must be superuser to create an event trigger." msgstr "åªæœ‰è¶…级用户能创建事件触å‘器." -#: commands/event_trigger.c:193 +#: commands/event_trigger.c:199 #, c-format msgid "unrecognized event name \"%s\"" msgstr "无法识别的事件å:\"%s\"" -#: commands/event_trigger.c:210 +#: commands/event_trigger.c:216 #, c-format msgid "unrecognized filter variable \"%s\"" msgstr "ä¸å¯è¯†åˆ«çš„过滤器å˜é‡ \"%s\"" -#: commands/event_trigger.c:265 +#: commands/event_trigger.c:271 #, c-format msgid "filter value \"%s\" not recognized for filter variable \"%s\"" msgstr "过滤器å˜é‡ \"%2$s\"中的过滤器值\"%1$s\"ä¸èƒ½è¯†åˆ«" #. translator: %s represents an SQL statement name -#: commands/event_trigger.c:271 commands/event_trigger.c:341 +#: commands/event_trigger.c:277 commands/event_trigger.c:347 #, c-format msgid "event triggers are not supported for %s" msgstr "事件触å‘器在%s中ä¸è¢«æ”¯æŒ" -#: commands/event_trigger.c:364 +#: commands/event_trigger.c:370 #, c-format msgid "filter variable \"%s\" specified more than once" msgstr "过滤器å˜é‡ \"%s\" 被指定多次" -#: commands/event_trigger.c:512 commands/event_trigger.c:556 -#: commands/event_trigger.c:649 +#: commands/event_trigger.c:520 commands/event_trigger.c:564 +#: commands/event_trigger.c:658 #, c-format msgid "event trigger \"%s\" does not exist" msgstr "过滤器å˜é‡\"%s\" ä¸å­˜åœ¨" -#: commands/event_trigger.c:617 +#: commands/event_trigger.c:626 #, c-format msgid "permission denied to change owner of event trigger \"%s\"" msgstr "修改事件触å‘器的 \"%s\" 的属主æƒé™ä¸å¤Ÿ" -#: commands/event_trigger.c:619 +#: commands/event_trigger.c:628 #, c-format msgid "The owner of an event trigger must be a superuser." msgstr "事件触å‘器的属主必须是超级用户." -#: commands/event_trigger.c:1442 +#: commands/event_trigger.c:1466 #, c-format msgid "%s can only be called in a sql_drop event trigger function" msgstr "%såªèƒ½åœ¨sql_drop事件触å‘器函数中被调用" -#: commands/event_trigger.c:1562 commands/event_trigger.c:1583 +#: commands/event_trigger.c:1586 commands/event_trigger.c:1607 #, c-format msgid "%s can only be called in a table_rewrite event trigger function" msgstr "%såªèƒ½åœ¨table_rewrite事件触å‘器函数中被调用" -#: commands/event_trigger.c:1993 +#: commands/event_trigger.c:2018 #, c-format msgid "%s can only be called in an event trigger function" msgstr "%såªèƒ½åœ¨äº‹ä»¶è§¦å‘器函数中被调用" -#: commands/explain.c:184 +#: commands/explain.c:193 #, c-format msgid "unrecognized value for EXPLAIN option \"%s\": \"%s\"" msgstr "用于EXPLAIN选项\"%s\"的值无效:\"%s\"" -#: commands/explain.c:190 +#: commands/explain.c:200 #, c-format msgid "unrecognized EXPLAIN option \"%s\"" msgstr "无法识别的EXPLAIN选项\"%s\"" -#: commands/explain.c:197 +#: commands/explain.c:208 #, c-format msgid "EXPLAIN option BUFFERS requires ANALYZE" msgstr "在EXPLAIN命令中BUFFERSå’ŒANALYZE选项需è¦ä¸€èµ·ä½¿ç”¨" -#: commands/explain.c:206 +#: commands/explain.c:217 #, c-format msgid "EXPLAIN option TIMING requires ANALYZE" msgstr "在EXPLAIN命令中的TIMING选项需è¦ANALYZE" -#: commands/extension.c:154 commands/extension.c:2718 +#: commands/extension.c:171 commands/extension.c:2918 #, c-format msgid "extension \"%s\" does not exist" msgstr "扩展 \"%s\" ä¸å­˜åœ¨" -#: commands/extension.c:253 commands/extension.c:262 commands/extension.c:274 -#: commands/extension.c:284 +#: commands/extension.c:270 commands/extension.c:279 commands/extension.c:291 +#: commands/extension.c:301 #, c-format msgid "invalid extension name: \"%s\"" msgstr "无效扩展å: \"%s\"" -#: commands/extension.c:254 +#: commands/extension.c:271 #, c-format msgid "Extension names must not be empty." msgstr "扩展åä¸èƒ½ä¸ºç©º." -#: commands/extension.c:263 +#: commands/extension.c:280 #, c-format msgid "Extension names must not contain \"--\"." msgstr "扩展åä¸èƒ½åŒ…å«\"--\"." -#: commands/extension.c:275 +#: commands/extension.c:292 #, c-format msgid "Extension names must not begin or end with \"-\"." msgstr "扩展åä¸èƒ½ä»¥ \"-\"作为开始或结æŸç¬¦." -#: commands/extension.c:285 +#: commands/extension.c:302 #, c-format msgid "Extension names must not contain directory separator characters." msgstr "扩展åä¸èƒ½åŒ…å«ç›®å½•分隔符." -#: commands/extension.c:300 commands/extension.c:309 commands/extension.c:318 -#: commands/extension.c:328 +#: commands/extension.c:317 commands/extension.c:326 commands/extension.c:335 +#: commands/extension.c:345 #, c-format msgid "invalid extension version name: \"%s\"" msgstr "无效的扩展版本å: \"%s\"" -#: commands/extension.c:301 +#: commands/extension.c:318 #, c-format msgid "Version names must not be empty." msgstr "版本åä¸èƒ½ä¸ºç©º." -#: commands/extension.c:310 +#: commands/extension.c:327 #, c-format msgid "Version names must not contain \"--\"." msgstr "版本åä¸èƒ½åŒ…å«\"--\"." -#: commands/extension.c:319 +#: commands/extension.c:336 #, c-format msgid "Version names must not begin or end with \"-\"." msgstr "版本åä¸èƒ½ä»¥ \"-\"作为开始或结æŸç¬¦." -#: commands/extension.c:329 +#: commands/extension.c:346 #, c-format msgid "Version names must not contain directory separator characters." msgstr "版本åä¸èƒ½åŒ…å«ç›®å½•分隔符." -#: commands/extension.c:479 +#: commands/extension.c:496 #, c-format msgid "could not open extension control file \"%s\": %m" msgstr "无法打开扩展控制文件 \"%s\": %m" -#: commands/extension.c:501 commands/extension.c:511 +#: commands/extension.c:518 commands/extension.c:528 #, c-format msgid "parameter \"%s\" cannot be set in a secondary extension control file" msgstr "第二扩展控制文件中, æ— æ³•è®¾ç½®å‚æ•° \"%s\"" -#: commands/extension.c:550 +#: commands/extension.c:550 commands/extension.c:558 utils/misc/guc.c:6554 +#, c-format +msgid "parameter \"%s\" requires a Boolean value" +msgstr "傿•° \"%s\" 需è¦ä¸€ä¸ªå¸ƒå°”值" + +#: commands/extension.c:567 #, c-format msgid "\"%s\" is not a valid encoding name" msgstr "\"%s\" 是一个无效编ç å" -#: commands/extension.c:564 +#: commands/extension.c:581 #, c-format msgid "parameter \"%s\" must be a list of extension names" msgstr "傿•° \"%s\"å¿…é¡»æ˜¯ä¸€ä¸ªåŒ…å«æ‰©å±•å的列表" -#: commands/extension.c:571 +#: commands/extension.c:588 #, c-format msgid "unrecognized parameter \"%s\" in file \"%s\"" msgstr "文件\"%2$s\"ä¸­å‡ºçŽ°æœªè¯†åˆ«çš„å‚æ•° \"%1$s\"" -#: commands/extension.c:580 +#: commands/extension.c:597 #, c-format msgid "parameter \"schema\" cannot be specified when \"relocatable\" is true" msgstr "当\"relocatable\"ä¸ºçœŸæ—¶ï¼Œå‚æ•°\"schema\"ä¸å…许被指定" -#: commands/extension.c:721 +#: commands/extension.c:762 #, c-format -msgid "" -"transaction control statements are not allowed within an extension script" +msgid "transaction control statements are not allowed within an extension script" msgstr "扩展脚本中ä¸å…许出现事务控制语å¥" -#: commands/extension.c:789 +#: commands/extension.c:808 #, c-format msgid "permission denied to create extension \"%s\"" msgstr "创建扩展 \"%s\" æƒé™ä¸å¤Ÿ" -#: commands/extension.c:791 +#: commands/extension.c:810 #, c-format msgid "Must be superuser to create this extension." msgstr "åªæœ‰è¶…级用户能创建扩展." -#: commands/extension.c:795 +#: commands/extension.c:814 #, c-format msgid "permission denied to update extension \"%s\"" msgstr "更新扩展 \"%s\" æƒé™ä¸å¤Ÿ" -#: commands/extension.c:797 +#: commands/extension.c:816 #, c-format msgid "Must be superuser to update this extension." msgstr "åªæœ‰è¶…级用户能更新扩展." -#: commands/extension.c:1079 +#: commands/extension.c:1100 #, c-format -msgid "" -"extension \"%s\" has no update path from version \"%s\" to version \"%s\"" +msgid "extension \"%s\" has no update path from version \"%s\" to version \"%s\"" msgstr "扩展 \"%s\" 没有从版本\"%s\"到版本\"%s\"的更新路径" -#: commands/extension.c:1261 commands/extension.c:2778 +#: commands/extension.c:1307 commands/extension.c:2979 #, c-format msgid "version to install must be specified" msgstr "必须指定安装版本" -#: commands/extension.c:1278 +#: commands/extension.c:1329 #, c-format msgid "FROM version must be different from installation target version \"%s\"" msgstr "FROM 版本与安装的目标版本 \"%s\" å¿…é¡»ä¸åŒ" -#: commands/extension.c:1343 +#: commands/extension.c:1394 +#, c-format +msgid "extension \"%s\" has no installation script nor update path for version \"%s\"" +msgstr "扩展 \"%s\" 没有安装脚本,也没有版本\"%s\"的更新路径" + +#: commands/extension.c:1429 #, c-format msgid "extension \"%s\" must be installed in schema \"%s\"" msgstr "扩展\"%s\"å·²ç»å®‰è£…到模å¼\"%s\"中了" -#: commands/extension.c:1435 +#: commands/extension.c:1589 #, c-format -#| msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" msgid "cyclic dependency detected between extensions \"%s\" and \"%s\"" msgstr "在扩展 \"%s\" å’Œ \"%s\" 之间检测到循环ä¾èµ–" -#: commands/extension.c:1440 +#: commands/extension.c:1594 #, c-format -#| msgid "invalid extension name: \"%s\"" msgid "installing required extension \"%s\"" msgstr "正在安装所需的扩展 \"%s\"" -#: commands/extension.c:1468 commands/extension.c:2923 +#: commands/extension.c:1618 #, c-format msgid "required extension \"%s\" is not installed" msgstr "所需è¦çš„æ‰©å±•\"%s\"没被安装" -#: commands/extension.c:1470 +#: commands/extension.c:1621 #, c-format -#| msgid "Use ALTER ... CASCADE to alter the typed tables too." -msgid "Use CREATE EXTENSION CASCADE to install required extensions too." -msgstr "请使用 CREATE EXTENSION CASCADE 安装所需的扩展。" +msgid "Use CREATE EXTENSION ... CASCADE to install required extensions too." +msgstr "请使用 CREATE EXTENSION ... CASCADE 安装所需的扩展。" -#: commands/extension.c:1534 +#: commands/extension.c:1658 #, c-format msgid "extension \"%s\" already exists, skipping" msgstr "扩展 \"%s\" å·²ç»å­˜åœ¨,跳过" -#: commands/extension.c:1541 +#: commands/extension.c:1665 #, c-format msgid "extension \"%s\" already exists" msgstr "扩展 \"%s\" å·²ç»å­˜åœ¨" -#: commands/extension.c:1552 +#: commands/extension.c:1676 #, c-format msgid "nested CREATE EXTENSION is not supported" msgstr "䏿”¯æŒåµŒå¥—çš„CREATE EXTENSION" -#: commands/extension.c:1680 +#: commands/extension.c:1860 #, c-format msgid "cannot drop extension \"%s\" because it is being modified" msgstr "无法删除扩展\"%s\",因为它正被修改中" -#: commands/extension.c:2151 -#, c-format -msgid "" -"pg_extension_config_dump() can only be called from an SQL script executed by " -"CREATE EXTENSION" +#: commands/extension.c:2362 +#, fuzzy, c-format +#| msgid "pg_extension_config_dump() can only be called from an SQL script executed by CREATE EXTENSION" +msgid "%s can only be called from an SQL script executed by CREATE EXTENSION" msgstr "pg_extension_config_dump() åªèƒ½åœ¨æ‰§è¡Œ CREATE EXTENSIONçš„SQL脚本里调用" -#: commands/extension.c:2163 +#: commands/extension.c:2374 #, c-format msgid "OID %u does not refer to a table" msgstr "OID %u没有引用任何表" -#: commands/extension.c:2168 +#: commands/extension.c:2379 #, c-format msgid "table \"%s\" is not a member of the extension being created" msgstr "表\"%s\"䏿˜¯è¢«åˆ›å»ºçš„任何一个扩展的æˆå‘˜" -#: commands/extension.c:2533 +#: commands/extension.c:2733 #, c-format -msgid "" -"cannot move extension \"%s\" into schema \"%s\" because the extension " -"contains the schema" +msgid "cannot move extension \"%s\" into schema \"%s\" because the extension contains the schema" msgstr "ä¸èƒ½å°†æ‰©å±• \"%s\" è½¬ç§»åˆ°æ¨¡å¼ \"%s\" é‡Œï¼Œå› ä¸ºè¯¥æ‰©å±•å·²ç»æ‹¥æœ‰è¯¥æ¨¡å¼" -#: commands/extension.c:2573 commands/extension.c:2636 +#: commands/extension.c:2774 commands/extension.c:2837 #, c-format msgid "extension \"%s\" does not support SET SCHEMA" msgstr "扩展 \"%s\" 䏿”¯æŒSET SCHEMAæ“作" -#: commands/extension.c:2638 +#: commands/extension.c:2839 #, c-format msgid "%s is not in the extension's schema \"%s\"" msgstr "扩展模å¼\"%2$s\"中ä¸å­˜åœ¨%1$s" -#: commands/extension.c:2698 +#: commands/extension.c:2898 #, c-format msgid "nested ALTER EXTENSION is not supported" msgstr "䏿”¯æŒä½¿ç”¨åµŒå¥—çš„ALTER EXTENSION" -#: commands/extension.c:2789 +#: commands/extension.c:2990 #, c-format msgid "version \"%s\" of extension \"%s\" is already installed" msgstr "扩展\"%2$s\"的版本\"%1$s\"å·²ç»å®‰è£…" -#: commands/extension.c:3040 +#: commands/extension.c:3241 #, c-format -msgid "" -"cannot add schema \"%s\" to extension \"%s\" because the schema contains the " -"extension" +msgid "cannot add schema \"%s\" to extension \"%s\" because the schema contains the extension" msgstr "无法为扩展\"%2$s\"添加模å¼\"%1$s\",因为该模å¼å·²ç»åŒ…嫿­¤æ‰©å±•" -#: commands/extension.c:3058 +#: commands/extension.c:3269 #, c-format msgid "%s is not a member of extension \"%s\"" msgstr "%s䏿˜¯æ‰©å±•çš„æˆå‘˜\"%s\"" -#: commands/extension.c:3114 +#: commands/extension.c:3335 #, c-format msgid "file \"%s\" is too large" msgstr "文件\"%s\"太大" -#: commands/foreigncmds.c:150 commands/foreigncmds.c:159 +#: commands/foreigncmds.c:151 commands/foreigncmds.c:160 #, c-format msgid "option \"%s\" not found" msgstr "没有找到选项 \"%s\" " -#: commands/foreigncmds.c:169 +#: commands/foreigncmds.c:170 #, c-format msgid "option \"%s\" provided more than once" msgstr "选项 \"%s\" 被æä¾›äº†å¤šæ¬¡" -#: commands/foreigncmds.c:223 commands/foreigncmds.c:231 +#: commands/foreigncmds.c:224 commands/foreigncmds.c:232 #, c-format msgid "permission denied to change owner of foreign-data wrapper \"%s\"" msgstr "修改外部数æ®å°è£…器的 \"%s\" 的属主æƒé™ä¸å¤Ÿ" -#: commands/foreigncmds.c:225 +#: commands/foreigncmds.c:226 #, c-format msgid "Must be superuser to change owner of a foreign-data wrapper." msgstr "åªæœ‰è¶…级用户å¯ä»¥æ›´æ”¹å¤–部数æ®å°è£…器的属主" -#: commands/foreigncmds.c:233 +#: commands/foreigncmds.c:234 #, c-format msgid "The owner of a foreign-data wrapper must be a superuser." msgstr "外部数æ®å°è£…器的属主必须是超级用户." -#: commands/foreigncmds.c:292 commands/foreigncmds.c:709 foreign/foreign.c:777 +#: commands/foreigncmds.c:294 commands/foreigncmds.c:715 foreign/foreign.c:701 #, c-format msgid "foreign-data wrapper \"%s\" does not exist" msgstr "外部数æ®å°è£…器 \"%s\" ä¸å­˜åœ¨" -#: commands/foreigncmds.c:584 +#: commands/foreigncmds.c:588 #, c-format msgid "permission denied to create foreign-data wrapper \"%s\"" msgstr "创建外部数æ®å°è£…器\"%s\"失败" -#: commands/foreigncmds.c:586 +#: commands/foreigncmds.c:590 #, c-format msgid "Must be superuser to create a foreign-data wrapper." msgstr "åªæœ‰è¶…级用户能创建外部数æ®å°è£…器" -#: commands/foreigncmds.c:699 +#: commands/foreigncmds.c:705 #, c-format msgid "permission denied to alter foreign-data wrapper \"%s\"" msgstr "ä¸å…许修改外部数æ®å°è£…器\"%s\"" -#: commands/foreigncmds.c:701 +#: commands/foreigncmds.c:707 #, c-format msgid "Must be superuser to alter a foreign-data wrapper." msgstr "åªæœ‰è¶…级用户æ‰èƒ½ä¿®æ”¹ä¸€ä¸ªå¤–部数æ®å°è£…器." -#: commands/foreigncmds.c:732 +#: commands/foreigncmds.c:738 #, c-format -msgid "" -"changing the foreign-data wrapper handler can change behavior of existing " -"foreign tables" +msgid "changing the foreign-data wrapper handler can change behavior of existing foreign tables" msgstr "改å˜å¤–部数æ®å°è£…器å¯èƒ½ä¼šæ”¹å˜çŽ°å­˜çš„å¤–éƒ¨è¡¨çš„è¡Œä¸º" -#: commands/foreigncmds.c:747 +#: commands/foreigncmds.c:753 #, c-format -msgid "" -"changing the foreign-data wrapper validator can cause the options for " -"dependent objects to become invalid" +msgid "changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid" msgstr "改å˜å¤–部数æ®å°è£…器的验è¯èƒ½å¤Ÿä½¿æ‰€å®ƒä¾èµ–对象的选项å˜ä¸ºæ— æ•ˆ" -#: commands/foreigncmds.c:1169 +#: commands/foreigncmds.c:899 #, c-format -msgid "user mapping \"%s\" already exists for server %s" +msgid "server \"%s\" already exists, skipping" +msgstr "æœåŠ¡ \"%s\" 已存在, 跳过" + +#: commands/foreigncmds.c:1187 +#, fuzzy, c-format +#| msgid "user mapping for \"%s\" already exists for server %s, skipping" +msgid "user mapping for \"%s\" already exists for server \"%s\", skipping" +msgstr "对于æœåС噍%2$s,用户映射\"%1$s\"已存在, 跳过" + +#: commands/foreigncmds.c:1197 +#, fuzzy, c-format +#| msgid "user mapping for \"%s\" already exists for server %s" +msgid "user mapping for \"%s\" already exists for server \"%s\"" msgstr "对于æœåС噍%2$s,用户映射\"%1$s\"已存在 " -#: commands/foreigncmds.c:1267 commands/foreigncmds.c:1388 -#, c-format -msgid "user mapping \"%s\" does not exist for the server" +#: commands/foreigncmds.c:1297 commands/foreigncmds.c:1414 +#, fuzzy, c-format +#| msgid "user mapping for \"%s\" does not exist for the server" +msgid "user mapping for \"%s\" does not exist for server \"%s\"" msgstr "对于æœåС噍æ¥è¯´ï¼Œç”¨æˆ·æ˜ å°„\"%s\"ä¸å­˜åœ¨" -#: commands/foreigncmds.c:1375 -#, c-format -msgid "server does not exist, skipping" -msgstr "æœåС噍ä¸å­˜åœ¨,跳过" - -#: commands/foreigncmds.c:1393 -#, c-format -msgid "user mapping \"%s\" does not exist for the server, skipping" +#: commands/foreigncmds.c:1419 +#, fuzzy, c-format +#| msgid "user mapping for \"%s\" does not exist for the server, skipping" +msgid "user mapping for \"%s\" does not exist for server \"%s\", skipping" msgstr "用户映射\"%s\"对于æœåС噍æ¥è¯´ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/foreigncmds.c:1545 foreign/foreign.c:467 +#: commands/foreigncmds.c:1570 foreign/foreign.c:389 #, c-format msgid "foreign-data wrapper \"%s\" has no handler" msgstr "外部数æ®å°è£…器 \"%s\"没有处ç†å‡½æ•°" -#: commands/foreigncmds.c:1551 +#: commands/foreigncmds.c:1576 #, c-format msgid "foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA" msgstr "外部数æ®åŒ…装器\"%s\"䏿”¯æŒIMPORT FOREIGN SCHEMA" -#: commands/foreigncmds.c:1644 +#: commands/foreigncmds.c:1679 #, c-format msgid "importing foreign table \"%s\"" msgstr "导入外部表\"%s\"" -#: commands/functioncmds.c:99 +#: commands/functioncmds.c:103 #, c-format msgid "SQL function cannot return shell type %s" msgstr "SQL 函数ä¸èƒ½è¿”回 shell 类型 %s" -#: commands/functioncmds.c:104 +#: commands/functioncmds.c:108 #, c-format msgid "return type %s is only a shell" msgstr "返回类型 %s åªæ˜¯ä¸€ä¸ª shell" -#: commands/functioncmds.c:134 parser/parse_type.c:337 +#: commands/functioncmds.c:138 parser/parse_type.c:337 #, c-format msgid "type modifier cannot be specified for shell type \"%s\"" msgstr "ä¸èƒ½ä¸ºshell类型\"%s\"指定类型修改器" -#: commands/functioncmds.c:140 +#: commands/functioncmds.c:144 #, c-format msgid "type \"%s\" is not yet defined" msgstr "类型 \"%s\" 仿²¡è¢«å®šä¹‰" -#: commands/functioncmds.c:141 +#: commands/functioncmds.c:145 #, c-format msgid "Creating a shell type definition." msgstr "创建一个 shell 类型定义." -#: commands/functioncmds.c:239 +#: commands/functioncmds.c:237 #, c-format msgid "SQL function cannot accept shell type %s" msgstr "SQL 函数ä¸èƒ½æŽ¥æ”¶ shell 类型 %s" -#: commands/functioncmds.c:245 +#: commands/functioncmds.c:243 #, c-format msgid "aggregate cannot accept shell type %s" msgstr "èšé›†å‡½æ•°ä¸èƒ½æŽ¥æ”¶ shell 类型 %s" -#: commands/functioncmds.c:250 +#: commands/functioncmds.c:248 #, c-format msgid "argument type %s is only a shell" msgstr "傿•°ç±»åž‹ %s åªæ˜¯ä¸€ä¸ª shell" -#: commands/functioncmds.c:260 +#: commands/functioncmds.c:258 #, c-format msgid "type %s does not exist" msgstr "类型 %s ä¸å­˜åœ¨" -#: commands/functioncmds.c:274 +#: commands/functioncmds.c:272 #, c-format msgid "aggregates cannot accept set arguments" msgstr "èšåˆå‡½æ•°ä¸èƒ½æŽ¥å—集åˆç±»åž‹å‚æ•°" -#: commands/functioncmds.c:278 +#: commands/functioncmds.c:276 +#, c-format +msgid "procedures cannot accept set arguments" +msgstr "过程ä¸èƒ½æŽ¥å—集åˆç±»åž‹å‚æ•°" + +#: commands/functioncmds.c:280 #, c-format msgid "functions cannot accept set arguments" msgstr "函数ä¸èƒ½æŽ¥æ”¶è®¾å®šå‚æ•°" #: commands/functioncmds.c:288 #, c-format +msgid "procedures cannot have OUT arguments" +msgstr "过程ä¸èƒ½æœ‰è¾“å‡ºå‚æ•°" + +#: commands/functioncmds.c:289 +#, c-format +msgid "INOUT arguments are permitted." +msgstr "å…è®¸è¾“å…¥è¾“å‡ºå‚æ•°." + +#: commands/functioncmds.c:299 +#, c-format msgid "VARIADIC parameter must be the last input parameter" msgstr "傿•°VARIADIC必须是最åŽä¸€ä¸ªè¾“入傿•°" -#: commands/functioncmds.c:316 +#: commands/functioncmds.c:329 #, c-format msgid "VARIADIC parameter must be an array" msgstr "傿•°VARIADIC必须是一个数组" -#: commands/functioncmds.c:356 +#: commands/functioncmds.c:369 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "å¤šæ¬¡ä½¿ç”¨å‚æ•°åç§° \"%s\"" -#: commands/functioncmds.c:371 +#: commands/functioncmds.c:384 #, c-format msgid "only input parameters can have default values" msgstr "åªæœ‰è¾“入傿•°æ‰èƒ½æœ‰ç¼ºçœå€¼" -#: commands/functioncmds.c:386 +#: commands/functioncmds.c:399 #, c-format msgid "cannot use table references in parameter default value" msgstr "åœ¨å‚æ•°ç¼ºçœå€¼ä¸­ä¸èƒ½ä½¿ç”¨è¡¨å¼•用" -#: commands/functioncmds.c:410 +#: commands/functioncmds.c:423 #, c-format msgid "input parameters after one with a default value must also have defaults" msgstr "在带有缺çœå€¼å‚æ•°åŽé¢çš„è¾“å…¥å‚æ•°å¿…须也带有缺çœå€¼." -#: commands/functioncmds.c:701 +#: commands/functioncmds.c:575 commands/functioncmds.c:766 +#, c-format +msgid "invalid attribute in procedure definition" +msgstr "过程定义中的属性无效" + +#: commands/functioncmds.c:671 +#, fuzzy, c-format +#| msgid "function %s must return type %s" +msgid "support function %s must return type %s" +msgstr "函数 %s 必须返回类型 %s" + +#: commands/functioncmds.c:682 +#, fuzzy, c-format +#| msgid "must be superuser to set grantor" +msgid "must be superuser to specify a support function" +msgstr "åªæœ‰è¶…级用户能设置授æƒè€…" + +#: commands/functioncmds.c:798 #, c-format msgid "no function body specified" msgstr "没有指定函数体" -#: commands/functioncmds.c:711 +#: commands/functioncmds.c:808 #, c-format msgid "no language specified" msgstr "没有指定语言" -#: commands/functioncmds.c:736 commands/functioncmds.c:1243 +#: commands/functioncmds.c:833 commands/functioncmds.c:1317 #, c-format msgid "COST must be positive" msgstr "COST必需为正数" -#: commands/functioncmds.c:744 commands/functioncmds.c:1251 +#: commands/functioncmds.c:841 commands/functioncmds.c:1325 #, c-format msgid "ROWS must be positive" msgstr "ROWS必需为正数" -#: commands/functioncmds.c:785 -#, c-format -msgid "unrecognized function attribute \"%s\" ignored" -msgstr "忽略未认å¯çš„函数属性 \"%s\"" - -#: commands/functioncmds.c:836 +#: commands/functioncmds.c:895 #, c-format msgid "only one AS item needed for language \"%s\"" msgstr "对于 \"%s\" 语言åªèƒ½è¦æ±‚一个 AS 项目" -#: commands/functioncmds.c:929 commands/functioncmds.c:2119 -#: commands/proclang.c:563 +#: commands/functioncmds.c:993 commands/functioncmds.c:2227 +#: commands/proclang.c:568 #, c-format msgid "language \"%s\" does not exist" msgstr "语言 \"%s\" ä¸å­˜åœ¨" -#: commands/functioncmds.c:931 commands/functioncmds.c:2121 +#: commands/functioncmds.c:995 commands/functioncmds.c:2229 #, c-format -msgid "Use CREATE LANGUAGE to load the language into the database." -msgstr "使用CREATE LANGUAGE呿•°æ®åº“加载语言." +msgid "Use CREATE EXTENSION to load the language into the database." +msgstr "使用CREATE EXTENSION呿•°æ®åº“加载语言." -#: commands/functioncmds.c:966 commands/functioncmds.c:1235 +#: commands/functioncmds.c:1030 commands/functioncmds.c:1309 #, c-format msgid "only superuser can define a leakproof function" msgstr "åªæœ‰è¶…级用户æ‰èƒ½å®šä¹‰ä¸€ä¸ªå¯†å°å‡½æ•°" -#: commands/functioncmds.c:1010 +#: commands/functioncmds.c:1079 #, c-format msgid "function result type must be %s because of OUT parameters" msgstr "因为OUT傿•°ï¼Œå‡½æ•°çš„结果类型必须是%s" -#: commands/functioncmds.c:1023 +#: commands/functioncmds.c:1092 #, c-format msgid "function result type must be specified" msgstr "必须指定函数返回结果的类型" -#: commands/functioncmds.c:1077 commands/functioncmds.c:1255 +#: commands/functioncmds.c:1144 commands/functioncmds.c:1329 #, c-format msgid "ROWS is not applicable when function does not return a set" msgstr "当转æ¢å‡½æ•°ä¸è¿”å›žä¸€ä¸ªç»„åˆæ—¶ï¼Œä¸é€‚用ROWS" -#: commands/functioncmds.c:1412 +#: commands/functioncmds.c:1521 #, c-format msgid "source data type %s is a pseudo-type" msgstr "æºæ•°æ®ç±»åž‹ %s 是一个伪类型" -#: commands/functioncmds.c:1418 +#: commands/functioncmds.c:1527 #, c-format msgid "target data type %s is a pseudo-type" msgstr "目标数æ®ç±»åž‹ %s 是一个伪类型" -#: commands/functioncmds.c:1442 +#: commands/functioncmds.c:1551 #, c-format msgid "cast will be ignored because the source data type is a domain" msgstr "转æ¢å°†è¢«å¿½ç•¥ï¼Œå› ä¸ºæºæ•°æ®ç±»åž‹æ˜¯ä¸€ä¸ªåŸŸ" -#: commands/functioncmds.c:1447 +#: commands/functioncmds.c:1556 #, c-format msgid "cast will be ignored because the target data type is a domain" msgstr "转æ¢å°†è¢«å¿½ç•¥ï¼Œå› ä¸ºç›®æ ‡æ•°æ®ç±»åž‹æ˜¯ä¸€ä¸ªåŸŸ" -#: commands/functioncmds.c:1474 +#: commands/functioncmds.c:1581 #, c-format msgid "cast function must take one to three arguments" msgstr "类型转æ¢å‡½æ•°åªèƒ½å¸¦ä¸€åˆ°ä¸‰ä¸ªå‚æ•°" -#: commands/functioncmds.c:1478 +#: commands/functioncmds.c:1585 #, c-format -msgid "" -"argument of cast function must match or be binary-coercible from source data " -"type" +msgid "argument of cast function must match or be binary-coercible from source data type" msgstr "åŠŸèƒ½æŒ‡æ´¾å‡½æ•°çš„å‚æ•°å¿…é¡»åŒ¹é…æˆ–è€…æ˜¯æˆ–è€…ä»Žæºæ•°æ®ç±»åž‹ä»¥äºŒè¿›åˆ¶æ–¹å¼å¼ºåˆ¶è½¬æ¢çš„" -#: commands/functioncmds.c:1482 +#: commands/functioncmds.c:1589 #, c-format -msgid "second argument of cast function must be type integer" -msgstr "类型转æ¢å‡½æ•°çš„ç¬¬äºŒä¸ªå‚æ•°å¿…须为整型" +msgid "second argument of cast function must be type %s" +msgstr "类型转æ¢å‡½æ•°çš„ç¬¬äºŒä¸ªå‚æ•°å¿…须为类型%s" -#: commands/functioncmds.c:1486 +#: commands/functioncmds.c:1594 #, c-format -msgid "third argument of cast function must be type boolean" -msgstr "类型转æ¢å‡½æ•°çš„ç¬¬ä¸‰ä¸ªå‚æ•°å¿…须为布尔类型" +msgid "third argument of cast function must be type %s" +msgstr "类型转æ¢å‡½æ•°çš„ç¬¬ä¸‰ä¸ªå‚æ•°å¿…须为类型%s" -#: commands/functioncmds.c:1490 +#: commands/functioncmds.c:1599 #, c-format -msgid "" -"return data type of cast function must match or be binary-coercible to " -"target data type" +msgid "return data type of cast function must match or be binary-coercible to target data type" msgstr "功能指派函数的返回数æ®ç±»åž‹å¿…é¡»åŒ¹é…æˆ–者强制二进制方å¼è½¬æ¢çš„目标数æ®ç±»åž‹" -#: commands/functioncmds.c:1501 +#: commands/functioncmds.c:1610 #, c-format msgid "cast function must not be volatile" msgstr "类型转æ¢å‡½æ•°ä¸èƒ½ä¸ºæ˜“失的 (volatile)" -#: commands/functioncmds.c:1506 -#, c-format -msgid "cast function must not be an aggregate function" -msgstr "转æ¢å‡½æ•°ä¸èƒ½æ˜¯ä¸€ä¸ªèšåˆå‡½æ•°" - -#: commands/functioncmds.c:1510 +#: commands/functioncmds.c:1615 #, c-format -msgid "cast function must not be a window function" -msgstr "功能转æ¢å‡½æ•°ä¸èƒ½ä½¿çª—å£å‡½æ•°" +msgid "cast function must be a normal function" +msgstr "强转æ¢å‡½æ•°å¿…须是普通函数" -#: commands/functioncmds.c:1514 +#: commands/functioncmds.c:1619 #, c-format msgid "cast function must not return a set" msgstr "转æ¢å‡½æ•°ä¸èƒ½è¿”回一个组åˆ" -#: commands/functioncmds.c:1540 +#: commands/functioncmds.c:1645 #, c-format msgid "must be superuser to create a cast WITHOUT FUNCTION" msgstr "åªæœ‰è¶…级用户能创建一个éžå‡½æ•°çš„类型转æ¢" -#: commands/functioncmds.c:1555 +#: commands/functioncmds.c:1660 #, c-format msgid "source and target data types are not physically compatible" msgstr "æºæ•°æ®ç±»åž‹å’Œç›®æ ‡æ•°æ®ç±»åž‹ä¸ç›¸å®¹" -#: commands/functioncmds.c:1570 +#: commands/functioncmds.c:1675 #, c-format msgid "composite data types are not binary-compatible" msgstr "ç»„åˆæ•°æ®ç±»åž‹ä¸æ˜¯äºŒè¿›åˆ¶å…¼å®¹" -#: commands/functioncmds.c:1576 +#: commands/functioncmds.c:1681 #, c-format msgid "enum data types are not binary-compatible" msgstr "枚举数æ®ç±»åž‹ä¸æ˜¯äºŒè¿›åˆ¶å…¼å®¹" -#: commands/functioncmds.c:1582 +#: commands/functioncmds.c:1687 #, c-format msgid "array data types are not binary-compatible" msgstr "数组数æ®ç±»åž‹ä¸æ˜¯äºŒè¿›åˆ¶å…¼å®¹çš„" -#: commands/functioncmds.c:1599 +#: commands/functioncmds.c:1704 #, c-format msgid "domain data types must not be marked binary-compatible" msgstr "域数æ®ç±»åž‹ä¸èƒ½æ ‡ä¸ºäºŒè¿›åˆ¶å…¼å®¹" -#: commands/functioncmds.c:1609 +#: commands/functioncmds.c:1714 #, c-format msgid "source data type and target data type are the same" msgstr "æºæ•°æ®ç±»åž‹å’Œç›®æ ‡æ•°æ®ç±»åž‹ç›¸åŒ" -#: commands/functioncmds.c:1642 +#: commands/functioncmds.c:1747 #, c-format msgid "cast from type %s to type %s already exists" msgstr "类型 %s 到 %s 的转æ¢å·²ç»å­˜åœ¨" -#: commands/functioncmds.c:1717 +#: commands/functioncmds.c:1822 #, c-format msgid "cast from type %s to type %s does not exist" msgstr "类型 %s 到类型 %s 的转æ¢ä¸å­˜åœ¨" -#: commands/functioncmds.c:1756 +#: commands/functioncmds.c:1861 #, c-format msgid "transform function must not be volatile" msgstr "转æ¢å‡½æ•°ä¸èƒ½æ˜¯ä¸ç¨³å®šçš„ (volatile)" -#: commands/functioncmds.c:1760 -#, c-format -msgid "transform function must not be an aggregate function" -msgstr "转æ¢å‡½æ•°ä¸èƒ½æ˜¯ä¸€ä¸ªèšé›†å‡½æ•°" - -#: commands/functioncmds.c:1764 +#: commands/functioncmds.c:1865 #, c-format -msgid "transform function must not be a window function" -msgstr "转æ¢å‡½æ•°ä¸èƒ½æ˜¯ä¸€ä¸ªçª—å£å‡½æ•°" +msgid "transform function must be a normal function" +msgstr "转æ¢å‡½æ•°å¿…须是普通函数" -#: commands/functioncmds.c:1768 +#: commands/functioncmds.c:1869 #, c-format msgid "transform function must not return a set" msgstr "转æ¢å‡½æ•°ä¸èƒ½è¿”回一个集åˆ" -#: commands/functioncmds.c:1772 +#: commands/functioncmds.c:1873 #, c-format msgid "transform function must take one argument" msgstr "转æ¢å‡½æ•°å¿…é¡»æœ‰ä¸€ä¸ªå‚æ•°" -#: commands/functioncmds.c:1776 +#: commands/functioncmds.c:1877 #, c-format -msgid "first argument of transform function must be type \"internal\"" -msgstr "转æ¢å‡½æ•°çš„ç¬¬ä¸€ä¸ªå‚æ•°å¿…须为类型\"internal\"" +msgid "first argument of transform function must be type %s" +msgstr "转æ¢å‡½æ•°çš„ç¬¬ä¸€ä¸ªå‚æ•°å¿…须为类型%s" -#: commands/functioncmds.c:1813 +#: commands/functioncmds.c:1915 #, c-format msgid "data type %s is a pseudo-type" msgstr "æ•°æ®ç±»åž‹ %s是一个伪类型" -#: commands/functioncmds.c:1819 +#: commands/functioncmds.c:1921 #, c-format msgid "data type %s is a domain" msgstr "æ•°æ®ç±»åž‹%s是一个域" -#: commands/functioncmds.c:1859 +#: commands/functioncmds.c:1961 #, c-format -msgid "return data type of FROM SQL function must be \"internal\"" -msgstr "FROM SQL函数的返回数æ®ç±»åž‹å¿…须是\"internal\"" +msgid "return data type of FROM SQL function must be %s" +msgstr "FROM SQL函数的返回数æ®ç±»åž‹å¿…须是%s" -#: commands/functioncmds.c:1884 +#: commands/functioncmds.c:1987 #, c-format msgid "return data type of TO SQL function must be the transform data type" msgstr "TO SQL函数的返回数æ®ç±»åž‹å¿…é¡»æ˜¯è½¬æ¢æ•°æ®ç±»åž‹" -#: commands/functioncmds.c:1911 +#: commands/functioncmds.c:2016 #, c-format msgid "transform for type %s language \"%s\" already exists" msgstr "类型%s语言\"%s\"的转æ¢å·²ç»å­˜åœ¨" -#: commands/functioncmds.c:2002 +#: commands/functioncmds.c:2108 #, c-format msgid "transform for type %s language \"%s\" does not exist" msgstr "类型%s语言\"%s\"的转æ¢ä¸å­˜åœ¨" -#: commands/functioncmds.c:2053 +#: commands/functioncmds.c:2159 #, c-format msgid "function %s already exists in schema \"%s\"" msgstr "åœ¨æ¨¡å¼ \"%2$s\" 中函数 %1$s å·²ç»å­˜åœ¨" -#: commands/functioncmds.c:2106 +#: commands/functioncmds.c:2214 #, c-format msgid "no inline code specified" msgstr "没有指定内è”代ç " -#: commands/functioncmds.c:2151 +#: commands/functioncmds.c:2260 #, c-format msgid "language \"%s\" does not support inline code execution" msgstr "语言 \"%s\" 䏿”¯æŒæ‰§è¡Œå†…è”代ç " -#: commands/indexcmds.c:349 +#: commands/functioncmds.c:2372 +#, c-format +msgid "cannot pass more than %d argument to a procedure" +msgid_plural "cannot pass more than %d arguments to a procedure" +msgstr[0] "å‘è¿‡ç¨‹ä¼ é€’çš„å‚æ•°ä¸å¤šäºŽ%d个" + +#: commands/indexcmds.c:536 #, c-format msgid "must specify at least one column" msgstr "必需至少指定一个字段" -#: commands/indexcmds.c:353 +#: commands/indexcmds.c:540 #, c-format msgid "cannot use more than %d columns in an index" msgstr "在一个索引中ä¸èƒ½ä½¿ç”¨è¶…过 %d 个字段" -#: commands/indexcmds.c:384 +#: commands/indexcmds.c:579 #, c-format msgid "cannot create index on foreign table \"%s\"" msgstr "外部表\"%s\"上无法创建索引" -#: commands/indexcmds.c:399 +#: commands/indexcmds.c:604 +#, c-format +msgid "cannot create index on partitioned table \"%s\" concurrently" +msgstr "æ— æ³•åŒæ—¶åœ¨åˆ†åŒºè¡¨\"%s\"上创建索引" + +#: commands/indexcmds.c:609 +#, c-format +msgid "cannot create exclusion constraints on partitioned table \"%s\"" +msgstr "无法在分区表\"%s\"上创建排他约æŸ" + +#: commands/indexcmds.c:619 #, c-format msgid "cannot create indexes on temporary tables of other sessions" msgstr "ä¸èƒ½åœ¨å…¶ä»–会è¯çš„临时表上创建索引" -#: commands/indexcmds.c:454 commands/tablecmds.c:545 commands/tablecmds.c:9599 +#: commands/indexcmds.c:657 commands/tablecmds.c:673 commands/tablespace.c:1155 +#, fuzzy, c-format +#| msgid "cannot assign new default tablespace \"%s\"" +msgid "cannot specify default tablespace for partitioned relations" +msgstr "æ— æ³•åˆ†é…æ–°çš„默认表空间 \"%s\"" + +#: commands/indexcmds.c:689 commands/tablecmds.c:704 commands/tablecmds.c:12213 +#: commands/tablecmds.c:12325 #, c-format msgid "only shared relations can be placed in pg_global tablespace" msgstr "在pg_global表空间中åªèƒ½æ”¾ç½®å…±äº«å…³ç³»" -#: commands/indexcmds.c:487 +#: commands/indexcmds.c:722 #, c-format msgid "substituting access method \"gist\" for obsolete method \"rtree\"" msgstr "将已作废的方法\"rtree\"替æ¢ä¸ºè®¿é—®æ–¹æ³•\"gist\" " -#: commands/indexcmds.c:505 -#, c-format -msgid "hash indexes are not WAL-logged and their use is discouraged" -msgstr "哈希索引ä¸è¢«WAL记录并且ä¸é¼“励使用它们" - -#: commands/indexcmds.c:510 +#: commands/indexcmds.c:743 #, c-format msgid "access method \"%s\" does not support unique indexes" msgstr "å­˜å–æ–¹æ³• \"%s\" 䏿”¯æŒå”¯ä¸€ç´¢å¼•" -#: commands/indexcmds.c:515 +#: commands/indexcmds.c:748 +#, c-format +msgid "access method \"%s\" does not support included columns" +msgstr "å­˜å–æ–¹æ³• \"%s\" 䏿”¯æŒåŒ…å«çš„列" + +#: commands/indexcmds.c:753 #, c-format msgid "access method \"%s\" does not support multicolumn indexes" msgstr "å­˜å–æ–¹æ³• \"%s\" 䏿”¯æŒå¤šå­—段索引" -#: commands/indexcmds.c:520 +#: commands/indexcmds.c:758 #, c-format msgid "access method \"%s\" does not support exclusion constraints" msgstr "访问方法 \"%s\" 䏿”¯æŒæŽ’他约æŸ" -#: commands/indexcmds.c:590 commands/indexcmds.c:610 +#: commands/indexcmds.c:870 +#, c-format +msgid "unsupported %s constraint with partition key definition" +msgstr "䏿”¯æŒå¸¦åˆ†åŒºé”®å®šä¹‰çš„%s约æŸ" + +#: commands/indexcmds.c:872 +#, c-format +msgid "%s constraints cannot be used when partition keys include expressions." +msgstr "当分区键包å«è¡¨è¾¾å¼æ—¶ï¼Œä¸èƒ½ä½¿ç”¨%s约æŸ." + +#: commands/indexcmds.c:890 +#, c-format +msgid "insufficient columns in %s constraint definition" +msgstr "%s约æŸå®šä¹‰ä¸­çš„列ä¸è¶³" + +#: commands/indexcmds.c:892 +#, c-format +msgid "%s constraint on table \"%s\" lacks column \"%s\" which is part of the partition key." +msgstr "表\"%2$s\"上的约æŸ%1$s缺少列\"%3$s\",该列是分区键的一部分." + +#: commands/indexcmds.c:911 commands/indexcmds.c:930 #, c-format -#| msgid "concurrent index creation on system catalog tables is not supported" msgid "index creation on system columns is not supported" msgstr "䏿”¯æŒåœ¨ç³»ç»Ÿåˆ—上创建索引" -#: commands/indexcmds.c:635 +#: commands/indexcmds.c:955 #, c-format msgid "%s %s will create implicit index \"%s\" for table \"%s\"" msgstr "%1$s %2$s å°†è¦ä¸ºè¡¨ \"%4$s\" 创建éšå«ç´¢å¼• \"%3$s\"" -#: commands/indexcmds.c:982 +#: commands/indexcmds.c:1511 #, c-format msgid "functions in index predicate must be marked IMMUTABLE" msgstr "索引声明中函数必需标记为 IMMUTABLE" -#: commands/indexcmds.c:1048 parser/parse_utilcmd.c:1894 +#: commands/indexcmds.c:1577 parser/parse_utilcmd.c:2307 +#: parser/parse_utilcmd.c:2441 #, c-format msgid "column \"%s\" named in key does not exist" msgstr "在键字中命å的字段 \"%s\" ä¸å­˜åœ¨" -#: commands/indexcmds.c:1108 +#: commands/indexcmds.c:1601 parser/parse_utilcmd.c:1633 +#, c-format +msgid "expressions are not supported in included columns" +msgstr "包å«çš„åˆ—ä¸­ä¸æ”¯æŒè¡¨è¾¾å¼" + +#: commands/indexcmds.c:1642 #, c-format msgid "functions in index expression must be marked IMMUTABLE" msgstr "索引表达å¼ä¸­å‡½æ•°å¿…需标记为 IMMUTABLE" -#: commands/indexcmds.c:1131 +#: commands/indexcmds.c:1657 +#, c-format +msgid "including column does not support a collation" +msgstr "包å«çš„åˆ—ä¸æ”¯æŒæŽ’åºè§„则" + +# sql_help.h:61 +#: commands/indexcmds.c:1661 +#, c-format +msgid "including column does not support an operator class" +msgstr "包å«çš„åˆ—ä¸æ”¯æŒè¿ç®—符类" + +#: commands/indexcmds.c:1665 +#, c-format +msgid "including column does not support ASC/DESC options" +msgstr "包å«çš„åˆ—ä¸æ”¯æŒASC/DESC选项" + +#: commands/indexcmds.c:1669 +#, c-format +msgid "including column does not support NULLS FIRST/LAST options" +msgstr "包å«çš„åˆ—ä¸æ”¯æŒNULLS FIRST/LAST选项" + +#: commands/indexcmds.c:1696 #, c-format msgid "could not determine which collation to use for index expression" msgstr "索引表达å¼ä¸Šæ— æ³•确定使用哪个排åºè§„则" -#: commands/indexcmds.c:1139 commands/typecmds.c:827 parser/parse_expr.c:2559 -#: parser/parse_type.c:550 parser/parse_utilcmd.c:2820 utils/adt/misc.c:666 +#: commands/indexcmds.c:1704 commands/tablecmds.c:15096 commands/typecmds.c:837 +#: parser/parse_expr.c:2854 parser/parse_type.c:549 parser/parse_utilcmd.c:3514 +#: utils/adt/misc.c:490 #, c-format msgid "collations are not supported by type %s" msgstr "类型%sä¸èƒ½ä½¿ç”¨æŽ’åºè§„则" -#: commands/indexcmds.c:1177 +#: commands/indexcmds.c:1742 #, c-format msgid "operator %s is not commutative" msgstr "æ“作符%s䏿˜¯å¯äº¤æ¢çš„" -#: commands/indexcmds.c:1179 +#: commands/indexcmds.c:1744 #, c-format msgid "Only commutative operators can be used in exclusion constraints." msgstr "åªæœ‰å¯äº¤æ¢æ“作符能够在排他约æŸä¸­ä½¿ç”¨." -#: commands/indexcmds.c:1205 +#: commands/indexcmds.c:1770 #, c-format msgid "operator %s is not a member of operator family \"%s\"" msgstr "æ“作符%s䏿˜¯æ“作符表\"%s\"çš„æˆå‘˜" -#: commands/indexcmds.c:1208 +#: commands/indexcmds.c:1773 #, c-format -msgid "" -"The exclusion operator must be related to the index operator class for the " -"constraint." +msgid "The exclusion operator must be related to the index operator class for the constraint." msgstr "排他æ“作符必须和用于约æŸçš„索引æ“作符级别相关è”" -#: commands/indexcmds.c:1243 +#: commands/indexcmds.c:1808 #, c-format msgid "access method \"%s\" does not support ASC/DESC options" msgstr "访问方法 \"%s\" 䏿”¯æŒASC/DESC选项" -#: commands/indexcmds.c:1248 +#: commands/indexcmds.c:1813 #, c-format msgid "access method \"%s\" does not support NULLS FIRST/LAST options" msgstr "访问方法 \"%s\" 䏿”¯æŒNULLS FIRST/LAST选项" -#: commands/indexcmds.c:1304 commands/typecmds.c:1935 +#: commands/indexcmds.c:1873 commands/tablecmds.c:15121 +#: commands/tablecmds.c:15127 commands/typecmds.c:1981 #, c-format msgid "data type %s has no default operator class for access method \"%s\"" msgstr "对访问方法 \"%2$s\" æ•°æ®ç±»åž‹ %1$s 没有默认的æ“作符表" -#: commands/indexcmds.c:1306 +#: commands/indexcmds.c:1875 #, c-format -msgid "" -"You must specify an operator class for the index or define a default " -"operator class for the data type." +msgid "You must specify an operator class for the index or define a default operator class for the data type." msgstr "你必须指定一个æ“作符表给索引或定义一个默认的æ“作符表给数æ®ç±»åž‹." -#: commands/indexcmds.c:1335 commands/indexcmds.c:1343 -#: commands/opclasscmds.c:205 +#: commands/indexcmds.c:1904 commands/indexcmds.c:1912 +#: commands/opclasscmds.c:208 #, c-format msgid "operator class \"%s\" does not exist for access method \"%s\"" msgstr "å¤„ç†æ–¹æ³• \"%s\" çš„æ“作符类 \"%s\" ä¸å­˜åœ¨" -#: commands/indexcmds.c:1356 commands/typecmds.c:1923 +#: commands/indexcmds.c:1926 commands/typecmds.c:1969 #, c-format msgid "operator class \"%s\" does not accept data type %s" msgstr "æ“作符表 \"%s\" ä¸èƒ½å¤„ç†æ•°æ®ç±»åž‹ %s" -#: commands/indexcmds.c:1446 +#: commands/indexcmds.c:2016 #, c-format msgid "there are multiple default operator classes for data type %s" msgstr "æ•°æ®ç±»åž‹ %s 有多个默认的æ“作符表" -#: commands/indexcmds.c:1837 +#: commands/indexcmds.c:2456 #, c-format msgid "table \"%s\" has no indexes" msgstr "表 \"%s\" 没有索引" -#: commands/indexcmds.c:1892 +#: commands/indexcmds.c:2494 +#, fuzzy, c-format +#| msgid "concurrent index creation on system catalog tables is not supported" +msgid "concurrent reindex of system catalogs is not supported" +msgstr "䏿”¯æŒåœ¨ç³»ç»Ÿç›®å½•è¡¨ä¸ŠåŒæ—¶åˆ›å»ºç´¢å¼•" + +#: commands/indexcmds.c:2517 #, c-format msgid "can only reindex the currently open database" msgstr "åªèƒ½åœ¨å½“剿‰“开的数æ®åº“上é‡å»ºç´¢å¼•" -#: commands/indexcmds.c:1994 +#: commands/indexcmds.c:2608 +#, c-format +msgid "concurrent reindex is not supported for catalog relations, skipping all" +msgstr "" + +#: commands/indexcmds.c:2659 commands/indexcmds.c:3292 #, c-format msgid "table \"%s.%s\" was reindexed" msgstr "表 \"%s.%s\" å·²è¢«é‡æ–°ç´¢å¼•" -#: commands/matview.c:181 +#: commands/indexcmds.c:2756 commands/indexcmds.c:2850 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "cannot reindex a system catalog concurrently" +msgstr "æ— æ³•åŒæ—¶åœ¨åˆ†åŒºè¡¨\"%s\"上创建索引" + +#: commands/indexcmds.c:2771 commands/indexcmds.c:2817 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "cannot reindex invalid index \"%s.%s\" concurrently, skipping" +msgstr "æ— æ³•åŒæ—¶åœ¨åˆ†åŒºè¡¨\"%s\"上创建索引" + +#: commands/indexcmds.c:2777 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "cannot reindex exclusion constraint index \"%s.%s\" concurrently, skipping" +msgstr "æ— æ³•åŒæ—¶åœ¨åˆ†åŒºè¡¨\"%s\"上创建索引" + +#: commands/indexcmds.c:2878 +#, fuzzy, c-format +#| msgid "cannot create index on partitioned table \"%s\" concurrently" +msgid "cannot reindex this type of relation concurrently" +msgstr "æ— æ³•åŒæ—¶åœ¨åˆ†åŒºè¡¨\"%s\"上创建索引" + +#: commands/indexcmds.c:3274 commands/indexcmds.c:3285 +#, fuzzy, c-format +#| msgid "index \"%s\" was reindexed" +msgid "index \"%s.%s\" was reindexed" +msgstr "索引\"%s\"å·²è¢«é‡æ–°ç´¢å¼•" + +#: commands/indexcmds.c:3317 +#, c-format +msgid "REINDEX is not yet implemented for partitioned indexes" +msgstr "对于分区索引,没有实现REINDEX" + +#: commands/lockcmds.c:102 commands/tablecmds.c:5145 commands/trigger.c:313 +#: rewrite/rewriteDefine.c:271 rewrite/rewriteDefine.c:928 +#, c-format +msgid "\"%s\" is not a table or view" +msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè§†å›¾æˆ–视图" + +#: commands/lockcmds.c:235 rewrite/rewriteHandler.c:1974 +#: rewrite/rewriteHandler.c:3707 +#, c-format +msgid "infinite recursion detected in rules for relation \"%s\"" +msgstr "在关系 \"%s\" 的规则中å‘现无é™å¾ªçޝ" + +#: commands/matview.c:182 #, c-format msgid "CONCURRENTLY cannot be used when the materialized view is not populated" msgstr "CONCURRENTLY ä¸èƒ½ç”¨äºŽç‰©åŒ–视图未被产生之å‰" -#: commands/matview.c:187 +#: commands/matview.c:188 #, c-format msgid "CONCURRENTLY and WITH NO DATA options cannot be used together" msgstr "CONCURRENTLY å’Œ WITH NO DATA 两个选项ä¸èƒ½åŒæ—¶ä½¿ç”¨" # describe.c:933 -#: commands/matview.c:258 +#: commands/matview.c:244 #, c-format msgid "cannot refresh materialized view \"%s\" concurrently" msgstr "ä¸èƒ½åŒæ—¶åˆ·æ–°ç‰©åŒ–视图 \"%s\"" -#: commands/matview.c:261 +#: commands/matview.c:247 #, c-format -msgid "" -"Create a unique index with no WHERE clause on one or more columns of the " -"materialized view." +msgid "Create a unique index with no WHERE clause on one or more columns of the materialized view." msgstr "在物化视图的一个或多个列上创建ä¸å¸¦WHEREå­å¥çš„唯一索引." -#: commands/matview.c:656 +#: commands/matview.c:645 #, c-format -msgid "" -"new data for materialized view \"%s\" contains duplicate rows without any " -"null columns" +msgid "new data for materialized view \"%s\" contains duplicate rows without any null columns" msgstr "物化视图\"%s\"的新数æ®åŒ…å«é‡å¤çš„æ²¡æœ‰ç©ºå€¼åˆ—的行" -#: commands/matview.c:658 +#: commands/matview.c:647 #, c-format msgid "Row: %s" msgstr "行: %s" -#: commands/opclasscmds.c:126 +#: commands/opclasscmds.c:127 #, c-format msgid "operator family \"%s\" does not exist for access method \"%s\"" msgstr "访问方法\"%2$s\"çš„æ“作符表 \"%1$s\" ä¸å­˜åœ¨" -#: commands/opclasscmds.c:264 +#: commands/opclasscmds.c:269 #, c-format msgid "operator family \"%s\" for access method \"%s\" already exists" msgstr "访问方法 \"%2$s\" æ“作符表 \"%1$s\" å·²ç»å­˜åœ¨" -#: commands/opclasscmds.c:404 +#: commands/opclasscmds.c:412 #, c-format msgid "must be superuser to create an operator class" msgstr "åªæœ‰è¶…级用户能创建一个æ“作符表" -#: commands/opclasscmds.c:478 commands/opclasscmds.c:863 -#: commands/opclasscmds.c:996 +#: commands/opclasscmds.c:485 commands/opclasscmds.c:864 +#: commands/opclasscmds.c:988 #, c-format msgid "invalid operator number %d, must be between 1 and %d" msgstr "无效的æ“ä½œç¬¦å· %d, 必需在 1 到 %d 之间" -#: commands/opclasscmds.c:529 commands/opclasscmds.c:914 -#: commands/opclasscmds.c:1011 +#: commands/opclasscmds.c:529 commands/opclasscmds.c:908 +#: commands/opclasscmds.c:1003 #, c-format -msgid "invalid procedure number %d, must be between 1 and %d" -msgstr "æ— æ•ˆçš„è¿‡ç¨‹å· %d, 必需在 1 到 %d 之间" +msgid "invalid function number %d, must be between 1 and %d" +msgstr "æ— æ•ˆçš„å‡½æ•°å· %d, 必需在 1 到 %d 之间" -#: commands/opclasscmds.c:559 +#: commands/opclasscmds.c:558 #, c-format msgid "storage type specified more than once" msgstr "存储类型指定了多次" -#: commands/opclasscmds.c:586 +#: commands/opclasscmds.c:585 #, c-format -msgid "" -"storage type cannot be different from data type for access method \"%s\"" +msgid "storage type cannot be different from data type for access method \"%s\"" msgstr "存储类型应该和用于访问方法 \"%s\" æ•°æ®ç±»åž‹ä¸€æ ·" -#: commands/opclasscmds.c:602 +#: commands/opclasscmds.c:601 #, c-format msgid "operator class \"%s\" for access method \"%s\" already exists" msgstr "访问方法 \"%2$s\" æ“作符表 \"%1$s\" å·²ç»å­˜åœ¨" -#: commands/opclasscmds.c:630 +#: commands/opclasscmds.c:629 #, c-format msgid "could not make operator class \"%s\" be default for type %s" msgstr "无法把æ“作符表 \"%s\" 设置为类型 %s 的默认æ“作符表" -#: commands/opclasscmds.c:633 +#: commands/opclasscmds.c:632 #, c-format msgid "Operator class \"%s\" already is the default." msgstr "æ“作符表 \"%s\" å·²ç»æ˜¯é»˜è®¤çš„了." @@ -7625,255 +7805,264 @@ msgstr "æ“作符表 \"%s\" å·²ç»æ˜¯é»˜è®¤çš„了." msgid "must be superuser to create an operator family" msgstr "åªæœ‰è¶…级用户能创建一个æ“作符表" -#: commands/opclasscmds.c:816 +#: commands/opclasscmds.c:818 #, c-format msgid "must be superuser to alter an operator family" msgstr "åªæœ‰è¶…级用户能修改一个æ“作符表" -#: commands/opclasscmds.c:879 +#: commands/opclasscmds.c:873 #, c-format msgid "operator argument types must be specified in ALTER OPERATOR FAMILY" msgstr "在ALTER OPERATOR FAMILY中必须指定æ“ä½œç¬¦å‚æ•°ç±»åž‹" -#: commands/opclasscmds.c:943 +#: commands/opclasscmds.c:936 #, c-format msgid "STORAGE cannot be specified in ALTER OPERATOR FAMILY" msgstr "在ALTER OPERATOR FAMILYä¸­æ— æ³•æŒ‡å®šå‚æ•°STORAGE" -#: commands/opclasscmds.c:1066 +#: commands/opclasscmds.c:1058 #, c-format msgid "one or two argument types must be specified" msgstr "å¿…é¡»æŒ‡å®šä¸€ä¸ªæˆ–ä¸¤ä¸ªå‚æ•°ç±»åž‹" -#: commands/opclasscmds.c:1092 +#: commands/opclasscmds.c:1084 #, c-format msgid "index operators must be binary" msgstr "索引æ“作符必须为二进制" -#: commands/opclasscmds.c:1111 +#: commands/opclasscmds.c:1103 #, c-format msgid "access method \"%s\" does not support ordering operators" msgstr "访问方法 \"%s\" 䏿”¯æŒæŽ’åºæ“作符" -#: commands/opclasscmds.c:1122 +#: commands/opclasscmds.c:1114 #, c-format msgid "index search operators must return boolean" msgstr "索引æœç´¢æ“作符必须返回布尔值" -#: commands/opclasscmds.c:1164 +#: commands/opclasscmds.c:1158 +#, c-format +msgid "btree comparison functions must have two arguments" +msgstr "Bæ ‘æ¯”è¾ƒå‡½æ•°å¿…é¡»æœ‰ä¸¤ä¸ªå‚æ•°" + +#: commands/opclasscmds.c:1162 #, c-format -msgid "btree comparison procedures must have two arguments" -msgstr "Bæ ‘æ¯”è¾ƒè¿‡ç¨‹å¿…é¡»æœ‰ä¸¤ä¸ªå‚æ•°" +msgid "btree comparison functions must return integer" +msgstr "B树比较函数必须返回整数" -#: commands/opclasscmds.c:1168 +#: commands/opclasscmds.c:1179 #, c-format -msgid "btree comparison procedures must return integer" -msgstr "B树比较过程必须返回整数" +msgid "btree sort support functions must accept type \"internal\"" +msgstr "Bæ ‘æŽ’åºæ”¯æŒçš„函数必须接å—\"internal\"类型" -#: commands/opclasscmds.c:1185 +#: commands/opclasscmds.c:1183 #, c-format -msgid "btree sort support procedures must accept type \"internal\"" -msgstr "Bæ ‘æŽ’åºæ”¯æŒè¿‡ç¨‹å¿…须接å—\"internal\"类型" +msgid "btree sort support functions must return void" +msgstr "Bæ ‘æŽ’åºæ”¯æŒçš„函数必须返回void" -#: commands/opclasscmds.c:1189 +#: commands/opclasscmds.c:1194 #, c-format -msgid "btree sort support procedures must return void" -msgstr "Bæ ‘æŽ’åºæ”¯æŒè¿‡ç¨‹å¿…须返回void" +msgid "btree in_range functions must have five arguments" +msgstr "Bæ ‘in_rangeå‡½æ•°å¿…é¡»æœ‰äº”ä¸ªå‚æ•°" -#: commands/opclasscmds.c:1201 +#: commands/opclasscmds.c:1198 #, c-format -msgid "hash procedures must have one argument" -msgstr "å“ˆå¸Œå­˜å‚¨è¿‡ç¨‹å¿…é¡»æœ‰ä¸€ä¸ªå‚æ•°" +msgid "btree in_range functions must return boolean" +msgstr "Bæ ‘in_range函数必需返回布尔类型" -#: commands/opclasscmds.c:1205 +#: commands/opclasscmds.c:1217 #, c-format -msgid "hash procedures must return integer" -msgstr "哈希存储过程必须返回整数" +msgid "hash function 1 must have one argument" +msgstr "哈希函数1å¿…é¡»æœ‰ä¸€ä¸ªå‚æ•°" -#: commands/opclasscmds.c:1229 +#: commands/opclasscmds.c:1221 #, c-format -msgid "associated data types must be specified for index support procedure" -msgstr "必须为索引支æŒçš„存储过程指定相关è”的数æ®ç±»åž‹" +msgid "hash function 1 must return integer" +msgstr "哈希函数1必须返回整数" -#: commands/opclasscmds.c:1254 +#: commands/opclasscmds.c:1228 #, c-format -msgid "procedure number %d for (%s,%s) appears more than once" -msgstr "对于(%2$s,%3$s)的存储过程å·%1$d出现了多次 " +msgid "hash function 2 must have two arguments" +msgstr "哈希函数2å¿…é¡»æœ‰ä¸¤ä¸ªå‚æ•°" -#: commands/opclasscmds.c:1261 +#: commands/opclasscmds.c:1232 +#, c-format +msgid "hash function 2 must return bigint" +msgstr "哈希函数2ä¸èƒ½è¿”回bigint类型" + +#: commands/opclasscmds.c:1257 +#, c-format +msgid "associated data types must be specified for index support function" +msgstr "必须为索引支æŒçš„函数指定相关è”的数æ®ç±»åž‹" + +#: commands/opclasscmds.c:1282 +#, c-format +msgid "function number %d for (%s,%s) appears more than once" +msgstr "对于(%2$s,%3$s)函数å·%1$d出现过多次" + +#: commands/opclasscmds.c:1289 #, c-format msgid "operator number %d for (%s,%s) appears more than once" msgstr "对于(%2$s,%3$s)æ“作符å·%1$d出现过多次" -#: commands/opclasscmds.c:1310 +#: commands/opclasscmds.c:1338 #, c-format msgid "operator %d(%s,%s) already exists in operator family \"%s\"" msgstr "在æ“作符表\"%4$s\"中已存在æ“作符 %1$d(%2$s,%3$s)" -#: commands/opclasscmds.c:1426 +#: commands/opclasscmds.c:1455 #, c-format msgid "function %d(%s,%s) already exists in operator family \"%s\"" msgstr "在æ“作符表\"%4$s\"中已存在函数 %1$d(%2$s,%3$s)" -#: commands/opclasscmds.c:1516 +#: commands/opclasscmds.c:1546 #, c-format msgid "operator %d(%s,%s) does not exist in operator family \"%s\"" msgstr "在æ“作符表\"%4$s\"中ä¸å­˜åœ¨æ“作符 %1$d(%2$s,%3$s)" -#: commands/opclasscmds.c:1556 +#: commands/opclasscmds.c:1586 #, c-format msgid "function %d(%s,%s) does not exist in operator family \"%s\"" msgstr "在æ“作符表\"%4$s\"中ä¸å­˜åœ¨å‡½æ•° %1$d(%2$s,%3$s)" -#: commands/opclasscmds.c:1686 +#: commands/opclasscmds.c:1716 #, c-format -msgid "" -"operator class \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" +msgid "operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "访问方法 \"%s\" çš„æ“作符表 \"%s\" å·²ç»åœ¨æ¨¡å¼ \"%s\" 存在了" -#: commands/opclasscmds.c:1709 +#: commands/opclasscmds.c:1739 #, c-format -msgid "" -"operator family \"%s\" for access method \"%s\" already exists in schema \"%s" -"\"" +msgid "operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"" msgstr "对于访问方法 \"%2$s\" çš„æ“作符表 \"%1$s\" å·²ç»åœ¨æ¨¡å¼ \"%3$s\" 存在了" -#: commands/operatorcmds.c:114 commands/operatorcmds.c:122 +#: commands/operatorcmds.c:113 commands/operatorcmds.c:121 #, c-format msgid "SETOF type not allowed for operator argument" msgstr "ä¸å…许将SETOF类型用于æ“ä½œç¬¦å‚æ•°" -#: commands/operatorcmds.c:152 commands/operatorcmds.c:457 +#: commands/operatorcmds.c:154 commands/operatorcmds.c:457 #, c-format msgid "operator attribute \"%s\" not recognized" msgstr "æ“作符属性 \"%s\" ä¸è¢«è®¤å¯" -#: commands/operatorcmds.c:163 +#: commands/operatorcmds.c:165 #, c-format -msgid "operator procedure must be specified" -msgstr "必须指定æ“作符过程" +msgid "operator function must be specified" +msgstr "必须指定è¿ç®—符函数" -#: commands/operatorcmds.c:174 +#: commands/operatorcmds.c:176 #, c-format msgid "at least one of leftarg or rightarg must be specified" msgstr "å¿…é¡»è‡³å°‘æŒ‡å®šä¸€ä¸ªå·¦å‚æ•° (leftarg) 或å³å‚æ•° (rightarg)" -#: commands/operatorcmds.c:278 +#: commands/operatorcmds.c:280 #, c-format -#| msgid "restriction estimator function %s must return type \"float8\"" msgid "restriction estimator function %s must return type %s" msgstr "é™åˆ¶ä¼°ç®—器函数 %s 必需返回类型 %s" -#: commands/operatorcmds.c:324 +#: commands/operatorcmds.c:326 #, c-format -#| msgid "join estimator function %s must return type \"float8\"" msgid "join estimator function %s must return type %s" msgstr "连接估算器函数 %s 必需返回类型 %s" #: commands/operatorcmds.c:451 #, c-format -#| msgid "operator attribute \"%s\" not recognized" -msgid "operator attribute \"%s\" can not be changed" +msgid "operator attribute \"%s\" cannot be changed" msgstr "æ“作符属性 \"%s\" ä¸èƒ½è¢«æ›´æ”¹" -#: commands/policy.c:87 commands/policy.c:395 commands/policy.c:484 -#: commands/tablecmds.c:970 commands/tablecmds.c:1312 -#: commands/tablecmds.c:2184 commands/tablecmds.c:4330 -#: commands/tablecmds.c:6281 commands/tablecmds.c:11935 -#: commands/tablecmds.c:11970 commands/trigger.c:241 commands/trigger.c:1125 -#: commands/trigger.c:1233 rewrite/rewriteDefine.c:273 -#: rewrite/rewriteDefine.c:917 +#: commands/policy.c:88 commands/policy.c:401 commands/policy.c:491 +#: commands/tablecmds.c:1428 commands/tablecmds.c:1910 +#: commands/tablecmds.c:2877 commands/tablecmds.c:5124 +#: commands/tablecmds.c:7594 commands/tablecmds.c:14695 +#: commands/tablecmds.c:14730 commands/trigger.c:319 commands/trigger.c:1545 +#: commands/trigger.c:1654 rewrite/rewriteDefine.c:277 +#: rewrite/rewriteDefine.c:933 #, c-format msgid "permission denied: \"%s\" is a system catalog" msgstr "æƒé™ä¸å¤Ÿ: \"%s\" 是一个系统表" -#: commands/policy.c:170 +#: commands/policy.c:171 #, c-format -#| msgid "ignoring roles specified other than public" msgid "ignoring specified roles other than PUBLIC" msgstr "忽略所指定的除 PUBLIC 之外的角色" -#: commands/policy.c:171 +#: commands/policy.c:172 #, c-format -#| msgid "All roles are members of the public role." msgid "All roles are members of the PUBLIC role." msgstr "所有角色都是 PUBLIC 角色的æˆå‘˜ã€‚" -#: commands/policy.c:508 +#: commands/policy.c:515 #, c-format -#| msgid "File \"%s\" could not be renamed to \"%s\": %m." msgid "role \"%s\" could not be removed from policy \"%s\" on \"%s\"" msgstr "ä¸èƒ½ä»Ž \"%3$s\" 上的策略 \"%2$s\" 中移除角色 \"%1$s\"" -#: commands/policy.c:717 +#: commands/policy.c:724 #, c-format msgid "WITH CHECK cannot be applied to SELECT or DELETE" msgstr "ä¸èƒ½æŠŠWITH CHECK应用到SELECT或者DELETE" -#: commands/policy.c:726 commands/policy.c:1026 +#: commands/policy.c:733 commands/policy.c:1038 #, c-format msgid "only WITH CHECK expression allowed for INSERT" msgstr "对INSERTåªå…许WITH CHECK表达å¼" -#: commands/policy.c:799 commands/policy.c:1249 +#: commands/policy.c:808 commands/policy.c:1260 #, c-format msgid "policy \"%s\" for table \"%s\" already exists" msgstr "用于表\"%2$s\"的策略\"%1$s\"å·²ç»å­˜åœ¨" -#: commands/policy.c:998 commands/policy.c:1277 commands/policy.c:1352 +#: commands/policy.c:1010 commands/policy.c:1288 commands/policy.c:1359 #, c-format msgid "policy \"%s\" for table \"%s\" does not exist" msgstr "用于表\"%2$s\"的策略\"%1$s\"ä¸å­˜åœ¨" -#: commands/policy.c:1016 +#: commands/policy.c:1028 #, c-format msgid "only USING expression allowed for SELECT, DELETE" msgstr "对SELECTã€DELETEåªå…许USING表达å¼" -#: commands/portalcmds.c:61 commands/portalcmds.c:160 -#: commands/portalcmds.c:212 +#: commands/portalcmds.c:58 commands/portalcmds.c:182 commands/portalcmds.c:234 #, c-format msgid "invalid cursor name: must not be empty" msgstr "无效的游标åç§°: ä¸èƒ½ä¸ºç©º" -#: commands/portalcmds.c:168 commands/portalcmds.c:222 -#: executor/execCurrent.c:67 utils/adt/xml.c:2391 utils/adt/xml.c:2558 +#: commands/portalcmds.c:190 commands/portalcmds.c:244 +#: executor/execCurrent.c:70 utils/adt/xml.c:2608 utils/adt/xml.c:2778 #, c-format msgid "cursor \"%s\" does not exist" msgstr "游标 \"%s\" ä¸å­˜åœ¨" -#: commands/prepare.c:71 +#: commands/prepare.c:75 #, c-format msgid "invalid statement name: must not be empty" msgstr "无效的语å¥åç§°: ä¸èƒ½ä¸ºç©º" -#: commands/prepare.c:129 parser/parse_param.c:304 tcop/postgres.c:1345 +#: commands/prepare.c:141 parser/parse_param.c:304 tcop/postgres.c:1468 #, c-format msgid "could not determine data type of parameter $%d" msgstr "æ— æ³•ç¡®å®šå‚æ•° $%d 的数æ®ç±»åž‹" -#: commands/prepare.c:147 +#: commands/prepare.c:159 #, c-format msgid "utility statements cannot be prepared" msgstr "ä¸èƒ½å‡†å¤‡å¥½å·¥å…·è¯­å¥" -#: commands/prepare.c:257 commands/prepare.c:264 +#: commands/prepare.c:269 commands/prepare.c:274 #, c-format msgid "prepared statement is not a SELECT" msgstr "准备好的语å¥ä¸æ˜¯ä¸€ä¸ª SELECT" -#: commands/prepare.c:332 +#: commands/prepare.c:342 #, c-format msgid "wrong number of parameters for prepared statement \"%s\"" msgstr "å‡†å¤‡å¥½çš„è¯­å¥ \"%s\" 傿•°ä¸ªæ•°é”™è¯¯" -#: commands/prepare.c:334 +#: commands/prepare.c:344 #, c-format msgid "Expected %d parameters but got %d." msgstr "预计 %d ä¸ªå‚æ•°, 但得到了 %d 个." -#: commands/prepare.c:370 +#: commands/prepare.c:380 #, c-format msgid "parameter $%d of type %s cannot be coerced to the expected type %s" msgstr "类型 %2$s çš„å‚æ•° $%1$d ä¸èƒ½å¼ºåˆ¶åˆ°é¢„计 (expected) 类型 %3$s" @@ -7888,48 +8077,94 @@ msgstr "å‡†å¤‡å¥½çš„è¯­å¥ \"%s\" å·²ç»å­˜åœ¨" msgid "prepared statement \"%s\" does not exist" msgstr "å‡†å¤‡å¥½çš„è¯­å¥ \"%s\" ä¸å­˜åœ¨" -#: commands/proclang.c:87 +#: commands/proclang.c:85 #, c-format msgid "using pg_pltemplate information instead of CREATE LANGUAGE parameters" msgstr "使用pg_pltemplateä¿¡æ¯ï¼Œè€Œä¸æ˜¯CREATE LANGUAGEçš„å‚æ•°" -#: commands/proclang.c:97 +#: commands/proclang.c:95 #, c-format msgid "must be superuser to create procedural language \"%s\"" msgstr "åªæœ‰æœ‰è¶…级用户æƒé™çš„用户æ‰èƒ½åˆ›å»ºè¿‡ç¨‹è¯­è¨€\"%s\"" -#: commands/proclang.c:252 +#: commands/proclang.c:250 #, c-format msgid "unsupported language \"%s\"" msgstr "䏿”¯æŒè¯­è¨€ \"%s\"" -#: commands/proclang.c:254 +#: commands/proclang.c:252 #, c-format msgid "The supported languages are listed in the pg_pltemplate system catalog." msgstr "在pg_pltemplate系统目录视图中列出了所支æŒçš„语言." -#: commands/proclang.c:262 +#: commands/proclang.c:260 #, c-format msgid "must be superuser to create custom procedural language" msgstr "åªæœ‰æœ‰è¶…级用户æƒé™çš„用户æ‰èƒ½åˆ›å»ºè¿‡ç¨‹è¯­è¨€" -#: commands/proclang.c:281 +#: commands/proclang.c:279 commands/trigger.c:711 commands/typecmds.c:458 +#: commands/typecmds.c:475 #, c-format -msgid "" -"changing return type of function %s from \"opaque\" to \"language_handler\"" -msgstr "函数 %s 的返回类型 \"opaque\" æ”¹å˜æˆ \"language_handler\"" +msgid "changing return type of function %s from %s to %s" +msgstr "把函数 %1$s 的返回类型从 %2$s æ”¹æˆ %3$s" + +#: commands/publicationcmds.c:108 +#, c-format +msgid "invalid list syntax for \"publish\" option" +msgstr "\"publish\"选项使用了无效的列表语法" + +#: commands/publicationcmds.c:126 +#, c-format +msgid "unrecognized \"publish\" value: \"%s\"" +msgstr "未知的\"publish\"值: \"%s\"" + +#: commands/publicationcmds.c:132 +#, fuzzy, c-format +#| msgid "unrecognized publication parameter: %s" +msgid "unrecognized publication parameter: \"%s\"" +msgstr "未识别å‘å¸ƒå‚æ•°: %s" + +#: commands/publicationcmds.c:165 +#, c-format +msgid "must be superuser to create FOR ALL TABLES publication" +msgstr "åªæœ‰è¶…级用户能创建FOR ALL TABLESå‘布" + +#: commands/publicationcmds.c:341 +#, c-format +msgid "publication \"%s\" is defined as FOR ALL TABLES" +msgstr "å‘布\"%s\"被定义为FOR ALL TABLES" -#: commands/schemacmds.c:103 commands/schemacmds.c:266 +#: commands/publicationcmds.c:343 +#, c-format +msgid "Tables cannot be added to or dropped from FOR ALL TABLES publications." +msgstr "对于FOR ALL TABLESå‘布,ä¸èƒ½å°†è¡¨æ·»åŠ åˆ°æˆ–ä»Žä¸­åˆ é™¤." + +#: commands/publicationcmds.c:648 +#, c-format +msgid "relation \"%s\" is not part of the publication" +msgstr "关系 \"%s\" 䏿˜¯å‘布的一部分" + +#: commands/publicationcmds.c:691 +#, c-format +msgid "permission denied to change owner of publication \"%s\"" +msgstr "改å˜å‘布\"%s\"属主的æƒé™ä¸å¤Ÿ" + +#: commands/publicationcmds.c:693 +#, c-format +msgid "The owner of a FOR ALL TABLES publication must be a superuser." +msgstr "FOR ALL TABLESå‘布的属主必须是超级用户." + +#: commands/schemacmds.c:106 commands/schemacmds.c:282 #, c-format msgid "unacceptable schema name \"%s\"" msgstr "ä¸å¯è®¿é—®çš„æ¨¡å¼åå­— \"%s\"" -#: commands/schemacmds.c:104 commands/schemacmds.c:267 +#: commands/schemacmds.c:107 commands/schemacmds.c:283 #, c-format msgid "The prefix \"pg_\" is reserved for system schemas." msgstr "å‰ç¼€ \"pg_\" 是ä¿ç•™ç»™ç³»ç»Ÿæ¨¡å¼çš„." -#: commands/schemacmds.c:118 +#: commands/schemacmds.c:121 #, c-format msgid "schema \"%s\" already exists, skipping" msgstr "æ¨¡å¼ \"%s\" 已存在, 跳过" @@ -7941,8 +8176,7 @@ msgstr "没有安全标签æä¾›è€…被加载" #: commands/seclabel.c:64 #, c-format -msgid "" -"must specify provider when multiple security label providers have been loaded" +msgid "must specify provider when multiple security label providers have been loaded" msgstr "当多个安全æä¾›è€…å·²ç»åŠ è½½æ—¶ï¼Œå¿…é¡»æŒ‡å®šæä¾›è€…" #: commands/seclabel.c:82 @@ -7950,1101 +8184,1732 @@ msgstr "当多个安全æä¾›è€…å·²ç»åŠ è½½æ—¶ï¼Œå¿…é¡»æŒ‡å®šæä¾›è€…" msgid "security label provider \"%s\" is not loaded" msgstr "安装标签æä¾›è€…\"%s\"没有加载" -#: commands/sequence.c:127 +#: commands/sequence.c:140 #, c-format msgid "unlogged sequences are not supported" msgstr "éžäº‹åŠ¡æ—¥å¿—åž‹åºåˆ—ä¸è¢«æ”¯æŒ" -#: commands/sequence.c:651 +#: commands/sequence.c:709 #, c-format msgid "nextval: reached maximum value of sequence \"%s\" (%s)" msgstr "nextval: 达到åºåˆ— \"%s\" 的最大值了 (%s)" -#: commands/sequence.c:674 +#: commands/sequence.c:732 #, c-format msgid "nextval: reached minimum value of sequence \"%s\" (%s)" msgstr "nextval: 达到åºåˆ— \"%s\" 的最å°å€¼äº† (%s)" -#: commands/sequence.c:792 +#: commands/sequence.c:850 #, c-format msgid "currval of sequence \"%s\" is not yet defined in this session" msgstr "在此会è¯ä¸­åºåˆ— \"%s\" çš„ currval 仿²¡è¢«å®šä¹‰" -#: commands/sequence.c:811 commands/sequence.c:817 +#: commands/sequence.c:869 commands/sequence.c:875 #, c-format msgid "lastval is not yet defined in this session" msgstr "在这个会è¯ä¸­è¿˜æ²¡æœ‰å®šä¹‰lastval " -#: commands/sequence.c:893 +#: commands/sequence.c:963 #, c-format msgid "setval: value %s is out of bounds for sequence \"%s\" (%s..%s)" msgstr "setval: 值 %s 超出åºåˆ— \"%s\" 的范围 (%s..%s)" -#: commands/sequence.c:1267 +#: commands/sequence.c:1360 +#, c-format +msgid "invalid sequence option SEQUENCE NAME" +msgstr "åºåˆ—选项SEQUENCE NAME无效 " + +#: commands/sequence.c:1386 +#, c-format +msgid "identity column type must be smallint, integer, or bigint" +msgstr "标识列类型必须是smallintã€integer或bigint" + +#: commands/sequence.c:1387 +#, c-format +msgid "sequence type must be smallint, integer, or bigint" +msgstr "åºåˆ—类型必须是smallintã€integer或bigint" + +#: commands/sequence.c:1421 #, c-format msgid "INCREMENT must not be zero" msgstr "INCREMENT ä¸å¿…为零" -#: commands/sequence.c:1323 +#: commands/sequence.c:1474 +#, c-format +msgid "MAXVALUE (%s) is out of range for sequence data type %s" +msgstr "MAXVALUE (%s) 超出åºåˆ—æ•°æ®ç±»åž‹%s的范围" + +#: commands/sequence.c:1511 +#, c-format +msgid "MINVALUE (%s) is out of range for sequence data type %s" +msgstr "MINVALUE (%s)超出åºåˆ—æ•°æ®ç±»åž‹%s的范围" + +#: commands/sequence.c:1525 #, c-format msgid "MINVALUE (%s) must be less than MAXVALUE (%s)" msgstr "MINVALUE (%s) 必需å°äºŽ MAXVALUE (%s)" -#: commands/sequence.c:1348 +#: commands/sequence.c:1552 #, c-format msgid "START value (%s) cannot be less than MINVALUE (%s)" msgstr "START 值 (%s) ä¸èƒ½å°äºŽ MINVALUE (%s)" -#: commands/sequence.c:1360 +#: commands/sequence.c:1564 #, c-format msgid "START value (%s) cannot be greater than MAXVALUE (%s)" msgstr "START 值 (%s) ä¸èƒ½å¤§äºŽ MAXVALUE (%s)" -#: commands/sequence.c:1390 +#: commands/sequence.c:1594 #, c-format msgid "RESTART value (%s) cannot be less than MINVALUE (%s)" msgstr "RESTART值 (%s) ä¸èƒ½å°äºŽ MINVALUE (%s)" -#: commands/sequence.c:1402 +#: commands/sequence.c:1606 #, c-format msgid "RESTART value (%s) cannot be greater than MAXVALUE (%s)" msgstr "RESTART 值 (%s) ä¸èƒ½å¤§äºŽ MAXVALUE (%s)" -#: commands/sequence.c:1417 +#: commands/sequence.c:1621 #, c-format msgid "CACHE (%s) must be greater than zero" msgstr "CACHE (%s) 必须大于零" -#: commands/sequence.c:1449 +#: commands/sequence.c:1658 #, c-format msgid "invalid OWNED BY option" msgstr "无效的OWNED BY选项" -#: commands/sequence.c:1450 +#: commands/sequence.c:1659 #, c-format msgid "Specify OWNED BY table.column or OWNED BY NONE." msgstr "指定OWNED BY 表.列 or OWNED BY NONE." -#: commands/sequence.c:1473 +#: commands/sequence.c:1684 #, c-format msgid "referenced relation \"%s\" is not a table or foreign table" msgstr "å…³è”的关系 \"%s\" 䏿˜¯ä¸€ä¸ªè¡¨æˆ–外部å‚照表" -#: commands/sequence.c:1480 +#: commands/sequence.c:1691 #, c-format msgid "sequence must have same owner as table it is linked to" msgstr "åºåˆ—的属主必须和与它相链接的表的属主相åŒ." -#: commands/sequence.c:1484 +#: commands/sequence.c:1695 #, c-format msgid "sequence must be in same schema as table it is linked to" msgstr "åºåˆ—必须和与它相链接的表存放在åŒä¸€ä¸ªæ¨¡å¼" -#: commands/tablecmds.c:215 +#: commands/sequence.c:1717 +#, c-format +msgid "cannot change ownership of identity sequence" +msgstr "无法更改标识åºåˆ—的所有æƒ" + +#: commands/sequence.c:1718 commands/tablecmds.c:11597 +#: commands/tablecmds.c:14107 +#, c-format +msgid "Sequence \"%s\" is linked to table \"%s\"." +msgstr "åºåˆ— \"%s\"已链接到表\"%s\"." + +#: commands/statscmds.c:97 commands/statscmds.c:106 +#, c-format +msgid "only a single relation is allowed in CREATE STATISTICS" +msgstr "在创建统计信æ¯ä¸­åªå…许一个关系" + +#: commands/statscmds.c:124 +#, c-format +msgid "relation \"%s\" is not a table, foreign table, or materialized view" +msgstr "关系\"%s\"䏿˜¯è¡¨ã€å¤–部表或物化视图" + +#: commands/statscmds.c:167 +#, c-format +msgid "statistics object \"%s\" already exists, skipping" +msgstr "统计信æ¯å¯¹è±¡ \"%s\" å·²ç»å­˜åœ¨, 跳过" + +#: commands/statscmds.c:175 +#, c-format +msgid "statistics object \"%s\" already exists" +msgstr "统计信æ¯å¯¹è±¡ \"%s\" å·²ç»å­˜åœ¨" + +#: commands/statscmds.c:197 commands/statscmds.c:203 +#, c-format +msgid "only simple column references are allowed in CREATE STATISTICS" +msgstr "创建统计信æ¯ä¸­åªå…许简å•列引用" + +#: commands/statscmds.c:218 +#, c-format +msgid "statistics creation on system columns is not supported" +msgstr "䏿”¯æŒåœ¨ç³»ç»Ÿåˆ—上创建统计信æ¯" + +#: commands/statscmds.c:225 +#, c-format +msgid "column \"%s\" cannot be used in statistics because its type %s has no default btree operator class" +msgstr "列\"%s\"ä¸èƒ½ç”¨äºŽç»Ÿè®¡ï¼Œå› ä¸ºå®ƒçš„类型%s没有默认的Bæ ‘è¿ç®—符类" + +#: commands/statscmds.c:232 +#, c-format +msgid "cannot have more than %d columns in statistics" +msgstr "在一个统计信æ¯ä¸­ä¸èƒ½ä½¿ç”¨è¶…过 %d 个字段" + +#: commands/statscmds.c:247 +#, c-format +msgid "extended statistics require at least 2 columns" +msgstr "扩展统计信æ¯è‡³å°‘需è¦2列" + +#: commands/statscmds.c:265 +#, c-format +msgid "duplicate column name in statistics definition" +msgstr "统计信æ¯å®šä¹‰ä¸­æœ‰é‡å¤çš„列å" + +#: commands/statscmds.c:299 +#, c-format +msgid "unrecognized statistics kind \"%s\"" +msgstr "未识别的统计类型\"%s\"" + +#: commands/subscriptioncmds.c:188 +#, fuzzy, c-format +#| msgid "unrecognized subscription parameter: %s" +msgid "unrecognized subscription parameter: \"%s\"" +msgstr "æœªè¯†åˆ«çš„è®¢é˜…å‚æ•°: %s" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:202 commands/subscriptioncmds.c:208 +#: commands/subscriptioncmds.c:214 commands/subscriptioncmds.c:233 +#: commands/subscriptioncmds.c:239 +#, fuzzy, c-format +#| msgid "connect = false and enabled = true are mutually exclusive options" +msgid "%s and %s are mutually exclusive options" +msgstr "connect = falseå’Œenabled = true是互斥选项" + +#. translator: both %s are strings of the form "option = value" +#: commands/subscriptioncmds.c:246 commands/subscriptioncmds.c:252 +#, fuzzy, c-format +#| msgid "subscription with slot_name = NONE must also set enabled = false" +msgid "subscription with %s must also set %s" +msgstr "有slot_name = NONE选项的订阅还必须设置enabled = false" + +#: commands/subscriptioncmds.c:294 +#, c-format +msgid "publication name \"%s\" used more than once" +msgstr "å‘布åç§°\"%s\"使用了多次" + +#: commands/subscriptioncmds.c:358 +#, c-format +msgid "must be superuser to create subscriptions" +msgstr "åªæœ‰è¶…级用户能创建订阅" + +#: commands/subscriptioncmds.c:441 commands/subscriptioncmds.c:534 +#: replication/logical/tablesync.c:846 replication/logical/worker.c:1704 +#, c-format +msgid "could not connect to the publisher: %s" +msgstr "无法连接到å‘布æœåŠ¡å™¨ï¼š%s" + +#: commands/subscriptioncmds.c:483 +#, c-format +msgid "created replication slot \"%s\" on publisher" +msgstr "在å‘布æœåŠ¡å™¨ä¸Šåˆ›å»ºå¤åˆ¶æ§½ \"%s\"" + +#. translator: %s is an SQL ALTER statement +#: commands/subscriptioncmds.c:501 +#, fuzzy, c-format +#| msgid "tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables" +msgid "tables were not subscribed, you will have to run %s to subscribe the tables" +msgstr "没有订阅表,您必须è¿è¡ŒALTER SUBSCRIPTION ... REFRESH PUBLICATION订阅表" + +#: commands/subscriptioncmds.c:590 +#, c-format +msgid "table \"%s.%s\" added to subscription \"%s\"" +msgstr "表\"%s.%s\"添加到订阅\"%s\"中" + +#: commands/subscriptioncmds.c:614 +#, c-format +msgid "table \"%s.%s\" removed from subscription \"%s\"" +msgstr "已从订阅\"%3$s\"中删除表\"%1$s.%2$s\"" + +#: commands/subscriptioncmds.c:686 +#, fuzzy, c-format +#| msgid "cannot set slot_name = NONE for enabled subscription" +msgid "cannot set %s for enabled subscription" +msgstr "无法为å¯ç”¨çš„订阅设置slot_name = NONE" + +#: commands/subscriptioncmds.c:721 +#, c-format +msgid "cannot enable subscription that does not have a slot name" +msgstr "无法å¯ç”¨æ²¡æœ‰æ§½å称的订阅" + +#: commands/subscriptioncmds.c:767 +#, c-format +msgid "ALTER SUBSCRIPTION with refresh is not allowed for disabled subscriptions" +msgstr "ç¦ç”¨çš„订阅ä¸å…许使用带刷新的ALTER SUBSCRIPTION" + +#: commands/subscriptioncmds.c:768 +#, c-format +msgid "Use ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." +msgstr "使用ALTER SUBSCRIPTION ... SET PUBLICATION ... WITH (refresh = false)." + +#: commands/subscriptioncmds.c:786 +#, c-format +msgid "ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions" +msgstr "ALTER SUBSCRIPTION ... REFRESHä¸å…许用于已ç¦ç”¨çš„订阅" + +#: commands/subscriptioncmds.c:866 +#, c-format +msgid "subscription \"%s\" does not exist, skipping" +msgstr "订阅\"%s\"ä¸å­˜åœ¨ï¼Œè·³è¿‡" + +#: commands/subscriptioncmds.c:992 +#, c-format +msgid "could not connect to publisher when attempting to drop the replication slot \"%s\"" +msgstr "å°è¯•删除å¤åˆ¶æ§½\"%s\"时无法连接到å‘布æœåС噍" + +#: commands/subscriptioncmds.c:994 commands/subscriptioncmds.c:1009 +#: replication/logical/tablesync.c:895 replication/logical/tablesync.c:917 +#, c-format +msgid "The error was: %s" +msgstr "错误是: %s" + +#. translator: %s is an SQL ALTER command +#: commands/subscriptioncmds.c:996 +#, fuzzy, c-format +#| msgid "Use ALTER SUBSCRIPTION ... SET (slot_name = NONE) to disassociate the subscription from the slot." +msgid "Use %s to disassociate the subscription from the slot." +msgstr "使用ALTER SUBSCRIPTION ... SET (slot_name = NONE)å–æ¶ˆè®¢é˜…ä¸Žæ’æ§½çš„å…³è”." + +#: commands/subscriptioncmds.c:1007 +#, c-format +msgid "could not drop the replication slot \"%s\" on publisher" +msgstr "无法删除å‘布æœåŠ¡å™¨ä¸Šçš„å¤åˆ¶æ§½\"%s\"" + +#: commands/subscriptioncmds.c:1012 +#, c-format +msgid "dropped replication slot \"%s\" on publisher" +msgstr "已删除å‘布æœåŠ¡å™¨ä¸Šçš„å¤åˆ¶æ§½\"%s\"" + +#: commands/subscriptioncmds.c:1053 +#, c-format +msgid "permission denied to change owner of subscription \"%s\"" +msgstr "更改订阅所有者\"%s\"çš„æƒé™è¢«æ‹’ç»" + +#: commands/subscriptioncmds.c:1055 +#, c-format +msgid "The owner of a subscription must be a superuser." +msgstr "订阅的所有者必须是超级用户." + +#: commands/subscriptioncmds.c:1170 +#, c-format +msgid "could not receive list of replicated tables from the publisher: %s" +msgstr "无法从å‘布æœåŠ¡å™¨æŽ¥æ”¶å·²å¤åˆ¶è¡¨çš„列表: %s" + +#: commands/tablecmds.c:222 commands/tablecmds.c:264 #, c-format msgid "table \"%s\" does not exist" msgstr "表 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:216 +#: commands/tablecmds.c:223 commands/tablecmds.c:265 #, c-format msgid "table \"%s\" does not exist, skipping" msgstr "表 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:218 +#: commands/tablecmds.c:225 commands/tablecmds.c:267 msgid "Use DROP TABLE to remove a table." msgstr "请使用 DROP TABLE 删除一个表." -#: commands/tablecmds.c:221 +#: commands/tablecmds.c:228 #, c-format msgid "sequence \"%s\" does not exist" msgstr "åºåˆ— \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:222 +#: commands/tablecmds.c:229 #, c-format msgid "sequence \"%s\" does not exist, skipping" msgstr "åºåˆ— \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:224 +#: commands/tablecmds.c:231 msgid "Use DROP SEQUENCE to remove a sequence." msgstr "请使用 DROP SEQUENCE 删除一个åºåˆ—." -#: commands/tablecmds.c:227 +#: commands/tablecmds.c:234 #, c-format msgid "view \"%s\" does not exist" msgstr "视图 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:228 +#: commands/tablecmds.c:235 #, c-format msgid "view \"%s\" does not exist, skipping" msgstr "视图 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:230 +#: commands/tablecmds.c:237 msgid "Use DROP VIEW to remove a view." msgstr "请使用 DROP VIEW 删除一个视图." -#: commands/tablecmds.c:233 +#: commands/tablecmds.c:240 #, c-format msgid "materialized view \"%s\" does not exist" msgstr "物化视图 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:234 +#: commands/tablecmds.c:241 #, c-format msgid "materialized view \"%s\" does not exist, skipping" msgstr "物化视图 \"%s\" ä¸å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/tablecmds.c:236 +#: commands/tablecmds.c:243 msgid "Use DROP MATERIALIZED VIEW to remove a materialized view." msgstr "请使用 DROP MATERIALIZED VIEW 删除一个物化视图." -#: commands/tablecmds.c:239 parser/parse_utilcmd.c:1643 +#: commands/tablecmds.c:246 commands/tablecmds.c:270 commands/tablecmds.c:16171 +#: parser/parse_utilcmd.c:2045 #, c-format msgid "index \"%s\" does not exist" msgstr "索引 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:240 +#: commands/tablecmds.c:247 commands/tablecmds.c:271 #, c-format msgid "index \"%s\" does not exist, skipping" msgstr "索引 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:242 +#: commands/tablecmds.c:249 commands/tablecmds.c:273 msgid "Use DROP INDEX to remove an index." msgstr "请使用 DROP INDEX 删除一个索引." -#: commands/tablecmds.c:247 +#: commands/tablecmds.c:254 #, c-format msgid "\"%s\" is not a type" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç±»åž‹" -#: commands/tablecmds.c:248 +#: commands/tablecmds.c:255 msgid "Use DROP TYPE to remove a type." msgstr "请使用 DROP TYPE 删除一个类型." -#: commands/tablecmds.c:251 commands/tablecmds.c:8488 -#: commands/tablecmds.c:11196 +#: commands/tablecmds.c:258 commands/tablecmds.c:11026 +#: commands/tablecmds.c:13887 #, c-format msgid "foreign table \"%s\" does not exist" msgstr "外部表 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:252 +#: commands/tablecmds.c:259 #, c-format msgid "foreign table \"%s\" does not exist, skipping" msgstr "外部表 \"%s\" ä¸å­˜åœ¨, 跳过" -#: commands/tablecmds.c:254 +#: commands/tablecmds.c:261 msgid "Use DROP FOREIGN TABLE to remove a foreign table." msgstr "请使用 DROP FOREIGN TABLE 删除一个外部表." -#: commands/tablecmds.c:493 +#: commands/tablecmds.c:589 #, c-format msgid "ON COMMIT can only be used on temporary tables" msgstr "ON COMMIT åªèƒ½è¢«ç”¨äºŽä¸´æ—¶è¡¨" -#: commands/tablecmds.c:513 +#: commands/tablecmds.c:620 #, c-format msgid "cannot create temporary table within security-restricted operation" msgstr "ä¸èƒ½åœ¨å®‰å…¨é™åˆ¶çš„æ“ä½œä¸­åˆ›å»ºä¸´æ—¶è¡¨" -#: commands/tablecmds.c:821 +#: commands/tablecmds.c:656 commands/tablecmds.c:12791 +#, c-format +msgid "relation \"%s\" would be inherited from more than once" +msgstr "关系 \"%s\" 将被继承多次" + +#: commands/tablecmds.c:826 +#, fuzzy, c-format +#| msgid "exclusion constraints are not supported on partitioned tables" +msgid "specifying a table access method is not supported on a partitioned table" +msgstr "åˆ†åŒºè¡¨ä¸Šä¸æ”¯æŒæŽ’除约æŸ" + +#: commands/tablecmds.c:922 +#, c-format +msgid "\"%s\" is not partitioned" +msgstr "\"%s\" 未分区" + +#: commands/tablecmds.c:1015 +#, c-format +msgid "cannot partition using more than %d columns" +msgstr "无法使用超过%d列进行分区" + +#: commands/tablecmds.c:1218 #, c-format msgid "DROP INDEX CONCURRENTLY does not support dropping multiple objects" msgstr "DROP INDEX CONCURRENTLY䏿”¯æŒåŒæ—¶åˆ é™¤å¤šä¸ªå¯¹è±¡" -#: commands/tablecmds.c:825 +#: commands/tablecmds.c:1222 #, c-format msgid "DROP INDEX CONCURRENTLY does not support CASCADE" msgstr "DROP INDEX CONCURRENTLY 䏿”¯æŒçº§è”æ“作" -#: commands/tablecmds.c:1084 +#: commands/tablecmds.c:1564 +#, c-format +msgid "cannot truncate only a partitioned table" +msgstr "ä¸èƒ½åªæˆªæ–­åˆ†åŒºè¡¨" + +#: commands/tablecmds.c:1565 +#, c-format +msgid "Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly." +msgstr "ä¸è¦æŒ‡å®šONLY关键字,或者分区上直接使用TRUNCATE ONLY." + +#: commands/tablecmds.c:1634 #, c-format msgid "truncate cascades to table \"%s\"" msgstr "çº§è”æˆªæ–­è¡¨\"%s\"" -#: commands/tablecmds.c:1322 +#: commands/tablecmds.c:1929 #, c-format msgid "cannot truncate temporary tables of other sessions" msgstr "ä¸èƒ½ç¼©çŸ­å…¶ä»–会è¯çš„临时表" -#: commands/tablecmds.c:1528 parser/parse_utilcmd.c:1857 +#: commands/tablecmds.c:2149 commands/tablecmds.c:12688 +#, c-format +msgid "cannot inherit from partitioned table \"%s\"" +msgstr "无法从分区表\"%s\"继承" + +#: commands/tablecmds.c:2154 +#, c-format +msgid "cannot inherit from partition \"%s\"" +msgstr "无法从分区\"%s\"继承" + +#: commands/tablecmds.c:2162 parser/parse_utilcmd.c:2269 +#: parser/parse_utilcmd.c:2410 #, c-format msgid "inherited relation \"%s\" is not a table or foreign table" msgstr "被继承的关系\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨æˆ–外部表" -#: commands/tablecmds.c:1535 commands/tablecmds.c:10055 +#: commands/tablecmds.c:2174 +#, c-format +msgid "cannot create a temporary relation as partition of permanent relation \"%s\"" +msgstr "无法创建临时关系作为永久关系的分区\"%s\"" + +#: commands/tablecmds.c:2183 commands/tablecmds.c:12667 #, c-format msgid "cannot inherit from temporary relation \"%s\"" msgstr "ä¸èƒ½ä»Žä¸´æ—¶å…³ç³» \"%s\" 继承" -#: commands/tablecmds.c:1543 commands/tablecmds.c:10063 +#: commands/tablecmds.c:2193 commands/tablecmds.c:12675 #, c-format msgid "cannot inherit from temporary relation of another session" msgstr "ä¸èƒ½ä»Žå¦ä¸€ä¸ªä¼šè¯çš„临时关系继承" -#: commands/tablecmds.c:1559 commands/tablecmds.c:10097 -#, c-format -msgid "relation \"%s\" would be inherited from more than once" -msgstr "关系 \"%s\" 将被继承多次" - -#: commands/tablecmds.c:1607 +#: commands/tablecmds.c:2245 #, c-format msgid "merging multiple inherited definitions of column \"%s\"" msgstr "åˆå¹¶å±žæ€§ \"%s\" 的多个继承定义" -#: commands/tablecmds.c:1615 +#: commands/tablecmds.c:2253 #, c-format msgid "inherited column \"%s\" has a type conflict" msgstr "继承属性 \"%s\" 类型冲çª" -#: commands/tablecmds.c:1617 commands/tablecmds.c:1640 -#: commands/tablecmds.c:1838 commands/tablecmds.c:1862 -#: parser/parse_coerce.c:1630 parser/parse_coerce.c:1650 -#: parser/parse_coerce.c:1670 parser/parse_coerce.c:1715 -#: parser/parse_coerce.c:1752 parser/parse_param.c:218 +#: commands/tablecmds.c:2255 commands/tablecmds.c:2278 +#: commands/tablecmds.c:2491 commands/tablecmds.c:2521 +#: parser/parse_coerce.c:1721 parser/parse_coerce.c:1741 +#: parser/parse_coerce.c:1761 parser/parse_coerce.c:1807 +#: parser/parse_coerce.c:1846 parser/parse_param.c:218 #, c-format msgid "%s versus %s" msgstr "%s 对 %s" -#: commands/tablecmds.c:1626 +#: commands/tablecmds.c:2264 #, c-format msgid "inherited column \"%s\" has a collation conflict" msgstr "继承列 \"%s\" 出现排åºè§„则冲çª" -#: commands/tablecmds.c:1628 commands/tablecmds.c:1850 -#: commands/tablecmds.c:4768 +#: commands/tablecmds.c:2266 commands/tablecmds.c:2503 +#: commands/tablecmds.c:5586 #, c-format msgid "\"%s\" versus \"%s\"" msgstr "\"%s\" 对 \"%s\"" -#: commands/tablecmds.c:1638 +#: commands/tablecmds.c:2276 #, c-format msgid "inherited column \"%s\" has a storage parameter conflict" msgstr "继承列 \"%s\" æœ‰ä¸€ä¸ªå­˜å‚¨å‚æ•°å†²çª" -#: commands/tablecmds.c:1751 parser/parse_utilcmd.c:938 -#: parser/parse_utilcmd.c:1287 parser/parse_utilcmd.c:1363 +#: commands/tablecmds.c:2292 +#, fuzzy, c-format +#| msgid "inherited column \"%s\" has a collation conflict" +msgid "inherited column \"%s\" has a generation conflict" +msgstr "继承列 \"%s\" 出现排åºè§„则冲çª" + +#: commands/tablecmds.c:2397 commands/tablecmds.c:10398 +#: parser/parse_utilcmd.c:1063 parser/parse_utilcmd.c:1149 +#: parser/parse_utilcmd.c:1562 parser/parse_utilcmd.c:1669 #, c-format msgid "cannot convert whole-row table reference" msgstr "æ— æ³•è½¬æ¢æ•´è¡Œè¡¨å¼•用" -#: commands/tablecmds.c:1752 parser/parse_utilcmd.c:939 +#: commands/tablecmds.c:2398 parser/parse_utilcmd.c:1150 #, c-format msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." msgstr "约æŸ\"%s\"包å«åˆ°è¡¨\"%s\"的整行引用." -#: commands/tablecmds.c:1824 +#: commands/tablecmds.c:2477 #, c-format msgid "merging column \"%s\" with inherited definition" msgstr "åˆå¹¶å±žæ€§ \"%s\" 连åŒç»§æ‰¿å®šä¹‰" -#: commands/tablecmds.c:1828 +#: commands/tablecmds.c:2481 #, c-format msgid "moving and merging column \"%s\" with inherited definition" msgstr "移动\"%s\"并且将它与继承的定义åˆå¹¶" -#: commands/tablecmds.c:1829 +#: commands/tablecmds.c:2482 #, c-format msgid "User-specified column moved to the position of the inherited column." msgstr "被移动到继承列ä½ç½®çš„用户指定列。" -#: commands/tablecmds.c:1836 +#: commands/tablecmds.c:2489 #, c-format msgid "column \"%s\" has a type conflict" msgstr "属性 \"%s\" 类型冲çª" -#: commands/tablecmds.c:1848 +#: commands/tablecmds.c:2501 #, c-format msgid "column \"%s\" has a collation conflict" msgstr "列 \"%s\" 出现排åºè§„则冲çª" -#: commands/tablecmds.c:1860 +#: commands/tablecmds.c:2519 #, c-format msgid "column \"%s\" has a storage parameter conflict" msgstr "列 \"%s\" 带有一个冲çªçš„å­˜å‚¨å‚æ•°" -#: commands/tablecmds.c:1912 +#: commands/tablecmds.c:2622 #, c-format msgid "column \"%s\" inherits conflicting default values" msgstr "属性 \"%s\" 继承与默认值冲çª" -#: commands/tablecmds.c:1914 +#: commands/tablecmds.c:2624 #, c-format msgid "To resolve the conflict, specify a default explicitly." msgstr "è¦è§£å†³å†²çª, 指定明确的默认值" -#: commands/tablecmds.c:1961 +#: commands/tablecmds.c:2669 #, c-format -msgid "" -"check constraint name \"%s\" appears multiple times but with different " -"expressions" +msgid "check constraint name \"%s\" appears multiple times but with different expressions" msgstr "检查约æŸåç§°\"%s\"出现多次,但是带有ä¸åŒçš„表达å¼" -#: commands/tablecmds.c:2155 +#: commands/tablecmds.c:2846 #, c-format msgid "cannot rename column of typed table" msgstr "æ— æ³•é‡æ–°å‘½å已确定类型表(typed table)的列" -#: commands/tablecmds.c:2172 +#: commands/tablecmds.c:2865 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, composite type, index, or " -"foreign table" +msgid "\"%s\" is not a table, view, materialized view, composite type, index, or foreign table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨,视图,物化视图,组åˆç±»åž‹,索引或者外部表" -#: commands/tablecmds.c:2266 +#: commands/tablecmds.c:2959 #, c-format msgid "inherited column \"%s\" must be renamed in child tables too" msgstr "在å­è¡¨ä¸­ç»§æ‰¿å±žæ€§ \"%s\" 也必需é‡å‘½å" -#: commands/tablecmds.c:2298 +#: commands/tablecmds.c:2991 #, c-format msgid "cannot rename system column \"%s\"" msgstr "ä¸èƒ½å¯¹ç³»ç»Ÿå­—段 \"%s\" é‡å‘½å" -#: commands/tablecmds.c:2313 +#: commands/tablecmds.c:3006 #, c-format msgid "cannot rename inherited column \"%s\"" msgstr "ä¸èƒ½å¯¹ç»§æ‰¿å­—段 \"%s\" é‡å‘½å" -#: commands/tablecmds.c:2468 +#: commands/tablecmds.c:3158 #, c-format msgid "inherited constraint \"%s\" must be renamed in child tables too" msgstr "ç»§æ‰¿çº¦æŸ \"%s\" 在å­è¡¨ä¸­ä¹Ÿå¿…é¡»é‡å‘½å" -#: commands/tablecmds.c:2475 +#: commands/tablecmds.c:3165 #, c-format msgid "cannot rename inherited constraint \"%s\"" msgstr "无法é‡å‘½å约æŸ\"%s\"" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2701 +#: commands/tablecmds.c:3398 #, c-format -msgid "" -"cannot %s \"%s\" because it is being used by active queries in this session" +msgid "cannot %s \"%s\" because it is being used by active queries in this session" msgstr "无法%s \"%s\" 因为它正在被这个会è¯ä¸­çš„æ´»åŠ¨æŸ¥è¯¢ä½¿ç”¨" #. translator: first %s is a SQL command, eg ALTER TABLE -#: commands/tablecmds.c:2710 +#: commands/tablecmds.c:3408 #, c-format msgid "cannot %s \"%s\" because it has pending trigger events" msgstr "无法%s \"%s\"因为它有一个待å‘生的触å‘器事件" -#: commands/tablecmds.c:3786 +#: commands/tablecmds.c:4536 #, c-format msgid "cannot rewrite system relation \"%s\"" msgstr "ä¸èƒ½æ”¹å†™ç³»ç»Ÿå…³ç³» \"%s\"" -#: commands/tablecmds.c:3792 +#: commands/tablecmds.c:4542 #, c-format msgid "cannot rewrite table \"%s\" used as a catalog table" msgstr "无法é‡å†™è¡¨\"%s\",以用作一个目录表" -#: commands/tablecmds.c:3802 +#: commands/tablecmds.c:4552 #, c-format msgid "cannot rewrite temporary tables of other sessions" msgstr "ä¸èƒ½æ”¹å†™å…¶ä»–会è¯çš„临时表" -#: commands/tablecmds.c:4070 +#: commands/tablecmds.c:4831 #, c-format msgid "rewriting table \"%s\"" msgstr "é‡å†™è¡¨ \"%s\"" -#: commands/tablecmds.c:4074 +#: commands/tablecmds.c:4835 #, c-format msgid "verifying table \"%s\"" msgstr "校验表\"%s\"" -#: commands/tablecmds.c:4188 +#: commands/tablecmds.c:4965 #, c-format msgid "column \"%s\" contains null values" msgstr "字段 \"%s\" 包å«ç©ºå€¼" -#: commands/tablecmds.c:4203 commands/tablecmds.c:7368 +#: commands/tablecmds.c:4981 commands/tablecmds.c:9635 #, c-format msgid "check constraint \"%s\" is violated by some row" msgstr "一些行è¿åäº†æ£€æŸ¥çº¦æŸ \"%s\"" -#: commands/tablecmds.c:4351 commands/trigger.c:235 -#: rewrite/rewriteDefine.c:267 rewrite/rewriteDefine.c:912 +#: commands/tablecmds.c:4999 #, c-format -msgid "\"%s\" is not a table or view" -msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè§†å›¾æˆ–视图" +msgid "updated partition constraint for default partition would be violated by some row" +msgstr "æŸäº›è¡Œå°†è¿å默认分区的更新分区约æŸ" + +#: commands/tablecmds.c:5003 +#, c-format +msgid "partition constraint is violated by some row" +msgstr "æŸäº›è¡Œè¿å了分区约æŸ" -#: commands/tablecmds.c:4354 commands/trigger.c:1119 commands/trigger.c:1224 +#: commands/tablecmds.c:5148 commands/trigger.c:1539 commands/trigger.c:1645 #, c-format msgid "\"%s\" is not a table, view, or foreign table" msgstr "\"%s\"䏿˜¯è¡¨ï¼Œè§†å›¾æˆ–外部表" -#: commands/tablecmds.c:4357 +#: commands/tablecmds.c:5151 #, c-format msgid "\"%s\" is not a table, view, materialized view, or index" msgstr "\"%s\" 䏿˜¯è¡¨,视图,物化视图,或者索引" -#: commands/tablecmds.c:4363 +#: commands/tablecmds.c:5157 #, c-format msgid "\"%s\" is not a table, materialized view, or index" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨,物化视图或索引" -#: commands/tablecmds.c:4366 +#: commands/tablecmds.c:5160 #, c-format msgid "\"%s\" is not a table, materialized view, or foreign table" msgstr "\"%s\"䏿˜¯è¡¨ã€ç‰©åŒ–视图或者外部表" -#: commands/tablecmds.c:4369 +#: commands/tablecmds.c:5163 #, c-format msgid "\"%s\" is not a table or foreign table" msgstr "\"%s\" 䏿˜¯è¡¨æˆ–外部表" -#: commands/tablecmds.c:4372 +#: commands/tablecmds.c:5166 #, c-format msgid "\"%s\" is not a table, composite type, or foreign table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨,组åˆç±»åž‹æˆ–者外部表" -#: commands/tablecmds.c:4375 commands/tablecmds.c:5427 +#: commands/tablecmds.c:5169 commands/tablecmds.c:6644 #, c-format msgid "\"%s\" is not a table, materialized view, index, or foreign table" msgstr "\"%s\"䏿˜¯è¡¨ï¼Œç‰©åŒ–视图, 索引或外部表" -#: commands/tablecmds.c:4385 +#: commands/tablecmds.c:5179 #, c-format msgid "\"%s\" is of the wrong type" msgstr "\"%s\" 是一个错误类型" -#: commands/tablecmds.c:4537 commands/tablecmds.c:4544 +#: commands/tablecmds.c:5354 commands/tablecmds.c:5361 #, c-format msgid "cannot alter type \"%s\" because column \"%s.%s\" uses it" msgstr "ä¸èƒ½ä¿®æ”¹ç±»åž‹ \"%s\", 因为列 \"%s.%s\"正在使用它" -#: commands/tablecmds.c:4551 +#: commands/tablecmds.c:5368 #, c-format -msgid "" -"cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" +msgid "cannot alter foreign table \"%s\" because column \"%s.%s\" uses its row type" msgstr "无法修改外部表\"%s\" ,因为列\"%s.%s\"使用它的行类型" -#: commands/tablecmds.c:4558 +#: commands/tablecmds.c:5375 #, c-format msgid "cannot alter table \"%s\" because column \"%s.%s\" uses its row type" msgstr "无法修改表\"%s\" ,因为列\"%s.%s\"使用它的行类型" -#: commands/tablecmds.c:4620 +#: commands/tablecmds.c:5431 #, c-format msgid "cannot alter type \"%s\" because it is the type of a typed table" msgstr "无法修改已确定类型表(typed table)中列的类型\"%s\"" -#: commands/tablecmds.c:4622 +#: commands/tablecmds.c:5433 #, c-format msgid "Use ALTER ... CASCADE to alter the typed tables too." msgstr "使用ALTER .. CASCADE 把类型表一并修改." -#: commands/tablecmds.c:4666 +#: commands/tablecmds.c:5479 #, c-format msgid "type %s is not a composite type" msgstr "类型 %s 䏿˜¯å¤åˆç±»åž‹" -#: commands/tablecmds.c:4692 +#: commands/tablecmds.c:5505 #, c-format msgid "cannot add column to typed table" msgstr "无法为已确定类型表(typed table)添加列" -#: commands/tablecmds.c:4760 commands/tablecmds.c:10256 +#: commands/tablecmds.c:5549 +#, c-format +msgid "cannot add column to a partition" +msgstr "无法将列添加到分区" + +#: commands/tablecmds.c:5578 commands/tablecmds.c:12918 #, c-format msgid "child table \"%s\" has different type for column \"%s\"" msgstr "å­è¡¨ \"%s\" 的字段 \"%s\" 有ä¸åŒçš„类型" -#: commands/tablecmds.c:4766 commands/tablecmds.c:10263 +#: commands/tablecmds.c:5584 commands/tablecmds.c:12925 #, c-format msgid "child table \"%s\" has different collation for column \"%s\"" msgstr "å­è¡¨ \"%s\" 的字段 \"%s\" 有ä¸åŒçš„æŽ’åºè§„则" -#: commands/tablecmds.c:4776 -#, c-format -msgid "child table \"%s\" has a conflicting \"%s\" column" -msgstr "å­è¡¨\"%s\"有一个冲çªåˆ—\"%s\"" - -#: commands/tablecmds.c:4788 +#: commands/tablecmds.c:5598 #, c-format msgid "merging definition of column \"%s\" for child \"%s\"" msgstr "åˆå¹¶å­è¡¨ \"%2$s\" 的字段 \"%1$s\" 定义" -#: commands/tablecmds.c:5015 +#: commands/tablecmds.c:5622 +#, c-format +msgid "cannot recursively add identity column to table that has child tables" +msgstr "无法将标识列递归添加到具有å­è¡¨çš„表中" + +#: commands/tablecmds.c:5856 #, c-format msgid "column must be added to child tables too" msgstr "属性也必需加入到å­è¡¨ä¸­" -#: commands/tablecmds.c:5090 +#: commands/tablecmds.c:5931 #, c-format -#| msgid "column \"%s\" of relation \"%s\" already exists" msgid "column \"%s\" of relation \"%s\" already exists, skipping" msgstr "关系 \"%2$s\" 的列 \"%1$s\" å·²ç»å­˜åœ¨ï¼Œè·³è¿‡" -#: commands/tablecmds.c:5097 +#: commands/tablecmds.c:5938 #, c-format msgid "column \"%s\" of relation \"%s\" already exists" msgstr "关系 \"%s\" 的属性 \"%s\" å·²ç»å­˜åœ¨" -#: commands/tablecmds.c:5208 commands/tablecmds.c:5314 -#: commands/tablecmds.c:5372 commands/tablecmds.c:5486 -#: commands/tablecmds.c:5543 commands/tablecmds.c:5637 -#: commands/tablecmds.c:7886 commands/tablecmds.c:8511 +#: commands/tablecmds.c:6004 commands/tablecmds.c:10078 +#, c-format +msgid "cannot remove constraint from only the partitioned table when partitions exist" +msgstr "存在分区时,ä¸èƒ½ä»…从分区表中删除约æŸ" + +#: commands/tablecmds.c:6005 commands/tablecmds.c:6274 +#: commands/tablecmds.c:7042 commands/tablecmds.c:10079 +#, c-format +msgid "Do not specify the ONLY keyword." +msgstr "ä¸è¦æŒ‡å®šONLY关键字" + +#: commands/tablecmds.c:6042 commands/tablecmds.c:6200 +#: commands/tablecmds.c:6342 commands/tablecmds.c:6425 +#: commands/tablecmds.c:6519 commands/tablecmds.c:6578 +#: commands/tablecmds.c:6728 commands/tablecmds.c:6798 +#: commands/tablecmds.c:6890 commands/tablecmds.c:10218 +#: commands/tablecmds.c:11049 #, c-format msgid "cannot alter system column \"%s\"" msgstr "ä¸èƒ½æ›´æ”¹ç³»ç»Ÿå­—段 \"%s\"" -#: commands/tablecmds.c:5244 +#: commands/tablecmds.c:6048 commands/tablecmds.c:6348 +#, c-format +msgid "column \"%s\" of relation \"%s\" is an identity column" +msgstr "关系\"%2$s\"的列\"%1$s\"是标识列" + +#: commands/tablecmds.c:6084 #, c-format msgid "column \"%s\" is in a primary key" msgstr "字段 \"%s\" 是一个主键" -#: commands/tablecmds.c:5459 +#: commands/tablecmds.c:6106 +#, c-format +msgid "column \"%s\" is marked NOT NULL in parent table" +msgstr "列\"%s\"在父表中标记为NOT NULL" + +#: commands/tablecmds.c:6271 commands/tablecmds.c:7492 +#, c-format +msgid "constraint must be added to child tables too" +msgstr "必须也è¦å¯¹å­è¡¨åŠ ä¸Šçº¦æŸ" + +#: commands/tablecmds.c:6272 +#, fuzzy, c-format +#| msgid "column \"%s\" of relation \"%s\" already exists" +msgid "Column \"%s\" of relation \"%s\" is not already NOT NULL." +msgstr "关系 \"%s\" 的属性 \"%s\" å·²ç»å­˜åœ¨" + +#: commands/tablecmds.c:6307 +#, c-format +msgid "existing constraints on column \"%s\".\"%s\" are sufficient to prove that it does not contain nulls" +msgstr "" + +#: commands/tablecmds.c:6350 +#, c-format +msgid "Use ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY instead." +msgstr "用ALTER TABLE ... ALTER COLUMN ... DROP IDENTITY代替" + +#: commands/tablecmds.c:6355 +#, fuzzy, c-format +#| msgid "column \"%s\" of relation \"%s\" is an identity column" +msgid "column \"%s\" of relation \"%s\" is a generated column" +msgstr "关系\"%2$s\"的列\"%1$s\"是标识列" + +#: commands/tablecmds.c:6436 +#, c-format +msgid "column \"%s\" of relation \"%s\" must be declared NOT NULL before identity can be added" +msgstr "在添加标识之å‰ï¼Œå¿…须声明关系\"%2$s\"的列\"%1$s\"为NOT NULL" + +#: commands/tablecmds.c:6442 +#, c-format +msgid "column \"%s\" of relation \"%s\" is already an identity column" +msgstr "关系\"%2$s\"的列\"%1$s\"å·²ç»æ˜¯æ ‡è¯†åˆ—" + +#: commands/tablecmds.c:6448 +#, c-format +msgid "column \"%s\" of relation \"%s\" already has a default value" +msgstr "关系\"%2$s\"的列\"%1$s\"已具有默认值" + +#: commands/tablecmds.c:6525 commands/tablecmds.c:6586 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column" +msgstr "关系\"%2$s\"的列\"%1$s\"䏿˜¯æ ‡è¯†åˆ—" + +#: commands/tablecmds.c:6591 +#, c-format +msgid "column \"%s\" of relation \"%s\" is not an identity column, skipping" +msgstr "关系\"%2$s\"的列\"%1$s\"䏿˜¯æ ‡è¯†åˆ—,跳过" + +#: commands/tablecmds.c:6656 +#, c-format +msgid "cannot refer to non-index column by number" +msgstr "ä¸èƒ½æŒ‰æ•°å­—引用éžç´¢å¼•列" + +#: commands/tablecmds.c:6687 #, c-format msgid "statistics target %d is too low" msgstr "目标统计 %d 太低" -#: commands/tablecmds.c:5467 +#: commands/tablecmds.c:6695 #, c-format msgid "lowering statistics target to %d" msgstr "é™ä½Žç›®æ ‡ç»Ÿè®¡åˆ° %d" -#: commands/tablecmds.c:5617 +#: commands/tablecmds.c:6718 +#, c-format +msgid "column number %d of relation \"%s\" does not exist" +msgstr "在关系\"%2$s\"ä¸­çš„åˆ—å· %1$d ä¸å­˜åœ¨" + +#: commands/tablecmds.c:6737 +#, c-format +msgid "cannot alter statistics on included column \"%s\" of index \"%s\"" +msgstr "无法更改索引\"%2$s\"的包å«åˆ—\"%1$s\"的统计信æ¯" + +#: commands/tablecmds.c:6742 +#, c-format +msgid "cannot alter statistics on non-expression column \"%s\" of index \"%s\"" +msgstr "无法更改索引\"%2$s\"çš„éžè¡¨è¾¾å¼åˆ—\"%1$s\"的统计信æ¯" + +#: commands/tablecmds.c:6744 +#, c-format +msgid "Alter statistics on table column instead." +msgstr "改为更改表列的统计信æ¯." + +#: commands/tablecmds.c:6870 #, c-format msgid "invalid storage type \"%s\"" msgstr "无效存储类型 \"%s\"" -#: commands/tablecmds.c:5649 +#: commands/tablecmds.c:6902 #, c-format msgid "column data type %s can only have storage PLAIN" msgstr "字段数æ®ç±»åž‹ %s åªèƒ½å­˜å‚¨ä¸ºæ˜Žæ–‡ (PLAIN)" -#: commands/tablecmds.c:5687 +#: commands/tablecmds.c:6937 #, c-format msgid "cannot drop column from typed table" msgstr "无法从已确定类型表(typed table)中删除列" -#: commands/tablecmds.c:5731 +#: commands/tablecmds.c:6982 #, c-format msgid "column \"%s\" of relation \"%s\" does not exist, skipping" -msgstr "关系 \"%2$s\" çš„ 列\"%1$s\"ä¸å­˜åœ¨" +msgstr "关系 \"%2$s\" çš„ 列\"%1$s\"ä¸å­˜åœ¨,跳过" -#: commands/tablecmds.c:5744 +#: commands/tablecmds.c:6995 #, c-format msgid "cannot drop system column \"%s\"" msgstr "ä¸èƒ½åˆ é™¤ç³»ç»Ÿå­—段 \"%s\"" -#: commands/tablecmds.c:5751 +#: commands/tablecmds.c:7002 #, c-format msgid "cannot drop inherited column \"%s\"" msgstr "ä¸èƒ½åˆ é™¤ç»§æ‰¿å­—段 \"%s\"" -#: commands/tablecmds.c:5991 +#: commands/tablecmds.c:7013 #, c-format -msgid "" -"ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" -msgstr "" -"ALTER TABLE / ADD CONSTRAINT USING INDEX 会把索引 \"%s\" é‡å‘½å为 \"%s\"" +msgid "cannot drop column named in partition key" +msgstr "无法删除分区键中的命å列" -#: commands/tablecmds.c:6204 +#: commands/tablecmds.c:7017 #, c-format -msgid "constraint must be added to child tables too" -msgstr "必须也è¦å¯¹å­è¡¨åŠ ä¸Šçº¦æŸ" +msgid "cannot drop column referenced in partition key expression" +msgstr "无法删除分区键表达å¼ä¸­å¼•用的列" + +#: commands/tablecmds.c:7041 +#, c-format +msgid "cannot drop column from only the partitioned table when partitions exist" +msgstr "存在分区时,ä¸èƒ½åªä»Žåˆ†åŒºè¡¨ä¸­åˆ é™¤åˆ—" + +#: commands/tablecmds.c:7213 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables" +msgstr "åˆ†åŒºè¡¨ä¸æ”¯æŒALTER TABLE / ADD CONSTRAINT USING INDEX" + +#: commands/tablecmds.c:7238 +#, c-format +msgid "ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index \"%s\" to \"%s\"" +msgstr "ALTER TABLE / ADD CONSTRAINT USING INDEX 会把索引 \"%s\" é‡å‘½å为 \"%s\"" + +#: commands/tablecmds.c:7572 +#, c-format +msgid "cannot use ONLY for foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "ä¸èƒ½å¯¹å¼•用关系\"%2$s\"的分区表\"%1$s\"使用ONLY作为外键" + +#: commands/tablecmds.c:7578 +#, c-format +msgid "cannot add NOT VALID foreign key on partitioned table \"%s\" referencing relation \"%s\"" +msgstr "无法在引用关系\"%2$s\"的分区表\"%1$s\"添加 NOT VALID外键" + +#: commands/tablecmds.c:7581 +#, c-format +msgid "This feature is not yet supported on partitioned tables." +msgstr "åˆ†åŒºè¡¨å°šä¸æ”¯æŒæ­¤åŠŸèƒ½" -#: commands/tablecmds.c:6275 +#: commands/tablecmds.c:7588 commands/tablecmds.c:7993 #, c-format msgid "referenced relation \"%s\" is not a table" msgstr "å…³è”的关系 \"%s\" 䏿˜¯ä¸€ä¸ªè¡¨" -#: commands/tablecmds.c:6298 +#: commands/tablecmds.c:7611 #, c-format msgid "constraints on permanent tables may reference only permanent tables" msgstr "永久表上的约æŸåªèƒ½å¼•用永久表" -#: commands/tablecmds.c:6305 +#: commands/tablecmds.c:7618 #, c-format -msgid "" -"constraints on unlogged tables may reference only permanent or unlogged " -"tables" +msgid "constraints on unlogged tables may reference only permanent or unlogged tables" msgstr "无事务日志的表上的约æŸåªèƒ½å¼•用æŒä¹…表或者无事务日志的表" -#: commands/tablecmds.c:6311 +#: commands/tablecmds.c:7624 #, c-format msgid "constraints on temporary tables may reference only temporary tables" msgstr "临时表上的约æŸåªèƒ½å¼•用临时表" -#: commands/tablecmds.c:6315 +#: commands/tablecmds.c:7628 #, c-format -msgid "" -"constraints on temporary tables must involve temporary tables of this session" +msgid "constraints on temporary tables must involve temporary tables of this session" msgstr "临时表上的约æŸåªèƒ½å¼•用该会è¯é‡Œçš„临时表" -#: commands/tablecmds.c:6376 +#: commands/tablecmds.c:7694 commands/tablecmds.c:7700 +#, fuzzy, c-format +#| msgid "validating foreign key constraint \"%s\"" +msgid "invalid %s action for foreign key constraint containing generated column" +msgstr "正验è¯å¤–é”®çº¦æŸ \"%s\"" + +#: commands/tablecmds.c:7716 #, c-format msgid "number of referencing and referenced columns for foreign key disagree" msgstr "å¤–é”®çš„å…³è”æ•°å’Œå…³è”字段ä¸ä¸€è‡´" -#: commands/tablecmds.c:6483 +#: commands/tablecmds.c:7823 #, c-format msgid "foreign key constraint \"%s\" cannot be implemented" msgstr "æ— æ³•å®žçŽ°å¤–é”®çº¦æŸ \"%s\"" -#: commands/tablecmds.c:6486 +#: commands/tablecmds.c:7825 #, c-format msgid "Key columns \"%s\" and \"%s\" are of incompatible types: %s and %s." msgstr "关键字段 \"%s\" å’Œ \"%s\" 为混和类型: %s å’Œ %s." -#: commands/tablecmds.c:6693 commands/tablecmds.c:6843 -#: commands/tablecmds.c:7725 commands/tablecmds.c:7781 +#: commands/tablecmds.c:8189 commands/tablecmds.c:8577 +#: parser/parse_utilcmd.c:753 parser/parse_utilcmd.c:882 +#, c-format +msgid "foreign key constraints are not supported on foreign tables" +msgstr "å¤–éƒ¨è¡¨ä¸Šä¸æ”¯æŒå¤–键约æŸ" + +#: commands/tablecmds.c:8944 commands/tablecmds.c:9107 +#: commands/tablecmds.c:10035 commands/tablecmds.c:10110 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist" msgstr "关系 \"%2$s\" çš„ 约æŸ\"%1$s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:6699 +#: commands/tablecmds.c:8951 #, c-format msgid "constraint \"%s\" of relation \"%s\" is not a foreign key constraint" msgstr "关系 \"%2$s\" çš„ 约æŸ\"%1$s\"䏿˜¯å¤–键约æŸ" -#: commands/tablecmds.c:6850 +#: commands/tablecmds.c:9115 #, c-format -msgid "" -"constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" +msgid "constraint \"%s\" of relation \"%s\" is not a foreign key or check constraint" msgstr "关系 \"%2$s\" çš„ 约æŸ\"%1$s\"䏿˜¯å¤–é”®ï¼Œä¹Ÿä¸æ˜¯check约æŸ" -#: commands/tablecmds.c:6918 +#: commands/tablecmds.c:9185 #, c-format msgid "constraint must be validated on child tables too" msgstr "å­è¡¨ä¸Šçš„约æŸä¹Ÿå¿…须进行验è¯" -#: commands/tablecmds.c:6987 +#: commands/tablecmds.c:9251 #, c-format msgid "column \"%s\" referenced in foreign key constraint does not exist" msgstr "在外键约æŸä¸­çš„å…³è”字段 \"%s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:6992 +#: commands/tablecmds.c:9256 #, c-format msgid "cannot have more than %d keys in a foreign key" msgstr "在一个外键中ä¸èƒ½è¶…过 %d 个键" -#: commands/tablecmds.c:7057 +#: commands/tablecmds.c:9321 #, c-format msgid "cannot use a deferrable primary key for referenced table \"%s\"" msgstr "无法为被引用的表\"%s\"使用å¯å»¶è¿Ÿçš„主键" -#: commands/tablecmds.c:7074 +#: commands/tablecmds.c:9338 #, c-format msgid "there is no primary key for referenced table \"%s\"" msgstr "å…³è”表 \"%s\" 没有主键" -#: commands/tablecmds.c:7139 +#: commands/tablecmds.c:9403 #, c-format msgid "foreign key referenced-columns list must not contain duplicates" msgstr "外键å‚照列的列表ä¸èƒ½æœ‰é‡å¤å€¼" -#: commands/tablecmds.c:7233 +#: commands/tablecmds.c:9497 #, c-format msgid "cannot use a deferrable unique constraint for referenced table \"%s\"" msgstr "无法为被引用的表\"%s\"使用å¯å»¶è¿Ÿçš„唯一性约æŸ" -#: commands/tablecmds.c:7238 +#: commands/tablecmds.c:9502 #, c-format -msgid "" -"there is no unique constraint matching given keys for referenced table \"%s\"" +msgid "there is no unique constraint matching given keys for referenced table \"%s\"" msgstr "没有唯一约æŸä¸Žå…³è”表 \"%s\" 给定的键值匹é…" -#: commands/tablecmds.c:7401 +#: commands/tablecmds.c:9670 #, c-format msgid "validating foreign key constraint \"%s\"" msgstr "正验è¯å¤–é”®çº¦æŸ \"%s\"" -#: commands/tablecmds.c:7697 +#: commands/tablecmds.c:9991 #, c-format msgid "cannot drop inherited constraint \"%s\" of relation \"%s\"" msgstr "ä¸èƒ½åˆ é™¤å…³ç³»\"%2$s\"的继承约æŸ\"%1$s\"" -#: commands/tablecmds.c:7731 +#: commands/tablecmds.c:10041 #, c-format msgid "constraint \"%s\" of relation \"%s\" does not exist, skipping" msgstr "关系 \"%2$s\" çš„ 约æŸ\"%1$s\" ä¸å­˜åœ¨" -#: commands/tablecmds.c:7870 +#: commands/tablecmds.c:10202 #, c-format msgid "cannot alter column type of typed table" msgstr "无法修改已确定类型表(typed table)中列的类型" -#: commands/tablecmds.c:7893 +#: commands/tablecmds.c:10225 #, c-format msgid "cannot alter inherited column \"%s\"" msgstr "ä¸èƒ½ä¿®æ”¹ç»§æ‰¿å­—段 \"%s\"" -#: commands/tablecmds.c:7942 +#: commands/tablecmds.c:10236 #, c-format -msgid "" -"result of USING clause for column \"%s\" cannot be cast automatically to " -"type %s" +msgid "cannot alter type of column named in partition key" +msgstr "无法更改分区键中命å列的类型" + +#: commands/tablecmds.c:10240 +#, c-format +msgid "cannot alter type of column referenced in partition key expression" +msgstr "无法更改分区键表达å¼ä¸­å¼•用的列的类型" + +#: commands/tablecmds.c:10290 +#, c-format +msgid "result of USING clause for column \"%s\" cannot be cast automatically to type %s" msgstr "用于列\"%s\"çš„USINGå­å¥çš„结果ä¸èƒ½è¢«è‡ªåŠ¨åœ°è½¬æ¢æˆç±»åž‹%s" -#: commands/tablecmds.c:7945 +#: commands/tablecmds.c:10293 #, c-format msgid "You might need to add an explicit cast." msgstr "您å¯èƒ½éœ€è¦å¢žåŠ ä¸€ä¸ªæ˜¾å¼è½¬æ¢ã€‚" -#: commands/tablecmds.c:7949 +#: commands/tablecmds.c:10297 #, c-format msgid "column \"%s\" cannot be cast automatically to type %s" msgstr "字段 \"%s\" ä¸èƒ½è‡ªåŠ¨è½¬æ¢æˆç±»åž‹ %s" #. translator: USING is SQL, don't translate it -#: commands/tablecmds.c:7952 +#: commands/tablecmds.c:10300 #, c-format msgid "You might need to specify \"USING %s::%s\"." msgstr "您å¯èƒ½éœ€è¦æŒ‡å®š\"USING %s::%s\"。" -#: commands/tablecmds.c:8005 +#: commands/tablecmds.c:10399 +#, c-format +msgid "USING expression contains a whole-row table reference." +msgstr "USING表达å¼åŒ…嫿•´è¡Œè¡¨å¼•用." + +#: commands/tablecmds.c:10410 #, c-format msgid "type of inherited column \"%s\" must be changed in child tables too" msgstr "在å­è¡¨ä¸­ç»§æ‰¿å­—段 \"%s\" 的类型也必需改å˜" -#: commands/tablecmds.c:8092 +#: commands/tablecmds.c:10535 #, c-format msgid "cannot alter type of column \"%s\" twice" msgstr "ä¸èƒ½æ›´æ”¹å­—段 \"%s\" 的类型两é" -#: commands/tablecmds.c:8128 +#: commands/tablecmds.c:10573 +#, fuzzy, c-format +#| msgid "default for column \"%s\" cannot be cast automatically to type %s" +msgid "generation expression for column \"%s\" cannot be cast automatically to type %s" +msgstr "字段 \"%s\" 的默认值ä¸èƒ½è½¬æ¢æˆç±»åž‹ %s" + +#: commands/tablecmds.c:10578 #, c-format msgid "default for column \"%s\" cannot be cast automatically to type %s" msgstr "字段 \"%s\" 的默认值ä¸èƒ½è½¬æ¢æˆç±»åž‹ %s" -#: commands/tablecmds.c:8254 +#: commands/tablecmds.c:10667 +#, fuzzy, c-format +#| msgid "cannot alter type of a column used by a view or rule" +msgid "cannot alter type of a column used by a generated column" +msgstr "ä¸èƒ½ä½¿ç”¨è§†å›¾æˆ–规则改å˜ä¸€ä¸ªå­—段的类型" + +#: commands/tablecmds.c:10668 +#, c-format +msgid "Column \"%s\" is used by generated column \"%s\"." +msgstr "" + +#: commands/tablecmds.c:10700 #, c-format msgid "cannot alter type of a column used by a view or rule" msgstr "ä¸èƒ½ä½¿ç”¨è§†å›¾æˆ–规则改å˜ä¸€ä¸ªå­—段的类型" -#: commands/tablecmds.c:8255 commands/tablecmds.c:8274 -#: commands/tablecmds.c:8292 +#: commands/tablecmds.c:10701 commands/tablecmds.c:10720 +#: commands/tablecmds.c:10738 #, c-format msgid "%s depends on column \"%s\"" msgstr "%s 倚赖于字段 \"%s\"" -#: commands/tablecmds.c:8273 +#: commands/tablecmds.c:10719 #, c-format msgid "cannot alter type of a column used in a trigger definition" msgstr "无法更改触å‘器定义中的列类型" -#: commands/tablecmds.c:8291 +#: commands/tablecmds.c:10737 #, c-format msgid "cannot alter type of a column used in a policy definition" msgstr "无法修改被用在策略定义中的列的类型" -#: commands/tablecmds.c:8956 +#: commands/tablecmds.c:11567 commands/tablecmds.c:11579 #, c-format msgid "cannot change owner of index \"%s\"" msgstr "无法改å˜ç´¢å¼•\"%s\" 的属主" -#: commands/tablecmds.c:8958 +#: commands/tablecmds.c:11569 commands/tablecmds.c:11581 #, c-format msgid "Change the ownership of the index's table, instead." msgstr "å¯ä»¥æ”¹å˜ç´¢å¼•表的所有æƒ" -#: commands/tablecmds.c:8974 +#: commands/tablecmds.c:11595 #, c-format msgid "cannot change owner of sequence \"%s\"" msgstr "无法改å˜åºåˆ— \"%s\"的属主" -#: commands/tablecmds.c:8976 commands/tablecmds.c:11398 -#, c-format -msgid "Sequence \"%s\" is linked to table \"%s\"." -msgstr "åºåˆ— \"%s\"已链接到表\"%s\"." - -#: commands/tablecmds.c:8988 commands/tablecmds.c:12045 +#: commands/tablecmds.c:11609 commands/tablecmds.c:14806 #, c-format msgid "Use ALTER TYPE instead." msgstr "请使用ALTER TYPE" -#: commands/tablecmds.c:8997 +#: commands/tablecmds.c:11618 #, c-format msgid "\"%s\" is not a table, view, sequence, or foreign table" msgstr "\"%s\" 䏿˜¯è¡¨,视图,åºåˆ—或者外部表" -#: commands/tablecmds.c:9340 +#: commands/tablecmds.c:11958 #, c-format msgid "cannot have multiple SET TABLESPACE subcommands" msgstr "无法执行多个SET TABLESPACEå­å‘½ä»¤" -#: commands/tablecmds.c:9413 +#: commands/tablecmds.c:12033 #, c-format msgid "\"%s\" is not a table, view, materialized view, index, or TOAST table" msgstr "\"%s\"䏿˜¯è¡¨ï¼Œè§†å›¾, 物化视图, 索引或TOAST表" -#: commands/tablecmds.c:9446 commands/view.c:481 +#: commands/tablecmds.c:12066 commands/view.c:504 #, c-format msgid "WITH CHECK OPTION is supported only on automatically updatable views" msgstr "WITH CHECK OPTIONåªèƒ½ç”¨äºŽè‡ªåŠ¨æ›´æ–°è§†å›¾ä¸Š" -#: commands/tablecmds.c:9592 +#: commands/tablecmds.c:12206 #, c-format msgid "cannot move system relation \"%s\"" msgstr "ä¸èƒ½åˆ é™¤ç³»ç»Ÿå…³ç³» \"%s\"" -#: commands/tablecmds.c:9608 +#: commands/tablecmds.c:12222 #, c-format msgid "cannot move temporary tables of other sessions" msgstr "ä¸èƒ½åœ¨å…¶ä»–会è¯ä¸­åˆ é™¤ä¸´æ—¶è¡¨" -#: commands/tablecmds.c:9745 +#: commands/tablecmds.c:12390 #, c-format msgid "only tables, indexes, and materialized views exist in tablespaces" msgstr "åªæœ‰è¡¨ã€ç´¢å¼•以åŠç‰©åŒ–视图存在于表空间当中" -#: commands/tablecmds.c:9757 +#: commands/tablecmds.c:12402 #, c-format msgid "cannot move relations in to or out of pg_global tablespace" msgstr "无法将关系移入或移出表空间pg_global" -#: commands/tablecmds.c:9848 +#: commands/tablecmds.c:12494 #, c-format msgid "aborting because lock on relation \"%s.%s\" is not available" msgstr "由于关系\"%s.%s\"上的é”ä¸å¯ç”¨è€Œä¸­æ­¢" # describe.c:1542 -#: commands/tablecmds.c:9864 +#: commands/tablecmds.c:12510 #, c-format msgid "no matching relations in tablespace \"%s\" found" msgstr "表空间\"%s\"中没有找到符åˆçš„关系" -#: commands/tablecmds.c:9938 storage/buffer/bufmgr.c:915 -#, c-format -msgid "invalid page in block %u of relation %s" -msgstr "关系 \"%2$s\" ä¸­çš„å— %1$u 存在无效的页" - -#: commands/tablecmds.c:10020 +#: commands/tablecmds.c:12626 #, c-format msgid "cannot change inheritance of typed table" msgstr "无法改å˜å·²ç¡®å®šç±»åž‹è¡¨(typed table)的继承性" -#: commands/tablecmds.c:10070 +#: commands/tablecmds.c:12631 commands/tablecmds.c:13127 +#, c-format +msgid "cannot change inheritance of a partition" +msgstr "无法更改分区的继承" + +#: commands/tablecmds.c:12636 +#, c-format +msgid "cannot change inheritance of partitioned table" +msgstr "无法更改分区表的继承" + +#: commands/tablecmds.c:12682 #, c-format msgid "cannot inherit to temporary relation of another session" msgstr "无法继承æ¥è‡ªå¦ä¸€ä¼šè¯ä¸­çš„临时关系" -#: commands/tablecmds.c:10124 +#: commands/tablecmds.c:12695 +#, c-format +msgid "cannot inherit from a partition" +msgstr "无法从分区继承" + +#: commands/tablecmds.c:12717 commands/tablecmds.c:15442 #, c-format msgid "circular inheritance not allowed" msgstr "ä¸å…许循环继承" -#: commands/tablecmds.c:10125 +#: commands/tablecmds.c:12718 commands/tablecmds.c:15443 #, c-format msgid "\"%s\" is already a child of \"%s\"." msgstr "\"%s\" å·²ç»æ˜¯ \"%s\"çš„å­è¡¨äº†." -#: commands/tablecmds.c:10133 +#: commands/tablecmds.c:12731 #, c-format -msgid "table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs" -msgstr "ä¸å¸¦æœ‰OIDs的表\"%s\"无法从带有OIDs的表\"%s\"继承。" +msgid "trigger \"%s\" prevents table \"%s\" from becoming an inheritance child" +msgstr "触å‘器\"%s\"阻止表\"%s\"æˆä¸ºç»§æ‰¿å­è¡¨" + +#: commands/tablecmds.c:12733 +#, fuzzy, c-format +#| msgid "ROW triggers with transition tables are not supported in inheritance hierarchies" +msgid "ROW triggers with transition tables are not supported in inheritance hierarchies." +msgstr "ç»§æ‰¿å±‚æ¬¡ç»“æž„ä¸­ä¸æ”¯æŒå…·æœ‰è½¬æ¢è¡¨çš„行触å‘器" -#: commands/tablecmds.c:10274 +#: commands/tablecmds.c:12936 #, c-format msgid "column \"%s\" in child table must be marked NOT NULL" msgstr "在å­è¡¨ä¸­çš„列\"%s\"必须标识为NOT NULL" -#: commands/tablecmds.c:10290 +#: commands/tablecmds.c:12963 #, c-format msgid "child table is missing column \"%s\"" msgstr "在å­è¡¨ä¸­æ²¡æœ‰åˆ—\"%s\"" -#: commands/tablecmds.c:10373 +#: commands/tablecmds.c:13051 #, c-format msgid "child table \"%s\" has different definition for check constraint \"%s\"" msgstr "å­è¡¨ \"%s\" 对于检查约æŸ\"%s\"有ä¸åŒçš„定义" -#: commands/tablecmds.c:10381 +#: commands/tablecmds.c:13059 #, c-format -msgid "" -"constraint \"%s\" conflicts with non-inherited constraint on child table \"%s" -"\"" +msgid "constraint \"%s\" conflicts with non-inherited constraint on child table \"%s\"" msgstr "çº¦æŸ \"%s\" 与å­è¡¨ä¸­çš„éžç»§æ‰¿çº¦æŸ \"%s\"相冲çª" -#: commands/tablecmds.c:10405 +#: commands/tablecmds.c:13070 +#, c-format +msgid "constraint \"%s\" conflicts with NOT VALID constraint on child table \"%s\"" +msgstr "约æŸ\"%s\"与å­è¡¨\"%s\"上的 NOT VALID 约æŸå†²çª" + +#: commands/tablecmds.c:13105 #, c-format msgid "child table is missing constraint \"%s\"" msgstr "å­è¡¨ä¸¢å¤±çº¦æŸ\"%s\"" -#: commands/tablecmds.c:10489 +#: commands/tablecmds.c:13194 +#, c-format +msgid "relation \"%s\" is not a partition of relation \"%s\"" +msgstr "关系\"%s\"䏿˜¯å…³ç³»\"%s\"的分区" + +#: commands/tablecmds.c:13200 #, c-format msgid "relation \"%s\" is not a parent of relation \"%s\"" msgstr "关系 \"%s\" 䏿˜¯å…³ç³»\"%s\"的父表" -#: commands/tablecmds.c:10723 +#: commands/tablecmds.c:13428 #, c-format msgid "typed tables cannot inherit" msgstr "类型表ä¸èƒ½ç»§æ‰¿" -#: commands/tablecmds.c:10754 +#: commands/tablecmds.c:13458 #, c-format msgid "table is missing column \"%s\"" msgstr "表中没有列\"%s\"" -#: commands/tablecmds.c:10764 +#: commands/tablecmds.c:13469 #, c-format msgid "table has column \"%s\" where type requires \"%s\"" msgstr "è¡¨ä¸­å«æœ‰åˆ—\"%s\",需è¦ç±»åž‹\"%s\"" -#: commands/tablecmds.c:10773 +#: commands/tablecmds.c:13478 #, c-format msgid "table \"%s\" has different type for column \"%s\"" msgstr "表\"%s\"中的列\"%s\"带有ä¸åŒçš„类型" -#: commands/tablecmds.c:10786 +#: commands/tablecmds.c:13492 #, c-format msgid "table has extra column \"%s\"" msgstr "è¡¨å«æœ‰å¤šä½™çš„列\"%s\"" -#: commands/tablecmds.c:10838 +#: commands/tablecmds.c:13544 #, c-format msgid "\"%s\" is not a typed table" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç±»åž‹è¡¨" -#: commands/tablecmds.c:11022 +#: commands/tablecmds.c:13726 #, c-format msgid "cannot use non-unique index \"%s\" as replica identity" msgstr "ä¸èƒ½å°†éžå”¯ä¸€ç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: commands/tablecmds.c:11028 +#: commands/tablecmds.c:13732 #, c-format msgid "cannot use non-immediate index \"%s\" as replica identity" msgstr "ä¸èƒ½æŠŠéžç«‹å³ç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: commands/tablecmds.c:11034 +#: commands/tablecmds.c:13738 #, c-format msgid "cannot use expression index \"%s\" as replica identity" msgstr "ä¸èƒ½å°†è¡¨è¾¾å¼ç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: commands/tablecmds.c:11040 +#: commands/tablecmds.c:13744 #, c-format msgid "cannot use partial index \"%s\" as replica identity" msgstr "ä¸èƒ½å°†å±€éƒ¨ç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: commands/tablecmds.c:11046 +#: commands/tablecmds.c:13750 #, c-format msgid "cannot use invalid index \"%s\" as replica identity" msgstr "ä¸èƒ½å°†æ— æ•ˆç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: commands/tablecmds.c:11067 +#: commands/tablecmds.c:13767 #, c-format -#| msgid "" -#| "index \"%s\" cannot be used as replica identity because column \"%s\" is " -#| "nullable" -msgid "" -"index \"%s\" cannot be used as replica identity because column %d is a " -"system column" +msgid "index \"%s\" cannot be used as replica identity because column %d is a system column" msgstr "索引 \"%s\" ä¸èƒ½ç”¨åšå¤åˆ¶æ ‡è¯†ï¼Œå› ä¸ºåˆ— %d 是一个系统列" -#: commands/tablecmds.c:11074 +#: commands/tablecmds.c:13774 #, c-format -msgid "" -"index \"%s\" cannot be used as replica identity because column \"%s\" is " -"nullable" +msgid "index \"%s\" cannot be used as replica identity because column \"%s\" is nullable" msgstr "索引 \"%s\" ä¸èƒ½ç”¨äºŽå¤åˆ¶æ ‡è¯†ï¼Œå› ä¸ºåˆ—\"%s\"éžç©º" -#: commands/tablecmds.c:11271 +#: commands/tablecmds.c:13967 #, c-format msgid "cannot change logged status of table \"%s\" because it is temporary" msgstr "无法更改表\"%s\"的已记录状æ€ï¼Œå› ä¸ºå®ƒæ˜¯ä¸´æ—¶è¡¨" -#: commands/tablecmds.c:11330 +#: commands/tablecmds.c:13991 #, c-format -msgid "" -"could not change table \"%s\" to logged because it references unlogged table " -"\"%s\"" +msgid "cannot change table \"%s\" to unlogged because it is part of a publication" +msgstr "无法把表\"%s\"更改为ä¸è¢«æ—¥å¿—记录,因为它是å‘布的一部分" + +#: commands/tablecmds.c:13993 +#, c-format +msgid "Unlogged relations cannot be replicated." +msgstr "无法å¤åˆ¶ä¸è¢«æ—¥å¿—记录的关系" + +#: commands/tablecmds.c:14038 +#, c-format +msgid "could not change table \"%s\" to logged because it references unlogged table \"%s\"" msgstr "无法把表\"%s\"更改为被日志记录,因为它引用了ä¸è¢«æ—¥å¿—记录的表\"%s\"" -#: commands/tablecmds.c:11340 +#: commands/tablecmds.c:14048 #, c-format -msgid "" -"could not change table \"%s\" to unlogged because it references logged table " -"\"%s\"" +msgid "could not change table \"%s\" to unlogged because it references logged table \"%s\"" msgstr "无法把表\"%s\"更改为ä¸è¢«æ—¥å¿—记录,因为它引用了日志记录的表\"%s\"" -#: commands/tablecmds.c:11397 +#: commands/tablecmds.c:14106 #, c-format msgid "cannot move an owned sequence into another schema" msgstr "无法将已分é…çš„åºåˆ—移动到å¦ä¸€ä¸ªæ¨¡å¼ä¸­" -#: commands/tablecmds.c:11502 +#: commands/tablecmds.c:14212 #, c-format msgid "relation \"%s\" already exists in schema \"%s\"" msgstr "在模å¼\"%2$s\"中已ç»å­˜åœ¨å…³ç³»\"%1$s\"" -#: commands/tablecmds.c:12029 +#: commands/tablecmds.c:14789 #, c-format msgid "\"%s\" is not a composite type" msgstr "\"%s\" 䏿˜¯ç»„åˆç±»åž‹" -#: commands/tablecmds.c:12059 +#: commands/tablecmds.c:14821 #, c-format -msgid "" -"\"%s\" is not a table, view, materialized view, sequence, or foreign table" +msgid "\"%s\" is not a table, view, materialized view, sequence, or foreign table" msgstr "\"%s\" 䏿˜¯è¡¨,视图,物化视图,åºåˆ—或者外部表" -#: commands/tablespace.c:162 commands/tablespace.c:179 -#: commands/tablespace.c:190 commands/tablespace.c:198 -#: commands/tablespace.c:629 replication/slot.c:969 storage/file/copydir.c:47 +#: commands/tablecmds.c:14856 +#, c-format +msgid "unrecognized partitioning strategy \"%s\"" +msgstr "无法识别的分区策略 \"%s\"" + +#: commands/tablecmds.c:14864 +#, c-format +msgid "cannot use \"list\" partition strategy with more than one column" +msgstr "ä¸èƒ½å°†\"list\"分区策略与多个列一起使用" + +#: commands/tablecmds.c:14930 +#, c-format +msgid "column \"%s\" named in partition key does not exist" +msgstr "分区键中å为\"%s\"的列ä¸å­˜åœ¨" + +#: commands/tablecmds.c:14938 +#, c-format +msgid "cannot use system column \"%s\" in partition key" +msgstr "无法在分区键中使用系统列\"%s\"" + +#: commands/tablecmds.c:14949 commands/tablecmds.c:15054 +#, fuzzy, c-format +#| msgid "cannot use system column \"%s\" in partition key" +msgid "cannot use generated column in partition key" +msgstr "无法在分区键中使用系统列\"%s\"" + +#: commands/tablecmds.c:14950 commands/tablecmds.c:15055 commands/trigger.c:659 +#: rewrite/rewriteHandler.c:826 rewrite/rewriteHandler.c:843 +#, fuzzy, c-format +#| msgid "column \"%s\" has a type conflict" +msgid "Column \"%s\" is a generated column." +msgstr "属性 \"%s\" 类型冲çª" + +#: commands/tablecmds.c:15014 +#, c-format +msgid "functions in partition key expression must be marked IMMUTABLE" +msgstr "分区键表达å¼ä¸­å‡½æ•°å¿…需标记为 IMMUTABLE" + +#: commands/tablecmds.c:15031 +#, c-format +msgid "partition key expressions cannot contain whole-row references" +msgstr "分区键表达å¼ä¸èƒ½åŒ…嫿•´è¡Œå¼•用" + +#: commands/tablecmds.c:15038 +#, c-format +msgid "partition key expressions cannot contain system column references" +msgstr "分区键表达å¼ä¸èƒ½åŒ…å«ç³»ç»Ÿåˆ—引用" + +#: commands/tablecmds.c:15067 +#, c-format +msgid "cannot use constant expression as partition key" +msgstr "ä¸èƒ½å°†å¸¸é‡è¡¨è¾¾å¼ç”¨ä½œåˆ†åŒºé”®" + +#: commands/tablecmds.c:15088 +#, c-format +msgid "could not determine which collation to use for partition expression" +msgstr "分区表达å¼ä¸Šæ— æ³•确定使用哪个排åºè§„则" + +#: commands/tablecmds.c:15123 +#, c-format +msgid "You must specify a hash operator class or define a default hash operator class for the data type." +msgstr "你必须为数æ®ç±»åž‹æŒ‡å®šå“ˆå¸Œè¿ç®—符类或定义默认哈希è¿ç®—符类." + +#: commands/tablecmds.c:15129 +#, c-format +msgid "You must specify a btree operator class or define a default btree operator class for the data type." +msgstr "你必须为数æ®ç±»åž‹æŒ‡å®šBæ ‘è¿ç®—符类或定义默认Bæ ‘è¿ç®—符类." + +#: commands/tablecmds.c:15274 +#, c-format +msgid "partition constraint for table \"%s\" is implied by existing constraints" +msgstr "表\"%s\"的分区约æŸç”±çŽ°æœ‰çº¦æŸéšå«" + +#: commands/tablecmds.c:15278 partitioning/partbounds.c:1249 +#: partitioning/partbounds.c:1292 +#, c-format +msgid "updated partition constraint for default partition \"%s\" is implied by existing constraints" +msgstr "默认分区\"%s\"的更新分区约æŸç”±çŽ°æœ‰çº¦æŸéšå«" + +#: commands/tablecmds.c:15382 +#, c-format +msgid "\"%s\" is already a partition" +msgstr "\"%s\" å·²ç»æ˜¯ä¸€ä¸ªåˆ†åŒºäº†" + +#: commands/tablecmds.c:15388 +#, c-format +msgid "cannot attach a typed table as partition" +msgstr "无法将类型表附加为分区" + +#: commands/tablecmds.c:15404 +#, c-format +msgid "cannot attach inheritance child as partition" +msgstr "无法将继承å­çº§é™„加为分区" + +#: commands/tablecmds.c:15418 +#, c-format +msgid "cannot attach inheritance parent as partition" +msgstr "无法将继承父级附加为分区" + +#: commands/tablecmds.c:15452 +#, c-format +msgid "cannot attach a temporary relation as partition of permanent relation \"%s\"" +msgstr "ä¸èƒ½å°†ä¸´æ—¶å…³ç³»é™„加为永久关系\"%s\"的分区" + +#: commands/tablecmds.c:15460 +#, c-format +msgid "cannot attach a permanent relation as partition of temporary relation \"%s\"" +msgstr "ä¸èƒ½å°†æ°¸ä¹…关系附加为临时关系 \"%s\" 的分区" + +#: commands/tablecmds.c:15468 +#, c-format +msgid "cannot attach as partition of temporary relation of another session" +msgstr "ä¸èƒ½ä½œä¸ºå¦ä¸€ä¼šè¯çš„临时关系的分区附加" + +#: commands/tablecmds.c:15475 +#, c-format +msgid "cannot attach temporary relation of another session as partition" +msgstr "无法将其他会è¯çš„临时关系附加为分区" + +#: commands/tablecmds.c:15495 +#, c-format +msgid "table \"%s\" contains column \"%s\" not found in parent \"%s\"" +msgstr "表\"%1$s\"包å«çˆ¶è¡¨\"%3$s\"中找ä¸åˆ°çš„列\"%2$s\"" + +#: commands/tablecmds.c:15498 +#, c-format +msgid "The new partition may contain only the columns present in parent." +msgstr "新分区åªèƒ½åŒ…å«çˆ¶åˆ†åŒºä¸­çš„列." + +#: commands/tablecmds.c:15510 +#, c-format +msgid "trigger \"%s\" prevents table \"%s\" from becoming a partition" +msgstr "触å‘器\"%s\"阻止表\"%s\"æˆä¸ºåˆ†åŒº" + +#: commands/tablecmds.c:15512 commands/trigger.c:465 +#, c-format +msgid "ROW triggers with transition tables are not supported on partitions" +msgstr "åˆ†åŒºä¸Šä¸æ”¯æŒå…·æœ‰è½¬æ¢è¡¨çš„行触å‘器" + +#: commands/tablecmds.c:16205 commands/tablecmds.c:16224 +#: commands/tablecmds.c:16246 commands/tablecmds.c:16265 +#: commands/tablecmds.c:16307 +#, c-format +msgid "cannot attach index \"%s\" as a partition of index \"%s\"" +msgstr "无法将索引\"%s\"作为索引\"%s\"分区附加" + +#: commands/tablecmds.c:16208 +#, c-format +msgid "Index \"%s\" is already attached to another index." +msgstr "索引\"%s\"已附加到å¦ä¸€ä¸ªç´¢å¼•" + +#: commands/tablecmds.c:16227 +#, c-format +msgid "Index \"%s\" is not an index on any partition of table \"%s\"." +msgstr "索引\"%s\"䏿˜¯è¡¨\"%s\"的任何分区上的索引." + +# sql_help.h:65 +#: commands/tablecmds.c:16249 +#, c-format +msgid "The index definitions do not match." +msgstr "索引定义ä¸åŒ¹é…" + +#: commands/tablecmds.c:16268 +#, c-format +msgid "The index \"%s\" belongs to a constraint in table \"%s\" but no constraint exists for index \"%s\"." +msgstr "索引\"%s\"属于表\"%s\"中的约æŸï¼Œä½†ä¸å­˜åœ¨ç´¢å¼•\"%s\"的约æŸ." + +#: commands/tablecmds.c:16310 +#, c-format +msgid "Another index is already attached for partition \"%s\"." +msgstr "å·²ç»ä¸ºåˆ†åŒº\"%s\"附加了å¦ä¸€ä¸ªç´¢å¼•." + +#: commands/tablespace.c:163 commands/tablespace.c:180 +#: commands/tablespace.c:191 commands/tablespace.c:199 +#: commands/tablespace.c:630 replication/slot.c:1198 storage/file/copydir.c:47 #, c-format msgid "could not create directory \"%s\": %m" msgstr "无法创建目录 \"%s\": %m" -#: commands/tablespace.c:209 +#: commands/tablespace.c:210 utils/adt/genfile.c:593 #, c-format msgid "could not stat directory \"%s\": %m" msgstr "无法å–目录 \"%s\" 状æ€: %m" -#: commands/tablespace.c:218 +#: commands/tablespace.c:219 #, c-format msgid "\"%s\" exists but is not a directory" msgstr "\"%s\" 存在, 但䏿˜¯ä¸€ä¸ªç›®å½•" -#: commands/tablespace.c:249 +#: commands/tablespace.c:250 #, c-format msgid "permission denied to create tablespace \"%s\"" msgstr "创建表空间 \"%s\" æƒé™ä¸å¤Ÿ" -#: commands/tablespace.c:251 +#: commands/tablespace.c:252 #, c-format msgid "Must be superuser to create a tablespace." msgstr "åªæœ‰è¶…级用户能创建表空间" -#: commands/tablespace.c:271 +#: commands/tablespace.c:268 #, c-format msgid "tablespace location cannot contain single quotes" msgstr "表空间路径ä¸èƒ½åŒ…å«å•引å·" -#: commands/tablespace.c:281 +#: commands/tablespace.c:278 #, c-format msgid "tablespace location must be an absolute path" msgstr "表空间路径必须为ç»å¯¹è·¯å¾„" -#: commands/tablespace.c:292 +#: commands/tablespace.c:290 #, c-format msgid "tablespace location \"%s\" is too long" msgstr "表空间路径 \"%s\" 太长" -#: commands/tablespace.c:299 +#: commands/tablespace.c:297 #, c-format msgid "tablespace location should not be inside the data directory" msgstr "表空间ä½ç½®ä¸åº”该ä½äºŽæ•°æ®ç›®å½•内" -#: commands/tablespace.c:308 commands/tablespace.c:956 +#: commands/tablespace.c:306 commands/tablespace.c:957 #, c-format msgid "unacceptable tablespace name \"%s\"" msgstr "ä¸å¯è®¿é—®çš„表空间åå­— \"%s\"" -#: commands/tablespace.c:310 commands/tablespace.c:957 +#: commands/tablespace.c:308 commands/tablespace.c:958 #, c-format msgid "The prefix \"pg_\" is reserved for system tablespaces." msgstr "å‰ç¼€ \"pg_\" 是ä¿ç•™ç»™ç³»ç»Ÿè¡¨ç©ºé—´çš„." -#: commands/tablespace.c:320 commands/tablespace.c:969 +#: commands/tablespace.c:318 commands/tablespace.c:970 #, c-format msgid "tablespace \"%s\" already exists" msgstr "表空间 \"%s\" å·²ç»å­˜åœ¨" -#: commands/tablespace.c:434 commands/tablespace.c:939 -#: commands/tablespace.c:1020 commands/tablespace.c:1089 -#: commands/tablespace.c:1222 commands/tablespace.c:1422 +#: commands/tablespace.c:434 commands/tablespace.c:940 +#: commands/tablespace.c:1020 commands/tablespace.c:1088 +#: commands/tablespace.c:1231 commands/tablespace.c:1431 #, c-format msgid "tablespace \"%s\" does not exist" msgstr "表空间 \"%s\" ä¸å­˜åœ¨" @@ -9054,235 +9919,334 @@ msgstr "表空间 \"%s\" ä¸å­˜åœ¨" msgid "tablespace \"%s\" does not exist, skipping" msgstr "表空间 \"%s\" ä¸å­˜åœ¨,跳过" -#: commands/tablespace.c:516 +#: commands/tablespace.c:517 #, c-format msgid "tablespace \"%s\" is not empty" msgstr "表空间 \"%s\" 䏿˜¯ç©ºçš„" -#: commands/tablespace.c:588 +#: commands/tablespace.c:589 #, c-format msgid "directory \"%s\" does not exist" msgstr "目录 \"%s\" ä¸å­˜åœ¨" -#: commands/tablespace.c:589 +#: commands/tablespace.c:590 #, c-format msgid "Create this directory for the tablespace before restarting the server." msgstr "åœ¨é‡æ–°å¯åЍæœåС噍å‰ä¸ºè¿™ä¸ªè¡¨ç©ºé—´åˆ›å»ºè¯¥ç›®å½•." -#: commands/tablespace.c:594 +#: commands/tablespace.c:595 #, c-format msgid "could not set permissions on directory \"%s\": %m" msgstr "无法为目录 \"%s\" 的设置æƒé™: %m" -#: commands/tablespace.c:624 +#: commands/tablespace.c:625 #, c-format msgid "directory \"%s\" already in use as a tablespace" msgstr "目录 \"%s\" ä»¥ä¸€ä¸ªè¡¨ç©ºé—´çš„å½¢å¼æ­£åœ¨ä½¿ç”¨" -#: commands/tablespace.c:748 commands/tablespace.c:761 -#: commands/tablespace.c:797 commands/tablespace.c:889 +#: commands/tablespace.c:710 commands/tablespace.c:720 +#: postmaster/postmaster.c:1474 storage/file/fd.c:2562 +#: storage/file/reinit.c:122 utils/adt/genfile.c:487 utils/adt/genfile.c:565 +#: utils/adt/misc.c:243 utils/misc/tzparser.c:339 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "无法打开目录 \"%s\": %m" + +#: commands/tablespace.c:749 commands/tablespace.c:762 +#: commands/tablespace.c:798 commands/tablespace.c:890 storage/file/fd.c:2992 #, c-format msgid "could not remove directory \"%s\": %m" msgstr "无法删除目录 \"%s\": %m" -#: commands/tablespace.c:810 commands/tablespace.c:898 +#: commands/tablespace.c:811 commands/tablespace.c:899 #, c-format msgid "could not remove symbolic link \"%s\": %m" msgstr "无法删除符å·é“¾æŽ¥ \"%s\": %m" -#: commands/tablespace.c:820 commands/tablespace.c:907 +#: commands/tablespace.c:821 commands/tablespace.c:908 #, c-format msgid "\"%s\" is not a directory or symbolic link" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªç›®å½•或者符å·é“¾æŽ¥" -#: commands/tablespace.c:1094 +#: commands/tablespace.c:1093 #, c-format msgid "Tablespace \"%s\" does not exist." msgstr "表空间 \"%s\" ä¸å­˜åœ¨." -#: commands/tablespace.c:1521 +#: commands/tablespace.c:1530 #, c-format msgid "directories for tablespace %u could not be removed" msgstr "表空间 %u 的目录ä¸èƒ½è¢«ç§»é™¤" -#: commands/tablespace.c:1523 +#: commands/tablespace.c:1532 #, c-format msgid "You can remove the directories manually if necessary." msgstr "å¦‚æœ‰å¿…è¦æ‚¨å¯ä»¥æ‰‹åŠ¨ç§»é™¤è¿™äº›ç›®å½•." -#: commands/trigger.c:184 +#: commands/trigger.c:210 commands/trigger.c:221 #, c-format msgid "\"%s\" is a table" msgstr "\"%s\" 是一个表" -#: commands/trigger.c:186 +#: commands/trigger.c:212 commands/trigger.c:223 #, c-format msgid "Tables cannot have INSTEAD OF triggers." msgstr "表ä¸èƒ½ä½¿ç”¨INSTEAD OF触å‘器." -#: commands/trigger.c:197 commands/trigger.c:204 +#: commands/trigger.c:240 +#, c-format +msgid "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers." +msgstr "分区表ä¸èƒ½æœ‰ BEFORE / FOR EACH ROW触å‘器." + +#: commands/trigger.c:258 +#, c-format +msgid "Triggers on partitioned tables cannot have transition tables." +msgstr "分区表上的触å‘器ä¸èƒ½æœ‰è½¬æ¢è¡¨ ." + +#: commands/trigger.c:270 commands/trigger.c:277 commands/trigger.c:447 #, c-format msgid "\"%s\" is a view" msgstr "\"%s\" 是一个视图" -#: commands/trigger.c:199 +#: commands/trigger.c:272 #, c-format msgid "Views cannot have row-level BEFORE or AFTER triggers." msgstr "视图ä¸èƒ½ä½¿ç”¨è¡Œçº§ BEFORE 或 AFTER 触å‘器." -#: commands/trigger.c:206 +#: commands/trigger.c:279 #, c-format msgid "Views cannot have TRUNCATE triggers." msgstr "视图ä¸èƒ½ä½¿ç”¨ TRUNCATE 触å‘器." -#: commands/trigger.c:214 commands/trigger.c:221 commands/trigger.c:228 +#: commands/trigger.c:287 commands/trigger.c:294 commands/trigger.c:306 +#: commands/trigger.c:440 #, c-format msgid "\"%s\" is a foreign table" msgstr "\"%s\" 是一个外部表" -#: commands/trigger.c:216 +#: commands/trigger.c:289 #, c-format msgid "Foreign tables cannot have INSTEAD OF triggers." msgstr "外部表ä¸èƒ½ä½¿ç”¨INSTEAD OF触å‘器." -#: commands/trigger.c:223 +#: commands/trigger.c:296 #, c-format msgid "Foreign tables cannot have TRUNCATE triggers." msgstr "外部表ä¸èƒ½ä½¿ç”¨ TRUNCATE 触å‘器." -#: commands/trigger.c:230 +#: commands/trigger.c:308 #, c-format msgid "Foreign tables cannot have constraint triggers." msgstr "外部表ä¸èƒ½ä½¿ç”¨çº¦æŸè§¦å‘器." -#: commands/trigger.c:293 +#: commands/trigger.c:383 #, c-format msgid "TRUNCATE FOR EACH ROW triggers are not supported" msgstr "䏿”¯æŒä½¿ç”¨TRUNCATE FOR EACH ROW触å‘器" -#: commands/trigger.c:301 +#: commands/trigger.c:391 #, c-format msgid "INSTEAD OF triggers must be FOR EACH ROW" msgstr "INSTEAD OF 触å‘器必须使用 FOR EACH ROW" -#: commands/trigger.c:305 +#: commands/trigger.c:395 #, c-format msgid "INSTEAD OF triggers cannot have WHEN conditions" msgstr "INSTEAD OF 触å‘器ä¸èƒ½ä½¿ç”¨ WHEN æ¡ä»¶å­å¥" -#: commands/trigger.c:309 +#: commands/trigger.c:399 #, c-format msgid "INSTEAD OF triggers cannot have column lists" msgstr "INSTEAD OF 触å‘器ä¸èƒ½å¸¦æœ‰å­—段列表" -#: commands/trigger.c:366 commands/trigger.c:379 +#: commands/trigger.c:428 +#, c-format +msgid "ROW variable naming in the REFERENCING clause is not supported" +msgstr "䏿”¯æŒREFERENCINGå­å¥ä¸­çš„行å˜é‡å‘½å" + +#: commands/trigger.c:429 +#, c-format +msgid "Use OLD TABLE or NEW TABLE for naming transition tables." +msgstr "使用 OLD TABLE 或 NEW TABLE 命å转æ¢è¡¨." + +#: commands/trigger.c:442 +#, c-format +msgid "Triggers on foreign tables cannot have transition tables." +msgstr "外部表上的触å‘器ä¸èƒ½æœ‰è½¬æ¢è¡¨." + +#: commands/trigger.c:449 +#, c-format +msgid "Triggers on views cannot have transition tables." +msgstr "视图上的触å‘器ä¸èƒ½æœ‰è½¬æ¢è¡¨." + +#: commands/trigger.c:469 +#, c-format +msgid "ROW triggers with transition tables are not supported on inheritance children" +msgstr "继承å­çº§ä¸æ”¯æŒå…·æœ‰è½¬æ¢è¡¨çš„行触å‘器" + +#: commands/trigger.c:475 +#, c-format +msgid "transition table name can only be specified for an AFTER trigger" +msgstr "åªèƒ½ä¸ºAFTER触å‘器指定转æ¢è¡¨å " + +#: commands/trigger.c:480 +#, c-format +msgid "TRUNCATE triggers with transition tables are not supported" +msgstr "䏿”¯æŒä½¿ç”¨è½¬æ¢è¡¨æˆªæ–­è§¦å‘器" + +#: commands/trigger.c:497 +#, c-format +msgid "transition tables cannot be specified for triggers with more than one event" +msgstr "ä¸èƒ½ä¸ºå…·æœ‰å¤šä¸ªäº‹ä»¶çš„触å‘器指定转æ¢è¡¨" + +#: commands/trigger.c:508 +#, c-format +msgid "transition tables cannot be specified for triggers with column lists" +msgstr "ä¸èƒ½ä¸ºå…·æœ‰åˆ—列表的触å‘器指定转æ¢è¡¨" + +#: commands/trigger.c:525 +#, c-format +msgid "NEW TABLE can only be specified for an INSERT or UPDATE trigger" +msgstr "åªèƒ½ä¸ºæ’入或更新触å‘器指定新表" + +#: commands/trigger.c:530 +#, c-format +msgid "NEW TABLE cannot be specified multiple times" +msgstr "ä¸èƒ½å¤šæ¬¡æŒ‡å®šæ–°è¡¨" + +#: commands/trigger.c:540 +#, c-format +msgid "OLD TABLE can only be specified for a DELETE or UPDATE trigger" +msgstr "åªèƒ½ä¸ºåˆ é™¤æˆ–更新触å‘器指定OLD表" + +#: commands/trigger.c:545 +#, c-format +msgid "OLD TABLE cannot be specified multiple times" +msgstr "ä¸èƒ½å¤šæ¬¡æŒ‡å®šOLD表" + +#: commands/trigger.c:555 +#, c-format +msgid "OLD TABLE name and NEW TABLE name cannot be the same" +msgstr "旧表å和新表åä¸èƒ½ç›¸åŒ" + +#: commands/trigger.c:619 commands/trigger.c:632 #, c-format msgid "statement trigger's WHEN condition cannot reference column values" msgstr "语å¥çº§è§¦å‘器的WHENæ¡ä»¶ä¸­ä¸èƒ½å¼•用列的值。" -#: commands/trigger.c:371 +#: commands/trigger.c:624 #, c-format msgid "INSERT trigger's WHEN condition cannot reference OLD values" msgstr "在INSERT触å‘器的WHENæ¡ä»¶ä¸­ä¸èƒ½å¼•用OLD值。" -#: commands/trigger.c:384 +#: commands/trigger.c:637 #, c-format msgid "DELETE trigger's WHEN condition cannot reference NEW values" msgstr "在DELETE触å‘器的WHENæ¡ä»¶ä¸­ä¸èƒ½å¼•用NEW值。" -#: commands/trigger.c:389 +#: commands/trigger.c:642 #, c-format msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" msgstr "BEFORE类型触å‘器的WHEREæ¡ä»¶ä¸èƒ½å¼•用NEW系统列" -#: commands/trigger.c:434 +#: commands/trigger.c:650 commands/trigger.c:658 +#, fuzzy, c-format +#| msgid "BEFORE trigger's WHEN condition cannot reference NEW system columns" +msgid "BEFORE trigger's WHEN condition cannot reference NEW generated columns" +msgstr "BEFORE类型触å‘器的WHEREæ¡ä»¶ä¸èƒ½å¼•用NEW系统列" + +#: commands/trigger.c:651 #, c-format -msgid "changing return type of function %s from \"opaque\" to \"trigger\"" -msgstr "改å˜å‡½æ•° %s 的返回类型 \"opaque\" 为 \"trigger\"" +msgid "A whole-row reference is used and the table contains generated columns." +msgstr "" -#: commands/trigger.c:553 commands/trigger.c:1303 +#: commands/trigger.c:833 commands/trigger.c:1724 #, c-format msgid "trigger \"%s\" for relation \"%s\" already exists" msgstr "对于关系 \"%2$s\" çš„ \"%1$s\" 触å‘器已ç»å­˜åœ¨" -#: commands/trigger.c:838 +#: commands/trigger.c:1249 msgid "Found referenced table's UPDATE trigger." msgstr "找到被引用表的UPDATE触å‘器" -#: commands/trigger.c:839 +#: commands/trigger.c:1250 msgid "Found referenced table's DELETE trigger." msgstr "找到被引用表的DELETE触å‘器" -#: commands/trigger.c:840 +#: commands/trigger.c:1251 msgid "Found referencing table's trigger." msgstr "找到正在引用表的触å‘器" -#: commands/trigger.c:949 commands/trigger.c:965 +#: commands/trigger.c:1360 commands/trigger.c:1376 #, c-format msgid "ignoring incomplete trigger group for constraint \"%s\" %s" msgstr "对于\"%s\" %s,忽略未完æˆçš„触å‘器组" -#: commands/trigger.c:977 +#: commands/trigger.c:1389 #, c-format msgid "converting trigger group into constraint \"%s\" %s" msgstr "正在将触å‘器组转æ¢ä¸ºçº¦æŸ\"%s\" %s" -#: commands/trigger.c:1190 commands/trigger.c:1351 commands/trigger.c:1469 +#: commands/trigger.c:1610 commands/trigger.c:1771 commands/trigger.c:1907 #, c-format msgid "trigger \"%s\" for table \"%s\" does not exist" msgstr "表 \"%2$s\" çš„ \"%1$s\" 触å‘器ä¸å­˜åœ¨" -#: commands/trigger.c:1434 +#: commands/trigger.c:1854 #, c-format msgid "permission denied: \"%s\" is a system trigger" msgstr "æƒé™ä¸å¤Ÿ: \"%s\" 是一个系统触å‘器" -#: commands/trigger.c:1930 +#: commands/trigger.c:2454 #, c-format msgid "trigger function %u returned null value" msgstr "触å‘器函数 %u 返回了空值" -#: commands/trigger.c:1989 commands/trigger.c:2188 commands/trigger.c:2392 -#: commands/trigger.c:2664 +#: commands/trigger.c:2520 commands/trigger.c:2737 commands/trigger.c:2989 +#: commands/trigger.c:3293 #, c-format msgid "BEFORE STATEMENT trigger cannot return a value" msgstr "BEFORE STATEMENT 触å‘器ä¸èƒ½è¿”回一个值" -#: commands/trigger.c:2726 executor/nodeModifyTable.c:664 -#: executor/nodeModifyTable.c:957 +#: commands/trigger.c:3356 executor/nodeModifyTable.c:1350 +#: executor/nodeModifyTable.c:1421 #, c-format -msgid "" -"tuple to be updated was already modified by an operation triggered by the " -"current command" +msgid "tuple to be updated was already modified by an operation triggered by the current command" msgstr "待更新元组值已ç»è¢«å½“å‰å‘½ä»¤è§¦å‘çš„æ“作修改了" -#: commands/trigger.c:2727 executor/nodeModifyTable.c:665 -#: executor/nodeModifyTable.c:958 +#: commands/trigger.c:3357 executor/nodeModifyTable.c:809 +#: executor/nodeModifyTable.c:884 executor/nodeModifyTable.c:1351 +#: executor/nodeModifyTable.c:1422 #, c-format -msgid "" -"Consider using an AFTER trigger instead of a BEFORE trigger to propagate " -"changes to other rows." +msgid "Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows." msgstr "考虑使用AFTER触å‘器代替BEFORE触å‘å™¨ï¼Œæ¥æ”¹å˜å…¶å®ƒè¡Œçš„值." -#: commands/trigger.c:2741 executor/execMain.c:2369 -#: executor/nodeLockRows.c:216 executor/nodeModifyTable.c:200 -#: executor/nodeModifyTable.c:677 executor/nodeModifyTable.c:970 -#: executor/nodeModifyTable.c:1136 +#: commands/trigger.c:3388 executor/nodeLockRows.c:231 +#: executor/nodeLockRows.c:240 executor/nodeModifyTable.c:220 +#: executor/nodeModifyTable.c:825 executor/nodeModifyTable.c:1367 +#: executor/nodeModifyTable.c:1585 #, c-format msgid "could not serialize access due to concurrent update" msgstr "ç”±äºŽåŒæ­¥æ›´æ–°è€Œæ— æ³•串行访问" -#: commands/trigger.c:4579 +#: commands/trigger.c:3396 executor/nodeModifyTable.c:916 +#: executor/nodeModifyTable.c:1439 executor/nodeModifyTable.c:1609 +#, fuzzy, c-format +#| msgid "could not serialize access due to concurrent update" +msgid "could not serialize access due to concurrent delete" +msgstr "ç”±äºŽåŒæ­¥æ›´æ–°è€Œæ— æ³•串行访问" + +#: commands/trigger.c:5447 #, c-format msgid "constraint \"%s\" is not deferrable" msgstr "çº¦æŸ \"%s\" ä¸å¯å±•缓" -#: commands/trigger.c:4602 +#: commands/trigger.c:5470 #, c-format msgid "constraint \"%s\" does not exist" msgstr "çº¦æŸ \"%s\" ä¸å­˜åœ¨" -#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:685 +#: commands/tsearchcmds.c:115 commands/tsearchcmds.c:686 #, c-format msgid "function %s should return type %s" msgstr "函数%s应该返回类型%s的值" @@ -9292,832 +10256,763 @@ msgstr "函数%s应该返回类型%s的值" msgid "must be superuser to create text search parsers" msgstr "åªæœ‰è¶…级用户能创建文本æœç´¢è§£æžå™¨" -#: commands/tsearchcmds.c:240 +#: commands/tsearchcmds.c:245 #, c-format msgid "text search parser parameter \"%s\" not recognized" msgstr "未识别文本æœç´¢å‚æ•°\"%s\"" -#: commands/tsearchcmds.c:250 +#: commands/tsearchcmds.c:255 #, c-format msgid "text search parser start method is required" msgstr "需è¦ä½¿ç”¨æ–‡æœ¬æœç´¢è§£æžå™¨çš„start方法" -#: commands/tsearchcmds.c:255 +#: commands/tsearchcmds.c:260 #, c-format msgid "text search parser gettoken method is required" msgstr "需è¦ä½¿ç”¨æ–‡æœ¬æœç´¢è§£æžå™¨çš„gettoken方法" -#: commands/tsearchcmds.c:260 +#: commands/tsearchcmds.c:265 #, c-format msgid "text search parser end method is required" msgstr "需è¦ä½¿ç”¨æ–‡æœ¬æœç´¢è§£æžå™¨çš„end方法" -#: commands/tsearchcmds.c:265 +#: commands/tsearchcmds.c:270 #, c-format msgid "text search parser lextypes method is required" msgstr "需è¦ä½¿ç”¨æ–‡æœ¬æœç´¢è§£æžå™¨çš„lextypes方法" -#: commands/tsearchcmds.c:386 +#: commands/tsearchcmds.c:387 #, c-format msgid "text search template \"%s\" does not accept options" msgstr "文本æœç´¢æ¨¡æ¿ \"%s\"䏿ޥå—使用选项" # describe.c:1753 -#: commands/tsearchcmds.c:460 +#: commands/tsearchcmds.c:461 #, c-format msgid "text search template is required" msgstr "è¦æ±‚使用文本æœå¯»æ¨¡æ¿" -#: commands/tsearchcmds.c:752 +#: commands/tsearchcmds.c:753 #, c-format msgid "must be superuser to create text search templates" msgstr "åªæœ‰è¶…级用户能创建文本æœç´¢æ¨¡æ¿" -#: commands/tsearchcmds.c:789 +#: commands/tsearchcmds.c:795 #, c-format msgid "text search template parameter \"%s\" not recognized" msgstr "未识别文本æœç´¢æ¨¡æ¿å‚æ•°\"%s\"" -#: commands/tsearchcmds.c:799 +#: commands/tsearchcmds.c:805 #, c-format msgid "text search template lexize method is required" msgstr "è¦æ±‚使用文本æœç´¢æ¨¡æ¿è¯æ±‡æ–¹æ³•" -#: commands/tsearchcmds.c:1008 +#: commands/tsearchcmds.c:1009 #, c-format msgid "text search configuration parameter \"%s\" not recognized" msgstr "未识别文本æœç´¢é…ç½®å‚æ•°\"%s\"" -#: commands/tsearchcmds.c:1015 +#: commands/tsearchcmds.c:1016 #, c-format msgid "cannot specify both PARSER and COPY options" msgstr "ä¸èƒ½åŒæ—¶æŒ‡å®šPARSERå’ŒCOPY选项" -#: commands/tsearchcmds.c:1051 +#: commands/tsearchcmds.c:1052 #, c-format msgid "text search parser is required" msgstr "需è¦ä½¿ç”¨æ–‡æœ¬æœç´¢è§£æžå™¨" -#: commands/tsearchcmds.c:1278 +#: commands/tsearchcmds.c:1276 #, c-format msgid "token type \"%s\" does not exist" msgstr "符å·ç±»åž‹ \"%s\" ä¸å­˜åœ¨" -#: commands/tsearchcmds.c:1502 +#: commands/tsearchcmds.c:1503 #, c-format msgid "mapping for token type \"%s\" does not exist" msgstr "符å·ç±»åž‹\"%s\"的映射ä¸å­˜åœ¨" -#: commands/tsearchcmds.c:1508 +#: commands/tsearchcmds.c:1509 #, c-format msgid "mapping for token type \"%s\" does not exist, skipping" msgstr "符å·ç±»åž‹\"%s\"的映射ä¸å­˜åœ¨, 跳过" -#: commands/tsearchcmds.c:1663 commands/tsearchcmds.c:1774 +#: commands/tsearchcmds.c:1664 commands/tsearchcmds.c:1775 #, c-format msgid "invalid parameter list format: \"%s\"" msgstr "æ— æ•ˆå‚æ•°åˆ—表格å¼: \"%s\"" -#: commands/typecmds.c:181 +#: commands/typecmds.c:184 #, c-format msgid "must be superuser to create a base type" msgstr "åªæœ‰è¶…级用户能创建基类型" -#: commands/typecmds.c:288 commands/typecmds.c:1421 +#: commands/typecmds.c:291 commands/typecmds.c:1467 #, c-format msgid "type attribute \"%s\" not recognized" msgstr "类型属性 \"%s\" ä¸è¢«è®¤å¯" -#: commands/typecmds.c:342 +#: commands/typecmds.c:347 #, c-format msgid "invalid type category \"%s\": must be simple ASCII" msgstr "无效的类型目录 \"%s\": 必须是简å•ASCII" -#: commands/typecmds.c:361 +#: commands/typecmds.c:366 #, c-format msgid "array element type cannot be %s" msgstr "排列元素类型ä¸èƒ½ä¸º %s" -#: commands/typecmds.c:393 +#: commands/typecmds.c:398 #, c-format msgid "alignment \"%s\" not recognized" msgstr "alignment \"%s\" ä¸è¢«è®¤å¯" -#: commands/typecmds.c:410 +#: commands/typecmds.c:415 #, c-format msgid "storage \"%s\" not recognized" msgstr "存储 \"%s\" ä¸è¢«è®¤å¯" -#: commands/typecmds.c:421 +#: commands/typecmds.c:426 #, c-format msgid "type input function must be specified" msgstr "类型输入函数必需指定" -#: commands/typecmds.c:425 +#: commands/typecmds.c:430 #, c-format msgid "type output function must be specified" msgstr "类型输出函数必需指定" -#: commands/typecmds.c:430 +#: commands/typecmds.c:435 #, c-format -msgid "" -"type modifier output function is useless without a type modifier input " -"function" +msgid "type modifier output function is useless without a type modifier input function" msgstr "如果没有类型修改器的输入函数,那么类型修改器的输出函数没有用" -#: commands/typecmds.c:453 commands/typecmds.c:470 -#, c-format -#| msgid "changing return type of function %s from \"opaque\" to %s" -msgid "changing return type of function %s from %s to %s" -msgstr "把函数 %1$s 的返回类型从 %2$s æ”¹æˆ %3$s" - -#: commands/typecmds.c:460 +#: commands/typecmds.c:465 #, c-format msgid "type input function %s must return type %s" msgstr "类型输入函数 %s 必需返回类型 %s" -#: commands/typecmds.c:477 +#: commands/typecmds.c:482 #, c-format -#| msgid "type input function %s must return type %s" msgid "type output function %s must return type %s" msgstr "类型输出函数 %s 必需返回类型 %s" -#: commands/typecmds.c:486 +#: commands/typecmds.c:491 #, c-format msgid "type receive function %s must return type %s" msgstr "类型接收函数 %s 必需返回类型 %s" -#: commands/typecmds.c:495 +#: commands/typecmds.c:500 #, c-format -#| msgid "type input function %s must return type %s" msgid "type send function %s must return type %s" msgstr "类型å‘é€å‡½æ•° %s 必需返回类型 %s" -#: commands/typecmds.c:560 +#: commands/typecmds.c:565 #, c-format msgid "type input function %s should not be volatile" msgstr "类型输入函数%sä¸èƒ½æ˜¯ä¸ç¨³å®šçš„ (volatile)" -#: commands/typecmds.c:565 +#: commands/typecmds.c:570 #, c-format msgid "type output function %s should not be volatile" msgstr "类型输出函数%sä¸èƒ½æ˜¯ä¸ç¨³å®šçš„ (volatile)" -#: commands/typecmds.c:570 +#: commands/typecmds.c:575 #, c-format msgid "type receive function %s should not be volatile" msgstr "类型接收函数%sä¸åº”该是ä¸ç¨³å®šçš„" -#: commands/typecmds.c:575 +#: commands/typecmds.c:580 #, c-format msgid "type send function %s should not be volatile" msgstr "类型å‘é€å‡½æ•°%sä¸åº”该是ä¸ç¨³å®šçš„" -#: commands/typecmds.c:580 +#: commands/typecmds.c:585 #, c-format msgid "type modifier input function %s should not be volatile" msgstr "类型修饰输入函数%sä¸åº”该是ä¸ç¨³å®šçš„" -#: commands/typecmds.c:585 +#: commands/typecmds.c:590 #, c-format msgid "type modifier output function %s should not be volatile" msgstr "类型修饰输出函数%sä¸åº”该是ä¸ç¨³å®šçš„" -#: commands/typecmds.c:807 +#: commands/typecmds.c:817 #, c-format msgid "\"%s\" is not a valid base type for a domain" msgstr "对于一个域, \"%s\" 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„基本类型" -#: commands/typecmds.c:893 +#: commands/typecmds.c:903 #, c-format msgid "multiple default expressions" msgstr "多é默认表达å¼" -#: commands/typecmds.c:955 commands/typecmds.c:964 +#: commands/typecmds.c:966 commands/typecmds.c:975 #, c-format msgid "conflicting NULL/NOT NULL constraints" msgstr "NULL/NOT NULL 约æŸå†²çª" -#: commands/typecmds.c:980 +#: commands/typecmds.c:991 #, c-format msgid "check constraints for domains cannot be marked NO INHERIT" msgstr "域的CHECK约æŸä¸èƒ½æ ‡ä¸ºNO INHERIT" -#: commands/typecmds.c:989 commands/typecmds.c:2522 +#: commands/typecmds.c:1000 commands/typecmds.c:2582 #, c-format msgid "unique constraints not possible for domains" msgstr "唯一约æŸå¯¹äºŽåŸŸä¸å¯ç”¨" -#: commands/typecmds.c:995 commands/typecmds.c:2528 +#: commands/typecmds.c:1006 commands/typecmds.c:2588 #, c-format msgid "primary key constraints not possible for domains" msgstr "ä¸å¯ä¸ºåŸŸä½¿ç”¨ä¸»é”®çº¦æŸ" -#: commands/typecmds.c:1001 commands/typecmds.c:2534 +#: commands/typecmds.c:1012 commands/typecmds.c:2594 #, c-format msgid "exclusion constraints not possible for domains" msgstr "排他约æŸå¯¹äºŽåŸŸä¸å¯ç”¨" -#: commands/typecmds.c:1007 commands/typecmds.c:2540 +#: commands/typecmds.c:1018 commands/typecmds.c:2600 #, c-format msgid "foreign key constraints not possible for domains" msgstr "外键约æŸå¯¹äºŽåŸŸä¸å¯ç”¨" -#: commands/typecmds.c:1016 commands/typecmds.c:2549 +#: commands/typecmds.c:1027 commands/typecmds.c:2609 #, c-format msgid "specifying constraint deferrability not supported for domains" msgstr "所指定的约æŸå»¶è¿Ÿå¯¹åŸŸä¸æ”¯æŒ" -#: commands/typecmds.c:1291 utils/cache/typcache.c:1634 +#: commands/typecmds.c:1337 utils/cache/typcache.c:2330 #, c-format msgid "%s is not an enum" msgstr "%s 䏿˜¯æžšä¸¾" -#: commands/typecmds.c:1429 +#: commands/typecmds.c:1475 #, c-format msgid "type attribute \"subtype\" is required" msgstr "类型属性 \"subtype\" 䏿˜¯å¿…需的" -#: commands/typecmds.c:1434 +#: commands/typecmds.c:1480 #, c-format msgid "range subtype cannot be %s" msgstr "范围å­ç±»åž‹ä¸èƒ½ä¸º %s" -#: commands/typecmds.c:1453 +#: commands/typecmds.c:1499 #, c-format msgid "range collation specified but subtype does not support collation" msgstr "已指定了范围排åºè§„则但是å­ç±»åž‹å¹¶ä¸æ”¯æŒæŽ’åº" -#: commands/typecmds.c:1687 +#: commands/typecmds.c:1733 #, c-format msgid "changing argument type of function %s from \"opaque\" to \"cstring\"" msgstr "改å˜å‡½æ•° %s çš„å‚æ•°ç±»åž‹ \"opaque\" 为 \"cstring\"" -#: commands/typecmds.c:1738 +#: commands/typecmds.c:1784 #, c-format msgid "changing argument type of function %s from \"opaque\" to %s" msgstr "改å˜å‡½æ•° %s çš„å‚æ•°ç±»åž‹ \"opaque\" 为 %s" -#: commands/typecmds.c:1837 +#: commands/typecmds.c:1883 #, c-format -#| msgid "type input function %s must return type %s" msgid "typmod_in function %s must return type %s" msgstr "typmod_in 函数 %s 必需返回类型 %s" -#: commands/typecmds.c:1864 +#: commands/typecmds.c:1910 #, c-format -#| msgid "typmod_out function %s must return type \"cstring\"" msgid "typmod_out function %s must return type %s" msgstr "typmod_out 函数 %s 必需返回类型 %s" -#: commands/typecmds.c:1891 +#: commands/typecmds.c:1937 #, c-format -#| msgid "type analyze function %s must return type \"boolean\"" msgid "type analyze function %s must return type %s" msgstr "类型分æžå‡½æ•° %s 必需返回类型 %s" -#: commands/typecmds.c:1937 +#: commands/typecmds.c:1983 #, c-format -msgid "" -"You must specify an operator class for the range type or define a default " -"operator class for the subtype." +msgid "You must specify an operator class for the range type or define a default operator class for the subtype." msgstr "你必须为范围类型指定一个æ“作符类或者为å­ç±»åž‹å®šä¹‰ä¸€ä¸ªé»˜è®¤çš„æ“ä½œç¬¦ç±»." -#: commands/typecmds.c:1968 +#: commands/typecmds.c:2014 #, c-format msgid "range canonical function %s must return range type" msgstr "范围的标准函数%s必须返回范围类型" -#: commands/typecmds.c:1974 +#: commands/typecmds.c:2020 #, c-format msgid "range canonical function %s must be immutable" msgstr "范围的标准函数%s必须是ä¸å¯å˜çš„" -#: commands/typecmds.c:2010 +#: commands/typecmds.c:2056 #, c-format -#| msgid "range subtype diff function %s must return type double precision" msgid "range subtype diff function %s must return type %s" msgstr "范围å­ç±»åž‹çš„ diff 函数 %s 必须返回类型 %s" -#: commands/typecmds.c:2017 +#: commands/typecmds.c:2063 #, c-format msgid "range subtype diff function %s must be immutable" msgstr "范围的å­ç±»åž‹diff函数%s必须是ä¸å¯å˜çš„" -#: commands/typecmds.c:2044 +#: commands/typecmds.c:2090 #, c-format msgid "pg_type array OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_type的数组OID值" -#: commands/typecmds.c:2348 +#: commands/typecmds.c:2398 #, c-format msgid "column \"%s\" of table \"%s\" contains null values" msgstr "表 \"%2$s\" 的字段 \"%1$s\" 包å«ç©ºå€¼" -#: commands/typecmds.c:2463 commands/typecmds.c:2646 +#: commands/typecmds.c:2511 commands/typecmds.c:2713 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist" msgstr "域 \"%2$s\" çš„ 约æŸ\"%1$s\" ä¸å­˜åœ¨" -#: commands/typecmds.c:2467 +#: commands/typecmds.c:2515 #, c-format msgid "constraint \"%s\" of domain \"%s\" does not exist, skipping" msgstr "域 \"%2$s\" çš„ 约æŸ\"%1$s\" ä¸å­˜åœ¨, 跳过" -#: commands/typecmds.c:2652 +#: commands/typecmds.c:2720 #, c-format msgid "constraint \"%s\" of domain \"%s\" is not a check constraint" msgstr "域 \"%2$s\" çš„ 约æŸ\"%1$s\" 䏿˜¯ä¸€ä¸ªcheck约æŸ" -#: commands/typecmds.c:2758 +#: commands/typecmds.c:2826 #, c-format -msgid "" -"column \"%s\" of table \"%s\" contains values that violate the new constraint" +msgid "column \"%s\" of table \"%s\" contains values that violate the new constraint" msgstr "表 \"%2$s\" 的字段 \"%1$s\" 包å«çš„值è¿å了新约æŸ" -#: commands/typecmds.c:2971 commands/typecmds.c:3228 commands/typecmds.c:3417 +#: commands/typecmds.c:3055 commands/typecmds.c:3253 commands/typecmds.c:3335 +#: commands/typecmds.c:3522 #, c-format msgid "%s is not a domain" msgstr "%s 䏿˜¯ä¸€ä¸ªåŸŸ" -#: commands/typecmds.c:3005 +#: commands/typecmds.c:3087 #, c-format msgid "constraint \"%s\" for domain \"%s\" already exists" msgstr "域 \"%2$s\" çš„çº¦æŸ \"%1$s\" å·²ç»å­˜åœ¨" -#: commands/typecmds.c:3055 +#: commands/typecmds.c:3138 #, c-format msgid "cannot use table references in domain check constraint" msgstr "在域检查约æŸä¸­ä¸å¯ä»¥ä½¿ç”¨è¡¨å…³è”" -#: commands/typecmds.c:3158 commands/typecmds.c:3240 commands/typecmds.c:3534 +#: commands/typecmds.c:3265 commands/typecmds.c:3347 commands/typecmds.c:3639 #, c-format msgid "%s is a table's row type" msgstr "%s 是一个表的记录类型" -#: commands/typecmds.c:3160 commands/typecmds.c:3242 commands/typecmds.c:3536 +#: commands/typecmds.c:3267 commands/typecmds.c:3349 commands/typecmds.c:3641 #, c-format msgid "Use ALTER TABLE instead." msgstr "请使用 ALTER TABLE命令代替." -#: commands/typecmds.c:3167 commands/typecmds.c:3249 commands/typecmds.c:3449 +#: commands/typecmds.c:3274 commands/typecmds.c:3356 commands/typecmds.c:3554 #, c-format msgid "cannot alter array type %s" msgstr "ä¸èƒ½æ›´æ”¹æ•°ç»„类型%s" -#: commands/typecmds.c:3169 commands/typecmds.c:3251 commands/typecmds.c:3451 +#: commands/typecmds.c:3276 commands/typecmds.c:3358 commands/typecmds.c:3556 #, c-format msgid "You can alter type %s, which will alter the array type as well." msgstr "您能够修改类型%s, 因而也能修改数组类型" -#: commands/typecmds.c:3519 +#: commands/typecmds.c:3624 #, c-format msgid "type \"%s\" already exists in schema \"%s\"" msgstr "在于模å¼\"%2$s\"中已存在类型\"%1$s\"" -#: commands/user.c:149 +#: commands/user.c:140 #, c-format msgid "SYSID can no longer be specified" msgstr "ä¸èƒ½å†æŒ‡å®šSYSID" -#: commands/user.c:291 +#: commands/user.c:294 #, c-format msgid "must be superuser to create superusers" msgstr "åªæœ‰è¶…级用户能创建å¦ä¸€ä¸ªè¶…级用户" -#: commands/user.c:298 +#: commands/user.c:301 #, c-format msgid "must be superuser to create replication users" msgstr "åªæœ‰è¶…级用户能创建å¤åˆ¶ç”¨æˆ·" -#: commands/user.c:305 commands/user.c:693 +#: commands/user.c:308 commands/user.c:714 #, c-format msgid "must be superuser to change bypassrls attribute" msgstr "åªæœ‰è¶…级用户能更改绕过行级安全性属性(bypassrls)" -#: commands/user.c:312 +#: commands/user.c:315 #, c-format msgid "permission denied to create role" msgstr "创建角色的æƒé™ä¸å¤Ÿ" -#: commands/user.c:322 commands/user.c:1176 commands/user.c:1183 gram.y:13599 -#: gram.y:13634 +#: commands/user.c:325 commands/user.c:1204 commands/user.c:1211 +#: utils/adt/acl.c:5342 utils/adt/acl.c:5348 gram.y:14896 gram.y:14934 #, c-format msgid "role name \"%s\" is reserved" msgstr "角色åç§° \"%s\" 被ä¿ç•™äº†" -#: commands/user.c:324 commands/user.c:1178 commands/user.c:1185 +#: commands/user.c:327 commands/user.c:1206 commands/user.c:1213 #, c-format -#| msgid "role name \"%s\" is reserved" msgid "Role names starting with \"pg_\" are reserved." msgstr "以 \"pg_\" å¼€å§‹çš„è§’è‰²åæ˜¯è¢«ä¿ç•™çš„。" -#: commands/user.c:336 commands/user.c:1191 +#: commands/user.c:339 commands/user.c:1219 #, c-format msgid "role \"%s\" already exists" msgstr "角色\"%s\" å·²ç»å­˜åœ¨" -#: commands/user.c:414 +#: commands/user.c:405 commands/user.c:823 +#, c-format +msgid "empty string is not a valid password, clearing password" +msgstr "ç©ºå­—ç¬¦ä¸²ä¸æ˜¯æœ‰æ•ˆå¯†ç ï¼Œæ­£åœ¨æ¸…除密ç " + +#: commands/user.c:434 #, c-format msgid "pg_authid OID value not set when in binary upgrade mode" msgstr "当处于二进制å‡çº§æ¨¡å¼æ—¶æ²¡æœ‰è®¾ç½®pg_authidçš„OID值" -#: commands/user.c:679 commands/user.c:896 commands/user.c:1443 -#: commands/user.c:1589 +#: commands/user.c:700 commands/user.c:924 commands/user.c:1458 +#: commands/user.c:1602 #, c-format msgid "must be superuser to alter superusers" msgstr "åªæœ‰è¶…级用户能修改超级用户" -#: commands/user.c:686 +#: commands/user.c:707 #, c-format msgid "must be superuser to alter replication users" msgstr "åªæœ‰è¶…级用户能修改å¤åˆ¶ç”¨æˆ·" -#: commands/user.c:709 commands/user.c:904 +#: commands/user.c:730 commands/user.c:931 #, c-format msgid "permission denied" msgstr "æƒé™ä¸å¤Ÿ" -#: commands/user.c:934 +#: commands/user.c:961 #, c-format msgid "must be superuser to alter settings globally" msgstr "åªæœ‰è¶…级用户å¯ä»¥åšå…¨å±€çš„alter settingsæ“作" -#: commands/user.c:956 +#: commands/user.c:983 #, c-format msgid "permission denied to drop role" msgstr "删除角色的æƒé™ä¸å¤Ÿ" -#: commands/user.c:980 +#: commands/user.c:1008 #, c-format -#| msgid "cannot use special role specifier in \"%s\"" msgid "cannot use special role specifier in DROP ROLE" msgstr "ä¸èƒ½åœ¨ DROP ROLE 中使用特殊角色说明符" -#: commands/user.c:990 commands/user.c:1147 commands/variable.c:805 -#: commands/variable.c:880 utils/adt/acl.c:5121 utils/adt/acl.c:5173 -#: utils/adt/acl.c:5206 utils/adt/acl.c:5224 utils/init/miscinit.c:502 +#: commands/user.c:1018 commands/user.c:1175 commands/variable.c:770 +#: commands/variable.c:844 utils/adt/acl.c:5199 utils/adt/acl.c:5246 +#: utils/adt/acl.c:5274 utils/adt/acl.c:5292 utils/init/miscinit.c:607 #, c-format msgid "role \"%s\" does not exist" msgstr "角色 \"%s\" ä¸å­˜åœ¨" -#: commands/user.c:995 +#: commands/user.c:1023 #, c-format msgid "role \"%s\" does not exist, skipping" msgstr "角色 \"%s\" ä¸å­˜åœ¨" -#: commands/user.c:1007 commands/user.c:1011 +#: commands/user.c:1036 commands/user.c:1040 #, c-format msgid "current user cannot be dropped" msgstr "当å‰ç”¨æˆ·ä¸èƒ½è¢«åˆ é™¤" -#: commands/user.c:1015 +#: commands/user.c:1044 #, c-format msgid "session user cannot be dropped" msgstr "会è¯ç”¨æˆ·ä¸èƒ½è¢«åˆ é™¤" -#: commands/user.c:1026 +#: commands/user.c:1054 #, c-format msgid "must be superuser to drop superusers" msgstr "åªæœ‰è¶…级用户å¯ä»¥åˆ é™¤è¶…级用户" -#: commands/user.c:1042 +#: commands/user.c:1070 #, c-format msgid "role \"%s\" cannot be dropped because some objects depend on it" msgstr "无法删除\"%s\"因为有其它对象倚赖它" -#: commands/user.c:1163 +#: commands/user.c:1191 #, c-format msgid "session user cannot be renamed" msgstr "无法é‡å‘½å会è¯ç”¨æˆ·" -#: commands/user.c:1167 +#: commands/user.c:1195 #, c-format msgid "current user cannot be renamed" msgstr "æ— æ³•é‡æ–°å‘½å当å‰ç”¨æˆ·" -#: commands/user.c:1201 +#: commands/user.c:1229 #, c-format msgid "must be superuser to rename superusers" msgstr "åªæœ‰è¶…级用户å¯ä»¥å¯¹è¶…级用户é‡å‘½å" -#: commands/user.c:1208 +#: commands/user.c:1236 #, c-format msgid "permission denied to rename role" msgstr "é‡å‘½å角色的æƒé™ä¸å¤Ÿ" -#: commands/user.c:1229 +#: commands/user.c:1257 #, c-format msgid "MD5 password cleared because of role rename" msgstr "由于对角色é‡å‘½å, éœ€è¦æ¸…除以MD5æ–¹å¼åŠ å¯†çš„å£ä»¤" -#: commands/user.c:1299 +#: commands/user.c:1317 #, c-format msgid "column names cannot be included in GRANT/REVOKE ROLE" msgstr "在GRANT/REVOKE ROLE中ä¸èƒ½åŒ…å«åˆ—å" -#: commands/user.c:1337 +#: commands/user.c:1355 #, c-format msgid "permission denied to drop objects" msgstr "删除对象的æƒé™ä¸è¶³" -#: commands/user.c:1364 commands/user.c:1376 +#: commands/user.c:1382 commands/user.c:1391 #, c-format msgid "permission denied to reassign objects" msgstr "釿–°åˆ†é…对象的æƒé™ä¸è¶³" -#: commands/user.c:1451 commands/user.c:1597 +#: commands/user.c:1466 commands/user.c:1610 #, c-format msgid "must have admin option on role \"%s\"" msgstr "在角色\"%s\"上必须有admin选项" -#: commands/user.c:1468 +#: commands/user.c:1483 #, c-format msgid "must be superuser to set grantor" msgstr "åªæœ‰è¶…级用户能设置授æƒè€…" -#: commands/user.c:1493 +#: commands/user.c:1508 #, c-format msgid "role \"%s\" is a member of role \"%s\"" msgstr "角色\"%s\" 是角色\"%s\"çš„æˆå‘˜" -#: commands/user.c:1508 +#: commands/user.c:1523 #, c-format msgid "role \"%s\" is already a member of role \"%s\"" msgstr "角色\"%s\" å·²ç»æ˜¯è§’色\"%s\"çš„æˆå‘˜" -#: commands/user.c:1619 +#: commands/user.c:1632 #, c-format msgid "role \"%s\" is not a member of role \"%s\"" msgstr "角色 \"%s\"䏿˜¯è§’色 \"%s\"çš„æˆå‘˜" -#: commands/vacuum.c:185 -#, c-format -msgid "%s cannot be executed from VACUUM or ANALYZE" -msgstr "ä¸èƒ½ä»ŽVACUUM或ANALYZE执行%s" - -#: commands/vacuum.c:528 -#, c-format -msgid "oldest xmin is far in the past" -msgstr "最旧的xminå·²ç»è¿‡åŽ»å¾ˆä¹…" - -#: commands/vacuum.c:529 -#, c-format -msgid "Close open transactions soon to avoid wraparound problems." -msgstr "ç«‹å³å…³é—­å·²æ‰“开的事物, 以é¿å… wraparound 问题." - -#: commands/vacuum.c:568 -#, c-format -msgid "oldest multixact is far in the past" -msgstr "最旧的多事务已ç»è¿‡åŽ»å¾ˆä¹…" +#: commands/vacuum.c:116 +#, fuzzy, c-format +#| msgid "unrecognized EXPLAIN option \"%s\"" +msgid "unrecognized ANALYZE option \"%s\"" +msgstr "无法识别的EXPLAIN选项\"%s\"" -#: commands/vacuum.c:569 +#: commands/vacuum.c:135 #, c-format -msgid "" -"Close open transactions with multixacts soon to avoid wraparound problems." -msgstr "ç«‹å³å…³é—­å·²æ‰“开的事务, 以é¿å…é‡å é—®é¢˜." +msgid "unrecognized VACUUM option \"%s\"" +msgstr "无法识别的清ç†é€‰é¡¹\"%s\"" -#: commands/vacuum.c:1131 +#: commands/vacuum.c:169 #, c-format -msgid "some databases have not been vacuumed in over 2 billion transactions" -msgstr "一些数æ®åº“在超过 20 äº¿ç¬”äº‹ç‰©åŽæ²¡æœ‰åšæ¸…ç† (vacuum)." +msgid "ANALYZE option must be specified when a column list is provided" +msgstr "æä¾›åˆ—列表时必须指定ANALYZE选项" -#: commands/vacuum.c:1132 +#: commands/vacuum.c:259 #, c-format -msgid "You might have already suffered transaction-wraparound data loss." -msgstr "您å¯èƒ½å·²ç»é‡åˆ°äº†ç”±äºŽäº‹åŠ¡é‡å è€Œé€ æˆçš„æ•°æ®ä¸¢å¤±." +msgid "%s cannot be executed from VACUUM or ANALYZE" +msgstr "ä¸èƒ½ä»ŽVACUUM或ANALYZE执行%s" -#: commands/vacuum.c:1253 +#: commands/vacuum.c:269 #, c-format -msgid "skipping vacuum of \"%s\" --- lock not available" -msgstr "跳过对 \"%s\" çš„åŽ‹ç¼©å¤„ç† --- 无法获å–相应é”" +msgid "VACUUM option DISABLE_PAGE_SKIPPING cannot be used with FULL" +msgstr "VACUUM 选项 DISABLE_PAGE_SKIPPINGä¸èƒ½ä¸Ž FULL 一起使用" -#: commands/vacuum.c:1279 +#: commands/vacuum.c:502 #, c-format msgid "skipping \"%s\" --- only superuser can vacuum it" msgstr "忽略 \"%s\" --- åªæœ‰è¶…çº§ç”¨æˆ·èƒ½å¤Ÿæ¸…ç† (vacuum)" -#: commands/vacuum.c:1283 +#: commands/vacuum.c:506 #, c-format msgid "skipping \"%s\" --- only superuser or database owner can vacuum it" msgstr "忽略 \"%s\" --- åªæœ‰è¶…级用户或数æ®åº“å±žä¸»èƒ½å¤Ÿæ¸…ç† (vacuum)" -#: commands/vacuum.c:1287 +#: commands/vacuum.c:510 #, c-format msgid "skipping \"%s\" --- only table or database owner can vacuum it" msgstr "忽略 \"%s\" --- åªæœ‰è¡¨æˆ–æ•°æ®åº“å±žä¸»èƒ½å¤Ÿæ¸…ç† (vacuum)" -#: commands/vacuum.c:1305 +#: commands/vacuum.c:525 #, c-format -msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" -msgstr "忽略 \"%s\" --- æ— æ³•æ¸…ç† (vacuum) éžè¡¨æˆ–者特殊的系统表" +msgid "skipping \"%s\" --- only superuser can analyze it" +msgstr "忽略 \"%s\" --- åªæœ‰è¶…级用户能够分æžå®ƒ" -#: commands/vacuumlazy.c:363 +#: commands/vacuum.c:529 #, c-format -msgid "automatic vacuum of table \"%s.%s.%s\": index scans: %d\n" -msgstr "自动清ç†è¡¨\"%s.%s.%s\":索引扫æï¼š%d\n" +msgid "skipping \"%s\" --- only superuser or database owner can analyze it" +msgstr "忽略 \"%s\" --- åªæœ‰è¶…级用户或数æ®åº“的属主能够分æžå®ƒ" -#: commands/vacuumlazy.c:368 +#: commands/vacuum.c:533 #, c-format -#| msgid "pages: %u removed, %u remain, %u skipped due to pins\n" -msgid "" -"pages: %u removed, %u remain, %u skipped due to pins, %u skipped frozen\n" -msgstr "页é¢ï¼š%u 被移除,%u ä¿ç•™ï¼Œ%u 由于被å ç”¨è€Œè·³è¿‡ï¼Œ%u 被跳过的已被冻结\n" +msgid "skipping \"%s\" --- only table or database owner can analyze it" +msgstr "忽略 \"%s\" --- åªæœ‰è¡¨æˆ–æ•°æ®åº“的属主能够分æžå®ƒ" -#: commands/vacuumlazy.c:374 +#: commands/vacuum.c:612 commands/vacuum.c:708 #, c-format -msgid "" -"tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n" -msgstr "元组:%.0f被移除,%.0fä¿ç•™ï¼Œ%.0få·²ç»æ­»äº¡ä½†è¿˜ä¸èƒ½è¢«ç§»é™¤\n" +msgid "skipping vacuum of \"%s\" --- lock not available" +msgstr "跳过对 \"%s\" çš„åŽ‹ç¼©å¤„ç† --- 无法获å–相应é”" -#: commands/vacuumlazy.c:379 +#: commands/vacuum.c:617 #, c-format -msgid "buffer usage: %d hits, %d misses, %d dirtied\n" -msgstr "缓冲区使用:%d次命中,%d次失效,%d次è„\n" +msgid "skipping vacuum of \"%s\" --- relation no longer exists" +msgstr "跳过对 \"%s\" çš„åŽ‹ç¼©å¤„ç† --- 关系ä¸å†å­˜åœ¨" -#: commands/vacuumlazy.c:383 +#: commands/vacuum.c:633 commands/vacuum.c:713 #, c-format -msgid "avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n" -msgstr "å¹³å‡è¯»å–率:%.3f MB/s,平å‡å†™å…¥çŽ‡ï¼š%.3f MB/s\n" +msgid "skipping analyze of \"%s\" --- lock not available" +msgstr "跳过对 \"%s\"çš„åˆ†æž --- 锿— æ³•得到" -#: commands/vacuumlazy.c:385 +#: commands/vacuum.c:638 #, c-format -msgid "system usage: %s" -msgstr "系统用法:%s" +msgid "skipping analyze of \"%s\" --- relation no longer exists" +msgstr "跳过对 \"%s\"çš„åˆ†æž --- 关系ä¸å†å­˜åœ¨" -#: commands/vacuumlazy.c:837 +#: commands/vacuum.c:935 #, c-format -msgid "relation \"%s\" page %u is uninitialized --- fixing" -msgstr "关系 \"%s\" 页 %u 没有åˆå§‹åŒ– --- ä¿®å¤" +msgid "oldest xmin is far in the past" +msgstr "最旧的xminå·²ç»è¿‡åŽ»å¾ˆä¹…" -#: commands/vacuumlazy.c:1301 +#: commands/vacuum.c:936 #, c-format -msgid "\"%s\": removed %.0f row versions in %u pages" -msgstr "\"%1$s\": 在%3$u页中已删除%2$.0f行版本å·" +msgid "" +"Close open transactions soon to avoid wraparound problems.\n" +"You might also need to commit or roll back old prepared transactions, or drop stale replication slots." +msgstr "" +"很快关闭未结交易以é¿å…覆盖问题.\n" +"您å¯èƒ½è¿˜éœ€è¦æäº¤æˆ–回滚旧的准备好的事务,或者删除过时的å¤åˆ¶æ§½." -#: commands/vacuumlazy.c:1311 +#: commands/vacuum.c:976 #, c-format -msgid "%.0f dead row versions cannot be removed yet.\n" -msgstr "%.0f的死亡行版本还ä¸èƒ½è¢«ç§»é™¤ã€‚\n" +msgid "oldest multixact is far in the past" +msgstr "最旧的多事务已ç»è¿‡åŽ»å¾ˆä¹…" -#: commands/vacuumlazy.c:1313 +#: commands/vacuum.c:977 #, c-format -msgid "There were %.0f unused item pointers.\n" -msgstr "有%.0f个未用的项指针。\n" +msgid "Close open transactions with multixacts soon to avoid wraparound problems." +msgstr "ç«‹å³å…³é—­å·²æ‰“开的事务, 以é¿å…é‡å é—®é¢˜." -#: commands/vacuumlazy.c:1315 +#: commands/vacuum.c:1548 #, c-format -msgid "Skipped %u page due to buffer pins.\n" -msgid_plural "Skipped %u pages due to buffer pins.\n" -msgstr[0] "由于缓冲区å ç”¨è€Œè·³è¿‡%u个页é¢ã€‚\n" +msgid "some databases have not been vacuumed in over 2 billion transactions" +msgstr "一些数æ®åº“在超过 20 äº¿ç¬”äº‹ç‰©åŽæ²¡æœ‰åšæ¸…ç† (vacuum)." -#: commands/vacuumlazy.c:1319 +#: commands/vacuum.c:1549 #, c-format -msgid "%u page is entirely empty.\n" -msgid_plural "%u pages are entirely empty.\n" -msgstr[0] "%u 个页é¢å®Œå…¨ä¸ºç©ºã€‚\n" +msgid "You might have already suffered transaction-wraparound data loss." +msgstr "您å¯èƒ½å·²ç»é‡åˆ°äº†ç”±äºŽäº‹åŠ¡é‡å è€Œé€ æˆçš„æ•°æ®ä¸¢å¤±." -#: commands/vacuumlazy.c:1327 +#: commands/vacuum.c:1707 #, c-format -msgid "" -"\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u " -"pages" -msgstr "" -"\"%1$s\": 在超出%5$u页的%4$u中找到å¯åˆ é™¤ç‰ˆæœ¬å·%2$.0f, ä¸å¯åˆ é™¤çš„版本å·%3$.0f" - -#: commands/vacuumlazy.c:1396 -#, c-format -msgid "\"%s\": removed %d row versions in %d pages" -msgstr "\"%1$s\": 在%3$d个页中已删除%2$d记录版本" - -#: commands/vacuumlazy.c:1585 -#, c-format -msgid "scanned index \"%s\" to remove %d row versions" -msgstr "扫æç´¢å¼•\"%s\"æ¥åˆ é™¤%d记录版本" - -#: commands/vacuumlazy.c:1631 -#, c-format -msgid "index \"%s\" now contains %.0f row versions in %u pages" -msgstr "索引\"%1$s\"在%3$u个页中包å«äº†è¡Œç‰ˆæœ¬å·%2$.0f" - -#: commands/vacuumlazy.c:1635 -#, c-format -msgid "" -"%.0f index row versions were removed.\n" -"%u index pages have been deleted, %u are currently reusable.\n" -"%s." -msgstr "" -"索引行版本%.0f被删除.\n" -"%u个索引页已ç»è¢«åˆ é™¤,%u当å‰å¯é‡ç”¨.\n" -"%s." - -#: commands/vacuumlazy.c:1721 -#, c-format -msgid "\"%s\": stopping truncate due to conflicting lock request" -msgstr "\"%s\":由于与é”请求相冲çªï¼Œåœæ­¢æˆªæ–­æ“作" - -#: commands/vacuumlazy.c:1786 -#, c-format -msgid "\"%s\": truncated %u to %u pages" -msgstr "\"%s\": å°†%u截断到%u pages" - -#: commands/vacuumlazy.c:1842 -#, c-format -msgid "\"%s\": suspending truncate due to conflicting lock request" -msgstr "\"%s\":由于与é”请求相冲çªï¼Œæš‚åœæˆªæ–­æ“作" +msgid "skipping \"%s\" --- cannot vacuum non-tables or special system tables" +msgstr "忽略 \"%s\" --- æ— æ³•æ¸…ç† (vacuum) éžè¡¨æˆ–者特殊的系统表" -#: commands/variable.c:164 utils/misc/guc.c:9877 +#: commands/variable.c:165 utils/misc/guc.c:10940 utils/misc/guc.c:11002 #, c-format msgid "Unrecognized key word: \"%s\"." msgstr "未知的关键字: \"%s\"." -#: commands/variable.c:176 +#: commands/variable.c:177 #, c-format msgid "Conflicting \"datestyle\" specifications." msgstr "\"datestyle\" 规范冲çª." -#: commands/variable.c:298 +#: commands/variable.c:299 #, c-format msgid "Cannot specify months in time zone interval." msgstr "在 time zone interval中无法指定月." -#: commands/variable.c:304 +#: commands/variable.c:305 #, c-format msgid "Cannot specify days in time zone interval." msgstr "在 time zone interval中无法指定天." -#: commands/variable.c:346 commands/variable.c:428 +#: commands/variable.c:343 commands/variable.c:425 #, c-format msgid "time zone \"%s\" appears to use leap seconds" msgstr "时区 \"%s\" 看上去使用了闰秒" -#: commands/variable.c:348 commands/variable.c:430 +#: commands/variable.c:345 commands/variable.c:427 #, c-format msgid "PostgreSQL does not support leap seconds." msgstr "PostgreSQL 䏿”¯æŒé—°ç§’" -#: commands/variable.c:357 +#: commands/variable.c:354 #, c-format msgid "UTC timezone offset is out of range." msgstr "UTC时区å移已超出范围" -#: commands/variable.c:497 +#: commands/variable.c:494 #, c-format msgid "cannot set transaction read-write mode inside a read-only transaction" msgstr "ä¸èƒ½åœ¨ä¸€ä¸ªåªè¯»äº‹ç‰©é‡Œé¢è®¾ç½®è¯»å†™æ¨¡å¼" -#: commands/variable.c:504 +#: commands/variable.c:501 #, c-format msgid "transaction read-write mode must be set before any query" msgstr "æ‰§è¡Œä»»æ„æŸ¥è¯¢å‰å¿…须设置事务的读写模å¼" -#: commands/variable.c:511 +#: commands/variable.c:508 #, c-format msgid "cannot set transaction read-write mode during recovery" msgstr "在æ¢å¤æ“作期间ä¸èƒ½è®¾ç½®äº‹åŠ¡çš„è¯»å†™æ¨¡å¼" -#: commands/variable.c:560 +#: commands/variable.c:534 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must be called before any query" msgstr "SET TRANSACTION ISOLATION LEVEL 必须在任何查询之å‰è°ƒç”¨" -#: commands/variable.c:567 +#: commands/variable.c:541 #, c-format msgid "SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction" msgstr "SET TRANSACTION ISOLATION LEVEL ä¸èƒ½åœ¨å­äº‹ç‰©ä¸­è°ƒç”¨" -#: commands/variable.c:574 storage/lmgr/predicate.c:1587 +#: commands/variable.c:548 storage/lmgr/predicate.c:1626 #, c-format msgid "cannot use serializable mode in a hot standby" msgstr "热备过程中无法使用å¯ä¸²è¡ŒåŒ–模å¼" -#: commands/variable.c:575 +#: commands/variable.c:549 #, c-format msgid "You can use REPEATABLE READ instead." msgstr "您必须使用REPEATABLE READæ¥ä»£æ›¿" -#: commands/variable.c:623 +#: commands/variable.c:567 #, c-format -msgid "" -"SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" +msgid "SET TRANSACTION [NOT] DEFERRABLE cannot be called within a subtransaction" msgstr "SET TRANSACTION [NOT] DEFERRABLE ä¸èƒ½åœ¨å­äº‹ç‰©ä¸­è°ƒç”¨" -#: commands/variable.c:629 +#: commands/variable.c:573 #, c-format msgid "SET TRANSACTION [NOT] DEFERRABLE must be called before any query" msgstr "SET TRANSACTION [NOT] DEFERRABLE 必须在任何查询之å‰è°ƒç”¨" -#: commands/variable.c:711 +#: commands/variable.c:655 #, c-format msgid "Conversion between %s and %s is not supported." msgstr "䏿”¯æŒ %s å’Œ %s 之间的编ç è½¬æ¢." -#: commands/variable.c:718 +#: commands/variable.c:662 #, c-format msgid "Cannot change \"client_encoding\" now." msgstr "çŽ°åœ¨æ— æ³•æ”¹å˜ \"client_encoding\" 值." -#: commands/variable.c:898 +#: commands/variable.c:723 +#, c-format +msgid "cannot change client_encoding during a parallel operation" +msgstr "在并行æ“作期间无法更改客户端编ç " + +#: commands/variable.c:863 #, c-format msgid "permission denied to set role \"%s\"" msgstr "设置角色\"%s\"çš„æƒé™ä¸è¶³" @@ -10132,480 +11027,518 @@ msgstr " \"check_option\" 选项的值无效" msgid "Valid values are \"local\" and \"cascaded\"." msgstr "有效值为 \"local\" å’Œ \"cascaded\"." -#: commands/view.c:114 +#: commands/view.c:103 #, c-format msgid "could not determine which collation to use for view column \"%s\"" msgstr "视图中的列\"%s\"æ— æ³•ç¡®å®šä½¿ç”¨å“ªç§æŽ’åºè§„则" -#: commands/view.c:129 -#, c-format -msgid "view must have at least one column" -msgstr "视图必需至少有一个字段" - -#: commands/view.c:263 commands/view.c:275 +#: commands/view.c:280 commands/view.c:291 #, c-format msgid "cannot drop columns from view" msgstr "无法从视图中删除列" -#: commands/view.c:280 +#: commands/view.c:296 #, c-format msgid "cannot change name of view column \"%s\" to \"%s\"" msgstr "ä¸èƒ½å°†è§†å›¾å­—段的å称从\"%s\"改æˆ\"%s\"" -#: commands/view.c:288 +#: commands/view.c:304 #, c-format msgid "cannot change data type of view column \"%s\" from %s to %s" msgstr "ä¸å¯ä»¥å°†è§†å›¾å­—段 \"%s\" 的数æ®ç±»åž‹ä»Ž%s改为%s" -#: commands/view.c:427 +#: commands/view.c:451 #, c-format msgid "views must not contain SELECT INTO" msgstr "视力中ä¸èƒ½åŒ…å«SELECT INTO" -#: commands/view.c:440 +#: commands/view.c:463 #, c-format msgid "views must not contain data-modifying statements in WITH" msgstr "视图ä¸èƒ½åŒ…å«ä¿®æ”¹æ•°æ®çš„WITHå­å¥" -#: commands/view.c:511 +#: commands/view.c:533 #, c-format msgid "CREATE VIEW specifies more column names than columns" msgstr "CREATE VIEW æŒ‡å®šçš„å­—æ®µåæ¯”实际字段多" -#: commands/view.c:519 +#: commands/view.c:541 #, c-format msgid "views cannot be unlogged because they do not have storage" msgstr "è§†å›¾æ— æ³•å–æ¶ˆäº‹åŠ¡æ—¥å¿—ï¼Œå› ä¸ºå®ƒä»¬æ²¡æœ‰ç›¸åº”å­˜å‚¨" -#: commands/view.c:533 +#: commands/view.c:555 #, c-format msgid "view \"%s\" will be a temporary view" msgstr "视图\"%s\" 将是一个临时视图." -#: executor/execCurrent.c:76 +#: executor/execCurrent.c:79 #, c-format msgid "cursor \"%s\" is not a SELECT query" msgstr "游标 \"%s\"䏿˜¯ä¸€ä¸ªSELECT查询" -#: executor/execCurrent.c:82 +#: executor/execCurrent.c:85 #, c-format msgid "cursor \"%s\" is held from a previous transaction" msgstr "游标\"%s\"是å‰ä¸€ä¸ªäº‹åŠ¡æ‰€æŒæœ‰çš„" -#: executor/execCurrent.c:114 +#: executor/execCurrent.c:118 #, c-format msgid "cursor \"%s\" has multiple FOR UPDATE/SHARE references to table \"%s\"" msgstr "游标\"%s\"有多个引用表\"%s\"çš„FOR UPDATE/SHARE语å¥" -#: executor/execCurrent.c:123 +#: executor/execCurrent.c:127 #, c-format -msgid "" -"cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" +msgid "cursor \"%s\" does not have a FOR UPDATE/SHARE reference to table \"%s\"" msgstr "游标\"%s\"没有引用表\"%s\"çš„FOR UPDATE/SHARE语å¥" -#: executor/execCurrent.c:133 executor/execCurrent.c:179 +#: executor/execCurrent.c:137 executor/execCurrent.c:182 #, c-format msgid "cursor \"%s\" is not positioned on a row" msgstr "没有在记录上对游标\"%s\"进行定ä½" -#: executor/execCurrent.c:166 +#: executor/execCurrent.c:169 executor/execCurrent.c:228 +#: executor/execCurrent.c:239 #, c-format msgid "cursor \"%s\" is not a simply updatable scan of table \"%s\"" msgstr "游标\"%s\"ä¸å¯¹è¡¨\"%s\"è¿›è¡Œå¯æ›´æ–°æ‰«æ" -#: executor/execCurrent.c:231 executor/execQual.c:1178 +#: executor/execCurrent.c:280 executor/execExprInterp.c:2312 #, c-format -msgid "" -"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" msgstr "第%dä¸ªå‚æ•°(%s)的类型与正在执行计划(%s)中的ä¸åŒ¹é…" -#: executor/execCurrent.c:243 executor/execQual.c:1190 +#: executor/execCurrent.c:292 executor/execExprInterp.c:2324 #, c-format msgid "no value found for parameter %d" msgstr "æ²¡æœ‰æ‰¾åˆ°å‚æ•° %d 的值" -#: executor/execIndexing.c:539 +#: executor/execExpr.c:857 parser/parse_agg.c:816 #, c-format -msgid "" -"ON CONFLICT does not support deferrable unique constraints/exclusion " -"constraints as arbiters" +msgid "window function calls cannot be nested" +msgstr "ä¸å…许嵌套调用窗å£å‡½æ•°" + +#: executor/execExpr.c:1316 +#, c-format +msgid "target type is not an array" +msgstr "ç›®æ ‡ç±»åž‹ä¸æ˜¯ä¸€ä¸ªæ•°ç»„" + +#: executor/execExpr.c:1649 +#, c-format +msgid "ROW() column has type %s instead of type %s" +msgstr "ROW() 列类型 %s 替æ¢ä¸º %s" + +#: executor/execExpr.c:2174 executor/execSRF.c:700 parser/parse_func.c:136 +#: parser/parse_func.c:650 parser/parse_func.c:1024 +#, c-format +msgid "cannot pass more than %d argument to a function" +msgid_plural "cannot pass more than %d arguments to a function" +msgstr[0] "å‘å‡½æ•°ä¼ é€’çš„å‚æ•°ä¸å¤šäºŽ%d个" + +#: executor/execExpr.c:2570 executor/execExpr.c:2576 +#: executor/execExprInterp.c:2641 utils/adt/arrayfuncs.c:261 +#: utils/adt/arrayfuncs.c:559 utils/adt/arrayfuncs.c:1301 +#: utils/adt/arrayfuncs.c:3347 utils/adt/arrayfuncs.c:5302 +#: utils/adt/arrayfuncs.c:5819 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "数组的维数(%d)超过最大å…许值(%d)" + +#: executor/execExprInterp.c:1862 +#, c-format +msgid "attribute %d of type %s has been dropped" +msgstr "已删除类型%2$s的属性%1$d" + +#: executor/execExprInterp.c:1868 +#, c-format +msgid "attribute %d of type %s has wrong type" +msgstr "类型%2$s的属性%1$d的类型错误" + +#: executor/execExprInterp.c:1870 executor/execExprInterp.c:2914 +#: executor/execExprInterp.c:2961 +#, c-format +msgid "Table has type %s, but query expects %s." +msgstr "表具有类型%s,但是查询期望类型%s." + +#: executor/execExprInterp.c:2402 +#, c-format +msgid "WHERE CURRENT OF is not supported for this table type" +msgstr "è¿™ç§è¡¨ç±»åž‹ä¸èƒ½ä½¿ç”¨WHERE CURRENT OF" + +#: executor/execExprInterp.c:2619 +#, c-format +msgid "cannot merge incompatible arrays" +msgstr "无法åˆå¹¶ä¸å…¼å®¹çš„æŽ’列" + +#: executor/execExprInterp.c:2620 +#, c-format +msgid "Array with element type %s cannot be included in ARRAY construct with element type %s." +msgstr "元素类型为 %s çš„ ARRAY 结构中ä¸èƒ½åŒ…å«å¸¦æœ‰å…ƒç´ ç±»åž‹ä¸º %s 的数组." + +#: executor/execExprInterp.c:2661 executor/execExprInterp.c:2691 +#, c-format +msgid "multidimensional arrays must have array expressions with matching dimensions" +msgstr "多维数组必须有符åˆç»´åº¦çš„æ•°ç»„表达å¼" + +#: executor/execExprInterp.c:2913 executor/execExprInterp.c:2960 +#, c-format +msgid "attribute %d has wrong type" +msgstr "属性%d的类型错误" + +#: executor/execExprInterp.c:3070 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "在分é…中的数组下标ä¸èƒ½ä¸ºç©º" + +#: executor/execExprInterp.c:3503 utils/adt/domains.c:149 +#, c-format +msgid "domain %s does not allow null values" +msgstr "域 %s ä¸å…许空值" + +#: executor/execExprInterp.c:3518 utils/adt/domains.c:184 +#, c-format +msgid "value for domain %s violates check constraint \"%s\"" +msgstr "域 %s 的值è¿åäº†æ£€æŸ¥çº¦æŸ \"%s\"" + +#: executor/execExprInterp.c:3889 executor/execExprInterp.c:3906 +#: executor/execExprInterp.c:4008 executor/nodeModifyTable.c:109 +#: executor/nodeModifyTable.c:120 executor/nodeModifyTable.c:137 +#: executor/nodeModifyTable.c:145 +#, c-format +msgid "table row type and query-specified row type do not match" +msgstr "表记录类型和查询指定记录ä¸åŒ¹é…" + +#: executor/execExprInterp.c:3890 +#, c-format +msgid "Table row contains %d attribute, but query expects %d." +msgid_plural "Table row contains %d attributes, but query expects %d." +msgstr[0] "在表记录中包å«%d个属性, 但是查询期望%d个属性" + +#: executor/execExprInterp.c:3907 executor/nodeModifyTable.c:121 +#, c-format +msgid "Table has type %s at ordinal position %d, but query expects %s." +msgstr "表在ä½ç½®%2$d具有类型%1$s,但是查询期望类型%3$s." + +#: executor/execExprInterp.c:4009 executor/execSRF.c:959 +#, c-format +msgid "Physical storage mismatch on dropped attribute at ordinal position %d." +msgstr "在顺åºä½ç½®%d上已删除属性与物ç†å­˜å‚¨ä¸Šçš„ä¸åŒ¹é…." + +#: executor/execIndexing.c:547 +#, c-format +msgid "ON CONFLICT does not support deferrable unique constraints/exclusion constraints as arbiters" msgstr "ON CONFLICT䏿”¯æŒå¯å»¶è¿Ÿå”¯ä¸€çº¦æŸ/排除约æŸä½œä¸ºä»²è£è€…" -#: executor/execIndexing.c:816 +#: executor/execIndexing.c:818 #, c-format msgid "could not create exclusion constraint \"%s\"" msgstr "无法创建排他约æŸ\"%s\"" -#: executor/execIndexing.c:819 +#: executor/execIndexing.c:821 #, c-format msgid "Key %s conflicts with key %s." msgstr "é”®%s与å¦å¤–一个键%s冲çª" -#: executor/execIndexing.c:821 +#: executor/execIndexing.c:823 #, c-format msgid "Key conflicts exist." msgstr "存在键冲çªã€‚" -#: executor/execIndexing.c:827 +#: executor/execIndexing.c:829 #, c-format msgid "conflicting key value violates exclusion constraint \"%s\"" msgstr "互相冲çªçš„键值è¿å排他约æŸ\"%s\"" -#: executor/execIndexing.c:830 +#: executor/execIndexing.c:832 #, c-format msgid "Key %s conflicts with existing key %s." msgstr "é”®%s与已存在的键%s冲çª" -#: executor/execIndexing.c:832 +#: executor/execIndexing.c:834 #, c-format msgid "Key conflicts with existing key." msgstr "与现有键å‘生键冲çªã€‚" -#: executor/execMain.c:1027 +#: executor/execMain.c:1093 #, c-format msgid "cannot change sequence \"%s\"" msgstr "ä¸å¯ä»¥æ”¹å˜åºåˆ— \"%s\"" -#: executor/execMain.c:1033 +#: executor/execMain.c:1099 #, c-format msgid "cannot change TOAST relation \"%s\"" msgstr "ä¸å¯ä»¥æ”¹å˜ TOAST 关系 \"%s\"" -#: executor/execMain.c:1051 rewrite/rewriteHandler.c:2648 +#: executor/execMain.c:1117 rewrite/rewriteHandler.c:2911 #, c-format msgid "cannot insert into view \"%s\"" msgstr "无法æ’入到视图\"%s\"" -#: executor/execMain.c:1053 rewrite/rewriteHandler.c:2651 +#: executor/execMain.c:1119 rewrite/rewriteHandler.c:2914 #, c-format -msgid "" -"To enable inserting into the view, provide an INSTEAD OF INSERT trigger or " -"an unconditional ON INSERT DO INSTEAD rule." -msgstr "" -"å¯ç”¨å‘视图æ’å…¥æ“作, è¦æä¾›INSTEAD OF INSERT触å‘器或者æä¾›ä¸€ä¸ªæ— æ¡ä»¶çš„ ON " -"INSERT DO INSTEAD 规则." +msgid "To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule." +msgstr "å¯ç”¨å‘视图æ’å…¥æ“作, è¦æä¾›INSTEAD OF INSERT触å‘器或者æä¾›ä¸€ä¸ªæ— æ¡ä»¶çš„ ON INSERT DO INSTEAD 规则." -#: executor/execMain.c:1059 rewrite/rewriteHandler.c:2656 +#: executor/execMain.c:1125 rewrite/rewriteHandler.c:2919 #, c-format msgid "cannot update view \"%s\"" msgstr "无法更新视图\"%s\"" -#: executor/execMain.c:1061 rewrite/rewriteHandler.c:2659 +#: executor/execMain.c:1127 rewrite/rewriteHandler.c:2922 #, c-format -msgid "" -"To enable updating the view, provide an INSTEAD OF UPDATE trigger or an " -"unconditional ON UPDATE DO INSTEAD rule." -msgstr "" -"å¯ç”¨å¯¹è§†å›¾çš„æ›´æ–°æ“作, éœ€è¦æä¾›INSTEAD OF UPDATE触å‘器或者一个无æ¡ä»¶çš„ ON " -"UPDATE DO INSTEAD 规则." +msgid "To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule." +msgstr "å¯ç”¨å¯¹è§†å›¾çš„æ›´æ–°æ“作, éœ€è¦æä¾›INSTEAD OF UPDATE触å‘器或者一个无æ¡ä»¶çš„ ON UPDATE DO INSTEAD 规则." -#: executor/execMain.c:1067 rewrite/rewriteHandler.c:2664 +#: executor/execMain.c:1133 rewrite/rewriteHandler.c:2927 #, c-format msgid "cannot delete from view \"%s\"" msgstr "无法删除视图\"%s\"" -#: executor/execMain.c:1069 rewrite/rewriteHandler.c:2667 +#: executor/execMain.c:1135 rewrite/rewriteHandler.c:2930 #, c-format -msgid "" -"To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an " -"unconditional ON DELETE DO INSTEAD rule." -msgstr "" -"å¯ç”¨ä»Žè§†å›¾åˆ é™¤æ•°æ®, éœ€è¦æä¾›ä¸€ä¸ªINSTEAD OF DELETE 触å‘器或者一个无æ¡ä»¶çš„ ON " -"DELETE DO INSTEAD 规则." +msgid "To enable deleting from the view, provide an INSTEAD OF DELETE trigger or an unconditional ON DELETE DO INSTEAD rule." +msgstr "å¯ç”¨ä»Žè§†å›¾åˆ é™¤æ•°æ®, éœ€è¦æä¾›ä¸€ä¸ªINSTEAD OF DELETE 触å‘器或者一个无æ¡ä»¶çš„ ON DELETE DO INSTEAD 规则." # describe.c:933 -#: executor/execMain.c:1080 +#: executor/execMain.c:1146 #, c-format msgid "cannot change materialized view \"%s\"" msgstr "ä¸èƒ½æ”¹å˜ç‰©åŒ–视图 \"%s\"" -#: executor/execMain.c:1092 +#: executor/execMain.c:1158 #, c-format msgid "cannot insert into foreign table \"%s\"" msgstr "ä¸èƒ½æ’值到外部表 \"%s\"" -#: executor/execMain.c:1098 +#: executor/execMain.c:1164 #, c-format msgid "foreign table \"%s\" does not allow inserts" msgstr "外部表 \"%s\" ä¸å…许æ’å…¥æ“作" -#: executor/execMain.c:1105 +#: executor/execMain.c:1171 #, c-format msgid "cannot update foreign table \"%s\"" msgstr "无法更新外部表 \"%s\"" -#: executor/execMain.c:1111 +#: executor/execMain.c:1177 #, c-format msgid "foreign table \"%s\" does not allow updates" msgstr "外部表 \"%s\" ä¸å…许更新" -#: executor/execMain.c:1118 +#: executor/execMain.c:1184 #, c-format msgid "cannot delete from foreign table \"%s\"" msgstr "ä¸èƒ½ä»Žå¤–部表 \"%s\" 删除数æ®" -#: executor/execMain.c:1124 +#: executor/execMain.c:1190 #, c-format msgid "foreign table \"%s\" does not allow deletes" msgstr "外部表 \"%s\" ä¸å…许删除数æ®" -#: executor/execMain.c:1135 +#: executor/execMain.c:1201 #, c-format msgid "cannot change relation \"%s\"" msgstr "无法改å˜å…³ç³» \"%s\"" -#: executor/execMain.c:1161 +#: executor/execMain.c:1228 #, c-format msgid "cannot lock rows in sequence \"%s\"" msgstr "无法é”定åºåˆ—\"%s\"中的行" -#: executor/execMain.c:1168 +#: executor/execMain.c:1235 #, c-format msgid "cannot lock rows in TOAST relation \"%s\"" msgstr "无法é”定TOAST 关系 \"%s\"中的行" -#: executor/execMain.c:1175 +#: executor/execMain.c:1242 #, c-format msgid "cannot lock rows in view \"%s\"" msgstr "无法é”定 \"%s\" 中的行" -#: executor/execMain.c:1183 +#: executor/execMain.c:1250 #, c-format msgid "cannot lock rows in materialized view \"%s\"" msgstr "无法é”定物化视图 \"%s\" 中的行" -#: executor/execMain.c:1192 executor/execMain.c:2603 -#: executor/nodeLockRows.c:132 +#: executor/execMain.c:1259 executor/execMain.c:2637 +#: executor/nodeLockRows.c:138 #, c-format msgid "cannot lock rows in foreign table \"%s\"" msgstr "无法é”定外部表 \"%s\"中的行" -#: executor/execMain.c:1198 +#: executor/execMain.c:1265 #, c-format msgid "cannot lock rows in relation \"%s\"" msgstr "无法é”定关系 \"%s\"中的行" -#: executor/execMain.c:1721 +#: executor/execMain.c:1891 #, c-format -msgid "null value in column \"%s\" violates not-null constraint" -msgstr "在字段 \"%s\" 中空值è¿å了éžç©ºçº¦æŸ" +msgid "new row for relation \"%s\" violates partition constraint" +msgstr "关系 \"%s\" 的新列è¿å了分区约æŸ" -#: executor/execMain.c:1723 executor/execMain.c:1749 executor/execMain.c:1838 +#: executor/execMain.c:1893 executor/execMain.c:1975 executor/execMain.c:2024 +#: executor/execMain.c:2133 #, c-format msgid "Failing row contains %s." msgstr "失败, 行包å«%s." -#: executor/execMain.c:1747 +#: executor/execMain.c:1973 +#, c-format +msgid "null value in column \"%s\" violates not-null constraint" +msgstr "在字段 \"%s\" 中空值è¿å了éžç©ºçº¦æŸ" + +#: executor/execMain.c:2022 #, c-format msgid "new row for relation \"%s\" violates check constraint \"%s\"" msgstr "关系 \"%s\" 的新列è¿åäº†æ£€æŸ¥çº¦æŸ \"%s\"" -#: executor/execMain.c:1836 +#: executor/execMain.c:2131 #, c-format msgid "new row violates check option for view \"%s\"" msgstr "新行è¿å了视图\"%s\"的检查选项" -#: executor/execMain.c:1846 +#: executor/execMain.c:2141 #, c-format msgid "new row violates row-level security policy \"%s\" for table \"%s\"" msgstr "新行è¿èƒŒäº†è¡¨\"%2$s\"的行级安全性策略\"%1$s\"" -#: executor/execMain.c:1851 +#: executor/execMain.c:2146 #, c-format msgid "new row violates row-level security policy for table \"%s\"" msgstr "新行è¿èƒŒäº†è¡¨\"%s\"的行级安全策略" -#: executor/execMain.c:1858 +#: executor/execMain.c:2153 #, c-format -msgid "" -"new row violates row-level security policy \"%s\" (USING expression) for " -"table \"%s\"" +msgid "new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"" msgstr "新行è¿èƒŒäº†è¡¨\"%s\"的行级安全策略\"%s\"(USING expression)" -#: executor/execMain.c:1863 +#: executor/execMain.c:2158 #, c-format -msgid "" -"new row violates row-level security policy (USING expression) for table \"%s" -"\"" +msgid "new row violates row-level security policy (USING expression) for table \"%s\"" msgstr "新行è¿èƒŒäº†è¡¨\"%s\"的行级安全策略(USING expression)" -#: executor/execQual.c:302 executor/execQual.c:339 executor/execQual.c:3213 -#: utils/adt/array_userfuncs.c:472 utils/adt/arrayfuncs.c:260 -#: utils/adt/arrayfuncs.c:558 utils/adt/arrayfuncs.c:1288 -#: utils/adt/arrayfuncs.c:3361 utils/adt/arrayfuncs.c:5245 -#: utils/adt/arrayfuncs.c:5768 +# describe.c:1542 +#: executor/execPartition.c:345 #, c-format -msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "数组的维数(%d)超过最大å…许值(%d)" +msgid "no partition of relation \"%s\" found for row" +msgstr "没有为行找到关系\"%s\"的分区" -#: executor/execQual.c:324 executor/execQual.c:360 +#: executor/execPartition.c:348 #, c-format -msgid "array subscript in assignment must not be null" -msgstr "在分é…中的数组下标ä¸èƒ½ä¸ºç©º" +msgid "Partition key of the failing row contains %s." +msgstr "失败行的分区键包å«%s." -#: executor/execQual.c:657 executor/execQual.c:4138 +#: executor/execReplication.c:195 executor/execReplication.c:359 #, c-format -msgid "attribute %d has wrong type" -msgstr "属性%d的类型错误" +msgid "tuple to be locked was already moved to another partition due to concurrent update, retrying" +msgstr "ç”±äºŽå¹¶å‘æ›´æ–°ï¼Œè¦é”定的元组已移动到å¦ä¸€ä¸ªåˆ†åŒºï¼Œæ­£åœ¨é‡è¯• " -#: executor/execQual.c:658 executor/execQual.c:4139 +#: executor/execReplication.c:199 executor/execReplication.c:363 #, c-format -msgid "Table has type %s, but query expects %s." -msgstr "表具有类型%s,但是查询期望类型%s." +msgid "concurrent update, retrying" +msgstr "并呿›´æ–°ï¼Œæ­£åœ¨é‡è¯•" -#: executor/execQual.c:851 executor/execQual.c:868 executor/execQual.c:1068 -#: executor/nodeModifyTable.c:95 executor/nodeModifyTable.c:105 -#: executor/nodeModifyTable.c:122 executor/nodeModifyTable.c:130 -#, c-format -msgid "table row type and query-specified row type do not match" -msgstr "表记录类型和查询指定记录ä¸åŒ¹é…" +#: executor/execReplication.c:205 executor/execReplication.c:369 +#, fuzzy, c-format +#| msgid "concurrent update, retrying" +msgid "concurrent delete, retrying" +msgstr "并呿›´æ–°ï¼Œæ­£åœ¨é‡è¯•" -#: executor/execQual.c:852 +#: executor/execReplication.c:263 parser/parse_oper.c:228 +#: utils/adt/array_userfuncs.c:719 utils/adt/array_userfuncs.c:858 +#: utils/adt/arrayfuncs.c:3625 utils/adt/arrayfuncs.c:4140 +#: utils/adt/arrayfuncs.c:6130 utils/adt/rowtypes.c:1180 #, c-format -msgid "Table row contains %d attribute, but query expects %d." -msgid_plural "Table row contains %d attributes, but query expects %d." -msgstr[0] "在表记录中包å«%d个属性, 但是查询期望%d个属性" +msgid "could not identify an equality operator for type %s" +msgstr "无法为类型%s识别等于æ“作符" -#: executor/execQual.c:869 executor/nodeModifyTable.c:106 +#: executor/execReplication.c:572 #, c-format -msgid "Table has type %s at ordinal position %d, but query expects %s." -msgstr "表在ä½ç½®%2$d具有类型%1$s,但是查询期望类型%3$s." +msgid "cannot update table \"%s\" because it does not have a replica identity and publishes updates" +msgstr "无法更新表\"%s\",因为它没有副本标识并å‘布更新" -#: executor/execQual.c:1069 executor/execQual.c:1665 +#: executor/execReplication.c:574 #, c-format -msgid "Physical storage mismatch on dropped attribute at ordinal position %d." -msgstr "在顺åºä½ç½®%d上已删除属性与物ç†å­˜å‚¨ä¸Šçš„ä¸åŒ¹é…." +msgid "To enable updating the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "è‹¥è¦å¯ç”¨è¡¨çš„æ›´æ–°ï¼Œè¯·ä½¿ç”¨ALTER TABLE设置REPLICA IDENTITY." -#: executor/execQual.c:1344 parser/parse_func.c:115 parser/parse_func.c:542 -#: parser/parse_func.c:895 +#: executor/execReplication.c:578 #, c-format -msgid "cannot pass more than %d argument to a function" -msgid_plural "cannot pass more than %d arguments to a function" -msgstr[0] "å‘å‡½æ•°ä¼ é€’çš„å‚æ•°ä¸å¤šäºŽ%d个" +msgid "cannot delete from table \"%s\" because it does not have a replica identity and publishes deletes" +msgstr "无法从表\"%s\"中删除,因为它没有副本标识并å‘布删除" -#: executor/execQual.c:1533 +#: executor/execReplication.c:580 #, c-format -msgid "functions and operators can take at most one set argument" -msgstr "函数和æ“ä½œç¬¦æœ€å¤šå¸¦ä¸€ç»„å‚æ•°" +msgid "To enable deleting from the table, set REPLICA IDENTITY using ALTER TABLE." +msgstr "è¦å¯ç”¨ä»Žè¡¨ä¸­åˆ é™¤ï¼Œè¯·ä½¿ç”¨ALTER TABLE设置REPLICA IDENTITY." -#: executor/execQual.c:1583 -#, c-format -msgid "" -"function returning setof record called in context that cannot accept type " -"record" -msgstr "调用用于返回setof记录的函数的环境ä¸èƒ½æŽ¥å—使用记录类型" +#: executor/execReplication.c:600 executor/execReplication.c:607 +#: executor/execReplication.c:615 +#, fuzzy, c-format +#| msgid "cannot use expression index \"%s\" as replica identity" +msgid "cannot use relation \"%s.%s\" as logical replication target" +msgstr "ä¸èƒ½å°†è¡¨è¾¾å¼ç´¢å¼•\"%s\"用作å¤åˆ¶æ ‡è¯†" -#: executor/execQual.c:1638 executor/execQual.c:1654 executor/execQual.c:1664 -#, c-format -msgid "function return row and query-specified return row do not match" -msgstr "指定查询返回记录和实际函数返回记录ä¸åŒ¹é…" +#: executor/execReplication.c:602 +#, fuzzy, c-format +#| msgid "\"%s\" is a partitioned table" +msgid "\"%s.%s\" is a partitioned table." +msgstr "\"%s\" 是一个分区表" -#: executor/execQual.c:1639 -#, c-format -msgid "Returned row contains %d attribute, but query expects %d." -msgid_plural "Returned row contains %d attributes, but query expects %d." -msgstr[0] "在所返回的记录中包å«äº†%d个属性,但是查询期望有%d个属性" +#: executor/execReplication.c:609 +#, fuzzy, c-format +#| msgid "\"%s\" is a foreign table" +msgid "\"%s.%s\" is a foreign table." +msgstr "\"%s\" 是一个外部表" + +#: executor/execReplication.c:617 +#, fuzzy, c-format +#| msgid "\"%s\" is not a table" +msgid "\"%s.%s\" is not a table." +msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªè¡¨" -#: executor/execQual.c:1655 +#: executor/execSRF.c:310 #, c-format -msgid "Returned type %s at ordinal position %d, but query expects %s." -msgstr "在顺åºä½ç½®%2$d的返回类型是%1$s, 但是查询期望使用类型%3$s." +msgid "rows returned by function are not all of the same row type" +msgstr "函数返回的记录ä¸å®Œå…¨å±žäºŽç›¸åŒçš„记录类型" -#: executor/execQual.c:1897 executor/execQual.c:2328 +#: executor/execSRF.c:358 executor/execSRF.c:649 #, c-format msgid "table-function protocol for materialize mode was not followed" msgstr "没有跟éšé’ˆå¯¹ç‰©åŒ–模å¼çš„表函数åè®®" -#: executor/execQual.c:1917 executor/execQual.c:2335 +#: executor/execSRF.c:365 executor/execSRF.c:667 #, c-format msgid "unrecognized table-function returnMode: %d" msgstr "未认å¯çš„è¡¨å‡½æ•°è¿”å›žæ¨¡å¼ (returnMode): %d" -#: executor/execQual.c:2245 -#, c-format -msgid "function returning set of rows cannot return null value" -msgstr "函数返回值为多列时ä¸èƒ½è¿”回空值" - -#: executor/execQual.c:2302 -#, c-format -msgid "rows returned by function are not all of the same row type" -msgstr "函数返回的记录ä¸å®Œå…¨å±žäºŽç›¸åŒçš„记录类型" - -#: executor/execQual.c:2517 -#, c-format -msgid "IS DISTINCT FROM does not support set arguments" -msgstr "IS DISTINCT FROM 䏿”¯æŒä¸€ç»„傿•°" - -#: executor/execQual.c:2594 -#, c-format -msgid "op ANY/ALL (array) does not support set arguments" -msgstr "æ“作符 ANY/ALL (数组) 䏿”¯æŒè®¾ç½®å‚æ•°" - -#: executor/execQual.c:3191 -#, c-format -msgid "cannot merge incompatible arrays" -msgstr "无法åˆå¹¶ä¸å…¼å®¹çš„æŽ’列" - -#: executor/execQual.c:3192 -#, c-format -msgid "" -"Array with element type %s cannot be included in ARRAY construct with " -"element type %s." -msgstr "元素类型为 %s çš„ ARRAY 结构中ä¸èƒ½åŒ…å«å¸¦æœ‰å…ƒç´ ç±»åž‹ä¸º %s 的数组." - -#: executor/execQual.c:3233 executor/execQual.c:3260 -#, c-format -msgid "" -"multidimensional arrays must have array expressions with matching dimensions" -msgstr "多维数组必须有符åˆç»´åº¦çš„æ•°ç»„表达å¼" - -#: executor/execQual.c:3775 -#, c-format -msgid "NULLIF does not support set arguments" -msgstr "NULLIF 䏿”¯æŒä¸€ç»„傿•°" - -#: executor/execQual.c:4008 utils/adt/domains.c:136 -#, c-format -msgid "domain %s does not allow null values" -msgstr "域 %s ä¸å…许空值" - -#: executor/execQual.c:4038 utils/adt/domains.c:173 -#, c-format -msgid "value for domain %s violates check constraint \"%s\"" -msgstr "域 %s 的值è¿åäº†æ£€æŸ¥çº¦æŸ \"%s\"" - -#: executor/execQual.c:4393 -#, c-format -msgid "WHERE CURRENT OF is not supported for this table type" -msgstr "è¿™ç§è¡¨ç±»åž‹ä¸èƒ½ä½¿ç”¨WHERE CURRENT OF" - -#: executor/execQual.c:4590 parser/parse_agg.c:743 +#: executor/execSRF.c:876 #, c-format -msgid "window function calls cannot be nested" -msgstr "ä¸å…许嵌套调用窗å£å‡½æ•°" +msgid "function returning setof record called in context that cannot accept type record" +msgstr "调用用于返回setof记录的函数的环境ä¸èƒ½æŽ¥å—使用记录类型" -#: executor/execQual.c:4802 +#: executor/execSRF.c:932 executor/execSRF.c:948 executor/execSRF.c:958 #, c-format -msgid "target type is not an array" -msgstr "ç›®æ ‡ç±»åž‹ä¸æ˜¯ä¸€ä¸ªæ•°ç»„" +msgid "function return row and query-specified return row do not match" +msgstr "指定查询返回记录和实际函数返回记录ä¸åŒ¹é…" -#: executor/execQual.c:4917 +#: executor/execSRF.c:933 #, c-format -msgid "ROW() column has type %s instead of type %s" -msgstr "ROW() 列类型 %s 替æ¢ä¸º %s" +msgid "Returned row contains %d attribute, but query expects %d." +msgid_plural "Returned row contains %d attributes, but query expects %d." +msgstr[0] "在所返回的记录中包å«äº†%d个属性,但是查询期望有%d个属性" -#: executor/execQual.c:5052 utils/adt/arrayfuncs.c:3803 -#: utils/adt/arrayfuncs.c:6341 utils/adt/rowtypes.c:927 +#: executor/execSRF.c:949 #, c-format -msgid "could not identify a comparison function for type %s" -msgstr "无法为类型 %s 确认一个比对函数" +msgid "Returned type %s at ordinal position %d, but query expects %s." +msgstr "在顺åºä½ç½®%2$d的返回类型是%1$s, 但是查询期望使用类型%3$s." -#: executor/execUtils.c:819 +#: executor/execUtils.c:712 #, c-format msgid "materialized view \"%s\" has not been populated" msgstr "物化视图 \"%s\"未被åˆå§‹åŒ–" -#: executor/execUtils.c:821 +#: executor/execUtils.c:714 #, c-format msgid "Use the REFRESH MATERIALIZED VIEW command." msgstr "使用命令 REFRESH MATERIALIZED VIEW." @@ -10615,1896 +11548,1947 @@ msgstr "使用命令 REFRESH MATERIALIZED VIEW." msgid "could not determine actual type of argument declared %s" msgstr "无法确定声明为 %s çš„å‚æ•°çš„实际类型" +#: executor/functions.c:521 +#, c-format +msgid "cannot COPY to/from client in a SQL function" +msgstr "无法在SQL函数中从客户端或å‘客户端使用COPY命令" + #. translator: %s is a SQL statement name -#: executor/functions.c:508 +#: executor/functions.c:527 #, c-format msgid "%s is not allowed in a SQL function" msgstr "%s ä¸å…许在一个 SQL 函数中" #. translator: %s is a SQL statement name -#: executor/functions.c:515 executor/spi.c:1368 executor/spi.c:2158 +#: executor/functions.c:535 executor/spi.c:1474 executor/spi.c:2262 #, c-format msgid "%s is not allowed in a non-volatile function" msgstr "%s 在一个 non-valatile 函数中是ä¸å…许的" -#: executor/functions.c:643 +#: executor/functions.c:656 #, c-format -msgid "" -"could not determine actual result type for function declared to return type " -"%s" +msgid "could not determine actual result type for function declared to return type %s" msgstr "无法确定实际结果类型为函数声明返回类型 %s" -#: executor/functions.c:1408 +#: executor/functions.c:1407 #, c-format msgid "SQL function \"%s\" statement %d" msgstr "SQL 函数 \"%s\" è¯­å¥ %d" -#: executor/functions.c:1434 +#: executor/functions.c:1433 #, c-format msgid "SQL function \"%s\" during startup" msgstr "SQL 函数 \"%s\" 在å¯åŠ¨çš„æ—¶å€™" -#: executor/functions.c:1593 executor/functions.c:1630 -#: executor/functions.c:1642 executor/functions.c:1755 -#: executor/functions.c:1788 executor/functions.c:1818 +#: executor/functions.c:1526 +#, c-format +msgid "calling procedures with output arguments is not supported in SQL functions" +msgstr "SQLå‡½æ•°ä¸­ä¸æ”¯æŒä½¿ç”¨è¾“å‡ºå‚æ•°è°ƒç”¨è¿‡ç¨‹" + +#: executor/functions.c:1646 executor/functions.c:1679 +#: executor/functions.c:1691 executor/functions.c:1826 +#: executor/functions.c:1859 executor/functions.c:1889 #, c-format msgid "return type mismatch in function declared to return %s" msgstr "函数返回类型和声明类型 %s ä¸åŒ¹é…" -#: executor/functions.c:1595 +#: executor/functions.c:1648 #, c-format -msgid "" -"Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." +msgid "Function's final statement must be SELECT or INSERT/UPDATE/DELETE RETURNING." msgstr "函数的最åŽè¯­å¥å¿…须是 SELECT 或 INSERT/UPDATE/DELETE RETURNING." -#: executor/functions.c:1632 +#: executor/functions.c:1681 #, c-format msgid "Final statement must return exactly one column." msgstr "最终的语å¥å¿…须返回一列." -#: executor/functions.c:1644 +#: executor/functions.c:1693 #, c-format msgid "Actual return type is %s." msgstr "实际返回类型是 %s." -#: executor/functions.c:1757 +#: executor/functions.c:1828 #, c-format msgid "Final statement returns too many columns." msgstr "最终的语å¥çš„返回列太多." -#: executor/functions.c:1790 +#: executor/functions.c:1861 #, c-format msgid "Final statement returns %s instead of %s at column %d." msgstr "最终语å¥åœ¨ç¬¬ %3$d 列返回 %1$s è€Œä¸æ˜¯ %2$s" -#: executor/functions.c:1820 +#: executor/functions.c:1891 #, c-format msgid "Final statement returns too few columns." msgstr "最终的语å¥è¿”回的列太少." -#: executor/functions.c:1869 +#: executor/functions.c:1945 #, c-format msgid "return type %s is not supported for SQL functions" msgstr "SQL å‡½æ•°ä¸æ”¯æŒè¿”回类型 %s" -#: executor/nodeAgg.c:3011 +#: executor/nodeAgg.c:2825 parser/parse_agg.c:655 parser/parse_agg.c:685 #, c-format -#| msgid "final function with extra arguments must not be declared STRICT" -msgid "combine function for aggregate %u must to be declared as strict" -msgstr "èšé›† %u 的组åˆå‡½æ•°å¿…须被声明为严格" +msgid "aggregate function calls cannot be nested" +msgstr "ä¸å…许嵌套调用èšåˆå‡½æ•°" -#: executor/nodeAgg.c:3055 executor/nodeWindowAgg.c:2289 +#: executor/nodeAgg.c:3030 executor/nodeWindowAgg.c:2835 #, c-format msgid "aggregate %u needs to have compatible input type and transition type" msgstr "èšé›† %u éœ€è¦æœ‰å…¼å®¹çš„输入类型和转æ¢ç±»åž‹" -#: executor/nodeAgg.c:3127 parser/parse_agg.c:597 parser/parse_agg.c:627 -#, c-format -msgid "aggregate function calls cannot be nested" -msgstr "ä¸å…许嵌套调用èšåˆå‡½æ•°" - -#: executor/nodeCustom.c:148 executor/nodeCustom.c:159 +#: executor/nodeCustom.c:146 executor/nodeCustom.c:157 #, c-format -#| msgid "custom-scan \"%s\" does not support MarkPos" msgid "custom scan \"%s\" does not support MarkPos" msgstr "自定义扫æ \"%s\" 䏿”¯æŒ MarkPos" -#: executor/nodeHashjoin.c:823 executor/nodeHashjoin.c:853 +#: executor/nodeHashjoin.c:1059 executor/nodeHashjoin.c:1089 #, c-format msgid "could not rewind hash-join temporary file: %m" msgstr "无法å·å›ž (rewind) æ•£åˆ—è”æŽ¥ (hash-join) 临时文件: %m" -#: executor/nodeHashjoin.c:888 executor/nodeHashjoin.c:894 +#: executor/nodeHashjoin.c:1248 executor/nodeHashjoin.c:1254 #, c-format msgid "could not write to hash-join temporary file: %m" msgstr "æ— æ³•å†™å…¥æ•£åˆ—è”æŽ¥ (hash-join) 临时文件: %m" -#: executor/nodeHashjoin.c:928 executor/nodeHashjoin.c:938 +#: executor/nodeHashjoin.c:1295 executor/nodeHashjoin.c:1305 #, c-format msgid "could not read from hash-join temporary file: %m" msgstr "æ— æ³•ä»Žæ•£åˆ—è”æŽ¥ (hash-join) 临时文件读å–: %m" -#: executor/nodeIndexonlyscan.c:179 +#: executor/nodeIndexonlyscan.c:242 #, c-format msgid "lossy distance functions are not supported in index-only scans" msgstr "在åªç”¨ç´¢å¼•扫æä¸­ä¸æ”¯æŒæœ‰æŸè·ç¦»å‡½æ•°" -#: executor/nodeLimit.c:253 +#: executor/nodeLimit.c:264 #, c-format msgid "OFFSET must not be negative" msgstr "OFFSETåŽçš„值ä¸èƒ½æ˜¯è´Ÿæ•°" -#: executor/nodeLimit.c:280 +#: executor/nodeLimit.c:290 #, c-format msgid "LIMIT must not be negative" msgstr "LIMITåŽçš„值ä¸èƒ½ä¸ºè´Ÿæ•°" -#: executor/nodeMergejoin.c:1584 +#: executor/nodeMergejoin.c:1570 #, c-format msgid "RIGHT JOIN is only supported with merge-joinable join conditions" msgstr "RIGHT JOIN åªæ”¯æŒå¯åˆå¹¶è”结æ¡ä»¶" -#: executor/nodeMergejoin.c:1604 +#: executor/nodeMergejoin.c:1588 #, c-format msgid "FULL JOIN is only supported with merge-joinable join conditions" msgstr "åªæœ‰åœ¨åˆå¹¶è¿žæŽ¥æŸ¥è¯¢æ¡ä»¶ä¸­æ‰æ”¯æŒFULL JOIN" -#: executor/nodeModifyTable.c:96 +#: executor/nodeModifyTable.c:110 #, c-format msgid "Query has too many columns." msgstr "查询中的列太多了" -#: executor/nodeModifyTable.c:123 +#: executor/nodeModifyTable.c:138 #, c-format msgid "Query provides a value for a dropped column at ordinal position %d." msgstr "在顺åºä½ç½®%d上查询为已删除的列æä¾›äº†ä¸€ä¸ªå€¼" -#: executor/nodeModifyTable.c:131 +#: executor/nodeModifyTable.c:146 #, c-format msgid "Query has too few columns." msgstr "查询中的列太少了" -#: executor/nodeModifyTable.c:1117 +#: executor/nodeModifyTable.c:808 executor/nodeModifyTable.c:883 +#, fuzzy, c-format +#| msgid "tuple to be updated was already modified by an operation triggered by the current command" +msgid "tuple to be deleted was already modified by an operation triggered by the current command" +msgstr "待更新元组值已ç»è¢«å½“å‰å‘½ä»¤è§¦å‘çš„æ“作修改了" + +#: executor/nodeModifyTable.c:1190 +#, c-format +msgid "invalid ON UPDATE specification" +msgstr "无效的ON UPDATE规范" + +#: executor/nodeModifyTable.c:1191 +#, c-format +msgid "The result tuple would appear in a different partition than the original tuple." +msgstr "结果元组将出现在与原始元组ä¸åŒçš„分区中" + +#: executor/nodeModifyTable.c:1564 #, c-format msgid "ON CONFLICT DO UPDATE command cannot affect row a second time" msgstr "ON CONFLICT DO UPDATEå‘½ä»¤æ— æ³•å†æ¬¡å½±å“行" -#: executor/nodeModifyTable.c:1118 +#: executor/nodeModifyTable.c:1565 #, c-format -msgid "" -"Ensure that no rows proposed for insertion within the same command have " -"duplicate constrained values." +msgid "Ensure that no rows proposed for insertion within the same command have duplicate constrained values." msgstr "ç¡®ä¿åœ¨å…·æœ‰é‡å¤å—约æŸå€¼çš„åŒä¸€ä¸ªå‘½ä»¤ä¸­ä¸ä¼šæ’入行。" -#: executor/nodeSamplescan.c:307 +#: executor/nodeSamplescan.c:259 #, c-format msgid "TABLESAMPLE parameter cannot be null" msgstr "TABLESAMPLE傿•°ä¸èƒ½ä¸ºç©ºå€¼" -#: executor/nodeSamplescan.c:320 +#: executor/nodeSamplescan.c:271 #, c-format msgid "TABLESAMPLE REPEATABLE parameter cannot be null" msgstr "TABLESAMPLE REPEATABLE傿•°ä¸èƒ½ä¸ºnull" -#: executor/nodeSubplan.c:345 executor/nodeSubplan.c:384 -#: executor/nodeSubplan.c:1040 +#: executor/nodeSubplan.c:347 executor/nodeSubplan.c:386 +#: executor/nodeSubplan.c:1147 #, c-format msgid "more than one row returned by a subquery used as an expression" msgstr "作为一个表达å¼ä½¿ç”¨çš„å­æŸ¥è¯¢è¿”回了多列" -#: executor/nodeWindowAgg.c:353 +#: executor/nodeTableFuncscan.c:378 +#, c-format +msgid "namespace URI must not be null" +msgstr "命å空间URIä¸èƒ½ä¸ºç©º" + +#: executor/nodeTableFuncscan.c:392 +#, c-format +msgid "row filter expression must not be null" +msgstr "行筛选表达å¼ä¸èƒ½ä¸ºç©º" + +#: executor/nodeTableFuncscan.c:418 +#, c-format +msgid "column filter expression must not be null" +msgstr "列筛选器表达å¼ä¸èƒ½ä¸ºç©º" + +#: executor/nodeTableFuncscan.c:419 +#, c-format +msgid "Filter for column \"%s\" is null." +msgstr "列\"%s\"的筛选器为空." + +#: executor/nodeTableFuncscan.c:509 +#, c-format +msgid "null is not allowed in column \"%s\"" +msgstr "列\"%s\"中ä¸å…许为空" + +#: executor/nodeWindowAgg.c:354 #, c-format msgid "moving-aggregate transition function must not return null" msgstr "移动èšåˆè½¬æ¢å‡½æ•°ä¸èƒ½è¿”回null值" -#: executor/nodeWindowAgg.c:1609 +#: executor/nodeWindowAgg.c:2057 #, c-format msgid "frame starting offset must not be null" msgstr "框架(frame)çš„å¯åЍåç§»é‡ä¸èƒ½ä¸ºç©º" -#: executor/nodeWindowAgg.c:1622 +#: executor/nodeWindowAgg.c:2070 #, c-format msgid "frame starting offset must not be negative" msgstr "框架(frame)çš„å¯åЍåç§»é‡ä¸èƒ½ä¸ºè´Ÿæ•°" -#: executor/nodeWindowAgg.c:1635 +#: executor/nodeWindowAgg.c:2082 #, c-format msgid "frame ending offset must not be null" msgstr "框架(frame)的结æŸåç§»é‡ä¸èƒ½ä¸ºç©º" -#: executor/nodeWindowAgg.c:1648 +#: executor/nodeWindowAgg.c:2095 #, c-format msgid "frame ending offset must not be negative" msgstr "框架(frame)的结æŸåç§»é‡ä¸èƒ½ä¸ºè´Ÿæ•°" -#: executor/spi.c:214 +#: executor/nodeWindowAgg.c:2751 +#, c-format +msgid "aggregate function %s does not support use as a window function" +msgstr "èšåˆå‡½æ•°%s䏿”¯æŒç”¨ä½œçª—å£å‡½æ•°" + +#: executor/spi.c:228 executor/spi.c:297 +#, c-format +msgid "invalid transaction termination" +msgstr "无效交易终止" + +#: executor/spi.c:242 +#, c-format +msgid "cannot commit while a subtransaction is active" +msgstr "å­äº‹åŠ¡å¤„äºŽæ´»åŠ¨çŠ¶æ€æ—¶æ— æ³•æäº¤" + +#: executor/spi.c:303 +#, c-format +msgid "cannot roll back while a subtransaction is active" +msgstr "å­äº‹åŠ¡å¤„äºŽæ´»åŠ¨çŠ¶æ€æ—¶æ— æ³•回滚" + +#: executor/spi.c:372 #, c-format msgid "transaction left non-empty SPI stack" msgstr "事物剩下éžç©ºçš„ SPI æ ˆ" -#: executor/spi.c:215 executor/spi.c:279 +#: executor/spi.c:373 executor/spi.c:435 #, c-format msgid "Check for missing \"SPI_finish\" calls." msgstr "检查是å¦ç¼ºå°‘ \"SPI_finish\" 调用." -#: executor/spi.c:278 +#: executor/spi.c:434 #, c-format msgid "subtransaction left non-empty SPI stack" msgstr "å­äº‹ç‰©å‰©ä¸‹éžç©ºçš„ SPI æ ˆ" -#: executor/spi.c:1229 +#: executor/spi.c:1335 #, c-format msgid "cannot open multi-query plan as cursor" msgstr "æ— æ³•ä½œä¸ºæ¸¸æ ‡æ‰“å¼€å¤šæ¡æŸ¥è¯¢è§„划" #. translator: %s is name of a SQL command, eg INSERT -#: executor/spi.c:1234 +#: executor/spi.c:1340 #, c-format msgid "cannot open %s query as cursor" msgstr "æ— æ³•ä»¥æ¸¸æ ‡çš„å½¢å¼æ‰“开查询%s" -#: executor/spi.c:1342 +#: executor/spi.c:1445 #, c-format msgid "DECLARE SCROLL CURSOR ... FOR UPDATE/SHARE is not supported" msgstr "䏿”¯æŒDECLARE SCROLL CURSOR ... FOR UPDATE/SHARE " -#: executor/spi.c:1343 parser/analyze.c:2292 +#: executor/spi.c:1446 parser/analyze.c:2493 #, c-format msgid "Scrollable cursors must be READ ONLY." msgstr "坿»šåŠ¨æ¸¸æ ‡å¿…é¡»ä¸ºåªè¯»." -#: executor/spi.c:2459 +#: executor/spi.c:2570 #, c-format msgid "SQL statement \"%s\"" msgstr "SQL è¯­å¥ \"%s\"" -#: foreign/foreign.c:314 +#: executor/tqueue.c:74 +#, c-format +msgid "could not send tuple to shared-memory queue" +msgstr "无法将元组å‘é€åˆ°å…±äº«å†…存队列" + +#: foreign/foreign.c:220 #, c-format msgid "user mapping not found for \"%s\"" msgstr "没有找到对于\"%s\"的用户映射" -#: foreign/foreign.c:750 +#: foreign/foreign.c:672 #, c-format msgid "invalid option \"%s\"" msgstr "无效选项 \"%s\"" -#: foreign/foreign.c:751 +#: foreign/foreign.c:673 #, c-format msgid "Valid options in this context are: %s" msgstr "这个环境中有效选项是:%s" -#: gram.y:1004 -#, c-format -msgid "unrecognized role option \"%s\"" -msgstr "无法识别的角色选项\"%s\"" - -#: gram.y:1280 gram.y:1295 -#, c-format -msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" -msgstr "CREATE SCHEMA IF NOT EXISTSä¸èƒ½åŒ…嫿–¹æ¡ˆ(schema)元素" - -#: gram.y:1440 -#, c-format -msgid "current database cannot be changed" -msgstr "ä¸èƒ½æ”¹å˜å½“å‰ä½¿ç”¨çš„æ•°æ®åº“" - -#: gram.y:1564 -#, c-format -msgid "time zone interval must be HOUR or HOUR TO MINUTE" -msgstr "时区间隔必须为 HOUR 或者 HOUR TO MINUTE" - -#: gram.y:2602 gram.y:2631 -#, c-format -msgid "STDIN/STDOUT not allowed with PROGRAM" -msgstr "STDIN/STDOUT ä¸å…许与PROGRAM一起使用" - -#: gram.y:2897 gram.y:2904 gram.y:10275 gram.y:10283 -#, c-format -msgid "GLOBAL is deprecated in temporary table creation" -msgstr "GLOBAL在临时表中的创建中已ç»è¢«åºŸå¼ƒä½¿ç”¨" - -#: gram.y:3345 utils/adt/ri_triggers.c:316 utils/adt/ri_triggers.c:373 -#: utils/adt/ri_triggers.c:792 utils/adt/ri_triggers.c:1015 -#: utils/adt/ri_triggers.c:1171 utils/adt/ri_triggers.c:1352 -#: utils/adt/ri_triggers.c:1517 utils/adt/ri_triggers.c:1693 -#: utils/adt/ri_triggers.c:1873 utils/adt/ri_triggers.c:2064 -#: utils/adt/ri_triggers.c:2122 utils/adt/ri_triggers.c:2227 -#: utils/adt/ri_triggers.c:2404 -#, c-format -msgid "MATCH PARTIAL not yet implemented" -msgstr "MATCH PARTIAL 仿œªå®žçް" - -#: gram.y:4800 -msgid "duplicate trigger events specified" -msgstr "é‡å¤æŒ‡å®šè§¦å‘器事件" - -#: gram.y:4893 parser/parse_utilcmd.c:2741 parser/parse_utilcmd.c:2767 -#, c-format -msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" -msgstr "约æŸå£°æ˜Ž INITIALLY DEFERRED 必须为 DEFERRABLE" - -#: gram.y:4900 -#, c-format -msgid "conflicting constraint properties" -msgstr "约æŸå±žæ€§å†²çª" - -#: gram.y:5032 -#, c-format -msgid "CREATE ASSERTION is not yet implemented" -msgstr "CREATE ASSERTION 仿œªå®žçް" - -#: gram.y:5048 -#, c-format -msgid "DROP ASSERTION is not yet implemented" -msgstr "DROP ASSERTION 仿œªå®žçް" - -#: gram.y:5394 -#, c-format -msgid "RECHECK is no longer required" -msgstr "ä¸å†éœ€è¦RECHECK选项了" - -# describe.c:289 -#: gram.y:5395 -#, c-format -msgid "Update your data type." -msgstr "更改您的数æ®ç±»åž‹" - -#: gram.y:6973 -#, c-format -msgid "aggregates cannot have output arguments" -msgstr "èšåˆå‡½æ•°ä¸èƒ½ä½¿ç”¨è¾“å‡ºå‚æ•°" - -#: gram.y:7292 utils/adt/regproc.c:774 utils/adt/regproc.c:815 -#, c-format -msgid "missing argument" -msgstr "ç¼ºå°‘å‚æ•°" - -#: gram.y:7293 utils/adt/regproc.c:775 utils/adt/regproc.c:816 -#, c-format -msgid "Use NONE to denote the missing argument of a unary operator." -msgstr "使用 NONE 表示一元æ“ä½œç¬¦ç¼ºå°‘çš„å‚æ•°." - -#: gram.y:8843 gram.y:8861 -#, c-format -msgid "WITH CHECK OPTION not supported on recursive views" -msgstr "递归视图ä¸èƒ½ä½¿ç”¨WITH CHECK OPTION" - -#: gram.y:9867 parser/parse_expr.c:1468 -#, c-format -msgid "number of columns does not match number of values" -msgstr "列的数é‡ä¸Žå€¼çš„æ•°é‡ä¸åŒ¹é…" - -#: gram.y:10383 -#, c-format -msgid "LIMIT #,# syntax is not supported" -msgstr "䏿”¯æŒ LIMIT #,# 语法" - -#: gram.y:10384 -#, c-format -msgid "Use separate LIMIT and OFFSET clauses." -msgstr "LIMITå’ŒOFFSETå­å¥è¦åˆ†éš”å¼€" - -#: gram.y:10647 gram.y:10672 -#, c-format -msgid "VALUES in FROM must have an alias" -msgstr "FROM中的VALUESå­å¥å¿…须有一个别å" - -#: gram.y:10648 gram.y:10673 -#, c-format -msgid "For example, FROM (VALUES ...) [AS] foo." -msgstr "例如, FROM (SELECT ...) [AS] foo." - -#: gram.y:10653 gram.y:10678 -#, c-format -msgid "subquery in FROM must have an alias" -msgstr "FROM ä¸­çš„å­æŸ¥è¯¢å¿…须有一个别å" - -#: gram.y:10654 gram.y:10679 -#, c-format -msgid "For example, FROM (SELECT ...) [AS] foo." -msgstr "例如, FROM (SELECT ...) [AS] foo." - -#: gram.y:11253 -#, c-format -msgid "precision for type float must be at least 1 bit" -msgstr "浮点类型的精确度必须至少 1 ä½" - -#: gram.y:11262 -#, c-format -msgid "precision for type float must be less than 54 bits" -msgstr "浮点类型的精确度必须å°äºŽ 54 ä½" - -#: gram.y:11766 -#, c-format -msgid "wrong number of parameters on left side of OVERLAPS expression" -msgstr "OVERLAPS 表达å¼å·¦è¾¹çš„傿•°ä¸ªæ•°ä¸å¯¹" - -#: gram.y:11771 -#, c-format -msgid "wrong number of parameters on right side of OVERLAPS expression" -msgstr "OVERLAPS 表达å¼å³è¾¹çš„傿•°ä¸ªæ•°ä¸å¯¹" - -#: gram.y:11948 -#, c-format -msgid "UNIQUE predicate is not yet implemented" -msgstr "没有实现UNIQUEè°“è¯" - -#: gram.y:12280 -#, c-format -msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" -msgstr "WITHIN GROUPä¸å…许多个 ORDER BY å­å¥" - -#: gram.y:12285 -#, c-format -msgid "cannot use DISTINCT with WITHIN GROUP" -msgstr "ä¸èƒ½å°† DISTINCT å’Œ WITHIN GROUP混在一起使用" - -#: gram.y:12290 -#, c-format -msgid "cannot use VARIADIC with WITHIN GROUP" -msgstr "ä¸èƒ½å°† VARIADIC å’Œ WITHIN GROUP在一起混用" - -#: gram.y:12796 -#, c-format -msgid "RANGE PRECEDING is only supported with UNBOUNDED" -msgstr "UNBOUNDED䏿”¯æŒRANGE PRECEDING" - -#: gram.y:12802 -#, c-format -msgid "RANGE FOLLOWING is only supported with UNBOUNDED" -msgstr "UNBOUNDED䏿”¯æŒRANGE FOLLOWING" - -#: gram.y:12829 gram.y:12852 -#, c-format -msgid "frame start cannot be UNBOUNDED FOLLOWING" -msgstr "框架的起始ä½ç½®ä¸èƒ½è¢«æ‰§è¡ŒUNBOUNDED FOLLOWINGæ“作." - -#: gram.y:12834 -#, c-format -msgid "frame starting from following row cannot end with current row" -msgstr "从åŽé¢è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½ä»¥å½“å‰è®°å½•结æŸ" - -#: gram.y:12857 +#: jit/jit.c:208 utils/fmgr/dfmgr.c:209 utils/fmgr/dfmgr.c:426 +#: utils/fmgr/dfmgr.c:474 #, c-format -msgid "frame end cannot be UNBOUNDED PRECEDING" -msgstr "框架的结æŸä½ç½®ä¸èƒ½è¢«æ‰§è¡ŒUNBOUNDED FOLLOWINGæ“作." +msgid "could not access file \"%s\": %m" +msgstr "无法访问文件 \"%s\": %m" -#: gram.y:12863 +#: jit/llvm/llvmjit.c:601 #, c-format -msgid "frame starting from current row cannot have preceding rows" -msgstr "从当å‰è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½æ‹¥æœ‰æ­£åœ¨å¤„ç†çš„记录" +msgid "time to inline: %.3fs, opt: %.3fs, emit: %.3fs" +msgstr "在线时间: %.3fs, 选项: %.3fs, å‘出: %.3fs" -#: gram.y:12870 +#: lib/dshash.c:247 utils/mmgr/dsa.c:702 utils/mmgr/dsa.c:724 +#: utils/mmgr/dsa.c:805 #, c-format -msgid "frame starting from following row cannot have preceding rows" -msgstr "从åŽé¢è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½æ‹¥æœ‰æ­£åœ¨å¤„ç†çš„记录" +msgid "Failed on DSA request of size %zu." +msgstr "在大å°ä¸º%zuçš„DSA请求时失败." -#: gram.y:13535 +#: lib/stringinfo.c:284 #, c-format -msgid "type modifier cannot have parameter name" -msgstr "类型修改器ä¸èƒ½æœ‰å‚æ•°åç§°" +msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." +msgstr "无法为包å«%d字节的字符串缓冲区扩大%d个更多字节." -#: gram.y:13541 +#: libpq/auth-scram.c:248 #, c-format -msgid "type modifier cannot have ORDER BY" -msgstr "类型修改器ä¸èƒ½æœ‰ORDER BY" +msgid "client selected an invalid SASL authentication mechanism" +msgstr "客户端选择了无效的SASLèº«ä»½éªŒè¯æœºåˆ¶" -#: gram.y:13605 gram.y:13611 +#: libpq/auth-scram.c:269 libpq/auth-scram.c:509 libpq/auth-scram.c:518 #, c-format -msgid "%s cannot be used as a role name here" -msgstr "在这里%sä¸èƒ½è¢«ç”¨åšä¸€ä¸ªè§’色å" - -#: gram.y:14233 gram.y:14422 -msgid "improper use of \"*\"" -msgstr "对\"*\"çš„ä½¿ç”¨ä¸æ­£ç¡®" +msgid "invalid SCRAM verifier for user \"%s\"" +msgstr "用户\"%s\"çš„SCRAM验è¯ç¨‹åºæ— æ•ˆ" -#: gram.y:14385 gram.y:14402 tsearch/spell.c:954 tsearch/spell.c:971 -#: tsearch/spell.c:988 tsearch/spell.c:1005 tsearch/spell.c:1070 +#: libpq/auth-scram.c:280 #, c-format -msgid "syntax error" -msgstr "语法错误" +msgid "User \"%s\" does not have a valid SCRAM verifier." +msgstr "用户\"%s\"没有有效的SCRAM验è¯å™¨." -#: gram.y:14486 +#: libpq/auth-scram.c:358 libpq/auth-scram.c:363 libpq/auth-scram.c:657 +#: libpq/auth-scram.c:665 libpq/auth-scram.c:776 libpq/auth-scram.c:786 +#: libpq/auth-scram.c:894 libpq/auth-scram.c:901 libpq/auth-scram.c:916 +#: libpq/auth-scram.c:931 libpq/auth-scram.c:945 libpq/auth-scram.c:963 +#: libpq/auth-scram.c:978 libpq/auth-scram.c:1264 libpq/auth-scram.c:1272 #, c-format -msgid "" -"an ordered-set aggregate with a VARIADIC direct argument must have one " -"VARIADIC aggregated argument of the same data type" -msgstr "带å¯å˜ç›´æŽ¥å‚数的有åºé›†èšé›†å‡½æ•°å¿…须有一个 相åŒç±»åž‹çš„VARIADIC èšé›†å‚æ•° " +msgid "malformed SCRAM message" +msgstr "异常的SCRAM消æ¯" -#: gram.y:14523 +#: libpq/auth-scram.c:359 #, c-format -msgid "multiple ORDER BY clauses not allowed" -msgstr "ä¸å…许多个 ORDER BY å­å¥" +msgid "The message is empty." +msgstr "消æ¯ä¸ºç©º." -#: gram.y:14534 +#: libpq/auth-scram.c:364 #, c-format -msgid "multiple OFFSET clauses not allowed" -msgstr "ä¸å…许多个 OFFSET å­å¥" +msgid "Message length does not match input length." +msgstr "消æ¯é•¿åº¦ä¸Žè¾“入长度ä¸åŒ¹é…." -#: gram.y:14543 +#: libpq/auth-scram.c:396 #, c-format -msgid "multiple LIMIT clauses not allowed" -msgstr "ä¸å…许多个 LIMIT å­å¥" +msgid "invalid SCRAM response" +msgstr "无效的SCRAMå“应" -#: gram.y:14552 +#: libpq/auth-scram.c:397 #, c-format -msgid "multiple WITH clauses not allowed" -msgstr "ä¸å…许使用多个WITHå­å¥" +msgid "Nonce does not match." +msgstr "Nonceä¸åŒ¹é…." -#: gram.y:14732 +#: libpq/auth-scram.c:471 #, c-format -msgid "OUT and INOUT arguments aren't allowed in TABLE functions" -msgstr "在TABLE函数中ä¸å…许使用OUT或INOUT模å¼çš„傿•°" +msgid "could not generate random salt" +msgstr "无法生æˆéšæœºsalt" -#: gram.y:14833 +#: libpq/auth-scram.c:658 #, c-format -msgid "multiple COLLATE clauses not allowed" -msgstr "ä¸å…许多个 COLLATE å­å¥" +msgid "Expected attribute \"%c\" but found \"%s\"." +msgstr "预期属性\"%c\",但å‘现结果是\"%s\"." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14871 gram.y:14884 +#: libpq/auth-scram.c:666 libpq/auth-scram.c:787 #, c-format -msgid "%s constraints cannot be marked DEFERRABLE" -msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºDEFERRABLE" +msgid "Expected character \"=\" for attribute \"%c\"." +msgstr "属性\"%c\"需è¦å­—符\"=\"." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14897 +#: libpq/auth-scram.c:777 #, c-format -msgid "%s constraints cannot be marked NOT VALID" -msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºNOT VALID" +msgid "Attribute expected, but found invalid character \"%s\"." +msgstr "应输入属性,但å‘现无效字符\"%s\"." -#. translator: %s is CHECK, UNIQUE, or similar -#: gram.y:14910 +#: libpq/auth-scram.c:895 libpq/auth-scram.c:917 #, c-format -msgid "%s constraints cannot be marked NO INHERIT" -msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºNO INHERIT" +msgid "The client selected SCRAM-SHA-256-PLUS, but the SCRAM message does not include channel binding data." +msgstr "客户端选择了SCRAM-SHA-256-PLUS,但SCRAM消æ¯ä¸åŒ…括通é“绑定数æ®." -#: guc-file.l:315 +#: libpq/auth-scram.c:902 libpq/auth-scram.c:932 #, c-format -msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" -msgstr "未认å¯çš„é…ç½®å‚æ•° \"%s\", 文件\"%s\", 行%u" +msgid "Comma expected, but found character \"%s\"." +msgstr "应为逗å·ï¼Œä½†æ‰¾åˆ°äº†å­—符\"%s\"." -#: guc-file.l:352 utils/misc/guc.c:5893 utils/misc/guc.c:6085 -#: utils/misc/guc.c:6175 utils/misc/guc.c:6265 utils/misc/guc.c:6373 -#: utils/misc/guc.c:6468 +#: libpq/auth-scram.c:923 #, c-format -msgid "parameter \"%s\" cannot be changed without restarting the server" -msgstr "在没有å¯åЍæœåŠ¡å™¨çš„æƒ…å†µä¸‹ï¼Œä¸èƒ½æ”¹å˜å‚æ•° \"%s\" " +msgid "SCRAM channel binding negotiation error" +msgstr "SCRAM通é“绑定å商错误" -#: guc-file.l:388 +#: libpq/auth-scram.c:924 #, c-format -msgid "parameter \"%s\" removed from configuration file, reset to default" -msgstr "傿•°\"%s\"已从é…ç½®æ–‡ä»¶ä¸­åˆ é™¤ï¼Œé‡æ–°è®¾ç½®ä¸ºç¼ºçœ" +msgid "The client supports SCRAM channel binding but thinks the server does not. However, this server does support channel binding." +msgstr "客户端支æŒSCRAM通é“绑定,但认为æœåС噍䏿”¯æŒã€‚但是,此æœåŠ¡å™¨æ”¯æŒé€šé“绑定" -#: guc-file.l:454 +#: libpq/auth-scram.c:946 #, c-format -msgid "parameter \"%s\" changed to \"%s\"" -msgstr "傿•° \"%s\"被改为\"%s\"" +msgid "The client selected SCRAM-SHA-256 without channel binding, but the SCRAM message includes channel binding data." +msgstr "客户机选择的SCRAM-SHA-256没有通é“绑定,但SCRAM消æ¯åŒ…å«é€šé“绑定数æ®." -#: guc-file.l:496 +#: libpq/auth-scram.c:957 #, c-format -msgid "configuration file \"%s\" contains errors" -msgstr "é…置文件 \"%s\" 有错" +msgid "unsupported SCRAM channel-binding type \"%s\"" +msgstr "䏿”¯æŒçš„SCRAM通é“绑定类型\"%s\"" -#: guc-file.l:501 +#: libpq/auth-scram.c:964 #, c-format -msgid "" -"configuration file \"%s\" contains errors; unaffected changes were applied" -msgstr "é…置文件 \"%s\" 有错; 使用了ä¸å—å½±å“的内容å˜åЍ" +msgid "Unexpected channel-binding flag \"%s\"." +msgstr "æ„外的通é“绑定标志\"%s\"." -#: guc-file.l:506 +#: libpq/auth-scram.c:974 #, c-format -msgid "configuration file \"%s\" contains errors; no changes were applied" -msgstr "é…置文件 \"%s\" 有错; 没有内容å˜åЍ" +msgid "client uses authorization identity, but it is not supported" +msgstr "å®¢æˆ·ç«¯ä½¿ç”¨æŽˆæƒæ ‡è¯†ï¼Œä½†ä¸æ”¯æŒ" -#: guc-file.l:579 +#: libpq/auth-scram.c:979 #, c-format -msgid "" -"could not open configuration file \"%s\": maximum nesting depth exceeded" -msgstr "无法打开é…置文件 \"%s\": 已超过最大的嵌套深度" +msgid "Unexpected attribute \"%s\" in client-first-message." +msgstr "å®¢æˆ·ç«¯ç¬¬ä¸€æ¡æ¶ˆæ¯ä¸­çš„æ„å¤–å±žæ€§\"%s\"" -#: guc-file.l:595 libpq/hba.c:1808 +#: libpq/auth-scram.c:995 #, c-format -msgid "could not open configuration file \"%s\": %m" -msgstr "无法打开é…置文件 \"%s\": %m" +msgid "client requires an unsupported SCRAM extension" +msgstr "客户端需è¦ä¸æ”¯æŒçš„SCRAM扩展" -#: guc-file.l:606 +#: libpq/auth-scram.c:1009 #, c-format -msgid "skipping missing configuration file \"%s\"" -msgstr "忽略丢失的é…置文件\"%s\"" +msgid "non-printable characters in SCRAM nonce" +msgstr "SCRAM nonce中的ä¸å¯æ‰“å°å­—符" -#: guc-file.l:860 +#: libpq/auth-scram.c:1126 #, c-format -msgid "syntax error in file \"%s\" line %u, near end of line" -msgstr "在文件 \"%s\" 第 %u 行, 行尾附近语法错误" +msgid "could not generate random nonce" +msgstr "无法生æˆéšæœºçš„nonce" -#: guc-file.l:870 +#: libpq/auth-scram.c:1230 #, c-format -msgid "syntax error in file \"%s\" line %u, near token \"%s\"" -msgstr "在文件 \"%s\" 第 %u 行, è®°å· \"%s\" 附近语法错误" +msgid "SCRAM channel binding check failed" +msgstr "SCRAM通é“绑定检查失败" -#: guc-file.l:890 +#: libpq/auth-scram.c:1248 #, c-format -msgid "too many syntax errors found, abandoning file \"%s\"" -msgstr "å‘现太多的语法错误, 放弃文件 \"%s\"" +msgid "unexpected SCRAM channel-binding attribute in client-final-message" +msgstr "客户端最终消æ¯ä¸­çš„æ„å¤–SCRAM通é“绑定属性" -#: guc-file.l:942 +#: libpq/auth-scram.c:1265 #, c-format -msgid "could not open configuration directory \"%s\": %m" -msgstr "无法打开é…置文件目录 \"%s\": %m" +msgid "Malformed proof in client-final-message." +msgstr "客户端最终消æ¯ä¸­çš„è¯æ˜Žæ ¼å¼ä¸æ­£ç¡®." -#: lib/stringinfo.c:259 +#: libpq/auth-scram.c:1273 #, c-format -msgid "Cannot enlarge string buffer containing %d bytes by %d more bytes." -msgstr "无法为包å«%d字节的字符串缓冲区扩大%d个更多字节." +msgid "Garbage found at the end of client-final-message." +msgstr "åœ¨å®¢æˆ·ç«¯æœ€ç»ˆæ¶ˆæ¯æœ«å°¾å‘现垃圾" -#: libpq/auth.c:251 +#: libpq/auth.c:279 #, c-format msgid "authentication failed for user \"%s\": host rejected" msgstr "用户 \"%s\" 认è¯å¤±è´¥: 主机拒ç»" -#: libpq/auth.c:254 +#: libpq/auth.c:282 #, c-format msgid "\"trust\" authentication failed for user \"%s\"" msgstr "用户 \"%s\" \"trust\" 认è¯å¤±è´¥" -#: libpq/auth.c:257 +#: libpq/auth.c:285 #, c-format msgid "Ident authentication failed for user \"%s\"" msgstr "用户 \"%s\" Ident 认è¯å¤±è´¥" -#: libpq/auth.c:260 +#: libpq/auth.c:288 #, c-format msgid "Peer authentication failed for user \"%s\"" msgstr "对用户\"%s\"的对等认è¯å¤±è´¥" -#: libpq/auth.c:264 +#: libpq/auth.c:293 #, c-format msgid "password authentication failed for user \"%s\"" msgstr "用户 \"%s\" Password 认è¯å¤±è´¥" -#: libpq/auth.c:269 +#: libpq/auth.c:298 #, c-format msgid "GSSAPI authentication failed for user \"%s\"" msgstr "对于用户\"%s\"çš„GSSAPI 认è¯å¤±è´¥" -#: libpq/auth.c:272 +#: libpq/auth.c:301 #, c-format msgid "SSPI authentication failed for user \"%s\"" msgstr "对于用户 \"%s\" çš„ SSPI 认è¯å¤±è´¥" -#: libpq/auth.c:275 +#: libpq/auth.c:304 #, c-format msgid "PAM authentication failed for user \"%s\"" msgstr "用户 \"%s\" è®¤è¯ PAM 失败" -#: libpq/auth.c:278 +#: libpq/auth.c:307 #, c-format -#| msgid "SSPI authentication failed for user \"%s\"" msgid "BSD authentication failed for user \"%s\"" msgstr "对于用户 \"%s\" çš„ BSD 认è¯å¤±è´¥" -#: libpq/auth.c:281 +#: libpq/auth.c:310 #, c-format msgid "LDAP authentication failed for user \"%s\"" msgstr "对于用户 \"%s\"çš„LDAP认è¯å¤±è´¥" -#: libpq/auth.c:284 +#: libpq/auth.c:313 #, c-format msgid "certificate authentication failed for user \"%s\"" msgstr "用户 \"%s\" 的认è¯å¤±è´¥" -#: libpq/auth.c:287 +#: libpq/auth.c:316 #, c-format msgid "RADIUS authentication failed for user \"%s\"" msgstr "用户 \"%s\" çš„RADIUS认è¯å¤±è´¥" -#: libpq/auth.c:290 +#: libpq/auth.c:319 #, c-format msgid "authentication failed for user \"%s\": invalid authentication method" msgstr "用户 \"%s\" 认è¯å¤±è´¥: æ— æ•ˆçš„è®¤è¯æ–¹å¼" -#: libpq/auth.c:294 +#: libpq/auth.c:323 #, c-format msgid "Connection matched pg_hba.conf line %d: \"%s\"" msgstr "与Connection相匹é…的文件行ä½äºŽ pg_hba.conf %d: \"%s\"" -#: libpq/auth.c:349 +#: libpq/auth.c:370 +#, c-format +msgid "client certificates can only be checked if a root certificate store is available" +msgstr "åªæœ‰åœ¨æ ¹è®¤è¯æœ‰æ•ˆçš„æƒ…况下æ‰èƒ½æ£€æŸ¥å®¢æˆ·ç«¯è®¤è¯" + +#: libpq/auth.c:381 #, c-format msgid "connection requires a valid client certificate" msgstr "连接中需è¦ä¸€ä¸ªæœ‰æ•ˆçš„客户端认è¯" #: libpq/auth.c:391 #, c-format -msgid "" -"pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" +msgid "GSSAPI encryption can only be used with gss, trust, or reject authentication methods" +msgstr "" + +#: libpq/auth.c:425 +#, c-format +msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s" msgstr "pg_hba.confä¸­çš„è®°å½•æ‹’ç»æ¥è‡ªä¸»æœº\"%s\",用户 \"%s\",%sçš„å¤åˆ¶è¿žæŽ¥" -#: libpq/auth.c:393 libpq/auth.c:409 libpq/auth.c:467 libpq/auth.c:485 +#: libpq/auth.c:427 libpq/auth.c:443 libpq/auth.c:501 libpq/auth.c:519 msgid "SSL off" msgstr "SSL 关闭" -#: libpq/auth.c:393 libpq/auth.c:409 libpq/auth.c:467 libpq/auth.c:485 +#: libpq/auth.c:427 libpq/auth.c:443 libpq/auth.c:501 libpq/auth.c:519 msgid "SSL on" msgstr "SSL å¼€å¯" -#: libpq/auth.c:397 +#: libpq/auth.c:431 #, c-format msgid "pg_hba.conf rejects replication connection for host \"%s\", user \"%s\"" msgstr "pg_hba.conf è®°å½•æ‹’ç»æ¥è‡ªä¸»æœº\"%s\", 用户\"%s\"çš„å¤åˆ¶è¿žæŽ¥" -#: libpq/auth.c:406 +#: libpq/auth.c:440 #, c-format -msgid "" -"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s" -"\", %s" -msgstr "" -"pg_hba.conf è®°å½•æ‹’ç»æ¥è‡ªä¸»æœº\"%s\", 用户\"%s\", æ•°æ®åº“\"%s\", %sçš„å¤åˆ¶è¿žæŽ¥" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s" +msgstr "pg_hba.conf è®°å½•æ‹’ç»æ¥è‡ªä¸»æœº\"%s\", 用户\"%s\", æ•°æ®åº“\"%s\", %sçš„å¤åˆ¶è¿žæŽ¥" -#: libpq/auth.c:413 +#: libpq/auth.c:447 #, c-format -msgid "" -"pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" +msgid "pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\"" msgstr "pg_hba.conf è®°å½•æ‹’ç»æ¥è‡ªä¸»æœº\"%s\", 用户\"%s\", æ•°æ®åº“\"%s\"çš„å¤åˆ¶è¿žæŽ¥" -#: libpq/auth.c:442 +#: libpq/auth.c:476 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup matches." msgstr "客户端IP地å€è§£æžä¸º \"%s\", ä¸Žè½¬å‘æŸ¥æ‰¾ç»“果相匹é…." -#: libpq/auth.c:445 +#: libpq/auth.c:479 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup not checked." msgstr "客户端IP地å€è§£æžä¸º \"%s\", è½¬å‘æŸ¥æ‰¾ç»“果没有检查." -#: libpq/auth.c:448 +#: libpq/auth.c:482 #, c-format msgid "Client IP address resolved to \"%s\", forward lookup does not match." msgstr "客户端IP地å€è§£æžä¸º \"%s\", ä¸Žè½¬å‘æŸ¥æ‰¾ç»“æžœä¸åŒ¹é…." # fe-misc.c:702 -#: libpq/auth.c:451 +#: libpq/auth.c:485 #, c-format msgid "Could not translate client host name \"%s\" to IP address: %s." msgstr "无法解æžä¸»æœºå \"%s\" 对应的IP地å€: %s." # fe-connect.c:1283 -#: libpq/auth.c:456 +#: libpq/auth.c:490 #, c-format msgid "Could not resolve client IP address to a host name: %s." msgstr "无法解æžå®¢æˆ·ç«¯åœ°å€ä¸»æœºå: %s." -#: libpq/auth.c:465 +#: libpq/auth.c:499 #, c-format -msgid "" -"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s" -"\", %s" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s" msgstr "没有æ¥è‡ªä¸»æœº \"%s\", 用户\"%s\", %sçš„å¤åˆ¶è¿žæŽ¥çš„pg_hba.conf记录" -#: libpq/auth.c:472 +#: libpq/auth.c:506 #, c-format -msgid "" -"no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" +msgid "no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\"" msgstr "没有æ¥è‡ªä¸»æœº \"%s\", 用户\"%s\"çš„å¤åˆ¶è¿žæŽ¥çš„pg_hba.conf记录" -#: libpq/auth.c:482 +#: libpq/auth.c:516 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" -msgstr "" -"没有用于主机 \"%s\", 用户 \"%s\", æ•°æ®åº“ \"%s\", %s çš„ pg_hba.conf 记录" +msgstr "没有用于主机 \"%s\", 用户 \"%s\", æ•°æ®åº“ \"%s\", %s çš„ pg_hba.conf 记录" -#: libpq/auth.c:490 +#: libpq/auth.c:524 #, c-format msgid "no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"" msgstr "没有用于主机 \"%s\", 用户 \"%s\", æ•°æ®åº“ \"%s\" çš„ pg_hba.conf 记录" -#: libpq/auth.c:533 libpq/hba.c:1180 -#, c-format -msgid "" -"MD5 authentication is not supported when \"db_user_namespace\" is enabled" -msgstr "当å¯ç”¨ \"db_user_namespace\" æ—¶ä¸æ”¯æŒ MD5 认è¯" - -#: libpq/auth.c:667 +#: libpq/auth.c:691 #, c-format msgid "expected password response, got message type %d" msgstr "期望得到å£ä»¤å›žåº”,但是得到了消æ¯ç±»åž‹%d." -#: libpq/auth.c:695 +#: libpq/auth.c:719 #, c-format msgid "invalid password packet size" msgstr "无效的å£ä»¤åŒ…尺寸" -#: libpq/auth.c:825 +#: libpq/auth.c:737 +#, c-format +msgid "empty password returned by client" +msgstr "客户端返回了空å£ä»¤" + +#: libpq/auth.c:857 libpq/hba.c:1340 +#, c-format +msgid "MD5 authentication is not supported when \"db_user_namespace\" is enabled" +msgstr "当å¯ç”¨ \"db_user_namespace\" æ—¶ä¸æ”¯æŒ MD5 认è¯" + +#: libpq/auth.c:863 +#, c-format +msgid "could not generate random MD5 salt" +msgstr "无法生æˆéšæœºMD5" + +#: libpq/auth.c:909 +#, c-format +msgid "SASL authentication is not supported in protocol version 2" +msgstr "在å议版本2䏭䏿”¯æŒSASL身份验è¯" + +#: libpq/auth.c:942 +#, c-format +msgid "expected SASL response, got message type %d" +msgstr "期望SASL回应,但是得到了信æ¯ç±»åž‹%d" + +#: libpq/auth.c:1071 #, c-format msgid "GSSAPI is not supported in protocol version 2" msgstr "在å议版本2䏭䏿”¯æŒä½¿ç”¨GSSAPI" -#: libpq/auth.c:885 +#: libpq/auth.c:1131 #, c-format msgid "expected GSS response, got message type %d" msgstr "期望GSS回应,但是得到了信æ¯ç±»åž‹%d" -#: libpq/auth.c:946 +#: libpq/auth.c:1193 msgid "accepting GSS security context failed" msgstr "接收GSS安全环境失败" -#: libpq/auth.c:972 +#: libpq/auth.c:1232 msgid "retrieving GSS user name failed" msgstr "获å–GSS用户å失败" -#: libpq/auth.c:1091 +#: libpq/auth.c:1363 #, c-format msgid "SSPI is not supported in protocol version 2" msgstr "在å议版本2䏭䏿”¯æŒä½¿ç”¨SSPI" -#: libpq/auth.c:1106 +#: libpq/auth.c:1378 msgid "could not acquire SSPI credentials" msgstr "无法获得SSPIè¯ä¹¦" -#: libpq/auth.c:1124 +#: libpq/auth.c:1396 #, c-format msgid "expected SSPI response, got message type %d" msgstr "期望SSPI回应,但是得到了消æ¯ç±»åž‹%d" -#: libpq/auth.c:1196 +#: libpq/auth.c:1469 msgid "could not accept SSPI security context" msgstr "无法访问SSPI安全环境" -#: libpq/auth.c:1258 +#: libpq/auth.c:1531 msgid "could not get token from SSPI security context" msgstr "无法从SSPI安全环境中获å–令牌(token)" -#: libpq/auth.c:1377 libpq/auth.c:1396 +#: libpq/auth.c:1650 libpq/auth.c:1669 #, c-format -#| msgid "could not parse file name \"%s\"" msgid "could not translate name" msgstr "ä¸èƒ½ç¿»è¯‘åç§°" -#: libpq/auth.c:1409 +#: libpq/auth.c:1682 #, c-format -#| msgid "channel name too long" msgid "realm name too long" msgstr "realm å称太长" -#: libpq/auth.c:1424 +#: libpq/auth.c:1697 #, c-format -#| msgid "encoding name too long" msgid "translated account name too long" msgstr "翻译的账户å太长" -#: libpq/auth.c:1610 +#: libpq/auth.c:1883 #, c-format msgid "could not create socket for Ident connection: %m" msgstr "无法为 Ident è”æŽ¥åˆ›å»ºå¥—æŽ¥å­—: %m" -#: libpq/auth.c:1625 +#: libpq/auth.c:1898 #, c-format msgid "could not bind to local address \"%s\": %m" msgstr "æ— æ³•ç»‘å®šåˆ°æœ¬åœ°åœ°å€ \"%s\": %m" -#: libpq/auth.c:1637 +#: libpq/auth.c:1910 #, c-format msgid "could not connect to Ident server at address \"%s\", port %s: %m" msgstr "æ— æ³•è”æŽ¥åˆ°åœ°å€ä¸º \"%s\", 端å£ä¸º %s çš„ Ident æœåС噍: %m" -#: libpq/auth.c:1659 +#: libpq/auth.c:1932 #, c-format msgid "could not send query to Ident server at address \"%s\", port %s: %m" msgstr "无法å‘逿Ÿ¥è¯¢åˆ°åœ°å€ä¸º \"%s\", 端å£ä¸º %s çš„ Ident æœåС噍: %m" -#: libpq/auth.c:1676 +#: libpq/auth.c:1949 #, c-format -msgid "" -"could not receive response from Ident server at address \"%s\", port %s: %m" +msgid "could not receive response from Ident server at address \"%s\", port %s: %m" msgstr "无法从地å€ä¸º \"%s\", 端å£ä¸º %s çš„ Ident æœåŠ¡å™¨æŽ¥æ”¶åº”ç­”: %m" -#: libpq/auth.c:1686 +#: libpq/auth.c:1959 #, c-format msgid "invalidly formatted response from Ident server: \"%s\"" msgstr "从 Ident æœåŠ¡å™¨æŽ¥æ”¶çš„æ— æ•ˆæ ¼å¼åº”ç­”: \"%s\"" # fe-auth.c:640 -#: libpq/auth.c:1726 +#: libpq/auth.c:1999 #, c-format msgid "peer authentication is not supported on this platform" msgstr "对等认è¯åœ¨è¿™ä¸ªå¹³å°ä¸Šä¸æ”¯æŒ" -#: libpq/auth.c:1730 +#: libpq/auth.c:2003 #, c-format msgid "could not get peer credentials: %m" msgstr "无法获得åŒç­‰ (peer) è¯ä¹¦: %m" -#: libpq/auth.c:1739 +#: libpq/auth.c:2014 #, c-format msgid "could not look up local user ID %ld: %s" msgstr "无法查找本地用户ID %ld:%s" -#: libpq/auth.c:1823 libpq/auth.c:2149 libpq/auth.c:2509 -#, c-format -msgid "empty password returned by client" -msgstr "客户端返回了空å£ä»¤" - -#: libpq/auth.c:1833 +#: libpq/auth.c:2102 #, c-format msgid "error from underlying PAM layer: %s" msgstr "æ¥è‡ª PAM 层下é¢çš„错误: %s" -#: libpq/auth.c:1914 +#: libpq/auth.c:2171 #, c-format msgid "could not create PAM authenticator: %s" msgstr "无法创建 PAM 类型器: %s" -#: libpq/auth.c:1925 +#: libpq/auth.c:2182 #, c-format msgid "pam_set_item(PAM_USER) failed: %s" msgstr "pam_set_item(PAM_USER) 失败: %s" -#: libpq/auth.c:1936 +#: libpq/auth.c:2214 #, c-format -#| msgid "pam_set_item(PAM_USER) failed: %s" msgid "pam_set_item(PAM_RHOST) failed: %s" msgstr "pam_set_item(PAM_RHOST) 失败: %s" -#: libpq/auth.c:1947 +#: libpq/auth.c:2226 #, c-format msgid "pam_set_item(PAM_CONV) failed: %s" msgstr "pam_set_item(PAM_CONV) 失败: %s" -#: libpq/auth.c:1958 +#: libpq/auth.c:2237 #, c-format msgid "pam_authenticate failed: %s" msgstr "pam_authenticate 失败: %s" -#: libpq/auth.c:1969 +#: libpq/auth.c:2248 #, c-format msgid "pam_acct_mgmt failed: %s" msgstr "pam_acct_mgmt 失败: %s" -#: libpq/auth.c:1980 +#: libpq/auth.c:2259 #, c-format msgid "could not release PAM authenticator: %s" msgstr "无法释放 PAM 类型器: %s" -#: libpq/auth.c:2045 -#, c-format -msgid "could not initialize LDAP: %m" -msgstr "无法åˆå§‹åŒ–LDAP: %m" - -#: libpq/auth.c:2048 +#: libpq/auth.c:2335 #, c-format msgid "could not initialize LDAP: error code %d" msgstr "无法åˆå§‹åŒ–LDAP: 错误代ç %d" -#: libpq/auth.c:2058 +#: libpq/auth.c:2372 +#, fuzzy, c-format +#| msgid "could not receive data from client: %m" +msgid "could not extract domain name from ldapbasedn" +msgstr "无法从客户端获得数æ®: %m" + +#: libpq/auth.c:2380 +#, fuzzy, c-format +#| msgid "LDAP authentication failed for user \"%s\"" +msgid "LDAP authentication could not find DNS SRV records for \"%s\"" +msgstr "对于用户 \"%s\"çš„LDAP认è¯å¤±è´¥" + +#: libpq/auth.c:2382 +#, c-format +msgid "Set an LDAP server name explicitly." +msgstr "" + +#: libpq/auth.c:2434 +#, c-format +msgid "could not initialize LDAP: %s" +msgstr "无法åˆå§‹åŒ–LDAP: %s" + +#: libpq/auth.c:2444 +#, c-format +msgid "ldaps not supported with this LDAP library" +msgstr "æ­¤LDAPåº“ä¸æ”¯æŒldaps" + +#: libpq/auth.c:2452 +#, c-format +msgid "could not initialize LDAP: %m" +msgstr "无法åˆå§‹åŒ–LDAP: %m" + +#: libpq/auth.c:2462 #, c-format msgid "could not set LDAP protocol version: %s" msgstr "无法设置LDAPå议版本: %s" -#: libpq/auth.c:2087 +#: libpq/auth.c:2493 #, c-format msgid "could not load wldap32.dll" msgstr "无法加载wldap32.dll" -#: libpq/auth.c:2095 +#: libpq/auth.c:2501 #, c-format msgid "could not load function _ldap_start_tls_sA in wldap32.dll" msgstr "无法加载在wldap32.dll中的函数_ldap_start_tls_sA" -#: libpq/auth.c:2096 +#: libpq/auth.c:2502 #, c-format msgid "LDAP over SSL is not supported on this platform." msgstr "在此平å°ä¸Šä¸æ”¯æŒåœ¨SSL连接上的LDAP" -#: libpq/auth.c:2111 +#: libpq/auth.c:2517 #, c-format msgid "could not start LDAP TLS session: %s" msgstr "无法å¯åЍLDAP TLS会è¯: %s" -#: libpq/auth.c:2133 +#: libpq/auth.c:2588 +#, fuzzy, c-format +#| msgid "LDAP server not specified" +msgid "LDAP server not specified, and no ldapbasedn" +msgstr "没有指定LDAPæœåС噍" + +#: libpq/auth.c:2595 #, c-format msgid "LDAP server not specified" msgstr "没有指定LDAPæœåС噍" -#: libpq/auth.c:2186 +#: libpq/auth.c:2657 #, c-format msgid "invalid character in user name for LDAP authentication" msgstr "在需è¦è¿›è¡ŒLDAP认è¯çš„用户å中出现无效字符" -#: libpq/auth.c:2201 +#: libpq/auth.c:2674 #, c-format -msgid "" -"could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": " -"%s" +msgid "could not perform initial LDAP bind for ldapbinddn \"%s\" on server \"%s\": %s" msgstr "无法在æœåС噍\"%2$s\"上为ldapbinddn\"%1$s\"执行åˆå§‹åŒ–LDAP绑定: %3$s" -#: libpq/auth.c:2225 +#: libpq/auth.c:2703 #, c-format msgid "could not search LDAP for filter \"%s\" on server \"%s\": %s" msgstr "无法在æœåС噍\"%2$s\"上为过滤器\"%1$s\"进行的æœç´¢LDAP:%3$s" -#: libpq/auth.c:2236 +#: libpq/auth.c:2717 #, c-format msgid "LDAP user \"%s\" does not exist" msgstr "LDAP用户\"%s\" ä¸å­˜åœ¨" -#: libpq/auth.c:2237 +#: libpq/auth.c:2718 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned no entries." msgstr "在æœåС噍\"%2$s\"上为过滤器\"%1$s\"进行的LDAPæœç´¢æ— ç»“æžœ." -#: libpq/auth.c:2241 +#: libpq/auth.c:2722 #, c-format msgid "LDAP user \"%s\" is not unique" msgstr "LDAP用户\"%s\" 䏿˜¯å”¯ä¸€çš„" -#: libpq/auth.c:2242 +#: libpq/auth.c:2723 #, c-format msgid "LDAP search for filter \"%s\" on server \"%s\" returned %d entry." -msgid_plural "" -"LDAP search for filter \"%s\" on server \"%s\" returned %d entries." +msgid_plural "LDAP search for filter \"%s\" on server \"%s\" returned %d entries." msgstr[0] "在æœåС噍\"%2$s\"上为过滤器\"%1$s\"进行的LDAPæœç´¢è¿”回%3$dæ¡ç»“æžœ." -#: libpq/auth.c:2260 +#: libpq/auth.c:2743 #, c-format -msgid "" -"could not get dn for the first entry matching \"%s\" on server \"%s\": %s" +msgid "could not get dn for the first entry matching \"%s\" on server \"%s\": %s" msgstr "无法为在æœåС噍\"%2$s\"上第一个与\"%1$s\"匹é…的项获å–dn: %3$s" -#: libpq/auth.c:2280 +#: libpq/auth.c:2764 #, c-format -msgid "could not unbind after searching for user \"%s\" on server \"%s\": %s" -msgstr "在æœåС噍 \"%2$s\"上æœç´¢ç”¨æˆ·\"%1$s\"åŽæ— æ³•解除绑定:%3$s" +msgid "could not unbind after searching for user \"%s\" on server \"%s\"" +msgstr "在æœåС噍 \"%2$s\"上æœç´¢ç”¨æˆ·\"%1$s\"åŽæ— æ³•解除绑定" -#: libpq/auth.c:2310 +#: libpq/auth.c:2795 #, c-format msgid "LDAP login failed for user \"%s\" on server \"%s\": %s" msgstr "用户 \"%s\" 在æœåС噍 \"%s\" 进行LDAP登录失败:%s" -#: libpq/auth.c:2338 +#: libpq/auth.c:2824 #, c-format -msgid "" -"certificate authentication failed for user \"%s\": client certificate " -"contains no user name" +msgid "LDAP diagnostics: %s" +msgstr "LDAP诊断: %s" + +#: libpq/auth.c:2851 +#, c-format +msgid "certificate authentication failed for user \"%s\": client certificate contains no user name" msgstr "用户\"%s\"的认è¯é‰´æƒå¤±è´¥: å®¢æˆ·ç«¯è®¤è¯æ²¡æœ‰åŒ…å«ç”¨æˆ·å" -#: libpq/auth.c:2465 +#: libpq/auth.c:2868 +#, fuzzy, c-format +#| msgid "certificate authentication failed for user \"%s\"" +msgid "certificate validation (clientcert=verify-full) failed for user \"%s\": cn mismatch" +msgstr "用户 \"%s\" 的认è¯å¤±è´¥" + +#: libpq/auth.c:2969 #, c-format msgid "RADIUS server not specified" msgstr "没有指定RADIUSæœåС噍" -#: libpq/auth.c:2472 +#: libpq/auth.c:2976 #, c-format msgid "RADIUS secret not specified" msgstr "没有指定RADIUS机密(secret) " -#: libpq/auth.c:2488 libpq/hba.c:1634 +#: libpq/auth.c:2990 #, c-format -msgid "could not translate RADIUS server name \"%s\" to address: %s" -msgstr "无法将RADIUSæœåС噍åç§° \"%s\" 翻译为相应地å€:%s" +msgid "RADIUS authentication does not support passwords longer than %d characters" +msgstr "RADIUS 认è¯ä¸æ”¯æŒé•¿åº¦è¶…过 %d 个字符的å£ä»¤" -#: libpq/auth.c:2516 +#: libpq/auth.c:3095 libpq/hba.c:1954 #, c-format -#| msgid "" -#| "RADIUS authentication does not support passwords longer than 16 characters" -msgid "" -"RADIUS authentication does not support passwords longer than %d characters" -msgstr "RADIUS 认è¯ä¸æ”¯æŒé•¿åº¦è¶…过 %d 个字符的å£ä»¤" +msgid "could not translate RADIUS server name \"%s\" to address: %s" +msgstr "无法将RADIUSæœåС噍åç§° \"%s\" 翻译为相应地å€:%s" -#: libpq/auth.c:2528 +#: libpq/auth.c:3109 #, c-format msgid "could not generate random encryption vector" msgstr "æ— æ³•äº§ç”ŸéšæœºåР坆å‘é‡" -#: libpq/auth.c:2563 +#: libpq/auth.c:3143 #, c-format msgid "could not perform MD5 encryption of password" msgstr "无法执行å£ä»¤çš„MD5加密" -#: libpq/auth.c:2588 +#: libpq/auth.c:3169 #, c-format msgid "could not create RADIUS socket: %m" msgstr "无法创建RADIUS套接字: %m" -#: libpq/auth.c:2609 +#: libpq/auth.c:3191 #, c-format msgid "could not bind local RADIUS socket: %m" msgstr "无法绑定本地RADIUS套接字: %m" -#: libpq/auth.c:2619 +#: libpq/auth.c:3201 #, c-format msgid "could not send RADIUS packet: %m" msgstr "无法å‘é€RADIUS包: %m" -#: libpq/auth.c:2652 libpq/auth.c:2677 +#: libpq/auth.c:3234 libpq/auth.c:3260 #, c-format -msgid "timeout waiting for RADIUS response" -msgstr "在等待RADIUS回应包时超时" +msgid "timeout waiting for RADIUS response from %s" +msgstr "在等待自%sçš„RADIUS回应包时超时" -#: libpq/auth.c:2670 +#: libpq/auth.c:3253 #, c-format msgid "could not check status on RADIUS socket: %m" msgstr "无法在RADIUS套接字上检查状æ€: %m" -#: libpq/auth.c:2699 +#: libpq/auth.c:3283 #, c-format msgid "could not read RADIUS response: %m" msgstr "无法读å–RADIUS回应包: %m" -#: libpq/auth.c:2711 libpq/auth.c:2715 +#: libpq/auth.c:3296 libpq/auth.c:3300 #, c-format -msgid "RADIUS response was sent from incorrect port: %d" -msgstr "RADIUS回应数æ®åŒ…æ˜¯ä»Žä¸æ­£ç¡®çš„端å£ä¸­å‘出的: %d" +msgid "RADIUS response from %s was sent from incorrect port: %d" +msgstr "æ¥è‡ª%sçš„RADIUS回应数æ®åŒ…æ˜¯ä»Žä¸æ­£ç¡®çš„端å£ä¸­å‘出的: %d" -#: libpq/auth.c:2724 +#: libpq/auth.c:3309 #, c-format -msgid "RADIUS response too short: %d" -msgstr "RADIUS回应包的长度太短:%d" +msgid "RADIUS response from %s too short: %d" +msgstr "æ¥è‡ª%sçš„RADIUS回应包的长度太短:%d" -#: libpq/auth.c:2731 +#: libpq/auth.c:3316 #, c-format -msgid "RADIUS response has corrupt length: %d (actual length %d)" -msgstr "RADIUSå›žåº”åŒ…çš„é•¿åº¦ä¸æ­£ç¡®:%d(实际长度是%d)" +msgid "RADIUS response from %s has corrupt length: %d (actual length %d)" +msgstr "æ¥è‡ª%sçš„RADIUSå›žåº”åŒ…çš„é•¿åº¦ä¸æ­£ç¡®:%d(实际长度是%d)" -#: libpq/auth.c:2739 +#: libpq/auth.c:3324 #, c-format -msgid "RADIUS response is to a different request: %d (should be %d)" -msgstr "RADIUS回应包å‘é€åˆ°äº†ä¸€ä¸ªä¸åŒçš„请求上:%d (应该是%d)" +msgid "RADIUS response from %s is to a different request: %d (should be %d)" +msgstr "æ¥è‡ª%sçš„RADIUS回应包å‘é€åˆ°äº†ä¸€ä¸ªä¸åŒçš„请求上:%d (应该是%d)" -#: libpq/auth.c:2764 +#: libpq/auth.c:3349 #, c-format msgid "could not perform MD5 encryption of received packet" msgstr "无法执行所接收数æ®åŒ…çš„MD5加密" -#: libpq/auth.c:2773 +#: libpq/auth.c:3358 #, c-format -msgid "RADIUS response has incorrect MD5 signature" -msgstr "RADIUSå›žåº”åŒ…å¸¦æœ‰ä¸æ­£ç¡®çš„MD5ç­¾å" +msgid "RADIUS response from %s has incorrect MD5 signature" +msgstr "æ¥è‡ª%sçš„RADIUSå›žåº”åŒ…å¸¦æœ‰ä¸æ­£ç¡®çš„MD5ç­¾å" -#: libpq/auth.c:2790 +#: libpq/auth.c:3376 #, c-format -msgid "RADIUS response has invalid code (%d) for user \"%s\"" -msgstr "对于用户\"%2$s\"æ¥è¯´RADIUS回应包带有无效编ç (%1$d) " +msgid "RADIUS response from %s has invalid code (%d) for user \"%s\"" +msgstr "对于用户\"%3$s\"æ¥è¯´æ¥è‡ª%1$sçš„RADIUS回应包带有无效编ç (%2$d) " -#: libpq/be-fsstubs.c:134 libpq/be-fsstubs.c:165 libpq/be-fsstubs.c:199 -#: libpq/be-fsstubs.c:239 libpq/be-fsstubs.c:264 libpq/be-fsstubs.c:312 -#: libpq/be-fsstubs.c:335 libpq/be-fsstubs.c:583 +#: libpq/be-fsstubs.c:119 libpq/be-fsstubs.c:150 libpq/be-fsstubs.c:178 +#: libpq/be-fsstubs.c:204 libpq/be-fsstubs.c:229 libpq/be-fsstubs.c:277 +#: libpq/be-fsstubs.c:300 libpq/be-fsstubs.c:555 #, c-format msgid "invalid large-object descriptor: %d" msgstr "无效的大对象æè¿°ç¬¦: %d" -#: libpq/be-fsstubs.c:180 libpq/be-fsstubs.c:218 libpq/be-fsstubs.c:602 -#: libpq/be-fsstubs.c:790 +#: libpq/be-fsstubs.c:161 #, c-format -msgid "permission denied for large object %u" -msgstr "访问大对象%uçš„æƒé™ä¸å¤Ÿ" +msgid "large object descriptor %d was not opened for reading" +msgstr "无法打开大对象æè¿°ç¬¦%d进行读æ“作" -#: libpq/be-fsstubs.c:205 libpq/be-fsstubs.c:589 +#: libpq/be-fsstubs.c:185 libpq/be-fsstubs.c:562 #, c-format msgid "large object descriptor %d was not opened for writing" msgstr "无法打开大对象æè¿°ç¬¦%d进行写æ“作" -#: libpq/be-fsstubs.c:247 +#: libpq/be-fsstubs.c:212 #, c-format msgid "lo_lseek result out of range for large-object descriptor %d" msgstr "lo_lseek的结果超出了大对象的æè¿°ç¬¦ %d所在范围" -#: libpq/be-fsstubs.c:320 +#: libpq/be-fsstubs.c:285 #, c-format msgid "lo_tell result out of range for large-object descriptor %d" msgstr "lo_tell 产生的结果超出了大对象æè¿°ç¬¦%d的有效范围" -#: libpq/be-fsstubs.c:457 -#, c-format -msgid "must be superuser to use server-side lo_import()" -msgstr "必须是超级用户æ‰å¯ä»¥ä½¿ç”¨æœåŠ¡å™¨ç«¯çš„ lo_import()" - -#: libpq/be-fsstubs.c:458 -#, c-format -msgid "Anyone can use the client-side lo_import() provided by libpq." -msgstr "任何人都å¯ä»¥ä½¿ç”¨ libpq æä¾›çš„客户端 lo_import()." - -#: libpq/be-fsstubs.c:471 +#: libpq/be-fsstubs.c:432 #, c-format msgid "could not open server file \"%s\": %m" msgstr "无法打开æœåŠ¡å™¨æ–‡ä»¶ \"%s\": %m" -#: libpq/be-fsstubs.c:493 +#: libpq/be-fsstubs.c:454 #, c-format msgid "could not read server file \"%s\": %m" msgstr "æ— æ³•è¯»å–æœåŠ¡å™¨æ–‡ä»¶ \"%s\": %m" -#: libpq/be-fsstubs.c:523 -#, c-format -msgid "must be superuser to use server-side lo_export()" -msgstr "必须是超级用户æ‰å¯ä»¥ä½¿ç”¨æœåŠ¡å™¨ç«¯çš„ lo_export()" - -#: libpq/be-fsstubs.c:524 -#, c-format -msgid "Anyone can use the client-side lo_export() provided by libpq." -msgstr "任何人都å¯ä»¥ä½¿ç”¨ libpq æä¾›çš„客户端 lo_export()." - -#: libpq/be-fsstubs.c:549 +#: libpq/be-fsstubs.c:516 #, c-format msgid "could not create server file \"%s\": %m" msgstr "无法创建æœåŠ¡å™¨æ–‡ä»¶ \"%s\": %m" -#: libpq/be-fsstubs.c:561 +#: libpq/be-fsstubs.c:528 #, c-format msgid "could not write server file \"%s\": %m" msgstr "无法写入æœåŠ¡å™¨æ–‡ä»¶ \"%s\": %m" -#: libpq/be-fsstubs.c:815 +#: libpq/be-fsstubs.c:762 #, c-format msgid "large object read request is too large" msgstr "大对象读请求太大" -#: libpq/be-fsstubs.c:857 utils/adt/genfile.c:211 utils/adt/genfile.c:252 +#: libpq/be-fsstubs.c:804 utils/adt/genfile.c:235 utils/adt/genfile.c:274 +#: utils/adt/genfile.c:310 #, c-format msgid "requested length cannot be negative" msgstr "所请求的长度ä¸èƒ½æ˜¯è´Ÿæ•°" -#: libpq/be-secure-openssl.c:184 +#: libpq/be-fsstubs.c:857 storage/large_object/inv_api.c:295 +#: storage/large_object/inv_api.c:307 storage/large_object/inv_api.c:511 +#: storage/large_object/inv_api.c:622 storage/large_object/inv_api.c:812 #, c-format -msgid "could not create SSL context: %s" -msgstr "无法创建 SSL 环境: %s" +msgid "permission denied for large object %u" +msgstr "访问大对象%uçš„æƒé™ä¸å¤Ÿ" -#: libpq/be-secure-openssl.c:200 +#: libpq/be-secure-common.c:91 #, c-format -msgid "could not load server certificate file \"%s\": %s" -msgstr "无法装载æœåŠ¡å™¨è®¤è¯æ–‡ä»¶ \"%s\": %s" +msgid "could not read from command \"%s\": %m" +msgstr "无法读å–命令 \"%s\": %m" + +#: libpq/be-secure-common.c:109 +#, c-format +msgid "command \"%s\" failed" +msgstr "命令\"%s\"失败" -#: libpq/be-secure-openssl.c:206 +#: libpq/be-secure-common.c:139 #, c-format msgid "could not access private key file \"%s\": %m" msgstr "无法处ç†ç§é’¥æ–‡ä»¶ \"%s\": %m" -#: libpq/be-secure-openssl.c:212 +#: libpq/be-secure-common.c:148 #, c-format -#| msgid "%s: file \"%s\" is not a regular file\n" msgid "private key file \"%s\" is not a regular file" msgstr "ç§é’¥æ–‡ä»¶ \"%s\" 䏿˜¯ä¸€ä¸ªå¸¸è§„文件" -#: libpq/be-secure-openssl.c:224 +#: libpq/be-secure-common.c:163 #, c-format msgid "private key file \"%s\" must be owned by the database user or root" msgstr "ç§é’¥æ–‡ä»¶ \"%s\" 必须由数æ®åº“用户或者 root 所拥有" -#: libpq/be-secure-openssl.c:244 +#: libpq/be-secure-common.c:186 #, c-format msgid "private key file \"%s\" has group or world access" msgstr "ç§é’¥æ–‡ä»¶\"%s\"具有由所在组或全局范围访问的æƒé™" -#: libpq/be-secure-openssl.c:246 +#: libpq/be-secure-common.c:188 #, c-format -msgid "" -"File must have permissions u=rw (0600) or less if owned by the database " -"user, or permissions u=rw,g=r (0640) or less if owned by root." +msgid "File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root." +msgstr "如果文件被数æ®åº“用户所拥有,它必须具有æƒé™ u=rw (0600) 或者更低;如果被 root 所拥有,它必须具有æƒé™ u=rw,g=r (0640) 或者更低。" + +#: libpq/be-secure-gssapi.c:178 +msgid "GSSAPI wrap error" +msgstr "" + +#: libpq/be-secure-gssapi.c:182 libpq/be-secure-gssapi.c:349 +#, c-format +msgid "GSSAPI did not provide confidentiality" +msgstr "" + +#: libpq/be-secure-gssapi.c:186 libpq/be-secure-gssapi.c:549 +#, c-format +msgid "server tried to send oversize GSSAPI packet: %zu bytes" +msgstr "" + +#: libpq/be-secure-gssapi.c:303 libpq/be-secure-gssapi.c:501 +#, c-format +msgid "oversize GSSAPI packet sent by the client: %zu bytes" +msgstr "" + +#: libpq/be-secure-gssapi.c:344 +msgid "GSSAPI unwrap error" +msgstr "" + +#: libpq/be-secure-gssapi.c:522 +msgid "GSSAPI context error" +msgstr "" + +#: libpq/be-secure-gssapi.c:594 +msgid "GSSAPI size check error" msgstr "" -"如果文件被数æ®åº“用户所拥有,它必须具有æƒé™ u=rw (0600) 或者更低;如果被 root " -"所拥有,它必须具有æƒé™ u=rw,g=r (0640) 或者更低。" -#: libpq/be-secure-openssl.c:253 +#: libpq/be-secure-openssl.c:111 +#, c-format +msgid "could not create SSL context: %s" +msgstr "无法创建 SSL 环境: %s" + +#: libpq/be-secure-openssl.c:154 +#, c-format +msgid "could not load server certificate file \"%s\": %s" +msgstr "无法装载æœåŠ¡å™¨è®¤è¯æ–‡ä»¶ \"%s\": %s" + +#: libpq/be-secure-openssl.c:174 +#, c-format +msgid "private key file \"%s\" cannot be reloaded because it requires a passphrase" +msgstr "æ— æ³•é‡æ–°åŠ è½½ç§é’¥æ–‡ä»¶\"%s\",因为它需è¦å¯†ç çŸ­è¯­" + +#: libpq/be-secure-openssl.c:179 #, c-format msgid "could not load private key file \"%s\": %s" msgstr "无法装载ç§é’¥æ–‡ä»¶ \"%s\": %s" -#: libpq/be-secure-openssl.c:258 +#: libpq/be-secure-openssl.c:188 #, c-format msgid "check of private key failed: %s" msgstr "检查ç§é’¥å¤±è´¥: %s" -#: libpq/be-secure-openssl.c:287 +#: libpq/be-secure-openssl.c:234 +#, c-format +msgid "could not set the cipher list (no valid ciphers available)" +msgstr "无法设置密ç åˆ—表(没有有效的密ç å¯ç”¨ï¼‰" + +#: libpq/be-secure-openssl.c:252 #, c-format msgid "could not load root certificate file \"%s\": %s" msgstr "无法装载根 (root) è®¤è¯æ–‡ä»¶ \"%s\": %s" -#: libpq/be-secure-openssl.c:311 +#: libpq/be-secure-openssl.c:279 #, c-format msgid "SSL certificate revocation list file \"%s\" ignored" msgstr "忽略SSLè®¤è¯æ’¤é”€åˆ—表文件 \"%s\"" -#: libpq/be-secure-openssl.c:313 +#: libpq/be-secure-openssl.c:281 #, c-format msgid "SSL library does not support certificate revocation lists." msgstr "SSLåº“ä¸æ”¯æŒè®¤è¯æ’¤é”€åˆ—表" -#: libpq/be-secure-openssl.c:318 +#: libpq/be-secure-openssl.c:288 #, c-format msgid "could not load SSL certificate revocation list file \"%s\": %s" msgstr "无法装载根 (root)è¯ä¹¦å–消列表文件 \"%s\": %s" -#: libpq/be-secure-openssl.c:365 +#: libpq/be-secure-openssl.c:363 +#, c-format +msgid "could not initialize SSL connection: SSL context not set up" +msgstr "无法åˆå§‹åŒ– SSL è”æŽ¥: 未设置SSL上下文" + +#: libpq/be-secure-openssl.c:371 #, c-format msgid "could not initialize SSL connection: %s" msgstr "无法åˆå§‹åŒ– SSL è”æŽ¥: %s" -#: libpq/be-secure-openssl.c:373 +#: libpq/be-secure-openssl.c:379 #, c-format msgid "could not set SSL socket: %s" msgstr "无法创建 SSL 套接字: %s" -#: libpq/be-secure-openssl.c:427 +#: libpq/be-secure-openssl.c:434 #, c-format msgid "could not accept SSL connection: %m" msgstr "无法访问 SSL è”æŽ¥: %m" -#: libpq/be-secure-openssl.c:431 libpq/be-secure-openssl.c:442 +#: libpq/be-secure-openssl.c:438 libpq/be-secure-openssl.c:449 #, c-format msgid "could not accept SSL connection: EOF detected" msgstr "无法访问 SSL è”æŽ¥: å‘现 EOF" -#: libpq/be-secure-openssl.c:436 +#: libpq/be-secure-openssl.c:443 #, c-format msgid "could not accept SSL connection: %s" msgstr "无法访问 SSL è”æŽ¥: %s" -#: libpq/be-secure-openssl.c:447 libpq/be-secure-openssl.c:588 -#: libpq/be-secure-openssl.c:648 +#: libpq/be-secure-openssl.c:454 libpq/be-secure-openssl.c:585 +#: libpq/be-secure-openssl.c:649 #, c-format msgid "unrecognized SSL error code: %d" msgstr "未知的 SSL 错误ç : %d" -#: libpq/be-secure-openssl.c:491 +#: libpq/be-secure-openssl.c:496 #, c-format msgid "SSL certificate's common name contains embedded null" msgstr "在SSL认è¯çš„æ™®é€šå称中包å«åµŒå…¥çš„空值" -#: libpq/be-secure-openssl.c:502 -#, c-format -msgid "SSL connection from \"%s\"" -msgstr "æ¥è‡ª \"%s\" çš„ SSL è”æŽ¥" - -#: libpq/be-secure-openssl.c:579 libpq/be-secure-openssl.c:639 +#: libpq/be-secure-openssl.c:574 libpq/be-secure-openssl.c:633 #, c-format msgid "SSL error: %s" msgstr "SSL 错误: %s" -#: libpq/be-secure-openssl.c:988 +#: libpq/be-secure-openssl.c:814 +#, c-format +msgid "could not open DH parameters file \"%s\": %m" +msgstr "无法打开DH傿•°æ–‡ä»¶ \"%s\": %m" + +#: libpq/be-secure-openssl.c:826 +#, c-format +msgid "could not load DH parameters file: %s" +msgstr "无法装载DH傿•°æ–‡ä»¶: %s" + +#: libpq/be-secure-openssl.c:836 +#, c-format +msgid "invalid DH parameters: %s" +msgstr "无效的DH傿•°: %s" + +#: libpq/be-secure-openssl.c:844 +#, c-format +msgid "invalid DH parameters: p is not prime" +msgstr "无效的DH傿•°ï¼šp䏿˜¯ä¸»è¦çš„" + +#: libpq/be-secure-openssl.c:852 +#, c-format +msgid "invalid DH parameters: neither suitable generator or safe prime" +msgstr "无效的DH傿•°ï¼šä¸é€‚用的生æˆå™¨æˆ–安全素数" + +# startup.c:446 +#: libpq/be-secure-openssl.c:1007 +#, c-format +msgid "DH: could not load DH parameters" +msgstr "DH: 无法加载DH傿•°" + +# startup.c:446 +#: libpq/be-secure-openssl.c:1015 +#, c-format +msgid "DH: could not set DH parameters: %s" +msgstr "DH: 无法设置DH傿•°: %s" + +#: libpq/be-secure-openssl.c:1039 #, c-format msgid "ECDH: unrecognized curve name: %s" msgstr "ECDH: 无法识别的曲线å: %s" # fe-connect.c:891 -#: libpq/be-secure-openssl.c:993 +#: libpq/be-secure-openssl.c:1048 #, c-format msgid "ECDH: could not create key" msgstr "ECDH: 无法创建键" -#: libpq/be-secure-openssl.c:1017 +#: libpq/be-secure-openssl.c:1076 msgid "no SSL error reported" msgstr "没有报告SSL错误" -#: libpq/be-secure-openssl.c:1021 +#: libpq/be-secure-openssl.c:1080 #, c-format msgid "SSL error code %lu" msgstr "SSLé”™è¯¯ä»£ç  %lu" -#: libpq/be-secure.c:171 libpq/be-secure.c:256 +# input.c:213 +#: libpq/be-secure-openssl.c:1310 +#, fuzzy, c-format +#| msgid "SSL is not supported by this build" +msgid "%s setting %s not supported by this build" +msgstr "è¿™ä¸ªç‰ˆæœ¬çš„å®‰è£…ä¸æ”¯æŒä½¿ç”¨SSL" + +#: libpq/be-secure.c:123 +#, c-format +msgid "SSL connection from \"%s\"" +msgstr "æ¥è‡ª \"%s\" çš„ SSL è”æŽ¥" + +#: libpq/be-secure.c:208 libpq/be-secure.c:304 #, c-format -#| msgid "terminating connection due to administrator command" msgid "terminating connection due to unexpected postmaster exit" msgstr "由于æ„外的 postmaster 退出而终止连接" -#: libpq/crypt.c:54 +#: libpq/crypt.c:52 #, c-format -#| msgid "role \"%s\" does not exist" msgid "Role \"%s\" does not exist." msgstr "角色 \"%s\" ä¸å­˜åœ¨ã€‚" -#: libpq/crypt.c:64 +#: libpq/crypt.c:62 #, c-format msgid "User \"%s\" has no password assigned." msgstr "用户 \"%s\" 没有分é…密ç ." -#: libpq/crypt.c:79 -#, c-format -#| msgid "User \"%s\" has an expired password." -msgid "User \"%s\" has an empty password." -msgstr "用户 \"%s\" 的密ç ä¸ºç©ºã€‚" - -#: libpq/crypt.c:159 +#: libpq/crypt.c:80 #, c-format msgid "User \"%s\" has an expired password." msgstr "User \"%s\" 密ç è¿‡æœŸ." +#: libpq/crypt.c:182 +#, c-format +msgid "User \"%s\" has a password that cannot be used with MD5 authentication." +msgstr "用户\"%s\"的密ç ä¸èƒ½ä¸ŽMD5身份验è¯ä¸€èµ·ä½¿ç”¨." + # command.c:915 # command.c:939 # startup.c:187 # startup.c:205 -#: libpq/crypt.c:167 +#: libpq/crypt.c:206 libpq/crypt.c:247 libpq/crypt.c:271 #, c-format -#| msgid "Password for user %s: " msgid "Password does not match for user \"%s\"." msgstr "用户 \"%s\" çš„å£ä»¤ä¸åŒ¹é…。" -#: libpq/hba.c:188 +#: libpq/crypt.c:290 +#, c-format +msgid "Password of user \"%s\" is in unrecognized format." +msgstr "用户\"%s\"çš„å¯†ç æ ¼å¼æ— æ³•识别" + +#: libpq/hba.c:235 #, c-format msgid "authentication file token too long, skipping: \"%s\"" msgstr "è®¤è¯æ–‡ä»¶æ ‡è®° (token) 太长, 忽略: \"%s\"" -#: libpq/hba.c:332 +#: libpq/hba.c:407 #, c-format msgid "could not open secondary authentication file \"@%s\" as \"%s\": %m" msgstr "æ— æ³•æ‰“å¼€æ¬¡è®¤è¯æ–‡ä»¶ \"@%s\" 为 \"%s\": %m" -#: libpq/hba.c:409 +#: libpq/hba.c:509 #, c-format msgid "authentication file line too long" msgstr "è®¤è¯æ–‡ä»¶æ–‡æœ¬è¡Œå¤ªé•¿" -#: libpq/hba.c:410 libpq/hba.c:757 libpq/hba.c:773 libpq/hba.c:803 -#: libpq/hba.c:849 libpq/hba.c:862 libpq/hba.c:884 libpq/hba.c:893 -#: libpq/hba.c:914 libpq/hba.c:926 libpq/hba.c:945 libpq/hba.c:966 -#: libpq/hba.c:977 libpq/hba.c:1032 libpq/hba.c:1050 libpq/hba.c:1062 -#: libpq/hba.c:1079 libpq/hba.c:1089 libpq/hba.c:1103 libpq/hba.c:1119 -#: libpq/hba.c:1134 libpq/hba.c:1145 libpq/hba.c:1181 libpq/hba.c:1219 -#: libpq/hba.c:1230 libpq/hba.c:1250 libpq/hba.c:1261 libpq/hba.c:1278 -#: libpq/hba.c:1327 libpq/hba.c:1364 libpq/hba.c:1374 libpq/hba.c:1430 -#: libpq/hba.c:1442 libpq/hba.c:1455 libpq/hba.c:1547 libpq/hba.c:1636 -#: libpq/hba.c:1654 libpq/hba.c:1675 tsearch/ts_locale.c:182 +#: libpq/hba.c:510 libpq/hba.c:867 libpq/hba.c:887 libpq/hba.c:925 +#: libpq/hba.c:975 libpq/hba.c:989 libpq/hba.c:1013 libpq/hba.c:1022 +#: libpq/hba.c:1035 libpq/hba.c:1056 libpq/hba.c:1069 libpq/hba.c:1089 +#: libpq/hba.c:1111 libpq/hba.c:1123 libpq/hba.c:1179 libpq/hba.c:1199 +#: libpq/hba.c:1213 libpq/hba.c:1232 libpq/hba.c:1243 libpq/hba.c:1258 +#: libpq/hba.c:1276 libpq/hba.c:1292 libpq/hba.c:1304 libpq/hba.c:1341 +#: libpq/hba.c:1382 libpq/hba.c:1395 libpq/hba.c:1417 libpq/hba.c:1430 +#: libpq/hba.c:1442 libpq/hba.c:1460 libpq/hba.c:1510 libpq/hba.c:1554 +#: libpq/hba.c:1565 libpq/hba.c:1581 libpq/hba.c:1598 libpq/hba.c:1608 +#: libpq/hba.c:1666 libpq/hba.c:1704 libpq/hba.c:1726 libpq/hba.c:1738 +#: libpq/hba.c:1825 libpq/hba.c:1843 libpq/hba.c:1937 libpq/hba.c:1956 +#: libpq/hba.c:1985 libpq/hba.c:1998 libpq/hba.c:2021 libpq/hba.c:2043 +#: libpq/hba.c:2057 tsearch/ts_locale.c:190 #, c-format msgid "line %d of configuration file \"%s\"" msgstr "é…置文件\"%2$s\"的第%1$d行" #. translator: the second %s is a list of auth methods -#: libpq/hba.c:755 +#: libpq/hba.c:865 #, c-format -msgid "" -"authentication option \"%s\" is only valid for authentication methods %s" +msgid "authentication option \"%s\" is only valid for authentication methods %s" msgstr "认è¯é€‰é¡¹\"%s\"åªå¯¹è®¤è¯æ–¹æ³•%s有效" # fe-auth.c:640 -#: libpq/hba.c:771 +#: libpq/hba.c:885 #, c-format msgid "authentication method \"%s\" requires argument \"%s\" to be set" msgstr "åœ¨è®¤è¯æ–¹æ³•\"%s\"需è¦è®¾ç½®å‚æ•°\"%s\" " -#: libpq/hba.c:792 +#: libpq/hba.c:913 #, c-format msgid "missing entry in file \"%s\" at end of line %d" msgstr "在 \"%s\" 文件的第 %d 行末尾缺少记录" -#: libpq/hba.c:802 +#: libpq/hba.c:924 #, c-format msgid "multiple values in ident field" msgstr "识别字段出现多个值" -#: libpq/hba.c:847 +#: libpq/hba.c:973 #, c-format msgid "multiple values specified for connection type" msgstr "连接类型指定了多个值" -#: libpq/hba.c:848 +#: libpq/hba.c:974 #, c-format msgid "Specify exactly one connection type per line." msgstr "æ¯è¡Œç²¾ç¡®æŒ‡å®šä¸€ä¸ªè¿žæŽ¥ç±»åž‹." # input.c:213 -#: libpq/hba.c:861 +#: libpq/hba.c:988 #, c-format msgid "local connections are not supported by this build" msgstr "è¿™ä¸ªç‰ˆæœ¬ç¼–è¯‘ä¸æ”¯æŒæœ¬åœ°è¿žæŽ¥" -#: libpq/hba.c:882 +#: libpq/hba.c:1011 #, c-format -msgid "hostssl requires SSL to be turned on" -msgstr "hostssl è¦æ±‚å¼€å¯ SSL开关" +msgid "hostssl record cannot match because SSL is disabled" +msgstr "hotssl记录无法匹é…,因为已ç¦ç”¨SSL" -#: libpq/hba.c:883 +#: libpq/hba.c:1012 #, c-format msgid "Set ssl = on in postgresql.conf." msgstr "在postgresql.confé…置文件中设置 ssl 开关为 on." # input.c:213 -#: libpq/hba.c:891 +#: libpq/hba.c:1020 #, c-format -msgid "hostssl is not supported by this build" -msgstr "è¿™ä¸ªç‰ˆæœ¬çš„ç¼–è¯‘å®‰è£…ä¸æ”¯æŒä½¿ç”¨hostssl" +msgid "hostssl record cannot match because SSL is not supported by this build" +msgstr "hotssl记录无法匹é…ï¼Œå› ä¸ºè¿™ä¸ªç‰ˆæœ¬çš„ç¼–è¯‘å®‰è£…ä¸æ”¯æŒä½¿ç”¨SSL" -#: libpq/hba.c:892 +#: libpq/hba.c:1021 #, c-format msgid "Compile with --with-openssl to use SSL connections." msgstr "为了使用SSL连接,在编译时需è¦å¸¦æœ‰ --with-openssl选项" +# input.c:213 +#: libpq/hba.c:1033 +#, fuzzy, c-format +#| msgid "hostssl record cannot match because SSL is not supported by this build" +msgid "hostgssenc record cannot match because GSSAPI is not supported by this build" +msgstr "hotssl记录无法匹é…ï¼Œå› ä¸ºè¿™ä¸ªç‰ˆæœ¬çš„ç¼–è¯‘å®‰è£…ä¸æ”¯æŒä½¿ç”¨SSL" + +#: libpq/hba.c:1034 +#, fuzzy, c-format +#| msgid "Compile with --with-openssl to use SSL connections." +msgid "Compile with --with-gssapi to use GSSAPI connections." +msgstr "为了使用SSL连接,在编译时需è¦å¸¦æœ‰ --with-openssl选项" + # fe-connect.c:2558 -#: libpq/hba.c:912 +#: libpq/hba.c:1054 #, c-format msgid "invalid connection type \"%s\"" msgstr "无效连接类型\"%s\"" -#: libpq/hba.c:925 +#: libpq/hba.c:1068 #, c-format msgid "end-of-line before database specification" msgstr "在数æ®åº“定义å‰é¢å‡ºçŽ°è¡Œç»“æŸç¬¦" -#: libpq/hba.c:944 +#: libpq/hba.c:1088 #, c-format msgid "end-of-line before role specification" msgstr "在角色定义å‰é¢å‡ºçŽ°è¡Œç»“æŸç¬¦" -#: libpq/hba.c:965 +#: libpq/hba.c:1110 #, c-format msgid "end-of-line before IP address specification" msgstr "在IP地å€å®šä¹‰å‰é¢å‡ºçŽ°è¡Œç»“æŸç¬¦" -#: libpq/hba.c:975 +#: libpq/hba.c:1121 #, c-format msgid "multiple values specified for host address" msgstr "ä¸»æœºåœ°å€æŒ‡å®šäº†å¤šä¸ªå€¼" -#: libpq/hba.c:976 +#: libpq/hba.c:1122 #, c-format msgid "Specify one address range per line." msgstr "æ¯è¡ŒæŒ‡å®šä¸€ä¸ªåœ°å€èŒƒå›´." -#: libpq/hba.c:1030 +#: libpq/hba.c:1177 #, c-format msgid "invalid IP address \"%s\": %s" msgstr "IPåœ°å€æ— æ•ˆ\"%s\": %s" -#: libpq/hba.c:1048 +#: libpq/hba.c:1197 #, c-format msgid "specifying both host name and CIDR mask is invalid: \"%s\"" msgstr "指定主机åï¼ŒåŒæ—¶ CIDR 掩ç : \"%s\"值无效" -#: libpq/hba.c:1060 +#: libpq/hba.c:1211 #, c-format msgid "invalid CIDR mask in address \"%s\"" msgstr "在地å€\"%s\"中的CIDRæŽ©ç æ— æ•ˆ" -#: libpq/hba.c:1077 +#: libpq/hba.c:1230 #, c-format msgid "end-of-line before netmask specification" msgstr "在网络掩ç å®šä¹‰å‰çš„行结æŸç¬¦" -#: libpq/hba.c:1078 +#: libpq/hba.c:1231 #, c-format -msgid "" -"Specify an address range in CIDR notation, or provide a separate netmask." +msgid "Specify an address range in CIDR notation, or provide a separate netmask." msgstr "使用CIDR ç¬¦å·æŒ‡å®šåœ°å€èŒƒå›´, 或者æä¾›ç‹¬ç«‹çš„网络掩ç ." -#: libpq/hba.c:1088 +#: libpq/hba.c:1242 #, c-format msgid "multiple values specified for netmask" msgstr "ç½‘ç»œæŽ©ç æŒ‡å®šäº†å¤šä¸ªå€¼" -#: libpq/hba.c:1101 +#: libpq/hba.c:1256 #, c-format msgid "invalid IP mask \"%s\": %s" msgstr "无效IPåœ°å€æŽ©ç \"%s\": %s" -#: libpq/hba.c:1118 +#: libpq/hba.c:1275 #, c-format msgid "IP address and mask do not match" msgstr "IP地å€ä¸ŽæŽ©ç ä¸åŒ¹é…" -#: libpq/hba.c:1133 +#: libpq/hba.c:1291 #, c-format msgid "end-of-line before authentication method" msgstr "åœ¨è®¤è¯æ–¹æ³•å‰é¢å‡ºçŽ°è¡Œç»“æŸç¬¦" -#: libpq/hba.c:1143 +#: libpq/hba.c:1302 #, c-format msgid "multiple values specified for authentication type" msgstr "认è¯ç±»åž‹æŒ‡å®šäº†å¤šä¸ªå€¼" -#: libpq/hba.c:1144 +#: libpq/hba.c:1303 #, c-format msgid "Specify exactly one authentication type per line." msgstr "æ¯è¡Œç²¾ç¡®æŒ‡å®šä¸€ä¸ªè®¤è¯ç±»åž‹." -#: libpq/hba.c:1217 +#: libpq/hba.c:1380 #, c-format msgid "invalid authentication method \"%s\"" msgstr "æ— æ•ˆè®¤è¯æ–¹æ³•\"%s\"" # fe-auth.c:640 -#: libpq/hba.c:1228 +#: libpq/hba.c:1393 #, c-format msgid "invalid authentication method \"%s\": not supported by this build" msgstr "è¿™ä¸ªç‰ˆæœ¬çš„ç¼–è¯‘å®‰è£…ä¸æ”¯æŒæ— æ•ˆçš„è®¤è¯æ–¹æ³•\"%s\"" -#: libpq/hba.c:1249 +#: libpq/hba.c:1416 #, c-format msgid "gssapi authentication is not supported on local sockets" msgstr "åœ¨æœ¬åœ°å¥—æŽ¥å­—ä¸Šä¸æ”¯æŒgssapi认è¯" -#: libpq/hba.c:1260 +#: libpq/hba.c:1429 +#, c-format +msgid "GSSAPI encryption only supports gss, trust, or reject authentication" +msgstr "" + +#: libpq/hba.c:1441 #, c-format msgid "peer authentication is only supported on local sockets" msgstr "对等认è¯åªæ”¯æŒåœ¨æœ¬åœ°å¥—接字的情形下使用" -#: libpq/hba.c:1277 +#: libpq/hba.c:1459 #, c-format msgid "cert authentication is only supported on hostssl connections" msgstr "åªæœ‰åœ¨hostsslè¿žæŽ¥ä¸Šæ‰æ”¯æŒcert认è¯" -#: libpq/hba.c:1326 +#: libpq/hba.c:1509 #, c-format msgid "authentication option not in name=value format: %s" msgstr "认è¯é€‰é¡¹çš„æ ¼å¼ä¸æ˜¯åç§°=值:%s" -#: libpq/hba.c:1363 +#: libpq/hba.c:1553 #, c-format -msgid "" -"cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, or " -"ldapurl together with ldapprefix" -msgstr "" -"无法和ldapprefix一åŒä½¿ç”¨ldapbasedn, ldapbinddn, ldapbindpasswd, " -"ldapsearchattribute或ldapurl" +msgid "cannot use ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter, or ldapurl together with ldapprefix" +msgstr "无法和ldapprefix一åŒä½¿ç”¨ldapbasedn, ldapbinddn, ldapbindpasswd, ldapsearchattribute, ldapsearchfilter或ldapurl" # fe-auth.c:640 -#: libpq/hba.c:1373 +#: libpq/hba.c:1564 #, c-format -msgid "" -"authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix" -"\", or \"ldapsuffix\" to be set" -msgstr "" -"åœ¨è®¤è¯æ–¹æ³•\"ldap\"中需è¦è®¾ç½®å‚æ•° \"ldapbasedn\", \"ldapprefix\"或\"ldapsuffix" -"\"" +msgid "authentication method \"ldap\" requires argument \"ldapbasedn\", \"ldapprefix\", or \"ldapsuffix\" to be set" +msgstr "åœ¨è®¤è¯æ–¹æ³•\"ldap\"中需è¦è®¾ç½®å‚æ•° \"ldapbasedn\", \"ldapprefix\"或\"ldapsuffix\"" -#: libpq/hba.c:1416 +#: libpq/hba.c:1580 +#, c-format +msgid "cannot use ldapsearchattribute together with ldapsearchfilter" +msgstr "无法和ldapsearchfilter一åŒä½¿ç”¨ldapsearchattribute" + +#: libpq/hba.c:1597 +#, c-format +msgid "list of RADIUS servers cannot be empty" +msgstr "RADIUSæœåŠ¡å™¨åˆ—è¡¨ä¸èƒ½ä¸ºç©º" + +#: libpq/hba.c:1607 +#, c-format +msgid "list of RADIUS secrets cannot be empty" +msgstr "RADIUS机密(secret)列表ä¸èƒ½ä¸ºç©º " + +#: libpq/hba.c:1660 +#, c-format +msgid "the number of %s (%d) must be 1 or the same as the number of %s (%d)" +msgstr "%s的数目(%d)必须是1或与%s (%d)的数目相åŒ" + +#: libpq/hba.c:1694 msgid "ident, peer, gssapi, sspi, and cert" msgstr "ident, peer, gssapi, sspiå’Œcert" -#: libpq/hba.c:1429 +#: libpq/hba.c:1703 #, c-format msgid "clientcert can only be configured for \"hostssl\" rows" msgstr "åªèƒ½ä¸º\"hostssl\" 记录é…ç½®clientcert " -#: libpq/hba.c:1440 -#, c-format -msgid "" -"client certificates can only be checked if a root certificate store is " -"available" -msgstr "åªæœ‰åœ¨æ ¹è®¤è¯æœ‰æ•ˆçš„æƒ…况下æ‰èƒ½æ£€æŸ¥å®¢æˆ·ç«¯è®¤è¯" - -#: libpq/hba.c:1454 -#, c-format -msgid "clientcert can not be set to 0 when using \"cert\" authentication" +#: libpq/hba.c:1725 +#, fuzzy, c-format +#| msgid "clientcert can not be set to 0 when using \"cert\" authentication" +msgid "clientcert can not be set to \"no-verify\" when using \"cert\" authentication" msgstr "当使用\"cert\"è®¤è¯æ—¶clientcertä¸èƒ½è®¾ç½®ä¸º0" +#: libpq/hba.c:1737 +#, fuzzy, c-format +#| msgid "invalid value for parameter \"%s\": \"%s\"" +msgid "invalid value for clientcert: \"%s\"" +msgstr "傿•° \"%s\" 的值无效: \"%s\"" + # fe-lobj.c:400 fe-lobj.c:483 -#: libpq/hba.c:1490 +#: libpq/hba.c:1771 #, c-format msgid "could not parse LDAP URL \"%s\": %s" msgstr "无法解æžLDAP URL \"%s\": %s" -#: libpq/hba.c:1498 +#: libpq/hba.c:1782 #, c-format msgid "unsupported LDAP URL scheme: %s" msgstr "䏿”¯æŒçš„LDAP URL模å¼: %s" -#: libpq/hba.c:1514 -#, c-format -msgid "filters not supported in LDAP URLs" -msgstr "LDAPçš„URL䏿”¯æŒè¿‡æ»¤å™¨" - -#: libpq/hba.c:1522 +#: libpq/hba.c:1806 #, c-format msgid "LDAP URLs not supported on this platform" msgstr "LDAP URLä¸èƒ½ç”¨äºŽæ­¤å¹³å°" -#: libpq/hba.c:1546 +#: libpq/hba.c:1824 +#, c-format +msgid "invalid ldapscheme value: \"%s\"" +msgstr "无效的 sslmode 值: \"%s\"" + +#: libpq/hba.c:1842 #, c-format msgid "invalid LDAP port number: \"%s\"" msgstr "无效LDAP端å£å·: \"%s\"" -#: libpq/hba.c:1586 libpq/hba.c:1593 +#: libpq/hba.c:1888 libpq/hba.c:1895 msgid "gssapi and sspi" msgstr "gssapi, å’Œsspi" -#: libpq/hba.c:1602 libpq/hba.c:1611 +#: libpq/hba.c:1904 libpq/hba.c:1913 msgid "sspi" msgstr "sspi" -#: libpq/hba.c:1653 +#: libpq/hba.c:1935 +#, c-format +msgid "could not parse RADIUS server list \"%s\"" +msgstr "无法分æžRADIUSæœåŠ¡å™¨åˆ—è¡¨\"%s\"" + +#: libpq/hba.c:1983 +#, c-format +msgid "could not parse RADIUS port list \"%s\"" +msgstr "无法分æžRADIUS端å£åˆ—表\"%s\"" + +#: libpq/hba.c:1997 #, c-format msgid "invalid RADIUS port number: \"%s\"" msgstr "无效RADIUS端å£å·: \"%s\"" -#: libpq/hba.c:1673 +#: libpq/hba.c:2019 +#, c-format +msgid "could not parse RADIUS secret list \"%s\"" +msgstr "无法分æžRADIUS秘密(secret)列表\"%s\"" + +#: libpq/hba.c:2041 +#, c-format +msgid "could not parse RADIUS identifiers list \"%s\"" +msgstr "无法分æžRADIUS标识符列表\"%s\"" + +#: libpq/hba.c:2055 #, c-format msgid "unrecognized authentication option name: \"%s\"" msgstr "未知认è¯é€‰é¡¹åç§°:\"%s\"" -#: libpq/hba.c:1859 +#: libpq/hba.c:2199 libpq/hba.c:2613 guc-file.l:596 +#, c-format +msgid "could not open configuration file \"%s\": %m" +msgstr "无法打开é…置文件 \"%s\": %m" + +#: libpq/hba.c:2250 #, c-format msgid "configuration file \"%s\" contains no entries" msgstr "é…置文件 \"%s\" 没有é…置项" -#: libpq/hba.c:1955 +#: libpq/hba.c:2769 #, c-format msgid "invalid regular expression \"%s\": %s" msgstr "无效的正则表达å¼\"%s\": %s" -#: libpq/hba.c:2015 +#: libpq/hba.c:2829 #, c-format msgid "regular expression match for \"%s\" failed: %s" msgstr "正则表达å¼åŒ¹é…\"%s\"失败:%s" -#: libpq/hba.c:2034 +#: libpq/hba.c:2848 #, c-format -msgid "" -"regular expression \"%s\" has no subexpressions as requested by " -"backreference in \"%s\"" +msgid "regular expression \"%s\" has no subexpressions as requested by backreference in \"%s\"" msgstr "正则表达å¼\"%s\"没有在\"%s\"中的åŽé¡¹å¼•ç”¨æ‰€è¦æ±‚çš„å­è¡¨è¾¾å¼." -#: libpq/hba.c:2131 +#: libpq/hba.c:2945 #, c-format msgid "provided user name (%s) and authenticated user name (%s) do not match" msgstr "所æä¾›çš„用户å(%s)和被认è¯çš„用户å(%s) ä¸åŒ¹é…" -#: libpq/hba.c:2151 +#: libpq/hba.c:2965 #, c-format msgid "no match in usermap \"%s\" for user \"%s\" authenticated as \"%s\"" msgstr "对于以\"%3$s\"身份认è¯ä¸ºçš„用户\"%2$s\",在用户映射\"%1$s\"中没有匹é…" -#: libpq/hba.c:2186 +#: libpq/hba.c:2998 #, c-format msgid "could not open usermap file \"%s\": %m" msgstr "无法打开用户映射文件\"%s\": %m" -#: libpq/pqcomm.c:202 +#: libpq/pqcomm.c:220 #, c-format msgid "could not set socket to nonblocking mode: %m" msgstr "无法将套接字设为éžé˜»å¡žæ¨¡å¼: %m" -#: libpq/pqcomm.c:354 +#: libpq/pqcomm.c:374 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)" msgstr "Unix域的套接字路径 \"%s\" è¶…é•¿(最大为%d字节)" -#: libpq/pqcomm.c:375 +#: libpq/pqcomm.c:395 #, c-format msgid "could not translate host name \"%s\", service \"%s\" to address: %s" msgstr "无法解æžä¸»æœºå \"%s\", æœåŠ¡ \"%s\" 到地å€: %s" -#: libpq/pqcomm.c:379 +#: libpq/pqcomm.c:399 #, c-format msgid "could not translate service \"%s\" to address: %s" msgstr "æ— æ³•è§£æžæœåŠ¡ \"%s\" 到地å€: %s" -#: libpq/pqcomm.c:406 +#: libpq/pqcomm.c:426 #, c-format msgid "could not bind to all requested addresses: MAXLISTEN (%d) exceeded" msgstr "无法绑定所有需è¦çš„地å€:超过最大数é‡MAXLISTEN (%d)" -#: libpq/pqcomm.c:415 +#: libpq/pqcomm.c:435 msgid "IPv4" msgstr "IPv4" -#: libpq/pqcomm.c:419 +#: libpq/pqcomm.c:439 msgid "IPv6" msgstr "IPv6" -#: libpq/pqcomm.c:424 +#: libpq/pqcomm.c:444 msgid "Unix" msgstr "Unix" -#: libpq/pqcomm.c:429 +#: libpq/pqcomm.c:449 #, c-format msgid "unrecognized address family %d" msgstr "ä¸è®¤å¯çš„åœ°å€æ— %d" -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:440 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:475 #, c-format -msgid "could not create %s socket: %m" -msgstr "无法创建 %s 套接字: %m" +msgid "could not create %s socket for address \"%s\": %m" +msgstr "无法为地å€\"%2$s\"创建%1$s套接字: %m" -#: libpq/pqcomm.c:465 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:501 #, c-format -msgid "setsockopt(SO_REUSEADDR) failed: %m" -msgstr "setsockopt(SO_REUSEADDR) 失败: %m" +msgid "setsockopt(SO_REUSEADDR) failed for %s address \"%s\": %m" +msgstr "%s地å€\"%s\"çš„setsockopt(SO_REUSEADDR) 失败: %m" -#: libpq/pqcomm.c:480 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:518 #, c-format -msgid "setsockopt(IPV6_V6ONLY) failed: %m" -msgstr "setsockopt(IPV6_V6ONLY) 失败: %m" +msgid "setsockopt(IPV6_V6ONLY) failed for %s address \"%s\": %m" +msgstr "%s地å€\"%s\"çš„setsockopt(IPV6_V6ONLY) 失败: %m" -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:499 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:538 #, c-format -msgid "could not bind %s socket: %m" -msgstr "无法绑定 %s 套接字: %m" +msgid "could not bind %s address \"%s\": %m" +msgstr "无法绑定%s地å€\"%s\": %m" -#: libpq/pqcomm.c:502 +#: libpq/pqcomm.c:541 #, c-format -msgid "" -"Is another postmaster already running on port %d? If not, remove socket file " -"\"%s\" and retry." -msgstr "" -"æ˜¯å¦æœ‰å…¶å®ƒ postmaster å·²ç»åœ¨ç«¯å£ %d 上è¿è¡Œäº†? 如果没有, 删除套接字文件 \"%s" -"\" ç„¶åŽå†é‡è¯•." +msgid "Is another postmaster already running on port %d? If not, remove socket file \"%s\" and retry." +msgstr "æ˜¯å¦æœ‰å…¶å®ƒ postmaster å·²ç»åœ¨ç«¯å£ %d 上è¿è¡Œäº†? 如果没有, 删除套接字文件 \"%s\" ç„¶åŽå†é‡è¯•." -#: libpq/pqcomm.c:505 +#: libpq/pqcomm.c:544 #, c-format -msgid "" -"Is another postmaster already running on port %d? If not, wait a few seconds " -"and retry." -msgstr "" -"æ˜¯å¦æœ‰å…¶å®ƒ postmaster å·²ç»åœ¨ç«¯å£ %d 上è¿è¡Œäº†? 如果没有, 请等待几秒钟åŽç„¶åŽå†" -"é‡è¯•." +msgid "Is another postmaster already running on port %d? If not, wait a few seconds and retry." +msgstr "æ˜¯å¦æœ‰å…¶å®ƒ postmaster å·²ç»åœ¨ç«¯å£ %d 上è¿è¡Œäº†? 如果没有, 请等待几秒钟åŽç„¶åŽå†é‡è¯•." -#. translator: %s is IPv4, IPv6, or Unix -#: libpq/pqcomm.c:538 +#. translator: first %s is IPv4, IPv6, or Unix +#: libpq/pqcomm.c:577 +#, c-format +msgid "could not listen on %s address \"%s\": %m" +msgstr "无法监å¬%s地å€\"%s\": %m" + +#: libpq/pqcomm.c:586 #, c-format -msgid "could not listen on %s socket: %m" -msgstr "无法在 %s 套接字上监å¬: %m" +msgid "listening on Unix socket \"%s\"" +msgstr "在Unix套接字 \"%s\"上侦å¬" -#: libpq/pqcomm.c:623 +#. translator: first %s is IPv4 or IPv6 +#: libpq/pqcomm.c:592 +#, c-format +msgid "listening on %s address \"%s\", port %d" +msgstr "正在监å¬%s地å€\"%s\"ï¼Œç«¯å£ %d" + +#: libpq/pqcomm.c:675 #, c-format msgid "group \"%s\" does not exist" msgstr "组 \"%s\" ä¸å­˜åœ¨" -#: libpq/pqcomm.c:633 +#: libpq/pqcomm.c:685 #, c-format msgid "could not set group of file \"%s\": %m" msgstr "无法设置文件 \"%s\" 的组: %m" -#: libpq/pqcomm.c:644 +#: libpq/pqcomm.c:696 #, c-format msgid "could not set permissions of file \"%s\": %m" msgstr "无法设置文件 \"%s\" çš„æƒé™: %m" -#: libpq/pqcomm.c:674 +#: libpq/pqcomm.c:726 #, c-format msgid "could not accept new connection: %m" msgstr "æ— æ³•è®¿é—®æ–°è”æŽ¥: %m" -#: libpq/pqcomm.c:885 +#: libpq/pqcomm.c:928 #, c-format msgid "there is no client connection" msgstr "没有客户端连接" -#: libpq/pqcomm.c:936 libpq/pqcomm.c:1032 +#: libpq/pqcomm.c:979 libpq/pqcomm.c:1075 #, c-format msgid "could not receive data from client: %m" msgstr "无法从客户端获得数æ®: %m" -#: libpq/pqcomm.c:1177 tcop/postgres.c:3906 +#: libpq/pqcomm.c:1220 tcop/postgres.c:4087 #, c-format msgid "terminating connection because protocol synchronization was lost" msgstr "由于åè®®åŒæ­¥ä¸¢å¤±è€Œä¸­æ–­è¿žæŽ¥" -#: libpq/pqcomm.c:1243 +#: libpq/pqcomm.c:1286 #, c-format msgid "unexpected EOF within message length word" msgstr "在信æ¯é•¿åº¦å­—里有æ„外的 EOF" -#: libpq/pqcomm.c:1254 +#: libpq/pqcomm.c:1297 #, c-format msgid "invalid message length" msgstr "无效的信æ¯é•¿åº¦" -#: libpq/pqcomm.c:1276 libpq/pqcomm.c:1289 +#: libpq/pqcomm.c:1319 libpq/pqcomm.c:1332 #, c-format msgid "incomplete message from client" msgstr "从客户端过æ¥çš„ä¸å®Œæ•´ä¿¡æ¯" -#: libpq/pqcomm.c:1422 +#: libpq/pqcomm.c:1465 #, c-format msgid "could not send data to client: %m" msgstr "无法å‘逿•°æ®ç»™å®¢æˆ·ç«¯: %m" -#: libpq/pqformat.c:436 +#: libpq/pqformat.c:406 #, c-format msgid "no data left in message" msgstr "ä¿¡æ¯ä¸­å·²ç»æ²¡æœ‰æ•°æ®äº†" -#: libpq/pqformat.c:556 libpq/pqformat.c:574 libpq/pqformat.c:595 -#: utils/adt/arrayfuncs.c:1457 utils/adt/rowtypes.c:563 +#: libpq/pqformat.c:517 libpq/pqformat.c:535 libpq/pqformat.c:556 +#: utils/adt/arrayfuncs.c:1470 utils/adt/rowtypes.c:567 #, c-format msgid "insufficient data left in message" msgstr "ä¿¡æ¯ä¸­å‰©ä¸‹çš„æ•°æ®ä¸å¤Ÿ" -#: libpq/pqformat.c:636 +#: libpq/pqformat.c:597 libpq/pqformat.c:626 #, c-format msgid "invalid string in message" msgstr "ä¿¡æ¯ä¸­çš„æ— æ•ˆå­—串" -#: libpq/pqformat.c:652 +#: libpq/pqformat.c:642 #, c-format msgid "invalid message format" msgstr "æ— æ•ˆçš„ä¿¡æ¯æ ¼å¼" @@ -12514,7 +13498,7 @@ msgstr "æ— æ•ˆçš„ä¿¡æ¯æ ¼å¼" msgid "%s: WSAStartup failed: %d\n" msgstr "%s: WSAStartup 失败: %d\n" -#: main/main.c:327 +#: main/main.c:328 #, c-format msgid "" "%s is the PostgreSQL server.\n" @@ -12523,7 +13507,7 @@ msgstr "" "%s 是 PostgreSQL æœåС噍.\n" "\n" -#: main/main.c:328 +#: main/main.c:329 #, c-format msgid "" "Usage:\n" @@ -12534,114 +13518,112 @@ msgstr "" " %s [选项]...\n" "\n" -#: main/main.c:329 +#: main/main.c:330 #, c-format msgid "Options:\n" msgstr "选项:\n" -#: main/main.c:330 +#: main/main.c:331 #, c-format msgid " -B NBUFFERS number of shared buffers\n" msgstr " -B NBUFFERS 共享缓冲区的数é‡\n" -#: main/main.c:331 +#: main/main.c:332 #, c-format msgid " -c NAME=VALUE set run-time parameter\n" msgstr " -c NAME=VALUE 设置è¿è¡Œæ—¶å‚æ•°\n" -#: main/main.c:332 +#: main/main.c:333 #, c-format msgid " -C NAME print value of run-time parameter, then exit\n" msgstr " -C NAME 打å°è¿è¡Œæ—¶å‚æ•°, ç„¶åŽé€€å‡º\n" -#: main/main.c:333 +#: main/main.c:334 #, c-format msgid " -d 1-5 debugging level\n" msgstr " -d 1-5 调试级别\n" -#: main/main.c:334 +#: main/main.c:335 #, c-format msgid " -D DATADIR database directory\n" msgstr " -D DATADIR æ•°æ®åº“目录\n" -#: main/main.c:335 +#: main/main.c:336 #, c-format msgid " -e use European date input format (DMY)\n" msgstr " -e ä½¿ç”¨æ¬§æ´²æ—¥æœŸè¾“å…¥æ ¼å¼ (DMY)\n" -#: main/main.c:336 +#: main/main.c:337 #, c-format msgid " -F turn fsync off\n" -msgstr " -F 关闭 fsync\n" +msgstr " -F 关闭 fsync\n" -#: main/main.c:337 +#: main/main.c:338 #, c-format msgid " -h HOSTNAME host name or IP address to listen on\n" msgstr " -h HOSTNAME 侦å¬çš„ä¸»æœºåæˆ–者 IP 地å€\n" -#: main/main.c:338 +#: main/main.c:339 #, c-format msgid " -i enable TCP/IP connections\n" msgstr " -i 打开 TCP/IP 连接\n" -#: main/main.c:339 +#: main/main.c:340 #, c-format msgid " -k DIRECTORY Unix-domain socket location\n" msgstr " -k DIRECTORY Unix 域套接字的目录ä½ç½®\n" -#: main/main.c:341 +#: main/main.c:342 #, c-format msgid " -l enable SSL connections\n" msgstr " -l å¼€å¯ SSL 连接\n" -#: main/main.c:343 +#: main/main.c:344 #, c-format msgid " -N MAX-CONNECT maximum number of allowed connections\n" msgstr " -N MAX-CONNECT å…许建立的最大连接数目\n" -#: main/main.c:344 +#: main/main.c:345 #, c-format -msgid "" -" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" -msgstr "" -" -o OPTIONS 把 \"OPTIONS\" 传递给æ¯ä¸€ä¸ªåŽç«¯æœåŠ¡å™¨è¿›ç¨‹(已作废)\n" +msgid " -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n" +msgstr " -o OPTIONS 把 \"OPTIONS\" 传递给æ¯ä¸€ä¸ªåŽç«¯æœåŠ¡å™¨è¿›ç¨‹(已作废)\n" -#: main/main.c:345 +#: main/main.c:346 #, c-format msgid " -p PORT port number to listen on\n" msgstr " -p PORT 监å¬çš„端å£å·\n" -#: main/main.c:346 +#: main/main.c:347 #, c-format msgid " -s show statistics after each query\n" msgstr " -s æ¯ä¸ªæŸ¥è¯¢åŽæ˜¾ç¤ºç»Ÿè®¡ä¿¡æ¯\n" -#: main/main.c:347 +#: main/main.c:348 #, c-format msgid " -S WORK-MEM set amount of memory for sorts (in kB)\n" msgstr " -S WORK-MEM 设置排åºå†…å­˜æ•°é‡ (å•ä½ä¸º kB)\n" -#: main/main.c:348 +#: main/main.c:349 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 输出版本信æ¯ï¼Œç„¶åŽé€€å‡º\n" -#: main/main.c:349 +#: main/main.c:350 #, c-format msgid " --NAME=VALUE set run-time parameter\n" msgstr " --NAME=VALUE 设置è¿è¡Œæ—¶å‚æ•°\n" -#: main/main.c:350 +#: main/main.c:351 #, c-format msgid " --describe-config describe configuration parameters, then exit\n" msgstr " --describe-config æè¿°é…ç½®å‚æ•°, ç„¶åŽé€€å‡º\n" -#: main/main.c:351 +#: main/main.c:352 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help 显示帮助信æ¯ï¼Œç„¶åŽé€€å‡º\n" -#: main/main.c:353 +#: main/main.c:354 #, c-format msgid "" "\n" @@ -12650,45 +13632,42 @@ msgstr "" "\n" "å¼€å‘人员选项:\n" -#: main/main.c:354 +#: main/main.c:355 #, c-format msgid " -f s|i|n|m|h forbid use of some plan types\n" msgstr " -f s|i|n|m|h ç¦æ­¢ä¸€äº›è®¡åˆ’类型的使用\n" -#: main/main.c:355 +#: main/main.c:356 #, c-format -msgid "" -" -n do not reinitialize shared memory after abnormal exit\n" +msgid " -n do not reinitialize shared memory after abnormal exit\n" msgstr " -n 在异常退出之åŽä¸å†é‡æ–°åˆå§‹åŒ–共享内存\n" -#: main/main.c:356 +#: main/main.c:357 #, c-format msgid " -O allow system table structure changes\n" -msgstr " -O å…许改å˜ç³»ç»Ÿè¡¨ç»“æž„\n" +msgstr " -O å…许改å˜ç³»ç»Ÿè¡¨ç»“æž„\n" -#: main/main.c:357 +#: main/main.c:358 #, c-format msgid " -P disable system indexes\n" msgstr " -P 关闭系统索引\n" -#: main/main.c:358 +#: main/main.c:359 #, c-format msgid " -t pa|pl|ex show timings after each query\n" msgstr " -t pa|pl|ex æ¯ä¸ªæŸ¥è¯¢åŽæ˜¾ç¤ºè®¡æ—¶\n" -#: main/main.c:359 +#: main/main.c:360 #, c-format -msgid "" -" -T send SIGSTOP to all backend processes if one dies\n" -msgstr "" -" -T 如果一个åŽç«¯è¿›ç¨‹é€€å‡º, é‚£ä¹ˆå‘æ‰€æœ‰åŽç«¯è¿›ç¨‹å‘é€ SIGSTOP\n" +msgid " -T send SIGSTOP to all backend processes if one dies\n" +msgstr " -T 如果一个åŽç«¯è¿›ç¨‹é€€å‡º, é‚£ä¹ˆå‘æ‰€æœ‰åŽç«¯è¿›ç¨‹å‘é€ SIGSTOP\n" -#: main/main.c:360 +#: main/main.c:361 #, c-format msgid " -W NUM wait NUM seconds to allow attach from a debugger\n" -msgstr " -W NUM 等待 NUM ç§’, 以便å…许调试器加入调试\n" +msgstr " -W NUM 等待 NUM ç§’, 以便å…许调试器加入调试\n" -#: main/main.c:362 +#: main/main.c:363 #, c-format msgid "" "\n" @@ -12698,40 +13677,38 @@ msgstr "" "å•用户模å¼çš„选项:\n" # help.c:109 -#: main/main.c:363 +#: main/main.c:364 #, c-format -msgid "" -" --single selects single-user mode (must be first argument)\n" +msgid " --single selects single-user mode (must be first argument)\n" msgstr " --single 选择å•用户模å¼(å¿…é¡»æ˜¯ç¬¬ä¸€ä¸ªå‚æ•°)\n" # help.c:136 -#: main/main.c:364 +#: main/main.c:365 #, c-format msgid " DBNAME database name (defaults to user name)\n" msgstr " DBNAME æ•°æ®åº“åç§°(对用户å缺çœ)\n" -#: main/main.c:365 +#: main/main.c:366 #, c-format msgid " -d 0-5 override debugging level\n" msgstr " -d 0-5 覆盖调试级别\n" -#: main/main.c:366 +#: main/main.c:367 #, c-format msgid " -E echo statement before execution\n" msgstr " -E æ‰§è¡Œå‰æ˜¾ç¤ºè¯­å¥\n" -#: main/main.c:367 +#: main/main.c:368 #, c-format -msgid "" -" -j do not use newline as interactive query delimiter\n" +msgid " -j do not use newline as interactive query delimiter\n" msgstr " -j ä¸ä½¿ç”¨æ–°è¡Œä½œä¸ºäº¤äº’查询的分隔符\n" -#: main/main.c:368 main/main.c:373 +#: main/main.c:369 main/main.c:374 #, c-format msgid " -r FILENAME send stdout and stderr to given file\n" msgstr " -r FILENAME 把标准输出和标准错误å‘é€åˆ°æŒ‡å®šçš„æ–‡ä»¶ä¸­\n" -#: main/main.c:370 +#: main/main.c:371 #, c-format msgid "" "\n" @@ -12740,33 +13717,37 @@ msgstr "" "\n" "引导模å¼çš„选项:\n" -#: main/main.c:371 +#: main/main.c:372 #, c-format -msgid "" -" --boot selects bootstrapping mode (must be first argument)\n" +msgid " --boot selects bootstrapping mode (must be first argument)\n" msgstr " --boot 选择引导模å¼(å¿…é¡»æ˜¯ç¬¬ä¸€ä¸ªå‚æ•°)\n" -#: main/main.c:372 +#: main/main.c:373 #, c-format -msgid "" -" DBNAME database name (mandatory argument in bootstrapping " -"mode)\n" +msgid " DBNAME database name (mandatory argument in bootstrapping mode)\n" msgstr " DBNAME æ•°æ®åº“å称(在引导模å¼ä¸­æ˜¯å¿…选傿•°)\n" -#: main/main.c:374 +#: main/main.c:375 #, c-format msgid " -x NUM internal use\n" msgstr " -x NUM 内部使用\n" -#: main/main.c:376 -#, c-format +#: main/main.c:377 +#, fuzzy, c-format +#| msgid "" +#| "\n" +#| "Please read the documentation for the complete list of run-time\n" +#| "configuration settings and how to set them on the command line or in\n" +#| "the configuration file.\n" +#| "\n" +#| "Report bugs to .\n" msgid "" "\n" "Please read the documentation for the complete list of run-time\n" "configuration settings and how to set them on the command line or in\n" "the configuration file.\n" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" "请阅读文档获å–è¿è¡Œæ—¶é…置设置的完整列表\n" @@ -12774,7 +13755,7 @@ msgstr "" "\n" "è¯·å‘ æŠ¥å‘Šè‡­è™«.\n" -#: main/main.c:390 +#: main/main.c:391 #, c-format msgid "" "\"root\" execution of the PostgreSQL server is not permitted.\n" @@ -12787,12 +13768,12 @@ msgstr "" "å¯èƒ½çš„系统安全性问题. å‚é˜…æ–‡æ¡£èŽ·å–æ›´å¤š\n" "有关如何正确å¯åЍæœåŠ¡å™¨çš„ä¿¡æ¯.\n" -#: main/main.c:407 +#: main/main.c:408 #, c-format msgid "%s: real and effective user IDs must match\n" msgstr "%s: 真实和有效用户标识必须相互匹é…\n" -#: main/main.c:414 +#: main/main.c:415 #, c-format msgid "" "Execution of PostgreSQL by a user with administrative permissions is not\n" @@ -12808,943 +13789,1042 @@ msgstr "" #: nodes/extensible.c:66 #, c-format -#| msgid "extension \"%s\" already exists" msgid "extensible node type \"%s\" already exists" msgstr "坿‰©å±•节点类型 \"%s\" 已存在" #: nodes/extensible.c:114 #, c-format -#| msgid "extension \"%s\" does not exist" msgid "ExtensibleNodeMethods \"%s\" was not registered" msgstr "ExtensibleNodeMethods \"%s\" 没有注册" -#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1820 -#: parser/parse_coerce.c:1848 parser/parse_coerce.c:1924 -#: parser/parse_expr.c:1981 parser/parse_func.c:597 parser/parse_oper.c:952 +#: nodes/nodeFuncs.c:123 nodes/nodeFuncs.c:154 parser/parse_coerce.c:1915 +#: parser/parse_coerce.c:1943 parser/parse_coerce.c:2019 +#: parser/parse_expr.c:2201 parser/parse_func.c:705 parser/parse_oper.c:967 #, c-format msgid "could not find array type for data type %s" msgstr "无法为数æ®ç±»åž‹ %s 找到数组类型" -#: optimizer/path/allpaths.c:2608 -#, c-format -msgid "WHERE CURRENT OF is not supported on a view with no underlying relation" -msgstr "åœ¨ä¸€ä¸ªæ²¡æœ‰åŸºç¡€å…³ç³»çš„è§†å›¾ä¸Šä¸æ”¯æŒWHERE CURRENT OF" - -#: optimizer/path/allpaths.c:2613 -#, c-format -msgid "" -"WHERE CURRENT OF is not supported on a view with more than one underlying " -"relation" -msgstr "åœ¨ä¸€ä¸ªæœ‰å¤šäºŽä¸€ä¸ªåŸºç¡€å…³ç³»çš„è§†å›¾ä¸Šä¸æ”¯æŒWHERE CURRENT OF" - -#: optimizer/path/allpaths.c:2618 +#: optimizer/path/joinrels.c:833 #, c-format -msgid "" -"WHERE CURRENT OF is not supported on a view with grouping or aggregation" -msgstr "在一个带有分组或者èšé›†çš„è§†å›¾ä¸Šä¸æ”¯æŒWHERE CURRENT OF" - -#: optimizer/path/joinrels.c:802 -#, c-format -msgid "" -"FULL JOIN is only supported with merge-joinable or hash-joinable join " -"conditions" +msgid "FULL JOIN is only supported with merge-joinable or hash-joinable join conditions" msgstr "åªæœ‰åœ¨åˆå¹¶è¿žæŽ¥æˆ–哈希连接的查询æ¡ä»¶ä¸­æ‰æ”¯æŒFULL JOIN" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/initsplan.c:1124 +#: optimizer/plan/initsplan.c:1195 #, c-format msgid "%s cannot be applied to the nullable side of an outer join" msgstr "%s ä¸èƒ½ç”¨äºŽå¤–连接中的空值一边" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: optimizer/plan/planner.c:1473 parser/analyze.c:1481 parser/analyze.c:1679 -#: parser/analyze.c:2460 +#: optimizer/plan/planner.c:1912 parser/analyze.c:1644 parser/analyze.c:1842 +#: parser/analyze.c:2700 #, c-format msgid "%s is not allowed with UNION/INTERSECT/EXCEPT" msgstr "%sä¸å…许使用UNION/INTERSECT/EXCEPT" -#: optimizer/plan/planner.c:3752 +#: optimizer/plan/planner.c:2498 optimizer/plan/planner.c:4152 #, c-format msgid "could not implement GROUP BY" msgstr "无法实现GROUP BY语å¥" -#: optimizer/plan/planner.c:3753 optimizer/plan/planner.c:4095 -#: optimizer/prep/prepunion.c:927 +#: optimizer/plan/planner.c:2499 optimizer/plan/planner.c:4153 +#: optimizer/plan/planner.c:4891 optimizer/prep/prepunion.c:1042 #, c-format -msgid "" -"Some of the datatypes only support hashing, while others only support " -"sorting." +msgid "Some of the datatypes only support hashing, while others only support sorting." msgstr "一些数æ®ç±»åž‹åªæ”¯æŒå“ˆå¸Œï¼ŒåŒæ—¶å¦å¤–一些数æ®ç±»åž‹åªæ”¯æŒæŽ’åº." -#: optimizer/plan/planner.c:4094 +#: optimizer/plan/planner.c:4890 #, c-format msgid "could not implement DISTINCT" msgstr "无法实现DISTINCT语å¥" -#: optimizer/plan/planner.c:4633 +#: optimizer/plan/planner.c:5625 #, c-format msgid "could not implement window PARTITION BY" msgstr "无法实现与窗å£å‡½æ•°ä¸€åŒä½¿ç”¨PARTITION BYå­å¥" -#: optimizer/plan/planner.c:4634 +#: optimizer/plan/planner.c:5626 #, c-format msgid "Window partitioning columns must be of sortable datatypes." msgstr "窗å£åˆ†åŒºåˆ—å¿…é¡»å±žäºŽå¯æŽ’åºçš„æ•°æ®ç±»åž‹" -#: optimizer/plan/planner.c:4638 +#: optimizer/plan/planner.c:5630 #, c-format msgid "could not implement window ORDER BY" msgstr "无法实现与窗å£å‡½æ•°ä¸€åŒä½¿ç”¨ORDER BY 语å¥" -#: optimizer/plan/planner.c:4639 +#: optimizer/plan/planner.c:5631 #, c-format msgid "Window ordering columns must be of sortable datatypes." msgstr "窗å£çš„æŽ’åºåˆ—å¿…é¡»å±žäºŽå¯æŽ’åºçš„æ•°æ®ç±»åž‹" -#: optimizer/plan/setrefs.c:423 +#: optimizer/plan/setrefs.c:424 #, c-format msgid "too many range table entries" msgstr "太多范围表" -#: optimizer/prep/prepunion.c:480 +#: optimizer/prep/prepunion.c:505 #, c-format msgid "could not implement recursive UNION" msgstr "无法实现递归UNIONæ“作" -#: optimizer/prep/prepunion.c:481 +#: optimizer/prep/prepunion.c:506 #, c-format msgid "All column datatypes must be hashable." msgstr "所有列的数æ®ç±»åž‹å¿…é¡»å¯è¿›è¡Œå“ˆå¸Œè®¡ç®—." #. translator: %s is UNION, INTERSECT, or EXCEPT -#: optimizer/prep/prepunion.c:926 +#: optimizer/prep/prepunion.c:1041 #, c-format msgid "could not implement %s" msgstr "无法实现%s" -#: optimizer/util/clauses.c:4965 +#: optimizer/util/clauses.c:4781 #, c-format msgid "SQL function \"%s\" during inlining" msgstr "SQL 函数 \"%s\" åœ¨å†…è” (inlining) 期间" -#: optimizer/util/plancat.c:114 +#: optimizer/util/plancat.c:130 #, c-format msgid "cannot access temporary or unlogged relations during recovery" msgstr "无法在æ¢å¤è¿‡ç¨‹ä¸­è®¿é—®ä¸´æ—¶å…³ç³»æˆ–éžäº‹åŠ¡æ—¥å¿—å…³ç³»" -#: optimizer/util/plancat.c:591 +#: optimizer/util/plancat.c:650 #, c-format -msgid "system columns cannot be used in an ON CONFLICT clause" -msgstr "在ON CONFLICTå­å¥ä¸­ä¸èƒ½ä½¿ç”¨ç³»ç»Ÿåˆ—" +msgid "whole row unique index inference specifications are not supported" +msgstr "䏿”¯æŒæ•´è¡Œå”¯ä¸€ç´¢å¼•推ç†è§„范" -#: optimizer/util/plancat.c:609 +#: optimizer/util/plancat.c:667 #, c-format msgid "constraint in ON CONFLICT clause has no associated index" msgstr "ON CONFLICTå­å¥ä¸­çš„çº¦æŸæ²¡æœ‰ç›¸å…³çš„索引" -#: optimizer/util/plancat.c:661 +#: optimizer/util/plancat.c:717 #, c-format msgid "ON CONFLICT DO UPDATE not supported with exclusion constraints" msgstr "ON CONFLICT DO UPDATE䏿”¯æŒå’ŒæŽ’除约æŸä¸€èµ·ä½¿ç”¨" -#: optimizer/util/plancat.c:768 +#: optimizer/util/plancat.c:822 #, c-format -msgid "" -"there is no unique or exclusion constraint matching the ON CONFLICT " -"specification" +msgid "there is no unique or exclusion constraint matching the ON CONFLICT specification" msgstr "没有匹é…ON CONFLICT说明的唯一或者排除约æŸ" -#: parser/analyze.c:639 parser/analyze.c:1253 +#: parser/analyze.c:711 parser/analyze.c:1407 #, c-format msgid "VALUES lists must all be the same length" msgstr "在VALUES列表中æ¯ä¸ªæˆå‘˜çš„长度必须相åŒ" -#: parser/analyze.c:811 +#: parser/analyze.c:914 #, c-format msgid "INSERT has more expressions than target columns" msgstr "INSERT 的表达å¼å¤šäºŽæŒ‡å®šçš„字段数" -#: parser/analyze.c:829 +#: parser/analyze.c:932 #, c-format msgid "INSERT has more target columns than expressions" msgstr "INSERT 的指定字段数多于表达å¼" -#: parser/analyze.c:833 +#: parser/analyze.c:936 #, c-format -msgid "" -"The insertion source is a row expression containing the same number of " -"columns expected by the INSERT. Did you accidentally use extra parentheses?" -msgstr "" -"æ’å…¥æºæ˜¯ä¸€ä¸ªè¡Œè¡¨è¾¾å¼ï¼Œé‡Œè¾¹çš„列个数与INSERT期望值相åŒ. 您是å¦å¶å°”使用了é¢å¤–çš„" -"父表达å¼?" +msgid "The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?" +msgstr "æ’å…¥æºæ˜¯ä¸€ä¸ªè¡Œè¡¨è¾¾å¼ï¼Œé‡Œè¾¹çš„列个数与INSERT期望值相åŒ. 您是å¦å¶å°”使用了é¢å¤–的父表达å¼?" -#: parser/analyze.c:1074 parser/analyze.c:1454 +#: parser/analyze.c:1218 parser/analyze.c:1617 #, c-format msgid "SELECT ... INTO is not allowed here" msgstr "这儿ä¸å…许使用SELECT ... INTO" -#: parser/analyze.c:1267 -#, c-format -msgid "DEFAULT can only appear in a VALUES list within INSERT" -msgstr "DEFAULTåªèƒ½åœ¨INSERT语å¥ä¸­çš„VALUES列表中出现" - #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:1386 parser/analyze.c:2630 +#: parser/analyze.c:1549 parser/analyze.c:2879 #, c-format msgid "%s cannot be applied to VALUES" msgstr "%s ä¸èƒ½ç”¨äºŽ VALUES" -#: parser/analyze.c:1607 +#: parser/analyze.c:1767 #, c-format msgid "invalid UNION/INTERSECT/EXCEPT ORDER BY clause" msgstr "无效的UNION/INTERSECT/EXCEPT ORDER BY å­å¥" -#: parser/analyze.c:1608 +#: parser/analyze.c:1768 #, c-format msgid "Only result column names can be used, not expressions or functions." msgstr "æ— æ³•ä½¿ç”¨è¡¨è¾¾å¼æˆ–å‡½æ•°ï¼Œåªæœ‰ç»“果列的åç§°å¯ä»¥ä½¿ç”¨." -#: parser/analyze.c:1609 +#: parser/analyze.c:1769 #, c-format -msgid "" -"Add the expression/function to every SELECT, or move the UNION into a FROM " -"clause." +msgid "Add the expression/function to every SELECT, or move the UNION into a FROM clause." msgstr "对æ¯ä¸ªSELECT语å¥å¢žåŠ è¡¨è¾¾å¼/函数, 或者将UNION移动到FROMå­å¥ä¸­." -#: parser/analyze.c:1669 +#: parser/analyze.c:1832 #, c-format msgid "INTO is only allowed on first SELECT of UNION/INTERSECT/EXCEPT" msgstr "INTO åªå…许在 UNION/INTERSECT/EXCEPT 的第一个 SELECT 上使用" -#: parser/analyze.c:1733 +#: parser/analyze.c:1904 #, c-format -msgid "" -"UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of " -"same query level" +msgid "UNION/INTERSECT/EXCEPT member statement cannot refer to other relations of same query level" msgstr "UNION/INTERSECT/EXCEPTçš„æˆå‘˜è¯­å¥ä¸èƒ½å‚è€ƒç›¸åŒæŸ¥è¯¢å±‚次的其它关系" -#: parser/analyze.c:1822 +#: parser/analyze.c:1993 #, c-format msgid "each %s query must have the same number of columns" msgstr "æ¯ä¸€ä¸ª %s 查询必须有相åŒçš„字段个数" -#: parser/analyze.c:2215 +#: parser/analyze.c:2411 #, c-format msgid "RETURNING must have at least one column" msgstr "RETURNING 必须至少有一列" -#: parser/analyze.c:2252 +#: parser/analyze.c:2452 #, c-format msgid "cannot specify both SCROLL and NO SCROLL" msgstr "ä¸å¯åŒæ—¶æŒ‡å®š SCROLL å’Œ NO SCROLL" -#: parser/analyze.c:2270 +#: parser/analyze.c:2471 #, c-format msgid "DECLARE CURSOR must not contain data-modifying statements in WITH" msgstr "DECLARE CURSORä¸èƒ½åœ¨WITHå­å¥ä¸­åŒ…å«ä¿®æ”¹æ•°æ®çš„æ“ä½œ" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2278 +#: parser/analyze.c:2479 #, c-format msgid "DECLARE CURSOR WITH HOLD ... %s is not supported" msgstr "DECLARE CURSOR WITH HOLD ... %sä¸èƒ½ä½¿ç”¨" -#: parser/analyze.c:2281 +#: parser/analyze.c:2482 #, c-format msgid "Holdable cursors must be READ ONLY." msgstr "å¯ä¿æŒæ¸¸æ ‡å¿…须为åªè¯»." #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2289 +#: parser/analyze.c:2490 #, c-format msgid "DECLARE SCROLL CURSOR ... %s is not supported" msgstr "DECLARE SCROLL CURSOR ... %sä¸èƒ½ä½¿ç”¨" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2300 +#: parser/analyze.c:2501 #, c-format msgid "DECLARE INSENSITIVE CURSOR ... %s is not supported" msgstr "DECLARE INSENSITIVE CURSOR ... %sä¸èƒ½ä½¿ç”¨" -#: parser/analyze.c:2303 +#: parser/analyze.c:2504 #, c-format msgid "Insensitive cursors must be READ ONLY." msgstr "éžæ•感游标必须为åªè¯»æ¨¡å¼ï¼ˆREAD ONLY)." -#: parser/analyze.c:2369 +#: parser/analyze.c:2570 #, c-format msgid "materialized views must not use data-modifying statements in WITH" msgstr "物化视图ä¸èƒ½åŒ…å«ä¿®æ”¹æ•°æ®çš„WITHå­å¥" -#: parser/analyze.c:2379 +#: parser/analyze.c:2580 #, c-format msgid "materialized views must not use temporary tables or views" msgstr "物化视图ä¸èƒ½ä½¿ç”¨ä¸´æ—¶è¡¨æˆ–视图" -#: parser/analyze.c:2389 +#: parser/analyze.c:2590 #, c-format msgid "materialized views may not be defined using bound parameters" msgstr "ç‰©åŒ–è§†å›¾åœ¨ç»‘å®šå‚æ•°é‡Œå¯èƒ½æ²¡è¢«å®šä¹‰" -#: parser/analyze.c:2401 -#, c-format -msgid "materialized views cannot be UNLOGGED" +#: parser/analyze.c:2602 +#, fuzzy, c-format +#| msgid "materialized views cannot be UNLOGGED" +msgid "materialized views cannot be unlogged" msgstr "物化视图ä¸èƒ½ä½¿ç”¨UNLOGGED" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2467 +#: parser/analyze.c:2707 #, c-format msgid "%s is not allowed with DISTINCT clause" msgstr "%sä¸èƒ½ç”¨äºŽDISTINCTå­å¥ä¸­" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2474 +#: parser/analyze.c:2714 #, c-format msgid "%s is not allowed with GROUP BY clause" msgstr "%sä¸èƒ½ç”¨äºŽGROUP BYå­å¥ä¸­" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2481 +#: parser/analyze.c:2721 #, c-format msgid "%s is not allowed with HAVING clause" msgstr "%sä¸èƒ½ç”¨äºŽHAVINGå­å¥ä¸­" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2488 +#: parser/analyze.c:2728 #, c-format msgid "%s is not allowed with aggregate functions" msgstr "%sä¸èƒ½ç”¨äºŽèšåˆå‡½æ•°ä¸­" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2495 +#: parser/analyze.c:2735 #, c-format msgid "%s is not allowed with window functions" msgstr "%sä¸èƒ½ç”¨äºŽçª—å£å‡½æ•°ä¸­" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2502 +#: parser/analyze.c:2742 #, c-format msgid "%s is not allowed with set-returning functions in the target list" msgstr "%sä¸èƒ½ç”¨äºŽç›®æ ‡åˆ—表中的返回集åˆçš„函数中" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2581 +#: parser/analyze.c:2821 #, c-format msgid "%s must specify unqualified relation names" msgstr "%s 必须指定ä¸åˆæ ¼çš„关系å" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2612 +#: parser/analyze.c:2852 #, c-format msgid "%s cannot be applied to a join" msgstr "%s ä¸èƒ½ç”¨äºŽè¿žæŽ¥(join)æ“作" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2621 +#: parser/analyze.c:2861 #, c-format msgid "%s cannot be applied to a function" msgstr "%sä¸èƒ½ç”¨äºŽå‡½æ•°" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2639 +#: parser/analyze.c:2870 +#, c-format +msgid "%s cannot be applied to a table function" +msgstr "%sä¸èƒ½åº”用于表函数" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2888 #, c-format msgid "%s cannot be applied to a WITH query" msgstr "%s ä¸èƒ½ç”¨äºŽWITH查询" #. translator: %s is a SQL row locking clause such as FOR UPDATE -#: parser/analyze.c:2656 +#: parser/analyze.c:2897 +#, c-format +msgid "%s cannot be applied to a named tuplestore" +msgstr "%sä¸èƒ½åº”用于命åçš„tuplestore" + +#. translator: %s is a SQL row locking clause such as FOR UPDATE +#: parser/analyze.c:2917 #, c-format msgid "relation \"%s\" in %s clause not found in FROM clause" msgstr "å­å¥%2$s中的关系 \"%1$s\" 在FROMå­å¥ä¸­æ— æ³•找到" -#: parser/parse_agg.c:208 parser/parse_oper.c:220 +#: parser/parse_agg.c:220 parser/parse_oper.c:222 #, c-format msgid "could not identify an ordering operator for type %s" msgstr "无法为类型%sè¯†åˆ«é¡ºåºæ“作符" -#: parser/parse_agg.c:210 +#: parser/parse_agg.c:222 #, c-format msgid "Aggregates with DISTINCT must be able to sort their inputs." msgstr "带有DISTINCT关键字的èšåˆå‡½æ•°å¿…须能够对它们的输入进行排åº" -#: parser/parse_agg.c:245 +#: parser/parse_agg.c:257 #, c-format msgid "GROUPING must have fewer than 32 arguments" msgstr "GROUPINGçš„å‚æ•°ä¸èƒ½è¶…过32个" -#: parser/parse_agg.c:348 +#: parser/parse_agg.c:360 msgid "aggregate functions are not allowed in JOIN conditions" msgstr "èšåˆå‡½æ•°ä¸å…许出现在 JOIN æ¡ä»¶ä¸­" -#: parser/parse_agg.c:350 +#: parser/parse_agg.c:362 msgid "grouping operations are not allowed in JOIN conditions" msgstr "JOINæ¡ä»¶ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:362 -msgid "" -"aggregate functions are not allowed in FROM clause of their own query level" +#: parser/parse_agg.c:374 +msgid "aggregate functions are not allowed in FROM clause of their own query level" msgstr "èšåˆå‡½æ•°ä¸å…许出现在它们自己查询级别的FROMå­å¥ä¸­" -#: parser/parse_agg.c:364 -msgid "" -"grouping operations are not allowed in FROM clause of their own query level" +#: parser/parse_agg.c:376 +msgid "grouping operations are not allowed in FROM clause of their own query level" msgstr "分组æ“作ä¸å…许出现在它们所在查询级别的FROMå­å¥ä¸­" -#: parser/parse_agg.c:369 +#: parser/parse_agg.c:381 msgid "aggregate functions are not allowed in functions in FROM" msgstr "èšåˆå‡½æ•°ä¸å…许出现在FROMå­å¥ä¸­çš„函数里" -#: parser/parse_agg.c:371 +#: parser/parse_agg.c:383 msgid "grouping operations are not allowed in functions in FROM" msgstr "分组æ“作ä¸å…许出现在FROM中的函数内" -#: parser/parse_agg.c:379 +#: parser/parse_agg.c:391 msgid "aggregate functions are not allowed in policy expressions" msgstr "策略表达å¼ä¸­ä¸å…许èšé›†å‡½æ•°" -#: parser/parse_agg.c:381 +#: parser/parse_agg.c:393 msgid "grouping operations are not allowed in policy expressions" msgstr "策略表达å¼ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:398 +#: parser/parse_agg.c:410 msgid "aggregate functions are not allowed in window RANGE" msgstr "在èšåˆå‡½æ•°ä¸å…许出现在窗å£èŒƒå›´å­å¥é‡Œ" -#: parser/parse_agg.c:400 +#: parser/parse_agg.c:412 msgid "grouping operations are not allowed in window RANGE" msgstr "窗å£RANGE中ä¸å…许分组æ“作" -#: parser/parse_agg.c:405 +#: parser/parse_agg.c:417 msgid "aggregate functions are not allowed in window ROWS" msgstr "èšåˆå‡½æ•°ä¸å…许出现在窗å£ROWSå­å¥é‡Œ" -#: parser/parse_agg.c:407 +#: parser/parse_agg.c:419 msgid "grouping operations are not allowed in window ROWS" msgstr "窗å£ROWS中ä¸å…许分组æ“作" -#: parser/parse_agg.c:440 +#: parser/parse_agg.c:424 +msgid "aggregate functions are not allowed in window GROUPS" +msgstr "èšåˆå‡½æ•°ä¸å…许出现在窗å£GROUPSå­å¥é‡Œ" + +#: parser/parse_agg.c:426 +msgid "grouping operations are not allowed in window GROUPS" +msgstr "窗å£GROUPS中ä¸å…许分组æ“作" + +#: parser/parse_agg.c:460 msgid "aggregate functions are not allowed in check constraints" msgstr "èšåˆå‡½æ•°ä¸å…许出现在check约æŸä¸­" -#: parser/parse_agg.c:442 +#: parser/parse_agg.c:462 msgid "grouping operations are not allowed in check constraints" msgstr "检查约æŸä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:449 +#: parser/parse_agg.c:469 msgid "aggregate functions are not allowed in DEFAULT expressions" msgstr "èšåˆå‡½æ•°ä¸å…许出现在DEFAULT表达å¼ä¸­" -#: parser/parse_agg.c:451 +#: parser/parse_agg.c:471 msgid "grouping operations are not allowed in DEFAULT expressions" msgstr "DEFAULT表达å¼ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:456 +#: parser/parse_agg.c:476 msgid "aggregate functions are not allowed in index expressions" msgstr "èšåˆå‡½æ•°ä¸å…许出现在索引表达å¼ä¸­" -#: parser/parse_agg.c:458 +#: parser/parse_agg.c:478 msgid "grouping operations are not allowed in index expressions" msgstr "索引表达å¼ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:463 +#: parser/parse_agg.c:483 msgid "aggregate functions are not allowed in index predicates" msgstr "èšåˆå‡½æ•°ä¸å…许出现在索引判定å­å¥å½“中" -#: parser/parse_agg.c:465 +#: parser/parse_agg.c:485 msgid "grouping operations are not allowed in index predicates" msgstr "索引谓è¯ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:470 +#: parser/parse_agg.c:490 msgid "aggregate functions are not allowed in transform expressions" msgstr "èšåˆå‡½æ•°ä¸å…许出现在转æ¢è¡¨è¾¾å¼ä¸­" -#: parser/parse_agg.c:472 +#: parser/parse_agg.c:492 msgid "grouping operations are not allowed in transform expressions" msgstr "转æ¢è¡¨è¾¾å¼ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:477 +#: parser/parse_agg.c:497 msgid "aggregate functions are not allowed in EXECUTE parameters" msgstr "èšåˆå‡½æ•°ä¸å…许出现在EXECUTE傿•°ä¸­" -#: parser/parse_agg.c:479 +#: parser/parse_agg.c:499 msgid "grouping operations are not allowed in EXECUTE parameters" msgstr "EXECUTE傿•°ä¸­ä¸å…许分组æ“作" -#: parser/parse_agg.c:484 +#: parser/parse_agg.c:504 msgid "aggregate functions are not allowed in trigger WHEN conditions" msgstr "èšåˆå‡½æ•°ä¸å…许出现在触å‘器WHENæ¡ä»¶ä¸­" -#: parser/parse_agg.c:486 +#: parser/parse_agg.c:506 msgid "grouping operations are not allowed in trigger WHEN conditions" msgstr "触å‘器WHENæ¡ä»¶ä¸­ä¸å…许分组æ“作" +#: parser/parse_agg.c:511 +#, fuzzy +#| msgid "aggregate functions are not allowed in partition key expressions" +msgid "aggregate functions are not allowed in partition bound" +msgstr "èšåˆå‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_agg.c:513 +#, fuzzy +#| msgid "grouping operations are not allowed in partition key expressions" +msgid "grouping operations are not allowed in partition bound" +msgstr "分区键表达å¼ä¸­ä¸å…许分组æ“作" + +#: parser/parse_agg.c:518 +msgid "aggregate functions are not allowed in partition key expressions" +msgstr "èšåˆå‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_agg.c:520 +msgid "grouping operations are not allowed in partition key expressions" +msgstr "分区键表达å¼ä¸­ä¸å…许分组æ“作" + +#: parser/parse_agg.c:526 +#, fuzzy +#| msgid "aggregate functions are not allowed in policy expressions" +msgid "aggregate functions are not allowed in column generation expressions" +msgstr "策略表达å¼ä¸­ä¸å…许èšé›†å‡½æ•°" + +#: parser/parse_agg.c:528 +#, fuzzy +#| msgid "grouping operations are not allowed in policy expressions" +msgid "grouping operations are not allowed in column generation expressions" +msgstr "策略表达å¼ä¸­ä¸å…许分组æ“作" + +#: parser/parse_agg.c:534 +msgid "aggregate functions are not allowed in CALL arguments" +msgstr "èšåˆå‡½æ•°ä¸å…许出现在CALL傿•°ä¸­" + +#: parser/parse_agg.c:536 +msgid "grouping operations are not allowed in CALL arguments" +msgstr "CALL傿•°ä¸­ä¸å…许分组æ“作" + +#: parser/parse_agg.c:542 +#, fuzzy +#| msgid "aggregate functions are not allowed in JOIN conditions" +msgid "aggregate functions are not allowed in COPY FROM WHERE conditions" +msgstr "èšåˆå‡½æ•°ä¸å…许出现在 JOIN æ¡ä»¶ä¸­" + +#: parser/parse_agg.c:544 +#, fuzzy +#| msgid "grouping operations are not allowed in JOIN conditions" +msgid "grouping operations are not allowed in COPY FROM WHERE conditions" +msgstr "JOINæ¡ä»¶ä¸­ä¸å…许分组æ“作" + #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:509 parser/parse_clause.c:1550 +#: parser/parse_agg.c:567 parser/parse_clause.c:1778 #, c-format msgid "aggregate functions are not allowed in %s" msgstr "èšåˆå‡½æ•°ä¸å…许出现在%s中" #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:512 +#: parser/parse_agg.c:570 #, c-format msgid "grouping operations are not allowed in %s" msgstr "%s中ä¸å…许分组æ“作" -#: parser/parse_agg.c:620 +#: parser/parse_agg.c:678 #, c-format -msgid "" -"outer-level aggregate cannot contain a lower-level variable in its direct " -"arguments" +msgid "outer-level aggregate cannot contain a lower-level variable in its direct arguments" msgstr "outer-level èšé›†å‡½æ•°åœ¨å…¶ç›´æŽ¥å‚数里ä¸èƒ½åŒ…嫿›´ä½Žçº§åˆ«çš„å˜é‡" -#: parser/parse_agg.c:691 +#: parser/parse_agg.c:757 +#, c-format +msgid "aggregate function calls cannot contain set-returning function calls" +msgstr "对于èšåˆå‡½æ•°è°ƒç”¨ä¸èƒ½åŒ…å«å°†è¿”回集åˆå‡½æ•°çš„调用" + +#: parser/parse_agg.c:758 parser/parse_expr.c:1839 parser/parse_expr.c:2328 +#: parser/parse_func.c:876 +#, c-format +msgid "You might be able to move the set-returning function into a LATERAL FROM item." +msgstr "您å¯ä»¥å°†è¿”回集åˆå‡½æ•°ç§»åˆ°LATERAL FROM项中" + +#: parser/parse_agg.c:763 #, c-format msgid "aggregate function calls cannot contain window function calls" msgstr "对于èšåˆå‡½æ•°è°ƒç”¨ä¸èƒ½åŒ…å«çª—å£å‡½æ•°çš„调用" -#: parser/parse_agg.c:769 +#: parser/parse_agg.c:842 msgid "window functions are not allowed in JOIN conditions" msgstr "窗å£å‡½æ•°ä¸å…许出现在JOINæ¡ä»¶ä¸­" -#: parser/parse_agg.c:776 +#: parser/parse_agg.c:849 msgid "window functions are not allowed in functions in FROM" msgstr "窗å£å‡½æ•°ä¸å…许出现在FROM的函数中" -#: parser/parse_agg.c:782 +#: parser/parse_agg.c:855 msgid "window functions are not allowed in policy expressions" msgstr "策略表达å¼ä¸­ä¸å…许窗å£å‡½æ•°" -#: parser/parse_agg.c:794 +#: parser/parse_agg.c:868 msgid "window functions are not allowed in window definitions" msgstr "窗å£å‡½æ•°ä¸å…许出现在窗å£å®šä¹‰ä¸­" -#: parser/parse_agg.c:825 +#: parser/parse_agg.c:900 msgid "window functions are not allowed in check constraints" msgstr "窗å£å‡½æ•°ä¸å…许出现在check约æŸä¸­" -#: parser/parse_agg.c:829 +#: parser/parse_agg.c:904 msgid "window functions are not allowed in DEFAULT expressions" msgstr "窗å£å‡½æ•°ä¸å…许出现在DEFAULT表达å¼ä¸­" -#: parser/parse_agg.c:832 +#: parser/parse_agg.c:907 msgid "window functions are not allowed in index expressions" msgstr "在窗å£å‡½æ•°ä¸å…许出现在索引表达å¼ä¸­" -#: parser/parse_agg.c:835 +#: parser/parse_agg.c:910 msgid "window functions are not allowed in index predicates" msgstr "在窗å£å‡½æ•°ä¸å…许出现在索引判定å­å¥ä¸­" -#: parser/parse_agg.c:838 +#: parser/parse_agg.c:913 msgid "window functions are not allowed in transform expressions" msgstr "窗å£å‡½æ•°ä¸å…许出现在转æ¢è¡¨è¾¾å¼ä¸­" -#: parser/parse_agg.c:841 +#: parser/parse_agg.c:916 msgid "window functions are not allowed in EXECUTE parameters" msgstr "窗å£å‡½æ•°ä¸å…许出现在EXECUTE傿•°ä¸­" -#: parser/parse_agg.c:844 +#: parser/parse_agg.c:919 msgid "window functions are not allowed in trigger WHEN conditions" msgstr "窗å£å‡½æ•°ä¸å…许出现在触å‘器WHENæ¡ä»¶ä¸­" +#: parser/parse_agg.c:922 +#, fuzzy +#| msgid "window functions are not allowed in partition key expressions" +msgid "window functions are not allowed in partition bound" +msgstr "在窗å£å‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_agg.c:925 +msgid "window functions are not allowed in partition key expressions" +msgstr "在窗å£å‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_agg.c:928 +msgid "window functions are not allowed in CALL arguments" +msgstr "窗å£å‡½æ•°ä¸å…许出现在CALL傿•°ä¸­" + +#: parser/parse_agg.c:931 +#, fuzzy +#| msgid "window functions are not allowed in JOIN conditions" +msgid "window functions are not allowed in COPY FROM WHERE conditions" +msgstr "窗å£å‡½æ•°ä¸å…许出现在JOINæ¡ä»¶ä¸­" + +#: parser/parse_agg.c:934 +#, fuzzy +#| msgid "window functions are not allowed in policy expressions" +msgid "window functions are not allowed in column generation expressions" +msgstr "策略表达å¼ä¸­ä¸å…许窗å£å‡½æ•°" + #. translator: %s is name of a SQL construct, eg GROUP BY -#: parser/parse_agg.c:864 parser/parse_clause.c:1559 +#: parser/parse_agg.c:954 parser/parse_clause.c:1787 #, c-format msgid "window functions are not allowed in %s" msgstr "窗å£å‡½æ•°ä¸å…许出现在%s中" -#: parser/parse_agg.c:898 parser/parse_clause.c:2396 +#: parser/parse_agg.c:988 parser/parse_clause.c:2623 #, c-format msgid "window \"%s\" does not exist" msgstr "窗å£\"%s\"ä¸å­˜åœ¨" -#: parser/parse_agg.c:983 +#: parser/parse_agg.c:1072 #, c-format msgid "too many grouping sets present (maximum 4096)" msgstr "出现过多分组集åˆï¼ˆæœ€å¤§4096个)" -#: parser/parse_agg.c:1132 +#: parser/parse_agg.c:1212 #, c-format -msgid "" -"aggregate functions are not allowed in a recursive query's recursive term" +msgid "aggregate functions are not allowed in a recursive query's recursive term" msgstr "èšåˆå‡½æ•°ä¸å…许出现在递归查询的递归项中" -#: parser/parse_agg.c:1325 +#: parser/parse_agg.c:1405 #, c-format -msgid "" -"column \"%s.%s\" must appear in the GROUP BY clause or be used in an " -"aggregate function" +msgid "column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function" msgstr "字段 \"%s.%s\" 必须出现在 GROUP BY å­å¥ä¸­æˆ–者在èšåˆå‡½æ•°ä¸­ä½¿ç”¨" -#: parser/parse_agg.c:1328 +#: parser/parse_agg.c:1408 #, c-format -msgid "" -"Direct arguments of an ordered-set aggregate must use only grouped columns." +msgid "Direct arguments of an ordered-set aggregate must use only grouped columns." msgstr "有åºèšé›†å‡½æ•°çš„ç›´æŽ¥å‚æ•°å¿…须使用分组列." -#: parser/parse_agg.c:1333 +#: parser/parse_agg.c:1413 #, c-format msgid "subquery uses ungrouped column \"%s.%s\" from outer query" msgstr "å­æŸ¥è¯¢ä½¿ç”¨äº†å¤–层查询中的éžåˆ†ç»„列 \"%s.%s\" " -#: parser/parse_agg.c:1497 +#: parser/parse_agg.c:1577 #, c-format -msgid "" -"arguments to GROUPING must be grouping expressions of the associated query " -"level" +msgid "arguments to GROUPING must be grouping expressions of the associated query level" msgstr "GROUPINGçš„å‚æ•°å¿…须是相关查询层次的分组表达å¼" -#: parser/parse_clause.c:649 +#: parser/parse_clause.c:198 +#, c-format +msgid "relation \"%s\" cannot be the target of a modifying statement" +msgstr "关系\"%s\"ä¸èƒ½ä½œä¸ºä¿®æ”¹è¯­å¥çš„目标" + +#: parser/parse_clause.c:575 parser/parse_clause.c:603 parser/parse_func.c:2434 +#, c-format +msgid "set-returning functions must appear at top level of FROM" +msgstr "返回集åˆå‡½æ•°å¿…须出现在FROM的顶层." + +#: parser/parse_clause.c:615 #, c-format msgid "multiple column definition lists are not allowed for the same function" msgstr "多列定义列表ä¸å…许了现在相åŒçš„函数中" -#: parser/parse_clause.c:682 +#: parser/parse_clause.c:648 #, c-format -msgid "" -"ROWS FROM() with multiple functions cannot have a column definition list" +msgid "ROWS FROM() with multiple functions cannot have a column definition list" msgstr "带多函数的ROWS FROM() ä¸èƒ½å¸¦æœ‰åˆ—定义列表" -#: parser/parse_clause.c:683 +#: parser/parse_clause.c:649 #, c-format -msgid "" -"Put a separate column definition list for each function inside ROWS FROM()." +msgid "Put a separate column definition list for each function inside ROWS FROM()." msgstr "在ROWS FROM()里为æ¯ä¸ªå‡½æ•°æ”¾ç½®ç‹¬ç«‹çš„列定义列表." -#: parser/parse_clause.c:689 +#: parser/parse_clause.c:655 #, c-format msgid "UNNEST() with multiple arguments cannot have a column definition list" msgstr "å¸¦å¤šä¸ªå‚æ•°çš„UNNEST() ä¸èƒ½å¸¦æœ‰åˆ—定义列表" -#: parser/parse_clause.c:690 +#: parser/parse_clause.c:656 #, c-format -msgid "" -"Use separate UNNEST() calls inside ROWS FROM(), and attach a column " -"definition list to each one." +msgid "Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one." msgstr "在ROWS FROM()里使用独立的UNNEST()调用, 并为æ¯ä¸ªè°ƒç”¨é™„上一个列定义列表." -#: parser/parse_clause.c:697 +#: parser/parse_clause.c:663 #, c-format msgid "WITH ORDINALITY cannot be used with a column definition list" msgstr "WITH ORDINALITY ä¸èƒ½ä½¿ç”¨åˆ—定义列表" -#: parser/parse_clause.c:698 +#: parser/parse_clause.c:664 #, c-format msgid "Put the column definition list inside ROWS FROM()." msgstr "在 ROWS FROM()时旋转列定义列表." -#: parser/parse_clause.c:753 +#: parser/parse_clause.c:767 +#, c-format +msgid "only one FOR ORDINALITY column is allowed" +msgstr "åªå…许一个FOR ORDINALITY列" + +#: parser/parse_clause.c:828 +#, c-format +msgid "column name \"%s\" is not unique" +msgstr "列å \"%s\" 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_clause.c:870 +#, c-format +msgid "namespace name \"%s\" is not unique" +msgstr "命å空间åç§° \"%s\" 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_clause.c:880 +#, c-format +msgid "only one default namespace is allowed" +msgstr "åªå…许一个默认命å空间" + +#: parser/parse_clause.c:942 #, c-format msgid "tablesample method %s does not exist" msgstr "表采样方法\"%s\"ä¸å­˜åœ¨" # fe-auth.c:640 -#: parser/parse_clause.c:775 +#: parser/parse_clause.c:964 #, c-format msgid "tablesample method %s requires %d argument, not %d" msgid_plural "tablesample method %s requires %d arguments, not %d" msgstr[0] "表采样方法%sè¦æ±‚%dä¸ªå‚æ•°ï¼Œè€Œä¸æ˜¯%d个" -#: parser/parse_clause.c:809 +#: parser/parse_clause.c:998 #, c-format msgid "tablesample method %s does not support REPEATABLE" msgstr "表采样方法%s䏿”¯æŒREPEATABLE" -#: parser/parse_clause.c:940 +#: parser/parse_clause.c:1168 #, c-format msgid "TABLESAMPLE clause can only be applied to tables and materialized views" msgstr "TABLESAMPLEå­å¥åªèƒ½è¢«åº”用于表和物化视图" -#: parser/parse_clause.c:1110 +#: parser/parse_clause.c:1338 #, c-format msgid "column name \"%s\" appears more than once in USING clause" msgstr "在 USING å­å¥ä¸­å­—段å \"%s\" 出现多次" -#: parser/parse_clause.c:1125 +#: parser/parse_clause.c:1353 #, c-format msgid "common column name \"%s\" appears more than once in left table" msgstr "å…±åŒçš„字段å \"%s\" 在左边的表中出现了多次" -#: parser/parse_clause.c:1134 +#: parser/parse_clause.c:1362 #, c-format msgid "column \"%s\" specified in USING clause does not exist in left table" msgstr "USING å­å¥ä¸­æŒ‡å®šçš„字段 \"%s\" 在左边的表中ä¸å­˜åœ¨" -#: parser/parse_clause.c:1148 +#: parser/parse_clause.c:1376 #, c-format msgid "common column name \"%s\" appears more than once in right table" msgstr "å…±åŒçš„字段å \"%s\" 在å³è¾¹çš„表中出现了多次" -#: parser/parse_clause.c:1157 +#: parser/parse_clause.c:1385 #, c-format msgid "column \"%s\" specified in USING clause does not exist in right table" msgstr "USING å­å¥ä¸­æŒ‡å®šçš„字段 \"%s\" 在å³è¾¹çš„表中ä¸å­˜åœ¨" -#: parser/parse_clause.c:1211 +#: parser/parse_clause.c:1439 #, c-format msgid "column alias list for \"%s\" has too many entries" msgstr "\"%s\" 的字段别å列表有太多记录" #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_clause.c:1520 +#: parser/parse_clause.c:1748 #, c-format msgid "argument of %s must not contain variables" msgstr "%s çš„å‚æ•°ä¸èƒ½åŒ…å«å˜é‡" #. translator: first %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1685 +#: parser/parse_clause.c:1913 #, c-format msgid "%s \"%s\" is ambiguous" msgstr "%s \"%s\" æ˜¯ä¸æ˜Žç¡®çš„" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1714 +#: parser/parse_clause.c:1942 #, c-format msgid "non-integer constant in %s" msgstr "在 %s ä¸­çš„éžæ•´æ•°å¸¸é‡" #. translator: %s is name of a SQL construct, eg ORDER BY -#: parser/parse_clause.c:1736 +#: parser/parse_clause.c:1964 #, c-format msgid "%s position %d is not in select list" msgstr "%s ä½ç½®%dä¸åœ¨select列表中." -#: parser/parse_clause.c:2178 +#: parser/parse_clause.c:2405 #, c-format msgid "CUBE is limited to 12 elements" msgstr "CUBE被é™åˆ¶ä¸º12个元素" -#: parser/parse_clause.c:2384 +#: parser/parse_clause.c:2611 #, c-format msgid "window \"%s\" is already defined" msgstr "å·²ç»å®šä¹‰çª—å£\"%s\"" -#: parser/parse_clause.c:2446 +#: parser/parse_clause.c:2672 #, c-format msgid "cannot override PARTITION BY clause of window \"%s\"" msgstr "无法覆盖窗å£\"%s\"çš„PARTITION BYå­å¥" -#: parser/parse_clause.c:2458 +#: parser/parse_clause.c:2684 #, c-format msgid "cannot override ORDER BY clause of window \"%s\"" msgstr "æ— æ³•è¦†ç›–çª—å£ \"%s\"çš„ORDER BYå­å¥" -#: parser/parse_clause.c:2488 parser/parse_clause.c:2494 +#: parser/parse_clause.c:2714 parser/parse_clause.c:2720 #, c-format msgid "cannot copy window \"%s\" because it has a frame clause" msgstr "因为已有frameå­å¥ï¼Œæ— æ³•å¤åˆ¶çª—å£\"%s\"" -#: parser/parse_clause.c:2496 +#: parser/parse_clause.c:2722 #, c-format msgid "Omit the parentheses in this OVER clause." msgstr "在这个 OVER å­å¥é‡Œå¿½ç•¥å…¶çˆ¶è¯­å¥." -#: parser/parse_clause.c:2562 +#: parser/parse_clause.c:2742 #, c-format -msgid "" -"in an aggregate with DISTINCT, ORDER BY expressions must appear in argument " -"list" -msgstr "" -"在带有DISTINCTå­å¥çš„èšåˆå‡½æ•°ä¸­ï¼ŒORDER BYå­å¥åŽé¢çš„表达å¼å¿…é¡»åœ¨å‚æ•°åˆ—表中出现" +msgid "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column" +msgstr "åç§»é‡PRECEDING/FOLLOWING的范围åªéœ€è¦ä¸€ä¸ªæŒ‰åˆ—排åº" -#: parser/parse_clause.c:2563 +#: parser/parse_clause.c:2765 +#, c-format +msgid "GROUPS mode requires an ORDER BY clause" +msgstr "GROUPS模å¼éœ€è¦ä¸€ä¸ªORDER BYå­å¥" + +#: parser/parse_clause.c:2835 +#, c-format +msgid "in an aggregate with DISTINCT, ORDER BY expressions must appear in argument list" +msgstr "在带有DISTINCTå­å¥çš„èšåˆå‡½æ•°ä¸­ï¼ŒORDER BYå­å¥åŽé¢çš„表达å¼å¿…é¡»åœ¨å‚æ•°åˆ—表中出现" + +#: parser/parse_clause.c:2836 #, c-format msgid "for SELECT DISTINCT, ORDER BY expressions must appear in select list" msgstr "在查询列表中必须出现SELECT DISTINCT, ORDER BY表达å¼" -#: parser/parse_clause.c:2596 +#: parser/parse_clause.c:2868 #, c-format msgid "an aggregate with DISTINCT must have at least one argument" msgstr "带有DISTINCT关键字的èšåˆå‡½æ•°å¿…é¡»è‡³å°‘æœ‰ä¸€ä¸ªå‚æ•°" -#: parser/parse_clause.c:2597 +#: parser/parse_clause.c:2869 #, c-format msgid "SELECT DISTINCT must have at least one column" msgstr "SELECT DISTINCT 至少拥有一列" -#: parser/parse_clause.c:2663 parser/parse_clause.c:2695 +#: parser/parse_clause.c:2935 parser/parse_clause.c:2967 #, c-format msgid "SELECT DISTINCT ON expressions must match initial ORDER BY expressions" msgstr "表达å¼SELECT DISTINCT ON必须匹é…åˆå§‹åŒ–çš„ORDER BY表达å¼" -#: parser/parse_clause.c:2774 +#: parser/parse_clause.c:3045 #, c-format msgid "ASC/DESC is not allowed in ON CONFLICT clause" msgstr "ON CONFLICTå­å¥ä¸­ä¸å…许ASC/DESC" -#: parser/parse_clause.c:2780 +#: parser/parse_clause.c:3051 #, c-format msgid "NULLS FIRST/LAST is not allowed in ON CONFLICT clause" msgstr "ON CONFLICTå­å¥ä¸­ä¸å…许NULLS FIRST/LAST" -#: parser/parse_clause.c:2860 +#: parser/parse_clause.c:3130 #, c-format -msgid "" -"ON CONFLICT DO UPDATE requires inference specification or constraint name" +msgid "ON CONFLICT DO UPDATE requires inference specification or constraint name" msgstr "ON CONFLICT DO UPDATEéœ€è¦æŽ¨ç†è§„范或者约æŸåç§°" -#: parser/parse_clause.c:2861 +#: parser/parse_clause.c:3131 #, c-format msgid "For example, ON CONFLICT (column_name)." msgstr "例如:ON CONFLICT (column_name)。" -#: parser/parse_clause.c:2872 +#: parser/parse_clause.c:3142 #, c-format msgid "ON CONFLICT is not supported with system catalog tables" msgstr "ç³»ç»Ÿç›®å½•è¡¨ä¸æ”¯æŒON CONFLICT" -#: parser/parse_clause.c:2880 +#: parser/parse_clause.c:3150 #, c-format msgid "ON CONFLICT is not supported on table \"%s\" used as a catalog table" msgstr "在用作目录表的表\"%s\"ä¸Šä¸æ”¯æŒON CONFLICT" -#: parser/parse_clause.c:3012 +#: parser/parse_clause.c:3293 #, c-format msgid "operator %s is not a valid ordering operator" msgstr "æ“作符%s䏿—¶æœ‰æ•ˆçš„æŽ’åºæ“作符" -#: parser/parse_clause.c:3014 +#: parser/parse_clause.c:3295 #, c-format -msgid "" -"Ordering operators must be \"<\" or \">\" members of btree operator families." +msgid "Ordering operators must be \"<\" or \">\" members of btree operator families." msgstr "é¡ºåºæ“作符必须是btreeæ“作符家æ—çš„æˆå‘˜\"<\"或\">\"." -#: parser/parse_coerce.c:971 parser/parse_coerce.c:1001 -#: parser/parse_coerce.c:1019 parser/parse_coerce.c:1034 -#: parser/parse_expr.c:2015 parser/parse_expr.c:2528 parser/parse_target.c:874 +#: parser/parse_clause.c:3606 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s" +msgstr "列类型 %s䏿”¯æŒåç§»é‡PRECEDING/FOLLOWING的范围" + +#: parser/parse_clause.c:3612 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING is not supported for column type %s and offset type %s" +msgstr "对于列类型%så’Œåç§»é‡ç±»åž‹%sï¼Œä¸æ”¯æŒåç§»é‡åœ¨PRECEDING/FOLLOWING的范围" + +#: parser/parse_clause.c:3615 +#, c-format +msgid "Cast the offset value to an appropriate type." +msgstr "å°†å移值强制转æ¢ä¸ºé€‚当的类型." + +#: parser/parse_clause.c:3620 +#, c-format +msgid "RANGE with offset PRECEDING/FOLLOWING has multiple interpretations for column type %s and offset type %s" +msgstr "åç§»é‡åœ¨PRECEDING/FOLLOWING的范围对列类型%så’Œåç§»é‡ç±»åž‹%s有多个解释" + +#: parser/parse_clause.c:3623 +#, c-format +msgid "Cast the offset value to the exact intended type." +msgstr "å°†å移值强制转æ¢ä¸ºå‡†ç¡®çš„预期类型." + +#: parser/parse_coerce.c:1022 parser/parse_coerce.c:1060 +#: parser/parse_coerce.c:1078 parser/parse_coerce.c:1093 +#: parser/parse_expr.c:2235 parser/parse_expr.c:2823 parser/parse_target.c:962 #, c-format msgid "cannot cast type %s to %s" msgstr "无法把类型 %s 转æ¢ä¸º %s" -#: parser/parse_coerce.c:1004 +#: parser/parse_coerce.c:1063 #, c-format msgid "Input has too few columns." msgstr "输入字段太少" -#: parser/parse_coerce.c:1022 +#: parser/parse_coerce.c:1081 #, c-format msgid "Cannot cast type %s to %s in column %d." msgstr "ä¸èƒ½æŠŠç¬¬ %3$d 个字段的类型 %1$s 转æ¢ä¸º %2$s." -#: parser/parse_coerce.c:1037 +#: parser/parse_coerce.c:1096 #, c-format msgid "Input has too many columns." msgstr "输入字段太多" #. translator: first %s is name of a SQL construct, eg WHERE -#: parser/parse_coerce.c:1080 +#. translator: first %s is name of a SQL construct, eg LIMIT +#: parser/parse_coerce.c:1151 parser/parse_coerce.c:1199 #, c-format -msgid "argument of %s must be type boolean, not type %s" -msgstr "%s çš„å‚æ•°å¿…需是布尔类型, è€Œä¸æ˜¯ %s 类型" +msgid "argument of %s must be type %s, not type %s" +msgstr "%s çš„å‚æ•°å¿…需是类型%s, è€Œä¸æ˜¯ç±»åž‹%s " #. translator: %s is name of a SQL construct, eg WHERE #. translator: %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1090 parser/parse_coerce.c:1139 +#: parser/parse_coerce.c:1162 parser/parse_coerce.c:1211 #, c-format msgid "argument of %s must not return a set" msgstr "%s çš„å‚æ•°ä¸èƒ½è¿”回一个组åˆ" -#. translator: first %s is name of a SQL construct, eg LIMIT -#: parser/parse_coerce.c:1127 -#, c-format -msgid "argument of %s must be type %s, not type %s" -msgstr "%s çš„å‚æ•°å¿…需是类型%s, è€Œä¸æ˜¯ç±»åž‹%s " - #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1260 +#: parser/parse_coerce.c:1351 #, c-format msgid "%s types %s and %s cannot be matched" msgstr "%s 的类型 %s å’Œ %s ä¸åŒ¹é…" #. translator: first %s is name of a SQL construct, eg CASE -#: parser/parse_coerce.c:1327 +#: parser/parse_coerce.c:1418 #, c-format msgid "%s could not convert type %s to %s" msgstr "%s 无法转æ¢ç±»åž‹ %s 为 %s" -#: parser/parse_coerce.c:1629 +#: parser/parse_coerce.c:1720 #, c-format msgid "arguments declared \"anyelement\" are not all alike" msgstr "傿•°å£°æ˜Žçš„ \"anyelement\" ä¸å…¨ç›¸åŒ" -#: parser/parse_coerce.c:1649 +#: parser/parse_coerce.c:1740 #, c-format msgid "arguments declared \"anyarray\" are not all alike" msgstr "傿•°å£°æ˜Žçš„ \"anyarray\" ä¸å…¨ç›¸åŒ" -#: parser/parse_coerce.c:1669 +#: parser/parse_coerce.c:1760 #, c-format msgid "arguments declared \"anyrange\" are not all alike" msgstr "声明为 \"anyarray\" çš„å‚æ•°ä¸å…¨ç›¸åŒ" -#: parser/parse_coerce.c:1698 parser/parse_coerce.c:1909 -#: parser/parse_coerce.c:1943 +#: parser/parse_coerce.c:1789 parser/parse_coerce.c:2004 +#: parser/parse_coerce.c:2038 #, c-format -msgid "argument declared \"anyarray\" is not an array but type %s" -msgstr "傿•°å£°æ˜Žçš„ \"anyarray\" 䏿˜¯ä¸€ä¸ªæ•°ç»„, 但是类型为 %s" +msgid "argument declared %s is not an array but type %s" +msgstr "傿•°å£°æ˜Ž%s䏿˜¯ä¸€ä¸ªæ•°ç»„, 但是类型为 %s" -#: parser/parse_coerce.c:1714 +#: parser/parse_coerce.c:1805 parser/parse_coerce.c:1844 #, c-format -msgid "" -"argument declared \"anyarray\" is not consistent with argument declared " -"\"anyelement\"" -msgstr "傿•°å£°æ˜Žçš„ \"anyarray\" å’Œå‚æ•°å£°æ˜Žçš„ \"anyelement\" ä¸ä¸€è‡´" - -#: parser/parse_coerce.c:1735 parser/parse_coerce.c:1956 -#, c-format -msgid "argument declared \"anyrange\" is not a range type but type %s" -msgstr "声明为 \"anyarray\" çš„å‚æ•°çš„ç±»åž‹ä¸æ˜¯èŒƒå›´ç±»åž‹, 其类型为 %s" +msgid "argument declared %s is not consistent with argument declared %s" +msgstr "傿•°å£°æ˜Ž%s å’Œå‚æ•°å£°æ˜Ž%s ä¸ä¸€è‡´" -#: parser/parse_coerce.c:1751 +#: parser/parse_coerce.c:1827 parser/parse_coerce.c:2051 #, c-format -msgid "" -"argument declared \"anyrange\" is not consistent with argument declared " -"\"anyelement\"" -msgstr "声明为 \"anyarray\" çš„å‚æ•°å’Œå£°æ˜Žä¸º \"anyelement\"çš„å‚æ•° ä¸ä¸€è‡´" +msgid "argument declared %s is not a range type but type %s" +msgstr "声明为%sçš„å‚æ•°çš„ç±»åž‹ä¸æ˜¯èŒƒå›´ç±»åž‹, 其类型为 %s" -#: parser/parse_coerce.c:1771 +#: parser/parse_coerce.c:1865 #, c-format -msgid "could not determine polymorphic type because input has type \"unknown\"" -msgstr "无法确定多æ€ç±»åž‹, 因为输入类型为 \"unknown\"" +msgid "could not determine polymorphic type because input has type %s" +msgstr "无法确定多æ€ç±»åž‹, 因为输入类型为%s" -#: parser/parse_coerce.c:1781 +#: parser/parse_coerce.c:1876 #, c-format msgid "type matched to anynonarray is an array type: %s" msgstr "与anynonarray匹é…的类型是一个数组类型:%s" -#: parser/parse_coerce.c:1791 +#: parser/parse_coerce.c:1886 #, c-format msgid "type matched to anyenum is not an enum type: %s" msgstr "匹é…anyenumçš„ç±»åž‹ä¸æ˜¯æžšä¸¾ç±»åž‹:%s" -#: parser/parse_coerce.c:1831 parser/parse_coerce.c:1861 +#: parser/parse_coerce.c:1926 parser/parse_coerce.c:1956 #, c-format msgid "could not find range type for data type %s" msgstr "无法为数æ®ç±»åž‹ %s 找到范围类型" #: parser/parse_collate.c:228 parser/parse_collate.c:475 -#: parser/parse_collate.c:986 +#: parser/parse_collate.c:981 #, c-format msgid "collation mismatch between implicit collations \"%s\" and \"%s\"" msgstr "排åºå:\"%s\" å’Œ \"%s\"之间的排åºè§„则ä¸åŒ¹é…" #: parser/parse_collate.c:231 parser/parse_collate.c:478 -#: parser/parse_collate.c:989 +#: parser/parse_collate.c:984 #, c-format -msgid "" -"You can choose the collation by applying the COLLATE clause to one or both " -"expressions." +msgid "You can choose the collation by applying the COLLATE clause to one or both expressions." msgstr "通过对一个或两个表达å¼åº”用 COLLATE å­å¥æ¥é€‰æ‹©æŽ’åºè§„则." -#: parser/parse_collate.c:834 +#: parser/parse_collate.c:831 #, c-format msgid "collation mismatch between explicit collations \"%s\" and \"%s\"" msgstr "排åºå:\"%s\" å’Œ \"%s\"之间的排åºè§„则ä¸åŒ¹é…" #: parser/parse_cte.c:42 #, c-format -msgid "" -"recursive reference to query \"%s\" must not appear within its non-recursive " -"term" +msgid "recursive reference to query \"%s\" must not appear within its non-recursive term" msgstr "对查询 \"%s\" 的递归引用ä¸èƒ½å‡ºçŽ°åœ¨å®ƒçš„éžé€’å½’å½¢å¼ä¸­" #: parser/parse_cte.c:44 @@ -13754,8 +14834,7 @@ msgstr "对查询 \"%s\" 的递归引用ä¸èƒ½å‡ºçŽ°åœ¨å­æŸ¥è¯¢ä¸­" #: parser/parse_cte.c:46 #, c-format -msgid "" -"recursive reference to query \"%s\" must not appear within an outer join" +msgid "recursive reference to query \"%s\" must not appear within an outer join" msgstr "对查询 \"%s\" 的递归引用ä¸èƒ½å‡ºçŽ°åœ¨å¤–è¿žæŽ¥ä¸­" #: parser/parse_cte.c:48 @@ -13775,15 +14854,12 @@ msgstr "WITH 查询å\"%s\" 被指定多次" #: parser/parse_cte.c:264 #, c-format -msgid "" -"WITH clause containing a data-modifying statement must be at the top level" +msgid "WITH clause containing a data-modifying statement must be at the top level" msgstr "包å«ä¿®æ”¹æ•°æ®çš„WITHå­å¥åªèƒ½åœ¨æœ€ä¸Šå±‚出现" #: parser/parse_cte.c:313 #, c-format -msgid "" -"recursive query \"%s\" column %d has type %s in non-recursive term but type " -"%s overall" +msgid "recursive query \"%s\" column %d has type %s in non-recursive term but type %s overall" msgstr "递归查询\"%s\"的列%d在éžé€’归术语中的类型是%s,但是全部类型都是%s" #: parser/parse_cte.c:319 @@ -13793,483 +14869,703 @@ msgstr "å°†éžé€’归术语的输出指派为正确的类型" #: parser/parse_cte.c:324 #, c-format -msgid "" -"recursive query \"%s\" column %d has collation \"%s\" in non-recursive term " -"but collation \"%s\" overall" -msgstr "" -"递归查询\"%s\"的列%d在éžé€’归术语中应有排åºè§„则\"%s\",但是其排åºè§„则都是%s" +msgid "recursive query \"%s\" column %d has collation \"%s\" in non-recursive term but collation \"%s\" overall" +msgstr "递归查询\"%s\"的列%d在éžé€’归术语中应有排åºè§„则\"%s\",但是其排åºè§„则都是%s" #: parser/parse_cte.c:328 #, c-format msgid "Use the COLLATE clause to set the collation of the non-recursive term." msgstr "使用COLLATEå­å¥è®¾ç½®éžé€’归项的排åºè§„则." -#: parser/parse_cte.c:419 +#: parser/parse_cte.c:418 #, c-format msgid "WITH query \"%s\" has %d columns available but %d columns specified" msgstr "WITH 查询\"%s\"有%d个有效字段, ä½†åªæŒ‡å®šäº†%d个字段" -#: parser/parse_cte.c:599 +#: parser/parse_cte.c:598 #, c-format msgid "mutual recursion between WITH items is not implemented" msgstr "没有实现在WITHæˆå‘˜ä¹‹é—´çš„相互递归引用" -#: parser/parse_cte.c:651 +#: parser/parse_cte.c:650 #, c-format msgid "recursive query \"%s\" must not contain data-modifying statements" msgstr "递归查询 \"%s\" ä¸èƒ½åŒ…嫿•°æ®ä¿®æ”¹è¯­å¥" -#: parser/parse_cte.c:659 +#: parser/parse_cte.c:658 #, c-format -msgid "" -"recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] " -"recursive-term" +msgid "recursive query \"%s\" does not have the form non-recursive-term UNION [ALL] recursive-term" msgstr "递归查询\"%s\"没有éžé€’归术语UNION [ALL]递归术语这ç§å½¢å¼" -#: parser/parse_cte.c:703 +#: parser/parse_cte.c:702 #, c-format msgid "ORDER BY in a recursive query is not implemented" msgstr "在递归查询中没有实现ORDER BY " -#: parser/parse_cte.c:709 +#: parser/parse_cte.c:708 #, c-format msgid "OFFSET in a recursive query is not implemented" msgstr "在递归查询终未实现OFFSET" -#: parser/parse_cte.c:715 +#: parser/parse_cte.c:714 #, c-format msgid "LIMIT in a recursive query is not implemented" msgstr "在递归查询终的未实现LIMIT" -#: parser/parse_cte.c:721 +#: parser/parse_cte.c:720 #, c-format msgid "FOR UPDATE/SHARE in a recursive query is not implemented" msgstr "在递归查询中没有实现FOR UPDATE/SHARE " -#: parser/parse_cte.c:778 +#: parser/parse_cte.c:777 #, c-format msgid "recursive reference to query \"%s\" must not appear more than once" msgstr "对查询\"%s\"的递归引用ä¸èƒ½å‡ºçŽ°å¤šæ¬¡" -#: parser/parse_expr.c:387 parser/parse_relation.c:3083 -#: parser/parse_relation.c:3103 +#: parser/parse_expr.c:349 +#, c-format +msgid "DEFAULT is not allowed in this context" +msgstr "此上下文中ä¸å…许使用默认值" + +#: parser/parse_expr.c:402 parser/parse_relation.c:3352 +#: parser/parse_relation.c:3372 #, c-format msgid "column %s.%s does not exist" msgstr "字段 %s.%s ä¸å­˜åœ¨" -#: parser/parse_expr.c:399 +#: parser/parse_expr.c:414 #, c-format msgid "column \"%s\" not found in data type %s" msgstr "在数æ®ç±»åž‹ %2$s 中未找到字段 \"%1$s\"" -#: parser/parse_expr.c:405 +#: parser/parse_expr.c:420 #, c-format msgid "could not identify column \"%s\" in record data type" msgstr "在记录数æ®ç±»åž‹ä¸­æ— æ³•确认字段 \"%s\"" -#: parser/parse_expr.c:411 +#: parser/parse_expr.c:426 #, c-format msgid "column notation .%s applied to type %s, which is not a composite type" msgstr "将列符å·.%s应用到类型%s(è¿™ä¸ªç±»åž‹ä¸æ˜¯ç»„åˆç±»åž‹)" -#: parser/parse_expr.c:441 parser/parse_target.c:660 +#: parser/parse_expr.c:457 parser/parse_target.c:729 #, c-format msgid "row expansion via \"*\" is not supported here" msgstr "䏿”¯æŒé€šè¿‡\"*\"实现的记录扩展" -#: parser/parse_expr.c:767 parser/parse_relation.c:667 -#: parser/parse_relation.c:767 parser/parse_target.c:1109 +#: parser/parse_expr.c:578 +#, fuzzy +#| msgid "cannot use column references in default expression" +msgid "cannot use column reference in DEFAULT expression" +msgstr "在默认的表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­—段关è”" + +#: parser/parse_expr.c:581 +#, fuzzy +#| msgid "cannot drop column referenced in partition key expression" +msgid "cannot use column reference in partition bound expression" +msgstr "无法删除分区键表达å¼ä¸­å¼•用的列" + +#: parser/parse_expr.c:844 parser/parse_relation.c:692 +#: parser/parse_relation.c:803 parser/parse_target.c:1200 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "å­—æ®µå…³è” \"%s\" æ˜¯ä¸æ˜Žç¡®çš„" -#: parser/parse_expr.c:823 parser/parse_param.c:110 parser/parse_param.c:142 +#: parser/parse_expr.c:900 parser/parse_param.c:110 parser/parse_param.c:142 #: parser/parse_param.c:199 parser/parse_param.c:298 #, c-format msgid "there is no parameter $%d" msgstr "æ²¡æœ‰å‚æ•° $%d" -#: parser/parse_expr.c:1034 +#: parser/parse_expr.c:1143 #, c-format msgid "NULLIF requires = operator to yield boolean" msgstr "在NULLIFæ“作中需è¦ç­‰å·æ“作符æ¥äº§ç”Ÿå¸ƒå°”类型的返回值" -#: parser/parse_expr.c:1697 +#. translator: %s is name of a SQL construct, eg NULLIF +#: parser/parse_expr.c:1149 parser/parse_expr.c:3139 +#, c-format +msgid "%s must not return a set" +msgstr "%s ä¸èƒ½è¿”回一个组åˆ" + +#: parser/parse_expr.c:1597 parser/parse_expr.c:1629 +#, c-format +msgid "number of columns does not match number of values" +msgstr "列的数é‡ä¸Žå€¼çš„æ•°é‡ä¸åŒ¹é…" + +#: parser/parse_expr.c:1643 +#, c-format +msgid "source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression" +msgstr "多列更新项的æºå¿…须是sub-SELECT或 ROW()表达å¼" + +#. translator: %s is name of a SQL construct, eg GROUP BY +#: parser/parse_expr.c:1837 parser/parse_expr.c:2326 parser/parse_func.c:2550 +#, c-format +msgid "set-returning functions are not allowed in %s" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在%s中" + +#: parser/parse_expr.c:1898 msgid "cannot use subquery in check constraint" msgstr "在检查约æŸä¸­ä¸å¯ä»¥ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1701 +#: parser/parse_expr.c:1902 msgid "cannot use subquery in DEFAULT expression" msgstr "DEFAULT表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1704 +#: parser/parse_expr.c:1905 msgid "cannot use subquery in index expression" msgstr "索引表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1707 +#: parser/parse_expr.c:1908 msgid "cannot use subquery in index predicate" msgstr "索引声明中ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1710 +#: parser/parse_expr.c:1911 msgid "cannot use subquery in transform expression" msgstr "在转æ¢è¡¨è¾¾å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1713 +#: parser/parse_expr.c:1914 msgid "cannot use subquery in EXECUTE parameter" msgstr "在 EXECUTE 傿•°ä¸­ä¸å¯ä»¥ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1716 +#: parser/parse_expr.c:1917 msgid "cannot use subquery in trigger WHEN condition" msgstr "在触å‘器的WHENæ¡ä»¶ä¸­æ— æ³•ä½¿ç”¨å­æŸ¥è¯¢" -#: parser/parse_expr.c:1770 +#: parser/parse_expr.c:1920 +#, fuzzy +#| msgid "cannot use subquery in partition key expression" +msgid "cannot use subquery in partition bound" +msgstr "分区键表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" + +#: parser/parse_expr.c:1923 +msgid "cannot use subquery in partition key expression" +msgstr "分区键表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" + +#: parser/parse_expr.c:1926 +msgid "cannot use subquery in CALL argument" +msgstr "在 CALL 傿•°ä¸­ä¸å¯ä»¥ä½¿ç”¨å­æŸ¥è¯¢" + +#: parser/parse_expr.c:1929 +#, fuzzy +#| msgid "cannot use subquery in trigger WHEN condition" +msgid "cannot use subquery in COPY FROM WHERE condition" +msgstr "在触å‘器的WHENæ¡ä»¶ä¸­æ— æ³•ä½¿ç”¨å­æŸ¥è¯¢" + +#: parser/parse_expr.c:1932 +#, fuzzy +#| msgid "cannot use subquery in index expression" +msgid "cannot use subquery in column generation expression" +msgstr "索引表达å¼ä¸­ä¸èƒ½ä½¿ç”¨å­æŸ¥è¯¢" + +#: parser/parse_expr.c:1985 #, c-format msgid "subquery must return only one column" msgstr "å­æŸ¥è¯¢å¿…é¡»åªèƒ½è¿”回一个字段" -#: parser/parse_expr.c:1854 +#: parser/parse_expr.c:2069 #, c-format msgid "subquery has too many columns" msgstr "å­æŸ¥è¯¢æœ‰å¤ªå¤šçš„字段" -#: parser/parse_expr.c:1859 +#: parser/parse_expr.c:2074 #, c-format msgid "subquery has too few columns" msgstr "å­æŸ¥è¯¢å­—段太少" -#: parser/parse_expr.c:1955 +#: parser/parse_expr.c:2175 #, c-format msgid "cannot determine type of empty array" msgstr "无法确定空数组的类型" -#: parser/parse_expr.c:1956 +#: parser/parse_expr.c:2176 #, c-format msgid "Explicitly cast to the desired type, for example ARRAY[]::integer[]." msgstr "显å¼åœ°å°†å€¼æŒ‡æ´¾ä¸ºæœŸæœ›ç±»åž‹,例如ARRAY[]::integer[]." -#: parser/parse_expr.c:1970 +#: parser/parse_expr.c:2190 #, c-format msgid "could not find element type for data type %s" msgstr "无法为数æ®ç±»åž‹%s找到æˆå‘˜ç±»åž‹" -#: parser/parse_expr.c:2193 +#: parser/parse_expr.c:2477 #, c-format msgid "unnamed XML attribute value must be a column reference" msgstr "未命åçš„XML属性值必须是一个列引用" -#: parser/parse_expr.c:2194 +#: parser/parse_expr.c:2478 #, c-format msgid "unnamed XML element value must be a column reference" msgstr "未命åçš„XMLæˆå‘˜å€¼å¿…须是一个列引用" -#: parser/parse_expr.c:2209 +#: parser/parse_expr.c:2493 #, c-format msgid "XML attribute name \"%s\" appears more than once" msgstr "XML属性åç§°\"%s\"出现多次" -#: parser/parse_expr.c:2316 +#: parser/parse_expr.c:2600 #, c-format msgid "cannot cast XMLSERIALIZE result to %s" msgstr "无法把XMLSERIALIZE强制转æ¢ä¸º%s" -#: parser/parse_expr.c:2601 parser/parse_expr.c:2797 +#: parser/parse_expr.c:2896 parser/parse_expr.c:3092 #, c-format msgid "unequal number of entries in row expressions" msgstr "在记录表达å¼ä¸­ï¼Œé¡¹çš„æ•°é‡ä¸ç›¸ç­‰" -#: parser/parse_expr.c:2611 +#: parser/parse_expr.c:2906 #, c-format msgid "cannot compare rows of zero length" msgstr "无法比较零长度的记录" -#: parser/parse_expr.c:2636 +#: parser/parse_expr.c:2931 #, c-format msgid "row comparison operator must yield type boolean, not type %s" msgstr "行比较æ“作符必需返回布尔类型, è€Œä¸æ˜¯ç±»åž‹%s" -#: parser/parse_expr.c:2643 +#: parser/parse_expr.c:2938 #, c-format msgid "row comparison operator must not return a set" msgstr "行比较æ“作符ä¸èƒ½è¿”回一个集åˆ" -#: parser/parse_expr.c:2702 parser/parse_expr.c:2743 +#: parser/parse_expr.c:2997 parser/parse_expr.c:3038 #, c-format msgid "could not determine interpretation of row comparison operator %s" msgstr "无法确定行比较æ“作符%s的说明" -#: parser/parse_expr.c:2704 +#: parser/parse_expr.c:2999 #, c-format -msgid "" -"Row comparison operators must be associated with btree operator families." +msgid "Row comparison operators must be associated with btree operator families." msgstr "记录比较表达å¼å¿…须与btreeæ“作符相关è”." -#: parser/parse_expr.c:2745 +#: parser/parse_expr.c:3040 #, c-format msgid "There are multiple equally-plausible candidates." msgstr "有多个相等的类似候选." -#: parser/parse_expr.c:2837 +#: parser/parse_expr.c:3133 #, c-format msgid "IS DISTINCT FROM requires = operator to yield boolean" msgstr "IS DISTINCT FROMæ“作中需è¦ç­‰å·æ¥äº§ç”Ÿå¸ƒå°”类型的值" -#: parser/parse_expr.c:3127 parser/parse_expr.c:3145 +#: parser/parse_expr.c:3452 parser/parse_expr.c:3470 #, c-format msgid "operator precedence change: %s is now lower precedence than %s" msgstr "æ“作符优先级改å˜ï¼š%s现在比%s的优先级低" -#: parser/parse_func.c:174 +#: parser/parse_func.c:195 #, c-format msgid "argument name \"%s\" used more than once" msgstr "傿•°åç§°\"%s\"被使用多次" -#: parser/parse_func.c:185 +#: parser/parse_func.c:206 #, c-format msgid "positional argument cannot follow named argument" msgstr "已确定ä½ç½®çš„傿•°ä¸èƒ½åœ¨å·²å‘½å傿•°çš„åŽé¢" -#: parser/parse_func.c:270 +#: parser/parse_func.c:288 parser/parse_func.c:2253 +#, c-format +msgid "%s is not a procedure" +msgstr "%s 䏿˜¯è¿‡ç¨‹" + +#: parser/parse_func.c:292 +#, c-format +msgid "To call a function, use SELECT." +msgstr "è¦è°ƒç”¨å‡½æ•°ï¼Œè¯·ä½¿ç”¨SELECT." + +#: parser/parse_func.c:298 +#, c-format +msgid "%s is a procedure" +msgstr "%s 是一个过程" + +#: parser/parse_func.c:302 +#, c-format +msgid "To call a procedure, use CALL." +msgstr "è¦è°ƒç”¨è¿‡ç¨‹ï¼Œè¯·ä½¿ç”¨CALL" + +#: parser/parse_func.c:316 #, c-format msgid "%s(*) specified, but %s is not an aggregate function" msgstr "指定了 %s(*), 但是 %s 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_func.c:277 +#: parser/parse_func.c:323 #, c-format msgid "DISTINCT specified, but %s is not an aggregate function" msgstr "指定了 DISTINCT, 但是 %s 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_func.c:283 +#: parser/parse_func.c:329 #, c-format msgid "WITHIN GROUP specified, but %s is not an aggregate function" msgstr "指定了 WITHIN GROUP , 但是 %s 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_func.c:289 +#: parser/parse_func.c:335 #, c-format msgid "ORDER BY specified, but %s is not an aggregate function" msgstr "指定了ORDER BY语å¥, 但是%s䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_func.c:295 +#: parser/parse_func.c:341 #, c-format msgid "FILTER specified, but %s is not an aggregate function" msgstr "FILTER指定了, 但是 %s 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_func.c:301 +#: parser/parse_func.c:347 #, c-format -msgid "" -"OVER specified, but %s is not a window function nor an aggregate function" +msgid "OVER specified, but %s is not a window function nor an aggregate function" msgstr "指定了OVER关键字,但是%s䏿˜¯çª—å£å‡½æ•°æˆ–èšåˆå‡½æ•°" -#: parser/parse_func.c:331 +#: parser/parse_func.c:385 #, c-format msgid "WITHIN GROUP is required for ordered-set aggregate %s" msgstr "WITHIN GROUP在有åºèšé›†å‡½æ•° %s中是必需的" -#: parser/parse_func.c:337 +#: parser/parse_func.c:391 #, c-format msgid "OVER is not supported for ordered-set aggregate %s" msgstr "OVERä¸èƒ½ç”¨äºŽæœ‰åºèšé›†å‡½æ•° %s中" -#: parser/parse_func.c:368 parser/parse_func.c:397 +#: parser/parse_func.c:422 parser/parse_func.c:451 #, c-format -msgid "" -"There is an ordered-set aggregate %s, but it requires %d direct arguments, " -"not %d." +msgid "There is an ordered-set aggregate %s, but it requires %d direct arguments, not %d." msgstr "存在有åºèšé›†å‡½æ•° %s, å®ƒéœ€è¦ %d ä¸ªç›´æŽ¥å‚æ•°, 䏿˜¯ %d个." -#: parser/parse_func.c:422 +#: parser/parse_func.c:476 #, c-format -msgid "" -"To use the hypothetical-set aggregate %s, the number of hypothetical direct " -"arguments (here %d) must match the number of ordering columns (here %d)." -msgstr "" -"使用判定集èšé›†å‡½æ•° %s, ç›´æŽ¥å‚æ•°çš„个数 (这里是 %d) 必须与有åºåˆ—çš„æ•°ç›®ç›¸åŒ¹é… " -"(这里是 %d)." +msgid "To use the hypothetical-set aggregate %s, the number of hypothetical direct arguments (here %d) must match the number of ordering columns (here %d)." +msgstr "使用判定集èšé›†å‡½æ•° %s, ç›´æŽ¥å‚æ•°çš„个数 (这里是 %d) 必须与有åºåˆ—çš„æ•°ç›®ç›¸åŒ¹é… (这里是 %d)." -#: parser/parse_func.c:436 +#: parser/parse_func.c:490 #, c-format -msgid "" -"There is an ordered-set aggregate %s, but it requires at least %d direct " -"arguments." +msgid "There is an ordered-set aggregate %s, but it requires at least %d direct arguments." msgstr "存在有åºé›†èšé›†å‡½æ•°%s, 它至少需è¦%dä¸ªç›´æŽ¥å‚æ•°." -#: parser/parse_func.c:455 +#: parser/parse_func.c:509 #, c-format msgid "%s is not an ordered-set aggregate, so it cannot have WITHIN GROUP" msgstr "%s 䏿˜¯æœ‰åºé›†èšé›†å‡½æ•°, 因此它ä¸èƒ½ä½¿ç”¨ WITHIN GROUP" -#: parser/parse_func.c:468 +#: parser/parse_func.c:522 #, c-format msgid "window function %s requires an OVER clause" msgstr "窗å£å‡½æ•° %s需è¦ä¸€ä¸ªOVERå­å¥" -#: parser/parse_func.c:475 +#: parser/parse_func.c:529 #, c-format msgid "window function %s cannot have WITHIN GROUP" msgstr "窗å£å‡½æ•°%sä¸èƒ½ä½¿ç”¨WITHIN GROUPå­å¥" -#: parser/parse_func.c:496 +#: parser/parse_func.c:558 +#, c-format +msgid "procedure %s is not unique" +msgstr "过程 %s 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_func.c:561 +#, c-format +msgid "Could not choose a best candidate procedure. You might need to add explicit type casts." +msgstr "无法选择最佳候选过程. 您也许需è¦å¢žåŠ æ˜¾å¼çš„类型转æ¢." + +#: parser/parse_func.c:567 #, c-format msgid "function %s is not unique" msgstr "函数 %s 䏿˜¯å”¯ä¸€çš„" -#: parser/parse_func.c:499 +#: parser/parse_func.c:570 #, c-format -msgid "" -"Could not choose a best candidate function. You might need to add explicit " -"type casts." +msgid "Could not choose a best candidate function. You might need to add explicit type casts." msgstr "无法选择最佳候选函数. 你也许需è¦å¢žåŠ æ˜Žç¡®çš„ç±»åž‹è½¬æ¢." -#: parser/parse_func.c:510 +#: parser/parse_func.c:609 #, c-format -msgid "" -"No aggregate function matches the given name and argument types. Perhaps you " -"misplaced ORDER BY; ORDER BY must appear after all regular arguments of the " -"aggregate." -msgstr "" -"æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„函数. 您å¯èƒ½å°†ORDER BYå­å¥æ”¾åœ¨äº†ä¸æ­£ç¡®çš„ä½ç½®ï¼›" -"ORDER BYå­å¥å¿…须出现在所有èšåˆå‡½æ•°çš„å¸¸è§„å‚æ•°çš„åŽé¢." +msgid "No aggregate function matches the given name and argument types. Perhaps you misplaced ORDER BY; ORDER BY must appear after all regular arguments of the aggregate." +msgstr "æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„函数. 您å¯èƒ½å°†ORDER BYå­å¥æ”¾åœ¨äº†ä¸æ­£ç¡®çš„ä½ç½®ï¼›ORDER BYå­å¥å¿…须出现在所有èšåˆå‡½æ•°çš„å¸¸è§„å‚æ•°çš„åŽé¢." -#: parser/parse_func.c:521 +#: parser/parse_func.c:617 parser/parse_func.c:2296 #, c-format -msgid "" -"No function matches the given name and argument types. You might need to add " -"explicit type casts." +msgid "procedure %s does not exist" +msgstr "过程 %s ä¸å­˜åœ¨" + +#: parser/parse_func.c:620 +#, c-format +msgid "No procedure matches the given name and argument types. You might need to add explicit type casts." +msgstr "æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„过程. 您也许需è¦å¢žåŠ æ˜Žç¡®çš„ç±»åž‹è½¬æ¢." + +#: parser/parse_func.c:629 +#, c-format +msgid "No function matches the given name and argument types. You might need to add explicit type casts." msgstr "æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„函数. 您也许需è¦å¢žåŠ æ˜Žç¡®çš„ç±»åž‹è½¬æ¢." -#: parser/parse_func.c:623 +#: parser/parse_func.c:731 #, c-format msgid "VARIADIC argument must be an array" msgstr "傿•°VARIADIC 必须是一个数组" -#: parser/parse_func.c:669 parser/parse_func.c:733 +#: parser/parse_func.c:783 parser/parse_func.c:847 #, c-format msgid "%s(*) must be used to call a parameterless aggregate function" msgstr "%s(*)必须用æ¥è°ƒç”¨æ²¡æœ‰å‚æ•°çš„èšåˆå‡½æ•°" -#: parser/parse_func.c:676 +#: parser/parse_func.c:790 #, c-format msgid "aggregates cannot return sets" msgstr "èšåˆå‡½æ•°å¯ä»¥ä¸è¿”回集åˆ" -#: parser/parse_func.c:691 +#: parser/parse_func.c:805 #, c-format msgid "aggregates cannot use named arguments" msgstr "èšåˆå‡½æ•°ä¸èƒ½ä½¿ç”¨å·²å‘½åçš„å‚æ•°" -#: parser/parse_func.c:723 +#: parser/parse_func.c:837 #, c-format msgid "DISTINCT is not implemented for window functions" msgstr "对于窗å£å‡½æ•°ï¼Œæ²¡æœ‰å®žçްDISTINCT" -#: parser/parse_func.c:743 +#: parser/parse_func.c:857 #, c-format msgid "aggregate ORDER BY is not implemented for window functions" msgstr "对于窗å£å‡½æ•°ï¼Œæ²¡æœ‰å®žçŽ°åœ¨æŒ‰ç…§èšåˆå‡½æ•°è¿›è¡ŒORDER BYæ“作的功能" -#: parser/parse_func.c:752 +#: parser/parse_func.c:866 #, c-format msgid "FILTER is not implemented for non-aggregate window functions" msgstr "FILTER在éžèšåˆçª—å£å‡½æ•°é‡Œå¹¶æœªè¢«å®žçް" -#: parser/parse_func.c:758 +#: parser/parse_func.c:875 +#, c-format +msgid "window function calls cannot contain set-returning function calls" +msgstr "窗å£å‡½æ•°è°ƒç”¨ä¸èƒ½åŒ…å«è¿”回集åˆå‡½æ•°çš„调用" + +#: parser/parse_func.c:883 #, c-format msgid "window functions cannot return sets" msgstr "窗å£å‡½æ•°ä¸èƒ½è¿”回集åˆ" -#: parser/parse_func.c:2008 +#: parser/parse_func.c:2134 parser/parse_func.c:2325 #, c-format -msgid "aggregate %s(*) does not exist" -msgstr "èšåˆå‡½æ•° %s(*) ä¸å­˜åœ¨" +msgid "could not find a function named \"%s\"" +msgstr "无法找到函数å\"%s\"" -#: parser/parse_func.c:2013 +#: parser/parse_func.c:2148 parser/parse_func.c:2343 #, c-format -msgid "aggregate %s does not exist" -msgstr "èšåˆå‡½æ•° %s(*) ä¸å­˜åœ¨" +msgid "function name \"%s\" is not unique" +msgstr "函数å \"%s\" 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_func.c:2150 parser/parse_func.c:2345 +#, c-format +msgid "Specify the argument list to select the function unambiguously." +msgstr "æŒ‡å®šå‚æ•°åˆ—表以明确选择函数" + +#: parser/parse_func.c:2194 +#, fuzzy, c-format +#| msgid "aggregates cannot have more than %d argument" +#| msgid_plural "aggregates cannot have more than %d arguments" +msgid "procedures cannot have more than %d argument" +msgid_plural "procedures cannot have more than %d arguments" +msgstr[0] "èšé›†å‡½æ•°çš„傿•°ä¸èƒ½å¤šäºŽ%d个" + +#: parser/parse_func.c:2243 +#, c-format +msgid "%s is not a function" +msgstr "%s 䏿˜¯ä¸€ä¸ªå‡½æ•°" -#: parser/parse_func.c:2032 +#: parser/parse_func.c:2263 #, c-format msgid "function %s is not an aggregate" msgstr "函数 \"%s\" 䏿˜¯ä¸€ä¸ªèšåˆå‡½æ•°" -#: parser/parse_node.c:84 +#: parser/parse_func.c:2291 +#, c-format +msgid "could not find a procedure named \"%s\"" +msgstr "找ä¸åˆ°å为\"%s\"的过程" + +# describe.c:641 +#: parser/parse_func.c:2305 +#, c-format +msgid "could not find an aggregate named \"%s\"" +msgstr "找ä¸åˆ°å为\"%s\"çš„èšåˆ" + +#: parser/parse_func.c:2310 +#, c-format +msgid "aggregate %s(*) does not exist" +msgstr "èšåˆå‡½æ•° %s(*) ä¸å­˜åœ¨" + +#: parser/parse_func.c:2315 +#, c-format +msgid "aggregate %s does not exist" +msgstr "èšåˆå‡½æ•° %s(*) ä¸å­˜åœ¨" + +#: parser/parse_func.c:2350 +#, fuzzy, c-format +#| msgid "procedure %s is not unique" +msgid "procedure name \"%s\" is not unique" +msgstr "过程 %s 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_func.c:2352 +#, fuzzy, c-format +#| msgid "Specify the argument list to select the function unambiguously." +msgid "Specify the argument list to select the procedure unambiguously." +msgstr "æŒ‡å®šå‚æ•°åˆ—表以明确选择函数" + +#: parser/parse_func.c:2357 +#, fuzzy, c-format +#| msgid "namespace name \"%s\" is not unique" +msgid "aggregate name \"%s\" is not unique" +msgstr "命å空间åç§° \"%s\" 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_func.c:2359 +#, fuzzy, c-format +#| msgid "Specify the argument list to select the function unambiguously." +msgid "Specify the argument list to select the aggregate unambiguously." +msgstr "æŒ‡å®šå‚æ•°åˆ—表以明确选择函数" + +#: parser/parse_func.c:2364 +#, fuzzy, c-format +#| msgid "function name \"%s\" is not unique" +msgid "routine name \"%s\" is not unique" +msgstr "函数å \"%s\" 䏿˜¯å”¯ä¸€çš„" + +#: parser/parse_func.c:2366 +#, fuzzy, c-format +#| msgid "Specify the argument list to select the function unambiguously." +msgid "Specify the argument list to select the routine unambiguously." +msgstr "æŒ‡å®šå‚æ•°åˆ—表以明确选择函数" + +#: parser/parse_func.c:2421 +msgid "set-returning functions are not allowed in JOIN conditions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在JOINæ¡ä»¶ä¸­" + +#: parser/parse_func.c:2442 +msgid "set-returning functions are not allowed in policy expressions" +msgstr "策略表达å¼ä¸­ä¸å…许返回集åˆå‡½æ•°" + +#: parser/parse_func.c:2458 +msgid "set-returning functions are not allowed in window definitions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在窗å£å®šä¹‰ä¸­" + +#: parser/parse_func.c:2496 +msgid "set-returning functions are not allowed in check constraints" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在check约æŸä¸­" + +#: parser/parse_func.c:2500 +msgid "set-returning functions are not allowed in DEFAULT expressions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在DEFAULT表达å¼ä¸­" + +#: parser/parse_func.c:2503 +msgid "set-returning functions are not allowed in index expressions" +msgstr "在返回集åˆå‡½æ•°ä¸å…许出现在索引表达å¼ä¸­" + +#: parser/parse_func.c:2506 +msgid "set-returning functions are not allowed in index predicates" +msgstr "返回函数集åˆä¸å…许出现在索引判定å­å¥ä¸­" + +#: parser/parse_func.c:2509 +msgid "set-returning functions are not allowed in transform expressions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在转æ¢è¡¨è¾¾å¼ä¸­" + +#: parser/parse_func.c:2512 +msgid "set-returning functions are not allowed in EXECUTE parameters" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在EXECUTE傿•°ä¸­" + +#: parser/parse_func.c:2515 +msgid "set-returning functions are not allowed in trigger WHEN conditions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在触å‘器WHENæ¡ä»¶ä¸­" + +#: parser/parse_func.c:2518 +#, fuzzy +#| msgid "set-returning functions are not allowed in partition key expressions" +msgid "set-returning functions are not allowed in partition bound" +msgstr "在返回集åˆå‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_func.c:2521 +msgid "set-returning functions are not allowed in partition key expressions" +msgstr "在返回集åˆå‡½æ•°ä¸å…许出现在分区键表达å¼ä¸­" + +#: parser/parse_func.c:2524 +msgid "set-returning functions are not allowed in CALL arguments" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在CALL傿•°ä¸­" + +#: parser/parse_func.c:2527 +#, fuzzy +#| msgid "set-returning functions are not allowed in JOIN conditions" +msgid "set-returning functions are not allowed in COPY FROM WHERE conditions" +msgstr "返回集åˆå‡½æ•°ä¸å…许出现在JOINæ¡ä»¶ä¸­" + +#: parser/parse_func.c:2530 +#, fuzzy +#| msgid "set-returning functions are not allowed in policy expressions" +msgid "set-returning functions are not allowed in column generation expressions" +msgstr "策略表达å¼ä¸­ä¸å…许返回集åˆå‡½æ•°" + +#: parser/parse_node.c:87 #, c-format msgid "target lists can have at most %d entries" msgstr "目标列表最多å¯ä»¥æœ‰ %d 个字段" -#: parser/parse_node.c:253 +#: parser/parse_node.c:257 #, c-format msgid "cannot subscript type %s because it is not an array" msgstr "无法下标类型 %s, å› ä¸ºå®ƒä¸æ˜¯ä¸€ä¸ªæ•°ç»„" -#: parser/parse_node.c:356 parser/parse_node.c:393 +#: parser/parse_node.c:363 parser/parse_node.c:400 #, c-format msgid "array subscript must have type integer" msgstr "数组下标必须为整数类型" -#: parser/parse_node.c:424 +#: parser/parse_node.c:431 #, c-format msgid "array assignment requires type %s but expression is of type %s" msgstr "数组分é…è¦æ±‚类型%s,但是表达å¼å±žäºŽç±»åž‹%s" -#: parser/parse_oper.c:125 parser/parse_oper.c:722 utils/adt/regproc.c:583 -#: utils/adt/regproc.c:603 utils/adt/regproc.c:787 +#: parser/parse_oper.c:125 parser/parse_oper.c:724 utils/adt/regproc.c:520 +#: utils/adt/regproc.c:704 #, c-format msgid "operator does not exist: %s" msgstr "æ“作符ä¸å­˜åœ¨: %s" -#: parser/parse_oper.c:222 +#: parser/parse_oper.c:224 #, c-format msgid "Use an explicit ordering operator or modify the query." msgstr "ä½¿ç”¨æ˜¾å¼æ“作符或修改查询" -#: parser/parse_oper.c:226 utils/adt/array_userfuncs.c:782 -#: utils/adt/array_userfuncs.c:920 utils/adt/arrayfuncs.c:3639 -#: utils/adt/arrayfuncs.c:4077 utils/adt/arrayfuncs.c:6055 -#: utils/adt/rowtypes.c:1167 -#, c-format -msgid "could not identify an equality operator for type %s" -msgstr "无法为类型%s识别等于æ“作符" - -#: parser/parse_oper.c:478 +#: parser/parse_oper.c:480 #, c-format msgid "operator requires run-time type coercion: %s" msgstr "æ“作符需è¦è¿è¡Œæ—¶ç±»åž‹å¼ºåˆ¶: %s" -#: parser/parse_oper.c:714 +#: parser/parse_oper.c:716 #, c-format msgid "operator is not unique: %s" msgstr "æ“ä½œç¬¦ä¸æ˜¯å”¯ä¸€çš„: %s" -#: parser/parse_oper.c:716 +#: parser/parse_oper.c:718 #, c-format -msgid "" -"Could not choose a best candidate operator. You might need to add explicit " -"type casts." +msgid "Could not choose a best candidate operator. You might need to add explicit type casts." msgstr "无法选择最佳候选æ“作符. 您也许需è¦å¢žåŠ æ˜¾å¼çš„类型转æ¢." -#: parser/parse_oper.c:724 +#: parser/parse_oper.c:727 #, c-format -msgid "" -"No operator matches the given name and argument type(s). You might need to " -"add explicit type casts." +msgid "No operator matches the given name and argument type. You might need to add an explicit type cast." +msgstr "æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„æ“ä½œç¬¦. 您也许需è¦å¢žåŠ æ˜Žç¡®çš„ç±»åž‹è½¬æ¢." + +#: parser/parse_oper.c:729 +#, c-format +msgid "No operator matches the given name and argument types. You might need to add explicit type casts." msgstr "æ²¡æœ‰åŒ¹é…æŒ‡å®šåç§°å’Œå‚æ•°ç±»åž‹çš„æ“ä½œç¬¦. 您也许需è¦å¢žåŠ æ˜Žç¡®çš„ç±»åž‹è½¬æ¢." -#: parser/parse_oper.c:783 parser/parse_oper.c:897 +#: parser/parse_oper.c:790 parser/parse_oper.c:912 #, c-format msgid "operator is only a shell: %s" msgstr "æ“ä½œç¬¦åªæ˜¯ä¸€ä¸ªshell: %s" -#: parser/parse_oper.c:885 +#: parser/parse_oper.c:900 #, c-format msgid "op ANY/ALL (array) requires array on right side" msgstr "æ“作符ANY/ALL (array)è¦æ±‚数组在å³è¾¹" -#: parser/parse_oper.c:927 +#: parser/parse_oper.c:942 #, c-format msgid "op ANY/ALL (array) requires operator to yield boolean" msgstr "æ“作ANY/ALL (array)需è¦äº§ç”Ÿå¸ƒå°”值的æ“作符." -#: parser/parse_oper.c:932 +#: parser/parse_oper.c:947 #, c-format msgid "op ANY/ALL (array) requires operator not to return a set" msgstr "æ“作ANY/ALL (array)需è¦ä¸è¿”回集åˆçš„æ“ä½œç¬¦" @@ -14279,175 +15575,166 @@ msgstr "æ“作ANY/ALL (array)需è¦ä¸è¿”回集åˆçš„æ“ä½œç¬¦" msgid "inconsistent types deduced for parameter $%d" msgstr "å¯¹äºŽå‚æ•°$%d,推断出ä¸ä¸€è‡´çš„类型" -#: parser/parse_relation.c:174 +#: parser/parse_relation.c:179 #, c-format msgid "table reference \"%s\" is ambiguous" msgstr "è¡¨å…³è” \"%s\" æ˜¯ä¸æ˜Žç¡®çš„" -#: parser/parse_relation.c:218 +#: parser/parse_relation.c:223 #, c-format msgid "table reference %u is ambiguous" msgstr "è¡¨å…³è” %u æ˜¯ä¸æ˜Žç¡®çš„" -#: parser/parse_relation.c:397 +#: parser/parse_relation.c:422 #, c-format msgid "table name \"%s\" specified more than once" msgstr "表å \"%s\" 被指定多次" -#: parser/parse_relation.c:424 parser/parse_relation.c:3023 +#: parser/parse_relation.c:449 parser/parse_relation.c:3292 #, c-format msgid "invalid reference to FROM-clause entry for table \"%s\"" msgstr "对于表 \"%s\"çš„FROMå­å¥é¡¹çš„引用无效 " -#: parser/parse_relation.c:427 parser/parse_relation.c:3028 +#: parser/parse_relation.c:452 parser/parse_relation.c:3297 #, c-format -msgid "" -"There is an entry for table \"%s\", but it cannot be referenced from this " -"part of the query." +msgid "There is an entry for table \"%s\", but it cannot be referenced from this part of the query." msgstr "这里有一个对于表\"%s\"的项,但是ä¸èƒ½ä»ŽæŸ¥è¯¢çš„这个部分中引用." -#: parser/parse_relation.c:429 +#: parser/parse_relation.c:454 #, c-format msgid "The combining JOIN type must be INNER or LEFT for a LATERAL reference." msgstr "在LATERAL引用里,组åˆçš„JOIN必须是INNER或LEFT JOIN类型." -#: parser/parse_relation.c:705 +#: parser/parse_relation.c:730 #, c-format msgid "system column \"%s\" reference in check constraint is invalid" msgstr "check约æŸä¸­çš„系统列\"%s\"å‚照是无效的" -#: parser/parse_relation.c:1065 parser/parse_relation.c:1345 -#: parser/parse_relation.c:1847 +#: parser/parse_relation.c:741 +#, fuzzy, c-format +#| msgid "cannot use system column \"%s\" in partition key" +msgid "cannot use system column \"%s\" in column generation expression" +msgstr "无法在分区键中使用系统列\"%s\"" + +#: parser/parse_relation.c:1100 parser/parse_relation.c:1404 +#: parser/parse_relation.c:1985 #, c-format msgid "table \"%s\" has %d columns available but %d columns specified" msgstr "表 \"%s\" 有 %d 个有效字段, 但指定了 %d 个字段" -#: parser/parse_relation.c:1152 +#: parser/parse_relation.c:1187 #, c-format -msgid "" -"There is a WITH item named \"%s\", but it cannot be referenced from this " -"part of the query." +msgid "There is a WITH item named \"%s\", but it cannot be referenced from this part of the query." msgstr "这里有一个å称为\"%s\"çš„WITHæˆå‘˜ï¼Œä½†æ˜¯ä¸èƒ½ä»ŽæŸ¥è¯¢çš„这个部分引用它." -#: parser/parse_relation.c:1154 +#: parser/parse_relation.c:1189 #, c-format -msgid "" -"Use WITH RECURSIVE, or re-order the WITH items to remove forward references." +msgid "Use WITH RECURSIVE, or re-order the WITH items to remove forward references." msgstr "使用WITH RECURSIVEæˆ–é‡æ–°æŽ’åºWITHæˆå‘˜æ¥åˆ é™¤å‰å‘引用." -#: parser/parse_relation.c:1465 +#: parser/parse_relation.c:1525 #, c-format -msgid "" -"a column definition list is only allowed for functions returning \"record\"" +msgid "a column definition list is only allowed for functions returning \"record\"" msgstr "一个字段定义列表åªå…许返回 \"record\" 的函数" -#: parser/parse_relation.c:1474 +#: parser/parse_relation.c:1534 #, c-format msgid "a column definition list is required for functions returning \"record\"" msgstr "一个字段定义列表需è¦è¿”回 \"record\" 的函数" -#: parser/parse_relation.c:1553 +#: parser/parse_relation.c:1620 #, c-format msgid "function \"%s\" in FROM has unsupported return type %s" msgstr "FROM 中的函数 \"%s\" 䏿”¯æŒè¿”回类型 %s" -#: parser/parse_relation.c:1675 +#: parser/parse_relation.c:1811 #, c-format msgid "VALUES lists \"%s\" have %d columns available but %d columns specified" msgstr "VALUES列表\"%s\"中有%d列有效, 但指定了%d个列." -#: parser/parse_relation.c:1730 +#: parser/parse_relation.c:1867 #, c-format msgid "joins can have at most %d columns" msgstr "连接最多å¯ä»¥æœ‰ %d 个字段" -#: parser/parse_relation.c:1820 +#: parser/parse_relation.c:1958 #, c-format msgid "WITH query \"%s\" does not have a RETURNING clause" msgstr "WITH 查询 \"%s\" 没有RETURNINGå­å¥" -#: parser/parse_relation.c:2652 parser/parse_relation.c:2807 +#: parser/parse_relation.c:2899 parser/parse_relation.c:2937 +#: parser/parse_relation.c:2946 parser/parse_relation.c:3072 +#: parser/parse_relation.c:3082 #, c-format msgid "column %d of relation \"%s\" does not exist" msgstr "在关系\"%2$s\"中的列 %1$d ä¸å­˜åœ¨" -#: parser/parse_relation.c:3026 +#: parser/parse_relation.c:3295 #, c-format msgid "Perhaps you meant to reference the table alias \"%s\"." msgstr "å¯èƒ½æ‚¨æ˜¯è¦å¼•用表的化å \"%s\"." -#: parser/parse_relation.c:3034 +#: parser/parse_relation.c:3303 #, c-format msgid "missing FROM-clause entry for table \"%s\"" msgstr "对于表\"%s\",丢失FROMå­å¥é¡¹" -#: parser/parse_relation.c:3086 +#: parser/parse_relation.c:3355 #, c-format msgid "Perhaps you meant to reference the column \"%s.%s\"." msgstr "也许您想è¦å¼•用列\"%s.%s\"。" -#: parser/parse_relation.c:3088 +#: parser/parse_relation.c:3357 #, c-format -msgid "" -"There is a column named \"%s\" in table \"%s\", but it cannot be referenced " -"from this part of the query." -msgstr "" -"表\"%2$s\"中存在一列,å为\"%1$s\", 但是这个表åå¹¶ä¸èƒ½ä»Žè¿™éƒ¨åˆ†æŸ¥è¯¢é‡Œå¼•用." +msgid "There is a column named \"%s\" in table \"%s\", but it cannot be referenced from this part of the query." +msgstr "表\"%2$s\"中存在一列,å为\"%1$s\", 但是这个表åå¹¶ä¸èƒ½ä»Žè¿™éƒ¨åˆ†æŸ¥è¯¢é‡Œå¼•用." -#: parser/parse_relation.c:3105 +#: parser/parse_relation.c:3374 #, c-format -msgid "" -"Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." +msgid "Perhaps you meant to reference the column \"%s.%s\" or the column \"%s.%s\"." msgstr "也许您想è¦å¼•用列\"%s.%s\"或者列\"%s.%s\"。" -#: parser/parse_target.c:421 parser/parse_target.c:713 +#: parser/parse_target.c:484 parser/parse_target.c:791 #, c-format msgid "cannot assign to system column \"%s\"" msgstr "ä¸èƒ½æŒ‡å®šç³»ç»Ÿå­—段å \"%s\"" -#: parser/parse_target.c:449 +#: parser/parse_target.c:512 #, c-format msgid "cannot set an array element to DEFAULT" msgstr "ä¸èƒ½è®¾ç½®ä¸€ä¸ªæ•°ç»„元素为 DEFAULT" -#: parser/parse_target.c:454 +#: parser/parse_target.c:517 #, c-format msgid "cannot set a subfield to DEFAULT" msgstr "ä¸èƒ½è®¾ç½®å­å­—段为 DEFAULT" -#: parser/parse_target.c:523 +#: parser/parse_target.c:586 #, c-format msgid "column \"%s\" is of type %s but expression is of type %s" msgstr "字段 \"%s\" 的类型为 %s, 但表达å¼çš„类型为 %s" -#: parser/parse_target.c:697 +#: parser/parse_target.c:775 #, c-format -msgid "" -"cannot assign to field \"%s\" of column \"%s\" because its type %s is not a " -"composite type" -msgstr "" -"无法指定列 \"%2$s\" 的字段 \"%1$s\", 因为它的类型 %3$s 䏿˜¯ä¸€ä¸ªå¤åˆç±»åž‹" +msgid "cannot assign to field \"%s\" of column \"%s\" because its type %s is not a composite type" +msgstr "无法指定列 \"%2$s\" 的字段 \"%1$s\", 因为它的类型 %3$s 䏿˜¯ä¸€ä¸ªå¤åˆç±»åž‹" -#: parser/parse_target.c:706 +#: parser/parse_target.c:784 #, c-format -msgid "" -"cannot assign to field \"%s\" of column \"%s\" because there is no such " -"column in data type %s" -msgstr "" -"无法给字段 \"%2$s\" 的数æ®åŸŸ \"%1$s\" 赋值, 因为在数æ®ç±»åž‹ %3$s 中没有此列" +msgid "cannot assign to field \"%s\" of column \"%s\" because there is no such column in data type %s" +msgstr "无法给字段 \"%2$s\" 的数æ®åŸŸ \"%1$s\" 赋值, 因为在数æ®ç±»åž‹ %3$s 中没有此列" -#: parser/parse_target.c:773 +#: parser/parse_target.c:861 #, c-format -msgid "" -"array assignment to \"%s\" requires type %s but expression is of type %s" +msgid "array assignment to \"%s\" requires type %s but expression is of type %s" msgstr "将数组分é…ç»™\"%s\" 时需è¦ç±»åž‹%s,但是表达å¼å±žäºŽç±»åž‹%s" -#: parser/parse_target.c:783 +#: parser/parse_target.c:871 #, c-format msgid "subfield \"%s\" is of type %s but expression is of type %s" msgstr "å­å­—段 \"%s\" 的类型为 %s, 但表达å¼çš„类型为 %s" -#: parser/parse_target.c:1199 +#: parser/parse_target.c:1290 #, c-format msgid "SELECT * with no tables specified is not valid" msgstr "SELECT * 没有指定表是无效的" @@ -14467,7 +15754,7 @@ msgstr "ä¸åˆé€‚çš„ %%TYPE å…³è” (å字中太多点符å·): %s" msgid "type reference %s converted to %s" msgstr "ç±»åž‹å…³è” %s 转æ¢ä¸º %s" -#: parser/parse_type.c:261 parser/parse_type.c:805 utils/cache/typcache.c:239 +#: parser/parse_type.c:261 parser/parse_type.c:840 utils/cache/typcache.c:374 #, c-format msgid "type \"%s\" is only a shell" msgstr "类型 \"%s\" åªæ˜¯ä¸€ä¸ª shell" @@ -14482,969 +15769,1085 @@ msgstr "对于类型\"%s\"ä¸å…许使用类型修改器" msgid "type modifiers must be simple constants or identifiers" msgstr "类型修改器必须是简å•çš„å¸¸é‡æˆ–标示符." -#: parser/parse_type.c:671 parser/parse_type.c:770 +#: parser/parse_type.c:704 parser/parse_type.c:803 #, c-format msgid "invalid type name \"%s\"" msgstr "无效的类型åå­— \"%s\"" -#: parser/parse_utilcmd.c:399 +#: parser/parse_utilcmd.c:263 #, c-format -msgid "array of serial is not implemented" -msgstr "未实现åºå·æ•°ç»„" +msgid "cannot create partitioned table as inheritance child" +msgstr "无法将分区表创建为继承å­çº§" -#: parser/parse_utilcmd.c:447 +#: parser/parse_utilcmd.c:426 #, c-format msgid "%s will create implicit sequence \"%s\" for serial column \"%s.%s\"" msgstr "%1$s 将为 serial 字段 \"%3$s.%4$s\" 创建éšå«åºåˆ— \"%2$s\"" -#: parser/parse_utilcmd.c:541 parser/parse_utilcmd.c:553 +#: parser/parse_utilcmd.c:550 #, c-format -msgid "" -"conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" +msgid "array of serial is not implemented" +msgstr "未实现åºå·æ•°ç»„" + +#: parser/parse_utilcmd.c:627 parser/parse_utilcmd.c:639 +#, c-format +msgid "conflicting NULL/NOT NULL declarations for column \"%s\" of table \"%s\"" msgstr "表 \"%2$s\" 的字段 \"%1$s\" 声明 NULL/NOT NULL 冲çª" -#: parser/parse_utilcmd.c:565 +#: parser/parse_utilcmd.c:651 #, c-format msgid "multiple default values specified for column \"%s\" of table \"%s\"" msgstr "对表 \"%2$s\" 的字段 \"%1$s\" 指定了多é默认值" -#: parser/parse_utilcmd.c:582 parser/parse_utilcmd.c:673 +#: parser/parse_utilcmd.c:668 +#, c-format +msgid "identity columns are not supported on typed tables" +msgstr "ç±»åž‹è¡¨ä¸æ”¯æŒæ ‡è¯†åˆ—" + +#: parser/parse_utilcmd.c:672 +#, c-format +msgid "identity columns are not supported on partitions" +msgstr "åˆ†åŒºä¸Šä¸æ”¯æŒæ ‡è¯†åˆ—" + +#: parser/parse_utilcmd.c:681 +#, c-format +msgid "multiple identity specifications for column \"%s\" of table \"%s\"" +msgstr "表\"%2$s\" 的的字段 \"%1$s\"的多个标识规范" + +#: parser/parse_utilcmd.c:700 +#, fuzzy, c-format +#| msgid "identity columns are not supported on typed tables" +msgid "generated columns are not supported on typed tables" +msgstr "ç±»åž‹è¡¨ä¸æ”¯æŒæ ‡è¯†åˆ—" + +#: parser/parse_utilcmd.c:704 +#, fuzzy, c-format +#| msgid "identity columns are not supported on partitions" +msgid "generated columns are not supported on partitions" +msgstr "åˆ†åŒºä¸Šä¸æ”¯æŒæ ‡è¯†åˆ—" + +#: parser/parse_utilcmd.c:709 +#, fuzzy, c-format +#| msgid "multiple default values specified for column \"%s\" of table \"%s\"" +msgid "multiple generation clauses specified for column \"%s\" of table \"%s\"" +msgstr "对表 \"%2$s\" 的字段 \"%1$s\" 指定了多é默认值" + +#: parser/parse_utilcmd.c:727 parser/parse_utilcmd.c:842 #, c-format msgid "primary key constraints are not supported on foreign tables" msgstr "å¤–éƒ¨è¡¨ä¸Šä¸æ”¯æŒä¸»é”®çº¦æŸ" -#: parser/parse_utilcmd.c:591 parser/parse_utilcmd.c:683 +#: parser/parse_utilcmd.c:736 parser/parse_utilcmd.c:852 #, c-format msgid "unique constraints are not supported on foreign tables" msgstr "å¤–éƒ¨è¡¨ä¸Šä¸æ”¯æŒå”¯ä¸€çº¦æŸ" -#: parser/parse_utilcmd.c:608 parser/parse_utilcmd.c:707 +#: parser/parse_utilcmd.c:781 #, c-format -msgid "foreign key constraints are not supported on foreign tables" -msgstr "å¤–éƒ¨è¡¨ä¸Šä¸æ”¯æŒå¤–键约æŸ" +msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgstr "对表 \"%2$s\" 的字段 \"%1$s\" 指定了默认值和标识" + +#: parser/parse_utilcmd.c:789 +#, fuzzy, c-format +#| msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgid "both default and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "对表 \"%2$s\" 的字段 \"%1$s\" 指定了默认值和标识" -#: parser/parse_utilcmd.c:693 +#: parser/parse_utilcmd.c:797 +#, fuzzy, c-format +#| msgid "both default and identity specified for column \"%s\" of table \"%s\"" +msgid "both identity and generation expression specified for column \"%s\" of table \"%s\"" +msgstr "对表 \"%2$s\" 的字段 \"%1$s\" 指定了默认值和标识" + +#: parser/parse_utilcmd.c:862 #, c-format msgid "exclusion constraints are not supported on foreign tables" msgstr "å¤–éƒ¨è¡¨ä¸Šä¸æ”¯æŒæŽ’除约æŸ" -#: parser/parse_utilcmd.c:757 +#: parser/parse_utilcmd.c:868 +#, c-format +msgid "exclusion constraints are not supported on partitioned tables" +msgstr "åˆ†åŒºè¡¨ä¸Šä¸æ”¯æŒæŽ’除约æŸ" + +#: parser/parse_utilcmd.c:932 #, c-format msgid "LIKE is not supported for creating foreign tables" msgstr "LIKEä¸èƒ½ç”¨äºŽåˆ›å»ºå¤–部表" -#: parser/parse_utilcmd.c:1288 parser/parse_utilcmd.c:1364 +#: parser/parse_utilcmd.c:1064 +#, fuzzy, c-format +#| msgid "Constraint \"%s\" contains a whole-row reference to table \"%s\"." +msgid "Generation expression for column \"%s\" contains a whole-row reference to table \"%s\"." +msgstr "约æŸ\"%s\"包å«åˆ°è¡¨\"%s\"的整行引用." + +#: parser/parse_utilcmd.c:1563 parser/parse_utilcmd.c:1670 #, c-format msgid "Index \"%s\" contains a whole-row table reference." msgstr "索引 \"%s\" 包å«ä¸€ä¸ªæ•´è¡Œè¡¨å¼•用." -#: parser/parse_utilcmd.c:1634 +#: parser/parse_utilcmd.c:2036 #, c-format msgid "cannot use an existing index in CREATE TABLE" msgstr " CREATE TABLE语å¥ä¸èƒ½ä½¿ç”¨ä¸€ä¸ªå·²å­˜åœ¨çš„索引" -#: parser/parse_utilcmd.c:1654 +#: parser/parse_utilcmd.c:2056 #, c-format msgid "index \"%s\" is already associated with a constraint" msgstr "index \"%s\"与æŸä¸ªçº¦æŸå·²ç»å…³è”" -#: parser/parse_utilcmd.c:1662 -#, c-format -msgid "index \"%s\" does not belong to table \"%s\"" -msgstr "索引 \"%s\" ä¸å±žäºŽè¡¨\"%s\"" - -#: parser/parse_utilcmd.c:1669 +#: parser/parse_utilcmd.c:2071 #, c-format msgid "index \"%s\" is not valid" msgstr "索引 \"%s\" 无效" -#: parser/parse_utilcmd.c:1675 +#: parser/parse_utilcmd.c:2077 #, c-format msgid "\"%s\" is not a unique index" msgstr "\"%s\" 䏿˜¯å”¯ä¸€ç´¢å¼•" -#: parser/parse_utilcmd.c:1676 parser/parse_utilcmd.c:1683 -#: parser/parse_utilcmd.c:1690 parser/parse_utilcmd.c:1760 +#: parser/parse_utilcmd.c:2078 parser/parse_utilcmd.c:2085 +#: parser/parse_utilcmd.c:2092 parser/parse_utilcmd.c:2163 #, c-format msgid "Cannot create a primary key or unique constraint using such an index." msgstr "无法使用该索引创建主键或唯一约æŸ." -#: parser/parse_utilcmd.c:1682 +#: parser/parse_utilcmd.c:2084 #, c-format msgid "index \"%s\" contains expressions" msgstr "索引 \"%s\" 嫿œ‰è¡¨è¾¾å¼" -#: parser/parse_utilcmd.c:1689 +#: parser/parse_utilcmd.c:2091 #, c-format msgid "\"%s\" is a partial index" msgstr "\"%s\" 是一个部分索引" -#: parser/parse_utilcmd.c:1701 +#: parser/parse_utilcmd.c:2103 #, c-format msgid "\"%s\" is a deferrable index" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªå»¶è¿Ÿç´¢å¼•" -#: parser/parse_utilcmd.c:1702 +#: parser/parse_utilcmd.c:2104 #, c-format msgid "Cannot create a non-deferrable constraint using a deferrable index." msgstr "无法为使用å¯å»¶è¿Ÿç´¢å¼•的约æŸåˆ›å»ºéžå¯å»¶è¿Ÿçº¦æŸ" -#: parser/parse_utilcmd.c:1759 -#, c-format -msgid "index \"%s\" does not have default sorting behavior" +#: parser/parse_utilcmd.c:2162 +#, fuzzy, c-format +#| msgid "index \"%s\" does not have default sorting behavior" +msgid "index \"%s\" column number %d does not have default sorting behavior" msgstr "索引 \"%s\"没有缺çœçš„æŽ’åºè¡Œä¸º" -#: parser/parse_utilcmd.c:1906 +#: parser/parse_utilcmd.c:2319 #, c-format msgid "column \"%s\" appears twice in primary key constraint" msgstr "在主键约æŸä¸­å­—段 \"%s\" 出现了两次" -#: parser/parse_utilcmd.c:1912 +#: parser/parse_utilcmd.c:2325 #, c-format msgid "column \"%s\" appears twice in unique constraint" msgstr "字段 \"%s\" 在唯一约æŸä¸­å‡ºçŽ°ä¸¤æ¬¡" -#: parser/parse_utilcmd.c:2116 +#: parser/parse_utilcmd.c:2676 #, c-format -msgid "index expression cannot return a set" -msgstr "索引表达å¼ä¸èƒ½è¿”回一个集åˆ" - -#: parser/parse_utilcmd.c:2127 -#, c-format -msgid "" -"index expressions and predicates can refer only to the table being indexed" +msgid "index expressions and predicates can refer only to the table being indexed" msgstr "索引表达å¼å’Œå£°æ˜Žåªèƒ½æŒ‡å‘è¦å»ºç´¢å¼•的表" -#: parser/parse_utilcmd.c:2173 +#: parser/parse_utilcmd.c:2722 #, c-format msgid "rules on materialized views are not supported" msgstr "物化视图ä¸èƒ½ä½¿ç”¨è§„则(rules)" -#: parser/parse_utilcmd.c:2234 +#: parser/parse_utilcmd.c:2785 #, c-format msgid "rule WHERE condition cannot contain references to other relations" msgstr "规则的WHEREæ¡ä»¶ä¸èƒ½åŒ…å«åˆ°å…¶å®ƒå…³ç³»çš„引用" -#: parser/parse_utilcmd.c:2306 +#: parser/parse_utilcmd.c:2859 #, c-format -msgid "" -"rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE " -"actions" +msgid "rules with WHERE conditions can only have SELECT, INSERT, UPDATE, or DELETE actions" msgstr "带有WHERE æ¡ä»¶çš„规则åªå…许有æ“作 SELECT, INSERT, UPDATE, 或者 DELETE " -#: parser/parse_utilcmd.c:2324 parser/parse_utilcmd.c:2423 -#: rewrite/rewriteHandler.c:485 rewrite/rewriteManip.c:1015 +#: parser/parse_utilcmd.c:2877 parser/parse_utilcmd.c:2976 +#: rewrite/rewriteHandler.c:501 rewrite/rewriteManip.c:1015 #, c-format msgid "conditional UNION/INTERSECT/EXCEPT statements are not implemented" msgstr "æ¡ä»¶å·¥å…·è¯­å¥ UNION/INTERSECT/EXCEPT 没有实现" -#: parser/parse_utilcmd.c:2342 +#: parser/parse_utilcmd.c:2895 #, c-format msgid "ON SELECT rule cannot use OLD" msgstr "规则ON SELECTä¸èƒ½ä½¿ç”¨å…³é”®è¯OLD" -#: parser/parse_utilcmd.c:2346 +#: parser/parse_utilcmd.c:2899 #, c-format msgid "ON SELECT rule cannot use NEW" msgstr "规则ON SELECTä¸èƒ½ä½¿ç”¨å…³é”®è¯NEW" -#: parser/parse_utilcmd.c:2355 +#: parser/parse_utilcmd.c:2908 #, c-format msgid "ON INSERT rule cannot use OLD" msgstr "规则ON INSERTä¸èƒ½ä½¿ç”¨å…³é”®è¯OLD" -#: parser/parse_utilcmd.c:2361 +#: parser/parse_utilcmd.c:2914 #, c-format msgid "ON DELETE rule cannot use NEW" msgstr "规则ON DELETEä¸èƒ½ä½¿ç”¨å…³é”®è¯NEW" -#: parser/parse_utilcmd.c:2389 +#: parser/parse_utilcmd.c:2942 #, c-format msgid "cannot refer to OLD within WITH query" msgstr "WITH查询中无法引用OLD" -#: parser/parse_utilcmd.c:2396 +#: parser/parse_utilcmd.c:2949 #, c-format msgid "cannot refer to NEW within WITH query" msgstr "WITH 查询无法引用NEW" -#: parser/parse_utilcmd.c:2599 -#, c-format -msgid "transform expression must not return a set" -msgstr "转æ¢è¡¨è¾¾å¼ä¸èƒ½è¿”回一个组åˆ" - -#: parser/parse_utilcmd.c:2713 +#: parser/parse_utilcmd.c:3407 #, c-format msgid "misplaced DEFERRABLE clause" msgstr "DEFERRABLE å­å¥ä½ç½®é”™è¯¯" -#: parser/parse_utilcmd.c:2718 parser/parse_utilcmd.c:2733 +#: parser/parse_utilcmd.c:3412 parser/parse_utilcmd.c:3427 #, c-format msgid "multiple DEFERRABLE/NOT DEFERRABLE clauses not allowed" msgstr "ä¸å…许多个 DEFERRABLE/NOT DEFERRABLE å­å¥" -#: parser/parse_utilcmd.c:2728 +#: parser/parse_utilcmd.c:3422 #, c-format msgid "misplaced NOT DEFERRABLE clause" msgstr "NOT DEFERRABLE å­å¥ä½ç½®é”™è¯¯" -#: parser/parse_utilcmd.c:2749 +#: parser/parse_utilcmd.c:3435 parser/parse_utilcmd.c:3461 gram.y:5529 +#, c-format +msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +msgstr "约æŸå£°æ˜Ž INITIALLY DEFERRED 必须为 DEFERRABLE" + +#: parser/parse_utilcmd.c:3443 #, c-format msgid "misplaced INITIALLY DEFERRED clause" msgstr "INITIALLY DEFERRED å­å¥ä½ç½®é”™è¯¯" -#: parser/parse_utilcmd.c:2754 parser/parse_utilcmd.c:2780 +#: parser/parse_utilcmd.c:3448 parser/parse_utilcmd.c:3474 #, c-format msgid "multiple INITIALLY IMMEDIATE/DEFERRED clauses not allowed" msgstr "ä¸å…许多个 INITIALLY IMMEDIATE/DEFERRED å­å¥" -#: parser/parse_utilcmd.c:2775 +#: parser/parse_utilcmd.c:3469 #, c-format msgid "misplaced INITIALLY IMMEDIATE clause" msgstr "INITIALLY IMMEDIATE å­å¥ä½ç½®é”™è¯¯" -#: parser/parse_utilcmd.c:2966 +#: parser/parse_utilcmd.c:3660 #, c-format -msgid "" -"CREATE specifies a schema (%s) different from the one being created (%s)" +msgid "CREATE specifies a schema (%s) different from the one being created (%s)" msgstr "CREATE æŒ‡å®šçš„æ¨¡å¼ (%s) 和将è¦åˆ›å»ºçš„ (%s) ä¸åŒ" +#: parser/parse_utilcmd.c:3694 +#, c-format +msgid "table \"%s\" is not partitioned" +msgstr "表\"%s\"未分区" + +#: parser/parse_utilcmd.c:3701 +#, c-format +msgid "index \"%s\" is not partitioned" +msgstr "索引 \"%s\" 未分区" + +#: parser/parse_utilcmd.c:3735 +#, c-format +msgid "a hash-partitioned table may not have a default partition" +msgstr "哈希分区表å¯èƒ½æ²¡æœ‰é»˜è®¤åˆ†åŒº" + +#: parser/parse_utilcmd.c:3752 +#, c-format +msgid "invalid bound specification for a hash partition" +msgstr "哈希分区的绑定规范无效" + +#: parser/parse_utilcmd.c:3758 partitioning/partbounds.c:2802 +#, c-format +msgid "modulus for hash partition must be a positive integer" +msgstr "哈希分区的模数必须是正整数" + +#: parser/parse_utilcmd.c:3765 partitioning/partbounds.c:2810 +#, c-format +msgid "remainder for hash partition must be less than modulus" +msgstr "哈希分区的余数必须å°äºŽæ¨¡æ•°" + +#: parser/parse_utilcmd.c:3778 +#, c-format +msgid "invalid bound specification for a list partition" +msgstr "列表分区的绑定规范无效" + +#: parser/parse_utilcmd.c:3831 +#, c-format +msgid "invalid bound specification for a range partition" +msgstr "范围分区的绑定规范无效" + +#: parser/parse_utilcmd.c:3837 +#, c-format +msgid "FROM must specify exactly one value per partitioning column" +msgstr "FROM必须为æ¯ä¸ªåˆ†åŒºåˆ—指定一个值" + +#: parser/parse_utilcmd.c:3841 +#, c-format +msgid "TO must specify exactly one value per partitioning column" +msgstr "TO必须为æ¯ä¸ªåˆ†åŒºåˆ—指定一个值" + +#: parser/parse_utilcmd.c:3955 +#, c-format +msgid "cannot specify NULL in range bound" +msgstr "无法在范围绑定中指定 NULL" + +#: parser/parse_utilcmd.c:4004 +#, c-format +msgid "every bound following MAXVALUE must also be MAXVALUE" +msgstr "MAXVALUEåŽé¢çš„æ¯ä¸ªç»‘å®šä¹Ÿå¿…é¡»æ˜¯MAXVALUE" + +#: parser/parse_utilcmd.c:4011 +#, c-format +msgid "every bound following MINVALUE must also be MINVALUE" +msgstr "MINVALUEåŽé¢çš„æ¯ä¸ªç»‘å®šä¹Ÿå¿…é¡»æ˜¯MINVALUE" + +#: parser/parse_utilcmd.c:4046 +#, fuzzy, c-format +#| msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgid "collation of partition bound value for column \"%s\" does not match partition key collation \"%s\"" +msgstr "分区列数(%d)与æä¾›çš„分区键数(%d)ä¸åŒ¹é…" + +#: parser/parse_utilcmd.c:4063 +#, c-format +msgid "specified value cannot be cast to type %s for column \"%s\"" +msgstr "ä¸èƒ½å°†æŒ‡å®šçš„值强制转æ¢ä¸ºåˆ—\"%2$s\"的类型%1$s" + #: parser/scansup.c:204 #, c-format msgid "identifier \"%s\" will be truncated to \"%s\"" msgstr "标识符\"%s\"将会被截断为\"%s\"" -#: port/pg_sema.c:113 port/sysv_sema.c:113 +#: partitioning/partbounds.c:959 #, c-format -msgid "could not create semaphores: %m" -msgstr "无法创建信å·é‡: %m" +msgid "partition \"%s\" conflicts with existing default partition \"%s\"" +msgstr "分区\"%s\"与现有默认分区\"%s\"冲çª" -#: port/pg_sema.c:114 port/sysv_sema.c:114 +#: partitioning/partbounds.c:1018 #, c-format -msgid "Failed system call was semget(%lu, %d, 0%o)." -msgstr "semget(%lu, %d, 0%o) 系统调用失败." +msgid "every hash partition modulus must be a factor of the next larger modulus" +msgstr "æ¯ä¸ªæ•£åˆ—分区模必须是下一个较大模的因å­" -#: port/pg_sema.c:118 port/sysv_sema.c:118 +#: partitioning/partbounds.c:1114 #, c-format -msgid "" -"This error does *not* mean that you have run out of disk space. It occurs " -"when either the system limit for the maximum number of semaphore sets " -"(SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be " -"exceeded. You need to raise the respective kernel parameter. " -"Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its " -"max_connections parameter.\n" -"The PostgreSQL documentation contains more information about configuring " -"your system for PostgreSQL." -msgstr "" -"这个错误ä¸è¡¨ç¤ºç£ç›˜ç©ºé—´å·²ç»ç”¨å®Œ. å‘生的原因有å¯èƒ½è¶…过系统对于最大数é‡ä¿¡å·ç¯é›†" -"åˆ(ç”±å‚æ•°SEMMNI表示),或者是对系统范围内最大å¯ä½¿ç”¨ä¿¡å·ç¯(ç”±å‚æ•°SEMMNS表示)çš„" -"é™åˆ¶.您需è¦å¢žåŠ è¿™ä¸¤ä¸ªç³»ç»Ÿæ ¸å¿ƒå‚æ•°çš„值。å¦å¤–也å¯ä»¥é€šè¿‡iå‡å°PostgreSQL傿•°" -"max_connectionsæ¥å‡å°‘它所消耗的信å·ç¯æ€»æ•°.\n" -"在PostgreSQL文档中包å«äº†æ›´å¤šå…³äºŽå¦‚何é…ç½®PostgreSQL的信æ¯ã€‚" +msgid "empty range bound specified for partition \"%s\"" +msgstr "为分区\"%s\"指定的空范围绑定" -#: port/pg_sema.c:148 port/sysv_sema.c:148 +#: partitioning/partbounds.c:1116 #, c-format -msgid "" -"You possibly need to raise your kernel's SEMVMX value to be at least %d. " -"Look into the PostgreSQL documentation for details." -msgstr "" -"ä½ å¯èƒ½éœ€è¦å¢žåŠ å†…æ ¸çš„ SEMVMX 值至少为 %d. 详细信æ¯è¯·æŸ¥æ‰¾ PostgreSQL 文档." +msgid "Specified lower bound %s is greater than or equal to upper bound %s." +msgstr "指定的下é™%s大于或等于上é™%s" + +#: partitioning/partbounds.c:1213 +#, c-format +msgid "partition \"%s\" would overlap partition \"%s\"" +msgstr "分区 \"%s\"会é‡å åˆ†åŒº\"%s\"" + +#: partitioning/partbounds.c:1311 +#, c-format +msgid "skipped scanning foreign table \"%s\" which is a partition of default partition \"%s\"" +msgstr "跳过扫æå¤–部表\"%s\",该表是默认分区 \"%s\"的分区" + +#: partitioning/partbounds.c:1348 +#, c-format +msgid "updated partition constraint for default partition \"%s\" would be violated by some row" +msgstr "æŸäº›è¡Œå°†è¿å默认分区\"%s\"的更新分区约æŸ" + +#: partitioning/partbounds.c:2806 +#, c-format +msgid "remainder for hash partition must be a non-negative integer" +msgstr "哈希分区的余数必须是éžè´Ÿæ•´æ•°" + +#: partitioning/partbounds.c:2833 +#, c-format +msgid "\"%s\" is not a hash partitioned table" +msgstr "\"%s\" 䏿˜¯å“ˆå¸Œåˆ†åŒºè¡¨" + +#: partitioning/partbounds.c:2844 partitioning/partbounds.c:2961 +#, c-format +msgid "number of partitioning columns (%d) does not match number of partition keys provided (%d)" +msgstr "分区列数(%d)与æä¾›çš„分区键数(%d)ä¸åŒ¹é…" + +#: partitioning/partbounds.c:2866 partitioning/partbounds.c:2898 +#, c-format +msgid "column %d of the partition key has type \"%s\", but supplied value is of type \"%s\"" +msgstr "分区键的列%d的类型为\"%s\",但æä¾›çš„值的类型为\"%s\"" -#: port/pg_shmem.c:141 port/sysv_shmem.c:141 +#: port/pg_shmem.c:216 port/sysv_shmem.c:216 #, c-format msgid "could not create shared memory segment: %m" msgstr "无法创建共享内存段: %m" -#: port/pg_shmem.c:142 port/sysv_shmem.c:142 +#: port/pg_shmem.c:217 port/sysv_shmem.c:217 #, c-format msgid "Failed system call was shmget(key=%lu, size=%zu, 0%o)." msgstr "系统调用shmget(key=%lu, size=%zu, 0%o) 执行失败." -#: port/pg_shmem.c:146 port/sysv_shmem.c:146 +#: port/pg_shmem.c:221 port/sysv_shmem.c:221 #, c-format msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded your kernel's SHMMAX parameter, or possibly that it is less " -"than your kernel's SHMMIN parameter.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter, or possibly that it is less than your kernel's SHMMIN parameter.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"这个错误通常表示PostgreSQL所请求的共享内存段超过了内核中的SHMMAX傿•°å€¼ï¼Œæˆ–者" -"å°äºŽå†…核中的SHMMIN傿•°å€¼ã€‚\n" +"这个错误通常表示PostgreSQL所请求的共享内存段超过了内核中的SHMMAX傿•°å€¼ï¼Œæˆ–者å°äºŽå†…核中的SHMMIN傿•°å€¼ã€‚\n" "PostgreSQL文档包å«äº†å…³äºŽå¦‚何é…置共享内存的更多信æ¯." -#: port/pg_shmem.c:153 port/sysv_shmem.c:153 +#: port/pg_shmem.c:228 port/sysv_shmem.c:228 #, c-format msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded your kernel's SHMALL parameter. You might need to " -"reconfigure the kernel with larger SHMALL.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." +"This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMALL parameter. You might need to reconfigure the kernel with larger SHMALL.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"这个错误通常表示PostgreSQL所请求的共享内存段超过了内核中设定的SHMALL傿•°å€¼ã€‚" -"您å¯ä»¥é‡æ–°é…置内核, 使用更大的SHMALL傿•°å€¼.\n" +"这个错误通常表示PostgreSQL所请求的共享内存段超过了内核中设定的SHMALL傿•°å€¼ã€‚您å¯ä»¥é‡æ–°é…置内核, 使用更大的SHMALL傿•°å€¼.\n" "PostgreSQL文档包å«äº†å…³äºŽå¦‚何é…置共享内存的更多信æ¯." -#: port/pg_shmem.c:159 port/sysv_shmem.c:159 +#: port/pg_shmem.c:234 port/sysv_shmem.c:234 #, c-format msgid "" -"This error does *not* mean that you have run out of disk space. It occurs " -"either if all available shared memory IDs have been taken, in which case you " -"need to raise the SHMMNI parameter in your kernel, or because the system's " -"overall limit for shared memory has been reached.\n" -"The PostgreSQL documentation contains more information about shared memory " -"configuration." +"This error does *not* mean that you have run out of disk space. It occurs either if all available shared memory IDs have been taken, in which case you need to raise the SHMMNI parameter in your kernel, or because the system's overall limit for shared memory has been reached.\n" +"The PostgreSQL documentation contains more information about shared memory configuration." msgstr "" -"这个错误ä¸è¡¨ç¤ºæ‚¨ç³»ç»Ÿä¸Šç£ç›˜ç©ºé—´å·²ç»ç”¨å°½.原因既有å¯èƒ½æ˜¯ç³»ç»Ÿä¸Šæ‰€æœ‰çš„æœ‰æ•ˆå…±äº«å†…å­˜" -"IDä¸å­˜åœ¨äº†ï¼Œè¿™æ ·éœ€è¦åœ¨å†…核中å‡é«˜SHMMNI傿•°çš„值,或者是因为已到达系统最大的共" -"享内存é™åˆ¶.如果无法增加共享内存的上é™å€¼.\n" +"这个错误ä¸è¡¨ç¤ºæ‚¨ç³»ç»Ÿä¸Šç£ç›˜ç©ºé—´å·²ç»ç”¨å°½.原因既有å¯èƒ½æ˜¯ç³»ç»Ÿä¸Šæ‰€æœ‰çš„æœ‰æ•ˆå…±äº«å†…å­˜IDä¸å­˜åœ¨äº†ï¼Œè¿™æ ·éœ€è¦åœ¨å†…核中å‡é«˜SHMMNI傿•°çš„值,或者是因为已到达系统最大的共享内存é™åˆ¶.如果无法增加共享内存的上é™å€¼.\n" "在PostgreSQL文档中包å«äº†å…³äºŽå¦‚何é…置共享内存的更多信æ¯." -#: port/pg_shmem.c:340 port/sysv_shmem.c:340 -#, c-format -msgid "huge TLB pages not supported on this platform" -msgstr "在此平å°ä¸Šä¸æ”¯æŒå·¨åž‹çš„TLB页" - -#: port/pg_shmem.c:390 port/sysv_shmem.c:390 +#: port/pg_shmem.c:577 port/sysv_shmem.c:577 #, c-format msgid "could not map anonymous shared memory: %m" msgstr "无法映射匿å共享内存: %m" -#: port/pg_shmem.c:392 port/sysv_shmem.c:392 +#: port/pg_shmem.c:579 port/sysv_shmem.c:579 #, c-format -msgid "" -"This error usually means that PostgreSQL's request for a shared memory " -"segment exceeded available memory, swap space, or huge pages. To reduce the " -"request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, " -"perhaps by reducing shared_buffers or max_connections." -msgstr "" -"这个错误通常表示PostgreSQL所请求的共享内存段超过了å¯ç”¨å†…å­˜æ€»é‡æˆ–者交æ¢ç©ºé—´æˆ–" -"者巨型页大å°ã€‚为å‡å°‘所请求空间的大å°(当剿˜¯%zu字节),å‡å°‘PostgreSQL文档包å«äº†" -"关于如何é…置共享内存的更多信æ¯." +msgid "This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently %zu bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections." +msgstr "这个错误通常表示PostgreSQL所请求的共享内存段超过了å¯ç”¨å†…å­˜æ€»é‡æˆ–者交æ¢ç©ºé—´æˆ–者巨型页大å°ã€‚为å‡å°‘所请求空间的大å°(当剿˜¯%zu字节),å‡å°‘PostgreSQL文档包å«äº†å…³äºŽå¦‚何é…置共享内存的更多信æ¯." -#: port/pg_shmem.c:439 port/sysv_shmem.c:439 port/win32_shmem.c:134 +#: port/pg_shmem.c:639 port/sysv_shmem.c:639 #, c-format msgid "huge pages not supported on this platform" msgstr "此平å°ä¸æ”¯æŒå·¨åž‹é¡µ" -#: port/pg_shmem.c:553 port/sysv_shmem.c:553 +#: port/pg_shmem.c:700 port/sysv_shmem.c:700 utils/init/miscinit.c:1069 +#, c-format +msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" +msgstr "å…ˆå‰å­˜åœ¨çš„å…±äº«å†…å­˜å— (key %lu, ID %lu) ä»åœ¨ä½¿ç”¨ä¸­" + +#: port/pg_shmem.c:703 port/sysv_shmem.c:703 utils/init/miscinit.c:1071 +#, c-format +msgid "Terminate any old server processes associated with data directory \"%s\"." +msgstr "" + +#: port/pg_shmem.c:754 port/sysv_shmem.c:754 #, c-format msgid "could not stat data directory \"%s\": %m" msgstr "无法å–目录 \"%s\" 状æ€: %m" -#: port/win32/crashdump.c:108 +#: port/sysv_sema.c:123 +#, c-format +msgid "could not create semaphores: %m" +msgstr "无法创建信å·é‡: %m" + +#: port/sysv_sema.c:124 +#, c-format +msgid "Failed system call was semget(%lu, %d, 0%o)." +msgstr "semget(%lu, %d, 0%o) 系统调用失败." + +#: port/sysv_sema.c:128 +#, c-format +msgid "" +"This error does *not* mean that you have run out of disk space. It occurs when either the system limit for the maximum number of semaphore sets (SEMMNI), or the system wide maximum number of semaphores (SEMMNS), would be exceeded. You need to raise the respective kernel parameter. Alternatively, reduce PostgreSQL's consumption of semaphores by reducing its max_connections parameter.\n" +"The PostgreSQL documentation contains more information about configuring your system for PostgreSQL." +msgstr "" +"这个错误ä¸è¡¨ç¤ºç£ç›˜ç©ºé—´å·²ç»ç”¨å®Œ. å‘生的原因有å¯èƒ½è¶…过系统对于最大数é‡ä¿¡å·ç¯é›†åˆ(ç”±å‚æ•°SEMMNI表示),或者是对系统范围内最大å¯ä½¿ç”¨ä¿¡å·ç¯(ç”±å‚æ•°SEMMNS表示)çš„é™åˆ¶.您需è¦å¢žåŠ è¿™ä¸¤ä¸ªç³»ç»Ÿæ ¸å¿ƒå‚æ•°çš„值。å¦å¤–也å¯ä»¥é€šè¿‡iå‡å°PostgreSQL傿•°max_connectionsæ¥å‡å°‘它所消耗的信å·ç¯æ€»æ•°.\n" +"在PostgreSQL文档中包å«äº†æ›´å¤šå…³äºŽå¦‚何é…ç½®PostgreSQL的信æ¯ã€‚" + +#: port/sysv_sema.c:158 +#, c-format +msgid "You possibly need to raise your kernel's SEMVMX value to be at least %d. Look into the PostgreSQL documentation for details." +msgstr "ä½ å¯èƒ½éœ€è¦å¢žåŠ å†…æ ¸çš„ SEMVMX 值至少为 %d. 详细信æ¯è¯·æŸ¥æ‰¾ PostgreSQL 文档." + +#: port/win32/crashdump.c:121 #, c-format msgid "could not load dbghelp.dll, cannot write crash dump\n" msgstr "无法加载dbghelp.dll动æ€åº“, 无法生æˆå´©æºƒè½¬å‚¨æ–‡ä»¶\n" -#: port/win32/crashdump.c:116 +#: port/win32/crashdump.c:129 #, c-format -msgid "" -"could not load required functions in dbghelp.dll, cannot write crash dump\n" +msgid "could not load required functions in dbghelp.dll, cannot write crash dump\n" msgstr "无法从dbghelp.dll动æ€åº“中加载所需è¦çš„函数, 无法生æˆå´©æºƒè½¬å‚¨æ–‡ä»¶\n" -#: port/win32/crashdump.c:147 +#: port/win32/crashdump.c:160 #, c-format msgid "could not open crash dump file \"%s\" for writing: error code %lu\n" msgstr "无法打开崩溃转储文件 \"%s\"执行写æ“作: é”™è¯¯ç  %lu\n" # command.c:646 -#: port/win32/crashdump.c:154 +#: port/win32/crashdump.c:167 #, c-format msgid "wrote crash dump to file \"%s\"\n" msgstr "生æˆå´©æºƒè½¬å‚¨æ–‡ä»¶\"%s\"\n" -#: port/win32/crashdump.c:156 +#: port/win32/crashdump.c:169 #, c-format msgid "could not write crash dump to file \"%s\": error code %lu\n" msgstr "无法写入崩溃转储文件 \"%s\": é”™è¯¯ç  %lu\n" -#: port/win32/signal.c:194 +#: port/win32/signal.c:196 #, c-format msgid "could not create signal listener pipe for PID %d: error code %lu" msgstr "无法为进程PID %d 创建信å·ç›‘å¬ç®¡é“: 错误ç ä¸º %lu" -#: port/win32/signal.c:274 port/win32/signal.c:306 +#: port/win32/signal.c:277 port/win32/signal.c:309 #, c-format msgid "could not create signal listener pipe: error code %lu; retrying\n" msgstr "无法创建信å·ç›‘å¬ç®¡é“: é”™è¯¯ç  %lu; é‡è¯•\n" -#: port/win32/signal.c:317 +#: port/win32/signal.c:320 #, c-format msgid "could not create signal dispatch thread: error code %lu\n" msgstr "无法创建信å·åˆ†å‘线程: é”™è¯¯ç  %lu\n" -#: port/win32_sema.c:94 +#: port/win32_sema.c:104 #, c-format msgid "could not create semaphore: error code %lu" msgstr "无法创建信å·é‡: é”™è¯¯ä»£ç  %lu" -#: port/win32_sema.c:167 +#: port/win32_sema.c:181 #, c-format msgid "could not lock semaphore: error code %lu" msgstr "无法é”定信å·ç¯(semaphore): 错误代ç %lu" -#: port/win32_sema.c:187 +#: port/win32_sema.c:201 #, c-format msgid "could not unlock semaphore: error code %lu" msgstr "无法对信å·ç¯(semaphore)è§£é”: é”™è¯¯ä»£ç  %lu" -#: port/win32_sema.c:216 +#: port/win32_sema.c:231 #, c-format msgid "could not try-lock semaphore: error code %lu" msgstr "无法进行é”定信å·ç¯(semaphore)çš„å°è¯•: é”™è¯¯ä»£ç  %lu" -#: port/win32_shmem.c:173 port/win32_shmem.c:208 port/win32_shmem.c:226 +#: port/win32_shmem.c:144 port/win32_shmem.c:152 port/win32_shmem.c:164 +#: port/win32_shmem.c:179 +#, c-format +msgid "could not enable Lock Pages in Memory user right: error code %lu" +msgstr "无法在内存中å¯ç”¨é”定页用户æƒé™: 错误ç %lu" + +#: port/win32_shmem.c:145 port/win32_shmem.c:153 port/win32_shmem.c:165 +#: port/win32_shmem.c:180 +#, c-format +msgid "Failed system call was %s." +msgstr "失败的系统调用是%s." + +#: port/win32_shmem.c:175 +#, c-format +msgid "could not enable Lock Pages in Memory user right" +msgstr "无法在内存中å¯ç”¨é”定页用户æƒé™" + +#: port/win32_shmem.c:176 +#, c-format +msgid "Assign Lock Pages in Memory user right to the Windows user account which runs PostgreSQL." +msgstr "为è¿è¡ŒPostgreSQLçš„Windowsç”¨æˆ·å¸æˆ·åˆ†é…内存中的é”定页用户æƒé™." + +#: port/win32_shmem.c:233 +#, c-format +msgid "the processor does not support large pages" +msgstr "处ç†å™¨ä¸æ”¯æŒå¤§é¡µé¢" + +#: port/win32_shmem.c:235 port/win32_shmem.c:240 +#, c-format +msgid "disabling huge pages" +msgstr "ç¦ç”¨å¤§é¡µé¢" + +#: port/win32_shmem.c:302 port/win32_shmem.c:338 port/win32_shmem.c:356 #, c-format msgid "could not create shared memory segment: error code %lu" msgstr "无法创建共享内存段: 错误ç %lu" -#: port/win32_shmem.c:174 +#: port/win32_shmem.c:303 #, c-format msgid "Failed system call was CreateFileMapping(size=%zu, name=%s)." msgstr "系统调用CreateFileMapping(size=%zu, name=%s)执行失败." -#: port/win32_shmem.c:198 +#: port/win32_shmem.c:328 #, c-format msgid "pre-existing shared memory block is still in use" msgstr "已存在的共享内存å—ä»åœ¨ä½¿ç”¨ä¸­" -#: port/win32_shmem.c:199 +#: port/win32_shmem.c:329 #, c-format -msgid "" -"Check if there are any old server processes still running, and terminate " -"them." +msgid "Check if there are any old server processes still running, and terminate them." msgstr "检查原先的æœåŠ¡å™¨è¿›ç¨‹æ˜¯å¦ä»åœ¨è¿è¡Œï¼Œå¦‚果是的è¯è¯·ç»ˆæ­¢è¿™äº›è¿›ç¨‹." -#: port/win32_shmem.c:209 +#: port/win32_shmem.c:339 #, c-format msgid "Failed system call was DuplicateHandle." msgstr "系统调用DuplicateHandle执行失败" -#: port/win32_shmem.c:227 +#: port/win32_shmem.c:357 #, c-format msgid "Failed system call was MapViewOfFileEx." msgstr "系统调用MapViewOfFileEx执行失败." -#: postmaster/autovacuum.c:377 +#: postmaster/autovacuum.c:405 #, c-format msgid "could not fork autovacuum launcher process: %m" msgstr "无法派生autovacuumå¯åŠ¨è¿›ç¨‹: %m" -#: postmaster/autovacuum.c:413 +#: postmaster/autovacuum.c:441 #, c-format msgid "autovacuum launcher started" msgstr "å·²å¯åЍautovacuum" -#: postmaster/autovacuum.c:775 +#: postmaster/autovacuum.c:819 #, c-format msgid "autovacuum launcher shutting down" msgstr "正在关闭autovacuumå¯åŠ¨è¿›ç¨‹" -#: postmaster/autovacuum.c:1443 +#: postmaster/autovacuum.c:1481 #, c-format msgid "could not fork autovacuum worker process: %m" msgstr "无法派生autovacuum工作进程: %m" -#: postmaster/autovacuum.c:1639 +#: postmaster/autovacuum.c:1687 #, c-format msgid "autovacuum: processing database \"%s\"" msgstr "autovacuum: æ­£åœ¨å¤„ç†æ•°æ®åº“ \"%s\"" -#: postmaster/autovacuum.c:2051 -#, c-format -msgid "autovacuum: dropping orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "autovacuum: 正在数æ®åº“\"%3$s\"中删除é—留的临时表\"%1$s\".\"%2$s\"" - -#: postmaster/autovacuum.c:2063 +#: postmaster/autovacuum.c:2256 #, c-format -msgid "autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"" -msgstr "autovacuum: 在数æ®åº“\"%3$s\"中找到é—留的临时表\"%1$s\".\"%2$s\"" +msgid "autovacuum: dropping orphan temp table \"%s.%s.%s\"" +msgstr "autovacuum: 正在删除é—留的临时表\"%s.%s.%s\"" -#: postmaster/autovacuum.c:2346 +#: postmaster/autovacuum.c:2485 #, c-format msgid "automatic vacuum of table \"%s.%s.%s\"" msgstr "对表\"%s.%s.%s\"进行自动清ç†" -#: postmaster/autovacuum.c:2349 +#: postmaster/autovacuum.c:2488 #, c-format msgid "automatic analyze of table \"%s.%s.%s\"" msgstr "对表\"%s.%s.%s\"进行自动分æž" -#: postmaster/autovacuum.c:2877 +#: postmaster/autovacuum.c:2681 +#, c-format +msgid "processing work entry for relation \"%s.%s.%s\"" +msgstr "正在处ç†å…³ç³»\"%s.%s.%s\"的工作项" + +#: postmaster/autovacuum.c:3262 #, c-format msgid "autovacuum not started because of misconfiguration" msgstr "因为é…制错误,而无法å¯åЍautovacuum" -#: postmaster/autovacuum.c:2878 +#: postmaster/autovacuum.c:3263 #, c-format msgid "Enable the \"track_counts\" option." msgstr "å¯ç”¨é€‰é¡¹\"track_counts\" " -#: postmaster/bgworker.c:346 postmaster/bgworker.c:746 +#: postmaster/bgworker.c:395 postmaster/bgworker.c:855 #, c-format msgid "registering background worker \"%s\"" msgstr "注册åŽå°å·¥ä½œè¿›ç¨‹ \"%s\"" -#: postmaster/bgworker.c:375 +#: postmaster/bgworker.c:427 #, c-format msgid "unregistering background worker \"%s\"" msgstr "注销åŽå°å·¥ä½œè¿›ç¨‹ \"%s\"" -#: postmaster/bgworker.c:484 +#: postmaster/bgworker.c:592 #, c-format -msgid "" -"background worker \"%s\": must attach to shared memory in order to request a " -"database connection" +msgid "background worker \"%s\": must attach to shared memory in order to request a database connection" msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": 必须关è”到共享内存,以用于请求一个数æ®åº“连接 " -#: postmaster/bgworker.c:493 +#: postmaster/bgworker.c:601 #, c-format -msgid "" -"background worker \"%s\": cannot request database access if starting at " -"postmaster start" -msgstr "" -"åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": 如果是在postmasterå¯åŠ¨æ—¶å¯åŠ¨ï¼Œåˆ™æ— æ³•è¯·æ±‚æ•°æ®åº“访问 " +msgid "background worker \"%s\": cannot request database access if starting at postmaster start" +msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": 如果是在postmasterå¯åŠ¨æ—¶å¯åŠ¨ï¼Œåˆ™æ— æ³•è¯·æ±‚æ•°æ®åº“访问 " -#: postmaster/bgworker.c:507 +#: postmaster/bgworker.c:615 #, c-format msgid "background worker \"%s\": invalid restart interval" msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": 无效的é‡å¯æ—¶é—´é—´éš”" -#: postmaster/bgworker.c:552 +#: postmaster/bgworker.c:630 +#, c-format +msgid "background worker \"%s\": parallel workers may not be configured for restart" +msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": ä¸èƒ½ä¸ºé‡æ–°å¯åЍé…置并行工作线程" + +#: postmaster/bgworker.c:674 #, c-format msgid "terminating background worker \"%s\" due to administrator command" msgstr "由于管ç†å‘˜å‘½ä»¤ä¸­æ–­åŽå°å·¥ä½œè¿›ç¨‹\"%s\"" -#: postmaster/bgworker.c:753 +#: postmaster/bgworker.c:863 #, c-format -msgid "" -"background worker \"%s\": must be registered in shared_preload_libraries" +msgid "background worker \"%s\": must be registered in shared_preload_libraries" msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": 必须注册于库 shared_preload_libraries中" -#: postmaster/bgworker.c:765 +#: postmaster/bgworker.c:875 #, c-format -msgid "" -"background worker \"%s\": only dynamic background workers can request " -"notification" +msgid "background worker \"%s\": only dynamic background workers can request notification" msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\": åªæœ‰åЍæ€å·¥ä½œè¿›ç¨‹å¯ä»¥è¯·æ±‚通知" -#: postmaster/bgworker.c:780 +#: postmaster/bgworker.c:890 #, c-format msgid "too many background workers" msgstr "太多åŽå°å·¥ä½œè¿›ç¨‹" -#: postmaster/bgworker.c:781 +#: postmaster/bgworker.c:891 #, c-format msgid "Up to %d background worker can be registered with the current settings." -msgid_plural "" -"Up to %d background workers can be registered with the current settings." +msgid_plural "Up to %d background workers can be registered with the current settings." msgstr[0] "当å‰è®¾ç½®é‡Œæœ€å¤šå¯ä»¥æ³¨å†Œ%d个åŽå°å·¥ä½œè¿›ç¨‹." -#: postmaster/bgworker.c:785 +#: postmaster/bgworker.c:895 #, c-format -msgid "" -"Consider increasing the configuration parameter \"max_worker_processes\"." +msgid "Consider increasing the configuration parameter \"max_worker_processes\"." msgstr "考虑增大é…ç½®å‚æ•° \"max_worker_processes\"的值." -#: postmaster/checkpointer.c:465 +#: postmaster/checkpointer.c:458 #, c-format msgid "checkpoints are occurring too frequently (%d second apart)" msgid_plural "checkpoints are occurring too frequently (%d seconds apart)" msgstr[0] "检查点事件å‘生过于频ç¹(%d ç§’é—´éš”)" -#: postmaster/checkpointer.c:469 +#: postmaster/checkpointer.c:462 #, c-format msgid "Consider increasing the configuration parameter \"max_wal_size\"." msgstr "考虑增大é…ç½®å‚æ•° \"max_wal_size\"的值。" -#: postmaster/checkpointer.c:616 -#, c-format -msgid "transaction log switch forced (archive_timeout=%d)" -msgstr "强制切æ¢äº‹åŠ¡æ—¥å¿— (archive_timeout=%d)" - -#: postmaster/checkpointer.c:1074 +#: postmaster/checkpointer.c:1081 #, c-format msgid "checkpoint request failed" msgstr "检查点请求失败" -#: postmaster/checkpointer.c:1075 +#: postmaster/checkpointer.c:1082 #, c-format msgid "Consult recent messages in the server log for details." msgstr "详细信æ¯è¯·å‚考æœåŠ¡å™¨æ—¥å¿—." -#: postmaster/checkpointer.c:1270 +#: postmaster/checkpointer.c:1267 #, c-format msgid "compacted fsync request queue from %d entries to %d entries" msgstr "å°†fsync请求队列从%d压缩至%d项" -#: postmaster/pgarch.c:149 +#: postmaster/pgarch.c:159 #, c-format msgid "could not fork archiver: %m" msgstr "无法 fork archiver: %m" -#: postmaster/pgarch.c:456 +#: postmaster/pgarch.c:470 #, c-format msgid "archive_mode enabled, yet archive_command is not set" msgstr "å·²å¯ç”¨å½’档模å¼å‚æ•°archive_modeï¼Œä½†æ˜¯è¿˜æ²¡æœ‰è®¾ç½®å‚æ•°archive_command is" -#: postmaster/pgarch.c:484 +#: postmaster/pgarch.c:492 +#, fuzzy, c-format +#| msgid "could not create archive status file \"%s\": %m" +msgid "removed orphan archive status file \"%s\"" +msgstr "æ— æ³•åˆ›å»ºå½’æ¡£çŠ¶æ€æ–‡ä»¶ \"%s\": %m" + +#: postmaster/pgarch.c:502 +#, fuzzy, c-format +#| msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgid "removal of orphan archive status file \"%s\" failed too many times, will try again later" +msgstr "归档预写日志文件 \"%s\" 多次失败, 将会é‡è¯•" + +#: postmaster/pgarch.c:538 #, c-format -msgid "" -"archiving transaction log file \"%s\" failed too many times, will try again " -"later" -msgstr "归档事务日志文件 \"%s\" 多次失败, 将会é‡è¯•" +msgid "archiving write-ahead log file \"%s\" failed too many times, will try again later" +msgstr "归档预写日志文件 \"%s\" 多次失败, 将会é‡è¯•" -#: postmaster/pgarch.c:587 +#: postmaster/pgarch.c:639 #, c-format msgid "archive command failed with exit code %d" msgstr "归档命令执行失败,退出代ç ä¸º %d" -#: postmaster/pgarch.c:589 postmaster/pgarch.c:599 postmaster/pgarch.c:606 -#: postmaster/pgarch.c:612 postmaster/pgarch.c:621 +#: postmaster/pgarch.c:641 postmaster/pgarch.c:651 postmaster/pgarch.c:657 +#: postmaster/pgarch.c:666 #, c-format msgid "The failed archive command was: %s" msgstr "执行失败的归档命令是: %s" -#: postmaster/pgarch.c:596 +#: postmaster/pgarch.c:648 #, c-format msgid "archive command was terminated by exception 0x%X" msgstr "归档命令被异常 0x%X 终止" -#: postmaster/pgarch.c:598 postmaster/postmaster.c:3478 +#: postmaster/pgarch.c:650 postmaster/postmaster.c:3669 #, c-format -msgid "" -"See C include file \"ntstatus.h\" for a description of the hexadecimal value." +msgid "See C include file \"ntstatus.h\" for a description of the hexadecimal value." msgstr "关于对16进制值的æè¿°ï¼Œ å‚è§C语言的引用文件 \"ntstatus.h\" " -#: postmaster/pgarch.c:603 +#: postmaster/pgarch.c:655 #, c-format msgid "archive command was terminated by signal %d: %s" msgstr "归档命令被信å·%d终止:%s" -#: postmaster/pgarch.c:610 -#, c-format -msgid "archive command was terminated by signal %d" -msgstr "归档命令被信å·%d终止" - -#: postmaster/pgarch.c:619 +#: postmaster/pgarch.c:664 #, c-format msgid "archive command exited with unrecognized status %d" msgstr "归档命令已退出, æœªçŸ¥çŠ¶æ€ %d" -#: postmaster/pgarch.c:631 -#, c-format -msgid "archived transaction log file \"%s\"" -msgstr "归档事务日志文件 \"%s\"" - -#: postmaster/pgarch.c:680 -#, c-format -msgid "could not open archive status directory \"%s\": %m" -msgstr "无法打开归档状æ€ç›®å½• \"%s\": %m" - -#: postmaster/pgstat.c:356 +#: postmaster/pgstat.c:396 #, c-format msgid "could not resolve \"localhost\": %s" msgstr "æ— æ³•è§£æž \"localhost\": %s" -#: postmaster/pgstat.c:379 +#: postmaster/pgstat.c:419 #, c-format msgid "trying another address for the statistics collector" msgstr "ä¸ºç»Ÿè®¡ä¿¡æ¯æ”¶é›†å™¨å°è¯•å¦ä¸€ä¸ªåœ°å€" -#: postmaster/pgstat.c:388 +#: postmaster/pgstat.c:428 #, c-format msgid "could not create socket for statistics collector: %m" msgstr "无法为统计收集器创建套接字: %m" -#: postmaster/pgstat.c:400 +#: postmaster/pgstat.c:440 #, c-format msgid "could not bind socket for statistics collector: %m" msgstr "无法绑定统计收集器的套接字: %m" -#: postmaster/pgstat.c:411 +#: postmaster/pgstat.c:451 #, c-format msgid "could not get address of socket for statistics collector: %m" msgstr "无法获得统计收集器的套接字地å€: %m" -#: postmaster/pgstat.c:427 +#: postmaster/pgstat.c:467 #, c-format msgid "could not connect socket for statistics collector: %m" msgstr "æ— æ³•è”æŽ¥ç»Ÿè®¡æ”¶é›†å™¨çš„å¥—æŽ¥å­—: %m" -#: postmaster/pgstat.c:448 +#: postmaster/pgstat.c:488 #, c-format msgid "could not send test message on socket for statistics collector: %m" msgstr "无法为统计收集器在套接字上å‘逿µ‹è¯•ä¿¡æ¯: %m" -#: postmaster/pgstat.c:474 +#: postmaster/pgstat.c:514 #, c-format msgid "select() failed in statistics collector: %m" msgstr "在统计收集器中 select() 失败: %m" -#: postmaster/pgstat.c:489 +#: postmaster/pgstat.c:529 #, c-format msgid "test message did not get through on socket for statistics collector" msgstr "ç»Ÿè®¡æ”¶é›†å™¨çš„æµ‹è¯•æ¶ˆæ¯æ²¡æœ‰é€šè¿‡å¥—接字" -#: postmaster/pgstat.c:504 +#: postmaster/pgstat.c:544 #, c-format msgid "could not receive test message on socket for statistics collector: %m" msgstr "无法为统计收集器在套接字上接收测试信æ¯: %m" -#: postmaster/pgstat.c:514 +#: postmaster/pgstat.c:554 #, c-format msgid "incorrect test message transmission on socket for statistics collector" msgstr "ç»Ÿè®¡æ”¶é›†å™¨åœ¨å¥—æŽ¥å­—ä¸Šä¸æ­£ç¡®çš„æµ‹è¯•消æ¯ä¼ è¾“" -#: postmaster/pgstat.c:537 +#: postmaster/pgstat.c:577 #, c-format msgid "could not set statistics collector socket to nonblocking mode: %m" msgstr "无法把统计收集器的套接字设置为éžé˜»å¡žæ¨¡å¼: %m" -#: postmaster/pgstat.c:547 +#: postmaster/pgstat.c:616 #, c-format msgid "disabling statistics collector for lack of working socket" msgstr "当缺ä¹å¯ç”¨å¥—æŽ¥å­—æ—¶å–æ¶ˆç»Ÿè®¡æ”¶é›†å™¨" -#: postmaster/pgstat.c:694 +#: postmaster/pgstat.c:763 #, c-format msgid "could not fork statistics collector: %m" msgstr "无法派生 (fork) 统计收集器: %m" -#: postmaster/pgstat.c:1262 +#: postmaster/pgstat.c:1347 #, c-format msgid "unrecognized reset target: \"%s\"" msgstr "未识别的é‡ç½®ç›®æ ‡:\"%s\"" -#: postmaster/pgstat.c:1263 +#: postmaster/pgstat.c:1348 #, c-format msgid "Target must be \"archiver\" or \"bgwriter\"." msgstr "目标必须是\"archiver\"或\"bgwriter\"." -#: postmaster/pgstat.c:3578 +#: postmaster/pgstat.c:4534 #, c-format msgid "could not read statistics message: %m" msgstr "无法读å–统计信æ¯: %m" -#: postmaster/pgstat.c:3909 postmaster/pgstat.c:4086 +#: postmaster/pgstat.c:4875 postmaster/pgstat.c:5032 #, c-format msgid "could not open temporary statistics file \"%s\": %m" msgstr "无法打开临时统计文件 \"%s\": %m" -#: postmaster/pgstat.c:3977 postmaster/pgstat.c:4131 +#: postmaster/pgstat.c:4942 postmaster/pgstat.c:5077 #, c-format msgid "could not write temporary statistics file \"%s\": %m" msgstr "无法写临时统计文件 \"%s\": %m" -#: postmaster/pgstat.c:3986 postmaster/pgstat.c:4140 +#: postmaster/pgstat.c:4951 postmaster/pgstat.c:5086 #, c-format msgid "could not close temporary statistics file \"%s\": %m" msgstr "无法关闭临时统计文件 \"%s\": %m" -#: postmaster/pgstat.c:3994 postmaster/pgstat.c:4148 +#: postmaster/pgstat.c:4959 postmaster/pgstat.c:5094 #, c-format msgid "could not rename temporary statistics file \"%s\" to \"%s\": %m" msgstr "无法把临时统计文件 \"%s\" é‡å‘½å为 \"%s\": %m" -#: postmaster/pgstat.c:4230 postmaster/pgstat.c:4413 postmaster/pgstat.c:4568 +#: postmaster/pgstat.c:5183 postmaster/pgstat.c:5389 postmaster/pgstat.c:5542 #, c-format msgid "could not open statistics file \"%s\": %m" msgstr "无法打开统计文件 \"%s\": %m" -#: postmaster/pgstat.c:4242 postmaster/pgstat.c:4252 postmaster/pgstat.c:4262 -#: postmaster/pgstat.c:4283 postmaster/pgstat.c:4298 postmaster/pgstat.c:4354 -#: postmaster/pgstat.c:4425 postmaster/pgstat.c:4445 postmaster/pgstat.c:4463 -#: postmaster/pgstat.c:4479 postmaster/pgstat.c:4497 postmaster/pgstat.c:4513 -#: postmaster/pgstat.c:4580 postmaster/pgstat.c:4592 postmaster/pgstat.c:4604 -#: postmaster/pgstat.c:4629 postmaster/pgstat.c:4651 +#: postmaster/pgstat.c:5195 postmaster/pgstat.c:5205 postmaster/pgstat.c:5226 +#: postmaster/pgstat.c:5248 postmaster/pgstat.c:5263 postmaster/pgstat.c:5326 +#: postmaster/pgstat.c:5401 postmaster/pgstat.c:5421 postmaster/pgstat.c:5439 +#: postmaster/pgstat.c:5455 postmaster/pgstat.c:5473 postmaster/pgstat.c:5489 +#: postmaster/pgstat.c:5554 postmaster/pgstat.c:5566 postmaster/pgstat.c:5578 +#: postmaster/pgstat.c:5603 postmaster/pgstat.c:5625 #, c-format msgid "corrupted statistics file \"%s\"" msgstr "统计文件æŸå\"%s\"" -#: postmaster/pgstat.c:4768 +#: postmaster/pgstat.c:5754 #, c-format -msgid "" -"using stale statistics instead of current ones because stats collector is " -"not responding" +msgid "using stale statistics instead of current ones because stats collector is not responding" msgstr "由于统计收集器无å“åº”è€Œä½¿ç”¨æ—§çš„ç»Ÿè®¡ä¿¡æ¯æ¥ä»£æ›¿å½“å‰çš„统计信æ¯" -#: postmaster/pgstat.c:5086 +#: postmaster/pgstat.c:6081 #, c-format msgid "database hash table corrupted during cleanup --- abort" msgstr "清ç†è¿‡ç¨‹ä¸­æ•°æ®åº“散列表æ¯å --- 终止" -#: postmaster/postmaster.c:676 +#: postmaster/postmaster.c:712 #, c-format msgid "%s: invalid argument for option -f: \"%s\"\n" msgstr "%s: 选项-fçš„å‚æ•°æ— æ•ˆ: \"%s\"\n" -#: postmaster/postmaster.c:762 +#: postmaster/postmaster.c:798 #, c-format msgid "%s: invalid argument for option -t: \"%s\"\n" msgstr "%s: -té€‰é¡¹çš„å‚æ•°æ— æ•ˆ: \"%s\"\n" -#: postmaster/postmaster.c:813 +#: postmaster/postmaster.c:849 #, c-format msgid "%s: invalid argument: \"%s\"\n" msgstr "%s: æ— æ•ˆå‚æ•°: \"%s\"\n" -#: postmaster/postmaster.c:848 -#, c-format -msgid "%s: superuser_reserved_connections must be less than max_connections\n" -msgstr "%s: 超级用户ä¿ç•™è”接数必须å°äºŽæœ€å¤§è”接数\n" - -#: postmaster/postmaster.c:853 -#, c-format -msgid "%s: max_wal_senders must be less than max_connections\n" -msgstr "%s: max_wal_senderså¿…é¡»å°äºŽæœ€å¤§è¿žæŽ¥æ•°\n" +#: postmaster/postmaster.c:891 +#, fuzzy, c-format +#| msgid "%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n" +msgid "%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n" +msgstr "%s: superuser_reserved_connections (%d) 加上 max_wal_senders (%d) 必须低于max_connections (%d)\n" -#: postmaster/postmaster.c:858 +#: postmaster/postmaster.c:898 #, c-format msgid "WAL archival cannot be enabled when wal_level is \"minimal\"" msgstr "当wal_level是\"minimal\"时无法å¯ç”¨WALå½’æ¡£" -#: postmaster/postmaster.c:861 +#: postmaster/postmaster.c:901 #, c-format -#| msgid "" -#| "WAL streaming (max_wal_senders > 0) requires wal_level \"archive\", " -#| "\"hot_standby\", or \"logical\"" -msgid "" -"WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or " -"\"logical\"" -msgstr "" -"WAL æµå¤åˆ¶ï¼ˆmax_wal_senders > 0ï¼‰è¦æ±‚å°† wal_level 设置为 \"replica\" 或 " -"\"logical\"" +msgid "WAL streaming (max_wal_senders > 0) requires wal_level \"replica\" or \"logical\"" +msgstr "WAL æµå¤åˆ¶ï¼ˆmax_wal_senders > 0ï¼‰è¦æ±‚å°† wal_level 设置为 \"replica\" 或 \"logical\"" -#: postmaster/postmaster.c:869 +#: postmaster/postmaster.c:909 #, c-format msgid "%s: invalid datetoken tables, please fix\n" msgstr "%s: 无效的 datetoken 表, 请修å¤\n" -#: postmaster/postmaster.c:961 postmaster/postmaster.c:1059 -#: utils/init/miscinit.c:1429 +#: postmaster/postmaster.c:998 +#, c-format +msgid "starting %s" +msgstr "" + +#: postmaster/postmaster.c:1027 postmaster/postmaster.c:1125 +#: utils/init/miscinit.c:1551 #, c-format msgid "invalid list syntax in parameter \"%s\"" msgstr "åœ¨å‚æ•°\"%s\"中列表语法无效" -#: postmaster/postmaster.c:992 +#: postmaster/postmaster.c:1058 #, c-format msgid "could not create listen socket for \"%s\"" msgstr "无法为 \"%s\" 创建监å¬å¥—接字" # fe-connect.c:891 -#: postmaster/postmaster.c:998 +#: postmaster/postmaster.c:1064 #, c-format msgid "could not create any TCP/IP sockets" msgstr "无法创建TCP/IP套接字" -#: postmaster/postmaster.c:1081 +#: postmaster/postmaster.c:1147 #, c-format msgid "could not create Unix-domain socket in directory \"%s\"" msgstr "在目录\"%s\"下ä¸èƒ½åˆ›å»ºUnix域的网络套接字" -#: postmaster/postmaster.c:1087 +#: postmaster/postmaster.c:1153 #, c-format msgid "could not create any Unix-domain sockets" msgstr "无法创建 Unix域 套接字" -#: postmaster/postmaster.c:1099 +#: postmaster/postmaster.c:1165 #, c-format msgid "no socket created for listening" msgstr "没有为监å¬åˆ›å»ºå¥—接字" # fe-lobj.c:412 -#: postmaster/postmaster.c:1139 +#: postmaster/postmaster.c:1205 #, c-format msgid "could not create I/O completion port for child queue" msgstr "无法为å­é˜Ÿåˆ—创建I/O完æˆç«¯å£" -#: postmaster/postmaster.c:1168 +#: postmaster/postmaster.c:1234 #, c-format msgid "%s: could not change permissions of external PID file \"%s\": %s\n" msgstr "%s: 无法改å˜å¤–部PID文件 \"%s\" çš„æƒé™: %s\n" -#: postmaster/postmaster.c:1172 +#: postmaster/postmaster.c:1238 #, c-format msgid "%s: could not write external PID file \"%s\": %s\n" msgstr "%s: 无法写入外部 PID 文件 \"%s\": %s\n" -#: postmaster/postmaster.c:1223 +#: postmaster/postmaster.c:1298 #, c-format msgid "ending log output to stderr" msgstr "终止日志输出到标准错误输出设备" -#: postmaster/postmaster.c:1224 +#: postmaster/postmaster.c:1299 #, c-format msgid "Future log output will go to log destination \"%s\"." msgstr "åŽç»­çš„æ—¥å¿—输出将进入到目标日志 \"%s\"." -#: postmaster/postmaster.c:1250 utils/init/postinit.c:214 +#: postmaster/postmaster.c:1325 utils/init/postinit.c:216 #, c-format msgid "could not load pg_hba.conf" msgstr "无法加载pg_hba.conf" -#: postmaster/postmaster.c:1276 +#: postmaster/postmaster.c:1351 #, c-format msgid "postmaster became multithreaded during startup" msgstr "在å¯åŠ¨æœŸé—´postmasterå˜æˆå¤šçº¿ç¨‹çš„" -#: postmaster/postmaster.c:1277 +#: postmaster/postmaster.c:1352 #, c-format msgid "Set the LC_ALL environment variable to a valid locale." msgstr "设定LC_ALL环境å˜é‡ä¸ºä¸€ä¸ªåˆæ³•的区域。" -#: postmaster/postmaster.c:1374 +#: postmaster/postmaster.c:1453 #, c-format msgid "%s: could not locate matching postgres executable" msgstr "%s: 无法找到匹é…çš„ postgres 执行文件" -#: postmaster/postmaster.c:1397 utils/misc/tzparser.c:341 -#, c-format -msgid "" -"This may indicate an incomplete PostgreSQL installation, or that the file " -"\"%s\" has been moved away from its proper location." -msgstr "" -"è¿™å¯èƒ½è¡¨ç¤ºPostgreSQL安装未完æˆï¼Œæˆ–者文件\"%s\"å·²ç»ä»Žæ­£ç¡®çš„ä½ç½®ç§»åŠ¨åˆ°å¦å¤–çš„ä½" -"置了." - -#: postmaster/postmaster.c:1425 -#, c-format -msgid "data directory \"%s\" does not exist" -msgstr "æ•°æ®ç›®å½• \"%s\" ä¸å­˜åœ¨" - -#: postmaster/postmaster.c:1430 -#, c-format -msgid "could not read permissions of directory \"%s\": %m" -msgstr "没有读å–目录 \"%s\" çš„æƒé™: %m" - -#: postmaster/postmaster.c:1438 -#, c-format -msgid "specified data directory \"%s\" is not a directory" -msgstr "所指定的数æ®ç›®å½• \"%s\"䏿˜¯ä¸€ä¸ªç›®å½•." - -#: postmaster/postmaster.c:1454 -#, c-format -msgid "data directory \"%s\" has wrong ownership" -msgstr "data目录 \"%s\"的所有者æƒé™é”™è¯¯." - -#: postmaster/postmaster.c:1456 -#, c-format -msgid "The server must be started by the user that owns the data directory." -msgstr "æœåŠ¡å™¨å¿…é¡»ç”±æ‹¥æœ‰data目录的用户å¯åЍ" - -#: postmaster/postmaster.c:1476 -#, c-format -msgid "data directory \"%s\" has group or world access" -msgstr "组或其他用户都å¯ä»¥è®¿é—®æ•°æ®ç›®å½• \"%s\"" - -#: postmaster/postmaster.c:1478 +#: postmaster/postmaster.c:1476 utils/misc/tzparser.c:341 #, c-format -msgid "Permissions should be u=rwx (0700)." -msgstr "æƒé™åº”该为 u=rwx (0700)." +msgid "This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location." +msgstr "è¿™å¯èƒ½è¡¨ç¤ºPostgreSQL安装未完æˆï¼Œæˆ–者文件\"%s\"å·²ç»ä»Žæ­£ç¡®çš„ä½ç½®ç§»åŠ¨åˆ°å¦å¤–çš„ä½ç½®äº†." -#: postmaster/postmaster.c:1489 +#: postmaster/postmaster.c:1503 #, c-format msgid "" "%s: could not find the database system\n" @@ -15455,1526 +16858,1921 @@ msgstr "" "预期在目录 \"%s\" 找到,\n" "但是无法打开文件 \"%s\": %s\n" -#: postmaster/postmaster.c:1666 +#: postmaster/postmaster.c:1680 #, c-format msgid "select() failed in postmaster: %m" msgstr "postmaster select() 失败: %m" -#: postmaster/postmaster.c:1816 +#: postmaster/postmaster.c:1835 #, c-format -msgid "" -"performing immediate shutdown because data directory lock file is invalid" +msgid "performing immediate shutdown because data directory lock file is invalid" msgstr "由于数æ®ç›®å½•锿–‡ä»¶éžæ³•而执行立å³å…³é—­" -#: postmaster/postmaster.c:1894 postmaster/postmaster.c:1925 +#: postmaster/postmaster.c:1934 postmaster/postmaster.c:1965 #, c-format msgid "incomplete startup packet" msgstr "ä¸å®Œæ•´çš„å¯åŠ¨åŒ…" -#: postmaster/postmaster.c:1906 +#: postmaster/postmaster.c:1946 #, c-format msgid "invalid length of startup packet" msgstr "无效的å¯åŠ¨åŒ…é•¿åº¦" -#: postmaster/postmaster.c:1964 +#: postmaster/postmaster.c:2004 #, c-format msgid "failed to send SSL negotiation response: %m" msgstr "å‘é€ SSL å商å“应失败: %m" -#: postmaster/postmaster.c:1993 +#: postmaster/postmaster.c:2031 +#, fuzzy, c-format +#| msgid "failed to send SSL negotiation response: %m" +msgid "failed to send GSSAPI negotiation response: %m" +msgstr "å‘é€ SSL å商å“应失败: %m" + +#: postmaster/postmaster.c:2056 #, c-format msgid "unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u" msgstr "䏿”¯æŒçš„å‰ç«¯åè®® %u.%u: æœåŠ¡ç«¯æ”¯æŒ %u.0 到 %u.%u" -#: postmaster/postmaster.c:2056 utils/misc/guc.c:5657 utils/misc/guc.c:5750 -#: utils/misc/guc.c:7047 utils/misc/guc.c:9783 utils/misc/guc.c:9817 +#: postmaster/postmaster.c:2120 utils/misc/guc.c:6574 utils/misc/guc.c:6610 +#: utils/misc/guc.c:6680 utils/misc/guc.c:8006 utils/misc/guc.c:10828 +#: utils/misc/guc.c:10862 #, c-format msgid "invalid value for parameter \"%s\": \"%s\"" msgstr "傿•° \"%s\" 的值无效: \"%s\"" -#: postmaster/postmaster.c:2059 +#: postmaster/postmaster.c:2123 #, c-format msgid "Valid values are: \"false\", 0, \"true\", 1, \"database\"." msgstr "有效值为:\"false\"ã€0ã€\"true\"ã€1ã€\"database\"。" -#: postmaster/postmaster.c:2079 +#: postmaster/postmaster.c:2168 #, c-format msgid "invalid startup packet layout: expected terminator as last byte" msgstr "无效的å¯åŠ¨åŒ…æ ¼å¼: 预计结æŸç¬¦ä¸ºæœ€åŽä¸€ä¸ªå­—节" -#: postmaster/postmaster.c:2107 +#: postmaster/postmaster.c:2206 #, c-format msgid "no PostgreSQL user name specified in startup packet" msgstr "在å¯åŠ¨åŒ…ä¸­æ²¡æœ‰æŒ‡å®š PostgreSQL 用户å" -#: postmaster/postmaster.c:2166 +#: postmaster/postmaster.c:2265 #, c-format msgid "the database system is starting up" msgstr "æ•°æ®åº“系统å¯åЍ䏭" -#: postmaster/postmaster.c:2171 +#: postmaster/postmaster.c:2270 #, c-format msgid "the database system is shutting down" msgstr "æ•°æ®åº“ç³»ç»Ÿåœæ­¢ä¸­" -#: postmaster/postmaster.c:2176 +#: postmaster/postmaster.c:2275 #, c-format msgid "the database system is in recovery mode" msgstr "æ•°æ®åº“系统在æ¢å¤æ¨¡å¼ä¸­" -#: postmaster/postmaster.c:2181 storage/ipc/procarray.c:297 -#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:340 +#: postmaster/postmaster.c:2280 storage/ipc/procarray.c:293 +#: storage/ipc/sinvaladt.c:298 storage/lmgr/proc.c:363 #, c-format msgid "sorry, too many clients already" msgstr "对ä¸èµ·, å·²ç»æœ‰å¤ªå¤šçš„客户" -#: postmaster/postmaster.c:2243 +#: postmaster/postmaster.c:2370 #, c-format msgid "wrong key in cancel request for process %d" msgstr "对于进程 %dï¼Œåœ¨å–æ¶ˆè¯·æ±‚中的键值错误" -#: postmaster/postmaster.c:2251 +#: postmaster/postmaster.c:2382 #, c-format msgid "PID %d in cancel request did not match any process" msgstr "æ²¡æœ‰è¿›ç¨‹ä¸Žå–æ¶ˆè¯·æ±‚中的PID %d 相匹é…" -#: postmaster/postmaster.c:2471 +#: postmaster/postmaster.c:2629 #, c-format msgid "received SIGHUP, reloading configuration files" msgstr "接收到 SIGHUP, é‡è½½é…置文件" -#: postmaster/postmaster.c:2496 -#, c-format -msgid "pg_hba.conf not reloaded" +#. translator: %s is a configuration file +#: postmaster/postmaster.c:2655 postmaster/postmaster.c:2659 +#, fuzzy, c-format +#| msgid "pg_hba.conf was not reloaded" +msgid "%s was not reloaded" msgstr "æ²¡æœ‰é‡æ–°åŠ è½½pg_hba.conf" -#: postmaster/postmaster.c:2500 +#: postmaster/postmaster.c:2669 #, c-format -msgid "pg_ident.conf not reloaded" -msgstr "pg_ident.conf æ²¡æœ‰é‡æ–°åŠ è½½" +msgid "SSL configuration was not reloaded" +msgstr "SSLé…ç½®æ²¡æœ‰é‡æ–°åŠ è½½" -#: postmaster/postmaster.c:2541 +#: postmaster/postmaster.c:2717 #, c-format msgid "received smart shutdown request" msgstr "接到到智能 (smart) åœæ­¢è¯·æ±‚" -#: postmaster/postmaster.c:2596 +#: postmaster/postmaster.c:2775 #, c-format msgid "received fast shutdown request" msgstr "接收到快速 (fast) åœæ­¢è¯·æ±‚" -#: postmaster/postmaster.c:2625 +#: postmaster/postmaster.c:2808 #, c-format msgid "aborting any active transactions" msgstr "中断任何激活事务" -#: postmaster/postmaster.c:2659 +#: postmaster/postmaster.c:2842 #, c-format msgid "received immediate shutdown request" msgstr "æŽ¥æ”¶åˆ°ç«‹å³ (immediate) åœæ­¢è¯·æ±‚" -#: postmaster/postmaster.c:2723 +#: postmaster/postmaster.c:2909 #, c-format msgid "shutdown at recovery target" msgstr "在æ¢å¤ç›®æ ‡å¤„关闭" -#: postmaster/postmaster.c:2739 postmaster/postmaster.c:2762 +#: postmaster/postmaster.c:2925 postmaster/postmaster.c:2948 msgid "startup process" msgstr "å¯åŠ¨è¿›ç¨‹" -#: postmaster/postmaster.c:2742 +#: postmaster/postmaster.c:2928 #, c-format msgid "aborting startup due to startup process failure" msgstr "由于å¯åŠ¨è¿›ç¨‹å¤±è´¥, 终止å¯åЍ" -#: postmaster/postmaster.c:2803 +#: postmaster/postmaster.c:2989 #, c-format msgid "database system is ready to accept connections" msgstr "æ•°æ®åº“系统准备接å—连接" -#: postmaster/postmaster.c:2822 +#: postmaster/postmaster.c:3010 msgid "background writer process" msgstr "åŽå°å†™å…¥è¿›ç¨‹" -#: postmaster/postmaster.c:2876 +#: postmaster/postmaster.c:3064 msgid "checkpointer process" msgstr "检查点(checkpointer)进程" -#: postmaster/postmaster.c:2892 +#: postmaster/postmaster.c:3080 msgid "WAL writer process" msgstr "WAL写入进程" -#: postmaster/postmaster.c:2906 +#: postmaster/postmaster.c:3095 msgid "WAL receiver process" msgstr "WAL接收进程" -#: postmaster/postmaster.c:2921 +#: postmaster/postmaster.c:3110 msgid "autovacuum launcher process" msgstr "autovacuumå¯åŠ¨è¿›ç¨‹" -#: postmaster/postmaster.c:2936 +#: postmaster/postmaster.c:3125 msgid "archiver process" msgstr "归档进程" -#: postmaster/postmaster.c:2952 +#: postmaster/postmaster.c:3141 msgid "statistics collector process" msgstr "统计收集器进程" -#: postmaster/postmaster.c:2966 +#: postmaster/postmaster.c:3155 msgid "system logger process" msgstr "系统日志进程" -#: postmaster/postmaster.c:3028 -msgid "worker process" -msgstr "工作进程" +#: postmaster/postmaster.c:3217 +#, c-format +msgid "background worker \"%s\"" +msgstr "åŽå°å·¥ä½œè¿›ç¨‹ \"%s\"" -#: postmaster/postmaster.c:3111 postmaster/postmaster.c:3131 -#: postmaster/postmaster.c:3138 postmaster/postmaster.c:3156 +#: postmaster/postmaster.c:3301 postmaster/postmaster.c:3321 +#: postmaster/postmaster.c:3328 postmaster/postmaster.c:3346 msgid "server process" msgstr "æœåŠ¡å™¨è¿›ç¨‹" -#: postmaster/postmaster.c:3210 +#: postmaster/postmaster.c:3400 #, c-format msgid "terminating any other active server processes" msgstr "中断任何其它已激活的æœåŠ¡å™¨è¿›ç¨‹" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3466 +#: postmaster/postmaster.c:3656 #, c-format msgid "%s (PID %d) exited with exit code %d" msgstr "%s (PID %d) 已退出, é€€å‡ºä»£ç  %d" -#: postmaster/postmaster.c:3468 postmaster/postmaster.c:3479 -#: postmaster/postmaster.c:3490 postmaster/postmaster.c:3499 -#: postmaster/postmaster.c:3509 +#: postmaster/postmaster.c:3658 postmaster/postmaster.c:3670 +#: postmaster/postmaster.c:3680 postmaster/postmaster.c:3691 #, c-format msgid "Failed process was running: %s" msgstr "失败进程:%s正在è¿è¡Œ" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3476 +#: postmaster/postmaster.c:3667 #, c-format msgid "%s (PID %d) was terminated by exception 0x%X" msgstr "%s (PID %d) 被异常 0x%X 终止" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3486 +#: postmaster/postmaster.c:3677 #, c-format msgid "%s (PID %d) was terminated by signal %d: %s" msgstr "%s (PID %d) è¢«ä¿¡å· %d 中断: %s" #. translator: %s is a noun phrase describing a child process, such as #. "server process" -#: postmaster/postmaster.c:3497 -#, c-format -msgid "%s (PID %d) was terminated by signal %d" -msgstr "%s (PID %d) è¢«ä¿¡å· %d 中断" - -#. translator: %s is a noun phrase describing a child process, such as -#. "server process" -#: postmaster/postmaster.c:3507 +#: postmaster/postmaster.c:3689 #, c-format msgid "%s (PID %d) exited with unrecognized status %d" msgstr "%s (PID %d) 已退出, æ„å¤–çŠ¶æ€ %d" -#: postmaster/postmaster.c:3694 +#: postmaster/postmaster.c:3872 #, c-format msgid "abnormal database system shutdown" msgstr "æ•°æ®åº“系统异常关闭" -#: postmaster/postmaster.c:3734 +#: postmaster/postmaster.c:3912 #, c-format msgid "all server processes terminated; reinitializing" msgstr "所有的æœåŠ¡å™¨è¿›ç¨‹è¢«ä¸­æ­¢; 釿–°åˆå§‹åŒ–" -#: postmaster/postmaster.c:3946 +#: postmaster/postmaster.c:4082 postmaster/postmaster.c:5473 +#: postmaster/postmaster.c:5847 +#, c-format +msgid "could not generate random cancel key" +msgstr "无法生æˆéšæœºå–æ¶ˆå¯†é’¥" + +#: postmaster/postmaster.c:4136 #, c-format msgid "could not fork new process for connection: %m" msgstr "æ— æ³•ä¸ºè”æŽ¥æ´¾ç”Ÿæ–°è¿›ç¨‹: %m" -#: postmaster/postmaster.c:3988 +#: postmaster/postmaster.c:4178 msgid "could not fork new process for connection: " msgstr "æ— æ³•ä¸ºè”æŽ¥æ´¾ç”Ÿæ–°è¿›ç¨‹: " -#: postmaster/postmaster.c:4102 +#: postmaster/postmaster.c:4288 #, c-format msgid "connection received: host=%s port=%s" msgstr "已接收到连接: 主机=%s 端å£=%s" -#: postmaster/postmaster.c:4107 +#: postmaster/postmaster.c:4293 #, c-format msgid "connection received: host=%s" msgstr "已接收到连接: 主机=%s" -#: postmaster/postmaster.c:4390 +#: postmaster/postmaster.c:4563 #, c-format msgid "could not execute server process \"%s\": %m" msgstr "无法执行æœåŠ¡å™¨è¿›ç¨‹ \"%s\": %m" -#: postmaster/postmaster.c:4955 +#: postmaster/postmaster.c:4716 +#, c-format +msgid "giving up after too many tries to reserve shared memory" +msgstr "过多å°è¯•ä¿ç•™å…±äº«å†…å­˜åŽæ”¾å¼ƒ" + +#: postmaster/postmaster.c:4717 +#, c-format +msgid "This might be caused by ASLR or antivirus software." +msgstr "è¿™å¯èƒ½æ˜¯ç”±ASLR或防病毒软件引起的." + +#: postmaster/postmaster.c:4928 +#, c-format +msgid "SSL configuration could not be loaded in child process" +msgstr "无法在å­è¿›ç¨‹ä¸­åŠ è½½SSLé…ç½®" + +#: postmaster/postmaster.c:5060 +#, fuzzy, c-format +#| msgid "Please report this to ." +msgid "Please report this to ." +msgstr "è¯·å‘ å‘é€æŠ¥å‘Š." + +#: postmaster/postmaster.c:5147 #, c-format msgid "database system is ready to accept read only connections" msgstr "æ•°æ®åº“系统准备接å—åªè¯»è¯·æ±‚的连接" -#: postmaster/postmaster.c:5242 +#: postmaster/postmaster.c:5401 #, c-format msgid "could not fork startup process: %m" msgstr "无法派生å¯åŠ¨è¿›ç¨‹: %m" -#: postmaster/postmaster.c:5246 +#: postmaster/postmaster.c:5405 #, c-format msgid "could not fork background writer process: %m" msgstr "无法 fork åŽå°å†™å…¥è¿›ç¨‹: %m" -#: postmaster/postmaster.c:5250 +#: postmaster/postmaster.c:5409 #, c-format msgid "could not fork checkpointer process: %m" msgstr "无法派生检查点进程: %m" -#: postmaster/postmaster.c:5254 +#: postmaster/postmaster.c:5413 #, c-format msgid "could not fork WAL writer process: %m" msgstr "无法派生WAL写入进程: %m" -#: postmaster/postmaster.c:5258 +#: postmaster/postmaster.c:5417 #, c-format msgid "could not fork WAL receiver process: %m" msgstr "无法派生WAL接收进程: %m" -#: postmaster/postmaster.c:5262 +#: postmaster/postmaster.c:5421 #, c-format msgid "could not fork process: %m" msgstr "无法派生进程: %m" -#: postmaster/postmaster.c:5424 postmaster/postmaster.c:5447 +#: postmaster/postmaster.c:5618 postmaster/postmaster.c:5641 #, c-format msgid "database connection requirement not indicated during registration" msgstr "在注册阶段没有指定需è¦çš„æ•°æ®åº“连接" -#: postmaster/postmaster.c:5431 postmaster/postmaster.c:5454 +#: postmaster/postmaster.c:5625 postmaster/postmaster.c:5648 #, c-format msgid "invalid processing mode in background worker" msgstr "åŽå°å·¥ä½œè¿›ç¨‹ä¸­çš„æ— æ•ˆå¤„ç†æ¨¡å¼" -#: postmaster/postmaster.c:5506 +#: postmaster/postmaster.c:5720 #, c-format msgid "starting background worker process \"%s\"" msgstr "å¯åЍåŽå°å·¥ä½œè¿›ç¨‹\"%s\"" -#: postmaster/postmaster.c:5517 +#: postmaster/postmaster.c:5732 #, c-format msgid "could not fork worker process: %m" msgstr "无法创建工作进程:%m" -#: postmaster/postmaster.c:5895 +#: postmaster/postmaster.c:6168 #, c-format msgid "could not duplicate socket %d for use in backend: error code %d" msgstr "无法为åŽç«¯ä½¿ç”¨å¤åˆ¶å¥—接字 %d: 错误ç ä¸º %d" -#: postmaster/postmaster.c:5927 +#: postmaster/postmaster.c:6200 #, c-format msgid "could not create inherited socket: error code %d\n" msgstr "无法创建继承套接字: 错误ç ä¸º %d\n" -#: postmaster/postmaster.c:5956 +#: postmaster/postmaster.c:6229 #, c-format msgid "could not open backend variables file \"%s\": %s\n" msgstr "无法打开åŽç«¯å˜é‡æ–‡ä»¶\"%s\":%s\n" -#: postmaster/postmaster.c:5963 +#: postmaster/postmaster.c:6236 #, c-format msgid "could not read from backend variables file \"%s\": %s\n" msgstr "无法从åŽç«¯å¯å˜ (variables) 文件 \"%s\" 读å–: %s\n" -#: postmaster/postmaster.c:5972 +#: postmaster/postmaster.c:6245 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "无法删除文件 \"%s\": %s\n" -#: postmaster/postmaster.c:5989 +#: postmaster/postmaster.c:6262 #, c-format msgid "could not map view of backend variables: error code %lu\n" msgstr "无法映射åŽç«¯å˜é‡è§†å›¾: 错误ç ä¸º %lu\n" -#: postmaster/postmaster.c:5998 +#: postmaster/postmaster.c:6271 #, c-format msgid "could not unmap view of backend variables: error code %lu\n" msgstr "æ— æ³•å–æ¶ˆåŽç«¯å˜é‡è§†å›¾çš„æ˜ å°„: 错误ç ä¸º %lu\n" -#: postmaster/postmaster.c:6005 +#: postmaster/postmaster.c:6278 #, c-format msgid "could not close handle to backend parameter variables: error code %lu\n" msgstr "无法关闭åŽç«¯å‚æ•°å˜é‡çš„奿Ÿ„: 错误ç ä¸º %lu\n" -#: postmaster/postmaster.c:6166 +#: postmaster/postmaster.c:6442 #, c-format msgid "could not read exit code for process\n" msgstr "无法为进程读å–退出代ç \n" -#: postmaster/postmaster.c:6171 +#: postmaster/postmaster.c:6447 #, c-format msgid "could not post child completion status\n" msgstr "无法传递å­é˜Ÿåˆ—的结æŸçжæ€\n" -#: postmaster/syslogger.c:441 postmaster/syslogger.c:1041 +#: postmaster/syslogger.c:480 postmaster/syslogger.c:1154 #, c-format msgid "could not read from logger pipe: %m" msgstr "无法从日志管é“读å–: %m" -#: postmaster/syslogger.c:490 +#: postmaster/syslogger.c:528 #, c-format msgid "logger shutting down" msgstr "日志正在关闭" -#: postmaster/syslogger.c:534 postmaster/syslogger.c:548 +#: postmaster/syslogger.c:572 postmaster/syslogger.c:586 #, c-format msgid "could not create pipe for syslog: %m" msgstr "无法为统计日志 (syslog) 创建管é“: %m" -#: postmaster/syslogger.c:584 +#: postmaster/syslogger.c:637 #, c-format msgid "could not fork system logger: %m" msgstr "无法派生 (fork) 系统日志: %m" -#: postmaster/syslogger.c:620 +#: postmaster/syslogger.c:673 #, c-format msgid "redirecting log output to logging collector process" msgstr "日志输出é‡å®šå‘到日志收集进程" -#: postmaster/syslogger.c:621 +#: postmaster/syslogger.c:674 #, c-format msgid "Future log output will appear in directory \"%s\"." msgstr "åŽç»­çš„æ—¥å¿—输出将出现在目录 \"%s\"中." -#: postmaster/syslogger.c:629 +#: postmaster/syslogger.c:682 #, c-format msgid "could not redirect stdout: %m" msgstr "无法é‡å®šå‘到标准输出 (stdout) : %m" -#: postmaster/syslogger.c:634 postmaster/syslogger.c:651 +#: postmaster/syslogger.c:687 postmaster/syslogger.c:704 #, c-format msgid "could not redirect stderr: %m" msgstr "无法é‡å®šå‘到标准错误 (stderr) : %m" -#: postmaster/syslogger.c:996 +#: postmaster/syslogger.c:1109 #, c-format msgid "could not write to log file: %s\n" msgstr "无法写入日志文件: %s\n" -#: postmaster/syslogger.c:1136 +#: postmaster/syslogger.c:1226 #, c-format msgid "could not open log file \"%s\": %m" msgstr "无法打开事务日志文件 \"%s\": %m" -#: postmaster/syslogger.c:1198 postmaster/syslogger.c:1242 +#: postmaster/syslogger.c:1288 postmaster/syslogger.c:1338 #, c-format msgid "disabling automatic rotation (use SIGHUP to re-enable)" msgstr "å–æ¶ˆè‡ªåŠ¨è½®å¯» (使用 SIGHUP re-enable)" -#: regex/regc_pg_locale.c:261 +#: regex/regc_pg_locale.c:262 #, c-format msgid "could not determine which collation to use for regular expression" msgstr "无法确定正规表达å¼ä¸­ä½¿ç”¨ä½•ç§æŽ’åºè§„则" -#: repl_gram.y:260 repl_gram.y:292 -#, c-format -msgid "invalid timeline %u" -msgstr "无效时间线%u" - -#: repl_scanner.l:120 -msgid "invalid streaming start location" -msgstr "无效的æµèµ·å§‹ä½ç½®" - -#: repl_scanner.l:171 scan.l:671 -msgid "unterminated quoted string" -msgstr "未结æŸçš„引用字符串" - -#: repl_scanner.l:181 -#, c-format -msgid "syntax error: unexpected character \"%s\"" -msgstr "语法错误: é‡åˆ°æ„外字符\"%s\"" - -#: replication/basebackup.c:230 -#, c-format -msgid "could not stat control file \"%s\": %m" -msgstr "无法统计控制文件 \"%s\": %m" +#: regex/regc_pg_locale.c:269 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for regular expression" +msgid "nondeterministic collations are not supported for regular expressions" +msgstr "无法确定正规表达å¼ä¸­ä½¿ç”¨ä½•ç§æŽ’åºè§„则" -#: replication/basebackup.c:339 +#: replication/basebackup.c:450 #, c-format msgid "could not find any WAL files" msgstr "无法找到任何WAL文件" -#: replication/basebackup.c:352 replication/basebackup.c:366 -#: replication/basebackup.c:375 +#: replication/basebackup.c:464 replication/basebackup.c:479 +#: replication/basebackup.c:488 #, c-format msgid "could not find WAL file \"%s\"" msgstr "找ä¸åˆ°WAL文件\"%s\"" -#: replication/basebackup.c:414 replication/basebackup.c:440 +#: replication/basebackup.c:530 replication/basebackup.c:558 #, c-format msgid "unexpected WAL file size \"%s\"" msgstr "æ„外的WAL文件大å°\"%s\"" -#: replication/basebackup.c:426 replication/basebackup.c:1172 +#: replication/basebackup.c:544 replication/basebackup.c:1539 #, c-format msgid "base backup could not send data, aborting backup" msgstr "基础备份无法å‘逿•°æ®ï¼Œç»ˆæ­¢å¤‡ä»½" -#: replication/basebackup.c:528 replication/basebackup.c:537 -#: replication/basebackup.c:546 replication/basebackup.c:555 -#: replication/basebackup.c:564 replication/basebackup.c:575 -#: replication/basebackup.c:592 +#: replication/basebackup.c:616 +#, c-format +msgid "%s total checksum verification failures" +msgstr "%s 校验和验è¯å¤±è´¥æ€»æ•°" + +#: replication/basebackup.c:620 +#, c-format +msgid "checksum verification failure during base backup" +msgstr "基础备份期间的校验和验è¯å¤±è´¥" + +#: replication/basebackup.c:664 replication/basebackup.c:673 +#: replication/basebackup.c:682 replication/basebackup.c:691 +#: replication/basebackup.c:700 replication/basebackup.c:711 +#: replication/basebackup.c:728 replication/basebackup.c:737 #, c-format msgid "duplicate option \"%s\"" msgstr "é‡å¤é€‰é¡¹ \"%s\"" -#: replication/basebackup.c:581 utils/misc/guc.c:5667 +#: replication/basebackup.c:717 #, c-format msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" msgstr "%d è¶…å‡ºäº†å‚æ•° \"%s\" (%d .. %d) 的有效范围" -#: replication/basebackup.c:855 replication/basebackup.c:957 +#: replication/basebackup.c:991 replication/basebackup.c:1161 #, c-format msgid "could not stat file or directory \"%s\": %m" msgstr "无法统计文件或目录\"%s\": %m" -#: replication/basebackup.c:1124 +#: replication/basebackup.c:1316 #, c-format msgid "skipping special file \"%s\"" msgstr "跳过特殊文件 \"%s\"" -#: replication/basebackup.c:1235 +#: replication/basebackup.c:1424 +#, c-format +msgid "invalid segment number %d in file \"%s\"" +msgstr "文件\"%2$s\"中的段å·%1$d无效" + +#: replication/basebackup.c:1443 +#, c-format +msgid "cannot verify checksum in file \"%s\", block %d: read buffer size %d and page size %d differ" +msgstr "æ— æ³•éªŒè¯æ–‡ä»¶\"%s\"ã€å—%d中的校验和:读å–缓冲区大å°%d和页大å°%dä¸åŒ" + +#: replication/basebackup.c:1487 replication/basebackup.c:1503 +#, c-format +msgid "could not fseek in file \"%s\": %m" +msgstr "无法在文件\"%s\"进行查找: %m" + +#: replication/basebackup.c:1495 +#, c-format +msgid "could not reread block %d of file \"%s\": %m" +msgstr "无法在文件\"%2$s\"䏭釿–°è¯»å–å—%1$d: %3$m" + +#: replication/basebackup.c:1519 +#, c-format +msgid "checksum verification failed in file \"%s\", block %d: calculated %X but expected %X" +msgstr "校验和验è¯åœ¨æ–‡ä»¶\"%s\"中失败,å—%d :计算的为%X,但应为%X" + +#: replication/basebackup.c:1526 +#, c-format +msgid "further checksum verification failures in file \"%s\" will not be reported" +msgstr "å°†ä¸ä¼šæŠ¥å‘Šæ–‡ä»¶ \"%s\"中的进一步校验和验è¯å¤±è´¥ã€‚" + +#: replication/basebackup.c:1584 +#, c-format +msgid "file \"%s\" has a total of %d checksum verification failures" +msgstr "文件\"%s\"总共有%d个校验和验è¯å¤±è´¥" + +#: replication/basebackup.c:1615 #, c-format msgid "file name too long for tar format: \"%s\"" msgstr "文件å对于taræ ¼å¼è¶…长:\"%s\"" -#: replication/basebackup.c:1240 +#: replication/basebackup.c:1620 #, c-format -msgid "" -"symbolic link target too long for tar format: file name \"%s\", target \"%s\"" +msgid "symbolic link target too long for tar format: file name \"%s\", target \"%s\"" msgstr "符å·é“¾æŽ¥ç›®æ ‡å¯¹äºŽtaræ ¼å¼è¿‡é•¿ï¼šæ–‡ä»¶å是\"%s\",目标是\"%s\"" -#: replication/libpqwalreceiver/libpqwalreceiver.c:116 +#: replication/libpqwalreceiver/libpqwalreceiver.c:232 #, c-format -msgid "could not connect to the primary server: %s" -msgstr "无法连接到主用æœåŠ¡å™¨ï¼š%s" +msgid "invalid connection string syntax: %s" +msgstr "无效的连接字符串语法: %s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:140 +#: replication/libpqwalreceiver/libpqwalreceiver.c:256 #, c-format -msgid "" -"could not receive database system identifier and timeline ID from the " -"primary server: %s" +msgid "could not parse connection string: %s" +msgstr "无法分æžè¿žæŽ¥å­—符串: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:328 +#, c-format +msgid "could not receive database system identifier and timeline ID from the primary server: %s" msgstr "无法从主用æœåŠ¡å™¨æŽ¥æ”¶æ•°æ®åº“系统标识符和时间线ID:%s" -#: replication/libpqwalreceiver/libpqwalreceiver.c:151 -#: replication/libpqwalreceiver/libpqwalreceiver.c:305 +#: replication/libpqwalreceiver/libpqwalreceiver.c:339 +#: replication/libpqwalreceiver/libpqwalreceiver.c:557 #, c-format msgid "invalid response from primary server" msgstr "æ¥è‡ªä¸»ç”¨æœåŠ¡å™¨çš„å›žåº”æ— æ•ˆ" -#: replication/libpqwalreceiver/libpqwalreceiver.c:152 +#: replication/libpqwalreceiver/libpqwalreceiver.c:340 #, c-format -msgid "" -"Could not identify system: got %d rows and %d fields, expected %d rows and " -"%d or more fields." +msgid "Could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields." msgstr "无法识别系统: 得到 %d 行和 %d 列, 期望值为: %d 行和 %d 列." -#: replication/libpqwalreceiver/libpqwalreceiver.c:168 -#, c-format -msgid "database system identifier differs between the primary and standby" -msgstr "在主用æœåŠ¡å™¨å’Œå¤‡ç”¨æœåŠ¡å™¨ä¹‹é—´ï¼Œæ•°æ®åº“系统标识符是ä¸ä¸€æ ·çš„。" - -#: replication/libpqwalreceiver/libpqwalreceiver.c:169 -#, c-format -msgid "The primary's identifier is %s, the standby's identifier is %s." -msgstr "主用æœåŠ¡å™¨çš„æ ‡è¯†ç¬¦æ˜¯%s,备用æœåŠ¡å™¨çš„æ ‡è¯†ç¬¦æ˜¯%s。" - -#: replication/libpqwalreceiver/libpqwalreceiver.c:211 +#: replication/libpqwalreceiver/libpqwalreceiver.c:413 +#: replication/libpqwalreceiver/libpqwalreceiver.c:419 +#: replication/libpqwalreceiver/libpqwalreceiver.c:444 #, c-format msgid "could not start WAL streaming: %s" msgstr "无法å¯åЍWALæµå¤åˆ¶: %s" # fe-misc.c:702 -#: replication/libpqwalreceiver/libpqwalreceiver.c:229 +#: replication/libpqwalreceiver/libpqwalreceiver.c:467 #, c-format msgid "could not send end-of-streaming message to primary: %s" msgstr "无法å‘主æœåС噍:%så‘逿µç»ˆæ­¢çš„æ¶ˆæ¯" # fe-exec.c:1371 -#: replication/libpqwalreceiver/libpqwalreceiver.c:251 +#: replication/libpqwalreceiver/libpqwalreceiver.c:489 #, c-format msgid "unexpected result set after end-of-streaming" msgstr "æµç»“æŸæ—¶å‡ºçްæ„外的结果集" -#: replication/libpqwalreceiver/libpqwalreceiver.c:263 +#: replication/libpqwalreceiver/libpqwalreceiver.c:503 +#, c-format +msgid "error while shutting down streaming COPY: %s" +msgstr "关闭æµå¼å¤åˆ¶æ—¶å‡ºé”™: %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:512 #, c-format msgid "error reading result of streaming command: %s" msgstr "读æµå‘½ä»¤çš„结果时出错: %s" # fe-exec.c:1371 -#: replication/libpqwalreceiver/libpqwalreceiver.c:271 +#: replication/libpqwalreceiver/libpqwalreceiver.c:520 +#: replication/libpqwalreceiver/libpqwalreceiver.c:754 #, c-format msgid "unexpected result after CommandComplete: %s" msgstr "CommandComplete %s结æŸåŽå‡ºçްæ„外结果" -#: replication/libpqwalreceiver/libpqwalreceiver.c:294 +#: replication/libpqwalreceiver/libpqwalreceiver.c:546 #, c-format msgid "could not receive timeline history file from the primary server: %s" msgstr "无法从主æœåС噍:%sæŽ¥æ”¶åŽ†å²æ—¶é—´çº¿" -#: replication/libpqwalreceiver/libpqwalreceiver.c:306 +#: replication/libpqwalreceiver/libpqwalreceiver.c:558 #, c-format msgid "Expected 1 tuple with 2 fields, got %d tuples with %d fields." -msgstr "" -"期望得到带有两个字段的一æ¡è®°å½•,但是现在得到了%dæ¡è®°å½•ï¼Œæ¯æ¡å¸¦æœ‰%d个字段." - -#: replication/libpqwalreceiver/libpqwalreceiver.c:334 -#, c-format -#| msgid "invalid mask length: %d" -msgid "invalid socket: %s" -msgstr "无效的套接字:%s" - -#: replication/libpqwalreceiver/libpqwalreceiver.c:374 -#: storage/ipc/latch.c:1271 -#, c-format -msgid "select() failed: %m" -msgstr "执行select()失败: %m" +msgstr "期望得到带有两个字段的一æ¡è®°å½•,但是现在得到了%dæ¡è®°å½•ï¼Œæ¯æ¡å¸¦æœ‰%d个字段." -#: replication/libpqwalreceiver/libpqwalreceiver.c:497 -#: replication/libpqwalreceiver/libpqwalreceiver.c:524 -#: replication/libpqwalreceiver/libpqwalreceiver.c:530 +#: replication/libpqwalreceiver/libpqwalreceiver.c:718 +#: replication/libpqwalreceiver/libpqwalreceiver.c:769 +#: replication/libpqwalreceiver/libpqwalreceiver.c:775 #, c-format msgid "could not receive data from WAL stream: %s" msgstr "无法从WALæµä¸­èŽ·å¾—æ•°æ®: %s" # fe-misc.c:702 -#: replication/libpqwalreceiver/libpqwalreceiver.c:549 +#: replication/libpqwalreceiver/libpqwalreceiver.c:794 #, c-format msgid "could not send data to WAL stream: %s" msgstr "无法å‘WALæµ:%så‘逿•°æ®" -#: replication/logical/logical.c:83 +#: replication/libpqwalreceiver/libpqwalreceiver.c:843 #, c-format -msgid "logical decoding requires wal_level >= logical" +msgid "could not create replication slot \"%s\": %s" +msgstr "无法创建å¤åˆ¶æ§½\"%s\": %s" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:877 +#, c-format +msgid "invalid query response" +msgstr "无效的查询å“应" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:878 +#, c-format +msgid "Expected %d fields, got %d fields." +msgstr "应输入%d个字段,得到%d个字段." + +#: replication/libpqwalreceiver/libpqwalreceiver.c:947 +#, c-format +msgid "the query interface requires a database connection" +msgstr "查询接å£éœ€è¦æ•°æ®åº“连接" + +#: replication/libpqwalreceiver/libpqwalreceiver.c:978 +msgid "empty query" +msgstr "空查询" + +#: replication/logical/launcher.c:307 +#, c-format +msgid "starting logical replication worker for subscription \"%s\"" +msgstr "正在为订阅\"%s\"å¯åŠ¨é€»è¾‘å¤åˆ¶å·¥ä½œçº¿ç¨‹" + +#: replication/logical/launcher.c:314 +#, c-format +msgid "cannot start logical replication workers when max_replication_slots = 0" +msgstr "当max_replication_slots = 0时,无法å¯åŠ¨é€»è¾‘å¤åˆ¶å·¥ä½œè¿›ç¨‹" + +#: replication/logical/launcher.c:394 +#, c-format +msgid "out of logical replication worker slots" +msgstr "逻辑å¤åˆ¶å·¥ä½œæ§½ä¸è¶³" + +#: replication/logical/launcher.c:395 +#, c-format +msgid "You might need to increase max_logical_replication_workers." +msgstr "您å¯èƒ½éœ€è¦å¢žåР傿•°max_logical_replication_workers." + +#: replication/logical/launcher.c:450 +#, c-format +msgid "out of background worker slots" +msgstr "超出åŽå°å·¥ä½œçº¿ç¨‹æ§½" + +#: replication/logical/launcher.c:451 +#, c-format +msgid "You might need to increase max_worker_processes." +msgstr "您å¯èƒ½éœ€è¦å¢žåР傿•°max_worker_processes." + +#: replication/logical/launcher.c:650 +#, c-format +msgid "logical replication worker slot %d is empty, cannot attach" +msgstr "逻辑å¤åˆ¶å·¥ä½œæ§½%d为空,无法附加" + +#: replication/logical/launcher.c:659 +#, c-format +msgid "logical replication worker slot %d is already used by another worker, cannot attach" +msgstr "逻辑å¤åˆ¶å·¥ä½œæ§½%d已被å¦ä¸€ä¸ªå·¥ä½œè¿›ç¨‹ä½¿ç”¨ï¼Œæ— æ³•附加" + +#: replication/logical/launcher.c:977 +#, c-format +msgid "logical replication launcher started" +msgstr "逻辑å¤åˆ¶å¯åŠ¨ç¨‹åºå·²å¯åЍ" + +#: replication/logical/logical.c:90 +#, c-format +msgid "logical decoding requires wal_level >= logical" msgstr "逻辑解ç è¦æ±‚wal_level >= logical" -#: replication/logical/logical.c:88 +#: replication/logical/logical.c:95 #, c-format msgid "logical decoding requires a database connection" msgstr "逻辑解ç éœ€è¦ä¸€ä¸ªæ•°æ®åº“连接" -#: replication/logical/logical.c:106 +#: replication/logical/logical.c:113 #, c-format msgid "logical decoding cannot be used while in recovery" msgstr "逻辑解ç ä¸èƒ½ç”¨äºŽæ¢å¤æ“作" -#: replication/logical/logical.c:238 replication/logical/logical.c:342 +#: replication/logical/logical.c:258 replication/logical/logical.c:396 #, c-format msgid "cannot use physical replication slot for logical decoding" msgstr "逻辑解ç ä¸èƒ½ä½¿ç”¨ç‰©ç†å¤åˆ¶æ§½" -#: replication/logical/logical.c:243 replication/logical/logical.c:347 +#: replication/logical/logical.c:263 replication/logical/logical.c:401 #, c-format msgid "replication slot \"%s\" was not created in this database" msgstr "å¤åˆ¶æ§½\"%s\"ä¸èƒ½ç”¨äºŽæ­¤æ•°æ®åº“" -#: replication/logical/logical.c:250 +#: replication/logical/logical.c:270 #, c-format -msgid "" -"cannot create logical replication slot in transaction that has performed " -"writes" +msgid "cannot create logical replication slot in transaction that has performed writes" msgstr "å·²ç»æ‰§è¡Œäº†å†™æ“作的事务里,ä¸èƒ½åˆ›å»ºé€»è¾‘å¤åˆ¶æ§½" -#: replication/logical/logical.c:384 +#: replication/logical/logical.c:441 #, c-format msgid "starting logical decoding for slot \"%s\"" msgstr "开始为槽\"%s\"进行逻辑解ç " -#: replication/logical/logical.c:386 +#: replication/logical/logical.c:443 #, c-format -msgid "streaming transactions committing after %X/%X, reading WAL from %X/%X" -msgstr "æµäº‹åŠ¡åœ¨%X/%XåŽæäº¤ï¼Œä»Ž%X/%Xä½ç½®è¯»" +msgid "Streaming transactions committing after %X/%X, reading WAL from %X/%X." +msgstr "æµäº‹åŠ¡åœ¨%X/%XåŽæäº¤ï¼Œä»Ž%X/%Xä½ç½®è¯»." -#: replication/logical/logical.c:521 +#: replication/logical/logical.c:593 #, c-format -msgid "" -"slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" +msgid "slot \"%s\", output plugin \"%s\", in the %s callback, associated LSN %X/%X" msgstr "æ§½ \"%s\", 输出æ’ä»¶ \"%s\", 在 %s 回调, å…³è”çš„ LSN 地å€ä¸º%X/%X" -#: replication/logical/logical.c:528 +#: replication/logical/logical.c:600 #, c-format msgid "slot \"%s\", output plugin \"%s\", in the %s callback" msgstr "æ§½ \"%s\", 输出æ’ä»¶ \"%s\", 在 %s 回调" -#: replication/logical/logicalfuncs.c:113 replication/slotfuncs.c:32 +#: replication/logical/logicalfuncs.c:114 replication/slotfuncs.c:34 #, c-format msgid "must be superuser or replication role to use replication slots" msgstr "åªæœ‰è¶…级用户或者拥有å¤åˆ¶è§’色的用户æ‰èƒ½ä½¿ç”¨å¤åˆ¶æ§½" -#: replication/logical/logicalfuncs.c:152 +#: replication/logical/logicalfuncs.c:153 #, c-format -#| msgid "field name must not be null" msgid "slot name must not be null" msgstr "æ§½åç§°ä¸èƒ½ä¸ºç©º" -#: replication/logical/logicalfuncs.c:168 +#: replication/logical/logicalfuncs.c:169 #, c-format -#| msgid "typmod array must not contain nulls" msgid "options array must not be null" msgstr "选项数组ä¸èƒ½ä¸ºç©º" -#: replication/logical/logicalfuncs.c:199 +#: replication/logical/logicalfuncs.c:200 #, c-format msgid "array must be one-dimensional" msgstr "数组必须是一维的" -#: replication/logical/logicalfuncs.c:205 +#: replication/logical/logicalfuncs.c:206 #, c-format msgid "array must not contain nulls" msgstr "数组ä¸èƒ½åŒ…å«ç©ºå€¼" -#: replication/logical/logicalfuncs.c:221 utils/adt/json.c:2277 -#: utils/adt/jsonb.c:1356 +#: replication/logical/logicalfuncs.c:222 utils/adt/json.c:2312 +#: utils/adt/jsonb.c:1282 #, c-format msgid "array must have even number of elements" msgstr "数组必须包å«å¶æ•°ä¸ªå…ƒç´ " -#: replication/logical/logicalfuncs.c:261 +#: replication/logical/logicalfuncs.c:269 #, c-format -msgid "" -"logical decoding output plugin \"%s\" produces binary output, but function " -"\"%s\" expects textual data" +msgid "logical decoding output plugin \"%s\" produces binary output, but function \"%s\" expects textual data" msgstr "逻辑解ç è¾“出æ’ä»¶\"%s\"产生二进制输出,但是函数\"%s\"期待的是文本数æ®" -#: replication/logical/origin.c:181 +#: replication/logical/origin.c:185 #, c-format msgid "only superusers can query or manipulate replication origins" msgstr "åªæœ‰è¶…级用户能查询或者æ“纵å¤åˆ¶æºå¤´" -#: replication/logical/origin.c:186 +#: replication/logical/origin.c:190 #, c-format -msgid "" -"cannot query or manipulate replication origin when max_replication_slots = 0" +msgid "cannot query or manipulate replication origin when max_replication_slots = 0" msgstr "当max_replication_slots = 0时无法查询或者æ“纵å¤åˆ¶æºå¤´" -#: replication/logical/origin.c:191 +#: replication/logical/origin.c:195 #, c-format msgid "cannot manipulate replication origins during recovery" msgstr "无法在æ¢å¤æœŸé—´æ“作å¤åˆ¶æºå¤´" -#: replication/logical/origin.c:316 +#: replication/logical/origin.c:230 +#, c-format +msgid "replication origin \"%s\" does not exist" +msgstr "å¤åˆ¶æº\"%s\"ä¸å­˜åœ¨" + +#: replication/logical/origin.c:321 #, c-format msgid "could not find free replication origin OID" msgstr "无法找到空闲的å¤åˆ¶æºå¤´OID" -#: replication/logical/origin.c:353 +#: replication/logical/origin.c:369 #, c-format msgid "could not drop replication origin with OID %d, in use by PID %d" msgstr "无法删除具有OID %dçš„å¤åˆ¶æºå¤´ï¼ŒPID %d正在使用它" -#: replication/logical/origin.c:671 +#: replication/logical/origin.c:461 #, c-format -msgid "replication checkpoint has wrong magic %u instead of %u" -msgstr "å¤åˆ¶æ£€æŸ¥ç‚¹å…·æœ‰é”™è¯¯çš„magic值%uè€Œä¸æ˜¯%u" +msgid "replication origin with OID %u does not exist" +msgstr "OID为%uçš„å¤åˆ¶æºä¸å­˜åœ¨" -#: replication/logical/origin.c:703 +#: replication/logical/origin.c:729 #, c-format -msgid "could not read file \"%s\": read %d of %zu" -msgstr "æ— æ³•è¯»å–æ–‡ä»¶\"%1$s\":读å–了%3$zu中的%2$d" +msgid "replication checkpoint has wrong magic %u instead of %u" +msgstr "å¤åˆ¶æ£€æŸ¥ç‚¹å…·æœ‰é”™è¯¯çš„magic值%uè€Œä¸æ˜¯%u" -#: replication/logical/origin.c:712 +#: replication/logical/origin.c:770 #, c-format msgid "could not find free replication state, increase max_replication_slots" msgstr "无法找到空闲的å¤åˆ¶çжæ€ï¼Œè¯·å¢žåŠ max_replication_slots的值" -#: replication/logical/origin.c:730 +#: replication/logical/origin.c:788 #, c-format msgid "replication slot checkpoint has wrong checksum %u, expected %u" msgstr "å¤åˆ¶æ§½æ£€æŸ¥ç‚¹å…·æœ‰é”™è¯¯çš„æ ¡éªŒå’Œ%u,正确的应该是%u" -#: replication/logical/origin.c:854 +#: replication/logical/origin.c:916 #, c-format msgid "replication origin with OID %d is already active for PID %d" msgstr "OID为%dçš„å¤åˆ¶æºå¤´å·²ç»è¢«ç”¨äºŽPID %d" -#: replication/logical/origin.c:865 replication/logical/origin.c:1045 +#: replication/logical/origin.c:927 replication/logical/origin.c:1114 #, c-format -msgid "" -"could not find free replication state slot for replication origin with OID %u" +msgid "could not find free replication state slot for replication origin with OID %u" msgstr "无法为带有OID %uçš„å¤åˆ¶æºå¤´æ‰¾åˆ°ç©ºé—²çš„å¤åˆ¶çŠ¶æ€æ§½" -#: replication/logical/origin.c:867 replication/logical/origin.c:1047 -#: replication/slot.c:1288 +#: replication/logical/origin.c:929 replication/logical/origin.c:1116 +#: replication/slot.c:1564 #, c-format msgid "Increase max_replication_slots and try again." msgstr "增大 max_replication_slots的值å†é‡è¯•." -#: replication/logical/origin.c:1004 +#: replication/logical/origin.c:1073 #, c-format msgid "cannot setup replication origin when one is already setup" msgstr "在已ç»è®¾ç½®äº†ä¸€ä¸ªå¤åˆ¶æºå¤´çš„æƒ…况下无法å†è®¾ç½®å¤åˆ¶æºå¤´" -#: replication/logical/origin.c:1033 +#: replication/logical/origin.c:1102 #, c-format msgid "replication identifier %d is already active for PID %d" msgstr "å¤åˆ¶æ ‡è¯†ç¬¦%då·²ç»è¢«ç”¨äºŽPID %d" -#: replication/logical/origin.c:1079 replication/logical/origin.c:1274 -#: replication/logical/origin.c:1294 +#: replication/logical/origin.c:1153 replication/logical/origin.c:1351 +#: replication/logical/origin.c:1371 #, c-format msgid "no replication origin is configured" msgstr "没有é…ç½®å¤åˆ¶æºå¤´" -#: replication/logical/reorderbuffer.c:2309 +#: replication/logical/relation.c:255 +#, c-format +msgid "logical replication target relation \"%s.%s\" does not exist" +msgstr "逻辑å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\"ä¸å­˜åœ¨" + +#: replication/logical/relation.c:297 +#, c-format +msgid "logical replication target relation \"%s.%s\" is missing some replicated columns" +msgstr "逻辑å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\"缺少æŸäº›å·²å¤åˆ¶åˆ—" + +#: replication/logical/relation.c:337 +#, c-format +msgid "logical replication target relation \"%s.%s\" uses system columns in REPLICA IDENTITY index" +msgstr "逻辑å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\"使用REPLICA IDENTITY索引中的系统列" + +#: replication/logical/reorderbuffer.c:2507 #, c-format msgid "could not write to data file for XID %u: %m" msgstr "无法将XID %u:%må†™å…¥æ•°æ®æ–‡ä»¶" -#: replication/logical/reorderbuffer.c:2405 -#: replication/logical/reorderbuffer.c:2425 +#: replication/logical/reorderbuffer.c:2600 +#: replication/logical/reorderbuffer.c:2622 #, c-format msgid "could not read from reorderbuffer spill file: %m" msgstr "无法读å–é‡æŽ’ç¼“å†²çš„æº¢å‡ºæ–‡ä»¶:%m" -#: replication/logical/reorderbuffer.c:2409 -#: replication/logical/reorderbuffer.c:2429 +#: replication/logical/reorderbuffer.c:2604 +#: replication/logical/reorderbuffer.c:2626 #, c-format -msgid "" -"could not read from reorderbuffer spill file: read %d instead of %u bytes" +msgid "could not read from reorderbuffer spill file: read %d instead of %u bytes" msgstr "无法读å–é‡æŽ’ç¼“å†²çš„æº¢å‡ºæ–‡ä»¶, 读到了%då­—èŠ‚ï¼Œè€Œä¸æ˜¯%u字节" -#: replication/logical/reorderbuffer.c:3084 +#: replication/logical/reorderbuffer.c:2849 +#, fuzzy, c-format +#| msgid "could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m" +msgid "could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m" +msgstr "在删除pg_replslot/%2$s/*.xid期间无法删除文件\"%1$s\": %3$m" + +#: replication/logical/reorderbuffer.c:3315 #, c-format msgid "could not read from file \"%s\": read %d instead of %d bytes" msgstr "无法读文件\"%s\": 读到了%då­—èŠ‚ï¼Œè€Œä¸æ˜¯%d字节" -#: replication/logical/snapbuild.c:600 +#: replication/logical/snapbuild.c:611 +#, c-format +msgid "initial slot snapshot too large" +msgstr "åˆå§‹æ§½å¿«ç…§å¤ªå¤§" + +#: replication/logical/snapbuild.c:665 #, c-format msgid "exported logical decoding snapshot: \"%s\" with %u transaction ID" -msgid_plural "" -"exported logical decoding snapshot: \"%s\" with %u transaction IDs" +msgid_plural "exported logical decoding snapshot: \"%s\" with %u transaction IDs" msgstr[0] "导出逻辑解ç å¿«ç…§: \"%s\" 带有 %u 个事务 ID" -#: replication/logical/snapbuild.c:919 replication/logical/snapbuild.c:1284 -#: replication/logical/snapbuild.c:1815 +#: replication/logical/snapbuild.c:1270 replication/logical/snapbuild.c:1363 +#: replication/logical/snapbuild.c:1917 #, c-format msgid "logical decoding found consistent point at %X/%X" msgstr "在 %X/%X处,逻辑解ç å‘现一致点" -#: replication/logical/snapbuild.c:921 -#, c-format -msgid "Transaction ID %u finished; no more running transactions." -msgstr "事务ID %u已结æŸï¼›å·²æ²¡æœ‰æ­£è¿è¡Œçš„事务." - -#: replication/logical/snapbuild.c:1286 +#: replication/logical/snapbuild.c:1272 #, c-format msgid "There are no running transactions." msgstr "没有正è¿è¡Œçš„事务." -#: replication/logical/snapbuild.c:1348 +#: replication/logical/snapbuild.c:1314 #, c-format msgid "logical decoding found initial starting point at %X/%X" msgstr "逻辑解ç åœ¨ %X/%Xå‘现åˆå§‹åŒ–的起始点" -#: replication/logical/snapbuild.c:1350 +#: replication/logical/snapbuild.c:1316 replication/logical/snapbuild.c:1340 +#, c-format +msgid "Waiting for transactions (approximately %d) older than %u to end." +msgstr "等待超过%2$u的事务(大约%1$d)结æŸ." + +#: replication/logical/snapbuild.c:1338 #, c-format -msgid "%u transaction needs to finish." -msgid_plural "%u transactions need to finish." -msgstr[0] "有%u笔事务需è¦ç»“æŸ." +msgid "logical decoding found initial consistent point at %X/%X" +msgstr "在 %X/%X处,逻辑解ç å‘现åˆå§‹ä¸€è‡´ç‚¹" -#: replication/logical/snapbuild.c:1689 replication/logical/snapbuild.c:1715 -#: replication/logical/snapbuild.c:1729 replication/logical/snapbuild.c:1743 +#: replication/logical/snapbuild.c:1365 #, c-format -msgid "could not read file \"%s\", read %d of %d: %m" -msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%1$s\", 从%3$d:%4$m中读å–了%2$d" +msgid "There are no old transactions anymore." +msgstr "ä¸å†æœ‰æ—§çš„事务." -#: replication/logical/snapbuild.c:1695 +#: replication/logical/snapbuild.c:1759 #, c-format msgid "snapbuild state file \"%s\" has wrong magic number: %u instead of %u" msgstr "å¿«ç…§æž„å»ºçŠ¶æ€æ–‡ä»¶\"%s\"具有错误的magicå·ï¼š%uè€Œä¸æ˜¯%u" -#: replication/logical/snapbuild.c:1700 +#: replication/logical/snapbuild.c:1765 #, c-format msgid "snapbuild state file \"%s\" has unsupported version: %u instead of %u" msgstr "å¿«ç…§æž„å»ºçŠ¶æ€æ–‡ä»¶\"%s\"具有ä¸è¢«æ”¯æŒçš„版本:%uè€Œä¸æ˜¯%u" -#: replication/logical/snapbuild.c:1756 +#: replication/logical/snapbuild.c:1864 #, c-format msgid "checksum mismatch for snapbuild state file \"%s\": is %u, should be %u" msgstr "å¿«ç…§æž„å»ºçŠ¶æ€æ–‡ä»¶\"%s\"的校验和ä¸åŒ¹é…:现在的值是%u,正确值应该是%u" -#: replication/logical/snapbuild.c:1817 +#: replication/logical/snapbuild.c:1919 #, c-format msgid "Logical decoding will begin using saved snapshot." msgstr "逻辑解ç å°†ä»Žä½¿ç”¨å·²å­˜çš„快照开始." -#: replication/logical/snapbuild.c:1890 +#: replication/logical/snapbuild.c:1991 #, c-format msgid "could not parse file name \"%s\"" msgstr "æ— æ³•è§£æžæ–‡ä»¶å \"%s\"" -#: replication/slot.c:183 +#: replication/logical/tablesync.c:139 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has finished" +msgstr "订阅\"%s\"ã€è¡¨ \"%s\" 的逻辑å¤åˆ¶è¡¨åŒæ­¥å·¥ä½œçº¿ç¨‹å·²å®Œæˆ" + +#: replication/logical/tablesync.c:672 +#, c-format +msgid "could not fetch table info for table \"%s.%s\" from publisher: %s" +msgstr "无法从å‘布æœåŠ¡å™¨èŽ·å–表\"%s.%s\"的表信æ¯: %s" + +#: replication/logical/tablesync.c:678 +#, c-format +msgid "table \"%s.%s\" not found on publisher" +msgstr "在å‘布æœåŠ¡å™¨ä¸Šæ‰¾ä¸åˆ°è¡¨\"%s.%s\"" + +#: replication/logical/tablesync.c:710 +#, c-format +msgid "could not fetch table info for table \"%s.%s\": %s" +msgstr "无法获å–表\"%s.%s\"的表信æ¯: %s" + +#: replication/logical/tablesync.c:780 +#, c-format +msgid "could not start initial contents copy for table \"%s.%s\": %s" +msgstr "无法å¯åŠ¨è¡¨\"%s.%s\"çš„åˆå§‹å†…容å¤åˆ¶: %s" + +#: replication/logical/tablesync.c:894 +#, c-format +msgid "table copy could not start transaction on publisher" +msgstr "表å¤åˆ¶æ— æ³•在å‘布æœåŠ¡å™¨ä¸Šå¯åŠ¨äº‹åŠ¡" + +#: replication/logical/tablesync.c:916 +#, c-format +msgid "table copy could not finish transaction on publisher" +msgstr "表å¤åˆ¶æ— æ³•完æˆå‘布æœåŠ¡å™¨ä¸Šçš„äº‹åŠ¡" + +#: replication/logical/worker.c:290 +#, c-format +msgid "processing remote data for replication target relation \"%s.%s\" column \"%s\", remote type %s, local type %s" +msgstr "正在处ç†å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\" 列\"%s\",远程类型%s,本地类型%s的远程数æ®" + +#: replication/logical/worker.c:511 +#, c-format +msgid "ORIGIN message sent out of order" +msgstr "æºæ¶ˆæ¯å‘é€ä¸æ­£å¸¸" + +#: replication/logical/worker.c:645 +#, c-format +msgid "publisher did not send replica identity column expected by the logical replication target relation \"%s.%s\"" +msgstr "å‘布æœåŠ¡å™¨æ²¡æœ‰å‘é€é€»è¾‘å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\"所需的副本标识列" + +#: replication/logical/worker.c:652 +#, c-format +msgid "logical replication target relation \"%s.%s\" has neither REPLICA IDENTITY index nor PRIMARY KEY and published relation does not have REPLICA IDENTITY FULL" +msgstr "逻辑å¤åˆ¶ç›®æ ‡å…³ç³»\"%s.%s\"既没有REPLICA IDENTITY索引,也没有PRIMARY KEY,并且å‘布的关系没有REPLICA IDENTITY FULL" + +#: replication/logical/worker.c:993 +#, c-format +msgid "invalid logical replication message type \"%c\"" +msgstr "无效的逻辑å¤åˆ¶æ¶ˆæ¯ç±»åž‹ \"%c\"" + +#: replication/logical/worker.c:1134 +#, c-format +msgid "data stream from publisher has ended" +msgstr "æ¥è‡ªå‘布æœåŠ¡å™¨çš„æ•°æ®æµå·²ç»“æŸ" + +#: replication/logical/worker.c:1289 +#, c-format +msgid "terminating logical replication worker due to timeout" +msgstr "由于超时而终止逻辑å¤åˆ¶å·¥ä½œçº¿ç¨‹" + +#: replication/logical/worker.c:1437 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was removed" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†åœæ­¢ï¼Œå› ä¸ºè¯¥è®¢é˜…已被删除。" + +#: replication/logical/worker.c:1451 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will stop because the subscription was disabled" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†åœæ­¢ï¼Œå› ä¸ºè¯¥è®¢é˜…已被ç¦ç”¨" + +#: replication/logical/worker.c:1465 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the connection information was changed" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†é‡æ–°å¯åŠ¨ï¼Œå› ä¸ºè¿žæŽ¥ä¿¡æ¯å·²æ›´æ”¹" + +#: replication/logical/worker.c:1479 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription was renamed" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†é‡æ–°å¯åŠ¨ï¼Œå› ä¸ºè®¢é˜…å·²é‡å‘½å" + +#: replication/logical/worker.c:1496 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because the replication slot name was changed" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†é‡æ–°å¯åŠ¨ï¼Œå› ä¸ºå¤åˆ¶æ§½å称已更改" + +#: replication/logical/worker.c:1510 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will restart because subscription's publications were changed" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”ç”¨å·¥ä½œçº¿ç¨‹å°†é‡æ–°å¯åŠ¨ï¼Œå› ä¸ºè®¢é˜…çš„å‘布已更改" + +#: replication/logical/worker.c:1614 +#, c-format +msgid "logical replication apply worker for subscription %u will not start because the subscription was removed during startup" +msgstr "订阅%u的逻辑å¤åˆ¶åº”用工作线程将ä¸ä¼šå¯åŠ¨ï¼Œå› ä¸ºåœ¨å¯åŠ¨æœŸé—´å·²åˆ é™¤è¯¥è®¢é˜…" + +#: replication/logical/worker.c:1626 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" will not start because the subscription was disabled during startup" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”用工作进程将ä¸ä¼šå¯åŠ¨ï¼Œå› ä¸ºåœ¨å¯åŠ¨è¿‡ç¨‹ä¸­ç¦ç”¨äº†è®¢é˜…" + +#: replication/logical/worker.c:1644 +#, c-format +msgid "logical replication table synchronization worker for subscription \"%s\", table \"%s\" has started" +msgstr "订阅\"%s\"ã€è¡¨\"%s\"的逻辑å¤åˆ¶è¡¨åŒæ­¥å·¥ä½œçº¿ç¨‹å·²å¯åЍ" + +#: replication/logical/worker.c:1648 +#, c-format +msgid "logical replication apply worker for subscription \"%s\" has started" +msgstr "订阅\"%s\"的逻辑å¤åˆ¶åº”用工作线程已å¯åЍ " + +#: replication/logical/worker.c:1687 +#, c-format +msgid "subscription has no replication slot set" +msgstr "订阅没有å¤åˆ¶æ§½é›†" + +#: replication/pgoutput/pgoutput.c:117 +#, c-format +msgid "invalid proto_version" +msgstr "无效的proto_version" + +#: replication/pgoutput/pgoutput.c:122 +#, c-format +msgid "proto_version \"%s\" out of range" +msgstr "proto_version \"%s\"超出范围" + +#: replication/pgoutput/pgoutput.c:139 +#, c-format +msgid "invalid publication_names syntax" +msgstr "无效的publication_names语法" + +#: replication/pgoutput/pgoutput.c:181 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or lower" +msgstr "客户端å‘é€çš„å议版本为%dï¼Œä½†æˆ‘ä»¬åªæ”¯æŒåè®®%d或更低版本" + +#: replication/pgoutput/pgoutput.c:187 +#, c-format +msgid "client sent proto_version=%d but we only support protocol %d or higher" +msgstr "客户端å‘é€çš„å议版本为%dï¼Œä½†æˆ‘ä»¬åªæ”¯æŒåè®®%d或更高版本" + +#: replication/pgoutput/pgoutput.c:193 +#, c-format +msgid "publication_names parameter missing" +msgstr "缺少publication_names傿•°" + +#: replication/slot.c:182 #, c-format msgid "replication slot name \"%s\" is too short" msgstr "å¤åˆ¶æ§½å \"%s\" 太短" -#: replication/slot.c:192 +#: replication/slot.c:191 #, c-format msgid "replication slot name \"%s\" is too long" msgstr "å¤åˆ¶æ§½å \"%s\" 太长" -#: replication/slot.c:205 +#: replication/slot.c:204 #, c-format msgid "replication slot name \"%s\" contains invalid character" msgstr "å¤åˆ¶æ§½å \"%s\"ä¸­åŒ…å«æ— æ•ˆçš„æ•°æ®" -#: replication/slot.c:207 +#: replication/slot.c:206 #, c-format -msgid "" -"Replication slot names may only contain lower case letters, numbers, and the " -"underscore character." +msgid "Replication slot names may only contain lower case letters, numbers, and the underscore character." msgstr "å¤åˆ¶æ§½çš„åå­—åªèƒ½åŒ…å«å°å†™å­—æ¯ã€æ•°å­—以åŠä¸‹åˆ’线字符。" -#: replication/slot.c:254 +#: replication/slot.c:253 #, c-format msgid "replication slot \"%s\" already exists" msgstr "å¤åˆ¶æ§½å \"%s\" å·²ç»å­˜åœ¨" -#: replication/slot.c:264 +#: replication/slot.c:263 #, c-format msgid "all replication slots are in use" msgstr "所有的å¤åˆ¶æ§½éƒ½åœ¨ä½¿ç”¨ä¸­" -#: replication/slot.c:265 +#: replication/slot.c:264 #, c-format msgid "Free one or increase max_replication_slots." msgstr "释放一个槽或者增大max_replication_slots的值." -#: replication/slot.c:351 +#: replication/slot.c:387 replication/slotfuncs.c:663 #, c-format msgid "replication slot \"%s\" does not exist" msgstr "å¤åˆ¶æ§½å \"%s\" ä¸å­˜åœ¨" -#: replication/slot.c:355 +#: replication/slot.c:398 replication/slot.c:947 #, c-format -#| msgid "replication slot \"%s\" is already active for PID %d" msgid "replication slot \"%s\" is active for PID %d" msgstr "å¤åˆ¶æ§½ \"%s\" 正用于 PID %d" -#: replication/slot.c:501 replication/slot.c:912 replication/slot.c:1249 +#: replication/slot.c:631 replication/slot.c:1139 replication/slot.c:1499 #, c-format msgid "could not remove directory \"%s\"" msgstr "无法删除目录 \"%s\"" -#: replication/slot.c:761 +#: replication/slot.c:982 #, c-format msgid "replication slots can only be used if max_replication_slots > 0" msgstr "å¤åˆ¶æ§½åªæœ‰å½“ max_replication_slots > 0æ—¶æ‰èƒ½ä½¿ç”¨" -#: replication/slot.c:766 +#: replication/slot.c:987 #, c-format -#| msgid "replication slots can only be used if wal_level >= archive" msgid "replication slots can only be used if wal_level >= replica" msgstr "å¤åˆ¶æ§½åªæœ‰å½“ wal_level >= replica æ—¶æ‰èƒ½ä½¿ç”¨" -#: replication/slot.c:1181 replication/slot.c:1219 -#, c-format -msgid "could not read file \"%s\", read %d of %u: %m" -msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%s\", 读到了%d字节,从%u:%m处" - -#: replication/slot.c:1190 +#: replication/slot.c:1437 #, c-format msgid "replication slot file \"%s\" has wrong magic number: %u instead of %u" msgstr "å¤åˆ¶æ§½æ–‡ä»¶\"%s\"具有错误的magicå·ï¼š%u,正确的应该是%u" -#: replication/slot.c:1197 +#: replication/slot.c:1444 #, c-format msgid "replication slot file \"%s\" has unsupported version %u" msgstr "å¤åˆ¶æ§½æ–‡ä»¶ \"%s\" 的版本å·%uä¸è¢«æ”¯æŒ" -#: replication/slot.c:1204 +#: replication/slot.c:1451 #, c-format msgid "replication slot file \"%s\" has corrupted length %u" msgstr "å¤åˆ¶æ§½æ–‡ä»¶ \"%s\" 的长度 %uå·²æŸå" -#: replication/slot.c:1234 +#: replication/slot.c:1487 #, c-format msgid "checksum mismatch for replication slot file \"%s\": is %u, should be %u" msgstr "å¤åˆ¶æ§½æ–‡ä»¶\"%s\"的校验和ä¸åŒ¹é…:值为 %u,正确值应该是 %u" -#: replication/slot.c:1287 +#: replication/slot.c:1521 +#, c-format +msgid "logical replication slot \"%s\" exists, but wal_level < logical" +msgstr "存在逻辑å¤åˆ¶æ§½\"%s\",但wal_level < logical" + +#: replication/slot.c:1523 +#, c-format +msgid "Change wal_level to be logical or higher." +msgstr "å°† wal_level更改为logical或更高级别." + +#: replication/slot.c:1527 +#, c-format +msgid "physical replication slot \"%s\" exists, but wal_level < replica" +msgstr "物ç†å¤åˆ¶æ§½\"%s\"存在,但wal_level < replica" + +#: replication/slot.c:1529 +#, c-format +msgid "Change wal_level to be replica or higher." +msgstr "å°†wal_level更改为replica或更高级别." + +#: replication/slot.c:1563 #, c-format msgid "too many replication slots active before shutdown" msgstr "关闭剿œ‰å¤ªå¤šæ´»åŠ¨çš„å¤åˆ¶æ§½" -#: replication/syncrep.c:228 +#: replication/slotfuncs.c:526 #, c-format -msgid "" -"canceling the wait for synchronous replication and terminating connection " -"due to administrator command" +msgid "invalid target wal lsn" +msgstr "无效的目标wal lsn" + +#: replication/slotfuncs.c:548 +#, c-format +msgid "cannot advance replication slot that has not previously reserved WAL" +msgstr "无法å‰è¿›ä»¥å‰æ²¡æœ‰ä¿ç•™çš„WALçš„å¤åˆ¶æ§½" + +#: replication/slotfuncs.c:564 +#, c-format +msgid "cannot advance replication slot to %X/%X, minimum is %X/%X" +msgstr "无法将å¤åˆ¶æ§½å‰è¿›åˆ°%X/%X,最å°å€¼ä¸º%X/%X" + +#: replication/slotfuncs.c:670 +#, fuzzy, c-format +#| msgid "cannot use physical replication slot for logical decoding" +msgid "cannot copy physical replication slot \"%s\" as a logical replication slot" +msgstr "逻辑解ç ä¸èƒ½ä½¿ç”¨ç‰©ç†å¤åˆ¶æ§½" + +#: replication/slotfuncs.c:672 +#, fuzzy, c-format +#| msgid "cannot use a logical replication slot for physical replication" +msgid "cannot copy logical replication slot \"%s\" as a physical replication slot" +msgstr "物ç†å¤åˆ¶æ“作ä¸èƒ½ä½¿ç”¨é€»è¾‘å¤åˆ¶æ§½" + +#: replication/slotfuncs.c:681 +#, fuzzy, c-format +#| msgid "cannot advance replication slot that has not previously reserved WAL" +msgid "cannot copy a replication slot that doesn't reserve WAL" +msgstr "无法å‰è¿›ä»¥å‰æ²¡æœ‰ä¿ç•™çš„WALçš„å¤åˆ¶æ§½" + +#: replication/slotfuncs.c:746 +#, fuzzy, c-format +#| msgid "could not create replication slot \"%s\": %s" +msgid "could not copy replication slot \"%s\"" +msgstr "无法创建å¤åˆ¶æ§½\"%s\": %s" + +#: replication/slotfuncs.c:748 +#, c-format +msgid "The source replication slot was modified incompatibly during the copy operation." +msgstr "" + +#: replication/syncrep.c:248 +#, c-format +msgid "canceling the wait for synchronous replication and terminating connection due to administrator command" msgstr "å–æ¶ˆç­‰å¾…åŒæ­¥å¤åˆ¶ï¼Œå¬ä»Žç®¡ç†å‘˜å‘½ä»¤ç»ˆæ–­è¿žæŽ¥" -#: replication/syncrep.c:229 replication/syncrep.c:246 +#: replication/syncrep.c:249 replication/syncrep.c:266 #, c-format -msgid "" -"The transaction has already committed locally, but might not have been " -"replicated to the standby." +msgid "The transaction has already committed locally, but might not have been replicated to the standby." msgstr "事务已ç»åœ¨æœ¬åœ°æäº¤, 但有å¯èƒ½è¿˜æ²¡å®Œæˆåˆ°å¤‡ç”¨èŠ‚ç‚¹çš„å¤åˆ¶." -#: replication/syncrep.c:245 +#: replication/syncrep.c:265 #, c-format msgid "canceling wait for synchronous replication due to user request" msgstr "å¬ä»Žç”¨æˆ·è¯·æ±‚ï¼Œå–æ¶ˆç­‰å¾…åŒæ­¥å¤åˆ¶" -#: replication/syncrep.c:380 +#: replication/syncrep.c:398 #, c-format msgid "standby \"%s\" now has synchronous standby priority %u" msgstr "备用节点 \"%s\" çŽ°åœ¨æ‹¥æœ‰åŒæ­¥å¤‡ç”¨ä¼˜å…ˆçº§: %u" -#: replication/syncrep.c:440 +#: replication/syncrep.c:461 #, c-format -#| msgid "standby \"%s\" is now the synchronous standby with priority %u" msgid "standby \"%s\" is now a synchronous standby with priority %u" msgstr "åŽå¤‡ \"%s\" 现在是具有优先级 %u çš„ä¸€ä¸ªåŒæ­¥åŽå¤‡" -#: replication/syncrep.c:969 +#: replication/syncrep.c:465 #, c-format -msgid "synchronous_standby_names parser returned %d" -msgstr "synchronous_standby_names è§£æžå™¨è¿”回 %d" +msgid "standby \"%s\" is now a candidate for quorum synchronous standby" +msgstr "待机 \"%s\"现在是仲è£åŒæ­¥å¾…机的候选" -#: replication/syncrep.c:1014 +#: replication/syncrep.c:1165 #, c-format -msgid "" -"The configured number of synchronous standbys (%d) exceeds the number of " -"names of potential synchronous ones (%d)" -msgstr "é…ç½®çš„åŒæ­¥åŽå¤‡çš„æ•°é‡ï¼ˆ%dï¼‰è¶…è¿‡äº†æ½œåœ¨åŒæ­¥åŽå¤‡çš„åç§°æ•°é‡ï¼ˆ%d)" +msgid "synchronous_standby_names parser failed" +msgstr "synchronous_standby_names è§£æžå¤±è´¥" -#: replication/syncrep.c:1016 +#: replication/syncrep.c:1171 #, c-format -#| msgid "List of names of potential synchronous standbys." -msgid "" -"Specify more names of potential synchronous standbys in " -"synchronous_standby_names." -msgstr "在 synchronous_standby_names ä¸­æŒ‡å®šæ›´å¤šæ½œåœ¨åŒæ­¥åŽå¤‡çš„å称。" +msgid "number of synchronous standbys (%d) must be greater than zero" +msgstr "åŒæ­¥å¤‡ç”¨çš„æ•°ç›®ï¼ˆ%d)必须大于零" -#: replication/walreceiver.c:172 +#: replication/walreceiver.c:160 #, c-format msgid "terminating walreceiver process due to administrator command" msgstr "由于管ç†å‘˜å‘½ä»¤ä¸­æ–­walreceiver进程" -#: replication/walreceiver.c:324 +#: replication/walreceiver.c:276 +#, c-format +msgid "could not connect to the primary server: %s" +msgstr "无法连接到主用æœåŠ¡å™¨ï¼š%s" + +#: replication/walreceiver.c:322 +#, c-format +msgid "database system identifier differs between the primary and standby" +msgstr "在主用æœåŠ¡å™¨å’Œå¤‡ç”¨æœåŠ¡å™¨ä¹‹é—´ï¼Œæ•°æ®åº“系统标识符是ä¸ä¸€æ ·çš„。" + +#: replication/walreceiver.c:323 +#, c-format +msgid "The primary's identifier is %s, the standby's identifier is %s." +msgstr "主用æœåŠ¡å™¨çš„æ ‡è¯†ç¬¦æ˜¯%s,备用æœåŠ¡å™¨çš„æ ‡è¯†ç¬¦æ˜¯%s。" + +#: replication/walreceiver.c:333 #, c-format msgid "highest timeline %u of the primary is behind recovery timeline %u" msgstr "主æœåŠ¡å™¨ä¸Šçš„æœ€é«˜æ—¶é—´çº¿%u还在æ¢å¤æ—¶é—´çº¿%uçš„åŽè¾¹" -#: replication/walreceiver.c:357 +#: replication/walreceiver.c:369 #, c-format msgid "started streaming WAL from primary at %X/%X on timeline %u" msgstr "在时间点: %X/%X (时间安排%u)å¯åŠ¨æ—¥å¿—çš„æµæ“作" -#: replication/walreceiver.c:362 +#: replication/walreceiver.c:374 #, c-format msgid "restarted WAL streaming at %X/%X on timeline %u" msgstr "在%X/%X处时间线%u上é‡å¯WALæµæ“作" -#: replication/walreceiver.c:391 +#: replication/walreceiver.c:403 #, c-format msgid "cannot continue WAL streaming, recovery has already ended" msgstr "无法继续进行WALæµå¤åˆ¶æ“作,æ¢å¤å·²ç»ç»“æŸ" -#: replication/walreceiver.c:428 +#: replication/walreceiver.c:440 #, c-format msgid "replication terminated by primary server" msgstr "å¤åˆ¶ç”±ä¸»ç”¨æœåŠ¡å™¨ç»ˆæ­¢" -#: replication/walreceiver.c:429 +#: replication/walreceiver.c:441 #, c-format msgid "End of WAL reached on timeline %u at %X/%X." msgstr "WALç»“æŸæ—¶ï¼Œåˆ°äº†æ—¶é—´çº¿%u和地å€%X/%X." -#: replication/walreceiver.c:523 +#: replication/walreceiver.c:529 #, c-format msgid "terminating walreceiver due to timeout" msgstr "由于超时, 中止walreceiver进程" -#: replication/walreceiver.c:563 +#: replication/walreceiver.c:567 #, c-format msgid "primary server contains no more WAL on requested timeline %u" msgstr "主æœåС噍 在时间点 %uä¸å†æœ‰WAL" -#: replication/walreceiver.c:578 replication/walreceiver.c:936 +#: replication/walreceiver.c:582 replication/walreceiver.c:922 #, c-format msgid "could not close log segment %s: %m" msgstr "无法关闭日志段%s: %m" -#: replication/walreceiver.c:702 +#: replication/walreceiver.c:700 #, c-format msgid "fetching timeline history file for timeline %u from primary server" msgstr "从主æœåŠ¡å™¨çš„æ—¶é—´ç‚¹%uèŽ·å–æ—¶é—´ç‚¹åކ岿–‡ä»¶" -#: replication/walreceiver.c:990 +#: replication/walreceiver.c:976 #, c-format msgid "could not write to log segment %s at offset %u, length %lu: %m" msgstr "无法在åç§»é‡ %2$u,长度 %3$lu写入日志文件%1$s, 段:%4$m" -#: replication/walsender.c:485 +#: replication/walsender.c:497 #, c-format msgid "could not seek to beginning of file \"%s\": %m" msgstr "无法查找到文件\"%s\"的起始ä½ç½®: %m" -#: replication/walsender.c:536 +#: replication/walsender.c:548 +#, c-format +msgid "IDENTIFY_SYSTEM has not been run before START_REPLICATION" +msgstr "IDENTIFY_SYSTEM在START_REPLICATION之剿œªè¿è¡Œ" + +#: replication/walsender.c:565 #, c-format msgid "cannot use a logical replication slot for physical replication" msgstr "物ç†å¤åˆ¶æ“作ä¸èƒ½ä½¿ç”¨é€»è¾‘å¤åˆ¶æ§½" -#: replication/walsender.c:599 +#: replication/walsender.c:628 #, c-format -msgid "" -"requested starting point %X/%X on timeline %u is not in this server's history" +msgid "requested starting point %X/%X on timeline %u is not in this server's history" msgstr "请求的起始点%X/%X, 时间线%u,ä¸åœ¨è¯¥æœåŠ¡å™¨çš„æ—¶é—´çº¿åŽ†å²è®°å½•里" -#: replication/walsender.c:603 +#: replication/walsender.c:632 #, c-format msgid "This server's history forked from timeline %u at %X/%X." msgstr "æœåŠ¡å™¨çš„åŽ†å²æ—¶é—´çº¿åœ¨æ—¶é—´çº¿%u,地å€%X/%X处产生了分支." -#: replication/walsender.c:648 +#: replication/walsender.c:677 #, c-format -msgid "" -"requested starting point %X/%X is ahead of the WAL flush position of this " -"server %X/%X" +msgid "requested starting point %X/%X is ahead of the WAL flush position of this server %X/%X" msgstr "请求的起始点 %X/%X ä½äºŽè¯¥æœåŠ¡å™¨çš„WAL刷新ä½ç½®%X/%X之å‰" -#: replication/walsender.c:974 +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:907 +#, fuzzy, c-format +#| msgid "%s cannot run inside a subtransaction" +msgid "%s must not be called inside a transaction" +msgstr "%s 无法在一个å­äº‹ç‰©ä¸­è¿è¡Œ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:917 +#, fuzzy, c-format +#| msgid "%s cannot run inside a subtransaction" +msgid "%s must be called inside a transaction" +msgstr "%s 无法在一个å­äº‹ç‰©ä¸­è¿è¡Œ" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:923 +#, fuzzy, c-format +#| msgid "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT must be called in REPEATABLE READ isolation mode transaction" +msgid "%s must be called in REPEATABLE READ isolation mode transaction" +msgstr "必须在REPEATABLE READ隔离模å¼äº‹åŠ¡ä¸­è°ƒç”¨CREATE_REPLICATION_SLOT ... USE_SNAPSHOT" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:929 +#, fuzzy, c-format +#| msgid "SET TRANSACTION SNAPSHOT must be called before any query" +msgid "%s must be called before any query" +msgstr "SET TRANSACTION SNAPSHOT 必须在任何查询之å‰è°ƒç”¨" + +#. translator: %s is a CREATE_REPLICATION_SLOT statement +#: replication/walsender.c:935 +#, fuzzy, c-format +#| msgid "%s is not allowed in a SQL function" +msgid "%s must not be called in a subtransaction" +msgstr "%s ä¸å…许在一个 SQL 函数中" + +#: replication/walsender.c:1082 #, c-format msgid "terminating walsender process after promotion" msgstr "在æå‡åŽ, 中断walreceiver进程" -#: replication/walsender.c:1300 +#: replication/walsender.c:1453 +#, c-format +msgid "cannot execute new commands while WAL sender is in stopping mode" +msgstr "当WAL senderå¤„äºŽåœæ­¢æ¨¡å¼æ—¶ï¼Œæ— æ³•执行新命令" + +#: replication/walsender.c:1486 #, c-format msgid "received replication command: %s" msgstr "收到的å¤åˆ¶å‘½ä»¤ï¼š%s" -#: replication/walsender.c:1393 replication/walsender.c:1409 +#: replication/walsender.c:1502 tcop/fastpath.c:279 tcop/postgres.c:1103 +#: tcop/postgres.c:1426 tcop/postgres.c:1684 tcop/postgres.c:2077 +#: tcop/postgres.c:2463 tcop/postgres.c:2542 +#, c-format +msgid "current transaction is aborted, commands ignored until end of transaction block" +msgstr "当å‰äº‹åŠ¡è¢«ç»ˆæ­¢, 事务å—结æŸä¹‹å‰çš„æŸ¥è¯¢è¢«å¿½ç•¥" + +#: replication/walsender.c:1570 +#, c-format +msgid "cannot execute SQL commands in WAL sender for physical replication" +msgstr "无法在WAL sender中执行用于物ç†å¤åˆ¶çš„SQL命令" + +#: replication/walsender.c:1618 replication/walsender.c:1634 #, c-format msgid "unexpected EOF on standby connection" msgstr "在备用æœåŠ¡å™¨è¿žæŽ¥ä¸Šçš„å‡ºçŽ°æ„外的EOF" -#: replication/walsender.c:1423 +#: replication/walsender.c:1648 #, c-format msgid "unexpected standby message type \"%c\", after receiving CopyDone" msgstr "在接收CopyDoneåŽå‡ºçްæ„外的消æ¯ç±»åž‹\"%c\"" -#: replication/walsender.c:1461 +#: replication/walsender.c:1686 #, c-format msgid "invalid standby message type \"%c\"" msgstr "无效的备用节点消æ¯ç±»åž‹ \"%c\"" -#: replication/walsender.c:1502 +#: replication/walsender.c:1727 #, c-format msgid "unexpected message type \"%c\"" msgstr "æ„外的消æ¯ç±»åž‹\"%c\"" -#: replication/walsender.c:1786 +#: replication/walsender.c:2145 #, c-format msgid "terminating walsender process due to replication timeout" msgstr "由于å¤åˆ¶è¶…æ—¶, 中断walreceiver进程" -#: replication/walsender.c:1879 +#: replication/walsender.c:2222 #, c-format -msgid "standby \"%s\" has now caught up with primary" -msgstr "备用节点 \"%s\" 现在é‡ä¸Šäº†ä¸»èŠ‚ç‚¹" +msgid "\"%s\" has now caught up with upstream server" +msgstr "现在,\"%s\"已赶上上游æœåС噍" -#: replication/walsender.c:1982 -#, c-format -msgid "" -"number of requested standby connections exceeds max_wal_senders (currently " -"%d)" -msgstr "æ‰€è¦æ±‚的备用æœåŠ¡å™¨è¿žæŽ¥æ•°è¶…è¿‡äº†å‚æ•°max_wal_senders的值(当å‰è®¾ç½®ä¸º%d)" +#: replication/walsender.c:2481 +#, fuzzy, c-format +#| msgid "could not read from log segment %s, offset %u, length %lu: %m" +msgid "could not read from log segment %s, offset %u, length %zu: %m" +msgstr "无法在日志段%s,åç§»é‡ä¸º%u, 长度为%luçš„ä½ç½®ä¸Šè¿›è¡Œè¯»æ“作: %m" -#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:973 +#: rewrite/rewriteDefine.c:112 rewrite/rewriteDefine.c:989 #, c-format msgid "rule \"%s\" for relation \"%s\" already exists" msgstr "关系 \"%2$s\" 的规则 \"%1$s\" å·²ç»å­˜åœ¨" -#: rewrite/rewriteDefine.c:297 +#: rewrite/rewriteDefine.c:301 #, c-format msgid "rule actions on OLD are not implemented" msgstr "在 OLD 上的规则动作没有实现" -#: rewrite/rewriteDefine.c:298 +#: rewrite/rewriteDefine.c:302 #, c-format msgid "Use views or triggers instead." msgstr "请使用视图或触å‘器代替." -#: rewrite/rewriteDefine.c:302 +#: rewrite/rewriteDefine.c:306 #, c-format msgid "rule actions on NEW are not implemented" msgstr "在 NEW 上的规则动作没有实现" -#: rewrite/rewriteDefine.c:303 +#: rewrite/rewriteDefine.c:307 #, c-format msgid "Use triggers instead." msgstr "请使用触å‘器代替." -#: rewrite/rewriteDefine.c:316 +#: rewrite/rewriteDefine.c:320 #, c-format msgid "INSTEAD NOTHING rules on SELECT are not implemented" msgstr "在 SELECT 上的 INSTEAD NOTHING 规则没有实现" -#: rewrite/rewriteDefine.c:317 +#: rewrite/rewriteDefine.c:321 #, c-format msgid "Use views instead." msgstr "请使用视图代替." -#: rewrite/rewriteDefine.c:325 +#: rewrite/rewriteDefine.c:329 #, c-format msgid "multiple actions for rules on SELECT are not implemented" msgstr "在 SELECT 上的多动作规则没有实现" -#: rewrite/rewriteDefine.c:336 +#: rewrite/rewriteDefine.c:339 #, c-format msgid "rules on SELECT must have action INSTEAD SELECT" msgstr "在 SELECT 上的规则必须有 INSTEAD SELECT 动作" -#: rewrite/rewriteDefine.c:344 +#: rewrite/rewriteDefine.c:347 #, c-format msgid "rules on SELECT must not contain data-modifying statements in WITH" msgstr "SELECT上的规则: ä¸èƒ½åœ¨WITHå­å¥ä¸­åŒ…嫿•°æ®ä¿®æ”¹æ“作" -#: rewrite/rewriteDefine.c:352 +#: rewrite/rewriteDefine.c:355 #, c-format msgid "event qualifications are not implemented for rules on SELECT" msgstr "在 SELECT 上规则的事件æ¡ä»¶æ²¡æœ‰å®žçް" -#: rewrite/rewriteDefine.c:379 +#: rewrite/rewriteDefine.c:382 #, c-format msgid "\"%s\" is already a view" msgstr "\"%s\" å·²ç»æ˜¯ä¸€ä¸ªè§†å›¾äº†" -#: rewrite/rewriteDefine.c:403 +#: rewrite/rewriteDefine.c:406 #, c-format msgid "view rule for \"%s\" must be named \"%s\"" msgstr "用于 \"%s\" 的视图规则必须命å为 \"%s\"" -#: rewrite/rewriteDefine.c:432 +#: rewrite/rewriteDefine.c:434 +#, c-format +msgid "cannot convert partitioned table \"%s\" to a view" +msgstr "无法将分区表\"%s\"转æ¢ä¸ºè§†å›¾" + +#: rewrite/rewriteDefine.c:440 +#, c-format +msgid "cannot convert partition \"%s\" to a view" +msgstr "无法将分区\"%s\"转æ¢ä¸ºè§†å›¾" + +#: rewrite/rewriteDefine.c:449 #, c-format msgid "could not convert table \"%s\" to a view because it is not empty" msgstr "无法把表 \"%s\" 转化为视图, å› ä¸ºå®ƒä¸æ˜¯ç©ºçš„" -#: rewrite/rewriteDefine.c:440 +#: rewrite/rewriteDefine.c:458 #, c-format msgid "could not convert table \"%s\" to a view because it has triggers" msgstr "无法把表 \"%s\" 转æ¢ä¸ºè§†å›¾, 因为它有触å‘器" -#: rewrite/rewriteDefine.c:442 +#: rewrite/rewriteDefine.c:460 #, c-format -msgid "" -"In particular, the table cannot be involved in any foreign key relationships." +msgid "In particular, the table cannot be involved in any foreign key relationships." msgstr "特别是在任何外键关系中ä¸èƒ½æ¶‰åŠè¡¨" -#: rewrite/rewriteDefine.c:447 +#: rewrite/rewriteDefine.c:465 #, c-format msgid "could not convert table \"%s\" to a view because it has indexes" msgstr "无法把表 \"%s\" 转æ¢ä¸ºè§†å›¾, 因为它有索引" -#: rewrite/rewriteDefine.c:453 +#: rewrite/rewriteDefine.c:471 #, c-format msgid "could not convert table \"%s\" to a view because it has child tables" msgstr "无法把表 \"%s\" 转æ¢ä¸ºè§†å›¾, 因为它有å­è¡¨" -#: rewrite/rewriteDefine.c:459 +#: rewrite/rewriteDefine.c:477 #, c-format -msgid "" -"could not convert table \"%s\" to a view because it has row security enabled" +msgid "could not convert table \"%s\" to a view because it has row security enabled" msgstr "无法把表\"%s\"转æ¢ä¸ºè§†å›¾ï¼Œå› ä¸ºå®ƒçš„行级安全性被å¯ç”¨" -#: rewrite/rewriteDefine.c:465 +#: rewrite/rewriteDefine.c:483 #, c-format -msgid "" -"could not convert table \"%s\" to a view because it has row security policies" +msgid "could not convert table \"%s\" to a view because it has row security policies" msgstr "无法把表\"%s\"转æ¢ä¸ºè§†å›¾ï¼Œå› ä¸ºå®ƒæœ‰è¡Œçº§å®‰å…¨æ€§ç­–ç•¥" -#: rewrite/rewriteDefine.c:492 +#: rewrite/rewriteDefine.c:510 #, c-format msgid "cannot have multiple RETURNING lists in a rule" msgstr "在一个规则中ä¸èƒ½æœ‰å¤šä¸ªRETURNING列表" -#: rewrite/rewriteDefine.c:497 +#: rewrite/rewriteDefine.c:515 #, c-format msgid "RETURNING lists are not supported in conditional rules" msgstr "在æ¡ä»¶è§„åˆ™ä¸­ä¸æ”¯æŒRETURNING列表" -#: rewrite/rewriteDefine.c:501 +#: rewrite/rewriteDefine.c:519 #, c-format msgid "RETURNING lists are not supported in non-INSTEAD rules" msgstr "在éžINSTEADè§„åˆ™ä¸­ä¸æ”¯æŒRETURNING列表" -#: rewrite/rewriteDefine.c:667 +#: rewrite/rewriteDefine.c:683 #, c-format msgid "SELECT rule's target list has too many entries" msgstr "SELECT 规则的目标列表的记录太多" -#: rewrite/rewriteDefine.c:668 +#: rewrite/rewriteDefine.c:684 #, c-format msgid "RETURNING list has too many entries" msgstr "RETURNING列表中的项太多." -#: rewrite/rewriteDefine.c:695 +#: rewrite/rewriteDefine.c:711 #, c-format msgid "cannot convert relation containing dropped columns to view" msgstr "无法转æ¢åŒ…å«å·²åˆ é™¤å­—段的关系为视图" -#: rewrite/rewriteDefine.c:696 +#: rewrite/rewriteDefine.c:712 #, c-format -#| msgid "cannot convert relation containing dropped columns to view" -msgid "" -"cannot create a RETURNING list for a relation containing dropped columns" +msgid "cannot create a RETURNING list for a relation containing dropped columns" msgstr "æ— æ³•ä¸ºä¸€ä¸ªåŒ…å«æœ‰è¢«åˆ é™¤åˆ—的关系创建一个 RETURNING 列表" -#: rewrite/rewriteDefine.c:702 +#: rewrite/rewriteDefine.c:718 #, c-format -msgid "" -"SELECT rule's target entry %d has different column name from column \"%s\"" +msgid "SELECT rule's target entry %d has different column name from column \"%s\"" msgstr "SELECT 规则的目标记录 %d 的字段å和字段 \"%s\" ä¸åŒ" -#: rewrite/rewriteDefine.c:704 +#: rewrite/rewriteDefine.c:720 #, c-format msgid "SELECT target entry is named \"%s\"." -msgstr "SELECT 目标项命å为\"%s\"," +msgstr "SELECT 目标项命å为\"%s\"." -#: rewrite/rewriteDefine.c:713 +#: rewrite/rewriteDefine.c:729 #, c-format msgid "SELECT rule's target entry %d has different type from column \"%s\"" msgstr "SELECT 规则的目标记录 %d 和字段 \"%s\" 的类型ä¸åŒ" -#: rewrite/rewriteDefine.c:715 +#: rewrite/rewriteDefine.c:731 #, c-format msgid "RETURNING list's entry %d has different type from column \"%s\"" msgstr "RETURNING列表中的第%d项与列\"%s\"的类型ä¸åŒ" -#: rewrite/rewriteDefine.c:718 rewrite/rewriteDefine.c:742 +#: rewrite/rewriteDefine.c:734 rewrite/rewriteDefine.c:758 #, c-format msgid "SELECT target entry has type %s, but column has type %s." msgstr "SELECT 目标项类型为%s, 但其列类型为%s." -#: rewrite/rewriteDefine.c:721 rewrite/rewriteDefine.c:746 +#: rewrite/rewriteDefine.c:737 rewrite/rewriteDefine.c:762 #, c-format msgid "RETURNING list entry has type %s, but column has type %s." msgstr "RETURNING列表项类型为%s, 但是其列类型为%s." -#: rewrite/rewriteDefine.c:737 +#: rewrite/rewriteDefine.c:753 #, c-format msgid "SELECT rule's target entry %d has different size from column \"%s\"" msgstr "SELECT 规则的目标记录 %d 与字段 \"%s\" 的大å°ä¸åŒ" -#: rewrite/rewriteDefine.c:739 +#: rewrite/rewriteDefine.c:755 #, c-format msgid "RETURNING list's entry %d has different size from column \"%s\"" msgstr "在RETURNING列表中的第%d项的大å°ä¸Žåˆ— \"%s\"ä¸åŒ" -#: rewrite/rewriteDefine.c:756 +#: rewrite/rewriteDefine.c:772 #, c-format msgid "SELECT rule's target list has too few entries" msgstr "SELECT 规则的目标列表记录数太少" -#: rewrite/rewriteDefine.c:757 +#: rewrite/rewriteDefine.c:773 #, c-format msgid "RETURNING list has too few entries" msgstr "RETURNING 列表åŽé¢çš„项太少" -#: rewrite/rewriteDefine.c:849 rewrite/rewriteDefine.c:964 -#: rewrite/rewriteSupport.c:112 +#: rewrite/rewriteDefine.c:866 rewrite/rewriteDefine.c:980 +#: rewrite/rewriteSupport.c:109 #, c-format msgid "rule \"%s\" for relation \"%s\" does not exist" msgstr "关系 \"%2$s\" çš„ \"%1$s\" 规则ä¸å­˜åœ¨" -#: rewrite/rewriteDefine.c:983 +#: rewrite/rewriteDefine.c:999 #, c-format msgid "renaming an ON SELECT rule is not allowed" msgstr "ä¸å…许é‡å‘½å一个ON SELECT规则" -#: rewrite/rewriteHandler.c:528 +#: rewrite/rewriteHandler.c:544 #, c-format -msgid "" -"WITH query name \"%s\" appears in both a rule action and the query being " -"rewritten" +msgid "WITH query name \"%s\" appears in both a rule action and the query being rewritten" msgstr "WITH 查询å \"%s\" 看起æ¥å¥½åƒåœ¨æŸè§„则行为和查询é‡å†™é‡ŒåŒæ—¶å‡ºçް" -#: rewrite/rewriteHandler.c:588 +#: rewrite/rewriteHandler.c:604 #, c-format msgid "cannot have RETURNING lists in multiple rules" msgstr "无法在多个规则中拥有RETURNING列表" -#: rewrite/rewriteHandler.c:928 rewrite/rewriteHandler.c:946 +#: rewrite/rewriteHandler.c:813 rewrite/rewriteHandler.c:825 #, c-format -msgid "multiple assignments to same column \"%s\"" -msgstr "对åŒä¸€åˆ—\"%s\"进行了多次分é…" +msgid "cannot insert into column \"%s\"" +msgstr "无法æ’入到列\"%s\"" -#: rewrite/rewriteHandler.c:1721 rewrite/rewriteHandler.c:3331 +#: rewrite/rewriteHandler.c:814 rewrite/rewriteHandler.c:836 #, c-format -msgid "infinite recursion detected in rules for relation \"%s\"" -msgstr "在关系 \"%s\" 的规则中å‘现无é™å¾ªçޝ" +msgid "Column \"%s\" is an identity column defined as GENERATED ALWAYS." +msgstr "列\"%s\"是定义为GENERATED ALWAYS的标识列." + +#: rewrite/rewriteHandler.c:816 +#, c-format +msgid "Use OVERRIDING SYSTEM VALUE to override." +msgstr "使用OVERRIDING SYSTEM VALUE覆盖." + +#: rewrite/rewriteHandler.c:835 rewrite/rewriteHandler.c:842 +#, c-format +msgid "column \"%s\" can only be updated to DEFAULT" +msgstr "列\"%s\"åªèƒ½æ›´æ–°ä¸ºé»˜è®¤å€¼" + +#: rewrite/rewriteHandler.c:1011 rewrite/rewriteHandler.c:1029 +#, c-format +msgid "multiple assignments to same column \"%s\"" +msgstr "对åŒä¸€åˆ—\"%s\"进行了多次分é…" -#: rewrite/rewriteHandler.c:1806 +#: rewrite/rewriteHandler.c:2059 #, c-format msgid "infinite recursion detected in policy for relation \"%s\"" msgstr "在关系\"%s\"的策略中检测到无é™å¾ªçޝ" -#: rewrite/rewriteHandler.c:2123 +#: rewrite/rewriteHandler.c:2379 msgid "Junk view columns are not updatable." msgstr "废弃视图列ä¸å¯æ›´æ–°." -#: rewrite/rewriteHandler.c:2128 -msgid "" -"View columns that are not columns of their base relation are not updatable." +#: rewrite/rewriteHandler.c:2384 +msgid "View columns that are not columns of their base relation are not updatable." msgstr "ä¸å±žäºŽåŸºç¡€å…³ç³»çš„列的那些视图列ä¸èƒ½ç”¨äºŽæ›´æ–°æ“作." -#: rewrite/rewriteHandler.c:2131 +#: rewrite/rewriteHandler.c:2387 msgid "View columns that refer to system columns are not updatable." msgstr "引用系统列的视图列ä¸èƒ½ç”¨äºŽæ›´æ–°æ“作." -#: rewrite/rewriteHandler.c:2134 +#: rewrite/rewriteHandler.c:2390 msgid "View columns that return whole-row references are not updatable." msgstr "返回整行引用的视图列ä¸èƒ½æ›´æ–°" -#: rewrite/rewriteHandler.c:2192 +#: rewrite/rewriteHandler.c:2451 msgid "Views containing DISTINCT are not automatically updatable." msgstr "包å«DISTINCT的视图列ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2195 +#: rewrite/rewriteHandler.c:2454 msgid "Views containing GROUP BY are not automatically updatable." msgstr "åŒ…å« GROUP BY 的视图列ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2198 +#: rewrite/rewriteHandler.c:2457 msgid "Views containing HAVING are not automatically updatable." msgstr "åŒ…å« HAVING 的视图列ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2201 -msgid "" -"Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." +#: rewrite/rewriteHandler.c:2460 +msgid "Views containing UNION, INTERSECT, or EXCEPT are not automatically updatable." msgstr "åŒ…å« UNION, INTERSECT, 或 EXCEPT ä¸èƒ½ç”¨äºŽè‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2204 +#: rewrite/rewriteHandler.c:2463 msgid "Views containing WITH are not automatically updatable." msgstr "åŒ…å« WITH 的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2207 +#: rewrite/rewriteHandler.c:2466 msgid "Views containing LIMIT or OFFSET are not automatically updatable." msgstr "åŒ…å« LIMIT 或 OFFSET 的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2219 +#: rewrite/rewriteHandler.c:2478 msgid "Views that return aggregate functions are not automatically updatable." msgstr "返回èšé›†å‡½æ•°çš„视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2222 +#: rewrite/rewriteHandler.c:2481 msgid "Views that return window functions are not automatically updatable." msgstr "返回窗å£å‡½æ•°çš„视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2225 -msgid "" -"Views that return set-returning functions are not automatically updatable." +#: rewrite/rewriteHandler.c:2484 +msgid "Views that return set-returning functions are not automatically updatable." msgstr "返回自返回函数的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2232 rewrite/rewriteHandler.c:2236 -#: rewrite/rewriteHandler.c:2243 -msgid "" -"Views that do not select from a single table or view are not automatically " -"updatable." +#: rewrite/rewriteHandler.c:2491 rewrite/rewriteHandler.c:2495 +#: rewrite/rewriteHandler.c:2503 +msgid "Views that do not select from a single table or view are not automatically updatable." msgstr "䏿¥è‡ªå•表或å•视图的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2246 +#: rewrite/rewriteHandler.c:2506 msgid "Views containing TABLESAMPLE are not automatically updatable." msgstr "包å«TABLESAMPLE的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°ã€‚" -#: rewrite/rewriteHandler.c:2270 +#: rewrite/rewriteHandler.c:2530 msgid "Views that have no updatable columns are not automatically updatable." msgstr "没有更新列的视图ä¸èƒ½è‡ªåŠ¨æ›´æ–°." -#: rewrite/rewriteHandler.c:2724 +#: rewrite/rewriteHandler.c:2987 #, c-format msgid "cannot insert into column \"%s\" of view \"%s\"" msgstr "无法æ’入列\"%s\"到视图\"%s\"" -#: rewrite/rewriteHandler.c:2732 +#: rewrite/rewriteHandler.c:2995 #, c-format msgid "cannot update column \"%s\" of view \"%s\"" msgstr "无法更新视图 \"%2$s\" 的字段 \"%1$s\"" -#: rewrite/rewriteHandler.c:3130 +#: rewrite/rewriteHandler.c:3471 #, c-format -msgid "" -"DO INSTEAD NOTHING rules are not supported for data-modifying statements in " -"WITH" +msgid "DO INSTEAD NOTHING rules are not supported for data-modifying statements in WITH" msgstr "DO INSTEAD NOTHINGè§„åˆ™ä¸æ”¯æŒåœ¨WITHå­å¥ä¸­æ‰§è¡Œæ•°æ®ä¿®æ”¹æ“作" -#: rewrite/rewriteHandler.c:3144 +#: rewrite/rewriteHandler.c:3485 #, c-format -msgid "" -"conditional DO INSTEAD rules are not supported for data-modifying statements " -"in WITH" +msgid "conditional DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "DO INSTEAD æ¡ä»¶è§„åˆ™ä¸æ”¯æŒåœ¨WITHå­å¥ä¸­æ‰§è¡Œæ•°æ®ä¿®æ”¹æ“作" -#: rewrite/rewriteHandler.c:3148 +#: rewrite/rewriteHandler.c:3489 #, c-format msgid "DO ALSO rules are not supported for data-modifying statements in WITH" msgstr "DO ALSO è§„åˆ™ä¸æ”¯æŒåœ¨WITHå­å¥ä¸­æ‰§è¡Œæ•°æ®ä¿®æ”¹æ“作" -#: rewrite/rewriteHandler.c:3153 +#: rewrite/rewriteHandler.c:3494 #, c-format -msgid "" -"multi-statement DO INSTEAD rules are not supported for data-modifying " -"statements in WITH" +msgid "multi-statement DO INSTEAD rules are not supported for data-modifying statements in WITH" msgstr "å¤šè¯­å¥ DO INSTEAD è§„åˆ™ä¸æ”¯æŒåœ¨WITHå­å¥ä¸­æ‰§è¡Œæ•°æ®ä¿®æ”¹æ“作" -#: rewrite/rewriteHandler.c:3368 +#: rewrite/rewriteHandler.c:3744 #, c-format msgid "cannot perform INSERT RETURNING on relation \"%s\"" msgstr "无法在关系\"%s\"上执行INSERT RETURNING " -#: rewrite/rewriteHandler.c:3370 +#: rewrite/rewriteHandler.c:3746 #, c-format -msgid "" -"You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." +msgid "You need an unconditional ON INSERT DO INSTEAD rule with a RETURNING clause." msgstr "您需è¦ä¸€ä¸ªæ— æ¡ä»¶, 且带有RETURNINGå­å¥çš„ON INSERT DO INSTEAD的规则." -#: rewrite/rewriteHandler.c:3375 +#: rewrite/rewriteHandler.c:3751 #, c-format msgid "cannot perform UPDATE RETURNING on relation \"%s\"" msgstr "无法在关系\"%s\"执行UPDATE RETURNING" -#: rewrite/rewriteHandler.c:3377 +#: rewrite/rewriteHandler.c:3753 #, c-format -msgid "" -"You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." +msgid "You need an unconditional ON UPDATE DO INSTEAD rule with a RETURNING clause." msgstr "您需è¦ä¸€ä¸ªæ— æ¡ä»¶çš„ ON UPDATE DO INSTEAD 规则." -#: rewrite/rewriteHandler.c:3382 +#: rewrite/rewriteHandler.c:3758 #, c-format msgid "cannot perform DELETE RETURNING on relation \"%s\"" msgstr "无法在关系 \"%s\"上执行DELETE RETURNING" -#: rewrite/rewriteHandler.c:3384 +#: rewrite/rewriteHandler.c:3760 #, c-format -msgid "" -"You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." +msgid "You need an unconditional ON DELETE DO INSTEAD rule with a RETURNING clause." msgstr "您需è¦ä¸€ä¸ªæ— æ¡ä»¶, 且带有RETURNINGå­å¥çš„ON DELETE DO INSTEAD 规则." -#: rewrite/rewriteHandler.c:3402 +#: rewrite/rewriteHandler.c:3778 #, c-format -msgid "" -"INSERT with ON CONFLICT clause cannot be used with table that has INSERT or " -"UPDATE rules" +msgid "INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules" msgstr "无法对具有INSERT或者UPDATE规则的表使用带有ON CONFLICTå­å¥çš„INSERT" -#: rewrite/rewriteHandler.c:3459 +#: rewrite/rewriteHandler.c:3835 #, c-format -msgid "" -"WITH cannot be used in a query that is rewritten by rules into multiple " -"queries" +msgid "WITH cannot be used in a query that is rewritten by rules into multiple queries" msgstr "WITH ä¸èƒ½ç”¨äºŽæŒ‰è§„则å¯é‡å†™ä¸ºå¤šä¸ªæŸ¥è¯¢çš„æŸ¥è¯¢è¯­å¥ä¸­" #: rewrite/rewriteManip.c:1003 @@ -16987,457 +18785,420 @@ msgstr "æ¡ä»¶å·¥å…·è¯­å¥æ²¡æœ‰å®žçް" msgid "WHERE CURRENT OF on a view is not implemented" msgstr "未实现在视图上的WHERE CURRENT OFæ“作" -#: rewrite/rewriteManip.c:1434 +#: rewrite/rewriteManip.c:1503 #, c-format -msgid "" -"NEW variables in ON UPDATE rules cannot reference columns that are part of a " -"multiple assignment in the subject UPDATE command" -msgstr "" -"ON UPDATE规则中的NEWå˜é‡ä¸èƒ½å¼•用主UPDATE命令中作为一个多é‡èµ‹å€¼çš„组æˆéƒ¨åˆ†çš„列" +msgid "NEW variables in ON UPDATE rules cannot reference columns that are part of a multiple assignment in the subject UPDATE command" +msgstr "ON UPDATE规则中的NEWå˜é‡ä¸èƒ½å¼•用主UPDATE命令中作为一个多é‡èµ‹å€¼çš„组æˆéƒ¨åˆ†çš„列" -#: rewrite/rewriteSupport.c:154 +#: snowball/dict_snowball.c:197 #, c-format -msgid "rule \"%s\" does not exist" -msgstr "规则 \"%s\" ä¸å­˜åœ¨" +msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" +msgstr "对于语言\"%s\" 和编ç \"%s\"æ¥è¯´ï¼Œæ²¡æœ‰æœ‰æ•ˆçš„Snowball stemmer " -#: rewrite/rewriteSupport.c:167 +#: snowball/dict_snowball.c:220 tsearch/dict_ispell.c:74 +#: tsearch/dict_simple.c:49 #, c-format -msgid "there are multiple rules named \"%s\"" -msgstr "有多æ¡è§„则的å字是 \"%s\"" +msgid "multiple StopWords parameters" +msgstr "多个 StopWords傿•°" -#: rewrite/rewriteSupport.c:168 +#: snowball/dict_snowball.c:229 #, c-format -msgid "Specify a relation name as well as a rule name." -msgstr "指定一个关系åç§°, 和规则å称一样." - -#: scan.l:433 -msgid "unterminated /* comment" -msgstr "/* 注释没有结æŸ" +msgid "multiple Language parameters" +msgstr "å¤šè¯­è¨€å‚æ•°" -#: scan.l:462 -msgid "unterminated bit string literal" -msgstr "未结æŸçš„bit字符串常é‡" +#: snowball/dict_snowball.c:236 +#, c-format +msgid "unrecognized Snowball parameter: \"%s\"" +msgstr "未识别Snowball傿•°: \"%s\"" -#: scan.l:483 -msgid "unterminated hexadecimal string literal" -msgstr "未结æŸçš„16进制字符串常é‡" +#: snowball/dict_snowball.c:244 +#, c-format +msgid "missing Language parameter" +msgstr "ç¼ºå°‘è¯­è¨€å‚æ•°" -#: scan.l:533 +#: statistics/dependencies.c:673 statistics/dependencies.c:726 +#: statistics/mcv.c:1310 statistics/mcv.c:1341 statistics/mvdistinct.c:348 +#: statistics/mvdistinct.c:401 utils/adt/pseudotypes.c:94 +#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:147 +#: utils/adt/pseudotypes.c:171 utils/adt/pseudotypes.c:282 +#: utils/adt/pseudotypes.c:307 utils/adt/pseudotypes.c:335 +#: utils/adt/pseudotypes.c:363 utils/adt/pseudotypes.c:393 #, c-format -msgid "unsafe use of string constant with Unicode escapes" -msgstr "è¿™ç§ä½¿ç”¨å¸¦æœ‰Unicode转义字符的字符串常é‡çš„æ–¹æ³•ä¸å®‰å…¨." +msgid "cannot accept a value of type %s" +msgstr "无法接å—一个类型%s的值" -#: scan.l:534 +#: statistics/extended_stats.c:119 #, c-format -msgid "" -"String constants with Unicode escapes cannot be used when " -"standard_conforming_strings is off." -msgstr "" -"当傿•°standard_conforming_stringså¤„äºŽå…³é—­çŠ¶æ€æ—¶ï¼Œæ— æ³•使用带有Unicode转义字符" -"的字符串常é‡." +msgid "statistics object \"%s.%s\" could not be computed for relation \"%s.%s\"" +msgstr "无法为关系\"%3$s.%4$s\"计算统计对象\"%1$s.%2$s\"" -#: scan.l:580 scan.l:779 -msgid "invalid Unicode escape character" -msgstr "无效Unicode转义字符" +#: statistics/mcv.c:1166 utils/adt/jsonfuncs.c:1709 utils/adt/jsonfuncs.c:3266 +#: utils/adt/jsonfuncs.c:3621 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "è¿”å›žå€¼ç±»åž‹æ˜¯è®°å½•çš„å‡½æ•°åœ¨ä¸æŽ¥å—使用记录类型的环境中调用" -#: scan.l:606 scan.l:614 scan.l:622 scan.l:623 scan.l:624 scan.l:1338 -#: scan.l:1365 scan.l:1369 scan.l:1407 scan.l:1411 scan.l:1433 -msgid "invalid Unicode surrogate pair" -msgstr "无效的Unicode代ç†é¡¹å¯¹(surrogate pair)" - -#: scan.l:628 -#, c-format -msgid "invalid Unicode escape" -msgstr "无效的Unicode转义字符" - -#: scan.l:629 -#, c-format -msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." -msgstr "Unicode转义字符必须是\\uXXXX或\\UXXXXXXXX." - -#: scan.l:640 -#, c-format -msgid "unsafe use of \\' in a string literal" -msgstr "在字符串常é‡ä¸­ä½¿ç”¨\\ä¸å®‰å…¨" - -#: scan.l:641 -#, c-format -msgid "" -"Use '' to write quotes in strings. \\' is insecure in client-only encodings." -msgstr "使用''在字符串中表示引å·,åœ¨åªæœ‰å®¢æˆ·ç«¯ä½¿ç”¨çš„ç¼–ç ä¸­ä½¿ç”¨\\'ä¸å®‰å…¨." - -#: scan.l:716 -msgid "unterminated dollar-quoted string" -msgstr "未结æŸçš„用$符å·å¼•用的字符串" - -#: scan.l:733 scan.l:759 scan.l:774 -msgid "zero-length delimited identifier" -msgstr "长度为0的分隔标示符" - -#: scan.l:794 -msgid "unterminated quoted identifier" -msgstr "未结æŸçš„引用标识符" - -#: scan.l:925 -msgid "operator too long" -msgstr "æ“作符太长" - -#. translator: %s is typically the translation of "syntax error" -#: scan.l:1078 -#, c-format -msgid "%s at end of input" -msgstr "%s 在输入的末尾" - -#. translator: first %s is typically the translation of "syntax error" -#: scan.l:1086 syncrep_scanner.l:115 -#, c-format -msgid "%s at or near \"%s\"" -msgstr "%s 在 \"%s\" 或附近的" - -#: scan.l:1252 scan.l:1284 -msgid "" -"Unicode escape values cannot be used for code point values above 007F when " -"the server encoding is not UTF8" -msgstr "当æœåŠ¡å™¨çš„ç¼–ç ä¸æ˜¯UTF8时,无法为在007F以上的ç ç‚¹å€¼ä½¿ç”¨Unicode转义值." - -#: scan.l:1280 scan.l:1425 -msgid "invalid Unicode escape value" -msgstr "无效的Unicode转义值" - -#: scan.l:1482 -#, c-format -msgid "nonstandard use of \\' in a string literal" -msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用\\'" - -#: scan.l:1483 -#, c-format -msgid "" -"Use '' to write quotes in strings, or use the escape string syntax (E'...')." -msgstr "使用''或者转义字符串语法(E'...')将字符串引起æ¥." - -#: scan.l:1492 -#, c-format -msgid "nonstandard use of \\\\ in a string literal" -msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用\\\\ " - -#: scan.l:1493 -#, c-format -msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." -msgstr "ä¸ºåæ–œçº¿ä½¿ç”¨è½¬ç§»å­—符串语法,例如.,E'\\\\'." - -#: scan.l:1507 -#, c-format -msgid "nonstandard use of escape in a string literal" -msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用转义字符" - -#: scan.l:1508 -#, c-format -msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." -msgstr "对转移字符使用转义字符串语法,例如 E'\\r\\n'." - -#: snowball/dict_snowball.c:177 -#, c-format -msgid "no Snowball stemmer available for language \"%s\" and encoding \"%s\"" -msgstr "对于语言\"%s\" 和编ç \"%s\"æ¥è¯´ï¼Œæ²¡æœ‰æœ‰æ•ˆçš„Snowball stemmer " - -#: snowball/dict_snowball.c:200 tsearch/dict_ispell.c:73 -#: tsearch/dict_simple.c:48 -#, c-format -msgid "multiple StopWords parameters" -msgstr "多个 StopWords傿•°" - -#: snowball/dict_snowball.c:209 -#, c-format -msgid "multiple Language parameters" -msgstr "å¤šè¯­è¨€å‚æ•°" - -#: snowball/dict_snowball.c:216 -#, c-format -msgid "unrecognized Snowball parameter: \"%s\"" -msgstr "未识别Snowball傿•°: \"%s\"" - -#: snowball/dict_snowball.c:224 -#, c-format -msgid "missing Language parameter" -msgstr "ç¼ºå°‘è¯­è¨€å‚æ•°" - -#: storage/buffer/bufmgr.c:544 storage/buffer/bufmgr.c:657 +#: storage/buffer/bufmgr.c:545 storage/buffer/bufmgr.c:658 #, c-format msgid "cannot access temporary tables of other sessions" msgstr "无法访问其它会è¯çš„临时表" -#: storage/buffer/bufmgr.c:807 +#: storage/buffer/bufmgr.c:814 #, c-format msgid "unexpected data beyond EOF in block %u of relation %s" msgstr "关系 \"%2$s\" çš„å— %1$u 中的EOFåŽé¢å‡ºçŽ°æœªæœŸæœ›çš„æ•°æ®" -#: storage/buffer/bufmgr.c:809 +#: storage/buffer/bufmgr.c:816 #, c-format -msgid "" -"This has been seen to occur with buggy kernels; consider updating your " -"system." +msgid "This has been seen to occur with buggy kernels; consider updating your system." msgstr "这是由于内核缺陷所致;请考虑更新您的æ“作系统." -#: storage/buffer/bufmgr.c:907 +#: storage/buffer/bufmgr.c:914 #, c-format msgid "invalid page in block %u of relation %s; zeroing out page" msgstr "关系 \"%2$s\" ä¸­çš„å— %1$u 无效的页;正在对页进行清零æ“作" -#: storage/buffer/bufmgr.c:3951 +#: storage/buffer/bufmgr.c:4056 #, c-format msgid "could not write block %u of %s" msgstr "无法写入%2$sçš„å—%1$u" -#: storage/buffer/bufmgr.c:3953 +#: storage/buffer/bufmgr.c:4058 #, c-format msgid "Multiple failures --- write error might be permanent." msgstr "多次失败 --- 写错误å¯èƒ½æ˜¯æ°¸ä¹…性的" -#: storage/buffer/bufmgr.c:3974 storage/buffer/bufmgr.c:3993 +#: storage/buffer/bufmgr.c:4079 storage/buffer/bufmgr.c:4098 #, c-format msgid "writing block %u of relation %s" msgstr "写入关系%2$sçš„å—%1$u" -#: storage/buffer/bufmgr.c:4317 +#: storage/buffer/bufmgr.c:4401 #, c-format -#| msgid "snapshot_id" msgid "snapshot too old" msgstr "快照太旧" -#: storage/buffer/localbuf.c:198 +#: storage/buffer/localbuf.c:199 #, c-format msgid "no empty local buffer available" msgstr "没有å¯ç”¨çš„æœ¬åœ°ç¼“冲区" -#: storage/file/fd.c:436 storage/file/fd.c:508 storage/file/fd.c:544 +#: storage/buffer/localbuf.c:427 +#, c-format +msgid "cannot access temporary tables during a parallel operation" +msgstr "ä¸èƒ½åœ¨å¹¶è¡Œæ“作期间访问临时表" + +#: storage/file/buffile.c:319 +#, c-format +msgid "could not open temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "无法打开BufFile \"%2$s\"中的临时文件\"%1$s\" :%3$m" + +#: storage/file/buffile.c:796 +#, c-format +msgid "could not determine size of temporary file \"%s\" from BufFile \"%s\": %m" +msgstr "无法从BufFile \"%2$s\"确定临时文件\"%1$s\"的大å°ï¼š%3$m" + +#: storage/file/fd.c:458 storage/file/fd.c:530 storage/file/fd.c:566 #, c-format -#| msgid "could not redirect stdout: %m" msgid "could not flush dirty data: %m" msgstr "æ— æ³•åˆ·å‡ºè„æ•°æ®ï¼š%m" -#: storage/file/fd.c:466 +#: storage/file/fd.c:488 #, c-format -#| msgid "could not determine input data type" msgid "could not determine dirty data size: %m" msgstr "æ— æ³•ç¡®å®šè„æ•°æ®çš„尺寸:%m" -#: storage/file/fd.c:518 +#: storage/file/fd.c:540 #, c-format -#| msgid "could not uncompress data: %s\n" msgid "could not munmap() while flushing data: %m" msgstr "åœ¨åˆ·å†™æ•°æ®æ—¶ä¸èƒ½ munmap():%m" -#: storage/file/fd.c:682 +#: storage/file/fd.c:748 #, c-format msgid "could not link file \"%s\" to \"%s\": %m" msgstr "无法把文件 \"%s\" 链接到 \"%s\": %m" # fe-misc.c:389 fe-misc.c:423 fe-misc.c:838 -#: storage/file/fd.c:776 +#: storage/file/fd.c:842 #, c-format msgid "getrlimit failed: %m" msgstr "函数getrlimit执行失败: %m" -#: storage/file/fd.c:866 +#: storage/file/fd.c:932 #, c-format msgid "insufficient file descriptors available to start server process" msgstr "å¯åЍæœåŠ¡å™¨è¿›ç¨‹çš„æœ‰æ•ˆæ–‡ä»¶æè¿°ç¬¦ä¸è¶³" -#: storage/file/fd.c:867 +#: storage/file/fd.c:933 #, c-format msgid "System allows %d, we need at least %d." msgstr "系统å…许 %d, æˆ‘ä»¬è‡³å°‘éœ€è¦ %d." -#: storage/file/fd.c:908 storage/file/fd.c:2001 storage/file/fd.c:2094 -#: storage/file/fd.c:2242 +#: storage/file/fd.c:984 storage/file/fd.c:2246 storage/file/fd.c:2356 +#: storage/file/fd.c:2507 #, c-format msgid "out of file descriptors: %m; release and retry" msgstr "超出文件æè¿°ç¬¦: %m; 释放å†é‡è¯•" -#: storage/file/fd.c:1482 +#: storage/file/fd.c:1284 #, c-format msgid "temporary file: path \"%s\", size %lu" msgstr "临时文件: 路径 \"%s\", 大å°%lu" -#: storage/file/fd.c:1656 +#: storage/file/fd.c:1415 +#, c-format +msgid "cannot create temporary directory \"%s\": %m" +msgstr "无法创建临时目录 \"%s\": %m" + +#: storage/file/fd.c:1422 +#, c-format +msgid "cannot create temporary subdirectory \"%s\": %m" +msgstr "无法创建临时å­ç›®å½•\"%s\": %m" + +#: storage/file/fd.c:1615 +#, c-format +msgid "could not create temporary file \"%s\": %m" +msgstr "无法创建临时文件\"%s\": %m" + +# command.c:1148 +#: storage/file/fd.c:1650 +#, c-format +msgid "could not open temporary file \"%s\": %m" +msgstr "无法打开临时文件 \"%s\": %m" + +# command.c:1148 +#: storage/file/fd.c:1691 +#, c-format +msgid "cannot unlink temporary file \"%s\": %m" +msgstr "æ— æ³•å–æ¶ˆé“¾æŽ¥ä¸´æ—¶æ–‡ä»¶ \"%s\": %m" + +#: storage/file/fd.c:1955 #, c-format msgid "temporary file size exceeds temp_file_limit (%dkB)" msgstr "临时文件大å°è¶…过最大å…许值temp_file_limit(%dkB)" -#: storage/file/fd.c:1977 storage/file/fd.c:2027 +#: storage/file/fd.c:2222 storage/file/fd.c:2281 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open file \"%s\"" msgstr "试图打开文件 \"%2$s\"超出了最大æè¿°ç¬¦èŒƒå›´å€¼ (%1$d)" -#: storage/file/fd.c:2067 +#: storage/file/fd.c:2326 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to execute command \"%s\"" msgstr "试图执行命令 \"%2$s\"时,超出了最大æè¿°ç¬¦èŒƒå›´å€¼ (%1$d)" -#: storage/file/fd.c:2218 +#: storage/file/fd.c:2483 #, c-format msgid "exceeded maxAllocatedDescs (%d) while trying to open directory \"%s\"" msgstr "试图打开目录 \"%2$s\"时,超出了最大æè¿°ç¬¦èŒƒå›´å€¼ (%1$d)" -#: storage/file/fd.c:2304 +#: storage/file/fd.c:2574 #, c-format msgid "could not read directory \"%s\": %m" msgstr "无法读å–目录 \"%s\": %m" -#: storage/ipc/dsm.c:363 +# command.c:1148 +#: storage/file/fd.c:3006 #, c-format -msgid "dynamic shared memory control segment is corrupt" -msgstr "动æ€å…±äº«å†…存控制段被æ¯å" +msgid "unexpected file found in temporary-files directory: \"%s\"" +msgstr "在临时文件目录中å‘现æ„外文件: \"%s\"" -#: storage/ipc/dsm.c:410 +#: storage/file/fd.c:3331 #, c-format -msgid "dynamic shared memory is disabled" -msgstr "动æ€å…±äº«å†…存被ç¦ç”¨" +msgid "could not rmdir directory \"%s\": %m" +msgstr "无法删除目录\"%s\": %m" -#: storage/ipc/dsm.c:411 +#: storage/file/sharedfileset.c:95 #, c-format -msgid "Set dynamic_shared_memory_type to a value other than \"none\"." -msgstr "设置 dynamic_shared_memory_type çš„å€¼ä¸ºéž \"none\"." +msgid "could not attach to a SharedFileSet that is already destroyed" +msgstr "无法附加到已被破åçš„SharedFileSet" -#: storage/ipc/dsm.c:431 +#: storage/ipc/dsm.c:343 +#, c-format +msgid "dynamic shared memory control segment is corrupt" +msgstr "动æ€å…±äº«å†…存控制段被æ¯å" + +#: storage/ipc/dsm.c:404 #, c-format msgid "dynamic shared memory control segment is not valid" msgstr "动æ€å…±äº«å†…存控制段无效" -#: storage/ipc/dsm.c:516 +#: storage/ipc/dsm.c:500 #, c-format msgid "too many dynamic shared memory segments" msgstr "太多动æ€å…±äº«å†…存段" -#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:361 -#: storage/ipc/dsm_impl.c:533 storage/ipc/dsm_impl.c:648 -#: storage/ipc/dsm_impl.c:811 storage/ipc/dsm_impl.c:953 +#: storage/ipc/dsm_impl.c:230 storage/ipc/dsm_impl.c:517 +#: storage/ipc/dsm_impl.c:621 storage/ipc/dsm_impl.c:792 #, c-format msgid "could not unmap shared memory segment \"%s\": %m" msgstr "无法解除映射共享内存段 \"%s\": %m" -#: storage/ipc/dsm_impl.c:271 storage/ipc/dsm_impl.c:543 -#: storage/ipc/dsm_impl.c:658 storage/ipc/dsm_impl.c:821 +#: storage/ipc/dsm_impl.c:240 storage/ipc/dsm_impl.c:527 +#: storage/ipc/dsm_impl.c:631 storage/ipc/dsm_impl.c:802 #, c-format msgid "could not remove shared memory segment \"%s\": %m" msgstr "无法删除共享内存段 \"%s\": %m" -#: storage/ipc/dsm_impl.c:292 storage/ipc/dsm_impl.c:721 -#: storage/ipc/dsm_impl.c:835 +#: storage/ipc/dsm_impl.c:261 storage/ipc/dsm_impl.c:702 +#: storage/ipc/dsm_impl.c:816 #, c-format msgid "could not open shared memory segment \"%s\": %m" msgstr "无法打开共享内存段 \"%s\": %m" -#: storage/ipc/dsm_impl.c:316 storage/ipc/dsm_impl.c:559 -#: storage/ipc/dsm_impl.c:766 storage/ipc/dsm_impl.c:859 +#: storage/ipc/dsm_impl.c:285 storage/ipc/dsm_impl.c:543 +#: storage/ipc/dsm_impl.c:747 storage/ipc/dsm_impl.c:840 #, c-format msgid "could not stat shared memory segment \"%s\": %m" msgstr "无法统计共享内存段 \"%s\": %m" -#: storage/ipc/dsm_impl.c:335 storage/ipc/dsm_impl.c:878 -#: storage/ipc/dsm_impl.c:926 +#: storage/ipc/dsm_impl.c:311 storage/ipc/dsm_impl.c:891 #, c-format msgid "could not resize shared memory segment \"%s\" to %zu bytes: %m" msgstr "æ— æ³•é‡æ–°è®¾ç½®å…±äº«å†…存段\"%s\"的大å°ä¸º%zu字节: %m" -#: storage/ipc/dsm_impl.c:385 storage/ipc/dsm_impl.c:580 -#: storage/ipc/dsm_impl.c:742 storage/ipc/dsm_impl.c:977 +#: storage/ipc/dsm_impl.c:332 storage/ipc/dsm_impl.c:564 +#: storage/ipc/dsm_impl.c:723 storage/ipc/dsm_impl.c:913 #, c-format msgid "could not map shared memory segment \"%s\": %m" msgstr "无法映射共享内存段 \"%s\": %m" -#: storage/ipc/dsm_impl.c:515 +#: storage/ipc/dsm_impl.c:499 #, c-format msgid "could not get shared memory segment: %m" msgstr "无法得到共享内存段: %m" -#: storage/ipc/dsm_impl.c:694 +#: storage/ipc/dsm_impl.c:687 #, c-format msgid "could not create shared memory segment \"%s\": %m" msgstr "无法创建共享内存段\"%s\": %m" -#: storage/ipc/dsm_impl.c:1018 +#: storage/ipc/dsm_impl.c:924 +#, fuzzy, c-format +#| msgid "could not open shared memory segment \"%s\": %m" +msgid "could not close shared memory segment \"%s\": %m" +msgstr "无法打开共享内存段 \"%s\": %m" + +#: storage/ipc/dsm_impl.c:963 storage/ipc/dsm_impl.c:1011 #, c-format msgid "could not duplicate handle for \"%s\": %m" msgstr "无法å¤åˆ¶å¥æŸ„ \"%s\": %m" -#: storage/ipc/latch.c:769 -#, c-format -#| msgid "poll() failed: %m" -msgid "epoll_ctl() failed: %m" -msgstr "epoll_ctl() 失败:%m" - -#: storage/ipc/latch.c:993 -#, c-format +#. translator: %s is a syscall name, such as "poll()" +#: storage/ipc/latch.c:860 storage/ipc/latch.c:1093 storage/ipc/latch.c:1219 +#, fuzzy, c-format #| msgid "poll() failed: %m" -msgid "epoll_wait() failed: %m" -msgstr "epoll_wait() 失败:%m" - -#: storage/ipc/latch.c:1113 -#, c-format -msgid "poll() failed: %m" +msgid "%s failed: %m" msgstr "poll()失败: %m" -#: storage/ipc/shm_toc.c:108 storage/ipc/shm_toc.c:189 storage/ipc/shmem.c:210 -#: storage/lmgr/lock.c:883 storage/lmgr/lock.c:917 storage/lmgr/lock.c:2682 -#: storage/lmgr/lock.c:4007 storage/lmgr/lock.c:4072 storage/lmgr/lock.c:4364 -#: storage/lmgr/predicate.c:2329 storage/lmgr/predicate.c:2344 -#: storage/lmgr/predicate.c:3736 storage/lmgr/predicate.c:4879 -#: storage/lmgr/proc.c:203 utils/hash/dynahash.c:1045 +#: storage/ipc/shm_toc.c:118 storage/ipc/shm_toc.c:200 storage/lmgr/lock.c:929 +#: storage/lmgr/lock.c:967 storage/lmgr/lock.c:2754 storage/lmgr/lock.c:4084 +#: storage/lmgr/lock.c:4149 storage/lmgr/lock.c:4441 +#: storage/lmgr/predicate.c:2404 storage/lmgr/predicate.c:2419 +#: storage/lmgr/predicate.c:3918 storage/lmgr/predicate.c:5075 +#: utils/hash/dynahash.c:1065 #, c-format msgid "out of shared memory" msgstr "共享内存用尽" -#: storage/ipc/shmem.c:366 storage/ipc/shmem.c:417 +#: storage/ipc/shmem.c:165 storage/ipc/shmem.c:246 #, c-format -msgid "" -"not enough shared memory for data structure \"%s\" (%zu bytes requested)" -msgstr "没有足够的共享内存æä¾›ç»™æ•°æ®ç»“æž„\"%s\" (需è¦%zu个字节)" +msgid "out of shared memory (%zu bytes requested)" +msgstr "共享内存ä¸è¶³ (需è¦%zu个字节)" -#: storage/ipc/shmem.c:385 +#: storage/ipc/shmem.c:421 #, c-format msgid "could not create ShmemIndex entry for data structure \"%s\"" msgstr "无法为数æ®ç»“æž„\"%s\"创建ShmemIndex项" -#: storage/ipc/shmem.c:400 +#: storage/ipc/shmem.c:436 #, c-format -msgid "" -"ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, " -"actual %zu" -msgstr "" -"对于数æ®ç»“æž„\"%s\"æ¥è¯´ShmemIndex项的大å°é”™è¯¯ï¼šæ‰€æœŸæœ›çš„值是%zu,实的值是%zu" +msgid "ShmemIndex entry size is wrong for data structure \"%s\": expected %zu, actual %zu" +msgstr "对于数æ®ç»“æž„\"%s\"æ¥è¯´ShmemIndex项的大å°é”™è¯¯ï¼šæ‰€æœŸæœ›çš„值是%zu,实的值是%zu" -#: storage/ipc/shmem.c:445 storage/ipc/shmem.c:464 +#: storage/ipc/shmem.c:453 +#, c-format +msgid "not enough shared memory for data structure \"%s\" (%zu bytes requested)" +msgstr "没有足够的共享内存æä¾›ç»™æ•°æ®ç»“æž„\"%s\" (需è¦%zu个字节)" + +#: storage/ipc/shmem.c:484 storage/ipc/shmem.c:503 #, c-format msgid "requested shared memory size overflows size_t" msgstr "æ‰€è¦æ±‚的共享内存大å°è¶…过size_t" -#: storage/ipc/standby.c:527 tcop/postgres.c:2963 +#: storage/ipc/signalfuncs.c:67 +#, c-format +msgid "PID %d is not a PostgreSQL server process" +msgstr "PID %d 䏿˜¯ PostgreSQL æœåŠ¡å™¨è¿›ç¨‹" + +#: storage/ipc/signalfuncs.c:98 storage/lmgr/proc.c:1364 +#, c-format +msgid "could not send signal to process %d: %m" +msgstr "无法å‘é€ä¿¡å·åˆ°è¿›ç¨‹ %d: %m" + +#: storage/ipc/signalfuncs.c:118 +#, c-format +msgid "must be a superuser to cancel superuser query" +msgstr "åªæœ‰è¶…级用户æ‰èƒ½å–消超级用户的查询" + +#: storage/ipc/signalfuncs.c:123 +#, c-format +msgid "must be a member of the role whose query is being canceled or member of pg_signal_backend" +msgstr "å¿…é¡»æ˜¯å…¶æŸ¥è¯¢è¢«å–æ¶ˆçš„角色的一个æˆå‘˜æˆ–者 pg_signal_backend 的一个æˆå‘˜" + +#: storage/ipc/signalfuncs.c:142 +#, c-format +msgid "must be a superuser to terminate superuser process" +msgstr "åªæœ‰è¶…级用户中止超级用户的进程" + +#: storage/ipc/signalfuncs.c:147 +#, c-format +msgid "must be a member of the role whose process is being terminated or member of pg_signal_backend" +msgstr "必须是其进程被终止的角色的一个æˆå‘˜æˆ–者 pg_signal_backend 的一个æˆå‘˜" + +#: storage/ipc/signalfuncs.c:183 +#, c-format +msgid "must be superuser to rotate log files with adminpack 1.0" +msgstr "必须是超级用户æ‰èƒ½ä½¿ç”¨adminpack 1.0旋转日志文件" + +#. translator: %s is a SQL function name +#: storage/ipc/signalfuncs.c:185 utils/adt/genfile.c:223 +#, fuzzy, c-format +#| msgid "Consider using pg_file_read(), which is part of core, instead." +msgid "Consider using %s, which is part of core, instead." +msgstr "考虑使用pg_file_read(),它是核心的一部分." + +#: storage/ipc/signalfuncs.c:191 storage/ipc/signalfuncs.c:211 +#, c-format +msgid "rotation not possible because log collection not active" +msgstr "æ—¥å¿—åˆ‡æ¢æ— æ³•进行,因为没有激活日志收集功能" + +#: storage/ipc/standby.c:558 tcop/postgres.c:3123 #, c-format msgid "canceling statement due to conflict with recovery" msgstr "由于与æ¢å¤æ“作冲çªï¼Œæ­£åœ¨å–消语å¥å‘½ä»¤" -#: storage/ipc/standby.c:528 tcop/postgres.c:2265 +#: storage/ipc/standby.c:559 tcop/postgres.c:2397 #, c-format msgid "User transaction caused buffer deadlock with recovery." msgstr "用户事务造æˆäº†æ¢å¤æ“作期间缓冲区的死é”" -#: storage/large_object/inv_api.c:203 +#: storage/large_object/inv_api.c:189 #, c-format msgid "pg_largeobject entry for OID %u, page %d has invalid data field size %d" msgstr "pg_largeobject çš„ OID为 %u, é¡µå· %d , æ•°æ®åŸŸçš„å¤§å° %d为无效值" -#: storage/large_object/inv_api.c:284 +#: storage/large_object/inv_api.c:270 #, c-format msgid "invalid flags for opening a large object: %d" msgstr "打开大对象的无效标记: %d" -#: storage/large_object/inv_api.c:436 +#: storage/large_object/inv_api.c:460 #, c-format msgid "invalid whence setting: %d" msgstr "无效的根æºè®¾ç½®: %d" -#: storage/large_object/inv_api.c:593 +#: storage/large_object/inv_api.c:632 #, c-format msgid "invalid large object write request size: %d" msgstr "无效的大对象写请求大å°: %d" @@ -17462,441 +19223,392 @@ msgstr "检测到死é”" msgid "See server log for query details." msgstr "详细信æ¯è¯·æŸ¥çœ‹æœåŠ¡å™¨æ—¥å¿—." -#: storage/lmgr/lmgr.c:719 +#: storage/lmgr/lmgr.c:815 #, c-format msgid "while updating tuple (%u,%u) in relation \"%s\"" msgstr "当更新关系\"%3$s\"的元组(%1$u, %2$u)æ—¶" -#: storage/lmgr/lmgr.c:722 +#: storage/lmgr/lmgr.c:818 #, c-format msgid "while deleting tuple (%u,%u) in relation \"%s\"" msgstr "当删除关系\"%3$s\"的元组(%1$u, %2$u)æ—¶" -#: storage/lmgr/lmgr.c:725 +#: storage/lmgr/lmgr.c:821 #, c-format msgid "while locking tuple (%u,%u) in relation \"%s\"" msgstr "当é”定关系\"%3$s\"的元组(%1$u, %2$u)æ—¶" -#: storage/lmgr/lmgr.c:728 +#: storage/lmgr/lmgr.c:824 #, c-format msgid "while locking updated version (%u,%u) of tuple in relation \"%s\"" msgstr "在é”定关系\"%3$s\"中的元组的更新版本 (%1$u,%2$u) æ—¶" -#: storage/lmgr/lmgr.c:731 +#: storage/lmgr/lmgr.c:827 #, c-format msgid "while inserting index tuple (%u,%u) in relation \"%s\"" msgstr "在往关系\"%3$s\"中æ’入索引元组 (%1$u,%2$u) æ—¶" -#: storage/lmgr/lmgr.c:734 +#: storage/lmgr/lmgr.c:830 #, c-format msgid "while checking uniqueness of tuple (%u,%u) in relation \"%s\"" msgstr "在检查关系\"%3$s\"中元组(%1$u, %2$u)的唯一性时" -#: storage/lmgr/lmgr.c:737 +#: storage/lmgr/lmgr.c:833 #, c-format msgid "while rechecking updated tuple (%u,%u) in relation \"%s\"" msgstr "釿–°æ£€æŸ¥å…³ç³» \"%3$s\"中已更新的元组(%1$u, %2$u)æ—¶" -#: storage/lmgr/lmgr.c:740 +#: storage/lmgr/lmgr.c:836 #, c-format msgid "while checking exclusion constraint on tuple (%u,%u) in relation \"%s\"" msgstr "在检查关系\"%3$s\"中的元组(%1$u, %2$u)的排它性ä¾èµ–æ—¶" -#: storage/lmgr/lmgr.c:960 +#: storage/lmgr/lmgr.c:1093 #, c-format msgid "relation %u of database %u" msgstr "æ•°æ®åº“%2$u的关系%1$u" -#: storage/lmgr/lmgr.c:966 +#: storage/lmgr/lmgr.c:1099 #, c-format msgid "extension of relation %u of database %u" msgstr "æ•°æ®åº“%2$u的关系%1$u的扩展" -#: storage/lmgr/lmgr.c:972 +#: storage/lmgr/lmgr.c:1105 #, c-format msgid "page %u of relation %u of database %u" msgstr "æ•°æ®åº“%3$u的关系%2$u的页%1$u" -#: storage/lmgr/lmgr.c:979 +#: storage/lmgr/lmgr.c:1112 #, c-format msgid "tuple (%u,%u) of relation %u of database %u" msgstr "æ•°æ®åº“%4$u的关系%3$u中的元组(%1$u,%2$u)" -#: storage/lmgr/lmgr.c:987 +#: storage/lmgr/lmgr.c:1120 #, c-format msgid "transaction %u" msgstr "事务 %u" # sql_help.h:101 # sql_help.h:413 -#: storage/lmgr/lmgr.c:992 +#: storage/lmgr/lmgr.c:1125 #, c-format msgid "virtual transaction %d/%u" msgstr "虚拟事务 %d/%u" -#: storage/lmgr/lmgr.c:998 +#: storage/lmgr/lmgr.c:1131 #, c-format msgid "speculative token %u of transaction %u" msgstr "事务%2$uçš„æŽ¨æµ‹è®°å·æ˜¯%1$u" -#: storage/lmgr/lmgr.c:1004 +#: storage/lmgr/lmgr.c:1137 #, c-format msgid "object %u of class %u of database %u" msgstr "æ•°æ®åº“%3$u的类%2$u的对象%1$u" -#: storage/lmgr/lmgr.c:1012 +#: storage/lmgr/lmgr.c:1145 #, c-format msgid "user lock [%u,%u,%u]" msgstr "用户é”[%u,%u,%u]" -#: storage/lmgr/lmgr.c:1019 +#: storage/lmgr/lmgr.c:1152 #, c-format msgid "advisory lock [%u,%u,%u,%u]" msgstr "å»ºè®®é” [%u,%u,%u,%u]" -#: storage/lmgr/lmgr.c:1027 +#: storage/lmgr/lmgr.c:1160 #, c-format msgid "unrecognized locktag type %d" msgstr "未知的locktag 类型 %d" -#: storage/lmgr/lock.c:732 +#: storage/lmgr/lock.c:764 #, c-format -msgid "" -"cannot acquire lock mode %s on database objects while recovery is in progress" +msgid "cannot acquire lock mode %s on database objects while recovery is in progress" msgstr "在æ¢å¤æ“作的过程中ä¸èƒ½åœ¨æ•°æ®åº“对象上获å–锿¨¡å¼%s" -#: storage/lmgr/lock.c:734 +#: storage/lmgr/lock.c:766 #, c-format -msgid "" -"Only RowExclusiveLock or less can be acquired on database objects during " -"recovery." +msgid "Only RowExclusiveLock or less can be acquired on database objects during recovery." msgstr "在æ¢å¤æ“ä½œæœŸé—´åªæœ‰åœ¨æ•°æ®å¯¹è±¡ä¸ŠèŽ·å–RowExclusiveLock或者更低级别的é”。" -#: storage/lmgr/lock.c:884 storage/lmgr/lock.c:918 storage/lmgr/lock.c:2683 -#: storage/lmgr/lock.c:4008 storage/lmgr/lock.c:4073 storage/lmgr/lock.c:4365 +#: storage/lmgr/lock.c:930 storage/lmgr/lock.c:968 storage/lmgr/lock.c:2755 +#: storage/lmgr/lock.c:4085 storage/lmgr/lock.c:4150 storage/lmgr/lock.c:4442 #, c-format msgid "You might need to increase max_locks_per_transaction." msgstr "您å¯èƒ½éœ€è¦å¢žåР傿•°max_locks_per_transaction." -#: storage/lmgr/lock.c:3124 storage/lmgr/lock.c:3240 +#: storage/lmgr/lock.c:3201 storage/lmgr/lock.c:3317 #, c-format -msgid "" -"cannot PREPARE while holding both session-level and transaction-level locks " -"on the same object" +msgid "cannot PREPARE while holding both session-level and transaction-level locks on the same object" msgstr "åœ¨ä¸€ä¸ªå¯¹è±¡ä¸ŠåŒæ—¶æ‹¥æœ‰ä¼šè¯çº§å’Œäº‹åŠ¡çº§é”æ—¶ï¼Œæ— æ³•执行PREPARE" -#: storage/lmgr/predicate.c:675 +#: storage/lmgr/predicate.c:703 #, c-format msgid "not enough elements in RWConflictPool to record a read/write conflict" msgstr "RWConflictPool(è¯»å†™å†²çªæ± )没有足够的元素æ¥è®°å½•读/写冲çª" -#: storage/lmgr/predicate.c:676 storage/lmgr/predicate.c:704 +#: storage/lmgr/predicate.c:704 storage/lmgr/predicate.c:732 #, c-format -msgid "" -"You might need to run fewer transactions at a time or increase " -"max_connections." +msgid "You might need to run fewer transactions at a time or increase max_connections." msgstr "您å¯èƒ½éœ€è¦æ¯æ¬¡æ‰§è¡Œæ›´å°‘的事务,è¦ä¹ˆå¢žå¤§max_connections值." -#: storage/lmgr/predicate.c:703 +#: storage/lmgr/predicate.c:731 #, c-format -msgid "" -"not enough elements in RWConflictPool to record a potential read/write " -"conflict" +msgid "not enough elements in RWConflictPool to record a potential read/write conflict" msgstr "RWConflictPool(è¯»å†™å†²çªæ± )没有足够的元素æ¥è®°å½•å¯èƒ½çš„读/写冲çª" -#: storage/lmgr/predicate.c:909 -#, c-format -msgid "memory for serializable conflict tracking is nearly exhausted" -msgstr "串行化冲çªè·Ÿè¸ªæ‰€éœ€è¦çš„内存几乎耗尽" - -#: storage/lmgr/predicate.c:910 -#, c-format -msgid "" -"There might be an idle transaction or a forgotten prepared transaction " -"causing this." -msgstr "å¯èƒ½æ˜¯ç”±äºŽç©ºé—²äº‹åŠ¡æˆ–è€…ä¸€ä¸ªå¿˜äº†å‡†å¤‡çš„äº‹åŠ¡å¯¼è‡´æ­¤é—®é¢˜." - -#: storage/lmgr/predicate.c:1190 storage/lmgr/predicate.c:1261 -#, c-format -msgid "" -"not enough shared memory for elements of data structure \"%s\" (%zu bytes " -"requested)" -msgstr "没有足够的共享内存供数æ®ç»“æž„\"%s\"使用 (它需è¦%zu个字节)" - -#: storage/lmgr/predicate.c:1549 +#: storage/lmgr/predicate.c:1538 #, c-format msgid "deferrable snapshot was unsafe; trying a new one" msgstr "å¯å»¶ç¼“的快照ä¸å®‰å…¨ï¼›è¯·å°è¯•使用新的快照" -#: storage/lmgr/predicate.c:1588 +#: storage/lmgr/predicate.c:1627 #, c-format msgid "\"default_transaction_isolation\" is set to \"serializable\"." msgstr "\"default_transaction_isolation\"被设置为\"å¯ä¸²è¡ŒåŒ–\"." -#: storage/lmgr/predicate.c:1589 +#: storage/lmgr/predicate.c:1628 #, c-format -msgid "" -"You can use \"SET default_transaction_isolation = 'repeatable read'\" to " -"change the default." -msgstr "" -"您å¯ä»¥ä½¿ç”¨ \"SET default_transaction_isolation = 'repeatable read'\"æ¥æ”¹å˜ç¼º" -"çœå€¼." +msgid "You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default." +msgstr "您å¯ä»¥ä½¿ç”¨ \"SET default_transaction_isolation = 'repeatable read'\"æ¥æ”¹å˜ç¼ºçœå€¼." -#: storage/lmgr/predicate.c:1628 +#: storage/lmgr/predicate.c:1679 #, c-format msgid "a snapshot-importing transaction must not be READ ONLY DEFERRABLE" msgstr "快照导入事务ä¸èƒ½æ˜¯å¯å»¶ç¼“çš„åªè¯»äº‹åŠ¡" -#: storage/lmgr/predicate.c:1706 utils/time/snapmgr.c:535 -#: utils/time/snapmgr.c:541 +#: storage/lmgr/predicate.c:1758 utils/time/snapmgr.c:623 +#: utils/time/snapmgr.c:629 #, c-format msgid "could not import the requested snapshot" msgstr "无法导入请求的快照" -#: storage/lmgr/predicate.c:1707 utils/time/snapmgr.c:542 +#: storage/lmgr/predicate.c:1759 utils/time/snapmgr.c:630 #, c-format -msgid "The source transaction %u is not running anymore." -msgstr "æºäº‹åŠ¡ %u ä¸å†è¿è¡Œ." +msgid "The source process with PID %d is not running anymore." +msgstr "PID为%dçš„æºè¿›ç¨‹ä¸å†è¿è¡Œ." -#: storage/lmgr/predicate.c:2330 storage/lmgr/predicate.c:2345 -#: storage/lmgr/predicate.c:3737 +#: storage/lmgr/predicate.c:2405 storage/lmgr/predicate.c:2420 +#: storage/lmgr/predicate.c:3919 #, c-format msgid "You might need to increase max_pred_locks_per_transaction." msgstr "您å¯èƒ½éœ€è¦å¢žå¤§å‚æ•°max_pred_locks_per_transaction的值." -#: storage/lmgr/predicate.c:3891 storage/lmgr/predicate.c:3980 -#: storage/lmgr/predicate.c:3988 storage/lmgr/predicate.c:4027 -#: storage/lmgr/predicate.c:4266 storage/lmgr/predicate.c:4603 -#: storage/lmgr/predicate.c:4615 storage/lmgr/predicate.c:4657 -#: storage/lmgr/predicate.c:4695 +#: storage/lmgr/predicate.c:4075 storage/lmgr/predicate.c:4164 +#: storage/lmgr/predicate.c:4172 storage/lmgr/predicate.c:4211 +#: storage/lmgr/predicate.c:4454 storage/lmgr/predicate.c:4791 +#: storage/lmgr/predicate.c:4803 storage/lmgr/predicate.c:4846 +#: storage/lmgr/predicate.c:4884 #, c-format -msgid "" -"could not serialize access due to read/write dependencies among transactions" +msgid "could not serialize access due to read/write dependencies among transactions" msgstr "由于多个事务间的读/写ä¾èµ–而无法串行访问" -#: storage/lmgr/predicate.c:3893 storage/lmgr/predicate.c:3982 -#: storage/lmgr/predicate.c:3990 storage/lmgr/predicate.c:4029 -#: storage/lmgr/predicate.c:4268 storage/lmgr/predicate.c:4605 -#: storage/lmgr/predicate.c:4617 storage/lmgr/predicate.c:4659 -#: storage/lmgr/predicate.c:4697 +#: storage/lmgr/predicate.c:4077 storage/lmgr/predicate.c:4166 +#: storage/lmgr/predicate.c:4174 storage/lmgr/predicate.c:4213 +#: storage/lmgr/predicate.c:4456 storage/lmgr/predicate.c:4793 +#: storage/lmgr/predicate.c:4805 storage/lmgr/predicate.c:4848 +#: storage/lmgr/predicate.c:4886 #, c-format msgid "The transaction might succeed if retried." msgstr "该事务如果é‡è¯•,有å¯èƒ½æˆåŠŸ." -#: storage/lmgr/proc.c:1263 +#: storage/lmgr/proc.c:359 +#, c-format +msgid "number of requested standby connections exceeds max_wal_senders (currently %d)" +msgstr "æ‰€è¦æ±‚的备用æœåŠ¡å™¨è¿žæŽ¥æ•°è¶…è¿‡äº†å‚æ•°max_wal_senders的值(当å‰è®¾ç½®ä¸º%d)" + +#: storage/lmgr/proc.c:1335 #, c-format msgid "Process %d waits for %s on %s." msgstr "进程%1$d等待在%3$s上的%2$s" -#: storage/lmgr/proc.c:1274 +#: storage/lmgr/proc.c:1346 #, c-format msgid "sending cancel to blocking autovacuum PID %d" msgstr "å‘阻塞的自动清ç†(autovacuum)进程%då‘é€å–消(cancel)请求" -#: storage/lmgr/proc.c:1292 utils/adt/misc.c:270 -#, c-format -msgid "could not send signal to process %d: %m" -msgstr "无法å‘é€ä¿¡å·åˆ°è¿›ç¨‹ %d: %m" - -#: storage/lmgr/proc.c:1394 +#: storage/lmgr/proc.c:1466 #, c-format -msgid "" -"process %d avoided deadlock for %s on %s by rearranging queue order after " -"%ld.%03d ms" -msgstr "" -"进程%1$d在%4$ld.%5$03d msé€šè¿‡é‡æ–°å®‰æŽ’åºåˆ—é¡ºåºæ¥é¿å…在%3$s上的%2$s的死é”" +msgid "process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms" +msgstr "进程%1$d在%4$ld.%5$03d msé€šè¿‡é‡æ–°å®‰æŽ’åºåˆ—é¡ºåºæ¥é¿å…在%3$s上的%2$s的死é”" -#: storage/lmgr/proc.c:1409 +#: storage/lmgr/proc.c:1481 #, c-format -msgid "" -"process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" +msgid "process %d detected deadlock while waiting for %s on %s after %ld.%03d ms" msgstr "进程%1$d在%4$ld.%5$03d ms等待在%3$s上的%2$såŒæ—¶ç›‘测到死é”" -#: storage/lmgr/proc.c:1418 +#: storage/lmgr/proc.c:1490 #, c-format msgid "process %d still waiting for %s on %s after %ld.%03d ms" msgstr "进程%1$d在%4$ld.%5$03d msä»ç„¶ç­‰å¾…在%3$s上的%2$s" -#: storage/lmgr/proc.c:1425 +#: storage/lmgr/proc.c:1497 #, c-format msgid "process %d acquired %s on %s after %ld.%03d ms" msgstr "进程%1$d在%4$ld.%5$03d msåŽèŽ·å–在%3$s上的%2$s" -#: storage/lmgr/proc.c:1441 +#: storage/lmgr/proc.c:1513 #, c-format msgid "process %d failed to acquire %s on %s after %ld.%03d ms" msgstr "进程%1$d在%4$ld.%5$03d msåŽèŽ·å–在%3$s上的%2$s失败" -#: storage/page/bufpage.c:144 +#: storage/page/bufpage.c:152 #, c-format msgid "page verification failed, calculated checksum %u but expected %u" msgstr "页校验失败,计算出的校验和为%u,但期望值是%u" -#: storage/page/bufpage.c:200 storage/page/bufpage.c:490 -#: storage/page/bufpage.c:705 storage/page/bufpage.c:836 -#: storage/page/bufpage.c:936 +#: storage/page/bufpage.c:216 storage/page/bufpage.c:510 +#: storage/page/bufpage.c:747 storage/page/bufpage.c:880 +#: storage/page/bufpage.c:976 storage/page/bufpage.c:1086 #, c-format msgid "corrupted page pointers: lower = %u, upper = %u, special = %u" msgstr "å·²æŸå的页指针:低ä½=%u, 高ä½=%u, 特定=%u" -#: storage/page/bufpage.c:534 -#, c-format -msgid "corrupted item pointer: %u" +#: storage/page/bufpage.c:532 +#, fuzzy, c-format +#| msgid "corrupted item pointer: %u" +msgid "corrupted line pointer: %u" msgstr "å·²æŸåçš„æˆå‘˜æŒ‡é’ˆ: %u" -#: storage/page/bufpage.c:545 storage/page/bufpage.c:887 -#: storage/page/bufpage.c:1042 +#: storage/page/bufpage.c:559 storage/page/bufpage.c:931 #, c-format msgid "corrupted item lengths: total %u, available space %u" msgstr "å·²æŸåçš„æˆå‘˜é•¿åº¦: 总长度%u,坿œ‰æ•ˆä½¿ç”¨çš„空间%u" -#: storage/page/bufpage.c:724 storage/page/bufpage.c:860 -#, c-format -msgid "corrupted item pointer: offset = %u, size = %u" +#: storage/page/bufpage.c:766 storage/page/bufpage.c:904 +#: storage/page/bufpage.c:992 storage/page/bufpage.c:1102 +#, fuzzy, c-format +#| msgid "corrupted item pointer: offset = %u, size = %u" +msgid "corrupted line pointer: offset = %u, size = %u" msgstr "å·²æŸåçš„æˆå‘˜æŒ‡é’ˆ: åç§»é‡ = %u, å¤§å° = %u" -#: storage/page/bufpage.c:965 -#, c-format -msgid "corrupted item pointer: offset = %u, length = %u" -msgstr "æŸå的项指针:åç§»é‡ = %u,长度 = %u" - -#: storage/smgr/md.c:442 storage/smgr/md.c:962 +#: storage/smgr/md.c:320 storage/smgr/md.c:815 #, c-format msgid "could not truncate file \"%s\": %m" msgstr "无法截断文件 \"%s\": %m" -#: storage/smgr/md.c:509 +#: storage/smgr/md.c:394 #, c-format msgid "cannot extend file \"%s\" beyond %u blocks" msgstr "扩展文件\"%s\"的大å°ä¸èƒ½è¶…过%u个数æ®å—" -#: storage/smgr/md.c:531 storage/smgr/md.c:743 storage/smgr/md.c:818 -#, c-format -msgid "could not seek to block %u in file \"%s\": %m" -msgstr "无法在文件\"%2$s\"中查找到数æ®å—%1$u: %3$m" - -#: storage/smgr/md.c:539 +#: storage/smgr/md.c:409 #, c-format msgid "could not extend file \"%s\": %m" msgstr "无法扩展文件 \"%s\": %m" -#: storage/smgr/md.c:541 storage/smgr/md.c:548 storage/smgr/md.c:845 +#: storage/smgr/md.c:411 storage/smgr/md.c:418 storage/smgr/md.c:698 #, c-format msgid "Check free disk space." msgstr "检查空闲ç£ç›˜æŽ§ä»¶." -#: storage/smgr/md.c:545 +#: storage/smgr/md.c:415 #, c-format msgid "could not extend file \"%s\": wrote only %d of %d bytes at block %u" msgstr "无法扩展文件\"%1$s\": åªèƒ½åœ¨å—%4$u上写%3$d字节的%2$d" -#: storage/smgr/md.c:761 +#: storage/smgr/md.c:619 #, c-format msgid "could not read block %u in file \"%s\": %m" msgstr "无法在文件\"%2$s\"中读å–å—%1$u: %3$m" -#: storage/smgr/md.c:777 +#: storage/smgr/md.c:635 #, c-format msgid "could not read block %u in file \"%s\": read only %d of %d bytes" msgstr "æ— æ³•è¯»å–æ–‡ä»¶\"%2$s\"çš„å—%1$u:åªè¯»å–了%4$d字节的%3$d" -#: storage/smgr/md.c:836 +#: storage/smgr/md.c:689 #, c-format msgid "could not write block %u in file \"%s\": %m" msgstr "无法在文件 \"%2$s\"中写入å—%1$u: %3$m" -#: storage/smgr/md.c:841 +#: storage/smgr/md.c:694 #, c-format msgid "could not write block %u in file \"%s\": wrote only %d of %d bytes" msgstr "无法对文件\"%2$s\"写æ“作数æ®å—%1$u: åªå†™äº†%4$d字节的%3$d" -#: storage/smgr/md.c:938 +#: storage/smgr/md.c:786 #, c-format msgid "could not truncate file \"%s\" to %u blocks: it's only %u blocks now" msgstr "无法将文件\"%s\"截断到%u个数æ®å—;å®ƒçŽ°åœ¨åªæœ‰%u个数æ®å—" -#: storage/smgr/md.c:987 +#: storage/smgr/md.c:841 #, c-format msgid "could not truncate file \"%s\" to %u blocks: %m" msgstr "无法将文件\"%s\"截断到%u个数æ®å—: %m" -#: storage/smgr/md.c:1267 -#, c-format -msgid "could not fsync file \"%s\" but retrying: %m" -msgstr "无法对文件\"%s\"进行fsyncæ“ä½œä½†æ˜¯æ­£åœ¨é‡æ–°å°è¯•: %m" - -#: storage/smgr/md.c:1430 +#: storage/smgr/md.c:913 #, c-format msgid "could not forward fsync request because request queue is full" msgstr "请求队列已满,无法转å‘fsync请求" -#: storage/smgr/md.c:1825 +#: storage/smgr/md.c:1210 +#, c-format +msgid "could not open file \"%s\" (target block %u): previous segment is only %u blocks" +msgstr "无法打开文件\"%s\"(目标å—%uï¼‰ï¼šä¸Šä¸€æ®µåªæœ‰%u个å—" + +#: storage/smgr/md.c:1224 #, c-format msgid "could not open file \"%s\" (target block %u): %m" msgstr "无法打开文件\"%s\"(目标数æ®å—%u): %m" -#: tcop/fastpath.c:111 tcop/fastpath.c:475 tcop/fastpath.c:605 +#: storage/sync/sync.c:400 #, c-format -msgid "invalid argument size %d in function call message" -msgstr "在函数调用信æ¯ä¸­, 傿•°å¤§å° %d 是无效的" +msgid "could not fsync file \"%s\" but retrying: %m" +msgstr "无法对文件\"%s\"进行fsyncæ“ä½œä½†æ˜¯æ­£åœ¨é‡æ–°å°è¯•: %m" -#: tcop/fastpath.c:291 tcop/postgres.c:992 tcop/postgres.c:1303 -#: tcop/postgres.c:1561 tcop/postgres.c:1966 tcop/postgres.c:2333 -#: tcop/postgres.c:2408 +#: tcop/fastpath.c:109 tcop/fastpath.c:461 tcop/fastpath.c:591 #, c-format -msgid "" -"current transaction is aborted, commands ignored until end of transaction " -"block" -msgstr "当å‰äº‹åŠ¡è¢«ç»ˆæ­¢, 事务å—结æŸä¹‹å‰çš„æŸ¥è¯¢è¢«å¿½ç•¥" +msgid "invalid argument size %d in function call message" +msgstr "在函数调用信æ¯ä¸­, 傿•°å¤§å° %d 是无效的" -#: tcop/fastpath.c:319 +#: tcop/fastpath.c:307 #, c-format msgid "fastpath function call: \"%s\" (OID %u)" msgstr "å¿«æ·è·¯å¾„函数调用: \"%s\" (OID %u)" -#: tcop/fastpath.c:401 tcop/postgres.c:1163 tcop/postgres.c:1428 -#: tcop/postgres.c:1807 tcop/postgres.c:2024 +#: tcop/fastpath.c:389 tcop/postgres.c:1288 tcop/postgres.c:1551 +#: tcop/postgres.c:1918 tcop/postgres.c:2139 #, c-format msgid "duration: %s ms" msgstr "执行时间: %s ms" -#: tcop/fastpath.c:405 +#: tcop/fastpath.c:393 #, c-format msgid "duration: %s ms fastpath function call: \"%s\" (OID %u)" msgstr "æŒç»­æ—¶é—´: %s ms 快速路ç»çš„函数调用: \"%s\" (OID %u)" -#: tcop/fastpath.c:443 tcop/fastpath.c:570 +#: tcop/fastpath.c:429 tcop/fastpath.c:556 #, c-format msgid "function call message contains %d arguments but function requires %d" msgstr "函数调用信æ¯åŒ…å« %d ä¸ªå‚æ•°, ä½†å‡½æ•°éœ€è¦ %d 个" -#: tcop/fastpath.c:451 +#: tcop/fastpath.c:437 #, c-format msgid "function call message contains %d argument formats but %d arguments" msgstr "函数调用信æ¯ä¸ºåŒ…å« %d ä¸ªå‚æ•°çš„æ ¼å¼, 但给定了 %d ä¸ªå‚æ•°" -#: tcop/fastpath.c:538 tcop/fastpath.c:621 +#: tcop/fastpath.c:524 tcop/fastpath.c:607 #, c-format msgid "incorrect binary data format in function argument %d" msgstr "å‡½æ•°å‚æ•° %d ä¸ºä¸æ­£ç¡®çš„äºŒè¿›åˆ¶æ•°æ®æ ¼å¼" -#: tcop/postgres.c:352 tcop/postgres.c:388 tcop/postgres.c:415 +#: tcop/postgres.c:359 tcop/postgres.c:395 tcop/postgres.c:422 #, c-format msgid "unexpected EOF on client connection" msgstr "åœ¨å®¢æˆ·ç«¯è”æŽ¥ä¸Šçš„æ„外 EOF" -#: tcop/postgres.c:438 tcop/postgres.c:450 tcop/postgres.c:461 -#: tcop/postgres.c:473 tcop/postgres.c:4297 +#: tcop/postgres.c:445 tcop/postgres.c:457 tcop/postgres.c:468 +#: tcop/postgres.c:480 tcop/postgres.c:4473 #, c-format msgid "invalid frontend message type %d" msgstr "无效å‰ç«¯ä¿¡æ¯ç±»åž‹ %d" -#: tcop/postgres.c:933 +#: tcop/postgres.c:1043 #, c-format msgid "statement: %s" msgstr "语å¥: %s" -#: tcop/postgres.c:1168 +#: tcop/postgres.c:1293 #, c-format msgid "duration: %s ms statement: %s" msgstr "执行时间: %s ms 语å¥: %s" @@ -17914,516 +19626,518 @@ msgstr "执行时间: %s ms 语å¥: %s" # common.c:170 # copy.c:530 # copy.c:575 -#: tcop/postgres.c:1218 +#: tcop/postgres.c:1343 #, c-format msgid "parse %s: %s" msgstr "è§£æž %s: %s" -#: tcop/postgres.c:1276 +#: tcop/postgres.c:1400 #, c-format msgid "cannot insert multiple commands into a prepared statement" msgstr "无法æ’入多æ¡å‘½ä»¤åˆ°ä¸€ä¸ªå‡†å¤‡å¥½çš„语å¥ä¸­" -#: tcop/postgres.c:1433 +#: tcop/postgres.c:1556 #, c-format msgid "duration: %s ms parse %s: %s" msgstr "执行时间: %s ms è§£æž %s: %s" -#: tcop/postgres.c:1478 +#: tcop/postgres.c:1601 #, c-format msgid "bind %s to %s" msgstr "å°†%s绑定到%s" -#: tcop/postgres.c:1497 tcop/postgres.c:2314 +#: tcop/postgres.c:1620 tcop/postgres.c:2444 #, c-format msgid "unnamed prepared statement does not exist" msgstr "未命å的准备语å¥ä¸å­˜åœ¨" -#: tcop/postgres.c:1539 +#: tcop/postgres.c:1661 #, c-format msgid "bind message has %d parameter formats but %d parameters" msgstr "ç»‘å®šä¿¡æ¯æœ‰%dä¸ªå‚æ•°æ ¼å¼ï¼Œä½†æ˜¯å®žé™…上有%dä¸ªå‚æ•°" -#: tcop/postgres.c:1545 +#: tcop/postgres.c:1667 #, c-format -msgid "" -"bind message supplies %d parameters, but prepared statement \"%s\" requires " -"%d" +msgid "bind message supplies %d parameters, but prepared statement \"%s\" requires %d" msgstr "ç»‘å®šæ¶ˆæ¯æä¾›äº†%dä¸ªå‚æ•°,但是已准备好语å¥\"%s\" è¦æ±‚%dä¸ªå‚æ•°" -#: tcop/postgres.c:1714 +#: tcop/postgres.c:1827 #, c-format msgid "incorrect binary data format in bind parameter %d" msgstr "åœ¨ç»‘å®šå‚æ•°%dä¸­å‡ºçŽ°ä¸æ­£ç¡®çš„二进制数æ®" -#: tcop/postgres.c:1812 +#: tcop/postgres.c:1923 #, c-format msgid "duration: %s ms bind %s%s%s: %s" msgstr "执行时间: %s ms 绑定%s%s%s: %s" -#: tcop/postgres.c:1860 tcop/postgres.c:2394 +#: tcop/postgres.c:1971 tcop/postgres.c:2528 #, c-format msgid "portal \"%s\" does not exist" msgstr "å…¥å£ \"%s\" ä¸å­˜åœ¨" -#: tcop/postgres.c:1945 +#: tcop/postgres.c:2056 #, c-format msgid "%s %s%s%s: %s" msgstr "%s %s%s%s: %s" -#: tcop/postgres.c:1947 tcop/postgres.c:2032 +#: tcop/postgres.c:2058 tcop/postgres.c:2147 msgid "execute fetch from" msgstr "执行FETCHæ“作" -#: tcop/postgres.c:1948 tcop/postgres.c:2033 +#: tcop/postgres.c:2059 tcop/postgres.c:2148 msgid "execute" msgstr "执行" -#: tcop/postgres.c:2029 +#: tcop/postgres.c:2144 #, c-format msgid "duration: %s ms %s %s%s%s: %s" msgstr "执行时间: %s ms %s%s%s%s: %s" -#: tcop/postgres.c:2155 +#: tcop/postgres.c:2285 #, c-format msgid "prepare: %s" msgstr "准备: %s" -#: tcop/postgres.c:2218 +#: tcop/postgres.c:2350 #, c-format msgid "parameters: %s" msgstr "傿•°: %s" -#: tcop/postgres.c:2237 +#: tcop/postgres.c:2369 #, c-format msgid "abort reason: recovery conflict" msgstr "中断原因:与æ¢å¤æ“作相冲çª" -#: tcop/postgres.c:2253 +#: tcop/postgres.c:2385 #, c-format msgid "User was holding shared buffer pin for too long." msgstr "ç”¨æˆ·æ‰€æŒæœ‰å…±äº«ç¼“å­˜é”的时间太长了." -#: tcop/postgres.c:2256 +#: tcop/postgres.c:2388 #, c-format msgid "User was holding a relation lock for too long." msgstr "ç”¨æˆ·å¯¹ä¸€ä¸ªå…³ç³»æ­£åœ¨æŒæœ‰çš„é”的时间太长了." -#: tcop/postgres.c:2259 +#: tcop/postgres.c:2391 #, c-format msgid "User was or might have been using tablespace that must be dropped." msgstr "用户正在使用一个必须被删除的表空间" -#: tcop/postgres.c:2262 +#: tcop/postgres.c:2394 #, c-format msgid "User query might have needed to see row versions that must be removed." msgstr "用户查询å¯èƒ½éœ€è¦çœ‹åˆ°è€Œå¿…须被删除的行版本å·" # large_obj.c:36 -#: tcop/postgres.c:2268 +#: tcop/postgres.c:2400 #, c-format msgid "User was connected to a database that must be dropped." msgstr "用户连接到必须被删除的数æ®åº“" -#: tcop/postgres.c:2597 +#: tcop/postgres.c:2724 #, c-format msgid "terminating connection because of crash of another server process" msgstr "ä¸­æ–­è”æŽ¥, 因为其它æœåŠ¡å™¨è¿›ç¨‹å´©æºƒ" -#: tcop/postgres.c:2598 +#: tcop/postgres.c:2725 #, c-format -msgid "" -"The postmaster has commanded this server process to roll back the current " -"transaction and exit, because another server process exited abnormally and " -"possibly corrupted shared memory." -msgstr "" -"Postmaster 命令此æœåŠ¡å™¨è¿›ç¨‹å›žæ»šå½“å‰äº‹ç‰©å¹¶é€€å‡º, 因为其它æœåŠ¡å™¨è¿›ç¨‹ä¸æ­£å¸¸çš„退出" -"å¯èƒ½æ¯å了共享内存." +msgid "The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory." +msgstr "Postmaster 命令此æœåŠ¡å™¨è¿›ç¨‹å›žæ»šå½“å‰äº‹ç‰©å¹¶é€€å‡º, 因为其它æœåŠ¡å™¨è¿›ç¨‹ä¸æ­£å¸¸çš„退出å¯èƒ½æ¯å了共享内存." -#: tcop/postgres.c:2602 tcop/postgres.c:2906 +#: tcop/postgres.c:2729 tcop/postgres.c:3053 #, c-format -msgid "" -"In a moment you should be able to reconnect to the database and repeat your " -"command." +msgid "In a moment you should be able to reconnect to the database and repeat your command." msgstr "一会儿你将å¯ä»¥é‡è”接数æ®åº“并且é‡å¤ä½ çš„命令." -#: tcop/postgres.c:2688 +#: tcop/postgres.c:2811 #, c-format msgid "floating-point exception" msgstr "浮点异常" -#: tcop/postgres.c:2689 +#: tcop/postgres.c:2812 #, c-format -msgid "" -"An invalid floating-point operation was signaled. This probably means an out-" -"of-range result or an invalid operation, such as division by zero." +msgid "An invalid floating-point operation was signaled. This probably means an out-of-range result or an invalid operation, such as division by zero." msgstr "无效的浮点数æ“作.这表示结果越界或者进行了无效的æ“作,例如除零." -#: tcop/postgres.c:2851 +#: tcop/postgres.c:2983 #, c-format msgid "canceling authentication due to timeout" msgstr "ç”±äºŽè¶…æ—¶ï¼Œæ­£åœ¨å–æ¶ˆè®¤è¯é‰´æƒå‘½ä»¤" -#: tcop/postgres.c:2855 +#: tcop/postgres.c:2987 #, c-format msgid "terminating autovacuum process due to administrator command" msgstr "由于管ç†å‘˜å‘½ä»¤ä¸­æ–­autovacuum进程" -#: tcop/postgres.c:2861 tcop/postgres.c:2871 tcop/postgres.c:2904 +#: tcop/postgres.c:2991 +#, c-format +msgid "terminating logical replication worker due to administrator command" +msgstr "由于管ç†å‘˜å‘½ä»¤è€Œç»ˆæ­¢é€»è¾‘å¤åˆ¶å·¥ä½œçº¿ç¨‹" + +#: tcop/postgres.c:2995 +#, c-format +msgid "logical replication launcher shutting down" +msgstr "逻辑å¤åˆ¶å¯åŠ¨ç¨‹åºæ­£åœ¨å…³é—­" + +#: tcop/postgres.c:3008 tcop/postgres.c:3018 tcop/postgres.c:3051 #, c-format msgid "terminating connection due to conflict with recovery" msgstr "由于与æ¢å¤æ“作相冲çªè€Œä¸­æ–­è¿žæŽ¥" -#: tcop/postgres.c:2877 +#: tcop/postgres.c:3024 #, c-format msgid "terminating connection due to administrator command" msgstr "由于管ç†å‘˜å‘½ä»¤ä¸­æ–­è”接" # common.c:298 -#: tcop/postgres.c:2887 +#: tcop/postgres.c:3034 #, c-format msgid "connection to client lost" msgstr "丢失了到客户端的连接" -#: tcop/postgres.c:2940 +#: tcop/postgres.c:3100 #, c-format msgid "canceling statement due to lock timeout" msgstr "由于é”è¶…æ—¶ï¼Œå–æ¶ˆè¯­å¥æ“作" -#: tcop/postgres.c:2947 +#: tcop/postgres.c:3107 #, c-format msgid "canceling statement due to statement timeout" msgstr "ç”±äºŽè¯­å¥æ‰§è¡Œè¶…æ—¶ï¼Œæ­£åœ¨å–æ¶ˆæŸ¥è¯¢å‘½ä»¤" -#: tcop/postgres.c:2954 +#: tcop/postgres.c:3114 #, c-format msgid "canceling autovacuum task" msgstr "æ­£åœ¨å–æ¶ˆè‡ªåŠ¨æ¸…ç†ä»»åŠ¡" -#: tcop/postgres.c:2977 +#: tcop/postgres.c:3137 #, c-format msgid "canceling statement due to user request" msgstr "ç”±äºŽç”¨æˆ·è¯·æ±‚è€Œæ­£åœ¨å–æ¶ˆæŸ¥è¯¢" -#: tcop/postgres.c:2987 +#: tcop/postgres.c:3147 #, c-format -#| msgid "terminating connection due to administrator command" msgid "terminating connection due to idle-in-transaction timeout" msgstr "由于空载事务超时而终止连接" -#: tcop/postgres.c:3101 +#: tcop/postgres.c:3261 #, c-format msgid "stack depth limit exceeded" msgstr "堆栈深度超过é™åˆ¶" -#: tcop/postgres.c:3102 +#: tcop/postgres.c:3262 #, c-format -msgid "" -"Increase the configuration parameter \"max_stack_depth\" (currently %dkB), " -"after ensuring the platform's stack depth limit is adequate." -msgstr "" -"在确定了平å°çš„堆栈深度é™åˆ¶æ˜¯è¶³å¤Ÿå¤§åŽï¼Œå¢žåŠ é…ç½®å‚æ•° \"max_stack_depth\"的值(当" -"å‰å€¼ä¸º%dkB)." +msgid "Increase the configuration parameter \"max_stack_depth\" (currently %dkB), after ensuring the platform's stack depth limit is adequate." +msgstr "在确定了平å°çš„堆栈深度é™åˆ¶æ˜¯è¶³å¤Ÿå¤§åŽï¼Œå¢žåŠ é…ç½®å‚æ•° \"max_stack_depth\"的值(当å‰å€¼ä¸º%dkB)." -#: tcop/postgres.c:3165 +#: tcop/postgres.c:3325 #, c-format msgid "\"max_stack_depth\" must not exceed %ldkB." msgstr "\"max_stack_depth\"ä¸èƒ½è¶…过%ldkB." -#: tcop/postgres.c:3167 +#: tcop/postgres.c:3327 #, c-format -msgid "" -"Increase the platform's stack depth limit via \"ulimit -s\" or local " -"equivalent." +msgid "Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent." msgstr "通过命令\"ulimit -s\"或本地相åŒçš„命令æ¥å¢žåŠ å¹³å°çš„堆栈深度é™åˆ¶." -#: tcop/postgres.c:3527 +#: tcop/postgres.c:3687 #, c-format msgid "invalid command-line argument for server process: %s" msgstr "æœåŠ¡å™¨è¿›ç¨‹:%sçš„æ— æ•ˆå‘½ä»¤è¡Œå‚æ•°" -#: tcop/postgres.c:3528 tcop/postgres.c:3534 +#: tcop/postgres.c:3688 tcop/postgres.c:3694 #, c-format msgid "Try \"%s --help\" for more information." msgstr "请用 \"%s --help\" èŽ·å–æ›´å¤šçš„ä¿¡æ¯." -#: tcop/postgres.c:3532 +#: tcop/postgres.c:3692 #, c-format msgid "%s: invalid command-line argument: %s" msgstr "%s: æ— æ•ˆçš„å‘½ä»¤è¡Œå‚æ•°:%s" -#: tcop/postgres.c:3594 +#: tcop/postgres.c:3754 #, c-format msgid "%s: no database nor user name specified" msgstr "%s: 没有指定数æ®åº“, 也没有指定用户å" -#: tcop/postgres.c:4205 +#: tcop/postgres.c:4381 #, c-format msgid "invalid CLOSE message subtype %d" msgstr "无效的 CLOSE ä¿¡æ¯å­ç±»åž‹ %d" -#: tcop/postgres.c:4240 +#: tcop/postgres.c:4416 #, c-format msgid "invalid DESCRIBE message subtype %d" msgstr "无效的 DESCRIBE ä¿¡æ¯å­ç±»åž‹ %d" -#: tcop/postgres.c:4318 +#: tcop/postgres.c:4494 #, c-format msgid "fastpath function calls not supported in a replication connection" msgstr "å¤åˆ¶è¿žæŽ¥ä¸èƒ½ä½¿ç”¨fastpath函数调用" -#: tcop/postgres.c:4322 +#: tcop/postgres.c:4498 #, c-format msgid "extended query protocol not supported in a replication connection" msgstr "扩展的查询å议在å¤åˆ¶è¿žæŽ¥é‡Œä¸æ”¯æŒ" -#: tcop/postgres.c:4492 +#: tcop/postgres.c:4675 #, c-format -msgid "" -"disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s" -"%s" +msgid "disconnection: session time: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" msgstr "断开连接: ä¼šè¯æ—¶é—´: %d:%02d:%02d.%03d user=%s database=%s host=%s%s%s" -#: tcop/pquery.c:663 +#: tcop/pquery.c:642 #, c-format msgid "bind message has %d result formats but query has %d columns" msgstr "ç»‘å®šä¿¡æ¯æœ‰%d个结果格å¼,但是在查询中有%d列." -#: tcop/pquery.c:965 +#: tcop/pquery.c:949 #, c-format msgid "cursor can only scan forward" msgstr "游标能够åªå‘剿‰«æ" -#: tcop/pquery.c:966 +#: tcop/pquery.c:950 #, c-format msgid "Declare it with SCROLL option to enable backward scan." msgstr "带 SCROLL 选项声明å…许å‘åŽæ‰«æ" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:235 +#: tcop/utility.c:245 #, c-format msgid "cannot execute %s in a read-only transaction" msgstr "ä¸èƒ½åœ¨ä¸€ä¸ªåªè¯»æ¨¡å¼çš„事务中执行%s" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:253 +#: tcop/utility.c:263 #, c-format msgid "cannot execute %s during a parallel operation" msgstr "并行æ“作期间ä¸èƒ½æ‰§è¡Œ%s" #. translator: %s is name of a SQL command, eg CREATE -#: tcop/utility.c:272 +#: tcop/utility.c:282 #, c-format msgid "cannot execute %s during recovery" msgstr "无法在æ¢å¤æœŸé—´æ‰§è¡Œ%s" #. translator: %s is name of a SQL command, eg PREPARE -#: tcop/utility.c:290 +#: tcop/utility.c:300 #, c-format msgid "cannot execute %s within security-restricted operation" msgstr "无法在安全é™åˆ¶æ“作中执行%s" -#: tcop/utility.c:744 +#: tcop/utility.c:760 #, c-format msgid "must be superuser to do CHECKPOINT" msgstr "åªæœ‰è¶…级用户å¯ä»¥åš CHECKPOINT" -#: tsearch/dict_ispell.c:51 tsearch/dict_thesaurus.c:623 +#: tcop/utility.c:1353 +#, c-format +msgid "cannot create index on partitioned table \"%s\"" +msgstr "无法在分区表 \"%s\"上创建索引" + +#: tcop/utility.c:1355 +#, c-format +msgid "Table \"%s\" contains partitions that are foreign tables." +msgstr "表\"%s\"包å«å±žäºŽå¤–部表的分区." + +#: tsearch/dict_ispell.c:52 tsearch/dict_thesaurus.c:624 #, c-format msgid "multiple DictFile parameters" msgstr "多个DictFile傿•°" -#: tsearch/dict_ispell.c:62 +#: tsearch/dict_ispell.c:63 #, c-format msgid "multiple AffFile parameters" msgstr "多个AffFile傿•°" -#: tsearch/dict_ispell.c:81 +#: tsearch/dict_ispell.c:82 #, c-format msgid "unrecognized Ispell parameter: \"%s\"" msgstr "未识别的Ispell傿•°: \"%s\"" -#: tsearch/dict_ispell.c:95 +#: tsearch/dict_ispell.c:96 #, c-format msgid "missing AffFile parameter" msgstr "丢失AffFile傿•°" -#: tsearch/dict_ispell.c:101 tsearch/dict_thesaurus.c:647 +#: tsearch/dict_ispell.c:102 tsearch/dict_thesaurus.c:648 #, c-format msgid "missing DictFile parameter" msgstr "丢失DictFile傿•°" -#: tsearch/dict_simple.c:57 +#: tsearch/dict_simple.c:58 #, c-format msgid "multiple Accept parameters" msgstr "多个接å—傿•°" -#: tsearch/dict_simple.c:65 +#: tsearch/dict_simple.c:66 #, c-format msgid "unrecognized simple dictionary parameter: \"%s\"" msgstr "未识别简å•字兏傿•°:\"%s\"" -#: tsearch/dict_synonym.c:117 +#: tsearch/dict_synonym.c:118 #, c-format msgid "unrecognized synonym parameter: \"%s\"" msgstr "未识别的åŒä¹‰è¯å‚æ•°: \"%s\"" -#: tsearch/dict_synonym.c:124 +#: tsearch/dict_synonym.c:125 #, c-format msgid "missing Synonyms parameter" msgstr "丢失åŒä¹‰è¯å‚æ•°" -#: tsearch/dict_synonym.c:131 +#: tsearch/dict_synonym.c:132 #, c-format msgid "could not open synonym file \"%s\": %m" msgstr "无法打开synonym文件 \"%s\": %m" -#: tsearch/dict_thesaurus.c:178 +#: tsearch/dict_thesaurus.c:179 #, c-format msgid "could not open thesaurus file \"%s\": %m" msgstr "无法打开åŒä¹‰è¯è¯å…¸æ–‡ä»¶ \"%s\": %m" -#: tsearch/dict_thesaurus.c:211 +#: tsearch/dict_thesaurus.c:212 #, c-format msgid "unexpected delimiter" msgstr "æ„外出现的分隔符" -#: tsearch/dict_thesaurus.c:261 tsearch/dict_thesaurus.c:277 +#: tsearch/dict_thesaurus.c:262 tsearch/dict_thesaurus.c:278 #, c-format msgid "unexpected end of line or lexeme" msgstr "æ„å¤–å‡ºçŽ°çš„è¡Œæˆ–è¯æ±‡æœ«å°¾" -#: tsearch/dict_thesaurus.c:286 +#: tsearch/dict_thesaurus.c:287 #, c-format msgid "unexpected end of line" msgstr "æ„外的输入末尾" -#: tsearch/dict_thesaurus.c:296 +#: tsearch/dict_thesaurus.c:297 #, c-format msgid "too many lexemes in thesaurus entry" msgstr "辞典项里有大多的语义" -#: tsearch/dict_thesaurus.c:420 +#: tsearch/dict_thesaurus.c:421 #, c-format -msgid "" -"thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" +msgid "thesaurus sample word \"%s\" isn't recognized by subdictionary (rule %d)" msgstr "(规则 %2$d)å­å­—典没有识别åŒä¹‰è¯å­—典样例è¯\"%1$s\" " -#: tsearch/dict_thesaurus.c:426 +#: tsearch/dict_thesaurus.c:427 #, c-format msgid "thesaurus sample word \"%s\" is a stop word (rule %d)" msgstr "(规则 %2$d)åŒä¹‰è¯å­—典样例è¯\"%1$s\"是一个终止è¯. " -#: tsearch/dict_thesaurus.c:429 +#: tsearch/dict_thesaurus.c:430 #, c-format msgid "Use \"?\" to represent a stop word within a sample phrase." msgstr "在示例短语中使用\"?\" æ¥ä»£è¡¨ä¸€ä¸ªç»“æŸè¯." -#: tsearch/dict_thesaurus.c:575 +#: tsearch/dict_thesaurus.c:576 #, c-format msgid "thesaurus substitute word \"%s\" is a stop word (rule %d)" msgstr "(规则 %2$d)åŒä¹‰è¯å­—典替代è¯\"%1$s\"是一个终止è¯. " -#: tsearch/dict_thesaurus.c:582 +#: tsearch/dict_thesaurus.c:583 #, c-format -msgid "" -"thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" +msgid "thesaurus substitute word \"%s\" isn't recognized by subdictionary (rule %d)" msgstr "(规则 %2$d)å­å­—典没有识别åŒä¹‰è¯å­—典替代è¯\"%1$s\"" -#: tsearch/dict_thesaurus.c:594 +#: tsearch/dict_thesaurus.c:595 #, c-format msgid "thesaurus substitute phrase is empty (rule %d)" msgstr "(规则 %d)åŒä¹‰è¯å­—典替代短语是空的" -#: tsearch/dict_thesaurus.c:632 +#: tsearch/dict_thesaurus.c:633 #, c-format msgid "multiple Dictionary parameters" msgstr "å¤šä¸ªå­—å…¸å‚æ•°" -#: tsearch/dict_thesaurus.c:639 +#: tsearch/dict_thesaurus.c:640 #, c-format msgid "unrecognized Thesaurus parameter: \"%s\"" msgstr "未识别的åŒä¹‰è¯å­—兏傿•° \"%s\"" -#: tsearch/dict_thesaurus.c:651 +#: tsearch/dict_thesaurus.c:652 #, c-format msgid "missing Dictionary parameter" msgstr "䏢失字兏傿•°" -#: tsearch/spell.c:382 tsearch/spell.c:399 tsearch/spell.c:408 +#: tsearch/spell.c:380 tsearch/spell.c:397 tsearch/spell.c:406 #: tsearch/spell.c:1034 #, c-format -#| msgid "invalid data in file \"%s\"" msgid "invalid affix flag \"%s\"" msgstr "无效的è¯ç¼€æ ‡å¿— \"%s\"" -#: tsearch/spell.c:386 tsearch/spell.c:1038 +#: tsearch/spell.c:384 tsearch/spell.c:1038 #, c-format -#| msgid "%s: transfer rate \"%s\" is out of range\n" msgid "affix flag \"%s\" is out of range" msgstr "è¯ç¼€æ ‡å¿— \"%s\" 超过范围" -#: tsearch/spell.c:416 +#: tsearch/spell.c:414 #, c-format -#| msgid "invalid data in file \"%s\"" msgid "invalid character in affix flag \"%s\"" msgstr "è¯ç¼€æ ‡å¿— \"%s\" 中有无效字符" -#: tsearch/spell.c:436 +#: tsearch/spell.c:434 #, c-format -msgid "invalid affix flag \"%s\" with long flag value" -msgstr "无效的具有 long 标志值的è¯ç¼€æ ‡å¿— \"%s\"" +msgid "invalid affix flag \"%s\" with \"long\" flag value" +msgstr "带有\"long\"标志值的附加标志\"%s\"无效" -#: tsearch/spell.c:523 +#: tsearch/spell.c:522 #, c-format msgid "could not open dictionary file \"%s\": %m" msgstr "无法打开字典文件 \"%s\": %m" -#: tsearch/spell.c:740 utils/adt/regexp.c:204 +#: tsearch/spell.c:740 utils/adt/regexp.c:208 #, c-format msgid "invalid regular expression: %s" msgstr "无效的正则表达å¼: %s" -#: tsearch/spell.c:1161 tsearch/spell.c:1716 +#: tsearch/spell.c:954 tsearch/spell.c:971 tsearch/spell.c:988 +#: tsearch/spell.c:1005 tsearch/spell.c:1070 gram.y:15735 gram.y:15752 +#, c-format +msgid "syntax error" +msgstr "语法错误" + +#: tsearch/spell.c:1161 tsearch/spell.c:1726 #, c-format -#| msgid "invalid cidr value: \"%s\"" msgid "invalid affix alias \"%s\"" msgstr "无效的è¯ç¼€åˆ«å \"%s\"" -#: tsearch/spell.c:1210 tsearch/spell.c:1280 tsearch/spell.c:1422 +#: tsearch/spell.c:1211 tsearch/spell.c:1282 tsearch/spell.c:1431 #, c-format msgid "could not open affix file \"%s\": %m" msgstr "无法打开affix文件 \"%s\": %m" -#: tsearch/spell.c:1264 +#: tsearch/spell.c:1265 #, c-format -#| msgid "Ispell dictionary supports only default flag value" -msgid "Ispell dictionary supports only default, long and num flag value" -msgstr "Ispell å­—å…¸åªæ”¯æŒ defaultã€long å’Œ num 标志值" +msgid "Ispell dictionary supports only \"default\", \"long\", and \"num\" flag values" +msgstr "Ispell å­—å…¸åªæ”¯æŒ\"default\", \"long\"å’Œ \"num\"标志值" -#: tsearch/spell.c:1307 +#: tsearch/spell.c:1309 #, c-format -#| msgid "%s: invalid number of parallel jobs\n" msgid "invalid number of flag vector aliases" msgstr "标志å‘é‡åˆ«åçš„æ•°é‡æ— æ•ˆ" -#: tsearch/spell.c:1538 +#: tsearch/spell.c:1332 +#, c-format +msgid "number of aliases exceeds specified number %d" +msgstr "别å的数目超过了指定的数目%d" + +#: tsearch/spell.c:1547 #, c-format msgid "affix file contains both old-style and new-style commands" msgstr "é™„åŠ æ–‡ä»¶åŒæ—¶åŒ…å«è€å¼å’Œæ–°å¼å‘½ä»¤" -#: tsearch/to_tsany.c:170 utils/adt/tsvector.c:270 -#: utils/adt/tsvector_op.c:1064 +#: tsearch/to_tsany.c:185 utils/adt/tsvector.c:271 utils/adt/tsvector_op.c:1132 #, c-format msgid "string is too long for tsvector (%d bytes, max %d bytes)" msgstr "字符串对于tsvectoræ¥è¯´å¤ªé•¿äº†(å½“å‰ %d字节, 最大å…许值是%d字节)" -#: tsearch/ts_locale.c:177 +#: tsearch/ts_locale.c:185 #, c-format msgid "line %d of configuration file \"%s\": \"%s\"" msgstr "é…置文件\"%2$s\"的第%1$d行: \"%3$s\"" -#: tsearch/ts_locale.c:299 +#: tsearch/ts_locale.c:302 #, c-format msgid "conversion from wchar_t to server encoding failed: %m" msgstr "从wchar_t转æ¢åˆ°æœåŠ¡å™¨ç¼–ç å¤±è´¥: %m" @@ -18451,479 +20165,462 @@ msgstr "无效的文本æœç´¢é…置文件å\"%s\"" msgid "could not open stop-word file \"%s\": %m" msgstr "无法打开stop-word 文件 \"%s\": %m" -#: tsearch/wparser.c:306 +#: tsearch/wparser.c:322 tsearch/wparser.c:410 tsearch/wparser.c:487 #, c-format msgid "text search parser does not support headline creation" msgstr "文本æœç´¢è§£æžå™¨ä¸æ”¯æŒæ ‡é¢˜åˆ›å»º" -#: tsearch/wparser_def.c:2583 +#: tsearch/wparser_def.c:2486 #, c-format msgid "unrecognized headline parameter: \"%s\"" msgstr "æœªè¯†åˆ«çš„æ ‡é¢˜å‚æ•°: \"%s\"" -#: tsearch/wparser_def.c:2592 +#: tsearch/wparser_def.c:2495 #, c-format msgid "MinWords should be less than MaxWords" msgstr "MinWords的值应该å°äºŽMaxWords的值" -#: tsearch/wparser_def.c:2596 +#: tsearch/wparser_def.c:2499 #, c-format msgid "MinWords should be positive" msgstr "MinWord应该是正数." -#: tsearch/wparser_def.c:2600 +#: tsearch/wparser_def.c:2503 #, c-format msgid "ShortWord should be >= 0" msgstr "ShortWord应该大于等于0" -#: tsearch/wparser_def.c:2604 +#: tsearch/wparser_def.c:2507 #, c-format msgid "MaxFragments should be >= 0" msgstr "MaxFragments应该大于等于0" -#: utils/adt/acl.c:170 utils/adt/name.c:91 +#: utils/adt/acl.c:171 utils/adt/name.c:93 #, c-format msgid "identifier too long" msgstr "标识符太长" -#: utils/adt/acl.c:171 utils/adt/name.c:92 +#: utils/adt/acl.c:172 utils/adt/name.c:94 #, c-format msgid "Identifier must be less than %d characters." msgstr "标识符必须å°äºŽ %d 个字符." -#: utils/adt/acl.c:257 +#: utils/adt/acl.c:258 #, c-format msgid "unrecognized key word: \"%s\"" msgstr "未知的键值: \"%s\"" -#: utils/adt/acl.c:258 +#: utils/adt/acl.c:259 #, c-format msgid "ACL key word must be \"group\" or \"user\"." msgstr "ACL 键值必须为 \"group\" 或者 \"user\"." -#: utils/adt/acl.c:263 +#: utils/adt/acl.c:264 #, c-format msgid "missing name" msgstr "缺少åå­—" -#: utils/adt/acl.c:264 +#: utils/adt/acl.c:265 #, c-format msgid "A name must follow the \"group\" or \"user\" key word." msgstr "一个å字必须为 \"group\" 或者 \"user\" 键值." -#: utils/adt/acl.c:270 +#: utils/adt/acl.c:271 #, c-format msgid "missing \"=\" sign" msgstr "缺少 \"=\" 符å·" -#: utils/adt/acl.c:323 +#: utils/adt/acl.c:324 #, c-format msgid "invalid mode character: must be one of \"%s\"" msgstr "无效的模å¼å­—符: 必须是 \"%s\" 其中的一个" -#: utils/adt/acl.c:345 +#: utils/adt/acl.c:346 #, c-format msgid "a name must follow the \"/\" sign" msgstr "åå­—å¿…é¡»å† \"/\" 符å·åŽ" -#: utils/adt/acl.c:353 +#: utils/adt/acl.c:354 #, c-format msgid "defaulting grantor to user ID %u" msgstr "缺çœå°†æŽˆæƒè€…身份给予用户ID %u" -#: utils/adt/acl.c:544 +#: utils/adt/acl.c:545 #, c-format msgid "ACL array contains wrong data type" msgstr "ACL数组包å«é”™è¯¯æ•°æ®ç±»åž‹" -#: utils/adt/acl.c:548 +#: utils/adt/acl.c:549 #, c-format msgid "ACL arrays must be one-dimensional" msgstr "ACL数组必须是一维数组" -#: utils/adt/acl.c:552 +#: utils/adt/acl.c:553 #, c-format msgid "ACL arrays must not contain null values" msgstr "ACL数组ä¸èƒ½åŒ…å«ç©ºå€¼" -#: utils/adt/acl.c:576 +#: utils/adt/acl.c:577 #, c-format msgid "extra garbage at the end of the ACL specification" msgstr "在ACL定义的结æŸéƒ¨åˆ†çš„多余的无用部分" -#: utils/adt/acl.c:1196 +#: utils/adt/acl.c:1212 #, c-format msgid "grant options cannot be granted back to your own grantor" msgstr "ä¸èƒ½å°†grant选项授予您自己的授予者 " -#: utils/adt/acl.c:1257 +#: utils/adt/acl.c:1273 #, c-format msgid "dependent privileges exist" msgstr "存在ä¾èµ–æƒé™" -#: utils/adt/acl.c:1258 +#: utils/adt/acl.c:1274 #, c-format msgid "Use CASCADE to revoke them too." msgstr "使用CASCADE回收这些æƒé™" -#: utils/adt/acl.c:1537 +#: utils/adt/acl.c:1536 #, c-format msgid "aclinsert is no longer supported" msgstr "ä¸å†æ”¯æŒ aclinsert" -#: utils/adt/acl.c:1547 +#: utils/adt/acl.c:1546 #, c-format msgid "aclremove is no longer supported" msgstr "ä¸å†æ”¯æŒ aclremove" -#: utils/adt/acl.c:1633 utils/adt/acl.c:1687 +#: utils/adt/acl.c:1632 utils/adt/acl.c:1686 #, c-format msgid "unrecognized privilege type: \"%s\"" msgstr "未知的æƒé™ç±»åž‹: \"%s\"" -#: utils/adt/acl.c:3427 utils/adt/regproc.c:123 utils/adt/regproc.c:144 -#: utils/adt/regproc.c:319 +#: utils/adt/acl.c:3486 utils/adt/regproc.c:102 utils/adt/regproc.c:277 #, c-format msgid "function \"%s\" does not exist" msgstr "函数 \"%s\" ä¸å­˜åœ¨" -#: utils/adt/acl.c:4881 +#: utils/adt/acl.c:4958 #, c-format msgid "must be member of role \"%s\"" msgstr "必须是角色\"%s\"çš„æˆå‘˜" -#: utils/adt/acl.c:5279 utils/adt/acl.c:5285 -#, c-format -#| msgid "role name \"%s\" is reserved" -msgid "role \"%s\" is reserved" -msgstr "角色 \"%s\" 是被ä¿ç•™çš„" - -#: utils/adt/array_expanded.c:276 utils/adt/arrayfuncs.c:931 -#: utils/adt/arrayfuncs.c:1519 utils/adt/arrayfuncs.c:3251 -#: utils/adt/arrayfuncs.c:3389 utils/adt/arrayfuncs.c:5864 -#: utils/adt/arrayfuncs.c:6175 utils/adt/arrayutils.c:93 +#: utils/adt/array_expanded.c:274 utils/adt/arrayfuncs.c:932 +#: utils/adt/arrayfuncs.c:1532 utils/adt/arrayfuncs.c:3235 +#: utils/adt/arrayfuncs.c:3375 utils/adt/arrayfuncs.c:5909 +#: utils/adt/arrayfuncs.c:6250 utils/adt/arrayutils.c:93 #: utils/adt/arrayutils.c:102 utils/adt/arrayutils.c:109 #, c-format msgid "array size exceeds the maximum allowed (%d)" msgstr "数组的大å°è¶…过了最大å…许值(%d)" -#: utils/adt/array_userfuncs.c:67 utils/adt/array_userfuncs.c:529 -#: utils/adt/array_userfuncs.c:609 utils/adt/json.c:1759 utils/adt/json.c:1854 -#: utils/adt/json.c:1892 utils/adt/jsonb.c:1126 utils/adt/jsonb.c:1155 -#: utils/adt/jsonb.c:1591 utils/adt/jsonb.c:1755 utils/adt/jsonb.c:1765 +#: utils/adt/array_userfuncs.c:80 utils/adt/array_userfuncs.c:466 +#: utils/adt/array_userfuncs.c:546 utils/adt/json.c:1829 utils/adt/json.c:1924 +#: utils/adt/json.c:1962 utils/adt/jsonb.c:1094 utils/adt/jsonb.c:1123 +#: utils/adt/jsonb.c:1517 utils/adt/jsonb.c:1681 utils/adt/jsonb.c:1691 #, c-format msgid "could not determine input data type" msgstr "无法确定输入数æ®ç±»åž‹" -#: utils/adt/array_userfuncs.c:72 +#: utils/adt/array_userfuncs.c:85 #, c-format msgid "input data type is not an array" msgstr "输入数æ®ç±»åž‹ä¸æ˜¯ä¸€ä¸ªæ•°ç»„" -#: utils/adt/array_userfuncs.c:120 utils/adt/array_userfuncs.c:174 -#: utils/adt/arrayfuncs.c:1322 utils/adt/float.c:1221 utils/adt/float.c:1280 -#: utils/adt/float.c:3509 utils/adt/float.c:3525 utils/adt/int.c:623 -#: utils/adt/int.c:652 utils/adt/int.c:673 utils/adt/int.c:704 -#: utils/adt/int.c:737 utils/adt/int.c:759 utils/adt/int.c:907 -#: utils/adt/int.c:928 utils/adt/int.c:955 utils/adt/int.c:995 -#: utils/adt/int.c:1016 utils/adt/int.c:1043 utils/adt/int.c:1076 -#: utils/adt/int.c:1159 utils/adt/int8.c:1298 utils/adt/numeric.c:2907 -#: utils/adt/numeric.c:2916 utils/adt/varbit.c:1173 utils/adt/varbit.c:1565 -#: utils/adt/varlena.c:1055 utils/adt/varlena.c:2807 +#: utils/adt/array_userfuncs.c:129 utils/adt/array_userfuncs.c:181 +#: utils/adt/arrayfuncs.c:1335 utils/adt/float.c:1220 utils/adt/float.c:1308 +#: utils/adt/float.c:3883 utils/adt/float.c:3897 utils/adt/int.c:759 +#: utils/adt/int.c:781 utils/adt/int.c:795 utils/adt/int.c:809 +#: utils/adt/int.c:840 utils/adt/int.c:861 utils/adt/int.c:978 +#: utils/adt/int.c:992 utils/adt/int.c:1006 utils/adt/int.c:1039 +#: utils/adt/int.c:1053 utils/adt/int.c:1067 utils/adt/int.c:1098 +#: utils/adt/int.c:1180 utils/adt/int8.c:1167 utils/adt/numeric.c:1565 +#: utils/adt/numeric.c:3240 utils/adt/varbit.c:1183 utils/adt/varbit.c:1585 +#: utils/adt/varlena.c:1075 utils/adt/varlena.c:3362 #, c-format msgid "integer out of range" msgstr "整数超出范围" -#: utils/adt/array_userfuncs.c:127 utils/adt/array_userfuncs.c:184 +#: utils/adt/array_userfuncs.c:136 utils/adt/array_userfuncs.c:191 #, c-format msgid "argument must be empty or one-dimensional array" msgstr "傿•°å¿…须为空或者一维数组" -#: utils/adt/array_userfuncs.c:266 utils/adt/array_userfuncs.c:305 -#: utils/adt/array_userfuncs.c:342 utils/adt/array_userfuncs.c:371 -#: utils/adt/array_userfuncs.c:399 +#: utils/adt/array_userfuncs.c:273 utils/adt/array_userfuncs.c:312 +#: utils/adt/array_userfuncs.c:349 utils/adt/array_userfuncs.c:378 +#: utils/adt/array_userfuncs.c:406 #, c-format msgid "cannot concatenate incompatible arrays" msgstr "无法连结ä¸å…¼å®¹çš„æ•°ç»„" -#: utils/adt/array_userfuncs.c:267 +#: utils/adt/array_userfuncs.c:274 #, c-format -msgid "" -"Arrays with element types %s and %s are not compatible for concatenation." +msgid "Arrays with element types %s and %s are not compatible for concatenation." msgstr "æˆå‘˜ç±»åž‹æ˜¯%så’Œ%sçš„æ•°ç»„å¯¹äºŽä¸²è”æ“作是ä¸å…¼å®¹çš„." -#: utils/adt/array_userfuncs.c:306 +#: utils/adt/array_userfuncs.c:313 #, c-format msgid "Arrays of %d and %d dimensions are not compatible for concatenation." msgstr "维度是%då’Œ%dçš„æ•°ç»„å¯¹äºŽä¸²è”æ“作ä¸å…¼å®¹" -#: utils/adt/array_userfuncs.c:343 +#: utils/adt/array_userfuncs.c:350 #, c-format -msgid "" -"Arrays with differing element dimensions are not compatible for " -"concatenation." +msgid "Arrays with differing element dimensions are not compatible for concatenation." msgstr "带有ä¸åŒæˆå‘˜ç»´åº¦çš„æ•°ç»„å¯¹äºŽä¸²è”æ“作ä¸å…¼å®¹" -#: utils/adt/array_userfuncs.c:372 utils/adt/array_userfuncs.c:400 +#: utils/adt/array_userfuncs.c:379 utils/adt/array_userfuncs.c:407 #, c-format msgid "Arrays with differing dimensions are not compatible for concatenation." msgstr "带有ä¸åŒç»´åº¦çš„æ•°ç»„å¯¹äºŽä¸²è”æ“作ä¸å…¼å®¹." -#: utils/adt/array_userfuncs.c:468 utils/adt/arrayfuncs.c:1284 -#: utils/adt/arrayfuncs.c:3357 utils/adt/arrayfuncs.c:5764 -#, c-format -msgid "invalid number of dimensions: %d" -msgstr "无效的大å°å€¼: %d" - -#: utils/adt/array_userfuncs.c:725 utils/adt/array_userfuncs.c:876 +#: utils/adt/array_userfuncs.c:662 utils/adt/array_userfuncs.c:814 #, c-format msgid "searching for elements in multidimensional arrays is not supported" msgstr "䏿”¯æŒåœ¨å¤šç»´æ•°ç»„中æœç´¢å…ƒç´ " -#: utils/adt/array_userfuncs.c:749 +#: utils/adt/array_userfuncs.c:686 #, c-format msgid "initial position must not be null" msgstr "åˆå§‹ä½ç½®ä¸èƒ½ä¸ºç©º" -#: utils/adt/arrayfuncs.c:268 utils/adt/arrayfuncs.c:282 -#: utils/adt/arrayfuncs.c:293 utils/adt/arrayfuncs.c:315 -#: utils/adt/arrayfuncs.c:330 utils/adt/arrayfuncs.c:344 -#: utils/adt/arrayfuncs.c:350 utils/adt/arrayfuncs.c:357 -#: utils/adt/arrayfuncs.c:488 utils/adt/arrayfuncs.c:504 -#: utils/adt/arrayfuncs.c:515 utils/adt/arrayfuncs.c:530 -#: utils/adt/arrayfuncs.c:551 utils/adt/arrayfuncs.c:581 -#: utils/adt/arrayfuncs.c:588 utils/adt/arrayfuncs.c:596 -#: utils/adt/arrayfuncs.c:630 utils/adt/arrayfuncs.c:653 -#: utils/adt/arrayfuncs.c:673 utils/adt/arrayfuncs.c:785 -#: utils/adt/arrayfuncs.c:794 utils/adt/arrayfuncs.c:824 -#: utils/adt/arrayfuncs.c:839 utils/adt/arrayfuncs.c:892 +#: utils/adt/arrayfuncs.c:269 utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:331 utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:505 +#: utils/adt/arrayfuncs.c:516 utils/adt/arrayfuncs.c:531 +#: utils/adt/arrayfuncs.c:552 utils/adt/arrayfuncs.c:582 +#: utils/adt/arrayfuncs.c:589 utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:631 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:674 utils/adt/arrayfuncs.c:786 +#: utils/adt/arrayfuncs.c:795 utils/adt/arrayfuncs.c:825 +#: utils/adt/arrayfuncs.c:840 utils/adt/arrayfuncs.c:893 #, c-format msgid "malformed array literal: \"%s\"" msgstr "有缺陷的数组常é‡:\"%s\"" -#: utils/adt/arrayfuncs.c:269 +#: utils/adt/arrayfuncs.c:270 #, c-format msgid "\"[\" must introduce explicitly-specified array dimensions." msgstr "\"[\"å¿…é¡»å¼•å…¥æ˜¾å¼æŒ‡å®šçš„æ•°ç»„规模。" -#: utils/adt/arrayfuncs.c:283 +#: utils/adt/arrayfuncs.c:284 #, c-format msgid "Missing array dimension value." msgstr "缺少数组尺寸值。" -#: utils/adt/arrayfuncs.c:294 utils/adt/arrayfuncs.c:331 +#: utils/adt/arrayfuncs.c:295 utils/adt/arrayfuncs.c:332 #, c-format msgid "Missing \"%s\" after array dimensions." msgstr "数组维度åŽç¼ºå°‘\"%s\"" -#: utils/adt/arrayfuncs.c:303 utils/adt/arrayfuncs.c:2870 -#: utils/adt/arrayfuncs.c:2902 utils/adt/arrayfuncs.c:2917 +#: utils/adt/arrayfuncs.c:304 utils/adt/arrayfuncs.c:2883 +#: utils/adt/arrayfuncs.c:2915 utils/adt/arrayfuncs.c:2930 #, c-format msgid "upper bound cannot be less than lower bound" msgstr "上é™ä¸èƒ½å°äºŽåº•é™" -#: utils/adt/arrayfuncs.c:316 +#: utils/adt/arrayfuncs.c:317 #, c-format msgid "Array value must start with \"{\" or dimension information." msgstr "数组值必须以 \"{\" 或者维度信æ¯å¼€å§‹ã€‚" -#: utils/adt/arrayfuncs.c:345 +#: utils/adt/arrayfuncs.c:346 #, c-format msgid "Array contents must start with \"{\"." msgstr "数组内容必须以\"{\"开始。" -#: utils/adt/arrayfuncs.c:351 utils/adt/arrayfuncs.c:358 +#: utils/adt/arrayfuncs.c:352 utils/adt/arrayfuncs.c:359 #, c-format msgid "Specified array dimensions do not match array contents." msgstr "指定的数组维数与数组内容ä¸åŒ¹é…" -#: utils/adt/arrayfuncs.c:489 utils/adt/arrayfuncs.c:516 -#: utils/adt/rangetypes.c:2124 utils/adt/rangetypes.c:2132 -#: utils/adt/rowtypes.c:208 utils/adt/rowtypes.c:216 +#: utils/adt/arrayfuncs.c:490 utils/adt/arrayfuncs.c:517 +#: utils/adt/rangetypes.c:2179 utils/adt/rangetypes.c:2187 +#: utils/adt/rowtypes.c:210 utils/adt/rowtypes.c:218 #, c-format msgid "Unexpected end of input." msgstr "æ„外的输入末尾" -#: utils/adt/arrayfuncs.c:505 utils/adt/arrayfuncs.c:552 -#: utils/adt/arrayfuncs.c:582 utils/adt/arrayfuncs.c:631 +#: utils/adt/arrayfuncs.c:506 utils/adt/arrayfuncs.c:553 +#: utils/adt/arrayfuncs.c:583 utils/adt/arrayfuncs.c:632 #, c-format msgid "Unexpected \"%c\" character." msgstr "æ„外的\"%c\"字符" -#: utils/adt/arrayfuncs.c:531 utils/adt/arrayfuncs.c:654 +#: utils/adt/arrayfuncs.c:532 utils/adt/arrayfuncs.c:655 #, c-format msgid "Unexpected array element." msgstr "æ„外的数组元素。" -#: utils/adt/arrayfuncs.c:589 +#: utils/adt/arrayfuncs.c:590 #, c-format msgid "Unmatched \"%c\" character." msgstr "ä¸åŒ¹é…çš„\"%c\"字符。" -#: utils/adt/arrayfuncs.c:597 +#: utils/adt/arrayfuncs.c:598 utils/adt/jsonfuncs.c:2398 #, c-format msgid "Multidimensional arrays must have sub-arrays with matching dimensions." msgstr "多维数组必须有具有匹é…ç»´åº¦çš„å­æ•°ç»„" -#: utils/adt/arrayfuncs.c:674 +#: utils/adt/arrayfuncs.c:675 #, c-format msgid "Junk after closing right brace." msgstr "ç»“å°¾çš„å³æ‹¬å·åŽçš„æ˜¯æ— ç”¨çš„内容。" -#: utils/adt/arrayfuncs.c:1295 +#: utils/adt/arrayfuncs.c:1297 utils/adt/arrayfuncs.c:3343 +#: utils/adt/arrayfuncs.c:5815 #, c-format -msgid "invalid array flags" +msgid "invalid number of dimensions: %d" +msgstr "无效的大å°å€¼: %d" + +#: utils/adt/arrayfuncs.c:1308 +#, c-format +msgid "invalid array flags" msgstr "无效的数组标记" -#: utils/adt/arrayfuncs.c:1303 +#: utils/adt/arrayfuncs.c:1316 #, c-format msgid "wrong element type" msgstr "错误的元素类型" -#: utils/adt/arrayfuncs.c:1353 utils/adt/rangetypes.c:334 -#: utils/cache/lsyscache.c:2651 +#: utils/adt/arrayfuncs.c:1366 utils/adt/rangetypes.c:335 +#: utils/cache/lsyscache.c:2725 #, c-format msgid "no binary input function available for type %s" msgstr "没有类型 %s 的有效二进制输入函数" -#: utils/adt/arrayfuncs.c:1493 +#: utils/adt/arrayfuncs.c:1506 #, c-format msgid "improper binary format in array element %d" msgstr "数组元素 %d ä¸ºä¸æ­£ç¡®çš„二进制格å¼" -#: utils/adt/arrayfuncs.c:1574 utils/adt/rangetypes.c:339 -#: utils/cache/lsyscache.c:2684 +#: utils/adt/arrayfuncs.c:1587 utils/adt/rangetypes.c:340 +#: utils/cache/lsyscache.c:2758 #, c-format msgid "no binary output function available for type %s" msgstr "没有类型 %s 的有效二进制输出函数" -#: utils/adt/arrayfuncs.c:2052 +#: utils/adt/arrayfuncs.c:2065 #, c-format msgid "slices of fixed-length arrays not implemented" msgstr "没有实现固定长度数组的部分" -#: utils/adt/arrayfuncs.c:2230 utils/adt/arrayfuncs.c:2252 -#: utils/adt/arrayfuncs.c:2301 utils/adt/arrayfuncs.c:2537 -#: utils/adt/arrayfuncs.c:2848 utils/adt/arrayfuncs.c:5744 -#: utils/adt/arrayfuncs.c:5776 utils/adt/arrayfuncs.c:5793 -#: utils/adt/json.c:2290 utils/adt/json.c:2365 utils/adt/jsonb.c:1369 -#: utils/adt/jsonb.c:1455 utils/adt/jsonfuncs.c:3537 -#: utils/adt/jsonfuncs.c:3582 utils/adt/jsonfuncs.c:3629 +#: utils/adt/arrayfuncs.c:2243 utils/adt/arrayfuncs.c:2265 +#: utils/adt/arrayfuncs.c:2314 utils/adt/arrayfuncs.c:2550 +#: utils/adt/arrayfuncs.c:2861 utils/adt/arrayfuncs.c:5801 +#: utils/adt/arrayfuncs.c:5827 utils/adt/arrayfuncs.c:5838 +#: utils/adt/json.c:2325 utils/adt/json.c:2400 utils/adt/jsonb.c:1295 +#: utils/adt/jsonb.c:1381 utils/adt/jsonfuncs.c:4295 utils/adt/jsonfuncs.c:4446 +#: utils/adt/jsonfuncs.c:4491 utils/adt/jsonfuncs.c:4538 #, c-format msgid "wrong number of array subscripts" msgstr "错误的数组下标" -#: utils/adt/arrayfuncs.c:2235 utils/adt/arrayfuncs.c:2343 -#: utils/adt/arrayfuncs.c:2601 utils/adt/arrayfuncs.c:2907 +#: utils/adt/arrayfuncs.c:2248 utils/adt/arrayfuncs.c:2356 +#: utils/adt/arrayfuncs.c:2614 utils/adt/arrayfuncs.c:2920 #, c-format msgid "array subscript out of range" msgstr "数组下标超出范围" -#: utils/adt/arrayfuncs.c:2240 +#: utils/adt/arrayfuncs.c:2253 #, c-format msgid "cannot assign null value to an element of a fixed-length array" msgstr "无法将空值分é…给固定长度数组的æˆå‘˜" -#: utils/adt/arrayfuncs.c:2795 +#: utils/adt/arrayfuncs.c:2808 #, c-format msgid "updates on slices of fixed-length arrays not implemented" msgstr "没有实现在固定长度数组部分上的更新æ“作" -#: utils/adt/arrayfuncs.c:2826 +#: utils/adt/arrayfuncs.c:2839 #, c-format -#| msgid "array subscript must have type integer" msgid "array slice subscript must provide both boundaries" msgstr "数组切片下标必须æä¾›ä¸¤ä¸ªè¾¹ç•Œ" -#: utils/adt/arrayfuncs.c:2827 +#: utils/adt/arrayfuncs.c:2840 #, c-format -msgid "" -"When assigning to a slice of an empty array value, slice boundaries must be " -"fully specified." +msgid "When assigning to a slice of an empty array value, slice boundaries must be fully specified." msgstr "在给一个空数组值的切片赋值时,必须完全指定切片的边界。" -#: utils/adt/arrayfuncs.c:2838 utils/adt/arrayfuncs.c:2933 +#: utils/adt/arrayfuncs.c:2851 utils/adt/arrayfuncs.c:2946 #, c-format msgid "source array too small" msgstr "æºæ•°ç»„太å°" -#: utils/adt/arrayfuncs.c:3513 +#: utils/adt/arrayfuncs.c:3499 #, c-format msgid "null array element not allowed in this context" msgstr "䏿”¯æŒç©ºæ•°ç»„元素" -#: utils/adt/arrayfuncs.c:3615 utils/adt/arrayfuncs.c:3786 -#: utils/adt/arrayfuncs.c:4060 +#: utils/adt/arrayfuncs.c:3601 utils/adt/arrayfuncs.c:3772 +#: utils/adt/arrayfuncs.c:4123 #, c-format msgid "cannot compare arrays of different element types" msgstr "无法比较ä¸åŒå…ƒç´ ç±»åž‹çš„æ•°ç»„" -#: utils/adt/arrayfuncs.c:3962 utils/adt/rangetypes.c:1253 +#: utils/adt/arrayfuncs.c:3948 utils/adt/rangetypes.c:1254 +#: utils/adt/rangetypes.c:1318 #, c-format msgid "could not identify a hash function for type %s" msgstr "无法为类型 %s 确认一个哈希函数" -#: utils/adt/arrayfuncs.c:5156 +#: utils/adt/arrayfuncs.c:4040 +#, c-format +msgid "could not identify an extended hash function for type %s" +msgstr "无法识别类型%s的扩展哈希函数" + +#: utils/adt/arrayfuncs.c:5215 #, c-format msgid "data type %s is not an array type" msgstr "æ•°æ®ç±»åž‹%s䏿˜¯ä¸€ä¸ªæ•°ç»„类型" -#: utils/adt/arrayfuncs.c:5213 +#: utils/adt/arrayfuncs.c:5270 #, c-format msgid "cannot accumulate null arrays" msgstr "无法累计空值数组" -#: utils/adt/arrayfuncs.c:5241 +#: utils/adt/arrayfuncs.c:5298 #, c-format msgid "cannot accumulate empty arrays" msgstr "无法累计空数组" -#: utils/adt/arrayfuncs.c:5270 utils/adt/arrayfuncs.c:5276 +#: utils/adt/arrayfuncs.c:5327 utils/adt/arrayfuncs.c:5333 #, c-format msgid "cannot accumulate arrays of different dimensionality" msgstr "无法累积ä¸åŒç»´åº¦çš„æ•°ç»„" -#: utils/adt/arrayfuncs.c:5642 utils/adt/arrayfuncs.c:5682 +#: utils/adt/arrayfuncs.c:5699 utils/adt/arrayfuncs.c:5739 #, c-format msgid "dimension array or low bound array cannot be null" msgstr "维度数组或低界数组ä¸èƒ½ä¸ºç©º(null)" -#: utils/adt/arrayfuncs.c:5745 utils/adt/arrayfuncs.c:5777 +#: utils/adt/arrayfuncs.c:5802 utils/adt/arrayfuncs.c:5828 #, c-format msgid "Dimension array must be one dimensional." msgstr "维度数组必须是一维" -#: utils/adt/arrayfuncs.c:5750 utils/adt/arrayfuncs.c:5782 -#, c-format -msgid "wrong range of array subscripts" -msgstr "无效的数组下标范围" - -#: utils/adt/arrayfuncs.c:5751 utils/adt/arrayfuncs.c:5783 -#, c-format -msgid "Lower bound of dimension array must be one." -msgstr "维度数组的低界必须是1" - -#: utils/adt/arrayfuncs.c:5756 utils/adt/arrayfuncs.c:5788 +#: utils/adt/arrayfuncs.c:5807 utils/adt/arrayfuncs.c:5833 #, c-format msgid "dimension values cannot be null" msgstr "维度值ä¸èƒ½ä¸ºç©º" -#: utils/adt/arrayfuncs.c:5794 +#: utils/adt/arrayfuncs.c:5839 #, c-format msgid "Low bound array has different size than dimensions array." msgstr "低界数组的大å°ä¸Žå¤šç»´æ•°ç»„ä¸åŒ" -#: utils/adt/arrayfuncs.c:6040 +#: utils/adt/arrayfuncs.c:6115 #, c-format msgid "removing elements from multidimensional arrays is not supported" msgstr "䏿”¯æŒå¤šç»´æ•°ç»„中删除元素的æ“作" -#: utils/adt/arrayfuncs.c:6317 +#: utils/adt/arrayfuncs.c:6392 #, c-format msgid "thresholds must be one-dimensional array" msgstr "thresholds必须是一维数组" -#: utils/adt/arrayfuncs.c:6322 +#: utils/adt/arrayfuncs.c:6397 #, c-format msgid "thresholds array must not contain NULLs" msgstr "thresholds数组ä¸èƒ½åŒ…å«ç©ºå€¼" @@ -18943,31 +20640,51 @@ msgstr "傿•°å¿…须为空或者一维数组" msgid "typmod array must not contain nulls" msgstr "typmodä¸èƒ½åŒ…å«ç©ºå€¼" -#: utils/adt/ascii.c:75 +#: utils/adt/ascii.c:76 #, c-format msgid "encoding conversion from %s to ASCII not supported" msgstr "ç¼–ç è½¬æ¢ä¸æ”¯æŒä»Ž %s 到 ASCII 的转æ¢" -#: utils/adt/bool.c:153 +#. translator: first %s is inet or cidr +#: utils/adt/bool.c:153 utils/adt/cash.c:277 utils/adt/datetime.c:3787 +#: utils/adt/float.c:168 utils/adt/float.c:252 utils/adt/float.c:276 +#: utils/adt/float.c:390 utils/adt/float.c:474 utils/adt/float.c:501 +#: utils/adt/geo_ops.c:220 utils/adt/geo_ops.c:230 utils/adt/geo_ops.c:242 +#: utils/adt/geo_ops.c:274 utils/adt/geo_ops.c:316 utils/adt/geo_ops.c:326 +#: utils/adt/geo_ops.c:974 utils/adt/geo_ops.c:1378 utils/adt/geo_ops.c:1413 +#: utils/adt/geo_ops.c:1421 utils/adt/geo_ops.c:3360 utils/adt/geo_ops.c:4526 +#: utils/adt/geo_ops.c:4541 utils/adt/geo_ops.c:4548 utils/adt/int8.c:128 +#: utils/adt/jsonpath.c:182 utils/adt/mac.c:94 utils/adt/mac8.c:93 +#: utils/adt/mac8.c:166 utils/adt/mac8.c:184 utils/adt/mac8.c:202 +#: utils/adt/mac8.c:221 utils/adt/network.c:74 utils/adt/numeric.c:607 +#: utils/adt/numeric.c:634 utils/adt/numeric.c:5806 utils/adt/numeric.c:5830 +#: utils/adt/numeric.c:5854 utils/adt/numeric.c:6684 utils/adt/numeric.c:6710 +#: utils/adt/numutils.c:52 utils/adt/numutils.c:62 utils/adt/numutils.c:106 +#: utils/adt/numutils.c:182 utils/adt/numutils.c:258 utils/adt/oid.c:44 +#: utils/adt/oid.c:58 utils/adt/oid.c:64 utils/adt/oid.c:86 +#: utils/adt/pg_lsn.c:43 utils/adt/pg_lsn.c:49 utils/adt/tid.c:73 +#: utils/adt/tid.c:81 utils/adt/tid.c:89 utils/adt/timestamp.c:495 +#: utils/adt/txid.c:410 utils/adt/uuid.c:136 #, c-format -msgid "invalid input syntax for type boolean: \"%s\"" -msgstr "无效的布尔类型输入语法: \"%s\"" +msgid "invalid input syntax for type %s: \"%s\"" +msgstr "无效的类型 %s 输入语法: \"%s\"" -#: utils/adt/cash.c:246 +#: utils/adt/cash.c:215 utils/adt/cash.c:240 utils/adt/cash.c:250 +#: utils/adt/cash.c:290 utils/adt/int8.c:120 utils/adt/numutils.c:76 +#: utils/adt/numutils.c:83 utils/adt/numutils.c:176 utils/adt/numutils.c:252 +#: utils/adt/oid.c:70 utils/adt/oid.c:109 #, c-format -msgid "invalid input syntax for type money: \"%s\"" -msgstr "无效的货å¸ç±»åž‹è¾“入语法: \"%s\"" +msgid "value \"%s\" is out of range for type %s" +msgstr "值 \"%s\" 超出类型 %s 的范围" -#: utils/adt/cash.c:607 utils/adt/cash.c:657 utils/adt/cash.c:708 -#: utils/adt/cash.c:757 utils/adt/cash.c:809 utils/adt/cash.c:859 -#: utils/adt/float.c:848 utils/adt/float.c:912 utils/adt/float.c:3268 -#: utils/adt/float.c:3331 utils/adt/geo_ops.c:4085 utils/adt/int.c:719 -#: utils/adt/int.c:861 utils/adt/int.c:969 utils/adt/int.c:1058 -#: utils/adt/int.c:1097 utils/adt/int.c:1125 utils/adt/int8.c:597 -#: utils/adt/int8.c:657 utils/adt/int8.c:897 utils/adt/int8.c:1005 -#: utils/adt/int8.c:1094 utils/adt/int8.c:1202 utils/adt/numeric.c:6800 -#: utils/adt/numeric.c:7089 utils/adt/numeric.c:8090 -#: utils/adt/timestamp.c:3446 +#: utils/adt/cash.c:652 utils/adt/cash.c:702 utils/adt/cash.c:753 +#: utils/adt/cash.c:802 utils/adt/cash.c:854 utils/adt/cash.c:904 +#: utils/adt/int.c:824 utils/adt/int.c:940 utils/adt/int.c:1020 +#: utils/adt/int.c:1082 utils/adt/int.c:1120 utils/adt/int.c:1148 +#: utils/adt/int8.c:595 utils/adt/int8.c:653 utils/adt/int8.c:853 +#: utils/adt/int8.c:933 utils/adt/int8.c:995 utils/adt/int8.c:1075 +#: utils/adt/numeric.c:7248 utils/adt/numeric.c:7537 utils/adt/numeric.c:8549 +#: utils/adt/timestamp.c:3279 #, c-format msgid "division by zero" msgstr "除以零" @@ -18977,216 +20694,184 @@ msgstr "除以零" msgid "\"char\" out of range" msgstr "\"char\" 超出范围" -#: utils/adt/date.c:67 utils/adt/timestamp.c:94 utils/adt/varbit.c:52 -#: utils/adt/varchar.c:45 +#: utils/adt/date.c:65 utils/adt/timestamp.c:95 utils/adt/varbit.c:55 +#: utils/adt/varchar.c:49 #, c-format msgid "invalid type modifier" msgstr "无效的类型修改器" -#: utils/adt/date.c:72 +#: utils/adt/date.c:77 #, c-format msgid "TIME(%d)%s precision must not be negative" msgstr "TIME(%d)%s 精确度ä¸èƒ½ä¸ºè´Ÿæ•°" -#: utils/adt/date.c:78 +#: utils/adt/date.c:83 #, c-format msgid "TIME(%d)%s precision reduced to maximum allowed, %d" msgstr "TIME(%d)%s精度å‡å°‘到最大å…许值,%d" -#: utils/adt/date.c:141 utils/adt/datetime.c:1277 utils/adt/datetime.c:2148 +#: utils/adt/date.c:144 utils/adt/datetime.c:1192 utils/adt/datetime.c:2103 #, c-format msgid "date/time value \"current\" is no longer supported" msgstr "日期/时间值 \"current\" ä¸å†è¢«æ”¯æŒäº†" -#: utils/adt/date.c:167 utils/adt/date.c:175 utils/adt/formatting.c:3535 -#: utils/adt/formatting.c:3544 +#: utils/adt/date.c:170 utils/adt/date.c:178 utils/adt/formatting.c:3733 +#: utils/adt/formatting.c:3742 #, c-format msgid "date out of range: \"%s\"" msgstr "时间戳超出范围: \"%s\"" -#: utils/adt/date.c:222 utils/adt/date.c:456 utils/adt/date.c:480 -#: utils/adt/xml.c:2029 +#: utils/adt/date.c:225 utils/adt/date.c:537 utils/adt/date.c:561 +#: utils/adt/xml.c:2228 #, c-format msgid "date out of range" msgstr "日期超出范围" -#: utils/adt/date.c:264 utils/adt/timestamp.c:593 +#: utils/adt/date.c:271 utils/adt/timestamp.c:575 #, c-format msgid "date field value out of range: %d-%02d-%02d" msgstr "日期字段值超出范围: %d-%02d-%02d" -#: utils/adt/date.c:271 utils/adt/date.c:280 utils/adt/timestamp.c:599 +#: utils/adt/date.c:278 utils/adt/date.c:287 utils/adt/timestamp.c:581 #, c-format msgid "date out of range: %d-%02d-%02d" msgstr "日期超出范围: %d-%02d-%02d" -#: utils/adt/date.c:431 -#, c-format -msgid "cannot subtract infinite dates" -msgstr "无法å‡åŽ»æ— é™å¤§çš„æ—¥æœŸ" - -#: utils/adt/date.c:509 utils/adt/date.c:544 utils/adt/date.c:566 -#: utils/adt/date.c:2629 utils/adt/date.c:2643 -#, c-format -msgid "date out of range for timestamp" -msgstr "日期超出了时间戳的范围" - -#: utils/adt/date.c:1022 utils/adt/date.c:1068 utils/adt/date.c:1678 -#: utils/adt/date.c:1714 utils/adt/date.c:1748 utils/adt/date.c:2592 -#: utils/adt/formatting.c:3410 utils/adt/formatting.c:3442 -#: utils/adt/formatting.c:3510 utils/adt/json.c:1534 utils/adt/json.c:1556 -#: utils/adt/jsonb.c:823 utils/adt/jsonb.c:847 utils/adt/nabstime.c:455 -#: utils/adt/nabstime.c:498 utils/adt/nabstime.c:528 utils/adt/nabstime.c:571 -#: utils/adt/timestamp.c:224 utils/adt/timestamp.c:268 -#: utils/adt/timestamp.c:726 utils/adt/timestamp.c:735 -#: utils/adt/timestamp.c:820 utils/adt/timestamp.c:860 -#: utils/adt/timestamp.c:3021 utils/adt/timestamp.c:3042 -#: utils/adt/timestamp.c:3055 utils/adt/timestamp.c:3064 -#: utils/adt/timestamp.c:3072 utils/adt/timestamp.c:3127 -#: utils/adt/timestamp.c:3150 utils/adt/timestamp.c:3163 -#: utils/adt/timestamp.c:3174 utils/adt/timestamp.c:3182 -#: utils/adt/timestamp.c:3756 utils/adt/timestamp.c:3885 -#: utils/adt/timestamp.c:3926 utils/adt/timestamp.c:4014 -#: utils/adt/timestamp.c:4060 utils/adt/timestamp.c:4171 -#: utils/adt/timestamp.c:4578 utils/adt/timestamp.c:4694 -#: utils/adt/timestamp.c:4704 utils/adt/timestamp.c:4800 -#: utils/adt/timestamp.c:4919 utils/adt/timestamp.c:4929 -#: utils/adt/timestamp.c:5250 utils/adt/timestamp.c:5264 -#: utils/adt/timestamp.c:5269 utils/adt/timestamp.c:5283 -#: utils/adt/timestamp.c:5366 utils/adt/timestamp.c:5398 -#: utils/adt/timestamp.c:5405 utils/adt/timestamp.c:5431 -#: utils/adt/timestamp.c:5435 utils/adt/timestamp.c:5504 -#: utils/adt/timestamp.c:5508 utils/adt/timestamp.c:5522 -#: utils/adt/timestamp.c:5560 utils/adt/xml.c:2051 utils/adt/xml.c:2058 -#: utils/adt/xml.c:2078 utils/adt/xml.c:2085 +#: utils/adt/date.c:325 utils/adt/date.c:348 utils/adt/date.c:374 +#: utils/adt/date.c:1118 utils/adt/date.c:1164 utils/adt/date.c:1665 +#: utils/adt/date.c:1696 utils/adt/date.c:1725 utils/adt/date.c:2557 +#: utils/adt/datetime.c:1676 utils/adt/formatting.c:3599 +#: utils/adt/formatting.c:3631 utils/adt/formatting.c:3708 +#: utils/adt/json.c:1621 utils/adt/json.c:1641 utils/adt/timestamp.c:230 +#: utils/adt/timestamp.c:262 utils/adt/timestamp.c:703 +#: utils/adt/timestamp.c:712 utils/adt/timestamp.c:790 +#: utils/adt/timestamp.c:823 utils/adt/timestamp.c:2858 +#: utils/adt/timestamp.c:2879 utils/adt/timestamp.c:2892 +#: utils/adt/timestamp.c:2901 utils/adt/timestamp.c:2909 +#: utils/adt/timestamp.c:2964 utils/adt/timestamp.c:2987 +#: utils/adt/timestamp.c:3000 utils/adt/timestamp.c:3011 +#: utils/adt/timestamp.c:3019 utils/adt/timestamp.c:3679 +#: utils/adt/timestamp.c:3804 utils/adt/timestamp.c:3845 +#: utils/adt/timestamp.c:3935 utils/adt/timestamp.c:3979 +#: utils/adt/timestamp.c:4082 utils/adt/timestamp.c:4566 +#: utils/adt/timestamp.c:4665 utils/adt/timestamp.c:4675 +#: utils/adt/timestamp.c:4767 utils/adt/timestamp.c:4869 +#: utils/adt/timestamp.c:4879 utils/adt/timestamp.c:5099 +#: utils/adt/timestamp.c:5113 utils/adt/timestamp.c:5118 +#: utils/adt/timestamp.c:5132 utils/adt/timestamp.c:5165 +#: utils/adt/timestamp.c:5214 utils/adt/timestamp.c:5221 +#: utils/adt/timestamp.c:5254 utils/adt/timestamp.c:5258 +#: utils/adt/timestamp.c:5327 utils/adt/timestamp.c:5331 +#: utils/adt/timestamp.c:5345 utils/adt/timestamp.c:5379 utils/adt/xml.c:2250 +#: utils/adt/xml.c:2257 utils/adt/xml.c:2277 utils/adt/xml.c:2284 #, c-format msgid "timestamp out of range" msgstr "时间戳超出范围" -#: utils/adt/date.c:1094 +#: utils/adt/date.c:512 #, c-format -msgid "cannot convert reserved abstime value to date" -msgstr "ä¸èƒ½è½¬æ¢ä¿ç•™ abstime 值为 date" +msgid "cannot subtract infinite dates" +msgstr "无法å‡åŽ»æ— é™å¤§çš„æ—¥æœŸ" -#: utils/adt/date.c:1112 utils/adt/date.c:1118 +#: utils/adt/date.c:590 utils/adt/date.c:621 utils/adt/date.c:639 +#: utils/adt/date.c:2594 utils/adt/date.c:2604 #, c-format -#| msgid "date out of range for timestamp" -msgid "abstime out of range for date" -msgstr "abstime 超过了日期范围" +msgid "date out of range for timestamp" +msgstr "日期超出了时间戳的范围" -#: utils/adt/date.c:1258 utils/adt/date.c:1265 utils/adt/date.c:2082 -#: utils/adt/date.c:2089 +#: utils/adt/date.c:1278 utils/adt/date.c:2052 #, c-format msgid "time out of range" msgstr "时间超出范围" -#: utils/adt/date.c:1326 utils/adt/timestamp.c:618 +#: utils/adt/date.c:1334 utils/adt/timestamp.c:600 #, c-format msgid "time field value out of range: %d:%02d:%02g" msgstr "日期/时间值超出范围: %d:%02d:%02g" -#: utils/adt/date.c:1960 utils/adt/date.c:1977 +#: utils/adt/date.c:1854 utils/adt/date.c:2356 utils/adt/float.c:1046 +#: utils/adt/float.c:1115 utils/adt/int.c:616 utils/adt/int.c:663 +#: utils/adt/int.c:698 utils/adt/int8.c:494 utils/adt/numeric.c:2203 +#: utils/adt/timestamp.c:3328 utils/adt/timestamp.c:3359 +#: utils/adt/timestamp.c:3390 +#, c-format +msgid "invalid preceding or following size in window function" +msgstr "窗å£å‡½æ•°ä¸­çš„å‰å¯¼æˆ–åŽå¯¼å¤§å°æ— æ•ˆ" + +#: utils/adt/date.c:1939 utils/adt/date.c:1952 #, c-format msgid "\"time\" units \"%s\" not recognized" msgstr "\"time\" å•ä½ \"%s\" ä¸è¢«è®¤å¯" -#: utils/adt/date.c:2098 +#: utils/adt/date.c:2060 #, c-format msgid "time zone displacement out of range" msgstr "时间区域置æ¢è¶…出范围" -#: utils/adt/date.c:2740 utils/adt/date.c:2757 +#: utils/adt/date.c:2689 utils/adt/date.c:2702 #, c-format msgid "\"time with time zone\" units \"%s\" not recognized" msgstr "\"time with time zone\" å•ä½ \"%s\" ä¸è¢«è®¤å¯" -#: utils/adt/date.c:2830 utils/adt/datetime.c:994 utils/adt/datetime.c:1874 -#: utils/adt/datetime.c:4700 utils/adt/timestamp.c:532 -#: utils/adt/timestamp.c:559 utils/adt/timestamp.c:5275 -#: utils/adt/timestamp.c:5514 +#: utils/adt/date.c:2775 utils/adt/datetime.c:914 utils/adt/datetime.c:1834 +#: utils/adt/datetime.c:4631 utils/adt/timestamp.c:514 +#: utils/adt/timestamp.c:541 utils/adt/timestamp.c:4165 +#: utils/adt/timestamp.c:5124 utils/adt/timestamp.c:5337 #, c-format msgid "time zone \"%s\" not recognized" msgstr "时区 \"%s\" ä¸è¢«è®¤å¯" -#: utils/adt/date.c:2870 utils/adt/timestamp.c:5351 utils/adt/timestamp.c:5545 +#: utils/adt/date.c:2807 utils/adt/timestamp.c:5154 utils/adt/timestamp.c:5368 #, c-format msgid "interval time zone \"%s\" must not include months or days" msgstr "间隔时区\"%s\"ä¸èƒ½åŒ…嫿œˆæˆ–天" -#: utils/adt/datetime.c:1749 -#, c-format -msgid "time zone abbreviation \"%s\" is not used in time zone \"%s\"" -msgstr "时区缩写\"%s\"ä¸èƒ½ç”¨äºŽæ—¶åŒº\"%s\"" - -#: utils/adt/datetime.c:3835 utils/adt/datetime.c:3842 +#: utils/adt/datetime.c:3760 utils/adt/datetime.c:3767 #, c-format msgid "date/time field value out of range: \"%s\"" msgstr "日期/时间值超出范围: \"%s\"" -#: utils/adt/datetime.c:3844 +#: utils/adt/datetime.c:3769 #, c-format msgid "Perhaps you need a different \"datestyle\" setting." msgstr "也许你需è¦ä¸åŒçš„ \"datesytle\" 设置." -#: utils/adt/datetime.c:3849 +#: utils/adt/datetime.c:3774 #, c-format msgid "interval field value out of range: \"%s\"" msgstr "间隔字段超出范围: \"%s\"" -#: utils/adt/datetime.c:3855 +#: utils/adt/datetime.c:3780 #, c-format msgid "time zone displacement out of range: \"%s\"" msgstr "时间区域置æ¢è¶…出范围: \"%s\"" -#. translator: first %s is inet or cidr -#: utils/adt/datetime.c:3862 utils/adt/float.c:454 utils/adt/float.c:537 -#: utils/adt/float.c:563 utils/adt/geo_ops.c:156 utils/adt/geo_ops.c:166 -#: utils/adt/geo_ops.c:178 utils/adt/geo_ops.c:210 utils/adt/geo_ops.c:255 -#: utils/adt/geo_ops.c:265 utils/adt/geo_ops.c:935 utils/adt/geo_ops.c:1321 -#: utils/adt/geo_ops.c:1356 utils/adt/geo_ops.c:1364 utils/adt/geo_ops.c:3422 -#: utils/adt/geo_ops.c:4555 utils/adt/geo_ops.c:4571 utils/adt/geo_ops.c:4578 -#: utils/adt/network.c:58 -#, c-format -msgid "invalid input syntax for type %s: \"%s\"" -msgstr "无效的类型 %s 输入语法: \"%s\"" - -#: utils/adt/datetime.c:4702 +#: utils/adt/datetime.c:4633 #, c-format -msgid "" -"This time zone name appears in the configuration file for time zone " -"abbreviation \"%s\"." +msgid "This time zone name appears in the configuration file for time zone abbreviation \"%s\"." msgstr "缩写时区 \"%s\"对应的时区å出现在é…置文件中." -#: utils/adt/datum.c:86 utils/adt/datum.c:98 +#: utils/adt/datum.c:88 utils/adt/datum.c:100 #, c-format msgid "invalid Datum pointer" msgstr "无效的 Datum 指针" -#: utils/adt/dbsize.c:110 -#, c-format -msgid "could not open tablespace directory \"%s\": %m" -msgstr "无法打开表空间目录 \"%s\": %m" - -#: utils/adt/dbsize.c:757 utils/adt/dbsize.c:776 utils/adt/dbsize.c:828 +#: utils/adt/dbsize.c:759 utils/adt/dbsize.c:827 #, c-format -#| msgid "invalid cidr value: \"%s\"" msgid "invalid size: \"%s\"" msgstr "无效的尺寸: \"%s\"" -#: utils/adt/dbsize.c:829 +#: utils/adt/dbsize.c:828 #, c-format -#| msgid "invalid time zone name: \"%s\"" msgid "Invalid size unit: \"%s\"." msgstr "无效的尺寸å•ä½: \"%s\"." -#: utils/adt/dbsize.c:830 +#: utils/adt/dbsize.c:829 #, c-format -#| msgid "" -#| "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." msgid "Valid units are \"bytes\", \"kB\", \"MB\", \"GB\", and \"TB\"." msgstr "有效的å•使˜¯ \"bytes\"ã€\"kB\"ã€\"MB\"ã€\"GB\" ä»¥åŠ \"TB\"。" -#: utils/adt/domains.c:85 +#: utils/adt/domains.c:92 #, c-format msgid "type %s is not a domain" msgstr "类型%s䏿˜¯ä¸€ä¸ªåŸŸ" @@ -19226,1874 +20911,1871 @@ msgstr "无效base64结æŸåºåˆ—" msgid "Input data is missing padding, is truncated, or is otherwise corrupted." msgstr "输入数æ®ç¼ºå°‘填充,或者已ç»è¢«æˆªæ–­ï¼Œåˆæˆ–者已被æŸå。" -#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/varlena.c:297 -#: utils/adt/varlena.c:338 +#: utils/adt/encode.c:442 utils/adt/encode.c:507 utils/adt/json.c:786 +#: utils/adt/json.c:826 utils/adt/json.c:842 utils/adt/json.c:854 +#: utils/adt/json.c:864 utils/adt/json.c:915 utils/adt/json.c:947 +#: utils/adt/json.c:966 utils/adt/json.c:978 utils/adt/json.c:990 +#: utils/adt/json.c:1135 utils/adt/json.c:1149 utils/adt/json.c:1160 +#: utils/adt/json.c:1168 utils/adt/json.c:1176 utils/adt/json.c:1184 +#: utils/adt/json.c:1192 utils/adt/json.c:1200 utils/adt/json.c:1208 +#: utils/adt/json.c:1216 utils/adt/json.c:1246 utils/adt/varlena.c:318 +#: utils/adt/varlena.c:359 jsonpath_gram.y:516 jsonpath_scan.l:543 +#: jsonpath_scan.l:559 jsonpath_scan.l:570 jsonpath_scan.l:580 +#: jsonpath_scan.l:622 +#, c-format +msgid "invalid input syntax for type %s" +msgstr "类型%s的输入语法无效" + +#: utils/adt/enum.c:100 #, c-format -msgid "invalid input syntax for type bytea" -msgstr "无效的 bytea 类型输入语法" +msgid "unsafe use of new value \"%s\" of enum type %s" +msgstr "" + +#: utils/adt/enum.c:103 +#, c-format +msgid "New enum values must be committed before they can be used." +msgstr "" -#: utils/adt/enum.c:48 utils/adt/enum.c:58 utils/adt/enum.c:113 -#: utils/adt/enum.c:123 +#: utils/adt/enum.c:121 utils/adt/enum.c:131 utils/adt/enum.c:189 +#: utils/adt/enum.c:199 #, c-format msgid "invalid input value for enum %s: \"%s\"" msgstr "对于枚举%s的输入值无效: \"%s\"" -#: utils/adt/enum.c:85 utils/adt/enum.c:148 utils/adt/enum.c:198 +#: utils/adt/enum.c:161 utils/adt/enum.c:227 utils/adt/enum.c:286 #, c-format msgid "invalid internal value for enum: %u" msgstr "对于枚举的无效内部值: %u" -#: utils/adt/enum.c:356 utils/adt/enum.c:385 utils/adt/enum.c:425 -#: utils/adt/enum.c:445 +#: utils/adt/enum.c:446 utils/adt/enum.c:475 utils/adt/enum.c:515 +#: utils/adt/enum.c:535 #, c-format msgid "could not determine actual enum type" msgstr "无法确定实际的枚举类型" -#: utils/adt/enum.c:364 utils/adt/enum.c:393 +#: utils/adt/enum.c:454 utils/adt/enum.c:483 #, c-format msgid "enum %s contains no values" msgstr "枚举 \"%s\" 没有值" -#: utils/adt/float.c:58 +#: utils/adt/expandedrecord.c:98 utils/adt/expandedrecord.c:230 +#: utils/cache/typcache.c:1574 utils/cache/typcache.c:1730 +#: utils/cache/typcache.c:1860 utils/fmgr/funcapi.c:415 #, c-format -msgid "value out of range: overflow" -msgstr "值超出范围: 上溢" - -#: utils/adt/float.c:63 -#, c-format -msgid "value out of range: underflow" -msgstr "值超出范围: 下溢" - -#: utils/adt/float.c:237 utils/adt/float.c:311 utils/adt/float.c:335 -#, c-format -msgid "invalid input syntax for type real: \"%s\"" -msgstr "无效的实数类型输入语法: \"%s\"" +msgid "type %s is not composite" +msgstr "类型 %s 䏿˜¯å¤åˆç±»åž‹" -#: utils/adt/float.c:305 +#: utils/adt/float.c:246 #, c-format msgid "\"%s\" is out of range for type real" msgstr "\"%s\" 超出实数类型的范围" -#: utils/adt/float.c:530 +#: utils/adt/float.c:466 #, c-format msgid "\"%s\" is out of range for type double precision" msgstr "\"%s\" 超出åŒç²¾åº¦ç±»åž‹çš„范围" -#: utils/adt/float.c:1239 utils/adt/float.c:1297 utils/adt/int.c:349 -#: utils/adt/int.c:775 utils/adt/int.c:804 utils/adt/int.c:825 -#: utils/adt/int.c:845 utils/adt/int.c:879 utils/adt/int.c:1174 -#: utils/adt/int8.c:1323 utils/adt/numeric.c:3004 utils/adt/numeric.c:3013 +#: utils/adt/float.c:1252 utils/adt/float.c:1340 utils/adt/int.c:336 +#: utils/adt/int.c:874 utils/adt/int.c:896 utils/adt/int.c:910 +#: utils/adt/int.c:924 utils/adt/int.c:956 utils/adt/int.c:1194 +#: utils/adt/int8.c:1188 utils/adt/numeric.c:3358 utils/adt/numeric.c:3367 #, c-format msgid "smallint out of range" msgstr "smallint 超出范围" -#: utils/adt/float.c:1423 utils/adt/numeric.c:7522 +#: utils/adt/float.c:1466 utils/adt/numeric.c:7970 #, c-format msgid "cannot take square root of a negative number" msgstr "无法为负数åšå¹³æ–¹æ ¹" -#: utils/adt/float.c:1465 utils/adt/numeric.c:2807 +#: utils/adt/float.c:1527 utils/adt/numeric.c:3138 #, c-format msgid "zero raised to a negative power is undefined" msgstr "被æå‡åˆ°è´Ÿä¹˜æ–¹çš„æœ€ä½Žç‚¹æ²¡æœ‰å®šä¹‰." -#: utils/adt/float.c:1469 utils/adt/numeric.c:2813 +#: utils/adt/float.c:1531 utils/adt/numeric.c:3144 #, c-format msgid "a negative number raised to a non-integer power yields a complex result" msgstr "被å‡ä¸ºéžæ•´æ•°çš„å¹³æ–¹çš„è´Ÿæ•°äº§ç”Ÿäº†ä¸€ä¸ªå¤æ‚结果." -#: utils/adt/float.c:1535 utils/adt/float.c:1565 utils/adt/numeric.c:7787 +#: utils/adt/float.c:1597 utils/adt/float.c:1627 utils/adt/numeric.c:8236 #, c-format msgid "cannot take logarithm of zero" msgstr "无法å–零的对数" -#: utils/adt/float.c:1539 utils/adt/float.c:1569 utils/adt/numeric.c:7791 +#: utils/adt/float.c:1601 utils/adt/float.c:1631 utils/adt/numeric.c:8240 #, c-format msgid "cannot take logarithm of a negative number" msgstr "无法å–负数的对数" -#: utils/adt/float.c:1599 utils/adt/float.c:1629 utils/adt/float.c:1721 -#: utils/adt/float.c:1747 utils/adt/float.c:1774 utils/adt/float.c:1800 -#: utils/adt/float.c:1922 utils/adt/float.c:1957 utils/adt/float.c:2110 -#: utils/adt/float.c:2163 utils/adt/float.c:2226 utils/adt/float.c:2280 +#: utils/adt/float.c:1661 utils/adt/float.c:1691 utils/adt/float.c:1783 +#: utils/adt/float.c:1809 utils/adt/float.c:1836 utils/adt/float.c:1862 +#: utils/adt/float.c:2009 utils/adt/float.c:2044 utils/adt/float.c:2208 +#: utils/adt/float.c:2262 utils/adt/float.c:2326 utils/adt/float.c:2381 +#: utils/adt/float.c:2569 utils/adt/float.c:2594 #, c-format msgid "input is out of range" msgstr "输入超出范围" -#: utils/adt/float.c:3485 utils/adt/numeric.c:1447 +#: utils/adt/float.c:2662 +#, c-format +msgid "setseed parameter %g is out of allowed range [-1,1]" +msgstr "" + +#: utils/adt/float.c:2880 utils/adt/float.c:2956 utils/adt/float.c:3179 +#, c-format +msgid "value out of range: overflow" +msgstr "值超出范围: 上溢" + +#: utils/adt/float.c:3861 utils/adt/numeric.c:1515 #, c-format msgid "count must be greater than zero" msgstr "总数必须大于零" -#: utils/adt/float.c:3490 utils/adt/numeric.c:1454 +#: utils/adt/float.c:3866 utils/adt/numeric.c:1522 #, c-format msgid "operand, lower bound, and upper bound cannot be NaN" msgstr "æ“作数,下é™å’Œä¸Šé™ä¸èƒ½æ˜¯NaN" -#: utils/adt/float.c:3496 +#: utils/adt/float.c:3872 #, c-format msgid "lower and upper bounds must be finite" msgstr "地ä½å’Œé«˜ä½è¾¹ç•Œå¿…须是有é™çš„." -#: utils/adt/float.c:3534 utils/adt/numeric.c:1467 +#: utils/adt/float.c:3906 utils/adt/numeric.c:1535 #, c-format msgid "lower bound cannot equal upper bound" msgstr "下é™ä¸èƒ½ç­‰äºŽä¸Šé™" -#: utils/adt/formatting.c:485 +#: utils/adt/formatting.c:504 #, c-format msgid "invalid format specification for an interval value" msgstr "间隔值的格å¼å®šä¹‰æ— æ•ˆ" -#: utils/adt/formatting.c:486 +#: utils/adt/formatting.c:505 #, c-format msgid "Intervals are not tied to specific calendar dates." msgstr "间隔没有与特定的日历的日期相è”ç³»" -#: utils/adt/formatting.c:1059 +#: utils/adt/formatting.c:1086 #, c-format msgid "\"EEEE\" must be the last pattern used" msgstr "\"EEEE\"必须是所使用的最åŽä¸€ä¸ªæ¨¡å¼" -#: utils/adt/formatting.c:1067 +#: utils/adt/formatting.c:1094 #, c-format msgid "\"9\" must be ahead of \"PR\"" msgstr "\"9\" 必须在 \"PR\" 之å‰" -#: utils/adt/formatting.c:1083 +#: utils/adt/formatting.c:1110 #, c-format msgid "\"0\" must be ahead of \"PR\"" msgstr "\"0\" 必须在 \"PR\" 之å‰" -#: utils/adt/formatting.c:1110 +#: utils/adt/formatting.c:1137 #, c-format msgid "multiple decimal points" msgstr "å¤šä¸ªå°æ•°ç‚¹" -#: utils/adt/formatting.c:1114 utils/adt/formatting.c:1197 +#: utils/adt/formatting.c:1141 utils/adt/formatting.c:1224 #, c-format msgid "cannot use \"V\" and decimal point together" msgstr "ä¸èƒ½ \"V\" å’Œå°æ•°ç‚¹ä¸€èµ·ä½¿ç”¨" -#: utils/adt/formatting.c:1126 +#: utils/adt/formatting.c:1153 #, c-format msgid "cannot use \"S\" twice" msgstr "无法两次使用 \"S\" " -#: utils/adt/formatting.c:1130 +#: utils/adt/formatting.c:1157 #, c-format msgid "cannot use \"S\" and \"PL\"/\"MI\"/\"SG\"/\"PR\" together" msgstr "\"S\" ä¸å¯ä»¥å’Œ \"PL\"/\"MI\"/\"SG\"/\"PR\" 一起使用" -#: utils/adt/formatting.c:1150 +#: utils/adt/formatting.c:1177 #, c-format msgid "cannot use \"S\" and \"MI\" together" msgstr "\"S\" ä¸å¯ä»¥å’Œ \"MI\" 一起使用" -#: utils/adt/formatting.c:1160 +#: utils/adt/formatting.c:1187 #, c-format msgid "cannot use \"S\" and \"PL\" together" msgstr "\"S\" ä¸å¯ä»¥å’Œ \"PL\" 一起使用" -#: utils/adt/formatting.c:1170 +#: utils/adt/formatting.c:1197 #, c-format msgid "cannot use \"S\" and \"SG\" together" msgstr "\"S\" ä¸å¯ä»¥å’Œ \"SG\" 一起使用" -#: utils/adt/formatting.c:1179 +#: utils/adt/formatting.c:1206 #, c-format msgid "cannot use \"PR\" and \"S\"/\"PL\"/\"MI\"/\"SG\" together" msgstr "\"PR\" ä¸å¯ä»¥å’Œ \"S\"/\"PL\"/\"MI\"/\"SG\" 一起使用" -#: utils/adt/formatting.c:1205 +#: utils/adt/formatting.c:1232 #, c-format msgid "cannot use \"EEEE\" twice" msgstr "无法两次使用 \"EEEE\"" -#: utils/adt/formatting.c:1211 +#: utils/adt/formatting.c:1238 #, c-format msgid "\"EEEE\" is incompatible with other formats" msgstr "\"EEEE\"与其它格å¼ä¸å…¼å®¹" -#: utils/adt/formatting.c:1212 +#: utils/adt/formatting.c:1239 #, c-format -msgid "" -"\"EEEE\" may only be used together with digit and decimal point patterns." +msgid "\"EEEE\" may only be used together with digit and decimal point patterns." msgstr "\"EEEE\"åªèƒ½ä¸Žæ•°å­—å’Œå°æ•°æ¨¡å¼ä¸€åŒä½¿ç”¨" -#: utils/adt/formatting.c:1412 +#: utils/adt/formatting.c:1426 #, c-format msgid "\"%s\" is not a number" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªæ•°å­—" -#: utils/adt/formatting.c:1513 utils/adt/formatting.c:1565 -#, c-format -msgid "could not determine which collation to use for lower() function" -msgstr "无法确定函数lower()使用哪个排åºè§„则" - -#: utils/adt/formatting.c:1633 utils/adt/formatting.c:1685 +#: utils/adt/formatting.c:1504 #, c-format -msgid "could not determine which collation to use for upper() function" -msgstr "无法确定函数upper()使用哪个排åºè§„则" +msgid "case conversion failed: %s" +msgstr "case转æ¢å¤±è´¥: %s" -#: utils/adt/formatting.c:1754 utils/adt/formatting.c:1818 -#, c-format -msgid "could not determine which collation to use for initcap() function" -msgstr "无法确定函数initcap()使用哪个排åºè§„则" +#: utils/adt/formatting.c:1569 utils/adt/formatting.c:1692 +#: utils/adt/formatting.c:1816 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for lower() function" +msgid "could not determine which collation to use for %s function" +msgstr "无法确定函数lower()使用哪个排åºè§„则" # fe-connect.c:2558 -#: utils/adt/formatting.c:2122 +#: utils/adt/formatting.c:2185 #, c-format msgid "invalid combination of date conventions" msgstr "无效的日期约定格å¼ç»„åˆ" -#: utils/adt/formatting.c:2123 +#: utils/adt/formatting.c:2186 #, c-format -msgid "" -"Do not mix Gregorian and ISO week date conventions in a formatting template." +msgid "Do not mix Gregorian and ISO week date conventions in a formatting template." msgstr "åœ¨æ ¼å¼æ¨¡æ¿ä¸­ä¸è¦æ··ç”¨Gregorianå’ŒISO周日期转æ¢. " -#: utils/adt/formatting.c:2140 +#: utils/adt/formatting.c:2203 #, c-format msgid "conflicting values for \"%s\" field in formatting string" msgstr "在格å¼åŒ–字符串中对于\"%s\"字段的值冲çª" -#: utils/adt/formatting.c:2142 +#: utils/adt/formatting.c:2205 #, c-format msgid "This value contradicts a previous setting for the same field type." msgstr "这个值与先å‰è®¾å®šçš„åŒä¸€å­—段类型相抵触" -#: utils/adt/formatting.c:2203 +#: utils/adt/formatting.c:2266 #, c-format msgid "source string too short for \"%s\" formatting field" msgstr "对于\"%s\" æ ¼å¼åŒ–字段的æºå­—符串太短" -#: utils/adt/formatting.c:2205 +#: utils/adt/formatting.c:2268 #, c-format msgid "Field requires %d characters, but only %d remain." msgstr "å­—æ®µè¦æ±‚有%d个字符,ä½†æ˜¯è¿™é‡Œåªæœ‰%d个" -#: utils/adt/formatting.c:2208 utils/adt/formatting.c:2222 +#: utils/adt/formatting.c:2271 utils/adt/formatting.c:2285 #, c-format -msgid "" -"If your source string is not fixed-width, try using the \"FM\" modifier." +msgid "If your source string is not fixed-width, try using the \"FM\" modifier." msgstr "如果æºå­—ç¬¦ä¸²ä¸æ˜¯å›ºå®šé•¿åº¦,请å°è¯•使用\"FM\"修改器." -#: utils/adt/formatting.c:2218 utils/adt/formatting.c:2231 -#: utils/adt/formatting.c:2361 +#: utils/adt/formatting.c:2281 utils/adt/formatting.c:2294 +#: utils/adt/formatting.c:2424 #, c-format msgid "invalid value \"%s\" for \"%s\"" msgstr "\"%s\"的值\"%s\"无效" -#: utils/adt/formatting.c:2220 +#: utils/adt/formatting.c:2283 #, c-format msgid "Field requires %d characters, but only %d could be parsed." msgstr "å­—æ®µè¦æ±‚%d个字符, 但是åªèƒ½è§£æž%d个字符." -#: utils/adt/formatting.c:2233 +#: utils/adt/formatting.c:2296 #, c-format msgid "Value must be an integer." msgstr "值必须是一个整数" -#: utils/adt/formatting.c:2238 +#: utils/adt/formatting.c:2301 #, c-format msgid "value for \"%s\" in source string is out of range" msgstr "在æºå­—符串中\"%s\"的值超出了范围" -#: utils/adt/formatting.c:2240 +#: utils/adt/formatting.c:2303 #, c-format msgid "Value must be in the range %d to %d." msgstr "值必须是在范围%d到%d之间." -#: utils/adt/formatting.c:2363 +#: utils/adt/formatting.c:2426 #, c-format msgid "The given value did not match any of the allowed values for this field." msgstr "给定的值与这个字段所å…许的值ä¸åŒ¹é…." -#: utils/adt/formatting.c:2558 utils/adt/formatting.c:2578 -#: utils/adt/formatting.c:2598 utils/adt/formatting.c:2618 -#: utils/adt/formatting.c:2637 utils/adt/formatting.c:2656 -#: utils/adt/formatting.c:2680 utils/adt/formatting.c:2698 -#: utils/adt/formatting.c:2716 utils/adt/formatting.c:2734 -#: utils/adt/formatting.c:2751 utils/adt/formatting.c:2768 +#: utils/adt/formatting.c:2624 utils/adt/formatting.c:2644 +#: utils/adt/formatting.c:2664 utils/adt/formatting.c:2684 +#: utils/adt/formatting.c:2703 utils/adt/formatting.c:2722 +#: utils/adt/formatting.c:2746 utils/adt/formatting.c:2764 +#: utils/adt/formatting.c:2782 utils/adt/formatting.c:2800 +#: utils/adt/formatting.c:2817 utils/adt/formatting.c:2834 #, c-format msgid "localized string format value too long" msgstr "本地化字符串格å¼å€¼å¤ªé•¿" -#: utils/adt/formatting.c:3055 +#: utils/adt/formatting.c:3176 #, c-format -msgid "\"TZ\"/\"tz\"/\"OF\" format patterns are not supported in to_date" -msgstr "在to_date䏭䏿”¯æŒ\"TZ\"/\"tz\"/\"OF\"çš„æ ¼å¼æ¨¡å¼" +msgid "formatting field \"%s\" is only supported in to_char" +msgstr "åªæœ‰åœ¨to_charä¸­æ‰æ”¯æŒæ ¼å¼åŒ–字段\"%s\"" -#: utils/adt/formatting.c:3163 +#: utils/adt/formatting.c:3317 #, c-format msgid "invalid input string for \"Y,YYY\"" msgstr "对于\"Y,YYY\", 所输入的字符串无效" -#: utils/adt/formatting.c:3674 +#: utils/adt/formatting.c:3851 #, c-format msgid "hour \"%d\" is invalid for the 12-hour clock" msgstr "对于12å°æ—¶åˆ¶çš„é’Ÿè¡¨ï¼Œå°æ—¶æ•°\"%d\"无效" -#: utils/adt/formatting.c:3676 +#: utils/adt/formatting.c:3853 #, c-format msgid "Use the 24-hour clock, or give an hour between 1 and 12." msgstr "使用24å°æ—¶åˆ¶çš„钟表,æˆ–è€…å°†å°æ—¶æ•°é™å®šåœ¨1到12之间." -#: utils/adt/formatting.c:3771 +#: utils/adt/formatting.c:3959 #, c-format msgid "cannot calculate day of year without year information" msgstr "æ²¡æœ‰å¹´ä»½ä¿¡æ¯æ— æ³•计算年的天数" -#: utils/adt/formatting.c:4620 +#: utils/adt/formatting.c:4866 #, c-format msgid "\"EEEE\" not supported for input" msgstr "䏿”¯æŒä¸ºè¾“入使用\"EEEE\"" -#: utils/adt/formatting.c:4632 +#: utils/adt/formatting.c:4878 #, c-format msgid "\"RN\" not supported for input" msgstr "䏿”¯æŒä¸ºè¾“入使用\"RN\"" -#: utils/adt/genfile.c:62 +#: utils/adt/genfile.c:81 #, c-format msgid "reference to parent directory (\"..\") not allowed" msgstr "ä¸å…许引用æºç›®å½•(\"..\") " -#: utils/adt/genfile.c:73 +#: utils/adt/genfile.c:92 #, c-format msgid "absolute path not allowed" msgstr "ä¸å…许使用ç»å¯¹è·¯å¾„" -#: utils/adt/genfile.c:78 +#: utils/adt/genfile.c:97 #, c-format msgid "path must be in or below the current directory" msgstr "路径必须在当å‰ç›®å½•或其å­ç›®å½•下" -#: utils/adt/genfile.c:125 utils/adt/oracle_compat.c:184 -#: utils/adt/oracle_compat.c:282 utils/adt/oracle_compat.c:758 -#: utils/adt/oracle_compat.c:1059 +#: utils/adt/genfile.c:144 utils/adt/oracle_compat.c:185 +#: utils/adt/oracle_compat.c:283 utils/adt/oracle_compat.c:759 +#: utils/adt/oracle_compat.c:1054 #, c-format msgid "requested length too large" msgstr "请求长度太大" -#: utils/adt/genfile.c:142 +#: utils/adt/genfile.c:161 #, c-format msgid "could not seek in file \"%s\": %m" msgstr "无法在文件\"%s\"进行查找: %m" -#: utils/adt/genfile.c:200 utils/adt/genfile.c:241 -#, c-format -msgid "must be superuser to read files" -msgstr "åªæœ‰è¶…级用户能对文件进行读æ“作" - -#: utils/adt/genfile.c:318 -#, c-format -msgid "must be superuser to get file information" -msgstr "åªæœ‰è¶…级用户æ‰èƒ½èŽ·å–æ–‡ä»¶ä¿¡æ¯" - -#: utils/adt/genfile.c:404 +#: utils/adt/genfile.c:221 #, c-format -msgid "must be superuser to get directory listings" -msgstr "åªæœ‰è¶…级用户æ‰èƒ½èŽ·å–目录列表" +msgid "must be superuser to read files with adminpack 1.0" +msgstr "必须是超级用户æ‰èƒ½ä½¿ç”¨adminpack 1.0è¯»å–æ–‡ä»¶" -#: utils/adt/geo_ops.c:940 +#: utils/adt/geo_ops.c:979 utils/adt/geo_ops.c:1025 #, c-format msgid "invalid line specification: A and B cannot both be zero" msgstr "无效的行规格: Aå’ŒBä¸èƒ½åŒæ—¶ä¸º0" -#: utils/adt/geo_ops.c:948 +#: utils/adt/geo_ops.c:987 utils/adt/geo_ops.c:1090 #, c-format msgid "invalid line specification: must be two distinct points" msgstr "无效的线规格: 必须是两个ä¸åŒçš„点" -#: utils/adt/geo_ops.c:1342 utils/adt/geo_ops.c:3432 utils/adt/geo_ops.c:4245 -#: utils/adt/geo_ops.c:5173 +#: utils/adt/geo_ops.c:1399 utils/adt/geo_ops.c:3370 utils/adt/geo_ops.c:4238 +#: utils/adt/geo_ops.c:5129 #, c-format msgid "too many points requested" msgstr "è¦æ±‚了太多的点" -#: utils/adt/geo_ops.c:1404 +#: utils/adt/geo_ops.c:1461 #, c-format msgid "invalid number of points in external \"path\" value" msgstr "在外部 \"path\" å€¼ä¸­çš„ç‚¹æ•°é‡æ— æ•ˆ." -#: utils/adt/geo_ops.c:2555 +#: utils/adt/geo_ops.c:2459 #, c-format msgid "function \"dist_lb\" not implemented" msgstr "函数 \"dist_lb\" 没有实现" -#: utils/adt/geo_ops.c:3007 +#: utils/adt/geo_ops.c:2859 #, c-format msgid "function \"close_sl\" not implemented" msgstr "函数 \"close_sl\" 没有实现" -#: utils/adt/geo_ops.c:3109 +#: utils/adt/geo_ops.c:3006 #, c-format msgid "function \"close_lb\" not implemented" msgstr "函数 \"close_lb\" 没有实现" -#: utils/adt/geo_ops.c:3398 -#, c-format -msgid "cannot create bounding box for empty polygon" -msgstr "无法为空多边形创建 bounding box" - -#: utils/adt/geo_ops.c:3479 +#: utils/adt/geo_ops.c:3417 #, c-format msgid "invalid number of points in external \"polygon\" value" msgstr "在外部\"polygon\" å€¼ä¸­çš„ç‚¹æ•°é‡æ— æ•ˆ." -#: utils/adt/geo_ops.c:4004 +#: utils/adt/geo_ops.c:3953 #, c-format msgid "function \"poly_distance\" not implemented" msgstr "函数 \"poly_distance\" 没有实现" -#: utils/adt/geo_ops.c:4357 +#: utils/adt/geo_ops.c:4330 #, c-format msgid "function \"path_center\" not implemented" msgstr "函数 \"path_center\" 没有实现" -#: utils/adt/geo_ops.c:4374 +#: utils/adt/geo_ops.c:4347 #, c-format msgid "open path cannot be converted to polygon" msgstr "打开的路径ä¸èƒ½è½¬æ¢ä¸ºå¤šæ€åž‹" -#: utils/adt/geo_ops.c:4623 +#: utils/adt/geo_ops.c:4594 #, c-format msgid "invalid radius in external \"circle\" value" msgstr "在外部\"circle\" 值中的åŠå¾„无效" -#: utils/adt/geo_ops.c:5159 +#: utils/adt/geo_ops.c:5115 #, c-format msgid "cannot convert circle with radius zero to polygon" msgstr "无法将åŠå¾„为0的圆转æ¢ä¸ºå¤šè¾¹ç±»åž‹" -#: utils/adt/geo_ops.c:5164 +#: utils/adt/geo_ops.c:5120 #, c-format msgid "must request at least 2 points" msgstr "å¿…é¡»è¦æ±‚至少两个点." -#: utils/adt/geo_ops.c:5208 -#, c-format -msgid "cannot convert empty polygon to circle" -msgstr "无法转æ¢ç©ºçš„多边形到圆形" - -#: utils/adt/int.c:162 +#: utils/adt/int.c:164 #, c-format msgid "int2vector has too many elements" msgstr "int2vector 有太多的元素" -#: utils/adt/int.c:237 +#: utils/adt/int.c:239 #, c-format msgid "invalid int2vector data" msgstr "无效的int2vectoræ•°æ®" -#: utils/adt/int.c:243 utils/adt/oid.c:212 utils/adt/oid.c:293 +#: utils/adt/int.c:245 utils/adt/oid.c:215 utils/adt/oid.c:296 #, c-format msgid "oidvector has too many elements" msgstr "oidvector 有太多元素" -#: utils/adt/int.c:1362 utils/adt/int8.c:1460 utils/adt/numeric.c:1355 -#: utils/adt/timestamp.c:5611 utils/adt/timestamp.c:5692 +#: utils/adt/int.c:1383 utils/adt/int8.c:1328 utils/adt/numeric.c:1423 +#: utils/adt/timestamp.c:5430 utils/adt/timestamp.c:5511 #, c-format msgid "step size cannot equal zero" msgstr "啿­¥æ‰§è¡Œå¤§å°ä¸èƒ½ç­‰äºŽ0" -#: utils/adt/int8.c:98 utils/adt/int8.c:133 utils/adt/numutils.c:51 -#: utils/adt/numutils.c:61 utils/adt/numutils.c:103 -#, c-format -msgid "invalid input syntax for integer: \"%s\"" -msgstr "无效的整数类型输入语法: \"%s\"" - -#: utils/adt/int8.c:114 -#, c-format -msgid "value \"%s\" is out of range for type bigint" -msgstr "值 \"%s\" 超出 bigint 类型范围" - -#: utils/adt/int8.c:500 utils/adt/int8.c:529 utils/adt/int8.c:550 -#: utils/adt/int8.c:581 utils/adt/int8.c:615 utils/adt/int8.c:640 -#: utils/adt/int8.c:697 utils/adt/int8.c:714 utils/adt/int8.c:741 -#: utils/adt/int8.c:758 utils/adt/int8.c:834 utils/adt/int8.c:855 -#: utils/adt/int8.c:882 utils/adt/int8.c:915 utils/adt/int8.c:943 -#: utils/adt/int8.c:964 utils/adt/int8.c:991 utils/adt/int8.c:1031 -#: utils/adt/int8.c:1052 utils/adt/int8.c:1079 utils/adt/int8.c:1112 -#: utils/adt/int8.c:1140 utils/adt/int8.c:1161 utils/adt/int8.c:1188 -#: utils/adt/int8.c:1361 utils/adt/int8.c:1400 utils/adt/numeric.c:2959 -#: utils/adt/varbit.c:1645 +#: utils/adt/int8.c:529 utils/adt/int8.c:552 utils/adt/int8.c:566 +#: utils/adt/int8.c:580 utils/adt/int8.c:611 utils/adt/int8.c:635 +#: utils/adt/int8.c:690 utils/adt/int8.c:704 utils/adt/int8.c:728 +#: utils/adt/int8.c:741 utils/adt/int8.c:810 utils/adt/int8.c:824 +#: utils/adt/int8.c:838 utils/adt/int8.c:869 utils/adt/int8.c:891 +#: utils/adt/int8.c:905 utils/adt/int8.c:919 utils/adt/int8.c:952 +#: utils/adt/int8.c:966 utils/adt/int8.c:980 utils/adt/int8.c:1011 +#: utils/adt/int8.c:1033 utils/adt/int8.c:1047 utils/adt/int8.c:1061 +#: utils/adt/int8.c:1230 utils/adt/int8.c:1272 utils/adt/numeric.c:3313 +#: utils/adt/varbit.c:1665 #, c-format msgid "bigint out of range" msgstr "bigint 超出范围" -#: utils/adt/int8.c:1417 +#: utils/adt/int8.c:1285 #, c-format msgid "OID out of range" msgstr "OID 超出范围" -#: utils/adt/json.c:785 utils/adt/json.c:825 utils/adt/json.c:840 -#: utils/adt/json.c:851 utils/adt/json.c:861 utils/adt/json.c:912 -#: utils/adt/json.c:943 utils/adt/json.c:961 utils/adt/json.c:973 -#: utils/adt/json.c:985 utils/adt/json.c:1130 utils/adt/json.c:1144 -#: utils/adt/json.c:1155 utils/adt/json.c:1163 utils/adt/json.c:1171 -#: utils/adt/json.c:1179 utils/adt/json.c:1187 utils/adt/json.c:1195 -#: utils/adt/json.c:1203 utils/adt/json.c:1211 utils/adt/json.c:1241 -#, c-format -msgid "invalid input syntax for type json" -msgstr "json类型使用了无效的输入语法" - -#: utils/adt/json.c:786 +#: utils/adt/json.c:787 #, c-format msgid "Character with value 0x%02x must be escaped." msgstr "值为 0x%02x 的字符必须进行转义处ç†." -#: utils/adt/json.c:826 +#: utils/adt/json.c:828 #, c-format msgid "\"\\u\" must be followed by four hexadecimal digits." msgstr "\"\\u\" åŽå¿…须紧跟有效的å六进制数数字" -#: utils/adt/json.c:841 +#: utils/adt/json.c:844 jsonpath_scan.l:560 #, c-format msgid "Unicode high surrogate must not follow a high surrogate." msgstr "Unicode 的高ä½ä»£ç†é¡¹ä¸èƒ½ç´§éšå¦ä¸€ä¸ªé«˜ä½ä»£ç†é¡¹." -#: utils/adt/json.c:852 utils/adt/json.c:862 utils/adt/json.c:913 -#: utils/adt/json.c:974 utils/adt/json.c:986 +#: utils/adt/json.c:855 utils/adt/json.c:865 utils/adt/json.c:917 +#: utils/adt/json.c:979 utils/adt/json.c:991 jsonpath_scan.l:571 +#: jsonpath_scan.l:581 jsonpath_scan.l:623 #, c-format msgid "Unicode low surrogate must follow a high surrogate." msgstr "Unicode 代ä½ä»£ç†é¡¹å¿…须紧éšä¸€ä¸ªé«˜ä½ä»£ç†é¡¹." -#: utils/adt/json.c:877 utils/adt/json.c:900 +#: utils/adt/json.c:880 utils/adt/json.c:903 jsonpath_scan.l:518 #, c-format msgid "unsupported Unicode escape sequence" msgstr "䏿”¯æŒçš„Unicode转义åºåˆ—" -#: utils/adt/json.c:878 +#: utils/adt/json.c:881 jsonpath_scan.l:519 #, c-format msgid "\\u0000 cannot be converted to text." msgstr "\\u0000ä¸èƒ½è¢«è½¬æ¢ä¸ºæ–‡æœ¬ã€‚" -#: utils/adt/json.c:901 +#: utils/adt/json.c:904 jsonpath_scan.l:544 #, c-format -msgid "" -"Unicode escape values cannot be used for code point values above 007F when " -"the server encoding is not UTF8." +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8." msgstr "当æœåŠ¡å™¨çš„ç¼–ç ä¸æ˜¯UTF8时,Unicode转义值就ä¸èƒ½ç”¨ä½œ007F以上的ç ç‚¹å€¼." -#: utils/adt/json.c:944 utils/adt/json.c:962 +#: utils/adt/json.c:949 utils/adt/json.c:967 #, c-format msgid "Escape sequence \"\\%s\" is invalid." msgstr "转义åºåˆ— \"\\%s\" 无效." -#: utils/adt/json.c:1131 +#: utils/adt/json.c:1136 #, c-format msgid "The input string ended unexpectedly." msgstr "输入字符串æ„外终止." -#: utils/adt/json.c:1145 +#: utils/adt/json.c:1150 #, c-format msgid "Expected end of input, but found \"%s\"." msgstr "期望输入结æŸï¼Œç»“æžœå‘现是\"%s\"." -#: utils/adt/json.c:1156 +#: utils/adt/json.c:1161 #, c-format msgid "Expected JSON value, but found \"%s\"." msgstr "期望 是JSON值, 但结果å‘现是\"%s\"." -#: utils/adt/json.c:1164 utils/adt/json.c:1212 +#: utils/adt/json.c:1169 utils/adt/json.c:1217 #, c-format msgid "Expected string, but found \"%s\"." msgstr "期望是字符串, 但å‘现结果是\"%s\"." -#: utils/adt/json.c:1172 +#: utils/adt/json.c:1177 #, c-format msgid "Expected array element or \"]\", but found \"%s\"." msgstr "期望为数组元素或者\"]\",但å‘现结果是\"%s\"." -#: utils/adt/json.c:1180 +#: utils/adt/json.c:1185 #, c-format msgid "Expected \",\" or \"]\", but found \"%s\"." msgstr "期望是\",\" 或 \"]\",但å‘现结果是\"%s\"." -#: utils/adt/json.c:1188 +#: utils/adt/json.c:1193 #, c-format msgid "Expected string or \"}\", but found \"%s\"." msgstr "期望是字符串或\"}\",但å‘现结果是\"%s\"." -#: utils/adt/json.c:1196 +#: utils/adt/json.c:1201 #, c-format msgid "Expected \":\", but found \"%s\"." msgstr "期望得到 \":\",但å‘现结果是\"%s\"." -#: utils/adt/json.c:1204 +#: utils/adt/json.c:1209 #, c-format msgid "Expected \",\" or \"}\", but found \"%s\"." msgstr "期望是 \",\" 或 \"}\",但å‘现结果是\"%s\"." -#: utils/adt/json.c:1242 +#: utils/adt/json.c:1247 #, c-format msgid "Token \"%s\" is invalid." msgstr "令牌 \"%s\" 无效." -#: utils/adt/json.c:1314 +#: utils/adt/json.c:1319 #, c-format msgid "JSON data, line %d: %s%s%s" msgstr "JSONæ•°æ®, 行 %d: %s%s%s" -#: utils/adt/json.c:1469 utils/adt/jsonb.c:724 +#: utils/adt/json.c:1475 utils/adt/jsonb.c:739 #, c-format msgid "key value must be scalar, not array, composite, or json" msgstr "键值必须是标é‡ï¼Œä¸èƒ½æ˜¯æ•°ç»„ã€å¤åˆå€¼æˆ–json值" -#: utils/adt/json.c:2006 +#: utils/adt/json.c:2076 utils/adt/json.c:2086 utils/fmgr/funcapi.c:1549 #, c-format -msgid "could not determine data type for argument 1" -msgstr "æ— æ³•ç¡®å®šå‚æ•°1的数æ®ç±»åž‹" - -#: utils/adt/json.c:2016 -#, c-format -msgid "could not determine data type for argument 2" -msgstr "æ— æ³•ç¡®å®šå‚æ•°2的数æ®ç±»åž‹" +msgid "could not determine data type for argument %d" +msgstr "æ— æ³•ç¡®å®šå‚æ•° %d 的数æ®ç±»åž‹" -#: utils/adt/json.c:2040 utils/adt/jsonb.c:1781 +#: utils/adt/json.c:2110 utils/adt/jsonb.c:1707 #, c-format msgid "field name must not be null" msgstr "字段åä¸èƒ½ä¸ºç©º" -#: utils/adt/json.c:2117 +#: utils/adt/json.c:2194 utils/adt/jsonb.c:1157 #, c-format msgid "argument list must have even number of elements" msgstr "傿•°åˆ—è¡¨çš„å…ƒç´ ä¸ªæ•°å¿…é¡»ä¸ºå¶æ•°" -#: utils/adt/json.c:2118 -#, c-format -msgid "" -"The arguments of json_build_object() must consist of alternating keys and " -"values." +#. translator: %s is a SQL function name +#: utils/adt/json.c:2196 utils/adt/jsonb.c:1159 +#, fuzzy, c-format +#| msgid "The arguments of json_build_object() must consist of alternating keys and values." +msgid "The arguments of %s must consist of alternating keys and values." msgstr "json_build_object()çš„å‚æ•°å¿…须包å«å¯æ›¿ä»£çš„键和对应的值." -#: utils/adt/json.c:2142 utils/adt/json.c:2163 utils/adt/json.c:2222 -#, c-format -msgid "could not determine data type for argument %d" -msgstr "æ— æ³•ç¡®å®šå‚æ•° %d 的数æ®ç±»åž‹" - -#: utils/adt/json.c:2148 +#: utils/adt/json.c:2212 #, c-format msgid "argument %d cannot be null" msgstr "傿•°%dä¸èƒ½ä¸ºç©º" -#: utils/adt/json.c:2149 +#: utils/adt/json.c:2213 #, c-format msgid "Object keys should be text." msgstr "对象的键必须是文本" -#: utils/adt/json.c:2284 utils/adt/jsonb.c:1363 +#: utils/adt/json.c:2319 utils/adt/jsonb.c:1289 #, c-format msgid "array must have two columns" msgstr "数组必须有两列" -#: utils/adt/json.c:2308 utils/adt/json.c:2392 utils/adt/jsonb.c:1387 -#: utils/adt/jsonb.c:1482 +#: utils/adt/json.c:2343 utils/adt/json.c:2427 utils/adt/jsonb.c:1313 +#: utils/adt/jsonb.c:1408 #, c-format msgid "null value not allowed for object key" msgstr "空值ä¸èƒ½ç”¨äºŽå¯¹è±¡çš„键当中" -#: utils/adt/json.c:2381 utils/adt/jsonb.c:1471 +#: utils/adt/json.c:2416 utils/adt/jsonb.c:1397 #, c-format msgid "mismatched array dimensions" msgstr "ä¸åŒ¹é…的数组维数" -#: utils/adt/jsonb.c:257 +#: utils/adt/jsonb.c:269 #, c-format msgid "string too long to represent as jsonb string" msgstr "用于æè¿°jsonb字符串的字符串太长了" -#: utils/adt/jsonb.c:258 +#: utils/adt/jsonb.c:270 #, c-format -msgid "" -"Due to an implementation restriction, jsonb strings cannot exceed %d bytes." +msgid "Due to an implementation restriction, jsonb strings cannot exceed %d bytes." msgstr "因为实现方é¢çš„é™åˆ¶ï¼Œjsonb字符串ä¸èƒ½è¶…过%d个字节." -#: utils/adt/jsonb.c:1182 -#, c-format -msgid "invalid number of arguments: object must be matched key value pairs" -msgstr "æ— æ•ˆçš„å‚æ•°æ•°é‡ï¼šå¯¹è±¡å¿…须是匹é…的键值对" - -#: utils/adt/jsonb.c:1195 +#: utils/adt/jsonb.c:1172 #, c-format msgid "argument %d: key must not be null" msgstr "傿•°%d:键ä¸èƒ½ä¸ºç©º" -#: utils/adt/jsonb.c:1214 utils/adt/jsonb.c:1237 utils/adt/jsonb.c:1297 -#, c-format -msgid "argument %d: could not determine data type" -msgstr "傿•°%d:ä¸èƒ½ç¡®å®šæ•°æ®ç±»åž‹" - -#: utils/adt/jsonb.c:1834 +#: utils/adt/jsonb.c:1760 #, c-format msgid "object keys must be strings" msgstr "对象键必须是字符串" -#: utils/adt/jsonb_util.c:656 +#: utils/adt/jsonb.c:1923 +#, c-format +msgid "cannot cast jsonb null to type %s" +msgstr "无法把jsonb nullè½¬æ¢æˆç±»åž‹%s" + +#: utils/adt/jsonb.c:1924 +#, c-format +msgid "cannot cast jsonb string to type %s" +msgstr "无法把jsonb string转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb.c:1925 +#, c-format +msgid "cannot cast jsonb numeric to type %s" +msgstr "无法把jsonb numeric转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb.c:1926 +#, c-format +msgid "cannot cast jsonb boolean to type %s" +msgstr "无法把jsonb boolean转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb.c:1927 +#, c-format +msgid "cannot cast jsonb array to type %s" +msgstr "无法把jsonb array转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb.c:1928 +#, c-format +msgid "cannot cast jsonb object to type %s" +msgstr "无法把jsonb object转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb.c:1929 +#, c-format +msgid "cannot cast jsonb array or object to type %s" +msgstr "无法把jsonb array或object转æ¢ä¸ºç±»åž‹%s" + +#: utils/adt/jsonb_util.c:657 #, c-format msgid "number of jsonb object pairs exceeds the maximum allowed (%zu)" msgstr "jsonb对象结对的数目超过了最大å…许值(%zu)" -#: utils/adt/jsonb_util.c:697 +#: utils/adt/jsonb_util.c:698 #, c-format msgid "number of jsonb array elements exceeds the maximum allowed (%zu)" msgstr "jsonb数组元素的数目超过了最大å…许值(%zu)" -#: utils/adt/jsonb_util.c:1525 utils/adt/jsonb_util.c:1545 +#: utils/adt/jsonb_util.c:1569 utils/adt/jsonb_util.c:1589 #, c-format msgid "total size of jsonb array elements exceeds the maximum of %u bytes" msgstr "jsonb数组的元素的总大å°è¶…过了最大值%u字节" -#: utils/adt/jsonb_util.c:1606 utils/adt/jsonb_util.c:1641 -#: utils/adt/jsonb_util.c:1661 +#: utils/adt/jsonb_util.c:1650 utils/adt/jsonb_util.c:1685 +#: utils/adt/jsonb_util.c:1705 #, c-format msgid "total size of jsonb object elements exceeds the maximum of %u bytes" msgstr "jsonb对象元素的总大å°ä¸èƒ½è¶…过最大 %u 字节" -#: utils/adt/jsonfuncs.c:305 utils/adt/jsonfuncs.c:470 -#: utils/adt/jsonfuncs.c:2065 utils/adt/jsonfuncs.c:2506 -#: utils/adt/jsonfuncs.c:3012 +#: utils/adt/jsonfuncs.c:523 utils/adt/jsonfuncs.c:688 +#: utils/adt/jsonfuncs.c:2276 utils/adt/jsonfuncs.c:2716 +#: utils/adt/jsonfuncs.c:3473 utils/adt/jsonfuncs.c:3830 #, c-format msgid "cannot call %s on a scalar" msgstr "无法在标é‡ä¸Šè°ƒç”¨%s" -#: utils/adt/jsonfuncs.c:310 utils/adt/jsonfuncs.c:457 -#: utils/adt/jsonfuncs.c:2495 +#: utils/adt/jsonfuncs.c:528 utils/adt/jsonfuncs.c:675 +#: utils/adt/jsonfuncs.c:2718 utils/adt/jsonfuncs.c:3462 #, c-format msgid "cannot call %s on an array" msgstr "无法在数组上调用%s" -#: utils/adt/jsonfuncs.c:1373 utils/adt/jsonfuncs.c:1408 +#: utils/adt/jsonfuncs.c:1591 utils/adt/jsonfuncs.c:1626 #, c-format msgid "cannot get array length of a scalar" msgstr "无法得到一个标题的数组长度" -#: utils/adt/jsonfuncs.c:1377 utils/adt/jsonfuncs.c:1396 +#: utils/adt/jsonfuncs.c:1595 utils/adt/jsonfuncs.c:1614 #, c-format msgid "cannot get array length of a non-array" msgstr "æ— æ³•ä»Žä¸€ä¸ªéžæ•°ç»„里得到数组的长度" -#: utils/adt/jsonfuncs.c:1473 +#: utils/adt/jsonfuncs.c:1691 #, c-format msgid "cannot call %s on a non-object" msgstr "ä¸èƒ½åœ¨éžå¯¹è±¡ä¸Šè°ƒç”¨ %s " -#: utils/adt/jsonfuncs.c:1491 utils/adt/jsonfuncs.c:2178 -#: utils/adt/jsonfuncs.c:2715 -#, c-format -msgid "" -"function returning record called in context that cannot accept type record" -msgstr "è¿”å›žå€¼ç±»åž‹æ˜¯è®°å½•çš„å‡½æ•°åœ¨ä¸æŽ¥å—使用记录类型的环境中调用" - -#: utils/adt/jsonfuncs.c:1734 +#: utils/adt/jsonfuncs.c:1949 #, c-format msgid "cannot deconstruct an array as an object" msgstr "ä¸èƒ½å°†ä¸€ä¸ªæ•°ç»„æžæž„为一个对象" -#: utils/adt/jsonfuncs.c:1746 +#: utils/adt/jsonfuncs.c:1961 #, c-format msgid "cannot deconstruct a scalar" msgstr "æ— æ³•æžæž„一个标é‡" -#: utils/adt/jsonfuncs.c:1792 +#: utils/adt/jsonfuncs.c:2007 #, c-format msgid "cannot extract elements from a scalar" msgstr "无法从标题值时æå–元素" -#: utils/adt/jsonfuncs.c:1796 +#: utils/adt/jsonfuncs.c:2011 #, c-format msgid "cannot extract elements from an object" msgstr "无法从一个对象里æå–元素" -#: utils/adt/jsonfuncs.c:2052 utils/adt/jsonfuncs.c:2811 +#: utils/adt/jsonfuncs.c:2263 utils/adt/jsonfuncs.c:3714 #, c-format msgid "cannot call %s on a non-array" msgstr "éžæ•°ç»„上ä¸èƒ½è°ƒç”¨%s" -#: utils/adt/jsonfuncs.c:2139 utils/adt/jsonfuncs.c:2691 +#: utils/adt/jsonfuncs.c:2333 utils/adt/jsonfuncs.c:2338 +#: utils/adt/jsonfuncs.c:2355 utils/adt/jsonfuncs.c:2361 +#, c-format +msgid "expected JSON array" +msgstr "应为JSON数组" + +#: utils/adt/jsonfuncs.c:2334 +#, c-format +msgid "See the value of key \"%s\"." +msgstr "查看键\"%s\"的值." + +#: utils/adt/jsonfuncs.c:2356 +#, c-format +msgid "See the array element %s of key \"%s\"." +msgstr "查看数组元素%s的键值\"%s\"." + +#: utils/adt/jsonfuncs.c:2362 +#, c-format +msgid "See the array element %s." +msgstr "查看数组元素%s." + +#: utils/adt/jsonfuncs.c:2397 +#, c-format +msgid "malformed JSON array" +msgstr "有缺陷的JSON数组" + +#: utils/adt/jsonfuncs.c:3250 utils/adt/jsonfuncs.c:3606 #, c-format msgid "first argument of %s must be a row type" msgstr "%s çš„ç¬¬ä¸€ä¸ªå‚æ•°å¿…需是一个行类型" -#: utils/adt/jsonfuncs.c:2180 +#: utils/adt/jsonfuncs.c:3268 utils/adt/jsonfuncs.c:3623 #, c-format -msgid "" -"Try calling the function in the FROM clause using a column definition list." +msgid "Try calling the function in the FROM clause using a column definition list." msgstr "试图在FROMå­å¥æ—¶åœ¨ï¼Œä½¿ç”¨åˆ—定义列表调用该函数." -#: utils/adt/jsonfuncs.c:2827 utils/adt/jsonfuncs.c:2994 +#: utils/adt/jsonfuncs.c:3731 utils/adt/jsonfuncs.c:3812 #, c-format msgid "argument of %s must be an array of objects" msgstr "%s çš„å‚æ•°å¿…须是一个对象数组" -#: utils/adt/jsonfuncs.c:2851 +#: utils/adt/jsonfuncs.c:3764 #, c-format msgid "cannot call %s on an object" msgstr "ä¸èƒ½åœ¨ä¸€ä¸ªå¯¹è±¡ä¸Šè°ƒç”¨%s" -#: utils/adt/jsonfuncs.c:3418 utils/adt/jsonfuncs.c:3471 +#: utils/adt/jsonfuncs.c:4241 utils/adt/jsonfuncs.c:4300 +#: utils/adt/jsonfuncs.c:4380 #, c-format msgid "cannot delete from scalar" msgstr "无法从标é‡åˆ é™¤" -#: utils/adt/jsonfuncs.c:3476 +#: utils/adt/jsonfuncs.c:4385 #, c-format -#| msgid "cannot delete from object using integer subscript" msgid "cannot delete from object using integer index" msgstr "ä¸èƒ½ä½¿ç”¨æ•´æ•°ç´¢å¼•从对象删除" -#: utils/adt/jsonfuncs.c:3542 utils/adt/jsonfuncs.c:3634 +#: utils/adt/jsonfuncs.c:4451 utils/adt/jsonfuncs.c:4543 #, c-format msgid "cannot set path in scalar" msgstr "无法在标é‡ä¸­è®¾ç½®è·¯å¾„" -#: utils/adt/jsonfuncs.c:3587 +#: utils/adt/jsonfuncs.c:4496 #, c-format msgid "cannot delete path in scalar" msgstr "无法在标é‡ä¸­åˆ é™¤è·¯å¾„" # fe-connect.c:2558 -#: utils/adt/jsonfuncs.c:3757 +#: utils/adt/jsonfuncs.c:4666 #, c-format msgid "invalid concatenation of jsonb objects" msgstr "jsonb对象的无效串接" -#: utils/adt/jsonfuncs.c:3791 +#: utils/adt/jsonfuncs.c:4700 #, c-format msgid "path element at position %d is null" msgstr "ä½ç½® %d 的路径元素为空" -#: utils/adt/jsonfuncs.c:3877 +#: utils/adt/jsonfuncs.c:4786 #, c-format -#| msgid "cannot reopen stdin\n" msgid "cannot replace existing key" msgstr "ä¸èƒ½æ›¿æ¢å·²ç»å­˜åœ¨çš„é”®" -#: utils/adt/jsonfuncs.c:3878 +#: utils/adt/jsonfuncs.c:4787 #, c-format msgid "Try using the function jsonb_set to replace key value." msgstr "å°è¯•使用 jsonb_set æ¥æ›¿æ¢é”®å€¼ã€‚" -#: utils/adt/jsonfuncs.c:3960 +#: utils/adt/jsonfuncs.c:4869 #, c-format -#| msgid "plpy.prepare: type name at ordinal position %d is not a string" msgid "path element at position %d is not an integer: \"%s\"" msgstr "ä½ç½® %d çš„è·¯å¾„å…ƒç´ ä¸æ˜¯ä¸€ä¸ªæ•´æ•°ï¼š\"%s\"" +#: utils/adt/jsonfuncs.c:4988 +#, c-format +msgid "wrong flag type, only arrays and scalars are allowed" +msgstr "错误的标志类型,åªå…许数组和标é‡" + +#: utils/adt/jsonfuncs.c:4995 +#, c-format +msgid "flag array element is not a string" +msgstr "æ ‡å¿—æ•°ç»„å…ƒç´ ä¸æ˜¯å­—符串" + +#: utils/adt/jsonfuncs.c:4996 utils/adt/jsonfuncs.c:5018 +#, fuzzy, c-format +#| msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"" +msgid "Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"." +msgstr "å¯èƒ½çš„值有:\"string\", \"numeric\", \"boolean\", \"key\", å’Œ \"all\"" + +#: utils/adt/jsonfuncs.c:5016 +#, c-format +msgid "wrong flag in flag array: \"%s\"" +msgstr "标志数组中的标志错误: \"%s\"" + +#: utils/adt/jsonpath.c:360 +#, fuzzy, c-format +#| msgid "window functions are not allowed in policy expressions" +msgid "@ is not allowed in root expressions" +msgstr "策略表达å¼ä¸­ä¸å…许窗å£å‡½æ•°" + +#: utils/adt/jsonpath.c:366 +#, fuzzy, c-format +#| msgid "wrong number of array subscripts" +msgid "LAST is allowed only in array subscripts" +msgstr "错误的数组下标" + +#: utils/adt/jsonpath_exec.c:342 +#, c-format +msgid "single boolean result is expected" +msgstr "" + +#: utils/adt/jsonpath_exec.c:490 +#, c-format +msgid "\"vars\" argument is not an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:491 +#, c-format +msgid "Jsonpath parameters should be encoded as key-value pairs of \"vars\" object." +msgstr "" + +#: utils/adt/jsonpath_exec.c:607 +#, c-format +msgid "JSON object does not contain key \"%s\"" +msgstr "" + +#: utils/adt/jsonpath_exec.c:619 +#, c-format +msgid "jsonpath member accessor can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:648 +#, c-format +msgid "jsonpath wildcard array accessor can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:696 +#, fuzzy, c-format +#| msgid "array subscript out of range" +msgid "jsonpath array subscript is out of bounds" +msgstr "数组下标超出范围" + +#: utils/adt/jsonpath_exec.c:753 +#, c-format +msgid "jsonpath array accessor can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:807 +#, c-format +msgid "jsonpath wildcard member accessor can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:937 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an array" +msgstr "" + +#: utils/adt/jsonpath_exec.c:991 utils/adt/jsonpath_exec.c:1012 +#: utils/adt/jsonpath_exec.c:1695 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1025 +#, c-format +msgid "jsonpath item method .%s() can only be applied to a string or numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1509 +#, c-format +msgid "left operand of jsonpath operator %s is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1516 +#, c-format +msgid "right operand of jsonpath operator %s is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1584 +#, c-format +msgid "operand of unary jsonpath operator %s is not a numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1754 +#, c-format +msgid "jsonpath item method .%s() can only be applied to an object" +msgstr "" + +#: utils/adt/jsonpath_exec.c:1937 +#, fuzzy, c-format +#| msgid "could not find WAL file \"%s\"" +msgid "could not find jsonpath variable \"%s\"" +msgstr "找ä¸åˆ°WAL文件\"%s\"" + +#: utils/adt/jsonpath_exec.c:2097 +#, c-format +msgid "jsonpath array subscript is not a single numeric value" +msgstr "" + +#: utils/adt/jsonpath_exec.c:2109 +#, fuzzy, c-format +#| msgid "array subscript out of range" +msgid "jsonpath array subscript is out of integer range" +msgstr "数组下标超出范围" + #: utils/adt/levenshtein.c:133 #, c-format -#| msgid "argument exceeds the maximum length of %d bytes" msgid "levenshtein argument exceeds maximum length of %d characters" msgstr "levenshtein 傿•°è¶…过了 %d 字符的最大长度" -#: utils/adt/like.c:212 utils/adt/selfuncs.c:5329 +#: utils/adt/like.c:160 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for ILIKE" +msgid "nondeterministic collations are not supported for LIKE" +msgstr "无法确定ILIKEä½¿ç”¨å“ªç§æŽ’åºè§„则" + +#: utils/adt/like.c:193 utils/adt/like_support.c:964 #, c-format msgid "could not determine which collation to use for ILIKE" msgstr "无法确定ILIKEä½¿ç”¨å“ªç§æŽ’åºè§„则" +#: utils/adt/like.c:201 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for ILIKE" +msgid "nondeterministic collations are not supported for ILIKE" +msgstr "无法确定ILIKEä½¿ç”¨å“ªç§æŽ’åºè§„则" + #: utils/adt/like_match.c:107 utils/adt/like_match.c:167 #, c-format msgid "LIKE pattern must not end with escape character" msgstr "LIKE模å¼ä¸èƒ½ä»¥è½¬ä¹‰å­—符结æŸ" -#: utils/adt/like_match.c:292 utils/adt/regexp.c:698 +#: utils/adt/like_match.c:292 utils/adt/regexp.c:702 #, c-format msgid "invalid escape string" msgstr "无效的逃逸字符串" -#: utils/adt/like_match.c:293 utils/adt/regexp.c:699 +#: utils/adt/like_match.c:293 utils/adt/regexp.c:703 #, c-format msgid "Escape string must be empty or one character." msgstr "逃逸字符串必须为空或者一个字符." -#: utils/adt/lockfuncs.c:545 -#, c-format -msgid "cannot use advisory locks during a parallel operation" -msgstr "在并行æ“作期间无法使用咨询é”" - -#: utils/adt/mac.c:68 -#, c-format -msgid "invalid input syntax for type macaddr: \"%s\"" -msgstr "无效的 macaddr 类型输入语法: \"%s\"" - -#: utils/adt/mac.c:75 -#, c-format -msgid "invalid octet value in \"macaddr\" value: \"%s\"" -msgstr "在 \"macaddr\" 值中的无效八ä½å€¼: \"%s\"" - -#: utils/adt/misc.c:239 -#, c-format -msgid "PID %d is not a PostgreSQL server process" -msgstr "PID %d 䏿˜¯ PostgreSQL æœåŠ¡å™¨è¿›ç¨‹" - -#: utils/adt/misc.c:290 +#: utils/adt/like_support.c:949 #, c-format -msgid "must be a superuser to cancel superuser query" -msgstr "åªæœ‰è¶…级用户æ‰èƒ½å–消超级用户的查询" +msgid "case insensitive matching not supported on type bytea" +msgstr "在类型byteaä¸Šä¸æ”¯æŒå¯¹ä¸åŒºåˆ†å¤§å°å†™çš„匹é…" -#: utils/adt/misc.c:295 +#: utils/adt/like_support.c:1051 #, c-format -#| msgid "must be a member of the role whose query is being canceled" -msgid "" -"must be a member of the role whose query is being canceled or member of " -"pg_signal_backend" -msgstr "å¿…é¡»æ˜¯å…¶æŸ¥è¯¢è¢«å–æ¶ˆçš„角色的一个æˆå‘˜æˆ–者 pg_signal_backend 的一个æˆå‘˜" +msgid "regular-expression matching not supported on type bytea" +msgstr "在 bytea ç±»åž‹ä¸Šä¸æ”¯æŒæ­£åˆ™è¡¨è¾¾å¼åŒ¹é…" -#: utils/adt/misc.c:314 +#: utils/adt/lockfuncs.c:664 #, c-format -msgid "must be a superuser to terminate superuser process" -msgstr "åªæœ‰è¶…级用户中止超级用户的进程" +msgid "cannot use advisory locks during a parallel operation" +msgstr "在并行æ“作期间无法使用咨询é”" -#: utils/adt/misc.c:319 +#: utils/adt/mac.c:102 #, c-format -#| msgid "must be a member of the role whose process is being terminated" -msgid "" -"must be a member of the role whose process is being terminated or member of " -"pg_signal_backend" -msgstr "必须是其进程被终止的角色的一个æˆå‘˜æˆ–者 pg_signal_backend 的一个æˆå‘˜" +msgid "invalid octet value in \"macaddr\" value: \"%s\"" +msgstr "在 \"macaddr\" 值中的无效八ä½å€¼: \"%s\"" -#: utils/adt/misc.c:336 +#: utils/adt/mac8.c:563 #, c-format -msgid "failed to send signal to postmaster: %m" -msgstr "无法å‘é€ä¿¡å·åˆ°postmaster进程: %m" +msgid "macaddr8 data out of range to convert to macaddr" +msgstr "macaddr8æ•°æ®è¶…出范围,无法转æ¢ä¸ºmacaddr" -#: utils/adt/misc.c:356 +#: utils/adt/mac8.c:564 #, c-format -msgid "rotation not possible because log collection not active" -msgstr "æ—¥å¿—åˆ‡æ¢æ— æ³•进行,因为没有激活日志收集功能" +msgid "Only addresses that have FF and FE as values in the 4th and 5th bytes from the left, for example xx:xx:xx:ff:fe:xx:xx:xx, are eligible to be converted from macaddr8 to macaddr." +msgstr "åªæœ‰åœ¨å·¦è¾¹ç¬¬4和第5个字节中具有FFå’ŒFE值的地å€ï¼ˆä¾‹å¦‚,xx:xx:xx:ff:fe:xx:xx:xxï¼‰æ‰æœ‰èµ„格从macaddr8转æ¢ä¸ºmacaddr." -#: utils/adt/misc.c:393 +#: utils/adt/misc.c:225 #, c-format msgid "global tablespace never has databases" msgstr "全局表空间没有数æ®åº“" -#: utils/adt/misc.c:414 +#: utils/adt/misc.c:246 #, c-format msgid "%u is not a tablespace OID" msgstr "%u 䏿˜¯ä¸€ä¸ªè¡¨ç©ºé—´ OID" -#: utils/adt/misc.c:611 +#: utils/adt/misc.c:435 msgid "unreserved" msgstr "未ä¿ç•™" -#: utils/adt/misc.c:615 +#: utils/adt/misc.c:439 msgid "unreserved (cannot be function or type name)" msgstr "未ä¿ç•™(ä¸èƒ½æ˜¯å‡½æ•°æˆ–者类型åç§°)" -#: utils/adt/misc.c:619 +#: utils/adt/misc.c:443 msgid "reserved (can be function or type name)" msgstr "å·²ä¿ç•™ï¼ˆå¯ä»¥æ˜¯å‡½æ•°æˆ–类型åç§°)" -#: utils/adt/misc.c:623 +#: utils/adt/misc.c:447 msgid "reserved" msgstr "å·²ä¿ç•™" -#: utils/adt/misc.c:797 utils/adt/misc.c:811 utils/adt/misc.c:850 -#: utils/adt/misc.c:856 utils/adt/misc.c:862 utils/adt/misc.c:885 +#: utils/adt/misc.c:621 utils/adt/misc.c:635 utils/adt/misc.c:674 +#: utils/adt/misc.c:680 utils/adt/misc.c:686 utils/adt/misc.c:709 #, c-format -#| msgid "invalid snapshot identifier: \"%s\"" msgid "string is not a valid identifier: \"%s\"" msgstr "å­—ç¬¦ä¸²ä¸æ˜¯ä¸€ä¸ªåˆæ³•的标识符:\"%s\"" -#: utils/adt/misc.c:799 +#: utils/adt/misc.c:623 #, c-format msgid "String has unclosed double quotes." msgstr "字符串有未å°é—­çš„åŒå¼•å·ã€‚" -#: utils/adt/misc.c:813 +#: utils/adt/misc.c:637 #, c-format -#| msgid "Extension names must not be empty." msgid "Quoted identifier must not be empty." msgstr "被引用的标识符ä¸èƒ½ä¸ºç©ºã€‚" -#: utils/adt/misc.c:852 +#: utils/adt/misc.c:676 #, c-format -msgid "No valid identifier before \".\" symbol." +msgid "No valid identifier before \".\"." msgstr "\".\" 符å·å‰æ²¡æœ‰åˆæ³•的标识符。" -#: utils/adt/misc.c:858 +#: utils/adt/misc.c:682 #, c-format -msgid "No valid identifier after \".\" symbol." +msgid "No valid identifier after \".\"." msgstr "\".\" 符å·åŽæ²¡æœ‰åˆæ³•的标识符。" -#: utils/adt/nabstime.c:136 -#, c-format -msgid "invalid time zone name: \"%s\"" -msgstr "无效时区åå­—: \"%s\"" - -#: utils/adt/nabstime.c:481 utils/adt/nabstime.c:554 -#, c-format -msgid "cannot convert abstime \"invalid\" to timestamp" -msgstr "无法把 abstime \"invalid\" 转æ¢ä¸º timestamp." - -#: utils/adt/nabstime.c:781 -#, c-format -msgid "invalid status in external \"tinterval\" value" -msgstr "无效的外部 \"tinterval\" 值状æ€" - -#: utils/adt/nabstime.c:855 +#: utils/adt/misc.c:743 #, c-format -msgid "cannot convert reltime \"invalid\" to interval" -msgstr "无法把 reltime \"invalid\" 转æ¢ä¸º interval" +msgid "log format \"%s\" is not supported" +msgstr "䏿”¯æŒæ—¥å¿—æ ¼å¼\"%s\"" -#: utils/adt/nabstime.c:1550 +#: utils/adt/misc.c:744 #, c-format -msgid "invalid input syntax for type tinterval: \"%s\"" -msgstr "无效的 tinterval 类型输入语法: \"%s\"" +msgid "The supported log formats are \"stderr\" and \"csvlog\"." +msgstr "支æŒçš„æ—¥å¿—æ ¼å¼ä¸º\"stderr\"å’Œ\"csvlog\"." -#: utils/adt/network.c:69 +#: utils/adt/network.c:85 #, c-format msgid "invalid cidr value: \"%s\"" msgstr "无效的 cidr 值: \"%s\"" -#: utils/adt/network.c:70 utils/adt/network.c:200 +#: utils/adt/network.c:86 utils/adt/network.c:216 #, c-format msgid "Value has bits set to right of mask." msgstr "这个值带有的bit集åˆï¼Œåœ¨æŽ©ç çš„å³è¾¹." -#: utils/adt/network.c:111 utils/adt/network.c:607 utils/adt/network.c:632 -#: utils/adt/network.c:657 +#: utils/adt/network.c:127 utils/adt/network.c:800 utils/adt/network.c:825 +#: utils/adt/network.c:850 #, c-format msgid "could not format inet value: %m" msgstr "无法格å¼åŒ– inet 值: %m" #. translator: %s is inet or cidr -#: utils/adt/network.c:168 +#: utils/adt/network.c:184 #, c-format msgid "invalid address family in external \"%s\" value" msgstr "在外部\"%s\"å€¼ä¸­çš„åœ°å€æ—无效" #. translator: %s is inet or cidr -#: utils/adt/network.c:175 +#: utils/adt/network.c:191 #, c-format msgid "invalid bits in external \"%s\" value" msgstr "在外部\"%s\"值中的bit无效" #. translator: %s is inet or cidr -#: utils/adt/network.c:184 +#: utils/adt/network.c:200 #, c-format msgid "invalid length in external \"%s\" value" msgstr "在外部\"%s\"值中的长度无效" -#: utils/adt/network.c:199 +#: utils/adt/network.c:215 #, c-format msgid "invalid external \"cidr\" value" msgstr "无效的外部 \"cidr\" 值" -#: utils/adt/network.c:321 utils/adt/network.c:348 +#: utils/adt/network.c:311 utils/adt/network.c:334 #, c-format msgid "invalid mask length: %d" msgstr "无效掩ç é•¿åº¦: %d" -#: utils/adt/network.c:675 +#: utils/adt/network.c:868 #, c-format msgid "could not format cidr value: %m" msgstr "无法格å¼åŒ–cidr值: %m" -#: utils/adt/network.c:917 +#: utils/adt/network.c:1101 #, c-format msgid "cannot merge addresses from different families" msgstr "无法åˆå¹¶æ¥è‡ªä¸åŒæ—的地å€" -#: utils/adt/network.c:1343 +#: utils/adt/network.c:1517 #, c-format msgid "cannot AND inet values of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„inet类型值进行与 (AND) ä½è¿ç®—" -#: utils/adt/network.c:1375 +#: utils/adt/network.c:1549 #, c-format msgid "cannot OR inet values of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„inet类型值进行或 (OR) è¿ç®—" -#: utils/adt/network.c:1436 utils/adt/network.c:1512 +#: utils/adt/network.c:1610 utils/adt/network.c:1686 #, c-format msgid "result is out of range" msgstr "结果超出范围" -#: utils/adt/network.c:1477 +#: utils/adt/network.c:1651 #, c-format msgid "cannot subtract inet values of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„inetç±»åž‹å€¼è¿›è¡Œå‡æ³•è¿ç®—" -#: utils/adt/numeric.c:542 utils/adt/numeric.c:569 utils/adt/numeric.c:5394 -#: utils/adt/numeric.c:5417 utils/adt/numeric.c:5441 utils/adt/numeric.c:5448 -#, c-format -msgid "invalid input syntax for type numeric: \"%s\"" -msgstr "无效的数字类型输入语法: \"%s\"" - -#: utils/adt/numeric.c:759 -#, c-format -msgid "invalid length in external \"numeric\" value" -msgstr "无效的外部 \"numeric\" 值长度" - -#: utils/adt/numeric.c:772 +#: utils/adt/numeric.c:833 #, c-format msgid "invalid sign in external \"numeric\" value" msgstr "无效的外部 \"numeric\" 值符å·" -#: utils/adt/numeric.c:778 +#: utils/adt/numeric.c:839 #, c-format msgid "invalid scale in external \"numeric\" value" msgstr "外部\"numeric\"值中范围无效" -#: utils/adt/numeric.c:787 +#: utils/adt/numeric.c:848 #, c-format msgid "invalid digit in external \"numeric\" value" msgstr "无效的外部 \"numeric\" 值使•°" -#: utils/adt/numeric.c:978 utils/adt/numeric.c:992 +#: utils/adt/numeric.c:1046 utils/adt/numeric.c:1060 #, c-format msgid "NUMERIC precision %d must be between 1 and %d" msgstr "NUMERIC %d 的精度必须在 1 å’Œ %d 之间" -#: utils/adt/numeric.c:983 +#: utils/adt/numeric.c:1051 #, c-format msgid "NUMERIC scale %d must be between 0 and precision %d" msgstr "NUMERIC 数值范围 %d 必须在 0 和精度 %d 之间" # fe-exec.c:2055 -#: utils/adt/numeric.c:1001 +#: utils/adt/numeric.c:1069 #, c-format msgid "invalid NUMERIC type modifier" msgstr "无效的NUMERIC类型修改器" -#: utils/adt/numeric.c:1333 +#: utils/adt/numeric.c:1401 #, c-format msgid "start value cannot be NaN" msgstr "开始值ä¸èƒ½æ˜¯NaN" -#: utils/adt/numeric.c:1338 +#: utils/adt/numeric.c:1406 #, c-format msgid "stop value cannot be NaN" msgstr "åœæ­¢å€¼ä¸èƒ½æ˜¯NaN" -#: utils/adt/numeric.c:1348 +#: utils/adt/numeric.c:1416 #, c-format msgid "step size cannot be NaN" msgstr "步长ä¸èƒ½æ˜¯NaN" -#: utils/adt/numeric.c:2543 utils/adt/numeric.c:5894 utils/adt/numeric.c:7597 -#: utils/adt/numeric.c:8126 utils/adt/numeric.c:8199 +#: utils/adt/numeric.c:2857 utils/adt/numeric.c:5869 utils/adt/numeric.c:6324 +#: utils/adt/numeric.c:8046 utils/adt/numeric.c:8471 utils/adt/numeric.c:8585 +#: utils/adt/numeric.c:8658 #, c-format msgid "value overflows numeric format" msgstr "值溢出数字格å¼" -#: utils/adt/numeric.c:2885 +#: utils/adt/numeric.c:3222 #, c-format msgid "cannot convert NaN to integer" msgstr "无法转化 NaN 为整数" -#: utils/adt/numeric.c:2951 +#: utils/adt/numeric.c:3305 #, c-format msgid "cannot convert NaN to bigint" msgstr "æ— æ³•è½¬æ¢ NaN 为 bigint" -#: utils/adt/numeric.c:2996 +#: utils/adt/numeric.c:3350 #, c-format msgid "cannot convert NaN to smallint" msgstr "æ— æ³•è½¬æ¢ NaN 为 smallint" -#: utils/adt/numeric.c:5964 +#: utils/adt/numeric.c:3387 utils/adt/numeric.c:3458 +#, c-format +msgid "cannot convert infinity to numeric" +msgstr "无法转化无穷大为整数" + +#: utils/adt/numeric.c:6408 #, c-format msgid "numeric field overflow" msgstr "数字字段溢出" -#: utils/adt/numeric.c:5965 +#: utils/adt/numeric.c:6409 #, c-format -msgid "" -"A field with precision %d, scale %d must round to an absolute value less " -"than %s%d." +msgid "A field with precision %d, scale %d must round to an absolute value less than %s%d." msgstr "精度为%d,范围是%d的字段必须四èˆäº”入到å°äºŽ%s%dçš„ç»å¯¹å€¼." -#: utils/adt/numeric.c:6236 utils/adt/numeric.c:6262 -#, c-format -msgid "invalid input syntax for type double precision: \"%s\"" -msgstr "无效的åŒç²¾åº¦ç±»åž‹è¾“入语法: \"%s\"" - -#: utils/adt/numutils.c:75 -#, c-format -msgid "value \"%s\" is out of range for type integer" -msgstr "值 \"%s\" 超出整数类型范围" - -#: utils/adt/numutils.c:81 -#, c-format -msgid "value \"%s\" is out of range for type smallint" -msgstr "值 \"%s\" 超出 smallint 类型范围" - -#: utils/adt/numutils.c:87 +#: utils/adt/numutils.c:90 #, c-format msgid "value \"%s\" is out of range for 8-bit integer" msgstr "值 \"%s\" 超出 8 使•´æ•°èŒƒå›´" -#: utils/adt/oid.c:43 utils/adt/oid.c:57 utils/adt/oid.c:63 utils/adt/oid.c:84 -#, c-format -msgid "invalid input syntax for type oid: \"%s\"" -msgstr "无效的 oid 类型输入语法: \"%s\"" - -#: utils/adt/oid.c:69 utils/adt/oid.c:107 -#, c-format -msgid "value \"%s\" is out of range for type oid" -msgstr "值 \"%s\" 超出类型 oid 范围" - -#: utils/adt/oid.c:287 +#: utils/adt/oid.c:290 #, c-format msgid "invalid oidvector data" msgstr "无效的oidvectoræ•°æ®" -#: utils/adt/oracle_compat.c:895 +#: utils/adt/oracle_compat.c:896 #, c-format msgid "requested character too large" msgstr "所请求的字符太大" -#: utils/adt/oracle_compat.c:945 utils/adt/oracle_compat.c:1007 +#: utils/adt/oracle_compat.c:946 utils/adt/oracle_compat.c:1008 #, c-format msgid "requested character too large for encoding: %d" msgstr "å¯¹äºŽç¼–ç æ¥è¯´æ‰€è¦æ±‚的字符太大了: %d" -#: utils/adt/oracle_compat.c:986 +#: utils/adt/oracle_compat.c:987 #, c-format msgid "requested character not valid for encoding: %d" msgstr "请求的字符对于编ç :%d是无效的" -#: utils/adt/oracle_compat.c:1000 +#: utils/adt/oracle_compat.c:1001 #, c-format msgid "null character not permitted" msgstr "ä¸å…许使用空字符" -#: utils/adt/orderedsetaggs.c:425 utils/adt/orderedsetaggs.c:530 -#: utils/adt/orderedsetaggs.c:669 +#: utils/adt/orderedsetaggs.c:442 utils/adt/orderedsetaggs.c:546 +#: utils/adt/orderedsetaggs.c:684 #, c-format msgid "percentile value %g is not between 0 and 1" msgstr "百分比值 %g ä¸åœ¨0å’Œ1之间" -#: utils/adt/pg_locale.c:917 +#: utils/adt/pg_locale.c:1097 #, c-format msgid "Apply system library package updates." msgstr "应用系统库包更新。" -#: utils/adt/pg_locale.c:1122 +#: utils/adt/pg_locale.c:1312 #, c-format msgid "could not create locale \"%s\": %m" msgstr "无法创建本地化环境 \"%s\": %m" -#: utils/adt/pg_locale.c:1125 +#: utils/adt/pg_locale.c:1315 #, c-format -msgid "" -"The operating system could not find any locale data for the locale name \"%s" -"\"." +msgid "The operating system could not find any locale data for the locale name \"%s\"." msgstr "æ“作系统无法找到本地化å \"%s\"对应的任何本地化数æ®." -#: utils/adt/pg_locale.c:1212 +#: utils/adt/pg_locale.c:1417 #, c-format -msgid "" -"collations with different collate and ctype values are not supported on this " -"platform" +msgid "collations with different collate and ctype values are not supported on this platform" msgstr "在此平å°ä¸Šä¸æ”¯æŒå¸¦æœ‰ä¸åŒcollateå’Œctype值的排åºè§„则" -#: utils/adt/pg_locale.c:1227 -#, c-format -msgid "nondefault collations are not supported on this platform" -msgstr "在这个平å°ä¸Šä¸æ”¯æŒä½¿ç”¨éžç¼ºçœçš„æŽ’åºè§„则" - -#: utils/adt/pg_locale.c:1398 -#, c-format -msgid "invalid multibyte character for locale" -msgstr "无效的多字节字符, 对于 locale" - -#: utils/adt/pg_locale.c:1399 -#, c-format -msgid "" -"The server's LC_CTYPE locale is probably incompatible with the database " -"encoding." -msgstr "æœåŠ¡å™¨æœ¬åœ° LC_CTYPE å¯èƒ½ä¸Žæ•°æ®åº“ç¼–ç ä¸å…¼å®¹." - -#: utils/adt/pg_lsn.c:44 utils/adt/pg_lsn.c:49 -#, c-format -msgid "invalid input syntax for type pg_lsn: \"%s\"" -msgstr "类型 pg_lsn: \"%s\"使用了无效的输入语法" - -#: utils/adt/pg_upgrade_support.c:40 -#, c-format -msgid "function can only be called when server is in binary upgrade mode" -msgstr "åªæœ‰å½“æœåŠ¡å™¨å¤„äºŽäºŒè¿›åˆ¶å‡çº§æ¨¡å¼æ—¶æ‰èƒ½è°ƒç”¨å‡½æ•°" - -#: utils/adt/pgstatfuncs.c:569 -#, c-format -#| msgid "invalid locale name: \"%s\"" -msgid "invalid command name: \"%s\"" -msgstr "无效的命令å:\"%s\"" - -#: utils/adt/pseudotypes.c:95 +#: utils/adt/pg_locale.c:1426 #, c-format -msgid "cannot accept a value of type any" -msgstr "无法接å—一个 any 类型值" +msgid "collation provider LIBC is not supported on this platform" +msgstr "此平å°ä¸æ”¯æŒæŽ’åºè§„则æä¾›ç¨‹åºLIBC" -#: utils/adt/pseudotypes.c:108 +#: utils/adt/pg_locale.c:1438 #, c-format -msgid "cannot display a value of type any" -msgstr "无法显示一个 any 类型值" +msgid "collations with different collate and ctype values are not supported by ICU" +msgstr "ICU䏿”¯æŒå¸¦æœ‰ä¸åŒcollateå’Œctype值的排åºè§„则" -#: utils/adt/pseudotypes.c:122 utils/adt/pseudotypes.c:150 +#: utils/adt/pg_locale.c:1444 utils/adt/pg_locale.c:1535 +#: utils/adt/pg_locale.c:1753 #, c-format -msgid "cannot accept a value of type anyarray" -msgstr "无法接å—一个 anyarray 类型值" +msgid "could not open collator for locale \"%s\": %s" +msgstr "无法打开区域设置\"%s\"的排åºå™¨: %s" -#: utils/adt/pseudotypes.c:175 -#, c-format -msgid "cannot accept a value of type anyenum" -msgstr "无法接å—一个anyenum类型值" - -#: utils/adt/pseudotypes.c:199 -#, c-format -msgid "cannot accept a value of type anyrange" -msgstr "无法接å—类型为anyrange的值" - -#: utils/adt/pseudotypes.c:276 -#, c-format -msgid "cannot accept a value of type trigger" -msgstr "无法接å—一个 trigger 类型值" - -#: utils/adt/pseudotypes.c:289 -#, c-format -msgid "cannot display a value of type trigger" -msgstr "无法显示一个 trigger 类型值" - -#: utils/adt/pseudotypes.c:303 -#, c-format -msgid "cannot accept a value of type event_trigger" -msgstr "无法接å—一个 事件触å‘器的 类型值" - -#: utils/adt/pseudotypes.c:316 -#, c-format -msgid "cannot display a value of type event_trigger" -msgstr "无法显示一个 事件触å‘器的 类型值" - -#: utils/adt/pseudotypes.c:330 -#, c-format -msgid "cannot accept a value of type language_handler" -msgstr "无法接å—一个 language_handler 类型值" - -#: utils/adt/pseudotypes.c:343 -#, c-format -msgid "cannot display a value of type language_handler" -msgstr "无法显示一个 language_handler 类型值" - -#: utils/adt/pseudotypes.c:357 -#, c-format -msgid "cannot accept a value of type fdw_handler" -msgstr "无法接å—一个 fdw_handler 类型值" - -#: utils/adt/pseudotypes.c:370 -#, c-format -msgid "cannot display a value of type fdw_handler" -msgstr "无法显示一个 fdw_handler 类型值" - -#: utils/adt/pseudotypes.c:384 +# input.c:213 +#: utils/adt/pg_locale.c:1458 #, c-format -#| msgid "cannot accept a value of type tsm_handler" -msgid "cannot accept a value of type index_am_handler" -msgstr "无法接å—一个类型 index_am_handler 的值" +msgid "ICU is not supported in this build" +msgstr "è¿™ä¸ªç‰ˆæœ¬çš„å®‰è£…ä¸æ”¯æŒä½¿ç”¨ICU" -#: utils/adt/pseudotypes.c:397 +#: utils/adt/pg_locale.c:1459 #, c-format -#| msgid "cannot display a value of type tsm_handler" -msgid "cannot display a value of type index_am_handler" -msgstr "无法显示一个类型 index_am_handler 的值" +msgid "You need to rebuild PostgreSQL using --with-icu." +msgstr "您需è¦ä½¿ç”¨--with-icu选项釿–°ç”ŸæˆPostgreSQL" -#: utils/adt/pseudotypes.c:411 +#: utils/adt/pg_locale.c:1479 #, c-format -msgid "cannot accept a value of type tsm_handler" -msgstr "无法接å—一个类型tsm_handler的值" +msgid "collation \"%s\" has no actual version, but a version was specified" +msgstr "排åºè§„则\"%s\"没有实际版本,但指定了版本" -#: utils/adt/pseudotypes.c:424 +#: utils/adt/pg_locale.c:1486 #, c-format -msgid "cannot display a value of type tsm_handler" -msgstr "无法显示一个类型tsm_handler的值" +msgid "collation \"%s\" has version mismatch" +msgstr "排åºè§„则\"%s\"的版本ä¸åŒ¹é…" -#: utils/adt/pseudotypes.c:438 +#: utils/adt/pg_locale.c:1488 #, c-format -msgid "cannot accept a value of type internal" -msgstr "无法接å—一个 internal 类型值" +msgid "The collation in the database was created using version %s, but the operating system provides version %s." +msgstr "æ•°æ®åº“中的排åºè§„则是使用版本%s创建的,但æ“作系统æä¾›ç‰ˆæœ¬%s." -#: utils/adt/pseudotypes.c:451 +#: utils/adt/pg_locale.c:1491 #, c-format -msgid "cannot display a value of type internal" -msgstr "无法显示一个 internal 类型值" +msgid "Rebuild all objects affected by this collation and run ALTER COLLATION %s REFRESH VERSION, or build PostgreSQL with the right library version." +msgstr "釿–°ç”Ÿæˆå—此排åºè§„则影å“的所有对象,并è¿è¡ŒALTER COLLATION %s REFRESH VERSION,,或使用正确的库版本生æˆPostgreSQL." -#: utils/adt/pseudotypes.c:465 +#: utils/adt/pg_locale.c:1575 #, c-format -msgid "cannot accept a value of type opaque" -msgstr "无法接å—一个 opaque 类型值" +msgid "could not open ICU converter for encoding \"%s\": %s" +msgstr "无法打开编ç \"%s\"çš„ICU转æ¢å™¨: %s" -#: utils/adt/pseudotypes.c:478 -#, c-format -msgid "cannot display a value of type opaque" -msgstr "无法显示一个 opaque 类型值" +#: utils/adt/pg_locale.c:1606 utils/adt/pg_locale.c:1615 +#: utils/adt/pg_locale.c:1644 utils/adt/pg_locale.c:1654 +#, fuzzy, c-format +#| msgid "pclose failed: %s" +msgid "%s failed: %s" +msgstr "pclose调用失败: %s" -#: utils/adt/pseudotypes.c:492 +#: utils/adt/pg_locale.c:1926 #, c-format -msgid "cannot accept a value of type anyelement" -msgstr "无法接å—一个 anyelement 类型值" +msgid "invalid multibyte character for locale" +msgstr "无效的多字节字符, 对于 locale" -#: utils/adt/pseudotypes.c:505 +#: utils/adt/pg_locale.c:1927 #, c-format -msgid "cannot display a value of type anyelement" -msgstr "无法显示一个 anyelement 类型值" +msgid "The server's LC_CTYPE locale is probably incompatible with the database encoding." +msgstr "æœåŠ¡å™¨æœ¬åœ° LC_CTYPE å¯èƒ½ä¸Žæ•°æ®åº“ç¼–ç ä¸å…¼å®¹." -#: utils/adt/pseudotypes.c:518 +#: utils/adt/pg_upgrade_support.c:29 #, c-format -msgid "cannot accept a value of type anynonarray" -msgstr "无法接å—一个anynonarray类型值" +msgid "function can only be called when server is in binary upgrade mode" +msgstr "åªæœ‰å½“æœåŠ¡å™¨å¤„äºŽäºŒè¿›åˆ¶å‡çº§æ¨¡å¼æ—¶æ‰èƒ½è°ƒç”¨å‡½æ•°" -#: utils/adt/pseudotypes.c:531 +#: utils/adt/pgstatfuncs.c:479 #, c-format -msgid "cannot display a value of type anynonarray" -msgstr "无法显示一个anynonarray类型的值" +msgid "invalid command name: \"%s\"" +msgstr "无效的命令å:\"%s\"" -#: utils/adt/pseudotypes.c:544 +#: utils/adt/pseudotypes.c:247 #, c-format msgid "cannot accept a value of a shell type" msgstr "无法接å—一个shell类型的值" -#: utils/adt/pseudotypes.c:557 +#: utils/adt/pseudotypes.c:260 #, c-format msgid "cannot display a value of a shell type" msgstr "无法显示一个shell类型值" -#: utils/adt/pseudotypes.c:579 utils/adt/pseudotypes.c:604 -#: utils/adt/pseudotypes.c:632 utils/adt/pseudotypes.c:660 -#, c-format -msgid "cannot accept a value of type %s" -msgstr "无法接å—一个类型%s的值" - -#: utils/adt/pseudotypes.c:647 utils/adt/pseudotypes.c:673 +#: utils/adt/pseudotypes.c:350 utils/adt/pseudotypes.c:376 #, c-format msgid "cannot output a value of type %s" msgstr "无法输出一个类型%s的值" -#: utils/adt/rangetypes.c:405 +#: utils/adt/pseudotypes.c:403 +#, c-format +msgid "cannot display a value of type %s" +msgstr "无法显示类型为%s的值" + +#: utils/adt/rangetypes.c:406 #, c-format msgid "range constructor flags argument must not be null" msgstr "èŒƒå›´æž„é€ å™¨çš„å‚æ•°ä¸èƒ½ä¸ºNULL" -#: utils/adt/rangetypes.c:992 +#: utils/adt/rangetypes.c:993 #, c-format msgid "result of range difference would not be contiguous" msgstr "è·ç¦»å·®ç»“æžœä¸èƒ½æ˜¯è¿žç»­çš„" -#: utils/adt/rangetypes.c:1053 +#: utils/adt/rangetypes.c:1054 #, c-format msgid "result of range union would not be contiguous" msgstr "范围并的结果ä¸èƒ½æ˜¯è¿žç»­çš„" -#: utils/adt/rangetypes.c:1543 +#: utils/adt/rangetypes.c:1598 #, c-format msgid "range lower bound must be less than or equal to range upper bound" msgstr "范围下é™å¿…é¡»å°äºŽæˆ–等于其上é™" -#: utils/adt/rangetypes.c:1926 utils/adt/rangetypes.c:1939 -#: utils/adt/rangetypes.c:1953 +#: utils/adt/rangetypes.c:1981 utils/adt/rangetypes.c:1994 +#: utils/adt/rangetypes.c:2008 #, c-format msgid "invalid range bound flags" msgstr "无效的范围边界标记" -#: utils/adt/rangetypes.c:1927 utils/adt/rangetypes.c:1940 -#: utils/adt/rangetypes.c:1954 +#: utils/adt/rangetypes.c:1982 utils/adt/rangetypes.c:1995 +#: utils/adt/rangetypes.c:2009 #, c-format msgid "Valid values are \"[]\", \"[)\", \"(]\", and \"()\"." msgstr "有效值为\"[]\", \"[)\", \"(]\", å’Œ \"()\"." -#: utils/adt/rangetypes.c:2019 utils/adt/rangetypes.c:2036 -#: utils/adt/rangetypes.c:2049 utils/adt/rangetypes.c:2067 -#: utils/adt/rangetypes.c:2078 utils/adt/rangetypes.c:2122 -#: utils/adt/rangetypes.c:2130 +#: utils/adt/rangetypes.c:2074 utils/adt/rangetypes.c:2091 +#: utils/adt/rangetypes.c:2104 utils/adt/rangetypes.c:2122 +#: utils/adt/rangetypes.c:2133 utils/adt/rangetypes.c:2177 +#: utils/adt/rangetypes.c:2185 #, c-format msgid "malformed range literal: \"%s\"" msgstr "有缺陷的范围字串:\"%s\"" -#: utils/adt/rangetypes.c:2021 +#: utils/adt/rangetypes.c:2076 #, c-format msgid "Junk after \"empty\" key word." msgstr "\"empty\" å…³é”®å­—åŽæœ‰Junk标识." -#: utils/adt/rangetypes.c:2038 +#: utils/adt/rangetypes.c:2093 #, c-format msgid "Missing left parenthesis or bracket." msgstr "缺少一个左大括弧或左方括弧." -#: utils/adt/rangetypes.c:2051 +#: utils/adt/rangetypes.c:2106 #, c-format msgid "Missing comma after lower bound." msgstr "下界åŽç¼ºå°‘逗å·." -#: utils/adt/rangetypes.c:2069 +#: utils/adt/rangetypes.c:2124 #, c-format msgid "Too many commas." msgstr "太多逗å·." -#: utils/adt/rangetypes.c:2080 +#: utils/adt/rangetypes.c:2135 #, c-format msgid "Junk after right parenthesis or bracket." msgstr "å³å¤§æ‹¬å·æˆ–å³ä¸­æ‹¬å¼§åŽçš„内容无用." -#: utils/adt/regexp.c:285 utils/adt/regexp.c:1288 utils/adt/varlena.c:3829 +#: utils/adt/regexp.c:289 utils/adt/regexp.c:1490 utils/adt/varlena.c:4476 #, c-format msgid "regular expression failed: %s" msgstr "正则表达å¼å¤±è´¥: %s" -#: utils/adt/regexp.c:422 +#: utils/adt/regexp.c:426 +#, fuzzy, c-format +#| msgid "invalid regular expression: %s" +msgid "invalid regular expression option: \"%c\"" +msgstr "无效的正则表达å¼: %s" + +#: utils/adt/regexp.c:838 +#, c-format +msgid "SQL regular expression may not contain more than two escape-double-quote separators" +msgstr "" + +#. translator: %s is a SQL function name +#: utils/adt/regexp.c:924 utils/adt/regexp.c:1307 utils/adt/regexp.c:1362 +#, fuzzy, c-format +#| msgid "regexp_match does not support the global option" +msgid "%s does not support the \"global\" option" +msgstr "regexp_match 䏿”¯æŒå…¨å±€é€‰é¡¹" + +#: utils/adt/regexp.c:926 #, c-format -msgid "invalid regexp option: \"%c\"" -msgstr "无效的正则表达å¼é€‰é¡¹: \"%c\"" +msgid "Use the regexp_matches function instead." +msgstr "改用regexp_matches函数" -#: utils/adt/regexp.c:948 +#: utils/adt/regexp.c:1108 #, c-format -msgid "regexp_split does not support the global option" -msgstr "regexp_split 䏿”¯æŒå…¨å±€é€‰é¡¹" +msgid "too many regular expression matches" +msgstr "匹é…的正则表达å¼å¤ªå¤š" -#: utils/adt/regproc.c:128 utils/adt/regproc.c:148 +#: utils/adt/regproc.c:106 #, c-format msgid "more than one function named \"%s\"" msgstr "多个函数å为 \"%s\"" -#: utils/adt/regproc.c:587 utils/adt/regproc.c:607 +#: utils/adt/regproc.c:524 #, c-format msgid "more than one operator named %s" msgstr "多个æ“作符å为 %s" -#: utils/adt/regproc.c:779 utils/adt/regproc.c:820 utils/adt/regproc.c:2006 -#: utils/adt/ruleutils.c:8173 utils/adt/ruleutils.c:8298 +#: utils/adt/regproc.c:691 utils/adt/regproc.c:732 gram.y:8145 +#, c-format +msgid "missing argument" +msgstr "ç¼ºå°‘å‚æ•°" + +#: utils/adt/regproc.c:692 utils/adt/regproc.c:733 gram.y:8146 +#, c-format +msgid "Use NONE to denote the missing argument of a unary operator." +msgstr "使用 NONE 表示一元æ“ä½œç¬¦ç¼ºå°‘çš„å‚æ•°." + +#: utils/adt/regproc.c:696 utils/adt/regproc.c:737 utils/adt/regproc.c:1865 +#: utils/adt/ruleutils.c:9210 utils/adt/ruleutils.c:9378 #, c-format msgid "too many arguments" msgstr "å¤ªå¤šå‚æ•°" -#: utils/adt/regproc.c:780 utils/adt/regproc.c:821 +#: utils/adt/regproc.c:697 utils/adt/regproc.c:738 #, c-format msgid "Provide two argument types for operator." msgstr "为æ“作符æä¾›ä¸¤ä¸ªå‚数类型." -#: utils/adt/regproc.c:1594 utils/adt/regproc.c:1618 utils/adt/regproc.c:1715 -#: utils/adt/regproc.c:1739 utils/adt/regproc.c:1841 utils/adt/regproc.c:1846 -#: utils/adt/varlena.c:3084 utils/adt/varlena.c:3089 +#: utils/adt/regproc.c:1449 utils/adt/regproc.c:1473 utils/adt/regproc.c:1574 +#: utils/adt/regproc.c:1598 utils/adt/regproc.c:1700 utils/adt/regproc.c:1705 +#: utils/adt/varlena.c:3625 utils/adt/varlena.c:3630 #, c-format msgid "invalid name syntax" msgstr "无效的å字语法" -#: utils/adt/regproc.c:1904 +#: utils/adt/regproc.c:1763 #, c-format msgid "expected a left parenthesis" msgstr "需è¦ä¸€ä¸ªå·¦æ‹¬å¼§" -#: utils/adt/regproc.c:1920 +#: utils/adt/regproc.c:1779 #, c-format msgid "expected a right parenthesis" msgstr "需è¦ä¸€ä¸ªå³æ‹¬å¼§" -#: utils/adt/regproc.c:1939 +#: utils/adt/regproc.c:1798 #, c-format msgid "expected a type name" msgstr "需è¦ä¸€ä¸ªç±»åž‹åå­—" -#: utils/adt/regproc.c:1971 +#: utils/adt/regproc.c:1830 #, c-format msgid "improper type name" msgstr "䏿­£ç¡®çš„类型åå­—" -#: utils/adt/ri_triggers.c:345 utils/adt/ri_triggers.c:2492 -#: utils/adt/ri_triggers.c:3317 +#: utils/adt/ri_triggers.c:298 utils/adt/ri_triggers.c:1534 +#: utils/adt/ri_triggers.c:2465 #, c-format msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" msgstr "æ’入或更新表 \"%s\" è¿åå¤–é”®çº¦æŸ \"%s\"" -#: utils/adt/ri_triggers.c:348 utils/adt/ri_triggers.c:2495 +#: utils/adt/ri_triggers.c:301 utils/adt/ri_triggers.c:1537 #, c-format msgid "MATCH FULL does not allow mixing of null and nonnull key values." msgstr "MATCH FULL ä¸å…许空和éžç©ºé”®å€¼çš„æ··åˆ." -#: utils/adt/ri_triggers.c:2734 +#: utils/adt/ri_triggers.c:1932 #, c-format msgid "function \"%s\" must be fired for INSERT" msgstr "函数 \"%s\"必须为INSERTæ“作触å‘" -#: utils/adt/ri_triggers.c:2740 +#: utils/adt/ri_triggers.c:1938 #, c-format msgid "function \"%s\" must be fired for UPDATE" msgstr "函数 \"%s\"必须为UPDATEæ“作触å‘" -#: utils/adt/ri_triggers.c:2746 +#: utils/adt/ri_triggers.c:1944 #, c-format msgid "function \"%s\" must be fired for DELETE" msgstr "函数 \"%s\"必须为DELETEæ“作触å‘" -#: utils/adt/ri_triggers.c:2769 +#: utils/adt/ri_triggers.c:1967 #, c-format msgid "no pg_constraint entry for trigger \"%s\" on table \"%s\"" msgstr "在pg_constraint上没有对于表 \"%2$s\" 上的触å‘器 \"%1$s\" 的项" -#: utils/adt/ri_triggers.c:2771 +#: utils/adt/ri_triggers.c:1969 #, c-format -msgid "" -"Remove this referential integrity trigger and its mates, then do ALTER TABLE " -"ADD CONSTRAINT." -msgstr "" -"删除这个å‚照完整性触å‘å™¨å’Œä¸Žå®ƒç›¸å…³çš„å¯¹è±¡ï¼Œç„¶åŽæ‰§è¡ŒALTER TABLE ADD CONSTRAINT" -"æ“作." +msgid "Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT." +msgstr "删除这个å‚照完整性触å‘å™¨å’Œä¸Žå®ƒç›¸å…³çš„å¯¹è±¡ï¼Œç„¶åŽæ‰§è¡ŒALTER TABLE ADD CONSTRAINTæ“作." -#: utils/adt/ri_triggers.c:3227 +#: utils/adt/ri_triggers.c:1999 gram.y:3784 #, c-format -msgid "" -"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave " -"unexpected result" -msgstr "" -"从在\"%3$s\"的约æŸ\"%2$s\"中在\"%1$s\"上执行的å‚ç…§å®Œæ•´æ€§æŸ¥è¯¢å¾—å‡ºéžæœŸå¾…结果." +msgid "MATCH PARTIAL not yet implemented" +msgstr "MATCH PARTIAL 仿œªå®žçް" -#: utils/adt/ri_triggers.c:3231 +#: utils/adt/ri_triggers.c:2291 +#, c-format +msgid "referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result" +msgstr "从在\"%3$s\"的约æŸ\"%2$s\"中在\"%1$s\"上执行的å‚ç…§å®Œæ•´æ€§æŸ¥è¯¢å¾—å‡ºéžæœŸå¾…结果." + +#: utils/adt/ri_triggers.c:2295 #, c-format msgid "This is most likely due to a rule having rewritten the query." msgstr "这很å¯èƒ½æ˜¯ç”±äºŽè§„则正在é‡å†™æŸ¥è¯¢" -#: utils/adt/ri_triggers.c:3321 +#: utils/adt/ri_triggers.c:2456 +#, fuzzy, c-format +#| msgid "insert or update on table \"%s\" violates foreign key constraint \"%s\"" +msgid "removing partition \"%s\" violates foreign key constraint \"%s\"" +msgstr "æ’入或更新表 \"%s\" è¿åå¤–é”®çº¦æŸ \"%s\"" + +#: utils/adt/ri_triggers.c:2459 +#, fuzzy, c-format +#| msgid "Key (%s)=(%s) is still referenced from table \"%s\"." +msgid "Key (%s)=(%s) still referenced from table \"%s\"." +msgstr "键值对(%s)=(%s)ä»ç„¶æ˜¯ä»Žè¡¨\"%s\"引用的." + +#: utils/adt/ri_triggers.c:2469 #, c-format msgid "Key (%s)=(%s) is not present in table \"%s\"." msgstr "键值对(%s)=(%s)没有在表\"%s\"中出现." -#: utils/adt/ri_triggers.c:3324 +#: utils/adt/ri_triggers.c:2472 #, c-format msgid "Key is not present in table \"%s\"." msgstr "表\"%s\"中没有出现键。" -#: utils/adt/ri_triggers.c:3330 +#: utils/adt/ri_triggers.c:2478 #, c-format -msgid "" -"update or delete on table \"%s\" violates foreign key constraint \"%s\" on " -"table \"%s\"" +msgid "update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"" msgstr "在 \"%1$s\" 上的更新或删除æ“作è¿å了在 \"%3$s\" ä¸Šçš„å¤–é”®çº¦æŸ \"%2$s\"" -#: utils/adt/ri_triggers.c:3335 +#: utils/adt/ri_triggers.c:2483 #, c-format msgid "Key (%s)=(%s) is still referenced from table \"%s\"." msgstr "键值对(%s)=(%s)ä»ç„¶æ˜¯ä»Žè¡¨\"%s\"引用的." -#: utils/adt/ri_triggers.c:3338 +#: utils/adt/ri_triggers.c:2486 #, c-format msgid "Key is still referenced from table \"%s\"." msgstr "表\"%s\"中ä»ç„¶æœ‰å¯¹é”®çš„引用。" -#: utils/adt/rowtypes.c:103 utils/adt/rowtypes.c:479 +#: utils/adt/rowtypes.c:104 utils/adt/rowtypes.c:482 #, c-format msgid "input of anonymous composite types is not implemented" msgstr "匿åå¤åˆç±»åž‹è¾“入仿œªå®žçް" -#: utils/adt/rowtypes.c:155 utils/adt/rowtypes.c:183 utils/adt/rowtypes.c:206 -#: utils/adt/rowtypes.c:214 utils/adt/rowtypes.c:266 utils/adt/rowtypes.c:274 +#: utils/adt/rowtypes.c:156 utils/adt/rowtypes.c:185 utils/adt/rowtypes.c:208 +#: utils/adt/rowtypes.c:216 utils/adt/rowtypes.c:268 utils/adt/rowtypes.c:276 #, c-format msgid "malformed record literal: \"%s\"" msgstr "有缺陷的记录常é‡: \"%s\"" -#: utils/adt/rowtypes.c:156 +#: utils/adt/rowtypes.c:157 #, c-format msgid "Missing left parenthesis." msgstr "缺少一个左括弧" -#: utils/adt/rowtypes.c:184 +#: utils/adt/rowtypes.c:186 #, c-format msgid "Too few columns." msgstr "字段太少." -#: utils/adt/rowtypes.c:267 +#: utils/adt/rowtypes.c:269 #, c-format msgid "Too many columns." msgstr "太多字段." -#: utils/adt/rowtypes.c:275 +#: utils/adt/rowtypes.c:277 #, c-format msgid "Junk after right parenthesis." msgstr "峿‹¬å·åŽçš„内容无用." -#: utils/adt/rowtypes.c:528 +#: utils/adt/rowtypes.c:531 #, c-format msgid "wrong number of columns: %d, expected %d" msgstr "错误的字段个数: %d, 期望为 %d" -#: utils/adt/rowtypes.c:555 +#: utils/adt/rowtypes.c:559 #, c-format msgid "wrong data type: %u, expected %u" msgstr "错误的数æ®ç±»åž‹: %u, 期望为 %u" -#: utils/adt/rowtypes.c:616 +#: utils/adt/rowtypes.c:620 #, c-format msgid "improper binary format in record column %d" msgstr "在记录字段 %d ä¸ºä¸æ­£ç¡®çš„二进制格å¼" -#: utils/adt/rowtypes.c:902 utils/adt/rowtypes.c:1142 -#: utils/adt/rowtypes.c:1396 utils/adt/rowtypes.c:1673 +#: utils/adt/rowtypes.c:911 utils/adt/rowtypes.c:1155 utils/adt/rowtypes.c:1414 +#: utils/adt/rowtypes.c:1658 #, c-format msgid "cannot compare dissimilar column types %s and %s at record column %d" msgstr "在记录列%3$d上ä¸èƒ½å¯¹ä¸ç›¸ä¼¼çš„列类型%1$så’Œ%2$s进行比较" -#: utils/adt/rowtypes.c:991 utils/adt/rowtypes.c:1213 -#: utils/adt/rowtypes.c:1529 utils/adt/rowtypes.c:1769 +#: utils/adt/rowtypes.c:1000 utils/adt/rowtypes.c:1226 +#: utils/adt/rowtypes.c:1509 utils/adt/rowtypes.c:1694 #, c-format msgid "cannot compare record types with different numbers of columns" msgstr "无法比较ä¸åŒå…ƒç´ ç±»åž‹çš„æ•°ç»„" -#: utils/adt/ruleutils.c:4153 +#: utils/adt/ruleutils.c:4885 #, c-format msgid "rule \"%s\" has unsupported event type %d" msgstr "规则 \"%s\" 䏿”¯æŒäº‹ä»¶ç±»åž‹ %d" -#: utils/adt/selfuncs.c:5314 -#, c-format -msgid "case insensitive matching not supported on type bytea" -msgstr "在类型byteaä¸Šä¸æ”¯æŒå¯¹ä¸åŒºåˆ†å¤§å°å†™çš„匹é…" - -#: utils/adt/selfuncs.c:5417 -#, c-format -msgid "regular-expression matching not supported on type bytea" -msgstr "在 bytea ç±»åž‹ä¸Šä¸æ”¯æŒæ­£åˆ™è¡¨è¾¾å¼åŒ¹é…" - -#: utils/adt/tid.c:71 utils/adt/tid.c:79 utils/adt/tid.c:87 -#, c-format -msgid "invalid input syntax for type tid: \"%s\"" -msgstr "无效的 tid 类型输入语法: \"%s\"" - -#: utils/adt/timestamp.c:99 +#: utils/adt/timestamp.c:107 #, c-format msgid "TIMESTAMP(%d)%s precision must not be negative" msgstr "TIMESTAMP(%d)%s 精确度ä¸èƒ½ä¸ºè´Ÿæ•°" -#: utils/adt/timestamp.c:105 +#: utils/adt/timestamp.c:113 #, c-format msgid "TIMESTAMP(%d)%s precision reduced to maximum allowed, %d" msgstr "å°†TIMESTAMP(%d)%så‡å°‘到最大å…许值,%d" -#: utils/adt/timestamp.c:170 utils/adt/timestamp.c:445 +#: utils/adt/timestamp.c:176 utils/adt/timestamp.c:427 #, c-format msgid "timestamp out of range: \"%s\"" msgstr "时间戳超出范围: \"%s\"" -#: utils/adt/timestamp.c:188 utils/adt/timestamp.c:463 -#: utils/adt/timestamp.c:993 +#: utils/adt/timestamp.c:194 utils/adt/timestamp.c:445 +#: utils/adt/timestamp.c:952 #, c-format msgid "date/time value \"%s\" is no longer supported" msgstr "日期/时间值 \"%s\" ä¸å†è¢«æ”¯æŒ" -#: utils/adt/timestamp.c:258 utils/adt/timestamp.c:754 -#, c-format -msgid "timestamp cannot be NaN" -msgstr "时间戳ä¸èƒ½æ˜¯NaN" - -#: utils/adt/timestamp.c:380 +#: utils/adt/timestamp.c:373 #, c-format msgid "timestamp(%d) precision must be between %d and %d" msgstr "timestamp(%d) 的精确度必需在 %d 到 %d 之间" -#: utils/adt/timestamp.c:513 -#, c-format -msgid "invalid input syntax for numeric time zone: \"%s\"" -msgstr "数字时区使用了无效的输入语法: \"%s\"" - -#: utils/adt/timestamp.c:515 +#: utils/adt/timestamp.c:497 #, c-format msgid "Numeric time zones must have \"-\" or \"+\" as first character." msgstr "数字时区必须是以\"-\" or \"+\" 作为第一个字符." -#: utils/adt/timestamp.c:528 +#: utils/adt/timestamp.c:510 #, c-format msgid "numeric time zone \"%s\" out of range" msgstr "数字时区\"%s\"超出范围" -#: utils/adt/timestamp.c:631 utils/adt/timestamp.c:641 -#: utils/adt/timestamp.c:653 +#: utils/adt/timestamp.c:612 utils/adt/timestamp.c:622 +#: utils/adt/timestamp.c:630 #, c-format msgid "timestamp out of range: %d-%02d-%02d %d:%02d:%02g" msgstr "时间戳超出范围:%d-%02d-%02d %d:%02d:%02g" -#: utils/adt/timestamp.c:770 utils/adt/timestamp.c:776 -#: utils/adt/timestamp.c:791 +#: utils/adt/timestamp.c:731 +#, c-format +msgid "timestamp cannot be NaN" +msgstr "时间戳ä¸èƒ½æ˜¯NaN" + +#: utils/adt/timestamp.c:749 utils/adt/timestamp.c:761 #, c-format -#| msgid "timestamp out of range: \"%s\"" msgid "timestamp out of range: \"%g\"" msgstr "时间戳超出范围: \"%g\"" -#: utils/adt/timestamp.c:987 utils/adt/timestamp.c:1558 -#: utils/adt/timestamp.c:2068 utils/adt/timestamp.c:3220 -#: utils/adt/timestamp.c:3225 utils/adt/timestamp.c:3230 -#: utils/adt/timestamp.c:3280 utils/adt/timestamp.c:3287 -#: utils/adt/timestamp.c:3294 utils/adt/timestamp.c:3314 -#: utils/adt/timestamp.c:3321 utils/adt/timestamp.c:3328 -#: utils/adt/timestamp.c:3358 utils/adt/timestamp.c:3366 -#: utils/adt/timestamp.c:3411 utils/adt/timestamp.c:3751 -#: utils/adt/timestamp.c:3880 utils/adt/timestamp.c:4271 +#: utils/adt/timestamp.c:946 utils/adt/timestamp.c:1526 +#: utils/adt/timestamp.c:1959 utils/adt/timestamp.c:3057 +#: utils/adt/timestamp.c:3062 utils/adt/timestamp.c:3067 +#: utils/adt/timestamp.c:3117 utils/adt/timestamp.c:3124 +#: utils/adt/timestamp.c:3131 utils/adt/timestamp.c:3151 +#: utils/adt/timestamp.c:3158 utils/adt/timestamp.c:3165 +#: utils/adt/timestamp.c:3195 utils/adt/timestamp.c:3203 +#: utils/adt/timestamp.c:3247 utils/adt/timestamp.c:3674 +#: utils/adt/timestamp.c:3799 utils/adt/timestamp.c:4259 #, c-format msgid "interval out of range" msgstr "interval 超出范围" -#: utils/adt/timestamp.c:1128 utils/adt/timestamp.c:1161 +#: utils/adt/timestamp.c:1079 utils/adt/timestamp.c:1112 #, c-format msgid "invalid INTERVAL type modifier" msgstr "无效的INTERVAL类型修改器" -#: utils/adt/timestamp.c:1144 +#: utils/adt/timestamp.c:1095 #, c-format msgid "INTERVAL(%d) precision must not be negative" msgstr "INTERVAL(%d) 的精确度ä¸èƒ½ä¸ºè´Ÿæ•°" -#: utils/adt/timestamp.c:1150 +#: utils/adt/timestamp.c:1101 #, c-format msgid "INTERVAL(%d) precision reduced to maximum allowed, %d" msgstr "å°†INTERVAL(%d)å‡å°‘到最大å…许值,%d" -#: utils/adt/timestamp.c:1502 +#: utils/adt/timestamp.c:1483 #, c-format msgid "interval(%d) precision must be between %d and %d" msgstr "interval(%d) 的精确度必需在 %d 到 %d 之间" -#: utils/adt/timestamp.c:2797 +#: utils/adt/timestamp.c:2658 #, c-format msgid "cannot subtract infinite timestamps" msgstr "无法å‡åŽ»æ— é™é•¿çš„æ—¶é—´æˆ³" -#: utils/adt/timestamp.c:4006 utils/adt/timestamp.c:4531 -#: utils/adt/timestamp.c:4715 utils/adt/timestamp.c:4740 +#: utils/adt/timestamp.c:3927 utils/adt/timestamp.c:4519 +#: utils/adt/timestamp.c:4686 utils/adt/timestamp.c:4707 #, c-format msgid "timestamp units \"%s\" not supported" msgstr "䏿”¯æŒæ—¶é—´æˆ³å•ä½ \"%s\"" -#: utils/adt/timestamp.c:4020 utils/adt/timestamp.c:4485 -#: utils/adt/timestamp.c:4750 +#: utils/adt/timestamp.c:3941 utils/adt/timestamp.c:4473 +#: utils/adt/timestamp.c:4717 #, c-format msgid "timestamp units \"%s\" not recognized" msgstr "时间戳å•ä½ \"%s\" ä¸è¢«è®¤å¯" -#: utils/adt/timestamp.c:4160 utils/adt/timestamp.c:4526 -#: utils/adt/timestamp.c:4937 utils/adt/timestamp.c:4963 +#: utils/adt/timestamp.c:4071 utils/adt/timestamp.c:4514 +#: utils/adt/timestamp.c:4887 utils/adt/timestamp.c:4909 #, c-format msgid "timestamp with time zone units \"%s\" not supported" msgstr "䏿”¯æŒå¸¦æ—¶åŒºçš„æ—¶é—´æˆ³å•ä½ \"%s\"" -#: utils/adt/timestamp.c:4177 utils/adt/timestamp.c:4480 -#: utils/adt/timestamp.c:4972 +#: utils/adt/timestamp.c:4088 utils/adt/timestamp.c:4468 +#: utils/adt/timestamp.c:4918 #, c-format msgid "timestamp with time zone units \"%s\" not recognized" msgstr "带时区的时间戳å•ä½ \"%s\" ä¸è¢«è®¤å¯" -#: utils/adt/timestamp.c:4258 +#: utils/adt/timestamp.c:4246 #, c-format -msgid "" -"interval units \"%s\" not supported because months usually have fractional " -"weeks" +msgid "interval units \"%s\" not supported because months usually have fractional weeks" msgstr "时间间隔的å•ä½ \"%s\"䏿”¯æŒä½¿ç”¨ï¼Œå› ä¸ºæœˆä»¥å‘¨æ¥è®¡ç®—时,通常带有分数值" -#: utils/adt/timestamp.c:4264 utils/adt/timestamp.c:5078 +#: utils/adt/timestamp.c:4252 utils/adt/timestamp.c:5012 #, c-format msgid "interval units \"%s\" not supported" msgstr "䏿”¯æŒ \"%s\" çš„ interval å•ä½" -#: utils/adt/timestamp.c:4280 utils/adt/timestamp.c:5105 +#: utils/adt/timestamp.c:4268 utils/adt/timestamp.c:5035 #, c-format msgid "interval units \"%s\" not recognized" msgstr "interval å•ä½ \"%s\" ä¸è¢«è®¤å¯" @@ -21118,334 +22800,346 @@ msgstr "suppress_redundant_updates_trigger: 必须在更新æ“作å‰è°ƒç”¨" msgid "suppress_redundant_updates_trigger: must be called for each row" msgstr "suppress_redundant_updates_trigger: å¿…é¡»ä¸ºæ¯æ¡è®°å½•调用" -#: utils/adt/tsgistidx.c:99 +#: utils/adt/tsgistidx.c:81 #, c-format msgid "gtsvector_in not implemented" msgstr "没有实现gtsvector_in" -#: utils/adt/tsquery.c:166 +#: utils/adt/tsquery.c:200 #, c-format msgid "distance in phrase operator should not be greater than %d" msgstr "短语æ“作符中的è·ç¦»ä¸åº”该大于 %d" -#: utils/adt/tsquery.c:254 utils/adt/tsquery.c:513 -#: utils/adt/tsvector_parser.c:141 +#: utils/adt/tsquery.c:310 utils/adt/tsquery.c:725 +#: utils/adt/tsvector_parser.c:133 #, c-format msgid "syntax error in tsquery: \"%s\"" msgstr "在tsquery中的语法错误:\"%s\"" -#: utils/adt/tsquery.c:275 +#: utils/adt/tsquery.c:334 #, c-format msgid "no operand in tsquery: \"%s\"" msgstr "在tsquery中没有æ“作数:\"%s\"" -#: utils/adt/tsquery.c:358 +#: utils/adt/tsquery.c:568 #, c-format msgid "value is too big in tsquery: \"%s\"" msgstr "在tsquery中的值太大了:\"%s\"" -#: utils/adt/tsquery.c:363 +#: utils/adt/tsquery.c:573 #, c-format msgid "operand is too long in tsquery: \"%s\"" msgstr "在tsquery中æ“作数太长了: \"%s\"" -#: utils/adt/tsquery.c:391 +#: utils/adt/tsquery.c:601 #, c-format msgid "word is too long in tsquery: \"%s\"" msgstr "在tsquery中的è¯å¤ªé•¿äº†:\"%s\" " -#: utils/adt/tsquery.c:648 +#: utils/adt/tsquery.c:870 #, c-format msgid "text-search query doesn't contain lexemes: \"%s\"" msgstr "文本æœç´¢æŸ¥è¯¢æ²¡æœ‰åŒ…å«è¯æ±‡å•ä½:\"%s\"" -#: utils/adt/tsquery.c:659 utils/adt/tsquery_util.c:347 +#: utils/adt/tsquery.c:881 utils/adt/tsquery_util.c:375 #, c-format msgid "tsquery is too large" msgstr "tsquery查询太大" -#: utils/adt/tsquery_cleanup.c:580 +#: utils/adt/tsquery_cleanup.c:407 #, c-format -msgid "" -"text-search query contains only stop words or doesn't contain lexemes, " -"ignored" +msgid "text-search query contains only stop words or doesn't contain lexemes, ignored" msgstr "文本æœç´¢æŸ¥è¯¢åªåŒ…å«ç»“æŸè¯æˆ–者ä¸åŒ…å«è¯æ±‡å•ä½, 被忽略" -#: utils/adt/tsquery_op.c:122 +#: utils/adt/tsquery_op.c:123 #, c-format msgid "distance in phrase operator should be non-negative and less than %d" msgstr "短语æ“作符中的è·ç¦»åº”该为éžè´Ÿå¹¶ä¸”å°äºŽ %d" -#: utils/adt/tsquery_rewrite.c:292 +#: utils/adt/tsquery_rewrite.c:321 #, c-format msgid "ts_rewrite query must return two tsquery columns" msgstr "ts_rewrite查询必须返回两个tsquery字段的记录" -#: utils/adt/tsrank.c:412 +#: utils/adt/tsrank.c:413 #, c-format msgid "array of weight must be one-dimensional" msgstr "æƒé‡æ•°ç»„必须为空或者一维数组" -#: utils/adt/tsrank.c:417 +#: utils/adt/tsrank.c:418 #, c-format msgid "array of weight is too short" msgstr "æƒé‡æ•°ç»„太短了." -#: utils/adt/tsrank.c:422 +#: utils/adt/tsrank.c:423 #, c-format msgid "array of weight must not contain nulls" msgstr "æƒé‡æ•°ç»„ä¸èƒ½åŒ…å«ç©ºå€¼" -#: utils/adt/tsrank.c:431 utils/adt/tsrank.c:862 +#: utils/adt/tsrank.c:432 utils/adt/tsrank.c:869 #, c-format msgid "weight out of range" msgstr "æƒé‡ 超出范围" -#: utils/adt/tsvector.c:213 +#: utils/adt/tsvector.c:214 #, c-format msgid "word is too long (%ld bytes, max %ld bytes)" msgstr "è¯å¤ªé•¿äº†(%ld字节, 最大 %ld 字节)" -#: utils/adt/tsvector.c:220 +#: utils/adt/tsvector.c:221 #, c-format msgid "string is too long for tsvector (%ld bytes, max %ld bytes)" msgstr "字符串对于tsvectoræ¥è¯´å¤ªé•¿äº†(å½“å‰ %ld字节, 最大å…许值是%ld字节)" -#: utils/adt/tsvector_op.c:317 utils/adt/tsvector_op.c:565 -#: utils/adt/tsvector_op.c:731 +#: utils/adt/tsvector_op.c:321 utils/adt/tsvector_op.c:608 +#: utils/adt/tsvector_op.c:776 #, c-format -#| msgid "array must not contain nulls" msgid "lexeme array may not contain nulls" msgstr "è¯ä½æ•°ç»„ä¸èƒ½åŒ…å«ç©ºå€¼" -#: utils/adt/tsvector_op.c:789 +#: utils/adt/tsvector_op.c:851 #, c-format -#| msgid "array must not contain nulls" msgid "weight array may not contain nulls" msgstr "æƒé‡æ•°ç»„ä¸èƒ½åŒ…å«ç©ºå€¼" -#: utils/adt/tsvector_op.c:1976 +#: utils/adt/tsvector_op.c:875 +#, c-format +msgid "unrecognized weight: \"%c\"" +msgstr "无法识别的æƒé‡: \"%c\"" + +#: utils/adt/tsvector_op.c:2312 #, c-format msgid "ts_stat query must return one tsvector column" msgstr "ts_stat查询必须在tsvector类型列上返回" -#: utils/adt/tsvector_op.c:2158 +#: utils/adt/tsvector_op.c:2494 #, c-format msgid "tsvector column \"%s\" does not exist" msgstr "tsvector字段 \"%s\" ä¸å­˜åœ¨" -#: utils/adt/tsvector_op.c:2164 +#: utils/adt/tsvector_op.c:2501 #, c-format msgid "column \"%s\" is not of tsvector type" msgstr "列\"%s\"ä¸å±žäºŽtsvector类型" -#: utils/adt/tsvector_op.c:2176 +#: utils/adt/tsvector_op.c:2513 #, c-format msgid "configuration column \"%s\" does not exist" msgstr "é…置字段 \"%s\" ä¸å­˜åœ¨" -#: utils/adt/tsvector_op.c:2182 +#: utils/adt/tsvector_op.c:2519 #, c-format msgid "column \"%s\" is not of regconfig type" msgstr "列\"%s\"ä¸å±žäºŽregconfig类型" -#: utils/adt/tsvector_op.c:2189 +#: utils/adt/tsvector_op.c:2526 #, c-format msgid "configuration column \"%s\" must not be null" msgstr "é…置列\"%s\"ä¸èƒ½ä¸ºç©º" -#: utils/adt/tsvector_op.c:2202 +#: utils/adt/tsvector_op.c:2539 #, c-format msgid "text search configuration name \"%s\" must be schema-qualified" msgstr "文本æœç´¢é…ç½®åç§°\"%s\"必须是模å¼é™å®šçš„。" -#: utils/adt/tsvector_op.c:2227 +#: utils/adt/tsvector_op.c:2564 #, c-format msgid "column \"%s\" is not of a character type" msgstr "字段 \"%s\"ä¸å±žäºŽå­—符类型" -#: utils/adt/tsvector_parser.c:142 +#: utils/adt/tsvector_parser.c:134 #, c-format msgid "syntax error in tsvector: \"%s\"" msgstr "在tsvector中的语法错误:\"%s\" " -#: utils/adt/tsvector_parser.c:207 +#: utils/adt/tsvector_parser.c:200 #, c-format msgid "there is no escaped character: \"%s\"" msgstr "那里没有转义的字符: \"%s\"" -#: utils/adt/tsvector_parser.c:324 +#: utils/adt/tsvector_parser.c:318 #, c-format msgid "wrong position info in tsvector: \"%s\"" msgstr "在tsvector中的错误ä½ç½®ä¿¡æ¯: \"%s\"" -#: utils/adt/txid.c:339 +#: utils/adt/txid.c:140 #, c-format -msgid "invalid input syntax for type txid_snapshot: \"%s\"" -msgstr "类型txid_snapshot的无效输入语法:\"%s\"" +msgid "transaction ID %s is in the future" +msgstr "事务ID %s 在将æ¥" -#: utils/adt/txid.c:534 +#: utils/adt/txid.c:629 #, c-format msgid "invalid external txid_snapshot data" msgstr "无效的外部txid_snapshotæ•°æ®" -#: utils/adt/uuid.c:145 -#, c-format -msgid "invalid input syntax for uuid: \"%s\"" -msgstr "uuid的输入语法无效:\"%s\" " - -#: utils/adt/varbit.c:57 utils/adt/varchar.c:50 +#: utils/adt/varbit.c:60 utils/adt/varchar.c:54 #, c-format msgid "length for type %s must be at least 1" msgstr "类型 %s 的长度至少为 1" -#: utils/adt/varbit.c:62 utils/adt/varchar.c:54 +#: utils/adt/varbit.c:65 utils/adt/varchar.c:58 #, c-format msgid "length for type %s cannot exceed %d" msgstr "类型 %s 的长度ä¸èƒ½è¶…过 %d" -#: utils/adt/varbit.c:163 utils/adt/varbit.c:475 utils/adt/varbit.c:973 +#: utils/adt/varbit.c:166 utils/adt/varbit.c:478 utils/adt/varbit.c:984 #, c-format msgid "bit string length exceeds the maximum allowed (%d)" msgstr "ä½å­—符串长度超过了最大å…许值(%d)" -#: utils/adt/varbit.c:177 utils/adt/varbit.c:320 utils/adt/varbit.c:377 +#: utils/adt/varbit.c:180 utils/adt/varbit.c:323 utils/adt/varbit.c:380 #, c-format msgid "bit string length %d does not match type bit(%d)" msgstr "bit字符串的长度(%d)与bit类型(%d)ä¸åŒ¹é…." -#: utils/adt/varbit.c:199 utils/adt/varbit.c:511 +#: utils/adt/varbit.c:202 utils/adt/varbit.c:514 #, c-format msgid "\"%c\" is not a valid binary digit" msgstr "\"%c\" 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„二进制数" -#: utils/adt/varbit.c:224 utils/adt/varbit.c:536 +#: utils/adt/varbit.c:227 utils/adt/varbit.c:539 #, c-format msgid "\"%c\" is not a valid hexadecimal digit" msgstr "\"%c\" 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„å六进制数" -#: utils/adt/varbit.c:311 utils/adt/varbit.c:627 +#: utils/adt/varbit.c:314 utils/adt/varbit.c:630 #, c-format msgid "invalid length in external bit string" msgstr "无效的外部ä½ä¸²é•¿åº¦" -#: utils/adt/varbit.c:489 utils/adt/varbit.c:636 utils/adt/varbit.c:731 +#: utils/adt/varbit.c:492 utils/adt/varbit.c:639 utils/adt/varbit.c:742 #, c-format msgid "bit string too long for type bit varying(%d)" msgstr "bit字符串对于å¯å˜bit类型(%d)æ¥è¯´å¤ªé•¿äº†." -#: utils/adt/varbit.c:1066 utils/adt/varbit.c:1168 utils/adt/varlena.c:842 -#: utils/adt/varlena.c:906 utils/adt/varlena.c:1050 utils/adt/varlena.c:2735 -#: utils/adt/varlena.c:2802 +#: utils/adt/varbit.c:1077 utils/adt/varbit.c:1179 utils/adt/varlena.c:863 +#: utils/adt/varlena.c:927 utils/adt/varlena.c:1071 utils/adt/varlena.c:3291 +#: utils/adt/varlena.c:3358 #, c-format msgid "negative substring length not allowed" msgstr "ä¸å…许å­ä¸²é•¿åº¦ä¸ºè´Ÿæ•°" -#: utils/adt/varbit.c:1226 +#: utils/adt/varbit.c:1236 #, c-format msgid "cannot AND bit strings of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„字符串进行与 (AND) ä½è¿ç®—" -#: utils/adt/varbit.c:1268 +#: utils/adt/varbit.c:1278 #, c-format msgid "cannot OR bit strings of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„字符串进行或 (OR) ä½è¿ç®—" -#: utils/adt/varbit.c:1315 +#: utils/adt/varbit.c:1325 #, c-format msgid "cannot XOR bit strings of different sizes" msgstr "无法为ä¸åŒå¤§å°çš„字符串进行异或 (XOR) ä½è¿ç®—" -#: utils/adt/varbit.c:1793 utils/adt/varbit.c:1851 +#: utils/adt/varbit.c:1813 utils/adt/varbit.c:1871 #, c-format msgid "bit index %d out of valid range (0..%d)" msgstr "比特索引 %d 超出有效范围 (0..%d)" -#: utils/adt/varbit.c:1802 utils/adt/varlena.c:3002 +#: utils/adt/varbit.c:1822 utils/adt/varlena.c:3549 #, c-format msgid "new bit must be 0 or 1" msgstr "æ–°çš„ä½å¿…须为 0 或 1" -#: utils/adt/varchar.c:154 utils/adt/varchar.c:307 +#: utils/adt/varchar.c:158 utils/adt/varchar.c:311 #, c-format msgid "value too long for type character(%d)" msgstr "对于字符类型æ¥è¯´è¿™ä¸ªå€¼å¤ªé•¿äº†(%d)" -#: utils/adt/varchar.c:469 utils/adt/varchar.c:623 +#: utils/adt/varchar.c:473 utils/adt/varchar.c:635 #, c-format msgid "value too long for type character varying(%d)" msgstr "对于å¯å˜å­—符类型æ¥è¯´ï¼Œå€¼å¤ªé•¿äº†(%d)" -#: utils/adt/varlena.c:1420 utils/adt/varlena.c:1825 +#: utils/adt/varchar.c:733 utils/adt/varlena.c:1455 #, c-format msgid "could not determine which collation to use for string comparison" msgstr "æ— æ³•ç¡®å®šå­—ç¬¦ä¸²æ¯”è¾ƒä¸­ä½¿ç”¨å“ªç§æŽ’åºè§„则" -#: utils/adt/varlena.c:1478 utils/adt/varlena.c:1491 +# sql_help.h:61 +#: utils/adt/varchar.c:1122 utils/adt/varchar.c:1232 utils/adt/varlena.c:3024 +#: utils/adt/varlena.c:3134 +#, fuzzy, c-format +#| msgid "including column does not support an operator class" +msgid "nondeterministic collations are not supported for operator class \"%s\"" +msgstr "包å«çš„åˆ—ä¸æ”¯æŒè¿ç®—符类" + +#: utils/adt/varlena.c:1165 utils/adt/varlena.c:1889 +#, fuzzy, c-format +#| msgid "could not determine which collation to use for string comparison" +msgid "nondeterministic collations are not supported for substring searches" +msgstr "æ— æ³•ç¡®å®šå­—ç¬¦ä¸²æ¯”è¾ƒä¸­ä½¿ç”¨å“ªç§æŽ’åºè§„则" + +#: utils/adt/varlena.c:1548 utils/adt/varlena.c:1561 #, c-format msgid "could not convert string to UTF-16: error code %lu" msgstr "无法将字符串转æ¢ä¸ºUTF-16ç¼–ç : é”™è¯¯ç  %lu" -#: utils/adt/varlena.c:1506 +#: utils/adt/varlena.c:1576 #, c-format msgid "could not compare Unicode strings: %m" msgstr "无法比较Unicode类型字符串: %m" -#: utils/adt/varlena.c:2880 utils/adt/varlena.c:2911 utils/adt/varlena.c:2947 -#: utils/adt/varlena.c:2990 +#: utils/adt/varlena.c:1627 utils/adt/varlena.c:2341 +#, c-format +msgid "collation failed: %s" +msgstr "排åºè§„则失败: %s" + +#: utils/adt/varlena.c:2549 +#, c-format +msgid "sort key generation failed: %s" +msgstr "排åºé”®ç”Ÿæˆå¤±è´¥: %s" + +#: utils/adt/varlena.c:3435 utils/adt/varlena.c:3466 utils/adt/varlena.c:3501 +#: utils/adt/varlena.c:3537 #, c-format msgid "index %d out of valid range, 0..%d" msgstr "索引 %d 超出有效范围, 0..%d" -#: utils/adt/varlena.c:3925 +#: utils/adt/varlena.c:4573 #, c-format msgid "field position must be greater than zero" msgstr "字段的ä½ç½®å¿…须大于0" -#: utils/adt/varlena.c:4804 +#: utils/adt/varlena.c:5439 #, c-format -#| msgid "unterminated format specifier" msgid "unterminated format() type specifier" msgstr "未结æŸçš„ format() 类型说明符" -#: utils/adt/varlena.c:4805 utils/adt/varlena.c:4939 utils/adt/varlena.c:5060 +#: utils/adt/varlena.c:5440 utils/adt/varlena.c:5574 utils/adt/varlena.c:5695 #, c-format msgid "For a single \"%%\" use \"%%%%\"." msgstr "对于å•个 \"%%\" 应使用 \"%%%%\"。" -#: utils/adt/varlena.c:4937 utils/adt/varlena.c:5058 +#: utils/adt/varlena.c:5572 utils/adt/varlena.c:5693 #, c-format -#| msgid "unrecognized conversion type specifier \"%c\"" msgid "unrecognized format() type specifier \"%c\"" msgstr "未识别的 format() 类型说明符 \"%c\"" -#: utils/adt/varlena.c:4950 +#: utils/adt/varlena.c:5585 utils/adt/varlena.c:5642 #, c-format -#| msgid "too few arguments for format" msgid "too few arguments for format()" msgstr "format() çš„å‚æ•°å¤ªå°‘" -#: utils/adt/varlena.c:5007 -#, c-format -msgid "too few arguments for format" -msgstr "æ ¼å¼åŒ–çš„å‚æ•°å¤ªå°‘" - -#: utils/adt/varlena.c:5102 utils/adt/varlena.c:5285 +#: utils/adt/varlena.c:5738 utils/adt/varlena.c:5920 #, c-format msgid "number is out of range" msgstr "数字超出范围" -#: utils/adt/varlena.c:5166 utils/adt/varlena.c:5194 +#: utils/adt/varlena.c:5801 utils/adt/varlena.c:5829 #, c-format msgid "format specifies argument 0, but arguments are numbered from 1" msgstr "æ ¼å¼æŒ‡å®šäº†å‚æ•° 0, 但傿•°å€¼åºå·ä»Ž 1开始记起" -#: utils/adt/varlena.c:5187 +#: utils/adt/varlena.c:5822 #, c-format msgid "width argument position must be ended by \"$\"" msgstr "width傿•°ä½ç½®å¿…须以\"$\"结æŸ" -#: utils/adt/varlena.c:5232 +#: utils/adt/varlena.c:5867 #, c-format msgid "null values cannot be formatted as an SQL identifier" msgstr "null值ä¸èƒ½æ ¼å¼åŒ–为SQL标识符" @@ -21460,234 +23154,224 @@ msgstr "ntileçš„å‚æ•°å¿…须大于零" msgid "argument of nth_value must be greater than zero" msgstr "nth_valueçš„å‚æ•°å¿…须大于零" -#: utils/adt/xml.c:171 +#: utils/adt/xml.c:222 #, c-format msgid "unsupported XML feature" msgstr "䏿”¯æŒçš„XML特性" -#: utils/adt/xml.c:172 +#: utils/adt/xml.c:223 #, c-format msgid "This functionality requires the server to be built with libxml support." msgstr "这个功能是需è¦åœ¨åˆ›å»ºæœåŠ¡å™¨æ—¶å¸¦æœ‰å¯¹libxmlçš„æ”¯æŒæ‰èƒ½å®žçް " -#: utils/adt/xml.c:173 +#: utils/adt/xml.c:224 #, c-format msgid "You need to rebuild PostgreSQL using --with-libxml." msgstr "您需è¦ä½¿ç”¨--with-libxml选项釿–°ç”ŸæˆPostgreSQL" -#: utils/adt/xml.c:192 utils/mb/mbutils.c:523 +#: utils/adt/xml.c:243 utils/mb/mbutils.c:512 #, c-format msgid "invalid encoding name \"%s\"" msgstr "无效的编ç åç§° \"%s\"" # command.c:122 -#: utils/adt/xml.c:435 utils/adt/xml.c:440 +#: utils/adt/xml.c:486 utils/adt/xml.c:491 #, c-format msgid "invalid XML comment" msgstr "无效的XML注释" -#: utils/adt/xml.c:569 +#: utils/adt/xml.c:620 #, c-format msgid "not an XML document" msgstr "䏿˜¯ä¸€ä¸ªXML文档" -#: utils/adt/xml.c:728 utils/adt/xml.c:751 +#: utils/adt/xml.c:779 utils/adt/xml.c:802 #, c-format msgid "invalid XML processing instruction" msgstr "无效的XML处ç†å‘½ä»¤" -#: utils/adt/xml.c:729 +#: utils/adt/xml.c:780 #, c-format msgid "XML processing instruction target name cannot be \"%s\"." msgstr "XML处ç†å‘½ä»¤ç›®æ ‡åç§°ä¸èƒ½æ˜¯\"%s\"." -#: utils/adt/xml.c:752 +#: utils/adt/xml.c:803 #, c-format msgid "XML processing instruction cannot contain \"?>\"." msgstr "XML处ç†å‘½ä»¤ä¸èƒ½åŒ…å«\"?>\"." -#: utils/adt/xml.c:831 +#: utils/adt/xml.c:882 #, c-format msgid "xmlvalidate is not implemented" msgstr "没有实现xmlvalidate" -#: utils/adt/xml.c:910 +#: utils/adt/xml.c:961 #, c-format msgid "could not initialize XML library" msgstr "无法åˆå§‹åŒ–XML库" -#: utils/adt/xml.c:911 +#: utils/adt/xml.c:962 #, c-format -msgid "" -"libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." +msgid "libxml2 has incompatible char type: sizeof(char)=%u, sizeof(xmlChar)=%u." msgstr "libxml2具有ä¸å…¼å®¹çš„字符类型: sizeof(char)=%u, sizeof(xmlChar)=%u. " -#: utils/adt/xml.c:997 +#: utils/adt/xml.c:1048 #, c-format msgid "could not set up XML error handler" msgstr "无法设置XML错误处ç†å‡½æ•°" -#: utils/adt/xml.c:998 +#: utils/adt/xml.c:1049 #, c-format -msgid "" -"This probably indicates that the version of libxml2 being used is not " -"compatible with the libxml2 header files that PostgreSQL was built with." -msgstr "" -"è¿™å¯èƒ½æ„å‘³ç€æ­£ä½¿ç”¨çš„libxml2版本与PostgreSQL编译 时使用的libxml2头文件ä¸å…¼å®¹" +msgid "This probably indicates that the version of libxml2 being used is not compatible with the libxml2 header files that PostgreSQL was built with." +msgstr "è¿™å¯èƒ½æ„å‘³ç€æ­£ä½¿ç”¨çš„libxml2版本与PostgreSQL编译 时使用的libxml2头文件ä¸å…¼å®¹" -#: utils/adt/xml.c:1737 +#: utils/adt/xml.c:1936 msgid "Invalid character value." msgstr "无效的字符值" -#: utils/adt/xml.c:1740 +#: utils/adt/xml.c:1939 msgid "Space required." msgstr "è¦æ±‚空格" -#: utils/adt/xml.c:1743 +#: utils/adt/xml.c:1942 msgid "standalone accepts only 'yes' or 'no'." msgstr "啿œºåªæŽ¥å—'yes'或'no'." -#: utils/adt/xml.c:1746 +#: utils/adt/xml.c:1945 msgid "Malformed declaration: missing version." msgstr "有缺陷的声明: 丢失版本." -#: utils/adt/xml.c:1749 +#: utils/adt/xml.c:1948 msgid "Missing encoding in text declaration." msgstr "在文本声明中丢失编ç " -#: utils/adt/xml.c:1752 +#: utils/adt/xml.c:1951 msgid "Parsing XML declaration: '?>' expected." msgstr "正在解æžXML声明: 期望'?>' " -#: utils/adt/xml.c:1755 +#: utils/adt/xml.c:1954 #, c-format msgid "Unrecognized libxml error code: %d." msgstr "未知的libxml错误ç : %d" -#: utils/adt/xml.c:2030 +#: utils/adt/xml.c:2229 #, c-format msgid "XML does not support infinite date values." msgstr "XML䏿”¯æŒæ— é™æ—¥æœŸå€¼" -#: utils/adt/xml.c:2052 utils/adt/xml.c:2079 +#: utils/adt/xml.c:2251 utils/adt/xml.c:2278 #, c-format msgid "XML does not support infinite timestamp values." msgstr "XML䏿”¯æŒæ— é™æ—¶é—´æˆ³å€¼" -#: utils/adt/xml.c:2470 +#: utils/adt/xml.c:2690 #, c-format msgid "invalid query" msgstr "无效的查询" -#: utils/adt/xml.c:3795 +#: utils/adt/xml.c:4037 #, c-format msgid "invalid array for XML namespace mapping" msgstr "对于XML命å空间映射的无效数组" -#: utils/adt/xml.c:3796 +#: utils/adt/xml.c:4038 #, c-format -msgid "" -"The array must be two-dimensional with length of the second axis equal to 2." +msgid "The array must be two-dimensional with length of the second axis equal to 2." msgstr "æ•°ç»„å¿…é¡»æ˜¯ç¬¬äºŒä¸ªåæ ‡è½´ç­‰äºŽ2的两维数组" -#: utils/adt/xml.c:3820 +#: utils/adt/xml.c:4062 #, c-format msgid "empty XPath expression" msgstr "空的XPath表达å¼" -#: utils/adt/xml.c:3869 +#: utils/adt/xml.c:4114 #, c-format msgid "neither namespace name nor URI may be null" msgstr "URI或者命å空间åç§°ä¸å¯ä¸ºç©º." # fe-misc.c:702 -#: utils/adt/xml.c:3876 +#: utils/adt/xml.c:4121 #, c-format msgid "could not register XML namespace with name \"%s\" and URI \"%s\"" msgstr "无法以åç§°\"%s\"å’ŒURI\"%s\"æ¥æ³¨å†ŒXML命å空间" -#: utils/cache/lsyscache.c:2580 utils/cache/lsyscache.c:2613 -#: utils/cache/lsyscache.c:2646 utils/cache/lsyscache.c:2679 +#: utils/adt/xml.c:4472 +#, c-format +msgid "DEFAULT namespace is not supported" +msgstr "䏿”¯æŒé»˜è®¤å‘½å空间" + +#: utils/adt/xml.c:4501 +#, c-format +msgid "row path filter must not be empty string" +msgstr "行路径筛选器ä¸èƒ½ä¸ºç©ºå­—符串" + +#: utils/adt/xml.c:4532 +#, c-format +msgid "column path filter must not be empty string" +msgstr "列路径筛选器ä¸èƒ½ä¸ºç©ºå­—符串" + +#: utils/adt/xml.c:4682 +#, c-format +msgid "more than one value returned by column XPath expression" +msgstr "列XPath表达å¼è¿”回了多个值" + +#: utils/cache/lsyscache.c:2654 utils/cache/lsyscache.c:2687 +#: utils/cache/lsyscache.c:2720 utils/cache/lsyscache.c:2753 #, c-format msgid "type %s is only a shell" msgstr "类型 %s åªæ˜¯ä¸€ä¸ª shell" -#: utils/cache/lsyscache.c:2585 +#: utils/cache/lsyscache.c:2659 #, c-format msgid "no input function available for type %s" msgstr "没有有效的 %s 类型输入函数" -#: utils/cache/lsyscache.c:2618 +#: utils/cache/lsyscache.c:2692 #, c-format msgid "no output function available for type %s" msgstr "没有有效的 %s 类型输出函数" -#: utils/cache/plancache.c:745 +#: utils/cache/partcache.c:195 +#, c-format +msgid "operator class \"%s\" of access method %s is missing support function %d for type %s" +msgstr "访问方法%2$sçš„è¿ç®—符类\"%1$s\"缺少类型%4$s的支æŒå‡½æ•°%3$d" + +#: utils/cache/plancache.c:718 #, c-format msgid "cached plan must not change result type" msgstr "已缓冲的计划ä¸èƒ½æ”¹å˜ç»“果类型" -#: utils/cache/relcache.c:5135 +#: utils/cache/relcache.c:5751 #, c-format msgid "could not create relation-cache initialization file \"%s\": %m" msgstr "无法创建 relation-cache åˆå§‹åŒ–文件 \"%s\": %m" -#: utils/cache/relcache.c:5137 +#: utils/cache/relcache.c:5753 #, c-format msgid "Continuing anyway, but there's something wrong." msgstr "ä»ç»§ç»­, 但肯定有些错误存在." -#: utils/cache/relcache.c:5365 +#: utils/cache/relcache.c:6107 #, c-format msgid "could not remove cache file \"%s\": %m" msgstr "无法删除缓存文件 \"%s\": %m" -#: utils/cache/relmapper.c:508 +#: utils/cache/relmapper.c:531 #, c-format msgid "cannot PREPARE a transaction that modified relation mapping" msgstr "䏿”¯æŒå¯¹ä¿®æ”¹å…³ç³»æ˜ å°„的事务进行PREPAREæ“作" -#: utils/cache/relmapper.c:651 utils/cache/relmapper.c:751 -#, c-format -msgid "could not open relation mapping file \"%s\": %m" -msgstr "无法打开关系映射文件 \"%s\": %m" - -#: utils/cache/relmapper.c:664 -#, c-format -msgid "could not read relation mapping file \"%s\": %m" -msgstr "无法读å–关系映射文件 \"%s\": %m" - -#: utils/cache/relmapper.c:674 +#: utils/cache/relmapper.c:761 #, c-format msgid "relation mapping file \"%s\" contains invalid data" msgstr "在关系映射文件\"%s\"ä¸­åŒ…å«æ— æ•ˆçš„æ•°æ®" -#: utils/cache/relmapper.c:684 +#: utils/cache/relmapper.c:771 #, c-format msgid "relation mapping file \"%s\" contains incorrect checksum" msgstr "在关系映射文件\"%s\"中包å«ä¸æ­£ç¡®çš„æ£€éªŒå’Œ" -#: utils/cache/relmapper.c:784 -#, c-format -msgid "could not write to relation mapping file \"%s\": %m" -msgstr "无法对关系映射文件 \"%s\" 进行写æ“作: %m" - -#: utils/cache/relmapper.c:797 -#, c-format -msgid "could not fsync relation mapping file \"%s\": %m" -msgstr "无法将关系映射文件\"%s\"的内容刷新到ç£ç›˜: %m" - -#: utils/cache/relmapper.c:803 -#, c-format -msgid "could not close relation mapping file \"%s\": %m" -msgstr "无法关闭关系映射文件\"%s\": %m" - -#: utils/cache/typcache.c:1211 -#, c-format -msgid "type %s is not composite" -msgstr "类型 %s 䏿˜¯å¤åˆç±»åž‹" - -#: utils/cache/typcache.c:1225 +#: utils/cache/typcache.c:1634 utils/fmgr/funcapi.c:420 #, c-format msgid "record type has not been registered" msgstr "记录类型没有注册" @@ -21702,2569 +23386,2713 @@ msgstr "TRAP: ExceptionalCondition: é”™è¯¯å‚æ•°\n" msgid "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n" msgstr "TRAP: %s(\"%s\", 文件: \"%s\", 行数: %d)\n" -#: utils/error/elog.c:322 utils/error/elog.c:1306 +#: utils/error/elog.c:319 utils/error/elog.c:1293 #, c-format msgid "error occurred at %s:%d before error message processing is available\n" msgstr "能得到错误消æ¯å¤„ç†ä¹‹å‰, 错误出现在%s:%d\n" -#: utils/error/elog.c:1880 +#: utils/error/elog.c:1871 #, c-format msgid "could not reopen file \"%s\" as stderr: %m" msgstr "æ— æ³•ä½œä¸ºæ ‡å‡†é”™è¯¯é‡æ–°æ‰“开文件 \"%s\": %m" -#: utils/error/elog.c:1893 +#: utils/error/elog.c:1884 #, c-format msgid "could not reopen file \"%s\" as stdout: %m" msgstr "æ— æ³•ä½œä¸ºæ ‡å‡†è¾“å‡ºé‡æ–°æ‰“开文件 \"%s\": %m" -#: utils/error/elog.c:2380 utils/error/elog.c:2397 utils/error/elog.c:2413 +#: utils/error/elog.c:2376 utils/error/elog.c:2393 utils/error/elog.c:2409 msgid "[unknown]" msgstr "[未知]" -#: utils/error/elog.c:2872 utils/error/elog.c:3171 utils/error/elog.c:3279 +#: utils/error/elog.c:2869 utils/error/elog.c:3172 utils/error/elog.c:3280 msgid "missing error text" msgstr "缺少错误信æ¯" -#: utils/error/elog.c:2875 utils/error/elog.c:2878 utils/error/elog.c:3282 -#: utils/error/elog.c:3285 +#: utils/error/elog.c:2872 utils/error/elog.c:2875 utils/error/elog.c:3283 +#: utils/error/elog.c:3286 #, c-format msgid " at character %d" msgstr " 第 %d 个字符处" -#: utils/error/elog.c:2888 utils/error/elog.c:2895 +#: utils/error/elog.c:2885 utils/error/elog.c:2892 msgid "DETAIL: " msgstr "详细信æ¯: " -#: utils/error/elog.c:2902 +#: utils/error/elog.c:2899 msgid "HINT: " msgstr "æç¤º: " -#: utils/error/elog.c:2909 +#: utils/error/elog.c:2906 msgid "QUERY: " msgstr "查询: " -#: utils/error/elog.c:2916 +#: utils/error/elog.c:2913 msgid "CONTEXT: " msgstr "上下文: " -#: utils/error/elog.c:2926 +#: utils/error/elog.c:2923 #, c-format msgid "LOCATION: %s, %s:%d\n" msgstr "ä½ç½®: %s, %s:%d\n" -#: utils/error/elog.c:2933 +#: utils/error/elog.c:2930 #, c-format msgid "LOCATION: %s:%d\n" msgstr "ä½ç½®: %s:%d\n" -#: utils/error/elog.c:2947 +#: utils/error/elog.c:2944 msgid "STATEMENT: " msgstr "语å¥: " -#. translator: This string will be truncated at 47 -#. characters expanded. -#: utils/error/elog.c:3400 -#, c-format -msgid "operating system error %d" -msgstr "æ“作系统错误 %d" - -#: utils/error/elog.c:3595 +#: utils/error/elog.c:3333 msgid "DEBUG" msgstr "调试" -#: utils/error/elog.c:3599 +#: utils/error/elog.c:3337 msgid "LOG" msgstr "日志" -#: utils/error/elog.c:3602 +#: utils/error/elog.c:3340 msgid "INFO" msgstr "ä¿¡æ¯" -#: utils/error/elog.c:3605 +#: utils/error/elog.c:3343 msgid "NOTICE" msgstr "注æ„" -#: utils/error/elog.c:3608 +#: utils/error/elog.c:3346 msgid "WARNING" msgstr "警告" -#: utils/error/elog.c:3611 +#: utils/error/elog.c:3349 msgid "ERROR" msgstr "错误" -#: utils/error/elog.c:3614 +#: utils/error/elog.c:3352 msgid "FATAL" msgstr "致命错误" -#: utils/error/elog.c:3617 +#: utils/error/elog.c:3355 msgid "PANIC" msgstr "比致命错误还过分的错误" -#: utils/fmgr/dfmgr.c:117 +#: utils/fmgr/dfmgr.c:130 #, c-format msgid "could not find function \"%s\" in file \"%s\"" msgstr "在文件 \"%2$s\" 中无法找到函数 \"%1$s\"" -#: utils/fmgr/dfmgr.c:196 utils/fmgr/dfmgr.c:405 utils/fmgr/dfmgr.c:453 -#, c-format -msgid "could not access file \"%s\": %m" -msgstr "无法访问文件 \"%s\": %m" - -#: utils/fmgr/dfmgr.c:234 +#: utils/fmgr/dfmgr.c:247 #, c-format msgid "could not load library \"%s\": %s" msgstr "无法加载库 \"%s\": %s" -#: utils/fmgr/dfmgr.c:266 +#: utils/fmgr/dfmgr.c:279 #, c-format msgid "incompatible library \"%s\": missing magic block" msgstr "库\"%s\"ä¸å…¼å®¹ï¼šä¸¢å¤±é­”法å—" -#: utils/fmgr/dfmgr.c:268 +#: utils/fmgr/dfmgr.c:281 #, c-format msgid "Extension libraries are required to use the PG_MODULE_MAGIC macro." msgstr "éœ€è¦æ‰©å±•库æ¥ä½¿ç”¨å®PG_MODULE_MAGIC。" -#: utils/fmgr/dfmgr.c:304 +#: utils/fmgr/dfmgr.c:327 #, c-format msgid "incompatible library \"%s\": version mismatch" msgstr "库 \"%s\"ä¸å…¼å®¹:版本ä¸åŒ¹é…" -#: utils/fmgr/dfmgr.c:306 +#: utils/fmgr/dfmgr.c:329 #, c-format -msgid "Server is version %d.%d, library is version %d.%d." -msgstr "æœåŠ¡å™¨ç‰ˆæœ¬æ˜¯%d.%d,库的版本是%d.%d." +msgid "Server is version %d, library is version %s." +msgstr "æœåŠ¡å™¨ç‰ˆæœ¬æ˜¯%d,库的版本是%s." -#: utils/fmgr/dfmgr.c:325 +#: utils/fmgr/dfmgr.c:346 #, c-format msgid "Server has FUNC_MAX_ARGS = %d, library has %d." msgstr "æœåŠ¡å™¨æœ‰FUNC_MAX_ARGS = %d, 库有%d" -#: utils/fmgr/dfmgr.c:334 +#: utils/fmgr/dfmgr.c:355 #, c-format msgid "Server has INDEX_MAX_KEYS = %d, library has %d." msgstr "æœåŠ¡å™¨æœ‰INDEX_MAX_KEYS = %d, 库有%d" -#: utils/fmgr/dfmgr.c:343 +#: utils/fmgr/dfmgr.c:364 #, c-format msgid "Server has NAMEDATALEN = %d, library has %d." msgstr "æœåŠ¡å™¨æœ‰NAMEDATALEN = %d, 库有%d" -#: utils/fmgr/dfmgr.c:352 +#: utils/fmgr/dfmgr.c:373 #, c-format msgid "Server has FLOAT4PASSBYVAL = %s, library has %s." msgstr "æœåŠ¡å™¨æœ‰FLOAT4PASSBYVAL = %s, 库有%s." -#: utils/fmgr/dfmgr.c:361 +#: utils/fmgr/dfmgr.c:382 #, c-format msgid "Server has FLOAT8PASSBYVAL = %s, library has %s." msgstr "æœåŠ¡å™¨æœ‰FLOAT8PASSBYVAL = %s, 库有%s." -#: utils/fmgr/dfmgr.c:368 +#: utils/fmgr/dfmgr.c:389 msgid "Magic block has unexpected length or padding difference." msgstr "Magicå—带有未期望的长度或者填充的方å¼ä¸åŒ." -#: utils/fmgr/dfmgr.c:371 +#: utils/fmgr/dfmgr.c:392 #, c-format msgid "incompatible library \"%s\": magic block mismatch" msgstr "ä¸å…¼å®¹çš„库\"%s\": 魔法å—ä¸åŒ¹é…" -#: utils/fmgr/dfmgr.c:535 +#: utils/fmgr/dfmgr.c:556 #, c-format msgid "access to library \"%s\" is not allowed" msgstr "ä¸å…许对库 \"%s\"进行访问" -#: utils/fmgr/dfmgr.c:561 +#: utils/fmgr/dfmgr.c:582 #, c-format msgid "invalid macro name in dynamic library path: %s" msgstr "动æ€åº“路径中无效的å®åå­—: %s" -#: utils/fmgr/dfmgr.c:601 +#: utils/fmgr/dfmgr.c:622 #, c-format msgid "zero-length component in parameter \"dynamic_library_path\"" msgstr "åœ¨å‚æ•°\"dynamic_library_path\"的组件长度为零" -#: utils/fmgr/dfmgr.c:620 +#: utils/fmgr/dfmgr.c:641 #, c-format msgid "component in parameter \"dynamic_library_path\" is not an absolute path" msgstr "åœ¨å‚æ•°\"dynamic_library_path\"中的组æˆéƒ¨åˆ†ä¸æ˜¯ç»å¯¹è·¯å¾„." -#: utils/fmgr/fmgr.c:272 +#: utils/fmgr/fmgr.c:236 #, c-format msgid "internal function \"%s\" is not in internal lookup table" msgstr "内部函数 \"%s\" ä¸åœ¨å†…部查找表中" -#: utils/fmgr/fmgr.c:479 +#: utils/fmgr/fmgr.c:485 #, c-format -msgid "unrecognized API version %d reported by info function \"%s\"" -msgstr "ä¿¡æ¯å‡½æ•°\"%2$s\"报告无法识别的API版本%1$d." +msgid "could not find function information for function \"%s\"" +msgstr "找ä¸åˆ°å‡½æ•°\"%s\"的函数信æ¯" + +#: utils/fmgr/fmgr.c:487 +#, c-format +msgid "SQL-callable functions need an accompanying PG_FUNCTION_INFO_V1(funcname)." +msgstr "SQLå¯è°ƒç”¨å‡½æ•°éœ€è¦ä¸€ä¸ªé™„带的PG_FUNCTION_INFO_V1(funcname)." -#: utils/fmgr/fmgr.c:849 utils/fmgr/fmgr.c:2110 +#: utils/fmgr/fmgr.c:505 #, c-format -msgid "function %u has too many arguments (%d, maximum is %d)" -msgstr "函数 %u 傿•°å¤ªå¤š (%d, 最大个数为 %d)" +msgid "unrecognized API version %d reported by info function \"%s\"" +msgstr "ä¿¡æ¯å‡½æ•°\"%2$s\"报告无法识别的API版本%1$d." -#: utils/fmgr/fmgr.c:2531 +#: utils/fmgr/fmgr.c:2032 #, c-format msgid "language validation function %u called for language %u instead of %u" msgstr "语言校验函数 %u 调用的目标语言是 %u ,è€Œä¸æ˜¯ %u" -#: utils/fmgr/funcapi.c:355 +#: utils/fmgr/funcapi.c:343 #, c-format -msgid "" -"could not determine actual result type for function \"%s\" declared to " -"return type %s" +msgid "could not determine actual result type for function \"%s\" declared to return type %s" msgstr "无法确定声明为返回类型%2$s的函数\"%1$s\"的实际结果类型" -#: utils/fmgr/funcapi.c:1342 utils/fmgr/funcapi.c:1373 +#: utils/fmgr/funcapi.c:1388 utils/fmgr/funcapi.c:1420 #, c-format msgid "number of aliases does not match number of columns" msgstr "别å个数与字段个数ä¸åŒ¹é…" -#: utils/fmgr/funcapi.c:1367 +#: utils/fmgr/funcapi.c:1414 #, c-format msgid "no column alias was provided" msgstr "没有æä¾›å­—段别å" -#: utils/fmgr/funcapi.c:1391 +#: utils/fmgr/funcapi.c:1438 #, c-format msgid "could not determine row description for function returning record" msgstr "无法确定函数返回记录的行æè¿°" -#: utils/init/miscinit.c:121 +#: utils/init/miscinit.c:110 #, c-format -msgid "could not change directory to \"%s\": %m" -msgstr "无法跳转到目录 \"%s\" 中: %m" +msgid "data directory \"%s\" does not exist" +msgstr "æ•°æ®ç›®å½• \"%s\" ä¸å­˜åœ¨" + +#: utils/init/miscinit.c:115 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "没有读å–目录 \"%s\" çš„æƒé™: %m" + +#: utils/init/miscinit.c:123 +#, c-format +msgid "specified data directory \"%s\" is not a directory" +msgstr "所指定的数æ®ç›®å½• \"%s\"䏿˜¯ä¸€ä¸ªç›®å½•." + +#: utils/init/miscinit.c:139 +#, c-format +msgid "data directory \"%s\" has wrong ownership" +msgstr "data目录 \"%s\"的所有者æƒé™é”™è¯¯." + +#: utils/init/miscinit.c:141 +#, c-format +msgid "The server must be started by the user that owns the data directory." +msgstr "æœåŠ¡å™¨å¿…é¡»ç”±æ‹¥æœ‰data目录的用户å¯åЍ" -#: utils/init/miscinit.c:449 utils/misc/guc.c:6012 +#: utils/init/miscinit.c:159 +#, c-format +msgid "data directory \"%s\" has invalid permissions" +msgstr "æ•°æ®ç›®å½•\"%s\"çš„æƒé™æ— æ•ˆ" + +#: utils/init/miscinit.c:161 +#, c-format +msgid "Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)." +msgstr "æƒé™åº”该为 u=rwx (0700) 或者u=rwx,g=rx (0750)." + +#: utils/init/miscinit.c:547 utils/misc/guc.c:6944 #, c-format msgid "cannot set parameter \"%s\" within security-restricted operation" msgstr "无法在对安全有严格é™åˆ¶çš„æ“ä½œä¸­è®¾ç½®å‚æ•°\"%s\" " -#: utils/init/miscinit.c:510 +#: utils/init/miscinit.c:615 #, c-format msgid "role with OID %u does not exist" msgstr "OID为%u的角色ä¸å­˜åœ¨" -#: utils/init/miscinit.c:540 +#: utils/init/miscinit.c:645 #, c-format msgid "role \"%s\" is not permitted to log in" msgstr "ä¸å…许角色\"%s\" 进行登录" -#: utils/init/miscinit.c:558 +#: utils/init/miscinit.c:663 #, c-format msgid "too many connections for role \"%s\"" msgstr "由角色\"%s\"å‘起的连接太多了" -#: utils/init/miscinit.c:618 +#: utils/init/miscinit.c:723 #, c-format msgid "permission denied to set session authorization" msgstr "设置会è¯è®¤è¯æƒé™ä¸å…许" -#: utils/init/miscinit.c:701 +#: utils/init/miscinit.c:806 #, c-format msgid "invalid role OID: %u" msgstr "无效的角色OID:%u" -#: utils/init/miscinit.c:755 +#: utils/init/miscinit.c:860 #, c-format msgid "database system is shut down" msgstr "æ•°æ®åº“系统已关闭" -#: utils/init/miscinit.c:842 +#: utils/init/miscinit.c:947 #, c-format msgid "could not create lock file \"%s\": %m" msgstr "æ— æ³•åˆ›å»ºé”æ–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:856 +#: utils/init/miscinit.c:961 #, c-format msgid "could not open lock file \"%s\": %m" msgstr "æ— æ³•æ‰“å¼€é”æ–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:862 +#: utils/init/miscinit.c:968 #, c-format msgid "could not read lock file \"%s\": %m" msgstr "无法读å–锿–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:870 +#: utils/init/miscinit.c:977 #, c-format msgid "lock file \"%s\" is empty" msgstr "锿–‡ä»¶ \"%s\" 为空" -#: utils/init/miscinit.c:871 +#: utils/init/miscinit.c:978 #, c-format -msgid "" -"Either another server is starting, or the lock file is the remnant of a " -"previous server startup crash." -msgstr "" -"或者å¦ä¸€ä¸ªæœåŠ¡æ­£åœ¨å¯åŠ¨ï¼Œæˆ–è€…é”æ–‡ä»¶æ˜¯å› ä¸ºå‰ä¸€æ¬¡æœåС噍å¯åŠ¨å´©æºƒæ—¶äº§ç”Ÿå¯¼è‡´çš„." +msgid "Either another server is starting, or the lock file is the remnant of a previous server startup crash." +msgstr "或者å¦ä¸€ä¸ªæœåŠ¡æ­£åœ¨å¯åŠ¨ï¼Œæˆ–è€…é”æ–‡ä»¶æ˜¯å› ä¸ºå‰ä¸€æ¬¡æœåС噍å¯åŠ¨å´©æºƒæ—¶äº§ç”Ÿå¯¼è‡´çš„." -#: utils/init/miscinit.c:918 +#: utils/init/miscinit.c:1022 #, c-format msgid "lock file \"%s\" already exists" msgstr "锿–‡ä»¶ \"%s\" å·²ç»å­˜åœ¨" -#: utils/init/miscinit.c:922 +#: utils/init/miscinit.c:1026 #, c-format msgid "Is another postgres (PID %d) running in data directory \"%s\"?" msgstr "是å¦å…¶å®ƒ postgres (PID %d) è¿è¡Œåœ¨æ•°æ®ç›®å½• \"%s\"?" -#: utils/init/miscinit.c:924 +#: utils/init/miscinit.c:1028 #, c-format msgid "Is another postmaster (PID %d) running in data directory \"%s\"?" msgstr "是å¦å…¶å®ƒ postmaster (PID %d) è¿è¡Œåœ¨æ•°æ®ç›®å½• \"%s\"?" -#: utils/init/miscinit.c:927 +#: utils/init/miscinit.c:1031 #, c-format msgid "Is another postgres (PID %d) using socket file \"%s\"?" msgstr "是å¦å…¶å®ƒ postgres (PID %d) 使用套接字文件 \"%s\"?" -#: utils/init/miscinit.c:929 +#: utils/init/miscinit.c:1033 #, c-format msgid "Is another postmaster (PID %d) using socket file \"%s\"?" msgstr "是å¦å…¶å®ƒ postmaster (PID %d) 使用套接字文件 \"%s\"?" -#: utils/init/miscinit.c:965 -#, c-format -msgid "pre-existing shared memory block (key %lu, ID %lu) is still in use" -msgstr "å…ˆå‰å­˜åœ¨çš„å…±äº«å†…å­˜å— (key %lu, ID %lu) ä»åœ¨ä½¿ç”¨ä¸­" - -#: utils/init/miscinit.c:968 -#, c-format -msgid "" -"If you're sure there are no old server processes still running, remove the " -"shared memory block or just delete the file \"%s\"." -msgstr "" -"如果你确认没有旧的æœåŠ¡å™¨è¿›ç¨‹åœ¨è¿è¡Œ, 删除共享内存å—,或者åªåˆ é™¤æ–‡ä»¶ \"%s\"." - -#: utils/init/miscinit.c:984 +#: utils/init/miscinit.c:1084 #, c-format msgid "could not remove old lock file \"%s\": %m" msgstr "æ— æ³•åˆ é™¤æ—§çš„é”æ–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:986 +#: utils/init/miscinit.c:1086 #, c-format -msgid "" -"The file seems accidentally left over, but it could not be removed. Please " -"remove the file by hand and try again." +msgid "The file seems accidentally left over, but it could not be removed. Please remove the file by hand and try again." msgstr "æ–‡ä»¶åƒæ˜¯æ„外留下的, 但是ä¸èƒ½åˆ é™¤å®ƒ. 请手工删除此文件, ç„¶åŽå†é‡è¯•一次." -#: utils/init/miscinit.c:1022 utils/init/miscinit.c:1033 -#: utils/init/miscinit.c:1043 +#: utils/init/miscinit.c:1123 utils/init/miscinit.c:1137 +#: utils/init/miscinit.c:1148 #, c-format msgid "could not write lock file \"%s\": %m" msgstr "æ— æ³•å†™å…¥é”æ–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:1172 utils/init/miscinit.c:1301 utils/misc/guc.c:8806 +#: utils/init/miscinit.c:1280 utils/init/miscinit.c:1423 utils/misc/guc.c:9851 #, c-format msgid "could not read from file \"%s\": %m" msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %m" -#: utils/init/miscinit.c:1291 +#: utils/init/miscinit.c:1411 #, c-format msgid "could not open file \"%s\": %m; continuing anyway" msgstr "无法打开文件\"%s\":%mï¼›ä»ç„¶ç»§ç»­" -#: utils/init/miscinit.c:1314 +#: utils/init/miscinit.c:1436 #, c-format msgid "lock file \"%s\" contains wrong PID: %ld instead of %ld" msgstr "锿–‡ä»¶\"%s\"包å«é”™è¯¯çš„PID:应该是%ldè€Œä¸æ˜¯%ld" -#: utils/init/miscinit.c:1356 utils/init/miscinit.c:1369 +#: utils/init/miscinit.c:1475 utils/init/miscinit.c:1491 #, c-format msgid "\"%s\" is not a valid data directory" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ•°æ®ç›®å½•" -#: utils/init/miscinit.c:1358 +#: utils/init/miscinit.c:1477 #, c-format msgid "File \"%s\" is missing." msgstr "文件 \"%s\" 丢失." -#: utils/init/miscinit.c:1371 +#: utils/init/miscinit.c:1493 #, c-format msgid "File \"%s\" does not contain valid data." msgstr "文件 \"%s\" æ²¡æœ‰åŒ…å«æœ‰æ•ˆæ•°æ®." -#: utils/init/miscinit.c:1373 +#: utils/init/miscinit.c:1495 #, c-format msgid "You might need to initdb." msgstr "您需è¦åˆå§‹åŒ–æ•°æ®åº“ (initdb)." -#: utils/init/miscinit.c:1381 +#: utils/init/miscinit.c:1503 #, c-format -msgid "" -"The data directory was initialized by PostgreSQL version %ld.%ld, which is " -"not compatible with this version %s." -msgstr "æ•°æ®ç›®å½•是以 PostgreSQL 版本 %ld.%ld åˆå§‹åŒ–çš„, 它于当å‰ç‰ˆæœ¬ %s ä¸å…¼å®¹." +msgid "The data directory was initialized by PostgreSQL version %s, which is not compatible with this version %s." +msgstr "æ•°æ®ç›®å½•是以 PostgreSQL 版本 %s åˆå§‹åŒ–çš„, 它于当å‰ç‰ˆæœ¬ %s ä¸å…¼å®¹." -#: utils/init/miscinit.c:1452 +#: utils/init/miscinit.c:1570 #, c-format msgid "loaded library \"%s\"" msgstr "已加载的库 \"%s\"" -#: utils/init/postinit.c:252 -#, c-format -msgid "" -"replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" -msgstr "" -"å¤åˆ¶è¿žæŽ¥å·²ç»æŽˆæƒ: user =%s SSL å·²å¯ç”¨ (protocol=%s, cipher=%s, compression=" -"%s)" +#: utils/init/postinit.c:255 +#, fuzzy, c-format +#| msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgid "replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "å¤åˆ¶è¿žæŽ¥å·²ç»æŽˆæƒ: user =%s SSL å·²å¯ç”¨ (protocol=%s, cipher=%s, bits=%d, compression=%s)" # help.c:48 -#: utils/init/postinit.c:254 utils/init/postinit.c:268 +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 msgid "off" msgstr "关闭" # help.c:48 -#: utils/init/postinit.c:254 utils/init/postinit.c:268 +#: utils/init/postinit.c:261 utils/init/postinit.c:267 +#: utils/init/postinit.c:289 utils/init/postinit.c:295 msgid "on" msgstr "å¼€å¯" -#: utils/init/postinit.c:258 +#: utils/init/postinit.c:262 +#, c-format +msgid "replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "å¤åˆ¶è¿žæŽ¥å·²ç»æŽˆæƒ: user =%s SSL å·²å¯ç”¨ (protocol=%s, cipher=%s, bits=%d, compression=%s)" + +#: utils/init/postinit.c:272 +#, fuzzy, c-format +#| msgid "replication connection authorized: user=%s" +msgid "replication connection authorized: user=%s application_name=%s" +msgstr "å¤åˆ¶è¿žæŽ¥å·²ç»æŽˆæƒ: 用户=%s" + +#: utils/init/postinit.c:275 #, c-format msgid "replication connection authorized: user=%s" msgstr "å¤åˆ¶è¿žæŽ¥å·²ç»æŽˆæƒ: 用户=%s" -#: utils/init/postinit.c:266 +#: utils/init/postinit.c:284 +#, fuzzy, c-format +#| msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgid "connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "连接授æƒ: user=%s database=%s SSL å¯ç”¨ ((protocol=%s, cipher=%s, bits=%d, compression=%s)" + +#: utils/init/postinit.c:290 #, c-format -msgid "" -"connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=" -"%s, compression=%s)" -msgstr "" -"连接授æƒ: user=%s database=%s SSL å¯ç”¨ (protocol=%s, cipher=%s, compression=" -"%s)" +msgid "connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)" +msgstr "连接授æƒ: user=%s database=%s SSL å¯ç”¨ ((protocol=%s, cipher=%s, bits=%d, compression=%s)" -#: utils/init/postinit.c:272 +#: utils/init/postinit.c:300 +#, fuzzy, c-format +#| msgid "connection authorized: user=%s database=%s" +msgid "connection authorized: user=%s database=%s application_name=%s" +msgstr "è”æŽ¥è®¤è¯: 主机=%s æ•°æ®åº“=%s" + +#: utils/init/postinit.c:302 #, c-format msgid "connection authorized: user=%s database=%s" msgstr "è”æŽ¥è®¤è¯: 主机=%s æ•°æ®åº“=%s" -#: utils/init/postinit.c:304 +#: utils/init/postinit.c:334 #, c-format msgid "database \"%s\" has disappeared from pg_database" msgstr "关于数æ®åº“\"%s\"的记录在系统目录视图pg_database中ä¸å­˜åœ¨" -#: utils/init/postinit.c:306 +#: utils/init/postinit.c:336 #, c-format msgid "Database OID %u now seems to belong to \"%s\"." msgstr "æ•°æ®åº“OID%u现在属于\"%s\"." -#: utils/init/postinit.c:326 +#: utils/init/postinit.c:356 #, c-format msgid "database \"%s\" is not currently accepting connections" msgstr "æ•°æ®åº“ \"%s\" 当å‰ä¸æŽ¥å—è”æŽ¥" -#: utils/init/postinit.c:339 +#: utils/init/postinit.c:369 #, c-format msgid "permission denied for database \"%s\"" msgstr "访问数æ®åº“\"%s\"çš„æƒé™ä¸å¤Ÿ" -#: utils/init/postinit.c:340 +#: utils/init/postinit.c:370 #, c-format msgid "User does not have CONNECT privilege." msgstr "用户没有CONNECTæƒé™." # command.c:981 -#: utils/init/postinit.c:357 +#: utils/init/postinit.c:387 #, c-format msgid "too many connections for database \"%s\"" msgstr "到数æ®åº“ \"%s\"的连接太多了" -#: utils/init/postinit.c:379 utils/init/postinit.c:386 +#: utils/init/postinit.c:409 utils/init/postinit.c:416 #, c-format msgid "database locale is incompatible with operating system" msgstr "æ•°æ®åº“所使用的语言环境和æ“作系统的ä¸å…¼å®¹" -#: utils/init/postinit.c:380 +#: utils/init/postinit.c:410 #, c-format -msgid "" -"The database was initialized with LC_COLLATE \"%s\", which is not " -"recognized by setlocale()." -msgstr "" -"æ•°æ®åº“集群是以 LC_COLLATE \"%s\"æ¥åˆå§‹åŒ–的,这个排åºè§„则无法由setlocale()识别" +msgid "The database was initialized with LC_COLLATE \"%s\", which is not recognized by setlocale()." +msgstr "æ•°æ®åº“集群是以 LC_COLLATE \"%s\"æ¥åˆå§‹åŒ–的,这个排åºè§„则无法由setlocale()识别" -#: utils/init/postinit.c:382 utils/init/postinit.c:389 +#: utils/init/postinit.c:412 utils/init/postinit.c:419 #, c-format -msgid "" -"Recreate the database with another locale or install the missing locale." +msgid "Recreate the database with another locale or install the missing locale." msgstr "以å¦å¤–一ç§è¯­è¨€çŽ¯å¢ƒé‡æ–°åˆ›å»ºæ•°æ®åº“,或者安装丢失的语言环境." -#: utils/init/postinit.c:387 +#: utils/init/postinit.c:417 #, c-format -msgid "" -"The database was initialized with LC_CTYPE \"%s\", which is not recognized " -"by setlocale()." -msgstr "" -"æ•°æ®åº“集群是带 LC_CTYPE \"%s\" åˆå§‹åŒ–çš„, 但此 LC_CTYPE 是ä¸è¢« setlocale() 认" -"å¯çš„." +msgid "The database was initialized with LC_CTYPE \"%s\", which is not recognized by setlocale()." +msgstr "æ•°æ®åº“集群是带 LC_CTYPE \"%s\" åˆå§‹åŒ–çš„, 但此 LC_CTYPE 是ä¸è¢« setlocale() 认å¯çš„." -#: utils/init/postinit.c:715 +#: utils/init/postinit.c:764 #, c-format msgid "no roles are defined in this database system" msgstr "当剿•°æ®åº“系统中没有定义角色" -#: utils/init/postinit.c:716 +#: utils/init/postinit.c:765 #, c-format msgid "You should immediately run CREATE USER \"%s\" SUPERUSER;." msgstr "您应该立å³è¿è¡Œ CREATE USER \"%s\" SUPERUSER;." -#: utils/init/postinit.c:752 +#: utils/init/postinit.c:801 #, c-format msgid "new replication connections are not allowed during database shutdown" msgstr "在数æ®åº“æœåŠ¡å™¨å…³é—­æœŸé—´ä¸å…è®¸æŽ¥å—æ–°çš„å¤åˆ¶è¿žæŽ¥" -#: utils/init/postinit.c:756 +#: utils/init/postinit.c:805 #, c-format msgid "must be superuser to connect during database shutdown" msgstr "åªæœ‰è¶…级用户æ‰èƒ½åœ¨æ•°æ®åº“关闭期间连接数æ®åº“" -#: utils/init/postinit.c:766 +#: utils/init/postinit.c:815 #, c-format msgid "must be superuser to connect in binary upgrade mode" msgstr "åªæœ‰è¶…级用户æ‰èƒ½ä»¥äºŒè¿›åˆ¶å‡çº§æ¨¡å¼è¿›è¡Œè¿žæŽ¥" -#: utils/init/postinit.c:780 +#: utils/init/postinit.c:828 #, c-format -msgid "" -"remaining connection slots are reserved for non-replication superuser " -"connections" +msgid "remaining connection slots are reserved for non-replication superuser connections" msgstr "å·²ä¿ç•™çš„连接ä½ç½®ä¸ºæ‰§è¡Œéžå¤åˆ¶è¯·æ±‚的超级用户预留" -#: utils/init/postinit.c:790 +#: utils/init/postinit.c:838 #, c-format msgid "must be superuser or replication role to start walsender" msgstr "åªæœ‰è¶…级用户或者拥有å¤åˆ¶è§’色的用户æ‰èƒ½å¯åЍ walsender" -#: utils/init/postinit.c:859 +#: utils/init/postinit.c:907 #, c-format msgid "database %u does not exist" msgstr "æ•°æ®åº“%uä¸å­˜åœ¨" -#: utils/init/postinit.c:945 +#: utils/init/postinit.c:996 #, c-format msgid "It seems to have just been dropped or renamed." msgstr "它已ç»è¢«åˆ é™¤æˆ–者改å了." -#: utils/init/postinit.c:963 +#: utils/init/postinit.c:1014 #, c-format msgid "The database subdirectory \"%s\" is missing." msgstr "æ•°æ®åº“å­ç›®å½• \"%s\" 丢失." -#: utils/init/postinit.c:968 +#: utils/init/postinit.c:1019 #, c-format msgid "could not access directory \"%s\": %m" msgstr "无法访问目录 \"%s\": %m" -#: utils/mb/conv.c:405 utils/mb/conv.c:591 +#: utils/mb/conv.c:488 utils/mb/conv.c:680 #, c-format msgid "invalid encoding number: %d" msgstr "无效编ç ç¼–å·: %d" -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:137 -#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:169 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:122 +#: utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c:154 #, c-format msgid "unexpected encoding ID %d for ISO 8859 character sets" msgstr " ISO 8859 å­—ç¬¦é›†å‡ºçŽ°éžæœŸæœ›çš„ç¼–ç ID%d" -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:127 -#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:159 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:103 +#: utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c:135 #, c-format msgid "unexpected encoding ID %d for WIN character sets" msgstr "WINå­—ç¬¦é›†å‡ºçŽ°éžæœŸæœ›çš„ç¼–ç ID%d" -#: utils/mb/encnames.c:496 +#: utils/mb/encnames.c:473 +#, c-format +msgid "encoding \"%s\" not supported by ICU" +msgstr "ICU䏿”¯æŒç¼–ç \"%s\"" + +#: utils/mb/encnames.c:572 #, c-format msgid "encoding name too long" msgstr "ç¼–ç å字太长" -#: utils/mb/mbutils.c:307 +#: utils/mb/mbutils.c:296 #, c-format msgid "conversion between %s and %s is not supported" msgstr "䏿”¯æŒ %s å’Œ %s 之间的编ç è½¬æ¢" -#: utils/mb/mbutils.c:366 +#: utils/mb/mbutils.c:355 #, c-format -msgid "" -"default conversion function for encoding \"%s\" to \"%s\" does not exist" +msgid "default conversion function for encoding \"%s\" to \"%s\" does not exist" msgstr "默认的 \"%s\" 到 \"%s\" 的编ç è½¬æ¢å‡½æ•°ä¸å­˜åœ¨" -#: utils/mb/mbutils.c:377 utils/mb/mbutils.c:710 +#: utils/mb/mbutils.c:366 utils/mb/mbutils.c:699 #, c-format msgid "String of %d bytes is too long for encoding conversion." msgstr "对于编ç è½¬åŒ–æ¥è¯´å¸¦æœ‰%d个字节的字符串太长." -#: utils/mb/mbutils.c:464 +#: utils/mb/mbutils.c:453 #, c-format msgid "invalid source encoding name \"%s\"" msgstr "无效的æºç¼–ç åç§° \"%s\"" -#: utils/mb/mbutils.c:469 +#: utils/mb/mbutils.c:458 #, c-format msgid "invalid destination encoding name \"%s\"" msgstr "无效的目标编ç åç§° \"%s\"" -#: utils/mb/mbutils.c:609 +#: utils/mb/mbutils.c:598 #, c-format msgid "invalid byte value for encoding \"%s\": 0x%02x" msgstr "对于编ç \"%s\"的字节值无效: 0x%02x" -#: utils/mb/mbutils.c:951 +#: utils/mb/mbutils.c:940 #, c-format msgid "bind_textdomain_codeset failed" msgstr "æ“作bind_textdomain_codeset 失败了" -#: utils/mb/wchar.c:2015 +#: utils/mb/wchar.c:2033 #, c-format msgid "invalid byte sequence for encoding \"%s\": %s" msgstr "无效的 \"%s\" ç¼–ç å­—节顺åº: %s" -#: utils/mb/wchar.c:2048 +#: utils/mb/wchar.c:2066 #, c-format -msgid "" -"character with byte sequence %s in encoding \"%s\" has no equivalent in " -"encoding \"%s\"" +msgid "character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"" msgstr "ç¼–ç \"%2$s\"的字符0x%1$s在编ç \"%3$s\"没有相对应值" -#: utils/misc/guc.c:548 +#: utils/misc/guc.c:636 msgid "Ungrouped" msgstr "å–æ¶ˆç»„" -#: utils/misc/guc.c:550 +#: utils/misc/guc.c:638 msgid "File Locations" msgstr "文件ä½ç½®" -#: utils/misc/guc.c:552 +#: utils/misc/guc.c:640 msgid "Connections and Authentication" msgstr "è”æŽ¥å’Œè®¤è¯" -#: utils/misc/guc.c:554 +#: utils/misc/guc.c:642 msgid "Connections and Authentication / Connection Settings" msgstr "è”æŽ¥å’Œè®¤è¯ / è”æŽ¥è®¾ç½®" -#: utils/misc/guc.c:556 -msgid "Connections and Authentication / Security and Authentication" -msgstr "è”æŽ¥å’Œè®¤è¯ / 安全和认è¯" +#: utils/misc/guc.c:644 +msgid "Connections and Authentication / Authentication" +msgstr "è¿žæŽ¥å’Œèº«ä»½éªŒè¯ / 身份验è¯" + +#: utils/misc/guc.c:646 +msgid "Connections and Authentication / SSL" +msgstr "è”æŽ¥å’Œèº«ä»½è®¤è¯ / SSL" -#: utils/misc/guc.c:558 +#: utils/misc/guc.c:648 msgid "Resource Usage" msgstr "资æºä½¿ç”¨" -#: utils/misc/guc.c:560 +#: utils/misc/guc.c:650 msgid "Resource Usage / Memory" msgstr "资æºä½¿ç”¨ / 内存" -#: utils/misc/guc.c:562 +#: utils/misc/guc.c:652 msgid "Resource Usage / Disk" msgstr "资æºä½¿ç”¨/ç£ç›˜" -#: utils/misc/guc.c:564 +#: utils/misc/guc.c:654 msgid "Resource Usage / Kernel Resources" msgstr "资æºä½¿ç”¨ / 内核资æº" -#: utils/misc/guc.c:566 +#: utils/misc/guc.c:656 msgid "Resource Usage / Cost-Based Vacuum Delay" msgstr "资æºä½¿ç”¨ / 基于开销的Vacuum延迟" -#: utils/misc/guc.c:568 +#: utils/misc/guc.c:658 msgid "Resource Usage / Background Writer" msgstr "资æºä½¿ç”¨ / åŽå°å†™å…¥è¿›ç¨‹" -#: utils/misc/guc.c:570 +#: utils/misc/guc.c:660 msgid "Resource Usage / Asynchronous Behavior" msgstr "资æºä½¿ç”¨ / 异步系统行为" -#: utils/misc/guc.c:572 +#: utils/misc/guc.c:662 msgid "Write-Ahead Log" msgstr "Write-Ahead 日志" -#: utils/misc/guc.c:574 +#: utils/misc/guc.c:664 msgid "Write-Ahead Log / Settings" msgstr "Write-Ahead 日志 / 设置" -#: utils/misc/guc.c:576 +#: utils/misc/guc.c:666 msgid "Write-Ahead Log / Checkpoints" msgstr "Write-Ahead 日志 / Checkpoints" -#: utils/misc/guc.c:578 +#: utils/misc/guc.c:668 msgid "Write-Ahead Log / Archiving" msgstr "Write-Ahead 日志 / å½’æ¡£" -#: utils/misc/guc.c:580 +#: utils/misc/guc.c:670 +#, fuzzy +#| msgid "Write-Ahead Log / Archiving" +msgid "Write-Ahead Log / Archive Recovery" +msgstr "Write-Ahead 日志 / å½’æ¡£" + +#: utils/misc/guc.c:672 +#, fuzzy +#| msgid "Write-Ahead Log / Checkpoints" +msgid "Write-Ahead Log / Recovery Target" +msgstr "Write-Ahead 日志 / Checkpoints" + +#: utils/misc/guc.c:674 msgid "Replication" msgstr "å¤åˆ¶" -#: utils/misc/guc.c:582 +#: utils/misc/guc.c:676 msgid "Replication / Sending Servers" msgstr "å¤åˆ¶/å‘逿œåС噍" -#: utils/misc/guc.c:584 +#: utils/misc/guc.c:678 msgid "Replication / Master Server" msgstr "å¤åˆ¶/主æœåС噍" -#: utils/misc/guc.c:586 +#: utils/misc/guc.c:680 msgid "Replication / Standby Servers" msgstr "å¤åˆ¶ / 备用æœåС噍" -#: utils/misc/guc.c:588 +#: utils/misc/guc.c:682 +msgid "Replication / Subscribers" +msgstr "å¤åˆ¶ / 订阅者" + +#: utils/misc/guc.c:684 msgid "Query Tuning" msgstr "查询调整" -#: utils/misc/guc.c:590 +#: utils/misc/guc.c:686 msgid "Query Tuning / Planner Method Configuration" msgstr "查询调整 / 规划器方法é…ç½®" -#: utils/misc/guc.c:592 +#: utils/misc/guc.c:688 msgid "Query Tuning / Planner Cost Constants" msgstr "查询调整 / Planner Cost Constants" -#: utils/misc/guc.c:594 +#: utils/misc/guc.c:690 msgid "Query Tuning / Genetic Query Optimizer" msgstr "查询调整 / 基因查询优化" -#: utils/misc/guc.c:596 +#: utils/misc/guc.c:692 msgid "Query Tuning / Other Planner Options" msgstr "查询调整 / 其它规划器选项" -#: utils/misc/guc.c:598 +#: utils/misc/guc.c:694 msgid "Reporting and Logging" msgstr "报告和日志" -#: utils/misc/guc.c:600 +#: utils/misc/guc.c:696 msgid "Reporting and Logging / Where to Log" msgstr "报告和日志 / 日志ä½ç½®" -#: utils/misc/guc.c:602 +#: utils/misc/guc.c:698 msgid "Reporting and Logging / When to Log" msgstr "报告和日志 / 日志时间" -#: utils/misc/guc.c:604 +#: utils/misc/guc.c:700 msgid "Reporting and Logging / What to Log" msgstr "报告和日志 / 日志内容" -#: utils/misc/guc.c:606 +#: utils/misc/guc.c:702 msgid "Process Title" msgstr "进程标题" -#: utils/misc/guc.c:608 +#: utils/misc/guc.c:704 msgid "Statistics" msgstr "统计信æ¯" -#: utils/misc/guc.c:610 +#: utils/misc/guc.c:706 msgid "Statistics / Monitoring" msgstr "ç»Ÿè®¡ä¿¡æ¯ / 监控" -#: utils/misc/guc.c:612 +#: utils/misc/guc.c:708 msgid "Statistics / Query and Index Statistics Collector" msgstr "ç»Ÿè®¡ä¿¡æ¯ / 查询和索引统计收集器" -#: utils/misc/guc.c:614 +#: utils/misc/guc.c:710 msgid "Autovacuum" msgstr "Autovacuum" -#: utils/misc/guc.c:616 +#: utils/misc/guc.c:712 msgid "Client Connection Defaults" msgstr "å®¢æˆ·ç«¯è”æŽ¥é»˜è®¤" -#: utils/misc/guc.c:618 +#: utils/misc/guc.c:714 msgid "Client Connection Defaults / Statement Behavior" msgstr "å®¢æˆ·ç«¯è”æŽ¥é»˜è®¤ / 语å¥åŠ¨ä½œ" -#: utils/misc/guc.c:620 +#: utils/misc/guc.c:716 msgid "Client Connection Defaults / Locale and Formatting" msgstr "å®¢æˆ·ç«¯è”æŽ¥é»˜è®¤ / 本地化和格å¼åŒ–" -#: utils/misc/guc.c:622 +#: utils/misc/guc.c:718 msgid "Client Connection Defaults / Shared Library Preloading" msgstr "å®¢æˆ·ç«¯è”æŽ¥é»˜è®¤ / 共享库预先加载" -#: utils/misc/guc.c:624 +#: utils/misc/guc.c:720 msgid "Client Connection Defaults / Other Defaults" msgstr "å®¢æˆ·ç«¯è”æŽ¥é»˜è®¤ / 其它默认" -#: utils/misc/guc.c:626 +#: utils/misc/guc.c:722 msgid "Lock Management" msgstr "é”管ç†" -#: utils/misc/guc.c:628 +#: utils/misc/guc.c:724 msgid "Version and Platform Compatibility" msgstr "版本和平å°å…¼å®¹æ€§" -#: utils/misc/guc.c:630 +#: utils/misc/guc.c:726 msgid "Version and Platform Compatibility / Previous PostgreSQL Versions" msgstr "版本和平å°å…¼å®¹æ€§ / 上一个 PostgreSQL 版本" -#: utils/misc/guc.c:632 +#: utils/misc/guc.c:728 msgid "Version and Platform Compatibility / Other Platforms and Clients" msgstr "版本和平å°å…¼å®¹æ€§ / 其它平å°å’Œå®¢æˆ·ç«¯" -#: utils/misc/guc.c:634 +#: utils/misc/guc.c:730 msgid "Error Handling" msgstr "错误处ç†" -#: utils/misc/guc.c:636 +#: utils/misc/guc.c:732 msgid "Preset Options" msgstr "预置选项" -#: utils/misc/guc.c:638 +#: utils/misc/guc.c:734 msgid "Customized Options" msgstr "定制选项" -#: utils/misc/guc.c:640 +#: utils/misc/guc.c:736 msgid "Developer Options" msgstr "å¼€å‘人员选项" -#: utils/misc/guc.c:697 -msgid "Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"." -msgstr "è¿™ä¸ªå‚æ•°çš„æœ‰æ•ˆå•使˜¯\"kB\", \"MB\", \"GB\"å’Œ\"TB\"." +#: utils/misc/guc.c:788 +msgid "Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"." +msgstr "è¿™ä¸ªå‚æ•°çš„æœ‰æ•ˆå•使˜¯\"B\", \"kB\", \"MB\", \"GB\"å’Œ\"TB\"." -#: utils/misc/guc.c:724 -msgid "" -"Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." +#: utils/misc/guc.c:825 +#, fuzzy +#| msgid "Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"." +msgid "Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"." msgstr "è¿™ä¸ªå‚æ•°å¯ä½¿ç”¨çš„æœ‰æ•ˆå•元是\"ms\", \"s\", \"min\", \"h\", å’Œ\"d\"." -#: utils/misc/guc.c:783 +#: utils/misc/guc.c:887 msgid "Enables the planner's use of sequential-scan plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’å™¨çš„é¡ºåºæ‰«æè®¡åˆ’." -#: utils/misc/guc.c:792 +#: utils/misc/guc.c:897 msgid "Enables the planner's use of index-scan plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的索引扫æè®¡åˆ’." -#: utils/misc/guc.c:801 +#: utils/misc/guc.c:907 msgid "Enables the planner's use of index-only-scan plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的仅索引扫æè®¡åˆ’." -#: utils/misc/guc.c:810 +#: utils/misc/guc.c:917 msgid "Enables the planner's use of bitmap-scan plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的ä½å›¾æ‰«æè®¡åˆ’." -#: utils/misc/guc.c:819 +#: utils/misc/guc.c:927 msgid "Enables the planner's use of TID scan plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的TID扫æè®¡åˆ’." -#: utils/misc/guc.c:828 +#: utils/misc/guc.c:937 msgid "Enables the planner's use of explicit sort steps." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’å™¨çš„æ˜¾å¼æŽ’åºæ­¥éª¤." -#: utils/misc/guc.c:837 +#: utils/misc/guc.c:947 msgid "Enables the planner's use of hashed aggregation plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的哈希èšåˆè®¡åˆ’." -#: utils/misc/guc.c:846 +#: utils/misc/guc.c:957 msgid "Enables the planner's use of materialization." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的实体化使用." -#: utils/misc/guc.c:855 +#: utils/misc/guc.c:967 msgid "Enables the planner's use of nested-loop join plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的嵌套循环连接计划." -#: utils/misc/guc.c:864 +#: utils/misc/guc.c:977 msgid "Enables the planner's use of merge join plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的åˆå¹¶è¿žæŽ¥è®¡åˆ’." -#: utils/misc/guc.c:873 +#: utils/misc/guc.c:987 msgid "Enables the planner's use of hash join plans." msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的哈希连接计划." -#: utils/misc/guc.c:882 -msgid "Enables use of foreign keys for estimating joins." -msgstr "å¯ç”¨å¤–é”®æ¥ä¼°è®¡è¿žæŽ¥ã€‚" +#: utils/misc/guc.c:997 +msgid "Enables the planner's use of gather merge plans." +msgstr "å…许查询计划器使用收集åˆå¹¶è®¡åˆ’." -#: utils/misc/guc.c:892 -msgid "Enables genetic query optimization." -msgstr "å¯ç”¨åŸºå› æŸ¥è¯¢ä¼˜åŒ–." +#: utils/misc/guc.c:1007 +msgid "Enables partitionwise join." +msgstr "å¯ç”¨åˆ†åŒºè¿žæŽ¥." -#: utils/misc/guc.c:893 -msgid "This algorithm attempts to do planning without exhaustive searching." -msgstr "算法ä¼å›¾æ‰§è¡Œä¸å¸¦æœ‰æ— ç©·æœç´¢çš„计划." +#: utils/misc/guc.c:1017 +msgid "Enables partitionwise aggregation and grouping." +msgstr "å¯ç”¨åˆ†åŒºèšåˆå’Œåˆ†ç»„." -#: utils/misc/guc.c:903 +#: utils/misc/guc.c:1027 +msgid "Enables the planner's use of parallel append plans." +msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器使用并行追加计划." + +#: utils/misc/guc.c:1037 +msgid "Enables the planner's use of parallel hash plans." +msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器使用并行哈希计划." + +#: utils/misc/guc.c:1047 +msgid "Enable plan-time and run-time partition pruning." +msgstr "å¯ç”¨è®¡åˆ’æ—¶é—´å’Œè¿è¡Œæ—¶åˆ†åŒºä¿®å‰ª." + +#: utils/misc/guc.c:1048 +msgid "Allows the query planner and executor to compare partition bounds to conditions in the query to determine which partitions must be scanned." +msgstr "å…许查询计划器和执行器将分区边界与查询中的æ¡ä»¶è¿›è¡Œæ¯”较,以确定必须扫æå“ªäº›åˆ†åŒº" + +#: utils/misc/guc.c:1059 +msgid "Enables genetic query optimization." +msgstr "å¯ç”¨åŸºå› æŸ¥è¯¢ä¼˜åŒ–." + +#: utils/misc/guc.c:1060 +msgid "This algorithm attempts to do planning without exhaustive searching." +msgstr "算法ä¼å›¾æ‰§è¡Œä¸å¸¦æœ‰æ— ç©·æœç´¢çš„计划." + +#: utils/misc/guc.c:1071 msgid "Shows whether the current user is a superuser." msgstr "显示当å‰ç”¨æˆ·æ˜¯å¦æ˜¯è¶…级用户." -#: utils/misc/guc.c:913 +#: utils/misc/guc.c:1081 msgid "Enables advertising the server via Bonjour." msgstr "å¯ç”¨é€šè¿‡Bonjourçš„æ–¹å¼æ¥å®£å¸ƒæ•°æ®åº“æœåŠ¡å™¨åœ¨ç½‘ç»œä¸­çš„å­˜åœ¨." -#: utils/misc/guc.c:922 +#: utils/misc/guc.c:1090 msgid "Collects transaction commit time." msgstr "收集事务æäº¤æ—¶é—´ã€‚" -#: utils/misc/guc.c:931 +#: utils/misc/guc.c:1099 msgid "Enables SSL connections." msgstr "å¯ç”¨ SSL è”æŽ¥." -#: utils/misc/guc.c:940 +#: utils/misc/guc.c:1108 +msgid "Also use ssl_passphrase_command during server reload." +msgstr "在æœåС噍釿–°åŠ è½½æœŸé—´ä¹Ÿä½¿ç”¨ssl_passphrase_command" + +#: utils/misc/guc.c:1117 msgid "Give priority to server ciphersuite order." msgstr "为æœåС噍坆ç ç»„çš„é¡ºåºæä¾›ä¼˜å…ˆ." -#: utils/misc/guc.c:949 +#: utils/misc/guc.c:1126 msgid "Forces synchronization of updates to disk." msgstr "强制和ç£ç›˜åŒæ­¥æ›´æ–°" -#: utils/misc/guc.c:950 -msgid "" -"The server will use the fsync() system call in several places to make sure " -"that updates are physically written to disk. This insures that a database " -"cluster will recover to a consistent state after an operating system or " -"hardware crash." -msgstr "" -"æœåŠ¡å™¨å°†åœ¨å¤šä¸ªä½ç½®ä½¿ç”¨ç³»ç»Ÿè°ƒç”¨fsync()æ¥ç¡®å®šæ›´æ–°æ“作已ç»å°†æ•°æ®å†™å…¥ç£ç›˜.这将确" -"ä¿åœ¨æ“ä½œç³»ç»Ÿæˆ–ç¡¬ä»¶å´©æºƒåŽæ•°æ®åº“集群将æ¢å¤åˆ°ä¸€ä¸ªä¸€è‡´æ€§çжæ€. " +#: utils/misc/guc.c:1127 +msgid "The server will use the fsync() system call in several places to make sure that updates are physically written to disk. This insures that a database cluster will recover to a consistent state after an operating system or hardware crash." +msgstr "æœåŠ¡å™¨å°†åœ¨å¤šä¸ªä½ç½®ä½¿ç”¨ç³»ç»Ÿè°ƒç”¨fsync()æ¥ç¡®å®šæ›´æ–°æ“作已ç»å°†æ•°æ®å†™å…¥ç£ç›˜.这将确ä¿åœ¨æ“ä½œç³»ç»Ÿæˆ–ç¡¬ä»¶å´©æºƒåŽæ•°æ®åº“集群将æ¢å¤åˆ°ä¸€ä¸ªä¸€è‡´æ€§çжæ€. " -#: utils/misc/guc.c:961 +#: utils/misc/guc.c:1138 msgid "Continues processing after a checksum failure." msgstr "校验失败åŽç»§ç»­å¤„ç†." -#: utils/misc/guc.c:962 -msgid "" -"Detection of a checksum failure normally causes PostgreSQL to report an " -"error, aborting the current transaction. Setting ignore_checksum_failure to " -"true causes the system to ignore the failure (but still report a warning), " -"and continue processing. This behavior could cause crashes or other serious " -"problems. Only has an effect if checksums are enabled." -msgstr "" -"å‘现校验失败通常会使PostgreSQL报告一个错误, 并中止当å‰äº‹åŠ¡.将傿•°" -"zero_damaged_pages设置为trueå¯ä»¥ä½¿ç³»ç»Ÿå¿½ç•¥å¤±è´¥(åªæŠ¥å‘Šä¸€ä¸ªè­¦å‘Šä¿¡æ¯),并且能够" -"继续处ç†å½“å‰äº‹åŠ¡.è¿™ç§æƒ…况将导致系统崩溃或者其它严é‡é—®é¢˜ï¼Œè¿™ä¹Ÿåªæœ‰åœ¨å¯ç”¨æ ¡éªŒæ—¶" -"æ‰æœ‰æ•ˆ." +#: utils/misc/guc.c:1139 +msgid "Detection of a checksum failure normally causes PostgreSQL to report an error, aborting the current transaction. Setting ignore_checksum_failure to true causes the system to ignore the failure (but still report a warning), and continue processing. This behavior could cause crashes or other serious problems. Only has an effect if checksums are enabled." +msgstr "å‘现校验失败通常会使PostgreSQL报告一个错误, 并中止当å‰äº‹åŠ¡.将傿•°zero_damaged_pages设置为trueå¯ä»¥ä½¿ç³»ç»Ÿå¿½ç•¥å¤±è´¥(åªæŠ¥å‘Šä¸€ä¸ªè­¦å‘Šä¿¡æ¯),并且能够继续处ç†å½“å‰äº‹åŠ¡.è¿™ç§æƒ…况将导致系统崩溃或者其它严é‡é—®é¢˜ï¼Œè¿™ä¹Ÿåªæœ‰åœ¨å¯ç”¨æ ¡éªŒæ—¶æ‰æœ‰æ•ˆ." -#: utils/misc/guc.c:976 +#: utils/misc/guc.c:1153 msgid "Continues processing past damaged page headers." msgstr "继续处ç†å·²æŸå的页头." -#: utils/misc/guc.c:977 -msgid "" -"Detection of a damaged page header normally causes PostgreSQL to report an " -"error, aborting the current transaction. Setting zero_damaged_pages to true " -"causes the system to instead report a warning, zero out the damaged page, " -"and continue processing. This behavior will destroy data, namely all the " -"rows on the damaged page." -msgstr "" -"对已æŸå页头的检测通常会使PostgreSQL报告一个错误, 并中止当å‰äº‹åŠ¡.将傿•°" -"zero_damaged_pages设置为trueå¯ä»¥ä½¿ç³»ç»ŸåªæŠ¥å‘Šä¸€ä¸ªè­¦å‘Šä¿¡æ¯ï¼Œä¸è¾“出已æŸå的页," -"并且能够继续处ç†å½“å‰äº‹åŠ¡.è¿™ç§æƒ…况将使æ¯åæ•°æ®ï¼Œå› ä¸ºè¿™æ ·é€šå¸¸ä¼šä½¿æ‰€æœ‰çš„记录在已" -"æŸå的页上存放." +#: utils/misc/guc.c:1154 +msgid "Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to true causes the system to instead report a warning, zero out the damaged page, and continue processing. This behavior will destroy data, namely all the rows on the damaged page." +msgstr "对已æŸå页头的检测通常会使PostgreSQL报告一个错误, 并中止当å‰äº‹åŠ¡.将傿•°zero_damaged_pages设置为trueå¯ä»¥ä½¿ç³»ç»ŸåªæŠ¥å‘Šä¸€ä¸ªè­¦å‘Šä¿¡æ¯ï¼Œä¸è¾“出已æŸå的页,并且能够继续处ç†å½“å‰äº‹åŠ¡.è¿™ç§æƒ…况将使æ¯åæ•°æ®ï¼Œå› ä¸ºè¿™æ ·é€šå¸¸ä¼šä½¿æ‰€æœ‰çš„记录在已æŸå的页上存放." -#: utils/misc/guc.c:990 +#: utils/misc/guc.c:1167 msgid "Writes full pages to WAL when first modified after a checkpoint." msgstr "在检查点事件å‘生åŽå‘ç”Ÿç¬¬ä¸€æ¬¡ä¿®æ”¹æ•°æ®æ—¶ï¼ŒæŠŠæ‰€æœ‰çš„页写到WAL文件中" -#: utils/misc/guc.c:991 -msgid "" -"A page write in process during an operating system crash might be only " -"partially written to disk. During recovery, the row changes stored in WAL " -"are not enough to recover. This option writes pages when first modified " -"after a checkpoint to WAL so full recovery is possible." -msgstr "" -"在æ“作系统崩溃过程中正在写入的页上的数æ®å¯èƒ½å·²ç»éƒ¨åˆ†å†™å…¥ç£ç›˜.在æ¢å¤æœŸé—´,在WAL" -"文件中所ä¿å­˜çš„已改å˜è®°å½•ä¸è¶³ä»¥è¿›è¡Œæ¢å¤.当对WALå‘生检查点事件åŽè¿›è¡Œç¬¬ä¸€æ¬¡ä¿®æ”¹" -"æ“作时这个选项å¯ä»¥å†™å…¥é¡µã€‚这样将å…许进行完全æ¢å¤." +#: utils/misc/guc.c:1168 +msgid "A page write in process during an operating system crash might be only partially written to disk. During recovery, the row changes stored in WAL are not enough to recover. This option writes pages when first modified after a checkpoint to WAL so full recovery is possible." +msgstr "在æ“作系统崩溃过程中正在写入的页上的数æ®å¯èƒ½å·²ç»éƒ¨åˆ†å†™å…¥ç£ç›˜.在æ¢å¤æœŸé—´,在WAL文件中所ä¿å­˜çš„已改å˜è®°å½•ä¸è¶³ä»¥è¿›è¡Œæ¢å¤.当对WALå‘生检查点事件åŽè¿›è¡Œç¬¬ä¸€æ¬¡ä¿®æ”¹æ“作时这个选项å¯ä»¥å†™å…¥é¡µã€‚这样将å…许进行完全æ¢å¤." -#: utils/misc/guc.c:1004 -msgid "" -"Writes full pages to WAL when first modified after a checkpoint, even for a " -"non-critical modifications." -msgstr "" -"在检查点事件å‘生åŽå‘生第一次修改数æ®ç”šè‡³æ˜¯éžå…³é”®ä¿®æ”¹æ—¶ï¼ŒæŠŠæ‰€æœ‰çš„页写到WAL文件" -"中" +#: utils/misc/guc.c:1181 +msgid "Writes full pages to WAL when first modified after a checkpoint, even for a non-critical modifications." +msgstr "在检查点事件å‘生åŽå‘生第一次修改数æ®ç”šè‡³æ˜¯éžå…³é”®ä¿®æ”¹æ—¶ï¼ŒæŠŠæ‰€æœ‰çš„页写到WAL文件中" -#: utils/misc/guc.c:1014 +#: utils/misc/guc.c:1191 msgid "Compresses full-page writes written in WAL file." msgstr "压缩写入WAL文件的整页写。" -#: utils/misc/guc.c:1024 +#: utils/misc/guc.c:1201 +msgid "Writes zeroes to new WAL files before first use." +msgstr "" + +#: utils/misc/guc.c:1211 +msgid "Recycles WAL files by renaming them." +msgstr "" + +#: utils/misc/guc.c:1221 msgid "Logs each checkpoint." msgstr "记录æ¯ä¸€ä¸ªæ£€æŸ¥ç‚¹äº‹ä»¶" -#: utils/misc/guc.c:1033 +#: utils/misc/guc.c:1230 msgid "Logs each successful connection." msgstr "记录æ¯ä¸€ä¸ªæˆåŠŸçš„è”æŽ¥." -#: utils/misc/guc.c:1042 +#: utils/misc/guc.c:1239 msgid "Logs end of a session, including duration." msgstr "对会è¯çš„ç»“æŸæ—¶é—´å’Œæ•´ä¸ªä¼šè¯çš„æŒç»­æ—¶é—´è¿›è¡Œæ—¥å¿—è®°å½•" -#: utils/misc/guc.c:1051 +#: utils/misc/guc.c:1248 msgid "Logs each replication command." msgstr "记录æ¯ä¸€ä¸ªå¤åˆ¶å‘½ä»¤ã€‚" -#: utils/misc/guc.c:1060 +#: utils/misc/guc.c:1257 msgid "Shows whether the running server has assertion checks enabled." msgstr "显示正在è¿è¡Œçš„æœåŠ¡å™¨æ˜¯å¦å¯ç”¨äº†æ–­è¨€æ£€æŸ¥ã€‚" -#: utils/misc/guc.c:1075 +#: utils/misc/guc.c:1272 msgid "Terminate session on any error." msgstr "åªè¦é‡é”™å³ç»ˆæ­¢ä¼šè¯." -#: utils/misc/guc.c:1084 +#: utils/misc/guc.c:1281 msgid "Reinitialize server after backend crash." msgstr "åŽç«¯æœåŠ¡å™¨å´©æºƒæ—¶é‡æ–°åˆå§‹åŒ–æœåС噍." -#: utils/misc/guc.c:1094 +#: utils/misc/guc.c:1291 msgid "Logs the duration of each completed SQL statement." msgstr "记录æ¯ä¸€æ¡å®Œæˆäº†çš„ SQL 语å¥è¿‡ç¨‹." -#: utils/misc/guc.c:1103 +#: utils/misc/guc.c:1300 msgid "Logs each query's parse tree." msgstr "对æ¯ä¸ªæŸ¥è¯¢çš„åˆ†æžæ ‘进行日志记录" -#: utils/misc/guc.c:1112 +#: utils/misc/guc.c:1309 msgid "Logs each query's rewritten parse tree." msgstr "对æ¯ä¸ªæŸ¥è¯¢çš„é‡å†™åˆ†æžæ ‘进行日志记录" -#: utils/misc/guc.c:1121 +#: utils/misc/guc.c:1318 msgid "Logs each query's execution plan." msgstr "记录æ¯ä¸€ä¸ªæŸ¥è¯¢çš„æ‰§è¡Œè®¡åˆ’" -#: utils/misc/guc.c:1130 +#: utils/misc/guc.c:1327 msgid "Indents parse and plan tree displays." msgstr "显示缩进的解æžå’Œè®¡åˆ’æ ‘" -#: utils/misc/guc.c:1139 +#: utils/misc/guc.c:1336 msgid "Writes parser performance statistics to the server log." msgstr "把分æžå™¨æ€§èƒ½ç»Ÿè®¡ä¿¡æ¯å†™å…¥åˆ°æœåŠ¡å™¨æ—¥å¿—ä¸­." -#: utils/misc/guc.c:1148 +#: utils/misc/guc.c:1345 msgid "Writes planner performance statistics to the server log." msgstr "把规划器性能统计信æ¯å†™å…¥åˆ°æœåŠ¡å™¨æ—¥å¿—ä¸­." -#: utils/misc/guc.c:1157 +#: utils/misc/guc.c:1354 msgid "Writes executor performance statistics to the server log." msgstr "把执行器 (executor) 性能统计信æ¯å†™å…¥åˆ°æœåŠ¡å™¨æ—¥å¿—ä¸­." -#: utils/misc/guc.c:1166 +#: utils/misc/guc.c:1363 msgid "Writes cumulative performance statistics to the server log." msgstr "把 cumulative 性能统计信æ¯å†™å…¥åˆ°æœåŠ¡å™¨æ—¥å¿—ä¸­." -#: utils/misc/guc.c:1176 -msgid "" -"Logs system resource usage statistics (memory and CPU) on various B-tree " -"operations." +#: utils/misc/guc.c:1373 +msgid "Logs system resource usage statistics (memory and CPU) on various B-tree operations." msgstr "基于å¯å˜çš„B-æ ‘æ“作的日志系统资æºä½¿ç”¨ç»Ÿè®¡ (内存和CPU) ." -#: utils/misc/guc.c:1188 +#: utils/misc/guc.c:1385 msgid "Collects information about executing commands." msgstr "收集执行命令的统计信æ¯." -#: utils/misc/guc.c:1189 -msgid "" -"Enables the collection of information on the currently executing command of " -"each session, along with the time at which that command began execution." +#: utils/misc/guc.c:1386 +msgid "Enables the collection of information on the currently executing command of each session, along with the time at which that command began execution." msgstr "在æ¯ä¸ªä¼šè¯å½“剿­£åœ¨æ‰§è¡Œçš„命令上å¯ç”¨ä¿¡æ¯æ”¶é›†, 并带有命令开始执行的时间." -#: utils/misc/guc.c:1199 +#: utils/misc/guc.c:1396 msgid "Collects statistics on database activity." msgstr "在数æ®åº“上正在执行的事务上收集统计信æ¯." -#: utils/misc/guc.c:1208 +#: utils/misc/guc.c:1405 msgid "Collects timing statistics for database I/O activity." msgstr "为数æ®åº“I/O活动进行时间统计." -#: utils/misc/guc.c:1218 +#: utils/misc/guc.c:1415 msgid "Updates the process title to show the active SQL command." msgstr "æ›´æ–°è¿›ç¨‹æ ‡é¢˜æ¥æ˜¾ç¤ºå¤„于活动状æ€çš„SQL命令" -#: utils/misc/guc.c:1219 -msgid "" -"Enables updating of the process title every time a new SQL command is " -"received by the server." +#: utils/misc/guc.c:1416 +msgid "Enables updating of the process title every time a new SQL command is received by the server." msgstr "æ¯ä¸€æ¬¡æœåС噍开始è¿è¡Œæ–°çš„SQL命令时å¯ç”¨è¿›ç¨‹æ ‡é¢˜çš„æ›´æ–°." -#: utils/misc/guc.c:1228 +#: utils/misc/guc.c:1429 msgid "Starts the autovacuum subprocess." msgstr "å¯åЍautovacuumå­è¿›ç¨‹." -#: utils/misc/guc.c:1238 +#: utils/misc/guc.c:1439 msgid "Generates debugging output for LISTEN and NOTIFY." msgstr "为 LISTEN å’Œ NOTIFY 生æˆå‡ºé”™ä¿¡æ¯." -#: utils/misc/guc.c:1250 +#: utils/misc/guc.c:1451 msgid "Emits information about lock usage." msgstr "å‘出有关é”使用的信æ¯." -#: utils/misc/guc.c:1260 +#: utils/misc/guc.c:1461 msgid "Emits information about user lock usage." msgstr "å‘出有关用户é”使用情况的信æ¯." -#: utils/misc/guc.c:1270 +#: utils/misc/guc.c:1471 msgid "Emits information about lightweight lock usage." msgstr "å‘出有关轻é‡é”使用的相关信æ¯." -#: utils/misc/guc.c:1280 -msgid "" -"Dumps information about all current locks when a deadlock timeout occurs." +#: utils/misc/guc.c:1481 +msgid "Dumps information about all current locks when a deadlock timeout occurs." msgstr "输出死é”è¶…æ—¶å‘生时所有当å‰é”的相关信æ¯." -#: utils/misc/guc.c:1292 +#: utils/misc/guc.c:1493 msgid "Logs long lock waits." msgstr "对长时间的é”等待记日志" -#: utils/misc/guc.c:1302 +#: utils/misc/guc.c:1503 msgid "Logs the host name in the connection logs." msgstr "åœ¨è”æŽ¥æ—¥å¿—ä¸­è®°å½•ä¸»æœºå." -#: utils/misc/guc.c:1303 -msgid "" -"By default, connection logs only show the IP address of the connecting host. " -"If you want them to show the host name you can turn this on, but depending " -"on your host name resolution setup it might impose a non-negligible " -"performance penalty." -msgstr "" -"åœ¨ç¼ºçœæƒ…况下,è¿žæŽ¥æ—¥å¿—åªæ˜¾ç¤ºæ¯ä¸ªæ­£åœ¨è¿žæŽ¥ä¸»æœºçš„IP地å€.å¦‚æžœæƒ³è¦æ˜¾ç¤ºä¸»æœºå,那么" -"必须把它打开,但是这å–决于主机åè§£æžçš„设置,这在性能上ä¸ä¼šæœ‰å½±å“." - -#: utils/misc/guc.c:1314 -msgid "Causes subtables to be included by default in various commands." -msgstr "使å­è¡¨åœ¨ä¸åŒçš„命令中被缺çœåŒ…å«" - -#: utils/misc/guc.c:1323 -msgid "Encrypt passwords." -msgstr "加密å£ä»¤." - -#: utils/misc/guc.c:1324 -msgid "" -"When a password is specified in CREATE USER or ALTER USER without writing " -"either ENCRYPTED or UNENCRYPTED, this parameter determines whether the " -"password is to be encrypted." -msgstr "" -"当在 CREATE USER 或者 ALTER USER 语å¥ä¸­æŒ‡å®šçš„å£ä»¤æ²¡æœ‰ç”¨ ENCRYPTED 或者 " -"UNENCRYPTED, æ­¤å‚æ•°ç¡®å®šå£ä»¤æ˜¯å¦åР坆." +#: utils/misc/guc.c:1504 +msgid "By default, connection logs only show the IP address of the connecting host. If you want them to show the host name you can turn this on, but depending on your host name resolution setup it might impose a non-negligible performance penalty." +msgstr "åœ¨ç¼ºçœæƒ…况下,è¿žæŽ¥æ—¥å¿—åªæ˜¾ç¤ºæ¯ä¸ªæ­£åœ¨è¿žæŽ¥ä¸»æœºçš„IP地å€.å¦‚æžœæƒ³è¦æ˜¾ç¤ºä¸»æœºå,那么必须把它打开,但是这å–决于主机åè§£æžçš„设置,这在性能上ä¸ä¼šæœ‰å½±å“." -#: utils/misc/guc.c:1334 +#: utils/misc/guc.c:1515 msgid "Treats \"expr=NULL\" as \"expr IS NULL\"." msgstr "\"expr=NULL\" 看作为 \"expr IS NULL\"." -#: utils/misc/guc.c:1335 -msgid "" -"When turned on, expressions of the form expr = NULL (or NULL = expr) are " -"treated as expr IS NULL, that is, they return true if expr evaluates to the " -"null value, and false otherwise. The correct behavior of expr = NULL is to " -"always return null (unknown)." -msgstr "" -"当打开选项, expr = NULL (或 NULL = expr)å½¢å¼çš„表达å¼ä¼šè¢«å½“作expr IS NUL而进" -"行处ç†, 那就是说,如果expr计算为空值那么会返回true,å¦åˆ™è¿”回为false。表达å¼" -"expr = NULL的正确行为应该是永远返回为空(未知)" +#: utils/misc/guc.c:1516 +msgid "When turned on, expressions of the form expr = NULL (or NULL = expr) are treated as expr IS NULL, that is, they return true if expr evaluates to the null value, and false otherwise. The correct behavior of expr = NULL is to always return null (unknown)." +msgstr "当打开选项, expr = NULL (或 NULL = expr)å½¢å¼çš„表达å¼ä¼šè¢«å½“作expr IS NUL而进行处ç†, 那就是说,如果expr计算为空值那么会返回true,å¦åˆ™è¿”回为false。表达å¼expr = NULL的正确行为应该是永远返回为空(未知)" -#: utils/misc/guc.c:1347 +#: utils/misc/guc.c:1528 msgid "Enables per-database user names." msgstr "å¯ç”¨æ¯ä¸ªæ•°æ®åº“的用户å" -#: utils/misc/guc.c:1356 +#: utils/misc/guc.c:1537 msgid "Sets the default read-only status of new transactions." msgstr "为新事物设置默认的åªè¯»çжæ€." -#: utils/misc/guc.c:1365 +#: utils/misc/guc.c:1546 msgid "Sets the current transaction's read-only status." msgstr "设置当å‰äº‹åŠ¡çš„åªè¯»çжæ€." -#: utils/misc/guc.c:1375 +#: utils/misc/guc.c:1556 msgid "Sets the default deferrable status of new transactions." msgstr "为新事物设置默认的å¯å»¶è¿Ÿçжæ€." -#: utils/misc/guc.c:1384 -msgid "" -"Whether to defer a read-only serializable transaction until it can be " -"executed with no possible serialization failures." -msgstr "" -"是å¦è¦å»¶æœŸæ‰§è¡Œä¸€ä¸ªåªè¯»å¯ä¸²è¡ŒåŒ–事务,直到执行时ä¸ä¼šå‡ºçް任何å¯ä¸²è¡ŒåŒ–失败." +#: utils/misc/guc.c:1565 +msgid "Whether to defer a read-only serializable transaction until it can be executed with no possible serialization failures." +msgstr "是å¦è¦å»¶æœŸæ‰§è¡Œä¸€ä¸ªåªè¯»å¯ä¸²è¡ŒåŒ–事务,直到执行时ä¸ä¼šå‡ºçް任何å¯ä¸²è¡ŒåŒ–失败." -#: utils/misc/guc.c:1394 +#: utils/misc/guc.c:1575 msgid "Enable row security." msgstr "å¯ç”¨è¡Œå®‰å…¨ã€‚" # sql_help.h:117 -#: utils/misc/guc.c:1395 +#: utils/misc/guc.c:1576 msgid "When enabled, row security will be applied to all users." msgstr "当被å¯ç”¨æ—¶ï¼Œè¡Œå®‰å…¨æ€§å°†è¢«åº”用到所有用户。" -#: utils/misc/guc.c:1403 +#: utils/misc/guc.c:1584 msgid "Check function bodies during CREATE FUNCTION." msgstr "在创建函数过程中检查函数体." -#: utils/misc/guc.c:1412 +#: utils/misc/guc.c:1593 msgid "Enable input of NULL elements in arrays." msgstr "在数组中å¯ç”¨ç©ºå€¼æˆå‘˜è¾“å…¥" -#: utils/misc/guc.c:1413 -msgid "" -"When turned on, unquoted NULL in an array input value means a null value; " -"otherwise it is taken literally." -msgstr "" -"当打开这个选项的时候,在数组输入值中没有引用的NULL表示空值;å¦åˆ™æ˜¯æŒ‰ç…§å­—é¢ä¸Šçš„" -"å«ä¹‰è¿›è¡Œè§£é‡Š." +#: utils/misc/guc.c:1594 +msgid "When turned on, unquoted NULL in an array input value means a null value; otherwise it is taken literally." +msgstr "当打开这个选项的时候,在数组输入值中没有引用的NULL表示空值;å¦åˆ™æ˜¯æŒ‰ç…§å­—é¢ä¸Šçš„å«ä¹‰è¿›è¡Œè§£é‡Š." -#: utils/misc/guc.c:1423 -msgid "Create new tables with OIDs by default." -msgstr "缺çœä¸‹ä½¿ç”¨OIDsæ¥åˆ›å»ºè¡¨." +#: utils/misc/guc.c:1610 +#, fuzzy +#| msgid "SSL renegotiation is no longer supported; this can only be 0." +msgid "WITH OIDS is no longer supported; this can only be false." +msgstr "SSL é‡å商已ç»ä¸å†è¢«æ”¯æŒï¼Œè¿™é‡Œåªèƒ½æ˜¯ 0。" -#: utils/misc/guc.c:1432 -msgid "" -"Start a subprocess to capture stderr output and/or csvlogs into log files." +#: utils/misc/guc.c:1620 +msgid "Start a subprocess to capture stderr output and/or csvlogs into log files." msgstr "å¯åŠ¨ä¸€ä¸ªå­è¿›ç¨‹ç”¨æ¥æ•获stderr输出或csvlogs,写到到日志文件中." -#: utils/misc/guc.c:1441 +#: utils/misc/guc.c:1629 msgid "Truncate existing log files of same name during log rotation." msgstr "åœ¨æ—¥å¿—åˆ‡æ¢æœŸé—´æˆªæ–­ç›¸åŒå称的日志文件" -#: utils/misc/guc.c:1452 +#: utils/misc/guc.c:1640 msgid "Emit information about resource usage in sorting." msgstr "å‘出在排åºä¸­å…³äºŽèµ„æºä½¿ç”¨çš„ä¿¡æ¯." -#: utils/misc/guc.c:1466 +#: utils/misc/guc.c:1654 msgid "Generate debugging output for synchronized scanning." msgstr "ä¸ºåŒæ­¥æ‰«æç”Ÿæˆè°ƒè¯•ä¿¡æ¯." -#: utils/misc/guc.c:1481 +#: utils/misc/guc.c:1669 msgid "Enable bounded sorting using heap sort." msgstr "ä½¿ç”¨å †æŽ’åºæ¥å¯ç”¨æœ‰ç•ŒæŽ’åº." -#: utils/misc/guc.c:1494 +#: utils/misc/guc.c:1682 msgid "Emit WAL-related debugging output." msgstr "å‘出与WAL相关的调试信æ¯è¾“出" -#: utils/misc/guc.c:1506 +#: utils/misc/guc.c:1694 msgid "Datetimes are integer based." msgstr "日期时间类型值是基于整数类型的" -#: utils/misc/guc.c:1521 -msgid "" -"Sets whether Kerberos and GSSAPI user names should be treated as case-" -"insensitive." +#: utils/misc/guc.c:1705 +msgid "Sets whether Kerberos and GSSAPI user names should be treated as case-insensitive." msgstr "设置 Kerberoså’ŒGSSAPIçš„ç”¨æˆ·åæ˜¯å¦åº”该区分大å°å†™." -#: utils/misc/guc.c:1531 +#: utils/misc/guc.c:1715 msgid "Warn about backslash escapes in ordinary string literals." msgstr "在顺åºå­—ç¬¦ä¸²æ–‡å­—ä¸­å…³äºŽåæ–œçº¿è½¬ä¹‰çš„警告" -#: utils/misc/guc.c:1541 +#: utils/misc/guc.c:1725 msgid "Causes '...' strings to treat backslashes literally." msgstr "使字符串'...' 按照字é¢å«ä¹‰å¤„ç†å斜线" -#: utils/misc/guc.c:1552 +#: utils/misc/guc.c:1736 msgid "Enable synchronized sequential scans." msgstr "å¯ç”¨åŒæ­¥åºåˆ—扫æ" -#: utils/misc/guc.c:1562 +#: utils/misc/guc.c:1746 +#, fuzzy +#| msgid "Sets the current transaction's read-only status." +msgid "Sets whether to include or exclude transaction with recovery target." +msgstr "设置当å‰äº‹åŠ¡çš„åªè¯»çжæ€." + +#: utils/misc/guc.c:1756 msgid "Allows connections and queries during recovery." msgstr "å…许在æ¢å¤æœŸé—´è¿›è¡Œè¿žæŽ¥å’ŒæŸ¥è¯¢." -#: utils/misc/guc.c:1572 -msgid "" -"Allows feedback from a hot standby to the primary that will avoid query " -"conflicts." +#: utils/misc/guc.c:1766 +msgid "Allows feedback from a hot standby to the primary that will avoid query conflicts." msgstr "å…许æ¥è‡ªçƒ­å¤‡èŠ‚ç‚¹åˆ°ä¸»èŠ‚ç‚¹çš„å“应,以é¿å…查询冲çª." -#: utils/misc/guc.c:1582 +#: utils/misc/guc.c:1776 msgid "Allows modifications of the structure of system tables." msgstr "å…许修改系统表的结构." -#: utils/misc/guc.c:1593 +#: utils/misc/guc.c:1787 msgid "Disables reading from system indexes." msgstr "ç¦æ­¢ä»Žç³»ç»Ÿç´¢å¼•中进行读æ“作" -#: utils/misc/guc.c:1594 -msgid "" -"It does not prevent updating the indexes, so it is safe to use. The worst " -"consequence is slowness." +#: utils/misc/guc.c:1788 +msgid "It does not prevent updating the indexes, so it is safe to use. The worst consequence is slowness." msgstr "è¿™ä¸èƒ½é˜²æ­¢æ›´æ–°ç´¢å¼•ï¼Œæ‰€ä»¥åº”è¯¥å®‰å…¨çš„ä½¿ç”¨ã€‚æœ€ç³Ÿç³•çš„ç»“æžœæ˜¯ä½¿ç³»ç»Ÿæ€§èƒ½å˜æ…¢." -#: utils/misc/guc.c:1605 -msgid "" -"Enables backward compatibility mode for privilege checks on large objects." +#: utils/misc/guc.c:1799 +msgid "Enables backward compatibility mode for privilege checks on large objects." msgstr "为在大对象上的æƒé™æ£€æŸ¥å¯ç”¨å‘åŽå…¼å®¹æ¨¡å¼." -#: utils/misc/guc.c:1606 -msgid "" -"Skips privilege checks when reading or modifying large objects, for " -"compatibility with PostgreSQL releases prior to 9.0." -msgstr "" -"为了与9.0版本之å‰çš„PostgreSQLç›¸å…¼å®¹ï¼Œåœ¨è¯»å–æˆ–修改大对象时候ä¸è¿›è¡Œæƒé™æ£€æŸ¥" +#: utils/misc/guc.c:1800 +msgid "Skips privilege checks when reading or modifying large objects, for compatibility with PostgreSQL releases prior to 9.0." +msgstr "为了与9.0版本之å‰çš„PostgreSQLç›¸å…¼å®¹ï¼Œåœ¨è¯»å–æˆ–修改大对象时候ä¸è¿›è¡Œæƒé™æ£€æŸ¥" -#: utils/misc/guc.c:1616 -msgid "" -"Emit a warning for constructs that changed meaning since PostgreSQL 9.4." +#: utils/misc/guc.c:1810 +msgid "Emit a warning for constructs that changed meaning since PostgreSQL 9.4." msgstr "为从PostgreSQL 9.4ä»¥æ¥æ”¹å˜äº†å«ä¹‰çš„结构å‘出一个警告。" -#: utils/misc/guc.c:1626 +#: utils/misc/guc.c:1820 msgid "When generating SQL fragments, quote all identifiers." msgstr "在生æˆSQLç‰‡æ®µæ—¶ï¼Œå¯¹æ‰€æœ‰æ ‡è¯†ç¬¦åŠ å¼•å·æ‹¬èµ·æ¥." -#: utils/misc/guc.c:1636 +#: utils/misc/guc.c:1830 msgid "Shows whether data checksums are turned on for this cluster." msgstr "显示当å‰ç°‡æ˜¯å¦å¼€å¯æ•°æ®æ ¡éªŒå’Œ." -#: utils/misc/guc.c:1647 +#: utils/misc/guc.c:1841 msgid "Add sequence number to syslog messages to avoid duplicate suppression." msgstr "å‘ syslog 消æ¯ä¸­å¢žåŠ åºå·ä»¥é¿å…抑制é‡å¤ã€‚" -#: utils/misc/guc.c:1657 +#: utils/misc/guc.c:1851 msgid "Split messages sent to syslog by lines and to fit into 1024 bytes." msgstr "å°†å‘é€ç»™ syslog 的消æ¯ç”¨è¡Œåˆ†ç¦»å¹¶ä¸”让æ¯ä¸ªéƒ¨åˆ†é€‚åˆäºŽ 1024 字节。" -#: utils/misc/guc.c:1676 -msgid "" -"Forces a switch to the next xlog file if a new file has not been started " -"within N seconds." -msgstr "如果新的文件没有在N秒内å¯åЍ,那么强制切æ¢åˆ°ä¸‹ä¸€ä¸ªxlog文件." +#: utils/misc/guc.c:1861 +msgid "Controls whether Gather and Gather Merge also run subplans." +msgstr "控制收集和收集åˆå¹¶æ˜¯å¦ä¹Ÿè¿è¡Œå­è®¡åˆ’." + +#: utils/misc/guc.c:1862 +msgid "Should gather nodes also run subplans, or just gather tuples?" +msgstr "收集节点也应该è¿è¡Œå­è®¡åˆ’ï¼Œæˆ–è€…åªæ˜¯æ”¶é›†å…ƒç»„?" + +#: utils/misc/guc.c:1872 +msgid "Allow JIT compilation." +msgstr "å…许JIT编译." + +#: utils/misc/guc.c:1883 +msgid "Register JIT compiled function with debugger." +msgstr "å‘调试器注册JIT编译函数." + +#: utils/misc/guc.c:1900 +msgid "Write out LLVM bitcode to facilitate JIT debugging." +msgstr "写出LLVM比特ç ï¼Œä¾¿äºŽJIT调试." + +#: utils/misc/guc.c:1911 +msgid "Allow JIT compilation of expressions." +msgstr "å…许JIT编译表达å¼." -#: utils/misc/guc.c:1687 +#: utils/misc/guc.c:1922 +msgid "Register JIT compiled function with perf profiler." +msgstr "用性能分æžå™¨æ³¨å†ŒJIT编译函数." + +#: utils/misc/guc.c:1939 +msgid "Allow JIT compilation of tuple deforming." +msgstr "å…许对元组å˜å½¢è¿›è¡ŒJIT编译." + +#: utils/misc/guc.c:1950 +msgid "Whether to continue running after a failure to sync data files." +msgstr "åŒæ­¥æ•°æ®æ–‡ä»¶å¤±è´¥åŽæ˜¯å¦ç»§ç»­è¿è¡Œ." + +#: utils/misc/guc.c:1968 +msgid "Forces a switch to the next WAL file if a new file has not been started within N seconds." +msgstr "如果新的文件没有在N秒内å¯åЍ,那么强制切æ¢åˆ°ä¸‹ä¸€ä¸ªWAL文件." + +#: utils/misc/guc.c:1979 msgid "Waits N seconds on connection startup after authentication." msgstr "完æˆè®¤è¯åŽï¼Œåœ¨å¯åŠ¨çš„è¿žæŽ¥ä¸Šç­‰å¾…Nç§’" -#: utils/misc/guc.c:1688 utils/misc/guc.c:2211 +#: utils/misc/guc.c:1980 utils/misc/guc.c:2526 msgid "This allows attaching a debugger to the process." msgstr "å…许将调试器添加到进程" -#: utils/misc/guc.c:1697 +#: utils/misc/guc.c:1989 msgid "Sets the default statistics target." msgstr "设置默认统计对象." -#: utils/misc/guc.c:1698 -msgid "" -"This applies to table columns that have not had a column-specific target set " -"via ALTER TABLE SET STATISTICS." +#: utils/misc/guc.c:1990 +msgid "This applies to table columns that have not had a column-specific target set via ALTER TABLE SET STATISTICS." msgstr "在没有通过ALTER TABLE SET STATISTICS产生列定义目标集åˆçš„列上使用." -#: utils/misc/guc.c:1707 +#: utils/misc/guc.c:1999 msgid "Sets the FROM-list size beyond which subqueries are not collapsed." msgstr "所设置的FROM列表大å°è¶…è¿‡å­æŸ¥è¯¢æ‰€å…许的最大长度" -#: utils/misc/guc.c:1709 -msgid "" -"The planner will merge subqueries into upper queries if the resulting FROM " -"list would have no more than this many items." -msgstr "" -"如果所产生的FROM列表æˆå‘˜ä¸è¶…过上层查询的相应的数é‡,é‚£ä¹ˆè®¡åˆ’å™¨ä¼šæŠŠå­æŸ¥è¯¢åˆå¹¶åˆ°" -"上层查询中." +#: utils/misc/guc.c:2001 +msgid "The planner will merge subqueries into upper queries if the resulting FROM list would have no more than this many items." +msgstr "如果所产生的FROM列表æˆå‘˜ä¸è¶…过上层查询的相应的数é‡,é‚£ä¹ˆè®¡åˆ’å™¨ä¼šæŠŠå­æŸ¥è¯¢åˆå¹¶åˆ°ä¸Šå±‚查询中." -#: utils/misc/guc.c:1719 +#: utils/misc/guc.c:2012 msgid "Sets the FROM-list size beyond which JOIN constructs are not flattened." msgstr "设置的FROM列表大å°è¶…过没有展平的JOIN结构大å°." -#: utils/misc/guc.c:1721 -msgid "" -"The planner will flatten explicit JOIN constructs into lists of FROM items " -"whenever a list of no more than this many items would result." -msgstr "" -"无论什么时候产生ä¸è¶…过这个数é‡çš„æˆå‘˜,计划器都将显å¼çš„JOIN结构展平到FROMå­å¥åŽ" -"é¢çš„æˆå‘˜åˆ—è¡¨ä¸­." +#: utils/misc/guc.c:2014 +msgid "The planner will flatten explicit JOIN constructs into lists of FROM items whenever a list of no more than this many items would result." +msgstr "无论什么时候产生ä¸è¶…过这个数é‡çš„æˆå‘˜,计划器都将显å¼çš„JOIN结构展平到FROMå­å¥åŽé¢çš„æˆå‘˜åˆ—è¡¨ä¸­." -#: utils/misc/guc.c:1731 +#: utils/misc/guc.c:2025 msgid "Sets the threshold of FROM items beyond which GEQO is used." msgstr "设置超过GEQO使用的FROM列表æˆå‘˜æ•°é‡é—¨é™å€¼." -#: utils/misc/guc.c:1740 +#: utils/misc/guc.c:2035 msgid "GEQO: effort is used to set the default for other GEQO parameters." msgstr "GEQO: 为其它GEQO傿•°è®¾ç½®ç¼ºçœå€¼" -#: utils/misc/guc.c:1749 +#: utils/misc/guc.c:2045 msgid "GEQO: number of individuals in the population." msgstr "GEQO: 人群 (population) 个体 (individual) æ•°" -#: utils/misc/guc.c:1750 utils/misc/guc.c:1759 +#: utils/misc/guc.c:2046 utils/misc/guc.c:2056 msgid "Zero selects a suitable default value." msgstr "没有选择出一个åˆé€‚的缺çœå€¼" -#: utils/misc/guc.c:1758 +#: utils/misc/guc.c:2055 msgid "GEQO: number of iterations of the algorithm." msgstr "GEQO: 算法的迭代次数" -#: utils/misc/guc.c:1769 +#: utils/misc/guc.c:2067 msgid "Sets the time to wait on a lock before checking for deadlock." msgstr "在检查死é”å‰è®¾ç½®åœ¨ä¸€ä¸ªé”上的等待时间." -#: utils/misc/guc.c:1780 -msgid "" -"Sets the maximum delay before canceling queries when a hot standby server is " -"processing archived WAL data." +#: utils/misc/guc.c:2078 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing archived WAL data." msgstr "当热备æœåŠ¡å™¨åœ¨å¤„ç†å·²å½’档的WALæ•°æ®æ—¶ï¼Œåœ¨å–消查询请求å‰è®¾ç½®æœ€å¤§çš„延迟." -#: utils/misc/guc.c:1791 -msgid "" -"Sets the maximum delay before canceling queries when a hot standby server is " -"processing streamed WAL data." -msgstr "" -"当热备æœåŠ¡å™¨åœ¨å¤„ç†é€šè¿‡æµå¤åˆ¶çš„WALæ•°æ®æ—¶ï¼Œåœ¨å–消查询请求å‰è®¾ç½®æœ€å¤§çš„延迟." +#: utils/misc/guc.c:2089 +msgid "Sets the maximum delay before canceling queries when a hot standby server is processing streamed WAL data." +msgstr "当热备æœåŠ¡å™¨åœ¨å¤„ç†é€šè¿‡æµå¤åˆ¶çš„WALæ•°æ®æ—¶ï¼Œåœ¨å–消查询请求å‰è®¾ç½®æœ€å¤§çš„延迟." -#: utils/misc/guc.c:1802 -msgid "" -"Sets the maximum interval between WAL receiver status reports to the primary." +#: utils/misc/guc.c:2100 +#, fuzzy +#| msgid "cannot manipulate replication origins during recovery" +msgid "Sets the minimum delay for applying changes during recovery." +msgstr "无法在æ¢å¤æœŸé—´æ“作å¤åˆ¶æºå¤´" + +#: utils/misc/guc.c:2111 +#, fuzzy +#| msgid "Sets the maximum interval between WAL receiver status reports to the primary." +msgid "Sets the maximum interval between WAL receiver status reports to the sending server." msgstr "为WAL接å—è¿›ç¨‹çš„çŠ¶æ€æŠ¥å‘Š(å‘主节点)设置最大时间间隔." -#: utils/misc/guc.c:1813 -msgid "Sets the maximum wait time to receive data from the primary." +#: utils/misc/guc.c:2122 +#, fuzzy +#| msgid "Sets the maximum wait time to receive data from the primary." +msgid "Sets the maximum wait time to receive data from the sending server." msgstr "设置从主节点上接收数æ®çš„æœ€å¤§ç­‰å¾…æ—¶é—´." -#: utils/misc/guc.c:1824 +#: utils/misc/guc.c:2133 msgid "Sets the maximum number of concurrent connections." msgstr "设置并å‘è”æŽ¥çš„æœ€å¤§ä¸ªæ•°." -#: utils/misc/guc.c:1834 +#: utils/misc/guc.c:2144 msgid "Sets the number of connection slots reserved for superusers." msgstr "设置为超级用户ä¿ç•™çš„è”æŽ¥æ•°." -#: utils/misc/guc.c:1848 +#: utils/misc/guc.c:2158 msgid "Sets the number of shared memory buffers used by the server." msgstr "设置æœåŠ¡å™¨ä½¿ç”¨çš„å…±äº«å†…å­˜ç¼“å†²åŒºçš„æ•°é‡." -#: utils/misc/guc.c:1859 +#: utils/misc/guc.c:2169 msgid "Sets the maximum number of temporary buffers used by each session." msgstr "设置æ¯ä¸ªä¼šè¯å¯ä½¿ç”¨çš„临时缓冲区的最大数é‡." -#: utils/misc/guc.c:1870 +#: utils/misc/guc.c:2180 msgid "Sets the TCP port the server listens on." msgstr "设置æœåŠ¡å™¨ç›‘å¬çš„ TCP 端å£å·." -#: utils/misc/guc.c:1880 +#: utils/misc/guc.c:2190 msgid "Sets the access permissions of the Unix-domain socket." msgstr "设置 Unix-domain 套接字的访问æƒé™." -#: utils/misc/guc.c:1881 -msgid "" -"Unix-domain sockets use the usual Unix file system permission set. The " -"parameter value is expected to be a numeric mode specification in the form " -"accepted by the chmod and umask system calls. (To use the customary octal " -"format the number must start with a 0 (zero).)" -msgstr "" -"Unix-domain 套接字使用普通的Unix文件许å¯é›†åˆ.傿•°å€¼åº”该是数值模å¼å®šä¹‰, 它的形" -"å¼åº”该是系统调用chmodå’Œumask坿ޥå—çš„.(为了使用习惯上以0å¼€å¤´çš„å…«è¿›åˆ¶æ ¼å¼æ•°å€¼)" +#: utils/misc/guc.c:2191 +msgid "Unix-domain sockets use the usual Unix file system permission set. The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "Unix-domain 套接字使用普通的Unix文件许å¯é›†åˆ.傿•°å€¼åº”该是数值模å¼å®šä¹‰, 它的形å¼åº”该是系统调用chmodå’Œumask坿ޥå—çš„.(为了使用习惯上以0å¼€å¤´çš„å…«è¿›åˆ¶æ ¼å¼æ•°å€¼)" -#: utils/misc/guc.c:1895 +#: utils/misc/guc.c:2205 msgid "Sets the file permissions for log files." msgstr "设置日志文件的文件访问æƒé™." -#: utils/misc/guc.c:1896 -msgid "" -"The parameter value is expected to be a numeric mode specification in the " -"form accepted by the chmod and umask system calls. (To use the customary " -"octal format the number must start with a 0 (zero).)" -msgstr "" -"傿•°å€¼æœŸæœ›ä½¿ç”¨æ•°å€¼æ¨¡å¼æ¥æŒ‡å®š, 它的形å¼åº”该是系统调用chmodå’Œumask坿ޥå—çš„.(为" -"了使用习惯上以0å¼€å¤´çš„å…«è¿›åˆ¶æ ¼å¼æ•°å€¼)" +#: utils/misc/guc.c:2206 +msgid "The parameter value is expected to be a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "傿•°å€¼æœŸæœ›ä½¿ç”¨æ•°å€¼æ¨¡å¼æ¥æŒ‡å®š, 它的形å¼åº”该是系统调用chmodå’Œumask坿ޥå—çš„.(为了使用习惯上以0å¼€å¤´çš„å…«è¿›åˆ¶æ ¼å¼æ•°å€¼)" + +#: utils/misc/guc.c:2220 +msgid "Mode of the data directory." +msgstr "æ•°æ®ç›®å½•的模å¼." -#: utils/misc/guc.c:1909 +#: utils/misc/guc.c:2221 +msgid "The parameter value is a numeric mode specification in the form accepted by the chmod and umask system calls. (To use the customary octal format the number must start with a 0 (zero).)" +msgstr "傿•°ä½¿ç”¨æ•°å€¼æ¨¡å¼æ¥æŒ‡å®š, 它的形å¼åº”该是系统调用chmodå’Œumask坿ޥå—çš„.(为了使用习惯上以0å¼€å¤´çš„å…«è¿›åˆ¶æ ¼å¼æ•°å€¼)" + +#: utils/misc/guc.c:2234 msgid "Sets the maximum memory to be used for query workspaces." msgstr "设置查询工作空间使用的最大内存数." -#: utils/misc/guc.c:1910 -msgid "" -"This much memory can be used by each internal sort operation and hash table " -"before switching to temporary disk files." -msgstr "" -"这些内存将å¯ä»¥ç”±æ¯ä¸€ä¸ªå†…éƒ¨æŽ’åºæ“作和转æ¢åˆ°ä¸´æ—¶ç£ç›˜æ–‡ä»¶ä¹‹å‰çš„æ•£åˆ—表æ¥ä½¿ç”¨" +#: utils/misc/guc.c:2235 +msgid "This much memory can be used by each internal sort operation and hash table before switching to temporary disk files." +msgstr "这些内存将å¯ä»¥ç”±æ¯ä¸€ä¸ªå†…éƒ¨æŽ’åºæ“作和转æ¢åˆ°ä¸´æ—¶ç£ç›˜æ–‡ä»¶ä¹‹å‰çš„æ•£åˆ—表æ¥ä½¿ç”¨" -#: utils/misc/guc.c:1922 +#: utils/misc/guc.c:2247 msgid "Sets the maximum memory to be used for maintenance operations." msgstr "设置维护æ“作使用的最大内存数." -#: utils/misc/guc.c:1923 +#: utils/misc/guc.c:2248 msgid "This includes operations such as VACUUM and CREATE INDEX." msgstr "此处动作包括 VACUUM å’Œ CREATE INDEX." -#: utils/misc/guc.c:1933 -#| msgid "Sets the maximum number of temporary buffers used by each session." -msgid "" -"Sets the maximum number of tuples to be sorted using replacement selection." -msgstr "设定è¦ä½¿ç”¨æ›¿æ¢é€‰æ‹©è¿›è¡ŒæŽ’åºçš„æœ€å¤§å…ƒç»„数。" - -#: utils/misc/guc.c:1934 -msgid "When more tuples than this are present, quicksort will be used." -msgstr "当存在超过这么多个元组时,将使用快速排åºã€‚" - -#: utils/misc/guc.c:1948 +#: utils/misc/guc.c:2263 msgid "Sets the maximum stack depth, in kilobytes." msgstr "设置最大的堆栈深度,å•使˜¯åƒå­—节." -#: utils/misc/guc.c:1959 -msgid "Limits the total size of all temporary files used by each session." -msgstr "为æ¯ä¸ªä¼šè¯å¯ä½¿ç”¨çš„æ‰€æœ‰ä¸´æ—¶æ–‡ä»¶é™åˆ¶æœ€å¤§å¤§å°." +#: utils/misc/guc.c:2274 +msgid "Limits the total size of all temporary files used by each process." +msgstr "é™åˆ¶æ¯ä¸ªè¿›ç¨‹ä½¿ç”¨çš„æ‰€æœ‰ä¸´æ—¶æ–‡ä»¶çš„æ€»å¤§å°." -#: utils/misc/guc.c:1960 +#: utils/misc/guc.c:2275 msgid "-1 means no limit." msgstr "-1 æ„æŒ‡æ²¡æœ‰é™åˆ¶." -#: utils/misc/guc.c:1970 +#: utils/misc/guc.c:2285 msgid "Vacuum cost for a page found in the buffer cache." msgstr "在缓冲区缓存中找到对于一个页进行清ç†çš„开销." -#: utils/misc/guc.c:1980 +#: utils/misc/guc.c:2295 msgid "Vacuum cost for a page not found in the buffer cache." msgstr "在缓冲区缓存中没有找到对于一个页进行清ç†çš„开销." -#: utils/misc/guc.c:1990 +#: utils/misc/guc.c:2305 msgid "Vacuum cost for a page dirtied by vacuum." msgstr "ç”±vacuum进程对è„页进行清ç†çš„开销." -#: utils/misc/guc.c:2000 +#: utils/misc/guc.c:2315 msgid "Vacuum cost amount available before napping." msgstr "在暂åœå‰å¯ç”¨çš„æ¸…ç†å¼€é”€æ€»é‡." -#: utils/misc/guc.c:2010 -msgid "Vacuum cost delay in milliseconds." -msgstr "Vacuum开销延迟是以毫秒为å•ä½" - -#: utils/misc/guc.c:2021 -msgid "Vacuum cost delay in milliseconds, for autovacuum." -msgstr "对于autovacuumæ¥è¯´,Vacuum开销延迟是以毫秒为å•ä½" - -#: utils/misc/guc.c:2032 +#: utils/misc/guc.c:2325 msgid "Vacuum cost amount available before napping, for autovacuum." msgstr "对于autovacuum进程,在暂åœå‰å‰è¿›è¡Œæ¸…ç†æœ‰æ•ˆå¼€é”€æ€»é‡." -#: utils/misc/guc.c:2042 -msgid "" -"Sets the maximum number of simultaneously open files for each server process." +#: utils/misc/guc.c:2335 +msgid "Sets the maximum number of simultaneously open files for each server process." msgstr "设置æ¯ä¸€ä¸ªæœåŠ¡å™¨è¿›ç¨‹åŒæ—¶æ‰“开文件的最大个数." -#: utils/misc/guc.c:2055 +#: utils/misc/guc.c:2348 msgid "Sets the maximum number of simultaneously prepared transactions." msgstr "è®¾ç½®åŒæ­¥çš„已准备好事务的最大个数." -#: utils/misc/guc.c:2066 +#: utils/misc/guc.c:2359 msgid "Sets the minimum OID of tables for tracking locks." msgstr "设置跟踪é”的表的最å°OID." -#: utils/misc/guc.c:2067 +#: utils/misc/guc.c:2360 msgid "Is used to avoid output on system tables." msgstr "用于é¿å…输出到系统表." -#: utils/misc/guc.c:2076 +#: utils/misc/guc.c:2369 msgid "Sets the OID of the table with unconditionally lock tracing." msgstr "设置无æ¡ä»¶é”追踪的表的OID." -#: utils/misc/guc.c:2088 +#: utils/misc/guc.c:2381 msgid "Sets the maximum allowed duration of any statement." msgstr "è®¾ç½®ä»»ä½•è¯­å¥æ‰§è¡Œæ—¶é—´çš„æœ€å¤§å€¼ (å•使¯«ç§’)." -#: utils/misc/guc.c:2089 utils/misc/guc.c:2100 utils/misc/guc.c:2111 +#: utils/misc/guc.c:2382 utils/misc/guc.c:2393 utils/misc/guc.c:2404 msgid "A value of 0 turns off the timeout." msgstr "值为 0 的时候关闭超时." -#: utils/misc/guc.c:2099 +#: utils/misc/guc.c:2392 msgid "Sets the maximum allowed duration of any wait for a lock." msgstr "等待é”的的最长时间值." -#: utils/misc/guc.c:2110 -#| msgid "Sets the maximum allowed duration of any statement." +#: utils/misc/guc.c:2403 msgid "Sets the maximum allowed duration of any idling transaction." msgstr "设定任何空载事务的最大å…许æŒç»­æ—¶é—´ã€‚" -#: utils/misc/guc.c:2121 +#: utils/misc/guc.c:2414 msgid "Minimum age at which VACUUM should freeze a table row." msgstr "VACUUMåº”è¯¥å†»ç»“ä¸€è¡Œè®°å½•çš„æœ€å°æ—¶é—´." -#: utils/misc/guc.c:2131 +#: utils/misc/guc.c:2424 msgid "Age at which VACUUM should scan whole table to freeze tuples." msgstr "这是VACUUMåº”è¯¥æ‰«ææ•´ä¸ªè¡¨æ¥å†»ç»“元组的时候." -#: utils/misc/guc.c:2141 +#: utils/misc/guc.c:2434 msgid "Minimum age at which VACUUM should freeze a MultiXactId in a table row." msgstr "VACUUM用于冻结表中æŸè¡Œå¯¹åº”çš„MultiXactIdçš„æœ€å°æ—¶é—´èŒƒå›´." -#: utils/misc/guc.c:2151 +#: utils/misc/guc.c:2444 msgid "Multixact age at which VACUUM should scan whole table to freeze tuples." msgstr "这是VACUUMåº”è¯¥æ‰«ææ•´ä¸ªè¡¨æ¥å†»ç»“元组的事务时间范围." -#: utils/misc/guc.c:2161 -msgid "" -"Number of transactions by which VACUUM and HOT cleanup should be deferred, " -"if any." +#: utils/misc/guc.c:2454 +msgid "Number of transactions by which VACUUM and HOT cleanup should be deferred, if any." msgstr "VACUUMå’Œçƒ­æ¸…ç†æ“作应该延迟的事务数é‡." -#: utils/misc/guc.c:2174 +#: utils/misc/guc.c:2467 msgid "Sets the maximum number of locks per transaction." msgstr "设置æ¯ä¸€ä¸ªäº‹ç‰©é”的最大个数." -#: utils/misc/guc.c:2175 -msgid "" -"The shared lock table is sized on the assumption that at most " -"max_locks_per_transaction * max_connections distinct objects will need to be " -"locked at any one time." -msgstr "" -"æŒæœ‰å…±äº«é”è¡¨çš„å¤§å°æ˜¯åŸºäºŽæœ€å¤šmax_locks_per_transaction * max_connections个ä¸åŒ" -"对象需è¦åœ¨ä»»ä½•时刻被é”定的å‡è®¾æ¥æŒ‡å®šçš„." +#: utils/misc/guc.c:2468 +msgid "The shared lock table is sized on the assumption that at most max_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "æŒæœ‰å…±äº«é”è¡¨çš„å¤§å°æ˜¯åŸºäºŽæœ€å¤šmax_locks_per_transaction * max_connections个ä¸åŒå¯¹è±¡éœ€è¦åœ¨ä»»ä½•时刻被é”定的å‡è®¾æ¥æŒ‡å®šçš„." -#: utils/misc/guc.c:2186 +#: utils/misc/guc.c:2479 msgid "Sets the maximum number of predicate locks per transaction." msgstr "设置æ¯ä¸€ä¸ªäº‹ç‰©çš„æ–­è¨€é”的最大个数." -#: utils/misc/guc.c:2187 -msgid "" -"The shared predicate lock table is sized on the assumption that at most " -"max_pred_locks_per_transaction * max_connections distinct objects will need " -"to be locked at any one time." -msgstr "" -"共享断言é”è¡¨çš„å¤§å°æ˜¯åŸºäºŽæœ€å¤šmax_locks_per_transaction * max_connections个ä¸åŒ" -"对象需è¦åœ¨ä»»ä½•时刻被é”定的å‡è®¾æ¥æŒ‡å®šçš„." +#: utils/misc/guc.c:2480 +msgid "The shared predicate lock table is sized on the assumption that at most max_pred_locks_per_transaction * max_connections distinct objects will need to be locked at any one time." +msgstr "共享断言é”è¡¨çš„å¤§å°æ˜¯åŸºäºŽæœ€å¤šmax_locks_per_transaction * max_connections个ä¸åŒå¯¹è±¡éœ€è¦åœ¨ä»»ä½•时刻被é”定的å‡è®¾æ¥æŒ‡å®šçš„." + +#: utils/misc/guc.c:2491 +msgid "Sets the maximum number of predicate-locked pages and tuples per relation." +msgstr "设置æ¯ä¸ªå…³ç³»çš„æ–­è¨€é”定页和元组的最大数目." + +#: utils/misc/guc.c:2492 +msgid "If more than this total of pages and tuples in the same relation are locked by a connection, those locks are replaced by a relation-level lock." +msgstr "如果一个连接é”定了åŒä¸€å…³ç³»ä¸­è¶…过此总数的页和元组,则这些é”将替æ¢ä¸ºå…³ç³»çº§åˆ«é”." -#: utils/misc/guc.c:2198 +#: utils/misc/guc.c:2502 +msgid "Sets the maximum number of predicate-locked tuples per page." +msgstr "设置æ¯é¡µæ–­è¨€é”定元组的最大数目." + +#: utils/misc/guc.c:2503 +msgid "If more than this number of tuples on the same page are locked by a connection, those locks are replaced by a page-level lock." +msgstr "如果一个连接é”定了åŒä¸€é¡µä¸Šè¶…过此数目的元组,则这些é”å°†è¢«é¡µçº§é”æ›¿æ¢." + +#: utils/misc/guc.c:2513 msgid "Sets the maximum allowed time to complete client authentication." msgstr "设置完æˆå®¢æˆ·ç«¯è®¤è¯çš„需è¦ç­‰å¾…的最长时间" -#: utils/misc/guc.c:2210 +#: utils/misc/guc.c:2525 msgid "Waits N seconds on connection startup before authentication." msgstr "在认è¯å‰åœ¨è¿žæŽ¥å¯åŠ¨ä¸Šéœ€è¦ç­‰å¾…Nç§’" -#: utils/misc/guc.c:2221 +#: utils/misc/guc.c:2536 msgid "Sets the number of WAL files held for standby servers." msgstr "设置用于备用æœåŠ¡å™¨è€ŒæŒæœ‰WAL文件的数é‡." -#: utils/misc/guc.c:2231 +#: utils/misc/guc.c:2546 msgid "Sets the minimum size to shrink the WAL to." msgstr "è®¾ç½®è¦æŠŠWAL收缩到的最å°å°ºå¯¸ã€‚" -#: utils/misc/guc.c:2242 +#: utils/misc/guc.c:2558 msgid "Sets the WAL size that triggers a checkpoint." msgstr "设置触å‘一次检查点的WAL尺寸。" -#: utils/misc/guc.c:2253 +#: utils/misc/guc.c:2570 msgid "Sets the maximum time between automatic WAL checkpoints." msgstr "设置两次自动WAL检查点事件之间需è¦ç­‰å¾…的最大时间" -#: utils/misc/guc.c:2264 -msgid "" -"Enables warnings if checkpoint segments are filled more frequently than this." +#: utils/misc/guc.c:2581 +msgid "Enables warnings if checkpoint segments are filled more frequently than this." msgstr "如果检查点段的填充频度超过了最大值,å¯ç”¨è­¦å‘ŠåŠŸèƒ½ã€‚" -#: utils/misc/guc.c:2266 -msgid "" -"Write a message to the server log if checkpoints caused by the filling of " -"checkpoint segment files happens more frequently than this number of " -"seconds. Zero turns off the warning." -msgstr "" -"如果检查点事件是由于填充检查点段比这个数é‡çš„ç§’æ•°æ›´åŠ é¢‘ç¹æ‰€å¼•èµ·ï¼Œé‚£ä¹ˆä¼šå‘æœåŠ¡" -"å™¨æ—¥å¿—å†™ä¸€æ¡æ¶ˆæ¯. å¦‚æžœæŠŠå‚æ•°è®¾ç½®ä¸º0,那么å¯ä»¥å…³æŽ‰è­¦å‘ŠåŠŸèƒ½." +#: utils/misc/guc.c:2583 +msgid "Write a message to the server log if checkpoints caused by the filling of checkpoint segment files happens more frequently than this number of seconds. Zero turns off the warning." +msgstr "如果检查点事件是由于填充检查点段比这个数é‡çš„ç§’æ•°æ›´åŠ é¢‘ç¹æ‰€å¼•èµ·ï¼Œé‚£ä¹ˆä¼šå‘æœåŠ¡å™¨æ—¥å¿—å†™ä¸€æ¡æ¶ˆæ¯. å¦‚æžœæŠŠå‚æ•°è®¾ç½®ä¸º0,那么å¯ä»¥å…³æŽ‰è­¦å‘ŠåŠŸèƒ½." + +#: utils/misc/guc.c:2595 utils/misc/guc.c:2753 utils/misc/guc.c:2782 +msgid "Number of pages after which previously performed writes are flushed to disk." +msgstr "页颿•°ï¼Œåœ¨æ­¤ä¹‹åŽä»¥å‰æ‰§è¡Œçš„写æ“作会被刷写到ç£ç›˜ã€‚" -#: utils/misc/guc.c:2278 +#: utils/misc/guc.c:2606 msgid "Sets the number of disk-page buffers in shared memory for WAL." msgstr "为 WAL 设置共享内存中ç£ç›˜é¡µç¼“冲区的个数." -#: utils/misc/guc.c:2289 +#: utils/misc/guc.c:2617 msgid "Time between WAL flushes performed in the WAL writer." msgstr "WAL 写入器中执行 WAL 刷写之间的时间。" -#: utils/misc/guc.c:2300 -msgid "Amount of WAL written out by WAL writer triggering a flush." +#: utils/misc/guc.c:2628 +msgid "Amount of WAL written out by WAL writer that triggers a flush." msgstr "触å‘一次刷写的 WAL 写入器写出的 WAL æ•°é‡ã€‚" -#: utils/misc/guc.c:2312 +#: utils/misc/guc.c:2639 msgid "Sets the maximum number of simultaneously running WAL sender processes." msgstr "è®¾ç½®åŒæ—¶è¿è¡Œçš„WALå‘é€è¿›ç¨‹æœ€å¤§æ•°é‡" -#: utils/misc/guc.c:2323 +#: utils/misc/guc.c:2650 msgid "Sets the maximum number of simultaneously defined replication slots." msgstr "è®¾ç½®åŒæ­¥çš„已定义å¤åˆ¶æ§½çš„æœ€å¤§æ•°." -#: utils/misc/guc.c:2333 +#: utils/misc/guc.c:2660 msgid "Sets the maximum time to wait for WAL replication." msgstr "设置最大时间,等待WALå¤åˆ¶." -#: utils/misc/guc.c:2344 -msgid "" -"Sets the delay in microseconds between transaction commit and flushing WAL " -"to disk." +#: utils/misc/guc.c:2671 +msgid "Sets the delay in microseconds between transaction commit and flushing WAL to disk." msgstr "设置事物æäº¤å’Œåˆ·æ–° WAL 到ç£ç›˜é—´çš„延迟时间, å•ä½å¾®ç§’." -#: utils/misc/guc.c:2356 -msgid "" -"Sets the minimum concurrent open transactions before performing commit_delay." +#: utils/misc/guc.c:2683 +msgid "Sets the minimum concurrent open transactions before performing commit_delay." msgstr "在执行commit_delayå‰ï¼Œè®¾ç½®æœ€å°‘çš„å¯åŒæ­¥æ‰“开事务的数é‡." -#: utils/misc/guc.c:2367 +#: utils/misc/guc.c:2694 msgid "Sets the number of digits displayed for floating-point values." msgstr "è®¾ç½®æµ®ç‚¹æ•°æ˜¾ç¤ºçš„ä½æ•°." -#: utils/misc/guc.c:2368 -msgid "" -"This affects real, double precision, and geometric data types. The parameter " -"value is added to the standard number of digits (FLT_DIG or DBL_DIG as " -"appropriate)." -msgstr "" -"这将影å“实数,åŒç²¾åº¦ç±»åž‹å’Œå‡ ä½•æ•°æ®ç±»åž‹.傿•°è¢«åŠ åˆ°ä½æ•°çš„æ ‡å‡†æ•°é‡(视情况而定,å¯" -"能是FLT_DIG或DBL_DIG)" +#: utils/misc/guc.c:2695 +#, fuzzy +#| msgid "This affects real, double precision, and geometric data types. The parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate)." +msgid "This affects real, double precision, and geometric data types. A zero or negative parameter value is added to the standard number of digits (FLT_DIG or DBL_DIG as appropriate). Any value greater than zero selects precise output mode." +msgstr "这将影å“实数,åŒç²¾åº¦ç±»åž‹å’Œå‡ ä½•æ•°æ®ç±»åž‹.傿•°è¢«åŠ åˆ°ä½æ•°çš„æ ‡å‡†æ•°é‡(视情况而定,å¯èƒ½æ˜¯FLT_DIG或DBL_DIG)" -#: utils/misc/guc.c:2379 +#: utils/misc/guc.c:2707 msgid "Sets the minimum execution time above which statements will be logged." msgstr "è®¾ç½®æœ€å°æ‰§è¡Œæ—¶é—´ï¼Œæ‰§è¡Œæ—¶é—´å¤§äºŽç­‰äºŽè¿™ä¸ªå€¼çš„语å¥éƒ½å°†è¢«è®°å½•." -#: utils/misc/guc.c:2381 -msgid "Zero prints all queries. -1 turns this feature off." -msgstr "" -"如果值设置为0,那么打å°å‡ºæ‰€æœ‰æŸ¥è¯¢. 如果设置为-1,那么将把这个功能特性关闭" +#: utils/misc/guc.c:2709 +#, fuzzy +#| msgid "Zero prints all queries. -1 turns this feature off." +msgid "Zero prints all queries, subject to log_statement_sample_rate. -1 turns this feature off." +msgstr "如果值设置为0,那么打å°å‡ºæ‰€æœ‰æŸ¥è¯¢. 如果设置为-1,那么将把这个功能特性关闭" -#: utils/misc/guc.c:2391 -msgid "" -"Sets the minimum execution time above which autovacuum actions will be " -"logged." -msgstr "" -"è®¾ç½®æœ€å°æ‰§è¡Œæ—¶é—´,如果autovacuumæ“作时间大于等于这个值,那么将记录这些æ“作." +#: utils/misc/guc.c:2720 +msgid "Sets the minimum execution time above which autovacuum actions will be logged." +msgstr "è®¾ç½®æœ€å°æ‰§è¡Œæ—¶é—´,如果autovacuumæ“作时间大于等于这个值,那么将记录这些æ“作." -#: utils/misc/guc.c:2393 +#: utils/misc/guc.c:2722 msgid "Zero prints all actions. -1 turns autovacuum logging off." msgstr "0表示打å°å‡ºæ‰€æœ‰çš„æ“ä½œ.-1表示关闭对autovacuum的日志记录功能" -#: utils/misc/guc.c:2403 +#: utils/misc/guc.c:2732 msgid "Background writer sleep time between rounds." msgstr "åŽå°å†™å…¥è¿›ç¨‹ (Background writer) 两次è¿è¡Œä¹‹é—´çš„休眠时间." -#: utils/misc/guc.c:2414 +#: utils/misc/guc.c:2743 msgid "Background writer maximum number of LRU pages to flush per round." msgstr "åŽå°å†™å…¥è¿›ç¨‹ (Background writer) æ¯æ¬¡å¯åˆ·æ–°LRU页的最大数é‡" -#: utils/misc/guc.c:2426 -msgid "" -"Number of simultaneous requests that can be handled efficiently by the disk " -"subsystem." +#: utils/misc/guc.c:2766 +msgid "Number of simultaneous requests that can be handled efficiently by the disk subsystem." msgstr "å¯ä»¥ç”±ç£ç›˜å­ç³»ç»Ÿæœ‰æ•ˆå¤„ç†çš„å¹¶å‘请求数é‡." -#: utils/misc/guc.c:2427 -msgid "" -"For RAID arrays, this should be approximately the number of drive spindles " -"in the array." +#: utils/misc/guc.c:2767 +msgid "For RAID arrays, this should be approximately the number of drive spindles in the array." msgstr "对于RAIDç£ç›˜é˜µåˆ—æ¥è¯´ï¼ŒåŒæ­¥å¯å¤„ç†çš„请求与ç£ç›˜é˜µåˆ—中ç£ç›˜æ•°é‡åº”该相近." -#: utils/misc/guc.c:2440 utils/misc/guc.c:2452 utils/misc/guc.c:2464 -msgid "" -"Number of pages after which previously performed writes are flushed to disk." -msgstr "页颿•°ï¼Œåœ¨æ­¤ä¹‹åŽä»¥å‰æ‰§è¡Œçš„写æ“作会被刷写到ç£ç›˜ã€‚" - -#: utils/misc/guc.c:2478 +#: utils/misc/guc.c:2795 msgid "Maximum number of concurrent worker processes." msgstr "最大并å‘工作进程数." -#: utils/misc/guc.c:2488 +#: utils/misc/guc.c:2807 +msgid "Maximum number of logical replication worker processes." +msgstr "逻辑å¤åˆ¶å·¥ä½œè¿›ç¨‹çš„æœ€å¤§æ•°ç›®." + +#: utils/misc/guc.c:2819 +msgid "Maximum number of table synchronization workers per subscription." +msgstr "æ¯ä¸ªè®¢é˜…çš„è¡¨åŒæ­¥å·¥ä½œçº¿ç¨‹çš„æœ€å¤§æ•°ç›®." + +#: utils/misc/guc.c:2829 msgid "Automatic log file rotation will occur after N minutes." msgstr "在N分钟åŽå°†ä¼šäº§ç”Ÿè‡ªåŠ¨æ—¥å¿—æ–‡ä»¶åˆ‡æ¢." -#: utils/misc/guc.c:2499 +#: utils/misc/guc.c:2840 msgid "Automatic log file rotation will occur after N kilobytes." msgstr "当写入了Nåƒå­—节会å‘生自动日志文件切æ¢" -#: utils/misc/guc.c:2510 +#: utils/misc/guc.c:2851 msgid "Shows the maximum number of function arguments." msgstr "æ˜¾ç¤ºå‡½æ•°å‚æ•°çš„æœ€å¤§ä¸ªæ•°." -#: utils/misc/guc.c:2521 +#: utils/misc/guc.c:2862 msgid "Shows the maximum number of index keys." msgstr "显示索引键值的最大个数." -#: utils/misc/guc.c:2532 +#: utils/misc/guc.c:2873 msgid "Shows the maximum identifier length." msgstr "显示标识符最大长度" -#: utils/misc/guc.c:2543 +#: utils/misc/guc.c:2884 msgid "Shows the size of a disk block." msgstr "显示一个ç£ç›˜å—的大å°" -#: utils/misc/guc.c:2554 +#: utils/misc/guc.c:2895 msgid "Shows the number of pages per disk file." msgstr "显示在æ¯ä¸ªç£ç›˜æ–‡ä»¶ä¸­é¡µçš„æ•°é‡." -#: utils/misc/guc.c:2565 +#: utils/misc/guc.c:2906 msgid "Shows the block size in the write ahead log." msgstr "显示预写日志中的å—大å°." -#: utils/misc/guc.c:2576 -msgid "" -"Sets the time to wait before retrying to retrieve WAL after a failed attempt." +#: utils/misc/guc.c:2917 +msgid "Sets the time to wait before retrying to retrieve WAL after a failed attempt." msgstr "设置在å°è¯•失败åŽé‡è¯•检索WAL之å‰è¦ç­‰å¾…的时间。" -#: utils/misc/guc.c:2588 -msgid "Shows the number of pages per write ahead log segment." -msgstr "显示æ¯ä¸ªé¢„写日志段中页的数é‡." +#: utils/misc/guc.c:2929 +msgid "Shows the size of write ahead log segments." +msgstr "显示预写日志段的大å°." -#: utils/misc/guc.c:2601 +#: utils/misc/guc.c:2942 msgid "Time to sleep between autovacuum runs." msgstr "两次è¿è¡Œautovacuum进程的休眠时间" -#: utils/misc/guc.c:2611 +#: utils/misc/guc.c:2952 msgid "Minimum number of tuple updates or deletes prior to vacuum." msgstr "è®¾ç½®æ¿€æ´»æ¸…ç†æ“ä½œæ‰€éœ€è¦æœ€å°æ•°é‡çš„æ›´æ–°æˆ–删除元组." -#: utils/misc/guc.c:2620 +#: utils/misc/guc.c:2961 msgid "Minimum number of tuple inserts, updates, or deletes prior to analyze." msgstr "分æžå‰å¯æ’å…¥ï¼Œæ›´æ–°æˆ–åˆ é™¤å…ƒç»„çš„æœ€å°æ•°é‡" -#: utils/misc/guc.c:2630 -msgid "" -"Age at which to autovacuum a table to prevent transaction ID wraparound." +#: utils/misc/guc.c:2971 +msgid "Age at which to autovacuum a table to prevent transaction ID wraparound." msgstr "这是应该自动清ç†ä¸€å¼ è¡¨ä»¥é¿å…事务IDé‡å çš„æ—¶é—´æ®µ." -#: utils/misc/guc.c:2641 -msgid "" -"Multixact age at which to autovacuum a table to prevent multixact wraparound." +#: utils/misc/guc.c:2982 +msgid "Multixact age at which to autovacuum a table to prevent multixact wraparound." msgstr "自动清ç†ä¸€å¼ è¡¨ä»¥é¿å…事务IDé‡å çš„æ—¶é—´èŒƒå›´." -#: utils/misc/guc.c:2651 -msgid "" -"Sets the maximum number of simultaneously running autovacuum worker " -"processes." +#: utils/misc/guc.c:2992 +msgid "Sets the maximum number of simultaneously running autovacuum worker processes." msgstr "设置最大å¯åŒæ—¶è¿è¡Œçš„autovacuum工作进程数é‡" -#: utils/misc/guc.c:2661 -#| msgid "Sets the maximum number of predicate locks per transaction." +#: utils/misc/guc.c:3002 +msgid "Sets the maximum number of parallel processes per maintenance operation." +msgstr "设置æ¯ä¸ªç»´æŠ¤æ“作的最大并行进程数." + +#: utils/misc/guc.c:3012 msgid "Sets the maximum number of parallel processes per executor node." msgstr "设定一个执行器节点上的最大并行进程数。" -#: utils/misc/guc.c:2671 +#: utils/misc/guc.c:3023 +msgid "Sets the maximum number of parallel workers that can be active at one time." +msgstr "设置一次å¯ä»¥æ¿€æ´»çš„æœ€å¤§å¹¶è¡Œå·¥ä½œæ•°." + +#: utils/misc/guc.c:3034 msgid "Sets the maximum memory to be used by each autovacuum worker process." msgstr "设置æ¯ä¸ªè‡ªåŠ¨æ¸…ç†(autovacuum)工作进程è¦ä½¿ç”¨çš„æœ€å¤§å†…存数." -#: utils/misc/guc.c:2682 -msgid "" -"Time before a snapshot is too old to read pages changed after the snapshot " -"was taken." +#: utils/misc/guc.c:3045 +msgid "Time before a snapshot is too old to read pages changed after the snapshot was taken." msgstr "快照在被å–得多久以åŽï¼Œä¼šå˜å¾—å¯¹äºŽè¯»å–æ”¹å˜çš„页é¢å¤ªæ—§ã€‚" -#: utils/misc/guc.c:2683 -#| msgid "A value of 0 uses the system default." +#: utils/misc/guc.c:3046 msgid "A value of -1 disables this feature." msgstr "值为 -1 å°†ç¦ç”¨è¿™ä¸ªç‰¹æ€§." -#: utils/misc/guc.c:2693 +#: utils/misc/guc.c:3056 msgid "Time between issuing TCP keepalives." msgstr "å¯åЍTCP存活定时器的间隔" -#: utils/misc/guc.c:2694 utils/misc/guc.c:2705 +#: utils/misc/guc.c:3057 utils/misc/guc.c:3068 utils/misc/guc.c:3192 msgid "A value of 0 uses the system default." msgstr "值为0的时候表示系统缺çœå€¼" -#: utils/misc/guc.c:2704 +#: utils/misc/guc.c:3067 msgid "Time between TCP keepalive retransmits." msgstr "在两次TCP存活å¯åЍ噍釿–°ä¼ é€ä¹‹é—´éœ€è¦èŠ±è´¹çš„æ—¶é—´" -#: utils/misc/guc.c:2715 -#| msgid "SSL regenotiation is no longer supported; this can only be 0." +#: utils/misc/guc.c:3078 msgid "SSL renegotiation is no longer supported; this can only be 0." msgstr "SSL é‡å商已ç»ä¸å†è¢«æ”¯æŒï¼Œè¿™é‡Œåªèƒ½æ˜¯ 0。" -#: utils/misc/guc.c:2726 +#: utils/misc/guc.c:3089 msgid "Maximum number of TCP keepalive retransmits." msgstr "设置æ¯ä¸€ä¸ªäº‹ç‰©é”的最大个数." -#: utils/misc/guc.c:2727 -msgid "" -"This controls the number of consecutive keepalive retransmits that can be " -"lost before a connection is considered dead. A value of 0 uses the system " -"default." -msgstr "" -"ç”¨äºŽæŽ§åˆ¶è¿žç»­å­˜æ´»å™¨å†æ¬¡ä¼ è¾“æ•°é‡ï¼Œè¿™äº›å­˜æ´»å™¨é‡åœ¨è¿žæŽ¥è¢«è®¤ä¸ºæ–­å¼€å‰ä¼šä¸¢å¤±.值0用于" -"表示系统缺çœ." +#: utils/misc/guc.c:3090 +msgid "This controls the number of consecutive keepalive retransmits that can be lost before a connection is considered dead. A value of 0 uses the system default." +msgstr "ç”¨äºŽæŽ§åˆ¶è¿žç»­å­˜æ´»å™¨å†æ¬¡ä¼ è¾“æ•°é‡ï¼Œè¿™äº›å­˜æ´»å™¨é‡åœ¨è¿žæŽ¥è¢«è®¤ä¸ºæ–­å¼€å‰ä¼šä¸¢å¤±.值0用于表示系统缺çœ." -#: utils/misc/guc.c:2738 +#: utils/misc/guc.c:3101 msgid "Sets the maximum allowed result for exact search by GIN." msgstr "设置由GIN进行的精确æœç´¢æ‰€å…许的最大å…许结果." -#: utils/misc/guc.c:2749 -msgid "Sets the planner's assumption about the size of the disk cache." -msgstr "设置关于计划器对ç£ç›˜ç¼“冲大å°çš„å‡è®¾." +#: utils/misc/guc.c:3112 +msgid "Sets the planner's assumption about the total size of the data caches." +msgstr "设置查询计划器对数æ®ç¼“存总大å°çš„å‡è®¾." -#: utils/misc/guc.c:2750 -msgid "" -"That is, the portion of the kernel's disk cache that will be used for " -"PostgreSQL data files. This is measured in disk pages, which are normally 8 " -"kB each." -msgstr "å°†è¦ç”¨äºŽå­˜å‚¨PostgreSQLæ•°æ®æ–‡ä»¶çš„内核ç£ç›˜ç¼“冲部分,以8K大å°çš„页为å•ä½." +#: utils/misc/guc.c:3113 +msgid "That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. This is measured in disk pages, which are normally 8 kB each." +msgstr "PostgreSQLæ•°æ®æ–‡ä»¶ä½¿ç”¨çš„缓存(内核缓存和共享缓冲区)的总大å°ï¼Œè¿™æ˜¯ä»¥ç£ç›˜é¡µä¸ºå•使µ‹é‡çš„,通常æ¯ä¸ªç£ç›˜é¡µä¸º8KB." + +#: utils/misc/guc.c:3124 +msgid "Sets the minimum amount of table data for a parallel scan." +msgstr "为并行扫æè®¾ç½®è¡¨æ•°æ®çš„æœ€å°é‡." + +#: utils/misc/guc.c:3125 +msgid "If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered." +msgstr "如果查询计划器估计它将读å–的表页太å°ï¼Œæ— æ³•达到此é™åˆ¶ï¼Œåˆ™ä¸ä¼šè€ƒè™‘并行扫æ." + +#: utils/misc/guc.c:3135 +msgid "Sets the minimum amount of index data for a parallel scan." +msgstr "设置并行扫æçš„æœ€å°ç´¢å¼•æ•°æ®é‡." -#: utils/misc/guc.c:2763 +#: utils/misc/guc.c:3136 +msgid "If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered." +msgstr "如果查询计划器估计它将读å–的索引页太å°ï¼Œæ— æ³•达到此é™åˆ¶ï¼Œåˆ™ä¸ä¼šè€ƒè™‘并行扫æ." + +#: utils/misc/guc.c:3147 msgid "Shows the server version as an integer." msgstr "ä»¥æ•´æ•°çš„å½¢å¼æ˜¾ç¤ºæœåŠ¡å™¨ç‰ˆæœ¬ä¿¡æ¯." -#: utils/misc/guc.c:2774 +#: utils/misc/guc.c:3158 msgid "Log the use of temporary files larger than this number of kilobytes." msgstr "记录对超过这个数é‡(以åƒå­—节为å•ä½)的临时文件的使用." -#: utils/misc/guc.c:2775 +#: utils/misc/guc.c:3159 msgid "Zero logs all files. The default is -1 (turning this feature off)." msgstr "如果设置为0ï¼Œæ‰“å°æ‰€æœ‰æŸ¥è¯¢. 默认值为 -1 (表示关闭此功能)." -#: utils/misc/guc.c:2785 +#: utils/misc/guc.c:3169 msgid "Sets the size reserved for pg_stat_activity.query, in bytes." msgstr "设置为pg_stat_activity.query所ä¿ç•™çš„空间大å°ï¼Œä»¥å­—节为å•ä½." -#: utils/misc/guc.c:2800 +#: utils/misc/guc.c:3180 msgid "Sets the maximum size of the pending list for GIN index." msgstr "为GIN索引设置待处ç†åˆ—表的最大尺寸。" -#: utils/misc/guc.c:2820 -msgid "" -"Sets the planner's estimate of the cost of a sequentially fetched disk page." +#: utils/misc/guc.c:3191 +msgid "TCP user timeout." +msgstr "" + +#: utils/misc/guc.c:3211 +msgid "Sets the planner's estimate of the cost of a sequentially fetched disk page." msgstr "设置计划器对顺åºèŽ·å–ç£ç›˜é¡µçš„开销估算" -#: utils/misc/guc.c:2830 -msgid "" -"Sets the planner's estimate of the cost of a nonsequentially fetched disk " -"page." +#: utils/misc/guc.c:3222 +msgid "Sets the planner's estimate of the cost of a nonsequentially fetched disk page." msgstr "设置计划器对éžé¡ºåºèŽ·å–ç£ç›˜é¡µçš„开销估算." -#: utils/misc/guc.c:2840 +#: utils/misc/guc.c:3233 msgid "Sets the planner's estimate of the cost of processing each tuple (row)." msgstr "è®¾ç½®è®¡åˆ’å™¨å¯¹å¤„ç†æ¯ä¸ªå…ƒç»„(也就是记录)的开销估算" -#: utils/misc/guc.c:2850 -msgid "" -"Sets the planner's estimate of the cost of processing each index entry " -"during an index scan." +#: utils/misc/guc.c:3244 +msgid "Sets the planner's estimate of the cost of processing each index entry during an index scan." msgstr "è®¾ç½®è®¡åˆ’å™¨åœ¨ç´¢å¼•æ‰«ææœŸé—´å¯¹å¤„ç†æ¯ä¸ªç´¢å¼•项的开销估算." -#: utils/misc/guc.c:2860 -msgid "" -"Sets the planner's estimate of the cost of processing each operator or " -"function call." +#: utils/misc/guc.c:3255 +msgid "Sets the planner's estimate of the cost of processing each operator or function call." msgstr "è®¾ç½®è®¡åˆ’å™¨å¯¹å¤„ç†æ¯ä¸ªæ“作符和函数调用的开销估算." -#: utils/misc/guc.c:2870 -#| msgid "" -#| "Sets the planner's estimate of the cost of processing each tuple (row)." -msgid "" -"Sets the planner's estimate of the cost of passing each tuple (row) from " -"worker to master backend." +#: utils/misc/guc.c:3266 +msgid "Sets the planner's estimate of the cost of passing each tuple (row) from worker to master backend." msgstr "设定规划器对于从工作者å‘主控åŽç«¯ä¼ é€’æ¯ä¸€ä¸ªå…ƒç»„(行)的代价估计。" -#: utils/misc/guc.c:2880 -#| msgid "" -#| "Sets the planner's estimate of the cost of processing each tuple (row)." -msgid "" -"Sets the planner's estimate of the cost of starting up worker processes for " -"parallel query." +#: utils/misc/guc.c:3277 +msgid "Sets the planner's estimate of the cost of starting up worker processes for parallel query." msgstr "设定规划器对于å¯åŠ¨å¹¶è¡ŒæŸ¥è¯¢çš„å·¥ä½œè€…è¿›ç¨‹çš„ä»£ä»·ä¼°è®¡ã€‚" -#: utils/misc/guc.c:2891 -msgid "" -"Sets the planner's estimate of the fraction of a cursor's rows that will be " -"retrieved." +#: utils/misc/guc.c:3289 +msgid "Perform JIT compilation if query is more expensive." +msgstr "如果查询更昂贵,则执行JIT编译." + +#: utils/misc/guc.c:3290 +msgid "-1 disables JIT compilation." +msgstr "使用-1ç¦ç”¨JIT编译." + +#: utils/misc/guc.c:3300 +msgid "Optimize JITed functions if query is more expensive." +msgstr "å¦‚æžœæŸ¥è¯¢æˆæœ¬æ›´é«˜ï¼Œåˆ™ä¼˜åŒ–JITed函数" + +#: utils/misc/guc.c:3301 +msgid "-1 disables optimization." +msgstr "使用-1ç¦ç”¨ä¼˜åŒ–." + +#: utils/misc/guc.c:3311 +msgid "Perform JIT inlining if query is more expensive." +msgstr "如果查询更昂贵,则执行JIT内è”." + +#: utils/misc/guc.c:3312 +msgid "-1 disables inlining." +msgstr "使用-1ç¦ç”¨å†…è”." + +#: utils/misc/guc.c:3322 +msgid "Sets the planner's estimate of the fraction of a cursor's rows that will be retrieved." msgstr "设置计划器对于通过游标å–回记录部分的估算." -#: utils/misc/guc.c:2902 +#: utils/misc/guc.c:3334 msgid "GEQO: selective pressure within the population." msgstr "GEQO: 在总体中的选择性压力" -#: utils/misc/guc.c:2912 +#: utils/misc/guc.c:3345 msgid "GEQO: seed for random path selection." msgstr "GEQO:ç”¨äºŽéšæœºè·¯å¾„选择的ç§å­." -#: utils/misc/guc.c:2922 +#: utils/misc/guc.c:3356 msgid "Multiple of the average buffer usage to free per round." msgstr "æ¯ä¸€æ¬¡é‡Šæ”¾å¹³å‡ç¼“冲区使用é‡çš„倿•°å¤§å°" -#: utils/misc/guc.c:2932 +#: utils/misc/guc.c:3366 msgid "Sets the seed for random-number generation." msgstr "设置生æˆéšæœºæ•°çš„ç§å­." -#: utils/misc/guc.c:2943 -msgid "" -"Number of tuple updates or deletes prior to vacuum as a fraction of " -"reltuples." +#: utils/misc/guc.c:3377 +msgid "Vacuum cost delay in milliseconds." +msgstr "Vacuum开销延迟是以毫秒为å•ä½" + +#: utils/misc/guc.c:3388 +msgid "Vacuum cost delay in milliseconds, for autovacuum." +msgstr "对于autovacuumæ¥è¯´,Vacuum开销延迟是以毫秒为å•ä½" + +#: utils/misc/guc.c:3399 +msgid "Number of tuple updates or deletes prior to vacuum as a fraction of reltuples." msgstr "在清ç†å‰éœ€è¦æ’å…¥,删除或更新元组的数é‡ï¼Œè¿™ä¸ªæ•°é‡æ˜¯ä½œä¸ºè¡¨å¤§å°çš„百分比" -#: utils/misc/guc.c:2952 -msgid "" -"Number of tuple inserts, updates, or deletes prior to analyze as a fraction " -"of reltuples." +#: utils/misc/guc.c:3408 +msgid "Number of tuple inserts, updates, or deletes prior to analyze as a fraction of reltuples." msgstr "在分æžå‰æ’å…¥,更新或删除元组的数é‡ï¼Œè¿™ä¸ªæ•°é‡ä»¥è¡¨å¤§å°çš„百分比的形å¼å‡ºçް" -#: utils/misc/guc.c:2962 -msgid "" -"Time spent flushing dirty buffers during checkpoint, as fraction of " -"checkpoint interval." +#: utils/misc/guc.c:3418 +msgid "Time spent flushing dirty buffers during checkpoint, as fraction of checkpoint interval." +msgstr "在检查点事件期间花费在将缓冲区中è„页刷新到ç£ç›˜çš„æ—¶é—´ï¼Œ 这个时间作为检查点间隔的百分比。" + +#: utils/misc/guc.c:3428 +msgid "Number of tuple inserts prior to index cleanup as a fraction of reltuples." +msgstr "在索引清ç†ä¹‹å‰ä½œä¸ºå…ƒç»„的一部分æ’入的元组数." + +#: utils/misc/guc.c:3438 +msgid "Fraction of statements exceeding log_min_duration_statement to be logged." +msgstr "" + +#: utils/misc/guc.c:3439 +msgid "If you only want a sample, use a value between 0.0 (never log) and 1.0 (always log)." +msgstr "" + +#: utils/misc/guc.c:3449 +#, fuzzy +#| msgid "Sets the transaction isolation level of each new transaction." +msgid "Set the fraction of transactions to log for new transactions." +msgstr "设置æ¯ä¸€ä¸ªæ–°äº‹ç‰©çš„隔离 (isolation) 级别." + +#: utils/misc/guc.c:3450 +msgid "Logs all statements from a fraction of transactions. Use a value between 0.0 (never log) and 1.0 (log all statements for all transactions)." msgstr "" -"在检查点事件期间花费在将缓冲区中è„页刷新到ç£ç›˜çš„æ—¶é—´ï¼Œ 这个时间作为检查点间隔" -"的百分比。" -#: utils/misc/guc.c:2981 +#: utils/misc/guc.c:3470 msgid "Sets the shell command that will be called to archive a WAL file." msgstr "设置用于对WAL文件进行归档的shell命令" -#: utils/misc/guc.c:2991 +#: utils/misc/guc.c:3480 +#, fuzzy +#| msgid "Sets the shell command that will be called to archive a WAL file." +msgid "Sets the shell command that will retrieve an archived WAL file." +msgstr "设置用于对WAL文件进行归档的shell命令" + +#: utils/misc/guc.c:3490 +#, fuzzy +#| msgid "Sets the shell command that will be called to archive a WAL file." +msgid "Sets the shell command that will be executed at every restart point." +msgstr "设置用于对WAL文件进行归档的shell命令" + +#: utils/misc/guc.c:3500 +#, fuzzy +#| msgid "Sets the shell command that will be called to archive a WAL file." +msgid "Sets the shell command that will be executed once at the end of recovery." +msgstr "设置用于对WAL文件进行归档的shell命令" + +#: utils/misc/guc.c:3510 +msgid "Specifies the timeline to recovery into." +msgstr "" + +#: utils/misc/guc.c:3520 +msgid "Set to 'immediate' to end recovery as soon as a consistent state is reached." +msgstr "" + +#: utils/misc/guc.c:3529 +msgid "Sets the transaction ID up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3538 +msgid "Sets the time stamp up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3547 +msgid "Sets the named restore point up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3556 +msgid "Sets the LSN of the write-ahead log location up to which recovery will proceed." +msgstr "" + +#: utils/misc/guc.c:3566 +msgid "Specifies a file name whose presence ends recovery in the standby." +msgstr "" + +#: utils/misc/guc.c:3576 +msgid "Sets the connection string to be used to connect to the sending server." +msgstr "" + +#: utils/misc/guc.c:3587 +#, fuzzy +#| msgid "Sets the number of connection slots reserved for superusers." +msgid "Sets the name of the replication slot to use on the sending server." +msgstr "设置为超级用户ä¿ç•™çš„è”æŽ¥æ•°." + +#: utils/misc/guc.c:3597 msgid "Sets the client's character set encoding." msgstr "设置客户端编ç " -#: utils/misc/guc.c:3002 +#: utils/misc/guc.c:3608 msgid "Controls information prefixed to each log line." msgstr "将控制信æ¯ä½œä¸ºæ¯æ¡æ—¥å¿—文本的å‰ç¼€" -#: utils/misc/guc.c:3003 +#: utils/misc/guc.c:3609 msgid "If blank, no prefix is used." msgstr "如果是空的,那么ä¸ä½¿ç”¨å‰ç¼€" -#: utils/misc/guc.c:3012 +#: utils/misc/guc.c:3618 msgid "Sets the time zone to use in log messages." msgstr "设置在日志消æ¯ä¸­ä½¿ç”¨çš„æ—¶é—´åŒºåŸŸ" -#: utils/misc/guc.c:3022 +#: utils/misc/guc.c:3628 msgid "Sets the display format for date and time values." msgstr "设置日期和时间值的显示格å¼." -#: utils/misc/guc.c:3023 +#: utils/misc/guc.c:3629 msgid "Also controls interpretation of ambiguous date inputs." msgstr "控制对模糊日期输入的解释." -#: utils/misc/guc.c:3034 +#: utils/misc/guc.c:3640 +#, fuzzy +#| msgid "Sets the default tablespace to create tables and indexes in." +msgid "Sets the default table access method for new tables." +msgstr "设置用于创建表和索引的缺çœè¡¨ç©ºé—´." + +#: utils/misc/guc.c:3651 msgid "Sets the default tablespace to create tables and indexes in." msgstr "设置用于创建表和索引的缺çœè¡¨ç©ºé—´." -#: utils/misc/guc.c:3035 +#: utils/misc/guc.c:3652 msgid "An empty string selects the database's default tablespace." msgstr "使用空字符串表示数æ®åº“的缺çœè¡¨ç©ºé—´." -#: utils/misc/guc.c:3045 +#: utils/misc/guc.c:3662 msgid "Sets the tablespace(s) to use for temporary tables and sort files." msgstr "å°†è¡¨ç©ºé—´è®¾ç½®ä¸ºç”¨äºŽå­˜æ”¾ä¸´æ—¶è¡¨å’ŒæŽ’åºæ–‡ä»¶" -#: utils/misc/guc.c:3056 +#: utils/misc/guc.c:3673 msgid "Sets the path for dynamically loadable modules." msgstr "设置动æ€åŠ è½½æ‘¸ç»„çš„è·¯å¾„." -#: utils/misc/guc.c:3057 -msgid "" -"If a dynamically loadable module needs to be opened and the specified name " -"does not have a directory component (i.e., the name does not contain a " -"slash), the system will search this path for the specified file." -msgstr "" -"如果一个动æ€åŠ è½½æ¨¡å—éœ€è¦æ‰“开并且指定å字没有路径 (例如, åå­—ä¸­æ²¡åŒ…å«æ–œæ ), ç³»" -"统将在此路径中查找指定的文件." +#: utils/misc/guc.c:3674 +msgid "If a dynamically loadable module needs to be opened and the specified name does not have a directory component (i.e., the name does not contain a slash), the system will search this path for the specified file." +msgstr "如果一个动æ€åŠ è½½æ¨¡å—éœ€è¦æ‰“开并且指定å字没有路径 (例如, åå­—ä¸­æ²¡åŒ…å«æ–œæ ), 系统将在此路径中查找指定的文件." -#: utils/misc/guc.c:3070 +#: utils/misc/guc.c:3687 msgid "Sets the location of the Kerberos server key file." msgstr "设置 Kerberos æœåŠ¡å™¨å¯†é’¥æ–‡ä»¶ä½ç½®." -#: utils/misc/guc.c:3081 +#: utils/misc/guc.c:3698 msgid "Sets the Bonjour service name." msgstr "设置BonjouræœåŠ¡åç§°." -#: utils/misc/guc.c:3093 +#: utils/misc/guc.c:3710 msgid "Shows the collation order locale." msgstr "显示排åºè§„则顺åºçš„语言环境" -#: utils/misc/guc.c:3104 +#: utils/misc/guc.c:3721 msgid "Shows the character classification and case conversion locale." msgstr "显示字符分类和按æ¡ä»¶è½¬æ¢çš„语言环境." -#: utils/misc/guc.c:3115 +#: utils/misc/guc.c:3732 msgid "Sets the language in which messages are displayed." msgstr "è®¾ç½®ä¿¡æ¯æ˜¾ç¤ºè¯­è¨€." -#: utils/misc/guc.c:3125 +#: utils/misc/guc.c:3742 msgid "Sets the locale for formatting monetary amounts." msgstr "ä¸ºè´§å¸æ•°é‡æ ¼å¼è®¾ç½® locale." -#: utils/misc/guc.c:3135 +#: utils/misc/guc.c:3752 msgid "Sets the locale for formatting numbers." msgstr "为数字格å¼è®¾ç½® locale" -#: utils/misc/guc.c:3145 +#: utils/misc/guc.c:3762 msgid "Sets the locale for formatting date and time values." msgstr "为日期和时间值格å¼è®¾ç½® locale" -#: utils/misc/guc.c:3155 +#: utils/misc/guc.c:3772 msgid "Lists shared libraries to preload into each backend." msgstr "列出预先加载到æ¯ä¸ªåŽå°è¿›ç¨‹çš„共享库." -#: utils/misc/guc.c:3166 +#: utils/misc/guc.c:3783 msgid "Lists shared libraries to preload into server." msgstr "列出预装入æœåŠ¡å™¨çš„å…±äº«åº“." -#: utils/misc/guc.c:3177 +#: utils/misc/guc.c:3794 msgid "Lists unprivileged shared libraries to preload into each backend." msgstr "列出预先加载到æ¯ä¸ªåŽå°è¿›ç¨‹çš„éžä¼˜å…ˆçš„共享库." -#: utils/misc/guc.c:3188 +#: utils/misc/guc.c:3805 msgid "Sets the schema search order for names that are not schema-qualified." msgstr "ä¸ºä¸æ˜¯æ¨¡å¼é™å®šçš„åç§°è®¾ç½®æ¨¡å¼æœç´¢é¡ºåº" -#: utils/misc/guc.c:3200 +#: utils/misc/guc.c:3817 msgid "Sets the server (database) character set encoding." msgstr "设置æœåС噍 (æ•°æ®åº“) 字符编ç ." -#: utils/misc/guc.c:3212 +#: utils/misc/guc.c:3829 msgid "Shows the server version." msgstr "显示æœåŠ¡å™¨ç‰ˆæœ¬ä¿¡æ¯." -#: utils/misc/guc.c:3224 +#: utils/misc/guc.c:3841 msgid "Sets the current role." msgstr "设置当å‰çš„角色" -#: utils/misc/guc.c:3236 +#: utils/misc/guc.c:3853 msgid "Sets the session user name." msgstr "设置会è¯ç”¨æˆ·åç§°." -#: utils/misc/guc.c:3247 +#: utils/misc/guc.c:3864 msgid "Sets the destination for server log output." msgstr "设置æœåŠ¡å™¨æ—¥å¿—è¾“å‡ºç›®æ ‡." -#: utils/misc/guc.c:3248 -msgid "" -"Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and " -"\"eventlog\", depending on the platform." -msgstr "" -"有效值为 \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\" 的组åˆ, è¿™å–决" -"于平å°çš„ç§ç±»." +#: utils/misc/guc.c:3865 +msgid "Valid values are combinations of \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\", depending on the platform." +msgstr "有效值为 \"stderr\", \"syslog\", \"csvlog\", and \"eventlog\" 的组åˆ, è¿™å–决于平å°çš„ç§ç±»." -#: utils/misc/guc.c:3259 +#: utils/misc/guc.c:3876 msgid "Sets the destination directory for log files." msgstr "设置日志文件目的目录." -#: utils/misc/guc.c:3260 +#: utils/misc/guc.c:3877 msgid "Can be specified as relative to the data directory or as absolute path." msgstr "å¯ä»¥æŒ‡å®šä¸ºdata目录的相对目录或ç»å¯¹ç›®å½•." -#: utils/misc/guc.c:3270 +#: utils/misc/guc.c:3887 msgid "Sets the file name pattern for log files." msgstr "设置日志文件的文件å字模å¼." -#: utils/misc/guc.c:3281 +#: utils/misc/guc.c:3898 msgid "Sets the program name used to identify PostgreSQL messages in syslog." msgstr "设置在系统日志 (syslog) 中确认 PostgreSQL ä¿¡æ¯çš„程åºå." -#: utils/misc/guc.c:3292 -msgid "" -"Sets the application name used to identify PostgreSQL messages in the event " -"log." +#: utils/misc/guc.c:3909 +msgid "Sets the application name used to identify PostgreSQL messages in the event log." msgstr "设置在事件日志 (syslog) 中用于标识 PostgreSQL 消æ¯çš„程åºå." -#: utils/misc/guc.c:3303 +#: utils/misc/guc.c:3920 msgid "Sets the time zone for displaying and interpreting time stamps." msgstr "设置显示和解释时间戳的时区." -#: utils/misc/guc.c:3313 +#: utils/misc/guc.c:3930 msgid "Selects a file of time zone abbreviations." msgstr "选择时间区域缩写的文件" -#: utils/misc/guc.c:3323 -msgid "Sets the current transaction's isolation level." -msgstr "设置当å‰äº‹ç‰©çš„隔离级别." - -#: utils/misc/guc.c:3334 +#: utils/misc/guc.c:3940 msgid "Sets the owning group of the Unix-domain socket." msgstr "设置 Unix-domain 套接字的属组." -#: utils/misc/guc.c:3335 -msgid "" -"The owning user of the socket is always the user that starts the server." +#: utils/misc/guc.c:3941 +msgid "The owning user of the socket is always the user that starts the server." msgstr "套接字的属主用户也是起动æœåŠ¡çš„ç”¨æˆ·." -#: utils/misc/guc.c:3345 +#: utils/misc/guc.c:3951 msgid "Sets the directories where Unix-domain sockets will be created." msgstr "设置用于创建Unix-domain套接字的目录." -#: utils/misc/guc.c:3360 +#: utils/misc/guc.c:3966 msgid "Sets the host name or IP address(es) to listen to." msgstr "设置监å¬çš„ä¸»æœºåæˆ– IP 地å€." -#: utils/misc/guc.c:3375 +#: utils/misc/guc.c:3981 msgid "Sets the server's data directory." msgstr "设置æœåŠ¡å™¨çš„æ•°æ®ç›®å½•" -#: utils/misc/guc.c:3386 +#: utils/misc/guc.c:3992 msgid "Sets the server's main configuration file." msgstr "设置æœåŠ¡å™¨çš„ä¸»é…置文件" -#: utils/misc/guc.c:3397 +#: utils/misc/guc.c:4003 msgid "Sets the server's \"hba\" configuration file." msgstr "设置æœåŠ¡å™¨çš„ \"hba\" é…置文件" -#: utils/misc/guc.c:3408 +#: utils/misc/guc.c:4014 msgid "Sets the server's \"ident\" configuration file." msgstr "设置æœåŠ¡å™¨çš„ \"ident\" é…置文件" -#: utils/misc/guc.c:3419 +#: utils/misc/guc.c:4025 msgid "Writes the postmaster PID to the specified file." msgstr "把 postmaster PID 写到指定文件." -#: utils/misc/guc.c:3430 +#: utils/misc/guc.c:4036 +msgid "Name of the SSL library." +msgstr "" + +#: utils/misc/guc.c:4051 msgid "Location of the SSL server certificate file." msgstr "SSLæœåС噍è¯ä¹¦æ–‡ä»¶çš„ä½ç½®" -#: utils/misc/guc.c:3440 +#: utils/misc/guc.c:4061 msgid "Location of the SSL server private key file." msgstr "SSLæœåС噍ç§é’¥æ–‡ä»¶çš„ä½ç½®." -#: utils/misc/guc.c:3450 +#: utils/misc/guc.c:4071 msgid "Location of the SSL certificate authority file." msgstr "SSLè¯ä¹¦æŽˆæƒæ–‡ä»¶çš„ä½ç½®." -#: utils/misc/guc.c:3460 +#: utils/misc/guc.c:4081 msgid "Location of the SSL certificate revocation list file." msgstr "SSLè¯ä¹¦æ’¤é”€åˆ—表文件的ä½ç½®." -#: utils/misc/guc.c:3470 +#: utils/misc/guc.c:4091 msgid "Writes temporary statistics files to the specified directory." msgstr "å°†ä¸´æ—¶ç»Ÿè®¡ä¿¡æ¯æ–‡ä»¶å†™åˆ°æŒ‡å®šçš„目录" -#: utils/misc/guc.c:3481 -#| msgid "List of names of potential synchronous standbys." -msgid "" -"Number of synchronous standbys and list of names of potential synchronous " -"ones." +#: utils/misc/guc.c:4102 +msgid "Number of synchronous standbys and list of names of potential synchronous ones." msgstr "åŒæ­¥åŽå¤‡çš„æ•°é‡ä»¥åŠæ½œåœ¨çš„åŒæ­¥åŽå¤‡çš„å称列表。" # describe.c:97 -#: utils/misc/guc.c:3492 +#: utils/misc/guc.c:4113 msgid "Sets default text search configuration." msgstr "è®¾ç½®ç¼ºçœæ–‡æœ¬æœç´¢é…ç½®" -#: utils/misc/guc.c:3502 +#: utils/misc/guc.c:4123 msgid "Sets the list of allowed SSL ciphers." msgstr "设置日志信æ¯çš„冗长." -#: utils/misc/guc.c:3517 +#: utils/misc/guc.c:4138 msgid "Sets the curve to use for ECDH." msgstr "设置该曲线,用于ECDH." -#: utils/misc/guc.c:3532 +#: utils/misc/guc.c:4153 +msgid "Location of the SSL DH parameters file." +msgstr "SSL DH傿•°æ–‡ä»¶çš„ä½ç½®." + +#: utils/misc/guc.c:4164 +msgid "Command to obtain passphrases for SSL." +msgstr "获å–SSL密ç çš„命令" + +#: utils/misc/guc.c:4174 msgid "Sets the application name to be reported in statistics and logs." msgstr "设置在统计和日志中出现的应用程åºåç§°." -#: utils/misc/guc.c:3543 +#: utils/misc/guc.c:4185 msgid "Sets the name of the cluster, which is included in the process title." msgstr "设定集簇的å称,它会被包括在进程的标题中。" -#: utils/misc/guc.c:3563 +#: utils/misc/guc.c:4196 +msgid "Sets the WAL resource managers for which WAL consistency checks are done." +msgstr "设置对其进行WAL一致性检查的WAL资æºç®¡ç†å™¨" + +#: utils/misc/guc.c:4197 +msgid "Full-page images will be logged for all data blocks and cross-checked against the results of WAL replay." +msgstr "将记录所有数æ®å—的整页图åƒï¼Œå¹¶å¯¹ç…§WAL釿”¾ç»“æžœè¿›è¡Œäº¤å‰æ£€æŸ¥." + +#: utils/misc/guc.c:4207 +msgid "JIT provider to use." +msgstr "è¦ä½¿ç”¨çš„JITæä¾›ç¨‹åº." + +#: utils/misc/guc.c:4227 msgid "Sets whether \"\\'\" is allowed in string literals." msgstr "在字符串常é‡ä¸­è®¾ç½®æ˜¯å¦å…许使用\"\\'\"" -#: utils/misc/guc.c:3573 +#: utils/misc/guc.c:4237 msgid "Sets the output format for bytea." msgstr "设置bytea类型数æ®çš„输出格å¼" -#: utils/misc/guc.c:3583 +#: utils/misc/guc.c:4247 msgid "Sets the message levels that are sent to the client." msgstr "设置å‘é€åˆ°å®¢æˆ·ç«¯çš„ä¿¡æ¯çº§åˆ«." -#: utils/misc/guc.c:3584 utils/misc/guc.c:3637 utils/misc/guc.c:3648 -#: utils/misc/guc.c:3714 -msgid "" -"Each level includes all the levels that follow it. The later the level, the " -"fewer messages are sent." +#: utils/misc/guc.c:4248 utils/misc/guc.c:4313 utils/misc/guc.c:4324 +#: utils/misc/guc.c:4400 +msgid "Each level includes all the levels that follow it. The later the level, the fewer messages are sent." msgstr "æ¯ä¸€å±‚都包å«åœ¨è¿™ä¸€å±‚åŽé¢çš„层次, 对于越往åŽçš„层次,就会å‘é€è¶Šå°‘的消æ¯." -#: utils/misc/guc.c:3594 +#: utils/misc/guc.c:4258 msgid "Enables the planner to use constraints to optimize queries." msgstr "使计划器å¯ä»¥ä½¿ç”¨çº¦æŸæ¥ä¼˜åŒ–查询." -#: utils/misc/guc.c:3595 -msgid "" -"Table scans will be skipped if their constraints guarantee that no rows " -"match the query." +#: utils/misc/guc.c:4259 +msgid "Table scans will be skipped if their constraints guarantee that no rows match the query." msgstr "如果约æŸèƒ½å¤Ÿç¡®ä¿æ²¡æœ‰åˆ—ç¬¦åˆæŸ¥è¯¢æ¡ä»¶ï¼Œé‚£ä¹ˆå°†è·³è¿‡è¡¨æ‰«æ." -#: utils/misc/guc.c:3605 +#: utils/misc/guc.c:4270 msgid "Sets the transaction isolation level of each new transaction." msgstr "设置æ¯ä¸€ä¸ªæ–°äº‹ç‰©çš„隔离 (isolation) 级别." -#: utils/misc/guc.c:3615 +#: utils/misc/guc.c:4280 +msgid "Sets the current transaction's isolation level." +msgstr "设置当å‰äº‹ç‰©çš„隔离级别." + +#: utils/misc/guc.c:4291 msgid "Sets the display format for interval values." msgstr "设置时间间隔值的显示格å¼." -#: utils/misc/guc.c:3626 +#: utils/misc/guc.c:4302 msgid "Sets the verbosity of logged messages." msgstr "设置日志信æ¯çš„冗长." -#: utils/misc/guc.c:3636 +#: utils/misc/guc.c:4312 msgid "Sets the message levels that are logged." msgstr "设置日志记录的信æ¯çº§åˆ«." -#: utils/misc/guc.c:3647 -msgid "" -"Causes all statements generating error at or above this level to be logged." +#: utils/misc/guc.c:4323 +msgid "Causes all statements generating error at or above this level to be logged." msgstr "在此级别或以上级别, 所有语å¥äº§ç”Ÿçš„错误将被记录." -#: utils/misc/guc.c:3658 +#: utils/misc/guc.c:4334 msgid "Sets the type of statements logged." msgstr "设置记录语å¥çš„类型." -#: utils/misc/guc.c:3668 +#: utils/misc/guc.c:4344 msgid "Sets the syslog \"facility\" to be used when syslog enabled." msgstr "当å¯ç”¨ç³»ç»Ÿæ—¥å¿— (syslog), 设置系统日志使用 \"facility\"." -#: utils/misc/guc.c:3683 +#: utils/misc/guc.c:4359 msgid "Sets the session's behavior for triggers and rewrite rules." msgstr "为触å‘器和é‡å†™è§„则设置会è¯çš„行为" -#: utils/misc/guc.c:3693 +#: utils/misc/guc.c:4369 msgid "Sets the current transaction's synchronization level." msgstr "设置当å‰äº‹ç‰©çš„åŒæ­¥çº§åˆ«." -#: utils/misc/guc.c:3703 +#: utils/misc/guc.c:4379 msgid "Allows archiving of WAL files using archive_command." msgstr "å…许使用archive_command傿•°å¯¹WAL文件进行归档." -#: utils/misc/guc.c:3713 +#: utils/misc/guc.c:4389 +msgid "Sets the action to perform upon reaching the recovery target." +msgstr "" + +#: utils/misc/guc.c:4399 msgid "Enables logging of recovery-related debugging information." msgstr "å¯ç”¨æ—¥å¿—功能,对与æ¢å¤æ“作相关的调试信æ¯è¿›è¡Œè®°å½•." -#: utils/misc/guc.c:3729 +#: utils/misc/guc.c:4415 msgid "Collects function-level statistics on database activity." msgstr "在数æ®åº“è¿è¡Œçš„事务中收集函数级别统计信æ¯." -#: utils/misc/guc.c:3739 +#: utils/misc/guc.c:4425 msgid "Set the level of information written to the WAL." msgstr "设置写入WAL文件的信æ¯çš„内容详细级别" -#: utils/misc/guc.c:3749 +#: utils/misc/guc.c:4435 msgid "Selects the dynamic shared memory implementation used." msgstr "选择过去的动æ€å…±äº«å†…存实现." -#: utils/misc/guc.c:3759 +#: utils/misc/guc.c:4445 +#, fuzzy +#| msgid "Selects the dynamic shared memory implementation used." +msgid "Selects the shared memory implementation used for the main shared memory region." +msgstr "选择过去的动æ€å…±äº«å†…存实现." + +#: utils/misc/guc.c:4455 msgid "Selects the method used for forcing WAL updates to disk." msgstr "选择用于强制将WAL缓冲区的内容更新到ç£ç›˜çš„æ–¹æ³•." -#: utils/misc/guc.c:3769 +#: utils/misc/guc.c:4465 msgid "Sets how binary values are to be encoded in XML." msgstr "设置在XML中如何对二进制的值进行编ç ." -#: utils/misc/guc.c:3779 -msgid "" -"Sets whether XML data in implicit parsing and serialization operations is to " -"be considered as documents or content fragments." +#: utils/misc/guc.c:4475 +msgid "Sets whether XML data in implicit parsing and serialization operations is to be considered as documents or content fragments." msgstr "设置在éšå¼åˆ†æžå’Œä¸²è¡Œæ“作中的XMLæ•°æ®æ˜¯å¦è¢«å½“作文档或者内容片断." -#: utils/misc/guc.c:3790 -msgid "Use of huge pages on Linux." -msgstr "使用Linux上的超大(huge)页" +#: utils/misc/guc.c:4486 +msgid "Use of huge pages on Linux or Windows." +msgstr "在Linux或Windows上使用大页é¢." -#: utils/misc/guc.c:3800 +#: utils/misc/guc.c:4496 msgid "Forces use of parallel query facilities." msgstr "强制使用并行查询功能。" -#: utils/misc/guc.c:3801 -msgid "" -"If possible, run query using a parallel worker and with parallel " -"restrictions." +#: utils/misc/guc.c:4497 +msgid "If possible, run query using a parallel worker and with parallel restrictions." msgstr "如果å¯èƒ½ï¼Œä½¿ç”¨ä¸€ä¸ªå¹¶è¡Œå·¥ä½œè€…并且加上并行é™åˆ¶æ¥è¿è¡ŒæŸ¥è¯¢ã€‚" -#: utils/misc/guc.c:4601 +#: utils/misc/guc.c:4507 +msgid "Encrypt passwords." +msgstr "加密å£ä»¤." + +#: utils/misc/guc.c:4508 +msgid "When a password is specified in CREATE USER or ALTER USER without writing either ENCRYPTED or UNENCRYPTED, this parameter determines whether the password is to be encrypted." +msgstr "当在 CREATE USER 或者 ALTER USER 语å¥ä¸­æŒ‡å®šçš„å£ä»¤æ²¡æœ‰ç”¨ ENCRYPTED 或者 UNENCRYPTED, æ­¤å‚æ•°ç¡®å®šå£ä»¤æ˜¯å¦åР坆." + +#: utils/misc/guc.c:4519 +#, fuzzy +#| msgid "Enables the planner's use of merge join plans." +msgid "Controls the planner's selection of custom or generic plan." +msgstr "å¯ç”¨æŸ¥è¯¢è®¡åˆ’器的åˆå¹¶è¿žæŽ¥è®¡åˆ’." + +#: utils/misc/guc.c:4520 +msgid "Prepared statements can have custom and generic plans, and the planner will attempt to choose which is better. This can be set to override the default behavior." +msgstr "" + +#: utils/misc/guc.c:4532 +#, fuzzy +#| msgid "Sets the minimum size to shrink the WAL to." +msgid "Sets the minimum SSL/TLS protocol version to use." +msgstr "è®¾ç½®è¦æŠŠWAL收缩到的最å°å°ºå¯¸ã€‚" + +#: utils/misc/guc.c:4544 +msgid "Sets the maximum SSL/TLS protocol version to use." +msgstr "" + +#: utils/misc/guc.c:5367 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: 无法访问目录 \"%s\": %s\n" -#: utils/misc/guc.c:4606 +#: utils/misc/guc.c:5372 #, c-format -#| msgid "" -#| "%s initializes a PostgreSQL database cluster.\n" -#| "\n" -msgid "" -"Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" +msgid "Run initdb or pg_basebackup to initialize a PostgreSQL data directory.\n" msgstr "è¿è¡Œ initdb 或者 pg_basebackup 以åˆå§‹åŒ–一个 PostgreSQL æ•°æ®ç›®å½•.\n" -#: utils/misc/guc.c:4626 +#: utils/misc/guc.c:5392 #, c-format msgid "" "%s does not know where to find the server configuration file.\n" -"You must specify the --config-file or -D invocation option or set the PGDATA " -"environment variable.\n" +"You must specify the --config-file or -D invocation option or set the PGDATA environment variable.\n" msgstr "" "%s ä¸çŸ¥é“在哪里å¯ä»¥æ‰¾åˆ°æ•°æ®åº“系统é…置文件.\n" "你必须通过 --config-file 或 -D 选项指定或者通过设置 PGDATA 环境å˜é‡.\n" -#: utils/misc/guc.c:4645 +#: utils/misc/guc.c:5411 #, c-format -#| msgid "%s cannot access the server configuration file \"%s\": %s\n" msgid "%s: could not access the server configuration file \"%s\": %s\n" msgstr "%s:无法访问æœåС噍é…置文件 \"%s\": %s\n" -#: utils/misc/guc.c:4671 +#: utils/misc/guc.c:5437 #, c-format msgid "" "%s does not know where to find the database system data.\n" -"This can be specified as \"data_directory\" in \"%s\", or by the -D " -"invocation option, or by the PGDATA environment variable.\n" +"This can be specified as \"data_directory\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" msgstr "" "%s ä¸çŸ¥é“在哪里å¯ä»¥æ‰¾åˆ°æ•°æ®åº“系统数æ®.\n" -"å¯ä»¥åœ¨ \"%s\" 中指定 \"data_directory\", 或者通过 -D 选项指定或者通过设置 " -"PGDATA 环境å˜é‡.\n" +"å¯ä»¥åœ¨ \"%s\" 中指定 \"data_directory\", 或者通过 -D 选项指定或者通过设置 PGDATA 环境å˜é‡.\n" -#: utils/misc/guc.c:4719 +#: utils/misc/guc.c:5485 #, c-format msgid "" "%s does not know where to find the \"hba\" configuration file.\n" -"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation " -"option, or by the PGDATA environment variable.\n" +"This can be specified as \"hba_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" msgstr "" "%s ä¸çŸ¥é“在哪里å¯ä»¥æ‰¾åˆ° \"hba\" é…置文件.\n" -"å¯ä»¥åœ¨ \"%s\" 中指定 \"hba_file\", 或者通过 -D 选项指定或者通过设置PGDATA 环" -"境å˜é‡.\n" +"å¯ä»¥åœ¨ \"%s\" 中指定 \"hba_file\", 或者通过 -D 选项指定或者通过设置PGDATA 环境å˜é‡.\n" -#: utils/misc/guc.c:4742 +#: utils/misc/guc.c:5508 #, c-format msgid "" "%s does not know where to find the \"ident\" configuration file.\n" -"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation " -"option, or by the PGDATA environment variable.\n" +"This can be specified as \"ident_file\" in \"%s\", or by the -D invocation option, or by the PGDATA environment variable.\n" msgstr "" "%s ä¸çŸ¥é“在哪里å¯ä»¥æ‰¾åˆ° \"ident\" é…置文件.\n" -"å¯ä»¥åœ¨ \"%s\" 中指定 \"ident_file\", 或者通过 -D 选项指定或者通过设置PGDATA " -"环境å˜é‡.\n" +"å¯ä»¥åœ¨ \"%s\" 中指定 \"ident_file\", 或者通过 -D 选项指定或者通过设置PGDATA 环境å˜é‡.\n" -#: utils/misc/guc.c:5416 utils/misc/guc.c:5463 +#: utils/misc/guc.c:6350 msgid "Value exceeds integer range." msgstr "值已超过整数范围" -#: utils/misc/guc.c:5686 -#, c-format -msgid "parameter \"%s\" requires a numeric value" -msgstr "傿•° \"%s\" 需è¦ä¸€ä¸ªæ•°å­—值" +#: utils/misc/guc.c:6586 +#, fuzzy, c-format +#| msgid "%d is outside the valid range for parameter \"%s\" (%d .. %d)" +msgid "%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)" +msgstr "%d è¶…å‡ºäº†å‚æ•° \"%s\" (%d .. %d) 的有效范围" -#: utils/misc/guc.c:5695 -#, c-format -msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" +#: utils/misc/guc.c:6622 +#, fuzzy, c-format +#| msgid "%g is outside the valid range for parameter \"%s\" (%g .. %g)" +msgid "%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)" msgstr "%g è¶…å‡ºäº†å‚æ•° \"%s\" (%g .. %g) 的有效范围" -#: utils/misc/guc.c:5848 utils/misc/guc.c:7190 +#: utils/misc/guc.c:6778 utils/misc/guc.c:8148 #, c-format msgid "cannot set parameters during a parallel operation" msgstr "在并行æ“作期间ä¸èƒ½è®¾ç½®å‚æ•°" -#: utils/misc/guc.c:5855 utils/misc/guc.c:6605 utils/misc/guc.c:6657 -#: utils/misc/guc.c:7018 utils/misc/guc.c:7778 utils/misc/guc.c:7946 -#: utils/misc/guc.c:9603 +#: utils/misc/guc.c:6785 utils/misc/guc.c:7537 utils/misc/guc.c:7590 +#: utils/misc/guc.c:7641 utils/misc/guc.c:7977 utils/misc/guc.c:8744 +#: utils/misc/guc.c:9010 utils/misc/guc.c:10648 #, c-format msgid "unrecognized configuration parameter \"%s\"" msgstr "未认å¯çš„é…ç½®å‚æ•° \"%s\"" -#: utils/misc/guc.c:5870 utils/misc/guc.c:7030 +#: utils/misc/guc.c:6800 utils/misc/guc.c:7989 #, c-format msgid "parameter \"%s\" cannot be changed" msgstr "傿•° \"%s\" ä¸å¯ä»¥æ”¹å˜" -#: utils/misc/guc.c:5903 +#: utils/misc/guc.c:6823 utils/misc/guc.c:7017 utils/misc/guc.c:7107 +#: utils/misc/guc.c:7197 utils/misc/guc.c:7305 utils/misc/guc.c:7400 +#: guc-file.l:353 +#, c-format +msgid "parameter \"%s\" cannot be changed without restarting the server" +msgstr "在没有å¯åЍæœåŠ¡å™¨çš„æƒ…å†µä¸‹ï¼Œä¸èƒ½æ”¹å˜å‚æ•° \"%s\" " + +#: utils/misc/guc.c:6833 #, c-format msgid "parameter \"%s\" cannot be changed now" msgstr "傿•° \"%s\" 现在ä¸èƒ½æ”¹å˜" -#: utils/misc/guc.c:5921 utils/misc/guc.c:5966 utils/misc/guc.c:9619 +#: utils/misc/guc.c:6851 utils/misc/guc.c:6898 utils/misc/guc.c:10664 #, c-format msgid "permission denied to set parameter \"%s\"" msgstr "è®¾ç½®å‚æ•° \"%s\" æƒé™ä¸å…许" -#: utils/misc/guc.c:5956 +#: utils/misc/guc.c:6888 #, c-format msgid "parameter \"%s\" cannot be set after connection start" msgstr "è”æŽ¥å¯åЍåŽ, 傿•° \"%s\" ä¸èƒ½è®¾ç½®" -#: utils/misc/guc.c:6004 +#: utils/misc/guc.c:6936 #, c-format msgid "cannot set parameter \"%s\" within security-definer function" msgstr "无法在安全定义者æ“ä½œä¸­è®¾ç½®å‚æ•°\"%s\" " -#: utils/misc/guc.c:6613 utils/misc/guc.c:6661 utils/misc/guc.c:7952 +#: utils/misc/guc.c:7545 utils/misc/guc.c:7595 utils/misc/guc.c:9017 #, c-format -msgid "must be superuser to examine \"%s\"" -msgstr "检查 \"%s\" 必须为超级用户" +msgid "must be superuser or a member of pg_read_all_settings to examine \"%s\"" +msgstr "必须是超级用户或pg_read_all_settingsçš„æˆå‘˜æ‰èƒ½æ£€æŸ¥\"%s\"" -#: utils/misc/guc.c:6727 +#: utils/misc/guc.c:7686 #, c-format msgid "SET %s takes only one argument" msgstr "SET %s åªèƒ½å¸¦ä¸€ä¸ªå‚æ•°" -#: utils/misc/guc.c:6978 +#: utils/misc/guc.c:7937 #, c-format msgid "must be superuser to execute ALTER SYSTEM command" msgstr "åªæœ‰è¶…级用户æ‰èƒ½æ‰§è¡Œå‘½ä»¤ALTER SYSTEM" -#: utils/misc/guc.c:7063 +#: utils/misc/guc.c:8022 #, c-format msgid "parameter value for ALTER SYSTEM must not contain a newline" msgstr "用于 ALTER SYSTEM çš„å‚æ•°å€¼ä¸èƒ½åŒ…嫿–°è¡Œ" -#: utils/misc/guc.c:7108 +#: utils/misc/guc.c:8067 #, c-format msgid "could not parse contents of file \"%s\"" msgstr "æ— æ³•è§£æžæ–‡ä»¶\"%s\"的内容" -#: utils/misc/guc.c:7266 +#: utils/misc/guc.c:8224 #, c-format msgid "SET LOCAL TRANSACTION SNAPSHOT is not implemented" msgstr "SET LOCAL TRANSACTION SNAPSHOT没有实现" -#: utils/misc/guc.c:7351 +#: utils/misc/guc.c:8308 #, c-format msgid "SET requires parameter name" msgstr "SET 需è¦å‚æ•°åå­—" -#: utils/misc/guc.c:7475 +#: utils/misc/guc.c:8441 #, c-format msgid "attempt to redefine parameter \"%s\"" msgstr "å°è¯•釿–°å®šä¹‰å‚æ•° \"%s\"" -#: utils/misc/guc.c:9236 +#: utils/misc/guc.c:10281 #, c-format msgid "parameter \"%s\" could not be set" msgstr "傿•°\"%s\" ä¸èƒ½è¢«è®¾ç½®" -#: utils/misc/guc.c:9323 +#: utils/misc/guc.c:10368 #, c-format msgid "could not parse setting for parameter \"%s\"" msgstr "无法分æžå‚æ•° \"%s\" 的设置" -#: utils/misc/guc.c:9681 utils/misc/guc.c:9715 +#: utils/misc/guc.c:10726 utils/misc/guc.c:10760 #, c-format msgid "invalid value for parameter \"%s\": %d" msgstr "傿•° \"%s\" 的值无效: %d" -#: utils/misc/guc.c:9749 +#: utils/misc/guc.c:10794 #, c-format msgid "invalid value for parameter \"%s\": %g" msgstr "傿•° \"%s\" 的值无效: %g" -#: utils/misc/guc.c:9939 +#: utils/misc/guc.c:11064 #, c-format -msgid "" -"\"temp_buffers\" cannot be changed after any temporary tables have been " -"accessed in the session." -msgstr "" -"在当å‰ä¼šè¯ä¸­ï¼Œå¦‚果有任何临时表被访问,就ä¸èƒ½æ”¹å˜\"temp_buffers\"中的内容." +msgid "\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session." +msgstr "在当å‰ä¼šè¯ä¸­ï¼Œå¦‚果有任何临时表被访问,就ä¸èƒ½æ”¹å˜\"temp_buffers\"中的内容." # input.c:213 -#: utils/misc/guc.c:9951 +#: utils/misc/guc.c:11076 #, c-format msgid "Bonjour is not supported by this build" msgstr "è¿™ä¸ªç‰ˆæœ¬çš„å®‰è£…ä¸æ”¯æŒä½¿ç”¨Bonjour " # input.c:213 -#: utils/misc/guc.c:9964 +#: utils/misc/guc.c:11089 #, c-format msgid "SSL is not supported by this build" msgstr "è¿™ä¸ªç‰ˆæœ¬çš„å®‰è£…ä¸æ”¯æŒä½¿ç”¨SSL" -#: utils/misc/guc.c:9976 +#: utils/misc/guc.c:11101 #, c-format msgid "Cannot enable parameter when \"log_statement_stats\" is true." msgstr "当 \"log_statement_stats\" 为 true æ—¶, ä¸èƒ½å¯åЍ傿•°." -#: utils/misc/guc.c:9988 +#: utils/misc/guc.c:11113 #, c-format -msgid "" -"Cannot enable \"log_statement_stats\" when \"log_parser_stats\", " -"\"log_planner_stats\", or \"log_executor_stats\" is true." +msgid "Cannot enable \"log_statement_stats\" when \"log_parser_stats\", \"log_planner_stats\", or \"log_executor_stats\" is true." +msgstr "当 \"log_parser_stats\", \"log_planner_stats\", 或者 \"log_executor_stats\" 为 true æ—¶, 无法å¯ç”¨ \"log_statement_stats\"." + +#: utils/misc/guc.c:11357 +#, fuzzy, c-format +#| msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()" +msgid "effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()." +msgstr "在没有posix_fadvise()的平å°ä¸Šï¼Œeffective_io_concurrency必须设置为0" + +#: utils/misc/guc.c:11471 +#, fuzzy, c-format +#| msgid "recovery_target_timeline is not a valid number: \"%s\"" +msgid "recovery_target_timeline is not a valid number." +msgstr "recovery_target_timeline 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ•°å­—: \"%s\"" + +#: utils/misc/guc.c:11511 +#, fuzzy, c-format +#| msgid "multiple values specified for netmask" +msgid "multiple recovery targets specified" +msgstr "ç½‘ç»œæŽ©ç æŒ‡å®šäº†å¤šä¸ªå€¼" + +#: utils/misc/guc.c:11512 +#, c-format +msgid "At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set." msgstr "" -"当 \"log_parser_stats\", \"log_planner_stats\", 或者 \"log_executor_stats\" " -"为 true æ—¶, 无法å¯ç”¨ \"log_statement_stats\"." -#: utils/misc/help_config.c:131 +#: utils/misc/guc.c:11520 +#, c-format +msgid "The only allowed value is \"immediate\"." +msgstr "唯一有效的值是\"immediate\"." + +#: utils/misc/help_config.c:130 #, c-format msgid "internal error: unrecognized run-time parameter type\n" msgstr "内部错误: 未知的è¿è¡Œæ—¶å‚数类型\n" -#: utils/misc/pg_config.c:61 +#: utils/misc/pg_config.c:60 #, c-format -msgid "" -"query-specified return tuple and function return type are not compatible" +msgid "query-specified return tuple and function return type are not compatible" msgstr "查询指定返回的元组和函数返回类型ä¸å…¼å®¹" +#: utils/misc/pg_controldata.c:60 utils/misc/pg_controldata.c:138 +#: utils/misc/pg_controldata.c:242 utils/misc/pg_controldata.c:309 +#, c-format +msgid "calculated CRC checksum does not match value stored in file" +msgstr "计算得到的 CRC 校验与存储在文件中的值ä¸åŒ¹é…" + +#: utils/misc/pg_rusage.c:64 +#, c-format +msgid "CPU: user: %d.%02d s, system: %d.%02d s, elapsed: %d.%02d s" +msgstr "CPU:用户:%d.%02d s,系统:%d.%02d s,已用时间:%d.%02d s" + #: utils/misc/rls.c:127 #, c-format -#| msgid "new row violates row-level security policy for table \"%s\"" msgid "query would be affected by row-level security policy for table \"%s\"" msgstr "查询将被表 \"%s\" 的行级安全性策略所影å“" #: utils/misc/rls.c:129 #, c-format -msgid "" -"To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW " -"LEVEL SECURITY." +msgid "To disable the policy for the table's owner, use ALTER TABLE NO FORCE ROW LEVEL SECURITY." msgstr "è¦ç¦ç”¨å¯¹è¡¨æ‹¥æœ‰è€…的策略,使用 ALTER TABLE NO FORCE ROW LEVEL SECURITY。" #: utils/misc/timeout.c:388 @@ -24274,9 +26102,7 @@ msgstr "无法添加更多的超时原因" #: utils/misc/tzparser.c:61 #, c-format -msgid "" -"time zone abbreviation \"%s\" is too long (maximum %d characters) in time " -"zone file \"%s\", line %d" +msgid "time zone abbreviation \"%s\" is too long (maximum %d characters) in time zone file \"%s\", line %d" msgstr "在时区文件\"%3$s\"的第%4$d行中时区缩写\"%1$s\"太长了(最大å…许%2$d字符)" #: utils/misc/tzparser.c:73 @@ -24311,9 +26137,7 @@ msgstr "多次定义时间区缩写\"%s\" " #: utils/misc/tzparser.c:239 #, c-format -msgid "" -"Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s" -"\", line %d." +msgid "Entry in time zone file \"%s\", line %d, conflicts with entry in file \"%s\", line %d." msgstr "在时区文件\"%s\"中第%d行的项, 与在文件\"%s\"第%d行中的项相冲çª." #: utils/misc/tzparser.c:301 @@ -24341,334 +26165,697 @@ msgstr "在时间区域文件\"%s\"的第%d行中文本太长了." msgid "@INCLUDE without file name in time zone file \"%s\", line %d" msgstr "在时间区域文件\"%s\"中的第%d行中,@INCLUDE没有带文件å " -#: utils/mmgr/aset.c:506 +#: utils/mmgr/aset.c:485 utils/mmgr/generation.c:250 utils/mmgr/slab.c:240 #, c-format msgid "Failed while creating memory context \"%s\"." msgstr "创建内存上下文 \"%s\" 失败." -#: utils/mmgr/mcxt.c:771 utils/mmgr/mcxt.c:806 utils/mmgr/mcxt.c:843 -#: utils/mmgr/mcxt.c:880 utils/mmgr/mcxt.c:914 utils/mmgr/mcxt.c:943 -#: utils/mmgr/mcxt.c:977 utils/mmgr/mcxt.c:1059 utils/mmgr/mcxt.c:1093 -#: utils/mmgr/mcxt.c:1142 +#: utils/mmgr/dsa.c:519 utils/mmgr/dsa.c:1332 #, c-format -msgid "Failed on request of size %zu." -msgstr "æ— æ³•è¯·æ±‚å¤§å° %zu." +msgid "could not attach to dynamic shared area" +msgstr "无法附加到动æ€å…±äº«åŒºåŸŸ" -#: utils/mmgr/portalmem.c:208 +#: utils/mmgr/mcxt.c:797 utils/mmgr/mcxt.c:833 utils/mmgr/mcxt.c:871 +#: utils/mmgr/mcxt.c:909 utils/mmgr/mcxt.c:945 utils/mmgr/mcxt.c:976 +#: utils/mmgr/mcxt.c:1012 utils/mmgr/mcxt.c:1064 utils/mmgr/mcxt.c:1099 +#: utils/mmgr/mcxt.c:1134 +#, c-format +msgid "Failed on request of size %zu in memory context \"%s\"." +msgstr "在内存上下文\"%2$s\"中请求大å°ä¸º%1$zu时失败." + +#: utils/mmgr/portalmem.c:187 #, c-format msgid "cursor \"%s\" already exists" msgstr "游标 \"%s\" å·²ç»å­˜åœ¨" -#: utils/mmgr/portalmem.c:212 +#: utils/mmgr/portalmem.c:191 #, c-format msgid "closing existing cursor \"%s\"" msgstr "关闭已存在的游标 \"%s\"" -#: utils/mmgr/portalmem.c:419 +#: utils/mmgr/portalmem.c:398 #, c-format msgid "portal \"%s\" cannot be run" msgstr "å…¥å£ \"%s\" ä¸å¯ä»¥è¿è¡Œ" -#: utils/mmgr/portalmem.c:499 +#: utils/mmgr/portalmem.c:476 +#, c-format +msgid "cannot drop pinned portal \"%s\"" +msgstr "无法删除固定的portal \"%s\"" + +#: utils/mmgr/portalmem.c:484 #, c-format msgid "cannot drop active portal \"%s\"" msgstr "ä¸èƒ½åˆ é™¤å¤„于活动状æ€çš„portal \"%s\"" -#: utils/mmgr/portalmem.c:689 +#: utils/mmgr/portalmem.c:729 #, c-format msgid "cannot PREPARE a transaction that has created a cursor WITH HOLD" msgstr "无法对一个已ç»åˆ›å»ºå¸¦æœ‰WITH HOLD游标的事务执行PREPAREæ“作." -#: utils/sort/logtape.c:226 +#: utils/mmgr/portalmem.c:1269 +#, c-format +msgid "cannot perform transaction commands inside a cursor loop that is not read-only" +msgstr "ä¸èƒ½åœ¨éžåªè¯»çš„æ¸¸æ ‡å¾ªçŽ¯å†…æ‰§è¡Œäº‹åŠ¡å‘½ä»¤" + +#: utils/sort/logtape.c:276 #, c-format msgid "could not read block %ld of temporary file: %m" msgstr "无法读å–ä¸´æ—¶æ–‡ä»¶å— %ld: %m" -#: utils/sort/tuplesort.c:3360 +#: utils/sort/sharedtuplestore.c:208 +#, c-format +msgid "could not write to temporary file: %m" +msgstr "无法写入临时文件: %m" + +#: utils/sort/sharedtuplestore.c:437 utils/sort/sharedtuplestore.c:446 +#: utils/sort/sharedtuplestore.c:469 utils/sort/sharedtuplestore.c:486 +#: utils/sort/sharedtuplestore.c:503 utils/sort/sharedtuplestore.c:575 +#: utils/sort/sharedtuplestore.c:581 +#, c-format +msgid "could not read from shared tuplestore temporary file" +msgstr "无法从共享的元组存储临时文件读å–" + +#: utils/sort/sharedtuplestore.c:492 +#, c-format +msgid "unexpected chunk in shared tuplestore temporary file" +msgstr "共享的元组存储临时文件中的æ„外å—" + +#: utils/sort/tuplesort.c:2967 #, c-format -#| msgid "cannot use more than %d columns in an index" msgid "cannot have more than %d runs for an external sort" msgstr "ä¸èƒ½ä¸ºä¸€æ¬¡å¤–部排åºè¿è¡Œè¶…过 %d 次" -#: utils/sort/tuplesort.c:4416 +#: utils/sort/tuplesort.c:4051 #, c-format msgid "could not create unique index \"%s\"" msgstr "无法创建唯一索引\"%s\"" -#: utils/sort/tuplesort.c:4418 +#: utils/sort/tuplesort.c:4053 #, c-format msgid "Key %s is duplicated." msgstr "键值%sé‡å¤äº†" -#: utils/sort/tuplesort.c:4419 +#: utils/sort/tuplesort.c:4054 #, c-format msgid "Duplicate keys exist." msgstr "存在é‡å¤é”®ã€‚" -#: utils/sort/tuplestore.c:515 utils/sort/tuplestore.c:525 -#: utils/sort/tuplestore.c:852 utils/sort/tuplestore.c:956 -#: utils/sort/tuplestore.c:1020 utils/sort/tuplestore.c:1037 -#: utils/sort/tuplestore.c:1239 utils/sort/tuplestore.c:1304 -#: utils/sort/tuplestore.c:1313 +#: utils/sort/tuplestore.c:518 utils/sort/tuplestore.c:528 +#: utils/sort/tuplestore.c:869 utils/sort/tuplestore.c:973 +#: utils/sort/tuplestore.c:1037 utils/sort/tuplestore.c:1054 +#: utils/sort/tuplestore.c:1256 utils/sort/tuplestore.c:1321 +#: utils/sort/tuplestore.c:1330 #, c-format msgid "could not seek in tuplestore temporary file: %m" msgstr "无法在元组存储临时文件中定ä½: %m" -#: utils/sort/tuplestore.c:1460 utils/sort/tuplestore.c:1533 -#: utils/sort/tuplestore.c:1539 +#: utils/sort/tuplestore.c:1477 utils/sort/tuplestore.c:1550 +#: utils/sort/tuplestore.c:1556 #, c-format msgid "could not read from tuplestore temporary file: %m" msgstr "无法从元组存储临时文件读å–: %m" -#: utils/sort/tuplestore.c:1501 utils/sort/tuplestore.c:1506 -#: utils/sort/tuplestore.c:1512 +#: utils/sort/tuplestore.c:1518 utils/sort/tuplestore.c:1523 +#: utils/sort/tuplestore.c:1529 #, c-format msgid "could not write to tuplestore temporary file: %m" msgstr "无法写入元组存储临时文件: %m" -#: utils/time/snapmgr.c:536 +#: utils/time/snapmgr.c:624 #, c-format msgid "The source transaction is not running anymore." msgstr "æºäº‹åС已ä¸å†è¿è¡Œ." -#: utils/time/snapmgr.c:1090 +#: utils/time/snapmgr.c:1202 #, c-format msgid "cannot export a snapshot from a subtransaction" msgstr "å­äº‹åŠ¡ä¸­æ— æ³•å¯¼å‡ºä¸€ä¸ªå¿«ç…§" -#: utils/time/snapmgr.c:1239 utils/time/snapmgr.c:1244 -#: utils/time/snapmgr.c:1249 utils/time/snapmgr.c:1264 -#: utils/time/snapmgr.c:1269 utils/time/snapmgr.c:1274 -#: utils/time/snapmgr.c:1373 utils/time/snapmgr.c:1389 -#: utils/time/snapmgr.c:1414 +#: utils/time/snapmgr.c:1361 utils/time/snapmgr.c:1366 +#: utils/time/snapmgr.c:1371 utils/time/snapmgr.c:1386 +#: utils/time/snapmgr.c:1391 utils/time/snapmgr.c:1396 +#: utils/time/snapmgr.c:1411 utils/time/snapmgr.c:1416 +#: utils/time/snapmgr.c:1421 utils/time/snapmgr.c:1523 +#: utils/time/snapmgr.c:1539 utils/time/snapmgr.c:1564 #, c-format msgid "invalid snapshot data in file \"%s\"" msgstr "文件 \"%s\" 中存在无效快照数æ®" -#: utils/time/snapmgr.c:1311 +#: utils/time/snapmgr.c:1458 #, c-format msgid "SET TRANSACTION SNAPSHOT must be called before any query" msgstr "SET TRANSACTION SNAPSHOT 必须在任何查询之å‰è°ƒç”¨" -#: utils/time/snapmgr.c:1320 +#: utils/time/snapmgr.c:1467 #, c-format -msgid "" -"a snapshot-importing transaction must have isolation level SERIALIZABLE or " -"REPEATABLE READ" -msgstr "" -"一个snapshot-importing事务的隔离级åªèƒ½æ˜¯SERIALIZABLE或者REPEATABLE READ" +msgid "a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ" +msgstr "一个snapshot-importing事务的隔离级åªèƒ½æ˜¯SERIALIZABLE或者REPEATABLE READ" -#: utils/time/snapmgr.c:1329 utils/time/snapmgr.c:1338 +#: utils/time/snapmgr.c:1476 utils/time/snapmgr.c:1485 #, c-format msgid "invalid snapshot identifier: \"%s\"" msgstr "无效快照标识符: \"%s\"" -#: utils/time/snapmgr.c:1427 +#: utils/time/snapmgr.c:1577 #, c-format -msgid "" -"a serializable transaction cannot import a snapshot from a non-serializable " -"transaction" +msgid "a serializable transaction cannot import a snapshot from a non-serializable transaction" msgstr "一个å¯ä¸²è¡ŒåŒ–事务ä¸èƒ½ä»Žéžå¯ä¸²è¡ŒåŒ–事务中导入一个快照" -#: utils/time/snapmgr.c:1431 +#: utils/time/snapmgr.c:1581 #, c-format -msgid "" -"a non-read-only serializable transaction cannot import a snapshot from a " -"read-only transaction" +msgid "a non-read-only serializable transaction cannot import a snapshot from a read-only transaction" msgstr "éžåªè¯»å¯ä¸²è¡ŒåŒ–事务无法导入æ¥è‡ªåªè¯»äº‹åŠ¡çš„å¿«ç…§" -#: utils/time/snapmgr.c:1446 +#: utils/time/snapmgr.c:1596 #, c-format msgid "cannot import a snapshot from a different database" msgstr "无法导入æ¥è‡ªä¸åŒæ•°æ®åº“的快照" -#~ msgid "user name lookup failure: %s" -#~ msgstr "用户å: %s查找失败" +#: gram.y:1030 +#, c-format +msgid "UNENCRYPTED PASSWORD is no longer supported" +msgstr "UNENCRYPTED PASSWORD ä¸å†è¢«æ”¯æŒ" + +#: gram.y:1031 +#, c-format +msgid "Remove UNENCRYPTED to store the password in encrypted form instead." +msgstr "删除 UNENCRYPTED 以加密形å¼å­˜å‚¨å¯†ç ." + +#: gram.y:1093 +#, c-format +msgid "unrecognized role option \"%s\"" +msgstr "无法识别的角色选项\"%s\"" + +#: gram.y:1340 gram.y:1355 +#, c-format +msgid "CREATE SCHEMA IF NOT EXISTS cannot include schema elements" +msgstr "CREATE SCHEMA IF NOT EXISTSä¸èƒ½åŒ…嫿–¹æ¡ˆ(schema)元素" + +#: gram.y:1501 +#, c-format +msgid "current database cannot be changed" +msgstr "ä¸èƒ½æ”¹å˜å½“å‰ä½¿ç”¨çš„æ•°æ®åº“" + +#: gram.y:1625 +#, c-format +msgid "time zone interval must be HOUR or HOUR TO MINUTE" +msgstr "时区间隔必须为 HOUR 或者 HOUR TO MINUTE" + +#: gram.y:2143 +#, c-format +msgid "column number must be in range from 1 to %d" +msgstr "列å·å¿…须是在范围1到%d之间" + +#: gram.y:2675 +#, c-format +msgid "sequence option \"%s\" not supported here" +msgstr "æ­¤å¤„ä¸æ”¯æŒåºåˆ—选项\"%s\"" + +#: gram.y:2704 +#, c-format +msgid "modulus for hash partition provided more than once" +msgstr "哈希分区的模数æä¾›äº†å¤šæ¬¡" + +#: gram.y:2713 +#, c-format +msgid "remainder for hash partition provided more than once" +msgstr "哈希分区的剩余部分æä¾›äº†å¤šæ¬¡" + +#: gram.y:2720 +#, c-format +msgid "unrecognized hash partition bound specification \"%s\"" +msgstr "ä¸å¯è¯†åˆ«çš„哈希分区绑定规范\"%s\"" + +#: gram.y:2728 +#, c-format +msgid "modulus for hash partition must be specified" +msgstr "必须指定哈希分区的模数" + +#: gram.y:2732 +#, c-format +msgid "remainder for hash partition must be specified" +msgstr "必须指定哈希分区的剩余部分" + +#: gram.y:2933 gram.y:2966 +#, c-format +msgid "STDIN/STDOUT not allowed with PROGRAM" +msgstr "STDIN/STDOUT ä¸å…许与PROGRAM一起使用" + +#: gram.y:2939 +#, fuzzy, c-format +#| msgid "%s is not allowed with GROUP BY clause" +msgid "WHERE clause not allowed with COPY TO" +msgstr "%sä¸èƒ½ç”¨äºŽGROUP BYå­å¥ä¸­" + +#: gram.y:3271 gram.y:3278 gram.y:11480 gram.y:11488 +#, c-format +msgid "GLOBAL is deprecated in temporary table creation" +msgstr "GLOBAL在临时表中的创建中已ç»è¢«åºŸå¼ƒä½¿ç”¨" + +#: gram.y:3518 +#, c-format +msgid "for a generated column, GENERATED ALWAYS must be specified" +msgstr "" + +#: gram.y:5274 +#, c-format +msgid "unrecognized row security option \"%s\"" +msgstr "无法识别的行安全选项\"%s\"" + +#: gram.y:5275 +#, c-format +msgid "Only PERMISSIVE or RESTRICTIVE policies are supported currently." +msgstr "当å‰ä»…æ”¯æŒ PERMISSIVE 或 RESTRICTIVE ç­–ç•¥ " + +#: gram.y:5388 +msgid "duplicate trigger events specified" +msgstr "é‡å¤æŒ‡å®šè§¦å‘器事件" + +#: gram.y:5536 +#, c-format +msgid "conflicting constraint properties" +msgstr "约æŸå±žæ€§å†²çª" + +#: gram.y:5632 +#, c-format +msgid "CREATE ASSERTION is not yet implemented" +msgstr "CREATE ASSERTION 仿œªå®žçް" + +#: gram.y:6015 +#, c-format +msgid "RECHECK is no longer required" +msgstr "ä¸å†éœ€è¦RECHECK选项了" + +# describe.c:289 +#: gram.y:6016 +#, c-format +msgid "Update your data type." +msgstr "更改您的数æ®ç±»åž‹" + +#: gram.y:7753 +#, c-format +msgid "aggregates cannot have output arguments" +msgstr "èšåˆå‡½æ•°ä¸èƒ½ä½¿ç”¨è¾“å‡ºå‚æ•°" + +#: gram.y:10025 gram.y:10043 +#, c-format +msgid "WITH CHECK OPTION not supported on recursive views" +msgstr "递归视图ä¸èƒ½ä½¿ç”¨WITH CHECK OPTION" + +#: gram.y:11588 +#, c-format +msgid "LIMIT #,# syntax is not supported" +msgstr "䏿”¯æŒ LIMIT #,# 语法" + +#: gram.y:11589 +#, c-format +msgid "Use separate LIMIT and OFFSET clauses." +msgstr "LIMITå’ŒOFFSETå­å¥è¦åˆ†éš”å¼€" + +#: gram.y:11887 gram.y:11912 +#, c-format +msgid "VALUES in FROM must have an alias" +msgstr "FROM中的VALUESå­å¥å¿…须有一个别å" + +#: gram.y:11888 gram.y:11913 +#, c-format +msgid "For example, FROM (VALUES ...) [AS] foo." +msgstr "例如, FROM (SELECT ...) [AS] foo." + +#: gram.y:11893 gram.y:11918 +#, c-format +msgid "subquery in FROM must have an alias" +msgstr "FROM ä¸­çš„å­æŸ¥è¯¢å¿…须有一个别å" + +#: gram.y:11894 gram.y:11919 +#, c-format +msgid "For example, FROM (SELECT ...) [AS] foo." +msgstr "例如, FROM (SELECT ...) [AS] foo." + +#: gram.y:12372 +#, c-format +msgid "only one DEFAULT value is allowed" +msgstr "åªå…许一个默认值" + +#: gram.y:12381 +#, c-format +msgid "only one PATH value per column is allowed" +msgstr "æ¯åˆ—åªå…许一个路径值" + +#: gram.y:12390 +#, c-format +msgid "conflicting or redundant NULL / NOT NULL declarations for column \"%s\"" +msgstr "列\"%s\"çš„ NULL / NOT NULL å£°æ˜Žå†²çªæˆ–冗余" + +#: gram.y:12399 +#, c-format +msgid "unrecognized column option \"%s\"" +msgstr "无法识别的列选项\"%s\"" + +#: gram.y:12653 +#, c-format +msgid "precision for type float must be at least 1 bit" +msgstr "浮点类型的精确度必须至少 1 ä½" -#~ msgid "mapped win32 error code %lu to %d" -#~ msgstr "å°†win32错误代ç %2$d映射为%1$lu" +#: gram.y:12662 +#, c-format +msgid "precision for type float must be less than 54 bits" +msgstr "浮点类型的精确度必须å°äºŽ 54 ä½" -#~ msgid "unrecognized win32 error code: %lu" -#~ msgstr "未知的 win32 错误ç : %lu" +#: gram.y:13153 +#, c-format +msgid "wrong number of parameters on left side of OVERLAPS expression" +msgstr "OVERLAPS 表达å¼å·¦è¾¹çš„傿•°ä¸ªæ•°ä¸å¯¹" -#~ msgid "redo record is at %X/%X; shutdown %s" -#~ msgstr "é‡åšè®°å½•是在%X/%X; 关闭 %s" +#: gram.y:13158 +#, c-format +msgid "wrong number of parameters on right side of OVERLAPS expression" +msgstr "OVERLAPS 表达å¼å³è¾¹çš„傿•°ä¸ªæ•°ä¸å¯¹" -#~ msgid "next transaction ID: %u/%u; next OID: %u" -#~ msgstr "下一个事务ID: %u/%u; 下一个 OID: %u" +#: gram.y:13333 +#, c-format +msgid "UNIQUE predicate is not yet implemented" +msgstr "没有实现UNIQUEè°“è¯" -#~ msgid "next MultiXactId: %u; next MultiXactOffset: %u" -#~ msgstr "下一个MultiXactId: %u; 下一个MultiXactOffset: %u" +#: gram.y:13680 +#, c-format +msgid "cannot use multiple ORDER BY clauses with WITHIN GROUP" +msgstr "WITHIN GROUPä¸å…许多个 ORDER BY å­å¥" -#~ msgid "oldest unfrozen transaction ID: %u, in database %u" -#~ msgstr "在数æ®åº“%2$u中,最旧的éžå†»ç»“事务ID是%1$u" +#: gram.y:13685 +#, c-format +msgid "cannot use DISTINCT with WITHIN GROUP" +msgstr "ä¸èƒ½å°† DISTINCT å’Œ WITHIN GROUP混在一起使用" -#~ msgid "=> is deprecated as an operator name" -#~ msgstr "=>åšä¸ºæ“作符å称已被废弃" +#: gram.y:13690 +#, c-format +msgid "cannot use VARIADIC with WITHIN GROUP" +msgstr "ä¸èƒ½å°† VARIADIC å’Œ WITHIN GROUP在一起混用" -#~ msgid "" -#~ "This name may be disallowed altogether in future versions of PostgreSQL." -#~ msgstr "在将æ¥çš„PostgreSQL版本中ä¸å…许使用这个åç§°." +#: gram.y:14148 gram.y:14171 +#, c-format +msgid "frame start cannot be UNBOUNDED FOLLOWING" +msgstr "框架的起始ä½ç½®ä¸èƒ½è¢«æ‰§è¡ŒUNBOUNDED FOLLOWINGæ“作." -#~ msgid "inherited relation \"%s\" is not a table" -#~ msgstr "继承关系 \"%s\" 䏿˜¯ä¸€ä¸ªè¡¨" +#: gram.y:14153 +#, c-format +msgid "frame starting from following row cannot end with current row" +msgstr "从åŽé¢è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½ä»¥å½“å‰è®°å½•结æŸ" -#~ msgid "Specify a USING expression to perform the conversion." -#~ msgstr "指定一个USINGè¡¨è¾¾å¼æ¥æ‰§è¡Œè½¬æ¢" +#: gram.y:14176 +#, c-format +msgid "frame end cannot be UNBOUNDED PRECEDING" +msgstr "框架的结æŸä½ç½®ä¸èƒ½è¢«æ‰§è¡ŒUNBOUNDED FOLLOWINGæ“作." -#~ msgid "" -#~ "%.0f dead row versions cannot be removed yet.\n" -#~ "There were %.0f unused item pointers.\n" -#~ "%u pages are entirely empty.\n" -#~ "%s." -#~ msgstr "" -#~ "å·²ä¸ç”¨çš„行版本%.0f还ä¸èƒ½åˆ é™¤.\n" -#~ "那里有%.0f个没使用的æˆå‘˜æŒ‡é’ˆ.\n" -#~ "%u页当å‰å®Œå…¨æ˜¯ç©ºçš„.\n" -#~ "%s." +#: gram.y:14182 +#, c-format +msgid "frame starting from current row cannot have preceding rows" +msgstr "从当å‰è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½æ‹¥æœ‰æ­£åœ¨å¤„ç†çš„记录" -#~ msgid "interval precision specified twice" -#~ msgstr "两次指定间隔精度" +#: gram.y:14189 +#, c-format +msgid "frame starting from following row cannot have preceding rows" +msgstr "从åŽé¢è®°å½•å¯åŠ¨çš„çª—å£æ¡†æž¶(frame)ä¸èƒ½æ‹¥æœ‰æ­£åœ¨å¤„ç†çš„记录" + +#: gram.y:14832 +#, c-format +msgid "type modifier cannot have parameter name" +msgstr "类型修改器ä¸èƒ½æœ‰å‚æ•°åç§°" + +#: gram.y:14838 +#, c-format +msgid "type modifier cannot have ORDER BY" +msgstr "类型修改器ä¸èƒ½æœ‰ORDER BY" -#~ msgid "received password packet" -#~ msgstr "接收到å£ä»¤åŒ…" +#: gram.y:14903 gram.y:14910 +#, c-format +msgid "%s cannot be used as a role name here" +msgstr "在这里%sä¸èƒ½è¢«ç”¨åšä¸€ä¸ªè§’色å" -#~ msgid "could not complete SSL handshake on renegotiation, too many failures" -#~ msgstr "åœ¨å†æ¬¡åå•†é˜¶æ®µæ— æ³•å®Œæˆ SSL æ¡æ‰‹ , 因为其间出现了太多的失败" +#: gram.y:15583 gram.y:15772 +msgid "improper use of \"*\"" +msgstr "对\"*\"çš„ä½¿ç”¨ä¸æ­£ç¡®" + +#: gram.y:15836 +#, c-format +msgid "an ordered-set aggregate with a VARIADIC direct argument must have one VARIADIC aggregated argument of the same data type" +msgstr "带å¯å˜ç›´æŽ¥å‚数的有åºé›†èšé›†å‡½æ•°å¿…须有一个 相åŒç±»åž‹çš„VARIADIC èšé›†å‚æ•° " + +#: gram.y:15873 +#, c-format +msgid "multiple ORDER BY clauses not allowed" +msgstr "ä¸å…许多个 ORDER BY å­å¥" + +#: gram.y:15884 +#, c-format +msgid "multiple OFFSET clauses not allowed" +msgstr "ä¸å…许多个 OFFSET å­å¥" + +#: gram.y:15893 +#, c-format +msgid "multiple LIMIT clauses not allowed" +msgstr "ä¸å…许多个 LIMIT å­å¥" + +#: gram.y:15902 +#, c-format +msgid "multiple WITH clauses not allowed" +msgstr "ä¸å…许使用多个WITHå­å¥" + +#: gram.y:16106 +#, c-format +msgid "OUT and INOUT arguments aren't allowed in TABLE functions" +msgstr "在TABLE函数中ä¸å…许使用OUT或INOUT模å¼çš„傿•°" + +#: gram.y:16207 +#, c-format +msgid "multiple COLLATE clauses not allowed" +msgstr "ä¸å…许多个 COLLATE å­å¥" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16245 gram.y:16258 +#, c-format +msgid "%s constraints cannot be marked DEFERRABLE" +msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºDEFERRABLE" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16271 +#, c-format +msgid "%s constraints cannot be marked NOT VALID" +msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºNOT VALID" + +#. translator: %s is CHECK, UNIQUE, or similar +#: gram.y:16284 +#, c-format +msgid "%s constraints cannot be marked NO INHERIT" +msgstr "%s约æŸä¸èƒ½æ ‡ä¸ºNO INHERIT" + +#: guc-file.l:316 +#, c-format +msgid "unrecognized configuration parameter \"%s\" in file \"%s\" line %u" +msgstr "未认å¯çš„é…ç½®å‚æ•° \"%s\", 文件\"%s\", 行%u" + +#: guc-file.l:389 +#, c-format +msgid "parameter \"%s\" removed from configuration file, reset to default" +msgstr "傿•°\"%s\"已从é…ç½®æ–‡ä»¶ä¸­åˆ é™¤ï¼Œé‡æ–°è®¾ç½®ä¸ºç¼ºçœ" -#~ msgid "could not set socket to blocking mode: %m" -#~ msgstr "无法将套接字设置为阻塞模å¼: %m" +#: guc-file.l:455 +#, c-format +msgid "parameter \"%s\" changed to \"%s\"" +msgstr "傿•° \"%s\"被改为\"%s\"" -#~ msgid "%s: setsysinfo failed: %s\n" -#~ msgstr "%s: setsysinfo 失败: %s\n" +#: guc-file.l:497 +#, c-format +msgid "configuration file \"%s\" contains errors" +msgstr "é…置文件 \"%s\" 有错" -#~ msgid " -A 1|0 enable/disable run-time assert checking\n" -#~ msgstr " -A 1|0 打开/关闭è¿è¡Œæ—¶æ–­è¨€æ£€æŸ¥\n" +#: guc-file.l:502 +#, c-format +msgid "configuration file \"%s\" contains errors; unaffected changes were applied" +msgstr "é…置文件 \"%s\" 有错; 使用了ä¸å—å½±å“的内容å˜åЍ" -#~ msgid "subquery must return a column" -#~ msgstr "å­æŸ¥è¯¢å¿…须返回一个字段" +#: guc-file.l:507 +#, c-format +msgid "configuration file \"%s\" contains errors; no changes were applied" +msgstr "é…置文件 \"%s\" 有错; 没有内容å˜åЍ" -#~ msgid "" -#~ "Consider increasing the configuration parameter \"checkpoint_segments\"." -#~ msgstr "认为增加é…ç½®å‚æ•° \"checkpoint_segments\"." +#: guc-file.l:580 +#, c-format +msgid "could not open configuration file \"%s\": maximum nesting depth exceeded" +msgstr "无法打开é…置文件 \"%s\": 已超过最大的嵌套深度" -#~ msgid "archive member \"%s\" too large for tar format" -#~ msgstr "在 tar æ ¼å¼ä¸­å½’æ¡£æˆå‘˜\"%s\"太大" +#: guc-file.l:607 +#, c-format +msgid "skipping missing configuration file \"%s\"" +msgstr "忽略丢失的é…置文件\"%s\"" -#~ msgid "could not determine input data types" -#~ msgstr "无法确定输入数æ®ç±»åž‹" +#: guc-file.l:861 +#, c-format +msgid "syntax error in file \"%s\" line %u, near end of line" +msgstr "在文件 \"%s\" 第 %u 行, 行尾附近语法错误" -#~ msgid "neither input type is an array" -#~ msgstr "没有输入类型是数组" +#: guc-file.l:871 +#, c-format +msgid "syntax error in file \"%s\" line %u, near token \"%s\"" +msgstr "在文件 \"%s\" 第 %u 行, è®°å· \"%s\" 附近语法错误" -#~ msgid "missing assignment operator" -#~ msgstr "缺少指定的æ“作符" +#: guc-file.l:891 +#, c-format +msgid "too many syntax errors found, abandoning file \"%s\"" +msgstr "å‘现太多的语法错误, 放弃文件 \"%s\"" -#~ msgid "invalid symbol" -#~ msgstr "无效符å·" +#: guc-file.l:943 +#, c-format +msgid "could not open configuration directory \"%s\": %m" +msgstr "无法打开é…置文件目录 \"%s\": %m" -#~ msgid "" -#~ "must be superuser or have the same role to cancel queries running in " -#~ "other server processes" -#~ msgstr "åªæœ‰è¶…级用户或拥有相åŒè§’色的用户å¯ä»¥å–消其他æœåŠ¡å™¨è¿›ç¨‹ä¸­çš„æŸ¥è¯¢" +#: jsonpath_gram.y:517 +#, fuzzy, c-format +#| msgid "unrecognized parameter \"%s\" in file \"%s\"" +msgid "unrecognized flag character \"%c\" in LIKE_REGEX predicate" +msgstr "文件\"%2$s\"ä¸­å‡ºçŽ°æœªè¯†åˆ«çš„å‚æ•° \"%1$s\"" -#~ msgid "" -#~ "must be superuser or have the same role to terminate other server " -#~ "processes" -#~ msgstr "åªæœ‰è¶…级用户或拥有相åŒè§’色的用户å¯ä»¥ç»ˆæ­¢å…¶ä»–æœåŠ¡å™¨è¿›ç¨‹" +#. translator: %s is typically "syntax error" +#: jsonpath_scan.l:300 +#, fuzzy, c-format +#| msgid "%s at end of input" +msgid "%s at end of jsonpath input" +msgstr "%s 在输入的末尾" -#~ msgid "cannot accept a value of type pg_node_tree" -#~ msgstr "无法接å—一个 pg_node_tree类型值" +#. translator: first %s is typically "syntax error" +#: jsonpath_scan.l:307 +#, fuzzy, c-format +#| msgid "%s at or near \"%s\"" +msgid "%s at or near \"%s\" of jsonpath input" +msgstr "%s 在 \"%s\" 或附近的" -#~ msgid "Turns on various assertion checks." -#~ msgstr "打开å„ç§åˆ¤æ–­æ£€æŸ¥." +#: repl_gram.y:336 repl_gram.y:368 +#, c-format +msgid "invalid timeline %u" +msgstr "无效时间线%u" -#~ msgid "This is a debugging aid." -#~ msgstr "这是一个出错帮助." +#: repl_scanner.l:129 +msgid "invalid streaming start location" +msgstr "无效的æµèµ·å§‹ä½ç½®" -#~ msgid "This parameter doesn't do anything." -#~ msgstr "è¿™ä¸ªå‚æ•°ä¸åšä»»ä½•事情." +#: repl_scanner.l:180 scan.l:703 +msgid "unterminated quoted string" +msgstr "未结æŸçš„引用字符串" -#~ msgid "" -#~ "It's just here so that we won't choke on SET AUTOCOMMIT TO ON from 7.3-" -#~ "vintage clients." -#~ msgstr "åªæ˜¯è¿™é‡Œæˆ‘们ä¸èƒ½ä»Ž7.3版本的客户端中阻止è¿è¡ŒSET AUTOCOMMIT TO ON." +#: scan.l:463 +msgid "unterminated /* comment" +msgstr "/* 注释没有结æŸ" -#~ msgid "" -#~ "Sets the maximum distance in log segments between automatic WAL " -#~ "checkpoints." -#~ msgstr "在自动WAL检查点之间设置log段中的最大è·ç¦»." +#: scan.l:494 +msgid "unterminated bit string literal" +msgstr "未结æŸçš„bit字符串常é‡" -#~ msgid "" -#~ "Set the amount of traffic to send and receive before renegotiating the " -#~ "encryption keys." -#~ msgstr "åœ¨é‡æ–°è®¾å®šåР坆键之å‰è®¾å®šéœ€è¦è¿›è¡Œå‘é€å’ŒæŽ¥æ”¶çš„æµé‡æ€»å’Œ" +#: scan.l:515 +msgid "unterminated hexadecimal string literal" +msgstr "未结æŸçš„16进制字符串常é‡" -#~ msgid "SET AUTOCOMMIT TO OFF is no longer supported" -#~ msgstr "SET AUTOCOMMIT TO OFF ä¸å†è¢«æ”¯æŒ" +#: scan.l:565 +#, c-format +msgid "unsafe use of string constant with Unicode escapes" +msgstr "è¿™ç§ä½¿ç”¨å¸¦æœ‰Unicode转义字符的字符串常é‡çš„æ–¹æ³•ä¸å®‰å…¨." -#~ msgid "assertion checking is not supported by this build" -#~ msgstr "è¿™ä¸ªç‰ˆæœ¬çš„å®‰è£…ä¸æ”¯æŒä½¿ç”¨æ–­è¨€æ£€æŸ¥" +#: scan.l:566 +#, c-format +msgid "String constants with Unicode escapes cannot be used when standard_conforming_strings is off." +msgstr "当傿•°standard_conforming_stringså¤„äºŽå…³é—­çŠ¶æ€æ—¶ï¼Œæ— æ³•使用带有Unicode转义字符的字符串常é‡." -#~ msgid "Perhaps out of disk space?" -#~ msgstr "å¯èƒ½è¶…出ç£ç›˜ç©ºé—´?" +#: scan.l:612 scan.l:811 +msgid "invalid Unicode escape character" +msgstr "无效Unicode转义字符" -#~ msgid "" -#~ "time zone offset %d is not a multiple of 900 sec (15 min) in time zone " -#~ "file \"%s\", line %d" -#~ msgstr "" -#~ "在时区文件 \"%2$s\"中的第%3$d行中时区åç§»%1$d䏿˜¯900ç§’(15分钟)çš„å€æ•°." +#: scan.l:638 scan.l:646 scan.l:654 scan.l:655 scan.l:656 scan.l:1400 +#: scan.l:1427 scan.l:1431 scan.l:1469 scan.l:1473 scan.l:1495 scan.l:1505 +msgid "invalid Unicode surrogate pair" +msgstr "无效的Unicode代ç†é¡¹å¯¹(surrogate pair)" -#~ msgid "Sets the name of the Kerberos service." -#~ msgstr "设置KerberosæœåŠ¡çš„åç§°" +#: scan.l:660 +#, c-format +msgid "invalid Unicode escape" +msgstr "无效的Unicode转义字符" -#~ msgid "No description available." -#~ msgstr "没有å¯ç”¨çš„æè¿°" +#: scan.l:661 +#, c-format +msgid "Unicode escapes must be \\uXXXX or \\UXXXXXXXX." +msgstr "Unicode转义字符必须是\\uXXXX或\\UXXXXXXXX." -#~ msgid "insufficient privilege to bypass row-level security" -#~ msgstr "没有足够的特æƒç»•过行级安全性" +#: scan.l:672 +#, c-format +msgid "unsafe use of \\' in a string literal" +msgstr "在字符串常é‡ä¸­ä½¿ç”¨\\ä¸å®‰å…¨" -#~ msgid "WAL writer sleep time between WAL flushes." -#~ msgstr "WAL写进程在两次刷新WAL缓存内容之间的ç¡çœ æ—¶é—´" +#: scan.l:673 +#, c-format +msgid "Use '' to write quotes in strings. \\' is insecure in client-only encodings." +msgstr "使用''在字符串中表示引å·,åœ¨åªæœ‰å®¢æˆ·ç«¯ä½¿ç”¨çš„ç¼–ç ä¸­ä½¿ç”¨\\'ä¸å®‰å…¨." -#~ msgid "could not convert to time zone \"%s\"" -#~ msgstr "无法转æ¢åˆ°æ—¶é—´åŒºåŸŸ\"%s\"" +#: scan.l:748 +msgid "unterminated dollar-quoted string" +msgstr "未结æŸçš„用$符å·å¼•用的字符串" -#~ msgid "argument for function \"exp\" too big" -#~ msgstr "对于函数 \"exp\" 傿•°å¤ªå¤§" +#: scan.l:765 scan.l:791 scan.l:806 +msgid "zero-length delimited identifier" +msgstr "长度为0的分隔标示符" -#~ msgid "must be superuser to rotate log files" -#~ msgstr "åªæœ‰è¶…çº§ç”¨æˆ·èƒ½åˆ‡æ¢æ—¥å¿—文件" +#: scan.l:826 syncrep_scanner.l:91 +msgid "unterminated quoted identifier" +msgstr "未结æŸçš„引用标识符" -#~ msgid "must be superuser to signal the postmaster" -#~ msgstr "åªæœ‰è¶…级用户å¯ä»¥å‘é€ä¿¡å·åˆ°postmaster进程" +#: scan.l:989 +msgid "operator too long" +msgstr "æ“作符太长" -#~ msgid "could not format \"circle\" value" -#~ msgstr "无法格å¼åŒ– \"circle\" 的值" +#. translator: %s is typically the translation of "syntax error" +#: scan.l:1141 +#, c-format +msgid "%s at end of input" +msgstr "%s 在输入的末尾" -#~ msgid "invalid input syntax for type circle: \"%s\"" -#~ msgstr "无效的 circle 类型输入语法: \"%s\"" +#. translator: first %s is typically the translation of "syntax error" +#: scan.l:1149 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s 在 \"%s\" 或附近的" -#~ msgid "invalid input syntax for type polygon: \"%s\"" -#~ msgstr "无效的 polygon 类型输入语法: \"%s\"" +#: scan.l:1314 scan.l:1346 +msgid "Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8" +msgstr "当æœåŠ¡å™¨çš„ç¼–ç ä¸æ˜¯UTF8时,无法为在007F以上的ç ç‚¹å€¼ä½¿ç”¨Unicode转义值." -#~ msgid "invalid input syntax for type lseg: \"%s\"" -#~ msgstr "无效的 lseg 类型输入语法: \"%s\"" +#: scan.l:1342 scan.l:1487 +msgid "invalid Unicode escape value" +msgstr "无效的Unicode转义值" -#~ msgid "invalid input syntax for type point: \"%s\"" -#~ msgstr "无效的 point 类型输入语法: \"%s\"" +#: scan.l:1551 +#, c-format +msgid "nonstandard use of \\' in a string literal" +msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用\\'" -#~ msgid "invalid input syntax for type path: \"%s\"" -#~ msgstr "无效的 path 类型输入语法: \"%s\"" +#: scan.l:1552 +#, c-format +msgid "Use '' to write quotes in strings, or use the escape string syntax (E'...')." +msgstr "使用''或者转义字符串语法(E'...')将字符串引起æ¥." -#~ msgid "invalid input syntax for type line: \"%s\"" -#~ msgstr "无效的 line 类型输入语法: \"%s\"" +#: scan.l:1561 +#, c-format +msgid "nonstandard use of \\\\ in a string literal" +msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用\\\\ " -#~ msgid "invalid input syntax for type box: \"%s\"" -#~ msgstr "无效的 box 类型输入语法: \"%s\"" +#: scan.l:1562 +#, c-format +msgid "Use the escape string syntax for backslashes, e.g., E'\\\\'." +msgstr "ä¸ºåæ–œçº¿ä½¿ç”¨è½¬ç§»å­—符串语法,例如.,E'\\\\'." -#~ msgid "could not format \"path\" value" -#~ msgstr "无法格å¼åŒ– \"path\" 值" +#: scan.l:1576 +#, c-format +msgid "nonstandard use of escape in a string literal" +msgstr "在字符串常é‡ä¸­ä»¥ä¸æ ‡å‡†çš„æ–¹æ³•使用转义字符" -#~ msgid "multibyte flag character is not allowed" -#~ msgstr "ä¸å…许使用多字节标志字符" +#: scan.l:1577 +#, c-format +msgid "Use the escape string syntax for escapes, e.g., E'\\r\\n'." +msgstr "对转移字符使用转义字符串语法,例如 E'\\r\\n'." diff --git a/src/backend/port/.gitignore b/src/backend/port/.gitignore index 9f4f1af5e93..4ef36b82c77 100644 --- a/src/backend/port/.gitignore +++ b/src/backend/port/.gitignore @@ -1,4 +1,3 @@ -/dynloader.c /pg_sema.c /pg_shmem.c /tas.s diff --git a/src/backend/port/Makefile b/src/backend/port/Makefile index aba1e92fe1f..f4120bec55f 100644 --- a/src/backend/port/Makefile +++ b/src/backend/port/Makefile @@ -21,7 +21,7 @@ subdir = src/backend/port top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -OBJS = atomics.o dynloader.o pg_sema.o pg_shmem.o $(TAS) +OBJS = atomics.o pg_sema.o pg_shmem.o $(TAS) ifeq ($(PORTNAME), win32) SUBDIRS += win32 diff --git a/src/backend/port/atomics.c b/src/backend/port/atomics.c index caa84bf2b62..5209deeb688 100644 --- a/src/backend/port/atomics.c +++ b/src/backend/port/atomics.c @@ -3,7 +3,7 @@ * atomics.c * Non-Inline parts of the atomics implementation * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/port/dynloader/aix.c b/src/backend/port/dynloader/aix.c deleted file mode 100644 index bf6ec257e77..00000000000 --- a/src/backend/port/dynloader/aix.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * src/backend/port/dynloader/aix.c - * - * Dummy file used for nothing at this point - * - * see aix.h - */ diff --git a/src/backend/port/dynloader/aix.h b/src/backend/port/dynloader/aix.h deleted file mode 100644 index df4f5d5a1a7..00000000000 --- a/src/backend/port/dynloader/aix.h +++ /dev/null @@ -1,39 +0,0 @@ -/*------------------------------------------------------------------------- - * - * aix.h - * prototypes for AIX-specific routines - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/aix.h - * - *------------------------------------------------------------------------- - */ - -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym(h, f) ((PGFunction) dlsym(h, f)) -#define pg_dlclose(h) dlclose(h) -#define pg_dlerror() dlerror() - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/cygwin.c b/src/backend/port/dynloader/cygwin.c deleted file mode 100644 index 5c52bf61476..00000000000 --- a/src/backend/port/dynloader/cygwin.c +++ /dev/null @@ -1,3 +0,0 @@ -/* src/backend/port/dynloader/cygwin.c */ - -/* Dummy file used for nothing at this point; see cygwin.h */ diff --git a/src/backend/port/dynloader/cygwin.h b/src/backend/port/dynloader/cygwin.h deleted file mode 100644 index ef05e6b4161..00000000000 --- a/src/backend/port/dynloader/cygwin.h +++ /dev/null @@ -1,36 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Dynamic loader declarations for Cygwin - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/cygwin.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym dlsym -#define pg_dlclose dlclose -#define pg_dlerror dlerror - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/darwin.c b/src/backend/port/dynloader/darwin.c deleted file mode 100644 index 93f19878f56..00000000000 --- a/src/backend/port/dynloader/darwin.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Dynamic loading support for macOS (Darwin) - * - * If dlopen() is available (Darwin 10.3 and later), we just use it. - * Otherwise we emulate it with the older, now deprecated, NSLinkModule API. - * - * src/backend/port/dynloader/darwin.c - */ -#include "postgres.h" - -#ifdef HAVE_DLOPEN -#include -#else -#include -#endif - -#include "dynloader.h" - - -#ifdef HAVE_DLOPEN - -void * -pg_dlopen(const char *filename) -{ - return dlopen(filename, RTLD_NOW | RTLD_GLOBAL); -} - -void -pg_dlclose(void *handle) -{ - dlclose(handle); -} - -PGFunction -pg_dlsym(void *handle, const char *funcname) -{ - /* Do not prepend an underscore: see dlopen(3) */ - return dlsym(handle, funcname); -} - -char * -pg_dlerror(void) -{ - return dlerror(); -} -#else /* !HAVE_DLOPEN */ - -/* - * These routines were taken from the Apache source, but were made - * available with a PostgreSQL-compatible license. Kudos Wilfredo - * Sánchez . - */ - -static NSObjectFileImageReturnCode cofiff_result = NSObjectFileImageFailure; - -void * -pg_dlopen(const char *filename) -{ - NSObjectFileImage image; - - cofiff_result = NSCreateObjectFileImageFromFile(filename, &image); - if (cofiff_result != NSObjectFileImageSuccess) - return NULL; - return NSLinkModule(image, filename, - NSLINKMODULE_OPTION_BINDNOW | - NSLINKMODULE_OPTION_RETURN_ON_ERROR); -} - -void -pg_dlclose(void *handle) -{ - NSUnLinkModule(handle, NSUNLINKMODULE_OPTION_NONE); -} - -PGFunction -pg_dlsym(void *handle, const char *funcname) -{ - NSSymbol symbol; - char *symname = (char *) malloc(strlen(funcname) + 2); - - if (!symname) - return NULL; - - sprintf(symname, "_%s", funcname); - if (NSIsSymbolNameDefined(symname)) - { - symbol = NSLookupAndBindSymbol(symname); - - free(symname); - return (PGFunction) NSAddressOfSymbol(symbol); - } - else - { - free(symname); - return NULL; - } -} - -char * -pg_dlerror(void) -{ - NSLinkEditErrors c; - int errorNumber; - const char *fileName; - const char *errorString = NULL; - - switch (cofiff_result) - { - case NSObjectFileImageSuccess: - /* must have failed in NSLinkModule */ - NSLinkEditError(&c, &errorNumber, &fileName, &errorString); - if (errorString == NULL || *errorString == '\0') - errorString = "unknown link-edit failure"; - break; - case NSObjectFileImageFailure: - errorString = "failed to open object file"; - break; - case NSObjectFileImageInappropriateFile: - errorString = "inappropriate object file"; - break; - case NSObjectFileImageArch: - errorString = "object file is for wrong architecture"; - break; - case NSObjectFileImageFormat: - errorString = "object file has wrong format"; - break; - case NSObjectFileImageAccess: - errorString = "insufficient permissions for object file"; - break; - default: - errorString = "unknown failure to open object file"; - break; - } - - return (char *) errorString; -} - -#endif /* HAVE_DLOPEN */ diff --git a/src/backend/port/dynloader/darwin.h b/src/backend/port/dynloader/darwin.h deleted file mode 100644 index 292a31de131..00000000000 --- a/src/backend/port/dynloader/darwin.h +++ /dev/null @@ -1,8 +0,0 @@ -/* src/backend/port/dynloader/darwin.h */ - -#include "fmgr.h" - -void *pg_dlopen(const char *filename); -PGFunction pg_dlsym(void *handle, const char *funcname); -void pg_dlclose(void *handle); -char *pg_dlerror(void); diff --git a/src/backend/port/dynloader/freebsd.c b/src/backend/port/dynloader/freebsd.c deleted file mode 100644 index 54ee0e84482..00000000000 --- a/src/backend/port/dynloader/freebsd.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * src/backend/port/dynloader/freebsd.c - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91"; -#endif /* LIBC_SCCS and not lint */ - -#include "postgres.h" - -#include -#include -#include - -#include "dynloader.h" - -static char error_message[BUFSIZ]; - -char * -BSD44_derived_dlerror(void) -{ - static char ret[BUFSIZ]; - - strcpy(ret, error_message); - error_message[0] = 0; - return (ret[0] == 0) ? NULL : ret; -} - -void * -BSD44_derived_dlopen(const char *file, int num) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) not supported", file); - return NULL; -#else - void *vp; - - if ((vp = dlopen((char *) file, num)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) failed: %s", file, dlerror()); - return vp; -#endif -} - -void * -BSD44_derived_dlsym(void *handle, const char *name) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return NULL; -#else - void *vp; - -#ifndef __ELF__ - char buf[BUFSIZ]; - - if (*name != '_') - { - snprintf(buf, sizeof(buf), "_%s", name); - name = buf; - } -#endif /* !__ELF__ */ - if ((vp = dlsym(handle, (char *) name)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return vp; -#endif -} - -void -BSD44_derived_dlclose(void *handle) -{ -#if defined(HAVE_DLOPEN) - dlclose(handle); -#endif -} diff --git a/src/backend/port/dynloader/freebsd.h b/src/backend/port/dynloader/freebsd.h deleted file mode 100644 index d047b1662ee..00000000000 --- a/src/backend/port/dynloader/freebsd.h +++ /dev/null @@ -1,58 +0,0 @@ -/*------------------------------------------------------------------------- - * - * freebsd.h - * port-specific prototypes for FreeBSD - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/freebsd.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include -#include - -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * Dynamic Loader on NetBSD 1.0. - * - * this dynamic loader uses the system dynamic loading interface for shared - * libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared - * library as the file to be dynamically loaded. - * - * agc - I know this is all a bit crufty, but it does work, is fairly - * portable, and works (the stipulation that the d.l. function must - * begin with an underscore is fairly tricky, and some versions of - * NetBSD (like 1.0, and 1.0A pre June 1995) have no dlerror.) - */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) BSD44_derived_dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym BSD44_derived_dlsym -#define pg_dlclose BSD44_derived_dlclose -#define pg_dlerror BSD44_derived_dlerror - -char *BSD44_derived_dlerror(void); -void *BSD44_derived_dlopen(const char *filename, int num); -void *BSD44_derived_dlsym(void *handle, const char *name); -void BSD44_derived_dlclose(void *handle); - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/hpux.c b/src/backend/port/dynloader/hpux.c deleted file mode 100644 index d82dd7603bf..00000000000 --- a/src/backend/port/dynloader/hpux.c +++ /dev/null @@ -1,68 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dynloader.c - * dynamic loader for HP-UX using the shared library mechanism - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/port/dynloader/hpux.c - * - * NOTES - * all functions are defined here -- it's impossible to trace the - * shl_* routines from the bundled HP-UX debugger. - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -/* System includes */ -#include -#include - -#include "dynloader.h" -#include "utils/dynamic_loader.h" - -void * -pg_dlopen(const char *filename) -{ - /* - * Use BIND_IMMEDIATE so that undefined symbols cause a failure return - * from shl_load(), rather than an abort() later on when we attempt to - * call the library! - */ - shl_t handle = shl_load(filename, - BIND_IMMEDIATE | BIND_VERBOSE | DYNAMIC_PATH, - 0L); - - return (void *) handle; -} - -PGFunction -pg_dlsym(void *handle, const char *funcname) -{ - PGFunction f; - - if (shl_findsym((shl_t *) & handle, funcname, TYPE_PROCEDURE, &f) == -1) - f = (PGFunction) NULL; - return f; -} - -void -pg_dlclose(void *handle) -{ - shl_unload((shl_t) handle); -} - -char * -pg_dlerror(void) -{ - static char errmsg[] = "shl_load failed"; - - if (errno) - return strerror(errno); - - return errmsg; -} diff --git a/src/backend/port/dynloader/hpux.h b/src/backend/port/dynloader/hpux.h deleted file mode 100644 index 1cbc46960e2..00000000000 --- a/src/backend/port/dynloader/hpux.h +++ /dev/null @@ -1,25 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dynloader.h - * dynamic loader for HP-UX using the shared library mechanism - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/port/dynloader/hpux.h - * - * NOTES - * all functions are defined here -- it's impossible to trace the - * shl_* routines from the bundled HP-UX debugger. - * - *------------------------------------------------------------------------- - */ -/* System includes */ -#include "fmgr.h" - -extern void *pg_dlopen(const char *filename); -extern PGFunction pg_dlsym(void *handle, const char *funcname); -extern void pg_dlclose(void *handle); -extern char *pg_dlerror(void); diff --git a/src/backend/port/dynloader/linux.c b/src/backend/port/dynloader/linux.c deleted file mode 100644 index 8735767add8..00000000000 --- a/src/backend/port/dynloader/linux.c +++ /dev/null @@ -1,133 +0,0 @@ -/*------------------------------------------------------------------------- - * - * linux.c - * Dynamic Loader for Postgres for Linux, generated from those for - * Ultrix. - * - * You need to install the dld library on your Linux system! - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/port/dynloader/linux.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#ifdef HAVE_DLD_H -#include -#endif - -#include "dynloader.h" -#include "miscadmin.h" - - -#ifndef HAVE_DLOPEN - -void * -pg_dlopen(const char *filename) -{ -#ifndef HAVE_DLD_H - elog(ERROR, "dynamic load not supported"); - return NULL; -#else - static int dl_initialized = 0; - - /* - * initializes the dynamic loader with the executable's pathname. (only - * needs to do this the first time pg_dlopen is called.) - */ - if (!dl_initialized) - { - if (dld_init(dld_find_executable(my_exec_path))) - return NULL; - - /* - * if there are undefined symbols, we want dl to search from the - * following libraries also. - */ - dl_initialized = 1; - } - - /* - * link the file, then check for undefined symbols! - */ - if (dld_link(filename)) - return NULL; - - /* - * If undefined symbols: try to link with the C and math libraries! This - * could be smarter, if the dynamic linker was able to handle shared libs! - */ - if (dld_undefined_sym_count > 0) - { - if (dld_link("/usr/lib/libc.a")) - { - elog(WARNING, "could not link C library"); - return NULL; - } - if (dld_undefined_sym_count > 0) - { - if (dld_link("/usr/lib/libm.a")) - { - elog(WARNING, "could not link math library"); - return NULL; - } - if (dld_undefined_sym_count > 0) - { - int count = dld_undefined_sym_count; - char **list = dld_list_undefined_sym(); - - /* list the undefined symbols, if any */ - do - { - elog(WARNING, "\"%s\" is undefined", *list); - list++; - count--; - } while (count > 0); - - dld_unlink_by_file(filename, 1); - return NULL; - } - } - } - - return (void *) strdup(filename); -#endif -} - -PGFunction -pg_dlsym(void *handle, const char *funcname) -{ -#ifndef HAVE_DLD_H - return NULL; -#else - return (PGFunction) dld_get_func((funcname)); -#endif -} - -void -pg_dlclose(void *handle) -{ -#ifndef HAVE_DLD_H -#else - dld_unlink_by_file(handle, 1); - free(handle); -#endif -} - -char * -pg_dlerror(void) -{ -#ifndef HAVE_DLD_H - return "dynaloader unsupported"; -#else - return dld_strerror(dld_errno); -#endif -} - -#endif /* !HAVE_DLOPEN */ diff --git a/src/backend/port/dynloader/linux.h b/src/backend/port/dynloader/linux.h deleted file mode 100644 index df2852ac58b..00000000000 --- a/src/backend/port/dynloader/linux.h +++ /dev/null @@ -1,44 +0,0 @@ -/*------------------------------------------------------------------------- - * - * linux.h - * Port-specific prototypes for Linux - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/linux.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ -#ifdef HAVE_DLOPEN -#include -#endif - - -#ifdef HAVE_DLOPEN - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym dlsym -#define pg_dlclose dlclose -#define pg_dlerror dlerror -#endif /* HAVE_DLOPEN */ - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/netbsd.c b/src/backend/port/dynloader/netbsd.c deleted file mode 100644 index 7b8d90caa76..00000000000 --- a/src/backend/port/dynloader/netbsd.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * src/backend/port/dynloader/netbsd.c - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91"; -#endif /* LIBC_SCCS and not lint */ - -#include "postgres.h" - -#include -#include -#include - -#include "dynloader.h" - -static char error_message[BUFSIZ]; - -char * -BSD44_derived_dlerror(void) -{ - static char ret[BUFSIZ]; - - strcpy(ret, error_message); - error_message[0] = 0; - return (ret[0] == 0) ? NULL : ret; -} - -void * -BSD44_derived_dlopen(const char *file, int num) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) not supported", file); - return NULL; -#else - void *vp; - - if ((vp = dlopen((char *) file, num)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) failed: %s", file, dlerror()); - return vp; -#endif -} - -void * -BSD44_derived_dlsym(void *handle, const char *name) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return NULL; -#else - void *vp; - -#ifndef __ELF__ - char buf[BUFSIZ]; - - if (*name != '_') - { - snprintf(buf, sizeof(buf), "_%s", name); - name = buf; - } -#endif /* !__ELF__ */ - if ((vp = dlsym(handle, (char *) name)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return vp; -#endif -} - -void -BSD44_derived_dlclose(void *handle) -{ -#if defined(HAVE_DLOPEN) - dlclose(handle); -#endif -} diff --git a/src/backend/port/dynloader/netbsd.h b/src/backend/port/dynloader/netbsd.h deleted file mode 100644 index 823574abf02..00000000000 --- a/src/backend/port/dynloader/netbsd.h +++ /dev/null @@ -1,59 +0,0 @@ -/*------------------------------------------------------------------------- - * - * netbsd.h - * port-specific prototypes for NetBSD - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/netbsd.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include -#include - -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * Dynamic Loader on NetBSD 1.0. - * - * this dynamic loader uses the system dynamic loading interface for shared - * libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared - * library as the file to be dynamically loaded. - * - * agc - I know this is all a bit crufty, but it does work, is fairly - * portable, and works (the stipulation that the d.l. function must - * begin with an underscore is fairly tricky, and some versions of - * NetBSD (like 1.0, and 1.0A pre June 1995) have no dlerror.) - */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) BSD44_derived_dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym BSD44_derived_dlsym -#define pg_dlclose BSD44_derived_dlclose -#define pg_dlerror BSD44_derived_dlerror - -char *BSD44_derived_dlerror(void); -void *BSD44_derived_dlopen(const char *filename, int num); -void *BSD44_derived_dlsym(void *handle, const char *name); -void BSD44_derived_dlclose(void *handle); - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/openbsd.c b/src/backend/port/dynloader/openbsd.c deleted file mode 100644 index 2104915c6c7..00000000000 --- a/src/backend/port/dynloader/openbsd.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * src/backend/port/dynloader/openbsd.c - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)dl.c 5.4 (Berkeley) 2/23/91"; -#endif /* LIBC_SCCS and not lint */ - -#include "postgres.h" - -#include -#include -#include - -#include "dynloader.h" - -static char error_message[BUFSIZ]; - -char * -BSD44_derived_dlerror(void) -{ - static char ret[BUFSIZ]; - - strcpy(ret, error_message); - error_message[0] = 0; - return (ret[0] == 0) ? NULL : ret; -} - -void * -BSD44_derived_dlopen(const char *file, int num) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) not supported", file); - return NULL; -#else - void *vp; - - if ((vp = dlopen((char *) file, num)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlopen (%s) failed: %s", file, dlerror()); - return vp; -#endif -} - -void * -BSD44_derived_dlsym(void *handle, const char *name) -{ -#if !defined(HAVE_DLOPEN) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return NULL; -#else - void *vp; - -#ifndef __ELF__ - char buf[BUFSIZ]; - - if (*name != '_') - { - snprintf(buf, sizeof(buf), "_%s", name); - name = buf; - } -#endif /* !__ELF__ */ - if ((vp = dlsym(handle, (char *) name)) == NULL) - snprintf(error_message, sizeof(error_message), - "dlsym (%s) failed", name); - return vp; -#endif -} - -void -BSD44_derived_dlclose(void *handle) -{ -#if defined(HAVE_DLOPEN) - dlclose(handle); -#endif -} diff --git a/src/backend/port/dynloader/openbsd.h b/src/backend/port/dynloader/openbsd.h deleted file mode 100644 index a184ca8ecd2..00000000000 --- a/src/backend/port/dynloader/openbsd.h +++ /dev/null @@ -1,58 +0,0 @@ -/*------------------------------------------------------------------------- - * - * openbsd.h - * port-specific prototypes for OpenBSD - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/openbsd.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include -#include - -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * Dynamic Loader on NetBSD 1.0. - * - * this dynamic loader uses the system dynamic loading interface for shared - * libraries (ie. dlopen/dlsym/dlclose). The user must specify a shared - * library as the file to be dynamically loaded. - * - * agc - I know this is all a bit crufty, but it does work, is fairly - * portable, and works (the stipulation that the d.l. function must - * begin with an underscore is fairly tricky, and some versions of - * NetBSD (like 1.0, and 1.0A pre June 1995) have no dlerror.) - */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) BSD44_derived_dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym BSD44_derived_dlsym -#define pg_dlclose BSD44_derived_dlclose -#define pg_dlerror BSD44_derived_dlerror - -char *BSD44_derived_dlerror(void); -void *BSD44_derived_dlopen(const char *filename, int num); -void *BSD44_derived_dlsym(void *handle, const char *name); -void BSD44_derived_dlclose(void *handle); - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/solaris.c b/src/backend/port/dynloader/solaris.c deleted file mode 100644 index 19adcedc5e6..00000000000 --- a/src/backend/port/dynloader/solaris.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * src/backend/port/dynloader/solaris.c - * - * Dummy file used for nothing at this point - * - * see solaris.h - */ diff --git a/src/backend/port/dynloader/solaris.h b/src/backend/port/dynloader/solaris.h deleted file mode 100644 index b583c266cfa..00000000000 --- a/src/backend/port/dynloader/solaris.h +++ /dev/null @@ -1,38 +0,0 @@ -/*------------------------------------------------------------------------- - * - * solaris.h - * port-specific prototypes for Solaris - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/backend/port/dynloader/solaris.h - * - *------------------------------------------------------------------------- - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -/* - * In some older systems, the RTLD_NOW flag isn't defined and the mode - * argument to dlopen must always be 1. The RTLD_GLOBAL flag is wanted - * if available, but it doesn't exist everywhere. - * If it doesn't exist, set it to 0 so it has no effect. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define pg_dlopen(f) dlopen((f), RTLD_NOW | RTLD_GLOBAL) -#define pg_dlsym dlsym -#define pg_dlclose dlclose -#define pg_dlerror dlerror - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/dynloader/win32.c b/src/backend/port/dynloader/win32.c deleted file mode 100644 index c59823e3675..00000000000 --- a/src/backend/port/dynloader/win32.c +++ /dev/null @@ -1,85 +0,0 @@ -/* src/backend/port/dynloader/win32.c */ - -#include "postgres.h" - -char *dlerror(void); -int dlclose(void *handle); -void *dlsym(void *handle, const char *symbol); -void *dlopen(const char *path, int mode); - -static char last_dyn_error[512]; - -static void -set_dl_error(void) -{ - DWORD err = GetLastError(); - - if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - err, - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - last_dyn_error, - sizeof(last_dyn_error) - 1, - NULL) == 0) - { - snprintf(last_dyn_error, sizeof(last_dyn_error) - 1, - "unknown error %lu", err); - } -} - -char * -dlerror(void) -{ - if (last_dyn_error[0]) - return last_dyn_error; - else - return NULL; -} - -int -dlclose(void *handle) -{ - if (!FreeLibrary((HMODULE) handle)) - { - set_dl_error(); - return 1; - } - last_dyn_error[0] = 0; - return 0; -} - -void * -dlsym(void *handle, const char *symbol) -{ - void *ptr; - - ptr = GetProcAddress((HMODULE) handle, symbol); - if (!ptr) - { - set_dl_error(); - return NULL; - } - last_dyn_error[0] = 0; - return ptr; -} - -void * -dlopen(const char *path, int mode) -{ - HMODULE h; - int prevmode; - - /* Disable popup error messages when loading DLLs */ - prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); - h = LoadLibrary(path); - SetErrorMode(prevmode); - - if (!h) - { - set_dl_error(); - return NULL; - } - last_dyn_error[0] = 0; - return (void *) h; -} diff --git a/src/backend/port/dynloader/win32.h b/src/backend/port/dynloader/win32.h deleted file mode 100644 index ddbf8665201..00000000000 --- a/src/backend/port/dynloader/win32.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * src/backend/port/dynloader/win32.h - */ -#ifndef PORT_PROTOS_H -#define PORT_PROTOS_H - -#include "utils/dynamic_loader.h" /* pgrminclude ignore */ - -#define pg_dlopen(f) dlopen((f), 1) -#define pg_dlsym dlsym -#define pg_dlclose dlclose -#define pg_dlerror dlerror - -char *dlerror(void); -int dlclose(void *handle); -void *dlsym(void *handle, const char *symbol); -void *dlopen(const char *path, int mode); - -#endif /* PORT_PROTOS_H */ diff --git a/src/backend/port/posix_sema.c b/src/backend/port/posix_sema.c index a2cabe58fcb..bdd6552f614 100644 --- a/src/backend/port/posix_sema.c +++ b/src/backend/port/posix_sema.c @@ -15,7 +15,7 @@ * forked backends, but they could not be accessed by exec'd backends. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -29,6 +29,7 @@ #include #include #include +#include #include "miscadmin.h" #include "storage/ipc.h" @@ -41,13 +42,19 @@ #error cannot use named POSIX semaphores with EXEC_BACKEND #endif +typedef union SemTPadded +{ + sem_t pgsem; + char pad[PG_CACHE_LINE_SIZE]; +} SemTPadded; + /* typedef PGSemaphore is equivalent to pointer to sem_t */ typedef struct PGSemaphoreData { - sem_t pgsem; + SemTPadded sem_padded; } PGSemaphoreData; -#define PG_SEM_REF(x) (&(x)->pgsem) +#define PG_SEM_REF(x) (&(x)->sem_padded.pgsem) #define IPCProtection (0600) /* access/modify by user only */ @@ -175,23 +182,33 @@ PGSemaphoreShmemSize(int maxSemas) * are acquired here or in PGSemaphoreCreate, register an on_shmem_exit * callback to release them. * - * The port number is passed for possible use as a key (for Posix, we use - * it to generate the starting semaphore name). In a standalone backend, - * zero will be passed. - * * In the Posix implementation, we acquire semaphores on-demand; the * maxSemas parameter is just used to size the arrays. For unnamed * semaphores, there is an array of PGSemaphoreData structs in shared memory. * For named semaphores, we keep a postmaster-local array of sem_t pointers, - * which we use for releasing the semphores when done. + * which we use for releasing the semaphores when done. * (This design minimizes the dependency of postmaster shutdown on the * contents of shared memory, which a failed backend might have clobbered. * We can't do much about the possibility of sem_destroy() crashing, but * we don't have to expose the counters to other processes.) */ void -PGReserveSemaphores(int maxSemas, int port) +PGReserveSemaphores(int maxSemas) { + struct stat statbuf; + + /* + * We use the data directory's inode number to seed the search for free + * semaphore keys. This minimizes the odds of collision with other + * postmasters, while maximizing the odds that we will detect and clean up + * semaphores left over from a crashed postmaster in our own directory. + */ + if (stat(DataDir, &statbuf) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not stat data directory \"%s\": %m", + DataDir))); + #ifdef USE_NAMED_POSIX_SEMAPHORES mySemPointers = (sem_t **) malloc(maxSemas * sizeof(sem_t *)); if (mySemPointers == NULL) @@ -209,7 +226,7 @@ PGReserveSemaphores(int maxSemas, int port) numSems = 0; maxSems = maxSemas; - nextSemKey = port * 1000; + nextSemKey = statbuf.st_ino; on_shmem_exit(ReleaseSemaphores, 0); } diff --git a/src/backend/port/sysv_sema.c b/src/backend/port/sysv_sema.c index 1c178a73179..a1652cce59c 100644 --- a/src/backend/port/sysv_sema.c +++ b/src/backend/port/sysv_sema.c @@ -4,7 +4,7 @@ * Implement PGSemaphores using SysV semaphore facilities * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef HAVE_SYS_IPC_H #include #endif @@ -72,9 +73,9 @@ static int nextSemaNumber; /* next free sem num in last sema set */ static IpcSemaphoreId InternalIpcSemaphoreCreate(IpcSemaphoreKey semKey, - int numSems); + int numSems); static void IpcSemaphoreInitialize(IpcSemaphoreId semId, int semNum, - int value); + int value); static void IpcSemaphoreKill(IpcSemaphoreId semId); static int IpcSemaphoreGetValue(IpcSemaphoreId semId, int semNum); static pid_t IpcSemaphoreGetLastPID(IpcSemaphoreId semId, int semNum); @@ -301,10 +302,6 @@ PGSemaphoreShmemSize(int maxSemas) * are acquired here or in PGSemaphoreCreate, register an on_shmem_exit * callback to release them. * - * The port number is passed for possible use as a key (for SysV, we use - * it to generate the starting semaphore key). In a standalone backend, - * zero will be passed. - * * In the SysV implementation, we acquire semaphore sets on-demand; the * maxSemas parameter is just used to size the arrays. There is an array * of PGSemaphoreData structs in shared memory, and a postmaster-local array @@ -314,8 +311,22 @@ PGSemaphoreShmemSize(int maxSemas) * have clobbered.) */ void -PGReserveSemaphores(int maxSemas, int port) +PGReserveSemaphores(int maxSemas) { + struct stat statbuf; + + /* + * We use the data directory's inode number to seed the search for free + * semaphore keys. This minimizes the odds of collision with other + * postmasters, while maximizing the odds that we will detect and clean up + * semaphores left over from a crashed postmaster in our own directory. + */ + if (stat(DataDir, &statbuf) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not stat data directory \"%s\": %m", + DataDir))); + /* * We must use ShmemAllocUnlocked(), since the spinlock protecting * ShmemAlloc() won't be ready yet. (This ordering is necessary when we @@ -332,7 +343,7 @@ PGReserveSemaphores(int maxSemas, int port) if (mySemaSets == NULL) elog(PANIC, "out of memory"); numSemaSets = 0; - nextSemaKey = port * 1000; + nextSemaKey = statbuf.st_ino; nextSemaNumber = SEMAS_PER_SET; /* force sema set alloc on 1st call */ on_shmem_exit(ReleaseSemaphores, 0); diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index 741c455ccbc..278e483eddc 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -9,7 +9,7 @@ * exist, though, because mmap'd shmem provides no way to find out how * many processes are attached, which we need for interlocking purposes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -32,7 +32,9 @@ #endif #include "miscadmin.h" +#include "common/file_perm.h" #include "portability/mem.h" +#include "postmaster/postmaster.h" #include "storage/dsm.h" #include "storage/fd.h" #include "storage/ipc.h" @@ -40,7 +42,6 @@ #include "utils/guc.h" #include "utils/pidfile.h" - /* * As of PostgreSQL 9.3, we normally allocate only a very small amount of * System V shared memory, and only for the purposes of providing an @@ -62,29 +63,50 @@ * to a process after exec(). Since EXEC_BACKEND is intended only for * developer use, this shouldn't be a big problem. Because of this, we do * not worry about supporting anonymous shmem in the EXEC_BACKEND cases below. + * + * As of PostgreSQL 12, we regained the ability to use a large System V shared + * memory region even in non-EXEC_BACKEND builds, if shared_memory_type is set + * to sysv (though this is not the default). */ -#ifndef EXEC_BACKEND -#define USE_ANONYMOUS_SHMEM -#endif typedef key_t IpcMemoryKey; /* shared memory key passed to shmget(2) */ typedef int IpcMemoryId; /* shared memory ID returned by shmget(2) */ +/* + * How does a given IpcMemoryId relate to this PostgreSQL process? + * + * One could recycle unattached segments of different data directories if we + * distinguished that case from other SHMSTATE_FOREIGN cases. Doing so would + * cause us to visit less of the key space, making us less likely to detect a + * SHMSTATE_ATTACHED key. It would also complicate the concurrency analysis, + * in that postmasters of different data directories could simultaneously + * attempt to recycle a given key. We'll waste keys longer in some cases, but + * avoiding the problems of the alternative justifies that loss. + */ +typedef enum +{ + SHMSTATE_ANALYSIS_FAILURE, /* unexpected failure to analyze the ID */ + SHMSTATE_ATTACHED, /* pertinent to DataDir, has attached PIDs */ + SHMSTATE_ENOENT, /* no segment of that ID */ + SHMSTATE_FOREIGN, /* exists, but not pertinent to DataDir */ + SHMSTATE_UNATTACHED /* pertinent to DataDir, no attached PIDs */ +} IpcMemoryState; + unsigned long UsedShmemSegID = 0; void *UsedShmemSegAddr = NULL; -#ifdef USE_ANONYMOUS_SHMEM +void *AnonymousShmem = NULL; +int AnonymousShmemFile = -1; static Size AnonymousShmemSize; -static void *AnonymousShmem = NULL; -#endif static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size); static void IpcMemoryDetach(int status, Datum shmaddr); static void IpcMemoryDelete(int status, Datum shmId); -static PGShmemHeader *PGSharedMemoryAttach(IpcMemoryKey key, - IpcMemoryId *shmid); +static IpcMemoryState PGSharedMemoryAttach(IpcMemoryId shmId, + void *attachAt, + PGShmemHeader **addr); /* @@ -105,7 +127,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) IpcMemoryId shmid; void *requestedAddress = NULL; void *memAddress; - + int mode = IPC_CREAT | IPC_EXCL | IPCProtection; /* * Normally we just pass requestedAddress = NULL to shmat(), allowing the * system to choose where the segment gets mapped. But in an EXEC_BACKEND @@ -116,21 +138,21 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) * interest for anything except debugging, we'd probably create a cleaner * and better-documented way to set it, such as a GUC.) */ -#ifdef EXEC_BACKEND { char *pg_shmem_addr = getenv("PG_SHMEM_ADDR"); if (pg_shmem_addr) requestedAddress = (void *) strtoul(pg_shmem_addr, NULL, 0); } -#endif - - shmid = shmget(memKey, size, IPC_CREAT | IPC_EXCL | IPCProtection); + if (IsOnlineUpgrade) + { + mode &= ~IPC_EXCL; + } + shmid = shmget(memKey, size, mode); if (shmid < 0) { int shmget_errno = errno; - /* * Fail quietly if error indicates a collision with existing segment. * One would expect EEXIST, given that we said IPC_EXCL, but perhaps @@ -155,7 +177,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) */ if (shmget_errno == EINVAL) { - shmid = shmget(memKey, 0, IPC_CREAT | IPC_EXCL | IPCProtection); + shmid = shmget(memKey, 0, mode); if (shmid < 0) { @@ -196,7 +218,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) (errmsg("could not create shared memory segment: %m"), errdetail("Failed system call was shmget(key=%lu, size=%zu, 0%o).", (unsigned long) memKey, size, - IPC_CREAT | IPC_EXCL | IPCProtection), + mode), (shmget_errno == EINVAL) ? errhint("This error usually means that PostgreSQL's request for a shared memory " "segment exceeded your kernel's SHMMAX parameter, or possibly that " @@ -229,7 +251,7 @@ InternalIpcMemoryCreate(IpcMemoryKey memKey, Size size) if (memAddress == (void *) -1) elog(FATAL, "shmat(id=%d, addr=%p, flags=0x%x) failed: %m", shmid, requestedAddress, PG_SHMAT_FLAGS); - + elog(LOG, "Map shared memory to %p", memAddress); /* Register on-exit routine to detach new segment before deleting */ on_shmem_exit(IpcMemoryDetach, PointerGetDatum(memAddress)); @@ -269,9 +291,12 @@ IpcMemoryDetach(int status, Datum shmaddr) static void IpcMemoryDelete(int status, Datum shmId) { - if (shmctl(DatumGetInt32(shmId), IPC_RMID, NULL) < 0) - elog(LOG, "shmctl(%d, %d, 0) failed: %m", - DatumGetInt32(shmId), IPC_RMID); + if (!IsOnlineUpgrade) + { + if (shmctl(DatumGetInt32(shmId), IPC_RMID, NULL) < 0) + elog(LOG, "shmctl(%d, %d, 0) failed: %m", + DatumGetInt32(shmId), IPC_RMID); + } } /* @@ -288,14 +313,46 @@ IpcMemoryDelete(int status, Datum shmId) bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) { - IpcMemoryId shmId = (IpcMemoryId) id2; + PGShmemHeader *memAddress; + IpcMemoryState state; + + state = PGSharedMemoryAttach((IpcMemoryId) id2, NULL, &memAddress); + if (memAddress && shmdt(memAddress) < 0) + elog(LOG, "shmdt(%p) failed: %m", memAddress); + switch (state) + { + case SHMSTATE_ENOENT: + case SHMSTATE_FOREIGN: + case SHMSTATE_UNATTACHED: + return false; + case SHMSTATE_ANALYSIS_FAILURE: + case SHMSTATE_ATTACHED: + return true; + } + return true; +} + +/* + * Test for a segment with id shmId; see comment at IpcMemoryState. + * + * If the segment exists, we'll attempt to attach to it, using attachAt + * if that's not NULL (but it's best to pass NULL if possible). + * + * *addr is set to the segment memory address if we attached to it, else NULL. + */ +static IpcMemoryState +PGSharedMemoryAttach(IpcMemoryId shmId, + void *attachAt, + PGShmemHeader **addr) +{ struct shmid_ds shmStat; struct stat statbuf; PGShmemHeader *hdr; + *addr = NULL; + /* - * We detect whether a shared memory segment is in use by seeing whether - * it (a) exists and (b) has any processes attached to it. + * First, try to stat the shm segment ID, to see if it exists at all. */ if (shmctl(shmId, IPC_STAT, &shmStat) < 0) { @@ -305,15 +362,15 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) * exists. */ if (errno == EINVAL) - return false; + return SHMSTATE_ENOENT; /* - * EACCES implies that the segment belongs to some other userid, which - * means it is not a Postgres shmem segment (or at least, not one that - * is relevant to our data directory). + * EACCES implies we have no read permission, which means it is not a + * Postgres shmem segment (or at least, not one that is relevant to + * our data directory). */ if (errno == EACCES) - return false; + return SHMSTATE_FOREIGN; /* * Some Linux kernel versions (in fact, all of them as of July 2007) @@ -324,33 +381,55 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) */ #ifdef HAVE_LINUX_EIDRM_BUG if (errno == EIDRM) - return false; + return SHMSTATE_ENOENT; #endif /* - * Otherwise, we had better assume that the segment is in use. The - * only likely case is EIDRM, which implies that the segment has been - * IPC_RMID'd but there are still processes attached to it. + * Otherwise, we had better assume that the segment is in use. The + * only likely case is (non-Linux, assumed spec-compliant) EIDRM, + * which implies that the segment has been IPC_RMID'd but there are + * still processes attached to it. */ - return true; + return SHMSTATE_ANALYSIS_FAILURE; } - /* If it has no attached processes, it's not in use */ - if (shmStat.shm_nattch == 0) - return false; - /* * Try to attach to the segment and see if it matches our data directory. - * This avoids shmid-conflict problems on machines that are running - * several postmasters under the same userid. + * This avoids any risk of duplicate-shmem-key conflicts on machines that + * are running several postmasters under the same userid. + * + * (When we're called from PGSharedMemoryCreate, this stat call is + * duplicative; but since this isn't a high-traffic case it's not worth + * trying to optimize.) */ if (stat(DataDir, &statbuf) < 0) - return true; /* if can't stat, be conservative */ - - hdr = (PGShmemHeader *) shmat(shmId, NULL, PG_SHMAT_FLAGS); + return SHMSTATE_ANALYSIS_FAILURE; /* can't stat; be conservative */ + hdr = (PGShmemHeader *) shmat(shmId, attachAt, PG_SHMAT_FLAGS); if (hdr == (PGShmemHeader *) -1) - return true; /* if can't attach, be conservative */ + { + /* + * Attachment failed. The cases we're interested in are the same as + * for the shmctl() call above. In particular, note that the owning + * postmaster could have terminated and removed the segment between + * shmctl() and shmat(). + * + * If attachAt isn't NULL, it's possible that EINVAL reflects a + * problem with that address not a vanished segment, so it's best to + * pass NULL when probing for conflicting segments. + */ + if (errno == EINVAL) + return SHMSTATE_ENOENT; /* segment disappeared */ + if (errno == EACCES) + return SHMSTATE_FOREIGN; /* must be non-Postgres */ +#ifdef HAVE_LINUX_EIDRM_BUG + if (errno == EIDRM) + return SHMSTATE_ENOENT; /* segment disappeared */ +#endif + /* Otherwise, be conservative. */ + return SHMSTATE_ANALYSIS_FAILURE; + } + *addr = hdr; if (hdr->magic != PGShmemMagic || hdr->device != statbuf.st_dev || @@ -358,20 +437,19 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) { /* * It's either not a Postgres segment, or not one for my data - * directory. In either case it poses no threat. + * directory. */ - shmdt((void *) hdr); - return false; + return SHMSTATE_FOREIGN; } - /* Trouble --- looks a lot like there's still live backends */ - shmdt((void *) hdr); - - return true; + /* + * It does match our data directory, so now test whether any processes are + * still attached to it. (We are, now, but the shm_nattch result is from + * before we attached to it.) + */ + return shmStat.shm_nattch == 0 ? SHMSTATE_UNATTACHED : SHMSTATE_ATTACHED; } -#ifdef USE_ANONYMOUS_SHMEM - #ifdef MAP_HUGETLB /* @@ -459,6 +537,36 @@ CreateAnonymousSegment(Size *size) Size allocsize = *size; void *ptr = MAP_FAILED; int mmap_errno = 0; + int fd = -1; + void *hint = NULL; + int mmap_flags = PG_MMAP_FLAGS; + + if (shared_memory_type == SHMEM_TYPE_POSIX) + { + mmap_flags &= ~MAP_ANONYMOUS; + if (IsOnlineUpgrade) + { + Assert(AnonymousShmemFile >= 0); + fd = AnonymousShmemFile; + mmap_flags |= MAP_FIXED; + hint = AnonymousShmem; + } + else + { + int flags; + char path[64]; + sprintf(path, "/%d", MyProcPid); + fd = shm_open(path, O_CREAT|O_TRUNC|O_RDWR, pg_file_create_mode); + if (fd < 0) + ereport(FATAL, + (errmsg("could not create shared memory object: %m"), 0)); + AnonymousShmemFile = fd; + shm_unlink(path); + flags = fcntl(fd, F_GETFD); + flags &= ~FD_CLOEXEC; + fcntl(fd, F_SETFD, flags); + } + } #ifndef MAP_HUGETLB /* PGSharedMemoryCreate should have dealt with this case */ @@ -470,15 +578,21 @@ CreateAnonymousSegment(Size *size) * Round up the request size to a suitable large value. */ Size hugepagesize; - int mmap_flags; + int huge_flags; - GetHugePageSize(&hugepagesize, &mmap_flags); + GetHugePageSize(&hugepagesize, &huge_flags); if (allocsize % hugepagesize != 0) allocsize += hugepagesize - (allocsize % hugepagesize); - ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, - PG_MMAP_FLAGS | mmap_flags, -1, 0); + if (fd >= 0 && !IsOnlineUpgrade) + { + if (ftruncate(fd, allocsize) < 0) + ereport(FATAL, + (errmsg("could not truncate shared memory file: %m"), 0)); + } + ptr = mmap(hint, allocsize, PROT_READ | PROT_WRITE, + huge_flags | mmap_flags, fd, 0); mmap_errno = errno; if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED) elog(DEBUG1, "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m", @@ -493,8 +607,14 @@ CreateAnonymousSegment(Size *size) * to non-huge pages. */ allocsize = *size; - ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, - PG_MMAP_FLAGS, -1, 0); + if (fd >= 0 && !IsOnlineUpgrade) + { + if (ftruncate(fd, allocsize) < 0) + ereport(FATAL, + (errmsg("could not truncate shared memory file: %m"), 0)); + } + ptr = mmap(hint, allocsize, PROT_READ | PROT_WRITE, + mmap_flags, fd, 0); mmap_errno = errno; } @@ -534,8 +654,6 @@ AnonymousShmemDetach(int status, Datum arg) } } -#endif /* USE_ANONYMOUS_SHMEM */ - /* * PGSharedMemoryCreate * @@ -543,30 +661,34 @@ AnonymousShmemDetach(int status, Datum arg) * standard header. Also, register an on_shmem_exit callback to release * the storage. * - * Dead Postgres segments are recycled if found, but we do not fail upon - * collision with non-Postgres shmem segments. The idea here is to detect and - * re-use keys that may have been assigned by a crashed postmaster or backend. - * - * makePrivate means to always create a new segment, rather than attach to - * or recycle any existing segment. - * - * The port number is passed for possible use as a key (for SysV, we use - * it to generate the starting shmem key). In a standalone backend, - * zero will be passed. + * Dead Postgres segments pertinent to this DataDir are recycled if found, but + * we do not fail upon collision with foreign shmem segments. The idea here + * is to detect and re-use keys that may have been assigned by a crashed + * postmaster or backend. */ PGShmemHeader * -PGSharedMemoryCreate(Size size, bool makePrivate, int port, +PGSharedMemoryCreate(Size size, PGShmemHeader **shim) { IpcMemoryKey NextShmemSegID; void *memAddress; PGShmemHeader *hdr; - IpcMemoryId shmid; struct stat statbuf; Size sysvsize; + /* + * We use the data directory's ID info (inode and device numbers) to + * positively identify shmem segments associated with this data dir, and + * also as seeds for searching for a free shmem key. + */ + if (stat(DataDir, &statbuf) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not stat data directory \"%s\": %m", + DataDir))); + /* Complain if hugepages demanded but we can't possibly support them */ -#if !defined(USE_ANONYMOUS_SHMEM) || !defined(MAP_HUGETLB) +#if !defined(MAP_HUGETLB) if (huge_pages == HUGE_PAGES_ON) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -576,27 +698,34 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); -#ifdef USE_ANONYMOUS_SHMEM - AnonymousShmem = CreateAnonymousSegment(&size); - AnonymousShmemSize = size; - - /* Register on-exit routine to unmap the anonymous segment */ - on_shmem_exit(AnonymousShmemDetach, (Datum) 0); + if (shared_memory_type != SHMEM_TYPE_SYSV) + { + AnonymousShmem = CreateAnonymousSegment(&size); + AnonymousShmemSize = size; - /* Now we need only allocate a minimal-sized SysV shmem block. */ - sysvsize = sizeof(PGShmemHeader); -#else - sysvsize = size; -#endif + /* Register on-exit routine to unmap the anonymous segment */ + on_shmem_exit(AnonymousShmemDetach, (Datum) 0); - /* Make sure PGSharedMemoryAttach doesn't fail without need */ - UsedShmemSegAddr = NULL; + /* Now we need only allocate a minimal-sized SysV shmem block. */ + sysvsize = sizeof(PGShmemHeader); + } + else + sysvsize = size; - /* Loop till we find a free IPC key */ - NextShmemSegID = port * 1000; + /* + * Loop till we find a free IPC key. Trust CreateDataDirLockFile() to + * ensure no more than one postmaster per data directory can enter this + * loop simultaneously. (CreateDataDirLockFile() does not entirely ensure + * that, but prefer fixing it over coping here.) + */ + NextShmemSegID = statbuf.st_ino; - for (NextShmemSegID++;; NextShmemSegID++) + for (;;) { + IpcMemoryId shmid; + PGShmemHeader *oldhdr; + IpcMemoryState state; + /* Try to create new segment */ memAddress = InternalIpcMemoryCreate(NextShmemSegID, sysvsize); if (memAddress) @@ -604,69 +733,82 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, /* Check shared memory and possibly remove and recreate */ - if (makePrivate) /* a standalone backend shouldn't do this */ - continue; - - if ((memAddress = PGSharedMemoryAttach(NextShmemSegID, &shmid)) == NULL) - continue; /* can't attach, not one of mine */ - /* - * If I am not the creator and it belongs to an extant process, - * continue. + * shmget() failure is typically EACCES, hence SHMSTATE_FOREIGN. + * ENOENT, a narrow possibility, implies SHMSTATE_ENOENT, but one can + * safely treat SHMSTATE_ENOENT like SHMSTATE_FOREIGN. */ - hdr = (PGShmemHeader *) memAddress; - if (hdr->creatorPID != getpid()) + shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0); + if (shmid < 0) { - if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH) - { - shmdt(memAddress); - continue; /* segment belongs to a live process */ - } + oldhdr = NULL; + state = SHMSTATE_FOREIGN; } + else + state = PGSharedMemoryAttach(shmid, NULL, &oldhdr); - /* - * The segment appears to be from a dead Postgres process, or from a - * previous cycle of life in this same process. Zap it, if possible, - * and any associated dynamic shared memory segments, as well. This - * probably shouldn't fail, but if it does, assume the segment belongs - * to someone else after all, and continue quietly. - */ - if (hdr->dsm_control != 0) - dsm_cleanup_using_control_segment(hdr->dsm_control); - shmdt(memAddress); - if (shmctl(shmid, IPC_RMID, NULL) < 0) - continue; + switch (state) + { + case SHMSTATE_ANALYSIS_FAILURE: + case SHMSTATE_ATTACHED: + ereport(FATAL, + (errcode(ERRCODE_LOCK_FILE_EXISTS), + errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use", + (unsigned long) NextShmemSegID, + (unsigned long) shmid), + errhint("Terminate any old server processes associated with data directory \"%s\".", + DataDir))); + break; + case SHMSTATE_ENOENT: - /* - * Now try again to create the segment. - */ - memAddress = InternalIpcMemoryCreate(NextShmemSegID, sysvsize); - if (memAddress) - break; /* successful create and attach */ + /* + * To our surprise, some other process deleted since our last + * InternalIpcMemoryCreate(). Moments earlier, we would have + * seen SHMSTATE_FOREIGN. Try that same ID again. + */ + elog(LOG, + "shared memory block (key %lu, ID %lu) deleted during startup", + (unsigned long) NextShmemSegID, + (unsigned long) shmid); + break; + case SHMSTATE_FOREIGN: + NextShmemSegID++; + break; + case SHMSTATE_UNATTACHED: - /* - * Can only get here if some other process managed to create the same - * shmem key before we did. Let him have that one, loop around to try - * next key. - */ + /* + * The segment pertains to DataDir, and every process that had + * used it has died or detached. Zap it, if possible, and any + * associated dynamic shared memory segments, as well. This + * shouldn't fail, but if it does, assume the segment belongs + * to someone else after all, and try the next candidate. + * Otherwise, try again to create the segment. That may fail + * if some other process creates the same shmem key before we + * do, in which case we'll try the next key. + */ + if (oldhdr->dsm_control != 0) + dsm_cleanup_using_control_segment(oldhdr->dsm_control); + if (shmctl(shmid, IPC_RMID, NULL) < 0) + NextShmemSegID++; + break; + } + + if (oldhdr && shmdt(oldhdr) < 0) + elog(LOG, "shmdt(%p) failed: %m", oldhdr); } - /* - * OK, we created a new segment. Mark it as created by this process. The - * order of assignments here is critical so that another Postgres process - * can't see the header as valid but belonging to an invalid PID! - */ + /* Initialize new segment. */ hdr = (PGShmemHeader *) memAddress; + + *shim = hdr; + if (IsOnlineUpgrade) + return AnonymousShmem ? AnonymousShmem : (void*)hdr; + hdr->creatorPID = getpid(); hdr->magic = PGShmemMagic; hdr->dsm_control = 0; /* Fill in the data directory ID info, too */ - if (stat(DataDir, &statbuf) < 0) - ereport(FATAL, - (errcode_for_file_access(), - errmsg("could not stat data directory \"%s\": %m", - DataDir))); hdr->device = statbuf.st_dev; hdr->inode = statbuf.st_ino; @@ -675,7 +817,6 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, */ hdr->totalsize = size; hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader)); - *shim = hdr; /* Save info for possible future use */ UsedShmemSegAddr = memAddress; @@ -687,18 +828,12 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, * block. Otherwise, the System V shared memory block is only a shim, and * we must return a pointer to the real block. */ -#ifdef USE_ANONYMOUS_SHMEM if (AnonymousShmem == NULL) return hdr; memcpy(AnonymousShmem, hdr, sizeof(PGShmemHeader)); return (PGShmemHeader *) AnonymousShmem; -#else - return hdr; -#endif } -#ifdef EXEC_BACKEND - /* * PGSharedMemoryReAttach * @@ -715,11 +850,12 @@ void PGSharedMemoryReAttach(void) { IpcMemoryId shmid; - void *hdr; + PGShmemHeader *hdr; + IpcMemoryState state; void *origUsedShmemSegAddr = UsedShmemSegAddr; Assert(UsedShmemSegAddr != NULL); - Assert(IsUnderPostmaster); + Assert(IsUnderPostmaster || IsOnlineUpgrade); #ifdef __CYGWIN__ /* cygipc (currently) appears to not detach on exec. */ @@ -728,16 +864,30 @@ PGSharedMemoryReAttach(void) #endif elog(DEBUG3, "attaching to %p", UsedShmemSegAddr); - hdr = (void *) PGSharedMemoryAttach((IpcMemoryKey) UsedShmemSegID, &shmid); - if (hdr == NULL) - elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %m", - (int) UsedShmemSegID, UsedShmemSegAddr); + shmid = shmget(UsedShmemSegID, sizeof(PGShmemHeader), 0); + if (shmid < 0) + state = SHMSTATE_FOREIGN; + else + state = PGSharedMemoryAttach(shmid, UsedShmemSegAddr, &hdr); + if (state != SHMSTATE_ATTACHED) + elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p, state=%d): %m", + (int) UsedShmemSegID, UsedShmemSegAddr, state); if (hdr != origUsedShmemSegAddr) elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)", hdr, origUsedShmemSegAddr); - dsm_set_control_handle(((PGShmemHeader *) hdr)->dsm_control); + dsm_set_control_handle(hdr->dsm_control); UsedShmemSegAddr = hdr; /* probably redundant */ + + if (IsOnlineUpgrade && AnonymousShmem) + { + Size size = hdr->totalsize; + void* addr = CreateAnonymousSegment(&size); + Assert(addr == AnonymousShmem); + Assert(size == hdr->totalsize); + AnonymousShmemSize = size; + elog(LOG, "Online upgrade maps anonymous segment to %p", addr); + } } /* @@ -772,7 +922,6 @@ PGSharedMemoryNoReAttach(void) UsedShmemSegID = 0; } -#endif /* EXEC_BACKEND */ /* * PGSharedMemoryDetach @@ -801,7 +950,6 @@ PGSharedMemoryDetach(void) UsedShmemSegAddr = NULL; } -#ifdef USE_ANONYMOUS_SHMEM if (AnonymousShmem != NULL) { if (munmap(AnonymousShmem, AnonymousShmemSize) < 0) @@ -809,33 +957,4 @@ PGSharedMemoryDetach(void) AnonymousShmem, AnonymousShmemSize); AnonymousShmem = NULL; } -#endif -} - - -/* - * Attach to shared memory and make sure it has a Postgres header - * - * Returns attach address if OK, else NULL - */ -static PGShmemHeader * -PGSharedMemoryAttach(IpcMemoryKey key, IpcMemoryId *shmid) -{ - PGShmemHeader *hdr; - - if ((*shmid = shmget(key, sizeof(PGShmemHeader), 0)) < 0) - return NULL; - - hdr = (PGShmemHeader *) shmat(*shmid, UsedShmemSegAddr, PG_SHMAT_FLAGS); - - if (hdr == (PGShmemHeader *) -1) - return NULL; /* failed: must be some other app's */ - - if (hdr->magic != PGShmemMagic) - { - shmdt((void *) hdr); - return NULL; /* segment belongs to a non-Postgres app */ - } - - return hdr; } diff --git a/src/backend/port/tas/sunstudio_sparc.s b/src/backend/port/tas/sunstudio_sparc.s index b041a296ca0..c8d88f26345 100644 --- a/src/backend/port/tas/sunstudio_sparc.s +++ b/src/backend/port/tas/sunstudio_sparc.s @@ -3,7 +3,7 @@ ! sunstudio_sparc.s ! compare and swap for Sun Studio on Sparc ! -! Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +! Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group ! Portions Copyright (c) 1994, Regents of the University of California ! ! IDENTIFICATION @@ -26,7 +26,7 @@ pg_atomic_cas: ! "cas" only works on sparcv9 and sparcv8plus chips, and - ! requies a compiler targeting these CPUs. It will fail + ! requires a compiler targeting these CPUs. It will fail ! on a compiler targeting sparcv8, and of course will not ! be understood by a sparcv8 CPU. gcc continues to use ! "ldstub" because it targets sparcv7. diff --git a/src/backend/port/tas/sunstudio_x86.s b/src/backend/port/tas/sunstudio_x86.s index af2b8c6a17e..2364c5ba07d 100644 --- a/src/backend/port/tas/sunstudio_x86.s +++ b/src/backend/port/tas/sunstudio_x86.s @@ -3,7 +3,7 @@ / sunstudio_x86.s / compare and swap for Sun Studio on x86 / -/ Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +/ Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group / Portions Copyright (c) 1994, Regents of the University of California / / IDENTIFICATION diff --git a/src/backend/port/win32/Makefile b/src/backend/port/win32/Makefile index a6ace93e261..833c9e06dc6 100644 --- a/src/backend/port/win32/Makefile +++ b/src/backend/port/win32/Makefile @@ -12,7 +12,7 @@ subdir = src/backend/port/win32 top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = timer.o socket.o signal.o mingwcompat.o +OBJS = timer.o socket.o signal.o ifeq ($(have_win32_dbghelp), yes) OBJS += crashdump.o endif diff --git a/src/backend/port/win32/crashdump.c b/src/backend/port/win32/crashdump.c index 7b84d22679f..b1fe5d3430e 100644 --- a/src/backend/port/win32/crashdump.c +++ b/src/backend/port/win32/crashdump.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- * - * win32_crashdump.c + * crashdump.c * Automatic crash dump creation for PostgreSQL on Windows * * The crashdump feature traps unhandled win32 exceptions produced by the @@ -28,7 +28,7 @@ * be added, though at the cost of a greater chance of the crash dump failing. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/crashdump.c diff --git a/src/backend/port/win32/mingwcompat.c b/src/backend/port/win32/mingwcompat.c deleted file mode 100644 index 3577d2538fd..00000000000 --- a/src/backend/port/win32/mingwcompat.c +++ /dev/null @@ -1,84 +0,0 @@ -/*------------------------------------------------------------------------- - * - * mingwcompat.c - * MinGW compatibility functions - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/backend/port/win32/mingwcompat.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#ifndef _MSC_VER -/* - * MingW defines an extern to this struct, but the actual struct isn't present - * in any library. It's trivial enough that we can safely define it - * ourselves. - */ -const struct in6_addr in6addr_any = {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}; - - -/* - * This file contains loaders for functions that are missing in the MinGW - * import libraries. It's only for actual Win32 API functions, so they are - * all present in proper Win32 compilers. - */ -static HMODULE kernel32 = NULL; - -/* - * Load DLL file just once regardless of how many functions - * we load/call in it. - */ -static void -LoadKernel32() -{ - if (kernel32 != NULL) - return; - - kernel32 = LoadLibraryEx("kernel32.dll", NULL, 0); - if (kernel32 == NULL) - ereport(FATAL, - (errmsg_internal("could not load kernel32.dll: error code %lu", - GetLastError()))); -} - - -/* - * Replacement for RegisterWaitForSingleObject(), which lives in - * kernel32.dll - */ -typedef -BOOL (WINAPI * __RegisterWaitForSingleObject) - (PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG); -static __RegisterWaitForSingleObject _RegisterWaitForSingleObject = NULL; - -BOOL WINAPI -RegisterWaitForSingleObject(PHANDLE phNewWaitObject, - HANDLE hObject, - WAITORTIMERCALLBACK Callback, - PVOID Context, - ULONG dwMilliseconds, - ULONG dwFlags) -{ - if (_RegisterWaitForSingleObject == NULL) - { - LoadKernel32(); - - _RegisterWaitForSingleObject = (__RegisterWaitForSingleObject) - GetProcAddress(kernel32, "RegisterWaitForSingleObject"); - - if (_RegisterWaitForSingleObject == NULL) - ereport(FATAL, - (errmsg_internal("could not locate RegisterWaitForSingleObject in kernel32.dll: error code %lu", - GetLastError()))); - } - - return (_RegisterWaitForSingleObject) - (phNewWaitObject, hObject, Callback, Context, dwMilliseconds, dwFlags); -} - -#endif diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c index f489cee8bd5..9b5e544febb 100644 --- a/src/backend/port/win32/signal.c +++ b/src/backend/port/win32/signal.c @@ -3,7 +3,7 @@ * signal.c * Microsoft Windows Win32 Signal Emulation Functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/signal.c @@ -52,6 +52,7 @@ static BOOL WINAPI pg_console_handler(DWORD dwCtrlType); void pg_usleep(long microsec) { + Assert(pgwin32_signal_event != NULL); if (WaitForSingleObject(pgwin32_signal_event, (microsec < 500 ? 1 : (microsec + 500) / 1000)) == WAIT_OBJECT_0) @@ -101,13 +102,14 @@ pgwin32_signal_initialize(void) /* * Dispatch all signals currently queued and not blocked * Blocked signals are ignored, and will be fired at the time of - * the sigsetmask() call. + * the pqsigsetmask() call. */ void pgwin32_dispatch_queued_signals(void) { int exec_mask; + Assert(pgwin32_signal_event != NULL); EnterCriticalSection(&pg_signal_crit_sec); while ((exec_mask = UNBLOCKED_SIGNAL_QUEUE()) != 0) { @@ -209,6 +211,7 @@ pgwin32_create_signal_listener(pid_t pid) void pg_queue_signal(int signum) { + Assert(pgwin32_signal_event != NULL); if (signum >= PG_SIGNAL_COUNT || signum <= 0) return; diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c index f4356fe1f31..d5b5e771e91 100644 --- a/src/backend/port/win32/socket.c +++ b/src/backend/port/win32/socket.c @@ -3,7 +3,7 @@ * socket.c * Microsoft Windows Win32 Socket Functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/socket.c @@ -690,39 +690,3 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c memcpy(writefds, &outwritefds, sizeof(fd_set)); return nummatches; } - - -/* - * Return win32 error string, since strerror can't - * handle winsock codes - */ -static char wserrbuf[256]; -const char * -pgwin32_socket_strerror(int err) -{ - static HANDLE handleDLL = INVALID_HANDLE_VALUE; - - if (handleDLL == INVALID_HANDLE_VALUE) - { - handleDLL = LoadLibraryEx("netmsg.dll", NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if (handleDLL == NULL) - ereport(FATAL, - (errmsg_internal("could not load netmsg.dll: error code %lu", GetLastError()))); - } - - ZeroMemory(&wserrbuf, sizeof(wserrbuf)); - if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_FROM_HMODULE, - handleDLL, - err, - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - wserrbuf, - sizeof(wserrbuf) - 1, - NULL) == 0) - { - /* Failed to get id */ - sprintf(wserrbuf, "unrecognized winsock error %d", err); - } - return wserrbuf; -} diff --git a/src/backend/port/win32/timer.c b/src/backend/port/win32/timer.c index dac105acf55..4085c7db6bc 100644 --- a/src/backend/port/win32/timer.c +++ b/src/backend/port/win32/timer.c @@ -8,7 +8,7 @@ * - Does not support interval timer (value->it_interval) * - Only supports ITIMER_REAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32/timer.c diff --git a/src/backend/port/win32_sema.c b/src/backend/port/win32_sema.c index a924c59cdb8..32cc6978669 100644 --- a/src/backend/port/win32_sema.c +++ b/src/backend/port/win32_sema.c @@ -3,7 +3,7 @@ * win32_sema.c * Microsoft Windows Win32 Semaphores Emulation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32_sema.c @@ -44,7 +44,7 @@ PGSemaphoreShmemSize(int maxSemas) * process exits. */ void -PGReserveSemaphores(int maxSemas, int port) +PGReserveSemaphores(int maxSemas) { mySemSet = (HANDLE *) malloc(maxSemas * sizeof(HANDLE)); if (mySemSet == NULL) @@ -127,7 +127,6 @@ PGSemaphoreReset(PGSemaphore sema) * PGSemaphoreLock * * Lock a semaphore (decrement count), blocking if count would be < 0. - * Serve the interrupt if interruptOK is true. */ void PGSemaphoreLock(PGSemaphore sema) diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index fa80cebfbd8..6cb63282847 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -3,7 +3,7 @@ * win32_shmem.c * Implement shared memory using win32 facilities * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/port/win32_shmem.c @@ -17,6 +17,28 @@ #include "storage/ipc.h" #include "storage/pg_shmem.h" +/* + * Early in a process's life, Windows asynchronously creates threads for the + * process's "default thread pool" + * (https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-pools). + * Occasionally, thread creation allocates a stack after + * PGSharedMemoryReAttach() has released UsedShmemSegAddr and before it has + * mapped shared memory at UsedShmemSegAddr. This would cause mapping to fail + * if the allocator preferred the just-released region for allocating the new + * thread stack. We observed such failures in some Windows Server 2016 + * configurations. To give the system another region to prefer, reserve and + * release an additional, protective region immediately before reserving or + * releasing shared memory. The idea is that, if the allocator handed out + * REGION1 pages before REGION2 pages at one occasion, it will do so whenever + * both regions are free. Windows Server 2016 exhibits that behavior, and a + * system behaving differently would have less need to protect + * UsedShmemSegAddr. The protective region must be at least large enough for + * one thread stack. However, ten times as much is less than 2% of the 32-bit + * address space and is negligible relative to the 64-bit address space. + */ +#define PROTECTIVE_REGION_SIZE (10 * WIN32_STACK_RLIMIT) +void *ShmemProtectiveRegion = NULL; + HANDLE UsedShmemSegID = INVALID_HANDLE_VALUE; void *UsedShmemSegAddr = NULL; static Size UsedShmemSegSize = 0; @@ -112,9 +134,9 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2) static bool EnableLockPagesPrivilege(int elevel) { - HANDLE hToken; + HANDLE hToken; TOKEN_PRIVILEGES tp; - LUID luid; + LUID luid; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { @@ -170,14 +192,9 @@ EnableLockPagesPrivilege(int elevel) * * Create a shared memory segment of the given size and initialize its * standard header. - * - * makePrivate means to always create a new segment, rather than attach to - * or recycle any existing segment. On win32, we always create a new segment, - * since there is no need for recycling (segments go away automatically - * when the last backend exits) */ PGShmemHeader * -PGSharedMemoryCreate(Size size, bool makePrivate, int port, +PGSharedMemoryCreate(Size size, PGShmemHeader **shim) { void *memAddress; @@ -192,6 +209,12 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, Size orig_size = size; DWORD flProtect = PAGE_READWRITE; + ShmemProtectiveRegion = VirtualAlloc(NULL, PROTECTIVE_REGION_SIZE, + MEM_RESERVE, PAGE_NOACCESS); + if (ShmemProtectiveRegion == NULL) + elog(FATAL, "could not reserve memory region: error code %lu", + GetLastError()); + /* Room for a header? */ Assert(size > MAXALIGN(sizeof(PGShmemHeader))); @@ -267,8 +290,8 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, size); /* - * Use the original size, not the rounded-up value, when falling back - * to non-huge pages. + * Use the original size, not the rounded-up value, when + * falling back to non-huge pages. */ size = orig_size; flProtect = PAGE_READWRITE; @@ -370,9 +393,9 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port, * an already existing shared memory segment, using the handle inherited from * the postmaster. * - * UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this - * routine. The caller must have already restored them to the postmaster's - * values. + * ShmemProtectiveRegion, UsedShmemSegID and UsedShmemSegAddr are implicit + * parameters to this routine. The caller must have already restored them to + * the postmaster's values. */ void PGSharedMemoryReAttach(void) @@ -380,12 +403,16 @@ PGSharedMemoryReAttach(void) PGShmemHeader *hdr; void *origUsedShmemSegAddr = UsedShmemSegAddr; + Assert(ShmemProtectiveRegion != NULL); Assert(UsedShmemSegAddr != NULL); Assert(IsUnderPostmaster); /* - * Release memory region reservation that was made by the postmaster + * Release memory region reservations made by the postmaster */ + if (VirtualFree(ShmemProtectiveRegion, 0, MEM_RELEASE) == 0) + elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu", + ShmemProtectiveRegion, GetLastError()); if (VirtualFree(UsedShmemSegAddr, 0, MEM_RELEASE) == 0) elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu", UsedShmemSegAddr, GetLastError()); @@ -414,13 +441,14 @@ PGSharedMemoryReAttach(void) * The child process startup logic might or might not call PGSharedMemoryDetach * after this; make sure that it will be a no-op if called. * - * UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this - * routine. The caller must have already restored them to the postmaster's - * values. + * ShmemProtectiveRegion, UsedShmemSegID and UsedShmemSegAddr are implicit + * parameters to this routine. The caller must have already restored them to + * the postmaster's values. */ void PGSharedMemoryNoReAttach(void) { + Assert(ShmemProtectiveRegion != NULL); Assert(UsedShmemSegAddr != NULL); Assert(IsUnderPostmaster); @@ -447,12 +475,25 @@ PGSharedMemoryNoReAttach(void) * Rather, this is for subprocesses that have inherited an attachment and want * to get rid of it. * - * UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this - * routine. + * ShmemProtectiveRegion, UsedShmemSegID and UsedShmemSegAddr are implicit + * parameters to this routine. */ void PGSharedMemoryDetach(void) { + /* + * Releasing the protective region liberates an unimportant quantity of + * address space, but be tidy. + */ + if (ShmemProtectiveRegion != NULL) + { + if (VirtualFree(ShmemProtectiveRegion, 0, MEM_RELEASE) == 0) + elog(LOG, "failed to release reserved memory region (addr=%p): error code %lu", + ShmemProtectiveRegion, GetLastError()); + + ShmemProtectiveRegion = NULL; + } + /* Unmap the view, if it's mapped */ if (UsedShmemSegAddr != NULL) { @@ -510,19 +551,22 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild) { void *address; + Assert(ShmemProtectiveRegion != NULL); Assert(UsedShmemSegAddr != NULL); Assert(UsedShmemSegSize != 0); - address = VirtualAllocEx(hChild, UsedShmemSegAddr, UsedShmemSegSize, - MEM_RESERVE, PAGE_READWRITE); + /* ShmemProtectiveRegion */ + address = VirtualAllocEx(hChild, ShmemProtectiveRegion, + PROTECTIVE_REGION_SIZE, + MEM_RESERVE, PAGE_NOACCESS); if (address == NULL) { /* Don't use FATAL since we're running in the postmaster */ elog(LOG, "could not reserve shared memory region (addr=%p) for child %p: error code %lu", - UsedShmemSegAddr, hChild, GetLastError()); + ShmemProtectiveRegion, hChild, GetLastError()); return false; } - if (address != UsedShmemSegAddr) + if (address != ShmemProtectiveRegion) { /* * Should never happen - in theory if allocation granularity causes @@ -530,9 +574,24 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild) * * Don't use FATAL since we're running in the postmaster. */ + elog(LOG, "reserved shared memory region got incorrect address %p, expected %p", + address, ShmemProtectiveRegion); + return false; + } + + /* UsedShmemSegAddr */ + address = VirtualAllocEx(hChild, UsedShmemSegAddr, UsedShmemSegSize, + MEM_RESERVE, PAGE_READWRITE); + if (address == NULL) + { + elog(LOG, "could not reserve shared memory region (addr=%p) for child %p: error code %lu", + UsedShmemSegAddr, hChild, GetLastError()); + return false; + } + if (address != UsedShmemSegAddr) + { elog(LOG, "reserved shared memory region got incorrect address %p, expected %p", address, UsedShmemSegAddr); - VirtualFreeEx(hChild, address, 0, MEM_RELEASE); return false; } diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 3b90b16daec..073f313337d 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -50,7 +50,7 @@ * there is a window (caused by pgstat delay) on which a worker may choose a * table that was already vacuumed; this is a bug in the current design. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -69,6 +69,7 @@ #include "access/htup_details.h" #include "access/multixact.h" #include "access/reloptions.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/dependency.h" @@ -104,7 +105,6 @@ #include "utils/syscache.h" #include "utils/timeout.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* @@ -121,7 +121,7 @@ double autovacuum_anl_scale; int autovacuum_freeze_max_age; int autovacuum_multixact_freeze_max_age; -int autovacuum_vac_cost_delay; +double autovacuum_vac_cost_delay; int autovacuum_vac_cost_limit; int Log_autovacuum_min_duration = -1; @@ -188,9 +188,8 @@ typedef struct av_relation typedef struct autovac_table { Oid at_relid; - int at_vacoptions; /* bitmask of VacuumOption */ VacuumParams at_params; - int at_vacuum_cost_delay; + double at_vacuum_cost_delay; int at_vacuum_cost_limit; bool at_dobalance; bool at_sharedrel; @@ -226,7 +225,7 @@ typedef struct WorkerInfoData TimestampTz wi_launchtime; bool wi_dobalance; bool wi_sharedrel; - int wi_cost_delay; + double wi_cost_delay; int wi_cost_limit; int wi_cost_limit_base; } WorkerInfoData; @@ -313,7 +312,7 @@ NON_EXEC_STATIC void AutoVacLauncherMain(int argc, char *argv[]) pg_attribute_no static Oid do_start_worker(void); static void launcher_determine_sleep(bool canlaunch, bool recursing, - struct timeval *nap); + struct timeval *nap); static void launch_worker(TimestampTz now); static List *get_database_list(void); static void rebuild_database_list(Oid newdb); @@ -324,25 +323,25 @@ static void do_autovacuum(void); static void FreeWorkerInfo(int code, Datum arg); static autovac_table *table_recheck_autovac(Oid relid, HTAB *table_toast_map, - TupleDesc pg_class_desc, - int effective_multixact_freeze_max_age); + TupleDesc pg_class_desc, + int effective_multixact_freeze_max_age); static void relation_needs_vacanalyze(Oid relid, AutoVacOpts *relopts, - Form_pg_class classForm, - PgStat_StatTabEntry *tabentry, - int effective_multixact_freeze_max_age, - bool *dovacuum, bool *doanalyze, bool *wraparound); + Form_pg_class classForm, + PgStat_StatTabEntry *tabentry, + int effective_multixact_freeze_max_age, + bool *dovacuum, bool *doanalyze, bool *wraparound); static void autovacuum_do_vac_analyze(autovac_table *tab, - BufferAccessStrategy bstrategy); + BufferAccessStrategy bstrategy); static AutoVacOpts *extract_autovac_opts(HeapTuple tup, - TupleDesc pg_class_desc); + TupleDesc pg_class_desc); static PgStat_StatTabEntry *get_pgstat_tabentry_relid(Oid relid, bool isshared, - PgStat_StatDBEntry *shared, - PgStat_StatDBEntry *dbentry); + PgStat_StatDBEntry *shared, + PgStat_StatDBEntry *dbentry); static void perform_work_item(AutoVacuumWorkItem *workitem); static void autovac_report_activity(autovac_table *tab); static void autovac_report_workitem(AutoVacuumWorkItem *workitem, - const char *nspname, const char *relname); + const char *nspname, const char *relname); static void av_sighup_handler(SIGNAL_ARGS); static void avl_sigusr2_handler(SIGNAL_ARGS); static void avl_sigterm_handler(SIGNAL_ARGS); @@ -522,16 +521,12 @@ AutoVacLauncherMain(int argc, char *argv[]) pgstat_report_wait_end(); AbortBufferIO(); UnlockBuffers(); - if (CurrentResourceOwner) - { - ResourceOwnerRelease(CurrentResourceOwner, - RESOURCE_RELEASE_BEFORE_LOCKS, - false, true); - /* we needn't bother with the other ResourceOwnerRelease phases */ - } + /* this is probably dead code, but let's be safe: */ + if (AuxProcessResourceOwner) + ReleaseAuxProcessResources(false); AtEOXact_Buffers(false); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(false); AtEOXact_HashTables(false); /* @@ -632,7 +627,6 @@ AutoVacLauncherMain(int argc, char *argv[]) struct timeval nap; TimestampTz current_time = 0; bool can_launch; - int rc; /* * This loop is a bit different from the normal use of WaitLatch, @@ -648,23 +642,16 @@ AutoVacLauncherMain(int argc, char *argv[]) * Wait until naptime expires or we get some type of signal (all the * signal handlers will wake us by calling SetLatch). */ - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L), - WAIT_EVENT_AUTOVACUUM_MAIN); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + (nap.tv_sec * 1000L) + (nap.tv_usec / 1000L), + WAIT_EVENT_AUTOVACUUM_MAIN); ResetLatch(MyLatch); /* Process sinval catchup interrupts that happened while sleeping */ ProcessCatchupInterrupt(); - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - /* the normal shutdown case */ if (got_SIGTERM) break; @@ -1082,7 +1069,7 @@ rebuild_database_list(Oid newdb) current_time = GetCurrentTimestamp(); /* - * move the elements from the array into the dllist, setting the + * move the elements from the array into the dlist, setting the * next_worker while walking the array */ for (i = 0; i < nelems; i++) @@ -1798,7 +1785,7 @@ autovac_balance_cost(void) */ int vac_cost_limit = (autovacuum_vac_cost_limit > 0 ? autovacuum_vac_cost_limit : VacuumCostLimit); - int vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ? + double vac_cost_delay = (autovacuum_vac_cost_delay >= 0 ? autovacuum_vac_cost_delay : VacuumCostDelay); double cost_total; double cost_avail; @@ -1853,7 +1840,7 @@ autovac_balance_cost(void) } if (worker->wi_proc != NULL) - elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%d)", + elog(DEBUG2, "autovac_balance_cost(pid=%u db=%u, rel=%u, dobalance=%s cost_limit=%d, cost_limit_base=%d, cost_delay=%g)", worker->wi_proc->pid, worker->wi_dboid, worker->wi_tableoid, worker->wi_dobalance ? "yes" : "no", worker->wi_cost_limit, worker->wi_cost_limit_base, @@ -1878,7 +1865,7 @@ get_database_list(void) { List *dblist = NIL; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; MemoryContext resultcxt; @@ -1895,8 +1882,8 @@ get_database_list(void) StartTransactionCommand(); (void) GetTransactionSnapshot(); - rel = heap_open(DatabaseRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(DatabaseRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { @@ -1914,7 +1901,7 @@ get_database_list(void) avdb = (avw_dbase *) palloc(sizeof(avw_dbase)); - avdb->adw_datid = HeapTupleGetOid(tup); + avdb->adw_datid = pgdatabase->oid; avdb->adw_name = pstrdup(NameStr(pgdatabase->datname)); avdb->adw_frozenxid = pgdatabase->datfrozenxid; avdb->adw_minmulti = pgdatabase->datminmxid; @@ -1925,8 +1912,8 @@ get_database_list(void) MemoryContextSwitchTo(oldcxt); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); CommitTransactionCommand(); @@ -1944,7 +1931,7 @@ do_autovacuum(void) { Relation classRel; HeapTuple tuple; - HeapScanDesc relScan; + TableScanDesc relScan; Form_pg_database dbForm; List *table_oids = NIL; List *orphan_oids = NIL; @@ -2027,7 +2014,7 @@ do_autovacuum(void) /* The database hash where pgstat keeps shared relations */ shared = pgstat_fetch_stat_dbentry(InvalidOid); - classRel = heap_open(RelationRelationId, AccessShareLock); + classRel = table_open(RelationRelationId, AccessShareLock); /* create a copy so we can use it after closing pg_class */ pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel)); @@ -2056,7 +2043,7 @@ do_autovacuum(void) * wide tables there might be proportionally much more activity in the * TOAST table than in its parent. */ - relScan = heap_beginscan_catalog(classRel, 0, NULL); + relScan = table_beginscan_catalog(classRel, 0, NULL); /* * On the first pass, we collect main tables to vacuum, and also the main @@ -2076,7 +2063,7 @@ do_autovacuum(void) classForm->relkind != RELKIND_MATVIEW) continue; - relid = HeapTupleGetOid(tuple); + relid = classForm->oid; /* * Check if it is a temp table (presumably, of some other backend's). @@ -2084,14 +2071,11 @@ do_autovacuum(void) */ if (classForm->relpersistence == RELPERSISTENCE_TEMP) { - int backendID; - - backendID = GetTempNamespaceBackendId(classForm->relnamespace); - - /* We just ignore it if the owning backend is still active */ - if (backendID != InvalidBackendId && - (backendID == MyBackendId || - BackendIdGetProc(backendID) == NULL)) + /* + * We just ignore it if the owning backend is still active and + * using the temporary schema. + */ + if (!isTempNamespaceInUse(classForm->relnamespace)) { /* * The table seems to be orphaned -- although it might be that @@ -2148,7 +2132,7 @@ do_autovacuum(void) } } - heap_endscan(relScan); + table_endscan(relScan); /* second pass: check TOAST tables */ ScanKeyInit(&key, @@ -2156,7 +2140,7 @@ do_autovacuum(void) BTEqualStrategyNumber, F_CHAREQ, CharGetDatum(RELKIND_TOASTVALUE)); - relScan = heap_beginscan_catalog(classRel, 1, &key); + relScan = table_beginscan_catalog(classRel, 1, &key); while ((tuple = heap_getnext(relScan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); @@ -2173,7 +2157,7 @@ do_autovacuum(void) if (classForm->relpersistence == RELPERSISTENCE_TEMP) continue; - relid = HeapTupleGetOid(tuple); + relid = classForm->oid; /* * fetch reloptions -- if this toast table does not have them, try the @@ -2203,8 +2187,8 @@ do_autovacuum(void) table_oids = lappend_oid(table_oids, relid); } - heap_endscan(relScan); - heap_close(classRel, AccessShareLock); + table_endscan(relScan); + table_close(classRel, AccessShareLock); /* * Recheck orphan temporary tables, and if they still seem orphaned, drop @@ -2219,7 +2203,6 @@ do_autovacuum(void) { Oid relid = lfirst_oid(cell); Form_pg_class classForm; - int backendID; ObjectAddress object; /* @@ -2261,10 +2244,8 @@ do_autovacuum(void) UnlockRelationOid(relid, AccessExclusiveLock); continue; } - backendID = GetTempNamespaceBackendId(classForm->relnamespace); - if (!(backendID != InvalidBackendId && - (backendID == MyBackendId || - BackendIdGetProc(backendID) == NULL))) + + if (isTempNamespaceInUse(classForm->relnamespace)) { UnlockRelationOid(relid, AccessExclusiveLock); continue; @@ -2321,7 +2302,7 @@ do_autovacuum(void) autovac_table *tab; bool isshared; bool skipit; - int stdVacuumCostDelay; + double stdVacuumCostDelay; int stdVacuumCostLimit; dlist_iter iter; @@ -2500,7 +2481,7 @@ do_autovacuum(void) * next table in our list. */ HOLD_INTERRUPTS(); - if (tab->at_vacoptions & VACOPT_VACUUM) + if (tab->at_params.options & VACOPT_VACUUM) errcontext("automatic vacuum of table \"%s.%s.%s\"", tab->at_datname, tab->at_nspname, tab->at_relname); else @@ -2652,7 +2633,7 @@ perform_work_item(AutoVacuumWorkItem *workitem) if (!cur_relname || !cur_nspname || !cur_datname) goto deleted2; - autovac_report_workitem(workitem, cur_nspname, cur_datname); + autovac_report_workitem(workitem, cur_nspname, cur_relname); /* clean up memory before each work item */ MemoryContextResetAndDeleteChildren(PortalContext); @@ -2850,7 +2831,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, int multixact_freeze_min_age; int multixact_freeze_table_age; int vac_cost_limit; - int vac_cost_delay; + double vac_cost_delay; int log_min_duration; /* @@ -2901,10 +2882,12 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map, tab = palloc(sizeof(autovac_table)); tab->at_relid = relid; tab->at_sharedrel = classForm->relisshared; - tab->at_vacoptions = VACOPT_SKIPTOAST | + tab->at_params.options = VACOPT_SKIPTOAST | (dovacuum ? VACOPT_VACUUM : 0) | (doanalyze ? VACOPT_ANALYZE : 0) | - (!wraparound ? VACOPT_NOWAIT : 0); + (!wraparound ? VACOPT_SKIP_LOCKED : 0); + tab->at_params.index_cleanup = VACOPT_TERNARY_DEFAULT; + tab->at_params.truncate = VACOPT_TERNARY_DEFAULT; tab->at_params.freeze_min_age = freeze_min_age; tab->at_params.freeze_table_age = freeze_table_age; tab->at_params.multixact_freeze_min_age = multixact_freeze_min_age; @@ -3012,7 +2995,7 @@ relation_needs_vacanalyze(Oid relid, * table), or the autovacuum GUC variables. */ - /* -1 in autovac setting means use plain vacuum_cost_delay */ + /* -1 in autovac setting means use plain vacuum_scale_factor */ vac_scale_factor = (relopts && relopts->vacuum_scale_factor >= 0) ? relopts->vacuum_scale_factor : autovacuum_vac_scale; @@ -3051,8 +3034,8 @@ relation_needs_vacanalyze(Oid relid, multiForceLimit = recentMulti - multixact_freeze_max_age; if (multiForceLimit < FirstMultiXactId) multiForceLimit -= FirstMultiXactId; - force_vacuum = MultiXactIdPrecedes(classForm->relminmxid, - multiForceLimit); + force_vacuum = MultiXactIdIsValid(classForm->relminmxid) && + MultiXactIdPrecedes(classForm->relminmxid, multiForceLimit); } *wraparound = force_vacuum; @@ -3128,7 +3111,7 @@ autovacuum_do_vac_analyze(autovac_table *tab, BufferAccessStrategy bstrategy) rel = makeVacuumRelation(rangevar, tab->at_relid, NIL); rel_list = list_make1(rel); - vacuum(tab->at_vacoptions, rel_list, &tab->at_params, bstrategy, true); + vacuum(rel_list, &tab->at_params, bstrategy, true); } /* @@ -3150,10 +3133,10 @@ autovac_report_activity(autovac_table *tab) int len; /* Report the command and possible options */ - if (tab->at_vacoptions & VACOPT_VACUUM) + if (tab->at_params.options & VACOPT_VACUUM) snprintf(activity, MAX_AUTOVAC_ACTIV_LEN, "autovacuum: VACUUM%s", - tab->at_vacoptions & VACOPT_ANALYZE ? " ANALYZE" : ""); + tab->at_params.options & VACOPT_ANALYZE ? " ANALYZE" : ""); else snprintf(activity, MAX_AUTOVAC_ACTIV_LEN, "autovacuum: ANALYZE"); diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index f651bb49b15..f4d09cf059d 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -2,7 +2,7 @@ * bgworker.c * POSTGRES pluggable background workers implementation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/postmaster/bgworker.c @@ -152,6 +152,24 @@ BackgroundWorkerShmemSize(void) return size; } +void +BackgroundWorkerShmemAttach(void) +{ + slist_iter siter; + int slotno = 0; + + slist_foreach(siter, &BackgroundWorkerList) + { + RegisteredBgWorker *rw; + + rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur); + Assert(slotno < max_worker_processes); + rw->rw_shmem_slot = slotno; + rw->rw_worker.bgw_notify_pid = 0; /* might be reinit after crash */ + ++slotno; + } +} + /* * Initialize shared memory. */ @@ -377,7 +395,7 @@ BackgroundWorkerStateChange(void) rw->rw_worker.bgw_notify_pid = slot->worker.bgw_notify_pid; if (!PostmasterMarkPIDForWorkerNotify(rw->rw_worker.bgw_notify_pid)) { - elog(DEBUG1, "worker notification PID %lu is not valid", + elog(LOG, "worker notification PID %lu is not valid", (long) rw->rw_worker.bgw_notify_pid); rw->rw_worker.bgw_notify_pid = 0; } @@ -480,6 +498,7 @@ ReportBackgroundWorkerExit(slist_mutable_iter *cur) rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART) ForgetBackgroundWorker(cur); + elog(LOG, "Notify PID=%d", notify_pid); if (notify_pid != 0) kill(notify_pid, SIGUSR1); } @@ -525,7 +544,7 @@ ResetBackgroundWorkerCrashTimes(void) if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART) { /* - * Workers marked BGW_NVER_RESTART shouldn't get relaunched after + * Workers marked BGW_NEVER_RESTART shouldn't get relaunched after * the crash, so forget about them. (If we wait until after the * crash to forget about them, and they are parallel workers, * parallel_terminate_count will get incremented after we've @@ -553,7 +572,6 @@ ResetBackgroundWorkerCrashTimes(void) } } -#ifdef EXEC_BACKEND /* * In EXEC_BACKEND mode, workers use this to retrieve their details from * shared memory. @@ -572,7 +590,18 @@ BackgroundWorkerEntry(int slotno) memcpy(&myEntry, &slot->worker, sizeof myEntry); return &myEntry; } -#endif + +void* +GetBackgroundWorkerEntries(void) +{ + return BackgroundWorkerData; +} + +void +SetBackgroundWorkerEntries(void* entries) +{ + BackgroundWorkerData = entries; +} /* * Complain about the BackgroundWorker definition using error level elevel. @@ -644,28 +673,21 @@ SanityCheckBackgroundWorker(BackgroundWorker *worker, int elevel) static void bgworker_quickdie(SIGNAL_ARGS) { - sigaddset(&BlockSig, SIGQUIT); /* prevent nested calls */ - PG_SETMASK(&BlockSig); - - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } /* @@ -1154,6 +1176,7 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle) CHECK_FOR_INTERRUPTS(); status = GetBackgroundWorkerPid(handle, &pid); + elog(LOG, "GetBackgroundWorkerPid(%d) = %d", pid, status); if (status == BGWH_STOPPED) break; @@ -1191,6 +1214,7 @@ TerminateBackgroundWorker(BackgroundWorkerHandle *handle) /* Set terminate flag in shared memory, unless slot has been reused. */ LWLockAcquire(BackgroundWorkerLock, LW_EXCLUSIVE); + elog(LOG, "Terminate worker slot %d", handle->slot); if (handle->generation == slot->generation) { slot->terminate = true; diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index b7813d7a4fb..8ec16a3fb8d 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -24,7 +24,7 @@ * should be killed by SIGQUIT and then a recovery cycle started. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -133,20 +133,10 @@ BackgroundWriterMain(void) * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); - /* - * Create a resource owner to keep track of our resources (currently only - * buffer pins). - */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "Background Writer"); - /* * We just started, assume there has been either a shutdown or * end-of-recovery snapshot. @@ -191,14 +181,10 @@ BackgroundWriterMain(void) ConditionVariableCancelSleep(); AbortBufferIO(); UnlockBuffers(); - /* buffer pins are released here: */ - ResourceOwnerRelease(CurrentResourceOwner, - RESOURCE_RELEASE_BEFORE_LOCKS, - false, true); - /* we needn't bother with the other ResourceOwnerRelease phases */ + ReleaseAuxProcessResources(false); AtEOXact_Buffers(false); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(false); AtEOXact_HashTables(false); /* @@ -305,10 +291,10 @@ BackgroundWriterMain(void) * significantly bigger than BgWriterDelay, so we don't complicate the * overall timeout handling but just assume we're going to get called * often enough even if hibernation mode is active. It's not that - * important that log_snap_interval_ms is met strictly. To make sure - * we're not waking the disk up unnecessarily on an idle system we - * check whether there has been any WAL inserted since the last time - * we've logged a running xacts. + * important that LOG_SNAPSHOT_INTERVAL_MS is met strictly. To make + * sure we're not waking the disk up unnecessarily on an idle system + * we check whether there has been any WAL inserted since the last + * time we've logged a running xacts. * * We do this logging in the bgwriter as it is the only process that * is run regularly and returns to its mainloop all the time. E.g. @@ -349,7 +335,7 @@ BackgroundWriterMain(void) * normal operation. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, BgWriterDelay /* ms */ , WAIT_EVENT_BGWRITER_MAIN); /* @@ -375,21 +361,14 @@ BackgroundWriterMain(void) /* Ask for notification at next buffer allocation */ StrategyNotifyBgWriter(MyProc->pgprocno); /* Sleep ... */ - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - BgWriterDelay * HIBERNATE_FACTOR, - WAIT_EVENT_BGWRITER_HIBERNATE); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + BgWriterDelay * HIBERNATE_FACTOR, + WAIT_EVENT_BGWRITER_HIBERNATE); /* Reset the notification request in case we timed out */ StrategyNotifyBgWriter(-1); } - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (rc & WL_POSTMASTER_DEATH) - exit(1); - prev_hibernate = can_hibernate; } } @@ -409,27 +388,21 @@ BackgroundWriterMain(void) static void bg_quickdie(SIGNAL_ARGS) { - PG_SETMASK(&BlockSig); - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } /* SIGHUP: set flag to re-read config file at next convenient time */ diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 4b452e7cee6..ea6abe73f4a 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -26,7 +26,7 @@ * restart needs to be forced.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -47,6 +47,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "postmaster/bgwriter.h" +#include "postmaster/postmaster.h" #include "replication/syncrep.h" #include "storage/bufmgr.h" #include "storage/condition_variable.h" @@ -108,10 +109,8 @@ */ typedef struct { - RelFileNode rnode; - ForkNumber forknum; - BlockNumber segno; /* see md.c for special values */ - /* might add a real request-type field later; not needed yet */ + SyncRequestType type; /* request type */ + FileTag ftag; /* file identifier */ } CheckpointerRequest; typedef struct @@ -126,6 +125,9 @@ typedef struct int ckpt_flags; /* checkpoint flags, as defined in xlog.h */ + ConditionVariable start_cv; /* signaled when ckpt_started advances */ + ConditionVariable done_cv; /* signaled when ckpt_done advances */ + uint32 num_backend_writes; /* counts user backend buffer writes */ uint32 num_backend_fsync; /* counts user backend fsync calls */ @@ -136,7 +138,7 @@ typedef struct static CheckpointerShmemStruct *CheckpointerShmem; -/* interval for calling AbsorbFsyncRequests in CheckpointWriteDelay */ +/* interval for calling AbsorbSyncRequests in CheckpointWriteDelay */ #define WRITES_PER_ABSORB 1000 /* @@ -150,8 +152,8 @@ double CheckPointCompletionTarget = 0.5; * Flags set by interrupt handlers for later service in the main loop. */ static volatile sig_atomic_t got_SIGHUP = false; -static volatile sig_atomic_t checkpoint_requested = false; static volatile sig_atomic_t shutdown_requested = false; +static volatile sig_atomic_t fast_shutdown_requested = false; /* * Private state @@ -218,10 +220,6 @@ CheckpointerMain(void) * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); @@ -231,12 +229,6 @@ CheckpointerMain(void) */ last_checkpoint_time = last_xlog_switch_time = (pg_time_t) time(NULL); - /* - * Create a resource owner to keep track of our resources (currently only - * buffer pins). - */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "Checkpointer"); - /* * Create a memory context that we will do all our work in. We do this so * that we can reset the context during error recovery and thereby avoid @@ -275,14 +267,10 @@ CheckpointerMain(void) pgstat_report_wait_end(); AbortBufferIO(); UnlockBuffers(); - /* buffer pins are released here: */ - ResourceOwnerRelease(CurrentResourceOwner, - RESOURCE_RELEASE_BEFORE_LOCKS, - false, true); - /* we needn't bother with the other ResourceOwnerRelease phases */ + ReleaseAuxProcessResources(false); AtEOXact_Buffers(false); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(false); AtEOXact_HashTables(false); /* Warn any waiting backends that the checkpoint failed. */ @@ -293,6 +281,8 @@ CheckpointerMain(void) CheckpointerShmem->ckpt_done = CheckpointerShmem->ckpt_started; SpinLockRelease(&CheckpointerShmem->ckpt_lck); + ConditionVariableBroadcast(&CheckpointerShmem->done_cv); + ckpt_active = false; } @@ -354,7 +344,6 @@ CheckpointerMain(void) pg_time_t now; int elapsed_secs; int cur_timeout; - int rc; /* Clear any already-pending wakeups */ ResetLatch(MyLatch); @@ -362,7 +351,7 @@ CheckpointerMain(void) /* * Process any requests or signals received recently. */ - AbsorbFsyncRequests(); + AbsorbSyncRequests(); if (got_SIGHUP) { @@ -382,11 +371,10 @@ CheckpointerMain(void) */ UpdateSharedMemoryConfig(); } - if (checkpoint_requested) + if (fast_shutdown_requested) { - checkpoint_requested = false; - do_checkpoint = true; - BgWriterStats.m_requested_checkpoints++; + /* Normal exit from the checkpointer is here */ + proc_exit(0); /* done */ } if (shutdown_requested) { @@ -401,6 +389,17 @@ CheckpointerMain(void) proc_exit(0); /* done */ } + /* + * Detect a pending checkpoint request by checking whether the flags + * word in shared memory is nonzero. We shouldn't need to acquire the + * ckpt_lck for this. + */ + if (((volatile CheckpointerShmemStruct *) CheckpointerShmem)->ckpt_flags) + { + do_checkpoint = true; + BgWriterStats.m_requested_checkpoints++; + } + /* * Force a checkpoint if too much time has elapsed since the last one. * Note that we count a timed checkpoint in stats only when this @@ -443,6 +442,8 @@ CheckpointerMain(void) CheckpointerShmem->ckpt_started++; SpinLockRelease(&CheckpointerShmem->ckpt_lck); + ConditionVariableBroadcast(&CheckpointerShmem->start_cv); + /* * The end-of-recovery checkpoint is a real checkpoint that's * performed while we're still in recovery. @@ -503,6 +504,8 @@ CheckpointerMain(void) CheckpointerShmem->ckpt_done = CheckpointerShmem->ckpt_started; SpinLockRelease(&CheckpointerShmem->ckpt_lck); + ConditionVariableBroadcast(&CheckpointerShmem->done_cv); + if (ckpt_performed) { /* @@ -555,17 +558,10 @@ CheckpointerMain(void) cur_timeout = Min(cur_timeout, XLogArchiveTimeout - elapsed_secs); } - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - cur_timeout * 1000L /* convert to ms */ , - WAIT_EVENT_CHECKPOINTER_MAIN); - - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (rc & WL_POSTMASTER_DEATH) - exit(1); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + cur_timeout * 1000L /* convert to ms */ , + WAIT_EVENT_CHECKPOINTER_MAIN); } } @@ -645,17 +641,14 @@ CheckArchiveTimeout(void) static bool ImmediateCheckpointRequested(void) { - if (checkpoint_requested) - { - volatile CheckpointerShmemStruct *cps = CheckpointerShmem; + volatile CheckpointerShmemStruct *cps = CheckpointerShmem; - /* - * We don't need to acquire the ckpt_lck in this case because we're - * only looking at a single flag bit. - */ - if (cps->ckpt_flags & CHECKPOINT_IMMEDIATE) - return true; - } + /* + * We don't need to acquire the ckpt_lck in this case because we're only + * looking at a single flag bit. + */ + if (cps->ckpt_flags & CHECKPOINT_IMMEDIATE) + return true; return false; } @@ -687,6 +680,7 @@ CheckpointWriteDelay(int flags, double progress) */ if (!(flags & CHECKPOINT_IMMEDIATE) && !shutdown_requested && + !fast_shutdown_requested && !ImmediateCheckpointRequested() && IsCheckpointOnSchedule(progress)) { @@ -698,7 +692,7 @@ CheckpointWriteDelay(int flags, double progress) UpdateSharedMemoryConfig(); } - AbsorbFsyncRequests(); + AbsorbSyncRequests(); absorb_counter = WRITES_PER_ABSORB; CheckArchiveTimeout(); @@ -723,7 +717,7 @@ CheckpointWriteDelay(int flags, double progress) * operations even when we don't sleep, to prevent overflow of the * fsync request queue. */ - AbsorbFsyncRequests(); + AbsorbSyncRequests(); absorb_counter = WRITES_PER_ABSORB; } } @@ -764,7 +758,7 @@ IsCheckpointOnSchedule(double progress) * We compare the current WAL insert location against the location * computed before calling CreateCheckPoint. The code in XLogInsert that * actually triggers a checkpoint when CheckPointSegments is exceeded - * compares against RedoRecptr, so this is not completely accurate. + * compares against RedoRecPtr, so this is not completely accurate. * However, it's good enough for our purposes, we're only calculating an * estimate anyway. * @@ -823,27 +817,26 @@ IsCheckpointOnSchedule(double progress) static void chkpt_quickdie(SIGNAL_ARGS) { - PG_SETMASK(&BlockSig); - - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + if (*OnlineUpgradePath != '\0') + { + fast_shutdown_requested = true; + } + else + _exit(2); } /* SIGHUP: set flag to re-read config file at next convenient time */ @@ -864,7 +857,10 @@ ReqCheckpointHandler(SIGNAL_ARGS) { int save_errno = errno; - checkpoint_requested = true; + /* + * The signalling process should have set ckpt_flags nonzero, so all we + * need do is ensure that our main loop gets kicked out of any wait. + */ SetLatch(MyLatch); errno = save_errno; @@ -943,6 +939,8 @@ CheckpointerShmemInit(void) MemSet(CheckpointerShmem, 0, size); SpinLockInit(&CheckpointerShmem->ckpt_lck); CheckpointerShmem->max_requests = NBuffers; + ConditionVariableInit(&CheckpointerShmem->start_cv); + ConditionVariableInit(&CheckpointerShmem->done_cv); } } @@ -1003,31 +1001,35 @@ RequestCheckpoint(int flags) old_failed = CheckpointerShmem->ckpt_failed; old_started = CheckpointerShmem->ckpt_started; - CheckpointerShmem->ckpt_flags |= flags; + CheckpointerShmem->ckpt_flags |= (flags | CHECKPOINT_REQUESTED); SpinLockRelease(&CheckpointerShmem->ckpt_lck); /* * Send signal to request checkpoint. It's possible that the checkpointer * hasn't started yet, or is in process of restarting, so we will retry a - * few times if needed. Also, if not told to wait for the checkpoint to - * occur, we consider failure to send the signal to be nonfatal and merely - * LOG it. + * few times if needed. (Actually, more than a few times, since on slow + * or overloaded buildfarm machines, it's been observed that the + * checkpointer can take several seconds to start.) However, if not told + * to wait for the checkpoint to occur, we consider failure to send the + * signal to be nonfatal and merely LOG it. The checkpointer should see + * the request when it does start, with or without getting a signal. */ +#define MAX_SIGNAL_TRIES 600 /* max wait 60.0 sec */ for (ntries = 0;; ntries++) { if (CheckpointerShmem->checkpointer_pid == 0) { - if (ntries >= 20) /* max wait 2.0 sec */ + if (ntries >= MAX_SIGNAL_TRIES || !(flags & CHECKPOINT_WAIT)) { elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG, - "could not request checkpoint because checkpointer not running"); + "could not signal for checkpoint: checkpointer is not running"); break; } } else if (kill(CheckpointerShmem->checkpointer_pid, SIGINT) != 0) { - if (ntries >= 20) /* max wait 2.0 sec */ + if (ntries >= MAX_SIGNAL_TRIES || !(flags & CHECKPOINT_WAIT)) { elog((flags & CHECKPOINT_WAIT) ? ERROR : LOG, "could not signal for checkpoint: %m"); @@ -1051,6 +1053,7 @@ RequestCheckpoint(int flags) new_failed; /* Wait for a new checkpoint to start. */ + ConditionVariablePrepareToSleep(&CheckpointerShmem->start_cv); for (;;) { SpinLockAcquire(&CheckpointerShmem->ckpt_lck); @@ -1060,13 +1063,15 @@ RequestCheckpoint(int flags) if (new_started != old_started) break; - CHECK_FOR_INTERRUPTS(); - pg_usleep(100000L); + ConditionVariableSleep(&CheckpointerShmem->start_cv, + WAIT_EVENT_CHECKPOINT_START); } + ConditionVariableCancelSleep(); /* * We are waiting for ckpt_done >= new_started, in a modulo sense. */ + ConditionVariablePrepareToSleep(&CheckpointerShmem->done_cv); for (;;) { int new_done; @@ -1079,9 +1084,10 @@ RequestCheckpoint(int flags) if (new_done - new_started >= 0) break; - CHECK_FOR_INTERRUPTS(); - pg_usleep(100000L); + ConditionVariableSleep(&CheckpointerShmem->done_cv, + WAIT_EVENT_CHECKPOINT_DONE); } + ConditionVariableCancelSleep(); if (new_failed != old_failed) ereport(ERROR, @@ -1091,7 +1097,7 @@ RequestCheckpoint(int flags) } /* - * ForwardFsyncRequest + * ForwardSyncRequest * Forward a file-fsync request from a backend to the checkpointer * * Whenever a backend is compelled to write directly to a relation @@ -1100,15 +1106,6 @@ RequestCheckpoint(int flags) * is dirty and must be fsync'd before next checkpoint. We also use this * opportunity to count such writes for statistical purposes. * - * This functionality is only supported for regular (not backend-local) - * relations, so the rnode argument is intentionally RelFileNode not - * RelFileNodeBackend. - * - * segno specifies which segment (not block!) of the relation needs to be - * fsync'd. (Since the valid range is much less than BlockNumber, we can - * use high values for special flags; that's all internal to md.c, which - * see for details.) - * * To avoid holding the lock for longer than necessary, we normally write * to the requests[] queue without checking for duplicates. The checkpointer * will have to eliminate dups internally anyway. However, if we discover @@ -1120,7 +1117,7 @@ RequestCheckpoint(int flags) * let the backend know by returning false. */ bool -ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno) +ForwardSyncRequest(const FileTag *ftag, SyncRequestType type) { CheckpointerRequest *request; bool too_full; @@ -1129,7 +1126,7 @@ ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno) return false; /* probably shouldn't even get here */ if (AmCheckpointerProcess()) - elog(ERROR, "ForwardFsyncRequest must not be called in checkpointer"); + elog(ERROR, "ForwardSyncRequest must not be called in checkpointer"); LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE); @@ -1158,9 +1155,8 @@ ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno) /* OK, insert request */ request = &CheckpointerShmem->requests[CheckpointerShmem->num_requests++]; - request->rnode = rnode; - request->forknum = forknum; - request->segno = segno; + request->ftag = *ftag; + request->type = type; /* If queue is more than half full, nudge the checkpointer to empty it */ too_full = (CheckpointerShmem->num_requests >= @@ -1230,12 +1226,11 @@ CompactCheckpointerRequestQueue(void) * backwards from the end of the queue and check whether a request is * *preceded* by an earlier, identical request, in the hopes of doing less * copying. But that might change the semantics, if there's an - * intervening FORGET_RELATION_FSYNC or FORGET_DATABASE_FSYNC request, so - * we do it this way. It would be possible to be even smarter if we made - * the code below understand the specific semantics of such requests (it - * could blow away preceding entries that would end up being canceled - * anyhow), but it's not clear that the extra complexity would buy us - * anything. + * intervening SYNC_FORGET_REQUEST or SYNC_FILTER_REQUEST, so we do it + * this way. It would be possible to be even smarter if we made the code + * below understand the specific semantics of such requests (it could blow + * away preceding entries that would end up being canceled anyhow), but + * it's not clear that the extra complexity would buy us anything. */ for (n = 0; n < CheckpointerShmem->num_requests; n++) { @@ -1291,8 +1286,8 @@ CompactCheckpointerRequestQueue(void) } /* - * AbsorbFsyncRequests - * Retrieve queued fsync requests and pass them to local smgr. + * AbsorbSyncRequests + * Retrieve queued sync requests and pass them to sync mechanism. * * This is exported because it must be called during CreateCheckPoint; * we have to be sure we have accepted all pending requests just before @@ -1300,7 +1295,7 @@ CompactCheckpointerRequestQueue(void) * non-checkpointer processes, do nothing if not checkpointer. */ void -AbsorbFsyncRequests(void) +AbsorbSyncRequests(void) { CheckpointerRequest *requests = NULL; CheckpointerRequest *request; @@ -1342,7 +1337,7 @@ AbsorbFsyncRequests(void) LWLockRelease(CheckpointerCommLock); for (request = requests; n > 0; request++, n--) - RememberFsyncRequest(request->rnode, request->forknum, request->segno); + RememberSyncRequest(&request->ftag, request->type); END_CRIT_SECTION(); diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c index d3005d9f1d1..a9138f589ee 100644 --- a/src/backend/postmaster/fork_process.c +++ b/src/backend/postmaster/fork_process.c @@ -4,7 +4,7 @@ * EXEC_BACKEND case; it might be extended to do so, but it would be * considerably more complex. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/postmaster/fork_process.c diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index 885e85ad8af..f84f882c4cb 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -14,7 +14,7 @@ * * Initial author: Simon Riggs simon@2ndquadrant.com * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -59,8 +60,18 @@ #define PGARCH_RESTART_INTERVAL 10 /* How often to attempt to restart a * failed archiver; in seconds. */ +/* + * Maximum number of retries allowed when attempting to archive a WAL + * file. + */ #define NUM_ARCHIVE_RETRIES 3 +/* + * Maximum number of retries allowed when attempting to remove an + * orphan archive status file. + */ +#define NUM_ORPHAN_CLEANUP_RETRIES 3 + /* ---------- * Local data @@ -226,11 +237,8 @@ PgArchiverMain(int argc, char *argv[]) pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, pgarch_waken); pqsignal(SIGUSR2, pgarch_waken_stop); + /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); PG_SETMASK(&UnBlockSig); /* @@ -393,6 +401,8 @@ pgarch_MainLoop(void) WAIT_EVENT_ARCHIVER_MAIN); if (rc & WL_TIMEOUT) wakened = true; + if (rc & WL_POSTMASTER_DEATH) + time_to_stop = true; } else wakened = true; @@ -403,7 +413,7 @@ pgarch_MainLoop(void) * or after completing one more archiving cycle after receiving * SIGUSR2. */ - } while (PostmasterIsAlive() && !time_to_stop); + } while (!time_to_stop); } /* @@ -425,9 +435,13 @@ pgarch_ArchiverCopyLoop(void) while (pgarch_readyXlog(xlog)) { int failures = 0; + int failures_orphan = 0; for (;;) { + struct stat stat_buf; + char pathname[MAXPGPATH]; + /* * Do not initiate any more archive commands after receiving * SIGTERM, nor after the postmaster has died unexpectedly. The @@ -457,6 +471,46 @@ pgarch_ArchiverCopyLoop(void) return; } + /* + * Since archive status files are not removed in a durable manner, + * a system crash could leave behind .ready files for WAL segments + * that have already been recycled or removed. In this case, + * simply remove the orphan status file and move on. unlink() is + * used here as even on subsequent crashes the same orphan files + * would get removed, so there is no need to worry about + * durability. + */ + snprintf(pathname, MAXPGPATH, XLOGDIR "/%s", xlog); + if (stat(pathname, &stat_buf) != 0 && errno == ENOENT) + { + char xlogready[MAXPGPATH]; + + StatusFilePath(xlogready, xlog, ".ready"); + if (unlink(xlogready) == 0) + { + ereport(WARNING, + (errmsg("removed orphan archive status file \"%s\"", + xlogready))); + + /* leave loop and move to the next status file */ + break; + } + + if (++failures_orphan >= NUM_ORPHAN_CLEANUP_RETRIES) + { + ereport(WARNING, + (errmsg("removal of orphan archive status file \"%s\" failed too many times, will try again later", + xlogready))); + + /* give up cleanup of orphan status files */ + return; + } + + /* wait a bit before retrying */ + pg_usleep(1000000L); + continue; + } + if (pgarch_archiveXlog(xlog)) { /* successful */ @@ -573,13 +627,11 @@ pgarch_archiveXlog(char *xlog) * If either the shell itself, or a called command, died on a signal, * abort the archiver. We do this because system() ignores SIGINT and * SIGQUIT while waiting; so a signal is very likely something that - * should have interrupted us too. If we overreact it's no big deal, - * the postmaster will just start the archiver again. - * - * Per the Single Unix Spec, shells report exit status > 128 when a - * called command died on a signal. + * should have interrupted us too. Also die if the shell got a hard + * "command not found" type of error. If we overreact it's no big + * deal, the postmaster will just start the archiver again. */ - int lev = (WIFSIGNALED(rc) || WEXITSTATUS(rc) > 128) ? FATAL : LOG; + int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG; if (WIFEXITED(rc)) { @@ -598,17 +650,10 @@ pgarch_archiveXlog(char *xlog) errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."), errdetail("The failed archive command was: %s", xlogarchcmd))); -#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST - ereport(lev, - (errmsg("archive command was terminated by signal %d: %s", - WTERMSIG(rc), - WTERMSIG(rc) < NSIG ? sys_siglist[WTERMSIG(rc)] : "(unknown)"), - errdetail("The failed archive command was: %s", - xlogarchcmd))); #else ereport(lev, - (errmsg("archive command was terminated by signal %d", - WTERMSIG(rc)), + (errmsg("archive command was terminated by signal %d: %s", + WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))), errdetail("The failed archive command was: %s", xlogarchcmd))); #endif @@ -650,11 +695,12 @@ pgarch_archiveXlog(char *xlog) * 2) because the oldest ones will sooner become candidates for * recycling at time of checkpoint * - * NOTE: the "oldest" comparison will presently consider all segments of - * a timeline with a smaller ID to be older than all segments of a timeline - * with a larger ID; the net result being that past timelines are given - * higher priority for archiving. This seems okay, or at least not - * obviously worth changing. + * NOTE: the "oldest" comparison will consider any .history file to be older + * than any other file except another .history file. Segments on a timeline + * with a smaller ID will be older than all segments on a timeline with a + * larger ID; the net result being that past timelines are given higher + * priority for archiving. This seems okay, or at least not obviously worth + * changing. */ static bool pgarch_readyXlog(char *xlog) @@ -666,10 +712,10 @@ pgarch_readyXlog(char *xlog) * of calls, so.... */ char XLogArchiveStatusDir[MAXPGPATH]; - char newxlog[MAX_XFN_CHARS + 6 + 1]; DIR *rldir; struct dirent *rlde; bool found = false; + bool historyFound = false; snprintf(XLogArchiveStatusDir, MAXPGPATH, XLOGDIR "/archive_status"); rldir = AllocateDir(XLogArchiveStatusDir); @@ -677,32 +723,51 @@ pgarch_readyXlog(char *xlog) while ((rlde = ReadDir(rldir, XLogArchiveStatusDir)) != NULL) { int basenamelen = (int) strlen(rlde->d_name) - 6; + char basename[MAX_XFN_CHARS + 1]; + bool ishistory; + + /* Ignore entries with unexpected number of characters */ + if (basenamelen < MIN_XFN_CHARS || + basenamelen > MAX_XFN_CHARS) + continue; + + /* Ignore entries with unexpected characters */ + if (strspn(rlde->d_name, VALID_XFN_CHARS) < basenamelen) + continue; + + /* Ignore anything not suffixed with .ready */ + if (strcmp(rlde->d_name + basenamelen, ".ready") != 0) + continue; + + /* Truncate off the .ready */ + memcpy(basename, rlde->d_name, basenamelen); + basename[basenamelen] = '\0'; + + /* Is this a history file? */ + ishistory = IsTLHistoryFileName(basename); - if (basenamelen >= MIN_XFN_CHARS && - basenamelen <= MAX_XFN_CHARS && - strspn(rlde->d_name, VALID_XFN_CHARS) >= basenamelen && - strcmp(rlde->d_name + basenamelen, ".ready") == 0) + /* + * Consume the file to archive. History files have the highest + * priority. If this is the first file or the first history file + * ever, copy it. In the presence of a history file already chosen as + * target, ignore all other files except history files which have been + * generated for an older timeline than what is already chosen as + * target to archive. + */ + if (!found || (ishistory && !historyFound)) { - if (!found) - { - strcpy(newxlog, rlde->d_name); - found = true; - } - else - { - if (strcmp(rlde->d_name, newxlog) < 0) - strcpy(newxlog, rlde->d_name); - } + strcpy(xlog, basename); + found = true; + historyFound = ishistory; + } + else if (ishistory || !historyFound) + { + if (strcmp(basename, xlog) < 0) + strcpy(xlog, basename); } } FreeDir(rldir); - if (found) - { - /* truncate off the .ready */ - newxlog[strlen(newxlog) - 6] = '\0'; - strcpy(xlog, newxlog); - } return found; } diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 96ba2163878..011076c3e3e 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -11,7 +11,7 @@ * - Add a pgstat config column to pg_database, so this * entire thing can be enabled/disabled on a per db basis. * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/backend/postmaster/pgstat.c * ---------- @@ -36,6 +36,7 @@ #include "access/heapam.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/twophase_rmgr.h" #include "access/xact.h" @@ -67,7 +68,6 @@ #include "utils/rel.h" #include "utils/snapmgr.h" #include "utils/timestamp.h" -#include "utils/tqual.h" /* ---------- @@ -291,7 +291,7 @@ static void pgstat_sighup_handler(SIGNAL_ARGS); static PgStat_StatDBEntry *pgstat_get_db_entry(Oid databaseid, bool create); static PgStat_StatTabEntry *pgstat_get_tab_entry(PgStat_StatDBEntry *dbentry, - Oid tableoid, bool create); + Oid tableoid, bool create); static void pgstat_write_statsfiles(bool permanent, bool allDbs); static void pgstat_write_db_statsfile(PgStat_StatDBEntry *dbentry, bool permanent); static HTAB *pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep); @@ -304,7 +304,7 @@ static bool pgstat_db_requested(Oid databaseid); static void pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg); static void pgstat_send_funcstats(void); -static HTAB *pgstat_collect_oids(Oid catalogid); +static HTAB *pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid); static PgStat_TableStatus *get_tabstat_entry(Oid rel_id, bool isshared); @@ -335,6 +335,7 @@ static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len); static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len); static void pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len); static void pgstat_recv_deadlock(PgStat_MsgDeadlock *msg, int len); +static void pgstat_recv_checksum_failure(PgStat_MsgChecksumFailure *msg, int len); static void pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len); /* ------------------------------------------------------------ @@ -892,7 +893,7 @@ pgstat_report_stat(bool force) this_msg->m_nentries = 0; } } - /* zero out TableStatus structs after use */ + /* zero out PgStat_TableStatus structs after use */ MemSet(tsa->tsa_entries, 0, tsa->tsa_used * sizeof(PgStat_TableStatus)); tsa->tsa_used = 0; @@ -1042,7 +1043,7 @@ pgstat_vacuum_stat(void) /* * Read pg_database and make a list of OIDs of all existing databases */ - htab = pgstat_collect_oids(DatabaseRelationId); + htab = pgstat_collect_oids(DatabaseRelationId, Anum_pg_database_oid); /* * Search the database hash table for dead databases and tell the @@ -1076,7 +1077,7 @@ pgstat_vacuum_stat(void) /* * Similarly to above, make a list of all known relations in this DB. */ - htab = pgstat_collect_oids(RelationRelationId); + htab = pgstat_collect_oids(RelationRelationId, Anum_pg_class_oid); /* * Initialize our messages table counter to zero @@ -1140,7 +1141,7 @@ pgstat_vacuum_stat(void) if (dbentry->functions != NULL && hash_get_num_entries(dbentry->functions) > 0) { - htab = pgstat_collect_oids(ProcedureRelationId); + htab = pgstat_collect_oids(ProcedureRelationId, Anum_pg_proc_oid); pgstat_setheader(&f_msg.m_hdr, PGSTAT_MTYPE_FUNCPURGE); f_msg.m_databaseid = MyDatabaseId; @@ -1201,12 +1202,12 @@ pgstat_vacuum_stat(void) * ---------- */ static HTAB * -pgstat_collect_oids(Oid catalogid) +pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid) { HTAB *htab; HASHCTL hash_ctl; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; Snapshot snapshot; @@ -1219,20 +1220,24 @@ pgstat_collect_oids(Oid catalogid) &hash_ctl, HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - rel = heap_open(catalogid, AccessShareLock); + rel = table_open(catalogid, AccessShareLock); snapshot = RegisterSnapshot(GetLatestSnapshot()); - scan = heap_beginscan(rel, snapshot, 0, NULL); + scan = table_beginscan(rel, snapshot, 0, NULL); while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { - Oid thisoid = HeapTupleGetOid(tup); + Oid thisoid; + bool isnull; + + thisoid = heap_getattr(tup, anum_oid, RelationGetDescr(rel), &isnull); + Assert(!isnull); CHECK_FOR_INTERRUPTS(); (void) hash_search(htab, (void *) &thisoid, HASH_ENTER, NULL); } - heap_endscan(scan); + table_endscan(scan); UnregisterSnapshot(snapshot); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); return htab; } @@ -1515,6 +1520,42 @@ pgstat_report_deadlock(void) pgstat_send(&msg, sizeof(msg)); } + + +/* -------- + * pgstat_report_checksum_failures_in_db() - + * + * Tell the collector about one or more checksum failures. + * -------- + */ +void +pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount) +{ + PgStat_MsgChecksumFailure msg; + + if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts) + return; + + pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CHECKSUMFAILURE); + msg.m_databaseid = dboid; + msg.m_failurecount = failurecount; + msg.m_failure_time = GetCurrentTimestamp(); + + pgstat_send(&msg, sizeof(msg)); +} + +/* -------- + * pgstat_report_checksum_failure() - + * + * Tell the collector about a checksum failure. + * -------- + */ +void +pgstat_report_checksum_failure(void) +{ + pgstat_report_checksum_failures_in_db(MyDatabaseId, 1); +} + /* -------- * pgstat_report_tempfile() - * @@ -1578,7 +1619,7 @@ pgstat_send_inquiry(TimestampTz clock_time, TimestampTz cutoff_time, Oid databas * Called by the executor before invoking a function. */ void -pgstat_init_function_usage(FunctionCallInfoData *fcinfo, +pgstat_init_function_usage(FunctionCallInfo fcinfo, PgStat_FunctionCallUsage *fcu) { PgStat_BackendFunctionEntry *htabent; @@ -2050,18 +2091,22 @@ pgstat_update_heap_dead_tuples(Relation rel, int delta) * ---------- */ void -AtEOXact_PgStat(bool isCommit) +AtEOXact_PgStat(bool isCommit, bool parallel) { PgStat_SubXactStatus *xact_state; - /* - * Count transaction commit or abort. (We use counters, not just bools, - * in case the reporting message isn't sent right away.) - */ - if (isCommit) - pgStatXactCommit++; - else - pgStatXactRollback++; + /* Don't count parallel worker transaction stats */ + if (!parallel) + { + /* + * Count transaction commit or abort. (We use counters, not just + * bools, in case the reporting message isn't sent right away.) + */ + if (isCommit) + pgStatXactCommit++; + else + pgStatXactRollback++; + } /* * Transfer transactional insert/update counts into the base tabstat @@ -2595,6 +2640,9 @@ static Size BackendActivityBufferSize = 0; #ifdef USE_SSL static PgBackendSSLStatus *BackendSslStatusBuffer = NULL; #endif +#ifdef ENABLE_GSS +static PgBackendGSSStatus *BackendGssStatusBuffer = NULL; +#endif /* @@ -2650,7 +2698,7 @@ CreateSharedBackendStatus(void) } /* Create or attach to the shared appname buffer */ - size = mul_size(NAMEDATALEN, MaxBackends); + size = mul_size(NAMEDATALEN, NumBackendStatSlots); BackendAppnameBuffer = (char *) ShmemInitStruct("Backend Application Name Buffer", size, &found); @@ -2668,7 +2716,7 @@ CreateSharedBackendStatus(void) } /* Create or attach to the shared client hostname buffer */ - size = mul_size(NAMEDATALEN, MaxBackends); + size = mul_size(NAMEDATALEN, NumBackendStatSlots); BackendClientHostnameBuffer = (char *) ShmemInitStruct("Backend Client Host Name Buffer", size, &found); @@ -2695,7 +2743,7 @@ CreateSharedBackendStatus(void) if (!found) { - MemSet(BackendActivityBuffer, 0, size); + MemSet(BackendActivityBuffer, 0, BackendActivityBufferSize); /* Initialize st_activity pointers. */ buffer = BackendActivityBuffer; @@ -2727,6 +2775,28 @@ CreateSharedBackendStatus(void) } } #endif + +#ifdef ENABLE_GSS + /* Create or attach to the shared GSSAPI status buffer */ + size = mul_size(sizeof(PgBackendGSSStatus), NumBackendStatSlots); + BackendGssStatusBuffer = (PgBackendGSSStatus *) + ShmemInitStruct("Backend GSS Status Buffer", size, &found); + + if (!found) + { + PgBackendGSSStatus *ptr; + + MemSet(BackendGssStatusBuffer, 0, size); + + /* Initialize st_gssstatus pointers. */ + ptr = BackendGssStatusBuffer; + for (i = 0; i < NumBackendStatSlots; i++) + { + BackendStatusArray[i].st_gssstatus = ptr; + ptr++; + } + } +#endif } @@ -2779,74 +2849,80 @@ pgstat_initialize(void) * Apart from auxiliary processes, MyBackendId, MyDatabaseId, * session userid, and application_name must be set for a * backend (hence, this cannot be combined with pgstat_initialize). + * Note also that we must be inside a transaction if this isn't an aux + * process, as we may need to do encoding conversion on some strings. * ---------- */ void pgstat_bestart(void) { - TimestampTz proc_start_timestamp; - SockAddr clientaddr; - volatile PgBackendStatus *beentry; + volatile PgBackendStatus *vbeentry = MyBEEntry; + PgBackendStatus lbeentry; +#ifdef USE_SSL + PgBackendSSLStatus lsslstatus; +#endif +#ifdef ENABLE_GSS + PgBackendGSSStatus lgssstatus; +#endif + + /* pgstats state must be initialized from pgstat_initialize() */ + Assert(vbeentry != NULL); /* - * To minimize the time spent modifying the PgBackendStatus entry, fetch - * all the needed data first. + * To minimize the time spent modifying the PgBackendStatus entry, and + * avoid risk of errors inside the critical section, we first copy the + * shared-memory struct to a local variable, then modify the data in the + * local variable, then copy the local variable back to shared memory. + * Only the last step has to be inside the critical section. * - * If we have a MyProcPort, use its session start time (for consistency, - * and to save a kernel call). + * Most of the data we copy from shared memory is just going to be + * overwritten, but the struct's not so large that it's worth the + * maintenance hassle to copy only the needful fields. */ - if (MyProcPort) - proc_start_timestamp = MyProcPort->SessionStartTime; - else - proc_start_timestamp = GetCurrentTimestamp(); + memcpy(&lbeentry, + unvolatize(PgBackendStatus *, vbeentry), + sizeof(PgBackendStatus)); - /* - * We may not have a MyProcPort (eg, if this is the autovacuum process). - * If so, use all-zeroes client address, which is dealt with specially in - * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port. - */ - if (MyProcPort) - memcpy(&clientaddr, &MyProcPort->raddr, sizeof(clientaddr)); - else - MemSet(&clientaddr, 0, sizeof(clientaddr)); + /* These structs can just start from zeroes each time, though */ +#ifdef USE_SSL + memset(&lsslstatus, 0, sizeof(lsslstatus)); +#endif +#ifdef ENABLE_GSS + memset(&lgssstatus, 0, sizeof(lgssstatus)); +#endif /* - * Initialize my status entry, following the protocol of bumping - * st_changecount before and after; and make sure it's even afterwards. We - * use a volatile pointer here to ensure the compiler doesn't try to get - * cute. + * Now fill in all the fields of lbeentry, except for strings that are + * out-of-line data. Those have to be handled separately, below. */ - beentry = MyBEEntry; - - /* pgstats state must be initialized from pgstat_initialize() */ - Assert(beentry != NULL); + lbeentry.st_procpid = MyProcPid; if (MyBackendId != InvalidBackendId) { if (IsAutoVacuumLauncherProcess()) { /* Autovacuum Launcher */ - beentry->st_backendType = B_AUTOVAC_LAUNCHER; + lbeentry.st_backendType = B_AUTOVAC_LAUNCHER; } else if (IsAutoVacuumWorkerProcess()) { /* Autovacuum Worker */ - beentry->st_backendType = B_AUTOVAC_WORKER; + lbeentry.st_backendType = B_AUTOVAC_WORKER; } else if (am_walsender) { /* Wal sender */ - beentry->st_backendType = B_WAL_SENDER; + lbeentry.st_backendType = B_WAL_SENDER; } else if (IsBackgroundWorker) { /* bgworker */ - beentry->st_backendType = B_BG_WORKER; + lbeentry.st_backendType = B_BG_WORKER; } else { /* client-backend */ - beentry->st_backendType = B_BACKEND; + lbeentry.st_backendType = B_BACKEND; } } else @@ -2856,79 +2932,92 @@ pgstat_bestart(void) switch (MyAuxProcType) { case StartupProcess: - beentry->st_backendType = B_STARTUP; + lbeentry.st_backendType = B_STARTUP; break; case BgWriterProcess: - beentry->st_backendType = B_BG_WRITER; + lbeentry.st_backendType = B_BG_WRITER; break; case CheckpointerProcess: - beentry->st_backendType = B_CHECKPOINTER; + lbeentry.st_backendType = B_CHECKPOINTER; break; case WalWriterProcess: - beentry->st_backendType = B_WAL_WRITER; + lbeentry.st_backendType = B_WAL_WRITER; break; case WalReceiverProcess: - beentry->st_backendType = B_WAL_RECEIVER; + lbeentry.st_backendType = B_WAL_RECEIVER; break; default: elog(FATAL, "unrecognized process type: %d", (int) MyAuxProcType); - proc_exit(1); } } - do - { - pgstat_increment_changecount_before(beentry); - } while ((beentry->st_changecount & 1) == 0); - - beentry->st_procpid = MyProcPid; - beentry->st_proc_start_timestamp = proc_start_timestamp; - beentry->st_activity_start_timestamp = 0; - beentry->st_state_start_timestamp = 0; - beentry->st_xact_start_timestamp = 0; - beentry->st_databaseid = MyDatabaseId; + lbeentry.st_proc_start_timestamp = MyStartTimestamp; + lbeentry.st_activity_start_timestamp = 0; + lbeentry.st_state_start_timestamp = 0; + lbeentry.st_xact_start_timestamp = 0; + lbeentry.st_databaseid = MyDatabaseId; /* We have userid for client-backends, wal-sender and bgworker processes */ - if (beentry->st_backendType == B_BACKEND - || beentry->st_backendType == B_WAL_SENDER - || beentry->st_backendType == B_BG_WORKER) - beentry->st_userid = GetSessionUserId(); + if (lbeentry.st_backendType == B_BACKEND + || lbeentry.st_backendType == B_WAL_SENDER + || lbeentry.st_backendType == B_BG_WORKER) + lbeentry.st_userid = GetSessionUserId(); else - beentry->st_userid = InvalidOid; + lbeentry.st_userid = InvalidOid; - beentry->st_clientaddr = clientaddr; - if (MyProcPort && MyProcPort->remote_hostname) - strlcpy(beentry->st_clienthostname, MyProcPort->remote_hostname, - NAMEDATALEN); + /* + * We may not have a MyProcPort (eg, if this is the autovacuum process). + * If so, use all-zeroes client address, which is dealt with specially in + * pg_stat_get_backend_client_addr and pg_stat_get_backend_client_port. + */ + if (MyProcPort) + memcpy(&lbeentry.st_clientaddr, &MyProcPort->raddr, + sizeof(lbeentry.st_clientaddr)); else - beentry->st_clienthostname[0] = '\0'; + MemSet(&lbeentry.st_clientaddr, 0, sizeof(lbeentry.st_clientaddr)); + #ifdef USE_SSL if (MyProcPort && MyProcPort->ssl != NULL) { - beentry->st_ssl = true; - beentry->st_sslstatus->ssl_bits = be_tls_get_cipher_bits(MyProcPort); - beentry->st_sslstatus->ssl_compression = be_tls_get_compression(MyProcPort); - strlcpy(beentry->st_sslstatus->ssl_version, be_tls_get_version(MyProcPort), NAMEDATALEN); - strlcpy(beentry->st_sslstatus->ssl_cipher, be_tls_get_cipher(MyProcPort), NAMEDATALEN); - be_tls_get_peerdn_name(MyProcPort, beentry->st_sslstatus->ssl_clientdn, NAMEDATALEN); + lbeentry.st_ssl = true; + lsslstatus.ssl_bits = be_tls_get_cipher_bits(MyProcPort); + lsslstatus.ssl_compression = be_tls_get_compression(MyProcPort); + strlcpy(lsslstatus.ssl_version, be_tls_get_version(MyProcPort), NAMEDATALEN); + strlcpy(lsslstatus.ssl_cipher, be_tls_get_cipher(MyProcPort), NAMEDATALEN); + be_tls_get_peer_subject_name(MyProcPort, lsslstatus.ssl_client_dn, NAMEDATALEN); + be_tls_get_peer_serial(MyProcPort, lsslstatus.ssl_client_serial, NAMEDATALEN); + be_tls_get_peer_issuer_name(MyProcPort, lsslstatus.ssl_issuer_dn, NAMEDATALEN); } else { - beentry->st_ssl = false; + lbeentry.st_ssl = false; } #else - beentry->st_ssl = false; + lbeentry.st_ssl = false; +#endif + +#ifdef ENABLE_GSS + if (MyProcPort && MyProcPort->gss != NULL) + { + lbeentry.st_gss = true; + lgssstatus.gss_auth = be_gssapi_get_auth(MyProcPort); + lgssstatus.gss_enc = be_gssapi_get_enc(MyProcPort); + + if (lgssstatus.gss_auth) + strlcpy(lgssstatus.gss_princ, be_gssapi_get_princ(MyProcPort), NAMEDATALEN); + } + else + { + lbeentry.st_gss = false; + } +#else + lbeentry.st_gss = false; #endif - beentry->st_state = STATE_UNDEFINED; - beentry->st_appname[0] = '\0'; - beentry->st_activity_raw[0] = '\0'; - /* Also make sure the last byte in each string area is always 0 */ - beentry->st_clienthostname[NAMEDATALEN - 1] = '\0'; - beentry->st_appname[NAMEDATALEN - 1] = '\0'; - beentry->st_activity_raw[pgstat_track_activity_query_size - 1] = '\0'; - beentry->st_progress_command = PROGRESS_COMMAND_INVALID; - beentry->st_progress_command_target = InvalidOid; + + lbeentry.st_state = STATE_UNDEFINED; + lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID; + lbeentry.st_progress_command_target = InvalidOid; /* * we don't zero st_progress_param here to save cycles; nobody should @@ -2936,7 +3025,45 @@ pgstat_bestart(void) * than PROGRESS_COMMAND_INVALID */ - pgstat_increment_changecount_after(beentry); + /* + * We're ready to enter the critical section that fills the shared-memory + * status entry. We follow the protocol of bumping st_changecount before + * and after; and make sure it's even afterwards. We use a volatile + * pointer here to ensure the compiler doesn't try to get cute. + */ + PGSTAT_BEGIN_WRITE_ACTIVITY(vbeentry); + + /* make sure we'll memcpy the same st_changecount back */ + lbeentry.st_changecount = vbeentry->st_changecount; + + memcpy(unvolatize(PgBackendStatus *, vbeentry), + &lbeentry, + sizeof(PgBackendStatus)); + + /* + * We can write the out-of-line strings and structs using the pointers + * that are in lbeentry; this saves some de-volatilizing messiness. + */ + lbeentry.st_appname[0] = '\0'; + if (MyProcPort && MyProcPort->remote_hostname) + strlcpy(lbeentry.st_clienthostname, MyProcPort->remote_hostname, + NAMEDATALEN); + else + lbeentry.st_clienthostname[0] = '\0'; + lbeentry.st_activity_raw[0] = '\0'; + /* Also make sure the last byte in each string area is always 0 */ + lbeentry.st_appname[NAMEDATALEN - 1] = '\0'; + lbeentry.st_clienthostname[NAMEDATALEN - 1] = '\0'; + lbeentry.st_activity_raw[pgstat_track_activity_query_size - 1] = '\0'; + +#ifdef USE_SSL + memcpy(lbeentry.st_sslstatus, &lsslstatus, sizeof(PgBackendSSLStatus)); +#endif +#ifdef ENABLE_GSS + memcpy(lbeentry.st_gssstatus, &lgssstatus, sizeof(PgBackendGSSStatus)); +#endif + + PGSTAT_END_WRITE_ACTIVITY(vbeentry); /* Update app name to current GUC setting */ if (application_name) @@ -2971,11 +3098,11 @@ pgstat_beshutdown_hook(int code, Datum arg) * before and after. We use a volatile pointer here to ensure the * compiler doesn't try to get cute. */ - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_procpid = 0; /* mark invalid */ - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } @@ -3014,7 +3141,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str) * non-disabled state. As our final update, change the state and * clear fields we will not be updating anymore. */ - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_state = STATE_DISABLED; beentry->st_state_start_timestamp = 0; beentry->st_activity_raw[0] = '\0'; @@ -3022,14 +3149,14 @@ pgstat_report_activity(BackendState state, const char *cmd_str) /* st_xact_start_timestamp and wait_event_info are also disabled */ beentry->st_xact_start_timestamp = 0; proc->wait_event_info = 0; - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } return; } /* - * To minimize the time spent modifying the entry, fetch all the needed - * data first. + * To minimize the time spent modifying the entry, and avoid risk of + * errors inside the critical section, fetch all the needed data first. */ start_timestamp = GetCurrentStatementStartTimestamp(); if (cmd_str != NULL) @@ -3046,7 +3173,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str) /* * Now update the status entry */ - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_state = state; beentry->st_state_start_timestamp = current_timestamp; @@ -3058,7 +3185,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str) beentry->st_activity_start_timestamp = start_timestamp; } - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /*----------- @@ -3076,11 +3203,11 @@ pgstat_progress_start_command(ProgressCommandType cmdtype, Oid relid) if (!beentry || !pgstat_track_activities) return; - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_progress_command = cmdtype; beentry->st_progress_command_target = relid; MemSet(&beentry->st_progress_param, 0, sizeof(beentry->st_progress_param)); - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /*----------- @@ -3099,9 +3226,9 @@ pgstat_progress_update_param(int index, int64 val) if (!beentry || !pgstat_track_activities) return; - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_progress_param[index] = val; - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /*----------- @@ -3121,7 +3248,7 @@ pgstat_progress_update_multi_param(int nparam, const int *index, if (!beentry || !pgstat_track_activities || nparam == 0) return; - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); for (i = 0; i < nparam; ++i) { @@ -3130,7 +3257,7 @@ pgstat_progress_update_multi_param(int nparam, const int *index, beentry->st_progress_param[index[i]] = val[i]; } - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /*----------- @@ -3145,16 +3272,16 @@ pgstat_progress_end_command(void) { volatile PgBackendStatus *beentry = MyBEEntry; - if (!beentry) + if (!beentry || !pgstat_track_activities) return; - if (!pgstat_track_activities - && beentry->st_progress_command == PROGRESS_COMMAND_INVALID) + + if (beentry->st_progress_command == PROGRESS_COMMAND_INVALID) return; - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->st_progress_command = PROGRESS_COMMAND_INVALID; beentry->st_progress_command_target = InvalidOid; - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /* ---------- @@ -3180,12 +3307,12 @@ pgstat_report_appname(const char *appname) * st_changecount before and after. We use a volatile pointer here to * ensure the compiler doesn't try to get cute. */ - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); memcpy((char *) beentry->st_appname, appname, len); beentry->st_appname[len] = '\0'; - pgstat_increment_changecount_after(beentry); + PGSTAT_END_WRITE_ACTIVITY(beentry); } /* @@ -3205,9 +3332,11 @@ pgstat_report_xact_timestamp(TimestampTz tstamp) * st_changecount before and after. We use a volatile pointer here to * ensure the compiler doesn't try to get cute. */ - pgstat_increment_changecount_before(beentry); + PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); + beentry->st_xact_start_timestamp = tstamp; - pgstat_increment_changecount_after(beentry); + + PGSTAT_END_WRITE_ACTIVITY(beentry); } /* ---------- @@ -3224,9 +3353,13 @@ pgstat_read_current_status(void) LocalPgBackendStatus *localtable; LocalPgBackendStatus *localentry; char *localappname, + *localclienthostname, *localactivity; #ifdef USE_SSL PgBackendSSLStatus *localsslstatus; +#endif +#ifdef ENABLE_GSS + PgBackendGSSStatus *localgssstatus; #endif int i; @@ -3236,20 +3369,36 @@ pgstat_read_current_status(void) pgstat_setup_memcxt(); + /* + * Allocate storage for local copy of state data. We can presume that + * none of these requests overflow size_t, because we already calculated + * the same values using mul_size during shmem setup. However, with + * probably-silly values of pgstat_track_activity_query_size and + * max_connections, the localactivity buffer could exceed 1GB, so use + * "huge" allocation for that one. + */ localtable = (LocalPgBackendStatus *) MemoryContextAlloc(pgStatLocalContext, sizeof(LocalPgBackendStatus) * NumBackendStatSlots); localappname = (char *) MemoryContextAlloc(pgStatLocalContext, NAMEDATALEN * NumBackendStatSlots); - localactivity = (char *) + localclienthostname = (char *) MemoryContextAlloc(pgStatLocalContext, - pgstat_track_activity_query_size * NumBackendStatSlots); + NAMEDATALEN * NumBackendStatSlots); + localactivity = (char *) + MemoryContextAllocHuge(pgStatLocalContext, + pgstat_track_activity_query_size * NumBackendStatSlots); #ifdef USE_SSL localsslstatus = (PgBackendSSLStatus *) MemoryContextAlloc(pgStatLocalContext, sizeof(PgBackendSSLStatus) * NumBackendStatSlots); #endif +#ifdef ENABLE_GSS + localgssstatus = (PgBackendGSSStatus *) + MemoryContextAlloc(pgStatLocalContext, + sizeof(PgBackendGSSStatus) * NumBackendStatSlots); +#endif localNumBackends = 0; @@ -3269,34 +3418,48 @@ pgstat_read_current_status(void) int before_changecount; int after_changecount; - pgstat_save_changecount_before(beentry, before_changecount); + pgstat_begin_read_activity(beentry, before_changecount); localentry->backendStatus.st_procpid = beentry->st_procpid; + /* Skip all the data-copying work if entry is not in use */ if (localentry->backendStatus.st_procpid > 0) { - memcpy(&localentry->backendStatus, (char *) beentry, sizeof(PgBackendStatus)); + memcpy(&localentry->backendStatus, unvolatize(PgBackendStatus *, beentry), sizeof(PgBackendStatus)); /* + * For each PgBackendStatus field that is a pointer, copy the + * pointed-to data, then adjust the local copy of the pointer + * field to point at the local copy of the data. + * * strcpy is safe even if the string is modified concurrently, * because there's always a \0 at the end of the buffer. */ strcpy(localappname, (char *) beentry->st_appname); localentry->backendStatus.st_appname = localappname; + strcpy(localclienthostname, (char *) beentry->st_clienthostname); + localentry->backendStatus.st_clienthostname = localclienthostname; strcpy(localactivity, (char *) beentry->st_activity_raw); localentry->backendStatus.st_activity_raw = localactivity; - localentry->backendStatus.st_ssl = beentry->st_ssl; #ifdef USE_SSL if (beentry->st_ssl) { memcpy(localsslstatus, beentry->st_sslstatus, sizeof(PgBackendSSLStatus)); localentry->backendStatus.st_sslstatus = localsslstatus; } +#endif +#ifdef ENABLE_GSS + if (beentry->st_gss) + { + memcpy(localgssstatus, beentry->st_gssstatus, sizeof(PgBackendGSSStatus)); + localentry->backendStatus.st_gssstatus = localgssstatus; + } #endif } - pgstat_save_changecount_after(beentry, after_changecount); - if (before_changecount == after_changecount && - (before_changecount & 1) == 0) + pgstat_end_read_activity(beentry, after_changecount); + + if (pgstat_read_activity_complete(before_changecount, + after_changecount)) break; /* Make sure we can break out of loop if stuck... */ @@ -3313,9 +3476,13 @@ pgstat_read_current_status(void) localentry++; localappname += NAMEDATALEN; + localclienthostname += NAMEDATALEN; localactivity += pgstat_track_activity_query_size; #ifdef USE_SSL localsslstatus++; +#endif +#ifdef ENABLE_GSS + localgssstatus++; #endif localNumBackends++; } @@ -3485,12 +3652,12 @@ pgstat_get_wait_activity(WaitEventActivity w) case WAIT_EVENT_CHECKPOINTER_MAIN: event_name = "CheckpointerMain"; break; - case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN: - event_name = "LogicalLauncherMain"; - break; case WAIT_EVENT_LOGICAL_APPLY_MAIN: event_name = "LogicalApplyMain"; break; + case WAIT_EVENT_LOGICAL_LAUNCHER_MAIN: + event_name = "LogicalLauncherMain"; + break; case WAIT_EVENT_PGSTAT_MAIN: event_name = "PgStatMain"; break; @@ -3555,6 +3722,9 @@ pgstat_get_wait_client(WaitEventClient w) case WAIT_EVENT_WAL_SENDER_WRITE_DATA: event_name = "WalSenderWriteData"; break; + case WAIT_EVENT_GSS_OPEN_SERVER: + event_name = "GSSOpenServer"; + break; /* no default case, so that compiler will warn */ } @@ -3583,6 +3753,15 @@ pgstat_get_wait_ipc(WaitEventIPC w) case WAIT_EVENT_BTREE_PAGE: event_name = "BtreePage"; break; + case WAIT_EVENT_CHECKPOINT_DONE: + event_name = "CheckpointDone"; + break; + case WAIT_EVENT_CHECKPOINT_START: + event_name = "CheckpointStart"; + break; + case WAIT_EVENT_CLOG_GROUP_UPDATE: + event_name = "ClogGroupUpdate"; + break; case WAIT_EVENT_EXECUTE_GATHER: event_name = "ExecuteGather"; break; @@ -3649,20 +3828,20 @@ pgstat_get_wait_ipc(WaitEventIPC w) case WAIT_EVENT_MQ_SEND: event_name = "MessageQueueSend"; break; - case WAIT_EVENT_PARALLEL_FINISH: - event_name = "ParallelFinish"; - break; case WAIT_EVENT_PARALLEL_BITMAP_SCAN: event_name = "ParallelBitmapScan"; break; case WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN: event_name = "ParallelCreateIndexScan"; break; + case WAIT_EVENT_PARALLEL_FINISH: + event_name = "ParallelFinish"; + break; case WAIT_EVENT_PROCARRAY_GROUP_UPDATE: event_name = "ProcArrayGroupUpdate"; break; - case WAIT_EVENT_CLOG_GROUP_UPDATE: - event_name = "ClogGroupUpdate"; + case WAIT_EVENT_PROMOTE: + event_name = "Promote"; break; case WAIT_EVENT_REPLICATION_ORIGIN_DROP: event_name = "ReplicationOriginDrop"; @@ -3793,7 +3972,7 @@ pgstat_get_wait_io(WaitEventIO w) event_name = "LockFileCreateSync"; break; case WAIT_EVENT_LOCK_FILE_CREATE_WRITE: - event_name = "LockFileCreateWRITE"; + event_name = "LockFileCreateWrite"; break; case WAIT_EVENT_LOCK_FILE_RECHECKDATADIR_READ: event_name = "LockFileReCheckDataDirRead"; @@ -3918,6 +4097,9 @@ pgstat_get_wait_io(WaitEventIO w) case WAIT_EVENT_WAL_READ: event_name = "WALRead"; break; + case WAIT_EVENT_WAL_SYNC: + event_name = "WALSync"; + break; case WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN: event_name = "WALSyncMethodAssign"; break; @@ -3978,14 +4160,14 @@ pgstat_get_backend_current_activity(int pid, bool checkUser) int before_changecount; int after_changecount; - pgstat_save_changecount_before(vbeentry, before_changecount); + pgstat_begin_read_activity(vbeentry, before_changecount); found = (vbeentry->st_procpid == pid); - pgstat_save_changecount_after(vbeentry, after_changecount); + pgstat_end_read_activity(vbeentry, after_changecount); - if (before_changecount == after_changecount && - (before_changecount & 1) == 0) + if (pgstat_read_activity_complete(before_changecount, + after_changecount)) break; /* Make sure we can break out of loop if stuck... */ @@ -4262,11 +4444,8 @@ PgstatCollectorMain(int argc, char *argv[]) pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGUSR1, SIG_IGN); pqsignal(SIGUSR2, SIG_IGN); + /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); PG_SETMASK(&UnBlockSig); /* @@ -4376,76 +4555,83 @@ PgstatCollectorMain(int argc, char *argv[]) break; case PGSTAT_MTYPE_INQUIRY: - pgstat_recv_inquiry((PgStat_MsgInquiry *) &msg, len); + pgstat_recv_inquiry(&msg.msg_inquiry, len); break; case PGSTAT_MTYPE_TABSTAT: - pgstat_recv_tabstat((PgStat_MsgTabstat *) &msg, len); + pgstat_recv_tabstat(&msg.msg_tabstat, len); break; case PGSTAT_MTYPE_TABPURGE: - pgstat_recv_tabpurge((PgStat_MsgTabpurge *) &msg, len); + pgstat_recv_tabpurge(&msg.msg_tabpurge, len); break; case PGSTAT_MTYPE_DROPDB: - pgstat_recv_dropdb((PgStat_MsgDropdb *) &msg, len); + pgstat_recv_dropdb(&msg.msg_dropdb, len); break; case PGSTAT_MTYPE_RESETCOUNTER: - pgstat_recv_resetcounter((PgStat_MsgResetcounter *) &msg, - len); + pgstat_recv_resetcounter(&msg.msg_resetcounter, len); break; case PGSTAT_MTYPE_RESETSHAREDCOUNTER: pgstat_recv_resetsharedcounter( - (PgStat_MsgResetsharedcounter *) &msg, + &msg.msg_resetsharedcounter, len); break; case PGSTAT_MTYPE_RESETSINGLECOUNTER: pgstat_recv_resetsinglecounter( - (PgStat_MsgResetsinglecounter *) &msg, + &msg.msg_resetsinglecounter, len); break; case PGSTAT_MTYPE_AUTOVAC_START: - pgstat_recv_autovac((PgStat_MsgAutovacStart *) &msg, len); + pgstat_recv_autovac(&msg.msg_autovacuum_start, len); break; case PGSTAT_MTYPE_VACUUM: - pgstat_recv_vacuum((PgStat_MsgVacuum *) &msg, len); + pgstat_recv_vacuum(&msg.msg_vacuum, len); break; case PGSTAT_MTYPE_ANALYZE: - pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, len); + pgstat_recv_analyze(&msg.msg_analyze, len); break; case PGSTAT_MTYPE_ARCHIVER: - pgstat_recv_archiver((PgStat_MsgArchiver *) &msg, len); + pgstat_recv_archiver(&msg.msg_archiver, len); break; case PGSTAT_MTYPE_BGWRITER: - pgstat_recv_bgwriter((PgStat_MsgBgWriter *) &msg, len); + pgstat_recv_bgwriter(&msg.msg_bgwriter, len); break; case PGSTAT_MTYPE_FUNCSTAT: - pgstat_recv_funcstat((PgStat_MsgFuncstat *) &msg, len); + pgstat_recv_funcstat(&msg.msg_funcstat, len); break; case PGSTAT_MTYPE_FUNCPURGE: - pgstat_recv_funcpurge((PgStat_MsgFuncpurge *) &msg, len); + pgstat_recv_funcpurge(&msg.msg_funcpurge, len); break; case PGSTAT_MTYPE_RECOVERYCONFLICT: - pgstat_recv_recoveryconflict((PgStat_MsgRecoveryConflict *) &msg, len); + pgstat_recv_recoveryconflict( + &msg.msg_recoveryconflict, + len); break; case PGSTAT_MTYPE_DEADLOCK: - pgstat_recv_deadlock((PgStat_MsgDeadlock *) &msg, len); + pgstat_recv_deadlock(&msg.msg_deadlock, len); break; case PGSTAT_MTYPE_TEMPFILE: - pgstat_recv_tempfile((PgStat_MsgTempFile *) &msg, len); + pgstat_recv_tempfile(&msg.msg_tempfile, len); + break; + + case PGSTAT_MTYPE_CHECKSUMFAILURE: + pgstat_recv_checksum_failure( + &msg.msg_checksumfailure, + len); break; default: @@ -4547,6 +4733,8 @@ reset_dbentry_counters(PgStat_StatDBEntry *dbentry) dbentry->n_temp_files = 0; dbentry->n_temp_bytes = 0; dbentry->n_deadlocks = 0; + dbentry->n_checksum_failures = 0; + dbentry->last_checksum_failure = 0; dbentry->n_block_read_time = 0; dbentry->n_block_write_time = 0; @@ -4800,7 +4988,7 @@ get_dbstat_filename(bool permanent, bool tempname, Oid databaseid, pgstat_stat_directory, databaseid, tempname ? "tmp" : "stat"); - if (printed > len) + if (printed >= len) elog(ERROR, "overlength pgstat path"); } @@ -5934,7 +6122,7 @@ pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len) } /* ---------- - * pgstat_recv_resetshared() - + * pgstat_recv_resetsharedcounter() - * * Reset some shared statistics of the cluster. * ---------- @@ -6189,6 +6377,23 @@ pgstat_recv_deadlock(PgStat_MsgDeadlock *msg, int len) dbentry->n_deadlocks++; } +/* ---------- + * pgstat_recv_checksum_failure() - + * + * Process a CHECKSUMFAILURE message. + * ---------- + */ +static void +pgstat_recv_checksum_failure(PgStat_MsgChecksumFailure *msg, int len) +{ + PgStat_StatDBEntry *dbentry; + + dbentry = pgstat_get_db_entry(msg->m_databaseid, true); + + dbentry->n_checksum_failures += msg->m_failurecount; + dbentry->last_checksum_failure = msg->m_failure_time; +} + /* ---------- * pgstat_recv_tempfile() - * diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index d948369f3ea..2a0677f9be5 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -32,7 +32,7 @@ * clients. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -99,6 +99,7 @@ #include "catalog/pg_control.h" #include "common/file_perm.h" #include "common/ip.h" +#include "common/string.h" #include "lib/ilist.h" #include "libpq/auth.h" #include "libpq/libpq.h" @@ -124,16 +125,13 @@ #include "tcop/tcopprot.h" #include "utils/builtins.h" #include "utils/datetime.h" -#include "utils/dynamic_loader.h" #include "utils/memutils.h" #include "utils/pidfile.h" #include "utils/ps_status.h" #include "utils/timeout.h" +#include "utils/timestamp.h" #include "utils/varlena.h" - -#ifdef EXEC_BACKEND #include "storage/spin.h" -#endif /* @@ -190,7 +188,10 @@ static Backend *ShmemBackendArray; BackgroundWorker *MyBgworkerEntry = NULL; - +extern slock_t *ShmemLock; +extern slock_t *ProcStructLock; +extern PGPROC *AuxiliaryProcs; +extern PMSignalData *PMSignalState; /* The socket number we are listening for connections on */ int PostPortNumber; @@ -353,6 +354,8 @@ bool ClientAuthInProgress = false; /* T during new-client bool redirection_done = false; /* stderr redirected for syslogger? */ +char* OnlineUpgradePath = (char*)""; + /* received START_AUTOVAC_LAUNCHER signal */ static volatile sig_atomic_t start_autovac_launcher = false; @@ -366,16 +369,6 @@ static volatile sig_atomic_t WalReceiverRequested = false; static volatile bool StartWorkerNeeded = true; static volatile bool HaveCrashedWorker = false; -#ifndef HAVE_STRONG_RANDOM -/* - * State for assigning cancel keys. - * Also, the global MyCancelKey passes the cancel key assigned to a given - * backend from the postmaster to that backend (via fork). - */ -static unsigned int random_seed = 0; -static struct timeval random_start_time; -#endif - #ifdef USE_SSL /* Set when and if SSL has been initialized properly */ static bool LoadedSSL = false; @@ -394,26 +387,26 @@ static void getInstallationPaths(const char *argv0); static void checkControlFile(void); static Port *ConnCreate(int serverFd); static void ConnFree(Port *port); -static void reset_shared(int port); +static void reset_shared(void); static void SIGHUP_handler(SIGNAL_ARGS); static void pmdie(SIGNAL_ARGS); static void reaper(SIGNAL_ARGS); static void sigusr1_handler(SIGNAL_ARGS); static void startup_die(SIGNAL_ARGS); -static void dummy_handler(SIGNAL_ARGS); +static void upgrade_handler(SIGNAL_ARGS); static void StartupPacketTimeoutHandler(void); static void CleanupBackend(int pid, int exitstatus); static bool CleanupBackgroundWorker(int pid, int exitstatus); static void HandleChildCrash(int pid, int exitstatus, const char *procname); static void LogChildExit(int lev, const char *procname, - int pid, int exitstatus); + int pid, int exitstatus); static void PostmasterStateMachine(void); static void BackendInitialize(Port *port); static void BackendRun(Port *port) pg_attribute_noreturn(); static void ExitPostmaster(int status) pg_attribute_noreturn(); static int ServerLoop(void); static int BackendStartup(Port *port); -static int ProcessStartupPacket(Port *port, bool SSLdone); +static int ProcessStartupPacket(Port *port, bool secure_done); static void SendNegotiateProtocolVersion(List *unrecognized_protocol_options); static void processCancelRequest(Port *port, void *pkt); static int initMasks(fd_set *rmask); @@ -493,6 +486,7 @@ typedef struct #ifndef WIN32 unsigned long UsedShmemSegID; #else + void *ShmemProtectiveRegion; HANDLE UsedShmemSegID; #endif void *UsedShmemSegAddr; @@ -519,6 +513,7 @@ typedef struct bool IsBinaryUpgrade; int max_safe_fds; int MaxBackends; + void* BackgroundWorkers; #ifdef WIN32 HANDLE PostmasterHandle; HANDLE initial_signal_pipe; @@ -539,7 +534,7 @@ static void restore_backend_variables(BackendParameters *param, Port *port); static bool save_backend_variables(BackendParameters *param, Port *port); #else static bool save_backend_variables(BackendParameters *param, Port *port, - HANDLE childProcess, pid_t childPid); + HANDLE childProcess, pid_t childPid); #endif static void ShmemBackendArrayAdd(Backend *bn); @@ -568,6 +563,240 @@ int postmaster_alive_fds[2] = {-1, -1}; HANDLE PostmasterHandle; #endif +typedef struct +{ + pgsocket ListenSocket[MAXLISTEN]; + char DataDir[MAXPGPATH]; +#ifndef WIN32 + unsigned long UsedShmemSegID; +#else + void *ShmemProtectiveRegion; + HANDLE UsedShmemSegID; +#endif + void *UsedShmemSegAddr; + void *AnonymousShmem; + int AnonymousShmemFile; + slock_t *ShmemLock; + VariableCache ShmemVariableCache; +#ifndef HAVE_SPINLOCKS + PGSemaphore *SpinlockSemaArray; +#endif + NamedLWLockTranche *NamedLWLockTrancheArray; + LWLockPadded *MainLWLockArray; + slock_t *ProcStructLock; + PROC_HDR *ProcGlobal; + PGPROC *AuxiliaryProcs; + PGPROC *PreparedXactProcs; + PMSignalData *PMSignalState; + int MaxBackends; + void* BackgroundWorkers; + bool redirection_done; +#ifdef WIN32 + HANDLE PostmasterHandle; + HANDLE initial_signal_pipe; + HANDLE syslogPipe[2]; +#else + int postmaster_alive_fds[2]; + int syslogPipe[2]; +#endif +} PostmasterParameters; + +static bool SavePostmasterParameters(void) +{ + PostmasterParameters param; + FILE *fp = AllocateFile("postmaster.params", PG_BINARY_W); + dlist_iter iter; + Backend *bp; + + if (!fp) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not create file \"postmaster.params\": %m"))); + return false; + } + strlcpy(param.DataDir, DataDir, MAXPGPATH); + + memcpy(¶m.ListenSocket, &ListenSocket, sizeof(ListenSocket)); +#ifdef WIN32 + param.ShmemProtectiveRegion = ShmemProtectiveRegion; +#endif + param.UsedShmemSegID = UsedShmemSegID; + param.UsedShmemSegAddr = UsedShmemSegAddr; + param.AnonymousShmem = AnonymousShmem; + param.AnonymousShmemFile = AnonymousShmemFile; + param.ShmemLock = ShmemLock; + param.ShmemVariableCache = ShmemVariableCache; + +#ifndef HAVE_SPINLOCKS + param.SpinlockSemaArray = SpinlockSemaArray; +#endif + param.NamedLWLockTrancheArray = NamedLWLockTrancheArray; + param.MainLWLockArray = MainLWLockArray; + param.ProcStructLock = ProcStructLock; + param.ProcGlobal = ProcGlobal; + param.AuxiliaryProcs = AuxiliaryProcs; + param.PreparedXactProcs = PreparedXactProcs; + param.PMSignalState = PMSignalState; + param.BackgroundWorkers = GetBackgroundWorkerEntries(); + + param.redirection_done = redirection_done; + + param.MaxBackends = MaxBackends; + +#ifdef WIN32 + param.PostmasterHandle = PostmasterHandle; + if (!write_duplicated_handle(¶m.initial_signal_pipe, + pgwin32_create_signal_listener(childPid), + childProcess)) + return false; +#else + memcpy(¶m.postmaster_alive_fds, &postmaster_alive_fds, + sizeof(postmaster_alive_fds)); +#endif + + memcpy(¶m.syslogPipe, &syslogPipe, sizeof(syslogPipe)); + + if (fwrite(¶m, sizeof(param), 1, fp) != 1) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not write to file \"postmaster.params\": %m"))); + FreeFile(fp); + return false; + } + + dlist_foreach(iter, &BackendList) + { + bp = dlist_container(Backend, elem, iter.cur); + if (bp->bkend_type == BACKEND_TYPE_NORMAL) + { + if (fwrite(bp, sizeof(*bp), 1, fp) != 1) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not write to file \"postmaster.params\": %m"))); + FreeFile(fp); + return false; + } + } + } + + /* Release file */ + if (FreeFile(fp)) + { + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not write to file \"postmaster.params\": %m"))); + return false; + } + return true; +} + +static bool +RestorePostmasterParameters(void) +{ + PostmasterParameters param; + FILE *fp = AllocateFile("postmaster.params", PG_BINARY_R); + Backend *bp = (Backend *) malloc(sizeof(Backend)); + + if (!fp) + { + write_stderr("%s: could not open file \"%s/postmaster.params\": %s\n", + progname, get_current_dir_name(), strerror(errno)); + return false; + } + if (fread(¶m, sizeof(param), 1, fp) != 1) + { + write_stderr("%s: could not read file \"postmaster.params\": %s\n", + progname, strerror(errno)); + FreeFile(fp); + return false; + } + + SetDataDir(param.DataDir); + + memcpy(&ListenSocket, ¶m.ListenSocket, sizeof(ListenSocket)); + +#ifdef WIN32 + ShmemProtectiveRegion = param.ShmemProtectiveRegion; +#endif + UsedShmemSegID = param.UsedShmemSegID; + UsedShmemSegAddr = param.UsedShmemSegAddr; + AnonymousShmem = param.AnonymousShmem; + AnonymousShmemFile = param.AnonymousShmemFile; + + ShmemLock = param.ShmemLock; + ShmemVariableCache = param.ShmemVariableCache; + +#ifndef HAVE_SPINLOCKS + SpinlockSemaArray = param.SpinlockSemaArray; +#endif + NamedLWLockTrancheArray = param.NamedLWLockTrancheArray; + MainLWLockArray = param.MainLWLockArray; + ProcStructLock = param.ProcStructLock; + ProcGlobal = param.ProcGlobal; + AuxiliaryProcs = param.AuxiliaryProcs; + PreparedXactProcs = param.PreparedXactProcs; + PMSignalState = param.PMSignalState; + redirection_done = param.redirection_done; + + SetBackgroundWorkerEntries(param.BackgroundWorkers); + MaxBackends = param.MaxBackends; + +#ifdef WIN32 + PostmasterHandle = param.PostmasterHandle; + pgwin32_initial_signal_pipe = param.initial_signal_pipe; +#else + memcpy(&postmaster_alive_fds, ¶m.postmaster_alive_fds, + sizeof(postmaster_alive_fds)); +#endif + + memcpy(&syslogPipe, ¶m.syslogPipe, sizeof(syslogPipe)); + + while (fread(bp, sizeof(*bp), 1, fp) == 1) + { + dlist_push_head(&BackendList, &bp->elem); + bp = (Backend *) malloc(sizeof(Backend)); + } + free(bp); + + /* Release file */ + if (FreeFile(fp)) + { + write_stderr("%s: could not close file \"postmaster.params\": %s\n", + progname, strerror(errno)); + return false; + } + return true; +} + +static void +UpgradePostgres(void) +{ + char* PostmasterArgs[] = {"postgres", "-U", "-D", ".", NULL}; + + if (*OnlineUpgradePath == '\0') + elog(ERROR, "Online upgrade path was not specified: alter system set online_ugrade_path='...' ; select pg_reload_conf()"); + + PG_SETMASK(&BlockSig); + IsOnlineUpgrade = true; + TerminateChildren(SIGTERM); + if (CheckpointerPID != 0) + signal_child(CheckpointerPID, SIGQUIT/*SIGUSR2*/); + + if (!SavePostmasterParameters()) + { + elog(LOG, "Failed to perform online upgrade"); + return; + } + elog(LOG, "Upgrade postgres to %s", OnlineUpgradePath); + PostmasterArgs[0] = psprintf("%s/postgres", OnlineUpgradePath); + execv(PostmasterArgs[0], PostmasterArgs); +} + + + /* * Postmaster main entry point */ @@ -581,9 +810,9 @@ PostmasterMain(int argc, char *argv[]) int i; char *output_config_variable = NULL; - MyProcPid = PostmasterPid = getpid(); + InitProcessGlobals(); - MyStartTime = time(NULL); + PostmasterPid = MyProcPid; IsPostmasterEnvironment = true; @@ -597,16 +826,6 @@ PostmasterMain(int argc, char *argv[]) */ umask(PG_MODE_MASK_OWNER); - /* - * Initialize random(3) so we don't get the same values in every run. - * - * Note: the seed is pretty predictable from externally-visible facts such - * as postmaster start time, so avoid using random() for security-critical - * random values during postmaster startup. At the time of first - * connection, PostmasterRandom will select a hopefully-more-random seed. - */ - srandom((unsigned int) (MyProcPid ^ MyStartTime)); - /* * By default, palloc() requests in the postmaster will be allocated in * the PostmasterContext, which is space that can be recycled by backends. @@ -652,11 +871,25 @@ PostmasterMain(int argc, char *argv[]) pqsignal(SIGPIPE, SIG_IGN); /* ignored */ pqsignal_no_restart(SIGUSR1, sigusr1_handler); /* message from child * process */ - pqsignal_no_restart(SIGUSR2, dummy_handler); /* unused, reserve for + pqsignal_no_restart(SIGUSR2, upgrade_handler); /* unused, reserve for * children */ pqsignal_no_restart(SIGCHLD, reaper); /* handle child termination */ + pqsignal_no_restart(SIGCHLD, reaper); /* handle child termination */ + + /* + * No other place in Postgres should touch SIGTTIN/SIGTTOU handling. We + * ignore those signals in a postmaster environment, so that there is no + * risk of a child process freezing up due to writing to stderr. But for + * a standalone backend, their default handling is reasonable. Hence, all + * child processes should just allow the inherited settings to stand. + */ +#ifdef SIGTTIN pqsignal(SIGTTIN, SIG_IGN); /* ignored */ +#endif +#ifdef SIGTTOU pqsignal(SIGTTOU, SIG_IGN); /* ignored */ +#endif + /* ignore SIGXFSZ, so that ulimit violations work like disk full */ #ifdef SIGXFSZ pqsignal(SIGXFSZ, SIG_IGN); /* ignored */ @@ -674,13 +907,16 @@ PostmasterMain(int argc, char *argv[]) * tcop/postgres.c (the option sets should not conflict) and with the * common help() function in main/main.c. */ - while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W:-:")) != -1) + while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:UW:-:")) != -1) { switch (opt) { case 'B': SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV); break; + case 'U': + IsOnlineUpgrade = true; + break; case 'b': /* Undocumented flag used for binary upgrades */ @@ -858,6 +1094,17 @@ PostmasterMain(int argc, char *argv[]) ExitPostmaster(1); } + if (IsOnlineUpgrade) + { + if (!RestorePostmasterParameters()) + { + write_stderr("%s: Failed to restore postmaster parameteres\n", + progname); + ExitPostmaster(1); + } + RegisterUnlinkLockFileCallback(); + } + /* * Locate the proper configuration files and data directory, and read * postgresql.conf for the first time. @@ -891,11 +1138,11 @@ PostmasterMain(int argc, char *argv[]) /* * Check for invalid combinations of GUC settings. */ - if (ReservedBackends + max_wal_senders >= MaxConnections) + if (ReservedBackends >= MaxConnections) { - write_stderr("%s: superuser_reserved_connections (%d) plus max_wal_senders (%d) must be less than max_connections (%d)\n", + write_stderr("%s: superuser_reserved_connections (%d) must be less than max_connections (%d)\n", progname, - ReservedBackends, max_wal_senders, MaxConnections); + ReservedBackends, MaxConnections); ExitPostmaster(1); } if (XLogArchiveMode > ARCHIVE_MODE_OFF && wal_level == WAL_LEVEL_MINIMAL) @@ -955,9 +1202,18 @@ PostmasterMain(int argc, char *argv[]) * so it must happen before opening sockets so that at exit, the socket * lockfiles go away after CloseServerPorts runs. */ - CreateDataDirLockFile(true); + if (!IsOnlineUpgrade) + CreateDataDirLockFile(true); - /* read control file (error checking and contains config) */ + /* + * Read the control file (for error checking and config info). + * + * Since we verify the control file's CRC, this has a useful side effect + * on machines where we need a run-time test for CRC support instructions. + * The postmaster will do the test once at startup, and then its child + * processes will inherit the correct function pointer and not need to + * repeat the test. + */ LocalProcessControlFile(false); /* @@ -985,10 +1241,131 @@ PostmasterMain(int argc, char *argv[]) process_shared_preload_libraries(); /* - * Now that loadable modules have had their chance to register background - * workers, calculate MaxBackends. + * Set up shared memory and semaphores. + */ + if (IsOnlineUpgrade) + { + PGSharedMemoryReAttach(); + InitShmemAccess(AnonymousShmem ? AnonymousShmem : UsedShmemSegAddr); + IsUnderPostmaster = true; + /* Attach process to shared data structures */ + CreateSharedMemoryAndSemaphores(); + IsUnderPostmaster = false; + } + else + { + /* + * Now that loadable modules have had their chance to register background + * workers, calculate MaxBackends. + */ + InitializeMaxBackends(); + reset_shared(); + } + + /* + * Estimate number of openable files. This must happen after setting up + * semaphores, because on some platforms semaphores count as open files. + */ + set_max_safe_fds(); + + /* + * Set reference point for stack-depth checking. + */ + set_stack_base(); + + /* + * Initialize pipe (or process handle on Windows) that allows children to + * wake up from sleep on postmaster death. + */ + InitPostmasterDeathWatchHandle(); + +#ifdef WIN32 + + /* + * Initialize I/O completion port used to deliver list of dead children. + */ + win32ChildQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); + if (win32ChildQueue == NULL) + ereport(FATAL, + (errmsg("could not create I/O completion port for child queue"))); +#endif + +#ifdef EXEC_BACKEND + /* Write out nondefault GUC settings for child processes to use */ + write_nondefault_variables(PGC_POSTMASTER); + + /* + * Clean out the temp directory used to transmit parameters to child + * processes (see internal_forkexec, below). We must do this before + * launching any child processes, else we have a race condition: we could + * remove a parameter file before the child can read it. It should be + * safe to do so now, because we verified earlier that there are no + * conflicting Postgres processes in this data directory. + */ + RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false); +#endif + + /* + * Forcibly remove the files signaling a standby promotion request. + * Otherwise, the existence of those files triggers a promotion too early, + * whether a user wants that or not. + * + * This removal of files is usually unnecessary because they can exist + * only during a few moments during a standby promotion. However there is + * a race condition: if pg_ctl promote is executed and creates the files + * during a promotion, the files can stay around even after the server is + * brought up to new master. Then, if new standby starts by using the + * backup taken from that master, the files can exist at the server + * startup and should be removed in order to avoid an unexpected + * promotion. + * + * Note that promotion signal files need to be removed before the startup + * process is invoked. Because, after that, they can be used by + * postmaster's SIGUSR1 signal handler. + */ + RemovePromoteSignalFiles(); + + /* Do the same for logrotate signal file */ + RemoveLogrotateSignalFiles(); + + /* Remove any outdated file holding the current log filenames. */ + if (unlink(LOG_METAINFO_DATAFILE) < 0 && errno != ENOENT) + ereport(LOG, + (errcode_for_file_access(), + errmsg("could not remove file \"%s\": %m", + LOG_METAINFO_DATAFILE))); + + /* + * If enabled, start up syslogger collection subprocess + */ + SysLoggerPID = SysLogger_Start(); + + /* + * Reset whereToSendOutput from DestDebug (its starting state) to + * DestNone. This stops ereport from sending log messages to stderr unless + * Log_destination permits. We don't do this until the postmaster is + * fully launched, since startup failures may as well be reported to + * stderr. + * + * If we are in fact disabling logging to stderr, first emit a log message + * saying so, to provide a breadcrumb trail for users who may not remember + * that their logging is configured to go somewhere else. + */ + if (!(Log_destination & LOG_DESTINATION_STDERR)) + ereport(LOG, + (errmsg("ending log output to stderr"), + errhint("Future log output will go to log destination \"%s\".", + Log_destination_string))); + + whereToSendOutput = DestNone; + + /* + * Report server startup in log. While we could emit this much earlier, + * it seems best to do so after starting the log collector, if we intend + * to use one. */ - InitializeMaxBackends(); + ereport(LOG, + (errmsg("starting %s", PG_VERSION_STR))); /* * Establish input sockets. @@ -996,12 +1373,14 @@ PostmasterMain(int argc, char *argv[]) * First, mark them all closed, and set up an on_proc_exit function that's * charged with closing the sockets again at postmaster shutdown. */ - for (i = 0; i < MAXLISTEN; i++) - ListenSocket[i] = PGINVALID_SOCKET; - + if (!IsOnlineUpgrade) + { + for (i = 0; i < MAXLISTEN; i++) + ListenSocket[i] = PGINVALID_SOCKET; + } on_proc_exit(CloseServerPorts, 0); - if (ListenAddresses) + if (ListenAddresses && !IsOnlineUpgrade) { char *rawstring; List *elemlist; @@ -1165,51 +1544,13 @@ PostmasterMain(int argc, char *argv[]) if (!listen_addr_saved) AddToDataDirLockFile(LOCK_FILE_LINE_LISTEN_ADDR, ""); - /* - * Set up shared memory and semaphores. - */ - reset_shared(PostPortNumber); - - /* - * Estimate number of openable files. This must happen after setting up - * semaphores, because on some platforms semaphores count as open files. - */ - set_max_safe_fds(); - - /* - * Set reference point for stack-depth checking. - */ - set_stack_base(); - - /* - * Initialize pipe (or process handle on Windows) that allows children to - * wake up from sleep on postmaster death. - */ - InitPostmasterDeathWatchHandle(); - -#ifdef WIN32 - - /* - * Initialize I/O completion port used to deliver list of dead children. - */ - win32ChildQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); - if (win32ChildQueue == NULL) - ereport(FATAL, - (errmsg("could not create I/O completion port for child queue"))); -#endif - /* * Record postmaster options. We delay this till now to avoid recording - * bogus options (eg, NBuffers too high for available memory). + * bogus options (eg, unusable port number). */ - if (!CreateOptsFile(argc, argv, my_exec_path)) + if (!IsOnlineUpgrade && !CreateOptsFile(argc, argv, my_exec_path)) ExitPostmaster(1); -#ifdef EXEC_BACKEND - /* Write out nondefault GUC settings for child processes to use */ - write_nondefault_variables(PGC_POSTMASTER); -#endif - /* * Write the external PID file if requested */ @@ -1240,57 +1581,6 @@ PostmasterMain(int argc, char *argv[]) */ RemovePgTempFiles(); - /* - * Forcibly remove the files signaling a standby promotion request. - * Otherwise, the existence of those files triggers a promotion too early, - * whether a user wants that or not. - * - * This removal of files is usually unnecessary because they can exist - * only during a few moments during a standby promotion. However there is - * a race condition: if pg_ctl promote is executed and creates the files - * during a promotion, the files can stay around even after the server is - * brought up to new master. Then, if new standby starts by using the - * backup taken from that master, the files can exist at the server - * startup and should be removed in order to avoid an unexpected - * promotion. - * - * Note that promotion signal files need to be removed before the startup - * process is invoked. Because, after that, they can be used by - * postmaster's SIGUSR1 signal handler. - */ - RemovePromoteSignalFiles(); - - /* Remove any outdated file holding the current log filenames. */ - if (unlink(LOG_METAINFO_DATAFILE) < 0 && errno != ENOENT) - ereport(LOG, - (errcode_for_file_access(), - errmsg("could not remove file \"%s\": %m", - LOG_METAINFO_DATAFILE))); - - /* - * If enabled, start up syslogger collection subprocess - */ - SysLoggerPID = SysLogger_Start(); - - /* - * Reset whereToSendOutput from DestDebug (its starting state) to - * DestNone. This stops ereport from sending log messages to stderr unless - * Log_destination permits. We don't do this until the postmaster is - * fully launched, since startup failures may as well be reported to - * stderr. - * - * If we are in fact disabling logging to stderr, first emit a log message - * saying so, to provide a breadcrumb trail for users who may not remember - * that their logging is configured to go somewhere else. - */ - if (!(Log_destination & LOG_DESTINATION_STDERR)) - ereport(LOG, - (errmsg("ending log output to stderr"), - errhint("Future log output will go to log destination \"%s\".", - Log_destination_string))); - - whereToSendOutput = DestNone; - /* * Initialize stats collection subsystem (this does NOT start the * collector process!) @@ -1346,10 +1636,6 @@ PostmasterMain(int argc, char *argv[]) * Remember postmaster startup time */ PgStartTime = GetCurrentTimestamp(); -#ifndef HAVE_STRONG_RANDOM - /* RandomCancelKey wants its own copy */ - gettimeofday(&random_start_time, NULL); -#endif /* * Report postmaster status in the postmaster.pid file, to allow pg_ctl to @@ -1360,10 +1646,18 @@ PostmasterMain(int argc, char *argv[]) /* * We're ready to rock and roll... */ - StartupPID = StartupDataBase(); - Assert(StartupPID != 0); - StartupStatus = STARTUP_RUNNING; - pmState = PM_STARTUP; + if (!IsOnlineUpgrade) + { + StartupPID = StartupDataBase(); + Assert(StartupPID != 0); + StartupStatus = STARTUP_RUNNING; + pmState = PM_STARTUP; + } + else + { + BackgroundWorkerShmemAttach(); + pmState = PM_RUN; + } /* Some workers may be scheduled to start now */ maybe_start_bgworkers(); @@ -1621,6 +1915,7 @@ ServerLoop(void) last_lockfile_recheck_time = last_touch_time = time(NULL); nSockets = initMasks(&readmask); + IsOnlineUpgrade = false; for (;;) { @@ -1884,9 +2179,12 @@ initMasks(fd_set *rmask) * if that's what you want. Return STATUS_ERROR if you don't want to * send anything to the client, which would typically be appropriate * if we detect a communications failure.) + * + * Set secure_done when negotiation of an encrypted layer (currently, TLS or + * GSSAPI) is already completed. */ static int -ProcessStartupPacket(Port *port, bool SSLdone) +ProcessStartupPacket(Port *port, bool secure_done) { int32 len; void *buf; @@ -1894,14 +2192,32 @@ ProcessStartupPacket(Port *port, bool SSLdone) MemoryContext oldcontext; pq_startmsgread(); - if (pq_getbytes((char *) &len, 4) == EOF) + + /* + * Grab the first byte of the length word separately, so that we can tell + * whether we have no data at all or an incomplete packet. (This might + * sound inefficient, but it's not really, because of buffering in + * pqcomm.c.) + */ + if (pq_getbytes((char *) &len, 1) == EOF) { /* - * EOF after SSLdone probably means the client didn't like our - * response to NEGOTIATE_SSL_CODE. That's not an error condition, so - * don't clutter the log with a complaint. + * If we get no data at all, don't clutter the log with a complaint; + * such cases often occur for legitimate reasons. An example is that + * we might be here after responding to NEGOTIATE_SSL_CODE, and if the + * client didn't like our response, it'll probably just drop the + * connection. Service-monitoring software also often just opens and + * closes a connection without sending anything. (So do port + * scanners, which may be less benign, but it's not really our job to + * notice those.) */ - if (!SSLdone) + return STATUS_ERROR; + } + + if (pq_getbytes(((char *) &len) + 1, 3) == EOF) + { + /* Got a partial length word, so bleat about that */ + if (!secure_done) ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("incomplete startup packet"))); @@ -1953,7 +2269,7 @@ ProcessStartupPacket(Port *port, bool SSLdone) return STATUS_ERROR; } - if (proto == NEGOTIATE_SSL_CODE && !SSLdone) + if (proto == NEGOTIATE_SSL_CODE && !secure_done) { char SSLok; @@ -1986,6 +2302,32 @@ ProcessStartupPacket(Port *port, bool SSLdone) /* but not another SSL negotiation request */ return ProcessStartupPacket(port, true); } + else if (proto == NEGOTIATE_GSS_CODE && !secure_done) + { + char GSSok = 'N'; +#ifdef ENABLE_GSS + /* No GSSAPI encryption when on Unix socket */ + if (!IS_AF_UNIX(port->laddr.addr.ss_family)) + GSSok = 'G'; +#endif + + while (send(port->sock, &GSSok, 1, 0) != 1) + { + if (errno == EINTR) + continue; + ereport(COMMERROR, + (errcode_for_socket_access(), + errmsg("failed to send GSSAPI negotiation response: %m"))); + return STATUS_ERROR; /* close the connection */ + } + +#ifdef ENABLE_GSS + if (GSSok == 'G' && secure_open_gssapi(port) == -1) + return STATUS_ERROR; +#endif + /* Won't ever see more than one negotiation request */ + return ProcessStartupPacket(port, true); + } /* Could add additional special packet types here */ @@ -2086,6 +2428,21 @@ ProcessStartupPacket(Port *port, bool SSLdone) pstrdup(nameptr)); port->guc_options = lappend(port->guc_options, pstrdup(valptr)); + + /* + * Copy application_name to port if we come across it. This + * is done so we can log the application_name in the + * connection authorization message. Note that the GUC would + * be used but we haven't gone through GUC setup yet. + */ + if (strcmp(nameptr, "application_name") == 0) + { + char *tmp_app_name = pstrdup(valptr); + + pg_clean_ascii(tmp_app_name); + + port->application_name = tmp_app_name; + } } offset = valoffset + strlen(valptr) + 1; } @@ -2303,7 +2660,11 @@ processCancelRequest(Port *port, void *pkt) backendPID))); return; } +#ifndef EXEC_BACKEND /* make GNU Emacs 26.1 see brace balance */ + } +#else } +#endif /* No matching backend */ ereport(LOG, @@ -2448,7 +2809,7 @@ ClosePostmasterPorts(bool am_syslogger) * do this as early as possible, so that if postmaster dies, others won't * think that it's still running because we're holding the pipe open. */ - if (close(postmaster_alive_fds[POSTMASTER_FD_OWN])) + if (close(postmaster_alive_fds[POSTMASTER_FD_OWN]) != 0) ereport(FATAL, (errcode_for_file_access(), errmsg_internal("could not close postmaster death monitoring pipe in child process: %m"))); @@ -2487,21 +2848,56 @@ ClosePostmasterPorts(bool am_syslogger) } +/* + * InitProcessGlobals -- set MyProcPid, MyStartTime[stamp], random seeds + * + * Called early in the postmaster and every backend. + */ +void +InitProcessGlobals(void) +{ + unsigned int rseed; + + MyProcPid = getpid(); + MyStartTimestamp = GetCurrentTimestamp(); + MyStartTime = timestamptz_to_time_t(MyStartTimestamp); + + /* + * Set a different seed for random() in every process. We want something + * unpredictable, so if possible, use high-quality random bits for the + * seed. Otherwise, fall back to a seed based on timestamp and PID. + */ + if (!pg_strong_random(&rseed, sizeof(rseed))) + { + /* + * Since PIDs and timestamps tend to change more frequently in their + * least significant bits, shift the timestamp left to allow a larger + * total number of seeds in a given time period. Since that would + * leave only 20 bits of the timestamp that cycle every ~1 second, + * also mix in some higher bits. + */ + rseed = ((uint64) MyProcPid) ^ + ((uint64) MyStartTimestamp << 12) ^ + ((uint64) MyStartTimestamp >> 20); + } + srandom(rseed); +} + + /* * reset_shared -- reset shared memory and semaphores */ static void -reset_shared(int port) +reset_shared(void) { /* * Create or re-create shared memory and semaphores. * * Note: in each "cycle of life" we will normally assign the same IPC keys - * (if using SysV shmem and/or semas), since the port number is used to - * determine IPC keys. This helps ensure that we will clean up dead IPC - * objects if the postmaster crashes and is restarted. + * (if using SysV shmem and/or semas). This helps ensure that we will + * clean up dead IPC objects if the postmaster crashes and is restarted. */ - CreateSharedMemoryAndSemaphores(false, port); + CreateSharedMemoryAndSemaphores(); } @@ -2543,11 +2939,12 @@ SIGHUP_handler(SIGNAL_ARGS) /* Reload authentication config files too */ if (!load_hba()) ereport(LOG, - (errmsg("pg_hba.conf was not reloaded"))); + /* translator: %s is a configuration file */ + (errmsg("%s was not reloaded", "pg_hba.conf"))); if (!load_ident()) ereport(LOG, - (errmsg("pg_ident.conf was not reloaded"))); + (errmsg("%s was not reloaded", "pg_ident.conf"))); #ifdef USE_SSL /* Reload SSL configuration as well */ @@ -2677,7 +3074,7 @@ pmdie(SIGNAL_ARGS) signal_child(BgWriterPID, SIGTERM); if (WalReceiverPID != 0) signal_child(WalReceiverPID, SIGTERM); - if (pmState == PM_RECOVERY) + if (pmState == PM_STARTUP || pmState == PM_RECOVERY) { SignalSomeChildren(SIGTERM, BACKEND_TYPE_BGWORKER); @@ -2811,7 +3208,9 @@ reaper(SIGNAL_ARGS) * during PM_STARTUP is treated as catastrophic. There are no * other processes running yet, so we can just exit. */ - if (pmState == PM_STARTUP && !EXIT_STATUS_0(exitstatus)) + if (pmState == PM_STARTUP && + StartupStatus != STARTUP_SIGNALED && + !EXIT_STATUS_0(exitstatus)) { LogChildExit(LOG, _("startup process"), pid, exitstatus); @@ -2828,11 +3227,24 @@ reaper(SIGNAL_ARGS) * then we previously sent the startup process a SIGQUIT; so * that's probably the reason it died, and we do want to try to * restart in that case. + * + * This stanza also handles the case where we sent a SIGQUIT + * during PM_STARTUP due to some dead_end child crashing: in that + * situation, if the startup process dies on the SIGQUIT, we need + * to transition to PM_WAIT_BACKENDS state which will allow + * PostmasterStateMachine to restart the startup process. (On the + * other hand, the startup process might complete normally, if we + * were too late with the SIGQUIT. In that case we'll fall + * through and commence normal operations.) */ if (!EXIT_STATUS_0(exitstatus)) { if (StartupStatus == STARTUP_SIGNALED) + { StartupStatus = STARTUP_NOT_RUNNING; + if (pmState == PM_STARTUP) + pmState = PM_WAIT_BACKENDS; + } else StartupStatus = STARTUP_CRASHED; HandleChildCrash(pid, exitstatus, @@ -2845,7 +3257,7 @@ reaper(SIGNAL_ARGS) */ StartupStatus = STARTUP_NOT_RUNNING; FatalError = false; - Assert(AbortStartTime == 0); + AbortStartTime = 0; ReachedNormalRunning = true; pmState = PM_RUN; @@ -3395,7 +3807,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) if (pid == StartupPID) { StartupPID = 0; - StartupStatus = STARTUP_CRASHED; + /* Caller adjusts StartupStatus, so don't touch it here */ } else if (StartupPID != 0 && take_action) { @@ -3548,6 +3960,7 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) procname, pid, WEXITSTATUS(exitstatus)), activity ? errdetail("Failed process was running: %s", activity) : 0)); else if (WIFSIGNALED(exitstatus)) + { #if defined(WIN32) ereport(lev, @@ -3558,7 +3971,7 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) procname, pid, WTERMSIG(exitstatus)), errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."), activity ? errdetail("Failed process was running: %s", activity) : 0)); -#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST +#else ereport(lev, /*------ @@ -3566,19 +3979,10 @@ LogChildExit(int lev, const char *procname, int pid, int exitstatus) "server process" */ (errmsg("%s (PID %d) was terminated by signal %d: %s", procname, pid, WTERMSIG(exitstatus), - WTERMSIG(exitstatus) < NSIG ? - sys_siglist[WTERMSIG(exitstatus)] : "(unknown)"), - activity ? errdetail("Failed process was running: %s", activity) : 0)); -#else - ereport(lev, - - /*------ - translator: %s is a noun phrase describing a child process, such as - "server process" */ - (errmsg("%s (PID %d) was terminated by signal %d", - procname, pid, WTERMSIG(exitstatus)), + pg_strsignal(WTERMSIG(exitstatus))), activity ? errdetail("Failed process was running: %s", activity) : 0)); #endif + } else ereport(lev, @@ -3715,12 +4119,8 @@ PostmasterStateMachine(void) * dead_end children left. There shouldn't be any regular backends * left by now anyway; what we're really waiting for is walsenders and * archiver. - * - * Walreceiver should normally be dead by now, but not when a fast - * shutdown is performed during recovery. */ - if (PgArchPID == 0 && CountChildren(BACKEND_TYPE_ALL) == 0 && - WalReceiverPID == 0) + if (PgArchPID == 0 && CountChildren(BACKEND_TYPE_ALL) == 0) { pmState = PM_WAIT_DEAD_END; } @@ -3822,7 +4222,7 @@ PostmasterStateMachine(void) /* re-read control file into local memory */ LocalProcessControlFile(true); - reset_shared(PostPortNumber); + reset_shared(); StartupPID = StartupDataBase(); Assert(StartupPID != 0); @@ -3923,7 +4323,10 @@ SignalSomeChildren(int signal, int target) static void TerminateChildren(int signal) { - SignalChildren(signal); + if (IsOnlineUpgrade) + SignalSomeChildren(signal, BACKEND_TYPE_WALSND | BACKEND_TYPE_WORKER); + else + SignalChildren(signal); if (StartupPID != 0) { signal_child(StartupPID, signal); @@ -3943,7 +4346,7 @@ TerminateChildren(int signal) if (PgArchPID != 0) signal_child(PgArchPID, signal); if (PgStatPID != 0) - signal_child(PgStatPID, signal); + signal_child(PgStatPID, IsOnlineUpgrade ? SIGQUIT : signal); } /* @@ -4128,10 +4531,6 @@ BackendInitialize(Port *port) /* This flag will remain set until InitPostgres finishes authentication */ ClientAuthInProgress = true; /* limit visibility of log messages */ - /* save process start time */ - port->SessionStartTime = GetCurrentTimestamp(); - MyStartTime = timestamptz_to_time_t(port->SessionStartTime); - /* set these to empty in case they are needed before we set them up */ port->remote_host = ""; port->remote_port = ""; @@ -4289,23 +4688,8 @@ BackendRun(Port *port) char **av; int maxac; int ac; - long secs; - int usecs; int i; - /* - * Don't want backend to be able to see the postmaster random number - * generator state. We have to clobber the static random_seed *and* start - * a new random sequence in the random() library function. - */ -#ifndef HAVE_STRONG_RANDOM - random_seed = 0; - random_start_time.tv_usec = 0; -#endif - /* slightly hacky way to convert timestamptz into integers */ - TimestampDifference(0, port->SessionStartTime, &secs, &usecs); - srandom((unsigned int) (MyProcPid ^ (usecs << 12) ^ secs)); - /* * Now, build the argv vector that will be given to PostgresMain. * @@ -4665,8 +5049,8 @@ internal_forkexec(int argc, char *argv[], Port *port) } /* - * Queue a waiter for to signal when this child dies. The wait will be - * handled automatically by an operating system thread pool. + * Queue a waiter to signal when this child dies. The wait will be handled + * automatically by an operating system thread pool. * * Note: use malloc instead of palloc, since it needs to be thread-safe. * Struct will be free():d from the callback function that runs on a @@ -4869,11 +5253,15 @@ SubPostmasterMain(int argc, char *argv[]) InitProcess(); /* Attach process to shared data structures */ - CreateSharedMemoryAndSemaphores(false, 0); + CreateSharedMemoryAndSemaphores(); /* And run the backend */ BackendRun(&port); /* does not return */ } + if (strcmp(argv[1], "--forkpostmaster") == 0) + { + InitShmemAccess(UsedShmemSegAddr); + } if (strcmp(argv[1], "--forkboot") == 0) { /* Restore basic shared memory pointers */ @@ -4883,7 +5271,7 @@ SubPostmasterMain(int argc, char *argv[]) InitAuxiliaryProcess(); /* Attach process to shared data structures */ - CreateSharedMemoryAndSemaphores(false, 0); + CreateSharedMemoryAndSemaphores(); AuxiliaryProcessMain(argc - 2, argv + 2); /* does not return */ } @@ -4896,7 +5284,7 @@ SubPostmasterMain(int argc, char *argv[]) InitProcess(); /* Attach process to shared data structures */ - CreateSharedMemoryAndSemaphores(false, 0); + CreateSharedMemoryAndSemaphores(); AutoVacLauncherMain(argc - 2, argv + 2); /* does not return */ } @@ -4909,7 +5297,7 @@ SubPostmasterMain(int argc, char *argv[]) InitProcess(); /* Attach process to shared data structures */ - CreateSharedMemoryAndSemaphores(false, 0); + CreateSharedMemoryAndSemaphores(); AutoVacWorkerMain(argc - 2, argv + 2); /* does not return */ } @@ -4927,7 +5315,7 @@ SubPostmasterMain(int argc, char *argv[]) InitProcess(); /* Attach process to shared data structures */ - CreateSharedMemoryAndSemaphores(false, 0); + CreateSharedMemoryAndSemaphores(); /* Fetch MyBgworkerEntry from shared memory */ shmem_slot = atoi(argv[1] + 15); @@ -4979,7 +5367,7 @@ ExitPostmaster(int status) ereport(LOG, (errcode(ERRCODE_INTERNAL_ERROR), errmsg_internal("postmaster became multithreaded"), - errdetail("Please report this to ."))); + errdetail("Please report this to ."))); #endif /* should cleanup shared memory and kill all backends */ @@ -5022,7 +5410,7 @@ sigusr1_handler(SIGNAL_ARGS) { /* WAL redo has started. We're out of reinitialization. */ FatalError = false; - Assert(AbortStartTime == 0); + AbortStartTime = 0; /* * Crank up the background tasks. It doesn't matter if this fails, @@ -5092,11 +5480,18 @@ sigusr1_handler(SIGNAL_ARGS) signal_child(PgArchPID, SIGUSR1); } - if (CheckPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE) && - SysLoggerPID != 0) + /* Tell syslogger to rotate logfile if requested */ + if (SysLoggerPID != 0) { - /* Tell syslogger to rotate logfile */ - signal_child(SysLoggerPID, SIGUSR1); + if (CheckLogrotateSignal()) + { + signal_child(SysLoggerPID, SIGUSR1); + RemoveLogrotateSignalFiles(); + } + else if (CheckPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE)) + { + signal_child(SysLoggerPID, SIGUSR1); + } } if (CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER) && @@ -5129,16 +5524,25 @@ sigusr1_handler(SIGNAL_ARGS) MaybeStartWalReceiver(); } - if (CheckPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE) && - (pmState == PM_WAIT_BACKUP || pmState == PM_WAIT_BACKENDS)) + /* + * Try to advance postmaster's state machine, if a child requests it. + * + * Be careful about the order of this action relative to sigusr1_handler's + * other actions. Generally, this should be after other actions, in case + * they have effects PostmasterStateMachine would need to know about. + * However, we should do it before the CheckPromoteSignal step, which + * cannot have any (immediate) effect on the state machine, but does + * depend on what state we're in now. + */ + if (CheckPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE)) { - /* Advance postmaster's state machine */ PostmasterStateMachine(); } - if (CheckPromoteSignal() && StartupPID != 0 && + if (StartupPID != 0 && (pmState == PM_STARTUP || pmState == PM_RECOVERY || - pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY)) + pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY) && + CheckPromoteSignal()) { /* Tell startup process to finish recovery */ signal_child(StartupPID, SIGUSR2); @@ -5174,8 +5578,9 @@ startup_die(SIGNAL_ARGS) * tcop/postgres.c.) */ static void -dummy_handler(SIGNAL_ARGS) +upgrade_handler(SIGNAL_ARGS) { + UpgradePostgres(); } /* @@ -5195,38 +5600,7 @@ StartupPacketTimeoutHandler(void) static bool RandomCancelKey(int32 *cancel_key) { -#ifdef HAVE_STRONG_RANDOM - return pg_strong_random((char *) cancel_key, sizeof(int32)); -#else - - /* - * If built with --disable-strong-random, use plain old erand48. - * - * We cannot use pg_backend_random() in postmaster, because it stores its - * state in shared memory. - */ - static unsigned short seed[3]; - - /* - * Select a random seed at the time of first receiving a request. - */ - if (random_seed == 0) - { - struct timeval random_stop_time; - - gettimeofday(&random_stop_time, NULL); - - seed[0] = (unsigned short) random_start_time.tv_usec; - seed[1] = (unsigned short) (random_stop_time.tv_usec) ^ (random_start_time.tv_usec >> 16); - seed[2] = (unsigned short) (random_stop_time.tv_usec >> 16); - - random_seed = 1; - } - - *cancel_key = pg_jrand48(seed); - - return true; -#endif + return pg_strong_random(cancel_key, sizeof(int32)); } /* @@ -5465,6 +5839,14 @@ StartAutovacuumWorker(void) /* * MaybeStartWalReceiver * Start the WAL receiver process, if not running and our state allows. + * + * Note: if WalReceiverPID is already nonzero, it might seem that we should + * clear WalReceiverRequested. However, there's a race condition if the + * walreceiver terminates and the startup process immediately requests a new + * one: it's quite possible to get the signal for the request before reaping + * the dead walreceiver process. Better to risk launching an extra + * walreceiver than to miss launching one we need. (The walreceiver code + * has logic to recognize that it should go away if not needed.) */ static void MaybeStartWalReceiver(void) @@ -5475,7 +5857,9 @@ MaybeStartWalReceiver(void) Shutdown == NoShutdown) { WalReceiverPID = StartWalReceiver(); - WalReceiverRequested = false; + if (WalReceiverPID != 0) + WalReceiverRequested = false; + /* else leave the flag set, so we'll try again later */ } } @@ -5527,7 +5911,7 @@ int MaxLivePostmasterChildren(void) { return 2 * (MaxConnections + autovacuum_max_workers + 1 + - max_worker_processes); + max_wal_senders + max_worker_processes); } /* @@ -5950,10 +6334,6 @@ PostmasterMarkPIDForWorkerNotify(int pid) * The following need to be available to the save/restore_backend_variables * functions. They are marked NON_EXEC_STATIC in their home modules. */ -extern slock_t *ShmemLock; -extern slock_t *ProcStructLock; -extern PGPROC *AuxiliaryProcs; -extern PMSignalData *PMSignalState; extern pgsocket pgStatSock; extern pg_time_t first_syslogger_file_time; @@ -5963,7 +6343,7 @@ extern pg_time_t first_syslogger_file_time; #else static bool write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE child); static bool write_inheritable_socket(InheritableSocket *dest, SOCKET src, - pid_t childPid); + pid_t childPid); static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src); #endif @@ -5978,10 +6358,12 @@ save_backend_variables(BackendParameters *param, Port *port, HANDLE childProcess, pid_t childPid) #endif { - memcpy(¶m->port, port, sizeof(Port)); - if (!write_inheritable_socket(¶m->portsocket, port->sock, childPid)) - return false; - + if (port) + { + memcpy(¶m->port, port, sizeof(Port)); + if (!write_inheritable_socket(¶m->portsocket, port->sock, childPid)) + return false; + } strlcpy(param->DataDir, DataDir, MAXPGPATH); memcpy(¶m->ListenSocket, &ListenSocket, sizeof(ListenSocket)); @@ -5989,6 +6371,9 @@ save_backend_variables(BackendParameters *param, Port *port, param->MyCancelKey = MyCancelKey; param->MyPMChildSlot = MyPMChildSlot; +#ifdef WIN32 + param->ShmemProtectiveRegion = ShmemProtectiveRegion; +#endif param->UsedShmemSegID = UsedShmemSegID; param->UsedShmemSegAddr = UsedShmemSegAddr; @@ -6014,6 +6399,7 @@ save_backend_variables(BackendParameters *param, Port *port, param->PgStartTime = PgStartTime; param->PgReloadTime = PgReloadTime; param->first_syslogger_file_time = first_syslogger_file_time; + param->BackgroundWorkers = GetBackgroundWorkerEntries(); param->redirection_done = redirection_done; param->IsBinaryUpgrade = IsBinaryUpgrade; @@ -6212,9 +6598,11 @@ read_backend_variables(char *id, Port *port) static void restore_backend_variables(BackendParameters *param, Port *port) { - memcpy(port, ¶m->port, sizeof(Port)); - read_inheritable_socket(&port->sock, ¶m->portsocket); - + if (port) + { + memcpy(port, ¶m->port, sizeof(Port)); + read_inheritable_socket(&port->sock, ¶m->portsocket); + } SetDataDir(param->DataDir); memcpy(&ListenSocket, ¶m->ListenSocket, sizeof(ListenSocket)); @@ -6222,6 +6610,9 @@ restore_backend_variables(BackendParameters *param, Port *port) MyCancelKey = param->MyCancelKey; MyPMChildSlot = param->MyPMChildSlot; +#ifdef WIN32 + ShmemProtectiveRegion = param->ShmemProtectiveRegion; +#endif UsedShmemSegID = param->UsedShmemSegID; UsedShmemSegAddr = param->UsedShmemSegAddr; @@ -6246,6 +6637,7 @@ restore_backend_variables(BackendParameters *param, Port *port) PgStartTime = param->PgStartTime; PgReloadTime = param->PgReloadTime; first_syslogger_file_time = param->first_syslogger_file_time; + SetBackgroundWorkerEntries(param->BackgroundWorkers); redirection_done = param->redirection_done; IsBinaryUpgrade = param->IsBinaryUpgrade; diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c index 38300527a54..5048a2c2aad 100644 --- a/src/backend/postmaster/startup.c +++ b/src/backend/postmaster/startup.c @@ -9,7 +9,7 @@ * though.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -69,27 +69,21 @@ static void StartupProcSigHupHandler(SIGNAL_ARGS); static void startupproc_quickdie(SIGNAL_ARGS) { - PG_SETMASK(&BlockSig); - - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } @@ -194,10 +188,6 @@ StartupProcessMain(void) * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); /* * Register timeouts needed for standby mode diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index 58b759f305f..bb2baff7631 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -13,7 +13,7 @@ * * Author: Andreas Pflug * - * Copyright (c) 2004-2018, PostgreSQL Global Development Group + * Copyright (c) 2004-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -31,6 +31,7 @@ #include #include +#include "common/file_perm.h" #include "lib/stringinfo.h" #include "libpq/pqsignal.h" #include "miscadmin.h" @@ -45,6 +46,7 @@ #include "storage/ipc.h" #include "storage/latch.h" #include "storage/pg_shmem.h" +#include "tcop/tcopprot.h" #include "utils/guc.h" #include "utils/ps_status.h" #include "utils/timestamp.h" @@ -56,6 +58,9 @@ */ #define READ_BUF_SIZE (2 * PIPE_CHUNK_SIZE) +/* Log rotation signal file path, relative to $PGDATA */ +#define LOGROTATE_SIGNAL_FILE "logrotate" + /* * GUC parameters. Logging_collector cannot be changed after postmaster @@ -135,9 +140,8 @@ static void syslogger_parseArgs(int argc, char *argv[]); NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn(); static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer); static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer); -static void open_csvlogfile(void); static FILE *logfile_open(const char *filename, const char *mode, - bool allow_errors); + bool allow_errors); #ifdef WIN32 static unsigned int __stdcall pipeThread(void *arg); @@ -165,6 +169,7 @@ SysLoggerMain(int argc, char *argv[]) char *currentLogFilename; int currentLogRotationAge; pg_time_t now; + WaitEventSet *wes; now = MyStartTime; @@ -254,10 +259,6 @@ SysLoggerMain(int argc, char *argv[]) * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); PG_SETMASK(&UnBlockSig); @@ -272,11 +273,13 @@ SysLoggerMain(int argc, char *argv[]) #endif /* WIN32 */ /* - * Remember active logfile's name. We recompute this from the reference + * Remember active logfiles' name(s). We recompute 'em from the reference * time because passing down just the pg_time_t is a lot cheaper than * passing a whole file path in the EXEC_BACKEND case. */ last_file_name = logfile_getname(first_syslogger_file_time, NULL); + if (csvlogFile != NULL) + last_csv_file_name = logfile_getname(first_syslogger_file_time, ".csv"); /* remember active logfile parameters */ currentLogDir = pstrdup(Log_directory); @@ -286,13 +289,36 @@ SysLoggerMain(int argc, char *argv[]) set_next_rotation_time(); update_metainfo_datafile(); + /* + * Reset whereToSendOutput, as the postmaster will do (but hasn't yet, at + * the point where we forked). This prevents duplicate output of messages + * from syslogger itself. + */ + whereToSendOutput = DestNone; + + /* + * Set up a reusable WaitEventSet object we'll use to wait for our latch, + * and (except on Windows) our socket. + * + * Unlike all other postmaster child processes, we'll ignore postmaster + * death because we want to collect final log output from all backends and + * then exit last. We'll do that by running until we see EOF on the + * syslog pipe, which implies that all other backends have exited + * (including the postmaster). + */ + wes = CreateWaitEventSet(CurrentMemoryContext, 2); + AddWaitEventToSet(wes, WL_LATCH_SET, PGINVALID_SOCKET, MyLatch, NULL); +#ifndef WIN32 + AddWaitEventToSet(wes, WL_SOCKET_READABLE, syslogPipe[0], NULL, NULL); +#endif + /* main worker loop */ for (;;) { bool time_based_rotation = false; int size_rotation_for = 0; long cur_timeout; - int cur_flags; + WaitEvent event; #ifndef WIN32 int rc; @@ -332,6 +358,14 @@ SysLoggerMain(int argc, char *argv[]) rotation_requested = true; } + /* + * Force a rotation if CSVLOG output was just turned on or off and + * we need to open or close csvlogFile accordingly. + */ + if (((Log_destination & LOG_DESTINATION_CSVLOG) != 0) != + (csvlogFile != NULL)) + rotation_requested = true; + /* * If rotation time parameter changed, reset next rotation time, * but don't immediately force a rotation. @@ -388,7 +422,7 @@ SysLoggerMain(int argc, char *argv[]) { /* * Force rotation when both values are zero. It means the request - * was sent by pg_rotate_logfile. + * was sent by pg_rotate_logfile() or "pg_ctl logrotate". */ if (!time_based_rotation && size_rotation_for == 0) size_rotation_for = LOG_DESTINATION_STDERR | LOG_DESTINATION_CSVLOG; @@ -420,25 +454,18 @@ SysLoggerMain(int argc, char *argv[]) } else cur_timeout = 0; - cur_flags = WL_TIMEOUT; } else - { cur_timeout = -1L; - cur_flags = 0; - } /* * Sleep until there's something to do */ #ifndef WIN32 - rc = WaitLatchOrSocket(MyLatch, - WL_LATCH_SET | WL_SOCKET_READABLE | cur_flags, - syslogPipe[0], - cur_timeout, - WAIT_EVENT_SYSLOGGER_MAIN); + rc = WaitEventSetWait(wes, cur_timeout, &event, 1, + WAIT_EVENT_SYSLOGGER_MAIN); - if (rc & WL_SOCKET_READABLE) + if (rc == 1 && event.events == WL_SOCKET_READABLE) { int bytesRead; @@ -485,10 +512,8 @@ SysLoggerMain(int argc, char *argv[]) */ LeaveCriticalSection(&sysloggerSection); - (void) WaitLatch(MyLatch, - WL_LATCH_SET | cur_flags, - cur_timeout, - WAIT_EVENT_SYSLOGGER_MAIN); + (void) WaitEventSetWait(wes, cur_timeout, &event, 1, + WAIT_EVENT_SYSLOGGER_MAIN); EnterCriticalSection(&sysloggerSection); #endif /* WIN32 */ @@ -580,12 +605,27 @@ SysLogger_Start(void) * a time-based rotation. */ first_syslogger_file_time = time(NULL); + filename = logfile_getname(first_syslogger_file_time, NULL); syslogFile = logfile_open(filename, "a", false); pfree(filename); + /* + * Likewise for the initial CSV log file, if that's enabled. (Note that + * we open syslogFile even when only CSV output is nominally enabled, + * since some code paths will write to syslogFile anyway.) + */ + if (Log_destination & LOG_DESTINATION_CSVLOG) + { + filename = logfile_getname(first_syslogger_file_time, ".csv"); + + csvlogFile = logfile_open(filename, "a", false); + + pfree(filename); + } + #ifdef EXEC_BACKEND switch ((sysloggerPid = syslogger_forkexec())) #else @@ -675,9 +715,14 @@ SysLogger_Start(void) redirection_done = true; } - /* postmaster will never write the file; close it */ + /* postmaster will never write the file(s); close 'em */ fclose(syslogFile); syslogFile = NULL; + if (csvlogFile != NULL) + { + fclose(csvlogFile); + csvlogFile = NULL; + } return (int) sysloggerPid; } @@ -699,6 +744,7 @@ syslogger_forkexec(void) char *av[10]; int ac = 0; char filenobuf[32]; + char csvfilenobuf[32]; av[ac++] = "postgres"; av[ac++] = "--forklog"; @@ -720,6 +766,21 @@ syslogger_forkexec(void) #endif /* WIN32 */ av[ac++] = filenobuf; +#ifndef WIN32 + if (csvlogFile != NULL) + snprintf(csvfilenobuf, sizeof(csvfilenobuf), "%d", + fileno(csvlogFile)); + else + strcpy(csvfilenobuf, "-1"); +#else /* WIN32 */ + if (csvlogFile != NULL) + snprintf(csvfilenobuf, sizeof(csvfilenobuf), "%ld", + (long) _get_osfhandle(_fileno(csvlogFile))); + else + strcpy(csvfilenobuf, "0"); +#endif /* WIN32 */ + av[ac++] = csvfilenobuf; + av[ac] = NULL; Assert(ac < lengthof(av)); @@ -736,9 +797,16 @@ syslogger_parseArgs(int argc, char *argv[]) { int fd; - Assert(argc == 4); + Assert(argc == 5); argv += 3; + /* + * Re-open the error output files that were opened by SysLogger_Start(). + * + * We expect this will always succeed, which is too optimistic, but if it + * fails there's not a lot we can do to report the problem anyway. As + * coded, we'll just crash on a null pointer dereference after failure... + */ #ifndef WIN32 fd = atoi(*argv++); if (fd != -1) @@ -746,6 +814,12 @@ syslogger_parseArgs(int argc, char *argv[]) syslogFile = fdopen(fd, "a"); setvbuf(syslogFile, NULL, PG_IOLBF, 0); } + fd = atoi(*argv++); + if (fd != -1) + { + csvlogFile = fdopen(fd, "a"); + setvbuf(csvlogFile, NULL, PG_IOLBF, 0); + } #else /* WIN32 */ fd = atoi(*argv++); if (fd != 0) @@ -757,6 +831,16 @@ syslogger_parseArgs(int argc, char *argv[]) setvbuf(syslogFile, NULL, PG_IOLBF, 0); } } + fd = atoi(*argv++); + if (fd != 0) + { + fd = _open_osfhandle(fd, _O_APPEND | _O_TEXT); + if (fd > 0) + { + csvlogFile = fdopen(fd, "a"); + setvbuf(csvlogFile, NULL, PG_IOLBF, 0); + } + } #endif /* WIN32 */ } #endif /* EXEC_BACKEND */ @@ -998,13 +1082,29 @@ write_syslogger_file(const char *buffer, int count, int destination) int rc; FILE *logfile; - if (destination == LOG_DESTINATION_CSVLOG && csvlogFile == NULL) - open_csvlogfile(); + /* + * If we're told to write to csvlogFile, but it's not open, dump the data + * to syslogFile (which is always open) instead. This can happen if CSV + * output is enabled after postmaster start and we've been unable to open + * csvlogFile. There are also race conditions during a parameter change + * whereby backends might send us CSV output before we open csvlogFile or + * after we close it. Writing CSV-formatted output to the regular log + * file isn't great, but it beats dropping log output on the floor. + * + * Think not to improve this by trying to open csvlogFile on-the-fly. Any + * failure in that would lead to recursion. + */ + logfile = (destination == LOG_DESTINATION_CSVLOG && + csvlogFile != NULL) ? csvlogFile : syslogFile; - logfile = destination == LOG_DESTINATION_CSVLOG ? csvlogFile : syslogFile; rc = fwrite(buffer, 1, count, logfile); - /* can't use ereport here because of possible recursion */ + /* + * Try to report any failure. We mustn't use ereport because it would + * just recurse right back here, but write_stderr is OK: it will write + * either to the postmaster's original stderr, or to /dev/null, but never + * to our input pipe which would result in a different sort of looping. + */ if (rc != count) write_stderr("could not write to log file: %s\n", strerror(errno)); } @@ -1014,7 +1114,7 @@ write_syslogger_file(const char *buffer, int count, int destination) /* * Worker thread to transfer data from the pipe to the current logfile. * - * We need this because on Windows, WaitforMultipleObjects does not work on + * We need this because on Windows, WaitForMultipleObjects does not work on * unnamed pipes: it always reports "signaled", so the blocking ReadFile won't * allow for SIGHUP; and select is for sockets only. */ @@ -1087,31 +1187,6 @@ pipeThread(void *arg) } #endif /* WIN32 */ -/* - * Open the csv log file - we do this opportunistically, because - * we don't know if CSV logging will be wanted. - * - * This is only used the first time we open the csv log in a given syslogger - * process, not during rotations. As with opening the main log file, we - * always append in this situation. - */ -static void -open_csvlogfile(void) -{ - char *filename; - - filename = logfile_getname(time(NULL), ".csv"); - - csvlogFile = logfile_open(filename, "a", false); - - if (last_csv_file_name != NULL) /* probably shouldn't happen */ - pfree(last_csv_file_name); - - last_csv_file_name = filename; - - update_metainfo_datafile(); -} - /* * Open a new logfile with proper permissions and buffering options. * @@ -1179,7 +1254,7 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) else fntime = time(NULL); filename = logfile_getname(fntime, NULL); - if (csvlogFile != NULL) + if (Log_destination & LOG_DESTINATION_CSVLOG) csvfilename = logfile_getname(fntime, ".csv"); /* @@ -1231,10 +1306,16 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) filename = NULL; } - /* Same as above, but for csv file. */ - - if (csvlogFile != NULL && - (time_based_rotation || (size_rotation_for & LOG_DESTINATION_CSVLOG))) + /* + * Same as above, but for csv file. Note that if LOG_DESTINATION_CSVLOG + * was just turned on, we might have to open csvlogFile here though it was + * not open before. In such a case we'll append not overwrite (since + * last_csv_file_name will be NULL); that is consistent with the normal + * rules since it's not a time-based rotation. + */ + if ((Log_destination & LOG_DESTINATION_CSVLOG) && + (csvlogFile == NULL || + time_based_rotation || (size_rotation_for & LOG_DESTINATION_CSVLOG))) { if (Log_truncate_on_rotation && time_based_rotation && last_csv_file_name != NULL && @@ -1265,7 +1346,8 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) return; } - fclose(csvlogFile); + if (csvlogFile != NULL) + fclose(csvlogFile); csvlogFile = fh; /* instead of pfree'ing filename, remember it for next time */ @@ -1274,6 +1356,16 @@ logfile_rotate(bool time_based_rotation, int size_rotation_for) last_csv_file_name = csvfilename; csvfilename = NULL; } + else if (!(Log_destination & LOG_DESTINATION_CSVLOG) && + csvlogFile != NULL) + { + /* CSVLOG was just turned off, so close the old file */ + fclose(csvlogFile); + csvlogFile = NULL; + if (last_csv_file_name != NULL) + pfree(last_csv_file_name); + last_csv_file_name = NULL; + } if (filename) pfree(filename); @@ -1356,12 +1448,14 @@ set_next_rotation_time(void) * log messages. Useful for finding the name(s) of the current log file(s) * when there is time-based logfile rotation. Filenames are stored in a * temporary file and which is renamed into the final destination for - * atomicity. + * atomicity. The file is opened with the same permissions as what gets + * created in the data directory and has proper buffering options. */ static void update_metainfo_datafile(void) { FILE *fh; + mode_t oumask; if (!(Log_destination & LOG_DESTINATION_STDERR) && !(Log_destination & LOG_DESTINATION_CSVLOG)) @@ -1374,7 +1468,21 @@ update_metainfo_datafile(void) return; } - if ((fh = logfile_open(LOG_METAINFO_DATAFILE_TMP, "w", true)) == NULL) + /* use the same permissions as the data directory for the new file */ + oumask = umask(pg_mode_mask); + fh = fopen(LOG_METAINFO_DATAFILE_TMP, "w"); + umask(oumask); + + if (fh) + { + setvbuf(fh, NULL, PG_IOLBF, 0); + +#ifdef WIN32 + /* use CRLF line endings on Windows */ + _setmode(_fileno(fh), _O_TEXT); +#endif + } + else { ereport(LOG, (errcode_for_file_access(), @@ -1422,6 +1530,30 @@ update_metainfo_datafile(void) * -------------------------------- */ +/* + * Check to see if a log rotation request has arrived. Should be + * called by postmaster after receiving SIGUSR1. + */ +bool +CheckLogrotateSignal(void) +{ + struct stat stat_buf; + + if (stat(LOGROTATE_SIGNAL_FILE, &stat_buf) == 0) + return true; + + return false; +} + +/* + * Remove the file signaling a log rotation request. + */ +void +RemoveLogrotateSignalFiles(void) +{ + unlink(LOGROTATE_SIGNAL_FILE); +} + /* SIGHUP: set flag to reload config file */ static void sigHupHandler(SIGNAL_ARGS) diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 4fa3a3b0aaf..a6fdba3f413 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -31,7 +31,7 @@ * should be killed by SIGQUIT and then a recovery cycle started. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -121,20 +121,10 @@ WalWriterMain(void) * Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); - /* - * Create a resource owner to keep track of our resources (not clear that - * we need this, but may as well have one). - */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "Wal Writer"); - /* * Create a memory context that we will do all our work in. We do this so * that we can reset the context during error recovery and thereby avoid @@ -172,14 +162,10 @@ WalWriterMain(void) pgstat_report_wait_end(); AbortBufferIO(); UnlockBuffers(); - /* buffer pins are released here: */ - ResourceOwnerRelease(CurrentResourceOwner, - RESOURCE_RELEASE_BEFORE_LOCKS, - false, true); - /* we needn't bother with the other ResourceOwnerRelease phases */ + ReleaseAuxProcessResources(false); AtEOXact_Buffers(false); AtEOXact_SMgr(); - AtEOXact_Files(); + AtEOXact_Files(false); AtEOXact_HashTables(false); /* @@ -237,7 +223,6 @@ WalWriterMain(void) for (;;) { long cur_timeout; - int rc; /* * Advertise whether we might hibernate in this cycle. We do this @@ -290,17 +275,10 @@ WalWriterMain(void) else cur_timeout = WalWriterDelay * HIBERNATE_FACTOR; - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - cur_timeout, - WAIT_EVENT_WAL_WRITER_MAIN); - - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (rc & WL_POSTMASTER_DEATH) - exit(1); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + cur_timeout, + WAIT_EVENT_WAL_WRITER_MAIN); } } @@ -319,27 +297,21 @@ WalWriterMain(void) static void wal_quickdie(SIGNAL_ARGS) { - PG_SETMASK(&BlockSig); - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } /* SIGHUP: set flag to re-read config file at next convenient time */ diff --git a/src/backend/regex/regc_lex.c b/src/backend/regex/regc_lex.c index 2c6551ca746..38617b79fd1 100644 --- a/src/backend/regex/regc_lex.c +++ b/src/backend/regex/regc_lex.c @@ -875,6 +875,7 @@ lexescape(struct vars *v) /* oops, doesn't look like it's a backref after all... */ v->now = save; /* and fall through into octal number */ + /* FALLTHROUGH */ case CHR('0'): NOTE(REG_UUNPORT); v->now--; /* put first digit back */ diff --git a/src/backend/regex/regc_pg_locale.c b/src/backend/regex/regc_pg_locale.c index acbed2eeedb..4a808b7606c 100644 --- a/src/backend/regex/regc_pg_locale.c +++ b/src/backend/regex/regc_pg_locale.c @@ -6,7 +6,7 @@ * * This file is #included by regcomp.c; it's not meant to compile standalone. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -263,6 +263,11 @@ pg_set_regex_collation(Oid collation) errhint("Use the COLLATE clause to set the collation explicitly."))); } + if (pg_regex_locale && !pg_regex_locale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for regular expressions"))); + #ifdef USE_ICU if (pg_regex_locale && pg_regex_locale->provider == COLLPROVIDER_ICU) pg_regex_strategy = PG_REGEX_LOCALE_ICU; diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index 51385509bba..91078dcd806 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -55,7 +55,7 @@ static const chr *scanplain(struct vars *); static void onechr(struct vars *, chr, struct state *, struct state *); static void wordchrs(struct vars *); static void processlacon(struct vars *, struct state *, struct state *, int, - struct state *, struct state *); + struct state *, struct state *); static struct subre *subre(struct vars *, int, int, struct state *, struct state *); static void freesubre(struct vars *, struct subre *); static void freesrnode(struct vars *, struct subre *); @@ -161,15 +161,15 @@ static int push(struct nfa *, struct arc *, struct state **); static int combine(struct arc *, struct arc *); static void fixempties(struct nfa *, FILE *); static struct state *emptyreachable(struct nfa *, struct state *, - struct state *, struct arc **); + struct state *, struct arc **); static int isconstraintarc(struct arc *); static int hasconstraintout(struct state *); static void fixconstraintloops(struct nfa *, FILE *); static int findconstraintloop(struct nfa *, struct state *); static void breakconstraintloop(struct nfa *, struct state *); static void clonesuccessorstates(struct nfa *, struct state *, struct state *, - struct state *, struct arc *, - char *, char *, int); + struct state *, struct arc *, + char *, char *, int); static void cleanup(struct nfa *); static void markreachable(struct nfa *, struct state *, struct state *, struct state *); static void markcanreach(struct nfa *, struct state *, struct state *, struct state *); @@ -288,7 +288,6 @@ struct vars #define NWBDRY 'W' /* non-word-boundary constraint */ #define SBEGIN 'A' /* beginning of string (even if not BOL) */ #define SEND 'Z' /* end of string (even if not EOL) */ -#define PREFER 'P' /* length preference */ /* is an arc colored, and hence on a color chain? */ #define COLORED(a) \ @@ -909,7 +908,8 @@ parseqatom(struct vars *v, } /* legal in EREs due to specification botch */ NOTE(REG_UPBOTCH); - /* fallthrough into case PLAIN */ + /* fall through into case PLAIN */ + /* FALLTHROUGH */ case PLAIN: onechr(v, v->nextvalue, lp, rp); okcolors(v->nfa, v->cm); @@ -1154,7 +1154,10 @@ parseqatom(struct vars *v, /* rest of branch can be strung starting from atom->end */ s2 = atom->end; } - else if (m == 1 && n == 1) + else if (m == 1 && n == 1 && + (qprefer == 0 || + (atom->flags & (LONGER | SHORTER | MIXED)) == 0 || + qprefer == (atom->flags & (LONGER | SHORTER | MIXED)))) { /* no/vacuous quantifier: done */ EMPTYARC(s, atom->begin); /* empty prefix */ diff --git a/src/backend/regex/regexport.c b/src/backend/regex/regexport.c index 81b3bf1fc8a..30e7186021d 100644 --- a/src/backend/regex/regexport.c +++ b/src/backend/regex/regexport.c @@ -15,7 +15,7 @@ * allows the caller to decide how big is too big to bother with. * * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1998, 1999 Henry Spencer * * IDENTIFICATION diff --git a/src/backend/regex/regprefix.c b/src/backend/regex/regprefix.c index 6bf7c77f984..207d40904ba 100644 --- a/src/backend/regex/regprefix.c +++ b/src/backend/regex/regprefix.c @@ -4,7 +4,7 @@ * Extract a common prefix, if any, from a compiled regex. * * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1998, 1999 Henry Spencer * * IDENTIFICATION @@ -19,8 +19,8 @@ /* * forward declarations */ -static int findprefix(struct cnfa *cnfa, struct colormap *cm, - chr *string, size_t *slength); +static int findprefix(struct cnfa *cnfa, struct colormap *cm, + chr *string, size_t *slength); /* diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 50c052e9935..d0f210de8ca 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -3,7 +3,7 @@ * basebackup.c * code for taking a base backup and streaming it to a standby * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/basebackup.c @@ -56,21 +56,21 @@ typedef struct static int64 sendDir(const char *path, int basepathlen, bool sizeonly, - List *tablespaces, bool sendtblspclinks); + List *tablespaces, bool sendtblspclinks); static bool sendFile(const char *readfilename, const char *tarfilename, - struct stat *statbuf, bool missing_ok); + struct stat *statbuf, bool missing_ok, Oid dboid); static void sendFileWithContent(const char *filename, const char *content); static int64 _tarWriteHeader(const char *filename, const char *linktarget, - struct stat *statbuf, bool sizeonly); + struct stat *statbuf, bool sizeonly); static int64 _tarWriteDir(const char *pathbuf, int basepathlen, struct stat *statbuf, - bool sizeonly); + bool sizeonly); static void send_int8_string(StringInfoData *buf, int64 intval); static void SendBackupHeader(List *tablespaces); static void base_backup_cleanup(int code, Datum arg); static void perform_base_backup(basebackup_options *opt); static void parse_basebackup_options(List *options, basebackup_options *opt); static void SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli); -static int compareWalFileNames(const void *a, const void *b); +static int compareWalFileNames(const ListCell *a, const ListCell *b); static void throttle(size_t increment); static bool is_checksummed_file(const char *fullpath, const char *filename); @@ -90,6 +90,18 @@ static char *statrelpath = NULL; */ #define THROTTLING_FREQUENCY 8 +/* + * Checks whether we encountered any error in fread(). fread() doesn't give + * any clue what has happened, so we check with ferror(). Also, neither + * fread() nor ferror() set errno, so we just throw a generic error. + */ +#define CHECK_FREAD_ERROR(fp, filename) \ +do { \ + if (ferror(fp)) \ + ereport(ERROR, \ + (errmsg("could not read from file \"%s\"", filename))); \ +} while (0) + /* The actual number of bytes, transfer of which may cause sleep. */ static uint64 throttling_sample; @@ -106,7 +118,7 @@ static TimestampTz throttled_last; static XLogRecPtr startptr; /* Total number of checksum failures during base backup. */ -static int64 total_checksum_failures; +static long long int total_checksum_failures; /* Do not verify checksums. */ static bool noverify_checksums = false; @@ -119,7 +131,7 @@ static bool noverify_checksums = false; * Note: this list should be kept in sync with the filter lists in pg_rewind's * filemap.c. */ -static const char *excludeDirContents[] = +static const char *const excludeDirContents[] = { /* * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped even @@ -160,7 +172,7 @@ static const char *excludeDirContents[] = /* * List of files excluded from backups. */ -static const char *excludeFiles[] = +static const char *const excludeFiles[] = { /* Skip auto conf temporary file. */ PG_AUTOCONF_FILENAME ".tmp", @@ -189,12 +201,19 @@ static const char *excludeFiles[] = /* * List of files excluded from checksum validation. + * + * Note: this list should be kept in sync with what pg_checksums.c + * includes. */ -static const char *noChecksumFiles[] = { +static const char *const noChecksumFiles[] = { "pg_control", "pg_filenode.map", "pg_internal.init", "PG_VERSION", +#ifdef EXEC_BACKEND + "config_exec_params", + "config_exec_params.new", +#endif NULL, }; @@ -243,8 +262,8 @@ perform_base_backup(basebackup_options *opt) /* * Once do_pg_start_backup has been called, ensure that any failure causes * us to abort the backup so we don't "leak" a backup counter. For this - * reason, *all* functionality between do_pg_start_backup() and - * the end of do_pg_stop_backup() should be inside the error cleanup block! + * reason, *all* functionality between do_pg_start_backup() and the end of + * do_pg_stop_backup() should be inside the error cleanup block! */ PG_ENSURE_ERROR_CLEANUP(base_backup_cleanup, (Datum) 0); @@ -333,9 +352,9 @@ perform_base_backup(basebackup_options *opt) if (lstat(XLOG_CONTROL_FILE, &statbuf) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not stat control file \"%s\": %m", + errmsg("could not stat file \"%s\": %m", XLOG_CONTROL_FILE))); - sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false); + sendFile(XLOG_CONTROL_FILE, XLOG_CONTROL_FILE, &statbuf, false, InvalidOid); } else sendTablespace(ti->path, false); @@ -348,7 +367,7 @@ perform_base_backup(basebackup_options *opt) */ if (opt->includewal && ti->path == NULL) { - Assert(lnext(lc) == NULL); + Assert(lnext(tablespaces, lc) == NULL); } else pq_putemptymessage('c'); /* CopyDone */ @@ -372,13 +391,10 @@ perform_base_backup(basebackup_options *opt) struct stat statbuf; List *historyFileList = NIL; List *walFileList = NIL; - char **walFiles; - int nWalFiles; char firstoff[MAXFNAMELEN]; char lastoff[MAXFNAMELEN]; DIR *dir; struct dirent *de; - int i; ListCell *lc; TimeLineID tli; @@ -421,24 +437,17 @@ perform_base_backup(basebackup_options *opt) CheckXLogRemoved(startsegno, ThisTimeLineID); /* - * Put the WAL filenames into an array, and sort. We send the files in - * order from oldest to newest, to reduce the chance that a file is - * recycled before we get a chance to send it over. + * Sort the WAL filenames. We want to send the files in order from + * oldest to newest, to reduce the chance that a file is recycled + * before we get a chance to send it over. */ - nWalFiles = list_length(walFileList); - walFiles = palloc(nWalFiles * sizeof(char *)); - i = 0; - foreach(lc, walFileList) - { - walFiles[i++] = lfirst(lc); - } - qsort(walFiles, nWalFiles, sizeof(char *), compareWalFileNames); + list_sort(walFileList, compareWalFileNames); /* * There must be at least one xlog file in the pg_wal directory, since * we are doing backup-including-xlog. */ - if (nWalFiles < 1) + if (walFileList == NIL) ereport(ERROR, (errmsg("could not find any WAL files"))); @@ -446,7 +455,8 @@ perform_base_backup(basebackup_options *opt) * Sanity check: the first and last segment should cover startptr and * endptr, with no gaps in between. */ - XLogFromFileName(walFiles[0], &tli, &segno, wal_segment_size); + XLogFromFileName((char *) linitial(walFileList), + &tli, &segno, wal_segment_size); if (segno != startsegno) { char startfname[MAXFNAMELEN]; @@ -456,12 +466,13 @@ perform_base_backup(basebackup_options *opt) ereport(ERROR, (errmsg("could not find WAL file \"%s\"", startfname))); } - for (i = 0; i < nWalFiles; i++) + foreach(lc, walFileList) { + char *walFileName = (char *) lfirst(lc); XLogSegNo currsegno = segno; XLogSegNo nextsegno = segno + 1; - XLogFromFileName(walFiles[i], &tli, &segno, wal_segment_size); + XLogFromFileName(walFileName, &tli, &segno, wal_segment_size); if (!(nextsegno == segno || currsegno == segno)) { char nextfname[MAXFNAMELEN]; @@ -482,19 +493,22 @@ perform_base_backup(basebackup_options *opt) } /* Ok, we have everything we need. Send the WAL files. */ - for (i = 0; i < nWalFiles; i++) + foreach(lc, walFileList) { + char *walFileName = (char *) lfirst(lc); FILE *fp; char buf[TAR_SEND_SIZE]; size_t cnt; pgoff_t len = 0; - snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFiles[i]); - XLogFromFileName(walFiles[i], &tli, &segno, wal_segment_size); + snprintf(pathbuf, MAXPGPATH, XLOGDIR "/%s", walFileName); + XLogFromFileName(walFileName, &tli, &segno, wal_segment_size); fp = AllocateFile(pathbuf, "rb"); if (fp == NULL) { + int save_errno = errno; + /* * Most likely reason for this is that the file was already * removed by a checkpoint, so check for that to get a better @@ -502,6 +516,7 @@ perform_base_backup(basebackup_options *opt) */ CheckXLogRemoved(segno, tli); + errno = save_errno; ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", pathbuf))); @@ -517,7 +532,7 @@ perform_base_backup(basebackup_options *opt) CheckXLogRemoved(segno, tli); ereport(ERROR, (errcode_for_file_access(), - errmsg("unexpected WAL file size \"%s\"", walFiles[i]))); + errmsg("unexpected WAL file size \"%s\"", walFileName))); } /* send the WAL file itself */ @@ -540,12 +555,14 @@ perform_base_backup(basebackup_options *opt) break; } + CHECK_FREAD_ERROR(fp, pathbuf); + if (len != wal_segment_size) { CheckXLogRemoved(segno, tli); ereport(ERROR, (errcode_for_file_access(), - errmsg("unexpected WAL file size \"%s\"", walFiles[i]))); + errmsg("unexpected WAL file size \"%s\"", walFileName))); } /* wal_segment_size is a multiple of 512, so no need for padding */ @@ -558,7 +575,7 @@ perform_base_backup(basebackup_options *opt) * walreceiver.c always doing an XLogArchiveForceDone() after a * complete segment. */ - StatusFilePath(pathbuf, walFiles[i], ".done"); + StatusFilePath(pathbuf, walFileName, ".done"); sendFileWithContent(pathbuf, ""); } @@ -582,7 +599,7 @@ perform_base_backup(basebackup_options *opt) (errcode_for_file_access(), errmsg("could not stat file \"%s\": %m", pathbuf))); - sendFile(pathbuf, pathbuf, &statbuf, false); + sendFile(pathbuf, pathbuf, &statbuf, false, InvalidOid); /* unconditionally mark file as archived */ StatusFilePath(pathbuf, fname, ".done"); @@ -597,14 +614,9 @@ perform_base_backup(basebackup_options *opt) if (total_checksum_failures) { if (total_checksum_failures > 1) - { - char buf[64]; - - snprintf(buf, sizeof(buf), INT64_FORMAT, total_checksum_failures); - ereport(WARNING, - (errmsg("%s total checksum verification failures", buf))); - } + (errmsg("%lld total checksum verification failures", total_checksum_failures))); + ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("checksum verification failure during base backup"))); @@ -613,14 +625,14 @@ perform_base_backup(basebackup_options *opt) } /* - * qsort comparison function, to compare log/seg portion of WAL segment + * list_sort comparison function, to compare log/seg portion of WAL segment * filenames, ignoring the timeline portion. */ static int -compareWalFileNames(const void *a, const void *b) +compareWalFileNames(const ListCell *a, const ListCell *b) { - char *fna = *((char **) a); - char *fnb = *((char **) b); + char *fna = (char *) lfirst(a); + char *fnb = (char *) lfirst(b); return strcmp(fna + 8, fnb + 8); } @@ -794,7 +806,7 @@ SendBackupHeader(List *tablespaces) pq_sendint32(&buf, 0); /* typmod */ pq_sendint16(&buf, 0); /* format code */ - /* Second field - spcpath */ + /* Second field - spclocation */ pq_sendstring(&buf, "spclocation"); pq_sendint32(&buf, 0); pq_sendint16(&buf, 0); @@ -1015,15 +1027,15 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, char pathbuf[MAXPGPATH * 2]; struct stat statbuf; int64 size = 0; - const char *lastDir; /* Split last dir from parent path. */ - bool isDbDir = false; /* Does this directory contain relations? */ + const char *lastDir; /* Split last dir from parent path. */ + bool isDbDir = false; /* Does this directory contain relations? */ /* - * Determine if the current path is a database directory that can - * contain relations. + * Determine if the current path is a database directory that can contain + * relations. * - * Start by finding the location of the delimiter between the parent - * path and the current path. + * Start by finding the location of the delimiter between the parent path + * and the current path. */ lastDir = last_dir_separator(path); @@ -1032,7 +1044,7 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, strspn(lastDir + 1, "0123456789") == strlen(lastDir + 1)) { /* Part of path that contains the parent directory. */ - int parentPathLen = lastDir - path; + int parentPathLen = lastDir - path; /* * Mark path as a database directory if the parent path is either @@ -1051,7 +1063,7 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, { int excludeIdx; bool excludeFound; - ForkNumber relForkNum; /* Type of fork if file is a relation */ + ForkNumber relForkNum; /* Type of fork if file is a relation */ int relOidChars; /* Chars in filename that are the rel oid */ /* Skip special stuff */ @@ -1069,7 +1081,7 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, * error in that case. The error handler further up will call * do_pg_abort_backup() for us. Also check that if the backup was * started while still in recovery, the server wasn't promoted. - * dp_pg_stop_backup() will check that too, but it's better to stop + * do_pg_stop_backup() will check that too, but it's better to stop * the backup early than continue to the end and fail there. */ CHECK_FOR_INTERRUPTS(); @@ -1104,8 +1116,8 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, /* Never exclude init forks */ if (relForkNum != INIT_FORKNUM) { - char initForkFile[MAXPGPATH]; - char relOid[OIDCHARS + 1]; + char initForkFile[MAXPGPATH]; + char relOid[OIDCHARS + 1]; /* * If any other type of fork, check if there is an init fork @@ -1292,7 +1304,7 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, if (!sizeonly) sent = sendFile(pathbuf, pathbuf + basepathlen + 1, &statbuf, - true); + true, isDbDir ? pg_atoi(lastDir + 1, sizeof(Oid), 0) : InvalidOid); if (sent || sizeonly) { @@ -1318,7 +1330,7 @@ sendDir(const char *path, int basepathlen, bool sizeonly, List *tablespaces, static bool is_checksummed_file(const char *fullpath, const char *filename) { - const char **f; + const char *const *f; /* Check that the file is in a tablespace */ if (strncmp(fullpath, "./global/", 9) == 0 || @@ -1348,12 +1360,15 @@ is_checksummed_file(const char *fullpath, const char *filename) * * If 'missing_ok' is true, will not throw an error if the file is not found. * + * If dboid is anything other than InvalidOid then any checksum failures detected + * will get reported to the stats collector. + * * Returns true if the file was successfully sent, false if 'missing_ok', * and the file did not exist. */ static bool sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf, - bool missing_ok) + bool missing_ok, Oid dboid) { FILE *fp; BlockNumber blkno = 0; @@ -1361,7 +1376,7 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf char buf[TAR_SEND_SIZE]; uint16 checksum; int checksum_failures = 0; - size_t cnt; + off_t cnt; int i; pgoff_t len = 0; char *page; @@ -1417,17 +1432,17 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf while ((cnt = fread(buf, 1, Min(sizeof(buf), statbuf->st_size - len), fp)) > 0) { /* - * The checksums are verified at block level, so we iterate over - * the buffer in chunks of BLCKSZ, after making sure that - * TAR_SEND_SIZE/buf is divisible by BLCKSZ and we read a multiple - * of BLCKSZ bytes. + * The checksums are verified at block level, so we iterate over the + * buffer in chunks of BLCKSZ, after making sure that + * TAR_SEND_SIZE/buf is divisible by BLCKSZ and we read a multiple of + * BLCKSZ bytes. */ Assert(TAR_SEND_SIZE % BLCKSZ == 0); if (verify_checksum && (cnt % BLCKSZ != 0)) { ereport(WARNING, - (errmsg("cannot verify checksum in file \"%s\", block " + (errmsg("could not verify checksum in file \"%s\", block " "%d: read buffer size %d and page size %d " "differ", readfilename, blkno, (int) cnt, BLCKSZ))); @@ -1445,9 +1460,10 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf * start of the base backup. Otherwise, they might have been * written only halfway and the checksum would not be valid. * However, replaying WAL would reinstate the correct page in - * this case. + * this case. We also skip completely new pages, since they + * don't have a checksum yet. */ - if (PageGetLSN(page) < startptr) + if (!PageIsNew(page) && PageGetLSN(page) < startptr) { checksum = pg_checksum_page((char *) page, blkno + segmentno * RELSEG_SIZE); phdr = (PageHeader) page; @@ -1476,6 +1492,20 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf if (fread(buf + BLCKSZ * i, 1, BLCKSZ, fp) != BLCKSZ) { + /* + * If we hit end-of-file, a concurrent + * truncation must have occurred, so break out + * of this loop just as if the initial fread() + * returned 0. We'll drop through to the same + * code that handles that case. (We must fix + * up cnt first, though.) + */ + if (feof(fp)) + { + cnt = BLCKSZ * i; + break; + } + ereport(ERROR, (errcode_for_file_access(), errmsg("could not reread block %d of file \"%s\": %m", @@ -1527,7 +1557,7 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf len += cnt; throttle(cnt); - if (len >= statbuf->st_size) + if (feof(fp) || len >= statbuf->st_size) { /* * Reached end of file. The file could be longer, if it was @@ -1538,6 +1568,8 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf } } + CHECK_FREAD_ERROR(fp, readfilename); + /* If the file was truncated while we were sending it, pad it with zeros */ if (len < statbuf->st_size) { @@ -1567,9 +1599,14 @@ sendFile(const char *readfilename, const char *tarfilename, struct stat *statbuf if (checksum_failures > 1) { ereport(WARNING, - (errmsg("file \"%s\" has a total of %d checksum verification " - "failures", readfilename, checksum_failures))); + (errmsg_plural("file \"%s\" has a total of %d checksum verification failure", + "file \"%s\" has a total of %d checksum verification failures", + checksum_failures, + readfilename, checksum_failures))); + + pgstat_report_checksum_failures_in_db(dboid, checksum_failures); } + total_checksum_failures += checksum_failures; return true; @@ -1682,7 +1719,7 @@ throttle(size_t increment) * the maximum time to sleep. Thus the cast to long is safe. */ wait_result = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, (long) (sleep / 1000), WAIT_EVENT_BASE_BACKUP_THROTTLE); diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index ec37377efe5..6eba08a9208 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -6,7 +6,7 @@ * loaded as a dynamic module to avoid linking the main server binary with * libpq. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -49,35 +49,35 @@ struct WalReceiverConn /* Prototypes for interface functions */ static WalReceiverConn *libpqrcv_connect(const char *conninfo, - bool logical, const char *appname, - char **err); + bool logical, const char *appname, + char **err); static void libpqrcv_check_conninfo(const char *conninfo); static char *libpqrcv_get_conninfo(WalReceiverConn *conn); static void libpqrcv_get_senderinfo(WalReceiverConn *conn, - char **sender_host, int *sender_port); + char **sender_host, int *sender_port); static char *libpqrcv_identify_system(WalReceiverConn *conn, - TimeLineID *primary_tli, - int *server_version); + TimeLineID *primary_tli); +static int libpqrcv_server_version(WalReceiverConn *conn); static void libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn, - TimeLineID tli, char **filename, - char **content, int *len); + TimeLineID tli, char **filename, + char **content, int *len); static bool libpqrcv_startstreaming(WalReceiverConn *conn, - const WalRcvStreamOptions *options); + const WalRcvStreamOptions *options); static void libpqrcv_endstreaming(WalReceiverConn *conn, - TimeLineID *next_tli); -static int libpqrcv_receive(WalReceiverConn *conn, char **buffer, - pgsocket *wait_fd); + TimeLineID *next_tli); +static int libpqrcv_receive(WalReceiverConn *conn, char **buffer, + pgsocket *wait_fd); static void libpqrcv_send(WalReceiverConn *conn, const char *buffer, - int nbytes); + int nbytes); static char *libpqrcv_create_slot(WalReceiverConn *conn, - const char *slotname, - bool temporary, - CRSSnapshotAction snapshot_action, - XLogRecPtr *lsn); + const char *slotname, + bool temporary, + CRSSnapshotAction snapshot_action, + XLogRecPtr *lsn); static WalRcvExecResult *libpqrcv_exec(WalReceiverConn *conn, - const char *query, - const int nRetTypes, - const Oid *retTypes); + const char *query, + const int nRetTypes, + const Oid *retTypes); static void libpqrcv_disconnect(WalReceiverConn *conn); static WalReceiverFunctionsType PQWalReceiverFunctions = { @@ -86,6 +86,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = { libpqrcv_get_conninfo, libpqrcv_get_senderinfo, libpqrcv_identify_system, + libpqrcv_server_version, libpqrcv_readtimelinehistoryfile, libpqrcv_startstreaming, libpqrcv_endstreaming, @@ -98,6 +99,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = { /* Prototypes for private functions */ static PGresult *libpqrcv_PQexec(PGconn *streamConn, const char *query); +static PGresult *libpqrcv_PQgetResult(PGconn *streamConn); static char *stringlist_to_identifierstr(PGconn *conn, List *strings); /* @@ -128,10 +130,7 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname, /* * We use the expand_dbname parameter to process the connection string (or - * URI), and pass some extra options. The deliberately undocumented - * parameter "replication=true" makes it a replication connection. The - * database name is ignored by the server in replication mode, but specify - * "replication" for .pgpass lookup. + * URI), and pass some extra options. */ keys[i] = "dbname"; vals[i] = conninfo; @@ -139,6 +138,10 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname, vals[i] = logical ? "database" : "true"; if (!logical) { + /* + * The database name is ignored by the server in replication mode, but + * specify "replication" for .pgpass lookup. + */ keys[++i] = "dbname"; vals[i] = "replication"; } @@ -185,21 +188,16 @@ libpqrcv_connect(const char *conninfo, bool logical, const char *appname, io_flag = WL_SOCKET_WRITEABLE; rc = WaitLatchOrSocket(MyLatch, - WL_POSTMASTER_DEATH | - WL_LATCH_SET | io_flag, + WL_EXIT_ON_PM_DEATH | WL_LATCH_SET | io_flag, PQsocket(conn->streamConn), 0, WAIT_EVENT_LIBPQWALRECEIVER_CONNECT); - /* Emergency bailout? */ - if (rc & WL_POSTMASTER_DEATH) - exit(1); - /* Interrupted? */ if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); - CHECK_FOR_INTERRUPTS(); + ProcessWalRcvInterrupts(); } /* If socket is ready, advance the libpq state machine */ @@ -290,9 +288,9 @@ libpqrcv_get_conninfo(WalReceiverConn *conn) */ static void libpqrcv_get_senderinfo(WalReceiverConn *conn, char **sender_host, - int *sender_port) + int *sender_port) { - char *ret = NULL; + char *ret = NULL; *sender_host = NULL; *sender_port = 0; @@ -313,8 +311,7 @@ libpqrcv_get_senderinfo(WalReceiverConn *conn, char **sender_host, * timeline ID of the primary. */ static char * -libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli, - int *server_version) +libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli) { PGresult *res; char *primary_sysid; @@ -344,14 +341,21 @@ libpqrcv_identify_system(WalReceiverConn *conn, TimeLineID *primary_tli, ntuples, nfields, 3, 1))); } primary_sysid = pstrdup(PQgetvalue(res, 0, 0)); - *primary_tli = pg_atoi(PQgetvalue(res, 0, 1), 4, 0); + *primary_tli = pg_strtoint32(PQgetvalue(res, 0, 1)); PQclear(res); - *server_version = PQserverVersion(conn->streamConn); - return primary_sysid; } +/* + * Thin wrapper around libpq to obtain server version. + */ +static int +libpqrcv_server_version(WalReceiverConn *conn) +{ + return PQserverVersion(conn->streamConn); +} + /* * Start streaming WAL data from given streaming options. * @@ -453,6 +457,10 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) { PGresult *res; + /* + * Send copy-end message. As in libpqrcv_PQexec, this could theoretically + * block, but the risk seems small. + */ if (PQputCopyEnd(conn->streamConn, NULL) <= 0 || PQflush(conn->streamConn)) ereport(ERROR, @@ -469,7 +477,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) * If we had not yet received CopyDone from the backend, PGRES_COPY_OUT is * also possible in case we aborted the copy in mid-stream. */ - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); if (PQresultStatus(res) == PGRES_TUPLES_OK) { /* @@ -479,11 +487,11 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) if (PQnfields(res) < 2 || PQntuples(res) != 1) ereport(ERROR, (errmsg("unexpected result set after end-of-streaming"))); - *next_tli = pg_atoi(PQgetvalue(res, 0, 0), sizeof(uint32), 0); + *next_tli = pg_strtoint32(PQgetvalue(res, 0, 0)); PQclear(res); /* the result set should be followed by CommandComplete */ - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); } else if (PQresultStatus(res) == PGRES_COPY_OUT) { @@ -496,7 +504,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) pchomp(PQerrorMessage(conn->streamConn))))); /* CommandComplete should follow */ - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); } if (PQresultStatus(res) != PGRES_COMMAND_OK) @@ -506,7 +514,7 @@ libpqrcv_endstreaming(WalReceiverConn *conn, TimeLineID *next_tli) PQclear(res); /* Verify that there are no more results */ - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); if (res != NULL) ereport(ERROR, (errmsg("unexpected result after CommandComplete: %s", @@ -569,12 +577,11 @@ libpqrcv_readtimelinehistoryfile(WalReceiverConn *conn, * The function is modeled on PQexec() in libpq, but only implements * those parts that are in use in the walreceiver api. * - * Queries are always executed on the connection in streamConn. + * May return NULL, rather than an error result, on failure. */ static PGresult * libpqrcv_PQexec(PGconn *streamConn, const char *query) { - PGresult *result = NULL; PGresult *lastResult = NULL; /* @@ -585,64 +592,26 @@ libpqrcv_PQexec(PGconn *streamConn, const char *query) */ /* - * Submit a query. Since we don't use non-blocking mode, this also can - * block. But its risk is relatively small, so we ignore that for now. + * Submit the query. Since we don't use non-blocking mode, this could + * theoretically block. In practice, since we don't send very long query + * strings, the risk seems negligible. */ if (!PQsendQuery(streamConn, query)) return NULL; for (;;) { - /* - * Receive data until PQgetResult is ready to get the result without - * blocking. - */ - while (PQisBusy(streamConn)) - { - int rc; - - /* - * We don't need to break down the sleep into smaller increments, - * since we'll get interrupted by signals and can either handle - * interrupts here or elog(FATAL) within SIGTERM signal handler if - * the signal arrives in the middle of establishment of - * replication connection. - */ - rc = WaitLatchOrSocket(MyLatch, - WL_POSTMASTER_DEATH | WL_SOCKET_READABLE | - WL_LATCH_SET, - PQsocket(streamConn), - 0, - WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE); - - /* Emergency bailout? */ - if (rc & WL_POSTMASTER_DEATH) - exit(1); - - /* Interrupted? */ - if (rc & WL_LATCH_SET) - { - ResetLatch(MyLatch); - CHECK_FOR_INTERRUPTS(); - } + /* Wait for, and collect, the next PGresult. */ + PGresult *result; - /* Consume whatever data is available from the socket */ - if (PQconsumeInput(streamConn) == 0) - { - /* trouble; drop whatever we had and return NULL */ - PQclear(lastResult); - return NULL; - } - } + result = libpqrcv_PQgetResult(streamConn); + if (result == NULL) + break; /* query is complete, or failure */ /* * Emulate PQexec()'s behavior of returning the last result when there * are many. We are fine with returning just last error message. */ - result = PQgetResult(streamConn); - if (result == NULL) - break; /* query is complete */ - PQclear(lastResult); lastResult = result; @@ -656,6 +625,51 @@ libpqrcv_PQexec(PGconn *streamConn, const char *query) return lastResult; } +/* + * Perform the equivalent of PQgetResult(), but watch for interrupts. + */ +static PGresult * +libpqrcv_PQgetResult(PGconn *streamConn) +{ + /* + * Collect data until PQgetResult is ready to get the result without + * blocking. + */ + while (PQisBusy(streamConn)) + { + int rc; + + /* + * We don't need to break down the sleep into smaller increments, + * since we'll get interrupted by signals and can handle any + * interrupts here. + */ + rc = WaitLatchOrSocket(MyLatch, + WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | + WL_LATCH_SET, + PQsocket(streamConn), + 0, + WAIT_EVENT_LIBPQWALRECEIVER_RECEIVE); + + /* Interrupted? */ + if (rc & WL_LATCH_SET) + { + ResetLatch(MyLatch); + ProcessWalRcvInterrupts(); + } + + /* Consume whatever data is available from the socket */ + if (PQconsumeInput(streamConn) == 0) + { + /* trouble; return NULL */ + return NULL; + } + } + + /* Now we can collect and return the next PGresult */ + return PQgetResult(streamConn); +} + /* * Disconnect connection to primary, if any. */ @@ -717,13 +731,13 @@ libpqrcv_receive(WalReceiverConn *conn, char **buffer, { PGresult *res; - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); if (PQresultStatus(res) == PGRES_COMMAND_OK) { PQclear(res); /* Verify that there are no more results. */ - res = PQgetResult(conn->streamConn); + res = libpqrcv_PQgetResult(conn->streamConn); if (res != NULL) { PQclear(res); @@ -867,7 +881,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres, walres->tuplestore = tuplestore_begin_heap(true, false, work_mem); /* Create tuple descriptor corresponding to expected result. */ - walres->tupledesc = CreateTemplateTupleDesc(nRetTypes, false); + walres->tupledesc = CreateTemplateTupleDesc(nRetTypes); for (coln = 0; coln < nRetTypes; coln++) TupleDescInitEntry(walres->tupledesc, (AttrNumber) coln + 1, PQfname(pgres, coln), retTypes[coln], -1, 0); @@ -887,7 +901,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres, { char *cstrs[MaxTupleAttributeNumber]; - CHECK_FOR_INTERRUPTS(); + ProcessWalRcvInterrupts(); /* Do the allocations in temporary context. */ oldcontext = MemoryContextSwitchTo(rowcontext); diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index 59c003de9ce..c53e7e22798 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -16,7 +16,7 @@ * contents of records in here except turning them into a more usable * format. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -70,9 +70,9 @@ static void DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf static void DecodeSpecConfirm(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); static void DecodeCommit(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_commit *parsed, TransactionId xid); + xl_xact_parsed_commit *parsed, TransactionId xid); static void DecodeAbort(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, - xl_xact_parsed_abort *parsed, TransactionId xid); + xl_xact_parsed_abort *parsed, TransactionId xid); /* common function to decode tuples */ static void DecodeXLogTuple(char *data, Size len, ReorderBufferTupleBuf *tup); @@ -217,12 +217,15 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) uint8 info = XLogRecGetInfo(r) & XLOG_XACT_OPMASK; /* - * No point in doing anything yet, data could not be decoded anyway. It's - * ok not to call ReorderBufferProcessXid() in that case, except in the - * assignment case there'll not be any later records with the same xid; - * and in the assignment case we'll not decode those xacts. + * If the snapshot isn't yet fully built, we cannot decode anything, so + * bail out. + * + * However, it's critical to process XLOG_XACT_ASSIGNMENT records even + * when the snapshot is being built: it is possible to get later records + * that require subxids to be properly assigned. */ - if (SnapBuildCurrentState(builder) < SNAPBUILD_FULL_SNAPSHOT) + if (SnapBuildCurrentState(builder) < SNAPBUILD_FULL_SNAPSHOT && + info != XLOG_XACT_ASSIGNMENT) return; switch (info) @@ -665,6 +668,9 @@ DecodeAbort(LogicalDecodingContext *ctx, XLogRecordBuffer *buf, static void DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) { + Size datalen; + char *tupledata; + Size tuplelen; XLogReaderState *r = buf->record; xl_heap_insert *xlrec; ReorderBufferChange *change; @@ -672,6 +678,13 @@ DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) xlrec = (xl_heap_insert *) XLogRecGetData(r); + /* + * Ignore insert records without new tuples (this does happen when + * raw_heap_insert marks the TOAST record as HEAP_INSERT_NO_LOGICAL). + */ + if (!(xlrec->flags & XLH_INSERT_CONTAINS_NEW_TUPLE)) + return; + /* only interested in our database */ XLogRecGetBlockTag(r, 0, &target_node, NULL, NULL); if (target_node.dbNode != ctx->slot->data.database) @@ -690,17 +703,13 @@ DecodeInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) memcpy(&change->data.tp.relnode, &target_node, sizeof(RelFileNode)); - if (xlrec->flags & XLH_INSERT_CONTAINS_NEW_TUPLE) - { - Size datalen; - char *tupledata = XLogRecGetBlockData(r, 0, &datalen); - Size tuplelen = datalen - SizeOfHeapHeader; + tupledata = XLogRecGetBlockData(r, 0, &datalen); + tuplelen = datalen - SizeOfHeapHeader; - change->data.tp.newtuple = - ReorderBufferGetTupleBuf(ctx->reorder, tuplelen); + change->data.tp.newtuple = + ReorderBufferGetTupleBuf(ctx->reorder, tuplelen); - DecodeXLogTuple(tupledata, datalen, change->data.tp.newtuple); - } + DecodeXLogTuple(tupledata, datalen, change->data.tp.newtuple); change->data.tp.clear_toast_afterwards = true; @@ -859,7 +868,8 @@ DecodeTruncate(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) if (xlrec->flags & XLH_TRUNCATE_RESTART_SEQS) change->data.truncate.restart_seqs = true; change->data.truncate.nrelids = xlrec->nrelids; - change->data.truncate.relids = palloc(xlrec->nrelids * sizeof(Oid)); + change->data.truncate.relids = ReorderBufferGetRelids(ctx->reorder, + xlrec->nrelids); memcpy(change->data.truncate.relids, xlrec->relids, xlrec->nrelids * sizeof(Oid)); ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), @@ -893,7 +903,12 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) if (FilterByOrigin(ctx, XLogRecGetOrigin(r))) return; + /* + * As multi_insert is not used for catalogs yet, the block should always + * have data even if a full-page write of it is taken. + */ tupledata = XLogRecGetBlockData(r, 0, &tuplelen); + Assert(tupledata != NULL); data = tupledata; for (i = 0; i < xlrec->ntuples; i++) @@ -909,6 +924,10 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) memcpy(&change->data.tp.relnode, &rnode, sizeof(RelFileNode)); + xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data); + data = ((char *) xlhdr) + SizeOfMultiInsertTuple; + datalen = xlhdr->datalen; + /* * CONTAINS_NEW_TUPLE will always be set currently as multi_insert * isn't used for catalogs, but better be future proof. @@ -920,10 +939,6 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) { HeapTupleHeader header; - xlhdr = (xl_multi_insert_tuple *) SHORTALIGN(data); - data = ((char *) xlhdr) + SizeOfMultiInsertTuple; - datalen = xlhdr->datalen; - change->data.tp.newtuple = ReorderBufferGetTupleBuf(ctx->reorder, datalen); @@ -946,8 +961,6 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) memcpy((char *) tuple->tuple.t_data + SizeofHeapTupleHeader, (char *) data, datalen); - data += datalen; - header->t_infomask = xlhdr->t_infomask; header->t_infomask2 = xlhdr->t_infomask2; header->t_hoff = xlhdr->t_hoff; @@ -966,6 +979,9 @@ DecodeMultiInsert(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) ReorderBufferQueueChange(ctx->reorder, XLogRecGetXid(r), buf->origptr, change); + + /* move to the next xl_multi_insert_tuple entry */ + data += datalen; } Assert(data == tupledata + tuplelen); } diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c index 6ef333b7257..7e639be1fff 100644 --- a/src/backend/replication/logical/launcher.c +++ b/src/backend/replication/logical/launcher.c @@ -2,7 +2,7 @@ * launcher.c * PostgreSQL logical replication worker launcher process * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/launcher.c @@ -24,6 +24,7 @@ #include "access/heapam.h" #include "access/htup.h" #include "access/htup_details.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/pg_subscription.h" @@ -79,7 +80,19 @@ typedef struct LogicalRepWorkerId Oid relid; } LogicalRepWorkerId; -static List *on_commit_stop_workers = NIL; +typedef struct StopWorkersData +{ + int nestDepth; /* Sub-transaction nest level */ + List *workers; /* List of LogicalRepWorkerId */ + struct StopWorkersData *parent; /* This need not be an immediate + * subtransaction parent */ +} StopWorkersData; + +/* + * Stack of StopWorkersData elements. Each stack element contains the workers + * to be stopped for that subtransaction. + */ +static StopWorkersData *on_commit_stop_workers = NULL; static void ApplyLauncherWakeup(void); static void logicalrep_launcher_onexit(int code, Datum arg); @@ -106,7 +119,7 @@ get_subscription_list(void) { List *res = NIL; Relation rel; - HeapScanDesc scan; + TableScanDesc scan; HeapTuple tup; MemoryContext resultcxt; @@ -123,8 +136,8 @@ get_subscription_list(void) StartTransactionCommand(); (void) GetTransactionSnapshot(); - rel = heap_open(SubscriptionRelationId, AccessShareLock); - scan = heap_beginscan_catalog(rel, 0, NULL); + rel = table_open(SubscriptionRelationId, AccessShareLock); + scan = table_beginscan_catalog(rel, 0, NULL); while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) { @@ -141,7 +154,7 @@ get_subscription_list(void) oldcxt = MemoryContextSwitchTo(resultcxt); sub = (Subscription *) palloc0(sizeof(Subscription)); - sub->oid = HeapTupleGetOid(tup); + sub->oid = subform->oid; sub->dbid = subform->subdbid; sub->owner = subform->subowner; sub->enabled = subform->subenabled; @@ -152,8 +165,8 @@ get_subscription_list(void) MemoryContextSwitchTo(oldcxt); } - heap_endscan(scan); - heap_close(rel, AccessShareLock); + table_endscan(scan); + table_close(rel, AccessShareLock); CommitTransactionCommand(); @@ -209,13 +222,9 @@ WaitForReplicationWorkerAttach(LogicalRepWorker *worker, * about the worker attach. But we don't expect to have to wait long. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 10L, WAIT_EVENT_BGWORKER_STARTUP); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); @@ -486,13 +495,9 @@ logicalrep_worker_stop(Oid subid, Oid relid) /* Wait a bit --- we don't expect to have to wait long. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 10L, WAIT_EVENT_BGWORKER_STARTUP); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); @@ -534,13 +539,9 @@ logicalrep_worker_stop(Oid subid, Oid relid) /* Wait a bit --- we don't expect to have to wait long. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 10L, WAIT_EVENT_BGWORKER_SHUTDOWN); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); @@ -559,17 +560,41 @@ logicalrep_worker_stop(Oid subid, Oid relid) void logicalrep_worker_stop_at_commit(Oid subid, Oid relid) { + int nestDepth = GetCurrentTransactionNestLevel(); LogicalRepWorkerId *wid; MemoryContext oldctx; /* Make sure we store the info in context that survives until commit. */ oldctx = MemoryContextSwitchTo(TopTransactionContext); + /* Check that previous transactions were properly cleaned up. */ + Assert(on_commit_stop_workers == NULL || + nestDepth >= on_commit_stop_workers->nestDepth); + + /* + * Push a new stack element if we don't already have one for the current + * nestDepth. + */ + if (on_commit_stop_workers == NULL || + nestDepth > on_commit_stop_workers->nestDepth) + { + StopWorkersData *newdata = palloc(sizeof(StopWorkersData)); + + newdata->nestDepth = nestDepth; + newdata->workers = NIL; + newdata->parent = on_commit_stop_workers; + on_commit_stop_workers = newdata; + } + + /* + * Finally add a new worker into the worker list of the current + * subtransaction. + */ wid = palloc(sizeof(LogicalRepWorkerId)); wid->subid = subid; wid->relid = relid; - - on_commit_stop_workers = lappend(on_commit_stop_workers, wid); + on_commit_stop_workers->workers = + lappend(on_commit_stop_workers->workers, wid); MemoryContextSwitchTo(oldctx); } @@ -823,7 +848,7 @@ ApplyLauncherShmemInit(void) bool XactManipulatesLogicalReplicationWorkers(void) { - return (on_commit_stop_workers != NIL); + return (on_commit_stop_workers != NULL); } /* @@ -832,15 +857,25 @@ XactManipulatesLogicalReplicationWorkers(void) void AtEOXact_ApplyLauncher(bool isCommit) { + + Assert(on_commit_stop_workers == NULL || + (on_commit_stop_workers->nestDepth == 1 && + on_commit_stop_workers->parent == NULL)); + if (isCommit) { ListCell *lc; - foreach(lc, on_commit_stop_workers) + if (on_commit_stop_workers != NULL) { - LogicalRepWorkerId *wid = lfirst(lc); + List *workers = on_commit_stop_workers->workers; - logicalrep_worker_stop(wid->subid, wid->relid); + foreach(lc, workers) + { + LogicalRepWorkerId *wid = lfirst(lc); + + logicalrep_worker_stop(wid->subid, wid->relid); + } } if (on_commit_launcher_wakeup) @@ -851,10 +886,64 @@ AtEOXact_ApplyLauncher(bool isCommit) * No need to pfree on_commit_stop_workers. It was allocated in * transaction memory context, which is going to be cleaned soon. */ - on_commit_stop_workers = NIL; + on_commit_stop_workers = NULL; on_commit_launcher_wakeup = false; } +/* + * On commit, merge the current on_commit_stop_workers list into the + * immediate parent, if present. + * On rollback, discard the current on_commit_stop_workers list. + * Pop out the stack. + */ +void +AtEOSubXact_ApplyLauncher(bool isCommit, int nestDepth) +{ + StopWorkersData *parent; + + /* Exit immediately if there's no work to do at this level. */ + if (on_commit_stop_workers == NULL || + on_commit_stop_workers->nestDepth < nestDepth) + return; + + Assert(on_commit_stop_workers->nestDepth == nestDepth); + + parent = on_commit_stop_workers->parent; + + if (isCommit) + { + /* + * If the upper stack element is not an immediate parent + * subtransaction, just decrement the notional nesting depth without + * doing any real work. Else, we need to merge the current workers + * list into the parent. + */ + if (!parent || parent->nestDepth < nestDepth - 1) + { + on_commit_stop_workers->nestDepth--; + return; + } + + parent->workers = + list_concat(parent->workers, on_commit_stop_workers->workers); + } + else + { + /* + * Abandon everything that was done at this nesting level. Explicitly + * free memory to avoid a transaction-lifespan leak. + */ + list_free_deep(on_commit_stop_workers->workers); + } + + /* + * We have taken care of the current subtransaction workers list for both + * abort or commit. So we are ready to pop the stack. + */ + pfree(on_commit_stop_workers); + on_commit_stop_workers = parent; +} + /* * Request wakeup of the launcher on commit of the transaction. * @@ -889,6 +978,9 @@ ApplyLauncherMain(Datum main_arg) before_shmem_exit(logicalrep_launcher_onexit, (Datum) 0); + while (LogicalRepCtx->launcher_pid != 0) + pg_usleep(1000000); + Assert(LogicalRepCtx->launcher_pid == 0); LogicalRepCtx->launcher_pid = MyProcPid; @@ -972,14 +1064,10 @@ ApplyLauncherMain(Datum main_arg) /* Wait for more work. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, wait_time, WAIT_EVENT_LOGICAL_LAUNCHER_MAIN); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c index 0737c7b1e75..da265f52940 100644 --- a/src/backend/replication/logical/logical.c +++ b/src/backend/replication/logical/logical.c @@ -2,7 +2,7 @@ * logical.c * PostgreSQL logical decoding coordination * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/logical.c @@ -28,6 +28,7 @@ #include "postgres.h" +#include "fmgr.h" #include "miscadmin.h" #include "access/xact.h" @@ -55,18 +56,18 @@ typedef struct LogicalErrorCallbackState /* wrappers around output plugin callbacks */ static void output_plugin_error_callback(void *arg); static void startup_cb_wrapper(LogicalDecodingContext *ctx, OutputPluginOptions *opt, - bool is_init); + bool is_init); static void shutdown_cb_wrapper(LogicalDecodingContext *ctx); static void begin_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn); static void commit_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr commit_lsn); + XLogRecPtr commit_lsn); static void change_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - Relation relation, ReorderBufferChange *change); + Relation relation, ReorderBufferChange *change); static void truncate_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - int nrelations, Relation relations[], ReorderBufferChange *change); + int nrelations, Relation relations[], ReorderBufferChange *change); static void message_cb_wrapper(ReorderBuffer *cache, ReorderBufferTXN *txn, - XLogRecPtr message_lsn, bool transactional, - const char *prefix, Size message_size, const char *message); + XLogRecPtr message_lsn, bool transactional, + const char *prefix, Size message_size, const char *message); static void LoadOutputPlugin(OutputPluginCallbacks *callbacks, char *plugin); @@ -79,6 +80,11 @@ CheckLogicalDecodingRequirements(void) { CheckSlotRequirements(); + /* + * NB: Adding a new requirement likely means that RestoreSlotFromDisk() + * needs the same check. + */ + if (wal_level < WAL_LEVEL_LOGICAL) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -109,7 +115,7 @@ CheckLogicalDecodingRequirements(void) } /* - * Helper function for CreateInitialDecodingContext() and + * Helper function for CreateInitDecodingContext() and * CreateDecodingContext() performing common tasks. */ static LogicalDecodingContext * @@ -167,14 +173,12 @@ StartupDecodingContext(List *output_plugin_options, ctx->slot = slot; - ctx->reader = XLogReaderAllocate(wal_segment_size, read_page, ctx); + ctx->reader = XLogReaderAllocate(wal_segment_size, NULL, read_page, ctx); if (!ctx->reader) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"))); - ctx->reader->private_data = ctx; - ctx->reorder = ReorderBufferAllocate(); ctx->snapshot_builder = AllocateSnapshotBuilder(ctx->reorder, xmin_horizon, start_lsn, @@ -206,11 +210,15 @@ StartupDecodingContext(List *output_plugin_options, /* * Create a new decoding context, for a new logical slot. * - * plugin contains the name of the output plugin - * output_plugin_options contains options passed to the output plugin - * read_page, prepare_write, do_write, update_progress - * callbacks that have to be filled to perform the use-case dependent, - * actual, work. + * plugin -- contains the name of the output plugin + * output_plugin_options -- contains options passed to the output plugin + * restart_lsn -- if given as invalid, it's this routine's responsibility to + * mark WAL as reserved by setting a convenient restart_lsn for the slot. + * Otherwise, we set for decoding to start from the given LSN without + * marking WAL reserved beforehand. In that scenario, it's up to the + * caller to guarantee that WAL remains available. + * read_page, prepare_write, do_write, update_progress -- + * callbacks that perform the use-case dependent, actual, work. * * Needs to be called while in a memory context that's at least as long lived * as the decoding context because further memory contexts will be created @@ -223,6 +231,7 @@ LogicalDecodingContext * CreateInitDecodingContext(char *plugin, List *output_plugin_options, bool need_full_snapshot, + XLogRecPtr restart_lsn, XLogPageReadCB read_page, LogicalOutputPluginWriterPrepareWrite prepare_write, LogicalOutputPluginWriterWrite do_write, @@ -266,7 +275,14 @@ CreateInitDecodingContext(char *plugin, StrNCpy(NameStr(slot->data.plugin), plugin, NAMEDATALEN); SpinLockRelease(&slot->mutex); - ReplicationSlotReserveWal(); + if (XLogRecPtrIsInvalid(restart_lsn)) + ReplicationSlotReserveWal(); + else + { + SpinLockAcquire(&slot->mutex); + slot->data.restart_lsn = restart_lsn; + SpinLockRelease(&slot->mutex); + } /* ---- * This is a bit tricky: We need to determine a safe xmin horizon to start @@ -297,10 +313,12 @@ CreateInitDecodingContext(char *plugin, xmin_horizon = GetOldestSafeDecodingTransactionId(!need_full_snapshot); + SpinLockAcquire(&slot->mutex); slot->effective_catalog_xmin = xmin_horizon; slot->data.catalog_xmin = xmin_horizon; if (need_full_snapshot) slot->effective_xmin = xmin_horizon; + SpinLockRelease(&slot->mutex); ReplicationSlotsComputeRequiredXmin(true); @@ -309,8 +327,8 @@ CreateInitDecodingContext(char *plugin, ReplicationSlotMarkDirty(); ReplicationSlotSave(); - ctx = StartupDecodingContext(NIL, InvalidXLogRecPtr, xmin_horizon, - need_full_snapshot, true, + ctx = StartupDecodingContext(NIL, restart_lsn, xmin_horizon, + need_full_snapshot, false, read_page, prepare_write, do_write, update_progress); @@ -336,7 +354,10 @@ CreateInitDecodingContext(char *plugin, * that, see below). * * output_plugin_options - * contains options passed to the output plugin. + * options passed to the output plugin. + * + * fast_forward + * bypass the generation of logical changes. * * read_page, prepare_write, do_write, update_progress * callbacks that have to be filled to perform the use-case dependent, @@ -445,13 +466,14 @@ void DecodingContextFindStartpoint(LogicalDecodingContext *ctx) { XLogRecPtr startptr; + ReplicationSlot *slot = ctx->slot; /* Initialize from where to start reading WAL. */ - startptr = ctx->slot->data.restart_lsn; + startptr = slot->data.restart_lsn; elog(DEBUG1, "searching for logical decoding starting point, starting at %X/%X", - (uint32) (ctx->slot->data.restart_lsn >> 32), - (uint32) ctx->slot->data.restart_lsn); + (uint32) (slot->data.restart_lsn >> 32), + (uint32) slot->data.restart_lsn); /* Wait for a consistent starting point */ for (;;) @@ -477,7 +499,9 @@ DecodingContextFindStartpoint(LogicalDecodingContext *ctx) CHECK_FOR_INTERRUPTS(); } - ctx->slot->data.confirmed_flush = ctx->reader->EndRecPtr; + SpinLockAcquire(&slot->mutex); + slot->data.confirmed_flush = ctx->reader->EndRecPtr; + SpinLockRelease(&slot->mutex); } /* @@ -905,7 +929,7 @@ LogicalIncreaseXminForSlot(XLogRecPtr current_lsn, TransactionId xmin) * Mark the minimal LSN (restart_lsn) we need to read to replay all * transactions that have not yet committed at current_lsn. * - * Just like IncreaseRestartDecodingForSlot this only takes effect when the + * Just like LogicalIncreaseXminForSlot this only takes effect when the * client has confirmed to have received current_lsn. */ void diff --git a/src/backend/replication/logical/logicalfuncs.c b/src/backend/replication/logical/logicalfuncs.c index 54c25f1f5b2..d1cf80d4417 100644 --- a/src/backend/replication/logical/logicalfuncs.c +++ b/src/backend/replication/logical/logicalfuncs.c @@ -6,7 +6,7 @@ * logical replication slots via SQL. * * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logicalfuncs.c @@ -116,10 +116,10 @@ check_permissions(void) int logical_read_local_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, char *cur_page, TimeLineID *pageTLI) + int reqLen, XLogRecPtr targetRecPtr, char *cur_page) { return read_local_xlog_page(state, targetPagePtr, reqLen, - targetRecPtr, cur_page, pageTLI); + targetRecPtr, cur_page); } /* @@ -279,8 +279,6 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin */ startptr = MyReplicationSlot->data.restart_lsn; - CurrentResourceOwner = ResourceOwnerCreate(CurrentResourceOwner, "logical decoding"); - /* invalidate non-timetravel entries */ InvalidateSystemCaches(); @@ -320,6 +318,11 @@ pg_logical_slot_get_changes_guts(FunctionCallInfo fcinfo, bool confirm, bool bin tuplestore_donestoring(tupstore); + /* + * Logical decoding could have clobbered CurrentResourceOwner during + * transaction management, so restore the executor's value. (This is + * a kluge, but it's not worth cleaning up right now.) + */ CurrentResourceOwner = old_resowner; /* diff --git a/src/backend/replication/logical/message.c b/src/backend/replication/logical/message.c index 0eba74c26af..0681cb4a2a4 100644 --- a/src/backend/replication/logical/message.c +++ b/src/backend/replication/logical/message.c @@ -3,7 +3,7 @@ * message.c * Generic logical messages. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/message.c @@ -69,8 +69,8 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size, XLogBeginInsert(); XLogRegisterData((char *) &xlrec, SizeOfLogicalMessage); - XLogRegisterData((char *) prefix, xlrec.prefix_size); - XLogRegisterData((char *) message, size); + XLogRegisterData(unconstify(char *, prefix), xlrec.prefix_size); + XLogRegisterData(unconstify(char *, message), size); /* allow origin filtering */ XLogSetRecordFlags(XLOG_INCLUDE_ORIGIN); diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 963878a5d87..07ae613f708 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -3,7 +3,7 @@ * origin.c * Logical replication progress tracking support. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/origin.c @@ -74,10 +74,11 @@ #include "miscadmin.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" +#include "catalog/catalog.h" #include "catalog/indexing.h" #include "nodes/execnodes.h" @@ -95,7 +96,7 @@ #include "utils/pg_lsn.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" +#include "utils/snapmgr.h" /* * Replay progress of a single remote node. @@ -270,7 +271,7 @@ replorigin_create(char *roname) */ InitDirtySnapshot(SnapshotDirty); - rel = heap_open(ReplicationOriginRelationId, ExclusiveLock); + rel = table_open(ReplicationOriginRelationId, ExclusiveLock); for (roident = InvalidOid + 1; roident < PG_UINT16_MAX; roident++) { @@ -313,7 +314,7 @@ replorigin_create(char *roname) } /* now release lock again, */ - heap_close(rel, ExclusiveLock); + table_close(rel, ExclusiveLock); if (tuple == NULL) ereport(ERROR, @@ -343,7 +344,7 @@ replorigin_drop(RepOriginId roident, bool nowait) * To interlock against concurrent drops, we hold ExclusiveLock on * pg_replication_origin throughout this function. */ - rel = heap_open(ReplicationOriginRelationId, ExclusiveLock); + rel = table_open(ReplicationOriginRelationId, ExclusiveLock); /* * First, clean up the slot state info, if there is any matching slot. @@ -419,7 +420,7 @@ replorigin_drop(RepOriginId roident, bool nowait) CommandCounterIncrement(); /* now release lock again */ - heap_close(rel, ExclusiveLock); + table_close(rel, ExclusiveLock); } @@ -576,9 +577,12 @@ CheckPointReplicationOrigin(void) tmppath))); /* write magic */ + errno = 0; if ((write(tmpfd, &magic, sizeof(magic))) != sizeof(magic)) { - CloseTransientFile(tmpfd); + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(PANIC, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", @@ -614,10 +618,13 @@ CheckPointReplicationOrigin(void) /* make sure we only write out a commit that's persistent */ XLogFlush(local_lsn); + errno = 0; if ((write(tmpfd, &disk_state, sizeof(disk_state))) != sizeof(disk_state)) { - CloseTransientFile(tmpfd); + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(PANIC, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", @@ -631,16 +638,23 @@ CheckPointReplicationOrigin(void) /* write out the CRC */ FIN_CRC32C(crc); + errno = 0; if ((write(tmpfd, &crc, sizeof(crc))) != sizeof(crc)) { - CloseTransientFile(tmpfd); + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; ereport(PANIC, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", tmppath))); } - CloseTransientFile(tmpfd); + if (CloseTransientFile(tmpfd) != 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + tmppath))); /* fsync, rename to permanent file, fsync file and directory */ durable_rename(tmppath, path, PANIC); @@ -697,9 +711,18 @@ StartupReplicationOrigin(void) /* verify magic, that is written even if nothing was active */ readBytes = read(fd, &magic, sizeof(magic)); if (readBytes != sizeof(magic)) - ereport(PANIC, - (errmsg("could not read file \"%s\": %m", - path))); + { + if (readBytes < 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", + path))); + else + ereport(PANIC, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, sizeof(magic)))); + } COMP_CRC32C(crc, &magic, sizeof(magic)); if (magic != REPLICATION_STATE_MAGIC) @@ -766,7 +789,11 @@ StartupReplicationOrigin(void) errmsg("replication slot checkpoint has wrong checksum %u, expected %u", crc, file_crc))); - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + path))); } void @@ -1073,7 +1100,7 @@ replorigin_session_setup(RepOriginId node) { ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("replication identifier %d is already active for PID %d", + errmsg("replication origin %d is already active for PID %d", curstate->roident, curstate->acquired_by))); } @@ -1202,6 +1229,24 @@ pg_replication_origin_create(PG_FUNCTION_ARGS) replorigin_check_prerequisites(false, false); name = text_to_cstring((text *) DatumGetPointer(PG_GETARG_DATUM(0))); + + /* Replication origins "pg_xxx" are reserved for internal use */ + if (IsReservedName(name)) + ereport(ERROR, + (errcode(ERRCODE_RESERVED_NAME), + errmsg("replication origin name \"%s\" is reserved", + name), + errdetail("Origin names starting with \"pg_\" are reserved."))); + + /* + * If built with appropriate switch, whine when regression-testing + * conventions for replication origin names are violated. + */ +#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS + if (strncmp(name, "regress_", 8) != 0) + elog(WARNING, "replication origins created by regression test cases should have names starting with \"regress_\""); +#endif + roident = replorigin_create(name); pfree(name); @@ -1433,7 +1478,7 @@ pg_show_replication_origin_status(PG_FUNCTION_ARGS) int i; #define REPLICATION_ORIGIN_PROGRESS_COLS 4 - /* we we want to return 0 rows if slot is set to zero */ + /* we want to return 0 rows if slot is set to zero */ replorigin_check_prerequisites(false, true); if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) diff --git a/src/backend/replication/logical/proto.c b/src/backend/replication/logical/proto.c index edc97a7662b..e7df47de3ed 100644 --- a/src/backend/replication/logical/proto.c +++ b/src/backend/replication/logical/proto.c @@ -3,7 +3,7 @@ * proto.c * logical replication protocol functions * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/proto.c @@ -31,7 +31,7 @@ static void logicalrep_write_attrs(StringInfo out, Relation rel); static void logicalrep_write_tuple(StringInfo out, Relation rel, - HeapTuple tuple); + HeapTuple tuple); static void logicalrep_read_attrs(StringInfo in, LogicalRepRelation *rel); static void logicalrep_read_tuple(StringInfo in, LogicalRepTupleData *tuple); @@ -305,7 +305,7 @@ logicalrep_write_truncate(StringInfo out, bool cascade, bool restart_seqs) { int i; - uint8 flags = 0; + uint8 flags = 0; pq_sendbyte(out, 'T'); /* action TRUNCATE */ @@ -332,7 +332,7 @@ logicalrep_read_truncate(StringInfo in, int i; int nrelids; List *relids = NIL; - uint8 flags; + uint8 flags; nrelids = pq_getmsgint(in, 4); @@ -453,7 +453,7 @@ logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple) for (i = 0; i < desc->natts; i++) { - if (TupleDescAttr(desc, i)->attisdropped) + if (TupleDescAttr(desc, i)->attisdropped || TupleDescAttr(desc, i)->attgenerated) continue; nliveatts++; } @@ -473,8 +473,7 @@ logicalrep_write_tuple(StringInfo out, Relation rel, HeapTuple tuple) Form_pg_attribute att = TupleDescAttr(desc, i); char *outputstr; - /* skip dropped columns */ - if (att->attisdropped) + if (att->attisdropped || att->attgenerated) continue; if (isnull[i]) @@ -573,7 +572,7 @@ logicalrep_write_attrs(StringInfo out, Relation rel) /* send number of live attributes */ for (i = 0; i < desc->natts; i++) { - if (TupleDescAttr(desc, i)->attisdropped) + if (TupleDescAttr(desc, i)->attisdropped || TupleDescAttr(desc, i)->attgenerated) continue; nliveatts++; } @@ -591,7 +590,7 @@ logicalrep_write_attrs(StringInfo out, Relation rel) Form_pg_attribute att = TupleDescAttr(desc, i); uint8 flags = 0; - if (att->attisdropped) + if (att->attisdropped || att->attgenerated) continue; /* REPLICA IDENTITY FULL means all columns are sent as part of key. */ diff --git a/src/backend/replication/logical/relation.c b/src/backend/replication/logical/relation.c index 1f20df5680e..85269c037de 100644 --- a/src/backend/replication/logical/relation.c +++ b/src/backend/replication/logical/relation.c @@ -2,7 +2,7 @@ * relation.c * PostgreSQL logical replication * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/relation.c @@ -16,8 +16,8 @@ #include "postgres.h" -#include "access/heapam.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/namespace.h" #include "catalog/pg_subscription_rel.h" #include "executor/executor.h" @@ -254,7 +254,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("logical replication target relation \"%s.%s\" does not exist", remoterel->nspname, remoterel->relname))); - entry->localrel = heap_open(relid, NoLock); + entry->localrel = table_open(relid, NoLock); /* Check for supported relkind. */ CheckSubscriptionRelkind(entry->localrel->rd_rel->relkind, @@ -276,7 +276,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) int attnum; Form_pg_attribute attr = TupleDescAttr(desc, i); - if (attr->attisdropped) + if (attr->attisdropped || attr->attgenerated) { entry->attrmap[i] = -1; continue; @@ -350,7 +350,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) entry->localreloid = relid; } else - entry->localrel = heap_open(entry->localreloid, lockmode); + entry->localrel = table_open(entry->localreloid, lockmode); if (entry->state != SUBREL_STATE_READY) entry->state = GetSubscriptionRelState(MySubscription->oid, @@ -367,7 +367,7 @@ logicalrep_rel_open(LogicalRepRelId remoteid, LOCKMODE lockmode) void logicalrep_rel_close(LogicalRepRelMapEntry *rel, LOCKMODE lockmode) { - heap_close(rel->localrel, lockmode); + table_close(rel->localrel, lockmode); rel->localrel = NULL; } @@ -425,7 +425,7 @@ logicalrep_typmap_gettypname(Oid remoteid) bool found; /* Internal types are mapped directly. */ - if (remoteid < FirstNormalObjectId) + if (remoteid < FirstGenbkiObjectId) { if (!get_typisdefined(remoteid)) { diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 596c91e9a95..8ce28ad6297 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -4,7 +4,7 @@ * PostgreSQL logical replay/reorder buffer management * * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -56,9 +56,10 @@ #include #include +#include "access/detoast.h" +#include "access/heapam.h" #include "access/rewriteheap.h" #include "access/transam.h" -#include "access/tuptoaster.h" #include "access/xact.h" #include "access/xlog_internal.h" #include "catalog/catalog.h" @@ -78,7 +79,6 @@ #include "utils/memutils.h" #include "utils/rel.h" #include "utils/relfilenodemap.h" -#include "utils/tqual.h" /* entry for a hash table we use to map from xid to our transaction state */ @@ -163,8 +163,10 @@ static const Size max_changes_in_memory = 4096; static ReorderBufferTXN *ReorderBufferGetTXN(ReorderBuffer *rb); static void ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn); static ReorderBufferTXN *ReorderBufferTXNByXid(ReorderBuffer *rb, - TransactionId xid, bool create, bool *is_new, - XLogRecPtr lsn, bool create_as_top); + TransactionId xid, bool create, bool *is_new, + XLogRecPtr lsn, bool create_as_top); +static void ReorderBufferTransferSnapToParent(ReorderBufferTXN *txn, + ReorderBufferTXN *subtxn); static void AssertTXNLsnOrder(ReorderBuffer *rb); @@ -179,7 +181,7 @@ static void AssertTXNLsnOrder(ReorderBuffer *rb); static ReorderBufferIterTXNState *ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn); static ReorderBufferChange *ReorderBufferIterTXNNext(ReorderBuffer *rb, ReorderBufferIterTXNState *state); static void ReorderBufferIterTXNFinish(ReorderBuffer *rb, - ReorderBufferIterTXNState *state); + ReorderBufferIterTXNState *state); static void ReorderBufferExecuteInvalidations(ReorderBuffer *rb, ReorderBufferTXN *txn); /* @@ -190,19 +192,19 @@ static void ReorderBufferExecuteInvalidations(ReorderBuffer *rb, ReorderBufferTX static void ReorderBufferCheckSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn); static void ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn); static void ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, - int fd, ReorderBufferChange *change); + int fd, ReorderBufferChange *change); static Size ReorderBufferRestoreChanges(ReorderBuffer *rb, ReorderBufferTXN *txn, - int *fd, XLogSegNo *segno); + int *fd, XLogSegNo *segno); static void ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, - char *change); + char *change); static void ReorderBufferRestoreCleanup(ReorderBuffer *rb, ReorderBufferTXN *txn); static void ReorderBufferCleanupSerializedTXNs(const char *slotname); static void ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, - TransactionId xid, XLogSegNo segno); + TransactionId xid, XLogSegNo segno); static void ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap); static Snapshot ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap, - ReorderBufferTXN *txn, CommandId cid); + ReorderBufferTXN *txn, CommandId cid); /* --------------------------------------- * toast reassembly support @@ -211,9 +213,9 @@ static Snapshot ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap, static void ReorderBufferToastInitHash(ReorderBuffer *rb, ReorderBufferTXN *txn); static void ReorderBufferToastReset(ReorderBuffer *rb, ReorderBufferTXN *txn); static void ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn, - Relation relation, ReorderBufferChange *change); + Relation relation, ReorderBufferChange *change); static void ReorderBufferToastAppendChunk(ReorderBuffer *rb, ReorderBufferTXN *txn, - Relation relation, ReorderBufferChange *change); + Relation relation, ReorderBufferChange *change); /* @@ -271,6 +273,7 @@ ReorderBufferAllocate(void) buffer->current_restart_decoding_lsn = InvalidXLogRecPtr; dlist_init(&buffer->toplevel_by_lsn); + dlist_init(&buffer->txns_by_base_snapshot_lsn); /* * Ensure there's no stale data from prior uses of this slot, in case some @@ -322,9 +325,6 @@ ReorderBufferGetTXN(ReorderBuffer *rb) /* * Free a ReorderBufferTXN. - * - * Deallocation might be delayed for efficiency purposes, for details check - * the comments above max_cached_changes's definition. */ static void ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) @@ -354,7 +354,7 @@ ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) } /* - * Get an unused, possibly preallocated, ReorderBufferChange. + * Get an fresh ReorderBufferChange. */ ReorderBufferChange * ReorderBufferGetChange(ReorderBuffer *rb) @@ -370,9 +370,6 @@ ReorderBufferGetChange(ReorderBuffer *rb) /* * Free an ReorderBufferChange. - * - * Deallocation might be delayed for efficiency purposes, for details check - * the comments above max_cached_changes's definition. */ void ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change) @@ -412,10 +409,16 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change) } break; /* no data in addition to the struct itself */ + case REORDER_BUFFER_CHANGE_TRUNCATE: + if (change->data.truncate.relids != NULL) + { + ReorderBufferReturnRelids(rb, change->data.truncate.relids); + change->data.truncate.relids = NULL; + } + break; case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: - case REORDER_BUFFER_CHANGE_TRUNCATE: break; } @@ -423,8 +426,8 @@ ReorderBufferReturnChange(ReorderBuffer *rb, ReorderBufferChange *change) } /* - * Get an unused, possibly preallocated, ReorderBufferTupleBuf fitting at - * least a tuple of size tuple_len (excluding header overhead). + * Get a fresh ReorderBufferTupleBuf fitting at least a tuple of size + * tuple_len (excluding header overhead). */ ReorderBufferTupleBuf * ReorderBufferGetTupleBuf(ReorderBuffer *rb, Size tuple_len) @@ -446,9 +449,6 @@ ReorderBufferGetTupleBuf(ReorderBuffer *rb, Size tuple_len) /* * Free an ReorderBufferTupleBuf. - * - * Deallocation might be delayed for efficiency purposes, for details check - * the comments above max_cached_changes's definition. */ void ReorderBufferReturnTupleBuf(ReorderBuffer *rb, ReorderBufferTupleBuf *tuple) @@ -456,6 +456,37 @@ ReorderBufferReturnTupleBuf(ReorderBuffer *rb, ReorderBufferTupleBuf *tuple) pfree(tuple); } +/* + * Get an array for relids of truncated relations. + * + * We use the global memory context (for the whole reorder buffer), because + * none of the existing ones seems like a good match (some are SLAB, so we + * can't use those, and tup_context is meant for tuple data, not relids). We + * could add yet another context, but it seems like an overkill - TRUNCATE is + * not particularly common operation, so it does not seem worth it. + */ +Oid * +ReorderBufferGetRelids(ReorderBuffer *rb, int nrelids) +{ + Oid *relids; + Size alloc_len; + + alloc_len = sizeof(Oid) * nrelids; + + relids = (Oid *) MemoryContextAlloc(rb->context, alloc_len); + + return relids; +} + +/* + * Free an array of relids. + */ +void +ReorderBufferReturnRelids(ReorderBuffer *rb, Oid *relids) +{ + pfree(relids); +} + /* * Return the ReorderBufferTXN from the given buffer, specified by Xid. * If create is true, and a transaction doesn't already exist, create it @@ -471,7 +502,6 @@ ReorderBufferTXNByXid(ReorderBuffer *rb, TransactionId xid, bool create, bool found; Assert(TransactionIdIsValid(xid)); - Assert(!create || lsn != InvalidXLogRecPtr); /* * Check the one-entry lookup cache first @@ -515,6 +545,7 @@ ReorderBufferTXNByXid(ReorderBuffer *rb, TransactionId xid, bool create, { /* initialize the new entry, if creation was requested */ Assert(ent != NULL); + Assert(lsn != InvalidXLogRecPtr); ent->txn = ReorderBufferGetTXN(rb); ent->txn->xid = xid; @@ -616,43 +647,80 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, } } - +/* + * AssertTXNLsnOrder + * Verify LSN ordering of transaction lists in the reorderbuffer + * + * Other LSN-related invariants are checked too. + * + * No-op if assertions are not in use. + */ static void AssertTXNLsnOrder(ReorderBuffer *rb) { #ifdef USE_ASSERT_CHECKING dlist_iter iter; XLogRecPtr prev_first_lsn = InvalidXLogRecPtr; + XLogRecPtr prev_base_snap_lsn = InvalidXLogRecPtr; dlist_foreach(iter, &rb->toplevel_by_lsn) { - ReorderBufferTXN *cur_txn; + ReorderBufferTXN *cur_txn = dlist_container(ReorderBufferTXN, node, + iter.cur); - cur_txn = dlist_container(ReorderBufferTXN, node, iter.cur); + /* start LSN must be set */ Assert(cur_txn->first_lsn != InvalidXLogRecPtr); + /* If there is an end LSN, it must be higher than start LSN */ if (cur_txn->end_lsn != InvalidXLogRecPtr) Assert(cur_txn->first_lsn <= cur_txn->end_lsn); + /* Current initial LSN must be strictly higher than previous */ if (prev_first_lsn != InvalidXLogRecPtr) Assert(prev_first_lsn < cur_txn->first_lsn); + /* known-as-subtxn txns must not be listed */ Assert(!cur_txn->is_known_as_subxact); + prev_first_lsn = cur_txn->first_lsn; } + + dlist_foreach(iter, &rb->txns_by_base_snapshot_lsn) + { + ReorderBufferTXN *cur_txn = dlist_container(ReorderBufferTXN, + base_snapshot_node, + iter.cur); + + /* base snapshot (and its LSN) must be set */ + Assert(cur_txn->base_snapshot != NULL); + Assert(cur_txn->base_snapshot_lsn != InvalidXLogRecPtr); + + /* current LSN must be strictly higher than previous */ + if (prev_base_snap_lsn != InvalidXLogRecPtr) + Assert(prev_base_snap_lsn < cur_txn->base_snapshot_lsn); + + /* known-as-subtxn txns must not be listed */ + Assert(!cur_txn->is_known_as_subxact); + + prev_base_snap_lsn = cur_txn->base_snapshot_lsn; + } #endif } +/* + * ReorderBufferGetOldestTXN + * Return oldest transaction in reorderbuffer + */ ReorderBufferTXN * ReorderBufferGetOldestTXN(ReorderBuffer *rb) { ReorderBufferTXN *txn; + AssertTXNLsnOrder(rb); + if (dlist_is_empty(&rb->toplevel_by_lsn)) return NULL; - AssertTXNLsnOrder(rb); - txn = dlist_head_element(ReorderBufferTXN, node, &rb->toplevel_by_lsn); Assert(!txn->is_known_as_subxact); @@ -660,12 +728,44 @@ ReorderBufferGetOldestTXN(ReorderBuffer *rb) return txn; } +/* + * ReorderBufferGetOldestXmin + * Return oldest Xmin in reorderbuffer + * + * Returns oldest possibly running Xid from the point of view of snapshots + * used in the transactions kept by reorderbuffer, or InvalidTransactionId if + * there are none. + * + * Since snapshots are assigned monotonically, this equals the Xmin of the + * base snapshot with minimal base_snapshot_lsn. + */ +TransactionId +ReorderBufferGetOldestXmin(ReorderBuffer *rb) +{ + ReorderBufferTXN *txn; + + AssertTXNLsnOrder(rb); + + if (dlist_is_empty(&rb->txns_by_base_snapshot_lsn)) + return InvalidTransactionId; + + txn = dlist_head_element(ReorderBufferTXN, base_snapshot_node, + &rb->txns_by_base_snapshot_lsn); + return txn->base_snapshot->xmin; +} + void ReorderBufferSetRestartPoint(ReorderBuffer *rb, XLogRecPtr ptr) { rb->current_restart_decoding_lsn = ptr; } +/* + * ReorderBufferAssignChild + * + * Make note that we know that subxid is a subtransaction of xid, seen as of + * the given lsn. + */ void ReorderBufferAssignChild(ReorderBuffer *rb, TransactionId xid, TransactionId subxid, XLogRecPtr lsn) @@ -678,32 +778,107 @@ ReorderBufferAssignChild(ReorderBuffer *rb, TransactionId xid, txn = ReorderBufferTXNByXid(rb, xid, true, &new_top, lsn, true); subtxn = ReorderBufferTXNByXid(rb, subxid, true, &new_sub, lsn, false); - if (new_sub) + if (new_top && !new_sub) + elog(ERROR, "subtransaction logged without previous top-level txn record"); + + if (!new_sub) { - /* - * we assign subtransactions to top level transaction even if we don't - * have data for it yet, assignment records frequently reference xids - * that have not yet produced any records. Knowing those aren't top - * level xids allows us to make processing cheaper in some places. - */ - dlist_push_tail(&txn->subtxns, &subtxn->node); - txn->nsubtxns++; + if (subtxn->is_known_as_subxact) + { + /* already associated, nothing to do */ + return; + } + else + { + /* + * We already saw this transaction, but initially added it to the + * list of top-level txns. Now that we know it's not top-level, + * remove it from there. + */ + dlist_delete(&subtxn->node); + } } - else if (!subtxn->is_known_as_subxact) - { - subtxn->is_known_as_subxact = true; - Assert(subtxn->nsubtxns == 0); - /* remove from lsn order list of top-level transactions */ - dlist_delete(&subtxn->node); + subtxn->is_known_as_subxact = true; + subtxn->toplevel_xid = xid; + Assert(subtxn->nsubtxns == 0); - /* add to toplevel transaction */ - dlist_push_tail(&txn->subtxns, &subtxn->node); - txn->nsubtxns++; - } - else if (new_top) + /* add to subtransaction list */ + dlist_push_tail(&txn->subtxns, &subtxn->node); + txn->nsubtxns++; + + /* Possibly transfer the subtxn's snapshot to its top-level txn. */ + ReorderBufferTransferSnapToParent(txn, subtxn); + + /* Verify LSN-ordering invariant */ + AssertTXNLsnOrder(rb); +} + +/* + * ReorderBufferTransferSnapToParent + * Transfer base snapshot from subtxn to top-level txn, if needed + * + * This is done if the top-level txn doesn't have a base snapshot, or if the + * subtxn's base snapshot has an earlier LSN than the top-level txn's base + * snapshot's LSN. This can happen if there are no changes in the toplevel + * txn but there are some in the subtxn, or the first change in subtxn has + * earlier LSN than first change in the top-level txn and we learned about + * their kinship only now. + * + * The subtransaction's snapshot is cleared regardless of the transfer + * happening, since it's not needed anymore in either case. + * + * We do this as soon as we become aware of their kinship, to avoid queueing + * extra snapshots to txns known-as-subtxns -- only top-level txns will + * receive further snapshots. + */ +static void +ReorderBufferTransferSnapToParent(ReorderBufferTXN *txn, + ReorderBufferTXN *subtxn) +{ + Assert(subtxn->toplevel_xid == txn->xid); + + if (subtxn->base_snapshot != NULL) { - elog(ERROR, "existing subxact assigned to unknown toplevel xact"); + if (txn->base_snapshot == NULL || + subtxn->base_snapshot_lsn < txn->base_snapshot_lsn) + { + /* + * If the toplevel transaction already has a base snapshot but + * it's newer than the subxact's, purge it. + */ + if (txn->base_snapshot != NULL) + { + SnapBuildSnapDecRefcount(txn->base_snapshot); + dlist_delete(&txn->base_snapshot_node); + } + + /* + * The snapshot is now the top transaction's; transfer it, and + * adjust the list position of the top transaction in the list by + * moving it to where the subtransaction is. + */ + txn->base_snapshot = subtxn->base_snapshot; + txn->base_snapshot_lsn = subtxn->base_snapshot_lsn; + dlist_insert_before(&subtxn->base_snapshot_node, + &txn->base_snapshot_node); + + /* + * The subtransaction doesn't have a snapshot anymore (so it + * mustn't be in the list.) + */ + subtxn->base_snapshot = NULL; + subtxn->base_snapshot_lsn = InvalidXLogRecPtr; + dlist_delete(&subtxn->base_snapshot_node); + } + else + { + /* Base snap of toplevel is fine, so subxact's is not needed */ + SnapBuildSnapDecRefcount(subtxn->base_snapshot); + dlist_delete(&subtxn->base_snapshot_node); + subtxn->base_snapshot = NULL; + subtxn->base_snapshot_lsn = InvalidXLogRecPtr; + } } } @@ -716,7 +891,6 @@ ReorderBufferCommitChild(ReorderBuffer *rb, TransactionId xid, TransactionId subxid, XLogRecPtr commit_lsn, XLogRecPtr end_lsn) { - ReorderBufferTXN *txn; ReorderBufferTXN *subtxn; subtxn = ReorderBufferTXNByXid(rb, subxid, false, NULL, @@ -728,42 +902,14 @@ ReorderBufferCommitChild(ReorderBuffer *rb, TransactionId xid, if (!subtxn) return; - txn = ReorderBufferTXNByXid(rb, xid, false, NULL, commit_lsn, true); - - if (txn == NULL) - elog(ERROR, "subxact logged without previous toplevel record"); - - /* - * Pass our base snapshot to the parent transaction if it doesn't have - * one, or ours is older. That can happen if there are no changes in the - * toplevel transaction but in one of the child transactions. This allows - * the parent to simply use its base snapshot initially. - */ - if (subtxn->base_snapshot != NULL && - (txn->base_snapshot == NULL || - txn->base_snapshot_lsn > subtxn->base_snapshot_lsn)) - { - txn->base_snapshot = subtxn->base_snapshot; - txn->base_snapshot_lsn = subtxn->base_snapshot_lsn; - subtxn->base_snapshot = NULL; - subtxn->base_snapshot_lsn = InvalidXLogRecPtr; - } - subtxn->final_lsn = commit_lsn; subtxn->end_lsn = end_lsn; - if (!subtxn->is_known_as_subxact) - { - subtxn->is_known_as_subxact = true; - Assert(subtxn->nsubtxns == 0); - - /* remove from lsn order list of top-level transactions */ - dlist_delete(&subtxn->node); - - /* add to subtransaction list */ - dlist_push_tail(&txn->subtxns, &subtxn->node); - txn->nsubtxns++; - } + /* + * Assign this subxact as a child of the toplevel xact (no-op if already + * done.) + */ + ReorderBufferAssignChild(rb, xid, subxid, InvalidXLogRecPtr); } @@ -1087,11 +1233,13 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) ReorderBufferReturnChange(rb, change); } + /* + * Cleanup the base snapshot, if set. + */ if (txn->base_snapshot != NULL) { SnapBuildSnapDecRefcount(txn->base_snapshot); - txn->base_snapshot = NULL; - txn->base_snapshot_lsn = InvalidXLogRecPtr; + dlist_delete(&txn->base_snapshot_node); } /* @@ -1121,7 +1269,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) /* * Build a hash with a (relfilenode, ctid) -> (cmin, cmax) mapping for use by - * tqual.c's HeapTupleSatisfiesHistoricMVCC. + * HeapTupleSatisfiesHistoricMVCC. */ static void ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn) @@ -1178,15 +1326,19 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn) } else { + /* + * Maybe we already saw this tuple before in this transaction, but + * if so it must have the same cmin. + */ Assert(ent->cmin == change->data.tuplecid.cmin); - Assert(ent->cmax == InvalidCommandId || - ent->cmax == change->data.tuplecid.cmax); /* - * if the tuple got valid in this transaction and now got deleted - * we already have a valid cmin stored. The cmax will be - * InvalidCommandId though. + * cmax may be initially invalid, but once set it can only grow, + * and never become invalid again. */ + Assert((ent->cmax == InvalidCommandId) || + ((change->data.tuplecid.cmax != InvalidCommandId) && + (change->data.tuplecid.cmax > ent->cmax))); ent->cmax = change->data.tuplecid.cmax; } } @@ -1229,7 +1381,7 @@ ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap, snap->subxip[i++] = txn->xid; /* - * nsubxcnt isn't decreased when subtransactions abort, so count manually. + * subxcnt isn't decreased when subtransactions abort, so count manually. * Since it's an upper boundary it is safe to use it for the allocation * above. */ @@ -1266,17 +1418,17 @@ ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap) } /* - * Perform the replay of a transaction and it's non-aborted subtransactions. + * Perform the replay of a transaction and its non-aborted subtransactions. * * Subtransactions previously have to be processed by * ReorderBufferCommitChild(), even if previously assigned to the toplevel * transaction with ReorderBufferAssignChild. * - * We currently can only decode a transaction's contents in when their commit - * record is read because that's currently the only place where we know about - * cache invalidations. Thus, once a toplevel commit is read, we iterate over - * the top and subtransactions (using a k-way merge) and replay the changes in - * lsn order. + * We currently can only decode a transaction's contents when its commit + * record is read because that's the only place where we know about cache + * invalidations. Thus, once a toplevel commit is read, we iterate over the top + * and subtransactions (using a k-way merge) and replay the changes in lsn + * order. */ void ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, @@ -1304,10 +1456,10 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, txn->origin_lsn = origin_lsn; /* - * If this transaction didn't have any real changes in our database, it's - * OK not to have a snapshot. Note that ReorderBufferCommitChild will have - * transferred its snapshot to this transaction if it had one and the - * toplevel tx didn't. + * If this transaction has no snapshot, it didn't make any changes to the + * database, so there's nothing to decode. Note that + * ReorderBufferCommitChild will have transferred any snapshots from + * subtransactions if there were any. */ if (txn->base_snapshot == NULL) { @@ -1363,6 +1515,8 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, * use as a normal record. It'll be cleaned up at the end * of INSERT processing. */ + if (specinsert == NULL) + elog(ERROR, "invalid ordering of speculative insertion changes"); Assert(specinsert->data.tp.oldtuple == NULL); change = specinsert; change->action = REORDER_BUFFER_CHANGE_INSERT; @@ -1377,8 +1531,16 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, change->data.tp.relnode.relNode); /* - * Catalog tuple without data, emitted while catalog was - * in the process of being rewritten. + * Mapped catalog tuple without data, emitted while + * catalog table was in the process of being rewritten. We + * can fail to look up the relfilenode, because the + * relmapper has no "historic" view, in contrast to normal + * the normal catalog during decoding. Thus repeated + * rewrites can cause a lookup failure. That's OK because + * we do not decode catalog changes anyway. Normally such + * tuples would be skipped over below, but we can't + * identify whether the table should be logically logged + * without mapping the relfilenode to the oid. */ if (reloid == InvalidOid && change->data.tp.newtuple == NULL && @@ -1391,7 +1553,7 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, relation = RelationIdGetRelation(reloid); - if (relation == NULL) + if (!RelationIsValid(relation)) elog(ERROR, "could not open relation with OID %u (for filenode \"%s\")", reloid, relpathperm(change->data.tp.relnode, @@ -1441,6 +1603,8 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, * freed/reused while restoring spooled data from * disk. */ + Assert(change->data.tp.newtuple != NULL); + dlist_delete(&change->node); ReorderBufferToastAppendChunk(rb, txn, relation, change); @@ -1493,36 +1657,36 @@ ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid, break; case REORDER_BUFFER_CHANGE_TRUNCATE: - { - int i; - int nrelids = change->data.truncate.nrelids; - int nrelations = 0; - Relation *relations; - - relations = palloc0(nrelids * sizeof(Relation)); - for (i = 0; i < nrelids; i++) { - Oid relid = change->data.truncate.relids[i]; - Relation relation; + int i; + int nrelids = change->data.truncate.nrelids; + int nrelations = 0; + Relation *relations; - relation = RelationIdGetRelation(relid); + relations = palloc0(nrelids * sizeof(Relation)); + for (i = 0; i < nrelids; i++) + { + Oid relid = change->data.truncate.relids[i]; + Relation relation; - if (relation == NULL) - elog(ERROR, "could not open relation with OID %u", relid); + relation = RelationIdGetRelation(relid); - if (!RelationIsLogicallyLogged(relation)) - continue; + if (!RelationIsValid(relation)) + elog(ERROR, "could not open relation with OID %u", relid); - relations[nrelations++] = relation; - } + if (!RelationIsLogicallyLogged(relation)) + continue; - rb->apply_truncate(rb, txn, nrelations, relations, change); + relations[nrelations++] = relation; + } - for (i = 0; i < nrelations; i++) - RelationClose(relations[i]); + rb->apply_truncate(rb, txn, nrelations, relations, change); - break; - } + for (i = 0; i < nrelations; i++) + RelationClose(relations[i]); + + break; + } case REORDER_BUFFER_CHANGE_MESSAGE: rb->message(rb, txn, change->lsn, true, @@ -1744,7 +1908,7 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid) if (txn->serialized && txn->final_lsn == 0) { ReorderBufferChange *last = - dlist_tail_element(ReorderBufferChange, node, &txn->changes); + dlist_tail_element(ReorderBufferChange, node, &txn->changes); txn->final_lsn = last->lsn; } @@ -1760,7 +1924,7 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid) } /* - * Forget the contents of a transaction if we aren't interested in it's + * Forget the contents of a transaction if we aren't interested in its * contents. Needs to be first called for subtransactions and then for the * toplevel xid. * @@ -1870,12 +2034,10 @@ ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid, } /* - * Setup the base snapshot of a transaction. The base snapshot is the snapshot - * that is used to decode all changes until either this transaction modifies - * the catalog or another catalog modifying transaction commits. + * Set up the transaction's base snapshot. * - * Needs to be called before any changes are added with - * ReorderBufferQueueChange(). + * If we know that xid is a subtransaction, set the base snapshot on the + * top-level transaction instead. */ void ReorderBufferSetBaseSnapshot(ReorderBuffer *rb, TransactionId xid, @@ -1884,12 +2046,23 @@ ReorderBufferSetBaseSnapshot(ReorderBuffer *rb, TransactionId xid, ReorderBufferTXN *txn; bool is_new; + AssertArg(snap != NULL); + + /* + * Fetch the transaction to operate on. If we know it's a subtransaction, + * operate on its top-level transaction instead. + */ txn = ReorderBufferTXNByXid(rb, xid, true, &is_new, lsn, true); + if (txn->is_known_as_subxact) + txn = ReorderBufferTXNByXid(rb, txn->toplevel_xid, false, + NULL, InvalidXLogRecPtr, false); Assert(txn->base_snapshot == NULL); - Assert(snap != NULL); txn->base_snapshot = snap; txn->base_snapshot_lsn = lsn; + dlist_push_tail(&rb->txns_by_base_snapshot_lsn, &txn->base_snapshot_node); + + AssertTXNLsnOrder(rb); } /* @@ -2008,25 +2181,26 @@ ReorderBufferXidHasCatalogChanges(ReorderBuffer *rb, TransactionId xid) } /* - * Have we already added the first snapshot? + * ReorderBufferXidHasBaseSnapshot + * Have we already set the base snapshot for the given txn/subtxn? */ bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *rb, TransactionId xid) { ReorderBufferTXN *txn; - txn = ReorderBufferTXNByXid(rb, xid, false, NULL, InvalidXLogRecPtr, - false); + txn = ReorderBufferTXNByXid(rb, xid, false, + NULL, InvalidXLogRecPtr, false); /* transaction isn't known yet, ergo no snapshot */ if (txn == NULL) return false; - /* - * TODO: It would be a nice improvement if we would check the toplevel - * transaction in subtransactions, but we'd need to keep track of a bit - * more state. - */ + /* a known subtxn? operate on top-level txn instead */ + if (txn->is_known_as_subxact) + txn = ReorderBufferTXNByXid(rb, txn->toplevel_xid, false, + NULL, InvalidXLogRecPtr, false); + return txn->base_snapshot != NULL; } @@ -2289,6 +2463,26 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, break; } case REORDER_BUFFER_CHANGE_TRUNCATE: + { + Size size; + char *data; + + /* account for the OIDs of truncated relations */ + size = sizeof(Oid) * change->data.truncate.nrelids; + sz += size; + + /* make sure we have enough space */ + ReorderBufferSerializeReserve(rb, sz); + + data = ((char *) rb->outbuf) + sizeof(ReorderBufferDiskChange); + /* might have been reallocated above */ + ondisk = (ReorderBufferDiskChange *) rb->outbuf; + + memcpy(data, change->data.truncate.relids, size); + data += size; + + break; + } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: @@ -2298,13 +2492,16 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn, ondisk->size = sz; + errno = 0; pgstat_report_wait_start(WAIT_EVENT_REORDER_BUFFER_WRITE); if (write(fd, rb->outbuf, ondisk->size) != ondisk->size) { int save_errno = errno; CloseTransientFile(fd); - errno = save_errno; + + /* if write didn't set errno, assume problem is no disk space */ + errno = save_errno ? save_errno : ENOSPC; ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to data file for XID %u: %m", @@ -2569,6 +2766,16 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn, } /* the base struct contains all the data, easy peasy */ case REORDER_BUFFER_CHANGE_TRUNCATE: + { + Oid *relids; + + relids = ReorderBufferGetRelids(rb, + change->data.truncate.nrelids); + memcpy(relids, data, change->data.truncate.nrelids * sizeof(Oid)); + change->data.truncate.relids = relids; + + break; + } case REORDER_BUFFER_CHANGE_INTERNAL_SPEC_CONFIRM: case REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID: case REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID: @@ -2639,7 +2846,7 @@ ReorderBufferCleanupSerializedTXNs(const char *slotname) if (unlink(path) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not remove file \"%s\" during removal of pg_replslot/%s/*.xid: %m", + errmsg("could not remove file \"%s\" during removal of pg_replslot/%s/xid*: %m", path, slotname))); } } @@ -2657,12 +2864,12 @@ ReorderBufferSerializedPath(char *path, ReplicationSlot *slot, TransactionId xid { XLogRecPtr recptr; - XLogSegNoOffsetToRecPtr(segno, 0, recptr, wal_segment_size); + XLogSegNoOffsetToRecPtr(segno, 0, wal_segment_size, recptr); - snprintf(path, MAXPGPATH, "pg_replslot/%s/xid-%u-lsn-%X-%X.snap", - NameStr(MyReplicationSlot->data.name), - xid, - (uint32) (recptr >> 32), (uint32) recptr); + snprintf(path, MAXPGPATH, "pg_replslot/%s/xid-%u-lsn-%X-%X.spill", + NameStr(MyReplicationSlot->data.name), + xid, + (uint32) (recptr >> 32), (uint32) recptr); } /* @@ -2824,6 +3031,10 @@ ReorderBufferToastReplace(ReorderBuffer *rb, ReorderBufferTXN *txn, desc = RelationGetDescr(relation); toast_rel = RelationIdGetRelation(relation->rd_rel->reltoastrelid); + if (!RelationIsValid(toast_rel)) + elog(ERROR, "could not open relation with OID %u", + relation->rd_rel->reltoastrelid); + toast_desc = RelationGetDescr(toast_rel); /* should we allocate from stack instead? */ @@ -3029,7 +3240,7 @@ ReorderBufferToastReset(ReorderBuffer *rb, ReorderBufferTXN *txn) * ------------------------------------------------------------------------- */ -/* struct for qsort()ing mapping files by lsn somewhat efficiently */ +/* struct for sorting mapping files by LSN efficiently */ typedef struct RewriteMappingFile { XLogRecPtr lsn; @@ -3152,11 +3363,16 @@ ApplyLogicalMappingFile(HTAB *tuplecid_data, Oid relid, const char *fname) new_ent->combocid = ent->combocid; } } + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); } /* - * Check whether the TransactionOId 'xid' is in the pre-sorted array 'xip'. + * Check whether the TransactionId 'xid' is in the pre-sorted array 'xip'. */ static bool TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) @@ -3166,13 +3382,13 @@ TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num) } /* - * qsort() comparator for sorting RewriteMappingFiles in LSN order. + * list_sort() comparator for sorting RewriteMappingFiles in LSN order. */ static int -file_sort_by_lsn(const void *a_p, const void *b_p) +file_sort_by_lsn(const ListCell *a_p, const ListCell *b_p) { - RewriteMappingFile *a = *(RewriteMappingFile **) a_p; - RewriteMappingFile *b = *(RewriteMappingFile **) b_p; + RewriteMappingFile *a = (RewriteMappingFile *) lfirst(a_p); + RewriteMappingFile *b = (RewriteMappingFile *) lfirst(b_p); if (a->lsn < b->lsn) return -1; @@ -3192,8 +3408,6 @@ UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot) struct dirent *mapping_de; List *files = NIL; ListCell *file; - RewriteMappingFile **files_a; - size_t off; Oid dboid = IsSharedRelation(relid) ? InvalidOid : MyDatabaseId; mapping_dir = AllocateDir("pg_logical/mappings"); @@ -3247,21 +3461,12 @@ UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot) } FreeDir(mapping_dir); - /* build array we can easily sort */ - files_a = palloc(list_length(files) * sizeof(RewriteMappingFile *)); - off = 0; - foreach(file, files) - { - files_a[off++] = lfirst(file); - } - /* sort files so we apply them in LSN order */ - qsort(files_a, list_length(files), sizeof(RewriteMappingFile *), - file_sort_by_lsn); + list_sort(files, file_sort_by_lsn); - for (off = 0; off < list_length(files); off++) + foreach(file, files) { - RewriteMappingFile *f = files_a[off]; + RewriteMappingFile *f = (RewriteMappingFile *) lfirst(file); elog(DEBUG1, "applying mapping: \"%s\" in %u", f->fname, snapshot->subxip[0]); diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 4123cdebcfd..0bd1d0f9545 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -107,7 +107,7 @@ * is a convenient point to initialize replication from, which is why we * export a snapshot at that point, which *can* be used to read normal data. * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/snapbuild.c @@ -136,7 +136,6 @@ #include "utils/memutils.h" #include "utils/snapshot.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" #include "storage/block.h" /* debugging output */ #include "storage/fd.h" @@ -270,7 +269,7 @@ static void SnapBuildSnapIncRefcount(Snapshot snap); static void SnapBuildDistributeNewCatalogSnapshot(SnapBuild *builder, XLogRecPtr lsn); -/* xlog reading helper functions for SnapBuildProcessRecord */ +/* xlog reading helper functions for SnapBuildProcessRunningXacts */ static bool SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *running); static void SnapBuildWaitSnapshot(xl_running_xacts *running, TransactionId cutoff); @@ -376,7 +375,7 @@ static void SnapBuildFreeSnapshot(Snapshot snap) { /* make sure we don't get passed an external snapshot */ - Assert(snap->satisfies == HeapTupleSatisfiesHistoricMVCC); + Assert(snap->snapshot_type == SNAPSHOT_HISTORIC_MVCC); /* make sure nobody modified our snapshot */ Assert(snap->curcid == FirstCommandId); @@ -434,7 +433,7 @@ void SnapBuildSnapDecRefcount(Snapshot snap) { /* make sure we don't get passed an external snapshot */ - Assert(snap->satisfies == HeapTupleSatisfiesHistoricMVCC); + Assert(snap->snapshot_type == SNAPSHOT_HISTORIC_MVCC); /* make sure nobody modified our snapshot */ Assert(snap->curcid == FirstCommandId); @@ -476,7 +475,7 @@ SnapBuildBuildSnapshot(SnapBuild *builder) snapshot = MemoryContextAllocZero(builder->context, ssize); - snapshot->satisfies = HeapTupleSatisfiesHistoricMVCC; + snapshot->snapshot_type = SNAPSHOT_HISTORIC_MVCC; /* * We misuse the original meaning of SnapshotData's xip and subxip fields @@ -617,6 +616,8 @@ SnapBuildInitialSnapshot(SnapBuild *builder) TransactionIdAdvance(xid); } + /* adjust remaining snapshot fields as needed */ + snap->snapshot_type = SNAPSHOT_MVCC; snap->xcnt = newxcnt; snap->xip = newxip; @@ -830,9 +831,9 @@ SnapBuildDistributeNewCatalogSnapshot(SnapBuild *builder, XLogRecPtr lsn) * all. We'll add a snapshot when the first change gets queued. * * NB: This works correctly even for subtransactions because - * ReorderBufferCommitChild() takes care to pass the parent the base - * snapshot, and while iterating the changequeue we'll get the change - * from the subtxn. + * ReorderBufferAssignChild() takes care to transfer the base snapshot + * to the top-level transaction, and while iterating the changequeue + * we'll get the change from the subtxn. */ if (!ReorderBufferXidHasBaseSnapshot(builder->reorder, txn->xid)) continue; @@ -1074,7 +1075,7 @@ SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, TransactionId xid, /* refcount of the snapshot builder for the new snapshot */ SnapBuildSnapIncRefcount(builder->snapshot); - /* add a new Snapshot to all currently running transactions */ + /* add a new catalog snapshot to all currently running transactions */ SnapBuildDistributeNewCatalogSnapshot(builder, lsn); } } @@ -1094,6 +1095,7 @@ void SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *running) { ReorderBufferTXN *txn; + TransactionId xmin; /* * If we're not consistent yet, inspect the record to see whether it @@ -1119,22 +1121,28 @@ SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, xl_running_xact * NB: We only increase xmax when a catalog modifying transaction commits * (see SnapBuildCommitTxn). Because of this, xmax can be lower than * xmin, which looks odd but is correct and actually more efficient, since - * we hit fast paths in tqual.c. + * we hit fast paths in heapam_visibility.c. */ builder->xmin = running->oldestRunningXid; /* Remove transactions we don't need to keep track off anymore */ SnapBuildPurgeCommittedTxn(builder); - elog(DEBUG3, "xmin: %u, xmax: %u, oldestrunning: %u", - builder->xmin, builder->xmax, - running->oldestRunningXid); - /* - * Increase shared memory limits, so vacuum can work on tuples we - * prevented from being pruned till now. + * Advance the xmin limit for the current replication slot, to allow + * vacuum to clean up the tuples this slot has been protecting. + * + * The reorderbuffer might have an xmin among the currently running + * snapshots; use it if so. If not, we need only consider the snapshots + * we'll produce later, which can't be less than the oldest running xid in + * the record we're reading now. */ - LogicalIncreaseXminForSlot(lsn, running->oldestRunningXid); + xmin = ReorderBufferGetOldestXmin(builder->reorder); + if (xmin == InvalidTransactionId) + xmin = running->oldestRunningXid; + elog(DEBUG3, "xmin: %u, xmax: %u, oldest running: %u, oldest xmin: %u", + builder->xmin, builder->xmax, running->oldestRunningXid, xmin); + LogicalIncreaseXminForSlot(lsn, xmin); /* * Also tell the slot where we can restart decoding from. We don't want to @@ -1515,7 +1523,8 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) if (ret != 0 && errno != ENOENT) ereport(ERROR, - (errmsg("could not stat file \"%s\": %m", path))); + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", path))); else if (ret == 0) { @@ -1557,7 +1566,7 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) if (unlink(tmppath) != 0 && errno != ENOENT) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not remove file \"%s\": %m", path))); + errmsg("could not remove file \"%s\": %m", tmppath))); needed_length = sizeof(SnapBuildOnDisk) + sizeof(TransactionId) * builder->committed.xcnt; @@ -1600,12 +1609,19 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) O_CREAT | O_EXCL | O_WRONLY | PG_BINARY); if (fd < 0) ereport(ERROR, - (errmsg("could not open file \"%s\": %m", path))); + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", tmppath))); + errno = 0; pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_WRITE); if ((write(fd, ondisk, needed_length)) != needed_length) { + int save_errno = errno; + CloseTransientFile(fd); + + /* if write didn't set errno, assume problem is no disk space */ + errno = save_errno ? save_errno : ENOSPC; ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", tmppath))); @@ -1616,6 +1632,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) * fsync the file before renaming so that even if we crash after this we * have either a fully valid file or nothing. * + * It's safe to just ERROR on fsync() here because we'll retry the whole + * operation including the writes. + * * TODO: Do the fsync() via checkpoints/restartpoints, doing it here has * some noticeable overhead since it's performed synchronously during * decoding? @@ -1623,13 +1642,20 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) pgstat_report_wait_start(WAIT_EVENT_SNAPBUILD_SYNC); if (pg_fsync(fd) != 0) { + int save_errno = errno; + CloseTransientFile(fd); + errno = save_errno; ereport(ERROR, (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", tmppath))); } pgstat_report_wait_end(); - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", tmppath))); fsync_fname("pg_logical/snapshots", true); @@ -1708,21 +1734,35 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) pgstat_report_wait_end(); if (readBytes != SnapBuildOnDiskConstantSize) { + int save_errno = errno; + CloseTransientFile(fd); - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %d: %m", - path, readBytes, (int) SnapBuildOnDiskConstantSize))); + + if (readBytes < 0) + { + errno = save_errno; + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, + (Size) SnapBuildOnDiskConstantSize))); } if (ondisk.magic != SNAPBUILD_MAGIC) ereport(ERROR, - (errmsg("snapbuild state file \"%s\" has wrong magic number: %u instead of %u", + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("snapbuild state file \"%s\" has wrong magic number: %u instead of %u", path, ondisk.magic, SNAPBUILD_MAGIC))); if (ondisk.version != SNAPBUILD_VERSION) ereport(ERROR, - (errmsg("snapbuild state file \"%s\" has unsupported version: %u instead of %u", + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("snapbuild state file \"%s\" has unsupported version: %u instead of %u", path, ondisk.version, SNAPBUILD_VERSION))); INIT_CRC32C(checksum); @@ -1736,11 +1776,22 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) pgstat_report_wait_end(); if (readBytes != sizeof(SnapBuild)) { + int save_errno = errno; + CloseTransientFile(fd); - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %d: %m", - path, readBytes, (int) sizeof(SnapBuild)))); + + if (readBytes < 0) + { + errno = save_errno; + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, sizeof(SnapBuild)))); } COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild)); @@ -1753,11 +1804,22 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) pgstat_report_wait_end(); if (readBytes != sz) { + int save_errno = errno; + CloseTransientFile(fd); - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %d: %m", - path, readBytes, (int) sz))); + + if (readBytes < 0) + { + errno = save_errno; + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, sz))); } COMP_CRC32C(checksum, ondisk.builder.was_running.was_xip, sz); @@ -1769,22 +1831,36 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) pgstat_report_wait_end(); if (readBytes != sz) { + int save_errno = errno; + CloseTransientFile(fd); - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %d: %m", - path, readBytes, (int) sz))); + + if (readBytes < 0) + { + errno = save_errno; + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + } + else + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, sz))); } COMP_CRC32C(checksum, ondisk.builder.committed.xip, sz); - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); FIN_CRC32C(checksum); /* verify checksum of what we've read */ if (!EQ_CRC32C(checksum, ondisk.checksum)) ereport(ERROR, - (errcode_for_file_access(), + (errcode(ERRCODE_DATA_CORRUPTED), errmsg("checksum mismatch for snapbuild state file \"%s\": is %u, should be %u", path, checksum, ondisk.checksum))); diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c index acc6498567d..7881079e96b 100644 --- a/src/backend/replication/logical/tablesync.c +++ b/src/backend/replication/logical/tablesync.c @@ -2,7 +2,7 @@ * tablesync.c * PostgreSQL logical replication * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/tablesync.c @@ -88,6 +88,7 @@ #include "miscadmin.h" #include "pgstat.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/pg_subscription_rel.h" @@ -159,7 +160,6 @@ finish_sync_worker(void) static bool wait_for_relation_state_change(Oid relid, char expected_state) { - int rc; char state; for (;;) @@ -192,13 +192,9 @@ wait_for_relation_state_change(Oid relid, char expected_state) if (!worker) return false; - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - 1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE); - - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + 1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE); ResetLatch(MyLatch); } @@ -250,13 +246,9 @@ wait_for_worker_state_change(char expected_state) * but use a timeout in case it dies without sending one. */ rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, 1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) ResetLatch(MyLatch); } @@ -593,7 +585,6 @@ copy_read_data(void *outbuf, int minread, int maxread) while (maxread > 0 && bytesread < minread) { pgsocket fd = PGINVALID_SOCKET; - int rc; int len; char *buf = NULL; @@ -632,14 +623,10 @@ copy_read_data(void *outbuf, int minread, int maxread) /* * Wait for more data or latch. */ - rc = WaitLatchOrSocket(MyLatch, - WL_SOCKET_READABLE | WL_LATCH_SET | - WL_TIMEOUT | WL_POSTMASTER_DEATH, - fd, 1000L, WAIT_EVENT_LOGICAL_SYNC_DATA); - - /* Emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); + (void) WaitLatchOrSocket(MyLatch, + WL_SOCKET_READABLE | WL_LATCH_SET | + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + fd, 1000L, WAIT_EVENT_LOGICAL_SYNC_DATA); ResetLatch(MyLatch); } @@ -685,7 +672,7 @@ fetch_remote_table_info(char *nspname, char *relname, (errmsg("could not fetch table info for table \"%s.%s\" from publisher: %s", nspname, relname, res->err))); - slot = MakeSingleTupleTableSlot(res->tupledesc); + slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); if (!tuplestore_gettupleslot(res->tuplestore, true, false, slot)) ereport(ERROR, (errmsg("table \"%s.%s\" not found on publisher", @@ -710,10 +697,12 @@ fetch_remote_table_info(char *nspname, char *relname, " LEFT JOIN pg_catalog.pg_index i" " ON (i.indexrelid = pg_get_replica_identity_index(%u))" " WHERE a.attnum > 0::pg_catalog.int2" - " AND NOT a.attisdropped" + " AND NOT a.attisdropped %s" " AND a.attrelid = %u" " ORDER BY a.attnum", - lrel->remoteid, lrel->remoteid); + lrel->remoteid, + (walrcv_server_version(wrconn) >= 120000 ? "AND a.attgenerated = ''" : ""), + lrel->remoteid); res = walrcv_exec(wrconn, cmd.data, 4, attrRow); if (res->status != WALRCV_OK_TUPLES) @@ -727,7 +716,7 @@ fetch_remote_table_info(char *nspname, char *relname, lrel->attkeys = NULL; natt = 0; - slot = MakeSingleTupleTableSlot(res->tupledesc); + slot = MakeSingleTupleTableSlot(res->tupledesc, &TTSOpsMinimalTuple); while (tuplestore_gettupleslot(res->tuplestore, true, false, slot)) { lrel->attnames[natt] = @@ -795,7 +784,8 @@ copy_table(Relation rel) copybuf = makeStringInfo(); pstate = make_parsestate(NULL); - addRangeTableEntryForRelation(pstate, rel, NULL, false, false); + addRangeTableEntryForRelation(pstate, rel, AccessShareLock, + NULL, false, false); attnamelist = make_copy_attnamelist(relmapentry); cstate = BeginCopyFrom(pstate, rel, NULL, false, copy_read_data, attnamelist, NIL); @@ -889,7 +879,7 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) * working and it has to open the relation in RowExclusiveLock * when remapping remote relation id to local one. */ - rel = heap_open(MyLogicalRepWorker->relid, RowExclusiveLock); + rel = table_open(MyLogicalRepWorker->relid, RowExclusiveLock); /* * Create a temporary slot for the sync process. We do this @@ -927,7 +917,7 @@ LogicalRepSyncTableStart(XLogRecPtr *origin_startpos) errdetail("The error was: %s", res->err))); walrcv_clear_result(res); - heap_close(rel, NoLock); + table_close(rel, NoLock); /* Make the copy visible. */ CommandCounterIncrement(); diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c index aa7e27179e8..11e6331f494 100644 --- a/src/backend/replication/logical/worker.c +++ b/src/backend/replication/logical/worker.c @@ -2,7 +2,7 @@ * worker.c * PostgreSQL logical replication worker (apply) * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/logical/worker.c @@ -23,60 +23,47 @@ #include "postgres.h" -#include "miscadmin.h" -#include "pgstat.h" -#include "funcapi.h" - +#include "access/table.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog_internal.h" - #include "catalog/catalog.h" #include "catalog/namespace.h" #include "catalog/pg_subscription.h" #include "catalog/pg_subscription_rel.h" - #include "commands/tablecmds.h" #include "commands/trigger.h" - #include "executor/executor.h" #include "executor/nodeModifyTable.h" - +#include "funcapi.h" #include "libpq/pqformat.h" #include "libpq/pqsignal.h" - #include "mb/pg_wchar.h" - +#include "miscadmin.h" #include "nodes/makefuncs.h" - -#include "optimizer/planner.h" - +#include "optimizer/optimizer.h" #include "parser/parse_relation.h" - +#include "pgstat.h" #include "postmaster/bgworker.h" #include "postmaster/postmaster.h" #include "postmaster/walwriter.h" - #include "replication/decode.h" #include "replication/logical.h" #include "replication/logicalproto.h" #include "replication/logicalrelation.h" #include "replication/logicalworker.h" -#include "replication/reorderbuffer.h" #include "replication/origin.h" +#include "replication/reorderbuffer.h" #include "replication/snapbuild.h" #include "replication/walreceiver.h" #include "replication/worker_internal.h" - #include "rewrite/rewriteHandler.h" - #include "storage/bufmgr.h" #include "storage/ipc.h" #include "storage/lmgr.h" #include "storage/proc.h" #include "storage/procarray.h" - #include "tcop/tcopprot.h" - #include "utils/builtins.h" #include "utils/catcache.h" #include "utils/datum.h" @@ -86,9 +73,8 @@ #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" -#include "utils/timeout.h" -#include "utils/tqual.h" #include "utils/syscache.h" +#include "utils/timeout.h" #define NAPTIME_PER_CYCLE 1000 /* max sleep time between cycles (1s) */ @@ -199,7 +185,8 @@ create_estate_for_relation(LogicalRepRelMapEntry *rel) rte->rtekind = RTE_RELATION; rte->relid = RelationGetRelid(rel->localrel); rte->relkind = rel->localrel->rd_rel->relkind; - estate->es_range_table = list_make1(rte); + rte->rellockmode = AccessShareLock; + ExecInitRangeTable(estate, list_make1(rte)); resultRelInfo = makeNode(ResultRelInfo); InitResultRelInfo(resultRelInfo, rel->localrel, 1, NULL, 0); @@ -210,10 +197,6 @@ create_estate_for_relation(LogicalRepRelMapEntry *rel) estate->es_output_cid = GetCurrentCommandId(true); - /* Triggers might need a slot */ - if (resultRelInfo->ri_TrigDesc) - estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate, NULL); - /* Prepare to catch AFTER triggers. */ AfterTriggerBeginQuery(); @@ -253,7 +236,7 @@ slot_fill_defaults(LogicalRepRelMapEntry *rel, EState *estate, { Expr *defexpr; - if (TupleDescAttr(desc, attnum)->attisdropped) + if (TupleDescAttr(desc, attnum)->attisdropped || TupleDescAttr(desc, attnum)->attgenerated) continue; if (rel->attrmap[attnum] >= 0) @@ -608,7 +591,11 @@ apply_handle_insert(StringInfo s) /* Initialize the executor state. */ estate = create_estate_for_relation(rel); remoteslot = ExecInitExtraTupleSlot(estate, - RelationGetDescr(rel->localrel)); + RelationGetDescr(rel->localrel), + &TTSOpsVirtual); + + /* Input functions may need an active snapshot, so get one */ + PushActiveSnapshot(GetTransactionSnapshot()); /* Process and store remote tuple in the slot */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); @@ -616,7 +603,6 @@ apply_handle_insert(StringInfo s) slot_fill_defaults(rel, estate, remoteslot); MemoryContextSwitchTo(oldctx); - PushActiveSnapshot(GetTransactionSnapshot()); ExecOpenIndices(estate->es_result_relation_info, false); /* Do the insert. */ @@ -712,9 +698,10 @@ apply_handle_update(StringInfo s) /* Initialize the executor state. */ estate = create_estate_for_relation(rel); remoteslot = ExecInitExtraTupleSlot(estate, - RelationGetDescr(rel->localrel)); - localslot = ExecInitExtraTupleSlot(estate, - RelationGetDescr(rel->localrel)); + RelationGetDescr(rel->localrel), + &TTSOpsVirtual); + localslot = table_slot_create(rel->localrel, + &estate->es_tupleTable); EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1); PushActiveSnapshot(GetTransactionSnapshot()); @@ -753,7 +740,7 @@ apply_handle_update(StringInfo s) { /* Process and store remote tuple in the slot */ oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate)); - ExecStoreTuple(localslot->tts_tuple, remoteslot, InvalidBuffer, false); + ExecCopySlot(remoteslot, localslot); slot_modify_cstrings(remoteslot, rel, newtup.values, newtup.changed); MemoryContextSwitchTo(oldctx); @@ -830,9 +817,10 @@ apply_handle_delete(StringInfo s) /* Initialize the executor state. */ estate = create_estate_for_relation(rel); remoteslot = ExecInitExtraTupleSlot(estate, - RelationGetDescr(rel->localrel)); - localslot = ExecInitExtraTupleSlot(estate, - RelationGetDescr(rel->localrel)); + RelationGetDescr(rel->localrel), + &TTSOpsVirtual); + localslot = table_slot_create(rel->localrel, + &estate->es_tupleTable); EvalPlanQualInit(&epqstate, estate, NULL, NIL, -1); PushActiveSnapshot(GetTransactionSnapshot()); @@ -869,10 +857,10 @@ apply_handle_delete(StringInfo s) else { /* The tuple to be deleted could not be found. */ - ereport(DEBUG1, - (errmsg("logical replication could not find row for delete " - "in replication target relation \"%s\"", - RelationGetRelationName(rel->localrel)))); + elog(DEBUG1, + "logical replication could not find row for delete " + "in replication target relation \"%s\"", + RelationGetRelationName(rel->localrel)); } /* Cleanup. */ @@ -899,14 +887,14 @@ apply_handle_delete(StringInfo s) static void apply_handle_truncate(StringInfo s) { - bool cascade = false; - bool restart_seqs = false; - List *remote_relids = NIL; - List *remote_rels = NIL; - List *rels = NIL; - List *relids = NIL; - List *relids_logged = NIL; - ListCell *lc; + bool cascade = false; + bool restart_seqs = false; + List *remote_relids = NIL; + List *remote_rels = NIL; + List *rels = NIL; + List *relids = NIL; + List *relids_logged = NIL; + ListCell *lc; ensure_transaction(); @@ -932,13 +920,13 @@ apply_handle_truncate(StringInfo s) rels = lappend(rels, rel->localrel); relids = lappend_oid(relids, rel->localreloid); if (RelationIsLogicallyLogged(rel->localrel)) - relids_logged = lappend_oid(relids, rel->localreloid); + relids_logged = lappend_oid(relids_logged, rel->localreloid); } /* - * Even if we used CASCADE on the upstream master we explicitly - * default to replaying changes without further cascading. - * This might be later changeable with a user specified option. + * Even if we used CASCADE on the upstream master we explicitly default to + * replaying changes without further cascading. This might be later + * changeable with a user specified option. */ ExecuteTruncateGuts(rels, relids, relids_logged, DROP_RESTRICT, restart_seqs); @@ -1255,14 +1243,10 @@ LogicalRepApplyLoop(XLogRecPtr last_received) rc = WaitLatchOrSocket(MyLatch, WL_SOCKET_READABLE | WL_LATCH_SET | - WL_TIMEOUT | WL_POSTMASTER_DEATH, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, fd, wait_time, WAIT_EVENT_LOGICAL_APPLY_MAIN); - /* Emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); @@ -1595,6 +1579,11 @@ ApplyWorkerMain(Datum main_arg) pqsignal(SIGTERM, die); BackgroundWorkerUnblockSignals(); + /* + * We don't currently need any ResourceOwner in a walreceiver process, but + * if we did, we could call CreateAuxProcessResourceOwner here. + */ + /* Initialise stats to a sanish value */ MyLogicalRepWorker->last_send_time = MyLogicalRepWorker->last_recv_time = MyLogicalRepWorker->reply_time = GetCurrentTimestamp(); @@ -1602,10 +1591,6 @@ ApplyWorkerMain(Datum main_arg) /* Load the libpq-specific functions */ load_file("libpqwalreceiver", false); - Assert(CurrentResourceOwner == NULL); - CurrentResourceOwner = ResourceOwnerCreate(NULL, - "logical replication apply"); - /* Run as replica session replication role. */ SetConfigOption("session_replication_role", "replica", PGC_SUSET, PGC_S_OVERRIDE); @@ -1673,7 +1658,7 @@ ApplyWorkerMain(Datum main_arg) { char *syncslotname; - /* This is table synchroniation worker, call initial sync. */ + /* This is table synchronization worker, call initial sync. */ syncslotname = LogicalRepSyncTableStart(&origin_startpos); /* The slot name needs to be allocated in permanent memory context. */ @@ -1689,7 +1674,6 @@ ApplyWorkerMain(Datum main_arg) RepOriginId originid; TimeLineID startpointTLI; char *err; - int server_version; myslotname = MySubscription->slotname; @@ -1723,8 +1707,7 @@ ApplyWorkerMain(Datum main_arg) * We don't really use the output identify_system for anything but it * does some initializations on the upstream so let's still call it. */ - (void) walrcv_identify_system(wrconn, &startpointTLI, - &server_version); + (void) walrcv_identify_system(wrconn, &startpointTLI); } diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c index 06dfbc082f2..9c08757fcaf 100644 --- a/src/backend/replication/pgoutput/pgoutput.c +++ b/src/backend/replication/pgoutput/pgoutput.c @@ -3,7 +3,7 @@ * pgoutput.c * Logical Replication output plugin * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/pgoutput/pgoutput.c @@ -14,6 +14,8 @@ #include "catalog/pg_publication.h" +#include "fmgr.h" + #include "replication/logical.h" #include "replication/logicalproto.h" #include "replication/origin.h" @@ -30,26 +32,26 @@ PG_MODULE_MAGIC; extern void _PG_output_plugin_init(OutputPluginCallbacks *cb); static void pgoutput_startup(LogicalDecodingContext *ctx, - OutputPluginOptions *opt, bool is_init); + OutputPluginOptions *opt, bool is_init); static void pgoutput_shutdown(LogicalDecodingContext *ctx); static void pgoutput_begin_txn(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn); + ReorderBufferTXN *txn); static void pgoutput_commit_txn(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, XLogRecPtr commit_lsn); + ReorderBufferTXN *txn, XLogRecPtr commit_lsn); static void pgoutput_change(LogicalDecodingContext *ctx, - ReorderBufferTXN *txn, Relation rel, - ReorderBufferChange *change); + ReorderBufferTXN *txn, Relation rel, + ReorderBufferChange *change); static void pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change); static bool pgoutput_origin_filter(LogicalDecodingContext *ctx, - RepOriginId origin_id); + RepOriginId origin_id); static bool publications_valid; static List *LoadPublications(List *pubnames); static void publication_invalidation_cb(Datum arg, int cacheid, - uint32 hashvalue); + uint32 hashvalue); /* Entry in the map used to remember which relation schemas we sent. */ typedef struct RelationSyncEntry @@ -67,7 +69,7 @@ static void init_rel_sync_cache(MemoryContext decoding_context); static RelationSyncEntry *get_rel_sync_entry(PGOutputData *data, Oid relid); static void rel_sync_cache_relation_cb(Datum arg, Oid relid); static void rel_sync_cache_publication_cb(Datum arg, int cacheid, - uint32 hashvalue); + uint32 hashvalue); /* * Specify output plugin callbacks @@ -269,17 +271,21 @@ maybe_send_schema(LogicalDecodingContext *ctx, desc = RelationGetDescr(relation); /* - * Write out type info if needed. We do that only for user created - * types. + * Write out type info if needed. We do that only for user-created + * types. We use FirstGenbkiObjectId as the cutoff, so that we only + * consider objects with hand-assigned OIDs to be "built in", not for + * instance any function or type defined in the information_schema. + * This is important because only hand-assigned OIDs can be expected + * to remain stable across major versions. */ for (i = 0; i < desc->natts; i++) { Form_pg_attribute att = TupleDescAttr(desc, i); - if (att->attisdropped) + if (att->attisdropped || att->attgenerated) continue; - if (att->atttypid < FirstNormalObjectId) + if (att->atttypid < FirstGenbkiObjectId) continue; OutputPluginPrepareWrite(ctx, false); @@ -407,13 +413,16 @@ pgoutput_truncate(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, maybe_send_schema(ctx, relation, relentry); } - OutputPluginPrepareWrite(ctx, true); - logicalrep_write_truncate(ctx->out, - nrelids, - relids, - change->data.truncate.cascade, - change->data.truncate.restart_seqs); - OutputPluginWrite(ctx, true); + if (nrelids > 0) + { + OutputPluginPrepareWrite(ctx, true); + logicalrep_write_truncate(ctx->out, + nrelids, + relids, + change->data.truncate.cascade, + change->data.truncate.restart_seqs); + OutputPluginWrite(ctx, true); + } MemoryContextSwitchTo(old); MemoryContextReset(data->context); diff --git a/src/backend/replication/repl_gram.y b/src/backend/replication/repl_gram.y index 843a878ff37..c4e11cc4e8f 100644 --- a/src/backend/replication/repl_gram.y +++ b/src/backend/replication/repl_gram.y @@ -3,7 +3,7 @@ * * repl_gram.y - Parser for the replication commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 7bb501f5949..380faeb5f6e 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -4,7 +4,7 @@ * repl_scanner.l * a lexical scanner for the replication commands * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index 056628fe8e3..b1bcd93345d 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -4,7 +4,7 @@ * Replication slot management. * * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -108,7 +108,7 @@ static void CreateSlotOnDisk(ReplicationSlot *slot); static void SaveSlotToPath(ReplicationSlot *slot, const char *path, int elevel); /* - * Report shared-memory space needed by ReplicationSlotShmemInit. + * Report shared-memory space needed by ReplicationSlotsShmemInit. */ Size ReplicationSlotsShmemSize(void) @@ -298,7 +298,7 @@ ReplicationSlotCreate(const char *name, bool db_specific, * We need to briefly prevent any other backend from iterating over the * slots while we flip the in_use flag. We also need to set the active * flag while holding the ControlLock as otherwise a concurrent - * SlotAcquire() could acquire the slot as well. + * ReplicationSlotAcquire() could acquire the slot as well. */ LWLockAcquire(ReplicationSlotControlLock, LW_EXCLUSIVE); @@ -351,20 +351,28 @@ ReplicationSlotAcquire(const char *name, bool nowait) if (s->in_use && strcmp(name, NameStr(s->data.name)) == 0) { /* - * This is the slot we want. We don't know yet if it's active, so - * get ready to sleep on it in case it is. (We may end up not - * sleeping, but we don't want to do this while holding the - * spinlock.) + * This is the slot we want; check if it's active under some other + * process. In single user mode, we don't need this check. */ - ConditionVariablePrepareToSleep(&s->active_cv); + if (IsUnderPostmaster) + { + /* + * Get ready to sleep on it in case it is active. (We may end + * up not sleeping, but we don't want to do this while holding + * the spinlock.) + */ + ConditionVariablePrepareToSleep(&s->active_cv); - SpinLockAcquire(&s->mutex); + SpinLockAcquire(&s->mutex); - active_pid = s->active_pid; - if (active_pid == 0) - active_pid = s->active_pid = MyProcPid; + active_pid = s->active_pid; + if (active_pid == 0) + active_pid = s->active_pid = MyProcPid; - SpinLockRelease(&s->mutex); + SpinLockRelease(&s->mutex); + } + else + active_pid = MyProcPid; slot = s; break; @@ -620,8 +628,7 @@ ReplicationSlotDropPtr(ReplicationSlot *slot) */ if (!rmtree(tmppath, true)) ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not remove directory \"%s\"", tmppath))); + (errmsg("could not remove directory \"%s\"", tmppath))); /* * We release this at the very end, so that nobody starts trying to create @@ -964,6 +971,11 @@ ReplicationSlotsDropDBSlots(Oid dboid) void CheckSlotRequirements(void) { + /* + * NB: Adding a new requirement likely means that RestoreSlotFromDisk() + * needs the same check. + */ + if (max_replication_slots == 0) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), @@ -999,6 +1011,7 @@ ReplicationSlotReserveWal(void) while (true) { XLogSegNo segno; + XLogRecPtr restart_lsn; /* * For logical slots log a standby snapshot and start logical decoding @@ -1016,7 +1029,10 @@ ReplicationSlotReserveWal(void) XLogRecPtr flushptr; /* start at current insert position */ - slot->data.restart_lsn = GetXLogInsertRecPtr(); + restart_lsn = GetXLogInsertRecPtr(); + SpinLockAcquire(&slot->mutex); + slot->data.restart_lsn = restart_lsn; + SpinLockRelease(&slot->mutex); /* make sure we have enough information to start */ flushptr = LogStandbySnapshot(); @@ -1026,7 +1042,10 @@ ReplicationSlotReserveWal(void) } else { - slot->data.restart_lsn = GetRedoRecPtr(); + restart_lsn = GetRedoRecPtr(); + SpinLockAcquire(&slot->mutex); + slot->data.restart_lsn = restart_lsn; + SpinLockRelease(&slot->mutex); } /* prevent WAL removal as fast as possible */ @@ -1117,8 +1136,8 @@ StartupReplicationSlots(void) if (!rmtree(path, true)) { ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not remove directory \"%s\"", path))); + (errmsg("could not remove directory \"%s\"", + path))); continue; } fsync_fname("pg_replslot", true); @@ -1260,6 +1279,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) SnapBuildOnDiskChecksummedSize); FIN_CRC32C(cp.checksum); + errno = 0; pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_WRITE); if ((write(fd, &cp, sizeof(cp))) != sizeof(cp)) { @@ -1267,7 +1287,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) pgstat_report_wait_end(); CloseTransientFile(fd); - errno = save_errno; + + /* if write didn't set errno, assume problem is no disk space */ + errno = save_errno ? save_errno : ENOSPC; ereport(elevel, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", @@ -1293,7 +1315,14 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) } pgstat_report_wait_end(); - CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + tmppath))); + return; + } /* rename to permanent file, fsync file and directory */ if (rename(tmppath, path) != 0) @@ -1305,7 +1334,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) return; } - /* Check CreateSlot() for the reasoning of using a crit. section. */ + /* + * Check CreateSlotOnDisk() for the reasoning of using a critical section. + */ START_CRIT_SECTION(); fsync_fname(path, false); @@ -1334,6 +1365,7 @@ RestoreSlotFromDisk(const char *name) { ReplicationSlotOnDisk cp; int i; + char slotdir[MAXPGPATH + 12]; char path[MAXPGPATH + 22]; int fd; bool restored = false; @@ -1343,17 +1375,18 @@ RestoreSlotFromDisk(const char *name) /* no need to lock here, no concurrent access allowed yet */ /* delete temp file if it exists */ - sprintf(path, "pg_replslot/%s/state.tmp", name); + sprintf(slotdir, "pg_replslot/%s", name); + sprintf(path, "%s/state.tmp", slotdir); if (unlink(path) < 0 && errno != ENOENT) ereport(PANIC, (errcode_for_file_access(), errmsg("could not remove file \"%s\": %m", path))); - sprintf(path, "pg_replslot/%s/state", name); + sprintf(path, "%s/state", slotdir); elog(DEBUG1, "restoring replication slot from \"%s\"", path); - fd = OpenTransientFile(path, O_RDWR | PG_BINARY); + fd = OpenTransientFile(path, O_RDONLY | PG_BINARY); /* * We do not need to handle this as we are rename()ing the directory into @@ -1370,18 +1403,15 @@ RestoreSlotFromDisk(const char *name) */ pgstat_report_wait_start(WAIT_EVENT_REPLICATION_SLOT_RESTORE_SYNC); if (pg_fsync(fd) != 0) - { - CloseTransientFile(fd); ereport(PANIC, (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", path))); - } pgstat_report_wait_end(); /* Also sync the parent directory */ START_CRIT_SECTION(); - fsync_fname(path, true); + fsync_fname(slotdir, true); END_CRIT_SECTION(); /* read part of statefile that's guaranteed to be version independent */ @@ -1390,35 +1420,36 @@ RestoreSlotFromDisk(const char *name) pgstat_report_wait_end(); if (readBytes != ReplicationSlotOnDiskConstantSize) { - int saved_errno = errno; - - CloseTransientFile(fd); - errno = saved_errno; - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %u: %m", - path, readBytes, - (uint32) ReplicationSlotOnDiskConstantSize))); + if (readBytes < 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + else + ereport(PANIC, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, + (Size) ReplicationSlotOnDiskConstantSize))); } /* verify magic */ if (cp.magic != SLOT_MAGIC) ereport(PANIC, - (errcode_for_file_access(), + (errcode(ERRCODE_DATA_CORRUPTED), errmsg("replication slot file \"%s\" has wrong magic number: %u instead of %u", path, cp.magic, SLOT_MAGIC))); /* verify version */ if (cp.version != SLOT_VERSION) ereport(PANIC, - (errcode_for_file_access(), + (errcode(ERRCODE_DATA_CORRUPTED), errmsg("replication slot file \"%s\" has unsupported version %u", path, cp.version))); /* boundary check on length */ if (cp.length != ReplicationSlotOnDiskV2Size) ereport(PANIC, - (errcode_for_file_access(), + (errcode(ERRCODE_DATA_CORRUPTED), errmsg("replication slot file \"%s\" has corrupted length %u", path, cp.length))); @@ -1430,17 +1461,21 @@ RestoreSlotFromDisk(const char *name) pgstat_report_wait_end(); if (readBytes != cp.length) { - int saved_errno = errno; + if (readBytes < 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", path))); + else + ereport(PANIC, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, readBytes, (Size) cp.length))); + } - CloseTransientFile(fd); - errno = saved_errno; + if (CloseTransientFile(fd) != 0) ereport(PANIC, (errcode_for_file_access(), - errmsg("could not read file \"%s\", read %d of %u: %m", - path, readBytes, cp.length))); - } - - CloseTransientFile(fd); + errmsg("could not close file \"%s\": %m", path))); /* now verify the CRC */ INIT_CRC32C(checksum); @@ -1460,18 +1495,41 @@ RestoreSlotFromDisk(const char *name) */ if (cp.slotdata.persistency != RS_PERSISTENT) { - sprintf(path, "pg_replslot/%s", name); - - if (!rmtree(path, true)) + if (!rmtree(slotdir, true)) { ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not remove directory \"%s\"", path))); + (errmsg("could not remove directory \"%s\"", + slotdir))); } fsync_fname("pg_replslot", true); return; } + /* + * Verify that requirements for the specific slot type are met. That's + * important because if these aren't met we're not guaranteed to retain + * all the necessary resources for the slot. + * + * NB: We have to do so *after* the above checks for ephemeral slots, + * because otherwise a slot that shouldn't exist anymore could prevent + * restarts. + * + * NB: Changing the requirements here also requires adapting + * CheckSlotRequirements() and CheckLogicalDecodingRequirements(). + */ + if (cp.slotdata.database != InvalidOid && wal_level < WAL_LEVEL_LOGICAL) + ereport(FATAL, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("logical replication slot \"%s\" exists, but wal_level < logical", + NameStr(cp.slotdata.name)), + errhint("Change wal_level to be logical or higher."))); + else if (wal_level < WAL_LEVEL_REPLICA) + ereport(FATAL, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("physical replication slot \"%s\" exists, but wal_level < replica", + NameStr(cp.slotdata.name)), + errhint("Change wal_level to be replica or higher."))); + /* nothing can be active yet, don't lock anything */ for (i = 0; i < max_replication_slots; i++) { @@ -1503,7 +1561,7 @@ RestoreSlotFromDisk(const char *name) } if (!restored) - ereport(PANIC, + ereport(FATAL, (errmsg("too many replication slots active before shutdown"), errhint("Increase max_replication_slots and try again."))); } diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index e873dd1f81a..42da6318238 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -3,20 +3,19 @@ * slotfuncs.c * Support functions for replication slots * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/slotfuncs.c * *------------------------------------------------------------------------- */ - #include "postgres.h" +#include "access/htup_details.h" +#include "access/xlog_internal.h" #include "funcapi.h" #include "miscadmin.h" - -#include "access/htup_details.h" #include "replication/decode.h" #include "replication/slot.h" #include "replication/logical.h" @@ -35,6 +34,38 @@ check_permissions(void) (errmsg("must be superuser or replication role to use replication slots")))); } +/* + * Helper function for creating a new physical replication slot with + * given arguments. Note that this function doesn't release the created + * slot. + * + * If restart_lsn is a valid value, we use it without WAL reservation + * routine. So the caller must guarantee that WAL is available. + */ +static void +create_physical_replication_slot(char *name, bool immediately_reserve, + bool temporary, XLogRecPtr restart_lsn) +{ + Assert(!MyReplicationSlot); + + /* acquire replication slot, this will check for conflicting names */ + ReplicationSlotCreate(name, false, + temporary ? RS_TEMPORARY : RS_PERSISTENT); + + if (immediately_reserve) + { + /* Reserve WAL as the user asked for it */ + if (XLogRecPtrIsInvalid(restart_lsn)) + ReplicationSlotReserveWal(); + else + MyReplicationSlot->data.restart_lsn = restart_lsn; + + /* Write this slot to disk */ + ReplicationSlotMarkDirty(); + ReplicationSlotSave(); + } +} + /* * SQL function for creating a new physical (streaming replication) * replication slot. @@ -51,8 +82,6 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) HeapTuple tuple; Datum result; - Assert(!MyReplicationSlot); - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -60,29 +89,21 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) CheckSlotRequirements(); - /* acquire replication slot, this will check for conflicting names */ - ReplicationSlotCreate(NameStr(*name), false, - temporary ? RS_TEMPORARY : RS_PERSISTENT); + create_physical_replication_slot(NameStr(*name), + immediately_reserve, + temporary, + InvalidXLogRecPtr); values[0] = NameGetDatum(&MyReplicationSlot->data.name); nulls[0] = false; if (immediately_reserve) { - /* Reserve WAL as the user asked for it */ - ReplicationSlotReserveWal(); - - /* Write this slot to disk */ - ReplicationSlotMarkDirty(); - ReplicationSlotSave(); - values[1] = LSNGetDatum(MyReplicationSlot->data.restart_lsn); nulls[1] = false; } else - { nulls[1] = true; - } tuple = heap_form_tuple(tupdesc, values, nulls); result = HeapTupleGetDatum(tuple); @@ -94,32 +115,18 @@ pg_create_physical_replication_slot(PG_FUNCTION_ARGS) /* - * SQL function for creating a new logical replication slot. + * Helper function for creating a new logical replication slot with + * given arguments. Note that this function doesn't release the created + * slot. */ -Datum -pg_create_logical_replication_slot(PG_FUNCTION_ARGS) +static void +create_logical_replication_slot(char *name, char *plugin, + bool temporary, XLogRecPtr restart_lsn) { - Name name = PG_GETARG_NAME(0); - Name plugin = PG_GETARG_NAME(1); - bool temporary = PG_GETARG_BOOL(2); - LogicalDecodingContext *ctx = NULL; - TupleDesc tupdesc; - HeapTuple tuple; - Datum result; - Datum values[2]; - bool nulls[2]; - Assert(!MyReplicationSlot); - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - elog(ERROR, "return type must be a row type"); - - check_permissions(); - - CheckLogicalDecodingRequirements(); - /* * Acquire a logical decoding slot, this will check for conflicting names. * Initially create persistent slot as ephemeral - that allows us to @@ -128,25 +135,54 @@ pg_create_logical_replication_slot(PG_FUNCTION_ARGS) * slots can be created as temporary from beginning as they get dropped on * error as well. */ - ReplicationSlotCreate(NameStr(*name), true, + ReplicationSlotCreate(name, true, temporary ? RS_TEMPORARY : RS_EPHEMERAL); /* * Create logical decoding context, to build the initial snapshot. */ - ctx = CreateInitDecodingContext(NameStr(*plugin), NIL, + ctx = CreateInitDecodingContext(plugin, NIL, false, /* do not build snapshot */ + restart_lsn, logical_read_local_xlog_page, NULL, NULL, NULL); /* build initial snapshot, might take a while */ DecodingContextFindStartpoint(ctx); - values[0] = CStringGetTextDatum(NameStr(MyReplicationSlot->data.name)); - values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush); - /* don't need the decoding context anymore */ FreeDecodingContext(ctx); +} + +/* + * SQL function for creating a new logical replication slot. + */ +Datum +pg_create_logical_replication_slot(PG_FUNCTION_ARGS) +{ + Name name = PG_GETARG_NAME(0); + Name plugin = PG_GETARG_NAME(1); + bool temporary = PG_GETARG_BOOL(2); + Datum result; + TupleDesc tupdesc; + HeapTuple tuple; + Datum values[2]; + bool nulls[2]; + + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + check_permissions(); + + CheckLogicalDecodingRequirements(); + + create_logical_replication_slot(NameStr(*name), + NameStr(*plugin), + temporary, + InvalidXLogRecPtr); + + values[0] = NameGetDatum(&MyReplicationSlot->data.name); + values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush); memset(nulls, 0, sizeof(nulls)); @@ -317,80 +353,113 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) } /* - * Helper function for advancing physical replication slot forward. + * Helper function for advancing our physical replication slot forward. + * + * The LSN position to move to is compared simply to the slot's restart_lsn, + * knowing that any position older than that would be removed by successive + * checkpoints. */ static XLogRecPtr -pg_physical_replication_slot_advance(XLogRecPtr startlsn, XLogRecPtr moveto) +pg_physical_replication_slot_advance(XLogRecPtr moveto) { - XLogRecPtr retlsn = InvalidXLogRecPtr; + XLogRecPtr startlsn = MyReplicationSlot->data.restart_lsn; + XLogRecPtr retlsn = startlsn; - SpinLockAcquire(&MyReplicationSlot->mutex); - if (MyReplicationSlot->data.restart_lsn < moveto) + if (startlsn < moveto) { + SpinLockAcquire(&MyReplicationSlot->mutex); MyReplicationSlot->data.restart_lsn = moveto; + SpinLockRelease(&MyReplicationSlot->mutex); retlsn = moveto; } - SpinLockRelease(&MyReplicationSlot->mutex); return retlsn; } /* - * Helper function for advancing logical replication slot forward. + * Helper function for advancing our logical replication slot forward. + * + * The slot's restart_lsn is used as start point for reading records, + * while confirmed_lsn is used as base point for the decoding context. + * + * We cannot just do LogicalConfirmReceivedLocation to update confirmed_flush, + * because we need to digest WAL to advance restart_lsn allowing to recycle + * WAL and removal of old catalog tuples. As decoding is done in fast_forward + * mode, no changes are generated anyway. */ static XLogRecPtr -pg_logical_replication_slot_advance(XLogRecPtr startlsn, XLogRecPtr moveto) +pg_logical_replication_slot_advance(XLogRecPtr moveto) { LogicalDecodingContext *ctx; - ResourceOwner old_resowner = CurrentResourceOwner; - XLogRecPtr retlsn = InvalidXLogRecPtr; + ResourceOwner old_resowner = CurrentResourceOwner; + XLogRecPtr startlsn; + XLogRecPtr retlsn; PG_TRY(); { - /* restart at slot's confirmed_flush */ + /* + * Create our decoding context in fast_forward mode, passing start_lsn + * as InvalidXLogRecPtr, so that we start processing from my slot's + * confirmed_flush. + */ ctx = CreateDecodingContext(InvalidXLogRecPtr, NIL, - true, + true, /* fast_forward */ logical_read_local_xlog_page, NULL, NULL, NULL); - CurrentResourceOwner = ResourceOwnerCreate(CurrentResourceOwner, - "logical decoding"); + /* + * Start reading at the slot's restart_lsn, which we know to point to + * a valid record. + */ + startlsn = MyReplicationSlot->data.restart_lsn; + + /* Initialize our return value in case we don't do anything */ + retlsn = MyReplicationSlot->data.confirmed_flush; /* invalidate non-timetravel entries */ InvalidateSystemCaches(); - /* Decode until we run out of records */ - while ((startlsn != InvalidXLogRecPtr && startlsn < moveto) || - (ctx->reader->EndRecPtr != InvalidXLogRecPtr && ctx->reader->EndRecPtr < moveto)) + /* Decode at least one record, until we run out of records */ + while ((!XLogRecPtrIsInvalid(startlsn) && + startlsn < moveto) || + (!XLogRecPtrIsInvalid(ctx->reader->EndRecPtr) && + ctx->reader->EndRecPtr < moveto)) { - XLogRecord *record; char *errm = NULL; + XLogRecord *record; + /* + * Read records. No changes are generated in fast_forward mode, + * but snapbuilder/slot statuses are updated properly. + */ record = XLogReadRecord(ctx->reader, startlsn, &errm); if (errm) elog(ERROR, "%s", errm); - /* - * Now that we've set up the xlog reader state, subsequent calls - * pass InvalidXLogRecPtr to say "continue from last record" - */ + /* Read sequentially from now on */ startlsn = InvalidXLogRecPtr; /* - * The {begin_txn,change,commit_txn}_wrapper callbacks above will - * store the description into our tuplestore. + * Process the record. Storage-level changes are ignored in + * fast_forward mode, but other modules (such as snapbuilder) + * might still have critical updates to do. */ - if (record != NULL) + if (record) LogicalDecodingProcessRecord(ctx, ctx->reader); - /* check limits */ + /* Stop once the requested target has been reached */ if (moveto <= ctx->reader->EndRecPtr) break; CHECK_FOR_INTERRUPTS(); } + /* + * Logical decoding could have clobbered CurrentResourceOwner during + * transaction management, so restore the executor's value. (This is + * a kluge, but it's not worth cleaning up right now.) + */ CurrentResourceOwner = old_resowner; if (ctx->reader->EndRecPtr != InvalidXLogRecPtr) @@ -398,7 +467,7 @@ pg_logical_replication_slot_advance(XLogRecPtr startlsn, XLogRecPtr moveto) LogicalConfirmReceivedLocation(moveto); /* - * If only the confirmed_flush_lsn has changed the slot won't get + * If only the confirmed_flush LSN has changed the slot won't get * marked as dirty by the above. Callers on the walsender * interface are expected to keep track of their own progress and * don't need it written out. But SQL-interface users cannot @@ -441,7 +510,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) Name slotname = PG_GETARG_NAME(0); XLogRecPtr moveto = PG_GETARG_LSN(1); XLogRecPtr endlsn; - XLogRecPtr startlsn; + XLogRecPtr minlsn; TupleDesc tupdesc; Datum values[2]; bool nulls[2]; @@ -454,7 +523,7 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) if (XLogRecPtrIsInvalid(moveto)) ereport(ERROR, - (errmsg("invalid target wal lsn"))); + (errmsg("invalid target WAL LSN"))); /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) @@ -472,21 +541,35 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) /* Acquire the slot so we "own" it */ ReplicationSlotAcquire(NameStr(*slotname), true); - startlsn = MyReplicationSlot->data.confirmed_flush; - if (moveto < startlsn) - { - ReplicationSlotRelease(); + /* A slot whose restart_lsn has never been reserved cannot be advanced */ + if (XLogRecPtrIsInvalid(MyReplicationSlot->data.restart_lsn)) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot move slot to %X/%X, minimum is %X/%X", + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot advance replication slot that has not previously reserved WAL"))); + + /* + * Check if the slot is not moving backwards. Physical slots rely simply + * on restart_lsn as a minimum point, while logical slots have confirmed + * consumption up to confirmed_lsn, meaning that in both cases data older + * than that is not available anymore. + */ + if (OidIsValid(MyReplicationSlot->data.database)) + minlsn = MyReplicationSlot->data.confirmed_flush; + else + minlsn = MyReplicationSlot->data.restart_lsn; + + if (moveto < minlsn) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot advance replication slot to %X/%X, minimum is %X/%X", (uint32) (moveto >> 32), (uint32) moveto, - (uint32) (startlsn >> 32), (uint32) startlsn))); - } + (uint32) (minlsn >> 32), (uint32) minlsn))); + /* Do the actual slot update, depending on the slot type */ if (OidIsValid(MyReplicationSlot->data.database)) - endlsn = pg_logical_replication_slot_advance(startlsn, moveto); + endlsn = pg_logical_replication_slot_advance(moveto); else - endlsn = pg_physical_replication_slot_advance(startlsn, moveto); + endlsn = pg_physical_replication_slot_advance(moveto); values[0] = NameGetDatum(&MyReplicationSlot->data.name); nulls[0] = false; @@ -511,3 +594,235 @@ pg_replication_slot_advance(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } + +/* + * Helper function of copying a replication slot. + */ +static Datum +copy_replication_slot(FunctionCallInfo fcinfo, bool logical_slot) +{ + Name src_name = PG_GETARG_NAME(0); + Name dst_name = PG_GETARG_NAME(1); + ReplicationSlot *src = NULL; + XLogRecPtr src_restart_lsn; + bool src_islogical; + bool temporary; + char *plugin; + Datum values[2]; + bool nulls[2]; + Datum result; + TupleDesc tupdesc; + HeapTuple tuple; + + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + elog(ERROR, "return type must be a row type"); + + check_permissions(); + + if (logical_slot) + CheckLogicalDecodingRequirements(); + else + CheckSlotRequirements(); + + LWLockAcquire(ReplicationSlotControlLock, LW_SHARED); + + /* + * We need to prevent the source slot's reserved WAL from being removed, + * but we don't want to lock that slot for very long, and it can advance + * in the meantime. So obtain the source slot's data, and create a new + * slot using its restart_lsn. Afterwards we lock the source slot again + * and verify that the data we copied (name, type) has not changed + * incompatibly. No inconvenient WAL removal can occur once the new slot + * is created -- but since WAL removal could have occurred before we + * managed to create the new slot, we advance the new slot's restart_lsn + * to the source slot's updated restart_lsn the second time we lock it. + */ + for (int i = 0; i < max_replication_slots; i++) + { + ReplicationSlot *s = &ReplicationSlotCtl->replication_slots[i]; + + if (s->in_use && strcmp(NameStr(s->data.name), NameStr(*src_name)) == 0) + { + SpinLockAcquire(&s->mutex); + src_islogical = SlotIsLogical(s); + src_restart_lsn = s->data.restart_lsn; + temporary = s->data.persistency == RS_TEMPORARY; + plugin = logical_slot ? pstrdup(NameStr(s->data.plugin)) : NULL; + SpinLockRelease(&s->mutex); + + src = s; + break; + } + } + + LWLockRelease(ReplicationSlotControlLock); + + if (src == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("replication slot \"%s\" does not exist", NameStr(*src_name)))); + + /* Check type of replication slot */ + if (src_islogical != logical_slot) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + src_islogical ? + errmsg("cannot copy physical replication slot \"%s\" as a logical replication slot", + NameStr(*src_name)) : + errmsg("cannot copy logical replication slot \"%s\" as a physical replication slot", + NameStr(*src_name)))); + + /* Copying non-reserved slot doesn't make sense */ + if (XLogRecPtrIsInvalid(src_restart_lsn)) + { + Assert(!logical_slot); + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + (errmsg("cannot copy a replication slot that doesn't reserve WAL")))); + } + + /* Overwrite params from optional arguments */ + if (PG_NARGS() >= 3) + temporary = PG_GETARG_BOOL(2); + if (PG_NARGS() >= 4) + { + Assert(logical_slot); + plugin = NameStr(*(PG_GETARG_NAME(3))); + } + + /* Create new slot and acquire it */ + if (logical_slot) + create_logical_replication_slot(NameStr(*dst_name), + plugin, + temporary, + src_restart_lsn); + else + create_physical_replication_slot(NameStr(*dst_name), + true, + temporary, + src_restart_lsn); + + /* + * Update the destination slot to current values of the source slot; + * recheck that the source slot is still the one we saw previously. + */ + { + TransactionId copy_effective_xmin; + TransactionId copy_effective_catalog_xmin; + TransactionId copy_xmin; + TransactionId copy_catalog_xmin; + XLogRecPtr copy_restart_lsn; + bool copy_islogical; + char *copy_name; + + /* Copy data of source slot again */ + SpinLockAcquire(&src->mutex); + copy_effective_xmin = src->effective_xmin; + copy_effective_catalog_xmin = src->effective_catalog_xmin; + + copy_xmin = src->data.xmin; + copy_catalog_xmin = src->data.catalog_xmin; + copy_restart_lsn = src->data.restart_lsn; + + /* for existence check */ + copy_name = pstrdup(NameStr(src->data.name)); + copy_islogical = SlotIsLogical(src); + SpinLockRelease(&src->mutex); + + /* + * Check if the source slot still exists and is valid. We regard it as + * invalid if the type of replication slot or name has been changed, + * or the restart_lsn either is invalid or has gone backward. (The + * restart_lsn could go backwards if the source slot is dropped and + * copied from an older slot during installation.) + * + * Since erroring out will release and drop the destination slot we + * don't need to release it here. + */ + if (copy_restart_lsn < src_restart_lsn || + src_islogical != copy_islogical || + strcmp(copy_name, NameStr(*src_name)) != 0) + ereport(ERROR, + (errmsg("could not copy replication slot \"%s\"", + NameStr(*src_name)), + errdetail("The source replication slot was modified incompatibly during the copy operation."))); + + /* Install copied values again */ + SpinLockAcquire(&MyReplicationSlot->mutex); + MyReplicationSlot->effective_xmin = copy_effective_xmin; + MyReplicationSlot->effective_catalog_xmin = copy_effective_catalog_xmin; + + MyReplicationSlot->data.xmin = copy_xmin; + MyReplicationSlot->data.catalog_xmin = copy_catalog_xmin; + MyReplicationSlot->data.restart_lsn = copy_restart_lsn; + SpinLockRelease(&MyReplicationSlot->mutex); + + ReplicationSlotMarkDirty(); + ReplicationSlotsComputeRequiredXmin(false); + ReplicationSlotsComputeRequiredLSN(); + ReplicationSlotSave(); + +#ifdef USE_ASSERT_CHECKING + /* Check that the restart_lsn is available */ + { + XLogSegNo segno; + + XLByteToSeg(copy_restart_lsn, segno, wal_segment_size); + Assert(XLogGetLastRemovedSegno() < segno); + } +#endif + } + + /* target slot fully created, mark as persistent if needed */ + if (logical_slot && !temporary) + ReplicationSlotPersist(); + + /* All done. Set up the return values */ + values[0] = NameGetDatum(dst_name); + nulls[0] = false; + if (!XLogRecPtrIsInvalid(MyReplicationSlot->data.confirmed_flush)) + { + values[1] = LSNGetDatum(MyReplicationSlot->data.confirmed_flush); + nulls[1] = false; + } + else + nulls[1] = true; + + tuple = heap_form_tuple(tupdesc, values, nulls); + result = HeapTupleGetDatum(tuple); + + ReplicationSlotRelease(); + + PG_RETURN_DATUM(result); +} + +/* The wrappers below are all to appease opr_sanity */ +Datum +pg_copy_logical_replication_slot_a(PG_FUNCTION_ARGS) +{ + return copy_replication_slot(fcinfo, true); +} + +Datum +pg_copy_logical_replication_slot_b(PG_FUNCTION_ARGS) +{ + return copy_replication_slot(fcinfo, true); +} + +Datum +pg_copy_logical_replication_slot_c(PG_FUNCTION_ARGS) +{ + return copy_replication_slot(fcinfo, true); +} + +Datum +pg_copy_physical_replication_slot_a(PG_FUNCTION_ARGS) +{ + return copy_replication_slot(fcinfo, false); +} + +Datum +pg_copy_physical_replication_slot_b(PG_FUNCTION_ARGS) +{ + return copy_replication_slot(fcinfo, false); +} diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index 75d26817192..a21f7d33471 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -63,7 +63,7 @@ * the standbys which are considered as synchronous at that moment * will release waiters from the queue. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/syncrep.c @@ -102,17 +102,17 @@ static void SyncRepCancelWait(void); static int SyncRepWakeQueue(bool all, int mode); static bool SyncRepGetSyncRecPtr(XLogRecPtr *writePtr, - XLogRecPtr *flushPtr, - XLogRecPtr *applyPtr, - bool *am_sync); + XLogRecPtr *flushPtr, + XLogRecPtr *applyPtr, + bool *am_sync); static void SyncRepGetOldestSyncRecPtr(XLogRecPtr *writePtr, - XLogRecPtr *flushPtr, - XLogRecPtr *applyPtr, - List *sync_standbys); + XLogRecPtr *flushPtr, + XLogRecPtr *applyPtr, + List *sync_standbys); static void SyncRepGetNthLatestSyncRecPtr(XLogRecPtr *writePtr, - XLogRecPtr *flushPtr, - XLogRecPtr *applyPtr, - List *sync_standbys, uint8 nth); + XLogRecPtr *flushPtr, + XLogRecPtr *applyPtr, + List *sync_standbys, uint8 nth); static int SyncRepGetStandbyPriority(void); static List *SyncRepGetSyncStandbysPriority(bool *am_sync); static List *SyncRepGetSyncStandbysQuorum(bool *am_sync); @@ -214,6 +214,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit) */ for (;;) { + int rc; + /* Must reset the latch before testing state. */ ResetLatch(MyLatch); @@ -267,24 +269,23 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit) } /* - * If the postmaster dies, we'll probably never get an - * acknowledgement, because all the wal sender processes will exit. So - * just bail out. + * Wait on latch. Any condition that should wake us up will set the + * latch, so no need for timeout. */ - if (!PostmasterIsAlive()) + rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1, + WAIT_EVENT_SYNC_REP); + + /* + * If the postmaster dies, we'll probably never get an acknowledgment, + * because all the wal sender processes will exit. So just bail out. + */ + if (rc & WL_POSTMASTER_DEATH) { ProcDiePending = true; whereToSendOutput = DestNone; SyncRepCancelWait(); break; } - - /* - * Wait on latch. Any condition that should wake us up will set the - * latch, so no need for timeout. - */ - WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1, - WAIT_EVENT_SYNC_REP); } /* @@ -423,10 +424,12 @@ SyncRepReleaseWaiters(void) * If this WALSender is serving a standby that is not on the list of * potential sync standbys then we have nothing to do. If we are still * starting up, still running base backup or the current flush position is - * still invalid, then leave quickly also. + * still invalid, then leave quickly also. Streaming or stopping WAL + * senders are allowed to release waiters. */ if (MyWalSnd->sync_standby_priority == 0 || - MyWalSnd->state < WALSNDSTATE_STREAMING || + (MyWalSnd->state != WALSNDSTATE_STREAMING && + MyWalSnd->state != WALSNDSTATE_STOPPING) || XLogRecPtrIsInvalid(MyWalSnd->flush)) { announce_next_takeover = true; @@ -728,8 +731,9 @@ SyncRepGetSyncStandbysQuorum(bool *am_sync) if (pid == 0) continue; - /* Must be streaming */ - if (state != WALSNDSTATE_STREAMING) + /* Must be streaming or stopping */ + if (state != WALSNDSTATE_STREAMING && + state != WALSNDSTATE_STOPPING) continue; /* Must be synchronous */ @@ -807,8 +811,9 @@ SyncRepGetSyncStandbysPriority(bool *am_sync) if (pid == 0) continue; - /* Must be streaming */ - if (state != WALSNDSTATE_STREAMING) + /* Must be streaming or stopping */ + if (state != WALSNDSTATE_STREAMING && + state != WALSNDSTATE_STOPPING) continue; /* Must be synchronous */ @@ -860,8 +865,6 @@ SyncRepGetSyncStandbysPriority(bool *am_sync) */ if (list_length(result) + list_length(pending) <= SyncRepConfig->num_sync) { - bool needfree = (result != NIL && pending != NIL); - /* * Set *am_sync to true if this walsender is in the pending list * because all pending standbys are considered as sync. @@ -870,8 +873,7 @@ SyncRepGetSyncStandbysPriority(bool *am_sync) *am_sync = am_in_pending; result = list_concat(result, pending); - if (needfree) - pfree(pending); + list_free(pending); return result; } @@ -882,18 +884,14 @@ SyncRepGetSyncStandbysPriority(bool *am_sync) while (priority <= lowest_priority) { ListCell *cell; - ListCell *prev = NULL; - ListCell *next; next_highest_priority = lowest_priority + 1; - for (cell = list_head(pending); cell != NULL; cell = next) + foreach(cell, pending) { i = lfirst_int(cell); walsnd = &WalSndCtl->walsnds[i]; - next = lnext(cell); - this_priority = walsnd->sync_standby_priority; if (this_priority == priority) { @@ -916,15 +914,13 @@ SyncRepGetSyncStandbysPriority(bool *am_sync) * Remove the entry for this sync standby from the list to * prevent us from looking at the same entry again. */ - pending = list_delete_cell(pending, cell, prev); + pending = foreach_delete_current(pending, cell); - continue; + continue; /* don't adjust next_highest_priority */ } if (this_priority < next_highest_priority) next_highest_priority = this_priority; - - prev = cell; } priority = next_highest_priority; diff --git a/src/backend/replication/syncrep_gram.y b/src/backend/replication/syncrep_gram.y index 5d12925ab82..4a1fe909b44 100644 --- a/src/backend/replication/syncrep_gram.y +++ b/src/backend/replication/syncrep_gram.y @@ -3,7 +3,7 @@ * * syncrep_gram.y - Parser for synchronous_standby_names * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/syncrep_scanner.l b/src/backend/replication/syncrep_scanner.l index 5b641d8297b..15f65c8a113 100644 --- a/src/backend/replication/syncrep_scanner.l +++ b/src/backend/replication/syncrep_scanner.l @@ -4,7 +4,7 @@ * syncrep_scanner.l * a lexical scanner for synchronous_standby_names * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index b9dab322d6b..6abc7807783 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -33,7 +33,7 @@ * specific parts are in the libpqwalreceiver module. It's loaded * dynamically to avoid linking the server with libpq. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -112,28 +112,7 @@ static struct static StringInfoData reply_message; static StringInfoData incoming_message; -/* - * About SIGTERM handling: - * - * We can't just exit(1) within SIGTERM signal handler, because the signal - * might arrive in the middle of some critical operation, like while we're - * holding a spinlock. We also can't just set a flag in signal handler and - * check it in the main loop, because we perform some blocking operations - * like libpqrcv_PQexec(), which can take a long time to finish. - * - * We use a combined approach: When WalRcvImmediateInterruptOK is true, it's - * safe for the signal handler to elog(FATAL) immediately. Otherwise it just - * sets got_SIGTERM flag, which is checked in the main loop when convenient. - * - * This is very much like what regular backends do with ImmediateInterruptOK, - * ProcessInterrupts() etc. - */ -static volatile bool WalRcvImmediateInterruptOK = false; - /* Prototypes for private functions */ -static void ProcessWalRcvInterrupts(void); -static void EnableWalRcvImmediateExit(void); -static void DisableWalRcvImmediateExit(void); static void WalRcvFetchTimeLineHistoryFiles(TimeLineID first, TimeLineID last); static void WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI); static void WalRcvDie(int code, Datum arg); @@ -151,7 +130,20 @@ static void WalRcvShutdownHandler(SIGNAL_ARGS); static void WalRcvQuickDieHandler(SIGNAL_ARGS); -static void +/* + * Process any interrupts the walreceiver process may have received. + * This should be called any time the process's latch has become set. + * + * Currently, only SIGTERM is of interest. We can't just exit(1) within the + * SIGTERM signal handler, because the signal might arrive in the middle of + * some critical operation, like while we're holding a spinlock. Instead, the + * signal handler sets a flag variable as well as setting the process's latch. + * We must check the flag (by calling ProcessWalRcvInterrupts) anytime the + * latch has become set. Operations that could block for a long time, such as + * reading from a remote server, must pay attention to the latch too; see + * libpqrcv_PQgetResult for example. + */ +void ProcessWalRcvInterrupts(void) { /* @@ -163,26 +155,12 @@ ProcessWalRcvInterrupts(void) if (got_SIGTERM) { - WalRcvImmediateInterruptOK = false; ereport(FATAL, (errcode(ERRCODE_ADMIN_SHUTDOWN), errmsg("terminating walreceiver process due to administrator command"))); } } -static void -EnableWalRcvImmediateExit(void) -{ - WalRcvImmediateInterruptOK = true; - ProcessWalRcvInterrupts(); -} - -static void -DisableWalRcvImmediateExit(void) -{ - WalRcvImmediateInterruptOK = false; - ProcessWalRcvInterrupts(); -} /* Main entry point for walreceiver process */ void @@ -279,10 +257,6 @@ WalReceiverMain(void) /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); /* We allow SIGQUIT (quickdie) at all times */ sigdelset(&BlockSig, SIGQUIT); @@ -292,22 +266,14 @@ WalReceiverMain(void) if (WalReceiverFunctions == NULL) elog(ERROR, "libpqwalreceiver didn't initialize correctly"); - /* - * Create a resource owner to keep track of our resources (not clear that - * we need this, but may as well have one). - */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "Wal Receiver"); - /* Unblock signals (they were blocked when the postmaster forked us) */ PG_SETMASK(&UnBlockSig); /* Establish the connection to the primary for XLOG streaming */ - EnableWalRcvImmediateExit(); - wrconn = walrcv_connect(conninfo, false, "walreceiver", &err); + wrconn = walrcv_connect(conninfo, false, cluster_name[0] ? cluster_name : "walreceiver", &err); if (!wrconn) ereport(ERROR, (errmsg("could not connect to the primary server: %s", err))); - DisableWalRcvImmediateExit(); /* * Save user-visible connection string. This clobbers the original @@ -340,16 +306,13 @@ WalReceiverMain(void) { char *primary_sysid; char standby_sysid[32]; - int server_version; WalRcvStreamOptions options; /* * Check that we're connected to a valid server using the * IDENTIFY_SYSTEM replication command. */ - EnableWalRcvImmediateExit(); - primary_sysid = walrcv_identify_system(wrconn, &primaryTLI, - &server_version); + primary_sysid = walrcv_identify_system(wrconn, &primaryTLI); snprintf(standby_sysid, sizeof(standby_sysid), UINT64_FORMAT, GetSystemIdentifier()); @@ -360,7 +323,6 @@ WalReceiverMain(void) errdetail("The primary's identifier is %s, the standby's identifier is %s.", primary_sysid, standby_sysid))); } - DisableWalRcvImmediateExit(); /* * Confirm that the current timeline of the primary is the same or @@ -513,7 +475,7 @@ WalReceiverMain(void) */ Assert(wait_fd != PGINVALID_SOCKET); rc = WaitLatchOrSocket(walrcv->latch, - WL_POSTMASTER_DEATH | WL_SOCKET_READABLE | + WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | WL_TIMEOUT | WL_LATCH_SET, wait_fd, NAPTIME_PER_CYCLE, @@ -521,6 +483,8 @@ WalReceiverMain(void) if (rc & WL_LATCH_SET) { ResetLatch(walrcv->latch); + ProcessWalRcvInterrupts(); + if (walrcv->force_reply) { /* @@ -534,15 +498,6 @@ WalReceiverMain(void) XLogWalRcvSendReply(true, false); } } - if (rc & WL_POSTMASTER_DEATH) - { - /* - * Emergency bailout if postmaster has died. This is to - * avoid the necessity for manual cleanup of all - * postmaster children. - */ - exit(1); - } if (rc & WL_TIMEOUT) { /* @@ -598,9 +553,7 @@ WalReceiverMain(void) * The backend finished streaming. Exit streaming COPY-mode from * our side, too. */ - EnableWalRcvImmediateExit(); walrcv_endstreaming(wrconn, &primaryTLI); - DisableWalRcvImmediateExit(); /* * If the server had switched to a new timeline that we didn't @@ -683,13 +636,6 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI) { ResetLatch(walrcv->latch); - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (!PostmasterIsAlive()) - exit(1); - ProcessWalRcvInterrupts(); SpinLockAcquire(&walrcv->mutex); @@ -716,8 +662,8 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, TimeLineID *startpointTLI) } SpinLockRelease(&walrcv->mutex); - WaitLatch(walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0, - WAIT_EVENT_WAL_RECEIVER_WAIT_START); + (void) WaitLatch(walrcv->latch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_WAL_RECEIVER_WAIT_START); } if (update_process_title) @@ -754,9 +700,7 @@ WalRcvFetchTimeLineHistoryFiles(TimeLineID first, TimeLineID last) (errmsg("fetching timeline history file for timeline %u from primary server", tli))); - EnableWalRcvImmediateExit(); walrcv_readtimelinehistoryfile(wrconn, tli, &fname, &content, &len); - DisableWalRcvImmediateExit(); /* * Check that the filename on the master matches what we @@ -833,7 +777,7 @@ WalRcvSigUsr1Handler(SIGNAL_ARGS) errno = save_errno; } -/* SIGTERM: set flag for main loop, or shutdown immediately if safe */ +/* SIGTERM: set flag for ProcessWalRcvInterrupts */ static void WalRcvShutdownHandler(SIGNAL_ARGS) { @@ -844,10 +788,6 @@ WalRcvShutdownHandler(SIGNAL_ARGS) if (WalRcv->latch) SetLatch(WalRcv->latch); - /* Don't joggle the elbow of proc_exit */ - if (!proc_exit_inprogress && WalRcvImmediateInterruptOK) - ProcessWalRcvInterrupts(); - errno = save_errno; } @@ -860,27 +800,21 @@ WalRcvShutdownHandler(SIGNAL_ARGS) static void WalRcvQuickDieHandler(SIGNAL_ARGS) { - PG_SETMASK(&BlockSig); - /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we use _exit(2) not _exit(0). This is to force the postmaster + * into a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } /* @@ -1194,6 +1128,7 @@ static void XLogWalRcvSendHSFeedback(bool immed) { TimestampTz now; + FullTransactionId nextFullXid; TransactionId nextXid; uint32 xmin_epoch, catalog_xmin_epoch; @@ -1272,7 +1207,9 @@ XLogWalRcvSendHSFeedback(bool immed) * Get epoch and adjust if nextXid and oldestXmin are different sides of * the epoch boundary. */ - GetNextXidAndEpoch(&nextXid, &xmin_epoch); + nextFullXid = ReadNextFullTransactionId(); + nextXid = XidFromFullTransactionId(nextFullXid); + xmin_epoch = EpochFromFullTransactionId(nextFullXid); catalog_xmin_epoch = xmin_epoch; if (nextXid < xmin) xmin_epoch--; @@ -1461,8 +1398,8 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) { /* * Only superusers and members of pg_read_all_stats can see details. - * Other users only get the pid value - * to know whether it is a WAL receiver, but no details. + * Other users only get the pid value to know whether it is a WAL + * receiver, but no details. */ MemSet(&nulls[1], true, sizeof(bool) * (tupdesc->natts - 1)); } diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c index 67b1a074cce..2d6cdfe0a21 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -6,7 +6,7 @@ * with the walreceiver process. Functions implementing walreceiver itself * are in walreceiver.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 642e859439f..eb4a98cc912 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -37,7 +37,7 @@ * record, wait for it to be replicated to the standby, and then exit. * * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/replication/walsender.c @@ -90,7 +90,6 @@ #include "utils/pg_lsn.h" #include "utils/portal.h" #include "utils/ps_status.h" -#include "utils/resowner.h" #include "utils/timeout.h" #include "utils/timestamp.h" @@ -129,16 +128,8 @@ bool log_replication_commands = false; */ bool wake_wal_senders = false; -/* - * These variables are used similarly to openLogFile/SegNo/Off, - * but for walsender to read the XLOG. - */ -static int sendFile = -1; -static XLogSegNo sendSegNo = 0; -static uint32 sendOff = 0; - -/* Timeline ID of the currently open file */ -static TimeLineID curFileTimeLine = 0; +static WALOpenSegment *sendSeg = NULL; +static WALSegmentContext *sendCxt = NULL; /* * These variables keep track of the state of the timeline we're currently @@ -162,9 +153,12 @@ static StringInfoData output_message; static StringInfoData reply_message; static StringInfoData tmpbuf; +/* Timestamp of last ProcessRepliesIfAny(). */ +static TimestampTz last_processing = 0; + /* - * Timestamp of the last receipt of the reply from the standby. Set to 0 if - * wal_sender_timeout doesn't need to be active. + * Timestamp of last ProcessRepliesIfAny() that saw a reply from the + * standby. Set to 0 if wal_sender_timeout doesn't need to be active. */ static TimestampTz last_reply_timestamp = 0; @@ -209,14 +203,16 @@ typedef struct #define LAG_TRACKER_BUFFER_SIZE 8192 /* A mechanism for tracking replication lag. */ -static struct +typedef struct { XLogRecPtr last_lsn; WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]; int write_head; int read_heads[NUM_SYNC_REP_WAIT_MODE]; WalTimeSample last_read[NUM_SYNC_REP_WAIT_MODE]; -} LagTracker; +} LagTracker; + +static LagTracker *lag_tracker; /* Signal handlers */ static void WalSndLastCycleHandler(SIGNAL_ARGS); @@ -241,8 +237,8 @@ static void ProcessStandbyReplyMessage(void); static void ProcessStandbyHSFeedbackMessage(void); static void ProcessRepliesIfAny(void); static void WalSndKeepalive(bool requestReply); -static void WalSndKeepaliveIfNecessary(TimestampTz now); -static void WalSndCheckTimeOut(TimestampTz now); +static void WalSndKeepaliveIfNecessary(void); +static void WalSndCheckTimeOut(void); static long WalSndComputeSleeptime(TimestampTz now); static void WalSndPrepareWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write); static void WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write); @@ -252,7 +248,7 @@ static void LagTrackerWrite(XLogRecPtr lsn, TimestampTz local_flush_time); static TimeOffset LagTrackerRead(int head, XLogRecPtr lsn, TimestampTz now); static bool TransactionIdInRecentPast(TransactionId xid, uint32 epoch); -static void XLogRead(char *buf, XLogRecPtr startptr, Size count); +static void XLogRead(WALSegmentContext *segcxt, char *buf, XLogRecPtr startptr, Size count); /* Initialize walsender process before entering the main command loop */ @@ -264,8 +260,10 @@ InitWalSender(void) /* Create a per-walsender data structure in shared memory */ InitWalSenderSlot(); - /* Set up resource owner */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "walsender top-level resource owner"); + /* + * We don't currently need any ResourceOwner in a walsender process, but + * if we did, we could call CreateAuxProcessResourceOwner here. + */ /* * Let postmaster know that we're a WAL sender. Once we've declared us as @@ -278,7 +276,14 @@ InitWalSender(void) SendPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE); /* Initialize empty timestamp buffer for lag tracking. */ - memset(&LagTracker, 0, sizeof(LagTracker)); + lag_tracker = MemoryContextAllocZero(TopMemoryContext, sizeof(LagTracker)); + + /* Make sure we can remember the current read position in XLOG. */ + sendSeg = (WALOpenSegment *) + MemoryContextAlloc(TopMemoryContext, sizeof(WALOpenSegment)); + sendCxt = (WALSegmentContext *) + MemoryContextAlloc(TopMemoryContext, sizeof(WALSegmentContext)); + WALOpenSegmentInit(sendSeg, sendCxt, wal_segment_size, NULL); } /* @@ -295,10 +300,10 @@ WalSndErrorCleanup(void) ConditionVariableCancelSleep(); pgstat_report_wait_end(); - if (sendFile >= 0) + if (sendSeg->ws_file >= 0) { - close(sendFile); - sendFile = -1; + close(sendSeg->ws_file); + sendSeg->ws_file = -1; } if (MyReplicationSlot != NULL) @@ -386,7 +391,7 @@ IdentifySystem(void) MemSet(nulls, false, sizeof(nulls)); /* need a tuple descriptor representing four columns */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "systemid", TEXTOID, -1, 0); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "timeline", @@ -397,7 +402,7 @@ IdentifySystem(void) TEXTOID, -1, 0); /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc); + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); /* column 1: system identifier */ values[0] = CStringGetTextDatum(sysid); @@ -495,21 +500,31 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd) bytesleft = histfilelen; while (bytesleft > 0) { - char rbuf[BLCKSZ]; + PGAlignedBlock rbuf; int nread; pgstat_report_wait_start(WAIT_EVENT_WALSENDER_TIMELINE_HISTORY_READ); - nread = read(fd, rbuf, sizeof(rbuf)); + nread = read(fd, rbuf.data, sizeof(rbuf)); pgstat_report_wait_end(); - if (nread <= 0) + if (nread < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not read file \"%s\": %m", path))); - pq_sendbytes(&buf, rbuf, nread); + else if (nread == 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + path, nread, (Size) bytesleft))); + + pq_sendbytes(&buf, rbuf.data, nread); bytesleft -= nread; } - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", path))); pq_endmessage(&buf); } @@ -716,14 +731,14 @@ StartReplication(StartReplicationCmd *cmd) * like a surprising data type for this, but in theory int4 would not * be wide enough for this, as TimeLineID is unsigned. */ - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "next_tli", INT8OID, -1, 0); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "next_tli_startpos", TEXTOID, -1, 0); /* prepare for projection of tuple */ - tstate = begin_tup_output_tupdesc(dest, tupdesc); + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); values[0] = Int64GetDatum((int64) sendTimeLineNextTLI); values[1] = CStringGetTextDatum(startpos_str); @@ -747,7 +762,7 @@ StartReplication(StartReplicationCmd *cmd) */ static int logical_read_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, - XLogRecPtr targetRecPtr, char *cur_page, TimeLineID *pageTLI) + XLogRecPtr targetRecPtr, char *cur_page) { XLogRecPtr flushptr; int count; @@ -771,7 +786,7 @@ logical_read_xlog_page(XLogReaderState *state, XLogRecPtr targetPagePtr, int req count = flushptr - targetPagePtr; /* part of the page available */ /* now actually read the data, we know it's there */ - XLogRead(cur_page, targetPagePtr, XLOG_BLCKSZ); + XLogRead(sendCxt, cur_page, targetPagePtr, XLOG_BLCKSZ); return count; } @@ -850,7 +865,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) parseCreateReplSlotOptions(cmd, &reserve_wal, &snapshot_action); - /* setup state for XLogReadPage */ + /* setup state for XLogRead */ sendTimeLineIsHistoric = false; sendTimeLine = ThisTimeLineID; @@ -887,8 +902,9 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) { if (IsTransactionBlock()) ereport(ERROR, - (errmsg("CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT " - "must not be called inside a transaction"))); + /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ + (errmsg("%s must not be called inside a transaction", + "CREATE_REPLICATION_SLOT ... EXPORT_SNAPSHOT"))); need_full_snapshot = true; } @@ -896,28 +912,33 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) { if (!IsTransactionBlock()) ereport(ERROR, - (errmsg("CREATE_REPLICATION_SLOT ... USE_SNAPSHOT " - "must be called inside a transaction"))); + /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ + (errmsg("%s must be called inside a transaction", + "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); if (XactIsoLevel != XACT_REPEATABLE_READ) ereport(ERROR, - (errmsg("CREATE_REPLICATION_SLOT ... USE_SNAPSHOT " - "must be called in REPEATABLE READ isolation mode transaction"))); + /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ + (errmsg("%s must be called in REPEATABLE READ isolation mode transaction", + "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); if (FirstSnapshotSet) ereport(ERROR, - (errmsg("CREATE_REPLICATION_SLOT ... USE_SNAPSHOT " - "must be called before any query"))); + /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ + (errmsg("%s must be called before any query", + "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); if (IsSubTransaction()) ereport(ERROR, - (errmsg("CREATE_REPLICATION_SLOT ... USE_SNAPSHOT " - "must not be called in a subtransaction"))); + /*- translator: %s is a CREATE_REPLICATION_SLOT statement */ + (errmsg("%s must not be called in a subtransaction", + "CREATE_REPLICATION_SLOT ... USE_SNAPSHOT"))); need_full_snapshot = true; } ctx = CreateInitDecodingContext(cmd->plugin, NIL, need_full_snapshot, + InvalidXLogRecPtr, logical_read_xlog_page, WalSndPrepareWrite, WalSndWriteData, WalSndUpdateProgress); @@ -984,7 +1005,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) * - fourth field: output plugin *---------- */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "slot_name", TEXTOID, -1, 0); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "consistent_point", @@ -995,7 +1016,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd) TEXTOID, -1, 0); /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc); + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); /* slot_name */ slot_name = NameStr(MyReplicationSlot->data.name); @@ -1061,6 +1082,20 @@ StartLogicalReplication(StartReplicationCmd *cmd) got_STOPPING = true; } + /* + * Create our decoding context, making it start at the previously ack'ed + * position. + * + * Do this before sending a CopyBothResponse message, so that any errors + * are reported early. + */ + logical_decoding_ctx = + CreateDecodingContext(cmd->startpoint, cmd->options, false, + logical_read_xlog_page, + WalSndPrepareWrite, WalSndWriteData, + WalSndUpdateProgress); + + WalSndSetState(WALSNDSTATE_CATCHUP); /* Send a CopyBothResponse message, and start streaming */ @@ -1070,16 +1105,6 @@ StartLogicalReplication(StartReplicationCmd *cmd) pq_endmessage(&buf); pq_flush(); - /* - * Initialize position to the last ack'ed one, then the xlog records begin - * to be shipped from that position. - */ - logical_decoding_ctx = CreateDecodingContext(cmd->startpoint, cmd->options, - false, - logical_read_xlog_page, - WalSndPrepareWrite, - WalSndWriteData, - WalSndUpdateProgress); /* Start reading WAL from the oldest required WAL. */ logical_startptr = MyReplicationSlot->data.restart_lsn; @@ -1153,7 +1178,7 @@ static void WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write) { - TimestampTz now; + TimestampTz now; /* output previously gathered data in a CopyData packet */ pq_putmessage_noblock('d', ctx->out->data, ctx->out->len); @@ -1192,33 +1217,24 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, /* Check for input from the client */ ProcessRepliesIfAny(); - now = GetCurrentTimestamp(); - /* die if timeout was reached */ - WalSndCheckTimeOut(now); + WalSndCheckTimeOut(); /* Send keepalive if the time has come */ - WalSndKeepaliveIfNecessary(now); + WalSndKeepaliveIfNecessary(); if (!pq_is_send_pending()) break; - sleeptime = WalSndComputeSleeptime(now); + sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); - wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | + wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_SOCKET_WRITEABLE | WL_SOCKET_READABLE | WL_TIMEOUT; /* Sleep until something happens or we time out */ - WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_WRITE_DATA); - - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (!PostmasterIsAlive()) - exit(1); + (void) WaitLatchOrSocket(MyLatch, wakeEvents, + MyProcPort->sock, sleeptime, + WAIT_EVENT_WAL_SENDER_WRITE_DATA); /* Clear any already-pending wakeups */ ResetLatch(MyLatch); @@ -1298,14 +1314,6 @@ WalSndWaitForWal(XLogRecPtr loc) for (;;) { long sleeptime; - TimestampTz now; - - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (!PostmasterIsAlive()) - exit(1); /* Clear any already-pending wakeups */ ResetLatch(MyLatch); @@ -1383,13 +1391,11 @@ WalSndWaitForWal(XLogRecPtr loc) !pq_is_send_pending()) break; - now = GetCurrentTimestamp(); - /* die if timeout was reached */ - WalSndCheckTimeOut(now); + WalSndCheckTimeOut(); /* Send keepalive if the time has come */ - WalSndKeepaliveIfNecessary(now); + WalSndKeepaliveIfNecessary(); /* * Sleep until something happens or we time out. Also wait for the @@ -1398,17 +1404,17 @@ WalSndWaitForWal(XLogRecPtr loc) * new WAL to be generated. (But if we have nothing to send, we don't * want to wake on socket-writable.) */ - sleeptime = WalSndComputeSleeptime(now); + sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); - wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | + wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | WL_TIMEOUT; if (pq_is_send_pending()) wakeEvents |= WL_SOCKET_WRITEABLE; - WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_WAIT_WAL); + (void) WaitLatchOrSocket(MyLatch, wakeEvents, + MyProcPort->sock, sleeptime, + WAIT_EVENT_WAL_SENDER_WAIT_WAL); } /* reactivate latch so WalSndLoop knows to continue */ @@ -1551,7 +1557,10 @@ exec_replication_command(const char *cmd_string) DestReceiver *dest = CreateDestReceiver(DestRemoteSimple); VariableShowStmt *n = (VariableShowStmt *) cmd_node; + /* syscache access needs a transaction environment */ + StartTransactionCommand(); GetPGVariable(n->name, dest); + CommitTransactionCommand(); } break; @@ -1595,6 +1604,8 @@ ProcessRepliesIfAny(void) int r; bool received = false; + last_processing = GetCurrentTimestamp(); + for (;;) { pq_startmsgread(); @@ -1682,7 +1693,7 @@ ProcessRepliesIfAny(void) */ if (received) { - last_reply_timestamp = GetCurrentTimestamp(); + last_reply_timestamp = last_processing; waiting_for_ping_response = false; } } @@ -1765,6 +1776,7 @@ ProcessStandbyReplyMessage(void) applyLag; bool clearLagTimes; TimestampTz now; + TimestampTz replyTime; static bool fullyAppliedLastTime = false; @@ -1772,14 +1784,25 @@ ProcessStandbyReplyMessage(void) writePtr = pq_getmsgint64(&reply_message); flushPtr = pq_getmsgint64(&reply_message); applyPtr = pq_getmsgint64(&reply_message); - (void) pq_getmsgint64(&reply_message); /* sendTime; not used ATM */ + replyTime = pq_getmsgint64(&reply_message); replyRequested = pq_getmsgbyte(&reply_message); - elog(DEBUG2, "write %X/%X flush %X/%X apply %X/%X%s", - (uint32) (writePtr >> 32), (uint32) writePtr, - (uint32) (flushPtr >> 32), (uint32) flushPtr, - (uint32) (applyPtr >> 32), (uint32) applyPtr, - replyRequested ? " (reply requested)" : ""); + if (log_min_messages <= DEBUG2) + { + char *replyTimeStr; + + /* Copy because timestamptz_to_str returns a static buffer */ + replyTimeStr = pstrdup(timestamptz_to_str(replyTime)); + + elog(DEBUG2, "write %X/%X flush %X/%X apply %X/%X%s reply_time %s", + (uint32) (writePtr >> 32), (uint32) writePtr, + (uint32) (flushPtr >> 32), (uint32) flushPtr, + (uint32) (applyPtr >> 32), (uint32) applyPtr, + replyRequested ? " (reply requested)" : "", + replyTimeStr); + + pfree(replyTimeStr); + } /* See if we can compute the round-trip lag for these positions. */ now = GetCurrentTimestamp(); @@ -1826,6 +1849,7 @@ ProcessStandbyReplyMessage(void) walsnd->flushLag = flushLag; if (applyLag != -1 || clearLagTimes) walsnd->applyLag = applyLag; + walsnd->replyTime = replyTime; SpinLockRelease(&walsnd->mutex); } @@ -1897,10 +1921,13 @@ PhysicalReplicationSlotNewXmin(TransactionId feedbackXmin, TransactionId feedbac static bool TransactionIdInRecentPast(TransactionId xid, uint32 epoch) { + FullTransactionId nextFullXid; TransactionId nextXid; uint32 nextEpoch; - GetNextXidAndEpoch(&nextXid, &nextEpoch); + nextFullXid = ReadNextFullTransactionId(); + nextXid = XidFromFullTransactionId(nextFullXid); + nextEpoch = EpochFromFullTransactionId(nextFullXid); if (xid <= nextXid) { @@ -1929,23 +1956,47 @@ ProcessStandbyHSFeedbackMessage(void) uint32 feedbackEpoch; TransactionId feedbackCatalogXmin; uint32 feedbackCatalogEpoch; + TimestampTz replyTime; /* * Decipher the reply message. The caller already consumed the msgtype * byte. See XLogWalRcvSendHSFeedback() in walreceiver.c for the creation * of this message. */ - (void) pq_getmsgint64(&reply_message); /* sendTime; not used ATM */ + replyTime = pq_getmsgint64(&reply_message); feedbackXmin = pq_getmsgint(&reply_message, 4); feedbackEpoch = pq_getmsgint(&reply_message, 4); feedbackCatalogXmin = pq_getmsgint(&reply_message, 4); feedbackCatalogEpoch = pq_getmsgint(&reply_message, 4); - elog(DEBUG2, "hot standby feedback xmin %u epoch %u, catalog_xmin %u epoch %u", - feedbackXmin, - feedbackEpoch, - feedbackCatalogXmin, - feedbackCatalogEpoch); + if (log_min_messages <= DEBUG2) + { + char *replyTimeStr; + + /* Copy because timestamptz_to_str returns a static buffer */ + replyTimeStr = pstrdup(timestamptz_to_str(replyTime)); + + elog(DEBUG2, "hot standby feedback xmin %u epoch %u, catalog_xmin %u epoch %u reply_time %s", + feedbackXmin, + feedbackEpoch, + feedbackCatalogXmin, + feedbackCatalogEpoch, + replyTimeStr); + + pfree(replyTimeStr); + } + + /* + * Update shared state for this WalSender process based on reply data from + * standby. + */ + { + WalSnd *walsnd = MyWalSnd; + + SpinLockAcquire(&walsnd->mutex); + walsnd->replyTime = replyTime; + SpinLockRelease(&walsnd->mutex); + } /* * Unset WalSender's xmins if the feedback message values are invalid. @@ -2061,10 +2112,18 @@ WalSndComputeSleeptime(TimestampTz now) /* * Check whether there have been responses by the client within - * wal_sender_timeout and shutdown if not. + * wal_sender_timeout and shutdown if not. Using last_processing as the + * reference point avoids counting server-side stalls against the client. + * However, a long server-side stall can make WalSndKeepaliveIfNecessary() + * postdate last_processing by more than wal_sender_timeout. If that happens, + * the client must reply almost immediately to avoid a timeout. This rarely + * affects the default configuration, under which clients spontaneously send a + * message every standby_message_timeout = wal_sender_timeout/6 = 10s. We + * could eliminate that problem by recognizing timeout expiration at + * wal_sender_timeout/2 after the keepalive. */ static void -WalSndCheckTimeOut(TimestampTz now) +WalSndCheckTimeOut(void) { TimestampTz timeout; @@ -2075,7 +2134,7 @@ WalSndCheckTimeOut(TimestampTz now) timeout = TimestampTzPlusMilliseconds(last_reply_timestamp, wal_sender_timeout); - if (wal_sender_timeout > 0 && now >= timeout) + if (wal_sender_timeout > 0 && last_processing >= timeout) { /* * Since typically expiration of replication timeout means @@ -2106,15 +2165,6 @@ WalSndLoop(WalSndSendDataCallback send_data) */ for (;;) { - TimestampTz now; - - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - if (!PostmasterIsAlive()) - exit(1); - /* Clear any already-pending wakeups */ ResetLatch(MyLatch); @@ -2169,7 +2219,7 @@ WalSndLoop(WalSndSendDataCallback send_data) if (MyWalSnd->state == WALSNDSTATE_CATCHUP) { ereport(DEBUG1, - (errmsg("standby \"%s\" has now caught up with primary", + (errmsg("\"%s\" has now caught up with upstream server", application_name))); WalSndSetState(WALSNDSTATE_STREAMING); } @@ -2185,13 +2235,11 @@ WalSndLoop(WalSndSendDataCallback send_data) WalSndDone(send_data); } - now = GetCurrentTimestamp(); - /* Check for replication timeout. */ - WalSndCheckTimeOut(now); + WalSndCheckTimeOut(); /* Send keepalive if the time has come */ - WalSndKeepaliveIfNecessary(now); + WalSndKeepaliveIfNecessary(); /* * We don't block if not caught up, unless there is unsent data @@ -2206,18 +2254,22 @@ WalSndLoop(WalSndSendDataCallback send_data) long sleeptime; int wakeEvents; - wakeEvents = WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT | + wakeEvents = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH | WL_TIMEOUT | WL_SOCKET_READABLE; - sleeptime = WalSndComputeSleeptime(now); + /* + * Use fresh timestamp, not last_processing, to reduce the chance + * of reaching wal_sender_timeout before sending a keepalive. + */ + sleeptime = WalSndComputeSleeptime(GetCurrentTimestamp()); if (pq_is_send_pending()) wakeEvents |= WL_SOCKET_WRITEABLE; /* Sleep until something happens or we time out */ - WaitLatchOrSocket(MyLatch, wakeEvents, - MyProcPort->sock, sleeptime, - WAIT_EVENT_WAL_SENDER_MAIN); + (void) WaitLatchOrSocket(MyLatch, wakeEvents, + MyProcPort->sock, sleeptime, + WAIT_EVENT_WAL_SENDER_MAIN); } } return; @@ -2237,8 +2289,8 @@ InitWalSenderSlot(void) Assert(MyWalSnd == NULL); /* - * Find a free walsender slot and reserve it. If this fails, we must be - * out of WalSnd structures. + * Find a free walsender slot and reserve it. This must not fail due to + * the prior check for free WAL senders in InitProcess(). */ for (i = 0; i < max_wal_senders; i++) { @@ -2266,6 +2318,7 @@ InitWalSenderSlot(void) walsnd->applyLag = -1; walsnd->state = WALSNDSTATE_STARTUP; walsnd->latch = &MyProc->procLatch; + walsnd->replyTime = 0; SpinLockRelease(&walsnd->mutex); /* don't need the lock anymore */ MyWalSnd = (WalSnd *) walsnd; @@ -2273,12 +2326,8 @@ InitWalSenderSlot(void) break; } } - if (MyWalSnd == NULL) - ereport(FATAL, - (errcode(ERRCODE_TOO_MANY_CONNECTIONS), - errmsg("number of requested standby connections " - "exceeds max_wal_senders (currently %d)", - max_wal_senders))); + + Assert(MyWalSnd != NULL); /* Arrange to clean up at walsender exit */ on_shmem_exit(WalSndKill, 0); @@ -2314,7 +2363,7 @@ WalSndKill(int code, Datum arg) * more than one. */ static void -XLogRead(char *buf, XLogRecPtr startptr, Size count) +XLogRead(WALSegmentContext *segcxt, char *buf, XLogRecPtr startptr, Size count) { char *p; XLogRecPtr recptr; @@ -2332,17 +2381,18 @@ XLogRead(char *buf, XLogRecPtr startptr, Size count) int segbytes; int readbytes; - startoff = XLogSegmentOffset(recptr, wal_segment_size); + startoff = XLogSegmentOffset(recptr, segcxt->ws_segsize); - if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo, wal_segment_size)) + if (sendSeg->ws_file < 0 || + !XLByteInSeg(recptr, sendSeg->ws_segno, segcxt->ws_segsize)) { char path[MAXPGPATH]; /* Switch to another logfile segment */ - if (sendFile >= 0) - close(sendFile); + if (sendSeg->ws_file >= 0) + close(sendSeg->ws_file); - XLByteToSeg(recptr, sendSegNo, wal_segment_size); + XLByteToSeg(recptr, sendSeg->ws_segno, segcxt->ws_segsize); /*------- * When reading from a historic timeline, and there is a timeline @@ -2370,20 +2420,20 @@ XLogRead(char *buf, XLogRecPtr startptr, Size count) * used portion of the old segment is copied to the new file. *------- */ - curFileTimeLine = sendTimeLine; + sendSeg->ws_tli = sendTimeLine; if (sendTimeLineIsHistoric) { XLogSegNo endSegNo; - XLByteToSeg(sendTimeLineValidUpto, endSegNo, wal_segment_size); - if (sendSegNo == endSegNo) - curFileTimeLine = sendTimeLineNextTLI; + XLByteToSeg(sendTimeLineValidUpto, endSegNo, segcxt->ws_segsize); + if (sendSeg->ws_segno == endSegNo) + sendSeg->ws_tli = sendTimeLineNextTLI; } - XLogFilePath(path, curFileTimeLine, sendSegNo, wal_segment_size); + XLogFilePath(path, sendSeg->ws_tli, sendSeg->ws_segno, segcxt->ws_segsize); - sendFile = BasicOpenFile(path, O_RDONLY | PG_BINARY); - if (sendFile < 0) + sendSeg->ws_file = BasicOpenFile(path, O_RDONLY | PG_BINARY); + if (sendSeg->ws_file < 0) { /* * If the file is not found, assume it's because the standby @@ -2394,50 +2444,58 @@ XLogRead(char *buf, XLogRecPtr startptr, Size count) ereport(ERROR, (errcode_for_file_access(), errmsg("requested WAL segment %s has already been removed", - XLogFileNameP(curFileTimeLine, sendSegNo)))); + XLogFileNameP(sendSeg->ws_tli, sendSeg->ws_segno)))); else ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", path))); } - sendOff = 0; + sendSeg->ws_off = 0; } /* Need to seek in the file? */ - if (sendOff != startoff) + if (sendSeg->ws_off != startoff) { - if (lseek(sendFile, (off_t) startoff, SEEK_SET) < 0) + if (lseek(sendSeg->ws_file, (off_t) startoff, SEEK_SET) < 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not seek in log segment %s to offset %u: %m", - XLogFileNameP(curFileTimeLine, sendSegNo), + XLogFileNameP(sendSeg->ws_tli, sendSeg->ws_segno), startoff))); - sendOff = startoff; + sendSeg->ws_off = startoff; } /* How many bytes are within this segment? */ - if (nbytes > (wal_segment_size - startoff)) - segbytes = wal_segment_size - startoff; + if (nbytes > (segcxt->ws_segsize - startoff)) + segbytes = segcxt->ws_segsize - startoff; else segbytes = nbytes; pgstat_report_wait_start(WAIT_EVENT_WAL_READ); - readbytes = read(sendFile, p, segbytes); + readbytes = read(sendSeg->ws_file, p, segbytes); pgstat_report_wait_end(); - if (readbytes <= 0) + if (readbytes < 0) { ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read from log segment %s, offset %u, length %lu: %m", - XLogFileNameP(curFileTimeLine, sendSegNo), - sendOff, (unsigned long) segbytes))); + errmsg("could not read from log segment %s, offset %u, length %zu: %m", + XLogFileNameP(sendSeg->ws_tli, sendSeg->ws_segno), + sendSeg->ws_off, (Size) segbytes))); + } + else if (readbytes == 0) + { + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read from log segment %s, offset %u: read %d of %zu", + XLogFileNameP(sendSeg->ws_tli, sendSeg->ws_segno), + sendSeg->ws_off, readbytes, (Size) segbytes))); } /* Update state for read */ recptr += readbytes; - sendOff += readbytes; + sendSeg->ws_off += readbytes; nbytes -= readbytes; p += readbytes; } @@ -2449,7 +2507,7 @@ XLogRead(char *buf, XLogRecPtr startptr, Size count) * read() succeeds in that case, but the data we tried to read might * already have been overwritten with new WAL records. */ - XLByteToSeg(startptr, segno, wal_segment_size); + XLByteToSeg(startptr, segno, segcxt->ws_segsize); CheckXLogRemoved(segno, ThisTimeLineID); /* @@ -2468,10 +2526,10 @@ XLogRead(char *buf, XLogRecPtr startptr, Size count) walsnd->needreload = false; SpinLockRelease(&walsnd->mutex); - if (reload && sendFile >= 0) + if (reload && sendSeg->ws_file >= 0) { - close(sendFile); - sendFile = -1; + close(sendSeg->ws_file); + sendSeg->ws_file = -1; goto retry; } @@ -2608,7 +2666,7 @@ XLogSendPhysical(void) * very close to together here so that we'll get a later position if it is * still moving. * - * Because LagTrackerWriter ignores samples when the LSN hasn't advanced, + * Because LagTrackerWrite ignores samples when the LSN hasn't advanced, * this gives us a cheap approximation for the WAL flush time for this * LSN. * @@ -2637,9 +2695,9 @@ XLogSendPhysical(void) if (sendTimeLineIsHistoric && sendTimeLineValidUpto <= sentPtr) { /* close the current file. */ - if (sendFile >= 0) - close(sendFile); - sendFile = -1; + if (sendSeg->ws_file >= 0) + close(sendSeg->ws_file); + sendSeg->ws_file = -1; /* Send CopyDone */ pq_putmessage_noblock('c', NULL, 0); @@ -2710,7 +2768,7 @@ XLogSendPhysical(void) * calls. */ enlargeStringInfo(&output_message, nbytes); - XLogRead(&output_message.data[output_message.len], startptr, nbytes); + XLogRead(sendCxt, &output_message.data[output_message.len], startptr, nbytes); output_message.len += nbytes; output_message.data[output_message.len] = '\0'; @@ -2758,10 +2816,10 @@ XLogSendLogical(void) char *errm; /* - * Don't know whether we've caught up yet. We'll set it to true in - * WalSndWaitForWal, if we're actually waiting. We also set to true if - * XLogReadRecord() had to stop reading but WalSndWaitForWal didn't wait - - * i.e. when we're shutting down. + * Don't know whether we've caught up yet. We'll set WalSndCaughtUp to + * true in WalSndWaitForWal, if we're actually waiting. We also set to + * true if XLogReadRecord() had to stop reading but WalSndWaitForWal + * didn't wait - i.e. when we're shutting down. */ WalSndCaughtUp = false; @@ -2774,6 +2832,9 @@ XLogSendLogical(void) if (record != NULL) { + /* XXX: Note that logical decoding cannot be used while in recovery */ + XLogRecPtr flushPtr = GetFlushRecPtr(); + /* * Note the lack of any call to LagTrackerWrite() which is handled by * WalSndUpdateProgress which is called by output plugin through @@ -2782,6 +2843,13 @@ XLogSendLogical(void) LogicalDecodingProcessRecord(logical_decoding_ctx, logical_decoding_ctx->reader); sentPtr = logical_decoding_ctx->reader->EndRecPtr; + + /* + * If we have sent a record that is at or beyond the flushed point, we + * have caught up. + */ + if (sentPtr >= flushPtr) + WalSndCaughtUp = true; } else { @@ -2965,10 +3033,6 @@ WalSndSignals(void) /* Reset some signals that are accepted by postmaster but not here */ pqsignal(SIGCHLD, SIG_DFL); - pqsignal(SIGTTIN, SIG_DFL); - pqsignal(SIGTTOU, SIG_DFL); - pqsignal(SIGCONT, SIG_DFL); - pqsignal(SIGWINCH, SIG_DFL); } /* Report shared-memory space needed by WalSndShmemInit */ @@ -3166,7 +3230,7 @@ offset_to_interval(TimeOffset offset) Datum pg_stat_get_wal_senders(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_WAL_SENDERS_COLS 11 +#define PG_STAT_GET_WAL_SENDERS_COLS 12 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; TupleDesc tupdesc; Tuplestorestate *tupstore; @@ -3220,6 +3284,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) int priority; int pid; WalSndState state; + TimestampTz replyTime; Datum values[PG_STAT_GET_WAL_SENDERS_COLS]; bool nulls[PG_STAT_GET_WAL_SENDERS_COLS]; @@ -3239,6 +3304,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) flushLag = walsnd->flushLag; applyLag = walsnd->applyLag; priority = walsnd->sync_standby_priority; + replyTime = walsnd->replyTime; SpinLockRelease(&walsnd->mutex); memset(nulls, 0, sizeof(nulls)); @@ -3247,9 +3313,9 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) if (!is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) { /* - * Only superusers and members of pg_read_all_stats can see details. - * Other users only get the pid value to know it's a walsender, - * but no details. + * Only superusers and members of pg_read_all_stats can see + * details. Other users only get the pid value to know it's a + * walsender, but no details. */ MemSet(&nulls[1], true, PG_STAT_GET_WAL_SENDERS_COLS - 1); } @@ -3315,6 +3381,11 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) CStringGetTextDatum("sync") : CStringGetTextDatum("quorum"); else values[10] = CStringGetTextDatum("potential"); + + if (replyTime == 0) + nulls[11] = true; + else + values[11] = TimestampTzGetDatum(replyTime); } tuplestore_putvalues(tupstore, tupdesc, values, nulls); @@ -3351,7 +3422,7 @@ WalSndKeepalive(bool requestReply) * Send keepalive message if too much time has elapsed. */ static void -WalSndKeepaliveIfNecessary(TimestampTz now) +WalSndKeepaliveIfNecessary(void) { TimestampTz ping_time; @@ -3372,7 +3443,7 @@ WalSndKeepaliveIfNecessary(TimestampTz now) */ ping_time = TimestampTzPlusMilliseconds(last_reply_timestamp, wal_sender_timeout / 2); - if (now >= ping_time) + if (last_processing >= ping_time) { WalSndKeepalive(true); waiting_for_ping_response = true; @@ -3403,9 +3474,9 @@ LagTrackerWrite(XLogRecPtr lsn, TimestampTz local_flush_time) * If the lsn hasn't advanced since last time, then do nothing. This way * we only record a new sample when new WAL has been written. */ - if (LagTracker.last_lsn == lsn) + if (lag_tracker->last_lsn == lsn) return; - LagTracker.last_lsn = lsn; + lag_tracker->last_lsn = lsn; /* * If advancing the write head of the circular buffer would crash into any @@ -3413,11 +3484,11 @@ LagTrackerWrite(XLogRecPtr lsn, TimestampTz local_flush_time) * slowest reader (presumably apply) is the one that controls the release * of space. */ - new_write_head = (LagTracker.write_head + 1) % LAG_TRACKER_BUFFER_SIZE; + new_write_head = (lag_tracker->write_head + 1) % LAG_TRACKER_BUFFER_SIZE; buffer_full = false; for (i = 0; i < NUM_SYNC_REP_WAIT_MODE; ++i) { - if (new_write_head == LagTracker.read_heads[i]) + if (new_write_head == lag_tracker->read_heads[i]) buffer_full = true; } @@ -3428,17 +3499,17 @@ LagTrackerWrite(XLogRecPtr lsn, TimestampTz local_flush_time) */ if (buffer_full) { - new_write_head = LagTracker.write_head; - if (LagTracker.write_head > 0) - LagTracker.write_head--; + new_write_head = lag_tracker->write_head; + if (lag_tracker->write_head > 0) + lag_tracker->write_head--; else - LagTracker.write_head = LAG_TRACKER_BUFFER_SIZE - 1; + lag_tracker->write_head = LAG_TRACKER_BUFFER_SIZE - 1; } /* Store a sample at the current write head position. */ - LagTracker.buffer[LagTracker.write_head].lsn = lsn; - LagTracker.buffer[LagTracker.write_head].time = local_flush_time; - LagTracker.write_head = new_write_head; + lag_tracker->buffer[lag_tracker->write_head].lsn = lsn; + lag_tracker->buffer[lag_tracker->write_head].time = local_flush_time; + lag_tracker->write_head = new_write_head; } /* @@ -3460,14 +3531,14 @@ LagTrackerRead(int head, XLogRecPtr lsn, TimestampTz now) TimestampTz time = 0; /* Read all unread samples up to this LSN or end of buffer. */ - while (LagTracker.read_heads[head] != LagTracker.write_head && - LagTracker.buffer[LagTracker.read_heads[head]].lsn <= lsn) + while (lag_tracker->read_heads[head] != lag_tracker->write_head && + lag_tracker->buffer[lag_tracker->read_heads[head]].lsn <= lsn) { - time = LagTracker.buffer[LagTracker.read_heads[head]].time; - LagTracker.last_read[head] = - LagTracker.buffer[LagTracker.read_heads[head]]; - LagTracker.read_heads[head] = - (LagTracker.read_heads[head] + 1) % LAG_TRACKER_BUFFER_SIZE; + time = lag_tracker->buffer[lag_tracker->read_heads[head]].time; + lag_tracker->last_read[head] = + lag_tracker->buffer[lag_tracker->read_heads[head]]; + lag_tracker->read_heads[head] = + (lag_tracker->read_heads[head] + 1) % LAG_TRACKER_BUFFER_SIZE; } /* @@ -3477,8 +3548,8 @@ LagTrackerRead(int head, XLogRecPtr lsn, TimestampTz now) * interpolation at the beginning of the next burst of WAL after a period * of idleness. */ - if (LagTracker.read_heads[head] == LagTracker.write_head) - LagTracker.last_read[head].time = 0; + if (lag_tracker->read_heads[head] == lag_tracker->write_head) + lag_tracker->last_read[head].time = 0; if (time > now) { @@ -3496,17 +3567,17 @@ LagTrackerRead(int head, XLogRecPtr lsn, TimestampTz now) * eventually start moving again and cross one of our samples before * we can show the lag increasing. */ - if (LagTracker.read_heads[head] == LagTracker.write_head) + if (lag_tracker->read_heads[head] == lag_tracker->write_head) { /* There are no future samples, so we can't interpolate. */ return -1; } - else if (LagTracker.last_read[head].time != 0) + else if (lag_tracker->last_read[head].time != 0) { /* We can interpolate between last_read and the next sample. */ double fraction; - WalTimeSample prev = LagTracker.last_read[head]; - WalTimeSample next = LagTracker.buffer[LagTracker.read_heads[head]]; + WalTimeSample prev = lag_tracker->last_read[head]; + WalTimeSample next = lag_tracker->buffer[lag_tracker->read_heads[head]]; if (lsn < prev.lsn) { @@ -3543,7 +3614,7 @@ LagTrackerRead(int head, XLogRecPtr lsn, TimestampTz now) * standby reaches the future sample the best we can do is report * the hypothetical lag if that sample were to be replayed now. */ - time = LagTracker.buffer[LagTracker.read_heads[head]].time; + time = lag_tracker->buffer[lag_tracker->read_heads[head]].time; } } diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index d81a2ea342b..7df2b6154cb 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -3,7 +3,7 @@ * rewriteDefine.c * routines for defining a rewrite rule * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,7 @@ #include "access/heapam.h" #include "access/htup_details.h" #include "access/multixact.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/catalog.h" @@ -41,11 +42,10 @@ #include "utils/rel.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" static void checkRuleResultList(List *targetList, TupleDesc resultDesc, - bool isSelect, bool requireColumnNameMatch); + bool isSelect, bool requireColumnNameMatch); static bool setRuleCheckAsUser_walker(Node *node, Oid *context); static void setRuleCheckAsUser_Query(Query *qry, Oid userid); @@ -95,7 +95,7 @@ InsertRule(const char *rulname, /* * Ready to store new pg_rewrite tuple */ - pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock); + pg_rewrite_desc = table_open(RewriteRelationId, RowExclusiveLock); /* * Check to see if we are replacing an existing tuple @@ -128,14 +128,19 @@ InsertRule(const char *rulname, ReleaseSysCache(oldtup); - rewriteObjectId = HeapTupleGetOid(tup); + rewriteObjectId = ((Form_pg_rewrite) GETSTRUCT(tup))->oid; is_update = true; } else { + rewriteObjectId = GetNewOidWithIndex(pg_rewrite_desc, + RewriteOidIndexId, + Anum_pg_rewrite_oid); + values[Anum_pg_rewrite_oid - 1] = ObjectIdGetDatum(rewriteObjectId); + tup = heap_form_tuple(pg_rewrite_desc->rd_att, values, nulls); - rewriteObjectId = CatalogTupleInsert(pg_rewrite_desc, tup); + CatalogTupleInsert(pg_rewrite_desc, tup); } @@ -181,7 +186,7 @@ InsertRule(const char *rulname, /* Post creation hook for new rule */ InvokeObjectPostCreateHook(RewriteRelationId, rewriteObjectId, 0); - heap_close(pg_rewrite_desc, RowExclusiveLock); + table_close(pg_rewrite_desc, RowExclusiveLock); return rewriteObjectId; } @@ -250,7 +255,7 @@ DefineQueryRewrite(const char *rulename, * * Note that this lock level should match the one used in DefineRule. */ - event_relation = heap_open(event_relid, AccessExclusiveLock); + event_relation = table_open(event_relid, AccessExclusiveLock); /* * Verify relation is of a type that rules can sensibly be applied to. @@ -419,8 +424,9 @@ DefineQueryRewrite(const char *rulename, if (event_relation->rd_rel->relkind != RELKIND_VIEW && event_relation->rd_rel->relkind != RELKIND_MATVIEW) { - HeapScanDesc scanDesc; + TableScanDesc scanDesc; Snapshot snapshot; + TupleTableSlot *slot; if (event_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) ereport(ERROR, @@ -435,13 +441,15 @@ DefineQueryRewrite(const char *rulename, RelationGetRelationName(event_relation)))); snapshot = RegisterSnapshot(GetLatestSnapshot()); - scanDesc = heap_beginscan(event_relation, snapshot, 0, NULL); - if (heap_getnext(scanDesc, ForwardScanDirection) != NULL) + scanDesc = table_beginscan(event_relation, snapshot, 0, NULL); + slot = table_slot_create(event_relation, NULL); + if (table_scan_getnextslot(scanDesc, ForwardScanDirection, slot)) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("could not convert table \"%s\" to a view because it is not empty", RelationGetRelationName(event_relation)))); - heap_endscan(scanDesc); + ExecDropSingleTupleTableSlot(slot); + table_endscan(scanDesc); UnregisterSnapshot(snapshot); if (event_relation->rd_rel->relhastriggers) @@ -560,7 +568,7 @@ DefineQueryRewrite(const char *rulename, HeapTuple classTup; Form_pg_class classForm; - relationRelation = heap_open(RelationRelationId, RowExclusiveLock); + relationRelation = table_open(RelationRelationId, RowExclusiveLock); toastrelid = event_relation->rd_rel->reltoastrelid; /* drop storage while table still looks like a table */ @@ -610,6 +618,7 @@ DefineQueryRewrite(const char *rulename, elog(ERROR, "cache lookup failed for relation %u", event_relid); classForm = (Form_pg_class) GETSTRUCT(classTup); + classForm->relam = InvalidOid; classForm->reltablespace = InvalidOid; classForm->relpages = 0; classForm->reltuples = 0; @@ -617,7 +626,6 @@ DefineQueryRewrite(const char *rulename, classForm->reltoastrelid = InvalidOid; classForm->relhasindex = false; classForm->relkind = RELKIND_VIEW; - classForm->relhasoids = false; classForm->relfrozenxid = InvalidTransactionId; classForm->relminmxid = InvalidMultiXactId; classForm->relreplident = REPLICA_IDENTITY_NOTHING; @@ -625,13 +633,13 @@ DefineQueryRewrite(const char *rulename, CatalogTupleUpdate(relationRelation, &classTup->t_self, classTup); heap_freetuple(classTup); - heap_close(relationRelation, RowExclusiveLock); + table_close(relationRelation, RowExclusiveLock); } ObjectAddressSet(address, RewriteRelationId, ruleId); /* Close rel, but keep lock till commit... */ - heap_close(event_relation, NoLock); + table_close(event_relation, NoLock); return address; } @@ -842,12 +850,13 @@ EnableDisableRule(Relation rel, const char *rulename, Oid owningRel = RelationGetRelid(rel); Oid eventRelationOid; HeapTuple ruletup; + Form_pg_rewrite ruleform; bool changed = false; /* * Find the rule tuple to change. */ - pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock); + pg_rewrite_desc = table_open(RewriteRelationId, RowExclusiveLock); ruletup = SearchSysCacheCopy2(RULERELNAME, ObjectIdGetDatum(owningRel), PointerGetDatum(rulename)); @@ -857,10 +866,12 @@ EnableDisableRule(Relation rel, const char *rulename, errmsg("rule \"%s\" for relation \"%s\" does not exist", rulename, get_rel_name(owningRel)))); + ruleform = (Form_pg_rewrite) GETSTRUCT(ruletup); + /* * Verify that the user has appropriate permissions. */ - eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_class; + eventRelationOid = ruleform->ev_class; Assert(eventRelationOid == owningRel); if (!pg_class_ownercheck(eventRelationOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(eventRelationOid)), @@ -869,21 +880,19 @@ EnableDisableRule(Relation rel, const char *rulename, /* * Change ev_enabled if it is different from the desired new state. */ - if (DatumGetChar(((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled) != + if (DatumGetChar(ruleform->ev_enabled) != fires_when) { - ((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled = - CharGetDatum(fires_when); + ruleform->ev_enabled = CharGetDatum(fires_when); CatalogTupleUpdate(pg_rewrite_desc, &ruletup->t_self, ruletup); changed = true; } - InvokeObjectPostAlterHook(RewriteRelationId, - HeapTupleGetOid(ruletup), 0); + InvokeObjectPostAlterHook(RewriteRelationId, ruleform->oid, 0); heap_freetuple(ruletup); - heap_close(pg_rewrite_desc, RowExclusiveLock); + table_close(pg_rewrite_desc, RowExclusiveLock); /* * If we changed anything, broadcast a SI inval message to force each @@ -959,7 +968,7 @@ RenameRewriteRule(RangeVar *relation, const char *oldName, targetrel = relation_open(relid, NoLock); /* Prepare to modify pg_rewrite */ - pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock); + pg_rewrite_desc = table_open(RewriteRelationId, RowExclusiveLock); /* Fetch the rule's entry (it had better exist) */ ruletup = SearchSysCacheCopy2(RULERELNAME, @@ -971,7 +980,7 @@ RenameRewriteRule(RangeVar *relation, const char *oldName, errmsg("rule \"%s\" for relation \"%s\" does not exist", oldName, RelationGetRelationName(targetrel)))); ruleform = (Form_pg_rewrite) GETSTRUCT(ruletup); - ruleOid = HeapTupleGetOid(ruletup); + ruleOid = ruleform->oid; /* rule with the new name should not already exist */ if (IsDefinedRewriteRule(relid, newName)) @@ -995,7 +1004,7 @@ RenameRewriteRule(RangeVar *relation, const char *oldName, CatalogTupleUpdate(pg_rewrite_desc, &ruletup->t_self, ruletup); heap_freetuple(ruletup); - heap_close(pg_rewrite_desc, RowExclusiveLock); + table_close(pg_rewrite_desc, RowExclusiveLock); /* * Invalidate relation's relcache entry so that other backends (and this diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index cb4bcd58d16..3e38007643e 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -3,7 +3,7 @@ * rewriteHandler.c * Primary module of query rewriter. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,7 +20,9 @@ */ #include "postgres.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/pg_type.h" #include "commands/trigger.h" @@ -29,6 +31,7 @@ #include "nodes/nodeFuncs.h" #include "parser/analyze.h" #include "parser/parse_coerce.h" +#include "parser/parse_relation.h" #include "parser/parsetree.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rewriteHandler.h" @@ -52,33 +55,31 @@ typedef struct acquireLocksOnSubLinks_context } acquireLocksOnSubLinks_context; static bool acquireLocksOnSubLinks(Node *node, - acquireLocksOnSubLinks_context *context); + acquireLocksOnSubLinks_context *context); static Query *rewriteRuleAction(Query *parsetree, - Query *rule_action, - Node *rule_qual, - int rt_index, - CmdType event, - bool *returning_flag); + Query *rule_action, + Node *rule_qual, + int rt_index, + CmdType event, + bool *returning_flag); static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index); static List *rewriteTargetListIU(List *targetList, - CmdType commandType, - OverridingKind override, - Relation target_relation, - int result_rti, - List **attrno_list); + CmdType commandType, + OverridingKind override, + Relation target_relation, + int result_rti); static TargetEntry *process_matched_tle(TargetEntry *src_tle, - TargetEntry *prior_tle, - const char *attrName); + TargetEntry *prior_tle, + const char *attrName); static Node *get_assignment_input(Node *node); -static void rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, - List *attrnos); +static bool rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, + Relation target_relation, bool force_nulls); static void markQueryForLocking(Query *qry, Node *jtnode, - LockClauseStrength strength, LockWaitPolicy waitPolicy, - bool pushedDown); + LockClauseStrength strength, LockWaitPolicy waitPolicy, + bool pushedDown); static List *matchLocks(CmdType event, RuleLock *rulelocks, - int varno, Query *parsetree, bool *hasUpdate); -static Query *fireRIRrules(Query *parsetree, List *activeRIRs, - bool forUpdatePushedDown); + int varno, Query *parsetree, bool *hasUpdate); +static Query *fireRIRrules(Query *parsetree, List *activeRIRs); static bool view_has_instead_trigger(Relation view, CmdType event); static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist); @@ -87,13 +88,14 @@ static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist); * AcquireRewriteLocks - * Acquire suitable locks on all the relations mentioned in the Query. * These locks will ensure that the relation schemas don't change under us - * while we are rewriting and planning the query. + * while we are rewriting, planning, and executing the query. * - * forExecute indicates that the query is about to be executed. - * If so, we'll acquire RowExclusiveLock on the query's resultRelation, - * RowShareLock on any relation accessed FOR [KEY] UPDATE/SHARE, and - * AccessShareLock on all other relations mentioned. + * Caution: this may modify the querytree, therefore caller should usually + * have done a copyObject() to make a writable copy of the querytree in the + * current memory context. * + * forExecute indicates that the query is about to be executed. If so, + * we'll acquire the lock modes specified in the RTE rellockmode fields. * If forExecute is false, AccessShareLock is acquired on all relations. * This case is suitable for ruleutils.c, for example, where we only need * schema stability and we don't intend to actually modify any relations. @@ -101,13 +103,11 @@ static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist); * forUpdatePushedDown indicates that a pushed-down FOR [KEY] UPDATE/SHARE * applies to the current subquery, requiring all rels to be opened with at * least RowShareLock. This should always be false at the top of the - * recursion. This flag is ignored if forExecute is false. + * recursion. When it is true, we adjust RTE rellockmode fields to reflect + * the higher lock level. This flag is ignored if forExecute is false. * * A secondary purpose of this routine is to fix up JOIN RTE references to - * dropped columns (see details below). Because the RTEs are modified in - * place, it is generally appropriate for the caller of this routine to have - * first done a copyObject() to make a writable copy of the querytree in the - * current memory context. + * dropped columns (see details below). Such RTEs are modified in-place. * * This processing can, and for efficiency's sake should, be skipped when the * querytree has just been built by the parser: parse analysis already got @@ -160,23 +160,26 @@ AcquireRewriteLocks(Query *parsetree, /* * Grab the appropriate lock type for the relation, and do not - * release it until end of transaction. This protects the - * rewriter and planner against schema changes mid-query. + * release it until end of transaction. This protects the + * rewriter, planner, and executor against schema changes + * mid-query. * - * Assuming forExecute is true, this logic must match what the - * executor will do, else we risk lock-upgrade deadlocks. + * If forExecute is false, ignore rellockmode and just use + * AccessShareLock. */ if (!forExecute) lockmode = AccessShareLock; - else if (rt_index == parsetree->resultRelation) - lockmode = RowExclusiveLock; - else if (forUpdatePushedDown || - get_parse_rowmark(parsetree, rt_index) != NULL) - lockmode = RowShareLock; + else if (forUpdatePushedDown) + { + /* Upgrade RTE's lock mode to reflect pushed-down lock */ + if (rte->rellockmode == AccessShareLock) + rte->rellockmode = RowShareLock; + lockmode = rte->rellockmode; + } else - lockmode = AccessShareLock; + lockmode = rte->rellockmode; - rel = heap_open(rte->relid, lockmode); + rel = table_open(rte->relid, lockmode); /* * While we have the relation open, update the RTE's relkind, @@ -184,7 +187,7 @@ AcquireRewriteLocks(Query *parsetree, */ rte->relkind = rel->rd_rel->relkind; - heap_close(rel, NoLock); + table_close(rel, NoLock); break; case RTE_JOIN: @@ -701,11 +704,6 @@ adjustJoinTreeList(Query *parsetree, bool removert, int rt_index) * is not needed for rewriting, but will be needed by the planner, and we * can do it essentially for free while handling the other items. * - * If attrno_list isn't NULL, we return an additional output besides the - * rewritten targetlist: an integer list of the assigned-to attnums, in - * order of the original tlist's non-junk entries. This is needed for - * processing VALUES RTEs. - * * Note that for an inheritable UPDATE, this processing is only done once, * using the parent relation as reference. It must not do anything that * will not be correct when transposed to the child relation(s). (Step 4 @@ -718,8 +716,7 @@ rewriteTargetListIU(List *targetList, CmdType commandType, OverridingKind override, Relation target_relation, - int result_rti, - List **attrno_list) + int result_rti) { TargetEntry **new_tles; List *new_tlist = NIL; @@ -730,9 +727,6 @@ rewriteTargetListIU(List *targetList, numattrs; ListCell *temp; - if (attrno_list) /* initialize optional result list */ - *attrno_list = NIL; - /* * We process the normal (non-junk) attributes by scanning the input tlist * once and transferring TLEs into an array, then scanning the array to @@ -758,10 +752,6 @@ rewriteTargetListIU(List *targetList, elog(ERROR, "bogus resno %d in targetlist", attrno); att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1); - /* put attrno into attrno_list even if it's dropped */ - if (attrno_list) - *attrno_list = lappend_int(*attrno_list, attrno); - /* We can (and must) ignore deleted attributes */ if (att_tup->attisdropped) continue; @@ -828,6 +818,13 @@ rewriteTargetListIU(List *targetList, if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && override == OVERRIDING_USER_VALUE) apply_default = true; + + if (att_tup->attgenerated && !apply_default) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("cannot insert into column \"%s\"", NameStr(att_tup->attname)), + errdetail("Column \"%s\" is a generated column.", + NameStr(att_tup->attname)))); } if (commandType == CMD_UPDATE) @@ -838,9 +835,23 @@ rewriteTargetListIU(List *targetList, errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)), errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.", NameStr(att_tup->attname)))); + + if (att_tup->attgenerated && new_tle && !apply_default) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("column \"%s\" can only be updated to DEFAULT", NameStr(att_tup->attname)), + errdetail("Column \"%s\" is a generated column.", + NameStr(att_tup->attname)))); } - if (apply_default) + if (att_tup->attgenerated) + { + /* + * stored generated column will be fixed in executor + */ + new_tle = NULL; + } + else if (apply_default) { Node *new_expr; @@ -947,7 +958,7 @@ process_matched_tle(TargetEntry *src_tle, /*---------- * Multiple assignments to same attribute. Allow only if all are - * FieldStore or ArrayRef assignment operations. This is a bit + * FieldStore or SubscriptingRef assignment operations. This is a bit * tricky because what we may actually be looking at is a nest of * such nodes; consider * UPDATE tab SET col.fld1.subfld1 = x, col.fld2.subfld2 = y @@ -955,7 +966,7 @@ process_matched_tle(TargetEntry *src_tle, * FieldStore(col, fld1, FieldStore(placeholder, subfld1, x)) * FieldStore(col, fld2, FieldStore(placeholder, subfld2, y)) * However, we can ignore the substructure and just consider the top - * FieldStore or ArrayRef from each assignment, because it works to + * FieldStore or SubscriptingRef from each assignment, because it works to * combine these as * FieldStore(FieldStore(col, fld1, * FieldStore(placeholder, subfld1, x)), @@ -965,15 +976,15 @@ process_matched_tle(TargetEntry *src_tle, * * For FieldStore, instead of nesting we can generate a single * FieldStore with multiple target fields. We must nest when - * ArrayRefs are involved though. + * SubscriptingRefs are involved though. * * As a further complication, the destination column might be a domain, * resulting in each assignment containing a CoerceToDomain node over a - * FieldStore or ArrayRef. These should have matching target domains, - * so we strip them and reconstitute a single CoerceToDomain over the - * combined FieldStore/ArrayRef nodes. (Notice that this has the result - * that the domain's checks are applied only after we do all the field or - * element updates, not after each one. This is arguably desirable.) + * FieldStore or SubscriptingRef. These should have matching target + * domains, so we strip them and reconstitute a single CoerceToDomain over + * the combined FieldStore/SubscriptingRef nodes. (Notice that this has the + * result that the domain's checks are applied only after we do all the + * field or element updates, not after each one. This is arguably desirable.) *---------- */ src_expr = (Node *) src_tle->expr; @@ -1030,11 +1041,11 @@ process_matched_tle(TargetEntry *src_tle, /* combine the two */ memcpy(fstore, prior_expr, sizeof(FieldStore)); fstore->newvals = - list_concat(list_copy(((FieldStore *) prior_expr)->newvals), - list_copy(((FieldStore *) src_expr)->newvals)); + list_concat_copy(((FieldStore *) prior_expr)->newvals, + ((FieldStore *) src_expr)->newvals); fstore->fieldnums = - list_concat(list_copy(((FieldStore *) prior_expr)->fieldnums), - list_copy(((FieldStore *) src_expr)->fieldnums)); + list_concat_copy(((FieldStore *) prior_expr)->fieldnums, + ((FieldStore *) src_expr)->fieldnums); } else { @@ -1044,13 +1055,13 @@ process_matched_tle(TargetEntry *src_tle, } newexpr = (Node *) fstore; } - else if (IsA(src_expr, ArrayRef)) + else if (IsA(src_expr, SubscriptingRef)) { - ArrayRef *aref = makeNode(ArrayRef); + SubscriptingRef *sbsref = makeNode(SubscriptingRef); - memcpy(aref, src_expr, sizeof(ArrayRef)); - aref->refexpr = (Expr *) prior_expr; - newexpr = (Node *) aref; + memcpy(sbsref, src_expr, sizeof(SubscriptingRef)); + sbsref->refexpr = (Expr *) prior_expr; + newexpr = (Node *) sbsref; } else { @@ -1087,14 +1098,16 @@ get_assignment_input(Node *node) return (Node *) fstore->arg; } - else if (IsA(node, ArrayRef)) + else if (IsA(node, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) return NULL; - return (Node *) aref->refexpr; + + return (Node *) sbsref->refexpr; } + return NULL; } @@ -1117,7 +1130,7 @@ build_column_default(Relation rel, int attrno) { NextValueExpr *nve = makeNode(NextValueExpr); - nve->seqid = getOwnedSequence(RelationGetRelid(rel), attrno); + nve->seqid = getIdentitySequence(RelationGetRelid(rel), attrno, false); nve->typeId = att_tup->atttypid; return (Node *) nve; @@ -1145,13 +1158,12 @@ build_column_default(Relation rel, int attrno) } } - if (expr == NULL) - { - /* - * No per-column default, so look for a default for the type itself. - */ + /* + * No per-column default, so look for a default for the type itself. But + * not for generated columns. + */ + if (expr == NULL && !att_tup->attgenerated) expr = get_typdefault(atttype); - } if (expr == NULL) return NULL; /* No default anywhere */ @@ -1213,59 +1225,175 @@ searchForDefault(RangeTblEntry *rte) * the appropriate default expressions. The other aspects of targetlist * rewriting need be applied only to the query's targetlist proper. * - * Note that we currently can't support subscripted or field assignment - * in the multi-VALUES case. The targetlist will contain simple Vars - * referencing the VALUES RTE, and therefore process_matched_tle() will - * reject any such attempt with "multiple assignments to same column". + * For an auto-updatable view, each DEFAULT item in the VALUES list is + * replaced with the default from the view, if it has one. Otherwise it is + * left untouched so that the underlying base relation's default can be + * applied instead (when we later recurse to here after rewriting the query + * to refer to the base relation instead of the view). + * + * For other types of relation, including rule- and trigger-updatable views, + * all DEFAULT items are replaced, and if the target relation doesn't have a + * default, the value is explicitly set to NULL. + * + * Additionally, if force_nulls is true, the target relation's defaults are + * ignored and all DEFAULT items in the VALUES list are explicitly set to + * NULL, regardless of the target relation's type. This is used for the + * product queries generated by DO ALSO rules attached to an auto-updatable + * view, for which we will have already called this function with force_nulls + * false. For these product queries, we must then force any remaining DEFAULT + * items to NULL to provide concrete values for the rule actions. + * Essentially, this is a mix of the 2 cases above --- the original query is + * an insert into an auto-updatable view, and the product queries are inserts + * into a rule-updatable view. + * + * Note that we may have subscripted or field assignment targetlist entries, + * as well as more complex expressions from already-replaced DEFAULT items if + * we have recursed to here for an auto-updatable view. However, it ought to + * be impossible for such entries to have DEFAULTs assigned to them --- we + * should only have to replace DEFAULT items for targetlist entries that + * contain simple Vars referencing the VALUES RTE. + * + * Returns true if all DEFAULT items were replaced, and false if some were + * left untouched. */ -static void -rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos) +static bool +rewriteValuesRTE(Query *parsetree, RangeTblEntry *rte, int rti, + Relation target_relation, bool force_nulls) { List *newValues; ListCell *lc; + bool isAutoUpdatableView; + bool allReplaced; + int numattrs; + int *attrnos; /* * Rebuilding all the lists is a pretty expensive proposition in a big * VALUES list, and it's a waste of time if there aren't any DEFAULT * placeholders. So first scan to see if there are any. + * + * We skip this check if force_nulls is true, because we know that there + * are DEFAULT items present in that case. */ - if (!searchForDefault(rte)) - return; /* nothing to do */ + if (!force_nulls && !searchForDefault(rte)) + return true; /* nothing to do */ - /* Check list lengths (we can assume all the VALUES sublists are alike) */ - Assert(list_length(attrnos) == list_length(linitial(rte->values_lists))); + /* + * Scan the targetlist for entries referring to the VALUES RTE, and note + * the target attributes. As noted above, we should only need to do this + * for targetlist entries containing simple Vars --- nothing else in the + * VALUES RTE should contain DEFAULT items, and we complain if such a + * thing does occur. + */ + numattrs = list_length(linitial(rte->values_lists)); + attrnos = (int *) palloc0(numattrs * sizeof(int)); + + foreach(lc, parsetree->targetList) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + + if (IsA(tle->expr, Var)) + { + Var *var = (Var *) tle->expr; + + if (var->varno == rti) + { + int attrno = var->varattno; + + Assert(attrno >= 1 && attrno <= numattrs); + attrnos[attrno - 1] = tle->resno; + } + } + } + + /* + * Check if the target relation is an auto-updatable view, in which case + * unresolved defaults will be left untouched rather than being set to + * NULL. If force_nulls is true, we always set DEFAULT items to NULL, so + * skip this check in that case --- it isn't an auto-updatable view. + */ + isAutoUpdatableView = false; + if (!force_nulls && + target_relation->rd_rel->relkind == RELKIND_VIEW && + !view_has_instead_trigger(target_relation, CMD_INSERT)) + { + List *locks; + bool hasUpdate; + bool found; + ListCell *l; + + /* Look for an unconditional DO INSTEAD rule */ + locks = matchLocks(CMD_INSERT, target_relation->rd_rules, + parsetree->resultRelation, parsetree, &hasUpdate); + + found = false; + foreach(l, locks) + { + RewriteRule *rule_lock = (RewriteRule *) lfirst(l); + + if (rule_lock->isInstead && + rule_lock->qual == NULL) + { + found = true; + break; + } + } + + /* + * If we didn't find an unconditional DO INSTEAD rule, assume that the + * view is auto-updatable. If it isn't, rewriteTargetView() will + * throw an error. + */ + if (!found) + isAutoUpdatableView = true; + } newValues = NIL; + allReplaced = true; foreach(lc, rte->values_lists) { List *sublist = (List *) lfirst(lc); List *newList = NIL; ListCell *lc2; - ListCell *lc3; + int i; - forboth(lc2, sublist, lc3, attrnos) + Assert(list_length(sublist) == numattrs); + + i = 0; + foreach(lc2, sublist) { Node *col = (Node *) lfirst(lc2); - int attrno = lfirst_int(lc3); + int attrno = attrnos[i++]; if (IsA(col, SetToDefault)) { Form_pg_attribute att_tup; Node *new_expr; + if (attrno == 0) + elog(ERROR, "cannot set value in column %d to DEFAULT", i); att_tup = TupleDescAttr(target_relation->rd_att, attrno - 1); - if (!att_tup->attisdropped) + if (!force_nulls && !att_tup->attisdropped) new_expr = build_column_default(target_relation, attrno); else new_expr = NULL; /* force a NULL if dropped */ /* * If there is no default (ie, default is effectively NULL), - * we've got to explicitly set the column to NULL. + * we've got to explicitly set the column to NULL, unless the + * target relation is an auto-updatable view. */ if (!new_expr) { + if (isAutoUpdatableView) + { + /* Leave the value untouched */ + newList = lappend(newList, col); + allReplaced = false; + continue; + } + new_expr = (Node *) makeConst(att_tup->atttypid, -1, att_tup->attcollation, @@ -1290,6 +1418,10 @@ rewriteValuesRTE(RangeTblEntry *rte, Relation target_relation, List *attrnos) newValues = lappend(newValues, newList); } rte->values_lists = newValues; + + pfree(attrnos); + + return allReplaced; } @@ -1377,57 +1509,6 @@ rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte, } } -void -rewriteTargetListMerge(Query *parsetree, Relation target_relation) -{ - Var *var = NULL; - const char *attrname; - TargetEntry *tle; - - Assert(target_relation->rd_rel->relkind == RELKIND_RELATION || - target_relation->rd_rel->relkind == RELKIND_MATVIEW || - target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE); - - /* - * Emit CTID so that executor can find the row to update or delete. - */ - var = makeVar(parsetree->mergeTarget_relation, - SelfItemPointerAttributeNumber, - TIDOID, - -1, - InvalidOid, - 0); - - attrname = "ctid"; - tle = makeTargetEntry((Expr *) var, - list_length(parsetree->targetList) + 1, - pstrdup(attrname), - true); - - parsetree->targetList = lappend(parsetree->targetList, tle); - - /* - * If we are dealing with partitioned table, then emit TABLEOID so that - * executor can find the partition the row belongs to. - */ - if (target_relation->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - { - var = makeVar(parsetree->mergeTarget_relation, - TableOidAttributeNumber, - OIDOID, - -1, - InvalidOid, - 0); - - attrname = "tableoid"; - tle = makeTargetEntry((Expr *) var, - list_length(parsetree->targetList) + 1, - pstrdup(attrname), - true); - - parsetree->targetList = lappend(parsetree->targetList, tle); - } -} /* * matchLocks - @@ -1504,8 +1585,7 @@ ApplyRetrieveRule(Query *parsetree, RewriteRule *rule, int rt_index, Relation relation, - List *activeRIRs, - bool forUpdatePushedDown) + List *activeRIRs) { Query *rule_action; RangeTblEntry *rte, @@ -1596,35 +1676,57 @@ ApplyRetrieveRule(Query *parsetree, } /* - * If FOR [KEY] UPDATE/SHARE of view, be sure we get right initial lock on - * the relations it references. + * Check if there's a FOR [KEY] UPDATE/SHARE clause applying to this view. + * + * Note: we needn't explicitly consider any such clauses appearing in + * ancestor query levels; their effects have already been pushed down to + * here by markQueryForLocking, and will be reflected in "rc". */ rc = get_parse_rowmark(parsetree, rt_index); - forUpdatePushedDown |= (rc != NULL); /* * Make a modifiable copy of the view query, and acquire needed locks on - * the relations it mentions. + * the relations it mentions. Force at least RowShareLock for all such + * rels if there's a FOR [KEY] UPDATE/SHARE clause affecting this view. */ rule_action = copyObject(linitial(rule->actions)); - AcquireRewriteLocks(rule_action, true, forUpdatePushedDown); + AcquireRewriteLocks(rule_action, true, (rc != NULL)); + + /* + * If FOR [KEY] UPDATE/SHARE of view, mark all the contained tables as + * implicit FOR [KEY] UPDATE/SHARE, the same as the parser would have done + * if the view's subquery had been written out explicitly. + */ + if (rc != NULL) + markQueryForLocking(rule_action, (Node *) rule_action->jointree, + rc->strength, rc->waitPolicy, true); /* * Recursively expand any view references inside the view. + * + * Note: this must happen after markQueryForLocking. That way, any UPDATE + * permission bits needed for sub-views are initially applied to their + * RTE_RELATION RTEs by markQueryForLocking, and then transferred to their + * OLD rangetable entries by the action below (in a recursive call of this + * routine). */ - rule_action = fireRIRrules(rule_action, activeRIRs, forUpdatePushedDown); + rule_action = fireRIRrules(rule_action, activeRIRs); /* - * Now, plug the view query in as a subselect, replacing the relation's - * original RTE. + * Now, plug the view query in as a subselect, converting the relation's + * original RTE to a subquery RTE. */ rte = rt_fetch(rt_index, parsetree->rtable); rte->rtekind = RTE_SUBQUERY; - rte->relid = InvalidOid; - rte->security_barrier = RelationIsSecurityView(relation); rte->subquery = rule_action; + rte->security_barrier = RelationIsSecurityView(relation); + /* Clear fields that should not be set in a subquery RTE */ + rte->relid = InvalidOid; + rte->relkind = 0; + rte->rellockmode = 0; + rte->tablesample = NULL; rte->inh = false; /* must not be set for a subquery */ /* @@ -1638,24 +1740,14 @@ ApplyRetrieveRule(Query *parsetree, subrte->selectedCols = rte->selectedCols; subrte->insertedCols = rte->insertedCols; subrte->updatedCols = rte->updatedCols; + subrte->extraUpdatedCols = rte->extraUpdatedCols; rte->requiredPerms = 0; /* no permission check on subquery itself */ rte->checkAsUser = InvalidOid; rte->selectedCols = NULL; rte->insertedCols = NULL; rte->updatedCols = NULL; - - /* - * If FOR [KEY] UPDATE/SHARE of view, mark all the contained tables as - * implicit FOR [KEY] UPDATE/SHARE, the same as the parser would have done - * if the view's subquery had been written out explicitly. - * - * Note: we don't consider forUpdatePushedDown here; such marks will be - * made by recursing from the upper level in markQueryForLocking. - */ - if (rc != NULL) - markQueryForLocking(rule_action, (Node *) rule_action->jointree, - rc->strength, rc->waitPolicy, true); + rte->extraUpdatedCols = NULL; return parsetree; } @@ -1742,7 +1834,7 @@ fireRIRonSubLink(Node *node, List *activeRIRs) /* Do what we came for */ sub->subselect = (Node *) fireRIRrules((Query *) sub->subselect, - activeRIRs, false); + activeRIRs); /* Fall through to process lefthand args of SubLink */ } @@ -1757,10 +1849,13 @@ fireRIRonSubLink(Node *node, List *activeRIRs) /* * fireRIRrules - - * Apply all RIR rules on each rangetable entry in a query + * Apply all RIR rules on each rangetable entry in the given query + * + * activeRIRs is a list of the OIDs of views we're already processing RIR + * rules for, used to detect/reject recursion. */ static Query * -fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) +fireRIRrules(Query *parsetree, List *activeRIRs) { int origResultRelation = parsetree->resultRelation; int rt_index; @@ -1791,9 +1886,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) */ if (rte->rtekind == RTE_SUBQUERY) { - rte->subquery = fireRIRrules(rte->subquery, activeRIRs, - (forUpdatePushedDown || - get_parse_rowmark(parsetree, rt_index) != NULL)); + rte->subquery = fireRIRrules(rte->subquery, activeRIRs); continue; } @@ -1816,6 +1909,17 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) if (rte->relkind == RELKIND_MATVIEW) continue; + /* + * In INSERT ... ON CONFLICT, ignore the EXCLUDED pseudo-relation; + * even if it points to a view, we needn't expand it, and should not + * because we want the RTE to remain of RTE_RELATION type. Otherwise, + * it would get changed to RTE_SUBQUERY type, which is an + * untested/unsupported situation. + */ + if (parsetree->onConflict && + rt_index == parsetree->onConflict->exclRelIndex) + continue; + /* * If the table is not referenced in the query, then we ignore it. * This prevents infinite expansion loop due to new rtable entries @@ -1839,7 +1943,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) * We can use NoLock here since either the parser or * AcquireRewriteLocks should have locked the rel already. */ - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); /* * Collect the RIR rules that we must apply @@ -1869,7 +1973,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), errmsg("infinite recursion detected in rules for relation \"%s\"", RelationGetRelationName(rel)))); - activeRIRs = lcons_oid(RelationGetRelid(rel), activeRIRs); + activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel)); foreach(l, locks) { @@ -1879,15 +1983,14 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) rule, rt_index, rel, - activeRIRs, - forUpdatePushedDown); + activeRIRs); } - activeRIRs = list_delete_first(activeRIRs); + activeRIRs = list_delete_last(activeRIRs); } } - heap_close(rel, NoLock); + table_close(rel, NoLock); } /* Recurse into subqueries in WITH */ @@ -1896,7 +1999,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc); cte->ctequery = (Node *) - fireRIRrules((Query *) cte->ctequery, activeRIRs, false); + fireRIRrules((Query *) cte->ctequery, activeRIRs); } /* @@ -1931,7 +2034,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) rte->relkind != RELKIND_PARTITIONED_TABLE)) continue; - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); /* * Fetch any new security quals that must be applied to this RTE. @@ -1956,7 +2059,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) errmsg("infinite recursion detected in policy for relation \"%s\"", RelationGetRelationName(rel)))); - activeRIRs = lcons_oid(RelationGetRelid(rel), activeRIRs); + activeRIRs = lappend_oid(activeRIRs, RelationGetRelid(rel)); /* * get_row_security_policies just passed back securityQuals @@ -1981,7 +2084,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) expression_tree_walker((Node *) withCheckOptions, fireRIRonSubLink, (void *) activeRIRs); - activeRIRs = list_delete_first(activeRIRs); + activeRIRs = list_delete_last(activeRIRs); } /* @@ -2006,7 +2109,7 @@ fireRIRrules(Query *parsetree, List *activeRIRs, bool forUpdatePushedDown) if (hasSubLinks) parsetree->hasSubLinks = true; - heap_close(rel, NoLock); + table_close(rel, NoLock); } return parsetree; @@ -2252,6 +2355,9 @@ view_has_instead_trigger(Relation view, CmdType event) * is auto-updatable. Returns NULL (if the column can be updated) or a message * string giving the reason that it cannot be. * + * The returned string has not been translated; if it is shown as an error + * message, the caller should apply _() to translate it. + * * Note that the checks performed here are local to this view. We do not check * whether the referenced column of the underlying base relation is updatable. */ @@ -2291,6 +2397,9 @@ view_col_is_auto_updatable(RangeTblRef *rtr, TargetEntry *tle) * view_query_is_auto_updatable - test whether the specified view definition * represents an auto-updatable view. Returns NULL (if the view can be updated) * or a message string giving the reason that it cannot be. + + * The returned string has not been translated; if it is shown as an error + * message, the caller should apply _() to translate it. * * If check_cols is true, the view is required to have at least one updatable * column (necessary for INSERT/UPDATE). Otherwise the view's columns are not @@ -2431,6 +2540,9 @@ view_query_is_auto_updatable(Query *viewquery, bool check_cols) * required columns can be updated) or a message string giving the reason that * they cannot be. * + * The returned string has not been translated; if it is shown as an error + * message, the caller should apply _() to translate it. + * * This should be used for INSERT/UPDATE to ensure that we don't attempt to * assign to any non-updatable columns. * @@ -2914,7 +3026,7 @@ rewriteTargetView(Query *parsetree, Relation view) * already have the right lock!) Since it will become the query target * relation, RowExclusiveLock is always the right thing. */ - base_rel = heap_open(base_rte->relid, RowExclusiveLock); + base_rel = table_open(base_rte->relid, RowExclusiveLock); /* * While we have the relation open, update the RTE's relkind, just in case @@ -2922,8 +3034,6 @@ rewriteTargetView(Query *parsetree, Relation view) */ base_rte->relkind = base_rel->rd_rel->relkind; - heap_close(base_rel, NoLock); - /* * If the view query contains any sublink subqueries then we need to also * acquire locks on any relations they refer to. We know that there won't @@ -2945,8 +3055,14 @@ rewriteTargetView(Query *parsetree, Relation view) * very much like what the planner would do to "pull up" the view into the * outer query. Perhaps someday we should refactor things enough so that * we can share code with the planner.) + * + * Be sure to set rellockmode to the correct thing for the target table. + * Since we copied the whole viewquery above, we can just scribble on + * base_rte instead of copying it. */ - new_rte = (RangeTblEntry *) base_rte; + new_rte = base_rte; + new_rte->rellockmode = RowExclusiveLock; + parsetree->rtable = lappend(parsetree->rtable, new_rte); new_rt_index = list_length(parsetree->rtable); @@ -3081,6 +3197,93 @@ rewriteTargetView(Query *parsetree, Relation view) } } + /* + * For INSERT .. ON CONFLICT .. DO UPDATE, we must also update assorted + * stuff in the onConflict data structure. + */ + if (parsetree->onConflict && + parsetree->onConflict->action == ONCONFLICT_UPDATE) + { + Index old_exclRelIndex, + new_exclRelIndex; + RangeTblEntry *new_exclRte; + List *tmp_tlist; + + /* + * Like the INSERT/UPDATE code above, update the resnos in the + * auxiliary UPDATE targetlist to refer to columns of the base + * relation. + */ + foreach(lc, parsetree->onConflict->onConflictSet) + { + TargetEntry *tle = (TargetEntry *) lfirst(lc); + TargetEntry *view_tle; + + if (tle->resjunk) + continue; + + view_tle = get_tle_by_resno(view_targetlist, tle->resno); + if (view_tle != NULL && !view_tle->resjunk && IsA(view_tle->expr, Var)) + tle->resno = ((Var *) view_tle->expr)->varattno; + else + elog(ERROR, "attribute number %d not found in view targetlist", + tle->resno); + } + + /* + * Also, create a new RTE for the EXCLUDED pseudo-relation, using the + * query's new base rel (which may well have a different column list + * from the view, hence we need a new column alias list). This should + * match transformOnConflictClause. In particular, note that the + * relkind is set to composite to signal that we're not dealing with + * an actual relation, and no permissions checks are wanted. + */ + old_exclRelIndex = parsetree->onConflict->exclRelIndex; + + new_exclRte = addRangeTableEntryForRelation(make_parsestate(NULL), + base_rel, + RowExclusiveLock, + makeAlias("excluded", NIL), + false, false); + new_exclRte->relkind = RELKIND_COMPOSITE_TYPE; + new_exclRte->requiredPerms = 0; + /* other permissions fields in new_exclRte are already empty */ + + parsetree->rtable = lappend(parsetree->rtable, new_exclRte); + new_exclRelIndex = parsetree->onConflict->exclRelIndex = + list_length(parsetree->rtable); + + /* + * Replace the targetlist for the EXCLUDED pseudo-relation with a new + * one, representing the columns from the new base relation. + */ + parsetree->onConflict->exclRelTlist = + BuildOnConflictExcludedTargetlist(base_rel, new_exclRelIndex); + + /* + * Update all Vars in the ON CONFLICT clause that refer to the old + * EXCLUDED pseudo-relation. We want to use the column mappings + * defined in the view targetlist, but we need the outputs to refer to + * the new EXCLUDED pseudo-relation rather than the new target RTE. + * Also notice that "EXCLUDED.*" will be expanded using the view's + * rowtype, which seems correct. + */ + tmp_tlist = copyObject(view_targetlist); + + ChangeVarNodes((Node *) tmp_tlist, new_rt_index, + new_exclRelIndex, 0); + + parsetree->onConflict = (OnConflictExpr *) + ReplaceVarsFromTargetList((Node *) parsetree->onConflict, + old_exclRelIndex, + 0, + view_rte, + tmp_tlist, + REPLACEVARS_REPORT_ERROR, + 0, + &parsetree->hasSubLinks); + } + /* * For UPDATE/DELETE, pull up any WHERE quals from the view. We know that * any Vars in the quals must reference the one base relation, so we need @@ -3208,6 +3411,8 @@ rewriteTargetView(Query *parsetree, Relation view) } } + table_close(base_rel, NoLock); + return parsetree; } @@ -3306,6 +3511,8 @@ RewriteQuery(Query *parsetree, List *rewrite_events) List *locks; List *product_queries; bool hasUpdate = false; + int values_rte_index = 0; + bool defaults_remaining = false; result_relation = parsetree->resultRelation; Assert(result_relation != 0); @@ -3316,7 +3523,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) * We can use NoLock here since either the parser or * AcquireRewriteLocks should have locked the rel already. */ - rt_entry_relation = heap_open(rt_entry->relid, NoLock); + rt_entry_relation = table_open(rt_entry->relid, NoLock); /* * Rewrite the targetlist as needed for the command type. @@ -3339,23 +3546,25 @@ RewriteQuery(Query *parsetree, List *rewrite_events) parsetree->rtable); if (rte->rtekind == RTE_VALUES) + { values_rte = rte; + values_rte_index = rtr->rtindex; + } } } if (values_rte) { - List *attrnos; - /* Process the main targetlist ... */ parsetree->targetList = rewriteTargetListIU(parsetree->targetList, parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation, - &attrnos); + parsetree->resultRelation); /* ... and the VALUES expression lists */ - rewriteValuesRTE(values_rte, rt_entry_relation, attrnos); + if (!rewriteValuesRTE(parsetree, values_rte, values_rte_index, + rt_entry_relation, false)) + defaults_remaining = true; } else { @@ -3365,7 +3574,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation, NULL); + parsetree->resultRelation); } if (parsetree->onConflict && @@ -3376,61 +3585,17 @@ RewriteQuery(Query *parsetree, List *rewrite_events) CMD_UPDATE, parsetree->override, rt_entry_relation, - parsetree->resultRelation, - NULL); + parsetree->resultRelation); } } else if (event == CMD_UPDATE) { - Assert(parsetree->override == OVERRIDING_NOT_SET); parsetree->targetList = rewriteTargetListIU(parsetree->targetList, parsetree->commandType, parsetree->override, rt_entry_relation, - parsetree->resultRelation, NULL); - } - else if (event == CMD_MERGE) - { - Assert(parsetree->override == OVERRIDING_NOT_SET); - - /* - * Rewrite each action targetlist separately - */ - foreach(lc1, parsetree->mergeActionList) - { - MergeAction *action = (MergeAction *) lfirst(lc1); - - switch (action->commandType) - { - case CMD_NOTHING: - case CMD_DELETE: /* Nothing to do here */ - break; - case CMD_UPDATE: - action->targetList = - rewriteTargetListIU(action->targetList, - action->commandType, - parsetree->override, - rt_entry_relation, - parsetree->resultRelation, - NULL); - break; - case CMD_INSERT: - { - action->targetList = - rewriteTargetListIU(action->targetList, - action->commandType, - action->override, - rt_entry_relation, - parsetree->resultRelation, - NULL); - } - break; - default: - elog(ERROR, "unrecognized commandType: %d", action->commandType); - break; - } - } + parsetree->resultRelation); } else if (event == CMD_DELETE) { @@ -3445,20 +3610,41 @@ RewriteQuery(Query *parsetree, List *rewrite_events) locks = matchLocks(event, rt_entry_relation->rd_rules, result_relation, parsetree, &hasUpdate); + product_queries = fireRules(parsetree, + result_relation, + event, + locks, + &instead, + &returning, + &qual_product); + /* - * XXX MERGE doesn't support write rules because they would violate - * the SQL Standard spec and would be unclear how they should work. + * If we have a VALUES RTE with any remaining untouched DEFAULT items, + * and we got any product queries, finalize the VALUES RTE for each + * product query (replacing the remaining DEFAULT items with NULLs). + * We don't do this for the original query, because we know that it + * must be an auto-insert on a view, and so should use the base + * relation's defaults for any remaining DEFAULT items. */ - if (event == CMD_MERGE) - product_queries = NIL; - else - product_queries = fireRules(parsetree, - result_relation, - event, - locks, - &instead, - &returning, - &qual_product); + if (defaults_remaining && product_queries != NIL) + { + ListCell *n; + + /* + * Each product query has its own copy of the VALUES RTE at the + * same index in the rangetable, so we must finalize each one. + */ + foreach(n, product_queries) + { + Query *pt = (Query *) lfirst(n); + RangeTblEntry *values_rte = rt_fetch(values_rte_index, + pt->rtable); + + rewriteValuesRTE(pt, values_rte, values_rte_index, + rt_entry_relation, + true); /* Force remaining defaults to NULL */ + } + } /* * If there were no INSTEAD rules, and the target relation is a view @@ -3525,7 +3711,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) rev = (rewrite_event *) palloc(sizeof(rewrite_event)); rev->relation = RelationGetRelid(rt_entry_relation); rev->event = event; - rewrite_events = lcons(rev, rewrite_events); + rewrite_events = lappend(rewrite_events, rev); foreach(n, product_queries) { @@ -3536,7 +3722,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) rewritten = list_concat(rewritten, newstuff); } - rewrite_events = list_delete_first(rewrite_events); + rewrite_events = list_delete_last(rewrite_events); } /* @@ -3591,7 +3777,7 @@ RewriteQuery(Query *parsetree, List *rewrite_events) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("INSERT with ON CONFLICT clause cannot be used with table that has INSERT or UPDATE rules"))); - heap_close(rt_entry_relation, NoLock); + table_close(rt_entry_relation, NoLock); } /* @@ -3698,7 +3884,7 @@ QueryRewrite(Query *parsetree) { Query *query = (Query *) lfirst(l); - query = fireRIRrules(query, NIL, false); + query = fireRIRrules(query, NIL); query->queryId = input_query_id; diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index f1f4212b5df..93508c2a87e 100644 --- a/src/backend/rewrite/rewriteManip.c +++ b/src/backend/rewrite/rewriteManip.c @@ -2,7 +2,7 @@ * * rewriteManip.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,8 +16,8 @@ #include "catalog/pg_type.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "optimizer/clauses.h" #include "parser/parse_coerce.h" #include "parser/parse_relation.h" #include "parser/parsetree.h" @@ -41,12 +41,12 @@ typedef struct } locate_windowfunc_context; static bool contain_aggs_of_level_walker(Node *node, - contain_aggs_of_level_context *context); + contain_aggs_of_level_context *context); static bool locate_agg_of_level_walker(Node *node, - locate_agg_of_level_context *context); + locate_agg_of_level_context *context); static bool contain_windowfuncs_walker(Node *node, void *context); static bool locate_windowfunc_walker(Node *node, - locate_windowfunc_context *context); + locate_windowfunc_context *context); static bool checkExprHasSubLink_walker(Node *node, void *context); static Relids offset_relid_set(Relids relids, int offset); static Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid); @@ -761,7 +761,7 @@ IncrementVarSublevelsUp_walker(Node *node, result = query_tree_walker((Query *) node, IncrementVarSublevelsUp_walker, (void *) context, - QTW_EXAMINE_RTES); + QTW_EXAMINE_RTES_BEFORE); context->min_sublevels_up--; return result; } @@ -785,7 +785,7 @@ IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, query_or_expression_tree_walker(node, IncrementVarSublevelsUp_walker, (void *) &context, - QTW_EXAMINE_RTES); + QTW_EXAMINE_RTES_BEFORE); } /* @@ -804,7 +804,7 @@ IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up, range_table_walker(rtable, IncrementVarSublevelsUp_walker, (void *) &context, - QTW_EXAMINE_RTES); + QTW_EXAMINE_RTES_BEFORE); } @@ -1015,7 +1015,7 @@ AddQual(Query *parsetree, Node *qual) errmsg("conditional UNION/INTERSECT/EXCEPT statements are not implemented"))); } - /* INTERSECT want's the original, but we need to copy - Jan */ + /* INTERSECT wants the original, but we need to copy - Jan */ copy = copyObject(qual); parsetree->jointree->quals = make_and_qual(parsetree->jointree->quals, @@ -1208,7 +1208,7 @@ replace_rte_variables_mutator(Node *node, * a ConvertRowtypeExpr to map back to the rowtype expected by the expression. * (Therefore, to_rowtype had better be a child rowtype of the rowtype of the * RTE we're changing references to.) Callers that don't provide to_rowtype - * should report an error if *found_row_type is true; we don't do that here + * should report an error if *found_whole_row is true; we don't do that here * because we don't know exactly what wording for the error message would * be most appropriate. The caller will be aware of the context. * diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c index 07de85b8a31..c5e2aed58df 100644 --- a/src/backend/rewrite/rewriteRemove.c +++ b/src/backend/rewrite/rewriteRemove.c @@ -3,7 +3,7 @@ * rewriteRemove.c * routines for removing rewrite rules * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,9 +15,9 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -29,7 +29,6 @@ #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* * Guts of rule deletion. @@ -47,13 +46,13 @@ RemoveRewriteRuleById(Oid ruleOid) /* * Open the pg_rewrite relation. */ - RewriteRelation = heap_open(RewriteRelationId, RowExclusiveLock); + RewriteRelation = table_open(RewriteRelationId, RowExclusiveLock); /* * Find the tuple for the target rule. */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_rewrite_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(ruleOid)); @@ -71,7 +70,7 @@ RemoveRewriteRuleById(Oid ruleOid) * suffice if it's not an ON SELECT rule.) */ eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; - event_relation = heap_open(eventRelationOid, AccessExclusiveLock); + event_relation = table_open(eventRelationOid, AccessExclusiveLock); /* * Now delete the pg_rewrite tuple for the rule @@ -80,7 +79,7 @@ RemoveRewriteRuleById(Oid ruleOid) systable_endscan(rcscan); - heap_close(RewriteRelation, RowExclusiveLock); + table_close(RewriteRelation, RowExclusiveLock); /* * Issue shared-inval notice to force all backends (including me!) to @@ -89,5 +88,5 @@ RemoveRewriteRuleById(Oid ruleOid) CacheInvalidateRelcache(event_relation); /* Close rel, but keep lock till commit... */ - heap_close(event_relation, NoLock); + table_close(event_relation, NoLock); } diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c index ab291a43e2c..d36611d4a2b 100644 --- a/src/backend/rewrite/rewriteSupport.c +++ b/src/backend/rewrite/rewriteSupport.c @@ -3,7 +3,7 @@ * rewriteSupport.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,8 @@ */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_rewrite.h" #include "rewrite/rewriteSupport.h" @@ -24,7 +24,6 @@ #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -61,7 +60,7 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules) /* * Find the tuple to update in pg_class, using syscache for the lookup. */ - relationRelation = heap_open(RelationRelationId, RowExclusiveLock); + relationRelation = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relationId)); if (!HeapTupleIsValid(tuple)) elog(ERROR, "cache lookup failed for relation %u", relationId); @@ -81,7 +80,7 @@ SetRelationRuleStatus(Oid relationId, bool relHasRules) } heap_freetuple(tuple); - heap_close(relationRelation, RowExclusiveLock); + table_close(relationRelation, RowExclusiveLock); } /* @@ -94,6 +93,7 @@ Oid get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok) { HeapTuple tuple; + Form_pg_rewrite ruleform; Oid ruleoid; /* Find the rule's pg_rewrite tuple, get its OID */ @@ -109,8 +109,9 @@ get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok) errmsg("rule \"%s\" for relation \"%s\" does not exist", rulename, get_rel_name(relid)))); } - Assert(relid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class); - ruleoid = HeapTupleGetOid(tuple); + ruleform = (Form_pg_rewrite) GETSTRUCT(tuple); + Assert(relid == ruleform->ev_class); + ruleoid = ruleform->oid; ReleaseSysCache(tuple); return ruleoid; } diff --git a/src/backend/rewrite/rowsecurity.c b/src/backend/rewrite/rowsecurity.c index 57e52b4f988..1c44714589b 100644 --- a/src/backend/rewrite/rowsecurity.c +++ b/src/backend/rewrite/rowsecurity.c @@ -29,14 +29,14 @@ * in the current environment, but that may change if the row_security GUC or * the current role changes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ #include "postgres.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/pg_class.h" #include "catalog/pg_inherits.h" #include "catalog/pg_policy.h" @@ -47,6 +47,7 @@ #include "nodes/pg_list.h" #include "nodes/plannodes.h" #include "parser/parsetree.h" +#include "rewrite/rewriteDefine.h" #include "rewrite/rewriteHandler.h" #include "rewrite/rewriteManip.h" #include "rewrite/rowsecurity.h" @@ -58,28 +59,28 @@ #include "tcop/utility.h" static void get_policies_for_relation(Relation relation, - CmdType cmd, Oid user_id, - List **permissive_policies, - List **restrictive_policies); + CmdType cmd, Oid user_id, + List **permissive_policies, + List **restrictive_policies); -static List *sort_policies_by_name(List *policies); +static void sort_policies_by_name(List *policies); -static int row_security_policy_cmp(const void *a, const void *b); +static int row_security_policy_cmp(const ListCell *a, const ListCell *b); static void add_security_quals(int rt_index, - List *permissive_policies, - List *restrictive_policies, - List **securityQuals, - bool *hasSubLinks); + List *permissive_policies, + List *restrictive_policies, + List **securityQuals, + bool *hasSubLinks); static void add_with_check_options(Relation rel, - int rt_index, - WCOKind kind, - List *permissive_policies, - List *restrictive_policies, - List **withCheckOptions, - bool *hasSubLinks, - bool force_using); + int rt_index, + WCOKind kind, + List *permissive_policies, + List *restrictive_policies, + List **withCheckOptions, + bool *hasSubLinks, + bool force_using); static bool check_role_for_policy(ArrayType *policy_roles, Oid user_id); @@ -162,7 +163,7 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, * for example in UPDATE t1 ... FROM t2 we need to apply t1's UPDATE * policies and t2's SELECT policies. */ - rel = heap_open(rte->relid, NoLock); + rel = table_open(rte->relid, NoLock); commandType = rt_index == root->resultRelation ? root->commandType : CMD_SELECT; @@ -379,96 +380,14 @@ get_row_security_policies(Query *root, RangeTblEntry *rte, int rt_index, } } + table_close(rel, NoLock); + /* - * FOR MERGE, we fetch policies for UPDATE, DELETE and INSERT (and ALL) - * and set them up so that we can enforce the appropriate policy depending - * on the final action we take. - * - * We don't fetch the SELECT policies since they are correctly applied to - * the root->mergeTarget_relation. The target rows are selected after - * joining the mergeTarget_relation and the source relation and hence it's - * enough to apply SELECT policies to the mergeTarget_relation. - * - * We don't push the UPDATE/DELETE USING quals to the RTE because we don't - * really want to apply them while scanning the relation since we don't - * know whether we will be doing a UPDATE or a DELETE at the end. We apply - * the respective policy once we decide the final action on the target - * tuple. - * - * XXX We are setting up USING quals as WITH CHECK. If RLS prohibits - * UPDATE/DELETE on the target row, we shall throw an error instead of - * silently ignoring the row. This is different than how normal - * UPDATE/DELETE works and more in line with INSERT ON CONFLICT DO UPDATE - * handling. + * Copy checkAsUser to the row security quals and WithCheckOption checks, + * in case they contain any subqueries referring to other relations. */ - if (commandType == CMD_MERGE) - { - List *merge_permissive_policies; - List *merge_restrictive_policies; - - /* - * Fetch the UPDATE policies and set them up to execute on the - * existing target row before doing UPDATE. - */ - get_policies_for_relation(rel, CMD_UPDATE, user_id, - &merge_permissive_policies, - &merge_restrictive_policies); - - /* - * WCO_RLS_MERGE_UPDATE_CHECK is used to check UPDATE USING quals on - * the existing target row. - */ - add_with_check_options(rel, rt_index, - WCO_RLS_MERGE_UPDATE_CHECK, - merge_permissive_policies, - merge_restrictive_policies, - withCheckOptions, - hasSubLinks, - true); - - /* - * Same with DELETE policies. - */ - get_policies_for_relation(rel, CMD_DELETE, user_id, - &merge_permissive_policies, - &merge_restrictive_policies); - - add_with_check_options(rel, rt_index, - WCO_RLS_MERGE_DELETE_CHECK, - merge_permissive_policies, - merge_restrictive_policies, - withCheckOptions, - hasSubLinks, - true); - - /* - * No special handling is required for INSERT policies. They will be - * checked and enforced during ExecInsert(). But we must add them to - * withCheckOptions. - */ - get_policies_for_relation(rel, CMD_INSERT, user_id, - &merge_permissive_policies, - &merge_restrictive_policies); - - add_with_check_options(rel, rt_index, - WCO_RLS_INSERT_CHECK, - merge_permissive_policies, - merge_restrictive_policies, - withCheckOptions, - hasSubLinks, - false); - - /* Enforce the WITH CHECK clauses of the UPDATE policies */ - add_with_check_options(rel, rt_index, - WCO_RLS_UPDATE_CHECK, - merge_permissive_policies, - merge_restrictive_policies, - withCheckOptions, - hasSubLinks, - false); - } - - heap_close(rel, NoLock); + setRuleCheckAsUser((Node *) *securityQuals, rte->checkAsUser); + setRuleCheckAsUser((Node *) *withCheckOptions, rte->checkAsUser); /* * Mark this query as having row security, so plancache can invalidate it @@ -527,14 +446,6 @@ get_policies_for_relation(Relation relation, CmdType cmd, Oid user_id, if (policy->polcmd == ACL_DELETE_CHR) cmd_matches = true; break; - case CMD_MERGE: - - /* - * We do not support a separate policy for MERGE command. - * Instead it derives from the policies defined for other - * commands. - */ - break; default: elog(ERROR, "unrecognized policy command type %d", (int) cmd); @@ -559,7 +470,7 @@ get_policies_for_relation(Relation relation, CmdType cmd, Oid user_id, * We sort restrictive policies by name so that any WCOs they generate are * checked in a well-defined order. */ - *restrictive_policies = sort_policies_by_name(*restrictive_policies); + sort_policies_by_name(*restrictive_policies); /* * Then add any permissive or restrictive policies defined by extensions. @@ -577,7 +488,7 @@ get_policies_for_relation(Relation relation, CmdType cmd, Oid user_id, * always check all built-in restrictive policies, in name order, * before checking restrictive policies added by hooks, in name order. */ - hook_policies = sort_policies_by_name(hook_policies); + sort_policies_by_name(hook_policies); foreach(item, hook_policies) { @@ -611,43 +522,20 @@ get_policies_for_relation(Relation relation, CmdType cmd, Oid user_id, * This is not necessary for permissive policies, since they are all combined * together using OR into a single WithCheckOption check. */ -static List * +static void sort_policies_by_name(List *policies) { - int npol = list_length(policies); - RowSecurityPolicy *pols; - ListCell *item; - int ii = 0; - - if (npol <= 1) - return policies; - - pols = (RowSecurityPolicy *) palloc(sizeof(RowSecurityPolicy) * npol); - - foreach(item, policies) - { - RowSecurityPolicy *policy = (RowSecurityPolicy *) lfirst(item); - - pols[ii++] = *policy; - } - - qsort(pols, npol, sizeof(RowSecurityPolicy), row_security_policy_cmp); - - policies = NIL; - for (ii = 0; ii < npol; ii++) - policies = lappend(policies, &pols[ii]); - - return policies; + list_sort(policies, row_security_policy_cmp); } /* - * qsort comparator to sort RowSecurityPolicy entries by name + * list_sort comparator to sort RowSecurityPolicy entries by name */ static int -row_security_policy_cmp(const void *a, const void *b) +row_security_policy_cmp(const ListCell *a, const ListCell *b) { - const RowSecurityPolicy *pa = (const RowSecurityPolicy *) a; - const RowSecurityPolicy *pb = (const RowSecurityPolicy *) b; + const RowSecurityPolicy *pa = (const RowSecurityPolicy *) lfirst(a); + const RowSecurityPolicy *pb = (const RowSecurityPolicy *) lfirst(b); /* Guard against NULL policy names from extensions */ if (pa->policy_name == NULL) diff --git a/src/backend/snowball/Makefile b/src/backend/snowball/Makefile index 50cbace41da..bf55b192347 100644 --- a/src/backend/snowball/Makefile +++ b/src/backend/snowball/Makefile @@ -23,23 +23,31 @@ OBJS= $(WIN32RES) dict_snowball.o api.o utilities.o \ stem_ISO_8859_1_finnish.o \ stem_ISO_8859_1_french.o \ stem_ISO_8859_1_german.o \ - stem_ISO_8859_1_hungarian.o \ + stem_ISO_8859_1_indonesian.o \ + stem_ISO_8859_1_irish.o \ stem_ISO_8859_1_italian.o \ stem_ISO_8859_1_norwegian.o \ stem_ISO_8859_1_porter.o \ stem_ISO_8859_1_portuguese.o \ stem_ISO_8859_1_spanish.o \ stem_ISO_8859_1_swedish.o \ + stem_ISO_8859_2_hungarian.o \ stem_ISO_8859_2_romanian.o \ stem_KOI8_R_russian.o \ + stem_UTF_8_arabic.o \ stem_UTF_8_danish.o \ stem_UTF_8_dutch.o \ stem_UTF_8_english.o \ stem_UTF_8_finnish.o \ stem_UTF_8_french.o \ stem_UTF_8_german.o \ + stem_UTF_8_greek.o \ stem_UTF_8_hungarian.o \ + stem_UTF_8_indonesian.o \ + stem_UTF_8_irish.o \ stem_UTF_8_italian.o \ + stem_UTF_8_lithuanian.o \ + stem_UTF_8_nepali.o \ stem_UTF_8_norwegian.o \ stem_UTF_8_porter.o \ stem_UTF_8_portuguese.o \ @@ -47,6 +55,7 @@ OBJS= $(WIN32RES) dict_snowball.o api.o utilities.o \ stem_UTF_8_russian.o \ stem_UTF_8_spanish.o \ stem_UTF_8_swedish.o \ + stem_UTF_8_tamil.o \ stem_UTF_8_turkish.o # first column is language name and also name of dictionary for not-all-ASCII @@ -54,20 +63,27 @@ OBJS= $(WIN32RES) dict_snowball.o api.o utilities.o \ # Note order dependency: use of some other language as ASCII dictionary # must come after creation of that language LANGUAGES= \ - danish danish \ - dutch dutch \ - english english \ - finnish finnish \ - french french \ - german german \ - hungarian hungarian \ - italian italian \ - norwegian norwegian \ - portuguese portuguese \ - romanian romanian \ - russian english \ - spanish spanish \ - swedish swedish \ + arabic arabic \ + danish danish \ + dutch dutch \ + english english \ + finnish finnish \ + french french \ + german german \ + greek greek \ + hungarian hungarian \ + indonesian indonesian \ + irish irish \ + italian italian \ + lithuanian lithuanian \ + nepali nepali \ + norwegian norwegian \ + portuguese portuguese \ + romanian romanian \ + russian english \ + spanish spanish \ + swedish swedish \ + tamil tamil \ turkish turkish diff --git a/src/backend/snowball/README b/src/backend/snowball/README index d6fe143e998..3463289f1c4 100644 --- a/src/backend/snowball/README +++ b/src/backend/snowball/README @@ -4,46 +4,61 @@ Snowball-Based Stemming ======================= This module uses the word stemming code developed by the Snowball project, -http://snowball.tartarus.org/ +http://snowballstem.org (formerly http://snowball.tartarus.org) which is released by them under a BSD-style license. -The files under src/backend/snowball/libstemmer/ and -src/include/snowball/libstemmer/ are taken directly from their libstemmer_c -distribution, with only some minor adjustments of file inclusions. Note +The Snowball project is not currently making formal releases; it's best +to pull from their git repository + +git clone https://github.com/snowballstem/snowball.git + +and then building the derived files is as simple as + +cd snowball +make + +At least on Linux, no platform-specific adjustment is needed. + +Postgres' files under src/backend/snowball/libstemmer/ and +src/include/snowball/libstemmer/ are taken directly from the Snowball +files, with only some minor adjustments of file inclusions. Note that most of these files are in fact derived files, not master source. -The master sources are in the Snowball language, and are available along -with the Snowball-to-C compiler from the Snowball project. We choose to -include the derived files in the PostgreSQL distribution because most -installations will not have the Snowball compiler available. +The master sources are in the Snowball language, and are built using +the Snowball-to-C compiler that is also part of the Snowball project. +We choose to include the derived files in the PostgreSQL distribution +because most installations will not have the Snowball compiler available. + +We are currently synced with the Snowball git commit +4456b82c26c02493e8807a66f30593a98c5d2888 +of 2019-06-24. -To update the PostgreSQL sources from a new Snowball libstemmer_c -distribution: +To update the PostgreSQL sources from a new Snowball version: -1. Copy the *.c files in libstemmer_c/src_c/ to src/backend/snowball/libstemmer +0. If you didn't do it already, "make -C snowball". + +1. Copy the *.c files in snowball/src_c/ to src/backend/snowball/libstemmer with replacement of "../runtime/header.h" by "header.h", for example -for f in libstemmer_c/src_c/*.c +for f in .../snowball/src_c/*.c do sed 's|\.\./runtime/header\.h|header.h|' $f >libstemmer/`basename $f` done -(Alternatively, if you rebuild the stemmer files from the master Snowball -sources, just omit "-r ../runtime" from the Snowball compiler switches.) - -2. Copy the *.c files in libstemmer_c/runtime/ to +2. Copy the *.c files in snowball/runtime/ to src/backend/snowball/libstemmer, and edit them to remove direct inclusions of system headers such as --- they should only include "header.h". (This removal avoids portability problems on some platforms where is sensitive to largefile compilation options.) -3. Copy the *.h files in libstemmer_c/src_c/ and libstemmer_c/runtime/ +3. Copy the *.h files in snowball/src_c/ and snowball/runtime/ to src/include/snowball/libstemmer. At this writing the header files do not require any changes. 4. Check whether any stemmer modules have been added or removed. If so, edit the OBJS list in Makefile, the list of #include's in dict_snowball.c, and the -stemmer_modules[] table in dict_snowball.c. +stemmer_modules[] table in dict_snowball.c. You might also need to change +the LANGUAGES list in Makefile and tsearch_config_languages in initdb.c. 5. The various stopword files in stopwords/ must be downloaded -individually from pages on the snowball.tartarus.org website. +individually from pages on the snowballstem.org website. Be careful that these files must be stored in UTF-8 encoding. diff --git a/src/backend/snowball/dict_snowball.c b/src/backend/snowball/dict_snowball.c index 78c9f73ef03..1d32b7d356d 100644 --- a/src/backend/snowball/dict_snowball.c +++ b/src/backend/snowball/dict_snowball.c @@ -3,7 +3,7 @@ * dict_snowball.c * Snowball dictionary * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/snowball/dict_snowball.c @@ -32,23 +32,31 @@ #include "snowball/libstemmer/stem_ISO_8859_1_finnish.h" #include "snowball/libstemmer/stem_ISO_8859_1_french.h" #include "snowball/libstemmer/stem_ISO_8859_1_german.h" -#include "snowball/libstemmer/stem_ISO_8859_1_hungarian.h" +#include "snowball/libstemmer/stem_ISO_8859_1_indonesian.h" +#include "snowball/libstemmer/stem_ISO_8859_1_irish.h" #include "snowball/libstemmer/stem_ISO_8859_1_italian.h" #include "snowball/libstemmer/stem_ISO_8859_1_norwegian.h" #include "snowball/libstemmer/stem_ISO_8859_1_porter.h" #include "snowball/libstemmer/stem_ISO_8859_1_portuguese.h" #include "snowball/libstemmer/stem_ISO_8859_1_spanish.h" #include "snowball/libstemmer/stem_ISO_8859_1_swedish.h" +#include "snowball/libstemmer/stem_ISO_8859_2_hungarian.h" #include "snowball/libstemmer/stem_ISO_8859_2_romanian.h" #include "snowball/libstemmer/stem_KOI8_R_russian.h" +#include "snowball/libstemmer/stem_UTF_8_arabic.h" #include "snowball/libstemmer/stem_UTF_8_danish.h" #include "snowball/libstemmer/stem_UTF_8_dutch.h" #include "snowball/libstemmer/stem_UTF_8_english.h" #include "snowball/libstemmer/stem_UTF_8_finnish.h" #include "snowball/libstemmer/stem_UTF_8_french.h" #include "snowball/libstemmer/stem_UTF_8_german.h" +#include "snowball/libstemmer/stem_UTF_8_greek.h" #include "snowball/libstemmer/stem_UTF_8_hungarian.h" +#include "snowball/libstemmer/stem_UTF_8_indonesian.h" +#include "snowball/libstemmer/stem_UTF_8_irish.h" #include "snowball/libstemmer/stem_UTF_8_italian.h" +#include "snowball/libstemmer/stem_UTF_8_lithuanian.h" +#include "snowball/libstemmer/stem_UTF_8_nepali.h" #include "snowball/libstemmer/stem_UTF_8_norwegian.h" #include "snowball/libstemmer/stem_UTF_8_porter.h" #include "snowball/libstemmer/stem_UTF_8_portuguese.h" @@ -56,6 +64,7 @@ #include "snowball/libstemmer/stem_UTF_8_russian.h" #include "snowball/libstemmer/stem_UTF_8_spanish.h" #include "snowball/libstemmer/stem_UTF_8_swedish.h" +#include "snowball/libstemmer/stem_UTF_8_tamil.h" #include "snowball/libstemmer/stem_UTF_8_turkish.h" PG_MODULE_MAGIC; @@ -74,48 +83,61 @@ typedef struct stemmer_module int (*stem) (struct SN_env *); } stemmer_module; +/* Args: stemmer name, PG code for encoding, Snowball's name for encoding */ +#define STEMMER_MODULE(name,enc,senc) \ + {#name, enc, name##_##senc##_create_env, name##_##senc##_close_env, name##_##senc##_stem} + static const stemmer_module stemmer_modules[] = { /* * Stemmers list from Snowball distribution */ - {"danish", PG_LATIN1, danish_ISO_8859_1_create_env, danish_ISO_8859_1_close_env, danish_ISO_8859_1_stem}, - {"dutch", PG_LATIN1, dutch_ISO_8859_1_create_env, dutch_ISO_8859_1_close_env, dutch_ISO_8859_1_stem}, - {"english", PG_LATIN1, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, - {"finnish", PG_LATIN1, finnish_ISO_8859_1_create_env, finnish_ISO_8859_1_close_env, finnish_ISO_8859_1_stem}, - {"french", PG_LATIN1, french_ISO_8859_1_create_env, french_ISO_8859_1_close_env, french_ISO_8859_1_stem}, - {"german", PG_LATIN1, german_ISO_8859_1_create_env, german_ISO_8859_1_close_env, german_ISO_8859_1_stem}, - {"hungarian", PG_LATIN1, hungarian_ISO_8859_1_create_env, hungarian_ISO_8859_1_close_env, hungarian_ISO_8859_1_stem}, - {"italian", PG_LATIN1, italian_ISO_8859_1_create_env, italian_ISO_8859_1_close_env, italian_ISO_8859_1_stem}, - {"norwegian", PG_LATIN1, norwegian_ISO_8859_1_create_env, norwegian_ISO_8859_1_close_env, norwegian_ISO_8859_1_stem}, - {"porter", PG_LATIN1, porter_ISO_8859_1_create_env, porter_ISO_8859_1_close_env, porter_ISO_8859_1_stem}, - {"portuguese", PG_LATIN1, portuguese_ISO_8859_1_create_env, portuguese_ISO_8859_1_close_env, portuguese_ISO_8859_1_stem}, - {"spanish", PG_LATIN1, spanish_ISO_8859_1_create_env, spanish_ISO_8859_1_close_env, spanish_ISO_8859_1_stem}, - {"swedish", PG_LATIN1, swedish_ISO_8859_1_create_env, swedish_ISO_8859_1_close_env, swedish_ISO_8859_1_stem}, - {"romanian", PG_LATIN2, romanian_ISO_8859_2_create_env, romanian_ISO_8859_2_close_env, romanian_ISO_8859_2_stem}, - {"russian", PG_KOI8R, russian_KOI8_R_create_env, russian_KOI8_R_close_env, russian_KOI8_R_stem}, - {"danish", PG_UTF8, danish_UTF_8_create_env, danish_UTF_8_close_env, danish_UTF_8_stem}, - {"dutch", PG_UTF8, dutch_UTF_8_create_env, dutch_UTF_8_close_env, dutch_UTF_8_stem}, - {"english", PG_UTF8, english_UTF_8_create_env, english_UTF_8_close_env, english_UTF_8_stem}, - {"finnish", PG_UTF8, finnish_UTF_8_create_env, finnish_UTF_8_close_env, finnish_UTF_8_stem}, - {"french", PG_UTF8, french_UTF_8_create_env, french_UTF_8_close_env, french_UTF_8_stem}, - {"german", PG_UTF8, german_UTF_8_create_env, german_UTF_8_close_env, german_UTF_8_stem}, - {"hungarian", PG_UTF8, hungarian_UTF_8_create_env, hungarian_UTF_8_close_env, hungarian_UTF_8_stem}, - {"italian", PG_UTF8, italian_UTF_8_create_env, italian_UTF_8_close_env, italian_UTF_8_stem}, - {"norwegian", PG_UTF8, norwegian_UTF_8_create_env, norwegian_UTF_8_close_env, norwegian_UTF_8_stem}, - {"porter", PG_UTF8, porter_UTF_8_create_env, porter_UTF_8_close_env, porter_UTF_8_stem}, - {"portuguese", PG_UTF8, portuguese_UTF_8_create_env, portuguese_UTF_8_close_env, portuguese_UTF_8_stem}, - {"romanian", PG_UTF8, romanian_UTF_8_create_env, romanian_UTF_8_close_env, romanian_UTF_8_stem}, - {"russian", PG_UTF8, russian_UTF_8_create_env, russian_UTF_8_close_env, russian_UTF_8_stem}, - {"spanish", PG_UTF8, spanish_UTF_8_create_env, spanish_UTF_8_close_env, spanish_UTF_8_stem}, - {"swedish", PG_UTF8, swedish_UTF_8_create_env, swedish_UTF_8_close_env, swedish_UTF_8_stem}, - {"turkish", PG_UTF8, turkish_UTF_8_create_env, turkish_UTF_8_close_env, turkish_UTF_8_stem}, + STEMMER_MODULE(danish, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(dutch, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(english, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(finnish, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(french, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(german, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(indonesian, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(irish, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(italian, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(norwegian, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(porter, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(portuguese, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(spanish, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(swedish, PG_LATIN1, ISO_8859_1), + STEMMER_MODULE(hungarian, PG_LATIN2, ISO_8859_2), + STEMMER_MODULE(romanian, PG_LATIN2, ISO_8859_2), + STEMMER_MODULE(russian, PG_KOI8R, KOI8_R), + STEMMER_MODULE(arabic, PG_UTF8, UTF_8), + STEMMER_MODULE(danish, PG_UTF8, UTF_8), + STEMMER_MODULE(dutch, PG_UTF8, UTF_8), + STEMMER_MODULE(english, PG_UTF8, UTF_8), + STEMMER_MODULE(finnish, PG_UTF8, UTF_8), + STEMMER_MODULE(french, PG_UTF8, UTF_8), + STEMMER_MODULE(german, PG_UTF8, UTF_8), + STEMMER_MODULE(greek, PG_UTF8, UTF_8), + STEMMER_MODULE(hungarian, PG_UTF8, UTF_8), + STEMMER_MODULE(indonesian, PG_UTF8, UTF_8), + STEMMER_MODULE(irish, PG_UTF8, UTF_8), + STEMMER_MODULE(italian, PG_UTF8, UTF_8), + STEMMER_MODULE(lithuanian, PG_UTF8, UTF_8), + STEMMER_MODULE(nepali, PG_UTF8, UTF_8), + STEMMER_MODULE(norwegian, PG_UTF8, UTF_8), + STEMMER_MODULE(porter, PG_UTF8, UTF_8), + STEMMER_MODULE(portuguese, PG_UTF8, UTF_8), + STEMMER_MODULE(romanian, PG_UTF8, UTF_8), + STEMMER_MODULE(russian, PG_UTF8, UTF_8), + STEMMER_MODULE(spanish, PG_UTF8, UTF_8), + STEMMER_MODULE(swedish, PG_UTF8, UTF_8), + STEMMER_MODULE(tamil, PG_UTF8, UTF_8), + STEMMER_MODULE(turkish, PG_UTF8, UTF_8), /* * Stemmer with PG_SQL_ASCII encoding should be valid for any server * encoding */ - {"english", PG_SQL_ASCII, english_ISO_8859_1_create_env, english_ISO_8859_1_close_env, english_ISO_8859_1_stem}, + STEMMER_MODULE(english, PG_SQL_ASCII, ISO_8859_1), {NULL, 0, NULL, NULL, NULL} /* list end marker */ }; diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c index 36a9f99276f..0ecbbb76a8f 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_danish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -124,6 +124,8 @@ static const struct among a_2[5] = /* 4 */ { 4, s_2_4, -1, 2, 0} }; +static const unsigned char g_c[] = { 119, 223, 119, 1 }; + static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; static const unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }; @@ -132,55 +134,52 @@ static const symbol s_0[] = { 's', 't' }; static const symbol s_1[] = { 'i', 'g' }; static const symbol s_2[] = { 'l', 0xF8, 's' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 33 */ - { int ret = z->c + 3; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 33 */ + { int c_test1 = z->c; /* test, line 35 */ + { int ret = z->c + 3; /* hop, line 35 */ if (0 > ret || ret > z->l) return 0; - z->c = ret; /* hop, line 33 */ + z->c = ret; } - z->I[1] = z->c; /* setmark x, line 33 */ - z->c = c_test; + z->I[1] = z->c; /* setmark x, line 35 */ + z->c = c_test1; } - if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 34 */ - { /* gopast */ /* non v, line 34 */ + if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 36 */ + { /* gopast */ /* non v, line 36 */ int ret = in_grouping(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 34 */ - /* try, line 35 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + z->I[0] = z->c; /* setmark p1, line 36 */ + /* try, line 37 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 37 */ + z->I[0] = z->I[1]; /* $p1 = , line 37 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 41 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 43 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 41 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 41 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 32); /* substring, line 41 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 41 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 43 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 43 */ + among_var = find_among_b(z, a_0, 32); + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 43 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 44 */ case 1: - { int ret = slice_del(z); /* delete, line 48 */ + { int ret = slice_del(z); /* delete, line 50 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_s_ending, 97, 229, 0)) return 0; - { int ret = slice_del(z); /* delete, line 50 */ + if (in_grouping_b(z, g_s_ending, 97, 229, 0)) return 0; /* grouping s_ending, line 52 */ + { int ret = slice_del(z); /* delete, line 52 */ if (ret < 0) return ret; } break; @@ -188,66 +187,61 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 55 */ - { int mlimit; /* setlimit, line 56 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 57 */ + + { int mlimit2; /* setlimit, line 58 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 56 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit; return 0; } /* substring, line 56 */ - z->bra = z->c; /* ], line 56 */ - z->lb = mlimit; + mlimit2 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 58 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } /* substring, line 58 */ + if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit2; return 0; } + z->bra = z->c; /* ], line 58 */ + z->lb = mlimit2; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } if (z->c <= z->lb) return 0; - z->c--; /* next, line 62 */ - z->bra = z->c; /* ], line 62 */ - { int ret = slice_del(z); /* delete, line 62 */ + z->c--; /* next, line 64 */ + z->bra = z->c; /* ], line 64 */ + { int ret = slice_del(z); /* delete, line 64 */ if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 66 */ - z->ket = z->c; /* [, line 66 */ - if (!(eq_s_b(z, 2, s_0))) goto lab0; - z->bra = z->c; /* ], line 66 */ - if (!(eq_s_b(z, 2, s_1))) goto lab0; - { int ret = slice_del(z); /* delete, line 66 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 68 */ + z->ket = z->c; /* [, line 68 */ + if (!(eq_s_b(z, 2, s_0))) goto lab0; /* literal, line 68 */ + z->bra = z->c; /* ], line 68 */ + if (!(eq_s_b(z, 2, s_1))) goto lab0; /* literal, line 68 */ + { int ret = slice_del(z); /* delete, line 68 */ if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - { int mlimit; /* setlimit, line 67 */ - int m2 = z->l - z->c; (void)m2; + + { int mlimit2; /* setlimit, line 69 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 67 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - z->ket = z->c; /* [, line 67 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 5); /* substring, line 67 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 67 */ - z->lb = mlimit; + mlimit2 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 69 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } /* substring, line 69 */ + among_var = find_among_b(z, a_2, 5); + if (!(among_var)) { z->lb = mlimit2; return 0; } + z->bra = z->c; /* ], line 69 */ + z->lb = mlimit2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 70 */ case 1: - { int ret = slice_del(z); /* delete, line 70 */ + { int ret = slice_del(z); /* delete, line 72 */ if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* do, line 70 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab1; /* call consonant_pair, line 70 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 72 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 72 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -255,7 +249,7 @@ static int r_other_suffix(struct SN_env * z) { } break; case 2: - { int ret = slice_from_s(z, 3, s_2); /* <-, line 72 */ + { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ if (ret < 0) return ret; } break; @@ -263,65 +257,63 @@ static int r_other_suffix(struct SN_env * z) { return 1; } -static int r_undouble(struct SN_env * z) { - { int mlimit; /* setlimit, line 76 */ - int m1 = z->l - z->c; (void)m1; +static int r_undouble(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 78 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 76 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 76 */ - if (out_grouping_b(z, g_v, 97, 248, 0)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 76 */ - z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */ - if (z->S[0] == 0) return -1; /* -> ch, line 76 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 78 */ + if (in_grouping_b(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } /* grouping c, line 78 */ + z->bra = z->c; /* ], line 78 */ + z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 78 */ + if (z->S[0] == 0) return -1; /* -> ch, line 78 */ + z->lb = mlimit1; } - if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */ - { int ret = slice_del(z); /* delete, line 78 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 79 */ + { int ret = slice_del(z); /* delete, line 80 */ if (ret < 0) return ret; } return 1; } -extern int danish_ISO_8859_1_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 84 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 84 */ +extern int danish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 86 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 86 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 85 */ + z->lb = z->c; z->c = z->l; /* backwards, line 87 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 86 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 86 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 88 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 87 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 87 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 89 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 89 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 88 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 88 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 90 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 90 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 89 */ - { int ret = r_undouble(z); - if (ret == 0) goto lab4; /* call undouble, line 89 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 91 */ + { int ret = r_undouble(z); /* call undouble, line 91 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c index e5ba288b1f5..b3d2c4e5d13 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_dutch.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -134,36 +134,28 @@ static const symbol s_1[] = { 'e' }; static const symbol s_2[] = { 'i' }; static const symbol s_3[] = { 'o' }; static const symbol s_4[] = { 'u' }; -static const symbol s_5[] = { 'y' }; -static const symbol s_6[] = { 'Y' }; -static const symbol s_7[] = { 'i' }; -static const symbol s_8[] = { 'I' }; -static const symbol s_9[] = { 'y' }; -static const symbol s_10[] = { 'Y' }; -static const symbol s_11[] = { 'y' }; -static const symbol s_12[] = { 'i' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'g', 'e', 'm' }; -static const symbol s_15[] = { 'h', 'e', 'i', 'd' }; -static const symbol s_16[] = { 'h', 'e', 'i', 'd' }; -static const symbol s_17[] = { 'c' }; -static const symbol s_18[] = { 'e', 'n' }; -static const symbol s_19[] = { 'i', 'g' }; -static const symbol s_20[] = { 'e' }; -static const symbol s_21[] = { 'e' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_5[] = { 'Y' }; +static const symbol s_6[] = { 'I' }; +static const symbol s_7[] = { 'Y' }; +static const symbol s_8[] = { 'y' }; +static const symbol s_9[] = { 'i' }; +static const symbol s_10[] = { 'g', 'e', 'm' }; +static const symbol s_11[] = { 'h', 'e', 'i', 'd' }; +static const symbol s_12[] = { 'h', 'e', 'i', 'd' }; +static const symbol s_13[] = { 'e', 'n' }; +static const symbol s_14[] = { 'i', 'g' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; - { int c_test = z->c; /* test, line 42 */ + { int c_test1 = z->c; /* test, line 42 */ while(1) { /* repeat, line 42 */ - int c1 = z->c; + int c2 = z->c; z->bra = z->c; /* [, line 43 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((340306450 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else - among_var = find_among(z, a_0, 11); /* substring, line 43 */ + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((340306450 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else /* substring, line 43 */ + among_var = find_among(z, a_0, 11); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 43 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 43 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ if (ret < 0) return ret; @@ -196,62 +188,65 @@ static int r_prelude(struct SN_env * z) { } continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } - { int c_keep = z->c; /* try, line 57 */ + { int c3 = z->c; /* try, line 57 */ z->bra = z->c; /* [, line 57 */ - if (!(eq_s(z, 1, s_5))) { z->c = c_keep; goto lab1; } + if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } /* literal, line 57 */ + z->c++; z->ket = z->c; /* ], line 57 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 57 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 57 */ if (ret < 0) return ret; } lab1: ; } while(1) { /* repeat, line 58 */ - int c2 = z->c; + int c4 = z->c; while(1) { /* goto, line 58 */ - int c3 = z->c; - if (in_grouping(z, g_v, 97, 232, 0)) goto lab3; + int c5 = z->c; + if (in_grouping(z, g_v, 97, 232, 0)) goto lab3; /* grouping v, line 59 */ z->bra = z->c; /* [, line 59 */ - { int c4 = z->c; /* or, line 59 */ - if (!(eq_s(z, 1, s_7))) goto lab5; + { int c6 = z->c; /* or, line 59 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab5; /* literal, line 59 */ + z->c++; z->ket = z->c; /* ], line 59 */ - if (in_grouping(z, g_v, 97, 232, 0)) goto lab5; - { int ret = slice_from_s(z, 1, s_8); /* <-, line 59 */ + if (in_grouping(z, g_v, 97, 232, 0)) goto lab5; /* grouping v, line 59 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 59 */ if (ret < 0) return ret; } goto lab4; lab5: - z->c = c4; - if (!(eq_s(z, 1, s_9))) goto lab3; + z->c = c6; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 60 */ + z->c++; z->ket = z->c; /* ], line 60 */ - { int ret = slice_from_s(z, 1, s_10); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 60 */ if (ret < 0) return ret; } } lab4: - z->c = c3; + z->c = c5; break; lab3: - z->c = c3; + z->c = c5; if (z->c >= z->l) goto lab2; z->c++; /* goto, line 58 */ } continue; lab2: - z->c = c2; + z->c = c4; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 66 */ + z->I[1] = z->l; /* $p2 = , line 67 */ { /* gopast */ /* grouping v, line 69 */ int ret = out_grouping(z, g_v, 97, 232, 1); if (ret < 0) return 0; @@ -263,9 +258,9 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 69 */ - /* try, line 70 */ - if (!(z->I[0] < 3)) goto lab0; - z->I[0] = 3; + /* try, line 70 */ + if (!(z->I[0] < 3)) goto lab0; /* $( < ), line 70 */ + z->I[0] = 3; /* $p1 = , line 70 */ lab0: { /* gopast */ /* grouping v, line 71 */ int ret = out_grouping(z, g_v, 97, 232, 1); @@ -281,24 +276,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 75 */ int c1 = z->c; z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 77 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else /* substring, line 77 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 77 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 77 */ case 1: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 78 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 79 */ if (ret < 0) return ret; } break; @@ -315,21 +309,21 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 87 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 88 */ return 1; } -static int r_undouble(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 91 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */ - z->c = z->l - m_test; +static int r_undouble(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 91 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 91 */ + if (!(find_among_b(z, a_2, 3))) return 0; + z->c = z->l - m_test1; } z->ket = z->c; /* [, line 91 */ if (z->c <= z->lb) return 0; @@ -341,40 +335,38 @@ static int r_undouble(struct SN_env * z) { return 1; } -static int r_e_ending(struct SN_env * z) { +static int r_e_ending(struct SN_env * z) { /* backwardmode */ z->B[0] = 0; /* unset e_found, line 95 */ z->ket = z->c; /* [, line 96 */ - if (!(eq_s_b(z, 1, s_13))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 96 */ + z->c--; z->bra = z->c; /* ], line 96 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 96 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 96 */ + if (ret <= 0) return ret; } - { int m_test = z->l - z->c; /* test, line 96 */ - if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; - z->c = z->l - m_test; + { int m_test1 = z->l - z->c; /* test, line 96 */ + if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; /* non v, line 96 */ + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 96 */ if (ret < 0) return ret; } z->B[0] = 1; /* set e_found, line 97 */ - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 98 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 98 */ + if (ret <= 0) return ret; } return 1; } -static int r_en_ending(struct SN_env * z) { - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 102 */ - if (ret < 0) return ret; +static int r_en_ending(struct SN_env * z) { /* backwardmode */ + { int ret = r_R1(z); /* call R1, line 102 */ + if (ret <= 0) return ret; } { int m1 = z->l - z->c; (void)m1; /* and, line 102 */ - if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; + if (out_grouping_b(z, g_v, 97, 232, 0)) return 0; /* non v, line 102 */ z->c = z->l - m1; { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - if (!(eq_s_b(z, 3, s_14))) goto lab0; + if (!(eq_s_b(z, 3, s_10))) goto lab0; /* literal, line 102 */ return 0; lab0: z->c = z->l - m2; @@ -383,44 +375,42 @@ static int r_en_ending(struct SN_env * z) { { int ret = slice_del(z); /* delete, line 102 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 103 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 103 */ + if (ret <= 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; { int m1 = z->l - z->c; (void)m1; /* do, line 107 */ z->ket = z->c; /* [, line 108 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; - among_var = find_among_b(z, a_3, 5); /* substring, line 108 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 108 */ + among_var = find_among_b(z, a_3, 5); if (!(among_var)) goto lab0; z->bra = z->c; /* ], line 108 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 108 */ case 1: - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 110 */ + { int ret = r_R1(z); /* call R1, line 110 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - { int ret = slice_from_s(z, 4, s_15); /* <-, line 110 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 110 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_en_ending(z); - if (ret == 0) goto lab0; /* call en_ending, line 113 */ + { int ret = r_en_ending(z); /* call en_ending, line 113 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } break; case 3: - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 116 */ + { int ret = r_R1(z); /* call R1, line 116 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - if (out_grouping_b(z, g_v_j, 97, 232, 0)) goto lab0; + if (out_grouping_b(z, g_v_j, 97, 232, 0)) goto lab0; /* non v_j, line 116 */ { int ret = slice_del(z); /* delete, line 116 */ if (ret < 0) return ret; } @@ -430,8 +420,8 @@ static int r_standard_suffix(struct SN_env * z) { z->c = z->l - m1; } { int m2 = z->l - z->c; (void)m2; /* do, line 120 */ - { int ret = r_e_ending(z); - if (ret == 0) goto lab1; /* call e_ending, line 120 */ + { int ret = r_e_ending(z); /* call e_ending, line 120 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -439,14 +429,15 @@ static int r_standard_suffix(struct SN_env * z) { } { int m3 = z->l - z->c; (void)m3; /* do, line 122 */ z->ket = z->c; /* [, line 122 */ - if (!(eq_s_b(z, 4, s_16))) goto lab2; + if (!(eq_s_b(z, 4, s_12))) goto lab2; /* literal, line 122 */ z->bra = z->c; /* ], line 122 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 122 */ + { int ret = r_R2(z); /* call R2, line 122 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } { int m4 = z->l - z->c; (void)m4; /* not, line 122 */ - if (!(eq_s_b(z, 1, s_17))) goto lab3; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab3; /* literal, line 122 */ + z->c--; goto lab2; lab3: z->c = z->l - m4; @@ -455,10 +446,10 @@ static int r_standard_suffix(struct SN_env * z) { if (ret < 0) return ret; } z->ket = z->c; /* [, line 123 */ - if (!(eq_s_b(z, 2, s_18))) goto lab2; + if (!(eq_s_b(z, 2, s_13))) goto lab2; /* literal, line 123 */ z->bra = z->c; /* ], line 123 */ - { int ret = r_en_ending(z); - if (ret == 0) goto lab2; /* call en_ending, line 123 */ + { int ret = r_en_ending(z); /* call en_ending, line 123 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: @@ -466,15 +457,14 @@ static int r_standard_suffix(struct SN_env * z) { } { int m5 = z->l - z->c; (void)m5; /* do, line 126 */ z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4; - among_var = find_among_b(z, a_4, 6); /* substring, line 127 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4; /* substring, line 127 */ + among_var = find_among_b(z, a_4, 6); if (!(among_var)) goto lab4; z->bra = z->c; /* ], line 127 */ - switch(among_var) { - case 0: goto lab4; + switch (among_var) { /* among, line 127 */ case 1: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 129 */ + { int ret = r_R2(z); /* call R2, line 129 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 129 */ @@ -482,14 +472,15 @@ static int r_standard_suffix(struct SN_env * z) { } { int m6 = z->l - z->c; (void)m6; /* or, line 130 */ z->ket = z->c; /* [, line 130 */ - if (!(eq_s_b(z, 2, s_19))) goto lab6; + if (!(eq_s_b(z, 2, s_14))) goto lab6; /* literal, line 130 */ z->bra = z->c; /* ], line 130 */ - { int ret = r_R2(z); - if (ret == 0) goto lab6; /* call R2, line 130 */ + { int ret = r_R2(z); /* call R2, line 130 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } { int m7 = z->l - z->c; (void)m7; /* not, line 130 */ - if (!(eq_s_b(z, 1, s_20))) goto lab7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; /* literal, line 130 */ + z->c--; goto lab6; lab7: z->c = z->l - m7; @@ -500,20 +491,21 @@ static int r_standard_suffix(struct SN_env * z) { goto lab5; lab6: z->c = z->l - m6; - { int ret = r_undouble(z); - if (ret == 0) goto lab4; /* call undouble, line 130 */ + { int ret = r_undouble(z); /* call undouble, line 130 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: break; case 2: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 133 */ + { int ret = r_R2(z); /* call R2, line 133 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int m8 = z->l - z->c; (void)m8; /* not, line 133 */ - if (!(eq_s_b(z, 1, s_21))) goto lab8; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab8; /* literal, line 133 */ + z->c--; goto lab4; lab8: z->c = z->l - m8; @@ -523,21 +515,21 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 136 */ + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; } - { int ret = r_e_ending(z); - if (ret == 0) goto lab4; /* call e_ending, line 136 */ + { int ret = r_e_ending(z); /* call e_ending, line 136 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 139 */ + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 139 */ @@ -545,8 +537,8 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 5: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 142 */ + { int ret = r_R2(z); /* call R2, line 142 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */ @@ -559,12 +551,12 @@ static int r_standard_suffix(struct SN_env * z) { z->c = z->l - m5; } { int m9 = z->l - z->c; (void)m9; /* do, line 146 */ - if (out_grouping_b(z, g_v_I, 73, 232, 0)) goto lab9; - { int m_test = z->l - z->c; /* test, line 148 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9; - if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */ - if (out_grouping_b(z, g_v, 97, 232, 0)) goto lab9; - z->c = z->l - m_test; + if (out_grouping_b(z, g_v_I, 73, 232, 0)) goto lab9; /* non v_I, line 147 */ + { int m_test10 = z->l - z->c; /* test, line 148 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9; /* among, line 149 */ + if (!(find_among_b(z, a_5, 4))) goto lab9; + if (out_grouping_b(z, g_v, 97, 232, 0)) goto lab9; /* non v, line 150 */ + z->c = z->l - m_test10; } z->ket = z->c; /* [, line 152 */ if (z->c <= z->lb) goto lab9; @@ -579,18 +571,18 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -extern int dutch_ISO_8859_1_stem(struct SN_env * z) { +extern int dutch_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 159 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 159 */ + { int ret = r_prelude(z); /* call prelude, line 159 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } { int c2 = z->c; /* do, line 160 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 160 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 160 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -598,22 +590,20 @@ extern int dutch_ISO_8859_1_stem(struct SN_env * z) { } z->lb = z->c; z->c = z->l; /* backwards, line 161 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 162 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab2; /* call standard_suffix, line 162 */ - if (ret < 0) return ret; - } - lab2: - z->c = z->l - m3; + /* do, line 162 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 162 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; } +lab2: z->c = z->lb; - { int c4 = z->c; /* do, line 163 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab3; /* call postlude, line 163 */ + { int c3 = z->c; /* do, line 163 */ + { int ret = r_postlude(z); /* call postlude, line 163 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = c4; + z->c = c3; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c index 141c45dc275..87ff8041aa3 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_english.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -153,12 +153,12 @@ static const struct among a_5[24] = /* 0 */ { 4, s_5_0, -1, 3, 0}, /* 1 */ { 4, s_5_1, -1, 2, 0}, /* 2 */ { 3, s_5_2, -1, 13, 0}, -/* 3 */ { 2, s_5_3, -1, 16, 0}, +/* 3 */ { 2, s_5_3, -1, 15, 0}, /* 4 */ { 3, s_5_4, 3, 12, 0}, /* 5 */ { 4, s_5_5, 4, 4, 0}, /* 6 */ { 4, s_5_6, 3, 8, 0}, -/* 7 */ { 5, s_5_7, 3, 14, 0}, -/* 8 */ { 6, s_5_8, 3, 15, 0}, +/* 7 */ { 5, s_5_7, 3, 9, 0}, +/* 8 */ { 6, s_5_8, 3, 14, 0}, /* 9 */ { 5, s_5_9, 3, 10, 0}, /* 10 */ { 5, s_5_10, 3, 5, 0}, /* 11 */ { 5, s_5_11, -1, 8, 0}, @@ -317,62 +317,52 @@ static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; static const unsigned char g_valid_LI[] = { 55, 141, 2 }; -static const symbol s_0[] = { '\'' }; -static const symbol s_1[] = { 'y' }; -static const symbol s_2[] = { 'Y' }; -static const symbol s_3[] = { 'y' }; -static const symbol s_4[] = { 'Y' }; -static const symbol s_5[] = { 's', 's' }; -static const symbol s_6[] = { 'i' }; -static const symbol s_7[] = { 'i', 'e' }; -static const symbol s_8[] = { 'e', 'e' }; -static const symbol s_9[] = { 'e' }; -static const symbol s_10[] = { 'e' }; -static const symbol s_11[] = { 'y' }; -static const symbol s_12[] = { 'Y' }; -static const symbol s_13[] = { 'i' }; -static const symbol s_14[] = { 't', 'i', 'o', 'n' }; -static const symbol s_15[] = { 'e', 'n', 'c', 'e' }; -static const symbol s_16[] = { 'a', 'n', 'c', 'e' }; -static const symbol s_17[] = { 'a', 'b', 'l', 'e' }; -static const symbol s_18[] = { 'e', 'n', 't' }; -static const symbol s_19[] = { 'i', 'z', 'e' }; -static const symbol s_20[] = { 'a', 't', 'e' }; -static const symbol s_21[] = { 'a', 'l' }; -static const symbol s_22[] = { 'f', 'u', 'l' }; -static const symbol s_23[] = { 'o', 'u', 's' }; -static const symbol s_24[] = { 'i', 'v', 'e' }; -static const symbol s_25[] = { 'b', 'l', 'e' }; -static const symbol s_26[] = { 'l' }; -static const symbol s_27[] = { 'o', 'g' }; -static const symbol s_28[] = { 'f', 'u', 'l' }; -static const symbol s_29[] = { 'l', 'e', 's', 's' }; -static const symbol s_30[] = { 't', 'i', 'o', 'n' }; -static const symbol s_31[] = { 'a', 't', 'e' }; -static const symbol s_32[] = { 'a', 'l' }; -static const symbol s_33[] = { 'i', 'c' }; -static const symbol s_34[] = { 's' }; -static const symbol s_35[] = { 't' }; -static const symbol s_36[] = { 'l' }; -static const symbol s_37[] = { 's', 'k', 'i' }; -static const symbol s_38[] = { 's', 'k', 'y' }; -static const symbol s_39[] = { 'd', 'i', 'e' }; -static const symbol s_40[] = { 'l', 'i', 'e' }; -static const symbol s_41[] = { 't', 'i', 'e' }; -static const symbol s_42[] = { 'i', 'd', 'l' }; -static const symbol s_43[] = { 'g', 'e', 'n', 't', 'l' }; -static const symbol s_44[] = { 'u', 'g', 'l', 'i' }; -static const symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' }; -static const symbol s_46[] = { 'o', 'n', 'l', 'i' }; -static const symbol s_47[] = { 's', 'i', 'n', 'g', 'l' }; -static const symbol s_48[] = { 'Y' }; -static const symbol s_49[] = { 'y' }; +static const symbol s_0[] = { 'Y' }; +static const symbol s_1[] = { 'Y' }; +static const symbol s_2[] = { 's', 's' }; +static const symbol s_3[] = { 'i' }; +static const symbol s_4[] = { 'i', 'e' }; +static const symbol s_5[] = { 'e', 'e' }; +static const symbol s_6[] = { 'e' }; +static const symbol s_7[] = { 'e' }; +static const symbol s_8[] = { 'i' }; +static const symbol s_9[] = { 't', 'i', 'o', 'n' }; +static const symbol s_10[] = { 'e', 'n', 'c', 'e' }; +static const symbol s_11[] = { 'a', 'n', 'c', 'e' }; +static const symbol s_12[] = { 'a', 'b', 'l', 'e' }; +static const symbol s_13[] = { 'e', 'n', 't' }; +static const symbol s_14[] = { 'i', 'z', 'e' }; +static const symbol s_15[] = { 'a', 't', 'e' }; +static const symbol s_16[] = { 'a', 'l' }; +static const symbol s_17[] = { 'f', 'u', 'l' }; +static const symbol s_18[] = { 'o', 'u', 's' }; +static const symbol s_19[] = { 'i', 'v', 'e' }; +static const symbol s_20[] = { 'b', 'l', 'e' }; +static const symbol s_21[] = { 'o', 'g' }; +static const symbol s_22[] = { 'l', 'e', 's', 's' }; +static const symbol s_23[] = { 't', 'i', 'o', 'n' }; +static const symbol s_24[] = { 'a', 't', 'e' }; +static const symbol s_25[] = { 'a', 'l' }; +static const symbol s_26[] = { 'i', 'c' }; +static const symbol s_27[] = { 's', 'k', 'i' }; +static const symbol s_28[] = { 's', 'k', 'y' }; +static const symbol s_29[] = { 'd', 'i', 'e' }; +static const symbol s_30[] = { 'l', 'i', 'e' }; +static const symbol s_31[] = { 't', 'i', 'e' }; +static const symbol s_32[] = { 'i', 'd', 'l' }; +static const symbol s_33[] = { 'g', 'e', 'n', 't', 'l' }; +static const symbol s_34[] = { 'u', 'g', 'l', 'i' }; +static const symbol s_35[] = { 'e', 'a', 'r', 'l', 'i' }; +static const symbol s_36[] = { 'o', 'n', 'l', 'i' }; +static const symbol s_37[] = { 's', 'i', 'n', 'g', 'l' }; +static const symbol s_38[] = { 'y' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ z->B[0] = 0; /* unset Y_found, line 26 */ { int c1 = z->c; /* do, line 27 */ z->bra = z->c; /* [, line 27 */ - if (!(eq_s(z, 1, s_0))) goto lab0; + if (z->c == z->l || z->p[z->c] != '\'') goto lab0; /* literal, line 27 */ + z->c++; z->ket = z->c; /* ], line 27 */ { int ret = slice_del(z); /* delete, line 27 */ if (ret < 0) return ret; @@ -382,9 +372,10 @@ static int r_prelude(struct SN_env * z) { } { int c2 = z->c; /* do, line 28 */ z->bra = z->c; /* [, line 28 */ - if (!(eq_s(z, 1, s_1))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'y') goto lab1; /* literal, line 28 */ + z->c++; z->ket = z->c; /* ], line 28 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 28 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 28 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 28 */ @@ -396,9 +387,10 @@ static int r_prelude(struct SN_env * z) { int c4 = z->c; while(1) { /* goto, line 29 */ int c5 = z->c; - if (in_grouping(z, g_v, 97, 121, 0)) goto lab4; + if (in_grouping(z, g_v, 97, 121, 0)) goto lab4; /* grouping v, line 29 */ z->bra = z->c; /* [, line 29 */ - if (!(eq_s(z, 1, s_3))) goto lab4; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 29 */ + z->c++; z->ket = z->c; /* ], line 29 */ z->c = c5; break; @@ -407,7 +399,7 @@ static int r_prelude(struct SN_env * z) { if (z->c >= z->l) goto lab3; z->c++; /* goto, line 29 */ } - { int ret = slice_from_s(z, 1, s_4); /* <-, line 29 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 29 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 29 */ @@ -421,13 +413,13 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 33 */ + z->I[1] = z->l; /* $p2 = , line 34 */ { int c1 = z->c; /* do, line 35 */ { int c2 = z->c; /* or, line 41 */ - if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; - if (!(find_among(z, a_0, 3))) goto lab2; /* among, line 36 */ + if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; /* among, line 36 */ + if (!(find_among(z, a_0, 3))) goto lab2; goto lab1; lab2: z->c = c2; @@ -461,76 +453,69 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_shortv(struct SN_env * z) { +static int r_shortv(struct SN_env * z) { /* backwardmode */ { int m1 = z->l - z->c; (void)m1; /* or, line 51 */ - if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) goto lab1; - if (in_grouping_b(z, g_v, 97, 121, 0)) goto lab1; - if (out_grouping_b(z, g_v, 97, 121, 0)) goto lab1; + if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) goto lab1; /* non v_WXY, line 50 */ + if (in_grouping_b(z, g_v, 97, 121, 0)) goto lab1; /* grouping v, line 50 */ + if (out_grouping_b(z, g_v, 97, 121, 0)) goto lab1; /* non v, line 50 */ goto lab0; lab1: z->c = z->l - m1; - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; - if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 52 */ + if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 52 */ if (z->c > z->lb) return 0; /* atlimit, line 52 */ } lab0: return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 55 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 56 */ return 1; } -static int r_Step_1a(struct SN_env * z) { +static int r_Step_1a(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 59 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 59 */ z->ket = z->c; /* [, line 60 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m_keep; goto lab0; } - among_var = find_among_b(z, a_1, 3); /* substring, line 60 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } /* substring, line 60 */ + if (!(find_among_b(z, a_1, 3))) { z->c = z->l - m1; goto lab0; } z->bra = z->c; /* ], line 60 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } - case 1: - { int ret = slice_del(z); /* delete, line 62 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 62 */ + if (ret < 0) return ret; } lab0: ; } z->ket = z->c; /* [, line 65 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; - among_var = find_among_b(z, a_2, 6); /* substring, line 65 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; /* substring, line 65 */ + among_var = find_among_b(z, a_2, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 65 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 65 */ case 1: - { int ret = slice_from_s(z, 2, s_5); /* <-, line 66 */ + { int ret = slice_from_s(z, 2, s_2); /* <-, line 66 */ if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 68 */ - { int ret = z->c - 2; + { int m2 = z->l - z->c; (void)m2; /* or, line 68 */ + { int ret = z->c - 2; /* hop, line 68 */ if (z->lb > ret || ret > z->l) goto lab2; - z->c = ret; /* hop, line 68 */ + z->c = ret; } - { int ret = slice_from_s(z, 1, s_6); /* <-, line 68 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 68 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m1; - { int ret = slice_from_s(z, 2, s_7); /* <-, line 68 */ + z->c = z->l - m2; + { int ret = slice_from_s(z, 2, s_4); /* <-, line 68 */ if (ret < 0) return ret; } } @@ -552,48 +537,47 @@ static int r_Step_1a(struct SN_env * z) { return 1; } -static int r_Step_1b(struct SN_env * z) { +static int r_Step_1b(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 75 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_4, 6); /* substring, line 75 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 75 */ + among_var = find_among_b(z, a_4, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 75 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 75 */ case 1: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 77 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 77 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_8); /* <-, line 77 */ + { int ret = slice_from_s(z, 2, s_5); /* <-, line 77 */ if (ret < 0) return ret; } break; case 2: - { int m_test = z->l - z->c; /* test, line 80 */ + { int m_test1 = z->l - z->c; /* test, line 80 */ { /* gopast */ /* grouping v, line 80 */ int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 80 */ if (ret < 0) return ret; } - { int m_test = z->l - z->c; /* test, line 81 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else - among_var = find_among_b(z, a_3, 13); /* substring, line 81 */ + { int m_test2 = z->l - z->c; /* test, line 81 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 81 */ + among_var = find_among_b(z, a_3, 13); if (!(among_var)) return 0; - z->c = z->l - m_test; + z->c = z->l - m_test2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 81 */ case 1: - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 83 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_6); /* <+, line 83 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -608,16 +592,17 @@ static int r_Step_1b(struct SN_env * z) { break; case 3: if (z->c != z->I[0]) return 0; /* atmark, line 87 */ - { int m_test = z->l - z->c; /* test, line 87 */ - { int ret = r_shortv(z); - if (ret == 0) return 0; /* call shortv, line 87 */ - if (ret < 0) return ret; + { int m_test3 = z->l - z->c; /* test, line 87 */ + { int ret = r_shortv(z); /* call shortv, line 87 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test3; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 87 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_7); /* <+, line 87 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -627,121 +612,115 @@ static int r_Step_1b(struct SN_env * z) { return 1; } -static int r_Step_1c(struct SN_env * z) { +static int r_Step_1c(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 94 */ { int m1 = z->l - z->c; (void)m1; /* or, line 94 */ - if (!(eq_s_b(z, 1, s_11))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 94 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_12))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 94 */ + z->c--; } lab0: z->bra = z->c; /* ], line 94 */ - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; - { int m2 = z->l - z->c; (void)m2; /* not, line 95 */ - if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ - return 0; - lab2: - z->c = z->l - m2; - } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 96 */ + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 95 */ + /* not, line 95 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ + return 0; +lab2: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 96 */ if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { +static int r_Step_2(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 100 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 24); /* substring, line 100 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 100 */ + among_var = find_among_b(z, a_5, 24); if (!(among_var)) return 0; z->bra = z->c; /* ], line 100 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 100 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 100 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 100 */ case 1: - { int ret = slice_from_s(z, 4, s_14); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_9); /* <-, line 101 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_15); /* <-, line 102 */ + { int ret = slice_from_s(z, 4, s_10); /* <-, line 102 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_16); /* <-, line 103 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 103 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_17); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 105 */ + { int ret = slice_from_s(z, 3, s_13); /* <-, line 105 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_14); /* <-, line 107 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 109 */ + { int ret = slice_from_s(z, 3, s_15); /* <-, line 109 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 2, s_21); /* <-, line 111 */ + { int ret = slice_from_s(z, 2, s_16); /* <-, line 111 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 3, s_22); /* <-, line 112 */ + { int ret = slice_from_s(z, 3, s_17); /* <-, line 112 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_23); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 114 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_24); /* <-, line 116 */ + { int ret = slice_from_s(z, 3, s_19); /* <-, line 116 */ if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_25); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ if (ret < 0) return ret; } break; case 13: - if (!(eq_s_b(z, 1, s_26))) return 0; - { int ret = slice_from_s(z, 2, s_27); /* <-, line 119 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 119 */ + z->c--; + { int ret = slice_from_s(z, 2, s_21); /* <-, line 119 */ if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 3, s_28); /* <-, line 120 */ + { int ret = slice_from_s(z, 4, s_22); /* <-, line 121 */ if (ret < 0) return ret; } break; case 15: - { int ret = slice_from_s(z, 4, s_29); /* <-, line 121 */ - if (ret < 0) return ret; - } - break; - case 16: - if (in_grouping_b(z, g_valid_LI, 99, 116, 0)) return 0; + if (in_grouping_b(z, g_valid_LI, 99, 116, 0)) return 0; /* grouping valid_LI, line 122 */ { int ret = slice_del(z); /* delete, line 122 */ if (ret < 0) return ret; } @@ -750,36 +729,34 @@ static int r_Step_2(struct SN_env * z) { return 1; } -static int r_Step_3(struct SN_env * z) { +static int r_Step_3(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 127 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_6, 9); /* substring, line 127 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 127 */ + among_var = find_among_b(z, a_6, 9); if (!(among_var)) return 0; z->bra = z->c; /* ], line 127 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 127 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 127 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 127 */ case 1: - { int ret = slice_from_s(z, 4, s_30); /* <-, line 128 */ + { int ret = slice_from_s(z, 4, s_23); /* <-, line 128 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_31); /* <-, line 129 */ + { int ret = slice_from_s(z, 3, s_24); /* <-, line 129 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_32); /* <-, line 130 */ + { int ret = slice_from_s(z, 2, s_25); /* <-, line 130 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_33); /* <-, line 132 */ + { int ret = slice_from_s(z, 2, s_26); /* <-, line 132 */ if (ret < 0) return ret; } break; @@ -789,9 +766,8 @@ static int r_Step_3(struct SN_env * z) { } break; case 6: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 136 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; @@ -801,19 +777,17 @@ static int r_Step_3(struct SN_env * z) { return 1; } -static int r_Step_4(struct SN_env * z) { +static int r_Step_4(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 141 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_7, 18); /* substring, line 141 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 141 */ + among_var = find_among_b(z, a_7, 18); if (!(among_var)) return 0; z->bra = z->c; /* ], line 141 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 141 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 141 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 141 */ case 1: { int ret = slice_del(z); /* delete, line 144 */ if (ret < 0) return ret; @@ -821,11 +795,13 @@ static int r_Step_4(struct SN_env * z) { break; case 2: { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (!(eq_s_b(z, 1, s_34))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 145 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_35))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 145 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 145 */ @@ -836,31 +812,29 @@ static int r_Step_4(struct SN_env * z) { return 1; } -static int r_Step_5(struct SN_env * z) { +static int r_Step_5(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 150 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; - among_var = find_among_b(z, a_8, 2); /* substring, line 150 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; /* substring, line 150 */ + among_var = find_among_b(z, a_8, 2); if (!(among_var)) return 0; z->bra = z->c; /* ], line 150 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 150 */ case 1: { int m1 = z->l - z->c; (void)m1; /* or, line 151 */ - { int ret = r_R2(z); - if (ret == 0) goto lab1; /* call R2, line 151 */ + { int ret = r_R2(z); /* call R2, line 151 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 151 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 151 */ + if (ret <= 0) return ret; } { int m2 = z->l - z->c; (void)m2; /* not, line 151 */ - { int ret = r_shortv(z); - if (ret == 0) goto lab2; /* call shortv, line 151 */ + { int ret = r_shortv(z); /* call shortv, line 151 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } return 0; @@ -874,11 +848,11 @@ static int r_Step_5(struct SN_env * z) { } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 152 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 152 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_36))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 152 */ + z->c--; { int ret = slice_del(z); /* delete, line 152 */ if (ret < 0) return ret; } @@ -887,77 +861,76 @@ static int r_Step_5(struct SN_env * z) { return 1; } -static int r_exception2(struct SN_env * z) { +static int r_exception2(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 158 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; - if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 158 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 158 */ + if (!(find_among_b(z, a_9, 8))) return 0; z->bra = z->c; /* ], line 158 */ if (z->c > z->lb) return 0; /* atlimit, line 158 */ return 1; } -static int r_exception1(struct SN_env * z) { +static int r_exception1(struct SN_env * z) { /* forwardmode */ int among_var; z->bra = z->c; /* [, line 170 */ - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; - among_var = find_among(z, a_10, 18); /* substring, line 170 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* substring, line 170 */ + among_var = find_among(z, a_10, 18); if (!(among_var)) return 0; z->ket = z->c; /* ], line 170 */ if (z->c < z->l) return 0; /* atlimit, line 170 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 170 */ case 1: - { int ret = slice_from_s(z, 3, s_37); /* <-, line 174 */ + { int ret = slice_from_s(z, 3, s_27); /* <-, line 174 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_38); /* <-, line 175 */ + { int ret = slice_from_s(z, 3, s_28); /* <-, line 175 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_39); /* <-, line 176 */ + { int ret = slice_from_s(z, 3, s_29); /* <-, line 176 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 3, s_40); /* <-, line 177 */ + { int ret = slice_from_s(z, 3, s_30); /* <-, line 177 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_41); /* <-, line 178 */ + { int ret = slice_from_s(z, 3, s_31); /* <-, line 178 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_42); /* <-, line 182 */ + { int ret = slice_from_s(z, 3, s_32); /* <-, line 182 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_43); /* <-, line 183 */ + { int ret = slice_from_s(z, 5, s_33); /* <-, line 183 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 4, s_44); /* <-, line 184 */ + { int ret = slice_from_s(z, 4, s_34); /* <-, line 184 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_45); /* <-, line 185 */ + { int ret = slice_from_s(z, 5, s_35); /* <-, line 185 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 4, s_46); /* <-, line 186 */ + { int ret = slice_from_s(z, 4, s_36); /* <-, line 186 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 5, s_47); /* <-, line 187 */ + { int ret = slice_from_s(z, 5, s_37); /* <-, line 187 */ if (ret < 0) return ret; } break; @@ -965,14 +938,15 @@ static int r_exception1(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */ while(1) { /* repeat, line 203 */ int c1 = z->c; while(1) { /* goto, line 203 */ int c2 = z->c; z->bra = z->c; /* [, line 203 */ - if (!(eq_s(z, 1, s_48))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; /* literal, line 203 */ + z->c++; z->ket = z->c; /* ], line 203 */ z->c = c2; break; @@ -981,7 +955,7 @@ static int r_postlude(struct SN_env * z) { if (z->c >= z->l) goto lab0; z->c++; /* goto, line 203 */ } - { int ret = slice_from_s(z, 1, s_49); /* <-, line 203 */ + { int ret = slice_from_s(z, 1, s_38); /* <-, line 203 */ if (ret < 0) return ret; } continue; @@ -992,19 +966,19 @@ static int r_postlude(struct SN_env * z) { return 1; } -extern int english_ISO_8859_1_stem(struct SN_env * z) { +extern int english_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* or, line 207 */ - { int ret = r_exception1(z); - if (ret == 0) goto lab1; /* call exception1, line 207 */ + { int ret = r_exception1(z); /* call exception1, line 207 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = c1; { int c2 = z->c; /* not, line 208 */ - { int ret = z->c + 3; + { int ret = z->c + 3; /* hop, line 208 */ if (0 > ret || ret > z->l) goto lab3; - z->c = ret; /* hop, line 208 */ + z->c = ret; } goto lab2; lab3: @@ -1013,98 +987,94 @@ extern int english_ISO_8859_1_stem(struct SN_env * z) { goto lab0; lab2: z->c = c1; - { int c3 = z->c; /* do, line 209 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab4; /* call prelude, line 209 */ - if (ret < 0) return ret; - } - lab4: - z->c = c3; + /* do, line 209 */ + { int ret = r_prelude(z); /* call prelude, line 209 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; } - { int c4 = z->c; /* do, line 210 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab5; /* call mark_regions, line 210 */ - if (ret < 0) return ret; - } - lab5: - z->c = c4; + lab4: + /* do, line 210 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 210 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; } + lab5: z->lb = z->c; z->c = z->l; /* backwards, line 211 */ - { int m5 = z->l - z->c; (void)m5; /* do, line 213 */ - { int ret = r_Step_1a(z); - if (ret == 0) goto lab6; /* call Step_1a, line 213 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 213 */ + { int ret = r_Step_1a(z); /* call Step_1a, line 213 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m5; + z->c = z->l - m3; } - { int m6 = z->l - z->c; (void)m6; /* or, line 215 */ - { int ret = r_exception2(z); - if (ret == 0) goto lab8; /* call exception2, line 215 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 215 */ + { int ret = r_exception2(z); /* call exception2, line 215 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: - z->c = z->l - m6; - { int m7 = z->l - z->c; (void)m7; /* do, line 217 */ - { int ret = r_Step_1b(z); - if (ret == 0) goto lab9; /* call Step_1b, line 217 */ + z->c = z->l - m4; + { int m5 = z->l - z->c; (void)m5; /* do, line 217 */ + { int ret = r_Step_1b(z); /* call Step_1b, line 217 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: - z->c = z->l - m7; + z->c = z->l - m5; } - { int m8 = z->l - z->c; (void)m8; /* do, line 218 */ - { int ret = r_Step_1c(z); - if (ret == 0) goto lab10; /* call Step_1c, line 218 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 218 */ + { int ret = r_Step_1c(z); /* call Step_1c, line 218 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } lab10: - z->c = z->l - m8; + z->c = z->l - m6; } - { int m9 = z->l - z->c; (void)m9; /* do, line 220 */ - { int ret = r_Step_2(z); - if (ret == 0) goto lab11; /* call Step_2, line 220 */ + { int m7 = z->l - z->c; (void)m7; /* do, line 220 */ + { int ret = r_Step_2(z); /* call Step_2, line 220 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: - z->c = z->l - m9; + z->c = z->l - m7; } - { int m10 = z->l - z->c; (void)m10; /* do, line 221 */ - { int ret = r_Step_3(z); - if (ret == 0) goto lab12; /* call Step_3, line 221 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 221 */ + { int ret = r_Step_3(z); /* call Step_3, line 221 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: - z->c = z->l - m10; + z->c = z->l - m8; } - { int m11 = z->l - z->c; (void)m11; /* do, line 222 */ - { int ret = r_Step_4(z); - if (ret == 0) goto lab13; /* call Step_4, line 222 */ + { int m9 = z->l - z->c; (void)m9; /* do, line 222 */ + { int ret = r_Step_4(z); /* call Step_4, line 222 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } lab13: - z->c = z->l - m11; + z->c = z->l - m9; } - { int m12 = z->l - z->c; (void)m12; /* do, line 224 */ - { int ret = r_Step_5(z); - if (ret == 0) goto lab14; /* call Step_5, line 224 */ + { int m10 = z->l - z->c; (void)m10; /* do, line 224 */ + { int ret = r_Step_5(z); /* call Step_5, line 224 */ + if (ret == 0) goto lab14; if (ret < 0) return ret; } lab14: - z->c = z->l - m12; + z->c = z->l - m10; } } lab7: z->c = z->lb; - { int c13 = z->c; /* do, line 227 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab15; /* call postlude, line 227 */ + { int c11 = z->c; /* do, line 227 */ + { int ret = r_postlude(z); /* call postlude, line 227 */ + if (ret == 0) goto lab15; if (ret < 0) return ret; } lab15: - z->c = c13; + z->c = c11; } } lab0: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c index 9621771d282..58285e8c343 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_finnish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -183,7 +183,7 @@ static const struct among a_6[30] = /* 4 */ { 2, s_6_4, 0, -1, 0}, /* 5 */ { 3, s_6_5, 4, -1, 0}, /* 6 */ { 3, s_6_6, 4, -1, 0}, -/* 7 */ { 3, s_6_7, 4, 9, 0}, +/* 7 */ { 3, s_6_7, 4, 2, 0}, /* 8 */ { 3, s_6_8, -1, -1, 0}, /* 9 */ { 3, s_6_9, -1, -1, 0}, /* 10 */ { 3, s_6_10, -1, -1, 0}, @@ -205,7 +205,7 @@ static const struct among a_6[30] = /* 26 */ { 2, s_6_26, 22, -1, 0}, /* 27 */ { 3, s_6_27, 26, -1, 0}, /* 28 */ { 3, s_6_28, 26, -1, 0}, -/* 29 */ { 3, s_6_29, 26, 9, 0} +/* 29 */ { 3, s_6_29, 26, 2, 0} }; static const symbol s_7_0[3] = { 'e', 'j', 'a' }; @@ -261,151 +261,132 @@ static const struct among a_9[2] = static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; +static const unsigned char g_C[] = { 119, 223, 119, 1 }; + static const unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; static const unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; static const unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; -static const symbol s_0[] = { 'k' }; -static const symbol s_1[] = { 'k', 's', 'e' }; -static const symbol s_2[] = { 'k', 's', 'i' }; -static const symbol s_3[] = { 'i' }; -static const symbol s_4[] = { 'a' }; -static const symbol s_5[] = { 'e' }; -static const symbol s_6[] = { 'i' }; -static const symbol s_7[] = { 'o' }; -static const symbol s_8[] = { 0xE4 }; -static const symbol s_9[] = { 0xF6 }; -static const symbol s_10[] = { 'i', 'e' }; -static const symbol s_11[] = { 'e' }; -static const symbol s_12[] = { 'p', 'o' }; -static const symbol s_13[] = { 't' }; -static const symbol s_14[] = { 'p', 'o' }; -static const symbol s_15[] = { 'j' }; -static const symbol s_16[] = { 'o' }; -static const symbol s_17[] = { 'u' }; -static const symbol s_18[] = { 'o' }; -static const symbol s_19[] = { 'j' }; - -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 46 */ - { /* gopast */ /* non V1, line 46 */ +static const symbol s_0[] = { 'k', 's', 'e' }; +static const symbol s_1[] = { 'k', 's', 'i' }; +static const symbol s_2[] = { 'i', 'e' }; +static const symbol s_3[] = { 'p', 'o' }; +static const symbol s_4[] = { 'p', 'o' }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 44 */ + z->I[1] = z->l; /* $p2 = , line 45 */ + if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ + { /* gopast */ /* non V1, line 47 */ int ret = in_grouping(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 46 */ - if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ - { /* gopast */ /* non V1, line 47 */ + z->I[0] = z->c; /* setmark p1, line 47 */ + if (out_grouping(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 48 */ + { /* gopast */ /* non V1, line 48 */ int ret = in_grouping(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 47 */ + z->I[1] = z->c; /* setmark p2, line 48 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 53 */ return 1; } -static int r_particle_etc(struct SN_env * z) { +static int r_particle_etc(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 55 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 56 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 55 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 55 */ - among_var = find_among_b(z, a_0, 10); /* substring, line 55 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 55 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 56 */ + among_var = find_among_b(z, a_0, 10); /* substring, line 56 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 56 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 57 */ case 1: - if (in_grouping_b(z, g_particle_end, 97, 246, 0)) return 0; + if (in_grouping_b(z, g_particle_end, 97, 246, 0)) return 0; /* grouping particle_end, line 63 */ break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 64 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 65 */ + if (ret <= 0) return ret; } break; } - { int ret = slice_del(z); /* delete, line 66 */ + { int ret = slice_del(z); /* delete, line 67 */ if (ret < 0) return ret; } return 1; } -static int r_possessive(struct SN_env * z) { +static int r_possessive(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 69 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 70 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 69 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 69 */ - among_var = find_among_b(z, a_4, 9); /* substring, line 69 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 69 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 70 */ + among_var = find_among_b(z, a_4, 9); /* substring, line 70 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 70 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 71 */ case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 72 */ - if (!(eq_s_b(z, 1, s_0))) goto lab0; + { int m2 = z->l - z->c; (void)m2; /* not, line 73 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; /* literal, line 73 */ + z->c--; return 0; lab0: z->c = z->l - m2; } - { int ret = slice_del(z); /* delete, line 72 */ + { int ret = slice_del(z); /* delete, line 73 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 74 */ + { int ret = slice_del(z); /* delete, line 75 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 74 */ - if (!(eq_s_b(z, 3, s_1))) return 0; - z->bra = z->c; /* ], line 74 */ - { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ + z->ket = z->c; /* [, line 75 */ + if (!(eq_s_b(z, 3, s_0))) return 0; /* literal, line 75 */ + z->bra = z->c; /* ], line 75 */ + { int ret = slice_from_s(z, 3, s_1); /* <-, line 75 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 78 */ + { int ret = slice_del(z); /* delete, line 79 */ if (ret < 0) return ret; } break; case 4: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; - if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */ - { int ret = slice_del(z); /* delete, line 81 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; /* among, line 82 */ + if (!(find_among_b(z, a_1, 6))) return 0; + { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } break; case 5: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 228) return 0; - if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */ - { int ret = slice_del(z); /* delete, line 84 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 228) return 0; /* among, line 84 */ + if (!(find_among_b(z, a_2, 6))) return 0; + { int ret = slice_del(z); /* delete, line 85 */ if (ret < 0) return ret; } break; case 6: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; - if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; /* among, line 87 */ + if (!(find_among_b(z, a_3, 2))) return 0; + { int ret = slice_del(z); /* delete, line 87 */ if (ret < 0) return ret; } break; @@ -413,344 +394,336 @@ static int r_possessive(struct SN_env * z) { return 1; } -static int r_LONG(struct SN_env * z) { - if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */ +static int r_LONG(struct SN_env * z) { /* backwardmode */ + if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 92 */ return 1; } -static int r_VI(struct SN_env * z) { - if (!(eq_s_b(z, 1, s_3))) return 0; - if (in_grouping_b(z, g_V2, 97, 246, 0)) return 0; +static int r_VI(struct SN_env * z) { /* backwardmode */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 94 */ + z->c--; + if (in_grouping_b(z, g_V2, 97, 246, 0)) return 0; /* grouping V2, line 94 */ return 1; } -static int r_case_ending(struct SN_env * z) { +static int r_case_ending(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 96 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 97 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 96 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 96 */ - among_var = find_among_b(z, a_6, 30); /* substring, line 96 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 96 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 97 */ + among_var = find_among_b(z, a_6, 30); /* substring, line 97 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 97 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 98 */ case 1: - if (!(eq_s_b(z, 1, s_4))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; /* literal, line 99 */ + z->c--; break; case 2: - if (!(eq_s_b(z, 1, s_5))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 100 */ + z->c--; break; case 3: - if (!(eq_s_b(z, 1, s_6))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 101 */ + z->c--; break; case 4: - if (!(eq_s_b(z, 1, s_7))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; /* literal, line 102 */ + z->c--; break; case 5: - if (!(eq_s_b(z, 1, s_8))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xE4) return 0; /* literal, line 103 */ + z->c--; break; case 6: - if (!(eq_s_b(z, 1, s_9))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xF6) return 0; /* literal, line 104 */ + z->c--; break; case 7: - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ - { int m2 = z->l - z->c; (void)m2; /* and, line 113 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 112 */ - { int ret = r_LONG(z); - if (ret == 0) goto lab2; /* call LONG, line 111 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 112 */ + { int m3 = z->l - z->c; (void)m3; /* and, line 114 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 113 */ + { int ret = r_LONG(z); /* call LONG, line 112 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m3; - if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m_keep; goto lab0; } + z->c = z->l - m4; + if (!(eq_s_b(z, 2, s_2))) { z->c = z->l - m2; goto lab0; } /* literal, line 113 */ } lab1: - z->c = z->l - m2; - if (z->c <= z->lb) { z->c = z->l - m_keep; goto lab0; } - z->c--; /* next, line 113 */ + z->c = z->l - m3; + if (z->c <= z->lb) { z->c = z->l - m2; goto lab0; } + z->c--; /* next, line 114 */ } - z->bra = z->c; /* ], line 113 */ + z->bra = z->c; /* ], line 114 */ lab0: ; } break; case 8: - if (in_grouping_b(z, g_V1, 97, 246, 0)) return 0; - if (out_grouping_b(z, g_V1, 97, 246, 0)) return 0; - break; - case 9: - if (!(eq_s_b(z, 1, s_11))) return 0; + if (in_grouping_b(z, g_V1, 97, 246, 0)) return 0; /* grouping V1, line 120 */ + if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 120 */ break; } - { int ret = slice_del(z); /* delete, line 138 */ + { int ret = slice_del(z); /* delete, line 139 */ if (ret < 0) return ret; } - z->B[0] = 1; /* set ending_removed, line 139 */ + z->B[0] = 1; /* set ending_removed, line 140 */ return 1; } -static int r_other_endings(struct SN_env * z) { +static int r_other_endings(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 142 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 143 */ if (z->c < z->I[1]) return 0; - z->c = z->I[1]; /* tomark, line 142 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 142 */ - among_var = find_among_b(z, a_7, 14); /* substring, line 142 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 142 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; /* [, line 143 */ + among_var = find_among_b(z, a_7, 14); /* substring, line 143 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 143 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 144 */ case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 146 */ - if (!(eq_s_b(z, 2, s_12))) goto lab0; + { int m2 = z->l - z->c; (void)m2; /* not, line 147 */ + if (!(eq_s_b(z, 2, s_3))) goto lab0; /* literal, line 147 */ return 0; lab0: z->c = z->l - m2; } break; } - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); /* delete, line 152 */ if (ret < 0) return ret; } return 1; } -static int r_i_plural(struct SN_env * z) { - { int mlimit; /* setlimit, line 154 */ - int m1 = z->l - z->c; (void)m1; +static int r_i_plural(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 155 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 154 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 154 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit; return 0; } /* substring, line 154 */ - z->bra = z->c; /* ], line 154 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 155 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } /* substring, line 155 */ + if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 155 */ + z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 158 */ + { int ret = slice_del(z); /* delete, line 159 */ if (ret < 0) return ret; } return 1; } -static int r_t_plural(struct SN_env * z) { +static int r_t_plural(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 161 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 162 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 161 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 162 */ - if (!(eq_s_b(z, 1, s_13))) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 162 */ - { int m_test = z->l - z->c; /* test, line 162 */ - if (in_grouping_b(z, g_V1, 97, 246, 0)) { z->lb = mlimit; return 0; } - z->c = z->l - m_test; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 163 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } /* literal, line 163 */ + z->c--; + z->bra = z->c; /* ], line 163 */ + { int m_test2 = z->l - z->c; /* test, line 163 */ + if (in_grouping_b(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } /* grouping V1, line 163 */ + z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_del(z); /* delete, line 164 */ if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } - { int mlimit; /* setlimit, line 165 */ - int m2 = z->l - z->c; (void)m2; + + { int mlimit3; /* setlimit, line 166 */ if (z->c < z->I[1]) return 0; - z->c = z->I[1]; /* tomark, line 165 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - z->ket = z->c; /* [, line 165 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_9, 2); /* substring, line 165 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 165 */ - z->lb = mlimit; + mlimit3 = z->lb; z->lb = z->I[1]; + z->ket = z->c; /* [, line 166 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } /* substring, line 166 */ + among_var = find_among_b(z, a_9, 2); + if (!(among_var)) { z->lb = mlimit3; return 0; } + z->bra = z->c; /* ], line 166 */ + z->lb = mlimit3; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 167 */ case 1: - { int m3 = z->l - z->c; (void)m3; /* not, line 167 */ - if (!(eq_s_b(z, 2, s_14))) goto lab0; + { int m4 = z->l - z->c; (void)m4; /* not, line 168 */ + if (!(eq_s_b(z, 2, s_4))) goto lab0; /* literal, line 168 */ return 0; lab0: - z->c = z->l - m3; + z->c = z->l - m4; } break; } - { int ret = slice_del(z); /* delete, line 170 */ + { int ret = slice_del(z); /* delete, line 171 */ if (ret < 0) return ret; } return 1; } -static int r_tidy(struct SN_env * z) { - { int mlimit; /* setlimit, line 173 */ - int m1 = z->l - z->c; (void)m1; +static int r_tidy(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 174 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 173 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* do, line 174 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 174 */ - { int ret = r_LONG(z); - if (ret == 0) goto lab0; /* call LONG, line 174 */ + mlimit1 = z->lb; z->lb = z->I[0]; + { int m2 = z->l - z->c; (void)m2; /* do, line 175 */ + { int m3 = z->l - z->c; (void)m3; /* and, line 175 */ + { int ret = r_LONG(z); /* call LONG, line 175 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } z->c = z->l - m3; - z->ket = z->c; /* [, line 174 */ + z->ket = z->c; /* [, line 175 */ if (z->c <= z->lb) goto lab0; - z->c--; /* next, line 174 */ - z->bra = z->c; /* ], line 174 */ - { int ret = slice_del(z); /* delete, line 174 */ + z->c--; /* next, line 175 */ + z->bra = z->c; /* ], line 175 */ + { int ret = slice_del(z); /* delete, line 175 */ if (ret < 0) return ret; } } lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 175 */ - z->ket = z->c; /* [, line 175 */ - if (in_grouping_b(z, g_AEI, 97, 228, 0)) goto lab1; - z->bra = z->c; /* ], line 175 */ - if (out_grouping_b(z, g_V1, 97, 246, 0)) goto lab1; - { int ret = slice_del(z); /* delete, line 175 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 176 */ + z->ket = z->c; /* [, line 176 */ + if (in_grouping_b(z, g_AEI, 97, 228, 0)) goto lab1; /* grouping AEI, line 176 */ + z->bra = z->c; /* ], line 176 */ + if (in_grouping_b(z, g_C, 98, 122, 0)) goto lab1; /* grouping C, line 176 */ + { int ret = slice_del(z); /* delete, line 176 */ if (ret < 0) return ret; } lab1: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 176 */ - z->ket = z->c; /* [, line 176 */ - if (!(eq_s_b(z, 1, s_15))) goto lab2; - z->bra = z->c; /* ], line 176 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 176 */ - if (!(eq_s_b(z, 1, s_16))) goto lab4; + { int m5 = z->l - z->c; (void)m5; /* do, line 177 */ + z->ket = z->c; /* [, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; /* literal, line 177 */ + z->c--; + z->bra = z->c; /* ], line 177 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; /* literal, line 177 */ + z->c--; goto lab3; lab4: z->c = z->l - m6; - if (!(eq_s_b(z, 1, s_17))) goto lab2; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; /* literal, line 177 */ + z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 176 */ + { int ret = slice_del(z); /* delete, line 177 */ if (ret < 0) return ret; } lab2: z->c = z->l - m5; } - { int m7 = z->l - z->c; (void)m7; /* do, line 177 */ - z->ket = z->c; /* [, line 177 */ - if (!(eq_s_b(z, 1, s_18))) goto lab5; - z->bra = z->c; /* ], line 177 */ - if (!(eq_s_b(z, 1, s_19))) goto lab5; - { int ret = slice_del(z); /* delete, line 177 */ + { int m7 = z->l - z->c; (void)m7; /* do, line 178 */ + z->ket = z->c; /* [, line 178 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 178 */ + z->c--; + z->bra = z->c; /* ], line 178 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; /* literal, line 178 */ + z->c--; + { int ret = slice_del(z); /* delete, line 178 */ if (ret < 0) return ret; } lab5: z->c = z->l - m7; } - z->lb = mlimit; + z->lb = mlimit1; } - if (in_grouping_b(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 179 */ - z->ket = z->c; /* [, line 179 */ - if (z->c <= z->lb) return 0; - z->c--; /* next, line 179 */ - z->bra = z->c; /* ], line 179 */ - z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */ - if (z->S[0] == 0) return -1; /* -> x, line 179 */ - if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */ - { int ret = slice_del(z); /* delete, line 179 */ + if (in_grouping_b(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 180 */ + z->ket = z->c; /* [, line 180 */ + if (in_grouping_b(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 180 */ + z->bra = z->c; /* ], line 180 */ + z->S[0] = slice_to(z, z->S[0]); /* -> x, line 180 */ + if (z->S[0] == 0) return -1; /* -> x, line 180 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 180 */ + { int ret = slice_del(z); /* delete, line 180 */ if (ret < 0) return ret; } return 1; } -extern int finnish_ISO_8859_1_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 185 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 185 */ +extern int finnish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 186 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - z->B[0] = 0; /* unset ending_removed, line 186 */ - z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + z->B[0] = 0; /* unset ending_removed, line 187 */ + z->lb = z->c; z->c = z->l; /* backwards, line 188 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 188 */ - { int ret = r_particle_etc(z); - if (ret == 0) goto lab1; /* call particle_etc, line 188 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ + { int ret = r_particle_etc(z); /* call particle_etc, line 189 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 189 */ - { int ret = r_possessive(z); - if (ret == 0) goto lab2; /* call possessive, line 189 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 190 */ + { int ret = r_possessive(z); /* call possessive, line 190 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 190 */ - { int ret = r_case_ending(z); - if (ret == 0) goto lab3; /* call case_ending, line 190 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 191 */ + { int ret = r_case_ending(z); /* call case_ending, line 191 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 191 */ - { int ret = r_other_endings(z); - if (ret == 0) goto lab4; /* call other_endings, line 191 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 192 */ + { int ret = r_other_endings(z); /* call other_endings, line 192 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* or, line 192 */ - if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */ - { int m7 = z->l - z->c; (void)m7; /* do, line 192 */ - { int ret = r_i_plural(z); - if (ret == 0) goto lab7; /* call i_plural, line 192 */ - if (ret < 0) return ret; - } - lab7: - z->c = z->l - m7; + /* or, line 193 */ + if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 193 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 193 */ + { int ret = r_i_plural(z); /* call i_plural, line 193 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; } - goto lab5; - lab6: + lab7: z->c = z->l - m6; - { int m8 = z->l - z->c; (void)m8; /* do, line 192 */ - { int ret = r_t_plural(z); - if (ret == 0) goto lab8; /* call t_plural, line 192 */ - if (ret < 0) return ret; - } - lab8: - z->c = z->l - m8; + } + goto lab5; +lab6: + { int m7 = z->l - z->c; (void)m7; /* do, line 193 */ + { int ret = r_t_plural(z); /* call t_plural, line 193 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; } + lab8: + z->c = z->l - m7; } lab5: - { int m9 = z->l - z->c; (void)m9; /* do, line 193 */ - { int ret = r_tidy(z); - if (ret == 0) goto lab9; /* call tidy, line 193 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 194 */ + { int ret = r_tidy(z); /* call tidy, line 194 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: - z->c = z->l - m9; + z->c = z->l - m8; } z->c = z->lb; return 1; diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c index fc79c0a24dc..4e9f76cd9a4 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_french.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -45,16 +45,22 @@ static const struct among a_0[3] = /* 2 */ { 3, s_0_2, -1, -1, 0} }; -static const symbol s_1_1[1] = { 'I' }; -static const symbol s_1_2[1] = { 'U' }; -static const symbol s_1_3[1] = { 'Y' }; +static const symbol s_1_1[1] = { 'H' }; +static const symbol s_1_2[2] = { 'H', 'e' }; +static const symbol s_1_3[2] = { 'H', 'i' }; +static const symbol s_1_4[1] = { 'I' }; +static const symbol s_1_5[1] = { 'U' }; +static const symbol s_1_6[1] = { 'Y' }; -static const struct among a_1[4] = +static const struct among a_1[7] = { -/* 0 */ { 0, 0, -1, 4, 0}, -/* 1 */ { 1, s_1_1, 0, 1, 0}, -/* 2 */ { 1, s_1_2, 0, 2, 0}, -/* 3 */ { 1, s_1_3, 0, 3, 0} +/* 0 */ { 0, 0, -1, 7, 0}, +/* 1 */ { 1, s_1_1, 0, 6, 0}, +/* 2 */ { 2, s_1_2, 1, 4, 0}, +/* 3 */ { 2, s_1_3, 1, 5, 0}, +/* 4 */ { 1, s_1_4, 0, 1, 0}, +/* 5 */ { 1, s_1_5, 0, 2, 0}, +/* 6 */ { 1, s_1_6, 0, 3, 0} }; static const symbol s_2_0[3] = { 'i', 'q', 'U' }; @@ -338,17 +344,15 @@ static const symbol s_7_2[4] = { 'i', 0xE8, 'r', 'e' }; static const symbol s_7_3[3] = { 'i', 'o', 'n' }; static const symbol s_7_4[3] = { 'I', 'e', 'r' }; static const symbol s_7_5[3] = { 'i', 'e', 'r' }; -static const symbol s_7_6[1] = { 0xEB }; -static const struct among a_7[7] = +static const struct among a_7[6] = { /* 0 */ { 1, s_7_0, -1, 3, 0}, /* 1 */ { 4, s_7_1, 0, 2, 0}, /* 2 */ { 4, s_7_2, 0, 2, 0}, /* 3 */ { 3, s_7_3, -1, 1, 0}, /* 4 */ { 3, s_7_4, -1, 2, 0}, -/* 5 */ { 3, s_7_5, -1, 2, 0}, -/* 6 */ { 1, s_7_6, -1, 4, 0} +/* 5 */ { 3, s_7_5, -1, 2, 0} }; static const symbol s_8_0[3] = { 'e', 'l', 'l' }; @@ -370,82 +374,75 @@ static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static const unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; -static const symbol s_0[] = { 'u' }; -static const symbol s_1[] = { 'U' }; -static const symbol s_2[] = { 'i' }; -static const symbol s_3[] = { 'I' }; -static const symbol s_4[] = { 'y' }; +static const symbol s_0[] = { 'U' }; +static const symbol s_1[] = { 'I' }; +static const symbol s_2[] = { 'Y' }; +static const symbol s_3[] = { 'H', 'e' }; +static const symbol s_4[] = { 'H', 'i' }; static const symbol s_5[] = { 'Y' }; -static const symbol s_6[] = { 'y' }; -static const symbol s_7[] = { 'Y' }; -static const symbol s_8[] = { 'q' }; -static const symbol s_9[] = { 'u' }; -static const symbol s_10[] = { 'U' }; -static const symbol s_11[] = { 'i' }; -static const symbol s_12[] = { 'u' }; -static const symbol s_13[] = { 'y' }; -static const symbol s_14[] = { 'i', 'c' }; -static const symbol s_15[] = { 'i', 'q', 'U' }; -static const symbol s_16[] = { 'l', 'o', 'g' }; -static const symbol s_17[] = { 'u' }; -static const symbol s_18[] = { 'e', 'n', 't' }; -static const symbol s_19[] = { 'a', 't' }; -static const symbol s_20[] = { 'e', 'u', 'x' }; -static const symbol s_21[] = { 'i' }; -static const symbol s_22[] = { 'a', 'b', 'l' }; -static const symbol s_23[] = { 'i', 'q', 'U' }; -static const symbol s_24[] = { 'a', 't' }; -static const symbol s_25[] = { 'i', 'c' }; -static const symbol s_26[] = { 'i', 'q', 'U' }; -static const symbol s_27[] = { 'e', 'a', 'u' }; -static const symbol s_28[] = { 'a', 'l' }; -static const symbol s_29[] = { 'e', 'u', 'x' }; -static const symbol s_30[] = { 'a', 'n', 't' }; -static const symbol s_31[] = { 'e', 'n', 't' }; +static const symbol s_6[] = { 'U' }; +static const symbol s_7[] = { 'i' }; +static const symbol s_8[] = { 'u' }; +static const symbol s_9[] = { 'y' }; +static const symbol s_10[] = { 0xEB }; +static const symbol s_11[] = { 0xEF }; +static const symbol s_12[] = { 'i', 'c' }; +static const symbol s_13[] = { 'i', 'q', 'U' }; +static const symbol s_14[] = { 'l', 'o', 'g' }; +static const symbol s_15[] = { 'u' }; +static const symbol s_16[] = { 'e', 'n', 't' }; +static const symbol s_17[] = { 'a', 't' }; +static const symbol s_18[] = { 'e', 'u', 'x' }; +static const symbol s_19[] = { 'i' }; +static const symbol s_20[] = { 'a', 'b', 'l' }; +static const symbol s_21[] = { 'i', 'q', 'U' }; +static const symbol s_22[] = { 'a', 't' }; +static const symbol s_23[] = { 'i', 'c' }; +static const symbol s_24[] = { 'i', 'q', 'U' }; +static const symbol s_25[] = { 'e', 'a', 'u' }; +static const symbol s_26[] = { 'a', 'l' }; +static const symbol s_27[] = { 'e', 'u', 'x' }; +static const symbol s_28[] = { 'a', 'n', 't' }; +static const symbol s_29[] = { 'e', 'n', 't' }; +static const symbol s_30[] = { 'H', 'i' }; +static const symbol s_31[] = { 'i' }; static const symbol s_32[] = { 'e' }; -static const symbol s_33[] = { 's' }; -static const symbol s_34[] = { 's' }; -static const symbol s_35[] = { 't' }; -static const symbol s_36[] = { 'i' }; -static const symbol s_37[] = { 'g', 'u' }; -static const symbol s_38[] = { 0xE9 }; -static const symbol s_39[] = { 0xE8 }; -static const symbol s_40[] = { 'e' }; -static const symbol s_41[] = { 'Y' }; -static const symbol s_42[] = { 'i' }; -static const symbol s_43[] = { 0xE7 }; -static const symbol s_44[] = { 'c' }; +static const symbol s_33[] = { 'i' }; +static const symbol s_34[] = { 'c' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ while(1) { /* repeat, line 38 */ int c1 = z->c; while(1) { /* goto, line 38 */ int c2 = z->c; { int c3 = z->c; /* or, line 44 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab3; + if (in_grouping(z, g_v, 97, 251, 0)) goto lab3; /* grouping v, line 40 */ z->bra = z->c; /* [, line 40 */ { int c4 = z->c; /* or, line 40 */ - if (!(eq_s(z, 1, s_0))) goto lab5; + if (z->c == z->l || z->p[z->c] != 'u') goto lab5; /* literal, line 40 */ + z->c++; z->ket = z->c; /* ], line 40 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab5; - { int ret = slice_from_s(z, 1, s_1); /* <-, line 40 */ + if (in_grouping(z, g_v, 97, 251, 0)) goto lab5; /* grouping v, line 40 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 40 */ if (ret < 0) return ret; } goto lab4; lab5: z->c = c4; - if (!(eq_s(z, 1, s_2))) goto lab6; + if (z->c == z->l || z->p[z->c] != 'i') goto lab6; /* literal, line 41 */ + z->c++; z->ket = z->c; /* ], line 41 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab6; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 41 */ + if (in_grouping(z, g_v, 97, 251, 0)) goto lab6; /* grouping v, line 41 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 41 */ if (ret < 0) return ret; } goto lab4; lab6: z->c = c4; - if (!(eq_s(z, 1, s_4))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 42 */ + z->c++; z->ket = z->c; /* ], line 42 */ - { int ret = slice_from_s(z, 1, s_5); /* <-, line 42 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ if (ret < 0) return ret; } } @@ -454,20 +451,43 @@ static int r_prelude(struct SN_env * z) { lab3: z->c = c3; z->bra = z->c; /* [, line 45 */ - if (!(eq_s(z, 1, s_6))) goto lab7; + if (z->c == z->l || z->p[z->c] != 0xEB) goto lab7; /* literal, line 45 */ + z->c++; z->ket = z->c; /* ], line 45 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab7; - { int ret = slice_from_s(z, 1, s_7); /* <-, line 45 */ + { int ret = slice_from_s(z, 2, s_3); /* <-, line 45 */ if (ret < 0) return ret; } goto lab2; lab7: z->c = c3; - if (!(eq_s(z, 1, s_8))) goto lab1; z->bra = z->c; /* [, line 47 */ - if (!(eq_s(z, 1, s_9))) goto lab1; + if (z->c == z->l || z->p[z->c] != 0xEF) goto lab8; /* literal, line 47 */ + z->c++; z->ket = z->c; /* ], line 47 */ - { int ret = slice_from_s(z, 1, s_10); /* <-, line 47 */ + { int ret = slice_from_s(z, 2, s_4); /* <-, line 47 */ + if (ret < 0) return ret; + } + goto lab2; + lab8: + z->c = c3; + z->bra = z->c; /* [, line 49 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab9; /* literal, line 49 */ + z->c++; + z->ket = z->c; /* ], line 49 */ + if (in_grouping(z, g_v, 97, 251, 0)) goto lab9; /* grouping v, line 49 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 49 */ + if (ret < 0) return ret; + } + goto lab2; + lab9: + z->c = c3; + if (z->c == z->l || z->p[z->c] != 'q') goto lab1; /* literal, line 51 */ + z->c++; + z->bra = z->c; /* [, line 51 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab1; /* literal, line 51 */ + z->c++; + z->ket = z->c; /* ], line 51 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 51 */ if (ret < 0) return ret; } } @@ -487,95 +507,109 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; - { int c1 = z->c; /* do, line 56 */ - { int c2 = z->c; /* or, line 58 */ - if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; - if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 56 */ + z->I[1] = z->l; /* $p1 = , line 57 */ + z->I[2] = z->l; /* $p2 = , line 58 */ + { int c1 = z->c; /* do, line 60 */ + { int c2 = z->c; /* or, line 62 */ + if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ + if (in_grouping(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ if (z->c >= z->l) goto lab2; - z->c++; /* next, line 57 */ + z->c++; /* next, line 61 */ goto lab1; lab2: z->c = c2; - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; - if (!(find_among(z, a_0, 3))) goto lab3; /* among, line 59 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; /* among, line 63 */ + if (!(find_among(z, a_0, 3))) goto lab3; goto lab1; lab3: z->c = c2; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 66 */ - { /* gopast */ /* grouping v, line 66 */ + z->c++; /* next, line 70 */ + { /* gopast */ /* grouping v, line 70 */ int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark pV, line 67 */ + z->I[0] = z->c; /* setmark pV, line 71 */ lab0: z->c = c1; } - { int c3 = z->c; /* do, line 69 */ - { /* gopast */ /* grouping v, line 70 */ + { int c3 = z->c; /* do, line 73 */ + { /* gopast */ /* grouping v, line 74 */ int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 70 */ + { /* gopast */ /* non v, line 74 */ int ret = in_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 70 */ - { /* gopast */ /* grouping v, line 71 */ + z->I[1] = z->c; /* setmark p1, line 74 */ + { /* gopast */ /* grouping v, line 75 */ int ret = out_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 71 */ + { /* gopast */ /* non v, line 75 */ int ret = in_grouping(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 71 */ + z->I[2] = z->c; /* setmark p2, line 75 */ lab4: z->c = c3; } return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; - while(1) { /* repeat, line 75 */ + while(1) { /* repeat, line 79 */ int c1 = z->c; - z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652096 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 4; else - among_var = find_among(z, a_1, 4); /* substring, line 77 */ + z->bra = z->c; /* [, line 81 */ + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else /* substring, line 81 */ + among_var = find_among(z, a_1, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 77 */ - switch(among_var) { - case 0: goto lab0; + z->ket = z->c; /* ], line 81 */ + switch (among_var) { /* among, line 81 */ case 1: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 82 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 80 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 84 */ if (ret < 0) return ret; } break; case 4: + { int ret = slice_from_s(z, 1, s_10); /* <-, line 85 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 1, s_11); /* <-, line 86 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 7: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 81 */ + z->c++; /* next, line 88 */ break; } continue; @@ -586,62 +620,59 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 94 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 95 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 96 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 92 */ - among_var = find_among_b(z, a_4, 43); /* substring, line 92 */ + z->ket = z->c; /* [, line 99 */ + among_var = find_among_b(z, a_4, 43); /* substring, line 99 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 99 */ + switch (among_var) { /* among, line 99 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 96 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 103 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); /* delete, line 103 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 99 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 99 */ + { int ret = slice_del(z); /* delete, line 106 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 100 */ - z->ket = z->c; /* [, line 100 */ - if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 100 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 100 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 100 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 107 */ + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 2, s_12))) { z->c = z->l - m1; goto lab0; } /* literal, line 107 */ + z->bra = z->c; /* ], line 107 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 107 */ + { int ret = r_R2(z); /* call R2, line 107 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 100 */ + { int ret = slice_del(z); /* delete, line 107 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m1; - { int ret = slice_from_s(z, 3, s_15); /* <-, line 100 */ + z->c = z->l - m2; + { int ret = slice_from_s(z, 3, s_13); /* <-, line 107 */ if (ret < 0) return ret; } } @@ -651,103 +682,98 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 104 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_16); /* <-, line 104 */ + { int ret = slice_from_s(z, 3, s_14); /* <-, line 111 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 107 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 114 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_17); /* <-, line 107 */ + { int ret = slice_from_s(z, 1, s_15); /* <-, line 114 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 110 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 117 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_18); /* <-, line 110 */ + { int ret = slice_from_s(z, 3, s_16); /* <-, line 117 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 114 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 121 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 114 */ + { int ret = slice_del(z); /* delete, line 121 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 115 */ - z->ket = z->c; /* [, line 116 */ - among_var = find_among_b(z, a_2, 6); /* substring, line 116 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 116 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab3; } + { int m3 = z->l - z->c; (void)m3; /* try, line 122 */ + z->ket = z->c; /* [, line 123 */ + among_var = find_among_b(z, a_2, 6); /* substring, line 123 */ + if (!(among_var)) { z->c = z->l - m3; goto lab3; } + z->bra = z->c; /* ], line 123 */ + switch (among_var) { /* among, line 123 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */ + { int ret = r_R2(z); /* call R2, line 124 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); /* delete, line 124 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 117 */ - if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 117 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */ + z->ket = z->c; /* [, line 124 */ + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m3; goto lab3; } /* literal, line 124 */ + z->bra = z->c; /* ], line 124 */ + { int ret = r_R2(z); /* call R2, line 124 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); /* delete, line 124 */ if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 118 */ - { int ret = r_R2(z); - if (ret == 0) goto lab5; /* call R2, line 118 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 125 */ + { int ret = r_R2(z); /* call R2, line 125 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 118 */ + { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } goto lab4; lab5: - z->c = z->l - m2; - { int ret = r_R1(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R1, line 118 */ + z->c = z->l - m4; + { int ret = r_R1(z); /* call R1, line 125 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 125 */ if (ret < 0) return ret; } } lab4: break; case 3: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 120 */ + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 120 */ + { int ret = slice_del(z); /* delete, line 127 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call RV, line 122 */ + { int ret = r_RV(z); /* call RV, line 129 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 1, s_21); /* <-, line 122 */ + { int ret = slice_from_s(z, 1, s_19); /* <-, line 129 */ if (ret < 0) return ret; } break; @@ -757,63 +783,61 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 129 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 130 */ - z->ket = z->c; /* [, line 131 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab6; } - among_var = find_among_b(z, a_3, 3); /* substring, line 131 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab6; } - z->bra = z->c; /* ], line 131 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab6; } + { int m5 = z->l - z->c; (void)m5; /* try, line 137 */ + z->ket = z->c; /* [, line 138 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } /* substring, line 138 */ + among_var = find_among_b(z, a_3, 3); + if (!(among_var)) { z->c = z->l - m5; goto lab6; } + z->bra = z->c; /* ], line 138 */ + switch (among_var) { /* among, line 138 */ case 1: - { int m3 = z->l - z->c; (void)m3; /* or, line 132 */ - { int ret = r_R2(z); - if (ret == 0) goto lab8; /* call R2, line 132 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 139 */ + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 132 */ + { int ret = slice_del(z); /* delete, line 139 */ if (ret < 0) return ret; } goto lab7; lab8: - z->c = z->l - m3; - { int ret = slice_from_s(z, 3, s_22); /* <-, line 132 */ + z->c = z->l - m6; + { int ret = slice_from_s(z, 3, s_20); /* <-, line 139 */ if (ret < 0) return ret; } } lab7: break; case 2: - { int m4 = z->l - z->c; (void)m4; /* or, line 133 */ - { int ret = r_R2(z); - if (ret == 0) goto lab10; /* call R2, line 133 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 140 */ + { int ret = r_R2(z); /* call R2, line 140 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); /* delete, line 140 */ if (ret < 0) return ret; } goto lab9; lab10: - z->c = z->l - m4; - { int ret = slice_from_s(z, 3, s_23); /* <-, line 133 */ + z->c = z->l - m7; + { int ret = slice_from_s(z, 3, s_21); /* <-, line 140 */ if (ret < 0) return ret; } } lab9: break; case 3: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R2, line 134 */ + { int ret = r_R2(z); /* call R2, line 141 */ + if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); /* delete, line 141 */ if (ret < 0) return ret; } break; @@ -823,39 +847,38 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 141 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 148 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 141 */ + { int ret = slice_del(z); /* delete, line 148 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 142 */ - z->ket = z->c; /* [, line 142 */ - if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m_keep; goto lab11; } - z->bra = z->c; /* ], line 142 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab11; } /* call R2, line 142 */ + { int m8 = z->l - z->c; (void)m8; /* try, line 149 */ + z->ket = z->c; /* [, line 149 */ + if (!(eq_s_b(z, 2, s_22))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ + z->bra = z->c; /* ], line 149 */ + { int ret = r_R2(z); /* call R2, line 149 */ + if (ret == 0) { z->c = z->l - m8; goto lab11; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 142 */ - if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m_keep; goto lab11; } - z->bra = z->c; /* ], line 142 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 142 */ - { int ret = r_R2(z); - if (ret == 0) goto lab13; /* call R2, line 142 */ + z->ket = z->c; /* [, line 149 */ + if (!(eq_s_b(z, 2, s_23))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ + z->bra = z->c; /* ], line 149 */ + { int m9 = z->l - z->c; (void)m9; /* or, line 149 */ + { int ret = r_R2(z); /* call R2, line 149 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } goto lab12; lab13: - z->c = z->l - m5; - { int ret = slice_from_s(z, 3, s_26); /* <-, line 142 */ + z->c = z->l - m9; + { int ret = slice_from_s(z, 3, s_24); /* <-, line 149 */ if (ret < 0) return ret; } } @@ -865,153 +888,143 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 9: - { int ret = slice_from_s(z, 3, s_27); /* <-, line 144 */ + { int ret = slice_from_s(z, 3, s_25); /* <-, line 151 */ if (ret < 0) return ret; } break; case 10: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 145 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 152 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_28); /* <-, line 145 */ + { int ret = slice_from_s(z, 2, s_26); /* <-, line 152 */ if (ret < 0) return ret; } break; case 11: - { int m6 = z->l - z->c; (void)m6; /* or, line 147 */ - { int ret = r_R2(z); - if (ret == 0) goto lab15; /* call R2, line 147 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 154 */ + { int ret = r_R2(z); /* call R2, line 154 */ + if (ret == 0) goto lab15; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); /* delete, line 154 */ if (ret < 0) return ret; } goto lab14; lab15: - z->c = z->l - m6; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 147 */ - if (ret < 0) return ret; + z->c = z->l - m10; + { int ret = r_R1(z); /* call R1, line 154 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_29); /* <-, line 147 */ + { int ret = slice_from_s(z, 3, s_27); /* <-, line 154 */ if (ret < 0) return ret; } } lab14: break; case 12: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 150 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 157 */ + if (ret <= 0) return ret; } - if (out_grouping_b(z, g_v, 97, 251, 0)) return 0; - { int ret = slice_del(z); /* delete, line 150 */ + if (out_grouping_b(z, g_v, 97, 251, 0)) return 0; /* non v, line 157 */ + { int ret = slice_del(z); /* delete, line 157 */ if (ret < 0) return ret; } break; case 13: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 155 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 162 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_30); /* <-, line 155 */ + { int ret = slice_from_s(z, 3, s_28); /* <-, line 162 */ if (ret < 0) return ret; } - return 0; /* fail, line 155 */ + return 0; /* fail, line 162 */ break; case 14: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 156 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 163 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_31); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_29); /* <-, line 163 */ if (ret < 0) return ret; } - return 0; /* fail, line 156 */ + return 0; /* fail, line 163 */ break; case 15: - { int m_test = z->l - z->c; /* test, line 158 */ - if (in_grouping_b(z, g_v, 97, 251, 0)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 158 */ - if (ret < 0) return ret; + { int m_test11 = z->l - z->c; /* test, line 165 */ + if (in_grouping_b(z, g_v, 97, 251, 0)) return 0; /* grouping v, line 165 */ + { int ret = r_RV(z); /* call RV, line 165 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test11; } - { int ret = slice_del(z); /* delete, line 158 */ + { int ret = slice_del(z); /* delete, line 165 */ if (ret < 0) return ret; } - return 0; /* fail, line 158 */ + return 0; /* fail, line 165 */ break; } return 1; } -static int r_i_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 163 */ - int m1 = z->l - z->c; (void)m1; +static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 170 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 163 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 164 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_5, 35); /* substring, line 164 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 164 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - if (out_grouping_b(z, g_v, 97, 251, 0)) { z->lb = mlimit; return 0; } - { int ret = slice_del(z); /* delete, line 170 */ - if (ret < 0) return ret; - } - break; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 171 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 171 */ + if (!(find_among_b(z, a_5, 35))) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 171 */ + { int m2 = z->l - z->c; (void)m2; /* not, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; /* literal, line 177 */ + z->c--; + { z->lb = mlimit1; return 0; } + lab0: + z->c = z->l - m2; } - z->lb = mlimit; + if (out_grouping_b(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } /* non v, line 177 */ + { int ret = slice_del(z); /* delete, line 177 */ + if (ret < 0) return ret; + } + z->lb = mlimit1; } return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 174 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 181 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 174 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 175 */ - among_var = find_among_b(z, a_6, 38); /* substring, line 175 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 175 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 182 */ + among_var = find_among_b(z, a_6, 38); /* substring, line 182 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 182 */ + switch (among_var) { /* among, line 182 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 177 */ + { int ret = r_R2(z); /* call R2, line 184 */ + if (ret == 0) { z->lb = mlimit1; return 0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 177 */ + { int ret = slice_del(z); /* delete, line 184 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 185 */ + { int ret = slice_del(z); /* delete, line 192 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 190 */ + { int ret = slice_del(z); /* delete, line 197 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 191 */ - z->ket = z->c; /* [, line 191 */ - if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 191 */ - { int ret = slice_del(z); /* delete, line 191 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 198 */ + z->ket = z->c; /* [, line 198 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } /* literal, line 198 */ + z->c--; + z->bra = z->c; /* ], line 198 */ + { int ret = slice_del(z); /* delete, line 198 */ if (ret < 0) return ret; } lab0: @@ -1019,98 +1032,100 @@ static int r_verb_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_residual_suffix(struct SN_env * z) { +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 199 */ - z->ket = z->c; /* [, line 199 */ - if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 199 */ - { int m_test = z->l - z->c; /* test, line 199 */ - if (out_grouping_b(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m1 = z->l - z->c; (void)m1; /* try, line 206 */ + z->ket = z->c; /* [, line 206 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } /* literal, line 206 */ + z->c--; + z->bra = z->c; /* ], line 206 */ + { int m_test2 = z->l - z->c; /* test, line 206 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 206 */ + if (!(eq_s_b(z, 2, s_30))) goto lab2; /* literal, line 206 */ + goto lab1; + lab2: + z->c = z->l - m3; + if (out_grouping_b(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } /* non keep_with_s, line 206 */ + } + lab1: + z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 199 */ + { int ret = slice_del(z); /* delete, line 206 */ if (ret < 0) return ret; } lab0: ; } - { int mlimit; /* setlimit, line 200 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit4; /* setlimit, line 207 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 200 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 201 */ - among_var = find_among_b(z, a_7, 7); /* substring, line 201 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 201 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + mlimit4 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 208 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } /* substring, line 208 */ + among_var = find_among_b(z, a_7, 6); + if (!(among_var)) { z->lb = mlimit4; return 0; } + z->bra = z->c; /* ], line 208 */ + switch (among_var) { /* among, line 208 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 202 */ + { int ret = r_R2(z); /* call R2, line 209 */ + if (ret == 0) { z->lb = mlimit4; return 0; } if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* or, line 202 */ - if (!(eq_s_b(z, 1, s_34))) goto lab2; - goto lab1; - lab2: - z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_35))) { z->lb = mlimit; return 0; } + { int m5 = z->l - z->c; (void)m5; /* or, line 209 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; /* literal, line 209 */ + z->c--; + goto lab3; + lab4: + z->c = z->l - m5; + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } /* literal, line 209 */ + z->c--; } - lab1: - { int ret = slice_del(z); /* delete, line 202 */ + lab3: + { int ret = slice_del(z); /* delete, line 209 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_36); /* <-, line 204 */ + { int ret = slice_from_s(z, 1, s_31); /* <-, line 211 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 205 */ - if (ret < 0) return ret; - } - break; - case 4: - if (!(eq_s_b(z, 2, s_37))) { z->lb = mlimit; return 0; } - { int ret = slice_del(z); /* delete, line 206 */ + { int ret = slice_del(z); /* delete, line 212 */ if (ret < 0) return ret; } break; } - z->lb = mlimit; + z->lb = mlimit4; } return 1; } -static int r_un_double(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 212 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_8, 5))) return 0; /* among, line 212 */ - z->c = z->l - m_test; +static int r_un_double(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 218 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 218 */ + if (!(find_among_b(z, a_8, 5))) return 0; + z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 212 */ + z->ket = z->c; /* [, line 218 */ if (z->c <= z->lb) return 0; - z->c--; /* next, line 212 */ - z->bra = z->c; /* ], line 212 */ - { int ret = slice_del(z); /* delete, line 212 */ + z->c--; /* next, line 218 */ + z->bra = z->c; /* ], line 218 */ + { int ret = slice_del(z); /* delete, line 218 */ if (ret < 0) return ret; } return 1; } -static int r_un_accent(struct SN_env * z) { +static int r_un_accent(struct SN_env * z) { /* backwardmode */ { int i = 1; - while(1) { /* atleast, line 216 */ - if (out_grouping_b(z, g_v, 97, 251, 0)) goto lab0; + while(1) { /* atleast, line 222 */ + if (out_grouping_b(z, g_v, 97, 251, 0)) goto lab0; /* non v, line 222 */ i--; continue; lab0: @@ -1118,80 +1133,82 @@ static int r_un_accent(struct SN_env * z) { } if (i > 0) return 0; } - z->ket = z->c; /* [, line 217 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 217 */ - if (!(eq_s_b(z, 1, s_38))) goto lab2; + z->ket = z->c; /* [, line 223 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 223 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xE9) goto lab2; /* literal, line 223 */ + z->c--; goto lab1; lab2: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_39))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xE8) return 0; /* literal, line 223 */ + z->c--; } lab1: - z->bra = z->c; /* ], line 217 */ - { int ret = slice_from_s(z, 1, s_40); /* <-, line 217 */ + z->bra = z->c; /* ], line 223 */ + { int ret = slice_from_s(z, 1, s_32); /* <-, line 223 */ if (ret < 0) return ret; } return 1; } -extern int french_ISO_8859_1_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 223 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 223 */ +extern int french_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 229 */ + { int ret = r_prelude(z); /* call prelude, line 229 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 224 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 224 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 230 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 230 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 225 */ +lab1: + z->lb = z->c; z->c = z->l; /* backwards, line 231 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 227 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 237 */ - { int m5 = z->l - z->c; (void)m5; /* and, line 233 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 229 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab6; /* call standard_suffix, line 229 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 233 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 243 */ + { int m4 = z->l - z->c; (void)m4; /* and, line 239 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 235 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 235 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_i_verb_suffix(z); - if (ret == 0) goto lab7; /* call i_verb_suffix, line 230 */ + z->c = z->l - m5; + { int ret = r_i_verb_suffix(z); /* call i_verb_suffix, line 236 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } goto lab5; lab7: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 231 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 237 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: - z->c = z->l - m5; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 234 */ - z->ket = z->c; /* [, line 234 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 234 */ - if (!(eq_s_b(z, 1, s_41))) goto lab10; - z->bra = z->c; /* ], line 234 */ - { int ret = slice_from_s(z, 1, s_42); /* <-, line 234 */ + z->c = z->l - m4; + { int m6 = z->l - z->c; (void)m6; /* try, line 240 */ + z->ket = z->c; /* [, line 240 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 240 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab10; /* literal, line 240 */ + z->c--; + z->bra = z->c; /* ], line 240 */ + { int ret = slice_from_s(z, 1, s_33); /* <-, line 240 */ if (ret < 0) return ret; } goto lab9; lab10: z->c = z->l - m7; - if (!(eq_s_b(z, 1, s_43))) { z->c = z->l - m_keep; goto lab8; } - z->bra = z->c; /* ], line 235 */ - { int ret = slice_from_s(z, 1, s_44); /* <-, line 235 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xE7) { z->c = z->l - m6; goto lab8; } /* literal, line 241 */ + z->c--; + z->bra = z->c; /* ], line 241 */ + { int ret = slice_from_s(z, 1, s_34); /* <-, line 241 */ if (ret < 0) return ret; } } @@ -1202,36 +1219,36 @@ extern int french_ISO_8859_1_stem(struct SN_env * z) { } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab2; /* call residual_suffix, line 238 */ + z->c = z->l - m3; + { int ret = r_residual_suffix(z); /* call residual_suffix, line 244 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 243 */ - { int ret = r_un_double(z); - if (ret == 0) goto lab11; /* call un_double, line 243 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 249 */ + { int ret = r_un_double(z); /* call un_double, line 249 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 244 */ - { int ret = r_un_accent(z); - if (ret == 0) goto lab12; /* call un_accent, line 244 */ + { int m9 = z->l - z->c; (void)m9; /* do, line 250 */ + { int ret = r_un_accent(z); /* call un_accent, line 250 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: z->c = z->l - m9; } z->c = z->lb; - { int c10 = z->c; /* do, line 246 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab13; /* call postlude, line 246 */ + { int c10 = z->c; /* do, line 252 */ + { int ret = r_postlude(z); /* call postlude, line 252 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } lab13: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c index 13c24230923..ae334f80bf9 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_german.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -36,12 +36,12 @@ static const symbol s_0_5[1] = { 0xFC }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 6, 0}, +/* 0 */ { 0, 0, -1, 5, 0}, /* 1 */ { 1, s_0_1, 0, 2, 0}, /* 2 */ { 1, s_0_2, 0, 1, 0}, /* 3 */ { 1, s_0_3, 0, 3, 0}, /* 4 */ { 1, s_0_4, 0, 4, 0}, -/* 5 */ { 1, s_0_5, 0, 5, 0} +/* 5 */ { 1, s_0_5, 0, 2, 0} }; static const symbol s_1_0[1] = { 'e' }; @@ -54,13 +54,13 @@ static const symbol s_1_6[2] = { 'e', 's' }; static const struct among a_1[7] = { -/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 0 */ { 1, s_1_0, -1, 2, 0}, /* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 2, 0}, /* 3 */ { 3, s_1_3, -1, 1, 0}, /* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 1, s_1_5, -1, 2, 0}, -/* 6 */ { 2, s_1_6, 5, 1, 0} +/* 5 */ { 1, s_1_5, -1, 3, 0}, +/* 6 */ { 2, s_1_6, 5, 2, 0} }; static const symbol s_2_0[2] = { 'e', 'n' }; @@ -112,165 +112,157 @@ static const unsigned char g_s_ending[] = { 117, 30, 5 }; static const unsigned char g_st_ending[] = { 117, 30, 4 }; -static const symbol s_0[] = { 0xDF }; -static const symbol s_1[] = { 's', 's' }; -static const symbol s_2[] = { 'u' }; -static const symbol s_3[] = { 'U' }; -static const symbol s_4[] = { 'y' }; -static const symbol s_5[] = { 'Y' }; -static const symbol s_6[] = { 'y' }; -static const symbol s_7[] = { 'u' }; -static const symbol s_8[] = { 'a' }; -static const symbol s_9[] = { 'o' }; -static const symbol s_10[] = { 'u' }; -static const symbol s_11[] = { 'i', 'g' }; -static const symbol s_12[] = { 'e' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'e', 'r' }; -static const symbol s_15[] = { 'e', 'n' }; +static const symbol s_0[] = { 's', 's' }; +static const symbol s_1[] = { 'U' }; +static const symbol s_2[] = { 'Y' }; +static const symbol s_3[] = { 'y' }; +static const symbol s_4[] = { 'u' }; +static const symbol s_5[] = { 'a' }; +static const symbol s_6[] = { 'o' }; +static const symbol s_7[] = { 'n', 'i', 's' }; +static const symbol s_8[] = { 'i', 'g' }; +static const symbol s_9[] = { 'e', 'r' }; +static const symbol s_10[] = { 'e', 'n' }; -static int r_prelude(struct SN_env * z) { - { int c_test = z->c; /* test, line 30 */ - while(1) { /* repeat, line 30 */ - int c1 = z->c; - { int c2 = z->c; /* or, line 33 */ - z->bra = z->c; /* [, line 32 */ - if (!(eq_s(z, 1, s_0))) goto lab2; - z->ket = z->c; /* ], line 32 */ - { int ret = slice_from_s(z, 2, s_1); /* <-, line 32 */ +static int r_prelude(struct SN_env * z) { /* forwardmode */ + { int c_test1 = z->c; /* test, line 35 */ + while(1) { /* repeat, line 35 */ + int c2 = z->c; + { int c3 = z->c; /* or, line 38 */ + z->bra = z->c; /* [, line 37 */ + if (z->c == z->l || z->p[z->c] != 0xDF) goto lab2; /* literal, line 37 */ + z->c++; + z->ket = z->c; /* ], line 37 */ + { int ret = slice_from_s(z, 2, s_0); /* <-, line 37 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = c2; + z->c = c3; if (z->c >= z->l) goto lab0; - z->c++; /* next, line 33 */ + z->c++; /* next, line 38 */ } lab1: continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } - while(1) { /* repeat, line 36 */ - int c3 = z->c; - while(1) { /* goto, line 36 */ - int c4 = z->c; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; - z->bra = z->c; /* [, line 37 */ - { int c5 = z->c; /* or, line 37 */ - if (!(eq_s(z, 1, s_2))) goto lab6; - z->ket = z->c; /* ], line 37 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab6; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 37 */ + while(1) { /* repeat, line 41 */ + int c4 = z->c; + while(1) { /* goto, line 41 */ + int c5 = z->c; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 42 */ + z->bra = z->c; /* [, line 42 */ + { int c6 = z->c; /* or, line 42 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab6; /* literal, line 42 */ + z->c++; + z->ket = z->c; /* ], line 42 */ + if (in_grouping(z, g_v, 97, 252, 0)) goto lab6; /* grouping v, line 42 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 42 */ if (ret < 0) return ret; } goto lab5; lab6: - z->c = c5; - if (!(eq_s(z, 1, s_4))) goto lab4; - z->ket = z->c; /* ], line 38 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; - { int ret = slice_from_s(z, 1, s_5); /* <-, line 38 */ + z->c = c6; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 43 */ + z->c++; + z->ket = z->c; /* ], line 43 */ + if (in_grouping(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 43 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 43 */ if (ret < 0) return ret; } } lab5: - z->c = c4; + z->c = c5; break; lab4: - z->c = c4; + z->c = c5; if (z->c >= z->l) goto lab3; - z->c++; /* goto, line 36 */ + z->c++; /* goto, line 41 */ } continue; lab3: - z->c = c3; + z->c = c4; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - { int c_test = z->c; /* test, line 47 */ - { int ret = z->c + 3; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 49 */ + z->I[1] = z->l; /* $p2 = , line 50 */ + { int c_test1 = z->c; /* test, line 52 */ + { int ret = z->c + 3; /* hop, line 52 */ if (0 > ret || ret > z->l) return 0; - z->c = ret; /* hop, line 47 */ + z->c = ret; } - z->I[2] = z->c; /* setmark x, line 47 */ - z->c = c_test; + z->I[2] = z->c; /* setmark x, line 52 */ + z->c = c_test1; } - { /* gopast */ /* grouping v, line 49 */ + { /* gopast */ /* grouping v, line 54 */ int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 49 */ + { /* gopast */ /* non v, line 54 */ int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 49 */ - /* try, line 50 */ - if (!(z->I[0] < z->I[2])) goto lab0; - z->I[0] = z->I[2]; + z->I[0] = z->c; /* setmark p1, line 54 */ + /* try, line 55 */ + if (!(z->I[0] < z->I[2])) goto lab0; /* $( < ), line 55 */ + z->I[0] = z->I[2]; /* $p1 = , line 55 */ lab0: - { /* gopast */ /* grouping v, line 51 */ + { /* gopast */ /* grouping v, line 56 */ int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 51 */ + { /* gopast */ /* non v, line 56 */ int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 51 */ + z->I[1] = z->c; /* setmark p2, line 56 */ return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; - while(1) { /* repeat, line 55 */ + while(1) { /* repeat, line 60 */ int c1 = z->c; - z->bra = z->c; /* [, line 57 */ - among_var = find_among(z, a_0, 6); /* substring, line 57 */ + z->bra = z->c; /* [, line 62 */ + among_var = find_among(z, a_0, 6); /* substring, line 62 */ if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 57 */ - switch(among_var) { - case 0: goto lab0; + z->ket = z->c; /* ], line 62 */ + switch (among_var) { /* among, line 62 */ case 1: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 58 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 64 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 65 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 61 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 66 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 62 */ - if (ret < 0) return ret; - } - break; - case 6: if (z->c >= z->l) goto lab0; - z->c++; /* next, line 63 */ + z->c++; /* next, line 68 */ break; } continue; @@ -281,38 +273,54 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 75 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 76 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 74 */ - z->ket = z->c; /* [, line 75 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; - among_var = find_among_b(z, a_1, 7); /* substring, line 75 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 79 */ + z->ket = z->c; /* [, line 80 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 80 */ + among_var = find_among_b(z, a_1, 7); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 75 */ - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 75 */ + z->bra = z->c; /* ], line 80 */ + { int ret = r_R1(z); /* call R1, line 80 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 80 */ case 1: - { int ret = slice_del(z); /* delete, line 77 */ + { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_s_ending, 98, 116, 0)) goto lab0; - { int ret = slice_del(z); /* delete, line 80 */ + { int ret = slice_del(z); /* delete, line 85 */ + if (ret < 0) return ret; + } + { int m2 = z->l - z->c; (void)m2; /* try, line 86 */ + z->ket = z->c; /* [, line 86 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + z->c--; + z->bra = z->c; /* ], line 86 */ + if (!(eq_s_b(z, 3, s_7))) { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + { int ret = slice_del(z); /* delete, line 86 */ + if (ret < 0) return ret; + } + lab1: + ; + } + break; + case 3: + if (in_grouping_b(z, g_s_ending, 98, 116, 0)) goto lab0; /* grouping s_ending, line 89 */ + { int ret = slice_del(z); /* delete, line 89 */ if (ret < 0) return ret; } break; @@ -320,179 +328,171 @@ static int r_standard_suffix(struct SN_env * z) { lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 84 */ - z->ket = z->c; /* [, line 85 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1; - among_var = find_among_b(z, a_2, 4); /* substring, line 85 */ - if (!(among_var)) goto lab1; - z->bra = z->c; /* ], line 85 */ - { int ret = r_R1(z); - if (ret == 0) goto lab1; /* call R1, line 85 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 93 */ + z->ket = z->c; /* [, line 94 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 94 */ + among_var = find_among_b(z, a_2, 4); + if (!(among_var)) goto lab2; + z->bra = z->c; /* ], line 94 */ + { int ret = r_R1(z); /* call R1, line 94 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab1; + switch (among_var) { /* among, line 94 */ case 1: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); /* delete, line 96 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_st_ending, 98, 116, 0)) goto lab1; - { int ret = z->c - 3; - if (z->lb > ret || ret > z->l) goto lab1; - z->c = ret; /* hop, line 90 */ + if (in_grouping_b(z, g_st_ending, 98, 116, 0)) goto lab2; /* grouping st_ending, line 99 */ + { int ret = z->c - 3; /* hop, line 99 */ + if (z->lb > ret || ret > z->l) goto lab2; + z->c = ret; } - { int ret = slice_del(z); /* delete, line 90 */ + { int ret = slice_del(z); /* delete, line 99 */ if (ret < 0) return ret; } break; } - lab1: - z->c = z->l - m2; + lab2: + z->c = z->l - m3; } - { int m3 = z->l - z->c; (void)m3; /* do, line 94 */ - z->ket = z->c; /* [, line 95 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; - among_var = find_among_b(z, a_4, 8); /* substring, line 95 */ - if (!(among_var)) goto lab2; - z->bra = z->c; /* ], line 95 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 95 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 103 */ + z->ket = z->c; /* [, line 104 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 104 */ + among_var = find_among_b(z, a_4, 8); + if (!(among_var)) goto lab3; + z->bra = z->c; /* ], line 104 */ + { int ret = r_R2(z); /* call R2, line 104 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab2; + switch (among_var) { /* among, line 104 */ case 1: - { int ret = slice_del(z); /* delete, line 97 */ + { int ret = slice_del(z); /* delete, line 106 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 98 */ - z->ket = z->c; /* [, line 98 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 98 */ - { int m4 = z->l - z->c; (void)m4; /* not, line 98 */ - if (!(eq_s_b(z, 1, s_12))) goto lab4; - { z->c = z->l - m_keep; goto lab3; } - lab4: - z->c = z->l - m4; + { int m5 = z->l - z->c; (void)m5; /* try, line 107 */ + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m5; goto lab4; } /* literal, line 107 */ + z->bra = z->c; /* ], line 107 */ + { int m6 = z->l - z->c; (void)m6; /* not, line 107 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; /* literal, line 107 */ + z->c--; + { z->c = z->l - m5; goto lab4; } + lab5: + z->c = z->l - m6; } - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 98 */ + { int ret = r_R2(z); /* call R2, line 107 */ + if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 98 */ + { int ret = slice_del(z); /* delete, line 107 */ if (ret < 0) return ret; } - lab3: + lab4: ; } break; case 2: - { int m5 = z->l - z->c; (void)m5; /* not, line 101 */ - if (!(eq_s_b(z, 1, s_13))) goto lab5; - goto lab2; - lab5: - z->c = z->l - m5; + { int m7 = z->l - z->c; (void)m7; /* not, line 110 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 110 */ + z->c--; + goto lab3; + lab6: + z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 101 */ + { int ret = slice_del(z); /* delete, line 110 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 104 */ + { int ret = slice_del(z); /* delete, line 113 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 105 */ - z->ket = z->c; /* [, line 106 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 106 */ - if (!(eq_s_b(z, 2, s_14))) goto lab8; - goto lab7; - lab8: - z->c = z->l - m6; - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab6; } + { int m8 = z->l - z->c; (void)m8; /* try, line 114 */ + z->ket = z->c; /* [, line 115 */ + { int m9 = z->l - z->c; (void)m9; /* or, line 115 */ + if (!(eq_s_b(z, 2, s_9))) goto lab9; /* literal, line 115 */ + goto lab8; + lab9: + z->c = z->l - m9; + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m8; goto lab7; } /* literal, line 115 */ } - lab7: - z->bra = z->c; /* ], line 106 */ - { int ret = r_R1(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R1, line 106 */ + lab8: + z->bra = z->c; /* ], line 115 */ + { int ret = r_R1(z); /* call R1, line 115 */ + if (ret == 0) { z->c = z->l - m8; goto lab7; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); /* delete, line 115 */ if (ret < 0) return ret; } - lab6: + lab7: ; } break; case 4: - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); /* delete, line 119 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m_keep; goto lab9; } - among_var = find_among_b(z, a_3, 2); /* substring, line 112 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab9; } - z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab9; } /* call R2, line 112 */ + { int m10 = z->l - z->c; (void)m10; /* try, line 120 */ + z->ket = z->c; /* [, line 121 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } /* substring, line 121 */ + if (!(find_among_b(z, a_3, 2))) { z->c = z->l - m10; goto lab10; } + z->bra = z->c; /* ], line 121 */ + { int ret = r_R2(z); /* call R2, line 121 */ + if (ret == 0) { z->c = z->l - m10; goto lab10; } if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab9; } - case 1: - { int ret = slice_del(z); /* delete, line 114 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; } - lab9: + lab10: ; } break; } - lab2: - z->c = z->l - m3; + lab3: + z->c = z->l - m4; } return 1; } -extern int german_ISO_8859_1_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 125 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 125 */ +extern int german_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 134 */ + { int ret = r_prelude(z); /* call prelude, line 134 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 126 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 126 */ + { int c2 = z->c; /* do, line 135 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 135 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 127 */ + z->lb = z->c; z->c = z->l; /* backwards, line 136 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 128 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab2; /* call standard_suffix, line 128 */ - if (ret < 0) return ret; - } - lab2: - z->c = z->l - m3; + /* do, line 137 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 137 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; } +lab2: z->c = z->lb; - { int c4 = z->c; /* do, line 129 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab3; /* call postlude, line 129 */ + { int c3 = z->c; /* do, line 138 */ + { int ret = r_postlude(z); /* call postlude, line 138 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = c4; + z->c = c3; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c new file mode 100644 index 00000000000..42711709032 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_indonesian.c @@ -0,0 +1,414 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int indonesian_ISO_8859_1_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_VOWEL(struct SN_env * z); +static int r_SUFFIX_I_OK(struct SN_env * z); +static int r_SUFFIX_AN_OK(struct SN_env * z); +static int r_SUFFIX_KAN_OK(struct SN_env * z); +static int r_KER(struct SN_env * z); +static int r_remove_suffix(struct SN_env * z); +static int r_remove_second_order_prefix(struct SN_env * z); +static int r_remove_first_order_prefix(struct SN_env * z); +static int r_remove_possessive_pronoun(struct SN_env * z); +static int r_remove_particle(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * indonesian_ISO_8859_1_create_env(void); +extern void indonesian_ISO_8859_1_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[3] = { 'k', 'a', 'h' }; +static const symbol s_0_1[3] = { 'l', 'a', 'h' }; +static const symbol s_0_2[3] = { 'p', 'u', 'n' }; + +static const struct among a_0[3] = +{ +/* 0 */ { 3, s_0_0, -1, 1, 0}, +/* 1 */ { 3, s_0_1, -1, 1, 0}, +/* 2 */ { 3, s_0_2, -1, 1, 0} +}; + +static const symbol s_1_0[3] = { 'n', 'y', 'a' }; +static const symbol s_1_1[2] = { 'k', 'u' }; +static const symbol s_1_2[2] = { 'm', 'u' }; + +static const struct among a_1[3] = +{ +/* 0 */ { 3, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0} +}; + +static const symbol s_2_0[1] = { 'i' }; +static const symbol s_2_1[2] = { 'a', 'n' }; +static const symbol s_2_2[3] = { 'k', 'a', 'n' }; + +static const struct among a_2[3] = +{ +/* 0 */ { 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, +/* 1 */ { 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, +/* 2 */ { 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} +}; + +static const symbol s_3_0[2] = { 'd', 'i' }; +static const symbol s_3_1[2] = { 'k', 'e' }; +static const symbol s_3_2[2] = { 'm', 'e' }; +static const symbol s_3_3[3] = { 'm', 'e', 'm' }; +static const symbol s_3_4[3] = { 'm', 'e', 'n' }; +static const symbol s_3_5[4] = { 'm', 'e', 'n', 'g' }; +static const symbol s_3_6[4] = { 'm', 'e', 'n', 'y' }; +static const symbol s_3_7[3] = { 'p', 'e', 'm' }; +static const symbol s_3_8[3] = { 'p', 'e', 'n' }; +static const symbol s_3_9[4] = { 'p', 'e', 'n', 'g' }; +static const symbol s_3_10[4] = { 'p', 'e', 'n', 'y' }; +static const symbol s_3_11[3] = { 't', 'e', 'r' }; + +static const struct among a_3[12] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 2, s_3_1, -1, 2, 0}, +/* 2 */ { 2, s_3_2, -1, 1, 0}, +/* 3 */ { 3, s_3_3, 2, 5, 0}, +/* 4 */ { 3, s_3_4, 2, 1, 0}, +/* 5 */ { 4, s_3_5, 4, 1, 0}, +/* 6 */ { 4, s_3_6, 4, 3, r_VOWEL}, +/* 7 */ { 3, s_3_7, -1, 6, 0}, +/* 8 */ { 3, s_3_8, -1, 2, 0}, +/* 9 */ { 4, s_3_9, 8, 2, 0}, +/* 10 */ { 4, s_3_10, 8, 4, r_VOWEL}, +/* 11 */ { 3, s_3_11, -1, 1, 0} +}; + +static const symbol s_4_0[2] = { 'b', 'e' }; +static const symbol s_4_1[7] = { 'b', 'e', 'l', 'a', 'j', 'a', 'r' }; +static const symbol s_4_2[3] = { 'b', 'e', 'r' }; +static const symbol s_4_3[2] = { 'p', 'e' }; +static const symbol s_4_4[7] = { 'p', 'e', 'l', 'a', 'j', 'a', 'r' }; +static const symbol s_4_5[3] = { 'p', 'e', 'r' }; + +static const struct among a_4[6] = +{ +/* 0 */ { 2, s_4_0, -1, 3, r_KER}, +/* 1 */ { 7, s_4_1, 0, 4, 0}, +/* 2 */ { 3, s_4_2, 0, 3, 0}, +/* 3 */ { 2, s_4_3, -1, 1, 0}, +/* 4 */ { 7, s_4_4, 3, 2, 0}, +/* 5 */ { 3, s_4_5, 3, 1, 0} +}; + +static const unsigned char g_vowel[] = { 17, 65, 16 }; + +static const symbol s_0[] = { 'e', 'r' }; +static const symbol s_1[] = { 's' }; +static const symbol s_2[] = { 's' }; +static const symbol s_3[] = { 'p' }; +static const symbol s_4[] = { 'p' }; +static const symbol s_5[] = { 'a', 'j', 'a', 'r' }; +static const symbol s_6[] = { 'a', 'j', 'a', 'r' }; + +static int r_remove_particle(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 51 */ + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; /* substring, line 51 */ + if (!(find_among_b(z, a_0, 3))) return 0; + z->bra = z->c; /* ], line 51 */ + { int ret = slice_del(z); /* delete, line 52 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 52 */ + return 1; +} + +static int r_remove_possessive_pronoun(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 57 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; /* substring, line 57 */ + if (!(find_among_b(z, a_1, 3))) return 0; + z->bra = z->c; /* ], line 57 */ + { int ret = slice_del(z); /* delete, line 58 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 58 */ + return 1; +} + +static int r_SUFFIX_KAN_OK(struct SN_env * z) { /* backwardmode */ + /* and, line 85 */ + if (!(z->I[1] != 3)) return 0; /* $( != ), line 85 */ + if (!(z->I[1] != 2)) return 0; /* $( != ), line 85 */ + return 1; +} + +static int r_SUFFIX_AN_OK(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] != 1)) return 0; /* $( != ), line 89 */ + return 1; +} + +static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= 2)) return 0; /* $( <= ), line 93 */ + { int m1 = z->l - z->c; (void)m1; /* not, line 128 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; /* literal, line 128 */ + z->c--; + return 0; + lab0: + z->c = z->l - m1; + } + return 1; +} + +static int r_remove_suffix(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 132 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; /* substring, line 132 */ + if (!(find_among_b(z, a_2, 3))) return 0; + z->bra = z->c; /* ], line 132 */ + { int ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 134 */ + return 1; +} + +static int r_VOWEL(struct SN_env * z) { /* forwardmode */ + if (in_grouping(z, g_vowel, 97, 117, 0)) return 0; /* grouping vowel, line 141 */ + return 1; +} + +static int r_KER(struct SN_env * z) { /* forwardmode */ + if (out_grouping(z, g_vowel, 97, 117, 0)) return 0; /* non vowel, line 143 */ + if (!(eq_s(z, 2, s_0))) return 0; /* literal, line 143 */ + return 1; +} + +static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 146 */ + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; /* substring, line 146 */ + among_var = find_among(z, a_3, 12); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 146 */ + switch (among_var) { /* among, line 146 */ + case 1: + { int ret = slice_del(z); /* delete, line 147 */ + if (ret < 0) return ret; + } + z->I[1] = 1; /* $prefix = , line 147 */ + z->I[0] -= 1; /* $measure -= , line 147 */ + break; + case 2: + { int ret = slice_del(z); /* delete, line 148 */ + if (ret < 0) return ret; + } + z->I[1] = 3; /* $prefix = , line 148 */ + z->I[0] -= 1; /* $measure -= , line 148 */ + break; + case 3: + z->I[1] = 1; /* $prefix = , line 149 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 149 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 149 */ + break; + case 4: + z->I[1] = 3; /* $prefix = , line 150 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 150 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 150 */ + break; + case 5: + z->I[1] = 1; /* $prefix = , line 151 */ + z->I[0] -= 1; /* $measure -= , line 151 */ + { int c1 = z->c; /* or, line 151 */ + { int c2 = z->c; /* and, line 151 */ + if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab1; /* grouping vowel, line 151 */ + z->c = c2; + { int ret = slice_from_s(z, 1, s_3); /* <-, line 151 */ + if (ret < 0) return ret; + } + } + goto lab0; + lab1: + z->c = c1; + { int ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + } + lab0: + break; + case 6: + z->I[1] = 3; /* $prefix = , line 152 */ + z->I[0] -= 1; /* $measure -= , line 152 */ + { int c3 = z->c; /* or, line 152 */ + { int c4 = z->c; /* and, line 152 */ + if (in_grouping(z, g_vowel, 97, 117, 0)) goto lab3; /* grouping vowel, line 152 */ + z->c = c4; + { int ret = slice_from_s(z, 1, s_4); /* <-, line 152 */ + if (ret < 0) return ret; + } + } + goto lab2; + lab3: + z->c = c3; + { int ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + } + lab2: + break; + } + return 1; +} + +static int r_remove_second_order_prefix(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 162 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; /* substring, line 162 */ + among_var = find_among(z, a_4, 6); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 162 */ + switch (among_var) { /* among, line 162 */ + case 1: + { int ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + z->I[1] = 2; /* $prefix = , line 163 */ + z->I[0] -= 1; /* $measure -= , line 163 */ + break; + case 2: + { int ret = slice_from_s(z, 4, s_5); /* <-, line 164 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 164 */ + break; + case 3: + { int ret = slice_del(z); /* delete, line 165 */ + if (ret < 0) return ret; + } + z->I[1] = 4; /* $prefix = , line 165 */ + z->I[0] -= 1; /* $measure -= , line 165 */ + break; + case 4: + { int ret = slice_from_s(z, 4, s_6); /* <-, line 166 */ + if (ret < 0) return ret; + } + z->I[1] = 4; /* $prefix = , line 166 */ + z->I[0] -= 1; /* $measure -= , line 166 */ + break; + } + return 1; +} + +extern int indonesian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + z->I[0] = 0; /* $measure = , line 172 */ + { int c1 = z->c; /* do, line 173 */ + while(1) { /* repeat, line 173 */ + int c2 = z->c; + { /* gopast */ /* grouping vowel, line 173 */ + int ret = out_grouping(z, g_vowel, 97, 117, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[0] += 1; /* $measure += , line 173 */ + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + if (!(z->I[0] > 2)) return 0; /* $( > ), line 174 */ + z->I[1] = 0; /* $prefix = , line 175 */ + z->lb = z->c; z->c = z->l; /* backwards, line 176 */ + + { int m3 = z->l - z->c; (void)m3; /* do, line 177 */ + { int ret = r_remove_particle(z); /* call remove_particle, line 177 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m3; + } + if (!(z->I[0] > 2)) return 0; /* $( > ), line 178 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 179 */ + { int ret = r_remove_possessive_pronoun(z); /* call remove_possessive_pronoun, line 179 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m4; + } + z->c = z->lb; + if (!(z->I[0] > 2)) return 0; /* $( > ), line 181 */ + { int c5 = z->c; /* or, line 188 */ + { int c_test6 = z->c; /* test, line 182 */ + { int ret = r_remove_first_order_prefix(z); /* call remove_first_order_prefix, line 183 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; + } + { int c7 = z->c; /* do, line 184 */ + { int c_test8 = z->c; /* test, line 185 */ + if (!(z->I[0] > 2)) goto lab6; /* $( > ), line 185 */ + z->lb = z->c; z->c = z->l; /* backwards, line 185 */ + + { int ret = r_remove_suffix(z); /* call remove_suffix, line 185 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + z->c = z->lb; + z->c = c_test8; + } + if (!(z->I[0] > 2)) goto lab6; /* $( > ), line 186 */ + { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 186 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + lab6: + z->c = c7; + } + z->c = c_test6; + } + goto lab4; + lab5: + z->c = c5; + { int c9 = z->c; /* do, line 189 */ + { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 189 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + lab7: + z->c = c9; + } + { int c10 = z->c; /* do, line 190 */ + if (!(z->I[0] > 2)) goto lab8; /* $( > ), line 190 */ + z->lb = z->c; z->c = z->l; /* backwards, line 190 */ + + { int ret = r_remove_suffix(z); /* call remove_suffix, line 190 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; + } + z->c = z->lb; + lab8: + z->c = c10; + } + } +lab4: + return 1; +} + +extern struct SN_env * indonesian_ISO_8859_1_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void indonesian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c new file mode 100644 index 00000000000..8ef9a90d501 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_irish.c @@ -0,0 +1,490 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int irish_ISO_8859_1_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_verb_sfx(struct SN_env * z); +static int r_deriv(struct SN_env * z); +static int r_noun_sfx(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_initial_morph(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * irish_ISO_8859_1_create_env(void); +extern void irish_ISO_8859_1_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[2] = { 'b', '\'' }; +static const symbol s_0_1[2] = { 'b', 'h' }; +static const symbol s_0_2[3] = { 'b', 'h', 'f' }; +static const symbol s_0_3[2] = { 'b', 'p' }; +static const symbol s_0_4[2] = { 'c', 'h' }; +static const symbol s_0_5[2] = { 'd', '\'' }; +static const symbol s_0_6[4] = { 'd', '\'', 'f', 'h' }; +static const symbol s_0_7[2] = { 'd', 'h' }; +static const symbol s_0_8[2] = { 'd', 't' }; +static const symbol s_0_9[2] = { 'f', 'h' }; +static const symbol s_0_10[2] = { 'g', 'c' }; +static const symbol s_0_11[2] = { 'g', 'h' }; +static const symbol s_0_12[2] = { 'h', '-' }; +static const symbol s_0_13[2] = { 'm', '\'' }; +static const symbol s_0_14[2] = { 'm', 'b' }; +static const symbol s_0_15[2] = { 'm', 'h' }; +static const symbol s_0_16[2] = { 'n', '-' }; +static const symbol s_0_17[2] = { 'n', 'd' }; +static const symbol s_0_18[2] = { 'n', 'g' }; +static const symbol s_0_19[2] = { 'p', 'h' }; +static const symbol s_0_20[2] = { 's', 'h' }; +static const symbol s_0_21[2] = { 't', '-' }; +static const symbol s_0_22[2] = { 't', 'h' }; +static const symbol s_0_23[2] = { 't', 's' }; + +static const struct among a_0[24] = +{ +/* 0 */ { 2, s_0_0, -1, 1, 0}, +/* 1 */ { 2, s_0_1, -1, 4, 0}, +/* 2 */ { 3, s_0_2, 1, 2, 0}, +/* 3 */ { 2, s_0_3, -1, 8, 0}, +/* 4 */ { 2, s_0_4, -1, 5, 0}, +/* 5 */ { 2, s_0_5, -1, 1, 0}, +/* 6 */ { 4, s_0_6, 5, 2, 0}, +/* 7 */ { 2, s_0_7, -1, 6, 0}, +/* 8 */ { 2, s_0_8, -1, 9, 0}, +/* 9 */ { 2, s_0_9, -1, 2, 0}, +/* 10 */ { 2, s_0_10, -1, 5, 0}, +/* 11 */ { 2, s_0_11, -1, 7, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 2, s_0_13, -1, 1, 0}, +/* 14 */ { 2, s_0_14, -1, 4, 0}, +/* 15 */ { 2, s_0_15, -1, 10, 0}, +/* 16 */ { 2, s_0_16, -1, 1, 0}, +/* 17 */ { 2, s_0_17, -1, 6, 0}, +/* 18 */ { 2, s_0_18, -1, 7, 0}, +/* 19 */ { 2, s_0_19, -1, 8, 0}, +/* 20 */ { 2, s_0_20, -1, 3, 0}, +/* 21 */ { 2, s_0_21, -1, 1, 0}, +/* 22 */ { 2, s_0_22, -1, 9, 0}, +/* 23 */ { 2, s_0_23, -1, 3, 0} +}; + +static const symbol s_1_0[6] = { 0xED, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_1_1[7] = { 'a', 0xED, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_1_2[3] = { 'i', 'r', 'e' }; +static const symbol s_1_3[4] = { 'a', 'i', 'r', 'e' }; +static const symbol s_1_4[3] = { 'a', 'b', 'h' }; +static const symbol s_1_5[4] = { 'e', 'a', 'b', 'h' }; +static const symbol s_1_6[3] = { 'i', 'b', 'h' }; +static const symbol s_1_7[4] = { 'a', 'i', 'b', 'h' }; +static const symbol s_1_8[3] = { 'a', 'm', 'h' }; +static const symbol s_1_9[4] = { 'e', 'a', 'm', 'h' }; +static const symbol s_1_10[3] = { 'i', 'm', 'h' }; +static const symbol s_1_11[4] = { 'a', 'i', 'm', 'h' }; +static const symbol s_1_12[5] = { 0xED, 'o', 'c', 'h', 't' }; +static const symbol s_1_13[6] = { 'a', 0xED, 'o', 'c', 'h', 't' }; +static const symbol s_1_14[3] = { 'i', 'r', 0xED }; +static const symbol s_1_15[4] = { 'a', 'i', 'r', 0xED }; + +static const struct among a_1[16] = +{ +/* 0 */ { 6, s_1_0, -1, 1, 0}, +/* 1 */ { 7, s_1_1, 0, 1, 0}, +/* 2 */ { 3, s_1_2, -1, 2, 0}, +/* 3 */ { 4, s_1_3, 2, 2, 0}, +/* 4 */ { 3, s_1_4, -1, 1, 0}, +/* 5 */ { 4, s_1_5, 4, 1, 0}, +/* 6 */ { 3, s_1_6, -1, 1, 0}, +/* 7 */ { 4, s_1_7, 6, 1, 0}, +/* 8 */ { 3, s_1_8, -1, 1, 0}, +/* 9 */ { 4, s_1_9, 8, 1, 0}, +/* 10 */ { 3, s_1_10, -1, 1, 0}, +/* 11 */ { 4, s_1_11, 10, 1, 0}, +/* 12 */ { 5, s_1_12, -1, 1, 0}, +/* 13 */ { 6, s_1_13, 12, 1, 0}, +/* 14 */ { 3, s_1_14, -1, 2, 0}, +/* 15 */ { 4, s_1_15, 14, 2, 0} +}; + +static const symbol s_2_0[8] = { 0xF3, 'i', 'd', 'e', 'a', 'c', 'h', 'a' }; +static const symbol s_2_1[7] = { 'p', 'a', 't', 'a', 'c', 'h', 'a' }; +static const symbol s_2_2[5] = { 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_3[8] = { 'a', 'r', 'c', 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_4[6] = { 'e', 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_5[11] = { 'g', 'r', 'a', 'f', 'a', 0xED, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_2_6[5] = { 'p', 'a', 'i', 't', 'e' }; +static const symbol s_2_7[3] = { 'a', 'c', 'h' }; +static const symbol s_2_8[4] = { 'e', 'a', 'c', 'h' }; +static const symbol s_2_9[7] = { 0xF3, 'i', 'd', 'e', 'a', 'c', 'h' }; +static const symbol s_2_10[7] = { 'g', 'i', 'n', 'e', 'a', 'c', 'h' }; +static const symbol s_2_11[6] = { 'p', 'a', 't', 'a', 'c', 'h' }; +static const symbol s_2_12[9] = { 'g', 'r', 'a', 'f', 'a', 0xED, 'o', 'c', 'h' }; +static const symbol s_2_13[7] = { 'p', 'a', 't', 'a', 'i', 'g', 'h' }; +static const symbol s_2_14[6] = { 0xF3, 'i', 'd', 'i', 'g', 'h' }; +static const symbol s_2_15[7] = { 'a', 'c', 'h', 't', 0xFA, 'i', 'l' }; +static const symbol s_2_16[8] = { 'e', 'a', 'c', 'h', 't', 0xFA, 'i', 'l' }; +static const symbol s_2_17[6] = { 'g', 'i', 'n', 'e', 'a', 's' }; +static const symbol s_2_18[5] = { 'g', 'i', 'n', 'i', 's' }; +static const symbol s_2_19[4] = { 'a', 'c', 'h', 't' }; +static const symbol s_2_20[7] = { 'a', 'r', 'c', 'a', 'c', 'h', 't' }; +static const symbol s_2_21[5] = { 'e', 'a', 'c', 'h', 't' }; +static const symbol s_2_22[10] = { 'g', 'r', 'a', 'f', 'a', 0xED, 'o', 'c', 'h', 't' }; +static const symbol s_2_23[9] = { 'a', 'r', 'c', 'a', 'c', 'h', 't', 'a', 0xED }; +static const symbol s_2_24[12] = { 'g', 'r', 'a', 'f', 'a', 0xED, 'o', 'c', 'h', 't', 'a', 0xED }; + +static const struct among a_2[25] = +{ +/* 0 */ { 8, s_2_0, -1, 6, 0}, +/* 1 */ { 7, s_2_1, -1, 5, 0}, +/* 2 */ { 5, s_2_2, -1, 1, 0}, +/* 3 */ { 8, s_2_3, 2, 2, 0}, +/* 4 */ { 6, s_2_4, 2, 1, 0}, +/* 5 */ { 11, s_2_5, -1, 4, 0}, +/* 6 */ { 5, s_2_6, -1, 5, 0}, +/* 7 */ { 3, s_2_7, -1, 1, 0}, +/* 8 */ { 4, s_2_8, 7, 1, 0}, +/* 9 */ { 7, s_2_9, 8, 6, 0}, +/* 10 */ { 7, s_2_10, 8, 3, 0}, +/* 11 */ { 6, s_2_11, 7, 5, 0}, +/* 12 */ { 9, s_2_12, -1, 4, 0}, +/* 13 */ { 7, s_2_13, -1, 5, 0}, +/* 14 */ { 6, s_2_14, -1, 6, 0}, +/* 15 */ { 7, s_2_15, -1, 1, 0}, +/* 16 */ { 8, s_2_16, 15, 1, 0}, +/* 17 */ { 6, s_2_17, -1, 3, 0}, +/* 18 */ { 5, s_2_18, -1, 3, 0}, +/* 19 */ { 4, s_2_19, -1, 1, 0}, +/* 20 */ { 7, s_2_20, 19, 2, 0}, +/* 21 */ { 5, s_2_21, 19, 1, 0}, +/* 22 */ { 10, s_2_22, -1, 4, 0}, +/* 23 */ { 9, s_2_23, -1, 2, 0}, +/* 24 */ { 12, s_2_24, -1, 4, 0} +}; + +static const symbol s_3_0[4] = { 'i', 'm', 'i', 'd' }; +static const symbol s_3_1[5] = { 'a', 'i', 'm', 'i', 'd' }; +static const symbol s_3_2[4] = { 0xED, 'm', 'i', 'd' }; +static const symbol s_3_3[5] = { 'a', 0xED, 'm', 'i', 'd' }; +static const symbol s_3_4[3] = { 'a', 'd', 'h' }; +static const symbol s_3_5[4] = { 'e', 'a', 'd', 'h' }; +static const symbol s_3_6[5] = { 'f', 'a', 'i', 'd', 'h' }; +static const symbol s_3_7[4] = { 'f', 'i', 'd', 'h' }; +static const symbol s_3_8[3] = { 0xE1, 'i', 'l' }; +static const symbol s_3_9[3] = { 'a', 'i', 'n' }; +static const symbol s_3_10[4] = { 't', 'e', 'a', 'r' }; +static const symbol s_3_11[3] = { 't', 'a', 'r' }; + +static const struct among a_3[12] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 5, s_3_1, 0, 1, 0}, +/* 2 */ { 4, s_3_2, -1, 1, 0}, +/* 3 */ { 5, s_3_3, 2, 1, 0}, +/* 4 */ { 3, s_3_4, -1, 2, 0}, +/* 5 */ { 4, s_3_5, 4, 2, 0}, +/* 6 */ { 5, s_3_6, -1, 1, 0}, +/* 7 */ { 4, s_3_7, -1, 1, 0}, +/* 8 */ { 3, s_3_8, -1, 2, 0}, +/* 9 */ { 3, s_3_9, -1, 2, 0}, +/* 10 */ { 4, s_3_10, -1, 2, 0}, +/* 11 */ { 3, s_3_11, -1, 2, 0} +}; + +static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 2 }; + +static const symbol s_0[] = { 'f' }; +static const symbol s_1[] = { 's' }; +static const symbol s_2[] = { 'b' }; +static const symbol s_3[] = { 'c' }; +static const symbol s_4[] = { 'd' }; +static const symbol s_5[] = { 'g' }; +static const symbol s_6[] = { 'p' }; +static const symbol s_7[] = { 't' }; +static const symbol s_8[] = { 'm' }; +static const symbol s_9[] = { 'a', 'r', 'c' }; +static const symbol s_10[] = { 'g', 'i', 'n' }; +static const symbol s_11[] = { 'g', 'r', 'a', 'f' }; +static const symbol s_12[] = { 'p', 'a', 'i', 't', 'e' }; +static const symbol s_13[] = { 0xF3, 'i', 'd' }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 30 */ + z->I[1] = z->l; /* $p1 = , line 31 */ + z->I[2] = z->l; /* $p2 = , line 32 */ + { int c1 = z->c; /* do, line 34 */ + { /* gopast */ /* grouping v, line 35 */ + int ret = out_grouping(z, g_v, 97, 250, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[0] = z->c; /* setmark pV, line 35 */ + lab0: + z->c = c1; + } + { int c2 = z->c; /* do, line 37 */ + { /* gopast */ /* grouping v, line 38 */ + int ret = out_grouping(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + { /* gopast */ /* non v, line 38 */ + int ret = in_grouping(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[1] = z->c; /* setmark p1, line 38 */ + { /* gopast */ /* grouping v, line 39 */ + int ret = out_grouping(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + { /* gopast */ /* non v, line 39 */ + int ret = in_grouping(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[2] = z->c; /* setmark p2, line 39 */ + lab1: + z->c = c2; + } + return 1; +} + +static int r_initial_morph(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 44 */ + among_var = find_among(z, a_0, 24); /* substring, line 44 */ + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 44 */ + switch (among_var) { /* among, line 44 */ + case 1: + { int ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 1, s_0); /* <-, line 52 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 1, s_1); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 1, s_2); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 1, s_4); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 1, s_5); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 1, s_6); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 1, s_7); /* <-, line 75 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 89 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 99 */ + return 1; +} + +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 100 */ + return 1; +} + +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 101 */ + return 1; +} + +static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 104 */ + among_var = find_among_b(z, a_1, 16); /* substring, line 104 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 104 */ + switch (among_var) { /* among, line 104 */ + case 1: + { int ret = r_R1(z); /* call R1, line 108 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); /* call R2, line 110 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_deriv(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 114 */ + among_var = find_among_b(z, a_2, 25); /* substring, line 114 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 114 */ + switch (among_var) { /* among, line 114 */ + case 1: + { int ret = r_R2(z); /* call R2, line 116 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 116 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 3, s_9); /* <-, line 118 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 3, s_10); /* <-, line 120 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 4, s_11); /* <-, line 122 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 5, s_12); /* <-, line 124 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 3, s_13); /* <-, line 126 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 130 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 130 */ + among_var = find_among_b(z, a_3, 12); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 130 */ + switch (among_var) { /* among, line 130 */ + case 1: + { int ret = r_RV(z); /* call RV, line 133 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R1(z); /* call R1, line 138 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int irish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 144 */ + { int ret = r_initial_morph(z); /* call initial_morph, line 144 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + /* do, line 145 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 145 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } +lab1: + z->lb = z->c; z->c = z->l; /* backwards, line 146 */ + + { int m2 = z->l - z->c; (void)m2; /* do, line 147 */ + { int ret = r_noun_sfx(z); /* call noun_sfx, line 147 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; /* do, line 148 */ + { int ret = r_deriv(z); /* call deriv, line 148 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m3; + } + { int m4 = z->l - z->c; (void)m4; /* do, line 149 */ + { int ret = r_verb_sfx(z); /* call verb_sfx, line 149 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m4; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * irish_ISO_8859_1_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void irish_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c index d941b0f0363..fca2e3af1c3 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_italian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -476,34 +476,29 @@ static const symbol s_2[] = { 0xEC }; static const symbol s_3[] = { 0xF2 }; static const symbol s_4[] = { 0xF9 }; static const symbol s_5[] = { 'q', 'U' }; -static const symbol s_6[] = { 'u' }; -static const symbol s_7[] = { 'U' }; +static const symbol s_6[] = { 'U' }; +static const symbol s_7[] = { 'I' }; static const symbol s_8[] = { 'i' }; -static const symbol s_9[] = { 'I' }; -static const symbol s_10[] = { 'i' }; -static const symbol s_11[] = { 'u' }; -static const symbol s_12[] = { 'e' }; -static const symbol s_13[] = { 'i', 'c' }; -static const symbol s_14[] = { 'l', 'o', 'g' }; -static const symbol s_15[] = { 'u' }; -static const symbol s_16[] = { 'e', 'n', 't', 'e' }; -static const symbol s_17[] = { 'a', 't' }; -static const symbol s_18[] = { 'a', 't' }; -static const symbol s_19[] = { 'i', 'c' }; -static const symbol s_20[] = { 'i' }; -static const symbol s_21[] = { 'h' }; +static const symbol s_9[] = { 'u' }; +static const symbol s_10[] = { 'e' }; +static const symbol s_11[] = { 'i', 'c' }; +static const symbol s_12[] = { 'l', 'o', 'g' }; +static const symbol s_13[] = { 'u' }; +static const symbol s_14[] = { 'e', 'n', 't', 'e' }; +static const symbol s_15[] = { 'a', 't' }; +static const symbol s_16[] = { 'a', 't' }; +static const symbol s_17[] = { 'i', 'c' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; - { int c_test = z->c; /* test, line 35 */ + { int c_test1 = z->c; /* test, line 35 */ while(1) { /* repeat, line 35 */ - int c1 = z->c; + int c2 = z->c; z->bra = z->c; /* [, line 36 */ among_var = find_among(z, a_0, 7); /* substring, line 36 */ if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 36 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 36 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 37 */ if (ret < 0) return ret; @@ -541,59 +536,61 @@ static int r_prelude(struct SN_env * z) { } continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } while(1) { /* repeat, line 46 */ - int c2 = z->c; + int c3 = z->c; while(1) { /* goto, line 46 */ - int c3 = z->c; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + int c4 = z->c; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 47 */ z->bra = z->c; /* [, line 47 */ - { int c4 = z->c; /* or, line 47 */ - if (!(eq_s(z, 1, s_6))) goto lab4; + { int c5 = z->c; /* or, line 47 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab4; /* literal, line 47 */ + z->c++; z->ket = z->c; /* ], line 47 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab4; - { int ret = slice_from_s(z, 1, s_7); /* <-, line 47 */ + if (in_grouping(z, g_v, 97, 249, 0)) goto lab4; /* grouping v, line 47 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 47 */ if (ret < 0) return ret; } goto lab3; lab4: - z->c = c4; - if (!(eq_s(z, 1, s_8))) goto lab2; + z->c = c5; + if (z->c == z->l || z->p[z->c] != 'i') goto lab2; /* literal, line 48 */ + z->c++; z->ket = z->c; /* ], line 48 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; - { int ret = slice_from_s(z, 1, s_9); /* <-, line 48 */ + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 48 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 48 */ if (ret < 0) return ret; } } lab3: - z->c = c3; + z->c = c4; break; lab2: - z->c = c3; + z->c = c4; if (z->c >= z->l) goto lab1; z->c++; /* goto, line 46 */ } continue; lab1: - z->c = c2; + z->c = c3; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 54 */ + z->I[1] = z->l; /* $p1 = , line 55 */ + z->I[2] = z->l; /* $p2 = , line 56 */ { int c1 = z->c; /* do, line 58 */ { int c2 = z->c; /* or, line 60 */ - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ { int c3 = z->c; /* or, line 59 */ - if (out_grouping(z, g_v, 97, 249, 0)) goto lab4; + if (out_grouping(z, g_v, 97, 249, 0)) goto lab4; /* non v, line 59 */ { /* gopast */ /* grouping v, line 59 */ int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab4; @@ -602,7 +599,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ { /* gopast */ /* non v, line 59 */ int ret = in_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab2; @@ -613,9 +610,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 249, 0)) goto lab0; + if (out_grouping(z, g_v, 97, 249, 0)) goto lab0; /* non v, line 61 */ { int c4 = z->c; /* or, line 61 */ - if (out_grouping(z, g_v, 97, 249, 0)) goto lab6; + if (out_grouping(z, g_v, 97, 249, 0)) goto lab6; /* non v, line 61 */ { /* gopast */ /* grouping v, line 61 */ int ret = out_grouping(z, g_v, 97, 249, 1); if (ret < 0) goto lab6; @@ -624,7 +621,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 249, 0)) goto lab0; + if (in_grouping(z, g_v, 97, 249, 0)) goto lab0; /* grouping v, line 61 */ if (z->c >= z->l) goto lab0; z->c++; /* next, line 61 */ } @@ -665,24 +662,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 70 */ int c1 = z->c; z->bra = z->c; /* [, line 72 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 72 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 72 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 72 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 72 */ case 1: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 73 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 73 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 74 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 74 */ if (ret < 0) return ret; } break; @@ -699,43 +695,41 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 82 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 83 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 84 */ return 1; } -static int r_attached_pronoun(struct SN_env * z) { +static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 87 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + if (!(find_among_b(z, a_2, 37))) return 0; z->bra = z->c; /* ], line 87 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; - among_var = find_among_b(z, a_3, 5); /* among, line 97 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* among, line 97 */ + among_var = find_among_b(z, a_3, 5); if (!(among_var)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 97 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 97 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 97 */ case 1: { int ret = slice_del(z); /* delete, line 98 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 99 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 99 */ if (ret < 0) return ret; } break; @@ -743,37 +737,34 @@ static int r_attached_pronoun(struct SN_env * z) { return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 104 */ among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 104 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 104 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 111 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 111 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 113 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 113 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 113 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 114 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 114 */ z->ket = z->c; /* [, line 114 */ - if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } /* literal, line 114 */ z->bra = z->c; /* ], line 114 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 114 */ + { int ret = r_R2(z); /* call R2, line 114 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 114 */ @@ -784,70 +775,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 117 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 117 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_14); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_12); /* <-, line 117 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 119 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 119 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_15); /* <-, line 119 */ + { int ret = slice_from_s(z, 1, s_13); /* <-, line 119 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 121 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 121 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_16); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_14); /* <-, line 121 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 123 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 123 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 123 */ if (ret < 0) return ret; } break; case 7: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 125 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 125 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 126 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 126 */ z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_4, 4); /* substring, line 127 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 127 */ + among_var = find_among_b(z, a_4, 4); + if (!(among_var)) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 127 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */ + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 127 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } + switch (among_var) { /* among, line 127 */ case 1: z->ket = z->c; /* [, line 128 */ - if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m_keep; goto lab1; } + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } /* literal, line 128 */ z->bra = z->c; /* ], line 128 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 128 */ + { int ret = r_R2(z); /* call R2, line 128 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 128 */ @@ -860,59 +845,51 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 134 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 134 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_5, 3); /* substring, line 136 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 136 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 137 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 137 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 137 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 137 */ + if (ret < 0) return ret; } lab2: ; } break; case 9: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 142 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 142 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 142 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 143 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 143 */ z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */ + { int ret = r_R2(z); /* call R2, line 143 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 143 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */ + { int ret = r_R2(z); /* call R2, line 143 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 143 */ @@ -926,48 +903,40 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 148 */ - int m1 = z->l - z->c; (void)m1; +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 148 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 148 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 149 */ - among_var = find_among_b(z, a_7, 87); /* substring, line 149 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } /* substring, line 149 */ z->bra = z->c; /* ], line 149 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - { int ret = slice_del(z); /* delete, line 163 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_vowel_suffix(struct SN_env * z) { - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 171 */ +static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* try, line 171 */ z->ket = z->c; /* [, line 172 */ - if (in_grouping_b(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m_keep; goto lab0; } + if (in_grouping_b(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } /* grouping AEIO, line 172 */ z->bra = z->c; /* ], line 172 */ - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 172 */ + { int ret = r_RV(z); /* call RV, line 172 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 172 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 173 */ - if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } /* literal, line 173 */ + z->c--; z->bra = z->c; /* ], line 173 */ - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 173 */ + { int ret = r_RV(z); /* call RV, line 173 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 173 */ @@ -976,13 +945,14 @@ static int r_vowel_suffix(struct SN_env * z) { lab0: ; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 175 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 175 */ z->ket = z->c; /* [, line 176 */ - if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab1; } + if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } /* literal, line 176 */ + z->c--; z->bra = z->c; /* ], line 176 */ - if (in_grouping_b(z, g_CG, 99, 103, 0)) { z->c = z->l - m_keep; goto lab1; } - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call RV, line 176 */ + if (in_grouping_b(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } /* grouping CG, line 176 */ + { int ret = r_RV(z); /* call RV, line 176 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 176 */ @@ -994,67 +964,65 @@ static int r_vowel_suffix(struct SN_env * z) { return 1; } -extern int italian_ISO_8859_1_stem(struct SN_env * z) { +extern int italian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 182 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 182 */ + { int ret = r_prelude(z); /* call prelude, line 182 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 183 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 183 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 183 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 183 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 184 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 185 */ - { int ret = r_attached_pronoun(z); - if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 185 */ + { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 185 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 186 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 186 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab5; /* call standard_suffix, line 186 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 186 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 186 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 186 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: - z->c = z->l - m5; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab3; /* call verb_suffix, line 186 */ + z->c = z->l - m4; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 186 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } } lab4: lab3: - z->c = z->l - m4; + z->c = z->l - m3; } - { int m6 = z->l - z->c; (void)m6; /* do, line 187 */ - { int ret = r_vowel_suffix(z); - if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 187 */ + { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 187 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m6; + z->c = z->l - m5; } z->c = z->lb; - { int c7 = z->c; /* do, line 189 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab7; /* call postlude, line 189 */ + { int c6 = z->c; /* do, line 189 */ + { int ret = r_postlude(z); /* call postlude, line 189 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = c7; + z->c = c6; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c index 2debf1082d8..88eb9290e97 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_norwegian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -129,18 +129,17 @@ static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static const unsigned char g_s_ending[] = { 119, 125, 149, 1 }; -static const symbol s_0[] = { 'k' }; -static const symbol s_1[] = { 'e', 'r' }; +static const symbol s_0[] = { 'e', 'r' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 30 */ - { int ret = z->c + 3; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 28 */ + { int c_test1 = z->c; /* test, line 30 */ + { int ret = z->c + 3; /* hop, line 30 */ if (0 > ret || ret > z->l) return 0; - z->c = ret; /* hop, line 30 */ + z->c = ret; } z->I[1] = z->c; /* setmark x, line 30 */ - z->c = c_test; + z->c = c_test1; } if (out_grouping(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */ { /* gopast */ /* non v, line 31 */ @@ -149,30 +148,27 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 31 */ - /* try, line 32 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + /* try, line 32 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 32 */ + z->I[0] = z->I[1]; /* $p1 = , line 32 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 38 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 38 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 38 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 38 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 29); /* substring, line 38 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 38 */ + among_var = find_among_b(z, a_0, 29); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 38 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 39 */ case 1: { int ret = slice_del(z); /* delete, line 44 */ if (ret < 0) return ret; @@ -180,12 +176,13 @@ static int r_main_suffix(struct SN_env * z) { break; case 2: { int m2 = z->l - z->c; (void)m2; /* or, line 46 */ - if (in_grouping_b(z, g_s_ending, 98, 122, 0)) goto lab1; + if (in_grouping_b(z, g_s_ending, 98, 122, 0)) goto lab1; /* grouping s_ending, line 46 */ goto lab0; lab1: z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_0))) return 0; - if (out_grouping_b(z, g_v, 97, 248, 0)) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; /* literal, line 46 */ + z->c--; + if (out_grouping_b(z, g_v, 97, 248, 0)) return 0; /* non v, line 46 */ } lab0: { int ret = slice_del(z); /* delete, line 46 */ @@ -193,7 +190,7 @@ static int r_main_suffix(struct SN_env * z) { } break; case 3: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 48 */ + { int ret = slice_from_s(z, 2, s_0); /* <-, line 48 */ if (ret < 0) return ret; } break; @@ -201,21 +198,19 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 53 */ - { int mlimit; /* setlimit, line 54 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 53 */ + + { int mlimit2; /* setlimit, line 54 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 54 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit2 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 54 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit; return 0; } /* substring, line 54 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } /* substring, line 54 */ + if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit2; return 0; } z->bra = z->c; /* ], line 54 */ - z->lb = mlimit; + z->lb = mlimit2; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } if (z->c <= z->lb) return 0; z->c--; /* next, line 59 */ @@ -226,36 +221,27 @@ static int r_consonant_pair(struct SN_env * z) { return 1; } -static int r_other_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 63 */ - int m1 = z->l - z->c; (void)m1; +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 63 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 63 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 63 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 11); /* substring, line 63 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 63 */ + if (!(find_among_b(z, a_2, 11))) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 63 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 67 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 67 */ + if (ret < 0) return ret; } return 1; } -extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { +extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 74 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 74 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 74 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -264,24 +250,24 @@ extern int norwegian_ISO_8859_1_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 75 */ { int m2 = z->l - z->c; (void)m2; /* do, line 76 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 76 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 76 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 77 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 77 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 77 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 78 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 78 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 78 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c index 69e4fc4c1f2..cc330e0cd73 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_porter.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -115,21 +115,21 @@ static const struct among a_3[20] = /* 2 */ { 4, s_3_2, -1, 4, 0}, /* 3 */ { 3, s_3_3, -1, 6, 0}, /* 4 */ { 4, s_3_4, -1, 9, 0}, -/* 5 */ { 5, s_3_5, -1, 12, 0}, +/* 5 */ { 5, s_3_5, -1, 11, 0}, /* 6 */ { 5, s_3_6, -1, 5, 0}, -/* 7 */ { 5, s_3_7, -1, 10, 0}, -/* 8 */ { 6, s_3_8, -1, 14, 0}, -/* 9 */ { 5, s_3_9, -1, 13, 0}, +/* 7 */ { 5, s_3_7, -1, 9, 0}, +/* 8 */ { 6, s_3_8, -1, 13, 0}, +/* 9 */ { 5, s_3_9, -1, 12, 0}, /* 10 */ { 6, s_3_10, -1, 1, 0}, /* 11 */ { 7, s_3_11, 10, 8, 0}, -/* 12 */ { 5, s_3_12, -1, 10, 0}, +/* 12 */ { 5, s_3_12, -1, 9, 0}, /* 13 */ { 5, s_3_13, -1, 8, 0}, /* 14 */ { 7, s_3_14, 13, 7, 0}, /* 15 */ { 4, s_3_15, -1, 7, 0}, /* 16 */ { 4, s_3_16, -1, 8, 0}, -/* 17 */ { 7, s_3_17, -1, 13, 0}, -/* 18 */ { 7, s_3_18, -1, 11, 0}, -/* 19 */ { 7, s_3_19, -1, 12, 0} +/* 17 */ { 7, s_3_17, -1, 12, 0}, +/* 18 */ { 7, s_3_18, -1, 10, 0}, +/* 19 */ { 7, s_3_19, -1, 11, 0} }; static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -203,63 +203,51 @@ static const symbol s_1[] = { 'i' }; static const symbol s_2[] = { 'e', 'e' }; static const symbol s_3[] = { 'e' }; static const symbol s_4[] = { 'e' }; -static const symbol s_5[] = { 'y' }; -static const symbol s_6[] = { 'Y' }; -static const symbol s_7[] = { 'i' }; -static const symbol s_8[] = { 't', 'i', 'o', 'n' }; -static const symbol s_9[] = { 'e', 'n', 'c', 'e' }; -static const symbol s_10[] = { 'a', 'n', 'c', 'e' }; -static const symbol s_11[] = { 'a', 'b', 'l', 'e' }; -static const symbol s_12[] = { 'e', 'n', 't' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'i', 'z', 'e' }; -static const symbol s_15[] = { 'a', 't', 'e' }; -static const symbol s_16[] = { 'a', 'l' }; -static const symbol s_17[] = { 'a', 'l' }; -static const symbol s_18[] = { 'f', 'u', 'l' }; -static const symbol s_19[] = { 'o', 'u', 's' }; -static const symbol s_20[] = { 'i', 'v', 'e' }; -static const symbol s_21[] = { 'b', 'l', 'e' }; -static const symbol s_22[] = { 'a', 'l' }; -static const symbol s_23[] = { 'i', 'c' }; -static const symbol s_24[] = { 's' }; -static const symbol s_25[] = { 't' }; -static const symbol s_26[] = { 'e' }; -static const symbol s_27[] = { 'l' }; -static const symbol s_28[] = { 'l' }; -static const symbol s_29[] = { 'y' }; -static const symbol s_30[] = { 'Y' }; -static const symbol s_31[] = { 'y' }; -static const symbol s_32[] = { 'Y' }; -static const symbol s_33[] = { 'Y' }; -static const symbol s_34[] = { 'y' }; - -static int r_shortv(struct SN_env * z) { - if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) return 0; - if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; - if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; +static const symbol s_5[] = { 'i' }; +static const symbol s_6[] = { 't', 'i', 'o', 'n' }; +static const symbol s_7[] = { 'e', 'n', 'c', 'e' }; +static const symbol s_8[] = { 'a', 'n', 'c', 'e' }; +static const symbol s_9[] = { 'a', 'b', 'l', 'e' }; +static const symbol s_10[] = { 'e', 'n', 't' }; +static const symbol s_11[] = { 'e' }; +static const symbol s_12[] = { 'i', 'z', 'e' }; +static const symbol s_13[] = { 'a', 't', 'e' }; +static const symbol s_14[] = { 'a', 'l' }; +static const symbol s_15[] = { 'f', 'u', 'l' }; +static const symbol s_16[] = { 'o', 'u', 's' }; +static const symbol s_17[] = { 'i', 'v', 'e' }; +static const symbol s_18[] = { 'b', 'l', 'e' }; +static const symbol s_19[] = { 'a', 'l' }; +static const symbol s_20[] = { 'i', 'c' }; +static const symbol s_21[] = { 'Y' }; +static const symbol s_22[] = { 'Y' }; +static const symbol s_23[] = { 'y' }; + +static int r_shortv(struct SN_env * z) { /* backwardmode */ + if (out_grouping_b(z, g_v_WXY, 89, 121, 0)) return 0; /* non v_WXY, line 19 */ + if (in_grouping_b(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 19 */ + if (out_grouping_b(z, g_v, 97, 121, 0)) return 0; /* non v, line 19 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 21 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 22 */ return 1; } -static int r_Step_1a(struct SN_env * z) { +static int r_Step_1a(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 25 */ - if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; - among_var = find_among_b(z, a_0, 4); /* substring, line 25 */ + if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; /* substring, line 25 */ + among_var = find_among_b(z, a_0, 4); if (!(among_var)) return 0; z->bra = z->c; /* ], line 25 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 25 */ case 1: { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ if (ret < 0) return ret; @@ -279,48 +267,47 @@ static int r_Step_1a(struct SN_env * z) { return 1; } -static int r_Step_1b(struct SN_env * z) { +static int r_Step_1b(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 34 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; - among_var = find_among_b(z, a_2, 3); /* substring, line 34 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 34 */ + among_var = find_among_b(z, a_2, 3); if (!(among_var)) return 0; z->bra = z->c; /* ], line 34 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 34 */ case 1: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 35 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 35 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ if (ret < 0) return ret; } break; case 2: - { int m_test = z->l - z->c; /* test, line 38 */ + { int m_test1 = z->l - z->c; /* test, line 38 */ { /* gopast */ /* grouping v, line 38 */ int ret = out_grouping_b(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 38 */ if (ret < 0) return ret; } - { int m_test = z->l - z->c; /* test, line 39 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else - among_var = find_among_b(z, a_1, 13); /* substring, line 39 */ + { int m_test2 = z->l - z->c; /* test, line 39 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 39 */ + among_var = find_among_b(z, a_1, 13); if (!(among_var)) return 0; - z->c = z->l - m_test; + z->c = z->l - m_test2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 39 */ case 1: - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -335,16 +322,17 @@ static int r_Step_1b(struct SN_env * z) { break; case 3: if (z->c != z->I[0]) return 0; /* atmark, line 45 */ - { int m_test = z->l - z->c; /* test, line 45 */ - { int ret = r_shortv(z); - if (ret == 0) return 0; /* call shortv, line 45 */ - if (ret < 0) return ret; + { int m_test3 = z->l - z->c; /* test, line 45 */ + { int ret = r_shortv(z); /* call shortv, line 45 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test3; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -354,14 +342,16 @@ static int r_Step_1b(struct SN_env * z) { return 1; } -static int r_Step_1c(struct SN_env * z) { +static int r_Step_1c(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 52 */ { int m1 = z->l - z->c; (void)m1; /* or, line 52 */ - if (!(eq_s_b(z, 1, s_5))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 52 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_6))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 52 */ + z->c--; } lab0: z->bra = z->c; /* ], line 52 */ @@ -370,92 +360,85 @@ static int r_Step_1c(struct SN_env * z) { if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_from_s(z, 1, s_7); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 54 */ if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { +static int r_Step_2(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 58 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_3, 20); /* substring, line 58 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 58 */ + among_var = find_among_b(z, a_3, 20); if (!(among_var)) return 0; z->bra = z->c; /* ], line 58 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 58 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 58 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 58 */ case 1: - { int ret = slice_from_s(z, 4, s_8); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_6); /* <-, line 59 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 60 */ + { int ret = slice_from_s(z, 4, s_7); /* <-, line 60 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_10); /* <-, line 61 */ + { int ret = slice_from_s(z, 4, s_8); /* <-, line 61 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 62 */ + { int ret = slice_from_s(z, 4, s_9); /* <-, line 62 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_12); /* <-, line 63 */ + { int ret = slice_from_s(z, 3, s_10); /* <-, line 63 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_11); /* <-, line 64 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_14); /* <-, line 66 */ + { int ret = slice_from_s(z, 3, s_12); /* <-, line 66 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 68 */ + { int ret = slice_from_s(z, 3, s_13); /* <-, line 68 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 69 */ + { int ret = slice_from_s(z, 2, s_14); /* <-, line 69 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 71 */ + { int ret = slice_from_s(z, 3, s_15); /* <-, line 72 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 72 */ + { int ret = slice_from_s(z, 3, s_16); /* <-, line 74 */ if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 74 */ + { int ret = slice_from_s(z, 3, s_17); /* <-, line 76 */ if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 76 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_from_s(z, 3, s_21); /* <-, line 77 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 77 */ if (ret < 0) return ret; } break; @@ -463,26 +446,24 @@ static int r_Step_2(struct SN_env * z) { return 1; } -static int r_Step_3(struct SN_env * z) { +static int r_Step_3(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 82 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_4, 7); /* substring, line 82 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 82 */ + among_var = find_among_b(z, a_4, 7); if (!(among_var)) return 0; z->bra = z->c; /* ], line 82 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 82 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 82 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 82 */ case 1: - { int ret = slice_from_s(z, 2, s_22); /* <-, line 83 */ + { int ret = slice_from_s(z, 2, s_19); /* <-, line 83 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_23); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_20); /* <-, line 85 */ if (ret < 0) return ret; } break; @@ -495,19 +476,17 @@ static int r_Step_3(struct SN_env * z) { return 1; } -static int r_Step_4(struct SN_env * z) { +static int r_Step_4(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 92 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 19); /* substring, line 92 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 92 */ + among_var = find_among_b(z, a_5, 19); if (!(among_var)) return 0; z->bra = z->c; /* ], line 92 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 92 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 92 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 92 */ case 1: { int ret = slice_del(z); /* delete, line 95 */ if (ret < 0) return ret; @@ -515,11 +494,13 @@ static int r_Step_4(struct SN_env * z) { break; case 2: { int m1 = z->l - z->c; (void)m1; /* or, line 96 */ - if (!(eq_s_b(z, 1, s_24))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 96 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_25))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 96 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 96 */ @@ -530,25 +511,25 @@ static int r_Step_4(struct SN_env * z) { return 1; } -static int r_Step_5a(struct SN_env * z) { +static int r_Step_5a(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 101 */ - if (!(eq_s_b(z, 1, s_26))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 101 */ + z->c--; z->bra = z->c; /* ], line 101 */ { int m1 = z->l - z->c; (void)m1; /* or, line 102 */ - { int ret = r_R2(z); - if (ret == 0) goto lab1; /* call R2, line 102 */ + { int ret = r_R2(z); /* call R2, line 102 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 102 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 102 */ + if (ret <= 0) return ret; } { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - { int ret = r_shortv(z); - if (ret == 0) goto lab2; /* call shortv, line 102 */ + { int ret = r_shortv(z); /* call shortv, line 102 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } return 0; @@ -563,28 +544,30 @@ static int r_Step_5a(struct SN_env * z) { return 1; } -static int r_Step_5b(struct SN_env * z) { +static int r_Step_5b(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 1, s_27))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 107 */ + z->c--; z->bra = z->c; /* ], line 107 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 108 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 108 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_28))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 108 */ + z->c--; { int ret = slice_del(z); /* delete, line 109 */ if (ret < 0) return ret; } return 1; } -extern int porter_ISO_8859_1_stem(struct SN_env * z) { +extern int porter_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ z->B[0] = 0; /* unset Y_found, line 115 */ { int c1 = z->c; /* do, line 116 */ z->bra = z->c; /* [, line 116 */ - if (!(eq_s(z, 1, s_29))) goto lab0; + if (z->c == z->l || z->p[z->c] != 'y') goto lab0; /* literal, line 116 */ + z->c++; z->ket = z->c; /* ], line 116 */ - { int ret = slice_from_s(z, 1, s_30); /* <-, line 116 */ + { int ret = slice_from_s(z, 1, s_21); /* <-, line 116 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 116 */ @@ -596,9 +579,10 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { int c3 = z->c; while(1) { /* goto, line 117 */ int c4 = z->c; - if (in_grouping(z, g_v, 97, 121, 0)) goto lab3; + if (in_grouping(z, g_v, 97, 121, 0)) goto lab3; /* grouping v, line 117 */ z->bra = z->c; /* [, line 117 */ - if (!(eq_s(z, 1, s_31))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 117 */ + z->c++; z->ket = z->c; /* ], line 117 */ z->c = c4; break; @@ -607,7 +591,7 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { if (z->c >= z->l) goto lab2; z->c++; /* goto, line 117 */ } - { int ret = slice_from_s(z, 1, s_32); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_22); /* <-, line 117 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 117 */ @@ -618,8 +602,8 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { } z->c = c2; } - z->I[0] = z->l; - z->I[1] = z->l; + z->I[0] = z->l; /* $p1 = , line 119 */ + z->I[1] = z->l; /* $p2 = , line 120 */ { int c5 = z->c; /* do, line 121 */ { /* gopast */ /* grouping v, line 122 */ int ret = out_grouping(z, g_v, 97, 121, 1); @@ -649,64 +633,64 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 126 */ { int m6 = z->l - z->c; (void)m6; /* do, line 127 */ - { int ret = r_Step_1a(z); - if (ret == 0) goto lab5; /* call Step_1a, line 127 */ + { int ret = r_Step_1a(z); /* call Step_1a, line 127 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } lab5: z->c = z->l - m6; } { int m7 = z->l - z->c; (void)m7; /* do, line 128 */ - { int ret = r_Step_1b(z); - if (ret == 0) goto lab6; /* call Step_1b, line 128 */ + { int ret = r_Step_1b(z); /* call Step_1b, line 128 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: z->c = z->l - m7; } { int m8 = z->l - z->c; (void)m8; /* do, line 129 */ - { int ret = r_Step_1c(z); - if (ret == 0) goto lab7; /* call Step_1c, line 129 */ + { int ret = r_Step_1c(z); /* call Step_1c, line 129 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: z->c = z->l - m8; } { int m9 = z->l - z->c; (void)m9; /* do, line 130 */ - { int ret = r_Step_2(z); - if (ret == 0) goto lab8; /* call Step_2, line 130 */ + { int ret = r_Step_2(z); /* call Step_2, line 130 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: z->c = z->l - m9; } { int m10 = z->l - z->c; (void)m10; /* do, line 131 */ - { int ret = r_Step_3(z); - if (ret == 0) goto lab9; /* call Step_3, line 131 */ + { int ret = r_Step_3(z); /* call Step_3, line 131 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: z->c = z->l - m10; } { int m11 = z->l - z->c; (void)m11; /* do, line 132 */ - { int ret = r_Step_4(z); - if (ret == 0) goto lab10; /* call Step_4, line 132 */ + { int ret = r_Step_4(z); /* call Step_4, line 132 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } lab10: z->c = z->l - m11; } { int m12 = z->l - z->c; (void)m12; /* do, line 133 */ - { int ret = r_Step_5a(z); - if (ret == 0) goto lab11; /* call Step_5a, line 133 */ + { int ret = r_Step_5a(z); /* call Step_5a, line 133 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: z->c = z->l - m12; } { int m13 = z->l - z->c; (void)m13; /* do, line 134 */ - { int ret = r_Step_5b(z); - if (ret == 0) goto lab12; /* call Step_5b, line 134 */ + { int ret = r_Step_5b(z); /* call Step_5b, line 134 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: @@ -720,7 +704,8 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { while(1) { /* goto, line 137 */ int c16 = z->c; z->bra = z->c; /* [, line 137 */ - if (!(eq_s(z, 1, s_33))) goto lab15; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab15; /* literal, line 137 */ + z->c++; z->ket = z->c; /* ], line 137 */ z->c = c16; break; @@ -729,7 +714,7 @@ extern int porter_ISO_8859_1_stem(struct SN_env * z) { if (z->c >= z->l) goto lab14; z->c++; /* goto, line 137 */ } - { int ret = slice_from_s(z, 1, s_34); /* <-, line 137 */ + { int ret = slice_from_s(z, 1, s_23); /* <-, line 137 */ if (ret < 0) return ret; } continue; diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c index 06d425d008f..674d9c2657a 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_portuguese.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -90,42 +90,42 @@ static const struct among a_4[3] = static const symbol s_5_0[3] = { 'i', 'c', 'a' }; static const symbol s_5_1[5] = { 0xE2, 'n', 'c', 'i', 'a' }; static const symbol s_5_2[5] = { 0xEA, 'n', 'c', 'i', 'a' }; -static const symbol s_5_3[3] = { 'i', 'r', 'a' }; -static const symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' }; -static const symbol s_5_5[3] = { 'o', 's', 'a' }; -static const symbol s_5_6[4] = { 'i', 's', 't', 'a' }; -static const symbol s_5_7[3] = { 'i', 'v', 'a' }; -static const symbol s_5_8[3] = { 'e', 'z', 'a' }; -static const symbol s_5_9[5] = { 'l', 'o', 'g', 0xED, 'a' }; +static const symbol s_5_3[5] = { 'l', 'o', 'g', 'i', 'a' }; +static const symbol s_5_4[3] = { 'i', 'r', 'a' }; +static const symbol s_5_5[5] = { 'a', 'd', 'o', 'r', 'a' }; +static const symbol s_5_6[3] = { 'o', 's', 'a' }; +static const symbol s_5_7[4] = { 'i', 's', 't', 'a' }; +static const symbol s_5_8[3] = { 'i', 'v', 'a' }; +static const symbol s_5_9[3] = { 'e', 'z', 'a' }; static const symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' }; static const symbol s_5_11[4] = { 'a', 'n', 't', 'e' }; static const symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' }; static const symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; static const symbol s_5_14[4] = { 0xE1, 'v', 'e', 'l' }; static const symbol s_5_15[4] = { 0xED, 'v', 'e', 'l' }; -static const symbol s_5_16[5] = { 'u', 'c', 'i', 0xF3, 'n' }; -static const symbol s_5_17[3] = { 'i', 'c', 'o' }; -static const symbol s_5_18[4] = { 'i', 's', 'm', 'o' }; -static const symbol s_5_19[3] = { 'o', 's', 'o' }; -static const symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; -static const symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; -static const symbol s_5_22[3] = { 'i', 'v', 'o' }; -static const symbol s_5_23[5] = { 'a', 0xE7, 'a', '~', 'o' }; +static const symbol s_5_16[3] = { 'i', 'c', 'o' }; +static const symbol s_5_17[4] = { 'i', 's', 'm', 'o' }; +static const symbol s_5_18[3] = { 'o', 's', 'o' }; +static const symbol s_5_19[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static const symbol s_5_20[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static const symbol s_5_21[3] = { 'i', 'v', 'o' }; +static const symbol s_5_22[5] = { 'a', 0xE7, 'a', '~', 'o' }; +static const symbol s_5_23[5] = { 'u', 0xE7, 'a', '~', 'o' }; static const symbol s_5_24[4] = { 'a', 'd', 'o', 'r' }; static const symbol s_5_25[4] = { 'i', 'c', 'a', 's' }; static const symbol s_5_26[6] = { 0xEA, 'n', 'c', 'i', 'a', 's' }; -static const symbol s_5_27[4] = { 'i', 'r', 'a', 's' }; -static const symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; -static const symbol s_5_29[4] = { 'o', 's', 'a', 's' }; -static const symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' }; -static const symbol s_5_31[4] = { 'i', 'v', 'a', 's' }; -static const symbol s_5_32[4] = { 'e', 'z', 'a', 's' }; -static const symbol s_5_33[6] = { 'l', 'o', 'g', 0xED, 'a', 's' }; +static const symbol s_5_27[6] = { 'l', 'o', 'g', 'i', 'a', 's' }; +static const symbol s_5_28[4] = { 'i', 'r', 'a', 's' }; +static const symbol s_5_29[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static const symbol s_5_30[4] = { 'o', 's', 'a', 's' }; +static const symbol s_5_31[5] = { 'i', 's', 't', 'a', 's' }; +static const symbol s_5_32[4] = { 'i', 'v', 'a', 's' }; +static const symbol s_5_33[4] = { 'e', 'z', 'a', 's' }; static const symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; -static const symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; -static const symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; -static const symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' }; -static const symbol s_5_38[6] = { 'a', 0xE7, 'o', '~', 'e', 's' }; +static const symbol s_5_35[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static const symbol s_5_36[5] = { 'a', 'n', 't', 'e', 's' }; +static const symbol s_5_37[6] = { 'a', 0xE7, 'o', '~', 'e', 's' }; +static const symbol s_5_38[6] = { 'u', 0xE7, 'o', '~', 'e', 's' }; static const symbol s_5_39[4] = { 'i', 'c', 'o', 's' }; static const symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' }; static const symbol s_5_41[4] = { 'o', 's', 'o', 's' }; @@ -138,42 +138,42 @@ static const struct among a_5[45] = /* 0 */ { 3, s_5_0, -1, 1, 0}, /* 1 */ { 5, s_5_1, -1, 1, 0}, /* 2 */ { 5, s_5_2, -1, 4, 0}, -/* 3 */ { 3, s_5_3, -1, 9, 0}, -/* 4 */ { 5, s_5_4, -1, 1, 0}, -/* 5 */ { 3, s_5_5, -1, 1, 0}, -/* 6 */ { 4, s_5_6, -1, 1, 0}, -/* 7 */ { 3, s_5_7, -1, 8, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 5, s_5_9, -1, 2, 0}, +/* 3 */ { 5, s_5_3, -1, 2, 0}, +/* 4 */ { 3, s_5_4, -1, 9, 0}, +/* 5 */ { 5, s_5_5, -1, 1, 0}, +/* 6 */ { 3, s_5_6, -1, 1, 0}, +/* 7 */ { 4, s_5_7, -1, 1, 0}, +/* 8 */ { 3, s_5_8, -1, 8, 0}, +/* 9 */ { 3, s_5_9, -1, 1, 0}, /* 10 */ { 5, s_5_10, -1, 7, 0}, /* 11 */ { 4, s_5_11, -1, 1, 0}, /* 12 */ { 5, s_5_12, -1, 6, 0}, /* 13 */ { 6, s_5_13, 12, 5, 0}, /* 14 */ { 4, s_5_14, -1, 1, 0}, /* 15 */ { 4, s_5_15, -1, 1, 0}, -/* 16 */ { 5, s_5_16, -1, 3, 0}, -/* 17 */ { 3, s_5_17, -1, 1, 0}, -/* 18 */ { 4, s_5_18, -1, 1, 0}, -/* 19 */ { 3, s_5_19, -1, 1, 0}, +/* 16 */ { 3, s_5_16, -1, 1, 0}, +/* 17 */ { 4, s_5_17, -1, 1, 0}, +/* 18 */ { 3, s_5_18, -1, 1, 0}, +/* 19 */ { 6, s_5_19, -1, 1, 0}, /* 20 */ { 6, s_5_20, -1, 1, 0}, -/* 21 */ { 6, s_5_21, -1, 1, 0}, -/* 22 */ { 3, s_5_22, -1, 8, 0}, -/* 23 */ { 5, s_5_23, -1, 1, 0}, +/* 21 */ { 3, s_5_21, -1, 8, 0}, +/* 22 */ { 5, s_5_22, -1, 1, 0}, +/* 23 */ { 5, s_5_23, -1, 3, 0}, /* 24 */ { 4, s_5_24, -1, 1, 0}, /* 25 */ { 4, s_5_25, -1, 1, 0}, /* 26 */ { 6, s_5_26, -1, 4, 0}, -/* 27 */ { 4, s_5_27, -1, 9, 0}, -/* 28 */ { 6, s_5_28, -1, 1, 0}, -/* 29 */ { 4, s_5_29, -1, 1, 0}, -/* 30 */ { 5, s_5_30, -1, 1, 0}, -/* 31 */ { 4, s_5_31, -1, 8, 0}, -/* 32 */ { 4, s_5_32, -1, 1, 0}, -/* 33 */ { 6, s_5_33, -1, 2, 0}, +/* 27 */ { 6, s_5_27, -1, 2, 0}, +/* 28 */ { 4, s_5_28, -1, 9, 0}, +/* 29 */ { 6, s_5_29, -1, 1, 0}, +/* 30 */ { 4, s_5_30, -1, 1, 0}, +/* 31 */ { 5, s_5_31, -1, 1, 0}, +/* 32 */ { 4, s_5_32, -1, 8, 0}, +/* 33 */ { 4, s_5_33, -1, 1, 0}, /* 34 */ { 6, s_5_34, -1, 7, 0}, -/* 35 */ { 7, s_5_35, -1, 3, 0}, -/* 36 */ { 6, s_5_36, -1, 1, 0}, -/* 37 */ { 5, s_5_37, -1, 1, 0}, -/* 38 */ { 6, s_5_38, -1, 1, 0}, +/* 35 */ { 6, s_5_35, -1, 1, 0}, +/* 36 */ { 5, s_5_36, -1, 1, 0}, +/* 37 */ { 6, s_5_37, -1, 1, 0}, +/* 38 */ { 6, s_5_38, -1, 3, 0}, /* 39 */ { 4, s_5_39, -1, 1, 0}, /* 40 */ { 5, s_5_40, -1, 1, 0}, /* 41 */ { 4, s_5_41, -1, 1, 0}, @@ -470,27 +470,19 @@ static const symbol s_5[] = { 'u' }; static const symbol s_6[] = { 'e', 'n', 't', 'e' }; static const symbol s_7[] = { 'a', 't' }; static const symbol s_8[] = { 'a', 't' }; -static const symbol s_9[] = { 'e' }; -static const symbol s_10[] = { 'i', 'r' }; -static const symbol s_11[] = { 'u' }; -static const symbol s_12[] = { 'g' }; -static const symbol s_13[] = { 'i' }; -static const symbol s_14[] = { 'c' }; -static const symbol s_15[] = { 'c' }; -static const symbol s_16[] = { 'i' }; -static const symbol s_17[] = { 'c' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_9[] = { 'i', 'r' }; +static const symbol s_10[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 36 */ int c1 = z->c; z->bra = z->c; /* [, line 37 */ - if (z->c >= z->l || (z->p[z->c + 0] != 227 && z->p[z->c + 0] != 245)) among_var = 3; else - among_var = find_among(z, a_0, 3); /* substring, line 37 */ + if (z->c >= z->l || (z->p[z->c + 0] != 227 && z->p[z->c + 0] != 245)) among_var = 3; else /* substring, line 37 */ + among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 37 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 37 */ case 1: { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ if (ret < 0) return ret; @@ -514,15 +506,15 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 46 */ + z->I[1] = z->l; /* $p1 = , line 47 */ + z->I[2] = z->l; /* $p2 = , line 48 */ { int c1 = z->c; /* do, line 50 */ { int c2 = z->c; /* or, line 52 */ - if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ { int c3 = z->c; /* or, line 51 */ - if (out_grouping(z, g_v, 97, 250, 0)) goto lab4; + if (out_grouping(z, g_v, 97, 250, 0)) goto lab4; /* non v, line 51 */ { /* gopast */ /* grouping v, line 51 */ int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab4; @@ -531,7 +523,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ { /* gopast */ /* non v, line 51 */ int ret = in_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab2; @@ -542,9 +534,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 250, 0)) goto lab0; + if (out_grouping(z, g_v, 97, 250, 0)) goto lab0; /* non v, line 53 */ { int c4 = z->c; /* or, line 53 */ - if (out_grouping(z, g_v, 97, 250, 0)) goto lab6; + if (out_grouping(z, g_v, 97, 250, 0)) goto lab6; /* non v, line 53 */ { /* gopast */ /* grouping v, line 53 */ int ret = out_grouping(z, g_v, 97, 250, 1); if (ret < 0) goto lab6; @@ -553,7 +545,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 250, 0)) goto lab0; + if (in_grouping(z, g_v, 97, 250, 0)) goto lab0; /* grouping v, line 53 */ if (z->c >= z->l) goto lab0; z->c++; /* next, line 53 */ } @@ -594,17 +586,16 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 62 */ int c1 = z->c; z->bra = z->c; /* [, line 63 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 63 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else /* substring, line 63 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 63 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 63 */ case 1: { int ret = slice_from_s(z, 1, s_2); /* <-, line 64 */ if (ret < 0) return ret; @@ -628,95 +619,88 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 72 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 73 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 74 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 77 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((839714 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 45); /* substring, line 77 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 77 */ + among_var = find_among_b(z, a_5, 45); if (!(among_var)) return 0; z->bra = z->c; /* ], line 77 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 77 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 93 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 93 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 93 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 98 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 98 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 102 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 102 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 106 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 110 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 110 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 110 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; } - among_var = find_among_b(z, a_2, 4); /* substring, line 112 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + among_var = find_among_b(z, a_2, 4); + if (!(among_var)) { z->c = z->l - m1; goto lab0; } z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 112 */ + { int ret = r_R2(z); /* call R2, line 112 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 112 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } + switch (among_var) { /* among, line 112 */ case 1: z->ket = z->c; /* [, line 113 */ - if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } /* literal, line 113 */ z->bra = z->c; /* ], line 113 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 113 */ + { int ret = r_R2(z); /* call R2, line 113 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 113 */ @@ -729,79 +713,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 6: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 122 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 122 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 122 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 123 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 123 */ z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_3, 3); /* substring, line 124 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } /* substring, line 124 */ + if (!(find_among_b(z, a_3, 3))) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 124 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 127 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; } lab1: ; } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 134 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 134 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_4, 3); /* substring, line 136 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 136 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 139 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 139 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; } lab2: ; } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 146 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 146 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 146 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 147 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 147 */ z->ket = z->c; /* [, line 148 */ - if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } /* literal, line 148 */ z->bra = z->c; /* ], line 148 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 148 */ + { int ret = r_R2(z); /* call R2, line 148 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 148 */ @@ -812,12 +781,12 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 9: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 153 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 153 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_9))) return 0; - { int ret = slice_from_s(z, 2, s_10); /* <-, line 154 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 153 */ + z->c--; + { int ret = slice_from_s(z, 2, s_9); /* <-, line 154 */ if (ret < 0) return ret; } break; @@ -825,97 +794,81 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 159 */ - int m1 = z->l - z->c; (void)m1; +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 159 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 159 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 160 */ - among_var = find_among_b(z, a_6, 120); /* substring, line 160 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } /* substring, line 160 */ z->bra = z->c; /* ], line 160 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - { int ret = slice_del(z); /* delete, line 179 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_residual_suffix(struct SN_env * z) { - int among_var; +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 184 */ - among_var = find_among_b(z, a_7, 7); /* substring, line 184 */ - if (!(among_var)) return 0; + if (!(find_among_b(z, a_7, 7))) return 0; /* substring, line 184 */ z->bra = z->c; /* ], line 184 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 187 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 187 */ - if (ret < 0) return ret; - } - break; + { int ret = r_RV(z); /* call RV, line 187 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 187 */ + if (ret < 0) return ret; } return 1; } -static int r_residual_form(struct SN_env * z) { +static int r_residual_form(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 192 */ among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 192 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 192 */ case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 194 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 194 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 194 */ { int m1 = z->l - z->c; (void)m1; /* or, line 194 */ - if (!(eq_s_b(z, 1, s_11))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; /* literal, line 194 */ + z->c--; z->bra = z->c; /* ], line 194 */ - { int m_test = z->l - z->c; /* test, line 194 */ - if (!(eq_s_b(z, 1, s_12))) goto lab1; - z->c = z->l - m_test; + { int m_test2 = z->l - z->c; /* test, line 194 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; /* literal, line 194 */ + z->c--; + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_13))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 195 */ + z->c--; z->bra = z->c; /* ], line 195 */ - { int m_test = z->l - z->c; /* test, line 195 */ - if (!(eq_s_b(z, 1, s_14))) return 0; - z->c = z->l - m_test; + { int m_test3 = z->l - z->c; /* test, line 195 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; /* literal, line 195 */ + z->c--; + z->c = z->l - m_test3; } } lab0: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 195 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 195 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 195 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_15); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 196 */ if (ret < 0) return ret; } break; @@ -923,77 +876,77 @@ static int r_residual_form(struct SN_env * z) { return 1; } -extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { +extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 202 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 202 */ + { int ret = r_prelude(z); /* call prelude, line 202 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 203 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 203 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 203 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 203 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 204 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 205 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 209 */ - { int m5 = z->l - z->c; (void)m5; /* and, line 207 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 206 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab6; /* call standard_suffix, line 206 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 205 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 209 */ + { int m4 = z->l - z->c; (void)m4; /* and, line 207 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 206 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 206 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 206 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 206 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: - z->c = z->l - m5; - { int m7 = z->l - z->c; (void)m7; /* do, line 207 */ + z->c = z->l - m4; + { int m6 = z->l - z->c; (void)m6; /* do, line 207 */ z->ket = z->c; /* [, line 207 */ - if (!(eq_s_b(z, 1, s_16))) goto lab7; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab7; /* literal, line 207 */ + z->c--; z->bra = z->c; /* ], line 207 */ - { int m_test = z->l - z->c; /* test, line 207 */ - if (!(eq_s_b(z, 1, s_17))) goto lab7; - z->c = z->l - m_test; + { int m_test7 = z->l - z->c; /* test, line 207 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab7; /* literal, line 207 */ + z->c--; + z->c = z->l - m_test7; } - { int ret = r_RV(z); - if (ret == 0) goto lab7; /* call RV, line 207 */ + { int ret = r_RV(z); /* call RV, line 207 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 207 */ if (ret < 0) return ret; } lab7: - z->c = z->l - m7; + z->c = z->l - m6; } } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab2; /* call residual_suffix, line 209 */ + z->c = z->l - m3; + { int ret = r_residual_suffix(z); /* call residual_suffix, line 209 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } { int m8 = z->l - z->c; (void)m8; /* do, line 211 */ - { int ret = r_residual_form(z); - if (ret == 0) goto lab8; /* call residual_form, line 211 */ + { int ret = r_residual_form(z); /* call residual_form, line 211 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: @@ -1001,8 +954,8 @@ extern int portuguese_ISO_8859_1_stem(struct SN_env * z) { } z->c = z->lb; { int c9 = z->c; /* do, line 213 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab9; /* call postlude, line 213 */ + { int ret = r_postlude(z); /* call postlude, line 213 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c index 27f26e7865e..c2f101df3ac 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_spanish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -497,28 +497,22 @@ static const symbol s_6[] = { 'a', 'n', 'd', 'o' }; static const symbol s_7[] = { 'a', 'r' }; static const symbol s_8[] = { 'e', 'r' }; static const symbol s_9[] = { 'i', 'r' }; -static const symbol s_10[] = { 'u' }; -static const symbol s_11[] = { 'i', 'c' }; -static const symbol s_12[] = { 'l', 'o', 'g' }; -static const symbol s_13[] = { 'u' }; -static const symbol s_14[] = { 'e', 'n', 't', 'e' }; +static const symbol s_10[] = { 'i', 'c' }; +static const symbol s_11[] = { 'l', 'o', 'g' }; +static const symbol s_12[] = { 'u' }; +static const symbol s_13[] = { 'e', 'n', 't', 'e' }; +static const symbol s_14[] = { 'a', 't' }; static const symbol s_15[] = { 'a', 't' }; -static const symbol s_16[] = { 'a', 't' }; -static const symbol s_17[] = { 'u' }; -static const symbol s_18[] = { 'u' }; -static const symbol s_19[] = { 'g' }; -static const symbol s_20[] = { 'u' }; -static const symbol s_21[] = { 'g' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 33 */ + z->I[1] = z->l; /* $p1 = , line 34 */ + z->I[2] = z->l; /* $p2 = , line 35 */ { int c1 = z->c; /* do, line 37 */ { int c2 = z->c; /* or, line 39 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ { int c3 = z->c; /* or, line 38 */ - if (out_grouping(z, g_v, 97, 252, 0)) goto lab4; + if (out_grouping(z, g_v, 97, 252, 0)) goto lab4; /* non v, line 38 */ { /* gopast */ /* grouping v, line 38 */ int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab4; @@ -527,7 +521,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ { /* gopast */ /* non v, line 38 */ int ret = in_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab2; @@ -538,9 +532,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 252, 0)) goto lab0; + if (out_grouping(z, g_v, 97, 252, 0)) goto lab0; /* non v, line 40 */ { int c4 = z->c; /* or, line 40 */ - if (out_grouping(z, g_v, 97, 252, 0)) goto lab6; + if (out_grouping(z, g_v, 97, 252, 0)) goto lab6; /* non v, line 40 */ { /* gopast */ /* grouping v, line 40 */ int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) goto lab6; @@ -549,7 +543,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 252, 0)) goto lab0; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab0; /* grouping v, line 40 */ if (z->c >= z->l) goto lab0; z->c++; /* next, line 40 */ } @@ -590,17 +584,16 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 49 */ int c1 = z->c; z->bra = z->c; /* [, line 50 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((67641858 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else - among_var = find_among(z, a_0, 6); /* substring, line 50 */ + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 7 || !((67641858 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 6; else /* substring, line 50 */ + among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 50 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 50 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ if (ret < 0) return ret; @@ -639,36 +632,34 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 63 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 64 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 65 */ return 1; } -static int r_attached_pronoun(struct SN_env * z) { +static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 68 */ + if (!(find_among_b(z, a_1, 13))) return 0; z->bra = z->c; /* ], line 68 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; - among_var = find_among_b(z, a_2, 11); /* substring, line 72 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* substring, line 72 */ + among_var = find_among_b(z, a_2, 11); if (!(among_var)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 72 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 72 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 72 */ case 1: z->bra = z->c; /* ], line 73 */ { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ @@ -705,7 +696,8 @@ static int r_attached_pronoun(struct SN_env * z) { } break; case 7: - if (!(eq_s_b(z, 1, s_10))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 82 */ + z->c--; { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } @@ -714,38 +706,35 @@ static int r_attached_pronoun(struct SN_env * z) { return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 87 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_6, 46); /* substring, line 87 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + among_var = find_among_b(z, a_6, 46); if (!(among_var)) return 0; z->bra = z->c; /* ], line 87 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 87 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 99 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 99 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 99 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 105 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 105 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 105 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 106 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 106 */ z->ket = z->c; /* [, line 106 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } /* literal, line 106 */ z->bra = z->c; /* ], line 106 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 106 */ + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 106 */ @@ -756,61 +745,56 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 111 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_12); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_11); /* <-, line 111 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 115 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 115 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 115 */ + { int ret = slice_from_s(z, 1, s_12); /* <-, line 115 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 119 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 119 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_14); /* <-, line 119 */ + { int ret = slice_from_s(z, 4, s_13); /* <-, line 119 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 123 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 123 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 123 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 124 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 124 */ z->ket = z->c; /* [, line 125 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_3, 4); /* substring, line 125 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 125 */ + among_var = find_among_b(z, a_3, 4); + if (!(among_var)) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 125 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 125 */ + { int ret = r_R2(z); /* call R2, line 125 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } + switch (among_var) { /* among, line 125 */ case 1: z->ket = z->c; /* [, line 126 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab1; } + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } /* literal, line 126 */ z->bra = z->c; /* ], line 126 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 126 */ + { int ret = r_R2(z); /* call R2, line 126 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 126 */ @@ -823,79 +807,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 135 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 135 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 135 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 136 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 136 */ z->ket = z->c; /* [, line 137 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_4, 3); /* substring, line 137 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } /* substring, line 137 */ + if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 137 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 140 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 140 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 140 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 140 */ + if (ret < 0) return ret; } lab2: ; } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 147 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 147 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 147 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 148 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 148 */ z->ket = z->c; /* [, line 149 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab3; } - among_var = find_among_b(z, a_5, 3); /* substring, line 149 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab3; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } /* substring, line 149 */ + if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m4; goto lab3; } z->bra = z->c; /* ], line 149 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab3; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 152 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 152 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 152 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; } lab3: ; } break; case 9: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 159 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 159 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 159 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 160 */ + { int m5 = z->l - z->c; (void)m5; /* try, line 160 */ z->ket = z->c; /* [, line 161 */ - if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m_keep; goto lab4; } + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } /* literal, line 161 */ z->bra = z->c; /* ], line 161 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call R2, line 161 */ + { int ret = r_R2(z); /* call R2, line 161 */ + if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 161 */ @@ -909,54 +878,45 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_y_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 168 */ - int m1 = z->l - z->c; (void)m1; +static int r_y_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 168 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 168 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 168 */ - among_var = find_among_b(z, a_7, 12); /* substring, line 168 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } /* substring, line 168 */ z->bra = z->c; /* ], line 168 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; - case 1: - if (!(eq_s_b(z, 1, s_17))) return 0; - { int ret = slice_del(z); /* delete, line 171 */ - if (ret < 0) return ret; - } - break; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 171 */ + z->c--; + { int ret = slice_del(z); /* delete, line 171 */ + if (ret < 0) return ret; } return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 176 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 176 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 176 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 176 */ among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 176 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 176 */ case 1: - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 179 */ - if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m_keep; goto lab0; } - { int m_test = z->l - z->c; /* test, line 179 */ - if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m2 = z->l - z->c; (void)m2; /* try, line 179 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + z->c--; + { int m_test3 = z->l - z->c; /* test, line 179 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + z->c--; + z->c = z->l - m_test3; } lab0: ; @@ -975,41 +935,40 @@ static int r_verb_suffix(struct SN_env * z) { return 1; } -static int r_residual_suffix(struct SN_env * z) { +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 205 */ among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 205 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 205 */ case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 208 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 208 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 208 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 210 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 210 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 210 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 210 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 210 */ z->ket = z->c; /* [, line 210 */ - if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->c--; z->bra = z->c; /* ], line 210 */ - { int m_test = z->l - z->c; /* test, line 210 */ - if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m_test2 = z->l - z->c; /* test, line 210 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->c--; + z->c = z->l - m_test2; } - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 210 */ + { int ret = r_RV(z); /* call RV, line 210 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 210 */ @@ -1023,66 +982,64 @@ static int r_residual_suffix(struct SN_env * z) { return 1; } -extern int spanish_ISO_8859_1_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 216 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 216 */ - if (ret < 0) return ret; - } - lab0: - z->c = c1; +extern int spanish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ + /* do, line 216 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 216 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; } +lab0: z->lb = z->c; z->c = z->l; /* backwards, line 217 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 218 */ - { int ret = r_attached_pronoun(z); - if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 218 */ + { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 218 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: - z->c = z->l - m2; + z->c = z->l - m1; } - { int m3 = z->l - z->c; (void)m3; /* do, line 219 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 219 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab4; /* call standard_suffix, line 219 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 219 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 219 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 219 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_y_verb_suffix(z); - if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */ + z->c = z->l - m3; + { int ret = r_y_verb_suffix(z); /* call y_verb_suffix, line 220 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab3; lab5: - z->c = z->l - m4; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab2; /* call verb_suffix, line 221 */ + z->c = z->l - m3; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 221 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m5 = z->l - z->c; (void)m5; /* do, line 223 */ - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab6; /* call residual_suffix, line 223 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 223 */ + { int ret = r_residual_suffix(z); /* call residual_suffix, line 223 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m5; + z->c = z->l - m4; } z->c = z->lb; - { int c6 = z->c; /* do, line 225 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab7; /* call postlude, line 225 */ + { int c5 = z->c; /* do, line 225 */ + { int ret = r_postlude(z); /* call postlude, line 225 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = c6; + z->c = c5; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c index f9bef1ada56..13be21762c3 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_1_swedish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -146,15 +146,15 @@ static const unsigned char g_s_ending[] = { 119, 127, 149 }; static const symbol s_0[] = { 'l', 0xF6, 's' }; static const symbol s_1[] = { 'f', 'u', 'l', 'l' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 29 */ - { int ret = z->c + 3; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 28 */ + { int c_test1 = z->c; /* test, line 29 */ + { int ret = z->c + 3; /* hop, line 29 */ if (0 > ret || ret > z->l) return 0; - z->c = ret; /* hop, line 29 */ + z->c = ret; } z->I[1] = z->c; /* setmark x, line 29 */ - z->c = c_test; + z->c = c_test1; } if (out_grouping(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */ { /* gopast */ /* non v, line 30 */ @@ -163,37 +163,34 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 30 */ - /* try, line 31 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + /* try, line 31 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 31 */ + z->I[0] = z->I[1]; /* $p1 = , line 31 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 37 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 37 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 37 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 37 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 37); /* substring, line 37 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 37 */ + among_var = find_among_b(z, a_0, 37); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 37 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 38 */ case 1: { int ret = slice_del(z); /* delete, line 44 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b(z, g_s_ending, 98, 121, 0)) return 0; + if (in_grouping_b(z, g_s_ending, 98, 121, 0)) return 0; /* grouping s_ending, line 46 */ { int ret = slice_del(z); /* delete, line 46 */ if (ret < 0) return ret; } @@ -202,45 +199,40 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int mlimit; /* setlimit, line 50 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 50 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 50 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; { int m2 = z->l - z->c; (void)m2; /* and, line 52 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit; return 0; } /* among, line 51 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* among, line 51 */ + if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit1; return 0; } z->c = z->l - m2; z->ket = z->c; /* [, line 52 */ - if (z->c <= z->lb) { z->lb = mlimit; return 0; } + if (z->c <= z->lb) { z->lb = mlimit1; return 0; } z->c--; /* next, line 52 */ z->bra = z->c; /* ], line 52 */ { int ret = slice_del(z); /* delete, line 52 */ if (ret < 0) return ret; } } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_other_suffix(struct SN_env * z) { +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 55 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 55 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 55 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 5); /* substring, line 56 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 56 */ + among_var = find_among_b(z, a_2, 5); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 56 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + switch (among_var) { /* among, line 56 */ case 1: { int ret = slice_del(z); /* delete, line 57 */ if (ret < 0) return ret; @@ -257,15 +249,15 @@ static int r_other_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -extern int swedish_ISO_8859_1_stem(struct SN_env * z) { +extern int swedish_ISO_8859_1_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 66 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 66 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 66 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -274,24 +266,24 @@ extern int swedish_ISO_8859_1_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 67 */ { int m2 = z->l - z->c; (void)m2; /* do, line 68 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 68 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 68 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 69 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 69 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 69 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 70 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 70 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 70 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c similarity index 54% rename from src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c rename to src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c index ff4b23e0605..ae088a32f75 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_1_hungarian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_2_hungarian.c @@ -1,12 +1,12 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" #ifdef __cplusplus extern "C" { #endif -extern int hungarian_ISO_8859_1_stem(struct SN_env * z); +extern int hungarian_ISO_8859_2_stem(struct SN_env * z); #ifdef __cplusplus } #endif @@ -29,8 +29,8 @@ extern "C" { #endif -extern struct SN_env * hungarian_ISO_8859_1_create_env(void); -extern void hungarian_ISO_8859_1_close_env(struct SN_env * z); +extern struct SN_env * hungarian_ISO_8859_2_create_env(void); +extern void hungarian_ISO_8859_2_close_env(struct SN_env * z); #ifdef __cplusplus @@ -123,7 +123,7 @@ static const symbol s_3_1[2] = { 'e', 'l' }; static const struct among a_3[2] = { /* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 2, 0} +/* 1 */ { 2, s_3_1, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'a' }; @@ -227,7 +227,7 @@ static const struct among a_5[3] = { /* 0 */ { 2, s_5_0, -1, 2, 0}, /* 1 */ { 2, s_5_1, -1, 1, 0}, -/* 2 */ { 6, s_5_2, -1, 3, 0} +/* 2 */ { 6, s_5_2, -1, 2, 0} }; static const symbol s_6_0[4] = { 's', 't', 'u', 'l' }; @@ -239,12 +239,12 @@ static const symbol s_6_5[5] = { 0xE9, 's', 't', 0xFC, 'l' }; static const struct among a_6[6] = { -/* 0 */ { 4, s_6_0, -1, 2, 0}, +/* 0 */ { 4, s_6_0, -1, 1, 0}, /* 1 */ { 5, s_6_1, 0, 1, 0}, -/* 2 */ { 5, s_6_2, 0, 3, 0}, -/* 3 */ { 4, s_6_3, -1, 2, 0}, +/* 2 */ { 5, s_6_2, 0, 2, 0}, +/* 3 */ { 4, s_6_3, -1, 1, 0}, /* 4 */ { 5, s_6_4, 3, 1, 0}, -/* 5 */ { 5, s_6_5, 3, 4, 0} +/* 5 */ { 5, s_6_5, 3, 3, 0} }; static const symbol s_7_0[1] = { 0xE1 }; @@ -253,7 +253,7 @@ static const symbol s_7_1[1] = { 0xE9 }; static const struct among a_7[2] = { /* 0 */ { 1, s_7_0, -1, 1, 0}, -/* 1 */ { 1, s_7_1, -1, 2, 0} +/* 1 */ { 1, s_7_1, -1, 1, 0} }; static const symbol s_8_0[1] = { 'k' }; @@ -266,10 +266,10 @@ static const symbol s_8_6[2] = { 0xF6, 'k' }; static const struct among a_8[7] = { -/* 0 */ { 1, s_8_0, -1, 7, 0}, -/* 1 */ { 2, s_8_1, 0, 4, 0}, -/* 2 */ { 2, s_8_2, 0, 6, 0}, -/* 3 */ { 2, s_8_3, 0, 5, 0}, +/* 0 */ { 1, s_8_0, -1, 3, 0}, +/* 1 */ { 2, s_8_1, 0, 3, 0}, +/* 2 */ { 2, s_8_2, 0, 3, 0}, +/* 3 */ { 2, s_8_3, 0, 3, 0}, /* 4 */ { 2, s_8_4, 0, 1, 0}, /* 5 */ { 2, s_8_5, 0, 2, 0}, /* 6 */ { 2, s_8_6, 0, 3, 0} @@ -290,18 +290,18 @@ static const symbol s_9_11[2] = { 0xE9, 0xE9 }; static const struct among a_9[12] = { -/* 0 */ { 2, s_9_0, -1, 7, 0}, -/* 1 */ { 3, s_9_1, 0, 6, 0}, -/* 2 */ { 3, s_9_2, 0, 5, 0}, -/* 3 */ { 1, s_9_3, -1, 9, 0}, -/* 4 */ { 2, s_9_4, 3, 4, 0}, +/* 0 */ { 2, s_9_0, -1, 1, 0}, +/* 1 */ { 3, s_9_1, 0, 3, 0}, +/* 2 */ { 3, s_9_2, 0, 2, 0}, +/* 3 */ { 1, s_9_3, -1, 1, 0}, +/* 4 */ { 2, s_9_4, 3, 1, 0}, /* 5 */ { 3, s_9_5, 4, 1, 0}, /* 6 */ { 3, s_9_6, 4, 1, 0}, /* 7 */ { 3, s_9_7, 4, 1, 0}, /* 8 */ { 3, s_9_8, 4, 3, 0}, /* 9 */ { 3, s_9_9, 4, 2, 0}, /* 10 */ { 3, s_9_10, 4, 1, 0}, -/* 11 */ { 2, s_9_11, 3, 8, 0} +/* 11 */ { 2, s_9_11, 3, 2, 0} }; static const symbol s_10_0[1] = { 'a' }; @@ -338,37 +338,37 @@ static const symbol s_10_30[1] = { 0xE9 }; static const struct among a_10[31] = { -/* 0 */ { 1, s_10_0, -1, 18, 0}, -/* 1 */ { 2, s_10_1, 0, 17, 0}, -/* 2 */ { 1, s_10_2, -1, 16, 0}, -/* 3 */ { 2, s_10_3, 2, 13, 0}, -/* 4 */ { 2, s_10_4, 2, 13, 0}, -/* 5 */ { 2, s_10_5, 2, 13, 0}, -/* 6 */ { 2, s_10_6, 2, 14, 0}, -/* 7 */ { 2, s_10_7, 2, 15, 0}, -/* 8 */ { 2, s_10_8, 2, 13, 0}, -/* 9 */ { 1, s_10_9, -1, 18, 0}, -/* 10 */ { 2, s_10_10, 9, 17, 0}, -/* 11 */ { 2, s_10_11, -1, 4, 0}, +/* 0 */ { 1, s_10_0, -1, 1, 0}, +/* 1 */ { 2, s_10_1, 0, 1, 0}, +/* 2 */ { 1, s_10_2, -1, 1, 0}, +/* 3 */ { 2, s_10_3, 2, 1, 0}, +/* 4 */ { 2, s_10_4, 2, 1, 0}, +/* 5 */ { 2, s_10_5, 2, 1, 0}, +/* 6 */ { 2, s_10_6, 2, 2, 0}, +/* 7 */ { 2, s_10_7, 2, 3, 0}, +/* 8 */ { 2, s_10_8, 2, 1, 0}, +/* 9 */ { 1, s_10_9, -1, 1, 0}, +/* 10 */ { 2, s_10_10, 9, 1, 0}, +/* 11 */ { 2, s_10_11, -1, 1, 0}, /* 12 */ { 3, s_10_12, 11, 1, 0}, /* 13 */ { 3, s_10_13, 11, 2, 0}, /* 14 */ { 3, s_10_14, 11, 3, 0}, /* 15 */ { 3, s_10_15, 11, 1, 0}, -/* 16 */ { 2, s_10_16, -1, 8, 0}, -/* 17 */ { 3, s_10_17, 16, 7, 0}, -/* 18 */ { 4, s_10_18, 17, 5, 0}, -/* 19 */ { 2, s_10_19, -1, 8, 0}, -/* 20 */ { 3, s_10_20, 19, 7, 0}, -/* 21 */ { 4, s_10_21, 20, 6, 0}, -/* 22 */ { 1, s_10_22, -1, 12, 0}, -/* 23 */ { 2, s_10_23, 22, 9, 0}, -/* 24 */ { 2, s_10_24, 22, 9, 0}, -/* 25 */ { 2, s_10_25, 22, 9, 0}, -/* 26 */ { 2, s_10_26, 22, 10, 0}, -/* 27 */ { 2, s_10_27, 22, 11, 0}, -/* 28 */ { 1, s_10_28, -1, 18, 0}, -/* 29 */ { 1, s_10_29, -1, 19, 0}, -/* 30 */ { 1, s_10_30, -1, 20, 0} +/* 16 */ { 2, s_10_16, -1, 1, 0}, +/* 17 */ { 3, s_10_17, 16, 1, 0}, +/* 18 */ { 4, s_10_18, 17, 2, 0}, +/* 19 */ { 2, s_10_19, -1, 1, 0}, +/* 20 */ { 3, s_10_20, 19, 1, 0}, +/* 21 */ { 4, s_10_21, 20, 3, 0}, +/* 22 */ { 1, s_10_22, -1, 1, 0}, +/* 23 */ { 2, s_10_23, 22, 1, 0}, +/* 24 */ { 2, s_10_24, 22, 1, 0}, +/* 25 */ { 2, s_10_25, 22, 1, 0}, +/* 26 */ { 2, s_10_26, 22, 2, 0}, +/* 27 */ { 2, s_10_27, 22, 3, 0}, +/* 28 */ { 1, s_10_28, -1, 1, 0}, +/* 29 */ { 1, s_10_29, -1, 2, 0}, +/* 30 */ { 1, s_10_30, -1, 3, 0} }; static const symbol s_11_0[2] = { 'i', 'd' }; @@ -416,45 +416,45 @@ static const symbol s_11_41[3] = { 0xE9, 'i', 'm' }; static const struct among a_11[42] = { -/* 0 */ { 2, s_11_0, -1, 10, 0}, -/* 1 */ { 3, s_11_1, 0, 9, 0}, -/* 2 */ { 4, s_11_2, 1, 6, 0}, -/* 3 */ { 3, s_11_3, 0, 9, 0}, -/* 4 */ { 4, s_11_4, 3, 6, 0}, -/* 5 */ { 3, s_11_5, 0, 7, 0}, -/* 6 */ { 3, s_11_6, 0, 8, 0}, -/* 7 */ { 1, s_11_7, -1, 15, 0}, -/* 8 */ { 2, s_11_8, 7, 14, 0}, -/* 9 */ { 3, s_11_9, 8, 11, 0}, -/* 10 */ { 2, s_11_10, 7, 14, 0}, -/* 11 */ { 3, s_11_11, 10, 11, 0}, -/* 12 */ { 2, s_11_12, 7, 12, 0}, -/* 13 */ { 2, s_11_13, 7, 13, 0}, -/* 14 */ { 4, s_11_14, -1, 24, 0}, -/* 15 */ { 5, s_11_15, 14, 21, 0}, -/* 16 */ { 6, s_11_16, 15, 20, 0}, -/* 17 */ { 5, s_11_17, 14, 23, 0}, -/* 18 */ { 2, s_11_18, -1, 29, 0}, -/* 19 */ { 3, s_11_19, 18, 26, 0}, -/* 20 */ { 4, s_11_20, 19, 25, 0}, -/* 21 */ { 3, s_11_21, 18, 26, 0}, -/* 22 */ { 4, s_11_22, 21, 25, 0}, -/* 23 */ { 3, s_11_23, 18, 27, 0}, -/* 24 */ { 3, s_11_24, 18, 28, 0}, -/* 25 */ { 3, s_11_25, -1, 20, 0}, -/* 26 */ { 4, s_11_26, 25, 17, 0}, -/* 27 */ { 5, s_11_27, 26, 16, 0}, -/* 28 */ { 4, s_11_28, 25, 17, 0}, -/* 29 */ { 5, s_11_29, 28, 16, 0}, -/* 30 */ { 4, s_11_30, 25, 18, 0}, -/* 31 */ { 4, s_11_31, 25, 19, 0}, -/* 32 */ { 5, s_11_32, -1, 21, 0}, -/* 33 */ { 6, s_11_33, 32, 20, 0}, -/* 34 */ { 5, s_11_34, -1, 22, 0}, -/* 35 */ { 2, s_11_35, -1, 5, 0}, -/* 36 */ { 3, s_11_36, 35, 4, 0}, +/* 0 */ { 2, s_11_0, -1, 1, 0}, +/* 1 */ { 3, s_11_1, 0, 1, 0}, +/* 2 */ { 4, s_11_2, 1, 1, 0}, +/* 3 */ { 3, s_11_3, 0, 1, 0}, +/* 4 */ { 4, s_11_4, 3, 1, 0}, +/* 5 */ { 3, s_11_5, 0, 2, 0}, +/* 6 */ { 3, s_11_6, 0, 3, 0}, +/* 7 */ { 1, s_11_7, -1, 1, 0}, +/* 8 */ { 2, s_11_8, 7, 1, 0}, +/* 9 */ { 3, s_11_9, 8, 1, 0}, +/* 10 */ { 2, s_11_10, 7, 1, 0}, +/* 11 */ { 3, s_11_11, 10, 1, 0}, +/* 12 */ { 2, s_11_12, 7, 2, 0}, +/* 13 */ { 2, s_11_13, 7, 3, 0}, +/* 14 */ { 4, s_11_14, -1, 1, 0}, +/* 15 */ { 5, s_11_15, 14, 1, 0}, +/* 16 */ { 6, s_11_16, 15, 1, 0}, +/* 17 */ { 5, s_11_17, 14, 3, 0}, +/* 18 */ { 2, s_11_18, -1, 1, 0}, +/* 19 */ { 3, s_11_19, 18, 1, 0}, +/* 20 */ { 4, s_11_20, 19, 1, 0}, +/* 21 */ { 3, s_11_21, 18, 1, 0}, +/* 22 */ { 4, s_11_22, 21, 1, 0}, +/* 23 */ { 3, s_11_23, 18, 2, 0}, +/* 24 */ { 3, s_11_24, 18, 3, 0}, +/* 25 */ { 3, s_11_25, -1, 1, 0}, +/* 26 */ { 4, s_11_26, 25, 1, 0}, +/* 27 */ { 5, s_11_27, 26, 1, 0}, +/* 28 */ { 4, s_11_28, 25, 1, 0}, +/* 29 */ { 5, s_11_29, 28, 1, 0}, +/* 30 */ { 4, s_11_30, 25, 2, 0}, +/* 31 */ { 4, s_11_31, 25, 3, 0}, +/* 32 */ { 5, s_11_32, -1, 1, 0}, +/* 33 */ { 6, s_11_33, 32, 1, 0}, +/* 34 */ { 5, s_11_34, -1, 2, 0}, +/* 35 */ { 2, s_11_35, -1, 1, 0}, +/* 36 */ { 3, s_11_36, 35, 1, 0}, /* 37 */ { 4, s_11_37, 36, 1, 0}, -/* 38 */ { 3, s_11_38, 35, 4, 0}, +/* 38 */ { 3, s_11_38, 35, 1, 0}, /* 39 */ { 4, s_11_39, 38, 1, 0}, /* 40 */ { 3, s_11_40, 35, 2, 0}, /* 41 */ { 3, s_11_41, 35, 3, 0} @@ -467,46 +467,24 @@ static const symbol s_1[] = { 'e' }; static const symbol s_2[] = { 'e' }; static const symbol s_3[] = { 'a' }; static const symbol s_4[] = { 'a' }; -static const symbol s_5[] = { 'a' }; -static const symbol s_6[] = { 'e' }; -static const symbol s_7[] = { 'a' }; +static const symbol s_5[] = { 'e' }; +static const symbol s_6[] = { 'a' }; +static const symbol s_7[] = { 'e' }; static const symbol s_8[] = { 'e' }; -static const symbol s_9[] = { 'e' }; +static const symbol s_9[] = { 'a' }; static const symbol s_10[] = { 'a' }; static const symbol s_11[] = { 'e' }; static const symbol s_12[] = { 'a' }; static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'a' }; -static const symbol s_15[] = { 'e' }; -static const symbol s_16[] = { 'a' }; -static const symbol s_17[] = { 'e' }; -static const symbol s_18[] = { 'a' }; -static const symbol s_19[] = { 'e' }; -static const symbol s_20[] = { 'a' }; -static const symbol s_21[] = { 'e' }; -static const symbol s_22[] = { 'a' }; -static const symbol s_23[] = { 'e' }; -static const symbol s_24[] = { 'a' }; -static const symbol s_25[] = { 'e' }; -static const symbol s_26[] = { 'a' }; -static const symbol s_27[] = { 'e' }; -static const symbol s_28[] = { 'a' }; -static const symbol s_29[] = { 'e' }; -static const symbol s_30[] = { 'a' }; -static const symbol s_31[] = { 'e' }; -static const symbol s_32[] = { 'a' }; -static const symbol s_33[] = { 'e' }; -static const symbol s_34[] = { 'a' }; -static const symbol s_35[] = { 'e' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 46 */ { int c1 = z->c; /* or, line 51 */ - if (in_grouping(z, g_v, 97, 252, 0)) goto lab1; + if (in_grouping(z, g_v, 97, 252, 0)) goto lab1; /* grouping v, line 48 */ if (in_grouping(z, g_v, 97, 252, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */ { int c2 = z->c; /* or, line 49 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; - if (!(find_among(z, a_0, 8))) goto lab3; /* among, line 49 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; /* among, line 49 */ + if (!(find_among(z, a_0, 8))) goto lab3; goto lab2; lab3: z->c = c2; @@ -518,7 +496,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab0; lab1: z->c = c1; - if (out_grouping(z, g_v, 97, 252, 0)) return 0; + if (out_grouping(z, g_v, 97, 252, 0)) return 0; /* non v, line 53 */ { /* gopast */ /* grouping v, line 53 */ int ret = out_grouping(z, g_v, 97, 252, 1); if (ret < 0) return 0; @@ -530,24 +508,22 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 58 */ return 1; } -static int r_v_ending(struct SN_env * z) { +static int r_v_ending(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 61 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; - among_var = find_among_b(z, a_1, 2); /* substring, line 61 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; /* substring, line 61 */ + among_var = find_among_b(z, a_1, 2); if (!(among_var)) return 0; z->bra = z->c; /* ], line 61 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 61 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 61 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 61 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */ if (ret < 0) return ret; @@ -562,22 +538,22 @@ static int r_v_ending(struct SN_env * z) { return 1; } -static int r_double(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 23))) return 0; /* among, line 68 */ - z->c = z->l - m_test; +static int r_double(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 68 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 68 */ + if (!(find_among_b(z, a_2, 23))) return 0; + z->c = z->l - m_test1; } return 1; } -static int r_undouble(struct SN_env * z) { +static int r_undouble(struct SN_env * z) { /* backwardmode */ if (z->c <= z->lb) return 0; z->c--; /* next, line 73 */ z->ket = z->c; /* [, line 73 */ - { int ret = z->c - 1; + { int ret = z->c - 1; /* hop, line 73 */ if (z->lb > ret || ret > z->l) return 0; - z->c = ret; /* hop, line 73 */ + z->c = ret; } z->bra = z->c; /* ], line 73 */ { int ret = slice_del(z); /* delete, line 73 */ @@ -586,73 +562,53 @@ static int r_undouble(struct SN_env * z) { return 1; } -static int r_instrum(struct SN_env * z) { - int among_var; +static int r_instrum(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 77 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; - among_var = find_among_b(z, a_3, 2); /* substring, line 77 */ - if (!(among_var)) return 0; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 77 */ + if (!(find_among_b(z, a_3, 2))) return 0; z->bra = z->c; /* ], line 77 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 77 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 77 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 78 */ - if (ret < 0) return ret; - } - break; - case 2: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 79 */ - if (ret < 0) return ret; - } - break; + { int ret = r_double(z); /* call double, line 78 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 81 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 82 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 82 */ + if (ret <= 0) return ret; } return 1; } -static int r_case(struct SN_env * z) { +static int r_case(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 87 */ if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */ z->bra = z->c; /* ], line 87 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 87 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 87 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 111 */ if (ret < 0) return ret; } - { int ret = r_v_ending(z); - if (ret == 0) return 0; /* call v_ending, line 112 */ - if (ret < 0) return ret; + { int ret = r_v_ending(z); /* call v_ending, line 112 */ + if (ret <= 0) return ret; } return 1; } -static int r_case_special(struct SN_env * z) { +static int r_case_special(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 116 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; - among_var = find_among_b(z, a_5, 3); /* substring, line 116 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; /* substring, line 116 */ + among_var = find_among_b(z, a_5, 3); if (!(among_var)) return 0; z->bra = z->c; /* ], line 116 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 116 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 116 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 116 */ case 1: { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */ if (ret < 0) return ret; @@ -663,45 +619,33 @@ static int r_case_special(struct SN_env * z) { if (ret < 0) return ret; } break; - case 3: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 119 */ - if (ret < 0) return ret; - } - break; } return 1; } -static int r_case_other(struct SN_env * z) { +static int r_case_other(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; - among_var = find_among_b(z, a_6, 6); /* substring, line 124 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 124 */ + among_var = find_among_b(z, a_6, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 124 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 124 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 124 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 124 */ case 1: { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 126 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 127 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 127 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 128 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 128 */ if (ret < 0) return ret; } break; @@ -709,62 +653,44 @@ static int r_case_other(struct SN_env * z) { return 1; } -static int r_factive(struct SN_env * z) { - int among_var; +static int r_factive(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 133 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; - among_var = find_among_b(z, a_7, 2); /* substring, line 133 */ - if (!(among_var)) return 0; + if (z->c <= z->lb || (z->p[z->c - 1] != 225 && z->p[z->c - 1] != 233)) return 0; /* substring, line 133 */ + if (!(find_among_b(z, a_7, 2))) return 0; z->bra = z->c; /* ], line 133 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 133 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 133 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 134 */ - if (ret < 0) return ret; - } - break; - case 2: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 135 */ - if (ret < 0) return ret; - } - break; + { int ret = r_double(z); /* call double, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 137 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 138 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 138 */ + if (ret <= 0) return ret; } return 1; } -static int r_plural(struct SN_env * z) { +static int r_plural(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 142 */ - if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; - among_var = find_among_b(z, a_8, 7); /* substring, line 142 */ + if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; /* substring, line 142 */ + among_var = find_among_b(z, a_8, 7); if (!(among_var)) return 0; z->bra = z->c; /* ], line 142 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 142 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 142 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 142 */ case 1: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 143 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 143 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 144 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 144 */ if (ret < 0) return ret; } break; @@ -773,85 +699,33 @@ static int r_plural(struct SN_env * z) { if (ret < 0) return ret; } break; - case 4: - { int ret = slice_del(z); /* delete, line 146 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_del(z); /* delete, line 147 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_del(z); /* delete, line 148 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 149 */ - if (ret < 0) return ret; - } - break; } return 1; } -static int r_owned(struct SN_env * z) { +static int r_owned(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 154 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 233)) return 0; - among_var = find_among_b(z, a_9, 12); /* substring, line 154 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 233)) return 0; /* substring, line 154 */ + among_var = find_among_b(z, a_9, 12); if (!(among_var)) return 0; z->bra = z->c; /* ], line 154 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 154 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 154 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 154 */ case 1: { int ret = slice_del(z); /* delete, line 155 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 156 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 156 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 157 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 158 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 159 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 160 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 161 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 162 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 157 */ if (ret < 0) return ret; } break; @@ -859,115 +733,28 @@ static int r_owned(struct SN_env * z) { return 1; } -static int r_sing_owner(struct SN_env * z) { +static int r_sing_owner(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 168 */ among_var = find_among_b(z, a_10, 31); /* substring, line 168 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 168 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 168 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 168 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 168 */ case 1: { int ret = slice_del(z); /* delete, line 169 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_14); /* <-, line 170 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 170 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_15); /* <-, line 171 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 172 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_from_s(z, 1, s_16); /* <-, line 173 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_from_s(z, 1, s_17); /* <-, line 174 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 175 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_del(z); /* delete, line 176 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 177 */ - if (ret < 0) return ret; - } - break; - case 10: - { int ret = slice_from_s(z, 1, s_18); /* <-, line 178 */ - if (ret < 0) return ret; - } - break; - case 11: - { int ret = slice_from_s(z, 1, s_19); /* <-, line 179 */ - if (ret < 0) return ret; - } - break; - case 12: - { int ret = slice_del(z); /* delete, line 180 */ - if (ret < 0) return ret; - } - break; - case 13: - { int ret = slice_del(z); /* delete, line 181 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_from_s(z, 1, s_20); /* <-, line 182 */ - if (ret < 0) return ret; - } - break; - case 15: - { int ret = slice_from_s(z, 1, s_21); /* <-, line 183 */ - if (ret < 0) return ret; - } - break; - case 16: - { int ret = slice_del(z); /* delete, line 184 */ - if (ret < 0) return ret; - } - break; - case 17: - { int ret = slice_del(z); /* delete, line 185 */ - if (ret < 0) return ret; - } - break; - case 18: - { int ret = slice_del(z); /* delete, line 186 */ - if (ret < 0) return ret; - } - break; - case 19: - { int ret = slice_from_s(z, 1, s_22); /* <-, line 187 */ - if (ret < 0) return ret; - } - break; - case 20: - { int ret = slice_from_s(z, 1, s_23); /* <-, line 188 */ + { int ret = slice_from_s(z, 1, s_11); /* <-, line 171 */ if (ret < 0) return ret; } break; @@ -975,161 +762,29 @@ static int r_sing_owner(struct SN_env * z) { return 1; } -static int r_plur_owner(struct SN_env * z) { +static int r_plur_owner(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 193 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_11, 42); /* substring, line 193 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 193 */ + among_var = find_among_b(z, a_11, 42); if (!(among_var)) return 0; z->bra = z->c; /* ], line 193 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 193 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 193 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 193 */ case 1: { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_24); /* <-, line 195 */ + { int ret = slice_from_s(z, 1, s_12); /* <-, line 195 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_25); /* <-, line 196 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 197 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_del(z); /* delete, line 198 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_del(z); /* delete, line 199 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_from_s(z, 1, s_26); /* <-, line 200 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_from_s(z, 1, s_27); /* <-, line 201 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 202 */ - if (ret < 0) return ret; - } - break; - case 10: - { int ret = slice_del(z); /* delete, line 203 */ - if (ret < 0) return ret; - } - break; - case 11: - { int ret = slice_del(z); /* delete, line 204 */ - if (ret < 0) return ret; - } - break; - case 12: - { int ret = slice_from_s(z, 1, s_28); /* <-, line 205 */ - if (ret < 0) return ret; - } - break; - case 13: - { int ret = slice_from_s(z, 1, s_29); /* <-, line 206 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_del(z); /* delete, line 207 */ - if (ret < 0) return ret; - } - break; - case 15: - { int ret = slice_del(z); /* delete, line 208 */ - if (ret < 0) return ret; - } - break; - case 16: - { int ret = slice_del(z); /* delete, line 209 */ - if (ret < 0) return ret; - } - break; - case 17: - { int ret = slice_del(z); /* delete, line 210 */ - if (ret < 0) return ret; - } - break; - case 18: - { int ret = slice_from_s(z, 1, s_30); /* <-, line 211 */ - if (ret < 0) return ret; - } - break; - case 19: - { int ret = slice_from_s(z, 1, s_31); /* <-, line 212 */ - if (ret < 0) return ret; - } - break; - case 20: - { int ret = slice_del(z); /* delete, line 214 */ - if (ret < 0) return ret; - } - break; - case 21: - { int ret = slice_del(z); /* delete, line 215 */ - if (ret < 0) return ret; - } - break; - case 22: - { int ret = slice_from_s(z, 1, s_32); /* <-, line 216 */ - if (ret < 0) return ret; - } - break; - case 23: - { int ret = slice_from_s(z, 1, s_33); /* <-, line 217 */ - if (ret < 0) return ret; - } - break; - case 24: - { int ret = slice_del(z); /* delete, line 218 */ - if (ret < 0) return ret; - } - break; - case 25: - { int ret = slice_del(z); /* delete, line 219 */ - if (ret < 0) return ret; - } - break; - case 26: - { int ret = slice_del(z); /* delete, line 220 */ - if (ret < 0) return ret; - } - break; - case 27: - { int ret = slice_from_s(z, 1, s_34); /* <-, line 221 */ - if (ret < 0) return ret; - } - break; - case 28: - { int ret = slice_from_s(z, 1, s_35); /* <-, line 222 */ - if (ret < 0) return ret; - } - break; - case 29: - { int ret = slice_del(z); /* delete, line 223 */ + { int ret = slice_from_s(z, 1, s_13); /* <-, line 196 */ if (ret < 0) return ret; } break; @@ -1137,10 +792,10 @@ static int r_plur_owner(struct SN_env * z) { return 1; } -extern int hungarian_ISO_8859_1_stem(struct SN_env * z) { +extern int hungarian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 229 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 229 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 229 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -1149,72 +804,72 @@ extern int hungarian_ISO_8859_1_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 230 */ { int m2 = z->l - z->c; (void)m2; /* do, line 231 */ - { int ret = r_instrum(z); - if (ret == 0) goto lab1; /* call instrum, line 231 */ + { int ret = r_instrum(z); /* call instrum, line 231 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 232 */ - { int ret = r_case(z); - if (ret == 0) goto lab2; /* call case, line 232 */ + { int ret = r_case(z); /* call case, line 232 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 233 */ - { int ret = r_case_special(z); - if (ret == 0) goto lab3; /* call case_special, line 233 */ + { int ret = r_case_special(z); /* call case_special, line 233 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } { int m5 = z->l - z->c; (void)m5; /* do, line 234 */ - { int ret = r_case_other(z); - if (ret == 0) goto lab4; /* call case_other, line 234 */ + { int ret = r_case_other(z); /* call case_other, line 234 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: z->c = z->l - m5; } { int m6 = z->l - z->c; (void)m6; /* do, line 235 */ - { int ret = r_factive(z); - if (ret == 0) goto lab5; /* call factive, line 235 */ + { int ret = r_factive(z); /* call factive, line 235 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } lab5: z->c = z->l - m6; } { int m7 = z->l - z->c; (void)m7; /* do, line 236 */ - { int ret = r_owned(z); - if (ret == 0) goto lab6; /* call owned, line 236 */ + { int ret = r_owned(z); /* call owned, line 236 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: z->c = z->l - m7; } { int m8 = z->l - z->c; (void)m8; /* do, line 237 */ - { int ret = r_sing_owner(z); - if (ret == 0) goto lab7; /* call sing_owner, line 237 */ + { int ret = r_sing_owner(z); /* call sing_owner, line 237 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: z->c = z->l - m8; } { int m9 = z->l - z->c; (void)m9; /* do, line 238 */ - { int ret = r_plur_owner(z); - if (ret == 0) goto lab8; /* call plur_owner, line 238 */ + { int ret = r_plur_owner(z); /* call plur_owner, line 238 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: z->c = z->l - m9; } { int m10 = z->l - z->c; (void)m10; /* do, line 239 */ - { int ret = r_plural(z); - if (ret == 0) goto lab9; /* call plural, line 239 */ + { int ret = r_plural(z); /* call plural, line 239 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: @@ -1224,7 +879,7 @@ extern int hungarian_ISO_8859_1_stem(struct SN_env * z) { return 1; } -extern struct SN_env * hungarian_ISO_8859_1_create_env(void) { return SN_create_env(0, 1, 0); } +extern struct SN_env * hungarian_ISO_8859_2_create_env(void) { return SN_create_env(0, 1, 0); } -extern void hungarian_ISO_8859_1_close_env(struct SN_env * z) { SN_close_env(z, 0); } +extern void hungarian_ISO_8859_2_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c index d5cc2bec3fc..a085e09efe5 100644 --- a/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c +++ b/src/backend/snowball/libstemmer/stem_ISO_8859_2_romanian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -516,51 +516,49 @@ static const struct among a_5[5] = static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 32 }; -static const symbol s_0[] = { 'u' }; -static const symbol s_1[] = { 'U' }; +static const symbol s_0[] = { 'U' }; +static const symbol s_1[] = { 'I' }; static const symbol s_2[] = { 'i' }; -static const symbol s_3[] = { 'I' }; -static const symbol s_4[] = { 'i' }; -static const symbol s_5[] = { 'u' }; -static const symbol s_6[] = { 'a' }; -static const symbol s_7[] = { 'e' }; +static const symbol s_3[] = { 'u' }; +static const symbol s_4[] = { 'a' }; +static const symbol s_5[] = { 'e' }; +static const symbol s_6[] = { 'i' }; +static const symbol s_7[] = { 'a', 'b' }; static const symbol s_8[] = { 'i' }; -static const symbol s_9[] = { 'a', 'b' }; -static const symbol s_10[] = { 'i' }; -static const symbol s_11[] = { 'a', 't' }; -static const symbol s_12[] = { 'a', 0xFE, 'i' }; -static const symbol s_13[] = { 'a', 'b', 'i', 'l' }; -static const symbol s_14[] = { 'i', 'b', 'i', 'l' }; -static const symbol s_15[] = { 'i', 'v' }; -static const symbol s_16[] = { 'i', 'c' }; -static const symbol s_17[] = { 'a', 't' }; -static const symbol s_18[] = { 'i', 't' }; -static const symbol s_19[] = { 0xFE }; -static const symbol s_20[] = { 't' }; -static const symbol s_21[] = { 'i', 's', 't' }; -static const symbol s_22[] = { 'u' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_9[] = { 'a', 't' }; +static const symbol s_10[] = { 'a', 0xFE, 'i' }; +static const symbol s_11[] = { 'a', 'b', 'i', 'l' }; +static const symbol s_12[] = { 'i', 'b', 'i', 'l' }; +static const symbol s_13[] = { 'i', 'v' }; +static const symbol s_14[] = { 'i', 'c' }; +static const symbol s_15[] = { 'a', 't' }; +static const symbol s_16[] = { 'i', 't' }; +static const symbol s_17[] = { 't' }; +static const symbol s_18[] = { 'i', 's', 't' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ while(1) { /* repeat, line 32 */ int c1 = z->c; while(1) { /* goto, line 32 */ int c2 = z->c; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; /* grouping v, line 33 */ z->bra = z->c; /* [, line 33 */ { int c3 = z->c; /* or, line 33 */ - if (!(eq_s(z, 1, s_0))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'u') goto lab3; /* literal, line 33 */ + z->c++; z->ket = z->c; /* ], line 33 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab3; - { int ret = slice_from_s(z, 1, s_1); /* <-, line 33 */ + if (in_grouping(z, g_v, 97, 238, 0)) goto lab3; /* grouping v, line 33 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 33 */ if (ret < 0) return ret; } goto lab2; lab3: z->c = c3; - if (!(eq_s(z, 1, s_2))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'i') goto lab1; /* literal, line 34 */ + z->c++; z->ket = z->c; /* ], line 34 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 34 */ + if (in_grouping(z, g_v, 97, 238, 0)) goto lab1; /* grouping v, line 34 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 34 */ if (ret < 0) return ret; } } @@ -580,15 +578,15 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 40 */ + z->I[1] = z->l; /* $p1 = , line 41 */ + z->I[2] = z->l; /* $p2 = , line 42 */ { int c1 = z->c; /* do, line 44 */ { int c2 = z->c; /* or, line 46 */ - if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; /* grouping v, line 45 */ { int c3 = z->c; /* or, line 45 */ - if (out_grouping(z, g_v, 97, 238, 0)) goto lab4; + if (out_grouping(z, g_v, 97, 238, 0)) goto lab4; /* non v, line 45 */ { /* gopast */ /* grouping v, line 45 */ int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab4; @@ -597,7 +595,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab2; /* grouping v, line 45 */ { /* gopast */ /* non v, line 45 */ int ret = in_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab2; @@ -608,9 +606,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping(z, g_v, 97, 238, 0)) goto lab0; + if (out_grouping(z, g_v, 97, 238, 0)) goto lab0; /* non v, line 47 */ { int c4 = z->c; /* or, line 47 */ - if (out_grouping(z, g_v, 97, 238, 0)) goto lab6; + if (out_grouping(z, g_v, 97, 238, 0)) goto lab6; /* non v, line 47 */ { /* gopast */ /* grouping v, line 47 */ int ret = out_grouping(z, g_v, 97, 238, 1); if (ret < 0) goto lab6; @@ -619,7 +617,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping(z, g_v, 97, 238, 0)) goto lab0; + if (in_grouping(z, g_v, 97, 238, 0)) goto lab0; /* grouping v, line 47 */ if (z->c >= z->l) goto lab0; z->c++; /* next, line 47 */ } @@ -660,24 +658,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 56 */ int c1 = z->c; z->bra = z->c; /* [, line 58 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else - among_var = find_among(z, a_0, 3); /* substring, line 58 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 58 */ + among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 58 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 58 */ case 1: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 59 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 60 */ if (ret < 0) return ret; } break; @@ -694,72 +691,70 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 68 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 69 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 70 */ return 1; } -static int r_step_0(struct SN_env * z) { +static int r_step_0(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 73 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_1, 16); /* substring, line 73 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; z->bra = z->c; /* ], line 73 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 73 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 73 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 73 */ case 1: { int ret = slice_del(z); /* delete, line 75 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 77 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 77 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 79 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 81 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 81 */ if (ret < 0) return ret; } break; case 5: { int m1 = z->l - z->c; (void)m1; /* not, line 83 */ - if (!(eq_s_b(z, 2, s_9))) goto lab0; + if (!(eq_s_b(z, 2, s_7))) goto lab0; /* literal, line 83 */ return 0; lab0: z->c = z->l - m1; } - { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_11); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_9); /* <-, line 85 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_12); /* <-, line 87 */ + { int ret = slice_from_s(z, 3, s_10); /* <-, line 87 */ if (ret < 0) return ret; } break; @@ -767,63 +762,61 @@ static int r_step_0(struct SN_env * z) { return 1; } -static int r_combo_suffix(struct SN_env * z) { +static int r_combo_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_test = z->l - z->c; /* test, line 91 */ + { int m_test1 = z->l - z->c; /* test, line 91 */ z->ket = z->c; /* [, line 92 */ among_var = find_among_b(z, a_2, 46); /* substring, line 92 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 92 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 92 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 92 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 93 */ case 1: - { int ret = slice_from_s(z, 4, s_13); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 101 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_14); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 107 */ + { int ret = slice_from_s(z, 2, s_13); /* <-, line 107 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 113 */ + { int ret = slice_from_s(z, 2, s_14); /* <-, line 113 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 118 */ + { int ret = slice_from_s(z, 2, s_15); /* <-, line 118 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_18); /* <-, line 122 */ + { int ret = slice_from_s(z, 2, s_16); /* <-, line 122 */ if (ret < 0) return ret; } break; } z->B[0] = 1; /* set standard_suffix_removed, line 125 */ - z->c = z->l - m_test; + z->c = z->l - m_test1; } return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->B[0] = 0; /* unset standard_suffix_removed, line 130 */ while(1) { /* repeat, line 131 */ int m1 = z->l - z->c; (void)m1; - { int ret = r_combo_suffix(z); - if (ret == 0) goto lab0; /* call combo_suffix, line 131 */ + { int ret = r_combo_suffix(z); /* call combo_suffix, line 131 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } continue; @@ -835,26 +828,25 @@ static int r_standard_suffix(struct SN_env * z) { among_var = find_among_b(z, a_3, 62); /* substring, line 132 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 132 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 132 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 132 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 133 */ case 1: { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 1, s_19))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xFE) return 0; /* literal, line 152 */ + z->c--; z->bra = z->c; /* ], line 152 */ - { int ret = slice_from_s(z, 1, s_20); /* <-, line 152 */ + { int ret = slice_from_s(z, 1, s_17); /* <-, line 152 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_21); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 156 */ if (ret < 0) return ret; } break; @@ -863,27 +855,25 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 164 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 164 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 164 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 165 */ among_var = find_among_b(z, a_4, 94); /* substring, line 165 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 165 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + switch (among_var) { /* among, line 165 */ case 1: { int m2 = z->l - z->c; (void)m2; /* or, line 200 */ - if (out_grouping_b(z, g_v, 97, 238, 0)) goto lab1; + if (out_grouping_b(z, g_v, 97, 238, 0)) goto lab1; /* non v, line 200 */ goto lab0; lab1: z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_22))) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } /* literal, line 200 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 200 */ @@ -896,98 +886,88 @@ static int r_verb_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_vowel_suffix(struct SN_env * z) { - int among_var; +static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 219 */ - among_var = find_among_b(z, a_5, 5); /* substring, line 219 */ - if (!(among_var)) return 0; + if (!(find_among_b(z, a_5, 5))) return 0; /* substring, line 219 */ z->bra = z->c; /* ], line 219 */ - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 219 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 219 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 220 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 220 */ + if (ret < 0) return ret; } return 1; } -extern int romanian_ISO_8859_2_stem(struct SN_env * z) { +extern int romanian_ISO_8859_2_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 226 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 226 */ + { int ret = r_prelude(z); /* call prelude, line 226 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 227 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 227 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 227 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 227 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 228 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 229 */ - { int ret = r_step_0(z); - if (ret == 0) goto lab2; /* call step_0, line 229 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 229 */ + { int ret = r_step_0(z); /* call step_0, line 229 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 230 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab3; /* call standard_suffix, line 230 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 230 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 230 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = z->l - m4; + z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 231 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 231 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 231 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 231 */ if (!(z->B[0])) goto lab6; /* Boolean test standard_suffix_removed, line 231 */ goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 231 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 231 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: lab4: - z->c = z->l - m5; + z->c = z->l - m4; } - { int m7 = z->l - z->c; (void)m7; /* do, line 232 */ - { int ret = r_vowel_suffix(z); - if (ret == 0) goto lab7; /* call vowel_suffix, line 232 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 232 */ + { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 232 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = z->l - m7; + z->c = z->l - m6; } z->c = z->lb; - { int c8 = z->c; /* do, line 234 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab8; /* call postlude, line 234 */ + { int c7 = z->c; /* do, line 234 */ + { int ret = r_postlude(z); /* call postlude, line 234 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: - z->c = c8; + z->c = c7; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c index be7feb752ee..fea26a66cf7 100644 --- a/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c +++ b/src/backend/snowball/libstemmer/stem_KOI8_R_russian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -340,20 +340,11 @@ static const struct among a_7[4] = static const unsigned char g_v[] = { 35, 130, 34, 18 }; -static const symbol s_0[] = { 0xC1 }; -static const symbol s_1[] = { 0xD1 }; -static const symbol s_2[] = { 0xC1 }; -static const symbol s_3[] = { 0xD1 }; -static const symbol s_4[] = { 0xC1 }; -static const symbol s_5[] = { 0xD1 }; -static const symbol s_6[] = { 0xCE }; -static const symbol s_7[] = { 0xCE }; -static const symbol s_8[] = { 0xCE }; -static const symbol s_9[] = { 0xC9 }; - -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; +static const symbol s_0[] = { 0xC5 }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 61 */ + z->I[1] = z->l; /* $p2 = , line 62 */ { int c1 = z->c; /* do, line 63 */ { /* gopast */ /* grouping v, line 64 */ int ret = out_grouping(z, g_v, 192, 220, 1); @@ -383,27 +374,28 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 71 */ return 1; } -static int r_perfective_gerund(struct SN_env * z) { +static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 74 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((25166336 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_0, 9); /* substring, line 74 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((25166336 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 74 */ + among_var = find_among_b(z, a_0, 9); if (!(among_var)) return 0; z->bra = z->c; /* ], line 74 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 74 */ case 1: { int m1 = z->l - z->c; (void)m1; /* or, line 78 */ - if (!(eq_s_b(z, 1, s_0))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; /* literal, line 78 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_1))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; /* literal, line 78 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 78 */ @@ -419,45 +411,38 @@ static int r_perfective_gerund(struct SN_env * z) { return 1; } -static int r_adjective(struct SN_env * z) { - int among_var; +static int r_adjective(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 90 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((2271009 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_1, 26); /* substring, line 90 */ - if (!(among_var)) return 0; + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((2271009 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 90 */ + if (!(find_among_b(z, a_1, 26))) return 0; z->bra = z->c; /* ], line 90 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 99 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 99 */ + if (ret < 0) return ret; } return 1; } -static int r_adjectival(struct SN_env * z) { +static int r_adjectival(struct SN_env * z) { /* backwardmode */ int among_var; - { int ret = r_adjective(z); - if (ret == 0) return 0; /* call adjective, line 104 */ - if (ret < 0) return ret; + { int ret = r_adjective(z); /* call adjective, line 104 */ + if (ret <= 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ z->ket = z->c; /* [, line 112 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((671113216 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; } - among_var = find_among_b(z, a_2, 8); /* substring, line 112 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((671113216 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + among_var = find_among_b(z, a_2, 8); + if (!(among_var)) { z->c = z->l - m1; goto lab0; } z->bra = z->c; /* ], line 112 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } + switch (among_var) { /* among, line 112 */ case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 117 */ - if (!(eq_s_b(z, 1, s_2))) goto lab2; + { int m2 = z->l - z->c; (void)m2; /* or, line 117 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab2; /* literal, line 117 */ + z->c--; goto lab1; lab2: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_3))) { z->c = z->l - m_keep; goto lab0; } + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) { z->c = z->l - m1; goto lab0; } /* literal, line 117 */ + z->c--; } lab1: { int ret = slice_del(z); /* delete, line 117 */ @@ -476,40 +461,34 @@ static int r_adjectival(struct SN_env * z) { return 1; } -static int r_reflexive(struct SN_env * z) { - int among_var; +static int r_reflexive(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 131 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 209 && z->p[z->c - 1] != 216)) return 0; - among_var = find_among_b(z, a_3, 2); /* substring, line 131 */ - if (!(among_var)) return 0; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 209 && z->p[z->c - 1] != 216)) return 0; /* substring, line 131 */ + if (!(find_among_b(z, a_3, 2))) return 0; z->bra = z->c; /* ], line 131 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 134 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; } return 1; } -static int r_verb(struct SN_env * z) { +static int r_verb(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 139 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((51443235 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_4, 46); /* substring, line 139 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((51443235 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 139 */ + among_var = find_among_b(z, a_4, 46); if (!(among_var)) return 0; z->bra = z->c; /* ], line 139 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 139 */ case 1: { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (!(eq_s_b(z, 1, s_4))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 0xC1) goto lab1; /* literal, line 145 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_5))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xD1) return 0; /* literal, line 145 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 145 */ @@ -525,69 +504,56 @@ static int r_verb(struct SN_env * z) { return 1; } -static int r_noun(struct SN_env * z) { - int among_var; +static int r_noun(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 162 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((60991267 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 36); /* substring, line 162 */ - if (!(among_var)) return 0; + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((60991267 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 162 */ + if (!(find_among_b(z, a_5, 36))) return 0; z->bra = z->c; /* ], line 162 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 169 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 169 */ + if (ret < 0) return ret; } return 1; } -static int r_derivational(struct SN_env * z) { - int among_var; +static int r_derivational(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 178 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 212 && z->p[z->c - 1] != 216)) return 0; - among_var = find_among_b(z, a_6, 2); /* substring, line 178 */ - if (!(among_var)) return 0; + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 212 && z->p[z->c - 1] != 216)) return 0; /* substring, line 178 */ + if (!(find_among_b(z, a_6, 2))) return 0; z->bra = z->c; /* ], line 178 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 178 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 178 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 181 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 181 */ + if (ret < 0) return ret; } return 1; } -static int r_tidy_up(struct SN_env * z) { +static int r_tidy_up(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 186 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((151011360 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_7, 4); /* substring, line 186 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 6 || !((151011360 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 186 */ + among_var = find_among_b(z, a_7, 4); if (!(among_var)) return 0; z->bra = z->c; /* ], line 186 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 186 */ case 1: { int ret = slice_del(z); /* delete, line 190 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 191 */ - if (!(eq_s_b(z, 1, s_6))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 191 */ + z->c--; z->bra = z->c; /* ], line 191 */ - if (!(eq_s_b(z, 1, s_7))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 191 */ + z->c--; { int ret = slice_del(z); /* delete, line 191 */ if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 1, s_8))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 0xCE) return 0; /* literal, line 194 */ + z->c--; { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } @@ -601,94 +567,117 @@ static int r_tidy_up(struct SN_env * z) { return 1; } -extern int russian_KOI8_R_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 203 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 203 */ - if (ret < 0) return ret; +extern int russian_KOI8_R_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 205 */ + while(1) { /* repeat, line 205 */ + int c2 = z->c; + while(1) { /* goto, line 205 */ + int c3 = z->c; + z->bra = z->c; /* [, line 205 */ + if (z->c == z->l || z->p[z->c] != 0xA3) goto lab2; /* literal, line 205 */ + z->c++; + z->ket = z->c; /* ], line 205 */ + z->c = c3; + break; + lab2: + z->c = c3; + if (z->c >= z->l) goto lab1; + z->c++; /* goto, line 205 */ + } + { int ret = slice_from_s(z, 1, s_0); /* <-, line 205 */ + if (ret < 0) return ret; + } + continue; + lab1: + z->c = c2; + break; } - lab0: z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 204 */ + /* do, line 207 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 207 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } +lab3: + z->lb = z->c; z->c = z->l; /* backwards, line 208 */ + - { int mlimit; /* setlimit, line 204 */ - int m2 = z->l - z->c; (void)m2; + { int mlimit4; /* setlimit, line 208 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 204 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - { int m3 = z->l - z->c; (void)m3; /* do, line 205 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 206 */ - { int ret = r_perfective_gerund(z); - if (ret == 0) goto lab3; /* call perfective_gerund, line 206 */ + mlimit4 = z->lb; z->lb = z->I[0]; + { int m5 = z->l - z->c; (void)m5; /* do, line 209 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 210 */ + { int ret = r_perfective_gerund(z); /* call perfective_gerund, line 210 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } - goto lab2; - lab3: - z->c = z->l - m4; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 207 */ - { int ret = r_reflexive(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call reflexive, line 207 */ + goto lab5; + lab6: + z->c = z->l - m6; + { int m7 = z->l - z->c; (void)m7; /* try, line 211 */ + { int ret = r_reflexive(z); /* call reflexive, line 211 */ + if (ret == 0) { z->c = z->l - m7; goto lab7; } if (ret < 0) return ret; } - lab4: + lab7: ; } - { int m5 = z->l - z->c; (void)m5; /* or, line 208 */ - { int ret = r_adjectival(z); - if (ret == 0) goto lab6; /* call adjectival, line 208 */ + { int m8 = z->l - z->c; (void)m8; /* or, line 212 */ + { int ret = r_adjectival(z); /* call adjectival, line 212 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } - goto lab5; - lab6: - z->c = z->l - m5; - { int ret = r_verb(z); - if (ret == 0) goto lab7; /* call verb, line 208 */ + goto lab8; + lab9: + z->c = z->l - m8; + { int ret = r_verb(z); /* call verb, line 212 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } - goto lab5; - lab7: - z->c = z->l - m5; - { int ret = r_noun(z); - if (ret == 0) goto lab1; /* call noun, line 208 */ + goto lab8; + lab10: + z->c = z->l - m8; + { int ret = r_noun(z); /* call noun, line 212 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } - lab5: + lab8: ; } - lab2: - lab1: - z->c = z->l - m3; + lab5: + lab4: + z->c = z->l - m5; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 211 */ - z->ket = z->c; /* [, line 211 */ - if (!(eq_s_b(z, 1, s_9))) { z->c = z->l - m_keep; goto lab8; } - z->bra = z->c; /* ], line 211 */ - { int ret = slice_del(z); /* delete, line 211 */ + { int m9 = z->l - z->c; (void)m9; /* try, line 215 */ + z->ket = z->c; /* [, line 215 */ + if (z->c <= z->lb || z->p[z->c - 1] != 0xC9) { z->c = z->l - m9; goto lab11; } /* literal, line 215 */ + z->c--; + z->bra = z->c; /* ], line 215 */ + { int ret = slice_del(z); /* delete, line 215 */ if (ret < 0) return ret; } - lab8: + lab11: ; } - { int m6 = z->l - z->c; (void)m6; /* do, line 214 */ - { int ret = r_derivational(z); - if (ret == 0) goto lab9; /* call derivational, line 214 */ + { int m10 = z->l - z->c; (void)m10; /* do, line 218 */ + { int ret = r_derivational(z); /* call derivational, line 218 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } - lab9: - z->c = z->l - m6; + lab12: + z->c = z->l - m10; } - { int m7 = z->l - z->c; (void)m7; /* do, line 215 */ - { int ret = r_tidy_up(z); - if (ret == 0) goto lab10; /* call tidy_up, line 215 */ + { int m11 = z->l - z->c; (void)m11; /* do, line 219 */ + { int ret = r_tidy_up(z); /* call tidy_up, line 219 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } - lab10: - z->c = z->l - m7; + lab13: + z->c = z->l - m11; } - z->lb = mlimit; + z->lb = mlimit4; } z->c = z->lb; return 1; diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c b/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c new file mode 100644 index 00000000000..30bf1d99642 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_arabic.c @@ -0,0 +1,1683 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int arabic_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_Checks1(struct SN_env * z); +static int r_Normalize_pre(struct SN_env * z); +static int r_Normalize_post(struct SN_env * z); +static int r_Suffix_Verb_Step2c(struct SN_env * z); +static int r_Suffix_Verb_Step2b(struct SN_env * z); +static int r_Suffix_Verb_Step2a(struct SN_env * z); +static int r_Suffix_Verb_Step1(struct SN_env * z); +static int r_Suffix_Noun_Step3(struct SN_env * z); +static int r_Suffix_Noun_Step2c2(struct SN_env * z); +static int r_Suffix_Noun_Step2c1(struct SN_env * z); +static int r_Suffix_Noun_Step2b(struct SN_env * z); +static int r_Suffix_Noun_Step2a(struct SN_env * z); +static int r_Suffix_Noun_Step1b(struct SN_env * z); +static int r_Suffix_Noun_Step1a(struct SN_env * z); +static int r_Suffix_All_alef_maqsura(struct SN_env * z); +static int r_Prefix_Step4_Verb(struct SN_env * z); +static int r_Prefix_Step3_Verb(struct SN_env * z); +static int r_Prefix_Step3b_Noun(struct SN_env * z); +static int r_Prefix_Step3a_Noun(struct SN_env * z); +static int r_Prefix_Step2(struct SN_env * z); +static int r_Prefix_Step1(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * arabic_UTF_8_create_env(void); +extern void arabic_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[2] = { 0xD9, 0x80 }; +static const symbol s_0_1[2] = { 0xD9, 0x8B }; +static const symbol s_0_2[2] = { 0xD9, 0x8C }; +static const symbol s_0_3[2] = { 0xD9, 0x8D }; +static const symbol s_0_4[2] = { 0xD9, 0x8E }; +static const symbol s_0_5[2] = { 0xD9, 0x8F }; +static const symbol s_0_6[2] = { 0xD9, 0x90 }; +static const symbol s_0_7[2] = { 0xD9, 0x91 }; +static const symbol s_0_8[2] = { 0xD9, 0x92 }; +static const symbol s_0_9[2] = { 0xD9, 0xA0 }; +static const symbol s_0_10[2] = { 0xD9, 0xA1 }; +static const symbol s_0_11[2] = { 0xD9, 0xA2 }; +static const symbol s_0_12[2] = { 0xD9, 0xA3 }; +static const symbol s_0_13[2] = { 0xD9, 0xA4 }; +static const symbol s_0_14[2] = { 0xD9, 0xA5 }; +static const symbol s_0_15[2] = { 0xD9, 0xA6 }; +static const symbol s_0_16[2] = { 0xD9, 0xA7 }; +static const symbol s_0_17[2] = { 0xD9, 0xA8 }; +static const symbol s_0_18[2] = { 0xD9, 0xA9 }; +static const symbol s_0_19[3] = { 0xEF, 0xBA, 0x80 }; +static const symbol s_0_20[3] = { 0xEF, 0xBA, 0x81 }; +static const symbol s_0_21[3] = { 0xEF, 0xBA, 0x82 }; +static const symbol s_0_22[3] = { 0xEF, 0xBA, 0x83 }; +static const symbol s_0_23[3] = { 0xEF, 0xBA, 0x84 }; +static const symbol s_0_24[3] = { 0xEF, 0xBA, 0x85 }; +static const symbol s_0_25[3] = { 0xEF, 0xBA, 0x86 }; +static const symbol s_0_26[3] = { 0xEF, 0xBA, 0x87 }; +static const symbol s_0_27[3] = { 0xEF, 0xBA, 0x88 }; +static const symbol s_0_28[3] = { 0xEF, 0xBA, 0x89 }; +static const symbol s_0_29[3] = { 0xEF, 0xBA, 0x8A }; +static const symbol s_0_30[3] = { 0xEF, 0xBA, 0x8B }; +static const symbol s_0_31[3] = { 0xEF, 0xBA, 0x8C }; +static const symbol s_0_32[3] = { 0xEF, 0xBA, 0x8D }; +static const symbol s_0_33[3] = { 0xEF, 0xBA, 0x8E }; +static const symbol s_0_34[3] = { 0xEF, 0xBA, 0x8F }; +static const symbol s_0_35[3] = { 0xEF, 0xBA, 0x90 }; +static const symbol s_0_36[3] = { 0xEF, 0xBA, 0x91 }; +static const symbol s_0_37[3] = { 0xEF, 0xBA, 0x92 }; +static const symbol s_0_38[3] = { 0xEF, 0xBA, 0x93 }; +static const symbol s_0_39[3] = { 0xEF, 0xBA, 0x94 }; +static const symbol s_0_40[3] = { 0xEF, 0xBA, 0x95 }; +static const symbol s_0_41[3] = { 0xEF, 0xBA, 0x96 }; +static const symbol s_0_42[3] = { 0xEF, 0xBA, 0x97 }; +static const symbol s_0_43[3] = { 0xEF, 0xBA, 0x98 }; +static const symbol s_0_44[3] = { 0xEF, 0xBA, 0x99 }; +static const symbol s_0_45[3] = { 0xEF, 0xBA, 0x9A }; +static const symbol s_0_46[3] = { 0xEF, 0xBA, 0x9B }; +static const symbol s_0_47[3] = { 0xEF, 0xBA, 0x9C }; +static const symbol s_0_48[3] = { 0xEF, 0xBA, 0x9D }; +static const symbol s_0_49[3] = { 0xEF, 0xBA, 0x9E }; +static const symbol s_0_50[3] = { 0xEF, 0xBA, 0x9F }; +static const symbol s_0_51[3] = { 0xEF, 0xBA, 0xA0 }; +static const symbol s_0_52[3] = { 0xEF, 0xBA, 0xA1 }; +static const symbol s_0_53[3] = { 0xEF, 0xBA, 0xA2 }; +static const symbol s_0_54[3] = { 0xEF, 0xBA, 0xA3 }; +static const symbol s_0_55[3] = { 0xEF, 0xBA, 0xA4 }; +static const symbol s_0_56[3] = { 0xEF, 0xBA, 0xA5 }; +static const symbol s_0_57[3] = { 0xEF, 0xBA, 0xA6 }; +static const symbol s_0_58[3] = { 0xEF, 0xBA, 0xA7 }; +static const symbol s_0_59[3] = { 0xEF, 0xBA, 0xA8 }; +static const symbol s_0_60[3] = { 0xEF, 0xBA, 0xA9 }; +static const symbol s_0_61[3] = { 0xEF, 0xBA, 0xAA }; +static const symbol s_0_62[3] = { 0xEF, 0xBA, 0xAB }; +static const symbol s_0_63[3] = { 0xEF, 0xBA, 0xAC }; +static const symbol s_0_64[3] = { 0xEF, 0xBA, 0xAD }; +static const symbol s_0_65[3] = { 0xEF, 0xBA, 0xAE }; +static const symbol s_0_66[3] = { 0xEF, 0xBA, 0xAF }; +static const symbol s_0_67[3] = { 0xEF, 0xBA, 0xB0 }; +static const symbol s_0_68[3] = { 0xEF, 0xBA, 0xB1 }; +static const symbol s_0_69[3] = { 0xEF, 0xBA, 0xB2 }; +static const symbol s_0_70[3] = { 0xEF, 0xBA, 0xB3 }; +static const symbol s_0_71[3] = { 0xEF, 0xBA, 0xB4 }; +static const symbol s_0_72[3] = { 0xEF, 0xBA, 0xB5 }; +static const symbol s_0_73[3] = { 0xEF, 0xBA, 0xB6 }; +static const symbol s_0_74[3] = { 0xEF, 0xBA, 0xB7 }; +static const symbol s_0_75[3] = { 0xEF, 0xBA, 0xB8 }; +static const symbol s_0_76[3] = { 0xEF, 0xBA, 0xB9 }; +static const symbol s_0_77[3] = { 0xEF, 0xBA, 0xBA }; +static const symbol s_0_78[3] = { 0xEF, 0xBA, 0xBB }; +static const symbol s_0_79[3] = { 0xEF, 0xBA, 0xBC }; +static const symbol s_0_80[3] = { 0xEF, 0xBA, 0xBD }; +static const symbol s_0_81[3] = { 0xEF, 0xBA, 0xBE }; +static const symbol s_0_82[3] = { 0xEF, 0xBA, 0xBF }; +static const symbol s_0_83[3] = { 0xEF, 0xBB, 0x80 }; +static const symbol s_0_84[3] = { 0xEF, 0xBB, 0x81 }; +static const symbol s_0_85[3] = { 0xEF, 0xBB, 0x82 }; +static const symbol s_0_86[3] = { 0xEF, 0xBB, 0x83 }; +static const symbol s_0_87[3] = { 0xEF, 0xBB, 0x84 }; +static const symbol s_0_88[3] = { 0xEF, 0xBB, 0x85 }; +static const symbol s_0_89[3] = { 0xEF, 0xBB, 0x86 }; +static const symbol s_0_90[3] = { 0xEF, 0xBB, 0x87 }; +static const symbol s_0_91[3] = { 0xEF, 0xBB, 0x88 }; +static const symbol s_0_92[3] = { 0xEF, 0xBB, 0x89 }; +static const symbol s_0_93[3] = { 0xEF, 0xBB, 0x8A }; +static const symbol s_0_94[3] = { 0xEF, 0xBB, 0x8B }; +static const symbol s_0_95[3] = { 0xEF, 0xBB, 0x8C }; +static const symbol s_0_96[3] = { 0xEF, 0xBB, 0x8D }; +static const symbol s_0_97[3] = { 0xEF, 0xBB, 0x8E }; +static const symbol s_0_98[3] = { 0xEF, 0xBB, 0x8F }; +static const symbol s_0_99[3] = { 0xEF, 0xBB, 0x90 }; +static const symbol s_0_100[3] = { 0xEF, 0xBB, 0x91 }; +static const symbol s_0_101[3] = { 0xEF, 0xBB, 0x92 }; +static const symbol s_0_102[3] = { 0xEF, 0xBB, 0x93 }; +static const symbol s_0_103[3] = { 0xEF, 0xBB, 0x94 }; +static const symbol s_0_104[3] = { 0xEF, 0xBB, 0x95 }; +static const symbol s_0_105[3] = { 0xEF, 0xBB, 0x96 }; +static const symbol s_0_106[3] = { 0xEF, 0xBB, 0x97 }; +static const symbol s_0_107[3] = { 0xEF, 0xBB, 0x98 }; +static const symbol s_0_108[3] = { 0xEF, 0xBB, 0x99 }; +static const symbol s_0_109[3] = { 0xEF, 0xBB, 0x9A }; +static const symbol s_0_110[3] = { 0xEF, 0xBB, 0x9B }; +static const symbol s_0_111[3] = { 0xEF, 0xBB, 0x9C }; +static const symbol s_0_112[3] = { 0xEF, 0xBB, 0x9D }; +static const symbol s_0_113[3] = { 0xEF, 0xBB, 0x9E }; +static const symbol s_0_114[3] = { 0xEF, 0xBB, 0x9F }; +static const symbol s_0_115[3] = { 0xEF, 0xBB, 0xA0 }; +static const symbol s_0_116[3] = { 0xEF, 0xBB, 0xA1 }; +static const symbol s_0_117[3] = { 0xEF, 0xBB, 0xA2 }; +static const symbol s_0_118[3] = { 0xEF, 0xBB, 0xA3 }; +static const symbol s_0_119[3] = { 0xEF, 0xBB, 0xA4 }; +static const symbol s_0_120[3] = { 0xEF, 0xBB, 0xA5 }; +static const symbol s_0_121[3] = { 0xEF, 0xBB, 0xA6 }; +static const symbol s_0_122[3] = { 0xEF, 0xBB, 0xA7 }; +static const symbol s_0_123[3] = { 0xEF, 0xBB, 0xA8 }; +static const symbol s_0_124[3] = { 0xEF, 0xBB, 0xA9 }; +static const symbol s_0_125[3] = { 0xEF, 0xBB, 0xAA }; +static const symbol s_0_126[3] = { 0xEF, 0xBB, 0xAB }; +static const symbol s_0_127[3] = { 0xEF, 0xBB, 0xAC }; +static const symbol s_0_128[3] = { 0xEF, 0xBB, 0xAD }; +static const symbol s_0_129[3] = { 0xEF, 0xBB, 0xAE }; +static const symbol s_0_130[3] = { 0xEF, 0xBB, 0xAF }; +static const symbol s_0_131[3] = { 0xEF, 0xBB, 0xB0 }; +static const symbol s_0_132[3] = { 0xEF, 0xBB, 0xB1 }; +static const symbol s_0_133[3] = { 0xEF, 0xBB, 0xB2 }; +static const symbol s_0_134[3] = { 0xEF, 0xBB, 0xB3 }; +static const symbol s_0_135[3] = { 0xEF, 0xBB, 0xB4 }; +static const symbol s_0_136[3] = { 0xEF, 0xBB, 0xB5 }; +static const symbol s_0_137[3] = { 0xEF, 0xBB, 0xB6 }; +static const symbol s_0_138[3] = { 0xEF, 0xBB, 0xB7 }; +static const symbol s_0_139[3] = { 0xEF, 0xBB, 0xB8 }; +static const symbol s_0_140[3] = { 0xEF, 0xBB, 0xB9 }; +static const symbol s_0_141[3] = { 0xEF, 0xBB, 0xBA }; +static const symbol s_0_142[3] = { 0xEF, 0xBB, 0xBB }; +static const symbol s_0_143[3] = { 0xEF, 0xBB, 0xBC }; + +static const struct among a_0[144] = +{ +/* 0 */ { 2, s_0_0, -1, 1, 0}, +/* 1 */ { 2, s_0_1, -1, 1, 0}, +/* 2 */ { 2, s_0_2, -1, 1, 0}, +/* 3 */ { 2, s_0_3, -1, 1, 0}, +/* 4 */ { 2, s_0_4, -1, 1, 0}, +/* 5 */ { 2, s_0_5, -1, 1, 0}, +/* 6 */ { 2, s_0_6, -1, 1, 0}, +/* 7 */ { 2, s_0_7, -1, 1, 0}, +/* 8 */ { 2, s_0_8, -1, 1, 0}, +/* 9 */ { 2, s_0_9, -1, 2, 0}, +/* 10 */ { 2, s_0_10, -1, 3, 0}, +/* 11 */ { 2, s_0_11, -1, 4, 0}, +/* 12 */ { 2, s_0_12, -1, 5, 0}, +/* 13 */ { 2, s_0_13, -1, 6, 0}, +/* 14 */ { 2, s_0_14, -1, 7, 0}, +/* 15 */ { 2, s_0_15, -1, 8, 0}, +/* 16 */ { 2, s_0_16, -1, 9, 0}, +/* 17 */ { 2, s_0_17, -1, 10, 0}, +/* 18 */ { 2, s_0_18, -1, 11, 0}, +/* 19 */ { 3, s_0_19, -1, 12, 0}, +/* 20 */ { 3, s_0_20, -1, 16, 0}, +/* 21 */ { 3, s_0_21, -1, 16, 0}, +/* 22 */ { 3, s_0_22, -1, 13, 0}, +/* 23 */ { 3, s_0_23, -1, 13, 0}, +/* 24 */ { 3, s_0_24, -1, 17, 0}, +/* 25 */ { 3, s_0_25, -1, 17, 0}, +/* 26 */ { 3, s_0_26, -1, 14, 0}, +/* 27 */ { 3, s_0_27, -1, 14, 0}, +/* 28 */ { 3, s_0_28, -1, 15, 0}, +/* 29 */ { 3, s_0_29, -1, 15, 0}, +/* 30 */ { 3, s_0_30, -1, 15, 0}, +/* 31 */ { 3, s_0_31, -1, 15, 0}, +/* 32 */ { 3, s_0_32, -1, 18, 0}, +/* 33 */ { 3, s_0_33, -1, 18, 0}, +/* 34 */ { 3, s_0_34, -1, 19, 0}, +/* 35 */ { 3, s_0_35, -1, 19, 0}, +/* 36 */ { 3, s_0_36, -1, 19, 0}, +/* 37 */ { 3, s_0_37, -1, 19, 0}, +/* 38 */ { 3, s_0_38, -1, 20, 0}, +/* 39 */ { 3, s_0_39, -1, 20, 0}, +/* 40 */ { 3, s_0_40, -1, 21, 0}, +/* 41 */ { 3, s_0_41, -1, 21, 0}, +/* 42 */ { 3, s_0_42, -1, 21, 0}, +/* 43 */ { 3, s_0_43, -1, 21, 0}, +/* 44 */ { 3, s_0_44, -1, 22, 0}, +/* 45 */ { 3, s_0_45, -1, 22, 0}, +/* 46 */ { 3, s_0_46, -1, 22, 0}, +/* 47 */ { 3, s_0_47, -1, 22, 0}, +/* 48 */ { 3, s_0_48, -1, 23, 0}, +/* 49 */ { 3, s_0_49, -1, 23, 0}, +/* 50 */ { 3, s_0_50, -1, 23, 0}, +/* 51 */ { 3, s_0_51, -1, 23, 0}, +/* 52 */ { 3, s_0_52, -1, 24, 0}, +/* 53 */ { 3, s_0_53, -1, 24, 0}, +/* 54 */ { 3, s_0_54, -1, 24, 0}, +/* 55 */ { 3, s_0_55, -1, 24, 0}, +/* 56 */ { 3, s_0_56, -1, 25, 0}, +/* 57 */ { 3, s_0_57, -1, 25, 0}, +/* 58 */ { 3, s_0_58, -1, 25, 0}, +/* 59 */ { 3, s_0_59, -1, 25, 0}, +/* 60 */ { 3, s_0_60, -1, 26, 0}, +/* 61 */ { 3, s_0_61, -1, 26, 0}, +/* 62 */ { 3, s_0_62, -1, 27, 0}, +/* 63 */ { 3, s_0_63, -1, 27, 0}, +/* 64 */ { 3, s_0_64, -1, 28, 0}, +/* 65 */ { 3, s_0_65, -1, 28, 0}, +/* 66 */ { 3, s_0_66, -1, 29, 0}, +/* 67 */ { 3, s_0_67, -1, 29, 0}, +/* 68 */ { 3, s_0_68, -1, 30, 0}, +/* 69 */ { 3, s_0_69, -1, 30, 0}, +/* 70 */ { 3, s_0_70, -1, 30, 0}, +/* 71 */ { 3, s_0_71, -1, 30, 0}, +/* 72 */ { 3, s_0_72, -1, 31, 0}, +/* 73 */ { 3, s_0_73, -1, 31, 0}, +/* 74 */ { 3, s_0_74, -1, 31, 0}, +/* 75 */ { 3, s_0_75, -1, 31, 0}, +/* 76 */ { 3, s_0_76, -1, 32, 0}, +/* 77 */ { 3, s_0_77, -1, 32, 0}, +/* 78 */ { 3, s_0_78, -1, 32, 0}, +/* 79 */ { 3, s_0_79, -1, 32, 0}, +/* 80 */ { 3, s_0_80, -1, 33, 0}, +/* 81 */ { 3, s_0_81, -1, 33, 0}, +/* 82 */ { 3, s_0_82, -1, 33, 0}, +/* 83 */ { 3, s_0_83, -1, 33, 0}, +/* 84 */ { 3, s_0_84, -1, 34, 0}, +/* 85 */ { 3, s_0_85, -1, 34, 0}, +/* 86 */ { 3, s_0_86, -1, 34, 0}, +/* 87 */ { 3, s_0_87, -1, 34, 0}, +/* 88 */ { 3, s_0_88, -1, 35, 0}, +/* 89 */ { 3, s_0_89, -1, 35, 0}, +/* 90 */ { 3, s_0_90, -1, 35, 0}, +/* 91 */ { 3, s_0_91, -1, 35, 0}, +/* 92 */ { 3, s_0_92, -1, 36, 0}, +/* 93 */ { 3, s_0_93, -1, 36, 0}, +/* 94 */ { 3, s_0_94, -1, 36, 0}, +/* 95 */ { 3, s_0_95, -1, 36, 0}, +/* 96 */ { 3, s_0_96, -1, 37, 0}, +/* 97 */ { 3, s_0_97, -1, 37, 0}, +/* 98 */ { 3, s_0_98, -1, 37, 0}, +/* 99 */ { 3, s_0_99, -1, 37, 0}, +/*100 */ { 3, s_0_100, -1, 38, 0}, +/*101 */ { 3, s_0_101, -1, 38, 0}, +/*102 */ { 3, s_0_102, -1, 38, 0}, +/*103 */ { 3, s_0_103, -1, 38, 0}, +/*104 */ { 3, s_0_104, -1, 39, 0}, +/*105 */ { 3, s_0_105, -1, 39, 0}, +/*106 */ { 3, s_0_106, -1, 39, 0}, +/*107 */ { 3, s_0_107, -1, 39, 0}, +/*108 */ { 3, s_0_108, -1, 40, 0}, +/*109 */ { 3, s_0_109, -1, 40, 0}, +/*110 */ { 3, s_0_110, -1, 40, 0}, +/*111 */ { 3, s_0_111, -1, 40, 0}, +/*112 */ { 3, s_0_112, -1, 41, 0}, +/*113 */ { 3, s_0_113, -1, 41, 0}, +/*114 */ { 3, s_0_114, -1, 41, 0}, +/*115 */ { 3, s_0_115, -1, 41, 0}, +/*116 */ { 3, s_0_116, -1, 42, 0}, +/*117 */ { 3, s_0_117, -1, 42, 0}, +/*118 */ { 3, s_0_118, -1, 42, 0}, +/*119 */ { 3, s_0_119, -1, 42, 0}, +/*120 */ { 3, s_0_120, -1, 43, 0}, +/*121 */ { 3, s_0_121, -1, 43, 0}, +/*122 */ { 3, s_0_122, -1, 43, 0}, +/*123 */ { 3, s_0_123, -1, 43, 0}, +/*124 */ { 3, s_0_124, -1, 44, 0}, +/*125 */ { 3, s_0_125, -1, 44, 0}, +/*126 */ { 3, s_0_126, -1, 44, 0}, +/*127 */ { 3, s_0_127, -1, 44, 0}, +/*128 */ { 3, s_0_128, -1, 45, 0}, +/*129 */ { 3, s_0_129, -1, 45, 0}, +/*130 */ { 3, s_0_130, -1, 46, 0}, +/*131 */ { 3, s_0_131, -1, 46, 0}, +/*132 */ { 3, s_0_132, -1, 47, 0}, +/*133 */ { 3, s_0_133, -1, 47, 0}, +/*134 */ { 3, s_0_134, -1, 47, 0}, +/*135 */ { 3, s_0_135, -1, 47, 0}, +/*136 */ { 3, s_0_136, -1, 51, 0}, +/*137 */ { 3, s_0_137, -1, 51, 0}, +/*138 */ { 3, s_0_138, -1, 49, 0}, +/*139 */ { 3, s_0_139, -1, 49, 0}, +/*140 */ { 3, s_0_140, -1, 50, 0}, +/*141 */ { 3, s_0_141, -1, 50, 0}, +/*142 */ { 3, s_0_142, -1, 48, 0}, +/*143 */ { 3, s_0_143, -1, 48, 0} +}; + +static const symbol s_1_0[2] = { 0xD8, 0xA2 }; +static const symbol s_1_1[2] = { 0xD8, 0xA3 }; +static const symbol s_1_2[2] = { 0xD8, 0xA4 }; +static const symbol s_1_3[2] = { 0xD8, 0xA5 }; +static const symbol s_1_4[2] = { 0xD8, 0xA6 }; + +static const struct among a_1[5] = +{ +/* 0 */ { 2, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 3 */ { 2, s_1_3, -1, 1, 0}, +/* 4 */ { 2, s_1_4, -1, 1, 0} +}; + +static const symbol s_2_0[2] = { 0xD8, 0xA2 }; +static const symbol s_2_1[2] = { 0xD8, 0xA3 }; +static const symbol s_2_2[2] = { 0xD8, 0xA4 }; +static const symbol s_2_3[2] = { 0xD8, 0xA5 }; +static const symbol s_2_4[2] = { 0xD8, 0xA6 }; + +static const struct among a_2[5] = +{ +/* 0 */ { 2, s_2_0, -1, 1, 0}, +/* 1 */ { 2, s_2_1, -1, 1, 0}, +/* 2 */ { 2, s_2_2, -1, 2, 0}, +/* 3 */ { 2, s_2_3, -1, 1, 0}, +/* 4 */ { 2, s_2_4, -1, 3, 0} +}; + +static const symbol s_3_0[4] = { 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_3_1[6] = { 0xD8, 0xA8, 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_3_2[6] = { 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_3_3[4] = { 0xD9, 0x84, 0xD9, 0x84 }; + +static const struct among a_3[4] = +{ +/* 0 */ { 4, s_3_0, -1, 2, 0}, +/* 1 */ { 6, s_3_1, -1, 1, 0}, +/* 2 */ { 6, s_3_2, -1, 1, 0}, +/* 3 */ { 4, s_3_3, -1, 2, 0} +}; + +static const symbol s_4_0[4] = { 0xD8, 0xA3, 0xD8, 0xA2 }; +static const symbol s_4_1[4] = { 0xD8, 0xA3, 0xD8, 0xA3 }; +static const symbol s_4_2[4] = { 0xD8, 0xA3, 0xD8, 0xA4 }; +static const symbol s_4_3[4] = { 0xD8, 0xA3, 0xD8, 0xA5 }; +static const symbol s_4_4[4] = { 0xD8, 0xA3, 0xD8, 0xA7 }; + +static const struct among a_4[5] = +{ +/* 0 */ { 4, s_4_0, -1, 2, 0}, +/* 1 */ { 4, s_4_1, -1, 1, 0}, +/* 2 */ { 4, s_4_2, -1, 1, 0}, +/* 3 */ { 4, s_4_3, -1, 4, 0}, +/* 4 */ { 4, s_4_4, -1, 3, 0} +}; + +static const symbol s_5_0[2] = { 0xD9, 0x81 }; +static const symbol s_5_1[2] = { 0xD9, 0x88 }; + +static const struct among a_5[2] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 2, s_5_1, -1, 1, 0} +}; + +static const symbol s_6_0[4] = { 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_6_1[6] = { 0xD8, 0xA8, 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_6_2[6] = { 0xD9, 0x83, 0xD8, 0xA7, 0xD9, 0x84 }; +static const symbol s_6_3[4] = { 0xD9, 0x84, 0xD9, 0x84 }; + +static const struct among a_6[4] = +{ +/* 0 */ { 4, s_6_0, -1, 2, 0}, +/* 1 */ { 6, s_6_1, -1, 1, 0}, +/* 2 */ { 6, s_6_2, -1, 1, 0}, +/* 3 */ { 4, s_6_3, -1, 2, 0} +}; + +static const symbol s_7_0[2] = { 0xD8, 0xA8 }; +static const symbol s_7_1[4] = { 0xD8, 0xA8, 0xD8, 0xA8 }; +static const symbol s_7_2[4] = { 0xD9, 0x83, 0xD9, 0x83 }; + +static const struct among a_7[3] = +{ +/* 0 */ { 2, s_7_0, -1, 1, 0}, +/* 1 */ { 4, s_7_1, 0, 2, 0}, +/* 2 */ { 4, s_7_2, -1, 3, 0} +}; + +static const symbol s_8_0[4] = { 0xD8, 0xB3, 0xD8, 0xA3 }; +static const symbol s_8_1[4] = { 0xD8, 0xB3, 0xD8, 0xAA }; +static const symbol s_8_2[4] = { 0xD8, 0xB3, 0xD9, 0x86 }; +static const symbol s_8_3[4] = { 0xD8, 0xB3, 0xD9, 0x8A }; + +static const struct among a_8[4] = +{ +/* 0 */ { 4, s_8_0, -1, 4, 0}, +/* 1 */ { 4, s_8_1, -1, 2, 0}, +/* 2 */ { 4, s_8_2, -1, 3, 0}, +/* 3 */ { 4, s_8_3, -1, 1, 0} +}; + +static const symbol s_9_0[6] = { 0xD8, 0xAA, 0xD8, 0xB3, 0xD8, 0xAA }; +static const symbol s_9_1[6] = { 0xD9, 0x86, 0xD8, 0xB3, 0xD8, 0xAA }; +static const symbol s_9_2[6] = { 0xD9, 0x8A, 0xD8, 0xB3, 0xD8, 0xAA }; + +static const struct among a_9[3] = +{ +/* 0 */ { 6, s_9_0, -1, 1, 0}, +/* 1 */ { 6, s_9_1, -1, 1, 0}, +/* 2 */ { 6, s_9_2, -1, 1, 0} +}; + +static const symbol s_10_0[2] = { 0xD9, 0x83 }; +static const symbol s_10_1[4] = { 0xD9, 0x83, 0xD9, 0x85 }; +static const symbol s_10_2[4] = { 0xD9, 0x87, 0xD9, 0x85 }; +static const symbol s_10_3[4] = { 0xD9, 0x87, 0xD9, 0x86 }; +static const symbol s_10_4[2] = { 0xD9, 0x87 }; +static const symbol s_10_5[2] = { 0xD9, 0x8A }; +static const symbol s_10_6[6] = { 0xD9, 0x83, 0xD9, 0x85, 0xD8, 0xA7 }; +static const symbol s_10_7[6] = { 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xA7 }; +static const symbol s_10_8[4] = { 0xD9, 0x86, 0xD8, 0xA7 }; +static const symbol s_10_9[4] = { 0xD9, 0x87, 0xD8, 0xA7 }; + +static const struct among a_10[10] = +{ +/* 0 */ { 2, s_10_0, -1, 1, 0}, +/* 1 */ { 4, s_10_1, -1, 2, 0}, +/* 2 */ { 4, s_10_2, -1, 2, 0}, +/* 3 */ { 4, s_10_3, -1, 2, 0}, +/* 4 */ { 2, s_10_4, -1, 1, 0}, +/* 5 */ { 2, s_10_5, -1, 1, 0}, +/* 6 */ { 6, s_10_6, -1, 3, 0}, +/* 7 */ { 6, s_10_7, -1, 3, 0}, +/* 8 */ { 4, s_10_8, -1, 2, 0}, +/* 9 */ { 4, s_10_9, -1, 2, 0} +}; + +static const symbol s_11_0[2] = { 0xD9, 0x86 }; + +static const struct among a_11[1] = +{ +/* 0 */ { 2, s_11_0, -1, 1, 0} +}; + +static const symbol s_12_0[2] = { 0xD9, 0x88 }; +static const symbol s_12_1[2] = { 0xD9, 0x8A }; +static const symbol s_12_2[2] = { 0xD8, 0xA7 }; + +static const struct among a_12[3] = +{ +/* 0 */ { 2, s_12_0, -1, 1, 0}, +/* 1 */ { 2, s_12_1, -1, 1, 0}, +/* 2 */ { 2, s_12_2, -1, 1, 0} +}; + +static const symbol s_13_0[4] = { 0xD8, 0xA7, 0xD8, 0xAA }; + +static const struct among a_13[1] = +{ +/* 0 */ { 4, s_13_0, -1, 1, 0} +}; + +static const symbol s_14_0[2] = { 0xD8, 0xAA }; + +static const struct among a_14[1] = +{ +/* 0 */ { 2, s_14_0, -1, 1, 0} +}; + +static const symbol s_15_0[2] = { 0xD8, 0xA9 }; + +static const struct among a_15[1] = +{ +/* 0 */ { 2, s_15_0, -1, 1, 0} +}; + +static const symbol s_16_0[2] = { 0xD9, 0x8A }; + +static const struct among a_16[1] = +{ +/* 0 */ { 2, s_16_0, -1, 1, 0} +}; + +static const symbol s_17_0[2] = { 0xD9, 0x83 }; +static const symbol s_17_1[4] = { 0xD9, 0x83, 0xD9, 0x85 }; +static const symbol s_17_2[4] = { 0xD9, 0x87, 0xD9, 0x85 }; +static const symbol s_17_3[4] = { 0xD9, 0x83, 0xD9, 0x86 }; +static const symbol s_17_4[4] = { 0xD9, 0x87, 0xD9, 0x86 }; +static const symbol s_17_5[2] = { 0xD9, 0x87 }; +static const symbol s_17_6[6] = { 0xD9, 0x83, 0xD9, 0x85, 0xD9, 0x88 }; +static const symbol s_17_7[4] = { 0xD9, 0x86, 0xD9, 0x8A }; +static const symbol s_17_8[6] = { 0xD9, 0x83, 0xD9, 0x85, 0xD8, 0xA7 }; +static const symbol s_17_9[6] = { 0xD9, 0x87, 0xD9, 0x85, 0xD8, 0xA7 }; +static const symbol s_17_10[4] = { 0xD9, 0x86, 0xD8, 0xA7 }; +static const symbol s_17_11[4] = { 0xD9, 0x87, 0xD8, 0xA7 }; + +static const struct among a_17[12] = +{ +/* 0 */ { 2, s_17_0, -1, 1, 0}, +/* 1 */ { 4, s_17_1, -1, 2, 0}, +/* 2 */ { 4, s_17_2, -1, 2, 0}, +/* 3 */ { 4, s_17_3, -1, 2, 0}, +/* 4 */ { 4, s_17_4, -1, 2, 0}, +/* 5 */ { 2, s_17_5, -1, 1, 0}, +/* 6 */ { 6, s_17_6, -1, 3, 0}, +/* 7 */ { 4, s_17_7, -1, 2, 0}, +/* 8 */ { 6, s_17_8, -1, 3, 0}, +/* 9 */ { 6, s_17_9, -1, 3, 0}, +/* 10 */ { 4, s_17_10, -1, 2, 0}, +/* 11 */ { 4, s_17_11, -1, 2, 0} +}; + +static const symbol s_18_0[2] = { 0xD9, 0x86 }; +static const symbol s_18_1[4] = { 0xD9, 0x88, 0xD9, 0x86 }; +static const symbol s_18_2[4] = { 0xD9, 0x8A, 0xD9, 0x86 }; +static const symbol s_18_3[4] = { 0xD8, 0xA7, 0xD9, 0x86 }; +static const symbol s_18_4[4] = { 0xD8, 0xAA, 0xD9, 0x86 }; +static const symbol s_18_5[2] = { 0xD9, 0x8A }; +static const symbol s_18_6[2] = { 0xD8, 0xA7 }; +static const symbol s_18_7[6] = { 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xA7 }; +static const symbol s_18_8[4] = { 0xD9, 0x86, 0xD8, 0xA7 }; +static const symbol s_18_9[4] = { 0xD8, 0xAA, 0xD8, 0xA7 }; +static const symbol s_18_10[2] = { 0xD8, 0xAA }; + +static const struct among a_18[11] = +{ +/* 0 */ { 2, s_18_0, -1, 1, 0}, +/* 1 */ { 4, s_18_1, 0, 3, 0}, +/* 2 */ { 4, s_18_2, 0, 3, 0}, +/* 3 */ { 4, s_18_3, 0, 3, 0}, +/* 4 */ { 4, s_18_4, 0, 2, 0}, +/* 5 */ { 2, s_18_5, -1, 1, 0}, +/* 6 */ { 2, s_18_6, -1, 1, 0}, +/* 7 */ { 6, s_18_7, 6, 4, 0}, +/* 8 */ { 4, s_18_8, 6, 2, 0}, +/* 9 */ { 4, s_18_9, 6, 2, 0}, +/* 10 */ { 2, s_18_10, -1, 1, 0} +}; + +static const symbol s_19_0[4] = { 0xD8, 0xAA, 0xD9, 0x85 }; +static const symbol s_19_1[4] = { 0xD9, 0x88, 0xD8, 0xA7 }; + +static const struct among a_19[2] = +{ +/* 0 */ { 4, s_19_0, -1, 1, 0}, +/* 1 */ { 4, s_19_1, -1, 1, 0} +}; + +static const symbol s_20_0[2] = { 0xD9, 0x88 }; +static const symbol s_20_1[6] = { 0xD8, 0xAA, 0xD9, 0x85, 0xD9, 0x88 }; + +static const struct among a_20[2] = +{ +/* 0 */ { 2, s_20_0, -1, 1, 0}, +/* 1 */ { 6, s_20_1, 0, 2, 0} +}; + +static const symbol s_21_0[2] = { 0xD9, 0x89 }; + +static const struct among a_21[1] = +{ +/* 0 */ { 2, s_21_0, -1, 1, 0} +}; + +static const symbol s_0[] = { '0' }; +static const symbol s_1[] = { '1' }; +static const symbol s_2[] = { '2' }; +static const symbol s_3[] = { '3' }; +static const symbol s_4[] = { '4' }; +static const symbol s_5[] = { '5' }; +static const symbol s_6[] = { '6' }; +static const symbol s_7[] = { '7' }; +static const symbol s_8[] = { '8' }; +static const symbol s_9[] = { '9' }; +static const symbol s_10[] = { 0xD8, 0xA1 }; +static const symbol s_11[] = { 0xD8, 0xA3 }; +static const symbol s_12[] = { 0xD8, 0xA5 }; +static const symbol s_13[] = { 0xD8, 0xA6 }; +static const symbol s_14[] = { 0xD8, 0xA2 }; +static const symbol s_15[] = { 0xD8, 0xA4 }; +static const symbol s_16[] = { 0xD8, 0xA7 }; +static const symbol s_17[] = { 0xD8, 0xA8 }; +static const symbol s_18[] = { 0xD8, 0xA9 }; +static const symbol s_19[] = { 0xD8, 0xAA }; +static const symbol s_20[] = { 0xD8, 0xAB }; +static const symbol s_21[] = { 0xD8, 0xAC }; +static const symbol s_22[] = { 0xD8, 0xAD }; +static const symbol s_23[] = { 0xD8, 0xAE }; +static const symbol s_24[] = { 0xD8, 0xAF }; +static const symbol s_25[] = { 0xD8, 0xB0 }; +static const symbol s_26[] = { 0xD8, 0xB1 }; +static const symbol s_27[] = { 0xD8, 0xB2 }; +static const symbol s_28[] = { 0xD8, 0xB3 }; +static const symbol s_29[] = { 0xD8, 0xB4 }; +static const symbol s_30[] = { 0xD8, 0xB5 }; +static const symbol s_31[] = { 0xD8, 0xB6 }; +static const symbol s_32[] = { 0xD8, 0xB7 }; +static const symbol s_33[] = { 0xD8, 0xB8 }; +static const symbol s_34[] = { 0xD8, 0xB9 }; +static const symbol s_35[] = { 0xD8, 0xBA }; +static const symbol s_36[] = { 0xD9, 0x81 }; +static const symbol s_37[] = { 0xD9, 0x82 }; +static const symbol s_38[] = { 0xD9, 0x83 }; +static const symbol s_39[] = { 0xD9, 0x84 }; +static const symbol s_40[] = { 0xD9, 0x85 }; +static const symbol s_41[] = { 0xD9, 0x86 }; +static const symbol s_42[] = { 0xD9, 0x87 }; +static const symbol s_43[] = { 0xD9, 0x88 }; +static const symbol s_44[] = { 0xD9, 0x89 }; +static const symbol s_45[] = { 0xD9, 0x8A }; +static const symbol s_46[] = { 0xD9, 0x84, 0xD8, 0xA7 }; +static const symbol s_47[] = { 0xD9, 0x84, 0xD8, 0xA3 }; +static const symbol s_48[] = { 0xD9, 0x84, 0xD8, 0xA5 }; +static const symbol s_49[] = { 0xD9, 0x84, 0xD8, 0xA2 }; +static const symbol s_50[] = { 0xD8, 0xA1 }; +static const symbol s_51[] = { 0xD8, 0xA7 }; +static const symbol s_52[] = { 0xD9, 0x88 }; +static const symbol s_53[] = { 0xD9, 0x8A }; +static const symbol s_54[] = { 0xD8, 0xA3 }; +static const symbol s_55[] = { 0xD8, 0xA2 }; +static const symbol s_56[] = { 0xD8, 0xA7 }; +static const symbol s_57[] = { 0xD8, 0xA5 }; +static const symbol s_58[] = { 0xD9, 0x81, 0xD8, 0xA7 }; +static const symbol s_59[] = { 0xD9, 0x88, 0xD8, 0xA7 }; +static const symbol s_60[] = { 0xD8, 0xA8, 0xD8, 0xA7 }; +static const symbol s_61[] = { 0xD8, 0xA8 }; +static const symbol s_62[] = { 0xD9, 0x83 }; +static const symbol s_63[] = { 0xD9, 0x8A }; +static const symbol s_64[] = { 0xD8, 0xAA }; +static const symbol s_65[] = { 0xD9, 0x86 }; +static const symbol s_66[] = { 0xD8, 0xA3 }; +static const symbol s_67[] = { 0xD8, 0xA7, 0xD8, 0xB3, 0xD8, 0xAA }; +static const symbol s_68[] = { 0xD9, 0x8A }; + +static int r_Normalize_pre(struct SN_env * z) { /* forwardmode */ + int among_var; + { int c1 = z->c; /* do, line 247 */ + while(1) { /* repeat, line 247 */ + int c2 = z->c; + { int c3 = z->c; /* or, line 311 */ + z->bra = z->c; /* [, line 249 */ + among_var = find_among(z, a_0, 144); /* substring, line 249 */ + if (!(among_var)) goto lab3; + z->ket = z->c; /* ], line 249 */ + switch (among_var) { /* among, line 249 */ + case 1: + { int ret = slice_del(z); /* delete, line 250 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 1, s_0); /* <-, line 254 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 1, s_1); /* <-, line 255 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 1, s_2); /* <-, line 256 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 1, s_3); /* <-, line 257 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 1, s_4); /* <-, line 258 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 1, s_5); /* <-, line 259 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 1, s_6); /* <-, line 260 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 1, s_7); /* <-, line 261 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 262 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 1, s_9); /* <-, line 263 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 2, s_10); /* <-, line 266 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 2, s_11); /* <-, line 267 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 2, s_12); /* <-, line 268 */ + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 2, s_13); /* <-, line 269 */ + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 2, s_14); /* <-, line 270 */ + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 2, s_15); /* <-, line 271 */ + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 2, s_16); /* <-, line 272 */ + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 2, s_17); /* <-, line 273 */ + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 2, s_18); /* <-, line 274 */ + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 2, s_19); /* <-, line 275 */ + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 2, s_20); /* <-, line 276 */ + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 2, s_21); /* <-, line 277 */ + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 2, s_22); /* <-, line 278 */ + if (ret < 0) return ret; + } + break; + case 25: + { int ret = slice_from_s(z, 2, s_23); /* <-, line 279 */ + if (ret < 0) return ret; + } + break; + case 26: + { int ret = slice_from_s(z, 2, s_24); /* <-, line 280 */ + if (ret < 0) return ret; + } + break; + case 27: + { int ret = slice_from_s(z, 2, s_25); /* <-, line 281 */ + if (ret < 0) return ret; + } + break; + case 28: + { int ret = slice_from_s(z, 2, s_26); /* <-, line 282 */ + if (ret < 0) return ret; + } + break; + case 29: + { int ret = slice_from_s(z, 2, s_27); /* <-, line 283 */ + if (ret < 0) return ret; + } + break; + case 30: + { int ret = slice_from_s(z, 2, s_28); /* <-, line 284 */ + if (ret < 0) return ret; + } + break; + case 31: + { int ret = slice_from_s(z, 2, s_29); /* <-, line 285 */ + if (ret < 0) return ret; + } + break; + case 32: + { int ret = slice_from_s(z, 2, s_30); /* <-, line 286 */ + if (ret < 0) return ret; + } + break; + case 33: + { int ret = slice_from_s(z, 2, s_31); /* <-, line 287 */ + if (ret < 0) return ret; + } + break; + case 34: + { int ret = slice_from_s(z, 2, s_32); /* <-, line 288 */ + if (ret < 0) return ret; + } + break; + case 35: + { int ret = slice_from_s(z, 2, s_33); /* <-, line 289 */ + if (ret < 0) return ret; + } + break; + case 36: + { int ret = slice_from_s(z, 2, s_34); /* <-, line 290 */ + if (ret < 0) return ret; + } + break; + case 37: + { int ret = slice_from_s(z, 2, s_35); /* <-, line 291 */ + if (ret < 0) return ret; + } + break; + case 38: + { int ret = slice_from_s(z, 2, s_36); /* <-, line 292 */ + if (ret < 0) return ret; + } + break; + case 39: + { int ret = slice_from_s(z, 2, s_37); /* <-, line 293 */ + if (ret < 0) return ret; + } + break; + case 40: + { int ret = slice_from_s(z, 2, s_38); /* <-, line 294 */ + if (ret < 0) return ret; + } + break; + case 41: + { int ret = slice_from_s(z, 2, s_39); /* <-, line 295 */ + if (ret < 0) return ret; + } + break; + case 42: + { int ret = slice_from_s(z, 2, s_40); /* <-, line 296 */ + if (ret < 0) return ret; + } + break; + case 43: + { int ret = slice_from_s(z, 2, s_41); /* <-, line 297 */ + if (ret < 0) return ret; + } + break; + case 44: + { int ret = slice_from_s(z, 2, s_42); /* <-, line 298 */ + if (ret < 0) return ret; + } + break; + case 45: + { int ret = slice_from_s(z, 2, s_43); /* <-, line 299 */ + if (ret < 0) return ret; + } + break; + case 46: + { int ret = slice_from_s(z, 2, s_44); /* <-, line 300 */ + if (ret < 0) return ret; + } + break; + case 47: + { int ret = slice_from_s(z, 2, s_45); /* <-, line 301 */ + if (ret < 0) return ret; + } + break; + case 48: + { int ret = slice_from_s(z, 4, s_46); /* <-, line 304 */ + if (ret < 0) return ret; + } + break; + case 49: + { int ret = slice_from_s(z, 4, s_47); /* <-, line 305 */ + if (ret < 0) return ret; + } + break; + case 50: + { int ret = slice_from_s(z, 4, s_48); /* <-, line 306 */ + if (ret < 0) return ret; + } + break; + case 51: + { int ret = slice_from_s(z, 4, s_49); /* <-, line 307 */ + if (ret < 0) return ret; + } + break; + } + goto lab2; + lab3: + z->c = c3; + { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (ret < 0) goto lab1; + z->c = ret; /* next, line 312 */ + } + } + lab2: + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + return 1; +} + +static int r_Normalize_post(struct SN_env * z) { /* forwardmode */ + int among_var; + { int c1 = z->c; /* do, line 318 */ + z->lb = z->c; z->c = z->l; /* backwards, line 320 */ + + z->ket = z->c; /* [, line 321 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((124 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 321 */ + if (!(find_among_b(z, a_1, 5))) goto lab0; + z->bra = z->c; /* ], line 321 */ + { int ret = slice_from_s(z, 2, s_50); /* <-, line 322 */ + if (ret < 0) return ret; + } + z->c = z->lb; + lab0: + z->c = c1; + } + { int c2 = z->c; /* do, line 329 */ + while(1) { /* repeat, line 329 */ + int c3 = z->c; + { int c4 = z->c; /* or, line 338 */ + z->bra = z->c; /* [, line 332 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((124 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab4; /* substring, line 332 */ + among_var = find_among(z, a_2, 5); + if (!(among_var)) goto lab4; + z->ket = z->c; /* ], line 332 */ + switch (among_var) { /* among, line 332 */ + case 1: + { int ret = slice_from_s(z, 2, s_51); /* <-, line 333 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 2, s_52); /* <-, line 334 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 2, s_53); /* <-, line 335 */ + if (ret < 0) return ret; + } + break; + } + goto lab3; + lab4: + z->c = c4; + { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (ret < 0) goto lab2; + z->c = ret; /* next, line 339 */ + } + } + lab3: + continue; + lab2: + z->c = c3; + break; + } + z->c = c2; + } + return 1; +} + +static int r_Checks1(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 345 */ + if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; /* substring, line 345 */ + among_var = find_among(z, a_3, 4); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 345 */ + switch (among_var) { /* among, line 345 */ + case 1: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 346 */ + z->B[0] = 1; /* set is_noun, line 346 */ + z->B[1] = 0; /* unset is_verb, line 346 */ + z->B[2] = 1; /* set is_defined, line 346 */ + break; + case 2: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 347 */ + z->B[0] = 1; /* set is_noun, line 347 */ + z->B[1] = 0; /* unset is_verb, line 347 */ + z->B[2] = 1; /* set is_defined, line 347 */ + break; + } + return 1; +} + +static int r_Prefix_Step1(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 354 */ + if (z->c + 3 >= z->l || z->p[z->c + 3] >> 5 != 5 || !((188 >> (z->p[z->c + 3] & 0x1f)) & 1)) return 0; /* substring, line 354 */ + among_var = find_among(z, a_4, 5); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 354 */ + switch (among_var) { /* among, line 354 */ + case 1: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 355 */ + { int ret = slice_from_s(z, 2, s_54); /* <-, line 355 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 356 */ + { int ret = slice_from_s(z, 2, s_55); /* <-, line 356 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 358 */ + { int ret = slice_from_s(z, 2, s_56); /* <-, line 358 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 359 */ + { int ret = slice_from_s(z, 2, s_57); /* <-, line 359 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Prefix_Step2(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* not, line 365 */ + if (!(eq_s(z, 4, s_58))) goto lab0; /* literal, line 365 */ + return 0; + lab0: + z->c = c1; + } + { int c2 = z->c; /* not, line 366 */ + if (!(eq_s(z, 4, s_59))) goto lab1; /* literal, line 366 */ + return 0; + lab1: + z->c = c2; + } + z->bra = z->c; /* [, line 367 */ + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 129 && z->p[z->c + 1] != 136)) return 0; /* substring, line 367 */ + if (!(find_among(z, a_5, 2))) return 0; + z->ket = z->c; /* ], line 367 */ + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 368 */ + { int ret = slice_del(z); /* delete, line 368 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Prefix_Step3a_Noun(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 374 */ + if (z->c + 3 >= z->l || (z->p[z->c + 3] != 132 && z->p[z->c + 3] != 167)) return 0; /* substring, line 374 */ + among_var = find_among(z, a_6, 4); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 374 */ + switch (among_var) { /* among, line 374 */ + case 1: + if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 375 */ + { int ret = slice_del(z); /* delete, line 375 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 376 */ + { int ret = slice_del(z); /* delete, line 376 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Prefix_Step3b_Noun(struct SN_env * z) { /* forwardmode */ + int among_var; + { int c1 = z->c; /* not, line 381 */ + if (!(eq_s(z, 4, s_60))) goto lab0; /* literal, line 381 */ + return 0; + lab0: + z->c = c1; + } + z->bra = z->c; /* [, line 382 */ + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 168 && z->p[z->c + 1] != 131)) return 0; /* substring, line 382 */ + among_var = find_among(z, a_7, 3); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 382 */ + switch (among_var) { /* among, line 382 */ + case 1: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 383 */ + { int ret = slice_del(z); /* delete, line 383 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 385 */ + { int ret = slice_from_s(z, 2, s_61); /* <-, line 385 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 386 */ + { int ret = slice_from_s(z, 2, s_62); /* <-, line 386 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Prefix_Step3_Verb(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 392 */ + among_var = find_among(z, a_8, 4); /* substring, line 392 */ + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 392 */ + switch (among_var) { /* among, line 392 */ + case 1: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 394 */ + { int ret = slice_from_s(z, 2, s_63); /* <-, line 394 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 395 */ + { int ret = slice_from_s(z, 2, s_64); /* <-, line 395 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 396 */ + { int ret = slice_from_s(z, 2, s_65); /* <-, line 396 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 397 */ + { int ret = slice_from_s(z, 2, s_66); /* <-, line 397 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Prefix_Step4_Verb(struct SN_env * z) { /* forwardmode */ + z->bra = z->c; /* [, line 402 */ + if (z->c + 5 >= z->l || z->p[z->c + 5] != 170) return 0; /* substring, line 402 */ + if (!(find_among(z, a_9, 3))) return 0; + z->ket = z->c; /* ], line 402 */ + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 403 */ + z->B[1] = 1; /* set is_verb, line 403 */ + z->B[0] = 0; /* unset is_noun, line 403 */ + { int ret = slice_from_s(z, 6, s_67); /* <-, line 403 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step1a(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 411 */ + among_var = find_among_b(z, a_10, 10); /* substring, line 411 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 411 */ + switch (among_var) { /* among, line 411 */ + case 1: + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 412 */ + { int ret = slice_del(z); /* delete, line 412 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 413 */ + { int ret = slice_del(z); /* delete, line 413 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 414 */ + { int ret = slice_del(z); /* delete, line 414 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Suffix_Noun_Step1b(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 418 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 134) return 0; /* substring, line 418 */ + if (!(find_among_b(z, a_11, 1))) return 0; + z->bra = z->c; /* ], line 418 */ + if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 419 */ + { int ret = slice_del(z); /* delete, line 419 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step2a(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 424 */ + if (!(find_among_b(z, a_12, 3))) return 0; /* substring, line 424 */ + z->bra = z->c; /* ], line 424 */ + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 425 */ + { int ret = slice_del(z); /* delete, line 425 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step2b(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 430 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 170) return 0; /* substring, line 430 */ + if (!(find_among_b(z, a_13, 1))) return 0; + z->bra = z->c; /* ], line 430 */ + if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 431 */ + { int ret = slice_del(z); /* delete, line 431 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step2c1(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 436 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 170) return 0; /* substring, line 436 */ + if (!(find_among_b(z, a_14, 1))) return 0; + z->bra = z->c; /* ], line 436 */ + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 437 */ + { int ret = slice_del(z); /* delete, line 437 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step2c2(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 441 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 169) return 0; /* substring, line 441 */ + if (!(find_among_b(z, a_15, 1))) return 0; + z->bra = z->c; /* ], line 441 */ + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 442 */ + { int ret = slice_del(z); /* delete, line 442 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Noun_Step3(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 446 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 138) return 0; /* substring, line 446 */ + if (!(find_among_b(z, a_16, 1))) return 0; + z->bra = z->c; /* ], line 446 */ + if (!(len_utf8(z->p) >= 3)) return 0; /* $( >= ), line 447 */ + { int ret = slice_del(z); /* delete, line 447 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Verb_Step1(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 452 */ + among_var = find_among_b(z, a_17, 12); /* substring, line 452 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 452 */ + switch (among_var) { /* among, line 452 */ + case 1: + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 453 */ + { int ret = slice_del(z); /* delete, line 453 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 454 */ + { int ret = slice_del(z); /* delete, line 454 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 455 */ + { int ret = slice_del(z); /* delete, line 455 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Suffix_Verb_Step2a(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 459 */ + among_var = find_among_b(z, a_18, 11); /* substring, line 459 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 459 */ + switch (among_var) { /* among, line 459 */ + case 1: + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 460 */ + { int ret = slice_del(z); /* delete, line 460 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 462 */ + { int ret = slice_del(z); /* delete, line 462 */ + if (ret < 0) return ret; + } + break; + case 3: + if (!(len_utf8(z->p) > 5)) return 0; /* $( > ), line 463 */ + { int ret = slice_del(z); /* delete, line 463 */ + if (ret < 0) return ret; + } + break; + case 4: + if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 464 */ + { int ret = slice_del(z); /* delete, line 464 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Suffix_Verb_Step2b(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 469 */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 133 && z->p[z->c - 1] != 167)) return 0; /* substring, line 469 */ + if (!(find_among_b(z, a_19, 2))) return 0; + z->bra = z->c; /* ], line 469 */ + if (!(len_utf8(z->p) >= 5)) return 0; /* $( >= ), line 470 */ + { int ret = slice_del(z); /* delete, line 470 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_Suffix_Verb_Step2c(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 476 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 136) return 0; /* substring, line 476 */ + among_var = find_among_b(z, a_20, 2); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 476 */ + switch (among_var) { /* among, line 476 */ + case 1: + if (!(len_utf8(z->p) >= 4)) return 0; /* $( >= ), line 477 */ + { int ret = slice_del(z); /* delete, line 477 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(len_utf8(z->p) >= 6)) return 0; /* $( >= ), line 478 */ + { int ret = slice_del(z); /* delete, line 478 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_Suffix_All_alef_maqsura(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 483 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 137) return 0; /* substring, line 483 */ + if (!(find_among_b(z, a_21, 1))) return 0; + z->bra = z->c; /* ], line 483 */ + { int ret = slice_from_s(z, 2, s_68); /* <-, line 484 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int arabic_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->B[0] = 1; /* set is_noun, line 493 */ + z->B[1] = 1; /* set is_verb, line 494 */ + z->B[2] = 0; /* unset is_defined, line 495 */ + { int c1 = z->c; /* do, line 498 */ + { int ret = r_Checks1(z); /* call Checks1, line 498 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + /* do, line 501 */ + { int ret = r_Normalize_pre(z); /* call Normalize_pre, line 501 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } +lab1: + z->lb = z->c; z->c = z->l; /* backwards, line 504 */ + + { int m2 = z->l - z->c; (void)m2; /* do, line 506 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 520 */ + if (!(z->B[1])) goto lab4; /* Boolean test is_verb, line 509 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 515 */ + { int i = 1; + while(1) { /* atleast, line 512 */ + int m5 = z->l - z->c; (void)m5; + { int ret = r_Suffix_Verb_Step1(z); /* call Suffix_Verb_Step1, line 512 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + i--; + continue; + lab7: + z->c = z->l - m5; + break; + } + if (i > 0) goto lab6; + } + { int m6 = z->l - z->c; (void)m6; /* or, line 513 */ + { int ret = r_Suffix_Verb_Step2a(z); /* call Suffix_Verb_Step2a, line 513 */ + if (ret == 0) goto lab9; + if (ret < 0) return ret; + } + goto lab8; + lab9: + z->c = z->l - m6; + { int ret = r_Suffix_Verb_Step2c(z); /* call Suffix_Verb_Step2c, line 513 */ + if (ret == 0) goto lab10; + if (ret < 0) return ret; + } + goto lab8; + lab10: + z->c = z->l - m6; + { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (ret < 0) goto lab6; + z->c = ret; /* next, line 513 */ + } + } + lab8: + goto lab5; + lab6: + z->c = z->l - m4; + { int ret = r_Suffix_Verb_Step2b(z); /* call Suffix_Verb_Step2b, line 515 */ + if (ret == 0) goto lab11; + if (ret < 0) return ret; + } + goto lab5; + lab11: + z->c = z->l - m4; + { int ret = r_Suffix_Verb_Step2a(z); /* call Suffix_Verb_Step2a, line 516 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + } + lab5: + goto lab3; + lab4: + z->c = z->l - m3; + if (!(z->B[0])) goto lab12; /* Boolean test is_noun, line 521 */ + { int m7 = z->l - z->c; (void)m7; /* try, line 524 */ + { int m8 = z->l - z->c; (void)m8; /* or, line 526 */ + { int ret = r_Suffix_Noun_Step2c2(z); /* call Suffix_Noun_Step2c2, line 525 */ + if (ret == 0) goto lab15; + if (ret < 0) return ret; + } + goto lab14; + lab15: + z->c = z->l - m8; + /* not, line 526 */ + if (!(z->B[2])) goto lab17; /* Boolean test is_defined, line 526 */ + goto lab16; + lab17: + { int ret = r_Suffix_Noun_Step1a(z); /* call Suffix_Noun_Step1a, line 526 */ + if (ret == 0) goto lab16; + if (ret < 0) return ret; + } + { int m9 = z->l - z->c; (void)m9; /* or, line 528 */ + { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 527 */ + if (ret == 0) goto lab19; + if (ret < 0) return ret; + } + goto lab18; + lab19: + z->c = z->l - m9; + { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 528 */ + if (ret == 0) goto lab20; + if (ret < 0) return ret; + } + goto lab18; + lab20: + z->c = z->l - m9; + { int ret = r_Suffix_Noun_Step2c1(z); /* call Suffix_Noun_Step2c1, line 529 */ + if (ret == 0) goto lab21; + if (ret < 0) return ret; + } + goto lab18; + lab21: + z->c = z->l - m9; + { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (ret < 0) goto lab16; + z->c = ret; /* next, line 530 */ + } + } + lab18: + goto lab14; + lab16: + z->c = z->l - m8; + { int ret = r_Suffix_Noun_Step1b(z); /* call Suffix_Noun_Step1b, line 531 */ + if (ret == 0) goto lab22; + if (ret < 0) return ret; + } + { int m10 = z->l - z->c; (void)m10; /* or, line 533 */ + { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 532 */ + if (ret == 0) goto lab24; + if (ret < 0) return ret; + } + goto lab23; + lab24: + z->c = z->l - m10; + { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 533 */ + if (ret == 0) goto lab25; + if (ret < 0) return ret; + } + goto lab23; + lab25: + z->c = z->l - m10; + { int ret = r_Suffix_Noun_Step2c1(z); /* call Suffix_Noun_Step2c1, line 534 */ + if (ret == 0) goto lab22; + if (ret < 0) return ret; + } + } + lab23: + goto lab14; + lab22: + z->c = z->l - m8; + /* not, line 535 */ + if (!(z->B[2])) goto lab27; /* Boolean test is_defined, line 535 */ + goto lab26; + lab27: + { int ret = r_Suffix_Noun_Step2a(z); /* call Suffix_Noun_Step2a, line 535 */ + if (ret == 0) goto lab26; + if (ret < 0) return ret; + } + goto lab14; + lab26: + z->c = z->l - m8; + { int ret = r_Suffix_Noun_Step2b(z); /* call Suffix_Noun_Step2b, line 536 */ + if (ret == 0) { z->c = z->l - m7; goto lab13; } + if (ret < 0) return ret; + } + } + lab14: + lab13: + ; + } + { int ret = r_Suffix_Noun_Step3(z); /* call Suffix_Noun_Step3, line 538 */ + if (ret == 0) goto lab12; + if (ret < 0) return ret; + } + goto lab3; + lab12: + z->c = z->l - m3; + { int ret = r_Suffix_All_alef_maqsura(z); /* call Suffix_All_alef_maqsura, line 544 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + } + lab3: + lab2: + z->c = z->l - m2; + } + z->c = z->lb; + { int c11 = z->c; /* do, line 549 */ + { int c12 = z->c; /* try, line 550 */ + { int ret = r_Prefix_Step1(z); /* call Prefix_Step1, line 550 */ + if (ret == 0) { z->c = c12; goto lab29; } + if (ret < 0) return ret; + } + lab29: + ; + } + { int c13 = z->c; /* try, line 551 */ + { int ret = r_Prefix_Step2(z); /* call Prefix_Step2, line 551 */ + if (ret == 0) { z->c = c13; goto lab30; } + if (ret < 0) return ret; + } + lab30: + ; + } + { int c14 = z->c; /* or, line 553 */ + { int ret = r_Prefix_Step3a_Noun(z); /* call Prefix_Step3a_Noun, line 552 */ + if (ret == 0) goto lab32; + if (ret < 0) return ret; + } + goto lab31; + lab32: + z->c = c14; + if (!(z->B[0])) goto lab33; /* Boolean test is_noun, line 553 */ + { int ret = r_Prefix_Step3b_Noun(z); /* call Prefix_Step3b_Noun, line 553 */ + if (ret == 0) goto lab33; + if (ret < 0) return ret; + } + goto lab31; + lab33: + z->c = c14; + if (!(z->B[1])) goto lab28; /* Boolean test is_verb, line 554 */ + { int c15 = z->c; /* try, line 554 */ + { int ret = r_Prefix_Step3_Verb(z); /* call Prefix_Step3_Verb, line 554 */ + if (ret == 0) { z->c = c15; goto lab34; } + if (ret < 0) return ret; + } + lab34: + ; + } + { int ret = r_Prefix_Step4_Verb(z); /* call Prefix_Step4_Verb, line 554 */ + if (ret == 0) goto lab28; + if (ret < 0) return ret; + } + } + lab31: + lab28: + z->c = c11; + } + /* do, line 559 */ + { int ret = r_Normalize_post(z); /* call Normalize_post, line 559 */ + if (ret == 0) goto lab35; + if (ret < 0) return ret; + } +lab35: + return 1; +} + +extern struct SN_env * arabic_UTF_8_create_env(void) { return SN_create_env(0, 0, 3); } + +extern void arabic_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_danish.c b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c index cfd41376da2..901491c7b6e 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_danish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_danish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -124,6 +124,8 @@ static const struct among a_2[5] = /* 4 */ { 5, s_2_4, -1, 2, 0} }; +static const unsigned char g_c[] = { 119, 223, 119, 1 }; + static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 128 }; static const unsigned char g_s_ending[] = { 239, 254, 42, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }; @@ -132,55 +134,52 @@ static const symbol s_0[] = { 's', 't' }; static const symbol s_1[] = { 'i', 'g' }; static const symbol s_2[] = { 'l', 0xC3, 0xB8, 's' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 33 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 33 */ + { int c_test1 = z->c; /* test, line 35 */ + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 35 */ if (ret < 0) return 0; - z->c = ret; /* hop, line 33 */ + z->c = ret; } - z->I[1] = z->c; /* setmark x, line 33 */ - z->c = c_test; + z->I[1] = z->c; /* setmark x, line 35 */ + z->c = c_test1; } - if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 34 */ - { /* gopast */ /* non v, line 34 */ + if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 36 */ + { /* gopast */ /* non v, line 36 */ int ret = in_grouping_U(z, g_v, 97, 248, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 34 */ - /* try, line 35 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + z->I[0] = z->c; /* setmark p1, line 36 */ + /* try, line 37 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 37 */ + z->I[0] = z->I[1]; /* $p1 = , line 37 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 41 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 43 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 41 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 41 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 32); /* substring, line 41 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 41 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 43 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851440 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 43 */ + among_var = find_among_b(z, a_0, 32); + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 43 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 44 */ case 1: - { int ret = slice_del(z); /* delete, line 48 */ + { int ret = slice_del(z); /* delete, line 50 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_s_ending, 97, 229, 0)) return 0; - { int ret = slice_del(z); /* delete, line 50 */ + if (in_grouping_b_U(z, g_s_ending, 97, 229, 0)) return 0; /* grouping s_ending, line 52 */ + { int ret = slice_del(z); /* delete, line 52 */ if (ret < 0) return ret; } break; @@ -188,68 +187,63 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 55 */ - { int mlimit; /* setlimit, line 56 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 57 */ + + { int mlimit2; /* setlimit, line 58 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 56 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit; return 0; } /* substring, line 56 */ - z->bra = z->c; /* ], line 56 */ - z->lb = mlimit; + mlimit2 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 58 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 116)) { z->lb = mlimit2; return 0; } /* substring, line 58 */ + if (!(find_among_b(z, a_1, 4))) { z->lb = mlimit2; return 0; } + z->bra = z->c; /* ], line 58 */ + z->lb = mlimit2; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 62 */ + z->c = ret; /* next, line 64 */ } - z->bra = z->c; /* ], line 62 */ - { int ret = slice_del(z); /* delete, line 62 */ + z->bra = z->c; /* ], line 64 */ + { int ret = slice_del(z); /* delete, line 64 */ if (ret < 0) return ret; } return 1; } -static int r_other_suffix(struct SN_env * z) { +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 66 */ - z->ket = z->c; /* [, line 66 */ - if (!(eq_s_b(z, 2, s_0))) goto lab0; - z->bra = z->c; /* ], line 66 */ - if (!(eq_s_b(z, 2, s_1))) goto lab0; - { int ret = slice_del(z); /* delete, line 66 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 68 */ + z->ket = z->c; /* [, line 68 */ + if (!(eq_s_b(z, 2, s_0))) goto lab0; /* literal, line 68 */ + z->bra = z->c; /* ], line 68 */ + if (!(eq_s_b(z, 2, s_1))) goto lab0; /* literal, line 68 */ + { int ret = slice_del(z); /* delete, line 68 */ if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - { int mlimit; /* setlimit, line 67 */ - int m2 = z->l - z->c; (void)m2; + + { int mlimit2; /* setlimit, line 69 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 67 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - z->ket = z->c; /* [, line 67 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 5); /* substring, line 67 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 67 */ - z->lb = mlimit; + mlimit2 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 69 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit2; return 0; } /* substring, line 69 */ + among_var = find_among_b(z, a_2, 5); + if (!(among_var)) { z->lb = mlimit2; return 0; } + z->bra = z->c; /* ], line 69 */ + z->lb = mlimit2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 70 */ case 1: - { int ret = slice_del(z); /* delete, line 70 */ + { int ret = slice_del(z); /* delete, line 72 */ if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* do, line 70 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab1; /* call consonant_pair, line 70 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 72 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 72 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -257,7 +251,7 @@ static int r_other_suffix(struct SN_env * z) { } break; case 2: - { int ret = slice_from_s(z, 4, s_2); /* <-, line 72 */ + { int ret = slice_from_s(z, 4, s_2); /* <-, line 74 */ if (ret < 0) return ret; } break; @@ -265,65 +259,63 @@ static int r_other_suffix(struct SN_env * z) { return 1; } -static int r_undouble(struct SN_env * z) { - { int mlimit; /* setlimit, line 76 */ - int m1 = z->l - z->c; (void)m1; +static int r_undouble(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 78 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 76 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 76 */ - if (out_grouping_b_U(z, g_v, 97, 248, 0)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 76 */ - z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 76 */ - if (z->S[0] == 0) return -1; /* -> ch, line 76 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 78 */ + if (in_grouping_b_U(z, g_c, 98, 122, 0)) { z->lb = mlimit1; return 0; } /* grouping c, line 78 */ + z->bra = z->c; /* ], line 78 */ + z->S[0] = slice_to(z, z->S[0]); /* -> ch, line 78 */ + if (z->S[0] == 0) return -1; /* -> ch, line 78 */ + z->lb = mlimit1; } - if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 77 */ - { int ret = slice_del(z); /* delete, line 78 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name ch, line 79 */ + { int ret = slice_del(z); /* delete, line 80 */ if (ret < 0) return ret; } return 1; } -extern int danish_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 84 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 84 */ +extern int danish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 86 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 86 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 85 */ + z->lb = z->c; z->c = z->l; /* backwards, line 87 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 86 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 86 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 88 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 87 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 87 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 89 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 89 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 88 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 88 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 90 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 90 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 89 */ - { int ret = r_undouble(z); - if (ret == 0) goto lab4; /* call undouble, line 89 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 91 */ + { int ret = r_undouble(z); /* call undouble, line 91 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c index f04c88d3e6a..0a61174502d 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_dutch.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -134,36 +134,28 @@ static const symbol s_1[] = { 'e' }; static const symbol s_2[] = { 'i' }; static const symbol s_3[] = { 'o' }; static const symbol s_4[] = { 'u' }; -static const symbol s_5[] = { 'y' }; -static const symbol s_6[] = { 'Y' }; -static const symbol s_7[] = { 'i' }; -static const symbol s_8[] = { 'I' }; -static const symbol s_9[] = { 'y' }; -static const symbol s_10[] = { 'Y' }; -static const symbol s_11[] = { 'y' }; -static const symbol s_12[] = { 'i' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'g', 'e', 'm' }; -static const symbol s_15[] = { 'h', 'e', 'i', 'd' }; -static const symbol s_16[] = { 'h', 'e', 'i', 'd' }; -static const symbol s_17[] = { 'c' }; -static const symbol s_18[] = { 'e', 'n' }; -static const symbol s_19[] = { 'i', 'g' }; -static const symbol s_20[] = { 'e' }; -static const symbol s_21[] = { 'e' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_5[] = { 'Y' }; +static const symbol s_6[] = { 'I' }; +static const symbol s_7[] = { 'Y' }; +static const symbol s_8[] = { 'y' }; +static const symbol s_9[] = { 'i' }; +static const symbol s_10[] = { 'g', 'e', 'm' }; +static const symbol s_11[] = { 'h', 'e', 'i', 'd' }; +static const symbol s_12[] = { 'h', 'e', 'i', 'd' }; +static const symbol s_13[] = { 'e', 'n' }; +static const symbol s_14[] = { 'i', 'g' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; - { int c_test = z->c; /* test, line 42 */ + { int c_test1 = z->c; /* test, line 42 */ while(1) { /* repeat, line 42 */ - int c1 = z->c; + int c2 = z->c; z->bra = z->c; /* [, line 43 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((340306450 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else - among_var = find_among(z, a_0, 11); /* substring, line 43 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((340306450 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else /* substring, line 43 */ + among_var = find_among(z, a_0, 11); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 43 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 43 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 45 */ if (ret < 0) return ret; @@ -198,48 +190,51 @@ static int r_prelude(struct SN_env * z) { } continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } - { int c_keep = z->c; /* try, line 57 */ + { int c3 = z->c; /* try, line 57 */ z->bra = z->c; /* [, line 57 */ - if (!(eq_s(z, 1, s_5))) { z->c = c_keep; goto lab1; } + if (z->c == z->l || z->p[z->c] != 'y') { z->c = c3; goto lab1; } /* literal, line 57 */ + z->c++; z->ket = z->c; /* ], line 57 */ - { int ret = slice_from_s(z, 1, s_6); /* <-, line 57 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 57 */ if (ret < 0) return ret; } lab1: ; } while(1) { /* repeat, line 58 */ - int c2 = z->c; + int c4 = z->c; while(1) { /* goto, line 58 */ - int c3 = z->c; - if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab3; + int c5 = z->c; + if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab3; /* grouping v, line 59 */ z->bra = z->c; /* [, line 59 */ - { int c4 = z->c; /* or, line 59 */ - if (!(eq_s(z, 1, s_7))) goto lab5; + { int c6 = z->c; /* or, line 59 */ + if (z->c == z->l || z->p[z->c] != 'i') goto lab5; /* literal, line 59 */ + z->c++; z->ket = z->c; /* ], line 59 */ - if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab5; - { int ret = slice_from_s(z, 1, s_8); /* <-, line 59 */ + if (in_grouping_U(z, g_v, 97, 232, 0)) goto lab5; /* grouping v, line 59 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 59 */ if (ret < 0) return ret; } goto lab4; lab5: - z->c = c4; - if (!(eq_s(z, 1, s_9))) goto lab3; + z->c = c6; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 60 */ + z->c++; z->ket = z->c; /* ], line 60 */ - { int ret = slice_from_s(z, 1, s_10); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 60 */ if (ret < 0) return ret; } } lab4: - z->c = c3; + z->c = c5; break; lab3: - z->c = c3; + z->c = c5; { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab2; z->c = ret; /* goto, line 58 */ @@ -247,15 +242,15 @@ static int r_prelude(struct SN_env * z) { } continue; lab2: - z->c = c2; + z->c = c4; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 66 */ + z->I[1] = z->l; /* $p2 = , line 67 */ { /* gopast */ /* grouping v, line 69 */ int ret = out_grouping_U(z, g_v, 97, 232, 1); if (ret < 0) return 0; @@ -267,9 +262,9 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 69 */ - /* try, line 70 */ - if (!(z->I[0] < 3)) goto lab0; - z->I[0] = 3; + /* try, line 70 */ + if (!(z->I[0] < 3)) goto lab0; /* $( < ), line 70 */ + z->I[0] = 3; /* $p1 = , line 70 */ lab0: { /* gopast */ /* grouping v, line 71 */ int ret = out_grouping_U(z, g_v, 97, 232, 1); @@ -285,24 +280,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 75 */ int c1 = z->c; z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 77 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 89)) among_var = 3; else /* substring, line 77 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 77 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 77 */ case 1: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 78 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 79 */ if (ret < 0) return ret; } break; @@ -321,21 +315,21 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 87 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 88 */ return 1; } -static int r_undouble(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 91 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 3))) return 0; /* among, line 91 */ - z->c = z->l - m_test; +static int r_undouble(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 91 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1050640 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 91 */ + if (!(find_among_b(z, a_2, 3))) return 0; + z->c = z->l - m_test1; } z->ket = z->c; /* [, line 91 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); @@ -349,40 +343,38 @@ static int r_undouble(struct SN_env * z) { return 1; } -static int r_e_ending(struct SN_env * z) { +static int r_e_ending(struct SN_env * z) { /* backwardmode */ z->B[0] = 0; /* unset e_found, line 95 */ z->ket = z->c; /* [, line 96 */ - if (!(eq_s_b(z, 1, s_13))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 96 */ + z->c--; z->bra = z->c; /* ], line 96 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 96 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 96 */ + if (ret <= 0) return ret; } - { int m_test = z->l - z->c; /* test, line 96 */ - if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; - z->c = z->l - m_test; + { int m_test1 = z->l - z->c; /* test, line 96 */ + if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; /* non v, line 96 */ + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 96 */ if (ret < 0) return ret; } z->B[0] = 1; /* set e_found, line 97 */ - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 98 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 98 */ + if (ret <= 0) return ret; } return 1; } -static int r_en_ending(struct SN_env * z) { - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 102 */ - if (ret < 0) return ret; +static int r_en_ending(struct SN_env * z) { /* backwardmode */ + { int ret = r_R1(z); /* call R1, line 102 */ + if (ret <= 0) return ret; } { int m1 = z->l - z->c; (void)m1; /* and, line 102 */ - if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; + if (out_grouping_b_U(z, g_v, 97, 232, 0)) return 0; /* non v, line 102 */ z->c = z->l - m1; { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - if (!(eq_s_b(z, 3, s_14))) goto lab0; + if (!(eq_s_b(z, 3, s_10))) goto lab0; /* literal, line 102 */ return 0; lab0: z->c = z->l - m2; @@ -391,44 +383,42 @@ static int r_en_ending(struct SN_env * z) { { int ret = slice_del(z); /* delete, line 102 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 103 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 103 */ + if (ret <= 0) return ret; } return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; { int m1 = z->l - z->c; (void)m1; /* do, line 107 */ z->ket = z->c; /* [, line 108 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; - among_var = find_among_b(z, a_3, 5); /* substring, line 108 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((540704 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 108 */ + among_var = find_among_b(z, a_3, 5); if (!(among_var)) goto lab0; z->bra = z->c; /* ], line 108 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 108 */ case 1: - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 110 */ + { int ret = r_R1(z); /* call R1, line 110 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - { int ret = slice_from_s(z, 4, s_15); /* <-, line 110 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 110 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_en_ending(z); - if (ret == 0) goto lab0; /* call en_ending, line 113 */ + { int ret = r_en_ending(z); /* call en_ending, line 113 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } break; case 3: - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 116 */ + { int ret = r_R1(z); /* call R1, line 116 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - if (out_grouping_b_U(z, g_v_j, 97, 232, 0)) goto lab0; + if (out_grouping_b_U(z, g_v_j, 97, 232, 0)) goto lab0; /* non v_j, line 116 */ { int ret = slice_del(z); /* delete, line 116 */ if (ret < 0) return ret; } @@ -438,8 +428,8 @@ static int r_standard_suffix(struct SN_env * z) { z->c = z->l - m1; } { int m2 = z->l - z->c; (void)m2; /* do, line 120 */ - { int ret = r_e_ending(z); - if (ret == 0) goto lab1; /* call e_ending, line 120 */ + { int ret = r_e_ending(z); /* call e_ending, line 120 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -447,14 +437,15 @@ static int r_standard_suffix(struct SN_env * z) { } { int m3 = z->l - z->c; (void)m3; /* do, line 122 */ z->ket = z->c; /* [, line 122 */ - if (!(eq_s_b(z, 4, s_16))) goto lab2; + if (!(eq_s_b(z, 4, s_12))) goto lab2; /* literal, line 122 */ z->bra = z->c; /* ], line 122 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 122 */ + { int ret = r_R2(z); /* call R2, line 122 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } { int m4 = z->l - z->c; (void)m4; /* not, line 122 */ - if (!(eq_s_b(z, 1, s_17))) goto lab3; + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab3; /* literal, line 122 */ + z->c--; goto lab2; lab3: z->c = z->l - m4; @@ -463,10 +454,10 @@ static int r_standard_suffix(struct SN_env * z) { if (ret < 0) return ret; } z->ket = z->c; /* [, line 123 */ - if (!(eq_s_b(z, 2, s_18))) goto lab2; + if (!(eq_s_b(z, 2, s_13))) goto lab2; /* literal, line 123 */ z->bra = z->c; /* ], line 123 */ - { int ret = r_en_ending(z); - if (ret == 0) goto lab2; /* call en_ending, line 123 */ + { int ret = r_en_ending(z); /* call en_ending, line 123 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: @@ -474,15 +465,14 @@ static int r_standard_suffix(struct SN_env * z) { } { int m5 = z->l - z->c; (void)m5; /* do, line 126 */ z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4; - among_var = find_among_b(z, a_4, 6); /* substring, line 127 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((264336 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab4; /* substring, line 127 */ + among_var = find_among_b(z, a_4, 6); if (!(among_var)) goto lab4; z->bra = z->c; /* ], line 127 */ - switch(among_var) { - case 0: goto lab4; + switch (among_var) { /* among, line 127 */ case 1: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 129 */ + { int ret = r_R2(z); /* call R2, line 129 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 129 */ @@ -490,14 +480,15 @@ static int r_standard_suffix(struct SN_env * z) { } { int m6 = z->l - z->c; (void)m6; /* or, line 130 */ z->ket = z->c; /* [, line 130 */ - if (!(eq_s_b(z, 2, s_19))) goto lab6; + if (!(eq_s_b(z, 2, s_14))) goto lab6; /* literal, line 130 */ z->bra = z->c; /* ], line 130 */ - { int ret = r_R2(z); - if (ret == 0) goto lab6; /* call R2, line 130 */ + { int ret = r_R2(z); /* call R2, line 130 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } { int m7 = z->l - z->c; (void)m7; /* not, line 130 */ - if (!(eq_s_b(z, 1, s_20))) goto lab7; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab7; /* literal, line 130 */ + z->c--; goto lab6; lab7: z->c = z->l - m7; @@ -508,20 +499,21 @@ static int r_standard_suffix(struct SN_env * z) { goto lab5; lab6: z->c = z->l - m6; - { int ret = r_undouble(z); - if (ret == 0) goto lab4; /* call undouble, line 130 */ + { int ret = r_undouble(z); /* call undouble, line 130 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: break; case 2: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 133 */ + { int ret = r_R2(z); /* call R2, line 133 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int m8 = z->l - z->c; (void)m8; /* not, line 133 */ - if (!(eq_s_b(z, 1, s_21))) goto lab8; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab8; /* literal, line 133 */ + z->c--; goto lab4; lab8: z->c = z->l - m8; @@ -531,21 +523,21 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 136 */ + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; } - { int ret = r_e_ending(z); - if (ret == 0) goto lab4; /* call e_ending, line 136 */ + { int ret = r_e_ending(z); /* call e_ending, line 136 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 139 */ + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 139 */ @@ -553,8 +545,8 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 5: - { int ret = r_R2(z); - if (ret == 0) goto lab4; /* call R2, line 142 */ + { int ret = r_R2(z); /* call R2, line 142 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } if (!(z->B[0])) goto lab4; /* Boolean test e_found, line 142 */ @@ -567,12 +559,12 @@ static int r_standard_suffix(struct SN_env * z) { z->c = z->l - m5; } { int m9 = z->l - z->c; (void)m9; /* do, line 146 */ - if (out_grouping_b_U(z, g_v_I, 73, 232, 0)) goto lab9; - { int m_test = z->l - z->c; /* test, line 148 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9; - if (!(find_among_b(z, a_5, 4))) goto lab9; /* among, line 149 */ - if (out_grouping_b_U(z, g_v, 97, 232, 0)) goto lab9; - z->c = z->l - m_test; + if (out_grouping_b_U(z, g_v_I, 73, 232, 0)) goto lab9; /* non v_I, line 147 */ + { int m_test10 = z->l - z->c; /* test, line 148 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2129954 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab9; /* among, line 149 */ + if (!(find_among_b(z, a_5, 4))) goto lab9; + if (out_grouping_b_U(z, g_v, 97, 232, 0)) goto lab9; /* non v, line 150 */ + z->c = z->l - m_test10; } z->ket = z->c; /* [, line 152 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); @@ -589,18 +581,18 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -extern int dutch_UTF_8_stem(struct SN_env * z) { +extern int dutch_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 159 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 159 */ + { int ret = r_prelude(z); /* call prelude, line 159 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } { int c2 = z->c; /* do, line 160 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 160 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 160 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: @@ -608,22 +600,20 @@ extern int dutch_UTF_8_stem(struct SN_env * z) { } z->lb = z->c; z->c = z->l; /* backwards, line 161 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 162 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab2; /* call standard_suffix, line 162 */ - if (ret < 0) return ret; - } - lab2: - z->c = z->l - m3; + /* do, line 162 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 162 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; } +lab2: z->c = z->lb; - { int c4 = z->c; /* do, line 163 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab3; /* call postlude, line 163 */ + { int c3 = z->c; /* do, line 163 */ + { int ret = r_postlude(z); /* call postlude, line 163 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = c4; + z->c = c3; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_english.c b/src/backend/snowball/libstemmer/stem_UTF_8_english.c index c5d4c2a445d..ae206f654f6 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_english.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_english.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -153,12 +153,12 @@ static const struct among a_5[24] = /* 0 */ { 4, s_5_0, -1, 3, 0}, /* 1 */ { 4, s_5_1, -1, 2, 0}, /* 2 */ { 3, s_5_2, -1, 13, 0}, -/* 3 */ { 2, s_5_3, -1, 16, 0}, +/* 3 */ { 2, s_5_3, -1, 15, 0}, /* 4 */ { 3, s_5_4, 3, 12, 0}, /* 5 */ { 4, s_5_5, 4, 4, 0}, /* 6 */ { 4, s_5_6, 3, 8, 0}, -/* 7 */ { 5, s_5_7, 3, 14, 0}, -/* 8 */ { 6, s_5_8, 3, 15, 0}, +/* 7 */ { 5, s_5_7, 3, 9, 0}, +/* 8 */ { 6, s_5_8, 3, 14, 0}, /* 9 */ { 5, s_5_9, 3, 10, 0}, /* 10 */ { 5, s_5_10, 3, 5, 0}, /* 11 */ { 5, s_5_11, -1, 8, 0}, @@ -317,62 +317,52 @@ static const unsigned char g_v_WXY[] = { 1, 17, 65, 208, 1 }; static const unsigned char g_valid_LI[] = { 55, 141, 2 }; -static const symbol s_0[] = { '\'' }; -static const symbol s_1[] = { 'y' }; -static const symbol s_2[] = { 'Y' }; -static const symbol s_3[] = { 'y' }; -static const symbol s_4[] = { 'Y' }; -static const symbol s_5[] = { 's', 's' }; -static const symbol s_6[] = { 'i' }; -static const symbol s_7[] = { 'i', 'e' }; -static const symbol s_8[] = { 'e', 'e' }; -static const symbol s_9[] = { 'e' }; -static const symbol s_10[] = { 'e' }; -static const symbol s_11[] = { 'y' }; -static const symbol s_12[] = { 'Y' }; -static const symbol s_13[] = { 'i' }; -static const symbol s_14[] = { 't', 'i', 'o', 'n' }; -static const symbol s_15[] = { 'e', 'n', 'c', 'e' }; -static const symbol s_16[] = { 'a', 'n', 'c', 'e' }; -static const symbol s_17[] = { 'a', 'b', 'l', 'e' }; -static const symbol s_18[] = { 'e', 'n', 't' }; -static const symbol s_19[] = { 'i', 'z', 'e' }; -static const symbol s_20[] = { 'a', 't', 'e' }; -static const symbol s_21[] = { 'a', 'l' }; -static const symbol s_22[] = { 'f', 'u', 'l' }; -static const symbol s_23[] = { 'o', 'u', 's' }; -static const symbol s_24[] = { 'i', 'v', 'e' }; -static const symbol s_25[] = { 'b', 'l', 'e' }; -static const symbol s_26[] = { 'l' }; -static const symbol s_27[] = { 'o', 'g' }; -static const symbol s_28[] = { 'f', 'u', 'l' }; -static const symbol s_29[] = { 'l', 'e', 's', 's' }; -static const symbol s_30[] = { 't', 'i', 'o', 'n' }; -static const symbol s_31[] = { 'a', 't', 'e' }; -static const symbol s_32[] = { 'a', 'l' }; -static const symbol s_33[] = { 'i', 'c' }; -static const symbol s_34[] = { 's' }; -static const symbol s_35[] = { 't' }; -static const symbol s_36[] = { 'l' }; -static const symbol s_37[] = { 's', 'k', 'i' }; -static const symbol s_38[] = { 's', 'k', 'y' }; -static const symbol s_39[] = { 'd', 'i', 'e' }; -static const symbol s_40[] = { 'l', 'i', 'e' }; -static const symbol s_41[] = { 't', 'i', 'e' }; -static const symbol s_42[] = { 'i', 'd', 'l' }; -static const symbol s_43[] = { 'g', 'e', 'n', 't', 'l' }; -static const symbol s_44[] = { 'u', 'g', 'l', 'i' }; -static const symbol s_45[] = { 'e', 'a', 'r', 'l', 'i' }; -static const symbol s_46[] = { 'o', 'n', 'l', 'i' }; -static const symbol s_47[] = { 's', 'i', 'n', 'g', 'l' }; -static const symbol s_48[] = { 'Y' }; -static const symbol s_49[] = { 'y' }; +static const symbol s_0[] = { 'Y' }; +static const symbol s_1[] = { 'Y' }; +static const symbol s_2[] = { 's', 's' }; +static const symbol s_3[] = { 'i' }; +static const symbol s_4[] = { 'i', 'e' }; +static const symbol s_5[] = { 'e', 'e' }; +static const symbol s_6[] = { 'e' }; +static const symbol s_7[] = { 'e' }; +static const symbol s_8[] = { 'i' }; +static const symbol s_9[] = { 't', 'i', 'o', 'n' }; +static const symbol s_10[] = { 'e', 'n', 'c', 'e' }; +static const symbol s_11[] = { 'a', 'n', 'c', 'e' }; +static const symbol s_12[] = { 'a', 'b', 'l', 'e' }; +static const symbol s_13[] = { 'e', 'n', 't' }; +static const symbol s_14[] = { 'i', 'z', 'e' }; +static const symbol s_15[] = { 'a', 't', 'e' }; +static const symbol s_16[] = { 'a', 'l' }; +static const symbol s_17[] = { 'f', 'u', 'l' }; +static const symbol s_18[] = { 'o', 'u', 's' }; +static const symbol s_19[] = { 'i', 'v', 'e' }; +static const symbol s_20[] = { 'b', 'l', 'e' }; +static const symbol s_21[] = { 'o', 'g' }; +static const symbol s_22[] = { 'l', 'e', 's', 's' }; +static const symbol s_23[] = { 't', 'i', 'o', 'n' }; +static const symbol s_24[] = { 'a', 't', 'e' }; +static const symbol s_25[] = { 'a', 'l' }; +static const symbol s_26[] = { 'i', 'c' }; +static const symbol s_27[] = { 's', 'k', 'i' }; +static const symbol s_28[] = { 's', 'k', 'y' }; +static const symbol s_29[] = { 'd', 'i', 'e' }; +static const symbol s_30[] = { 'l', 'i', 'e' }; +static const symbol s_31[] = { 't', 'i', 'e' }; +static const symbol s_32[] = { 'i', 'd', 'l' }; +static const symbol s_33[] = { 'g', 'e', 'n', 't', 'l' }; +static const symbol s_34[] = { 'u', 'g', 'l', 'i' }; +static const symbol s_35[] = { 'e', 'a', 'r', 'l', 'i' }; +static const symbol s_36[] = { 'o', 'n', 'l', 'i' }; +static const symbol s_37[] = { 's', 'i', 'n', 'g', 'l' }; +static const symbol s_38[] = { 'y' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ z->B[0] = 0; /* unset Y_found, line 26 */ { int c1 = z->c; /* do, line 27 */ z->bra = z->c; /* [, line 27 */ - if (!(eq_s(z, 1, s_0))) goto lab0; + if (z->c == z->l || z->p[z->c] != '\'') goto lab0; /* literal, line 27 */ + z->c++; z->ket = z->c; /* ], line 27 */ { int ret = slice_del(z); /* delete, line 27 */ if (ret < 0) return ret; @@ -382,9 +372,10 @@ static int r_prelude(struct SN_env * z) { } { int c2 = z->c; /* do, line 28 */ z->bra = z->c; /* [, line 28 */ - if (!(eq_s(z, 1, s_1))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'y') goto lab1; /* literal, line 28 */ + z->c++; z->ket = z->c; /* ], line 28 */ - { int ret = slice_from_s(z, 1, s_2); /* <-, line 28 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 28 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 28 */ @@ -396,9 +387,10 @@ static int r_prelude(struct SN_env * z) { int c4 = z->c; while(1) { /* goto, line 29 */ int c5 = z->c; - if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab4; + if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab4; /* grouping v, line 29 */ z->bra = z->c; /* [, line 29 */ - if (!(eq_s(z, 1, s_3))) goto lab4; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 29 */ + z->c++; z->ket = z->c; /* ], line 29 */ z->c = c5; break; @@ -409,7 +401,7 @@ static int r_prelude(struct SN_env * z) { z->c = ret; /* goto, line 29 */ } } - { int ret = slice_from_s(z, 1, s_4); /* <-, line 29 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 29 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 29 */ @@ -423,13 +415,13 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 33 */ + z->I[1] = z->l; /* $p2 = , line 34 */ { int c1 = z->c; /* do, line 35 */ { int c2 = z->c; /* or, line 41 */ - if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; - if (!(find_among(z, a_0, 3))) goto lab2; /* among, line 36 */ + if (z->c + 4 >= z->l || z->p[z->c + 4] >> 5 != 3 || !((2375680 >> (z->p[z->c + 4] & 0x1f)) & 1)) goto lab2; /* among, line 36 */ + if (!(find_among(z, a_0, 3))) goto lab2; goto lab1; lab2: z->c = c2; @@ -463,76 +455,69 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_shortv(struct SN_env * z) { +static int r_shortv(struct SN_env * z) { /* backwardmode */ { int m1 = z->l - z->c; (void)m1; /* or, line 51 */ - if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) goto lab1; - if (in_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; - if (out_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; + if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) goto lab1; /* non v_WXY, line 50 */ + if (in_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; /* grouping v, line 50 */ + if (out_grouping_b_U(z, g_v, 97, 121, 0)) goto lab1; /* non v, line 50 */ goto lab0; lab1: z->c = z->l - m1; - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; - if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 52 */ + if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 52 */ if (z->c > z->lb) return 0; /* atlimit, line 52 */ } lab0: return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 55 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 56 */ return 1; } -static int r_Step_1a(struct SN_env * z) { +static int r_Step_1a(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 59 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 59 */ z->ket = z->c; /* [, line 60 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m_keep; goto lab0; } - among_var = find_among_b(z, a_1, 3); /* substring, line 60 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || (z->p[z->c - 1] != 39 && z->p[z->c - 1] != 115)) { z->c = z->l - m1; goto lab0; } /* substring, line 60 */ + if (!(find_among_b(z, a_1, 3))) { z->c = z->l - m1; goto lab0; } z->bra = z->c; /* ], line 60 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } - case 1: - { int ret = slice_del(z); /* delete, line 62 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 62 */ + if (ret < 0) return ret; } lab0: ; } z->ket = z->c; /* [, line 65 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; - among_var = find_among_b(z, a_2, 6); /* substring, line 65 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 115)) return 0; /* substring, line 65 */ + among_var = find_among_b(z, a_2, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 65 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 65 */ case 1: - { int ret = slice_from_s(z, 2, s_5); /* <-, line 66 */ + { int ret = slice_from_s(z, 2, s_2); /* <-, line 66 */ if (ret < 0) return ret; } break; case 2: - { int m1 = z->l - z->c; (void)m1; /* or, line 68 */ - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 2); + { int m2 = z->l - z->c; (void)m2; /* or, line 68 */ + { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 2); /* hop, line 68 */ if (ret < 0) goto lab2; - z->c = ret; /* hop, line 68 */ + z->c = ret; } - { int ret = slice_from_s(z, 1, s_6); /* <-, line 68 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 68 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m1; - { int ret = slice_from_s(z, 2, s_7); /* <-, line 68 */ + z->c = z->l - m2; + { int ret = slice_from_s(z, 2, s_4); /* <-, line 68 */ if (ret < 0) return ret; } } @@ -556,48 +541,47 @@ static int r_Step_1a(struct SN_env * z) { return 1; } -static int r_Step_1b(struct SN_env * z) { +static int r_Step_1b(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 75 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_4, 6); /* substring, line 75 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33554576 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 75 */ + among_var = find_among_b(z, a_4, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 75 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 75 */ case 1: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 77 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 77 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_8); /* <-, line 77 */ + { int ret = slice_from_s(z, 2, s_5); /* <-, line 77 */ if (ret < 0) return ret; } break; case 2: - { int m_test = z->l - z->c; /* test, line 80 */ + { int m_test1 = z->l - z->c; /* test, line 80 */ { /* gopast */ /* grouping v, line 80 */ int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 80 */ if (ret < 0) return ret; } - { int m_test = z->l - z->c; /* test, line 81 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else - among_var = find_among_b(z, a_3, 13); /* substring, line 81 */ + { int m_test2 = z->l - z->c; /* test, line 81 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 81 */ + among_var = find_among_b(z, a_3, 13); if (!(among_var)) return 0; - z->c = z->l - m_test; + z->c = z->l - m_test2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 81 */ case 1: - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_9); /* <+, line 83 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_6); /* <+, line 83 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -614,16 +598,17 @@ static int r_Step_1b(struct SN_env * z) { break; case 3: if (z->c != z->I[0]) return 0; /* atmark, line 87 */ - { int m_test = z->l - z->c; /* test, line 87 */ - { int ret = r_shortv(z); - if (ret == 0) return 0; /* call shortv, line 87 */ - if (ret < 0) return ret; + { int m_test3 = z->l - z->c; /* test, line 87 */ + { int ret = r_shortv(z); /* call shortv, line 87 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test3; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_10); /* <+, line 87 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_7); /* <+, line 87 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -633,121 +618,115 @@ static int r_Step_1b(struct SN_env * z) { return 1; } -static int r_Step_1c(struct SN_env * z) { +static int r_Step_1c(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 94 */ { int m1 = z->l - z->c; (void)m1; /* or, line 94 */ - if (!(eq_s_b(z, 1, s_11))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 94 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_12))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 94 */ + z->c--; } lab0: z->bra = z->c; /* ], line 94 */ - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; - { int m2 = z->l - z->c; (void)m2; /* not, line 95 */ - if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ - return 0; - lab2: - z->c = z->l - m2; - } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 96 */ + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 95 */ + /* not, line 95 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 95 */ + return 0; +lab2: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 96 */ if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { +static int r_Step_2(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 100 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 24); /* substring, line 100 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 100 */ + among_var = find_among_b(z, a_5, 24); if (!(among_var)) return 0; z->bra = z->c; /* ], line 100 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 100 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 100 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 100 */ case 1: - { int ret = slice_from_s(z, 4, s_14); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_9); /* <-, line 101 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_15); /* <-, line 102 */ + { int ret = slice_from_s(z, 4, s_10); /* <-, line 102 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_16); /* <-, line 103 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 103 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_17); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 105 */ + { int ret = slice_from_s(z, 3, s_13); /* <-, line 105 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 107 */ + { int ret = slice_from_s(z, 3, s_14); /* <-, line 107 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 109 */ + { int ret = slice_from_s(z, 3, s_15); /* <-, line 109 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 2, s_21); /* <-, line 111 */ + { int ret = slice_from_s(z, 2, s_16); /* <-, line 111 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 3, s_22); /* <-, line 112 */ + { int ret = slice_from_s(z, 3, s_17); /* <-, line 112 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 3, s_23); /* <-, line 114 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 114 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_24); /* <-, line 116 */ + { int ret = slice_from_s(z, 3, s_19); /* <-, line 116 */ if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_25); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ if (ret < 0) return ret; } break; case 13: - if (!(eq_s_b(z, 1, s_26))) return 0; - { int ret = slice_from_s(z, 2, s_27); /* <-, line 119 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 119 */ + z->c--; + { int ret = slice_from_s(z, 2, s_21); /* <-, line 119 */ if (ret < 0) return ret; } break; case 14: - { int ret = slice_from_s(z, 3, s_28); /* <-, line 120 */ + { int ret = slice_from_s(z, 4, s_22); /* <-, line 121 */ if (ret < 0) return ret; } break; case 15: - { int ret = slice_from_s(z, 4, s_29); /* <-, line 121 */ - if (ret < 0) return ret; - } - break; - case 16: - if (in_grouping_b_U(z, g_valid_LI, 99, 116, 0)) return 0; + if (in_grouping_b_U(z, g_valid_LI, 99, 116, 0)) return 0; /* grouping valid_LI, line 122 */ { int ret = slice_del(z); /* delete, line 122 */ if (ret < 0) return ret; } @@ -756,36 +735,34 @@ static int r_Step_2(struct SN_env * z) { return 1; } -static int r_Step_3(struct SN_env * z) { +static int r_Step_3(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 127 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_6, 9); /* substring, line 127 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 127 */ + among_var = find_among_b(z, a_6, 9); if (!(among_var)) return 0; z->bra = z->c; /* ], line 127 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 127 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 127 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 127 */ case 1: - { int ret = slice_from_s(z, 4, s_30); /* <-, line 128 */ + { int ret = slice_from_s(z, 4, s_23); /* <-, line 128 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_31); /* <-, line 129 */ + { int ret = slice_from_s(z, 3, s_24); /* <-, line 129 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_32); /* <-, line 130 */ + { int ret = slice_from_s(z, 2, s_25); /* <-, line 130 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_33); /* <-, line 132 */ + { int ret = slice_from_s(z, 2, s_26); /* <-, line 132 */ if (ret < 0) return ret; } break; @@ -795,9 +772,8 @@ static int r_Step_3(struct SN_env * z) { } break; case 6: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 136 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; @@ -807,19 +783,17 @@ static int r_Step_3(struct SN_env * z) { return 1; } -static int r_Step_4(struct SN_env * z) { +static int r_Step_4(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 141 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_7, 18); /* substring, line 141 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1864232 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 141 */ + among_var = find_among_b(z, a_7, 18); if (!(among_var)) return 0; z->bra = z->c; /* ], line 141 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 141 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 141 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 141 */ case 1: { int ret = slice_del(z); /* delete, line 144 */ if (ret < 0) return ret; @@ -827,11 +801,13 @@ static int r_Step_4(struct SN_env * z) { break; case 2: { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - if (!(eq_s_b(z, 1, s_34))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 145 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_35))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 145 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 145 */ @@ -842,31 +818,29 @@ static int r_Step_4(struct SN_env * z) { return 1; } -static int r_Step_5(struct SN_env * z) { +static int r_Step_5(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 150 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; - among_var = find_among_b(z, a_8, 2); /* substring, line 150 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) return 0; /* substring, line 150 */ + among_var = find_among_b(z, a_8, 2); if (!(among_var)) return 0; z->bra = z->c; /* ], line 150 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 150 */ case 1: { int m1 = z->l - z->c; (void)m1; /* or, line 151 */ - { int ret = r_R2(z); - if (ret == 0) goto lab1; /* call R2, line 151 */ + { int ret = r_R2(z); /* call R2, line 151 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 151 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 151 */ + if (ret <= 0) return ret; } { int m2 = z->l - z->c; (void)m2; /* not, line 151 */ - { int ret = r_shortv(z); - if (ret == 0) goto lab2; /* call shortv, line 151 */ + { int ret = r_shortv(z); /* call shortv, line 151 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } return 0; @@ -880,11 +854,11 @@ static int r_Step_5(struct SN_env * z) { } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 152 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 152 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_36))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 152 */ + z->c--; { int ret = slice_del(z); /* delete, line 152 */ if (ret < 0) return ret; } @@ -893,77 +867,76 @@ static int r_Step_5(struct SN_env * z) { return 1; } -static int r_exception2(struct SN_env * z) { +static int r_exception2(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 158 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; - if (!(find_among_b(z, a_9, 8))) return 0; /* substring, line 158 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 158 */ + if (!(find_among_b(z, a_9, 8))) return 0; z->bra = z->c; /* ], line 158 */ if (z->c > z->lb) return 0; /* atlimit, line 158 */ return 1; } -static int r_exception1(struct SN_env * z) { +static int r_exception1(struct SN_env * z) { /* forwardmode */ int among_var; z->bra = z->c; /* [, line 170 */ - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; - among_var = find_among(z, a_10, 18); /* substring, line 170 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((42750482 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* substring, line 170 */ + among_var = find_among(z, a_10, 18); if (!(among_var)) return 0; z->ket = z->c; /* ], line 170 */ if (z->c < z->l) return 0; /* atlimit, line 170 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 170 */ case 1: - { int ret = slice_from_s(z, 3, s_37); /* <-, line 174 */ + { int ret = slice_from_s(z, 3, s_27); /* <-, line 174 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 3, s_38); /* <-, line 175 */ + { int ret = slice_from_s(z, 3, s_28); /* <-, line 175 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_39); /* <-, line 176 */ + { int ret = slice_from_s(z, 3, s_29); /* <-, line 176 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 3, s_40); /* <-, line 177 */ + { int ret = slice_from_s(z, 3, s_30); /* <-, line 177 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_41); /* <-, line 178 */ + { int ret = slice_from_s(z, 3, s_31); /* <-, line 178 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 3, s_42); /* <-, line 182 */ + { int ret = slice_from_s(z, 3, s_32); /* <-, line 182 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 5, s_43); /* <-, line 183 */ + { int ret = slice_from_s(z, 5, s_33); /* <-, line 183 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 4, s_44); /* <-, line 184 */ + { int ret = slice_from_s(z, 4, s_34); /* <-, line 184 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 5, s_45); /* <-, line 185 */ + { int ret = slice_from_s(z, 5, s_35); /* <-, line 185 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 4, s_46); /* <-, line 186 */ + { int ret = slice_from_s(z, 4, s_36); /* <-, line 186 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 5, s_47); /* <-, line 187 */ + { int ret = slice_from_s(z, 5, s_37); /* <-, line 187 */ if (ret < 0) return ret; } break; @@ -971,14 +944,15 @@ static int r_exception1(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ if (!(z->B[0])) return 0; /* Boolean test Y_found, line 203 */ while(1) { /* repeat, line 203 */ int c1 = z->c; while(1) { /* goto, line 203 */ int c2 = z->c; z->bra = z->c; /* [, line 203 */ - if (!(eq_s(z, 1, s_48))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab1; /* literal, line 203 */ + z->c++; z->ket = z->c; /* ], line 203 */ z->c = c2; break; @@ -989,7 +963,7 @@ static int r_postlude(struct SN_env * z) { z->c = ret; /* goto, line 203 */ } } - { int ret = slice_from_s(z, 1, s_49); /* <-, line 203 */ + { int ret = slice_from_s(z, 1, s_38); /* <-, line 203 */ if (ret < 0) return ret; } continue; @@ -1000,19 +974,19 @@ static int r_postlude(struct SN_env * z) { return 1; } -extern int english_UTF_8_stem(struct SN_env * z) { +extern int english_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* or, line 207 */ - { int ret = r_exception1(z); - if (ret == 0) goto lab1; /* call exception1, line 207 */ + { int ret = r_exception1(z); /* call exception1, line 207 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = c1; { int c2 = z->c; /* not, line 208 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 208 */ if (ret < 0) goto lab3; - z->c = ret; /* hop, line 208 */ + z->c = ret; } goto lab2; lab3: @@ -1021,98 +995,94 @@ extern int english_UTF_8_stem(struct SN_env * z) { goto lab0; lab2: z->c = c1; - { int c3 = z->c; /* do, line 209 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab4; /* call prelude, line 209 */ - if (ret < 0) return ret; - } - lab4: - z->c = c3; + /* do, line 209 */ + { int ret = r_prelude(z); /* call prelude, line 209 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; } - { int c4 = z->c; /* do, line 210 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab5; /* call mark_regions, line 210 */ - if (ret < 0) return ret; - } - lab5: - z->c = c4; + lab4: + /* do, line 210 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 210 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; } + lab5: z->lb = z->c; z->c = z->l; /* backwards, line 211 */ - { int m5 = z->l - z->c; (void)m5; /* do, line 213 */ - { int ret = r_Step_1a(z); - if (ret == 0) goto lab6; /* call Step_1a, line 213 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 213 */ + { int ret = r_Step_1a(z); /* call Step_1a, line 213 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m5; + z->c = z->l - m3; } - { int m6 = z->l - z->c; (void)m6; /* or, line 215 */ - { int ret = r_exception2(z); - if (ret == 0) goto lab8; /* call exception2, line 215 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 215 */ + { int ret = r_exception2(z); /* call exception2, line 215 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: - z->c = z->l - m6; - { int m7 = z->l - z->c; (void)m7; /* do, line 217 */ - { int ret = r_Step_1b(z); - if (ret == 0) goto lab9; /* call Step_1b, line 217 */ + z->c = z->l - m4; + { int m5 = z->l - z->c; (void)m5; /* do, line 217 */ + { int ret = r_Step_1b(z); /* call Step_1b, line 217 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: - z->c = z->l - m7; + z->c = z->l - m5; } - { int m8 = z->l - z->c; (void)m8; /* do, line 218 */ - { int ret = r_Step_1c(z); - if (ret == 0) goto lab10; /* call Step_1c, line 218 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 218 */ + { int ret = r_Step_1c(z); /* call Step_1c, line 218 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } lab10: - z->c = z->l - m8; + z->c = z->l - m6; } - { int m9 = z->l - z->c; (void)m9; /* do, line 220 */ - { int ret = r_Step_2(z); - if (ret == 0) goto lab11; /* call Step_2, line 220 */ + { int m7 = z->l - z->c; (void)m7; /* do, line 220 */ + { int ret = r_Step_2(z); /* call Step_2, line 220 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: - z->c = z->l - m9; + z->c = z->l - m7; } - { int m10 = z->l - z->c; (void)m10; /* do, line 221 */ - { int ret = r_Step_3(z); - if (ret == 0) goto lab12; /* call Step_3, line 221 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 221 */ + { int ret = r_Step_3(z); /* call Step_3, line 221 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: - z->c = z->l - m10; + z->c = z->l - m8; } - { int m11 = z->l - z->c; (void)m11; /* do, line 222 */ - { int ret = r_Step_4(z); - if (ret == 0) goto lab13; /* call Step_4, line 222 */ + { int m9 = z->l - z->c; (void)m9; /* do, line 222 */ + { int ret = r_Step_4(z); /* call Step_4, line 222 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } lab13: - z->c = z->l - m11; + z->c = z->l - m9; } - { int m12 = z->l - z->c; (void)m12; /* do, line 224 */ - { int ret = r_Step_5(z); - if (ret == 0) goto lab14; /* call Step_5, line 224 */ + { int m10 = z->l - z->c; (void)m10; /* do, line 224 */ + { int ret = r_Step_5(z); /* call Step_5, line 224 */ + if (ret == 0) goto lab14; if (ret < 0) return ret; } lab14: - z->c = z->l - m12; + z->c = z->l - m10; } } lab7: z->c = z->lb; - { int c13 = z->c; /* do, line 227 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab15; /* call postlude, line 227 */ + { int c11 = z->c; /* do, line 227 */ + { int ret = r_postlude(z); /* call postlude, line 227 */ + if (ret == 0) goto lab15; if (ret < 0) return ret; } lab15: - z->c = c13; + z->c = c11; } } lab0: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c index 55fba0a732d..0cbb64d65bf 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_finnish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -183,7 +183,7 @@ static const struct among a_6[30] = /* 4 */ { 2, s_6_4, 0, -1, 0}, /* 5 */ { 3, s_6_5, 4, -1, 0}, /* 6 */ { 3, s_6_6, 4, -1, 0}, -/* 7 */ { 3, s_6_7, 4, 9, 0}, +/* 7 */ { 3, s_6_7, 4, 2, 0}, /* 8 */ { 3, s_6_8, -1, -1, 0}, /* 9 */ { 3, s_6_9, -1, -1, 0}, /* 10 */ { 3, s_6_10, -1, -1, 0}, @@ -205,7 +205,7 @@ static const struct among a_6[30] = /* 26 */ { 3, s_6_26, 22, -1, 0}, /* 27 */ { 4, s_6_27, 26, -1, 0}, /* 28 */ { 4, s_6_28, 26, -1, 0}, -/* 29 */ { 4, s_6_29, 26, 9, 0} +/* 29 */ { 4, s_6_29, 26, 2, 0} }; static const symbol s_7_0[3] = { 'e', 'j', 'a' }; @@ -261,151 +261,134 @@ static const struct among a_9[2] = static const unsigned char g_AEI[] = { 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 }; +static const unsigned char g_C[] = { 119, 223, 119, 1 }; + static const unsigned char g_V1[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; static const unsigned char g_V2[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; static const unsigned char g_particle_end[] = { 17, 97, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 32 }; -static const symbol s_0[] = { 'k' }; -static const symbol s_1[] = { 'k', 's', 'e' }; -static const symbol s_2[] = { 'k', 's', 'i' }; -static const symbol s_3[] = { 'i' }; -static const symbol s_4[] = { 'a' }; -static const symbol s_5[] = { 'e' }; -static const symbol s_6[] = { 'i' }; -static const symbol s_7[] = { 'o' }; -static const symbol s_8[] = { 0xC3, 0xA4 }; -static const symbol s_9[] = { 0xC3, 0xB6 }; -static const symbol s_10[] = { 'i', 'e' }; -static const symbol s_11[] = { 'e' }; -static const symbol s_12[] = { 'p', 'o' }; -static const symbol s_13[] = { 't' }; -static const symbol s_14[] = { 'p', 'o' }; -static const symbol s_15[] = { 'j' }; -static const symbol s_16[] = { 'o' }; -static const symbol s_17[] = { 'u' }; -static const symbol s_18[] = { 'o' }; -static const symbol s_19[] = { 'j' }; - -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 46 */ - { /* gopast */ /* non V1, line 46 */ +static const symbol s_0[] = { 'k', 's', 'e' }; +static const symbol s_1[] = { 'k', 's', 'i' }; +static const symbol s_2[] = { 0xC3, 0xA4 }; +static const symbol s_3[] = { 0xC3, 0xB6 }; +static const symbol s_4[] = { 'i', 'e' }; +static const symbol s_5[] = { 'p', 'o' }; +static const symbol s_6[] = { 'p', 'o' }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 44 */ + z->I[1] = z->l; /* $p2 = , line 45 */ + if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ + { /* gopast */ /* non V1, line 47 */ int ret = in_grouping_U(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 46 */ - if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 47 */ - { /* gopast */ /* non V1, line 47 */ + z->I[0] = z->c; /* setmark p1, line 47 */ + if (out_grouping_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* grouping V1, line 48 */ + { /* gopast */ /* non V1, line 48 */ int ret = in_grouping_U(z, g_V1, 97, 246, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 47 */ + z->I[1] = z->c; /* setmark p2, line 48 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 53 */ return 1; } -static int r_particle_etc(struct SN_env * z) { +static int r_particle_etc(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 55 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 56 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 55 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 55 */ - among_var = find_among_b(z, a_0, 10); /* substring, line 55 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 55 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 56 */ + among_var = find_among_b(z, a_0, 10); /* substring, line 56 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 56 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 57 */ case 1: - if (in_grouping_b_U(z, g_particle_end, 97, 246, 0)) return 0; + if (in_grouping_b_U(z, g_particle_end, 97, 246, 0)) return 0; /* grouping particle_end, line 63 */ break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 64 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 65 */ + if (ret <= 0) return ret; } break; } - { int ret = slice_del(z); /* delete, line 66 */ + { int ret = slice_del(z); /* delete, line 67 */ if (ret < 0) return ret; } return 1; } -static int r_possessive(struct SN_env * z) { +static int r_possessive(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 69 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 70 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 69 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 69 */ - among_var = find_among_b(z, a_4, 9); /* substring, line 69 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 69 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 70 */ + among_var = find_among_b(z, a_4, 9); /* substring, line 70 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 70 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 71 */ case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 72 */ - if (!(eq_s_b(z, 1, s_0))) goto lab0; + { int m2 = z->l - z->c; (void)m2; /* not, line 73 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'k') goto lab0; /* literal, line 73 */ + z->c--; return 0; lab0: z->c = z->l - m2; } - { int ret = slice_del(z); /* delete, line 72 */ + { int ret = slice_del(z); /* delete, line 73 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 74 */ + { int ret = slice_del(z); /* delete, line 75 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 74 */ - if (!(eq_s_b(z, 3, s_1))) return 0; - z->bra = z->c; /* ], line 74 */ - { int ret = slice_from_s(z, 3, s_2); /* <-, line 74 */ + z->ket = z->c; /* [, line 75 */ + if (!(eq_s_b(z, 3, s_0))) return 0; /* literal, line 75 */ + z->bra = z->c; /* ], line 75 */ + { int ret = slice_from_s(z, 3, s_1); /* <-, line 75 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 78 */ + { int ret = slice_del(z); /* delete, line 79 */ if (ret < 0) return ret; } break; case 4: - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; - if (!(find_among_b(z, a_1, 6))) return 0; /* among, line 81 */ - { int ret = slice_del(z); /* delete, line 81 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 97) return 0; /* among, line 82 */ + if (!(find_among_b(z, a_1, 6))) return 0; + { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } break; case 5: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 164) return 0; - if (!(find_among_b(z, a_2, 6))) return 0; /* among, line 83 */ - { int ret = slice_del(z); /* delete, line 84 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 164) return 0; /* among, line 84 */ + if (!(find_among_b(z, a_2, 6))) return 0; + { int ret = slice_del(z); /* delete, line 85 */ if (ret < 0) return ret; } break; case 6: - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; - if (!(find_among_b(z, a_3, 2))) return 0; /* among, line 86 */ - { int ret = slice_del(z); /* delete, line 86 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 101) return 0; /* among, line 87 */ + if (!(find_among_b(z, a_3, 2))) return 0; + { int ret = slice_del(z); /* delete, line 87 */ if (ret < 0) return ret; } break; @@ -413,350 +396,338 @@ static int r_possessive(struct SN_env * z) { return 1; } -static int r_LONG(struct SN_env * z) { - if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 91 */ +static int r_LONG(struct SN_env * z) { /* backwardmode */ + if (!(find_among_b(z, a_5, 7))) return 0; /* among, line 92 */ return 1; } -static int r_VI(struct SN_env * z) { - if (!(eq_s_b(z, 1, s_3))) return 0; - if (in_grouping_b_U(z, g_V2, 97, 246, 0)) return 0; +static int r_VI(struct SN_env * z) { /* backwardmode */ + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 94 */ + z->c--; + if (in_grouping_b_U(z, g_V2, 97, 246, 0)) return 0; /* grouping V2, line 94 */ return 1; } -static int r_case_ending(struct SN_env * z) { +static int r_case_ending(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 96 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 97 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 96 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 96 */ - among_var = find_among_b(z, a_6, 30); /* substring, line 96 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 96 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 97 */ + among_var = find_among_b(z, a_6, 30); /* substring, line 97 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 97 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 98 */ case 1: - if (!(eq_s_b(z, 1, s_4))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'a') return 0; /* literal, line 99 */ + z->c--; break; case 2: - if (!(eq_s_b(z, 1, s_5))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 100 */ + z->c--; break; case 3: - if (!(eq_s_b(z, 1, s_6))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 101 */ + z->c--; break; case 4: - if (!(eq_s_b(z, 1, s_7))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') return 0; /* literal, line 102 */ + z->c--; break; case 5: - if (!(eq_s_b(z, 2, s_8))) return 0; + if (!(eq_s_b(z, 2, s_2))) return 0; /* literal, line 103 */ break; case 6: - if (!(eq_s_b(z, 2, s_9))) return 0; + if (!(eq_s_b(z, 2, s_3))) return 0; /* literal, line 104 */ break; case 7: - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ - { int m2 = z->l - z->c; (void)m2; /* and, line 113 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 112 */ - { int ret = r_LONG(z); - if (ret == 0) goto lab2; /* call LONG, line 111 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 112 */ + { int m3 = z->l - z->c; (void)m3; /* and, line 114 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 113 */ + { int ret = r_LONG(z); /* call LONG, line 112 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m3; - if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m_keep; goto lab0; } + z->c = z->l - m4; + if (!(eq_s_b(z, 2, s_4))) { z->c = z->l - m2; goto lab0; } /* literal, line 113 */ } lab1: - z->c = z->l - m2; + z->c = z->l - m3; { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) { z->c = z->l - m_keep; goto lab0; } - z->c = ret; /* next, line 113 */ + if (ret < 0) { z->c = z->l - m2; goto lab0; } + z->c = ret; /* next, line 114 */ } } - z->bra = z->c; /* ], line 113 */ + z->bra = z->c; /* ], line 114 */ lab0: ; } break; case 8: - if (in_grouping_b_U(z, g_V1, 97, 246, 0)) return 0; - if (out_grouping_b_U(z, g_V1, 97, 246, 0)) return 0; - break; - case 9: - if (!(eq_s_b(z, 1, s_11))) return 0; + if (in_grouping_b_U(z, g_V1, 97, 246, 0)) return 0; /* grouping V1, line 120 */ + if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 120 */ break; } - { int ret = slice_del(z); /* delete, line 138 */ + { int ret = slice_del(z); /* delete, line 139 */ if (ret < 0) return ret; } - z->B[0] = 1; /* set ending_removed, line 139 */ + z->B[0] = 1; /* set ending_removed, line 140 */ return 1; } -static int r_other_endings(struct SN_env * z) { +static int r_other_endings(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 142 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 143 */ if (z->c < z->I[1]) return 0; - z->c = z->I[1]; /* tomark, line 142 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 142 */ - among_var = find_among_b(z, a_7, 14); /* substring, line 142 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 142 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[1]; + z->ket = z->c; /* [, line 143 */ + among_var = find_among_b(z, a_7, 14); /* substring, line 143 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 143 */ + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 144 */ case 1: - { int m2 = z->l - z->c; (void)m2; /* not, line 146 */ - if (!(eq_s_b(z, 2, s_12))) goto lab0; + { int m2 = z->l - z->c; (void)m2; /* not, line 147 */ + if (!(eq_s_b(z, 2, s_5))) goto lab0; /* literal, line 147 */ return 0; lab0: z->c = z->l - m2; } break; } - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); /* delete, line 152 */ if (ret < 0) return ret; } return 1; } -static int r_i_plural(struct SN_env * z) { - { int mlimit; /* setlimit, line 154 */ - int m1 = z->l - z->c; (void)m1; +static int r_i_plural(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 155 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 154 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 154 */ - if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit; return 0; } /* substring, line 154 */ - z->bra = z->c; /* ], line 154 */ - z->lb = mlimit; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 155 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 106)) { z->lb = mlimit1; return 0; } /* substring, line 155 */ + if (!(find_among_b(z, a_8, 2))) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 155 */ + z->lb = mlimit1; } - { int ret = slice_del(z); /* delete, line 158 */ + { int ret = slice_del(z); /* delete, line 159 */ if (ret < 0) return ret; } return 1; } -static int r_t_plural(struct SN_env * z) { +static int r_t_plural(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 161 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 162 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 161 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 162 */ - if (!(eq_s_b(z, 1, s_13))) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 162 */ - { int m_test = z->l - z->c; /* test, line 162 */ - if (in_grouping_b_U(z, g_V1, 97, 246, 0)) { z->lb = mlimit; return 0; } - z->c = z->l - m_test; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 163 */ + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit1; return 0; } /* literal, line 163 */ + z->c--; + z->bra = z->c; /* ], line 163 */ + { int m_test2 = z->l - z->c; /* test, line 163 */ + if (in_grouping_b_U(z, g_V1, 97, 246, 0)) { z->lb = mlimit1; return 0; } /* grouping V1, line 163 */ + z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_del(z); /* delete, line 164 */ if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } - { int mlimit; /* setlimit, line 165 */ - int m2 = z->l - z->c; (void)m2; + + { int mlimit3; /* setlimit, line 166 */ if (z->c < z->I[1]) return 0; - z->c = z->I[1]; /* tomark, line 165 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - z->ket = z->c; /* [, line 165 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_9, 2); /* substring, line 165 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 165 */ - z->lb = mlimit; + mlimit3 = z->lb; z->lb = z->I[1]; + z->ket = z->c; /* [, line 166 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 97) { z->lb = mlimit3; return 0; } /* substring, line 166 */ + among_var = find_among_b(z, a_9, 2); + if (!(among_var)) { z->lb = mlimit3; return 0; } + z->bra = z->c; /* ], line 166 */ + z->lb = mlimit3; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 167 */ case 1: - { int m3 = z->l - z->c; (void)m3; /* not, line 167 */ - if (!(eq_s_b(z, 2, s_14))) goto lab0; + { int m4 = z->l - z->c; (void)m4; /* not, line 168 */ + if (!(eq_s_b(z, 2, s_6))) goto lab0; /* literal, line 168 */ return 0; lab0: - z->c = z->l - m3; + z->c = z->l - m4; } break; } - { int ret = slice_del(z); /* delete, line 170 */ + { int ret = slice_del(z); /* delete, line 171 */ if (ret < 0) return ret; } return 1; } -static int r_tidy(struct SN_env * z) { - { int mlimit; /* setlimit, line 173 */ - int m1 = z->l - z->c; (void)m1; +static int r_tidy(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 174 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 173 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* do, line 174 */ - { int m3 = z->l - z->c; (void)m3; /* and, line 174 */ - { int ret = r_LONG(z); - if (ret == 0) goto lab0; /* call LONG, line 174 */ + mlimit1 = z->lb; z->lb = z->I[0]; + { int m2 = z->l - z->c; (void)m2; /* do, line 175 */ + { int m3 = z->l - z->c; (void)m3; /* and, line 175 */ + { int ret = r_LONG(z); /* call LONG, line 175 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } z->c = z->l - m3; - z->ket = z->c; /* [, line 174 */ + z->ket = z->c; /* [, line 175 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 174 */ + z->c = ret; /* next, line 175 */ } - z->bra = z->c; /* ], line 174 */ - { int ret = slice_del(z); /* delete, line 174 */ + z->bra = z->c; /* ], line 175 */ + { int ret = slice_del(z); /* delete, line 175 */ if (ret < 0) return ret; } } lab0: z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 175 */ - z->ket = z->c; /* [, line 175 */ - if (in_grouping_b_U(z, g_AEI, 97, 228, 0)) goto lab1; - z->bra = z->c; /* ], line 175 */ - if (out_grouping_b_U(z, g_V1, 97, 246, 0)) goto lab1; - { int ret = slice_del(z); /* delete, line 175 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 176 */ + z->ket = z->c; /* [, line 176 */ + if (in_grouping_b_U(z, g_AEI, 97, 228, 0)) goto lab1; /* grouping AEI, line 176 */ + z->bra = z->c; /* ], line 176 */ + if (in_grouping_b_U(z, g_C, 98, 122, 0)) goto lab1; /* grouping C, line 176 */ + { int ret = slice_del(z); /* delete, line 176 */ if (ret < 0) return ret; } lab1: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 176 */ - z->ket = z->c; /* [, line 176 */ - if (!(eq_s_b(z, 1, s_15))) goto lab2; - z->bra = z->c; /* ], line 176 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 176 */ - if (!(eq_s_b(z, 1, s_16))) goto lab4; + { int m5 = z->l - z->c; (void)m5; /* do, line 177 */ + z->ket = z->c; /* [, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab2; /* literal, line 177 */ + z->c--; + z->bra = z->c; /* ], line 177 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab4; /* literal, line 177 */ + z->c--; goto lab3; lab4: z->c = z->l - m6; - if (!(eq_s_b(z, 1, s_17))) goto lab2; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab2; /* literal, line 177 */ + z->c--; } lab3: - { int ret = slice_del(z); /* delete, line 176 */ + { int ret = slice_del(z); /* delete, line 177 */ if (ret < 0) return ret; } lab2: z->c = z->l - m5; } - { int m7 = z->l - z->c; (void)m7; /* do, line 177 */ - z->ket = z->c; /* [, line 177 */ - if (!(eq_s_b(z, 1, s_18))) goto lab5; - z->bra = z->c; /* ], line 177 */ - if (!(eq_s_b(z, 1, s_19))) goto lab5; - { int ret = slice_del(z); /* delete, line 177 */ + { int m7 = z->l - z->c; (void)m7; /* do, line 178 */ + z->ket = z->c; /* [, line 178 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 178 */ + z->c--; + z->bra = z->c; /* ], line 178 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'j') goto lab5; /* literal, line 178 */ + z->c--; + { int ret = slice_del(z); /* delete, line 178 */ if (ret < 0) return ret; } lab5: z->c = z->l - m7; } - z->lb = mlimit; + z->lb = mlimit1; } - if (in_grouping_b_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 179 */ - z->ket = z->c; /* [, line 179 */ - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) return 0; - z->c = ret; /* next, line 179 */ - } - z->bra = z->c; /* ], line 179 */ - z->S[0] = slice_to(z, z->S[0]); /* -> x, line 179 */ - if (z->S[0] == 0) return -1; /* -> x, line 179 */ - if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 179 */ - { int ret = slice_del(z); /* delete, line 179 */ + if (in_grouping_b_U(z, g_V1, 97, 246, 1) < 0) return 0; /* goto */ /* non V1, line 180 */ + z->ket = z->c; /* [, line 180 */ + if (in_grouping_b_U(z, g_C, 98, 122, 0)) return 0; /* grouping C, line 180 */ + z->bra = z->c; /* ], line 180 */ + z->S[0] = slice_to(z, z->S[0]); /* -> x, line 180 */ + if (z->S[0] == 0) return -1; /* -> x, line 180 */ + if (!(eq_v_b(z, z->S[0]))) return 0; /* name x, line 180 */ + { int ret = slice_del(z); /* delete, line 180 */ if (ret < 0) return ret; } return 1; } -extern int finnish_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 185 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 185 */ +extern int finnish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 186 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 186 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - z->B[0] = 0; /* unset ending_removed, line 186 */ - z->lb = z->c; z->c = z->l; /* backwards, line 187 */ + z->B[0] = 0; /* unset ending_removed, line 187 */ + z->lb = z->c; z->c = z->l; /* backwards, line 188 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 188 */ - { int ret = r_particle_etc(z); - if (ret == 0) goto lab1; /* call particle_etc, line 188 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 189 */ + { int ret = r_particle_etc(z); /* call particle_etc, line 189 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 189 */ - { int ret = r_possessive(z); - if (ret == 0) goto lab2; /* call possessive, line 189 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 190 */ + { int ret = r_possessive(z); /* call possessive, line 190 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } - { int m4 = z->l - z->c; (void)m4; /* do, line 190 */ - { int ret = r_case_ending(z); - if (ret == 0) goto lab3; /* call case_ending, line 190 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 191 */ + { int ret = r_case_ending(z); /* call case_ending, line 191 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } - { int m5 = z->l - z->c; (void)m5; /* do, line 191 */ - { int ret = r_other_endings(z); - if (ret == 0) goto lab4; /* call other_endings, line 191 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 192 */ + { int ret = r_other_endings(z); /* call other_endings, line 192 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: z->c = z->l - m5; } - { int m6 = z->l - z->c; (void)m6; /* or, line 192 */ - if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 192 */ - { int m7 = z->l - z->c; (void)m7; /* do, line 192 */ - { int ret = r_i_plural(z); - if (ret == 0) goto lab7; /* call i_plural, line 192 */ - if (ret < 0) return ret; - } - lab7: - z->c = z->l - m7; + /* or, line 193 */ + if (!(z->B[0])) goto lab6; /* Boolean test ending_removed, line 193 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 193 */ + { int ret = r_i_plural(z); /* call i_plural, line 193 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; } - goto lab5; - lab6: + lab7: z->c = z->l - m6; - { int m8 = z->l - z->c; (void)m8; /* do, line 192 */ - { int ret = r_t_plural(z); - if (ret == 0) goto lab8; /* call t_plural, line 192 */ - if (ret < 0) return ret; - } - lab8: - z->c = z->l - m8; + } + goto lab5; +lab6: + { int m7 = z->l - z->c; (void)m7; /* do, line 193 */ + { int ret = r_t_plural(z); /* call t_plural, line 193 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; } + lab8: + z->c = z->l - m7; } lab5: - { int m9 = z->l - z->c; (void)m9; /* do, line 193 */ - { int ret = r_tidy(z); - if (ret == 0) goto lab9; /* call tidy, line 193 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 194 */ + { int ret = r_tidy(z); /* call tidy, line 194 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: - z->c = z->l - m9; + z->c = z->l - m8; } z->c = z->lb; return 1; diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_french.c b/src/backend/snowball/libstemmer/stem_UTF_8_french.c index fa1507f2c63..9e12865c678 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_french.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_french.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -45,16 +45,22 @@ static const struct among a_0[3] = /* 2 */ { 3, s_0_2, -1, -1, 0} }; -static const symbol s_1_1[1] = { 'I' }; -static const symbol s_1_2[1] = { 'U' }; -static const symbol s_1_3[1] = { 'Y' }; +static const symbol s_1_1[1] = { 'H' }; +static const symbol s_1_2[2] = { 'H', 'e' }; +static const symbol s_1_3[2] = { 'H', 'i' }; +static const symbol s_1_4[1] = { 'I' }; +static const symbol s_1_5[1] = { 'U' }; +static const symbol s_1_6[1] = { 'Y' }; -static const struct among a_1[4] = +static const struct among a_1[7] = { -/* 0 */ { 0, 0, -1, 4, 0}, -/* 1 */ { 1, s_1_1, 0, 1, 0}, -/* 2 */ { 1, s_1_2, 0, 2, 0}, -/* 3 */ { 1, s_1_3, 0, 3, 0} +/* 0 */ { 0, 0, -1, 7, 0}, +/* 1 */ { 1, s_1_1, 0, 6, 0}, +/* 2 */ { 2, s_1_2, 1, 4, 0}, +/* 3 */ { 2, s_1_3, 1, 5, 0}, +/* 4 */ { 1, s_1_4, 0, 1, 0}, +/* 5 */ { 1, s_1_5, 0, 2, 0}, +/* 6 */ { 1, s_1_6, 0, 3, 0} }; static const symbol s_2_0[3] = { 'i', 'q', 'U' }; @@ -338,17 +344,15 @@ static const symbol s_7_2[5] = { 'i', 0xC3, 0xA8, 'r', 'e' }; static const symbol s_7_3[3] = { 'i', 'o', 'n' }; static const symbol s_7_4[3] = { 'I', 'e', 'r' }; static const symbol s_7_5[3] = { 'i', 'e', 'r' }; -static const symbol s_7_6[2] = { 0xC3, 0xAB }; -static const struct among a_7[7] = +static const struct among a_7[6] = { /* 0 */ { 1, s_7_0, -1, 3, 0}, /* 1 */ { 5, s_7_1, 0, 2, 0}, /* 2 */ { 5, s_7_2, 0, 2, 0}, /* 3 */ { 3, s_7_3, -1, 1, 0}, /* 4 */ { 3, s_7_4, -1, 2, 0}, -/* 5 */ { 3, s_7_5, -1, 2, 0}, -/* 6 */ { 2, s_7_6, -1, 4, 0} +/* 5 */ { 3, s_7_5, -1, 2, 0} }; static const symbol s_8_0[3] = { 'e', 'l', 'l' }; @@ -370,20 +374,20 @@ static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static const unsigned char g_keep_with_s[] = { 1, 65, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 }; -static const symbol s_0[] = { 'u' }; -static const symbol s_1[] = { 'U' }; -static const symbol s_2[] = { 'i' }; -static const symbol s_3[] = { 'I' }; -static const symbol s_4[] = { 'y' }; -static const symbol s_5[] = { 'Y' }; -static const symbol s_6[] = { 'y' }; +static const symbol s_0[] = { 'U' }; +static const symbol s_1[] = { 'I' }; +static const symbol s_2[] = { 'Y' }; +static const symbol s_3[] = { 0xC3, 0xAB }; +static const symbol s_4[] = { 'H', 'e' }; +static const symbol s_5[] = { 0xC3, 0xAF }; +static const symbol s_6[] = { 'H', 'i' }; static const symbol s_7[] = { 'Y' }; -static const symbol s_8[] = { 'q' }; -static const symbol s_9[] = { 'u' }; -static const symbol s_10[] = { 'U' }; -static const symbol s_11[] = { 'i' }; -static const symbol s_12[] = { 'u' }; -static const symbol s_13[] = { 'y' }; +static const symbol s_8[] = { 'U' }; +static const symbol s_9[] = { 'i' }; +static const symbol s_10[] = { 'u' }; +static const symbol s_11[] = { 'y' }; +static const symbol s_12[] = { 0xC3, 0xAB }; +static const symbol s_13[] = { 0xC3, 0xAF }; static const symbol s_14[] = { 'i', 'c' }; static const symbol s_15[] = { 'i', 'q', 'U' }; static const symbol s_16[] = { 'l', 'o', 'g' }; @@ -402,50 +406,48 @@ static const symbol s_28[] = { 'a', 'l' }; static const symbol s_29[] = { 'e', 'u', 'x' }; static const symbol s_30[] = { 'a', 'n', 't' }; static const symbol s_31[] = { 'e', 'n', 't' }; -static const symbol s_32[] = { 'e' }; -static const symbol s_33[] = { 's' }; -static const symbol s_34[] = { 's' }; -static const symbol s_35[] = { 't' }; -static const symbol s_36[] = { 'i' }; -static const symbol s_37[] = { 'g', 'u' }; -static const symbol s_38[] = { 0xC3, 0xA9 }; -static const symbol s_39[] = { 0xC3, 0xA8 }; -static const symbol s_40[] = { 'e' }; -static const symbol s_41[] = { 'Y' }; -static const symbol s_42[] = { 'i' }; -static const symbol s_43[] = { 0xC3, 0xA7 }; -static const symbol s_44[] = { 'c' }; +static const symbol s_32[] = { 'H', 'i' }; +static const symbol s_33[] = { 'i' }; +static const symbol s_34[] = { 0xC3, 0xA9 }; +static const symbol s_35[] = { 0xC3, 0xA8 }; +static const symbol s_36[] = { 'e' }; +static const symbol s_37[] = { 'i' }; +static const symbol s_38[] = { 0xC3, 0xA7 }; +static const symbol s_39[] = { 'c' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ while(1) { /* repeat, line 38 */ int c1 = z->c; while(1) { /* goto, line 38 */ int c2 = z->c; { int c3 = z->c; /* or, line 44 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab3; + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab3; /* grouping v, line 40 */ z->bra = z->c; /* [, line 40 */ { int c4 = z->c; /* or, line 40 */ - if (!(eq_s(z, 1, s_0))) goto lab5; + if (z->c == z->l || z->p[z->c] != 'u') goto lab5; /* literal, line 40 */ + z->c++; z->ket = z->c; /* ], line 40 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab5; - { int ret = slice_from_s(z, 1, s_1); /* <-, line 40 */ + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab5; /* grouping v, line 40 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 40 */ if (ret < 0) return ret; } goto lab4; lab5: z->c = c4; - if (!(eq_s(z, 1, s_2))) goto lab6; + if (z->c == z->l || z->p[z->c] != 'i') goto lab6; /* literal, line 41 */ + z->c++; z->ket = z->c; /* ], line 41 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab6; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 41 */ + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab6; /* grouping v, line 41 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 41 */ if (ret < 0) return ret; } goto lab4; lab6: z->c = c4; - if (!(eq_s(z, 1, s_4))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 42 */ + z->c++; z->ket = z->c; /* ], line 42 */ - { int ret = slice_from_s(z, 1, s_5); /* <-, line 42 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ if (ret < 0) return ret; } } @@ -454,20 +456,41 @@ static int r_prelude(struct SN_env * z) { lab3: z->c = c3; z->bra = z->c; /* [, line 45 */ - if (!(eq_s(z, 1, s_6))) goto lab7; + if (!(eq_s(z, 2, s_3))) goto lab7; /* literal, line 45 */ z->ket = z->c; /* ], line 45 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab7; - { int ret = slice_from_s(z, 1, s_7); /* <-, line 45 */ + { int ret = slice_from_s(z, 2, s_4); /* <-, line 45 */ if (ret < 0) return ret; } goto lab2; lab7: z->c = c3; - if (!(eq_s(z, 1, s_8))) goto lab1; z->bra = z->c; /* [, line 47 */ - if (!(eq_s(z, 1, s_9))) goto lab1; + if (!(eq_s(z, 2, s_5))) goto lab8; /* literal, line 47 */ z->ket = z->c; /* ], line 47 */ - { int ret = slice_from_s(z, 1, s_10); /* <-, line 47 */ + { int ret = slice_from_s(z, 2, s_6); /* <-, line 47 */ + if (ret < 0) return ret; + } + goto lab2; + lab8: + z->c = c3; + z->bra = z->c; /* [, line 49 */ + if (z->c == z->l || z->p[z->c] != 'y') goto lab9; /* literal, line 49 */ + z->c++; + z->ket = z->c; /* ], line 49 */ + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab9; /* grouping v, line 49 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 49 */ + if (ret < 0) return ret; + } + goto lab2; + lab9: + z->c = c3; + if (z->c == z->l || z->p[z->c] != 'q') goto lab1; /* literal, line 51 */ + z->c++; + z->bra = z->c; /* [, line 51 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab1; /* literal, line 51 */ + z->c++; + z->ket = z->c; /* ], line 51 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 51 */ if (ret < 0) return ret; } } @@ -489,100 +512,114 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; - { int c1 = z->c; /* do, line 56 */ - { int c2 = z->c; /* or, line 58 */ - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; - if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 56 */ + z->I[1] = z->l; /* $p1 = , line 57 */ + z->I[2] = z->l; /* $p2 = , line 58 */ + { int c1 = z->c; /* do, line 60 */ + { int c2 = z->c; /* or, line 62 */ + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ + if (in_grouping_U(z, g_v, 97, 251, 0)) goto lab2; /* grouping v, line 61 */ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab2; - z->c = ret; /* next, line 57 */ + z->c = ret; /* next, line 61 */ } goto lab1; lab2: z->c = c2; - if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; - if (!(find_among(z, a_0, 3))) goto lab3; /* among, line 59 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 3 || !((331776 >> (z->p[z->c + 2] & 0x1f)) & 1)) goto lab3; /* among, line 63 */ + if (!(find_among(z, a_0, 3))) goto lab3; goto lab1; lab3: z->c = c2; { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 66 */ + z->c = ret; /* next, line 70 */ } - { /* gopast */ /* grouping v, line 66 */ + { /* gopast */ /* grouping v, line 70 */ int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab0; z->c += ret; } } lab1: - z->I[0] = z->c; /* setmark pV, line 67 */ + z->I[0] = z->c; /* setmark pV, line 71 */ lab0: z->c = c1; } - { int c3 = z->c; /* do, line 69 */ - { /* gopast */ /* grouping v, line 70 */ + { int c3 = z->c; /* do, line 73 */ + { /* gopast */ /* grouping v, line 74 */ int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 70 */ + { /* gopast */ /* non v, line 74 */ int ret = in_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[1] = z->c; /* setmark p1, line 70 */ - { /* gopast */ /* grouping v, line 71 */ + z->I[1] = z->c; /* setmark p1, line 74 */ + { /* gopast */ /* grouping v, line 75 */ int ret = out_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - { /* gopast */ /* non v, line 71 */ + { /* gopast */ /* non v, line 75 */ int ret = in_grouping_U(z, g_v, 97, 251, 1); if (ret < 0) goto lab4; z->c += ret; } - z->I[2] = z->c; /* setmark p2, line 71 */ + z->I[2] = z->c; /* setmark p2, line 75 */ lab4: z->c = c3; } return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; - while(1) { /* repeat, line 75 */ + while(1) { /* repeat, line 79 */ int c1 = z->c; - z->bra = z->c; /* [, line 77 */ - if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652096 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 4; else - among_var = find_among(z, a_1, 4); /* substring, line 77 */ + z->bra = z->c; /* [, line 81 */ + if (z->c >= z->l || z->p[z->c + 0] >> 5 != 2 || !((35652352 >> (z->p[z->c + 0] & 0x1f)) & 1)) among_var = 7; else /* substring, line 81 */ + among_var = find_among(z, a_1, 7); if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 77 */ - switch(among_var) { - case 0: goto lab0; + z->ket = z->c; /* ], line 81 */ + switch (among_var) { /* among, line 81 */ case 1: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 78 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 82 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 80 */ + { int ret = slice_from_s(z, 1, s_11); /* <-, line 84 */ if (ret < 0) return ret; } break; case 4: + { int ret = slice_from_s(z, 2, s_12); /* <-, line 85 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 2, s_13); /* <-, line 86 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_del(z); /* delete, line 87 */ + if (ret < 0) return ret; + } + break; + case 7: { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 81 */ + z->c = ret; /* next, line 88 */ } break; } @@ -594,62 +631,59 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 94 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 95 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 96 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 92 */ - among_var = find_among_b(z, a_4, 43); /* substring, line 92 */ + z->ket = z->c; /* [, line 99 */ + among_var = find_among_b(z, a_4, 43); /* substring, line 99 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 92 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 99 */ + switch (among_var) { /* among, line 99 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 96 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 103 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 96 */ + { int ret = slice_del(z); /* delete, line 103 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 99 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 99 */ + { int ret = slice_del(z); /* delete, line 106 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 100 */ - z->ket = z->c; /* [, line 100 */ - if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 100 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 100 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 100 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 107 */ + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m1; goto lab0; } /* literal, line 107 */ + z->bra = z->c; /* ], line 107 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 107 */ + { int ret = r_R2(z); /* call R2, line 107 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 100 */ + { int ret = slice_del(z); /* delete, line 107 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = z->l - m1; - { int ret = slice_from_s(z, 3, s_15); /* <-, line 100 */ + z->c = z->l - m2; + { int ret = slice_from_s(z, 3, s_15); /* <-, line 107 */ if (ret < 0) return ret; } } @@ -659,103 +693,98 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 104 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_16); /* <-, line 104 */ + { int ret = slice_from_s(z, 3, s_16); /* <-, line 111 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 107 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 114 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_17); /* <-, line 107 */ + { int ret = slice_from_s(z, 1, s_17); /* <-, line 114 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 110 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 117 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_18); /* <-, line 110 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 117 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 114 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 121 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 114 */ + { int ret = slice_del(z); /* delete, line 121 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 115 */ - z->ket = z->c; /* [, line 116 */ - among_var = find_among_b(z, a_2, 6); /* substring, line 116 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 116 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab3; } + { int m3 = z->l - z->c; (void)m3; /* try, line 122 */ + z->ket = z->c; /* [, line 123 */ + among_var = find_among_b(z, a_2, 6); /* substring, line 123 */ + if (!(among_var)) { z->c = z->l - m3; goto lab3; } + z->bra = z->c; /* ], line 123 */ + switch (among_var) { /* among, line 123 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */ + { int ret = r_R2(z); /* call R2, line 124 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); /* delete, line 124 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 117 */ - if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 117 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 117 */ + z->ket = z->c; /* [, line 124 */ + if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m3; goto lab3; } /* literal, line 124 */ + z->bra = z->c; /* ], line 124 */ + { int ret = r_R2(z); /* call R2, line 124 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 117 */ + { int ret = slice_del(z); /* delete, line 124 */ if (ret < 0) return ret; } break; case 2: - { int m2 = z->l - z->c; (void)m2; /* or, line 118 */ - { int ret = r_R2(z); - if (ret == 0) goto lab5; /* call R2, line 118 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 125 */ + { int ret = r_R2(z); /* call R2, line 125 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 118 */ + { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } goto lab4; lab5: - z->c = z->l - m2; - { int ret = r_R1(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R1, line 118 */ + z->c = z->l - m4; + { int ret = r_R1(z); /* call R1, line 125 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 3, s_20); /* <-, line 118 */ + { int ret = slice_from_s(z, 3, s_20); /* <-, line 125 */ if (ret < 0) return ret; } } lab4: break; case 3: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 120 */ + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 120 */ + { int ret = slice_del(z); /* delete, line 127 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call RV, line 122 */ + { int ret = r_RV(z); /* call RV, line 129 */ + if (ret == 0) { z->c = z->l - m3; goto lab3; } if (ret < 0) return ret; } - { int ret = slice_from_s(z, 1, s_21); /* <-, line 122 */ + { int ret = slice_from_s(z, 1, s_21); /* <-, line 129 */ if (ret < 0) return ret; } break; @@ -765,63 +794,61 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 129 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 136 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 129 */ + { int ret = slice_del(z); /* delete, line 136 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 130 */ - z->ket = z->c; /* [, line 131 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab6; } - among_var = find_among_b(z, a_3, 3); /* substring, line 131 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab6; } - z->bra = z->c; /* ], line 131 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab6; } + { int m5 = z->l - z->c; (void)m5; /* try, line 137 */ + z->ket = z->c; /* [, line 138 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m5; goto lab6; } /* substring, line 138 */ + among_var = find_among_b(z, a_3, 3); + if (!(among_var)) { z->c = z->l - m5; goto lab6; } + z->bra = z->c; /* ], line 138 */ + switch (among_var) { /* among, line 138 */ case 1: - { int m3 = z->l - z->c; (void)m3; /* or, line 132 */ - { int ret = r_R2(z); - if (ret == 0) goto lab8; /* call R2, line 132 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 139 */ + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 132 */ + { int ret = slice_del(z); /* delete, line 139 */ if (ret < 0) return ret; } goto lab7; lab8: - z->c = z->l - m3; - { int ret = slice_from_s(z, 3, s_22); /* <-, line 132 */ + z->c = z->l - m6; + { int ret = slice_from_s(z, 3, s_22); /* <-, line 139 */ if (ret < 0) return ret; } } lab7: break; case 2: - { int m4 = z->l - z->c; (void)m4; /* or, line 133 */ - { int ret = r_R2(z); - if (ret == 0) goto lab10; /* call R2, line 133 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 140 */ + { int ret = r_R2(z); /* call R2, line 140 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 133 */ + { int ret = slice_del(z); /* delete, line 140 */ if (ret < 0) return ret; } goto lab9; lab10: - z->c = z->l - m4; - { int ret = slice_from_s(z, 3, s_23); /* <-, line 133 */ + z->c = z->l - m7; + { int ret = slice_from_s(z, 3, s_23); /* <-, line 140 */ if (ret < 0) return ret; } } lab9: break; case 3: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R2, line 134 */ + { int ret = r_R2(z); /* call R2, line 141 */ + if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 134 */ + { int ret = slice_del(z); /* delete, line 141 */ if (ret < 0) return ret; } break; @@ -831,39 +858,38 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 141 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 148 */ + if (ret <= 0) return ret; } - { int ret = slice_del(z); /* delete, line 141 */ + { int ret = slice_del(z); /* delete, line 148 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 142 */ - z->ket = z->c; /* [, line 142 */ - if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m_keep; goto lab11; } - z->bra = z->c; /* ], line 142 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab11; } /* call R2, line 142 */ + { int m8 = z->l - z->c; (void)m8; /* try, line 149 */ + z->ket = z->c; /* [, line 149 */ + if (!(eq_s_b(z, 2, s_24))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ + z->bra = z->c; /* ], line 149 */ + { int ret = r_R2(z); /* call R2, line 149 */ + if (ret == 0) { z->c = z->l - m8; goto lab11; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 142 */ - if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m_keep; goto lab11; } - z->bra = z->c; /* ], line 142 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 142 */ - { int ret = r_R2(z); - if (ret == 0) goto lab13; /* call R2, line 142 */ + z->ket = z->c; /* [, line 149 */ + if (!(eq_s_b(z, 2, s_25))) { z->c = z->l - m8; goto lab11; } /* literal, line 149 */ + z->bra = z->c; /* ], line 149 */ + { int m9 = z->l - z->c; (void)m9; /* or, line 149 */ + { int ret = r_R2(z); /* call R2, line 149 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 142 */ + { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } goto lab12; lab13: - z->c = z->l - m5; - { int ret = slice_from_s(z, 3, s_26); /* <-, line 142 */ + z->c = z->l - m9; + { int ret = slice_from_s(z, 3, s_26); /* <-, line 149 */ if (ret < 0) return ret; } } @@ -873,153 +899,143 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 9: - { int ret = slice_from_s(z, 3, s_27); /* <-, line 144 */ + { int ret = slice_from_s(z, 3, s_27); /* <-, line 151 */ if (ret < 0) return ret; } break; case 10: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 145 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 152 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 2, s_28); /* <-, line 145 */ + { int ret = slice_from_s(z, 2, s_28); /* <-, line 152 */ if (ret < 0) return ret; } break; case 11: - { int m6 = z->l - z->c; (void)m6; /* or, line 147 */ - { int ret = r_R2(z); - if (ret == 0) goto lab15; /* call R2, line 147 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 154 */ + { int ret = r_R2(z); /* call R2, line 154 */ + if (ret == 0) goto lab15; if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 147 */ + { int ret = slice_del(z); /* delete, line 154 */ if (ret < 0) return ret; } goto lab14; lab15: - z->c = z->l - m6; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 147 */ - if (ret < 0) return ret; + z->c = z->l - m10; + { int ret = r_R1(z); /* call R1, line 154 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_29); /* <-, line 147 */ + { int ret = slice_from_s(z, 3, s_29); /* <-, line 154 */ if (ret < 0) return ret; } } lab14: break; case 12: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 150 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 157 */ + if (ret <= 0) return ret; } - if (out_grouping_b_U(z, g_v, 97, 251, 0)) return 0; - { int ret = slice_del(z); /* delete, line 150 */ + if (out_grouping_b_U(z, g_v, 97, 251, 0)) return 0; /* non v, line 157 */ + { int ret = slice_del(z); /* delete, line 157 */ if (ret < 0) return ret; } break; case 13: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 155 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 162 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_30); /* <-, line 155 */ + { int ret = slice_from_s(z, 3, s_30); /* <-, line 162 */ if (ret < 0) return ret; } - return 0; /* fail, line 155 */ + return 0; /* fail, line 162 */ break; case 14: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 156 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 163 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_31); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_31); /* <-, line 163 */ if (ret < 0) return ret; } - return 0; /* fail, line 156 */ + return 0; /* fail, line 163 */ break; case 15: - { int m_test = z->l - z->c; /* test, line 158 */ - if (in_grouping_b_U(z, g_v, 97, 251, 0)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 158 */ - if (ret < 0) return ret; + { int m_test11 = z->l - z->c; /* test, line 165 */ + if (in_grouping_b_U(z, g_v, 97, 251, 0)) return 0; /* grouping v, line 165 */ + { int ret = r_RV(z); /* call RV, line 165 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test11; } - { int ret = slice_del(z); /* delete, line 158 */ + { int ret = slice_del(z); /* delete, line 165 */ if (ret < 0) return ret; } - return 0; /* fail, line 158 */ + return 0; /* fail, line 165 */ break; } return 1; } -static int r_i_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 163 */ - int m1 = z->l - z->c; (void)m1; +static int r_i_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 170 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 163 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 164 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_5, 35); /* substring, line 164 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 164 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - if (out_grouping_b_U(z, g_v, 97, 251, 0)) { z->lb = mlimit; return 0; } - { int ret = slice_del(z); /* delete, line 170 */ - if (ret < 0) return ret; - } - break; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 171 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68944418 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 171 */ + if (!(find_among_b(z, a_5, 35))) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 171 */ + { int m2 = z->l - z->c; (void)m2; /* not, line 177 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'H') goto lab0; /* literal, line 177 */ + z->c--; + { z->lb = mlimit1; return 0; } + lab0: + z->c = z->l - m2; } - z->lb = mlimit; + if (out_grouping_b_U(z, g_v, 97, 251, 0)) { z->lb = mlimit1; return 0; } /* non v, line 177 */ + { int ret = slice_del(z); /* delete, line 177 */ + if (ret < 0) return ret; + } + z->lb = mlimit1; } return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 174 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 181 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 174 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 175 */ - among_var = find_among_b(z, a_6, 38); /* substring, line 175 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 175 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 182 */ + among_var = find_among_b(z, a_6, 38); /* substring, line 182 */ + if (!(among_var)) { z->lb = mlimit1; return 0; } + z->bra = z->c; /* ], line 182 */ + switch (among_var) { /* among, line 182 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 177 */ + { int ret = r_R2(z); /* call R2, line 184 */ + if (ret == 0) { z->lb = mlimit1; return 0; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 177 */ + { int ret = slice_del(z); /* delete, line 184 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 185 */ + { int ret = slice_del(z); /* delete, line 192 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 190 */ + { int ret = slice_del(z); /* delete, line 197 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 191 */ - z->ket = z->c; /* [, line 191 */ - if (!(eq_s_b(z, 1, s_32))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 191 */ - { int ret = slice_del(z); /* delete, line 191 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 198 */ + z->ket = z->c; /* [, line 198 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') { z->c = z->l - m2; goto lab0; } /* literal, line 198 */ + z->c--; + z->bra = z->c; /* ], line 198 */ + { int ret = slice_del(z); /* delete, line 198 */ if (ret < 0) return ret; } lab0: @@ -1027,100 +1043,102 @@ static int r_verb_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_residual_suffix(struct SN_env * z) { +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 199 */ - z->ket = z->c; /* [, line 199 */ - if (!(eq_s_b(z, 1, s_33))) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 199 */ - { int m_test = z->l - z->c; /* test, line 199 */ - if (out_grouping_b_U(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m1 = z->l - z->c; (void)m1; /* try, line 206 */ + z->ket = z->c; /* [, line 206 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m1; goto lab0; } /* literal, line 206 */ + z->c--; + z->bra = z->c; /* ], line 206 */ + { int m_test2 = z->l - z->c; /* test, line 206 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 206 */ + if (!(eq_s_b(z, 2, s_32))) goto lab2; /* literal, line 206 */ + goto lab1; + lab2: + z->c = z->l - m3; + if (out_grouping_b_U(z, g_keep_with_s, 97, 232, 0)) { z->c = z->l - m1; goto lab0; } /* non keep_with_s, line 206 */ + } + lab1: + z->c = z->l - m_test2; } - { int ret = slice_del(z); /* delete, line 199 */ + { int ret = slice_del(z); /* delete, line 206 */ if (ret < 0) return ret; } lab0: ; } - { int mlimit; /* setlimit, line 200 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit4; /* setlimit, line 207 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 200 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; - z->ket = z->c; /* [, line 201 */ - among_var = find_among_b(z, a_7, 7); /* substring, line 201 */ - if (!(among_var)) { z->lb = mlimit; return 0; } - z->bra = z->c; /* ], line 201 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + mlimit4 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 208 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((278560 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit4; return 0; } /* substring, line 208 */ + among_var = find_among_b(z, a_7, 6); + if (!(among_var)) { z->lb = mlimit4; return 0; } + z->bra = z->c; /* ], line 208 */ + switch (among_var) { /* among, line 208 */ case 1: - { int ret = r_R2(z); - if (ret == 0) { z->lb = mlimit; return 0; } /* call R2, line 202 */ + { int ret = r_R2(z); /* call R2, line 209 */ + if (ret == 0) { z->lb = mlimit4; return 0; } if (ret < 0) return ret; } - { int m2 = z->l - z->c; (void)m2; /* or, line 202 */ - if (!(eq_s_b(z, 1, s_34))) goto lab2; - goto lab1; - lab2: - z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_35))) { z->lb = mlimit; return 0; } + { int m5 = z->l - z->c; (void)m5; /* or, line 209 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab4; /* literal, line 209 */ + z->c--; + goto lab3; + lab4: + z->c = z->l - m5; + if (z->c <= z->lb || z->p[z->c - 1] != 't') { z->lb = mlimit4; return 0; } /* literal, line 209 */ + z->c--; } - lab1: - { int ret = slice_del(z); /* delete, line 202 */ + lab3: + { int ret = slice_del(z); /* delete, line 209 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_36); /* <-, line 204 */ + { int ret = slice_from_s(z, 1, s_33); /* <-, line 211 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 205 */ - if (ret < 0) return ret; - } - break; - case 4: - if (!(eq_s_b(z, 2, s_37))) { z->lb = mlimit; return 0; } - { int ret = slice_del(z); /* delete, line 206 */ + { int ret = slice_del(z); /* delete, line 212 */ if (ret < 0) return ret; } break; } - z->lb = mlimit; + z->lb = mlimit4; } return 1; } -static int r_un_double(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 212 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_8, 5))) return 0; /* among, line 212 */ - z->c = z->l - m_test; +static int r_un_double(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 218 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1069056 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 218 */ + if (!(find_among_b(z, a_8, 5))) return 0; + z->c = z->l - m_test1; } - z->ket = z->c; /* [, line 212 */ + z->ket = z->c; /* [, line 218 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 212 */ + z->c = ret; /* next, line 218 */ } - z->bra = z->c; /* ], line 212 */ - { int ret = slice_del(z); /* delete, line 212 */ + z->bra = z->c; /* ], line 218 */ + { int ret = slice_del(z); /* delete, line 218 */ if (ret < 0) return ret; } return 1; } -static int r_un_accent(struct SN_env * z) { +static int r_un_accent(struct SN_env * z) { /* backwardmode */ { int i = 1; - while(1) { /* atleast, line 216 */ - if (out_grouping_b_U(z, g_v, 97, 251, 0)) goto lab0; + while(1) { /* atleast, line 222 */ + if (out_grouping_b_U(z, g_v, 97, 251, 0)) goto lab0; /* non v, line 222 */ i--; continue; lab0: @@ -1128,80 +1146,79 @@ static int r_un_accent(struct SN_env * z) { } if (i > 0) return 0; } - z->ket = z->c; /* [, line 217 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 217 */ - if (!(eq_s_b(z, 2, s_38))) goto lab2; + z->ket = z->c; /* [, line 223 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 223 */ + if (!(eq_s_b(z, 2, s_34))) goto lab2; /* literal, line 223 */ goto lab1; lab2: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_39))) return 0; + if (!(eq_s_b(z, 2, s_35))) return 0; /* literal, line 223 */ } lab1: - z->bra = z->c; /* ], line 217 */ - { int ret = slice_from_s(z, 1, s_40); /* <-, line 217 */ + z->bra = z->c; /* ], line 223 */ + { int ret = slice_from_s(z, 1, s_36); /* <-, line 223 */ if (ret < 0) return ret; } return 1; } -extern int french_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 223 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 223 */ +extern int french_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 229 */ + { int ret = r_prelude(z); /* call prelude, line 229 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 224 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 224 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 230 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 230 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 225 */ +lab1: + z->lb = z->c; z->c = z->l; /* backwards, line 231 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 227 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 237 */ - { int m5 = z->l - z->c; (void)m5; /* and, line 233 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 229 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab6; /* call standard_suffix, line 229 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 233 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 243 */ + { int m4 = z->l - z->c; (void)m4; /* and, line 239 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 235 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 235 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_i_verb_suffix(z); - if (ret == 0) goto lab7; /* call i_verb_suffix, line 230 */ + z->c = z->l - m5; + { int ret = r_i_verb_suffix(z); /* call i_verb_suffix, line 236 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } goto lab5; lab7: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 231 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 237 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: - z->c = z->l - m5; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 234 */ - z->ket = z->c; /* [, line 234 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 234 */ - if (!(eq_s_b(z, 1, s_41))) goto lab10; - z->bra = z->c; /* ], line 234 */ - { int ret = slice_from_s(z, 1, s_42); /* <-, line 234 */ + z->c = z->l - m4; + { int m6 = z->l - z->c; (void)m6; /* try, line 240 */ + z->ket = z->c; /* [, line 240 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 240 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') goto lab10; /* literal, line 240 */ + z->c--; + z->bra = z->c; /* ], line 240 */ + { int ret = slice_from_s(z, 1, s_37); /* <-, line 240 */ if (ret < 0) return ret; } goto lab9; lab10: z->c = z->l - m7; - if (!(eq_s_b(z, 2, s_43))) { z->c = z->l - m_keep; goto lab8; } - z->bra = z->c; /* ], line 235 */ - { int ret = slice_from_s(z, 1, s_44); /* <-, line 235 */ + if (!(eq_s_b(z, 2, s_38))) { z->c = z->l - m6; goto lab8; } /* literal, line 241 */ + z->bra = z->c; /* ], line 241 */ + { int ret = slice_from_s(z, 1, s_39); /* <-, line 241 */ if (ret < 0) return ret; } } @@ -1212,36 +1229,36 @@ extern int french_UTF_8_stem(struct SN_env * z) { } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab2; /* call residual_suffix, line 238 */ + z->c = z->l - m3; + { int ret = r_residual_suffix(z); /* call residual_suffix, line 244 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m8 = z->l - z->c; (void)m8; /* do, line 243 */ - { int ret = r_un_double(z); - if (ret == 0) goto lab11; /* call un_double, line 243 */ + { int m8 = z->l - z->c; (void)m8; /* do, line 249 */ + { int ret = r_un_double(z); /* call un_double, line 249 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: z->c = z->l - m8; } - { int m9 = z->l - z->c; (void)m9; /* do, line 244 */ - { int ret = r_un_accent(z); - if (ret == 0) goto lab12; /* call un_accent, line 244 */ + { int m9 = z->l - z->c; (void)m9; /* do, line 250 */ + { int ret = r_un_accent(z); /* call un_accent, line 250 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: z->c = z->l - m9; } z->c = z->lb; - { int c10 = z->c; /* do, line 246 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab13; /* call postlude, line 246 */ + { int c10 = z->c; /* do, line 252 */ + { int ret = r_postlude(z); /* call postlude, line 252 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } lab13: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_german.c b/src/backend/snowball/libstemmer/stem_UTF_8_german.c index 5d406e50921..1a8b5924b41 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_german.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_german.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -36,12 +36,12 @@ static const symbol s_0_5[2] = { 0xC3, 0xBC }; static const struct among a_0[6] = { -/* 0 */ { 0, 0, -1, 6, 0}, +/* 0 */ { 0, 0, -1, 5, 0}, /* 1 */ { 1, s_0_1, 0, 2, 0}, /* 2 */ { 1, s_0_2, 0, 1, 0}, /* 3 */ { 2, s_0_3, 0, 3, 0}, /* 4 */ { 2, s_0_4, 0, 4, 0}, -/* 5 */ { 2, s_0_5, 0, 5, 0} +/* 5 */ { 2, s_0_5, 0, 2, 0} }; static const symbol s_1_0[1] = { 'e' }; @@ -54,13 +54,13 @@ static const symbol s_1_6[2] = { 'e', 's' }; static const struct among a_1[7] = { -/* 0 */ { 1, s_1_0, -1, 1, 0}, +/* 0 */ { 1, s_1_0, -1, 2, 0}, /* 1 */ { 2, s_1_1, -1, 1, 0}, -/* 2 */ { 2, s_1_2, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 2, 0}, /* 3 */ { 3, s_1_3, -1, 1, 0}, /* 4 */ { 2, s_1_4, -1, 1, 0}, -/* 5 */ { 1, s_1_5, -1, 2, 0}, -/* 6 */ { 2, s_1_6, 5, 1, 0} +/* 5 */ { 1, s_1_5, -1, 3, 0}, +/* 6 */ { 2, s_1_6, 5, 2, 0} }; static const symbol s_2_0[2] = { 'e', 'n' }; @@ -114,168 +114,160 @@ static const unsigned char g_st_ending[] = { 117, 30, 4 }; static const symbol s_0[] = { 0xC3, 0x9F }; static const symbol s_1[] = { 's', 's' }; -static const symbol s_2[] = { 'u' }; -static const symbol s_3[] = { 'U' }; +static const symbol s_2[] = { 'U' }; +static const symbol s_3[] = { 'Y' }; static const symbol s_4[] = { 'y' }; -static const symbol s_5[] = { 'Y' }; -static const symbol s_6[] = { 'y' }; -static const symbol s_7[] = { 'u' }; -static const symbol s_8[] = { 'a' }; -static const symbol s_9[] = { 'o' }; -static const symbol s_10[] = { 'u' }; -static const symbol s_11[] = { 'i', 'g' }; -static const symbol s_12[] = { 'e' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'e', 'r' }; -static const symbol s_15[] = { 'e', 'n' }; +static const symbol s_5[] = { 'u' }; +static const symbol s_6[] = { 'a' }; +static const symbol s_7[] = { 'o' }; +static const symbol s_8[] = { 'n', 'i', 's' }; +static const symbol s_9[] = { 'i', 'g' }; +static const symbol s_10[] = { 'e', 'r' }; +static const symbol s_11[] = { 'e', 'n' }; -static int r_prelude(struct SN_env * z) { - { int c_test = z->c; /* test, line 30 */ - while(1) { /* repeat, line 30 */ - int c1 = z->c; - { int c2 = z->c; /* or, line 33 */ - z->bra = z->c; /* [, line 32 */ - if (!(eq_s(z, 2, s_0))) goto lab2; - z->ket = z->c; /* ], line 32 */ - { int ret = slice_from_s(z, 2, s_1); /* <-, line 32 */ +static int r_prelude(struct SN_env * z) { /* forwardmode */ + { int c_test1 = z->c; /* test, line 35 */ + while(1) { /* repeat, line 35 */ + int c2 = z->c; + { int c3 = z->c; /* or, line 38 */ + z->bra = z->c; /* [, line 37 */ + if (!(eq_s(z, 2, s_0))) goto lab2; /* literal, line 37 */ + z->ket = z->c; /* ], line 37 */ + { int ret = slice_from_s(z, 2, s_1); /* <-, line 37 */ if (ret < 0) return ret; } goto lab1; lab2: - z->c = c2; + z->c = c3; { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 33 */ + z->c = ret; /* next, line 38 */ } } lab1: continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } - while(1) { /* repeat, line 36 */ - int c3 = z->c; - while(1) { /* goto, line 36 */ - int c4 = z->c; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; - z->bra = z->c; /* [, line 37 */ - { int c5 = z->c; /* or, line 37 */ - if (!(eq_s(z, 1, s_2))) goto lab6; - z->ket = z->c; /* ], line 37 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab6; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 37 */ + while(1) { /* repeat, line 41 */ + int c4 = z->c; + while(1) { /* goto, line 41 */ + int c5 = z->c; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 42 */ + z->bra = z->c; /* [, line 42 */ + { int c6 = z->c; /* or, line 42 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab6; /* literal, line 42 */ + z->c++; + z->ket = z->c; /* ], line 42 */ + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab6; /* grouping v, line 42 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 42 */ if (ret < 0) return ret; } goto lab5; lab6: - z->c = c5; - if (!(eq_s(z, 1, s_4))) goto lab4; - z->ket = z->c; /* ], line 38 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; - { int ret = slice_from_s(z, 1, s_5); /* <-, line 38 */ + z->c = c6; + if (z->c == z->l || z->p[z->c] != 'y') goto lab4; /* literal, line 43 */ + z->c++; + z->ket = z->c; /* ], line 43 */ + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* grouping v, line 43 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 43 */ if (ret < 0) return ret; } } lab5: - z->c = c4; + z->c = c5; break; lab4: - z->c = c4; + z->c = c5; { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab3; - z->c = ret; /* goto, line 36 */ + z->c = ret; /* goto, line 41 */ } } continue; lab3: - z->c = c3; + z->c = c4; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - { int c_test = z->c; /* test, line 47 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 49 */ + z->I[1] = z->l; /* $p2 = , line 50 */ + { int c_test1 = z->c; /* test, line 52 */ + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 52 */ if (ret < 0) return 0; - z->c = ret; /* hop, line 47 */ + z->c = ret; } - z->I[2] = z->c; /* setmark x, line 47 */ - z->c = c_test; + z->I[2] = z->c; /* setmark x, line 52 */ + z->c = c_test1; } - { /* gopast */ /* grouping v, line 49 */ + { /* gopast */ /* grouping v, line 54 */ int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 49 */ + { /* gopast */ /* non v, line 54 */ int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[0] = z->c; /* setmark p1, line 49 */ - /* try, line 50 */ - if (!(z->I[0] < z->I[2])) goto lab0; - z->I[0] = z->I[2]; + z->I[0] = z->c; /* setmark p1, line 54 */ + /* try, line 55 */ + if (!(z->I[0] < z->I[2])) goto lab0; /* $( < ), line 55 */ + z->I[0] = z->I[2]; /* $p1 = , line 55 */ lab0: - { /* gopast */ /* grouping v, line 51 */ + { /* gopast */ /* grouping v, line 56 */ int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - { /* gopast */ /* non v, line 51 */ + { /* gopast */ /* non v, line 56 */ int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) return 0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 51 */ + z->I[1] = z->c; /* setmark p2, line 56 */ return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; - while(1) { /* repeat, line 55 */ + while(1) { /* repeat, line 60 */ int c1 = z->c; - z->bra = z->c; /* [, line 57 */ - among_var = find_among(z, a_0, 6); /* substring, line 57 */ + z->bra = z->c; /* [, line 62 */ + among_var = find_among(z, a_0, 6); /* substring, line 62 */ if (!(among_var)) goto lab0; - z->ket = z->c; /* ], line 57 */ - switch(among_var) { - case 0: goto lab0; + z->ket = z->c; /* ], line 62 */ + switch (among_var) { /* among, line 62 */ case 1: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 58 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 63 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 64 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 65 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 61 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 66 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 62 */ - if (ret < 0) return ret; - } - break; - case 6: { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; - z->c = ret; /* next, line 63 */ + z->c = ret; /* next, line 68 */ } break; } @@ -287,38 +279,54 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 75 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 76 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m1 = z->l - z->c; (void)m1; /* do, line 74 */ - z->ket = z->c; /* [, line 75 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; - among_var = find_among_b(z, a_1, 7); /* substring, line 75 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 79 */ + z->ket = z->c; /* [, line 80 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((811040 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab0; /* substring, line 80 */ + among_var = find_among_b(z, a_1, 7); if (!(among_var)) goto lab0; - z->bra = z->c; /* ], line 75 */ - { int ret = r_R1(z); - if (ret == 0) goto lab0; /* call R1, line 75 */ + z->bra = z->c; /* ], line 80 */ + { int ret = r_R1(z); /* call R1, line 80 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 80 */ case 1: - { int ret = slice_del(z); /* delete, line 77 */ + { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_s_ending, 98, 116, 0)) goto lab0; - { int ret = slice_del(z); /* delete, line 80 */ + { int ret = slice_del(z); /* delete, line 85 */ + if (ret < 0) return ret; + } + { int m2 = z->l - z->c; (void)m2; /* try, line 86 */ + z->ket = z->c; /* [, line 86 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + z->c--; + z->bra = z->c; /* ], line 86 */ + if (!(eq_s_b(z, 3, s_8))) { z->c = z->l - m2; goto lab1; } /* literal, line 86 */ + { int ret = slice_del(z); /* delete, line 86 */ + if (ret < 0) return ret; + } + lab1: + ; + } + break; + case 3: + if (in_grouping_b_U(z, g_s_ending, 98, 116, 0)) goto lab0; /* grouping s_ending, line 89 */ + { int ret = slice_del(z); /* delete, line 89 */ if (ret < 0) return ret; } break; @@ -326,179 +334,171 @@ static int r_standard_suffix(struct SN_env * z) { lab0: z->c = z->l - m1; } - { int m2 = z->l - z->c; (void)m2; /* do, line 84 */ - z->ket = z->c; /* [, line 85 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1; - among_var = find_among_b(z, a_2, 4); /* substring, line 85 */ - if (!(among_var)) goto lab1; - z->bra = z->c; /* ], line 85 */ - { int ret = r_R1(z); - if (ret == 0) goto lab1; /* call R1, line 85 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 93 */ + z->ket = z->c; /* [, line 94 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1327104 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 94 */ + among_var = find_among_b(z, a_2, 4); + if (!(among_var)) goto lab2; + z->bra = z->c; /* ], line 94 */ + { int ret = r_R1(z); /* call R1, line 94 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab1; + switch (among_var) { /* among, line 94 */ case 1: - { int ret = slice_del(z); /* delete, line 87 */ + { int ret = slice_del(z); /* delete, line 96 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_st_ending, 98, 116, 0)) goto lab1; - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 3); - if (ret < 0) goto lab1; - z->c = ret; /* hop, line 90 */ + if (in_grouping_b_U(z, g_st_ending, 98, 116, 0)) goto lab2; /* grouping st_ending, line 99 */ + { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 3); /* hop, line 99 */ + if (ret < 0) goto lab2; + z->c = ret; } - { int ret = slice_del(z); /* delete, line 90 */ + { int ret = slice_del(z); /* delete, line 99 */ if (ret < 0) return ret; } break; } - lab1: - z->c = z->l - m2; + lab2: + z->c = z->l - m3; } - { int m3 = z->l - z->c; (void)m3; /* do, line 94 */ - z->ket = z->c; /* [, line 95 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; - among_var = find_among_b(z, a_4, 8); /* substring, line 95 */ - if (!(among_var)) goto lab2; - z->bra = z->c; /* ], line 95 */ - { int ret = r_R2(z); - if (ret == 0) goto lab2; /* call R2, line 95 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 103 */ + z->ket = z->c; /* [, line 104 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1051024 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab3; /* substring, line 104 */ + among_var = find_among_b(z, a_4, 8); + if (!(among_var)) goto lab3; + z->bra = z->c; /* ], line 104 */ + { int ret = r_R2(z); /* call R2, line 104 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } - switch(among_var) { - case 0: goto lab2; + switch (among_var) { /* among, line 104 */ case 1: - { int ret = slice_del(z); /* delete, line 97 */ + { int ret = slice_del(z); /* delete, line 106 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 98 */ - z->ket = z->c; /* [, line 98 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab3; } - z->bra = z->c; /* ], line 98 */ - { int m4 = z->l - z->c; (void)m4; /* not, line 98 */ - if (!(eq_s_b(z, 1, s_12))) goto lab4; - { z->c = z->l - m_keep; goto lab3; } - lab4: - z->c = z->l - m4; + { int m5 = z->l - z->c; (void)m5; /* try, line 107 */ + z->ket = z->c; /* [, line 107 */ + if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m5; goto lab4; } /* literal, line 107 */ + z->bra = z->c; /* ], line 107 */ + { int m6 = z->l - z->c; (void)m6; /* not, line 107 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab5; /* literal, line 107 */ + z->c--; + { z->c = z->l - m5; goto lab4; } + lab5: + z->c = z->l - m6; } - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 98 */ + { int ret = r_R2(z); /* call R2, line 107 */ + if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 98 */ + { int ret = slice_del(z); /* delete, line 107 */ if (ret < 0) return ret; } - lab3: + lab4: ; } break; case 2: - { int m5 = z->l - z->c; (void)m5; /* not, line 101 */ - if (!(eq_s_b(z, 1, s_13))) goto lab5; - goto lab2; - lab5: - z->c = z->l - m5; + { int m7 = z->l - z->c; (void)m7; /* not, line 110 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab6; /* literal, line 110 */ + z->c--; + goto lab3; + lab6: + z->c = z->l - m7; } - { int ret = slice_del(z); /* delete, line 101 */ + { int ret = slice_del(z); /* delete, line 110 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 104 */ + { int ret = slice_del(z); /* delete, line 113 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 105 */ - z->ket = z->c; /* [, line 106 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 106 */ - if (!(eq_s_b(z, 2, s_14))) goto lab8; - goto lab7; - lab8: - z->c = z->l - m6; - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab6; } + { int m8 = z->l - z->c; (void)m8; /* try, line 114 */ + z->ket = z->c; /* [, line 115 */ + { int m9 = z->l - z->c; (void)m9; /* or, line 115 */ + if (!(eq_s_b(z, 2, s_10))) goto lab9; /* literal, line 115 */ + goto lab8; + lab9: + z->c = z->l - m9; + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m8; goto lab7; } /* literal, line 115 */ } - lab7: - z->bra = z->c; /* ], line 106 */ - { int ret = r_R1(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call R1, line 106 */ + lab8: + z->bra = z->c; /* ], line 115 */ + { int ret = r_R1(z); /* call R1, line 115 */ + if (ret == 0) { z->c = z->l - m8; goto lab7; } if (ret < 0) return ret; } - { int ret = slice_del(z); /* delete, line 106 */ + { int ret = slice_del(z); /* delete, line 115 */ if (ret < 0) return ret; } - lab6: + lab7: ; } break; case 4: - { int ret = slice_del(z); /* delete, line 110 */ + { int ret = slice_del(z); /* delete, line 119 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ - z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m_keep; goto lab9; } - among_var = find_among_b(z, a_3, 2); /* substring, line 112 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab9; } - z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab9; } /* call R2, line 112 */ + { int m10 = z->l - z->c; (void)m10; /* try, line 120 */ + z->ket = z->c; /* [, line 121 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 103 && z->p[z->c - 1] != 104)) { z->c = z->l - m10; goto lab10; } /* substring, line 121 */ + if (!(find_among_b(z, a_3, 2))) { z->c = z->l - m10; goto lab10; } + z->bra = z->c; /* ], line 121 */ + { int ret = r_R2(z); /* call R2, line 121 */ + if (ret == 0) { z->c = z->l - m10; goto lab10; } if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab9; } - case 1: - { int ret = slice_del(z); /* delete, line 114 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; } - lab9: + lab10: ; } break; } - lab2: - z->c = z->l - m3; + lab3: + z->c = z->l - m4; } return 1; } -extern int german_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 125 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 125 */ +extern int german_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 134 */ + { int ret = r_prelude(z); /* call prelude, line 134 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 126 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 126 */ + { int c2 = z->c; /* do, line 135 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 135 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = c2; } - z->lb = z->c; z->c = z->l; /* backwards, line 127 */ + z->lb = z->c; z->c = z->l; /* backwards, line 136 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 128 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab2; /* call standard_suffix, line 128 */ - if (ret < 0) return ret; - } - lab2: - z->c = z->l - m3; + /* do, line 137 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 137 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; } +lab2: z->c = z->lb; - { int c4 = z->c; /* do, line 129 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab3; /* call postlude, line 129 */ + { int c3 = z->c; /* do, line 138 */ + { int ret = r_postlude(z); /* call postlude, line 138 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = c4; + z->c = c3; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_greek.c b/src/backend/snowball/libstemmer/stem_UTF_8_greek.c new file mode 100644 index 00000000000..6566d9cafb9 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_greek.c @@ -0,0 +1,4199 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +static int r_step7(struct SN_env * z); +static int r_step6(struct SN_env * z); +static int r_step5m(struct SN_env * z); +static int r_step5l(struct SN_env * z); +static int r_step5k(struct SN_env * z); +static int r_step5j(struct SN_env * z); +static int r_step5i(struct SN_env * z); +static int r_step5h(struct SN_env * z); +static int r_step5g(struct SN_env * z); +static int r_step5f(struct SN_env * z); +static int r_step5e(struct SN_env * z); +static int r_step5d(struct SN_env * z); +static int r_step5c(struct SN_env * z); +static int r_step5b(struct SN_env * z); +static int r_step5a(struct SN_env * z); +static int r_step4(struct SN_env * z); +static int r_step3(struct SN_env * z); +static int r_step2d(struct SN_env * z); +static int r_step2c(struct SN_env * z); +static int r_step2b(struct SN_env * z); +static int r_step2a(struct SN_env * z); +static int r_step1(struct SN_env * z); +static int r_steps10(struct SN_env * z); +static int r_steps9(struct SN_env * z); +static int r_steps8(struct SN_env * z); +static int r_steps7(struct SN_env * z); +static int r_steps6(struct SN_env * z); +static int r_steps5(struct SN_env * z); +static int r_steps4(struct SN_env * z); +static int r_steps3(struct SN_env * z); +static int r_steps2(struct SN_env * z); +static int r_steps1(struct SN_env * z); +static int r_has_min_length(struct SN_env * z); +static int r_tolower(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif +extern int greek_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * greek_UTF_8_create_env(void); +extern void greek_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_1[2] = { 0xCF, 0x82 }; +static const symbol s_0_2[2] = { 0xCE, 0x86 }; +static const symbol s_0_3[2] = { 0xCE, 0x88 }; +static const symbol s_0_4[2] = { 0xCE, 0x89 }; +static const symbol s_0_5[2] = { 0xCE, 0x8A }; +static const symbol s_0_6[2] = { 0xCF, 0x8A }; +static const symbol s_0_7[2] = { 0xCF, 0x8B }; +static const symbol s_0_8[2] = { 0xCE, 0x8C }; +static const symbol s_0_9[2] = { 0xCF, 0x8C }; +static const symbol s_0_10[2] = { 0xCF, 0x8D }; +static const symbol s_0_11[2] = { 0xCE, 0x8E }; +static const symbol s_0_12[2] = { 0xCF, 0x8E }; +static const symbol s_0_13[2] = { 0xCE, 0x8F }; +static const symbol s_0_14[2] = { 0xCE, 0x90 }; +static const symbol s_0_15[2] = { 0xCE, 0x91 }; +static const symbol s_0_16[2] = { 0xCE, 0x92 }; +static const symbol s_0_17[2] = { 0xCE, 0x93 }; +static const symbol s_0_18[2] = { 0xCE, 0x94 }; +static const symbol s_0_19[2] = { 0xCE, 0x95 }; +static const symbol s_0_20[2] = { 0xCE, 0x96 }; +static const symbol s_0_21[2] = { 0xCE, 0x97 }; +static const symbol s_0_22[2] = { 0xCE, 0x98 }; +static const symbol s_0_23[2] = { 0xCE, 0x99 }; +static const symbol s_0_24[2] = { 0xCE, 0x9A }; +static const symbol s_0_25[2] = { 0xCE, 0x9B }; +static const symbol s_0_26[2] = { 0xCE, 0x9C }; +static const symbol s_0_27[2] = { 0xCE, 0x9D }; +static const symbol s_0_28[2] = { 0xCE, 0x9E }; +static const symbol s_0_29[2] = { 0xCE, 0x9F }; +static const symbol s_0_30[2] = { 0xCE, 0xA0 }; +static const symbol s_0_31[2] = { 0xCE, 0xA1 }; +static const symbol s_0_32[2] = { 0xCE, 0xA3 }; +static const symbol s_0_33[2] = { 0xCE, 0xA4 }; +static const symbol s_0_34[2] = { 0xCE, 0xA5 }; +static const symbol s_0_35[2] = { 0xCE, 0xA6 }; +static const symbol s_0_36[2] = { 0xCE, 0xA7 }; +static const symbol s_0_37[2] = { 0xCE, 0xA8 }; +static const symbol s_0_38[2] = { 0xCE, 0xA9 }; +static const symbol s_0_39[2] = { 0xCE, 0xAA }; +static const symbol s_0_40[2] = { 0xCE, 0xAB }; +static const symbol s_0_41[2] = { 0xCE, 0xAC }; +static const symbol s_0_42[2] = { 0xCE, 0xAD }; +static const symbol s_0_43[2] = { 0xCE, 0xAE }; +static const symbol s_0_44[2] = { 0xCE, 0xAF }; +static const symbol s_0_45[2] = { 0xCE, 0xB0 }; + +static const struct among a_0[46] = +{ +/* 0 */ { 0, 0, -1, 25, 0}, +/* 1 */ { 2, s_0_1, 0, 18, 0}, +/* 2 */ { 2, s_0_2, 0, 1, 0}, +/* 3 */ { 2, s_0_3, 0, 5, 0}, +/* 4 */ { 2, s_0_4, 0, 7, 0}, +/* 5 */ { 2, s_0_5, 0, 9, 0}, +/* 6 */ { 2, s_0_6, 0, 7, 0}, +/* 7 */ { 2, s_0_7, 0, 20, 0}, +/* 8 */ { 2, s_0_8, 0, 15, 0}, +/* 9 */ { 2, s_0_9, 0, 15, 0}, +/* 10 */ { 2, s_0_10, 0, 20, 0}, +/* 11 */ { 2, s_0_11, 0, 20, 0}, +/* 12 */ { 2, s_0_12, 0, 24, 0}, +/* 13 */ { 2, s_0_13, 0, 24, 0}, +/* 14 */ { 2, s_0_14, 0, 7, 0}, +/* 15 */ { 2, s_0_15, 0, 1, 0}, +/* 16 */ { 2, s_0_16, 0, 2, 0}, +/* 17 */ { 2, s_0_17, 0, 3, 0}, +/* 18 */ { 2, s_0_18, 0, 4, 0}, +/* 19 */ { 2, s_0_19, 0, 5, 0}, +/* 20 */ { 2, s_0_20, 0, 6, 0}, +/* 21 */ { 2, s_0_21, 0, 7, 0}, +/* 22 */ { 2, s_0_22, 0, 8, 0}, +/* 23 */ { 2, s_0_23, 0, 9, 0}, +/* 24 */ { 2, s_0_24, 0, 10, 0}, +/* 25 */ { 2, s_0_25, 0, 11, 0}, +/* 26 */ { 2, s_0_26, 0, 12, 0}, +/* 27 */ { 2, s_0_27, 0, 13, 0}, +/* 28 */ { 2, s_0_28, 0, 14, 0}, +/* 29 */ { 2, s_0_29, 0, 15, 0}, +/* 30 */ { 2, s_0_30, 0, 16, 0}, +/* 31 */ { 2, s_0_31, 0, 17, 0}, +/* 32 */ { 2, s_0_32, 0, 18, 0}, +/* 33 */ { 2, s_0_33, 0, 19, 0}, +/* 34 */ { 2, s_0_34, 0, 20, 0}, +/* 35 */ { 2, s_0_35, 0, 21, 0}, +/* 36 */ { 2, s_0_36, 0, 22, 0}, +/* 37 */ { 2, s_0_37, 0, 23, 0}, +/* 38 */ { 2, s_0_38, 0, 24, 0}, +/* 39 */ { 2, s_0_39, 0, 9, 0}, +/* 40 */ { 2, s_0_40, 0, 20, 0}, +/* 41 */ { 2, s_0_41, 0, 1, 0}, +/* 42 */ { 2, s_0_42, 0, 5, 0}, +/* 43 */ { 2, s_0_43, 0, 7, 0}, +/* 44 */ { 2, s_0_44, 0, 9, 0}, +/* 45 */ { 2, s_0_45, 0, 20, 0} +}; + +static const symbol s_1_0[16] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCF, 0x83 }; +static const symbol s_1_1[6] = { 0xCF, 0x86, 0xCF, 0x89, 0xCF, 0x83 }; +static const symbol s_1_2[10] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_1_3[10] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_1_4[10] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_1_5[20] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_6[10] = { 0xCF, 0x86, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_7[14] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_8[14] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_9[14] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_10[18] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_11[14] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_1_12[12] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_1_13[14] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_1_14[12] = { 0xCF, 0x83, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_1_15[16] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_1_16[14] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_1_17[18] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_18[8] = { 0xCF, 0x86, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_19[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_20[12] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_21[12] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_22[16] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_1_23[10] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_1_24[12] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_1_25[10] = { 0xCF, 0x83, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_1_26[14] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_1_27[12] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_1_28[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB7 }; +static const symbol s_1_29[20] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_30[10] = { 0xCF, 0x86, 0xCF, 0x89, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_31[14] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_32[14] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_33[14] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_34[18] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_35[12] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_36[14] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_37[12] = { 0xCF, 0x83, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_38[16] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_1_39[14] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_1[40] = +{ +/* 0 */ { 16, s_1_0, -1, 10, 0}, +/* 1 */ { 6, s_1_1, -1, 9, 0}, +/* 2 */ { 10, s_1_2, -1, 7, 0}, +/* 3 */ { 10, s_1_3, -1, 8, 0}, +/* 4 */ { 10, s_1_4, -1, 6, 0}, +/* 5 */ { 20, s_1_5, -1, 10, 0}, +/* 6 */ { 10, s_1_6, -1, 9, 0}, +/* 7 */ { 14, s_1_7, -1, 7, 0}, +/* 8 */ { 14, s_1_8, -1, 8, 0}, +/* 9 */ { 14, s_1_9, -1, 6, 0}, +/* 10 */ { 18, s_1_10, -1, 11, 0}, +/* 11 */ { 14, s_1_11, -1, 11, 0}, +/* 12 */ { 12, s_1_12, -1, 1, 0}, +/* 13 */ { 14, s_1_13, -1, 2, 0}, +/* 14 */ { 12, s_1_14, -1, 4, 0}, +/* 15 */ { 16, s_1_15, -1, 5, 0}, +/* 16 */ { 14, s_1_16, -1, 3, 0}, +/* 17 */ { 18, s_1_17, -1, 10, 0}, +/* 18 */ { 8, s_1_18, -1, 9, 0}, +/* 19 */ { 12, s_1_19, -1, 7, 0}, +/* 20 */ { 12, s_1_20, -1, 8, 0}, +/* 21 */ { 12, s_1_21, -1, 6, 0}, +/* 22 */ { 16, s_1_22, -1, 11, 0}, +/* 23 */ { 10, s_1_23, -1, 1, 0}, +/* 24 */ { 12, s_1_24, -1, 2, 0}, +/* 25 */ { 10, s_1_25, -1, 4, 0}, +/* 26 */ { 14, s_1_26, -1, 5, 0}, +/* 27 */ { 12, s_1_27, -1, 3, 0}, +/* 28 */ { 12, s_1_28, -1, 7, 0}, +/* 29 */ { 20, s_1_29, -1, 10, 0}, +/* 30 */ { 10, s_1_30, -1, 9, 0}, +/* 31 */ { 14, s_1_31, -1, 7, 0}, +/* 32 */ { 14, s_1_32, -1, 8, 0}, +/* 33 */ { 14, s_1_33, -1, 6, 0}, +/* 34 */ { 18, s_1_34, -1, 11, 0}, +/* 35 */ { 12, s_1_35, -1, 1, 0}, +/* 36 */ { 14, s_1_36, -1, 2, 0}, +/* 37 */ { 12, s_1_37, -1, 4, 0}, +/* 38 */ { 16, s_1_38, -1, 5, 0}, +/* 39 */ { 14, s_1_39, -1, 3, 0} +}; + +static const symbol s_2_0[4] = { 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_1[12] = { 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_2[6] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_3[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_4[12] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_5[8] = { 0xCE, 0xB5, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_2_6[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_2_7[8] = { 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; +static const symbol s_2_8[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; + +static const struct among a_2[9] = +{ +/* 0 */ { 4, s_2_0, -1, 1, 0}, +/* 1 */ { 12, s_2_1, 0, 1, 0}, +/* 2 */ { 6, s_2_2, 0, 1, 0}, +/* 3 */ { 12, s_2_3, 0, 1, 0}, +/* 4 */ { 12, s_2_4, 0, 1, 0}, +/* 5 */ { 8, s_2_5, 0, 1, 0}, +/* 6 */ { 8, s_2_6, -1, 1, 0}, +/* 7 */ { 8, s_2_7, -1, 1, 0}, +/* 8 */ { 14, s_2_8, 7, 1, 0} +}; + +static const symbol s_3_0[2] = { 0xCF, 0x80 }; +static const symbol s_3_1[6] = { 0xCE, 0xB9, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_3_2[2] = { 0xCF, 0x81 }; +static const symbol s_3_3[4] = { 0xCF, 0x80, 0xCF, 0x81 }; +static const symbol s_3_4[6] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCF, 0x81 }; +static const symbol s_3_5[6] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x81 }; +static const symbol s_3_6[12] = { 0xCE, 0xB3, 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xBA, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_3_7[10] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_3_8[10] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_3_9[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_3_10[6] = { 0xCE, 0xB3, 0xCE, 0xBA, 0xCF, 0x81 }; +static const symbol s_3_11[14] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_3_12[12] = { 0xCE, 0xB2, 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xB2, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_3_13[12] = { 0xCE, 0xB3, 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_3_14[6] = { 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_3_15[2] = { 0xCE, 0xB2 }; +static const symbol s_3_16[12] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x85, 0xCF, 0x81, 0xCE, 0xB9 }; +static const symbol s_3_17[8] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBA }; +static const symbol s_3_18[8] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBA }; +static const symbol s_3_19[2] = { 0xCE, 0xBB }; +static const symbol s_3_20[2] = { 0xCE, 0xBC }; +static const symbol s_3_21[8] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81, 0xCE, 0xBD }; + +static const struct among a_3[22] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 6, s_3_1, 0, 1, 0}, +/* 2 */ { 2, s_3_2, -1, 1, 0}, +/* 3 */ { 4, s_3_3, 2, 1, 0}, +/* 4 */ { 6, s_3_4, 3, 1, 0}, +/* 5 */ { 6, s_3_5, 2, 1, 0}, +/* 6 */ { 12, s_3_6, 2, 1, 0}, +/* 7 */ { 10, s_3_7, 2, 1, 0}, +/* 8 */ { 10, s_3_8, 2, 1, 0}, +/* 9 */ { 6, s_3_9, 2, 1, 0}, +/* 10 */ { 6, s_3_10, 2, 1, 0}, +/* 11 */ { 14, s_3_11, 2, 1, 0}, +/* 12 */ { 12, s_3_12, 2, 1, 0}, +/* 13 */ { 12, s_3_13, 2, 1, 0}, +/* 14 */ { 6, s_3_14, -1, 1, 0}, +/* 15 */ { 2, s_3_15, -1, 1, 0}, +/* 16 */ { 12, s_3_16, -1, 1, 0}, +/* 17 */ { 8, s_3_17, -1, 1, 0}, +/* 18 */ { 8, s_3_18, -1, 1, 0}, +/* 19 */ { 2, s_3_19, -1, 1, 0}, +/* 20 */ { 2, s_3_20, -1, 1, 0}, +/* 21 */ { 8, s_3_21, -1, 1, 0} +}; + +static const symbol s_4_0[8] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_4_1[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_4_2[6] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCF, 0x89 }; +static const symbol s_4_3[6] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1 }; +static const symbol s_4_4[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_4_5[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_4_6[6] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5 }; +static const symbol s_4_7[12] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_4_8[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_4_9[12] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_4_10[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_4_11[8] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_4_12[10] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_4_13[8] = { 0xCE, 0xB9, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBD }; + +static const struct among a_4[14] = +{ +/* 0 */ { 8, s_4_0, -1, 1, 0}, +/* 1 */ { 10, s_4_1, -1, 1, 0}, +/* 2 */ { 6, s_4_2, -1, 1, 0}, +/* 3 */ { 6, s_4_3, -1, 1, 0}, +/* 4 */ { 10, s_4_4, -1, 1, 0}, +/* 5 */ { 10, s_4_5, -1, 1, 0}, +/* 6 */ { 6, s_4_6, -1, 1, 0}, +/* 7 */ { 12, s_4_7, -1, 1, 0}, +/* 8 */ { 10, s_4_8, -1, 1, 0}, +/* 9 */ { 12, s_4_9, -1, 1, 0}, +/* 10 */ { 10, s_4_10, -1, 1, 0}, +/* 11 */ { 8, s_4_11, -1, 1, 0}, +/* 12 */ { 10, s_4_12, -1, 1, 0}, +/* 13 */ { 8, s_4_13, -1, 1, 0} +}; + +static const symbol s_5_0[2] = { 0xCF, 0x83 }; +static const symbol s_5_1[2] = { 0xCF, 0x87 }; +static const symbol s_5_2[4] = { 0xCF, 0x85, 0xCF, 0x88 }; +static const symbol s_5_3[4] = { 0xCE, 0xB6, 0xCF, 0x89 }; +static const symbol s_5_4[4] = { 0xCE, 0xB2, 0xCE, 0xB9 }; +static const symbol s_5_5[4] = { 0xCE, 0xBB, 0xCE, 0xB9 }; +static const symbol s_5_6[4] = { 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_5_7[4] = { 0xCE, 0xB5, 0xCE, 0xBD }; + +static const struct among a_5[8] = +{ +/* 0 */ { 2, s_5_0, -1, 1, 0}, +/* 1 */ { 2, s_5_1, -1, 1, 0}, +/* 2 */ { 4, s_5_2, -1, 1, 0}, +/* 3 */ { 4, s_5_3, -1, 1, 0}, +/* 4 */ { 4, s_5_4, -1, 1, 0}, +/* 5 */ { 4, s_5_5, -1, 1, 0}, +/* 6 */ { 4, s_5_6, -1, 1, 0}, +/* 7 */ { 4, s_5_7, -1, 1, 0} +}; + +static const symbol s_6_0[12] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_6_1[10] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1 }; +static const symbol s_6_2[14] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_6_3[10] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5 }; +static const symbol s_6_4[14] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_6_5[14] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_6_6[12] = { 0xCF, 0x89, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD }; + +static const struct among a_6[7] = +{ +/* 0 */ { 12, s_6_0, -1, 1, 0}, +/* 1 */ { 10, s_6_1, -1, 1, 0}, +/* 2 */ { 14, s_6_2, -1, 1, 0}, +/* 3 */ { 10, s_6_3, -1, 1, 0}, +/* 4 */ { 14, s_6_4, -1, 1, 0}, +/* 5 */ { 14, s_6_5, -1, 1, 0}, +/* 6 */ { 12, s_6_6, -1, 1, 0} +}; + +static const symbol s_7_0[12] = { 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_1[6] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_2[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_3[12] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_4[8] = { 0xCE, 0xB5, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_5[14] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_7_6[12] = { 0xCE, 0xB5, 0xCE, 0xBE, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x87, 0xCE, 0xB1 }; +static const symbol s_7_7[4] = { 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_7_8[6] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_7_9[12] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_7_10[6] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_7_11[6] = { 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_7_12[12] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x89, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_7_13[8] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_7_14[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_7_15[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_7_16[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_7_17[8] = { 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; +static const symbol s_7_18[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; + +static const struct among a_7[19] = +{ +/* 0 */ { 12, s_7_0, -1, 1, 0}, +/* 1 */ { 6, s_7_1, -1, 1, 0}, +/* 2 */ { 12, s_7_2, -1, 1, 0}, +/* 3 */ { 12, s_7_3, -1, 1, 0}, +/* 4 */ { 8, s_7_4, -1, 1, 0}, +/* 5 */ { 14, s_7_5, -1, 1, 0}, +/* 6 */ { 12, s_7_6, -1, 1, 0}, +/* 7 */ { 4, s_7_7, -1, 1, 0}, +/* 8 */ { 6, s_7_8, 7, 1, 0}, +/* 9 */ { 12, s_7_9, 8, 1, 0}, +/* 10 */ { 6, s_7_10, -1, 1, 0}, +/* 11 */ { 6, s_7_11, -1, 1, 0}, +/* 12 */ { 12, s_7_12, 11, 1, 0}, +/* 13 */ { 8, s_7_13, 11, 1, 0}, +/* 14 */ { 12, s_7_14, 13, 1, 0}, +/* 15 */ { 12, s_7_15, 11, 1, 0}, +/* 16 */ { 8, s_7_16, -1, 1, 0}, +/* 17 */ { 8, s_7_17, -1, 1, 0}, +/* 18 */ { 14, s_7_18, 17, 1, 0} +}; + +static const symbol s_8_0[2] = { 0xCF, 0x80 }; +static const symbol s_8_1[6] = { 0xCE, 0xBB, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_8_2[16] = { 0xCE, 0xB4, 0xCE, 0xB7, 0xCE, 0xBC, 0xCE, 0xBF, 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_8_3[4] = { 0xCE, 0xB1, 0xCF, 0x86 }; +static const symbol s_8_4[18] = { 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB1, 0xCF, 0x86 }; +static const symbol s_8_5[4] = { 0xCE, 0xB3, 0xCE, 0xB5 }; +static const symbol s_8_6[6] = { 0xCE, 0xB3, 0xCE, 0xBA, 0xCE, 0xB5 }; +static const symbol s_8_7[4] = { 0xCE, 0xB3, 0xCE, 0xBA }; +static const symbol s_8_8[2] = { 0xCE, 0xBC }; +static const symbol s_8_9[12] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_8_10[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBC }; +static const symbol s_8_11[4] = { 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_8_12[6] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF }; + +static const struct among a_8[13] = +{ +/* 0 */ { 2, s_8_0, -1, 1, 0}, +/* 1 */ { 6, s_8_1, -1, 1, 0}, +/* 2 */ { 16, s_8_2, -1, 1, 0}, +/* 3 */ { 4, s_8_3, -1, 1, 0}, +/* 4 */ { 18, s_8_4, 3, 1, 0}, +/* 5 */ { 4, s_8_5, -1, 1, 0}, +/* 6 */ { 6, s_8_6, -1, 1, 0}, +/* 7 */ { 4, s_8_7, -1, 1, 0}, +/* 8 */ { 2, s_8_8, -1, 1, 0}, +/* 9 */ { 12, s_8_9, 8, 1, 0}, +/* 10 */ { 6, s_8_10, 8, 1, 0}, +/* 11 */ { 4, s_8_11, -1, 1, 0}, +/* 12 */ { 6, s_8_12, -1, 1, 0} +}; + +static const symbol s_9_0[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_9_1[6] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_9_2[6] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_9_3[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_9_4[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_9_5[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_9_6[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD }; + +static const struct among a_9[7] = +{ +/* 0 */ { 8, s_9_0, -1, 1, 0}, +/* 1 */ { 6, s_9_1, -1, 1, 0}, +/* 2 */ { 6, s_9_2, -1, 1, 0}, +/* 3 */ { 10, s_9_3, -1, 1, 0}, +/* 4 */ { 10, s_9_4, -1, 1, 0}, +/* 5 */ { 10, s_9_5, -1, 1, 0}, +/* 6 */ { 8, s_9_6, -1, 1, 0} +}; + +static const symbol s_10_0[12] = { 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_1[6] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_2[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_3[12] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_4[8] = { 0xCE, 0xB5, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_5[14] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xB1 }; +static const symbol s_10_6[12] = { 0xCE, 0xB5, 0xCE, 0xBE, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x87, 0xCE, 0xB1 }; +static const symbol s_10_7[4] = { 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_10_8[6] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_10_9[12] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB5 }; +static const symbol s_10_10[6] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_10_11[6] = { 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_10_12[12] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x89, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_10_13[8] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_10_14[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_10_15[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_10_16[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_10_17[8] = { 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; +static const symbol s_10_18[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; + +static const struct among a_10[19] = +{ +/* 0 */ { 12, s_10_0, -1, 1, 0}, +/* 1 */ { 6, s_10_1, -1, 1, 0}, +/* 2 */ { 12, s_10_2, -1, 1, 0}, +/* 3 */ { 12, s_10_3, -1, 1, 0}, +/* 4 */ { 8, s_10_4, -1, 1, 0}, +/* 5 */ { 14, s_10_5, -1, 1, 0}, +/* 6 */ { 12, s_10_6, -1, 1, 0}, +/* 7 */ { 4, s_10_7, -1, 1, 0}, +/* 8 */ { 6, s_10_8, 7, 1, 0}, +/* 9 */ { 12, s_10_9, 8, 1, 0}, +/* 10 */ { 6, s_10_10, -1, 1, 0}, +/* 11 */ { 6, s_10_11, -1, 1, 0}, +/* 12 */ { 12, s_10_12, 11, 1, 0}, +/* 13 */ { 8, s_10_13, 11, 1, 0}, +/* 14 */ { 12, s_10_14, 13, 1, 0}, +/* 15 */ { 12, s_10_15, 11, 1, 0}, +/* 16 */ { 8, s_10_16, -1, 1, 0}, +/* 17 */ { 8, s_10_17, -1, 1, 0}, +/* 18 */ { 14, s_10_18, 17, 1, 0} +}; + +static const symbol s_11_0[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_11_1[6] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x89 }; +static const symbol s_11_2[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_11_3[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_11_4[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_11_5[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_11_6[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; + +static const struct among a_11[7] = +{ +/* 0 */ { 10, s_11_0, -1, 1, 0}, +/* 1 */ { 6, s_11_1, -1, 1, 0}, +/* 2 */ { 10, s_11_2, -1, 1, 0}, +/* 3 */ { 12, s_11_3, -1, 1, 0}, +/* 4 */ { 12, s_11_4, -1, 1, 0}, +/* 5 */ { 8, s_11_5, -1, 1, 0}, +/* 6 */ { 10, s_11_6, -1, 1, 0} +}; + +static const symbol s_12_0[4] = { 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_12_1[6] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_12_2[6] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_12_3[6] = { 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_12_4[12] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x89, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_12_5[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_12_6[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x81, 0xCE, 0xBF }; + +static const struct among a_12[7] = +{ +/* 0 */ { 4, s_12_0, -1, 1, 0}, +/* 1 */ { 6, s_12_1, 0, 1, 0}, +/* 2 */ { 6, s_12_2, -1, 1, 0}, +/* 3 */ { 6, s_12_3, -1, 1, 0}, +/* 4 */ { 12, s_12_4, 3, 1, 0}, +/* 5 */ { 8, s_12_5, -1, 1, 0}, +/* 6 */ { 14, s_12_6, -1, 1, 0} +}; + +static const symbol s_13_0[2] = { 0xCF, 0x80 }; +static const symbol s_13_1[6] = { 0xCE, 0xB5, 0xCF, 0x85, 0xCF, 0x80 }; +static const symbol s_13_2[4] = { 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_13_3[6] = { 0xCE, 0xB5, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_13_4[6] = { 0xCE, 0xB3, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_13_5[4] = { 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_13_6[6] = { 0xCF, 0x87, 0xCF, 0x89, 0xCF, 0x81 }; +static const symbol s_13_7[4] = { 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_13_8[6] = { 0xCE, 0xB1, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_13_9[4] = { 0xCF, 0x87, 0xCF, 0x84 }; +static const symbol s_13_10[6] = { 0xCE, 0xB1, 0xCF, 0x87, 0xCF, 0x84 }; +static const symbol s_13_11[4] = { 0xCE, 0xBA, 0xCF, 0x84 }; +static const symbol s_13_12[6] = { 0xCE, 0xB1, 0xCE, 0xBA, 0xCF, 0x84 }; +static const symbol s_13_13[4] = { 0xCF, 0x83, 0xCF, 0x87 }; +static const symbol s_13_14[6] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x87 }; +static const symbol s_13_15[6] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x87 }; +static const symbol s_13_16[4] = { 0xCF, 0x85, 0xCF, 0x88 }; +static const symbol s_13_17[6] = { 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_13_18[4] = { 0xCF, 0x86, 0xCE, 0xB1 }; +static const symbol s_13_19[6] = { 0xCE, 0xB7, 0xCF, 0x86, 0xCE, 0xB1 }; +static const symbol s_13_20[6] = { 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xB3 }; +static const symbol s_13_21[6] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xB3 }; +static const symbol s_13_22[4] = { 0xCE, 0xB7, 0xCE, 0xB4 }; +static const symbol s_13_23[6] = { 0xCE, 0xB5, 0xCF, 0x87, 0xCE, 0xB8 }; +static const symbol s_13_24[6] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_13_25[4] = { 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_13_26[6] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_13_27[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_13_28[6] = { 0xCE, 0xBA, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_13_29[6] = { 0xCF, 0x86, 0xCE, 0xB9, 0xCE, 0xBB }; +static const symbol s_13_30[2] = { 0xCE, 0xBC }; +static const symbol s_13_31[6] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xBC }; +static const symbol s_13_32[6] = { 0xCE, 0xB1, 0xCF, 0x87, 0xCE, 0xBD }; + +static const struct among a_13[33] = +{ +/* 0 */ { 2, s_13_0, -1, 1, 0}, +/* 1 */ { 6, s_13_1, 0, 1, 0}, +/* 2 */ { 4, s_13_2, 0, 1, 0}, +/* 3 */ { 6, s_13_3, 0, 1, 0}, +/* 4 */ { 6, s_13_4, -1, 1, 0}, +/* 5 */ { 4, s_13_5, -1, 1, 0}, +/* 6 */ { 6, s_13_6, -1, 1, 0}, +/* 7 */ { 4, s_13_7, -1, 1, 0}, +/* 8 */ { 6, s_13_8, -1, 1, 0}, +/* 9 */ { 4, s_13_9, -1, 1, 0}, +/* 10 */ { 6, s_13_10, 9, 1, 0}, +/* 11 */ { 4, s_13_11, -1, 1, 0}, +/* 12 */ { 6, s_13_12, 11, 1, 0}, +/* 13 */ { 4, s_13_13, -1, 1, 0}, +/* 14 */ { 6, s_13_14, 13, 1, 0}, +/* 15 */ { 6, s_13_15, -1, 1, 0}, +/* 16 */ { 4, s_13_16, -1, 1, 0}, +/* 17 */ { 6, s_13_17, -1, 1, 0}, +/* 18 */ { 4, s_13_18, -1, 1, 0}, +/* 19 */ { 6, s_13_19, 18, 1, 0}, +/* 20 */ { 6, s_13_20, -1, 1, 0}, +/* 21 */ { 6, s_13_21, -1, 1, 0}, +/* 22 */ { 4, s_13_22, -1, 1, 0}, +/* 23 */ { 6, s_13_23, -1, 1, 0}, +/* 24 */ { 6, s_13_24, -1, 1, 0}, +/* 25 */ { 4, s_13_25, -1, 1, 0}, +/* 26 */ { 6, s_13_26, -1, 1, 0}, +/* 27 */ { 6, s_13_27, -1, 1, 0}, +/* 28 */ { 6, s_13_28, -1, 1, 0}, +/* 29 */ { 6, s_13_29, -1, 1, 0}, +/* 30 */ { 2, s_13_30, -1, 1, 0}, +/* 31 */ { 6, s_13_31, 30, 1, 0}, +/* 32 */ { 6, s_13_32, -1, 1, 0} +}; + +static const symbol s_14_0[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_14_1[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_14_2[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB7, 0xCF, 0x83 }; +static const symbol s_14_3[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_14_4[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_14_5[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_14_6[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_14_7[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB7 }; +static const symbol s_14_8[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB9 }; +static const symbol s_14_9[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_14_10[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xBF }; + +static const struct among a_14[11] = +{ +/* 0 */ { 12, s_14_0, -1, 1, 0}, +/* 1 */ { 10, s_14_1, -1, 1, 0}, +/* 2 */ { 10, s_14_2, -1, 1, 0}, +/* 3 */ { 10, s_14_3, -1, 1, 0}, +/* 4 */ { 10, s_14_4, -1, 1, 0}, +/* 5 */ { 8, s_14_5, -1, 1, 0}, +/* 6 */ { 8, s_14_6, -1, 1, 0}, +/* 7 */ { 8, s_14_7, -1, 1, 0}, +/* 8 */ { 10, s_14_8, -1, 1, 0}, +/* 9 */ { 10, s_14_9, -1, 1, 0}, +/* 10 */ { 8, s_14_10, -1, 1, 0} +}; + +static const symbol s_15_0[4] = { 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_15_1[12] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_15_2[14] = { 0xCE, 0xBC, 0xCE, 0xB9, 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB5 }; +static const symbol s_15_3[10] = { 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_15_4[12] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5 }; + +static const struct among a_15[5] = +{ +/* 0 */ { 4, s_15_0, -1, 1, 0}, +/* 1 */ { 12, s_15_1, 0, 1, 0}, +/* 2 */ { 14, s_15_2, 0, 1, 0}, +/* 3 */ { 10, s_15_3, -1, 1, 0}, +/* 4 */ { 12, s_15_4, -1, 1, 0} +}; + +static const symbol s_16_0[8] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_16_1[16] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; + +static const struct among a_16[2] = +{ +/* 0 */ { 8, s_16_0, -1, 1, 0}, +/* 1 */ { 16, s_16_1, 0, 1, 0} +}; + +static const symbol s_17_0[10] = { 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_1[14] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x80, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_2[14] = { 0xCE, 0xB3, 0xCE, 0xBD, 0xCF, 0x89, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_3[16] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xBD, 0xCF, 0x89, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_4[16] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBA, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_5[12] = { 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_6[10] = { 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBD, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_17_7[14] = { 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB9, 0xCE, 0xBD }; +static const symbol s_17_8[20] = { 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB4, 0xCF, 0x81, 0xCE, 0xB9, 0xCE, 0xBD }; +static const symbol s_17_9[16] = { 0xCE, 0xB2, 0xCF, 0x85, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBD }; + +static const struct among a_17[10] = +{ +/* 0 */ { 10, s_17_0, -1, 7, 0}, +/* 1 */ { 14, s_17_1, -1, 6, 0}, +/* 2 */ { 14, s_17_2, -1, 3, 0}, +/* 3 */ { 16, s_17_3, 2, 1, 0}, +/* 4 */ { 16, s_17_4, -1, 5, 0}, +/* 5 */ { 12, s_17_5, -1, 2, 0}, +/* 6 */ { 10, s_17_6, -1, 4, 0}, +/* 7 */ { 14, s_17_7, -1, 10, 0}, +/* 8 */ { 20, s_17_8, -1, 8, 0}, +/* 9 */ { 16, s_17_9, -1, 9, 0} +}; + +static const symbol s_18_0[12] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_18_1[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_18_2[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_18_3[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF, 0xCE, 0xB9 }; +static const symbol s_18_4[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_18_5[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xBF }; + +static const struct among a_18[6] = +{ +/* 0 */ { 12, s_18_0, -1, 1, 0}, +/* 1 */ { 10, s_18_1, -1, 1, 0}, +/* 2 */ { 10, s_18_2, -1, 1, 0}, +/* 3 */ { 10, s_18_3, -1, 1, 0}, +/* 4 */ { 10, s_18_4, -1, 1, 0}, +/* 5 */ { 8, s_18_5, -1, 1, 0} +}; + +static const symbol s_19_0[2] = { 0xCF, 0x83 }; +static const symbol s_19_1[2] = { 0xCF, 0x87 }; + +static const struct among a_19[2] = +{ +/* 0 */ { 2, s_19_0, -1, 1, 0}, +/* 1 */ { 2, s_19_1, -1, 1, 0} +}; + +static const symbol s_20_0[12] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_20_1[14] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_20_2[10] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9 }; +static const symbol s_20_3[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9 }; + +static const struct among a_20[4] = +{ +/* 0 */ { 12, s_20_0, -1, 1, 0}, +/* 1 */ { 14, s_20_1, -1, 1, 0}, +/* 2 */ { 10, s_20_2, -1, 1, 0}, +/* 3 */ { 12, s_20_3, -1, 1, 0} +}; + +static const symbol s_21_0[12] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_21_1[2] = { 0xCF, 0x81 }; +static const symbol s_21_2[4] = { 0xCE, 0xB2, 0xCF, 0x81 }; +static const symbol s_21_3[8] = { 0xCE, 0xBB, 0xCE, 0xB1, 0xCE, 0xB2, 0xCF, 0x81 }; +static const symbol s_21_4[8] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB2, 0xCF, 0x81 }; +static const symbol s_21_5[6] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_21_6[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB8, 0xCF, 0x81 }; +static const symbol s_21_7[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_21_8[2] = { 0xCF, 0x83 }; +static const symbol s_21_9[12] = { 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_21_10[10] = { 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_21_11[4] = { 0xCF, 0x81, 0xCF, 0x85 }; +static const symbol s_21_12[2] = { 0xCF, 0x86 }; +static const symbol s_21_13[4] = { 0xCF, 0x83, 0xCF, 0x86 }; +static const symbol s_21_14[10] = { 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x86 }; +static const symbol s_21_15[2] = { 0xCF, 0x87 }; +static const symbol s_21_16[8] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB2 }; +static const symbol s_21_17[8] = { 0xCF, 0x83, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB2 }; +static const symbol s_21_18[18] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x87, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB2 }; +static const symbol s_21_19[4] = { 0xCF, 0x84, 0xCE, 0xB6 }; +static const symbol s_21_20[2] = { 0xCE, 0xBA }; +static const symbol s_21_21[4] = { 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_21_22[10] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_21_23[6] = { 0xCF, 0x83, 0xCE, 0xBF, 0xCE, 0xBA }; +static const symbol s_21_24[4] = { 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_21_25[6] = { 0xCF, 0x86, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_21_26[8] = { 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_21_27[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_21_28[8] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBC }; +static const symbol s_21_29[8] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB9, 0xCE, 0xBC }; +static const symbol s_21_30[8] = { 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xBC }; +static const symbol s_21_31[8] = { 0xCF, 0x83, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_21_32[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_21[33] = +{ +/* 0 */ { 12, s_21_0, -1, 1, 0}, +/* 1 */ { 2, s_21_1, -1, 1, 0}, +/* 2 */ { 4, s_21_2, 1, 1, 0}, +/* 3 */ { 8, s_21_3, 2, 1, 0}, +/* 4 */ { 8, s_21_4, 2, 1, 0}, +/* 5 */ { 6, s_21_5, 1, 1, 0}, +/* 6 */ { 8, s_21_6, 1, 1, 0}, +/* 7 */ { 6, s_21_7, 1, 1, 0}, +/* 8 */ { 2, s_21_8, -1, 1, 0}, +/* 9 */ { 12, s_21_9, 8, 1, 0}, +/* 10 */ { 10, s_21_10, -1, 1, 0}, +/* 11 */ { 4, s_21_11, -1, 1, 0}, +/* 12 */ { 2, s_21_12, -1, 1, 0}, +/* 13 */ { 4, s_21_13, 12, 1, 0}, +/* 14 */ { 10, s_21_14, 13, 1, 0}, +/* 15 */ { 2, s_21_15, -1, 1, 0}, +/* 16 */ { 8, s_21_16, -1, 1, 0}, +/* 17 */ { 8, s_21_17, -1, 1, 0}, +/* 18 */ { 18, s_21_18, 17, 1, 0}, +/* 19 */ { 4, s_21_19, -1, 1, 0}, +/* 20 */ { 2, s_21_20, -1, 1, 0}, +/* 21 */ { 4, s_21_21, 20, 1, 0}, +/* 22 */ { 10, s_21_22, 20, 1, 0}, +/* 23 */ { 6, s_21_23, 20, 1, 0}, +/* 24 */ { 4, s_21_24, -1, 1, 0}, +/* 25 */ { 6, s_21_25, -1, 1, 0}, +/* 26 */ { 8, s_21_26, -1, 1, 0}, +/* 27 */ { 6, s_21_27, -1, 1, 0}, +/* 28 */ { 8, s_21_28, -1, 1, 0}, +/* 29 */ { 8, s_21_29, -1, 1, 0}, +/* 30 */ { 8, s_21_30, -1, 1, 0}, +/* 31 */ { 8, s_21_31, -1, 1, 0}, +/* 32 */ { 6, s_21_32, -1, 1, 0} +}; + +static const symbol s_22_0[2] = { 0xCF, 0x80 }; +static const symbol s_22_1[10] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_22_2[6] = { 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_22_3[6] = { 0xCE, 0xBD, 0xCF, 0x85, 0xCF, 0x86 }; +static const symbol s_22_4[2] = { 0xCE, 0xB2 }; +static const symbol s_22_5[8] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB4 }; +static const symbol s_22_6[2] = { 0xCE, 0xB6 }; +static const symbol s_22_7[4] = { 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_22_8[6] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_22_9[4] = { 0xCE, 0xB3, 0xCE, 0xBB }; +static const symbol s_22_10[12] = { 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB }; +static const symbol s_22_11[12] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBA, 0xCF, 0x81, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_22_12[8] = { 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_22_13[14] = { 0xCE, 0xB7, 0xCE, 0xB3, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xBD }; +static const symbol s_22_14[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_22[15] = +{ +/* 0 */ { 2, s_22_0, -1, 1, 0}, +/* 1 */ { 10, s_22_1, -1, 1, 0}, +/* 2 */ { 6, s_22_2, -1, 1, 0}, +/* 3 */ { 6, s_22_3, -1, 1, 0}, +/* 4 */ { 2, s_22_4, -1, 1, 0}, +/* 5 */ { 8, s_22_5, -1, 1, 0}, +/* 6 */ { 2, s_22_6, -1, 1, 0}, +/* 7 */ { 4, s_22_7, -1, 1, 0}, +/* 8 */ { 6, s_22_8, -1, 1, 0}, +/* 9 */ { 4, s_22_9, -1, 1, 0}, +/* 10 */ { 12, s_22_10, -1, 1, 0}, +/* 11 */ { 12, s_22_11, -1, 1, 0}, +/* 12 */ { 8, s_22_12, -1, 1, 0}, +/* 13 */ { 14, s_22_13, -1, 1, 0}, +/* 14 */ { 6, s_22_14, -1, 1, 0} +}; + +static const symbol s_23_0[10] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_23_1[10] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_23_2[8] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_23_3[8] = { 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_23_4[12] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_23_5[6] = { 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9 }; +static const symbol s_23_6[10] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB9 }; +static const symbol s_23_7[10] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_23[8] = +{ +/* 0 */ { 10, s_23_0, -1, 1, 0}, +/* 1 */ { 10, s_23_1, -1, 1, 0}, +/* 2 */ { 8, s_23_2, -1, 1, 0}, +/* 3 */ { 8, s_23_3, -1, 1, 0}, +/* 4 */ { 12, s_23_4, 3, 1, 0}, +/* 5 */ { 6, s_23_5, -1, 1, 0}, +/* 6 */ { 10, s_23_6, 5, 1, 0}, +/* 7 */ { 10, s_23_7, -1, 1, 0} +}; + +static const symbol s_24_0[4] = { 0xCE, 0xB9, 0xCF, 0x81 }; +static const symbol s_24_1[6] = { 0xCF, 0x88, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_24_2[8] = { 0xCE, 0xB1, 0xCE, 0xB9, 0xCF, 0x86, 0xCE, 0xBD }; +static const symbol s_24_3[6] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF }; + +static const struct among a_24[4] = +{ +/* 0 */ { 4, s_24_0, -1, 1, 0}, +/* 1 */ { 6, s_24_1, -1, 1, 0}, +/* 2 */ { 8, s_24_2, -1, 1, 0}, +/* 3 */ { 6, s_24_3, -1, 1, 0} +}; + +static const symbol s_25_0[2] = { 0xCE, 0xB5 }; +static const symbol s_25_1[10] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xB9, 0xCF, 0x87, 0xCE, 0xBD }; + +static const struct among a_25[2] = +{ +/* 0 */ { 2, s_25_0, -1, 1, 0}, +/* 1 */ { 10, s_25_1, -1, 1, 0} +}; + +static const symbol s_26_0[8] = { 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_26_1[10] = { 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_26_2[8] = { 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xBF }; + +static const struct among a_26[3] = +{ +/* 0 */ { 8, s_26_0, -1, 1, 0}, +/* 1 */ { 10, s_26_1, -1, 1, 0}, +/* 2 */ { 8, s_26_2, -1, 1, 0} +}; + +static const symbol s_27_0[2] = { 0xCF, 0x81 }; +static const symbol s_27_1[4] = { 0xCE, 0xB9, 0xCE, 0xB2 }; +static const symbol s_27_2[2] = { 0xCE, 0xB4 }; +static const symbol s_27_3[6] = { 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xBA }; +static const symbol s_27_4[10] = { 0xCF, 0x86, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xBA }; +static const symbol s_27_5[8] = { 0xCE, 0xBF, 0xCE, 0xB2, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_27_6[6] = { 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBD }; + +static const struct among a_27[7] = +{ +/* 0 */ { 2, s_27_0, -1, 1, 0}, +/* 1 */ { 4, s_27_1, -1, 1, 0}, +/* 2 */ { 2, s_27_2, -1, 1, 0}, +/* 3 */ { 6, s_27_3, -1, 1, 0}, +/* 4 */ { 10, s_27_4, -1, 1, 0}, +/* 5 */ { 8, s_27_5, -1, 1, 0}, +/* 6 */ { 6, s_27_6, -1, 1, 0} +}; + +static const symbol s_28_0[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_28_1[10] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_28_2[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB5 }; +static const symbol s_28_3[8] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF }; + +static const struct among a_28[4] = +{ +/* 0 */ { 10, s_28_0, -1, 1, 0}, +/* 1 */ { 10, s_28_1, -1, 1, 0}, +/* 2 */ { 8, s_28_2, -1, 1, 0}, +/* 3 */ { 8, s_28_3, -1, 1, 0} +}; + +static const symbol s_29_0[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_29_1[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_29[2] = +{ +/* 0 */ { 8, s_29_0, -1, 1, 0}, +/* 1 */ { 8, s_29_1, -1, 1, 0} +}; + +static const symbol s_30_0[10] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_30_1[6] = { 0xCE, 0xBA, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_30_2[10] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_30_3[10] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_30_4[10] = { 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_30_5[10] = { 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9 }; +static const symbol s_30_6[6] = { 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_30_7[4] = { 0xCE, 0xBF, 0xCE, 0xBA }; +static const symbol s_30_8[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_30_9[6] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBD }; + +static const struct among a_30[10] = +{ +/* 0 */ { 10, s_30_0, -1, -1, 0}, +/* 1 */ { 6, s_30_1, -1, -1, 0}, +/* 2 */ { 10, s_30_2, -1, -1, 0}, +/* 3 */ { 10, s_30_3, -1, -1, 0}, +/* 4 */ { 10, s_30_4, -1, -1, 0}, +/* 5 */ { 10, s_30_5, -1, -1, 0}, +/* 6 */ { 6, s_30_6, -1, -1, 0}, +/* 7 */ { 4, s_30_7, -1, -1, 0}, +/* 8 */ { 6, s_30_8, -1, -1, 0}, +/* 9 */ { 6, s_30_9, -1, -1, 0} +}; + +static const symbol s_31_0[8] = { 0xCE, 0xB5, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_31_1[8] = { 0xCE, 0xB5, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_31[2] = +{ +/* 0 */ { 8, s_31_0, -1, 1, 0}, +/* 1 */ { 8, s_31_1, -1, 1, 0} +}; + +static const symbol s_32_0[10] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x80 }; +static const symbol s_32_1[4] = { 0xCF, 0x85, 0xCF, 0x80 }; +static const symbol s_32_2[6] = { 0xCE, 0xB4, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_32_3[6] = { 0xCE, 0xB3, 0xCE, 0xB7, 0xCF, 0x80 }; +static const symbol s_32_4[4] = { 0xCE, 0xB9, 0xCF, 0x80 }; +static const symbol s_32_5[6] = { 0xCE, 0xB5, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_32_6[4] = { 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_32_7[6] = { 0xCE, 0xBC, 0xCE, 0xB9, 0xCE, 0xBB }; + +static const struct among a_32[8] = +{ +/* 0 */ { 10, s_32_0, -1, 1, 0}, +/* 1 */ { 4, s_32_1, -1, 1, 0}, +/* 2 */ { 6, s_32_2, -1, 1, 0}, +/* 3 */ { 6, s_32_3, -1, 1, 0}, +/* 4 */ { 4, s_32_4, -1, 1, 0}, +/* 5 */ { 6, s_32_5, -1, 1, 0}, +/* 6 */ { 4, s_32_6, -1, 1, 0}, +/* 7 */ { 6, s_32_7, -1, 1, 0} +}; + +static const symbol s_33_0[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_33_1[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_33[2] = +{ +/* 0 */ { 10, s_33_0, -1, 1, 0}, +/* 1 */ { 10, s_33_1, -1, 1, 0} +}; + +static const symbol s_34_0[4] = { 0xCF, 0x83, 0xCF, 0x80 }; +static const symbol s_34_1[4] = { 0xCF, 0x86, 0xCF, 0x81 }; +static const symbol s_34_2[2] = { 0xCF, 0x83 }; +static const symbol s_34_3[6] = { 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x87 }; +static const symbol s_34_4[8] = { 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_34_5[4] = { 0xCF, 0x86, 0xCE, 0xB5 }; +static const symbol s_34_6[6] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBA }; +static const symbol s_34_7[4] = { 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_34_8[12] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_34_9[8] = { 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_34_10[4] = { 0xCF, 0x86, 0xCE, 0xBB }; +static const symbol s_34_11[10] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_34_12[6] = { 0xCE, 0xB2, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_34_13[4] = { 0xCF, 0x87, 0xCE, 0xBD }; +static const symbol s_34_14[8] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBE }; + +static const struct among a_34[15] = +{ +/* 0 */ { 4, s_34_0, -1, 1, 0}, +/* 1 */ { 4, s_34_1, -1, 1, 0}, +/* 2 */ { 2, s_34_2, -1, 1, 0}, +/* 3 */ { 6, s_34_3, -1, 1, 0}, +/* 4 */ { 8, s_34_4, -1, 1, 0}, +/* 5 */ { 4, s_34_5, -1, 1, 0}, +/* 6 */ { 6, s_34_6, -1, 1, 0}, +/* 7 */ { 4, s_34_7, -1, 1, 0}, +/* 8 */ { 12, s_34_8, -1, 1, 0}, +/* 9 */ { 8, s_34_9, -1, 1, 0}, +/* 10 */ { 4, s_34_10, -1, 1, 0}, +/* 11 */ { 10, s_34_11, -1, 1, 0}, +/* 12 */ { 6, s_34_12, -1, 1, 0}, +/* 13 */ { 4, s_34_13, -1, 1, 0}, +/* 14 */ { 8, s_34_14, -1, 1, 0} +}; + +static const symbol s_35_0[6] = { 0xCE, 0xB5, 0xCF, 0x89, 0xCF, 0x83 }; +static const symbol s_35_1[6] = { 0xCE, 0xB5, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_35[2] = +{ +/* 0 */ { 6, s_35_0, -1, 1, 0}, +/* 1 */ { 6, s_35_1, -1, 1, 0} +}; + +static const symbol s_36_0[2] = { 0xCF, 0x80 }; +static const symbol s_36_1[6] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_36_2[2] = { 0xCE, 0xB4 }; +static const symbol s_36_3[4] = { 0xCE, 0xB9, 0xCE, 0xB4 }; +static const symbol s_36_4[2] = { 0xCE, 0xB8 }; +static const symbol s_36_5[6] = { 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_36_6[4] = { 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_36_7[2] = { 0xCE, 0xBD }; + +static const struct among a_36[8] = +{ +/* 0 */ { 2, s_36_0, -1, 1, 0}, +/* 1 */ { 6, s_36_1, -1, 1, 0}, +/* 2 */ { 2, s_36_2, -1, 1, 0}, +/* 3 */ { 4, s_36_3, 2, 1, 0}, +/* 4 */ { 2, s_36_4, -1, 1, 0}, +/* 5 */ { 6, s_36_5, -1, 1, 0}, +/* 6 */ { 4, s_36_6, -1, 1, 0}, +/* 7 */ { 2, s_36_7, -1, 1, 0} +}; + +static const symbol s_37_0[6] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_37_1[4] = { 0xCE, 0xB9, 0xCE, 0xB1 }; +static const symbol s_37_2[6] = { 0xCE, 0xB9, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_37[3] = +{ +/* 0 */ { 6, s_37_0, -1, 1, 0}, +/* 1 */ { 4, s_37_1, -1, 1, 0}, +/* 2 */ { 6, s_37_2, -1, 1, 0} +}; + +static const symbol s_38_0[8] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_38_1[6] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xB1 }; +static const symbol s_38_2[8] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_38_3[6] = { 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xBF }; + +static const struct among a_38[4] = +{ +/* 0 */ { 8, s_38_0, -1, 1, 0}, +/* 1 */ { 6, s_38_1, -1, 1, 0}, +/* 2 */ { 8, s_38_2, -1, 1, 0}, +/* 3 */ { 6, s_38_3, -1, 1, 0} +}; + +static const symbol s_39_0[8] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCF, 0x80 }; +static const symbol s_39_1[6] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_39_2[12] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_39_3[8] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_39_4[8] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_39_5[6] = { 0xCF, 0x86, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_39_6[6] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_39_7[8] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_39_8[8] = { 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x81, 0xCF, 0x84 }; +static const symbol s_39_9[14] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_39_10[6] = { 0xCE, 0xBD, 0xCE, 0xB9, 0xCF, 0x84 }; +static const symbol s_39_11[12] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_39_12[8] = { 0xCE, 0xB5, 0xCE, 0xBE, 0xCF, 0x89, 0xCE, 0xB4 }; +static const symbol s_39_13[4] = { 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_39_14[10] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_39_15[10] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_39_16[10] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xB4 }; +static const symbol s_39_17[6] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xB4 }; +static const symbol s_39_18[8] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xB4 }; +static const symbol s_39_19[12] = { 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xB4 }; +static const symbol s_39_20[10] = { 0xCF, 0x86, 0xCF, 0x85, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB4 }; +static const symbol s_39_21[4] = { 0xCE, 0xB7, 0xCE, 0xB8 }; +static const symbol s_39_22[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB7, 0xCE, 0xB8 }; +static const symbol s_39_23[6] = { 0xCE, 0xBE, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_39_24[8] = { 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_39_25[4] = { 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_39_26[14] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x87, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_39_27[14] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBB }; +static const symbol s_39_28[8] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB }; +static const symbol s_39_29[8] = { 0xCE, 0xB2, 0xCF, 0x81, 0xCF, 0x89, 0xCE, 0xBC }; +static const symbol s_39_30[8] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_39_31[8] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_39_32[8] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_39_33[12] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xBD }; +static const symbol s_39_34[14] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCE, 0xBB, 0xCE, 0xBD }; +static const symbol s_39_35[10] = { 0xCF, 0x86, 0xCE, 0xB9, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_39[36] = +{ +/* 0 */ { 8, s_39_0, -1, 1, 0}, +/* 1 */ { 6, s_39_1, -1, 1, 0}, +/* 2 */ { 12, s_39_2, -1, 1, 0}, +/* 3 */ { 8, s_39_3, -1, 1, 0}, +/* 4 */ { 8, s_39_4, -1, 1, 0}, +/* 5 */ { 6, s_39_5, -1, 1, 0}, +/* 6 */ { 6, s_39_6, -1, 1, 0}, +/* 7 */ { 8, s_39_7, -1, 1, 0}, +/* 8 */ { 8, s_39_8, -1, 1, 0}, +/* 9 */ { 14, s_39_9, -1, 1, 0}, +/* 10 */ { 6, s_39_10, -1, 1, 0}, +/* 11 */ { 12, s_39_11, -1, 1, 0}, +/* 12 */ { 8, s_39_12, -1, 1, 0}, +/* 13 */ { 4, s_39_13, -1, 1, 0}, +/* 14 */ { 10, s_39_14, 13, 1, 0}, +/* 15 */ { 10, s_39_15, 13, 1, 0}, +/* 16 */ { 10, s_39_16, -1, 1, 0}, +/* 17 */ { 6, s_39_17, -1, 1, 0}, +/* 18 */ { 8, s_39_18, -1, 1, 0}, +/* 19 */ { 12, s_39_19, -1, 1, 0}, +/* 20 */ { 10, s_39_20, -1, 1, 0}, +/* 21 */ { 4, s_39_21, -1, 1, 0}, +/* 22 */ { 8, s_39_22, 21, 1, 0}, +/* 23 */ { 6, s_39_23, -1, 1, 0}, +/* 24 */ { 8, s_39_24, -1, 1, 0}, +/* 25 */ { 4, s_39_25, -1, 1, 0}, +/* 26 */ { 14, s_39_26, 25, 1, 0}, +/* 27 */ { 14, s_39_27, -1, 1, 0}, +/* 28 */ { 8, s_39_28, -1, 1, 0}, +/* 29 */ { 8, s_39_29, -1, 1, 0}, +/* 30 */ { 8, s_39_30, -1, 1, 0}, +/* 31 */ { 8, s_39_31, -1, 1, 0}, +/* 32 */ { 8, s_39_32, -1, 1, 0}, +/* 33 */ { 12, s_39_33, -1, 1, 0}, +/* 34 */ { 14, s_39_34, -1, 1, 0}, +/* 35 */ { 10, s_39_35, -1, 1, 0} +}; + +static const symbol s_40_0[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_40_1[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_40_2[10] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_40_3[10] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_40_4[14] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; + +static const struct among a_40[5] = +{ +/* 0 */ { 12, s_40_0, -1, 1, 0}, +/* 1 */ { 10, s_40_1, -1, 1, 0}, +/* 2 */ { 10, s_40_2, -1, 1, 0}, +/* 3 */ { 10, s_40_3, -1, 1, 0}, +/* 4 */ { 14, s_40_4, 3, 1, 0} +}; + +static const symbol s_41_0[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_41_1[8] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xBA, 0xCF, 0x81 }; +static const symbol s_41_2[10] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_41_3[6] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x84 }; +static const symbol s_41_4[2] = { 0xCF, 0x87 }; +static const symbol s_41_5[6] = { 0xCF, 0x83, 0xCE, 0xB9, 0xCF, 0x87 }; +static const symbol s_41_6[8] = { 0xCE, 0xB2, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB2 }; +static const symbol s_41_7[6] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xB8 }; +static const symbol s_41_8[6] = { 0xCE, 0xBE, 0xCE, 0xB5, 0xCE, 0xB8 }; +static const symbol s_41_9[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xB8 }; +static const symbol s_41_10[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBA }; +static const symbol s_41_11[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; + +static const struct among a_41[12] = +{ +/* 0 */ { 8, s_41_0, -1, 1, 0}, +/* 1 */ { 8, s_41_1, -1, 1, 0}, +/* 2 */ { 10, s_41_2, -1, 1, 0}, +/* 3 */ { 6, s_41_3, -1, 1, 0}, +/* 4 */ { 2, s_41_4, -1, 1, 0}, +/* 5 */ { 6, s_41_5, 4, 1, 0}, +/* 6 */ { 8, s_41_6, -1, 1, 0}, +/* 7 */ { 6, s_41_7, -1, 1, 0}, +/* 8 */ { 6, s_41_8, -1, 1, 0}, +/* 9 */ { 8, s_41_9, -1, 1, 0}, +/* 10 */ { 8, s_41_10, -1, 1, 0}, +/* 11 */ { 6, s_41_11, -1, 1, 0} +}; + +static const symbol s_42_0[4] = { 0xCF, 0x84, 0xCF, 0x81 }; +static const symbol s_42_1[4] = { 0xCF, 0x84, 0xCF, 0x83 }; + +static const struct among a_42[2] = +{ +/* 0 */ { 4, s_42_0, -1, 1, 0}, +/* 1 */ { 4, s_42_1, -1, 1, 0} +}; + +static const symbol s_43_0[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_1[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_2[14] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_3[16] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_4[12] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_5[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_6[10] = { 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_7[12] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_8[10] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_9[10] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_43_10[14] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; + +static const struct among a_43[11] = +{ +/* 0 */ { 12, s_43_0, -1, 1, 0}, +/* 1 */ { 10, s_43_1, -1, 1, 0}, +/* 2 */ { 14, s_43_2, -1, 1, 0}, +/* 3 */ { 16, s_43_3, 2, 1, 0}, +/* 4 */ { 12, s_43_4, -1, 1, 0}, +/* 5 */ { 14, s_43_5, 4, 1, 0}, +/* 6 */ { 10, s_43_6, -1, 1, 0}, +/* 7 */ { 12, s_43_7, 6, 1, 0}, +/* 8 */ { 10, s_43_8, -1, 1, 0}, +/* 9 */ { 10, s_43_9, -1, 1, 0}, +/* 10 */ { 14, s_43_10, 9, 1, 0} +}; + +static const symbol s_44_0[2] = { 0xCF, 0x80 }; +static const symbol s_44_1[4] = { 0xCF, 0x83, 0xCF, 0x80 }; +static const symbol s_44_2[14] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xB4, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_44_3[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_44_4[18] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB4, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_44_5[8] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_44_6[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_44_7[12] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_44_8[12] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x81 }; +static const symbol s_44_9[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_44_10[4] = { 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_44_11[10] = { 0xCE, 0xB2, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_44_12[6] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_44_13[12] = { 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB8, 0xCE, 0xB7, 0xCF, 0x81 }; +static const symbol s_44_14[12] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_44_15[2] = { 0xCF, 0x83 }; +static const symbol s_44_16[16] = { 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_44_17[6] = { 0xCE, 0xB8, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_44_18[6] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_44_19[10] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_44_20[8] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_44_21[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_44_22[8] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_44_23[14] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBB, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_44_24[6] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x84 }; +static const symbol s_44_25[12] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x81, 0xCE, 0xB9, 0xCF, 0x84 }; +static const symbol s_44_26[10] = { 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB, 0xCF, 0x84 }; +static const symbol s_44_27[8] = { 0xCE, 0xB6, 0xCF, 0x89, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_44_28[10] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xB9, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_44_29[2] = { 0xCF, 0x86 }; +static const symbol s_44_30[14] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x86 }; +static const symbol s_44_31[14] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xB9, 0xCE, 0xBB, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x86 }; +static const symbol s_44_32[6] = { 0xCE, 0xBF, 0xCF, 0x81, 0xCF, 0x86 }; +static const symbol s_44_33[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x86 }; +static const symbol s_44_34[8] = { 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x86 }; +static const symbol s_44_35[16] = { 0xCF, 0x86, 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x86 }; +static const symbol s_44_36[10] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB7, 0xCF, 0x86 }; +static const symbol s_44_37[12] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB7, 0xCF, 0x86 }; +static const symbol s_44_38[2] = { 0xCF, 0x87 }; +static const symbol s_44_39[14] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_40[8] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_41[12] = { 0xCE, 0xB2, 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_42[22] = { 0xCE, 0xBC, 0xCE, 0xB9, 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xB2, 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_43[22] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB2, 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_44[22] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBD, 0xCE, 0xBF, 0xCE, 0xB2, 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB7, 0xCF, 0x87 }; +static const symbol s_44_45[6] = { 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x87 }; +static const symbol s_44_46[6] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB2 }; +static const symbol s_44_47[8] = { 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB2 }; +static const symbol s_44_48[14] = { 0xCF, 0x88, 0xCE, 0xB7, 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB2 }; +static const symbol s_44_49[6] = { 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB2 }; +static const symbol s_44_50[8] = { 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB2 }; +static const symbol s_44_51[16] = { 0xCE, 0xBE, 0xCE, 0xB7, 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB2 }; +static const symbol s_44_52[2] = { 0xCE, 0xB3 }; +static const symbol s_44_53[10] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x81, 0xCE, 0xB3 }; +static const symbol s_44_54[10] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x81, 0xCE, 0xB3 }; +static const symbol s_44_55[4] = { 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_44_56[8] = { 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_44_57[8] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_44_58[10] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB9, 0xCE, 0xB3, 0xCE, 0xB3 }; +static const symbol s_44_59[12] = { 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB9, 0xCE, 0xB3, 0xCE, 0xB3 }; +static const symbol s_44_60[10] = { 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB9, 0xCE, 0xB3, 0xCE, 0xB3 }; +static const symbol s_44_61[8] = { 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCE, 0xB3 }; +static const symbol s_44_62[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB7, 0xCE, 0xB3 }; +static const symbol s_44_63[6] = { 0xCF, 0x83, 0xCE, 0xB9, 0xCE, 0xB3 }; +static const symbol s_44_64[14] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB6 }; +static const symbol s_44_65[2] = { 0xCE, 0xB8 }; +static const symbol s_44_66[12] = { 0xCE, 0xBC, 0xCF, 0x89, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xB8 }; +static const symbol s_44_67[6] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xB8 }; +static const symbol s_44_68[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xB8 }; +static const symbol s_44_69[8] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_44_70[12] = { 0xCE, 0xB2, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x87, 0xCF, 0x85, 0xCE, 0xBA }; +static const symbol s_44_71[6] = { 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xBA }; +static const symbol s_44_72[10] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBA }; +static const symbol s_44_73[4] = { 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_44_74[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_44_75[10] = { 0xCE, 0xB2, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB, 0xCE, 0xBA }; +static const symbol s_44_76[4] = { 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_44_77[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_44_78[12] = { 0xCF, 0x88, 0xCF, 0x85, 0xCF, 0x87, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_44_79[10] = { 0xCE, 0xBB, 0xCE, 0xB1, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_44_80[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_44_81[6] = { 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_44_82[14] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCE, 0xB8, 0xCF, 0x85, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_44_83[14] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_44_84[12] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_44_85[12] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_44_86[6] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_44_87[12] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x81, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xBB }; +static const symbol s_44_88[2] = { 0xCE, 0xBC }; +static const symbol s_44_89[14] = { 0xCE, 0xB4, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB4, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC }; +static const symbol s_44_90[10] = { 0xCE, 0xB2, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x87, 0xCE, 0xBC }; +static const symbol s_44_91[16] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xB4, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_44_92[16] = { 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB, 0xCE, 0xBC }; +static const symbol s_44_93[2] = { 0xCE, 0xBD }; +static const symbol s_44_94[16] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB9, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD }; + +static const struct among a_44[95] = +{ +/* 0 */ { 2, s_44_0, -1, 1, 0}, +/* 1 */ { 4, s_44_1, 0, 1, 0}, +/* 2 */ { 14, s_44_2, 0, 1, 0}, +/* 3 */ { 8, s_44_3, 0, 1, 0}, +/* 4 */ { 18, s_44_4, 0, 1, 0}, +/* 5 */ { 8, s_44_5, 0, 1, 0}, +/* 6 */ { 6, s_44_6, 0, 1, 0}, +/* 7 */ { 12, s_44_7, 6, 1, 0}, +/* 8 */ { 12, s_44_8, -1, 1, 0}, +/* 9 */ { 6, s_44_9, -1, 1, 0}, +/* 10 */ { 4, s_44_10, -1, 1, 0}, +/* 11 */ { 10, s_44_11, 10, 1, 0}, +/* 12 */ { 6, s_44_12, 10, 1, 0}, +/* 13 */ { 12, s_44_13, -1, 1, 0}, +/* 14 */ { 12, s_44_14, -1, 1, 0}, +/* 15 */ { 2, s_44_15, -1, 1, 0}, +/* 16 */ { 16, s_44_16, 15, 1, 0}, +/* 17 */ { 6, s_44_17, 15, 1, 0}, +/* 18 */ { 6, s_44_18, 15, 1, 0}, +/* 19 */ { 10, s_44_19, 15, 1, 0}, +/* 20 */ { 8, s_44_20, -1, 1, 0}, +/* 21 */ { 8, s_44_21, -1, 1, 0}, +/* 22 */ { 8, s_44_22, -1, 1, 0}, +/* 23 */ { 14, s_44_23, -1, 1, 0}, +/* 24 */ { 6, s_44_24, -1, 1, 0}, +/* 25 */ { 12, s_44_25, -1, 1, 0}, +/* 26 */ { 10, s_44_26, -1, 1, 0}, +/* 27 */ { 8, s_44_27, -1, 1, 0}, +/* 28 */ { 10, s_44_28, -1, 1, 0}, +/* 29 */ { 2, s_44_29, -1, 1, 0}, +/* 30 */ { 14, s_44_30, 29, 1, 0}, +/* 31 */ { 14, s_44_31, 29, 1, 0}, +/* 32 */ { 6, s_44_32, 29, 1, 0}, +/* 33 */ { 8, s_44_33, 29, 1, 0}, +/* 34 */ { 8, s_44_34, 29, 1, 0}, +/* 35 */ { 16, s_44_35, 34, 1, 0}, +/* 36 */ { 10, s_44_36, 29, 1, 0}, +/* 37 */ { 12, s_44_37, 36, 1, 0}, +/* 38 */ { 2, s_44_38, -1, 1, 0}, +/* 39 */ { 14, s_44_39, 38, 1, 0}, +/* 40 */ { 8, s_44_40, 38, 1, 0}, +/* 41 */ { 12, s_44_41, 38, 1, 0}, +/* 42 */ { 22, s_44_42, 41, 1, 0}, +/* 43 */ { 22, s_44_43, 41, 1, 0}, +/* 44 */ { 22, s_44_44, 41, 1, 0}, +/* 45 */ { 6, s_44_45, 38, 1, 0}, +/* 46 */ { 6, s_44_46, -1, 1, 0}, +/* 47 */ { 8, s_44_47, 46, 1, 0}, +/* 48 */ { 14, s_44_48, 46, 1, 0}, +/* 49 */ { 6, s_44_49, -1, 1, 0}, +/* 50 */ { 8, s_44_50, 49, 1, 0}, +/* 51 */ { 16, s_44_51, 50, 1, 0}, +/* 52 */ { 2, s_44_52, -1, 1, 0}, +/* 53 */ { 10, s_44_53, 52, 1, 0}, +/* 54 */ { 10, s_44_54, 52, 1, 0}, +/* 55 */ { 4, s_44_55, 52, 1, 0}, +/* 56 */ { 8, s_44_56, 55, 1, 0}, +/* 57 */ { 8, s_44_57, 55, 1, 0}, +/* 58 */ { 10, s_44_58, 52, 1, 0}, +/* 59 */ { 12, s_44_59, 58, 1, 0}, +/* 60 */ { 10, s_44_60, 52, 1, 0}, +/* 61 */ { 8, s_44_61, 52, 1, 0}, +/* 62 */ { 8, s_44_62, 52, 1, 0}, +/* 63 */ { 6, s_44_63, 52, 1, 0}, +/* 64 */ { 14, s_44_64, -1, 1, 0}, +/* 65 */ { 2, s_44_65, -1, 1, 0}, +/* 66 */ { 12, s_44_66, 65, 1, 0}, +/* 67 */ { 6, s_44_67, 65, 1, 0}, +/* 68 */ { 8, s_44_68, 67, 1, 0}, +/* 69 */ { 8, s_44_69, -1, 1, 0}, +/* 70 */ { 12, s_44_70, -1, 1, 0}, +/* 71 */ { 6, s_44_71, -1, 1, 0}, +/* 72 */ { 10, s_44_72, -1, 1, 0}, +/* 73 */ { 4, s_44_73, -1, 1, 0}, +/* 74 */ { 8, s_44_74, 73, 1, 0}, +/* 75 */ { 10, s_44_75, -1, 1, 0}, +/* 76 */ { 4, s_44_76, -1, 1, 0}, +/* 77 */ { 8, s_44_77, 76, 1, 0}, +/* 78 */ { 12, s_44_78, 76, 1, 0}, +/* 79 */ { 10, s_44_79, 76, 1, 0}, +/* 80 */ { 6, s_44_80, -1, 1, 0}, +/* 81 */ { 6, s_44_81, -1, 1, 0}, +/* 82 */ { 14, s_44_82, 81, 1, 0}, +/* 83 */ { 14, s_44_83, 81, 1, 0}, +/* 84 */ { 12, s_44_84, 81, 1, 0}, +/* 85 */ { 12, s_44_85, -1, 1, 0}, +/* 86 */ { 6, s_44_86, -1, 1, 0}, +/* 87 */ { 12, s_44_87, -1, 1, 0}, +/* 88 */ { 2, s_44_88, -1, 1, 0}, +/* 89 */ { 14, s_44_89, 88, 1, 0}, +/* 90 */ { 10, s_44_90, 88, 1, 0}, +/* 91 */ { 16, s_44_91, 88, 1, 0}, +/* 92 */ { 16, s_44_92, 88, 1, 0}, +/* 93 */ { 2, s_44_93, -1, 1, 0}, +/* 94 */ { 16, s_44_94, 93, 1, 0} +}; + +static const symbol s_45_0[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5 }; + +static const struct among a_45[1] = +{ +/* 0 */ { 10, s_45_0, -1, 1, 0} +}; + +static const symbol s_46_0[6] = { 0xCF, 0x80, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_46_1[6] = { 0xCE, 0xB5, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_46_2[6] = { 0xCF, 0x87, 0xCF, 0x89, 0xCF, 0x81 }; +static const symbol s_46_3[6] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_46_4[4] = { 0xCE, 0xB2, 0xCF, 0x81 }; +static const symbol s_46_5[6] = { 0xCE, 0xB1, 0xCE, 0xB9, 0xCF, 0x81 }; +static const symbol s_46_6[6] = { 0xCF, 0x86, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_46_7[6] = { 0xCE, 0xBD, 0xCE, 0xB5, 0xCF, 0x84 }; +static const symbol s_46_8[4] = { 0xCF, 0x83, 0xCF, 0x87 }; +static const symbol s_46_9[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB4 }; +static const symbol s_46_10[6] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xB4 }; +static const symbol s_46_11[4] = { 0xCE, 0xBF, 0xCE, 0xB4 }; +static const symbol s_46_12[10] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB8 }; +static const symbol s_46_13[4] = { 0xCF, 0x83, 0xCE, 0xB8 }; +static const symbol s_46_14[6] = { 0xCE, 0xB5, 0xCF, 0x85, 0xCE, 0xB8 }; +static const symbol s_46_15[6] = { 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_46_16[6] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_46_17[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_46_18[6] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_46_19[6] = { 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xB8 }; +static const symbol s_46_20[6] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xB8 }; +static const symbol s_46_21[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB8 }; +static const symbol s_46_22[6] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xB8 }; +static const symbol s_46_23[6] = { 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xB8 }; +static const symbol s_46_24[6] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBA }; +static const symbol s_46_25[8] = { 0xCF, 0x89, 0xCF, 0x86, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_46_26[6] = { 0xCE, 0xB2, 0xCE, 0xBF, 0xCE, 0xBB }; +static const symbol s_46_27[6] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_46_28[6] = { 0xCE, 0xB1, 0xCE, 0xB9, 0xCE, 0xBD }; +static const symbol s_46_29[6] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBD }; +static const symbol s_46_30[6] = { 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_46[31] = +{ +/* 0 */ { 6, s_46_0, -1, 1, 0}, +/* 1 */ { 6, s_46_1, -1, 1, 0}, +/* 2 */ { 6, s_46_2, -1, 1, 0}, +/* 3 */ { 6, s_46_3, -1, 1, 0}, +/* 4 */ { 4, s_46_4, -1, 1, 0}, +/* 5 */ { 6, s_46_5, -1, 1, 0}, +/* 6 */ { 6, s_46_6, -1, 1, 0}, +/* 7 */ { 6, s_46_7, -1, 1, 0}, +/* 8 */ { 4, s_46_8, -1, 1, 0}, +/* 9 */ { 8, s_46_9, -1, 1, 0}, +/* 10 */ { 6, s_46_10, -1, 1, 0}, +/* 11 */ { 4, s_46_11, -1, 1, 0}, +/* 12 */ { 10, s_46_12, -1, 1, 0}, +/* 13 */ { 4, s_46_13, -1, 1, 0}, +/* 14 */ { 6, s_46_14, -1, 1, 0}, +/* 15 */ { 6, s_46_15, -1, 1, 0}, +/* 16 */ { 6, s_46_16, -1, 1, 0}, +/* 17 */ { 8, s_46_17, -1, 1, 0}, +/* 18 */ { 6, s_46_18, -1, 1, 0}, +/* 19 */ { 6, s_46_19, -1, 1, 0}, +/* 20 */ { 6, s_46_20, -1, 1, 0}, +/* 21 */ { 8, s_46_21, -1, 1, 0}, +/* 22 */ { 6, s_46_22, -1, 1, 0}, +/* 23 */ { 6, s_46_23, -1, 1, 0}, +/* 24 */ { 6, s_46_24, -1, 1, 0}, +/* 25 */ { 8, s_46_25, -1, 1, 0}, +/* 26 */ { 6, s_46_26, -1, 1, 0}, +/* 27 */ { 6, s_46_27, -1, 1, 0}, +/* 28 */ { 6, s_46_28, -1, 1, 0}, +/* 29 */ { 6, s_46_29, -1, 1, 0}, +/* 30 */ { 6, s_46_30, -1, 1, 0} +}; + +static const symbol s_47_0[8] = { 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x81, 0xCF, 0x80 }; +static const symbol s_47_1[6] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_47_2[8] = { 0xCE, 0xB8, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x81 }; +static const symbol s_47_3[6] = { 0xCE, 0xBD, 0xCF, 0x84, 0xCF, 0x81 }; +static const symbol s_47_4[8] = { 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_47_5[8] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_47_6[6] = { 0xCE, 0xB1, 0xCE, 0xB2, 0xCF, 0x81 }; +static const symbol s_47_7[8] = { 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_47_8[2] = { 0xCF, 0x85 }; +static const symbol s_47_9[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCF, 0x81, 0xCF, 0x86 }; +static const symbol s_47_10[6] = { 0xCE, 0xBD, 0xCE, 0xB9, 0xCF, 0x86 }; +static const symbol s_47_11[6] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_47_12[2] = { 0xCE, 0xB4 }; +static const symbol s_47_13[4] = { 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_47_14[2] = { 0xCE, 0xB8 }; +static const symbol s_47_15[4] = { 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_47_16[4] = { 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_47_17[6] = { 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xBA }; +static const symbol s_47_18[6] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_47_19[14] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_47_20[8] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_47_21[4] = { 0xCE, 0xB5, 0xCE, 0xBC }; +static const symbol s_47_22[4] = { 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_47_23[6] = { 0xCE, 0xB2, 0xCE, 0xB5, 0xCE, 0xBD }; +static const symbol s_47_24[10] = { 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_47[25] = +{ +/* 0 */ { 8, s_47_0, -1, 1, 0}, +/* 1 */ { 6, s_47_1, -1, 1, 0}, +/* 2 */ { 8, s_47_2, -1, 1, 0}, +/* 3 */ { 6, s_47_3, -1, 1, 0}, +/* 4 */ { 8, s_47_4, -1, 1, 0}, +/* 5 */ { 8, s_47_5, -1, 1, 0}, +/* 6 */ { 6, s_47_6, -1, 1, 0}, +/* 7 */ { 8, s_47_7, -1, 1, 0}, +/* 8 */ { 2, s_47_8, -1, 1, 0}, +/* 9 */ { 8, s_47_9, -1, 1, 0}, +/* 10 */ { 6, s_47_10, -1, 1, 0}, +/* 11 */ { 6, s_47_11, -1, 1, 0}, +/* 12 */ { 2, s_47_12, -1, 1, 0}, +/* 13 */ { 4, s_47_13, 12, 1, 0}, +/* 14 */ { 2, s_47_14, -1, 1, 0}, +/* 15 */ { 4, s_47_15, 14, 1, 0}, +/* 16 */ { 4, s_47_16, -1, 1, 0}, +/* 17 */ { 6, s_47_17, -1, 1, 0}, +/* 18 */ { 6, s_47_18, -1, 1, 0}, +/* 19 */ { 14, s_47_19, -1, 1, 0}, +/* 20 */ { 8, s_47_20, -1, 1, 0}, +/* 21 */ { 4, s_47_21, -1, 1, 0}, +/* 22 */ { 4, s_47_22, -1, 1, 0}, +/* 23 */ { 6, s_47_23, -1, 1, 0}, +/* 24 */ { 10, s_47_24, -1, 1, 0} +}; + +static const symbol s_48_0[10] = { 0xCF, 0x89, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_48_1[10] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x83 }; + +static const struct among a_48[2] = +{ +/* 0 */ { 10, s_48_0, -1, 1, 0}, +/* 1 */ { 10, s_48_1, -1, 1, 0} +}; + +static const symbol s_49_0[12] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_49_1[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; + +static const struct among a_49[2] = +{ +/* 0 */ { 12, s_49_0, -1, 1, 0}, +/* 1 */ { 14, s_49_1, 0, 1, 0} +}; + +static const symbol s_50_0[2] = { 0xCF, 0x80 }; +static const symbol s_50_1[4] = { 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_50_2[12] = { 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x80 }; +static const symbol s_50_3[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_50_4[10] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_50_5[14] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x86 }; + +static const struct among a_50[6] = +{ +/* 0 */ { 2, s_50_0, -1, 1, 0}, +/* 1 */ { 4, s_50_1, 0, 1, 0}, +/* 2 */ { 12, s_50_2, 1, 1, 0}, +/* 3 */ { 8, s_50_3, 0, 1, 0}, +/* 4 */ { 10, s_50_4, 3, 1, 0}, +/* 5 */ { 14, s_50_5, -1, 1, 0} +}; + +static const symbol s_51_0[4] = { 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_51_1[6] = { 0xCE, 0xBD, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_51_2[2] = { 0xCE, 0xB6 }; +static const symbol s_51_3[4] = { 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_51_4[14] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_51_5[10] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCF, 0x84, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_51_6[2] = { 0xCE, 0xBC }; +static const symbol s_51_7[2] = { 0xCE, 0xBE }; +static const symbol s_51_8[6] = { 0xCF, 0x80, 0xCF, 0x81, 0xCE, 0xBF }; + +static const struct among a_51[9] = +{ +/* 0 */ { 4, s_51_0, -1, 1, 0}, +/* 1 */ { 6, s_51_1, -1, 1, 0}, +/* 2 */ { 2, s_51_2, -1, 1, 0}, +/* 3 */ { 4, s_51_3, -1, 1, 0}, +/* 4 */ { 14, s_51_4, 3, 1, 0}, +/* 5 */ { 10, s_51_5, -1, 1, 0}, +/* 6 */ { 2, s_51_6, -1, 1, 0}, +/* 7 */ { 2, s_51_7, -1, 1, 0}, +/* 8 */ { 6, s_51_8, -1, 1, 0} +}; + +static const symbol s_52_0[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_52_1[10] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1 }; +static const symbol s_52_2[10] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5 }; + +static const struct among a_52[3] = +{ +/* 0 */ { 12, s_52_0, -1, 1, 0}, +/* 1 */ { 10, s_52_1, -1, 1, 0}, +/* 2 */ { 10, s_52_2, -1, 1, 0} +}; + +static const symbol s_53_0[4] = { 0xCF, 0x83, 0xCF, 0x86 }; +static const symbol s_53_1[8] = { 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB8 }; +static const symbol s_53_2[6] = { 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xB8 }; +static const symbol s_53_3[4] = { 0xCE, 0xBF, 0xCE, 0xB8 }; +static const symbol s_53_4[10] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB }; +static const symbol s_53_5[8] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCF, 0x89, 0xCE, 0xBB }; + +static const struct among a_53[6] = +{ +/* 0 */ { 4, s_53_0, -1, 1, 0}, +/* 1 */ { 8, s_53_1, -1, 1, 0}, +/* 2 */ { 6, s_53_2, -1, 1, 0}, +/* 3 */ { 4, s_53_3, -1, 1, 0}, +/* 4 */ { 10, s_53_4, -1, 1, 0}, +/* 5 */ { 8, s_53_5, -1, 1, 0} +}; + +static const symbol s_54_0[2] = { 0xCE, 0xB8 }; +static const symbol s_54_1[10] = { 0xCF, 0x80, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB8 }; +static const symbol s_54_2[18] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_54_3[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCE, 0xB8 }; +static const symbol s_54_4[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB8 }; + +static const struct among a_54[5] = +{ +/* 0 */ { 2, s_54_0, -1, 1, 0}, +/* 1 */ { 10, s_54_1, 0, 1, 0}, +/* 2 */ { 18, s_54_2, 0, 1, 0}, +/* 3 */ { 8, s_54_3, 0, 1, 0}, +/* 4 */ { 8, s_54_4, 0, 1, 0} +}; + +static const symbol s_55_0[8] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_55_1[6] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1 }; +static const symbol s_55_2[6] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB5 }; + +static const struct among a_55[3] = +{ +/* 0 */ { 8, s_55_0, -1, 1, 0}, +/* 1 */ { 6, s_55_1, -1, 1, 0}, +/* 2 */ { 6, s_55_2, -1, 1, 0} +}; + +static const symbol s_56_0[8] = { 0xCE, 0xB2, 0xCE, 0xBB, 0xCE, 0xB5, 0xCF, 0x80 }; +static const symbol s_56_1[10] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xB4, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_56_2[8] = { 0xCF, 0x80, 0xCF, 0x81, 0xCF, 0x89, 0xCF, 0x84 }; +static const symbol s_56_3[10] = { 0xCE, 0xBA, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_56_4[12] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x87 }; +static const symbol s_56_5[6] = { 0xCE, 0xBB, 0xCE, 0xB1, 0xCF, 0x87 }; +static const symbol s_56_6[6] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_56_7[6] = { 0xCE, 0xBB, 0xCE, 0xB7, 0xCE, 0xB3 }; +static const symbol s_56_8[8] = { 0xCF, 0x86, 0xCF, 0x81, 0xCF, 0x85, 0xCE, 0xB4 }; +static const symbol s_56_9[12] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB9, 0xCE, 0xBB }; +static const symbol s_56_10[8] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBB }; +static const symbol s_56_11[4] = { 0xCE, 0xBF, 0xCE, 0xBC }; + +static const struct among a_56[12] = +{ +/* 0 */ { 8, s_56_0, -1, 1, 0}, +/* 1 */ { 10, s_56_1, -1, 1, 0}, +/* 2 */ { 8, s_56_2, -1, 1, 0}, +/* 3 */ { 10, s_56_3, -1, 1, 0}, +/* 4 */ { 12, s_56_4, -1, 1, 0}, +/* 5 */ { 6, s_56_5, -1, 1, 0}, +/* 6 */ { 6, s_56_6, -1, 1, 0}, +/* 7 */ { 6, s_56_7, -1, 1, 0}, +/* 8 */ { 8, s_56_8, -1, 1, 0}, +/* 9 */ { 12, s_56_9, -1, 1, 0}, +/* 10 */ { 8, s_56_10, -1, 1, 0}, +/* 11 */ { 4, s_56_11, -1, 1, 0} +}; + +static const symbol s_57_0[10] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB9, 0xCF, 0x80 }; +static const symbol s_57_1[2] = { 0xCF, 0x81 }; +static const symbol s_57_2[10] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x81 }; +static const symbol s_57_3[16] = { 0xCE, 0xB5, 0xCE, 0xBD, 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x86, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_57_4[6] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_57_5[14] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB5, 0xCF, 0x85 }; +static const symbol s_57_6[16] = { 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x85, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB5, 0xCF, 0x85 }; +static const symbol s_57_7[6] = { 0xCE, 0xBB, 0xCE, 0xB5, 0xCF, 0x87 }; +static const symbol s_57_8[6] = { 0xCF, 0x84, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_57_9[6] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_57_10[6] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xB4 }; +static const symbol s_57_11[12] = { 0xCE, 0xBB, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x80, 0xCE, 0xB9, 0xCE, 0xB4 }; +static const symbol s_57_12[4] = { 0xCE, 0xB4, 0xCE, 0xB5 }; +static const symbol s_57_13[6] = { 0xCF, 0x80, 0xCE, 0xBB, 0xCE, 0xB5 }; +static const symbol s_57_14[10] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xB6 }; +static const symbol s_57_15[12] = { 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xB6 }; +static const symbol s_57_16[6] = { 0xCE, 0xB1, 0xCE, 0xB9, 0xCE, 0xB8 }; +static const symbol s_57_17[12] = { 0xCF, 0x86, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_57_18[6] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xBA }; +static const symbol s_57_19[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB7, 0xCE, 0xBA }; +static const symbol s_57_20[2] = { 0xCE, 0xBB }; +static const symbol s_57_21[2] = { 0xCE, 0xBC }; +static const symbol s_57_22[4] = { 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_57_23[8] = { 0xCE, 0xB2, 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBC }; +static const symbol s_57_24[14] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB5, 0xCE, 0xB9, 0xCE, 0xBD }; + +static const struct among a_57[25] = +{ +/* 0 */ { 10, s_57_0, -1, 1, 0}, +/* 1 */ { 2, s_57_1, -1, 1, 0}, +/* 2 */ { 10, s_57_2, 1, 1, 0}, +/* 3 */ { 16, s_57_3, 1, 1, 0}, +/* 4 */ { 6, s_57_4, -1, 1, 0}, +/* 5 */ { 14, s_57_5, -1, 1, 0}, +/* 6 */ { 16, s_57_6, -1, 1, 0}, +/* 7 */ { 6, s_57_7, -1, 1, 0}, +/* 8 */ { 6, s_57_8, -1, 1, 0}, +/* 9 */ { 6, s_57_9, -1, 1, 0}, +/* 10 */ { 6, s_57_10, -1, 1, 0}, +/* 11 */ { 12, s_57_11, -1, 1, 0}, +/* 12 */ { 4, s_57_12, -1, 1, 0}, +/* 13 */ { 6, s_57_13, -1, 1, 0}, +/* 14 */ { 10, s_57_14, -1, 1, 0}, +/* 15 */ { 12, s_57_15, -1, 1, 0}, +/* 16 */ { 6, s_57_16, -1, 1, 0}, +/* 17 */ { 12, s_57_17, -1, 1, 0}, +/* 18 */ { 6, s_57_18, -1, 1, 0}, +/* 19 */ { 8, s_57_19, -1, 1, 0}, +/* 20 */ { 2, s_57_20, -1, 1, 0}, +/* 21 */ { 2, s_57_21, -1, 1, 0}, +/* 22 */ { 4, s_57_22, 21, 1, 0}, +/* 23 */ { 8, s_57_23, 21, 1, 0}, +/* 24 */ { 14, s_57_24, -1, 1, 0} +}; + +static const symbol s_58_0[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_58_1[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_58_2[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB5 }; + +static const struct among a_58[3] = +{ +/* 0 */ { 10, s_58_0, -1, 1, 0}, +/* 1 */ { 8, s_58_1, -1, 1, 0}, +/* 2 */ { 8, s_58_2, -1, 1, 0} +}; + +static const symbol s_59_0[6] = { 0xCF, 0x88, 0xCE, 0xBF, 0xCF, 0x86 }; +static const symbol s_59_1[12] = { 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x85, 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x87 }; + +static const struct among a_59[2] = +{ +/* 0 */ { 6, s_59_0, -1, -1, 0}, +/* 1 */ { 12, s_59_1, -1, -1, 0} +}; + +static const symbol s_60_0[4] = { 0xCF, 0x81, 0xCF, 0x80 }; +static const symbol s_60_1[4] = { 0xCF, 0x80, 0xCF, 0x81 }; +static const symbol s_60_2[4] = { 0xCF, 0x86, 0xCF, 0x81 }; +static const symbol s_60_3[8] = { 0xCF, 0x87, 0xCE, 0xBF, 0xCF, 0x81, 0xCF, 0x84 }; +static const symbol s_60_4[4] = { 0xCF, 0x83, 0xCF, 0x86 }; +static const symbol s_60_5[4] = { 0xCE, 0xBF, 0xCF, 0x86 }; +static const symbol s_60_6[6] = { 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x87 }; +static const symbol s_60_7[6] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCE, 0xBB }; +static const symbol s_60_8[4] = { 0xCE, 0xBB, 0xCE, 0xBB }; +static const symbol s_60_9[8] = { 0xCF, 0x83, 0xCE, 0xBC, 0xCE, 0xB7, 0xCE, 0xBD }; + +static const struct among a_60[10] = +{ +/* 0 */ { 4, s_60_0, -1, 1, 0}, +/* 1 */ { 4, s_60_1, -1, 1, 0}, +/* 2 */ { 4, s_60_2, -1, 1, 0}, +/* 3 */ { 8, s_60_3, -1, 1, 0}, +/* 4 */ { 4, s_60_4, -1, 1, 0}, +/* 5 */ { 4, s_60_5, -1, 1, 0}, +/* 6 */ { 6, s_60_6, -1, 1, 0}, +/* 7 */ { 6, s_60_7, -1, 1, 0}, +/* 8 */ { 4, s_60_8, -1, 1, 0}, +/* 9 */ { 8, s_60_9, -1, 1, 0} +}; + +static const symbol s_61_0[2] = { 0xCF, 0x80 }; +static const symbol s_61_1[6] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x80 }; +static const symbol s_61_2[8] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x85, 0xCF, 0x80 }; +static const symbol s_61_3[10] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x84, 0xCE, 0xB9, 0xCF, 0x80 }; +static const symbol s_61_4[8] = { 0xCE, 0xB1, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x80 }; +static const symbol s_61_5[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBC, 0xCF, 0x80 }; +static const symbol s_61_6[16] = { 0xCF, 0x80, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x89, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_7[14] = { 0xCF, 0x83, 0xCE, 0xB9, 0xCE, 0xB4, 0xCE, 0xB7, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_8[12] = { 0xCE, 0xB4, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_9[8] = { 0xCE, 0xBD, 0xCE, 0xB5, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_10[16] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xBF, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_11[8] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_61_12[2] = { 0xCF, 0x81 }; +static const symbol s_61_13[4] = { 0xCF, 0x84, 0xCF, 0x81 }; +static const symbol s_61_14[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x81 }; +static const symbol s_61_15[10] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_61_16[6] = { 0xCF, 0x87, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_61_17[8] = { 0xCE, 0xB1, 0xCF, 0x87, 0xCE, 0xB1, 0xCF, 0x81 }; +static const symbol s_61_18[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_61_19[2] = { 0xCF, 0x84 }; +static const symbol s_61_20[10] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x85, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_61_21[10] = { 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_61_22[10] = { 0xCF, 0x80, 0xCF, 0x81, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_61_23[12] = { 0xCE, 0xB1, 0xCE, 0xB9, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_61_24[8] = { 0xCE, 0xB4, 0xCE, 0xB9, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_61_25[8] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCE, 0xB9, 0xCF, 0x84 }; +static const symbol s_61_26[8] = { 0xCF, 0x83, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_61_27[8] = { 0xCF, 0x85, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x84 }; +static const symbol s_61_28[8] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBF, 0xCF, 0x84 }; +static const symbol s_61_29[8] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x84 }; +static const symbol s_61_30[10] = { 0xCE, 0xBD, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x84 }; +static const symbol s_61_31[6] = { 0xCE, 0xBD, 0xCE, 0xB1, 0xCF, 0x85 }; +static const symbol s_61_32[10] = { 0xCF, 0x80, 0xCE, 0xBF, 0xCE, 0xBB, 0xCF, 0x85, 0xCF, 0x86 }; +static const symbol s_61_33[4] = { 0xCE, 0xB1, 0xCF, 0x86 }; +static const symbol s_61_34[6] = { 0xCE, 0xBE, 0xCE, 0xB5, 0xCF, 0x86 }; +static const symbol s_61_35[8] = { 0xCE, 0xB1, 0xCE, 0xB4, 0xCE, 0xB7, 0xCF, 0x86 }; +static const symbol s_61_36[8] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBC, 0xCF, 0x86 }; +static const symbol s_61_37[12] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBB, 0xCE, 0xB9 }; +static const symbol s_61_38[2] = { 0xCE, 0xBB }; +static const symbol s_61_39[8] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xBB }; +static const symbol s_61_40[2] = { 0xCE, 0xBC }; +static const symbol s_61_41[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBB, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_61_42[4] = { 0xCE, 0xB5, 0xCE, 0xBD }; +static const symbol s_61_43[12] = { 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB2, 0xCE, 0xB5, 0xCE, 0xBD }; + +static const struct among a_61[44] = +{ +/* 0 */ { 2, s_61_0, -1, 1, 0}, +/* 1 */ { 6, s_61_1, 0, 1, 0}, +/* 2 */ { 8, s_61_2, 0, 1, 0}, +/* 3 */ { 10, s_61_3, 0, 1, 0}, +/* 4 */ { 8, s_61_4, 0, 1, 0}, +/* 5 */ { 8, s_61_5, 0, 1, 0}, +/* 6 */ { 16, s_61_6, 0, 1, 0}, +/* 7 */ { 14, s_61_7, 0, 1, 0}, +/* 8 */ { 12, s_61_8, 0, 1, 0}, +/* 9 */ { 8, s_61_9, 0, 1, 0}, +/* 10 */ { 16, s_61_10, 0, 1, 0}, +/* 11 */ { 8, s_61_11, 0, 1, 0}, +/* 12 */ { 2, s_61_12, -1, 1, 0}, +/* 13 */ { 4, s_61_13, 12, 1, 0}, +/* 14 */ { 6, s_61_14, 12, 1, 0}, +/* 15 */ { 10, s_61_15, 12, 1, 0}, +/* 16 */ { 6, s_61_16, 12, 1, 0}, +/* 17 */ { 8, s_61_17, 16, 1, 0}, +/* 18 */ { 8, s_61_18, 12, 1, 0}, +/* 19 */ { 2, s_61_19, -1, 1, 0}, +/* 20 */ { 10, s_61_20, 19, 1, 0}, +/* 21 */ { 10, s_61_21, 19, 1, 0}, +/* 22 */ { 10, s_61_22, 19, 1, 0}, +/* 23 */ { 12, s_61_23, 19, 1, 0}, +/* 24 */ { 8, s_61_24, 19, 1, 0}, +/* 25 */ { 8, s_61_25, 19, 1, 0}, +/* 26 */ { 8, s_61_26, 19, 1, 0}, +/* 27 */ { 8, s_61_27, 19, 1, 0}, +/* 28 */ { 8, s_61_28, 19, 1, 0}, +/* 29 */ { 8, s_61_29, 19, 1, 0}, +/* 30 */ { 10, s_61_30, 29, 1, 0}, +/* 31 */ { 6, s_61_31, -1, 1, 0}, +/* 32 */ { 10, s_61_32, -1, 1, 0}, +/* 33 */ { 4, s_61_33, -1, 1, 0}, +/* 34 */ { 6, s_61_34, -1, 1, 0}, +/* 35 */ { 8, s_61_35, -1, 1, 0}, +/* 36 */ { 8, s_61_36, -1, 1, 0}, +/* 37 */ { 12, s_61_37, -1, 1, 0}, +/* 38 */ { 2, s_61_38, -1, 1, 0}, +/* 39 */ { 8, s_61_39, 38, 1, 0}, +/* 40 */ { 2, s_61_40, -1, 1, 0}, +/* 41 */ { 10, s_61_41, 40, 1, 0}, +/* 42 */ { 4, s_61_42, -1, 1, 0}, +/* 43 */ { 12, s_61_43, 42, 1, 0} +}; + +static const symbol s_62_0[8] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_62_1[6] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1 }; +static const symbol s_62_2[6] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB5 }; + +static const struct among a_62[3] = +{ +/* 0 */ { 8, s_62_0, -1, 1, 0}, +/* 1 */ { 6, s_62_1, -1, 1, 0}, +/* 2 */ { 6, s_62_2, -1, 1, 0} +}; + +static const symbol s_63_0[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_63_1[6] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_63_2[6] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5 }; + +static const struct among a_63[3] = +{ +/* 0 */ { 8, s_63_0, -1, 1, 0}, +/* 1 */ { 6, s_63_1, -1, 1, 0}, +/* 2 */ { 6, s_63_2, -1, 1, 0} +}; + +static const symbol s_64_0[2] = { 0xCE, 0xBD }; +static const symbol s_64_1[10] = { 0xCE, 0xB5, 0xCF, 0x80, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_64_2[14] = { 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xB4, 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_64_3[12] = { 0xCF, 0x87, 0xCE, 0xB5, 0xCF, 0x81, 0xCF, 0x83, 0xCE, 0xBF, 0xCE, 0xBD }; +static const symbol s_64_4[14] = { 0xCE, 0xBC, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBF, 0xCE, 0xBD }; +static const symbol s_64_5[12] = { 0xCE, 0xB5, 0xCF, 0x81, 0xCE, 0xB7, 0xCE, 0xBC, 0xCE, 0xBF, 0xCE, 0xBD }; + +static const struct among a_64[6] = +{ +/* 0 */ { 2, s_64_0, -1, 1, 0}, +/* 1 */ { 10, s_64_1, 0, 1, 0}, +/* 2 */ { 14, s_64_2, 0, 1, 0}, +/* 3 */ { 12, s_64_3, 0, 1, 0}, +/* 4 */ { 14, s_64_4, 0, 1, 0}, +/* 5 */ { 12, s_64_5, 0, 1, 0} +}; + +static const symbol s_65_0[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; + +static const struct among a_65[1] = +{ +/* 0 */ { 8, s_65_0, -1, 1, 0} +}; + +static const symbol s_66_0[4] = { 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_66_1[10] = { 0xCE, 0xB4, 0xCF, 0x85, 0xCF, 0x83, 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_66_2[8] = { 0xCE, 0xB5, 0xCF, 0x85, 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_66_3[6] = { 0xCE, 0xB1, 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_66_4[14] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xB9, 0xCE, 0xBD, 0xCE, 0xBF, 0xCF, 0x87, 0xCF, 0x81 }; +static const symbol s_66_5[12] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xB9, 0xCE, 0xBC, 0xCF, 0x88 }; +static const symbol s_66_6[4] = { 0xCF, 0x83, 0xCE, 0xB2 }; +static const symbol s_66_7[6] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xB2 }; +static const symbol s_66_8[6] = { 0xCE, 0xB1, 0xCF, 0x80, 0xCE, 0xBB }; +static const symbol s_66_9[10] = { 0xCE, 0xB1, 0xCE, 0xB5, 0xCE, 0xB9, 0xCE, 0xBC, 0xCE, 0xBD }; + +static const struct among a_66[10] = +{ +/* 0 */ { 4, s_66_0, -1, 1, 0}, +/* 1 */ { 10, s_66_1, 0, 1, 0}, +/* 2 */ { 8, s_66_2, 0, 1, 0}, +/* 3 */ { 6, s_66_3, 0, 1, 0}, +/* 4 */ { 14, s_66_4, 0, 1, 0}, +/* 5 */ { 12, s_66_5, -1, 1, 0}, +/* 6 */ { 4, s_66_6, -1, 1, 0}, +/* 7 */ { 6, s_66_7, 6, 1, 0}, +/* 8 */ { 6, s_66_8, -1, 1, 0}, +/* 9 */ { 10, s_66_9, -1, 1, 0} +}; + +static const symbol s_67_0[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_67_1[12] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_67_2[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB5 }; + +static const struct among a_67[3] = +{ +/* 0 */ { 8, s_67_0, -1, 1, 0}, +/* 1 */ { 12, s_67_1, 0, 1, 0}, +/* 2 */ { 12, s_67_2, 0, 1, 0} +}; + +static const symbol s_68_0[2] = { 0xCF, 0x81 }; +static const symbol s_68_1[22] = { 0xCF, 0x83, 0xCF, 0x84, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_68_2[18] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_68_3[6] = { 0xCF, 0x83, 0xCF, 0x80, 0xCE, 0xB9 }; +static const symbol s_68_4[2] = { 0xCE, 0xBD }; +static const symbol s_68_5[8] = { 0xCE, 0xB5, 0xCE, 0xBE, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_68[6] = +{ +/* 0 */ { 2, s_68_0, -1, 1, 0}, +/* 1 */ { 22, s_68_1, -1, 1, 0}, +/* 2 */ { 18, s_68_2, -1, 1, 0}, +/* 3 */ { 6, s_68_3, -1, 1, 0}, +/* 4 */ { 2, s_68_4, -1, 1, 0}, +/* 5 */ { 8, s_68_5, 4, 1, 0} +}; + +static const symbol s_69_0[8] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_69_1[12] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_69_2[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB5 }; + +static const struct among a_69[3] = +{ +/* 0 */ { 8, s_69_0, -1, 1, 0}, +/* 1 */ { 12, s_69_1, 0, 1, 0}, +/* 2 */ { 12, s_69_2, 0, 1, 0} +}; + +static const symbol s_70_0[10] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_70_1[16] = { 0xCF, 0x80, 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_70_2[16] = { 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xBB, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_70_3[2] = { 0xCF, 0x86 }; +static const symbol s_70_4[2] = { 0xCF, 0x87 }; +static const symbol s_70_5[4] = { 0xCE, 0xB1, 0xCE, 0xB6 }; +static const symbol s_70_6[12] = { 0xCF, 0x89, 0xCF, 0x81, 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x80, 0xCE, 0xBB }; + +static const struct among a_70[7] = +{ +/* 0 */ { 10, s_70_0, -1, 1, 0}, +/* 1 */ { 16, s_70_1, 0, 1, 0}, +/* 2 */ { 16, s_70_2, -1, 1, 0}, +/* 3 */ { 2, s_70_3, -1, 1, 0}, +/* 4 */ { 2, s_70_4, -1, 1, 0}, +/* 5 */ { 4, s_70_5, -1, 1, 0}, +/* 6 */ { 12, s_70_6, -1, 1, 0} +}; + +static const symbol s_71_0[10] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_71_1[8] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1 }; +static const symbol s_71_2[10] = { 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x89, 0xCE, 0xBD }; + +static const struct among a_71[3] = +{ +/* 0 */ { 10, s_71_0, -1, 1, 0}, +/* 1 */ { 8, s_71_1, -1, 1, 0}, +/* 2 */ { 10, s_71_2, -1, 1, 0} +}; + +static const symbol s_72_0[4] = { 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_72_1[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_72_2[4] = { 0xCE, 0xB1, 0xCF, 0x83 }; +static const symbol s_72_3[4] = { 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_72_4[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_72_5[8] = { 0xCE, 0xB7, 0xCE, 0xB4, 0xCE, 0xB5, 0xCF, 0x83 }; +static const symbol s_72_6[4] = { 0xCE, 0xB7, 0xCF, 0x83 }; +static const symbol s_72_7[6] = { 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_72_8[10] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_72_9[4] = { 0xCE, 0xBF, 0xCF, 0x83 }; +static const symbol s_72_10[2] = { 0xCF, 0x85 }; +static const symbol s_72_11[4] = { 0xCE, 0xBF, 0xCF, 0x85 }; +static const symbol s_72_12[2] = { 0xCF, 0x89 }; +static const symbol s_72_13[6] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCF, 0x89 }; +static const symbol s_72_14[4] = { 0xCE, 0xB1, 0xCF, 0x89 }; +static const symbol s_72_15[6] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCF, 0x89 }; +static const symbol s_72_16[2] = { 0xCE, 0xB1 }; +static const symbol s_72_17[10] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB1 }; +static const symbol s_72_18[12] = { 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1 }; +static const symbol s_72_19[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1 }; +static const symbol s_72_20[12] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1 }; +static const symbol s_72_21[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCE, 0xB1 }; +static const symbol s_72_22[2] = { 0xCE, 0xB5 }; +static const symbol s_72_23[14] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_24[12] = { 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_25[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_26[14] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_27[16] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_28[14] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_29[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_30[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_31[10] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_32[10] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_33[14] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_34[8] = { 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_35[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB9, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_72_36[2] = { 0xCE, 0xB7 }; +static const symbol s_72_37[2] = { 0xCE, 0xB9 }; +static const symbol s_72_38[8] = { 0xCE, 0xB1, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_39[8] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_40[10] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_41[8] = { 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_42[8] = { 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_43[10] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_44[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_45[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_46[10] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_47[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_48[8] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_49[10] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_50[8] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCE, 0xB9 }; +static const symbol s_72_51[4] = { 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_72_52[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_72_53[6] = { 0xCE, 0xB1, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_72_54[8] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB9 }; +static const symbol s_72_55[4] = { 0xCE, 0xBF, 0xCE, 0xB9 }; +static const symbol s_72_56[6] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_57[10] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_58[10] = { 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_59[12] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_60[10] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_61[10] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_62[12] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_72_63[4] = { 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_72_64[8] = { 0xCE, 0xB7, 0xCE, 0xB4, 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_72_65[4] = { 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_66[10] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_67[16] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_68[18] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_69[8] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_70[14] = { 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_71[16] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x83, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_72[14] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_73[16] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_74[12] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_75[14] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_76[10] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_77[12] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_78[8] = { 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_79[10] = { 0xCE, 0xB9, 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_80[8] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_81[8] = { 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_82[12] = { 0xCE, 0xB7, 0xCE, 0xB8, 0xCE, 0xB7, 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_72_83[2] = { 0xCE, 0xBF }; + +static const struct among a_72[84] = +{ +/* 0 */ { 4, s_72_0, -1, 1, 0}, +/* 1 */ { 6, s_72_1, 0, 1, 0}, +/* 2 */ { 4, s_72_2, -1, 1, 0}, +/* 3 */ { 4, s_72_3, -1, 1, 0}, +/* 4 */ { 8, s_72_4, 3, 1, 0}, +/* 5 */ { 8, s_72_5, 3, 1, 0}, +/* 6 */ { 4, s_72_6, -1, 1, 0}, +/* 7 */ { 6, s_72_7, -1, 1, 0}, +/* 8 */ { 10, s_72_8, 7, 1, 0}, +/* 9 */ { 4, s_72_9, -1, 1, 0}, +/* 10 */ { 2, s_72_10, -1, 1, 0}, +/* 11 */ { 4, s_72_11, 10, 1, 0}, +/* 12 */ { 2, s_72_12, -1, 1, 0}, +/* 13 */ { 6, s_72_13, 12, 1, 0}, +/* 14 */ { 4, s_72_14, 12, 1, 0}, +/* 15 */ { 6, s_72_15, 12, 1, 0}, +/* 16 */ { 2, s_72_16, -1, 1, 0}, +/* 17 */ { 10, s_72_17, 16, 1, 0}, +/* 18 */ { 12, s_72_18, 16, 1, 0}, +/* 19 */ { 14, s_72_19, 18, 1, 0}, +/* 20 */ { 12, s_72_20, 16, 1, 0}, +/* 21 */ { 14, s_72_21, 20, 1, 0}, +/* 22 */ { 2, s_72_22, -1, 1, 0}, +/* 23 */ { 14, s_72_23, 22, 1, 0}, +/* 24 */ { 12, s_72_24, 22, 1, 0}, +/* 25 */ { 14, s_72_25, 24, 1, 0}, +/* 26 */ { 14, s_72_26, 22, 1, 0}, +/* 27 */ { 16, s_72_27, 26, 1, 0}, +/* 28 */ { 14, s_72_28, 22, 1, 0}, +/* 29 */ { 12, s_72_29, 22, 1, 0}, +/* 30 */ { 10, s_72_30, 22, 1, 0}, +/* 31 */ { 10, s_72_31, 22, 1, 0}, +/* 32 */ { 10, s_72_32, 22, 1, 0}, +/* 33 */ { 14, s_72_33, 32, 1, 0}, +/* 34 */ { 8, s_72_34, 22, 1, 0}, +/* 35 */ { 12, s_72_35, 34, 1, 0}, +/* 36 */ { 2, s_72_36, -1, 1, 0}, +/* 37 */ { 2, s_72_37, -1, 1, 0}, +/* 38 */ { 8, s_72_38, 37, 1, 0}, +/* 39 */ { 8, s_72_39, 37, 1, 0}, +/* 40 */ { 10, s_72_40, 39, 1, 0}, +/* 41 */ { 8, s_72_41, 37, 1, 0}, +/* 42 */ { 8, s_72_42, 37, 1, 0}, +/* 43 */ { 10, s_72_43, 42, 1, 0}, +/* 44 */ { 12, s_72_44, 37, 1, 0}, +/* 45 */ { 14, s_72_45, 44, 1, 0}, +/* 46 */ { 10, s_72_46, 37, 1, 0}, +/* 47 */ { 10, s_72_47, 37, 1, 0}, +/* 48 */ { 8, s_72_48, 37, 1, 0}, +/* 49 */ { 10, s_72_49, 37, 1, 0}, +/* 50 */ { 8, s_72_50, 37, 1, 0}, +/* 51 */ { 4, s_72_51, 37, 1, 0}, +/* 52 */ { 8, s_72_52, 51, 1, 0}, +/* 53 */ { 6, s_72_53, 51, 1, 0}, +/* 54 */ { 8, s_72_54, 51, 1, 0}, +/* 55 */ { 4, s_72_55, 37, 1, 0}, +/* 56 */ { 6, s_72_56, -1, 1, 0}, +/* 57 */ { 10, s_72_57, 56, 1, 0}, +/* 58 */ { 10, s_72_58, 56, 1, 0}, +/* 59 */ { 12, s_72_59, 58, 1, 0}, +/* 60 */ { 10, s_72_60, 56, 1, 0}, +/* 61 */ { 10, s_72_61, 56, 1, 0}, +/* 62 */ { 12, s_72_62, 61, 1, 0}, +/* 63 */ { 4, s_72_63, -1, 1, 0}, +/* 64 */ { 8, s_72_64, 63, 1, 0}, +/* 65 */ { 4, s_72_65, -1, 1, 0}, +/* 66 */ { 10, s_72_66, 65, 1, 0}, +/* 67 */ { 16, s_72_67, 66, 1, 0}, +/* 68 */ { 18, s_72_68, 67, 1, 0}, +/* 69 */ { 8, s_72_69, 65, 1, 0}, +/* 70 */ { 14, s_72_70, 65, 1, 0}, +/* 71 */ { 16, s_72_71, 70, 1, 0}, +/* 72 */ { 14, s_72_72, 65, 1, 0}, +/* 73 */ { 16, s_72_73, 72, 1, 0}, +/* 74 */ { 12, s_72_74, 65, 1, 0}, +/* 75 */ { 14, s_72_75, 74, 1, 0}, +/* 76 */ { 10, s_72_76, 65, 1, 0}, +/* 77 */ { 12, s_72_77, 76, 1, 0}, +/* 78 */ { 8, s_72_78, 65, 1, 0}, +/* 79 */ { 10, s_72_79, 78, 1, 0}, +/* 80 */ { 8, s_72_80, 65, 1, 0}, +/* 81 */ { 8, s_72_81, 65, 1, 0}, +/* 82 */ { 12, s_72_82, 81, 1, 0}, +/* 83 */ { 2, s_72_83, -1, 1, 0} +}; + +static const symbol s_73_0[10] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_73_1[8] = { 0xCF, 0x85, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_73_2[8] = { 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_73_3[8] = { 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_73_4[10] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_73_5[8] = { 0xCF, 0x85, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_73_6[8] = { 0xCF, 0x89, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84 }; +static const symbol s_73_7[8] = { 0xCE, 0xBF, 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84 }; + +static const struct among a_73[8] = +{ +/* 0 */ { 10, s_73_0, -1, 1, 0}, +/* 1 */ { 8, s_73_1, -1, 1, 0}, +/* 2 */ { 8, s_73_2, -1, 1, 0}, +/* 3 */ { 8, s_73_3, -1, 1, 0}, +/* 4 */ { 10, s_73_4, -1, 1, 0}, +/* 5 */ { 8, s_73_5, -1, 1, 0}, +/* 6 */ { 8, s_73_6, -1, 1, 0}, +/* 7 */ { 8, s_73_7, -1, 1, 0} +}; + +static const unsigned char g_v[] = { 81, 65, 16, 1 }; + +static const unsigned char g_v2[] = { 81, 65, 0, 1 }; + +static const symbol s_0[] = { 0xCE, 0xB1 }; +static const symbol s_1[] = { 0xCE, 0xB2 }; +static const symbol s_2[] = { 0xCE, 0xB3 }; +static const symbol s_3[] = { 0xCE, 0xB4 }; +static const symbol s_4[] = { 0xCE, 0xB5 }; +static const symbol s_5[] = { 0xCE, 0xB6 }; +static const symbol s_6[] = { 0xCE, 0xB7 }; +static const symbol s_7[] = { 0xCE, 0xB8 }; +static const symbol s_8[] = { 0xCE, 0xB9 }; +static const symbol s_9[] = { 0xCE, 0xBA }; +static const symbol s_10[] = { 0xCE, 0xBB }; +static const symbol s_11[] = { 0xCE, 0xBC }; +static const symbol s_12[] = { 0xCE, 0xBD }; +static const symbol s_13[] = { 0xCE, 0xBE }; +static const symbol s_14[] = { 0xCE, 0xBF }; +static const symbol s_15[] = { 0xCF, 0x80 }; +static const symbol s_16[] = { 0xCF, 0x81 }; +static const symbol s_17[] = { 0xCF, 0x83 }; +static const symbol s_18[] = { 0xCF, 0x84 }; +static const symbol s_19[] = { 0xCF, 0x85 }; +static const symbol s_20[] = { 0xCF, 0x86 }; +static const symbol s_21[] = { 0xCF, 0x87 }; +static const symbol s_22[] = { 0xCF, 0x88 }; +static const symbol s_23[] = { 0xCF, 0x89 }; +static const symbol s_24[] = { 0xCF, 0x86, 0xCE, 0xB1 }; +static const symbol s_25[] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB1 }; +static const symbol s_26[] = { 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBF }; +static const symbol s_27[] = { 0xCF, 0x83, 0xCE, 0xBF }; +static const symbol s_28[] = { 0xCF, 0x84, 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF }; +static const symbol s_29[] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5 }; +static const symbol s_30[] = { 0xCF, 0x80, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_31[] = { 0xCF, 0x84, 0xCE, 0xB5, 0xCF, 0x81 }; +static const symbol s_32[] = { 0xCF, 0x86, 0xCF, 0x89 }; +static const symbol s_33[] = { 0xCE, 0xBA, 0xCE, 0xB1, 0xCE, 0xB8, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_34[] = { 0xCE, 0xB3, 0xCE, 0xB5, 0xCE, 0xB3, 0xCE, 0xBF, 0xCE, 0xBD }; +static const symbol s_35[] = { 0xCE, 0xB9 }; +static const symbol s_36[] = { 0xCE, 0xB9, 0xCE, 0xB6 }; +static const symbol s_37[] = { 0xCF, 0x89, 0xCE, 0xBD }; +static const symbol s_38[] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xB1 }; +static const symbol s_39[] = { 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_40[] = { 0xCE, 0xB9 }; +static const symbol s_41[] = { 0xCE, 0xB9, 0xCF, 0x83 }; +static const symbol s_42[] = { 0xCE, 0xB9 }; +static const symbol s_43[] = { 0xCE, 0xB9 }; +static const symbol s_44[] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_45[] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBC }; +static const symbol s_46[] = { 0xCE, 0xB9 }; +static const symbol s_47[] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xBD, 0xCF, 0x89, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_48[] = { 0xCE, 0xB1, 0xCF, 0x84, 0xCE, 0xBF, 0xCE, 0xBC }; +static const symbol s_49[] = { 0xCE, 0xB3, 0xCE, 0xBD, 0xCF, 0x89, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_50[] = { 0xCE, 0xB5, 0xCE, 0xB8, 0xCE, 0xBD }; +static const symbol s_51[] = { 0xCE, 0xB5, 0xCE, 0xBA, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBA, 0xCF, 0x84 }; +static const symbol s_52[] = { 0xCF, 0x83, 0xCE, 0xBA, 0xCE, 0xB5, 0xCF, 0x80, 0xCF, 0x84 }; +static const symbol s_53[] = { 0xCF, 0x84, 0xCE, 0xBF, 0xCF, 0x80 }; +static const symbol s_54[] = { 0xCE, 0xB1, 0xCE, 0xBB, 0xCE, 0xB5, 0xCE, 0xBE, 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB4, 0xCF, 0x81 }; +static const symbol s_55[] = { 0xCE, 0xB2, 0xCF, 0x85, 0xCE, 0xB6, 0xCE, 0xB1, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_56[] = { 0xCE, 0xB8, 0xCE, 0xB5, 0xCE, 0xB1, 0xCF, 0x84, 0xCF, 0x81 }; +static const symbol s_57[] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_58[] = { 0xCE, 0xB1, 0xCE, 0xBA }; +static const symbol s_59[] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_60[] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCF, 0x81 }; +static const symbol s_61[] = { 0xCE, 0xB9, 0xCF, 0x84, 0xCF, 0x83 }; +static const symbol s_62[] = { 0xCE, 0xB9, 0xCE, 0xB4 }; +static const symbol s_63[] = { 0xCE, 0xB9, 0xCE, 0xB4 }; +static const symbol s_64[] = { 0xCE, 0xB9, 0xCF, 0x83, 0xCE, 0xBA }; +static const symbol s_65[] = { 0xCE, 0xB1, 0xCE, 0xB4 }; +static const symbol s_66[] = { 0xCE, 0xB5, 0xCE, 0xB4 }; +static const symbol s_67[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xB4 }; +static const symbol s_68[] = { 0xCE, 0xB5 }; +static const symbol s_69[] = { 0xCE, 0xB9 }; +static const symbol s_70[] = { 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_71[] = { 0xCE, 0xB9, 0xCE, 0xBA }; +static const symbol s_72[] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_73[] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_74[] = { 0xCE, 0xB1, 0xCE, 0xBC, 0xCE, 0xB5 }; +static const symbol s_75[] = { 0xCE, 0xB1, 0xCE, 0xBC }; +static const symbol s_76[] = { 0xCE, 0xB1, 0xCE, 0xB3, 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_77[] = { 0xCE, 0xB1, 0xCE, 0xBD, 0xCE, 0xB5 }; +static const symbol s_78[] = { 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_79[] = { 0xCE, 0xB1, 0xCE, 0xBD }; +static const symbol s_80[] = { 0xCE, 0xB5, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_81[] = { 0xCE, 0xB5, 0xCF, 0x84 }; +static const symbol s_82[] = { 0xCE, 0xB5, 0xCF, 0x84 }; +static const symbol s_83[] = { 0xCE, 0xB5, 0xCF, 0x84 }; +static const symbol s_84[] = { 0xCE, 0xB1, 0xCF, 0x81, 0xCF, 0x87 }; +static const symbol s_85[] = { 0xCE, 0xBF, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_86[] = { 0xCE, 0xBA, 0xCF, 0x81, 0xCE, 0xB5 }; +static const symbol s_87[] = { 0xCF, 0x89, 0xCE, 0xBD, 0xCF, 0x84 }; +static const symbol s_88[] = { 0xCE, 0xBF, 0xCE, 0xBD }; +static const symbol s_89[] = { 0xCE, 0xBF, 0xCE, 0xBC, 0xCE, 0xB1, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_90[] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_91[] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_92[] = { 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84, 0xCE, 0xB5 }; +static const symbol s_93[] = { 0xCE, 0xB9, 0xCE, 0xB5, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_94[] = { 0xCE, 0xB7, 0xCE, 0xBA }; +static const symbol s_95[] = { 0xCE, 0xB7, 0xCE, 0xBA }; +static const symbol s_96[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_97[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCF, 0x83 }; +static const symbol s_98[] = { 0xCE, 0xBA, 0xCE, 0xBF, 0xCE, 0xBB, 0xCE, 0xBB }; +static const symbol s_99[] = { 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_100[] = { 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_101[] = { 0xCE, 0xB1, 0xCE, 0xB3 }; +static const symbol s_102[] = { 0xCE, 0xB7, 0xCF, 0x83 }; +static const symbol s_103[] = { 0xCE, 0xB7, 0xCF, 0x83, 0xCF, 0x84 }; +static const symbol s_104[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBD }; +static const symbol s_105[] = { 0xCE, 0xBF, 0xCF, 0x85, 0xCE, 0xBC }; +static const symbol s_106[] = { 0xCE, 0xBC, 0xCE, 0xB1 }; + +static int r_has_min_length(struct SN_env * z) { /* backwardmode */ + if (!(len_utf8(z->p) >= 3)) return 0; /* $( >= ), line 111 */ + return 1; +} + +static int r_tolower(struct SN_env * z) { /* backwardmode */ + int among_var; + while(1) { /* repeat, line 115 */ + int m1 = z->l - z->c; (void)m1; + z->ket = z->c; /* [, line 116 */ + among_var = find_among_b(z, a_0, 46); /* substring, line 116 */ + if (!(among_var)) goto lab0; + z->bra = z->c; /* ], line 116 */ + switch (among_var) { /* among, line 116 */ + case 1: + { int ret = slice_from_s(z, 2, s_0); /* <-, line 117 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 2, s_1); /* <-, line 118 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 2, s_2); /* <-, line 119 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 2, s_3); /* <-, line 120 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 2, s_4); /* <-, line 121 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 2, s_5); /* <-, line 122 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 2, s_6); /* <-, line 123 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 2, s_7); /* <-, line 124 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 2, s_8); /* <-, line 125 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 2, s_9); /* <-, line 126 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 2, s_10); /* <-, line 127 */ + if (ret < 0) return ret; + } + break; + case 12: + { int ret = slice_from_s(z, 2, s_11); /* <-, line 128 */ + if (ret < 0) return ret; + } + break; + case 13: + { int ret = slice_from_s(z, 2, s_12); /* <-, line 129 */ + if (ret < 0) return ret; + } + break; + case 14: + { int ret = slice_from_s(z, 2, s_13); /* <-, line 130 */ + if (ret < 0) return ret; + } + break; + case 15: + { int ret = slice_from_s(z, 2, s_14); /* <-, line 131 */ + if (ret < 0) return ret; + } + break; + case 16: + { int ret = slice_from_s(z, 2, s_15); /* <-, line 132 */ + if (ret < 0) return ret; + } + break; + case 17: + { int ret = slice_from_s(z, 2, s_16); /* <-, line 133 */ + if (ret < 0) return ret; + } + break; + case 18: + { int ret = slice_from_s(z, 2, s_17); /* <-, line 134 */ + if (ret < 0) return ret; + } + break; + case 19: + { int ret = slice_from_s(z, 2, s_18); /* <-, line 135 */ + if (ret < 0) return ret; + } + break; + case 20: + { int ret = slice_from_s(z, 2, s_19); /* <-, line 136 */ + if (ret < 0) return ret; + } + break; + case 21: + { int ret = slice_from_s(z, 2, s_20); /* <-, line 137 */ + if (ret < 0) return ret; + } + break; + case 22: + { int ret = slice_from_s(z, 2, s_21); /* <-, line 138 */ + if (ret < 0) return ret; + } + break; + case 23: + { int ret = slice_from_s(z, 2, s_22); /* <-, line 139 */ + if (ret < 0) return ret; + } + break; + case 24: + { int ret = slice_from_s(z, 2, s_23); /* <-, line 140 */ + if (ret < 0) return ret; + } + break; + case 25: + { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); + if (ret < 0) goto lab0; + z->c = ret; /* next, line 162 */ + } + break; + } + continue; + lab0: + z->c = z->l - m1; + break; + } + return 1; +} + +static int r_step1(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 168 */ + among_var = find_among_b(z, a_1, 40); /* substring, line 168 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 168 */ + switch (among_var) { /* among, line 168 */ + case 1: + { int ret = slice_from_s(z, 4, s_24); /* <-, line 169 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 6, s_25); /* <-, line 170 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 6, s_26); /* <-, line 171 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 4, s_27); /* <-, line 172 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 8, s_28); /* <-, line 173 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 6, s_29); /* <-, line 174 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 6, s_30); /* <-, line 175 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 6, s_31); /* <-, line 176 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 4, s_32); /* <-, line 177 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 12, s_33); /* <-, line 178 */ + if (ret < 0) return ret; + } + break; + case 11: + { int ret = slice_from_s(z, 10, s_34); /* <-, line 179 */ + if (ret < 0) return ret; + } + break; + } + z->B[0] = 0; /* unset test1, line 181 */ + return 1; +} + +static int r_steps1(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 185 */ + if (!(find_among_b(z, a_4, 14))) return 0; /* substring, line 185 */ + z->bra = z->c; /* ], line 185 */ + { int ret = slice_del(z); /* delete, line 188 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 189 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 193 */ + z->ket = z->c; /* [, line 190 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab1; /* substring, line 190 */ + if (!(find_among_b(z, a_2, 9))) goto lab1; + z->bra = z->c; /* ], line 190 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 190 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 192 */ + if (z->S[0] == 0) return -1; /* -> s, line 192 */ + { int ret = slice_from_s(z, 2, s_35); /* <-, line 192 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 192 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 194 */ + if (!(find_among_b(z, a_3, 22))) return 0; /* substring, line 194 */ + z->bra = z->c; /* ], line 194 */ + if (z->c > z->lb) return 0; /* atlimit, line 194 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 198 */ + if (z->S[0] == 0) return -1; /* -> s, line 198 */ + { int ret = slice_from_s(z, 4, s_36); /* <-, line 198 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 198 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_steps2(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 205 */ + if (!(find_among_b(z, a_6, 7))) return 0; /* substring, line 205 */ + z->bra = z->c; /* ], line 205 */ + { int ret = slice_del(z); /* delete, line 207 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 208 */ + z->ket = z->c; /* [, line 209 */ + if (!(find_among_b(z, a_5, 8))) return 0; /* substring, line 209 */ + z->bra = z->c; /* ], line 209 */ + if (z->c > z->lb) return 0; /* atlimit, line 209 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 210 */ + if (z->S[0] == 0) return -1; /* -> s, line 210 */ + { int ret = slice_from_s(z, 4, s_37); /* <-, line 210 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 210 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_steps3(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 217 */ + if (!(find_among_b(z, a_9, 7))) return 0; /* substring, line 217 */ + z->bra = z->c; /* ], line 217 */ + { int ret = slice_del(z); /* delete, line 219 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 220 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 221 */ + if (!(eq_s_b(z, 6, s_38))) goto lab1; /* literal, line 221 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 221 */ + { int ret = slice_from_s(z, 4, s_39); /* <-, line 221 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 222 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab2; /* substring, line 222 */ + if (!(find_among_b(z, a_7, 19))) goto lab2; + z->bra = z->c; /* ], line 222 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 222 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 226 */ + if (z->S[0] == 0) return -1; /* -> s, line 226 */ + { int ret = slice_from_s(z, 2, s_40); /* <-, line 226 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 226 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab2: + z->c = z->l - m1; + z->ket = z->c; /* [, line 228 */ + if (!(find_among_b(z, a_8, 13))) return 0; /* substring, line 228 */ + z->bra = z->c; /* ], line 228 */ + if (z->c > z->lb) return 0; /* atlimit, line 228 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 231 */ + if (z->S[0] == 0) return -1; /* -> s, line 231 */ + { int ret = slice_from_s(z, 4, s_41); /* <-, line 231 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 231 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_steps4(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 238 */ + if (!(find_among_b(z, a_11, 7))) return 0; /* substring, line 238 */ + z->bra = z->c; /* ], line 238 */ + { int ret = slice_del(z); /* delete, line 240 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 241 */ + z->ket = z->c; /* [, line 242 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-2145255424 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 242 */ + if (!(find_among_b(z, a_10, 19))) return 0; + z->bra = z->c; /* ], line 242 */ + if (z->c > z->lb) return 0; /* atlimit, line 242 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 246 */ + if (z->S[0] == 0) return -1; /* -> s, line 246 */ + { int ret = slice_from_s(z, 2, s_42); /* <-, line 246 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 246 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_steps5(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 253 */ + if (!(find_among_b(z, a_14, 11))) return 0; /* substring, line 253 */ + z->bra = z->c; /* ], line 253 */ + { int ret = slice_del(z); /* delete, line 256 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 257 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 261 */ + z->ket = z->c; /* [, line 258 */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 191)) goto lab1; /* substring, line 258 */ + if (!(find_among_b(z, a_12, 7))) goto lab1; + z->bra = z->c; /* ], line 258 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 258 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 260 */ + if (z->S[0] == 0) return -1; /* -> s, line 260 */ + { int ret = slice_from_s(z, 2, s_43); /* <-, line 260 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 260 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 262 */ + if (!(find_among_b(z, a_13, 33))) return 0; /* substring, line 262 */ + z->bra = z->c; /* ], line 262 */ + if (z->c > z->lb) return 0; /* atlimit, line 262 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 266 */ + if (z->S[0] == 0) return -1; /* -> s, line 266 */ + { int ret = slice_from_s(z, 6, s_44); /* <-, line 266 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 266 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_steps6(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 273 */ + if (!(find_among_b(z, a_18, 6))) return 0; /* substring, line 273 */ + z->bra = z->c; /* ], line 273 */ + { int ret = slice_del(z); /* delete, line 275 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 276 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 280 */ + z->ket = z->c; /* [, line 277 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 181) goto lab1; /* substring, line 277 */ + if (!(find_among_b(z, a_15, 5))) goto lab1; + z->bra = z->c; /* ], line 277 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 277 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 279 */ + if (z->S[0] == 0) return -1; /* -> s, line 279 */ + { int ret = slice_from_s(z, 6, s_45); /* <-, line 279 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 279 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 281 */ + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) goto lab2; /* substring, line 281 */ + if (!(find_among_b(z, a_16, 2))) goto lab2; + z->bra = z->c; /* ], line 281 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 281 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 283 */ + if (z->S[0] == 0) return -1; /* -> s, line 283 */ + { int ret = slice_from_s(z, 2, s_46); /* <-, line 283 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 283 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab2: + z->c = z->l - m1; + z->ket = z->c; /* [, line 285 */ + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 186 && z->p[z->c - 1] != 189)) return 0; /* substring, line 285 */ + among_var = find_among_b(z, a_17, 10); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 285 */ + switch (among_var) { /* among, line 285 */ + case 1: + { int ret = slice_from_s(z, 12, s_47); /* <-, line 286 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 8, s_48); /* <-, line 287 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 10, s_49); /* <-, line 288 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 6, s_50); /* <-, line 289 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 12, s_51); /* <-, line 290 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 10, s_52); /* <-, line 291 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 6, s_53); /* <-, line 292 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 16, s_54); /* <-, line 293 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 12, s_55); /* <-, line 294 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 10, s_56); /* <-, line 295 */ + if (ret < 0) return ret; + } + break; + } + } +lab0: + return 1; +} + +static int r_steps7(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 302 */ + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 177 && z->p[z->c - 1] != 185)) return 0; /* substring, line 302 */ + if (!(find_among_b(z, a_20, 4))) return 0; + z->bra = z->c; /* ], line 302 */ + { int ret = slice_del(z); /* delete, line 304 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 305 */ + z->ket = z->c; /* [, line 306 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 135)) return 0; /* substring, line 306 */ + if (!(find_among_b(z, a_19, 2))) return 0; + z->bra = z->c; /* ], line 306 */ + if (z->c > z->lb) return 0; /* atlimit, line 306 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 308 */ + if (z->S[0] == 0) return -1; /* -> s, line 308 */ + { int ret = slice_from_s(z, 8, s_57); /* <-, line 308 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 308 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_steps8(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 315 */ + if (!(find_among_b(z, a_23, 8))) return 0; /* substring, line 315 */ + z->bra = z->c; /* ], line 315 */ + { int ret = slice_del(z); /* delete, line 317 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 318 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 325 */ + z->ket = z->c; /* [, line 319 */ + if (!(find_among_b(z, a_21, 33))) goto lab1; /* substring, line 319 */ + z->bra = z->c; /* ], line 319 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 319 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 324 */ + if (z->S[0] == 0) return -1; /* -> s, line 324 */ + { int ret = slice_from_s(z, 4, s_58); /* <-, line 324 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 324 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 326 */ + if (!(find_among_b(z, a_22, 15))) goto lab2; /* substring, line 326 */ + z->bra = z->c; /* ], line 326 */ + if (z->c > z->lb) goto lab2; /* atlimit, line 326 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 329 */ + if (z->S[0] == 0) return -1; /* -> s, line 329 */ + { int ret = slice_from_s(z, 6, s_59); /* <-, line 329 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 329 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab2: + z->c = z->l - m1; + z->ket = z->c; /* [, line 331 */ + if (!(eq_s_b(z, 6, s_60))) return 0; /* literal, line 331 */ + z->bra = z->c; /* ], line 331 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 331 */ + if (z->S[0] == 0) return -1; /* -> s, line 331 */ + { int ret = slice_from_s(z, 6, s_61); /* <-, line 331 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 331 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_steps9(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 337 */ + if (z->c - 7 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((-1610481664 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 337 */ + if (!(find_among_b(z, a_26, 3))) return 0; + z->bra = z->c; /* ], line 337 */ + { int ret = slice_del(z); /* delete, line 339 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 340 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 343 */ + z->ket = z->c; /* [, line 341 */ + if (!(find_among_b(z, a_24, 4))) goto lab1; /* substring, line 341 */ + z->bra = z->c; /* ], line 341 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 341 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 342 */ + if (z->S[0] == 0) return -1; /* -> s, line 342 */ + { int ret = slice_from_s(z, 4, s_62); /* <-, line 342 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 342 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 344 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 181 && z->p[z->c - 1] != 189)) return 0; /* substring, line 344 */ + if (!(find_among_b(z, a_25, 2))) return 0; + z->bra = z->c; /* ], line 344 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 345 */ + if (z->S[0] == 0) return -1; /* -> s, line 345 */ + { int ret = slice_from_s(z, 4, s_63); /* <-, line 345 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 345 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_steps10(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 352 */ + if (!(find_among_b(z, a_28, 4))) return 0; /* substring, line 352 */ + z->bra = z->c; /* ], line 352 */ + { int ret = slice_del(z); /* delete, line 354 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 355 */ + z->ket = z->c; /* [, line 356 */ + if (!(find_among_b(z, a_27, 7))) return 0; /* substring, line 356 */ + z->bra = z->c; /* ], line 356 */ + if (z->c > z->lb) return 0; /* atlimit, line 356 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 358 */ + if (z->S[0] == 0) return -1; /* -> s, line 358 */ + { int ret = slice_from_s(z, 6, s_64); /* <-, line 358 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 358 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step2a(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 365 */ + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 365 */ + if (!(find_among_b(z, a_29, 2))) return 0; + z->bra = z->c; /* ], line 365 */ + { int ret = slice_del(z); /* delete, line 366 */ + if (ret < 0) return ret; + } + { int m1 = z->l - z->c; (void)m1; /* not, line 368 */ + z->ket = z->c; /* [, line 368 */ + if (!(find_among_b(z, a_30, 10))) goto lab0; /* substring, line 368 */ + z->bra = z->c; /* ], line 368 */ + return 0; + lab0: + z->c = z->l - m1; + } + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 4, s_65); /* <+, line 371 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step2b(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 375 */ + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 375 */ + if (!(find_among_b(z, a_31, 2))) return 0; + z->bra = z->c; /* ], line 375 */ + { int ret = slice_del(z); /* delete, line 376 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 378 */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 187)) return 0; /* substring, line 378 */ + if (!(find_among_b(z, a_32, 8))) return 0; + z->bra = z->c; /* ], line 378 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 379 */ + if (z->S[0] == 0) return -1; /* -> s, line 379 */ + { int ret = slice_from_s(z, 4, s_66); /* <-, line 379 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 379 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step2c(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 384 */ + if (z->c - 9 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 384 */ + if (!(find_among_b(z, a_33, 2))) return 0; + z->bra = z->c; /* ], line 384 */ + { int ret = slice_del(z); /* delete, line 385 */ + if (ret < 0) return ret; + } + z->ket = z->c; /* [, line 387 */ + if (!(find_among_b(z, a_34, 15))) return 0; /* substring, line 387 */ + z->bra = z->c; /* ], line 387 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 389 */ + if (z->S[0] == 0) return -1; /* -> s, line 389 */ + { int ret = slice_from_s(z, 6, s_67); /* <-, line 389 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 389 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step2d(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 394 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 131 && z->p[z->c - 1] != 189)) return 0; /* substring, line 394 */ + if (!(find_among_b(z, a_35, 2))) return 0; + z->bra = z->c; /* ], line 394 */ + { int ret = slice_del(z); /* delete, line 395 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 395 */ + z->ket = z->c; /* [, line 397 */ + if (!(find_among_b(z, a_36, 8))) return 0; /* substring, line 397 */ + z->bra = z->c; /* ], line 397 */ + if (z->c > z->lb) return 0; /* atlimit, line 397 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 398 */ + if (z->S[0] == 0) return -1; /* -> s, line 398 */ + { int ret = slice_from_s(z, 2, s_68); /* <-, line 398 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 398 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step3(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 403 */ + if (!(find_among_b(z, a_37, 3))) return 0; /* substring, line 403 */ + z->bra = z->c; /* ], line 403 */ + { int ret = slice_del(z); /* delete, line 404 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 404 */ + z->ket = z->c; /* [, line 406 */ + if (in_grouping_b_U(z, g_v, 945, 969, 0)) return 0; /* grouping v, line 406 */ + z->bra = z->c; /* ], line 406 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 406 */ + if (z->S[0] == 0) return -1; /* -> s, line 406 */ + { int ret = slice_from_s(z, 2, s_69); /* <-, line 406 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 406 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step4(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 410 */ + if (!(find_among_b(z, a_38, 4))) return 0; /* substring, line 410 */ + z->bra = z->c; /* ], line 410 */ + { int ret = slice_del(z); /* delete, line 411 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 411 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 413 */ + z->ket = z->c; /* [, line 413 */ + if (in_grouping_b_U(z, g_v, 945, 969, 0)) goto lab1; /* grouping v, line 413 */ + z->bra = z->c; /* ], line 413 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 413 */ + if (z->S[0] == 0) return -1; /* -> s, line 413 */ + { int ret = slice_from_s(z, 4, s_70); /* <-, line 413 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 413 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 414 */ + } +lab0: + if (!(find_among_b(z, a_39, 36))) return 0; /* substring, line 414 */ + z->bra = z->c; /* ], line 414 */ + if (z->c > z->lb) return 0; /* atlimit, line 414 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 419 */ + if (z->S[0] == 0) return -1; /* -> s, line 419 */ + { int ret = slice_from_s(z, 4, s_71); /* <-, line 419 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 419 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5a(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 424 */ + if (!(eq_s_b(z, 10, s_72))) goto lab0; /* literal, line 424 */ + if (z->c > z->lb) goto lab0; /* atlimit, line 424 */ + { int ret = slice_from_s(z, 8, s_73); /* <-, line 424 */ + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + { int m2 = z->l - z->c; (void)m2; /* do, line 425 */ + z->ket = z->c; /* [, line 426 */ + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab1; /* substring, line 426 */ + if (!(find_among_b(z, a_40, 5))) goto lab1; + z->bra = z->c; /* ], line 426 */ + { int ret = slice_del(z); /* delete, line 427 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 427 */ + lab1: + z->c = z->l - m2; + } + z->ket = z->c; /* [, line 430 */ + if (!(eq_s_b(z, 6, s_74))) return 0; /* literal, line 430 */ + z->bra = z->c; /* ], line 430 */ + { int ret = slice_del(z); /* delete, line 431 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 432 */ + z->ket = z->c; /* [, line 433 */ + if (!(find_among_b(z, a_41, 12))) return 0; /* substring, line 433 */ + z->bra = z->c; /* ], line 433 */ + if (z->c > z->lb) return 0; /* atlimit, line 433 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 435 */ + if (z->S[0] == 0) return -1; /* -> s, line 435 */ + { int ret = slice_from_s(z, 4, s_75); /* <-, line 435 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 435 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5b(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 440 */ + z->ket = z->c; /* [, line 441 */ + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; /* substring, line 441 */ + if (!(find_among_b(z, a_43, 11))) goto lab0; + z->bra = z->c; /* ], line 441 */ + { int ret = slice_del(z); /* delete, line 444 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 445 */ + z->ket = z->c; /* [, line 446 */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 131)) goto lab0; /* substring, line 446 */ + if (!(find_among_b(z, a_42, 2))) goto lab0; + z->bra = z->c; /* ], line 446 */ + if (z->c > z->lb) goto lab0; /* atlimit, line 446 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 447 */ + if (z->S[0] == 0) return -1; /* -> s, line 447 */ + { int ret = slice_from_s(z, 8, s_76); /* <-, line 447 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 447 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + z->ket = z->c; /* [, line 452 */ + if (!(eq_s_b(z, 6, s_77))) return 0; /* literal, line 452 */ + z->bra = z->c; /* ], line 452 */ + { int ret = slice_del(z); /* delete, line 453 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 454 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 455 */ + z->ket = z->c; /* [, line 455 */ + if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; /* grouping v2, line 455 */ + z->bra = z->c; /* ], line 455 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 455 */ + if (z->S[0] == 0) return -1; /* -> s, line 455 */ + { int ret = slice_from_s(z, 4, s_78); /* <-, line 455 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 455 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m2; + z->ket = z->c; /* [, line 456 */ + } +lab1: + if (!(find_among_b(z, a_44, 95))) return 0; /* substring, line 456 */ + z->bra = z->c; /* ], line 456 */ + if (z->c > z->lb) return 0; /* atlimit, line 456 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 473 */ + if (z->S[0] == 0) return -1; /* -> s, line 473 */ + { int ret = slice_from_s(z, 4, s_79); /* <-, line 473 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 473 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5c(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 478 */ + z->ket = z->c; /* [, line 479 */ + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 181) goto lab0; /* substring, line 479 */ + if (!(find_among_b(z, a_45, 1))) goto lab0; + z->bra = z->c; /* ], line 479 */ + { int ret = slice_del(z); /* delete, line 480 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 480 */ + lab0: + z->c = z->l - m1; + } + z->ket = z->c; /* [, line 483 */ + if (!(eq_s_b(z, 6, s_80))) return 0; /* literal, line 483 */ + z->bra = z->c; /* ], line 483 */ + { int ret = slice_del(z); /* delete, line 484 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 485 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 486 */ + z->ket = z->c; /* [, line 486 */ + if (in_grouping_b_U(z, g_v2, 945, 969, 0)) goto lab2; /* grouping v2, line 486 */ + z->bra = z->c; /* ], line 486 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 486 */ + if (z->S[0] == 0) return -1; /* -> s, line 486 */ + { int ret = slice_from_s(z, 4, s_81); /* <-, line 486 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 486 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m2; + z->ket = z->c; /* [, line 487 */ + if (!(find_among_b(z, a_46, 31))) goto lab3; /* substring, line 487 */ + z->bra = z->c; /* ], line 487 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 491 */ + if (z->S[0] == 0) return -1; /* -> s, line 491 */ + { int ret = slice_from_s(z, 4, s_82); /* <-, line 491 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 491 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab1; + lab3: + z->c = z->l - m2; + z->ket = z->c; /* [, line 493 */ + } +lab1: + if (!(find_among_b(z, a_47, 25))) return 0; /* substring, line 493 */ + z->bra = z->c; /* ], line 493 */ + if (z->c > z->lb) return 0; /* atlimit, line 493 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 497 */ + if (z->S[0] == 0) return -1; /* -> s, line 497 */ + { int ret = slice_from_s(z, 4, s_83); /* <-, line 497 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 497 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5d(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 502 */ + if (z->c - 9 <= z->lb || z->p[z->c - 1] != 131) return 0; /* substring, line 502 */ + if (!(find_among_b(z, a_48, 2))) return 0; + z->bra = z->c; /* ], line 502 */ + { int ret = slice_del(z); /* delete, line 504 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 505 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 506 */ + z->ket = z->c; /* [, line 506 */ + if (!(eq_s_b(z, 6, s_84))) goto lab1; /* literal, line 506 */ + z->bra = z->c; /* ], line 506 */ + if (z->c > z->lb) goto lab1; /* atlimit, line 506 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 506 */ + if (z->S[0] == 0) return -1; /* -> s, line 506 */ + { int ret = slice_from_s(z, 6, s_85); /* <-, line 506 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 506 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 507 */ + if (!(eq_s_b(z, 6, s_86))) return 0; /* literal, line 507 */ + z->bra = z->c; /* ], line 507 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 507 */ + if (z->S[0] == 0) return -1; /* -> s, line 507 */ + { int ret = slice_from_s(z, 6, s_87); /* <-, line 507 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 507 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_step5e(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 513 */ + if (z->c - 11 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 513 */ + if (!(find_among_b(z, a_49, 2))) return 0; + z->bra = z->c; /* ], line 513 */ + { int ret = slice_del(z); /* delete, line 515 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 516 */ + z->ket = z->c; /* [, line 517 */ + if (!(eq_s_b(z, 4, s_88))) return 0; /* literal, line 517 */ + z->bra = z->c; /* ], line 517 */ + if (z->c > z->lb) return 0; /* atlimit, line 517 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 517 */ + if (z->S[0] == 0) return -1; /* -> s, line 517 */ + { int ret = slice_from_s(z, 10, s_89); /* <-, line 517 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 517 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5f(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 523 */ + z->ket = z->c; /* [, line 524 */ + if (!(eq_s_b(z, 10, s_90))) goto lab0; /* literal, line 524 */ + z->bra = z->c; /* ], line 524 */ + { int ret = slice_del(z); /* delete, line 525 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 526 */ + z->ket = z->c; /* [, line 527 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 128 && z->p[z->c - 1] != 134)) goto lab0; /* substring, line 527 */ + if (!(find_among_b(z, a_50, 6))) goto lab0; + z->bra = z->c; /* ], line 527 */ + if (z->c > z->lb) goto lab0; /* atlimit, line 527 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 528 */ + if (z->S[0] == 0) return -1; /* -> s, line 528 */ + { int ret = slice_from_s(z, 8, s_91); /* <-, line 528 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 528 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + z->ket = z->c; /* [, line 531 */ + if (!(eq_s_b(z, 8, s_92))) return 0; /* literal, line 531 */ + z->bra = z->c; /* ], line 531 */ + { int ret = slice_del(z); /* delete, line 532 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 533 */ + z->ket = z->c; /* [, line 534 */ + if (!(find_among_b(z, a_51, 9))) return 0; /* substring, line 534 */ + z->bra = z->c; /* ], line 534 */ + if (z->c > z->lb) return 0; /* atlimit, line 534 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 536 */ + if (z->S[0] == 0) return -1; /* -> s, line 536 */ + { int ret = slice_from_s(z, 8, s_93); /* <-, line 536 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 536 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5g(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 541 */ + z->ket = z->c; /* [, line 542 */ + if (!(find_among_b(z, a_52, 3))) goto lab0; /* substring, line 542 */ + z->bra = z->c; /* ], line 542 */ + { int ret = slice_del(z); /* delete, line 543 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 543 */ + lab0: + z->c = z->l - m1; + } + z->ket = z->c; /* [, line 546 */ + if (!(find_among_b(z, a_55, 3))) return 0; /* substring, line 546 */ + z->bra = z->c; /* ], line 546 */ + { int ret = slice_del(z); /* delete, line 548 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 549 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 552 */ + z->ket = z->c; /* [, line 550 */ + if (!(find_among_b(z, a_53, 6))) goto lab2; /* substring, line 550 */ + z->bra = z->c; /* ], line 550 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 551 */ + if (z->S[0] == 0) return -1; /* -> s, line 551 */ + { int ret = slice_from_s(z, 4, s_94); /* <-, line 551 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 551 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab1; + lab2: + z->c = z->l - m2; + z->ket = z->c; /* [, line 553 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 184) return 0; /* substring, line 553 */ + if (!(find_among_b(z, a_54, 5))) return 0; + z->bra = z->c; /* ], line 553 */ + if (z->c > z->lb) return 0; /* atlimit, line 553 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 554 */ + if (z->S[0] == 0) return -1; /* -> s, line 554 */ + { int ret = slice_from_s(z, 4, s_95); /* <-, line 554 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 554 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab1: + return 1; +} + +static int r_step5h(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 561 */ + if (!(find_among_b(z, a_58, 3))) return 0; /* substring, line 561 */ + z->bra = z->c; /* ], line 561 */ + { int ret = slice_del(z); /* delete, line 563 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 564 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 569 */ + z->ket = z->c; /* [, line 565 */ + if (!(find_among_b(z, a_56, 12))) goto lab1; /* substring, line 565 */ + z->bra = z->c; /* ], line 565 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 567 */ + if (z->S[0] == 0) return -1; /* -> s, line 567 */ + { int ret = slice_from_s(z, 6, s_96); /* <-, line 567 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 567 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 570 */ + if (!(find_among_b(z, a_57, 25))) return 0; /* substring, line 570 */ + z->bra = z->c; /* ], line 570 */ + if (z->c > z->lb) return 0; /* atlimit, line 570 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 574 */ + if (z->S[0] == 0) return -1; /* -> s, line 574 */ + { int ret = slice_from_s(z, 6, s_97); /* <-, line 574 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 574 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_step5i(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 581 */ + if (!(find_among_b(z, a_62, 3))) return 0; /* substring, line 581 */ + z->bra = z->c; /* ], line 581 */ + { int ret = slice_del(z); /* delete, line 583 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 584 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 585 */ + z->ket = z->c; /* [, line 585 */ + if (!(eq_s_b(z, 8, s_98))) goto lab1; /* literal, line 585 */ + z->bra = z->c; /* ], line 585 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 585 */ + if (z->S[0] == 0) return -1; /* -> s, line 585 */ + { int ret = slice_from_s(z, 4, s_99); /* <-, line 585 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 585 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + { int m2 = z->l - z->c; (void)m2; /* not, line 586 */ + z->ket = z->c; /* [, line 586 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 134 && z->p[z->c - 1] != 135)) goto lab2; /* substring, line 586 */ + if (!(find_among_b(z, a_59, 2))) goto lab2; + z->bra = z->c; /* ], line 586 */ + return 0; + lab2: + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; /* or, line 590 */ + z->ket = z->c; /* [, line 587 */ + if (!(find_among_b(z, a_60, 10))) goto lab4; /* substring, line 587 */ + z->bra = z->c; /* ], line 587 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 589 */ + if (z->S[0] == 0) return -1; /* -> s, line 589 */ + { int ret = slice_from_s(z, 4, s_100); /* <-, line 589 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 589 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + goto lab3; + lab4: + z->c = z->l - m3; + z->ket = z->c; /* [, line 591 */ + if (!(find_among_b(z, a_61, 44))) return 0; /* substring, line 591 */ + z->bra = z->c; /* ], line 591 */ + if (z->c > z->lb) return 0; /* atlimit, line 591 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 597 */ + if (z->S[0] == 0) return -1; /* -> s, line 597 */ + { int ret = slice_from_s(z, 4, s_101); /* <-, line 597 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 597 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + } + lab3: + ; + } +lab0: + return 1; +} + +static int r_step5j(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 605 */ + if (!(find_among_b(z, a_63, 3))) return 0; /* substring, line 605 */ + z->bra = z->c; /* ], line 605 */ + { int ret = slice_del(z); /* delete, line 606 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 606 */ + z->ket = z->c; /* [, line 608 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 189) return 0; /* substring, line 608 */ + if (!(find_among_b(z, a_64, 6))) return 0; + z->bra = z->c; /* ], line 608 */ + if (z->c > z->lb) return 0; /* atlimit, line 608 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 609 */ + if (z->S[0] == 0) return -1; /* -> s, line 609 */ + { int ret = slice_from_s(z, 4, s_102); /* <-, line 609 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 609 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5k(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 614 */ + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 614 */ + if (!(find_among_b(z, a_65, 1))) return 0; + z->bra = z->c; /* ], line 614 */ + { int ret = slice_del(z); /* delete, line 615 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 615 */ + z->ket = z->c; /* [, line 617 */ + if (!(find_among_b(z, a_66, 10))) return 0; /* substring, line 617 */ + z->bra = z->c; /* ], line 617 */ + if (z->c > z->lb) return 0; /* atlimit, line 617 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 619 */ + if (z->S[0] == 0) return -1; /* -> s, line 619 */ + { int ret = slice_from_s(z, 6, s_103); /* <-, line 619 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 619 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5l(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 624 */ + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 624 */ + if (!(find_among_b(z, a_67, 3))) return 0; + z->bra = z->c; /* ], line 624 */ + { int ret = slice_del(z); /* delete, line 625 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 625 */ + z->ket = z->c; /* [, line 627 */ + if (!(find_among_b(z, a_68, 6))) return 0; /* substring, line 627 */ + z->bra = z->c; /* ], line 627 */ + if (z->c > z->lb) return 0; /* atlimit, line 627 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 628 */ + if (z->S[0] == 0) return -1; /* -> s, line 628 */ + { int ret = slice_from_s(z, 6, s_104); /* <-, line 628 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 628 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step5m(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 633 */ + if (z->c - 7 <= z->lb || z->p[z->c - 1] != 181) return 0; /* substring, line 633 */ + if (!(find_among_b(z, a_69, 3))) return 0; + z->bra = z->c; /* ], line 633 */ + { int ret = slice_del(z); /* delete, line 634 */ + if (ret < 0) return ret; + } + z->B[0] = 0; /* unset test1, line 634 */ + z->ket = z->c; /* [, line 636 */ + if (!(find_among_b(z, a_70, 7))) return 0; /* substring, line 636 */ + z->bra = z->c; /* ], line 636 */ + if (z->c > z->lb) return 0; /* atlimit, line 636 */ + z->S[0] = slice_to(z, z->S[0]); /* -> s, line 638 */ + if (z->S[0] == 0) return -1; /* -> s, line 638 */ + { int ret = slice_from_s(z, 6, s_105); /* <-, line 638 */ + if (ret < 0) return ret; + } + { int ret; + { int saved_c = z->c; + ret = insert_v(z, z->c, z->c, z->S[0]); /* <+ s, line 638 */ + z->c = saved_c; + } + if (ret < 0) return ret; + } + return 1; +} + +static int r_step6(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* do, line 643 */ + z->ket = z->c; /* [, line 644 */ + if (!(find_among_b(z, a_71, 3))) goto lab0; /* substring, line 644 */ + z->bra = z->c; /* ], line 644 */ + { int ret = slice_from_s(z, 4, s_106); /* <-, line 645 */ + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + if (!(z->B[0])) return 0; /* Boolean test test1, line 648 */ + z->ket = z->c; /* [, line 649 */ + if (!(find_among_b(z, a_72, 84))) return 0; /* substring, line 649 */ + z->bra = z->c; /* ], line 649 */ + { int ret = slice_del(z); /* delete, line 659 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_step7(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 664 */ + if (z->c - 7 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 132)) return 0; /* substring, line 664 */ + if (!(find_among_b(z, a_73, 8))) return 0; + z->bra = z->c; /* ], line 664 */ + { int ret = slice_del(z); /* delete, line 665 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int greek_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->lb = z->c; z->c = z->l; /* backwards, line 671 */ + + { int m1 = z->l - z->c; (void)m1; /* do, line 672 */ + { int ret = r_tolower(z); /* call tolower, line 672 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + { int ret = r_has_min_length(z); /* call has_min_length, line 673 */ + if (ret <= 0) return ret; + } + z->B[0] = 1; /* set test1, line 674 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 675 */ + { int ret = r_step1(z); /* call step1, line 675 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } + lab1: + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; /* do, line 676 */ + { int ret = r_steps1(z); /* call steps1, line 676 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m3; + } + { int m4 = z->l - z->c; (void)m4; /* do, line 677 */ + { int ret = r_steps2(z); /* call steps2, line 677 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m4; + } + { int m5 = z->l - z->c; (void)m5; /* do, line 678 */ + { int ret = r_steps3(z); /* call steps3, line 678 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m5; + } + { int m6 = z->l - z->c; (void)m6; /* do, line 679 */ + { int ret = r_steps4(z); /* call steps4, line 679 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; + } + lab5: + z->c = z->l - m6; + } + { int m7 = z->l - z->c; (void)m7; /* do, line 680 */ + { int ret = r_steps5(z); /* call steps5, line 680 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m7; + } + { int m8 = z->l - z->c; (void)m8; /* do, line 681 */ + { int ret = r_steps6(z); /* call steps6, line 681 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m8; + } + { int m9 = z->l - z->c; (void)m9; /* do, line 682 */ + { int ret = r_steps7(z); /* call steps7, line 682 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; + } + lab8: + z->c = z->l - m9; + } + { int m10 = z->l - z->c; (void)m10; /* do, line 683 */ + { int ret = r_steps8(z); /* call steps8, line 683 */ + if (ret == 0) goto lab9; + if (ret < 0) return ret; + } + lab9: + z->c = z->l - m10; + } + { int m11 = z->l - z->c; (void)m11; /* do, line 684 */ + { int ret = r_steps9(z); /* call steps9, line 684 */ + if (ret == 0) goto lab10; + if (ret < 0) return ret; + } + lab10: + z->c = z->l - m11; + } + { int m12 = z->l - z->c; (void)m12; /* do, line 685 */ + { int ret = r_steps10(z); /* call steps10, line 685 */ + if (ret == 0) goto lab11; + if (ret < 0) return ret; + } + lab11: + z->c = z->l - m12; + } + { int m13 = z->l - z->c; (void)m13; /* do, line 686 */ + { int ret = r_step2a(z); /* call step2a, line 686 */ + if (ret == 0) goto lab12; + if (ret < 0) return ret; + } + lab12: + z->c = z->l - m13; + } + { int m14 = z->l - z->c; (void)m14; /* do, line 687 */ + { int ret = r_step2b(z); /* call step2b, line 687 */ + if (ret == 0) goto lab13; + if (ret < 0) return ret; + } + lab13: + z->c = z->l - m14; + } + { int m15 = z->l - z->c; (void)m15; /* do, line 688 */ + { int ret = r_step2c(z); /* call step2c, line 688 */ + if (ret == 0) goto lab14; + if (ret < 0) return ret; + } + lab14: + z->c = z->l - m15; + } + { int m16 = z->l - z->c; (void)m16; /* do, line 689 */ + { int ret = r_step2d(z); /* call step2d, line 689 */ + if (ret == 0) goto lab15; + if (ret < 0) return ret; + } + lab15: + z->c = z->l - m16; + } + { int m17 = z->l - z->c; (void)m17; /* do, line 690 */ + { int ret = r_step3(z); /* call step3, line 690 */ + if (ret == 0) goto lab16; + if (ret < 0) return ret; + } + lab16: + z->c = z->l - m17; + } + { int m18 = z->l - z->c; (void)m18; /* do, line 691 */ + { int ret = r_step4(z); /* call step4, line 691 */ + if (ret == 0) goto lab17; + if (ret < 0) return ret; + } + lab17: + z->c = z->l - m18; + } + { int m19 = z->l - z->c; (void)m19; /* do, line 692 */ + { int ret = r_step5a(z); /* call step5a, line 692 */ + if (ret == 0) goto lab18; + if (ret < 0) return ret; + } + lab18: + z->c = z->l - m19; + } + { int m20 = z->l - z->c; (void)m20; /* do, line 693 */ + { int ret = r_step5b(z); /* call step5b, line 693 */ + if (ret == 0) goto lab19; + if (ret < 0) return ret; + } + lab19: + z->c = z->l - m20; + } + { int m21 = z->l - z->c; (void)m21; /* do, line 694 */ + { int ret = r_step5c(z); /* call step5c, line 694 */ + if (ret == 0) goto lab20; + if (ret < 0) return ret; + } + lab20: + z->c = z->l - m21; + } + { int m22 = z->l - z->c; (void)m22; /* do, line 695 */ + { int ret = r_step5d(z); /* call step5d, line 695 */ + if (ret == 0) goto lab21; + if (ret < 0) return ret; + } + lab21: + z->c = z->l - m22; + } + { int m23 = z->l - z->c; (void)m23; /* do, line 696 */ + { int ret = r_step5e(z); /* call step5e, line 696 */ + if (ret == 0) goto lab22; + if (ret < 0) return ret; + } + lab22: + z->c = z->l - m23; + } + { int m24 = z->l - z->c; (void)m24; /* do, line 697 */ + { int ret = r_step5f(z); /* call step5f, line 697 */ + if (ret == 0) goto lab23; + if (ret < 0) return ret; + } + lab23: + z->c = z->l - m24; + } + { int m25 = z->l - z->c; (void)m25; /* do, line 698 */ + { int ret = r_step5g(z); /* call step5g, line 698 */ + if (ret == 0) goto lab24; + if (ret < 0) return ret; + } + lab24: + z->c = z->l - m25; + } + { int m26 = z->l - z->c; (void)m26; /* do, line 699 */ + { int ret = r_step5h(z); /* call step5h, line 699 */ + if (ret == 0) goto lab25; + if (ret < 0) return ret; + } + lab25: + z->c = z->l - m26; + } + { int m27 = z->l - z->c; (void)m27; /* do, line 700 */ + { int ret = r_step5j(z); /* call step5j, line 700 */ + if (ret == 0) goto lab26; + if (ret < 0) return ret; + } + lab26: + z->c = z->l - m27; + } + { int m28 = z->l - z->c; (void)m28; /* do, line 701 */ + { int ret = r_step5i(z); /* call step5i, line 701 */ + if (ret == 0) goto lab27; + if (ret < 0) return ret; + } + lab27: + z->c = z->l - m28; + } + { int m29 = z->l - z->c; (void)m29; /* do, line 702 */ + { int ret = r_step5k(z); /* call step5k, line 702 */ + if (ret == 0) goto lab28; + if (ret < 0) return ret; + } + lab28: + z->c = z->l - m29; + } + { int m30 = z->l - z->c; (void)m30; /* do, line 703 */ + { int ret = r_step5l(z); /* call step5l, line 703 */ + if (ret == 0) goto lab29; + if (ret < 0) return ret; + } + lab29: + z->c = z->l - m30; + } + { int m31 = z->l - z->c; (void)m31; /* do, line 704 */ + { int ret = r_step5m(z); /* call step5m, line 704 */ + if (ret == 0) goto lab30; + if (ret < 0) return ret; + } + lab30: + z->c = z->l - m31; + } + { int m32 = z->l - z->c; (void)m32; /* do, line 705 */ + { int ret = r_step6(z); /* call step6, line 705 */ + if (ret == 0) goto lab31; + if (ret < 0) return ret; + } + lab31: + z->c = z->l - m32; + } + { int m33 = z->l - z->c; (void)m33; /* do, line 706 */ + { int ret = r_step7(z); /* call step7, line 706 */ + if (ret == 0) goto lab32; + if (ret < 0) return ret; + } + lab32: + z->c = z->l - m33; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * greek_UTF_8_create_env(void) { return SN_create_env(1, 0, 1); } + +extern void greek_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 1); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c index e40df8e6c18..d8ae15aeabd 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_hungarian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -123,7 +123,7 @@ static const symbol s_3_1[2] = { 'e', 'l' }; static const struct among a_3[2] = { /* 0 */ { 2, s_3_0, -1, 1, 0}, -/* 1 */ { 2, s_3_1, -1, 2, 0} +/* 1 */ { 2, s_3_1, -1, 1, 0} }; static const symbol s_4_0[2] = { 'b', 'a' }; @@ -136,14 +136,14 @@ static const symbol s_4_6[3] = { 'n', 'e', 'k' }; static const symbol s_4_7[3] = { 'v', 'a', 'l' }; static const symbol s_4_8[3] = { 'v', 'e', 'l' }; static const symbol s_4_9[2] = { 'u', 'l' }; -static const symbol s_4_10[4] = { 'n', 0xC3, 0xA1, 'l' }; -static const symbol s_4_11[4] = { 'n', 0xC3, 0xA9, 'l' }; -static const symbol s_4_12[4] = { 'b', 0xC3, 0xB3, 'l' }; -static const symbol s_4_13[4] = { 'r', 0xC3, 0xB3, 'l' }; -static const symbol s_4_14[4] = { 't', 0xC3, 0xB3, 'l' }; -static const symbol s_4_15[4] = { 'b', 0xC3, 0xB5, 'l' }; -static const symbol s_4_16[4] = { 'r', 0xC3, 0xB5, 'l' }; -static const symbol s_4_17[4] = { 't', 0xC3, 0xB5, 'l' }; +static const symbol s_4_10[4] = { 'b', 0xC5, 0x91, 'l' }; +static const symbol s_4_11[4] = { 'r', 0xC5, 0x91, 'l' }; +static const symbol s_4_12[4] = { 't', 0xC5, 0x91, 'l' }; +static const symbol s_4_13[4] = { 'n', 0xC3, 0xA1, 'l' }; +static const symbol s_4_14[4] = { 'n', 0xC3, 0xA9, 'l' }; +static const symbol s_4_15[4] = { 'b', 0xC3, 0xB3, 'l' }; +static const symbol s_4_16[4] = { 'r', 0xC3, 0xB3, 'l' }; +static const symbol s_4_17[4] = { 't', 0xC3, 0xB3, 'l' }; static const symbol s_4_18[3] = { 0xC3, 0xBC, 'l' }; static const symbol s_4_19[1] = { 'n' }; static const symbol s_4_20[2] = { 'a', 'n' }; @@ -227,7 +227,7 @@ static const struct among a_5[3] = { /* 0 */ { 3, s_5_0, -1, 2, 0}, /* 1 */ { 3, s_5_1, -1, 1, 0}, -/* 2 */ { 8, s_5_2, -1, 3, 0} +/* 2 */ { 8, s_5_2, -1, 2, 0} }; static const symbol s_6_0[4] = { 's', 't', 'u', 'l' }; @@ -239,12 +239,12 @@ static const symbol s_6_5[7] = { 0xC3, 0xA9, 's', 't', 0xC3, 0xBC, 'l' }; static const struct among a_6[6] = { -/* 0 */ { 4, s_6_0, -1, 2, 0}, +/* 0 */ { 4, s_6_0, -1, 1, 0}, /* 1 */ { 5, s_6_1, 0, 1, 0}, -/* 2 */ { 6, s_6_2, 0, 3, 0}, -/* 3 */ { 5, s_6_3, -1, 2, 0}, +/* 2 */ { 6, s_6_2, 0, 2, 0}, +/* 3 */ { 5, s_6_3, -1, 1, 0}, /* 4 */ { 6, s_6_4, 3, 1, 0}, -/* 5 */ { 7, s_6_5, 3, 4, 0} +/* 5 */ { 7, s_6_5, 3, 3, 0} }; static const symbol s_7_0[2] = { 0xC3, 0xA1 }; @@ -253,7 +253,7 @@ static const symbol s_7_1[2] = { 0xC3, 0xA9 }; static const struct among a_7[2] = { /* 0 */ { 2, s_7_0, -1, 1, 0}, -/* 1 */ { 2, s_7_1, -1, 2, 0} +/* 1 */ { 2, s_7_1, -1, 1, 0} }; static const symbol s_8_0[1] = { 'k' }; @@ -266,10 +266,10 @@ static const symbol s_8_6[3] = { 0xC3, 0xB6, 'k' }; static const struct among a_8[7] = { -/* 0 */ { 1, s_8_0, -1, 7, 0}, -/* 1 */ { 2, s_8_1, 0, 4, 0}, -/* 2 */ { 2, s_8_2, 0, 6, 0}, -/* 3 */ { 2, s_8_3, 0, 5, 0}, +/* 0 */ { 1, s_8_0, -1, 3, 0}, +/* 1 */ { 2, s_8_1, 0, 3, 0}, +/* 2 */ { 2, s_8_2, 0, 3, 0}, +/* 3 */ { 2, s_8_3, 0, 3, 0}, /* 4 */ { 3, s_8_4, 0, 1, 0}, /* 5 */ { 3, s_8_5, 0, 2, 0}, /* 6 */ { 3, s_8_6, 0, 3, 0} @@ -290,18 +290,18 @@ static const symbol s_9_11[4] = { 0xC3, 0xA9, 0xC3, 0xA9 }; static const struct among a_9[12] = { -/* 0 */ { 3, s_9_0, -1, 7, 0}, -/* 1 */ { 5, s_9_1, 0, 6, 0}, -/* 2 */ { 5, s_9_2, 0, 5, 0}, -/* 3 */ { 2, s_9_3, -1, 9, 0}, -/* 4 */ { 3, s_9_4, 3, 4, 0}, +/* 0 */ { 3, s_9_0, -1, 1, 0}, +/* 1 */ { 5, s_9_1, 0, 3, 0}, +/* 2 */ { 5, s_9_2, 0, 2, 0}, +/* 3 */ { 2, s_9_3, -1, 1, 0}, +/* 4 */ { 3, s_9_4, 3, 1, 0}, /* 5 */ { 4, s_9_5, 4, 1, 0}, /* 6 */ { 4, s_9_6, 4, 1, 0}, /* 7 */ { 4, s_9_7, 4, 1, 0}, /* 8 */ { 5, s_9_8, 4, 3, 0}, /* 9 */ { 5, s_9_9, 4, 2, 0}, /* 10 */ { 5, s_9_10, 4, 1, 0}, -/* 11 */ { 4, s_9_11, 3, 8, 0} +/* 11 */ { 4, s_9_11, 3, 2, 0} }; static const symbol s_10_0[1] = { 'a' }; @@ -338,37 +338,37 @@ static const symbol s_10_30[2] = { 0xC3, 0xA9 }; static const struct among a_10[31] = { -/* 0 */ { 1, s_10_0, -1, 18, 0}, -/* 1 */ { 2, s_10_1, 0, 17, 0}, -/* 2 */ { 1, s_10_2, -1, 16, 0}, -/* 3 */ { 2, s_10_3, 2, 13, 0}, -/* 4 */ { 2, s_10_4, 2, 13, 0}, -/* 5 */ { 2, s_10_5, 2, 13, 0}, -/* 6 */ { 3, s_10_6, 2, 14, 0}, -/* 7 */ { 3, s_10_7, 2, 15, 0}, -/* 8 */ { 3, s_10_8, 2, 13, 0}, -/* 9 */ { 1, s_10_9, -1, 18, 0}, -/* 10 */ { 2, s_10_10, 9, 17, 0}, -/* 11 */ { 2, s_10_11, -1, 4, 0}, +/* 0 */ { 1, s_10_0, -1, 1, 0}, +/* 1 */ { 2, s_10_1, 0, 1, 0}, +/* 2 */ { 1, s_10_2, -1, 1, 0}, +/* 3 */ { 2, s_10_3, 2, 1, 0}, +/* 4 */ { 2, s_10_4, 2, 1, 0}, +/* 5 */ { 2, s_10_5, 2, 1, 0}, +/* 6 */ { 3, s_10_6, 2, 2, 0}, +/* 7 */ { 3, s_10_7, 2, 3, 0}, +/* 8 */ { 3, s_10_8, 2, 1, 0}, +/* 9 */ { 1, s_10_9, -1, 1, 0}, +/* 10 */ { 2, s_10_10, 9, 1, 0}, +/* 11 */ { 2, s_10_11, -1, 1, 0}, /* 12 */ { 3, s_10_12, 11, 1, 0}, /* 13 */ { 4, s_10_13, 11, 2, 0}, /* 14 */ { 4, s_10_14, 11, 3, 0}, /* 15 */ { 4, s_10_15, 11, 1, 0}, -/* 16 */ { 2, s_10_16, -1, 8, 0}, -/* 17 */ { 3, s_10_17, 16, 7, 0}, -/* 18 */ { 5, s_10_18, 17, 5, 0}, -/* 19 */ { 3, s_10_19, -1, 8, 0}, -/* 20 */ { 4, s_10_20, 19, 7, 0}, -/* 21 */ { 6, s_10_21, 20, 6, 0}, -/* 22 */ { 1, s_10_22, -1, 12, 0}, -/* 23 */ { 2, s_10_23, 22, 9, 0}, -/* 24 */ { 2, s_10_24, 22, 9, 0}, -/* 25 */ { 2, s_10_25, 22, 9, 0}, -/* 26 */ { 3, s_10_26, 22, 10, 0}, -/* 27 */ { 3, s_10_27, 22, 11, 0}, -/* 28 */ { 1, s_10_28, -1, 18, 0}, -/* 29 */ { 2, s_10_29, -1, 19, 0}, -/* 30 */ { 2, s_10_30, -1, 20, 0} +/* 16 */ { 2, s_10_16, -1, 1, 0}, +/* 17 */ { 3, s_10_17, 16, 1, 0}, +/* 18 */ { 5, s_10_18, 17, 2, 0}, +/* 19 */ { 3, s_10_19, -1, 1, 0}, +/* 20 */ { 4, s_10_20, 19, 1, 0}, +/* 21 */ { 6, s_10_21, 20, 3, 0}, +/* 22 */ { 1, s_10_22, -1, 1, 0}, +/* 23 */ { 2, s_10_23, 22, 1, 0}, +/* 24 */ { 2, s_10_24, 22, 1, 0}, +/* 25 */ { 2, s_10_25, 22, 1, 0}, +/* 26 */ { 3, s_10_26, 22, 2, 0}, +/* 27 */ { 3, s_10_27, 22, 3, 0}, +/* 28 */ { 1, s_10_28, -1, 1, 0}, +/* 29 */ { 2, s_10_29, -1, 2, 0}, +/* 30 */ { 2, s_10_30, -1, 3, 0} }; static const symbol s_11_0[2] = { 'i', 'd' }; @@ -416,97 +416,75 @@ static const symbol s_11_41[4] = { 0xC3, 0xA9, 'i', 'm' }; static const struct among a_11[42] = { -/* 0 */ { 2, s_11_0, -1, 10, 0}, -/* 1 */ { 3, s_11_1, 0, 9, 0}, -/* 2 */ { 4, s_11_2, 1, 6, 0}, -/* 3 */ { 3, s_11_3, 0, 9, 0}, -/* 4 */ { 4, s_11_4, 3, 6, 0}, -/* 5 */ { 4, s_11_5, 0, 7, 0}, -/* 6 */ { 4, s_11_6, 0, 8, 0}, -/* 7 */ { 1, s_11_7, -1, 15, 0}, -/* 8 */ { 2, s_11_8, 7, 14, 0}, -/* 9 */ { 3, s_11_9, 8, 11, 0}, -/* 10 */ { 2, s_11_10, 7, 14, 0}, -/* 11 */ { 3, s_11_11, 10, 11, 0}, -/* 12 */ { 3, s_11_12, 7, 12, 0}, -/* 13 */ { 3, s_11_13, 7, 13, 0}, -/* 14 */ { 4, s_11_14, -1, 24, 0}, -/* 15 */ { 5, s_11_15, 14, 21, 0}, -/* 16 */ { 6, s_11_16, 15, 20, 0}, -/* 17 */ { 6, s_11_17, 14, 23, 0}, -/* 18 */ { 2, s_11_18, -1, 29, 0}, -/* 19 */ { 3, s_11_19, 18, 26, 0}, -/* 20 */ { 4, s_11_20, 19, 25, 0}, -/* 21 */ { 3, s_11_21, 18, 26, 0}, -/* 22 */ { 4, s_11_22, 21, 25, 0}, -/* 23 */ { 4, s_11_23, 18, 27, 0}, -/* 24 */ { 4, s_11_24, 18, 28, 0}, -/* 25 */ { 3, s_11_25, -1, 20, 0}, -/* 26 */ { 4, s_11_26, 25, 17, 0}, -/* 27 */ { 5, s_11_27, 26, 16, 0}, -/* 28 */ { 4, s_11_28, 25, 17, 0}, -/* 29 */ { 5, s_11_29, 28, 16, 0}, -/* 30 */ { 5, s_11_30, 25, 18, 0}, -/* 31 */ { 5, s_11_31, 25, 19, 0}, -/* 32 */ { 5, s_11_32, -1, 21, 0}, -/* 33 */ { 6, s_11_33, 32, 20, 0}, -/* 34 */ { 6, s_11_34, -1, 22, 0}, -/* 35 */ { 2, s_11_35, -1, 5, 0}, -/* 36 */ { 3, s_11_36, 35, 4, 0}, +/* 0 */ { 2, s_11_0, -1, 1, 0}, +/* 1 */ { 3, s_11_1, 0, 1, 0}, +/* 2 */ { 4, s_11_2, 1, 1, 0}, +/* 3 */ { 3, s_11_3, 0, 1, 0}, +/* 4 */ { 4, s_11_4, 3, 1, 0}, +/* 5 */ { 4, s_11_5, 0, 2, 0}, +/* 6 */ { 4, s_11_6, 0, 3, 0}, +/* 7 */ { 1, s_11_7, -1, 1, 0}, +/* 8 */ { 2, s_11_8, 7, 1, 0}, +/* 9 */ { 3, s_11_9, 8, 1, 0}, +/* 10 */ { 2, s_11_10, 7, 1, 0}, +/* 11 */ { 3, s_11_11, 10, 1, 0}, +/* 12 */ { 3, s_11_12, 7, 2, 0}, +/* 13 */ { 3, s_11_13, 7, 3, 0}, +/* 14 */ { 4, s_11_14, -1, 1, 0}, +/* 15 */ { 5, s_11_15, 14, 1, 0}, +/* 16 */ { 6, s_11_16, 15, 1, 0}, +/* 17 */ { 6, s_11_17, 14, 3, 0}, +/* 18 */ { 2, s_11_18, -1, 1, 0}, +/* 19 */ { 3, s_11_19, 18, 1, 0}, +/* 20 */ { 4, s_11_20, 19, 1, 0}, +/* 21 */ { 3, s_11_21, 18, 1, 0}, +/* 22 */ { 4, s_11_22, 21, 1, 0}, +/* 23 */ { 4, s_11_23, 18, 2, 0}, +/* 24 */ { 4, s_11_24, 18, 3, 0}, +/* 25 */ { 3, s_11_25, -1, 1, 0}, +/* 26 */ { 4, s_11_26, 25, 1, 0}, +/* 27 */ { 5, s_11_27, 26, 1, 0}, +/* 28 */ { 4, s_11_28, 25, 1, 0}, +/* 29 */ { 5, s_11_29, 28, 1, 0}, +/* 30 */ { 5, s_11_30, 25, 2, 0}, +/* 31 */ { 5, s_11_31, 25, 3, 0}, +/* 32 */ { 5, s_11_32, -1, 1, 0}, +/* 33 */ { 6, s_11_33, 32, 1, 0}, +/* 34 */ { 6, s_11_34, -1, 2, 0}, +/* 35 */ { 2, s_11_35, -1, 1, 0}, +/* 36 */ { 3, s_11_36, 35, 1, 0}, /* 37 */ { 4, s_11_37, 36, 1, 0}, -/* 38 */ { 3, s_11_38, 35, 4, 0}, +/* 38 */ { 3, s_11_38, 35, 1, 0}, /* 39 */ { 4, s_11_39, 38, 1, 0}, /* 40 */ { 4, s_11_40, 35, 2, 0}, /* 41 */ { 4, s_11_41, 35, 3, 0} }; -static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 52, 14 }; +static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 36, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 }; static const symbol s_0[] = { 'a' }; static const symbol s_1[] = { 'e' }; static const symbol s_2[] = { 'e' }; static const symbol s_3[] = { 'a' }; static const symbol s_4[] = { 'a' }; -static const symbol s_5[] = { 'a' }; -static const symbol s_6[] = { 'e' }; -static const symbol s_7[] = { 'a' }; +static const symbol s_5[] = { 'e' }; +static const symbol s_6[] = { 'a' }; +static const symbol s_7[] = { 'e' }; static const symbol s_8[] = { 'e' }; -static const symbol s_9[] = { 'e' }; +static const symbol s_9[] = { 'a' }; static const symbol s_10[] = { 'a' }; static const symbol s_11[] = { 'e' }; static const symbol s_12[] = { 'a' }; static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'a' }; -static const symbol s_15[] = { 'e' }; -static const symbol s_16[] = { 'a' }; -static const symbol s_17[] = { 'e' }; -static const symbol s_18[] = { 'a' }; -static const symbol s_19[] = { 'e' }; -static const symbol s_20[] = { 'a' }; -static const symbol s_21[] = { 'e' }; -static const symbol s_22[] = { 'a' }; -static const symbol s_23[] = { 'e' }; -static const symbol s_24[] = { 'a' }; -static const symbol s_25[] = { 'e' }; -static const symbol s_26[] = { 'a' }; -static const symbol s_27[] = { 'e' }; -static const symbol s_28[] = { 'a' }; -static const symbol s_29[] = { 'e' }; -static const symbol s_30[] = { 'a' }; -static const symbol s_31[] = { 'e' }; -static const symbol s_32[] = { 'a' }; -static const symbol s_33[] = { 'e' }; -static const symbol s_34[] = { 'a' }; -static const symbol s_35[] = { 'e' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 46 */ { int c1 = z->c; /* or, line 51 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab1; - if (in_grouping_U(z, g_v, 97, 252, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */ + if (in_grouping_U(z, g_v, 97, 369, 0)) goto lab1; /* grouping v, line 48 */ + if (in_grouping_U(z, g_v, 97, 369, 1) < 0) goto lab1; /* goto */ /* non v, line 48 */ { int c2 = z->c; /* or, line 49 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; - if (!(find_among(z, a_0, 8))) goto lab3; /* among, line 49 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 3 || !((101187584 >> (z->p[z->c + 1] & 0x1f)) & 1)) goto lab3; /* among, line 49 */ + if (!(find_among(z, a_0, 8))) goto lab3; goto lab2; lab3: z->c = c2; @@ -520,9 +498,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab0; lab1: z->c = c1; - if (out_grouping_U(z, g_v, 97, 252, 0)) return 0; + if (out_grouping_U(z, g_v, 97, 369, 0)) return 0; /* non v, line 53 */ { /* gopast */ /* grouping v, line 53 */ - int ret = out_grouping_U(z, g_v, 97, 252, 1); + int ret = out_grouping_U(z, g_v, 97, 369, 1); if (ret < 0) return 0; z->c += ret; } @@ -532,24 +510,22 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 58 */ return 1; } -static int r_v_ending(struct SN_env * z) { +static int r_v_ending(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 61 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; - among_var = find_among_b(z, a_1, 2); /* substring, line 61 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; /* substring, line 61 */ + among_var = find_among_b(z, a_1, 2); if (!(among_var)) return 0; z->bra = z->c; /* ], line 61 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 61 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 61 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 61 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 62 */ if (ret < 0) return ret; @@ -564,24 +540,24 @@ static int r_v_ending(struct SN_env * z) { return 1; } -static int r_double(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 23))) return 0; /* among, line 68 */ - z->c = z->l - m_test; +static int r_double(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 68 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((106790108 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 68 */ + if (!(find_among_b(z, a_2, 23))) return 0; + z->c = z->l - m_test1; } return 1; } -static int r_undouble(struct SN_env * z) { +static int r_undouble(struct SN_env * z) { /* backwardmode */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; z->c = ret; /* next, line 73 */ } z->ket = z->c; /* [, line 73 */ - { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 1); + { int ret = skip_utf8(z->p, z->c, z->lb, z->l, - 1); /* hop, line 73 */ if (ret < 0) return 0; - z->c = ret; /* hop, line 73 */ + z->c = ret; } z->bra = z->c; /* ], line 73 */ { int ret = slice_del(z); /* delete, line 73 */ @@ -590,73 +566,53 @@ static int r_undouble(struct SN_env * z) { return 1; } -static int r_instrum(struct SN_env * z) { - int among_var; +static int r_instrum(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 77 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; - among_var = find_among_b(z, a_3, 2); /* substring, line 77 */ - if (!(among_var)) return 0; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 77 */ + if (!(find_among_b(z, a_3, 2))) return 0; z->bra = z->c; /* ], line 77 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 77 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 77 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 78 */ - if (ret < 0) return ret; - } - break; - case 2: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 79 */ - if (ret < 0) return ret; - } - break; + { int ret = r_double(z); /* call double, line 78 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 81 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 82 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 82 */ + if (ret <= 0) return ret; } return 1; } -static int r_case(struct SN_env * z) { +static int r_case(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 87 */ if (!(find_among_b(z, a_4, 44))) return 0; /* substring, line 87 */ z->bra = z->c; /* ], line 87 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 87 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 87 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 111 */ if (ret < 0) return ret; } - { int ret = r_v_ending(z); - if (ret == 0) return 0; /* call v_ending, line 112 */ - if (ret < 0) return ret; + { int ret = r_v_ending(z); /* call v_ending, line 112 */ + if (ret <= 0) return ret; } return 1; } -static int r_case_special(struct SN_env * z) { +static int r_case_special(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 116 */ - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; - among_var = find_among_b(z, a_5, 3); /* substring, line 116 */ + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 110 && z->p[z->c - 1] != 116)) return 0; /* substring, line 116 */ + among_var = find_among_b(z, a_5, 3); if (!(among_var)) return 0; z->bra = z->c; /* ], line 116 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 116 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 116 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 116 */ case 1: { int ret = slice_from_s(z, 1, s_2); /* <-, line 117 */ if (ret < 0) return ret; @@ -667,45 +623,33 @@ static int r_case_special(struct SN_env * z) { if (ret < 0) return ret; } break; - case 3: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 119 */ - if (ret < 0) return ret; - } - break; } return 1; } -static int r_case_other(struct SN_env * z) { +static int r_case_other(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; - among_var = find_among_b(z, a_6, 6); /* substring, line 124 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 108) return 0; /* substring, line 124 */ + among_var = find_among_b(z, a_6, 6); if (!(among_var)) return 0; z->bra = z->c; /* ], line 124 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 124 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 124 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 124 */ case 1: { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 126 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 127 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 127 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 128 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 128 */ if (ret < 0) return ret; } break; @@ -713,62 +657,44 @@ static int r_case_other(struct SN_env * z) { return 1; } -static int r_factive(struct SN_env * z) { - int among_var; +static int r_factive(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 133 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; - among_var = find_among_b(z, a_7, 2); /* substring, line 133 */ - if (!(among_var)) return 0; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 161 && z->p[z->c - 1] != 169)) return 0; /* substring, line 133 */ + if (!(find_among_b(z, a_7, 2))) return 0; z->bra = z->c; /* ], line 133 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 133 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 133 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 134 */ - if (ret < 0) return ret; - } - break; - case 2: - { int ret = r_double(z); - if (ret == 0) return 0; /* call double, line 135 */ - if (ret < 0) return ret; - } - break; + { int ret = r_double(z); /* call double, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 137 */ if (ret < 0) return ret; } - { int ret = r_undouble(z); - if (ret == 0) return 0; /* call undouble, line 138 */ - if (ret < 0) return ret; + { int ret = r_undouble(z); /* call undouble, line 138 */ + if (ret <= 0) return ret; } return 1; } -static int r_plural(struct SN_env * z) { +static int r_plural(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 142 */ - if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; - among_var = find_among_b(z, a_8, 7); /* substring, line 142 */ + if (z->c <= z->lb || z->p[z->c - 1] != 107) return 0; /* substring, line 142 */ + among_var = find_among_b(z, a_8, 7); if (!(among_var)) return 0; z->bra = z->c; /* ], line 142 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 142 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 142 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 142 */ case 1: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 143 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 143 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 144 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 144 */ if (ret < 0) return ret; } break; @@ -777,85 +703,33 @@ static int r_plural(struct SN_env * z) { if (ret < 0) return ret; } break; - case 4: - { int ret = slice_del(z); /* delete, line 146 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_del(z); /* delete, line 147 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_del(z); /* delete, line 148 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 149 */ - if (ret < 0) return ret; - } - break; } return 1; } -static int r_owned(struct SN_env * z) { +static int r_owned(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 154 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 169)) return 0; - among_var = find_among_b(z, a_9, 12); /* substring, line 154 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 169)) return 0; /* substring, line 154 */ + among_var = find_among_b(z, a_9, 12); if (!(among_var)) return 0; z->bra = z->c; /* ], line 154 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 154 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 154 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 154 */ case 1: { int ret = slice_del(z); /* delete, line 155 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_9); /* <-, line 156 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 156 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 157 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 158 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 159 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 160 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 161 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 162 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 163 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 157 */ if (ret < 0) return ret; } break; @@ -863,115 +737,28 @@ static int r_owned(struct SN_env * z) { return 1; } -static int r_sing_owner(struct SN_env * z) { +static int r_sing_owner(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 168 */ among_var = find_among_b(z, a_10, 31); /* substring, line 168 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 168 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 168 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 168 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 168 */ case 1: { int ret = slice_del(z); /* delete, line 169 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_14); /* <-, line 170 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 170 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_15); /* <-, line 171 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 172 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_from_s(z, 1, s_16); /* <-, line 173 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_from_s(z, 1, s_17); /* <-, line 174 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_del(z); /* delete, line 175 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_del(z); /* delete, line 176 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 177 */ - if (ret < 0) return ret; - } - break; - case 10: - { int ret = slice_from_s(z, 1, s_18); /* <-, line 178 */ - if (ret < 0) return ret; - } - break; - case 11: - { int ret = slice_from_s(z, 1, s_19); /* <-, line 179 */ - if (ret < 0) return ret; - } - break; - case 12: - { int ret = slice_del(z); /* delete, line 180 */ - if (ret < 0) return ret; - } - break; - case 13: - { int ret = slice_del(z); /* delete, line 181 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_from_s(z, 1, s_20); /* <-, line 182 */ - if (ret < 0) return ret; - } - break; - case 15: - { int ret = slice_from_s(z, 1, s_21); /* <-, line 183 */ - if (ret < 0) return ret; - } - break; - case 16: - { int ret = slice_del(z); /* delete, line 184 */ - if (ret < 0) return ret; - } - break; - case 17: - { int ret = slice_del(z); /* delete, line 185 */ - if (ret < 0) return ret; - } - break; - case 18: - { int ret = slice_del(z); /* delete, line 186 */ - if (ret < 0) return ret; - } - break; - case 19: - { int ret = slice_from_s(z, 1, s_22); /* <-, line 187 */ - if (ret < 0) return ret; - } - break; - case 20: - { int ret = slice_from_s(z, 1, s_23); /* <-, line 188 */ + { int ret = slice_from_s(z, 1, s_11); /* <-, line 171 */ if (ret < 0) return ret; } break; @@ -979,161 +766,29 @@ static int r_sing_owner(struct SN_env * z) { return 1; } -static int r_plur_owner(struct SN_env * z) { +static int r_plur_owner(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 193 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_11, 42); /* substring, line 193 */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((10768 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 193 */ + among_var = find_among_b(z, a_11, 42); if (!(among_var)) return 0; z->bra = z->c; /* ], line 193 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 193 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 193 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 193 */ case 1: { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_24); /* <-, line 195 */ + { int ret = slice_from_s(z, 1, s_12); /* <-, line 195 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_25); /* <-, line 196 */ - if (ret < 0) return ret; - } - break; - case 4: - { int ret = slice_del(z); /* delete, line 197 */ - if (ret < 0) return ret; - } - break; - case 5: - { int ret = slice_del(z); /* delete, line 198 */ - if (ret < 0) return ret; - } - break; - case 6: - { int ret = slice_del(z); /* delete, line 199 */ - if (ret < 0) return ret; - } - break; - case 7: - { int ret = slice_from_s(z, 1, s_26); /* <-, line 200 */ - if (ret < 0) return ret; - } - break; - case 8: - { int ret = slice_from_s(z, 1, s_27); /* <-, line 201 */ - if (ret < 0) return ret; - } - break; - case 9: - { int ret = slice_del(z); /* delete, line 202 */ - if (ret < 0) return ret; - } - break; - case 10: - { int ret = slice_del(z); /* delete, line 203 */ - if (ret < 0) return ret; - } - break; - case 11: - { int ret = slice_del(z); /* delete, line 204 */ - if (ret < 0) return ret; - } - break; - case 12: - { int ret = slice_from_s(z, 1, s_28); /* <-, line 205 */ - if (ret < 0) return ret; - } - break; - case 13: - { int ret = slice_from_s(z, 1, s_29); /* <-, line 206 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_del(z); /* delete, line 207 */ - if (ret < 0) return ret; - } - break; - case 15: - { int ret = slice_del(z); /* delete, line 208 */ - if (ret < 0) return ret; - } - break; - case 16: - { int ret = slice_del(z); /* delete, line 209 */ - if (ret < 0) return ret; - } - break; - case 17: - { int ret = slice_del(z); /* delete, line 210 */ - if (ret < 0) return ret; - } - break; - case 18: - { int ret = slice_from_s(z, 1, s_30); /* <-, line 211 */ - if (ret < 0) return ret; - } - break; - case 19: - { int ret = slice_from_s(z, 1, s_31); /* <-, line 212 */ - if (ret < 0) return ret; - } - break; - case 20: - { int ret = slice_del(z); /* delete, line 214 */ - if (ret < 0) return ret; - } - break; - case 21: - { int ret = slice_del(z); /* delete, line 215 */ - if (ret < 0) return ret; - } - break; - case 22: - { int ret = slice_from_s(z, 1, s_32); /* <-, line 216 */ - if (ret < 0) return ret; - } - break; - case 23: - { int ret = slice_from_s(z, 1, s_33); /* <-, line 217 */ - if (ret < 0) return ret; - } - break; - case 24: - { int ret = slice_del(z); /* delete, line 218 */ - if (ret < 0) return ret; - } - break; - case 25: - { int ret = slice_del(z); /* delete, line 219 */ - if (ret < 0) return ret; - } - break; - case 26: - { int ret = slice_del(z); /* delete, line 220 */ - if (ret < 0) return ret; - } - break; - case 27: - { int ret = slice_from_s(z, 1, s_34); /* <-, line 221 */ - if (ret < 0) return ret; - } - break; - case 28: - { int ret = slice_from_s(z, 1, s_35); /* <-, line 222 */ - if (ret < 0) return ret; - } - break; - case 29: - { int ret = slice_del(z); /* delete, line 223 */ + { int ret = slice_from_s(z, 1, s_13); /* <-, line 196 */ if (ret < 0) return ret; } break; @@ -1141,10 +796,10 @@ static int r_plur_owner(struct SN_env * z) { return 1; } -extern int hungarian_UTF_8_stem(struct SN_env * z) { +extern int hungarian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 229 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 229 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 229 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -1153,72 +808,72 @@ extern int hungarian_UTF_8_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 230 */ { int m2 = z->l - z->c; (void)m2; /* do, line 231 */ - { int ret = r_instrum(z); - if (ret == 0) goto lab1; /* call instrum, line 231 */ + { int ret = r_instrum(z); /* call instrum, line 231 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 232 */ - { int ret = r_case(z); - if (ret == 0) goto lab2; /* call case, line 232 */ + { int ret = r_case(z); /* call case, line 232 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 233 */ - { int ret = r_case_special(z); - if (ret == 0) goto lab3; /* call case_special, line 233 */ + { int ret = r_case_special(z); /* call case_special, line 233 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: z->c = z->l - m4; } { int m5 = z->l - z->c; (void)m5; /* do, line 234 */ - { int ret = r_case_other(z); - if (ret == 0) goto lab4; /* call case_other, line 234 */ + { int ret = r_case_other(z); /* call case_other, line 234 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } lab4: z->c = z->l - m5; } { int m6 = z->l - z->c; (void)m6; /* do, line 235 */ - { int ret = r_factive(z); - if (ret == 0) goto lab5; /* call factive, line 235 */ + { int ret = r_factive(z); /* call factive, line 235 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } lab5: z->c = z->l - m6; } { int m7 = z->l - z->c; (void)m7; /* do, line 236 */ - { int ret = r_owned(z); - if (ret == 0) goto lab6; /* call owned, line 236 */ + { int ret = r_owned(z); /* call owned, line 236 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: z->c = z->l - m7; } { int m8 = z->l - z->c; (void)m8; /* do, line 237 */ - { int ret = r_sing_owner(z); - if (ret == 0) goto lab7; /* call sing_owner, line 237 */ + { int ret = r_sing_owner(z); /* call sing_owner, line 237 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: z->c = z->l - m8; } { int m9 = z->l - z->c; (void)m9; /* do, line 238 */ - { int ret = r_plur_owner(z); - if (ret == 0) goto lab8; /* call plur_owner, line 238 */ + { int ret = r_plur_owner(z); /* call plur_owner, line 238 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: z->c = z->l - m9; } { int m10 = z->l - z->c; (void)m10; /* do, line 239 */ - { int ret = r_plural(z); - if (ret == 0) goto lab9; /* call plural, line 239 */ + { int ret = r_plural(z); /* call plural, line 239 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c b/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c new file mode 100644 index 00000000000..846e6e76bf7 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_indonesian.c @@ -0,0 +1,414 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int indonesian_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_VOWEL(struct SN_env * z); +static int r_SUFFIX_I_OK(struct SN_env * z); +static int r_SUFFIX_AN_OK(struct SN_env * z); +static int r_SUFFIX_KAN_OK(struct SN_env * z); +static int r_KER(struct SN_env * z); +static int r_remove_suffix(struct SN_env * z); +static int r_remove_second_order_prefix(struct SN_env * z); +static int r_remove_first_order_prefix(struct SN_env * z); +static int r_remove_possessive_pronoun(struct SN_env * z); +static int r_remove_particle(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * indonesian_UTF_8_create_env(void); +extern void indonesian_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[3] = { 'k', 'a', 'h' }; +static const symbol s_0_1[3] = { 'l', 'a', 'h' }; +static const symbol s_0_2[3] = { 'p', 'u', 'n' }; + +static const struct among a_0[3] = +{ +/* 0 */ { 3, s_0_0, -1, 1, 0}, +/* 1 */ { 3, s_0_1, -1, 1, 0}, +/* 2 */ { 3, s_0_2, -1, 1, 0} +}; + +static const symbol s_1_0[3] = { 'n', 'y', 'a' }; +static const symbol s_1_1[2] = { 'k', 'u' }; +static const symbol s_1_2[2] = { 'm', 'u' }; + +static const struct among a_1[3] = +{ +/* 0 */ { 3, s_1_0, -1, 1, 0}, +/* 1 */ { 2, s_1_1, -1, 1, 0}, +/* 2 */ { 2, s_1_2, -1, 1, 0} +}; + +static const symbol s_2_0[1] = { 'i' }; +static const symbol s_2_1[2] = { 'a', 'n' }; +static const symbol s_2_2[3] = { 'k', 'a', 'n' }; + +static const struct among a_2[3] = +{ +/* 0 */ { 1, s_2_0, -1, 1, r_SUFFIX_I_OK}, +/* 1 */ { 2, s_2_1, -1, 1, r_SUFFIX_AN_OK}, +/* 2 */ { 3, s_2_2, 1, 1, r_SUFFIX_KAN_OK} +}; + +static const symbol s_3_0[2] = { 'd', 'i' }; +static const symbol s_3_1[2] = { 'k', 'e' }; +static const symbol s_3_2[2] = { 'm', 'e' }; +static const symbol s_3_3[3] = { 'm', 'e', 'm' }; +static const symbol s_3_4[3] = { 'm', 'e', 'n' }; +static const symbol s_3_5[4] = { 'm', 'e', 'n', 'g' }; +static const symbol s_3_6[4] = { 'm', 'e', 'n', 'y' }; +static const symbol s_3_7[3] = { 'p', 'e', 'm' }; +static const symbol s_3_8[3] = { 'p', 'e', 'n' }; +static const symbol s_3_9[4] = { 'p', 'e', 'n', 'g' }; +static const symbol s_3_10[4] = { 'p', 'e', 'n', 'y' }; +static const symbol s_3_11[3] = { 't', 'e', 'r' }; + +static const struct among a_3[12] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 2, s_3_1, -1, 2, 0}, +/* 2 */ { 2, s_3_2, -1, 1, 0}, +/* 3 */ { 3, s_3_3, 2, 5, 0}, +/* 4 */ { 3, s_3_4, 2, 1, 0}, +/* 5 */ { 4, s_3_5, 4, 1, 0}, +/* 6 */ { 4, s_3_6, 4, 3, r_VOWEL}, +/* 7 */ { 3, s_3_7, -1, 6, 0}, +/* 8 */ { 3, s_3_8, -1, 2, 0}, +/* 9 */ { 4, s_3_9, 8, 2, 0}, +/* 10 */ { 4, s_3_10, 8, 4, r_VOWEL}, +/* 11 */ { 3, s_3_11, -1, 1, 0} +}; + +static const symbol s_4_0[2] = { 'b', 'e' }; +static const symbol s_4_1[7] = { 'b', 'e', 'l', 'a', 'j', 'a', 'r' }; +static const symbol s_4_2[3] = { 'b', 'e', 'r' }; +static const symbol s_4_3[2] = { 'p', 'e' }; +static const symbol s_4_4[7] = { 'p', 'e', 'l', 'a', 'j', 'a', 'r' }; +static const symbol s_4_5[3] = { 'p', 'e', 'r' }; + +static const struct among a_4[6] = +{ +/* 0 */ { 2, s_4_0, -1, 3, r_KER}, +/* 1 */ { 7, s_4_1, 0, 4, 0}, +/* 2 */ { 3, s_4_2, 0, 3, 0}, +/* 3 */ { 2, s_4_3, -1, 1, 0}, +/* 4 */ { 7, s_4_4, 3, 2, 0}, +/* 5 */ { 3, s_4_5, 3, 1, 0} +}; + +static const unsigned char g_vowel[] = { 17, 65, 16 }; + +static const symbol s_0[] = { 'e', 'r' }; +static const symbol s_1[] = { 's' }; +static const symbol s_2[] = { 's' }; +static const symbol s_3[] = { 'p' }; +static const symbol s_4[] = { 'p' }; +static const symbol s_5[] = { 'a', 'j', 'a', 'r' }; +static const symbol s_6[] = { 'a', 'j', 'a', 'r' }; + +static int r_remove_particle(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 51 */ + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 104 && z->p[z->c - 1] != 110)) return 0; /* substring, line 51 */ + if (!(find_among_b(z, a_0, 3))) return 0; + z->bra = z->c; /* ], line 51 */ + { int ret = slice_del(z); /* delete, line 52 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 52 */ + return 1; +} + +static int r_remove_possessive_pronoun(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 57 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 117)) return 0; /* substring, line 57 */ + if (!(find_among_b(z, a_1, 3))) return 0; + z->bra = z->c; /* ], line 57 */ + { int ret = slice_del(z); /* delete, line 58 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 58 */ + return 1; +} + +static int r_SUFFIX_KAN_OK(struct SN_env * z) { /* backwardmode */ + /* and, line 85 */ + if (!(z->I[1] != 3)) return 0; /* $( != ), line 85 */ + if (!(z->I[1] != 2)) return 0; /* $( != ), line 85 */ + return 1; +} + +static int r_SUFFIX_AN_OK(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] != 1)) return 0; /* $( != ), line 89 */ + return 1; +} + +static int r_SUFFIX_I_OK(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= 2)) return 0; /* $( <= ), line 93 */ + { int m1 = z->l - z->c; (void)m1; /* not, line 128 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab0; /* literal, line 128 */ + z->c--; + return 0; + lab0: + z->c = z->l - m1; + } + return 1; +} + +static int r_remove_suffix(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 132 */ + if (z->c <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 110)) return 0; /* substring, line 132 */ + if (!(find_among_b(z, a_2, 3))) return 0; + z->bra = z->c; /* ], line 132 */ + { int ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 134 */ + return 1; +} + +static int r_VOWEL(struct SN_env * z) { /* forwardmode */ + if (in_grouping_U(z, g_vowel, 97, 117, 0)) return 0; /* grouping vowel, line 141 */ + return 1; +} + +static int r_KER(struct SN_env * z) { /* forwardmode */ + if (out_grouping_U(z, g_vowel, 97, 117, 0)) return 0; /* non vowel, line 143 */ + if (!(eq_s(z, 2, s_0))) return 0; /* literal, line 143 */ + return 1; +} + +static int r_remove_first_order_prefix(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 146 */ + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 105 && z->p[z->c + 1] != 101)) return 0; /* substring, line 146 */ + among_var = find_among(z, a_3, 12); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 146 */ + switch (among_var) { /* among, line 146 */ + case 1: + { int ret = slice_del(z); /* delete, line 147 */ + if (ret < 0) return ret; + } + z->I[1] = 1; /* $prefix = , line 147 */ + z->I[0] -= 1; /* $measure -= , line 147 */ + break; + case 2: + { int ret = slice_del(z); /* delete, line 148 */ + if (ret < 0) return ret; + } + z->I[1] = 3; /* $prefix = , line 148 */ + z->I[0] -= 1; /* $measure -= , line 148 */ + break; + case 3: + z->I[1] = 1; /* $prefix = , line 149 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 149 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 149 */ + break; + case 4: + z->I[1] = 3; /* $prefix = , line 150 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 150 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 150 */ + break; + case 5: + z->I[1] = 1; /* $prefix = , line 151 */ + z->I[0] -= 1; /* $measure -= , line 151 */ + { int c1 = z->c; /* or, line 151 */ + { int c2 = z->c; /* and, line 151 */ + if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab1; /* grouping vowel, line 151 */ + z->c = c2; + { int ret = slice_from_s(z, 1, s_3); /* <-, line 151 */ + if (ret < 0) return ret; + } + } + goto lab0; + lab1: + z->c = c1; + { int ret = slice_del(z); /* delete, line 151 */ + if (ret < 0) return ret; + } + } + lab0: + break; + case 6: + z->I[1] = 3; /* $prefix = , line 152 */ + z->I[0] -= 1; /* $measure -= , line 152 */ + { int c3 = z->c; /* or, line 152 */ + { int c4 = z->c; /* and, line 152 */ + if (in_grouping_U(z, g_vowel, 97, 117, 0)) goto lab3; /* grouping vowel, line 152 */ + z->c = c4; + { int ret = slice_from_s(z, 1, s_4); /* <-, line 152 */ + if (ret < 0) return ret; + } + } + goto lab2; + lab3: + z->c = c3; + { int ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; + } + } + lab2: + break; + } + return 1; +} + +static int r_remove_second_order_prefix(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 162 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] != 101) return 0; /* substring, line 162 */ + among_var = find_among(z, a_4, 6); + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 162 */ + switch (among_var) { /* among, line 162 */ + case 1: + { int ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; + } + z->I[1] = 2; /* $prefix = , line 163 */ + z->I[0] -= 1; /* $measure -= , line 163 */ + break; + case 2: + { int ret = slice_from_s(z, 4, s_5); /* <-, line 164 */ + if (ret < 0) return ret; + } + z->I[0] -= 1; /* $measure -= , line 164 */ + break; + case 3: + { int ret = slice_del(z); /* delete, line 165 */ + if (ret < 0) return ret; + } + z->I[1] = 4; /* $prefix = , line 165 */ + z->I[0] -= 1; /* $measure -= , line 165 */ + break; + case 4: + { int ret = slice_from_s(z, 4, s_6); /* <-, line 166 */ + if (ret < 0) return ret; + } + z->I[1] = 4; /* $prefix = , line 166 */ + z->I[0] -= 1; /* $measure -= , line 166 */ + break; + } + return 1; +} + +extern int indonesian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->I[0] = 0; /* $measure = , line 172 */ + { int c1 = z->c; /* do, line 173 */ + while(1) { /* repeat, line 173 */ + int c2 = z->c; + { /* gopast */ /* grouping vowel, line 173 */ + int ret = out_grouping_U(z, g_vowel, 97, 117, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[0] += 1; /* $measure += , line 173 */ + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + if (!(z->I[0] > 2)) return 0; /* $( > ), line 174 */ + z->I[1] = 0; /* $prefix = , line 175 */ + z->lb = z->c; z->c = z->l; /* backwards, line 176 */ + + { int m3 = z->l - z->c; (void)m3; /* do, line 177 */ + { int ret = r_remove_particle(z); /* call remove_particle, line 177 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m3; + } + if (!(z->I[0] > 2)) return 0; /* $( > ), line 178 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 179 */ + { int ret = r_remove_possessive_pronoun(z); /* call remove_possessive_pronoun, line 179 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m4; + } + z->c = z->lb; + if (!(z->I[0] > 2)) return 0; /* $( > ), line 181 */ + { int c5 = z->c; /* or, line 188 */ + { int c_test6 = z->c; /* test, line 182 */ + { int ret = r_remove_first_order_prefix(z); /* call remove_first_order_prefix, line 183 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; + } + { int c7 = z->c; /* do, line 184 */ + { int c_test8 = z->c; /* test, line 185 */ + if (!(z->I[0] > 2)) goto lab6; /* $( > ), line 185 */ + z->lb = z->c; z->c = z->l; /* backwards, line 185 */ + + { int ret = r_remove_suffix(z); /* call remove_suffix, line 185 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + z->c = z->lb; + z->c = c_test8; + } + if (!(z->I[0] > 2)) goto lab6; /* $( > ), line 186 */ + { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 186 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + lab6: + z->c = c7; + } + z->c = c_test6; + } + goto lab4; + lab5: + z->c = c5; + { int c9 = z->c; /* do, line 189 */ + { int ret = r_remove_second_order_prefix(z); /* call remove_second_order_prefix, line 189 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + lab7: + z->c = c9; + } + { int c10 = z->c; /* do, line 190 */ + if (!(z->I[0] > 2)) goto lab8; /* $( > ), line 190 */ + z->lb = z->c; z->c = z->l; /* backwards, line 190 */ + + { int ret = r_remove_suffix(z); /* call remove_suffix, line 190 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; + } + z->c = z->lb; + lab8: + z->c = c10; + } + } +lab4: + return 1; +} + +extern struct SN_env * indonesian_UTF_8_create_env(void) { return SN_create_env(0, 2, 0); } + +extern void indonesian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_irish.c b/src/backend/snowball/libstemmer/stem_UTF_8_irish.c new file mode 100644 index 00000000000..239c967c2b0 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_irish.c @@ -0,0 +1,490 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int irish_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_verb_sfx(struct SN_env * z); +static int r_deriv(struct SN_env * z); +static int r_noun_sfx(struct SN_env * z); +static int r_mark_regions(struct SN_env * z); +static int r_initial_morph(struct SN_env * z); +static int r_RV(struct SN_env * z); +static int r_R2(struct SN_env * z); +static int r_R1(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * irish_UTF_8_create_env(void); +extern void irish_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[2] = { 'b', '\'' }; +static const symbol s_0_1[2] = { 'b', 'h' }; +static const symbol s_0_2[3] = { 'b', 'h', 'f' }; +static const symbol s_0_3[2] = { 'b', 'p' }; +static const symbol s_0_4[2] = { 'c', 'h' }; +static const symbol s_0_5[2] = { 'd', '\'' }; +static const symbol s_0_6[4] = { 'd', '\'', 'f', 'h' }; +static const symbol s_0_7[2] = { 'd', 'h' }; +static const symbol s_0_8[2] = { 'd', 't' }; +static const symbol s_0_9[2] = { 'f', 'h' }; +static const symbol s_0_10[2] = { 'g', 'c' }; +static const symbol s_0_11[2] = { 'g', 'h' }; +static const symbol s_0_12[2] = { 'h', '-' }; +static const symbol s_0_13[2] = { 'm', '\'' }; +static const symbol s_0_14[2] = { 'm', 'b' }; +static const symbol s_0_15[2] = { 'm', 'h' }; +static const symbol s_0_16[2] = { 'n', '-' }; +static const symbol s_0_17[2] = { 'n', 'd' }; +static const symbol s_0_18[2] = { 'n', 'g' }; +static const symbol s_0_19[2] = { 'p', 'h' }; +static const symbol s_0_20[2] = { 's', 'h' }; +static const symbol s_0_21[2] = { 't', '-' }; +static const symbol s_0_22[2] = { 't', 'h' }; +static const symbol s_0_23[2] = { 't', 's' }; + +static const struct among a_0[24] = +{ +/* 0 */ { 2, s_0_0, -1, 1, 0}, +/* 1 */ { 2, s_0_1, -1, 4, 0}, +/* 2 */ { 3, s_0_2, 1, 2, 0}, +/* 3 */ { 2, s_0_3, -1, 8, 0}, +/* 4 */ { 2, s_0_4, -1, 5, 0}, +/* 5 */ { 2, s_0_5, -1, 1, 0}, +/* 6 */ { 4, s_0_6, 5, 2, 0}, +/* 7 */ { 2, s_0_7, -1, 6, 0}, +/* 8 */ { 2, s_0_8, -1, 9, 0}, +/* 9 */ { 2, s_0_9, -1, 2, 0}, +/* 10 */ { 2, s_0_10, -1, 5, 0}, +/* 11 */ { 2, s_0_11, -1, 7, 0}, +/* 12 */ { 2, s_0_12, -1, 1, 0}, +/* 13 */ { 2, s_0_13, -1, 1, 0}, +/* 14 */ { 2, s_0_14, -1, 4, 0}, +/* 15 */ { 2, s_0_15, -1, 10, 0}, +/* 16 */ { 2, s_0_16, -1, 1, 0}, +/* 17 */ { 2, s_0_17, -1, 6, 0}, +/* 18 */ { 2, s_0_18, -1, 7, 0}, +/* 19 */ { 2, s_0_19, -1, 8, 0}, +/* 20 */ { 2, s_0_20, -1, 3, 0}, +/* 21 */ { 2, s_0_21, -1, 1, 0}, +/* 22 */ { 2, s_0_22, -1, 9, 0}, +/* 23 */ { 2, s_0_23, -1, 3, 0} +}; + +static const symbol s_1_0[7] = { 0xC3, 0xAD, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_1_1[8] = { 'a', 0xC3, 0xAD, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_1_2[3] = { 'i', 'r', 'e' }; +static const symbol s_1_3[4] = { 'a', 'i', 'r', 'e' }; +static const symbol s_1_4[3] = { 'a', 'b', 'h' }; +static const symbol s_1_5[4] = { 'e', 'a', 'b', 'h' }; +static const symbol s_1_6[3] = { 'i', 'b', 'h' }; +static const symbol s_1_7[4] = { 'a', 'i', 'b', 'h' }; +static const symbol s_1_8[3] = { 'a', 'm', 'h' }; +static const symbol s_1_9[4] = { 'e', 'a', 'm', 'h' }; +static const symbol s_1_10[3] = { 'i', 'm', 'h' }; +static const symbol s_1_11[4] = { 'a', 'i', 'm', 'h' }; +static const symbol s_1_12[6] = { 0xC3, 0xAD, 'o', 'c', 'h', 't' }; +static const symbol s_1_13[7] = { 'a', 0xC3, 0xAD, 'o', 'c', 'h', 't' }; +static const symbol s_1_14[4] = { 'i', 'r', 0xC3, 0xAD }; +static const symbol s_1_15[5] = { 'a', 'i', 'r', 0xC3, 0xAD }; + +static const struct among a_1[16] = +{ +/* 0 */ { 7, s_1_0, -1, 1, 0}, +/* 1 */ { 8, s_1_1, 0, 1, 0}, +/* 2 */ { 3, s_1_2, -1, 2, 0}, +/* 3 */ { 4, s_1_3, 2, 2, 0}, +/* 4 */ { 3, s_1_4, -1, 1, 0}, +/* 5 */ { 4, s_1_5, 4, 1, 0}, +/* 6 */ { 3, s_1_6, -1, 1, 0}, +/* 7 */ { 4, s_1_7, 6, 1, 0}, +/* 8 */ { 3, s_1_8, -1, 1, 0}, +/* 9 */ { 4, s_1_9, 8, 1, 0}, +/* 10 */ { 3, s_1_10, -1, 1, 0}, +/* 11 */ { 4, s_1_11, 10, 1, 0}, +/* 12 */ { 6, s_1_12, -1, 1, 0}, +/* 13 */ { 7, s_1_13, 12, 1, 0}, +/* 14 */ { 4, s_1_14, -1, 2, 0}, +/* 15 */ { 5, s_1_15, 14, 2, 0} +}; + +static const symbol s_2_0[9] = { 0xC3, 0xB3, 'i', 'd', 'e', 'a', 'c', 'h', 'a' }; +static const symbol s_2_1[7] = { 'p', 'a', 't', 'a', 'c', 'h', 'a' }; +static const symbol s_2_2[5] = { 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_3[8] = { 'a', 'r', 'c', 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_4[6] = { 'e', 'a', 'c', 'h', 't', 'a' }; +static const symbol s_2_5[12] = { 'g', 'r', 'a', 'f', 'a', 0xC3, 0xAD, 'o', 'c', 'h', 't', 'a' }; +static const symbol s_2_6[5] = { 'p', 'a', 'i', 't', 'e' }; +static const symbol s_2_7[3] = { 'a', 'c', 'h' }; +static const symbol s_2_8[4] = { 'e', 'a', 'c', 'h' }; +static const symbol s_2_9[8] = { 0xC3, 0xB3, 'i', 'd', 'e', 'a', 'c', 'h' }; +static const symbol s_2_10[7] = { 'g', 'i', 'n', 'e', 'a', 'c', 'h' }; +static const symbol s_2_11[6] = { 'p', 'a', 't', 'a', 'c', 'h' }; +static const symbol s_2_12[10] = { 'g', 'r', 'a', 'f', 'a', 0xC3, 0xAD, 'o', 'c', 'h' }; +static const symbol s_2_13[7] = { 'p', 'a', 't', 'a', 'i', 'g', 'h' }; +static const symbol s_2_14[7] = { 0xC3, 0xB3, 'i', 'd', 'i', 'g', 'h' }; +static const symbol s_2_15[8] = { 'a', 'c', 'h', 't', 0xC3, 0xBA, 'i', 'l' }; +static const symbol s_2_16[9] = { 'e', 'a', 'c', 'h', 't', 0xC3, 0xBA, 'i', 'l' }; +static const symbol s_2_17[6] = { 'g', 'i', 'n', 'e', 'a', 's' }; +static const symbol s_2_18[5] = { 'g', 'i', 'n', 'i', 's' }; +static const symbol s_2_19[4] = { 'a', 'c', 'h', 't' }; +static const symbol s_2_20[7] = { 'a', 'r', 'c', 'a', 'c', 'h', 't' }; +static const symbol s_2_21[5] = { 'e', 'a', 'c', 'h', 't' }; +static const symbol s_2_22[11] = { 'g', 'r', 'a', 'f', 'a', 0xC3, 0xAD, 'o', 'c', 'h', 't' }; +static const symbol s_2_23[10] = { 'a', 'r', 'c', 'a', 'c', 'h', 't', 'a', 0xC3, 0xAD }; +static const symbol s_2_24[14] = { 'g', 'r', 'a', 'f', 'a', 0xC3, 0xAD, 'o', 'c', 'h', 't', 'a', 0xC3, 0xAD }; + +static const struct among a_2[25] = +{ +/* 0 */ { 9, s_2_0, -1, 6, 0}, +/* 1 */ { 7, s_2_1, -1, 5, 0}, +/* 2 */ { 5, s_2_2, -1, 1, 0}, +/* 3 */ { 8, s_2_3, 2, 2, 0}, +/* 4 */ { 6, s_2_4, 2, 1, 0}, +/* 5 */ { 12, s_2_5, -1, 4, 0}, +/* 6 */ { 5, s_2_6, -1, 5, 0}, +/* 7 */ { 3, s_2_7, -1, 1, 0}, +/* 8 */ { 4, s_2_8, 7, 1, 0}, +/* 9 */ { 8, s_2_9, 8, 6, 0}, +/* 10 */ { 7, s_2_10, 8, 3, 0}, +/* 11 */ { 6, s_2_11, 7, 5, 0}, +/* 12 */ { 10, s_2_12, -1, 4, 0}, +/* 13 */ { 7, s_2_13, -1, 5, 0}, +/* 14 */ { 7, s_2_14, -1, 6, 0}, +/* 15 */ { 8, s_2_15, -1, 1, 0}, +/* 16 */ { 9, s_2_16, 15, 1, 0}, +/* 17 */ { 6, s_2_17, -1, 3, 0}, +/* 18 */ { 5, s_2_18, -1, 3, 0}, +/* 19 */ { 4, s_2_19, -1, 1, 0}, +/* 20 */ { 7, s_2_20, 19, 2, 0}, +/* 21 */ { 5, s_2_21, 19, 1, 0}, +/* 22 */ { 11, s_2_22, -1, 4, 0}, +/* 23 */ { 10, s_2_23, -1, 2, 0}, +/* 24 */ { 14, s_2_24, -1, 4, 0} +}; + +static const symbol s_3_0[4] = { 'i', 'm', 'i', 'd' }; +static const symbol s_3_1[5] = { 'a', 'i', 'm', 'i', 'd' }; +static const symbol s_3_2[5] = { 0xC3, 0xAD, 'm', 'i', 'd' }; +static const symbol s_3_3[6] = { 'a', 0xC3, 0xAD, 'm', 'i', 'd' }; +static const symbol s_3_4[3] = { 'a', 'd', 'h' }; +static const symbol s_3_5[4] = { 'e', 'a', 'd', 'h' }; +static const symbol s_3_6[5] = { 'f', 'a', 'i', 'd', 'h' }; +static const symbol s_3_7[4] = { 'f', 'i', 'd', 'h' }; +static const symbol s_3_8[4] = { 0xC3, 0xA1, 'i', 'l' }; +static const symbol s_3_9[3] = { 'a', 'i', 'n' }; +static const symbol s_3_10[4] = { 't', 'e', 'a', 'r' }; +static const symbol s_3_11[3] = { 't', 'a', 'r' }; + +static const struct among a_3[12] = +{ +/* 0 */ { 4, s_3_0, -1, 1, 0}, +/* 1 */ { 5, s_3_1, 0, 1, 0}, +/* 2 */ { 5, s_3_2, -1, 1, 0}, +/* 3 */ { 6, s_3_3, 2, 1, 0}, +/* 4 */ { 3, s_3_4, -1, 2, 0}, +/* 5 */ { 4, s_3_5, 4, 2, 0}, +/* 6 */ { 5, s_3_6, -1, 1, 0}, +/* 7 */ { 4, s_3_7, -1, 1, 0}, +/* 8 */ { 4, s_3_8, -1, 2, 0}, +/* 9 */ { 3, s_3_9, -1, 2, 0}, +/* 10 */ { 4, s_3_10, -1, 2, 0}, +/* 11 */ { 3, s_3_11, -1, 2, 0} +}; + +static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 4, 2 }; + +static const symbol s_0[] = { 'f' }; +static const symbol s_1[] = { 's' }; +static const symbol s_2[] = { 'b' }; +static const symbol s_3[] = { 'c' }; +static const symbol s_4[] = { 'd' }; +static const symbol s_5[] = { 'g' }; +static const symbol s_6[] = { 'p' }; +static const symbol s_7[] = { 't' }; +static const symbol s_8[] = { 'm' }; +static const symbol s_9[] = { 'a', 'r', 'c' }; +static const symbol s_10[] = { 'g', 'i', 'n' }; +static const symbol s_11[] = { 'g', 'r', 'a', 'f' }; +static const symbol s_12[] = { 'p', 'a', 'i', 't', 'e' }; +static const symbol s_13[] = { 0xC3, 0xB3, 'i', 'd' }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 30 */ + z->I[1] = z->l; /* $p1 = , line 31 */ + z->I[2] = z->l; /* $p2 = , line 32 */ + { int c1 = z->c; /* do, line 34 */ + { /* gopast */ /* grouping v, line 35 */ + int ret = out_grouping_U(z, g_v, 97, 250, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[0] = z->c; /* setmark pV, line 35 */ + lab0: + z->c = c1; + } + { int c2 = z->c; /* do, line 37 */ + { /* gopast */ /* grouping v, line 38 */ + int ret = out_grouping_U(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + { /* gopast */ /* non v, line 38 */ + int ret = in_grouping_U(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[1] = z->c; /* setmark p1, line 38 */ + { /* gopast */ /* grouping v, line 39 */ + int ret = out_grouping_U(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + { /* gopast */ /* non v, line 39 */ + int ret = in_grouping_U(z, g_v, 97, 250, 1); + if (ret < 0) goto lab1; + z->c += ret; + } + z->I[2] = z->c; /* setmark p2, line 39 */ + lab1: + z->c = c2; + } + return 1; +} + +static int r_initial_morph(struct SN_env * z) { /* forwardmode */ + int among_var; + z->bra = z->c; /* [, line 44 */ + among_var = find_among(z, a_0, 24); /* substring, line 44 */ + if (!(among_var)) return 0; + z->ket = z->c; /* ], line 44 */ + switch (among_var) { /* among, line 44 */ + case 1: + { int ret = slice_del(z); /* delete, line 46 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 1, s_0); /* <-, line 52 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 1, s_1); /* <-, line 58 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 1, s_2); /* <-, line 61 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 1, s_3); /* <-, line 63 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 1, s_4); /* <-, line 65 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 1, s_5); /* <-, line 69 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 1, s_6); /* <-, line 71 */ + if (ret < 0) return ret; + } + break; + case 9: + { int ret = slice_from_s(z, 1, s_7); /* <-, line 75 */ + if (ret < 0) return ret; + } + break; + case 10: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 89 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 99 */ + return 1; +} + +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 100 */ + return 1; +} + +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 101 */ + return 1; +} + +static int r_noun_sfx(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 104 */ + among_var = find_among_b(z, a_1, 16); /* substring, line 104 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 104 */ + switch (among_var) { /* among, line 104 */ + case 1: + { int ret = r_R1(z); /* call R1, line 108 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 108 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R2(z); /* call R2, line 110 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 110 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_deriv(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 114 */ + among_var = find_among_b(z, a_2, 25); /* substring, line 114 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 114 */ + switch (among_var) { /* among, line 114 */ + case 1: + { int ret = r_R2(z); /* call R2, line 116 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 116 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 3, s_9); /* <-, line 118 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 3, s_10); /* <-, line 120 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 4, s_11); /* <-, line 122 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 5, s_12); /* <-, line 124 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 4, s_13); /* <-, line 126 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_verb_sfx(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 130 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((282896 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 130 */ + among_var = find_among_b(z, a_3, 12); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 130 */ + switch (among_var) { /* among, line 130 */ + case 1: + { int ret = r_RV(z); /* call RV, line 133 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 133 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = r_R1(z); /* call R1, line 138 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 138 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +extern int irish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 144 */ + { int ret = r_initial_morph(z); /* call initial_morph, line 144 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + /* do, line 145 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 145 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } +lab1: + z->lb = z->c; z->c = z->l; /* backwards, line 146 */ + + { int m2 = z->l - z->c; (void)m2; /* do, line 147 */ + { int ret = r_noun_sfx(z); /* call noun_sfx, line 147 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m2; + } + { int m3 = z->l - z->c; (void)m3; /* do, line 148 */ + { int ret = r_deriv(z); /* call deriv, line 148 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m3; + } + { int m4 = z->l - z->c; (void)m4; /* do, line 149 */ + { int ret = r_verb_sfx(z); /* call verb_sfx, line 149 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m4; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * irish_UTF_8_create_env(void) { return SN_create_env(0, 3, 0); } + +extern void irish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_italian.c b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c index 395e38a548e..7546960fac9 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_italian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_italian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -476,34 +476,29 @@ static const symbol s_2[] = { 0xC3, 0xAC }; static const symbol s_3[] = { 0xC3, 0xB2 }; static const symbol s_4[] = { 0xC3, 0xB9 }; static const symbol s_5[] = { 'q', 'U' }; -static const symbol s_6[] = { 'u' }; -static const symbol s_7[] = { 'U' }; +static const symbol s_6[] = { 'U' }; +static const symbol s_7[] = { 'I' }; static const symbol s_8[] = { 'i' }; -static const symbol s_9[] = { 'I' }; -static const symbol s_10[] = { 'i' }; -static const symbol s_11[] = { 'u' }; -static const symbol s_12[] = { 'e' }; -static const symbol s_13[] = { 'i', 'c' }; -static const symbol s_14[] = { 'l', 'o', 'g' }; -static const symbol s_15[] = { 'u' }; -static const symbol s_16[] = { 'e', 'n', 't', 'e' }; -static const symbol s_17[] = { 'a', 't' }; -static const symbol s_18[] = { 'a', 't' }; -static const symbol s_19[] = { 'i', 'c' }; -static const symbol s_20[] = { 'i' }; -static const symbol s_21[] = { 'h' }; +static const symbol s_9[] = { 'u' }; +static const symbol s_10[] = { 'e' }; +static const symbol s_11[] = { 'i', 'c' }; +static const symbol s_12[] = { 'l', 'o', 'g' }; +static const symbol s_13[] = { 'u' }; +static const symbol s_14[] = { 'e', 'n', 't', 'e' }; +static const symbol s_15[] = { 'a', 't' }; +static const symbol s_16[] = { 'a', 't' }; +static const symbol s_17[] = { 'i', 'c' }; -static int r_prelude(struct SN_env * z) { +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; - { int c_test = z->c; /* test, line 35 */ + { int c_test1 = z->c; /* test, line 35 */ while(1) { /* repeat, line 35 */ - int c1 = z->c; + int c2 = z->c; z->bra = z->c; /* [, line 36 */ among_var = find_among(z, a_0, 7); /* substring, line 36 */ if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 36 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 36 */ case 1: { int ret = slice_from_s(z, 2, s_0); /* <-, line 37 */ if (ret < 0) return ret; @@ -543,39 +538,41 @@ static int r_prelude(struct SN_env * z) { } continue; lab0: - z->c = c1; + z->c = c2; break; } - z->c = c_test; + z->c = c_test1; } while(1) { /* repeat, line 46 */ - int c2 = z->c; + int c3 = z->c; while(1) { /* goto, line 46 */ - int c3 = z->c; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + int c4 = z->c; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 47 */ z->bra = z->c; /* [, line 47 */ - { int c4 = z->c; /* or, line 47 */ - if (!(eq_s(z, 1, s_6))) goto lab4; + { int c5 = z->c; /* or, line 47 */ + if (z->c == z->l || z->p[z->c] != 'u') goto lab4; /* literal, line 47 */ + z->c++; z->ket = z->c; /* ], line 47 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab4; - { int ret = slice_from_s(z, 1, s_7); /* <-, line 47 */ + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab4; /* grouping v, line 47 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 47 */ if (ret < 0) return ret; } goto lab3; lab4: - z->c = c4; - if (!(eq_s(z, 1, s_8))) goto lab2; + z->c = c5; + if (z->c == z->l || z->p[z->c] != 'i') goto lab2; /* literal, line 48 */ + z->c++; z->ket = z->c; /* ], line 48 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; - { int ret = slice_from_s(z, 1, s_9); /* <-, line 48 */ + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 48 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 48 */ if (ret < 0) return ret; } } lab3: - z->c = c3; + z->c = c4; break; lab2: - z->c = c3; + z->c = c4; { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab1; z->c = ret; /* goto, line 46 */ @@ -583,21 +580,21 @@ static int r_prelude(struct SN_env * z) { } continue; lab1: - z->c = c2; + z->c = c3; break; } return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 54 */ + z->I[1] = z->l; /* $p1 = , line 55 */ + z->I[2] = z->l; /* $p2 = , line 56 */ { int c1 = z->c; /* do, line 58 */ { int c2 = z->c; /* or, line 60 */ - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ { int c3 = z->c; /* or, line 59 */ - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab4; + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab4; /* non v, line 59 */ { /* gopast */ /* grouping v, line 59 */ int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab4; @@ -606,7 +603,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab2; /* grouping v, line 59 */ { /* gopast */ /* non v, line 59 */ int ret = in_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab2; @@ -617,9 +614,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab0; + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab0; /* non v, line 61 */ { int c4 = z->c; /* or, line 61 */ - if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab6; + if (out_grouping_U(z, g_v, 97, 249, 0)) goto lab6; /* non v, line 61 */ { /* gopast */ /* grouping v, line 61 */ int ret = out_grouping_U(z, g_v, 97, 249, 1); if (ret < 0) goto lab6; @@ -628,7 +625,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab0; + if (in_grouping_U(z, g_v, 97, 249, 0)) goto lab0; /* grouping v, line 61 */ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; z->c = ret; /* next, line 61 */ @@ -671,24 +668,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 70 */ int c1 = z->c; z->bra = z->c; /* [, line 72 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 72 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 72 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 72 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 72 */ case 1: - { int ret = slice_from_s(z, 1, s_10); /* <-, line 73 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 73 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_11); /* <-, line 74 */ + { int ret = slice_from_s(z, 1, s_9); /* <-, line 74 */ if (ret < 0) return ret; } break; @@ -707,43 +703,41 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 82 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 83 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 84 */ return 1; } -static int r_attached_pronoun(struct SN_env * z) { +static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 87 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_2, 37))) return 0; /* substring, line 87 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((33314 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + if (!(find_among_b(z, a_2, 37))) return 0; z->bra = z->c; /* ], line 87 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; - among_var = find_among_b(z, a_3, 5); /* among, line 97 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* among, line 97 */ + among_var = find_among_b(z, a_3, 5); if (!(among_var)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 97 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 97 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 97 */ case 1: { int ret = slice_del(z); /* delete, line 98 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_12); /* <-, line 99 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 99 */ if (ret < 0) return ret; } break; @@ -751,37 +745,34 @@ static int r_attached_pronoun(struct SN_env * z) { return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 104 */ among_var = find_among_b(z, a_6, 51); /* substring, line 104 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 104 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 104 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 111 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 111 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 113 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 113 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 113 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 114 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 114 */ z->ket = z->c; /* [, line 114 */ - if (!(eq_s_b(z, 2, s_13))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m1; goto lab0; } /* literal, line 114 */ z->bra = z->c; /* ], line 114 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 114 */ + { int ret = r_R2(z); /* call R2, line 114 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 114 */ @@ -792,70 +783,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 117 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 117 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_14); /* <-, line 117 */ + { int ret = slice_from_s(z, 3, s_12); /* <-, line 117 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 119 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 119 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_15); /* <-, line 119 */ + { int ret = slice_from_s(z, 1, s_13); /* <-, line 119 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 121 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 121 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_16); /* <-, line 121 */ + { int ret = slice_from_s(z, 4, s_14); /* <-, line 121 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 123 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 123 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 123 */ if (ret < 0) return ret; } break; case 7: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 125 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 125 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 126 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 126 */ z->ket = z->c; /* [, line 127 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_4, 4); /* substring, line 127 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4722696 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 127 */ + among_var = find_among_b(z, a_4, 4); + if (!(among_var)) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 127 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */ + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 127 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } + switch (among_var) { /* among, line 127 */ case 1: z->ket = z->c; /* [, line 128 */ - if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m_keep; goto lab1; } + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m2; goto lab1; } /* literal, line 128 */ z->bra = z->c; /* ], line 128 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 128 */ + { int ret = r_R2(z); /* call R2, line 128 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 128 */ @@ -868,59 +853,51 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 134 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 134 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_5, 3); /* substring, line 136 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 136 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 137 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 137 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 137 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 137 */ + if (ret < 0) return ret; } lab2: ; } break; case 9: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 142 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 142 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 142 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 143 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 143 */ z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_18))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */ + { int ret = r_R2(z); /* call R2, line 143 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 143 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 143 */ - if (!(eq_s_b(z, 2, s_19))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_17))) { z->c = z->l - m4; goto lab3; } /* literal, line 143 */ z->bra = z->c; /* ], line 143 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 143 */ + { int ret = r_R2(z); /* call R2, line 143 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 143 */ @@ -934,48 +911,40 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 148 */ - int m1 = z->l - z->c; (void)m1; +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 148 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 148 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 149 */ - among_var = find_among_b(z, a_7, 87); /* substring, line 149 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_7, 87))) { z->lb = mlimit1; return 0; } /* substring, line 149 */ z->bra = z->c; /* ], line 149 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - { int ret = slice_del(z); /* delete, line 163 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 163 */ + if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_vowel_suffix(struct SN_env * z) { - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 171 */ +static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* try, line 171 */ z->ket = z->c; /* [, line 172 */ - if (in_grouping_b_U(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m_keep; goto lab0; } + if (in_grouping_b_U(z, g_AEIO, 97, 242, 0)) { z->c = z->l - m1; goto lab0; } /* grouping AEIO, line 172 */ z->bra = z->c; /* ], line 172 */ - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 172 */ + { int ret = r_RV(z); /* call RV, line 172 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 172 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 173 */ - if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'i') { z->c = z->l - m1; goto lab0; } /* literal, line 173 */ + z->c--; z->bra = z->c; /* ], line 173 */ - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 173 */ + { int ret = r_RV(z); /* call RV, line 173 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 173 */ @@ -984,13 +953,14 @@ static int r_vowel_suffix(struct SN_env * z) { lab0: ; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 175 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 175 */ z->ket = z->c; /* [, line 176 */ - if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab1; } + if (z->c <= z->lb || z->p[z->c - 1] != 'h') { z->c = z->l - m2; goto lab1; } /* literal, line 176 */ + z->c--; z->bra = z->c; /* ], line 176 */ - if (in_grouping_b_U(z, g_CG, 99, 103, 0)) { z->c = z->l - m_keep; goto lab1; } - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call RV, line 176 */ + if (in_grouping_b_U(z, g_CG, 99, 103, 0)) { z->c = z->l - m2; goto lab1; } /* grouping CG, line 176 */ + { int ret = r_RV(z); /* call RV, line 176 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 176 */ @@ -1002,67 +972,65 @@ static int r_vowel_suffix(struct SN_env * z) { return 1; } -extern int italian_UTF_8_stem(struct SN_env * z) { +extern int italian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 182 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 182 */ + { int ret = r_prelude(z); /* call prelude, line 182 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 183 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 183 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 183 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 183 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 184 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 185 */ - { int ret = r_attached_pronoun(z); - if (ret == 0) goto lab2; /* call attached_pronoun, line 185 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 185 */ + { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 185 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 186 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 186 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab5; /* call standard_suffix, line 186 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 186 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 186 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 186 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab4; lab5: - z->c = z->l - m5; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab3; /* call verb_suffix, line 186 */ + z->c = z->l - m4; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 186 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } } lab4: lab3: - z->c = z->l - m4; + z->c = z->l - m3; } - { int m6 = z->l - z->c; (void)m6; /* do, line 187 */ - { int ret = r_vowel_suffix(z); - if (ret == 0) goto lab6; /* call vowel_suffix, line 187 */ + { int m5 = z->l - z->c; (void)m5; /* do, line 187 */ + { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 187 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m6; + z->c = z->l - m5; } z->c = z->lb; - { int c7 = z->c; /* do, line 189 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab7; /* call postlude, line 189 */ + { int c6 = z->c; /* do, line 189 */ + { int ret = r_postlude(z); /* call postlude, line 189 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = c7; + z->c = c6; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c b/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c new file mode 100644 index 00000000000..dbf27e62ddf --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_lithuanian.c @@ -0,0 +1,850 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +static int r_fix_conflicts(struct SN_env * z); +static int r_fix_gd(struct SN_env * z); +static int r_fix_chdz(struct SN_env * z); +static int r_step1(struct SN_env * z); +static int r_R1(struct SN_env * z); +static int r_step2(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif +extern int lithuanian_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * lithuanian_UTF_8_create_env(void); +extern void lithuanian_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[1] = { 'a' }; +static const symbol s_0_1[2] = { 'i', 'a' }; +static const symbol s_0_2[4] = { 'e', 'r', 'i', 'a' }; +static const symbol s_0_3[4] = { 'o', 's', 'n', 'a' }; +static const symbol s_0_4[5] = { 'i', 'o', 's', 'n', 'a' }; +static const symbol s_0_5[5] = { 'u', 'o', 's', 'n', 'a' }; +static const symbol s_0_6[6] = { 'i', 'u', 'o', 's', 'n', 'a' }; +static const symbol s_0_7[4] = { 'y', 's', 'n', 'a' }; +static const symbol s_0_8[5] = { 0xC4, 0x97, 's', 'n', 'a' }; +static const symbol s_0_9[1] = { 'e' }; +static const symbol s_0_10[2] = { 'i', 'e' }; +static const symbol s_0_11[4] = { 'e', 'n', 'i', 'e' }; +static const symbol s_0_12[4] = { 'e', 'r', 'i', 'e' }; +static const symbol s_0_13[3] = { 'o', 'j', 'e' }; +static const symbol s_0_14[4] = { 'i', 'o', 'j', 'e' }; +static const symbol s_0_15[3] = { 'u', 'j', 'e' }; +static const symbol s_0_16[4] = { 'i', 'u', 'j', 'e' }; +static const symbol s_0_17[3] = { 'y', 'j', 'e' }; +static const symbol s_0_18[5] = { 'e', 'n', 'y', 'j', 'e' }; +static const symbol s_0_19[5] = { 'e', 'r', 'y', 'j', 'e' }; +static const symbol s_0_20[4] = { 0xC4, 0x97, 'j', 'e' }; +static const symbol s_0_21[3] = { 'a', 'm', 'e' }; +static const symbol s_0_22[4] = { 'i', 'a', 'm', 'e' }; +static const symbol s_0_23[4] = { 's', 'i', 'm', 'e' }; +static const symbol s_0_24[3] = { 'o', 'm', 'e' }; +static const symbol s_0_25[4] = { 0xC4, 0x97, 'm', 'e' }; +static const symbol s_0_26[7] = { 't', 'u', 'm', 0xC4, 0x97, 'm', 'e' }; +static const symbol s_0_27[3] = { 'o', 's', 'e' }; +static const symbol s_0_28[4] = { 'i', 'o', 's', 'e' }; +static const symbol s_0_29[4] = { 'u', 'o', 's', 'e' }; +static const symbol s_0_30[5] = { 'i', 'u', 'o', 's', 'e' }; +static const symbol s_0_31[3] = { 'y', 's', 'e' }; +static const symbol s_0_32[5] = { 'e', 'n', 'y', 's', 'e' }; +static const symbol s_0_33[5] = { 'e', 'r', 'y', 's', 'e' }; +static const symbol s_0_34[4] = { 0xC4, 0x97, 's', 'e' }; +static const symbol s_0_35[3] = { 'a', 't', 'e' }; +static const symbol s_0_36[4] = { 'i', 'a', 't', 'e' }; +static const symbol s_0_37[3] = { 'i', 't', 'e' }; +static const symbol s_0_38[4] = { 'k', 'i', 't', 'e' }; +static const symbol s_0_39[4] = { 's', 'i', 't', 'e' }; +static const symbol s_0_40[3] = { 'o', 't', 'e' }; +static const symbol s_0_41[4] = { 't', 'u', 't', 'e' }; +static const symbol s_0_42[4] = { 0xC4, 0x97, 't', 'e' }; +static const symbol s_0_43[7] = { 't', 'u', 'm', 0xC4, 0x97, 't', 'e' }; +static const symbol s_0_44[1] = { 'i' }; +static const symbol s_0_45[2] = { 'a', 'i' }; +static const symbol s_0_46[3] = { 'i', 'a', 'i' }; +static const symbol s_0_47[5] = { 'e', 'r', 'i', 'a', 'i' }; +static const symbol s_0_48[2] = { 'e', 'i' }; +static const symbol s_0_49[5] = { 't', 'u', 'm', 'e', 'i' }; +static const symbol s_0_50[2] = { 'k', 'i' }; +static const symbol s_0_51[3] = { 'i', 'm', 'i' }; +static const symbol s_0_52[5] = { 'e', 'r', 'i', 'm', 'i' }; +static const symbol s_0_53[3] = { 'u', 'm', 'i' }; +static const symbol s_0_54[4] = { 'i', 'u', 'm', 'i' }; +static const symbol s_0_55[2] = { 's', 'i' }; +static const symbol s_0_56[3] = { 'a', 's', 'i' }; +static const symbol s_0_57[4] = { 'i', 'a', 's', 'i' }; +static const symbol s_0_58[3] = { 'e', 's', 'i' }; +static const symbol s_0_59[4] = { 'i', 'e', 's', 'i' }; +static const symbol s_0_60[5] = { 's', 'i', 'e', 's', 'i' }; +static const symbol s_0_61[3] = { 'i', 's', 'i' }; +static const symbol s_0_62[4] = { 'a', 'i', 's', 'i' }; +static const symbol s_0_63[4] = { 'e', 'i', 's', 'i' }; +static const symbol s_0_64[7] = { 't', 'u', 'm', 'e', 'i', 's', 'i' }; +static const symbol s_0_65[4] = { 'u', 'i', 's', 'i' }; +static const symbol s_0_66[3] = { 'o', 's', 'i' }; +static const symbol s_0_67[6] = { 0xC4, 0x97, 'j', 'o', 's', 'i' }; +static const symbol s_0_68[4] = { 'u', 'o', 's', 'i' }; +static const symbol s_0_69[5] = { 'i', 'u', 'o', 's', 'i' }; +static const symbol s_0_70[6] = { 's', 'i', 'u', 'o', 's', 'i' }; +static const symbol s_0_71[3] = { 'u', 's', 'i' }; +static const symbol s_0_72[4] = { 'a', 'u', 's', 'i' }; +static const symbol s_0_73[7] = { 0xC4, 0x8D, 'i', 'a', 'u', 's', 'i' }; +static const symbol s_0_74[4] = { 0xC4, 0x85, 's', 'i' }; +static const symbol s_0_75[4] = { 0xC4, 0x97, 's', 'i' }; +static const symbol s_0_76[4] = { 0xC5, 0xB3, 's', 'i' }; +static const symbol s_0_77[5] = { 't', 0xC5, 0xB3, 's', 'i' }; +static const symbol s_0_78[2] = { 't', 'i' }; +static const symbol s_0_79[4] = { 'e', 'n', 't', 'i' }; +static const symbol s_0_80[4] = { 'i', 'n', 't', 'i' }; +static const symbol s_0_81[3] = { 'o', 't', 'i' }; +static const symbol s_0_82[4] = { 'i', 'o', 't', 'i' }; +static const symbol s_0_83[4] = { 'u', 'o', 't', 'i' }; +static const symbol s_0_84[5] = { 'i', 'u', 'o', 't', 'i' }; +static const symbol s_0_85[4] = { 'a', 'u', 't', 'i' }; +static const symbol s_0_86[5] = { 'i', 'a', 'u', 't', 'i' }; +static const symbol s_0_87[3] = { 'y', 't', 'i' }; +static const symbol s_0_88[4] = { 0xC4, 0x97, 't', 'i' }; +static const symbol s_0_89[7] = { 't', 'e', 'l', 0xC4, 0x97, 't', 'i' }; +static const symbol s_0_90[6] = { 'i', 'n', 0xC4, 0x97, 't', 'i' }; +static const symbol s_0_91[7] = { 't', 'e', 'r', 0xC4, 0x97, 't', 'i' }; +static const symbol s_0_92[2] = { 'u', 'i' }; +static const symbol s_0_93[3] = { 'i', 'u', 'i' }; +static const symbol s_0_94[5] = { 'e', 'n', 'i', 'u', 'i' }; +static const symbol s_0_95[2] = { 'o', 'j' }; +static const symbol s_0_96[3] = { 0xC4, 0x97, 'j' }; +static const symbol s_0_97[1] = { 'k' }; +static const symbol s_0_98[2] = { 'a', 'm' }; +static const symbol s_0_99[3] = { 'i', 'a', 'm' }; +static const symbol s_0_100[3] = { 'i', 'e', 'm' }; +static const symbol s_0_101[2] = { 'i', 'm' }; +static const symbol s_0_102[3] = { 's', 'i', 'm' }; +static const symbol s_0_103[2] = { 'o', 'm' }; +static const symbol s_0_104[3] = { 't', 'u', 'm' }; +static const symbol s_0_105[3] = { 0xC4, 0x97, 'm' }; +static const symbol s_0_106[6] = { 't', 'u', 'm', 0xC4, 0x97, 'm' }; +static const symbol s_0_107[2] = { 'a', 'n' }; +static const symbol s_0_108[2] = { 'o', 'n' }; +static const symbol s_0_109[3] = { 'i', 'o', 'n' }; +static const symbol s_0_110[2] = { 'u', 'n' }; +static const symbol s_0_111[3] = { 'i', 'u', 'n' }; +static const symbol s_0_112[3] = { 0xC4, 0x97, 'n' }; +static const symbol s_0_113[1] = { 'o' }; +static const symbol s_0_114[2] = { 'i', 'o' }; +static const symbol s_0_115[4] = { 'e', 'n', 'i', 'o' }; +static const symbol s_0_116[4] = { 0xC4, 0x97, 'j', 'o' }; +static const symbol s_0_117[2] = { 'u', 'o' }; +static const symbol s_0_118[1] = { 's' }; +static const symbol s_0_119[2] = { 'a', 's' }; +static const symbol s_0_120[3] = { 'i', 'a', 's' }; +static const symbol s_0_121[2] = { 'e', 's' }; +static const symbol s_0_122[3] = { 'i', 'e', 's' }; +static const symbol s_0_123[2] = { 'i', 's' }; +static const symbol s_0_124[3] = { 'a', 'i', 's' }; +static const symbol s_0_125[4] = { 'i', 'a', 'i', 's' }; +static const symbol s_0_126[6] = { 't', 'u', 'm', 'e', 'i', 's' }; +static const symbol s_0_127[4] = { 'i', 'm', 'i', 's' }; +static const symbol s_0_128[6] = { 'e', 'n', 'i', 'm', 'i', 's' }; +static const symbol s_0_129[4] = { 'o', 'm', 'i', 's' }; +static const symbol s_0_130[5] = { 'i', 'o', 'm', 'i', 's' }; +static const symbol s_0_131[4] = { 'u', 'm', 'i', 's' }; +static const symbol s_0_132[5] = { 0xC4, 0x97, 'm', 'i', 's' }; +static const symbol s_0_133[4] = { 'e', 'n', 'i', 's' }; +static const symbol s_0_134[4] = { 'a', 's', 'i', 's' }; +static const symbol s_0_135[4] = { 'y', 's', 'i', 's' }; +static const symbol s_0_136[3] = { 'a', 'm', 's' }; +static const symbol s_0_137[4] = { 'i', 'a', 'm', 's' }; +static const symbol s_0_138[4] = { 'i', 'e', 'm', 's' }; +static const symbol s_0_139[3] = { 'i', 'm', 's' }; +static const symbol s_0_140[5] = { 'e', 'n', 'i', 'm', 's' }; +static const symbol s_0_141[5] = { 'e', 'r', 'i', 'm', 's' }; +static const symbol s_0_142[3] = { 'o', 'm', 's' }; +static const symbol s_0_143[4] = { 'i', 'o', 'm', 's' }; +static const symbol s_0_144[3] = { 'u', 'm', 's' }; +static const symbol s_0_145[4] = { 0xC4, 0x97, 'm', 's' }; +static const symbol s_0_146[3] = { 'e', 'n', 's' }; +static const symbol s_0_147[2] = { 'o', 's' }; +static const symbol s_0_148[3] = { 'i', 'o', 's' }; +static const symbol s_0_149[3] = { 'u', 'o', 's' }; +static const symbol s_0_150[4] = { 'i', 'u', 'o', 's' }; +static const symbol s_0_151[3] = { 'e', 'r', 's' }; +static const symbol s_0_152[2] = { 'u', 's' }; +static const symbol s_0_153[3] = { 'a', 'u', 's' }; +static const symbol s_0_154[4] = { 'i', 'a', 'u', 's' }; +static const symbol s_0_155[3] = { 'i', 'u', 's' }; +static const symbol s_0_156[2] = { 'y', 's' }; +static const symbol s_0_157[4] = { 'e', 'n', 'y', 's' }; +static const symbol s_0_158[4] = { 'e', 'r', 'y', 's' }; +static const symbol s_0_159[3] = { 0xC4, 0x85, 's' }; +static const symbol s_0_160[4] = { 'i', 0xC4, 0x85, 's' }; +static const symbol s_0_161[3] = { 0xC4, 0x97, 's' }; +static const symbol s_0_162[5] = { 'a', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_163[6] = { 'i', 'a', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_164[5] = { 'i', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_165[6] = { 'k', 'i', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_166[6] = { 's', 'i', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_167[5] = { 'o', 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_168[6] = { 0xC4, 0x97, 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_169[9] = { 't', 'u', 'm', 0xC4, 0x97, 'm', 0xC4, 0x97, 's' }; +static const symbol s_0_170[5] = { 'a', 't', 0xC4, 0x97, 's' }; +static const symbol s_0_171[6] = { 'i', 'a', 't', 0xC4, 0x97, 's' }; +static const symbol s_0_172[6] = { 's', 'i', 't', 0xC4, 0x97, 's' }; +static const symbol s_0_173[5] = { 'o', 't', 0xC4, 0x97, 's' }; +static const symbol s_0_174[6] = { 0xC4, 0x97, 't', 0xC4, 0x97, 's' }; +static const symbol s_0_175[9] = { 't', 'u', 'm', 0xC4, 0x97, 't', 0xC4, 0x97, 's' }; +static const symbol s_0_176[3] = { 0xC5, 0xAB, 's' }; +static const symbol s_0_177[3] = { 0xC4, 0xAF, 's' }; +static const symbol s_0_178[4] = { 't', 0xC5, 0xB3, 's' }; +static const symbol s_0_179[2] = { 'a', 't' }; +static const symbol s_0_180[3] = { 'i', 'a', 't' }; +static const symbol s_0_181[2] = { 'i', 't' }; +static const symbol s_0_182[3] = { 's', 'i', 't' }; +static const symbol s_0_183[2] = { 'o', 't' }; +static const symbol s_0_184[3] = { 0xC4, 0x97, 't' }; +static const symbol s_0_185[6] = { 't', 'u', 'm', 0xC4, 0x97, 't' }; +static const symbol s_0_186[1] = { 'u' }; +static const symbol s_0_187[2] = { 'a', 'u' }; +static const symbol s_0_188[3] = { 'i', 'a', 'u' }; +static const symbol s_0_189[5] = { 0xC4, 0x8D, 'i', 'a', 'u' }; +static const symbol s_0_190[2] = { 'i', 'u' }; +static const symbol s_0_191[4] = { 'e', 'n', 'i', 'u' }; +static const symbol s_0_192[3] = { 's', 'i', 'u' }; +static const symbol s_0_193[1] = { 'y' }; +static const symbol s_0_194[2] = { 0xC4, 0x85 }; +static const symbol s_0_195[3] = { 'i', 0xC4, 0x85 }; +static const symbol s_0_196[2] = { 0xC4, 0x97 }; +static const symbol s_0_197[2] = { 0xC4, 0x99 }; +static const symbol s_0_198[2] = { 0xC4, 0xAF }; +static const symbol s_0_199[4] = { 'e', 'n', 0xC4, 0xAF }; +static const symbol s_0_200[4] = { 'e', 'r', 0xC4, 0xAF }; +static const symbol s_0_201[2] = { 0xC5, 0xB3 }; +static const symbol s_0_202[3] = { 'i', 0xC5, 0xB3 }; +static const symbol s_0_203[4] = { 'e', 'r', 0xC5, 0xB3 }; + +static const struct among a_0[204] = +{ +/* 0 */ { 1, s_0_0, -1, -1, 0}, +/* 1 */ { 2, s_0_1, 0, -1, 0}, +/* 2 */ { 4, s_0_2, 1, -1, 0}, +/* 3 */ { 4, s_0_3, 0, -1, 0}, +/* 4 */ { 5, s_0_4, 3, -1, 0}, +/* 5 */ { 5, s_0_5, 3, -1, 0}, +/* 6 */ { 6, s_0_6, 5, -1, 0}, +/* 7 */ { 4, s_0_7, 0, -1, 0}, +/* 8 */ { 5, s_0_8, 0, -1, 0}, +/* 9 */ { 1, s_0_9, -1, -1, 0}, +/* 10 */ { 2, s_0_10, 9, -1, 0}, +/* 11 */ { 4, s_0_11, 10, -1, 0}, +/* 12 */ { 4, s_0_12, 10, -1, 0}, +/* 13 */ { 3, s_0_13, 9, -1, 0}, +/* 14 */ { 4, s_0_14, 13, -1, 0}, +/* 15 */ { 3, s_0_15, 9, -1, 0}, +/* 16 */ { 4, s_0_16, 15, -1, 0}, +/* 17 */ { 3, s_0_17, 9, -1, 0}, +/* 18 */ { 5, s_0_18, 17, -1, 0}, +/* 19 */ { 5, s_0_19, 17, -1, 0}, +/* 20 */ { 4, s_0_20, 9, -1, 0}, +/* 21 */ { 3, s_0_21, 9, -1, 0}, +/* 22 */ { 4, s_0_22, 21, -1, 0}, +/* 23 */ { 4, s_0_23, 9, -1, 0}, +/* 24 */ { 3, s_0_24, 9, -1, 0}, +/* 25 */ { 4, s_0_25, 9, -1, 0}, +/* 26 */ { 7, s_0_26, 25, -1, 0}, +/* 27 */ { 3, s_0_27, 9, -1, 0}, +/* 28 */ { 4, s_0_28, 27, -1, 0}, +/* 29 */ { 4, s_0_29, 27, -1, 0}, +/* 30 */ { 5, s_0_30, 29, -1, 0}, +/* 31 */ { 3, s_0_31, 9, -1, 0}, +/* 32 */ { 5, s_0_32, 31, -1, 0}, +/* 33 */ { 5, s_0_33, 31, -1, 0}, +/* 34 */ { 4, s_0_34, 9, -1, 0}, +/* 35 */ { 3, s_0_35, 9, -1, 0}, +/* 36 */ { 4, s_0_36, 35, -1, 0}, +/* 37 */ { 3, s_0_37, 9, -1, 0}, +/* 38 */ { 4, s_0_38, 37, -1, 0}, +/* 39 */ { 4, s_0_39, 37, -1, 0}, +/* 40 */ { 3, s_0_40, 9, -1, 0}, +/* 41 */ { 4, s_0_41, 9, -1, 0}, +/* 42 */ { 4, s_0_42, 9, -1, 0}, +/* 43 */ { 7, s_0_43, 42, -1, 0}, +/* 44 */ { 1, s_0_44, -1, -1, 0}, +/* 45 */ { 2, s_0_45, 44, -1, 0}, +/* 46 */ { 3, s_0_46, 45, -1, 0}, +/* 47 */ { 5, s_0_47, 46, -1, 0}, +/* 48 */ { 2, s_0_48, 44, -1, 0}, +/* 49 */ { 5, s_0_49, 48, -1, 0}, +/* 50 */ { 2, s_0_50, 44, -1, 0}, +/* 51 */ { 3, s_0_51, 44, -1, 0}, +/* 52 */ { 5, s_0_52, 51, -1, 0}, +/* 53 */ { 3, s_0_53, 44, -1, 0}, +/* 54 */ { 4, s_0_54, 53, -1, 0}, +/* 55 */ { 2, s_0_55, 44, -1, 0}, +/* 56 */ { 3, s_0_56, 55, -1, 0}, +/* 57 */ { 4, s_0_57, 56, -1, 0}, +/* 58 */ { 3, s_0_58, 55, -1, 0}, +/* 59 */ { 4, s_0_59, 58, -1, 0}, +/* 60 */ { 5, s_0_60, 59, -1, 0}, +/* 61 */ { 3, s_0_61, 55, -1, 0}, +/* 62 */ { 4, s_0_62, 61, -1, 0}, +/* 63 */ { 4, s_0_63, 61, -1, 0}, +/* 64 */ { 7, s_0_64, 63, -1, 0}, +/* 65 */ { 4, s_0_65, 61, -1, 0}, +/* 66 */ { 3, s_0_66, 55, -1, 0}, +/* 67 */ { 6, s_0_67, 66, -1, 0}, +/* 68 */ { 4, s_0_68, 66, -1, 0}, +/* 69 */ { 5, s_0_69, 68, -1, 0}, +/* 70 */ { 6, s_0_70, 69, -1, 0}, +/* 71 */ { 3, s_0_71, 55, -1, 0}, +/* 72 */ { 4, s_0_72, 71, -1, 0}, +/* 73 */ { 7, s_0_73, 72, -1, 0}, +/* 74 */ { 4, s_0_74, 55, -1, 0}, +/* 75 */ { 4, s_0_75, 55, -1, 0}, +/* 76 */ { 4, s_0_76, 55, -1, 0}, +/* 77 */ { 5, s_0_77, 76, -1, 0}, +/* 78 */ { 2, s_0_78, 44, -1, 0}, +/* 79 */ { 4, s_0_79, 78, -1, 0}, +/* 80 */ { 4, s_0_80, 78, -1, 0}, +/* 81 */ { 3, s_0_81, 78, -1, 0}, +/* 82 */ { 4, s_0_82, 81, -1, 0}, +/* 83 */ { 4, s_0_83, 81, -1, 0}, +/* 84 */ { 5, s_0_84, 83, -1, 0}, +/* 85 */ { 4, s_0_85, 78, -1, 0}, +/* 86 */ { 5, s_0_86, 85, -1, 0}, +/* 87 */ { 3, s_0_87, 78, -1, 0}, +/* 88 */ { 4, s_0_88, 78, -1, 0}, +/* 89 */ { 7, s_0_89, 88, -1, 0}, +/* 90 */ { 6, s_0_90, 88, -1, 0}, +/* 91 */ { 7, s_0_91, 88, -1, 0}, +/* 92 */ { 2, s_0_92, 44, -1, 0}, +/* 93 */ { 3, s_0_93, 92, -1, 0}, +/* 94 */ { 5, s_0_94, 93, -1, 0}, +/* 95 */ { 2, s_0_95, -1, -1, 0}, +/* 96 */ { 3, s_0_96, -1, -1, 0}, +/* 97 */ { 1, s_0_97, -1, -1, 0}, +/* 98 */ { 2, s_0_98, -1, -1, 0}, +/* 99 */ { 3, s_0_99, 98, -1, 0}, +/*100 */ { 3, s_0_100, -1, -1, 0}, +/*101 */ { 2, s_0_101, -1, -1, 0}, +/*102 */ { 3, s_0_102, 101, -1, 0}, +/*103 */ { 2, s_0_103, -1, -1, 0}, +/*104 */ { 3, s_0_104, -1, -1, 0}, +/*105 */ { 3, s_0_105, -1, -1, 0}, +/*106 */ { 6, s_0_106, 105, -1, 0}, +/*107 */ { 2, s_0_107, -1, -1, 0}, +/*108 */ { 2, s_0_108, -1, -1, 0}, +/*109 */ { 3, s_0_109, 108, -1, 0}, +/*110 */ { 2, s_0_110, -1, -1, 0}, +/*111 */ { 3, s_0_111, 110, -1, 0}, +/*112 */ { 3, s_0_112, -1, -1, 0}, +/*113 */ { 1, s_0_113, -1, -1, 0}, +/*114 */ { 2, s_0_114, 113, -1, 0}, +/*115 */ { 4, s_0_115, 114, -1, 0}, +/*116 */ { 4, s_0_116, 113, -1, 0}, +/*117 */ { 2, s_0_117, 113, -1, 0}, +/*118 */ { 1, s_0_118, -1, -1, 0}, +/*119 */ { 2, s_0_119, 118, -1, 0}, +/*120 */ { 3, s_0_120, 119, -1, 0}, +/*121 */ { 2, s_0_121, 118, -1, 0}, +/*122 */ { 3, s_0_122, 121, -1, 0}, +/*123 */ { 2, s_0_123, 118, -1, 0}, +/*124 */ { 3, s_0_124, 123, -1, 0}, +/*125 */ { 4, s_0_125, 124, -1, 0}, +/*126 */ { 6, s_0_126, 123, -1, 0}, +/*127 */ { 4, s_0_127, 123, -1, 0}, +/*128 */ { 6, s_0_128, 127, -1, 0}, +/*129 */ { 4, s_0_129, 123, -1, 0}, +/*130 */ { 5, s_0_130, 129, -1, 0}, +/*131 */ { 4, s_0_131, 123, -1, 0}, +/*132 */ { 5, s_0_132, 123, -1, 0}, +/*133 */ { 4, s_0_133, 123, -1, 0}, +/*134 */ { 4, s_0_134, 123, -1, 0}, +/*135 */ { 4, s_0_135, 123, -1, 0}, +/*136 */ { 3, s_0_136, 118, -1, 0}, +/*137 */ { 4, s_0_137, 136, -1, 0}, +/*138 */ { 4, s_0_138, 118, -1, 0}, +/*139 */ { 3, s_0_139, 118, -1, 0}, +/*140 */ { 5, s_0_140, 139, -1, 0}, +/*141 */ { 5, s_0_141, 139, -1, 0}, +/*142 */ { 3, s_0_142, 118, -1, 0}, +/*143 */ { 4, s_0_143, 142, -1, 0}, +/*144 */ { 3, s_0_144, 118, -1, 0}, +/*145 */ { 4, s_0_145, 118, -1, 0}, +/*146 */ { 3, s_0_146, 118, -1, 0}, +/*147 */ { 2, s_0_147, 118, -1, 0}, +/*148 */ { 3, s_0_148, 147, -1, 0}, +/*149 */ { 3, s_0_149, 147, -1, 0}, +/*150 */ { 4, s_0_150, 149, -1, 0}, +/*151 */ { 3, s_0_151, 118, -1, 0}, +/*152 */ { 2, s_0_152, 118, -1, 0}, +/*153 */ { 3, s_0_153, 152, -1, 0}, +/*154 */ { 4, s_0_154, 153, -1, 0}, +/*155 */ { 3, s_0_155, 152, -1, 0}, +/*156 */ { 2, s_0_156, 118, -1, 0}, +/*157 */ { 4, s_0_157, 156, -1, 0}, +/*158 */ { 4, s_0_158, 156, -1, 0}, +/*159 */ { 3, s_0_159, 118, -1, 0}, +/*160 */ { 4, s_0_160, 159, -1, 0}, +/*161 */ { 3, s_0_161, 118, -1, 0}, +/*162 */ { 5, s_0_162, 161, -1, 0}, +/*163 */ { 6, s_0_163, 162, -1, 0}, +/*164 */ { 5, s_0_164, 161, -1, 0}, +/*165 */ { 6, s_0_165, 164, -1, 0}, +/*166 */ { 6, s_0_166, 164, -1, 0}, +/*167 */ { 5, s_0_167, 161, -1, 0}, +/*168 */ { 6, s_0_168, 161, -1, 0}, +/*169 */ { 9, s_0_169, 168, -1, 0}, +/*170 */ { 5, s_0_170, 161, -1, 0}, +/*171 */ { 6, s_0_171, 170, -1, 0}, +/*172 */ { 6, s_0_172, 161, -1, 0}, +/*173 */ { 5, s_0_173, 161, -1, 0}, +/*174 */ { 6, s_0_174, 161, -1, 0}, +/*175 */ { 9, s_0_175, 174, -1, 0}, +/*176 */ { 3, s_0_176, 118, -1, 0}, +/*177 */ { 3, s_0_177, 118, -1, 0}, +/*178 */ { 4, s_0_178, 118, -1, 0}, +/*179 */ { 2, s_0_179, -1, -1, 0}, +/*180 */ { 3, s_0_180, 179, -1, 0}, +/*181 */ { 2, s_0_181, -1, -1, 0}, +/*182 */ { 3, s_0_182, 181, -1, 0}, +/*183 */ { 2, s_0_183, -1, -1, 0}, +/*184 */ { 3, s_0_184, -1, -1, 0}, +/*185 */ { 6, s_0_185, 184, -1, 0}, +/*186 */ { 1, s_0_186, -1, -1, 0}, +/*187 */ { 2, s_0_187, 186, -1, 0}, +/*188 */ { 3, s_0_188, 187, -1, 0}, +/*189 */ { 5, s_0_189, 188, -1, 0}, +/*190 */ { 2, s_0_190, 186, -1, 0}, +/*191 */ { 4, s_0_191, 190, -1, 0}, +/*192 */ { 3, s_0_192, 190, -1, 0}, +/*193 */ { 1, s_0_193, -1, -1, 0}, +/*194 */ { 2, s_0_194, -1, -1, 0}, +/*195 */ { 3, s_0_195, 194, -1, 0}, +/*196 */ { 2, s_0_196, -1, -1, 0}, +/*197 */ { 2, s_0_197, -1, -1, 0}, +/*198 */ { 2, s_0_198, -1, -1, 0}, +/*199 */ { 4, s_0_199, 198, -1, 0}, +/*200 */ { 4, s_0_200, 198, -1, 0}, +/*201 */ { 2, s_0_201, -1, -1, 0}, +/*202 */ { 3, s_0_202, 201, -1, 0}, +/*203 */ { 4, s_0_203, 201, -1, 0} +}; + +static const symbol s_1_0[3] = { 'i', 'n', 'g' }; +static const symbol s_1_1[2] = { 'a', 'j' }; +static const symbol s_1_2[3] = { 'i', 'a', 'j' }; +static const symbol s_1_3[3] = { 'i', 'e', 'j' }; +static const symbol s_1_4[2] = { 'o', 'j' }; +static const symbol s_1_5[3] = { 'i', 'o', 'j' }; +static const symbol s_1_6[3] = { 'u', 'o', 'j' }; +static const symbol s_1_7[4] = { 'i', 'u', 'o', 'j' }; +static const symbol s_1_8[3] = { 'a', 'u', 'j' }; +static const symbol s_1_9[3] = { 0xC4, 0x85, 'j' }; +static const symbol s_1_10[4] = { 'i', 0xC4, 0x85, 'j' }; +static const symbol s_1_11[3] = { 0xC4, 0x97, 'j' }; +static const symbol s_1_12[3] = { 0xC5, 0xB3, 'j' }; +static const symbol s_1_13[4] = { 'i', 0xC5, 0xB3, 'j' }; +static const symbol s_1_14[2] = { 'o', 'k' }; +static const symbol s_1_15[3] = { 'i', 'o', 'k' }; +static const symbol s_1_16[3] = { 'i', 'u', 'k' }; +static const symbol s_1_17[5] = { 'u', 'l', 'i', 'u', 'k' }; +static const symbol s_1_18[6] = { 'u', 0xC4, 0x8D, 'i', 'u', 'k' }; +static const symbol s_1_19[4] = { 'i', 0xC5, 0xA1, 'k' }; +static const symbol s_1_20[3] = { 'i', 'u', 'l' }; +static const symbol s_1_21[2] = { 'y', 'l' }; +static const symbol s_1_22[3] = { 0xC4, 0x97, 'l' }; +static const symbol s_1_23[2] = { 'a', 'm' }; +static const symbol s_1_24[3] = { 'd', 'a', 'm' }; +static const symbol s_1_25[3] = { 'j', 'a', 'm' }; +static const symbol s_1_26[4] = { 'z', 'g', 'a', 'n' }; +static const symbol s_1_27[3] = { 'a', 'i', 'n' }; +static const symbol s_1_28[3] = { 'e', 's', 'n' }; +static const symbol s_1_29[2] = { 'o', 'p' }; +static const symbol s_1_30[3] = { 'i', 'o', 'p' }; +static const symbol s_1_31[3] = { 'i', 'a', 's' }; +static const symbol s_1_32[3] = { 'i', 'e', 's' }; +static const symbol s_1_33[3] = { 'a', 'i', 's' }; +static const symbol s_1_34[4] = { 'i', 'a', 'i', 's' }; +static const symbol s_1_35[2] = { 'o', 's' }; +static const symbol s_1_36[3] = { 'i', 'o', 's' }; +static const symbol s_1_37[3] = { 'u', 'o', 's' }; +static const symbol s_1_38[4] = { 'i', 'u', 'o', 's' }; +static const symbol s_1_39[3] = { 'a', 'u', 's' }; +static const symbol s_1_40[4] = { 'i', 'a', 'u', 's' }; +static const symbol s_1_41[3] = { 0xC4, 0x85, 's' }; +static const symbol s_1_42[4] = { 'i', 0xC4, 0x85, 's' }; +static const symbol s_1_43[3] = { 0xC4, 0x99, 's' }; +static const symbol s_1_44[7] = { 'u', 't', 0xC4, 0x97, 'a', 'i', 't' }; +static const symbol s_1_45[3] = { 'a', 'n', 't' }; +static const symbol s_1_46[4] = { 'i', 'a', 'n', 't' }; +static const symbol s_1_47[5] = { 's', 'i', 'a', 'n', 't' }; +static const symbol s_1_48[3] = { 'i', 'n', 't' }; +static const symbol s_1_49[2] = { 'o', 't' }; +static const symbol s_1_50[3] = { 'u', 'o', 't' }; +static const symbol s_1_51[4] = { 'i', 'u', 'o', 't' }; +static const symbol s_1_52[2] = { 'y', 't' }; +static const symbol s_1_53[3] = { 0xC4, 0x97, 't' }; +static const symbol s_1_54[5] = { 'y', 'k', 0xC5, 0xA1, 't' }; +static const symbol s_1_55[3] = { 'i', 'a', 'u' }; +static const symbol s_1_56[3] = { 'd', 'a', 'v' }; +static const symbol s_1_57[2] = { 's', 'v' }; +static const symbol s_1_58[3] = { 0xC5, 0xA1, 'v' }; +static const symbol s_1_59[6] = { 'y', 'k', 0xC5, 0xA1, 0xC4, 0x8D }; +static const symbol s_1_60[2] = { 0xC4, 0x99 }; +static const symbol s_1_61[5] = { 0xC4, 0x97, 'j', 0xC4, 0x99 }; + +static const struct among a_1[62] = +{ +/* 0 */ { 3, s_1_0, -1, -1, 0}, +/* 1 */ { 2, s_1_1, -1, -1, 0}, +/* 2 */ { 3, s_1_2, 1, -1, 0}, +/* 3 */ { 3, s_1_3, -1, -1, 0}, +/* 4 */ { 2, s_1_4, -1, -1, 0}, +/* 5 */ { 3, s_1_5, 4, -1, 0}, +/* 6 */ { 3, s_1_6, 4, -1, 0}, +/* 7 */ { 4, s_1_7, 6, -1, 0}, +/* 8 */ { 3, s_1_8, -1, -1, 0}, +/* 9 */ { 3, s_1_9, -1, -1, 0}, +/* 10 */ { 4, s_1_10, 9, -1, 0}, +/* 11 */ { 3, s_1_11, -1, -1, 0}, +/* 12 */ { 3, s_1_12, -1, -1, 0}, +/* 13 */ { 4, s_1_13, 12, -1, 0}, +/* 14 */ { 2, s_1_14, -1, -1, 0}, +/* 15 */ { 3, s_1_15, 14, -1, 0}, +/* 16 */ { 3, s_1_16, -1, -1, 0}, +/* 17 */ { 5, s_1_17, 16, -1, 0}, +/* 18 */ { 6, s_1_18, 16, -1, 0}, +/* 19 */ { 4, s_1_19, -1, -1, 0}, +/* 20 */ { 3, s_1_20, -1, -1, 0}, +/* 21 */ { 2, s_1_21, -1, -1, 0}, +/* 22 */ { 3, s_1_22, -1, -1, 0}, +/* 23 */ { 2, s_1_23, -1, -1, 0}, +/* 24 */ { 3, s_1_24, 23, -1, 0}, +/* 25 */ { 3, s_1_25, 23, -1, 0}, +/* 26 */ { 4, s_1_26, -1, -1, 0}, +/* 27 */ { 3, s_1_27, -1, -1, 0}, +/* 28 */ { 3, s_1_28, -1, -1, 0}, +/* 29 */ { 2, s_1_29, -1, -1, 0}, +/* 30 */ { 3, s_1_30, 29, -1, 0}, +/* 31 */ { 3, s_1_31, -1, -1, 0}, +/* 32 */ { 3, s_1_32, -1, -1, 0}, +/* 33 */ { 3, s_1_33, -1, -1, 0}, +/* 34 */ { 4, s_1_34, 33, -1, 0}, +/* 35 */ { 2, s_1_35, -1, -1, 0}, +/* 36 */ { 3, s_1_36, 35, -1, 0}, +/* 37 */ { 3, s_1_37, 35, -1, 0}, +/* 38 */ { 4, s_1_38, 37, -1, 0}, +/* 39 */ { 3, s_1_39, -1, -1, 0}, +/* 40 */ { 4, s_1_40, 39, -1, 0}, +/* 41 */ { 3, s_1_41, -1, -1, 0}, +/* 42 */ { 4, s_1_42, 41, -1, 0}, +/* 43 */ { 3, s_1_43, -1, -1, 0}, +/* 44 */ { 7, s_1_44, -1, -1, 0}, +/* 45 */ { 3, s_1_45, -1, -1, 0}, +/* 46 */ { 4, s_1_46, 45, -1, 0}, +/* 47 */ { 5, s_1_47, 46, -1, 0}, +/* 48 */ { 3, s_1_48, -1, -1, 0}, +/* 49 */ { 2, s_1_49, -1, -1, 0}, +/* 50 */ { 3, s_1_50, 49, -1, 0}, +/* 51 */ { 4, s_1_51, 50, -1, 0}, +/* 52 */ { 2, s_1_52, -1, -1, 0}, +/* 53 */ { 3, s_1_53, -1, -1, 0}, +/* 54 */ { 5, s_1_54, -1, -1, 0}, +/* 55 */ { 3, s_1_55, -1, -1, 0}, +/* 56 */ { 3, s_1_56, -1, -1, 0}, +/* 57 */ { 2, s_1_57, -1, -1, 0}, +/* 58 */ { 3, s_1_58, -1, -1, 0}, +/* 59 */ { 6, s_1_59, -1, -1, 0}, +/* 60 */ { 2, s_1_60, -1, -1, 0}, +/* 61 */ { 5, s_1_61, 60, -1, 0} +}; + +static const symbol s_2_0[5] = { 'o', 'j', 'i', 'm', 'e' }; +static const symbol s_2_1[6] = { 0xC4, 0x97, 'j', 'i', 'm', 'e' }; +static const symbol s_2_2[5] = { 'a', 'v', 'i', 'm', 'e' }; +static const symbol s_2_3[5] = { 'o', 'k', 'a', 't', 'e' }; +static const symbol s_2_4[4] = { 'a', 'i', 't', 'e' }; +static const symbol s_2_5[4] = { 'u', 'o', 't', 'e' }; +static const symbol s_2_6[5] = { 'a', 's', 'i', 'u', 's' }; +static const symbol s_2_7[7] = { 'o', 'k', 'a', 't', 0xC4, 0x97, 's' }; +static const symbol s_2_8[6] = { 'a', 'i', 't', 0xC4, 0x97, 's' }; +static const symbol s_2_9[6] = { 'u', 'o', 't', 0xC4, 0x97, 's' }; +static const symbol s_2_10[4] = { 'e', 's', 'i', 'u' }; + +static const struct among a_2[11] = +{ +/* 0 */ { 5, s_2_0, -1, 7, 0}, +/* 1 */ { 6, s_2_1, -1, 3, 0}, +/* 2 */ { 5, s_2_2, -1, 6, 0}, +/* 3 */ { 5, s_2_3, -1, 8, 0}, +/* 4 */ { 4, s_2_4, -1, 1, 0}, +/* 5 */ { 4, s_2_5, -1, 2, 0}, +/* 6 */ { 5, s_2_6, -1, 5, 0}, +/* 7 */ { 7, s_2_7, -1, 8, 0}, +/* 8 */ { 6, s_2_8, -1, 1, 0}, +/* 9 */ { 6, s_2_9, -1, 2, 0}, +/* 10 */ { 4, s_2_10, -1, 4, 0} +}; + +static const symbol s_3_0[2] = { 0xC4, 0x8D }; +static const symbol s_3_1[3] = { 'd', 0xC5, 0xBE }; + +static const struct among a_3[2] = +{ +/* 0 */ { 2, s_3_0, -1, 1, 0}, +/* 1 */ { 3, s_3_1, -1, 2, 0} +}; + +static const symbol s_4_0[2] = { 'g', 'd' }; + +static const struct among a_4[1] = +{ +/* 0 */ { 2, s_4_0, -1, 1, 0} +}; + +static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 64, 1, 0, 64, 0, 0, 0, 0, 0, 0, 0, 4, 4 }; + +static const symbol s_0[] = { 'a', 'i', 't', 0xC4, 0x97 }; +static const symbol s_1[] = { 'u', 'o', 't', 0xC4, 0x97 }; +static const symbol s_2[] = { 0xC4, 0x97, 'j', 'i', 'm', 'a', 's' }; +static const symbol s_3[] = { 'e', 's', 'y', 's' }; +static const symbol s_4[] = { 'a', 's', 'y', 's' }; +static const symbol s_5[] = { 'a', 'v', 'i', 'm', 'a', 's' }; +static const symbol s_6[] = { 'o', 'j', 'i', 'm', 'a', 's' }; +static const symbol s_7[] = { 'o', 'k', 'a', 't', 0xC4, 0x97 }; +static const symbol s_8[] = { 't' }; +static const symbol s_9[] = { 'd' }; +static const symbol s_10[] = { 'g' }; + +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 43 */ + return 1; +} + +static int r_step1(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 45 */ + if (z->c < z->I[0]) return 0; + mlimit1 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 45 */ + if (!(find_among_b(z, a_0, 204))) { z->lb = mlimit1; return 0; } /* substring, line 45 */ + z->bra = z->c; /* ], line 45 */ + z->lb = mlimit1; + } + { int ret = r_R1(z); /* call R1, line 45 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 229 */ + if (ret < 0) return ret; + } + return 1; +} + +static int r_step2(struct SN_env * z) { /* backwardmode */ + while(1) { /* repeat, line 232 */ + int m1 = z->l - z->c; (void)m1; + + { int mlimit2; /* setlimit, line 233 */ + if (z->c < z->I[0]) goto lab0; + mlimit2 = z->lb; z->lb = z->I[0]; + z->ket = z->c; /* [, line 233 */ + if (!(find_among_b(z, a_1, 62))) { z->lb = mlimit2; goto lab0; } /* substring, line 233 */ + z->bra = z->c; /* ], line 233 */ + z->lb = mlimit2; + } + { int ret = slice_del(z); /* delete, line 303 */ + if (ret < 0) return ret; + } + continue; + lab0: + z->c = z->l - m1; + break; + } + return 1; +} + +static int r_fix_conflicts(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 307 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((2621472 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 307 */ + among_var = find_among_b(z, a_2, 11); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 307 */ + switch (among_var) { /* among, line 307 */ + case 1: + { int ret = slice_from_s(z, 5, s_0); /* <-, line 309 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 5, s_1); /* <-, line 314 */ + if (ret < 0) return ret; + } + break; + case 3: + { int ret = slice_from_s(z, 7, s_2); /* <-, line 319 */ + if (ret < 0) return ret; + } + break; + case 4: + { int ret = slice_from_s(z, 4, s_3); /* <-, line 322 */ + if (ret < 0) return ret; + } + break; + case 5: + { int ret = slice_from_s(z, 4, s_4); /* <-, line 324 */ + if (ret < 0) return ret; + } + break; + case 6: + { int ret = slice_from_s(z, 6, s_5); /* <-, line 327 */ + if (ret < 0) return ret; + } + break; + case 7: + { int ret = slice_from_s(z, 6, s_6); /* <-, line 328 */ + if (ret < 0) return ret; + } + break; + case 8: + { int ret = slice_from_s(z, 6, s_7); /* <-, line 331 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_fix_chdz(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 338 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 190)) return 0; /* substring, line 338 */ + among_var = find_among_b(z, a_3, 2); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 338 */ + switch (among_var) { /* among, line 338 */ + case 1: + { int ret = slice_from_s(z, 1, s_8); /* <-, line 339 */ + if (ret < 0) return ret; + } + break; + case 2: + { int ret = slice_from_s(z, 1, s_9); /* <-, line 340 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_fix_gd(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 345 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 100) return 0; /* substring, line 345 */ + if (!(find_among_b(z, a_4, 1))) return 0; + z->bra = z->c; /* ], line 345 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 346 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int lithuanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 355 */ + { int c1 = z->c; /* do, line 357 */ + { int c2 = z->c; /* try, line 359 */ + { int c_test3 = z->c; /* test, line 359 */ + if (z->c == z->l || z->p[z->c] != 'a') { z->c = c2; goto lab1; } /* literal, line 359 */ + z->c++; + z->c = c_test3; + } + if (!(len_utf8(z->p) > 6)) { z->c = c2; goto lab1; } /* $( > ), line 359 */ + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 1); /* hop, line 359 */ + if (ret < 0) { z->c = c2; goto lab1; } + z->c = ret; + } + lab1: + ; + } + { /* gopast */ /* grouping v, line 361 */ + int ret = out_grouping_U(z, g_v, 97, 371, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + { /* gopast */ /* non v, line 361 */ + int ret = in_grouping_U(z, g_v, 97, 371, 1); + if (ret < 0) goto lab0; + z->c += ret; + } + z->I[0] = z->c; /* setmark p1, line 361 */ + lab0: + z->c = c1; + } + z->lb = z->c; z->c = z->l; /* backwards, line 364 */ + + { int m4 = z->l - z->c; (void)m4; /* do, line 365 */ + { int ret = r_fix_conflicts(z); /* call fix_conflicts, line 365 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = z->l - m4; + } + { int m5 = z->l - z->c; (void)m5; /* do, line 366 */ + { int ret = r_step1(z); /* call step1, line 366 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = z->l - m5; + } + { int m6 = z->l - z->c; (void)m6; /* do, line 367 */ + { int ret = r_fix_chdz(z); /* call fix_chdz, line 367 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + lab4: + z->c = z->l - m6; + } + { int m7 = z->l - z->c; (void)m7; /* do, line 368 */ + { int ret = r_step2(z); /* call step2, line 368 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; + } + lab5: + z->c = z->l - m7; + } + { int m8 = z->l - z->c; (void)m8; /* do, line 369 */ + { int ret = r_fix_chdz(z); /* call fix_chdz, line 369 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + lab6: + z->c = z->l - m8; + } + { int m9 = z->l - z->c; (void)m9; /* do, line 370 */ + { int ret = r_fix_gd(z); /* call fix_gd, line 370 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + lab7: + z->c = z->l - m9; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * lithuanian_UTF_8_create_env(void) { return SN_create_env(0, 1, 0); } + +extern void lithuanian_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c b/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c new file mode 100644 index 00000000000..d1c1be76f37 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_nepali.c @@ -0,0 +1,424 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int nepali_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_remove_category_3(struct SN_env * z); +static int r_remove_category_2(struct SN_env * z); +static int r_check_category_2(struct SN_env * z); +static int r_remove_category_1(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * nepali_UTF_8_create_env(void); +extern void nepali_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[6] = { 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; +static const symbol s_0_1[9] = { 0xE0, 0xA4, 0xB2, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0x87 }; +static const symbol s_0_2[6] = { 0xE0, 0xA4, 0xB2, 0xE0, 0xA5, 0x87 }; +static const symbol s_0_3[9] = { 0xE0, 0xA4, 0xB2, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0x88 }; +static const symbol s_0_4[6] = { 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x88 }; +static const symbol s_0_5[12] = { 0xE0, 0xA4, 0xB8, 0xE0, 0xA4, 0x81, 0xE0, 0xA4, 0x97, 0xE0, 0xA5, 0x88 }; +static const symbol s_0_6[6] = { 0xE0, 0xA4, 0xAE, 0xE0, 0xA5, 0x88 }; +static const symbol s_0_7[6] = { 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_0_8[9] = { 0xE0, 0xA4, 0xB8, 0xE0, 0xA4, 0x81, 0xE0, 0xA4, 0x97 }; +static const symbol s_0_9[9] = { 0xE0, 0xA4, 0xB8, 0xE0, 0xA4, 0x82, 0xE0, 0xA4, 0x97 }; +static const symbol s_0_10[18] = { 0xE0, 0xA4, 0xAE, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0xB0, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xAB, 0xE0, 0xA4, 0xA4 }; +static const symbol s_0_11[6] = { 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xA4 }; +static const symbol s_0_12[6] = { 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_0_13[6] = { 0xE0, 0xA4, 0xAE, 0xE0, 0xA4, 0xBE }; +static const symbol s_0_14[18] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xB5, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBE }; +static const symbol s_0_15[6] = { 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBF }; +static const symbol s_0_16[9] = { 0xE0, 0xA4, 0xAA, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xBF }; + +static const struct among a_0[17] = +{ +/* 0 */ { 6, s_0_0, -1, 2, 0}, +/* 1 */ { 9, s_0_1, -1, 1, 0}, +/* 2 */ { 6, s_0_2, -1, 1, 0}, +/* 3 */ { 9, s_0_3, -1, 1, 0}, +/* 4 */ { 6, s_0_4, -1, 2, 0}, +/* 5 */ { 12, s_0_5, -1, 1, 0}, +/* 6 */ { 6, s_0_6, -1, 1, 0}, +/* 7 */ { 6, s_0_7, -1, 2, 0}, +/* 8 */ { 9, s_0_8, -1, 1, 0}, +/* 9 */ { 9, s_0_9, -1, 1, 0}, +/* 10 */ { 18, s_0_10, -1, 1, 0}, +/* 11 */ { 6, s_0_11, -1, 1, 0}, +/* 12 */ { 6, s_0_12, -1, 2, 0}, +/* 13 */ { 6, s_0_13, -1, 1, 0}, +/* 14 */ { 18, s_0_14, -1, 1, 0}, +/* 15 */ { 6, s_0_15, -1, 2, 0}, +/* 16 */ { 9, s_0_16, -1, 1, 0} +}; + +static const symbol s_1_0[3] = { 0xE0, 0xA4, 0x81 }; +static const symbol s_1_1[3] = { 0xE0, 0xA4, 0x82 }; +static const symbol s_1_2[3] = { 0xE0, 0xA5, 0x88 }; + +static const struct among a_1[3] = +{ +/* 0 */ { 3, s_1_0, -1, -1, 0}, +/* 1 */ { 3, s_1_1, -1, -1, 0}, +/* 2 */ { 3, s_1_2, -1, -1, 0} +}; + +static const symbol s_2_0[3] = { 0xE0, 0xA4, 0x81 }; +static const symbol s_2_1[3] = { 0xE0, 0xA4, 0x82 }; +static const symbol s_2_2[3] = { 0xE0, 0xA5, 0x88 }; + +static const struct among a_2[3] = +{ +/* 0 */ { 3, s_2_0, -1, 1, 0}, +/* 1 */ { 3, s_2_1, -1, 1, 0}, +/* 2 */ { 3, s_2_2, -1, 2, 0} +}; + +static const symbol s_3_0[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_1[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_2[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_3[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_4[12] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x96, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_5[6] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_6[6] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x80 }; +static const symbol s_3_7[6] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_8[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_9[12] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_10[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_11[6] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_12[9] = { 0xE0, 0xA4, 0xB9, 0xE0, 0xA4, 0xB0, 0xE0, 0xA5, 0x81 }; +static const symbol s_3_13[9] = { 0xE0, 0xA4, 0xB9, 0xE0, 0xA4, 0xB0, 0xE0, 0xA5, 0x82 }; +static const symbol s_3_14[6] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x87 }; +static const symbol s_3_15[6] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x87 }; +static const symbol s_3_16[6] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87 }; +static const symbol s_3_17[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_18[12] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_19[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_20[6] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_21[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_22[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x88 }; +static const symbol s_3_23[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_24[12] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_25[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_26[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_27[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_28[6] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_29[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_30[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_31[6] = { 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_32[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_33[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_34[9] = { 0xE0, 0xA4, 0xAD, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_35[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_36[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_37[12] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8B }; +static const symbol s_3_38[6] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_39[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_40[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_41[12] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_42[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_43[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_44[6] = { 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_45[12] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_46[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_47[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8C }; +static const symbol s_3_48[9] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_49[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_50[12] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_51[15] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_52[12] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_53[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_54[12] = { 0xE0, 0xA4, 0xB2, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_55[12] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_56[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_57[9] = { 0xE0, 0xA4, 0xAA, 0xE0, 0xA4, 0xB0, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_58[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_59[15] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_60[12] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_61[12] = { 0xE0, 0xA4, 0xB9, 0xE0, 0xA5, 0x8B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_62[9] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_63[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_64[12] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_65[15] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_66[12] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_67[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x9B, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_68[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_69[12] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D }; +static const symbol s_3_70[9] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x8F }; +static const symbol s_3_71[3] = { 0xE0, 0xA4, 0x9B }; +static const symbol s_3_72[6] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_73[6] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_74[9] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_75[15] = { 0xE0, 0xA4, 0xB9, 0xE0, 0xA5, 0x81, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_76[15] = { 0xE0, 0xA4, 0xB9, 0xE0, 0xA5, 0x81, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_77[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_78[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_79[6] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_80[6] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x9B }; +static const symbol s_3_81[9] = { 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_82[12] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_83[9] = { 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_84[12] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_85[12] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0x8F, 0xE0, 0xA4, 0x95, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_86[6] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_87[9] = { 0xE0, 0xA4, 0x87, 0xE0, 0xA4, 0xA6, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_88[9] = { 0xE0, 0xA4, 0xBF, 0xE0, 0xA4, 0xA6, 0xE0, 0xA4, 0xBE }; +static const symbol s_3_89[12] = { 0xE0, 0xA4, 0xA6, 0xE0, 0xA5, 0x87, 0xE0, 0xA4, 0x96, 0xE0, 0xA4, 0xBF }; +static const symbol s_3_90[12] = { 0xE0, 0xA4, 0xAE, 0xE0, 0xA4, 0xBE, 0xE0, 0xA4, 0xA5, 0xE0, 0xA4, 0xBF }; + +static const struct among a_3[91] = +{ +/* 0 */ { 9, s_3_0, -1, 1, 0}, +/* 1 */ { 9, s_3_1, -1, 1, 0}, +/* 2 */ { 12, s_3_2, 1, 1, 0}, +/* 3 */ { 12, s_3_3, 1, 1, 0}, +/* 4 */ { 12, s_3_4, -1, 1, 0}, +/* 5 */ { 6, s_3_5, -1, 1, 0}, +/* 6 */ { 6, s_3_6, -1, 1, 0}, +/* 7 */ { 6, s_3_7, -1, 1, 0}, +/* 8 */ { 9, s_3_8, 7, 1, 0}, +/* 9 */ { 12, s_3_9, 8, 1, 0}, +/* 10 */ { 9, s_3_10, 7, 1, 0}, +/* 11 */ { 6, s_3_11, -1, 1, 0}, +/* 12 */ { 9, s_3_12, -1, 1, 0}, +/* 13 */ { 9, s_3_13, -1, 1, 0}, +/* 14 */ { 6, s_3_14, -1, 1, 0}, +/* 15 */ { 6, s_3_15, -1, 1, 0}, +/* 16 */ { 6, s_3_16, -1, 1, 0}, +/* 17 */ { 9, s_3_17, -1, 1, 0}, +/* 18 */ { 12, s_3_18, 17, 1, 0}, +/* 19 */ { 9, s_3_19, -1, 1, 0}, +/* 20 */ { 6, s_3_20, -1, 1, 0}, +/* 21 */ { 9, s_3_21, 20, 1, 0}, +/* 22 */ { 9, s_3_22, 20, 1, 0}, +/* 23 */ { 9, s_3_23, -1, 1, 0}, +/* 24 */ { 12, s_3_24, 23, 1, 0}, +/* 25 */ { 9, s_3_25, -1, 1, 0}, +/* 26 */ { 12, s_3_26, 25, 1, 0}, +/* 27 */ { 12, s_3_27, 25, 1, 0}, +/* 28 */ { 6, s_3_28, -1, 1, 0}, +/* 29 */ { 9, s_3_29, 28, 1, 0}, +/* 30 */ { 9, s_3_30, 28, 1, 0}, +/* 31 */ { 6, s_3_31, -1, 1, 0}, +/* 32 */ { 9, s_3_32, 31, 1, 0}, +/* 33 */ { 12, s_3_33, 31, 1, 0}, +/* 34 */ { 9, s_3_34, 31, 1, 0}, +/* 35 */ { 9, s_3_35, 31, 1, 0}, +/* 36 */ { 12, s_3_36, 35, 1, 0}, +/* 37 */ { 12, s_3_37, 35, 1, 0}, +/* 38 */ { 6, s_3_38, -1, 1, 0}, +/* 39 */ { 9, s_3_39, 38, 1, 0}, +/* 40 */ { 9, s_3_40, 38, 1, 0}, +/* 41 */ { 12, s_3_41, 40, 1, 0}, +/* 42 */ { 9, s_3_42, 38, 1, 0}, +/* 43 */ { 9, s_3_43, 38, 1, 0}, +/* 44 */ { 6, s_3_44, -1, 1, 0}, +/* 45 */ { 12, s_3_45, 44, 1, 0}, +/* 46 */ { 12, s_3_46, 44, 1, 0}, +/* 47 */ { 12, s_3_47, 44, 1, 0}, +/* 48 */ { 9, s_3_48, -1, 1, 0}, +/* 49 */ { 12, s_3_49, 48, 1, 0}, +/* 50 */ { 12, s_3_50, 48, 1, 0}, +/* 51 */ { 15, s_3_51, 50, 1, 0}, +/* 52 */ { 12, s_3_52, 48, 1, 0}, +/* 53 */ { 12, s_3_53, 48, 1, 0}, +/* 54 */ { 12, s_3_54, -1, 1, 0}, +/* 55 */ { 12, s_3_55, -1, 1, 0}, +/* 56 */ { 12, s_3_56, -1, 1, 0}, +/* 57 */ { 9, s_3_57, -1, 1, 0}, +/* 58 */ { 9, s_3_58, -1, 1, 0}, +/* 59 */ { 15, s_3_59, 58, 1, 0}, +/* 60 */ { 12, s_3_60, -1, 1, 0}, +/* 61 */ { 12, s_3_61, -1, 1, 0}, +/* 62 */ { 9, s_3_62, -1, 1, 0}, +/* 63 */ { 12, s_3_63, 62, 1, 0}, +/* 64 */ { 12, s_3_64, 62, 1, 0}, +/* 65 */ { 15, s_3_65, 64, 1, 0}, +/* 66 */ { 12, s_3_66, 62, 1, 0}, +/* 67 */ { 12, s_3_67, 62, 1, 0}, +/* 68 */ { 9, s_3_68, -1, 1, 0}, +/* 69 */ { 12, s_3_69, 68, 1, 0}, +/* 70 */ { 9, s_3_70, -1, 1, 0}, +/* 71 */ { 3, s_3_71, -1, 1, 0}, +/* 72 */ { 6, s_3_72, 71, 1, 0}, +/* 73 */ { 6, s_3_73, 71, 1, 0}, +/* 74 */ { 9, s_3_74, 73, 1, 0}, +/* 75 */ { 15, s_3_75, 74, 1, 0}, +/* 76 */ { 15, s_3_76, 71, 1, 0}, +/* 77 */ { 12, s_3_77, 71, 1, 0}, +/* 78 */ { 12, s_3_78, 71, 1, 0}, +/* 79 */ { 6, s_3_79, 71, 1, 0}, +/* 80 */ { 6, s_3_80, 71, 1, 0}, +/* 81 */ { 9, s_3_81, -1, 1, 0}, +/* 82 */ { 12, s_3_82, 81, 1, 0}, +/* 83 */ { 9, s_3_83, -1, 1, 0}, +/* 84 */ { 12, s_3_84, 83, 1, 0}, +/* 85 */ { 12, s_3_85, 83, 1, 0}, +/* 86 */ { 6, s_3_86, -1, 1, 0}, +/* 87 */ { 9, s_3_87, 86, 1, 0}, +/* 88 */ { 9, s_3_88, 86, 1, 0}, +/* 89 */ { 12, s_3_89, -1, 1, 0}, +/* 90 */ { 12, s_3_90, -1, 1, 0} +}; + +static const symbol s_0[] = { 0xE0, 0xA4, 0x8F }; +static const symbol s_1[] = { 0xE0, 0xA5, 0x87 }; +static const symbol s_2[] = { 0xE0, 0xA4, 0xAF, 0xE0, 0xA5, 0x8C }; +static const symbol s_3[] = { 0xE0, 0xA4, 0x9B, 0xE0, 0xA5, 0x8C }; +static const symbol s_4[] = { 0xE0, 0xA4, 0xA8, 0xE0, 0xA5, 0x8C }; +static const symbol s_5[] = { 0xE0, 0xA4, 0xA5, 0xE0, 0xA5, 0x87 }; +static const symbol s_6[] = { 0xE0, 0xA4, 0xA4, 0xE0, 0xA5, 0x8D, 0xE0, 0xA4, 0xB0 }; + +static int r_remove_category_1(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 54 */ + among_var = find_among_b(z, a_0, 17); /* substring, line 54 */ + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 54 */ + switch (among_var) { /* among, line 54 */ + case 1: + { int ret = slice_del(z); /* delete, line 58 */ + if (ret < 0) return ret; + } + break; + case 2: + { int m1 = z->l - z->c; (void)m1; /* or, line 59 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 59 */ + if (!(eq_s_b(z, 3, s_0))) goto lab3; /* literal, line 59 */ + goto lab2; + lab3: + z->c = z->l - m2; + if (!(eq_s_b(z, 3, s_1))) goto lab1; /* literal, line 59 */ + } + lab2: + goto lab0; + lab1: + z->c = z->l - m1; + { int ret = slice_del(z); /* delete, line 59 */ + if (ret < 0) return ret; + } + } + lab0: + break; + } + return 1; +} + +static int r_check_category_2(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 64 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 64 */ + if (!(find_among_b(z, a_1, 3))) return 0; + z->bra = z->c; /* ], line 64 */ + return 1; +} + +static int r_remove_category_2(struct SN_env * z) { /* backwardmode */ + int among_var; + z->ket = z->c; /* [, line 70 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((262 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 70 */ + among_var = find_among_b(z, a_2, 3); + if (!(among_var)) return 0; + z->bra = z->c; /* ], line 70 */ + switch (among_var) { /* among, line 70 */ + case 1: + { int m1 = z->l - z->c; (void)m1; /* or, line 71 */ + if (!(eq_s_b(z, 6, s_2))) goto lab1; /* literal, line 71 */ + goto lab0; + lab1: + z->c = z->l - m1; + if (!(eq_s_b(z, 6, s_3))) goto lab2; /* literal, line 71 */ + goto lab0; + lab2: + z->c = z->l - m1; + if (!(eq_s_b(z, 6, s_4))) goto lab3; /* literal, line 71 */ + goto lab0; + lab3: + z->c = z->l - m1; + if (!(eq_s_b(z, 6, s_5))) return 0; /* literal, line 71 */ + } + lab0: + { int ret = slice_del(z); /* delete, line 71 */ + if (ret < 0) return ret; + } + break; + case 2: + if (!(eq_s_b(z, 9, s_6))) return 0; /* literal, line 72 */ + { int ret = slice_del(z); /* delete, line 72 */ + if (ret < 0) return ret; + } + break; + } + return 1; +} + +static int r_remove_category_3(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 77 */ + if (!(find_among_b(z, a_3, 91))) return 0; /* substring, line 77 */ + z->bra = z->c; /* ], line 77 */ + { int ret = slice_del(z); /* delete, line 79 */ + if (ret < 0) return ret; + } + return 1; +} + +extern int nepali_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->lb = z->c; z->c = z->l; /* backwards, line 86 */ + + { int m1 = z->l - z->c; (void)m1; /* do, line 87 */ + { int ret = r_remove_category_1(z); /* call remove_category_1, line 87 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = z->l - m1; + } + { int m2 = z->l - z->c; (void)m2; /* do, line 88 */ + while(1) { /* repeat, line 89 */ + int m3 = z->l - z->c; (void)m3; + { int m4 = z->l - z->c; (void)m4; /* do, line 89 */ + { int m5 = z->l - z->c; (void)m5; /* and, line 89 */ + { int ret = r_check_category_2(z); /* call check_category_2, line 89 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + z->c = z->l - m5; + { int ret = r_remove_category_2(z); /* call remove_category_2, line 89 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + } + lab3: + z->c = z->l - m4; + } + { int ret = r_remove_category_3(z); /* call remove_category_3, line 89 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + continue; + lab2: + z->c = z->l - m3; + break; + } + z->c = z->l - m2; + } + z->c = z->lb; + return 1; +} + +extern struct SN_env * nepali_UTF_8_create_env(void) { return SN_create_env(0, 0, 0); } + +extern void nepali_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c index cbb0cd4601c..62d221be55a 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_norwegian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -129,18 +129,17 @@ static const unsigned char g_v[] = { 17, 65, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 static const unsigned char g_s_ending[] = { 119, 125, 149, 1 }; -static const symbol s_0[] = { 'k' }; -static const symbol s_1[] = { 'e', 'r' }; +static const symbol s_0[] = { 'e', 'r' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 30 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 28 */ + { int c_test1 = z->c; /* test, line 30 */ + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 30 */ if (ret < 0) return 0; - z->c = ret; /* hop, line 30 */ + z->c = ret; } z->I[1] = z->c; /* setmark x, line 30 */ - z->c = c_test; + z->c = c_test1; } if (out_grouping_U(z, g_v, 97, 248, 1) < 0) return 0; /* goto */ /* grouping v, line 31 */ { /* gopast */ /* non v, line 31 */ @@ -149,30 +148,27 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 31 */ - /* try, line 32 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + /* try, line 32 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 32 */ + z->I[0] = z->I[1]; /* $p1 = , line 32 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 38 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 38 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 38 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 38 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 29); /* substring, line 38 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851426 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 38 */ + among_var = find_among_b(z, a_0, 29); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 38 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 39 */ case 1: { int ret = slice_del(z); /* delete, line 44 */ if (ret < 0) return ret; @@ -180,12 +176,13 @@ static int r_main_suffix(struct SN_env * z) { break; case 2: { int m2 = z->l - z->c; (void)m2; /* or, line 46 */ - if (in_grouping_b_U(z, g_s_ending, 98, 122, 0)) goto lab1; + if (in_grouping_b_U(z, g_s_ending, 98, 122, 0)) goto lab1; /* grouping s_ending, line 46 */ goto lab0; lab1: z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_0))) return 0; - if (out_grouping_b_U(z, g_v, 97, 248, 0)) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'k') return 0; /* literal, line 46 */ + z->c--; + if (out_grouping_b_U(z, g_v, 97, 248, 0)) return 0; /* non v, line 46 */ } lab0: { int ret = slice_del(z); /* delete, line 46 */ @@ -193,7 +190,7 @@ static int r_main_suffix(struct SN_env * z) { } break; case 3: - { int ret = slice_from_s(z, 2, s_1); /* <-, line 48 */ + { int ret = slice_from_s(z, 2, s_0); /* <-, line 48 */ if (ret < 0) return ret; } break; @@ -201,21 +198,19 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 53 */ - { int mlimit; /* setlimit, line 54 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 53 */ + + { int mlimit2; /* setlimit, line 54 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 54 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit2 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 54 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit; return 0; } /* substring, line 54 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 116) { z->lb = mlimit2; return 0; } /* substring, line 54 */ + if (!(find_among_b(z, a_1, 2))) { z->lb = mlimit2; return 0; } z->bra = z->c; /* ], line 54 */ - z->lb = mlimit; + z->lb = mlimit2; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; @@ -228,36 +223,27 @@ static int r_consonant_pair(struct SN_env * z) { return 1; } -static int r_other_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 63 */ - int m1 = z->l - z->c; (void)m1; +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 63 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 63 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 63 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 11); /* substring, line 63 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718720 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 63 */ + if (!(find_among_b(z, a_2, 11))) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 63 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 67 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 67 */ + if (ret < 0) return ret; } return 1; } -extern int norwegian_UTF_8_stem(struct SN_env * z) { +extern int norwegian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 74 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 74 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 74 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -266,24 +252,24 @@ extern int norwegian_UTF_8_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 75 */ { int m2 = z->l - z->c; (void)m2; /* do, line 76 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 76 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 76 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 77 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 77 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 77 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 78 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 78 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 78 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_porter.c b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c index 421cc0e74a6..bb83a7449a1 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_porter.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_porter.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -115,21 +115,21 @@ static const struct among a_3[20] = /* 2 */ { 4, s_3_2, -1, 4, 0}, /* 3 */ { 3, s_3_3, -1, 6, 0}, /* 4 */ { 4, s_3_4, -1, 9, 0}, -/* 5 */ { 5, s_3_5, -1, 12, 0}, +/* 5 */ { 5, s_3_5, -1, 11, 0}, /* 6 */ { 5, s_3_6, -1, 5, 0}, -/* 7 */ { 5, s_3_7, -1, 10, 0}, -/* 8 */ { 6, s_3_8, -1, 14, 0}, -/* 9 */ { 5, s_3_9, -1, 13, 0}, +/* 7 */ { 5, s_3_7, -1, 9, 0}, +/* 8 */ { 6, s_3_8, -1, 13, 0}, +/* 9 */ { 5, s_3_9, -1, 12, 0}, /* 10 */ { 6, s_3_10, -1, 1, 0}, /* 11 */ { 7, s_3_11, 10, 8, 0}, -/* 12 */ { 5, s_3_12, -1, 10, 0}, +/* 12 */ { 5, s_3_12, -1, 9, 0}, /* 13 */ { 5, s_3_13, -1, 8, 0}, /* 14 */ { 7, s_3_14, 13, 7, 0}, /* 15 */ { 4, s_3_15, -1, 7, 0}, /* 16 */ { 4, s_3_16, -1, 8, 0}, -/* 17 */ { 7, s_3_17, -1, 13, 0}, -/* 18 */ { 7, s_3_18, -1, 11, 0}, -/* 19 */ { 7, s_3_19, -1, 12, 0} +/* 17 */ { 7, s_3_17, -1, 12, 0}, +/* 18 */ { 7, s_3_18, -1, 10, 0}, +/* 19 */ { 7, s_3_19, -1, 11, 0} }; static const symbol s_4_0[5] = { 'i', 'c', 'a', 't', 'e' }; @@ -203,63 +203,51 @@ static const symbol s_1[] = { 'i' }; static const symbol s_2[] = { 'e', 'e' }; static const symbol s_3[] = { 'e' }; static const symbol s_4[] = { 'e' }; -static const symbol s_5[] = { 'y' }; -static const symbol s_6[] = { 'Y' }; -static const symbol s_7[] = { 'i' }; -static const symbol s_8[] = { 't', 'i', 'o', 'n' }; -static const symbol s_9[] = { 'e', 'n', 'c', 'e' }; -static const symbol s_10[] = { 'a', 'n', 'c', 'e' }; -static const symbol s_11[] = { 'a', 'b', 'l', 'e' }; -static const symbol s_12[] = { 'e', 'n', 't' }; -static const symbol s_13[] = { 'e' }; -static const symbol s_14[] = { 'i', 'z', 'e' }; -static const symbol s_15[] = { 'a', 't', 'e' }; -static const symbol s_16[] = { 'a', 'l' }; -static const symbol s_17[] = { 'a', 'l' }; -static const symbol s_18[] = { 'f', 'u', 'l' }; -static const symbol s_19[] = { 'o', 'u', 's' }; -static const symbol s_20[] = { 'i', 'v', 'e' }; -static const symbol s_21[] = { 'b', 'l', 'e' }; -static const symbol s_22[] = { 'a', 'l' }; -static const symbol s_23[] = { 'i', 'c' }; -static const symbol s_24[] = { 's' }; -static const symbol s_25[] = { 't' }; -static const symbol s_26[] = { 'e' }; -static const symbol s_27[] = { 'l' }; -static const symbol s_28[] = { 'l' }; -static const symbol s_29[] = { 'y' }; -static const symbol s_30[] = { 'Y' }; -static const symbol s_31[] = { 'y' }; -static const symbol s_32[] = { 'Y' }; -static const symbol s_33[] = { 'Y' }; -static const symbol s_34[] = { 'y' }; - -static int r_shortv(struct SN_env * z) { - if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) return 0; - if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; - if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; +static const symbol s_5[] = { 'i' }; +static const symbol s_6[] = { 't', 'i', 'o', 'n' }; +static const symbol s_7[] = { 'e', 'n', 'c', 'e' }; +static const symbol s_8[] = { 'a', 'n', 'c', 'e' }; +static const symbol s_9[] = { 'a', 'b', 'l', 'e' }; +static const symbol s_10[] = { 'e', 'n', 't' }; +static const symbol s_11[] = { 'e' }; +static const symbol s_12[] = { 'i', 'z', 'e' }; +static const symbol s_13[] = { 'a', 't', 'e' }; +static const symbol s_14[] = { 'a', 'l' }; +static const symbol s_15[] = { 'f', 'u', 'l' }; +static const symbol s_16[] = { 'o', 'u', 's' }; +static const symbol s_17[] = { 'i', 'v', 'e' }; +static const symbol s_18[] = { 'b', 'l', 'e' }; +static const symbol s_19[] = { 'a', 'l' }; +static const symbol s_20[] = { 'i', 'c' }; +static const symbol s_21[] = { 'Y' }; +static const symbol s_22[] = { 'Y' }; +static const symbol s_23[] = { 'y' }; + +static int r_shortv(struct SN_env * z) { /* backwardmode */ + if (out_grouping_b_U(z, g_v_WXY, 89, 121, 0)) return 0; /* non v_WXY, line 19 */ + if (in_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* grouping v, line 19 */ + if (out_grouping_b_U(z, g_v, 97, 121, 0)) return 0; /* non v, line 19 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 21 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 22 */ return 1; } -static int r_Step_1a(struct SN_env * z) { +static int r_Step_1a(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 25 */ - if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; - among_var = find_among_b(z, a_0, 4); /* substring, line 25 */ + if (z->c <= z->lb || z->p[z->c - 1] != 115) return 0; /* substring, line 25 */ + among_var = find_among_b(z, a_0, 4); if (!(among_var)) return 0; z->bra = z->c; /* ], line 25 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 25 */ case 1: { int ret = slice_from_s(z, 2, s_0); /* <-, line 26 */ if (ret < 0) return ret; @@ -279,48 +267,47 @@ static int r_Step_1a(struct SN_env * z) { return 1; } -static int r_Step_1b(struct SN_env * z) { +static int r_Step_1b(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 34 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; - among_var = find_among_b(z, a_2, 3); /* substring, line 34 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 100 && z->p[z->c - 1] != 103)) return 0; /* substring, line 34 */ + among_var = find_among_b(z, a_2, 3); if (!(among_var)) return 0; z->bra = z->c; /* ], line 34 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 34 */ case 1: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 35 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 35 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 2, s_2); /* <-, line 35 */ if (ret < 0) return ret; } break; case 2: - { int m_test = z->l - z->c; /* test, line 38 */ + { int m_test1 = z->l - z->c; /* test, line 38 */ { /* gopast */ /* grouping v, line 38 */ int ret = out_grouping_b_U(z, g_v, 97, 121, 1); if (ret < 0) return 0; z->c -= ret; } - z->c = z->l - m_test; + z->c = z->l - m_test1; } { int ret = slice_del(z); /* delete, line 38 */ if (ret < 0) return ret; } - { int m_test = z->l - z->c; /* test, line 39 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else - among_var = find_among_b(z, a_1, 13); /* substring, line 39 */ + { int m_test2 = z->l - z->c; /* test, line 39 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((68514004 >> (z->p[z->c - 1] & 0x1f)) & 1)) among_var = 3; else /* substring, line 39 */ + among_var = find_among_b(z, a_1, 13); if (!(among_var)) return 0; - z->c = z->l - m_test; + z->c = z->l - m_test2; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 39 */ case 1: - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_3); /* <+, line 41 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -337,16 +324,17 @@ static int r_Step_1b(struct SN_env * z) { break; case 3: if (z->c != z->I[0]) return 0; /* atmark, line 45 */ - { int m_test = z->l - z->c; /* test, line 45 */ - { int ret = r_shortv(z); - if (ret == 0) return 0; /* call shortv, line 45 */ - if (ret < 0) return ret; + { int m_test3 = z->l - z->c; /* test, line 45 */ + { int ret = r_shortv(z); /* call shortv, line 45 */ + if (ret <= 0) return ret; } - z->c = z->l - m_test; + z->c = z->l - m_test3; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_4); /* <+, line 45 */ + z->c = saved_c; + } if (ret < 0) return ret; } break; @@ -356,14 +344,16 @@ static int r_Step_1b(struct SN_env * z) { return 1; } -static int r_Step_1c(struct SN_env * z) { +static int r_Step_1c(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 52 */ { int m1 = z->l - z->c; (void)m1; /* or, line 52 */ - if (!(eq_s_b(z, 1, s_5))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 52 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_6))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'Y') return 0; /* literal, line 52 */ + z->c--; } lab0: z->bra = z->c; /* ], line 52 */ @@ -372,92 +362,85 @@ static int r_Step_1c(struct SN_env * z) { if (ret < 0) return 0; z->c -= ret; } - { int ret = slice_from_s(z, 1, s_7); /* <-, line 54 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 54 */ if (ret < 0) return ret; } return 1; } -static int r_Step_2(struct SN_env * z) { +static int r_Step_2(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 58 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_3, 20); /* substring, line 58 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((815616 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 58 */ + among_var = find_among_b(z, a_3, 20); if (!(among_var)) return 0; z->bra = z->c; /* ], line 58 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 58 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 58 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 58 */ case 1: - { int ret = slice_from_s(z, 4, s_8); /* <-, line 59 */ + { int ret = slice_from_s(z, 4, s_6); /* <-, line 59 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_9); /* <-, line 60 */ + { int ret = slice_from_s(z, 4, s_7); /* <-, line 60 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 4, s_10); /* <-, line 61 */ + { int ret = slice_from_s(z, 4, s_8); /* <-, line 61 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 4, s_11); /* <-, line 62 */ + { int ret = slice_from_s(z, 4, s_9); /* <-, line 62 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 3, s_12); /* <-, line 63 */ + { int ret = slice_from_s(z, 3, s_10); /* <-, line 63 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 1, s_13); /* <-, line 64 */ + { int ret = slice_from_s(z, 1, s_11); /* <-, line 64 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 3, s_14); /* <-, line 66 */ + { int ret = slice_from_s(z, 3, s_12); /* <-, line 66 */ if (ret < 0) return ret; } break; case 8: - { int ret = slice_from_s(z, 3, s_15); /* <-, line 68 */ + { int ret = slice_from_s(z, 3, s_13); /* <-, line 68 */ if (ret < 0) return ret; } break; case 9: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 69 */ + { int ret = slice_from_s(z, 2, s_14); /* <-, line 69 */ if (ret < 0) return ret; } break; case 10: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 71 */ + { int ret = slice_from_s(z, 3, s_15); /* <-, line 72 */ if (ret < 0) return ret; } break; case 11: - { int ret = slice_from_s(z, 3, s_18); /* <-, line 72 */ + { int ret = slice_from_s(z, 3, s_16); /* <-, line 74 */ if (ret < 0) return ret; } break; case 12: - { int ret = slice_from_s(z, 3, s_19); /* <-, line 74 */ + { int ret = slice_from_s(z, 3, s_17); /* <-, line 76 */ if (ret < 0) return ret; } break; case 13: - { int ret = slice_from_s(z, 3, s_20); /* <-, line 76 */ - if (ret < 0) return ret; - } - break; - case 14: - { int ret = slice_from_s(z, 3, s_21); /* <-, line 77 */ + { int ret = slice_from_s(z, 3, s_18); /* <-, line 77 */ if (ret < 0) return ret; } break; @@ -465,26 +448,24 @@ static int r_Step_2(struct SN_env * z) { return 1; } -static int r_Step_3(struct SN_env * z) { +static int r_Step_3(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 82 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_4, 7); /* substring, line 82 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((528928 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 82 */ + among_var = find_among_b(z, a_4, 7); if (!(among_var)) return 0; z->bra = z->c; /* ], line 82 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 82 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 82 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 82 */ case 1: - { int ret = slice_from_s(z, 2, s_22); /* <-, line 83 */ + { int ret = slice_from_s(z, 2, s_19); /* <-, line 83 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_23); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_20); /* <-, line 85 */ if (ret < 0) return ret; } break; @@ -497,19 +478,17 @@ static int r_Step_3(struct SN_env * z) { return 1; } -static int r_Step_4(struct SN_env * z) { +static int r_Step_4(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 92 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 19); /* substring, line 92 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((3961384 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 92 */ + among_var = find_among_b(z, a_5, 19); if (!(among_var)) return 0; z->bra = z->c; /* ], line 92 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 92 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 92 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 92 */ case 1: { int ret = slice_del(z); /* delete, line 95 */ if (ret < 0) return ret; @@ -517,11 +496,13 @@ static int r_Step_4(struct SN_env * z) { break; case 2: { int m1 = z->l - z->c; (void)m1; /* or, line 96 */ - if (!(eq_s_b(z, 1, s_24))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 96 */ + z->c--; goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_25))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 't') return 0; /* literal, line 96 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 96 */ @@ -532,25 +513,25 @@ static int r_Step_4(struct SN_env * z) { return 1; } -static int r_Step_5a(struct SN_env * z) { +static int r_Step_5a(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 101 */ - if (!(eq_s_b(z, 1, s_26))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 101 */ + z->c--; z->bra = z->c; /* ], line 101 */ { int m1 = z->l - z->c; (void)m1; /* or, line 102 */ - { int ret = r_R2(z); - if (ret == 0) goto lab1; /* call R2, line 102 */ + { int ret = r_R2(z); /* call R2, line 102 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } goto lab0; lab1: z->c = z->l - m1; - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 102 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 102 */ + if (ret <= 0) return ret; } { int m2 = z->l - z->c; (void)m2; /* not, line 102 */ - { int ret = r_shortv(z); - if (ret == 0) goto lab2; /* call shortv, line 102 */ + { int ret = r_shortv(z); /* call shortv, line 102 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } return 0; @@ -565,28 +546,30 @@ static int r_Step_5a(struct SN_env * z) { return 1; } -static int r_Step_5b(struct SN_env * z) { +static int r_Step_5b(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 107 */ - if (!(eq_s_b(z, 1, s_27))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 107 */ + z->c--; z->bra = z->c; /* ], line 107 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 108 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 108 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_28))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'l') return 0; /* literal, line 108 */ + z->c--; { int ret = slice_del(z); /* delete, line 109 */ if (ret < 0) return ret; } return 1; } -extern int porter_UTF_8_stem(struct SN_env * z) { +extern int porter_UTF_8_stem(struct SN_env * z) { /* forwardmode */ z->B[0] = 0; /* unset Y_found, line 115 */ { int c1 = z->c; /* do, line 116 */ z->bra = z->c; /* [, line 116 */ - if (!(eq_s(z, 1, s_29))) goto lab0; + if (z->c == z->l || z->p[z->c] != 'y') goto lab0; /* literal, line 116 */ + z->c++; z->ket = z->c; /* ], line 116 */ - { int ret = slice_from_s(z, 1, s_30); /* <-, line 116 */ + { int ret = slice_from_s(z, 1, s_21); /* <-, line 116 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 116 */ @@ -598,9 +581,10 @@ extern int porter_UTF_8_stem(struct SN_env * z) { int c3 = z->c; while(1) { /* goto, line 117 */ int c4 = z->c; - if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab3; + if (in_grouping_U(z, g_v, 97, 121, 0)) goto lab3; /* grouping v, line 117 */ z->bra = z->c; /* [, line 117 */ - if (!(eq_s(z, 1, s_31))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'y') goto lab3; /* literal, line 117 */ + z->c++; z->ket = z->c; /* ], line 117 */ z->c = c4; break; @@ -611,7 +595,7 @@ extern int porter_UTF_8_stem(struct SN_env * z) { z->c = ret; /* goto, line 117 */ } } - { int ret = slice_from_s(z, 1, s_32); /* <-, line 117 */ + { int ret = slice_from_s(z, 1, s_22); /* <-, line 117 */ if (ret < 0) return ret; } z->B[0] = 1; /* set Y_found, line 117 */ @@ -622,8 +606,8 @@ extern int porter_UTF_8_stem(struct SN_env * z) { } z->c = c2; } - z->I[0] = z->l; - z->I[1] = z->l; + z->I[0] = z->l; /* $p1 = , line 119 */ + z->I[1] = z->l; /* $p2 = , line 120 */ { int c5 = z->c; /* do, line 121 */ { /* gopast */ /* grouping v, line 122 */ int ret = out_grouping_U(z, g_v, 97, 121, 1); @@ -653,64 +637,64 @@ extern int porter_UTF_8_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 126 */ { int m6 = z->l - z->c; (void)m6; /* do, line 127 */ - { int ret = r_Step_1a(z); - if (ret == 0) goto lab5; /* call Step_1a, line 127 */ + { int ret = r_Step_1a(z); /* call Step_1a, line 127 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } lab5: z->c = z->l - m6; } { int m7 = z->l - z->c; (void)m7; /* do, line 128 */ - { int ret = r_Step_1b(z); - if (ret == 0) goto lab6; /* call Step_1b, line 128 */ + { int ret = r_Step_1b(z); /* call Step_1b, line 128 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: z->c = z->l - m7; } { int m8 = z->l - z->c; (void)m8; /* do, line 129 */ - { int ret = r_Step_1c(z); - if (ret == 0) goto lab7; /* call Step_1c, line 129 */ + { int ret = r_Step_1c(z); /* call Step_1c, line 129 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: z->c = z->l - m8; } { int m9 = z->l - z->c; (void)m9; /* do, line 130 */ - { int ret = r_Step_2(z); - if (ret == 0) goto lab8; /* call Step_2, line 130 */ + { int ret = r_Step_2(z); /* call Step_2, line 130 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: z->c = z->l - m9; } { int m10 = z->l - z->c; (void)m10; /* do, line 131 */ - { int ret = r_Step_3(z); - if (ret == 0) goto lab9; /* call Step_3, line 131 */ + { int ret = r_Step_3(z); /* call Step_3, line 131 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: z->c = z->l - m10; } { int m11 = z->l - z->c; (void)m11; /* do, line 132 */ - { int ret = r_Step_4(z); - if (ret == 0) goto lab10; /* call Step_4, line 132 */ + { int ret = r_Step_4(z); /* call Step_4, line 132 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } lab10: z->c = z->l - m11; } { int m12 = z->l - z->c; (void)m12; /* do, line 133 */ - { int ret = r_Step_5a(z); - if (ret == 0) goto lab11; /* call Step_5a, line 133 */ + { int ret = r_Step_5a(z); /* call Step_5a, line 133 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } lab11: z->c = z->l - m12; } { int m13 = z->l - z->c; (void)m13; /* do, line 134 */ - { int ret = r_Step_5b(z); - if (ret == 0) goto lab12; /* call Step_5b, line 134 */ + { int ret = r_Step_5b(z); /* call Step_5b, line 134 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } lab12: @@ -724,7 +708,8 @@ extern int porter_UTF_8_stem(struct SN_env * z) { while(1) { /* goto, line 137 */ int c16 = z->c; z->bra = z->c; /* [, line 137 */ - if (!(eq_s(z, 1, s_33))) goto lab15; + if (z->c == z->l || z->p[z->c] != 'Y') goto lab15; /* literal, line 137 */ + z->c++; z->ket = z->c; /* ], line 137 */ z->c = c16; break; @@ -735,7 +720,7 @@ extern int porter_UTF_8_stem(struct SN_env * z) { z->c = ret; /* goto, line 137 */ } } - { int ret = slice_from_s(z, 1, s_34); /* <-, line 137 */ + { int ret = slice_from_s(z, 1, s_23); /* <-, line 137 */ if (ret < 0) return ret; } continue; diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c index 8939cfe016a..f5f2e0fe0cf 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_portuguese.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -90,42 +90,42 @@ static const struct among a_4[3] = static const symbol s_5_0[3] = { 'i', 'c', 'a' }; static const symbol s_5_1[6] = { 0xC3, 0xA2, 'n', 'c', 'i', 'a' }; static const symbol s_5_2[6] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a' }; -static const symbol s_5_3[3] = { 'i', 'r', 'a' }; -static const symbol s_5_4[5] = { 'a', 'd', 'o', 'r', 'a' }; -static const symbol s_5_5[3] = { 'o', 's', 'a' }; -static const symbol s_5_6[4] = { 'i', 's', 't', 'a' }; -static const symbol s_5_7[3] = { 'i', 'v', 'a' }; -static const symbol s_5_8[3] = { 'e', 'z', 'a' }; -static const symbol s_5_9[6] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a' }; +static const symbol s_5_3[5] = { 'l', 'o', 'g', 'i', 'a' }; +static const symbol s_5_4[3] = { 'i', 'r', 'a' }; +static const symbol s_5_5[5] = { 'a', 'd', 'o', 'r', 'a' }; +static const symbol s_5_6[3] = { 'o', 's', 'a' }; +static const symbol s_5_7[4] = { 'i', 's', 't', 'a' }; +static const symbol s_5_8[3] = { 'i', 'v', 'a' }; +static const symbol s_5_9[3] = { 'e', 'z', 'a' }; static const symbol s_5_10[5] = { 'i', 'd', 'a', 'd', 'e' }; static const symbol s_5_11[4] = { 'a', 'n', 't', 'e' }; static const symbol s_5_12[5] = { 'm', 'e', 'n', 't', 'e' }; static const symbol s_5_13[6] = { 'a', 'm', 'e', 'n', 't', 'e' }; static const symbol s_5_14[5] = { 0xC3, 0xA1, 'v', 'e', 'l' }; static const symbol s_5_15[5] = { 0xC3, 0xAD, 'v', 'e', 'l' }; -static const symbol s_5_16[6] = { 'u', 'c', 'i', 0xC3, 0xB3, 'n' }; -static const symbol s_5_17[3] = { 'i', 'c', 'o' }; -static const symbol s_5_18[4] = { 'i', 's', 'm', 'o' }; -static const symbol s_5_19[3] = { 'o', 's', 'o' }; -static const symbol s_5_20[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; -static const symbol s_5_21[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; -static const symbol s_5_22[3] = { 'i', 'v', 'o' }; -static const symbol s_5_23[6] = { 'a', 0xC3, 0xA7, 'a', '~', 'o' }; +static const symbol s_5_16[3] = { 'i', 'c', 'o' }; +static const symbol s_5_17[4] = { 'i', 's', 'm', 'o' }; +static const symbol s_5_18[3] = { 'o', 's', 'o' }; +static const symbol s_5_19[6] = { 'a', 'm', 'e', 'n', 't', 'o' }; +static const symbol s_5_20[6] = { 'i', 'm', 'e', 'n', 't', 'o' }; +static const symbol s_5_21[3] = { 'i', 'v', 'o' }; +static const symbol s_5_22[6] = { 'a', 0xC3, 0xA7, 'a', '~', 'o' }; +static const symbol s_5_23[6] = { 'u', 0xC3, 0xA7, 'a', '~', 'o' }; static const symbol s_5_24[4] = { 'a', 'd', 'o', 'r' }; static const symbol s_5_25[4] = { 'i', 'c', 'a', 's' }; static const symbol s_5_26[7] = { 0xC3, 0xAA, 'n', 'c', 'i', 'a', 's' }; -static const symbol s_5_27[4] = { 'i', 'r', 'a', 's' }; -static const symbol s_5_28[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; -static const symbol s_5_29[4] = { 'o', 's', 'a', 's' }; -static const symbol s_5_30[5] = { 'i', 's', 't', 'a', 's' }; -static const symbol s_5_31[4] = { 'i', 'v', 'a', 's' }; -static const symbol s_5_32[4] = { 'e', 'z', 'a', 's' }; -static const symbol s_5_33[7] = { 'l', 'o', 'g', 0xC3, 0xAD, 'a', 's' }; +static const symbol s_5_27[6] = { 'l', 'o', 'g', 'i', 'a', 's' }; +static const symbol s_5_28[4] = { 'i', 'r', 'a', 's' }; +static const symbol s_5_29[6] = { 'a', 'd', 'o', 'r', 'a', 's' }; +static const symbol s_5_30[4] = { 'o', 's', 'a', 's' }; +static const symbol s_5_31[5] = { 'i', 's', 't', 'a', 's' }; +static const symbol s_5_32[4] = { 'i', 'v', 'a', 's' }; +static const symbol s_5_33[4] = { 'e', 'z', 'a', 's' }; static const symbol s_5_34[6] = { 'i', 'd', 'a', 'd', 'e', 's' }; -static const symbol s_5_35[7] = { 'u', 'c', 'i', 'o', 'n', 'e', 's' }; -static const symbol s_5_36[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; -static const symbol s_5_37[5] = { 'a', 'n', 't', 'e', 's' }; -static const symbol s_5_38[7] = { 'a', 0xC3, 0xA7, 'o', '~', 'e', 's' }; +static const symbol s_5_35[6] = { 'a', 'd', 'o', 'r', 'e', 's' }; +static const symbol s_5_36[5] = { 'a', 'n', 't', 'e', 's' }; +static const symbol s_5_37[7] = { 'a', 0xC3, 0xA7, 'o', '~', 'e', 's' }; +static const symbol s_5_38[7] = { 'u', 0xC3, 0xA7, 'o', '~', 'e', 's' }; static const symbol s_5_39[4] = { 'i', 'c', 'o', 's' }; static const symbol s_5_40[5] = { 'i', 's', 'm', 'o', 's' }; static const symbol s_5_41[4] = { 'o', 's', 'o', 's' }; @@ -138,42 +138,42 @@ static const struct among a_5[45] = /* 0 */ { 3, s_5_0, -1, 1, 0}, /* 1 */ { 6, s_5_1, -1, 1, 0}, /* 2 */ { 6, s_5_2, -1, 4, 0}, -/* 3 */ { 3, s_5_3, -1, 9, 0}, -/* 4 */ { 5, s_5_4, -1, 1, 0}, -/* 5 */ { 3, s_5_5, -1, 1, 0}, -/* 6 */ { 4, s_5_6, -1, 1, 0}, -/* 7 */ { 3, s_5_7, -1, 8, 0}, -/* 8 */ { 3, s_5_8, -1, 1, 0}, -/* 9 */ { 6, s_5_9, -1, 2, 0}, +/* 3 */ { 5, s_5_3, -1, 2, 0}, +/* 4 */ { 3, s_5_4, -1, 9, 0}, +/* 5 */ { 5, s_5_5, -1, 1, 0}, +/* 6 */ { 3, s_5_6, -1, 1, 0}, +/* 7 */ { 4, s_5_7, -1, 1, 0}, +/* 8 */ { 3, s_5_8, -1, 8, 0}, +/* 9 */ { 3, s_5_9, -1, 1, 0}, /* 10 */ { 5, s_5_10, -1, 7, 0}, /* 11 */ { 4, s_5_11, -1, 1, 0}, /* 12 */ { 5, s_5_12, -1, 6, 0}, /* 13 */ { 6, s_5_13, 12, 5, 0}, /* 14 */ { 5, s_5_14, -1, 1, 0}, /* 15 */ { 5, s_5_15, -1, 1, 0}, -/* 16 */ { 6, s_5_16, -1, 3, 0}, -/* 17 */ { 3, s_5_17, -1, 1, 0}, -/* 18 */ { 4, s_5_18, -1, 1, 0}, -/* 19 */ { 3, s_5_19, -1, 1, 0}, +/* 16 */ { 3, s_5_16, -1, 1, 0}, +/* 17 */ { 4, s_5_17, -1, 1, 0}, +/* 18 */ { 3, s_5_18, -1, 1, 0}, +/* 19 */ { 6, s_5_19, -1, 1, 0}, /* 20 */ { 6, s_5_20, -1, 1, 0}, -/* 21 */ { 6, s_5_21, -1, 1, 0}, -/* 22 */ { 3, s_5_22, -1, 8, 0}, -/* 23 */ { 6, s_5_23, -1, 1, 0}, +/* 21 */ { 3, s_5_21, -1, 8, 0}, +/* 22 */ { 6, s_5_22, -1, 1, 0}, +/* 23 */ { 6, s_5_23, -1, 3, 0}, /* 24 */ { 4, s_5_24, -1, 1, 0}, /* 25 */ { 4, s_5_25, -1, 1, 0}, /* 26 */ { 7, s_5_26, -1, 4, 0}, -/* 27 */ { 4, s_5_27, -1, 9, 0}, -/* 28 */ { 6, s_5_28, -1, 1, 0}, -/* 29 */ { 4, s_5_29, -1, 1, 0}, -/* 30 */ { 5, s_5_30, -1, 1, 0}, -/* 31 */ { 4, s_5_31, -1, 8, 0}, -/* 32 */ { 4, s_5_32, -1, 1, 0}, -/* 33 */ { 7, s_5_33, -1, 2, 0}, +/* 27 */ { 6, s_5_27, -1, 2, 0}, +/* 28 */ { 4, s_5_28, -1, 9, 0}, +/* 29 */ { 6, s_5_29, -1, 1, 0}, +/* 30 */ { 4, s_5_30, -1, 1, 0}, +/* 31 */ { 5, s_5_31, -1, 1, 0}, +/* 32 */ { 4, s_5_32, -1, 8, 0}, +/* 33 */ { 4, s_5_33, -1, 1, 0}, /* 34 */ { 6, s_5_34, -1, 7, 0}, -/* 35 */ { 7, s_5_35, -1, 3, 0}, -/* 36 */ { 6, s_5_36, -1, 1, 0}, -/* 37 */ { 5, s_5_37, -1, 1, 0}, -/* 38 */ { 7, s_5_38, -1, 1, 0}, +/* 35 */ { 6, s_5_35, -1, 1, 0}, +/* 36 */ { 5, s_5_36, -1, 1, 0}, +/* 37 */ { 7, s_5_37, -1, 1, 0}, +/* 38 */ { 7, s_5_38, -1, 3, 0}, /* 39 */ { 4, s_5_39, -1, 1, 0}, /* 40 */ { 5, s_5_40, -1, 1, 0}, /* 41 */ { 4, s_5_41, -1, 1, 0}, @@ -470,27 +470,19 @@ static const symbol s_5[] = { 'u' }; static const symbol s_6[] = { 'e', 'n', 't', 'e' }; static const symbol s_7[] = { 'a', 't' }; static const symbol s_8[] = { 'a', 't' }; -static const symbol s_9[] = { 'e' }; -static const symbol s_10[] = { 'i', 'r' }; -static const symbol s_11[] = { 'u' }; -static const symbol s_12[] = { 'g' }; -static const symbol s_13[] = { 'i' }; -static const symbol s_14[] = { 'c' }; -static const symbol s_15[] = { 'c' }; -static const symbol s_16[] = { 'i' }; -static const symbol s_17[] = { 'c' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_9[] = { 'i', 'r' }; +static const symbol s_10[] = { 'c' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 36 */ int c1 = z->c; z->bra = z->c; /* [, line 37 */ - if (z->c + 1 >= z->l || (z->p[z->c + 1] != 163 && z->p[z->c + 1] != 181)) among_var = 3; else - among_var = find_among(z, a_0, 3); /* substring, line 37 */ + if (z->c + 1 >= z->l || (z->p[z->c + 1] != 163 && z->p[z->c + 1] != 181)) among_var = 3; else /* substring, line 37 */ + among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 37 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 37 */ case 1: { int ret = slice_from_s(z, 2, s_0); /* <-, line 38 */ if (ret < 0) return ret; @@ -516,15 +508,15 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 46 */ + z->I[1] = z->l; /* $p1 = , line 47 */ + z->I[2] = z->l; /* $p2 = , line 48 */ { int c1 = z->c; /* do, line 50 */ { int c2 = z->c; /* or, line 52 */ - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ { int c3 = z->c; /* or, line 51 */ - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab4; + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab4; /* non v, line 51 */ { /* gopast */ /* grouping v, line 51 */ int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab4; @@ -533,7 +525,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab2; /* grouping v, line 51 */ { /* gopast */ /* non v, line 51 */ int ret = in_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab2; @@ -544,9 +536,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab0; + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab0; /* non v, line 53 */ { int c4 = z->c; /* or, line 53 */ - if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab6; + if (out_grouping_U(z, g_v, 97, 250, 0)) goto lab6; /* non v, line 53 */ { /* gopast */ /* grouping v, line 53 */ int ret = out_grouping_U(z, g_v, 97, 250, 1); if (ret < 0) goto lab6; @@ -555,7 +547,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab0; + if (in_grouping_U(z, g_v, 97, 250, 0)) goto lab0; /* grouping v, line 53 */ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; z->c = ret; /* next, line 53 */ @@ -598,17 +590,16 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 62 */ int c1 = z->c; z->bra = z->c; /* [, line 63 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else - among_var = find_among(z, a_1, 3); /* substring, line 63 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] != 126) among_var = 3; else /* substring, line 63 */ + among_var = find_among(z, a_1, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 63 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 63 */ case 1: { int ret = slice_from_s(z, 2, s_2); /* <-, line 64 */ if (ret < 0) return ret; @@ -634,95 +625,88 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 72 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 73 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 74 */ return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 77 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((839714 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_5, 45); /* substring, line 77 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((823330 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 77 */ + among_var = find_among_b(z, a_5, 45); if (!(among_var)) return 0; z->bra = z->c; /* ], line 77 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 77 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 93 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 93 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 93 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 98 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 98 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 3, s_4); /* <-, line 98 */ if (ret < 0) return ret; } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 102 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 102 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 1, s_5); /* <-, line 102 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 106 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret <= 0) return ret; } { int ret = slice_from_s(z, 4, s_6); /* <-, line 106 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 110 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 110 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 110 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 111 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ z->ket = z->c; /* [, line 112 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab0; } - among_var = find_among_b(z, a_2, 4); /* substring, line 112 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m1; goto lab0; } /* substring, line 112 */ + among_var = find_among_b(z, a_2, 4); + if (!(among_var)) { z->c = z->l - m1; goto lab0; } z->bra = z->c; /* ], line 112 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 112 */ + { int ret = r_R2(z); /* call R2, line 112 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 112 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } + switch (among_var) { /* among, line 112 */ case 1: z->ket = z->c; /* [, line 113 */ - if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_7))) { z->c = z->l - m1; goto lab0; } /* literal, line 113 */ z->bra = z->c; /* ], line 113 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 113 */ + { int ret = r_R2(z); /* call R2, line 113 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 113 */ @@ -735,79 +719,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 6: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 122 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 122 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 122 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 123 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 123 */ z->ket = z->c; /* [, line 124 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_3, 3); /* substring, line 124 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 101 && z->p[z->c - 1] != 108)) { z->c = z->l - m2; goto lab1; } /* substring, line 124 */ + if (!(find_among_b(z, a_3, 3))) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 124 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 127 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 127 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 127 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 127 */ + if (ret < 0) return ret; } lab1: ; } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 134 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 134 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 134 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 135 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 135 */ z->ket = z->c; /* [, line 136 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_4, 3); /* substring, line 136 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m3; goto lab2; } /* substring, line 136 */ + if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 136 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 139 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 139 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 139 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 139 */ + if (ret < 0) return ret; } lab2: ; } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 146 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 146 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 146 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 147 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 147 */ z->ket = z->c; /* [, line 148 */ - if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m_keep; goto lab3; } + if (!(eq_s_b(z, 2, s_8))) { z->c = z->l - m4; goto lab3; } /* literal, line 148 */ z->bra = z->c; /* ], line 148 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 148 */ + { int ret = r_R2(z); /* call R2, line 148 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 148 */ @@ -818,12 +787,12 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 9: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 153 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 153 */ + if (ret <= 0) return ret; } - if (!(eq_s_b(z, 1, s_9))) return 0; - { int ret = slice_from_s(z, 2, s_10); /* <-, line 154 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') return 0; /* literal, line 153 */ + z->c--; + { int ret = slice_from_s(z, 2, s_9); /* <-, line 154 */ if (ret < 0) return ret; } break; @@ -831,97 +800,81 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 159 */ - int m1 = z->l - z->c; (void)m1; +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 159 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 159 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 160 */ - among_var = find_among_b(z, a_6, 120); /* substring, line 160 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_6, 120))) { z->lb = mlimit1; return 0; } /* substring, line 160 */ z->bra = z->c; /* ], line 160 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } - case 1: - { int ret = slice_del(z); /* delete, line 179 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 179 */ + if (ret < 0) return ret; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_residual_suffix(struct SN_env * z) { - int among_var; +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 184 */ - among_var = find_among_b(z, a_7, 7); /* substring, line 184 */ - if (!(among_var)) return 0; + if (!(find_among_b(z, a_7, 7))) return 0; /* substring, line 184 */ z->bra = z->c; /* ], line 184 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 187 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 187 */ - if (ret < 0) return ret; - } - break; + { int ret = r_RV(z); /* call RV, line 187 */ + if (ret <= 0) return ret; + } + { int ret = slice_del(z); /* delete, line 187 */ + if (ret < 0) return ret; } return 1; } -static int r_residual_form(struct SN_env * z) { +static int r_residual_form(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 192 */ among_var = find_among_b(z, a_8, 4); /* substring, line 192 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 192 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 192 */ case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 194 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 194 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } z->ket = z->c; /* [, line 194 */ { int m1 = z->l - z->c; (void)m1; /* or, line 194 */ - if (!(eq_s_b(z, 1, s_11))) goto lab1; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab1; /* literal, line 194 */ + z->c--; z->bra = z->c; /* ], line 194 */ - { int m_test = z->l - z->c; /* test, line 194 */ - if (!(eq_s_b(z, 1, s_12))) goto lab1; - z->c = z->l - m_test; + { int m_test2 = z->l - z->c; /* test, line 194 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') goto lab1; /* literal, line 194 */ + z->c--; + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_13))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') return 0; /* literal, line 195 */ + z->c--; z->bra = z->c; /* ], line 195 */ - { int m_test = z->l - z->c; /* test, line 195 */ - if (!(eq_s_b(z, 1, s_14))) return 0; - z->c = z->l - m_test; + { int m_test3 = z->l - z->c; /* test, line 195 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'c') return 0; /* literal, line 195 */ + z->c--; + z->c = z->l - m_test3; } } lab0: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 195 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 195 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 195 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_15); /* <-, line 196 */ + { int ret = slice_from_s(z, 1, s_10); /* <-, line 196 */ if (ret < 0) return ret; } break; @@ -929,77 +882,77 @@ static int r_residual_form(struct SN_env * z) { return 1; } -extern int portuguese_UTF_8_stem(struct SN_env * z) { +extern int portuguese_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 202 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 202 */ + { int ret = r_prelude(z); /* call prelude, line 202 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 203 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 203 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 203 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 203 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 204 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 205 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 209 */ - { int m5 = z->l - z->c; (void)m5; /* and, line 207 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 206 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab6; /* call standard_suffix, line 206 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 205 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 209 */ + { int m4 = z->l - z->c; (void)m4; /* and, line 207 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 206 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 206 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 206 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 206 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: - z->c = z->l - m5; - { int m7 = z->l - z->c; (void)m7; /* do, line 207 */ + z->c = z->l - m4; + { int m6 = z->l - z->c; (void)m6; /* do, line 207 */ z->ket = z->c; /* [, line 207 */ - if (!(eq_s_b(z, 1, s_16))) goto lab7; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab7; /* literal, line 207 */ + z->c--; z->bra = z->c; /* ], line 207 */ - { int m_test = z->l - z->c; /* test, line 207 */ - if (!(eq_s_b(z, 1, s_17))) goto lab7; - z->c = z->l - m_test; + { int m_test7 = z->l - z->c; /* test, line 207 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'c') goto lab7; /* literal, line 207 */ + z->c--; + z->c = z->l - m_test7; } - { int ret = r_RV(z); - if (ret == 0) goto lab7; /* call RV, line 207 */ + { int ret = r_RV(z); /* call RV, line 207 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 207 */ if (ret < 0) return ret; } lab7: - z->c = z->l - m7; + z->c = z->l - m6; } } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab2; /* call residual_suffix, line 209 */ + z->c = z->l - m3; + { int ret = r_residual_suffix(z); /* call residual_suffix, line 209 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } { int m8 = z->l - z->c; (void)m8; /* do, line 211 */ - { int ret = r_residual_form(z); - if (ret == 0) goto lab8; /* call residual_form, line 211 */ + { int ret = r_residual_form(z); /* call residual_form, line 211 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: @@ -1007,8 +960,8 @@ extern int portuguese_UTF_8_stem(struct SN_env * z) { } z->c = z->lb; { int c9 = z->c; /* do, line 213 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab9; /* call postlude, line 213 */ + { int ret = r_postlude(z); /* call postlude, line 213 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } lab9: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c index e82ebfe95f8..0e1e5fcd087 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_romanian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -516,51 +516,50 @@ static const struct among a_5[5] = static const unsigned char g_v[] = { 17, 65, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 0, 0, 4 }; -static const symbol s_0[] = { 'u' }; -static const symbol s_1[] = { 'U' }; +static const symbol s_0[] = { 'U' }; +static const symbol s_1[] = { 'I' }; static const symbol s_2[] = { 'i' }; -static const symbol s_3[] = { 'I' }; -static const symbol s_4[] = { 'i' }; -static const symbol s_5[] = { 'u' }; -static const symbol s_6[] = { 'a' }; -static const symbol s_7[] = { 'e' }; +static const symbol s_3[] = { 'u' }; +static const symbol s_4[] = { 'a' }; +static const symbol s_5[] = { 'e' }; +static const symbol s_6[] = { 'i' }; +static const symbol s_7[] = { 'a', 'b' }; static const symbol s_8[] = { 'i' }; -static const symbol s_9[] = { 'a', 'b' }; -static const symbol s_10[] = { 'i' }; -static const symbol s_11[] = { 'a', 't' }; -static const symbol s_12[] = { 'a', 0xC5, 0xA3, 'i' }; -static const symbol s_13[] = { 'a', 'b', 'i', 'l' }; -static const symbol s_14[] = { 'i', 'b', 'i', 'l' }; -static const symbol s_15[] = { 'i', 'v' }; -static const symbol s_16[] = { 'i', 'c' }; -static const symbol s_17[] = { 'a', 't' }; -static const symbol s_18[] = { 'i', 't' }; -static const symbol s_19[] = { 0xC5, 0xA3 }; -static const symbol s_20[] = { 't' }; -static const symbol s_21[] = { 'i', 's', 't' }; -static const symbol s_22[] = { 'u' }; - -static int r_prelude(struct SN_env * z) { +static const symbol s_9[] = { 'a', 't' }; +static const symbol s_10[] = { 'a', 0xC5, 0xA3, 'i' }; +static const symbol s_11[] = { 'a', 'b', 'i', 'l' }; +static const symbol s_12[] = { 'i', 'b', 'i', 'l' }; +static const symbol s_13[] = { 'i', 'v' }; +static const symbol s_14[] = { 'i', 'c' }; +static const symbol s_15[] = { 'a', 't' }; +static const symbol s_16[] = { 'i', 't' }; +static const symbol s_17[] = { 0xC5, 0xA3 }; +static const symbol s_18[] = { 't' }; +static const symbol s_19[] = { 'i', 's', 't' }; + +static int r_prelude(struct SN_env * z) { /* forwardmode */ while(1) { /* repeat, line 32 */ int c1 = z->c; while(1) { /* goto, line 32 */ int c2 = z->c; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; /* grouping v, line 33 */ z->bra = z->c; /* [, line 33 */ { int c3 = z->c; /* or, line 33 */ - if (!(eq_s(z, 1, s_0))) goto lab3; + if (z->c == z->l || z->p[z->c] != 'u') goto lab3; /* literal, line 33 */ + z->c++; z->ket = z->c; /* ], line 33 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab3; - { int ret = slice_from_s(z, 1, s_1); /* <-, line 33 */ + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab3; /* grouping v, line 33 */ + { int ret = slice_from_s(z, 1, s_0); /* <-, line 33 */ if (ret < 0) return ret; } goto lab2; lab3: z->c = c3; - if (!(eq_s(z, 1, s_2))) goto lab1; + if (z->c == z->l || z->p[z->c] != 'i') goto lab1; /* literal, line 34 */ + z->c++; z->ket = z->c; /* ], line 34 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; - { int ret = slice_from_s(z, 1, s_3); /* <-, line 34 */ + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab1; /* grouping v, line 34 */ + { int ret = slice_from_s(z, 1, s_1); /* <-, line 34 */ if (ret < 0) return ret; } } @@ -582,15 +581,15 @@ static int r_prelude(struct SN_env * z) { return 1; } -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 40 */ + z->I[1] = z->l; /* $p1 = , line 41 */ + z->I[2] = z->l; /* $p2 = , line 42 */ { int c1 = z->c; /* do, line 44 */ { int c2 = z->c; /* or, line 46 */ - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; /* grouping v, line 45 */ { int c3 = z->c; /* or, line 45 */ - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab4; + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab4; /* non v, line 45 */ { /* gopast */ /* grouping v, line 45 */ int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab4; @@ -599,7 +598,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab2; /* grouping v, line 45 */ { /* gopast */ /* non v, line 45 */ int ret = in_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab2; @@ -610,9 +609,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab0; + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab0; /* non v, line 47 */ { int c4 = z->c; /* or, line 47 */ - if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab6; + if (out_grouping_U(z, g_v, 97, 259, 0)) goto lab6; /* non v, line 47 */ { /* gopast */ /* grouping v, line 47 */ int ret = out_grouping_U(z, g_v, 97, 259, 1); if (ret < 0) goto lab6; @@ -621,7 +620,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab0; + if (in_grouping_U(z, g_v, 97, 259, 0)) goto lab0; /* grouping v, line 47 */ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; z->c = ret; /* next, line 47 */ @@ -664,24 +663,23 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 56 */ int c1 = z->c; z->bra = z->c; /* [, line 58 */ - if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else - among_var = find_among(z, a_0, 3); /* substring, line 58 */ + if (z->c >= z->l || (z->p[z->c + 0] != 73 && z->p[z->c + 0] != 85)) among_var = 3; else /* substring, line 58 */ + among_var = find_among(z, a_0, 3); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 58 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 58 */ case 1: - { int ret = slice_from_s(z, 1, s_4); /* <-, line 59 */ + { int ret = slice_from_s(z, 1, s_2); /* <-, line 59 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_5); /* <-, line 60 */ + { int ret = slice_from_s(z, 1, s_3); /* <-, line 60 */ if (ret < 0) return ret; } break; @@ -700,72 +698,70 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 68 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 69 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 70 */ return 1; } -static int r_step_0(struct SN_env * z) { +static int r_step_0(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 73 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_1, 16); /* substring, line 73 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((266786 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 73 */ + among_var = find_among_b(z, a_1, 16); if (!(among_var)) return 0; z->bra = z->c; /* ], line 73 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 73 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 73 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 73 */ case 1: { int ret = slice_del(z); /* delete, line 75 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 1, s_6); /* <-, line 77 */ + { int ret = slice_from_s(z, 1, s_4); /* <-, line 77 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_7); /* <-, line 79 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 79 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_8); /* <-, line 81 */ + { int ret = slice_from_s(z, 1, s_6); /* <-, line 81 */ if (ret < 0) return ret; } break; case 5: { int m1 = z->l - z->c; (void)m1; /* not, line 83 */ - if (!(eq_s_b(z, 2, s_9))) goto lab0; + if (!(eq_s_b(z, 2, s_7))) goto lab0; /* literal, line 83 */ return 0; lab0: z->c = z->l - m1; } - { int ret = slice_from_s(z, 1, s_10); /* <-, line 83 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 83 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_11); /* <-, line 85 */ + { int ret = slice_from_s(z, 2, s_9); /* <-, line 85 */ if (ret < 0) return ret; } break; case 7: - { int ret = slice_from_s(z, 4, s_12); /* <-, line 87 */ + { int ret = slice_from_s(z, 4, s_10); /* <-, line 87 */ if (ret < 0) return ret; } break; @@ -773,63 +769,61 @@ static int r_step_0(struct SN_env * z) { return 1; } -static int r_combo_suffix(struct SN_env * z) { +static int r_combo_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int m_test = z->l - z->c; /* test, line 91 */ + { int m_test1 = z->l - z->c; /* test, line 91 */ z->ket = z->c; /* [, line 92 */ among_var = find_among_b(z, a_2, 46); /* substring, line 92 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 92 */ - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 92 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 92 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 93 */ case 1: - { int ret = slice_from_s(z, 4, s_13); /* <-, line 101 */ + { int ret = slice_from_s(z, 4, s_11); /* <-, line 101 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 4, s_14); /* <-, line 104 */ + { int ret = slice_from_s(z, 4, s_12); /* <-, line 104 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 2, s_15); /* <-, line 107 */ + { int ret = slice_from_s(z, 2, s_13); /* <-, line 107 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 2, s_16); /* <-, line 113 */ + { int ret = slice_from_s(z, 2, s_14); /* <-, line 113 */ if (ret < 0) return ret; } break; case 5: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 118 */ + { int ret = slice_from_s(z, 2, s_15); /* <-, line 118 */ if (ret < 0) return ret; } break; case 6: - { int ret = slice_from_s(z, 2, s_18); /* <-, line 122 */ + { int ret = slice_from_s(z, 2, s_16); /* <-, line 122 */ if (ret < 0) return ret; } break; } z->B[0] = 1; /* set standard_suffix_removed, line 125 */ - z->c = z->l - m_test; + z->c = z->l - m_test1; } return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->B[0] = 0; /* unset standard_suffix_removed, line 130 */ while(1) { /* repeat, line 131 */ int m1 = z->l - z->c; (void)m1; - { int ret = r_combo_suffix(z); - if (ret == 0) goto lab0; /* call combo_suffix, line 131 */ + { int ret = r_combo_suffix(z); /* call combo_suffix, line 131 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } continue; @@ -841,26 +835,24 @@ static int r_standard_suffix(struct SN_env * z) { among_var = find_among_b(z, a_3, 62); /* substring, line 132 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 132 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 132 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 132 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 133 */ case 1: { int ret = slice_del(z); /* delete, line 149 */ if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 2, s_19))) return 0; + if (!(eq_s_b(z, 2, s_17))) return 0; /* literal, line 152 */ z->bra = z->c; /* ], line 152 */ - { int ret = slice_from_s(z, 1, s_20); /* <-, line 152 */ + { int ret = slice_from_s(z, 1, s_18); /* <-, line 152 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 3, s_21); /* <-, line 156 */ + { int ret = slice_from_s(z, 3, s_19); /* <-, line 156 */ if (ret < 0) return ret; } break; @@ -869,27 +861,25 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 164 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 164 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 164 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 165 */ among_var = find_among_b(z, a_4, 94); /* substring, line 165 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 165 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + switch (among_var) { /* among, line 165 */ case 1: { int m2 = z->l - z->c; (void)m2; /* or, line 200 */ - if (out_grouping_b_U(z, g_v, 97, 259, 0)) goto lab1; + if (out_grouping_b_U(z, g_v, 97, 259, 0)) goto lab1; /* non v, line 200 */ goto lab0; lab1: z->c = z->l - m2; - if (!(eq_s_b(z, 1, s_22))) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->lb = mlimit1; return 0; } /* literal, line 200 */ + z->c--; } lab0: { int ret = slice_del(z); /* delete, line 200 */ @@ -902,98 +892,88 @@ static int r_verb_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_vowel_suffix(struct SN_env * z) { - int among_var; +static int r_vowel_suffix(struct SN_env * z) { /* backwardmode */ z->ket = z->c; /* [, line 219 */ - among_var = find_among_b(z, a_5, 5); /* substring, line 219 */ - if (!(among_var)) return 0; + if (!(find_among_b(z, a_5, 5))) return 0; /* substring, line 219 */ z->bra = z->c; /* ], line 219 */ - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 219 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 219 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 220 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 220 */ + if (ret < 0) return ret; } return 1; } -extern int romanian_UTF_8_stem(struct SN_env * z) { +extern int romanian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 226 */ - { int ret = r_prelude(z); - if (ret == 0) goto lab0; /* call prelude, line 226 */ + { int ret = r_prelude(z); /* call prelude, line 226 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = c1; } - { int c2 = z->c; /* do, line 227 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab1; /* call mark_regions, line 227 */ - if (ret < 0) return ret; - } - lab1: - z->c = c2; + /* do, line 227 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 227 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; } +lab1: z->lb = z->c; z->c = z->l; /* backwards, line 228 */ - { int m3 = z->l - z->c; (void)m3; /* do, line 229 */ - { int ret = r_step_0(z); - if (ret == 0) goto lab2; /* call step_0, line 229 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 229 */ + { int ret = r_step_0(z); /* call step_0, line 229 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m4 = z->l - z->c; (void)m4; /* do, line 230 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab3; /* call standard_suffix, line 230 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 230 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 230 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: - z->c = z->l - m4; + z->c = z->l - m3; } - { int m5 = z->l - z->c; (void)m5; /* do, line 231 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 231 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 231 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 231 */ if (!(z->B[0])) goto lab6; /* Boolean test standard_suffix_removed, line 231 */ goto lab5; lab6: - z->c = z->l - m6; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab4; /* call verb_suffix, line 231 */ + z->c = z->l - m5; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 231 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } lab5: lab4: - z->c = z->l - m5; + z->c = z->l - m4; } - { int m7 = z->l - z->c; (void)m7; /* do, line 232 */ - { int ret = r_vowel_suffix(z); - if (ret == 0) goto lab7; /* call vowel_suffix, line 232 */ + { int m6 = z->l - z->c; (void)m6; /* do, line 232 */ + { int ret = r_vowel_suffix(z); /* call vowel_suffix, line 232 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = z->l - m7; + z->c = z->l - m6; } z->c = z->lb; - { int c8 = z->c; /* do, line 234 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab8; /* call postlude, line 234 */ + { int c7 = z->c; /* do, line 234 */ + { int ret = r_postlude(z); /* call postlude, line 234 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } lab8: - z->c = c8; + z->c = c7; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_russian.c b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c index fcbcc6cf464..5e5fd20fa3f 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_russian.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_russian.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -349,68 +349,69 @@ static const symbol s_5[] = { 0xD1, 0x8F }; static const symbol s_6[] = { 0xD0, 0xBD }; static const symbol s_7[] = { 0xD0, 0xBD }; static const symbol s_8[] = { 0xD0, 0xBD }; -static const symbol s_9[] = { 0xD0, 0xB8 }; - -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - { int c1 = z->c; /* do, line 61 */ - { /* gopast */ /* grouping v, line 62 */ +static const symbol s_9[] = { 0xD1, 0x91 }; +static const symbol s_10[] = { 0xD0, 0xB5 }; +static const symbol s_11[] = { 0xD0, 0xB8 }; + +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 61 */ + z->I[1] = z->l; /* $p2 = , line 62 */ + { int c1 = z->c; /* do, line 63 */ + { /* gopast */ /* grouping v, line 64 */ int ret = out_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[0] = z->c; /* setmark pV, line 62 */ - { /* gopast */ /* non v, line 62 */ + z->I[0] = z->c; /* setmark pV, line 64 */ + { /* gopast */ /* non v, line 64 */ int ret = in_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* grouping v, line 63 */ + { /* gopast */ /* grouping v, line 65 */ int ret = out_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - { /* gopast */ /* non v, line 63 */ + { /* gopast */ /* non v, line 65 */ int ret = in_grouping_U(z, g_v, 1072, 1103, 1); if (ret < 0) goto lab0; z->c += ret; } - z->I[1] = z->c; /* setmark p2, line 63 */ + z->I[1] = z->c; /* setmark p2, line 65 */ lab0: z->c = c1; } return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 71 */ return 1; } -static int r_perfective_gerund(struct SN_env * z) { +static int r_perfective_gerund(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 72 */ - among_var = find_among_b(z, a_0, 9); /* substring, line 72 */ + z->ket = z->c; /* [, line 74 */ + among_var = find_among_b(z, a_0, 9); /* substring, line 74 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 72 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 74 */ + switch (among_var) { /* among, line 74 */ case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 76 */ - if (!(eq_s_b(z, 2, s_0))) goto lab1; + { int m1 = z->l - z->c; (void)m1; /* or, line 78 */ + if (!(eq_s_b(z, 2, s_0))) goto lab1; /* literal, line 78 */ goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_1))) return 0; + if (!(eq_s_b(z, 2, s_1))) return 0; /* literal, line 78 */ } lab0: - { int ret = slice_del(z); /* delete, line 76 */ + { int ret = slice_del(z); /* delete, line 78 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 83 */ + { int ret = slice_del(z); /* delete, line 85 */ if (ret < 0) return ret; } break; @@ -418,51 +419,42 @@ static int r_perfective_gerund(struct SN_env * z) { return 1; } -static int r_adjective(struct SN_env * z) { - int among_var; - z->ket = z->c; /* [, line 88 */ - among_var = find_among_b(z, a_1, 26); /* substring, line 88 */ - if (!(among_var)) return 0; - z->bra = z->c; /* ], line 88 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 97 */ - if (ret < 0) return ret; - } - break; +static int r_adjective(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 90 */ + if (!(find_among_b(z, a_1, 26))) return 0; /* substring, line 90 */ + z->bra = z->c; /* ], line 90 */ + { int ret = slice_del(z); /* delete, line 99 */ + if (ret < 0) return ret; } return 1; } -static int r_adjectival(struct SN_env * z) { +static int r_adjectival(struct SN_env * z) { /* backwardmode */ int among_var; - { int ret = r_adjective(z); - if (ret == 0) return 0; /* call adjective, line 102 */ - if (ret < 0) return ret; + { int ret = r_adjective(z); /* call adjective, line 104 */ + if (ret <= 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 109 */ - z->ket = z->c; /* [, line 110 */ - among_var = find_among_b(z, a_2, 8); /* substring, line 110 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab0; } - z->bra = z->c; /* ], line 110 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab0; } + { int m1 = z->l - z->c; (void)m1; /* try, line 111 */ + z->ket = z->c; /* [, line 112 */ + among_var = find_among_b(z, a_2, 8); /* substring, line 112 */ + if (!(among_var)) { z->c = z->l - m1; goto lab0; } + z->bra = z->c; /* ], line 112 */ + switch (among_var) { /* among, line 112 */ case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 115 */ - if (!(eq_s_b(z, 2, s_2))) goto lab2; + { int m2 = z->l - z->c; (void)m2; /* or, line 117 */ + if (!(eq_s_b(z, 2, s_2))) goto lab2; /* literal, line 117 */ goto lab1; lab2: - z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m_keep; goto lab0; } + z->c = z->l - m2; + if (!(eq_s_b(z, 2, s_3))) { z->c = z->l - m1; goto lab0; } /* literal, line 117 */ } lab1: - { int ret = slice_del(z); /* delete, line 115 */ + { int ret = slice_del(z); /* delete, line 117 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 122 */ + { int ret = slice_del(z); /* delete, line 124 */ if (ret < 0) return ret; } break; @@ -473,47 +465,39 @@ static int r_adjectival(struct SN_env * z) { return 1; } -static int r_reflexive(struct SN_env * z) { - int among_var; - z->ket = z->c; /* [, line 129 */ - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 140 && z->p[z->c - 1] != 143)) return 0; - among_var = find_among_b(z, a_3, 2); /* substring, line 129 */ - if (!(among_var)) return 0; - z->bra = z->c; /* ], line 129 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 132 */ - if (ret < 0) return ret; - } - break; +static int r_reflexive(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 131 */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 140 && z->p[z->c - 1] != 143)) return 0; /* substring, line 131 */ + if (!(find_among_b(z, a_3, 2))) return 0; + z->bra = z->c; /* ], line 131 */ + { int ret = slice_del(z); /* delete, line 134 */ + if (ret < 0) return ret; } return 1; } -static int r_verb(struct SN_env * z) { +static int r_verb(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 137 */ - among_var = find_among_b(z, a_4, 46); /* substring, line 137 */ + z->ket = z->c; /* [, line 139 */ + among_var = find_among_b(z, a_4, 46); /* substring, line 139 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 137 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 139 */ + switch (among_var) { /* among, line 139 */ case 1: - { int m1 = z->l - z->c; (void)m1; /* or, line 143 */ - if (!(eq_s_b(z, 2, s_4))) goto lab1; + { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ + if (!(eq_s_b(z, 2, s_4))) goto lab1; /* literal, line 145 */ goto lab0; lab1: z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_5))) return 0; + if (!(eq_s_b(z, 2, s_5))) return 0; /* literal, line 145 */ } lab0: - { int ret = slice_del(z); /* delete, line 143 */ + { int ret = slice_del(z); /* delete, line 145 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_del(z); /* delete, line 151 */ + { int ret = slice_del(z); /* delete, line 153 */ if (ret < 0) return ret; } break; @@ -521,73 +505,57 @@ static int r_verb(struct SN_env * z) { return 1; } -static int r_noun(struct SN_env * z) { - int among_var; - z->ket = z->c; /* [, line 160 */ - among_var = find_among_b(z, a_5, 36); /* substring, line 160 */ - if (!(among_var)) return 0; - z->bra = z->c; /* ], line 160 */ - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 167 */ - if (ret < 0) return ret; - } - break; +static int r_noun(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 162 */ + if (!(find_among_b(z, a_5, 36))) return 0; /* substring, line 162 */ + z->bra = z->c; /* ], line 162 */ + { int ret = slice_del(z); /* delete, line 169 */ + if (ret < 0) return ret; } return 1; } -static int r_derivational(struct SN_env * z) { - int among_var; - z->ket = z->c; /* [, line 176 */ - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 130 && z->p[z->c - 1] != 140)) return 0; - among_var = find_among_b(z, a_6, 2); /* substring, line 176 */ - if (!(among_var)) return 0; - z->bra = z->c; /* ], line 176 */ - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 176 */ - if (ret < 0) return ret; +static int r_derivational(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 178 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 130 && z->p[z->c - 1] != 140)) return 0; /* substring, line 178 */ + if (!(find_among_b(z, a_6, 2))) return 0; + z->bra = z->c; /* ], line 178 */ + { int ret = r_R2(z); /* call R2, line 178 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; - case 1: - { int ret = slice_del(z); /* delete, line 179 */ - if (ret < 0) return ret; - } - break; + { int ret = slice_del(z); /* delete, line 181 */ + if (ret < 0) return ret; } return 1; } -static int r_tidy_up(struct SN_env * z) { +static int r_tidy_up(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 184 */ - among_var = find_among_b(z, a_7, 4); /* substring, line 184 */ + z->ket = z->c; /* [, line 186 */ + among_var = find_among_b(z, a_7, 4); /* substring, line 186 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 184 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 186 */ + switch (among_var) { /* among, line 186 */ case 1: - { int ret = slice_del(z); /* delete, line 188 */ + { int ret = slice_del(z); /* delete, line 190 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 189 */ - if (!(eq_s_b(z, 2, s_6))) return 0; - z->bra = z->c; /* ], line 189 */ - if (!(eq_s_b(z, 2, s_7))) return 0; - { int ret = slice_del(z); /* delete, line 189 */ + z->ket = z->c; /* [, line 191 */ + if (!(eq_s_b(z, 2, s_6))) return 0; /* literal, line 191 */ + z->bra = z->c; /* ], line 191 */ + if (!(eq_s_b(z, 2, s_7))) return 0; /* literal, line 191 */ + { int ret = slice_del(z); /* delete, line 191 */ if (ret < 0) return ret; } break; case 2: - if (!(eq_s_b(z, 2, s_8))) return 0; - { int ret = slice_del(z); /* delete, line 192 */ + if (!(eq_s_b(z, 2, s_8))) return 0; /* literal, line 194 */ + { int ret = slice_del(z); /* delete, line 194 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_del(z); /* delete, line 194 */ + { int ret = slice_del(z); /* delete, line 196 */ if (ret < 0) return ret; } break; @@ -595,94 +563,117 @@ static int r_tidy_up(struct SN_env * z) { return 1; } -extern int russian_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 201 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 201 */ - if (ret < 0) return ret; +extern int russian_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 205 */ + while(1) { /* repeat, line 205 */ + int c2 = z->c; + while(1) { /* goto, line 205 */ + int c3 = z->c; + z->bra = z->c; /* [, line 205 */ + if (!(eq_s(z, 2, s_9))) goto lab2; /* literal, line 205 */ + z->ket = z->c; /* ], line 205 */ + z->c = c3; + break; + lab2: + z->c = c3; + { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); + if (ret < 0) goto lab1; + z->c = ret; /* goto, line 205 */ + } + } + { int ret = slice_from_s(z, 2, s_10); /* <-, line 205 */ + if (ret < 0) return ret; + } + continue; + lab1: + z->c = c2; + break; } - lab0: z->c = c1; } - z->lb = z->c; z->c = z->l; /* backwards, line 202 */ + /* do, line 207 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 207 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } +lab3: + z->lb = z->c; z->c = z->l; /* backwards, line 208 */ + - { int mlimit; /* setlimit, line 202 */ - int m2 = z->l - z->c; (void)m2; + { int mlimit4; /* setlimit, line 208 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 202 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m2; - { int m3 = z->l - z->c; (void)m3; /* do, line 203 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 204 */ - { int ret = r_perfective_gerund(z); - if (ret == 0) goto lab3; /* call perfective_gerund, line 204 */ + mlimit4 = z->lb; z->lb = z->I[0]; + { int m5 = z->l - z->c; (void)m5; /* do, line 209 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 210 */ + { int ret = r_perfective_gerund(z); /* call perfective_gerund, line 210 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } - goto lab2; - lab3: - z->c = z->l - m4; - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 205 */ - { int ret = r_reflexive(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call reflexive, line 205 */ + goto lab5; + lab6: + z->c = z->l - m6; + { int m7 = z->l - z->c; (void)m7; /* try, line 211 */ + { int ret = r_reflexive(z); /* call reflexive, line 211 */ + if (ret == 0) { z->c = z->l - m7; goto lab7; } if (ret < 0) return ret; } - lab4: + lab7: ; } - { int m5 = z->l - z->c; (void)m5; /* or, line 206 */ - { int ret = r_adjectival(z); - if (ret == 0) goto lab6; /* call adjectival, line 206 */ + { int m8 = z->l - z->c; (void)m8; /* or, line 212 */ + { int ret = r_adjectival(z); /* call adjectival, line 212 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } - goto lab5; - lab6: - z->c = z->l - m5; - { int ret = r_verb(z); - if (ret == 0) goto lab7; /* call verb, line 206 */ + goto lab8; + lab9: + z->c = z->l - m8; + { int ret = r_verb(z); /* call verb, line 212 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } - goto lab5; - lab7: - z->c = z->l - m5; - { int ret = r_noun(z); - if (ret == 0) goto lab1; /* call noun, line 206 */ + goto lab8; + lab10: + z->c = z->l - m8; + { int ret = r_noun(z); /* call noun, line 212 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } } - lab5: + lab8: ; } - lab2: - lab1: - z->c = z->l - m3; + lab5: + lab4: + z->c = z->l - m5; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 209 */ - z->ket = z->c; /* [, line 209 */ - if (!(eq_s_b(z, 2, s_9))) { z->c = z->l - m_keep; goto lab8; } - z->bra = z->c; /* ], line 209 */ - { int ret = slice_del(z); /* delete, line 209 */ + { int m9 = z->l - z->c; (void)m9; /* try, line 215 */ + z->ket = z->c; /* [, line 215 */ + if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m9; goto lab11; } /* literal, line 215 */ + z->bra = z->c; /* ], line 215 */ + { int ret = slice_del(z); /* delete, line 215 */ if (ret < 0) return ret; } - lab8: + lab11: ; } - { int m6 = z->l - z->c; (void)m6; /* do, line 212 */ - { int ret = r_derivational(z); - if (ret == 0) goto lab9; /* call derivational, line 212 */ + { int m10 = z->l - z->c; (void)m10; /* do, line 218 */ + { int ret = r_derivational(z); /* call derivational, line 218 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } - lab9: - z->c = z->l - m6; + lab12: + z->c = z->l - m10; } - { int m7 = z->l - z->c; (void)m7; /* do, line 213 */ - { int ret = r_tidy_up(z); - if (ret == 0) goto lab10; /* call tidy_up, line 213 */ + { int m11 = z->l - z->c; (void)m11; /* do, line 219 */ + { int ret = r_tidy_up(z); /* call tidy_up, line 219 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } - lab10: - z->c = z->l - m7; + lab13: + z->c = z->l - m11; } - z->lb = mlimit; + z->lb = mlimit4; } z->c = z->lb; return 1; diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c index 5ac83fdc1df..a3755d4d840 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_spanish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -497,28 +497,22 @@ static const symbol s_6[] = { 'a', 'n', 'd', 'o' }; static const symbol s_7[] = { 'a', 'r' }; static const symbol s_8[] = { 'e', 'r' }; static const symbol s_9[] = { 'i', 'r' }; -static const symbol s_10[] = { 'u' }; -static const symbol s_11[] = { 'i', 'c' }; -static const symbol s_12[] = { 'l', 'o', 'g' }; -static const symbol s_13[] = { 'u' }; -static const symbol s_14[] = { 'e', 'n', 't', 'e' }; +static const symbol s_10[] = { 'i', 'c' }; +static const symbol s_11[] = { 'l', 'o', 'g' }; +static const symbol s_12[] = { 'u' }; +static const symbol s_13[] = { 'e', 'n', 't', 'e' }; +static const symbol s_14[] = { 'a', 't' }; static const symbol s_15[] = { 'a', 't' }; -static const symbol s_16[] = { 'a', 't' }; -static const symbol s_17[] = { 'u' }; -static const symbol s_18[] = { 'u' }; -static const symbol s_19[] = { 'g' }; -static const symbol s_20[] = { 'u' }; -static const symbol s_21[] = { 'g' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - z->I[1] = z->l; - z->I[2] = z->l; +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $pV = , line 33 */ + z->I[1] = z->l; /* $p1 = , line 34 */ + z->I[2] = z->l; /* $p2 = , line 35 */ { int c1 = z->c; /* do, line 37 */ { int c2 = z->c; /* or, line 39 */ - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ { int c3 = z->c; /* or, line 38 */ - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab4; + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab4; /* non v, line 38 */ { /* gopast */ /* grouping v, line 38 */ int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab4; @@ -527,7 +521,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab3; lab4: z->c = c3; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab2; /* grouping v, line 38 */ { /* gopast */ /* non v, line 38 */ int ret = in_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab2; @@ -538,9 +532,9 @@ static int r_mark_regions(struct SN_env * z) { goto lab1; lab2: z->c = c2; - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab0; + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab0; /* non v, line 40 */ { int c4 = z->c; /* or, line 40 */ - if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab6; + if (out_grouping_U(z, g_v, 97, 252, 0)) goto lab6; /* non v, line 40 */ { /* gopast */ /* grouping v, line 40 */ int ret = out_grouping_U(z, g_v, 97, 252, 1); if (ret < 0) goto lab6; @@ -549,7 +543,7 @@ static int r_mark_regions(struct SN_env * z) { goto lab5; lab6: z->c = c4; - if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab0; + if (in_grouping_U(z, g_v, 97, 252, 0)) goto lab0; /* grouping v, line 40 */ { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); if (ret < 0) goto lab0; z->c = ret; /* next, line 40 */ @@ -592,17 +586,16 @@ static int r_mark_regions(struct SN_env * z) { return 1; } -static int r_postlude(struct SN_env * z) { +static int r_postlude(struct SN_env * z) { /* forwardmode */ int among_var; while(1) { /* repeat, line 49 */ int c1 = z->c; z->bra = z->c; /* [, line 50 */ - if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((67641858 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else - among_var = find_among(z, a_0, 6); /* substring, line 50 */ + if (z->c + 1 >= z->l || z->p[z->c + 1] >> 5 != 5 || !((67641858 >> (z->p[z->c + 1] & 0x1f)) & 1)) among_var = 6; else /* substring, line 50 */ + among_var = find_among(z, a_0, 6); if (!(among_var)) goto lab0; z->ket = z->c; /* ], line 50 */ - switch(among_var) { - case 0: goto lab0; + switch (among_var) { /* among, line 50 */ case 1: { int ret = slice_from_s(z, 1, s_0); /* <-, line 51 */ if (ret < 0) return ret; @@ -643,36 +636,34 @@ static int r_postlude(struct SN_env * z) { return 1; } -static int r_RV(struct SN_env * z) { - if (!(z->I[0] <= z->c)) return 0; +static int r_RV(struct SN_env * z) { /* backwardmode */ + if (!(z->I[0] <= z->c)) return 0; /* $( <= ), line 63 */ return 1; } -static int r_R1(struct SN_env * z) { - if (!(z->I[1] <= z->c)) return 0; +static int r_R1(struct SN_env * z) { /* backwardmode */ + if (!(z->I[1] <= z->c)) return 0; /* $( <= ), line 64 */ return 1; } -static int r_R2(struct SN_env * z) { - if (!(z->I[2] <= z->c)) return 0; +static int r_R2(struct SN_env * z) { /* backwardmode */ + if (!(z->I[2] <= z->c)) return 0; /* $( <= ), line 65 */ return 1; } -static int r_attached_pronoun(struct SN_env * z) { +static int r_attached_pronoun(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 68 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_1, 13))) return 0; /* substring, line 68 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((557090 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 68 */ + if (!(find_among_b(z, a_1, 13))) return 0; z->bra = z->c; /* ], line 68 */ - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; - among_var = find_among_b(z, a_2, 11); /* substring, line 72 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 111 && z->p[z->c - 1] != 114)) return 0; /* substring, line 72 */ + among_var = find_among_b(z, a_2, 11); if (!(among_var)) return 0; - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 72 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 72 */ + if (ret <= 0) return ret; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 72 */ case 1: z->bra = z->c; /* ], line 73 */ { int ret = slice_from_s(z, 5, s_5); /* <-, line 73 */ @@ -709,7 +700,8 @@ static int r_attached_pronoun(struct SN_env * z) { } break; case 7: - if (!(eq_s_b(z, 1, s_10))) return 0; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 82 */ + z->c--; { int ret = slice_del(z); /* delete, line 82 */ if (ret < 0) return ret; } @@ -718,38 +710,35 @@ static int r_attached_pronoun(struct SN_env * z) { return 1; } -static int r_standard_suffix(struct SN_env * z) { +static int r_standard_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 87 */ - if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - among_var = find_among_b(z, a_6, 46); /* substring, line 87 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((835634 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* substring, line 87 */ + among_var = find_among_b(z, a_6, 46); if (!(among_var)) return 0; z->bra = z->c; /* ], line 87 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 87 */ case 1: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 99 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 99 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 99 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 105 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 105 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 105 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 106 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 106 */ z->ket = z->c; /* [, line 106 */ - if (!(eq_s_b(z, 2, s_11))) { z->c = z->l - m_keep; goto lab0; } + if (!(eq_s_b(z, 2, s_10))) { z->c = z->l - m1; goto lab0; } /* literal, line 106 */ z->bra = z->c; /* ], line 106 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call R2, line 106 */ + { int ret = r_R2(z); /* call R2, line 106 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 106 */ @@ -760,61 +749,56 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 3: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 111 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 111 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 3, s_12); /* <-, line 111 */ + { int ret = slice_from_s(z, 3, s_11); /* <-, line 111 */ if (ret < 0) return ret; } break; case 4: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 115 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 115 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 1, s_13); /* <-, line 115 */ + { int ret = slice_from_s(z, 1, s_12); /* <-, line 115 */ if (ret < 0) return ret; } break; case 5: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 119 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 119 */ + if (ret <= 0) return ret; } - { int ret = slice_from_s(z, 4, s_14); /* <-, line 119 */ + { int ret = slice_from_s(z, 4, s_13); /* <-, line 119 */ if (ret < 0) return ret; } break; case 6: - { int ret = r_R1(z); - if (ret == 0) return 0; /* call R1, line 123 */ - if (ret < 0) return ret; + { int ret = r_R1(z); /* call R1, line 123 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 123 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 124 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 124 */ z->ket = z->c; /* [, line 125 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab1; } - among_var = find_among_b(z, a_3, 4); /* substring, line 125 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab1; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4718616 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m2; goto lab1; } /* substring, line 125 */ + among_var = find_among_b(z, a_3, 4); + if (!(among_var)) { z->c = z->l - m2; goto lab1; } z->bra = z->c; /* ], line 125 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 125 */ + { int ret = r_R2(z); /* call R2, line 125 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 125 */ if (ret < 0) return ret; } - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab1; } + switch (among_var) { /* among, line 125 */ case 1: z->ket = z->c; /* [, line 126 */ - if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m_keep; goto lab1; } + if (!(eq_s_b(z, 2, s_14))) { z->c = z->l - m2; goto lab1; } /* literal, line 126 */ z->bra = z->c; /* ], line 126 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab1; } /* call R2, line 126 */ + { int ret = r_R2(z); /* call R2, line 126 */ + if (ret == 0) { z->c = z->l - m2; goto lab1; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 126 */ @@ -827,79 +811,64 @@ static int r_standard_suffix(struct SN_env * z) { } break; case 7: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 135 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 135 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 135 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 136 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 136 */ z->ket = z->c; /* [, line 137 */ - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m_keep; goto lab2; } - among_var = find_among_b(z, a_4, 3); /* substring, line 137 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab2; } + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 101) { z->c = z->l - m3; goto lab2; } /* substring, line 137 */ + if (!(find_among_b(z, a_4, 3))) { z->c = z->l - m3; goto lab2; } z->bra = z->c; /* ], line 137 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab2; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call R2, line 140 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 140 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 140 */ + if (ret == 0) { z->c = z->l - m3; goto lab2; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 140 */ + if (ret < 0) return ret; } lab2: ; } break; case 8: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 147 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 147 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 147 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 148 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 148 */ z->ket = z->c; /* [, line 149 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m_keep; goto lab3; } - among_var = find_among_b(z, a_5, 3); /* substring, line 149 */ - if (!(among_var)) { z->c = z->l - m_keep; goto lab3; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((4198408 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->c = z->l - m4; goto lab3; } /* substring, line 149 */ + if (!(find_among_b(z, a_5, 3))) { z->c = z->l - m4; goto lab3; } z->bra = z->c; /* ], line 149 */ - switch(among_var) { - case 0: { z->c = z->l - m_keep; goto lab3; } - case 1: - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab3; } /* call R2, line 152 */ - if (ret < 0) return ret; - } - { int ret = slice_del(z); /* delete, line 152 */ - if (ret < 0) return ret; - } - break; + { int ret = r_R2(z); /* call R2, line 152 */ + if (ret == 0) { z->c = z->l - m4; goto lab3; } + if (ret < 0) return ret; + } + { int ret = slice_del(z); /* delete, line 152 */ + if (ret < 0) return ret; } lab3: ; } break; case 9: - { int ret = r_R2(z); - if (ret == 0) return 0; /* call R2, line 159 */ - if (ret < 0) return ret; + { int ret = r_R2(z); /* call R2, line 159 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 159 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 160 */ + { int m5 = z->l - z->c; (void)m5; /* try, line 160 */ z->ket = z->c; /* [, line 161 */ - if (!(eq_s_b(z, 2, s_16))) { z->c = z->l - m_keep; goto lab4; } + if (!(eq_s_b(z, 2, s_15))) { z->c = z->l - m5; goto lab4; } /* literal, line 161 */ z->bra = z->c; /* ], line 161 */ - { int ret = r_R2(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call R2, line 161 */ + { int ret = r_R2(z); /* call R2, line 161 */ + if (ret == 0) { z->c = z->l - m5; goto lab4; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 161 */ @@ -913,54 +882,45 @@ static int r_standard_suffix(struct SN_env * z) { return 1; } -static int r_y_verb_suffix(struct SN_env * z) { - int among_var; - { int mlimit; /* setlimit, line 168 */ - int m1 = z->l - z->c; (void)m1; +static int r_y_verb_suffix(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 168 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 168 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 168 */ - among_var = find_among_b(z, a_7, 12); /* substring, line 168 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(find_among_b(z, a_7, 12))) { z->lb = mlimit1; return 0; } /* substring, line 168 */ z->bra = z->c; /* ], line 168 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; - case 1: - if (!(eq_s_b(z, 1, s_17))) return 0; - { int ret = slice_del(z); /* delete, line 171 */ - if (ret < 0) return ret; - } - break; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') return 0; /* literal, line 171 */ + z->c--; + { int ret = slice_del(z); /* delete, line 171 */ + if (ret < 0) return ret; } return 1; } -static int r_verb_suffix(struct SN_env * z) { +static int r_verb_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 176 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 176 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 176 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 176 */ among_var = find_among_b(z, a_8, 96); /* substring, line 176 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 176 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 176 */ case 1: - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 179 */ - if (!(eq_s_b(z, 1, s_18))) { z->c = z->l - m_keep; goto lab0; } - { int m_test = z->l - z->c; /* test, line 179 */ - if (!(eq_s_b(z, 1, s_19))) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m2 = z->l - z->c; (void)m2; /* try, line 179 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + z->c--; + { int m_test3 = z->l - z->c; /* test, line 179 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m2; goto lab0; } /* literal, line 179 */ + z->c--; + z->c = z->l - m_test3; } lab0: ; @@ -979,41 +939,40 @@ static int r_verb_suffix(struct SN_env * z) { return 1; } -static int r_residual_suffix(struct SN_env * z) { +static int r_residual_suffix(struct SN_env * z) { /* backwardmode */ int among_var; z->ket = z->c; /* [, line 205 */ among_var = find_among_b(z, a_9, 8); /* substring, line 205 */ if (!(among_var)) return 0; z->bra = z->c; /* ], line 205 */ - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 205 */ case 1: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 208 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 208 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 208 */ if (ret < 0) return ret; } break; case 2: - { int ret = r_RV(z); - if (ret == 0) return 0; /* call RV, line 210 */ - if (ret < 0) return ret; + { int ret = r_RV(z); /* call RV, line 210 */ + if (ret <= 0) return ret; } { int ret = slice_del(z); /* delete, line 210 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 210 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 210 */ z->ket = z->c; /* [, line 210 */ - if (!(eq_s_b(z, 1, s_20))) { z->c = z->l - m_keep; goto lab0; } + if (z->c <= z->lb || z->p[z->c - 1] != 'u') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->c--; z->bra = z->c; /* ], line 210 */ - { int m_test = z->l - z->c; /* test, line 210 */ - if (!(eq_s_b(z, 1, s_21))) { z->c = z->l - m_keep; goto lab0; } - z->c = z->l - m_test; + { int m_test2 = z->l - z->c; /* test, line 210 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'g') { z->c = z->l - m1; goto lab0; } /* literal, line 210 */ + z->c--; + z->c = z->l - m_test2; } - { int ret = r_RV(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab0; } /* call RV, line 210 */ + { int ret = r_RV(z); /* call RV, line 210 */ + if (ret == 0) { z->c = z->l - m1; goto lab0; } if (ret < 0) return ret; } { int ret = slice_del(z); /* delete, line 210 */ @@ -1027,66 +986,64 @@ static int r_residual_suffix(struct SN_env * z) { return 1; } -extern int spanish_UTF_8_stem(struct SN_env * z) { - { int c1 = z->c; /* do, line 216 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 216 */ - if (ret < 0) return ret; - } - lab0: - z->c = c1; +extern int spanish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + /* do, line 216 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 216 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; } +lab0: z->lb = z->c; z->c = z->l; /* backwards, line 217 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 218 */ - { int ret = r_attached_pronoun(z); - if (ret == 0) goto lab1; /* call attached_pronoun, line 218 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 218 */ + { int ret = r_attached_pronoun(z); /* call attached_pronoun, line 218 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: - z->c = z->l - m2; + z->c = z->l - m1; } - { int m3 = z->l - z->c; (void)m3; /* do, line 219 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 219 */ - { int ret = r_standard_suffix(z); - if (ret == 0) goto lab4; /* call standard_suffix, line 219 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 219 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 219 */ + { int ret = r_standard_suffix(z); /* call standard_suffix, line 219 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab3; lab4: - z->c = z->l - m4; - { int ret = r_y_verb_suffix(z); - if (ret == 0) goto lab5; /* call y_verb_suffix, line 220 */ + z->c = z->l - m3; + { int ret = r_y_verb_suffix(z); /* call y_verb_suffix, line 220 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab3; lab5: - z->c = z->l - m4; - { int ret = r_verb_suffix(z); - if (ret == 0) goto lab2; /* call verb_suffix, line 221 */ + z->c = z->l - m3; + { int ret = r_verb_suffix(z); /* call verb_suffix, line 221 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } } lab3: lab2: - z->c = z->l - m3; + z->c = z->l - m2; } - { int m5 = z->l - z->c; (void)m5; /* do, line 223 */ - { int ret = r_residual_suffix(z); - if (ret == 0) goto lab6; /* call residual_suffix, line 223 */ + { int m4 = z->l - z->c; (void)m4; /* do, line 223 */ + { int ret = r_residual_suffix(z); /* call residual_suffix, line 223 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } lab6: - z->c = z->l - m5; + z->c = z->l - m4; } z->c = z->lb; - { int c6 = z->c; /* do, line 225 */ - { int ret = r_postlude(z); - if (ret == 0) goto lab7; /* call postlude, line 225 */ + { int c5 = z->c; /* do, line 225 */ + { int ret = r_postlude(z); /* call postlude, line 225 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } lab7: - z->c = c6; + z->c = c5; } return 1; } diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c index 1372cec1eeb..c47777d7c5f 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_swedish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -146,15 +146,15 @@ static const unsigned char g_s_ending[] = { 119, 127, 149 }; static const symbol s_0[] = { 'l', 0xC3, 0xB6, 's' }; static const symbol s_1[] = { 'f', 'u', 'l', 'l' }; -static int r_mark_regions(struct SN_env * z) { - z->I[0] = z->l; - { int c_test = z->c; /* test, line 29 */ - { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); +static int r_mark_regions(struct SN_env * z) { /* forwardmode */ + z->I[0] = z->l; /* $p1 = , line 28 */ + { int c_test1 = z->c; /* test, line 29 */ + { int ret = skip_utf8(z->p, z->c, 0, z->l, + 3); /* hop, line 29 */ if (ret < 0) return 0; - z->c = ret; /* hop, line 29 */ + z->c = ret; } z->I[1] = z->c; /* setmark x, line 29 */ - z->c = c_test; + z->c = c_test1; } if (out_grouping_U(z, g_v, 97, 246, 1) < 0) return 0; /* goto */ /* grouping v, line 30 */ { /* gopast */ /* non v, line 30 */ @@ -163,37 +163,34 @@ static int r_mark_regions(struct SN_env * z) { z->c += ret; } z->I[0] = z->c; /* setmark p1, line 30 */ - /* try, line 31 */ - if (!(z->I[0] < z->I[1])) goto lab0; - z->I[0] = z->I[1]; + /* try, line 31 */ + if (!(z->I[0] < z->I[1])) goto lab0; /* $( < ), line 31 */ + z->I[0] = z->I[1]; /* $p1 = , line 31 */ lab0: return 1; } -static int r_main_suffix(struct SN_env * z) { +static int r_main_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 37 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 37 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 37 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 37 */ - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_0, 37); /* substring, line 37 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1851442 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 37 */ + among_var = find_among_b(z, a_0, 37); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 37 */ - z->lb = mlimit; + z->lb = mlimit1; } - switch(among_var) { - case 0: return 0; + switch (among_var) { /* among, line 38 */ case 1: { int ret = slice_del(z); /* delete, line 44 */ if (ret < 0) return ret; } break; case 2: - if (in_grouping_b_U(z, g_s_ending, 98, 121, 0)) return 0; + if (in_grouping_b_U(z, g_s_ending, 98, 121, 0)) return 0; /* grouping s_ending, line 46 */ { int ret = slice_del(z); /* delete, line 46 */ if (ret < 0) return ret; } @@ -202,20 +199,18 @@ static int r_main_suffix(struct SN_env * z) { return 1; } -static int r_consonant_pair(struct SN_env * z) { - { int mlimit; /* setlimit, line 50 */ - int m1 = z->l - z->c; (void)m1; +static int r_consonant_pair(struct SN_env * z) { /* backwardmode */ + + { int mlimit1; /* setlimit, line 50 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 50 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; { int m2 = z->l - z->c; (void)m2; /* and, line 52 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit; return 0; } /* among, line 51 */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1064976 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* among, line 51 */ + if (!(find_among_b(z, a_1, 7))) { z->lb = mlimit1; return 0; } z->c = z->l - m2; z->ket = z->c; /* [, line 52 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) { z->lb = mlimit; return 0; } + if (ret < 0) { z->lb = mlimit1; return 0; } z->c = ret; /* next, line 52 */ } z->bra = z->c; /* ], line 52 */ @@ -223,26 +218,23 @@ static int r_consonant_pair(struct SN_env * z) { if (ret < 0) return ret; } } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -static int r_other_suffix(struct SN_env * z) { +static int r_other_suffix(struct SN_env * z) { /* backwardmode */ int among_var; - { int mlimit; /* setlimit, line 55 */ - int m1 = z->l - z->c; (void)m1; + + { int mlimit1; /* setlimit, line 55 */ if (z->c < z->I[0]) return 0; - z->c = z->I[0]; /* tomark, line 55 */ - mlimit = z->lb; z->lb = z->c; - z->c = z->l - m1; + mlimit1 = z->lb; z->lb = z->I[0]; z->ket = z->c; /* [, line 56 */ - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit; return 0; } - among_var = find_among_b(z, a_2, 5); /* substring, line 56 */ - if (!(among_var)) { z->lb = mlimit; return 0; } + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((1572992 >> (z->p[z->c - 1] & 0x1f)) & 1)) { z->lb = mlimit1; return 0; } /* substring, line 56 */ + among_var = find_among_b(z, a_2, 5); + if (!(among_var)) { z->lb = mlimit1; return 0; } z->bra = z->c; /* ], line 56 */ - switch(among_var) { - case 0: { z->lb = mlimit; return 0; } + switch (among_var) { /* among, line 56 */ case 1: { int ret = slice_del(z); /* delete, line 57 */ if (ret < 0) return ret; @@ -259,15 +251,15 @@ static int r_other_suffix(struct SN_env * z) { } break; } - z->lb = mlimit; + z->lb = mlimit1; } return 1; } -extern int swedish_UTF_8_stem(struct SN_env * z) { +extern int swedish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ { int c1 = z->c; /* do, line 66 */ - { int ret = r_mark_regions(z); - if (ret == 0) goto lab0; /* call mark_regions, line 66 */ + { int ret = r_mark_regions(z); /* call mark_regions, line 66 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: @@ -276,24 +268,24 @@ extern int swedish_UTF_8_stem(struct SN_env * z) { z->lb = z->c; z->c = z->l; /* backwards, line 67 */ { int m2 = z->l - z->c; (void)m2; /* do, line 68 */ - { int ret = r_main_suffix(z); - if (ret == 0) goto lab1; /* call main_suffix, line 68 */ + { int ret = r_main_suffix(z); /* call main_suffix, line 68 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } { int m3 = z->l - z->c; (void)m3; /* do, line 69 */ - { int ret = r_consonant_pair(z); - if (ret == 0) goto lab2; /* call consonant_pair, line 69 */ + { int ret = r_consonant_pair(z); /* call consonant_pair, line 69 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: z->c = z->l - m3; } { int m4 = z->l - z->c; (void)m4; /* do, line 70 */ - { int ret = r_other_suffix(z); - if (ret == 0) goto lab3; /* call other_suffix, line 70 */ + { int ret = r_other_suffix(z); /* call other_suffix, line 70 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } lab3: diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c b/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c new file mode 100644 index 00000000000..9bb416c9b10 --- /dev/null +++ b/src/backend/snowball/libstemmer/stem_UTF_8_tamil.c @@ -0,0 +1,1915 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#include "header.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern int tamil_UTF_8_stem(struct SN_env * z); +#ifdef __cplusplus +} +#endif +static int r_has_min_length(struct SN_env * z); +static int r_remove_common_word_endings(struct SN_env * z); +static int r_remove_tense_suffixes(struct SN_env * z); +static int r_remove_tense_suffix(struct SN_env * z); +static int r_fix_endings(struct SN_env * z); +static int r_fix_ending(struct SN_env * z); +static int r_fix_va_start(struct SN_env * z); +static int r_remove_vetrumai_urupukal(struct SN_env * z); +static int r_remove_um(struct SN_env * z); +static int r_remove_command_suffixes(struct SN_env * z); +static int r_remove_pronoun_prefixes(struct SN_env * z); +static int r_remove_question_prefixes(struct SN_env * z); +static int r_remove_question_suffixes(struct SN_env * z); +static int r_remove_plural_suffix(struct SN_env * z); +#ifdef __cplusplus +extern "C" { +#endif + + +extern struct SN_env * tamil_UTF_8_create_env(void); +extern void tamil_UTF_8_close_env(struct SN_env * z); + + +#ifdef __cplusplus +} +#endif +static const symbol s_0_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_0_1[3] = { 0xE0, 0xAE, 0x99 }; +static const symbol s_0_2[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_0_3[3] = { 0xE0, 0xAE, 0x9E }; +static const symbol s_0_4[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_0_5[3] = { 0xE0, 0xAE, 0xA8 }; +static const symbol s_0_6[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_0_7[3] = { 0xE0, 0xAE, 0xAE }; +static const symbol s_0_8[3] = { 0xE0, 0xAE, 0xAF }; +static const symbol s_0_9[3] = { 0xE0, 0xAE, 0xB5 }; + +static const struct among a_0[10] = +{ +/* 0 */ { 3, s_0_0, -1, -1, 0}, +/* 1 */ { 3, s_0_1, -1, -1, 0}, +/* 2 */ { 3, s_0_2, -1, -1, 0}, +/* 3 */ { 3, s_0_3, -1, -1, 0}, +/* 4 */ { 3, s_0_4, -1, -1, 0}, +/* 5 */ { 3, s_0_5, -1, -1, 0}, +/* 6 */ { 3, s_0_6, -1, -1, 0}, +/* 7 */ { 3, s_0_7, -1, -1, 0}, +/* 8 */ { 3, s_0_8, -1, -1, 0}, +/* 9 */ { 3, s_0_9, -1, -1, 0} +}; + +static const symbol s_1_0[12] = { 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x8D }; +static const symbol s_1_1[6] = { 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D }; +static const symbol s_1_2[9] = { 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xA4 }; + +static const struct among a_1[3] = +{ +/* 0 */ { 12, s_1_0, -1, -1, 0}, +/* 1 */ { 6, s_1_1, -1, -1, 0}, +/* 2 */ { 9, s_1_2, -1, -1, 0} +}; + +static const symbol s_2_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_2_1[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_2_2[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_2[3] = +{ +/* 0 */ { 3, s_2_0, -1, -1, 0}, +/* 1 */ { 3, s_2_1, -1, -1, 0}, +/* 2 */ { 3, s_2_2, -1, -1, 0} +}; + +static const symbol s_3_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_3_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_3_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_3_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_3_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_3_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_3[6] = +{ +/* 0 */ { 3, s_3_0, -1, -1, 0}, +/* 1 */ { 3, s_3_1, -1, -1, 0}, +/* 2 */ { 3, s_3_2, -1, -1, 0}, +/* 3 */ { 3, s_3_3, -1, -1, 0}, +/* 4 */ { 3, s_3_4, -1, -1, 0}, +/* 5 */ { 3, s_3_5, -1, -1, 0} +}; + +static const symbol s_4_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_4_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_4_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_4_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_4_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_4_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_4[6] = +{ +/* 0 */ { 3, s_4_0, -1, -1, 0}, +/* 1 */ { 3, s_4_1, -1, -1, 0}, +/* 2 */ { 3, s_4_2, -1, -1, 0}, +/* 3 */ { 3, s_4_3, -1, -1, 0}, +/* 4 */ { 3, s_4_4, -1, -1, 0}, +/* 5 */ { 3, s_4_5, -1, -1, 0} +}; + +static const symbol s_5_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_5_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_5_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_5_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_5_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_5_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_5[6] = +{ +/* 0 */ { 3, s_5_0, -1, -1, 0}, +/* 1 */ { 3, s_5_1, -1, -1, 0}, +/* 2 */ { 3, s_5_2, -1, -1, 0}, +/* 3 */ { 3, s_5_3, -1, -1, 0}, +/* 4 */ { 3, s_5_4, -1, -1, 0}, +/* 5 */ { 3, s_5_5, -1, -1, 0} +}; + +static const symbol s_6_0[3] = { 0xE0, 0xAE, 0xAF }; +static const symbol s_6_1[3] = { 0xE0, 0xAE, 0xB0 }; +static const symbol s_6_2[3] = { 0xE0, 0xAE, 0xB2 }; +static const symbol s_6_3[3] = { 0xE0, 0xAE, 0xB3 }; +static const symbol s_6_4[3] = { 0xE0, 0xAE, 0xB4 }; +static const symbol s_6_5[3] = { 0xE0, 0xAE, 0xB5 }; + +static const struct among a_6[6] = +{ +/* 0 */ { 3, s_6_0, -1, -1, 0}, +/* 1 */ { 3, s_6_1, -1, -1, 0}, +/* 2 */ { 3, s_6_2, -1, -1, 0}, +/* 3 */ { 3, s_6_3, -1, -1, 0}, +/* 4 */ { 3, s_6_4, -1, -1, 0}, +/* 5 */ { 3, s_6_5, -1, -1, 0} +}; + +static const symbol s_7_0[3] = { 0xE0, 0xAE, 0x99 }; +static const symbol s_7_1[3] = { 0xE0, 0xAE, 0x9E }; +static const symbol s_7_2[3] = { 0xE0, 0xAE, 0xA3 }; +static const symbol s_7_3[3] = { 0xE0, 0xAE, 0xA8 }; +static const symbol s_7_4[3] = { 0xE0, 0xAE, 0xA9 }; +static const symbol s_7_5[3] = { 0xE0, 0xAE, 0xAE }; + +static const struct among a_7[6] = +{ +/* 0 */ { 3, s_7_0, -1, -1, 0}, +/* 1 */ { 3, s_7_1, -1, -1, 0}, +/* 2 */ { 3, s_7_2, -1, -1, 0}, +/* 3 */ { 3, s_7_3, -1, -1, 0}, +/* 4 */ { 3, s_7_4, -1, -1, 0}, +/* 5 */ { 3, s_7_5, -1, -1, 0} +}; + +static const symbol s_8_0[6] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8D }; +static const symbol s_8_1[3] = { 0xE0, 0xAE, 0xAF }; +static const symbol s_8_2[3] = { 0xE0, 0xAE, 0xB5 }; + +static const struct among a_8[3] = +{ +/* 0 */ { 6, s_8_0, -1, -1, 0}, +/* 1 */ { 3, s_8_1, -1, -1, 0}, +/* 2 */ { 3, s_8_2, -1, -1, 0} +}; + +static const symbol s_9_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_9_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_9_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_9_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_9_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_9_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_9_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_9_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_9[8] = +{ +/* 0 */ { 3, s_9_0, -1, -1, 0}, +/* 1 */ { 3, s_9_1, -1, -1, 0}, +/* 2 */ { 3, s_9_2, -1, -1, 0}, +/* 3 */ { 3, s_9_3, -1, -1, 0}, +/* 4 */ { 3, s_9_4, -1, -1, 0}, +/* 5 */ { 3, s_9_5, -1, -1, 0}, +/* 6 */ { 3, s_9_6, -1, -1, 0}, +/* 7 */ { 3, s_9_7, -1, -1, 0} +}; + +static const symbol s_10_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_10_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_10_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_10_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_10_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_10_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_10_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_10_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_10[8] = +{ +/* 0 */ { 3, s_10_0, -1, -1, 0}, +/* 1 */ { 3, s_10_1, -1, -1, 0}, +/* 2 */ { 3, s_10_2, -1, -1, 0}, +/* 3 */ { 3, s_10_3, -1, -1, 0}, +/* 4 */ { 3, s_10_4, -1, -1, 0}, +/* 5 */ { 3, s_10_5, -1, -1, 0}, +/* 6 */ { 3, s_10_6, -1, -1, 0}, +/* 7 */ { 3, s_10_7, -1, -1, 0} +}; + +static const symbol s_11_0[3] = { 0xE0, 0xAE, 0x85 }; +static const symbol s_11_1[3] = { 0xE0, 0xAE, 0x87 }; +static const symbol s_11_2[3] = { 0xE0, 0xAE, 0x89 }; + +static const struct among a_11[3] = +{ +/* 0 */ { 3, s_11_0, -1, -1, 0}, +/* 1 */ { 3, s_11_1, -1, -1, 0}, +/* 2 */ { 3, s_11_2, -1, -1, 0} +}; + +static const symbol s_12_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_12_1[3] = { 0xE0, 0xAE, 0x99 }; +static const symbol s_12_2[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_12_3[3] = { 0xE0, 0xAE, 0x9E }; +static const symbol s_12_4[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_12_5[3] = { 0xE0, 0xAE, 0xA8 }; +static const symbol s_12_6[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_12_7[3] = { 0xE0, 0xAE, 0xAE }; +static const symbol s_12_8[3] = { 0xE0, 0xAE, 0xAF }; +static const symbol s_12_9[3] = { 0xE0, 0xAE, 0xB5 }; + +static const struct among a_12[10] = +{ +/* 0 */ { 3, s_12_0, -1, -1, 0}, +/* 1 */ { 3, s_12_1, -1, -1, 0}, +/* 2 */ { 3, s_12_2, -1, -1, 0}, +/* 3 */ { 3, s_12_3, -1, -1, 0}, +/* 4 */ { 3, s_12_4, -1, -1, 0}, +/* 5 */ { 3, s_12_5, -1, -1, 0}, +/* 6 */ { 3, s_12_6, -1, -1, 0}, +/* 7 */ { 3, s_12_7, -1, -1, 0}, +/* 8 */ { 3, s_12_8, -1, -1, 0}, +/* 9 */ { 3, s_12_9, -1, -1, 0} +}; + +static const symbol s_13_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_13_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_13_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_13_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_13_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_13_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_13[6] = +{ +/* 0 */ { 3, s_13_0, -1, -1, 0}, +/* 1 */ { 3, s_13_1, -1, -1, 0}, +/* 2 */ { 3, s_13_2, -1, -1, 0}, +/* 3 */ { 3, s_13_3, -1, -1, 0}, +/* 4 */ { 3, s_13_4, -1, -1, 0}, +/* 5 */ { 3, s_13_5, -1, -1, 0} +}; + +static const symbol s_14_0[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_14_1[3] = { 0xE0, 0xAF, 0x8B }; +static const symbol s_14_2[3] = { 0xE0, 0xAE, 0xBE }; + +static const struct among a_14[3] = +{ +/* 0 */ { 3, s_14_0, -1, -1, 0}, +/* 1 */ { 3, s_14_1, -1, -1, 0}, +/* 2 */ { 3, s_14_2, -1, -1, 0} +}; + +static const symbol s_15_0[6] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xBF }; +static const symbol s_15_1[6] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xBF }; + +static const struct among a_15[2] = +{ +/* 0 */ { 6, s_15_0, -1, -1, 0}, +/* 1 */ { 6, s_15_1, -1, -1, 0} +}; + +static const symbol s_16_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_16_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_16_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_16_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_16_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_16_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_16_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_16_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_16[8] = +{ +/* 0 */ { 3, s_16_0, -1, -1, 0}, +/* 1 */ { 3, s_16_1, -1, -1, 0}, +/* 2 */ { 3, s_16_2, -1, -1, 0}, +/* 3 */ { 3, s_16_3, -1, -1, 0}, +/* 4 */ { 3, s_16_4, -1, -1, 0}, +/* 5 */ { 3, s_16_5, -1, -1, 0}, +/* 6 */ { 3, s_16_6, -1, -1, 0}, +/* 7 */ { 3, s_16_7, -1, -1, 0} +}; + +static const symbol s_17_0[15] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_17_1[18] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_17_2[9] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_17_3[12] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_17_4[18] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; +static const symbol s_17_5[21] = { 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB2, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_17_6[12] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F }; +static const symbol s_17_7[15] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xA3 }; +static const symbol s_17_8[9] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA9 }; +static const symbol s_17_9[18] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA4, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA9 }; +static const symbol s_17_10[15] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xB0, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xAF }; +static const symbol s_17_11[9] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xBF }; +static const symbol s_17_12[15] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAE, 0xBF }; + +static const struct among a_17[13] = +{ +/* 0 */ { 15, s_17_0, -1, -1, 0}, +/* 1 */ { 18, s_17_1, -1, -1, 0}, +/* 2 */ { 9, s_17_2, -1, -1, 0}, +/* 3 */ { 12, s_17_3, -1, -1, 0}, +/* 4 */ { 18, s_17_4, -1, -1, 0}, +/* 5 */ { 21, s_17_5, -1, -1, 0}, +/* 6 */ { 12, s_17_6, -1, -1, 0}, +/* 7 */ { 15, s_17_7, -1, -1, 0}, +/* 8 */ { 9, s_17_8, -1, -1, 0}, +/* 9 */ { 18, s_17_9, 8, -1, 0}, +/* 10 */ { 15, s_17_10, -1, -1, 0}, +/* 11 */ { 9, s_17_11, -1, -1, 0}, +/* 12 */ { 15, s_17_12, -1, -1, 0} +}; + +static const symbol s_18_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_18_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_18_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_18_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_18_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_18_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_18[6] = +{ +/* 0 */ { 3, s_18_0, -1, -1, 0}, +/* 1 */ { 3, s_18_1, -1, -1, 0}, +/* 2 */ { 3, s_18_2, -1, -1, 0}, +/* 3 */ { 3, s_18_3, -1, -1, 0}, +/* 4 */ { 3, s_18_4, -1, -1, 0}, +/* 5 */ { 3, s_18_5, -1, -1, 0} +}; + +static const symbol s_19_0[3] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_19_1[3] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_19_2[3] = { 0xE0, 0xAE, 0x9F }; +static const symbol s_19_3[3] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_19_4[3] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_19_5[3] = { 0xE0, 0xAE, 0xB1 }; + +static const struct among a_19[6] = +{ +/* 0 */ { 3, s_19_0, -1, -1, 0}, +/* 1 */ { 3, s_19_1, -1, -1, 0}, +/* 2 */ { 3, s_19_2, -1, -1, 0}, +/* 3 */ { 3, s_19_3, -1, -1, 0}, +/* 4 */ { 3, s_19_4, -1, -1, 0}, +/* 5 */ { 3, s_19_5, -1, -1, 0} +}; + +static const symbol s_20_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_20_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_20_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_20_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_20_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_20_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_20_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_20_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_20[8] = +{ +/* 0 */ { 3, s_20_0, -1, -1, 0}, +/* 1 */ { 3, s_20_1, -1, -1, 0}, +/* 2 */ { 3, s_20_2, -1, -1, 0}, +/* 3 */ { 3, s_20_3, -1, -1, 0}, +/* 4 */ { 3, s_20_4, -1, -1, 0}, +/* 5 */ { 3, s_20_5, -1, -1, 0}, +/* 6 */ { 3, s_20_6, -1, -1, 0}, +/* 7 */ { 3, s_20_7, -1, -1, 0} +}; + +static const symbol s_21_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_21_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_21_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_21_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_21_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_21_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_21_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_21_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_21[8] = +{ +/* 0 */ { 3, s_21_0, -1, -1, 0}, +/* 1 */ { 3, s_21_1, -1, -1, 0}, +/* 2 */ { 3, s_21_2, -1, -1, 0}, +/* 3 */ { 3, s_21_3, -1, -1, 0}, +/* 4 */ { 3, s_21_4, -1, -1, 0}, +/* 5 */ { 3, s_21_5, -1, -1, 0}, +/* 6 */ { 3, s_21_6, -1, -1, 0}, +/* 7 */ { 3, s_21_7, -1, -1, 0} +}; + +static const symbol s_22_0[9] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_22_1[24] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8A, 0xE0, 0xAE, 0xA3, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; + +static const struct among a_22[2] = +{ +/* 0 */ { 9, s_22_0, -1, -1, 0}, +/* 1 */ { 24, s_22_1, -1, -1, 0} +}; + +static const symbol s_23_0[3] = { 0xE0, 0xAE, 0x85 }; +static const symbol s_23_1[3] = { 0xE0, 0xAE, 0x86 }; +static const symbol s_23_2[3] = { 0xE0, 0xAE, 0x87 }; +static const symbol s_23_3[3] = { 0xE0, 0xAE, 0x88 }; +static const symbol s_23_4[3] = { 0xE0, 0xAE, 0x89 }; +static const symbol s_23_5[3] = { 0xE0, 0xAE, 0x8A }; +static const symbol s_23_6[3] = { 0xE0, 0xAE, 0x8E }; +static const symbol s_23_7[3] = { 0xE0, 0xAE, 0x8F }; +static const symbol s_23_8[3] = { 0xE0, 0xAE, 0x90 }; +static const symbol s_23_9[3] = { 0xE0, 0xAE, 0x92 }; +static const symbol s_23_10[3] = { 0xE0, 0xAE, 0x93 }; +static const symbol s_23_11[3] = { 0xE0, 0xAE, 0x94 }; + +static const struct among a_23[12] = +{ +/* 0 */ { 3, s_23_0, -1, -1, 0}, +/* 1 */ { 3, s_23_1, -1, -1, 0}, +/* 2 */ { 3, s_23_2, -1, -1, 0}, +/* 3 */ { 3, s_23_3, -1, -1, 0}, +/* 4 */ { 3, s_23_4, -1, -1, 0}, +/* 5 */ { 3, s_23_5, -1, -1, 0}, +/* 6 */ { 3, s_23_6, -1, -1, 0}, +/* 7 */ { 3, s_23_7, -1, -1, 0}, +/* 8 */ { 3, s_23_8, -1, -1, 0}, +/* 9 */ { 3, s_23_9, -1, -1, 0}, +/* 10 */ { 3, s_23_10, -1, -1, 0}, +/* 11 */ { 3, s_23_11, -1, -1, 0} +}; + +static const symbol s_24_0[3] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_24_1[3] = { 0xE0, 0xAF, 0x81 }; +static const symbol s_24_2[3] = { 0xE0, 0xAF, 0x82 }; +static const symbol s_24_3[3] = { 0xE0, 0xAF, 0x86 }; +static const symbol s_24_4[3] = { 0xE0, 0xAF, 0x87 }; +static const symbol s_24_5[3] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_24_6[3] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_24_7[3] = { 0xE0, 0xAE, 0xBF }; + +static const struct among a_24[8] = +{ +/* 0 */ { 3, s_24_0, -1, -1, 0}, +/* 1 */ { 3, s_24_1, -1, -1, 0}, +/* 2 */ { 3, s_24_2, -1, -1, 0}, +/* 3 */ { 3, s_24_3, -1, -1, 0}, +/* 4 */ { 3, s_24_4, -1, -1, 0}, +/* 5 */ { 3, s_24_5, -1, -1, 0}, +/* 6 */ { 3, s_24_6, -1, -1, 0}, +/* 7 */ { 3, s_24_7, -1, -1, 0} +}; + +static const symbol s_25_0[18] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_25_1[21] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA8, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_25_2[12] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_25_3[15] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1 }; +static const symbol s_25_4[18] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA8, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1 }; +static const symbol s_25_5[9] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB1 }; + +static const struct among a_25[6] = +{ +/* 0 */ { 18, s_25_0, -1, -1, 0}, +/* 1 */ { 21, s_25_1, -1, -1, 0}, +/* 2 */ { 12, s_25_2, -1, -1, 0}, +/* 3 */ { 15, s_25_3, -1, -1, 0}, +/* 4 */ { 18, s_25_4, -1, -1, 0}, +/* 5 */ { 9, s_25_5, -1, -1, 0} +}; + +static const symbol s_0[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8B }; +static const symbol s_1[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8B }; +static const symbol s_2[] = { 0xE0, 0xAE, 0x93 }; +static const symbol s_3[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8A }; +static const symbol s_4[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x8A }; +static const symbol s_5[] = { 0xE0, 0xAE, 0x92 }; +static const symbol s_6[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x81 }; +static const symbol s_7[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x81 }; +static const symbol s_8[] = { 0xE0, 0xAE, 0x89 }; +static const symbol s_9[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x82 }; +static const symbol s_10[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x82 }; +static const symbol s_11[] = { 0xE0, 0xAE, 0x8A }; +static const symbol s_12[] = { 0xE0, 0xAE, 0x8E }; +static const symbol s_13[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_14[] = { 0xE0, 0xAE, 0xAF, 0xE0, 0xAF, 0x8D }; +static const symbol s_15[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xAA, 0xE0, 0xAF, 0x8D }; +static const symbol s_16[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D }; +static const symbol s_17[] = { 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_18[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_19[] = { 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_20[] = { 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D }; +static const symbol s_21[] = { 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_22[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D }; +static const symbol s_23[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_24[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x8D }; +static const symbol s_25[] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_26[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_27[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D }; +static const symbol s_28[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D }; +static const symbol s_29[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_30[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_31[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_32[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x8D }; +static const symbol s_33[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_34[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_35[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_36[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_37[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_38[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x81 }; +static const symbol s_39[] = { 0xE0, 0xAE, 0x99, 0xE0, 0xAF, 0x8D }; +static const symbol s_40[] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_41[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_42[] = { 0xE0, 0xAE, 0x99, 0xE0, 0xAF, 0x8D }; +static const symbol s_43[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_44[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_45[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_46[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x99, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_47[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_48[] = { 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_49[] = { 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_50[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_51[] = { 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_52[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_53[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_54[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_55[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_56[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_57[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x88 }; +static const symbol s_58[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_59[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAE, 0xBF }; +static const symbol s_60[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF }; +static const symbol s_61[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xAF }; +static const symbol s_62[] = { 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x81 }; +static const symbol s_63[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB3 }; +static const symbol s_64[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x88, 0xE0, 0xAE, 0xAF }; +static const symbol s_65[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x88 }; +static const symbol s_66[] = { 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_67[] = { 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB2 }; +static const symbol s_68[] = { 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xA9 }; +static const symbol s_69[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xBF }; +static const symbol s_70[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_71[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x88 }; +static const symbol s_72[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x88 }; +static const symbol s_73[] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_74[] = { 0xE0, 0xAF, 0x88 }; +static const symbol s_75[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_76[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_77[] = { 0xE0, 0xAF, 0x8A, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_78[] = { 0xE0, 0xAF, 0x8B, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81 }; +static const symbol s_79[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_80[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_81[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_82[] = { 0xE0, 0xAE, 0xAE }; +static const symbol s_83[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x81 }; +static const symbol s_84[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xA8, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; +static const symbol s_85[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0x9F }; +static const symbol s_86[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0x9F, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_87[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_88[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x88 }; +static const symbol s_89[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xAE, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_90[] = { 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_91[] = { 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_92[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_93[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAE, 0xA3, 0xE0, 0xAF, 0x8D }; +static const symbol s_94[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_95[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xB2, 0xE0, 0xAF, 0x8D }; +static const symbol s_96[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D }; +static const symbol s_97[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x80, 0xE0, 0xAE, 0xB4, 0xE0, 0xAF, 0x8D }; +static const symbol s_98[] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_99[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; +static const symbol s_100[] = { 0xE0, 0xAF, 0x80 }; +static const symbol s_101[] = { 0xE0, 0xAE, 0xBF }; +static const symbol s_102[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_103[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_104[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_105[] = { 0xE0, 0xAE, 0xAE, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_106[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_107[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_108[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_109[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_110[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_111[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_112[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_113[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_114[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_115[] = { 0xE0, 0xAE, 0xA9 }; +static const symbol s_116[] = { 0xE0, 0xAE, 0xAA }; +static const symbol s_117[] = { 0xE0, 0xAE, 0x95 }; +static const symbol s_118[] = { 0xE0, 0xAE, 0xA4 }; +static const symbol s_119[] = { 0xE0, 0xAE, 0xAF }; +static const symbol s_120[] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_121[] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_122[] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_123[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; +static const symbol s_124[] = { 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x8D, 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x81 }; +static const symbol s_125[] = { 0xE0, 0xAE, 0xAA, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_126[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_127[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_128[] = { 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_129[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_130[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_131[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x88 }; +static const symbol s_132[] = { 0xE0, 0xAE, 0xB5, 0xE0, 0xAF, 0x88 }; +static const symbol s_133[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_134[] = { 0xE0, 0xAE, 0x9A }; +static const symbol s_135[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB3, 0xE0, 0xAF, 0x8D }; +static const symbol s_136[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_137[] = { 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_138[] = { 0xE0, 0xAE, 0xBE }; +static const symbol s_139[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_140[] = { 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_141[] = { 0xE0, 0xAF, 0x87, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_142[] = { 0xE0, 0xAF, 0x8B, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_143[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_144[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_145[] = { 0xE0, 0xAE, 0x9F, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_146[] = { 0xE0, 0xAE, 0xB1, 0xE0, 0xAF, 0x81, 0xE0, 0xAE, 0xAE, 0xE0, 0xAF, 0x8D }; +static const symbol s_147[] = { 0xE0, 0xAE, 0xBE, 0xE0, 0xAE, 0xAF, 0xE0, 0xAF, 0x8D }; +static const symbol s_148[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x86, 0xE0, 0xAE, 0xA9, 0xE0, 0xAF, 0x8D }; +static const symbol s_149[] = { 0xE0, 0xAE, 0xA9, 0xE0, 0xAE, 0xBF, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_150[] = { 0xE0, 0xAF, 0x80, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_151[] = { 0xE0, 0xAF, 0x80, 0xE0, 0xAE, 0xAF, 0xE0, 0xAE, 0xB0, 0xE0, 0xAF, 0x8D }; +static const symbol s_152[] = { 0xE0, 0xAF, 0x8D }; +static const symbol s_153[] = { 0xE0, 0xAE, 0x95, 0xE0, 0xAF, 0x81 }; +static const symbol s_154[] = { 0xE0, 0xAE, 0xA4, 0xE0, 0xAF, 0x81 }; +static const symbol s_155[] = { 0xE0, 0xAF, 0x8D }; + +static int r_has_min_length(struct SN_env * z) { /* forwardmode */ + if (!(len_utf8(z->p) > 4)) return 0; /* $( > ), line 100 */ + return 1; +} + +static int r_fix_va_start(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* or, line 104 */ + { int c2 = z->c; /* and, line 104 */ + { int c3 = z->c; /* try, line 104 */ + if (!(eq_s(z, 6, s_0))) { z->c = c3; goto lab2; } /* literal, line 104 */ + lab2: + ; + } + z->c = c2; + z->bra = z->c; /* [, line 104 */ + } + if (!(eq_s(z, 6, s_1))) goto lab1; /* literal, line 104 */ + z->ket = z->c; /* ], line 104 */ + { int ret = slice_from_s(z, 3, s_2); /* <-, line 104 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = c1; + { int c4 = z->c; /* and, line 105 */ + { int c5 = z->c; /* try, line 105 */ + if (!(eq_s(z, 6, s_3))) { z->c = c5; goto lab4; } /* literal, line 105 */ + lab4: + ; + } + z->c = c4; + z->bra = z->c; /* [, line 105 */ + } + if (!(eq_s(z, 6, s_4))) goto lab3; /* literal, line 105 */ + z->ket = z->c; /* ], line 105 */ + { int ret = slice_from_s(z, 3, s_5); /* <-, line 105 */ + if (ret < 0) return ret; + } + goto lab0; + lab3: + z->c = c1; + { int c6 = z->c; /* and, line 106 */ + { int c7 = z->c; /* try, line 106 */ + if (!(eq_s(z, 6, s_6))) { z->c = c7; goto lab6; } /* literal, line 106 */ + lab6: + ; + } + z->c = c6; + z->bra = z->c; /* [, line 106 */ + } + if (!(eq_s(z, 6, s_7))) goto lab5; /* literal, line 106 */ + z->ket = z->c; /* ], line 106 */ + { int ret = slice_from_s(z, 3, s_8); /* <-, line 106 */ + if (ret < 0) return ret; + } + goto lab0; + lab5: + z->c = c1; + { int c8 = z->c; /* and, line 107 */ + { int c9 = z->c; /* try, line 107 */ + if (!(eq_s(z, 6, s_9))) { z->c = c9; goto lab7; } /* literal, line 107 */ + lab7: + ; + } + z->c = c8; + z->bra = z->c; /* [, line 107 */ + } + if (!(eq_s(z, 6, s_10))) return 0; /* literal, line 107 */ + z->ket = z->c; /* ], line 107 */ + { int ret = slice_from_s(z, 3, s_11); /* <-, line 107 */ + if (ret < 0) return ret; + } + } +lab0: + return 1; +} + +static int r_fix_endings(struct SN_env * z) { /* forwardmode */ + { int c1 = z->c; /* do, line 111 */ + while(1) { /* repeat, line 111 */ + int c2 = z->c; + { int ret = r_fix_ending(z); /* call fix_ending, line 111 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } + continue; + lab1: + z->c = c2; + break; + } + z->c = c1; + } + return 1; +} + +static int r_remove_question_prefixes(struct SN_env * z) { /* forwardmode */ + z->bra = z->c; /* [, line 115 */ + if (!(eq_s(z, 3, s_12))) return 0; /* literal, line 115 */ + if (!(find_among(z, a_0, 10))) return 0; /* among, line 115 */ + if (!(eq_s(z, 3, s_13))) return 0; /* literal, line 115 */ + z->ket = z->c; /* ], line 115 */ + { int ret = slice_del(z); /* delete, line 115 */ + if (ret < 0) return ret; + } + { int c1 = z->c; /* do, line 116 */ + { int ret = r_fix_va_start(z); /* call fix_va_start, line 116 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + return 1; +} + +static int r_fix_ending(struct SN_env * z) { /* forwardmode */ + if (!(len_utf8(z->p) > 3)) return 0; /* $( > ), line 121 */ + z->lb = z->c; z->c = z->l; /* backwards, line 122 */ + + { int m1 = z->l - z->c; (void)m1; /* or, line 124 */ + z->ket = z->c; /* [, line 123 */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 164)) goto lab1; /* among, line 123 */ + if (!(find_among_b(z, a_1, 3))) goto lab1; + z->bra = z->c; /* ], line 123 */ + { int ret = slice_del(z); /* delete, line 123 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 125 */ + if (!(eq_s_b(z, 6, s_14))) goto lab2; /* literal, line 125 */ + { int m_test2 = z->l - z->c; /* test, line 125 */ + if (!(find_among_b(z, a_2, 3))) goto lab2; /* among, line 125 */ + z->c = z->l - m_test2; + } + z->bra = z->c; /* ], line 125 */ + { int ret = slice_del(z); /* delete, line 125 */ + if (ret < 0) return ret; + } + goto lab0; + lab2: + z->c = z->l - m1; + z->ket = z->c; /* [, line 127 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 127 */ + if (!(eq_s_b(z, 12, s_15))) goto lab5; /* literal, line 127 */ + goto lab4; + lab5: + z->c = z->l - m3; + if (!(eq_s_b(z, 12, s_16))) goto lab3; /* literal, line 127 */ + } + lab4: + z->bra = z->c; /* ], line 127 */ + { int ret = slice_from_s(z, 6, s_17); /* <-, line 127 */ + if (ret < 0) return ret; + } + goto lab0; + lab3: + z->c = z->l - m1; + z->ket = z->c; /* [, line 129 */ + if (!(eq_s_b(z, 12, s_18))) goto lab6; /* literal, line 129 */ + z->bra = z->c; /* ], line 129 */ + { int ret = slice_from_s(z, 6, s_19); /* <-, line 129 */ + if (ret < 0) return ret; + } + goto lab0; + lab6: + z->c = z->l - m1; + z->ket = z->c; /* [, line 132 */ + if (!(eq_s_b(z, 12, s_20))) goto lab7; /* literal, line 132 */ + z->bra = z->c; /* ], line 132 */ + { int ret = slice_from_s(z, 6, s_21); /* <-, line 132 */ + if (ret < 0) return ret; + } + goto lab0; + lab7: + z->c = z->l - m1; + z->ket = z->c; /* [, line 134 */ + if (!(eq_s_b(z, 12, s_22))) goto lab8; /* literal, line 134 */ + z->bra = z->c; /* ], line 134 */ + { int ret = slice_from_s(z, 6, s_23); /* <-, line 134 */ + if (ret < 0) return ret; + } + goto lab0; + lab8: + z->c = z->l - m1; + if (!(z->B[1])) goto lab9; /* Boolean test found_vetrumai_urupu, line 136 */ + z->ket = z->c; /* [, line 136 */ + if (!(eq_s_b(z, 12, s_24))) goto lab9; /* literal, line 136 */ + { int m_test4 = z->l - z->c; /* test, line 136 */ + { int m5 = z->l - z->c; (void)m5; /* not, line 136 */ + if (!(eq_s_b(z, 3, s_25))) goto lab10; /* literal, line 136 */ + goto lab9; + lab10: + z->c = z->l - m5; + } + z->c = z->l - m_test4; + } + z->bra = z->c; /* ], line 136 */ + { int ret = slice_from_s(z, 6, s_26); /* <-, line 136 */ + if (ret < 0) return ret; + } + z->bra = z->c; /* ], line 136 */ + goto lab0; + lab9: + z->c = z->l - m1; + z->ket = z->c; /* [, line 138 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 138 */ + if (!(eq_s_b(z, 9, s_27))) goto lab13; /* literal, line 138 */ + goto lab12; + lab13: + z->c = z->l - m6; + if (!(eq_s_b(z, 15, s_28))) goto lab11; /* literal, line 138 */ + } + lab12: + z->bra = z->c; /* ], line 138 */ + { int ret = slice_from_s(z, 3, s_29); /* <-, line 138 */ + if (ret < 0) return ret; + } + goto lab0; + lab11: + z->c = z->l - m1; + z->ket = z->c; /* [, line 140 */ + if (!(eq_s_b(z, 3, s_30))) goto lab14; /* literal, line 140 */ + if (!(find_among_b(z, a_3, 6))) goto lab14; /* among, line 140 */ + if (!(eq_s_b(z, 3, s_31))) goto lab14; /* literal, line 140 */ + if (!(find_among_b(z, a_4, 6))) goto lab14; /* among, line 140 */ + z->bra = z->c; /* ], line 140 */ + { int ret = slice_del(z); /* delete, line 140 */ + if (ret < 0) return ret; + } + goto lab0; + lab14: + z->c = z->l - m1; + z->ket = z->c; /* [, line 142 */ + if (!(eq_s_b(z, 9, s_32))) goto lab15; /* literal, line 142 */ + z->bra = z->c; /* ], line 142 */ + { int ret = slice_from_s(z, 3, s_33); /* <-, line 142 */ + if (ret < 0) return ret; + } + goto lab0; + lab15: + z->c = z->l - m1; + z->ket = z->c; /* [, line 144 */ + if (!(eq_s_b(z, 3, s_34))) goto lab16; /* literal, line 144 */ + if (!(find_among_b(z, a_5, 6))) goto lab16; /* among, line 144 */ + z->bra = z->c; /* ], line 144 */ + { int ret = slice_del(z); /* delete, line 144 */ + if (ret < 0) return ret; + } + goto lab0; + lab16: + z->c = z->l - m1; + z->ket = z->c; /* [, line 146 */ + if (!(eq_s_b(z, 3, s_35))) goto lab17; /* literal, line 146 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 146 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 5 || !((4030464 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab19; /* among, line 146 */ + if (!(find_among_b(z, a_6, 6))) goto lab19; + goto lab18; + lab19: + z->c = z->l - m7; + if (!(find_among_b(z, a_7, 6))) goto lab17; /* among, line 146 */ + } + lab18: + if (!(eq_s_b(z, 3, s_36))) goto lab17; /* literal, line 146 */ + z->bra = z->c; /* ], line 146 */ + { int ret = slice_from_s(z, 3, s_37); /* <-, line 146 */ + if (ret < 0) return ret; + } + goto lab0; + lab17: + z->c = z->l - m1; + z->ket = z->c; /* [, line 148 */ + if (!(find_among_b(z, a_8, 3))) goto lab20; /* among, line 148 */ + z->bra = z->c; /* ], line 148 */ + { int ret = slice_del(z); /* delete, line 148 */ + if (ret < 0) return ret; + } + goto lab0; + lab20: + z->c = z->l - m1; + z->ket = z->c; /* [, line 150 */ + if (!(eq_s_b(z, 6, s_38))) goto lab21; /* literal, line 150 */ + { int m_test8 = z->l - z->c; /* test, line 150 */ + { int m9 = z->l - z->c; (void)m9; /* not, line 150 */ + if (!(find_among_b(z, a_9, 8))) goto lab22; /* among, line 150 */ + goto lab21; + lab22: + z->c = z->l - m9; + } + z->c = z->l - m_test8; + } + z->bra = z->c; /* ], line 150 */ + { int ret = slice_del(z); /* delete, line 150 */ + if (ret < 0) return ret; + } + goto lab0; + lab21: + z->c = z->l - m1; + z->ket = z->c; /* [, line 152 */ + if (!(eq_s_b(z, 6, s_39))) goto lab23; /* literal, line 152 */ + { int m_test10 = z->l - z->c; /* test, line 152 */ + { int m11 = z->l - z->c; (void)m11; /* not, line 152 */ + if (!(eq_s_b(z, 3, s_40))) goto lab24; /* literal, line 152 */ + goto lab23; + lab24: + z->c = z->l - m11; + } + z->c = z->l - m_test10; + } + z->bra = z->c; /* ], line 152 */ + { int ret = slice_from_s(z, 6, s_41); /* <-, line 152 */ + if (ret < 0) return ret; + } + goto lab0; + lab23: + z->c = z->l - m1; + z->ket = z->c; /* [, line 154 */ + if (!(eq_s_b(z, 6, s_42))) goto lab25; /* literal, line 154 */ + z->bra = z->c; /* ], line 154 */ + { int ret = slice_del(z); /* delete, line 154 */ + if (ret < 0) return ret; + } + goto lab0; + lab25: + z->c = z->l - m1; + z->ket = z->c; /* [, line 156 */ + if (!(eq_s_b(z, 3, s_43))) return 0; /* literal, line 156 */ + { int m_test12 = z->l - z->c; /* test, line 156 */ + { int m13 = z->l - z->c; (void)m13; /* or, line 156 */ + if (!(find_among_b(z, a_10, 8))) goto lab27; /* among, line 156 */ + goto lab26; + lab27: + z->c = z->l - m13; + if (!(eq_s_b(z, 3, s_44))) return 0; /* literal, line 156 */ + } + lab26: + z->c = z->l - m_test12; + } + z->bra = z->c; /* ], line 156 */ + { int ret = slice_del(z); /* delete, line 156 */ + if (ret < 0) return ret; + } + } +lab0: + z->c = z->lb; + return 1; +} + +static int r_remove_pronoun_prefixes(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 161 */ + z->bra = z->c; /* [, line 162 */ + if (z->c + 2 >= z->l || z->p[z->c + 2] >> 5 != 4 || !((672 >> (z->p[z->c + 2] & 0x1f)) & 1)) return 0; /* among, line 162 */ + if (!(find_among(z, a_11, 3))) return 0; + if (!(find_among(z, a_12, 10))) return 0; /* among, line 162 */ + if (!(eq_s(z, 3, s_45))) return 0; /* literal, line 162 */ + z->ket = z->c; /* ], line 162 */ + { int ret = slice_del(z); /* delete, line 162 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 163 */ + { int c1 = z->c; /* do, line 164 */ + { int ret = r_fix_va_start(z); /* call fix_va_start, line 164 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + return 1; +} + +static int r_remove_plural_suffix(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 168 */ + z->lb = z->c; z->c = z->l; /* backwards, line 169 */ + + { int m1 = z->l - z->c; (void)m1; /* or, line 170 */ + z->ket = z->c; /* [, line 170 */ + if (!(eq_s_b(z, 18, s_46))) goto lab1; /* literal, line 170 */ + { int m_test2 = z->l - z->c; /* test, line 170 */ + { int m3 = z->l - z->c; (void)m3; /* not, line 170 */ + if (!(find_among_b(z, a_13, 6))) goto lab2; /* among, line 170 */ + goto lab1; + lab2: + z->c = z->l - m3; + } + z->c = z->l - m_test2; + } + z->bra = z->c; /* ], line 170 */ + { int ret = slice_from_s(z, 3, s_47); /* <-, line 170 */ + if (ret < 0) return ret; + } + goto lab0; + lab1: + z->c = z->l - m1; + z->ket = z->c; /* [, line 171 */ + if (!(eq_s_b(z, 15, s_48))) goto lab3; /* literal, line 171 */ + z->bra = z->c; /* ], line 171 */ + { int ret = slice_from_s(z, 6, s_49); /* <-, line 171 */ + if (ret < 0) return ret; + } + goto lab0; + lab3: + z->c = z->l - m1; + z->ket = z->c; /* [, line 172 */ + if (!(eq_s_b(z, 15, s_50))) goto lab4; /* literal, line 172 */ + z->bra = z->c; /* ], line 172 */ + { int ret = slice_from_s(z, 6, s_51); /* <-, line 172 */ + if (ret < 0) return ret; + } + goto lab0; + lab4: + z->c = z->l - m1; + z->ket = z->c; /* [, line 173 */ + if (!(eq_s_b(z, 9, s_52))) return 0; /* literal, line 173 */ + z->bra = z->c; /* ], line 173 */ + { int ret = slice_del(z); /* delete, line 173 */ + if (ret < 0) return ret; + } + } +lab0: + z->B[0] = 1; /* set found_a_match, line 174 */ + z->c = z->lb; + return 1; +} + +static int r_remove_question_suffixes(struct SN_env * z) { /* forwardmode */ + { int ret = r_has_min_length(z); /* call has_min_length, line 179 */ + if (ret <= 0) return ret; + } + z->B[0] = 0; /* unset found_a_match, line 180 */ + z->lb = z->c; z->c = z->l; /* backwards, line 181 */ + + { int m1 = z->l - z->c; (void)m1; /* do, line 182 */ + z->ket = z->c; /* [, line 183 */ + if (!(find_among_b(z, a_14, 3))) goto lab0; /* among, line 183 */ + z->bra = z->c; /* ], line 183 */ + { int ret = slice_from_s(z, 3, s_53); /* <-, line 183 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 184 */ + lab0: + z->c = z->l - m1; + } + z->c = z->lb; + /* do, line 187 */ + { int ret = r_fix_endings(z); /* call fix_endings, line 187 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } +lab1: + return 1; +} + +static int r_remove_command_suffixes(struct SN_env * z) { /* forwardmode */ + { int ret = r_has_min_length(z); /* call has_min_length, line 191 */ + if (ret <= 0) return ret; + } + z->B[0] = 0; /* unset found_a_match, line 192 */ + z->lb = z->c; z->c = z->l; /* backwards, line 193 */ + + z->ket = z->c; /* [, line 194 */ + if (z->c - 5 <= z->lb || z->p[z->c - 1] != 191) return 0; /* among, line 194 */ + if (!(find_among_b(z, a_15, 2))) return 0; + z->bra = z->c; /* ], line 194 */ + { int ret = slice_del(z); /* delete, line 194 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 195 */ + z->c = z->lb; + return 1; +} + +static int r_remove_um(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 200 */ + { int ret = r_has_min_length(z); /* call has_min_length, line 201 */ + if (ret <= 0) return ret; + } + z->lb = z->c; z->c = z->l; /* backwards, line 202 */ + + z->ket = z->c; /* [, line 202 */ + if (!(eq_s_b(z, 9, s_54))) return 0; /* literal, line 202 */ + z->bra = z->c; /* ], line 202 */ + { int ret = slice_from_s(z, 3, s_55); /* <-, line 202 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 203 */ + z->c = z->lb; + { int c1 = z->c; /* do, line 205 */ + { int ret = r_fix_ending(z); /* call fix_ending, line 205 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + return 1; +} + +static int r_remove_common_word_endings(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 212 */ + { int ret = r_has_min_length(z); /* call has_min_length, line 213 */ + if (ret <= 0) return ret; + } + z->lb = z->c; z->c = z->l; /* backwards, line 214 */ + + { int m1 = z->l - z->c; (void)m1; /* or, line 231 */ + { int m_test2 = z->l - z->c; /* test, line 215 */ + z->ket = z->c; /* [, line 215 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 215 */ + if (!(eq_s_b(z, 12, s_56))) goto lab3; /* literal, line 215 */ + goto lab2; + lab3: + z->c = z->l - m3; + if (!(eq_s_b(z, 15, s_57))) goto lab4; /* literal, line 216 */ + goto lab2; + lab4: + z->c = z->l - m3; + if (!(eq_s_b(z, 12, s_58))) goto lab5; /* literal, line 217 */ + goto lab2; + lab5: + z->c = z->l - m3; + if (!(eq_s_b(z, 15, s_59))) goto lab6; /* literal, line 218 */ + goto lab2; + lab6: + z->c = z->l - m3; + if (!(eq_s_b(z, 9, s_60))) goto lab7; /* literal, line 219 */ + goto lab2; + lab7: + z->c = z->l - m3; + if (!(eq_s_b(z, 12, s_61))) goto lab8; /* literal, line 220 */ + goto lab2; + lab8: + z->c = z->l - m3; + if (!(eq_s_b(z, 15, s_62))) goto lab9; /* literal, line 221 */ + goto lab2; + lab9: + z->c = z->l - m3; + if (!(eq_s_b(z, 12, s_63))) goto lab10; /* literal, line 222 */ + goto lab2; + lab10: + z->c = z->l - m3; + if (!(eq_s_b(z, 12, s_64))) goto lab11; /* literal, line 223 */ + goto lab2; + lab11: + z->c = z->l - m3; + if (!(eq_s_b(z, 9, s_65))) goto lab12; /* literal, line 224 */ + goto lab2; + lab12: + z->c = z->l - m3; + if (!(eq_s_b(z, 15, s_66))) goto lab13; /* literal, line 225 */ + goto lab2; + lab13: + z->c = z->l - m3; + if (!(eq_s_b(z, 9, s_67))) goto lab14; /* literal, line 226 */ + { int m_test4 = z->l - z->c; /* test, line 226 */ + { int m5 = z->l - z->c; (void)m5; /* not, line 226 */ + if (!(find_among_b(z, a_16, 8))) goto lab15; /* among, line 226 */ + goto lab14; + lab15: + z->c = z->l - m5; + } + z->c = z->l - m_test4; + } + goto lab2; + lab14: + z->c = z->l - m3; + if (!(eq_s_b(z, 6, s_68))) goto lab16; /* literal, line 227 */ + goto lab2; + lab16: + z->c = z->l - m3; + if (!(eq_s_b(z, 9, s_69))) goto lab1; /* literal, line 228 */ + } + lab2: + z->bra = z->c; /* ], line 228 */ + { int ret = slice_from_s(z, 3, s_70); /* <-, line 228 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 229 */ + z->c = z->l - m_test2; + } + goto lab0; + lab1: + z->c = z->l - m1; + { int m_test6 = z->l - z->c; /* test, line 232 */ + z->ket = z->c; /* [, line 232 */ + if (!(find_among_b(z, a_17, 13))) return 0; /* among, line 232 */ + z->bra = z->c; /* ], line 245 */ + { int ret = slice_del(z); /* delete, line 245 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 246 */ + z->c = z->l - m_test6; + } + } +lab0: + z->c = z->lb; + /* do, line 249 */ + { int ret = r_fix_endings(z); /* call fix_endings, line 249 */ + if (ret == 0) goto lab17; + if (ret < 0) return ret; + } +lab17: + return 1; +} + +static int r_remove_vetrumai_urupukal(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 253 */ + z->B[1] = 0; /* unset found_vetrumai_urupu, line 254 */ + { int ret = r_has_min_length(z); /* call has_min_length, line 255 */ + if (ret <= 0) return ret; + } + z->lb = z->c; z->c = z->l; /* backwards, line 256 */ + + { int m1 = z->l - z->c; (void)m1; /* or, line 259 */ + { int m_test2 = z->l - z->c; /* test, line 258 */ + z->ket = z->c; /* [, line 258 */ + if (!(eq_s_b(z, 6, s_71))) goto lab1; /* literal, line 258 */ + z->bra = z->c; /* ], line 258 */ + { int ret = slice_del(z); /* delete, line 258 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test2; + } + goto lab0; + lab1: + z->c = z->l - m1; + { int m_test3 = z->l - z->c; /* test, line 260 */ + z->ket = z->c; /* [, line 260 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 261 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 260 */ + if (!(eq_s_b(z, 9, s_72))) goto lab6; /* literal, line 260 */ + goto lab5; + lab6: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_73))) goto lab4; /* literal, line 261 */ + } + lab5: + { int m_test6 = z->l - z->c; /* test, line 261 */ + { int m7 = z->l - z->c; (void)m7; /* not, line 261 */ + if (!(find_among_b(z, a_18, 6))) goto lab7; /* among, line 261 */ + goto lab4; + lab7: + z->c = z->l - m7; + } + z->c = z->l - m_test6; + } + goto lab3; + lab4: + z->c = z->l - m4; + if (!(eq_s_b(z, 3, s_74))) goto lab2; /* literal, line 262 */ + { int m_test8 = z->l - z->c; /* test, line 262 */ + if (!(find_among_b(z, a_19, 6))) goto lab2; /* among, line 262 */ + if (!(eq_s_b(z, 3, s_75))) goto lab2; /* literal, line 262 */ + z->c = z->l - m_test8; + } + } + lab3: + z->bra = z->c; /* ], line 263 */ + { int ret = slice_from_s(z, 3, s_76); /* <-, line 263 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test3; + } + goto lab0; + lab2: + z->c = z->l - m1; + { int m_test9 = z->l - z->c; /* test, line 266 */ + z->ket = z->c; /* [, line 266 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 267 */ + if (!(eq_s_b(z, 9, s_77))) goto lab10; /* literal, line 267 */ + goto lab9; + lab10: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_78))) goto lab11; /* literal, line 268 */ + goto lab9; + lab11: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_79))) goto lab12; /* literal, line 269 */ + goto lab9; + lab12: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_80))) goto lab13; /* literal, line 270 */ + goto lab9; + lab13: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_81))) goto lab14; /* literal, line 271 */ + { int m_test11 = z->l - z->c; /* test, line 271 */ + { int m12 = z->l - z->c; (void)m12; /* not, line 271 */ + if (!(eq_s_b(z, 3, s_82))) goto lab15; /* literal, line 271 */ + goto lab14; + lab15: + z->c = z->l - m12; + } + z->c = z->l - m_test11; + } + goto lab9; + lab14: + z->c = z->l - m10; + if (!(eq_s_b(z, 15, s_83))) goto lab16; /* literal, line 272 */ + goto lab9; + lab16: + z->c = z->l - m10; + if (!(eq_s_b(z, 21, s_84))) goto lab17; /* literal, line 273 */ + goto lab9; + lab17: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_85))) goto lab18; /* literal, line 274 */ + goto lab9; + lab18: + z->c = z->l - m10; + if (!(len_utf8(z->p) >= 7)) goto lab19; /* $( >= ), line 275 */ + if (!(eq_s_b(z, 12, s_86))) goto lab19; /* literal, line 275 */ + goto lab9; + lab19: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_87))) goto lab20; /* literal, line 276 */ + goto lab9; + lab20: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_88))) goto lab21; /* literal, line 277 */ + goto lab9; + lab21: + z->c = z->l - m10; + if (!(eq_s_b(z, 12, s_89))) goto lab22; /* literal, line 278 */ + goto lab9; + lab22: + z->c = z->l - m10; + if (!(eq_s_b(z, 6, s_90))) goto lab23; /* literal, line 279 */ + { int m_test13 = z->l - z->c; /* test, line 279 */ + { int m14 = z->l - z->c; (void)m14; /* not, line 279 */ + if (!(find_among_b(z, a_20, 8))) goto lab24; /* among, line 279 */ + goto lab23; + lab24: + z->c = z->l - m14; + } + z->c = z->l - m_test13; + } + goto lab9; + lab23: + z->c = z->l - m10; + if (!(eq_s_b(z, 9, s_91))) goto lab8; /* literal, line 280 */ + } + lab9: + z->bra = z->c; /* ], line 281 */ + { int ret = slice_from_s(z, 3, s_92); /* <-, line 281 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test9; + } + goto lab0; + lab8: + z->c = z->l - m1; + { int m_test15 = z->l - z->c; /* test, line 284 */ + z->ket = z->c; /* [, line 284 */ + { int m16 = z->l - z->c; (void)m16; /* or, line 285 */ + if (!(eq_s_b(z, 9, s_93))) goto lab27; /* literal, line 285 */ + goto lab26; + lab27: + z->c = z->l - m16; + if (!(eq_s_b(z, 12, s_94))) goto lab28; /* literal, line 286 */ + goto lab26; + lab28: + z->c = z->l - m16; + if (!(eq_s_b(z, 12, s_95))) goto lab29; /* literal, line 287 */ + goto lab26; + lab29: + z->c = z->l - m16; + if (!(eq_s_b(z, 12, s_96))) goto lab30; /* literal, line 288 */ + goto lab26; + lab30: + z->c = z->l - m16; + if (!(eq_s_b(z, 12, s_97))) goto lab31; /* literal, line 289 */ + goto lab26; + lab31: + z->c = z->l - m16; + if (!(eq_s_b(z, 12, s_98))) goto lab32; /* literal, line 290 */ + goto lab26; + lab32: + z->c = z->l - m16; + if (!(eq_s_b(z, 6, s_99))) goto lab25; /* literal, line 291 */ + { int m_test17 = z->l - z->c; /* test, line 291 */ + { int m18 = z->l - z->c; (void)m18; /* not, line 291 */ + if (!(find_among_b(z, a_21, 8))) goto lab33; /* among, line 291 */ + goto lab25; + lab33: + z->c = z->l - m18; + } + z->c = z->l - m_test17; + } + } + lab26: + z->bra = z->c; /* ], line 292 */ + { int ret = slice_del(z); /* delete, line 292 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test15; + } + goto lab0; + lab25: + z->c = z->l - m1; + { int m_test19 = z->l - z->c; /* test, line 295 */ + z->ket = z->c; /* [, line 295 */ + if (!(eq_s_b(z, 3, s_100))) return 0; /* literal, line 295 */ + z->bra = z->c; /* ], line 295 */ + { int ret = slice_from_s(z, 3, s_101); /* <-, line 295 */ + if (ret < 0) return ret; + } + z->c = z->l - m_test19; + } + } +lab0: + z->B[0] = 1; /* set found_a_match, line 297 */ + z->B[1] = 1; /* set found_vetrumai_urupu, line 298 */ + { int m20 = z->l - z->c; (void)m20; /* do, line 299 */ + z->ket = z->c; /* [, line 299 */ + if (!(eq_s_b(z, 9, s_102))) goto lab34; /* literal, line 299 */ + z->bra = z->c; /* ], line 299 */ + { int ret = slice_from_s(z, 3, s_103); /* <-, line 299 */ + if (ret < 0) return ret; + } + lab34: + z->c = z->l - m20; + } + z->c = z->lb; + /* do, line 301 */ + { int ret = r_fix_endings(z); /* call fix_endings, line 301 */ + if (ret == 0) goto lab35; + if (ret < 0) return ret; + } +lab35: + return 1; +} + +static int r_remove_tense_suffixes(struct SN_env * z) { /* forwardmode */ + z->B[0] = 1; /* set found_a_match, line 305 */ + while(1) { /* repeat, line 306 */ + int c1 = z->c; + if (!(z->B[0])) goto lab0; /* Boolean test found_a_match, line 306 */ + { int c2 = z->c; /* do, line 306 */ + { int ret = r_remove_tense_suffix(z); /* call remove_tense_suffix, line 306 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } + lab1: + z->c = c2; + } + continue; + lab0: + z->c = c1; + break; + } + return 1; +} + +static int r_remove_tense_suffix(struct SN_env * z) { /* forwardmode */ + z->B[0] = 0; /* unset found_a_match, line 310 */ + { int ret = r_has_min_length(z); /* call has_min_length, line 311 */ + if (ret <= 0) return ret; + } + z->lb = z->c; z->c = z->l; /* backwards, line 312 */ + + { int m1 = z->l - z->c; (void)m1; /* do, line 313 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 320 */ + { int m_test3 = z->l - z->c; /* test, line 314 */ + z->ket = z->c; /* [, line 314 */ + if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 129 && z->p[z->c - 1] != 141)) goto lab2; /* among, line 314 */ + if (!(find_among_b(z, a_22, 2))) goto lab2; + z->bra = z->c; /* ], line 317 */ + { int ret = slice_del(z); /* delete, line 317 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 318 */ + z->c = z->l - m_test3; + } + goto lab1; + lab2: + z->c = z->l - m2; + { int m_test4 = z->l - z->c; /* test, line 321 */ + z->ket = z->c; /* [, line 321 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 322 */ + if (!(eq_s_b(z, 12, s_104))) goto lab5; /* literal, line 322 */ + goto lab4; + lab5: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_105))) goto lab6; /* literal, line 323 */ + goto lab4; + lab6: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_106))) goto lab7; /* literal, line 324 */ + goto lab4; + lab7: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_107))) goto lab8; /* literal, line 325 */ + goto lab4; + lab8: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_108))) goto lab9; /* literal, line 326 */ + goto lab4; + lab9: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_109))) goto lab10; /* literal, line 327 */ + goto lab4; + lab10: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_110))) goto lab11; /* literal, line 328 */ + { int m_test6 = z->l - z->c; /* test, line 328 */ + { int m7 = z->l - z->c; (void)m7; /* not, line 328 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] >> 5 != 4 || !((1951712 >> (z->p[z->c - 1] & 0x1f)) & 1)) goto lab12; /* among, line 328 */ + if (!(find_among_b(z, a_23, 12))) goto lab12; + goto lab11; + lab12: + z->c = z->l - m7; + } + z->c = z->l - m_test6; + } + goto lab4; + lab11: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_111))) goto lab13; /* literal, line 329 */ + goto lab4; + lab13: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_112))) goto lab14; /* literal, line 330 */ + goto lab4; + lab14: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_113))) goto lab15; /* literal, line 331 */ + goto lab4; + lab15: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_114))) goto lab16; /* literal, line 332 */ + goto lab4; + lab16: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_115))) goto lab17; /* literal, line 333 */ + goto lab4; + lab17: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_116))) goto lab18; /* literal, line 333 */ + goto lab4; + lab18: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_117))) goto lab19; /* literal, line 333 */ + goto lab4; + lab19: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_118))) goto lab20; /* literal, line 333 */ + goto lab4; + lab20: + z->c = z->l - m5; + if (!(eq_s_b(z, 3, s_119))) goto lab21; /* literal, line 333 */ + goto lab4; + lab21: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_120))) goto lab22; /* literal, line 334 */ + goto lab4; + lab22: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_121))) goto lab23; /* literal, line 335 */ + goto lab4; + lab23: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_122))) goto lab24; /* literal, line 336 */ + goto lab4; + lab24: + z->c = z->l - m5; + if (!(eq_s_b(z, 6, s_123))) goto lab25; /* literal, line 337 */ + { int m_test8 = z->l - z->c; /* test, line 337 */ + { int m9 = z->l - z->c; (void)m9; /* not, line 337 */ + if (!(find_among_b(z, a_24, 8))) goto lab26; /* among, line 337 */ + goto lab25; + lab26: + z->c = z->l - m9; + } + z->c = z->l - m_test8; + } + goto lab4; + lab25: + z->c = z->l - m5; + if (!(eq_s_b(z, 15, s_124))) goto lab27; /* literal, line 338 */ + goto lab4; + lab27: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_125))) goto lab28; /* literal, line 339 */ + goto lab4; + lab28: + z->c = z->l - m5; + if (!(eq_s_b(z, 9, s_126))) goto lab29; /* literal, line 340 */ + goto lab4; + lab29: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_127))) goto lab30; /* literal, line 341 */ + goto lab4; + lab30: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_128))) goto lab31; /* literal, line 342 */ + goto lab4; + lab31: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_129))) goto lab32; /* literal, line 343 */ + goto lab4; + lab32: + z->c = z->l - m5; + if (!(eq_s_b(z, 12, s_130))) goto lab33; /* literal, line 344 */ + goto lab4; + lab33: + z->c = z->l - m5; + if (!(eq_s_b(z, 6, s_131))) goto lab34; /* literal, line 345 */ + goto lab4; + lab34: + z->c = z->l - m5; + if (!(eq_s_b(z, 6, s_132))) goto lab3; /* literal, line 346 */ + } + lab4: + z->bra = z->c; /* ], line 347 */ + { int ret = slice_del(z); /* delete, line 347 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 348 */ + z->c = z->l - m_test4; + } + goto lab1; + lab3: + z->c = z->l - m2; + { int m_test10 = z->l - z->c; /* test, line 351 */ + z->ket = z->c; /* [, line 351 */ + { int m11 = z->l - z->c; (void)m11; /* or, line 352 */ + if (!(eq_s_b(z, 9, s_133))) goto lab37; /* literal, line 352 */ + { int m_test12 = z->l - z->c; /* test, line 352 */ + { int m13 = z->l - z->c; (void)m13; /* not, line 352 */ + if (!(eq_s_b(z, 3, s_134))) goto lab38; /* literal, line 352 */ + goto lab37; + lab38: + z->c = z->l - m13; + } + z->c = z->l - m_test12; + } + goto lab36; + lab37: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_135))) goto lab39; /* literal, line 353 */ + goto lab36; + lab39: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_136))) goto lab40; /* literal, line 354 */ + goto lab36; + lab40: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_137))) goto lab41; /* literal, line 355 */ + goto lab36; + lab41: + z->c = z->l - m11; + if (!(eq_s_b(z, 3, s_138))) goto lab42; /* literal, line 356 */ + goto lab36; + lab42: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_139))) goto lab43; /* literal, line 357 */ + goto lab36; + lab43: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_140))) goto lab44; /* literal, line 358 */ + goto lab36; + lab44: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_141))) goto lab45; /* literal, line 359 */ + goto lab36; + lab45: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_142))) goto lab46; /* literal, line 360 */ + goto lab36; + lab46: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_143))) goto lab47; /* literal, line 361 */ + goto lab36; + lab47: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_144))) goto lab48; /* literal, line 362 */ + goto lab36; + lab48: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_145))) goto lab49; /* literal, line 363 */ + goto lab36; + lab49: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_146))) goto lab50; /* literal, line 364 */ + goto lab36; + lab50: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_147))) goto lab51; /* literal, line 365 */ + goto lab36; + lab51: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_148))) goto lab52; /* literal, line 366 */ + goto lab36; + lab52: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_149))) goto lab53; /* literal, line 367 */ + goto lab36; + lab53: + z->c = z->l - m11; + if (!(eq_s_b(z, 9, s_150))) goto lab54; /* literal, line 368 */ + goto lab36; + lab54: + z->c = z->l - m11; + if (!(eq_s_b(z, 12, s_151))) goto lab35; /* literal, line 369 */ + } + lab36: + z->bra = z->c; /* ], line 370 */ + { int ret = slice_from_s(z, 3, s_152); /* <-, line 370 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 371 */ + z->c = z->l - m_test10; + } + goto lab1; + lab35: + z->c = z->l - m2; + { int m_test14 = z->l - z->c; /* test, line 374 */ + z->ket = z->c; /* [, line 374 */ + { int m15 = z->l - z->c; (void)m15; /* or, line 374 */ + if (!(eq_s_b(z, 6, s_153))) goto lab56; /* literal, line 374 */ + goto lab55; + lab56: + z->c = z->l - m15; + if (!(eq_s_b(z, 6, s_154))) goto lab0; /* literal, line 374 */ + } + lab55: + { int m_test16 = z->l - z->c; /* test, line 374 */ + if (!(eq_s_b(z, 3, s_155))) goto lab0; /* literal, line 374 */ + z->c = z->l - m_test16; + } + z->bra = z->c; /* ], line 374 */ + { int ret = slice_del(z); /* delete, line 374 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 375 */ + z->c = z->l - m_test14; + } + } + lab1: + lab0: + z->c = z->l - m1; + } + { int m17 = z->l - z->c; (void)m17; /* do, line 378 */ + z->ket = z->c; /* [, line 378 */ + if (z->c - 8 <= z->lb || (z->p[z->c - 1] != 141 && z->p[z->c - 1] != 177)) goto lab57; /* among, line 378 */ + if (!(find_among_b(z, a_25, 6))) goto lab57; + z->bra = z->c; /* ], line 385 */ + { int ret = slice_del(z); /* delete, line 385 */ + if (ret < 0) return ret; + } + z->B[0] = 1; /* set found_a_match, line 386 */ + lab57: + z->c = z->l - m17; + } + z->c = z->lb; + /* do, line 389 */ + { int ret = r_fix_endings(z); /* call fix_endings, line 389 */ + if (ret == 0) goto lab58; + if (ret < 0) return ret; + } +lab58: + return 1; +} + +extern int tamil_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + z->B[1] = 0; /* unset found_vetrumai_urupu, line 393 */ + { int c1 = z->c; /* do, line 394 */ + { int ret = r_fix_ending(z); /* call fix_ending, line 394 */ + if (ret == 0) goto lab0; + if (ret < 0) return ret; + } + lab0: + z->c = c1; + } + { int ret = r_has_min_length(z); /* call has_min_length, line 395 */ + if (ret <= 0) return ret; + } + { int c2 = z->c; /* do, line 396 */ + { int ret = r_remove_question_prefixes(z); /* call remove_question_prefixes, line 396 */ + if (ret == 0) goto lab1; + if (ret < 0) return ret; + } + lab1: + z->c = c2; + } + { int c3 = z->c; /* do, line 397 */ + { int ret = r_remove_pronoun_prefixes(z); /* call remove_pronoun_prefixes, line 397 */ + if (ret == 0) goto lab2; + if (ret < 0) return ret; + } + lab2: + z->c = c3; + } + { int c4 = z->c; /* do, line 398 */ + { int ret = r_remove_question_suffixes(z); /* call remove_question_suffixes, line 398 */ + if (ret == 0) goto lab3; + if (ret < 0) return ret; + } + lab3: + z->c = c4; + } + { int c5 = z->c; /* do, line 399 */ + { int ret = r_remove_um(z); /* call remove_um, line 399 */ + if (ret == 0) goto lab4; + if (ret < 0) return ret; + } + lab4: + z->c = c5; + } + { int c6 = z->c; /* do, line 400 */ + { int ret = r_remove_common_word_endings(z); /* call remove_common_word_endings, line 400 */ + if (ret == 0) goto lab5; + if (ret < 0) return ret; + } + lab5: + z->c = c6; + } + { int c7 = z->c; /* do, line 401 */ + { int ret = r_remove_vetrumai_urupukal(z); /* call remove_vetrumai_urupukal, line 401 */ + if (ret == 0) goto lab6; + if (ret < 0) return ret; + } + lab6: + z->c = c7; + } + { int c8 = z->c; /* do, line 402 */ + { int ret = r_remove_plural_suffix(z); /* call remove_plural_suffix, line 402 */ + if (ret == 0) goto lab7; + if (ret < 0) return ret; + } + lab7: + z->c = c8; + } + { int c9 = z->c; /* do, line 403 */ + { int ret = r_remove_command_suffixes(z); /* call remove_command_suffixes, line 403 */ + if (ret == 0) goto lab8; + if (ret < 0) return ret; + } + lab8: + z->c = c9; + } + { int c10 = z->c; /* do, line 404 */ + { int ret = r_remove_tense_suffixes(z); /* call remove_tense_suffixes, line 404 */ + if (ret == 0) goto lab9; + if (ret < 0) return ret; + } + lab9: + z->c = c10; + } + return 1; +} + +extern struct SN_env * tamil_UTF_8_create_env(void) { return SN_create_env(0, 0, 2); } + +extern void tamil_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } + diff --git a/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c index 587351d126f..85eee41ada9 100644 --- a/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c +++ b/src/backend/snowball/libstemmer/stem_UTF_8_turkish.c @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #include "header.h" @@ -438,575 +438,495 @@ static const unsigned char g_vowel5[] = { 65 }; static const unsigned char g_vowel6[] = { 65 }; -static const symbol s_0[] = { 'a' }; -static const symbol s_1[] = { 'e' }; -static const symbol s_2[] = { 0xC4, 0xB1 }; -static const symbol s_3[] = { 'i' }; -static const symbol s_4[] = { 'o' }; -static const symbol s_5[] = { 0xC3, 0xB6 }; -static const symbol s_6[] = { 'u' }; -static const symbol s_7[] = { 0xC3, 0xBC }; -static const symbol s_8[] = { 'n' }; -static const symbol s_9[] = { 'n' }; -static const symbol s_10[] = { 's' }; -static const symbol s_11[] = { 's' }; -static const symbol s_12[] = { 'y' }; -static const symbol s_13[] = { 'y' }; -static const symbol s_14[] = { 'k', 'i' }; -static const symbol s_15[] = { 'k', 'e', 'n' }; -static const symbol s_16[] = { 'p' }; -static const symbol s_17[] = { 0xC3, 0xA7 }; -static const symbol s_18[] = { 't' }; -static const symbol s_19[] = { 'k' }; -static const symbol s_20[] = { 'd' }; -static const symbol s_21[] = { 'g' }; -static const symbol s_22[] = { 'a' }; -static const symbol s_23[] = { 0xC4, 0xB1 }; -static const symbol s_24[] = { 0xC4, 0xB1 }; -static const symbol s_25[] = { 'e' }; -static const symbol s_26[] = { 'i' }; -static const symbol s_27[] = { 'i' }; -static const symbol s_28[] = { 'o' }; -static const symbol s_29[] = { 'u' }; -static const symbol s_30[] = { 'u' }; -static const symbol s_31[] = { 0xC3, 0xB6 }; -static const symbol s_32[] = { 0xC3, 0xBC }; -static const symbol s_33[] = { 0xC3, 0xBC }; -static const symbol s_34[] = { 'a', 'd' }; -static const symbol s_35[] = { 's', 'o', 'y', 'a', 'd' }; - -static int r_check_vowel_harmony(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 112 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 114 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 116 */ - if (!(eq_s_b(z, 1, s_0))) goto lab1; - if (out_grouping_b_U(z, g_vowel1, 97, 305, 1) < 0) goto lab1; /* goto */ /* grouping vowel1, line 116 */ +static const symbol s_0[] = { 0xC4, 0xB1 }; +static const symbol s_1[] = { 0xC3, 0xB6 }; +static const symbol s_2[] = { 0xC3, 0xBC }; +static const symbol s_3[] = { 'k', 'i' }; +static const symbol s_4[] = { 'k', 'e', 'n' }; +static const symbol s_5[] = { 'p' }; +static const symbol s_6[] = { 0xC3, 0xA7 }; +static const symbol s_7[] = { 't' }; +static const symbol s_8[] = { 'k' }; +static const symbol s_9[] = { 0xC4, 0xB1 }; +static const symbol s_10[] = { 0xC4, 0xB1 }; +static const symbol s_11[] = { 'i' }; +static const symbol s_12[] = { 'u' }; +static const symbol s_13[] = { 0xC3, 0xB6 }; +static const symbol s_14[] = { 0xC3, 0xBC }; +static const symbol s_15[] = { 0xC3, 0xBC }; +static const symbol s_16[] = { 'a', 'd' }; +static const symbol s_17[] = { 's', 'o', 'y' }; + +static int r_check_vowel_harmony(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 110 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 112 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 114 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab1; /* literal, line 114 */ + z->c--; + if (out_grouping_b_U(z, g_vowel1, 97, 305, 1) < 0) goto lab1; /* goto */ /* grouping vowel1, line 114 */ goto lab0; lab1: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_1))) goto lab2; - if (out_grouping_b_U(z, g_vowel2, 101, 252, 1) < 0) goto lab2; /* goto */ /* grouping vowel2, line 117 */ + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab2; /* literal, line 115 */ + z->c--; + if (out_grouping_b_U(z, g_vowel2, 101, 252, 1) < 0) goto lab2; /* goto */ /* grouping vowel2, line 115 */ goto lab0; lab2: - z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_2))) goto lab3; - if (out_grouping_b_U(z, g_vowel3, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel3, line 118 */ + z->c = z->l - m2; + if (!(eq_s_b(z, 2, s_0))) goto lab3; /* literal, line 116 */ + if (out_grouping_b_U(z, g_vowel3, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel3, line 116 */ goto lab0; lab3: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_3))) goto lab4; - if (out_grouping_b_U(z, g_vowel4, 101, 105, 1) < 0) goto lab4; /* goto */ /* grouping vowel4, line 119 */ + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab4; /* literal, line 117 */ + z->c--; + if (out_grouping_b_U(z, g_vowel4, 101, 105, 1) < 0) goto lab4; /* goto */ /* grouping vowel4, line 117 */ goto lab0; lab4: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_4))) goto lab5; - if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab5; /* goto */ /* grouping vowel5, line 120 */ + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab5; /* literal, line 118 */ + z->c--; + if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab5; /* goto */ /* grouping vowel5, line 118 */ goto lab0; lab5: - z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_5))) goto lab6; - if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) goto lab6; /* goto */ /* grouping vowel6, line 121 */ + z->c = z->l - m2; + if (!(eq_s_b(z, 2, s_1))) goto lab6; /* literal, line 119 */ + if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) goto lab6; /* goto */ /* grouping vowel6, line 119 */ goto lab0; lab6: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_6))) goto lab7; - if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab7; /* goto */ /* grouping vowel5, line 122 */ + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab7; /* literal, line 120 */ + z->c--; + if (out_grouping_b_U(z, g_vowel5, 111, 117, 1) < 0) goto lab7; /* goto */ /* grouping vowel5, line 120 */ goto lab0; lab7: - z->c = z->l - m1; - if (!(eq_s_b(z, 2, s_7))) return 0; - if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) return 0; /* goto */ /* grouping vowel6, line 123 */ + z->c = z->l - m2; + if (!(eq_s_b(z, 2, s_2))) return 0; /* literal, line 121 */ + if (out_grouping_b_U(z, g_vowel6, 246, 252, 1) < 0) return 0; /* goto */ /* grouping vowel6, line 121 */ } lab0: - z->c = z->l - m_test; + z->c = z->l - m_test1; } return 1; } -static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { - { int m1 = z->l - z->c; (void)m1; /* or, line 134 */ - { int m_test = z->l - z->c; /* test, line 133 */ - if (!(eq_s_b(z, 1, s_8))) goto lab1; - z->c = z->l - m_test; - } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) goto lab1; - z->c = ret; /* next, line 133 */ - } - { int m_test = z->l - z->c; /* test, line 133 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; - z->c = z->l - m_test; +static int r_mark_suffix_with_optional_n_consonant(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* or, line 132 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab1; /* literal, line 131 */ + z->c--; + { int m_test2 = z->l - z->c; /* test, line 131 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 131 */ + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 135 */ - { int m_test = z->l - z->c; /* test, line 135 */ - if (!(eq_s_b(z, 1, s_9))) goto lab2; - z->c = z->l - m_test; + { int m3 = z->l - z->c; (void)m3; /* not, line 133 */ + { int m_test4 = z->l - z->c; /* test, line 133 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'n') goto lab2; /* literal, line 133 */ + z->c--; + z->c = z->l - m_test4; } return 0; lab2: - z->c = z->l - m2; + z->c = z->l - m3; } - { int m_test = z->l - z->c; /* test, line 135 */ + { int m_test5 = z->l - z->c; /* test, line 133 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 135 */ - } - { int m_test = z->l - z->c; /* test, line 135 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; - z->c = z->l - m_test; + z->c = ret; /* next, line 133 */ } - z->c = z->l - m_test; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 133 */ + z->c = z->l - m_test5; } } lab0: return 1; } -static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { - { int m1 = z->l - z->c; (void)m1; /* or, line 145 */ - { int m_test = z->l - z->c; /* test, line 144 */ - if (!(eq_s_b(z, 1, s_10))) goto lab1; - z->c = z->l - m_test; - } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) goto lab1; - z->c = ret; /* next, line 144 */ - } - { int m_test = z->l - z->c; /* test, line 144 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; - z->c = z->l - m_test; +static int r_mark_suffix_with_optional_s_consonant(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* or, line 143 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab1; /* literal, line 142 */ + z->c--; + { int m_test2 = z->l - z->c; /* test, line 142 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 142 */ + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 146 */ - { int m_test = z->l - z->c; /* test, line 146 */ - if (!(eq_s_b(z, 1, s_11))) goto lab2; - z->c = z->l - m_test; + { int m3 = z->l - z->c; (void)m3; /* not, line 144 */ + { int m_test4 = z->l - z->c; /* test, line 144 */ + if (z->c <= z->lb || z->p[z->c - 1] != 's') goto lab2; /* literal, line 144 */ + z->c--; + z->c = z->l - m_test4; } return 0; lab2: - z->c = z->l - m2; + z->c = z->l - m3; } - { int m_test = z->l - z->c; /* test, line 146 */ + { int m_test5 = z->l - z->c; /* test, line 144 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 146 */ + z->c = ret; /* next, line 144 */ } - { int m_test = z->l - z->c; /* test, line 146 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; - z->c = z->l - m_test; - } - z->c = z->l - m_test; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 144 */ + z->c = z->l - m_test5; } } lab0: return 1; } -static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { - { int m1 = z->l - z->c; (void)m1; /* or, line 155 */ - { int m_test = z->l - z->c; /* test, line 154 */ - if (!(eq_s_b(z, 1, s_12))) goto lab1; - z->c = z->l - m_test; - } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) goto lab1; - z->c = ret; /* next, line 154 */ - } - { int m_test = z->l - z->c; /* test, line 154 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; - z->c = z->l - m_test; +static int r_mark_suffix_with_optional_y_consonant(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* or, line 153 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab1; /* literal, line 152 */ + z->c--; + { int m_test2 = z->l - z->c; /* test, line 152 */ + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* grouping vowel, line 152 */ + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 156 */ - { int m_test = z->l - z->c; /* test, line 156 */ - if (!(eq_s_b(z, 1, s_13))) goto lab2; - z->c = z->l - m_test; + { int m3 = z->l - z->c; (void)m3; /* not, line 154 */ + { int m_test4 = z->l - z->c; /* test, line 154 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'y') goto lab2; /* literal, line 154 */ + z->c--; + z->c = z->l - m_test4; } return 0; lab2: - z->c = z->l - m2; + z->c = z->l - m3; } - { int m_test = z->l - z->c; /* test, line 156 */ + { int m_test5 = z->l - z->c; /* test, line 154 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 156 */ - } - { int m_test = z->l - z->c; /* test, line 156 */ - if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; - z->c = z->l - m_test; + z->c = ret; /* next, line 154 */ } - z->c = z->l - m_test; + if (in_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* grouping vowel, line 154 */ + z->c = z->l - m_test5; } } lab0: return 1; } -static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) { - { int m1 = z->l - z->c; (void)m1; /* or, line 161 */ - { int m_test = z->l - z->c; /* test, line 160 */ - if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab1; - z->c = z->l - m_test; - } - { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); - if (ret < 0) goto lab1; - z->c = ret; /* next, line 160 */ - } - { int m_test = z->l - z->c; /* test, line 160 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; - z->c = z->l - m_test; +static int r_mark_suffix_with_optional_U_vowel(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* or, line 159 */ + if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab1; /* grouping U, line 158 */ + { int m_test2 = z->l - z->c; /* test, line 158 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) goto lab1; /* non vowel, line 158 */ + z->c = z->l - m_test2; } goto lab0; lab1: z->c = z->l - m1; - { int m2 = z->l - z->c; (void)m2; /* not, line 162 */ - { int m_test = z->l - z->c; /* test, line 162 */ - if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab2; - z->c = z->l - m_test; + { int m3 = z->l - z->c; (void)m3; /* not, line 160 */ + { int m_test4 = z->l - z->c; /* test, line 160 */ + if (in_grouping_b_U(z, g_U, 105, 305, 0)) goto lab2; /* grouping U, line 160 */ + z->c = z->l - m_test4; } return 0; lab2: - z->c = z->l - m2; + z->c = z->l - m3; } - { int m_test = z->l - z->c; /* test, line 162 */ + { int m_test5 = z->l - z->c; /* test, line 160 */ { int ret = skip_utf8(z->p, z->c, z->lb, 0, -1); if (ret < 0) return 0; - z->c = ret; /* next, line 162 */ - } - { int m_test = z->l - z->c; /* test, line 162 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; - z->c = z->l - m_test; + z->c = ret; /* next, line 160 */ } - z->c = z->l - m_test; + if (out_grouping_b_U(z, g_vowel, 97, 305, 0)) return 0; /* non vowel, line 160 */ + z->c = z->l - m_test5; } } lab0: return 1; } -static int r_mark_possessives(struct SN_env * z) { - if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((67133440 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_0, 10))) return 0; /* among, line 167 */ - { int ret = r_mark_suffix_with_optional_U_vowel(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_U_vowel, line 169 */ - if (ret < 0) return ret; +static int r_mark_possessives(struct SN_env * z) { /* backwardmode */ + if (z->c <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((67133440 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 165 */ + if (!(find_among_b(z, a_0, 10))) return 0; + { int ret = r_mark_suffix_with_optional_U_vowel(z); /* call mark_suffix_with_optional_U_vowel, line 167 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_sU(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 173 */ - if (ret < 0) return ret; +static int r_mark_sU(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 171 */ + if (ret <= 0) return ret; } - if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; - { int ret = r_mark_suffix_with_optional_s_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_s_consonant, line 175 */ - if (ret < 0) return ret; + if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; /* grouping U, line 172 */ + { int ret = r_mark_suffix_with_optional_s_consonant(z); /* call mark_suffix_with_optional_s_consonant, line 173 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_lArI(struct SN_env * z) { - if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 177)) return 0; - if (!(find_among_b(z, a_1, 2))) return 0; /* among, line 179 */ +static int r_mark_lArI(struct SN_env * z) { /* backwardmode */ + if (z->c - 3 <= z->lb || (z->p[z->c - 1] != 105 && z->p[z->c - 1] != 177)) return 0; /* among, line 177 */ + if (!(find_among_b(z, a_1, 2))) return 0; return 1; } -static int r_mark_yU(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 183 */ - if (ret < 0) return ret; +static int r_mark_yU(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 181 */ + if (ret <= 0) return ret; } - if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 185 */ - if (ret < 0) return ret; + if (in_grouping_b_U(z, g_U, 105, 305, 0)) return 0; /* grouping U, line 182 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 183 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_nU(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 189 */ - if (ret < 0) return ret; +static int r_mark_nU(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 187 */ + if (ret <= 0) return ret; } - if (!(find_among_b(z, a_2, 4))) return 0; /* among, line 190 */ + if (!(find_among_b(z, a_2, 4))) return 0; /* among, line 188 */ return 1; } -static int r_mark_nUn(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 194 */ - if (ret < 0) return ret; +static int r_mark_nUn(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 192 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 110) return 0; - if (!(find_among_b(z, a_3, 4))) return 0; /* among, line 195 */ - { int ret = r_mark_suffix_with_optional_n_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_n_consonant, line 196 */ - if (ret < 0) return ret; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 193 */ + if (!(find_among_b(z, a_3, 4))) return 0; + { int ret = r_mark_suffix_with_optional_n_consonant(z); /* call mark_suffix_with_optional_n_consonant, line 194 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_yA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 200 */ - if (ret < 0) return ret; +static int r_mark_yA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 198 */ + if (ret <= 0) return ret; } - if (z->c <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_4, 2))) return 0; /* among, line 201 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 202 */ - if (ret < 0) return ret; + if (z->c <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 199 */ + if (!(find_among_b(z, a_4, 2))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 200 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_nA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 206 */ - if (ret < 0) return ret; +static int r_mark_nA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 204 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_5, 2))) return 0; /* among, line 207 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 205 */ + if (!(find_among_b(z, a_5, 2))) return 0; return 1; } -static int r_mark_DA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 211 */ - if (ret < 0) return ret; +static int r_mark_DA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 209 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_6, 4))) return 0; /* among, line 212 */ + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 210 */ + if (!(find_among_b(z, a_6, 4))) return 0; return 1; } -static int r_mark_ndA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 216 */ - if (ret < 0) return ret; +static int r_mark_ndA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 214 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_7, 2))) return 0; /* among, line 217 */ + if (z->c - 2 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 215 */ + if (!(find_among_b(z, a_7, 2))) return 0; return 1; } -static int r_mark_DAn(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 221 */ - if (ret < 0) return ret; +static int r_mark_DAn(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 219 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; - if (!(find_among_b(z, a_8, 4))) return 0; /* among, line 222 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 220 */ + if (!(find_among_b(z, a_8, 4))) return 0; return 1; } -static int r_mark_ndAn(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 226 */ - if (ret < 0) return ret; +static int r_mark_ndAn(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 224 */ + if (ret <= 0) return ret; } - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 110) return 0; - if (!(find_among_b(z, a_9, 2))) return 0; /* among, line 227 */ + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 225 */ + if (!(find_among_b(z, a_9, 2))) return 0; return 1; } -static int r_mark_ylA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 231 */ - if (ret < 0) return ret; +static int r_mark_ylA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 229 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_10, 2))) return 0; /* among, line 232 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 233 */ - if (ret < 0) return ret; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 230 */ + if (!(find_among_b(z, a_10, 2))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 231 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_ki(struct SN_env * z) { - if (!(eq_s_b(z, 2, s_14))) return 0; +static int r_mark_ki(struct SN_env * z) { /* backwardmode */ + if (!(eq_s_b(z, 2, s_3))) return 0; /* literal, line 235 */ return 1; } -static int r_mark_ncA(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 241 */ - if (ret < 0) return ret; +static int r_mark_ncA(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 239 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_11, 2))) return 0; /* among, line 242 */ - { int ret = r_mark_suffix_with_optional_n_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_n_consonant, line 243 */ - if (ret < 0) return ret; + if (z->c - 1 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 240 */ + if (!(find_among_b(z, a_11, 2))) return 0; + { int ret = r_mark_suffix_with_optional_n_consonant(z); /* call mark_suffix_with_optional_n_consonant, line 241 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_yUm(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 247 */ - if (ret < 0) return ret; +static int r_mark_yUm(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 245 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 109) return 0; - if (!(find_among_b(z, a_12, 4))) return 0; /* among, line 248 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 249 */ - if (ret < 0) return ret; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 109) return 0; /* among, line 246 */ + if (!(find_among_b(z, a_12, 4))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 247 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_sUn(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 253 */ - if (ret < 0) return ret; +static int r_mark_sUn(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 251 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; - if (!(find_among_b(z, a_13, 4))) return 0; /* among, line 254 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 110) return 0; /* among, line 252 */ + if (!(find_among_b(z, a_13, 4))) return 0; return 1; } -static int r_mark_yUz(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 258 */ - if (ret < 0) return ret; +static int r_mark_yUz(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 256 */ + if (ret <= 0) return ret; } - if (z->c - 1 <= z->lb || z->p[z->c - 1] != 122) return 0; - if (!(find_among_b(z, a_14, 4))) return 0; /* among, line 259 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 260 */ - if (ret < 0) return ret; + if (z->c - 1 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 257 */ + if (!(find_among_b(z, a_14, 4))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 258 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_sUnUz(struct SN_env * z) { - if (z->c - 4 <= z->lb || z->p[z->c - 1] != 122) return 0; - if (!(find_among_b(z, a_15, 4))) return 0; /* among, line 264 */ +static int r_mark_sUnUz(struct SN_env * z) { /* backwardmode */ + if (z->c - 4 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 262 */ + if (!(find_among_b(z, a_15, 4))) return 0; return 1; } -static int r_mark_lAr(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 268 */ - if (ret < 0) return ret; +static int r_mark_lAr(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 266 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; - if (!(find_among_b(z, a_16, 2))) return 0; /* among, line 269 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; /* among, line 267 */ + if (!(find_among_b(z, a_16, 2))) return 0; return 1; } -static int r_mark_nUz(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 273 */ - if (ret < 0) return ret; +static int r_mark_nUz(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 271 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 122) return 0; - if (!(find_among_b(z, a_17, 4))) return 0; /* among, line 274 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 122) return 0; /* among, line 272 */ + if (!(find_among_b(z, a_17, 4))) return 0; return 1; } -static int r_mark_DUr(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 278 */ - if (ret < 0) return ret; +static int r_mark_DUr(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 276 */ + if (ret <= 0) return ret; } - if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; - if (!(find_among_b(z, a_18, 8))) return 0; /* among, line 279 */ + if (z->c - 2 <= z->lb || z->p[z->c - 1] != 114) return 0; /* among, line 277 */ + if (!(find_among_b(z, a_18, 8))) return 0; return 1; } -static int r_mark_cAsInA(struct SN_env * z) { - if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; - if (!(find_among_b(z, a_19, 2))) return 0; /* among, line 283 */ +static int r_mark_cAsInA(struct SN_env * z) { /* backwardmode */ + if (z->c - 5 <= z->lb || (z->p[z->c - 1] != 97 && z->p[z->c - 1] != 101)) return 0; /* among, line 281 */ + if (!(find_among_b(z, a_19, 2))) return 0; return 1; } -static int r_mark_yDU(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 287 */ - if (ret < 0) return ret; +static int r_mark_yDU(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 285 */ + if (ret <= 0) return ret; } - if (!(find_among_b(z, a_20, 32))) return 0; /* among, line 288 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 292 */ - if (ret < 0) return ret; + if (!(find_among_b(z, a_20, 32))) return 0; /* among, line 286 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 290 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_ysA(struct SN_env * z) { - if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((26658 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; - if (!(find_among_b(z, a_21, 8))) return 0; /* among, line 297 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 298 */ - if (ret < 0) return ret; +static int r_mark_ysA(struct SN_env * z) { /* backwardmode */ + if (z->c - 1 <= z->lb || z->p[z->c - 1] >> 5 != 3 || !((26658 >> (z->p[z->c - 1] & 0x1f)) & 1)) return 0; /* among, line 295 */ + if (!(find_among_b(z, a_21, 8))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 296 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_ymUs_(struct SN_env * z) { - { int ret = r_check_vowel_harmony(z); - if (ret == 0) return 0; /* call check_vowel_harmony, line 302 */ - if (ret < 0) return ret; +static int r_mark_ymUs_(struct SN_env * z) { /* backwardmode */ + { int ret = r_check_vowel_harmony(z); /* call check_vowel_harmony, line 300 */ + if (ret <= 0) return ret; } - if (z->c - 3 <= z->lb || z->p[z->c - 1] != 159) return 0; - if (!(find_among_b(z, a_22, 4))) return 0; /* among, line 303 */ - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 304 */ - if (ret < 0) return ret; + if (z->c - 3 <= z->lb || z->p[z->c - 1] != 159) return 0; /* among, line 301 */ + if (!(find_among_b(z, a_22, 4))) return 0; + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 302 */ + if (ret <= 0) return ret; } return 1; } -static int r_mark_yken(struct SN_env * z) { - if (!(eq_s_b(z, 3, s_15))) return 0; - { int ret = r_mark_suffix_with_optional_y_consonant(z); - if (ret == 0) return 0; /* call mark_suffix_with_optional_y_consonant, line 308 */ - if (ret < 0) return ret; +static int r_mark_yken(struct SN_env * z) { /* backwardmode */ + if (!(eq_s_b(z, 3, s_4))) return 0; /* literal, line 306 */ + { int ret = r_mark_suffix_with_optional_y_consonant(z); /* call mark_suffix_with_optional_y_consonant, line 306 */ + if (ret <= 0) return ret; } return 1; } -static int r_stem_nominal_verb_suffixes(struct SN_env * z) { - z->ket = z->c; /* [, line 312 */ - z->B[0] = 1; /* set continue_stemming_noun_suffixes, line 313 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 315 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 314 */ - { int ret = r_mark_ymUs_(z); - if (ret == 0) goto lab3; /* call mark_ymUs_, line 314 */ +static int r_stem_nominal_verb_suffixes(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 310 */ + z->B[0] = 1; /* set continue_stemming_noun_suffixes, line 311 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 313 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 312 */ + { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 312 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } goto lab2; lab3: z->c = z->l - m2; - { int ret = r_mark_yDU(z); - if (ret == 0) goto lab4; /* call mark_yDU, line 314 */ + { int ret = r_mark_yDU(z); /* call mark_yDU, line 312 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } goto lab2; lab4: z->c = z->l - m2; - { int ret = r_mark_ysA(z); - if (ret == 0) goto lab5; /* call mark_ysA, line 314 */ + { int ret = r_mark_ysA(z); /* call mark_ysA, line 312 */ + if (ret == 0) goto lab5; if (ret < 0) return ret; } goto lab2; lab5: z->c = z->l - m2; - { int ret = r_mark_yken(z); - if (ret == 0) goto lab1; /* call mark_yken, line 314 */ + { int ret = r_mark_yken(z); /* call mark_yken, line 312 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } } @@ -1014,41 +934,41 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { goto lab0; lab1: z->c = z->l - m1; - { int ret = r_mark_cAsInA(z); - if (ret == 0) goto lab6; /* call mark_cAsInA, line 316 */ + { int ret = r_mark_cAsInA(z); /* call mark_cAsInA, line 314 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } - { int m3 = z->l - z->c; (void)m3; /* or, line 316 */ - { int ret = r_mark_sUnUz(z); - if (ret == 0) goto lab8; /* call mark_sUnUz, line 316 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 314 */ + { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 314 */ + if (ret == 0) goto lab8; if (ret < 0) return ret; } goto lab7; lab8: z->c = z->l - m3; - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab9; /* call mark_lAr, line 316 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 314 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab7; lab9: z->c = z->l - m3; - { int ret = r_mark_yUm(z); - if (ret == 0) goto lab10; /* call mark_yUm, line 316 */ + { int ret = r_mark_yUm(z); /* call mark_yUm, line 314 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } goto lab7; lab10: z->c = z->l - m3; - { int ret = r_mark_sUn(z); - if (ret == 0) goto lab11; /* call mark_sUn, line 316 */ + { int ret = r_mark_sUn(z); /* call mark_sUn, line 314 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } goto lab7; lab11: z->c = z->l - m3; - { int ret = r_mark_yUz(z); - if (ret == 0) goto lab12; /* call mark_yUz, line 316 */ + { int ret = r_mark_yUz(z); /* call mark_yUz, line 314 */ + if (ret == 0) goto lab12; if (ret < 0) return ret; } goto lab7; @@ -1056,47 +976,47 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { z->c = z->l - m3; } lab7: - { int ret = r_mark_ymUs_(z); - if (ret == 0) goto lab6; /* call mark_ymUs_, line 316 */ + { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 314 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } goto lab0; lab6: z->c = z->l - m1; - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab13; /* call mark_lAr, line 319 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 317 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 319 */ - { int ret = slice_del(z); /* delete, line 319 */ + z->bra = z->c; /* ], line 317 */ + { int ret = slice_del(z); /* delete, line 317 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 319 */ - z->ket = z->c; /* [, line 319 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 319 */ - { int ret = r_mark_DUr(z); - if (ret == 0) goto lab16; /* call mark_DUr, line 319 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 317 */ + z->ket = z->c; /* [, line 317 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 317 */ + { int ret = r_mark_DUr(z); /* call mark_DUr, line 317 */ + if (ret == 0) goto lab16; if (ret < 0) return ret; } goto lab15; lab16: - z->c = z->l - m4; - { int ret = r_mark_yDU(z); - if (ret == 0) goto lab17; /* call mark_yDU, line 319 */ + z->c = z->l - m5; + { int ret = r_mark_yDU(z); /* call mark_yDU, line 317 */ + if (ret == 0) goto lab17; if (ret < 0) return ret; } goto lab15; lab17: - z->c = z->l - m4; - { int ret = r_mark_ysA(z); - if (ret == 0) goto lab18; /* call mark_ysA, line 319 */ + z->c = z->l - m5; + { int ret = r_mark_ysA(z); /* call mark_ysA, line 317 */ + if (ret == 0) goto lab18; if (ret < 0) return ret; } goto lab15; lab18: - z->c = z->l - m4; - { int ret = r_mark_ymUs_(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call mark_ymUs_, line 319 */ + z->c = z->l - m5; + { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 317 */ + if (ret == 0) { z->c = z->l - m4; goto lab14; } if (ret < 0) return ret; } } @@ -1104,24 +1024,24 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { lab14: ; } - z->B[0] = 0; /* unset continue_stemming_noun_suffixes, line 320 */ + z->B[0] = 0; /* unset continue_stemming_noun_suffixes, line 318 */ goto lab0; lab13: z->c = z->l - m1; - { int ret = r_mark_nUz(z); - if (ret == 0) goto lab19; /* call mark_nUz, line 323 */ + { int ret = r_mark_nUz(z); /* call mark_nUz, line 321 */ + if (ret == 0) goto lab19; if (ret < 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* or, line 323 */ - { int ret = r_mark_yDU(z); - if (ret == 0) goto lab21; /* call mark_yDU, line 323 */ + { int m6 = z->l - z->c; (void)m6; /* or, line 321 */ + { int ret = r_mark_yDU(z); /* call mark_yDU, line 321 */ + if (ret == 0) goto lab21; if (ret < 0) return ret; } goto lab20; lab21: - z->c = z->l - m5; - { int ret = r_mark_ysA(z); - if (ret == 0) goto lab19; /* call mark_ysA, line 323 */ + z->c = z->l - m6; + { int ret = r_mark_ysA(z); /* call mark_ysA, line 321 */ + if (ret == 0) goto lab19; if (ret < 0) return ret; } } @@ -1129,42 +1049,42 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { goto lab0; lab19: z->c = z->l - m1; - { int m6 = z->l - z->c; (void)m6; /* or, line 325 */ - { int ret = r_mark_sUnUz(z); - if (ret == 0) goto lab24; /* call mark_sUnUz, line 325 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 323 */ + { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 323 */ + if (ret == 0) goto lab24; if (ret < 0) return ret; } goto lab23; lab24: - z->c = z->l - m6; - { int ret = r_mark_yUz(z); - if (ret == 0) goto lab25; /* call mark_yUz, line 325 */ + z->c = z->l - m7; + { int ret = r_mark_yUz(z); /* call mark_yUz, line 323 */ + if (ret == 0) goto lab25; if (ret < 0) return ret; } goto lab23; lab25: - z->c = z->l - m6; - { int ret = r_mark_sUn(z); - if (ret == 0) goto lab26; /* call mark_sUn, line 325 */ + z->c = z->l - m7; + { int ret = r_mark_sUn(z); /* call mark_sUn, line 323 */ + if (ret == 0) goto lab26; if (ret < 0) return ret; } goto lab23; lab26: - z->c = z->l - m6; - { int ret = r_mark_yUm(z); - if (ret == 0) goto lab22; /* call mark_yUm, line 325 */ + z->c = z->l - m7; + { int ret = r_mark_yUm(z); /* call mark_yUm, line 323 */ + if (ret == 0) goto lab22; if (ret < 0) return ret; } } lab23: - z->bra = z->c; /* ], line 325 */ - { int ret = slice_del(z); /* delete, line 325 */ + z->bra = z->c; /* ], line 323 */ + { int ret = slice_del(z); /* delete, line 323 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 325 */ - z->ket = z->c; /* [, line 325 */ - { int ret = r_mark_ymUs_(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab27; } /* call mark_ymUs_, line 325 */ + { int m8 = z->l - z->c; (void)m8; /* try, line 323 */ + z->ket = z->c; /* [, line 323 */ + { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 323 */ + if (ret == 0) { z->c = z->l - m8; goto lab27; } if (ret < 0) return ret; } lab27: @@ -1173,56 +1093,55 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { goto lab0; lab22: z->c = z->l - m1; - { int ret = r_mark_DUr(z); - if (ret == 0) return 0; /* call mark_DUr, line 327 */ - if (ret < 0) return ret; + { int ret = r_mark_DUr(z); /* call mark_DUr, line 325 */ + if (ret <= 0) return ret; } - z->bra = z->c; /* ], line 327 */ - { int ret = slice_del(z); /* delete, line 327 */ + z->bra = z->c; /* ], line 325 */ + { int ret = slice_del(z); /* delete, line 325 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 327 */ - z->ket = z->c; /* [, line 327 */ - { int m7 = z->l - z->c; (void)m7; /* or, line 327 */ - { int ret = r_mark_sUnUz(z); - if (ret == 0) goto lab30; /* call mark_sUnUz, line 327 */ + { int m9 = z->l - z->c; (void)m9; /* try, line 325 */ + z->ket = z->c; /* [, line 325 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 325 */ + { int ret = r_mark_sUnUz(z); /* call mark_sUnUz, line 325 */ + if (ret == 0) goto lab30; if (ret < 0) return ret; } goto lab29; lab30: - z->c = z->l - m7; - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab31; /* call mark_lAr, line 327 */ + z->c = z->l - m10; + { int ret = r_mark_lAr(z); /* call mark_lAr, line 325 */ + if (ret == 0) goto lab31; if (ret < 0) return ret; } goto lab29; lab31: - z->c = z->l - m7; - { int ret = r_mark_yUm(z); - if (ret == 0) goto lab32; /* call mark_yUm, line 327 */ + z->c = z->l - m10; + { int ret = r_mark_yUm(z); /* call mark_yUm, line 325 */ + if (ret == 0) goto lab32; if (ret < 0) return ret; } goto lab29; lab32: - z->c = z->l - m7; - { int ret = r_mark_sUn(z); - if (ret == 0) goto lab33; /* call mark_sUn, line 327 */ + z->c = z->l - m10; + { int ret = r_mark_sUn(z); /* call mark_sUn, line 325 */ + if (ret == 0) goto lab33; if (ret < 0) return ret; } goto lab29; lab33: - z->c = z->l - m7; - { int ret = r_mark_yUz(z); - if (ret == 0) goto lab34; /* call mark_yUz, line 327 */ + z->c = z->l - m10; + { int ret = r_mark_yUz(z); /* call mark_yUz, line 325 */ + if (ret == 0) goto lab34; if (ret < 0) return ret; } goto lab29; lab34: - z->c = z->l - m7; + z->c = z->l - m10; } lab29: - { int ret = r_mark_ymUs_(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call mark_ymUs_, line 327 */ + { int ret = r_mark_ymUs_(z); /* call mark_ymUs_, line 325 */ + if (ret == 0) { z->c = z->l - m9; goto lab28; } if (ret < 0) return ret; } lab28: @@ -1230,42 +1149,41 @@ static int r_stem_nominal_verb_suffixes(struct SN_env * z) { } } lab0: - z->bra = z->c; /* ], line 328 */ - { int ret = slice_del(z); /* delete, line 328 */ + z->bra = z->c; /* ], line 326 */ + { int ret = slice_del(z); /* delete, line 326 */ if (ret < 0) return ret; } return 1; } -static int r_stem_suffix_chain_before_ki(struct SN_env * z) { - z->ket = z->c; /* [, line 333 */ - { int ret = r_mark_ki(z); - if (ret == 0) return 0; /* call mark_ki, line 334 */ - if (ret < 0) return ret; +static int r_stem_suffix_chain_before_ki(struct SN_env * z) { /* backwardmode */ + z->ket = z->c; /* [, line 331 */ + { int ret = r_mark_ki(z); /* call mark_ki, line 332 */ + if (ret <= 0) return ret; } - { int m1 = z->l - z->c; (void)m1; /* or, line 342 */ - { int ret = r_mark_DA(z); - if (ret == 0) goto lab1; /* call mark_DA, line 336 */ + { int m1 = z->l - z->c; (void)m1; /* or, line 340 */ + { int ret = r_mark_DA(z); /* call mark_DA, line 334 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 336 */ - { int ret = slice_del(z); /* delete, line 336 */ + z->bra = z->c; /* ], line 334 */ + { int ret = slice_del(z); /* delete, line 334 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 336 */ - z->ket = z->c; /* [, line 336 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 338 */ - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab4; /* call mark_lAr, line 337 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 334 */ + z->ket = z->c; /* [, line 334 */ + { int m3 = z->l - z->c; (void)m3; /* or, line 336 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 335 */ + if (ret == 0) goto lab4; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 337 */ - { int ret = slice_del(z); /* delete, line 337 */ + z->bra = z->c; /* ], line 335 */ + { int ret = slice_del(z); /* delete, line 335 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 337 */ - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab5; } /* call stem_suffix_chain_before_ki, line 337 */ + { int m4 = z->l - z->c; (void)m4; /* try, line 335 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 335 */ + if (ret == 0) { z->c = z->l - m4; goto lab5; } if (ret < 0) return ret; } lab5: @@ -1273,27 +1191,27 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { } goto lab3; lab4: - z->c = z->l - m2; - { int ret = r_mark_possessives(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call mark_possessives, line 339 */ + z->c = z->l - m3; + { int ret = r_mark_possessives(z); /* call mark_possessives, line 337 */ + if (ret == 0) { z->c = z->l - m2; goto lab2; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 339 */ - { int ret = slice_del(z); /* delete, line 339 */ + z->bra = z->c; /* ], line 337 */ + { int ret = slice_del(z); /* delete, line 337 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 339 */ - z->ket = z->c; /* [, line 339 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call mark_lAr, line 339 */ + { int m5 = z->l - z->c; (void)m5; /* try, line 337 */ + z->ket = z->c; /* [, line 337 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 337 */ + if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 339 */ - { int ret = slice_del(z); /* delete, line 339 */ + z->bra = z->c; /* ], line 337 */ + { int ret = slice_del(z); /* delete, line 337 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab6; } /* call stem_suffix_chain_before_ki, line 339 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 337 */ + if (ret == 0) { z->c = z->l - m5; goto lab6; } if (ret < 0) return ret; } lab6: @@ -1307,59 +1225,59 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { goto lab0; lab1: z->c = z->l - m1; - { int ret = r_mark_nUn(z); - if (ret == 0) goto lab7; /* call mark_nUn, line 343 */ + { int ret = r_mark_nUn(z); /* call mark_nUn, line 341 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 343 */ - { int ret = slice_del(z); /* delete, line 343 */ + z->bra = z->c; /* ], line 341 */ + { int ret = slice_del(z); /* delete, line 341 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 343 */ - z->ket = z->c; /* [, line 343 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 345 */ - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab10; /* call mark_lArI, line 344 */ + { int m6 = z->l - z->c; (void)m6; /* try, line 341 */ + z->ket = z->c; /* [, line 341 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 343 */ + { int ret = r_mark_lArI(z); /* call mark_lArI, line 342 */ + if (ret == 0) goto lab10; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 344 */ - { int ret = slice_del(z); /* delete, line 344 */ + z->bra = z->c; /* ], line 342 */ + { int ret = slice_del(z); /* delete, line 342 */ if (ret < 0) return ret; } goto lab9; lab10: - z->c = z->l - m3; - z->ket = z->c; /* [, line 346 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 346 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab13; /* call mark_possessives, line 346 */ + z->c = z->l - m7; + z->ket = z->c; /* [, line 344 */ + { int m8 = z->l - z->c; (void)m8; /* or, line 344 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 344 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } goto lab12; lab13: - z->c = z->l - m4; - { int ret = r_mark_sU(z); - if (ret == 0) goto lab11; /* call mark_sU, line 346 */ + z->c = z->l - m8; + { int ret = r_mark_sU(z); /* call mark_sU, line 344 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } } lab12: - z->bra = z->c; /* ], line 346 */ - { int ret = slice_del(z); /* delete, line 346 */ + z->bra = z->c; /* ], line 344 */ + { int ret = slice_del(z); /* delete, line 344 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 346 */ - z->ket = z->c; /* [, line 346 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call mark_lAr, line 346 */ + { int m9 = z->l - z->c; (void)m9; /* try, line 344 */ + z->ket = z->c; /* [, line 344 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 344 */ + if (ret == 0) { z->c = z->l - m9; goto lab14; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 346 */ - { int ret = slice_del(z); /* delete, line 346 */ + z->bra = z->c; /* ], line 344 */ + { int ret = slice_del(z); /* delete, line 344 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab14; } /* call stem_suffix_chain_before_ki, line 346 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 344 */ + if (ret == 0) { z->c = z->l - m9; goto lab14; } if (ret < 0) return ret; } lab14: @@ -1367,9 +1285,9 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { } goto lab9; lab11: - z->c = z->l - m3; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab8; } /* call stem_suffix_chain_before_ki, line 348 */ + z->c = z->l - m7; + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 346 */ + if (ret == 0) { z->c = z->l - m6; goto lab8; } if (ret < 0) return ret; } } @@ -1380,42 +1298,41 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { goto lab0; lab7: z->c = z->l - m1; - { int ret = r_mark_ndA(z); - if (ret == 0) return 0; /* call mark_ndA, line 351 */ - if (ret < 0) return ret; + { int ret = r_mark_ndA(z); /* call mark_ndA, line 349 */ + if (ret <= 0) return ret; } - { int m5 = z->l - z->c; (void)m5; /* or, line 353 */ - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab16; /* call mark_lArI, line 352 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 351 */ + { int ret = r_mark_lArI(z); /* call mark_lArI, line 350 */ + if (ret == 0) goto lab16; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 352 */ - { int ret = slice_del(z); /* delete, line 352 */ + z->bra = z->c; /* ], line 350 */ + { int ret = slice_del(z); /* delete, line 350 */ if (ret < 0) return ret; } goto lab15; lab16: - z->c = z->l - m5; - { int ret = r_mark_sU(z); - if (ret == 0) goto lab17; /* call mark_sU, line 354 */ + z->c = z->l - m10; + { int ret = r_mark_sU(z); /* call mark_sU, line 352 */ + if (ret == 0) goto lab17; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 354 */ - { int ret = slice_del(z); /* delete, line 354 */ + z->bra = z->c; /* ], line 352 */ + { int ret = slice_del(z); /* delete, line 352 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 354 */ - z->ket = z->c; /* [, line 354 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab18; } /* call mark_lAr, line 354 */ + { int m11 = z->l - z->c; (void)m11; /* try, line 352 */ + z->ket = z->c; /* [, line 352 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 352 */ + if (ret == 0) { z->c = z->l - m11; goto lab18; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 354 */ - { int ret = slice_del(z); /* delete, line 354 */ + z->bra = z->c; /* ], line 352 */ + { int ret = slice_del(z); /* delete, line 352 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab18; } /* call stem_suffix_chain_before_ki, line 354 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 352 */ + if (ret == 0) { z->c = z->l - m11; goto lab18; } if (ret < 0) return ret; } lab18: @@ -1423,10 +1340,9 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { } goto lab15; lab17: - z->c = z->l - m5; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) return 0; /* call stem_suffix_chain_before_ki, line 356 */ - if (ret < 0) return ret; + z->c = z->l - m10; + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 354 */ + if (ret <= 0) return ret; } } lab15: @@ -1436,20 +1352,20 @@ static int r_stem_suffix_chain_before_ki(struct SN_env * z) { return 1; } -static int r_stem_noun_suffixes(struct SN_env * z) { - { int m1 = z->l - z->c; (void)m1; /* or, line 363 */ - z->ket = z->c; /* [, line 362 */ - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab1; /* call mark_lAr, line 362 */ +static int r_stem_noun_suffixes(struct SN_env * z) { /* backwardmode */ + { int m1 = z->l - z->c; (void)m1; /* or, line 361 */ + z->ket = z->c; /* [, line 360 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 360 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 362 */ - { int ret = slice_del(z); /* delete, line 362 */ + z->bra = z->c; /* ], line 360 */ + { int ret = slice_del(z); /* delete, line 360 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 362 */ - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab2; } /* call stem_suffix_chain_before_ki, line 362 */ + { int m2 = z->l - z->c; (void)m2; /* try, line 360 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 360 */ + if (ret == 0) { z->c = z->l - m2; goto lab2; } if (ret < 0) return ret; } lab2: @@ -1458,60 +1374,60 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab1: z->c = z->l - m1; - z->ket = z->c; /* [, line 364 */ - { int ret = r_mark_ncA(z); - if (ret == 0) goto lab3; /* call mark_ncA, line 364 */ + z->ket = z->c; /* [, line 362 */ + { int ret = r_mark_ncA(z); /* call mark_ncA, line 362 */ + if (ret == 0) goto lab3; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 364 */ - { int ret = slice_del(z); /* delete, line 364 */ + z->bra = z->c; /* ], line 362 */ + { int ret = slice_del(z); /* delete, line 362 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 365 */ - { int m2 = z->l - z->c; (void)m2; /* or, line 367 */ - z->ket = z->c; /* [, line 366 */ - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab6; /* call mark_lArI, line 366 */ + { int m3 = z->l - z->c; (void)m3; /* try, line 363 */ + { int m4 = z->l - z->c; (void)m4; /* or, line 365 */ + z->ket = z->c; /* [, line 364 */ + { int ret = r_mark_lArI(z); /* call mark_lArI, line 364 */ + if (ret == 0) goto lab6; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 366 */ - { int ret = slice_del(z); /* delete, line 366 */ + z->bra = z->c; /* ], line 364 */ + { int ret = slice_del(z); /* delete, line 364 */ if (ret < 0) return ret; } goto lab5; lab6: - z->c = z->l - m2; - z->ket = z->c; /* [, line 368 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 368 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab9; /* call mark_possessives, line 368 */ + z->c = z->l - m4; + z->ket = z->c; /* [, line 366 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 366 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 366 */ + if (ret == 0) goto lab9; if (ret < 0) return ret; } goto lab8; lab9: - z->c = z->l - m3; - { int ret = r_mark_sU(z); - if (ret == 0) goto lab7; /* call mark_sU, line 368 */ + z->c = z->l - m5; + { int ret = r_mark_sU(z); /* call mark_sU, line 366 */ + if (ret == 0) goto lab7; if (ret < 0) return ret; } } lab8: - z->bra = z->c; /* ], line 368 */ - { int ret = slice_del(z); /* delete, line 368 */ + z->bra = z->c; /* ], line 366 */ + { int ret = slice_del(z); /* delete, line 366 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 368 */ - z->ket = z->c; /* [, line 368 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab10; } /* call mark_lAr, line 368 */ + { int m6 = z->l - z->c; (void)m6; /* try, line 366 */ + z->ket = z->c; /* [, line 366 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 366 */ + if (ret == 0) { z->c = z->l - m6; goto lab10; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 368 */ - { int ret = slice_del(z); /* delete, line 368 */ + z->bra = z->c; /* ], line 366 */ + { int ret = slice_del(z); /* delete, line 366 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab10; } /* call stem_suffix_chain_before_ki, line 368 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 366 */ + if (ret == 0) { z->c = z->l - m6; goto lab10; } if (ret < 0) return ret; } lab10: @@ -1519,18 +1435,18 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab5; lab7: - z->c = z->l - m2; - z->ket = z->c; /* [, line 370 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call mark_lAr, line 370 */ + z->c = z->l - m4; + z->ket = z->c; /* [, line 368 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 368 */ + if (ret == 0) { z->c = z->l - m3; goto lab4; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 370 */ - { int ret = slice_del(z); /* delete, line 370 */ + z->bra = z->c; /* ], line 368 */ + { int ret = slice_del(z); /* delete, line 368 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab4; } /* call stem_suffix_chain_before_ki, line 370 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 368 */ + if (ret == 0) { z->c = z->l - m3; goto lab4; } if (ret < 0) return ret; } } @@ -1541,53 +1457,53 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab3: z->c = z->l - m1; - z->ket = z->c; /* [, line 374 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 374 */ - { int ret = r_mark_ndA(z); - if (ret == 0) goto lab13; /* call mark_ndA, line 374 */ + z->ket = z->c; /* [, line 372 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 372 */ + { int ret = r_mark_ndA(z); /* call mark_ndA, line 372 */ + if (ret == 0) goto lab13; if (ret < 0) return ret; } goto lab12; lab13: - z->c = z->l - m4; - { int ret = r_mark_nA(z); - if (ret == 0) goto lab11; /* call mark_nA, line 374 */ + z->c = z->l - m7; + { int ret = r_mark_nA(z); /* call mark_nA, line 372 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } } lab12: - { int m5 = z->l - z->c; (void)m5; /* or, line 377 */ - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab15; /* call mark_lArI, line 376 */ + { int m8 = z->l - z->c; (void)m8; /* or, line 375 */ + { int ret = r_mark_lArI(z); /* call mark_lArI, line 374 */ + if (ret == 0) goto lab15; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 376 */ - { int ret = slice_del(z); /* delete, line 376 */ + z->bra = z->c; /* ], line 374 */ + { int ret = slice_del(z); /* delete, line 374 */ if (ret < 0) return ret; } goto lab14; lab15: - z->c = z->l - m5; - { int ret = r_mark_sU(z); - if (ret == 0) goto lab16; /* call mark_sU, line 378 */ + z->c = z->l - m8; + { int ret = r_mark_sU(z); /* call mark_sU, line 376 */ + if (ret == 0) goto lab16; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 378 */ - { int ret = slice_del(z); /* delete, line 378 */ + z->bra = z->c; /* ], line 376 */ + { int ret = slice_del(z); /* delete, line 376 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 378 */ - z->ket = z->c; /* [, line 378 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab17; } /* call mark_lAr, line 378 */ + { int m9 = z->l - z->c; (void)m9; /* try, line 376 */ + z->ket = z->c; /* [, line 376 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 376 */ + if (ret == 0) { z->c = z->l - m9; goto lab17; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 378 */ - { int ret = slice_del(z); /* delete, line 378 */ + z->bra = z->c; /* ], line 376 */ + { int ret = slice_del(z); /* delete, line 376 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab17; } /* call stem_suffix_chain_before_ki, line 378 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 376 */ + if (ret == 0) { z->c = z->l - m9; goto lab17; } if (ret < 0) return ret; } lab17: @@ -1595,9 +1511,9 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab14; lab16: - z->c = z->l - m5; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) goto lab11; /* call stem_suffix_chain_before_ki, line 380 */ + z->c = z->l - m8; + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 378 */ + if (ret == 0) goto lab11; if (ret < 0) return ret; } } @@ -1605,42 +1521,42 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab11: z->c = z->l - m1; - z->ket = z->c; /* [, line 384 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 384 */ - { int ret = r_mark_ndAn(z); - if (ret == 0) goto lab20; /* call mark_ndAn, line 384 */ + z->ket = z->c; /* [, line 382 */ + { int m10 = z->l - z->c; (void)m10; /* or, line 382 */ + { int ret = r_mark_ndAn(z); /* call mark_ndAn, line 382 */ + if (ret == 0) goto lab20; if (ret < 0) return ret; } goto lab19; lab20: - z->c = z->l - m6; - { int ret = r_mark_nU(z); - if (ret == 0) goto lab18; /* call mark_nU, line 384 */ + z->c = z->l - m10; + { int ret = r_mark_nU(z); /* call mark_nU, line 382 */ + if (ret == 0) goto lab18; if (ret < 0) return ret; } } lab19: - { int m7 = z->l - z->c; (void)m7; /* or, line 384 */ - { int ret = r_mark_sU(z); - if (ret == 0) goto lab22; /* call mark_sU, line 384 */ + { int m11 = z->l - z->c; (void)m11; /* or, line 382 */ + { int ret = r_mark_sU(z); /* call mark_sU, line 382 */ + if (ret == 0) goto lab22; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 384 */ - { int ret = slice_del(z); /* delete, line 384 */ + z->bra = z->c; /* ], line 382 */ + { int ret = slice_del(z); /* delete, line 382 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 384 */ - z->ket = z->c; /* [, line 384 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab23; } /* call mark_lAr, line 384 */ + { int m12 = z->l - z->c; (void)m12; /* try, line 382 */ + z->ket = z->c; /* [, line 382 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 382 */ + if (ret == 0) { z->c = z->l - m12; goto lab23; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 384 */ - { int ret = slice_del(z); /* delete, line 384 */ + z->bra = z->c; /* ], line 382 */ + { int ret = slice_del(z); /* delete, line 382 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab23; } /* call stem_suffix_chain_before_ki, line 384 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 382 */ + if (ret == 0) { z->c = z->l - m12; goto lab23; } if (ret < 0) return ret; } lab23: @@ -1648,9 +1564,9 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab21; lab22: - z->c = z->l - m7; - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab18; /* call mark_lArI, line 384 */ + z->c = z->l - m11; + { int ret = r_mark_lArI(z); /* call mark_lArI, line 382 */ + if (ret == 0) goto lab18; if (ret < 0) return ret; } } @@ -1658,38 +1574,38 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab18: z->c = z->l - m1; - z->ket = z->c; /* [, line 386 */ - { int ret = r_mark_DAn(z); - if (ret == 0) goto lab24; /* call mark_DAn, line 386 */ + z->ket = z->c; /* [, line 384 */ + { int ret = r_mark_DAn(z); /* call mark_DAn, line 384 */ + if (ret == 0) goto lab24; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 386 */ - { int ret = slice_del(z); /* delete, line 386 */ + z->bra = z->c; /* ], line 384 */ + { int ret = slice_del(z); /* delete, line 384 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 386 */ - z->ket = z->c; /* [, line 386 */ - { int m8 = z->l - z->c; (void)m8; /* or, line 389 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab27; /* call mark_possessives, line 388 */ + { int m13 = z->l - z->c; (void)m13; /* try, line 384 */ + z->ket = z->c; /* [, line 384 */ + { int m14 = z->l - z->c; (void)m14; /* or, line 387 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 386 */ + if (ret == 0) goto lab27; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 388 */ - { int ret = slice_del(z); /* delete, line 388 */ + z->bra = z->c; /* ], line 386 */ + { int ret = slice_del(z); /* delete, line 386 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 388 */ - z->ket = z->c; /* [, line 388 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call mark_lAr, line 388 */ + { int m15 = z->l - z->c; (void)m15; /* try, line 386 */ + z->ket = z->c; /* [, line 386 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 386 */ + if (ret == 0) { z->c = z->l - m15; goto lab28; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 388 */ - { int ret = slice_del(z); /* delete, line 388 */ + z->bra = z->c; /* ], line 386 */ + { int ret = slice_del(z); /* delete, line 386 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab28; } /* call stem_suffix_chain_before_ki, line 388 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 386 */ + if (ret == 0) { z->c = z->l - m15; goto lab28; } if (ret < 0) return ret; } lab28: @@ -1697,18 +1613,18 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab26; lab27: - z->c = z->l - m8; - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab29; /* call mark_lAr, line 390 */ + z->c = z->l - m14; + { int ret = r_mark_lAr(z); /* call mark_lAr, line 388 */ + if (ret == 0) goto lab29; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 390 */ - { int ret = slice_del(z); /* delete, line 390 */ + z->bra = z->c; /* ], line 388 */ + { int ret = slice_del(z); /* delete, line 388 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 390 */ - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab30; } /* call stem_suffix_chain_before_ki, line 390 */ + { int m16 = z->l - z->c; (void)m16; /* try, line 388 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 388 */ + if (ret == 0) { z->c = z->l - m16; goto lab30; } if (ret < 0) return ret; } lab30: @@ -1716,9 +1632,9 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab26; lab29: - z->c = z->l - m8; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab25; } /* call stem_suffix_chain_before_ki, line 392 */ + z->c = z->l - m14; + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 390 */ + if (ret == 0) { z->c = z->l - m13; goto lab25; } if (ret < 0) return ret; } } @@ -1729,74 +1645,74 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab24: z->c = z->l - m1; - z->ket = z->c; /* [, line 396 */ - { int m9 = z->l - z->c; (void)m9; /* or, line 396 */ - { int ret = r_mark_nUn(z); - if (ret == 0) goto lab33; /* call mark_nUn, line 396 */ + z->ket = z->c; /* [, line 394 */ + { int m17 = z->l - z->c; (void)m17; /* or, line 394 */ + { int ret = r_mark_nUn(z); /* call mark_nUn, line 394 */ + if (ret == 0) goto lab33; if (ret < 0) return ret; } goto lab32; lab33: - z->c = z->l - m9; - { int ret = r_mark_ylA(z); - if (ret == 0) goto lab31; /* call mark_ylA, line 396 */ + z->c = z->l - m17; + { int ret = r_mark_ylA(z); /* call mark_ylA, line 394 */ + if (ret == 0) goto lab31; if (ret < 0) return ret; } } lab32: - z->bra = z->c; /* ], line 396 */ - { int ret = slice_del(z); /* delete, line 396 */ + z->bra = z->c; /* ], line 394 */ + { int ret = slice_del(z); /* delete, line 394 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 397 */ - { int m10 = z->l - z->c; (void)m10; /* or, line 399 */ - z->ket = z->c; /* [, line 398 */ - { int ret = r_mark_lAr(z); - if (ret == 0) goto lab36; /* call mark_lAr, line 398 */ + { int m18 = z->l - z->c; (void)m18; /* try, line 395 */ + { int m19 = z->l - z->c; (void)m19; /* or, line 397 */ + z->ket = z->c; /* [, line 396 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 396 */ + if (ret == 0) goto lab36; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 398 */ - { int ret = slice_del(z); /* delete, line 398 */ + z->bra = z->c; /* ], line 396 */ + { int ret = slice_del(z); /* delete, line 396 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) goto lab36; /* call stem_suffix_chain_before_ki, line 398 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 396 */ + if (ret == 0) goto lab36; if (ret < 0) return ret; } goto lab35; lab36: - z->c = z->l - m10; - z->ket = z->c; /* [, line 400 */ - { int m11 = z->l - z->c; (void)m11; /* or, line 400 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab39; /* call mark_possessives, line 400 */ + z->c = z->l - m19; + z->ket = z->c; /* [, line 398 */ + { int m20 = z->l - z->c; (void)m20; /* or, line 398 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 398 */ + if (ret == 0) goto lab39; if (ret < 0) return ret; } goto lab38; lab39: - z->c = z->l - m11; - { int ret = r_mark_sU(z); - if (ret == 0) goto lab37; /* call mark_sU, line 400 */ + z->c = z->l - m20; + { int ret = r_mark_sU(z); /* call mark_sU, line 398 */ + if (ret == 0) goto lab37; if (ret < 0) return ret; } } lab38: - z->bra = z->c; /* ], line 400 */ - { int ret = slice_del(z); /* delete, line 400 */ + z->bra = z->c; /* ], line 398 */ + { int ret = slice_del(z); /* delete, line 398 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 400 */ - z->ket = z->c; /* [, line 400 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab40; } /* call mark_lAr, line 400 */ + { int m21 = z->l - z->c; (void)m21; /* try, line 398 */ + z->ket = z->c; /* [, line 398 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 398 */ + if (ret == 0) { z->c = z->l - m21; goto lab40; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 400 */ - { int ret = slice_del(z); /* delete, line 400 */ + z->bra = z->c; /* ], line 398 */ + { int ret = slice_del(z); /* delete, line 398 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab40; } /* call stem_suffix_chain_before_ki, line 400 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 398 */ + if (ret == 0) { z->c = z->l - m21; goto lab40; } if (ret < 0) return ret; } lab40: @@ -1804,9 +1720,9 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab35; lab37: - z->c = z->l - m10; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab34; } /* call stem_suffix_chain_before_ki, line 402 */ + z->c = z->l - m19; + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 400 */ + if (ret == 0) { z->c = z->l - m18; goto lab34; } if (ret < 0) return ret; } } @@ -1817,66 +1733,66 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab31: z->c = z->l - m1; - z->ket = z->c; /* [, line 406 */ - { int ret = r_mark_lArI(z); - if (ret == 0) goto lab41; /* call mark_lArI, line 406 */ + z->ket = z->c; /* [, line 404 */ + { int ret = r_mark_lArI(z); /* call mark_lArI, line 404 */ + if (ret == 0) goto lab41; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 406 */ - { int ret = slice_del(z); /* delete, line 406 */ + z->bra = z->c; /* ], line 404 */ + { int ret = slice_del(z); /* delete, line 404 */ if (ret < 0) return ret; } goto lab0; lab41: z->c = z->l - m1; - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) goto lab42; /* call stem_suffix_chain_before_ki, line 408 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 406 */ + if (ret == 0) goto lab42; if (ret < 0) return ret; } goto lab0; lab42: z->c = z->l - m1; - z->ket = z->c; /* [, line 410 */ - { int m12 = z->l - z->c; (void)m12; /* or, line 410 */ - { int ret = r_mark_DA(z); - if (ret == 0) goto lab45; /* call mark_DA, line 410 */ + z->ket = z->c; /* [, line 408 */ + { int m22 = z->l - z->c; (void)m22; /* or, line 408 */ + { int ret = r_mark_DA(z); /* call mark_DA, line 408 */ + if (ret == 0) goto lab45; if (ret < 0) return ret; } goto lab44; lab45: - z->c = z->l - m12; - { int ret = r_mark_yU(z); - if (ret == 0) goto lab46; /* call mark_yU, line 410 */ + z->c = z->l - m22; + { int ret = r_mark_yU(z); /* call mark_yU, line 408 */ + if (ret == 0) goto lab46; if (ret < 0) return ret; } goto lab44; lab46: - z->c = z->l - m12; - { int ret = r_mark_yA(z); - if (ret == 0) goto lab43; /* call mark_yA, line 410 */ + z->c = z->l - m22; + { int ret = r_mark_yA(z); /* call mark_yA, line 408 */ + if (ret == 0) goto lab43; if (ret < 0) return ret; } } lab44: - z->bra = z->c; /* ], line 410 */ - { int ret = slice_del(z); /* delete, line 410 */ + z->bra = z->c; /* ], line 408 */ + { int ret = slice_del(z); /* delete, line 408 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 410 */ - z->ket = z->c; /* [, line 410 */ - { int m13 = z->l - z->c; (void)m13; /* or, line 410 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab49; /* call mark_possessives, line 410 */ + { int m23 = z->l - z->c; (void)m23; /* try, line 408 */ + z->ket = z->c; /* [, line 408 */ + { int m24 = z->l - z->c; (void)m24; /* or, line 408 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 408 */ + if (ret == 0) goto lab49; if (ret < 0) return ret; } - z->bra = z->c; /* ], line 410 */ - { int ret = slice_del(z); /* delete, line 410 */ + z->bra = z->c; /* ], line 408 */ + { int ret = slice_del(z); /* delete, line 408 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 410 */ - z->ket = z->c; /* [, line 410 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab50; } /* call mark_lAr, line 410 */ + { int m25 = z->l - z->c; (void)m25; /* try, line 408 */ + z->ket = z->c; /* [, line 408 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 408 */ + if (ret == 0) { z->c = z->l - m25; goto lab50; } if (ret < 0) return ret; } lab50: @@ -1884,20 +1800,20 @@ static int r_stem_noun_suffixes(struct SN_env * z) { } goto lab48; lab49: - z->c = z->l - m13; - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab47; } /* call mark_lAr, line 410 */ + z->c = z->l - m24; + { int ret = r_mark_lAr(z); /* call mark_lAr, line 408 */ + if (ret == 0) { z->c = z->l - m23; goto lab47; } if (ret < 0) return ret; } } lab48: - z->bra = z->c; /* ], line 410 */ - { int ret = slice_del(z); /* delete, line 410 */ + z->bra = z->c; /* ], line 408 */ + { int ret = slice_del(z); /* delete, line 408 */ if (ret < 0) return ret; } - z->ket = z->c; /* [, line 410 */ - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab47; } /* call stem_suffix_chain_before_ki, line 410 */ + z->ket = z->c; /* [, line 408 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 408 */ + if (ret == 0) { z->c = z->l - m23; goto lab47; } if (ret < 0) return ret; } lab47: @@ -1906,37 +1822,36 @@ static int r_stem_noun_suffixes(struct SN_env * z) { goto lab0; lab43: z->c = z->l - m1; - z->ket = z->c; /* [, line 412 */ - { int m14 = z->l - z->c; (void)m14; /* or, line 412 */ - { int ret = r_mark_possessives(z); - if (ret == 0) goto lab52; /* call mark_possessives, line 412 */ + z->ket = z->c; /* [, line 410 */ + { int m26 = z->l - z->c; (void)m26; /* or, line 410 */ + { int ret = r_mark_possessives(z); /* call mark_possessives, line 410 */ + if (ret == 0) goto lab52; if (ret < 0) return ret; } goto lab51; lab52: - z->c = z->l - m14; - { int ret = r_mark_sU(z); - if (ret == 0) return 0; /* call mark_sU, line 412 */ - if (ret < 0) return ret; + z->c = z->l - m26; + { int ret = r_mark_sU(z); /* call mark_sU, line 410 */ + if (ret <= 0) return ret; } } lab51: - z->bra = z->c; /* ], line 412 */ - { int ret = slice_del(z); /* delete, line 412 */ + z->bra = z->c; /* ], line 410 */ + { int ret = slice_del(z); /* delete, line 410 */ if (ret < 0) return ret; } - { int m_keep = z->l - z->c;/* (void) m_keep;*/ /* try, line 412 */ - z->ket = z->c; /* [, line 412 */ - { int ret = r_mark_lAr(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab53; } /* call mark_lAr, line 412 */ + { int m27 = z->l - z->c; (void)m27; /* try, line 410 */ + z->ket = z->c; /* [, line 410 */ + { int ret = r_mark_lAr(z); /* call mark_lAr, line 410 */ + if (ret == 0) { z->c = z->l - m27; goto lab53; } if (ret < 0) return ret; } - z->bra = z->c; /* ], line 412 */ - { int ret = slice_del(z); /* delete, line 412 */ + z->bra = z->c; /* ], line 410 */ + { int ret = slice_del(z); /* delete, line 410 */ if (ret < 0) return ret; } - { int ret = r_stem_suffix_chain_before_ki(z); - if (ret == 0) { z->c = z->l - m_keep; goto lab53; } /* call stem_suffix_chain_before_ki, line 412 */ + { int ret = r_stem_suffix_chain_before_ki(z); /* call stem_suffix_chain_before_ki, line 410 */ + if (ret == 0) { z->c = z->l - m27; goto lab53; } if (ret < 0) return ret; } lab53: @@ -1947,31 +1862,30 @@ static int r_stem_noun_suffixes(struct SN_env * z) { return 1; } -static int r_post_process_last_consonants(struct SN_env * z) { +static int r_post_process_last_consonants(struct SN_env * z) { /* backwardmode */ int among_var; - z->ket = z->c; /* [, line 416 */ - among_var = find_among_b(z, a_23, 4); /* substring, line 416 */ + z->ket = z->c; /* [, line 414 */ + among_var = find_among_b(z, a_23, 4); /* substring, line 414 */ if (!(among_var)) return 0; - z->bra = z->c; /* ], line 416 */ - switch(among_var) { - case 0: return 0; + z->bra = z->c; /* ], line 414 */ + switch (among_var) { /* among, line 414 */ case 1: - { int ret = slice_from_s(z, 1, s_16); /* <-, line 417 */ + { int ret = slice_from_s(z, 1, s_5); /* <-, line 415 */ if (ret < 0) return ret; } break; case 2: - { int ret = slice_from_s(z, 2, s_17); /* <-, line 418 */ + { int ret = slice_from_s(z, 2, s_6); /* <-, line 416 */ if (ret < 0) return ret; } break; case 3: - { int ret = slice_from_s(z, 1, s_18); /* <-, line 419 */ + { int ret = slice_from_s(z, 1, s_7); /* <-, line 417 */ if (ret < 0) return ret; } break; case 4: - { int ret = slice_from_s(z, 1, s_19); /* <-, line 420 */ + { int ret = slice_from_s(z, 1, s_8); /* <-, line 418 */ if (ret < 0) return ret; } break; @@ -1979,94 +1893,109 @@ static int r_post_process_last_consonants(struct SN_env * z) { return 1; } -static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { - { int m_test = z->l - z->c; /* test, line 431 */ - { int m1 = z->l - z->c; (void)m1; /* or, line 431 */ - if (!(eq_s_b(z, 1, s_20))) goto lab1; +static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { /* backwardmode */ + { int m_test1 = z->l - z->c; /* test, line 429 */ + { int m2 = z->l - z->c; (void)m2; /* or, line 429 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'd') goto lab1; /* literal, line 429 */ + z->c--; goto lab0; lab1: - z->c = z->l - m1; - if (!(eq_s_b(z, 1, s_21))) return 0; + z->c = z->l - m2; + if (z->c <= z->lb || z->p[z->c - 1] != 'g') return 0; /* literal, line 429 */ + z->c--; } lab0: - z->c = z->l - m_test; + z->c = z->l - m_test1; } - { int m2 = z->l - z->c; (void)m2; /* or, line 433 */ - { int m_test = z->l - z->c; /* test, line 432 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel, line 432 */ - { int m3 = z->l - z->c; (void)m3; /* or, line 432 */ - if (!(eq_s_b(z, 1, s_22))) goto lab5; + { int m3 = z->l - z->c; (void)m3; /* or, line 431 */ + { int m_test4 = z->l - z->c; /* test, line 430 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab3; /* goto */ /* grouping vowel, line 430 */ + { int m5 = z->l - z->c; (void)m5; /* or, line 430 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'a') goto lab5; /* literal, line 430 */ + z->c--; goto lab4; lab5: - z->c = z->l - m3; - if (!(eq_s_b(z, 2, s_23))) goto lab3; + z->c = z->l - m5; + if (!(eq_s_b(z, 2, s_9))) goto lab3; /* literal, line 430 */ } lab4: - z->c = z->l - m_test; + z->c = z->l - m_test4; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 2, s_24); /* <+, line 432 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 2, s_10); /* <+, line 430 */ + z->c = saved_c; + } if (ret < 0) return ret; } goto lab2; lab3: - z->c = z->l - m2; - { int m_test = z->l - z->c; /* test, line 434 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab6; /* goto */ /* grouping vowel, line 434 */ - { int m4 = z->l - z->c; (void)m4; /* or, line 434 */ - if (!(eq_s_b(z, 1, s_25))) goto lab8; + z->c = z->l - m3; + { int m_test6 = z->l - z->c; /* test, line 432 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab6; /* goto */ /* grouping vowel, line 432 */ + { int m7 = z->l - z->c; (void)m7; /* or, line 432 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'e') goto lab8; /* literal, line 432 */ + z->c--; goto lab7; lab8: - z->c = z->l - m4; - if (!(eq_s_b(z, 1, s_26))) goto lab6; + z->c = z->l - m7; + if (z->c <= z->lb || z->p[z->c - 1] != 'i') goto lab6; /* literal, line 432 */ + z->c--; } lab7: - z->c = z->l - m_test; + z->c = z->l - m_test6; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_27); /* <+, line 434 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_11); /* <+, line 432 */ + z->c = saved_c; + } if (ret < 0) return ret; } goto lab2; lab6: - z->c = z->l - m2; - { int m_test = z->l - z->c; /* test, line 436 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab9; /* goto */ /* grouping vowel, line 436 */ - { int m5 = z->l - z->c; (void)m5; /* or, line 436 */ - if (!(eq_s_b(z, 1, s_28))) goto lab11; + z->c = z->l - m3; + { int m_test8 = z->l - z->c; /* test, line 434 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) goto lab9; /* goto */ /* grouping vowel, line 434 */ + { int m9 = z->l - z->c; (void)m9; /* or, line 434 */ + if (z->c <= z->lb || z->p[z->c - 1] != 'o') goto lab11; /* literal, line 434 */ + z->c--; goto lab10; lab11: - z->c = z->l - m5; - if (!(eq_s_b(z, 1, s_29))) goto lab9; + z->c = z->l - m9; + if (z->c <= z->lb || z->p[z->c - 1] != 'u') goto lab9; /* literal, line 434 */ + z->c--; } lab10: - z->c = z->l - m_test; + z->c = z->l - m_test8; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 1, s_30); /* <+, line 436 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 1, s_12); /* <+, line 434 */ + z->c = saved_c; + } if (ret < 0) return ret; } goto lab2; lab9: - z->c = z->l - m2; - { int m_test = z->l - z->c; /* test, line 438 */ - if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 438 */ - { int m6 = z->l - z->c; (void)m6; /* or, line 438 */ - if (!(eq_s_b(z, 2, s_31))) goto lab13; + z->c = z->l - m3; + { int m_test10 = z->l - z->c; /* test, line 436 */ + if (out_grouping_b_U(z, g_vowel, 97, 305, 1) < 0) return 0; /* goto */ /* grouping vowel, line 436 */ + { int m11 = z->l - z->c; (void)m11; /* or, line 436 */ + if (!(eq_s_b(z, 2, s_13))) goto lab13; /* literal, line 436 */ goto lab12; lab13: - z->c = z->l - m6; - if (!(eq_s_b(z, 2, s_32))) return 0; + z->c = z->l - m11; + if (!(eq_s_b(z, 2, s_14))) return 0; /* literal, line 436 */ } lab12: - z->c = z->l - m_test; + z->c = z->l - m_test10; } - { int c_keep = z->c; - int ret = insert_s(z, z->c, z->c, 2, s_33); /* <+, line 438 */ - z->c = c_keep; + { int ret; + { int saved_c = z->c; + ret = insert_s(z, z->c, z->c, 2, s_15); /* <+, line 436 */ + z->c = saved_c; + } if (ret < 0) return ret; } } @@ -2074,12 +2003,23 @@ static int r_append_U_to_stems_ending_with_d_or_g(struct SN_env * z) { return 1; } -static int r_more_than_one_syllable_word(struct SN_env * z) { - { int c_test = z->c; /* test, line 446 */ +static int r_is_reserved_word(struct SN_env * z) { /* backwardmode */ + if (!(eq_s_b(z, 2, s_16))) return 0; /* literal, line 440 */ + { int m1 = z->l - z->c; (void)m1; /* try, line 440 */ + if (!(eq_s_b(z, 3, s_17))) { z->c = z->l - m1; goto lab0; } /* literal, line 440 */ + lab0: + ; + } + if (z->c > z->lb) return 0; /* atlimit, line 440 */ + return 1; +} + +static int r_more_than_one_syllable_word(struct SN_env * z) { /* forwardmode */ + { int c_test1 = z->c; /* test, line 447 */ { int i = 2; - while(1) { /* atleast, line 446 */ - int c1 = z->c; - { /* gopast */ /* grouping vowel, line 446 */ + while(1) { /* atleast, line 447 */ + int c2 = z->c; + { /* gopast */ /* grouping vowel, line 447 */ int ret = out_grouping_U(z, g_vowel, 97, 305, 1); if (ret < 0) goto lab0; z->c += ret; @@ -2087,77 +2027,39 @@ static int r_more_than_one_syllable_word(struct SN_env * z) { i--; continue; lab0: - z->c = c1; + z->c = c2; break; } if (i > 0) return 0; } - z->c = c_test; + z->c = c_test1; } return 1; } -static int r_is_reserved_word(struct SN_env * z) { - { int c1 = z->c; /* or, line 451 */ - { int c_test = z->c; /* test, line 450 */ - while(1) { /* gopast, line 450 */ - if (!(eq_s(z, 2, s_34))) goto lab2; - break; - lab2: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); - if (ret < 0) goto lab1; - z->c = ret; /* gopast, line 450 */ - } - } - z->I[0] = 2; - if (!(z->I[0] == z->l)) goto lab1; - z->c = c_test; - } - goto lab0; - lab1: - z->c = c1; - { int c_test = z->c; /* test, line 452 */ - while(1) { /* gopast, line 452 */ - if (!(eq_s(z, 5, s_35))) goto lab3; - break; - lab3: - { int ret = skip_utf8(z->p, z->c, 0, z->l, 1); - if (ret < 0) return 0; - z->c = ret; /* gopast, line 452 */ - } - } - z->I[0] = 5; - if (!(z->I[0] == z->l)) return 0; - z->c = c_test; - } - } -lab0: - return 1; -} +static int r_postlude(struct SN_env * z) { /* forwardmode */ + z->lb = z->c; z->c = z->l; /* backwards, line 451 */ -static int r_postlude(struct SN_env * z) { - { int c1 = z->c; /* not, line 456 */ - { int ret = r_is_reserved_word(z); - if (ret == 0) goto lab0; /* call is_reserved_word, line 456 */ + { int m1 = z->l - z->c; (void)m1; /* not, line 452 */ + { int ret = r_is_reserved_word(z); /* call is_reserved_word, line 452 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } return 0; lab0: - z->c = c1; + z->c = z->l - m1; } - z->lb = z->c; z->c = z->l; /* backwards, line 457 */ - - { int m2 = z->l - z->c; (void)m2; /* do, line 458 */ - { int ret = r_append_U_to_stems_ending_with_d_or_g(z); - if (ret == 0) goto lab1; /* call append_U_to_stems_ending_with_d_or_g, line 458 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 453 */ + { int ret = r_append_U_to_stems_ending_with_d_or_g(z); /* call append_U_to_stems_ending_with_d_or_g, line 453 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } - { int m3 = z->l - z->c; (void)m3; /* do, line 459 */ - { int ret = r_post_process_last_consonants(z); - if (ret == 0) goto lab2; /* call post_process_last_consonants, line 459 */ + { int m3 = z->l - z->c; (void)m3; /* do, line 454 */ + { int ret = r_post_process_last_consonants(z); /* call post_process_last_consonants, line 454 */ + if (ret == 0) goto lab2; if (ret < 0) return ret; } lab2: @@ -2167,39 +2069,37 @@ static int r_postlude(struct SN_env * z) { return 1; } -extern int turkish_UTF_8_stem(struct SN_env * z) { - { int ret = r_more_than_one_syllable_word(z); - if (ret == 0) return 0; /* call more_than_one_syllable_word, line 465 */ - if (ret < 0) return ret; +extern int turkish_UTF_8_stem(struct SN_env * z) { /* forwardmode */ + { int ret = r_more_than_one_syllable_word(z); /* call more_than_one_syllable_word, line 460 */ + if (ret <= 0) return ret; } - z->lb = z->c; z->c = z->l; /* backwards, line 467 */ + z->lb = z->c; z->c = z->l; /* backwards, line 462 */ - { int m1 = z->l - z->c; (void)m1; /* do, line 468 */ - { int ret = r_stem_nominal_verb_suffixes(z); - if (ret == 0) goto lab0; /* call stem_nominal_verb_suffixes, line 468 */ + { int m1 = z->l - z->c; (void)m1; /* do, line 463 */ + { int ret = r_stem_nominal_verb_suffixes(z); /* call stem_nominal_verb_suffixes, line 463 */ + if (ret == 0) goto lab0; if (ret < 0) return ret; } lab0: z->c = z->l - m1; } - if (!(z->B[0])) return 0; /* Boolean test continue_stemming_noun_suffixes, line 469 */ - { int m2 = z->l - z->c; (void)m2; /* do, line 470 */ - { int ret = r_stem_noun_suffixes(z); - if (ret == 0) goto lab1; /* call stem_noun_suffixes, line 470 */ + if (!(z->B[0])) return 0; /* Boolean test continue_stemming_noun_suffixes, line 464 */ + { int m2 = z->l - z->c; (void)m2; /* do, line 465 */ + { int ret = r_stem_noun_suffixes(z); /* call stem_noun_suffixes, line 465 */ + if (ret == 0) goto lab1; if (ret < 0) return ret; } lab1: z->c = z->l - m2; } z->c = z->lb; - { int ret = r_postlude(z); - if (ret == 0) return 0; /* call postlude, line 473 */ - if (ret < 0) return ret; + { int ret = r_postlude(z); /* call postlude, line 468 */ + if (ret <= 0) return ret; } return 1; } -extern struct SN_env * turkish_UTF_8_create_env(void) { return SN_create_env(0, 1, 1); } +extern struct SN_env * turkish_UTF_8_create_env(void) { return SN_create_env(0, 0, 1); } extern void turkish_UTF_8_close_env(struct SN_env * z) { SN_close_env(z, 0); } diff --git a/src/backend/snowball/libstemmer/utilities.c b/src/backend/snowball/libstemmer/utilities.c index 8c89af1cd5c..d64d9223179 100644 --- a/src/backend/snowball/libstemmer/utilities.c +++ b/src/backend/snowball/libstemmer/utilities.c @@ -1,7 +1,5 @@ #include "header.h" -#define unless(C) if(!(C)) - #define CREATE_SIZE 1 extern symbol * create_s(void) { @@ -10,7 +8,7 @@ extern symbol * create_s(void) { if (mem == NULL) return NULL; p = (symbol *) (HEAD + (char *) mem); CAPACITY(p) = CREATE_SIZE; - SET_SIZE(p, CREATE_SIZE); + SET_SIZE(p, 0); return p; } @@ -22,7 +20,7 @@ extern void lose_s(symbol * p) { /* new_p = skip_utf8(p, c, lb, l, n); skips n characters forwards from p + c if n +ve, or n characters backwards from p + c - 1 if n -ve. new_p is the new - position, or 0 on failure. + position, or -1 on failure. -- used to implement hop and next in the utf8 case. */ @@ -61,38 +59,56 @@ extern int skip_utf8(const symbol * p, int c, int lb, int l, int n) { /* Code for character groupings: utf8 cases */ static int get_utf8(const symbol * p, int c, int l, int * slot) { - int b0, b1; + int b0, b1, b2; if (c >= l) return 0; b0 = p[c++]; if (b0 < 0xC0 || c == l) { /* 1100 0000 */ - * slot = b0; return 1; + *slot = b0; + return 1; } - b1 = p[c++]; + b1 = p[c++] & 0x3F; if (b0 < 0xE0 || c == l) { /* 1110 0000 */ - * slot = (b0 & 0x1F) << 6 | (b1 & 0x3F); return 2; + *slot = (b0 & 0x1F) << 6 | b1; + return 2; + } + b2 = p[c++] & 0x3F; + if (b0 < 0xF0 || c == l) { /* 1111 0000 */ + *slot = (b0 & 0xF) << 12 | b1 << 6 | b2; + return 3; } - * slot = (b0 & 0xF) << 12 | (b1 & 0x3F) << 6 | (p[c] & 0x3F); return 3; + *slot = (b0 & 0xE) << 18 | b1 << 12 | b2 << 6 | (p[c] & 0x3F); + return 4; } static int get_b_utf8(const symbol * p, int c, int lb, int * slot) { - int b0, b1; + int a, b; if (c <= lb) return 0; - b0 = p[--c]; - if (b0 < 0x80 || c == lb) { /* 1000 0000 */ - * slot = b0; return 1; + b = p[--c]; + if (b < 0x80 || c == lb) { /* 1000 0000 */ + *slot = b; + return 1; } - b1 = p[--c]; - if (b1 >= 0xC0 || c == lb) { /* 1100 0000 */ - * slot = (b1 & 0x1F) << 6 | (b0 & 0x3F); return 2; + a = b & 0x3F; + b = p[--c]; + if (b >= 0xC0 || c == lb) { /* 1100 0000 */ + *slot = (b & 0x1F) << 6 | a; + return 2; } - * slot = (p[c] & 0xF) << 12 | (b1 & 0x3F) << 6 | (b0 & 0x3F); return 3; + a |= (b & 0x3F) << 6; + b = p[--c]; + if (b >= 0xE0 || c == lb) { /* 1110 0000 */ + *slot = (b & 0xF) << 12 | a; + return 3; + } + *slot = (p[--c] & 0xE) << 18 | (b & 0x3F) << 12 | a; + return 4; } extern int in_grouping_U(struct SN_env * z, const unsigned char * s, int min, int max, int repeat) { do { int ch; int w = get_utf8(z->p, z->c, z->l, & ch); - unless (w) return -1; + if (!w) return -1; if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return w; z->c += w; @@ -104,7 +120,7 @@ extern int in_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, do { int ch; int w = get_b_utf8(z->p, z->c, z->lb, & ch); - unless (w) return -1; + if (!w) return -1; if (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) return w; z->c -= w; @@ -116,8 +132,8 @@ extern int out_grouping_U(struct SN_env * z, const unsigned char * s, int min, i do { int ch; int w = get_utf8(z->p, z->c, z->l, & ch); - unless (w) return -1; - unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) + if (!w) return -1; + if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) return w; z->c += w; } while (repeat); @@ -128,8 +144,8 @@ extern int out_grouping_b_U(struct SN_env * z, const unsigned char * s, int min, do { int ch; int w = get_b_utf8(z->p, z->c, z->lb, & ch); - unless (w) return -1; - unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) + if (!w) return -1; + if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) return w; z->c -= w; } while (repeat); @@ -167,7 +183,7 @@ extern int out_grouping(struct SN_env * z, const unsigned char * s, int min, int int ch; if (z->c >= z->l) return -1; ch = z->p[z->c]; - unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) + if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) return 1; z->c++; } while (repeat); @@ -179,7 +195,7 @@ extern int out_grouping_b(struct SN_env * z, const unsigned char * s, int min, i int ch; if (z->c <= z->lb) return -1; ch = z->p[z->c - 1]; - unless (ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0) + if (!(ch > max || (ch -= min) < 0 || (s[ch >> 3] & (0X1 << (ch & 0X7))) == 0)) return 1; z->c--; } while (repeat); @@ -232,8 +248,13 @@ extern int find_among(struct SN_env * z, const struct among * v, int v_size) { common++; } } - if (diff < 0) { j = k; common_j = common; } - else { i = k; common_i = common; } + if (diff < 0) { + j = k; + common_j = common; + } else { + i = k; + common_i = common; + } if (j - i <= 1) { if (i > 0) break; /* v->s has been inspected */ if (j == i) break; /* only one item in v */ @@ -362,11 +383,10 @@ extern int replace_s(struct SN_env * z, int c_bra, int c_ket, int s_size, const z->l += adjustment; if (z->c >= c_ket) z->c += adjustment; - else - if (z->c > c_bra) - z->c = c_bra; + else if (z->c > c_bra) + z->c = c_bra; } - unless (s_size == 0) memmove(z->p + c_bra, s, s_size * sizeof(symbol)); + if (s_size) memmove(z->p + c_bra, s, s_size * sizeof(symbol)); if (adjptr != NULL) *adjptr = adjustment; return 0; @@ -412,12 +432,7 @@ extern int insert_s(struct SN_env * z, int bra, int ket, int s_size, const symbo } extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p) { - int adjustment; - if (replace_s(z, bra, ket, SIZE(p), p, &adjustment)) - return -1; - if (bra <= z->bra) z->bra += adjustment; - if (bra <= z->ket) z->ket += adjustment; - return 0; + return insert_s(z, bra, ket, SIZE(p), p); } extern symbol * slice_to(struct SN_env * z, symbol * p) { @@ -450,6 +465,16 @@ extern symbol * assign_to(struct SN_env * z, symbol * p) { return p; } +extern int len_utf8(const symbol * p) { + int size = SIZE(p); + int len = 0; + while (size--) { + symbol b = *p++; + if (b >= 0xC0 || b < 0x80) ++len; + } + return len; +} + #if 0 extern void debug(struct SN_env * z, int number, int line_count) { int i; diff --git a/src/backend/snowball/snowball.sql.in b/src/backend/snowball/snowball.sql.in index 27550dfc9aa..151f6f74407 100644 --- a/src/backend/snowball/snowball.sql.in +++ b/src/backend/snowball/snowball.sql.in @@ -1,7 +1,7 @@ /* * text search configuration for _LANGNAME_ language * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/backend/snowball/snowball.sql.in * diff --git a/src/backend/snowball/snowball_func.sql.in b/src/backend/snowball/snowball_func.sql.in index c02dad43e38..483f0d85261 100644 --- a/src/backend/snowball/snowball_func.sql.in +++ b/src/backend/snowball/snowball_func.sql.in @@ -1,7 +1,7 @@ /* * Create underlying C functions for Snowball stemmers * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/backend/snowball/snowball_func.sql.in * diff --git a/src/backend/snowball/stopwords/nepali.stop b/src/backend/snowball/stopwords/nepali.stop new file mode 100644 index 00000000000..42e24a59594 --- /dev/null +++ b/src/backend/snowball/stopwords/nepali.stop @@ -0,0 +1,304 @@ +अकà¥à¤¸à¤° +अगाडि +अगाडी +अà¤à¥ˆ +अनà¥à¤¸à¤¾à¤° +अनà¥à¤¤à¤°à¥à¤—त +अनà¥à¤¯ +अनà¥à¤¯à¤¥à¤¾ +अब +अरॠ+अरू +अरà¥à¤•ा +अरà¥à¤•ी +अरà¥à¤•ो +अरà¥à¤¥à¤¾à¤¤ +अरà¥à¤¥à¤¾à¤¤à¥ +अरà¥à¤¬ +अलग +अलिकति +असार +आइतवार +आठ+आज +आठ +आतà¥à¤® +आदि +आफू +आफà¥à¤¨à¥ˆ +आफà¥à¤¨à¥‹ +आयो +आशà¥à¤µà¤¿à¤¨ +उदाहरण +उन +उप +उही +à¤à¤‰à¤Ÿà¥ˆ +à¤à¤• +à¤à¤•दम +à¤à¤•ै +ओठ +औं +कति +कतै +कतà¥à¤°à¤¾ +कतà¥à¤°à¥€ +कतà¥à¤°à¥‹ +करोड +कस +कसरी +कसै +कसà¥à¤¤à¤¾ +कसà¥à¤¤à¥€ +कसà¥à¤¤à¥‹ +कहिलà¥à¤¯à¥ˆ +कहीं +का +कारà¥à¤¤à¤¿à¤• +कि +किन +किनभने +कà¥à¤¨ +कà¥à¤¨à¥ˆ +कà¥à¤°à¤¾ +कृपया +के +केहि +केही +को +कोही +कà¥à¤°à¤®à¤¶à¤ƒ +खरà¥à¤¬ +गयौ +चाà¤à¤¡à¥ˆ +चार +चाले +चाहनà¥à¤¹à¥à¤¨à¥à¤› +चाहनà¥à¤›à¥ +चाहिठ+चैत +चौथो +छ +छनॠ+छॠ+छू +छैन +छौठ+छौं +जताततै +जति +जतà¥à¤°à¤¾ +जतà¥à¤°à¥€ +जतà¥à¤°à¥‹ +जब +जबकि +जस +जसà¥à¤¤à¤¾ +जसà¥à¤¤à¥€ +जसà¥à¤¤à¥‹ +जसà¥à¤¤à¥‹à¤¸à¥à¤•ै +जहाठ+जान +जाहिर +जà¥à¤¨ +जे +जेठ +जो +जोसà¥à¤•ै +ठीक +त +ततà¥à¤•ाल +तथा +तदनà¥à¤¸à¤¾à¤° +तपाई +तपाईं +तर +तल +तापनि +तापनी +तिन +तिनी +तिमी +तिर +ती +तीन +तà¥à¤°à¥à¤¨à¥à¤¤à¥ˆ +तेसà¥à¤•ारण +तेसà¥à¤°à¥‹ +तà¥à¤¯à¤¸à¤•ारण +तà¥à¤¯à¤¸à¤ªà¤›à¤¿ +तà¥à¤¯à¤¸à¤®à¤¾ +तà¥à¤¯à¤¸à¥ˆà¤²à¥‡ +तà¥à¤¯à¤¹à¤¾à¤ +तà¥à¤¯à¥‹ +तà¥à¤¸à¤ªà¤›à¤¿ +तà¥à¤¸à¥ˆà¤²à¥‡ +थिठ+थिà¤à¤¨ +थिà¤à¤¨à¤¨à¥ +थियो +थोरै +दस +दिठ+दिनà¥à¤­à¤à¤•ो +दिनà¥à¤¹à¥à¤¨à¥à¤› +दà¥à¤ˆ +देख +देखि +देखिनà¥à¤› +देखियो +देखे +देखेको +देखेर +देखà¥à¤¨ +दोशà¥à¤°à¥‹ +दोसà¥à¤°à¥‹ +धेरै +न +नजिकै +नतà¥à¤° +नयाठ+नि +निमà¥à¤¤à¤¿ +निमà¥à¤¨ +निमà¥à¤¨à¤¾à¤¨à¥à¤¸à¤¾à¤° +निरà¥à¤¦à¤¿à¤·à¥à¤Ÿ +नै +नौ +पकà¥à¤•ा +पकà¥à¤•ै +पछि +पछिलà¥à¤²à¥‹ +पटक +पनि +परà¥à¤› +परà¥à¤¥à¥à¤¯à¥‹ +परà¥à¤¯à¤¾à¤ªà¥à¤¤ +परà¥à¤¸à¥€ +पहिले +पहिलो +पहिलà¥à¤¯à¥ˆ +पाà¤à¤š +पाà¤à¤šà¥Œà¤‚ +पूरà¥à¤µ +पौष +पà¥à¤°à¤¤à¤¿ +पà¥à¤°à¤¤à¥‡à¤• +पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• +पà¥à¤°à¤¥à¤® +पà¥à¤²à¤¸ +फागà¥à¤¨ +फेरि +फेरी +बने +बनà¥à¤¦ +बनà¥à¤¨ +बरॠ+बाटो +बारे +बाहिर +बाहेक +बिरà¥à¤¦à¥à¤§ +बिशेष +बिहिवार +बीच +बà¥à¤§à¤µà¤¾à¤° +भठ+भदौ +भनॠ+भर +भितà¥à¤° +भितà¥à¤°à¥€ +भोलि +भोली +म +मंसिर +मङà¥à¤—लवार +महिना +मा +माघ +मातà¥à¤° +माथि +मà¥à¤–à¥à¤¯ +मेरो +यति +यतà¥à¤¤à¤¿ +यतà¥à¤°à¤¾ +यतà¥à¤°à¥€ +यतà¥à¤°à¥‹ +यथोचित +यदि +यदà¥à¤¯à¤ªà¤¿ +यस +यसरी +यसो +यसà¥à¤¤à¤¾ +यसà¥à¤¤à¥€ +यसà¥à¤¤à¥‹ +यहाठ+या +यिन +यिनी +यी +यो +र +रही +रहेका +रहेको +राखे +राखà¥à¤› +रामà¥à¤°à¥‹ +रूप +लगभग +लाई +लाख +लागि +ले +वरिपरि +वरीपरी +वरà¥à¤· +वासà¥à¤¤à¤µà¤®à¤¾ +वाहेक +विरà¥à¤¦à¥à¤§ +विशेष +वैशाख +शनिवार +शायद +शà¥à¤•à¥à¤°à¤µà¤¾à¤° +सà¤à¤— +सà¤à¤—ै +संग +संगै +सकà¥à¤› +सटà¥à¤Ÿà¤¾ +सधै +सधैं +सबै +समय +समà¥à¤­à¤µ +समà¥à¤® +सय +सही +साà¤à¤šà¥à¤šà¥ˆ +साउन +सात +साथ +साथै +सायद +सारा +सà¥à¤¨à¥à¤¨à¤¾ +सो +सोधà¥à¤¨ +सोमवार +सोही +सà¥à¤ªà¤·à¥à¤Ÿ +हजार +हपà¥à¤¤à¤¾ +हरे +हरेक +हामी +हामà¥à¤°à¥‹ +हिजो +हà¥à¤¨à¥à¤› +होला +होसॠdiff --git a/src/backend/statistics/Makefile b/src/backend/statistics/Makefile index 3404e4554ab..d2815265fbf 100644 --- a/src/backend/statistics/Makefile +++ b/src/backend/statistics/Makefile @@ -12,6 +12,6 @@ subdir = src/backend/statistics top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -OBJS = extended_stats.o dependencies.o mvdistinct.o +OBJS = extended_stats.o dependencies.o mcv.o mvdistinct.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/statistics/README b/src/backend/statistics/README index a8f00a590e6..7fda13e75be 100644 --- a/src/backend/statistics/README +++ b/src/backend/statistics/README @@ -18,6 +18,8 @@ There are currently two kinds of extended statistics: (b) soft functional dependencies (README.dependencies) + (c) MCV lists (README.mcv) + Compatible clause types ----------------------- @@ -26,6 +28,8 @@ Each type of statistics may be used to estimate some subset of clause types. (a) functional dependencies - equality clauses (AND), possibly IS NULL + (b) MCV lists - equality and inequality clauses (AND, OR, NOT), IS [NOT] NULL + Currently, only OpExprs in the form Var op Const, or Const op Var are supported, however it's feasible to expand the code later to also estimate the selectivities on clauses such as Var op Var. diff --git a/src/backend/statistics/README.mcv b/src/backend/statistics/README.mcv new file mode 100644 index 00000000000..8455b0d13f6 --- /dev/null +++ b/src/backend/statistics/README.mcv @@ -0,0 +1,103 @@ +MCV lists +========= + +Multivariate MCV (most-common values) lists are a straightforward extension of +regular MCV list, tracking most frequent combinations of values for a group of +attributes. + +This works particularly well for columns with a small number of distinct values, +as the list may include all the combinations and approximate the distribution +very accurately. + +For columns with a large number of distinct values (e.g. those with continuous +domains), the list will only track the most frequent combinations. If the +distribution is mostly uniform (all combinations about equally frequent), the +MCV list will be empty. + +Estimates of some clauses (e.g. equality) based on MCV lists are more accurate +than when using histograms. + +Also, MCV lists don't necessarily require sorting of the values (the fact that +we use sorting when building them is implementation detail), but even more +importantly the ordering is not built into the approximation (while histograms +are built on ordering). So MCV lists work well even for attributes where the +ordering of the data type is disconnected from the meaning of the data. For +example we know how to sort strings, but it's unlikely to make much sense for +city names (or other label-like attributes). + + +Selectivity estimation +---------------------- + +The estimation, implemented in mcv_clauselist_selectivity(), is quite simple +in principle - we need to identify MCV items matching all the clauses and sum +frequencies of all those items. + +Currently MCV lists support estimation of the following clause types: + + (a) equality clauses WHERE (a = 1) AND (b = 2) + (b) inequality clauses WHERE (a < 1) AND (b >= 2) + (c) NULL clauses WHERE (a IS NULL) AND (b IS NOT NULL) + (d) OR clauses WHERE (a < 1) OR (b >= 2) + +It's possible to add support for additional clauses, for example: + + (e) multi-var clauses WHERE (a > b) + +and possibly others. These are tasks for the future, not yet implemented. + + +Hashed MCV (not yet implemented) +-------------------------------- + +Regular MCV lists have to include actual values for each item, so if those items +are large the list may be quite large. This is especially true for multivariate +MCV lists, although the current implementation partially mitigates this by +performing de-duplicating the values before storing them on disk. + +It's possible to only store hashes (32-bit values) instead of the actual values, +significantly reducing the space requirements. Obviously, this would only make +the MCV lists useful for estimating equality conditions (assuming the 32-bit +hashes make the collisions rare enough). + +This might also complicate matching the columns to available stats. + + +TODO Consider implementing hashed MCV list, storing just 32-bit hashes instead + of the actual values. This type of MCV list will be useful only for + estimating equality clauses, and will reduce space requirements for large + varlena types (in such cases we usually only want equality anyway). + + +Inspecting the MCV list +----------------------- + +Inspecting the regular (per-attribute) MCV lists is trivial, as it's enough +to select the columns from pg_stats. The data is encoded as anyarrays, and +all the items have the same data type, so anyarray provides a simple way to +get a text representation. + +With multivariate MCV lists the columns may use different data types, making +it impossible to use anyarrays. It might be possible to produce a similar +array-like representation, but that would complicate further processing and +analysis of the MCV list. + +So instead the MCV lists are stored in a custom data type (pg_mcv_list), +which however makes it more difficult to inspect the contents. To make that +easier, there's a SRF returning detailed information about the MCV lists. + + SELECT m.* FROM pg_statistic_ext s, + pg_statistic_ext_data d, + pg_mcv_list_items(stxdmcv) m + WHERE s.stxname = 'stts2' + AND d.stxoid = s.oid; + +It accepts one parameter - a pg_mcv_list value (which can only be obtained +from pg_statistic_ext_data catalog, to defend against malicious input), and +returns these columns: + + - item index (0, ..., (nitems-1)) + - values (string array) + - nulls only (boolean array) + - frequency (double precision) + - base_frequency (double precision) diff --git a/src/backend/statistics/dependencies.c b/src/backend/statistics/dependencies.c index d7305b7ab39..585cad2ad94 100644 --- a/src/backend/statistics/dependencies.c +++ b/src/backend/statistics/dependencies.c @@ -3,7 +3,7 @@ * dependencies.c * POSTGRES functional dependencies * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,12 +17,13 @@ #include "access/sysattr.h" #include "catalog/pg_operator.h" #include "catalog/pg_statistic_ext.h" +#include "catalog/pg_statistic_ext_data.h" #include "lib/stringinfo.h" +#include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" -#include "optimizer/cost.h" -#include "optimizer/var.h" +#include "optimizer/optimizer.h" #include "nodes/nodes.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "statistics/extended_stats_internal.h" #include "statistics/statistics.h" #include "utils/bytea.h" @@ -32,6 +33,20 @@ #include "utils/syscache.h" #include "utils/typcache.h" +/* size of the struct header fields (magic, type, ndeps) */ +#define SizeOfHeader (3 * sizeof(uint32)) + +/* size of a serialized dependency (degree, natts, atts) */ +#define SizeOfItem(natts) \ + (sizeof(double) + sizeof(AttrNumber) * (1 + (natts))) + +/* minimal size of a dependency (with two attributes) */ +#define MinSizeOfItem SizeOfItem(2) + +/* minimal size of dependencies, when all deps are minimal */ +#define MinSizeOfItems(ndeps) \ + (SizeOfHeader + (ndeps) * MinSizeOfItem) + /* * Internal state for DependencyGenerator of dependencies. Dependencies are similar to * k-permutations of n elements, except that the order does not matter for the @@ -49,22 +64,22 @@ typedef struct DependencyGeneratorData typedef DependencyGeneratorData *DependencyGenerator; static void generate_dependencies_recurse(DependencyGenerator state, - int index, AttrNumber start, AttrNumber *current); + int index, AttrNumber start, AttrNumber *current); static void generate_dependencies(DependencyGenerator state); static DependencyGenerator DependencyGenerator_init(int n, int k); static void DependencyGenerator_free(DependencyGenerator state); static AttrNumber *DependencyGenerator_next(DependencyGenerator state); static double dependency_degree(int numrows, HeapTuple *rows, int k, - AttrNumber *dependency, VacAttrStats **stats, Bitmapset *attrs); + AttrNumber *dependency, VacAttrStats **stats, Bitmapset *attrs); static bool dependency_is_fully_matched(MVDependency *dependency, - Bitmapset *attnums); + Bitmapset *attnums); static bool dependency_implies_attribute(MVDependency *dependency, - AttrNumber attnum); + AttrNumber attnum); static bool dependency_is_compatible_clause(Node *clause, Index relid, - AttrNumber *attnum); + AttrNumber *attnum); static MVDependency *find_strongest_dependency(StatisticExtInfo *stats, - MVDependencies *dependencies, - Bitmapset *attnums); + MVDependencies *dependencies, + Bitmapset *attnums); static void generate_dependencies_recurse(DependencyGenerator state, int index, @@ -202,13 +217,12 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, VacAttrStats **stats, Bitmapset *attrs) { int i, - j; - int nvalues = numrows * k; + nitems; MultiSortSupport mss; SortItem *items; - Datum *values; - bool *isnull; - int *attnums; + AttrNumber *attnums; + AttrNumber *attnums_dep; + int numattrs; /* counters valid within a group */ int group_size = 0; @@ -223,26 +237,16 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, /* sort info for all attributes columns */ mss = multi_sort_init(k); - /* data for the sort */ - items = (SortItem *) palloc(numrows * sizeof(SortItem)); - values = (Datum *) palloc(sizeof(Datum) * nvalues); - isnull = (bool *) palloc(sizeof(bool) * nvalues); - - /* fix the pointers to values/isnull */ - for (i = 0; i < numrows; i++) - { - items[i].values = &values[i * k]; - items[i].isnull = &isnull[i * k]; - } - /* - * Transform the bms into an array, to make accessing i-th member easier. + * Transform the attrs from bitmap to an array to make accessing the i-th + * member easier, and then construct a filtered version with only attnums + * referenced by the dependency we validate. */ - attnums = (int *) palloc(sizeof(int) * bms_num_members(attrs)); - i = 0; - j = -1; - while ((j = bms_next_member(attrs, j)) >= 0) - attnums[i++] = j; + attnums = build_attnums_array(attrs, &numattrs); + + attnums_dep = (AttrNumber *) palloc(k * sizeof(AttrNumber)); + for (i = 0; i < k; i++) + attnums_dep[i] = attnums[dependency[i]]; /* * Verify the dependency (a,b,...)->z, using a rather simple algorithm: @@ -252,9 +256,12 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, * (b) split the data into groups by first (k-1) columns * * (c) for each group count different values in the last column + * + * We use the column data types' default sort operators and collations; + * perhaps at some point it'd be worth using column-specific collations? */ - /* prepare the sort function for the first dimension, and SortItem array */ + /* prepare the sort function for the dimensions */ for (i = 0; i < k; i++) { VacAttrStats *colstat = stats[dependency[i]]; @@ -266,20 +273,18 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, colstat->attrtypid); /* prepare the sort function for this dimension */ - multi_sort_add_dimension(mss, i, type->lt_opr); - - /* accumulate all the data for both columns into an array and sort it */ - for (j = 0; j < numrows; j++) - { - items[j].values[i] = - heap_getattr(rows[j], attnums[dependency[i]], - stats[i]->tupDesc, &items[j].isnull[i]); - } + multi_sort_add_dimension(mss, i, type->lt_opr, colstat->attrcollid); } - /* sort the items so that we can detect the groups */ - qsort_arg((void *) items, numrows, sizeof(SortItem), - multi_sort_compare, mss); + /* + * build an array of SortItem(s) sorted using the multi-sort support + * + * XXX This relies on all stats entries pointing to the same tuple + * descriptor. For now that assumption holds, but it might change in the + * future for example if we support statistics on multiple tables. + */ + items = build_sorted_items(numrows, &nitems, rows, stats[0]->tupDesc, + mss, k, attnums_dep); /* * Walk through the sorted array, split it into rows according to the @@ -292,14 +297,14 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, group_size = 1; /* loop 1 beyond the end of the array so that we count the final group */ - for (i = 1; i <= numrows; i++) + for (i = 1; i <= nitems; i++) { /* * Check if the group ended, which may be either because we processed - * all the items (i==numrows), or because the i-th item is not equal - * to the preceding one. + * all the items (i==nitems), or because the i-th item is not equal to + * the preceding one. */ - if (i == numrows || + if (i == nitems || multi_sort_compare_dims(0, k - 2, &items[i - 1], &items[i], mss) != 0) { /* @@ -321,10 +326,12 @@ dependency_degree(int numrows, HeapTuple *rows, int k, AttrNumber *dependency, group_size++; } - pfree(items); - pfree(values); - pfree(isnull); + if (items) + pfree(items); + pfree(mss); + pfree(attnums); + pfree(attnums_dep); /* Compute the 'degree of validity' as (supporting/total). */ return (n_supporting_rows * 1.0 / numrows); @@ -351,24 +358,17 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, VacAttrStats **stats) { int i, - j, k; int numattrs; - int *attnums; + AttrNumber *attnums; /* result */ MVDependencies *dependencies = NULL; - numattrs = bms_num_members(attrs); - /* * Transform the bms into an array, to make accessing i-th member easier. */ - attnums = palloc(sizeof(int) * bms_num_members(attrs)); - i = 0; - j = -1; - while ((j = bms_next_member(attrs, j)) >= 0) - attnums[i++] = j; + attnums = build_attnums_array(attrs, &numattrs); Assert(numattrs >= 2); @@ -395,7 +395,7 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, degree = dependency_degree(numrows, rows, k, dependency, stats, attrs); /* - * if the dependency seems entirely invalid, don't store it it + * if the dependency seems entirely invalid, don't store it */ if (degree == 0.0) continue; @@ -423,7 +423,7 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs, dependencies->ndeps++; dependencies = (MVDependencies *) repalloc(dependencies, offsetof(MVDependencies, deps) - + dependencies->ndeps * sizeof(MVDependency)); + + dependencies->ndeps * sizeof(MVDependency *)); dependencies->deps[dependencies->ndeps - 1] = d; } @@ -451,12 +451,11 @@ statext_dependencies_serialize(MVDependencies *dependencies) Size len; /* we need to store ndeps, with a number of attributes for each one */ - len = VARHDRSZ + SizeOfDependencies - + dependencies->ndeps * SizeOfDependency; + len = VARHDRSZ + SizeOfHeader; /* and also include space for the actual attribute numbers and degrees */ for (i = 0; i < dependencies->ndeps; i++) - len += (sizeof(AttrNumber) * dependencies->deps[i]->nattributes); + len += SizeOfItem(dependencies->deps[i]->nattributes); output = (bytea *) palloc0(len); SET_VARSIZE(output, len); @@ -476,15 +475,22 @@ statext_dependencies_serialize(MVDependencies *dependencies) { MVDependency *d = dependencies->deps[i]; - memcpy(tmp, d, SizeOfDependency); - tmp += SizeOfDependency; + memcpy(tmp, &d->degree, sizeof(double)); + tmp += sizeof(double); + + memcpy(tmp, &d->nattributes, sizeof(AttrNumber)); + tmp += sizeof(AttrNumber); memcpy(tmp, d->attributes, sizeof(AttrNumber) * d->nattributes); tmp += sizeof(AttrNumber) * d->nattributes; + /* protect against overflow */ Assert(tmp <= ((char *) output + len)); } + /* make sure we've produced exactly the right amount of data */ + Assert(tmp == ((char *) output + len)); + return output; } @@ -502,9 +508,9 @@ statext_dependencies_deserialize(bytea *data) if (data == NULL) return NULL; - if (VARSIZE_ANY_EXHDR(data) < SizeOfDependencies) + if (VARSIZE_ANY_EXHDR(data) < SizeOfHeader) elog(ERROR, "invalid MVDependencies size %zd (expected at least %zd)", - VARSIZE_ANY_EXHDR(data), SizeOfDependencies); + VARSIZE_ANY_EXHDR(data), SizeOfHeader); /* read the MVDependencies header */ dependencies = (MVDependencies *) palloc0(sizeof(MVDependencies)); @@ -529,14 +535,10 @@ statext_dependencies_deserialize(bytea *data) dependencies->type, STATS_DEPS_TYPE_BASIC); if (dependencies->ndeps == 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid zero-length item array in MVDependencies"))); + elog(ERROR, "invalid zero-length item array in MVDependencies"); /* what minimum bytea size do we expect for those parameters */ - min_expected_size = SizeOfDependencies + - dependencies->ndeps * (SizeOfDependency + - sizeof(AttrNumber) * 2); + min_expected_size = SizeOfItem(dependencies->ndeps); if (VARSIZE_ANY_EXHDR(data) < min_expected_size) elog(ERROR, "invalid dependencies size %zd (expected at least %zd)", @@ -631,20 +633,27 @@ dependency_implies_attribute(MVDependency *dependency, AttrNumber attnum) MVDependencies * statext_dependencies_load(Oid mvoid) { + MVDependencies *result; bool isnull; Datum deps; - HeapTuple htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid)); + HeapTuple htup; + htup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(mvoid)); if (!HeapTupleIsValid(htup)) elog(ERROR, "cache lookup failed for statistics object %u", mvoid); - deps = SysCacheGetAttr(STATEXTOID, htup, - Anum_pg_statistic_ext_stxdependencies, &isnull); - Assert(!isnull); + deps = SysCacheGetAttr(STATEXTDATASTXOID, htup, + Anum_pg_statistic_ext_data_stxddependencies, &isnull); + if (isnull) + elog(ERROR, + "requested statistic kind \"%c\" is not yet built for statistics object %u", + STATS_EXT_DEPENDENCIES, mvoid); + + result = statext_dependencies_deserialize(DatumGetByteaPP(deps)); ReleaseSysCache(htup); - return statext_dependencies_deserialize(DatumGetByteaP(deps)); + return result; } /* @@ -792,7 +801,7 @@ dependency_is_compatible_clause(Node *clause, Index relid, AttrNumber *attnum) /* OK to proceed with checking "var" */ } - else if (not_clause((Node *) rinfo->clause)) + else if (is_notclause(rinfo->clause)) { /* * "NOT x" can be interpreted as "x = false", so get the argument and @@ -908,9 +917,9 @@ find_strongest_dependency(StatisticExtInfo *stats, MVDependencies *dependencies, * using functional dependency statistics, or 1.0 if no useful functional * dependency statistic exists. * - * 'estimatedclauses' is an output argument that gets a bit set corresponding - * to the (zero-based) list index of each clause that is included in the - * estimated selectivity. + * 'estimatedclauses' is an input/output argument that gets a bit set + * corresponding to the (zero-based) list index of each clause that is included + * in the estimated selectivity. * * Given equality clauses on attributes (a,b) we find the strongest dependency * between them, i.e. either (a=>b) or (b=>a). Assuming (a=>b) is the selected @@ -945,9 +954,6 @@ dependencies_clauselist_selectivity(PlannerInfo *root, AttrNumber *list_attnums; int listidx; - /* initialize output argument */ - *estimatedclauses = NULL; - /* check if there's any stats that might be useful for us. */ if (!has_stats_of_kind(rel->statlist, STATS_EXT_DEPENDENCIES)) return 1.0; @@ -962,6 +968,9 @@ dependencies_clauselist_selectivity(PlannerInfo *root, * the attnums for each clause in a list which we'll reference later so we * don't need to repeat the same work again. We'll also keep track of all * attnums seen. + * + * We also skip clauses that we already estimated using different types of + * statistics (we treat them as incompatible). */ listidx = 0; foreach(l, clauses) @@ -969,7 +978,8 @@ dependencies_clauselist_selectivity(PlannerInfo *root, Node *clause = (Node *) lfirst(l); AttrNumber attnum; - if (dependency_is_compatible_clause(clause, rel->relid, &attnum)) + if (!bms_is_member(listidx, *estimatedclauses) && + dependency_is_compatible_clause(clause, rel->relid, &attnum)) { list_attnums[listidx] = attnum; clauses_attnums = bms_add_member(clauses_attnums, attnum); @@ -1039,8 +1049,7 @@ dependencies_clauselist_selectivity(PlannerInfo *root, /* * Skip incompatible clauses, and ones we've already estimated on. */ - if (list_attnums[listidx] == InvalidAttrNumber || - bms_is_member(listidx, *estimatedclauses)) + if (list_attnums[listidx] == InvalidAttrNumber) continue; /* diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c index 2df5f7dc3a5..207ee3160ef 100644 --- a/src/backend/statistics/extended_stats.c +++ b/src/backend/statistics/extended_stats.c @@ -6,7 +6,7 @@ * Generic code supporting statistics objects created via CREATE STATISTICS. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,23 +16,40 @@ */ #include "postgres.h" +#include "access/detoast.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_collation.h" #include "catalog/pg_statistic_ext.h" -#include "nodes/relation.h" +#include "catalog/pg_statistic_ext_data.h" +#include "miscadmin.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "postmaster/autovacuum.h" #include "statistics/extended_stats_internal.h" #include "statistics/statistics.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/rel.h" +#include "utils/selfuncs.h" #include "utils/syscache.h" +/* + * To avoid consuming too much memory during analysis and/or too much space + * in the resulting pg_statistic rows, we ignore varlena datums that are wider + * than WIDTH_THRESHOLD (after detoasting!). This is legitimate for MCV + * and distinct-value calculations since a wide value is unlikely to be + * duplicated at all, much less be a most-common value. For the same reason, + * ignoring wide values will not affect our estimates of histogram bin + * boundaries very much. + */ +#define WIDTH_THRESHOLD 1024 /* * Used internally to refer to an individual statistics object, i.e., @@ -45,16 +62,18 @@ typedef struct StatExtEntry char *name; /* statistics object's name */ Bitmapset *columns; /* attribute numbers covered by the object */ List *types; /* 'char' list of enabled statistic kinds */ + int stattarget; /* statistics target (-1 for default) */ } StatExtEntry; static List *fetch_statentries_for_relation(Relation pg_statext, Oid relid); static VacAttrStats **lookup_var_attr_stats(Relation rel, Bitmapset *attrs, - int nvacatts, VacAttrStats **vacatts); -static void statext_store(Relation pg_stext, Oid relid, - MVNDistinct *ndistinct, MVDependencies *dependencies, - VacAttrStats **stats); - + int nvacatts, VacAttrStats **vacatts); +static void statext_store(Oid relid, + MVNDistinct *ndistinct, MVDependencies *dependencies, + MCVList *mcv, VacAttrStats **stats); +static int statext_compute_stattarget(int stattarget, + int natts, VacAttrStats **stats); /* * Compute requested extended stats, using the rows sampled for the plain @@ -79,7 +98,7 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, ALLOCSET_DEFAULT_SIZES); oldcxt = MemoryContextSwitchTo(cxt); - pg_stext = heap_open(StatisticExtRelationId, RowExclusiveLock); + pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock); stats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel)); foreach(lc, stats) @@ -87,8 +106,10 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, StatExtEntry *stat = (StatExtEntry *) lfirst(lc); MVNDistinct *ndistinct = NULL; MVDependencies *dependencies = NULL; + MCVList *mcv = NULL; VacAttrStats **stats; ListCell *lc2; + int stattarget; /* * Check if we can build these stats based on the column analyzed. If @@ -113,6 +134,19 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, Assert(bms_num_members(stat->columns) >= 2 && bms_num_members(stat->columns) <= STATS_MAX_DIMENSIONS); + /* compute statistics target for this statistics */ + stattarget = statext_compute_stattarget(stat->stattarget, + bms_num_members(stat->columns), + stats); + + /* + * Don't rebuild statistics objects with statistics target set to 0 (we + * just leave the existing values around, just like we do for regular + * per-column statistics). + */ + if (stattarget == 0) + continue; + /* compute statistic of each requested type */ foreach(lc2, stat->types) { @@ -124,21 +158,153 @@ BuildRelationExtStatistics(Relation onerel, double totalrows, else if (t == STATS_EXT_DEPENDENCIES) dependencies = statext_dependencies_build(numrows, rows, stat->columns, stats); + else if (t == STATS_EXT_MCV) + mcv = statext_mcv_build(numrows, rows, stat->columns, stats, + totalrows, stattarget); } /* store the statistics in the catalog */ - statext_store(pg_stext, stat->statOid, ndistinct, dependencies, stats); + statext_store(stat->statOid, ndistinct, dependencies, mcv, stats); } - heap_close(pg_stext, RowExclusiveLock); + table_close(pg_stext, RowExclusiveLock); MemoryContextSwitchTo(oldcxt); MemoryContextDelete(cxt); } +/* + * ComputeExtStatisticsRows + * Compute number of rows required by extended statistics on a table. + * + * Computes number of rows we need to sample to build extended statistics on a + * table. This only looks at statistics we can actually build - for example + * when analyzing only some of the columns, this will skip statistics objects + * that would require additional columns. + * + * See statext_compute_stattarget for details about how we compute statistics + * target for a statistics objects (from the object target, attribute targets + * and default statistics target). + */ +int +ComputeExtStatisticsRows(Relation onerel, + int natts, VacAttrStats **vacattrstats) +{ + Relation pg_stext; + ListCell *lc; + List *lstats; + MemoryContext cxt; + MemoryContext oldcxt; + int result = 0; + + cxt = AllocSetContextCreate(CurrentMemoryContext, + "ComputeExtStatisticsRows", + ALLOCSET_DEFAULT_SIZES); + oldcxt = MemoryContextSwitchTo(cxt); + + pg_stext = table_open(StatisticExtRelationId, RowExclusiveLock); + lstats = fetch_statentries_for_relation(pg_stext, RelationGetRelid(onerel)); + + foreach(lc, lstats) + { + StatExtEntry *stat = (StatExtEntry *) lfirst(lc); + int stattarget = stat->stattarget; + VacAttrStats **stats; + int nattrs = bms_num_members(stat->columns); + + /* + * Check if we can build this statistics object based on the columns + * analyzed. If not, ignore it (don't report anything, we'll do that + * during the actual build BuildRelationExtStatistics). + */ + stats = lookup_var_attr_stats(onerel, stat->columns, + natts, vacattrstats); + + if (!stats) + continue; + + /* + * Compute statistics target, based on what's set for the statistic + * object itself, and for its attributes. + */ + stattarget = statext_compute_stattarget(stat->stattarget, + nattrs, stats); + + /* Use the largest value for all statistics objects. */ + if (stattarget > result) + result = stattarget; + } + + table_close(pg_stext, RowExclusiveLock); + + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(cxt); + + /* compute sample size based on the statistics target */ + return (300 * result); +} + +/* + * statext_compute_stattarget + * compute statistics target for an extended statistic + * + * When computing target for extended statistics objects, we consider three + * places where the target may be set - the statistics object itself, + * attributes the statistics is defined on, and then the default statistics + * target. + * + * First we look at what's set for the statistics object itself, using the + * ALTER STATISTICS ... SET STATISTICS command. If we find a valid value + * there (i.e. not -1) we're done. Otherwise we look at targets set for any + * of the attributes the statistic is defined on, and if there are columns + * with defined target, we use the maximum value. We do this mostly for + * backwards compatibility, because this is what we did before having + * statistics target for extended statistics. + * + * And finally, if we still don't have a statistics target, we use the value + * set in default_statistics_target. + */ +static int +statext_compute_stattarget(int stattarget, int nattrs, VacAttrStats **stats) +{ + int i; + + /* + * If there's statistics target set for the statistics object, use it. + * It may be set to 0 which disables building of that statistic. + */ + if (stattarget >= 0) + return stattarget; + + /* + * The target for the statistics object is set to -1, in which case we + * look at the maximum target set for any of the attributes the object + * is defined on. + */ + for (i = 0; i < nattrs; i++) + { + /* keep the maximmum statistics target */ + if (stats[i]->attr->attstattarget > stattarget) + stattarget = stats[i]->attr->attstattarget; + } + + /* + * If the value is still negative (so neither the statistics object nor + * any of the columns have custom statistics target set), use the global + * default target. + */ + if (stattarget < 0) + stattarget = default_statistics_target; + + /* As this point we should have a valid statistics target. */ + Assert((stattarget >= 0) && (stattarget <= 10000)); + + return stattarget; +} + /* * statext_is_kind_built - * Is this stat kind built in the given pg_statistic_ext tuple? + * Is this stat kind built in the given pg_statistic_ext_data tuple? */ bool statext_is_kind_built(HeapTuple htup, char type) @@ -148,11 +314,15 @@ statext_is_kind_built(HeapTuple htup, char type) switch (type) { case STATS_EXT_NDISTINCT: - attnum = Anum_pg_statistic_ext_stxndistinct; + attnum = Anum_pg_statistic_ext_data_stxdndistinct; break; case STATS_EXT_DEPENDENCIES: - attnum = Anum_pg_statistic_ext_stxdependencies; + attnum = Anum_pg_statistic_ext_data_stxddependencies; + break; + + case STATS_EXT_MCV: + attnum = Anum_pg_statistic_ext_data_stxdmcv; break; default: @@ -196,10 +366,11 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) Form_pg_statistic_ext staForm; entry = palloc0(sizeof(StatExtEntry)); - entry->statOid = HeapTupleGetOid(htup); staForm = (Form_pg_statistic_ext) GETSTRUCT(htup); + entry->statOid = staForm->oid; entry->schema = get_namespace_name(staForm->stxnamespace); entry->name = pstrdup(NameStr(staForm->stxname)); + entry->stattarget = staForm->stxstattarget; for (i = 0; i < staForm->stxkeys.dim1; i++) { entry->columns = bms_add_member(entry->columns, @@ -219,7 +390,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid) for (i = 0; i < ARR_DIMS(arr)[0]; i++) { Assert((enabled[i] == STATS_EXT_NDISTINCT) || - (enabled[i] == STATS_EXT_DEPENDENCIES)); + (enabled[i] == STATS_EXT_DEPENDENCIES) || + (enabled[i] == STATS_EXT_MCV)); entry->types = lappend_int(entry->types, (int) enabled[i]); } @@ -289,61 +461,76 @@ lookup_var_attr_stats(Relation rel, Bitmapset *attrs, /* * statext_store - * Serializes the statistics and stores them into the pg_statistic_ext tuple. + * Serializes the statistics and stores them into the pg_statistic_ext_data + * tuple. */ static void -statext_store(Relation pg_stext, Oid statOid, +statext_store(Oid statOid, MVNDistinct *ndistinct, MVDependencies *dependencies, - VacAttrStats **stats) + MCVList *mcv, VacAttrStats **stats) { HeapTuple stup, oldtup; - Datum values[Natts_pg_statistic_ext]; - bool nulls[Natts_pg_statistic_ext]; - bool replaces[Natts_pg_statistic_ext]; + Datum values[Natts_pg_statistic_ext_data]; + bool nulls[Natts_pg_statistic_ext_data]; + bool replaces[Natts_pg_statistic_ext_data]; + Relation pg_stextdata; memset(nulls, true, sizeof(nulls)); memset(replaces, false, sizeof(replaces)); memset(values, 0, sizeof(values)); /* - * Construct a new pg_statistic_ext tuple, replacing the calculated stats. + * Construct a new pg_statistic_ext_data tuple, replacing the calculated + * stats. */ if (ndistinct != NULL) { bytea *data = statext_ndistinct_serialize(ndistinct); - nulls[Anum_pg_statistic_ext_stxndistinct - 1] = (data == NULL); - values[Anum_pg_statistic_ext_stxndistinct - 1] = PointerGetDatum(data); + nulls[Anum_pg_statistic_ext_data_stxdndistinct - 1] = (data == NULL); + values[Anum_pg_statistic_ext_data_stxdndistinct - 1] = PointerGetDatum(data); } if (dependencies != NULL) { bytea *data = statext_dependencies_serialize(dependencies); - nulls[Anum_pg_statistic_ext_stxdependencies - 1] = (data == NULL); - values[Anum_pg_statistic_ext_stxdependencies - 1] = PointerGetDatum(data); + nulls[Anum_pg_statistic_ext_data_stxddependencies - 1] = (data == NULL); + values[Anum_pg_statistic_ext_data_stxddependencies - 1] = PointerGetDatum(data); + } + if (mcv != NULL) + { + bytea *data = statext_mcv_serialize(mcv, stats); + + nulls[Anum_pg_statistic_ext_data_stxdmcv - 1] = (data == NULL); + values[Anum_pg_statistic_ext_data_stxdmcv - 1] = PointerGetDatum(data); } /* always replace the value (either by bytea or NULL) */ - replaces[Anum_pg_statistic_ext_stxndistinct - 1] = true; - replaces[Anum_pg_statistic_ext_stxdependencies - 1] = true; + replaces[Anum_pg_statistic_ext_data_stxdndistinct - 1] = true; + replaces[Anum_pg_statistic_ext_data_stxddependencies - 1] = true; + replaces[Anum_pg_statistic_ext_data_stxdmcv - 1] = true; - /* there should already be a pg_statistic_ext tuple */ - oldtup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statOid)); + /* there should already be a pg_statistic_ext_data tuple */ + oldtup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(statOid)); if (!HeapTupleIsValid(oldtup)) elog(ERROR, "cache lookup failed for statistics object %u", statOid); /* replace it */ + pg_stextdata = table_open(StatisticExtDataRelationId, RowExclusiveLock); + stup = heap_modify_tuple(oldtup, - RelationGetDescr(pg_stext), + RelationGetDescr(pg_stextdata), values, nulls, replaces); ReleaseSysCache(oldtup); - CatalogTupleUpdate(pg_stext, &stup->t_self, stup); + CatalogTupleUpdate(pg_stextdata, &stup->t_self, stup); heap_freetuple(stup); + + table_close(pg_stextdata, RowExclusiveLock); } /* initialize multi-dimensional sort */ @@ -363,18 +550,18 @@ multi_sort_init(int ndims) } /* - * Prepare sort support info using the given sort operator + * Prepare sort support info using the given sort operator and collation * at the position 'sortdim' */ void -multi_sort_add_dimension(MultiSortSupport mss, int sortdim, Oid oper) +multi_sort_add_dimension(MultiSortSupport mss, int sortdim, + Oid oper, Oid collation) { SortSupport ssup = &mss->ssup[sortdim]; ssup->ssup_cxt = CurrentMemoryContext; - ssup->ssup_collation = DEFAULT_COLLATION_OID; + ssup->ssup_collation = collation; ssup->ssup_nulls_first = false; - ssup->ssup_cxt = CurrentMemoryContext; PrepareSortSupportFromOrderingOp(oper, ssup); } @@ -434,6 +621,202 @@ multi_sort_compare_dims(int start, int end, return 0; } +int +compare_scalars_simple(const void *a, const void *b, void *arg) +{ + return compare_datums_simple(*(Datum *) a, + *(Datum *) b, + (SortSupport) arg); +} + +int +compare_datums_simple(Datum a, Datum b, SortSupport ssup) +{ + return ApplySortComparator(a, false, b, false, ssup); +} + +/* simple counterpart to qsort_arg */ +void * +bsearch_arg(const void *key, const void *base, size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg) +{ + size_t l, + u, + idx; + const void *p; + int comparison; + + l = 0; + u = nmemb; + while (l < u) + { + idx = (l + u) / 2; + p = (void *) (((const char *) base) + (idx * size)); + comparison = (*compar) (key, p, arg); + + if (comparison < 0) + u = idx; + else if (comparison > 0) + l = idx + 1; + else + return (void *) p; + } + + return NULL; +} + +/* + * build_attnums_array + * Transforms a bitmap into an array of AttrNumber values. + * + * This is used for extended statistics only, so all the attribute must be + * user-defined. That means offsetting by FirstLowInvalidHeapAttributeNumber + * is not necessary here (and when querying the bitmap). + */ +AttrNumber * +build_attnums_array(Bitmapset *attrs, int *numattrs) +{ + int i, + j; + AttrNumber *attnums; + int num = bms_num_members(attrs); + + if (numattrs) + *numattrs = num; + + /* build attnums from the bitmapset */ + attnums = (AttrNumber *) palloc(sizeof(AttrNumber) * num); + i = 0; + j = -1; + while ((j = bms_next_member(attrs, j)) >= 0) + { + /* + * Make sure the bitmap contains only user-defined attributes. As + * bitmaps can't contain negative values, this can be violated in two + * ways. Firstly, the bitmap might contain 0 as a member, and secondly + * the integer value might be larger than MaxAttrNumber. + */ + Assert(AttrNumberIsForUserDefinedAttr(j)); + Assert(j <= MaxAttrNumber); + + attnums[i++] = (AttrNumber) j; + + /* protect against overflows */ + Assert(i <= num); + } + + return attnums; +} + +/* + * build_sorted_items + * build a sorted array of SortItem with values from rows + * + * Note: All the memory is allocated in a single chunk, so that the caller + * can simply pfree the return value to release all of it. + */ +SortItem * +build_sorted_items(int numrows, int *nitems, HeapTuple *rows, TupleDesc tdesc, + MultiSortSupport mss, int numattrs, AttrNumber *attnums) +{ + int i, + j, + len, + idx; + int nvalues = numrows * numattrs; + + SortItem *items; + Datum *values; + bool *isnull; + char *ptr; + + /* Compute the total amount of memory we need (both items and values). */ + len = numrows * sizeof(SortItem) + nvalues * (sizeof(Datum) + sizeof(bool)); + + /* Allocate the memory and split it into the pieces. */ + ptr = palloc0(len); + + /* items to sort */ + items = (SortItem *) ptr; + ptr += numrows * sizeof(SortItem); + + /* values and null flags */ + values = (Datum *) ptr; + ptr += nvalues * sizeof(Datum); + + isnull = (bool *) ptr; + ptr += nvalues * sizeof(bool); + + /* make sure we consumed the whole buffer exactly */ + Assert((ptr - (char *) items) == len); + + /* fix the pointers to Datum and bool arrays */ + idx = 0; + for (i = 0; i < numrows; i++) + { + bool toowide = false; + + items[idx].values = &values[idx * numattrs]; + items[idx].isnull = &isnull[idx * numattrs]; + + /* load the values/null flags from sample rows */ + for (j = 0; j < numattrs; j++) + { + Datum value; + bool isnull; + + value = heap_getattr(rows[i], attnums[j], tdesc, &isnull); + + /* + * If this is a varlena value, check if it's too wide and if yes + * then skip the whole item. Otherwise detoast the value. + * + * XXX It may happen that we've already detoasted some preceding + * values for the current item. We don't bother to cleanup those + * on the assumption that those are small (below WIDTH_THRESHOLD) + * and will be discarded at the end of analyze. + */ + if ((!isnull) && + (TupleDescAttr(tdesc, attnums[j] - 1)->attlen == -1)) + { + if (toast_raw_datum_size(value) > WIDTH_THRESHOLD) + { + toowide = true; + break; + } + + value = PointerGetDatum(PG_DETOAST_DATUM(value)); + } + + items[idx].values[j] = value; + items[idx].isnull[j] = isnull; + } + + if (toowide) + continue; + + idx++; + } + + /* store the actual number of items (ignoring the too-wide ones) */ + *nitems = idx; + + /* all items were too wide */ + if (idx == 0) + { + /* everything is allocated as a single chunk */ + pfree(items); + return NULL; + } + + /* do the sort, using the multi-sort */ + qsort_arg((void *) items, idx, sizeof(SortItem), + multi_sort_compare, mss); + + return items; +} + /* * has_stats_of_kind * Check whether the list contains statistic of a given kind @@ -464,7 +847,7 @@ has_stats_of_kind(List *stats, char requiredkind) * object referencing the most of the requested attributes, breaking ties * in favor of objects with fewer keys overall. * - * XXX if multiple statistics objects tie on both criteria, then which object + * XXX If multiple statistics objects tie on both criteria, then which object * is chosen depends on the order that they appear in the stats list. Perhaps * further tiebreakers are needed. */ @@ -514,3 +897,501 @@ choose_best_statistics(List *stats, Bitmapset *attnums, char requiredkind) return best_match; } + +/* + * statext_is_compatible_clause_internal + * Determines if the clause is compatible with MCV lists. + * + * Does the heavy lifting of actually inspecting the clauses for + * statext_is_compatible_clause. It needs to be split like this because + * of recursion. The attnums bitmap is an input/output parameter collecting + * attribute numbers from all compatible clauses (recursively). + */ +static bool +statext_is_compatible_clause_internal(PlannerInfo *root, Node *clause, + Index relid, Bitmapset **attnums) +{ + /* Look inside any binary-compatible relabeling (as in examine_variable) */ + if (IsA(clause, RelabelType)) + clause = (Node *) ((RelabelType *) clause)->arg; + + /* plain Var references (boolean Vars or recursive checks) */ + if (IsA(clause, Var)) + { + Var *var = (Var *) clause; + + /* Ensure var is from the correct relation */ + if (var->varno != relid) + return false; + + /* we also better ensure the Var is from the current level */ + if (var->varlevelsup > 0) + return false; + + /* Also skip system attributes (we don't allow stats on those). */ + if (!AttrNumberIsForUserDefinedAttr(var->varattno)) + return false; + + *attnums = bms_add_member(*attnums, var->varattno); + + return true; + } + + /* (Var op Const) or (Const op Var) */ + if (is_opclause(clause)) + { + RangeTblEntry *rte = root->simple_rte_array[relid]; + OpExpr *expr = (OpExpr *) clause; + Var *var; + + /* Only expressions with two arguments are considered compatible. */ + if (list_length(expr->args) != 2) + return false; + + /* Check if the expression the right shape (one Var, one Const) */ + if (!examine_opclause_expression(expr, &var, NULL, NULL)) + return false; + + /* + * If it's not one of the supported operators ("=", "<", ">", etc.), + * just ignore the clause, as it's not compatible with MCV lists. + * + * This uses the function for estimating selectivity, not the operator + * directly (a bit awkward, but well ...). + */ + switch (get_oprrest(expr->opno)) + { + case F_EQSEL: + case F_NEQSEL: + case F_SCALARLTSEL: + case F_SCALARLESEL: + case F_SCALARGTSEL: + case F_SCALARGESEL: + /* supported, will continue with inspection of the Var */ + break; + + default: + /* other estimators are considered unknown/unsupported */ + return false; + } + + /* + * If there are any securityQuals on the RTE from security barrier + * views or RLS policies, then the user may not have access to all the + * table's data, and we must check that the operator is leak-proof. + * + * If the operator is leaky, then we must ignore this clause for the + * purposes of estimating with MCV lists, otherwise the operator might + * reveal values from the MCV list that the user doesn't have + * permission to see. + */ + if (rte->securityQuals != NIL && + !get_func_leakproof(get_opcode(expr->opno))) + return false; + + return statext_is_compatible_clause_internal(root, (Node *) var, + relid, attnums); + } + + /* AND/OR/NOT clause */ + if (is_andclause(clause) || + is_orclause(clause) || + is_notclause(clause)) + { + /* + * AND/OR/NOT-clauses are supported if all sub-clauses are supported + * + * Perhaps we could improve this by handling mixed cases, when some of + * the clauses are supported and some are not. Selectivity for the + * supported subclauses would be computed using extended statistics, + * and the remaining clauses would be estimated using the traditional + * algorithm (product of selectivities). + * + * It however seems overly complex, and in a way we already do that + * because if we reject the whole clause as unsupported here, it will + * be eventually passed to clauselist_selectivity() which does exactly + * this (split into supported/unsupported clauses etc). + */ + BoolExpr *expr = (BoolExpr *) clause; + ListCell *lc; + + foreach(lc, expr->args) + { + /* + * Had we found incompatible clause in the arguments, treat the + * whole clause as incompatible. + */ + if (!statext_is_compatible_clause_internal(root, + (Node *) lfirst(lc), + relid, attnums)) + return false; + } + + return true; + } + + /* Var IS NULL */ + if (IsA(clause, NullTest)) + { + NullTest *nt = (NullTest *) clause; + + /* + * Only simple (Var IS NULL) expressions supported for now. Maybe we + * could use examine_variable to fix this? + */ + if (!IsA(nt->arg, Var)) + return false; + + return statext_is_compatible_clause_internal(root, (Node *) (nt->arg), + relid, attnums); + } + + return false; +} + +/* + * statext_is_compatible_clause + * Determines if the clause is compatible with MCV lists. + * + * Currently, we only support three types of clauses: + * + * (a) OpExprs of the form (Var op Const), or (Const op Var), where the op + * is one of ("=", "<", ">", ">=", "<=") + * + * (b) (Var IS [NOT] NULL) + * + * (c) combinations using AND/OR/NOT + * + * In the future, the range of supported clauses may be expanded to more + * complex cases, for example (Var op Var). + */ +static bool +statext_is_compatible_clause(PlannerInfo *root, Node *clause, Index relid, + Bitmapset **attnums) +{ + RangeTblEntry *rte = root->simple_rte_array[relid]; + RestrictInfo *rinfo = (RestrictInfo *) clause; + Oid userid; + + if (!IsA(rinfo, RestrictInfo)) + return false; + + /* Pseudoconstants are not really interesting here. */ + if (rinfo->pseudoconstant) + return false; + + /* clauses referencing multiple varnos are incompatible */ + if (bms_membership(rinfo->clause_relids) != BMS_SINGLETON) + return false; + + /* Check the clause and determine what attributes it references. */ + if (!statext_is_compatible_clause_internal(root, (Node *) rinfo->clause, + relid, attnums)) + return false; + + /* + * Check that the user has permission to read all these attributes. Use + * checkAsUser if it's set, in case we're accessing the table via a view. + */ + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + + if (pg_class_aclcheck(rte->relid, userid, ACL_SELECT) != ACLCHECK_OK) + { + /* Don't have table privilege, must check individual columns */ + if (bms_is_member(InvalidAttrNumber, *attnums)) + { + /* Have a whole-row reference, must have access to all columns */ + if (pg_attribute_aclcheck_all(rte->relid, userid, ACL_SELECT, + ACLMASK_ALL) != ACLCHECK_OK) + return false; + } + else + { + /* Check the columns referenced by the clause */ + int attnum = -1; + + while ((attnum = bms_next_member(*attnums, attnum)) >= 0) + { + if (pg_attribute_aclcheck(rte->relid, attnum, userid, + ACL_SELECT) != ACLCHECK_OK) + return false; + } + } + } + + /* If we reach here, the clause is OK */ + return true; +} + +/* + * statext_mcv_clauselist_selectivity + * Estimate clauses using the best multi-column statistics. + * + * Selects the best extended (multi-column) statistic on a table (measured by + * the number of attributes extracted from the clauses and covered by it), and + * computes the selectivity for the supplied clauses. + * + * One of the main challenges with using MCV lists is how to extrapolate the + * estimate to the data not covered by the MCV list. To do that, we compute + * not only the "MCV selectivity" (selectivities for MCV items matching the + * supplied clauses), but also a couple of derived selectivities: + * + * - simple selectivity: Computed without extended statistic, i.e. as if the + * columns/clauses were independent + * + * - base selectivity: Similar to simple selectivity, but is computed using + * the extended statistic by adding up the base frequencies (that we compute + * and store for each MCV item) of matching MCV items. + * + * - total selectivity: Selectivity covered by the whole MCV list. + * + * - other selectivity: A selectivity estimate for data not covered by the MCV + * list (i.e. satisfying the clauses, but not common enough to make it into + * the MCV list) + * + * Note: While simple and base selectivities are defined in a quite similar + * way, the values are computed differently and are not therefore equal. The + * simple selectivity is computed as a product of per-clause estimates, while + * the base selectivity is computed by adding up base frequencies of matching + * items of the multi-column MCV list. So the values may differ for two main + * reasons - (a) the MCV list may not cover 100% of the data and (b) some of + * the MCV items did not match the estimated clauses. + * + * As both (a) and (b) reduce the base selectivity value, it generally holds + * that (simple_selectivity >= base_selectivity). If the MCV list covers all + * the data, the values may be equal. + * + * So, (simple_selectivity - base_selectivity) is an estimate for the part + * not covered by the MCV list, and (mcv_selectivity - base_selectivity) may + * be seen as a correction for the part covered by the MCV list. Those two + * statements are actually equivalent. + * + * Note: Due to rounding errors and minor differences in how the estimates + * are computed, the inequality may not always hold. Which is why we clamp + * the selectivities to prevent strange estimate (negative etc.). + * + * 'estimatedclauses' is an input/output parameter. We set bits for the + * 0-based 'clauses' indexes we estimate for and also skip clause items that + * already have a bit set. + * + * XXX If we were to use multiple statistics, this is where it would happen. + * We would simply repeat this on a loop on the "remaining" clauses, possibly + * using the already estimated clauses as conditions (and combining the values + * using conditional probability formula). + */ +static Selectivity +statext_mcv_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo, + RelOptInfo *rel, Bitmapset **estimatedclauses) +{ + ListCell *l; + Bitmapset *clauses_attnums = NULL; + Bitmapset **list_attnums; + int listidx; + StatisticExtInfo *stat; + List *stat_clauses; + Selectivity simple_sel, + mcv_sel, + mcv_basesel, + mcv_totalsel, + other_sel, + sel; + + /* check if there's any stats that might be useful for us. */ + if (!has_stats_of_kind(rel->statlist, STATS_EXT_MCV)) + return 1.0; + + list_attnums = (Bitmapset **) palloc(sizeof(Bitmapset *) * + list_length(clauses)); + + /* + * Pre-process the clauses list to extract the attnums seen in each item. + * We need to determine if there's any clauses which will be useful for + * selectivity estimations with extended stats. Along the way we'll record + * all of the attnums for each clause in a list which we'll reference + * later so we don't need to repeat the same work again. We'll also keep + * track of all attnums seen. + * + * We also skip clauses that we already estimated using different types of + * statistics (we treat them as incompatible). + */ + listidx = 0; + foreach(l, clauses) + { + Node *clause = (Node *) lfirst(l); + Bitmapset *attnums = NULL; + + if (!bms_is_member(listidx, *estimatedclauses) && + statext_is_compatible_clause(root, clause, rel->relid, &attnums)) + { + list_attnums[listidx] = attnums; + clauses_attnums = bms_add_members(clauses_attnums, attnums); + } + else + list_attnums[listidx] = NULL; + + listidx++; + } + + /* We need at least two attributes for multivariate statistics. */ + if (bms_membership(clauses_attnums) != BMS_MULTIPLE) + return 1.0; + + /* find the best suited statistics object for these attnums */ + stat = choose_best_statistics(rel->statlist, clauses_attnums, STATS_EXT_MCV); + + /* if no matching stats could be found then we've nothing to do */ + if (!stat) + return 1.0; + + /* Ensure choose_best_statistics produced an expected stats type. */ + Assert(stat->kind == STATS_EXT_MCV); + + /* now filter the clauses to be estimated using the selected MCV */ + stat_clauses = NIL; + + listidx = 0; + foreach(l, clauses) + { + /* + * If the clause is compatible with the selected statistics, mark it + * as estimated and add it to the list to estimate. + */ + if (list_attnums[listidx] != NULL && + bms_is_subset(list_attnums[listidx], stat->keys)) + { + stat_clauses = lappend(stat_clauses, (Node *) lfirst(l)); + *estimatedclauses = bms_add_member(*estimatedclauses, listidx); + } + + listidx++; + } + + /* + * First compute "simple" selectivity, i.e. without the extended + * statistics, and essentially assuming independence of the + * columns/clauses. We'll then use the various selectivities computed from + * MCV list to improve it. + */ + simple_sel = clauselist_selectivity_simple(root, stat_clauses, varRelid, + jointype, sjinfo, NULL); + + /* + * Now compute the multi-column estimate from the MCV list, along with the + * other selectivities (base & total selectivity). + */ + mcv_sel = mcv_clauselist_selectivity(root, stat, stat_clauses, varRelid, + jointype, sjinfo, rel, + &mcv_basesel, &mcv_totalsel); + + /* Estimated selectivity of values not covered by MCV matches */ + other_sel = simple_sel - mcv_basesel; + CLAMP_PROBABILITY(other_sel); + + /* The non-MCV selectivity can't exceed the 1 - mcv_totalsel. */ + if (other_sel > 1.0 - mcv_totalsel) + other_sel = 1.0 - mcv_totalsel; + + /* Overall selectivity is the combination of MCV and non-MCV estimates. */ + sel = mcv_sel + other_sel; + CLAMP_PROBABILITY(sel); + + return sel; +} + +/* + * statext_clauselist_selectivity + * Estimate clauses using the best multi-column statistics. + */ +Selectivity +statext_clauselist_selectivity(PlannerInfo *root, List *clauses, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo, + RelOptInfo *rel, Bitmapset **estimatedclauses) +{ + Selectivity sel; + + /* First, try estimating clauses using a multivariate MCV list. */ + sel = statext_mcv_clauselist_selectivity(root, clauses, varRelid, jointype, + sjinfo, rel, estimatedclauses); + + /* + * Then, apply functional dependencies on the remaining clauses by calling + * dependencies_clauselist_selectivity. Pass 'estimatedclauses' so the + * function can properly skip clauses already estimated above. + * + * The reasoning for applying dependencies last is that the more complex + * stats can track more complex correlations between the attributes, and + * so may be considered more reliable. + * + * For example, MCV list can give us an exact selectivity for values in + * two columns, while functional dependencies can only provide information + * about the overall strength of the dependency. + */ + sel *= dependencies_clauselist_selectivity(root, clauses, varRelid, + jointype, sjinfo, rel, + estimatedclauses); + + return sel; +} + +/* + * examine_opclause_expression + * Split expression into Var and Const parts. + * + * Attempts to match the arguments to either (Var op Const) or (Const op Var), + * possibly with a RelabelType on top. When the expression matches this form, + * returns true, otherwise returns false. + * + * Optionally returns pointers to the extracted Var/Const nodes, when passed + * non-null pointers (varp, cstp and varonleftp). The varonleftp flag specifies + * on which side of the operator we found the Var node. + */ +bool +examine_opclause_expression(OpExpr *expr, Var **varp, Const **cstp, bool *varonleftp) +{ + Var *var; + Const *cst; + bool varonleft; + Node *leftop, + *rightop; + + /* enforced by statext_is_compatible_clause_internal */ + Assert(list_length(expr->args) == 2); + + leftop = linitial(expr->args); + rightop = lsecond(expr->args); + + /* strip RelabelType from either side of the expression */ + if (IsA(leftop, RelabelType)) + leftop = (Node *) ((RelabelType *) leftop)->arg; + + if (IsA(rightop, RelabelType)) + rightop = (Node *) ((RelabelType *) rightop)->arg; + + if (IsA(leftop, Var) && IsA(rightop, Const)) + { + var = (Var *) leftop; + cst = (Const *) rightop; + varonleft = true; + } + else if (IsA(leftop, Const) && IsA(rightop, Var)) + { + var = (Var *) rightop; + cst = (Const *) leftop; + varonleft = false; + } + else + return false; + + /* return pointers to the extracted parts if requested */ + if (varp) + *varp = var; + + if (cstp) + *cstp = cst; + + if (varonleftp) + *varonleftp = varonleft; + + return true; +} diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c new file mode 100644 index 00000000000..ee35f6afc56 --- /dev/null +++ b/src/backend/statistics/mcv.c @@ -0,0 +1,1829 @@ +/*------------------------------------------------------------------------- + * + * mcv.c + * POSTGRES multivariate MCV lists + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/statistics/mcv.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "access/htup_details.h" +#include "catalog/pg_collation.h" +#include "catalog/pg_statistic_ext.h" +#include "catalog/pg_statistic_ext_data.h" +#include "fmgr.h" +#include "funcapi.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/clauses.h" +#include "statistics/extended_stats_internal.h" +#include "statistics/statistics.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/bytea.h" +#include "utils/fmgroids.h" +#include "utils/fmgrprotos.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" +#include "utils/typcache.h" + +/* + * Computes size of a serialized MCV item, depending on the number of + * dimensions (columns) the statistic is defined on. The datum values are + * stored in a separate array (deduplicated, to minimize the size), and + * so the serialized items only store uint16 indexes into that array. + * + * Each serialized item stores (in this order): + * + * - indexes to values (ndim * sizeof(uint16)) + * - null flags (ndim * sizeof(bool)) + * - frequency (sizeof(double)) + * - base_frequency (sizeof(double)) + * + * There is no alignment padding within an MCV item. + * So in total each MCV item requires this many bytes: + * + * ndim * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double) + */ +#define ITEM_SIZE(ndims) \ + ((ndims) * (sizeof(uint16) + sizeof(bool)) + 2 * sizeof(double)) + +/* + * Used to compute size of serialized MCV list representation. + */ +#define MinSizeOfMCVList \ + (VARHDRSZ + sizeof(uint32) * 3 + sizeof(AttrNumber)) + +/* + * Size of the serialized MCV list, excluding the space needed for + * deduplicated per-dimension values. The macro is meant to be used + * when it's not yet safe to access the serialized info about amount + * of data for each column. + */ +#define SizeOfMCVList(ndims,nitems) \ + ((MinSizeOfMCVList + sizeof(Oid) * (ndims)) + \ + ((ndims) * sizeof(DimensionInfo)) + \ + ((nitems) * ITEM_SIZE(ndims))) + +static MultiSortSupport build_mss(VacAttrStats **stats, int numattrs); + +static SortItem *build_distinct_groups(int numrows, SortItem *items, + MultiSortSupport mss, int *ndistinct); + +static SortItem **build_column_frequencies(SortItem *groups, int ngroups, + MultiSortSupport mss, int *ncounts); + +static int count_distinct_groups(int numrows, SortItem *items, + MultiSortSupport mss); + +/* + * Compute new value for bitmap item, considering whether it's used for + * clauses connected by AND/OR. + */ +#define RESULT_MERGE(value, is_or, match) \ + ((is_or) ? ((value) || (match)) : ((value) && (match))) + +/* + * When processing a list of clauses, the bitmap item may get set to a value + * such that additional clauses can't change it. For example, when processing + * a list of clauses connected to AND, as soon as the item gets set to 'false' + * then it'll remain like that. Similarly clauses connected by OR and 'true'. + * + * Returns true when the value in the bitmap can't change no matter how the + * remaining clauses are evaluated. + */ +#define RESULT_IS_FINAL(value, is_or) ((is_or) ? (value) : (!(value))) + +/* + * get_mincount_for_mcv_list + * Determine the minimum number of times a value needs to appear in + * the sample for it to be included in the MCV list. + * + * We want to keep only values that appear sufficiently often in the + * sample that it is reasonable to extrapolate their sample frequencies to + * the entire table. We do this by placing an upper bound on the relative + * standard error of the sample frequency, so that any estimates the + * planner generates from the MCV statistics can be expected to be + * reasonably accurate. + * + * Since we are sampling without replacement, the sample frequency of a + * particular value is described by a hypergeometric distribution. A + * common rule of thumb when estimating errors in this situation is to + * require at least 10 instances of the value in the sample, in which case + * the distribution can be approximated by a normal distribution, and + * standard error analysis techniques can be applied. Given a sample size + * of n, a population size of N, and a sample frequency of p=cnt/n, the + * standard error of the proportion p is given by + * SE = sqrt(p*(1-p)/n) * sqrt((N-n)/(N-1)) + * where the second term is the finite population correction. To get + * reasonably accurate planner estimates, we impose an upper bound on the + * relative standard error of 20% -- i.e., SE/p < 0.2. This 20% relative + * error bound is fairly arbitrary, but has been found empirically to work + * well. Rearranging this formula gives a lower bound on the number of + * instances of the value seen: + * cnt > n*(N-n) / (N-n+0.04*n*(N-1)) + * This bound is at most 25, and approaches 0 as n approaches 0 or N. The + * case where n approaches 0 cannot happen in practice, since the sample + * size is at least 300. The case where n approaches N corresponds to + * sampling the whole the table, in which case it is reasonable to keep + * the whole MCV list (have no lower bound), so it makes sense to apply + * this formula for all inputs, even though the above derivation is + * technically only valid when the right hand side is at least around 10. + * + * An alternative way to look at this formula is as follows -- assume that + * the number of instances of the value seen scales up to the entire + * table, so that the population count is K=N*cnt/n. Then the distribution + * in the sample is a hypergeometric distribution parameterised by N, n + * and K, and the bound above is mathematically equivalent to demanding + * that the standard deviation of that distribution is less than 20% of + * its mean. Thus the relative errors in any planner estimates produced + * from the MCV statistics are likely to be not too large. + */ +static double +get_mincount_for_mcv_list(int samplerows, double totalrows) +{ + double n = samplerows; + double N = totalrows; + double numer, + denom; + + numer = n * (N - n); + denom = N - n + 0.04 * n * (N - 1); + + /* Guard against division by zero (possible if n = N = 1) */ + if (denom == 0.0) + return 0.0; + + return numer / denom; +} + +/* + * Builds MCV list from the set of sampled rows. + * + * The algorithm is quite simple: + * + * (1) sort the data (default collation, '<' for the data type) + * + * (2) count distinct groups, decide how many to keep + * + * (3) build the MCV list using the threshold determined in (2) + * + * (4) remove rows represented by the MCV from the sample + * + */ +MCVList * +statext_mcv_build(int numrows, HeapTuple *rows, Bitmapset *attrs, + VacAttrStats **stats, double totalrows, int stattarget) +{ + int i, + numattrs, + ngroups, + nitems; + AttrNumber *attnums; + double mincount; + SortItem *items; + SortItem *groups; + MCVList *mcvlist = NULL; + MultiSortSupport mss; + + attnums = build_attnums_array(attrs, &numattrs); + + /* comparator for all the columns */ + mss = build_mss(stats, numattrs); + + /* sort the rows */ + items = build_sorted_items(numrows, &nitems, rows, stats[0]->tupDesc, + mss, numattrs, attnums); + + if (!items) + return NULL; + + /* transform the sorted rows into groups (sorted by frequency) */ + groups = build_distinct_groups(nitems, items, mss, &ngroups); + + /* + * Maximum number of MCV items to store, based on the statistics target + * we computed for the statistics object (from target set for the object + * itself, attributes and the system default). In any case, we can't keep + * more groups than we have available. + */ + nitems = stattarget; + if (nitems > ngroups) + nitems = ngroups; + + /* + * Decide how many items to keep in the MCV list. We can't use the same + * algorithm as per-column MCV lists, because that only considers the + * actual group frequency - but we're primarily interested in how the + * actual frequency differs from the base frequency (product of simple + * per-column frequencies, as if the columns were independent). + * + * Using the same algorithm might exclude items that are close to the + * "average" frequency of the sample. But that does not say whether the + * observed frequency is close to the base frequency or not. We also need + * to consider unexpectedly uncommon items (again, compared to the base + * frequency), and the single-column algorithm does not have to. + * + * We simply decide how many items to keep by computing minimum count + * using get_mincount_for_mcv_list() and then keep all items that seem to + * be more common than that. + */ + mincount = get_mincount_for_mcv_list(numrows, totalrows); + + /* + * Walk the groups until we find the first group with a count below the + * mincount threshold (the index of that group is the number of groups we + * want to keep). + */ + for (i = 0; i < nitems; i++) + { + if (groups[i].count < mincount) + { + nitems = i; + break; + } + } + + /* + * At this point we know the number of items for the MCV list. There might + * be none (for uniform distribution with many groups), and in that case + * there will be no MCV list. Otherwise construct the MCV list. + */ + if (nitems > 0) + { + int j; + SortItem key; + MultiSortSupport tmp; + + /* frequencies for values in each attribute */ + SortItem **freqs; + int *nfreqs; + + /* used to search values */ + tmp = (MultiSortSupport) palloc(offsetof(MultiSortSupportData, ssup) + + sizeof(SortSupportData)); + + /* compute frequencies for values in each column */ + nfreqs = (int *) palloc0(sizeof(int) * numattrs); + freqs = build_column_frequencies(groups, ngroups, mss, nfreqs); + + /* + * Allocate the MCV list structure, set the global parameters. + */ + mcvlist = (MCVList *) palloc0(offsetof(MCVList, items) + + sizeof(MCVItem) * nitems); + + mcvlist->magic = STATS_MCV_MAGIC; + mcvlist->type = STATS_MCV_TYPE_BASIC; + mcvlist->ndimensions = numattrs; + mcvlist->nitems = nitems; + + /* store info about data type OIDs */ + for (i = 0; i < numattrs; i++) + mcvlist->types[i] = stats[i]->attrtypid; + + /* Copy the first chunk of groups into the result. */ + for (i = 0; i < nitems; i++) + { + /* just pointer to the proper place in the list */ + MCVItem *item = &mcvlist->items[i]; + + item->values = (Datum *) palloc(sizeof(Datum) * numattrs); + item->isnull = (bool *) palloc(sizeof(bool) * numattrs); + + /* copy values for the group */ + memcpy(item->values, groups[i].values, sizeof(Datum) * numattrs); + memcpy(item->isnull, groups[i].isnull, sizeof(bool) * numattrs); + + /* groups should be sorted by frequency in descending order */ + Assert((i == 0) || (groups[i - 1].count >= groups[i].count)); + + /* group frequency */ + item->frequency = (double) groups[i].count / numrows; + + /* base frequency, if the attributes were independent */ + item->base_frequency = 1.0; + for (j = 0; j < numattrs; j++) + { + SortItem *freq; + + /* single dimension */ + tmp->ndims = 1; + tmp->ssup[0] = mss->ssup[j]; + + /* fill search key */ + key.values = &groups[i].values[j]; + key.isnull = &groups[i].isnull[j]; + + freq = (SortItem *) bsearch_arg(&key, freqs[j], nfreqs[j], + sizeof(SortItem), + multi_sort_compare, tmp); + + item->base_frequency *= ((double) freq->count) / numrows; + } + } + + pfree(nfreqs); + pfree(freqs); + } + + pfree(items); + pfree(groups); + + return mcvlist; +} + +/* + * build_mss + * build MultiSortSupport for the attributes passed in attrs + */ +static MultiSortSupport +build_mss(VacAttrStats **stats, int numattrs) +{ + int i; + + /* Sort by multiple columns (using array of SortSupport) */ + MultiSortSupport mss = multi_sort_init(numattrs); + + /* prepare the sort functions for all the attributes */ + for (i = 0; i < numattrs; i++) + { + VacAttrStats *colstat = stats[i]; + TypeCacheEntry *type; + + type = lookup_type_cache(colstat->attrtypid, TYPECACHE_LT_OPR); + if (type->lt_opr == InvalidOid) /* shouldn't happen */ + elog(ERROR, "cache lookup failed for ordering operator for type %u", + colstat->attrtypid); + + multi_sort_add_dimension(mss, i, type->lt_opr, colstat->attrcollid); + } + + return mss; +} + +/* + * count_distinct_groups + * count distinct combinations of SortItems in the array + * + * The array is assumed to be sorted according to the MultiSortSupport. + */ +static int +count_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss) +{ + int i; + int ndistinct; + + ndistinct = 1; + for (i = 1; i < numrows; i++) + { + /* make sure the array really is sorted */ + Assert(multi_sort_compare(&items[i], &items[i - 1], mss) >= 0); + + if (multi_sort_compare(&items[i], &items[i - 1], mss) != 0) + ndistinct += 1; + } + + return ndistinct; +} + +/* + * compare_sort_item_count + * comparator for sorting items by count (frequencies) in descending order + */ +static int +compare_sort_item_count(const void *a, const void *b) +{ + SortItem *ia = (SortItem *) a; + SortItem *ib = (SortItem *) b; + + if (ia->count == ib->count) + return 0; + else if (ia->count > ib->count) + return -1; + + return 1; +} + +/* + * build_distinct_groups + * build an array of SortItems for distinct groups and counts matching items + * + * The input array is assumed to be sorted + */ +static SortItem * +build_distinct_groups(int numrows, SortItem *items, MultiSortSupport mss, + int *ndistinct) +{ + int i, + j; + int ngroups = count_distinct_groups(numrows, items, mss); + + SortItem *groups = (SortItem *) palloc(ngroups * sizeof(SortItem)); + + j = 0; + groups[0] = items[0]; + groups[0].count = 1; + + for (i = 1; i < numrows; i++) + { + /* Assume sorted in ascending order. */ + Assert(multi_sort_compare(&items[i], &items[i - 1], mss) >= 0); + + /* New distinct group detected. */ + if (multi_sort_compare(&items[i], &items[i - 1], mss) != 0) + { + groups[++j] = items[i]; + groups[j].count = 0; + } + + groups[j].count++; + } + + /* ensure we filled the expected number of distinct groups */ + Assert(j + 1 == ngroups); + + /* Sort the distinct groups by frequency (in descending order). */ + pg_qsort((void *) groups, ngroups, sizeof(SortItem), + compare_sort_item_count); + + *ndistinct = ngroups; + return groups; +} + +/* compare sort items (single dimension) */ +static int +sort_item_compare(const void *a, const void *b, void *arg) +{ + SortSupport ssup = (SortSupport) arg; + SortItem *ia = (SortItem *) a; + SortItem *ib = (SortItem *) b; + + return ApplySortComparator(ia->values[0], ia->isnull[0], + ib->values[0], ib->isnull[0], + ssup); +} + +/* + * build_column_frequencies + * compute frequencies of values in each column + * + * This returns an array of SortItems for each attibute the MCV is built + * on, with a frequency (number of occurrences) for each value. This is + * then used to compute "base" frequency of MCV items. + * + * All the memory is allocated in a single chunk, so that a single pfree + * is enough to release it. We do not allocate space for values/isnull + * arrays in the SortItems, because we can simply point into the input + * groups directly. + */ +static SortItem ** +build_column_frequencies(SortItem *groups, int ngroups, + MultiSortSupport mss, int *ncounts) +{ + int i, + dim; + SortItem **result; + char *ptr; + + Assert(groups); + Assert(ncounts); + + /* allocate arrays for all columns as a single chunk */ + ptr = palloc(MAXALIGN(sizeof(SortItem *) * mss->ndims) + + mss->ndims * MAXALIGN(sizeof(SortItem) * ngroups)); + + /* initial array of pointers */ + result = (SortItem **) ptr; + ptr += MAXALIGN(sizeof(SortItem *) * mss->ndims); + + for (dim = 0; dim < mss->ndims; dim++) + { + SortSupport ssup = &mss->ssup[dim]; + + /* array of values for a single column */ + result[dim] = (SortItem *) ptr; + ptr += MAXALIGN(sizeof(SortItem) * ngroups); + + /* extract data for the dimension */ + for (i = 0; i < ngroups; i++) + { + /* point into the input groups */ + result[dim][i].values = &groups[i].values[dim]; + result[dim][i].isnull = &groups[i].isnull[dim]; + result[dim][i].count = groups[i].count; + } + + /* sort the values, deduplicate */ + qsort_arg((void *) result[dim], ngroups, sizeof(SortItem), + sort_item_compare, ssup); + + /* + * Identify distinct values, compute frequency (there might be + * multiple MCV items containing this value, so we need to sum + * counts from all of them. + */ + ncounts[dim] = 1; + for (i = 1; i < ngroups; i++) + { + if (sort_item_compare(&result[dim][i-1], &result[dim][i], ssup) == 0) + { + result[dim][ncounts[dim]-1].count += result[dim][i].count; + continue; + } + + result[dim][ncounts[dim]] = result[dim][i]; + + ncounts[dim]++; + } + } + + return result; +} + +/* + * statext_mcv_load + * Load the MCV list for the indicated pg_statistic_ext tuple + */ +MCVList * +statext_mcv_load(Oid mvoid) +{ + MCVList *result; + bool isnull; + Datum mcvlist; + HeapTuple htup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(mvoid)); + + if (!HeapTupleIsValid(htup)) + elog(ERROR, "cache lookup failed for statistics object %u", mvoid); + + mcvlist = SysCacheGetAttr(STATEXTDATASTXOID, htup, + Anum_pg_statistic_ext_data_stxdmcv, &isnull); + + if (isnull) + elog(ERROR, + "requested statistic kind \"%c\" is not yet built for statistics object %u", + STATS_EXT_DEPENDENCIES, mvoid); + + result = statext_mcv_deserialize(DatumGetByteaP(mcvlist)); + + ReleaseSysCache(htup); + + return result; +} + + +/* + * statext_mcv_serialize + * Serialize MCV list into a pg_mcv_list value. + * + * The MCV items may include values of various data types, and it's reasonable + * to expect redundancy (values for a given attribute, repeated for multiple + * MCV list items). So we deduplicate the values into arrays, and then replace + * the values by indexes into those arrays. + * + * The overall structure of the serialized representation looks like this: + * + * +---------------+----------------+---------------------+-------+ + * | header fields | dimension info | deduplicated values | items | + * +---------------+----------------+---------------------+-------+ + * + * Where dimension info stores information about type of K-th attribute (e.g. + * typlen, typbyval and length of deduplicated values). Deduplicated values + * store deduplicated values for each attribute. And items store the actual + * MCV list items, with values replaced by indexes into the arrays. + * + * When serializing the items, we use uint16 indexes. The number of MCV items + * is limited by the statistics target (which is capped to 10k at the moment). + * We might increase this to 65k and still fit into uint16, so there's a bit of + * slack. Furthermore, this limit is on the number of distinct values per column, + * and we usually have few of those (and various combinations of them for the + * those MCV list). So uint16 seems fine for now. + * + * We don't really expect the serialization to save as much space as for + * histograms, as we are not doing any bucket splits (which is the source + * of high redundancy in histograms). + * + * TODO: Consider packing boolean flags (NULL) for each item into a single char + * (or a longer type) instead of using an array of bool items. + */ +bytea * +statext_mcv_serialize(MCVList *mcvlist, VacAttrStats **stats) +{ + int i; + int dim; + int ndims = mcvlist->ndimensions; + + SortSupport ssup; + DimensionInfo *info; + + Size total_length; + + /* serialized items (indexes into arrays, etc.) */ + bytea *raw; + char *ptr; + char *endptr PG_USED_FOR_ASSERTS_ONLY; + + /* values per dimension (and number of non-NULL values) */ + Datum **values = (Datum **) palloc0(sizeof(Datum *) * ndims); + int *counts = (int *) palloc0(sizeof(int) * ndims); + + /* + * We'll include some rudimentary information about the attribute types + * (length, by-val flag), so that we don't have to look them up while + * deserializating the MCV list (we already have the type OID in the + * header). This is safe, because when changing type of the attribute the + * statistics gets dropped automatically. We need to store the info about + * the arrays of deduplicated values anyway. + */ + info = (DimensionInfo *) palloc0(sizeof(DimensionInfo) * ndims); + + /* sort support data for all attributes included in the MCV list */ + ssup = (SortSupport) palloc0(sizeof(SortSupportData) * ndims); + + /* collect and deduplicate values for each dimension (attribute) */ + for (dim = 0; dim < ndims; dim++) + { + int ndistinct; + TypeCacheEntry *typentry; + + /* + * Lookup the LT operator (can't get it from stats extra_data, as we + * don't know how to interpret that - scalar vs. array etc.). + */ + typentry = lookup_type_cache(stats[dim]->attrtypid, TYPECACHE_LT_OPR); + + /* copy important info about the data type (length, by-value) */ + info[dim].typlen = stats[dim]->attrtype->typlen; + info[dim].typbyval = stats[dim]->attrtype->typbyval; + + /* allocate space for values in the attribute and collect them */ + values[dim] = (Datum *) palloc0(sizeof(Datum) * mcvlist->nitems); + + for (i = 0; i < mcvlist->nitems; i++) + { + /* skip NULL values - we don't need to deduplicate those */ + if (mcvlist->items[i].isnull[dim]) + continue; + + /* append the value at the end */ + values[dim][counts[dim]] = mcvlist->items[i].values[dim]; + counts[dim] += 1; + } + + /* if there are just NULL values in this dimension, we're done */ + if (counts[dim] == 0) + continue; + + /* sort and deduplicate the data */ + ssup[dim].ssup_cxt = CurrentMemoryContext; + ssup[dim].ssup_collation = stats[dim]->attrcollid; + ssup[dim].ssup_nulls_first = false; + + PrepareSortSupportFromOrderingOp(typentry->lt_opr, &ssup[dim]); + + qsort_arg(values[dim], counts[dim], sizeof(Datum), + compare_scalars_simple, &ssup[dim]); + + /* + * Walk through the array and eliminate duplicate values, but keep the + * ordering (so that we can do bsearch later). We know there's at + * least one item as (counts[dim] != 0), so we can skip the first + * element. + */ + ndistinct = 1; /* number of distinct values */ + for (i = 1; i < counts[dim]; i++) + { + /* expect sorted array */ + Assert(compare_datums_simple(values[dim][i - 1], values[dim][i], &ssup[dim]) <= 0); + + /* if the value is the same as the previous one, we can skip it */ + if (!compare_datums_simple(values[dim][i - 1], values[dim][i], &ssup[dim])) + continue; + + values[dim][ndistinct] = values[dim][i]; + ndistinct += 1; + } + + /* we must not exceed PG_UINT16_MAX, as we use uint16 indexes */ + Assert(ndistinct <= PG_UINT16_MAX); + + /* + * Store additional info about the attribute - number of deduplicated + * values, and also size of the serialized data. For fixed-length data + * types this is trivial to compute, for varwidth types we need to + * actually walk the array and sum the sizes. + */ + info[dim].nvalues = ndistinct; + + if (info[dim].typbyval) /* by-value data types */ + { + info[dim].nbytes = info[dim].nvalues * info[dim].typlen; + + /* + * We copy the data into the MCV item during deserialization, so + * we don't need to allocate any extra space. + */ + info[dim].nbytes_aligned = 0; + } + else if (info[dim].typlen > 0) /* fixed-length by-ref */ + { + /* + * We don't care about alignment in the serialized data, so we + * pack the data as much as possible. But we also track how much + * data will be needed after deserialization, and in that case + * we need to account for alignment of each item. + * + * Note: As the items are fixed-length, we could easily compute + * this during deserialization, but we do it here anyway. + */ + info[dim].nbytes = info[dim].nvalues * info[dim].typlen; + info[dim].nbytes_aligned = info[dim].nvalues * MAXALIGN(info[dim].typlen); + } + else if (info[dim].typlen == -1) /* varlena */ + { + info[dim].nbytes = 0; + info[dim].nbytes_aligned = 0; + for (i = 0; i < info[dim].nvalues; i++) + { + Size len; + + /* + * For varlena values, we detoast the values and store the + * length and data separately. We don't bother with alignment + * here, which means that during deserialization we need to + * copy the fields and only access the copies. + */ + values[dim][i] = PointerGetDatum(PG_DETOAST_DATUM(values[dim][i])); + + /* serialized length (uint32 length + data) */ + len = VARSIZE_ANY_EXHDR(values[dim][i]); + info[dim].nbytes += sizeof(uint32); /* length */ + info[dim].nbytes += len; /* value (no header) */ + + /* + * During deserialization we'll build regular varlena values + * with full headers, and we need to align them properly. + */ + info[dim].nbytes_aligned += MAXALIGN(VARHDRSZ + len); + } + } + else if (info[dim].typlen == -2) /* cstring */ + { + info[dim].nbytes = 0; + info[dim].nbytes_aligned = 0; + for (i = 0; i < info[dim].nvalues; i++) + { + Size len; + + /* + * For cstring, we do similar thing as for varlena - first we + * store the length as uint32 and then the data. We don't care + * about alignment, which means that during deserialization we + * need to copy the fields and only access the copies. + */ + + /* c-strings include terminator, so +1 byte */ + len = strlen(DatumGetCString(values[dim][i])) + 1; + info[dim].nbytes += sizeof(uint32); /* length */ + info[dim].nbytes += len; /* value */ + + /* space needed for properly aligned deserialized copies */ + info[dim].nbytes_aligned += MAXALIGN(len); + } + } + + /* we know (count>0) so there must be some data */ + Assert(info[dim].nbytes > 0); + } + + /* + * Now we can finally compute how much space we'll actually need for the + * whole serialized MCV list (varlena header, MCV header, dimension info + * for each attribute, deduplicated values and items). + */ + total_length = (3 * sizeof(uint32)) /* magic + type + nitems */ + + sizeof(AttrNumber) /* ndimensions */ + + (ndims * sizeof(Oid)); /* attribute types */ + + /* dimension info */ + total_length += ndims * sizeof(DimensionInfo); + + /* add space for the arrays of deduplicated values */ + for (i = 0; i < ndims; i++) + total_length += info[i].nbytes; + + /* + * And finally account for the items (those are fixed-length, thanks to + * replacing values with uint16 indexes into the deduplicated arrays). + */ + total_length += mcvlist->nitems * ITEM_SIZE(dim); + + /* + * Allocate space for the whole serialized MCV list (we'll skip bytes, so + * we set them to zero to make the result more compressible). + */ + raw = (bytea *) palloc0(VARHDRSZ + total_length); + SET_VARSIZE(raw, VARHDRSZ + total_length); + + ptr = VARDATA(raw); + endptr = ptr + total_length; + + /* copy the MCV list header fields, one by one */ + memcpy(ptr, &mcvlist->magic, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(ptr, &mcvlist->type, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(ptr, &mcvlist->nitems, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(ptr, &mcvlist->ndimensions, sizeof(AttrNumber)); + ptr += sizeof(AttrNumber); + + memcpy(ptr, mcvlist->types, sizeof(Oid) * ndims); + ptr += (sizeof(Oid) * ndims); + + /* store information about the attributes (data amounts, ...) */ + memcpy(ptr, info, sizeof(DimensionInfo) * ndims); + ptr += sizeof(DimensionInfo) * ndims; + + /* Copy the deduplicated values for all attributes to the output. */ + for (dim = 0; dim < ndims; dim++) + { + /* remember the starting point for Asserts later */ + char *start PG_USED_FOR_ASSERTS_ONLY = ptr; + + for (i = 0; i < info[dim].nvalues; i++) + { + Datum value = values[dim][i]; + + if (info[dim].typbyval) /* passed by value */ + { + Datum tmp; + + /* + * For values passed by value, we need to copy just the + * significant bytes - we can't use memcpy directly, as that + * assumes little endian behavior. store_att_byval does + * almost what we need, but it requires properly aligned + * buffer - the output buffer does not guarantee that. So we + * simply use a local Datum variable (which guarantees proper + * alignment), and then copy the value from it. + */ + store_att_byval(&tmp, value, info[dim].typlen); + + memcpy(ptr, &tmp, info[dim].typlen); + ptr += info[dim].typlen; + } + else if (info[dim].typlen > 0) /* passed by reference */ + { + /* no special alignment needed, treated as char array */ + memcpy(ptr, DatumGetPointer(value), info[dim].typlen); + ptr += info[dim].typlen; + } + else if (info[dim].typlen == -1) /* varlena */ + { + uint32 len = VARSIZE_ANY_EXHDR(DatumGetPointer(value)); + + /* copy the length */ + memcpy(ptr, &len, sizeof(uint32)); + ptr += sizeof(uint32); + + /* data from the varlena value (without the header) */ + memcpy(ptr, VARDATA_ANY(DatumGetPointer(value)), len); + ptr += len; + } + else if (info[dim].typlen == -2) /* cstring */ + { + uint32 len = (uint32) strlen(DatumGetCString(value)) + 1; + + /* copy the length */ + memcpy(ptr, &len, sizeof(uint32)); + ptr += sizeof(uint32); + + /* value */ + memcpy(ptr, DatumGetCString(value), len); + ptr += len; + } + + /* no underflows or overflows */ + Assert((ptr > start) && ((ptr - start) <= info[dim].nbytes)); + } + + /* we should get exactly nbytes of data for this dimension */ + Assert((ptr - start) == info[dim].nbytes); + } + + /* Serialize the items, with uint16 indexes instead of the values. */ + for (i = 0; i < mcvlist->nitems; i++) + { + MCVItem *mcvitem = &mcvlist->items[i]; + + /* don't write beyond the allocated space */ + Assert(ptr <= (endptr - ITEM_SIZE(dim))); + + /* copy NULL and frequency flags into the serialized MCV */ + memcpy(ptr, mcvitem->isnull, sizeof(bool) * ndims); + ptr += sizeof(bool) * ndims; + + memcpy(ptr, &mcvitem->frequency, sizeof(double)); + ptr += sizeof(double); + + memcpy(ptr, &mcvitem->base_frequency, sizeof(double)); + ptr += sizeof(double); + + /* store the indexes last */ + for (dim = 0; dim < ndims; dim++) + { + uint16 index = 0; + Datum *value; + + /* do the lookup only for non-NULL values */ + if (!mcvitem->isnull[dim]) + { + value = (Datum *) bsearch_arg(&mcvitem->values[dim], values[dim], + info[dim].nvalues, sizeof(Datum), + compare_scalars_simple, &ssup[dim]); + + Assert(value != NULL); /* serialization or deduplication error */ + + /* compute index within the deduplicated array */ + index = (uint16) (value - values[dim]); + + /* check the index is within expected bounds */ + Assert(index < info[dim].nvalues); + } + + /* copy the index into the serialized MCV */ + memcpy(ptr, &index, sizeof(uint16)); + ptr += sizeof(uint16); + } + + /* make sure we don't overflow the allocated value */ + Assert(ptr <= endptr); + } + + /* at this point we expect to match the total_length exactly */ + Assert(ptr == endptr); + + pfree(values); + pfree(counts); + + return raw; +} + +/* + * statext_mcv_deserialize + * Reads serialized MCV list into MCVList structure. + * + * All the memory needed by the MCV list is allocated as a single chunk, so + * it's possible to simply pfree() it at once. + */ +MCVList * +statext_mcv_deserialize(bytea *data) +{ + int dim, + i; + Size expected_size; + MCVList *mcvlist; + char *raw; + char *ptr; + char *endptr PG_USED_FOR_ASSERTS_ONLY; + + int ndims, + nitems; + DimensionInfo *info = NULL; + + /* local allocation buffer (used only for deserialization) */ + Datum **map = NULL; + + /* MCV list */ + Size mcvlen; + + /* buffer used for the result */ + Size datalen; + char *dataptr; + char *valuesptr; + char *isnullptr; + + if (data == NULL) + return NULL; + + /* + * We can't possibly deserialize a MCV list if there's not even a complete + * header. We need an explicit formula here, because we serialize the + * header fields one by one, so we need to ignore struct alignment. + */ + if (VARSIZE_ANY(data) < MinSizeOfMCVList) + elog(ERROR, "invalid MCV size %zd (expected at least %zu)", + VARSIZE_ANY(data), MinSizeOfMCVList); + + /* read the MCV list header */ + mcvlist = (MCVList *) palloc0(offsetof(MCVList, items)); + + /* pointer to the data part (skip the varlena header) */ + raw = (char *) data; + ptr = VARDATA_ANY(raw); + endptr = (char *) raw + VARSIZE_ANY(data); + + /* get the header and perform further sanity checks */ + memcpy(&mcvlist->magic, ptr, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(&mcvlist->type, ptr, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(&mcvlist->nitems, ptr, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(&mcvlist->ndimensions, ptr, sizeof(AttrNumber)); + ptr += sizeof(AttrNumber); + + if (mcvlist->magic != STATS_MCV_MAGIC) + elog(ERROR, "invalid MCV magic %u (expected %u)", + mcvlist->magic, STATS_MCV_MAGIC); + + if (mcvlist->type != STATS_MCV_TYPE_BASIC) + elog(ERROR, "invalid MCV type %u (expected %u)", + mcvlist->type, STATS_MCV_TYPE_BASIC); + + if (mcvlist->ndimensions == 0) + elog(ERROR, "invalid zero-length dimension array in MCVList"); + else if ((mcvlist->ndimensions > STATS_MAX_DIMENSIONS) || + (mcvlist->ndimensions < 0)) + elog(ERROR, "invalid length (%d) dimension array in MCVList", + mcvlist->ndimensions); + + if (mcvlist->nitems == 0) + elog(ERROR, "invalid zero-length item array in MCVList"); + else if (mcvlist->nitems > STATS_MCVLIST_MAX_ITEMS) + elog(ERROR, "invalid length (%u) item array in MCVList", + mcvlist->nitems); + + nitems = mcvlist->nitems; + ndims = mcvlist->ndimensions; + + /* + * Check amount of data including DimensionInfo for all dimensions and + * also the serialized items (including uint16 indexes). Also, walk + * through the dimension information and add it to the sum. + */ + expected_size = SizeOfMCVList(ndims, nitems); + + /* + * Check that we have at least the dimension and info records, along with + * the items. We don't know the size of the serialized values yet. We need + * to do this check first, before accessing the dimension info. + */ + if (VARSIZE_ANY(data) < expected_size) + elog(ERROR, "invalid MCV size %zd (expected %zu)", + VARSIZE_ANY(data), expected_size); + + /* Now copy the array of type Oids. */ + memcpy(mcvlist->types, ptr, sizeof(Oid) * ndims); + ptr += (sizeof(Oid) * ndims); + + /* Now it's safe to access the dimension info. */ + info = palloc(ndims * sizeof(DimensionInfo)); + + memcpy(info, ptr, ndims * sizeof(DimensionInfo)); + ptr += (ndims * sizeof(DimensionInfo)); + + /* account for the value arrays */ + for (dim = 0; dim < ndims; dim++) + { + /* + * XXX I wonder if we can/should rely on asserts here. Maybe those + * checks should be done every time? + */ + Assert(info[dim].nvalues >= 0); + Assert(info[dim].nbytes >= 0); + + expected_size += info[dim].nbytes; + } + + /* + * Now we know the total expected MCV size, including all the pieces + * (header, dimension info. items and deduplicated data). So do the final + * check on size. + */ + if (VARSIZE_ANY(data) != expected_size) + elog(ERROR, "invalid MCV size %zd (expected %zu)", + VARSIZE_ANY(data), expected_size); + + /* + * We need an array of Datum values for each dimension, so that we can + * easily translate the uint16 indexes later. We also need a top-level + * array of pointers to those per-dimension arrays. + * + * While allocating the arrays for dimensions, compute how much space we + * need for a copy of the by-ref data, as we can't simply point to the + * original values (it might go away). + */ + datalen = 0; /* space for by-ref data */ + map = (Datum **) palloc(ndims * sizeof(Datum *)); + + for (dim = 0; dim < ndims; dim++) + { + map[dim] = (Datum *) palloc(sizeof(Datum) * info[dim].nvalues); + + /* space needed for a copy of data for by-ref types */ + datalen += info[dim].nbytes_aligned; + } + + /* + * Now resize the MCV list so that the allocation includes all the data. + * + * Allocate space for a copy of the data, as we can't simply reference the + * serialized data - it's not aligned properly, and it may disappear while + * we're still using the MCV list, e.g. due to catcache release. + * + * We do care about alignment here, because we will allocate all the pieces + * at once, but then use pointers to different parts. + */ + mcvlen = MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems)); + + /* arrays of values and isnull flags for all MCV items */ + mcvlen += nitems * MAXALIGN(sizeof(Datum) * ndims); + mcvlen += nitems * MAXALIGN(sizeof(bool) * ndims); + + /* we don't quite need to align this, but it makes some asserts easier */ + mcvlen += MAXALIGN(datalen); + + /* now resize the deserialized MCV list, and compute pointers to parts */ + mcvlist = repalloc(mcvlist, mcvlen); + + /* pointer to the beginning of values/isnull arrays */ + valuesptr = (char *) mcvlist + + MAXALIGN(offsetof(MCVList, items) + (sizeof(MCVItem) * nitems)); + + isnullptr = valuesptr + (nitems * MAXALIGN(sizeof(Datum) * ndims)); + + dataptr = isnullptr + (nitems * MAXALIGN(sizeof(bool) * ndims)); + + /* + * Build mapping (index => value) for translating the serialized data into + * the in-memory representation. + */ + for (dim = 0; dim < ndims; dim++) + { + /* remember start position in the input array */ + char *start PG_USED_FOR_ASSERTS_ONLY = ptr; + + if (info[dim].typbyval) + { + /* for by-val types we simply copy data into the mapping */ + for (i = 0; i < info[dim].nvalues; i++) + { + Datum v = 0; + + memcpy(&v, ptr, info[dim].typlen); + ptr += info[dim].typlen; + + map[dim][i] = fetch_att(&v, true, info[dim].typlen); + + /* no under/overflow of input array */ + Assert(ptr <= (start + info[dim].nbytes)); + } + } + else + { + /* for by-ref types we need to also make a copy of the data */ + + /* passed by reference, but fixed length (name, tid, ...) */ + if (info[dim].typlen > 0) + { + for (i = 0; i < info[dim].nvalues; i++) + { + memcpy(dataptr, ptr, info[dim].typlen); + ptr += info[dim].typlen; + + /* just point into the array */ + map[dim][i] = PointerGetDatum(dataptr); + dataptr += MAXALIGN(info[dim].typlen); + } + } + else if (info[dim].typlen == -1) + { + /* varlena */ + for (i = 0; i < info[dim].nvalues; i++) + { + uint32 len; + + /* read the uint32 length */ + memcpy(&len, ptr, sizeof(uint32)); + ptr += sizeof(uint32); + + /* the length is data-only */ + SET_VARSIZE(dataptr, len + VARHDRSZ); + memcpy(VARDATA(dataptr), ptr, len); + ptr += len; + + /* just point into the array */ + map[dim][i] = PointerGetDatum(dataptr); + + /* skip to place of the next deserialized value */ + dataptr += MAXALIGN(len + VARHDRSZ); + } + } + else if (info[dim].typlen == -2) + { + /* cstring */ + for (i = 0; i < info[dim].nvalues; i++) + { + uint32 len; + + memcpy(&len, ptr, sizeof(uint32)); + ptr += sizeof(uint32); + + memcpy(dataptr, ptr, len); + ptr += len; + + /* just point into the array */ + map[dim][i] = PointerGetDatum(dataptr); + dataptr += MAXALIGN(len); + } + } + + /* no under/overflow of input array */ + Assert(ptr <= (start + info[dim].nbytes)); + + /* no overflow of the output mcv value */ + Assert(dataptr <= ((char *) mcvlist + mcvlen)); + } + + /* check we consumed input data for this dimension exactly */ + Assert(ptr == (start + info[dim].nbytes)); + } + + /* we should have also filled the MCV list exactly */ + Assert(dataptr == ((char *) mcvlist + mcvlen)); + + /* deserialize the MCV items and translate the indexes to Datums */ + for (i = 0; i < nitems; i++) + { + MCVItem *item = &mcvlist->items[i]; + + item->values = (Datum *) valuesptr; + valuesptr += MAXALIGN(sizeof(Datum) * ndims); + + item->isnull = (bool *) isnullptr; + isnullptr += MAXALIGN(sizeof(bool) * ndims); + + memcpy(item->isnull, ptr, sizeof(bool) * ndims); + ptr += sizeof(bool) * ndims; + + memcpy(&item->frequency, ptr, sizeof(double)); + ptr += sizeof(double); + + memcpy(&item->base_frequency, ptr, sizeof(double)); + ptr += sizeof(double); + + /* finally translate the indexes (for non-NULL only) */ + for (dim = 0; dim < ndims; dim++) + { + uint16 index; + + memcpy(&index, ptr, sizeof(uint16)); + ptr += sizeof(uint16); + + if (item->isnull[dim]) + continue; + + item->values[dim] = map[dim][index]; + } + + /* check we're not overflowing the input */ + Assert(ptr <= endptr); + } + + /* check that we processed all the data */ + Assert(ptr == endptr); + + /* release the buffers used for mapping */ + for (dim = 0; dim < ndims; dim++) + pfree(map[dim]); + + pfree(map); + + return mcvlist; +} + +/* + * SRF with details about buckets of a histogram: + * + * - item ID (0...nitems) + * - values (string array) + * - nulls only (boolean array) + * - frequency (double precision) + * - base_frequency (double precision) + * + * The input is the OID of the statistics, and there are no rows returned if + * the statistics contains no histogram. + */ +Datum +pg_stats_ext_mcvlist_items(PG_FUNCTION_ARGS) +{ + FuncCallContext *funcctx; + + /* stuff done only on the first call of the function */ + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcontext; + MCVList *mcvlist; + TupleDesc tupdesc; + + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); + + /* switch to memory context appropriate for multiple function calls */ + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + mcvlist = statext_mcv_deserialize(PG_GETARG_BYTEA_P(0)); + + funcctx->user_fctx = mcvlist; + + /* total number of tuples to be returned */ + funcctx->max_calls = 0; + if (funcctx->user_fctx != NULL) + funcctx->max_calls = mcvlist->nitems; + + /* Build a tuple descriptor for our result type */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + tupdesc = BlessTupleDesc(tupdesc); + + /* + * generate attribute metadata needed later to produce tuples from raw + * C strings + */ + funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc); + + MemoryContextSwitchTo(oldcontext); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + + if (funcctx->call_cntr < funcctx->max_calls) /* do when there is more left to send */ + { + Datum values[5]; + bool nulls[5]; + HeapTuple tuple; + Datum result; + ArrayBuildState *astate_values = NULL; + ArrayBuildState *astate_nulls = NULL; + + int i; + MCVList *mcvlist; + MCVItem *item; + + mcvlist = (MCVList *) funcctx->user_fctx; + + Assert(funcctx->call_cntr < mcvlist->nitems); + + item = &mcvlist->items[funcctx->call_cntr]; + + for (i = 0; i < mcvlist->ndimensions; i++) + { + + astate_nulls = accumArrayResult(astate_nulls, + BoolGetDatum(item->isnull[i]), + false, + BOOLOID, + CurrentMemoryContext); + + if (!item->isnull[i]) + { + bool isvarlena; + Oid outfunc; + FmgrInfo fmgrinfo; + Datum val; + text *txt; + + /* lookup output func for the type */ + getTypeOutputInfo(mcvlist->types[i], &outfunc, &isvarlena); + fmgr_info(outfunc, &fmgrinfo); + + val = FunctionCall1(&fmgrinfo, item->values[i]); + txt = cstring_to_text(DatumGetPointer(val)); + + astate_values = accumArrayResult(astate_values, + PointerGetDatum(txt), + false, + TEXTOID, + CurrentMemoryContext); + } + else + astate_values = accumArrayResult(astate_values, + (Datum) 0, + true, + TEXTOID, + CurrentMemoryContext); + } + + values[0] = Int32GetDatum(funcctx->call_cntr); + values[1] = PointerGetDatum(makeArrayResult(astate_values, CurrentMemoryContext)); + values[2] = PointerGetDatum(makeArrayResult(astate_nulls, CurrentMemoryContext)); + values[3] = Float8GetDatum(item->frequency); + values[4] = Float8GetDatum(item->base_frequency); + + /* no NULLs in the tuple */ + memset(nulls, 0, sizeof(nulls)); + + /* build a tuple */ + tuple = heap_form_tuple(funcctx->attinmeta->tupdesc, values, nulls); + + /* make the tuple into a datum */ + result = HeapTupleGetDatum(tuple); + + SRF_RETURN_NEXT(funcctx, result); + } + else /* do when there is no more left */ + { + SRF_RETURN_DONE(funcctx); + } +} + +/* + * pg_mcv_list_in - input routine for type pg_mcv_list. + * + * pg_mcv_list is real enough to be a table column, but it has no operations + * of its own, and disallows input too + */ +Datum +pg_mcv_list_in(PG_FUNCTION_ARGS) +{ + /* + * pg_mcv_list stores the data in binary form and parsing text input is + * not needed, so disallow this. + */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "pg_mcv_list"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + + +/* + * pg_mcv_list_out - output routine for type pg_mcv_list. + * + * MCV lists are serialized into a bytea value, so we simply call byteaout() + * to serialize the value into text. But it'd be nice to serialize that into + * a meaningful representation (e.g. for inspection by people). + * + * XXX This should probably return something meaningful, similar to what + * pg_dependencies_out does. Not sure how to deal with the deduplicated + * values, though - do we want to expand that or not? + */ +Datum +pg_mcv_list_out(PG_FUNCTION_ARGS) +{ + return byteaout(fcinfo); +} + +/* + * pg_mcv_list_recv - binary input routine for type pg_mcv_list. + */ +Datum +pg_mcv_list_recv(PG_FUNCTION_ARGS) +{ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot accept a value of type %s", "pg_mcv_list"))); + + PG_RETURN_VOID(); /* keep compiler quiet */ +} + +/* + * pg_mcv_list_send - binary output routine for type pg_mcv_list. + * + * MCV lists are serialized in a bytea value (although the type is named + * differently), so let's just send that. + */ +Datum +pg_mcv_list_send(PG_FUNCTION_ARGS) +{ + return byteasend(fcinfo); +} + +/* + * mcv_get_match_bitmap + * Evaluate clauses using the MCV list, and update the match bitmap. + * + * A match bitmap keeps match/mismatch status for each MCV item, and we + * update it based on additional clauses. We also use it to skip items + * that can't possibly match (e.g. item marked as "mismatch" can't change + * to "match" when evaluating AND clause list). + * + * The function also returns a flag indicating whether there was an + * equality condition for all attributes, the minimum frequency in the MCV + * list, and a total MCV frequency (sum of frequencies for all items). + * + * XXX Currently the match bitmap uses a bool for each MCV item, which is + * somewhat wasteful as we could do with just a single bit, thus reducing + * the size to ~1/8. It would also allow us to combine bitmaps simply using + * & and |, which should be faster than min/max. The bitmaps are fairly + * small, though (thanks to the cap on the MCV list size). + */ +static bool * +mcv_get_match_bitmap(PlannerInfo *root, List *clauses, + Bitmapset *keys, MCVList *mcvlist, bool is_or) +{ + int i; + ListCell *l; + bool *matches; + + /* The bitmap may be partially built. */ + Assert(clauses != NIL); + Assert(list_length(clauses) >= 1); + Assert(mcvlist != NULL); + Assert(mcvlist->nitems > 0); + Assert(mcvlist->nitems <= STATS_MCVLIST_MAX_ITEMS); + + matches = palloc(sizeof(bool) * mcvlist->nitems); + memset(matches, (is_or) ? false : true, + sizeof(bool) * mcvlist->nitems); + + /* + * Loop through the list of clauses, and for each of them evaluate all the + * MCV items not yet eliminated by the preceding clauses. + */ + foreach(l, clauses) + { + Node *clause = (Node *) lfirst(l); + + /* if it's a RestrictInfo, then extract the clause */ + if (IsA(clause, RestrictInfo)) + clause = (Node *) ((RestrictInfo *) clause)->clause; + + /* + * Handle the various types of clauses - OpClause, NullTest and + * AND/OR/NOT + */ + if (is_opclause(clause)) + { + OpExpr *expr = (OpExpr *) clause; + FmgrInfo opproc; + + /* valid only after examine_opclause_expression returns true */ + Var *var; + Const *cst; + bool varonleft; + + fmgr_info(get_opcode(expr->opno), &opproc); + + /* extract the var and const from the expression */ + if (examine_opclause_expression(expr, &var, &cst, &varonleft)) + { + int idx; + + /* match the attribute to a dimension of the statistic */ + idx = bms_member_index(keys, var->varattno); + + /* + * Walk through the MCV items and evaluate the current clause. + * We can skip items that were already ruled out, and + * terminate if there are no remaining MCV items that might + * possibly match. + */ + for (i = 0; i < mcvlist->nitems; i++) + { + bool match = true; + MCVItem *item = &mcvlist->items[i]; + + /* + * When the MCV item or the Const value is NULL we can treat + * this as a mismatch. We must not call the operator because + * of strictness. + */ + if (item->isnull[idx] || cst->constisnull) + { + matches[i] = RESULT_MERGE(matches[i], is_or, false); + continue; + } + + /* + * Skip MCV items that can't change result in the bitmap. + * Once the value gets false for AND-lists, or true for + * OR-lists, we don't need to look at more clauses. + */ + if (RESULT_IS_FINAL(matches[i], is_or)) + continue; + + /* + * First check whether the constant is below the lower + * boundary (in that case we can skip the bucket, because + * there's no overlap). + * + * We don't store collations used to build the statistics, + * but we can use the collation for the attribute itself, + * as stored in varcollid. We do reset the statistics after + * a type change (including collation change), so this is + * OK. We may need to relax this after allowing extended + * statistics on expressions. + */ + if (varonleft) + match = DatumGetBool(FunctionCall2Coll(&opproc, + var->varcollid, + item->values[idx], + cst->constvalue)); + else + match = DatumGetBool(FunctionCall2Coll(&opproc, + var->varcollid, + cst->constvalue, + item->values[idx])); + + /* update the match bitmap with the result */ + matches[i] = RESULT_MERGE(matches[i], is_or, match); + } + } + } + else if (IsA(clause, NullTest)) + { + NullTest *expr = (NullTest *) clause; + Var *var = (Var *) (expr->arg); + + /* match the attribute to a dimension of the statistic */ + int idx = bms_member_index(keys, var->varattno); + + /* + * Walk through the MCV items and evaluate the current clause. We + * can skip items that were already ruled out, and terminate if + * there are no remaining MCV items that might possibly match. + */ + for (i = 0; i < mcvlist->nitems; i++) + { + bool match = false; /* assume mismatch */ + MCVItem *item = &mcvlist->items[i]; + + /* if the clause mismatches the MCV item, update the bitmap */ + switch (expr->nulltesttype) + { + case IS_NULL: + match = (item->isnull[idx]) ? true : match; + break; + + case IS_NOT_NULL: + match = (!item->isnull[idx]) ? true : match; + break; + } + + /* now, update the match bitmap, depending on OR/AND type */ + matches[i] = RESULT_MERGE(matches[i], is_or, match); + } + } + else if (is_orclause(clause) || is_andclause(clause)) + { + /* AND/OR clause, with all subclauses being compatible */ + + int i; + BoolExpr *bool_clause = ((BoolExpr *) clause); + List *bool_clauses = bool_clause->args; + + /* match/mismatch bitmap for each MCV item */ + bool *bool_matches = NULL; + + Assert(bool_clauses != NIL); + Assert(list_length(bool_clauses) >= 2); + + /* build the match bitmap for the OR-clauses */ + bool_matches = mcv_get_match_bitmap(root, bool_clauses, keys, + mcvlist, is_orclause(clause)); + + /* + * Merge the bitmap produced by mcv_get_match_bitmap into the + * current one. We need to consider if we're evaluating AND or OR + * condition when merging the results. + */ + for (i = 0; i < mcvlist->nitems; i++) + matches[i] = RESULT_MERGE(matches[i], is_or, bool_matches[i]); + + pfree(bool_matches); + } + else if (is_notclause(clause)) + { + /* NOT clause, with all subclauses compatible */ + + int i; + BoolExpr *not_clause = ((BoolExpr *) clause); + List *not_args = not_clause->args; + + /* match/mismatch bitmap for each MCV item */ + bool *not_matches = NULL; + + Assert(not_args != NIL); + Assert(list_length(not_args) == 1); + + /* build the match bitmap for the NOT-clause */ + not_matches = mcv_get_match_bitmap(root, not_args, keys, + mcvlist, false); + + /* + * Merge the bitmap produced by mcv_get_match_bitmap into the + * current one. We're handling a NOT clause, so invert the result + * before merging it into the global bitmap. + */ + for (i = 0; i < mcvlist->nitems; i++) + matches[i] = RESULT_MERGE(matches[i], is_or, !not_matches[i]); + + pfree(not_matches); + } + else if (IsA(clause, Var)) + { + /* Var (has to be a boolean Var, possibly from below NOT) */ + + Var *var = (Var *) (clause); + + /* match the attribute to a dimension of the statistic */ + int idx = bms_member_index(keys, var->varattno); + + Assert(var->vartype == BOOLOID); + + /* + * Walk through the MCV items and evaluate the current clause. We + * can skip items that were already ruled out, and terminate if + * there are no remaining MCV items that might possibly match. + */ + for (i = 0; i < mcvlist->nitems; i++) + { + MCVItem *item = &mcvlist->items[i]; + bool match = false; + + /* if the item is NULL, it's a mismatch */ + if (!item->isnull[idx] && DatumGetBool(item->values[idx])) + match = true; + + /* update the result bitmap */ + matches[i] = RESULT_MERGE(matches[i], is_or, match); + } + } + else + elog(ERROR, "unknown clause type: %d", clause->type); + } + + return matches; +} + + +/* + * mcv_clauselist_selectivity + * Return the selectivity estimate computed using an MCV list. + * + * First builds a bitmap of MCV items matching the clauses, and then sums + * the frequencies of matching items. + * + * It also produces two additional interesting selectivities - total + * selectivity of all the MCV items (not just the matching ones), and the + * base frequency computed on the assumption of independence. + */ +Selectivity +mcv_clauselist_selectivity(PlannerInfo *root, StatisticExtInfo *stat, + List *clauses, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Selectivity *basesel, Selectivity *totalsel) +{ + int i; + MCVList *mcv; + Selectivity s = 0.0; + + /* match/mismatch bitmap for each MCV item */ + bool *matches = NULL; + + /* load the MCV list stored in the statistics object */ + mcv = statext_mcv_load(stat->statOid); + + /* build a match bitmap for the clauses */ + matches = mcv_get_match_bitmap(root, clauses, stat->keys, mcv, false); + + /* sum frequencies for all the matching MCV items */ + *basesel = 0.0; + *totalsel = 0.0; + for (i = 0; i < mcv->nitems; i++) + { + *totalsel += mcv->items[i].frequency; + + if (matches[i] != false) + { + /* XXX Shouldn't the basesel be outside the if condition? */ + *basesel += mcv->items[i].base_frequency; + s += mcv->items[i].frequency; + } + } + + return s; +} diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c index 24e74d7a1b2..f3383c05d91 100644 --- a/src/backend/statistics/mvdistinct.c +++ b/src/backend/statistics/mvdistinct.c @@ -13,7 +13,7 @@ * estimates are already available in pg_statistic. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -27,6 +27,7 @@ #include "access/htup_details.h" #include "catalog/pg_statistic_ext.h" +#include "catalog/pg_statistic_ext_data.h" #include "utils/fmgrprotos.h" #include "utils/lsyscache.h" #include "lib/stringinfo.h" @@ -37,12 +38,26 @@ static double ndistinct_for_combination(double totalrows, int numrows, - HeapTuple *rows, VacAttrStats **stats, - int k, int *combination); + HeapTuple *rows, VacAttrStats **stats, + int k, int *combination); static double estimate_ndistinct(double totalrows, int numrows, int d, int f1); static int n_choose_k(int n, int k); static int num_combinations(int n); +/* size of the struct header fields (magic, type, nitems) */ +#define SizeOfHeader (3 * sizeof(uint32)) + +/* size of a serialized ndistinct item (coefficient, natts, atts) */ +#define SizeOfItem(natts) \ + (sizeof(double) + sizeof(int) + (natts) * sizeof(AttrNumber)) + +/* minimal size of a ndistinct item (with two attributes) */ +#define MinSizeOfItem SizeOfItem(2) + +/* minimal size of mvndistinct, when all items are minimal */ +#define MinSizeOfItems(nitems) \ + (SizeOfHeader + (nitems) * MinSizeOfItem) + /* Combination generator API */ /* internal state for generator of k-combinations of n elements */ @@ -126,24 +141,27 @@ statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows, MVNDistinct * statext_ndistinct_load(Oid mvoid) { - bool isnull = false; + MVNDistinct *result; + bool isnull; Datum ndist; HeapTuple htup; - htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid)); - if (!htup) + htup = SearchSysCache1(STATEXTDATASTXOID, ObjectIdGetDatum(mvoid)); + if (!HeapTupleIsValid(htup)) elog(ERROR, "cache lookup failed for statistics object %u", mvoid); - ndist = SysCacheGetAttr(STATEXTOID, htup, - Anum_pg_statistic_ext_stxndistinct, &isnull); + ndist = SysCacheGetAttr(STATEXTDATASTXOID, htup, + Anum_pg_statistic_ext_data_stxdndistinct, &isnull); if (isnull) elog(ERROR, - "requested statistic kind %c is not yet built for statistics object %u", + "requested statistic kind \"%c\" is not yet built for statistics object %u", STATS_EXT_NDISTINCT, mvoid); + result = statext_ndistinct_deserialize(DatumGetByteaPP(ndist)); + ReleaseSysCache(htup); - return statext_ndistinct_deserialize(DatumGetByteaP(ndist)); + return result; } /* @@ -165,8 +183,7 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) * Base size is size of scalar fields in the struct, plus one base struct * for each item, including number of items for each. */ - len = VARHDRSZ + SizeOfMVNDistinct + - ndistinct->nitems * (offsetof(MVNDistinctItem, attrs) + sizeof(int)); + len = VARHDRSZ + SizeOfHeader; /* and also include space for the actual attribute numbers */ for (i = 0; i < ndistinct->nitems; i++) @@ -175,7 +192,8 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) nmembers = bms_num_members(ndistinct->items[i].attrs); Assert(nmembers >= 2); - len += sizeof(AttrNumber) * nmembers; + + len += SizeOfItem(nmembers); } output = (bytea *) palloc(len); @@ -192,8 +210,7 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) tmp += sizeof(uint32); /* - * store number of attributes and attribute numbers for each ndistinct - * entry + * store number of attributes and attribute numbers for each entry */ for (i = 0; i < ndistinct->nitems; i++) { @@ -215,9 +232,13 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct) tmp += sizeof(AttrNumber); } + /* protect against overflows */ Assert(tmp <= ((char *) output + len)); } + /* check we used exactly the expected space */ + Assert(tmp == ((char *) output + len)); + return output; } @@ -238,9 +259,9 @@ statext_ndistinct_deserialize(bytea *data) return NULL; /* we expect at least the basic fields of MVNDistinct struct */ - if (VARSIZE_ANY_EXHDR(data) < SizeOfMVNDistinct) + if (VARSIZE_ANY_EXHDR(data) < SizeOfHeader) elog(ERROR, "invalid MVNDistinct size %zd (expected at least %zd)", - VARSIZE_ANY_EXHDR(data), SizeOfMVNDistinct); + VARSIZE_ANY_EXHDR(data), SizeOfHeader); /* initialize pointer to the data part (skip the varlena header) */ tmp = VARDATA_ANY(data); @@ -254,35 +275,25 @@ statext_ndistinct_deserialize(bytea *data) tmp += sizeof(uint32); if (ndist.magic != STATS_NDISTINCT_MAGIC) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid ndistinct magic %08x (expected %08x)", - ndist.magic, STATS_NDISTINCT_MAGIC))); + elog(ERROR, "invalid ndistinct magic %08x (expected %08x)", + ndist.magic, STATS_NDISTINCT_MAGIC); if (ndist.type != STATS_NDISTINCT_TYPE_BASIC) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid ndistinct type %d (expected %d)", - ndist.type, STATS_NDISTINCT_TYPE_BASIC))); + elog(ERROR, "invalid ndistinct type %d (expected %d)", + ndist.type, STATS_NDISTINCT_TYPE_BASIC); if (ndist.nitems == 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid zero-length item array in MVNDistinct"))); + elog(ERROR, "invalid zero-length item array in MVNDistinct"); /* what minimum bytea size do we expect for those parameters */ - minimum_size = (SizeOfMVNDistinct + - ndist.nitems * (SizeOfMVNDistinctItem + - sizeof(AttrNumber) * 2)); + minimum_size = MinSizeOfItems(ndist.nitems); if (VARSIZE_ANY_EXHDR(data) < minimum_size) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("invalid MVNDistinct size %zd (expected at least %zd)", - VARSIZE_ANY_EXHDR(data), minimum_size))); + elog(ERROR, "invalid MVNDistinct size %zd (expected at least %zd)", + VARSIZE_ANY_EXHDR(data), minimum_size); /* * Allocate space for the ndistinct items (no space for each item's * attnos: those live in bitmapsets allocated separately) */ - ndistinct = palloc0(MAXALIGN(SizeOfMVNDistinct) + + ndistinct = palloc0(MAXALIGN(offsetof(MVNDistinct, items)) + (ndist.nitems * sizeof(MVNDistinctItem))); ndistinct->magic = ndist.magic; ndistinct->type = ndist.type; @@ -328,7 +339,7 @@ statext_ndistinct_deserialize(bytea *data) * input routine for type pg_ndistinct * * pg_ndistinct is real enough to be a table column, but it has no - * operations of its own, and disallows input (jus like pg_node_tree). + * operations of its own, and disallows input (just like pg_node_tree). */ Datum pg_ndistinct_in(PG_FUNCTION_ARGS) @@ -451,6 +462,9 @@ ndistinct_for_combination(double totalrows, int numrows, HeapTuple *rows, /* * For each dimension, set up sort-support and fill in the values from the * sample data. + * + * We use the column data types' default sort operators and collations; + * perhaps at some point it'd be worth using column-specific collations? */ for (i = 0; i < k; i++) { @@ -463,7 +477,7 @@ ndistinct_for_combination(double totalrows, int numrows, HeapTuple *rows, colstat->attrtypid); /* prepare the sort function for this dimension */ - multi_sort_add_dimension(mss, i, type->lt_opr); + multi_sort_add_dimension(mss, i, type->lt_opr, colstat->attrcollid); /* accumulate all the data for this dimension into the arrays */ for (j = 0; j < numrows; j++) diff --git a/src/backend/storage/Makefile b/src/backend/storage/Makefile index bd2d272c6ea..8376cdfca20 100644 --- a/src/backend/storage/Makefile +++ b/src/backend/storage/Makefile @@ -8,6 +8,6 @@ subdir = src/backend/storage top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -SUBDIRS = buffer file freespace ipc large_object lmgr page smgr +SUBDIRS = buffer file freespace ipc large_object lmgr page smgr sync include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 144a2cee6f0..ccd2c31c0b3 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -3,7 +3,7 @@ * buf_init.c * buffer manager initialization routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -179,7 +179,7 @@ BufferShmemSize(void) * and benchmarking has shown that keeping every BufferDesc aligned on a * cache line boundary is important for performance. So, instead, the * array of I/O locks is allocated in a separate tranche. Because those - * locks are not highly contentended, we lay out the array with minimal + * locks are not highly contended, we lay out the array with minimal * padding. */ size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded))); diff --git a/src/backend/storage/buffer/buf_table.c b/src/backend/storage/buffer/buf_table.c index 88155204fd2..e5465854566 100644 --- a/src/backend/storage/buffer/buf_table.c +++ b/src/backend/storage/buffer/buf_table.c @@ -10,7 +10,7 @@ * before the lock is released (see notes in README). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 01eabe57063..483f705305c 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -3,7 +3,7 @@ * bufmgr.c * buffer manager interface routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -33,6 +33,7 @@ #include #include +#include "access/tableam.h" #include "access/xlog.h" #include "catalog/catalog.h" #include "catalog/storage.h" @@ -429,27 +430,28 @@ ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref) static Buffer ReadBuffer_common(SMgrRelation reln, char relpersistence, - ForkNumber forkNum, BlockNumber blockNum, - ReadBufferMode mode, BufferAccessStrategy strategy, - bool *hit); + ForkNumber forkNum, BlockNumber blockNum, + ReadBufferMode mode, BufferAccessStrategy strategy, + bool *hit); static bool PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy); static void PinBuffer_Locked(BufferDesc *buf); static void UnpinBuffer(BufferDesc *buf, bool fixOwner); static void BufferSync(int flags); static uint32 WaitBufHdrUnlocked(BufferDesc *buf); -static int SyncOneBuffer(int buf_id, bool skip_recently_used, WritebackContext *flush_context); +static int SyncOneBuffer(int buf_id, bool skip_recently_used, + WritebackContext *wb_context); static void WaitIO(BufferDesc *buf); static bool StartBufferIO(BufferDesc *buf, bool forInput); static void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, - uint32 set_flag_bits); + uint32 set_flag_bits); static void shared_buffer_write_error_callback(void *arg); static void local_buffer_write_error_callback(void *arg); static BufferDesc *BufferAlloc(SMgrRelation smgr, - char relpersistence, - ForkNumber forkNum, - BlockNumber blockNum, - BufferAccessStrategy strategy, - bool *foundPtr); + char relpersistence, + ForkNumber forkNum, + BlockNumber blockNum, + BufferAccessStrategy strategy, + bool *foundPtr); static void FlushBuffer(BufferDesc *buf, SMgrRelation reln); static void AtProcExit_Buffers(int code, Datum arg); static void CheckForBufferLeaks(void); @@ -733,7 +735,10 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, bufHdr = LocalBufferAlloc(smgr, forkNum, blockNum, &found); if (found) pgBufferUsage.local_blks_hit++; - else + else if (isExtend) + pgBufferUsage.local_blks_written++; + else if (mode == RBM_NORMAL || mode == RBM_NORMAL_NO_LOG || + mode == RBM_ZERO_ON_ERROR) pgBufferUsage.local_blks_read++; } else @@ -746,7 +751,10 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, strategy, &found); if (found) pgBufferUsage.shared_blks_hit++; - else + else if (isExtend) + pgBufferUsage.shared_blks_written++; + else if (mode == RBM_NORMAL || mode == RBM_NORMAL_NO_LOG || + mode == RBM_ZERO_ON_ERROR) pgBufferUsage.shared_blks_read++; } @@ -2339,7 +2347,7 @@ BgBufferSync(WritebackContext *wb_context) * BUF_REUSABLE: buffer is available for replacement, ie, it has * pin count 0 and usage count 0. * - * (BUF_WRITTEN could be set in error if FlushBuffers finds the buffer clean + * (BUF_WRITTEN could be set in error if FlushBuffer finds the buffer clean * after locking it, but we don't care all that much.) * * Note: caller must have done ResourceOwnerEnlargeBuffers. @@ -2578,7 +2586,7 @@ CheckPointBuffers(int flags) BufferSync(flags); CheckpointStats.ckpt_sync_t = GetCurrentTimestamp(); TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START(); - smgrsync(); + ProcessSyncRequests(); CheckpointStats.ckpt_sync_end_t = GetCurrentTimestamp(); TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE(); } @@ -2783,14 +2791,50 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln) /* * RelationGetNumberOfBlocksInFork * Determines the current number of pages in the specified relation fork. + * + * Note that the accuracy of the result will depend on the details of the + * relation's storage. For builtin AMs it'll be accurate, but for external AMs + * it might not be. */ BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum) { - /* Open it at the smgr level if not already done */ - RelationOpenSmgr(relation); + switch (relation->rd_rel->relkind) + { + case RELKIND_SEQUENCE: + case RELKIND_INDEX: + case RELKIND_PARTITIONED_INDEX: + /* Open it at the smgr level if not already done */ + RelationOpenSmgr(relation); - return smgrnblocks(relation->rd_smgr, forkNum); + return smgrnblocks(relation->rd_smgr, forkNum); + + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: + { + /* + * Not every table AM uses BLCKSZ wide fixed size blocks. + * Therefore tableam returns the size in bytes - but for the + * purpose of this routine, we want the number of blocks. + * Therefore divide, rounding up. + */ + uint64 szbytes; + + szbytes = table_relation_size(relation, forkNum); + + return (szbytes + (BLCKSZ - 1)) / BLCKSZ; + } + case RELKIND_VIEW: + case RELKIND_COMPOSITE_TYPE: + case RELKIND_FOREIGN_TABLE: + case RELKIND_PARTITIONED_TABLE: + default: + Assert(false); + break; + } + + return 0; /* keep compiler quiet */ } /* @@ -2857,7 +2901,7 @@ BufferGetLSNAtomic(Buffer buffer) * DropRelFileNodeBuffers * * This function removes from the buffer pool all the pages of the - * specified relation fork that have block numbers >= firstDelBlock. + * specified relation forks that have block numbers >= firstDelBlock. * (In particular, with firstDelBlock = 0, all pages are removed.) * Dirty pages are simply dropped, without bothering to write them * out first. Therefore, this is NOT rollback-able, and so should be @@ -2880,16 +2924,21 @@ BufferGetLSNAtomic(Buffer buffer) * -------------------------------------------------------------------- */ void -DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, - BlockNumber firstDelBlock) +DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum, + int nforks, BlockNumber *firstDelBlock) { int i; + int j; /* If it's a local relation, it's localbuf.c's problem. */ if (RelFileNodeBackendIsTemp(rnode)) { if (rnode.backend == MyBackendId) - DropRelFileNodeLocalBuffers(rnode.node, forkNum, firstDelBlock); + { + for (j = 0; j < nforks; j++) + DropRelFileNodeLocalBuffers(rnode.node, forkNum[j], + firstDelBlock[j]); + } return; } @@ -2918,11 +2967,18 @@ DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, continue; buf_state = LockBufHdr(bufHdr); - if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) && - bufHdr->tag.forkNum == forkNum && - bufHdr->tag.blockNum >= firstDelBlock) - InvalidateBuffer(bufHdr); /* releases spinlock */ - else + + for (j = 0; j < nforks; j++) + { + if (RelFileNodeEquals(bufHdr->tag.rnode, rnode.node) && + bufHdr->tag.forkNum == forkNum[j] && + bufHdr->tag.blockNum >= firstDelBlock[j]) + { + InvalidateBuffer(bufHdr); /* releases spinlock */ + break; + } + } + if (j >= nforks) UnlockBufHdr(bufHdr, buf_state); } } diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index 18493dca175..c8d4e6f9e42 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -4,7 +4,7 @@ * routines for managing the buffer pool's replacement strategy. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -99,9 +99,9 @@ typedef struct BufferAccessStrategyData /* Prototypes for internal functions */ static BufferDesc *GetBufferFromRing(BufferAccessStrategy strategy, - uint32 *buf_state); + uint32 *buf_state); static void AddBufferToRing(BufferAccessStrategy strategy, - BufferDesc *buf); + BufferDesc *buf); /* * ClockSweepTick - Helper routine for StrategyGetBuffer() @@ -220,7 +220,7 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) * If asked, we need to waken the bgwriter. Since we don't want to rely on * a spinlock for this we force a read from shared memory once, and then * set the latch based on that value. We need to go through that length - * because otherwise bgprocno might be reset while/after we check because + * because otherwise bgwprocno might be reset while/after we check because * the compiler might just reread from memory. * * This can possibly set the latch of the wrong process if the bgwriter diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index e4146a260a5..f5f6a29222b 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -4,7 +4,7 @@ * local buffer manager. Fast buffer manager for temporary tables, * which never need to be WAL-logged or checkpointed, etc. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -361,7 +361,7 @@ DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum, * This function removes from the buffer pool all pages of all forks * of the specified relation. * - * See DropRelFileNodeAllBuffers in bufmgr.c for more notes. + * See DropRelFileNodesAllBuffers in bufmgr.c for more notes. */ void DropRelFileNodeAllLocalBuffers(RelFileNode rnode) @@ -537,7 +537,7 @@ GetLocalBufferStorage(void) /* * CheckForLocalBufferLeaks - ensure this backend holds no local buffer pins * - * This is just like CheckBufferLeaks(), but for local buffers. + * This is just like CheckForBufferLeaks(), but for local buffers. */ static void CheckForLocalBufferLeaks(void) diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index c058c3fc43e..b40e6f3fde9 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -3,7 +3,7 @@ * buffile.c * Management of large buffered temporary files. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -41,6 +41,7 @@ #include "postgres.h" +#include "commands/tablespace.h" #include "executor/instrument.h" #include "miscadmin.h" #include "pgstat.h" @@ -67,12 +68,6 @@ struct BufFile int numFiles; /* number of physical files in set */ /* all files except the last have length exactly MAX_PHYSICAL_FILESIZE */ File *files; /* palloc'd array with numFiles entries */ - off_t *offsets; /* palloc'd array with numFiles entries */ - - /* - * offsets[i] is the current seek position of files[i]. We use this to - * avoid making redundant FileSeek calls. - */ bool isInterXact; /* keep open over transactions? */ bool dirty; /* does buffer need to be written? */ @@ -96,9 +91,10 @@ struct BufFile off_t curOffset; /* offset part of current pos */ int pos; /* next read/write position in buffer */ int nbytes; /* total # of valid bytes in buffer */ - char buffer[BLCKSZ]; + PGAlignedBlock buffer; }; +static BufFile *makeBufFileCommon(int nfiles); static BufFile *makeBufFile(File firstfile); static void extendBufFile(BufFile *file); static void BufFileLoadBuffer(BufFile *file); @@ -106,21 +102,15 @@ static void BufFileDumpBuffer(BufFile *file); static int BufFileFlush(BufFile *file); static File MakeNewSharedSegment(BufFile *file, int segment); - /* - * Create a BufFile given the first underlying physical file. - * NOTE: caller must set isInterXact if appropriate. + * Create BufFile and perform the common initialization. */ static BufFile * -makeBufFile(File firstfile) +makeBufFileCommon(int nfiles) { BufFile *file = (BufFile *) palloc(sizeof(BufFile)); - file->numFiles = 1; - file->files = (File *) palloc(sizeof(File)); - file->files[0] = firstfile; - file->offsets = (off_t *) palloc(sizeof(off_t)); - file->offsets[0] = 0L; + file->numFiles = nfiles; file->isInterXact = false; file->dirty = false; file->resowner = CurrentResourceOwner; @@ -128,6 +118,21 @@ makeBufFile(File firstfile) file->curOffset = 0L; file->pos = 0; file->nbytes = 0; + + return file; +} + +/* + * Create a BufFile given the first underlying physical file. + * NOTE: caller must set isInterXact if appropriate. + */ +static BufFile * +makeBufFile(File firstfile) +{ + BufFile *file = makeBufFileCommon(1); + + file->files = (File *) palloc(sizeof(File)); + file->files[0] = firstfile; file->readOnly = false; file->fileset = NULL; file->name = NULL; @@ -159,10 +164,7 @@ extendBufFile(BufFile *file) file->files = (File *) repalloc(file->files, (file->numFiles + 1) * sizeof(File)); - file->offsets = (off_t *) repalloc(file->offsets, - (file->numFiles + 1) * sizeof(off_t)); file->files[file->numFiles] = pfile; - file->offsets[file->numFiles] = 0L; file->numFiles++; } @@ -184,6 +186,17 @@ BufFileCreateTemp(bool interXact) BufFile *file; File pfile; + /* + * Ensure that temp tablespaces are set up for OpenTemporaryFile to use. + * Possibly the caller will have done this already, but it seems useful to + * double-check here. Failure to do this at all would result in the temp + * files always getting placed in the default tablespace, which is a + * pretty hard-to-detect bug. Callers may prefer to do it earlier if they + * want to be sure that any required catalog access is done in some other + * resource context. + */ + PrepareTempTablespaces(); + pfile = OpenTemporaryFile(interXact); Assert(pfile >= 0); @@ -213,9 +226,9 @@ MakeNewSharedSegment(BufFile *buffile, int segment) /* * It is possible that there are files left over from before a crash - * restart with the same name. In order for BufFileOpenShared() - * not to get confused about how many segments there are, we'll unlink - * the next segment number if it already exists. + * restart with the same name. In order for BufFileOpenShared() not to + * get confused about how many segments there are, we'll unlink the next + * segment number if it already exists. */ SharedSegmentName(name, buffile->name, segment + 1); SharedFileSetDelete(buffile->fileset, name, true); @@ -246,23 +259,12 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name) { BufFile *file; - file = (BufFile *) palloc(sizeof(BufFile)); + file = makeBufFileCommon(1); file->fileset = fileset; file->name = pstrdup(name); - file->numFiles = 1; file->files = (File *) palloc(sizeof(File)); file->files[0] = MakeNewSharedSegment(file, 0); - file->offsets = (off_t *) palloc(sizeof(off_t)); - file->offsets[0] = 0L; - file->isInterXact = false; - file->dirty = false; - file->resowner = CurrentResourceOwner; - file->curFile = 0; - file->curOffset = 0L; - file->pos = 0; - file->nbytes = 0; file->readOnly = false; - file->name = pstrdup(name); return file; } @@ -277,13 +279,12 @@ BufFileCreateShared(SharedFileSet *fileset, const char *name) BufFile * BufFileOpenShared(SharedFileSet *fileset, const char *name) { - BufFile *file = (BufFile *) palloc(sizeof(BufFile)); + BufFile *file; char segment_name[MAXPGPATH]; Size capacity = 16; - File *files = palloc(sizeof(File) * capacity); + File *files; int nfiles = 0; - file = (BufFile *) palloc(sizeof(BufFile)); files = palloc(sizeof(File) * capacity); /* @@ -315,18 +316,11 @@ BufFileOpenShared(SharedFileSet *fileset, const char *name) if (nfiles == 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not open BufFile \"%s\"", name))); + errmsg("could not open temporary file \"%s\" from BufFile \"%s\": %m", + segment_name, name))); - file->numFiles = nfiles; + file = makeBufFileCommon(nfiles); file->files = files; - file->offsets = (off_t *) palloc0(sizeof(off_t) * nfiles); - file->isInterXact = false; - file->dirty = false; - file->resowner = CurrentResourceOwner; /* Unused, can't extend */ - file->curFile = 0; - file->curOffset = 0L; - file->pos = 0; - file->nbytes = 0; file->readOnly = true; /* Can't write to files opened this way */ file->fileset = fileset; file->name = pstrdup(name); @@ -405,7 +399,6 @@ BufFileClose(BufFile *file) FileClose(file->files[i]); /* release the buffer space */ pfree(file->files); - pfree(file->offsets); pfree(file); } @@ -431,27 +424,17 @@ BufFileLoadBuffer(BufFile *file) file->curOffset = 0L; } - /* - * May need to reposition physical file. - */ - thisfile = file->files[file->curFile]; - if (file->curOffset != file->offsets[file->curFile]) - { - if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset) - return; /* seek failed, read nothing */ - file->offsets[file->curFile] = file->curOffset; - } - /* * Read whatever we can get, up to a full bufferload. */ + thisfile = file->files[file->curFile]; file->nbytes = FileRead(thisfile, - file->buffer, + file->buffer.data, sizeof(file->buffer), + file->curOffset, WAIT_EVENT_BUFFILE_READ); if (file->nbytes < 0) file->nbytes = 0; - file->offsets[file->curFile] += file->nbytes; /* we choose not to advance curOffset here */ if (file->nbytes > 0) @@ -500,23 +483,14 @@ BufFileDumpBuffer(BufFile *file) if ((off_t) bytestowrite > availbytes) bytestowrite = (int) availbytes; - /* - * May need to reposition physical file. - */ thisfile = file->files[file->curFile]; - if (file->curOffset != file->offsets[file->curFile]) - { - if (FileSeek(thisfile, file->curOffset, SEEK_SET) != file->curOffset) - return; /* seek failed, give up */ - file->offsets[file->curFile] = file->curOffset; - } bytestowrite = FileWrite(thisfile, - file->buffer + wpos, + file->buffer.data + wpos, bytestowrite, + file->curOffset, WAIT_EVENT_BUFFILE_WRITE); if (bytestowrite <= 0) return; /* failed to write */ - file->offsets[file->curFile] += bytestowrite; file->curOffset += bytestowrite; wpos += bytestowrite; @@ -581,7 +555,7 @@ BufFileRead(BufFile *file, void *ptr, size_t size) nthistime = size; Assert(nthistime > 0); - memcpy(ptr, file->buffer + file->pos, nthistime); + memcpy(ptr, file->buffer.data + file->pos, nthistime); file->pos += nthistime; ptr = (void *) ((char *) ptr + nthistime); @@ -630,7 +604,7 @@ BufFileWrite(BufFile *file, void *ptr, size_t size) nthistime = size; Assert(nthistime > 0); - memcpy(file->buffer + file->pos, ptr, nthistime); + memcpy(file->buffer.data + file->pos, ptr, nthistime); file->dirty = true; file->pos += nthistime; @@ -690,7 +664,7 @@ BufFileSeek(BufFile *file, int fileno, off_t offset, int whence) /* * Relative seek considers only the signed offset, ignoring - * fileno. Note that large offsets (> 1 gig) risk overflow in this + * fileno. Note that large offsets (> 1 GB) risk overflow in this * add, unless we have 64-bit off_t. */ newFile = file->curFile; @@ -802,14 +776,29 @@ BufFileTellBlock(BufFile *file) #endif /* - * Return the current file size. Counts any holes left behind by - * BufFileViewAppend as part of the size. + * Return the current shared BufFile size. + * + * Counts any holes left behind by BufFileAppend as part of the size. + * ereport()s on failure. */ -off_t +int64 BufFileSize(BufFile *file) { - return ((file->numFiles - 1) * (off_t) MAX_PHYSICAL_FILESIZE) + - FileGetSize(file->files[file->numFiles - 1]); + int64 lastFileSize; + + Assert(file->fileset != NULL); + + /* Get the size of the last physical file. */ + lastFileSize = FileSize(file->files[file->numFiles - 1]); + if (lastFileSize < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not determine size of temporary file \"%s\" from BufFile \"%s\": %m", + FilePathName(file->files[file->numFiles - 1]), + file->name))); + + return ((file->numFiles - 1) * (int64) MAX_PHYSICAL_FILESIZE) + + lastFileSize; } /* @@ -848,13 +837,8 @@ BufFileAppend(BufFile *target, BufFile *source) target->files = (File *) repalloc(target->files, sizeof(File) * newNumFiles); - target->offsets = (off_t *) - repalloc(target->offsets, sizeof(off_t) * newNumFiles); for (i = target->numFiles; i < newNumFiles; i++) - { target->files[i] = source->files[i - target->numFiles]; - target->offsets[i] = 0L; - } target->numFiles = newNumFiles; return startBlock; diff --git a/src/backend/storage/file/copydir.c b/src/backend/storage/file/copydir.c index 4a0d23b11e3..ca1c9cd7655 100644 --- a/src/backend/storage/file/copydir.c +++ b/src/backend/storage/file/copydir.c @@ -3,7 +3,7 @@ * copydir.c * copies a directory * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * While "xcopy /e /i /q" works fine for copying directories, on Windows XP @@ -199,7 +199,6 @@ copy_file(char *fromfile, char *tofile) pgstat_report_wait_start(WAIT_EVENT_COPY_FILE_WRITE); if ((int) write(dstfd, buffer, nbytes) != nbytes) { - pgstat_report_wait_end(); /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; @@ -213,12 +212,15 @@ copy_file(char *fromfile, char *tofile) if (offset > flush_offset) pg_flush_data(dstfd, flush_offset, offset - flush_offset); - if (CloseTransientFile(dstfd)) + if (CloseTransientFile(dstfd) != 0) ereport(ERROR, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", tofile))); - CloseTransientFile(srcfd); + if (CloseTransientFile(srcfd) != 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", fromfile))); pfree(buffer); } diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index f772dfe93f7..94be62fa6ec 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -3,7 +3,7 @@ * fd.c * Virtual file descriptor code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -16,8 +16,8 @@ * including base tables, scratch files (e.g., sort and hash spool * files), and random calls to C library routines like system(3); it * is quite easy to exceed system limits on the number of open files a - * single process can have. (This is around 256 on many modern - * operating systems, but can be as low as 32 on others.) + * single process can have. (This is around 1024 on many modern + * operating systems, but may be lower on others.) * * VFDs are managed as an LRU pool, with actual OS file descriptors * being opened and closed as needed. Obviously, if a routine is @@ -145,6 +145,8 @@ int max_files_per_process = 1000; */ int max_safe_fds = 32; /* default if not changed */ +/* Whether it is safe to continue running after fsync() fails. */ +bool data_sync_retry = false; /* Debugging.... */ @@ -167,15 +169,6 @@ int max_safe_fds = 32; /* default if not changed */ #define FileIsNotOpen(file) (VfdCache[file].fd == VFD_CLOSED) -/* - * Note: a VFD's seekPos is normally always valid, but if for some reason - * an lseek() fails, it might become set to FileUnknownPos. We can struggle - * along without knowing the seek position in many cases, but in some places - * we have to fail if we don't have it. - */ -#define FileUnknownPos ((off_t) -1) -#define FilePosIsUnknown(pos) ((pos) < 0) - /* these are the assigned bits in fdstate below: */ #define FD_DELETE_AT_CLOSE (1 << 0) /* T = delete when closed */ #define FD_CLOSE_AT_EOXACT (1 << 1) /* T = close at eoXact */ @@ -189,7 +182,6 @@ typedef struct vfd File nextFree; /* link to next free VFD, if in freelist */ File lruMoreRecently; /* doubly linked recency-of-use list */ File lruLessRecently; - off_t seekPos; /* current logical file position, or -1 */ off_t fileSize; /* current size of file (0 if not temporary) */ char *fileName; /* name of file, or NULL for unused VFD */ /* NB: fileName is malloc'd, and must be free'd when closing the VFD */ @@ -277,7 +269,7 @@ static int nextTempTableSpace = 0; * LruInsert - put a file at the front of the Lru ring and open it * ReleaseLruFile - Release an fd by closing the last entry in the Lru ring * ReleaseLruFiles - Release fd(s) until we're under the max_safe_fds limit - * AllocateVfd - grab a free (or new) file record (from VfdArray) + * AllocateVfd - grab a free (or new) file record (from VfdCache) * FreeVfd - free a file record * * The Least Recently Used ring is a doubly linked list that begins and @@ -314,16 +306,14 @@ static bool reserveAllocatedDesc(void); static int FreeDesc(AllocateDesc *desc); static void AtProcExit_Files(int code, Datum arg); -static void CleanupTempFiles(bool isProcExit); -static void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, - bool unlink_all); +static void CleanupTempFiles(bool isCommit, bool isProcExit); static void RemovePgTempRelationFiles(const char *tsdirname); static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname); static void walkdir(const char *path, - void (*action) (const char *fname, bool isdir, int elevel), - bool process_symlinks, - int elevel); + void (*action) (const char *fname, bool isdir, int elevel), + bool process_symlinks, + int elevel); #ifdef PG_FLUSH_DATA_WORKS static void pre_sync_fname(const char *fname, bool isdir, int elevel); #endif @@ -407,9 +397,7 @@ pg_fdatasync(int fd) /* * pg_flush_data --- advise OS that the described dirty data should be flushed * - * offset of 0 with nbytes 0 means that the entire file should be flushed; - * in this case, this function may have side-effects on the file's - * seek position! + * offset of 0 with nbytes 0 means that the entire file should be flushed */ void pg_flush_data(int fd, off_t offset, off_t nbytes) @@ -430,6 +418,10 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) #if defined(HAVE_SYNC_FILE_RANGE) { int rc; + static bool not_implemented_by_kernel = false; + + if (not_implemented_by_kernel) + return; /* * sync_file_range(SYNC_FILE_RANGE_WRITE), currently linux specific, @@ -442,11 +434,24 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) */ rc = sync_file_range(fd, offset, nbytes, SYNC_FILE_RANGE_WRITE); - - /* don't error out, this is just a performance optimization */ if (rc != 0) { - ereport(WARNING, + int elevel; + + /* + * For systems that don't have an implementation of + * sync_file_range() such as Windows WSL, generate only one + * warning and then suppress all further attempts by this process. + */ + if (errno == ENOSYS) + { + elevel = WARNING; + not_implemented_by_kernel = true; + } + else + elevel = data_sync_elevel(WARNING); + + ereport(elevel, (errcode_for_file_access(), errmsg("could not flush dirty data: %m"))); } @@ -518,7 +523,7 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) rc = msync(p, (size_t) nbytes, MS_ASYNC); if (rc != 0) { - ereport(WARNING, + ereport(data_sync_elevel(WARNING), (errcode_for_file_access(), errmsg("could not flush dirty data: %m"))); /* NB: need to fall through to munmap()! */ @@ -574,7 +579,7 @@ pg_flush_data(int fd, off_t offset, off_t nbytes) void fsync_fname(const char *fname, bool isdir) { - fsync_fname_ext(fname, isdir, false, ERROR); + fsync_fname_ext(fname, isdir, false, data_sync_elevel(ERROR)); } /* @@ -639,7 +644,14 @@ durable_rename(const char *oldfile, const char *newfile, int elevel) errmsg("could not fsync file \"%s\": %m", newfile))); return -1; } - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", newfile))); + return -1; + } } /* Time to do the real deal... */ @@ -883,7 +895,7 @@ count_usable_fds(int max_to_probe, int *usable_fds, int *already_open) /* * set_max_safe_fds - * Determine number of filedescriptors that fd.c is allowed to use + * Determine number of file descriptors that fd.c is allowed to use */ void set_max_safe_fds(void) @@ -1029,28 +1041,13 @@ LruDelete(File file) vfdP = &VfdCache[file]; - /* - * Normally we should know the seek position, but if for some reason we - * have lost track of it, try again to get it. If we still can't get it, - * we have a problem: we will be unable to restore the file seek position - * when and if the file is re-opened. But we can't really throw an error - * and refuse to close the file, or activities such as transaction cleanup - * will be broken. - */ - if (FilePosIsUnknown(vfdP->seekPos)) - { - vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR); - if (FilePosIsUnknown(vfdP->seekPos)) - elog(LOG, "could not seek file \"%s\" before closing: %m", - vfdP->fileName); - } - /* * Close the file. We aren't expecting this to fail; if it does, better * to leak the FD than to mess up our internal state. */ - if (close(vfdP->fd)) - elog(LOG, "could not close file \"%s\": %m", vfdP->fileName); + if (close(vfdP->fd) != 0) + elog(vfdP->fdstate & FD_TEMP_FILE_LIMIT ? LOG : data_sync_elevel(LOG), + "could not close file \"%s\": %m", vfdP->fileName); vfdP->fd = VFD_CLOSED; --nfile; @@ -1113,33 +1110,6 @@ LruInsert(File file) { ++nfile; } - - /* - * Seek to the right position. We need no special case for seekPos - * equal to FileUnknownPos, as lseek() will certainly reject that - * (thus completing the logic noted in LruDelete() that we will fail - * to re-open a file if we couldn't get its seek position before - * closing). - */ - if (vfdP->seekPos != (off_t) 0) - { - if (lseek(vfdP->fd, vfdP->seekPos, SEEK_SET) < 0) - { - /* - * If we fail to restore the seek position, treat it like an - * open() failure. - */ - int save_errno = errno; - - elog(LOG, "could not seek file \"%s\" after re-opening: %m", - vfdP->fileName); - (void) close(vfdP->fd); - vfdP->fd = VFD_CLOSED; - --nfile; - errno = save_errno; - return -1; - } - } } /* @@ -1406,7 +1376,6 @@ PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode) /* Saved flags are adjusted to be OK for re-opening file */ vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL); vfdP->fileMode = fileMode; - vfdP->seekPos = 0; vfdP->fileSize = 0; vfdP->fdstate = 0x0; vfdP->resowner = NULL; @@ -1621,7 +1590,7 @@ OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError) * If the file is inside the top-level temporary directory, its name should * begin with PG_TEMP_FILE_PREFIX so that it can be identified as temporary * and deleted at startup by RemovePgTempFiles(). Alternatively, it can be - * inside a directory created with PathnameCreateTemporaryDir(), in which case + * inside a directory created with PathNameCreateTemporaryDir(), in which case * the prefix isn't needed. */ File @@ -1717,7 +1686,7 @@ PathNameDeleteTemporaryFile(const char *path, bool error_on_failure) if (errno != ENOENT) ereport(error_on_failure ? ERROR : LOG, (errcode_for_file_access(), - errmsg("cannot unlink temporary file \"%s\": %m", + errmsg("could not unlink temporary file \"%s\": %m", path))); return false; } @@ -1753,8 +1722,15 @@ FileClose(File file) if (!FileIsNotOpen(file)) { /* close the file */ - if (close(vfdP->fd)) - elog(LOG, "could not close file \"%s\": %m", vfdP->fileName); + if (close(vfdP->fd) != 0) + { + /* + * We may need to panic on failure to close non-temporary files; + * see LruDelete. + */ + elog(vfdP->fdstate & FD_TEMP_FILE_LIMIT ? LOG : data_sync_elevel(LOG), + "could not close file \"%s\": %m", vfdP->fileName); + } --nfile; vfdP->fd = VFD_CLOSED; @@ -1820,7 +1796,6 @@ FileClose(File file) /* * FilePrefetch - initiate asynchronous read of a given range of the file. - * The logical seek position is unaffected. * * Currently the only implementation of this function is using posix_fadvise * which is the simplest standardized interface that accomplishes this. @@ -1867,10 +1842,6 @@ FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info) file, VfdCache[file].fileName, (int64) offset, (int64) nbytes)); - /* - * Caution: do not call pg_flush_data with nbytes = 0, it could trash the - * file's seek position. We prefer to define that as a no-op here. - */ if (nbytes <= 0) return; @@ -1884,7 +1855,8 @@ FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info) } int -FileRead(File file, char *buffer, int amount, uint32 wait_event_info) +FileRead(File file, char *buffer, int amount, off_t offset, + uint32 wait_event_info) { int returnCode; Vfd *vfdP; @@ -1893,7 +1865,7 @@ FileRead(File file, char *buffer, int amount, uint32 wait_event_info) DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p", file, VfdCache[file].fileName, - (int64) VfdCache[file].seekPos, + (int64) offset, amount, buffer)); returnCode = FileAccess(file); @@ -1904,16 +1876,10 @@ FileRead(File file, char *buffer, int amount, uint32 wait_event_info) retry: pgstat_report_wait_start(wait_event_info); - returnCode = read(vfdP->fd, buffer, amount); + returnCode = pg_pread(vfdP->fd, buffer, amount, offset); pgstat_report_wait_end(); - if (returnCode >= 0) - { - /* if seekPos is unknown, leave it that way */ - if (!FilePosIsUnknown(vfdP->seekPos)) - vfdP->seekPos += returnCode; - } - else + if (returnCode < 0) { /* * Windows may run out of kernel buffers and return "Insufficient @@ -1939,16 +1905,14 @@ FileRead(File file, char *buffer, int amount, uint32 wait_event_info) /* OK to retry if interrupted */ if (errno == EINTR) goto retry; - - /* Trouble, so assume we don't know the file position anymore */ - vfdP->seekPos = FileUnknownPos; } return returnCode; } int -FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) +FileWrite(File file, char *buffer, int amount, off_t offset, + uint32 wait_event_info) { int returnCode; Vfd *vfdP; @@ -1957,7 +1921,7 @@ FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p", file, VfdCache[file].fileName, - (int64) VfdCache[file].seekPos, + (int64) offset, amount, buffer)); returnCode = FileAccess(file); @@ -1976,26 +1940,13 @@ FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) */ if (temp_file_limit >= 0 && (vfdP->fdstate & FD_TEMP_FILE_LIMIT)) { - off_t newPos; + off_t past_write = offset + amount; - /* - * Normally we should know the seek position, but if for some reason - * we have lost track of it, try again to get it. Here, it's fine to - * throw an error if we still can't get it. - */ - if (FilePosIsUnknown(vfdP->seekPos)) - { - vfdP->seekPos = lseek(vfdP->fd, (off_t) 0, SEEK_CUR); - if (FilePosIsUnknown(vfdP->seekPos)) - elog(ERROR, "could not seek file \"%s\": %m", vfdP->fileName); - } - - newPos = vfdP->seekPos + amount; - if (newPos > vfdP->fileSize) + if (past_write > vfdP->fileSize) { uint64 newTotal = temporary_files_size; - newTotal += newPos - vfdP->fileSize; + newTotal += past_write - vfdP->fileSize; if (newTotal > (uint64) temp_file_limit * (uint64) 1024) ereport(ERROR, (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED), @@ -2007,7 +1958,7 @@ FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) retry: errno = 0; pgstat_report_wait_start(wait_event_info); - returnCode = write(vfdP->fd, buffer, amount); + returnCode = pg_pwrite(VfdCache[file].fd, buffer, amount, offset); pgstat_report_wait_end(); /* if write didn't set errno, assume problem is no disk space */ @@ -2016,25 +1967,17 @@ FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) if (returnCode >= 0) { - /* if seekPos is unknown, leave it that way */ - if (!FilePosIsUnknown(vfdP->seekPos)) - vfdP->seekPos += returnCode; - /* * Maintain fileSize and temporary_files_size if it's a temp file. - * - * If seekPos is -1 (unknown), this will do nothing; but we could only - * get here in that state if we're not enforcing temporary_files_size, - * so we don't care. */ if (vfdP->fdstate & FD_TEMP_FILE_LIMIT) { - off_t newPos = vfdP->seekPos; + off_t past_write = offset + amount; - if (newPos > vfdP->fileSize) + if (past_write > vfdP->fileSize) { - temporary_files_size += newPos - vfdP->fileSize; - vfdP->fileSize = newPos; + temporary_files_size += past_write - vfdP->fileSize; + vfdP->fileSize = past_write; } } } @@ -2060,9 +2003,6 @@ FileWrite(File file, char *buffer, int amount, uint32 wait_event_info) /* OK to retry if interrupted */ if (errno == EINTR) goto retry; - - /* Trouble, so assume we don't know the file position anymore */ - vfdP->seekPos = FileUnknownPos; } return returnCode; @@ -2090,93 +2030,22 @@ FileSync(File file, uint32 wait_event_info) } off_t -FileSeek(File file, off_t offset, int whence) +FileSize(File file) { - Vfd *vfdP; - Assert(FileIsValid(file)); - DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d", - file, VfdCache[file].fileName, - (int64) VfdCache[file].seekPos, - (int64) offset, whence)); - - vfdP = &VfdCache[file]; + DO_DB(elog(LOG, "FileSize %d (%s)", + file, VfdCache[file].fileName)); if (FileIsNotOpen(file)) { - switch (whence) - { - case SEEK_SET: - if (offset < 0) - { - errno = EINVAL; - return (off_t) -1; - } - vfdP->seekPos = offset; - break; - case SEEK_CUR: - if (FilePosIsUnknown(vfdP->seekPos) || - vfdP->seekPos + offset < 0) - { - errno = EINVAL; - return (off_t) -1; - } - vfdP->seekPos += offset; - break; - case SEEK_END: - if (FileAccess(file) < 0) - return (off_t) -1; - vfdP->seekPos = lseek(vfdP->fd, offset, whence); - break; - default: - elog(ERROR, "invalid whence: %d", whence); - break; - } - } - else - { - switch (whence) - { - case SEEK_SET: - if (offset < 0) - { - errno = EINVAL; - return (off_t) -1; - } - if (vfdP->seekPos != offset) - vfdP->seekPos = lseek(vfdP->fd, offset, whence); - break; - case SEEK_CUR: - if (offset != 0 || FilePosIsUnknown(vfdP->seekPos)) - vfdP->seekPos = lseek(vfdP->fd, offset, whence); - break; - case SEEK_END: - vfdP->seekPos = lseek(vfdP->fd, offset, whence); - break; - default: - elog(ERROR, "invalid whence: %d", whence); - break; - } + if (FileAccess(file) < 0) + return (off_t) -1; } - return vfdP->seekPos; + return lseek(VfdCache[file].fd, 0, SEEK_END); } -/* - * XXX not actually used but here for completeness - */ -#ifdef NOT_USED -off_t -FileTell(File file) -{ - Assert(FileIsValid(file)); - DO_DB(elog(LOG, "FileTell %d (%s)", - file, VfdCache[file].fileName)); - return VfdCache[file].seekPos; -} -#endif - int FileTruncate(File file, off_t offset, uint32 wait_event_info) { @@ -2255,16 +2124,6 @@ FileGetRawMode(File file) return VfdCache[file].fileMode; } -/* - * FileGetSize - returns the size of file - */ -off_t -FileGetSize(File file) -{ - Assert(FileIsValid(file)); - return VfdCache[file].fileSize; -} - /* * Make room for another allocatedDescs[] array entry if needed and possible. * Returns true if an array element is available. @@ -2440,11 +2299,16 @@ OpenTransientFilePerm(const char *fileName, int fileFlags, mode_t fileMode) * Routines that want to initiate a pipe stream should use OpenPipeStream * rather than plain popen(). This lets fd.c deal with freeing FDs if * necessary. When done, call ClosePipeStream rather than pclose. + * + * This function also ensures that the popen'd program is run with default + * SIGPIPE processing, rather than the SIG_IGN setting the backend normally + * uses. This ensures desirable response to, eg, closing a read pipe early. */ FILE * OpenPipeStream(const char *command, const char *mode) { FILE *file; + int save_errno; DO_DB(elog(LOG, "OpenPipeStream: Allocated %d (%s)", numAllocatedDescs, command)); @@ -2462,8 +2326,13 @@ OpenPipeStream(const char *command, const char *mode) TryAgain: fflush(stdout); fflush(stderr); + pqsignal(SIGPIPE, SIG_DFL); errno = 0; - if ((file = popen(command, mode)) != NULL) + file = popen(command, mode); + save_errno = errno; + pqsignal(SIGPIPE, SIG_IGN); + errno = save_errno; + if (file != NULL) { AllocateDesc *desc = &allocatedDescs[numAllocatedDescs]; @@ -2476,12 +2345,9 @@ OpenPipeStream(const char *command, const char *mode) if (errno == EMFILE || errno == ENFILE) { - int save_errno = errno; - ereport(LOG, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of file descriptors: %m; release and retry"))); - errno = 0; if (ReleaseLruFile()) goto TryAgain; errno = save_errno; @@ -2902,17 +2768,19 @@ AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, /* * AtEOXact_Files * - * This routine is called during transaction commit or abort (it doesn't - * particularly care which). All still-open per-transaction temporary file - * VFDs are closed, which also causes the underlying files to be deleted - * (although they should've been closed already by the ResourceOwner - * cleanup). Furthermore, all "allocated" stdio files are closed. We also - * forget any transaction-local temp tablespace list. + * This routine is called during transaction commit or abort. All still-open + * per-transaction temporary file VFDs are closed, which also causes the + * underlying files to be deleted (although they should've been closed already + * by the ResourceOwner cleanup). Furthermore, all "allocated" stdio files are + * closed. We also forget any transaction-local temp tablespace list. + * + * The isCommit flag is used only to decide whether to emit warnings about + * unclosed files. */ void -AtEOXact_Files(void) +AtEOXact_Files(bool isCommit) { - CleanupTempFiles(false); + CleanupTempFiles(isCommit, false); tempTableSpaces = NULL; numTempTableSpaces = -1; } @@ -2926,12 +2794,15 @@ AtEOXact_Files(void) static void AtProcExit_Files(int code, Datum arg) { - CleanupTempFiles(true); + CleanupTempFiles(false, true); } /* * Close temporary files and delete their underlying files. * + * isCommit: if true, this is normal transaction commit, and we don't + * expect any remaining files; warn if there are some. + * * isProcExit: if true, this is being called as the backend process is * exiting. If that's the case, we should remove all temporary files; if * that's not the case, we are being called for transaction commit/abort @@ -2939,7 +2810,7 @@ AtProcExit_Files(int code, Datum arg) * also clean up "allocated" stdio files, dirs and fds. */ static void -CleanupTempFiles(bool isProcExit) +CleanupTempFiles(bool isCommit, bool isProcExit) { Index i; @@ -2979,6 +2850,11 @@ CleanupTempFiles(bool isProcExit) have_xact_temporary_files = false; } + /* Complain if any allocated files remain open at commit. */ + if (isCommit && numAllocatedDescs > 0) + elog(WARNING, "%d temporary files and directories not closed at end-of-transaction", + numAllocatedDescs); + /* Clean up "allocated" stdio files, dirs and fds. */ while (numAllocatedDescs > 0) FreeDesc(&allocatedDescs[0]); @@ -3041,11 +2917,10 @@ RemovePgTempFiles(void) /* * In EXEC_BACKEND case there is a pgsql_tmp directory at the top level of - * DataDir as well. + * DataDir as well. However, that is *not* cleaned here because doing so + * would create a race condition. It's done separately, earlier in + * postmaster startup. */ -#ifdef EXEC_BACKEND - RemovePgTempFilesInDir(PG_TEMP_FILES_DIR, true, false); -#endif } /* @@ -3063,7 +2938,7 @@ RemovePgTempFiles(void) * (These two flags could be replaced by one, but it seems clearer to keep * them separate.) */ -static void +void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, bool unlink_all) { DIR *temp_dir; @@ -3250,6 +3125,9 @@ looks_like_temp_rel_name(const char *name) * harmless cases such as read-only files in the data directory, and that's * not good either. * + * Note that if we previously crashed due to a PANIC on fsync(), we'll be + * rewriting all changes again during recovery. + * * Note we assume we're chdir'd into PGDATA to begin with. */ void @@ -3323,7 +3201,8 @@ SyncDataDirectory(void) * * Errors are reported at level elevel, which might be ERROR or less. * - * See also walkdir in initdb.c, which is a frontend version of this logic. + * See also walkdir in file_utils.c, which is a frontend version of this + * logic. */ static void walkdir(const char *path, @@ -3417,7 +3296,10 @@ pre_sync_fname(const char *fname, bool isdir, int elevel) */ pg_flush_data(fd, 0, 0); - (void) CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", fname))); } #endif /* PG_FLUSH_DATA_WORKS */ @@ -3440,7 +3322,7 @@ unlink_if_exists_fname(const char *fname, bool isdir, int elevel) if (rmdir(fname) != 0 && errno != ENOENT) ereport(elevel, (errcode_for_file_access(), - errmsg("could not rmdir directory \"%s\": %m", fname))); + errmsg("could not remove directory \"%s\": %m", fname))); } else { @@ -3501,7 +3383,7 @@ fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel) * Some OSes don't allow us to fsync directories at all, so we can ignore * those errors. Anything else needs to be logged. */ - if (returncode != 0 && !(isdir && errno == EBADF)) + if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL))) { int save_errno; @@ -3516,7 +3398,13 @@ fsync_fname_ext(const char *fname, bool isdir, bool ignore_perm, int elevel) return -1; } - (void) CloseTransientFile(fd); + if (CloseTransientFile(fd) != 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", fname))); + return -1; + } return 0; } @@ -3552,8 +3440,8 @@ fsync_parent_path(const char *fname, int elevel) /* * Create a PostgreSQL data sub-directory * - * The data directory itself, along with most other directories, are created at - * initdb-time, but we do have some occations where we create directories from + * The data directory itself, and most of its sub-directories, are created at + * initdb time, but we do have some occasions when we create directories in * the backend (CREATE TABLESPACE, for example). In those cases, we want to * make sure that those directories are created consistently. Today, that means * making sure that the created directory has the correct permissions, which is @@ -3562,8 +3450,8 @@ fsync_parent_path(const char *fname, int elevel) * Note that we also set the umask() based on what we understand the correct * permissions to be (see file_perm.c). * - * For permissions other than the default mkdir() can be used directly, but be - * sure to consider carefully such cases -- a directory with incorrect + * For permissions other than the default, mkdir() can be used directly, but + * be sure to consider carefully such cases -- a sub-directory with incorrect * permissions in a PostgreSQL data directory could cause backups and other * processes to fail. */ @@ -3572,3 +3460,26 @@ MakePGDirectory(const char *directoryName) { return mkdir(directoryName, pg_dir_create_mode); } + +/* + * Return the passed-in error level, or PANIC if data_sync_retry is off. + * + * Failure to fsync any data file is cause for immediate panic, unless + * data_sync_retry is enabled. Data may have been written to the operating + * system and removed from our buffer pool already, and if we are running on + * an operating system that forgets dirty data on write-back failure, there + * may be only one copy of the data remaining: in the WAL. A later attempt to + * fsync again might falsely report success. Therefore we must not allow any + * further checkpoints to be attempted. data_sync_retry can in theory be + * enabled on systems known not to drop dirty buffered data on write-back + * failure (with the likely outcome that checkpoints will continue to fail + * until the underlying problem is fixed). + * + * Any code that reports a failure from fsync() or related functions should + * filter the error level with this function. + */ +int +data_sync_elevel(int elevel) +{ + return data_sync_retry ? elevel : PANIC; +} diff --git a/src/backend/storage/file/reinit.c b/src/backend/storage/file/reinit.c index 74ff6c359b5..ccdf80d614c 100644 --- a/src/backend/storage/file/reinit.c +++ b/src/backend/storage/file/reinit.c @@ -3,7 +3,7 @@ * reinit.c * Reinitialization of unlogged relations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,9 +24,9 @@ #include "utils/memutils.h" static void ResetUnloggedRelationsInTablespaceDir(const char *tsdirname, - int op); + int op); static void ResetUnloggedRelationsInDbspaceDir(const char *dbspacedirname, - int op); + int op); typedef struct { diff --git a/src/backend/storage/file/sharedfileset.c b/src/backend/storage/file/sharedfileset.c index 0ac86965366..26e5091172d 100644 --- a/src/backend/storage/file/sharedfileset.c +++ b/src/backend/storage/file/sharedfileset.c @@ -3,13 +3,13 @@ * sharedfileset.c * Shared temporary file management. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION * src/backend/storage/file/sharedfileset.c * - * SharefFileSets provide a temporary namespace (think directory) so that + * SharedFileSets provide a temporary namespace (think directory) so that * files can be discovered by name, and a shared ownership semantics so that * shared files survive until the last user detaches. * @@ -18,13 +18,15 @@ #include "postgres.h" -#include "access/hash.h" +#include + #include "catalog/pg_tablespace.h" #include "commands/tablespace.h" #include "miscadmin.h" #include "storage/dsm.h" #include "storage/sharedfileset.h" #include "utils/builtins.h" +#include "utils/hashutils.h" static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum); static void SharedFileSetPath(char *path, SharedFileSet *fileset, Oid tablespace); @@ -141,7 +143,7 @@ SharedFileSetOpen(SharedFileSet *fileset, const char *name) } /* - * Delete a file that was created with PathNameCreateShared(). + * Delete a file that was created with SharedFileSetCreate(). * Return true if the file existed, false if didn't. */ bool @@ -214,9 +216,9 @@ SharedFileSetPath(char *path, SharedFileSet *fileset, Oid tablespace) char tempdirpath[MAXPGPATH]; TempTablespacePath(tempdirpath, tablespace); - snprintf(path, MAXPGPATH, "%s/%s%d.%u.sharedfileset", + snprintf(path, MAXPGPATH, "%s/%s%lu.%u.sharedfileset", tempdirpath, PG_TEMP_FILE_PREFIX, - fileset->creator_pid, fileset->number); + (unsigned long) fileset->creator_pid, fileset->number); } /* diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index 65c4e74999f..7e8e7e79a3d 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free space in relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -105,12 +105,12 @@ static uint8 fsm_space_needed_to_cat(Size needed); static Size fsm_space_cat_to_avail(uint8 cat); /* workhorse functions for various operations */ -static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, - uint8 newValue, uint8 minValue); +static int fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, + uint8 newValue, uint8 minValue); static BlockNumber fsm_search(Relation rel, uint8 min_cat); static uint8 fsm_vacuum_page(Relation rel, FSMAddress addr, - BlockNumber start, BlockNumber end, - bool *eof); + BlockNumber start, BlockNumber end, + bool *eof); /******** Public API ********/ @@ -223,7 +223,7 @@ XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk, } /* - * GetRecordedFreePage - return the amount of free space on a particular page, + * GetRecordedFreeSpace - return the amount of free space on a particular page, * according to the FSM. */ Size @@ -247,16 +247,18 @@ GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk) } /* - * FreeSpaceMapTruncateRel - adjust for truncation of a relation. - * - * The caller must hold AccessExclusiveLock on the relation, to ensure that - * other backends receive the smgr invalidation event that this function sends - * before they access the FSM again. + * FreeSpaceMapPrepareTruncateRel - prepare for truncation of a relation. * * nblocks is the new size of the heap. + * + * Return the number of blocks of new FSM. + * If it's InvalidBlockNumber, there is nothing to truncate; + * otherwise the caller is responsible for calling smgrtruncate() + * to truncate the FSM pages, and FreeSpaceMapVacuumRange() + * to update upper-level pages in the FSM. */ -void -FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks) +BlockNumber +FreeSpaceMapPrepareTruncateRel(Relation rel, BlockNumber nblocks) { BlockNumber new_nfsmblocks; FSMAddress first_removed_address; @@ -270,7 +272,7 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks) * truncate. */ if (!smgrexists(rel->rd_smgr, FSM_FORKNUM)) - return; + return InvalidBlockNumber; /* Get the location in the FSM of the first removed heap block */ first_removed_address = fsm_get_location(nblocks, &first_removed_slot); @@ -285,7 +287,7 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks) { buf = fsm_readbuf(rel, first_removed_address, false); if (!BufferIsValid(buf)) - return; /* nothing to do; the FSM was already smaller */ + return InvalidBlockNumber; /* nothing to do; the FSM was already smaller */ LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); /* NO EREPORT(ERROR) from here till changes are logged */ @@ -315,28 +317,10 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks) { new_nfsmblocks = fsm_logical_to_physical(first_removed_address); if (smgrnblocks(rel->rd_smgr, FSM_FORKNUM) <= new_nfsmblocks) - return; /* nothing to do; the FSM was already smaller */ + return InvalidBlockNumber; /* nothing to do; the FSM was already smaller */ } - /* Truncate the unused FSM pages, and send smgr inval message */ - smgrtruncate(rel->rd_smgr, FSM_FORKNUM, new_nfsmblocks); - - /* - * We might as well update the local smgr_fsm_nblocks setting. - * smgrtruncate sent an smgr cache inval message, which will cause other - * backends to invalidate their copy of smgr_fsm_nblocks, and this one too - * at the next command boundary. But this ensures it isn't outright wrong - * until then. - */ - if (rel->rd_smgr) - rel->rd_smgr->smgr_fsm_nblocks = new_nfsmblocks; - - /* - * Update upper-level FSM pages to account for the truncation. This is - * important because the just-truncated pages were likely marked as - * all-free, and would be preferentially selected. - */ - FreeSpaceMapVacuumRange(rel, nblocks, InvalidBlockNumber); + return new_nfsmblocks; } /* @@ -417,7 +401,7 @@ fsm_space_cat_to_avail(uint8 cat) /* * Which category does a page need to have, to accommodate x bytes of data? - * While fsm_size_to_avail_cat() rounds down, this needs to round up. + * While fsm_space_avail_to_cat() rounds down, this needs to round up. */ static uint8 fsm_space_needed_to_cat(Size needed) @@ -580,10 +564,29 @@ fsm_readbuf(Relation rel, FSMAddress addr, bool extend) * pages than error out. Since the FSM changes are not WAL-logged, the * so-called torn page problem on crash can lead to pages with corrupt * headers, for example. + * + * The initialize-the-page part is trickier than it looks, because of the + * possibility of multiple backends doing this concurrently, and our + * desire to not uselessly take the buffer lock in the normal path where + * the page is OK. We must take the lock to initialize the page, so + * recheck page newness after we have the lock, in case someone else + * already did it. Also, because we initially check PageIsNew with no + * lock, it's possible to fall through and return the buffer while someone + * else is still initializing the page (i.e., we might see pd_upper as set + * but other page header fields are still zeroes). This is harmless for + * callers that will take a buffer lock themselves, but some callers + * inspect the page without any lock at all. The latter is OK only so + * long as it doesn't depend on the page header having correct contents. + * Current usage is safe because PageGetContents() does not require that. */ buf = ReadBufferExtended(rel, FSM_FORKNUM, blkno, RBM_ZERO_ON_ERROR, NULL); if (PageIsNew(BufferGetPage(buf))) - PageInit(BufferGetPage(buf), BLCKSZ, 0); + { + LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); + if (PageIsNew(BufferGetPage(buf))) + PageInit(BufferGetPage(buf), BLCKSZ, 0); + LockBuffer(buf, BUFFER_LOCK_UNLOCK); + } return buf; } @@ -596,10 +599,9 @@ static void fsm_extend(Relation rel, BlockNumber fsm_nblocks) { BlockNumber fsm_nblocks_now; - Page pg; + PGAlignedBlock pg; - pg = (Page) palloc(BLCKSZ); - PageInit(pg, BLCKSZ, 0); + PageInit((Page) pg.data, BLCKSZ, 0); /* * We use the relation extension lock to lock out other backends trying to @@ -629,10 +631,10 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks) while (fsm_nblocks_now < fsm_nblocks) { - PageSetChecksumInplace(pg, fsm_nblocks_now); + PageSetChecksumInplace((Page) pg.data, fsm_nblocks_now); smgrextend(rel->rd_smgr, FSM_FORKNUM, fsm_nblocks_now, - (char *) pg, false); + pg.data, false); fsm_nblocks_now++; } @@ -640,8 +642,6 @@ fsm_extend(Relation rel, BlockNumber fsm_nblocks) rel->rd_smgr->smgr_fsm_nblocks = fsm_nblocks_now; UnlockRelationForExtension(rel, ExclusiveLock); - - pfree(pg); } /* diff --git a/src/backend/storage/freespace/fsmpage.c b/src/backend/storage/freespace/fsmpage.c index 2b382417c5b..cf7f03f12dd 100644 --- a/src/backend/storage/freespace/fsmpage.c +++ b/src/backend/storage/freespace/fsmpage.c @@ -4,7 +4,7 @@ * routines to search and manipulate one FSM page. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/freespace/indexfsm.c b/src/backend/storage/freespace/indexfsm.c index e21047b96f2..58cedeaa9f7 100644 --- a/src/backend/storage/freespace/indexfsm.c +++ b/src/backend/storage/freespace/indexfsm.c @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free pages in relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/ipc/Makefile b/src/backend/storage/ipc/Makefile index 9dbdc26c9bb..49e7c9f15e8 100644 --- a/src/backend/storage/ipc/Makefile +++ b/src/backend/storage/ipc/Makefile @@ -9,7 +9,7 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = barrier.o dsm_impl.o dsm.o ipc.o ipci.o latch.o pmsignal.o procarray.o \ - procsignal.o shmem.o shmqueue.o shm_mq.o shm_toc.o sinval.o \ - sinvaladt.o standby.o + procsignal.o shmem.o shmqueue.o shm_mq.o shm_toc.o signalfuncs.o \ + sinval.o sinvaladt.o standby.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c index 00ab57c0f62..83cbe33107c 100644 --- a/src/backend/storage/ipc/barrier.c +++ b/src/backend/storage/ipc/barrier.c @@ -3,7 +3,7 @@ * barrier.c * Barriers for synchronizing cooperating processes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * From Wikipedia[1]: "In parallel computing, a barrier is a type of @@ -113,9 +113,9 @@ BarrierInit(Barrier *barrier, int participants) * too and then return. Increments the current phase. The caller must be * attached. * - * While waiting, pg_stat_activity shows a wait_event_class and wait_event + * While waiting, pg_stat_activity shows a wait_event_type and wait_event * controlled by the wait_event_info passed in, which should be a value from - * from one of the WaitEventXXX enums defined in pgstat.h. + * one of the WaitEventXXX enums defined in pgstat.h. * * Return true in one arbitrarily chosen participant. Return false in all * others. The return code can be used to elect one participant to execute a @@ -226,9 +226,9 @@ BarrierAttach(Barrier *barrier) } /* - * Detach from a barrier. This may release other waiters from BarrierWait and - * advance the phase if they were only waiting for this backend. Return true - * if this participant was the last to detach. + * Detach from a barrier. This may release other waiters from + * BarrierArriveAndWait() and advance the phase if they were only waiting for + * this backend. Return true if this participant was the last to detach. */ bool BarrierDetach(Barrier *barrier) diff --git a/src/backend/storage/ipc/dsm.c b/src/backend/storage/ipc/dsm.c index f1f75b73f50..d9a3394baa6 100644 --- a/src/backend/storage/ipc/dsm.c +++ b/src/backend/storage/ipc/dsm.c @@ -14,7 +14,7 @@ * hard postmaster crash, remaining segments will be removed, if they * still exist, at the next postmaster startup. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -98,7 +98,7 @@ static void dsm_cleanup_for_mmap(void); static void dsm_postmaster_shutdown(int code, Datum arg); static dsm_segment *dsm_create_descriptor(void); static bool dsm_control_segment_sane(dsm_control_header *control, - Size mapped_size); + Size mapped_size); static uint64 dsm_control_bytes_needed(uint32 nitems); /* Has this backend initialized the dynamic shared memory system yet? */ @@ -150,10 +150,6 @@ dsm_postmaster_startup(PGShmemHeader *shim) Assert(!IsUnderPostmaster); - /* If dynamic shared memory is disabled, there's nothing to do. */ - if (dynamic_shared_memory_type == DSM_IMPL_NONE) - return; - /* * If we're using the mmap implementations, clean up any leftovers. * Cleanup isn't needed on Windows, and happens earlier in startup for @@ -219,10 +215,6 @@ dsm_cleanup_using_control_segment(dsm_handle old_control_handle) uint32 i; dsm_control_header *old_control; - /* If dynamic shared memory is disabled, there's nothing to do. */ - if (dynamic_shared_memory_type == DSM_IMPL_NONE) - return; - /* * Try to attach the segment. If this fails, it probably just means that * the operating system has been rebooted and the segment no longer @@ -391,14 +383,7 @@ dsm_postmaster_shutdown(int code, Datum arg) static void dsm_backend_startup(void) { - /* If dynamic shared memory is disabled, reject this. */ - if (dynamic_shared_memory_type == DSM_IMPL_NONE) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("dynamic shared memory is disabled"), - errhint("Set dynamic_shared_memory_type to a value other than \"none\"."))); - -#ifdef EXEC_BACKEND + if (dsm_control == NULL) { void *control_address = NULL; @@ -419,12 +404,10 @@ dsm_backend_startup(void) errmsg("dynamic shared memory control segment is not valid"))); } } -#endif dsm_init_done = true; } -#ifdef EXEC_BACKEND /* * When running under EXEC_BACKEND, we get a callback here when the main * shared memory segment is re-attached, so that we can record the control @@ -436,7 +419,6 @@ dsm_set_control_handle(dsm_handle h) Assert(dsm_control_handle == 0 && h != 0); dsm_control_handle = h; } -#endif /* * Create a new dynamic shared memory segment. @@ -444,7 +426,7 @@ dsm_set_control_handle(dsm_handle h) * If there is a non-NULL CurrentResourceOwner, the new segment is associated * with it and must be detached before the resource owner releases, or a * warning will be logged. If CurrentResourceOwner is NULL, the segment - * remains attached until explicitely detached or the session ends. + * remains attached until explicitly detached or the session ends. * Creating with a NULL CurrentResourceOwner is equivalent to creating * with a non-NULL CurrentResourceOwner and then calling dsm_pin_mapping. */ @@ -542,7 +524,7 @@ dsm_create(Size size, int flags) * If there is a non-NULL CurrentResourceOwner, the attached segment is * associated with it and must be detached before the resource owner releases, * or a warning will be logged. Otherwise the segment remains attached until - * explicitely detached or the session ends. See the note atop dsm_create(). + * explicitly detached or the session ends. See the note atop dsm_create(). */ dsm_segment * dsm_attach(dsm_handle h) @@ -584,22 +566,20 @@ dsm_attach(dsm_handle h) nitems = dsm_control->nitems; for (i = 0; i < nitems; ++i) { - /* If the reference count is 0, the slot is actually unused. */ - if (dsm_control->item[i].refcnt == 0) + /* + * If the reference count is 0, the slot is actually unused. If the + * reference count is 1, the slot is still in use, but the segment is + * in the process of going away; even if the handle matches, another + * slot may already have started using the same handle value by + * coincidence so we have to keep searching. + */ + if (dsm_control->item[i].refcnt <= 1) continue; /* If the handle doesn't match, it's not the slot we want. */ if (dsm_control->item[i].handle != seg->handle) continue; - /* - * If the reference count is 1, the slot is still in use, but the - * segment is in the process of going away. Treat that as if we - * didn't find a match. - */ - if (dsm_control->item[i].refcnt == 1) - break; - /* Otherwise we've found a match. */ dsm_control->item[i].refcnt++; seg->control_slot = i; @@ -668,38 +648,6 @@ dsm_detach_all(void) &dsm_control_mapped_size, ERROR); } -/* - * Resize an existing shared memory segment. - * - * This may cause the shared memory segment to be remapped at a different - * address. For the caller's convenience, we return the mapped address. - */ -void * -dsm_resize(dsm_segment *seg, Size size) -{ - Assert(seg->control_slot != INVALID_CONTROL_SLOT); - dsm_impl_op(DSM_OP_RESIZE, seg->handle, size, &seg->impl_private, - &seg->mapped_address, &seg->mapped_size, ERROR); - return seg->mapped_address; -} - -/* - * Remap an existing shared memory segment. - * - * This is intended to be used when some other process has extended the - * mapping using dsm_resize(), but we've still only got the initial - * portion mapped. Since this might change the address at which the - * segment is mapped, we return the new mapped address. - */ -void * -dsm_remap(dsm_segment *seg) -{ - dsm_impl_op(DSM_OP_ATTACH, seg->handle, 0, &seg->impl_private, - &seg->mapped_address, &seg->mapped_size, ERROR); - - return seg->mapped_address; -} - /* * Detach from a shared memory segment, destroying the segment if we * remove the last reference. @@ -893,8 +841,8 @@ dsm_unpin_segment(dsm_handle handle) LWLockAcquire(DynamicSharedMemoryControlLock, LW_EXCLUSIVE); for (i = 0; i < dsm_control->nitems; ++i) { - /* Skip unused slots. */ - if (dsm_control->item[i].refcnt == 0) + /* Skip unused slots and segments that are concurrently going away. */ + if (dsm_control->item[i].refcnt <= 1) continue; /* If we've found our handle, we can stop searching. */ diff --git a/src/backend/storage/ipc/dsm_impl.c b/src/backend/storage/ipc/dsm_impl.c index 2fca9fae512..2879b84bf61 100644 --- a/src/backend/storage/ipc/dsm_impl.c +++ b/src/backend/storage/ipc/dsm_impl.c @@ -36,7 +36,7 @@ * * As ever, Windows requires its own implementation. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -47,6 +47,7 @@ */ #include "postgres.h" +#include "miscadmin.h" #include #include @@ -72,24 +73,24 @@ #ifdef USE_DSM_POSIX static bool dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, - void **impl_private, void **mapped_address, - Size *mapped_size, int elevel); + void **impl_private, void **mapped_address, + Size *mapped_size, int elevel); static int dsm_impl_posix_resize(int fd, off_t size); #endif #ifdef USE_DSM_SYSV static bool dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, - void **impl_private, void **mapped_address, - Size *mapped_size, int elevel); + void **impl_private, void **mapped_address, + Size *mapped_size, int elevel); #endif #ifdef USE_DSM_WINDOWS static bool dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, - void **impl_private, void **mapped_address, - Size *mapped_size, int elevel); + void **impl_private, void **mapped_address, + Size *mapped_size, int elevel); #endif #ifdef USE_DSM_MMAP static bool dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, - void **impl_private, void **mapped_address, - Size *mapped_size, int elevel); + void **impl_private, void **mapped_address, + Size *mapped_size, int elevel); #endif static int errcode_for_dynamic_shared_memory(void); @@ -106,7 +107,6 @@ const struct config_enum_entry dynamic_shared_memory_options[] = { #ifdef USE_DSM_MMAP {"mmap", DSM_IMPL_MMAP, false}, #endif - {"none", DSM_IMPL_NONE, false}, {NULL, 0, false} }; @@ -127,14 +127,9 @@ int dynamic_shared_memory_type; * map it. * * DSM_OP_ATTACH. Map the segment, whose size must be the request_size. - * The segment may already be mapped; any existing mapping should be removed - * before creating a new one. * * DSM_OP_DETACH. Unmap the segment. * - * DSM_OP_RESIZE. Resize the segment to the given request_size and - * remap the segment at that new size. - * * DSM_OP_DESTROY. Unmap the segment, if it is mapped. Destroy the * segment. * @@ -142,8 +137,7 @@ int dynamic_shared_memory_type; * op: The operation to be performed. * handle: The handle of an existing object, or for DSM_OP_CREATE, the * a new handle the caller wants created. - * request_size: For DSM_OP_CREATE, the requested size. For DSM_OP_RESIZE, - * the new size. Otherwise, 0. + * request_size: For DSM_OP_CREATE, the requested size. Otherwise, 0. * impl_private: Private, implementation-specific data. Will be a pointer * to NULL for the first operation on a shared memory segment within this * backend; thereafter, it will point to the value to which it was set @@ -165,7 +159,7 @@ dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel) { - Assert(op == DSM_OP_CREATE || op == DSM_OP_RESIZE || request_size == 0); + Assert(op == DSM_OP_CREATE || request_size == 0); Assert((op != DSM_OP_CREATE && op != DSM_OP_ATTACH) || (*mapped_address == NULL && *mapped_size == 0)); @@ -198,33 +192,6 @@ dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, } } -/* - * Does the current dynamic shared memory implementation support resizing - * segments? (The answer here could be platform-dependent in the future, - * since AIX allows shmctl(shmid, SHM_RESIZE, &buffer), though you apparently - * can't resize segments to anything larger than 256MB that way. For now, - * we keep it simple.) - */ -bool -dsm_impl_can_resize(void) -{ - switch (dynamic_shared_memory_type) - { - case DSM_IMPL_NONE: - return false; - case DSM_IMPL_POSIX: - return true; - case DSM_IMPL_SYSV: - return false; - case DSM_IMPL_WINDOWS: - return false; - case DSM_IMPL_MMAP: - return true; - default: - return false; /* should not happen */ - } -} - #ifdef USE_DSM_POSIX /* * Operating system primitives to support POSIX shared memory. @@ -278,7 +245,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, } /* - * Create new segment or open an existing one for attach or resize. + * Create new segment or open an existing one for attach. * * Even though we're not going through fd.c, we should be safe against * running out of file descriptors, because of NUM_RESERVED_FDS. We're @@ -298,7 +265,7 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, /* * If we're attaching the segment, determine the current size; if we are - * creating or resizing the segment, set the size to the requested value. + * creating the segment, set the size to the requested value. */ if (op == DSM_OP_ATTACH) { @@ -321,18 +288,24 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, } request_size = st.st_size; } - else if (*mapped_size != request_size && - dsm_impl_posix_resize(fd, request_size) != 0) + else if (dsm_impl_posix_resize(fd, request_size) != 0) { int save_errno; /* Back out what's already been done. */ save_errno = errno; close(fd); - if (op == DSM_OP_CREATE) - shm_unlink(name); + shm_unlink(name); errno = save_errno; + /* + * If we received a query cancel or termination signal, we will have + * EINTR set here. If the caller said that errors are OK here, check + * for interrupts immediately. + */ + if (errno == EINTR && elevel >= ERROR) + CHECK_FOR_INTERRUPTS(); + ereport(elevel, (errcode_for_dynamic_shared_memory(), errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m", @@ -340,35 +313,6 @@ dsm_impl_posix(dsm_op op, dsm_handle handle, Size request_size, return false; } - /* - * If we're reattaching or resizing, we must remove any existing mapping, - * unless we've already got the right thing mapped. - */ - if (*mapped_address != NULL) - { - if (*mapped_size == request_size) - return true; - if (munmap(*mapped_address, *mapped_size) != 0) - { - int save_errno; - - /* Back out what's already been done. */ - save_errno = errno; - close(fd); - if (op == DSM_OP_CREATE) - shm_unlink(name); - errno = save_errno; - - ereport(elevel, - (errcode_for_dynamic_shared_memory(), - errmsg("could not unmap shared memory segment \"%s\": %m", - name))); - return false; - } - *mapped_address = NULL; - *mapped_size = 0; - } - /* Map it. */ address = mmap(NULL, request_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HASSEMAPHORE | MAP_NOSYNC, fd, 0); @@ -422,11 +366,15 @@ dsm_impl_posix_resize(int fd, off_t size) #if defined(HAVE_POSIX_FALLOCATE) && defined(__linux__) if (rc == 0) { - /* We may get interrupted, if so just retry. */ + /* + * We may get interrupted. If so, just retry unless there is an + * interrupt pending. This avoids the possibility of looping forever + * if another backend is repeatedly trying to interrupt us. + */ do { rc = posix_fallocate(fd, 0, size); - } while (rc == EINTR); + } while (rc == EINTR && !(ProcDiePending || QueryCancelPending)); /* * The caller expects errno to be set, but posix_fallocate() doesn't @@ -447,10 +395,9 @@ dsm_impl_posix_resize(int fd, off_t size) * Operating system primitives to support System V shared memory. * * System V shared memory segments are manipulated using shmget(), shmat(), - * shmdt(), and shmctl(). There's no portable way to resize such - * segments. As the default allocation limits for System V shared memory - * are usually quite low, the POSIX facilities may be preferable; but - * those are not supported everywhere. + * shmdt(), and shmctl(). As the default allocation limits for System V + * shared memory are usually quite low, the POSIX facilities may be + * preferable; but those are not supported everywhere. */ static bool dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, @@ -463,17 +410,6 @@ dsm_impl_sysv(dsm_op op, dsm_handle handle, Size request_size, char name[64]; int *ident_cache; - /* Resize is not supported for System V shared memory. */ - if (op == DSM_OP_RESIZE) - { - elog(elevel, "System V shared memory segments cannot be resized"); - return false; - } - - /* Since resize isn't supported, reattach is a no-op. */ - if (op == DSM_OP_ATTACH && *mapped_address != NULL) - return true; - /* * POSIX shared memory and mmap-based shared memory identify segments with * names. To avoid needless error message variation, we use the handle as @@ -660,17 +596,6 @@ dsm_impl_windows(dsm_op op, dsm_handle handle, Size request_size, char name[64]; MEMORY_BASIC_INFORMATION info; - /* Resize is not supported for Windows shared memory. */ - if (op == DSM_OP_RESIZE) - { - elog(elevel, "Windows shared memory segments cannot be resized"); - return false; - } - - /* Since resize isn't supported, reattach is a no-op. */ - if (op == DSM_OP_ATTACH && *mapped_address != NULL) - return true; - /* * Storing the shared memory segment in the Global\ namespace, can allow * any process running in any session to access that file mapping object @@ -881,7 +806,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, return true; } - /* Create new segment or open an existing one for attach or resize. */ + /* Create new segment or open an existing one for attach. */ flags = O_RDWR | (op == DSM_OP_CREATE ? O_CREAT | O_EXCL : 0); if ((fd = OpenTransientFile(name, flags)) == -1) { @@ -895,7 +820,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, /* * If we're attaching the segment, determine the current size; if we are - * creating or resizing the segment, set the size to the requested value. + * creating the segment, set the size to the requested value. */ if (op == DSM_OP_ATTACH) { @@ -918,24 +843,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, } request_size = st.st_size; } - else if (*mapped_size > request_size && ftruncate(fd, request_size)) - { - int save_errno; - - /* Back out what's already been done. */ - save_errno = errno; - close(fd); - if (op == DSM_OP_CREATE) - unlink(name); - errno = save_errno; - - ereport(elevel, - (errcode_for_dynamic_shared_memory(), - errmsg("could not resize shared memory segment \"%s\" to %zu bytes: %m", - name, request_size))); - return false; - } - else if (*mapped_size < request_size) + else { /* * Allocate a buffer full of zeros. @@ -975,8 +883,7 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, /* Back out what's already been done. */ save_errno = errno; CloseTransientFile(fd); - if (op == DSM_OP_CREATE) - unlink(name); + unlink(name); errno = save_errno ? save_errno : ENOSPC; ereport(elevel, @@ -987,35 +894,6 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, } } - /* - * If we're reattaching or resizing, we must remove any existing mapping, - * unless we've already got the right thing mapped. - */ - if (*mapped_address != NULL) - { - if (*mapped_size == request_size) - return true; - if (munmap(*mapped_address, *mapped_size) != 0) - { - int save_errno; - - /* Back out what's already been done. */ - save_errno = errno; - CloseTransientFile(fd); - if (op == DSM_OP_CREATE) - unlink(name); - errno = save_errno; - - ereport(elevel, - (errcode_for_dynamic_shared_memory(), - errmsg("could not unmap shared memory segment \"%s\": %m", - name))); - return false; - } - *mapped_address = NULL; - *mapped_size = 0; - } - /* Map it. */ address = mmap(NULL, request_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HASSEMAPHORE | MAP_NOSYNC, fd, 0); @@ -1038,7 +916,15 @@ dsm_impl_mmap(dsm_op op, dsm_handle handle, Size request_size, } *mapped_address = address; *mapped_size = request_size; - CloseTransientFile(fd); + + if (CloseTransientFile(fd) != 0) + { + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not close shared memory segment \"%s\": %m", + name))); + return false; + } return true; } diff --git a/src/backend/storage/ipc/ipc.c b/src/backend/storage/ipc/ipc.c index 53f7c1e77ea..05d02c23f55 100644 --- a/src/backend/storage/ipc/ipc.c +++ b/src/backend/storage/ipc/ipc.c @@ -8,7 +8,7 @@ * exit-time cleanup for either a postmaster or a backend. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -272,6 +272,8 @@ shmem_exit(int code) on_shmem_exit_list[on_shmem_exit_index].function(code, on_shmem_exit_list[on_shmem_exit_index].arg); on_shmem_exit_index = 0; + + shmem_exit_inprogress = false; } /* ---------------------------------------------------------------- diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c index 0c86a581c03..77904feb0fa 100644 --- a/src/backend/storage/ipc/ipci.c +++ b/src/backend/storage/ipc/ipci.c @@ -3,7 +3,7 @@ * ipci.c * POSTGRES inter-process communication initialization code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -44,9 +44,10 @@ #include "storage/procsignal.h" #include "storage/sinvaladt.h" #include "storage/spin.h" -#include "utils/backend_random.h" #include "utils/snapmgr.h" +/* GUCs */ +int shared_memory_type = DEFAULT_SHARED_MEMORY_TYPE; shmem_startup_hook_type shmem_startup_hook = NULL; @@ -88,12 +89,9 @@ RequestAddinShmemSpace(Size size) * through the same code as before. (Note that the called routines mostly * check IsUnderPostmaster, rather than EXEC_BACKEND, to detect this case. * This is a bit code-wasteful and could be cleaned up.) - * - * If "makePrivate" is true then we only need private memory, not shared - * memory. This is true for a standalone backend, false for a postmaster. */ void -CreateSharedMemoryAndSemaphores(bool makePrivate, int port) +CreateSharedMemoryAndSemaphores(void) { PGShmemHeader *shim = NULL; @@ -149,7 +147,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) size = add_size(size, BTreeShmemSize()); size = add_size(size, SyncScanShmemSize()); size = add_size(size, AsyncShmemSize()); - size = add_size(size, BackendRandomShmemSize()); #ifdef EXEC_BACKEND size = add_size(size, ShmemBackendArraySize()); #endif @@ -166,14 +163,14 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) /* * Create the shmem segment */ - seghdr = PGSharedMemoryCreate(size, makePrivate, port, &shim); + seghdr = PGSharedMemoryCreate(size, &shim); InitShmemAccess(seghdr); /* * Create semaphores */ - PGReserveSemaphores(numSemas, port); + PGReserveSemaphores(numSemas); /* * If spinlocks are disabled, initialize emulation layer (which @@ -187,20 +184,18 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) { /* * We are reattaching to an existing shared memory segment. This - * should only be reached in the EXEC_BACKEND case, and even then only - * with makePrivate == false. + * should only be reached in the EXEC_BACKEND case. */ -#ifdef EXEC_BACKEND - Assert(!makePrivate); -#else - elog(PANIC, "should be attached to shared memory already"); +#ifndef EXEC_BACKEND + if (!IsOnlineUpgrade) + elog(PANIC, "should be attached to shared memory already"); #endif } /* * Set up shared memory allocation mechanism */ - if (!IsUnderPostmaster) + if (!IsUnderPostmaster && !IsOnlineUpgrade) InitShmemAllocation(); /* @@ -269,7 +264,6 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port) BTreeShmemInit(); SyncScanShmemInit(); AsyncShmemInit(); - BackendRandomShmemInit(); #ifdef EXEC_BACKEND diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index e6706f7fb80..2426cbcf8e9 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -22,7 +22,7 @@ * The Windows implementation uses Windows events that are inherited by all * postmaster child processes. There's no need for the self-pipe trick there. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -48,6 +48,7 @@ #include "port/atomics.h" #include "portability/instr_time.h" #include "postmaster/postmaster.h" +#include "storage/ipc.h" #include "storage/latch.h" #include "storage/pmsignal.h" #include "storage/shmem.h" @@ -92,6 +93,13 @@ struct WaitEventSet Latch *latch; int latch_pos; + /* + * WL_EXIT_ON_PM_DEATH is converted to WL_POSTMASTER_DEATH, but this flag + * is set so that we'll exit immediately if postmaster death is detected, + * instead of returning. + */ + bool exit_on_postmaster_death; + #if defined(WAIT_USE_EPOLL) int epoll_fd; /* epoll_wait returns events in a user provided arrays, allocate once */ @@ -135,7 +143,7 @@ static void WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event); #endif static inline int WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, - WaitEvent *occurred_events, int nevents); + WaitEvent *occurred_events, int nevents); /* * Initialize the process-local latch infrastructure. @@ -217,7 +225,7 @@ InitializeLatchSupport(void) * Initialize a process-local latch. */ void -InitLatch(volatile Latch *latch) +InitLatch(Latch *latch) { latch->is_set = false; latch->owner_pid = MyProcPid; @@ -249,7 +257,7 @@ InitLatch(volatile Latch *latch) * process references to postmaster-private latches or WaitEventSets. */ void -InitSharedLatch(volatile Latch *latch) +InitSharedLatch(Latch *latch) { #ifdef WIN32 SECURITY_ATTRIBUTES sa; @@ -285,7 +293,7 @@ InitSharedLatch(volatile Latch *latch) * as shared latches use SIGUSR1 for inter-process communication. */ void -OwnLatch(volatile Latch *latch) +OwnLatch(Latch *latch) { /* Sanity checks */ Assert(latch->is_shared); @@ -305,7 +313,7 @@ OwnLatch(volatile Latch *latch) * Disown a shared latch currently owned by the current process. */ void -DisownLatch(volatile Latch *latch) +DisownLatch(Latch *latch) { Assert(latch->is_shared); Assert(latch->owner_pid == MyProcPid); @@ -333,7 +341,7 @@ DisownLatch(volatile Latch *latch) * we return all of them in one call, but we will return at least one. */ int -WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, +WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info) { return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout, @@ -348,12 +356,17 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, * to be reported as readable/writable/connected, so that the caller can deal * with the condition. * + * wakeEvents must include either WL_EXIT_ON_PM_DEATH for automatic exit + * if the postmaster dies or WL_POSTMASTER_DEATH for a flag set in the + * return value if the postmaster dies. The latter is useful for rare cases + * where some behavior other than immediate exit is needed. + * * NB: These days this is just a wrapper around the WaitEventSet API. When * using a latch very frequently, consider creating a longer living * WaitEventSet instead; that's more efficient. */ int -WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, +WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info) { int ret = 0; @@ -368,12 +381,21 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, if (wakeEvents & WL_LATCH_SET) AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET, - (Latch *) latch, NULL); + latch, NULL); + + /* Postmaster-managed callers must handle postmaster death somehow. */ + Assert(!IsUnderPostmaster || + (wakeEvents & WL_EXIT_ON_PM_DEATH) || + (wakeEvents & WL_POSTMASTER_DEATH)); - if (wakeEvents & WL_POSTMASTER_DEATH && IsUnderPostmaster) + if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster) AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET, NULL, NULL); + if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster) + AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET, + NULL, NULL); + if (wakeEvents & WL_SOCKET_MASK) { int ev; @@ -411,7 +433,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, * throwing an error is not a good idea. */ void -SetLatch(volatile Latch *latch) +SetLatch(Latch *latch) { #ifndef WIN32 pid_t owner_pid; @@ -494,7 +516,7 @@ SetLatch(volatile Latch *latch) * the latch is set again before the WaitLatch call. */ void -ResetLatch(volatile Latch *latch) +ResetLatch(Latch *latch) { /* Only the owner should reset the latch */ Assert(latch->owner_pid == MyProcPid); @@ -562,6 +584,7 @@ CreateWaitEventSet(MemoryContext context, int nevents) set->latch = NULL; set->nevents_space = nevents; + set->exit_on_postmaster_death = false; #if defined(WAIT_USE_EPOLL) #ifdef EPOLL_CLOEXEC @@ -646,6 +669,7 @@ FreeWaitEventSet(WaitEventSet *set) * - WL_SOCKET_CONNECTED: Wait for socket connection to be established, * can be combined with other WL_SOCKET_* events (on non-Windows * platforms, this is the same as WL_SOCKET_WRITEABLE) + * - WL_EXIT_ON_PM_DEATH: Exit immediately if the postmaster dies * * Returns the offset in WaitEventSet->events (starting from 0), which can be * used to modify previously added wait events using ModifyWaitEvent(). @@ -671,6 +695,12 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch, /* not enough space */ Assert(set->nevents < set->nevents_space); + if (events == WL_EXIT_ON_PM_DEATH) + { + events = WL_POSTMASTER_DEATH; + set->exit_on_postmaster_death = true; + } + if (latch) { if (latch->owner_pid != MyProcPid) @@ -826,7 +856,9 @@ WaitEventAdjustEpoll(WaitEventSet *set, WaitEvent *event, int action) if (rc < 0) ereport(ERROR, (errcode_for_socket_access(), - errmsg("epoll_ctl() failed: %m"))); + /* translator: %s is a syscall name, such as "poll()" */ + errmsg("%s failed: %m", + "epoll_ctl()"))); } #endif @@ -1030,7 +1062,7 @@ WaitEventSetWait(WaitEventSet *set, long timeout, /* * Wait using linux's epoll_wait(2). * - * This is the preferrable wait method, as several readiness notifications are + * This is the preferable wait method, as several readiness notifications are * delivered, without having to iterate through all of set->events. The return * epoll_event struct contain a pointer to our events, making association * easy. @@ -1057,7 +1089,9 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, waiting = false; ereport(ERROR, (errcode_for_socket_access(), - errmsg("epoll_wait() failed: %m"))); + /* translator: %s is a syscall name, such as "poll()" */ + errmsg("%s failed: %m", + "epoll_wait()"))); } return 0; } @@ -1112,8 +1146,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, * WL_POSTMASTER_DEATH event would be painful. Re-checking doesn't * cost much. */ - if (!PostmasterIsAlive()) + if (!PostmasterIsAliveInternal()) { + if (set->exit_on_postmaster_death) + proc_exit(1); occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_POSTMASTER_DEATH; occurred_events++; @@ -1179,7 +1215,9 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, waiting = false; ereport(ERROR, (errcode_for_socket_access(), - errmsg("poll() failed: %m"))); + /* translator: %s is a syscall name, such as "poll()" */ + errmsg("%s failed: %m", + "poll()"))); } return 0; } @@ -1230,8 +1268,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, * WL_POSTMASTER_DEATH event would be painful. Re-checking doesn't * cost much. */ - if (!PostmasterIsAlive()) + if (!PostmasterIsAliveInternal()) { + if (set->exit_on_postmaster_death) + proc_exit(1); occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_POSTMASTER_DEATH; occurred_events++; @@ -1390,8 +1430,10 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout, * even though there is no known reason to think that the event could * be falsely set on Windows. */ - if (!PostmasterIsAlive()) + if (!PostmasterIsAliveInternal()) { + if (set->exit_on_postmaster_death) + proc_exit(1); occurred_events->fd = PGINVALID_SOCKET; occurred_events->events = WL_POSTMASTER_DEATH; occurred_events++; diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c index be61858fc67..f098b6b9e65 100644 --- a/src/backend/storage/ipc/pmsignal.c +++ b/src/backend/storage/ipc/pmsignal.c @@ -4,7 +4,7 @@ * routines for signaling the postmaster from its child processes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -17,6 +17,10 @@ #include #include +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + #include "miscadmin.h" #include "postmaster/postmaster.h" #include "replication/walsender.h" @@ -69,8 +73,37 @@ struct PMSignalData sig_atomic_t PMChildFlags[FLEXIBLE_ARRAY_MEMBER]; }; -NON_EXEC_STATIC volatile PMSignalData *PMSignalState = NULL; +volatile PMSignalData *PMSignalState = NULL; +/* + * Signal handler to be notified if postmaster dies. + */ +#ifdef USE_POSTMASTER_DEATH_SIGNAL +volatile sig_atomic_t postmaster_possibly_dead = false; + +static void +postmaster_death_handler(int signo) +{ + postmaster_possibly_dead = true; +} + +/* + * The available signals depend on the OS. SIGUSR1 and SIGUSR2 are already + * used for other things, so choose another one. + * + * Currently, we assume that we can always find a signal to use. That + * seems like a reasonable assumption for all platforms that are modern + * enough to have a parent-death signaling mechanism. + */ +#if defined(SIGINFO) +#define POSTMASTER_DEATH_SIGNAL SIGINFO +#elif defined(SIGPWR) +#define POSTMASTER_DEATH_SIGNAL SIGPWR +#else +#error "cannot find a signal to use for postmaster death" +#endif + +#endif /* USE_POSTMASTER_DEATH_SIGNAL */ /* * PMSignalShmemSize @@ -101,7 +134,7 @@ PMSignalShmemInit(void) if (!found) { - MemSet(PMSignalState, 0, PMSignalShmemSize()); + MemSet(unvolatize(PMSignalData *, PMSignalState), 0, PMSignalShmemSize()); PMSignalState->num_child_flags = MaxLivePostmasterChildren(); } } @@ -266,28 +299,97 @@ MarkPostmasterChildInactive(void) /* - * PostmasterIsAlive - check whether postmaster process is still alive + * PostmasterIsAliveInternal - check whether postmaster process is still alive + * + * This is the slow path of PostmasterIsAlive(), where the caller has already + * checked 'postmaster_possibly_dead'. (On platforms that don't support + * a signal for parent death, PostmasterIsAlive() is just an alias for this.) */ bool -PostmasterIsAlive(void) +PostmasterIsAliveInternal(void) { -#ifndef WIN32 - char c; - ssize_t rc; +#ifdef USE_POSTMASTER_DEATH_SIGNAL + /* + * Reset the flag before checking, so that we don't miss a signal if + * postmaster dies right after the check. If postmaster was indeed dead, + * we'll re-arm it before returning to caller. + */ + postmaster_possibly_dead = false; +#endif - rc = read(postmaster_alive_fds[POSTMASTER_FD_WATCH], &c, 1); - if (rc < 0) +#ifndef WIN32 { - if (errno == EAGAIN || errno == EWOULDBLOCK) + char c; + ssize_t rc; + + rc = read(postmaster_alive_fds[POSTMASTER_FD_WATCH], &c, 1); + + /* + * In the usual case, the postmaster is still alive, and there is no + * data in the pipe. + */ + if (rc < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) return true; else - elog(FATAL, "read on postmaster death monitoring pipe failed: %m"); + { + /* + * Postmaster is dead, or something went wrong with the read() + * call. + */ + +#ifdef USE_POSTMASTER_DEATH_SIGNAL + postmaster_possibly_dead = true; +#endif + + if (rc < 0) + elog(FATAL, "read on postmaster death monitoring pipe failed: %m"); + else if (rc > 0) + elog(FATAL, "unexpected data in postmaster death monitoring pipe"); + + return false; + } } - else if (rc > 0) - elog(FATAL, "unexpected data in postmaster death monitoring pipe"); - return false; #else /* WIN32 */ - return (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT); + if (WaitForSingleObject(PostmasterHandle, 0) == WAIT_TIMEOUT) + return true; + else + { +#ifdef USE_POSTMASTER_DEATH_SIGNAL + postmaster_possibly_dead = true; +#endif + return false; + } #endif /* WIN32 */ } + +/* + * PostmasterDeathSignalInit - request signal on postmaster death if possible + */ +void +PostmasterDeathSignalInit(void) +{ +#ifdef USE_POSTMASTER_DEATH_SIGNAL + int signum = POSTMASTER_DEATH_SIGNAL; + + /* Register our signal handler. */ + pqsignal(signum, postmaster_death_handler); + + /* Request a signal on parent exit. */ +#if defined(PR_SET_PDEATHSIG) + if (prctl(PR_SET_PDEATHSIG, signum) < 0) + elog(ERROR, "could not request parent death signal: %m"); +#elif defined(PROC_PDEATHSIG_CTL) + if (procctl(P_PID, 0, PROC_PDEATHSIG_CTL, &signum) < 0) + elog(ERROR, "could not request parent death signal: %m"); +#else +#error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal" +#endif + + /* + * Just in case the parent was gone already and we missed it, we'd better + * check the slow way on the first call. + */ + postmaster_possibly_dead = true; +#endif /* USE_POSTMASTER_DEATH_SIGNAL */ +} diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index afe1c03aa3c..8abcfdf841f 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -32,7 +32,7 @@ * happen, it would tie up KnownAssignedXids indefinitely, so we protect * ourselves by pruning the array when a valid list of running XIDs arrives. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -61,6 +61,7 @@ #include "utils/rel.h" #include "utils/snapmgr.h" +#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var)))) /* Our shared memory area */ typedef struct ProcArrayStruct @@ -154,22 +155,22 @@ static void DisplayXidCache(void); /* Primitives for KnownAssignedXids array handling for standby */ static void KnownAssignedXidsCompress(bool force); static void KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, - bool exclusive_lock); + bool exclusive_lock); static bool KnownAssignedXidsSearch(TransactionId xid, bool remove); static bool KnownAssignedXidExists(TransactionId xid); static void KnownAssignedXidsRemove(TransactionId xid); static void KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids, - TransactionId *subxids); + TransactionId *subxids); static void KnownAssignedXidsRemovePreceding(TransactionId xid); static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax); -static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, - TransactionId *xmin, - TransactionId xmax); +static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, + TransactionId *xmin, + TransactionId xmax); static TransactionId KnownAssignedXidsGetOldestXmin(void); static void KnownAssignedXidsDisplay(int trace_level); static void KnownAssignedXidsReset(void); static inline void ProcArrayEndTransactionInternal(PGPROC *proc, - PGXACT *pgxact, TransactionId latestXid); + PGXACT *pgxact, TransactionId latestXid); static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid); /* @@ -264,7 +265,6 @@ CreateSharedProcArray(void) &found); } - /* Register and initialize fields of ProcLWLockTranche */ LWLockRegisterTranche(LWTRANCHE_PROC, "proc"); } @@ -483,7 +483,7 @@ ProcArrayEndTransactionInternal(PGPROC *proc, PGXACT *pgxact, static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) { - volatile PROC_HDR *procglobal = ProcGlobal; + PROC_HDR *procglobal = ProcGlobal; uint32 nextidx; uint32 wakeidx; @@ -542,14 +542,8 @@ ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid) * group XID clearing, saving a pointer to the head of the list. Trying * to pop elements one at a time could lead to an ABA problem. */ - while (true) - { - nextidx = pg_atomic_read_u32(&procglobal->procArrayGroupFirst); - if (pg_atomic_compare_exchange_u32(&procglobal->procArrayGroupFirst, - &nextidx, - INVALID_PGPROCNO)) - break; - } + nextidx = pg_atomic_exchange_u32(&procglobal->procArrayGroupFirst, + INVALID_PGPROCNO); /* Remember head of list so we can perform wakeups after dropping lock. */ wakeidx = nextidx; @@ -669,7 +663,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) { TransactionId *xids; int nxids; - TransactionId nextXid; int i; Assert(standbyState >= STANDBY_INITIALIZED); @@ -684,11 +677,8 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) /* * Remove stale locks, if any. - * - * Locks are always assigned to the toplevel xid so we don't need to care - * about subxcnt/subxids (and by extension not about ->suboverflowed). */ - StandbyReleaseOldLocks(running->xcnt, running->xids); + StandbyReleaseOldLocks(running->oldestRunningXid); /* * If our snapshot is already valid, nothing else to do... @@ -744,8 +734,6 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) Assert(standbyState == STANDBY_INITIALIZED); /* - * OK, we need to initialise from the RunningTransactionsData record. - * * NB: this can be reached at least twice, so make sure new code can deal * with that. */ @@ -760,11 +748,11 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) * sort them first. * * Some of the new xids are top-level xids and some are subtransactions. - * We don't call SubtransSetParent because it doesn't matter yet. If we + * We don't call SubTransSetParent because it doesn't matter yet. If we * aren't overflowed then all xids will fit in snapshot and so we don't * need subtrans. If we later overflow, an xid assignment record will add - * xids to subtrans. If RunningXacts is overflowed then we don't have - * enough information to correctly update subtrans anyway. + * xids to subtrans. If RunningTransactionsData is overflowed then we + * don't have enough information to correctly update subtrans anyway. */ /* @@ -808,10 +796,21 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) qsort(xids, nxids, sizeof(TransactionId), xidComparator); /* - * Add the sorted snapshot into KnownAssignedXids + * Add the sorted snapshot into KnownAssignedXids. The running-xacts + * snapshot may include duplicated xids because of prepared + * transactions, so ignore them. */ for (i = 0; i < nxids; i++) + { + if (i > 0 && TransactionIdEquals(xids[i - 1], xids[i])) + { + elog(DEBUG1, + "found duplicated transaction %u for KnownAssignedXids insertion", + xids[i]); + continue; + } KnownAssignedXidsAdd(xids[i], xids[i], true); + } KnownAssignedXidsDisplay(trace_recovery(DEBUG3)); } @@ -878,23 +877,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) LWLockRelease(ProcArrayLock); - /* - * ShmemVariableCache->nextXid must be beyond any observed xid. - * - * We don't expect anyone else to modify nextXid, hence we don't need to - * hold a lock while examining it. We still acquire the lock to modify - * it, though. - */ - nextXid = latestObservedXid; - TransactionIdAdvance(nextXid); - if (TransactionIdFollows(nextXid, ShmemVariableCache->nextXid)) - { - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = nextXid; - LWLockRelease(XidGenLock); - } + /* ShmemVariableCache->nextFullXid must be beyond any observed xid. */ + AdvanceNextFullTransactionIdPastXid(latestObservedXid); - Assert(TransactionIdIsValid(ShmemVariableCache->nextXid)); + Assert(FullTransactionIdIsValid(ShmemVariableCache->nextFullXid)); KnownAssignedXidsDisplay(trace_recovery(DEBUG3)); if (standbyState == STANDBY_SNAPSHOT_READY) @@ -1075,16 +1061,17 @@ TransactionIdIsInProgress(TransactionId xid) for (i = 0; i < arrayP->numProcs; i++) { int pgprocno = arrayP->pgprocnos[i]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId pxid; + int pxids; /* Ignore my own proc --- dealt with it above */ if (proc == MyProc) continue; /* Fetch xid just once - see GetNewTransactionId */ - pxid = pgxact->xid; + pxid = UINT32_ACCESS_ONCE(pgxact->xid); if (!TransactionIdIsValid(pxid)) continue; @@ -1109,10 +1096,12 @@ TransactionIdIsInProgress(TransactionId xid) /* * Step 2: check the cached child-Xids arrays */ - for (j = pgxact->nxids - 1; j >= 0; j--) + pxids = pgxact->nxids; + pg_read_barrier(); /* pairs with barrier in GetNewTransactionId() */ + for (j = pxids - 1; j >= 0; j--) { /* Fetch xid just once - see GetNewTransactionId */ - TransactionId cxid = proc->subxids.xids[j]; + TransactionId cxid = UINT32_ACCESS_ONCE(proc->subxids.xids[j]); if (TransactionIdEquals(cxid, xid)) { @@ -1231,12 +1220,12 @@ TransactionIdIsActive(TransactionId xid) for (i = 0; i < arrayP->numProcs; i++) { int pgprocno = arrayP->pgprocnos[i]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId pxid; /* Fetch xid just once - see GetNewTransactionId */ - pxid = pgxact->xid; + pxid = UINT32_ACCESS_ONCE(pgxact->xid); if (!TransactionIdIsValid(pxid)) continue; @@ -1319,8 +1308,8 @@ GetOldestXmin(Relation rel, int flags) int index; bool allDbs; - volatile TransactionId replication_slot_xmin = InvalidTransactionId; - volatile TransactionId replication_slot_catalog_xmin = InvalidTransactionId; + TransactionId replication_slot_xmin = InvalidTransactionId; + TransactionId replication_slot_catalog_xmin = InvalidTransactionId; /* * If we're not computing a relation specific limit, or if a shared @@ -1347,8 +1336,8 @@ GetOldestXmin(Relation rel, int flags) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; if (pgxact->vacuumFlags & (flags & PROCARRAY_PROC_FLAGS_MASK)) continue; @@ -1358,7 +1347,7 @@ GetOldestXmin(Relation rel, int flags) proc->databaseId == 0) /* always include WalSender */ { /* Fetch xid just once - see GetNewTransactionId */ - TransactionId xid = pgxact->xid; + TransactionId xid = UINT32_ACCESS_ONCE(pgxact->xid); /* First consider the transaction's own Xid, if any */ if (TransactionIdIsNormal(xid) && @@ -1372,14 +1361,18 @@ GetOldestXmin(Relation rel, int flags) * have an Xmin but not (yet) an Xid; conversely, if it has an * Xid, that could determine some not-yet-set Xmin. */ - xid = pgxact->xmin; /* Fetch just once */ + xid = UINT32_ACCESS_ONCE(pgxact->xmin); if (TransactionIdIsNormal(xid) && TransactionIdPrecedes(xid, result)) result = xid; } } - /* fetch into volatile var while ProcArrayLock is held */ + /* + * Fetch into local variable while ProcArrayLock is held - the + * LWLockRelease below is a barrier, ensuring this happens inside the + * lock. + */ replication_slot_xmin = procArray->replication_slot_xmin; replication_slot_catalog_xmin = procArray->replication_slot_catalog_xmin; @@ -1432,10 +1425,11 @@ GetOldestXmin(Relation rel, int flags) result = replication_slot_xmin; /* - * After locks have been released and defer_cleanup_age has been applied, - * check whether we need to back up further to make logical decoding - * possible. We need to do so if we're computing the global limit (rel = - * NULL) or if the passed relation is a catalog relation of some kind. + * After locks have been released and vacuum_defer_cleanup_age has been + * applied, check whether we need to back up further to make logical + * decoding possible. We need to do so if we're computing the global limit + * (rel = NULL) or if the passed relation is a catalog relation of some + * kind. */ if (!(flags & PROCARRAY_SLOTS_XMIN) && (rel == NULL || @@ -1488,7 +1482,7 @@ GetMaxSnapshotSubxidCount(void) * information may not be available. If we find any overflowed subxid arrays, * we have to mark the snapshot's subxid data as overflowed, and extra work * *may* need to be done to determine what's running (see XidInMVCCSnapshot() - * in tqual.c). + * in heapam_visibility.c). * * We also update the following backend-global variables: * TransactionXmin: the oldest xmin of any snapshot in use in the @@ -1516,8 +1510,8 @@ GetSnapshotData(Snapshot snapshot) int count = 0; int subcount = 0; bool suboverflowed = false; - volatile TransactionId replication_slot_xmin = InvalidTransactionId; - volatile TransactionId replication_slot_catalog_xmin = InvalidTransactionId; + TransactionId replication_slot_xmin = InvalidTransactionId; + TransactionId replication_slot_catalog_xmin = InvalidTransactionId; Assert(snapshot != NULL); @@ -1583,28 +1577,25 @@ GetSnapshotData(Snapshot snapshot) for (index = 0; index < numProcs; index++) { int pgprocno = pgprocnos[index]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId xid; /* - * Backend is doing logical decoding which manages xmin - * separately, check below. + * Skip over backends doing logical decoding which manages xmin + * separately (check below) and ones running LAZY VACUUM. */ - if (pgxact->vacuumFlags & PROC_IN_LOGICAL_DECODING) - continue; - - /* Ignore procs running LAZY VACUUM */ - if (pgxact->vacuumFlags & PROC_IN_VACUUM) + if (pgxact->vacuumFlags & + (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM)) continue; /* Update globalxmin to be the smallest valid xmin */ - xid = pgxact->xmin; /* fetch just once */ + xid = UINT32_ACCESS_ONCE(pgxact->xmin); if (TransactionIdIsNormal(xid) && NormalTransactionIdPrecedes(xid, globalxmin)) globalxmin = xid; /* Fetch xid just once - see GetNewTransactionId */ - xid = pgxact->xid; + xid = UINT32_ACCESS_ONCE(pgxact->xid); /* * If the transaction has no XID assigned, we can skip it; it @@ -1653,7 +1644,9 @@ GetSnapshotData(Snapshot snapshot) if (nxids > 0) { - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + + pg_read_barrier(); /* pairs with GetNewTransactionId */ memcpy(snapshot->subxip + subcount, (void *) proc->subxids.xids, @@ -1703,7 +1696,11 @@ GetSnapshotData(Snapshot snapshot) } - /* fetch into volatile var while ProcArrayLock is held */ + /* + * Fetch into local variable while ProcArrayLock is held - the + * LWLockRelease below is a barrier, ensuring this happens inside the + * lock. + */ replication_slot_xmin = procArray->replication_slot_xmin; replication_slot_catalog_xmin = procArray->replication_slot_catalog_xmin; @@ -1811,8 +1808,8 @@ ProcArrayInstallImportedXmin(TransactionId xmin, for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId xid; /* Ignore procs running LAZY VACUUM */ @@ -1837,7 +1834,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin, /* * Likewise, let's just make real sure its xmin does cover us. */ - xid = pgxact->xmin; /* fetch just once */ + xid = UINT32_ACCESS_ONCE(pgxact->xmin); if (!TransactionIdIsNormal(xid) || !TransactionIdPrecedesOrEquals(xid, xmin)) continue; @@ -1873,7 +1870,7 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) { bool result = false; TransactionId xid; - volatile PGXACT *pgxact; + PGXACT *pgxact; Assert(TransactionIdIsNormal(xmin)); Assert(proc != NULL); @@ -1889,7 +1886,7 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) * can't go backwards. Also, make sure it's running in the same database, * so that the per-database xmin cannot go backwards. */ - xid = pgxact->xmin; /* fetch just once */ + xid = UINT32_ACCESS_ONCE(pgxact->xmin); if (proc->databaseId == MyDatabaseId && TransactionIdIsNormal(xid) && TransactionIdPrecedesOrEquals(xid, xmin)) @@ -1907,7 +1904,8 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) * GetRunningTransactionData -- returns information about running transactions. * * Similar to GetSnapshotData but returns more information. We include - * all PGXACTs with an assigned TransactionId, even VACUUM processes. + * all PGXACTs with an assigned TransactionId, even VACUUM processes and + * prepared transactions. * * We acquire XidGenLock and ProcArrayLock, but the caller is responsible for * releasing them. Acquiring XidGenLock ensures that no new XIDs enter the proc @@ -1921,14 +1919,17 @@ ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc) * This is never executed during recovery so there is no need to look at * KnownAssignedXids. * + * Dummy PGXACTs from prepared transaction are included, meaning that this + * may return entries with duplicated TransactionId values coming from + * transaction finishing to prepare. Nothing is done about duplicated + * entries here to not hold on ProcArrayLock more than necessary. + * * We don't worry about updating other counters, we want to keep this as * simple as possible and leave GetSnapshotData() as the primary code for * that bookkeeping. * * Note that if any transaction has overflowed its cached subtransactions - * then there is no real need include any subtransactions. That isn't a - * common enough case to worry about optimising the size of the WAL record, - * and we may wish to see that data for diagnostic purposes anyway. + * then there is no real need include any subtransactions. */ RunningTransactions GetRunningTransactionData(void) @@ -1984,7 +1985,7 @@ GetRunningTransactionData(void) latestCompletedXid = ShmemVariableCache->latestCompletedXid; - oldestRunningXid = ShmemVariableCache->nextXid; + oldestRunningXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); /* * Spin over procArray collecting all xids @@ -1992,11 +1993,11 @@ GetRunningTransactionData(void) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId xid; /* Fetch xid just once - see GetNewTransactionId */ - xid = pgxact->xid; + xid = UINT32_ACCESS_ONCE(pgxact->xid); /* * We don't need to store transactions that don't have a TransactionId @@ -2005,13 +2006,26 @@ GetRunningTransactionData(void) if (!TransactionIdIsValid(xid)) continue; - xids[count++] = xid; - + /* + * Be careful not to exclude any xids before calculating the values of + * oldestRunningXid and suboverflowed, since these are used to clean + * up transaction information held on standbys. + */ if (TransactionIdPrecedes(xid, oldestRunningXid)) oldestRunningXid = xid; if (pgxact->overflowed) suboverflowed = true; + + /* + * If we wished to exclude xids this would be the right place for it. + * Procs with the PROC_IN_VACUUM flag set don't usually assign xids, + * but they do during truncation at the end when they get the lock and + * truncate, so it is not much of a problem to include them if they + * are seen and it is cleaner to include them. + */ + + xids[count++] = xid; } /* @@ -2023,8 +2037,8 @@ GetRunningTransactionData(void) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; int nxids; /* @@ -2034,6 +2048,9 @@ GetRunningTransactionData(void) nxids = pgxact->nxids; if (nxids > 0) { + /* barrier not really required, as XidGenLock is held, but ... */ + pg_read_barrier(); /* pairs with GetNewTransactionId */ + memcpy(&xids[count], (void *) proc->subxids.xids, nxids * sizeof(TransactionId)); count += nxids; @@ -2060,7 +2077,7 @@ GetRunningTransactionData(void) CurrentRunningXacts->xcnt = count - subcount; CurrentRunningXacts->subxcnt = subcount; CurrentRunningXacts->subxid_overflow = suboverflowed; - CurrentRunningXacts->nextXid = ShmemVariableCache->nextXid; + CurrentRunningXacts->nextXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); CurrentRunningXacts->oldestRunningXid = oldestRunningXid; CurrentRunningXacts->latestCompletedXid = latestCompletedXid; @@ -2105,7 +2122,7 @@ GetOldestActiveTransactionId(void) * have already completed), when we spin over it. */ LWLockAcquire(XidGenLock, LW_SHARED); - oldestRunningXid = ShmemVariableCache->nextXid; + oldestRunningXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); LWLockRelease(XidGenLock); /* @@ -2115,11 +2132,11 @@ GetOldestActiveTransactionId(void) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId xid; /* Fetch xid just once - see GetNewTransactionId */ - xid = pgxact->xid; + xid = UINT32_ACCESS_ONCE(pgxact->xid); if (!TransactionIdIsNormal(xid)) continue; @@ -2173,7 +2190,7 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly) * a safe, albeit pessimal, value. */ LWLockAcquire(XidGenLock, LW_SHARED); - oldestSafeXid = ShmemVariableCache->nextXid; + oldestSafeXid = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); /* * If there's already a slot pegging the xmin horizon, we can start with @@ -2213,11 +2230,11 @@ GetOldestSafeDecodingTransactionId(bool catalogOnly) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; TransactionId xid; /* Fetch xid just once - see GetNewTransactionId */ - xid = pgxact->xid; + xid = UINT32_ACCESS_ONCE(pgxact->xid); if (!TransactionIdIsNormal(xid)) continue; @@ -2267,8 +2284,8 @@ GetVirtualXIDsDelayingChkpt(int *nvxids) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; if (pgxact->delayChkpt) { @@ -2307,8 +2324,8 @@ HaveVirtualXIDsDelayingChkpt(VirtualTransactionId *vxids, int nvxids) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; VirtualTransactionId vxid; GET_VXID_FROM_PGPROC(vxid, *proc); @@ -2417,8 +2434,8 @@ BackendXidGetPid(TransactionId xid) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; if (pgxact->xid == xid) { @@ -2489,8 +2506,8 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; if (proc == MyProc) continue; @@ -2501,7 +2518,7 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, if (allDbs || proc->databaseId == MyDatabaseId) { /* Fetch xmin just once - might change on us */ - TransactionId pxmin = pgxact->xmin; + TransactionId pxmin = UINT32_ACCESS_ONCE(pgxact->xmin); if (excludeXmin0 && !TransactionIdIsValid(pxmin)) continue; @@ -2586,8 +2603,8 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; /* Exclude prepared transactions */ if (proc->pid == 0) @@ -2597,7 +2614,7 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) proc->databaseId == dbOid) { /* Fetch xmin just once - can't change on us, but good coding */ - TransactionId pxmin = pgxact->xmin; + TransactionId pxmin = UINT32_ACCESS_ONCE(pgxact->xmin); /* * We ignore an invalid pxmin because this means that backend has @@ -2645,7 +2662,7 @@ CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; VirtualTransactionId procvxid; GET_VXID_FROM_PGPROC(procvxid, *proc); @@ -2700,8 +2717,8 @@ MinimumActiveBackends(int min) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; /* * Since we're not holding a lock, need to be prepared to deal with @@ -2747,7 +2764,7 @@ CountDBBackends(Oid databaseid) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; if (proc->pid == 0) continue; /* do not count prepared xacts */ @@ -2777,7 +2794,7 @@ CountDBConnections(Oid databaseid) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; if (proc->pid == 0) continue; /* do not count prepared xacts */ @@ -2809,7 +2826,7 @@ CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; if (databaseid == InvalidOid || proc->databaseId == databaseid) { @@ -2848,7 +2865,7 @@ CountUserBackends(Oid roleid) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; if (proc->pid == 0) continue; /* do not count prepared xacts */ @@ -2911,8 +2928,8 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared) for (index = 0; index < arrayP->numProcs; index++) { int pgprocno = arrayP->pgprocnos[index]; - volatile PGPROC *proc = &allProcs[pgprocno]; - volatile PGXACT *pgxact = &allPgXact[pgprocno]; + PGPROC *proc = &allProcs[pgprocno]; + PGXACT *pgxact = &allPgXact[pgprocno]; if (proc->databaseId != databaseId) continue; @@ -3001,6 +3018,7 @@ ProcArrayGetReplicationSlotXmin(TransactionId *xmin, #define XidCacheRemove(i) \ do { \ MyProc->subxids.xids[i] = MyProc->subxids.xids[MyPgXact->nxids - 1]; \ + pg_write_barrier(); \ MyPgXact->nxids--; \ } while (0) @@ -3028,6 +3046,11 @@ XidCacheRemoveRunningXids(TransactionId xid, * possible this could be relaxed since we know this routine is only used * to abort subtransactions, but pending closer analysis we'd best be * conservative. + * + * Note that we do not have to be careful about memory ordering of our own + * reads wrt. GetNewTransactionId() here - only this process can modify + * relevant fields of MyProc/MyPgXact. But we do have to be careful about + * our own writes being well ordered. */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); @@ -3104,7 +3127,7 @@ DisplayXidCache(void) /* ---------------------------------------------- - * KnownAssignedTransactions sub-module + * KnownAssignedTransactionIds sub-module * ---------------------------------------------- */ @@ -3143,7 +3166,7 @@ DisplayXidCache(void) * * When we throw away subXIDs from KnownAssignedXids, we need to keep track of * that, similarly to tracking overflow of a PGPROC's subxids array. We do - * that by remembering the lastOverflowedXID, ie the last thrown-away subXID. + * that by remembering the lastOverflowedXid, ie the last thrown-away subXID. * As long as that is within the range of interesting XIDs, we have to assume * that subXIDs are missing from snapshots. (Note that subXID overflow occurs * on primary when 65th subXID arrives, whereas on standby it occurs when 64th @@ -3227,12 +3250,10 @@ RecordKnownAssignedTransactionIds(TransactionId xid) */ latestObservedXid = xid; - /* ShmemVariableCache->nextXid must be beyond any observed xid */ + /* ShmemVariableCache->nextFullXid must be beyond any observed xid */ + AdvanceNextFullTransactionIdPastXid(latestObservedXid); next_expected_xid = latestObservedXid; TransactionIdAdvance(next_expected_xid); - LWLockAcquire(XidGenLock, LW_EXCLUSIVE); - ShmemVariableCache->nextXid = next_expected_xid; - LWLockRelease(XidGenLock); } } @@ -3385,8 +3406,7 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid) static void KnownAssignedXidsCompress(bool force) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; int head, tail; int compress_index; @@ -3449,8 +3469,7 @@ static void KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, bool exclusive_lock) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; TransactionId next_xid; int head, tail; @@ -3567,8 +3586,7 @@ KnownAssignedXidsAdd(TransactionId from_xid, TransactionId to_xid, static bool KnownAssignedXidsSearch(TransactionId xid, bool remove) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; int first, last; int head; @@ -3722,8 +3740,7 @@ KnownAssignedXidsRemoveTree(TransactionId xid, int nsubxids, static void KnownAssignedXidsRemovePreceding(TransactionId removeXid) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; int count = 0; int head, tail, @@ -3908,8 +3925,7 @@ KnownAssignedXidsGetOldestXmin(void) static void KnownAssignedXidsDisplay(int trace_level) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; StringInfoData buf; int head, tail, @@ -3947,8 +3963,7 @@ KnownAssignedXidsDisplay(int trace_level) static void KnownAssignedXidsReset(void) { - /* use volatile pointer to prevent code rearrangement */ - volatile ProcArrayStruct *pArray = procArray; + ProcArrayStruct *pArray = procArray; LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index b0dd7d1b377..7605b2c3674 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -4,7 +4,7 @@ * Routines for interprocess signalling * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c index c80cb6e2f70..551515960d1 100644 --- a/src/backend/storage/ipc/shm_mq.c +++ b/src/backend/storage/ipc/shm_mq.c @@ -8,10 +8,10 @@ * and only the receiver may receive. This is intended to allow a user * backend to communicate with worker backends that it has registered. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/include/storage/shm_mq.h + * src/backend/storage/ipc/shm_mq.c * *------------------------------------------------------------------------- */ @@ -144,14 +144,14 @@ struct shm_mq_handle static void shm_mq_detach_internal(shm_mq *mq); static shm_mq_result shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, - const void *data, bool nowait, Size *bytes_written); + const void *data, bool nowait, Size *bytes_written); static shm_mq_result shm_mq_receive_bytes(shm_mq_handle *mqh, - Size bytes_needed, bool nowait, Size *nbytesp, - void **datap); + Size bytes_needed, bool nowait, Size *nbytesp, + void **datap); static bool shm_mq_counterparty_gone(shm_mq *mq, - BackgroundWorkerHandle *handle); + BackgroundWorkerHandle *handle); static bool shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, - BackgroundWorkerHandle *handle); + BackgroundWorkerHandle *handle); static void shm_mq_inc_bytes_read(shm_mq *mq, Size n); static void shm_mq_inc_bytes_written(shm_mq *mq, Size n); static void shm_mq_detach_callback(dsm_segment *seg, Datum arg); @@ -949,7 +949,8 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const void *data, * at top of loop, because setting an already-set latch is much * cheaper than setting one that has been reset. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_SEND); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_MQ_SEND); /* Reset the latch so we don't spin. */ ResetLatch(MyLatch); @@ -1093,7 +1094,8 @@ shm_mq_receive_bytes(shm_mq_handle *mqh, Size bytes_needed, bool nowait, * loop, because setting an already-set latch is much cheaper than * setting one that has been reset. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_RECEIVE); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_MQ_RECEIVE); /* Reset the latch so we don't spin. */ ResetLatch(MyLatch); @@ -1181,7 +1183,8 @@ shm_mq_wait_internal(shm_mq *mq, PGPROC **ptr, BackgroundWorkerHandle *handle) } /* Wait to be signalled. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, WAIT_EVENT_MQ_INTERNAL); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + WAIT_EVENT_MQ_INTERNAL); /* Reset the latch so we don't spin. */ ResetLatch(MyLatch); @@ -1203,9 +1206,10 @@ shm_mq_inc_bytes_read(shm_mq *mq, Size n) /* * Separate prior reads of mq_ring from the increment of mq_bytes_read - * which follows. This pairs with the full barrier in shm_mq_send_bytes(). - * We only need a read barrier here because the increment of mq_bytes_read - * is actually a read followed by a dependent write. + * which follows. This pairs with the full barrier in + * shm_mq_send_bytes(). We only need a read barrier here because the + * increment of mq_bytes_read is actually a read followed by a dependent + * write. */ pg_read_barrier(); @@ -1234,7 +1238,7 @@ shm_mq_inc_bytes_written(shm_mq *mq, Size n) /* * Separate prior reads of mq_ring from the write of mq_bytes_written * which we're about to do. Pairs with the read barrier found in - * shm_mq_get_receive_bytes. + * shm_mq_receive_bytes. */ pg_write_barrier(); @@ -1247,7 +1251,7 @@ shm_mq_inc_bytes_written(shm_mq *mq, Size n) pg_atomic_read_u64(&mq->mq_bytes_written) + n); } -/* Shim for on_dsm_callback. */ +/* Shim for on_dsm_detach callback. */ static void shm_mq_detach_callback(dsm_segment *seg, Datum arg) { diff --git a/src/backend/storage/ipc/shm_toc.c b/src/backend/storage/ipc/shm_toc.c index ee5ec6e3801..2870bb7a5a9 100644 --- a/src/backend/storage/ipc/shm_toc.c +++ b/src/backend/storage/ipc/shm_toc.c @@ -3,7 +3,7 @@ * shm_toc.c * shared memory segment table of contents * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/storage/ipc/shm_toc.c diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c index 7893c01983b..5b51867e10a 100644 --- a/src/backend/storage/ipc/shmem.c +++ b/src/backend/storage/ipc/shmem.c @@ -3,7 +3,7 @@ * shmem.c * create shared memory and initialize shared memory data structures. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -101,6 +101,7 @@ InitShmemAccess(void *seghdr) ShmemSegHdr = shmhdr; ShmemBase = (void *) shmhdr; ShmemEnd = (char *) ShmemBase + shmhdr->totalsize; + } /* @@ -383,7 +384,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr) /* Must be trying to create/attach to ShmemIndex itself */ Assert(strcmp(name, "ShmemIndex") == 0); - if (IsUnderPostmaster) + if (IsUnderPostmaster || IsOnlineUpgrade) { /* Must be initializing a (non-standalone) backend */ Assert(shmemseghdr->index != NULL); diff --git a/src/backend/storage/ipc/shmqueue.c b/src/backend/storage/ipc/shmqueue.c index 598d9ebcfb5..09d25735da5 100644 --- a/src/backend/storage/ipc/shmqueue.c +++ b/src/backend/storage/ipc/shmqueue.c @@ -3,7 +3,7 @@ * shmqueue.c * shared memory linked lists * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c new file mode 100644 index 00000000000..ade8d713aae --- /dev/null +++ b/src/backend/storage/ipc/signalfuncs.c @@ -0,0 +1,217 @@ +/*------------------------------------------------------------------------- + * + * signalfuncs.c + * Functions for signalling backends + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/storage/ipc/signalfuncs.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "catalog/pg_authid.h" +#include "miscadmin.h" +#include "postmaster/syslogger.h" +#include "storage/pmsignal.h" +#include "storage/proc.h" +#include "storage/procarray.h" +#include "utils/acl.h" +#include "utils/builtins.h" + + +/* + * Send a signal to another backend. + * + * The signal is delivered if the user is either a superuser or the same + * role as the backend being signaled. For "dangerous" signals, an explicit + * check for superuser needs to be done prior to calling this function. + * + * Returns 0 on success, 1 on general failure, 2 on normal permission error + * and 3 if the caller needs to be a superuser. + * + * In the event of a general failure (return code 1), a warning message will + * be emitted. For permission errors, doing that is the responsibility of + * the caller. + */ +#define SIGNAL_BACKEND_SUCCESS 0 +#define SIGNAL_BACKEND_ERROR 1 +#define SIGNAL_BACKEND_NOPERMISSION 2 +#define SIGNAL_BACKEND_NOSUPERUSER 3 +static int +pg_signal_backend(int pid, int sig) +{ + PGPROC *proc = BackendPidGetProc(pid); + + /* + * BackendPidGetProc returns NULL if the pid isn't valid; but by the time + * we reach kill(), a process for which we get a valid proc here might + * have terminated on its own. There's no way to acquire a lock on an + * arbitrary process to prevent that. But since so far all the callers of + * this mechanism involve some request for ending the process anyway, that + * it might end on its own first is not a problem. + */ + if (proc == NULL) + { + /* + * This is just a warning so a loop-through-resultset will not abort + * if one backend terminated on its own during the run. + */ + ereport(WARNING, + (errmsg("PID %d is not a PostgreSQL server process", pid))); + return SIGNAL_BACKEND_ERROR; + } + + /* Only allow superusers to signal superuser-owned backends. */ + if (superuser_arg(proc->roleId) && !superuser()) + return SIGNAL_BACKEND_NOSUPERUSER; + + /* Users can signal backends they have role membership in. */ + if (!has_privs_of_role(GetUserId(), proc->roleId) && + !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) + return SIGNAL_BACKEND_NOPERMISSION; + + /* + * Can the process we just validated above end, followed by the pid being + * recycled for a new process, before reaching here? Then we'd be trying + * to kill the wrong thing. Seems near impossible when sequential pid + * assignment and wraparound is used. Perhaps it could happen on a system + * where pid re-use is randomized. That race condition possibility seems + * too unlikely to worry about. + */ + + /* If we have setsid(), signal the backend's whole process group */ +#ifdef HAVE_SETSID + if (kill(-pid, sig)) +#else + if (kill(pid, sig)) +#endif + { + /* Again, just a warning to allow loops */ + ereport(WARNING, + (errmsg("could not send signal to process %d: %m", pid))); + return SIGNAL_BACKEND_ERROR; + } + return SIGNAL_BACKEND_SUCCESS; +} + +/* + * Signal to cancel a backend process. This is allowed if you are a member of + * the role whose process is being canceled. + * + * Note that only superusers can signal superuser-owned processes. + */ +Datum +pg_cancel_backend(PG_FUNCTION_ARGS) +{ + int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT); + + if (r == SIGNAL_BACKEND_NOSUPERUSER) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be a superuser to cancel superuser query")))); + + if (r == SIGNAL_BACKEND_NOPERMISSION) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be a member of the role whose query is being canceled or member of pg_signal_backend")))); + + PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); +} + +/* + * Signal to terminate a backend process. This is allowed if you are a member + * of the role whose process is being terminated. + * + * Note that only superusers can signal superuser-owned processes. + */ +Datum +pg_terminate_backend(PG_FUNCTION_ARGS) +{ + int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM); + + if (r == SIGNAL_BACKEND_NOSUPERUSER) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be a superuser to terminate superuser process")))); + + if (r == SIGNAL_BACKEND_NOPERMISSION) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend")))); + + PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); +} + +/* + * Signal to reload the database configuration + * + * Permission checking for this function is managed through the normal + * GRANT system. + */ +Datum +pg_reload_conf(PG_FUNCTION_ARGS) +{ + if (kill(PostmasterPid, SIGHUP)) + { + ereport(WARNING, + (errmsg("failed to send signal to postmaster: %m"))); + PG_RETURN_BOOL(false); + } + + PG_RETURN_BOOL(true); +} + + +/* + * Rotate log file + * + * This function is kept to support adminpack 1.0. + */ +Datum +pg_rotate_logfile(PG_FUNCTION_ARGS) +{ + if (!superuser()) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be superuser to rotate log files with adminpack 1.0"), + /* translator: %s is a SQL function name */ + errhint("Consider using %s, which is part of core, instead.", + "pg_logfile_rotate()")))); + + if (!Logging_collector) + { + ereport(WARNING, + (errmsg("rotation not possible because log collection not active"))); + PG_RETURN_BOOL(false); + } + + SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE); + PG_RETURN_BOOL(true); +} + +/* + * Rotate log file + * + * Permission checking for this function is managed through the normal + * GRANT system. + */ +Datum +pg_rotate_logfile_v2(PG_FUNCTION_ARGS) +{ + if (!Logging_collector) + { + ereport(WARNING, + (errmsg("rotation not possible because log collection not active"))); + PG_RETURN_BOOL(false); + } + + SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE); + PG_RETURN_BOOL(true); +} diff --git a/src/backend/storage/ipc/sinval.c b/src/backend/storage/ipc/sinval.c index 563e2906e36..a457c876c2b 100644 --- a/src/backend/storage/ipc/sinval.c +++ b/src/backend/storage/ipc/sinval.c @@ -3,7 +3,7 @@ * sinval.c * POSTGRES shared cache invalidation communication code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -68,8 +68,7 @@ SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, int n) * sucked out of sinvaladt.c. */ void -ReceiveSharedInvalidMessages( - void (*invalFunction) (SharedInvalidationMessage *msg), +ReceiveSharedInvalidMessages(void (*invalFunction) (SharedInvalidationMessage *msg), void (*resetFunction) (void)) { #define MAXINVALMSGS 32 diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index 569f1058fa9..db080c84e1c 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -3,7 +3,7 @@ * sinvaladt.c * POSTGRES shared cache invalidation data manager. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 44ed20992ed..01ddffec400 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -7,7 +7,7 @@ * AccessExclusiveLocks and starting snapshots for Hot Standby mode. * Plus conflict recovery processing. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -29,6 +29,8 @@ #include "storage/procarray.h" #include "storage/sinvaladt.h" #include "storage/standby.h" +#include "utils/hsearch.h" +#include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/timeout.h" #include "utils/timestamp.h" @@ -38,14 +40,22 @@ int vacuum_defer_cleanup_age; int max_standby_archive_delay = 30 * 1000; int max_standby_streaming_delay = 30 * 1000; -static List *RecoveryLockList; +static HTAB *RecoveryLockLists; static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, - ProcSignalReason reason); + ProcSignalReason reason); static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason); static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts); static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks); +/* + * Keep track of all the locks owned by a given transaction. + */ +typedef struct RecoveryLockListsEntry +{ + TransactionId xid; + List *locks; +} RecoveryLockListsEntry; /* * InitRecoveryTransactionEnvironment @@ -63,6 +73,19 @@ void InitRecoveryTransactionEnvironment(void) { VirtualTransactionId vxid; + HASHCTL hash_ctl; + + /* + * Initialize the hash table for tracking the list of locks held by each + * transaction. + */ + memset(&hash_ctl, 0, sizeof(hash_ctl)); + hash_ctl.keysize = sizeof(TransactionId); + hash_ctl.entrysize = sizeof(RecoveryLockListsEntry); + RecoveryLockLists = hash_create("RecoveryLockLists", + 64, + &hash_ctl, + HASH_ELEM | HASH_BLOBS); /* * Initialize shared invalidation management for Startup process, being @@ -76,7 +99,7 @@ InitRecoveryTransactionEnvironment(void) * Lock a virtual transaction id for Startup process. * * We need to do GetNextLocalTransactionId() because - * SharedInvalBackendInit() leaves localTransactionid invalid and the lock + * SharedInvalBackendInit() leaves localTransactionId invalid and the lock * manager doesn't like that at all. * * Note that we don't need to run XactLockTableInsert() because nobody @@ -107,6 +130,10 @@ ShutdownRecoveryTransactionEnvironment(void) /* Release all locks the tracked transactions were holding */ StandbyReleaseAllLocks(); + /* Destroy the hash table of locks. */ + hash_destroy(RecoveryLockLists); + RecoveryLockLists = NULL; + /* Cleanup our VirtualTransaction */ VirtualXactLockTableCleanup(); } @@ -175,7 +202,7 @@ WaitExceedsMaxStandbyDelay(void) /* * Progressively increase the sleep times, but not to more than 1s, since - * pg_usleep isn't interruptable on some platforms. + * pg_usleep isn't interruptible on some platforms. */ standbyWait_us *= 2; if (standbyWait_us > 1000000) @@ -374,7 +401,7 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag) */ VirtualTransactionId *backends; - backends = GetLockConflicts(&locktag, AccessExclusiveLock); + backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL); ResolveRecoveryConflictWithVirtualXIDs(backends, PROCSIG_RECOVERY_CONFLICT_LOCK); } @@ -586,8 +613,8 @@ StandbyLockTimeoutHandler(void) * We only keep track of AccessExclusiveLocks, which are only ever held by * one transaction on one relation. * - * We keep a single dynamically expandible list of locks in local memory, - * RecoveryLockList, so we can keep track of the various entries made by + * We keep a hash table of lists of locks in local memory keyed by xid, + * RecoveryLockLists, so we can keep track of the various entries made by * the Startup process's virtual xid in the shared lock table. * * List elements use type xl_standby_lock, since the WAL record type exactly @@ -601,8 +628,10 @@ StandbyLockTimeoutHandler(void) void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid) { + RecoveryLockListsEntry *entry; xl_standby_lock *newlock; LOCKTAG locktag; + bool found; /* Already processed? */ if (!TransactionIdIsValid(xid) || @@ -616,58 +645,69 @@ StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid) /* dbOid is InvalidOid when we are locking a shared relation. */ Assert(OidIsValid(relOid)); + /* Create a new list for this xid, if we don't have one already. */ + entry = hash_search(RecoveryLockLists, &xid, HASH_ENTER, &found); + if (!found) + { + entry->xid = xid; + entry->locks = NIL; + } + newlock = palloc(sizeof(xl_standby_lock)); newlock->xid = xid; newlock->dbOid = dbOid; newlock->relOid = relOid; - RecoveryLockList = lappend(RecoveryLockList, newlock); + entry->locks = lappend(entry->locks, newlock); SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid); - LockAcquireExtended(&locktag, AccessExclusiveLock, true, false, false); + (void) LockAcquire(&locktag, AccessExclusiveLock, true, false); } static void -StandbyReleaseLocks(TransactionId xid) +StandbyReleaseLockList(List *locks) { - ListCell *cell, - *prev, - *next; - - /* - * Release all matching locks and remove them from list - */ - prev = NULL; - for (cell = list_head(RecoveryLockList); cell; cell = next) + while (locks) { - xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell); - - next = lnext(cell); + xl_standby_lock *lock = (xl_standby_lock *) linitial(locks); + LOCKTAG locktag; - if (!TransactionIdIsValid(xid) || lock->xid == xid) + elog(trace_recovery(DEBUG4), + "releasing recovery lock: xid %u db %u rel %u", + lock->xid, lock->dbOid, lock->relOid); + SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid); + if (!LockRelease(&locktag, AccessExclusiveLock, true)) { - LOCKTAG locktag; - - elog(trace_recovery(DEBUG4), - "releasing recovery lock: xid %u db %u rel %u", + elog(LOG, + "RecoveryLockLists contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u", lock->xid, lock->dbOid, lock->relOid); - SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid); - if (!LockRelease(&locktag, AccessExclusiveLock, true)) - elog(LOG, - "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u", - lock->xid, lock->dbOid, lock->relOid); - - RecoveryLockList = list_delete_cell(RecoveryLockList, cell, prev); - pfree(lock); + Assert(false); + } + pfree(lock); + locks = list_delete_first(locks); + } +} + +static void +StandbyReleaseLocks(TransactionId xid) +{ + RecoveryLockListsEntry *entry; + + if (TransactionIdIsValid(xid)) + { + if ((entry = hash_search(RecoveryLockLists, &xid, HASH_FIND, NULL))) + { + StandbyReleaseLockList(entry->locks); + hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL); } - else - prev = cell; } + else + StandbyReleaseAllLocks(); } /* * Release locks for a transaction tree, starting at xid down, from - * RecoveryLockList. + * RecoveryLockLists. * * Called during WAL replay of COMMIT/ROLLBACK when in hot standby mode, * to remove any AccessExclusiveLocks requested by a transaction. @@ -689,30 +729,16 @@ StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids) void StandbyReleaseAllLocks(void) { - ListCell *cell, - *prev, - *next; - LOCKTAG locktag; + HASH_SEQ_STATUS status; + RecoveryLockListsEntry *entry; elog(trace_recovery(DEBUG2), "release all standby locks"); - prev = NULL; - for (cell = list_head(RecoveryLockList); cell; cell = next) + hash_seq_init(&status, RecoveryLockLists); + while ((entry = hash_seq_search(&status))) { - xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell); - - next = lnext(cell); - - elog(trace_recovery(DEBUG4), - "releasing recovery lock: xid %u db %u rel %u", - lock->xid, lock->dbOid, lock->relOid); - SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid); - if (!LockRelease(&locktag, AccessExclusiveLock, true)) - elog(LOG, - "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u", - lock->xid, lock->dbOid, lock->relOid); - RecoveryLockList = list_delete_cell(RecoveryLockList, cell, prev); - pfree(lock); + StandbyReleaseLockList(entry->locks); + hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL); } } @@ -722,61 +748,27 @@ StandbyReleaseAllLocks(void) * as long as they're not prepared transactions. */ void -StandbyReleaseOldLocks(int nxids, TransactionId *xids) +StandbyReleaseOldLocks(TransactionId oldxid) { - ListCell *cell, - *prev, - *next; - LOCKTAG locktag; + HASH_SEQ_STATUS status; + RecoveryLockListsEntry *entry; - prev = NULL; - for (cell = list_head(RecoveryLockList); cell; cell = next) + hash_seq_init(&status, RecoveryLockLists); + while ((entry = hash_seq_search(&status))) { - xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell); - bool remove = false; - - next = lnext(cell); + Assert(TransactionIdIsValid(entry->xid)); - Assert(TransactionIdIsValid(lock->xid)); - - if (StandbyTransactionIdIsPrepared(lock->xid)) - remove = false; - else - { - int i; - bool found = false; + /* Skip if prepared transaction. */ + if (StandbyTransactionIdIsPrepared(entry->xid)) + continue; - for (i = 0; i < nxids; i++) - { - if (lock->xid == xids[i]) - { - found = true; - break; - } - } + /* Skip if >= oldxid. */ + if (!TransactionIdPrecedes(entry->xid, oldxid)) + continue; - /* - * If its not a running transaction, remove it. - */ - if (!found) - remove = true; - } - - if (remove) - { - elog(trace_recovery(DEBUG4), - "releasing recovery lock: xid %u db %u rel %u", - lock->xid, lock->dbOid, lock->relOid); - SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid); - if (!LockRelease(&locktag, AccessExclusiveLock, true)) - elog(LOG, - "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u", - lock->xid, lock->dbOid, lock->relOid); - RecoveryLockList = list_delete_cell(RecoveryLockList, cell, prev); - pfree(lock); - } - else - prev = cell; + /* Remove all locks and hash table entry. */ + StandbyReleaseLockList(entry->locks); + hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL); } } @@ -875,7 +867,7 @@ standby_redo(XLogReaderState *record) * up from a checkpoint and are immediately at our starting point, we * unconditionally move to STANDBY_INITIALIZED. After this point we * must do 4 things: - * * move shared nextXid forwards as we see new xids + * * move shared nextFullXid forwards as we see new xids * * extend the clog and subtrans with each new xid * * keep track of uncommitted known assigned xids * * keep track of uncommitted AccessExclusiveLocks @@ -1050,11 +1042,6 @@ LogAccessExclusiveLock(Oid dbOid, Oid relOid) xlrec.xid = GetCurrentTransactionId(); - /* - * Decode the locktag back to the original values, to avoid sending lots - * of empty bytes with every message. See lock.h to check how a locktag - * is defined for LOCKTAG_RELATION - */ xlrec.dbOid = dbOid; xlrec.relOid = relOid; diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index 7eac0724bb2..e5912363433 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -19,7 +19,7 @@ * memory context given to inv_open (for LargeObjectDesc structs). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -32,10 +32,11 @@ #include +#include "access/detoast.h" #include "access/genam.h" -#include "access/heapam.h" +#include "access/htup_details.h" #include "access/sysattr.h" -#include "access/tuptoaster.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" @@ -48,7 +49,6 @@ #include "utils/fmgroids.h" #include "utils/rel.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" /* @@ -84,7 +84,7 @@ open_lo_relation(void) /* Use RowExclusiveLock since we might either read or write */ if (lo_heap_r == NULL) - lo_heap_r = heap_open(LargeObjectRelationId, RowExclusiveLock); + lo_heap_r = table_open(LargeObjectRelationId, RowExclusiveLock); if (lo_index_r == NULL) lo_index_r = index_open(LargeObjectLOidPNIndexId, RowExclusiveLock); @@ -113,7 +113,7 @@ close_lo_relation(bool isCommit) if (lo_index_r) index_close(lo_index_r, NoLock); if (lo_heap_r) - heap_close(lo_heap_r, NoLock); + table_close(lo_heap_r, NoLock); CurrentResourceOwner = currentOwner; } @@ -137,12 +137,12 @@ myLargeObjectExists(Oid loid, Snapshot snapshot) bool retval = false; ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_largeobject_metadata_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(loid)); - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - AccessShareLock); + pg_lo_meta = table_open(LargeObjectMetadataRelationId, + AccessShareLock); sd = systable_beginscan(pg_lo_meta, LargeObjectMetadataOidIndexId, true, @@ -154,7 +154,7 @@ myLargeObjectExists(Oid loid, Snapshot snapshot) systable_endscan(sd); - heap_close(pg_lo_meta, AccessShareLock); + table_close(pg_lo_meta, AccessShareLock); return retval; } diff --git a/src/backend/storage/lmgr/README-SSI b/src/backend/storage/lmgr/README-SSI index f2b099d1c9e..50d2ecca9d7 100644 --- a/src/backend/storage/lmgr/README-SSI +++ b/src/backend/storage/lmgr/README-SSI @@ -373,21 +373,22 @@ index *leaf* pages needed to lock the appropriate index range. If, however, a search discovers that no root page has yet been created, a predicate lock on the index relation is required. + * Like a B-tree, GIN searches acquire predicate locks only on the +leaf pages of entry tree. When performing an equality scan, and an +entry has a posting tree, the posting tree root is locked instead, to +lock only that key value. However, fastupdate=on postpones the +insertion of tuples into index structure by temporarily storing them +into pending list. That makes us unable to detect r-w conflicts using +page-level locks. To cope with that, insertions to the pending list +conflict with all scans. + * GiST searches can determine that there are no matches at any level of the index, so we acquire predicate lock at each index level during a GiST search. An index insert at the leaf level can then be trusted to ripple up to all levels and locations where conflicting predicate locks may exist. In case there is a page split, -we need to copy predicate lock from an original page to all new pages. - - * GIN searches acquire predicate locks only on the leaf pages -of entry tree and posting tree. During a page split, a predicate locks are -copied from the original page to the new page. In the same way predicate locks -are copied from entry tree leaf page to freshly created posting tree root. -However, when fast update is enabled, a predicate lock on the whole index -relation is required. Fast update postpones the insertion of tuples into index -structure by temporarily storing them into pending list. That makes us unable -to detect r-w conflicts using page-level locks. +we need to copy predicate lock from the original page to all the new +pages. * Hash index searches acquire predicate locks on the primary page of a bucket. It acquires a lock on both the old and new buckets @@ -395,7 +396,6 @@ for scans that happen concurrently with page splits. During a bucket split, a predicate lock is copied from the primary page of an old bucket to the primary page of a new bucket. - * The effects of page splits, overflows, consolidations, and removals must be carefully reviewed to ensure that predicate locks aren't "lost" during those operations, or kept with pages which could diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c index ef1d5baf016..e08507f0cc5 100644 --- a/src/backend/storage/lmgr/condition_variable.c +++ b/src/backend/storage/lmgr/condition_variable.c @@ -8,7 +8,7 @@ * interrupted, unlike LWLock waits. Condition variables are safe * to use within dynamic shared memory segments. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/storage/lmgr/condition_variable.c @@ -19,6 +19,7 @@ #include "postgres.h" #include "miscadmin.h" +#include "portability/instr_time.h" #include "storage/condition_variable.h" #include "storage/ipc.h" #include "storage/proc.h" @@ -72,7 +73,7 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv) new_event_set = CreateWaitEventSet(TopMemoryContext, 2); AddWaitEventToSet(new_event_set, WL_LATCH_SET, PGINVALID_SOCKET, MyLatch, NULL); - AddWaitEventToSet(new_event_set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET, + AddWaitEventToSet(new_event_set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET, NULL, NULL); /* Don't set cv_wait_event_set until we have a correct WES. */ cv_wait_event_set = new_event_set; @@ -122,8 +123,24 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv) void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info) { - WaitEvent event; - bool done = false; + (void) ConditionVariableTimedSleep(cv, -1 /* no timeout */ , + wait_event_info); +} + +/* + * Wait for a condition variable to be signaled or a timeout to be reached. + * + * Returns true when timeout expires, otherwise returns false. + * + * See ConditionVariableSleep() for general usage. + */ +bool +ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, + uint32 wait_event_info) +{ + long cur_timeout = -1; + instr_time start_time; + instr_time cur_time; /* * If the caller didn't prepare to sleep explicitly, then do so now and @@ -143,31 +160,37 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info) if (cv_sleep_target != cv) { ConditionVariablePrepareToSleep(cv); - return; + return false; } - do + /* + * Record the current time so that we can calculate the remaining timeout + * if we are woken up spuriously. + */ + if (timeout >= 0) { - CHECK_FOR_INTERRUPTS(); + INSTR_TIME_SET_CURRENT(start_time); + Assert(timeout >= 0 && timeout <= INT_MAX); + cur_timeout = timeout; + } + + while (true) + { + WaitEvent event; + bool done = false; /* * Wait for latch to be set. (If we're awakened for some other * reason, the code below will cope anyway.) */ - WaitEventSetWait(cv_wait_event_set, -1, &event, 1, wait_event_info); - - if (event.events & WL_POSTMASTER_DEATH) - { - /* - * Emergency bailout if postmaster has died. This is to avoid the - * necessity for manual cleanup of all postmaster children. - */ - exit(1); - } + (void) WaitEventSetWait(cv_wait_event_set, cur_timeout, &event, 1, + wait_event_info); /* Reset latch before examining the state of the wait list. */ ResetLatch(MyLatch); + CHECK_FOR_INTERRUPTS(); + /* * If this process has been taken out of the wait list, then we know * that it has been signaled by ConditionVariableSignal (or @@ -190,7 +213,23 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info) proclist_push_tail(&cv->wakeup, MyProc->pgprocno, cvWaitLink); } SpinLockRelease(&cv->mutex); - } while (!done); + + /* We were signaled, so return */ + if (done) + return false; + + /* If we're not done, update cur_timeout for next iteration */ + if (timeout >= 0) + { + INSTR_TIME_SET_CURRENT(cur_time); + INSTR_TIME_SUBTRACT(cur_time, start_time); + cur_timeout = timeout - (long) INSTR_TIME_GET_MILLISEC(cur_time); + + /* Have we crossed the timeout threshold? */ + if (cur_timeout <= 0) + return true; + } + } } /* @@ -206,6 +245,7 @@ void ConditionVariableCancelSleep(void) { ConditionVariable *cv = cv_sleep_target; + bool signaled = false; if (cv == NULL) return; @@ -213,8 +253,18 @@ ConditionVariableCancelSleep(void) SpinLockAcquire(&cv->mutex); if (proclist_contains(&cv->wakeup, MyProc->pgprocno, cvWaitLink)) proclist_delete(&cv->wakeup, MyProc->pgprocno, cvWaitLink); + else + signaled = true; SpinLockRelease(&cv->mutex); + /* + * If we've received a signal, pass it on to another waiting process, if + * there is one. Otherwise a call to ConditionVariableSignal() might get + * lost, despite there being another process ready to handle it. + */ + if (signaled) + ConditionVariableSignal(cv); + cv_sleep_target = NULL; } diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index aeaf1f3ab44..c687496b041 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -7,7 +7,7 @@ * detection and resolution algorithms. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -79,15 +79,15 @@ typedef struct static bool DeadLockCheckRecurse(PGPROC *proc); static int TestConfiguration(PGPROC *startProc); static bool FindLockCycle(PGPROC *checkProc, - EDGE *softEdges, int *nSoftEdges); + EDGE *softEdges, int *nSoftEdges); static bool FindLockCycleRecurse(PGPROC *checkProc, int depth, - EDGE *softEdges, int *nSoftEdges); + EDGE *softEdges, int *nSoftEdges); static bool FindLockCycleRecurseMember(PGPROC *checkProc, - PGPROC *checkProcLeader, - int depth, EDGE *softEdges, int *nSoftEdges); + PGPROC *checkProcLeader, + int depth, EDGE *softEdges, int *nSoftEdges); static bool ExpandConstraints(EDGE *constraints, int nConstraints); static bool TopoSort(LOCK *lock, EDGE *constraints, int nConstraints, - PGPROC **ordering); + PGPROC **ordering); #ifdef DEBUG_DEADLOCK static void PrintLockQueue(LOCK *lock, const char *info); @@ -922,6 +922,12 @@ TopoSort(LOCK *lock, * in the same lock group on the queue, set their number of * beforeConstraints to -1 to indicate that they should be emitted * with their groupmates rather than considered separately. + * + * In this loop and the similar one just below, it's critical that we + * consistently select the same representative member of any one lock + * group, so that all the constraints are associated with the same + * proc, and the -1's are only associated with not-representative + * members. We select the last one in the topoProcs array. */ proc = constraints[i].waiter; Assert(proc != NULL); @@ -940,7 +946,6 @@ TopoSort(LOCK *lock, Assert(beforeConstraints[j] <= 0); beforeConstraints[j] = -1; } - break; } } @@ -977,6 +982,7 @@ TopoSort(LOCK *lock, if (kk < 0) continue; + Assert(beforeConstraints[jj] >= 0); beforeConstraints[jj]++; /* waiter must come before */ /* add this constraint to list of after-constraints for blocker */ constraints[i].pred = jj; @@ -1115,7 +1121,7 @@ DeadLockReport(void) } /* Duplicate all the above for the server ... */ - appendStringInfoString(&logbuf, clientbuf.data); + appendBinaryStringInfo(&logbuf, clientbuf.data, clientbuf.len); /* ... and add info about query strings */ for (i = 0; i < nDeadlockDetails; i++) diff --git a/src/backend/storage/lmgr/generate-lwlocknames.pl b/src/backend/storage/lmgr/generate-lwlocknames.pl index 6cf71c10c46..607827c1449 100644 --- a/src/backend/storage/lmgr/generate-lwlocknames.pl +++ b/src/backend/storage/lmgr/generate-lwlocknames.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate lwlocknames.h and lwlocknames.c from lwlocknames.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; @@ -18,12 +18,12 @@ open my $c, '>', $ctmp or die "Could not open $ctmp: $!"; my $autogen = -"/* autogenerated from src/backend/storage/lmgr/lwlocknames.txt, do not edit */\n"; + "/* autogenerated from src/backend/storage/lmgr/lwlocknames.txt, do not edit */\n"; print $h $autogen; print $h "/* there is deliberately not an #ifndef LWLOCKNAMES_H here */\n\n"; print $c $autogen, "\n"; -print $c "char *MainLWLockNames[] = {"; +print $c "const char *const MainLWLockNames[] = {"; while (<$lwlocknames>) { diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index 7b2dcb6c600..46824381146 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -3,7 +3,7 @@ * lmgr.c * POSTGRES lock manager code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,9 +19,12 @@ #include "access/transam.h" #include "access/xact.h" #include "catalog/catalog.h" +#include "commands/progress.h" #include "miscadmin.h" +#include "pgstat.h" #include "storage/lmgr.h" #include "storage/procarray.h" +#include "storage/sinvaladt.h" #include "utils/inval.h" @@ -105,11 +108,12 @@ void LockRelationOid(Oid relid, LOCKMODE lockmode) { LOCKTAG tag; + LOCALLOCK *locallock; LockAcquireResult res; SetLocktagRelationOid(&tag, relid); - res = LockAcquire(&tag, lockmode, false, false); + res = LockAcquireExtended(&tag, lockmode, false, false, true, &locallock); /* * Now that we have the lock, check for invalidation messages, so that we @@ -120,9 +124,18 @@ LockRelationOid(Oid relid, LOCKMODE lockmode) * relcache entry in an undesirable way. (In the case where our own xact * modifies the rel, the relcache update happens via * CommandCounterIncrement, not here.) + * + * However, in corner cases where code acts on tables (usually catalogs) + * recursively, we might get here while still processing invalidation + * messages in some outer execution of this function or a sibling. The + * "cleared" status of the lock tells us whether we really are done + * absorbing relevant inval messages. */ - if (res != LOCKACQUIRE_ALREADY_HELD) + if (res != LOCKACQUIRE_ALREADY_CLEAR) + { AcceptInvalidationMessages(); + MarkLockClear(locallock); + } } /* @@ -138,11 +151,12 @@ bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode) { LOCKTAG tag; + LOCALLOCK *locallock; LockAcquireResult res; SetLocktagRelationOid(&tag, relid); - res = LockAcquire(&tag, lockmode, false, true); + res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock); if (res == LOCKACQUIRE_NOT_AVAIL) return false; @@ -151,8 +165,11 @@ ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode) * Now that we have the lock, check for invalidation messages; see notes * in LockRelationOid. */ - if (res != LOCKACQUIRE_ALREADY_HELD) + if (res != LOCKACQUIRE_ALREADY_CLEAR) + { AcceptInvalidationMessages(); + MarkLockClear(locallock); + } return true; } @@ -199,20 +216,24 @@ void LockRelation(Relation relation, LOCKMODE lockmode) { LOCKTAG tag; + LOCALLOCK *locallock; LockAcquireResult res; SET_LOCKTAG_RELATION(tag, relation->rd_lockInfo.lockRelId.dbId, relation->rd_lockInfo.lockRelId.relId); - res = LockAcquire(&tag, lockmode, false, false); + res = LockAcquireExtended(&tag, lockmode, false, false, true, &locallock); /* * Now that we have the lock, check for invalidation messages; see notes * in LockRelationOid. */ - if (res != LOCKACQUIRE_ALREADY_HELD) + if (res != LOCKACQUIRE_ALREADY_CLEAR) + { AcceptInvalidationMessages(); + MarkLockClear(locallock); + } } /* @@ -226,13 +247,14 @@ bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode) { LOCKTAG tag; + LOCALLOCK *locallock; LockAcquireResult res; SET_LOCKTAG_RELATION(tag, relation->rd_lockInfo.lockRelId.dbId, relation->rd_lockInfo.lockRelId.relId); - res = LockAcquire(&tag, lockmode, false, true); + res = LockAcquireExtended(&tag, lockmode, false, true, true, &locallock); if (res == LOCKACQUIRE_NOT_AVAIL) return false; @@ -241,8 +263,11 @@ ConditionalLockRelation(Relation relation, LOCKMODE lockmode) * Now that we have the lock, check for invalidation messages; see notes * in LockRelationOid. */ - if (res != LOCKACQUIRE_ALREADY_HELD) + if (res != LOCKACQUIRE_ALREADY_CLEAR) + { AcceptInvalidationMessages(); + MarkLockClear(locallock); + } return true; } @@ -265,6 +290,51 @@ UnlockRelation(Relation relation, LOCKMODE lockmode) LockRelease(&tag, lockmode, false); } +/* + * CheckRelationLockedByMe + * + * Returns true if current transaction holds a lock on 'relation' of mode + * 'lockmode'. If 'orstronger' is true, a stronger lockmode is also OK. + * ("Stronger" is defined as "numerically higher", which is a bit + * semantically dubious but is OK for the purposes we use this for.) + */ +bool +CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, bool orstronger) +{ + LOCKTAG tag; + + SET_LOCKTAG_RELATION(tag, + relation->rd_lockInfo.lockRelId.dbId, + relation->rd_lockInfo.lockRelId.relId); + + if (LockHeldByMe(&tag, lockmode)) + return true; + + if (orstronger) + { + LOCKMODE slockmode; + + for (slockmode = lockmode + 1; + slockmode <= MaxLockMode; + slockmode++) + { + if (LockHeldByMe(&tag, slockmode)) + { +#ifdef NOT_USED + /* Sometimes this might be useful for debugging purposes */ + elog(WARNING, "lock mode %s substituted for %s on relation %s", + GetLockmodeName(tag.locktag_lockmethodid, slockmode), + GetLockmodeName(tag.locktag_lockmethodid, lockmode), + RelationGetRelationName(relation)); +#endif + return true; + } + } + } + + return false; +} + /* * LockHasWaitersRelation * @@ -722,7 +792,7 @@ SpeculativeInsertionWait(TransactionId xid, uint32 token) } /* - * XactLockTableWaitErrorContextCb + * XactLockTableWaitErrorCb * Error context callback for transaction lock waits. */ static void @@ -790,10 +860,12 @@ XactLockTableWaitErrorCb(void *arg) * after we obtained our initial list of lockers, we will not wait for them. */ void -WaitForLockersMultiple(List *locktags, LOCKMODE lockmode) +WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress) { List *holders = NIL; ListCell *lc; + int total = 0; + int done = 0; /* Done if no locks to wait for */ if (list_length(locktags) == 0) @@ -803,10 +875,18 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode) foreach(lc, locktags) { LOCKTAG *locktag = lfirst(lc); + int count; - holders = lappend(holders, GetLockConflicts(locktag, lockmode)); + holders = lappend(holders, + GetLockConflicts(locktag, lockmode, + progress ? &count : NULL)); + if (progress) + total += count; } + if (progress) + pgstat_progress_update_param(PROGRESS_WAITFOR_TOTAL, total); + /* * Note: GetLockConflicts() never reports our own xid, hence we need not * check for that. Also, prepared xacts are not reported, which is fine @@ -820,10 +900,37 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode) while (VirtualTransactionIdIsValid(*lockholders)) { + /* + * If requested, publish who we're going to wait for. This is not + * 100% accurate if they're already gone, but we don't care. + */ + if (progress) + { + PGPROC *holder = BackendIdGetProc(lockholders->backendId); + + pgstat_progress_update_param(PROGRESS_WAITFOR_CURRENT_PID, + holder->pid); + } VirtualXactLock(*lockholders, true); lockholders++; + + if (progress) + pgstat_progress_update_param(PROGRESS_WAITFOR_DONE, ++done); } } + if (progress) + { + const int index[] = { + PROGRESS_WAITFOR_TOTAL, + PROGRESS_WAITFOR_DONE, + PROGRESS_WAITFOR_CURRENT_PID + }; + const int64 values[] = { + 0, 0, 0 + }; + + pgstat_progress_update_multi_param(3, index, values); + } list_free_deep(holders); } @@ -834,12 +941,12 @@ WaitForLockersMultiple(List *locktags, LOCKMODE lockmode) * Same as WaitForLockersMultiple, for a single lock tag. */ void -WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode) +WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress) { List *l; l = list_make1(&heaplocktag); - WaitForLockersMultiple(l, lockmode); + WaitForLockersMultiple(l, lockmode, progress); list_free(l); } diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index dc3d8d98179..9089733ecc7 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -3,7 +3,7 @@ * lock.c * POSTGRES primary lock mechanism * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -211,14 +211,14 @@ static int FastPathLocalUseCount = 0; static bool FastPathGrantRelationLock(Oid relid, LOCKMODE lockmode); static bool FastPathUnGrantRelationLock(Oid relid, LOCKMODE lockmode); static bool FastPathTransferRelationLocks(LockMethod lockMethodTable, - const LOCKTAG *locktag, uint32 hashcode); + const LOCKTAG *locktag, uint32 hashcode); static PROCLOCK *FastPathGetRelationLockEntry(LOCALLOCK *locallock); /* * To make the fast-path lock mechanism work, we must have some way of - * preventing the use of the fast-path when a conflicting lock might be - * present. We partition* the locktag space into FAST_PATH_HASH_BUCKETS - * partitions, and maintain an integer count of the number of "strong" lockers + * preventing the use of the fast-path when a conflicting lock might be present. + * We partition* the locktag space into FAST_PATH_STRONG_LOCK_HASH_PARTITIONS, + * and maintain an integer count of the number of "strong" lockers * in each partition. When any "strong" lockers are present (which is * hopefully not very often), the fast-path mechanism can't be used, and we * must fall back to the slower method of pushing matching locks directly @@ -342,7 +342,7 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP) static uint32 proclock_hash(const void *key, Size keysize); static void RemoveLocalLock(LOCALLOCK *locallock); static PROCLOCK *SetupLockInTable(LockMethod lockMethodTable, PGPROC *proc, - const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode); + const LOCKTAG *locktag, uint32 hashcode, LOCKMODE lockmode); static void GrantLockLocal(LOCALLOCK *locallock, ResourceOwner owner); static void BeginStrongLockAcquire(LOCALLOCK *locallock, uint32 fasthashcode); static void FinishStrongLockAcquire(void); @@ -350,15 +350,15 @@ static void WaitOnLock(LOCALLOCK *locallock, ResourceOwner owner); static void ReleaseLockIfHeld(LOCALLOCK *locallock, bool sessionLock); static void LockReassignOwner(LOCALLOCK *locallock, ResourceOwner parent); static bool UnGrantLock(LOCK *lock, LOCKMODE lockmode, - PROCLOCK *proclock, LockMethod lockMethodTable); + PROCLOCK *proclock, LockMethod lockMethodTable); static void CleanUpLock(LOCK *lock, PROCLOCK *proclock, - LockMethod lockMethodTable, uint32 hashcode, - bool wakeupNeeded); + LockMethod lockMethodTable, uint32 hashcode, + bool wakeupNeeded); static void LockRefindAndRelease(LockMethod lockMethodTable, PGPROC *proc, - LOCKTAG *locktag, LOCKMODE lockmode, - bool decrement_strong_lock_count); + LOCKTAG *locktag, LOCKMODE lockmode, + bool decrement_strong_lock_count); static void GetSingleProcBlockerStatusData(PGPROC *blocked_proc, - BlockedProcsData *data); + BlockedProcsData *data); /* @@ -563,6 +563,30 @@ DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2) return false; } +/* + * LockHeldByMe -- test whether lock 'locktag' is held with mode 'lockmode' + * by the current transaction + */ +bool +LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode) +{ + LOCALLOCKTAG localtag; + LOCALLOCK *locallock; + + /* + * See if there is a LOCALLOCK entry for this lock and lockmode + */ + MemSet(&localtag, 0, sizeof(localtag)); /* must clear padding */ + localtag.lock = *locktag; + localtag.mode = lockmode; + + locallock = (LOCALLOCK *) hash_search(LockMethodLocalHash, + (void *) &localtag, + HASH_FIND, NULL); + + return (locallock && locallock->nLocks > 0); +} + /* * LockHasWaiters -- look up 'locktag' and check if releasing this * lock would wake up other processes waiting for it. @@ -669,6 +693,7 @@ LockHasWaiters(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock) * LOCKACQUIRE_NOT_AVAIL lock not available, and dontWait=true * LOCKACQUIRE_OK lock successfully acquired * LOCKACQUIRE_ALREADY_HELD incremented count for lock already held + * LOCKACQUIRE_ALREADY_CLEAR incremented count for lock already clear * * In the normal case where dontWait=false and the caller doesn't need to * distinguish a freshly acquired lock from one already taken earlier in @@ -685,24 +710,31 @@ LockAcquire(const LOCKTAG *locktag, bool sessionLock, bool dontWait) { - return LockAcquireExtended(locktag, lockmode, sessionLock, dontWait, true); + return LockAcquireExtended(locktag, lockmode, sessionLock, dontWait, + true, NULL); } /* * LockAcquireExtended - allows us to specify additional options * - * reportMemoryError specifies whether a lock request that fills the - * lock table should generate an ERROR or not. This allows a priority - * caller to note that the lock table is full and then begin taking - * extreme action to reduce the number of other lock holders before - * retrying the action. + * reportMemoryError specifies whether a lock request that fills the lock + * table should generate an ERROR or not. Passing "false" allows the caller + * to attempt to recover from lock-table-full situations, perhaps by forcibly + * cancelling other lock holders and then retrying. Note, however, that the + * return code for that is LOCKACQUIRE_NOT_AVAIL, so that it's unsafe to use + * in combination with dontWait = true, as the cause of failure couldn't be + * distinguished. + * + * If locallockp isn't NULL, *locallockp receives a pointer to the LOCALLOCK + * table entry if a lock is successfully acquired, or NULL if not. */ LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, - bool reportMemoryError) + bool reportMemoryError, + LOCALLOCK **locallockp) { LOCKMETHODID lockmethodid = locktag->locktag_lockmethodid; LockMethod lockMethodTable; @@ -766,9 +798,10 @@ LockAcquireExtended(const LOCKTAG *locktag, locallock->proclock = NULL; locallock->hashcode = LockTagHashCode(&(localtag.lock)); locallock->nLocks = 0; + locallock->holdsStrongLockCount = false; + locallock->lockCleared = false; locallock->numLockOwners = 0; locallock->maxLockOwners = 8; - locallock->holdsStrongLockCount = false; locallock->lockOwners = NULL; /* in case next line fails */ locallock->lockOwners = (LOCALLOCKOWNER *) MemoryContextAlloc(TopMemoryContext, @@ -789,13 +822,22 @@ LockAcquireExtended(const LOCKTAG *locktag, } hashcode = locallock->hashcode; + if (locallockp) + *locallockp = locallock; + /* * If we already hold the lock, we can just increase the count locally. + * + * If lockCleared is already set, caller need not worry about absorbing + * sinval messages related to the lock's object. */ if (locallock->nLocks > 0) { GrantLockLocal(locallock, owner); - return LOCKACQUIRE_ALREADY_HELD; + if (locallock->lockCleared) + return LOCKACQUIRE_ALREADY_CLEAR; + else + return LOCKACQUIRE_ALREADY_HELD; } /* @@ -877,6 +919,10 @@ LockAcquireExtended(const LOCKTAG *locktag, hashcode)) { AbortStrongLockAcquire(); + if (locallock->nLocks == 0) + RemoveLocalLock(locallock); + if (locallockp) + *locallockp = NULL; if (reportMemoryError) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), @@ -911,6 +957,10 @@ LockAcquireExtended(const LOCKTAG *locktag, { AbortStrongLockAcquire(); LWLockRelease(partitionLock); + if (locallock->nLocks == 0) + RemoveLocalLock(locallock); + if (locallockp) + *locallockp = NULL; if (reportMemoryError) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), @@ -946,8 +996,8 @@ LockAcquireExtended(const LOCKTAG *locktag, /* * We can't acquire the lock immediately. If caller specified no - * blocking, remove useless table entries and return NOT_AVAIL without - * waiting. + * blocking, remove useless table entries and return + * LOCKACQUIRE_NOT_AVAIL without waiting. */ if (dontWait) { @@ -976,6 +1026,8 @@ LockAcquireExtended(const LOCKTAG *locktag, LWLockRelease(partitionLock); if (locallock->nLocks == 0) RemoveLocalLock(locallock); + if (locallockp) + *locallockp = NULL; return LOCKACQUIRE_NOT_AVAIL; } @@ -1645,6 +1697,20 @@ GrantAwaitedLock(void) GrantLockLocal(awaitedLock, awaitedOwner); } +/* + * MarkLockClear -- mark an acquired lock as "clear" + * + * This means that we know we have absorbed all sinval messages that other + * sessions generated before we acquired this lock, and so we can confidently + * assume we know about any catalog changes protected by this lock. + */ +void +MarkLockClear(LOCALLOCK *locallock) +{ + Assert(locallock->nLocks > 0); + locallock->lockCleared = true; +} + /* * WaitOnLock -- wait to acquire a lock * @@ -1909,6 +1975,15 @@ LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock) if (locallock->nLocks > 0) return true; + /* + * At this point we can no longer suppose we are clear of invalidation + * messages related to this lock. Although we'll delete the LOCALLOCK + * object before any intentional return from this routine, it seems worth + * the trouble to explicitly reset lockCleared right now, just in case + * some error prevents us from deleting the LOCALLOCK. + */ + locallock->lockCleared = false; + /* Attempt fast release of any lock eligible for the fast path. */ if (EligibleForRelationFastPath(locktag, lockmode) && FastPathLocalUseCount > 0) @@ -2634,7 +2709,7 @@ FastPathTransferRelationLocks(LockMethod lockMethodTable, const LOCKTAG *locktag } /* - * FastPathGetLockEntry + * FastPathGetRelationLockEntry * Return the PROCLOCK for a lock originally taken via the fast-path, * transferring it to the primary lock table if necessary. * @@ -2732,6 +2807,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock) * xacts merely awaiting such a lock are NOT reported. * * The result array is palloc'd and is terminated with an invalid VXID. + * *countp, if not null, is updated to the number of items set. * * Of course, the result could be out of date by the time it's returned, * so use of this function has to be thought about carefully. @@ -2742,7 +2818,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock) * uses of the result. */ VirtualTransactionId * -GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode) +GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp) { static VirtualTransactionId *vxids; LOCKMETHODID lockmethodid = locktag->locktag_lockmethodid; @@ -2820,8 +2896,8 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode) * the lock, then we needn't examine the individual relation IDs * at all; none of them can be relevant. * - * See FastPathTransferLocks() for discussion of why we do this - * test after acquiring the lock. + * See FastPathTransferRelationLocks() for discussion of why we do + * this test after acquiring the lock. */ if (proc->databaseId != locktag->locktag_field1) { @@ -2889,6 +2965,8 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode) LWLockRelease(partitionLock); vxids[count].backendId = InvalidBackendId; vxids[count].localTransactionId = InvalidLocalTransactionId; + if (countp) + *countp = count; return vxids; } @@ -2944,6 +3022,8 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode) vxids[count].backendId = InvalidBackendId; vxids[count].localTransactionId = InvalidLocalTransactionId; + if (countp) + *countp = count; return vxids; } @@ -3168,7 +3248,7 @@ AtPrepare_Locks(void) void PostPrepare_Locks(TransactionId xid) { - PGPROC *newproc = TwoPhaseGetDummyProc(xid); + PGPROC *newproc = TwoPhaseGetDummyProc(xid, false); HASH_SEQ_STATUS status; LOCALLOCK *locallock; LOCK *lock; @@ -3959,7 +4039,7 @@ lock_twophase_recover(TransactionId xid, uint16 info, void *recdata, uint32 len) { TwoPhaseLockRecord *rec = (TwoPhaseLockRecord *) recdata; - PGPROC *proc = TwoPhaseGetDummyProc(xid); + PGPROC *proc = TwoPhaseGetDummyProc(xid, false); LOCKTAG *locktag; LOCKMODE lockmode; LOCKMETHODID lockmethodid; @@ -4172,7 +4252,7 @@ lock_twophase_postcommit(TransactionId xid, uint16 info, void *recdata, uint32 len) { TwoPhaseLockRecord *rec = (TwoPhaseLockRecord *) recdata; - PGPROC *proc = TwoPhaseGetDummyProc(xid); + PGPROC *proc = TwoPhaseGetDummyProc(xid, true); LOCKTAG *locktag; LOCKMETHODID lockmethodid; LockMethod lockMethodTable; diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index a6fda81feb6..7badf4b205f 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -20,7 +20,7 @@ * appropriate value for a free lock. The meaning of the variable is up to * the caller, the lightweight lock code just assigns and compares it. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -232,7 +232,7 @@ LOG_LWDEBUG(const char *where, LWLock *lock, const char *msg) static void init_lwlock_stats(void); static void print_lwlock_stats(int code, Datum arg); -static lwlock_stats * get_lwlock_stats_entry(LWLock *lockid); +static lwlock_stats * get_lwlock_stats_entry(LWLock *lock); static void init_lwlock_stats(void) @@ -521,6 +521,7 @@ RegisterLWLockTranches(void) LWLockRegisterTranche(LWTRANCHE_TBM, "tbm"); LWLockRegisterTranche(LWTRANCHE_PARALLEL_APPEND, "parallel_append"); LWLockRegisterTranche(LWTRANCHE_PARALLEL_HASH_JOIN, "parallel_hash_join"); + LWLockRegisterTranche(LWTRANCHE_SXACT, "serializable_xact"); /* Register named tranches. */ for (i = 0; i < NamedLWLockTrancheRequests; i++) @@ -1074,8 +1075,8 @@ LWLockDequeueSelf(LWLock *lock) */ /* - * Reset releaseOk if somebody woke us before we removed ourselves - - * they'll have set it to false. + * Reset RELEASE_OK flag if somebody woke us before we removed + * ourselves - they'll have set it to false. */ pg_atomic_fetch_or_u32(&lock->state, LW_FLAG_RELEASE_OK); @@ -1146,7 +1147,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode) * during bootstrap or shared memory initialization. Put an Assert here * to catch unsafe coding practices. */ - Assert(!(proc == NULL && IsUnderPostmaster)); + Assert(!(proc == NULL && IsUnderPostmaster && !IsOnlineUpgrade)); /* Ensure we will have room to remember the lock */ if (num_held_lwlocks >= MAX_SIMUL_LWLOCKS) diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt index e6025ecedb3..db478432291 100644 --- a/src/backend/storage/lmgr/lwlocknames.txt +++ b/src/backend/storage/lmgr/lwlocknames.txt @@ -47,6 +47,5 @@ CommitTsLock 39 ReplicationOriginLock 40 MultiXactTruncationLock 41 OldSnapshotTimeMapLock 42 -BackendRandomLock 43 -LogicalRepWorkerLock 44 -CLogTruncationLock 45 +LogicalRepWorkerLock 43 +CLogTruncationLock 44 diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index e8390311d03..d7bc8d75edc 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -97,7 +97,9 @@ * - All transactions share this single lock (with no partitioning). * - There is never a need for a process other than the one running * an active transaction to walk the list of locks held by that - * transaction. + * transaction, except parallel query workers sharing the leader's + * transaction. In the parallel case, an extra per-sxact lock is + * taken; see below. * - It is relatively infrequent that another process needs to * modify the list for a transaction, but it does happen for such * things as index page splits for pages with predicate locks and @@ -116,6 +118,12 @@ * than its own active transaction must acquire an exclusive * lock. * + * SERIALIZABLEXACT's member 'predicateLockListLock' + * - Protects the linked list of locks held by a transaction. Only + * needed for parallel mode, where multiple backends share the + * same SERIALIZABLEXACT object. Not needed if + * SerializablePredicateLockListLock is held exclusively. + * * PredicateLockHashPartitionLock(hashcode) * - The same lock protects a target, all locks on that target, and * the linked list of locks on the target. @@ -127,7 +135,7 @@ * - Protects both PredXact and SerializableXidHash. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -162,7 +170,7 @@ * PredicateLockPageCombine(Relation relation, BlockNumber oldblkno, * BlockNumber newblkno) * TransferPredicateLocksToHeapRelation(Relation relation) - * ReleasePredicateLocks(bool isCommit) + * ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe) * * conflict detection (may also trigger rollback) * CheckForSerializableConflictOut(bool visible, Relation relation, @@ -185,7 +193,9 @@ #include "postgres.h" +#include "access/heapam.h" #include "access/htup_details.h" +#include "access/parallel.h" #include "access/slru.h" #include "access/subtrans.h" #include "access/transam.h" @@ -202,7 +212,6 @@ #include "storage/procarray.h" #include "utils/rel.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" /* Uncomment the next line to test the graceful degradation code. */ /* #define TEST_OLDSERXID */ @@ -279,6 +288,7 @@ #define SxactIsDeferrableWaiting(sxact) (((sxact)->flags & SXACT_FLAG_DEFERRABLE_WAITING) != 0) #define SxactIsROSafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_SAFE) != 0) #define SxactIsROUnsafe(sxact) (((sxact)->flags & SXACT_FLAG_RO_UNSAFE) != 0) +#define SxactIsPartiallyReleased(sxact) (((sxact)->flags & SXACT_FLAG_PARTIALLY_RELEASED) != 0) /* * Compute the hash code associated with a PREDICATELOCKTARGETTAG. @@ -354,7 +364,7 @@ static SERIALIZABLEXACT *OldCommittedSxact; * These configuration variables are used to set the predicate lock table size * and to control promotion of predicate locks to coarser granularity in an * attempt to degrade performance (mostly as false positive serialization - * failure) gracefully in the face of memory pressurel + * failure) gracefully in the face of memory pressure. */ int max_predicate_locks_per_xact; /* set by guc.c */ int max_predicate_locks_per_relation; /* set by guc.c */ @@ -409,6 +419,15 @@ static HTAB *LocalPredicateLockHash = NULL; static SERIALIZABLEXACT *MySerializableXact = InvalidSerializableXact; static bool MyXactDidWrite = false; +/* + * The SXACT_FLAG_RO_UNSAFE optimization might lead us to release + * MySerializableXact early. If that happens in a parallel query, the leader + * needs to defer the destruction of the SERIALIZABLEXACT until end of + * transaction, because the workers still have a reference to it. In that + * case, the leader stores it here. + */ +static SERIALIZABLEXACT *SavedSerializableXact = InvalidSerializableXact; + /* local functions */ static SERIALIZABLEXACT *CreatePredXact(void); @@ -432,39 +451,41 @@ static uint32 predicatelock_hash(const void *key, Size keysize); static void SummarizeOldestCommittedSxact(void); static Snapshot GetSafeSnapshot(Snapshot snapshot); static Snapshot GetSerializableTransactionSnapshotInt(Snapshot snapshot, - VirtualTransactionId *sourcevxid, - int sourcepid); + VirtualTransactionId *sourcevxid, + int sourcepid); static bool PredicateLockExists(const PREDICATELOCKTARGETTAG *targettag); static bool GetParentPredicateLockTag(const PREDICATELOCKTARGETTAG *tag, - PREDICATELOCKTARGETTAG *parent); + PREDICATELOCKTARGETTAG *parent); static bool CoarserLockCovers(const PREDICATELOCKTARGETTAG *newtargettag); static void RemoveScratchTarget(bool lockheld); static void RestoreScratchTarget(bool lockheld); static void RemoveTargetIfNoLongerUsed(PREDICATELOCKTARGET *target, - uint32 targettaghash); + uint32 targettaghash); static void DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag); static int MaxPredicateChildLocks(const PREDICATELOCKTARGETTAG *tag); static bool CheckAndPromotePredicateLockRequest(const PREDICATELOCKTARGETTAG *reqtag); static void DecrementParentLocks(const PREDICATELOCKTARGETTAG *targettag); static void CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag, - uint32 targettaghash, - SERIALIZABLEXACT *sxact); + uint32 targettaghash, + SERIALIZABLEXACT *sxact); static void DeleteLockTarget(PREDICATELOCKTARGET *target, uint32 targettaghash); static bool TransferPredicateLocksToNewTarget(PREDICATELOCKTARGETTAG oldtargettag, - PREDICATELOCKTARGETTAG newtargettag, - bool removeOld); + PREDICATELOCKTARGETTAG newtargettag, + bool removeOld); static void PredicateLockAcquire(const PREDICATELOCKTARGETTAG *targettag); static void DropAllPredicateLocksFromTable(Relation relation, - bool transfer); + bool transfer); static void SetNewSxactGlobalXmin(void); static void ClearOldPredicateLocks(void); static void ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, - bool summarize); + bool summarize); static bool XidIsConcurrent(TransactionId xid); static void CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag); static void FlagRWConflict(SERIALIZABLEXACT *reader, SERIALIZABLEXACT *writer); static void OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, - SERIALIZABLEXACT *writer); + SERIALIZABLEXACT *writer); +static void CreateLocalPredicateLockHash(void); +static void ReleasePredicateLocksLocal(void); /*------------------------------------------------------------------------*/ @@ -521,7 +542,7 @@ SerializationNeededForRead(Relation relation, Snapshot snapshot) */ if (SxactIsROSafe(MySerializableXact)) { - ReleasePredicateLocks(false); + ReleasePredicateLocks(false, true); return false; } @@ -828,7 +849,7 @@ OldSerXidInit(void) /* * Record a committed read write serializable xid and the minimum * commitSeqNo of any transactions to which this xid had a rw-conflict out. - * An invalid seqNo means that there were no conflicts out from xid. + * An invalid commitSeqNo means that there were no conflicts out from xid. */ static void OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo) @@ -1067,7 +1088,7 @@ InitPredicateLocks(void) bool found; #ifndef EXEC_BACKEND - Assert(!IsUnderPostmaster); + Assert(!IsUnderPostmaster || IsOnlineUpgrade); #endif /* @@ -1168,6 +1189,8 @@ InitPredicateLocks(void) memset(PredXact->element, 0, requestSize); for (i = 0; i < max_table_size; i++) { + LWLockInitialize(&PredXact->element[i].sxact.predicateLockListLock, + LWTRANCHE_SXACT); SHMQueueInsertBefore(&(PredXact->availableList), &(PredXact->element[i].link)); } @@ -1513,14 +1536,14 @@ GetSafeSnapshot(Snapshot origSnapshot) ereport(DEBUG2, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), errmsg("deferrable snapshot was unsafe; trying a new one"))); - ReleasePredicateLocks(false); + ReleasePredicateLocks(false, false); } /* * Now we have a safe snapshot, so we don't need to do any further checks. */ Assert(SxactIsROSafe(MySerializableXact)); - ReleasePredicateLocks(false); + ReleasePredicateLocks(false, true); return snapshot; } @@ -1633,6 +1656,17 @@ SetSerializableTransactionSnapshot(Snapshot snapshot, { Assert(IsolationIsSerializable()); + /* + * If this is called by parallel.c in a parallel worker, we don't want to + * create a SERIALIZABLEXACT just yet because the leader's + * SERIALIZABLEXACT will be installed with AttachSerializableXact(). We + * also don't want to reject SERIALIZABLE READ ONLY DEFERRABLE in this + * case, because the leader has already determined that the snapshot it + * has passed us is safe. So there is nothing for us to do. + */ + if (IsParallelWorker()) + return; + /* * We do not allow SERIALIZABLE READ ONLY DEFERRABLE transactions to * import snapshots, since there's no way to wait for a safe snapshot when @@ -1651,7 +1685,7 @@ SetSerializableTransactionSnapshot(Snapshot snapshot, /* * Guts of GetSerializableTransactionSnapshot * - * If sourcexid is valid, this is actually an import operation and we should + * If sourcevxid is valid, this is actually an import operation and we should * skip calling GetSnapshotData, because the snapshot contents are already * loaded up. HOWEVER: to avoid race conditions, we must check that the * source xact is still running after we acquire SerializableXactHashLock. @@ -1666,7 +1700,6 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot, VirtualTransactionId vxid; SERIALIZABLEXACT *sxact, *othersxact; - HASHCTL hash_ctl; /* We only do this for serializable transactions. Once. */ Assert(MySerializableXact == InvalidSerializableXact); @@ -1813,6 +1846,16 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot, LWLockRelease(SerializableXactHashLock); + CreateLocalPredicateLockHash(); + + return snapshot; +} + +static void +CreateLocalPredicateLockHash(void) +{ + HASHCTL hash_ctl; + /* Initialize the backend-local hash table of parent locks */ Assert(LocalPredicateLockHash == NULL); MemSet(&hash_ctl, 0, sizeof(hash_ctl)); @@ -1822,8 +1865,6 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot, max_predicate_locks_per_xact, &hash_ctl, HASH_ELEM | HASH_BLOBS); - - return snapshot; } /* @@ -2078,7 +2119,9 @@ RemoveTargetIfNoLongerUsed(PREDICATELOCKTARGET *target, uint32 targettaghash) * This implementation is assuming that the usage of each target tag field * is uniform. No need to make this hard if we don't have to. * - * We aren't acquiring lightweight locks for the predicate lock or lock + * We acquire an LWLock in the case of parallel mode, because worker + * backends have access to the leader's SERIALIZABLEXACT. Otherwise, + * we aren't acquiring LWLocks for the predicate lock or lock * target structures associated with this transaction unless we're going * to modify them, because no other process is permitted to modify our * locks. @@ -2091,6 +2134,8 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag) LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); sxact = MySerializableXact; + if (IsInParallelMode()) + LWLockAcquire(&sxact->predicateLockListLock, LW_EXCLUSIVE); predlock = (PREDICATELOCK *) SHMQueueNext(&(sxact->predicateLocks), &(sxact->predicateLocks), @@ -2144,6 +2189,8 @@ DeleteChildTargetLocks(const PREDICATELOCKTARGETTAG *newtargettag) predlock = nextpredlock; } + if (IsInParallelMode()) + LWLockRelease(&sxact->predicateLockListLock); LWLockRelease(SerializablePredicateLockListLock); } @@ -2342,6 +2389,8 @@ CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag, partitionLock = PredicateLockHashPartitionLock(targettaghash); LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); + if (IsInParallelMode()) + LWLockAcquire(&sxact->predicateLockListLock, LW_EXCLUSIVE); LWLockAcquire(partitionLock, LW_EXCLUSIVE); /* Make sure that the target is represented. */ @@ -2379,6 +2428,8 @@ CreatePredicateLock(const PREDICATELOCKTARGETTAG *targettag, } LWLockRelease(partitionLock); + if (IsInParallelMode()) + LWLockRelease(&sxact->predicateLockListLock); LWLockRelease(SerializablePredicateLockListLock); } @@ -2566,7 +2617,8 @@ DeleteLockTarget(PREDICATELOCKTARGET *target, uint32 targettaghash) PREDICATELOCK *nextpredlock; bool found; - Assert(LWLockHeldByMe(SerializablePredicateLockListLock)); + Assert(LWLockHeldByMeInMode(SerializablePredicateLockListLock, + LW_EXCLUSIVE)); Assert(LWLockHeldByMe(PredicateLockHashPartitionLock(targettaghash))); predlock = (PREDICATELOCK *) @@ -2626,7 +2678,7 @@ DeleteLockTarget(PREDICATELOCKTARGET *target, uint32 targettaghash) * covers it, or if we are absolutely certain that no one will need to * refer to that lock in the future. * - * Caller must hold SerializablePredicateLockListLock. + * Caller must hold SerializablePredicateLockListLock exclusively. */ static bool TransferPredicateLocksToNewTarget(PREDICATELOCKTARGETTAG oldtargettag, @@ -2641,7 +2693,8 @@ TransferPredicateLocksToNewTarget(PREDICATELOCKTARGETTAG oldtargettag, bool found; bool outOfShmem = false; - Assert(LWLockHeldByMe(SerializablePredicateLockListLock)); + Assert(LWLockHeldByMeInMode(SerializablePredicateLockListLock, + LW_EXCLUSIVE)); oldtargettaghash = PredicateLockTargetTagHashCode(&oldtargettag); newtargettaghash = PredicateLockTargetTagHashCode(&newtargettag); @@ -3217,9 +3270,17 @@ SetNewSxactGlobalXmin(void) * If this transaction is committing and is holding any predicate locks, * it must be added to a list of completed serializable transactions still * holding locks. + * + * If isReadOnlySafe is true, then predicate locks are being released before + * the end of the transaction because MySerializableXact has been determined + * to be RO_SAFE. In non-parallel mode we can release it completely, but it + * in parallel mode we partially release the SERIALIZABLEXACT and keep it + * around until the end of the transaction, allowing each backend to clear its + * MySerializableXact variable and benefit from the optimization in its own + * time. */ void -ReleasePredicateLocks(bool isCommit) +ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe) { bool needToClear; RWConflict conflict, @@ -3238,6 +3299,44 @@ ReleasePredicateLocks(bool isCommit) */ bool topLevelIsDeclaredReadOnly; + /* We can't be both committing and releasing early due to RO_SAFE. */ + Assert(!(isCommit && isReadOnlySafe)); + + /* Are we at the end of a transaction, that is, a commit or abort? */ + if (!isReadOnlySafe) + { + /* + * Parallel workers mustn't release predicate locks at the end of + * their transaction. The leader will do that at the end of its + * transaction. + */ + if (IsParallelWorker()) + { + ReleasePredicateLocksLocal(); + return; + } + + /* + * By the time the leader in a parallel query reaches end of + * transaction, it has waited for all workers to exit. + */ + Assert(!ParallelContextActive()); + + /* + * If the leader in a parallel query earlier stashed a partially + * released SERIALIZABLEXACT for final clean-up at end of transaction + * (because workers might still have been accessing it), then it's + * time to restore it. + */ + if (SavedSerializableXact != InvalidSerializableXact) + { + Assert(MySerializableXact == InvalidSerializableXact); + MySerializableXact = SavedSerializableXact; + SavedSerializableXact = InvalidSerializableXact; + Assert(SxactIsPartiallyReleased(MySerializableXact)); + } + } + if (MySerializableXact == InvalidSerializableXact) { Assert(LocalPredicateLockHash == NULL); @@ -3246,10 +3345,51 @@ ReleasePredicateLocks(bool isCommit) LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); + /* + * If the transaction is committing, but it has been partially released + * already, then treat this as a roll back. It was marked as rolled back. + */ + if (isCommit && SxactIsPartiallyReleased(MySerializableXact)) + isCommit = false; + + /* + * If we're called in the middle of a transaction because we discovered + * that the SXACT_FLAG_RO_SAFE flag was set, then we'll partially release + * it (that is, release the predicate locks and conflicts, but not the + * SERIALIZABLEXACT itself) if we're the first backend to have noticed. + */ + if (isReadOnlySafe && IsInParallelMode()) + { + /* + * The leader needs to stash a pointer to it, so that it can + * completely release it at end-of-transaction. + */ + if (!IsParallelWorker()) + SavedSerializableXact = MySerializableXact; + + /* + * The first backend to reach this condition will partially release + * the SERIALIZABLEXACT. All others will just clear their + * backend-local state so that they stop doing SSI checks for the rest + * of the transaction. + */ + if (SxactIsPartiallyReleased(MySerializableXact)) + { + LWLockRelease(SerializableXactHashLock); + ReleasePredicateLocksLocal(); + return; + } + else + { + MySerializableXact->flags |= SXACT_FLAG_PARTIALLY_RELEASED; + /* ... and proceed to perform the partial release below. */ + } + } Assert(!isCommit || SxactIsPrepared(MySerializableXact)); Assert(!isCommit || !SxactIsDoomed(MySerializableXact)); Assert(!SxactIsCommitted(MySerializableXact)); - Assert(!SxactIsRolledBack(MySerializableXact)); + Assert(SxactIsPartiallyReleased(MySerializableXact) + || !SxactIsRolledBack(MySerializableXact)); /* may not be serializable during COMMIT/ROLLBACK PREPARED */ Assert(MySerializableXact->pid == 0 || IsolationIsSerializable()); @@ -3265,16 +3405,16 @@ ReleasePredicateLocks(bool isCommit) * * If this value is changing, we don't care that much whether we get the * old or new value -- it is just used to determine how far - * GlobalSerializableXmin must advance before this transaction can be - * fully cleaned up. The worst that could happen is we wait for one more + * SxactGlobalXmin must advance before this transaction can be fully + * cleaned up. The worst that could happen is we wait for one more * transaction to complete before freeing some RAM; correctness of visible * behavior is not affected. */ - MySerializableXact->finishedBefore = ShmemVariableCache->nextXid; + MySerializableXact->finishedBefore = XidFromFullTransactionId(ShmemVariableCache->nextFullXid); /* - * If it's not a commit it's a rollback, and we can clear our locks - * immediately. + * If it's not a commit it's either a rollback or a read-only transaction + * flagged SXACT_FLAG_RO_SAFE, and we can clear our locks immediately. */ if (isCommit) { @@ -3513,14 +3653,28 @@ ReleasePredicateLocks(bool isCommit) SHMQueueInsertBefore(FinishedSerializableTransactions, &MySerializableXact->finishedLink); + /* + * If we're releasing a RO_SAFE transaction in parallel mode, we'll only + * partially release it. That's necessary because other backends may have + * a reference to it. The leader will release the SERIALIZABLEXACT itself + * at the end of the transaction after workers have stopped running. + */ if (!isCommit) - ReleaseOneSerializableXact(MySerializableXact, false, false); + ReleaseOneSerializableXact(MySerializableXact, + isReadOnlySafe && IsInParallelMode(), + false); LWLockRelease(SerializableFinishedListLock); if (needToClear) ClearOldPredicateLocks(); + ReleasePredicateLocksLocal(); +} + +static void +ReleasePredicateLocksLocal(void) +{ MySerializableXact = InvalidSerializableXact; MyXactDidWrite = false; @@ -3712,6 +3866,8 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, * them to OldCommittedSxact if summarize is true) */ LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); + if (IsInParallelMode()) + LWLockAcquire(&sxact->predicateLockListLock, LW_EXCLUSIVE); predlock = (PREDICATELOCK *) SHMQueueNext(&(sxact->predicateLocks), &(sxact->predicateLocks), @@ -3791,6 +3947,8 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial, */ SHMQueueInit(&sxact->predicateLocks); + if (IsInParallelMode()) + LWLockRelease(&sxact->predicateLockListLock); LWLockRelease(SerializablePredicateLockListLock); sxidtag.xid = sxact->topXid; @@ -4202,7 +4360,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) /* * If we found one of our own SIREAD locks to remove, remove it now. * - * At this point our transaction already has an ExclusiveRowLock on the + * At this point our transaction already has a RowExclusiveLock on the * relation, so we are OK to drop the predicate lock on the tuple, if * found, without fearing that another write against the tuple will occur * before the MVCC information makes it to the buffer. @@ -4213,6 +4371,8 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) PREDICATELOCK *rmpredlock; LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); + if (IsInParallelMode()) + LWLockAcquire(&MySerializableXact->predicateLockListLock, LW_EXCLUSIVE); LWLockAcquire(partitionLock, LW_EXCLUSIVE); LWLockAcquire(SerializableXactHashLock, LW_EXCLUSIVE); @@ -4247,6 +4407,8 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag) LWLockRelease(SerializableXactHashLock); LWLockRelease(partitionLock); + if (IsInParallelMode()) + LWLockRelease(&MySerializableXact->predicateLockListLock); LWLockRelease(SerializablePredicateLockListLock); if (rmpredlock != NULL) @@ -4647,7 +4809,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, } /* - * PreCommit_CheckForSerializableConflicts + * PreCommit_CheckForSerializationFailure * Check for dangerous structures in a serializable transaction * at commit. * @@ -4658,7 +4820,7 @@ OnConflict_CheckForSerializationFailure(const SERIALIZABLEXACT *reader, * * If a dangerous structure is found, the pivot (the near conflict) is * marked for death, because rolling back another transaction might mean - * that we flail without ever making progress. This transaction is + * that we fail without ever making progress. This transaction is * committing writes, so letting it commit ensures progress. If we * canceled the far conflict, it might immediately fail again on retry. */ @@ -4677,6 +4839,7 @@ PreCommit_CheckForSerializationFailure(void) /* Check if someone else has already decided that we need to die */ if (SxactIsDoomed(MySerializableXact)) { + Assert(!SxactIsPartiallyReleased(MySerializableXact)); LWLockRelease(SerializableXactHashLock); ereport(ERROR, (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE), @@ -4795,6 +4958,13 @@ AtPrepare_PredicateLocks(void) */ LWLockAcquire(SerializablePredicateLockListLock, LW_SHARED); + /* + * No need to take sxact->predicateLockListLock in parallel mode because + * there cannot be any parallel workers running while we are preparing a + * transaction. + */ + Assert(!IsParallelWorker() && !ParallelContextActive()); + predlock = (PREDICATELOCK *) SHMQueueNext(&(sxact->predicateLocks), &(sxact->predicateLocks), @@ -4867,7 +5037,7 @@ PredicateLockTwoPhaseFinish(TransactionId xid, bool isCommit) MySerializableXact = sxid->myXact; MyXactDidWrite = true; /* conservatively assume that we wrote * something */ - ReleasePredicateLocks(isCommit); + ReleasePredicateLocks(isCommit, false); } /* @@ -5003,3 +5173,28 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info, CreatePredicateLock(&lockRecord->target, targettaghash, sxact); } } + +/* + * Prepare to share the current SERIALIZABLEXACT with parallel workers. + * Return a handle object that can be used by AttachSerializableXact() in a + * parallel worker. + */ +SerializableXactHandle +ShareSerializableXact(void) +{ + return MySerializableXact; +} + +/* + * Allow parallel workers to import the leader's SERIALIZABLEXACT. + */ +void +AttachSerializableXact(SerializableXactHandle handle) +{ + + Assert(MySerializableXact == InvalidSerializableXact); + + MySerializableXact = (SERIALIZABLEXACT *) handle; + if (MySerializableXact != InvalidSerializableXact) + CreateLocalPredicateLockHash(); +} diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 6f30e082b26..94371dbe3f7 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -3,7 +3,7 @@ * proc.c * routines to manage per-process shared memory data structure * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -43,6 +43,7 @@ #include "postmaster/autovacuum.h" #include "replication/slot.h" #include "replication/syncrep.h" +#include "replication/walsender.h" #include "storage/condition_variable.h" #include "storage/standby.h" #include "storage/ipc.h" @@ -74,11 +75,11 @@ PGXACT *MyPgXact = NULL; * relatively infrequently (only at backend startup or shutdown) and not for * very long, so a spinlock is okay. */ -NON_EXEC_STATIC slock_t *ProcStructLock = NULL; +slock_t *ProcStructLock = NULL; /* Pointers to shared-memory structures */ PROC_HDR *ProcGlobal = NULL; -NON_EXEC_STATIC PGPROC *AuxiliaryProcs = NULL; +PGPROC *AuxiliaryProcs = NULL; PGPROC *PreparedXactProcs = NULL; /* If we are waiting for a lock, this points to the associated LOCALLOCK */ @@ -147,8 +148,9 @@ ProcGlobalSemas(void) * running out when trying to start another backend is a common failure. * So, now we grab enough semaphores to support the desired max number * of backends immediately at initialization --- if the sysadmin has set - * MaxConnections, max_worker_processes, or autovacuum_max_workers higher - * than his kernel will support, he'll find out sooner rather than later. + * MaxConnections, max_worker_processes, max_wal_senders, or + * autovacuum_max_workers higher than his kernel will support, he'll + * find out sooner rather than later. * * Another reason for creating semaphores here is that the semaphore * implementation typically requires us to create semaphores in the @@ -180,6 +182,7 @@ InitProcGlobal(void) ProcGlobal->freeProcs = NULL; ProcGlobal->autovacFreeProcs = NULL; ProcGlobal->bgworkerFreeProcs = NULL; + ProcGlobal->walsenderFreeProcs = NULL; ProcGlobal->startupProc = NULL; ProcGlobal->startupProcPid = 0; ProcGlobal->startupBufferPinWaitBufId = -1; @@ -253,13 +256,20 @@ InitProcGlobal(void) ProcGlobal->autovacFreeProcs = &procs[i]; procs[i].procgloballist = &ProcGlobal->autovacFreeProcs; } - else if (i < MaxBackends) + else if (i < MaxConnections + autovacuum_max_workers + 1 + max_worker_processes) { /* PGPROC for bgworker, add to bgworkerFreeProcs list */ procs[i].links.next = (SHM_QUEUE *) ProcGlobal->bgworkerFreeProcs; ProcGlobal->bgworkerFreeProcs = &procs[i]; procs[i].procgloballist = &ProcGlobal->bgworkerFreeProcs; } + else if (i < MaxBackends) + { + /* PGPROC for walsender, add to walsenderFreeProcs list */ + procs[i].links.next = (SHM_QUEUE *) ProcGlobal->walsenderFreeProcs; + ProcGlobal->walsenderFreeProcs = &procs[i]; + procs[i].procgloballist = &ProcGlobal->walsenderFreeProcs; + } /* Initialize myProcLocks[] shared memory queues. */ for (j = 0; j < NUM_LOCK_PARTITIONS; j++) @@ -267,6 +277,13 @@ InitProcGlobal(void) /* Initialize lockGroupMembers list. */ dlist_init(&procs[i].lockGroupMembers); + + /* + * Initialize the atomic variables, otherwise, it won't be safe to + * access them for backends that aren't currently in use. + */ + pg_atomic_init_u32(&(procs[i].procArrayGroupNext), INVALID_PGPROCNO); + pg_atomic_init_u32(&(procs[i].clogGroupNext), INVALID_PGPROCNO); } /* @@ -304,6 +321,8 @@ InitProcess(void) procgloballist = &ProcGlobal->autovacFreeProcs; else if (IsBackgroundWorker) procgloballist = &ProcGlobal->bgworkerFreeProcs; + else if (am_walsender) + procgloballist = &ProcGlobal->walsenderFreeProcs; else procgloballist = &ProcGlobal->freeProcs; @@ -334,6 +353,11 @@ InitProcess(void) * in the autovacuum case? */ SpinLockRelease(ProcStructLock); + if (am_walsender) + ereport(FATAL, + (errcode(ERRCODE_TOO_MANY_CONNECTIONS), + errmsg("number of requested standby connections exceeds max_wal_senders (currently %d)", + max_wal_senders))); ereport(FATAL, (errcode(ERRCODE_TOO_MANY_CONNECTIONS), errmsg("sorry, too many clients already"))); @@ -371,6 +395,7 @@ InitProcess(void) MyProc->backendId = InvalidBackendId; MyProc->databaseId = InvalidOid; MyProc->roleId = InvalidOid; + MyProc->tempNamespaceId = InvalidOid; MyProc->isBackgroundWorker = IsBackgroundWorker; MyPgXact->delayChkpt = false; MyPgXact->vacuumFlags = 0; @@ -400,7 +425,7 @@ InitProcess(void) /* Initialize fields for group XID clearing. */ MyProc->procArrayGroupMember = false; MyProc->procArrayGroupMemberXid = InvalidTransactionId; - pg_atomic_init_u32(&MyProc->procArrayGroupNext, INVALID_PGPROCNO); + Assert(pg_atomic_read_u32(&MyProc->procArrayGroupNext) == INVALID_PGPROCNO); /* Check that group locking fields are in a proper initial state. */ Assert(MyProc->lockGroupLeader == NULL); @@ -415,7 +440,7 @@ InitProcess(void) MyProc->clogGroupMemberXidStatus = TRANSACTION_STATUS_IN_PROGRESS; MyProc->clogGroupMemberPage = -1; MyProc->clogGroupMemberLsn = InvalidXLogRecPtr; - pg_atomic_init_u32(&MyProc->clogGroupNext, INVALID_PGPROCNO); + Assert(pg_atomic_read_u32(&MyProc->clogGroupNext) == INVALID_PGPROCNO); /* * Acquire ownership of the PGPROC's latch, so that we can use WaitLatch @@ -517,11 +542,20 @@ InitAuxiliaryProcess(void) /* * Find a free auxproc ... *big* trouble if there isn't one ... */ - for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++) + while (true) { - auxproc = &AuxiliaryProcs[proctype]; - if (auxproc->pid == 0) - break; + for (proctype = 0; proctype < NUM_AUXILIARY_PROCS; proctype++) + { + auxproc = &AuxiliaryProcs[proctype]; + if (auxproc->pid == 0) + break; + } + if (IsOnlineUpgrade && proctype >= NUM_AUXILIARY_PROCS) + { + pg_usleep(1000000); + continue; + } + break; } if (proctype >= NUM_AUXILIARY_PROCS) { @@ -552,6 +586,7 @@ InitAuxiliaryProcess(void) MyProc->backendId = InvalidBackendId; MyProc->databaseId = InvalidOid; MyProc->roleId = InvalidOid; + MyProc->tempNamespaceId = InvalidOid; MyProc->isBackgroundWorker = IsBackgroundWorker; MyPgXact->delayChkpt = false; MyPgXact->vacuumFlags = 0; @@ -1170,8 +1205,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) /* * If we detected deadlock, give up without waiting. This must agree with - * CheckDeadLock's recovery code, except that we shouldn't release the - * semaphore since we haven't tried to lock it yet. + * CheckDeadLock's recovery code. */ if (early_deadlock) { @@ -1207,9 +1241,9 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) /* * Set timer so we can wake up after awhile and check for a deadlock. If a - * deadlock is detected, the handler releases the process's semaphore and - * sets MyProc->waitStatus = STATUS_ERROR, allowing us to know that we - * must report failure rather than success. + * deadlock is detected, the handler sets MyProc->waitStatus = + * STATUS_ERROR, allowing us to know that we must report failure rather + * than success. * * By delaying the check until we've waited for a bit, we can avoid * running the rather expensive deadlock-check code in most cases. @@ -1261,8 +1295,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) } else { - WaitLatch(MyLatch, WL_LATCH_SET, 0, - PG_WAIT_LOCK | locallock->tag.lock.locktag_type); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + PG_WAIT_LOCK | locallock->tag.lock.locktag_type); ResetLatch(MyLatch); /* check for deadlocks first, as that's probably log-worthy */ if (got_deadlock_timeout) @@ -1552,7 +1586,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable) /* - * ProcWakeup -- wake up a process by releasing its private semaphore. + * ProcWakeup -- wake up a process by setting its latch. * * Also remove the process from the wait queue and set its links invalid. * RETURN: the next process in the wait queue. @@ -1687,8 +1721,7 @@ CheckDeadLock(void) * we know that we don't have to wait anymore. * * We check by looking to see if we've been unlinked from the wait queue. - * This is quicker than checking our semaphore's state, since no kernel - * call is needed, and it is safe because we hold the lock partition lock. + * This is safe because we hold the lock partition lock. */ if (MyProc->links.prev == NULL || MyProc->links.next == NULL) @@ -1774,7 +1807,8 @@ CheckDeadLockAlert(void) void ProcWaitForSignal(uint32 wait_event_info) { - WaitLatch(MyLatch, WL_LATCH_SET, 0, wait_event_info); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + wait_event_info); ResetLatch(MyLatch); CHECK_FOR_INTERRUPTS(); } diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c index 7482b2d44be..2e6c55b14bb 100644 --- a/src/backend/storage/lmgr/s_lock.c +++ b/src/backend/storage/lmgr/s_lock.c @@ -36,7 +36,7 @@ * the probability of unintended failure) than to fix the total time * spent. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/lmgr/spin.c b/src/backend/storage/lmgr/spin.c index 6d59a7f15dd..d0c431b97d5 100644 --- a/src/backend/storage/lmgr/spin.c +++ b/src/backend/storage/lmgr/spin.c @@ -11,7 +11,7 @@ * is too slow to be very useful :-( * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index dfbda5458fd..6b49810e378 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -3,7 +3,7 @@ * bufpage.c * POSTGRES standard buffer page code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,7 @@ #include "access/htup_details.h" #include "access/itup.h" #include "access/xlog.h" +#include "pgstat.h" #include "storage/checksum.h" #include "utils/memdebug.h" #include "utils/memutils.h" @@ -64,7 +65,7 @@ PageInit(Page page, Size pageSize, Size specialSize) * Check that the page header and checksum (if any) appear valid. * * This is called when a page has just been read in from disk. The idea is - * to cheaply detect trashed pages before we go nuts following bogus item + * to cheaply detect trashed pages before we go nuts following bogus line * pointers, testing invalid transaction identifiers, etc. * * It turns out to be necessary to allow zeroed pages here too. Even though @@ -151,6 +152,8 @@ PageIsVerified(Page page, BlockNumber blkno) errmsg("page verification failed, calculated checksum %u but expected %u", checksum, p->pd_checksum))); + pgstat_report_checksum_failure(); + if (header_sane && ignore_checksum_failure) return true; } @@ -167,12 +170,12 @@ PageIsVerified(Page page, BlockNumber blkno) * reason. A WARNING is issued indicating the reason for the refusal. * * offsetNumber must be either InvalidOffsetNumber to specify finding a - * free item pointer, or a value between FirstOffsetNumber and one past - * the last existing item, to specify using that particular item pointer. + * free line pointer, or a value between FirstOffsetNumber and one past + * the last existing item, to specify using that particular line pointer. * * If offsetNumber is valid and flag PAI_OVERWRITE is set, we just store * the item at the specified offsetNumber, which must be either a - * currently-unused item pointer, or one past the last existing item. + * currently-unused line pointer, or one past the last existing item. * * If offsetNumber is valid and flag PAI_OVERWRITE is not set, insert * the item at the specified offsetNumber, moving existing items later @@ -311,7 +314,7 @@ PageAddItemExtended(Page page, memmove(itemId + 1, itemId, (limit - offsetNumber) * sizeof(ItemIdData)); - /* set the item pointer */ + /* set the line pointer */ ItemIdSetNormal(itemId, upper, size); /* @@ -526,7 +529,7 @@ PageRepairFragmentation(Page page) itemidptr->itemoff >= (int) pd_special)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: %u", + errmsg("corrupted line pointer: %u", itemidptr->itemoff))); itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp)); totallen += itemidptr->alignedlen; @@ -760,7 +763,7 @@ PageIndexTupleDelete(Page page, OffsetNumber offnum) offset != MAXALIGN(offset)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: offset = %u, size = %u", + errmsg("corrupted line pointer: offset = %u, size = %u", offset, (unsigned int) size))); /* Amount of space to actually be deleted */ @@ -878,7 +881,7 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) pd_lower, pd_upper, pd_special))); /* - * Scan the item pointer array and build a list of just the ones we are + * Scan the line pointer array and build a list of just the ones we are * going to keep. Notice we do not modify the page yet, since we are * still validity-checking. */ @@ -898,7 +901,7 @@ PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems) offset != MAXALIGN(offset)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: offset = %u, length = %u", + errmsg("corrupted line pointer: offset = %u, size = %u", offset, (unsigned int) size))); if (nextitm < nitems && offnum == itemnos[nextitm]) @@ -986,14 +989,14 @@ PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offnum) offset != MAXALIGN(offset)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: offset = %u, size = %u", + errmsg("corrupted line pointer: offset = %u, size = %u", offset, (unsigned int) size))); /* Amount of space to actually be deleted */ size = MAXALIGN(size); /* - * Either set the item pointer to "unused", or zap it if it's the last + * Either set the line pointer to "unused", or zap it if it's the last * one. (Note: it's possible that the next-to-last one(s) are already * unused, but we do not trouble to try to compact them out if so.) */ @@ -1051,7 +1054,7 @@ PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offnum) * other tuples' data up or down as needed to keep the page compacted. * This is better than deleting and reinserting the tuple, because it * avoids any data shifting when the tuple size doesn't change; and - * even when it does, we avoid moving the item pointers around. + * even when it does, we avoid moving the line pointers around. * Conceivably this could also be of use to an index AM that cares about * the physical order of tuples as well as their ItemId order. * @@ -1096,7 +1099,7 @@ PageIndexTupleOverwrite(Page page, OffsetNumber offnum, offset != MAXALIGN(offset)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: offset = %u, size = %u", + errmsg("corrupted line pointer: offset = %u, size = %u", offset, (unsigned int) oldsize))); /* diff --git a/src/backend/storage/page/checksum.c b/src/backend/storage/page/checksum.c index a28343b79e1..1eb7ef6ea51 100644 --- a/src/backend/storage/page/checksum.c +++ b/src/backend/storage/page/checksum.c @@ -3,7 +3,7 @@ * checksum.c * Checksum implementation for data pages. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/storage/page/itemptr.c b/src/backend/storage/page/itemptr.c index a899dac6453..1a51080f3a7 100644 --- a/src/backend/storage/page/itemptr.c +++ b/src/backend/storage/page/itemptr.c @@ -3,7 +3,7 @@ * itemptr.c * POSTGRES disk item pointer code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/storage/smgr/Makefile b/src/backend/storage/smgr/Makefile index 2b95cb0df16..e486b7c0d1c 100644 --- a/src/backend/storage/smgr/Makefile +++ b/src/backend/storage/smgr/Makefile @@ -12,6 +12,6 @@ subdir = src/backend/storage/smgr top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = md.o smgr.o smgrtype.o +OBJS = md.o smgr.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/smgr/README b/src/backend/storage/smgr/README index 37ed40b6450..e1cfc6cd264 100644 --- a/src/backend/storage/smgr/README +++ b/src/backend/storage/smgr/README @@ -31,12 +31,6 @@ The files in this directory, and their contents, are md.c The "magnetic disk" storage manager, which is really just an interface to the kernel's filesystem operations. - smgrtype.c Storage manager type -- maps string names to storage manager - IDs and provides simple comparison operators. This is the - regproc support for type "smgr" in the system catalogs. - (This is vestigial since no columns of type smgr exist - in the catalogs anymore.) - Note that md.c in turn relies on src/backend/storage/file/fd.c. diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 2ec103e6047..07f3c93d3fe 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -10,7 +10,7 @@ * It doesn't matter whether the bits are on spinning rust or some other * storage technology. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,47 +26,21 @@ #include #include "miscadmin.h" +#include "access/xlogutils.h" #include "access/xlog.h" +#include "commands/tablespace.h" #include "pgstat.h" -#include "portability/instr_time.h" #include "postmaster/bgwriter.h" #include "storage/fd.h" #include "storage/bufmgr.h" +#include "storage/md.h" #include "storage/relfilenode.h" #include "storage/smgr.h" +#include "storage/sync.h" #include "utils/hsearch.h" #include "utils/memutils.h" #include "pg_trace.h" - -/* intervals for calling AbsorbFsyncRequests in mdsync and mdpostckpt */ -#define FSYNCS_PER_ABSORB 10 -#define UNLINKS_PER_ABSORB 10 - -/* - * Special values for the segno arg to RememberFsyncRequest. - * - * Note that CompactCheckpointerRequestQueue assumes that it's OK to remove an - * fsync request from the queue if an identical, subsequent request is found. - * See comments there before making changes here. - */ -#define FORGET_RELATION_FSYNC (InvalidBlockNumber) -#define FORGET_DATABASE_FSYNC (InvalidBlockNumber-1) -#define UNLINK_RELATION_REQUEST (InvalidBlockNumber-2) - -/* - * On Windows, we have to interpret EACCES as possibly meaning the same as - * ENOENT, because if a file is unlinked-but-not-yet-gone on that platform, - * that's what you get. Ugh. This code is designed so that we don't - * actually believe these cases are okay without further evidence (namely, - * a pending fsync request getting canceled ... see mdsync). - */ -#ifndef WIN32 -#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT) -#else -#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT || (err) == EACCES) -#endif - /* * The magnetic disk storage manager keeps track of open file * descriptors in its own descriptor pool. This is done to make it @@ -114,49 +88,15 @@ typedef struct _MdfdVec static MemoryContext MdCxt; /* context for all MdfdVec objects */ -/* - * In some contexts (currently, standalone backends and the checkpointer) - * we keep track of pending fsync operations: we need to remember all relation - * segments that have been written since the last checkpoint, so that we can - * fsync them down to disk before completing the next checkpoint. This hash - * table remembers the pending operations. We use a hash table mostly as - * a convenient way of merging duplicate requests. - * - * We use a similar mechanism to remember no-longer-needed files that can - * be deleted after the next checkpoint, but we use a linked list instead of - * a hash table, because we don't expect there to be any duplicate requests. - * - * These mechanisms are only used for non-temp relations; we never fsync - * temp rels, nor do we need to postpone their deletion (see comments in - * mdunlink). - * - * (Regular backends do not track pending operations locally, but forward - * them to the checkpointer.) - */ -typedef uint16 CycleCtr; /* can be any convenient integer size */ - -typedef struct -{ - RelFileNode rnode; /* hash table key (must be first!) */ - CycleCtr cycle_ctr; /* mdsync_cycle_ctr of oldest request */ - /* requests[f] has bit n set if we need to fsync segment n of fork f */ - Bitmapset *requests[MAX_FORKNUM + 1]; - /* canceled[f] is true if we canceled fsyncs for fork "recently" */ - bool canceled[MAX_FORKNUM + 1]; -} PendingOperationEntry; - -typedef struct -{ - RelFileNode rnode; /* the dead relation to delete */ - CycleCtr cycle_ctr; /* mdckpt_cycle_ctr when request was made */ -} PendingUnlinkEntry; - -static HTAB *pendingOpsTable = NULL; -static List *pendingUnlinks = NIL; -static MemoryContext pendingOpsCxt; /* context for the above */ - -static CycleCtr mdsync_cycle_ctr = 0; -static CycleCtr mdckpt_cycle_ctr = 0; +/* Populate a file tag describing an md.c segment file. */ +#define INIT_MD_FILETAG(a,xx_rnode,xx_forknum,xx_segno) \ +( \ + memset(&(a), 0, sizeof(FileTag)), \ + (a).handler = SYNC_HANDLER_MD, \ + (a).rnode = (xx_rnode), \ + (a).forknum = (xx_forknum), \ + (a).segno = (xx_segno) \ +) /*** behavior for mdopen & _mdfd_getseg ***/ @@ -170,7 +110,7 @@ static CycleCtr mdckpt_cycle_ctr = 0; #define EXTENSION_CREATE_RECOVERY (1 << 3) /* * Allow opening segments which are preceded by segments smaller than - * RELSEG_SIZE, e.g. inactive segments (see above). Note that this is breaks + * RELSEG_SIZE, e.g. inactive segments (see above). Note that this breaks * mdnblocks() and related functionality henceforth - which currently is ok, * because this is only required in the checkpointer which never uses * mdnblocks(). @@ -180,22 +120,25 @@ static CycleCtr mdckpt_cycle_ctr = 0; /* local routines */ static void mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, - bool isRedo); -static MdfdVec *mdopen(SMgrRelation reln, ForkNumber forknum, int behavior); + bool isRedo); +static MdfdVec *mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior); static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum, - MdfdVec *seg); -static void register_unlink(RelFileNodeBackend rnode); + MdfdVec *seg); +static void register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum, + BlockNumber segno); +static void register_forget_request(RelFileNodeBackend rnode, ForkNumber forknum, + BlockNumber segno); static void _fdvec_resize(SMgrRelation reln, - ForkNumber forknum, - int nseg); + ForkNumber forknum, + int nseg); static char *_mdfd_segpath(SMgrRelation reln, ForkNumber forknum, - BlockNumber segno); + BlockNumber segno); static MdfdVec *_mdfd_openseg(SMgrRelation reln, ForkNumber forkno, - BlockNumber segno, int oflags); + BlockNumber segno, int oflags); static MdfdVec *_mdfd_getseg(SMgrRelation reln, ForkNumber forkno, - BlockNumber blkno, bool skipFsync, int behavior); + BlockNumber blkno, bool skipFsync, int behavior); static BlockNumber _mdnblocks(SMgrRelation reln, ForkNumber forknum, - MdfdVec *seg); + MdfdVec *seg); /* @@ -207,64 +150,6 @@ mdinit(void) MdCxt = AllocSetContextCreate(TopMemoryContext, "MdSmgr", ALLOCSET_DEFAULT_SIZES); - - /* - * Create pending-operations hashtable if we need it. Currently, we need - * it if we are standalone (not under a postmaster) or if we are a startup - * or checkpointer auxiliary process. - */ - if (!IsUnderPostmaster || AmStartupProcess() || AmCheckpointerProcess()) - { - HASHCTL hash_ctl; - - /* - * XXX: The checkpointer needs to add entries to the pending ops table - * when absorbing fsync requests. That is done within a critical - * section, which isn't usually allowed, but we make an exception. It - * means that there's a theoretical possibility that you run out of - * memory while absorbing fsync requests, which leads to a PANIC. - * Fortunately the hash table is small so that's unlikely to happen in - * practice. - */ - pendingOpsCxt = AllocSetContextCreate(MdCxt, - "Pending ops context", - ALLOCSET_DEFAULT_SIZES); - MemoryContextAllowInCriticalSection(pendingOpsCxt, true); - - MemSet(&hash_ctl, 0, sizeof(hash_ctl)); - hash_ctl.keysize = sizeof(RelFileNode); - hash_ctl.entrysize = sizeof(PendingOperationEntry); - hash_ctl.hcxt = pendingOpsCxt; - pendingOpsTable = hash_create("Pending Ops Table", - 100L, - &hash_ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); - pendingUnlinks = NIL; - } -} - -/* - * In archive recovery, we rely on checkpointer to do fsyncs, but we will have - * already created the pendingOpsTable during initialization of the startup - * process. Calling this function drops the local pendingOpsTable so that - * subsequent requests will be forwarded to checkpointer. - */ -void -SetForwardFsyncRequests(void) -{ - /* Perform any pending fsyncs we may have queued up, then drop table */ - if (pendingOpsTable) - { - mdsync(); - hash_destroy(pendingOpsTable); - } - pendingOpsTable = NULL; - - /* - * We should not have any pending unlink requests, since mdunlink doesn't - * queue unlink requests when isRedo. - */ - Assert(pendingUnlinks == NIL); } /* @@ -281,7 +166,7 @@ mdexists(SMgrRelation reln, ForkNumber forkNum) */ mdclose(reln, forkNum); - return (mdopen(reln, forkNum, EXTENSION_RETURN_NULL) != NULL); + return (mdopenfork(reln, forkNum, EXTENSION_RETURN_NULL) != NULL); } /* @@ -301,6 +186,19 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo) Assert(reln->md_num_open_segs[forkNum] == 0); + /* + * We may be using the target table space for the first time in this + * database, so create a per-database subdirectory if needed. + * + * XXX this is a fairly ugly violation of module layering, but this seems + * to be the best place to put the check. Maybe TablespaceCreateDbspace + * should be here and not in commands/tablespace.c? But that would imply + * importing a lot of stuff that smgr.c oughtn't know, either. + */ + TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode, + reln->smgr_rnode.node.dbNode, + isRedo); + path = relpath(reln->smgr_rnode, forkNum); fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY); @@ -309,13 +207,7 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo) { int save_errno = errno; - /* - * During bootstrap, there are cases where a system relation will be - * accessed (by internal backend processes) before the bootstrap - * script nominally creates it. Therefore, allow the file to exist - * already, even if isRedo is not set. (See also mdopen) - */ - if (isRedo || IsBootstrapProcessingMode()) + if (isRedo) fd = PathNameOpenFile(path, O_RDWR | PG_BINARY); if (fd < 0) { @@ -385,16 +277,6 @@ mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo) void mdunlink(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) { - /* - * We have to clean out any pending fsync requests for the doomed - * relation, else the next mdsync() will fail. There can't be any such - * requests for a temp relation, though. We can send just one request - * even when deleting multiple forks, since the fsync queuing code accepts - * the "InvalidForkNumber = all forks" convention. - */ - if (!RelFileNodeBackendIsTemp(rnode)) - ForgetRelationFsyncRequests(rnode.node, forkNum); - /* Now do the per-fork work */ if (forkNum == InvalidForkNumber) { @@ -418,6 +300,11 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) */ if (isRedo || forkNum != MAIN_FORKNUM || RelFileNodeBackendIsTemp(rnode)) { + /* First, forget any pending sync requests for the first segment */ + if (!RelFileNodeBackendIsTemp(rnode)) + register_forget_request(rnode, forkNum, 0 /* first seg */ ); + + /* Next unlink the file */ ret = unlink(path); if (ret < 0 && errno != ENOENT) ereport(WARNING, @@ -447,7 +334,7 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) errmsg("could not truncate file \"%s\": %m", path))); /* Register request to unlink first segment later */ - register_unlink(rnode); + register_unlink_segment(rnode, forkNum, 0 /* first seg */ ); } /* @@ -464,6 +351,13 @@ mdunlinkfork(RelFileNodeBackend rnode, ForkNumber forkNum, bool isRedo) */ for (segno = 1;; segno++) { + /* + * Forget any pending sync requests for this segment before we try + * to unlink. + */ + if (!RelFileNodeBackendIsTemp(rnode)) + register_forget_request(rnode, forkNum, segno); + sprintf(segpath, "%s.%u", path, segno); if (unlink(segpath) < 0) { @@ -521,22 +415,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); - /* - * Note: because caller usually obtained blocknum by calling mdnblocks, - * which did a seek(SEEK_END), this seek is often redundant and will be - * optimized away by fd.c. It's not redundant, however, if there is a - * partial page at the end of the file. In that case we want to try to - * overwrite the partial page with a full page. It's also not redundant - * if bufmgr.c had to dump another buffer of the same file to make room - * for the new page's buffer. - */ - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not seek to block %u in file \"%s\": %m", - blocknum, FilePathName(v->mdfd_vfd)))); - - if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ) + if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, seekpos, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ) { if (nbytes < 0) ereport(ERROR, @@ -560,7 +439,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, } /* - * mdopen() -- Open the specified relation. + * mdopenfork() -- Open one fork of the specified relation. * * Note we only open the first segment, when there are multiple segments. * @@ -570,7 +449,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, * invent one out of whole cloth. */ static MdfdVec * -mdopen(SMgrRelation reln, ForkNumber forknum, int behavior) +mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior) { MdfdVec *mdfd; char *path; @@ -586,26 +465,15 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior) if (fd < 0) { - /* - * During bootstrap, there are cases where a system relation will be - * accessed (by internal backend processes) before the bootstrap - * script nominally creates it. Therefore, accept mdopen() as a - * substitute for mdcreate() in bootstrap mode only. (See mdcreate) - */ - if (IsBootstrapProcessingMode()) - fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY); - if (fd < 0) + if ((behavior & EXTENSION_RETURN_NULL) && + FILE_POSSIBLY_DELETED(errno)) { - if ((behavior & EXTENSION_RETURN_NULL) && - FILE_POSSIBLY_DELETED(errno)) - { - pfree(path); - return NULL; - } - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", path))); + pfree(path); + return NULL; } + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", path))); } pfree(path); @@ -620,6 +488,17 @@ mdopen(SMgrRelation reln, ForkNumber forknum, int behavior) return mdfd; } +/* + * mdopen() -- Initialize newly-opened relation. + */ +void +mdopen(SMgrRelation reln) +{ + /* mark it not open */ + for (int forknum = 0; forknum <= MAX_FORKNUM; forknum++) + reln->md_num_open_segs[forknum] = 0; +} + /* * mdclose() -- Close the specified relation, if it isn't closed already. */ @@ -747,13 +626,7 @@ mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not seek to block %u in file \"%s\": %m", - blocknum, FilePathName(v->mdfd_vfd)))); - - nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_READ); + nbytes = FileRead(v->mdfd_vfd, buffer, BLCKSZ, seekpos, WAIT_EVENT_DATA_FILE_READ); TRACE_POSTGRESQL_SMGR_MD_READ_DONE(forknum, blocknum, reln->smgr_rnode.node.spcNode, @@ -823,13 +696,7 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE); - if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not seek to block %u in file \"%s\": %m", - blocknum, FilePathName(v->mdfd_vfd)))); - - nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_WRITE); + nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, seekpos, WAIT_EVENT_DATA_FILE_WRITE); TRACE_POSTGRESQL_SMGR_MD_WRITE_DONE(forknum, blocknum, reln->smgr_rnode.node.spcNode, @@ -864,14 +731,14 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, * mdnblocks() -- Get the number of blocks stored in a relation. * * Important side effect: all active segments of the relation are opened - * and added to the mdfd_seg_fds array. If this routine has not been + * and added to the md_seg_fds array. If this routine has not been * called, then only segments up to the last one actually touched * are present in the array. */ BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum) { - MdfdVec *v = mdopen(reln, forknum, EXTENSION_FAIL); + MdfdVec *v = mdopenfork(reln, forknum, EXTENSION_FAIL); BlockNumber nblocks; BlockNumber segno = 0; @@ -908,8 +775,8 @@ mdnblocks(SMgrRelation reln, ForkNumber forknum) segno++; /* - * We used to pass O_CREAT here, but that's has the disadvantage that - * it might create a segment which has vanished through some operating + * We used to pass O_CREAT here, but that has the disadvantage that it + * might create a segment which has vanished through some operating * system misadventure. In such a case, creating the segment here * undermines _mdfd_getseg's attempts to notice and report an error * upon access to a missing segment. @@ -1038,7 +905,7 @@ mdimmedsync(SMgrRelation reln, ForkNumber forknum) MdfdVec *v = &reln->md_seg_fds[forknum][segno - 1]; if (FileSync(v->mdfd_vfd, WAIT_EVENT_DATA_FILE_IMMEDIATE_SYNC) < 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", FilePathName(v->mdfd_vfd)))); @@ -1046,405 +913,32 @@ mdimmedsync(SMgrRelation reln, ForkNumber forknum) } } -/* - * mdsync() -- Sync previous writes to stable storage. - */ -void -mdsync(void) -{ - static bool mdsync_in_progress = false; - - HASH_SEQ_STATUS hstat; - PendingOperationEntry *entry; - int absorb_counter; - - /* Statistics on sync times */ - int processed = 0; - instr_time sync_start, - sync_end, - sync_diff; - uint64 elapsed; - uint64 longest = 0; - uint64 total_elapsed = 0; - - /* - * This is only called during checkpoints, and checkpoints should only - * occur in processes that have created a pendingOpsTable. - */ - if (!pendingOpsTable) - elog(ERROR, "cannot sync without a pendingOpsTable"); - - /* - * If we are in the checkpointer, the sync had better include all fsync - * requests that were queued by backends up to this point. The tightest - * race condition that could occur is that a buffer that must be written - * and fsync'd for the checkpoint could have been dumped by a backend just - * before it was visited by BufferSync(). We know the backend will have - * queued an fsync request before clearing the buffer's dirtybit, so we - * are safe as long as we do an Absorb after completing BufferSync(). - */ - AbsorbFsyncRequests(); - - /* - * To avoid excess fsync'ing (in the worst case, maybe a never-terminating - * checkpoint), we want to ignore fsync requests that are entered into the - * hashtable after this point --- they should be processed next time, - * instead. We use mdsync_cycle_ctr to tell old entries apart from new - * ones: new ones will have cycle_ctr equal to the incremented value of - * mdsync_cycle_ctr. - * - * In normal circumstances, all entries present in the table at this point - * will have cycle_ctr exactly equal to the current (about to be old) - * value of mdsync_cycle_ctr. However, if we fail partway through the - * fsync'ing loop, then older values of cycle_ctr might remain when we - * come back here to try again. Repeated checkpoint failures would - * eventually wrap the counter around to the point where an old entry - * might appear new, causing us to skip it, possibly allowing a checkpoint - * to succeed that should not have. To forestall wraparound, any time the - * previous mdsync() failed to complete, run through the table and - * forcibly set cycle_ctr = mdsync_cycle_ctr. - * - * Think not to merge this loop with the main loop, as the problem is - * exactly that that loop may fail before having visited all the entries. - * From a performance point of view it doesn't matter anyway, as this path - * will never be taken in a system that's functioning normally. - */ - if (mdsync_in_progress) - { - /* prior try failed, so update any stale cycle_ctr values */ - hash_seq_init(&hstat, pendingOpsTable); - while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL) - { - entry->cycle_ctr = mdsync_cycle_ctr; - } - } - - /* Advance counter so that new hashtable entries are distinguishable */ - mdsync_cycle_ctr++; - - /* Set flag to detect failure if we don't reach the end of the loop */ - mdsync_in_progress = true; - - /* Now scan the hashtable for fsync requests to process */ - absorb_counter = FSYNCS_PER_ABSORB; - hash_seq_init(&hstat, pendingOpsTable); - while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL) - { - ForkNumber forknum; - - /* - * If the entry is new then don't process it this time; it might - * contain multiple fsync-request bits, but they are all new. Note - * "continue" bypasses the hash-remove call at the bottom of the loop. - */ - if (entry->cycle_ctr == mdsync_cycle_ctr) - continue; - - /* Else assert we haven't missed it */ - Assert((CycleCtr) (entry->cycle_ctr + 1) == mdsync_cycle_ctr); - - /* - * Scan over the forks and segments represented by the entry. - * - * The bitmap manipulations are slightly tricky, because we can call - * AbsorbFsyncRequests() inside the loop and that could result in - * bms_add_member() modifying and even re-palloc'ing the bitmapsets. - * This is okay because we unlink each bitmapset from the hashtable - * entry before scanning it. That means that any incoming fsync - * requests will be processed now if they reach the table before we - * begin to scan their fork. - */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - { - Bitmapset *requests = entry->requests[forknum]; - int segno; - - entry->requests[forknum] = NULL; - entry->canceled[forknum] = false; - - while ((segno = bms_first_member(requests)) >= 0) - { - int failures; - - /* - * If fsync is off then we don't have to bother opening the - * file at all. (We delay checking until this point so that - * changing fsync on the fly behaves sensibly.) - */ - if (!enableFsync) - continue; - - /* - * If in checkpointer, we want to absorb pending requests - * every so often to prevent overflow of the fsync request - * queue. It is unspecified whether newly-added entries will - * be visited by hash_seq_search, but we don't care since we - * don't need to process them anyway. - */ - if (--absorb_counter <= 0) - { - AbsorbFsyncRequests(); - absorb_counter = FSYNCS_PER_ABSORB; - } - - /* - * The fsync table could contain requests to fsync segments - * that have been deleted (unlinked) by the time we get to - * them. Rather than just hoping an ENOENT (or EACCES on - * Windows) error can be ignored, what we do on error is - * absorb pending requests and then retry. Since mdunlink() - * queues a "cancel" message before actually unlinking, the - * fsync request is guaranteed to be marked canceled after the - * absorb if it really was this case. DROP DATABASE likewise - * has to tell us to forget fsync requests before it starts - * deletions. - */ - for (failures = 0;; failures++) /* loop exits at "break" */ - { - SMgrRelation reln; - MdfdVec *seg; - char *path; - int save_errno; - - /* - * Find or create an smgr hash entry for this relation. - * This may seem a bit unclean -- md calling smgr? But - * it's really the best solution. It ensures that the - * open file reference isn't permanently leaked if we get - * an error here. (You may say "but an unreferenced - * SMgrRelation is still a leak!" Not really, because the - * only case in which a checkpoint is done by a process - * that isn't about to shut down is in the checkpointer, - * and it will periodically do smgrcloseall(). This fact - * justifies our not closing the reln in the success path - * either, which is a good thing since in non-checkpointer - * cases we couldn't safely do that.) - */ - reln = smgropen(entry->rnode, InvalidBackendId); - - /* Attempt to open and fsync the target segment */ - seg = _mdfd_getseg(reln, forknum, - (BlockNumber) segno * (BlockNumber) RELSEG_SIZE, - false, - EXTENSION_RETURN_NULL - | EXTENSION_DONT_CHECK_SIZE); - - INSTR_TIME_SET_CURRENT(sync_start); - - if (seg != NULL && - FileSync(seg->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC) >= 0) - { - /* Success; update statistics about sync timing */ - INSTR_TIME_SET_CURRENT(sync_end); - sync_diff = sync_end; - INSTR_TIME_SUBTRACT(sync_diff, sync_start); - elapsed = INSTR_TIME_GET_MICROSEC(sync_diff); - if (elapsed > longest) - longest = elapsed; - total_elapsed += elapsed; - processed++; - if (log_checkpoints) - elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec", - processed, - FilePathName(seg->mdfd_vfd), - (double) elapsed / 1000); - - break; /* out of retry loop */ - } - - /* Compute file name for use in message */ - save_errno = errno; - path = _mdfd_segpath(reln, forknum, (BlockNumber) segno); - errno = save_errno; - - /* - * It is possible that the relation has been dropped or - * truncated since the fsync request was entered. - * Therefore, allow ENOENT, but only if we didn't fail - * already on this file. This applies both for - * _mdfd_getseg() and for FileSync, since fd.c might have - * closed the file behind our back. - * - * XXX is there any point in allowing more than one retry? - * Don't see one at the moment, but easy to change the - * test here if so. - */ - if (!FILE_POSSIBLY_DELETED(errno) || - failures > 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not fsync file \"%s\": %m", - path))); - else - ereport(DEBUG1, - (errcode_for_file_access(), - errmsg("could not fsync file \"%s\" but retrying: %m", - path))); - pfree(path); - - /* - * Absorb incoming requests and check to see if a cancel - * arrived for this relation fork. - */ - AbsorbFsyncRequests(); - absorb_counter = FSYNCS_PER_ABSORB; /* might as well... */ - - if (entry->canceled[forknum]) - break; - } /* end retry loop */ - } - bms_free(requests); - } - - /* - * We've finished everything that was requested before we started to - * scan the entry. If no new requests have been inserted meanwhile, - * remove the entry. Otherwise, update its cycle counter, as all the - * requests now in it must have arrived during this cycle. - */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - { - if (entry->requests[forknum] != NULL) - break; - } - if (forknum <= MAX_FORKNUM) - entry->cycle_ctr = mdsync_cycle_ctr; - else - { - /* Okay to remove it */ - if (hash_search(pendingOpsTable, &entry->rnode, - HASH_REMOVE, NULL) == NULL) - elog(ERROR, "pendingOpsTable corrupted"); - } - } /* end loop over hashtable entries */ - - /* Return sync performance metrics for report at checkpoint end */ - CheckpointStats.ckpt_sync_rels = processed; - CheckpointStats.ckpt_longest_sync = longest; - CheckpointStats.ckpt_agg_sync_time = total_elapsed; - - /* Flag successful completion of mdsync */ - mdsync_in_progress = false; -} - -/* - * mdpreckpt() -- Do pre-checkpoint work - * - * To distinguish unlink requests that arrived before this checkpoint - * started from those that arrived during the checkpoint, we use a cycle - * counter similar to the one we use for fsync requests. That cycle - * counter is incremented here. - * - * This must be called *before* the checkpoint REDO point is determined. - * That ensures that we won't delete files too soon. - * - * Note that we can't do anything here that depends on the assumption - * that the checkpoint will be completed. - */ -void -mdpreckpt(void) -{ - /* - * Any unlink requests arriving after this point will be assigned the next - * cycle counter, and won't be unlinked until next checkpoint. - */ - mdckpt_cycle_ctr++; -} - -/* - * mdpostckpt() -- Do post-checkpoint work - * - * Remove any lingering files that can now be safely removed. - */ -void -mdpostckpt(void) -{ - int absorb_counter; - - absorb_counter = UNLINKS_PER_ABSORB; - while (pendingUnlinks != NIL) - { - PendingUnlinkEntry *entry = (PendingUnlinkEntry *) linitial(pendingUnlinks); - char *path; - - /* - * New entries are appended to the end, so if the entry is new we've - * reached the end of old entries. - * - * Note: if just the right number of consecutive checkpoints fail, we - * could be fooled here by cycle_ctr wraparound. However, the only - * consequence is that we'd delay unlinking for one more checkpoint, - * which is perfectly tolerable. - */ - if (entry->cycle_ctr == mdckpt_cycle_ctr) - break; - - /* Unlink the file */ - path = relpathperm(entry->rnode, MAIN_FORKNUM); - if (unlink(path) < 0) - { - /* - * There's a race condition, when the database is dropped at the - * same time that we process the pending unlink requests. If the - * DROP DATABASE deletes the file before we do, we will get ENOENT - * here. rmtree() also has to ignore ENOENT errors, to deal with - * the possibility that we delete the file first. - */ - if (errno != ENOENT) - ereport(WARNING, - (errcode_for_file_access(), - errmsg("could not remove file \"%s\": %m", path))); - } - pfree(path); - - /* And remove the list entry */ - pendingUnlinks = list_delete_first(pendingUnlinks); - pfree(entry); - - /* - * As in mdsync, we don't want to stop absorbing fsync requests for a - * long time when there are many deletions to be done. We can safely - * call AbsorbFsyncRequests() at this point in the loop (note it might - * try to delete list entries). - */ - if (--absorb_counter <= 0) - { - AbsorbFsyncRequests(); - absorb_counter = UNLINKS_PER_ABSORB; - } - } -} - /* * register_dirty_segment() -- Mark a relation segment as needing fsync * * If there is a local pending-ops table, just make an entry in it for - * mdsync to process later. Otherwise, try to pass off the fsync request - * to the checkpointer process. If that fails, just do the fsync - * locally before returning (we hope this will not happen often enough - * to be a performance problem). + * ProcessSyncRequests to process later. Otherwise, try to pass off the + * fsync request to the checkpointer process. If that fails, just do the + * fsync locally before returning (we hope this will not happen often + * enough to be a performance problem). */ static void register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg) { + FileTag tag; + + INIT_MD_FILETAG(tag, reln->smgr_rnode.node, forknum, seg->mdfd_segno); + /* Temp relations should never be fsync'd */ Assert(!SmgrIsTemp(reln)); - if (pendingOpsTable) + if (!RegisterSyncRequest(&tag, SYNC_REQUEST, false /* retryOnError */ )) { - /* push it into local pending-ops table */ - RememberFsyncRequest(reln->smgr_rnode.node, forknum, seg->mdfd_segno); - } - else - { - if (ForwardFsyncRequest(reln->smgr_rnode.node, forknum, seg->mdfd_segno)) - return; /* passed it off successfully */ - ereport(DEBUG1, (errmsg("could not forward fsync request because request queue is full"))); if (FileSync(seg->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC) < 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), errmsg("could not fsync file \"%s\": %m", FilePathName(seg->mdfd_vfd)))); @@ -1452,255 +946,83 @@ register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg) } /* - * register_unlink() -- Schedule a file to be deleted after next checkpoint - * - * We don't bother passing in the fork number, because this is only used - * with main forks. - * - * As with register_dirty_segment, this could involve either a local or - * a remote pending-ops table. + * register_unlink_segment() -- Schedule a file to be deleted after next checkpoint */ static void -register_unlink(RelFileNodeBackend rnode) +register_unlink_segment(RelFileNodeBackend rnode, ForkNumber forknum, + BlockNumber segno) { + FileTag tag; + + INIT_MD_FILETAG(tag, rnode.node, forknum, segno); + /* Should never be used with temp relations */ Assert(!RelFileNodeBackendIsTemp(rnode)); - if (pendingOpsTable) - { - /* push it into local pending-ops table */ - RememberFsyncRequest(rnode.node, MAIN_FORKNUM, - UNLINK_RELATION_REQUEST); - } - else - { - /* - * Notify the checkpointer about it. If we fail to queue the request - * message, we have to sleep and try again, because we can't simply - * delete the file now. Ugly, but hopefully won't happen often. - * - * XXX should we just leave the file orphaned instead? - */ - Assert(IsUnderPostmaster); - while (!ForwardFsyncRequest(rnode.node, MAIN_FORKNUM, - UNLINK_RELATION_REQUEST)) - pg_usleep(10000L); /* 10 msec seems a good number */ - } + RegisterSyncRequest(&tag, SYNC_UNLINK_REQUEST, true /* retryOnError */ ); } /* - * RememberFsyncRequest() -- callback from checkpointer side of fsync request - * - * We stuff fsync requests into the local hash table for execution - * during the checkpointer's next checkpoint. UNLINK requests go into a - * separate linked list, however, because they get processed separately. - * - * The range of possible segment numbers is way less than the range of - * BlockNumber, so we can reserve high values of segno for special purposes. - * We define three: - * - FORGET_RELATION_FSYNC means to cancel pending fsyncs for a relation, - * either for one fork, or all forks if forknum is InvalidForkNumber - * - FORGET_DATABASE_FSYNC means to cancel pending fsyncs for a whole database - * - UNLINK_RELATION_REQUEST is a request to delete the file after the next - * checkpoint. - * Note also that we're assuming real segment numbers don't exceed INT_MAX. - * - * (Handling FORGET_DATABASE_FSYNC requests is a tad slow because the hash - * table has to be searched linearly, but dropping a database is a pretty - * heavyweight operation anyhow, so we'll live with it.) + * register_forget_request() -- forget any fsyncs for a relation fork's segment */ -void -RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno) +static void +register_forget_request(RelFileNodeBackend rnode, ForkNumber forknum, + BlockNumber segno) { - Assert(pendingOpsTable); - - if (segno == FORGET_RELATION_FSYNC) - { - /* Remove any pending requests for the relation (one or all forks) */ - PendingOperationEntry *entry; - - entry = (PendingOperationEntry *) hash_search(pendingOpsTable, - &rnode, - HASH_FIND, - NULL); - if (entry) - { - /* - * We can't just delete the entry since mdsync could have an - * active hashtable scan. Instead we delete the bitmapsets; this - * is safe because of the way mdsync is coded. We also set the - * "canceled" flags so that mdsync can tell that a cancel arrived - * for the fork(s). - */ - if (forknum == InvalidForkNumber) - { - /* remove requests for all forks */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - { - bms_free(entry->requests[forknum]); - entry->requests[forknum] = NULL; - entry->canceled[forknum] = true; - } - } - else - { - /* remove requests for single fork */ - bms_free(entry->requests[forknum]); - entry->requests[forknum] = NULL; - entry->canceled[forknum] = true; - } - } - } - else if (segno == FORGET_DATABASE_FSYNC) - { - /* Remove any pending requests for the entire database */ - HASH_SEQ_STATUS hstat; - PendingOperationEntry *entry; - ListCell *cell, - *prev, - *next; - - /* Remove fsync requests */ - hash_seq_init(&hstat, pendingOpsTable); - while ((entry = (PendingOperationEntry *) hash_seq_search(&hstat)) != NULL) - { - if (entry->rnode.dbNode == rnode.dbNode) - { - /* remove requests for all forks */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - { - bms_free(entry->requests[forknum]); - entry->requests[forknum] = NULL; - entry->canceled[forknum] = true; - } - } - } - - /* Remove unlink requests */ - prev = NULL; - for (cell = list_head(pendingUnlinks); cell; cell = next) - { - PendingUnlinkEntry *entry = (PendingUnlinkEntry *) lfirst(cell); - - next = lnext(cell); - if (entry->rnode.dbNode == rnode.dbNode) - { - pendingUnlinks = list_delete_cell(pendingUnlinks, cell, prev); - pfree(entry); - } - else - prev = cell; - } - } - else if (segno == UNLINK_RELATION_REQUEST) - { - /* Unlink request: put it in the linked list */ - MemoryContext oldcxt = MemoryContextSwitchTo(pendingOpsCxt); - PendingUnlinkEntry *entry; - - /* PendingUnlinkEntry doesn't store forknum, since it's always MAIN */ - Assert(forknum == MAIN_FORKNUM); + FileTag tag; - entry = palloc(sizeof(PendingUnlinkEntry)); - entry->rnode = rnode; - entry->cycle_ctr = mdckpt_cycle_ctr; + INIT_MD_FILETAG(tag, rnode.node, forknum, segno); - pendingUnlinks = lappend(pendingUnlinks, entry); - - MemoryContextSwitchTo(oldcxt); - } - else - { - /* Normal case: enter a request to fsync this segment */ - MemoryContext oldcxt = MemoryContextSwitchTo(pendingOpsCxt); - PendingOperationEntry *entry; - bool found; - - entry = (PendingOperationEntry *) hash_search(pendingOpsTable, - &rnode, - HASH_ENTER, - &found); - /* if new entry, initialize it */ - if (!found) - { - entry->cycle_ctr = mdsync_cycle_ctr; - MemSet(entry->requests, 0, sizeof(entry->requests)); - MemSet(entry->canceled, 0, sizeof(entry->canceled)); - } - - /* - * NB: it's intentional that we don't change cycle_ctr if the entry - * already exists. The cycle_ctr must represent the oldest fsync - * request that could be in the entry. - */ - - entry->requests[forknum] = bms_add_member(entry->requests[forknum], - (int) segno); - - MemoryContextSwitchTo(oldcxt); - } + RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true /* retryOnError */ ); } /* - * ForgetRelationFsyncRequests -- forget any fsyncs for a relation fork - * - * forknum == InvalidForkNumber means all forks, although this code doesn't - * actually know that, since it's just forwarding the request elsewhere. + * ForgetDatabaseSyncRequests -- forget any fsyncs and unlinks for a DB */ void -ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum) +ForgetDatabaseSyncRequests(Oid dbid) { - if (pendingOpsTable) - { - /* standalone backend or startup process: fsync state is local */ - RememberFsyncRequest(rnode, forknum, FORGET_RELATION_FSYNC); - } - else if (IsUnderPostmaster) - { - /* - * Notify the checkpointer about it. If we fail to queue the cancel - * message, we have to sleep and try again ... ugly, but hopefully - * won't happen often. - * - * XXX should we CHECK_FOR_INTERRUPTS in this loop? Escaping with an - * error would leave the no-longer-used file still present on disk, - * which would be bad, so I'm inclined to assume that the checkpointer - * will always empty the queue soon. - */ - while (!ForwardFsyncRequest(rnode, forknum, FORGET_RELATION_FSYNC)) - pg_usleep(10000L); /* 10 msec seems a good number */ + FileTag tag; + RelFileNode rnode; - /* - * Note we don't wait for the checkpointer to actually absorb the - * cancel message; see mdsync() for the implications. - */ - } + rnode.dbNode = dbid; + rnode.spcNode = 0; + rnode.relNode = 0; + + INIT_MD_FILETAG(tag, rnode, InvalidForkNumber, InvalidBlockNumber); + + RegisterSyncRequest(&tag, SYNC_FILTER_REQUEST, true /* retryOnError */ ); } /* - * ForgetDatabaseFsyncRequests -- forget any fsyncs and unlinks for a DB + * DropRelationFiles -- drop files of all given relations */ void -ForgetDatabaseFsyncRequests(Oid dbid) +DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo) { - RelFileNode rnode; - - rnode.dbNode = dbid; - rnode.spcNode = 0; - rnode.relNode = 0; + SMgrRelation *srels; + int i; - if (pendingOpsTable) + srels = palloc(sizeof(SMgrRelation) * ndelrels); + for (i = 0; i < ndelrels; i++) { - /* standalone backend or startup process: fsync state is local */ - RememberFsyncRequest(rnode, InvalidForkNumber, FORGET_DATABASE_FSYNC); - } - else if (IsUnderPostmaster) - { - /* see notes in ForgetRelationFsyncRequests */ - while (!ForwardFsyncRequest(rnode, InvalidForkNumber, - FORGET_DATABASE_FSYNC)) - pg_usleep(10000L); /* 10 msec seems a good number */ + SMgrRelation srel = smgropen(delrels[i], InvalidBackendId); + + if (isRedo) + { + ForkNumber fork; + + for (fork = 0; fork <= MAX_FORKNUM; fork++) + XLogDropRelation(delrels[i], fork); + } + srels[i] = srel; } + + smgrdounlinkall(srels, ndelrels, isRedo); + + for (i = 0; i < ndelrels; i++) + smgrclose(srels[i]); + pfree(srels); } @@ -1840,7 +1162,7 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno, v = &reln->md_seg_fds[forknum][reln->md_num_open_segs[forknum] - 1]; else { - v = mdopen(reln, forknum, behavior); + v = mdopenfork(reln, forknum, behavior); if (!v) return NULL; /* if behavior & EXTENSION_RETURN_NULL */ } @@ -1866,9 +1188,6 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno, * replaying WAL data that has a write into a high-numbered * segment of a relation that was later deleted. We want to go * ahead and create the segments so we can finish out the replay. - * However if the caller has specified - * EXTENSION_REALLY_RETURN_NULL, then extension is not desired - * even in recovery; we won't reach this point in that case. * * We have to maintain the invariant that segments before the last * active segment are of size RELSEG_SIZE; therefore, if @@ -1941,7 +1260,7 @@ _mdnblocks(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg) { off_t len; - len = FileSeek(seg->mdfd_vfd, 0L, SEEK_END); + len = FileSize(seg->mdfd_vfd); if (len < 0) ereport(ERROR, (errcode_for_file_access(), @@ -1950,3 +1269,71 @@ _mdnblocks(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg) /* note that this calculation will ignore any partial block at EOF */ return (BlockNumber) (len / BLCKSZ); } + +/* + * Sync a file to disk, given a file tag. Write the path into an output + * buffer so the caller can use it in error messages. + * + * Return 0 on success, -1 on failure, with errno set. + */ +int +mdsyncfiletag(const FileTag *ftag, char *path) +{ + SMgrRelation reln = smgropen(ftag->rnode, InvalidBackendId); + MdfdVec *v; + char *p; + + /* Provide the path for informational messages. */ + p = _mdfd_segpath(reln, ftag->forknum, ftag->segno); + strlcpy(path, p, MAXPGPATH); + pfree(p); + + /* Try to open the requested segment. */ + v = _mdfd_getseg(reln, + ftag->forknum, + ftag->segno * (BlockNumber) RELSEG_SIZE, + false, + EXTENSION_RETURN_NULL | EXTENSION_DONT_CHECK_SIZE); + if (v == NULL) + return -1; + + /* Try to fsync the file. */ + return FileSync(v->mdfd_vfd, WAIT_EVENT_DATA_FILE_SYNC); +} + +/* + * Unlink a file, given a file tag. Write the path into an output + * buffer so the caller can use it in error messages. + * + * Return 0 on success, -1 on failure, with errno set. + */ +int +mdunlinkfiletag(const FileTag *ftag, char *path) +{ + char *p; + + /* Compute the path. */ + p = relpathperm(ftag->rnode, MAIN_FORKNUM); + strlcpy(path, p, MAXPGPATH); + pfree(p); + + /* Try to unlink the file. */ + return unlink(path); +} + +/* + * Check if a given candidate request matches a given tag, when processing + * a SYNC_FILTER_REQUEST request. This will be called for all pending + * requests to find out whether to forget them. + */ +bool +mdfiletagmatches(const FileTag *ftag, const FileTag *candidate) +{ + /* + * For now we only use filter requests as a way to drop all scheduled + * callbacks relating to a given database, when dropping the database. + * We'll return true for all candidates that have the same database OID as + * the ftag from the SYNC_FILTER_REQUEST request, so they're forgotten. + */ + return ftag->rnode.dbNode == candidate->rnode.dbNode; +} diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c index 08f06bade25..b50c69b438c 100644 --- a/src/backend/storage/smgr/smgr.c +++ b/src/backend/storage/smgr/smgr.c @@ -6,7 +6,7 @@ * All file system operations in POSTGRES dispatch through these * routines. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,9 +17,10 @@ */ #include "postgres.h" -#include "commands/tablespace.h" +#include "lib/ilist.h" #include "storage/bufmgr.h" #include "storage/ipc.h" +#include "storage/md.h" #include "storage/smgr.h" #include "utils/hsearch.h" #include "utils/inval.h" @@ -39,6 +40,7 @@ typedef struct f_smgr { void (*smgr_init) (void); /* may be NULL */ void (*smgr_shutdown) (void); /* may be NULL */ + void (*smgr_open) (SMgrRelation reln); void (*smgr_close) (SMgrRelation reln, ForkNumber forknum); void (*smgr_create) (SMgrRelation reln, ForkNumber forknum, bool isRedo); @@ -59,35 +61,41 @@ typedef struct f_smgr void (*smgr_truncate) (SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks); void (*smgr_immedsync) (SMgrRelation reln, ForkNumber forknum); - void (*smgr_pre_ckpt) (void); /* may be NULL */ - void (*smgr_sync) (void); /* may be NULL */ - void (*smgr_post_ckpt) (void); /* may be NULL */ } f_smgr; - static const f_smgr smgrsw[] = { /* magnetic disk */ - {mdinit, NULL, mdclose, mdcreate, mdexists, mdunlink, mdextend, - mdprefetch, mdread, mdwrite, mdwriteback, mdnblocks, mdtruncate, - mdimmedsync, mdpreckpt, mdsync, mdpostckpt + { + .smgr_init = mdinit, + .smgr_shutdown = NULL, + .smgr_open = mdopen, + .smgr_close = mdclose, + .smgr_create = mdcreate, + .smgr_exists = mdexists, + .smgr_unlink = mdunlink, + .smgr_extend = mdextend, + .smgr_prefetch = mdprefetch, + .smgr_read = mdread, + .smgr_write = mdwrite, + .smgr_writeback = mdwriteback, + .smgr_nblocks = mdnblocks, + .smgr_truncate = mdtruncate, + .smgr_immedsync = mdimmedsync, } }; static const int NSmgr = lengthof(smgrsw); - /* * Each backend has a hashtable that stores all extant SMgrRelation objects. * In addition, "unowned" SMgrRelation objects are chained together in a list. */ static HTAB *SMgrRelationHash = NULL; -static SMgrRelation first_unowned_reln = NULL; +static dlist_head unowned_relns; /* local function prototypes */ static void smgrshutdown(int code, Datum arg); -static void add_to_unowned_list(SMgrRelation reln); -static void remove_from_unowned_list(SMgrRelation reln); /* @@ -150,7 +158,7 @@ smgropen(RelFileNode rnode, BackendId backend) ctl.entrysize = sizeof(SMgrRelationData); SMgrRelationHash = hash_create("smgr relation table", 400, &ctl, HASH_ELEM | HASH_BLOBS); - first_unowned_reln = NULL; + dlist_init(&unowned_relns); } /* Look up or create an entry */ @@ -163,8 +171,6 @@ smgropen(RelFileNode rnode, BackendId backend) /* Initialize it if not present before */ if (!found) { - int forknum; - /* hash_search already filled in the lookup key */ reln->smgr_owner = NULL; reln->smgr_targblock = InvalidBlockNumber; @@ -172,12 +178,11 @@ smgropen(RelFileNode rnode, BackendId backend) reln->smgr_vm_nblocks = InvalidBlockNumber; reln->smgr_which = 0; /* we only have md.c at present */ - /* mark it not open */ - for (forknum = 0; forknum <= MAX_FORKNUM; forknum++) - reln->md_num_open_segs[forknum] = 0; + /* implementation-specific initialization */ + smgrsw[reln->smgr_which].smgr_open(reln); /* it has no owner yet */ - add_to_unowned_list(reln); + dlist_push_tail(&unowned_relns, &reln->node); } return reln; @@ -207,7 +212,7 @@ smgrsetowner(SMgrRelation *owner, SMgrRelation reln) if (reln->smgr_owner) *(reln->smgr_owner) = NULL; else - remove_from_unowned_list(reln); + dlist_delete(&reln->node); /* Now establish the ownership relationship. */ reln->smgr_owner = owner; @@ -231,53 +236,8 @@ smgrclearowner(SMgrRelation *owner, SMgrRelation reln) /* unset our reference to the owner */ reln->smgr_owner = NULL; - add_to_unowned_list(reln); -} - -/* - * add_to_unowned_list -- link an SMgrRelation onto the unowned list - * - * Check remove_from_unowned_list()'s comments for performance - * considerations. - */ -static void -add_to_unowned_list(SMgrRelation reln) -{ - /* place it at head of the list (to make smgrsetowner cheap) */ - reln->next_unowned_reln = first_unowned_reln; - first_unowned_reln = reln; -} - -/* - * remove_from_unowned_list -- unlink an SMgrRelation from the unowned list - * - * If the reln is not present in the list, nothing happens. Typically this - * would be caller error, but there seems no reason to throw an error. - * - * In the worst case this could be rather slow; but in all the cases that seem - * likely to be performance-critical, the reln being sought will actually be - * first in the list. Furthermore, the number of unowned relns touched in any - * one transaction shouldn't be all that high typically. So it doesn't seem - * worth expending the additional space and management logic needed for a - * doubly-linked list. - */ -static void -remove_from_unowned_list(SMgrRelation reln) -{ - SMgrRelation *link; - SMgrRelation cur; - - for (link = &first_unowned_reln, cur = *link; - cur != NULL; - link = &cur->next_unowned_reln, cur = *link) - { - if (cur == reln) - { - *link = cur->next_unowned_reln; - cur->next_unowned_reln = NULL; - break; - } - } + /* add to list of unowned relations */ + dlist_push_tail(&unowned_relns, &reln->node); } /* @@ -304,7 +264,7 @@ smgrclose(SMgrRelation reln) owner = reln->smgr_owner; if (!owner) - remove_from_unowned_list(reln); + dlist_delete(&reln->node); if (hash_search(SMgrRelationHash, (void *) &(reln->smgr_rnode), @@ -368,33 +328,10 @@ smgrclosenode(RelFileNodeBackend rnode) * Given an already-created (but presumably unused) SMgrRelation, * cause the underlying disk file or other storage for the fork * to be created. - * - * If isRedo is true, it is okay for the underlying file to exist - * already because we are in a WAL replay sequence. */ void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) { - /* - * Exit quickly in WAL replay mode if we've already opened the file. If - * it's open, it surely must exist. - */ - if (isRedo && reln->md_num_open_segs[forknum] > 0) - return; - - /* - * We may be using the target table space for the first time in this - * database, so create a per-database subdirectory if needed. - * - * XXX this is a fairly ugly violation of module layering, but this seems - * to be the best place to put the check. Maybe TablespaceCreateDbspace - * should be here and not in commands/tablespace.c? But that would imply - * importing a lot of stuff that smgr.c oughtn't know, either. - */ - TablespaceCreateDbspace(reln->smgr_rnode.node.spcNode, - reln->smgr_rnode.node.dbNode, - isRedo); - smgrsw[reln->smgr_which].smgr_create(reln, forknum, isRedo); } @@ -406,9 +343,6 @@ smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) * * If isRedo is true, it is okay for the underlying file(s) to be gone * already. - * - * This is equivalent to calling smgrdounlinkfork for each fork, but - * it's significantly quicker so should be preferred when possible. */ void smgrdounlink(SMgrRelation reln, bool isRedo) @@ -535,57 +469,6 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) pfree(rnodes); } -/* - * smgrdounlinkfork() -- Immediately unlink one fork of a relation. - * - * The specified fork of the relation is removed from the store. This - * should not be used during transactional operations, since it can't be - * undone. - * - * If isRedo is true, it is okay for the underlying file to be gone - * already. - */ -void -smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo) -{ - RelFileNodeBackend rnode = reln->smgr_rnode; - int which = reln->smgr_which; - - /* Close the fork at smgr level */ - smgrsw[which].smgr_close(reln, forknum); - - /* - * Get rid of any remaining buffers for the fork. bufmgr will just drop - * them without bothering to write the contents. - */ - DropRelFileNodeBuffers(rnode, forknum, 0); - - /* - * It'd be nice to tell the stats collector to forget it immediately, too. - * But we can't because we don't know the OID (and in cases involving - * relfilenode swaps, it's not always clear which table OID to forget, - * anyway). - */ - - /* - * Send a shared-inval message to force other backends to close any - * dangling smgr references they may have for this rel. We should do this - * before starting the actual unlinking, in case we fail partway through - * that step. Note that the sinval message will eventually come back to - * this backend, too, and thereby provide a backstop that we closed our - * own smgr rel. - */ - CacheInvalidateSmgr(rnode); - - /* - * Delete the physical file(s). - * - * Note: smgr_unlink must treat deletion failure as a WARNING, not an - * ERROR, because we've already decided to commit or abort the current - * xact. - */ - smgrsw[which].smgr_unlink(rnode, forknum, isRedo); -} /* * smgrextend() -- Add a new block to a file. @@ -675,19 +558,25 @@ smgrnblocks(SMgrRelation reln, ForkNumber forknum) } /* - * smgrtruncate() -- Truncate supplied relation to the specified number - * of blocks + * smgrtruncate() -- Truncate the given forks of supplied relation to + * each specified numbers of blocks * * The truncation is done immediately, so this can't be rolled back. + * + * The caller must hold AccessExclusiveLock on the relation, to ensure that + * other backends receive the smgr invalidation event that this function sends + * before they access any forks of the relation again. */ void -smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) +smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nblocks) { + int i; + /* * Get rid of any buffers for the about-to-be-deleted blocks. bufmgr will * just drop them without bothering to write the contents. */ - DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nblocks); + DropRelFileNodeBuffers(reln->smgr_rnode, forknum, nforks, nblocks); /* * Send a shared-inval message to force other backends to close any smgr @@ -701,10 +590,24 @@ smgrtruncate(SMgrRelation reln, ForkNumber forknum, BlockNumber nblocks) */ CacheInvalidateSmgr(reln->smgr_rnode); - /* - * Do the truncation. - */ - smgrsw[reln->smgr_which].smgr_truncate(reln, forknum, nblocks); + /* Do the truncation */ + for (i = 0; i < nforks; i++) + { + smgrsw[reln->smgr_which].smgr_truncate(reln, forknum[i], nblocks[i]); + + /* + * We might as well update the local smgr_fsm_nblocks and + * smgr_vm_nblocks settings. The smgr cache inval message that + * this function sent will cause other backends to invalidate + * their copies of smgr_fsm_nblocks and smgr_vm_nblocks, + * and these ones too at the next command boundary. + * But these ensure they aren't outright wrong until then. + */ + if (forknum[i] == FSM_FORKNUM) + reln->smgr_fsm_nblocks = nblocks[i]; + if (forknum[i] == VISIBILITYMAP_FORKNUM) + reln->smgr_vm_nblocks = nblocks[i]; + } } /* @@ -736,52 +639,6 @@ smgrimmedsync(SMgrRelation reln, ForkNumber forknum) smgrsw[reln->smgr_which].smgr_immedsync(reln, forknum); } - -/* - * smgrpreckpt() -- Prepare for checkpoint. - */ -void -smgrpreckpt(void) -{ - int i; - - for (i = 0; i < NSmgr; i++) - { - if (smgrsw[i].smgr_pre_ckpt) - smgrsw[i].smgr_pre_ckpt(); - } -} - -/* - * smgrsync() -- Sync files to disk during checkpoint. - */ -void -smgrsync(void) -{ - int i; - - for (i = 0; i < NSmgr; i++) - { - if (smgrsw[i].smgr_sync) - smgrsw[i].smgr_sync(); - } -} - -/* - * smgrpostckpt() -- Post-checkpoint cleanup. - */ -void -smgrpostckpt(void) -{ - int i; - - for (i = 0; i < NSmgr; i++) - { - if (smgrsw[i].smgr_post_ckpt) - smgrsw[i].smgr_post_ckpt(); - } -} - /* * AtEOXact_SMgr * @@ -797,13 +654,19 @@ smgrpostckpt(void) void AtEOXact_SMgr(void) { + dlist_mutable_iter iter; + /* * Zap all unowned SMgrRelations. We rely on smgrclose() to remove each * one from the list. */ - while (first_unowned_reln != NULL) + dlist_foreach_modify(iter, &unowned_relns) { - Assert(first_unowned_reln->smgr_owner == NULL); - smgrclose(first_unowned_reln); + SMgrRelation rel = dlist_container(SMgrRelationData, node, + iter.cur); + + Assert(rel->smgr_owner == NULL); + + smgrclose(rel); } } diff --git a/src/backend/storage/smgr/smgrtype.c b/src/backend/storage/smgr/smgrtype.c deleted file mode 100644 index e819f2e514f..00000000000 --- a/src/backend/storage/smgr/smgrtype.c +++ /dev/null @@ -1,80 +0,0 @@ -/*------------------------------------------------------------------------- - * - * smgrtype.c - * storage manager type - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/storage/smgr/smgrtype.c - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "storage/smgr.h" -#include "utils/builtins.h" - - -typedef struct smgrid -{ - const char *smgr_name; -} smgrid; - -/* - * StorageManager[] -- List of defined storage managers. - */ -static const smgrid StorageManager[] = { - {"magnetic disk"} -}; - -static const int NStorageManagers = lengthof(StorageManager); - - -Datum -smgrin(PG_FUNCTION_ARGS) -{ - char *s = PG_GETARG_CSTRING(0); - int16 i; - - for (i = 0; i < NStorageManagers; i++) - { - if (strcmp(s, StorageManager[i].smgr_name) == 0) - PG_RETURN_INT16(i); - } - elog(ERROR, "unrecognized storage manager name \"%s\"", s); - PG_RETURN_INT16(0); -} - -Datum -smgrout(PG_FUNCTION_ARGS) -{ - int16 i = PG_GETARG_INT16(0); - char *s; - - if (i >= NStorageManagers || i < 0) - elog(ERROR, "invalid storage manager ID: %d", i); - - s = pstrdup(StorageManager[i].smgr_name); - PG_RETURN_CSTRING(s); -} - -Datum -smgreq(PG_FUNCTION_ARGS) -{ - int16 a = PG_GETARG_INT16(0); - int16 b = PG_GETARG_INT16(1); - - PG_RETURN_BOOL(a == b); -} - -Datum -smgrne(PG_FUNCTION_ARGS) -{ - int16 a = PG_GETARG_INT16(0); - int16 b = PG_GETARG_INT16(1); - - PG_RETURN_BOOL(a != b); -} diff --git a/src/backend/storage/sync/Makefile b/src/backend/storage/sync/Makefile new file mode 100644 index 00000000000..cfc60cadb4c --- /dev/null +++ b/src/backend/storage/sync/Makefile @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for storage/sync +# +# IDENTIFICATION +# src/backend/storage/sync/Makefile +# +#------------------------------------------------------------------------- + +subdir = src/backend/storage/sync +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global + +OBJS = sync.o + +include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c new file mode 100644 index 00000000000..f329c3fd667 --- /dev/null +++ b/src/backend/storage/sync/sync.c @@ -0,0 +1,592 @@ +/*------------------------------------------------------------------------- + * + * sync.c + * File synchronization management code. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/storage/sync/sync.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include +#include +#include + +#include "miscadmin.h" +#include "pgstat.h" +#include "access/xlogutils.h" +#include "access/xlog.h" +#include "commands/tablespace.h" +#include "portability/instr_time.h" +#include "postmaster/bgwriter.h" +#include "storage/bufmgr.h" +#include "storage/ipc.h" +#include "storage/md.h" +#include "utils/hsearch.h" +#include "utils/memutils.h" +#include "utils/inval.h" + +static MemoryContext pendingOpsCxt; /* context for the pending ops state */ + +/* + * In some contexts (currently, standalone backends and the checkpointer) + * we keep track of pending fsync operations: we need to remember all relation + * segments that have been written since the last checkpoint, so that we can + * fsync them down to disk before completing the next checkpoint. This hash + * table remembers the pending operations. We use a hash table mostly as + * a convenient way of merging duplicate requests. + * + * We use a similar mechanism to remember no-longer-needed files that can + * be deleted after the next checkpoint, but we use a linked list instead of + * a hash table, because we don't expect there to be any duplicate requests. + * + * These mechanisms are only used for non-temp relations; we never fsync + * temp rels, nor do we need to postpone their deletion (see comments in + * mdunlink). + * + * (Regular backends do not track pending operations locally, but forward + * them to the checkpointer.) + */ +typedef uint16 CycleCtr; /* can be any convenient integer size */ + +typedef struct +{ + FileTag tag; /* identifies handler and file */ + CycleCtr cycle_ctr; /* sync_cycle_ctr of oldest request */ + bool canceled; /* canceled is true if we canceled "recently" */ +} PendingFsyncEntry; + +typedef struct +{ + FileTag tag; /* identifies handler and file */ + CycleCtr cycle_ctr; /* checkpoint_cycle_ctr when request was made */ +} PendingUnlinkEntry; + +static HTAB *pendingOps = NULL; +static List *pendingUnlinks = NIL; +static MemoryContext pendingOpsCxt; /* context for the above */ + +static CycleCtr sync_cycle_ctr = 0; +static CycleCtr checkpoint_cycle_ctr = 0; + +/* Intervals for calling AbsorbSyncRequests */ +#define FSYNCS_PER_ABSORB 10 +#define UNLINKS_PER_ABSORB 10 + +/* + * Function pointers for handling sync and unlink requests. + */ +typedef struct SyncOps +{ + int (*sync_syncfiletag) (const FileTag *ftag, char *path); + int (*sync_unlinkfiletag) (const FileTag *ftag, char *path); + bool (*sync_filetagmatches) (const FileTag *ftag, + const FileTag *candidate); +} SyncOps; + +static const SyncOps syncsw[] = { + /* magnetic disk */ + { + .sync_syncfiletag = mdsyncfiletag, + .sync_unlinkfiletag = mdunlinkfiletag, + .sync_filetagmatches = mdfiletagmatches + } +}; + +/* + * Initialize data structures for the file sync tracking. + */ +void +InitSync(void) +{ + /* + * Create pending-operations hashtable if we need it. Currently, we need + * it if we are standalone (not under a postmaster) or if we are a startup + * or checkpointer auxiliary process. + */ + if (!IsUnderPostmaster || AmStartupProcess() || AmCheckpointerProcess()) + { + HASHCTL hash_ctl; + + /* + * XXX: The checkpointer needs to add entries to the pending ops table + * when absorbing fsync requests. That is done within a critical + * section, which isn't usually allowed, but we make an exception. It + * means that there's a theoretical possibility that you run out of + * memory while absorbing fsync requests, which leads to a PANIC. + * Fortunately the hash table is small so that's unlikely to happen in + * practice. + */ + pendingOpsCxt = AllocSetContextCreate(TopMemoryContext, + "Pending ops context", + ALLOCSET_DEFAULT_SIZES); + MemoryContextAllowInCriticalSection(pendingOpsCxt, true); + + MemSet(&hash_ctl, 0, sizeof(hash_ctl)); + hash_ctl.keysize = sizeof(FileTag); + hash_ctl.entrysize = sizeof(PendingFsyncEntry); + hash_ctl.hcxt = pendingOpsCxt; + pendingOps = hash_create("Pending Ops Table", + 100L, + &hash_ctl, + HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); + pendingUnlinks = NIL; + } + +} + +/* + * SyncPreCheckpoint() -- Do pre-checkpoint work + * + * To distinguish unlink requests that arrived before this checkpoint + * started from those that arrived during the checkpoint, we use a cycle + * counter similar to the one we use for fsync requests. That cycle + * counter is incremented here. + * + * This must be called *before* the checkpoint REDO point is determined. + * That ensures that we won't delete files too soon. + * + * Note that we can't do anything here that depends on the assumption + * that the checkpoint will be completed. + */ +void +SyncPreCheckpoint(void) +{ + /* + * Any unlink requests arriving after this point will be assigned the next + * cycle counter, and won't be unlinked until next checkpoint. + */ + checkpoint_cycle_ctr++; +} + +/* + * SyncPostCheckpoint() -- Do post-checkpoint work + * + * Remove any lingering files that can now be safely removed. + */ +void +SyncPostCheckpoint(void) +{ + int absorb_counter; + + absorb_counter = UNLINKS_PER_ABSORB; + while (pendingUnlinks != NIL) + { + PendingUnlinkEntry *entry = (PendingUnlinkEntry *) linitial(pendingUnlinks); + char path[MAXPGPATH]; + + /* + * New entries are appended to the end, so if the entry is new we've + * reached the end of old entries. + * + * Note: if just the right number of consecutive checkpoints fail, we + * could be fooled here by cycle_ctr wraparound. However, the only + * consequence is that we'd delay unlinking for one more checkpoint, + * which is perfectly tolerable. + */ + if (entry->cycle_ctr == checkpoint_cycle_ctr) + break; + + /* Unlink the file */ + if (syncsw[entry->tag.handler].sync_unlinkfiletag(&entry->tag, + path) < 0) + { + /* + * There's a race condition, when the database is dropped at the + * same time that we process the pending unlink requests. If the + * DROP DATABASE deletes the file before we do, we will get ENOENT + * here. rmtree() also has to ignore ENOENT errors, to deal with + * the possibility that we delete the file first. + */ + if (errno != ENOENT) + ereport(WARNING, + (errcode_for_file_access(), + errmsg("could not remove file \"%s\": %m", path))); + } + + /* And remove the list entry */ + pendingUnlinks = list_delete_first(pendingUnlinks); + pfree(entry); + + /* + * As in ProcessSyncRequests, we don't want to stop absorbing fsync + * requests for along time when there are many deletions to be done. + * We can safely call AbsorbSyncRequests() at this point in the loop + * (note it might try to delete list entries). + */ + if (--absorb_counter <= 0) + { + AbsorbSyncRequests(); + absorb_counter = UNLINKS_PER_ABSORB; + } + } +} + +/* + + * ProcessSyncRequests() -- Process queued fsync requests. + */ +void +ProcessSyncRequests(void) +{ + static bool sync_in_progress = false; + + HASH_SEQ_STATUS hstat; + PendingFsyncEntry *entry; + int absorb_counter; + + /* Statistics on sync times */ + int processed = 0; + instr_time sync_start, + sync_end, + sync_diff; + uint64 elapsed; + uint64 longest = 0; + uint64 total_elapsed = 0; + + /* + * This is only called during checkpoints, and checkpoints should only + * occur in processes that have created a pendingOps. + */ + if (!pendingOps) + elog(ERROR, "cannot sync without a pendingOps table"); + + /* + * If we are in the checkpointer, the sync had better include all fsync + * requests that were queued by backends up to this point. The tightest + * race condition that could occur is that a buffer that must be written + * and fsync'd for the checkpoint could have been dumped by a backend just + * before it was visited by BufferSync(). We know the backend will have + * queued an fsync request before clearing the buffer's dirtybit, so we + * are safe as long as we do an Absorb after completing BufferSync(). + */ + AbsorbSyncRequests(); + + /* + * To avoid excess fsync'ing (in the worst case, maybe a never-terminating + * checkpoint), we want to ignore fsync requests that are entered into the + * hashtable after this point --- they should be processed next time, + * instead. We use sync_cycle_ctr to tell old entries apart from new + * ones: new ones will have cycle_ctr equal to the incremented value of + * sync_cycle_ctr. + * + * In normal circumstances, all entries present in the table at this point + * will have cycle_ctr exactly equal to the current (about to be old) + * value of sync_cycle_ctr. However, if we fail partway through the + * fsync'ing loop, then older values of cycle_ctr might remain when we + * come back here to try again. Repeated checkpoint failures would + * eventually wrap the counter around to the point where an old entry + * might appear new, causing us to skip it, possibly allowing a checkpoint + * to succeed that should not have. To forestall wraparound, any time the + * previous ProcessSyncRequests() failed to complete, run through the + * table and forcibly set cycle_ctr = sync_cycle_ctr. + * + * Think not to merge this loop with the main loop, as the problem is + * exactly that that loop may fail before having visited all the entries. + * From a performance point of view it doesn't matter anyway, as this path + * will never be taken in a system that's functioning normally. + */ + if (sync_in_progress) + { + /* prior try failed, so update any stale cycle_ctr values */ + hash_seq_init(&hstat, pendingOps); + while ((entry = (PendingFsyncEntry *) hash_seq_search(&hstat)) != NULL) + { + entry->cycle_ctr = sync_cycle_ctr; + } + } + + /* Advance counter so that new hashtable entries are distinguishable */ + sync_cycle_ctr++; + + /* Set flag to detect failure if we don't reach the end of the loop */ + sync_in_progress = true; + + /* Now scan the hashtable for fsync requests to process */ + absorb_counter = FSYNCS_PER_ABSORB; + hash_seq_init(&hstat, pendingOps); + while ((entry = (PendingFsyncEntry *) hash_seq_search(&hstat)) != NULL) + { + int failures; + + /* + * If fsync is off then we don't have to bother opening the file at + * all. (We delay checking until this point so that changing fsync on + * the fly behaves sensibly.) + */ + if (!enableFsync) + continue; + + /* + * If the entry is new then don't process it this time; it is new. + * Note "continue" bypasses the hash-remove call at the bottom of the + * loop. + */ + if (entry->cycle_ctr == sync_cycle_ctr) + continue; + + /* Else assert we haven't missed it */ + Assert((CycleCtr) (entry->cycle_ctr + 1) == sync_cycle_ctr); + + /* + * If in checkpointer, we want to absorb pending requests every so + * often to prevent overflow of the fsync request queue. It is + * unspecified whether newly-added entries will be visited by + * hash_seq_search, but we don't care since we don't need to process + * them anyway. + */ + if (--absorb_counter <= 0) + { + AbsorbSyncRequests(); + absorb_counter = FSYNCS_PER_ABSORB; + } + + /* + * The fsync table could contain requests to fsync segments that have + * been deleted (unlinked) by the time we get to them. Rather than + * just hoping an ENOENT (or EACCES on Windows) error can be ignored, + * what we do on error is absorb pending requests and then retry. + * Since mdunlink() queues a "cancel" message before actually + * unlinking, the fsync request is guaranteed to be marked canceled + * after the absorb if it really was this case. DROP DATABASE likewise + * has to tell us to forget fsync requests before it starts deletions. + */ + for (failures = 0; !entry->canceled; failures++) + { + char path[MAXPGPATH]; + + INSTR_TIME_SET_CURRENT(sync_start); + if (syncsw[entry->tag.handler].sync_syncfiletag(&entry->tag, + path) == 0) + { + /* Success; update statistics about sync timing */ + INSTR_TIME_SET_CURRENT(sync_end); + sync_diff = sync_end; + INSTR_TIME_SUBTRACT(sync_diff, sync_start); + elapsed = INSTR_TIME_GET_MICROSEC(sync_diff); + if (elapsed > longest) + longest = elapsed; + total_elapsed += elapsed; + processed++; + + if (log_checkpoints) + elog(DEBUG1, "checkpoint sync: number=%d file=%s time=%.3f msec", + processed, + path, + (double) elapsed / 1000); + + break; /* out of retry loop */ + } + + /* + * It is possible that the relation has been dropped or truncated + * since the fsync request was entered. Therefore, allow ENOENT, + * but only if we didn't fail already on this file. + */ + if (!FILE_POSSIBLY_DELETED(errno) || failures > 0) + ereport(data_sync_elevel(ERROR), + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\": %m", + path))); + else + ereport(DEBUG1, + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\" but retrying: %m", + path))); + + /* + * Absorb incoming requests and check to see if a cancel arrived + * for this relation fork. + */ + AbsorbSyncRequests(); + absorb_counter = FSYNCS_PER_ABSORB; /* might as well... */ + } /* end retry loop */ + + /* We are done with this entry, remove it */ + if (hash_search(pendingOps, &entry->tag, HASH_REMOVE, NULL) == NULL) + elog(ERROR, "pendingOps corrupted"); + } /* end loop over hashtable entries */ + + /* Return sync performance metrics for report at checkpoint end */ + CheckpointStats.ckpt_sync_rels = processed; + CheckpointStats.ckpt_longest_sync = longest; + CheckpointStats.ckpt_agg_sync_time = total_elapsed; + + /* Flag successful completion of ProcessSyncRequests */ + sync_in_progress = false; +} + +/* + * RememberSyncRequest() -- callback from checkpointer side of sync request + * + * We stuff fsync requests into the local hash table for execution + * during the checkpointer's next checkpoint. UNLINK requests go into a + * separate linked list, however, because they get processed separately. + * + * See sync.h for more information on the types of sync requests supported. + */ +void +RememberSyncRequest(const FileTag *ftag, SyncRequestType type) +{ + Assert(pendingOps); + + if (type == SYNC_FORGET_REQUEST) + { + PendingFsyncEntry *entry; + + /* Cancel previously entered request */ + entry = (PendingFsyncEntry *) hash_search(pendingOps, + (void *) ftag, + HASH_FIND, + NULL); + if (entry != NULL) + entry->canceled = true; + } + else if (type == SYNC_FILTER_REQUEST) + { + HASH_SEQ_STATUS hstat; + PendingFsyncEntry *entry; + ListCell *cell; + + /* Cancel matching fsync requests */ + hash_seq_init(&hstat, pendingOps); + while ((entry = (PendingFsyncEntry *) hash_seq_search(&hstat)) != NULL) + { + if (entry->tag.handler == ftag->handler && + syncsw[ftag->handler].sync_filetagmatches(ftag, &entry->tag)) + entry->canceled = true; + } + + /* Remove matching unlink requests */ + foreach(cell, pendingUnlinks) + { + PendingUnlinkEntry *entry = (PendingUnlinkEntry *) lfirst(cell); + + if (entry->tag.handler == ftag->handler && + syncsw[ftag->handler].sync_filetagmatches(ftag, &entry->tag)) + { + pendingUnlinks = foreach_delete_current(pendingUnlinks, cell); + pfree(entry); + } + } + } + else if (type == SYNC_UNLINK_REQUEST) + { + /* Unlink request: put it in the linked list */ + MemoryContext oldcxt = MemoryContextSwitchTo(pendingOpsCxt); + PendingUnlinkEntry *entry; + + entry = palloc(sizeof(PendingUnlinkEntry)); + entry->tag = *ftag; + entry->cycle_ctr = checkpoint_cycle_ctr; + + pendingUnlinks = lappend(pendingUnlinks, entry); + + MemoryContextSwitchTo(oldcxt); + } + else + { + /* Normal case: enter a request to fsync this segment */ + MemoryContext oldcxt = MemoryContextSwitchTo(pendingOpsCxt); + PendingFsyncEntry *entry; + bool found; + + Assert(type == SYNC_REQUEST); + + entry = (PendingFsyncEntry *) hash_search(pendingOps, + (void *) ftag, + HASH_ENTER, + &found); + /* if new entry, initialize it */ + if (!found) + { + entry->cycle_ctr = sync_cycle_ctr; + entry->canceled = false; + } + + /* + * NB: it's intentional that we don't change cycle_ctr if the entry + * already exists. The cycle_ctr must represent the oldest fsync + * request that could be in the entry. + */ + + MemoryContextSwitchTo(oldcxt); + } +} + +/* + * Register the sync request locally, or forward it to the checkpointer. + * + * If retryOnError is true, we'll keep trying if there is no space in the + * queue. Return true if we succeeded, or false if there wasn't space. + */ +bool +RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, + bool retryOnError) +{ + bool ret; + + if (pendingOps != NULL) + { + /* standalone backend or startup process: fsync state is local */ + RememberSyncRequest(ftag, type); + return true; + } + + for (;;) + { + /* + * Notify the checkpointer about it. If we fail to queue a message in + * retryOnError mode, we have to sleep and try again ... ugly, but + * hopefully won't happen often. + * + * XXX should we CHECK_FOR_INTERRUPTS in this loop? Escaping with an + * error in the case of SYNC_UNLINK_REQUEST would leave the + * no-longer-used file still present on disk, which would be bad, so + * I'm inclined to assume that the checkpointer will always empty the + * queue soon. + */ + ret = ForwardSyncRequest(ftag, type); + + /* + * If we are successful in queueing the request, or we failed and were + * instructed not to retry on error, break. + */ + if (ret || (!ret && !retryOnError)) + break; + + pg_usleep(10000L); + } + + return ret; +} + +/* + * In archive recovery, we rely on checkpointer to do fsyncs, but we will have + * already created the pendingOps during initialization of the startup + * process. Calling this function drops the local pendingOps so that + * subsequent requests will be forwarded to checkpointer. + */ +void +EnableSyncRequestForwarding(void) +{ + /* Perform any pending fsyncs we may have queued up, then drop table */ + if (pendingOps) + { + ProcessSyncRequests(); + hash_destroy(pendingOps); + } + pendingOps = NULL; + + /* + * We should not have any pending unlink requests, since mdunlink doesn't + * queue unlink requests when isRedo. + */ + Assert(pendingUnlinks == NIL); +} diff --git a/src/backend/tcop/Makefile b/src/backend/tcop/Makefile index 674302feb79..2320319c4ef 100644 --- a/src/backend/tcop/Makefile +++ b/src/backend/tcop/Makefile @@ -14,8 +14,4 @@ include $(top_builddir)/src/Makefile.global OBJS= dest.o fastpath.o postgres.o pquery.o utility.o -ifneq (,$(filter $(PORTNAME),cygwin win32)) -override CPPFLAGS += -DWIN32_STACK_RLIMIT=$(WIN32_STACK_RLIMIT) -endif - include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index c95a4d519de..7bb81df9707 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -4,7 +4,7 @@ * support for communication destinations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -67,29 +67,33 @@ donothingCleanup(DestReceiver *self) * static DestReceiver structs for dest types needing no local state * ---------------- */ -static DestReceiver donothingDR = { +static const DestReceiver donothingDR = { donothingReceive, donothingStartup, donothingCleanup, donothingCleanup, DestNone }; -static DestReceiver debugtupDR = { +static const DestReceiver debugtupDR = { debugtup, debugStartup, donothingCleanup, donothingCleanup, DestDebug }; -static DestReceiver printsimpleDR = { +static const DestReceiver printsimpleDR = { printsimple, printsimple_startup, donothingCleanup, donothingCleanup, DestRemoteSimple }; -static DestReceiver spi_printtupDR = { +static const DestReceiver spi_printtupDR = { spi_printtup, spi_dest_startup, donothingCleanup, donothingCleanup, DestSPI }; -/* Globally available receiver for DestNone */ -DestReceiver *None_Receiver = &donothingDR; - +/* + * Globally available receiver for DestNone. + * + * It's ok to cast the constness away as any modification of the none receiver + * would be a bug (which gets easier to catch this way). + */ +DestReceiver *None_Receiver = (DestReceiver *) &donothingDR; /* ---------------- * BeginCommand - initialize the destination at start of command @@ -108,6 +112,11 @@ BeginCommand(const char *commandTag, CommandDest dest) DestReceiver * CreateDestReceiver(CommandDest dest) { + /* + * It's ok to cast the constness away as any modification of the none + * receiver would be a bug (which gets easier to catch this way). + */ + switch (dest) { case DestRemote: @@ -115,16 +124,16 @@ CreateDestReceiver(CommandDest dest) return printtup_create_DR(dest); case DestRemoteSimple: - return &printsimpleDR; + return unconstify(DestReceiver *, &printsimpleDR); case DestNone: - return &donothingDR; + return unconstify(DestReceiver *, &donothingDR); case DestDebug: - return &debugtupDR; + return unconstify(DestReceiver *, &debugtupDR); case DestSPI: - return &spi_printtupDR; + return unconstify(DestReceiver *, &spi_printtupDR); case DestTuplestore: return CreateTuplestoreDestReceiver(); @@ -146,7 +155,7 @@ CreateDestReceiver(CommandDest dest) } /* should never get here */ - return &donothingDR; + pg_unreachable(); } /* ---------------- diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c index d16ba5ec927..61aa1697c3e 100644 --- a/src/backend/tcop/fastpath.c +++ b/src/backend/tcop/fastpath.c @@ -3,7 +3,7 @@ * fastpath.c * routines to handle function requests from the frontend * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -57,9 +57,9 @@ struct fp_info static int16 parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, - FunctionCallInfo fcinfo); + FunctionCallInfo fcinfo); static int16 parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip, - FunctionCallInfo fcinfo); + FunctionCallInfo fcinfo); /* ---------------- @@ -258,9 +258,9 @@ fetch_fp_info(Oid func_id, struct fp_info *fip) void HandleFunctionRequest(StringInfo msgBuf) { + LOCAL_FCINFO(fcinfo, FUNC_MAX_ARGS); Oid fid; AclResult aclresult; - FunctionCallInfoData fcinfo; int16 rformat; Datum retval; struct fp_info my_fp; @@ -332,12 +332,12 @@ HandleFunctionRequest(StringInfo msgBuf) * functions can't be called this way. Perhaps we should pass * DEFAULT_COLLATION_OID, instead? */ - InitFunctionCallInfoData(fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, &fip->flinfo, 0, InvalidOid, NULL, NULL); if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) - rformat = parse_fcall_arguments(msgBuf, fip, &fcinfo); + rformat = parse_fcall_arguments(msgBuf, fip, fcinfo); else - rformat = parse_fcall_arguments_20(msgBuf, fip, &fcinfo); + rformat = parse_fcall_arguments_20(msgBuf, fip, fcinfo); /* Verify we reached the end of the message where expected. */ pq_getmsgend(msgBuf); @@ -350,9 +350,9 @@ HandleFunctionRequest(StringInfo msgBuf) { int i; - for (i = 0; i < fcinfo.nargs; i++) + for (i = 0; i < fcinfo->nargs; i++) { - if (fcinfo.argnull[i]) + if (fcinfo->args[i].isnull) { callit = false; break; @@ -363,18 +363,18 @@ HandleFunctionRequest(StringInfo msgBuf) if (callit) { /* Okay, do it ... */ - retval = FunctionCallInvoke(&fcinfo); + retval = FunctionCallInvoke(fcinfo); } else { - fcinfo.isnull = true; + fcinfo->isnull = true; retval = (Datum) 0; } /* ensure we do at least one CHECK_FOR_INTERRUPTS per function call */ CHECK_FOR_INTERRUPTS(); - SendFunctionResult(retval, fcinfo.isnull, fip->rettype, rformat); + SendFunctionResult(retval, fcinfo->isnull, fip->rettype, rformat); /* We no longer need the snapshot */ PopActiveSnapshot(); @@ -450,11 +450,11 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, argsize = pq_getmsgint(msgBuf, 4); if (argsize == -1) { - fcinfo->argnull[i] = true; + fcinfo->args[i].isnull = true; } else { - fcinfo->argnull[i] = false; + fcinfo->args[i].isnull = false; if (argsize < 0) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -494,8 +494,8 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, else pstring = pg_client_to_server(abuf.data, argsize); - fcinfo->arg[i] = OidInputFunctionCall(typinput, pstring, - typioparam, -1); + fcinfo->args[i].value = OidInputFunctionCall(typinput, pstring, + typioparam, -1); /* Free result of encoding conversion, if any */ if (pstring && pstring != abuf.data) pfree(pstring); @@ -514,8 +514,8 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip, else bufptr = &abuf; - fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, bufptr, - typioparam, -1); + fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, bufptr, + typioparam, -1); /* Trouble if it didn't eat the whole buffer */ if (argsize != -1 && abuf.cursor != abuf.len) @@ -579,12 +579,12 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip, argsize = pq_getmsgint(msgBuf, 4); if (argsize == -1) { - fcinfo->argnull[i] = true; - fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, NULL, - typioparam, -1); + fcinfo->args[i].isnull = true; + fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, NULL, + typioparam, -1); continue; } - fcinfo->argnull[i] = false; + fcinfo->args[i].isnull = false; if (argsize < 0) ereport(ERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -597,8 +597,8 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip, pq_getmsgbytes(msgBuf, argsize), argsize); - fcinfo->arg[i] = OidReceiveFunctionCall(typreceive, &abuf, - typioparam, -1); + fcinfo->args[i].value = OidReceiveFunctionCall(typreceive, &abuf, + typioparam, -1); /* Trouble if it didn't eat the whole buffer */ if (abuf.cursor != abuf.len) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 5095a4f6867..e8d8e6f8285 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3,7 +3,7 @@ * postgres.c * POSTGRES C Backend Interface * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -42,13 +42,14 @@ #include "catalog/pg_type.h" #include "commands/async.h" #include "commands/prepare.h" +#include "executor/spi.h" #include "jit/jit.h" #include "libpq/libpq.h" #include "libpq/pqformat.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "nodes/print.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "pgstat.h" #include "pg_trace.h" #include "parser/analyze.h" @@ -314,7 +315,7 @@ interactive_getc(void) c = getc(stdin); - ProcessClientReadInterrupt(true); + ProcessClientReadInterrupt(false); return c; } @@ -519,8 +520,9 @@ ReadCommand(StringInfo inBuf) /* * ProcessClientReadInterrupt() - Process interrupts specific to client reads * - * This is called just after low-level reads. That might be after the read - * finished successfully, or it was interrupted via interrupt. + * This is called just before and after low-level reads. + * 'blocked' is true if no data was available to read and we plan to retry, + * false if about to read or done reading. * * Must preserve errno! */ @@ -531,23 +533,31 @@ ProcessClientReadInterrupt(bool blocked) if (DoingCommandRead) { - /* Check for general interrupts that arrived while reading */ + /* Check for general interrupts that arrived before/while reading */ CHECK_FOR_INTERRUPTS(); - /* Process sinval catchup interrupts that happened while reading */ + /* Process sinval catchup interrupts, if any */ if (catchupInterruptPending) ProcessCatchupInterrupt(); - /* Process sinval catchup interrupts that happened while reading */ + /* Process notify interrupts, if any */ if (notifyInterruptPending) ProcessNotifyInterrupt(); } - else if (ProcDiePending && blocked) + else if (ProcDiePending) { /* - * We're dying. It's safe (and sane) to handle that now. + * We're dying. If there is no data available to read, then it's safe + * (and sane) to handle that now. If we haven't tried to read yet, + * make sure the process latch is set, so that if there is no data + * then we'll come back here and die. If we're done reading, also + * make sure the process latch is set, as we might've undesirably + * cleared it while reading. */ - CHECK_FOR_INTERRUPTS(); + if (blocked) + CHECK_FOR_INTERRUPTS(); + else + SetLatch(MyLatch); } errno = save_errno; @@ -556,9 +566,9 @@ ProcessClientReadInterrupt(bool blocked) /* * ProcessClientWriteInterrupt() - Process interrupts specific to client writes * - * This is called just after low-level writes. That might be after the read - * finished successfully, or it was interrupted via interrupt. 'blocked' tells - * us whether the + * This is called just before and after low-level writes. + * 'blocked' is true if no data could be written and we plan to retry, + * false if about to write or done writing. * * Must preserve errno! */ @@ -567,25 +577,39 @@ ProcessClientWriteInterrupt(bool blocked) { int save_errno = errno; - /* - * We only want to process the interrupt here if socket writes are - * blocking to increase the chance to get an error message to the client. - * If we're not blocked there'll soon be a CHECK_FOR_INTERRUPTS(). But if - * we're blocked we'll never get out of that situation if the client has - * died. - */ - if (ProcDiePending && blocked) + if (ProcDiePending) { /* - * We're dying. It's safe (and sane) to handle that now. But we don't - * want to send the client the error message as that a) would possibly - * block again b) would possibly lead to sending an error message to - * the client, while we already started to send something else. + * We're dying. If it's not possible to write, then we should handle + * that immediately, else a stuck client could indefinitely delay our + * response to the signal. If we haven't tried to write yet, make + * sure the process latch is set, so that if the write would block + * then we'll come back here and die. If we're done writing, also + * make sure the process latch is set, as we might've undesirably + * cleared it while writing. */ - if (whereToSendOutput == DestRemote) - whereToSendOutput = DestNone; + if (blocked) + { + /* + * Don't mess with whereToSendOutput if ProcessInterrupts wouldn't + * do anything. + */ + if (InterruptHoldoffCount == 0 && CritSectionCount == 0) + { + /* + * We don't want to send the client the error message, as a) + * that would possibly block again, and b) it would likely + * lead to loss of protocol sync because we may have already + * sent a partial protocol message. + */ + if (whereToSendOutput == DestRemote) + whereToSendOutput = DestNone; - CHECK_FOR_INTERRUPTS(); + CHECK_FOR_INTERRUPTS(); + } + } + else + SetLatch(MyLatch); } errno = save_errno; @@ -632,6 +656,12 @@ pg_parse_query(const char *query_string) } #endif + /* + * Currently, outfuncs/readfuncs support is missing for many raw parse + * tree nodes, so we don't try to implement WRITE_READ_PARSE_PLAN_TREES + * here. + */ + TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string); return raw_parsetree_list; @@ -762,7 +792,7 @@ pg_rewrite_query(Query *query) ShowUsage("REWRITER STATISTICS"); #ifdef COPY_PARSE_PLAN_TREES - /* Optional debugging check: pass querytree output through copyObject() */ + /* Optional debugging check: pass querytree through copyObject() */ { List *new_list; @@ -775,6 +805,46 @@ pg_rewrite_query(Query *query) } #endif +#ifdef WRITE_READ_PARSE_PLAN_TREES + /* Optional debugging check: pass querytree through outfuncs/readfuncs */ + { + List *new_list = NIL; + ListCell *lc; + + /* + * We currently lack outfuncs/readfuncs support for most utility + * statement types, so only attempt to write/read non-utility queries. + */ + foreach(lc, querytree_list) + { + Query *query = castNode(Query, lfirst(lc)); + + if (query->commandType != CMD_UTILITY) + { + char *str = nodeToString(query); + Query *new_query = stringToNodeWithLocations(str); + + /* + * queryId is not saved in stored rules, but we must preserve + * it here to avoid breaking pg_stat_statements. + */ + new_query->queryId = query->queryId; + + new_list = lappend(new_list, new_query); + pfree(str); + } + else + new_list = lappend(new_list, query); + } + + /* This checks both outfuncs/readfuncs and the equal() routines... */ + if (!equal(new_list, querytree_list)) + elog(WARNING, "outfuncs/readfuncs failed to produce equal parse tree"); + else + querytree_list = new_list; + } +#endif + if (Debug_print_rewritten) elog_node_display(LOG, "rewritten parse tree", querytree_list, Debug_pretty_print); @@ -811,7 +881,7 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) ShowUsage("PLANNER STATISTICS"); #ifdef COPY_PARSE_PLAN_TREES - /* Optional debugging check: pass plan output through copyObject() */ + /* Optional debugging check: pass plan tree through copyObject() */ { PlannedStmt *new_plan = copyObject(plan); @@ -829,6 +899,30 @@ pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams) } #endif +#ifdef WRITE_READ_PARSE_PLAN_TREES + /* Optional debugging check: pass plan tree through outfuncs/readfuncs */ + { + char *str; + PlannedStmt *new_plan; + + str = nodeToString(plan); + new_plan = stringToNodeWithLocations(str); + pfree(str); + + /* + * equal() currently does not have routines to compare Plan nodes, so + * don't try to test equality here. Perhaps fix someday? + */ +#ifdef NOT_USED + /* This checks both outfuncs/readfuncs and the equal() routines... */ + if (!equal(new_plan, plan)) + elog(WARNING, "outfuncs/readfuncs failed to produce an equal plan tree"); + else +#endif + plan = new_plan; + } +#endif + /* * Print plan if debugging. */ @@ -976,6 +1070,7 @@ exec_simple_query(const char *query_string) bool snapshot_set = false; const char *commandTag; char completionTag[COMPLETION_TAG_BUFSIZE]; + MemoryContext per_parsetree_context = NULL; List *querytree_list, *plantree_list; Portal portal; @@ -1038,10 +1133,25 @@ exec_simple_query(const char *query_string) /* * OK to analyze, rewrite, and plan this query. * - * Switch to appropriate context for constructing querytrees (again, - * these must outlive the execution context). + * Switch to appropriate context for constructing query and plan trees + * (these can't be in the transaction context, as that will get reset + * when the command is COMMIT/ROLLBACK). If we have multiple + * parsetrees, we use a separate context for each one, so that we can + * free that memory before moving on to the next one. But for the + * last (or only) parsetree, just use MessageContext, which will be + * reset shortly after completion anyway. In event of an error, the + * per_parsetree_context will be deleted when MessageContext is reset. */ - oldcontext = MemoryContextSwitchTo(MessageContext); + if (lnext(parsetree_list, parsetree_item) != NULL) + { + per_parsetree_context = + AllocSetContextCreate(MessageContext, + "per-parsetree message context", + ALLOCSET_DEFAULT_SIZES); + oldcontext = MemoryContextSwitchTo(per_parsetree_context); + } + else + oldcontext = MemoryContextSwitchTo(MessageContext); querytree_list = pg_analyze_and_rewrite(parsetree, query_string, NULL, 0, NULL); @@ -1066,8 +1176,8 @@ exec_simple_query(const char *query_string) /* * We don't have to copy anything into the portal, because everything - * we are passing here is in MessageContext, which will outlive the - * portal anyway. + * we are passing here is in MessageContext or the + * per_parsetree_context, and so will outlive the portal anyway. */ PortalDefineQuery(portal, NULL, @@ -1130,7 +1240,7 @@ exec_simple_query(const char *query_string) PortalDrop(portal, false); - if (lnext(parsetree_item) == NULL) + if (lnext(parsetree_list, parsetree_item) == NULL) { /* * If this is the last parsetree of the query string, close down @@ -1169,6 +1279,10 @@ exec_simple_query(const char *query_string) * aborted by error will not send an EndCommand report at all.) */ EndCommand(completionTag, dest); + + /* Now we may drop the per-parsetree context, if one was created. */ + if (per_parsetree_context) + MemoryContextDelete(per_parsetree_context); } /* end loop over parsetrees */ /* @@ -1309,7 +1423,6 @@ exec_parse_message(const char *query_string, /* string to execute */ { Query *query; bool snapshot_set = false; - int i; raw_parse_tree = linitial_node(RawStmt, parsetree_list); @@ -1365,7 +1478,7 @@ exec_parse_message(const char *query_string, /* string to execute */ /* * Check all parameter types got determined. */ - for (i = 0; i < numParams; i++) + for (int i = 0; i < numParams; i++) { Oid ptype = paramTypes[i]; @@ -1554,10 +1667,8 @@ exec_bind_message(StringInfo input_message) numPFormats = pq_getmsgint(input_message, 2); if (numPFormats > 0) { - int i; - pformats = (int16 *) palloc(numPFormats * sizeof(int16)); - for (i = 0; i < numPFormats; i++) + for (int i = 0; i < numPFormats; i++) pformats[i] = pq_getmsgint(input_message, 2); } @@ -1640,20 +1751,9 @@ exec_bind_message(StringInfo input_message) */ if (numParams > 0) { - int paramno; - - params = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) + - numParams * sizeof(ParamExternData)); - /* we have static list of params, so no hooks needed */ - params->paramFetch = NULL; - params->paramFetchArg = NULL; - params->paramCompile = NULL; - params->paramCompileArg = NULL; - params->parserSetup = NULL; - params->parserSetupArg = NULL; - params->numParams = numParams; - - for (paramno = 0; paramno < numParams; paramno++) + params = makeParamList(numParams); + + for (int paramno = 0; paramno < numParams; paramno++) { Oid ptype = psrc->param_types[paramno]; int32 plength; @@ -1678,7 +1778,7 @@ exec_bind_message(StringInfo input_message) * trailing null. This is grotty but is a big win when * dealing with very large parameter strings. */ - pbuf.data = (char *) pvalue; + pbuf.data = unconstify(char *, pvalue); pbuf.maxlen = plength + 1; pbuf.len = plength; pbuf.cursor = 0; @@ -1781,10 +1881,8 @@ exec_bind_message(StringInfo input_message) numRFormats = pq_getmsgint(input_message, 2); if (numRFormats > 0) { - int i; - rformats = (int16 *) palloc(numRFormats * sizeof(int16)); - for (i = 0; i < numRFormats; i++) + for (int i = 0; i < numRFormats; i++) rformats[i] = pq_getmsgint(input_message, 2); } @@ -2115,6 +2213,8 @@ check_log_statement(List *stmt_list) /* * check_log_duration * Determine whether current command's duration should be logged + * We also check if this statement in this transaction must be logged + * (regardless of its duration). * * Returns: * 0 if no logging is needed @@ -2130,7 +2230,7 @@ check_log_statement(List *stmt_list) int check_log_duration(char *msec_str, bool was_logged) { - if (log_duration || log_min_duration_statement >= 0) + if (log_duration || log_min_duration_statement >= 0 || xact_is_sampled) { long secs; int usecs; @@ -2152,11 +2252,11 @@ check_log_duration(char *msec_str, bool was_logged) (secs > log_min_duration_statement / 1000 || secs * 1000 + msecs >= log_min_duration_statement))); - if (exceeded || log_duration) + if (exceeded || log_duration || xact_is_sampled) { snprintf(msec_str, 32, "%ld.%03d", secs * 1000 + msecs, usecs % 1000); - if (exceeded && !was_logged) + if ((exceeded || xact_is_sampled) && !was_logged) return 2; else return 1; @@ -2211,7 +2311,6 @@ errdetail_params(ParamListInfo params) { StringInfoData param_str; MemoryContext oldcontext; - int paramno; /* This code doesn't support dynamic param lists */ Assert(params->paramFetch == NULL); @@ -2221,7 +2320,7 @@ errdetail_params(ParamListInfo params) initStringInfo(¶m_str); - for (paramno = 0; paramno < params->numParams; paramno++) + for (int paramno = 0; paramno < params->numParams; paramno++) { ParamExternData *prm = ¶ms->params[paramno]; Oid typoutput; @@ -2324,7 +2423,6 @@ static void exec_describe_statement_message(const char *stmt_name) { CachedPlanSource *psrc; - int i; /* * Start up a transaction command. (Note that this will normally change @@ -2383,7 +2481,7 @@ exec_describe_statement_message(const char *stmt_name) * message type */ pq_sendint16(&row_description_buf, psrc->num_params); - for (i = 0; i < psrc->num_params; i++) + for (int i = 0; i < psrc->num_params; i++) { Oid ptype = psrc->param_types[i]; @@ -2615,6 +2713,16 @@ quickdie(SIGNAL_ARGS) whereToSendOutput = DestNone; /* + * Notify the client before exiting, to give a clue on what happened. + * + * It's dubious to call ereport() from a signal handler. It is certainly + * not async-signal safe. But it seems better to try, than to disconnect + * abruptly and leave the client wondering what happened. It's remotely + * possible that we crash or hang while trying to send the message, but + * receiving a SIGQUIT is a sign that something has already gone badly + * wrong, so there's not much to lose. Assuming the postmaster is still + * running, it will SIGKILL us soon if we get stuck for some reason. + * * Ideally this should be ereport(FATAL), but then we'd not get control * back... */ @@ -2629,24 +2737,20 @@ quickdie(SIGNAL_ARGS) " database and repeat your command."))); /* - * We DO NOT want to run proc_exit() callbacks -- we're here because - * shared memory may be corrupted, so we don't want to try to clean up our - * transaction. Just nail the windows shut and get out of town. Now that - * there's an atexit callback to prevent third-party code from breaking - * things by calling exit() directly, we have to reset the callbacks - * explicitly to make this work as intended. - */ - on_exit_reset(); - - /* - * Note we do exit(2) not exit(0). This is to force the postmaster into a - * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random + * We DO NOT want to run proc_exit() or atexit() callbacks -- we're here + * because shared memory may be corrupted, so we don't want to try to + * clean up our transaction. Just nail the windows shut and get out of + * town. The callbacks wouldn't be safe to run from a signal handler, + * anyway. + * + * Note we do _exit(2) not _exit(0). This is to force the postmaster into + * a system reset cycle if someone sends a manual SIGQUIT to a random * backend. This is necessary precisely because we don't clean up our * shared memory state. (The "dead man switch" mechanism in pmsignal.c * should ensure the postmaster sees this as a crash, too, but no harm in * being doubly sure.) */ - exit(2); + _exit(2); } /* @@ -2762,7 +2866,8 @@ RecoveryConflictInterrupt(ProcSignalReason reason) if (!IsWaitingForLock()) return; - /* Intentional drop through to check wait for pin */ + /* Intentional fall through to check wait for pin */ + /* FALLTHROUGH */ case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN: @@ -2775,7 +2880,8 @@ RecoveryConflictInterrupt(ProcSignalReason reason) MyProc->recoveryConflictPending = true; - /* Intentional drop through to error handling */ + /* Intentional fall through to error handling */ + /* FALLTHROUGH */ case PROCSIG_RECOVERY_CONFLICT_LOCK: case PROCSIG_RECOVERY_CONFLICT_TABLESPACE: @@ -2819,7 +2925,8 @@ RecoveryConflictInterrupt(ProcSignalReason reason) break; } - /* Intentional drop through to session cancel */ + /* Intentional fall through to session cancel */ + /* FALLTHROUGH */ case PROCSIG_RECOVERY_CONFLICT_DATABASE: RecoveryConflictPending = true; @@ -3938,6 +4045,7 @@ PostgresMain(int argc, char *argv[], WalSndErrorCleanup(); PortalErrorCleanup(); + SPICleanup(); /* * We can't release replication slots inside AbortTransaction() as we @@ -4168,10 +4276,8 @@ PostgresMain(int argc, char *argv[], numParams = pq_getmsgint(&input_message, 2); if (numParams > 0) { - int i; - paramTypes = (Oid *) palloc(numParams * sizeof(Oid)); - for (i = 0; i < numParams; i++) + for (int i = 0; i < numParams; i++) paramTypes[i] = pq_getmsgint(&input_message, 4); } pq_getmsgend(&input_message); @@ -4562,7 +4668,7 @@ log_disconnections(int code, Datum arg) minutes, seconds; - TimestampDifference(port->SessionStartTime, + TimestampDifference(MyStartTimestamp, GetCurrentTimestamp(), &secs, &usecs); msecs = usecs / 1000; diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index 50f852a4aa7..9e48adc53ce 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -3,7 +3,7 @@ * pquery.c * POSTGRES process query command code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -36,27 +36,27 @@ Portal ActivePortal = NULL; static void ProcessQuery(PlannedStmt *plan, - const char *sourceText, - ParamListInfo params, - QueryEnvironment *queryEnv, - DestReceiver *dest, - char *completionTag); + const char *sourceText, + ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, + char *completionTag); static void FillPortalStore(Portal portal, bool isTopLevel); static uint64 RunFromStore(Portal portal, ScanDirection direction, uint64 count, - DestReceiver *dest); + DestReceiver *dest); static uint64 PortalRunSelect(Portal portal, bool forward, long count, - DestReceiver *dest); + DestReceiver *dest); static void PortalRunUtility(Portal portal, PlannedStmt *pstmt, - bool isTopLevel, bool setHoldSnapshot, - DestReceiver *dest, char *completionTag); + bool isTopLevel, bool setHoldSnapshot, + DestReceiver *dest, char *completionTag); static void PortalRunMulti(Portal portal, - bool isTopLevel, bool setHoldSnapshot, - DestReceiver *dest, DestReceiver *altdest, - char *completionTag); + bool isTopLevel, bool setHoldSnapshot, + DestReceiver *dest, DestReceiver *altdest, + char *completionTag); static uint64 DoPortalRunFetch(Portal portal, - FetchDirection fdirection, - long count, - DestReceiver *dest); + FetchDirection fdirection, + long count, + DestReceiver *dest); static void DoPortalRewind(Portal portal); @@ -175,10 +175,8 @@ ProcessQuery(PlannedStmt *plan, queryDesc->estate->es_processed); break; case CMD_INSERT: - if (queryDesc->estate->es_processed == 1) - lastOid = queryDesc->estate->es_lastoid; - else - lastOid = InvalidOid; + /* lastoid doesn't exist anymore */ + lastOid = InvalidOid; snprintf(completionTag, COMPLETION_TAG_BUFSIZE, "INSERT %u " UINT64_FORMAT, lastOid, queryDesc->estate->es_processed); @@ -193,11 +191,6 @@ ProcessQuery(PlannedStmt *plan, "DELETE " UINT64_FORMAT, queryDesc->estate->es_processed); break; - case CMD_MERGE: - snprintf(completionTag, COMPLETION_TAG_BUFSIZE, - "MERGE " UINT64_FORMAT, - queryDesc->estate->es_processed); - break; default: strcpy(completionTag, "???"); break; @@ -556,8 +549,7 @@ PortalStart(Portal portal, ParamListInfo params, pstmt = PortalGetPrimaryStmt(portal); portal->tupDesc = - ExecCleanTypeFromTL(pstmt->planTree->targetlist, - false); + ExecCleanTypeFromTL(pstmt->planTree->targetlist); } /* @@ -1031,8 +1023,8 @@ FillPortalStore(Portal portal, bool isTopLevel) /* * Run the portal to completion just as for the default - * MULTI_QUERY case, but send the primary query's output to the - * tuplestore. Auxiliary query outputs are discarded. Set the + * PORTAL_MULTI_QUERY case, but send the primary query's output to + * the tuplestore. Auxiliary query outputs are discarded. Set the * portal's holdSnapshot to the snapshot used (or a copy of it). */ PortalRunMulti(portal, isTopLevel, true, @@ -1076,7 +1068,7 @@ RunFromStore(Portal portal, ScanDirection direction, uint64 count, uint64 current_tuple_count = 0; TupleTableSlot *slot; - slot = MakeSingleTupleTableSlot(portal->tupDesc); + slot = MakeSingleTupleTableSlot(portal->tupDesc, &TTSOpsMinimalTuple); dest->rStartup(dest, CMD_SELECT, portal->tupDesc); @@ -1342,7 +1334,7 @@ PortalRunMulti(Portal portal, * Increment command counter between queries, but not after the last * one. */ - if (lnext(stmtlist_item) != NULL) + if (lnext(portal->stmts, stmtlist_item) != NULL) CommandCounterIncrement(); /* diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 4effadcb300..c6faa6619d2 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -5,7 +5,7 @@ * commands. At one time acted as an interface between the Lisp and C * systems. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -67,7 +67,9 @@ #include "tcop/utility.h" #include "utils/acl.h" #include "utils/guc.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" +#include "utils/rel.h" /* Hook for plugins to get control in ProcessUtility() */ @@ -75,13 +77,13 @@ ProcessUtility_hook_type ProcessUtility_hook = NULL; /* local function declarations */ static void ProcessUtilitySlow(ParseState *pstate, - PlannedStmt *pstmt, - const char *queryString, - ProcessUtilityContext context, - ParamListInfo params, - QueryEnvironment *queryEnv, - DestReceiver *dest, - char *completionTag); + PlannedStmt *pstmt, + const char *queryString, + ProcessUtilityContext context, + ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, + char *completionTag); static void ExecDropStmt(DropStmt *stmt, bool isTopLevel); @@ -110,7 +112,6 @@ CommandIsReadOnly(PlannedStmt *pstmt) case CMD_UPDATE: case CMD_INSERT: case CMD_DELETE: - case CMD_MERGE: return false; case CMD_UTILITY: /* For now, treat all utility commands as read/write */ @@ -386,6 +387,9 @@ standard_ProcessUtility(PlannedStmt *pstmt, bool isAtomicContext = (!(context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY_NONATOMIC) || IsTransactionBlock()); ParseState *pstate; + /* This can recurse, so check for excessive recursion */ + check_stack_depth(); + check_xact_readonly(parsetree); if (completionTag) @@ -436,7 +440,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case TRANS_STMT_COMMIT: - if (!EndTransactionBlock()) + if (!EndTransactionBlock(stmt->chain)) { /* report unsuccessful commit in completionTag */ if (completionTag) @@ -467,7 +471,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, break; case TRANS_STMT_ROLLBACK: - UserAbortTransactionBlock(); + UserAbortTransactionBlock(stmt->chain); break; case TRANS_STMT_SAVEPOINT: @@ -625,7 +629,7 @@ standard_ProcessUtility(PlannedStmt *pstmt, { UnlistenStmt *stmt = (UnlistenStmt *) parsetree; - PreventCommandDuringRecovery("UNLISTEN"); + /* we allow UNLISTEN during recovery, as it's a noop */ CheckRestrictedOperation("UNLISTEN"); if (stmt->conditionname) Async_Unlisten(stmt->conditionname); @@ -660,10 +664,10 @@ standard_ProcessUtility(PlannedStmt *pstmt, VacuumStmt *stmt = (VacuumStmt *) parsetree; /* we choose to allow this during "read only" transactions */ - PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ? + PreventCommandDuringRecovery(stmt->is_vacuumcmd ? "VACUUM" : "ANALYZE"); /* forbidden in parallel mode due to CommandIsReadOnly */ - ExecVacuum(stmt, isTopLevel); + ExecVacuum(pstate, stmt, isTopLevel); } break; @@ -770,16 +774,20 @@ standard_ProcessUtility(PlannedStmt *pstmt, { ReindexStmt *stmt = (ReindexStmt *) parsetree; + if (stmt->concurrent) + PreventInTransactionBlock(isTopLevel, + "REINDEX CONCURRENTLY"); + /* we choose to allow this during "read only" transactions */ PreventCommandDuringRecovery("REINDEX"); /* forbidden in parallel mode due to CommandIsReadOnly */ switch (stmt->kind) { case REINDEX_OBJECT_INDEX: - ReindexIndex(stmt->relation, stmt->options); + ReindexIndex(stmt->relation, stmt->options, stmt->concurrent); break; case REINDEX_OBJECT_TABLE: - ReindexTable(stmt->relation, stmt->options); + ReindexTable(stmt->relation, stmt->options, stmt->concurrent); break; case REINDEX_OBJECT_SCHEMA: case REINDEX_OBJECT_SYSTEM: @@ -792,10 +800,10 @@ standard_ProcessUtility(PlannedStmt *pstmt, * intended effect! */ PreventInTransactionBlock(isTopLevel, - (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" : - (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" : - "REINDEX DATABASE"); - ReindexMultipleTables(stmt->name, stmt->kind, stmt->options); + (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" : + (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" : + "REINDEX DATABASE"); + ReindexMultipleTables(stmt->name, stmt->kind, stmt->options, stmt->concurrent); break; default: elog(ERROR, "unrecognized object type: %d", @@ -923,6 +931,13 @@ standard_ProcessUtility(PlannedStmt *pstmt, } free_parsestate(pstate); + + /* + * Make effects of commands visible, for instance so that + * PreCommit_on_commit_actions() can see them (see for example bug + * #15631). + */ + CommandCounterIncrement(); } /* @@ -942,7 +957,7 @@ ProcessUtilitySlow(ParseState *pstate, { Node *parsetree = pstmt->utilityStmt; bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL); - bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY); + bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); bool needCleanup; bool commandCollected = false; ObjectAddress address; @@ -1066,7 +1081,7 @@ ProcessUtilitySlow(ParseState *pstate, } /* Need CCI between commands */ - if (lnext(l) != NULL) + if (lnext(stmts, l) != NULL) CommandCounterIncrement(); } @@ -1147,7 +1162,7 @@ ProcessUtilitySlow(ParseState *pstate, } /* Need CCI between commands */ - if (lnext(l) != NULL) + if (lnext(stmts, l) != NULL) CommandCounterIncrement(); } @@ -1233,7 +1248,8 @@ ProcessUtilitySlow(ParseState *pstate, address = DefineAggregate(pstate, stmt->defnames, stmt->args, stmt->oldstyle, - stmt->definition); + stmt->definition, + stmt->replace); break; case OBJECT_OPERATOR: Assert(stmt->args == NIL); @@ -1287,11 +1303,10 @@ ProcessUtilitySlow(ParseState *pstate, IndexStmt *stmt = (IndexStmt *) parsetree; Oid relid; LOCKMODE lockmode; - List *inheritors = NIL; if (stmt->concurrent) PreventInTransactionBlock(isTopLevel, - "CREATE INDEX CONCURRENTLY"); + "CREATE INDEX CONCURRENTLY"); /* * Look up the relation OID just once, right here at the @@ -1314,17 +1329,39 @@ ProcessUtilitySlow(ParseState *pstate, * CREATE INDEX on partitioned tables (but not regular * inherited tables) recurses to partitions, so we must * acquire locks early to avoid deadlocks. + * + * We also take the opportunity to verify that all + * partitions are something we can put an index on, to + * avoid building some indexes only to fail later. */ - if (stmt->relation->inh) + if (stmt->relation->inh && + get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE) { - Relation rel; - - /* already locked by RangeVarGetRelidExtended */ - rel = heap_open(relid, NoLock); - if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE) - inheritors = find_all_inheritors(relid, lockmode, - NULL); - heap_close(rel, NoLock); + ListCell *lc; + List *inheritors = NIL; + + inheritors = find_all_inheritors(relid, lockmode, NULL); + foreach(lc, inheritors) + { + char relkind = get_rel_relkind(lfirst_oid(lc)); + + if (relkind != RELKIND_RELATION && + relkind != RELKIND_MATVIEW && + relkind != RELKIND_PARTITIONED_TABLE && + relkind != RELKIND_FOREIGN_TABLE) + elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"", + relkind, stmt->relation->relname); + + if (relkind == RELKIND_FOREIGN_TABLE && + (stmt->unique || stmt->primary)) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create unique index on partitioned table \"%s\"", + stmt->relation->relname), + errdetail("Table \"%s\" contains partitions that are foreign tables.", + stmt->relation->relname))); + } + list_free(inheritors); } /* Run parse analysis ... */ @@ -1353,8 +1390,6 @@ ProcessUtilitySlow(ParseState *pstate, parsetree); commandCollected = true; EventTriggerAlterTableEnd(); - - list_free(inheritors); } break; @@ -1425,7 +1460,7 @@ ProcessUtilitySlow(ParseState *pstate, break; case T_AlterEnumStmt: /* ALTER TYPE (enum) */ - address = AlterEnum((AlterEnumStmt *) parsetree, isTopLevel); + address = AlterEnum((AlterEnumStmt *) parsetree); break; case T_ViewStmt: /* CREATE VIEW */ @@ -1653,6 +1688,10 @@ ProcessUtilitySlow(ParseState *pstate, address = CreateStatistics((CreateStatsStmt *) parsetree); break; + case T_AlterStatsStmt: + address = AlterStatistics((AlterStatsStmt *) parsetree); + break; + case T_AlterCollationStmt: address = AlterCollation((AlterCollationStmt *) parsetree); break; @@ -1700,7 +1739,7 @@ ExecDropStmt(DropStmt *stmt, bool isTopLevel) case OBJECT_INDEX: if (stmt->concurrent) PreventInTransactionBlock(isTopLevel, - "DROP INDEX CONCURRENTLY"); + "DROP INDEX CONCURRENTLY"); /* fall through */ case OBJECT_TABLE: @@ -1730,6 +1769,12 @@ UtilityReturnsTuples(Node *parsetree) { switch (nodeTag(parsetree)) { + case T_CallStmt: + { + CallStmt *stmt = (CallStmt *) parsetree; + + return (stmt->funcexpr->funcresulttype == RECORDOID); + } case T_FetchStmt: { FetchStmt *stmt = (FetchStmt *) parsetree; @@ -1780,6 +1825,9 @@ UtilityTupleDescriptor(Node *parsetree) { switch (nodeTag(parsetree)) { + case T_CallStmt: + return CallStmtResultDesc((CallStmt *) parsetree); + case T_FetchStmt: { FetchStmt *stmt = (FetchStmt *) parsetree; @@ -1833,8 +1881,6 @@ QueryReturnsTuples(Query *parsetree) case CMD_SELECT: /* returns tuples */ return true; - case CMD_MERGE: - return false; case CMD_INSERT: case CMD_UPDATE: case CMD_DELETE: @@ -2079,10 +2125,6 @@ CreateCommandTag(Node *parsetree) tag = "UPDATE"; break; - case T_MergeStmt: - tag = "MERGE"; - break; - case T_SelectStmt: tag = "SELECT"; break; @@ -2550,7 +2592,7 @@ CreateCommandTag(Node *parsetree) break; case T_VacuumStmt: - if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM) + if (((VacuumStmt *) parsetree)->is_vacuumcmd) tag = "VACUUM"; else tag = "ANALYZE"; @@ -2767,6 +2809,10 @@ CreateCommandTag(Node *parsetree) tag = "CREATE STATISTICS"; break; + case T_AlterStatsStmt: + tag = "ALTER STATISTICS"; + break; + case T_DeallocateStmt: { DeallocateStmt *stmt = (DeallocateStmt *) parsetree; @@ -2826,9 +2872,6 @@ CreateCommandTag(Node *parsetree) case CMD_DELETE: tag = "DELETE"; break; - case CMD_MERGE: - tag = "MERGE"; - break; case CMD_UTILITY: tag = CreateCommandTag(stmt->utilityStmt); break; @@ -2889,9 +2932,6 @@ CreateCommandTag(Node *parsetree) case CMD_DELETE: tag = "DELETE"; break; - case CMD_MERGE: - tag = "MERGE"; - break; case CMD_UTILITY: tag = CreateCommandTag(stmt->utilityStmt); break; @@ -2940,7 +2980,6 @@ GetCommandLogLevel(Node *parsetree) case T_InsertStmt: case T_DeleteStmt: case T_UpdateStmt: - case T_MergeStmt: lev = LOGSTMT_MOD; break; @@ -3362,6 +3401,10 @@ GetCommandLogLevel(Node *parsetree) lev = LOGSTMT_DDL; break; + case T_AlterStatsStmt: + lev = LOGSTMT_DDL; + break; + case T_AlterCollationStmt: lev = LOGSTMT_DDL; break; @@ -3380,7 +3423,6 @@ GetCommandLogLevel(Node *parsetree) case CMD_UPDATE: case CMD_INSERT: case CMD_DELETE: - case CMD_MERGE: lev = LOGSTMT_MOD; break; @@ -3411,7 +3453,6 @@ GetCommandLogLevel(Node *parsetree) case CMD_UPDATE: case CMD_INSERT: case CMD_DELETE: - case CMD_MERGE: lev = LOGSTMT_MOD; break; diff --git a/src/backend/tsearch/Makefile b/src/backend/tsearch/Makefile index 227468ae9ed..62d8bb32548 100644 --- a/src/backend/tsearch/Makefile +++ b/src/backend/tsearch/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/tsearch # -# Copyright (c) 2006-2018, PostgreSQL Global Development Group +# Copyright (c) 2006-2019, PostgreSQL Global Development Group # # src/backend/tsearch/Makefile # diff --git a/src/backend/tsearch/dict.c b/src/backend/tsearch/dict.c index c44849b7d33..f12d336e480 100644 --- a/src/backend/tsearch/dict.c +++ b/src/backend/tsearch/dict.c @@ -3,7 +3,7 @@ * dict.c * Standard interface to dictionary * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_ispell.c b/src/backend/tsearch/dict_ispell.c index edc65477007..8b05a477f14 100644 --- a/src/backend/tsearch/dict_ispell.c +++ b/src/backend/tsearch/dict_ispell.c @@ -3,7 +3,7 @@ * dict_ispell.c * Ispell dictionary interface * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_simple.c b/src/backend/tsearch/dict_simple.c index ac6a24eba5b..2f62ef00c8f 100644 --- a/src/backend/tsearch/dict_simple.c +++ b/src/backend/tsearch/dict_simple.c @@ -3,7 +3,7 @@ * dict_simple.c * Simple dictionary: just lowercase and check for stopword * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dict_synonym.c b/src/backend/tsearch/dict_synonym.c index c011886cb05..ba1582c4515 100644 --- a/src/backend/tsearch/dict_synonym.c +++ b/src/backend/tsearch/dict_synonym.c @@ -3,7 +3,7 @@ * dict_synonym.c * Synonym dictionary: replace word by its synonym * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -37,7 +37,7 @@ typedef struct * Finds the next whitespace-delimited word within the 'in' string. * Returns a pointer to the first character of the word, and a pointer * to the next byte after the last character in the word (in *end). - * Character '*' at the end of word will not be threated as word + * Character '*' at the end of word will not be treated as word * character if flags is not null. */ static char * diff --git a/src/backend/tsearch/dict_thesaurus.c b/src/backend/tsearch/dict_thesaurus.c index 24364e646d3..75f8deef6a7 100644 --- a/src/backend/tsearch/dict_thesaurus.c +++ b/src/backend/tsearch/dict_thesaurus.c @@ -3,7 +3,7 @@ * dict_thesaurus.c * Thesaurus dictionary: phrase to phrase substitution * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/dicts/hunspell_sample_long.affix b/src/backend/tsearch/dicts/hunspell_sample_long.affix index fc0d485a4d9..d5df7a31f34 100644 --- a/src/backend/tsearch/dicts/hunspell_sample_long.affix +++ b/src/backend/tsearch/dicts/hunspell_sample_long.affix @@ -1,15 +1,23 @@ FLAG long -AF 7 +AF 11 AF cZ #1 AF cL #2 AF sGsJpUsS #3 AF sSpB #4 AF cZsS #5 -AF sScZs\ #6 +AF sScZs\sE #6 AF sA #7 +AF CaCp #8 +AF CcCp #9 +AF sD #10 +AF sB #11 COMPOUNDFLAG cZ +COMPOUNDBEGIN Ca +COMPOUNDMIDDLE Cb +COMPOUNDEND Cc +COMPOUNDPERMITFLAG Cp ONLYINCOMPOUND cL PFX pB Y 1 @@ -28,7 +36,18 @@ SFX sS Y 1 SFX sS 0 S [^SXZHY] SFX sA Y 1 -SFX sA Y IES [^AEIOU]Y +SFX sA Y IES [^AEIOU]Y{1} +SFX sB Y 1 +SFX sB 0 ED K{1} + +# Affixes with compound flags SFX s\ N 1 SFX s\ 0 Y/2 [^Y] + +SFX sE N 1 +SFX sE 0 S/2 [^S] + +# Check duplicate affixes +SFX sD N 1 +SFX sD 0 S/2 [^S] diff --git a/src/backend/tsearch/dicts/hunspell_sample_long.dict b/src/backend/tsearch/dicts/hunspell_sample_long.dict index 96ecbf007af..370c27acac3 100644 --- a/src/backend/tsearch/dicts/hunspell_sample_long.dict +++ b/src/backend/tsearch/dicts/hunspell_sample_long.dict @@ -1,4 +1,5 @@ book/3 +book/11 booking/4 footballklubber foot/5 @@ -6,3 +7,5 @@ football/1 ball/6 klubber/1 sky/7 +ex-/8 +machina/9 diff --git a/src/backend/tsearch/dicts/hunspell_sample_num.affix b/src/backend/tsearch/dicts/hunspell_sample_num.affix index 5f2f8e9bca7..0c4766a1918 100644 --- a/src/backend/tsearch/dicts/hunspell_sample_num.affix +++ b/src/backend/tsearch/dicts/hunspell_sample_num.affix @@ -18,6 +18,14 @@ SFX 302 0 ING [^E] SFX 303 Y 1 SFX 303 0 S [^SXZHY] +# Remove ED suffix from lexeme for base words with K ending +SFX 306 Y 1 +SFX 306 0 ED K{1} + +# Just add Y to lexeme for base words with Y ending +SFX 307 Y 1 +SFX 307 Y 0 Y* + SFX 304 Y 1 SFX 304 Y IES [^AEIOU]Y diff --git a/src/backend/tsearch/dicts/hunspell_sample_num.dict b/src/backend/tsearch/dicts/hunspell_sample_num.dict index 9db29dc780a..fbc321d5b10 100644 --- a/src/backend/tsearch/dicts/hunspell_sample_num.dict +++ b/src/backend/tsearch/dicts/hunspell_sample_num.dict @@ -1,8 +1,9 @@ book/302,301,202,303 +book/306 booking/303,201 footballklubber foot/101,303 football/101 ball/303,101,305 klubber/101 -sky/304 +sky/304,307 diff --git a/src/backend/tsearch/regis.c b/src/backend/tsearch/regis.c index cab5a4cbd20..648c02fccfe 100644 --- a/src/backend/tsearch/regis.c +++ b/src/backend/tsearch/regis.c @@ -3,7 +3,7 @@ * regis.c * Fast regex subset * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/spell.c b/src/backend/tsearch/spell.c index b9fdd77e198..c715f06b8e2 100644 --- a/src/backend/tsearch/spell.c +++ b/src/backend/tsearch/spell.c @@ -3,7 +3,7 @@ * spell.c * Normalizing word with ISpell * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * Ispell dictionary * ----------------- @@ -1303,7 +1303,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) { Conf->useFlagAliases = true; naffix = atoi(sflag); - if (naffix == 0) + if (naffix <= 0) ereport(ERROR, (errcode(ERRCODE_CONFIG_FILE_ERROR), errmsg("invalid number of flag vector aliases"))); @@ -1318,7 +1318,7 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) Conf->AffixData[curaffix] = VoidString; curaffix++; } - /* Other lines is aliases */ + /* Other lines are aliases */ else { if (curaffix < naffix) @@ -1326,6 +1326,11 @@ NIImportOOAffixes(IspellDict *Conf, const char *filename) Conf->AffixData[curaffix] = cpstrdup(Conf, sflag); curaffix++; } + else + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("number of aliases exceeds specified number %d", + naffix - 1))); } goto nextline; } @@ -1744,8 +1749,8 @@ NISortDictionary(IspellDict *Conf) naffix = 0; for (i = 0; i < Conf->nspell; i++) { - if (i == 0 - || strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag)) + if (i == 0 || + strcmp(Conf->Spell[i]->p.flag, Conf->Spell[i - 1]->p.flag) != 0) naffix++; } @@ -1759,8 +1764,8 @@ NISortDictionary(IspellDict *Conf) curaffix = -1; for (i = 0; i < Conf->nspell; i++) { - if (i == 0 - || strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix])) + if (i == 0 || + strcmp(Conf->Spell[i]->p.flag, Conf->AffixData[curaffix]) != 0) { curaffix++; Assert(curaffix < naffix); @@ -1963,8 +1968,10 @@ NISortAffixes(IspellDict *Conf) if ((Affix->flagflags & FF_COMPOUNDFLAG) && Affix->replen > 0 && isAffixInUse(Conf, Affix->flag)) { + bool issuffix = (Affix->type == FF_SUFFIX); + if (ptr == Conf->CompoundAffix || - ptr->issuffix != (ptr - 1)->issuffix || + issuffix != (ptr - 1)->issuffix || strbncmp((const unsigned char *) (ptr - 1)->affix, (const unsigned char *) Affix->repl, (ptr - 1)->len)) @@ -1972,7 +1979,7 @@ NISortAffixes(IspellDict *Conf) /* leave only unique and minimals suffixes */ ptr->affix = Affix->repl; ptr->len = Affix->replen; - ptr->issuffix = (Affix->type == FF_SUFFIX); + ptr->issuffix = issuffix; ptr++; } } diff --git a/src/backend/tsearch/to_tsany.c b/src/backend/tsearch/to_tsany.c index 2474b723b41..6baee8e1558 100644 --- a/src/backend/tsearch/to_tsany.c +++ b/src/backend/tsearch/to_tsany.c @@ -3,7 +3,7 @@ * to_tsany.c * to_ts* function definitions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -660,7 +660,7 @@ Datum websearch_to_tsquery_byid(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_PP(1); - MorphOpaque data; + MorphOpaque data; TSQuery query = NULL; data.cfg_id = PG_GETARG_OID(0); diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c index a114d6635be..309f7c0459a 100644 --- a/src/backend/tsearch/ts_locale.c +++ b/src/backend/tsearch/ts_locale.c @@ -3,7 +3,7 @@ * ts_locale.c * locale compatibility layer for tsearch * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -21,18 +21,29 @@ static void tsearch_readline_callback(void *arg); +/* + * The reason these functions use a 3-wchar_t output buffer, not 2 as you + * might expect, is that on Windows "wchar_t" is 16 bits and what we'll be + * getting from char2wchar() is UTF16 not UTF32. A single input character + * may therefore produce a surrogate pair rather than just one wchar_t; + * we also need room for a trailing null. When we do get a surrogate pair, + * we pass just the first code to iswdigit() etc, so that these functions will + * always return false for characters outside the Basic Multilingual Plane. + */ +#define WC_BUF_LEN 3 + int t_isdigit(const char *ptr) { int clen = pg_mblen(ptr); - wchar_t character[2]; + wchar_t character[WC_BUF_LEN]; Oid collation = DEFAULT_COLLATION_OID; /* TODO */ pg_locale_t mylocale = 0; /* TODO */ if (clen == 1 || lc_ctype_is_c(collation)) return isdigit(TOUCHAR(ptr)); - char2wchar(character, 2, ptr, clen, mylocale); + char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale); return iswdigit((wint_t) character[0]); } @@ -41,14 +52,14 @@ int t_isspace(const char *ptr) { int clen = pg_mblen(ptr); - wchar_t character[2]; + wchar_t character[WC_BUF_LEN]; Oid collation = DEFAULT_COLLATION_OID; /* TODO */ pg_locale_t mylocale = 0; /* TODO */ if (clen == 1 || lc_ctype_is_c(collation)) return isspace(TOUCHAR(ptr)); - char2wchar(character, 2, ptr, clen, mylocale); + char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale); return iswspace((wint_t) character[0]); } @@ -57,14 +68,14 @@ int t_isalpha(const char *ptr) { int clen = pg_mblen(ptr); - wchar_t character[2]; + wchar_t character[WC_BUF_LEN]; Oid collation = DEFAULT_COLLATION_OID; /* TODO */ pg_locale_t mylocale = 0; /* TODO */ if (clen == 1 || lc_ctype_is_c(collation)) return isalpha(TOUCHAR(ptr)); - char2wchar(character, 2, ptr, clen, mylocale); + char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale); return iswalpha((wint_t) character[0]); } @@ -73,14 +84,14 @@ int t_isprint(const char *ptr) { int clen = pg_mblen(ptr); - wchar_t character[2]; + wchar_t character[WC_BUF_LEN]; Oid collation = DEFAULT_COLLATION_OID; /* TODO */ pg_locale_t mylocale = 0; /* TODO */ if (clen == 1 || lc_ctype_is_c(collation)) return isprint(TOUCHAR(ptr)); - char2wchar(character, 2, ptr, clen, mylocale); + char2wchar(character, WC_BUF_LEN, ptr, clen, mylocale); return iswprint((wint_t) character[0]); } diff --git a/src/backend/tsearch/ts_parse.c b/src/backend/tsearch/ts_parse.c index 7b69ef56602..fb86ea2e08e 100644 --- a/src/backend/tsearch/ts_parse.c +++ b/src/backend/tsearch/ts_parse.c @@ -3,7 +3,7 @@ * ts_parse.c * main parse functions for tsearch * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -282,7 +282,7 @@ LexizeExec(LexizeData *ld, ParsedLex **correspondLexem) if (!dictExists) { /* - * Dictionary can't work with current tpe of lexeme, + * Dictionary can't work with current type of lexeme, * return to basic mode and redo all stored lexemes */ ld->curDictId = InvalidOid; diff --git a/src/backend/tsearch/ts_selfuncs.c b/src/backend/tsearch/ts_selfuncs.c index 7ebc3d46419..ed935faead7 100644 --- a/src/backend/tsearch/ts_selfuncs.c +++ b/src/backend/tsearch/ts_selfuncs.c @@ -3,7 +3,7 @@ * ts_selfuncs.c * Selectivity estimation functions for text search operators. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -48,10 +48,10 @@ typedef struct static Selectivity tsquerysel(VariableStatData *vardata, Datum constval); static Selectivity mcelem_tsquery_selec(TSQuery query, - Datum *mcelem, int nmcelem, - float4 *numbers, int nnumbers); + Datum *mcelem, int nmcelem, + float4 *numbers, int nnumbers); static Selectivity tsquery_opr_selec(QueryItem *item, char *operand, - TextFreq *lookup, int length, float4 minfreq); + TextFreq *lookup, int length, float4 minfreq); static int compare_lexeme_textfreq(const void *e1, const void *e2); #define tsquery_opr_selec_no_stats(query) \ diff --git a/src/backend/tsearch/ts_typanalyze.c b/src/backend/tsearch/ts_typanalyze.c index 1f93963c666..bd33e67e337 100644 --- a/src/backend/tsearch/ts_typanalyze.c +++ b/src/backend/tsearch/ts_typanalyze.c @@ -3,7 +3,7 @@ * ts_typanalyze.c * functions for gathering statistics from tsvector columns * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -13,11 +13,12 @@ */ #include "postgres.h" -#include "access/hash.h" +#include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "commands/vacuum.h" #include "tsearch/ts_type.h" #include "utils/builtins.h" +#include "utils/hashutils.h" /* A hash key for lexemes */ @@ -36,9 +37,9 @@ typedef struct } TrackItem; static void compute_tsvector_stats(VacAttrStats *stats, - AnalyzeAttrFetchFunc fetchfunc, - int samplerows, - double totalrows); + AnalyzeAttrFetchFunc fetchfunc, + int samplerows, + double totalrows); static void prune_lexemes_hashtable(HTAB *lexemes_tab, int b_current); static uint32 lexeme_hash(const void *key, Size keysize); static int lexeme_match(const void *key1, const void *key2, Size keysize); @@ -415,6 +416,7 @@ compute_tsvector_stats(VacAttrStats *stats, stats->stakind[0] = STATISTIC_KIND_MCELEM; stats->staop[0] = TextEqualOperator; + stats->stacoll[0] = DEFAULT_COLLATION_OID; stats->stanumbers[0] = mcelem_freqs; /* See above comment about two extra frequency fields */ stats->numnumbers[0] = num_mcelem + 2; diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c index f6e03aea4fe..065471c2da2 100644 --- a/src/backend/tsearch/ts_utils.c +++ b/src/backend/tsearch/ts_utils.c @@ -3,7 +3,7 @@ * ts_utils.c * various support functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c index 649245b2922..a3372a8c842 100644 --- a/src/backend/tsearch/wparser.c +++ b/src/backend/tsearch/wparser.c @@ -3,7 +3,7 @@ * wparser.c * Standard interface to word parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -66,7 +66,7 @@ tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid) (Datum) 0)); funcctx->user_fctx = (void *) st; - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "alias", @@ -212,7 +212,7 @@ prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt) st->cur = 0; funcctx->user_fctx = (void *) st; - tupdesc = CreateTemplateTupleDesc(2, false); + tupdesc = CreateTemplateTupleDesc(2); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "token", diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c index f0c34419905..f18e761af88 100644 --- a/src/backend/tsearch/wparser_def.c +++ b/src/backend/tsearch/wparser_def.c @@ -3,7 +3,7 @@ * wparser_def.c * Default text search parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -2460,13 +2460,13 @@ prsd_headline(PG_FUNCTION_ARGS) char *val = defGetString(defel); if (pg_strcasecmp(defel->defname, "MaxWords") == 0) - max_words = pg_atoi(val, sizeof(int32), 0); + max_words = pg_strtoint32(val); else if (pg_strcasecmp(defel->defname, "MinWords") == 0) - min_words = pg_atoi(val, sizeof(int32), 0); + min_words = pg_strtoint32(val); else if (pg_strcasecmp(defel->defname, "ShortWord") == 0) - shortword = pg_atoi(val, sizeof(int32), 0); + shortword = pg_strtoint32(val); else if (pg_strcasecmp(defel->defname, "MaxFragments") == 0) - max_fragments = pg_atoi(val, sizeof(int32), 0); + max_fragments = pg_strtoint32(val); else if (pg_strcasecmp(defel->defname, "StartSel") == 0) prs->startsel = pstrdup(val); else if (pg_strcasecmp(defel->defname, "StopSel") == 0) diff --git a/src/backend/utils/.gitignore b/src/backend/utils/.gitignore index f26215c6315..06855569594 100644 --- a/src/backend/utils/.gitignore +++ b/src/backend/utils/.gitignore @@ -1,5 +1,6 @@ /fmgrtab.c /fmgroids.h /fmgrprotos.h +/fmgr-stamp /probes.h /errcodes.h diff --git a/src/backend/utils/Gen_dummy_probes.pl b/src/backend/utils/Gen_dummy_probes.pl index 0458c43cc3b..a4b58ad69f5 100644 --- a/src/backend/utils/Gen_dummy_probes.pl +++ b/src/backend/utils/Gen_dummy_probes.pl @@ -4,7 +4,7 @@ # Gen_dummy_probes.pl # Perl script that generates probes.h file when dtrace is not available # -# Portions Copyright (c) 2008-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 2008-2019, PostgreSQL Global Development Group # # # IDENTIFICATION @@ -14,6 +14,9 @@ # #------------------------------------------------------------------------- +# turn off perlcritic for autogenerated code +## no critic + $0 =~ s/^.*?(\w+)[\.\w+]*$/$1/; use strict; @@ -97,38 +100,38 @@ () $CondReg ||= $s; } -# s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4)/ + # s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4)/ { $s = -s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4)/s; + s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4)/s; $CondReg ||= $s; } -# s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5)/ + # s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5)/ { $s = -s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5)/s; + s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5)/s; $CondReg ||= $s; } -# s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6)/ + # s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6)/ { $s = -s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6)/s; + s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6)/s; $CondReg ||= $s; } -# s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/ + # s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/ { $s = -s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/s; + s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6, INT7)/s; $CondReg ||= $s; } -# s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/ + # s/([^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\}, [^,)]\{1,\})/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/ { $s = -s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/s; + s /\([^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+, [^,)]+\)/(INT1, INT2, INT3, INT4, INT5, INT6, INT7, INT8)/s; $CondReg ||= $s; } diff --git a/src/backend/utils/Gen_dummy_probes.sed b/src/backend/utils/Gen_dummy_probes.sed index 023e2d32574..fcc9f30aba4 100644 --- a/src/backend/utils/Gen_dummy_probes.sed +++ b/src/backend/utils/Gen_dummy_probes.sed @@ -1,7 +1,7 @@ #------------------------------------------------------------------------- # sed script to create dummy probes.h file when dtrace is not available # -# Copyright (c) 2008-2018, PostgreSQL Global Development Group +# Copyright (c) 2008-2019, PostgreSQL Global Development Group # # src/backend/utils/Gen_dummy_probes.sed #------------------------------------------------------------------------- diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl index 4f5af79d0b5..80e99189e4f 100644 --- a/src/backend/utils/Gen_fmgrtab.pl +++ b/src/backend/utils/Gen_fmgrtab.pl @@ -5,7 +5,7 @@ # Perl script that generates fmgroids.h, fmgrprotos.h, and fmgrtab.c # from pg_proc.dat # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # @@ -18,32 +18,14 @@ use strict; use warnings; +use Getopt::Long; -# Collect arguments -my @input_files; my $output_path = ''; -my @include_path; +my $include_path; -while (@ARGV) -{ - my $arg = shift @ARGV; - if ($arg !~ /^-/) - { - push @input_files, $arg; - } - elsif ($arg =~ /^-o/) - { - $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; - } - elsif ($arg =~ /^-I/) - { - push @include_path, length($arg) > 2 ? substr($arg, 2) : shift @ARGV; - } - else - { - usage(); - } -} +GetOptions( + 'output:s' => \$output_path, + 'include-path:s' => \$include_path) || usage(); # Make sure output_path ends in a slash. if ($output_path ne '' && substr($output_path, -1) ne '/') @@ -52,23 +34,25 @@ } # Sanity check arguments. -die "No input files.\n" if !@input_files; -die "No include path; you must specify -I at least once.\n" if !@include_path; +die "No input files.\n" unless @ARGV; +die "--include-path must be specified.\n" unless $include_path; # Read all the input files into internal data structures. # Note: We pass data file names as arguments and then look for matching # headers to parse the schema from. This is backwards from genbki.pl, # but the Makefile dependencies look more sensible this way. +# We currently only need pg_proc, but retain the possibility of reading +# more than one data file. my %catalogs; my %catalog_data; -foreach my $datfile (@input_files) +foreach my $datfile (@ARGV) { $datfile =~ /(.+)\.dat$/ or die "Input files need to be data (.dat) files.\n"; my $header = "$1.h"; die "There in no header file corresponding to $datfile" - if ! -e $header; + if !-e $header; my $catalog = Catalog::ParseHeader($header); my $catname = $catalog->{catname}; @@ -78,14 +62,6 @@ $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0); } -# Fetch some values for later. -my $FirstBootstrapObjectId = Catalog::FindDefinedSymbol( - 'access/transam.h', \@include_path, 'FirstBootstrapObjectId'); -my $INTERNALlanguageId = Catalog::FindDefinedSymbolFromData( - $catalog_data{pg_language}, 'INTERNALlanguageId'); - -print "Generating fmgrtab.c, fmgroids.h, and fmgrprotos.h...\n"; - # Collect certain fields from pg_proc.dat. my @fmgr = (); @@ -94,14 +70,16 @@ my %bki_values = %$row; # Select out just the rows for internal-language procedures. - next if $bki_values{prolang} ne $INTERNALlanguageId; + next if $bki_values{prolang} ne 'internal'; push @fmgr, - { oid => $bki_values{oid}, + { + oid => $bki_values{oid}, strict => $bki_values{proisstrict}, retset => $bki_values{proretset}, nargs => $bki_values{pronargs}, - prosrc => $bki_values{prosrc}, }; + prosrc => $bki_values{prosrc}, + }; } # Emit headers for both files @@ -117,8 +95,8 @@ open my $tfh, '>', $tabfile . $tmpext or die "Could not open $tabfile$tmpext: $!"; -print $ofh -qq|/*------------------------------------------------------------------------- +print $ofh <{oid} <=> $b->{oid} } @fmgr) { print $tfh -" { $s->{oid}, \"$s->{prosrc}\", $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, $s->{prosrc} }"; + " { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }"; - $fmgr_builtin_oid_index[$s->{oid}] = $fmgr_count++; + $fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++; + $last_builtin_oid = $s->{oid}; if ($fmgr_count <= $#fmgr) { @@ -243,31 +223,30 @@ } print $tfh "};\n"; -print $tfh qq| +printf $tfh qq| const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin)); -|; +const Oid fmgr_last_builtin_oid = %u; +|, $last_builtin_oid; -# Create fmgr_builtins_oid_index table. -# -# Note that the array has to be filled up to FirstBootstrapObjectId, -# as we can't rely on zero initialization as 0 is a valid mapping. -print $tfh qq| -const uint16 fmgr_builtin_oid_index[FirstBootstrapObjectId] = { -|; -for (my $i = 0; $i < $FirstBootstrapObjectId; $i++) +# Create fmgr_builtin_oid_index table. +printf $tfh qq| +const uint16 fmgr_builtin_oid_index[%u] = { +|, $last_builtin_oid + 1; + +for (my $i = 0; $i <= $last_builtin_oid; $i++) { my $oid = $fmgr_builtin_oid_index[$i]; - # fmgr_builtin_oid_index is sparse, map nonexistant functions to + # fmgr_builtin_oid_index is sparse, map nonexistent functions to # InvalidOidBuiltinMapping if (not defined $oid) { $oid = 'InvalidOidBuiltinMapping'; } - if ($i + 1 == $FirstBootstrapObjectId) + if ($i == $last_builtin_oid) { print $tfh " $oid\n"; } @@ -280,8 +259,8 @@ # And add the file footers. -print $ofh "\n#endif /* FMGROIDS_H */\n"; -print $pfh "\n#endif /* FMGRPROTOS_H */\n"; +print $ofh "\n#endif\t\t\t\t\t\t\t/* FMGROIDS_H */\n"; +print $pfh "\n#endif\t\t\t\t\t\t\t/* FMGRPROTOS_H */\n"; close($ofh); close($pfh); @@ -295,12 +274,16 @@ sub usage { die <] [path to pg_proc.dat] + +Options: + --output Output directory (default '.') + --include-path Include path in source tree Gen_fmgrtab.pl generates fmgroids.h, fmgrprotos.h, and fmgrtab.c from pg_proc.dat -Report bugs to . +Report bugs to . EOM } diff --git a/src/backend/utils/Makefile b/src/backend/utils/Makefile index 343637af858..c2618e5272a 100644 --- a/src/backend/utils/Makefile +++ b/src/backend/utils/Makefile @@ -2,7 +2,7 @@ # # Makefile for backend/utils # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/backend/utils/Makefile @@ -21,23 +21,22 @@ catalogdir = $(top_srcdir)/src/backend/catalog include $(top_srcdir)/src/backend/common.mk -all: errcodes.h fmgroids.h fmgrprotos.h probes.h +all: distprep probes.h generated-header-symlinks -$(SUBDIRS:%=%-recursive): fmgroids.h fmgrprotos.h +distprep: fmgr-stamp errcodes.h -FMGR_DATA := $(addprefix $(top_srcdir)/src/include/catalog/,\ - pg_language.dat pg_proc.dat \ - ) +.PHONY: generated-header-symlinks -# see notes in src/backend/parser/Makefile -fmgrprotos.h: fmgroids.h - touch $@ +generated-header-symlinks: $(top_builddir)/src/include/utils/header-stamp $(top_builddir)/src/include/utils/probes.h -fmgroids.h: fmgrtab.c - touch $@ +$(SUBDIRS:%=%-recursive): fmgr-stamp errcodes.h -fmgrtab.c: Gen_fmgrtab.pl $(catalogdir)/Catalog.pm $(FMGR_DATA) $(top_srcdir)/src/include/access/transam.h - $(PERL) -I $(catalogdir) $< -I $(top_srcdir)/src/include/ $(FMGR_DATA) +# fmgr-stamp records the last time we ran Gen_fmgrtab.pl. We don't rely on +# the timestamps of the individual output files, because the Perl script +# won't update them if they didn't change (to avoid unnecessary recompiles). +fmgr-stamp: Gen_fmgrtab.pl $(catalogdir)/Catalog.pm $(top_srcdir)/src/include/catalog/pg_proc.dat $(top_srcdir)/src/include/access/transam.h + $(PERL) -I $(catalogdir) $< --include-path=$(top_srcdir)/src/include/ $(top_srcdir)/src/include/catalog/pg_proc.dat + touch $@ errcodes.h: $(top_srcdir)/src/backend/utils/errcodes.txt generate-errcodes.pl $(PERL) $(srcdir)/generate-errcodes.pl $< > $@ @@ -46,15 +45,37 @@ ifneq ($(enable_dtrace), yes) probes.h: Gen_dummy_probes.sed endif +# We editorialize on dtrace's output to the extent of changing the macro +# names (from POSTGRESQL_foo to TRACE_POSTGRESQL_foo) and changing any +# "char *" arguments to "const char *". probes.h: probes.d ifeq ($(enable_dtrace), yes) $(DTRACE) -C -h -s $< -o $@.tmp - sed -e 's/POSTGRESQL_/TRACE_POSTGRESQL_/g' $@.tmp >$@ + sed -e 's/POSTGRESQL_/TRACE_POSTGRESQL_/g' \ + -e 's/( *char \*/(const char */g' \ + -e 's/, *char \*/, const char */g' $@.tmp >$@ rm $@.tmp else sed -f $(srcdir)/Gen_dummy_probes.sed $< >$@ endif +# These generated headers must be symlinked into builddir/src/include/, +# using absolute links for the reasons explained in src/backend/Makefile. +# We use header-stamp to record that we've done this because the symlinks +# themselves may appear older than fmgr-stamp. +$(top_builddir)/src/include/utils/header-stamp: fmgr-stamp errcodes.h + prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \ + cd '$(dir $@)' && for file in fmgroids.h fmgrprotos.h errcodes.h; do \ + rm -f $$file && $(LN_S) "$$prereqdir/$$file" . ; \ + done + touch $@ + +# probes.h is handled differently because it's not in the distribution tarball. +$(top_builddir)/src/include/utils/probes.h: probes.h + cd '$(dir $@)' && rm -f $(notdir $@) && \ + $(LN_S) "../../../$(subdir)/probes.h" . + + .PHONY: install-data install-data: errcodes.txt installdirs $(INSTALL_DATA) $(srcdir)/errcodes.txt '$(DESTDIR)$(datadir)/errcodes.txt' @@ -66,10 +87,10 @@ installdirs: uninstall-data: rm -f $(addprefix '$(DESTDIR)$(datadir)'/, errcodes.txt) -# fmgroids.h, fmgrprotos.h, fmgrtab.c and errcodes.h are in the +# fmgroids.h, fmgrprotos.h, fmgrtab.c, fmgr-stamp, and errcodes.h are in the # distribution tarball, so they are not cleaned here. clean: rm -f probes.h maintainer-clean: clean - rm -f fmgroids.h fmgrprotos.h fmgrtab.c errcodes.h + rm -f fmgroids.h fmgrprotos.h fmgrtab.c fmgr-stamp errcodes.h diff --git a/src/backend/utils/adt/.gitignore b/src/backend/utils/adt/.gitignore new file mode 100644 index 00000000000..48cf941a522 --- /dev/null +++ b/src/backend/utils/adt/.gitignore @@ -0,0 +1,2 @@ +/jsonpath_gram.c +/jsonpath_scan.c diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 4b35dbb8bbc..580043233b3 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -17,11 +17,12 @@ OBJS = acl.o amutils.o arrayfuncs.o array_expanded.o array_selfuncs.o \ float.o format_type.o formatting.o genfile.o \ geo_ops.o geo_selfuncs.o geo_spgist.o inet_cidr_ntop.o inet_net_pton.o \ int.o int8.o json.o jsonb.o jsonb_gin.o jsonb_op.o jsonb_util.o \ - jsonfuncs.o like.o lockfuncs.o mac.o mac8.o misc.o nabstime.o name.o \ + jsonfuncs.o jsonpath_gram.o jsonpath.o jsonpath_exec.o \ + like.o like_support.o lockfuncs.o mac.o mac8.o misc.o name.o \ network.o network_gist.o network_selfuncs.o network_spgist.o \ numeric.o numutils.o oid.o oracle_compat.o \ - orderedsetaggs.o pg_locale.o pg_lsn.o pg_upgrade_support.o \ - pgstatfuncs.o \ + orderedsetaggs.o partitionfuncs.o pg_locale.o pg_lsn.o \ + pg_upgrade_support.o pgstatfuncs.o \ pseudotypes.o quote.o rangetypes.o rangetypes_gist.o \ rangetypes_selfuncs.o rangetypes_spgist.o rangetypes_typanalyze.o \ regexp.o regproc.o ri_triggers.o rowtypes.o ruleutils.o \ @@ -32,6 +33,17 @@ OBJS = acl.o amutils.o arrayfuncs.o array_expanded.o array_selfuncs.o \ txid.o uuid.o varbit.o varchar.o varlena.o version.o \ windowfuncs.o xid.o xml.o +jsonpath_scan.c: FLEXFLAGS = -CF -p -p +jsonpath_scan.c: FLEX_NO_BACKUP=yes + +# jsonpath_scan is compiled as part of jsonpath_gram +jsonpath_gram.o: jsonpath_scan.c + +# jsonpath_gram.c and jsonpath_scan.c are in the distribution tarball, +# so they are not cleaned here. +clean distclean maintainer-clean: + rm -f lex.backup + like.o: like.c like_match.c varlena.o: varlena.c levenshtein.c diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index 0cfc297b659..d7e6100ccbf 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -3,7 +3,7 @@ * acl.c * Basic access control list data structures manipulation routines. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,7 +16,6 @@ #include -#include "access/hash.h" #include "access/htup_details.h" #include "catalog/catalog.h" #include "catalog/namespace.h" @@ -31,8 +30,10 @@ #include "funcapi.h" #include "miscadmin.h" #include "utils/acl.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/catcache.h" +#include "utils/hashutils.h" #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -86,13 +87,13 @@ static const char *aclparse(const char *s, AclItem *aip); static bool aclitem_match(const AclItem *a1, const AclItem *a2); static int aclitemComparator(const void *arg1, const void *arg2); static void check_circularity(const Acl *old_acl, const AclItem *mod_aip, - Oid ownerId); + Oid ownerId); static Acl *recursive_revoke(Acl *acl, Oid grantee, AclMode revoke_privs, - Oid ownerId, DropBehavior behavior); + Oid ownerId, DropBehavior behavior); static AclMode convert_priv_string(text *priv_type_text); static AclMode convert_any_priv_string(text *priv_type_text, - const priv_map *privileges); + const priv_map *privileges); static Oid convert_table_name(text *tablename); static AclMode convert_table_priv_string(text *priv_type_text); @@ -855,8 +856,7 @@ acldefault(ObjectType objtype, Oid ownerId) /* * SQL-accessible version of acldefault(). Hackish mapping from "char" type to - * OBJECT_* values, but it's only used in the information schema, not - * documented for general use. + * OBJECT_* values. */ Datum acldefault_sql(PG_FUNCTION_ARGS) @@ -1764,7 +1764,7 @@ aclexplode(PG_FUNCTION_ARGS) * build tupdesc for result tuples (matches out parameters in pg_proc * entry) */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "grantor", OIDOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "grantee", @@ -2448,8 +2448,12 @@ has_any_column_privilege_id_id(PG_FUNCTION_ARGS) * * The result is a boolean value: true if user has the indicated * privilege, false if not. The variants that take a relation OID - * and an integer attnum return NULL (rather than throwing an error) - * if the column doesn't exist or is dropped. + * return NULL (rather than throwing an error) if that relation OID + * doesn't exist. Likewise, the variants that take an integer attnum + * return NULL (rather than throwing an error) if there is no such + * pg_attribute entry. All variants return NULL if an attisdropped + * column is selected. These rules are meant to avoid unnecessary + * failures in queries that scan pg_attribute. */ /* @@ -2466,6 +2470,12 @@ column_privilege_check(Oid tableoid, AttrNumber attnum, HeapTuple attTuple; Form_pg_attribute attributeForm; + /* + * If convert_column_name failed, we can just return -1 immediately. + */ + if (attnum == InvalidAttrNumber) + return -1; + /* * First check if we have the privilege at the table level. We check * existence of the pg_class row before risking calling pg_class_aclcheck. @@ -2827,21 +2837,59 @@ has_column_privilege_id_attnum(PG_FUNCTION_ARGS) /* * Given a table OID and a column name expressed as a string, look it up - * and return the column number + * and return the column number. Returns InvalidAttrNumber in cases + * where caller should return NULL instead of failing. */ static AttrNumber convert_column_name(Oid tableoid, text *column) { - AttrNumber attnum; char *colname; + HeapTuple attTuple; + AttrNumber attnum; colname = text_to_cstring(column); - attnum = get_attnum(tableoid, colname); - if (attnum == InvalidAttrNumber) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_COLUMN), - errmsg("column \"%s\" of relation \"%s\" does not exist", - colname, get_rel_name(tableoid)))); + + /* + * We don't use get_attnum() here because it will report that dropped + * columns don't exist. We need to treat dropped columns differently from + * nonexistent columns. + */ + attTuple = SearchSysCache2(ATTNAME, + ObjectIdGetDatum(tableoid), + CStringGetDatum(colname)); + if (HeapTupleIsValid(attTuple)) + { + Form_pg_attribute attributeForm; + + attributeForm = (Form_pg_attribute) GETSTRUCT(attTuple); + /* We want to return NULL for dropped columns */ + if (attributeForm->attisdropped) + attnum = InvalidAttrNumber; + else + attnum = attributeForm->attnum; + ReleaseSysCache(attTuple); + } + else + { + char *tablename = get_rel_name(tableoid); + + /* + * If the table OID is bogus, or it's just been dropped, we'll get + * NULL back. In such cases we want has_column_privilege to return + * NULL too, so just return InvalidAttrNumber. + */ + if (tablename != NULL) + { + /* tableoid exists, colname does not, so throw error */ + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" of relation \"%s\" does not exist", + colname, tablename))); + } + /* tableoid doesn't exist, so act like attisdropped case */ + attnum = InvalidAttrNumber; + } + pfree(colname); return attnum; } @@ -3145,6 +3193,9 @@ has_foreign_data_wrapper_privilege_name_id(PG_FUNCTION_ARGS) roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -3168,6 +3219,9 @@ has_foreign_data_wrapper_privilege_id(PG_FUNCTION_ARGS) roleid = GetUserId(); mode = convert_foreign_data_wrapper_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -3212,6 +3266,9 @@ has_foreign_data_wrapper_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_foreign_data_wrapper_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fdwid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_data_wrapper_aclcheck(fdwid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -3911,6 +3968,9 @@ has_server_privilege_name_id(PG_FUNCTION_ARGS) roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_server_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -3934,6 +3994,9 @@ has_server_privilege_id(PG_FUNCTION_ARGS) roleid = GetUserId(); mode = convert_server_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -3978,6 +4041,9 @@ has_server_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_server_priv_string(priv_type_text); + if (!SearchSysCacheExists1(FOREIGNSERVEROID, ObjectIdGetDatum(serverid))) + PG_RETURN_NULL(); + aclresult = pg_foreign_server_aclcheck(serverid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -4093,6 +4159,9 @@ has_tablespace_privilege_name_id(PG_FUNCTION_ARGS) roleid = get_role_oid_or_public(NameStr(*username)); mode = convert_tablespace_priv_string(priv_type_text); + if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid))) + PG_RETURN_NULL(); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -4116,6 +4185,9 @@ has_tablespace_privilege_id(PG_FUNCTION_ARGS) roleid = GetUserId(); mode = convert_tablespace_priv_string(priv_type_text); + if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid))) + PG_RETURN_NULL(); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -4160,6 +4232,9 @@ has_tablespace_privilege_id_id(PG_FUNCTION_ARGS) mode = convert_tablespace_priv_string(priv_type_text); + if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tablespaceoid))) + PG_RETURN_NULL(); + aclresult = pg_tablespace_aclcheck(tablespaceoid, roleid, mode); PG_RETURN_BOOL(aclresult == ACLCHECK_OK); @@ -5117,7 +5192,8 @@ get_role_oid(const char *rolname, bool missing_ok) { Oid oid; - oid = GetSysCacheOid1(AUTHNAME, CStringGetDatum(rolname)); + oid = GetSysCacheOid1(AUTHNAME, Anum_pg_authid_oid, + CStringGetDatum(rolname)); if (!OidIsValid(oid) && !missing_ok) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), @@ -5216,6 +5292,7 @@ get_rolespec_tuple(const RoleSpec *role) (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("role \"%s\" does not exist", "public"))); tuple = NULL; /* make compiler happy */ + break; default: elog(ERROR, "unexpected role type %d", role->roletype); diff --git a/src/backend/utils/adt/amutils.c b/src/backend/utils/adt/amutils.c index 0f8ad4ef0fa..e81d6cc0562 100644 --- a/src/backend/utils/adt/amutils.c +++ b/src/backend/utils/adt/amutils.c @@ -3,7 +3,7 @@ * amutils.c * SQL-level APIs related to index access methods. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -187,8 +187,8 @@ indexam_property(FunctionCallInfo fcinfo, } /* - * At this point, either index_oid == InvalidOid or it's a valid index OID. - * Also, after this test and the one below, either attno == 0 for + * At this point, either index_oid == InvalidOid or it's a valid index + * OID. Also, after this test and the one below, either attno == 0 for * index-wide or AM-wide tests, or it's a valid column number in a valid * index. */ @@ -276,6 +276,7 @@ indexam_property(FunctionCallInfo fcinfo, break; case AMPROP_ORDERABLE: + /* * generic assumption is that nonkey columns are not orderable */ @@ -293,8 +294,9 @@ indexam_property(FunctionCallInfo fcinfo, * getting there from just the index column type seems like a * lot of work. So instead we expect the AM to handle this in * its amproperty routine. The generic result is to return - * false if the AM says it never supports this, or if this is a - * nonkey column, and null otherwise (meaning we don't know). + * false if the AM says it never supports this, or if this is + * a nonkey column, and null otherwise (meaning we don't + * know). */ if (!iskey || !routine->amcanorderbyop) { @@ -314,8 +316,8 @@ indexam_property(FunctionCallInfo fcinfo, { /* * If possible, the AM should handle this test in its - * amproperty function without opening the rel. But this is the - * generic fallback if it does not. + * amproperty function without opening the rel. But this + * is the generic fallback if it does not. */ Relation indexrel = index_open(index_oid, AccessShareLock); @@ -443,3 +445,26 @@ pg_index_column_has_property(PG_FUNCTION_ARGS) return indexam_property(fcinfo, propname, InvalidOid, relid, attno); } + +/* + * Return the name of the given phase, as used for progress reporting by the + * given AM. + */ +Datum +pg_indexam_progress_phasename(PG_FUNCTION_ARGS) +{ + Oid amoid = PG_GETARG_OID(0); + int32 phasenum = PG_GETARG_INT32(1); + IndexAmRoutine *routine; + char *name; + + routine = GetIndexAmRoutineByAmId(amoid, true); + if (routine == NULL || !routine->ambuildphasename) + PG_RETURN_NULL(); + + name = routine->ambuildphasename(phasenum); + if (!name) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(CStringGetTextDatum(name)); +} diff --git a/src/backend/utils/adt/array_expanded.c b/src/backend/utils/adt/array_expanded.c index 277aaf13688..3df14f93900 100644 --- a/src/backend/utils/adt/array_expanded.c +++ b/src/backend/utils/adt/array_expanded.c @@ -3,7 +3,7 @@ * array_expanded.c * Basic functions for manipulating expanded arrays. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -23,7 +23,7 @@ /* "Methods" required for an expanded object */ static Size EA_get_flat_size(ExpandedObjectHeader *eohptr); static void EA_flatten_into(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size); + void *result, Size allocated_size); static const ExpandedObjectMethods EA_methods = { @@ -33,7 +33,7 @@ static const ExpandedObjectMethods EA_methods = /* Other local functions */ static void copy_byval_expanded_array(ExpandedArrayHeader *eah, - ExpandedArrayHeader *oldeah); + ExpandedArrayHeader *oldeah); /* diff --git a/src/backend/utils/adt/array_selfuncs.c b/src/backend/utils/adt/array_selfuncs.c index 339525b53b5..a0ac9492850 100644 --- a/src/backend/utils/adt/array_selfuncs.c +++ b/src/backend/utils/adt/array_selfuncs.c @@ -3,7 +3,7 @@ * array_selfuncs.c * Functions for selectivity estimation of array operators * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,7 +20,6 @@ #include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "catalog/pg_statistic.h" -#include "optimizer/clauses.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -40,27 +39,27 @@ DEFAULT_OVERLAP_SEL : DEFAULT_CONTAIN_SEL) static Selectivity calc_arraycontsel(VariableStatData *vardata, Datum constval, - Oid elemtype, Oid operator); + Oid elemtype, Oid operator); static Selectivity mcelem_array_selec(ArrayType *array, - TypeCacheEntry *typentry, - Datum *mcelem, int nmcelem, - float4 *numbers, int nnumbers, - float4 *hist, int nhist, - Oid operator, FmgrInfo *cmpfunc); + TypeCacheEntry *typentry, + Datum *mcelem, int nmcelem, + float4 *numbers, int nnumbers, + float4 *hist, int nhist, + Oid operator); static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, - float4 *numbers, int nnumbers, - Datum *array_data, int nitems, - Oid operator, FmgrInfo *cmpfunc); + float4 *numbers, int nnumbers, + Datum *array_data, int nitems, + Oid operator, TypeCacheEntry *typentry); static Selectivity mcelem_array_contained_selec(Datum *mcelem, int nmcelem, - float4 *numbers, int nnumbers, - Datum *array_data, int nitems, - float4 *hist, int nhist, - Oid operator, FmgrInfo *cmpfunc); + float4 *numbers, int nnumbers, + Datum *array_data, int nitems, + float4 *hist, int nhist, + Oid operator, TypeCacheEntry *typentry); static float *calc_hist(const float4 *hist, int nhist, int n); static float *calc_distr(const float *p, int n, int m, float rest); static int floor_log2(uint32 n); static bool find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, - int *index, FmgrInfo *cmpfunc); + int *index, TypeCacheEntry *typentry); static int element_compare(const void *key1, const void *key2, void *arg); static int float_compare_desc(const void *key1, const void *key2); @@ -166,7 +165,7 @@ scalararraysel_containment(PlannerInfo *root, sslot.nnumbers, &constval, 1, OID_ARRAY_CONTAINS_OP, - cmpfunc); + typentry); else selec = mcelem_array_contained_selec(sslot.values, sslot.nvalues, @@ -176,7 +175,7 @@ scalararraysel_containment(PlannerInfo *root, hslot.numbers, hslot.nnumbers, OID_ARRAY_CONTAINED_OP, - cmpfunc); + typentry); free_attstatsslot(&hslot); free_attstatsslot(&sslot); @@ -189,14 +188,14 @@ scalararraysel_containment(PlannerInfo *root, NULL, 0, &constval, 1, OID_ARRAY_CONTAINS_OP, - cmpfunc); + typentry); else selec = mcelem_array_contained_selec(NULL, 0, NULL, 0, &constval, 1, NULL, 0, OID_ARRAY_CONTAINED_OP, - cmpfunc); + typentry); } /* @@ -212,14 +211,14 @@ scalararraysel_containment(PlannerInfo *root, NULL, 0, &constval, 1, OID_ARRAY_CONTAINS_OP, - cmpfunc); + typentry); else selec = mcelem_array_contained_selec(NULL, 0, NULL, 0, &constval, 1, NULL, 0, OID_ARRAY_CONTAINED_OP, - cmpfunc); + typentry); /* we assume no nulls here, so no stanullfrac correction */ } @@ -385,7 +384,7 @@ calc_arraycontsel(VariableStatData *vardata, Datum constval, sslot.values, sslot.nvalues, sslot.numbers, sslot.nnumbers, hslot.numbers, hslot.nnumbers, - operator, cmpfunc); + operator); free_attstatsslot(&hslot); free_attstatsslot(&sslot); @@ -395,7 +394,7 @@ calc_arraycontsel(VariableStatData *vardata, Datum constval, /* No most-common-elements info, so do without */ selec = mcelem_array_selec(array, typentry, NULL, 0, NULL, 0, NULL, 0, - operator, cmpfunc); + operator); } /* @@ -408,7 +407,7 @@ calc_arraycontsel(VariableStatData *vardata, Datum constval, /* No stats at all, so do without */ selec = mcelem_array_selec(array, typentry, NULL, 0, NULL, 0, NULL, 0, - operator, cmpfunc); + operator); /* we assume no nulls here, so no stanullfrac correction */ } @@ -431,7 +430,7 @@ mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry, Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, float4 *hist, int nhist, - Oid operator, FmgrInfo *cmpfunc) + Oid operator) { Selectivity selec; int num_elems; @@ -476,20 +475,20 @@ mcelem_array_selec(ArrayType *array, TypeCacheEntry *typentry, /* Sort extracted elements using their default comparison function. */ qsort_arg(elem_values, nonnull_nitems, sizeof(Datum), - element_compare, cmpfunc); + element_compare, typentry); /* Separate cases according to operator */ if (operator == OID_ARRAY_CONTAINS_OP || operator == OID_ARRAY_OVERLAP_OP) selec = mcelem_array_contain_overlap_selec(mcelem, nmcelem, numbers, nnumbers, elem_values, nonnull_nitems, - operator, cmpfunc); + operator, typentry); else if (operator == OID_ARRAY_CONTAINED_OP) selec = mcelem_array_contained_selec(mcelem, nmcelem, numbers, nnumbers, elem_values, nonnull_nitems, hist, nhist, - operator, cmpfunc); + operator, typentry); else { elog(ERROR, "arraycontsel called for unrecognized operator %u", @@ -523,7 +522,7 @@ static Selectivity mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, - Oid operator, FmgrInfo *cmpfunc) + Oid operator, TypeCacheEntry *typentry) { Selectivity selec, elem_selec; @@ -586,14 +585,14 @@ mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, /* Ignore any duplicates in the array data. */ if (i > 0 && - element_compare(&array_data[i - 1], &array_data[i], cmpfunc) == 0) + element_compare(&array_data[i - 1], &array_data[i], typentry) == 0) continue; /* Find the smallest MCELEM >= this array item. */ if (use_bsearch) { match = find_next_mcelem(mcelem, nmcelem, array_data[i], - &mcelem_index, cmpfunc); + &mcelem_index, typentry); } else { @@ -601,7 +600,7 @@ mcelem_array_contain_overlap_selec(Datum *mcelem, int nmcelem, { int cmp = element_compare(&mcelem[mcelem_index], &array_data[i], - cmpfunc); + typentry); if (cmp < 0) mcelem_index++; @@ -699,7 +698,7 @@ mcelem_array_contained_selec(Datum *mcelem, int nmcelem, float4 *numbers, int nnumbers, Datum *array_data, int nitems, float4 *hist, int nhist, - Oid operator, FmgrInfo *cmpfunc) + Oid operator, TypeCacheEntry *typentry) { int mcelem_index, i, @@ -765,7 +764,7 @@ mcelem_array_contained_selec(Datum *mcelem, int nmcelem, /* Ignore any duplicates in the array data. */ if (i > 0 && - element_compare(&array_data[i - 1], &array_data[i], cmpfunc) == 0) + element_compare(&array_data[i - 1], &array_data[i], typentry) == 0) continue; /* @@ -777,7 +776,7 @@ mcelem_array_contained_selec(Datum *mcelem, int nmcelem, { int cmp = element_compare(&mcelem[mcelem_index], &array_data[i], - cmpfunc); + typentry); if (cmp < 0) { @@ -1130,7 +1129,7 @@ floor_log2(uint32 n) */ static bool find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index, - FmgrInfo *cmpfunc) + TypeCacheEntry *typentry) { int l = *index, r = nmcelem - 1, @@ -1140,7 +1139,7 @@ find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index, while (l <= r) { i = (l + r) / 2; - res = element_compare(&mcelem[i], &value, cmpfunc); + res = element_compare(&mcelem[i], &value, typentry); if (res == 0) { *index = i; @@ -1158,7 +1157,7 @@ find_next_mcelem(Datum *mcelem, int nmcelem, Datum value, int *index, /* * Comparison function for elements. * - * We use the element type's default btree opclass, and the default collation + * We use the element type's default btree opclass, and its default collation * if the type is collation-sensitive. * * XXX consider using SortSupport infrastructure @@ -1168,10 +1167,11 @@ element_compare(const void *key1, const void *key2, void *arg) { Datum d1 = *((const Datum *) key1); Datum d2 = *((const Datum *) key2); - FmgrInfo *cmpfunc = (FmgrInfo *) arg; + TypeCacheEntry *typentry = (TypeCacheEntry *) arg; + FmgrInfo *cmpfunc = &typentry->cmp_proc_finfo; Datum c; - c = FunctionCall2Coll(cmpfunc, DEFAULT_COLLATION_OID, d1, d2); + c = FunctionCall2Coll(cmpfunc, typentry->typcollation, d1, d2); return DatumGetInt32(c); } diff --git a/src/backend/utils/adt/array_typanalyze.c b/src/backend/utils/adt/array_typanalyze.c index 92e38b870f5..54f58496290 100644 --- a/src/backend/utils/adt/array_typanalyze.c +++ b/src/backend/utils/adt/array_typanalyze.c @@ -3,7 +3,7 @@ * array_typanalyze.c * Functions for gathering statistics from array columns * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,8 +14,7 @@ */ #include "postgres.h" -#include "access/tuptoaster.h" -#include "catalog/pg_collation.h" +#include "access/detoast.h" #include "commands/vacuum.h" #include "utils/array.h" #include "utils/builtins.h" @@ -39,6 +38,7 @@ typedef struct /* Information about array element type */ Oid type_id; /* element type's OID */ Oid eq_opr; /* default equality operator's OID */ + Oid coll_id; /* collation to use */ bool typbyval; /* physical properties of element type */ int16 typlen; char typalign; @@ -81,7 +81,7 @@ typedef struct } DECountItem; static void compute_array_stats(VacAttrStats *stats, - AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows); + AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows); static void prune_element_hashtable(HTAB *elements_tab, int b_current); static uint32 element_hash(const void *key, Size keysize); static int element_match(const void *key1, const void *key2, Size keysize); @@ -135,6 +135,7 @@ array_typanalyze(PG_FUNCTION_ARGS) extra_data = (ArrayAnalyzeExtraData *) palloc(sizeof(ArrayAnalyzeExtraData)); extra_data->type_id = typentry->type_id; extra_data->eq_opr = typentry->eq_opr; + extra_data->coll_id = stats->attrcollid; /* collation we should use */ extra_data->typbyval = typentry->typbyval; extra_data->typlen = typentry->typlen; extra_data->typalign = typentry->typalign; @@ -560,6 +561,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, stats->stakind[slot_idx] = STATISTIC_KIND_MCELEM; stats->staop[slot_idx] = extra_data->eq_opr; + stats->stacoll[slot_idx] = extra_data->coll_id; stats->stanumbers[slot_idx] = mcelem_freqs; /* See above comment about extra stanumber entries */ stats->numnumbers[slot_idx] = num_mcelem + 3; @@ -661,6 +663,7 @@ compute_array_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, stats->stakind[slot_idx] = STATISTIC_KIND_DECHIST; stats->staop[slot_idx] = extra_data->eq_opr; + stats->stacoll[slot_idx] = extra_data->coll_id; stats->stanumbers[slot_idx] = hist; stats->numnumbers[slot_idx] = num_hist + 1; slot_idx++; @@ -703,7 +706,7 @@ prune_element_hashtable(HTAB *elements_tab, int b_current) /* * Hash function for elements. * - * We use the element type's default hash opclass, and the default collation + * We use the element type's default hash opclass, and the column collation * if the type is collation-sensitive. */ static uint32 @@ -712,7 +715,9 @@ element_hash(const void *key, Size keysize) Datum d = *((const Datum *) key); Datum h; - h = FunctionCall1Coll(array_extra_data->hash, DEFAULT_COLLATION_OID, d); + h = FunctionCall1Coll(array_extra_data->hash, + array_extra_data->coll_id, + d); return DatumGetUInt32(h); } @@ -729,7 +734,7 @@ element_match(const void *key1, const void *key2, Size keysize) /* * Comparison function for elements. * - * We use the element type's default btree opclass, and the default collation + * We use the element type's default btree opclass, and the column collation * if the type is collation-sensitive. * * XXX consider using SortSupport infrastructure @@ -741,7 +746,9 @@ element_compare(const void *key1, const void *key2) Datum d2 = *((const Datum *) key2); Datum c; - c = FunctionCall2Coll(array_extra_data->cmp, DEFAULT_COLLATION_OID, d1, d2); + c = FunctionCall2Coll(array_extra_data->cmp, + array_extra_data->coll_id, + d1, d2); return DatumGetInt32(c); } diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c index cb7a6b6d010..470a480fdd0 100644 --- a/src/backend/utils/adt/array_userfuncs.c +++ b/src/backend/utils/adt/array_userfuncs.c @@ -3,7 +3,7 @@ * array_userfuncs.c * Misc user-visible array support functions * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/array_userfuncs.c diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index 0cbdbe5587e..8079b13ba50 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -3,7 +3,7 @@ * arrayfuncs.c * Support functions for arrays. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,22 +15,22 @@ #include "postgres.h" #include -#ifdef _MSC_VER -#include /* for _isnan */ -#endif #include -#include "access/hash.h" #include "access/htup_details.h" #include "catalog/pg_type.h" #include "funcapi.h" #include "libpq/pqformat.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" +#include "optimizer/optimizer.h" #include "utils/array.h" #include "utils/arrayaccess.h" #include "utils/builtins.h" #include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/selfuncs.h" #include "utils/typcache.h" @@ -90,74 +90,74 @@ typedef struct ArrayIteratorData static bool array_isspace(char ch); static int ArrayCount(const char *str, int *dim, char typdelim); static void ReadArrayStr(char *arrayStr, const char *origStr, - int nitems, int ndim, int *dim, - FmgrInfo *inputproc, Oid typioparam, int32 typmod, - char typdelim, - int typlen, bool typbyval, char typalign, - Datum *values, bool *nulls, - bool *hasnulls, int32 *nbytes); + int nitems, int ndim, int *dim, + FmgrInfo *inputproc, Oid typioparam, int32 typmod, + char typdelim, + int typlen, bool typbyval, char typalign, + Datum *values, bool *nulls, + bool *hasnulls, int32 *nbytes); static void ReadArrayBinary(StringInfo buf, int nitems, - FmgrInfo *receiveproc, Oid typioparam, int32 typmod, - int typlen, bool typbyval, char typalign, - Datum *values, bool *nulls, - bool *hasnulls, int32 *nbytes); + FmgrInfo *receiveproc, Oid typioparam, int32 typmod, + int typlen, bool typbyval, char typalign, + Datum *values, bool *nulls, + bool *hasnulls, int32 *nbytes); static Datum array_get_element_expanded(Datum arraydatum, - int nSubscripts, int *indx, - int arraytyplen, - int elmlen, bool elmbyval, char elmalign, - bool *isNull); + int nSubscripts, int *indx, + int arraytyplen, + int elmlen, bool elmbyval, char elmalign, + bool *isNull); static Datum array_set_element_expanded(Datum arraydatum, - int nSubscripts, int *indx, - Datum dataValue, bool isNull, - int arraytyplen, - int elmlen, bool elmbyval, char elmalign); + int nSubscripts, int *indx, + Datum dataValue, bool isNull, + int arraytyplen, + int elmlen, bool elmbyval, char elmalign); static bool array_get_isnull(const bits8 *nullbitmap, int offset); static void array_set_isnull(bits8 *nullbitmap, int offset, bool isNull); static Datum ArrayCast(char *value, bool byval, int len); -static int ArrayCastAndSet(Datum src, - int typlen, bool typbyval, char typalign, - char *dest); +static int ArrayCastAndSet(Datum src, + int typlen, bool typbyval, char typalign, + char *dest); static char *array_seek(char *ptr, int offset, bits8 *nullbitmap, int nitems, - int typlen, bool typbyval, char typalign); -static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, - int nitems, int typlen, bool typbyval, char typalign); -static int array_copy(char *destptr, int nitems, - char *srcptr, int offset, bits8 *nullbitmap, - int typlen, bool typbyval, char typalign); -static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, - int ndim, int *dim, int *lb, - int *st, int *endp, - int typlen, bool typbyval, char typalign); + int typlen, bool typbyval, char typalign); +static int array_nelems_size(char *ptr, int offset, bits8 *nullbitmap, + int nitems, int typlen, bool typbyval, char typalign); +static int array_copy(char *destptr, int nitems, + char *srcptr, int offset, bits8 *nullbitmap, + int typlen, bool typbyval, char typalign); +static int array_slice_size(char *arraydataptr, bits8 *arraynullsptr, + int ndim, int *dim, int *lb, + int *st, int *endp, + int typlen, bool typbyval, char typalign); static void array_extract_slice(ArrayType *newarray, - int ndim, int *dim, int *lb, - char *arraydataptr, bits8 *arraynullsptr, - int *st, int *endp, - int typlen, bool typbyval, char typalign); + int ndim, int *dim, int *lb, + char *arraydataptr, bits8 *arraynullsptr, + int *st, int *endp, + int typlen, bool typbyval, char typalign); static void array_insert_slice(ArrayType *destArray, ArrayType *origArray, - ArrayType *srcArray, - int ndim, int *dim, int *lb, - int *st, int *endp, - int typlen, bool typbyval, char typalign); + ArrayType *srcArray, + int ndim, int *dim, int *lb, + int *st, int *endp, + int typlen, bool typbyval, char typalign); static int array_cmp(FunctionCallInfo fcinfo); -static ArrayType *create_array_envelope(int ndims, int *dimv, int *lbv, int nbytes, - Oid elmtype, int dataoffset); +static ArrayType *create_array_envelope(int ndims, int *dimv, int *lbsv, int nbytes, + Oid elmtype, int dataoffset); static ArrayType *array_fill_internal(ArrayType *dims, ArrayType *lbs, - Datum value, bool isnull, Oid elmtype, - FunctionCallInfo fcinfo); + Datum value, bool isnull, Oid elmtype, + FunctionCallInfo fcinfo); static ArrayType *array_replace_internal(ArrayType *array, - Datum search, bool search_isnull, - Datum replace, bool replace_isnull, - bool remove, Oid collation, - FunctionCallInfo fcinfo); + Datum search, bool search_isnull, + Datum replace, bool replace_isnull, + bool remove, Oid collation, + FunctionCallInfo fcinfo); static int width_bucket_array_float8(Datum operand, ArrayType *thresholds); -static int width_bucket_array_fixed(Datum operand, - ArrayType *thresholds, - Oid collation, - TypeCacheEntry *typentry); -static int width_bucket_array_variable(Datum operand, - ArrayType *thresholds, - Oid collation, - TypeCacheEntry *typentry); +static int width_bucket_array_fixed(Datum operand, + ArrayType *thresholds, + Oid collation, + TypeCacheEntry *typentry); +static int width_bucket_array_variable(Datum operand, + ArrayType *thresholds, + Oid collation, + TypeCacheEntry *typentry); /* @@ -1030,8 +1030,8 @@ array_out(PG_FUNCTION_ARGS) */ bool *needquotes, needdims = false; + size_t overall_length; int nitems, - overall_length, i, j, k, @@ -1105,7 +1105,7 @@ array_out(PG_FUNCTION_ARGS) */ values = (char **) palloc(nitems * sizeof(char *)); needquotes = (bool *) palloc(nitems * sizeof(bool)); - overall_length = 1; /* don't forget to count \0 at end. */ + overall_length = 0; array_iter_setup(&iter, v); @@ -1158,19 +1158,24 @@ array_out(PG_FUNCTION_ARGS) /* Count the pair of double quotes, if needed */ if (needquote) overall_length += 2; - /* and the comma */ + /* and the comma (or other typdelim delimiter) */ overall_length += 1; } /* - * count total number of curly braces in output string + * The very last array element doesn't have a typdelim delimiter after it, + * but that's OK; that space is needed for the trailing '\0'. + * + * Now count total number of curly brace pairs in output string. */ for (i = j = 0, k = 1; i < ndim; i++) - k *= dims[i], j += k; + { + j += k, k *= dims[i]; + } + overall_length += 2 * j; + /* Format explicit dimensions if required */ dims_str[0] = '\0'; - - /* add explicit dimensions if required */ if (needdims) { char *ptr = dims_str; @@ -1182,9 +1187,11 @@ array_out(PG_FUNCTION_ARGS) } *ptr++ = *ASSGN; *ptr = '\0'; + overall_length += ptr - dims_str; } - retval = (char *) palloc(strlen(dims_str) + overall_length + 2 * j); + /* Now construct the output string */ + retval = (char *) palloc(overall_length); p = retval; #define APPENDSTR(str) (strcpy(p, (str)), p += strlen(p)) @@ -1222,14 +1229,16 @@ array_out(PG_FUNCTION_ARGS) for (i = ndim - 1; i >= 0; i--) { - indx[i] = (indx[i] + 1) % dims[i]; - if (indx[i]) + if (++(indx[i]) < dims[i]) { APPENDCHAR(typdelim); break; } else + { + indx[i] = 0; APPENDCHAR('}'); + } } j = i; } while (j != -1); @@ -1237,6 +1246,9 @@ array_out(PG_FUNCTION_ARGS) #undef APPENDSTR #undef APPENDCHAR + /* Assert that we calculated the string length accurately */ + Assert(overall_length == (p - retval + 1)); + pfree(values); pfree(needquotes); @@ -1310,7 +1322,7 @@ array_recv(PG_FUNCTION_ARGS) lBound[i] = pq_getmsgint(buf, 4); /* - * Check overflow of upper bound. (ArrayNItems() below checks that + * Check overflow of upper bound. (ArrayGetNItems() below checks that * dim[i] >= 0) */ if (dim[i] != 0) @@ -1985,7 +1997,7 @@ array_get_element_expanded(Datum arraydatum, /* * array_get_slice : - * This routine takes an array and a range of indices (upperIndex and + * This routine takes an array and a range of indices (upperIndx and * lowerIndx), creates a new array structure for the referred elements * and returns a pointer to it. * @@ -3562,6 +3574,7 @@ array_contains_nulls(ArrayType *array) Datum array_eq(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(locfcinfo, 2); AnyArrayType *array1 = PG_GETARG_ANY_ARRAY_P(0); AnyArrayType *array2 = PG_GETARG_ANY_ARRAY_P(1); Oid collation = PG_GET_COLLATION(); @@ -3581,7 +3594,6 @@ array_eq(PG_FUNCTION_ARGS) array_iter it1; array_iter it2; int i; - FunctionCallInfoData locfcinfo; if (element_type != AARR_ELEMTYPE(array2)) ereport(ERROR, @@ -3621,7 +3633,7 @@ array_eq(PG_FUNCTION_ARGS) /* * apply the operator to each pair of array elements. */ - InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2, collation, NULL, NULL); /* Loop over source data */ @@ -3657,12 +3669,12 @@ array_eq(PG_FUNCTION_ARGS) /* * Apply the operator to the element pair */ - locfcinfo.arg[0] = elt1; - locfcinfo.arg[1] = elt2; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt1; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = elt2; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo)); if (!oprresult) { result = false; @@ -3733,6 +3745,7 @@ btarraycmp(PG_FUNCTION_ARGS) static int array_cmp(FunctionCallInfo fcinfo) { + LOCAL_FCINFO(locfcinfo, 2); AnyArrayType *array1 = PG_GETARG_ANY_ARRAY_P(0); AnyArrayType *array2 = PG_GETARG_ANY_ARRAY_P(1); Oid collation = PG_GET_COLLATION(); @@ -3752,7 +3765,6 @@ array_cmp(FunctionCallInfo fcinfo) array_iter it1; array_iter it2; int i; - FunctionCallInfoData locfcinfo; if (element_type != AARR_ELEMTYPE(array2)) ereport(ERROR, @@ -3785,7 +3797,7 @@ array_cmp(FunctionCallInfo fcinfo) /* * apply the operator to each pair of array elements. */ - InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2, collation, NULL, NULL); /* Loop over source data */ @@ -3824,12 +3836,12 @@ array_cmp(FunctionCallInfo fcinfo) } /* Compare the pair of elements */ - locfcinfo.arg[0] = elt1; - locfcinfo.arg[1] = elt2; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt1; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = elt2; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo)); if (cmpresult == 0) continue; /* equal */ @@ -3904,6 +3916,7 @@ array_cmp(FunctionCallInfo fcinfo) Datum hash_array(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(locfcinfo, 1); AnyArrayType *array = PG_GETARG_ANY_ARRAY_P(0); int ndims = AARR_NDIM(array); int *dims = AARR_DIMS(array); @@ -3916,7 +3929,6 @@ hash_array(PG_FUNCTION_ARGS) char typalign; int i; array_iter iter; - FunctionCallInfoData locfcinfo; /* * We arrange to look up the hash function only once per series of calls, @@ -3944,8 +3956,8 @@ hash_array(PG_FUNCTION_ARGS) /* * apply the hash function to each array element. */ - InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1, - InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*locfcinfo, &typentry->hash_proc_finfo, 1, + PG_GET_COLLATION(), NULL, NULL); /* Loop over source data */ nitems = ArrayGetNItems(ndims, dims); @@ -3968,10 +3980,10 @@ hash_array(PG_FUNCTION_ARGS) else { /* Apply the hash function */ - locfcinfo.arg[0] = elt; - locfcinfo.argnull[0] = false; - locfcinfo.isnull = false; - elthash = DatumGetUInt32(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt; + locfcinfo->args[0].isnull = false; + locfcinfo->isnull = false; + elthash = DatumGetUInt32(FunctionCallInvoke(locfcinfo)); } /* @@ -4001,6 +4013,7 @@ hash_array(PG_FUNCTION_ARGS) Datum hash_array_extended(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(locfcinfo, 2); AnyArrayType *array = PG_GETARG_ANY_ARRAY_P(0); uint64 seed = PG_GETARG_INT64(1); int ndims = AARR_NDIM(array); @@ -4014,7 +4027,6 @@ hash_array_extended(PG_FUNCTION_ARGS) char typalign; int i; array_iter iter; - FunctionCallInfoData locfcinfo; typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra; if (typentry == NULL || @@ -4033,7 +4045,7 @@ hash_array_extended(PG_FUNCTION_ARGS) typbyval = typentry->typbyval; typalign = typentry->typalign; - InitFunctionCallInfoData(locfcinfo, &typentry->hash_extended_proc_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->hash_extended_proc_finfo, 2, InvalidOid, NULL, NULL); /* Loop over source data */ @@ -4056,12 +4068,11 @@ hash_array_extended(PG_FUNCTION_ARGS) else { /* Apply the hash function */ - locfcinfo.arg[0] = elt; - locfcinfo.arg[1] = Int64GetDatum(seed); - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - elthash = DatumGetUInt64(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = Int64GetDatum(seed); + locfcinfo->args[1].isnull = false; + elthash = DatumGetUInt64(FunctionCallInvoke(locfcinfo)); } result = (result << 5) - result + elthash; @@ -4091,6 +4102,7 @@ static bool array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, bool matchall, void **fn_extra) { + LOCAL_FCINFO(locfcinfo, 2); bool result = matchall; Oid element_type = AARR_ELEMTYPE(array1); TypeCacheEntry *typentry; @@ -4104,7 +4116,6 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, int i; int j; array_iter it1; - FunctionCallInfoData locfcinfo; if (element_type != AARR_ELEMTYPE(array2)) ereport(ERROR, @@ -4148,14 +4159,14 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, nelems2 = array2->xpn.nelems; } else - deconstruct_array(&(array2->flt), + deconstruct_array((ArrayType *) array2, element_type, typlen, typbyval, typalign, &values2, &nulls2, &nelems2); /* * Apply the comparison operator to each pair of array elements. */ - InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2, collation, NULL, NULL); /* Loop over source data */ @@ -4197,12 +4208,12 @@ array_contain_compare(AnyArrayType *array1, AnyArrayType *array2, Oid collation, /* * Apply the operator to the element pair */ - locfcinfo.arg[0] = elt1; - locfcinfo.arg[1] = elt2; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt1; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = elt2; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo)); if (oprresult) break; } @@ -6017,6 +6028,36 @@ array_unnest(PG_FUNCTION_ARGS) } } +/* + * Planner support function for array_unnest(anyarray) + */ +Datum +array_unnest_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestRows)) + { + /* Try to estimate the number of rows returned */ + SupportRequestRows *req = (SupportRequestRows *) rawreq; + + if (is_funcclause(req->node)) /* be paranoid */ + { + List *args = ((FuncExpr *) req->node)->args; + Node *arg1; + + /* We can use estimated argument values here */ + arg1 = estimate_expression_value(req->root, linitial(args)); + + req->rows = estimate_array_length(arg1); + ret = (Node *) req; + } + } + + PG_RETURN_POINTER(ret); +} + /* * array_replace/array_remove support @@ -6033,6 +6074,7 @@ array_replace_internal(ArrayType *array, bool remove, Oid collation, FunctionCallInfo fcinfo) { + LOCAL_FCINFO(locfcinfo, 2); ArrayType *result; Oid element_type; Datum *values; @@ -6053,7 +6095,6 @@ array_replace_internal(ArrayType *array, int bitmask; bool changed = false; TypeCacheEntry *typentry; - FunctionCallInfoData locfcinfo; element_type = ARR_ELEMTYPE(array); ndim = ARR_NDIM(array); @@ -6108,7 +6149,7 @@ array_replace_internal(ArrayType *array, } /* Prepare to apply the comparison operator */ - InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2, collation, NULL, NULL); /* Allocate temporary arrays for new values */ @@ -6166,12 +6207,12 @@ array_replace_internal(ArrayType *array, /* * Apply the operator to the element pair */ - locfcinfo.arg[0] = elt; - locfcinfo.arg[1] = search; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = elt; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = search; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo)); if (!oprresult) { /* no match, keep element */ @@ -6448,10 +6489,10 @@ width_bucket_array_fixed(Datum operand, Oid collation, TypeCacheEntry *typentry) { + LOCAL_FCINFO(locfcinfo, 2); char *thresholds_data; int typlen = typentry->typlen; bool typbyval = typentry->typbyval; - FunctionCallInfoData locfcinfo; int left; int right; @@ -6461,7 +6502,7 @@ width_bucket_array_fixed(Datum operand, */ thresholds_data = (char *) ARR_DATA_PTR(thresholds); - InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2, collation, NULL, NULL); /* Find the bucket */ @@ -6475,13 +6516,13 @@ width_bucket_array_fixed(Datum operand, ptr = thresholds_data + mid * typlen; - locfcinfo.arg[0] = operand; - locfcinfo.arg[1] = fetch_att(ptr, typbyval, typlen); - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; + locfcinfo->args[0].value = operand; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen); + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; - cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo)); + cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo)); if (cmpresult < 0) right = mid; @@ -6501,17 +6542,17 @@ width_bucket_array_variable(Datum operand, Oid collation, TypeCacheEntry *typentry) { + LOCAL_FCINFO(locfcinfo, 2); char *thresholds_data; int typlen = typentry->typlen; bool typbyval = typentry->typbyval; char typalign = typentry->typalign; - FunctionCallInfoData locfcinfo; int left; int right; thresholds_data = (char *) ARR_DATA_PTR(thresholds); - InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2, collation, NULL, NULL); /* Find the bucket */ @@ -6532,13 +6573,12 @@ width_bucket_array_variable(Datum operand, ptr = (char *) att_align_nominal(ptr, typalign); } - locfcinfo.arg[0] = operand; - locfcinfo.arg[1] = fetch_att(ptr, typbyval, typlen); - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; + locfcinfo->args[0].value = operand; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = fetch_att(ptr, typbyval, typlen); + locfcinfo->args[1].isnull = false; - cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo)); + cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo)); if (cmpresult < 0) right = mid; diff --git a/src/backend/utils/adt/arrayutils.c b/src/backend/utils/adt/arrayutils.c index c0d719e98cc..6170e35ac25 100644 --- a/src/backend/utils/adt/arrayutils.c +++ b/src/backend/utils/adt/arrayutils.c @@ -3,7 +3,7 @@ * arrayutils.c * This file contains some support routines required for array functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -226,8 +226,7 @@ ArrayGetIntegerTypmods(ArrayType *arr, int *n) result = (int32 *) palloc(*n * sizeof(int32)); for (i = 0; i < *n; i++) - result[i] = pg_atoi(DatumGetCString(elem_values[i]), - sizeof(int32), '\0'); + result[i] = pg_strtoint32(DatumGetCString(elem_values[i])); pfree(elem_values); diff --git a/src/backend/utils/adt/ascii.c b/src/backend/utils/adt/ascii.c index b26985369a7..8316d9aa062 100644 --- a/src/backend/utils/adt/ascii.c +++ b/src/backend/utils/adt/ascii.c @@ -2,7 +2,7 @@ * ascii.c * The PostgreSQL routine for string to ascii conversion. * - * Portions Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/ascii.c @@ -16,7 +16,7 @@ #include "utils/builtins.h" static void pg_to_ascii(unsigned char *src, unsigned char *src_end, - unsigned char *dest, int enc); + unsigned char *dest, int enc); static text *encode_to_ascii(text *data, int enc); diff --git a/src/backend/utils/adt/bool.c b/src/backend/utils/adt/bool.c index 2af62e3f2ea..35c181d2c00 100644 --- a/src/backend/utils/adt/bool.c +++ b/src/backend/utils/adt/bool.c @@ -3,7 +3,7 @@ * bool.c * Functions for the built-in type "bool". * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c index c787dd34191..6515fc8ec69 100644 --- a/src/backend/utils/adt/cash.c +++ b/src/backend/utils/adt/cash.c @@ -39,13 +39,13 @@ static const char * num_word(Cash value) { static char buf[128]; - static const char *small[] = { + static const char *const small[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; - const char **big = small + 18; + const char *const *big = small + 18; int tu = value % 100; /* deal with the simple cases first */ @@ -1032,13 +1032,8 @@ Datum cash_numeric(PG_FUNCTION_ARGS) { Cash money = PG_GETARG_CASH(0); - Numeric result; + Datum result; int fpoint; - int64 scale; - int i; - Datum amount; - Datum numeric_scale; - Datum quotient; struct lconv *lconvert = PGLC_localeconv(); /* see comments about frac_digits in cash_in() */ @@ -1046,22 +1041,45 @@ cash_numeric(PG_FUNCTION_ARGS) if (fpoint < 0 || fpoint > 10) fpoint = 2; - /* compute required scale factor */ - scale = 1; - for (i = 0; i < fpoint; i++) - scale *= 10; + /* convert the integral money value to numeric */ + result = DirectFunctionCall1(int8_numeric, Int64GetDatum(money)); - /* form the result as money / scale */ - amount = DirectFunctionCall1(int8_numeric, Int64GetDatum(money)); - numeric_scale = DirectFunctionCall1(int8_numeric, Int64GetDatum(scale)); - quotient = DirectFunctionCall2(numeric_div, amount, numeric_scale); + /* scale appropriately, if needed */ + if (fpoint > 0) + { + int64 scale; + int i; + Datum numeric_scale; + Datum quotient; + + /* compute required scale factor */ + scale = 1; + for (i = 0; i < fpoint; i++) + scale *= 10; + numeric_scale = DirectFunctionCall1(int8_numeric, + Int64GetDatum(scale)); - /* forcibly round to exactly the intended number of digits */ - result = DatumGetNumeric(DirectFunctionCall2(numeric_round, - quotient, - Int32GetDatum(fpoint))); + /* + * Given integral inputs approaching INT64_MAX, select_div_scale() + * might choose a result scale of zero, causing loss of fractional + * digits in the quotient. We can ensure an exact result by setting + * the dscale of either input to be at least as large as the desired + * result scale. numeric_round() will do that for us. + */ + numeric_scale = DirectFunctionCall2(numeric_round, + numeric_scale, + Int32GetDatum(fpoint)); + + /* Now we can safely divide ... */ + quotient = DirectFunctionCall2(numeric_div, result, numeric_scale); + + /* ... and forcibly round to exactly the intended number of digits */ + result = DirectFunctionCall2(numeric_round, + quotient, + Int32GetDatum(fpoint)); + } - PG_RETURN_NUMERIC(result); + PG_RETURN_DATUM(result); } /* numeric_cash() diff --git a/src/backend/utils/adt/char.c b/src/backend/utils/adt/char.c index d9fec3bb403..64232610028 100644 --- a/src/backend/utils/adt/char.c +++ b/src/backend/utils/adt/char.c @@ -4,7 +4,7 @@ * Functions for the built-in type "char" (not to be confused with * bpchar, which is the SQL CHAR(n) type). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/cryptohashes.c b/src/backend/utils/adt/cryptohashes.c index e1ff17590ea..55fdea22a81 100644 --- a/src/backend/utils/adt/cryptohashes.c +++ b/src/backend/utils/adt/cryptohashes.c @@ -3,7 +3,7 @@ * cryptohashes.c * Cryptographic hash functions * - * Portions Copyright (c) 2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index eea29044146..fa50d79c05d 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -3,7 +3,7 @@ * date.c * implements DATE and TIME data types specified in SQL standard * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * @@ -20,16 +20,16 @@ #include #include -#include "access/hash.h" #include "access/xact.h" #include "libpq/pqformat.h" #include "miscadmin.h" +#include "nodes/supportnodes.h" #include "parser/scansup.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/date.h" #include "utils/datetime.h" -#include "utils/nabstime.h" +#include "utils/hashutils.h" #include "utils/sortsupport.h" /* @@ -41,11 +41,6 @@ #endif -static int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result); -static int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result); -static void AdjustTimeForTypmod(TimeADT *time, int32 typmod); - - /* common code for timetypmodin and timetztypmodin */ static int32 anytime_typmodin(bool istz, ArrayType *ta) @@ -138,14 +133,6 @@ date_in(PG_FUNCTION_ARGS) case DTK_DATE: break; - case DTK_CURRENT: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"current\" is no longer supported"))); - - GetCurrentDateTime(tm); - break; - case DTK_EPOCH: GetEpochTime(tm); break; @@ -563,13 +550,15 @@ date_mii(PG_FUNCTION_ARGS) PG_RETURN_DATEADT(result); } + /* - * Internal routines for promoting date to timestamp and timestamp with - * time zone + * Promote date to timestamp. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set + * and zero is returned. */ - -static Timestamp -date2timestamp(DateADT dateVal) +Timestamp +date2timestamp_opt_error(DateADT dateVal, bool *have_error) { Timestamp result; @@ -585,9 +574,19 @@ date2timestamp(DateADT dateVal) * boundary need be checked for overflow. */ if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE)) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("date out of range for timestamp"))); + { + if (have_error) + { + *have_error = true; + return (Timestamp) 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range for timestamp"))); + } + } /* date is days since 2000, timestamp is microseconds since same... */ result = dateVal * USECS_PER_DAY; @@ -596,8 +595,23 @@ date2timestamp(DateADT dateVal) return result; } +/* + * Single-argument version of date2timestamp_opt_error(). + */ static TimestampTz -date2timestamptz(DateADT dateVal) +date2timestamp(DateADT dateVal) +{ + return date2timestamp_opt_error(dateVal, NULL); +} + +/* + * Promote date to timestamp with time zone. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set + * and zero is returned. + */ +TimestampTz +date2timestamptz_opt_error(DateADT dateVal, bool *have_error) { TimestampTz result; struct pg_tm tt, @@ -616,9 +630,19 @@ date2timestamptz(DateADT dateVal) * boundary need be checked for overflow. */ if (dateVal >= (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE)) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("date out of range for timestamp"))); + { + if (have_error) + { + *have_error = true; + return (TimestampTz) 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range for timestamp"))); + } + } j2date(dateVal + POSTGRES_EPOCH_JDATE, &(tm->tm_year), &(tm->tm_mon), &(tm->tm_mday)); @@ -634,14 +658,33 @@ date2timestamptz(DateADT dateVal) * of time zone, check for allowed timestamp range after adding tz. */ if (!IS_VALID_TIMESTAMP(result)) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("date out of range for timestamp"))); + { + if (have_error) + { + *have_error = true; + return (TimestampTz) 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range for timestamp"))); + } + } } return result; } +/* + * Single-argument version of date2timestamptz_opt_error(). + */ +static TimestampTz +date2timestamptz(DateADT dateVal) +{ + return date2timestamptz_opt_error(dateVal, NULL); +} + /* * date2timestamp_no_overflow * @@ -1170,55 +1213,6 @@ timestamptz_date(PG_FUNCTION_ARGS) } -/* abstime_date() - * Convert abstime to date data type. - */ -Datum -abstime_date(PG_FUNCTION_ARGS) -{ - AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); - DateADT result; - struct pg_tm tt, - *tm = &tt; - int tz; - - switch (abstime) - { - case INVALID_ABSTIME: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert reserved abstime value to date"))); - result = 0; /* keep compiler quiet */ - break; - - case NOSTART_ABSTIME: - DATE_NOBEGIN(result); - break; - - case NOEND_ABSTIME: - DATE_NOEND(result); - break; - - default: - abstime2tm(abstime, &tz, tm, NULL); - /* Prevent overflow in Julian-day routines */ - if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("abstime out of range for date"))); - result = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; - /* Now check for just-out-of-range dates */ - if (!IS_VALID_DATE(result)) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("abstime out of range for date"))); - break; - } - - PG_RETURN_DATEADT(result); -} - - /***************************************************************************** * Time ADT *****************************************************************************/ @@ -1260,7 +1254,7 @@ time_in(PG_FUNCTION_ARGS) /* tm2time() * Convert a tm structure to a time data type. */ -static int +int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result) { *result = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) @@ -1391,15 +1385,25 @@ make_time(PG_FUNCTION_ARGS) } -/* time_transform() - * Flatten calls to time_scale() and timetz_scale() that solely represent - * increases in allowed precision. +/* time_support() + * + * Planner support function for the time_scale() and timetz_scale() + * length coercion functions (we need not distinguish them here). */ Datum -time_transform(PG_FUNCTION_ARGS) +time_support(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(TemporalTransform(MAX_TIME_PRECISION, - (Node *) PG_GETARG_POINTER(0))); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + + ret = TemporalSimplify(MAX_TIME_PRECISION, (Node *) req->fcall); + } + + PG_RETURN_POINTER(ret); } /* time_scale() @@ -1421,12 +1425,12 @@ time_scale(PG_FUNCTION_ARGS) /* AdjustTimeForTypmod() * Force the precision of the time value to a specified value. - * Uses *exactly* the same code as in AdjustTimestampForTypemod() + * Uses *exactly* the same code as in AdjustTimestampForTypmod() * but we make a separate copy because those types do not * have a fundamental tie together but rather a coincidence of * implementation. - thomas */ -static void +void AdjustTimeForTypmod(TimeADT *time, int32 typmod) { static const int64 TimeScales[MAX_TIME_PRECISION + 1] = { @@ -1889,7 +1893,7 @@ in_range_time_interval(PG_FUNCTION_ARGS) */ if (offset->time < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* @@ -2004,7 +2008,7 @@ time_part(PG_FUNCTION_ARGS) /* tm2timetz() * Convert a tm structure to a time data type. */ -static int +int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result) { result->time = ((((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec) * @@ -2391,7 +2395,7 @@ in_range_timetz_interval(PG_FUNCTION_ARGS) */ if (offset->time < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 3f0f65c2956..e38bd930543 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -3,7 +3,7 @@ * datetime.c * Support functions for date/time types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,7 +15,6 @@ #include "postgres.h" #include -#include #include #include @@ -33,28 +32,28 @@ #include "utils/tzparser.h" -static int DecodeNumber(int flen, char *field, bool haveTextMonth, - int fmask, int *tmask, - struct pg_tm *tm, fsec_t *fsec, bool *is2digits); -static int DecodeNumberField(int len, char *str, - int fmask, int *tmask, - struct pg_tm *tm, fsec_t *fsec, bool *is2digits); -static int DecodeTime(char *str, int fmask, int range, - int *tmask, struct pg_tm *tm, fsec_t *fsec); +static int DecodeNumber(int flen, char *field, bool haveTextMonth, + int fmask, int *tmask, + struct pg_tm *tm, fsec_t *fsec, bool *is2digits); +static int DecodeNumberField(int len, char *str, + int fmask, int *tmask, + struct pg_tm *tm, fsec_t *fsec, bool *is2digits); +static int DecodeTime(char *str, int fmask, int range, + int *tmask, struct pg_tm *tm, fsec_t *fsec); static const datetkn *datebsearch(const char *key, const datetkn *base, int nel); -static int DecodeDate(char *str, int fmask, int *tmask, bool *is2digits, - struct pg_tm *tm); +static int DecodeDate(char *str, int fmask, int *tmask, bool *is2digits, + struct pg_tm *tm); static char *AppendSeconds(char *cp, int sec, fsec_t fsec, - int precision, bool fillzeros); + int precision, bool fillzeros); static void AdjustFractSeconds(double frac, struct pg_tm *tm, fsec_t *fsec, - int scale); + int scale); static void AdjustFractDays(double frac, struct pg_tm *tm, fsec_t *fsec, - int scale); -static int DetermineTimeZoneOffsetInternal(struct pg_tm *tm, pg_tz *tzp, - pg_time_t *tp); + int scale); +static int DetermineTimeZoneOffsetInternal(struct pg_tm *tm, pg_tz *tzp, + pg_time_t *tp); static bool DetermineTimeZoneAbbrevOffsetInternal(pg_time_t t, - const char *abbr, pg_tz *tzp, - int *offset, int *isdst); + const char *abbr, pg_tz *tzp, + int *offset, int *isdst); static pg_tz *FetchDynamicTimeZone(TimeZoneAbbrevTable *tbl, const datetkn *tp); @@ -100,7 +99,6 @@ static const datetkn datetktbl[] = { {"aug", MONTH, 8}, {"august", MONTH, 8}, {DB_C, ADBC, BC}, /* "bc" for years <= 0 */ - {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */ {"d", UNITS, DTK_DAY}, /* "day of month" for ISO input */ {"dec", MONTH, 12}, {"december", MONTH, 12}, @@ -114,7 +112,6 @@ static const datetkn datetktbl[] = { {"friday", DOW, 5}, {"h", UNITS, DTK_HOUR}, /* "hour" */ {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ - {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad time */ {"isodow", UNITS, DTK_ISODOW}, /* ISO day of week, Sunday == 7 */ {"isoyear", UNITS, DTK_ISOYEAR}, /* year in terms of the ISO week date */ {"j", UNITS, DTK_JULIAN}, @@ -158,7 +155,6 @@ static const datetkn datetktbl[] = { {"tue", DOW, 2}, {"tues", DOW, 2}, {"tuesday", DOW, 2}, - {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ {"wed", DOW, 3}, {"wednesday", DOW, 3}, {"weds", DOW, 3}, @@ -166,7 +162,7 @@ static const datetkn datetktbl[] = { {YESTERDAY, RESERV, DTK_YESTERDAY} /* yesterday midnight */ }; -static int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0]; +static const int szdatetktbl = sizeof datetktbl / sizeof datetktbl[0]; /* * deltatktbl: same format as datetktbl, but holds keywords used to represent @@ -192,7 +188,6 @@ static const datetkn deltatktbl[] = { {"hours", UNITS, DTK_HOUR}, /* "hours" relative */ {"hr", UNITS, DTK_HOUR}, /* "hour" relative */ {"hrs", UNITS, DTK_HOUR}, /* "hours" relative */ - {INVALID, RESERV, DTK_INVALID}, /* reserved for invalid time */ {"m", UNITS, DTK_MINUTE}, /* "minute" relative */ {"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative */ @@ -223,7 +218,6 @@ static const datetkn deltatktbl[] = { {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */ {"timezone_h", UNITS, DTK_TZ_HOUR}, /* timezone hour units */ {"timezone_m", UNITS, DTK_TZ_MINUTE}, /* timezone minutes units */ - {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ {"us", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative */ @@ -239,7 +233,7 @@ static const datetkn deltatktbl[] = { {"yrs", UNITS, DTK_YEAR} /* "years" relative */ }; -static int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0]; +static const int szdeltatktbl = sizeof deltatktbl / sizeof deltatktbl[0]; static TimeZoneAbbrevTable *zoneabbrevtbl = NULL; @@ -1145,8 +1139,8 @@ DecodeDateTime(char **field, int *ftype, int nf, * Is this a YMD or HMS specification, or a year number? * YMD and HMS are required to be six digits or more, so * if it is 5 digits, it is a year. If it is six or more - * more digits, we assume it is YMD or HMS unless no date - * and no time values have been specified. This forces 6+ + * digits, we assume it is YMD or HMS unless no date and + * no time values have been specified. This forces 6+ * digit years to be at the end of the string, or to use * the ISO date specification. */ @@ -1187,14 +1181,6 @@ DecodeDateTime(char **field, int *ftype, int nf, case RESERV: switch (val) { - case DTK_CURRENT: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"current\" is no longer supported"))); - - return DTERR_BAD_FORMAT; - break; - case DTK_NOW: tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ)); *dtype = DTK_DATE; @@ -1575,7 +1561,10 @@ DetermineTimeZoneOffsetInternal(struct pg_tm *tm, pg_tz *tzp, pg_time_t *tp) * fall-back transition, prefer "after". (We used to define and implement * this test as "prefer the standard-time interpretation", but that rule * does not help to resolve the behavior when both times are reported as - * standard time; which does happen, eg Europe/Moscow in Oct 2014.) + * standard time; which does happen, eg Europe/Moscow in Oct 2014. Also, + * in some zones such as Europe/Dublin, there is widespread confusion + * about which time offset is "standard" time, so it's fortunate that our + * behavior doesn't depend on that.) */ if (beforetime > aftertime) { @@ -1866,7 +1855,7 @@ DecodeTimeOnly(char **field, int *ftype, int nf, /* * Was this an "ISO time" with embedded field labels? An - * example is "h04m05s06" - thomas 2001-02-04 + * example is "h04mm05s06" - thomas 2001-02-04 */ if (ptype != 0) { @@ -2095,13 +2084,6 @@ DecodeTimeOnly(char **field, int *ftype, int nf, case RESERV: switch (val) { - case DTK_CURRENT: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"current\" is no longer supported"))); - return DTERR_BAD_FORMAT; - break; - case DTK_NOW: tmask = DTK_TIME_M; *dtype = DTK_TIME; @@ -2298,6 +2280,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf, GetCurrentDateTime(tmp); else { + /* a date has to be specified */ + if ((fmask & DTK_DATE_M) != DTK_DATE_M) + return DTERR_BAD_FORMAT; tmp->tm_year = tm->tm_year; tmp->tm_mon = tm->tm_mon; tmp->tm_mday = tm->tm_mday; @@ -2325,6 +2310,9 @@ DecodeTimeOnly(char **field, int *ftype, int nf, GetCurrentDateTime(tmp); else { + /* a date has to be specified */ + if ((fmask & DTK_DATE_M) != DTK_DATE_M) + return DTERR_BAD_FORMAT; tmp->tm_year = tm->tm_year; tmp->tm_mon = tm->tm_mon; tmp->tm_mday = tm->tm_mday; @@ -3047,7 +3035,7 @@ DecodeSpecial(int field, char *lowtoken, int *val) } -/* ClearPgTM +/* ClearPgTm * * Zero out a pg_tm and associated fsec_t */ @@ -3146,7 +3134,7 @@ DecodeInterval(char **field, int *ftype, int nf, int range, * handle signed float numbers and signed year-month values. */ - /* FALL THROUGH */ + /* FALLTHROUGH */ case DTK_DATE: case DTK_NUMBER: @@ -3577,6 +3565,7 @@ DecodeISO8601Interval(char *str, continue; } /* Else fall through to extended alternative format */ + /* FALLTHROUGH */ case '-': /* ISO 8601 4.4.3.3 Alternative Format, * Extended */ if (havefield) @@ -3655,6 +3644,7 @@ DecodeISO8601Interval(char *str, return 0; } /* Else fall through to extended alternative format */ + /* FALLTHROUGH */ case ':': /* ISO 8601 4.4.3.3 Alternative Format, * Extended */ if (havefield) @@ -4458,16 +4448,23 @@ CheckDateTokenTables(void) } /* - * Common code for temporal protransform functions. Types time, timetz, - * timestamp and timestamptz each have a range of allowed precisions. An - * unspecified precision is rigorously equivalent to the highest specifiable - * precision. + * Common code for temporal prosupport functions: simplify, if possible, + * a call to a temporal type's length-coercion function. + * + * Types time, timetz, timestamp and timestamptz each have a range of allowed + * precisions. An unspecified precision is rigorously equivalent to the + * highest specifiable precision. We can replace the function call with a + * no-op RelabelType if it is coercing to the same or higher precision as the + * input is known to have. + * + * The input Node is always a FuncExpr, but to reduce the #include footprint + * of datetime.h, we declare it as Node *. * * Note: timestamp_scale throws an error when the typmod is out of range, but * we can't get there from a cast: our typmodin will have caught it already. */ Node * -TemporalTransform(int32 max_precis, Node *node) +TemporalSimplify(int32 max_precis, Node *node) { FuncExpr *expr = castNode(FuncExpr, node); Node *ret = NULL; @@ -4670,7 +4667,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS) * build tupdesc for result tuples. This must match this function's * pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "abbrev", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset", @@ -4797,7 +4794,7 @@ pg_timezone_names(PG_FUNCTION_ARGS) * build tupdesc for result tuples. This must match this function's * pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "abbrev", @@ -4835,16 +4832,15 @@ pg_timezone_names(PG_FUNCTION_ARGS) continue; /* ignore if conversion fails */ /* - * Ignore zic's rather silly "Factory" time zone. The long string - * about "see zic manual page" is used in tzdata versions before - * 2016g; we can drop it someday when we're pretty sure no such data - * exists in the wild on platforms using --with-system-tzdata. In - * 2016g and later, the time zone abbreviation "-00" is used for - * "Factory" as well as some invalid cases, all of which we can - * reasonably omit from the pg_timezone_names view. + * IANA's rather silly "Factory" time zone used to emit ridiculously + * long "abbreviations" such as "Local time zone must be set--see zic + * manual page" or "Local time zone must be set--use tzsetup". While + * modern versions of tzdb emit the much saner "-00", it seems some + * benighted packagers are hacking the IANA data so that it continues + * to produce these strings. To prevent producing a weirdly wide + * abbrev column, reject ridiculously long abbreviations. */ - if (tzn && (strcmp(tzn, "-00") == 0 || - strcmp(tzn, "Local time zone must be set--see zic manual page") == 0)) + if (tzn && strlen(tzn) > 31) continue; /* Found a displayable zone */ diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index f02a5e77aee..1568658bc9c 100644 --- a/src/backend/utils/adt/datum.c +++ b/src/backend/utils/adt/datum.c @@ -3,7 +3,7 @@ * datum.c * POSTGRES Datum (abstract data type) manipulation routines. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -42,6 +42,8 @@ #include "postgres.h" +#include "access/detoast.h" +#include "fmgr.h" #include "utils/datum.h" #include "utils/expandeddatum.h" @@ -251,6 +253,61 @@ datumIsEqual(Datum value1, Datum value2, bool typByVal, int typLen) return res; } +/*------------------------------------------------------------------------- + * datum_image_eq + * + * Compares two datums for identical contents, based on byte images. Return + * true if the two datums are equal, false otherwise. + *------------------------------------------------------------------------- + */ +bool +datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen) +{ + bool result = true; + + if (typLen == -1) + { + Size len1, + len2; + + len1 = toast_raw_datum_size(value1); + len2 = toast_raw_datum_size(value2); + /* No need to de-toast if lengths don't match. */ + if (len1 != len2) + result = false; + else + { + struct varlena *arg1val; + struct varlena *arg2val; + + arg1val = PG_DETOAST_DATUM_PACKED(value1); + arg2val = PG_DETOAST_DATUM_PACKED(value2); + + result = (memcmp(VARDATA_ANY(arg1val), + VARDATA_ANY(arg2val), + len1 - VARHDRSZ) == 0); + + /* Only free memory if it's a copy made here. */ + if ((Pointer) arg1val != (Pointer) value1) + pfree(arg1val); + if ((Pointer) arg2val != (Pointer) value2) + pfree(arg2val); + } + } + else if (typByVal) + { + result = (value1 == value2); + } + else + { + result = (memcmp(DatumGetPointer(value1), + DatumGetPointer(value2), + typLen) == 0); + } + + return result; +} + /*------------------------------------------------------------------------- * datumEstimateSpace * @@ -338,8 +395,19 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen, } else if (eoh) { - EOH_flatten_into(eoh, (void *) *start_address, header); + char *tmp; + + /* + * EOH_flatten_into expects the target address to be maxaligned, + * so we can't store directly to *start_address. + */ + tmp = (char *) palloc(header); + EOH_flatten_into(eoh, (void *) tmp, header); + memcpy(*start_address, tmp, header); *start_address += header; + + /* be tidy. */ + pfree(tmp); } else { diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 07e5e78caa8..a87e7214e9f 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -2,7 +2,7 @@ * dbsize.c * Database object size functions, and related inquiries * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/dbsize.c @@ -13,8 +13,8 @@ #include -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/relation.h" #include "catalog/catalog.h" #include "catalog/namespace.h" #include "catalog/pg_authid.h" diff --git a/src/backend/utils/adt/domains.c b/src/backend/utils/adt/domains.c index 1df554ec93a..6553a67ea1c 100644 --- a/src/backend/utils/adt/domains.c +++ b/src/backend/utils/adt/domains.c @@ -19,7 +19,7 @@ * to evaluate them in. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index 56438382f67..7293d66de5b 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -3,7 +3,7 @@ * encode.c * Various data encoding/decoding things. * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c index 562cd5c555d..3402ff860d3 100644 --- a/src/backend/utils/adt/enum.c +++ b/src/backend/utils/adt/enum.c @@ -3,7 +3,7 @@ * enum.c * I/O functions, operators, aggregates etc for enum types * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -14,11 +14,12 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_enum.h" #include "libpq/pqformat.h" +#include "storage/procarray.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -31,6 +32,78 @@ static Oid enum_endpoint(Oid enumtypoid, ScanDirection direction); static ArrayType *enum_range_internal(Oid enumtypoid, Oid lower, Oid upper); +/* + * Disallow use of an uncommitted pg_enum tuple. + * + * We need to make sure that uncommitted enum values don't get into indexes. + * If they did, and if we then rolled back the pg_enum addition, we'd have + * broken the index because value comparisons will not work reliably without + * an underlying pg_enum entry. (Note that removal of the heap entry + * containing an enum value is not sufficient to ensure that it doesn't appear + * in upper levels of indexes.) To do this we prevent an uncommitted row from + * being used for any SQL-level purpose. This is stronger than necessary, + * since the value might not be getting inserted into a table or there might + * be no index on its column, but it's easy to enforce centrally. + * + * However, it's okay to allow use of uncommitted values belonging to enum + * types that were themselves created in the same transaction, because then + * any such index would also be new and would go away altogether on rollback. + * We don't implement that fully right now, but we do allow free use of enum + * values created during CREATE TYPE AS ENUM, which are surely of the same + * lifespan as the enum type. (This case is required by "pg_restore -1".) + * Values added by ALTER TYPE ADD VALUE are currently restricted, but could + * be allowed if the enum type could be proven to have been created earlier + * in the same transaction. (Note that comparing tuple xmins would not work + * for that, because the type tuple might have been updated in the current + * transaction. Subtransactions also create hazards to be accounted for.) + * + * This function needs to be called (directly or indirectly) in any of the + * functions below that could return an enum value to SQL operations. + */ +static void +check_safe_enum_use(HeapTuple enumval_tup) +{ + TransactionId xmin; + Form_pg_enum en = (Form_pg_enum) GETSTRUCT(enumval_tup); + + /* + * If the row is hinted as committed, it's surely safe. This provides a + * fast path for all normal use-cases. + */ + if (HeapTupleHeaderXminCommitted(enumval_tup->t_data)) + return; + + /* + * Usually, a row would get hinted as committed when it's read or loaded + * into syscache; but just in case not, let's check the xmin directly. + */ + xmin = HeapTupleHeaderGetXmin(enumval_tup->t_data); + if (!TransactionIdIsInProgress(xmin) && + TransactionIdDidCommit(xmin)) + return; + + /* + * Check if the enum value is blacklisted. If not, it's safe, because it + * was made during CREATE TYPE AS ENUM and can't be shorter-lived than its + * owning type. (This'd also be false for values made by other + * transactions; but the previous tests should have handled all of those.) + */ + if (!EnumBlacklisted(en->oid)) + return; + + /* + * There might well be other tests we could do here to narrow down the + * unsafe conditions, but for now just raise an exception. + */ + ereport(ERROR, + (errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE), + errmsg("unsafe use of new value \"%s\" of enum type %s", + NameStr(en->enumlabel), + format_type_be(en->enumtypid)), + errhint("New enum values must be committed before they can be used."))); +} + + /* Basic I/O support */ Datum @@ -59,11 +132,14 @@ enum_in(PG_FUNCTION_ARGS) format_type_be(enumtypoid), name))); + /* check it's safe to use in SQL */ + check_safe_enum_use(tup); + /* * This comes from pg_enum.oid and stores system oids in user tables. This * oid must be preserved by binary upgrades. */ - enumoid = HeapTupleGetOid(tup); + enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid; ReleaseSysCache(tup); @@ -124,7 +200,10 @@ enum_recv(PG_FUNCTION_ARGS) format_type_be(enumtypoid), name))); - enumoid = HeapTupleGetOid(tup); + /* check it's safe to use in SQL */ + check_safe_enum_use(tup); + + enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid; ReleaseSysCache(tup); @@ -324,20 +403,27 @@ enum_endpoint(Oid enumtypoid, ScanDirection direction) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(enumtypoid)); - enum_rel = heap_open(EnumRelationId, AccessShareLock); + enum_rel = table_open(EnumRelationId, AccessShareLock); enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock); enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey); enum_tuple = systable_getnext_ordered(enum_scan, direction); if (HeapTupleIsValid(enum_tuple)) - minmax = HeapTupleGetOid(enum_tuple); + { + /* check it's safe to use in SQL */ + check_safe_enum_use(enum_tuple); + minmax = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid; + } else + { + /* should only happen with an empty enum */ minmax = InvalidOid; + } systable_endscan_ordered(enum_scan); index_close(enum_idx, AccessShareLock); - heap_close(enum_rel, AccessShareLock); + table_close(enum_rel, AccessShareLock); return minmax; } @@ -476,7 +562,7 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(enumtypoid)); - enum_rel = heap_open(EnumRelationId, AccessShareLock); + enum_rel = table_open(EnumRelationId, AccessShareLock); enum_idx = index_open(EnumTypIdSortOrderIndexId, AccessShareLock); enum_scan = systable_beginscan_ordered(enum_rel, enum_idx, NULL, 1, &skey); @@ -487,13 +573,16 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper) while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection))) { - Oid enum_oid = HeapTupleGetOid(enum_tuple); + Oid enum_oid = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid; if (!left_found && lower == enum_oid) left_found = true; if (left_found) { + /* check it's safe to use in SQL */ + check_safe_enum_use(enum_tuple); + if (cnt >= max) { max *= 2; @@ -509,7 +598,7 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper) systable_endscan_ordered(enum_scan); index_close(enum_idx, AccessShareLock); - heap_close(enum_rel, AccessShareLock); + table_close(enum_rel, AccessShareLock); /* and build the result array */ /* note this hardwires some details about the representation of Oid */ diff --git a/src/backend/utils/adt/expandeddatum.c b/src/backend/utils/adt/expandeddatum.c index 33fa4a06291..115c4dedf10 100644 --- a/src/backend/utils/adt/expandeddatum.c +++ b/src/backend/utils/adt/expandeddatum.c @@ -3,7 +3,7 @@ * expandeddatum.c * Support functions for "expanded" value representations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/expandedrecord.c b/src/backend/utils/adt/expandedrecord.c index 0bf5fe8cc7a..369432d53cb 100644 --- a/src/backend/utils/adt/expandedrecord.c +++ b/src/backend/utils/adt/expandedrecord.c @@ -7,7 +7,7 @@ * store values of named composite types, domains over named composite types, * and record types (registered or anonymous). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,6 +18,8 @@ */ #include "postgres.h" +#include "access/detoast.h" +#include "access/heaptoast.h" #include "access/htup_details.h" #include "catalog/heap.h" #include "catalog/pg_type.h" @@ -31,7 +33,7 @@ /* "Methods" required for an expanded object */ static Size ER_get_flat_size(ExpandedObjectHeader *eohptr); static void ER_flatten_into(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size); + void *result, Size allocated_size); static const ExpandedObjectMethods ER_methods = { @@ -41,13 +43,13 @@ static const ExpandedObjectMethods ER_methods = /* Other local functions */ static void ER_mc_callback(void *arg); -static MemoryContext get_domain_check_cxt(ExpandedRecordHeader *erh); +static MemoryContext get_short_term_cxt(ExpandedRecordHeader *erh); static void build_dummy_expanded_header(ExpandedRecordHeader *main_erh); static pg_noinline void check_domain_for_new_field(ExpandedRecordHeader *erh, - int fnumber, - Datum newValue, bool isnull); + int fnumber, + Datum newValue, bool isnull); static pg_noinline void check_domain_for_new_tuple(ExpandedRecordHeader *erh, - HeapTuple tuple); + HeapTuple tuple); /* @@ -57,8 +59,9 @@ static pg_noinline void check_domain_for_new_tuple(ExpandedRecordHeader *erh, * * The expanded record is initially "empty", having a state logically * equivalent to a NULL composite value (not ROW(NULL, NULL, ...)). - * Note that this might not be a valid state for a domain type; if the - * caller needs to check that, call expanded_record_set_tuple(erh, NULL). + * Note that this might not be a valid state for a domain type; + * if the caller needs to check that, call + * expanded_record_set_tuple(erh, NULL, false, false). * * The expanded object will be a child of parentcontext. */ @@ -424,8 +427,11 @@ make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, * * The tuple is physically copied into the expanded record's local storage * if "copy" is true, otherwise it's caller's responsibility that the tuple - * will live as long as the expanded record does. In any case, out-of-line - * fields in the tuple are not automatically inlined. + * will live as long as the expanded record does. + * + * Out-of-line field values in the tuple are automatically inlined if + * "expand_external" is true, otherwise not. (The combination copy = false, + * expand_external = true is not sensible and not supported.) * * Alternatively, tuple can be NULL, in which case we just set the expanded * record to be empty. @@ -433,7 +439,8 @@ make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, void expanded_record_set_tuple(ExpandedRecordHeader *erh, HeapTuple tuple, - bool copy) + bool copy, + bool expand_external) { int oldflags; HeapTuple oldtuple; @@ -452,6 +459,25 @@ expanded_record_set_tuple(ExpandedRecordHeader *erh, if (erh->flags & ER_FLAG_IS_DOMAIN) check_domain_for_new_tuple(erh, tuple); + /* + * If we need to get rid of out-of-line field values, do so, using the + * short-term context to avoid leaking whatever cruft the toast fetch + * might generate. + */ + if (expand_external && tuple) + { + /* Assert caller didn't ask for unsupported case */ + Assert(copy); + if (HeapTupleHasExternal(tuple)) + { + oldcxt = MemoryContextSwitchTo(get_short_term_cxt(erh)); + tuple = toast_flatten_tuple(tuple, erh->er_tupdesc); + MemoryContextSwitchTo(oldcxt); + } + else + expand_external = false; /* need not clean up below */ + } + /* * Initialize new flags, keeping only non-data status bits. */ @@ -468,6 +494,10 @@ expanded_record_set_tuple(ExpandedRecordHeader *erh, newtuple = heap_copytuple(tuple); newflags |= ER_FLAG_FVALUE_ALLOCED; MemoryContextSwitchTo(oldcxt); + + /* We can now flush anything that detoasting might have leaked. */ + if (expand_external) + MemoryContextReset(erh->er_short_term_cxt); } else newtuple = tuple; @@ -676,23 +706,13 @@ ER_get_flat_size(ExpandedObjectHeader *eohptr) VARATT_IS_EXTERNAL(DatumGetPointer(erh->dvalues[i]))) { /* - * It's an external toasted value, so we need to dereference - * it so that the flat representation will be self-contained. - * Do this step in the caller's context because the TOAST - * fetch might leak memory. That means making an extra copy, - * which is a tad annoying, but repetitive leaks in the - * record's context would be worse. + * expanded_record_set_field_internal can do the actual work + * of detoasting. It needn't recheck domain constraints. */ - Datum newValue; - - newValue = PointerGetDatum(PG_DETOAST_DATUM(erh->dvalues[i])); - /* expanded_record_set_field can do the rest */ - /* ... and we don't need it to recheck domain constraints */ expanded_record_set_field_internal(erh, i + 1, - newValue, false, + erh->dvalues[i], false, + true, false); - /* Might as well free the detoasted value */ - pfree(DatumGetPointer(newValue)); } } @@ -722,9 +742,6 @@ ER_get_flat_size(ExpandedObjectHeader *eohptr) if (hasnull) len += BITMAPLEN(tupdesc->natts); - if (tupdesc->tdhasoid) - len += sizeof(Oid); - hoff = len = MAXALIGN(len); /* align user data safely */ data_len = heap_compute_data_size(tupdesc, erh->dvalues, erh->dnulls); @@ -785,9 +802,6 @@ ER_flatten_into(ExpandedObjectHeader *eohptr, HeapTupleHeaderSetNatts(tuphdr, tupdesc->natts); tuphdr->t_hoff = erh->hoff; - if (tupdesc->tdhasoid) /* else leave infomask = 0 */ - tuphdr->t_infomask = HEAP_HASOID; - /* And fill the data area from dvalues/dnulls */ heap_fill_tuple(tupdesc, erh->dvalues, @@ -1006,6 +1020,7 @@ expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, TupleDesc tupdesc; int fno; Form_pg_attribute attr; + const FormData_pg_attribute *sysattr; tupdesc = expanded_record_get_tupdesc(erh); @@ -1025,13 +1040,13 @@ expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname, } /* How about system attributes? */ - attr = SystemAttributeByName(fieldname, tupdesc->tdhasoid); - if (attr != NULL) + sysattr = SystemAttributeByName(fieldname); + if (sysattr != NULL) { - finfo->fnumber = attr->attnum; - finfo->ftypeid = attr->atttypid; - finfo->ftypmod = attr->atttypmod; - finfo->fcollation = attr->attcollation; + finfo->fnumber = sysattr->attnum; + finfo->ftypeid = sysattr->atttypid; + finfo->ftypmod = sysattr->atttypmod; + finfo->fcollation = sysattr->attcollation; return true; } @@ -1087,12 +1102,16 @@ expanded_record_fetch_field(ExpandedRecordHeader *erh, int fnumber, * (without changing the record's state) if the domain's constraints would * be violated. * + * If expand_external is true and newValue is an out-of-line value, we'll + * forcibly detoast it so that the record does not depend on external storage. + * * Internal callers can pass check_constraints = false to skip application * of domain constraints. External callers should never do that. */ void expanded_record_set_field_internal(ExpandedRecordHeader *erh, int fnumber, Datum newValue, bool isnull, + bool expand_external, bool check_constraints) { TupleDesc tupdesc; @@ -1124,23 +1143,46 @@ expanded_record_set_field_internal(ExpandedRecordHeader *erh, int fnumber, elog(ERROR, "cannot assign to field %d of expanded record", fnumber); /* - * Copy new field value into record's context, if needed. + * Copy new field value into record's context, and deal with detoasting, + * if needed. */ attr = TupleDescAttr(tupdesc, fnumber - 1); if (!isnull && !attr->attbyval) { MemoryContext oldcxt; + /* If requested, detoast any external value */ + if (expand_external) + { + if (attr->attlen == -1 && + VARATT_IS_EXTERNAL(DatumGetPointer(newValue))) + { + /* Detoasting should be done in short-lived context. */ + oldcxt = MemoryContextSwitchTo(get_short_term_cxt(erh)); + newValue = PointerGetDatum(heap_tuple_fetch_attr((struct varlena *) DatumGetPointer(newValue))); + MemoryContextSwitchTo(oldcxt); + } + else + expand_external = false; /* need not clean up below */ + } + + /* Copy value into record's context */ oldcxt = MemoryContextSwitchTo(erh->hdr.eoh_context); newValue = datumCopy(newValue, false, attr->attlen); MemoryContextSwitchTo(oldcxt); + /* We can now flush anything that detoasting might have leaked */ + if (expand_external) + MemoryContextReset(erh->er_short_term_cxt); + /* Remember that we have field(s) that may need to be pfree'd */ erh->flags |= ER_FLAG_DVALUES_ALLOCED; /* * While we're here, note whether it's an external toasted value, - * because that could mean we need to inline it later. + * because that could mean we need to inline it later. (Think not to + * merge this into the previous expand_external logic: datumCopy could + * by itself have made the value non-external.) */ if (attr->attlen == -1 && VARATT_IS_EXTERNAL(DatumGetPointer(newValue))) @@ -1193,14 +1235,20 @@ expanded_record_set_field_internal(ExpandedRecordHeader *erh, int fnumber, * Caller must ensure that the provided datums are of the right types * to match the record's previously assigned rowtype. * + * If expand_external is true, we'll forcibly detoast out-of-line field values + * so that the record does not depend on external storage. + * * Unlike repeated application of expanded_record_set_field(), this does not * guarantee to leave the expanded record in a non-corrupt state in event * of an error. Typically it would only be used for initializing a new - * expanded record. + * expanded record. Also, because we expect this to be applied at most once + * in the lifespan of an expanded record, we do not worry about any cruft + * that detoasting might leak. */ void expanded_record_set_fields(ExpandedRecordHeader *erh, - const Datum *newValues, const bool *isnulls) + const Datum *newValues, const bool *isnulls, + bool expand_external) { TupleDesc tupdesc; Datum *dvalues; @@ -1245,22 +1293,37 @@ expanded_record_set_fields(ExpandedRecordHeader *erh, if (!attr->attbyval) { /* - * Copy new field value into record's context, if needed. + * Copy new field value into record's context, and deal with + * detoasting, if needed. */ if (!isnull) { - newValue = datumCopy(newValue, false, attr->attlen); + /* Is it an external toasted value? */ + if (attr->attlen == -1 && + VARATT_IS_EXTERNAL(DatumGetPointer(newValue))) + { + if (expand_external) + { + /* Detoast as requested while copying the value */ + newValue = PointerGetDatum(heap_tuple_fetch_attr((struct varlena *) DatumGetPointer(newValue))); + } + else + { + /* Just copy the value */ + newValue = datumCopy(newValue, false, -1); + /* If it's still external, remember that */ + if (VARATT_IS_EXTERNAL(DatumGetPointer(newValue))) + erh->flags |= ER_FLAG_HAVE_EXTERNAL; + } + } + else + { + /* Not an external value, just copy it */ + newValue = datumCopy(newValue, false, attr->attlen); + } /* Remember that we have field(s) that need to be pfree'd */ erh->flags |= ER_FLAG_DVALUES_ALLOCED; - - /* - * While we're here, note whether it's an external toasted - * value, because that could mean we need to inline it later. - */ - if (attr->attlen == -1 && - VARATT_IS_EXTERNAL(DatumGetPointer(newValue))) - erh->flags |= ER_FLAG_HAVE_EXTERNAL; } /* @@ -1291,7 +1354,7 @@ expanded_record_set_fields(ExpandedRecordHeader *erh, if (erh->flags & ER_FLAG_IS_DOMAIN) { /* We run domain_check in a short-lived context to limit cruft */ - MemoryContextSwitchTo(get_domain_check_cxt(erh)); + MemoryContextSwitchTo(get_short_term_cxt(erh)); domain_check(ExpandedRecordGetRODatum(erh), false, erh->er_decltypeid, @@ -1303,25 +1366,26 @@ expanded_record_set_fields(ExpandedRecordHeader *erh, } /* - * Construct (or reset) working memory context for domain checks. + * Construct (or reset) working memory context for short-term operations. + * + * This context is used for domain check evaluation and for detoasting. * - * If we don't have a working memory context for domain checking, make one; - * if we have one, reset it to get rid of any leftover cruft. (It is a tad - * annoying to need a whole context for this, since it will often go unused - * --- but it's hard to avoid memory leaks otherwise. We can make the - * context small, at least.) + * If we don't have a short-lived memory context, make one; if we have one, + * reset it to get rid of any leftover cruft. (It is a tad annoying to need a + * whole context for this, since it will often go unused --- but it's hard to + * avoid memory leaks otherwise. We can make the context small, at least.) */ static MemoryContext -get_domain_check_cxt(ExpandedRecordHeader *erh) +get_short_term_cxt(ExpandedRecordHeader *erh) { - if (erh->er_domain_check_cxt == NULL) - erh->er_domain_check_cxt = + if (erh->er_short_term_cxt == NULL) + erh->er_short_term_cxt = AllocSetContextCreate(erh->hdr.eoh_context, - "expanded record domain checks", + "expanded record short-term context", ALLOCSET_SMALL_SIZES); else - MemoryContextReset(erh->er_domain_check_cxt); - return erh->er_domain_check_cxt; + MemoryContextReset(erh->er_short_term_cxt); + return erh->er_short_term_cxt; } /* @@ -1340,8 +1404,8 @@ build_dummy_expanded_header(ExpandedRecordHeader *main_erh) ExpandedRecordHeader *erh; TupleDesc tupdesc = expanded_record_get_tupdesc(main_erh); - /* Ensure we have a domain_check_cxt */ - (void) get_domain_check_cxt(main_erh); + /* Ensure we have a short-lived context */ + (void) get_short_term_cxt(main_erh); /* * Allocate dummy header on first time through, or in the unlikely event @@ -1372,7 +1436,7 @@ build_dummy_expanded_header(ExpandedRecordHeader *main_erh) * nothing else is authorized to delete or transfer ownership of the * object's context, so it should be safe enough. */ - EOH_init_header(&erh->hdr, &ER_methods, main_erh->er_domain_check_cxt); + EOH_init_header(&erh->hdr, &ER_methods, main_erh->er_short_term_cxt); erh->er_magic = ER_MAGIC; /* Set up dvalues/dnulls, with no valid contents as yet */ @@ -1488,7 +1552,7 @@ check_domain_for_new_field(ExpandedRecordHeader *erh, int fnumber, * We call domain_check in the short-lived context, so that any cruft * leaked by expression evaluation can be reclaimed. */ - oldcxt = MemoryContextSwitchTo(erh->er_domain_check_cxt); + oldcxt = MemoryContextSwitchTo(erh->er_short_term_cxt); /* * And now we can apply the check. Note we use main header's domain cache @@ -1502,7 +1566,7 @@ check_domain_for_new_field(ExpandedRecordHeader *erh, int fnumber, MemoryContextSwitchTo(oldcxt); /* We might as well clean up cruft immediately. */ - MemoryContextReset(erh->er_domain_check_cxt); + MemoryContextReset(erh->er_short_term_cxt); } /* @@ -1518,7 +1582,7 @@ check_domain_for_new_tuple(ExpandedRecordHeader *erh, HeapTuple tuple) if (tuple == NULL) { /* We run domain_check in a short-lived context to limit cruft */ - oldcxt = MemoryContextSwitchTo(get_domain_check_cxt(erh)); + oldcxt = MemoryContextSwitchTo(get_short_term_cxt(erh)); domain_check((Datum) 0, true, erh->er_decltypeid, @@ -1528,7 +1592,7 @@ check_domain_for_new_tuple(ExpandedRecordHeader *erh, HeapTuple tuple) MemoryContextSwitchTo(oldcxt); /* We might as well clean up cruft immediately. */ - MemoryContextReset(erh->er_domain_check_cxt); + MemoryContextReset(erh->er_short_term_cxt); return; } @@ -1551,7 +1615,7 @@ check_domain_for_new_tuple(ExpandedRecordHeader *erh, HeapTuple tuple) * We call domain_check in the short-lived context, so that any cruft * leaked by expression evaluation can be reclaimed. */ - oldcxt = MemoryContextSwitchTo(erh->er_domain_check_cxt); + oldcxt = MemoryContextSwitchTo(erh->er_short_term_cxt); /* * And now we can apply the check. Note we use main header's domain cache @@ -1565,5 +1629,5 @@ check_domain_for_new_tuple(ExpandedRecordHeader *erh, HeapTuple tuple) MemoryContextSwitchTo(oldcxt); /* We might as well clean up cruft immediately. */ - MemoryContextReset(erh->er_domain_check_cxt); + MemoryContextReset(erh->er_short_term_cxt); } diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 6522c0816ef..77a5d7d42f8 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -3,7 +3,7 @@ * float.c * Functions for the built-in floating-point types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,48 +21,25 @@ #include "catalog/pg_type.h" #include "common/int.h" +#include "common/shortest_dec.h" #include "libpq/pqformat.h" +#include "miscadmin.h" #include "utils/array.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" #include "utils/sortsupport.h" +#include "utils/timestamp.h" -#ifndef M_PI -/* from my RH5.2 gcc math.h file - thomas 2000-04-03 */ -#define M_PI 3.14159265358979323846 -#endif - -/* Radians per degree, a.k.a. PI / 180 */ -#define RADIANS_PER_DEGREE 0.0174532925199432957692 - -/* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. NAN definition from - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrfNotNumberNANItems.asp - */ -#if defined(WIN32) && !defined(NAN) -static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; - -#define NAN (*(const double *) nan) -#endif - /* - * check to see if a float4/8 val has underflowed or overflowed + * Configurable GUC parameter + * + * If >0, use shortest-decimal format for output; this is both the default and + * allows for compatibility with clients that explicitly set a value here to + * get round-trip-accurate results. If 0 or less, then use the old, slow, + * decimal rounding method. */ -#define CHECKFLOATVAL(val, inf_is_valid, zero_is_valid) \ -do { \ - if (isinf(val) && !(inf_is_valid)) \ - ereport(ERROR, \ - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ - errmsg("value out of range: overflow"))); \ - \ - if ((val) == 0.0 && !(zero_is_valid)) \ - ereport(ERROR, \ - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), \ - errmsg("value out of range: underflow"))); \ -} while(0) - - -/* Configurable GUC parameter */ -int extra_float_digits = 0; /* Added to DBL_DIG or FLT_DIG */ +int extra_float_digits = 1; /* Cached constants for degree-based trig functions */ static bool degree_consts_set = false; @@ -86,6 +63,10 @@ float8 degree_c_sixty = 60.0; float8 degree_c_one_half = 0.5; float8 degree_c_one = 1.0; +/* State for drandom() and setseed() */ +static bool drandom_seed_set = false; +static unsigned short drandom_seed[3] = {0, 0, 0}; + /* Local function prototypes */ static double sind_q1(double x); static double cosd_q1(double x); @@ -105,86 +86,6 @@ static double cbrt(double x); #endif /* HAVE_CBRT */ -/* - * Routines to provide reasonably platform-independent handling of - * infinity and NaN. We assume that isinf() and isnan() are available - * and work per spec. (On some platforms, we have to supply our own; - * see src/port.) However, generating an Infinity or NaN in the first - * place is less well standardized; pre-C99 systems tend not to have C99's - * INFINITY and NAN macros. We centralize our workarounds for this here. - */ - -double -get_float8_infinity(void) -{ -#ifdef INFINITY - /* C99 standard way */ - return (double) INFINITY; -#else - - /* - * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the - * largest normal double. We assume forcing an overflow will get us a - * true infinity. - */ - return (double) (HUGE_VAL * HUGE_VAL); -#endif -} - -/* -* The funny placements of the two #pragmas is necessary because of a -* long lived bug in the Microsoft compilers. -* See http://support.microsoft.com/kb/120968/en-us for details -*/ -#if (_MSC_VER >= 1800) -#pragma warning(disable:4756) -#endif -float -get_float4_infinity(void) -{ -#ifdef INFINITY - /* C99 standard way */ - return (float) INFINITY; -#else -#if (_MSC_VER >= 1800) -#pragma warning(default:4756) -#endif - - /* - * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the - * largest normal double. We assume forcing an overflow will get us a - * true infinity. - */ - return (float) (HUGE_VAL * HUGE_VAL); -#endif -} - -double -get_float8_nan(void) -{ - /* (double) NAN doesn't work on some NetBSD/MIPS releases */ -#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__)) - /* C99 standard way */ - return (double) NAN; -#else - /* Assume we can get a NAN via zero divide */ - return (double) (0.0 / 0.0); -#endif -} - -float -get_float4_nan(void) -{ -#ifdef NAN - /* C99 standard way */ - return (float) NAN; -#else - /* Assume we can get a NAN via zero divide */ - return (float) (0.0 / 0.0); -#endif -} - - /* * Returns -1 if 'val' represents negative infinity, 1 if 'val' * represents (positive) infinity, and 0 otherwise. On some platforms, @@ -211,13 +112,39 @@ is_infinite(double val) /* * float4in - converts "num" to float4 + * + * Note that this code now uses strtof(), where it used to use strtod(). + * + * The motivation for using strtof() is to avoid a double-rounding problem: + * for certain decimal inputs, if you round the input correctly to a double, + * and then round the double to a float, the result is incorrect in that it + * does not match the result of rounding the decimal value to float directly. + * + * One of the best examples is 7.038531e-26: + * + * 0xAE43FDp-107 = 7.03853069185120912085...e-26 + * midpoint 7.03853100000000022281...e-26 + * 0xAE43FEp-107 = 7.03853130814879132477...e-26 + * + * making 0xAE43FDp-107 the correct float result, but if you do the conversion + * via a double, you get + * + * 0xAE43FD.7FFFFFF8p-107 = 7.03853099999999907487...e-26 + * midpoint 7.03853099999999964884...e-26 + * 0xAE43FD.80000000p-107 = 7.03853100000000022281...e-26 + * 0xAE43FD.80000008p-107 = 7.03853100000000137076...e-26 + * + * so the value rounds to the double exactly on the midpoint between the two + * nearest floats, and then rounding again to a float gives the incorrect + * result of 0xAE43FEp-107. + * */ Datum float4in(PG_FUNCTION_ARGS) { char *num = PG_GETARG_CSTRING(0); char *orig_num; - double val; + float val; char *endptr; /* @@ -242,7 +169,7 @@ float4in(PG_FUNCTION_ARGS) "real", orig_num))); errno = 0; - val = strtod(num, &endptr); + val = strtof(num, &endptr); /* did we not see anything that looks like a double? */ if (endptr == num || errno != 0) @@ -250,14 +177,14 @@ float4in(PG_FUNCTION_ARGS) int save_errno = errno; /* - * C99 requires that strtod() accept NaN, [+-]Infinity, and [+-]Inf, + * C99 requires that strtof() accept NaN, [+-]Infinity, and [+-]Inf, * but not all platforms support all of these (and some accept them * but set ERANGE anyway...) Therefore, we check for these inputs - * ourselves if strtod() fails. + * ourselves if strtof() fails. * * Note: C99 also requires hexadecimal input as well as some extended * forms of NaN, but we consider these forms unportable and don't try - * to support them. You can use 'em if your strtod() takes 'em. + * to support them. You can use 'em if your strtof() takes 'em. */ if (pg_strncasecmp(num, "NaN", 3) == 0) { @@ -302,8 +229,18 @@ float4in(PG_FUNCTION_ARGS) * precision). We'd prefer not to throw error for that, so try to * detect whether it's a "real" out-of-range condition by checking * to see if the result is zero or huge. + * + * Use isinf() rather than HUGE_VALF on VS2013 because it + * generates a spurious overflow warning for -HUGE_VALF. Also use + * isinf() if HUGE_VALF is missing. */ - if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) + if (val == 0.0 || +#if !defined(HUGE_VALF) || (defined(_MSC_VER) && (_MSC_VER < 1900)) + isinf(val) +#else + (val >= HUGE_VALF || val <= -HUGE_VALF) +#endif + ) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("\"%s\" is out of range for type real", @@ -339,13 +276,7 @@ float4in(PG_FUNCTION_ARGS) errmsg("invalid input syntax for type %s: \"%s\"", "real", orig_num))); - /* - * if we get here, we have a legal double, still need to check to see if - * it's a legal float4 - */ - CHECKFLOATVAL((float4) val, isinf(val), val == 0); - - PG_RETURN_FLOAT4((float4) val); + PG_RETURN_FLOAT4(val); } /* @@ -356,30 +287,16 @@ Datum float4out(PG_FUNCTION_ARGS) { float4 num = PG_GETARG_FLOAT4(0); - char *ascii; + char *ascii = (char *) palloc(32); + int ndig = FLT_DIG + extra_float_digits; - if (isnan(num)) - PG_RETURN_CSTRING(pstrdup("NaN")); - - switch (is_infinite(num)) + if (extra_float_digits > 0) { - case 1: - ascii = pstrdup("Infinity"); - break; - case -1: - ascii = pstrdup("-Infinity"); - break; - default: - { - int ndig = FLT_DIG + extra_float_digits; - - if (ndig < 1) - ndig = 1; - - ascii = psprintf("%.*g", ndig, num); - } + float_to_shortest_decimal_buf(num, ascii); + PG_RETURN_CSTRING(ascii); } + (void) pg_strfromd(ascii, 32, ndig, num); PG_RETURN_CSTRING(ascii); } @@ -419,8 +336,19 @@ float8in(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(float8in_internal(num, NULL, "double precision", num)); } +/* Convenience macro: set *have_error flag (if provided) or throw error */ +#define RETURN_ERROR(throw_error, have_error) \ +do { \ + if (have_error) { \ + *have_error = true; \ + return 0.0; \ + } else { \ + throw_error; \ + } \ +} while (0) + /* - * float8in_internal - guts of float8in() + * float8in_internal_opt_error - guts of float8in() * * This is exposed for use by functions that want a reasonably * platform-independent way of inputting doubles. The behavior is @@ -436,14 +364,21 @@ float8in(PG_FUNCTION_ARGS) * * "num" could validly be declared "const char *", but that results in an * unreasonable amount of extra casting both here and in callers, so we don't. + * + * When "*have_error" flag is provided, it's set instead of throwing an + * error. This is helpful when caller need to handle errors by itself. */ double -float8in_internal(char *num, char **endptr_p, - const char *type_name, const char *orig_string) +float8in_internal_opt_error(char *num, char **endptr_p, + const char *type_name, const char *orig_string, + bool *have_error) { double val; char *endptr; + if (have_error) + *have_error = false; + /* skip leading whitespace */ while (*num != '\0' && isspace((unsigned char) *num)) num++; @@ -453,10 +388,11 @@ float8in_internal(char *num, char **endptr_p, * strtod() on different platforms. */ if (*num == '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - type_name, orig_string))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", + type_name, orig_string))), + have_error); errno = 0; val = strtod(num, &endptr); @@ -529,17 +465,20 @@ float8in_internal(char *num, char **endptr_p, char *errnumber = pstrdup(num); errnumber[endptr - num] = '\0'; - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("\"%s\" is out of range for type double precision", - errnumber))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("\"%s\" is out of range for type double precision", + errnumber))), + have_error); } } else - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - type_name, orig_string))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type " + "%s: \"%s\"", + type_name, orig_string))), + have_error); } #ifdef HAVE_BUGGY_SOLARIS_STRTOD else @@ -562,14 +501,28 @@ float8in_internal(char *num, char **endptr_p, if (endptr_p) *endptr_p = endptr; else if (*endptr != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - type_name, orig_string))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type " + "%s: \"%s\"", + type_name, orig_string))), + have_error); return val; } +/* + * Interface to float8in_internal_opt_error() without "have_error" argument. + */ +double +float8in_internal(char *num, char **endptr_p, + const char *type_name, const char *orig_string) +{ + return float8in_internal_opt_error(num, endptr_p, type_name, + orig_string, NULL); +} + + /* * float8out - converts float8 number to a string * using a standard output format @@ -592,30 +545,16 @@ float8out(PG_FUNCTION_ARGS) char * float8out_internal(double num) { - char *ascii; - - if (isnan(num)) - return pstrdup("NaN"); + char *ascii = (char *) palloc(32); + int ndig = DBL_DIG + extra_float_digits; - switch (is_infinite(num)) + if (extra_float_digits > 0) { - case 1: - ascii = pstrdup("Infinity"); - break; - case -1: - ascii = pstrdup("-Infinity"); - break; - default: - { - int ndig = DBL_DIG + extra_float_digits; - - if (ndig < 1) - ndig = 1; - - ascii = psprintf("%.*g", ndig, num); - } + double_to_shortest_decimal_buf(num, ascii); + return ascii; } + (void) pg_strfromd(ascii, 32, ndig, num); return ascii; } @@ -693,7 +632,7 @@ float4larger(PG_FUNCTION_ARGS) float4 arg2 = PG_GETARG_FLOAT4(1); float4 result; - if (float4_cmp_internal(arg1, arg2) > 0) + if (float4_gt(arg1, arg2)) result = arg1; else result = arg2; @@ -707,7 +646,7 @@ float4smaller(PG_FUNCTION_ARGS) float4 arg2 = PG_GETARG_FLOAT4(1); float4 result; - if (float4_cmp_internal(arg1, arg2) < 0) + if (float4_lt(arg1, arg2)) result = arg1; else result = arg2; @@ -760,7 +699,7 @@ float8larger(PG_FUNCTION_ARGS) float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; - if (float8_cmp_internal(arg1, arg2) > 0) + if (float8_gt(arg1, arg2)) result = arg1; else result = arg2; @@ -774,7 +713,7 @@ float8smaller(PG_FUNCTION_ARGS) float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; - if (float8_cmp_internal(arg1, arg2) < 0) + if (float8_lt(arg1, arg2)) result = arg1; else result = arg2; @@ -799,19 +738,8 @@ float4pl(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float4 result; - - result = arg1 + arg2; - /* - * There isn't any way to check for underflow of addition/subtraction - * because numbers near the underflow value have already been rounded to - * the point where we can't detect that the two values were originally - * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 == - * 1.4013e-45. - */ - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT4(result); + PG_RETURN_FLOAT4(float4_pl(arg1, arg2)); } Datum @@ -819,11 +747,8 @@ float4mi(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float4 result; - result = arg1 - arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT4(result); + PG_RETURN_FLOAT4(float4_mi(arg1, arg2)); } Datum @@ -831,12 +756,8 @@ float4mul(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float4 result; - result = arg1 * arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), - arg1 == 0 || arg2 == 0); - PG_RETURN_FLOAT4(result); + PG_RETURN_FLOAT4(float4_mul(arg1, arg2)); } Datum @@ -844,17 +765,8 @@ float4div(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float4 result; - - if (arg2 == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - result = arg1 / arg2; - - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); - PG_RETURN_FLOAT4(result); + PG_RETURN_FLOAT4(float4_div(arg1, arg2)); } /* @@ -868,12 +780,8 @@ float8pl(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - - result = arg1 + arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_pl(arg1, arg2)); } Datum @@ -881,12 +789,8 @@ float8mi(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - result = arg1 - arg2; - - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mi(arg1, arg2)); } Datum @@ -894,13 +798,8 @@ float8mul(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - - result = arg1 * arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), - arg1 == 0 || arg2 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mul(arg1, arg2)); } Datum @@ -908,17 +807,8 @@ float8div(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - - if (arg2 == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - - result = arg1 / arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_div(arg1, arg2)); } @@ -934,31 +824,11 @@ float8div(PG_FUNCTION_ARGS) int float4_cmp_internal(float4 a, float4 b) { - /* - * We consider all NANs to be equal and larger than any non-NAN. This is - * somewhat arbitrary; the important thing is to have a consistent sort - * order. - */ - if (isnan(a)) - { - if (isnan(b)) - return 0; /* NAN = NAN */ - else - return 1; /* NAN > non-NAN */ - } - else if (isnan(b)) - { - return -1; /* non-NAN < NAN */ - } - else - { - if (a > b) - return 1; - else if (a < b) - return -1; - else - return 0; - } + if (float4_gt(a, b)) + return 1; + if (float4_lt(a, b)) + return -1; + return 0; } Datum @@ -967,7 +837,7 @@ float4eq(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) == 0); + PG_RETURN_BOOL(float4_eq(arg1, arg2)); } Datum @@ -976,7 +846,7 @@ float4ne(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) != 0); + PG_RETURN_BOOL(float4_ne(arg1, arg2)); } Datum @@ -985,7 +855,7 @@ float4lt(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) < 0); + PG_RETURN_BOOL(float4_lt(arg1, arg2)); } Datum @@ -994,7 +864,7 @@ float4le(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) <= 0); + PG_RETURN_BOOL(float4_le(arg1, arg2)); } Datum @@ -1003,7 +873,7 @@ float4gt(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) > 0); + PG_RETURN_BOOL(float4_gt(arg1, arg2)); } Datum @@ -1012,7 +882,7 @@ float4ge(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float4_cmp_internal(arg1, arg2) >= 0); + PG_RETURN_BOOL(float4_ge(arg1, arg2)); } Datum @@ -1048,31 +918,11 @@ btfloat4sortsupport(PG_FUNCTION_ARGS) int float8_cmp_internal(float8 a, float8 b) { - /* - * We consider all NANs to be equal and larger than any non-NAN. This is - * somewhat arbitrary; the important thing is to have a consistent sort - * order. - */ - if (isnan(a)) - { - if (isnan(b)) - return 0; /* NAN = NAN */ - else - return 1; /* NAN > non-NAN */ - } - else if (isnan(b)) - { - return -1; /* non-NAN < NAN */ - } - else - { - if (a > b) - return 1; - else if (a < b) - return -1; - else - return 0; - } + if (float8_gt(a, b)) + return 1; + if (float8_lt(a, b)) + return -1; + return 0; } Datum @@ -1081,7 +931,7 @@ float8eq(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) == 0); + PG_RETURN_BOOL(float8_eq(arg1, arg2)); } Datum @@ -1090,7 +940,7 @@ float8ne(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) != 0); + PG_RETURN_BOOL(float8_ne(arg1, arg2)); } Datum @@ -1099,7 +949,7 @@ float8lt(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) < 0); + PG_RETURN_BOOL(float8_lt(arg1, arg2)); } Datum @@ -1108,7 +958,7 @@ float8le(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) <= 0); + PG_RETURN_BOOL(float8_le(arg1, arg2)); } Datum @@ -1117,7 +967,7 @@ float8gt(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) > 0); + PG_RETURN_BOOL(float8_gt(arg1, arg2)); } Datum @@ -1126,7 +976,7 @@ float8ge(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) >= 0); + PG_RETURN_BOOL(float8_ge(arg1, arg2)); } Datum @@ -1198,7 +1048,7 @@ in_range_float8_float8(PG_FUNCTION_ARGS) */ if (isnan(offset) || offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* @@ -1254,16 +1104,64 @@ in_range_float8_float8(PG_FUNCTION_ARGS) Datum in_range_float4_float8(PG_FUNCTION_ARGS) { - /* Doesn't seem worth duplicating code for, so just invoke float8_float8 */ - float8 val = (float8) PG_GETARG_FLOAT4(0); - float8 base = (float8) PG_GETARG_FLOAT4(1); + float4 val = PG_GETARG_FLOAT4(0); + float4 base = PG_GETARG_FLOAT4(1); + float8 offset = PG_GETARG_FLOAT8(2); + bool sub = PG_GETARG_BOOL(3); + bool less = PG_GETARG_BOOL(4); + float8 sum; + + /* + * Reject negative or NaN offset. Negative is per spec, and NaN is + * because appropriate semantics for that seem non-obvious. + */ + if (isnan(offset) || offset < 0) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), + errmsg("invalid preceding or following size in window function"))); + + /* + * Deal with cases where val and/or base is NaN, following the rule that + * NaN sorts after non-NaN (cf float8_cmp_internal). The offset cannot + * affect the conclusion. + */ + if (isnan(val)) + { + if (isnan(base)) + PG_RETURN_BOOL(true); /* NAN = NAN */ + else + PG_RETURN_BOOL(!less); /* NAN > non-NAN */ + } + else if (isnan(base)) + { + PG_RETURN_BOOL(less); /* non-NAN < NAN */ + } + + /* + * Deal with infinite offset (necessarily +inf, at this point). We must + * special-case this because if base happens to be -inf, their sum would + * be NaN, which is an overflow-ish condition we should avoid. + */ + if (isinf(offset)) + { + PG_RETURN_BOOL(sub ? !less : less); + } + + /* + * Otherwise it should be safe to compute base +/- offset. We trust the + * FPU to cope if base is +/-inf or the true sum would overflow, and + * produce a suitably signed infinity, which will compare properly against + * val whether or not that's infinity. + */ + if (sub) + sum = base - offset; + else + sum = base + offset; - return DirectFunctionCall5(in_range_float8_float8, - Float8GetDatumFast(val), - Float8GetDatumFast(base), - PG_GETARG_DATUM(2), - PG_GETARG_DATUM(3), - PG_GETARG_DATUM(4)); + if (less) + PG_RETURN_BOOL(val <= sum); + else + PG_RETURN_BOOL(val >= sum); } @@ -1293,7 +1191,7 @@ dtof(PG_FUNCTION_ARGS) { float8 num = PG_GETARG_FLOAT8(0); - CHECKFLOATVAL((float4) num, isinf(num), num == 0); + check_float4_val((float4) num, isinf(num), num == 0); PG_RETURN_FLOAT4((float4) num); } @@ -1306,16 +1204,28 @@ Datum dtoi4(PG_FUNCTION_ARGS) { float8 num = PG_GETARG_FLOAT8(0); - int32 result; - /* 'Inf' is handled by INT_MAX */ - if (num < INT_MIN || num > INT_MAX || isnan(num)) + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); + + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT32_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT32_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float8) PG_INT32_MIN || + num >= -((float8) PG_INT32_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); - result = (int32) rint(num); - PG_RETURN_INT32(result); + PG_RETURN_INT32((int32) num); } @@ -1327,12 +1237,27 @@ dtoi2(PG_FUNCTION_ARGS) { float8 num = PG_GETARG_FLOAT8(0); - if (num < SHRT_MIN || num > SHRT_MAX || isnan(num)) + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); + + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT16_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT16_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float8) PG_INT16_MIN || + num >= -((float8) PG_INT16_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); - PG_RETURN_INT16((int16) rint(num)); + PG_RETURN_INT16((int16) num); } @@ -1368,12 +1293,27 @@ ftoi4(PG_FUNCTION_ARGS) { float4 num = PG_GETARG_FLOAT4(0); - if (num < INT_MIN || num > INT_MAX || isnan(num)) + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); + + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT32_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT32_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float4) PG_INT32_MIN || + num >= -((float4) PG_INT32_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); - PG_RETURN_INT32((int32) rint(num)); + PG_RETURN_INT32((int32) num); } @@ -1385,12 +1325,27 @@ ftoi2(PG_FUNCTION_ARGS) { float4 num = PG_GETARG_FLOAT4(0); - if (num < SHRT_MIN || num > SHRT_MAX || isnan(num)) + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); + + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT16_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT16_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float4) PG_INT16_MIN || + num >= -((float4) PG_INT16_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("smallint out of range"))); - PG_RETURN_INT16((int16) rint(num)); + PG_RETURN_INT16((int16) num); } @@ -1518,7 +1473,7 @@ dsqrt(PG_FUNCTION_ARGS) result = sqrt(arg1); - CHECKFLOATVAL(result, isinf(arg1), arg1 == 0); + check_float8_val(result, isinf(arg1), arg1 == 0); PG_RETURN_FLOAT8(result); } @@ -1533,7 +1488,7 @@ dcbrt(PG_FUNCTION_ARGS) float8 result; result = cbrt(arg1); - CHECKFLOATVAL(result, isinf(arg1), arg1 == 0); + check_float8_val(result, isinf(arg1), arg1 == 0); PG_RETURN_FLOAT8(result); } @@ -1548,6 +1503,25 @@ dpow(PG_FUNCTION_ARGS) float8 arg2 = PG_GETARG_FLOAT8(1); float8 result; + /* + * The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other + * cases with NaN inputs yield NaN (with no error). Many older platforms + * get one or more of these cases wrong, so deal with them via explicit + * logic rather than trusting pow(3). + */ + if (isnan(arg1)) + { + if (isnan(arg2) || arg2 != 0.0) + PG_RETURN_FLOAT8(get_float8_nan()); + PG_RETURN_FLOAT8(1.0); + } + if (isnan(arg2)) + { + if (arg1 != 1.0) + PG_RETURN_FLOAT8(get_float8_nan()); + PG_RETURN_FLOAT8(1.0); + } + /* * The SQL spec requires that we emit a particular SQLSTATE error code for * certain error conditions. Specifically, we don't return a @@ -1566,7 +1540,7 @@ dpow(PG_FUNCTION_ARGS) * pow() sets errno only on some platforms, depending on whether it * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid using * errno. However, some platform/CPU combinations return errno == EDOM - * and result == Nan for negative arg1 and very large arg2 (they must be + * and result == NaN for negative arg1 and very large arg2 (they must be * using something different from our floor() test to decide it's * invalid). Other platforms (HPPA) return errno == ERANGE and a large * (HUGE_VAL) but finite result to signal overflow. @@ -1586,7 +1560,7 @@ dpow(PG_FUNCTION_ARGS) else if (errno == ERANGE && result != 0 && !isinf(result)) result = get_float8_infinity(); - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); + check_float8_val(result, isinf(arg1) || isinf(arg2), arg1 == 0); PG_RETURN_FLOAT8(result); } @@ -1605,7 +1579,7 @@ dexp(PG_FUNCTION_ARGS) if (errno == ERANGE && result != 0 && !isinf(result)) result = get_float8_infinity(); - CHECKFLOATVAL(result, isinf(arg1), false); + check_float8_val(result, isinf(arg1), false); PG_RETURN_FLOAT8(result); } @@ -1634,7 +1608,7 @@ dlog1(PG_FUNCTION_ARGS) result = log(arg1); - CHECKFLOATVAL(result, isinf(arg1), arg1 == 1); + check_float8_val(result, isinf(arg1), arg1 == 1); PG_RETURN_FLOAT8(result); } @@ -1664,7 +1638,7 @@ dlog10(PG_FUNCTION_ARGS) result = log10(arg1); - CHECKFLOATVAL(result, isinf(arg1), arg1 == 1); + check_float8_val(result, isinf(arg1), arg1 == 1); PG_RETURN_FLOAT8(result); } @@ -1694,7 +1668,7 @@ dacos(PG_FUNCTION_ARGS) result = acos(arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1724,7 +1698,7 @@ dasin(PG_FUNCTION_ARGS) result = asin(arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1749,7 +1723,7 @@ datan(PG_FUNCTION_ARGS) */ result = atan(arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1774,7 +1748,7 @@ datan2(PG_FUNCTION_ARGS) */ result = atan2(arg1, arg2); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1814,7 +1788,7 @@ dcos(PG_FUNCTION_ARGS) (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1841,7 +1815,7 @@ dcot(PG_FUNCTION_ARGS) errmsg("input is out of range"))); result = 1.0 / result; - CHECKFLOATVAL(result, true /* cot(0) == Inf */ , true); + check_float8_val(result, true /* cot(0) == Inf */ , true); PG_RETURN_FLOAT8(result); } @@ -1867,7 +1841,7 @@ dsin(PG_FUNCTION_ARGS) (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -1893,7 +1867,7 @@ dtan(PG_FUNCTION_ARGS) (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("input is out of range"))); - CHECKFLOATVAL(result, true /* tan(pi/2) == Inf */ , true); + check_float8_val(result, true /* tan(pi/2) == Inf */ , true); PG_RETURN_FLOAT8(result); } @@ -2045,7 +2019,7 @@ dacosd(PG_FUNCTION_ARGS) else result = 90.0 + asind_q1(-arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2080,7 +2054,7 @@ dasind(PG_FUNCTION_ARGS) else result = -asind_q1(-arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2110,7 +2084,7 @@ datand(PG_FUNCTION_ARGS) atan_arg1 = atan(arg1); result = (atan_arg1 / atan_1_0) * 45.0; - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2144,7 +2118,7 @@ datan2d(PG_FUNCTION_ARGS) atan2_arg1_arg2 = atan2(arg1, arg2); result = (atan2_arg1_arg2 / atan_1_0) * 45.0; - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2265,7 +2239,7 @@ dcosd(PG_FUNCTION_ARGS) result = sign * cosd_q1(arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2330,7 +2304,7 @@ dcotd(PG_FUNCTION_ARGS) if (result == 0.0) result = 0.0; - CHECKFLOATVAL(result, true /* cotd(0) == Inf */ , true); + check_float8_val(result, true /* cotd(0) == Inf */ , true); PG_RETURN_FLOAT8(result); } @@ -2384,7 +2358,7 @@ dsind(PG_FUNCTION_ARGS) result = sign * sind_q1(arg1); - CHECKFLOATVAL(result, false, true); + check_float8_val(result, false, true); PG_RETURN_FLOAT8(result); } @@ -2449,7 +2423,7 @@ dtand(PG_FUNCTION_ARGS) if (result == 0.0) result = 0.0; - CHECKFLOATVAL(result, true /* tand(90) == Inf */ , true); + check_float8_val(result, true /* tand(90) == Inf */ , true); PG_RETURN_FLOAT8(result); } @@ -2461,12 +2435,8 @@ Datum degrees(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); - float8 result; - - result = arg1 / RADIANS_PER_DEGREE; - CHECKFLOATVAL(result, isinf(arg1), arg1 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_div(arg1, RADIANS_PER_DEGREE)); } @@ -2485,13 +2455,163 @@ dpi(PG_FUNCTION_ARGS) */ Datum radians(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + + PG_RETURN_FLOAT8(float8_mul(arg1, RADIANS_PER_DEGREE)); +} + + +/* ========== HYPERBOLIC FUNCTIONS ========== */ + + +/* + * dsinh - returns the hyperbolic sine of arg1 + */ +Datum +dsinh(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + float8 result; + + errno = 0; + result = sinh(arg1); + + /* + * if an ERANGE error occurs, it means there is an overflow. For sinh, + * the result should be either -infinity or infinity, depending on the + * sign of arg1. + */ + if (errno == ERANGE) + { + if (arg1 < 0) + result = -get_float8_infinity(); + else + result = get_float8_infinity(); + } + + check_float8_val(result, true, true); + PG_RETURN_FLOAT8(result); +} + + +/* + * dcosh - returns the hyperbolic cosine of arg1 + */ +Datum +dcosh(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + float8 result; + + errno = 0; + result = cosh(arg1); + + /* + * if an ERANGE error occurs, it means there is an overflow. As cosh is + * always positive, it always means the result is positive infinity. + */ + if (errno == ERANGE) + result = get_float8_infinity(); + + check_float8_val(result, true, false); + PG_RETURN_FLOAT8(result); +} + +/* + * dtanh - returns the hyperbolic tangent of arg1 + */ +Datum +dtanh(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + float8 result; + + /* + * For tanh, we don't need an errno check because it never overflows. + */ + result = tanh(arg1); + + check_float8_val(result, false, true); + PG_RETURN_FLOAT8(result); +} + +/* + * dasinh - returns the inverse hyperbolic sine of arg1 + */ +Datum +dasinh(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + float8 result; + + /* + * For asinh, we don't need an errno check because it never overflows. + */ + result = asinh(arg1); + + check_float8_val(result, true, true); + PG_RETURN_FLOAT8(result); +} + +/* + * dacosh - returns the inverse hyperbolic cosine of arg1 + */ +Datum +dacosh(PG_FUNCTION_ARGS) +{ + float8 arg1 = PG_GETARG_FLOAT8(0); + float8 result; + + /* + * acosh is only defined for inputs >= 1.0. By checking this ourselves, + * we need not worry about checking for an EDOM error, which is a good + * thing because some implementations will report that for NaN. Otherwise, + * no error is possible. + */ + if (arg1 < 1.0) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("input is out of range"))); + + result = acosh(arg1); + + check_float8_val(result, true, true); + PG_RETURN_FLOAT8(result); +} + +/* + * datanh - returns the inverse hyperbolic tangent of arg1 + */ +Datum +datanh(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float8 result; - result = arg1 * RADIANS_PER_DEGREE; + /* + * atanh is only defined for inputs between -1 and 1. By checking this + * ourselves, we need not worry about checking for an EDOM error, which is + * a good thing because some implementations will report that for NaN. + */ + if (arg1 < -1.0 || arg1 > 1.0) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("input is out of range"))); + + /* + * Also handle the infinity cases ourselves; this is helpful because old + * glibc versions may produce the wrong errno for this. All other inputs + * cannot produce an error. + */ + if (arg1 == -1.0) + result = -get_float8_infinity(); + else if (arg1 == 1.0) + result = get_float8_infinity(); + else + result = atanh(arg1); - CHECKFLOATVAL(result, isinf(arg1), arg1 == 0); + check_float8_val(result, true, true); PG_RETURN_FLOAT8(result); } @@ -2504,8 +2624,30 @@ drandom(PG_FUNCTION_ARGS) { float8 result; - /* result [0.0 - 1.0) */ - result = (double) random() / ((double) MAX_RANDOM_VALUE + 1); + /* Initialize random seed, if not done yet in this process */ + if (unlikely(!drandom_seed_set)) + { + /* + * If possible, initialize the seed using high-quality random bits. + * Should that fail for some reason, we fall back on a lower-quality + * seed based on current time and PID. + */ + if (!pg_strong_random(drandom_seed, sizeof(drandom_seed))) + { + TimestampTz now = GetCurrentTimestamp(); + uint64 iseed; + + /* Mix the PID with the most predictable bits of the timestamp */ + iseed = (uint64) now ^ ((uint64) MyProcPid << 32); + drandom_seed[0] = (unsigned short) iseed; + drandom_seed[1] = (unsigned short) (iseed >> 16); + drandom_seed[2] = (unsigned short) (iseed >> 32); + } + drandom_seed_set = true; + } + + /* pg_erand48 produces desired result range [0.0 - 1.0) */ + result = pg_erand48(drandom_seed); PG_RETURN_FLOAT8(result); } @@ -2518,13 +2660,20 @@ Datum setseed(PG_FUNCTION_ARGS) { float8 seed = PG_GETARG_FLOAT8(0); - int iseed; + uint64 iseed; - if (seed < -1 || seed > 1) - elog(ERROR, "setseed parameter %f out of range [-1,1]", seed); + if (seed < -1 || seed > 1 || isnan(seed)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("setseed parameter %g is out of allowed range [-1,1]", + seed))); - iseed = (int) (seed * MAX_RANDOM_VALUE); - srandom((unsigned int) iseed); + /* Use sign bit + 47 fractional bits to fill drandom_seed[] */ + iseed = (int64) (seed * (float8) UINT64CONST(0x7FFFFFFFFFFF)); + drandom_seed[0] = (unsigned short) iseed; + drandom_seed[1] = (unsigned short) (iseed >> 16); + drandom_seed[2] = (unsigned short) (iseed >> 32); + drandom_seed_set = true; PG_RETURN_VOID(); } @@ -2544,13 +2693,39 @@ setseed(PG_FUNCTION_ARGS) * float8_stddev_samp - produce final result for float STDDEV_SAMP() * float8_stddev_pop - produce final result for float STDDEV_POP() * + * The naive schoolbook implementation of these aggregates works by + * accumulating sum(X) and sum(X^2). However, this approach suffers from + * large rounding errors in the final computation of quantities like the + * population variance (N*sum(X^2) - sum(X)^2) / N^2, since each of the + * intermediate terms is potentially very large, while the difference is often + * quite small. + * + * Instead we use the Youngs-Cramer algorithm [1] which works by accumulating + * Sx=sum(X) and Sxx=sum((X-Sx/N)^2), using a numerically stable algorithm to + * incrementally update those quantities. The final computations of each of + * the aggregate values is then trivial and gives more accurate results (for + * example, the population variance is just Sxx/N). This algorithm is also + * fairly easy to generalize to allow parallel execution without loss of + * precision (see, for example, [2]). For more details, and a comparison of + * this with other algorithms, see [3]. + * * The transition datatype for all these aggregates is a 3-element array - * of float8, holding the values N, sum(X), sum(X*X) in that order. + * of float8, holding the values N, Sx, Sxx in that order. * * Note that we represent N as a float to avoid having to build a special * datatype. Given a reasonable floating-point implementation, there should * be no accuracy loss unless N exceeds 2 ^ 52 or so (by which time the * user will have doubtless lost interest anyway...) + * + * [1] Some Results Relevant to Choice of Sum and Sum-of-Product Algorithms, + * E. A. Youngs and E. M. Cramer, Technometrics Vol 13, No 3, August 1971. + * + * [2] Updating Formulae and a Pairwise Algorithm for Computing Sample + * Variances, T. F. Chan, G. H. Golub & R. J. LeVeque, COMPSTAT 1982. + * + * [3] Numerically Stable Parallel Computation of (Co-)Variance, Erich + * Schubert and Michael Gertz, Proceedings of the 30th International + * Conference on Scientific and Statistical Database Management, 2018. */ static float8 * @@ -2584,33 +2759,90 @@ float8_combine(PG_FUNCTION_ARGS) ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1); float8 *transvalues1; float8 *transvalues2; - float8 N, - sumX, - sumX2; - - if (!AggCheckCallContext(fcinfo, NULL)) - elog(ERROR, "aggregate function called in non-aggregate context"); + float8 N1, + Sx1, + Sxx1, + N2, + Sx2, + Sxx2, + tmp, + N, + Sx, + Sxx; transvalues1 = check_float8_array(transarray1, "float8_combine", 3); - N = transvalues1[0]; - sumX = transvalues1[1]; - sumX2 = transvalues1[2]; - transvalues2 = check_float8_array(transarray2, "float8_combine", 3); - N += transvalues2[0]; - sumX += transvalues2[1]; - CHECKFLOATVAL(sumX, isinf(transvalues1[1]) || isinf(transvalues2[1]), - true); - sumX2 += transvalues2[2]; - CHECKFLOATVAL(sumX2, isinf(transvalues1[2]) || isinf(transvalues2[2]), - true); + N1 = transvalues1[0]; + Sx1 = transvalues1[1]; + Sxx1 = transvalues1[2]; + + N2 = transvalues2[0]; + Sx2 = transvalues2[1]; + Sxx2 = transvalues2[2]; + + /*-------------------- + * The transition values combine using a generalization of the + * Youngs-Cramer algorithm as follows: + * + * N = N1 + N2 + * Sx = Sx1 + Sx2 + * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N; + * + * It's worth handling the special cases N1 = 0 and N2 = 0 separately + * since those cases are trivial, and we then don't need to worry about + * division-by-zero errors in the general case. + *-------------------- + */ + if (N1 == 0.0) + { + N = N2; + Sx = Sx2; + Sxx = Sxx2; + } + else if (N2 == 0.0) + { + N = N1; + Sx = Sx1; + Sxx = Sxx1; + } + else + { + N = N1 + N2; + Sx = float8_pl(Sx1, Sx2); + tmp = Sx1 / N1 - Sx2 / N2; + Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp * tmp / N; + check_float8_val(Sxx, isinf(Sxx1) || isinf(Sxx2), true); + } + + /* + * If we're invoked as an aggregate, we can cheat and modify our first + * parameter in-place to reduce palloc overhead. Otherwise we construct a + * new array with the updated transition data and return it. + */ + if (AggCheckCallContext(fcinfo, NULL)) + { + transvalues1[0] = N; + transvalues1[1] = Sx; + transvalues1[2] = Sxx; + + PG_RETURN_ARRAYTYPE_P(transarray1); + } + else + { + Datum transdatums[3]; + ArrayType *result; + + transdatums[0] = Float8GetDatumFast(N); + transdatums[1] = Float8GetDatumFast(Sx); + transdatums[2] = Float8GetDatumFast(Sxx); - transvalues1[0] = N; - transvalues1[1] = sumX; - transvalues1[2] = sumX2; + result = construct_array(transdatums, 3, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, 'd'); - PG_RETURN_ARRAYTYPE_P(transarray1); + PG_RETURN_ARRAYTYPE_P(result); + } } Datum @@ -2620,19 +2852,42 @@ float8_accum(PG_FUNCTION_ARGS) float8 newval = PG_GETARG_FLOAT8(1); float8 *transvalues; float8 N, - sumX, - sumX2; + Sx, + Sxx, + tmp; transvalues = check_float8_array(transarray, "float8_accum", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + Sx = transvalues[1]; + Sxx = transvalues[2]; + /* + * Use the Youngs-Cramer algorithm to incorporate the new value into the + * transition values. + */ N += 1.0; - sumX += newval; - CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true); - sumX2 += newval * newval; - CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true); + Sx += newval; + if (transvalues[0] > 0.0) + { + tmp = newval * N - Sx; + Sxx += tmp * tmp / (N * transvalues[0]); + + /* + * Overflow check. We only report an overflow error when finite + * inputs lead to infinite results. Note also that Sxx should be NaN + * if any of the inputs are infinite, so we intentionally prevent Sxx + * from becoming infinite. + */ + if (isinf(Sx) || isinf(Sxx)) + { + if (!isinf(transvalues[1]) && !isinf(newval)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); + + Sxx = get_float8_nan(); + } + } /* * If we're invoked as an aggregate, we can cheat and modify our first @@ -2642,8 +2897,8 @@ float8_accum(PG_FUNCTION_ARGS) if (AggCheckCallContext(fcinfo, NULL)) { transvalues[0] = N; - transvalues[1] = sumX; - transvalues[2] = sumX2; + transvalues[1] = Sx; + transvalues[2] = Sxx; PG_RETURN_ARRAYTYPE_P(transarray); } @@ -2653,8 +2908,8 @@ float8_accum(PG_FUNCTION_ARGS) ArrayType *result; transdatums[0] = Float8GetDatumFast(N); - transdatums[1] = Float8GetDatumFast(sumX); - transdatums[2] = Float8GetDatumFast(sumX2); + transdatums[1] = Float8GetDatumFast(Sx); + transdatums[2] = Float8GetDatumFast(Sxx); result = construct_array(transdatums, 3, FLOAT8OID, @@ -2673,19 +2928,42 @@ float4_accum(PG_FUNCTION_ARGS) float8 newval = PG_GETARG_FLOAT4(1); float8 *transvalues; float8 N, - sumX, - sumX2; + Sx, + Sxx, + tmp; transvalues = check_float8_array(transarray, "float4_accum", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + Sx = transvalues[1]; + Sxx = transvalues[2]; + /* + * Use the Youngs-Cramer algorithm to incorporate the new value into the + * transition values. + */ N += 1.0; - sumX += newval; - CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newval), true); - sumX2 += newval * newval; - CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newval), true); + Sx += newval; + if (transvalues[0] > 0.0) + { + tmp = newval * N - Sx; + Sxx += tmp * tmp / (N * transvalues[0]); + + /* + * Overflow check. We only report an overflow error when finite + * inputs lead to infinite results. Note also that Sxx should be NaN + * if any of the inputs are infinite, so we intentionally prevent Sxx + * from becoming infinite. + */ + if (isinf(Sx) || isinf(Sxx)) + { + if (!isinf(transvalues[1]) && !isinf(newval)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); + + Sxx = get_float8_nan(); + } + } /* * If we're invoked as an aggregate, we can cheat and modify our first @@ -2695,8 +2973,8 @@ float4_accum(PG_FUNCTION_ARGS) if (AggCheckCallContext(fcinfo, NULL)) { transvalues[0] = N; - transvalues[1] = sumX; - transvalues[2] = sumX2; + transvalues[1] = Sx; + transvalues[2] = Sxx; PG_RETURN_ARRAYTYPE_P(transarray); } @@ -2706,8 +2984,8 @@ float4_accum(PG_FUNCTION_ARGS) ArrayType *result; transdatums[0] = Float8GetDatumFast(N); - transdatums[1] = Float8GetDatumFast(sumX); - transdatums[2] = Float8GetDatumFast(sumX2); + transdatums[1] = Float8GetDatumFast(Sx); + transdatums[2] = Float8GetDatumFast(Sxx); result = construct_array(transdatums, 3, FLOAT8OID, @@ -2723,18 +3001,18 @@ float8_avg(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX; + Sx; transvalues = check_float8_array(transarray, "float8_avg", 3); N = transvalues[0]; - sumX = transvalues[1]; - /* ignore sumX2 */ + Sx = transvalues[1]; + /* ignore Sxx */ /* SQL defines AVG of no values to be NULL */ if (N == 0.0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(sumX / N); + PG_RETURN_FLOAT8(Sx / N); } Datum @@ -2743,27 +3021,20 @@ float8_var_pop(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - numerator; + Sxx; transvalues = check_float8_array(transarray, "float8_var_pop", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + /* ignore Sx */ + Sxx = transvalues[2]; /* Population variance is undefined when N is 0, so return NULL */ if (N == 0.0) PG_RETURN_NULL(); - numerator = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); + /* Note that Sxx is guaranteed to be non-negative */ - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); - - PG_RETURN_FLOAT8(numerator / (N * N)); + PG_RETURN_FLOAT8(Sxx / N); } Datum @@ -2772,27 +3043,20 @@ float8_var_samp(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - numerator; + Sxx; transvalues = check_float8_array(transarray, "float8_var_samp", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + /* ignore Sx */ + Sxx = transvalues[2]; /* Sample variance is undefined when N is 0 or 1, so return NULL */ if (N <= 1.0) PG_RETURN_NULL(); - numerator = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); - - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); + /* Note that Sxx is guaranteed to be non-negative */ - PG_RETURN_FLOAT8(numerator / (N * (N - 1.0))); + PG_RETURN_FLOAT8(Sxx / (N - 1.0)); } Datum @@ -2801,27 +3065,20 @@ float8_stddev_pop(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - numerator; + Sxx; transvalues = check_float8_array(transarray, "float8_stddev_pop", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + /* ignore Sx */ + Sxx = transvalues[2]; /* Population stddev is undefined when N is 0, so return NULL */ if (N == 0.0) PG_RETURN_NULL(); - numerator = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); + /* Note that Sxx is guaranteed to be non-negative */ - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); - - PG_RETURN_FLOAT8(sqrt(numerator / (N * N))); + PG_RETURN_FLOAT8(sqrt(Sxx / N)); } Datum @@ -2830,27 +3087,20 @@ float8_stddev_samp(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - numerator; + Sxx; transvalues = check_float8_array(transarray, "float8_stddev_samp", 3); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + /* ignore Sx */ + Sxx = transvalues[2]; /* Sample stddev is undefined when N is 0 or 1, so return NULL */ if (N <= 1.0) PG_RETURN_NULL(); - numerator = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); - - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); + /* Note that Sxx is guaranteed to be non-negative */ - PG_RETURN_FLOAT8(sqrt(numerator / (N * (N - 1.0)))); + PG_RETURN_FLOAT8(sqrt(Sxx / (N - 1.0))); } /* @@ -2858,9 +3108,14 @@ float8_stddev_samp(PG_FUNCTION_ARGS) * SQL2003 BINARY AGGREGATES * ========================= * + * As with the preceding aggregates, we use the Youngs-Cramer algorithm to + * reduce rounding errors in the aggregate final functions. + * * The transition datatype for all these aggregates is a 6-element array of - * float8, holding the values N, sum(X), sum(X*X), sum(Y), sum(Y*Y), sum(X*Y) - * in that order. Note that Y is the first argument to the aggregates! + * float8, holding the values N, Sx=sum(X), Sxx=sum((X-Sx/N)^2), Sy=sum(Y), + * Syy=sum((Y-Sy/N)^2), Sxy=sum((X-Sx/N)*(Y-Sy/N)) in that order. + * + * Note that Y is the first argument to all these aggregates! * * It might seem attractive to optimize this by having multiple accumulator * functions that only calculate the sums actually needed. But on most @@ -2877,32 +3132,66 @@ float8_regr_accum(PG_FUNCTION_ARGS) float8 newvalX = PG_GETARG_FLOAT8(2); float8 *transvalues; float8 N, - sumX, - sumX2, - sumY, - sumY2, - sumXY; + Sx, + Sxx, + Sy, + Syy, + Sxy, + tmpX, + tmpY, + scale; transvalues = check_float8_array(transarray, "float8_regr_accum", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; - sumY = transvalues[3]; - sumY2 = transvalues[4]; - sumXY = transvalues[5]; + Sx = transvalues[1]; + Sxx = transvalues[2]; + Sy = transvalues[3]; + Syy = transvalues[4]; + Sxy = transvalues[5]; + /* + * Use the Youngs-Cramer algorithm to incorporate the new values into the + * transition values. + */ N += 1.0; - sumX += newvalX; - CHECKFLOATVAL(sumX, isinf(transvalues[1]) || isinf(newvalX), true); - sumX2 += newvalX * newvalX; - CHECKFLOATVAL(sumX2, isinf(transvalues[2]) || isinf(newvalX), true); - sumY += newvalY; - CHECKFLOATVAL(sumY, isinf(transvalues[3]) || isinf(newvalY), true); - sumY2 += newvalY * newvalY; - CHECKFLOATVAL(sumY2, isinf(transvalues[4]) || isinf(newvalY), true); - sumXY += newvalX * newvalY; - CHECKFLOATVAL(sumXY, isinf(transvalues[5]) || isinf(newvalX) || - isinf(newvalY), true); + Sx += newvalX; + Sy += newvalY; + if (transvalues[0] > 0.0) + { + tmpX = newvalX * N - Sx; + tmpY = newvalY * N - Sy; + scale = 1.0 / (N * transvalues[0]); + Sxx += tmpX * tmpX * scale; + Syy += tmpY * tmpY * scale; + Sxy += tmpX * tmpY * scale; + + /* + * Overflow check. We only report an overflow error when finite + * inputs lead to infinite results. Note also that Sxx, Syy and Sxy + * should be NaN if any of the relevant inputs are infinite, so we + * intentionally prevent them from becoming infinite. + */ + if (isinf(Sx) || isinf(Sxx) || isinf(Sy) || isinf(Syy) || isinf(Sxy)) + { + if (((isinf(Sx) || isinf(Sxx)) && + !isinf(transvalues[1]) && !isinf(newvalX)) || + ((isinf(Sy) || isinf(Syy)) && + !isinf(transvalues[3]) && !isinf(newvalY)) || + (isinf(Sxy) && + !isinf(transvalues[1]) && !isinf(newvalX) && + !isinf(transvalues[3]) && !isinf(newvalY))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); + + if (isinf(Sxx)) + Sxx = get_float8_nan(); + if (isinf(Syy)) + Syy = get_float8_nan(); + if (isinf(Sxy)) + Sxy = get_float8_nan(); + } + } /* * If we're invoked as an aggregate, we can cheat and modify our first @@ -2912,11 +3201,11 @@ float8_regr_accum(PG_FUNCTION_ARGS) if (AggCheckCallContext(fcinfo, NULL)) { transvalues[0] = N; - transvalues[1] = sumX; - transvalues[2] = sumX2; - transvalues[3] = sumY; - transvalues[4] = sumY2; - transvalues[5] = sumXY; + transvalues[1] = Sx; + transvalues[2] = Sxx; + transvalues[3] = Sy; + transvalues[4] = Syy; + transvalues[5] = Sxy; PG_RETURN_ARRAYTYPE_P(transarray); } @@ -2926,11 +3215,11 @@ float8_regr_accum(PG_FUNCTION_ARGS) ArrayType *result; transdatums[0] = Float8GetDatumFast(N); - transdatums[1] = Float8GetDatumFast(sumX); - transdatums[2] = Float8GetDatumFast(sumX2); - transdatums[3] = Float8GetDatumFast(sumY); - transdatums[4] = Float8GetDatumFast(sumY2); - transdatums[5] = Float8GetDatumFast(sumXY); + transdatums[1] = Float8GetDatumFast(Sx); + transdatums[2] = Float8GetDatumFast(Sxx); + transdatums[3] = Float8GetDatumFast(Sy); + transdatums[4] = Float8GetDatumFast(Syy); + transdatums[5] = Float8GetDatumFast(Sxy); result = construct_array(transdatums, 6, FLOAT8OID, @@ -2955,51 +3244,127 @@ float8_regr_combine(PG_FUNCTION_ARGS) ArrayType *transarray2 = PG_GETARG_ARRAYTYPE_P(1); float8 *transvalues1; float8 *transvalues2; - float8 N, - sumX, - sumX2, - sumY, - sumY2, - sumXY; - - if (!AggCheckCallContext(fcinfo, NULL)) - elog(ERROR, "aggregate function called in non-aggregate context"); + float8 N1, + Sx1, + Sxx1, + Sy1, + Syy1, + Sxy1, + N2, + Sx2, + Sxx2, + Sy2, + Syy2, + Sxy2, + tmp1, + tmp2, + N, + Sx, + Sxx, + Sy, + Syy, + Sxy; transvalues1 = check_float8_array(transarray1, "float8_regr_combine", 6); - N = transvalues1[0]; - sumX = transvalues1[1]; - sumX2 = transvalues1[2]; - sumY = transvalues1[3]; - sumY2 = transvalues1[4]; - sumXY = transvalues1[5]; - transvalues2 = check_float8_array(transarray2, "float8_regr_combine", 6); - N += transvalues2[0]; - sumX += transvalues2[1]; - CHECKFLOATVAL(sumX, isinf(transvalues1[1]) || isinf(transvalues2[1]), - true); - sumX2 += transvalues2[2]; - CHECKFLOATVAL(sumX2, isinf(transvalues1[2]) || isinf(transvalues2[2]), - true); - sumY += transvalues2[3]; - CHECKFLOATVAL(sumY, isinf(transvalues1[3]) || isinf(transvalues2[3]), - true); - sumY2 += transvalues2[4]; - CHECKFLOATVAL(sumY2, isinf(transvalues1[4]) || isinf(transvalues2[4]), - true); - sumXY += transvalues2[5]; - CHECKFLOATVAL(sumXY, isinf(transvalues1[5]) || isinf(transvalues2[5]), - true); + N1 = transvalues1[0]; + Sx1 = transvalues1[1]; + Sxx1 = transvalues1[2]; + Sy1 = transvalues1[3]; + Syy1 = transvalues1[4]; + Sxy1 = transvalues1[5]; + + N2 = transvalues2[0]; + Sx2 = transvalues2[1]; + Sxx2 = transvalues2[2]; + Sy2 = transvalues2[3]; + Syy2 = transvalues2[4]; + Sxy2 = transvalues2[5]; + + /*-------------------- + * The transition values combine using a generalization of the + * Youngs-Cramer algorithm as follows: + * + * N = N1 + N2 + * Sx = Sx1 + Sx2 + * Sxx = Sxx1 + Sxx2 + N1 * N2 * (Sx1/N1 - Sx2/N2)^2 / N + * Sy = Sy1 + Sy2 + * Syy = Syy1 + Syy2 + N1 * N2 * (Sy1/N1 - Sy2/N2)^2 / N + * Sxy = Sxy1 + Sxy2 + N1 * N2 * (Sx1/N1 - Sx2/N2) * (Sy1/N1 - Sy2/N2) / N + * + * It's worth handling the special cases N1 = 0 and N2 = 0 separately + * since those cases are trivial, and we then don't need to worry about + * division-by-zero errors in the general case. + *-------------------- + */ + if (N1 == 0.0) + { + N = N2; + Sx = Sx2; + Sxx = Sxx2; + Sy = Sy2; + Syy = Syy2; + Sxy = Sxy2; + } + else if (N2 == 0.0) + { + N = N1; + Sx = Sx1; + Sxx = Sxx1; + Sy = Sy1; + Syy = Syy1; + Sxy = Sxy1; + } + else + { + N = N1 + N2; + Sx = float8_pl(Sx1, Sx2); + tmp1 = Sx1 / N1 - Sx2 / N2; + Sxx = Sxx1 + Sxx2 + N1 * N2 * tmp1 * tmp1 / N; + check_float8_val(Sxx, isinf(Sxx1) || isinf(Sxx2), true); + Sy = float8_pl(Sy1, Sy2); + tmp2 = Sy1 / N1 - Sy2 / N2; + Syy = Syy1 + Syy2 + N1 * N2 * tmp2 * tmp2 / N; + check_float8_val(Syy, isinf(Syy1) || isinf(Syy2), true); + Sxy = Sxy1 + Sxy2 + N1 * N2 * tmp1 * tmp2 / N; + check_float8_val(Sxy, isinf(Sxy1) || isinf(Sxy2), true); + } + + /* + * If we're invoked as an aggregate, we can cheat and modify our first + * parameter in-place to reduce palloc overhead. Otherwise we construct a + * new array with the updated transition data and return it. + */ + if (AggCheckCallContext(fcinfo, NULL)) + { + transvalues1[0] = N; + transvalues1[1] = Sx; + transvalues1[2] = Sxx; + transvalues1[3] = Sy; + transvalues1[4] = Syy; + transvalues1[5] = Sxy; + + PG_RETURN_ARRAYTYPE_P(transarray1); + } + else + { + Datum transdatums[6]; + ArrayType *result; + + transdatums[0] = Float8GetDatumFast(N); + transdatums[1] = Float8GetDatumFast(Sx); + transdatums[2] = Float8GetDatumFast(Sxx); + transdatums[3] = Float8GetDatumFast(Sy); + transdatums[4] = Float8GetDatumFast(Syy); + transdatums[5] = Float8GetDatumFast(Sxy); - transvalues1[0] = N; - transvalues1[1] = sumX; - transvalues1[2] = sumX2; - transvalues1[3] = sumY; - transvalues1[4] = sumY2; - transvalues1[5] = sumXY; + result = construct_array(transdatums, 6, + FLOAT8OID, + sizeof(float8), FLOAT8PASSBYVAL, 'd'); - PG_RETURN_ARRAYTYPE_P(transarray1); + PG_RETURN_ARRAYTYPE_P(result); + } } @@ -3009,27 +3374,19 @@ float8_regr_sxx(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - numerator; + Sxx; transvalues = check_float8_array(transarray, "float8_regr_sxx", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; + Sxx = transvalues[2]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numerator = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numerator, isinf(sumX2) || isinf(sumX), true); - - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); + /* Note that Sxx is guaranteed to be non-negative */ - PG_RETURN_FLOAT8(numerator / N); + PG_RETURN_FLOAT8(Sxx); } Datum @@ -3038,27 +3395,19 @@ float8_regr_syy(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumY, - sumY2, - numerator; + Syy; transvalues = check_float8_array(transarray, "float8_regr_syy", 6); N = transvalues[0]; - sumY = transvalues[3]; - sumY2 = transvalues[4]; + Syy = transvalues[4]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numerator = N * sumY2 - sumY * sumY; - CHECKFLOATVAL(numerator, isinf(sumY2) || isinf(sumY), true); + /* Note that Syy is guaranteed to be non-negative */ - /* Watch out for roundoff error producing a negative numerator */ - if (numerator <= 0.0) - PG_RETURN_FLOAT8(0.0); - - PG_RETURN_FLOAT8(numerator / N); + PG_RETURN_FLOAT8(Syy); } Datum @@ -3067,28 +3416,19 @@ float8_regr_sxy(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumY, - sumXY, - numerator; + Sxy; transvalues = check_float8_array(transarray, "float8_regr_sxy", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumY = transvalues[3]; - sumXY = transvalues[5]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numerator = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - /* A negative result is valid here */ - PG_RETURN_FLOAT8(numerator / N); + PG_RETURN_FLOAT8(Sxy); } Datum @@ -3097,17 +3437,17 @@ float8_regr_avgx(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX; + Sx; transvalues = check_float8_array(transarray, "float8_regr_avgx", 6); N = transvalues[0]; - sumX = transvalues[1]; + Sx = transvalues[1]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(sumX / N); + PG_RETURN_FLOAT8(Sx / N); } Datum @@ -3116,17 +3456,17 @@ float8_regr_avgy(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumY; + Sy; transvalues = check_float8_array(transarray, "float8_regr_avgy", 6); N = transvalues[0]; - sumY = transvalues[3]; + Sy = transvalues[3]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(sumY / N); + PG_RETURN_FLOAT8(Sy / N); } Datum @@ -3135,26 +3475,17 @@ float8_covar_pop(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumY, - sumXY, - numerator; + Sxy; transvalues = check_float8_array(transarray, "float8_covar_pop", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumY = transvalues[3]; - sumXY = transvalues[5]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numerator = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - - PG_RETURN_FLOAT8(numerator / (N * N)); + PG_RETURN_FLOAT8(Sxy / N); } Datum @@ -3163,26 +3494,17 @@ float8_covar_samp(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumY, - sumXY, - numerator; + Sxy; transvalues = check_float8_array(transarray, "float8_covar_samp", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumY = transvalues[3]; - sumXY = transvalues[5]; + Sxy = transvalues[5]; /* if N is <= 1 we should return NULL */ if (N < 2.0) PG_RETURN_NULL(); - numerator = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numerator, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - - PG_RETURN_FLOAT8(numerator / (N * (N - 1.0))); + PG_RETURN_FLOAT8(Sxy / (N - 1.0)); } Datum @@ -3191,38 +3513,27 @@ float8_corr(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - sumY, - sumY2, - sumXY, - numeratorX, - numeratorY, - numeratorXY; + Sxx, + Syy, + Sxy; transvalues = check_float8_array(transarray, "float8_corr", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; - sumY = transvalues[3]; - sumY2 = transvalues[4]; - sumXY = transvalues[5]; + Sxx = transvalues[2]; + Syy = transvalues[4]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numeratorX = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); - numeratorY = N * sumY2 - sumY * sumY; - CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true); - numeratorXY = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - if (numeratorX <= 0 || numeratorY <= 0) + /* Note that Sxx and Syy are guaranteed to be non-negative */ + + /* per spec, return NULL for horizontal and vertical lines */ + if (Sxx == 0 || Syy == 0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(numeratorXY / sqrt(numeratorX * numeratorY)); + PG_RETURN_FLOAT8(Sxy / sqrt(Sxx * Syy)); } Datum @@ -3231,42 +3542,31 @@ float8_regr_r2(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - sumY, - sumY2, - sumXY, - numeratorX, - numeratorY, - numeratorXY; + Sxx, + Syy, + Sxy; transvalues = check_float8_array(transarray, "float8_regr_r2", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; - sumY = transvalues[3]; - sumY2 = transvalues[4]; - sumXY = transvalues[5]; + Sxx = transvalues[2]; + Syy = transvalues[4]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numeratorX = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); - numeratorY = N * sumY2 - sumY * sumY; - CHECKFLOATVAL(numeratorY, isinf(sumY2) || isinf(sumY), true); - numeratorXY = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - if (numeratorX <= 0) + /* Note that Sxx and Syy are guaranteed to be non-negative */ + + /* per spec, return NULL for a vertical line */ + if (Sxx == 0) PG_RETURN_NULL(); - /* per spec, horizontal line produces 1.0 */ - if (numeratorY <= 0) + + /* per spec, return 1.0 for a horizontal line */ + if (Syy == 0) PG_RETURN_FLOAT8(1.0); - PG_RETURN_FLOAT8((numeratorXY * numeratorXY) / - (numeratorX * numeratorY)); + PG_RETURN_FLOAT8((Sxy * Sxy) / (Sxx * Syy)); } Datum @@ -3275,33 +3575,25 @@ float8_regr_slope(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - sumY, - sumXY, - numeratorX, - numeratorXY; + Sxx, + Sxy; transvalues = check_float8_array(transarray, "float8_regr_slope", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; - sumY = transvalues[3]; - sumXY = transvalues[5]; + Sxx = transvalues[2]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numeratorX = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); - numeratorXY = N * sumXY - sumX * sumY; - CHECKFLOATVAL(numeratorXY, isinf(sumXY) || isinf(sumX) || - isinf(sumY), true); - if (numeratorX <= 0) + /* Note that Sxx is guaranteed to be non-negative */ + + /* per spec, return NULL for a vertical line */ + if (Sxx == 0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(numeratorXY / numeratorX); + PG_RETURN_FLOAT8(Sxy / Sxx); } Datum @@ -3310,33 +3602,29 @@ float8_regr_intercept(PG_FUNCTION_ARGS) ArrayType *transarray = PG_GETARG_ARRAYTYPE_P(0); float8 *transvalues; float8 N, - sumX, - sumX2, - sumY, - sumXY, - numeratorX, - numeratorXXY; + Sx, + Sxx, + Sy, + Sxy; transvalues = check_float8_array(transarray, "float8_regr_intercept", 6); N = transvalues[0]; - sumX = transvalues[1]; - sumX2 = transvalues[2]; - sumY = transvalues[3]; - sumXY = transvalues[5]; + Sx = transvalues[1]; + Sxx = transvalues[2]; + Sy = transvalues[3]; + Sxy = transvalues[5]; /* if N is 0 we should return NULL */ if (N < 1.0) PG_RETURN_NULL(); - numeratorX = N * sumX2 - sumX * sumX; - CHECKFLOATVAL(numeratorX, isinf(sumX2) || isinf(sumX), true); - numeratorXXY = sumY * sumX2 - sumX * sumXY; - CHECKFLOATVAL(numeratorXXY, isinf(sumY) || isinf(sumX2) || - isinf(sumX) || isinf(sumXY), true); - if (numeratorX <= 0) + /* Note that Sxx is guaranteed to be non-negative */ + + /* per spec, return NULL for a vertical line */ + if (Sxx == 0) PG_RETURN_NULL(); - PG_RETURN_FLOAT8(numeratorXXY / numeratorX); + PG_RETURN_FLOAT8((Sy - Sx * Sxy / Sxx) / N); } @@ -3357,11 +3645,8 @@ float48pl(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - result = arg1 + arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_pl((float8) arg1, arg2)); } Datum @@ -3369,11 +3654,8 @@ float48mi(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - result = arg1 - arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mi((float8) arg1, arg2)); } Datum @@ -3381,12 +3663,8 @@ float48mul(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - result = arg1 * arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), - arg1 == 0 || arg2 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mul((float8) arg1, arg2)); } Datum @@ -3394,16 +3672,8 @@ float48div(PG_FUNCTION_ARGS) { float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - float8 result; - - if (arg2 == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - result = arg1 / arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_div((float8) arg1, arg2)); } /* @@ -3417,12 +3687,8 @@ float84pl(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float8 result; - result = arg1 + arg2; - - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_pl(arg1, (float8) arg2)); } Datum @@ -3430,12 +3696,8 @@ float84mi(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float8 result; - - result = arg1 - arg2; - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), true); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mi(arg1, (float8) arg2)); } Datum @@ -3443,13 +3705,8 @@ float84mul(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float8 result; - result = arg1 * arg2; - - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), - arg1 == 0 || arg2 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_mul(arg1, (float8) arg2)); } Datum @@ -3457,17 +3714,8 @@ float84div(PG_FUNCTION_ARGS) { float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - float8 result; - if (arg2 == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - - result = arg1 / arg2; - - CHECKFLOATVAL(result, isinf(arg1) || isinf(arg2), arg1 == 0); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(float8_div(arg1, (float8) arg2)); } /* @@ -3485,7 +3733,7 @@ float48eq(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) == 0); + PG_RETURN_BOOL(float8_eq((float8) arg1, arg2)); } Datum @@ -3494,7 +3742,7 @@ float48ne(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) != 0); + PG_RETURN_BOOL(float8_ne((float8) arg1, arg2)); } Datum @@ -3503,7 +3751,7 @@ float48lt(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) < 0); + PG_RETURN_BOOL(float8_lt((float8) arg1, arg2)); } Datum @@ -3512,7 +3760,7 @@ float48le(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) <= 0); + PG_RETURN_BOOL(float8_le((float8) arg1, arg2)); } Datum @@ -3521,7 +3769,7 @@ float48gt(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) > 0); + PG_RETURN_BOOL(float8_gt((float8) arg1, arg2)); } Datum @@ -3530,7 +3778,7 @@ float48ge(PG_FUNCTION_ARGS) float4 arg1 = PG_GETARG_FLOAT4(0); float8 arg2 = PG_GETARG_FLOAT8(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) >= 0); + PG_RETURN_BOOL(float8_ge((float8) arg1, arg2)); } /* @@ -3542,7 +3790,7 @@ float84eq(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) == 0); + PG_RETURN_BOOL(float8_eq(arg1, (float8) arg2)); } Datum @@ -3551,7 +3799,7 @@ float84ne(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) != 0); + PG_RETURN_BOOL(float8_ne(arg1, (float8) arg2)); } Datum @@ -3560,7 +3808,7 @@ float84lt(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) < 0); + PG_RETURN_BOOL(float8_lt(arg1, (float8) arg2)); } Datum @@ -3569,7 +3817,7 @@ float84le(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) <= 0); + PG_RETURN_BOOL(float8_le(arg1, (float8) arg2)); } Datum @@ -3578,7 +3826,7 @@ float84gt(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) > 0); + PG_RETURN_BOOL(float8_gt(arg1, (float8) arg2)); } Datum @@ -3587,7 +3835,7 @@ float84ge(PG_FUNCTION_ARGS) float8 arg1 = PG_GETARG_FLOAT8(0); float4 arg2 = PG_GETARG_FLOAT4(1); - PG_RETURN_BOOL(float8_cmp_internal(arg1, arg2) >= 0); + PG_RETURN_BOOL(float8_ge(arg1, (float8) arg2)); } /* diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c index f1f0ba3e0b3..6ae2a31345f 100644 --- a/src/backend/utils/adt/format_type.c +++ b/src/backend/utils/adt/format_type.c @@ -4,7 +4,7 @@ * Display type names "nicely". * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,8 +26,6 @@ #include "utils/syscache.h" #include "mb/pg_wchar.h" -#define MAX_INT32_LEN 11 - static char *printTypmod(const char *typname, int32 typmod, Oid typmodout); diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 1a1088711c3..f7175df8da6 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -4,7 +4,7 @@ * src/backend/utils/adt/formatting.c * * - * Portions Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2019, PostgreSQL Global Development Group * * * TO_CHAR(); TO_TIMESTAMP(); TO_DATE(); TO_NUMBER(); @@ -49,7 +49,6 @@ * - better number building (formatting) / parsing, now it isn't * ideal code * - use Assert() - * - add support for abstime * - add support for roman number to standard number conversion * - add support for number spelling * - add support for string to string formatting (we must be better @@ -87,21 +86,62 @@ #endif #include "catalog/pg_collation.h" +#include "catalog/pg_type.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" #include "utils/date.h" #include "utils/datetime.h" +#include "utils/float.h" #include "utils/formatting.h" #include "utils/int8.h" +#include "utils/memutils.h" #include "utils/numeric.h" #include "utils/pg_locale.h" /* ---------- - * Routines type + * Convenience macros for error handling + * ---------- + * + * Two macros below help to handle errors in functions that take + * 'bool *have_error' argument. When this argument is not NULL, it's expected + * that function will suppress ereports when possible. Instead it should + * return some default value and set *have_error flag. + * + * RETURN_ERROR() macro intended to wrap ereport() calls. When have_error + * function argument is not NULL, then instead of ereport'ing we set + * *have_error flag and go to on_error label. It's supposed that jump + * resources will be freed and some 'default' value returned. + * + * CHECK_ERROR() jumps on_error label when *have_error flag is defined and set. + * It's supposed to be used for immediate exit from the function on error + * after call of another function with 'bool *have_error' argument. + */ +#define RETURN_ERROR(throw_error) \ +do { \ + if (have_error) \ + { \ + *have_error = true; \ + goto on_error; \ + } \ + else \ + { \ + throw_error; \ + } \ +} while (0) + +#define CHECK_ERROR \ +do { \ + if (have_error && *have_error) \ + goto on_error; \ +} while (0) + +/* ---------- + * Routines flags * ---------- */ -#define DCH_TYPE 1 /* DATE-TIME version */ -#define NUM_TYPE 2 /* NUMBER version */ +#define DCH_FLAG 0x1 /* DATE-TIME flag */ +#define NUM_FLAG 0x2 /* NUMBER flag */ +#define STD_FLAG 0x4 /* STANDARD flag */ /* ---------- * KeyWord Index (ascii from position 32 (' ') to 126 (~)) @@ -124,10 +164,10 @@ */ typedef struct { - char *name; /* suffix string */ + const char *name; /* suffix string */ int len, /* suffix length */ id, /* used in node->suffix */ - type; /* prefix / postfix */ + type; /* prefix / postfix */ } KeySuffix; /* ---------- @@ -155,15 +195,17 @@ typedef struct typedef struct { - int type; /* NODE_TYPE_XXX, see below */ - const KeyWord *key; /* if type is ACTION */ + uint8 type; /* NODE_TYPE_XXX, see below */ char character[MAX_MULTIBYTE_CHAR_LEN + 1]; /* if type is CHAR */ - int suffix; /* keyword prefix/suffix code, if any */ + uint8 suffix; /* keyword prefix/suffix code, if any */ + const KeyWord *key; /* if type is ACTION */ } FormatNode; #define NODE_TYPE_END 1 #define NODE_TYPE_ACTION 2 #define NODE_TYPE_CHAR 3 +#define NODE_TYPE_SEPARATOR 4 +#define NODE_TYPE_SPACE 5 #define SUFFTYPE_PREFIX 1 #define SUFFTYPE_POSTFIX 2 @@ -279,8 +321,6 @@ static const char *const numth[] = {"st", "nd", "rd", "th", NULL}; #define ALL_UPPER 2 /* NAME */ #define ALL_LOWER 3 /* name */ -#define FULL_SIZ 0 - #define MAX_MONTH_LEN 9 #define MAX_MON_LEN 3 #define MAX_DAY_LEN 9 @@ -356,19 +396,33 @@ typedef struct * For simplicity, the cache entries are fixed-size, so they allow for the * worst case of a FormatNode for each byte in the picture string. * - * The max number of entries in the caches is DCH_CACHE_ENTRIES + * The CACHE_SIZE constants are computed to make sizeof(DCHCacheEntry) and + * sizeof(NUMCacheEntry) be powers of 2, or just less than that, so that + * we don't waste too much space by palloc'ing them individually. Be sure + * to adjust those macros if you add fields to those structs. + * + * The max number of entries in each cache is DCH_CACHE_ENTRIES * resp. NUM_CACHE_ENTRIES. * ---------- */ -#define NUM_CACHE_SIZE 64 -#define NUM_CACHE_ENTRIES 20 -#define DCH_CACHE_SIZE 128 +#define DCH_CACHE_OVERHEAD \ + MAXALIGN(sizeof(bool) + sizeof(int)) +#define NUM_CACHE_OVERHEAD \ + MAXALIGN(sizeof(bool) + sizeof(int) + sizeof(NUMDesc)) + +#define DCH_CACHE_SIZE \ + ((2048 - DCH_CACHE_OVERHEAD) / (sizeof(FormatNode) + sizeof(char)) - 1) +#define NUM_CACHE_SIZE \ + ((1024 - NUM_CACHE_OVERHEAD) / (sizeof(FormatNode) + sizeof(char)) - 1) + #define DCH_CACHE_ENTRIES 20 +#define NUM_CACHE_ENTRIES 20 typedef struct { FormatNode format[DCH_CACHE_SIZE + 1]; char str[DCH_CACHE_SIZE + 1]; + bool std; bool valid; int age; } DCHCacheEntry; @@ -383,12 +437,12 @@ typedef struct } NUMCacheEntry; /* global cache for date/time format pictures */ -static DCHCacheEntry DCHCache[DCH_CACHE_ENTRIES]; +static DCHCacheEntry *DCHCache[DCH_CACHE_ENTRIES]; static int n_DCHCache = 0; /* current number of entries */ static int DCHCounter = 0; /* aging-event counter */ /* global cache for number format pictures */ -static NUMCacheEntry NUMCache[NUM_CACHE_ENTRIES]; +static NUMCacheEntry *NUMCache[NUM_CACHE_ENTRIES]; static int n_NUMCache = 0; /* current number of entries */ static int NUMCounter = 0; /* aging-event counter */ @@ -420,7 +474,8 @@ typedef struct clock, /* 12 or 24 hour clock? */ tzsign, /* +1, -1 or 0 if timezone info is absent */ tzh, - tzm; + tzm, + ff; /* fractional precision */ } TmFromChar; #define ZERO_tmfc(_X) memset(_X, 0, sizeof(TmFromChar)) @@ -494,7 +549,7 @@ do { \ *****************************************************************************/ /* ---------- - * Suffixes: + * Suffixes (FormatNode.suffix is an OR of these codes) * ---------- */ #define DCH_S_FM 0x01 @@ -580,6 +635,12 @@ typedef enum DCH_Day, DCH_Dy, DCH_D, + DCH_FF1, + DCH_FF2, + DCH_FF3, + DCH_FF4, + DCH_FF5, + DCH_FF6, DCH_FX, /* global suffix */ DCH_HH24, DCH_HH12, @@ -604,6 +665,7 @@ typedef enum DCH_PM, DCH_Q, DCH_RM, + DCH_SSSSS, DCH_SSSS, DCH_SS, DCH_TZH, @@ -629,6 +691,12 @@ typedef enum DCH_dd, DCH_dy, DCH_d, + DCH_ff1, + DCH_ff2, + DCH_ff3, + DCH_ff4, + DCH_ff5, + DCH_ff6, DCH_fx, DCH_hh24, DCH_hh12, @@ -650,6 +718,7 @@ typedef enum DCH_pm, DCH_q, DCH_rm, + DCH_sssss, DCH_ssss, DCH_ss, DCH_tz, @@ -729,7 +798,13 @@ static const KeyWord DCH_keywords[] = { {"Day", 3, DCH_Day, false, FROM_CHAR_DATE_NONE}, {"Dy", 2, DCH_Dy, false, FROM_CHAR_DATE_NONE}, {"D", 1, DCH_D, true, FROM_CHAR_DATE_GREGORIAN}, - {"FX", 2, DCH_FX, false, FROM_CHAR_DATE_NONE}, /* F */ + {"FF1", 3, DCH_FF1, false, FROM_CHAR_DATE_NONE}, /* F */ + {"FF2", 3, DCH_FF2, false, FROM_CHAR_DATE_NONE}, + {"FF3", 3, DCH_FF3, false, FROM_CHAR_DATE_NONE}, + {"FF4", 3, DCH_FF4, false, FROM_CHAR_DATE_NONE}, + {"FF5", 3, DCH_FF5, false, FROM_CHAR_DATE_NONE}, + {"FF6", 3, DCH_FF6, false, FROM_CHAR_DATE_NONE}, + {"FX", 2, DCH_FX, false, FROM_CHAR_DATE_NONE}, {"HH24", 4, DCH_HH24, true, FROM_CHAR_DATE_NONE}, /* H */ {"HH12", 4, DCH_HH12, true, FROM_CHAR_DATE_NONE}, {"HH", 2, DCH_HH, true, FROM_CHAR_DATE_NONE}, @@ -753,7 +828,8 @@ static const KeyWord DCH_keywords[] = { {"PM", 2, DCH_PM, false, FROM_CHAR_DATE_NONE}, {"Q", 1, DCH_Q, true, FROM_CHAR_DATE_NONE}, /* Q */ {"RM", 2, DCH_RM, false, FROM_CHAR_DATE_GREGORIAN}, /* R */ - {"SSSS", 4, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, /* S */ + {"SSSSS", 5, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, /* S */ + {"SSSS", 4, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, {"SS", 2, DCH_SS, true, FROM_CHAR_DATE_NONE}, {"TZH", 3, DCH_TZH, false, FROM_CHAR_DATE_NONE}, /* T */ {"TZM", 3, DCH_TZM, true, FROM_CHAR_DATE_NONE}, @@ -778,7 +854,13 @@ static const KeyWord DCH_keywords[] = { {"dd", 2, DCH_DD, true, FROM_CHAR_DATE_GREGORIAN}, {"dy", 2, DCH_dy, false, FROM_CHAR_DATE_NONE}, {"d", 1, DCH_D, true, FROM_CHAR_DATE_GREGORIAN}, - {"fx", 2, DCH_FX, false, FROM_CHAR_DATE_NONE}, /* f */ + {"ff1", 3, DCH_FF1, false, FROM_CHAR_DATE_NONE}, /* f */ + {"ff2", 3, DCH_FF2, false, FROM_CHAR_DATE_NONE}, + {"ff3", 3, DCH_FF3, false, FROM_CHAR_DATE_NONE}, + {"ff4", 3, DCH_FF4, false, FROM_CHAR_DATE_NONE}, + {"ff5", 3, DCH_FF5, false, FROM_CHAR_DATE_NONE}, + {"ff6", 3, DCH_FF6, false, FROM_CHAR_DATE_NONE}, + {"fx", 2, DCH_FX, false, FROM_CHAR_DATE_NONE}, {"hh24", 4, DCH_HH24, true, FROM_CHAR_DATE_NONE}, /* h */ {"hh12", 4, DCH_HH12, true, FROM_CHAR_DATE_NONE}, {"hh", 2, DCH_HH, true, FROM_CHAR_DATE_NONE}, @@ -799,7 +881,8 @@ static const KeyWord DCH_keywords[] = { {"pm", 2, DCH_pm, false, FROM_CHAR_DATE_NONE}, {"q", 1, DCH_Q, true, FROM_CHAR_DATE_NONE}, /* q */ {"rm", 2, DCH_rm, false, FROM_CHAR_DATE_GREGORIAN}, /* r */ - {"ssss", 4, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, /* s */ + {"sssss", 5, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, /* s */ + {"ssss", 4, DCH_SSSS, true, FROM_CHAR_DATE_NONE}, {"ss", 2, DCH_SS, true, FROM_CHAR_DATE_NONE}, {"tz", 2, DCH_tz, false, FROM_CHAR_DATE_NONE}, /* t */ {"us", 2, DCH_US, true, FROM_CHAR_DATE_NONE}, /* u */ @@ -879,11 +962,11 @@ static const int DCH_index[KeyWord_INDEX_SIZE] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, DCH_A_D, DCH_B_C, DCH_CC, DCH_DAY, -1, - DCH_FX, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, DCH_OF, - DCH_P_M, DCH_Q, DCH_RM, DCH_SSSS, DCH_TZH, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY, + DCH_FF1, -1, DCH_HH24, DCH_IDDD, DCH_J, -1, -1, DCH_MI, -1, DCH_OF, + DCH_P_M, DCH_Q, DCH_RM, DCH_SSSSS, DCH_TZH, DCH_US, -1, DCH_WW, -1, DCH_Y_YYY, -1, -1, -1, -1, -1, -1, -1, DCH_a_d, DCH_b_c, DCH_cc, - DCH_day, -1, DCH_fx, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi, - -1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_ssss, DCH_tz, DCH_us, -1, DCH_ww, + DCH_day, -1, DCH_ff1, -1, DCH_hh24, DCH_iddd, DCH_j, -1, -1, DCH_mi, + -1, -1, DCH_p_m, DCH_q, DCH_rm, DCH_sssss, DCH_tz, DCH_us, -1, DCH_ww, -1, DCH_y_yyy, -1, -1, -1, -1 /*---- chars over 126 are skipped ----*/ @@ -946,21 +1029,27 @@ typedef struct NUMProc *L_currency_symbol; } NUMProc; +/* Return flags for DCH_from_char() */ +#define DCH_DATED 0x01 +#define DCH_TIMED 0x02 +#define DCH_ZONED 0x04 /* ---------- * Functions * ---------- */ static const KeyWord *index_seq_search(const char *str, const KeyWord *kw, - const int *index); + const int *index); static const KeySuffix *suff_search(const char *str, const KeySuffix *suf, int type); +static bool is_separator_char(const char *str); static void NUMDesc_prepare(NUMDesc *num, FormatNode *n); static void parse_format(FormatNode *node, const char *str, const KeyWord *kw, - const KeySuffix *suf, const int *index, int ver, NUMDesc *Num); + const KeySuffix *suf, const int *index, uint32 flags, NUMDesc *Num); static void DCH_to_char(FormatNode *node, bool is_interval, - TmToChar *in, char *out, Oid collid); -static void DCH_from_char(FormatNode *node, char *in, TmFromChar *out); + TmToChar *in, char *out, Oid collid); +static void DCH_from_char(FormatNode *node, char *in, TmFromChar *out, + bool std, bool *have_error); #ifdef DEBUG_TO_FROM_CHAR static void dump_index(const KeyWord *k, const int *index); @@ -971,14 +1060,21 @@ static const char *get_th(char *num, int type); static char *str_numth(char *dest, char *num, int type); static int adjust_partial_year_to_2020(int year); static int strspace_len(char *str); -static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode); -static void from_char_set_int(int *dest, const int value, const FormatNode *node); -static int from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node); -static int from_char_parse_int(int *dest, char **src, FormatNode *node); +static void from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode, + bool *have_error); +static void from_char_set_int(int *dest, const int value, const FormatNode *node, + bool *have_error); +static int from_char_parse_int_len(int *dest, char **src, const int len, + FormatNode *node, bool *have_error); +static int from_char_parse_int(int *dest, char **src, FormatNode *node, + bool *have_error); static int seq_search(char *name, const char *const *array, int type, int max, int *len); -static int from_char_seq_search(int *dest, char **src, const char *const *array, int type, int max, FormatNode *node); -static void do_to_timestamp(text *date_txt, text *fmt, - struct pg_tm *tm, fsec_t *fsec); +static int from_char_seq_search(int *dest, char **src, + const char *const *array, int type, int max, + FormatNode *node, bool *have_error); +static void do_to_timestamp(text *date_txt, text *fmt, bool std, + struct pg_tm *tm, fsec_t *fsec, int *fprec, + uint32 *flags, bool *have_error); static char *fill_str(char *str, int c, int max); static FormatNode *NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree); static char *int_to_roman(int number); @@ -987,11 +1083,11 @@ static char *get_last_relevant_decnum(char *num); static void NUM_numpart_from_char(NUMProc *Np, int id, int input_len); static void NUM_numpart_to_char(NUMProc *Np, int id); static char *NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, - char *number, int input_len, int to_char_out_pre_spaces, - int sign, bool is_to_char, Oid collid); -static DCHCacheEntry *DCH_cache_getnew(const char *str); -static DCHCacheEntry *DCH_cache_search(const char *str); -static DCHCacheEntry *DCH_cache_fetch(const char *str); + char *number, int input_len, int to_char_out_pre_spaces, + int sign, bool is_to_char, Oid collid); +static DCHCacheEntry *DCH_cache_getnew(const char *str, bool std); +static DCHCacheEntry *DCH_cache_search(const char *str, bool std); +static DCHCacheEntry *DCH_cache_fetch(const char *str, bool std); static NUMCacheEntry *NUM_cache_getnew(const char *str); static NUMCacheEntry *NUM_cache_search(const char *str); static NUMCacheEntry *NUM_cache_fetch(const char *str); @@ -1043,6 +1139,16 @@ suff_search(const char *str, const KeySuffix *suf, int type) return NULL; } +static bool +is_separator_char(const char *str) +{ + /* ASCII printable character, but not letter or digit */ + return (*str > 0x20 && *str < 0x7F && + !(*str >= 'A' && *str <= 'Z') && + !(*str >= 'a' && *str <= 'z') && + !(*str >= '0' && *str <= '9')); +} + /* ---------- * Prepare NUMDesc (number description struct) via FormatNode struct * ---------- @@ -1224,7 +1330,7 @@ NUMDesc_prepare(NUMDesc *num, FormatNode *n) */ static void parse_format(FormatNode *node, const char *str, const KeyWord *kw, - const KeySuffix *suf, const int *index, int ver, NUMDesc *Num) + const KeySuffix *suf, const int *index, uint32 flags, NUMDesc *Num) { FormatNode *n; @@ -1242,7 +1348,7 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw, /* * Prefix */ - if (ver == DCH_TYPE && + if ((flags & DCH_FLAG) && (s = suff_search(str, suf, SUFFTYPE_PREFIX)) != NULL) { suffix |= s->id; @@ -1263,13 +1369,13 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw, /* * NUM version: Prepare global NUMDesc struct */ - if (ver == NUM_TYPE) + if (flags & NUM_FLAG) NUMDesc_prepare(Num, n); /* * Postfix */ - if (ver == DCH_TYPE && *str && + if ((flags & DCH_FLAG) && *str && (s = suff_search(str, suf, SUFFTYPE_POSTFIX)) != NULL) { n->suffix |= s->id; @@ -1283,11 +1389,34 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw, { int chlen; - /* - * Process double-quoted literal string, if any - */ - if (*str == '"') + if (flags & STD_FLAG) { + /* + * Standard mode, allow only following separators: "-./,':; " + */ + if (strchr("-./,':; ", *str) == NULL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid datetime format separator: \"%s\"", + pnstrdup(str, pg_mblen(str))))); + + if (*str == ' ') + n->type = NODE_TYPE_SPACE; + else + n->type = NODE_TYPE_SEPARATOR; + + n->character[0] = *str; + n->character[1] = '\0'; + n->key = NULL; + n->suffix = 0; + n++; + str++; + } + else if (*str == '"') + { + /* + * Process double-quoted literal string, if any + */ str++; while (*str) { @@ -1318,7 +1447,14 @@ parse_format(FormatNode *node, const char *str, const KeyWord *kw, if (*str == '\\' && *(str + 1) == '"') str++; chlen = pg_mblen(str); - n->type = NODE_TYPE_CHAR; + + if ((flags & DCH_FLAG) && is_separator_char(str)) + n->type = NODE_TYPE_SEPARATOR; + else if (isspace((unsigned char) *str)) + n->type = NODE_TYPE_SPACE; + else + n->type = NODE_TYPE_CHAR; + memcpy(n->character, str, chlen); n->character[chlen] = '\0'; n->key = NULL; @@ -1532,7 +1668,8 @@ str_tolower(const char *buff, size_t nbytes, Oid collid) */ ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for lower() function"), + errmsg("could not determine which collation to use for %s function", + "lower()"), errhint("Use the COLLATE clause to set the collation explicitly."))); } mylocale = pg_newlocale_from_collation(collid); @@ -1551,6 +1688,7 @@ str_tolower(const char *buff, size_t nbytes, Oid collid) &buff_conv, buff_uchar, len_uchar); icu_from_uchar(&result, buff_conv, len_conv); pfree(buff_uchar); + pfree(buff_conv); } else #endif @@ -1654,7 +1792,8 @@ str_toupper(const char *buff, size_t nbytes, Oid collid) */ ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for upper() function"), + errmsg("could not determine which collation to use for %s function", + "upper()"), errhint("Use the COLLATE clause to set the collation explicitly."))); } mylocale = pg_newlocale_from_collation(collid); @@ -1673,6 +1812,7 @@ str_toupper(const char *buff, size_t nbytes, Oid collid) &buff_conv, buff_uchar, len_uchar); icu_from_uchar(&result, buff_conv, len_conv); pfree(buff_uchar); + pfree(buff_conv); } else #endif @@ -1777,7 +1917,8 @@ str_initcap(const char *buff, size_t nbytes, Oid collid) */ ereport(ERROR, (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for initcap() function"), + errmsg("could not determine which collation to use for %s function", + "initcap()"), errhint("Use the COLLATE clause to set the collation explicitly."))); } mylocale = pg_newlocale_from_collation(collid); @@ -1796,6 +1937,7 @@ str_initcap(const char *buff, size_t nbytes, Oid collid) &buff_conv, buff_uchar, len_uchar); icu_from_uchar(&result, buff_conv, len_conv); pfree(buff_uchar); + pfree(buff_conv); } else #endif @@ -2134,21 +2276,26 @@ strspace_len(char *str) * * Puke if the date mode has already been set, and the caller attempts to set * it to a conflicting mode. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set. */ static void -from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode) +from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode, bool *have_error) { if (mode != FROM_CHAR_DATE_NONE) { if (tmfc->mode == FROM_CHAR_DATE_NONE) tmfc->mode = mode; else if (tmfc->mode != mode) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid combination of date conventions"), - errhint("Do not mix Gregorian and ISO week date " - "conventions in a formatting template."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid combination of date conventions"), + errhint("Do not mix Gregorian and ISO week date " + "conventions in a formatting template.")))); } + +on_error: + return; } /* @@ -2156,18 +2303,25 @@ from_char_set_mode(TmFromChar *tmfc, const FromCharDateMode mode) * * Puke if the destination integer has previously been set to some other * non-zero value. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set. */ static void -from_char_set_int(int *dest, const int value, const FormatNode *node) +from_char_set_int(int *dest, const int value, const FormatNode *node, + bool *have_error) { if (*dest != 0 && *dest != value) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("conflicting values for \"%s\" field in formatting string", - node->key->name), - errdetail("This value contradicts a previous setting for " - "the same field type."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("conflicting values for \"%s\" field in " + "formatting string", + node->key->name), + errdetail("This value contradicts a previous setting " + "for the same field type.")))); *dest = value; + +on_error: + return; } /* @@ -2189,9 +2343,13 @@ from_char_set_int(int *dest, const int value, const FormatNode *node) * Note that from_char_parse_int() provides a more convenient wrapper where * the length of the field is the same as the length of the format keyword (as * with DD and MI). + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set + * and -1 is returned. */ static int -from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node) +from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node, + bool *have_error) { long result; char copy[DCH_MAX_ITEM_SIZ + 1]; @@ -2224,51 +2382,60 @@ from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node) char *last; if (used < len) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("source string too short for \"%s\" formatting field", - node->key->name), - errdetail("Field requires %d characters, but only %d " - "remain.", - len, used), - errhint("If your source string is not fixed-width, try " - "using the \"FM\" modifier."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("source string too short for \"%s\" " + "formatting field", + node->key->name), + errdetail("Field requires %d characters, " + "but only %d remain.", + len, used), + errhint("If your source string is not fixed-width, " + "try using the \"FM\" modifier.")))); errno = 0; result = strtol(copy, &last, 10); used = last - copy; if (used > 0 && used < len) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid value \"%s\" for \"%s\"", - copy, node->key->name), - errdetail("Field requires %d characters, but only %d " - "could be parsed.", len, used), - errhint("If your source string is not fixed-width, try " - "using the \"FM\" modifier."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid value \"%s\" for \"%s\"", + copy, node->key->name), + errdetail("Field requires %d characters, " + "but only %d could be parsed.", + len, used), + errhint("If your source string is not fixed-width, " + "try using the \"FM\" modifier.")))); *src += used; } if (*src == init) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid value \"%s\" for \"%s\"", - copy, node->key->name), - errdetail("Value must be an integer."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid value \"%s\" for \"%s\"", + copy, node->key->name), + errdetail("Value must be an integer.")))); if (errno == ERANGE || result < INT_MIN || result > INT_MAX) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("value for \"%s\" in source string is out of range", - node->key->name), - errdetail("Value must be in the range %d to %d.", - INT_MIN, INT_MAX))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("value for \"%s\" in source string is out of range", + node->key->name), + errdetail("Value must be in the range %d to %d.", + INT_MIN, INT_MAX)))); if (dest != NULL) - from_char_set_int(dest, (int) result, node); + { + from_char_set_int(dest, (int) result, node, have_error); + CHECK_ERROR; + } + return *src - init; + +on_error: + return -1; } /* @@ -2281,9 +2448,9 @@ from_char_parse_int_len(int *dest, char **src, const int len, FormatNode *node) * required length explicitly. */ static int -from_char_parse_int(int *dest, char **src, FormatNode *node) +from_char_parse_int(int *dest, char **src, FormatNode *node, bool *have_error) { - return from_char_parse_int_len(dest, src, node->key->len, node); + return from_char_parse_int_len(dest, src, node->key->len, node, have_error); } /* ---------- @@ -2366,11 +2533,12 @@ seq_search(char *name, const char *const *array, int type, int max, int *len) * pointed to by 'dest', advance 'src' to the end of the part of the string * which matched, and return the number of characters consumed. * - * If the string doesn't match, throw an error. + * If the string doesn't match, throw an error if 'have_error' is NULL, + * otherwise set '*have_error' and return -1. */ static int -from_char_seq_search(int *dest, char **src, const char *const *array, int type, int max, - FormatNode *node) +from_char_seq_search(int *dest, char **src, const char *const *array, int type, + int max, FormatNode *node, bool *have_error) { int len; @@ -2382,15 +2550,18 @@ from_char_seq_search(int *dest, char **src, const char *const *array, int type, Assert(max <= DCH_MAX_ITEM_SIZ); strlcpy(copy, *src, max + 1); - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid value \"%s\" for \"%s\"", - copy, node->key->name), - errdetail("The given value did not match any of the allowed " - "values for this field."))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid value \"%s\" for \"%s\"", + copy, node->key->name), + errdetail("The given value did not match any of " + "the allowed values for this field.")))); } *src += len; return len; + +on_error: + return -1; } /* ---------- @@ -2480,18 +2651,32 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col str_numth(s, s, S_TH_TYPE(n->suffix)); s += strlen(s); break; - case DCH_MS: /* millisecond */ - sprintf(s, "%03d", (int) (in->fsec / INT64CONST(1000))); - if (S_THth(n->suffix)) - str_numth(s, s, S_TH_TYPE(n->suffix)); +#define DCH_to_char_fsec(frac_fmt, frac_val) \ + sprintf(s, frac_fmt, (int) (frac_val)); \ + if (S_THth(n->suffix)) \ + str_numth(s, s, S_TH_TYPE(n->suffix)); \ s += strlen(s); + case DCH_FF1: /* tenth of second */ + DCH_to_char_fsec("%01d", in->fsec / 100000); + break; + case DCH_FF2: /* hundredth of second */ + DCH_to_char_fsec("%02d", in->fsec / 10000); break; + case DCH_FF3: + case DCH_MS: /* millisecond */ + DCH_to_char_fsec("%03d", in->fsec / 1000); + break; + case DCH_FF4: /* tenth of a millisecond */ + DCH_to_char_fsec("%04d", in->fsec / 100); + break; + case DCH_FF5: /* hundredth of a millisecond */ + DCH_to_char_fsec("%05d", in->fsec / 10); + break; + case DCH_FF6: case DCH_US: /* microsecond */ - sprintf(s, "%06d", (int) in->fsec); - if (S_THth(n->suffix)) - str_numth(s, s, S_TH_TYPE(n->suffix)); - s += strlen(s); + DCH_to_char_fsec("%06d", in->fsec); break; +#undef DCH_to_char_fsec case DCH_SSSS: sprintf(s, "%d", tm->tm_hour * SECS_PER_HOUR + tm->tm_min * SECS_PER_MINUTE + @@ -2976,38 +3161,113 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col * * Note: we currently don't have any to_interval() function, so there * is no need here for INVALID_FOR_INTERVAL checks. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set. * ---------- */ static void -DCH_from_char(FormatNode *node, char *in, TmFromChar *out) +DCH_from_char(FormatNode *node, char *in, TmFromChar *out, bool std, + bool *have_error) { FormatNode *n; char *s; int len, value; - bool fx_mode = false; + bool fx_mode = std; + + /* number of extra skipped characters (more than given in format string) */ + int extra_skip = 0; for (n = node, s = in; n->type != NODE_TYPE_END && *s != '\0'; n++) { - if (n->type != NODE_TYPE_ACTION) + /* + * Ignore spaces at the beginning of the string and before fields when + * not in FX (fixed width) mode. + */ + if (!fx_mode && (n->type != NODE_TYPE_ACTION || n->key->id != DCH_FX) && + (n->type == NODE_TYPE_ACTION || n == node)) { - /* - * Separator, so consume one character from input string. Notice - * we don't insist that the consumed character match the format's - * character. - */ - s += pg_mblen(s); - continue; + while (*s != '\0' && isspace((unsigned char) *s)) + { + s++; + extra_skip++; + } } - /* Ignore spaces before fields when not in FX (fixed width) mode */ - if (!fx_mode && n->key->id != DCH_FX) + if (n->type == NODE_TYPE_SPACE || n->type == NODE_TYPE_SEPARATOR) { - while (*s != '\0' && isspace((unsigned char) *s)) - s++; + if (std) + { + /* + * Standard mode requires strict matching between format + * string separators/spaces and input string. + */ + Assert(n->character[0] && !n->character[1]); + + if (*s == n->character[0]) + s++; + else + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("unmatched format separator \"%c\"", + n->character[0])))); + } + else if (!fx_mode) + { + /* + * In non FX (fixed format) mode one format string space or + * separator match to one space or separator in input string. + * Or match nothing if there is no space or separator in the + * current position of input string. + */ + extra_skip--; + if (isspace((unsigned char) *s) || is_separator_char(s)) + { + s++; + extra_skip++; + } + } + else + { + /* + * In FX mode, on format string space or separator we consume + * exactly one character from input string. Notice we don't + * insist that the consumed character match the format's + * character. + */ + s += pg_mblen(s); + } + continue; + } + else if (n->type != NODE_TYPE_ACTION) + { + /* + * Text character, so consume one character from input string. + * Notice we don't insist that the consumed character match the + * format's character. + */ + if (!fx_mode) + { + /* + * In non FX mode we might have skipped some extra characters + * (more than specified in format string) before. In this + * case we don't skip input string character, because it might + * be part of field. + */ + if (extra_skip > 0) + extra_skip--; + else + s += pg_mblen(s); + } + else + { + s += pg_mblen(s); + } + continue; } - from_char_set_mode(out, n->key->date_mode); + from_char_set_mode(out, n->key->date_mode, have_error); + CHECK_ERROR; switch (n->key->id) { @@ -3019,8 +3279,10 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) case DCH_a_m: case DCH_p_m: from_char_seq_search(&value, &s, ampm_strings_long, - ALL_UPPER, n->key->len, n); - from_char_set_int(&out->pm, value % 2, n); + ALL_UPPER, n->key->len, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->pm, value % 2, n, have_error); + CHECK_ERROR; out->clock = CLOCK_12_HOUR; break; case DCH_AM: @@ -3028,30 +3290,37 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) case DCH_am: case DCH_pm: from_char_seq_search(&value, &s, ampm_strings, - ALL_UPPER, n->key->len, n); - from_char_set_int(&out->pm, value % 2, n); + ALL_UPPER, n->key->len, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->pm, value % 2, n, have_error); + CHECK_ERROR; out->clock = CLOCK_12_HOUR; break; case DCH_HH: case DCH_HH12: - from_char_parse_int_len(&out->hh, &s, 2, n); + from_char_parse_int_len(&out->hh, &s, 2, n, have_error); + CHECK_ERROR; out->clock = CLOCK_12_HOUR; SKIP_THth(s, n->suffix); break; case DCH_HH24: - from_char_parse_int_len(&out->hh, &s, 2, n); + from_char_parse_int_len(&out->hh, &s, 2, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_MI: - from_char_parse_int(&out->mi, &s, n); + from_char_parse_int(&out->mi, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_SS: - from_char_parse_int(&out->ss, &s, n); + from_char_parse_int(&out->ss, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_MS: /* millisecond */ - len = from_char_parse_int_len(&out->ms, &s, 3, n); + len = from_char_parse_int_len(&out->ms, &s, 3, n, have_error); + CHECK_ERROR; /* * 25 is 0.25 and 250 is 0.25 too; 025 is 0.025 and not 0.25 @@ -3061,8 +3330,19 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) SKIP_THth(s, n->suffix); break; + case DCH_FF1: + case DCH_FF2: + case DCH_FF3: + case DCH_FF4: + case DCH_FF5: + case DCH_FF6: + out->ff = n->key->id - DCH_FF1 + 1; + /* fall through */ case DCH_US: /* microsecond */ - len = from_char_parse_int_len(&out->us, &s, 6, n); + len = from_char_parse_int_len(&out->us, &s, + n->key->id == DCH_US ? 6 : + out->ff, n, have_error); + CHECK_ERROR; out->us *= len == 1 ? 100000 : len == 2 ? 10000 : @@ -3073,99 +3353,137 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) SKIP_THth(s, n->suffix); break; case DCH_SSSS: - from_char_parse_int(&out->ssss, &s, n); + from_char_parse_int(&out->ssss, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_tz: case DCH_TZ: case DCH_OF: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("formatting field \"%s\" is only supported in to_char", - n->key->name))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("formatting field \"%s\" is only supported in to_char", + n->key->name)))); + CHECK_ERROR; break; case DCH_TZH: - out->tzsign = *s == '-' ? -1 : +1; + /* + * Value of TZH might be negative. And the issue is that we + * might swallow minus sign as the separator. So, if we have + * skipped more characters than specified in the format + * string, then we consider prepending last skipped minus to + * TZH. + */ if (*s == '+' || *s == '-' || *s == ' ') + { + out->tzsign = *s == '-' ? -1 : +1; s++; + } + else + { + if (extra_skip > 0 && *(s - 1) == '-') + out->tzsign = -1; + else + out->tzsign = +1; + } - from_char_parse_int_len(&out->tzh, &s, 2, n); + from_char_parse_int_len(&out->tzh, &s, 2, n, have_error); + CHECK_ERROR; break; case DCH_TZM: /* assign positive timezone sign if TZH was not seen before */ if (!out->tzsign) out->tzsign = +1; - from_char_parse_int_len(&out->tzm, &s, 2, n); + from_char_parse_int_len(&out->tzm, &s, 2, n, have_error); + CHECK_ERROR; break; case DCH_A_D: case DCH_B_C: case DCH_a_d: case DCH_b_c: from_char_seq_search(&value, &s, adbc_strings_long, - ALL_UPPER, n->key->len, n); - from_char_set_int(&out->bc, value % 2, n); + ALL_UPPER, n->key->len, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->bc, value % 2, n, have_error); + CHECK_ERROR; break; case DCH_AD: case DCH_BC: case DCH_ad: case DCH_bc: from_char_seq_search(&value, &s, adbc_strings, - ALL_UPPER, n->key->len, n); - from_char_set_int(&out->bc, value % 2, n); + ALL_UPPER, n->key->len, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->bc, value % 2, n, have_error); + CHECK_ERROR; break; case DCH_MONTH: case DCH_Month: case DCH_month: from_char_seq_search(&value, &s, months_full, ONE_UPPER, - MAX_MONTH_LEN, n); - from_char_set_int(&out->mm, value + 1, n); + MAX_MONTH_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->mm, value + 1, n, have_error); + CHECK_ERROR; break; case DCH_MON: case DCH_Mon: case DCH_mon: from_char_seq_search(&value, &s, months, ONE_UPPER, - MAX_MON_LEN, n); - from_char_set_int(&out->mm, value + 1, n); + MAX_MON_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->mm, value + 1, n, have_error); + CHECK_ERROR; break; case DCH_MM: - from_char_parse_int(&out->mm, &s, n); + from_char_parse_int(&out->mm, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_DAY: case DCH_Day: case DCH_day: from_char_seq_search(&value, &s, days, ONE_UPPER, - MAX_DAY_LEN, n); - from_char_set_int(&out->d, value, n); + MAX_DAY_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->d, value, n, have_error); + CHECK_ERROR; out->d++; break; case DCH_DY: case DCH_Dy: case DCH_dy: from_char_seq_search(&value, &s, days, ONE_UPPER, - MAX_DY_LEN, n); - from_char_set_int(&out->d, value, n); + MAX_DY_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->d, value, n, have_error); + CHECK_ERROR; out->d++; break; case DCH_DDD: - from_char_parse_int(&out->ddd, &s, n); + from_char_parse_int(&out->ddd, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_IDDD: - from_char_parse_int_len(&out->ddd, &s, 3, n); + from_char_parse_int_len(&out->ddd, &s, 3, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_DD: - from_char_parse_int(&out->dd, &s, n); + from_char_parse_int(&out->dd, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_D: - from_char_parse_int(&out->d, &s, n); + from_char_parse_int(&out->d, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_ID: - from_char_parse_int_len(&out->d, &s, 1, n); + from_char_parse_int_len(&out->d, &s, 1, n, have_error); + CHECK_ERROR; /* Shift numbering to match Gregorian where Sunday = 1 */ if (++out->d > 7) out->d = 1; @@ -3173,7 +3491,8 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) break; case DCH_WW: case DCH_IW: - from_char_parse_int(&out->ww, &s, n); + from_char_parse_int(&out->ww, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_Q: @@ -3188,11 +3507,13 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) * We still parse the source string for an integer, but it * isn't stored anywhere in 'out'. */ - from_char_parse_int((int *) NULL, &s, n); + from_char_parse_int((int *) NULL, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_CC: - from_char_parse_int(&out->cc, &s, n); + from_char_parse_int(&out->cc, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_Y_YYY: @@ -3204,11 +3525,12 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) matched = sscanf(s, "%d,%03d%n", &millennia, &years, &nch); if (matched < 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid input string for \"Y,YYY\""))); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("invalid input string for \"Y,YYY\"")))); years += (millennia * 1000); - from_char_set_int(&out->year, years, n); + from_char_set_int(&out->year, years, n, have_error); + CHECK_ERROR; out->yysz = 4; s += nch; SKIP_THth(s, n->suffix); @@ -3216,82 +3538,253 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out) break; case DCH_YYYY: case DCH_IYYY: - from_char_parse_int(&out->year, &s, n); + from_char_parse_int(&out->year, &s, n, have_error); + CHECK_ERROR; out->yysz = 4; SKIP_THth(s, n->suffix); break; case DCH_YYY: case DCH_IYY: - if (from_char_parse_int(&out->year, &s, n) < 4) + len = from_char_parse_int(&out->year, &s, n, have_error); + CHECK_ERROR; + if (len < 4) out->year = adjust_partial_year_to_2020(out->year); out->yysz = 3; SKIP_THth(s, n->suffix); break; case DCH_YY: case DCH_IY: - if (from_char_parse_int(&out->year, &s, n) < 4) + len = from_char_parse_int(&out->year, &s, n, have_error); + CHECK_ERROR; + if (len < 4) out->year = adjust_partial_year_to_2020(out->year); out->yysz = 2; SKIP_THth(s, n->suffix); break; case DCH_Y: case DCH_I: - if (from_char_parse_int(&out->year, &s, n) < 4) + len = from_char_parse_int(&out->year, &s, n, have_error); + CHECK_ERROR; + if (len < 4) out->year = adjust_partial_year_to_2020(out->year); out->yysz = 1; SKIP_THth(s, n->suffix); break; case DCH_RM: from_char_seq_search(&value, &s, rm_months_upper, - ALL_UPPER, MAX_RM_LEN, n); - from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, n); + ALL_UPPER, MAX_RM_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, + n, have_error); + CHECK_ERROR; break; case DCH_rm: from_char_seq_search(&value, &s, rm_months_lower, - ALL_LOWER, MAX_RM_LEN, n); - from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, n); + ALL_LOWER, MAX_RM_LEN, n, have_error); + CHECK_ERROR; + from_char_set_int(&out->mm, MONTHS_PER_YEAR - value, + n, have_error); + CHECK_ERROR; break; case DCH_W: - from_char_parse_int(&out->w, &s, n); + from_char_parse_int(&out->w, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; case DCH_J: - from_char_parse_int(&out->j, &s, n); + from_char_parse_int(&out->j, &s, n, have_error); + CHECK_ERROR; SKIP_THth(s, n->suffix); break; } + + /* Ignore all spaces after fields */ + if (!fx_mode) + { + extra_skip = 0; + while (*s != '\0' && isspace((unsigned char) *s)) + { + s++; + extra_skip++; + } + } + } + + /* + * Standard parsing mode doesn't allow unmatched format patterns or + * trailing characters in the input string. + */ + if (std) + { + if (n->type != NODE_TYPE_END) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("input string is too short for datetime format")))); + + while (*s != '\0' && isspace((unsigned char) *s)) + s++; + + if (*s != '\0') + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("trailing characters remain in input string " + "after datetime format")))); } + +on_error: + return; } -/* select a DCHCacheEntry to hold the given format picture */ -static DCHCacheEntry * -DCH_cache_getnew(const char *str) +/* + * The invariant for DCH cache entry management is that DCHCounter is equal + * to the maximum age value among the existing entries, and we increment it + * whenever an access occurs. If we approach overflow, deal with that by + * halving all the age values, so that we retain a fairly accurate idea of + * which entries are oldest. + */ +static inline void +DCH_prevent_counter_overflow(void) { - DCHCacheEntry *ent; + if (DCHCounter >= (INT_MAX - 1)) + { + for (int i = 0; i < n_DCHCache; i++) + DCHCache[i]->age >>= 1; + DCHCounter >>= 1; + } +} + +/* + * Get mask of date/time/zone components present in format nodes. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set. + */ +static int +DCH_datetime_type(FormatNode *node, bool *have_error) +{ + FormatNode *n; + int flags = 0; - /* counter overflow check - paranoia? */ - if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES)) + for (n = node; n->type != NODE_TYPE_END; n++) { - DCHCounter = 0; + if (n->type != NODE_TYPE_ACTION) + continue; - for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++) - ent->age = (++DCHCounter); + switch (n->key->id) + { + case DCH_FX: + break; + case DCH_A_M: + case DCH_P_M: + case DCH_a_m: + case DCH_p_m: + case DCH_AM: + case DCH_PM: + case DCH_am: + case DCH_pm: + case DCH_HH: + case DCH_HH12: + case DCH_HH24: + case DCH_MI: + case DCH_SS: + case DCH_MS: /* millisecond */ + case DCH_US: /* microsecond */ + case DCH_FF1: + case DCH_FF2: + case DCH_FF3: + case DCH_FF4: + case DCH_FF5: + case DCH_FF6: + case DCH_SSSS: + flags |= DCH_TIMED; + break; + case DCH_tz: + case DCH_TZ: + case DCH_OF: + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("formatting field \"%s\" is only supported in to_char", + n->key->name)))); + flags |= DCH_ZONED; + break; + case DCH_TZH: + case DCH_TZM: + flags |= DCH_ZONED; + break; + case DCH_A_D: + case DCH_B_C: + case DCH_a_d: + case DCH_b_c: + case DCH_AD: + case DCH_BC: + case DCH_ad: + case DCH_bc: + case DCH_MONTH: + case DCH_Month: + case DCH_month: + case DCH_MON: + case DCH_Mon: + case DCH_mon: + case DCH_MM: + case DCH_DAY: + case DCH_Day: + case DCH_day: + case DCH_DY: + case DCH_Dy: + case DCH_dy: + case DCH_DDD: + case DCH_IDDD: + case DCH_DD: + case DCH_D: + case DCH_ID: + case DCH_WW: + case DCH_Q: + case DCH_CC: + case DCH_Y_YYY: + case DCH_YYYY: + case DCH_IYYY: + case DCH_YYY: + case DCH_IYY: + case DCH_YY: + case DCH_IY: + case DCH_Y: + case DCH_I: + case DCH_RM: + case DCH_rm: + case DCH_W: + case DCH_J: + flags |= DCH_DATED; + break; + } } +on_error: + return flags; +} + +/* select a DCHCacheEntry to hold the given format picture */ +static DCHCacheEntry * +DCH_cache_getnew(const char *str, bool std) +{ + DCHCacheEntry *ent; + + /* Ensure we can advance DCHCounter below */ + DCH_prevent_counter_overflow(); + /* * If cache is full, remove oldest entry (or recycle first not-valid one) */ if (n_DCHCache >= DCH_CACHE_ENTRIES) { - DCHCacheEntry *old = DCHCache + 0; + DCHCacheEntry *old = DCHCache[0]; #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "cache is full (%d)", n_DCHCache); #endif if (old->valid) { - for (ent = DCHCache + 1; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++) + for (int i = 1; i < DCH_CACHE_ENTRIES; i++) { + ent = DCHCache[i]; if (!ent->valid) { old = ent; @@ -3315,9 +3808,12 @@ DCH_cache_getnew(const char *str) #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "NEW (%d)", n_DCHCache); #endif - ent = DCHCache + n_DCHCache; + Assert(DCHCache[n_DCHCache] == NULL); + DCHCache[n_DCHCache] = ent = (DCHCacheEntry *) + MemoryContextAllocZero(TopMemoryContext, sizeof(DCHCacheEntry)); ent->valid = false; StrNCpy(ent->str, str, DCH_CACHE_SIZE + 1); + ent->std = std; ent->age = (++DCHCounter); /* caller is expected to fill format, then set valid */ ++n_DCHCache; @@ -3327,23 +3823,16 @@ DCH_cache_getnew(const char *str) /* look for an existing DCHCacheEntry matching the given format picture */ static DCHCacheEntry * -DCH_cache_search(const char *str) +DCH_cache_search(const char *str, bool std) { - int i; - DCHCacheEntry *ent; + /* Ensure we can advance DCHCounter below */ + DCH_prevent_counter_overflow(); - /* counter overflow check - paranoia? */ - if (DCHCounter >= (INT_MAX - DCH_CACHE_ENTRIES)) + for (int i = 0; i < n_DCHCache; i++) { - DCHCounter = 0; + DCHCacheEntry *ent = DCHCache[i]; - for (ent = DCHCache; ent < (DCHCache + DCH_CACHE_ENTRIES); ent++) - ent->age = (++DCHCounter); - } - - for (i = 0, ent = DCHCache; i < n_DCHCache; i++, ent++) - { - if (ent->valid && strcmp(ent->str, str) == 0) + if (ent->valid && strcmp(ent->str, str) == 0 && ent->std == std) { ent->age = (++DCHCounter); return ent; @@ -3355,21 +3844,21 @@ DCH_cache_search(const char *str) /* Find or create a DCHCacheEntry for the given format picture */ static DCHCacheEntry * -DCH_cache_fetch(const char *str) +DCH_cache_fetch(const char *str, bool std) { DCHCacheEntry *ent; - if ((ent = DCH_cache_search(str)) == NULL) + if ((ent = DCH_cache_search(str, std)) == NULL) { /* * Not in the cache, must run parser and save a new format-picture to * the cache. Do not mark the cache entry valid until parsing * succeeds. */ - ent = DCH_cache_getnew(str); + ent = DCH_cache_getnew(str, std); - parse_format(ent->format, str, DCH_keywords, - DCH_suff, DCH_index, DCH_TYPE, NULL); + parse_format(ent->format, str, DCH_keywords, DCH_suff, DCH_index, + DCH_FLAG | (std ? STD_FLAG : 0), NULL); ent->valid = true; } @@ -3414,14 +3903,14 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt, bool is_interval, Oid collid) format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode)); parse_format(format, fmt_str, DCH_keywords, - DCH_suff, DCH_index, DCH_TYPE, NULL); + DCH_suff, DCH_index, DCH_FLAG, NULL); } else { /* * Use cache buffers */ - DCHCacheEntry *ent = DCH_cache_fetch(fmt_str); + DCHCacheEntry *ent = DCH_cache_fetch(fmt_str, false); incache = true; format = ent->format; @@ -3561,13 +4050,14 @@ to_timestamp(PG_FUNCTION_ARGS) int tz; struct pg_tm tm; fsec_t fsec; + int fprec; - do_to_timestamp(date_txt, fmt, &tm, &fsec); + do_to_timestamp(date_txt, fmt, false, &tm, &fsec, &fprec, NULL, NULL); /* Use the specified time zone, if any. */ if (tm.tm_zone) { - int dterr = DecodeTimezone((char *) tm.tm_zone, &tz); + int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), &tz); if (dterr) DateTimeParseError(dterr, text_to_cstring(date_txt), "timestamptz"); @@ -3580,12 +4070,16 @@ to_timestamp(PG_FUNCTION_ARGS) (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); + /* Use the specified fractional precision, if any. */ + if (fprec) + AdjustTimestampForTypmod(&result, fprec); + PG_RETURN_TIMESTAMP(result); } /* ---------- * TO_DATE - * Make Date from date_str which is formated at argument 'fmt' + * Make Date from date_str which is formatted at argument 'fmt' * ---------- */ Datum @@ -3597,7 +4091,7 @@ to_date(PG_FUNCTION_ARGS) struct pg_tm tm; fsec_t fsec; - do_to_timestamp(date_txt, fmt, &tm, &fsec); + do_to_timestamp(date_txt, fmt, false, &tm, &fsec, NULL, NULL, NULL); /* Prevent overflow in Julian-day routines */ if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday)) @@ -3618,11 +4112,186 @@ to_date(PG_FUNCTION_ARGS) PG_RETURN_DATEADT(result); } +/* + * Convert the 'date_txt' input to a datetime type using argument 'fmt' as a format string. + * The actual data type (returned in 'typid', 'typmod') is determined by + * the presence of date/time/zone components in the format string. + * + * When timezone component is present, the corresponding offset is set to '*tz'. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set + * and zero value is returned. + */ +Datum +parse_datetime(text *date_txt, text *fmt, bool strict, Oid *typid, + int32 *typmod, int *tz, bool *have_error) +{ + struct pg_tm tm; + fsec_t fsec; + int fprec = 0; + uint32 flags; + + do_to_timestamp(date_txt, fmt, strict, &tm, &fsec, &fprec, &flags, have_error); + CHECK_ERROR; + + *typmod = fprec ? fprec : -1; /* fractional part precision */ + + if (flags & DCH_DATED) + { + if (flags & DCH_TIMED) + { + if (flags & DCH_ZONED) + { + TimestampTz result; + + if (tm.tm_zone) + { + int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz); + + if (dterr) + DateTimeParseError(dterr, text_to_cstring(date_txt), "timestamptz"); + } + else + { + /* + * Time zone is present in format string, but not in input + * string. Assuming do_to_timestamp() triggers no error + * this should be possible only in non-strict case. + */ + Assert(!strict); + + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("missing time zone in input string for type timestamptz")))); + } + + if (tm2timestamp(&tm, fsec, tz, &result) != 0) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamptz out of range")))); + + AdjustTimestampForTypmod(&result, *typmod); + + *typid = TIMESTAMPTZOID; + return TimestampTzGetDatum(result); + } + else + { + Timestamp result; + + if (tm2timestamp(&tm, fsec, NULL, &result) != 0) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range")))); + + AdjustTimestampForTypmod(&result, *typmod); + + *typid = TIMESTAMPOID; + return TimestampGetDatum(result); + } + } + else + { + if (flags & DCH_ZONED) + { + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("datetime format is zoned but not timed")))); + } + else + { + DateADT result; + + /* Prevent overflow in Julian-day routines */ + if (!IS_VALID_JULIAN(tm.tm_year, tm.tm_mon, tm.tm_mday)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range: \"%s\"", + text_to_cstring(date_txt))))); + + result = date2j(tm.tm_year, tm.tm_mon, tm.tm_mday) - + POSTGRES_EPOCH_JDATE; + + /* Now check for just-out-of-range dates */ + if (!IS_VALID_DATE(result)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range: \"%s\"", + text_to_cstring(date_txt))))); + + *typid = DATEOID; + return DateADTGetDatum(result); + } + } + } + else if (flags & DCH_TIMED) + { + if (flags & DCH_ZONED) + { + TimeTzADT *result = palloc(sizeof(TimeTzADT)); + + if (tm.tm_zone) + { + int dterr = DecodeTimezone(unconstify(char *, tm.tm_zone), tz); + + if (dterr) + RETURN_ERROR(DateTimeParseError(dterr, text_to_cstring(date_txt), "timetz")); + } + else + { + /* + * Time zone is present in format string, but not in input + * string. Assuming do_to_timestamp() triggers no error this + * should be possible only in non-strict case. + */ + Assert(!strict); + + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("missing time zone in input string for type timetz")))); + } + + if (tm2timetz(&tm, fsec, *tz, result) != 0) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timetz out of range")))); + + AdjustTimeForTypmod(&result->time, *typmod); + + *typid = TIMETZOID; + return TimeTzADTPGetDatum(result); + } + else + { + TimeADT result; + + if (tm2time(&tm, fsec, &result) != 0) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("time out of range")))); + + AdjustTimeForTypmod(&result, *typmod); + + *typid = TIMEOID; + return TimeADTGetDatum(result); + } + } + else + { + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("datetime format is not dated and not timed")))); + } + +on_error: + return (Datum) 0; +} + /* * do_to_timestamp: shared code for to_timestamp and to_date * - * Parse the 'date_txt' according to 'fmt', return results as a struct pg_tm - * and fractional seconds. + * Parse the 'date_txt' according to 'fmt', return results as a struct pg_tm, + * fractional seconds, and fractional precision. * * We parse 'fmt' into a list of FormatNodes, which is then passed to * DCH_from_char to populate a TmFromChar with the parsed contents of @@ -3630,16 +4299,24 @@ to_date(PG_FUNCTION_ARGS) * * The TmFromChar is then analysed and converted into the final results in * struct 'tm' and 'fsec'. + * + * Bit mask of date/time/zone components found in 'fmt' is returned in 'flags'. + * + * 'std' specifies standard parsing mode. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set. */ static void -do_to_timestamp(text *date_txt, text *fmt, - struct pg_tm *tm, fsec_t *fsec) +do_to_timestamp(text *date_txt, text *fmt, bool std, + struct pg_tm *tm, fsec_t *fsec, int *fprec, + uint32 *flags, bool *have_error) { - FormatNode *format; + FormatNode *format = NULL; TmFromChar tmfc; int fmt_len; char *date_str; int fmask; + bool incache = false; date_str = text_to_cstring(date_txt); @@ -3653,7 +4330,6 @@ do_to_timestamp(text *date_txt, text *fmt, if (fmt_len) { char *fmt_str; - bool incache; fmt_str = text_to_cstring(fmt); @@ -3663,19 +4339,17 @@ do_to_timestamp(text *date_txt, text *fmt, * Allocate new memory if format picture is bigger than static * cache and do not use cache (call parser always) */ - incache = false; - format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode)); - parse_format(format, fmt_str, DCH_keywords, - DCH_suff, DCH_index, DCH_TYPE, NULL); + parse_format(format, fmt_str, DCH_keywords, DCH_suff, DCH_index, + DCH_FLAG | (std ? STD_FLAG : 0), NULL); } else { /* * Use cache buffers */ - DCHCacheEntry *ent = DCH_cache_fetch(fmt_str); + DCHCacheEntry *ent = DCH_cache_fetch(fmt_str, std); incache = true; format = ent->format; @@ -3686,11 +4360,21 @@ do_to_timestamp(text *date_txt, text *fmt, /* dump_index(DCH_keywords, DCH_index); */ #endif - DCH_from_char(format, date_str, &tmfc); + DCH_from_char(format, date_str, &tmfc, std, have_error); + CHECK_ERROR; pfree(fmt_str); + + if (flags) + *flags = DCH_datetime_type(format, have_error); + if (!incache) + { pfree(format); + format = NULL; + } + + CHECK_ERROR; } DEBUG_TMFC(&tmfc); @@ -3719,11 +4403,13 @@ do_to_timestamp(text *date_txt, text *fmt, if (tmfc.clock == CLOCK_12_HOUR) { if (tm->tm_hour < 1 || tm->tm_hour > HOURS_PER_DAY / 2) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("hour \"%d\" is invalid for the 12-hour clock", - tm->tm_hour), - errhint("Use the 24-hour clock, or give an hour between 1 and 12."))); + { + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("hour \"%d\" is invalid for the 12-hour clock", + tm->tm_hour), + errhint("Use the 24-hour clock, or give an hour between 1 and 12.")))); + } if (tmfc.pm && tm->tm_hour < HOURS_PER_DAY / 2) tm->tm_hour += HOURS_PER_DAY / 2; @@ -3827,9 +4513,11 @@ do_to_timestamp(text *date_txt, text *fmt, */ if (!tm->tm_year && !tmfc.bc) - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("cannot calculate day of year without year information"))); + { + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_DATETIME_FORMAT), + errmsg("cannot calculate day of year without year information")))); + } if (tmfc.mode == FROM_CHAR_DATE_ISOWEEK) { @@ -3870,6 +4558,8 @@ do_to_timestamp(text *date_txt, text *fmt, *fsec += tmfc.ms * 1000; if (tmfc.us) *fsec += tmfc.us; + if (fprec) + *fprec = tmfc.ff; /* fractional precision, if specified */ /* Range-check date fields according to bit mask computed above */ if (fmask != 0) @@ -3884,7 +4574,7 @@ do_to_timestamp(text *date_txt, text *fmt, * said DTERR_MD_FIELD_OVERFLOW, because we don't want to print an * irrelevant hint about datestyle. */ - DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp"); + RETURN_ERROR(DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp")); } } @@ -3893,7 +4583,9 @@ do_to_timestamp(text *date_txt, text *fmt, tm->tm_min < 0 || tm->tm_min >= MINS_PER_HOUR || tm->tm_sec < 0 || tm->tm_sec >= SECS_PER_MINUTE || *fsec < INT64CONST(0) || *fsec >= USECS_PER_SEC) - DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp"); + { + RETURN_ERROR(DateTimeParseError(DTERR_FIELD_OVERFLOW, date_str, "timestamp")); + } /* Save parsed time-zone into tm->tm_zone if it was specified */ if (tmfc.tzsign) @@ -3902,16 +4594,23 @@ do_to_timestamp(text *date_txt, text *fmt, if (tmfc.tzh < 0 || tmfc.tzh > MAX_TZDISP_HOUR || tmfc.tzm < 0 || tmfc.tzm >= MINS_PER_HOUR) - DateTimeParseError(DTERR_TZDISP_OVERFLOW, date_str, "timestamp"); + { + RETURN_ERROR(DateTimeParseError(DTERR_TZDISP_OVERFLOW, date_str, "timestamp")); + } tz = psprintf("%c%02d:%02d", - tmfc.tzsign > 0 ? '+' : '-', tmfc.tzh, tmfc.tzm); + tmfc.tzsign > 0 ? '+' : '-', tmfc.tzh, tmfc.tzm); tm->tm_zone = tz; } DEBUG_TM(tm); +on_error: + + if (format && !incache) + pfree(format); + pfree(date_str); } @@ -3942,35 +4641,42 @@ do { \ (_n)->zero_end = 0; \ } while(0) +/* This works the same as DCH_prevent_counter_overflow */ +static inline void +NUM_prevent_counter_overflow(void) +{ + if (NUMCounter >= (INT_MAX - 1)) + { + for (int i = 0; i < n_NUMCache; i++) + NUMCache[i]->age >>= 1; + NUMCounter >>= 1; + } +} + /* select a NUMCacheEntry to hold the given format picture */ static NUMCacheEntry * NUM_cache_getnew(const char *str) { NUMCacheEntry *ent; - /* counter overflow check - paranoia? */ - if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES)) - { - NUMCounter = 0; - - for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++) - ent->age = (++NUMCounter); - } + /* Ensure we can advance NUMCounter below */ + NUM_prevent_counter_overflow(); /* * If cache is full, remove oldest entry (or recycle first not-valid one) */ if (n_NUMCache >= NUM_CACHE_ENTRIES) { - NUMCacheEntry *old = NUMCache + 0; + NUMCacheEntry *old = NUMCache[0]; #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "Cache is full (%d)", n_NUMCache); #endif if (old->valid) { - for (ent = NUMCache + 1; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++) + for (int i = 1; i < NUM_CACHE_ENTRIES; i++) { + ent = NUMCache[i]; if (!ent->valid) { old = ent; @@ -3994,7 +4700,9 @@ NUM_cache_getnew(const char *str) #ifdef DEBUG_TO_FROM_CHAR elog(DEBUG_elog_output, "NEW (%d)", n_NUMCache); #endif - ent = NUMCache + n_NUMCache; + Assert(NUMCache[n_NUMCache] == NULL); + NUMCache[n_NUMCache] = ent = (NUMCacheEntry *) + MemoryContextAllocZero(TopMemoryContext, sizeof(NUMCacheEntry)); ent->valid = false; StrNCpy(ent->str, str, NUM_CACHE_SIZE + 1); ent->age = (++NUMCounter); @@ -4008,20 +4716,13 @@ NUM_cache_getnew(const char *str) static NUMCacheEntry * NUM_cache_search(const char *str) { - int i; - NUMCacheEntry *ent; + /* Ensure we can advance NUMCounter below */ + NUM_prevent_counter_overflow(); - /* counter overflow check - paranoia? */ - if (NUMCounter >= (INT_MAX - NUM_CACHE_ENTRIES)) + for (int i = 0; i < n_NUMCache; i++) { - NUMCounter = 0; + NUMCacheEntry *ent = NUMCache[i]; - for (ent = NUMCache; ent < (NUMCache + NUM_CACHE_ENTRIES); ent++) - ent->age = (++NUMCounter); - } - - for (i = 0, ent = NUMCache; i < n_NUMCache; i++, ent++) - { if (ent->valid && strcmp(ent->str, str) == 0) { ent->age = (++NUMCounter); @@ -4050,7 +4751,7 @@ NUM_cache_fetch(const char *str) zeroize_NUM(&ent->Num); parse_format(ent->format, str, NUM_keywords, - NULL, NUM_index, NUM_TYPE, &ent->Num); + NULL, NUM_index, NUM_FLAG, &ent->Num); ent->valid = true; } @@ -4082,7 +4783,7 @@ NUM_cache(int len, NUMDesc *Num, text *pars_str, bool *shouldFree) zeroize_NUM(Num); parse_format(format, str, NUM_keywords, - NULL, NUM_index, NUM_TYPE, Num); + NULL, NUM_index, NUM_FLAG, Num); } else { @@ -5631,7 +6332,7 @@ float4_to_char(PG_FUNCTION_ARGS) numstr = orgnum = int_to_roman((int) rint(value)); else if (IS_EEEE(&Num)) { - if (isnan(value) || is_infinite(value)) + if (isnan(value) || isinf(value)) { /* * Allow 6 characters for the leading sign, the decimal point, @@ -5735,7 +6436,7 @@ float8_to_char(PG_FUNCTION_ARGS) numstr = orgnum = int_to_roman((int) rint(value)); else if (IS_EEEE(&Num)) { - if (isnan(value) || is_infinite(value)) + if (isnan(value) || isinf(value)) { /* * Allow 6 characters for the leading sign, the decimal point, diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c index a97cbea2483..5d4f26a4901 100644 --- a/src/backend/utils/adt/genfile.c +++ b/src/backend/utils/adt/genfile.c @@ -4,7 +4,7 @@ * Functions for direct access to files * * - * Copyright (c) 2004-2018, PostgreSQL Global Development Group + * Copyright (c) 2004-2019, PostgreSQL Global Development Group * * Author: Andreas Pflug * @@ -23,6 +23,7 @@ #include "access/htup_details.h" #include "access/xlog_internal.h" #include "catalog/pg_authid.h" +#include "catalog/pg_tablespace_d.h" #include "catalog/pg_type.h" #include "funcapi.h" #include "mb/pg_wchar.h" @@ -31,6 +32,7 @@ #include "storage/fd.h" #include "utils/builtins.h" #include "utils/memutils.h" +#include "utils/syscache.h" #include "utils/timestamp.h" typedef struct @@ -217,7 +219,9 @@ pg_read_file(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to read files with adminpack 1.0"), - errhint("Consider using pg_file_read(), which is part of core, instead.")))); + /* translator: %s is a SQL function name */ + errhint("Consider using %s, which is part of core, instead.", + "pg_file_read()")))); /* handle optional arguments */ if (PG_NARGS() >= 3) @@ -321,7 +325,7 @@ pg_read_binary_file(PG_FUNCTION_ARGS) /* * Wrapper functions for the 1 and 3 argument variants of pg_read_file_v2() - * and pg_binary_read_file(). + * and pg_read_binary_file(). * * These are necessary to pass the sanity check in opr_sanity, which checks * that all built-in functions that share the implementing C function take @@ -386,7 +390,7 @@ pg_stat_file(PG_FUNCTION_ARGS) * This record type had better match the output parameters declared for me * in pg_proc.h. */ - tupdesc = CreateTemplateTupleDesc(6, false); + tupdesc = CreateTemplateTupleDesc(6); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "size", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, @@ -520,7 +524,7 @@ pg_ls_dir_1arg(PG_FUNCTION_ARGS) /* Generic function to return a directory listing of files */ static Datum -pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir) +pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok) { FuncCallContext *funcctx; struct dirent *de; @@ -536,7 +540,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir) fctx = palloc(sizeof(directory_fctx)); - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "size", @@ -549,10 +553,18 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir) fctx->dirdesc = AllocateDir(fctx->location); if (!fctx->dirdesc) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not open directory \"%s\": %m", - fctx->location))); + { + if (missing_ok && errno == ENOENT) + { + MemoryContextSwitchTo(oldcontext); + SRF_RETURN_DONE(funcctx); + } + else + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open directory \"%s\": %m", + fctx->location))); + } funcctx->user_fctx = fctx; MemoryContextSwitchTo(oldcontext); @@ -601,12 +613,59 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir) Datum pg_ls_logdir(PG_FUNCTION_ARGS) { - return pg_ls_dir_files(fcinfo, Log_directory); + return pg_ls_dir_files(fcinfo, Log_directory, false); } /* Function to return the list of files in the WAL directory */ Datum pg_ls_waldir(PG_FUNCTION_ARGS) { - return pg_ls_dir_files(fcinfo, XLOGDIR); + return pg_ls_dir_files(fcinfo, XLOGDIR, false); +} + +/* + * Generic function to return the list of files in pgsql_tmp + */ +static Datum +pg_ls_tmpdir(FunctionCallInfo fcinfo, Oid tblspc) +{ + char path[MAXPGPATH]; + + if (!SearchSysCacheExists1(TABLESPACEOID, ObjectIdGetDatum(tblspc))) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("tablespace with OID %u does not exist", + tblspc))); + + TempTablespacePath(path, tblspc); + return pg_ls_dir_files(fcinfo, path, true); +} + +/* + * Function to return the list of temporary files in the pg_default tablespace's + * pgsql_tmp directory + */ +Datum +pg_ls_tmpdir_noargs(PG_FUNCTION_ARGS) +{ + return pg_ls_tmpdir(fcinfo, DEFAULTTABLESPACE_OID); +} + +/* + * Function to return the list of temporary files in the specified tablespace's + * pgsql_tmp directory + */ +Datum +pg_ls_tmpdir_1arg(PG_FUNCTION_ARGS) +{ + return pg_ls_tmpdir(fcinfo, PG_GETARG_OID(0)); +} + +/* + * Function to return the list of files in the WAL archive status directory. + */ +Datum +pg_ls_archive_statusdir(PG_FUNCTION_ARGS) +{ + return pg_ls_dir_files(fcinfo, XLOGDIR "/archive_status", true); } diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index f57380a4df2..6558ea3937d 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -3,7 +3,17 @@ * geo_ops.c * 2D geometric operations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * This module implements the geometric functions and operators. The + * geometric types are (from simple to more complicated): + * + * - point + * - line + * - line segment + * - box + * - circle + * - polygon + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,13 +31,38 @@ #include "libpq/pqformat.h" #include "miscadmin.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" #include "utils/geo_decls.h" -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - +/* + * * Type constructors have this form: + * void type_construct(Type *result, ...); + * + * * Operators commonly have signatures such as + * void type1_operator_type2(Type *result, Type1 *obj1, Type2 *obj2); + * + * Common operators are: + * * Intersection point: + * bool type1_interpt_type2(Point *result, Type1 *obj1, Type2 *obj2); + * Return whether the two objects intersect. If *result is not NULL, + * it is set to the intersection point. + * + * * Containment: + * bool type1_contain_type2(Type1 *obj1, Type2 *obj2); + * Return whether obj1 contains obj2. + * bool type1_contain_type2(Type1 *contains_obj, Type1 *contained_obj); + * Return whether obj1 contains obj2 (used when types are the same) + * + * * Distance of closest point in or on obj1 to obj2: + * float8 type1_closept_type2(Point *result, Type1 *obj1, Type2 *obj2); + * Returns the shortest distance between two objects. If *result is not + * NULL, it is set to the closest point in or on obj1 to obj2. + * + * These functions may be used to implement multiple SQL-level operators. For + * example, determining whether two lines are parallel is done by checking + * whether they don't intersect. + */ /* * Internal routines @@ -38,46 +73,74 @@ enum path_delim PATH_NONE, PATH_OPEN, PATH_CLOSED }; +/* Routines for points */ +static inline void point_construct(Point *result, float8 x, float8 y); +static inline void point_add_point(Point *result, Point *pt1, Point *pt2); +static inline void point_sub_point(Point *result, Point *pt1, Point *pt2); +static inline void point_mul_point(Point *result, Point *pt1, Point *pt2); +static inline void point_div_point(Point *result, Point *pt1, Point *pt2); +static inline bool point_eq_point(Point *pt1, Point *pt2); +static inline float8 point_dt(Point *pt1, Point *pt2); +static inline float8 point_sl(Point *pt1, Point *pt2); static int point_inside(Point *p, int npts, Point *plist); -static int lseg_crossing(double x, double y, double px, double py); -static BOX *box_construct(double x1, double x2, double y1, double y2); -static BOX *box_fill(BOX *result, double x1, double x2, double y1, double y2); + +/* Routines for lines */ +static inline void line_construct(LINE *result, Point *pt, float8 m); +static inline float8 line_sl(LINE *line); +static inline float8 line_invsl(LINE *line); +static bool line_interpt_line(Point *result, LINE *l1, LINE *l2); +static bool line_contain_point(LINE *line, Point *point); +static float8 line_closept_point(Point *result, LINE *line, Point *pt); + +/* Routines for line segments */ +static inline void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2); +static inline float8 lseg_sl(LSEG *lseg); +static inline float8 lseg_invsl(LSEG *lseg); +static bool lseg_interpt_line(Point *result, LSEG *lseg, LINE *line); +static bool lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2); +static int lseg_crossing(float8 x, float8 y, float8 px, float8 py); +static bool lseg_contain_point(LSEG *lseg, Point *point); +static float8 lseg_closept_point(Point *result, LSEG *lseg, Point *pt); +static float8 lseg_closept_line(Point *result, LSEG *lseg, LINE *line); +static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg); + +/* Routines for boxes */ +static inline void box_construct(BOX *result, Point *pt1, Point *pt2); +static void box_cn(Point *center, BOX *box); static bool box_ov(BOX *box1, BOX *box2); -static double box_ht(BOX *box); -static double box_wd(BOX *box); -static double circle_ar(CIRCLE *circle); -static CIRCLE *circle_copy(CIRCLE *circle); -static LINE *line_construct_pm(Point *pt, double m); -static void line_construct_pts(LINE *line, Point *pt1, Point *pt2); -static bool lseg_intersect_internal(LSEG *l1, LSEG *l2); -static double lseg_dt(LSEG *l1, LSEG *l2); -static bool on_ps_internal(Point *pt, LSEG *lseg); +static float8 box_ar(BOX *box); +static float8 box_ht(BOX *box); +static float8 box_wd(BOX *box); +static bool box_contain_point(BOX *box, Point *point); +static bool box_contain_box(BOX *contains_box, BOX *contained_box); +static bool box_contain_lseg(BOX *box, LSEG *lseg); +static bool box_interpt_lseg(Point *result, BOX *box, LSEG *lseg); +static float8 box_closept_point(Point *result, BOX *box, Point *point); +static float8 box_closept_lseg(Point *result, BOX *box, LSEG *lseg); + +/* Routines for circles */ +static float8 circle_ar(CIRCLE *circle); + +/* Routines for polygons */ static void make_bound_box(POLYGON *poly); +static void poly_to_circle(CIRCLE *result, POLYGON *poly); +static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start); +static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly); static bool plist_same(int npts, Point *p1, Point *p2); -static Point *point_construct(double x, double y); -static Point *point_copy(Point *pt); -static double single_decode(char *num, char **endptr_p, - const char *type_name, const char *orig_string); +static float8 dist_ppoly_internal(Point *pt, POLYGON *poly); + +/* Routines for encoding and decoding */ +static float8 single_decode(char *num, char **endptr_p, + const char *type_name, const char *orig_string); static void single_encode(float8 x, StringInfo str); -static void pair_decode(char *str, double *x, double *y, char **endptr_p, - const char *type_name, const char *orig_string); +static void pair_decode(char *str, float8 *x, float8 *y, char **endptr_p, + const char *type_name, const char *orig_string); static void pair_encode(float8 x, float8 y, StringInfo str); static int pair_count(char *s, char delim); static void path_decode(char *str, bool opentype, int npts, Point *p, - bool *isopen, char **endptr_p, - const char *type_name, const char *orig_string); + bool *isopen, char **endptr_p, + const char *type_name, const char *orig_string); static char *path_encode(enum path_delim path_delim, int npts, Point *pt); -static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2); -static double box_ar(BOX *box); -static void box_cn(Point *center, BOX *box); -static Point *interpt_sl(LSEG *lseg, LINE *line); -static bool has_interpt_sl(LSEG *lseg, LINE *line); -static double dist_pl_internal(Point *pt, LINE *line); -static double dist_ps_internal(Point *pt, LSEG *lseg); -static Point *line_interpt_internal(LINE *l1, LINE *l2); -static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start); -static Point *lseg_interpt_internal(LSEG *l1, LSEG *l2); -static double dist_ppoly_internal(Point *pt, POLYGON *poly); /* @@ -93,6 +156,8 @@ static double dist_ppoly_internal(Point *pt, POLYGON *poly); #define RDELIM_EP ']' #define LDELIM_C '<' #define RDELIM_C '>' +#define LDELIM_L '{' +#define RDELIM_L '}' /* @@ -120,7 +185,7 @@ static double dist_ppoly_internal(Point *pt, POLYGON *poly); * and restore that order for text output - tgl 97/01/16 */ -static double +static float8 single_decode(char *num, char **endptr_p, const char *type_name, const char *orig_string) { @@ -137,7 +202,7 @@ single_encode(float8 x, StringInfo str) } /* single_encode() */ static void -pair_decode(char *str, double *x, double *y, char **endptr_p, +pair_decode(char *str, float8 *x, float8 *y, char **endptr_p, const char *type_name, const char *orig_string) { bool has_delim; @@ -236,12 +301,9 @@ path_decode(char *str, bool opentype, int npts, Point *p, p++; } - while (isspace((unsigned char) *str)) - str++; while (depth > 0) { - if ((*str == RDELIM) - || ((*str == RDELIM_EP) && (*isopen) && (depth == 1))) + if (*str == RDELIM || (*str == RDELIM_EP && *isopen && depth == 1)) { depth--; str++; @@ -353,19 +415,19 @@ box_in(PG_FUNCTION_ARGS) char *str = PG_GETARG_CSTRING(0); BOX *box = (BOX *) palloc(sizeof(BOX)); bool isopen; - double x, + float8 x, y; path_decode(str, false, 2, &(box->high), &isopen, NULL, "box", str); /* reorder corners if necessary... */ - if (box->high.x < box->low.x) + if (float8_lt(box->high.x, box->low.x)) { x = box->high.x; box->high.x = box->low.x; box->low.x = x; } - if (box->high.y < box->low.y) + if (float8_lt(box->high.y, box->low.y)) { y = box->high.y; box->high.y = box->low.y; @@ -393,7 +455,7 @@ box_recv(PG_FUNCTION_ARGS) { StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); BOX *box; - double x, + float8 x, y; box = (BOX *) palloc(sizeof(BOX)); @@ -404,13 +466,13 @@ box_recv(PG_FUNCTION_ARGS) box->low.y = pq_getmsgfloat8(buf); /* reorder corners if necessary... */ - if (box->high.x < box->low.x) + if (float8_lt(box->high.x, box->low.x)) { x = box->high.x; box->high.x = box->low.x; box->low.x = x; } - if (box->high.y < box->low.y) + if (float8_lt(box->high.y, box->low.y)) { y = box->high.y; box->high.y = box->low.y; @@ -440,55 +502,29 @@ box_send(PG_FUNCTION_ARGS) /* box_construct - fill in a new box. */ -static BOX * -box_construct(double x1, double x2, double y1, double y2) -{ - BOX *result = (BOX *) palloc(sizeof(BOX)); - - return box_fill(result, x1, x2, y1, y2); -} - - -/* box_fill - fill in a given box struct - */ -static BOX * -box_fill(BOX *result, double x1, double x2, double y1, double y2) +static inline void +box_construct(BOX *result, Point *pt1, Point *pt2) { - if (x1 > x2) + if (float8_gt(pt1->x, pt2->x)) { - result->high.x = x1; - result->low.x = x2; + result->high.x = pt1->x; + result->low.x = pt2->x; } else { - result->high.x = x2; - result->low.x = x1; + result->high.x = pt2->x; + result->low.x = pt1->x; } - if (y1 > y2) + if (float8_gt(pt1->y, pt2->y)) { - result->high.y = y1; - result->low.y = y2; + result->high.y = pt1->y; + result->low.y = pt2->y; } else { - result->high.y = y2; - result->low.y = y1; + result->high.y = pt2->y; + result->low.y = pt1->y; } - - return result; -} - - -/* box_copy - copy a box - */ -BOX * -box_copy(BOX *box) -{ - BOX *result = (BOX *) palloc(sizeof(BOX)); - - memcpy((char *) result, (char *) box, sizeof(BOX)); - - return result; } @@ -505,10 +541,8 @@ box_same(PG_FUNCTION_ARGS) BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPeq(box1->high.x, box2->high.x) && - FPeq(box1->low.x, box2->low.x) && - FPeq(box1->high.y, box2->high.y) && - FPeq(box1->low.y, box2->low.y)); + PG_RETURN_BOOL(point_eq_point(&box1->high, &box2->high) && + point_eq_point(&box1->low, &box2->low)); } /* box_overlap - does box1 overlap box2? @@ -637,10 +671,7 @@ box_contained(PG_FUNCTION_ARGS) BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPle(box1->high.x, box2->high.x) && - FPge(box1->low.x, box2->low.x) && - FPle(box1->high.y, box2->high.y) && - FPge(box1->low.y, box2->low.y)); + PG_RETURN_BOOL(box_contain_box(box2, box1)); } /* box_contain - does box1 contain box2? @@ -651,10 +682,19 @@ box_contain(PG_FUNCTION_ARGS) BOX *box1 = PG_GETARG_BOX_P(0); BOX *box2 = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(FPge(box1->high.x, box2->high.x) && - FPle(box1->low.x, box2->low.x) && - FPge(box1->high.y, box2->high.y) && - FPle(box1->low.y, box2->low.y)); + PG_RETURN_BOOL(box_contain_box(box1, box2)); +} + +/* + * Check whether the second box is in the first box or on its border + */ +static bool +box_contain_box(BOX *contains_box, BOX *contained_box) +{ + return FPge(contains_box->high.x, contained_box->high.x) && + FPle(contains_box->low.x, contained_box->low.x) && + FPge(contains_box->high.y, contained_box->high.y) && + FPle(contains_box->low.y, contained_box->low.y); } @@ -757,7 +797,7 @@ box_width(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); - PG_RETURN_FLOAT8(box->high.x - box->low.x); + PG_RETURN_FLOAT8(box_wd(box)); } @@ -769,7 +809,7 @@ box_height(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); - PG_RETURN_FLOAT8(box->high.y - box->low.y); + PG_RETURN_FLOAT8(box_ht(box)); } @@ -787,7 +827,7 @@ box_distance(PG_FUNCTION_ARGS) box_cn(&a, box1); box_cn(&b, box2); - PG_RETURN_FLOAT8(HYPOT(a.x - b.x, a.y - b.y)); + PG_RETURN_FLOAT8(point_dt(&a, &b)); } @@ -807,10 +847,10 @@ box_center(PG_FUNCTION_ARGS) /* box_ar - returns the area of the box. */ -static double +static float8 box_ar(BOX *box) { - return box_wd(box) * box_ht(box); + return float8_mul(box_wd(box), box_ht(box)); } @@ -819,28 +859,28 @@ box_ar(BOX *box) static void box_cn(Point *center, BOX *box) { - center->x = (box->high.x + box->low.x) / 2.0; - center->y = (box->high.y + box->low.y) / 2.0; + center->x = float8_div(float8_pl(box->high.x, box->low.x), 2.0); + center->y = float8_div(float8_pl(box->high.y, box->low.y), 2.0); } /* box_wd - returns the width (length) of the box * (horizontal magnitude). */ -static double +static float8 box_wd(BOX *box) { - return box->high.x - box->low.x; + return float8_mi(box->high.x, box->low.x); } /* box_ht - returns the height of the box * (vertical magnitude). */ -static double +static float8 box_ht(BOX *box) { - return box->high.y - box->low.y; + return float8_mi(box->high.y, box->low.y); } @@ -864,10 +904,10 @@ box_intersect(PG_FUNCTION_ARGS) result = (BOX *) palloc(sizeof(BOX)); - result->high.x = Min(box1->high.x, box2->high.x); - result->low.x = Max(box1->low.x, box2->low.x); - result->high.y = Min(box1->high.y, box2->high.y); - result->low.y = Max(box1->low.y, box2->low.y); + result->high.x = float8_min(box1->high.x, box2->high.x); + result->low.x = float8_max(box1->low.x, box2->low.x); + result->high.y = float8_min(box1->high.y, box2->high.y); + result->low.y = float8_max(box1->low.y, box2->low.y); PG_RETURN_BOX_P(result); } @@ -905,7 +945,7 @@ line_decode(char *s, const char *str, LINE *line) if (*s++ != DELIM) return false; line->C = single_decode(s, &s, "line", str); - if (*s++ != '}') + if (*s++ != RDELIM_L) return false; while (isspace((unsigned char) *s)) s++; @@ -926,7 +966,7 @@ line_in(PG_FUNCTION_ARGS) s = str; while (isspace((unsigned char) *s)) s++; - if (*s == '{') + if (*s == LDELIM_L) { if (!line_decode(s + 1, str, line)) ereport(ERROR, @@ -940,12 +980,12 @@ line_in(PG_FUNCTION_ARGS) } else { - path_decode(s, true, 2, &(lseg.p[0]), &isopen, NULL, "line", str); - if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y)) + path_decode(s, true, 2, &lseg.p[0], &isopen, NULL, "line", str); + if (point_eq_point(&lseg.p[0], &lseg.p[1])) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid line specification: must be two distinct points"))); - line_construct_pts(line, &lseg.p[0], &lseg.p[1]); + line_construct(line, &lseg.p[0], lseg_sl(&lseg)); } PG_RETURN_LINE_P(line); @@ -960,7 +1000,8 @@ line_out(PG_FUNCTION_ARGS) char *bstr = float8out_internal(line->B); char *cstr = float8out_internal(line->C); - PG_RETURN_CSTRING(psprintf("{%s,%s,%s}", astr, bstr, cstr)); + PG_RETURN_CSTRING(psprintf("%c%s%c%s%c%s%c", LDELIM_L, astr, DELIM, bstr, + DELIM, cstr, RDELIM_L)); } /* @@ -978,6 +1019,11 @@ line_recv(PG_FUNCTION_ARGS) line->B = pq_getmsgfloat8(buf); line->C = pq_getmsgfloat8(buf); + if (FPzero(line->A) && FPzero(line->B)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), + errmsg("invalid line specification: A and B cannot both be zero"))); + PG_RETURN_LINE_P(line); } @@ -1003,19 +1049,17 @@ line_send(PG_FUNCTION_ARGS) * Internal form: Ax+By+C=0 *---------------------------------------------------------*/ -/* line_construct_pm() - * point-slope +/* + * Fill already-allocated LINE struct from the point and the slope */ -static LINE * -line_construct_pm(Point *pt, double m) +static inline void +line_construct(LINE *result, Point *pt, float8 m) { - LINE *result = (LINE *) palloc(sizeof(LINE)); - if (m == DBL_MAX) { /* vertical - use "x = C" */ - result->A = -1; - result->B = 0; + result->A = -1.0; + result->B = 0.0; result->C = pt->x; } else @@ -1023,51 +1067,10 @@ line_construct_pm(Point *pt, double m) /* use "mx - y + yinter = 0" */ result->A = m; result->B = -1.0; - result->C = pt->y - m * pt->x; - } - - return result; -} - -/* - * Fill already-allocated LINE struct from two points on the line - */ -static void -line_construct_pts(LINE *line, Point *pt1, Point *pt2) -{ - if (FPeq(pt1->x, pt2->x)) - { /* vertical */ - /* use "x = C" */ - line->A = -1; - line->B = 0; - line->C = pt1->x; -#ifdef GEODEBUG - printf("line_construct_pts- line is vertical\n"); -#endif - } - else if (FPeq(pt1->y, pt2->y)) - { /* horizontal */ - /* use "y = C" */ - line->A = 0; - line->B = -1; - line->C = pt1->y; -#ifdef GEODEBUG - printf("line_construct_pts- line is horizontal\n"); -#endif - } - else - { - /* use "mx - y + yinter = 0" */ - line->A = (pt2->y - pt1->y) / (pt2->x - pt1->x); - line->B = -1.0; - line->C = pt1->y - line->A * pt1->x; + result->C = float8_mi(pt->y, float8_mul(m, pt->x)); /* on some platforms, the preceding expression tends to produce -0 */ - if (line->C == 0.0) - line->C = 0.0; -#ifdef GEODEBUG - printf("line_construct_pts- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n", - DBL_DIG, (pt2->x - pt1->x), DBL_DIG, (pt2->y - pt1->y)); -#endif + if (result->C == 0.0) + result->C = 0.0; } } @@ -1081,7 +1084,13 @@ line_construct_pp(PG_FUNCTION_ARGS) Point *pt2 = PG_GETARG_POINT_P(1); LINE *result = (LINE *) palloc(sizeof(LINE)); - line_construct_pts(result, pt1, pt2); + if (point_eq_point(pt1, pt2)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid line specification: must be two distinct points"))); + + line_construct(result, pt1, point_sl(pt1, pt2)); + PG_RETURN_LINE_P(result); } @@ -1096,9 +1105,7 @@ line_intersect(PG_FUNCTION_ARGS) LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - PG_RETURN_BOOL(!DatumGetBool(DirectFunctionCall2(line_parallel, - LinePGetDatum(l1), - LinePGetDatum(l2)))); + PG_RETURN_BOOL(line_interpt_line(NULL, l1, l2)); } Datum @@ -1107,10 +1114,7 @@ line_parallel(PG_FUNCTION_ARGS) LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - if (FPzero(l1->B)) - PG_RETURN_BOOL(FPzero(l2->B)); - - PG_RETURN_BOOL(FPeq(l2->A, l1->A * (l2->B / l1->B))); + PG_RETURN_BOOL(!line_interpt_line(NULL, l1, l2)); } Datum @@ -1121,10 +1125,15 @@ line_perp(PG_FUNCTION_ARGS) if (FPzero(l1->A)) PG_RETURN_BOOL(FPzero(l2->B)); - else if (FPzero(l1->B)) + if (FPzero(l2->A)) + PG_RETURN_BOOL(FPzero(l1->B)); + if (FPzero(l1->B)) PG_RETURN_BOOL(FPzero(l2->A)); + if (FPzero(l2->B)) + PG_RETURN_BOOL(FPzero(l1->A)); - PG_RETURN_BOOL(FPeq(((l1->A * l2->B) / (l1->B * l2->A)), -1.0)); + PG_RETURN_BOOL(FPeq(float8_div(float8_mul(l1->A, l2->A), + float8_mul(l1->B, l2->B)), -1.0)); } Datum @@ -1143,25 +1152,35 @@ line_horizontal(PG_FUNCTION_ARGS) PG_RETURN_BOOL(FPzero(line->A)); } + +/* + * Check whether the two lines are the same + * + * We consider NaNs values to be equal to each other to let those lines + * to be found. + */ Datum line_eq(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - double k; - - if (!FPzero(l2->A)) - k = l1->A / l2->A; - else if (!FPzero(l2->B)) - k = l1->B / l2->B; - else if (!FPzero(l2->C)) - k = l1->C / l2->C; + float8 ratio; + + if (!FPzero(l2->A) && !isnan(l2->A)) + ratio = float8_div(l1->A, l2->A); + else if (!FPzero(l2->B) && !isnan(l2->B)) + ratio = float8_div(l1->B, l2->B); + else if (!FPzero(l2->C) && !isnan(l2->C)) + ratio = float8_div(l1->C, l2->C); else - k = 1.0; + ratio = 1.0; - PG_RETURN_BOOL(FPeq(l1->A, k * l2->A) && - FPeq(l1->B, k * l2->B) && - FPeq(l1->C, k * l2->C)); + PG_RETURN_BOOL((FPeq(l1->A, float8_mul(ratio, l2->A)) && + FPeq(l1->B, float8_mul(ratio, l2->B)) && + FPeq(l1->C, float8_mul(ratio, l2->C))) || + (float8_eq(l1->A, l2->A) && + float8_eq(l1->B, l2->B) && + float8_eq(l1->C, l2->C))); } @@ -1169,6 +1188,34 @@ line_eq(PG_FUNCTION_ARGS) * Line arithmetic routines. *---------------------------------------------------------*/ +/* + * Return slope of the line + */ +static inline float8 +line_sl(LINE *line) +{ + if (FPzero(line->A)) + return 0.0; + if (FPzero(line->B)) + return DBL_MAX; + return float8_div(line->A, -line->B); +} + + +/* + * Return inverse slope of the line + */ +static inline float8 +line_invsl(LINE *line) +{ + if (FPzero(line->A)) + return DBL_MAX; + if (FPzero(line->B)) + return 0.0; + return float8_div(line->B, line->A); +} + + /* line_distance() * Distance between two lines. */ @@ -1177,18 +1224,21 @@ line_distance(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - float8 result; - Point *tmp; + float8 ratio; - if (!DatumGetBool(DirectFunctionCall2(line_parallel, - LinePGetDatum(l1), - LinePGetDatum(l2)))) + if (line_interpt_line(NULL, l1, l2)) /* intersecting? */ PG_RETURN_FLOAT8(0.0); - if (FPzero(l1->B)) /* vertical? */ - PG_RETURN_FLOAT8(fabs(l1->C - l2->C)); - tmp = point_construct(0.0, l1->C); - result = dist_pl_internal(tmp, l2); - PG_RETURN_FLOAT8(result); + + if (!FPzero(l1->A) && !isnan(l1->A) && !FPzero(l2->A) && !isnan(l2->A)) + ratio = float8_div(l1->A, l2->A); + else if (!FPzero(l1->B) && !isnan(l1->B) && !FPzero(l2->B) && !isnan(l2->B)) + ratio = float8_div(l1->B, l2->B); + else + ratio = 1.0; + + PG_RETURN_FLOAT8(float8_div(fabs(float8_mi(l1->C, + float8_mul(ratio, l2->C))), + HYPOT(l1->A, l1->B))); } /* line_interpt() @@ -1201,9 +1251,9 @@ line_interpt(PG_FUNCTION_ARGS) LINE *l2 = PG_GETARG_LINE_P(1); Point *result; - result = line_interpt_internal(l1, l2); + result = (Point *) palloc(sizeof(Point)); - if (result == NULL) + if (!line_interpt_line(result, l1, l2)) PG_RETURN_NULL(); PG_RETURN_POINT_P(result); } @@ -1211,49 +1261,58 @@ line_interpt(PG_FUNCTION_ARGS) /* * Internal version of line_interpt * - * returns a NULL pointer if no intersection point + * Return whether two lines intersect. If *result is not NULL, it is set to + * the intersection point. + * + * NOTE: If the lines are identical then we will find they are parallel + * and report "no intersection". This is a little weird, but since + * there's no *unique* intersection, maybe it's appropriate behavior. + * + * If the lines have NaN constants, we will return true, and the intersection + * point would have NaN coordinates. We shouldn't return false in this case + * because that would mean the lines are parallel. */ -static Point * -line_interpt_internal(LINE *l1, LINE *l2) +static bool +line_interpt_line(Point *result, LINE *l1, LINE *l2) { - Point *result; - double x, + float8 x, y; - /* - * NOTE: if the lines are identical then we will find they are parallel - * and report "no intersection". This is a little weird, but since - * there's no *unique* intersection, maybe it's appropriate behavior. - */ - if (DatumGetBool(DirectFunctionCall2(line_parallel, - LinePGetDatum(l1), - LinePGetDatum(l2)))) - return NULL; - - if (FPzero(l1->B)) /* l1 vertical? */ + if (!FPzero(l1->B)) { - x = l1->C; - y = (l2->A * x + l2->C); + if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B)))) + return false; + + x = float8_div(float8_mi(float8_mul(l1->B, l2->C), + float8_mul(l2->B, l1->C)), + float8_mi(float8_mul(l1->A, l2->B), + float8_mul(l2->A, l1->B))); + y = float8_div(-float8_pl(float8_mul(l1->A, x), l1->C), l1->B); } - else if (FPzero(l2->B)) /* l2 vertical? */ + else if (!FPzero(l2->B)) { - x = l2->C; - y = (l1->A * x + l1->C); + if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B)))) + return false; + + x = float8_div(float8_mi(float8_mul(l2->B, l1->C), + float8_mul(l1->B, l2->C)), + float8_mi(float8_mul(l2->A, l1->B), + float8_mul(l1->A, l2->B))); + y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B); } else - { - x = (l1->C - l2->C) / (l2->A - l1->A); - y = (l1->A * x + l1->C); - } - result = point_construct(x, y); + return false; -#ifdef GEODEBUG - printf("line_interpt- lines are A=%.*g, B=%.*g, C=%.*g, A=%.*g, B=%.*g, C=%.*g\n", - DBL_DIG, l1->A, DBL_DIG, l1->B, DBL_DIG, l1->C, DBL_DIG, l2->A, DBL_DIG, l2->B, DBL_DIG, l2->C); - printf("line_interpt- lines intersect at (%.*g,%.*g)\n", DBL_DIG, x, DBL_DIG, y); -#endif + /* On some platforms, the preceding expressions tend to produce -0. */ + if (x == 0.0) + x = 0.0; + if (y == 0.0) + y = 0.0; - return result; + if (result != NULL) + point_construct(result, x, y); + + return true; } @@ -1283,7 +1342,7 @@ Datum path_area(PG_FUNCTION_ARGS) { PATH *path = PG_GETARG_PATH_P(0); - double area = 0.0; + float8 area = 0.0; int i, j; @@ -1293,12 +1352,11 @@ path_area(PG_FUNCTION_ARGS) for (i = 0; i < path->npts; i++) { j = (i + 1) % path->npts; - area += path->p[i].x * path->p[j].y; - area -= path->p[i].y * path->p[j].x; + area = float8_pl(area, float8_mul(path->p[i].x, path->p[j].y)); + area = float8_mi(area, float8_mul(path->p[i].y, path->p[j].x)); } - area *= 0.5; - PG_RETURN_FLOAT8(area < 0.0 ? -area : area); + PG_RETURN_FLOAT8(float8_div(fabs(area), 2.0)); } @@ -1562,26 +1620,25 @@ path_inter(PG_FUNCTION_ARGS) LSEG seg1, seg2; - if (p1->npts <= 0 || p2->npts <= 0) - PG_RETURN_BOOL(false); + Assert(p1->npts > 0 && p2->npts > 0); b1.high.x = b1.low.x = p1->p[0].x; b1.high.y = b1.low.y = p1->p[0].y; for (i = 1; i < p1->npts; i++) { - b1.high.x = Max(p1->p[i].x, b1.high.x); - b1.high.y = Max(p1->p[i].y, b1.high.y); - b1.low.x = Min(p1->p[i].x, b1.low.x); - b1.low.y = Min(p1->p[i].y, b1.low.y); + b1.high.x = float8_max(p1->p[i].x, b1.high.x); + b1.high.y = float8_max(p1->p[i].y, b1.high.y); + b1.low.x = float8_min(p1->p[i].x, b1.low.x); + b1.low.y = float8_min(p1->p[i].y, b1.low.y); } b2.high.x = b2.low.x = p2->p[0].x; b2.high.y = b2.low.y = p2->p[0].y; for (i = 1; i < p2->npts; i++) { - b2.high.x = Max(p2->p[i].x, b2.high.x); - b2.high.y = Max(p2->p[i].y, b2.high.y); - b2.low.x = Min(p2->p[i].x, b2.low.x); - b2.low.y = Min(p2->p[i].y, b2.low.y); + b2.high.x = float8_max(p2->p[i].x, b2.high.x); + b2.high.y = float8_max(p2->p[i].y, b2.high.y); + b2.low.x = float8_min(p2->p[i].x, b2.low.x); + b2.low.y = float8_min(p2->p[i].y, b2.low.y); } if (!box_ov(&b1, &b2)) PG_RETURN_BOOL(false); @@ -1615,7 +1672,7 @@ path_inter(PG_FUNCTION_ARGS) statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]); statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]); - if (lseg_intersect_internal(&seg1, &seg2)) + if (lseg_interpt_lseg(NULL, &seg1, &seg2)) PG_RETURN_BOOL(true); } } @@ -1670,10 +1727,8 @@ path_distance(PG_FUNCTION_ARGS) statlseg_construct(&seg1, &p1->p[iprev], &p1->p[i]); statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]); - tmp = DatumGetFloat8(DirectFunctionCall2(lseg_distance, - LsegPGetDatum(&seg1), - LsegPGetDatum(&seg2))); - if (!have_min || tmp < min) + tmp = lseg_closept_lseg(NULL, &seg1, &seg2); + if (!have_min || float8_lt(tmp, min)) { min = tmp; have_min = true; @@ -1712,7 +1767,7 @@ path_length(PG_FUNCTION_ARGS) iprev = path->npts - 1; /* include the closure segment */ } - result += point_dt(&path->p[iprev], &path->p[i]); + result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i])); } PG_RETURN_FLOAT8(result); @@ -1780,30 +1835,14 @@ point_send(PG_FUNCTION_ARGS) } -static Point * -point_construct(double x, double y) +/* + * Initialize a point + */ +static inline void +point_construct(Point *result, float8 x, float8 y) { - Point *result = (Point *) palloc(sizeof(Point)); - result->x = x; result->y = y; - return result; -} - - -static Point * -point_copy(Point *pt) -{ - Point *result; - - if (!PointerIsValid(pt)) - return NULL; - - result = (Point *) palloc(sizeof(Point)); - - result->x = pt->x; - result->y = pt->y; - return result; } @@ -1876,7 +1915,7 @@ point_eq(PG_FUNCTION_ARGS) Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y)); + PG_RETURN_BOOL(point_eq_point(pt1, pt2)); } Datum @@ -1885,9 +1924,24 @@ point_ne(PG_FUNCTION_ARGS) Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(FPne(pt1->x, pt2->x) || FPne(pt1->y, pt2->y)); + PG_RETURN_BOOL(!point_eq_point(pt1, pt2)); +} + + +/* + * Check whether the two points are the same + * + * We consider NaNs coordinates to be equal to each other to let those points + * to be found. + */ +static inline bool +point_eq_point(Point *pt1, Point *pt2) +{ + return ((FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y)) || + (float8_eq(pt1->x, pt2->x) && float8_eq(pt1->y, pt2->y))); } + /*---------------------------------------------------------- * "Arithmetic" operators on points. *---------------------------------------------------------*/ @@ -1898,17 +1952,13 @@ point_distance(PG_FUNCTION_ARGS) Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_FLOAT8(HYPOT(pt1->x - pt2->x, pt1->y - pt2->y)); + PG_RETURN_FLOAT8(point_dt(pt1, pt2)); } -double +static inline float8 point_dt(Point *pt1, Point *pt2) { -#ifdef GEODEBUG - printf("point_dt- segment (%f,%f),(%f,%f) length is %f\n", - pt1->x, pt1->y, pt2->x, pt2->y, HYPOT(pt1->x - pt2->x, pt1->y - pt2->y)); -#endif - return HYPOT(pt1->x - pt2->x, pt1->y - pt2->y); + return HYPOT(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y)); } Datum @@ -1921,12 +1971,35 @@ point_slope(PG_FUNCTION_ARGS) } -double +/* + * Return slope of two points + * + * Note that this function returns DBL_MAX when the points are the same. + */ +static inline float8 point_sl(Point *pt1, Point *pt2) { - return (FPeq(pt1->x, pt2->x) - ? (double) DBL_MAX - : (pt1->y - pt2->y) / (pt1->x - pt2->x)); + if (FPeq(pt1->x, pt2->x)) + return DBL_MAX; + if (FPeq(pt1->y, pt2->y)) + return 0.0; + return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x)); +} + + +/* + * Return inverse slope of two points + * + * Note that this function returns 0.0 when the points are the same. + */ +static inline float8 +point_invsl(Point *pt1, Point *pt2) +{ + if (FPeq(pt1->x, pt2->x)) + return 0.0; + if (FPeq(pt1->y, pt2->y)) + return DBL_MAX; + return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y)); } @@ -1952,7 +2025,7 @@ lseg_in(PG_FUNCTION_ARGS) LSEG *lseg = (LSEG *) palloc(sizeof(LSEG)); bool isopen; - path_decode(str, true, 2, &(lseg->p[0]), &isopen, NULL, "lseg", str); + path_decode(str, true, 2, &lseg->p[0], &isopen, NULL, "lseg", str); PG_RETURN_LSEG_P(lseg); } @@ -1962,7 +2035,7 @@ lseg_out(PG_FUNCTION_ARGS) { LSEG *ls = PG_GETARG_LSEG_P(0); - PG_RETURN_CSTRING(path_encode(PATH_OPEN, 2, (Point *) &(ls->p[0]))); + PG_RETURN_CSTRING(path_encode(PATH_OPEN, 2, &ls->p[0])); } /* @@ -2012,16 +2085,13 @@ lseg_construct(PG_FUNCTION_ARGS) Point *pt2 = PG_GETARG_POINT_P(1); LSEG *result = (LSEG *) palloc(sizeof(LSEG)); - result->p[0].x = pt1->x; - result->p[0].y = pt1->y; - result->p[1].x = pt2->x; - result->p[1].y = pt2->y; + statlseg_construct(result, pt1, pt2); PG_RETURN_LSEG_P(result); } /* like lseg_construct, but assume space already allocated */ -static void +static inline void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2) { lseg->p[0].x = pt1->x; @@ -2030,6 +2100,27 @@ statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2) lseg->p[1].y = pt2->y; } + +/* + * Return slope of the line segment + */ +static inline float8 +lseg_sl(LSEG *lseg) +{ + return point_sl(&lseg->p[0], &lseg->p[1]); +} + + +/* + * Return inverse slope of the line segment + */ +static inline float8 +lseg_invsl(LSEG *lseg) +{ + return point_invsl(&lseg->p[0], &lseg->p[1]); +} + + Datum lseg_length(PG_FUNCTION_ARGS) { @@ -2052,25 +2143,9 @@ lseg_intersect(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(lseg_intersect_internal(l1, l2)); + PG_RETURN_BOOL(lseg_interpt_lseg(NULL, l1, l2)); } -static bool -lseg_intersect_internal(LSEG *l1, LSEG *l2) -{ - LINE ln; - Point *interpt; - bool retval; - - line_construct_pts(&ln, &l2->p[0], &l2->p[1]); - interpt = interpt_sl(l1, &ln); - - if (interpt != NULL && on_ps_internal(interpt, l2)) - retval = true; /* interpt on l1 and l2 */ - else - retval = false; - return retval; -} Datum lseg_parallel(PG_FUNCTION_ARGS) @@ -2078,39 +2153,19 @@ lseg_parallel(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPeq(point_sl(&l1->p[0], &l1->p[1]), - point_sl(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(FPeq(lseg_sl(l1), lseg_sl(l2))); } -/* lseg_perp() +/* * Determine if two line segments are perpendicular. - * - * This code did not get the correct answer for - * '((0,0),(0,1))'::lseg ?-| '((0,0),(1,0))'::lseg - * So, modified it to check explicitly for slope of vertical line - * returned by point_sl() and the results seem better. - * - thomas 1998-01-31 */ Datum lseg_perp(PG_FUNCTION_ARGS) { LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - double m1, - m2; - - m1 = point_sl(&(l1->p[0]), &(l1->p[1])); - m2 = point_sl(&(l2->p[0]), &(l2->p[1])); - -#ifdef GEODEBUG - printf("lseg_perp- slopes are %g and %g\n", m1, m2); -#endif - if (FPzero(m1)) - PG_RETURN_BOOL(FPeq(m2, DBL_MAX)); - else if (FPzero(m2)) - PG_RETURN_BOOL(FPeq(m1, DBL_MAX)); - PG_RETURN_BOOL(FPeq(m1 / m2, -1.0)); + PG_RETURN_BOOL(FPeq(lseg_sl(l1), lseg_invsl(l2))); } Datum @@ -2136,10 +2191,8 @@ lseg_eq(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPeq(l1->p[0].x, l2->p[0].x) && - FPeq(l1->p[0].y, l2->p[0].y) && - FPeq(l1->p[1].x, l2->p[1].x) && - FPeq(l1->p[1].y, l2->p[1].y)); + PG_RETURN_BOOL(point_eq_point(&l1->p[0], &l2->p[0]) && + point_eq_point(&l1->p[1], &l2->p[1])); } Datum @@ -2148,10 +2201,8 @@ lseg_ne(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(!FPeq(l1->p[0].x, l2->p[0].x) || - !FPeq(l1->p[0].y, l2->p[0].y) || - !FPeq(l1->p[1].x, l2->p[1].x) || - !FPeq(l1->p[1].y, l2->p[1].y)); + PG_RETURN_BOOL(!point_eq_point(&l1->p[0], &l2->p[0]) || + !point_eq_point(&l1->p[1], &l2->p[1])); } Datum @@ -2210,33 +2261,7 @@ lseg_distance(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_FLOAT8(lseg_dt(l1, l2)); -} - -/* lseg_dt() - * Distance between two line segments. - * Must check both sets of endpoints to ensure minimum distance is found. - * - thomas 1998-02-01 - */ -static double -lseg_dt(LSEG *l1, LSEG *l2) -{ - double result, - d; - - if (lseg_intersect_internal(l1, l2)) - return 0.0; - - d = dist_ps_internal(&l1->p[0], l2); - result = d; - d = dist_ps_internal(&l1->p[1], l2); - result = Min(result, d); - d = dist_ps_internal(&l2->p[0], l1); - result = Min(result, d); - d = dist_ps_internal(&l2->p[1], l1); - result = Min(result, d); - - return result; + PG_RETURN_FLOAT8(lseg_closept_lseg(NULL, l1, l2)); } @@ -2248,63 +2273,43 @@ lseg_center(PG_FUNCTION_ARGS) result = (Point *) palloc(sizeof(Point)); - result->x = (lseg->p[0].x + lseg->p[1].x) / 2.0; - result->y = (lseg->p[0].y + lseg->p[1].y) / 2.0; + result->x = float8_div(float8_pl(lseg->p[0].x, lseg->p[1].x), 2.0); + result->y = float8_div(float8_pl(lseg->p[0].y, lseg->p[1].y), 2.0); PG_RETURN_POINT_P(result); } -static Point * -lseg_interpt_internal(LSEG *l1, LSEG *l2) + +/* + * Return whether the two segments intersect. If *result is not NULL, + * it is set to the intersection point. + * + * This function is almost perfectly symmetric, even though it doesn't look + * like it. See lseg_interpt_line() for the other half of it. + */ +static bool +lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2) { - Point *result; - LINE tmp1, - tmp2; + Point interpt; + LINE tmp; - /* - * Find the intersection of the appropriate lines, if any. - */ - line_construct_pts(&tmp1, &l1->p[0], &l1->p[1]); - line_construct_pts(&tmp2, &l2->p[0], &l2->p[1]); - result = line_interpt_internal(&tmp1, &tmp2); - if (!PointerIsValid(result)) - return NULL; + line_construct(&tmp, &l2->p[0], lseg_sl(l2)); + if (!lseg_interpt_line(&interpt, l1, &tmp)) + return false; /* - * If the line intersection point isn't within l1 (or equivalently l2), - * there is no valid segment intersection point at all. + * If the line intersection point isn't within l2, there is no valid + * segment intersection point at all. */ - if (!on_ps_internal(result, l1) || - !on_ps_internal(result, l2)) - { - pfree(result); - return NULL; - } + if (!lseg_contain_point(l2, &interpt)) + return false; - /* - * If there is an intersection, then check explicitly for matching - * endpoints since there may be rounding effects with annoying lsb - * residue. - tgl 1997-07-09 - */ - if ((FPeq(l1->p[0].x, l2->p[0].x) && FPeq(l1->p[0].y, l2->p[0].y)) || - (FPeq(l1->p[0].x, l2->p[1].x) && FPeq(l1->p[0].y, l2->p[1].y))) - { - result->x = l1->p[0].x; - result->y = l1->p[0].y; - } - else if ((FPeq(l1->p[1].x, l2->p[0].x) && FPeq(l1->p[1].y, l2->p[0].y)) || - (FPeq(l1->p[1].x, l2->p[1].x) && FPeq(l1->p[1].y, l2->p[1].y))) - { - result->x = l1->p[1].x; - result->y = l1->p[1].y; - } + if (result != NULL) + *result = interpt; - return result; + return true; } -/* lseg_interpt - - * Find the intersection point of two segments (if any). - */ Datum lseg_interpt(PG_FUNCTION_ARGS) { @@ -2312,10 +2317,10 @@ lseg_interpt(PG_FUNCTION_ARGS) LSEG *l2 = PG_GETARG_LSEG_P(1); Point *result; - result = lseg_interpt_internal(l1, l2); - if (!PointerIsValid(result)) - PG_RETURN_NULL(); + result = (Point *) palloc(sizeof(Point)); + if (!lseg_interpt_lseg(result, l1, l2)) + PG_RETURN_NULL(); PG_RETURN_POINT_P(result); } @@ -2340,14 +2345,19 @@ dist_pl(PG_FUNCTION_ARGS) Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); - PG_RETURN_FLOAT8(dist_pl_internal(pt, line)); + PG_RETURN_FLOAT8(line_closept_point(NULL, line, pt)); } -static double -dist_pl_internal(Point *pt, LINE *line) +/* + * Distance from a line to a point + */ +Datum +dist_lp(PG_FUNCTION_ARGS) { - return fabs((line->A * pt->x + line->B * pt->y + line->C) / - HYPOT(line->A, line->B)); + LINE *line = PG_GETARG_LINE_P(0); + Point *pt = PG_GETARG_POINT_P(1); + + PG_RETURN_FLOAT8(line_closept_point(NULL, line, pt)); } /* @@ -2359,117 +2369,83 @@ dist_ps(PG_FUNCTION_ARGS) Point *pt = PG_GETARG_POINT_P(0); LSEG *lseg = PG_GETARG_LSEG_P(1); - PG_RETURN_FLOAT8(dist_ps_internal(pt, lseg)); + PG_RETURN_FLOAT8(lseg_closept_point(NULL, lseg, pt)); } -static double -dist_ps_internal(Point *pt, LSEG *lseg) +/* + * Distance from a lseg to a point + */ +Datum +dist_sp(PG_FUNCTION_ARGS) { - double m; /* slope of perp. */ - LINE *ln; - double result, - tmpdist; - Point *ip; - - /* - * Construct a line perpendicular to the input segment and through the - * input point - */ - if (lseg->p[1].x == lseg->p[0].x) - m = 0; - else if (lseg->p[1].y == lseg->p[0].y) - m = (double) DBL_MAX; /* slope is infinite */ - else - m = (lseg->p[0].x - lseg->p[1].x) / (lseg->p[1].y - lseg->p[0].y); - ln = line_construct_pm(pt, m); - -#ifdef GEODEBUG - printf("dist_ps- line is A=%g B=%g C=%g from (point) slope (%f,%f) %g\n", - ln->A, ln->B, ln->C, pt->x, pt->y, m); -#endif - - /* - * Calculate distance to the line segment or to the nearest endpoint of - * the segment. - */ - - /* intersection is on the line segment? */ - if ((ip = interpt_sl(lseg, ln)) != NULL) - { - /* yes, so use distance to the intersection point */ - result = point_dt(pt, ip); -#ifdef GEODEBUG - printf("dist_ps- distance is %f to intersection point is (%f,%f)\n", - result, ip->x, ip->y); -#endif - } - else - { - /* no, so use distance to the nearer endpoint */ - result = point_dt(pt, &lseg->p[0]); - tmpdist = point_dt(pt, &lseg->p[1]); - if (tmpdist < result) - result = tmpdist; - } + LSEG *lseg = PG_GETARG_LSEG_P(0); + Point *pt = PG_GETARG_POINT_P(1); - return result; + PG_RETURN_FLOAT8(lseg_closept_point(NULL, lseg, pt)); } -/* - * Distance from a point to a path - */ -Datum -dist_ppath(PG_FUNCTION_ARGS) +static float8 +dist_ppath_internal(Point *pt, PATH *path) { - Point *pt = PG_GETARG_POINT_P(0); - PATH *path = PG_GETARG_PATH_P(1); float8 result = 0.0; /* keep compiler quiet */ bool have_min = false; float8 tmp; int i; LSEG lseg; - switch (path->npts) - { - case 0: - /* no points in path? then result is undefined... */ - PG_RETURN_NULL(); - case 1: - /* one point in path? then get distance between two points... */ - result = point_dt(pt, &path->p[0]); - break; - default: - /* make sure the path makes sense... */ - Assert(path->npts > 1); + Assert(path->npts > 0); - /* - * the distance from a point to a path is the smallest distance - * from the point to any of its constituent segments. - */ - for (i = 0; i < path->npts; i++) - { - int iprev; - - if (i > 0) - iprev = i - 1; - else - { - if (!path->closed) - continue; - iprev = path->npts - 1; /* include the closure segment */ - } - - statlseg_construct(&lseg, &path->p[iprev], &path->p[i]); - tmp = dist_ps_internal(pt, &lseg); - if (!have_min || tmp < result) - { - result = tmp; - have_min = true; - } - } - break; + /* + * The distance from a point to a path is the smallest distance from the + * point to any of its constituent segments. + */ + for (i = 0; i < path->npts; i++) + { + int iprev; + + if (i > 0) + iprev = i - 1; + else + { + if (!path->closed) + continue; + iprev = path->npts - 1; /* Include the closure segment */ + } + + statlseg_construct(&lseg, &path->p[iprev], &path->p[i]); + tmp = lseg_closept_point(NULL, &lseg, pt); + if (!have_min || float8_lt(tmp, result)) + { + result = tmp; + have_min = true; + } } - PG_RETURN_FLOAT8(result); + + return result; +} + +/* + * Distance from a point to a path + */ +Datum +dist_ppath(PG_FUNCTION_ARGS) +{ + Point *pt = PG_GETARG_POINT_P(0); + PATH *path = PG_GETARG_PATH_P(1); + + PG_RETURN_FLOAT8(dist_ppath_internal(pt, path)); +} + +/* + * Distance from a path to a point + */ +Datum +dist_pathp(PG_FUNCTION_ARGS) +{ + PATH *path = PG_GETARG_PATH_P(0); + Point *pt = PG_GETARG_POINT_P(1); + + PG_RETURN_FLOAT8(dist_ppath_internal(pt, path)); } /* @@ -2480,15 +2456,20 @@ dist_pb(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); BOX *box = PG_GETARG_BOX_P(1); - float8 result; - Point *near; - near = DatumGetPointP(DirectFunctionCall2(close_pb, - PointPGetDatum(pt), - BoxPGetDatum(box))); - result = point_dt(near, pt); + PG_RETURN_FLOAT8(box_closept_point(NULL, box, pt)); +} - PG_RETURN_FLOAT8(result); +/* + * Distance from a box to a point + */ +Datum +dist_bp(PG_FUNCTION_ARGS) +{ + BOX *box = PG_GETARG_BOX_P(0); + Point *pt = PG_GETARG_POINT_P(1); + + PG_RETURN_FLOAT8(box_closept_point(NULL, box, pt)); } /* @@ -2499,21 +2480,20 @@ dist_sl(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); LINE *line = PG_GETARG_LINE_P(1); - float8 result, - d2; - if (has_interpt_sl(lseg, line)) - result = 0.0; - else - { - result = dist_pl_internal(&lseg->p[0], line); - d2 = dist_pl_internal(&lseg->p[1], line); - /* XXX shouldn't we take the min not max? */ - if (d2 > result) - result = d2; - } + PG_RETURN_FLOAT8(lseg_closept_line(NULL, lseg, line)); +} - PG_RETURN_FLOAT8(result); +/* + * Distance from a line to a lseg + */ +Datum +dist_ls(PG_FUNCTION_ARGS) +{ + LINE *line = PG_GETARG_LINE_P(0); + LSEG *lseg = PG_GETARG_LSEG_P(1); + + PG_RETURN_FLOAT8(lseg_closept_line(NULL, lseg, line)); } /* @@ -2524,17 +2504,20 @@ dist_sb(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); BOX *box = PG_GETARG_BOX_P(1); - Point *tmp; - Datum result; - tmp = DatumGetPointP(DirectFunctionCall2(close_sb, - LsegPGetDatum(lseg), - BoxPGetDatum(box))); - result = DirectFunctionCall2(dist_pb, - PointPGetDatum(tmp), - BoxPGetDatum(box)); + PG_RETURN_FLOAT8(box_closept_lseg(NULL, box, lseg)); +} - PG_RETURN_DATUM(result); +/* + * Distance from a box to a lseg + */ +Datum +dist_bs(PG_FUNCTION_ARGS) +{ + BOX *box = PG_GETARG_BOX_P(0); + LSEG *lseg = PG_GETARG_LSEG_P(1); + + PG_RETURN_FLOAT8(box_closept_lseg(NULL, box, lseg)); } /* @@ -2556,6 +2539,39 @@ dist_lb(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } +/* + * Distance from a box to a line + */ +Datum +dist_bl(PG_FUNCTION_ARGS) +{ +#ifdef NOT_USED + BOX *box = PG_GETARG_BOX_P(0); + LINE *line = PG_GETARG_LINE_P(1); +#endif + + /* need to think about this one for a while */ + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function \"dist_bl\" not implemented"))); + + PG_RETURN_NULL(); +} + +static float8 +dist_cpoly_internal(CIRCLE *circle, POLYGON *poly) +{ + float8 result; + + /* calculate distance to center, and subtract radius */ + result = float8_mi(dist_ppoly_internal(&circle->center, poly), + circle->radius); + if (result < 0.0) + result = 0.0; + + return result; +} + /* * Distance from a circle to a polygon */ @@ -2564,16 +2580,20 @@ dist_cpoly(PG_FUNCTION_ARGS) { CIRCLE *circle = PG_GETARG_CIRCLE_P(0); POLYGON *poly = PG_GETARG_POLYGON_P(1); - float8 result; - /* calculate distance to center, and subtract radius */ - result = dist_ppoly_internal(&circle->center, poly); + PG_RETURN_FLOAT8(dist_cpoly_internal(circle, poly)); +} - result -= circle->radius; - if (result < 0) - result = 0; +/* + * Distance from a polygon to a circle + */ +Datum +dist_polyc(PG_FUNCTION_ARGS) +{ + POLYGON *poly = PG_GETARG_POLYGON_P(0); + CIRCLE *circle = PG_GETARG_CIRCLE_P(1); - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(dist_cpoly_internal(circle, poly)); } /* @@ -2584,11 +2604,8 @@ dist_ppoly(PG_FUNCTION_ARGS) { Point *point = PG_GETARG_POINT_P(0); POLYGON *poly = PG_GETARG_POLYGON_P(1); - float8 result; - result = dist_ppoly_internal(point, poly); - - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(dist_ppoly_internal(point, poly)); } Datum @@ -2596,14 +2613,11 @@ dist_polyp(PG_FUNCTION_ARGS) { POLYGON *poly = PG_GETARG_POLYGON_P(0); Point *point = PG_GETARG_POINT_P(1); - float8 result; - result = dist_ppoly_internal(point, poly); - - PG_RETURN_FLOAT8(result); + PG_RETURN_FLOAT8(dist_ppoly_internal(point, poly)); } -static double +static float8 dist_ppoly_internal(Point *pt, POLYGON *poly) { float8 result; @@ -2612,35 +2626,24 @@ dist_ppoly_internal(Point *pt, POLYGON *poly) LSEG seg; if (point_inside(pt, poly->npts, poly->p) != 0) - { -#ifdef GEODEBUG - printf("dist_ppoly_internal- point inside of polygon\n"); -#endif return 0.0; - } /* initialize distance with segment between first and last points */ seg.p[0].x = poly->p[0].x; seg.p[0].y = poly->p[0].y; seg.p[1].x = poly->p[poly->npts - 1].x; seg.p[1].y = poly->p[poly->npts - 1].y; - result = dist_ps_internal(pt, &seg); -#ifdef GEODEBUG - printf("dist_ppoly_internal- segment 0/n distance is %f\n", result); -#endif + result = lseg_closept_point(NULL, &seg, pt); /* check distances for other segments */ - for (i = 0; (i < poly->npts - 1); i++) + for (i = 0; i < poly->npts - 1; i++) { seg.p[0].x = poly->p[i].x; seg.p[0].y = poly->p[i].y; seg.p[1].x = poly->p[i + 1].x; seg.p[1].y = poly->p[i + 1].y; - d = dist_ps_internal(pt, &seg); -#ifdef GEODEBUG - printf("dist_ppoly_internal- segment %d distance is %f\n", (i + 1), d); -#endif - if (d < result) + d = lseg_closept_point(NULL, &seg, pt); + if (float8_lt(d, result)) result = d; } @@ -2655,49 +2658,47 @@ dist_ppoly_internal(Point *pt, POLYGON *poly) * lines and boxes, since there are typically two. *-------------------------------------------------------------------*/ -/* Get intersection point of lseg and line; returns NULL if no intersection */ -static Point * -interpt_sl(LSEG *lseg, LINE *line) +/* + * Return whether the line segment intersect with the line. If *result is not + * NULL, it is set to the intersection point. + */ +static bool +lseg_interpt_line(Point *result, LSEG *lseg, LINE *line) { + Point interpt; LINE tmp; - Point *p; - - line_construct_pts(&tmp, &lseg->p[0], &lseg->p[1]); - p = line_interpt_internal(&tmp, line); -#ifdef GEODEBUG - printf("interpt_sl- segment is (%.*g %.*g) (%.*g %.*g)\n", - DBL_DIG, lseg->p[0].x, DBL_DIG, lseg->p[0].y, DBL_DIG, lseg->p[1].x, DBL_DIG, lseg->p[1].y); - printf("interpt_sl- segment becomes line A=%.*g B=%.*g C=%.*g\n", - DBL_DIG, tmp.A, DBL_DIG, tmp.B, DBL_DIG, tmp.C); -#endif - if (PointerIsValid(p)) + + /* + * First, we promote the line segment to a line, because we know how to + * find the intersection point of two lines. If they don't have an + * intersection point, we are done. + */ + line_construct(&tmp, &lseg->p[0], lseg_sl(lseg)); + if (!line_interpt_line(&interpt, &tmp, line)) + return false; + + /* + * Then, we check whether the intersection point is actually on the line + * segment. + */ + if (!lseg_contain_point(lseg, &interpt)) + return false; + if (result != NULL) { -#ifdef GEODEBUG - printf("interpt_sl- intersection point is (%.*g %.*g)\n", DBL_DIG, p->x, DBL_DIG, p->y); -#endif - if (on_ps_internal(p, lseg)) - { -#ifdef GEODEBUG - printf("interpt_sl- intersection point is on segment\n"); -#endif - } + /* + * If there is an intersection, then check explicitly for matching + * endpoints since there may be rounding effects with annoying LSB + * residue. + */ + if (point_eq_point(&lseg->p[0], &interpt)) + *result = lseg->p[0]; + else if (point_eq_point(&lseg->p[1], &interpt)) + *result = lseg->p[1]; else - p = NULL; + *result = interpt; } - return p; -} - -/* variant: just indicate if intersection point exists */ -static bool -has_interpt_sl(LSEG *lseg, LINE *line) -{ - Point *tmp; - - tmp = interpt_sl(lseg, line); - if (tmp) - return true; - return false; + return true; } /*--------------------------------------------------------------------- @@ -2705,277 +2706,236 @@ has_interpt_sl(LSEG *lseg, LINE *line) * Point of closest proximity between objects. *-------------------------------------------------------------------*/ -/* close_pl - - * The intersection point of a perpendicular of the line - * through the point. +/* + * If *result is not NULL, it is set to the intersection point of a + * perpendicular of the line through the point. Returns the distance + * of those two points. */ +static float8 +line_closept_point(Point *result, LINE *line, Point *point) +{ + Point closept; + LINE tmp; + + /* + * We drop a perpendicular to find the intersection point. Ordinarily we + * should always find it, but that can fail in the presence of NaN + * coordinates, and perhaps even from simple roundoff issues. + */ + line_construct(&tmp, point, line_invsl(line)); + if (!line_interpt_line(&closept, &tmp, line)) + { + if (result != NULL) + *result = *point; + + return get_float8_nan(); + } + + if (result != NULL) + *result = closept; + + return point_dt(&closept, point); +} + Datum close_pl(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); Point *result; - LINE *tmp; - double invm; result = (Point *) palloc(sizeof(Point)); - if (FPzero(line->B)) /* vertical? */ - { - result->x = line->C; - result->y = pt->y; - PG_RETURN_POINT_P(result); - } - if (FPzero(line->A)) /* horizontal? */ - { - result->x = pt->x; - result->y = line->C; - PG_RETURN_POINT_P(result); - } - /* drop a perpendicular and find the intersection point */ + if (isnan(line_closept_point(result, line, pt))) + PG_RETURN_NULL(); - /* invert and flip the sign on the slope to get a perpendicular */ - invm = line->B / line->A; - tmp = line_construct_pm(pt, invm); - result = line_interpt_internal(tmp, line); - Assert(result != NULL); PG_RETURN_POINT_P(result); } -/* close_ps() +/* * Closest point on line segment to specified point. - * Take the closest endpoint if the point is left, right, - * above, or below the segment, otherwise find the intersection - * point of the segment and its perpendicular through the point. * - * Some tricky code here, relying on boolean expressions - * evaluating to only zero or one to use as an array index. - * bug fixes by gthaker@atl.lmco.com; May 1, 1998 + * If *result is not NULL, set it to the closest point on the line segment + * to the point. Returns the distance of the two points. */ -Datum -close_ps(PG_FUNCTION_ARGS) +static float8 +lseg_closept_point(Point *result, LSEG *lseg, Point *pt) { - Point *pt = PG_GETARG_POINT_P(0); - LSEG *lseg = PG_GETARG_LSEG_P(1); - Point *result = NULL; - LINE *tmp; - double invm; - int xh, - yh; - -#ifdef GEODEBUG - printf("close_sp:pt->x %f pt->y %f\nlseg(0).x %f lseg(0).y %f lseg(1).x %f lseg(1).y %f\n", - pt->x, pt->y, lseg->p[0].x, lseg->p[0].y, - lseg->p[1].x, lseg->p[1].y); -#endif - - /* xh (or yh) is the index of upper x( or y) end point of lseg */ - /* !xh (or !yh) is the index of lower x( or y) end point of lseg */ - xh = lseg->p[0].x < lseg->p[1].x; - yh = lseg->p[0].y < lseg->p[1].y; - - if (FPeq(lseg->p[0].x, lseg->p[1].x)) /* vertical? */ - { -#ifdef GEODEBUG - printf("close_ps- segment is vertical\n"); -#endif - /* first check if point is below or above the entire lseg. */ - if (pt->y < lseg->p[!yh].y) - result = point_copy(&lseg->p[!yh]); /* below the lseg */ - else if (pt->y > lseg->p[yh].y) - result = point_copy(&lseg->p[yh]); /* above the lseg */ - if (result != NULL) - PG_RETURN_POINT_P(result); - - /* point lines along (to left or right) of the vertical lseg. */ - - result = (Point *) palloc(sizeof(Point)); - result->x = lseg->p[0].x; - result->y = pt->y; - PG_RETURN_POINT_P(result); - } - else if (FPeq(lseg->p[0].y, lseg->p[1].y)) /* horizontal? */ - { -#ifdef GEODEBUG - printf("close_ps- segment is horizontal\n"); -#endif - /* first check if point is left or right of the entire lseg. */ - if (pt->x < lseg->p[!xh].x) - result = point_copy(&lseg->p[!xh]); /* left of the lseg */ - else if (pt->x > lseg->p[xh].x) - result = point_copy(&lseg->p[xh]); /* right of the lseg */ - if (result != NULL) - PG_RETURN_POINT_P(result); - - /* point lines along (at top or below) the horiz. lseg. */ - result = (Point *) palloc(sizeof(Point)); - result->x = pt->x; - result->y = lseg->p[0].y; - PG_RETURN_POINT_P(result); - } + Point closept; + LINE tmp; /* - * vert. and horiz. cases are down, now check if the closest point is one - * of the end points or someplace on the lseg. + * To find the closest point, we draw a perpendicular line from the point + * to the line segment. */ + line_construct(&tmp, pt, point_invsl(&lseg->p[0], &lseg->p[1])); + lseg_closept_line(&closept, lseg, &tmp); - invm = -1.0 / point_sl(&(lseg->p[0]), &(lseg->p[1])); - tmp = line_construct_pm(&lseg->p[!yh], invm); /* lower edge of the - * "band" */ - if (pt->y < (tmp->A * pt->x + tmp->C)) - { /* we are below the lower edge */ - result = point_copy(&lseg->p[!yh]); /* below the lseg, take lower end - * pt */ -#ifdef GEODEBUG - printf("close_ps below: tmp A %f B %f C %f\n", - tmp->A, tmp->B, tmp->C); -#endif - PG_RETURN_POINT_P(result); - } - tmp = line_construct_pm(&lseg->p[yh], invm); /* upper edge of the - * "band" */ - if (pt->y > (tmp->A * pt->x + tmp->C)) - { /* we are below the lower edge */ - result = point_copy(&lseg->p[yh]); /* above the lseg, take higher end - * pt */ -#ifdef GEODEBUG - printf("close_ps above: tmp A %f B %f C %f\n", - tmp->A, tmp->B, tmp->C); -#endif - PG_RETURN_POINT_P(result); - } + if (result != NULL) + *result = closept; - /* - * at this point the "normal" from point will hit lseg. The closest point - * will be somewhere on the lseg - */ - tmp = line_construct_pm(pt, invm); -#ifdef GEODEBUG - printf("close_ps- tmp A %f B %f C %f\n", - tmp->A, tmp->B, tmp->C); -#endif - result = interpt_sl(lseg, tmp); + return point_dt(&closept, pt); +} - /* - * ordinarily we should always find an intersection point, but that could - * fail in the presence of NaN coordinates, and perhaps even from simple - * roundoff issues. Return a SQL NULL if so. - */ - if (result == NULL) +Datum +close_ps(PG_FUNCTION_ARGS) +{ + Point *pt = PG_GETARG_POINT_P(0); + LSEG *lseg = PG_GETARG_LSEG_P(1); + Point *result; + + result = (Point *) palloc(sizeof(Point)); + + if (isnan(lseg_closept_point(result, lseg, pt))) PG_RETURN_NULL(); -#ifdef GEODEBUG - printf("close_ps- result.x %f result.y %f\n", result->x, result->y); -#endif PG_RETURN_POINT_P(result); } -/* close_lseg() - * Closest point to l1 on l2. +/* + * Closest point on line segment to line segment */ -Datum -close_lseg(PG_FUNCTION_ARGS) +static float8 +lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg) { - LSEG *l1 = PG_GETARG_LSEG_P(0); - LSEG *l2 = PG_GETARG_LSEG_P(1); - Point *result = NULL; Point point; - double dist; - double d; + float8 dist, + d; - d = dist_ps_internal(&l1->p[0], l2); - dist = d; - memcpy(&point, &l1->p[0], sizeof(Point)); + /* First, we handle the case when the line segments are intersecting. */ + if (lseg_interpt_lseg(result, on_lseg, to_lseg)) + return 0.0; - if ((d = dist_ps_internal(&l1->p[1], l2)) < dist) + /* + * Then, we find the closest points from the endpoints of the second line + * segment, and keep the closest one. + */ + dist = lseg_closept_point(result, on_lseg, &to_lseg->p[0]); + d = lseg_closept_point(&point, on_lseg, &to_lseg->p[1]); + if (float8_lt(d, dist)) { dist = d; - memcpy(&point, &l1->p[1], sizeof(Point)); + if (result != NULL) + *result = point; } - if (dist_ps_internal(&l2->p[0], l1) < dist) + /* The closest point can still be one of the endpoints, so we test them. */ + d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[0]); + if (float8_lt(d, dist)) { - result = DatumGetPointP(DirectFunctionCall2(close_ps, - PointPGetDatum(&l2->p[0]), - LsegPGetDatum(l1))); - memcpy(&point, result, sizeof(Point)); - result = DatumGetPointP(DirectFunctionCall2(close_ps, - PointPGetDatum(&point), - LsegPGetDatum(l2))); + dist = d; + if (result != NULL) + *result = on_lseg->p[0]; } - - if (dist_ps_internal(&l2->p[1], l1) < dist) + d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[1]); + if (float8_lt(d, dist)) { - result = DatumGetPointP(DirectFunctionCall2(close_ps, - PointPGetDatum(&l2->p[1]), - LsegPGetDatum(l1))); - memcpy(&point, result, sizeof(Point)); - result = DatumGetPointP(DirectFunctionCall2(close_ps, - PointPGetDatum(&point), - LsegPGetDatum(l2))); + dist = d; + if (result != NULL) + *result = on_lseg->p[1]; } - if (result == NULL) - result = point_copy(&point); + return dist; +} + +Datum +close_lseg(PG_FUNCTION_ARGS) +{ + LSEG *l1 = PG_GETARG_LSEG_P(0); + LSEG *l2 = PG_GETARG_LSEG_P(1); + Point *result; + + if (lseg_sl(l1) == lseg_sl(l2)) + PG_RETURN_NULL(); + + result = (Point *) palloc(sizeof(Point)); + + if (isnan(lseg_closept_lseg(result, l2, l1))) + PG_RETURN_NULL(); PG_RETURN_POINT_P(result); } -/* close_pb() + +/* * Closest point on or in box to specified point. + * + * If *result is not NULL, set it to the closest point on the box to the + * given point, and return the distance of the two points. */ -Datum -close_pb(PG_FUNCTION_ARGS) +static float8 +box_closept_point(Point *result, BOX *box, Point *pt) { - Point *pt = PG_GETARG_POINT_P(0); - BOX *box = PG_GETARG_BOX_P(1); - LSEG lseg, - seg; - Point point; - double dist, + float8 dist, d; + Point point, + closept; + LSEG lseg; + + if (box_contain_point(box, pt)) + { + if (result != NULL) + *result = *pt; - if (DatumGetBool(DirectFunctionCall2(on_pb, - PointPGetDatum(pt), - BoxPGetDatum(box)))) - PG_RETURN_POINT_P(pt); + return 0.0; + } /* pairwise check lseg distances */ point.x = box->low.x; point.y = box->high.y; statlseg_construct(&lseg, &box->low, &point); - dist = dist_ps_internal(pt, &lseg); + dist = lseg_closept_point(result, &lseg, pt); - statlseg_construct(&seg, &box->high, &point); - if ((d = dist_ps_internal(pt, &seg)) < dist) + statlseg_construct(&lseg, &box->high, &point); + d = lseg_closept_point(&closept, &lseg, pt); + if (float8_lt(d, dist)) { dist = d; - memcpy(&lseg, &seg, sizeof(lseg)); + if (result != NULL) + *result = closept; } point.x = box->high.x; point.y = box->low.y; - statlseg_construct(&seg, &box->low, &point); - if ((d = dist_ps_internal(pt, &seg)) < dist) + statlseg_construct(&lseg, &box->low, &point); + d = lseg_closept_point(&closept, &lseg, pt); + if (float8_lt(d, dist)) { dist = d; - memcpy(&lseg, &seg, sizeof(lseg)); + if (result != NULL) + *result = closept; } - statlseg_construct(&seg, &box->high, &point); - if ((d = dist_ps_internal(pt, &seg)) < dist) + statlseg_construct(&lseg, &box->high, &point); + d = lseg_closept_point(&closept, &lseg, pt); + if (float8_lt(d, dist)) { dist = d; - memcpy(&lseg, &seg, sizeof(lseg)); + if (result != NULL) + *result = closept; } - PG_RETURN_DATUM(DirectFunctionCall2(close_ps, - PointPGetDatum(pt), - LsegPGetDatum(&lseg))); + return dist; +} + +Datum +close_pb(PG_FUNCTION_ARGS) +{ + Point *pt = PG_GETARG_POINT_P(0); + BOX *box = PG_GETARG_BOX_P(1); + Point *result; + + result = (Point *) palloc(sizeof(Point)); + + if (isnan(box_closept_point(result, box, pt))) + PG_RETURN_NULL(); + + PG_RETURN_POINT_P(result); } + /* close_sl() * Closest point on line to line segment. * @@ -2995,16 +2955,17 @@ close_sl(PG_FUNCTION_ARGS) float8 d1, d2; - result = interpt_sl(lseg, line); - if (result) + result = (Point *) palloc(sizeof(Point)); + + if (lseg_interpt_line(result, lseg, line)) PG_RETURN_POINT_P(result); - d1 = dist_pl_internal(&lseg->p[0], line); - d2 = dist_pl_internal(&lseg->p[1], line); - if (d1 < d2) - result = point_copy(&lseg->p[0]); + d1 = line_closept_point(NULL, line, &lseg->p[0]); + d2 = line_closept_point(NULL, line, &lseg->p[1]); + if (float8_lt(d1, d2)) + *result = lseg->p[0]; else - result = point_copy(&lseg->p[1]); + *result = lseg->p[1]; PG_RETURN_POINT_P(result); #endif @@ -3016,92 +2977,137 @@ close_sl(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } -/* close_ls() +/* * Closest point on line segment to line. + * + * Return the distance between the line and the closest point of the line + * segment to the line. If *result is not NULL, set it to that point. + * + * NOTE: When the lines are parallel, endpoints of one of the line segment + * are FPeq(), in presence of NaN or Infinite coordinates, or perhaps = + * even because of simple roundoff issues, there may not be a single closest + * point. We are likely to set the result to the second endpoint in these + * cases. */ +static float8 +lseg_closept_line(Point *result, LSEG *lseg, LINE *line) +{ + float8 dist1, + dist2; + + if (lseg_interpt_line(result, lseg, line)) + return 0.0; + + dist1 = line_closept_point(NULL, line, &lseg->p[0]); + dist2 = line_closept_point(NULL, line, &lseg->p[1]); + + if (dist1 < dist2) + { + if (result != NULL) + *result = lseg->p[0]; + + return dist1; + } + else + { + if (result != NULL) + *result = lseg->p[1]; + + return dist2; + } +} + Datum close_ls(PG_FUNCTION_ARGS) { LINE *line = PG_GETARG_LINE_P(0); LSEG *lseg = PG_GETARG_LSEG_P(1); Point *result; - float8 d1, - d2; - result = interpt_sl(lseg, line); - if (result) - PG_RETURN_POINT_P(result); + if (lseg_sl(lseg) == line_sl(line)) + PG_RETURN_NULL(); - d1 = dist_pl_internal(&lseg->p[0], line); - d2 = dist_pl_internal(&lseg->p[1], line); - if (d1 < d2) - result = point_copy(&lseg->p[0]); - else - result = point_copy(&lseg->p[1]); + result = (Point *) palloc(sizeof(Point)); + + if (isnan(lseg_closept_line(result, lseg, line))) + PG_RETURN_NULL(); PG_RETURN_POINT_P(result); } -/* close_sb() + +/* * Closest point on or in box to line segment. + * + * Returns the distance between the closest point on or in the box to + * the line segment. If *result is not NULL, it is set to that point. */ -Datum -close_sb(PG_FUNCTION_ARGS) +static float8 +box_closept_lseg(Point *result, BOX *box, LSEG *lseg) { - LSEG *lseg = PG_GETARG_LSEG_P(0); - BOX *box = PG_GETARG_BOX_P(1); - Point point; - LSEG bseg, - seg; - double dist, + float8 dist, d; - - /* segment intersects box? then just return closest point to center */ - if (DatumGetBool(DirectFunctionCall2(inter_sb, - LsegPGetDatum(lseg), - BoxPGetDatum(box)))) - { - box_cn(&point, box); - PG_RETURN_DATUM(DirectFunctionCall2(close_ps, - PointPGetDatum(&point), - LsegPGetDatum(lseg))); - } + Point point, + closept; + LSEG bseg; + + if (box_interpt_lseg(result, box, lseg)) + return 0.0; /* pairwise check lseg distances */ point.x = box->low.x; point.y = box->high.y; statlseg_construct(&bseg, &box->low, &point); - dist = lseg_dt(lseg, &bseg); + dist = lseg_closept_lseg(result, &bseg, lseg); - statlseg_construct(&seg, &box->high, &point); - if ((d = lseg_dt(lseg, &seg)) < dist) + statlseg_construct(&bseg, &box->high, &point); + d = lseg_closept_lseg(&closept, &bseg, lseg); + if (float8_lt(d, dist)) { dist = d; - memcpy(&bseg, &seg, sizeof(bseg)); + if (result != NULL) + *result = closept; } point.x = box->high.x; point.y = box->low.y; - statlseg_construct(&seg, &box->low, &point); - if ((d = lseg_dt(lseg, &seg)) < dist) + statlseg_construct(&bseg, &box->low, &point); + d = lseg_closept_lseg(&closept, &bseg, lseg); + if (float8_lt(d, dist)) { dist = d; - memcpy(&bseg, &seg, sizeof(bseg)); + if (result != NULL) + *result = closept; } - statlseg_construct(&seg, &box->high, &point); - if ((d = lseg_dt(lseg, &seg)) < dist) + statlseg_construct(&bseg, &box->high, &point); + d = lseg_closept_lseg(&closept, &bseg, lseg); + if (float8_lt(d, dist)) { dist = d; - memcpy(&bseg, &seg, sizeof(bseg)); + if (result != NULL) + *result = closept; } - /* OK, we now have the closest line segment on the box boundary */ - PG_RETURN_DATUM(DirectFunctionCall2(close_lseg, - LsegPGetDatum(lseg), - LsegPGetDatum(&bseg))); + return dist; +} + +Datum +close_sb(PG_FUNCTION_ARGS) +{ + LSEG *lseg = PG_GETARG_LSEG_P(0); + BOX *box = PG_GETARG_BOX_P(1); + Point *result; + + result = (Point *) palloc(sizeof(Point)); + + if (isnan(box_closept_lseg(result, box, lseg))) + PG_RETURN_NULL(); + + PG_RETURN_POINT_P(result); } + Datum close_lb(PG_FUNCTION_ARGS) { @@ -3123,37 +3129,57 @@ close_lb(PG_FUNCTION_ARGS) * Whether one object lies completely within another. *-------------------------------------------------------------------*/ -/* on_pl - +/* * Does the point satisfy the equation? */ +static bool +line_contain_point(LINE *line, Point *point) +{ + return FPzero(float8_pl(float8_pl(float8_mul(line->A, point->x), + float8_mul(line->B, point->y)), + line->C)); +} + Datum on_pl(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); - PG_RETURN_BOOL(FPzero(line->A * pt->x + line->B * pt->y + line->C)); + PG_RETURN_BOOL(line_contain_point(line, pt)); } -/* on_ps - +/* * Determine colinearity by detecting a triangle inequality. * This algorithm seems to behave nicely even with lsb residues - tgl 1997-07-09 */ +static bool +lseg_contain_point(LSEG *lseg, Point *pt) +{ + return FPeq(point_dt(pt, &lseg->p[0]) + + point_dt(pt, &lseg->p[1]), + point_dt(&lseg->p[0], &lseg->p[1])); +} + Datum on_ps(PG_FUNCTION_ARGS) { Point *pt = PG_GETARG_POINT_P(0); LSEG *lseg = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(on_ps_internal(pt, lseg)); + PG_RETURN_BOOL(lseg_contain_point(lseg, pt)); } + +/* + * Check whether the point is in the box or on its border + */ static bool -on_ps_internal(Point *pt, LSEG *lseg) +box_contain_point(BOX *box, Point *point) { - return FPeq(point_dt(pt, &lseg->p[0]) + point_dt(pt, &lseg->p[1]), - point_dt(&lseg->p[0], &lseg->p[1])); + return box->high.x >= point->x && box->low.x <= point->x && + box->high.y >= point->y && box->low.y <= point->y; } Datum @@ -3162,8 +3188,7 @@ on_pb(PG_FUNCTION_ARGS) Point *pt = PG_GETARG_POINT_P(0); BOX *box = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x && - pt->y <= box->high.y && pt->y >= box->low.y); + PG_RETURN_BOOL(box_contain_point(box, pt)); } Datum @@ -3172,8 +3197,7 @@ box_contain_pt(PG_FUNCTION_ARGS) BOX *box = PG_GETARG_BOX_P(0); Point *pt = PG_GETARG_POINT_P(1); - PG_RETURN_BOOL(pt->x <= box->high.x && pt->x >= box->low.x && - pt->y <= box->high.y && pt->y >= box->low.y); + PG_RETURN_BOOL(box_contain_point(box, pt)); } /* on_ppath - @@ -3194,7 +3218,7 @@ on_ppath(PG_FUNCTION_ARGS) PATH *path = PG_GETARG_PATH_P(1); int i, n; - double a, + float8 a, b; /*-- OPEN --*/ @@ -3205,8 +3229,7 @@ on_ppath(PG_FUNCTION_ARGS) for (i = 0; i < n; i++) { b = point_dt(pt, &path->p[i + 1]); - if (FPeq(a + b, - point_dt(&path->p[i], &path->p[i + 1]))) + if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1]))) PG_RETURN_BOOL(true); a = b; } @@ -3217,18 +3240,33 @@ on_ppath(PG_FUNCTION_ARGS) PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0); } + +/* + * Check whether the line segment is on the line or close enough + * + * It is, if both of its points are on the line or close enough. + */ Datum on_sl(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); LINE *line = PG_GETARG_LINE_P(1); - PG_RETURN_BOOL(DatumGetBool(DirectFunctionCall2(on_pl, - PointPGetDatum(&lseg->p[0]), - LinePGetDatum(line))) && - DatumGetBool(DirectFunctionCall2(on_pl, - PointPGetDatum(&lseg->p[1]), - LinePGetDatum(line)))); + PG_RETURN_BOOL(line_contain_point(line, &lseg->p[0]) && + line_contain_point(line, &lseg->p[1])); +} + + +/* + * Check whether the line segment is in the box or on its border + * + * It is, if both of its points are in the box or on its border. + */ +static bool +box_contain_lseg(BOX *box, LSEG *lseg) +{ + return box_contain_point(box, &lseg->p[0]) && + box_contain_point(box, &lseg->p[1]); } Datum @@ -3237,12 +3275,7 @@ on_sb(PG_FUNCTION_ARGS) LSEG *lseg = PG_GETARG_LSEG_P(0); BOX *box = PG_GETARG_BOX_P(1); - PG_RETURN_BOOL(DatumGetBool(DirectFunctionCall2(on_pb, - PointPGetDatum(&lseg->p[0]), - BoxPGetDatum(box))) && - DatumGetBool(DirectFunctionCall2(on_pb, - PointPGetDatum(&lseg->p[1]), - BoxPGetDatum(box)))); + PG_RETURN_BOOL(box_contain_lseg(box, lseg)); } /*--------------------------------------------------------------------- @@ -3256,71 +3289,87 @@ inter_sl(PG_FUNCTION_ARGS) LSEG *lseg = PG_GETARG_LSEG_P(0); LINE *line = PG_GETARG_LINE_P(1); - PG_RETURN_BOOL(has_interpt_sl(lseg, line)); + PG_RETURN_BOOL(lseg_interpt_line(NULL, lseg, line)); } -/* inter_sb() + +/* * Do line segment and box intersect? * * Segment completely inside box counts as intersection. * If you want only segments crossing box boundaries, * try converting box to path first. * + * This function also sets the *result to the closest point on the line + * segment to the center of the box when they overlap and the result is + * not NULL. It is somewhat arbitrary, but maybe the best we can do as + * there are typically two points they intersect. + * * Optimize for non-intersection by checking for box intersection first. * - thomas 1998-01-30 */ -Datum -inter_sb(PG_FUNCTION_ARGS) +static bool +box_interpt_lseg(Point *result, BOX *box, LSEG *lseg) { - LSEG *lseg = PG_GETARG_LSEG_P(0); - BOX *box = PG_GETARG_BOX_P(1); BOX lbox; LSEG bseg; Point point; - lbox.low.x = Min(lseg->p[0].x, lseg->p[1].x); - lbox.low.y = Min(lseg->p[0].y, lseg->p[1].y); - lbox.high.x = Max(lseg->p[0].x, lseg->p[1].x); - lbox.high.y = Max(lseg->p[0].y, lseg->p[1].y); + lbox.low.x = float8_min(lseg->p[0].x, lseg->p[1].x); + lbox.low.y = float8_min(lseg->p[0].y, lseg->p[1].y); + lbox.high.x = float8_max(lseg->p[0].x, lseg->p[1].x); + lbox.high.y = float8_max(lseg->p[0].y, lseg->p[1].y); /* nothing close to overlap? then not going to intersect */ if (!box_ov(&lbox, box)) - PG_RETURN_BOOL(false); + return false; + + if (result != NULL) + { + box_cn(&point, box); + lseg_closept_point(result, lseg, &point); + } /* an endpoint of segment is inside box? then clearly intersects */ - if (DatumGetBool(DirectFunctionCall2(on_pb, - PointPGetDatum(&lseg->p[0]), - BoxPGetDatum(box))) || - DatumGetBool(DirectFunctionCall2(on_pb, - PointPGetDatum(&lseg->p[1]), - BoxPGetDatum(box)))) - PG_RETURN_BOOL(true); + if (box_contain_point(box, &lseg->p[0]) || + box_contain_point(box, &lseg->p[1])) + return true; /* pairwise check lseg intersections */ point.x = box->low.x; point.y = box->high.y; statlseg_construct(&bseg, &box->low, &point); - if (lseg_intersect_internal(&bseg, lseg)) - PG_RETURN_BOOL(true); + if (lseg_interpt_lseg(NULL, &bseg, lseg)) + return true; statlseg_construct(&bseg, &box->high, &point); - if (lseg_intersect_internal(&bseg, lseg)) - PG_RETURN_BOOL(true); + if (lseg_interpt_lseg(NULL, &bseg, lseg)) + return true; point.x = box->high.x; point.y = box->low.y; statlseg_construct(&bseg, &box->low, &point); - if (lseg_intersect_internal(&bseg, lseg)) - PG_RETURN_BOOL(true); + if (lseg_interpt_lseg(NULL, &bseg, lseg)) + return true; statlseg_construct(&bseg, &box->high, &point); - if (lseg_intersect_internal(&bseg, lseg)) - PG_RETURN_BOOL(true); + if (lseg_interpt_lseg(NULL, &bseg, lseg)) + return true; /* if we dropped through, no two segs intersected */ - PG_RETURN_BOOL(false); + return false; +} + +Datum +inter_sb(PG_FUNCTION_ARGS) +{ + LSEG *lseg = PG_GETARG_LSEG_P(0); + BOX *box = PG_GETARG_BOX_P(1); + + PG_RETURN_BOOL(box_interpt_lseg(NULL, box, lseg)); } + /* inter_lb() * Do line and box intersect? */ @@ -3339,22 +3388,22 @@ inter_lb(PG_FUNCTION_ARGS) p2.x = box->low.x; p2.y = box->high.y; statlseg_construct(&bseg, &p1, &p2); - if (has_interpt_sl(&bseg, line)) + if (lseg_interpt_line(NULL, &bseg, line)) PG_RETURN_BOOL(true); p1.x = box->high.x; p1.y = box->high.y; statlseg_construct(&bseg, &p1, &p2); - if (has_interpt_sl(&bseg, line)) + if (lseg_interpt_line(NULL, &bseg, line)) PG_RETURN_BOOL(true); p2.x = box->high.x; p2.y = box->low.y; statlseg_construct(&bseg, &p1, &p2); - if (has_interpt_sl(&bseg, line)) + if (lseg_interpt_line(NULL, &bseg, line)) PG_RETURN_BOOL(true); p1.x = box->low.x; p1.y = box->low.y; statlseg_construct(&bseg, &p1, &p2); - if (has_interpt_sl(&bseg, line)) + if (lseg_interpt_line(NULL, &bseg, line)) PG_RETURN_BOOL(true); /* if we dropped through, no intersection */ @@ -3376,33 +3425,31 @@ static void make_bound_box(POLYGON *poly) { int i; - double x1, + float8 x1, y1, x2, y2; - if (poly->npts > 0) - { - x2 = x1 = poly->p[0].x; - y2 = y1 = poly->p[0].y; - for (i = 1; i < poly->npts; i++) - { - if (poly->p[i].x < x1) - x1 = poly->p[i].x; - if (poly->p[i].x > x2) - x2 = poly->p[i].x; - if (poly->p[i].y < y1) - y1 = poly->p[i].y; - if (poly->p[i].y > y2) - y2 = poly->p[i].y; - } + Assert(poly->npts > 0); - box_fill(&(poly->boundbox), x1, x2, y1, y2); + x1 = x2 = poly->p[0].x; + y2 = y1 = poly->p[0].y; + for (i = 1; i < poly->npts; i++) + { + if (float8_lt(poly->p[i].x, x1)) + x1 = poly->p[i].x; + if (float8_gt(poly->p[i].x, x2)) + x2 = poly->p[i].x; + if (float8_lt(poly->p[i].y, y1)) + y1 = poly->p[i].y; + if (float8_gt(poly->p[i].y, y2)) + y2 = poly->p[i].y; } - else - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot create bounding box for empty polygon"))); + + poly->boundbox.low.x = x1; + poly->boundbox.high.x = x2; + poly->boundbox.low.y = y1; + poly->boundbox.high.y = y2; } /*------------------------------------------------------------------ @@ -3746,9 +3793,10 @@ poly_overlap(PG_FUNCTION_ARGS) POLYGON *polyb = PG_GETARG_POLYGON_P(1); bool result; + Assert(polya->npts > 0 && polyb->npts > 0); + /* Quick check by bounding box */ - result = (polya->npts > 0 && polyb->npts > 0 && - box_ov(&polya->boundbox, &polyb->boundbox)) ? true : false; + result = box_ov(&polya->boundbox, &polyb->boundbox); /* * Brute-force algorithm - try to find intersected edges, if so then @@ -3766,7 +3814,7 @@ poly_overlap(PG_FUNCTION_ARGS) sa.p[0] = polya->p[polya->npts - 1]; result = false; - for (ia = 0; ia < polya->npts && result == false; ia++) + for (ia = 0; ia < polya->npts && !result; ia++) { /* Second point of polya's edge is a current one */ sa.p[1] = polya->p[ia]; @@ -3774,10 +3822,10 @@ poly_overlap(PG_FUNCTION_ARGS) /* Init first of polyb's edge with last point */ sb.p[0] = polyb->p[polyb->npts - 1]; - for (ib = 0; ib < polyb->npts && result == false; ib++) + for (ib = 0; ib < polyb->npts && !result; ib++) { sb.p[1] = polyb->p[ib]; - result = lseg_intersect_internal(&sa, &sb); + result = lseg_interpt_lseg(NULL, &sa, &sb); sb.p[0] = sb.p[1]; } @@ -3787,10 +3835,9 @@ poly_overlap(PG_FUNCTION_ARGS) sa.p[0] = sa.p[1]; } - if (result == false) + if (!result) { - result = (point_inside(polya->p, polyb->npts, polyb->p) - || + result = (point_inside(polya->p, polyb->npts, polyb->p) || point_inside(polyb->p, polya->npts, polya->p)); } } @@ -3824,22 +3871,21 @@ touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start) t.p[0] = *a; t.p[1] = *b; -#define POINTEQ(pt1, pt2) (FPeq((pt1)->x, (pt2)->x) && FPeq((pt1)->y, (pt2)->y)) - if (POINTEQ(a, s->p)) + if (point_eq_point(a, s->p)) { - if (on_ps_internal(s->p + 1, &t)) + if (lseg_contain_point(&t, s->p + 1)) return lseg_inside_poly(b, s->p + 1, poly, start); } - else if (POINTEQ(a, s->p + 1)) + else if (point_eq_point(a, s->p + 1)) { - if (on_ps_internal(s->p, &t)) + if (lseg_contain_point(&t, s->p)) return lseg_inside_poly(b, s->p, poly, start); } - else if (on_ps_internal(s->p, &t)) + else if (lseg_contain_point(&t, s->p)) { return lseg_inside_poly(b, s->p, poly, start); } - else if (on_ps_internal(s->p + 1, &t)) + else if (lseg_contain_point(&t, s->p + 1)) { return lseg_inside_poly(b, s->p + 1, poly, start); } @@ -3850,7 +3896,7 @@ touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start) /* * Returns true if segment (a,b) is in polygon, option * start is used for optimization - function checks - * polygon's edges started from start + * polygon's edges starting from start */ static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start) @@ -3867,36 +3913,35 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start) for (i = start; i < poly->npts && res; i++) { - Point *interpt; + Point interpt; CHECK_FOR_INTERRUPTS(); s.p[1] = poly->p[i]; - if (on_ps_internal(t.p, &s)) + if (lseg_contain_point(&s, t.p)) { - if (on_ps_internal(t.p + 1, &s)) + if (lseg_contain_point(&s, t.p + 1)) return true; /* t is contained by s */ /* Y-cross */ res = touched_lseg_inside_poly(t.p, t.p + 1, &s, poly, i + 1); } - else if (on_ps_internal(t.p + 1, &s)) + else if (lseg_contain_point(&s, t.p + 1)) { /* Y-cross */ res = touched_lseg_inside_poly(t.p + 1, t.p, &s, poly, i + 1); } - else if ((interpt = lseg_interpt_internal(&t, &s)) != NULL) + else if (lseg_interpt_lseg(&interpt, &t, &s)) { /* * segments are X-crossing, go to check each subsegment */ intersection = true; - res = lseg_inside_poly(t.p, interpt, poly, i + 1); + res = lseg_inside_poly(t.p, &interpt, poly, i + 1); if (res) - res = lseg_inside_poly(t.p + 1, interpt, poly, i + 1); - pfree(interpt); + res = lseg_inside_poly(t.p + 1, &interpt, poly, i + 1); } s.p[0] = s.p[1]; @@ -3910,8 +3955,8 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start) * if X-intersection wasn't found then check central point of tested * segment. In opposite case we already check all subsegments */ - p.x = (t.p[0].x + t.p[1].x) / 2.0; - p.y = (t.p[0].y + t.p[1].y) / 2.0; + p.x = float8_div(float8_pl(t.p[0].x, t.p[1].x), 2.0); + p.y = float8_div(float8_pl(t.p[0].y, t.p[1].y), 2.0); res = point_inside(&p, poly->npts, poly->p); } @@ -3919,42 +3964,46 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start) return res; } -/*----------------------------------------------------------------- - * Determine if polygon A contains polygon B. - *-----------------------------------------------------------------*/ -Datum -poly_contain(PG_FUNCTION_ARGS) +/* + * Check whether the first polygon contains the second + */ +static bool +poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly) { - POLYGON *polya = PG_GETARG_POLYGON_P(0); - POLYGON *polyb = PG_GETARG_POLYGON_P(1); - bool result; + int i; + LSEG s; + + Assert(contains_poly->npts > 0 && contained_poly->npts > 0); /* - * Quick check to see if bounding box is contained. + * Quick check to see if contained's bounding box is contained in + * contains' bb. */ - if (polya->npts > 0 && polyb->npts > 0 && - DatumGetBool(DirectFunctionCall2(box_contain, - BoxPGetDatum(&polya->boundbox), - BoxPGetDatum(&polyb->boundbox)))) - { - int i; - LSEG s; + if (!box_contain_box(&contains_poly->boundbox, &contained_poly->boundbox)) + return false; - s.p[0] = polyb->p[polyb->npts - 1]; - result = true; + s.p[0] = contained_poly->p[contained_poly->npts - 1]; - for (i = 0; i < polyb->npts && result; i++) - { - s.p[1] = polyb->p[i]; - result = lseg_inside_poly(s.p, s.p + 1, polya, 0); - s.p[0] = s.p[1]; - } - } - else + for (i = 0; i < contained_poly->npts; i++) { - result = false; + s.p[1] = contained_poly->p[i]; + if (!lseg_inside_poly(s.p, s.p + 1, contains_poly, 0)) + return false; + s.p[0] = s.p[1]; } + return true; +} + +Datum +poly_contain(PG_FUNCTION_ARGS) +{ + POLYGON *polya = PG_GETARG_POLYGON_P(0); + POLYGON *polyb = PG_GETARG_POLYGON_P(1); + bool result; + + result = poly_contain_poly(polya, polyb); + /* * Avoid leaking memory for toasted inputs ... needed for rtree indexes */ @@ -3971,11 +4020,20 @@ poly_contain(PG_FUNCTION_ARGS) Datum poly_contained(PG_FUNCTION_ARGS) { - Datum polya = PG_GETARG_DATUM(0); - Datum polyb = PG_GETARG_DATUM(1); + POLYGON *polya = PG_GETARG_POLYGON_P(0); + POLYGON *polyb = PG_GETARG_POLYGON_P(1); + bool result; /* Just switch the arguments and pass it off to poly_contain */ - PG_RETURN_DATUM(DirectFunctionCall2(poly_contain, polyb, polya)); + result = poly_contain_poly(polyb, polya); + + /* + * Avoid leaking memory for toasted inputs ... needed for rtree indexes + */ + PG_FREE_IF_COPY(polya, 0); + PG_FREE_IF_COPY(polyb, 1); + + PG_RETURN_BOOL(result); } @@ -4025,8 +4083,22 @@ construct_point(PG_FUNCTION_ARGS) { float8 x = PG_GETARG_FLOAT8(0); float8 y = PG_GETARG_FLOAT8(1); + Point *result; + + result = (Point *) palloc(sizeof(Point)); + + point_construct(result, x, y); + + PG_RETURN_POINT_P(result); +} - PG_RETURN_POINT_P(point_construct(x, y)); + +static inline void +point_add_point(Point *result, Point *pt1, Point *pt2) +{ + point_construct(result, + float8_pl(pt1->x, pt2->x), + float8_pl(pt1->y, pt2->y)); } Datum @@ -4038,12 +4110,20 @@ point_add(PG_FUNCTION_ARGS) result = (Point *) palloc(sizeof(Point)); - result->x = (p1->x + p2->x); - result->y = (p1->y + p2->y); + point_add_point(result, p1, p2); PG_RETURN_POINT_P(result); } + +static inline void +point_sub_point(Point *result, Point *pt1, Point *pt2) +{ + point_construct(result, + float8_mi(pt1->x, pt2->x), + float8_mi(pt1->y, pt2->y)); +} + Datum point_sub(PG_FUNCTION_ARGS) { @@ -4053,12 +4133,22 @@ point_sub(PG_FUNCTION_ARGS) result = (Point *) palloc(sizeof(Point)); - result->x = (p1->x - p2->x); - result->y = (p1->y - p2->y); + point_sub_point(result, p1, p2); PG_RETURN_POINT_P(result); } + +static inline void +point_mul_point(Point *result, Point *pt1, Point *pt2) +{ + point_construct(result, + float8_mi(float8_mul(pt1->x, pt2->x), + float8_mul(pt1->y, pt2->y)), + float8_pl(float8_mul(pt1->x, pt2->y), + float8_mul(pt1->y, pt2->x))); +} + Datum point_mul(PG_FUNCTION_ARGS) { @@ -4068,31 +4158,36 @@ point_mul(PG_FUNCTION_ARGS) result = (Point *) palloc(sizeof(Point)); - result->x = (p1->x * p2->x) - (p1->y * p2->y); - result->y = (p1->x * p2->y) + (p1->y * p2->x); + point_mul_point(result, p1, p2); PG_RETURN_POINT_P(result); } + +static inline void +point_div_point(Point *result, Point *pt1, Point *pt2) +{ + float8 div; + + div = float8_pl(float8_mul(pt2->x, pt2->x), float8_mul(pt2->y, pt2->y)); + + point_construct(result, + float8_div(float8_pl(float8_mul(pt1->x, pt2->x), + float8_mul(pt1->y, pt2->y)), div), + float8_div(float8_mi(float8_mul(pt1->y, pt2->x), + float8_mul(pt1->x, pt2->y)), div)); +} + Datum point_div(PG_FUNCTION_ARGS) { Point *p1 = PG_GETARG_POINT_P(0); Point *p2 = PG_GETARG_POINT_P(1); Point *result; - double div; result = (Point *) palloc(sizeof(Point)); - div = (p2->x * p2->x) + (p2->y * p2->y); - - if (div == 0.0) - ereport(ERROR, - (errcode(ERRCODE_DIVISION_BY_ZERO), - errmsg("division by zero"))); - - result->x = ((p1->x * p2->x) + (p1->y * p2->y)) / div; - result->y = ((p2->x * p1->y) - (p2->y * p1->x)) / div; + point_div_point(result, p1, p2); PG_RETURN_POINT_P(result); } @@ -4109,8 +4204,13 @@ points_box(PG_FUNCTION_ARGS) { Point *p1 = PG_GETARG_POINT_P(0); Point *p2 = PG_GETARG_POINT_P(1); + BOX *result; - PG_RETURN_BOX_P(box_construct(p1->x, p2->x, p1->y, p2->y)); + result = (BOX *) palloc(sizeof(BOX)); + + box_construct(result, p1, p2); + + PG_RETURN_BOX_P(result); } Datum @@ -4118,11 +4218,14 @@ box_add(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); Point *p = PG_GETARG_POINT_P(1); + BOX *result; + + result = (BOX *) palloc(sizeof(BOX)); + + point_add_point(&result->high, &box->high, p); + point_add_point(&result->low, &box->low, p); - PG_RETURN_BOX_P(box_construct((box->high.x + p->x), - (box->low.x + p->x), - (box->high.y + p->y), - (box->low.y + p->y))); + PG_RETURN_BOX_P(result); } Datum @@ -4130,11 +4233,14 @@ box_sub(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); Point *p = PG_GETARG_POINT_P(1); + BOX *result; + + result = (BOX *) palloc(sizeof(BOX)); - PG_RETURN_BOX_P(box_construct((box->high.x - p->x), - (box->low.x - p->x), - (box->high.y - p->y), - (box->low.y - p->y))); + point_sub_point(&result->high, &box->high, p); + point_sub_point(&result->low, &box->low, p); + + PG_RETURN_BOX_P(result); } Datum @@ -4143,17 +4249,15 @@ box_mul(PG_FUNCTION_ARGS) BOX *box = PG_GETARG_BOX_P(0); Point *p = PG_GETARG_POINT_P(1); BOX *result; - Point *high, - *low; + Point high, + low; + + result = (BOX *) palloc(sizeof(BOX)); - high = DatumGetPointP(DirectFunctionCall2(point_mul, - PointPGetDatum(&box->high), - PointPGetDatum(p))); - low = DatumGetPointP(DirectFunctionCall2(point_mul, - PointPGetDatum(&box->low), - PointPGetDatum(p))); + point_mul_point(&high, &box->high, p); + point_mul_point(&low, &box->low, p); - result = box_construct(high->x, low->x, high->y, low->y); + box_construct(result, &high, &low); PG_RETURN_BOX_P(result); } @@ -4164,17 +4268,15 @@ box_div(PG_FUNCTION_ARGS) BOX *box = PG_GETARG_BOX_P(0); Point *p = PG_GETARG_POINT_P(1); BOX *result; - Point *high, - *low; + Point high, + low; - high = DatumGetPointP(DirectFunctionCall2(point_div, - PointPGetDatum(&box->high), - PointPGetDatum(p))); - low = DatumGetPointP(DirectFunctionCall2(point_div, - PointPGetDatum(&box->low), - PointPGetDatum(p))); + result = (BOX *) palloc(sizeof(BOX)); + + point_div_point(&high, &box->high, p); + point_div_point(&low, &box->low, p); - result = box_construct(high->x, low->x, high->y, low->y); + box_construct(result, &high, &low); PG_RETURN_BOX_P(result); } @@ -4210,10 +4312,10 @@ boxes_bound_box(PG_FUNCTION_ARGS) container = (BOX *) palloc(sizeof(BOX)); - container->high.x = Max(box1->high.x, box2->high.x); - container->low.x = Min(box1->low.x, box2->low.x); - container->high.y = Max(box1->high.y, box2->high.y); - container->low.y = Min(box1->low.y, box2->low.y); + container->high.x = float8_max(box1->high.x, box2->high.x); + container->low.x = float8_min(box1->low.x, box2->low.x); + container->high.y = float8_max(box1->high.y, box2->high.y); + container->low.y = float8_min(box1->low.y, box2->low.y); PG_RETURN_BOX_P(container); } @@ -4284,10 +4386,7 @@ path_add_pt(PG_FUNCTION_ARGS) int i; for (i = 0; i < path->npts; i++) - { - path->p[i].x += point->x; - path->p[i].y += point->y; - } + point_add_point(&path->p[i], &path->p[i], point); PG_RETURN_PATH_P(path); } @@ -4300,10 +4399,7 @@ path_sub_pt(PG_FUNCTION_ARGS) int i; for (i = 0; i < path->npts; i++) - { - path->p[i].x -= point->x; - path->p[i].y -= point->y; - } + point_sub_point(&path->p[i], &path->p[i], point); PG_RETURN_PATH_P(path); } @@ -4316,17 +4412,10 @@ path_mul_pt(PG_FUNCTION_ARGS) { PATH *path = PG_GETARG_PATH_P_COPY(0); Point *point = PG_GETARG_POINT_P(1); - Point *p; int i; for (i = 0; i < path->npts; i++) - { - p = DatumGetPointP(DirectFunctionCall2(point_mul, - PointPGetDatum(&path->p[i]), - PointPGetDatum(point))); - path->p[i].x = p->x; - path->p[i].y = p->y; - } + point_mul_point(&path->p[i], &path->p[i], point); PG_RETURN_PATH_P(path); } @@ -4336,17 +4425,10 @@ path_div_pt(PG_FUNCTION_ARGS) { PATH *path = PG_GETARG_PATH_P_COPY(0); Point *point = PG_GETARG_POINT_P(1); - Point *p; int i; for (i = 0; i < path->npts; i++) - { - p = DatumGetPointP(DirectFunctionCall2(point_div, - PointPGetDatum(&path->p[i]), - PointPGetDatum(point))); - path->p[i].x = p->x; - path->p[i].y = p->y; - } + point_div_point(&path->p[i], &path->p[i], point); PG_RETURN_PATH_P(path); } @@ -4421,15 +4503,15 @@ Datum poly_center(PG_FUNCTION_ARGS) { POLYGON *poly = PG_GETARG_POLYGON_P(0); - Datum result; - CIRCLE *circle; + Point *result; + CIRCLE circle; - circle = DatumGetCircleP(DirectFunctionCall1(poly_circle, - PolygonPGetDatum(poly))); - result = DirectFunctionCall1(circle_center, - CirclePGetDatum(circle)); + result = (Point *) palloc(sizeof(Point)); + + poly_to_circle(&circle, poly); + *result = circle.center; - PG_RETURN_DATUM(result); + PG_RETURN_POINT_P(result); } @@ -4439,10 +4521,8 @@ poly_box(PG_FUNCTION_ARGS) POLYGON *poly = PG_GETARG_POLYGON_P(0); BOX *box; - if (poly->npts < 1) - PG_RETURN_NULL(); - - box = box_copy(&poly->boundbox); + box = (BOX *) palloc(sizeof(BOX)); + *box = poly->boundbox; PG_RETURN_BOX_P(box); } @@ -4474,8 +4554,7 @@ box_poly(PG_FUNCTION_ARGS) poly->p[3].x = box->high.x; poly->p[3].y = box->low.y; - box_fill(&poly->boundbox, box->high.x, box->low.x, - box->high.y, box->low.y); + box_construct(&poly->boundbox, &box->high, &box->low); PG_RETURN_POLYGON_P(poly); } @@ -4556,7 +4635,8 @@ circle_in(PG_FUNCTION_ARGS) s++; circle->radius = single_decode(s, &s, "circle", str); - if (circle->radius < 0) + /* We have to accept NaN. */ + if (circle->radius < 0.0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type %s: \"%s\"", @@ -4564,8 +4644,7 @@ circle_in(PG_FUNCTION_ARGS) while (depth > 0) { - if ((*s == RDELIM) - || ((*s == RDELIM_C) && (depth == 1))) + if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1))) { depth--; s++; @@ -4624,7 +4703,8 @@ circle_recv(PG_FUNCTION_ARGS) circle->center.y = pq_getmsgfloat8(buf); circle->radius = pq_getmsgfloat8(buf); - if (circle->radius < 0) + /* We have to accept NaN. */ + if (circle->radius < 0.0) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid radius in external \"circle\" value"))); @@ -4655,6 +4735,9 @@ circle_send(PG_FUNCTION_ARGS) *---------------------------------------------------------*/ /* circles identical? + * + * We consider NaNs values to be equal to each other to let those circles + * to be found. */ Datum circle_same(PG_FUNCTION_ARGS) @@ -4662,9 +4745,9 @@ circle_same(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPeq(circle1->radius, circle2->radius) && - FPeq(circle1->center.x, circle2->center.x) && - FPeq(circle1->center.y, circle2->center.y)); + PG_RETURN_BOOL(((isnan(circle1->radius) && isnan(circle1->radius)) || + FPeq(circle1->radius, circle2->radius)) && + point_eq_point(&circle1->center, &circle2->center)); } /* circle_overlap - does circle1 overlap circle2? @@ -4676,7 +4759,7 @@ circle_overlap(PG_FUNCTION_ARGS) CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), - circle1->radius + circle2->radius)); + float8_pl(circle1->radius, circle2->radius))); } /* circle_overleft - is the right edge of circle1 at or left of @@ -4688,8 +4771,8 @@ circle_overleft(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((circle1->center.x + circle1->radius), - (circle2->center.x + circle2->radius))); + PG_RETURN_BOOL(FPle(float8_pl(circle1->center.x, circle1->radius), + float8_pl(circle2->center.x, circle2->radius))); } /* circle_left - is circle1 strictly left of circle2? @@ -4700,8 +4783,8 @@ circle_left(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPlt((circle1->center.x + circle1->radius), - (circle2->center.x - circle2->radius))); + PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.x, circle1->radius), + float8_mi(circle2->center.x, circle2->radius))); } /* circle_right - is circle1 strictly right of circle2? @@ -4712,8 +4795,8 @@ circle_right(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPgt((circle1->center.x - circle1->radius), - (circle2->center.x + circle2->radius))); + PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.x, circle1->radius), + float8_pl(circle2->center.x, circle2->radius))); } /* circle_overright - is the left edge of circle1 at or right of @@ -4725,8 +4808,8 @@ circle_overright(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPge((circle1->center.x - circle1->radius), - (circle2->center.x - circle2->radius))); + PG_RETURN_BOOL(FPge(float8_mi(circle1->center.x, circle1->radius), + float8_mi(circle2->center.x, circle2->radius))); } /* circle_contained - is circle1 contained by circle2? @@ -4737,7 +4820,8 @@ circle_contained(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle1->radius), circle2->radius)); + PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), + float8_mi(circle2->radius, circle1->radius))); } /* circle_contain - does circle1 contain circle2? @@ -4748,7 +4832,8 @@ circle_contain(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((point_dt(&circle1->center, &circle2->center) + circle2->radius), circle1->radius)); + PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), + float8_mi(circle1->radius, circle2->radius))); } @@ -4760,8 +4845,8 @@ circle_below(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPlt((circle1->center.y + circle1->radius), - (circle2->center.y - circle2->radius))); + PG_RETURN_BOOL(FPlt(float8_pl(circle1->center.y, circle1->radius), + float8_mi(circle2->center.y, circle2->radius))); } /* circle_above - is circle1 strictly above circle2? @@ -4772,8 +4857,8 @@ circle_above(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPgt((circle1->center.y - circle1->radius), - (circle2->center.y + circle2->radius))); + PG_RETURN_BOOL(FPgt(float8_mi(circle1->center.y, circle1->radius), + float8_pl(circle2->center.y, circle2->radius))); } /* circle_overbelow - is the upper edge of circle1 at or below @@ -4785,8 +4870,8 @@ circle_overbelow(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle((circle1->center.y + circle1->radius), - (circle2->center.y + circle2->radius))); + PG_RETURN_BOOL(FPle(float8_pl(circle1->center.y, circle1->radius), + float8_pl(circle2->center.y, circle2->radius))); } /* circle_overabove - is the lower edge of circle1 at or above @@ -4798,8 +4883,8 @@ circle_overabove(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPge((circle1->center.y - circle1->radius), - (circle2->center.y - circle2->radius))); + PG_RETURN_BOOL(FPge(float8_mi(circle1->center.y, circle1->radius), + float8_mi(circle2->center.y, circle2->radius))); } @@ -4865,20 +4950,6 @@ circle_ge(PG_FUNCTION_ARGS) * "Arithmetic" operators on circles. *---------------------------------------------------------*/ -static CIRCLE * -circle_copy(CIRCLE *circle) -{ - CIRCLE *result; - - if (!PointerIsValid(circle)) - return NULL; - - result = (CIRCLE *) palloc(sizeof(CIRCLE)); - memcpy((char *) result, (char *) circle, sizeof(CIRCLE)); - return result; -} - - /* circle_add_pt() * Translation operator. */ @@ -4889,10 +4960,10 @@ circle_add_pt(PG_FUNCTION_ARGS) Point *point = PG_GETARG_POINT_P(1); CIRCLE *result; - result = circle_copy(circle); + result = (CIRCLE *) palloc(sizeof(CIRCLE)); - result->center.x += point->x; - result->center.y += point->y; + point_add_point(&result->center, &circle->center, point); + result->radius = circle->radius; PG_RETURN_CIRCLE_P(result); } @@ -4904,10 +4975,10 @@ circle_sub_pt(PG_FUNCTION_ARGS) Point *point = PG_GETARG_POINT_P(1); CIRCLE *result; - result = circle_copy(circle); + result = (CIRCLE *) palloc(sizeof(CIRCLE)); - result->center.x -= point->x; - result->center.y -= point->y; + point_sub_point(&result->center, &circle->center, point); + result->radius = circle->radius; PG_RETURN_CIRCLE_P(result); } @@ -4922,16 +4993,11 @@ circle_mul_pt(PG_FUNCTION_ARGS) CIRCLE *circle = PG_GETARG_CIRCLE_P(0); Point *point = PG_GETARG_POINT_P(1); CIRCLE *result; - Point *p; - result = circle_copy(circle); + result = (CIRCLE *) palloc(sizeof(CIRCLE)); - p = DatumGetPointP(DirectFunctionCall2(point_mul, - PointPGetDatum(&circle->center), - PointPGetDatum(point))); - result->center.x = p->x; - result->center.y = p->y; - result->radius *= HYPOT(point->x, point->y); + point_mul_point(&result->center, &circle->center, point); + result->radius = float8_mul(circle->radius, HYPOT(point->x, point->y)); PG_RETURN_CIRCLE_P(result); } @@ -4942,16 +5008,11 @@ circle_div_pt(PG_FUNCTION_ARGS) CIRCLE *circle = PG_GETARG_CIRCLE_P(0); Point *point = PG_GETARG_POINT_P(1); CIRCLE *result; - Point *p; - result = circle_copy(circle); + result = (CIRCLE *) palloc(sizeof(CIRCLE)); - p = DatumGetPointP(DirectFunctionCall2(point_div, - PointPGetDatum(&circle->center), - PointPGetDatum(point))); - result->center.x = p->x; - result->center.y = p->y; - result->radius /= HYPOT(point->x, point->y); + point_div_point(&result->center, &circle->center, point); + result->radius = float8_div(circle->radius, HYPOT(point->x, point->y)); PG_RETURN_CIRCLE_P(result); } @@ -4975,7 +5036,7 @@ circle_diameter(PG_FUNCTION_ARGS) { CIRCLE *circle = PG_GETARG_CIRCLE_P(0); - PG_RETURN_FLOAT8(2 * circle->radius); + PG_RETURN_FLOAT8(float8_mul(circle->radius, 2.0)); } @@ -5000,10 +5061,11 @@ circle_distance(PG_FUNCTION_ARGS) CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); float8 result; - result = point_dt(&circle1->center, &circle2->center) - - (circle1->radius + circle2->radius); - if (result < 0) - result = 0; + result = float8_mi(point_dt(&circle1->center, &circle2->center), + float8_pl(circle1->radius, circle2->radius)); + if (result < 0.0) + result = 0.0; + PG_RETURN_FLOAT8(result); } @@ -5013,7 +5075,7 @@ circle_contain_pt(PG_FUNCTION_ARGS) { CIRCLE *circle = PG_GETARG_CIRCLE_P(0); Point *point = PG_GETARG_POINT_P(1); - double d; + float8 d; d = point_dt(&circle->center, point); PG_RETURN_BOOL(d <= circle->radius); @@ -5025,7 +5087,7 @@ pt_contained_circle(PG_FUNCTION_ARGS) { Point *point = PG_GETARG_POINT_P(0); CIRCLE *circle = PG_GETARG_CIRCLE_P(1); - double d; + float8 d; d = point_dt(&circle->center, point); PG_RETURN_BOOL(d <= circle->radius); @@ -5042,9 +5104,11 @@ dist_pc(PG_FUNCTION_ARGS) CIRCLE *circle = PG_GETARG_CIRCLE_P(1); float8 result; - result = point_dt(point, &circle->center) - circle->radius; - if (result < 0) - result = 0; + result = float8_mi(point_dt(point, &circle->center), + circle->radius); + if (result < 0.0) + result = 0.0; + PG_RETURN_FLOAT8(result); } @@ -5058,9 +5122,10 @@ dist_cpoint(PG_FUNCTION_ARGS) Point *point = PG_GETARG_POINT_P(1); float8 result; - result = point_dt(point, &circle->center) - circle->radius; - if (result < 0) - result = 0; + result = float8_mi(point_dt(point, &circle->center), circle->radius); + if (result < 0.0) + result = 0.0; + PG_RETURN_FLOAT8(result); } @@ -5082,10 +5147,10 @@ circle_center(PG_FUNCTION_ARGS) /* circle_ar - returns the area of the circle. */ -static double +static float8 circle_ar(CIRCLE *circle) { - return M_PI * (circle->radius * circle->radius); + return float8_mul(float8_mul(circle->radius, circle->radius), M_PI); } @@ -5114,16 +5179,16 @@ circle_box(PG_FUNCTION_ARGS) { CIRCLE *circle = PG_GETARG_CIRCLE_P(0); BOX *box; - double delta; + float8 delta; box = (BOX *) palloc(sizeof(BOX)); - delta = circle->radius / sqrt(2.0); + delta = float8_div(circle->radius, sqrt(2.0)); - box->high.x = circle->center.x + delta; - box->low.x = circle->center.x - delta; - box->high.y = circle->center.y + delta; - box->low.y = circle->center.y - delta; + box->high.x = float8_pl(circle->center.x, delta); + box->low.x = float8_mi(circle->center.x, delta); + box->high.y = float8_pl(circle->center.y, delta); + box->low.y = float8_mi(circle->center.y, delta); PG_RETURN_BOX_P(box); } @@ -5139,8 +5204,8 @@ box_circle(PG_FUNCTION_ARGS) circle = (CIRCLE *) palloc(sizeof(CIRCLE)); - circle->center.x = (box->high.x + box->low.x) / 2; - circle->center.y = (box->high.y + box->low.y) / 2; + circle->center.x = float8_div(float8_pl(box->high.x, box->low.x), 2.0); + circle->center.y = float8_div(float8_pl(box->high.y, box->low.y), 2.0); circle->radius = point_dt(&circle->center, &box->high); @@ -5157,8 +5222,8 @@ circle_poly(PG_FUNCTION_ARGS) int base_size, size; int i; - double angle; - double anglestep; + float8 angle; + float8 anglestep; if (FPzero(circle->radius)) ereport(ERROR, @@ -5183,13 +5248,16 @@ circle_poly(PG_FUNCTION_ARGS) SET_VARSIZE(poly, size); poly->npts = npts; - anglestep = (2.0 * M_PI) / npts; + anglestep = float8_div(2.0 * M_PI, npts); for (i = 0; i < npts; i++) { - angle = i * anglestep; - poly->p[i].x = circle->center.x - (circle->radius * cos(angle)); - poly->p[i].y = circle->center.y + (circle->radius * sin(angle)); + angle = float8_mul(anglestep, i); + + poly->p[i].x = float8_mi(circle->center.x, + float8_mul(circle->radius, cos(angle))); + poly->p[i].y = float8_pl(circle->center.y, + float8_mul(circle->radius, sin(angle))); } make_bound_box(poly); @@ -5197,42 +5265,47 @@ circle_poly(PG_FUNCTION_ARGS) PG_RETURN_POLYGON_P(poly); } -/* poly_circle - convert polygon to circle +/* + * Convert polygon to circle + * + * The result must be preallocated. * * XXX This algorithm should use weighted means of line segments * rather than straight average values of points - tgl 97/01/21. */ -Datum -poly_circle(PG_FUNCTION_ARGS) +static void +poly_to_circle(CIRCLE *result, POLYGON *poly) { - POLYGON *poly = PG_GETARG_POLYGON_P(0); - CIRCLE *circle; int i; - if (poly->npts < 1) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("cannot convert empty polygon to circle"))); - - circle = (CIRCLE *) palloc(sizeof(CIRCLE)); + Assert(poly->npts > 0); - circle->center.x = 0; - circle->center.y = 0; - circle->radius = 0; + result->center.x = 0; + result->center.y = 0; + result->radius = 0; for (i = 0; i < poly->npts; i++) - { - circle->center.x += poly->p[i].x; - circle->center.y += poly->p[i].y; - } - circle->center.x /= poly->npts; - circle->center.y /= poly->npts; + point_add_point(&result->center, &result->center, &poly->p[i]); + result->center.x = float8_div(result->center.x, poly->npts); + result->center.y = float8_div(result->center.y, poly->npts); for (i = 0; i < poly->npts; i++) - circle->radius += point_dt(&poly->p[i], &circle->center); - circle->radius /= poly->npts; + result->radius = float8_pl(result->radius, + point_dt(&poly->p[i], &result->center)); + result->radius = float8_div(result->radius, poly->npts); +} - PG_RETURN_CIRCLE_P(circle); +Datum +poly_circle(PG_FUNCTION_ARGS) +{ + POLYGON *poly = PG_GETARG_POLYGON_P(0); + CIRCLE *result; + + result = (CIRCLE *) palloc(sizeof(CIRCLE)); + + poly_to_circle(result, poly); + + PG_RETURN_CIRCLE_P(result); } @@ -5258,22 +5331,21 @@ poly_circle(PG_FUNCTION_ARGS) static int point_inside(Point *p, int npts, Point *plist) { - double x0, + float8 x0, y0; - double prev_x, + float8 prev_x, prev_y; int i = 0; - double x, + float8 x, y; int cross, total_cross = 0; - if (npts <= 0) - return 0; + Assert(npts > 0); /* compute first polygon point relative to single point */ - x0 = plist[0].x - p->x; - y0 = plist[0].y - p->y; + x0 = float8_mi(plist[0].x, p->x); + y0 = float8_mi(plist[0].y, p->y); prev_x = x0; prev_y = y0; @@ -5281,8 +5353,8 @@ point_inside(Point *p, int npts, Point *plist) for (i = 1; i < npts; i++) { /* compute next polygon point relative to single point */ - x = plist[i].x - p->x; - y = plist[i].y - p->y; + x = float8_mi(plist[i].x, p->x); + y = float8_mi(plist[i].y, p->y); /* compute previous to current point crossing */ if ((cross = lseg_crossing(x, y, prev_x, prev_y)) == POINT_ON_POLYGON) @@ -5314,9 +5386,9 @@ point_inside(Point *p, int npts, Point *plist) */ static int -lseg_crossing(double x, double y, double prev_x, double prev_y) +lseg_crossing(float8 x, float8 y, float8 prev_x, float8 prev_y) { - double z; + float8 z; int y_sign; if (FPzero(y)) @@ -5327,42 +5399,47 @@ lseg_crossing(double x, double y, double prev_x, double prev_y) { /* x > 0 */ if (FPzero(prev_y)) /* y and prev_y are zero */ /* prev_x > 0? */ - return FPgt(prev_x, 0) ? 0 : POINT_ON_POLYGON; - return FPlt(prev_y, 0) ? 1 : -1; + return FPgt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON; + return FPlt(prev_y, 0.0) ? 1 : -1; } else { /* x < 0, x not on positive X axis */ if (FPzero(prev_y)) /* prev_x < 0? */ - return FPlt(prev_x, 0) ? 0 : POINT_ON_POLYGON; + return FPlt(prev_x, 0.0) ? 0 : POINT_ON_POLYGON; return 0; } } else { /* y != 0 */ /* compute y crossing direction from previous point */ - y_sign = FPgt(y, 0) ? 1 : -1; + y_sign = FPgt(y, 0.0) ? 1 : -1; if (FPzero(prev_y)) /* previous point was on X axis, so new point is either off or on */ - return FPlt(prev_x, 0) ? 0 : y_sign; - else if (FPgt(y_sign * prev_y, 0)) + return FPlt(prev_x, 0.0) ? 0 : y_sign; + else if ((y_sign < 0 && FPlt(prev_y, 0.0)) || + (y_sign > 0 && FPgt(prev_y, 0.0))) /* both above or below X axis */ return 0; /* same sign */ else { /* y and prev_y cross X-axis */ - if (FPge(x, 0) && FPgt(prev_x, 0)) + if (FPge(x, 0.0) && FPgt(prev_x, 0.0)) /* both non-negative so cross positive X-axis */ return 2 * y_sign; - if (FPlt(x, 0) && FPle(prev_x, 0)) + if (FPlt(x, 0.0) && FPle(prev_x, 0.0)) /* both non-positive so do not cross positive X-axis */ return 0; - /* x and y cross axises, see URL above point_inside() */ - z = (x - prev_x) * y - (y - prev_y) * x; + /* x and y cross axes, see URL above point_inside() */ + z = float8_mi(float8_mul(float8_mi(x, prev_x), y), + float8_mul(float8_mi(y, prev_y), x)); if (FPzero(z)) return POINT_ON_POLYGON; - return FPgt((y_sign * z), 0) ? 0 : 2 * y_sign; + if ((y_sign < 0 && FPlt(z, 0.0)) || + (y_sign > 0 && FPgt(z, 0.0))) + return 0; + return 2 * y_sign; } } } @@ -5378,8 +5455,7 @@ plist_same(int npts, Point *p1, Point *p2) /* find match for first point */ for (i = 0; i < npts; i++) { - if ((FPeq(p2[i].x, p1[0].x)) - && (FPeq(p2[i].y, p1[0].y))) + if (point_eq_point(&p2[i], &p1[0])) { /* match found? then look forward through remaining points */ @@ -5387,18 +5463,9 @@ plist_same(int npts, Point *p1, Point *p2) { if (j >= npts) j = 0; - if ((!FPeq(p2[j].x, p1[ii].x)) - || (!FPeq(p2[j].y, p1[ii].y))) - { -#ifdef GEODEBUG - printf("plist_same- %d failed forward match with %d\n", j, ii); -#endif + if (!point_eq_point(&p2[j], &p1[ii])) break; - } } -#ifdef GEODEBUG - printf("plist_same- ii = %d/%d after forward match\n", ii, npts); -#endif if (ii == npts) return true; @@ -5407,18 +5474,9 @@ plist_same(int npts, Point *p1, Point *p2) { if (j < 0) j = (npts - 1); - if ((!FPeq(p2[j].x, p1[ii].x)) - || (!FPeq(p2[j].y, p1[ii].y))) - { -#ifdef GEODEBUG - printf("plist_same- %d failed reverse match with %d\n", j, ii); -#endif + if (!point_eq_point(&p2[j], &p1[ii])) break; - } } -#ifdef GEODEBUG - printf("plist_same- ii = %d/%d after reverse match\n", ii, npts); -#endif if (ii == npts) return true; } @@ -5449,10 +5507,11 @@ plist_same(int npts, Point *p1, Point *p2) * case of hypot(inf,nan) results in INF, and not NAN. *----------------------------------------------------------------------- */ -double -pg_hypot(double x, double y) +float8 +pg_hypot(float8 x, float8 y) { - double yx; + float8 yx, + result; /* Handle INF and NaN properly */ if (isinf(x) || isinf(y)) @@ -5468,7 +5527,7 @@ pg_hypot(double x, double y) /* Swap x and y if needed to make x the larger one */ if (x < y) { - double temp = x; + float8 temp = x; x = y; y = temp; @@ -5484,5 +5543,9 @@ pg_hypot(double x, double y) /* Determine the hypotenuse */ yx = y / x; - return x * sqrt(1.0 + (yx * yx)); + result = x * sqrt(1.0 + (yx * yx)); + + check_float8_val(result, false, false); + + return result; } diff --git a/src/backend/utils/adt/geo_selfuncs.c b/src/backend/utils/adt/geo_selfuncs.c index 02a8853d755..0d908660eb7 100644 --- a/src/backend/utils/adt/geo_selfuncs.c +++ b/src/backend/utils/adt/geo_selfuncs.c @@ -4,7 +4,7 @@ * Selectivity routines registered in the operator catalog in the * "oprrest" and "oprjoin" attributes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c index 3f1a755cbb3..8e29770422a 100644 --- a/src/backend/utils/adt/geo_spgist.c +++ b/src/backend/utils/adt/geo_spgist.c @@ -35,10 +35,10 @@ * * We are using traversal values provided by SP-GiST to calculate and * to store the bounds of the quadrants, while traversing into the tree. - * Traversal value has all the boundaries in the 4D space, and is is - * capable of transferring the required boundaries to the following - * traversal values. In conclusion, three things are necessary - * to calculate the next traversal value: + * Traversal value has all the boundaries in the 4D space, and is capable + * of transferring the required boundaries to the following traversal + * values. In conclusion, three things are necessary to calculate the + * next traversal value: * * (1) the traversal value of the parent * (2) the quadrant of the current node @@ -62,7 +62,7 @@ * except the root. For the root node, we are setting the boundaries * that we don't yet have as infinity. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -74,23 +74,26 @@ #include "postgres.h" #include "access/spgist.h" +#include "access/spgist_private.h" #include "access/stratnum.h" #include "catalog/pg_type.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgroids.h" +#include "utils/fmgrprotos.h" #include "utils/geo_decls.h" /* * Comparator for qsort * * We don't need to use the floating point macros in here, because this - * is going only going to be used in a place to effect the performance + * is only going to be used in a place to effect the performance * of the index, not the correctness. */ static int compareDoubles(const void *a, const void *b) { - double x = *(double *) a; - double y = *(double *) b; + float8 x = *(float8 *) a; + float8 y = *(float8 *) b; if (x == y) return 0; @@ -99,8 +102,8 @@ compareDoubles(const void *a, const void *b) typedef struct { - double low; - double high; + float8 low; + float8 high; } Range; typedef struct @@ -174,7 +177,7 @@ static RectBox * initRectBox(void) { RectBox *rect_box = (RectBox *) palloc(sizeof(RectBox)); - double infinity = get_float8_infinity(); + float8 infinity = get_float8_infinity(); rect_box->range_box_x.left.low = -infinity; rect_box->range_box_x.left.high = infinity; @@ -366,6 +369,31 @@ overAbove4D(RectBox *rect_box, RangeBox *query) return overHigher2D(&rect_box->range_box_y, &query->right); } +/* Lower bound for the distance between point and rect_box */ +static double +pointToRectBoxDistance(Point *point, RectBox *rect_box) +{ + double dx; + double dy; + + if (point->x < rect_box->range_box_x.left.low) + dx = rect_box->range_box_x.left.low - point->x; + else if (point->x > rect_box->range_box_x.right.high) + dx = point->x - rect_box->range_box_x.right.high; + else + dx = 0; + + if (point->y < rect_box->range_box_y.left.low) + dy = rect_box->range_box_y.left.low - point->y; + else if (point->y > rect_box->range_box_y.right.high) + dy = point->y - rect_box->range_box_y.right.high; + else + dy = 0; + + return HYPOT(dx, dy); +} + + /* * SP-GiST config function */ @@ -417,10 +445,10 @@ spg_box_quad_picksplit(PG_FUNCTION_ARGS) BOX *centroid; int median, i; - double *lowXs = palloc(sizeof(double) * in->nTuples); - double *highXs = palloc(sizeof(double) * in->nTuples); - double *lowYs = palloc(sizeof(double) * in->nTuples); - double *highYs = palloc(sizeof(double) * in->nTuples); + float8 *lowXs = palloc(sizeof(float8) * in->nTuples); + float8 *highXs = palloc(sizeof(float8) * in->nTuples); + float8 *lowYs = palloc(sizeof(float8) * in->nTuples); + float8 *highYs = palloc(sizeof(float8) * in->nTuples); /* Calculate median of all 4D coordinates */ for (i = 0; i < in->nTuples; i++) @@ -433,10 +461,10 @@ spg_box_quad_picksplit(PG_FUNCTION_ARGS) highYs[i] = box->high.y; } - qsort(lowXs, in->nTuples, sizeof(double), compareDoubles); - qsort(highXs, in->nTuples, sizeof(double), compareDoubles); - qsort(lowYs, in->nTuples, sizeof(double), compareDoubles); - qsort(highYs, in->nTuples, sizeof(double), compareDoubles); + qsort(lowXs, in->nTuples, sizeof(float8), compareDoubles); + qsort(highXs, in->nTuples, sizeof(float8), compareDoubles); + qsort(lowYs, in->nTuples, sizeof(float8), compareDoubles); + qsort(highYs, in->nTuples, sizeof(float8), compareDoubles); median = in->nTuples / 2; @@ -533,6 +561,15 @@ spg_box_quad_inner_consistent(PG_FUNCTION_ARGS) RangeBox *centroid, **queries; + /* + * We are saving the traversal value or initialize it an unbounded one, if + * we have just begun to walk the tree. + */ + if (in->traversalValue) + rect_box = in->traversalValue; + else + rect_box = initRectBox(); + if (in->allTheSame) { /* Report that all nodes should be visited */ @@ -541,18 +578,32 @@ spg_box_quad_inner_consistent(PG_FUNCTION_ARGS) for (i = 0; i < in->nNodes; i++) out->nodeNumbers[i] = i; + if (in->norderbys > 0 && in->nNodes > 0) + { + double *distances = palloc(sizeof(double) * in->norderbys); + int j; + + for (j = 0; j < in->norderbys; j++) + { + Point *pt = DatumGetPointP(in->orderbys[j].sk_argument); + + distances[j] = pointToRectBoxDistance(pt, rect_box); + } + + out->distances = (double **) palloc(sizeof(double *) * in->nNodes); + out->distances[0] = distances; + + for (i = 1; i < in->nNodes; i++) + { + out->distances[i] = palloc(sizeof(double) * in->norderbys); + memcpy(out->distances[i], distances, + sizeof(double) * in->norderbys); + } + } + PG_RETURN_VOID(); } - /* - * We are saving the traversal value or initialize it an unbounded one, if - * we have just begun to walk the tree. - */ - if (in->traversalValue) - rect_box = in->traversalValue; - else - rect_box = initRectBox(); - /* * We are casting the prefix and queries to RangeBoxes for ease of the * following operations. @@ -570,6 +621,8 @@ spg_box_quad_inner_consistent(PG_FUNCTION_ARGS) out->nNodes = 0; out->nodeNumbers = (int *) palloc(sizeof(int) * in->nNodes); out->traversalValues = (void **) palloc(sizeof(void *) * in->nNodes); + if (in->norderbys > 0) + out->distances = (double **) palloc(sizeof(double *) * in->nNodes); /* * We switch memory context, because we want to allocate memory for new @@ -647,6 +700,22 @@ spg_box_quad_inner_consistent(PG_FUNCTION_ARGS) { out->traversalValues[out->nNodes] = next_rect_box; out->nodeNumbers[out->nNodes] = quadrant; + + if (in->norderbys > 0) + { + double *distances = palloc(sizeof(double) * in->norderbys); + int j; + + out->distances[out->nNodes] = distances; + + for (j = 0; j < in->norderbys; j++) + { + Point *pt = DatumGetPointP(in->orderbys[j].sk_argument); + + distances[j] = pointToRectBoxDistance(pt, next_rect_box); + } + } + out->nNodes++; } else @@ -686,10 +755,10 @@ spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS) /* Perform the required comparison(s) */ for (i = 0; i < in->nkeys; i++) { - StrategyNumber strategy = in->scankeys[i].sk_strategy; - BOX *box = spg_box_quad_get_scankey_bbox(&in->scankeys[i], - &out->recheck); - Datum query = BoxPGetDatum(box); + StrategyNumber strategy = in->scankeys[i].sk_strategy; + BOX *box = spg_box_quad_get_scankey_bbox(&in->scankeys[i], + &out->recheck); + Datum query = BoxPGetDatum(box); switch (strategy) { @@ -762,6 +831,17 @@ spg_box_quad_leaf_consistent(PG_FUNCTION_ARGS) break; } + if (flag && in->norderbys > 0) + { + Oid distfnoid = in->orderbys[0].sk_func.fn_oid; + + out->distances = spg_key_orderbys_distances(leaf, false, + in->orderbys, in->norderbys); + + /* Recheck is necessary when computing distance to polygon */ + out->recheckDistances = distfnoid == F_DIST_POLYP; + } + PG_RETURN_BOOL(flag); } @@ -790,10 +870,11 @@ spg_bbox_quad_config(PG_FUNCTION_ARGS) Datum spg_poly_quad_compress(PG_FUNCTION_ARGS) { - POLYGON *polygon = PG_GETARG_POLYGON_P(0); + POLYGON *polygon = PG_GETARG_POLYGON_P(0); BOX *box; - box = box_copy(&polygon->boundbox); + box = (BOX *) palloc(sizeof(BOX)); + *box = polygon->boundbox; PG_RETURN_BOX_P(box); } diff --git a/src/backend/utils/adt/inet_cidr_ntop.c b/src/backend/utils/adt/inet_cidr_ntop.c index 30b3673789f..5f74c05a65d 100644 --- a/src/backend/utils/adt/inet_cidr_ntop.c +++ b/src/backend/utils/adt/inet_cidr_ntop.c @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * src/backend/utils/adt/inet_net_ntop.c + * src/backend/utils/adt/inet_cidr_ntop.c */ #if defined(LIBC_SCCS) && !defined(lint) @@ -38,13 +38,13 @@ static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 m #endif static char *inet_cidr_ntop_ipv4(const u_char *src, int bits, - char *dst, size_t size); + char *dst, size_t size); static char *inet_cidr_ntop_ipv6(const u_char *src, int bits, - char *dst, size_t size); + char *dst, size_t size); /* * char * - * inet_cidr_ntop(af, src, bits, dst, size) + * pg_inet_cidr_ntop(af, src, bits, dst, size) * convert network number from network to presentation format. * generates CIDR style result always. * return: @@ -53,7 +53,7 @@ static char *inet_cidr_ntop_ipv6(const u_char *src, int bits, * Paul Vixie (ISC), July 1996 */ char * -inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) +pg_inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) { switch (af) { @@ -146,7 +146,7 @@ inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) /* * static char * - * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size) + * inet_cidr_ntop_ipv6(src, bits, dst, size) * convert IPv6 network number from network to presentation format. * generates CIDR style result always. Picks the shortest representation * unless the IP is really IPv4. @@ -202,7 +202,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) b = bits % 8; if (b != 0) { - m = ~0 << (8 - b); + m = ((u_int) ~0) << (8 - b); inbuf[p - 1] &= m; } diff --git a/src/backend/utils/adt/inet_net_pton.c b/src/backend/utils/adt/inet_net_pton.c index 6f3ece1209c..d3221a13139 100644 --- a/src/backend/utils/adt/inet_net_pton.c +++ b/src/backend/utils/adt/inet_net_pton.c @@ -42,7 +42,7 @@ static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size); /* * int - * inet_net_pton(af, src, dst, size) + * pg_inet_net_pton(af, src, dst, size) * convert network number from presentation to network format. * accepts hex octets, hex strings, decimal octets, and /CIDR. * "size" is in bytes and describes "dst". @@ -59,7 +59,7 @@ static int inet_cidr_pton_ipv6(const char *src, u_char *dst, size_t size); * */ int -inet_net_pton(int af, const char *src, void *dst, size_t size) +pg_inet_net_pton(int af, const char *src, void *dst, size_t size) { switch (af) { @@ -189,7 +189,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) goto emsgsize; } - /* Firey death and destruction unless we prefetched EOS. */ + /* Fiery death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; @@ -241,7 +241,7 @@ inet_cidr_pton_ipv4(const char *src, u_char *dst, size_t size) /* * int - * inet_net_pton(af, src, dst, *bits) + * inet_net_pton_ipv4(af, src, dst, *bits) * convert network address from presentation to network format. * accepts inet_pton()'s input for this "af" plus trailing "/CIDR". * "dst" is assumed large enough for its "af". "bits" is set to the @@ -309,7 +309,7 @@ inet_net_pton_ipv4(const char *src, u_char *dst) goto emsgsize; } - /* Firey death and destruction unless we prefetched EOS. */ + /* Fiery death and destruction unless we prefetched EOS. */ if (ch != '\0') goto enoent; diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c index 559c365fecd..04825fc77de 100644 --- a/src/backend/utils/adt/int.c +++ b/src/backend/utils/adt/int.c @@ -3,7 +3,7 @@ * int.c * Functions for the built-in integer types (except int8). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,11 +30,15 @@ #include #include +#include #include "catalog/pg_type.h" #include "common/int.h" #include "funcapi.h" #include "libpq/pqformat.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" +#include "optimizer/optimizer.h" #include "utils/array.h" #include "utils/builtins.h" @@ -60,7 +64,7 @@ int2in(PG_FUNCTION_ARGS) { char *num = PG_GETARG_CSTRING(0); - PG_RETURN_INT16(pg_atoi(num, sizeof(int16), '\0')); + PG_RETURN_INT16(pg_strtoint16(num)); } /* @@ -201,8 +205,8 @@ int2vectorout(PG_FUNCTION_ARGS) Datum int2vectorrecv(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(locfcinfo, 3); StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - FunctionCallInfoData locfcinfo; int2vector *result; /* @@ -211,19 +215,19 @@ int2vectorrecv(PG_FUNCTION_ARGS) * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo * parameter. */ - InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, + InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3, InvalidOid, NULL, NULL); - locfcinfo.arg[0] = PointerGetDatum(buf); - locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID); - locfcinfo.arg[2] = Int32GetDatum(-1); - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.argnull[2] = false; + locfcinfo->args[0].value = PointerGetDatum(buf); + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = ObjectIdGetDatum(INT2OID); + locfcinfo->args[1].isnull = false; + locfcinfo->args[2].value = Int32GetDatum(-1); + locfcinfo->args[2].isnull = false; - result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo)); + result = (int2vector *) DatumGetPointer(array_recv(locfcinfo)); - Assert(!locfcinfo.isnull); + Assert(!locfcinfo->isnull); /* sanity checks: int2vector must be 1-D, 0-based, no nulls */ if (ARR_NDIM(result) != 1 || @@ -265,7 +269,7 @@ int4in(PG_FUNCTION_ARGS) { char *num = PG_GETARG_CSTRING(0); - PG_RETURN_INT32(pg_atoi(num, sizeof(int32), '\0')); + PG_RETURN_INT32(pg_strtoint32(num)); } /* @@ -608,7 +612,7 @@ in_range_int4_int4(PG_FUNCTION_ARGS) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); if (sub) @@ -655,7 +659,7 @@ in_range_int4_int8(PG_FUNCTION_ARGS) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); if (sub) @@ -690,7 +694,7 @@ in_range_int2_int4(PG_FUNCTION_ARGS) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); if (sub) @@ -1427,3 +1431,73 @@ generate_series_step_int4(PG_FUNCTION_ARGS) /* do when there is no more left */ SRF_RETURN_DONE(funcctx); } + +/* + * Planner support function for generate_series(int4, int4 [, int4]) + */ +Datum +generate_series_int4_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestRows)) + { + /* Try to estimate the number of rows returned */ + SupportRequestRows *req = (SupportRequestRows *) rawreq; + + if (is_funcclause(req->node)) /* be paranoid */ + { + List *args = ((FuncExpr *) req->node)->args; + Node *arg1, + *arg2, + *arg3; + + /* We can use estimated argument values here */ + arg1 = estimate_expression_value(req->root, linitial(args)); + arg2 = estimate_expression_value(req->root, lsecond(args)); + if (list_length(args) >= 3) + arg3 = estimate_expression_value(req->root, lthird(args)); + else + arg3 = NULL; + + /* + * If any argument is constant NULL, we can safely assume that + * zero rows are returned. Otherwise, if they're all non-NULL + * constants, we can calculate the number of rows that will be + * returned. Use double arithmetic to avoid overflow hazards. + */ + if ((IsA(arg1, Const) && + ((Const *) arg1)->constisnull) || + (IsA(arg2, Const) && + ((Const *) arg2)->constisnull) || + (arg3 != NULL && IsA(arg3, Const) && + ((Const *) arg3)->constisnull)) + { + req->rows = 0; + ret = (Node *) req; + } + else if (IsA(arg1, Const) && + IsA(arg2, Const) && + (arg3 == NULL || IsA(arg3, Const))) + { + double start, + finish, + step; + + start = DatumGetInt32(((Const *) arg1)->constvalue); + finish = DatumGetInt32(((Const *) arg2)->constvalue); + step = arg3 ? DatumGetInt32(((Const *) arg3)->constvalue) : 1; + + /* This equation works for either sign of step */ + if (step != 0) + { + req->rows = floor((finish - start + step) / step); + ret = (Node *) req; + } + } + } + } + + PG_RETURN_POINTER(ret); +} diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c index e6bae6860da..0ff9394a2fb 100644 --- a/src/backend/utils/adt/int8.c +++ b/src/backend/utils/adt/int8.c @@ -3,7 +3,7 @@ * int8.c * Internal 64-bit integer operations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,13 +14,15 @@ #include "postgres.h" #include -#include /* for _isnan */ #include #include #include "common/int.h" #include "funcapi.h" #include "libpq/pqformat.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" +#include "optimizer/optimizer.h" #include "utils/int8.h" #include "utils/builtins.h" @@ -102,6 +104,7 @@ scanint8(const char *str, bool errorOK, int64 *result) if (!neg) { + /* could fail if input is most negative number */ if (unlikely(tmp == PG_INT64_MIN)) goto out_of_range; tmp = -tmp; @@ -122,8 +125,8 @@ scanint8(const char *str, bool errorOK, int64 *result) if (!errorOK) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for integer: \"%s\"", - str))); + errmsg("invalid input syntax for type %s: \"%s\"", + "bigint", str))); return false; } @@ -487,7 +490,7 @@ in_range_int8_int8(PG_FUNCTION_ARGS) if (offset < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); if (sub) @@ -1204,22 +1207,29 @@ i8tod(PG_FUNCTION_ARGS) Datum dtoi8(PG_FUNCTION_ARGS) { - float8 arg = PG_GETARG_FLOAT8(0); - int64 result; + float8 num = PG_GETARG_FLOAT8(0); - /* Round arg to nearest integer (but it's still in float form) */ - arg = rint(arg); + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); - if (unlikely(arg < (double) PG_INT64_MIN) || - unlikely(arg > (double) PG_INT64_MAX) || - unlikely(isnan(arg))) + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT64_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT64_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float8) PG_INT64_MIN || + num >= -((float8) PG_INT64_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); - result = (int64) arg; - - PG_RETURN_INT64(result); + PG_RETURN_INT64((int64) num); } Datum @@ -1239,20 +1249,29 @@ i8tof(PG_FUNCTION_ARGS) Datum ftoi8(PG_FUNCTION_ARGS) { - float4 arg = PG_GETARG_FLOAT4(0); - float8 darg; + float4 num = PG_GETARG_FLOAT4(0); - /* Round arg to nearest integer (but it's still in float form) */ - darg = rint(arg); + /* + * Get rid of any fractional part in the input. This is so we don't fail + * on just-out-of-range values that would round into range. Note + * assumption that rint() will pass through a NaN or Inf unchanged. + */ + num = rint(num); - if (unlikely(arg < (float4) PG_INT64_MIN) || - unlikely(arg > (float4) PG_INT64_MAX) || - unlikely(isnan(arg))) + /* + * Range check. We must be careful here that the boundary values are + * expressed exactly in the float domain. We expect PG_INT64_MIN to be an + * exact power of 2, so it will be represented exactly; but PG_INT64_MAX + * isn't, and might get rounded off, so avoid using it. + */ + if (unlikely(num < (float4) PG_INT64_MIN || + num >= -((float4) PG_INT64_MIN) || + isnan(num))) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("bigint out of range"))); - PG_RETURN_INT64((int64) darg); + PG_RETURN_INT64((int64) num); } Datum @@ -1357,3 +1376,73 @@ generate_series_step_int8(PG_FUNCTION_ARGS) /* do when there is no more left */ SRF_RETURN_DONE(funcctx); } + +/* + * Planner support function for generate_series(int8, int8 [, int8]) + */ +Datum +generate_series_int8_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestRows)) + { + /* Try to estimate the number of rows returned */ + SupportRequestRows *req = (SupportRequestRows *) rawreq; + + if (is_funcclause(req->node)) /* be paranoid */ + { + List *args = ((FuncExpr *) req->node)->args; + Node *arg1, + *arg2, + *arg3; + + /* We can use estimated argument values here */ + arg1 = estimate_expression_value(req->root, linitial(args)); + arg2 = estimate_expression_value(req->root, lsecond(args)); + if (list_length(args) >= 3) + arg3 = estimate_expression_value(req->root, lthird(args)); + else + arg3 = NULL; + + /* + * If any argument is constant NULL, we can safely assume that + * zero rows are returned. Otherwise, if they're all non-NULL + * constants, we can calculate the number of rows that will be + * returned. Use double arithmetic to avoid overflow hazards. + */ + if ((IsA(arg1, Const) && + ((Const *) arg1)->constisnull) || + (IsA(arg2, Const) && + ((Const *) arg2)->constisnull) || + (arg3 != NULL && IsA(arg3, Const) && + ((Const *) arg3)->constisnull)) + { + req->rows = 0; + ret = (Node *) req; + } + else if (IsA(arg1, Const) && + IsA(arg2, Const) && + (arg3 == NULL || IsA(arg3, Const))) + { + double start, + finish, + step; + + start = DatumGetInt64(((Const *) arg1)->constvalue); + finish = DatumGetInt64(((Const *) arg2)->constvalue); + step = arg3 ? DatumGetInt64(((Const *) arg3)->constvalue) : 1; + + /* This equation works for either sign of step */ + if (step != 0) + { + req->rows = floor((finish - start + step) / step); + ret = (Node *) req; + } + } + } + } + + PG_RETURN_POINTER(ret); +} diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index 6f0fe94d63f..d4ba3bd87db 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -3,7 +3,7 @@ * json.c * JSON data type support. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -78,7 +78,7 @@ typedef struct JsonAggState static inline void json_lex(JsonLexContext *lex); static inline void json_lex_string(JsonLexContext *lex); static inline void json_lex_number(JsonLexContext *lex, char *s, - bool *num_err, int *total_len); + bool *num_err, int *total_len); static inline void parse_scalar(JsonLexContext *lex, JsonSemAction *sem); static void parse_object_field(JsonLexContext *lex, JsonSemAction *sem); static void parse_object(JsonLexContext *lex, JsonSemAction *sem); @@ -89,21 +89,21 @@ static void report_invalid_token(JsonLexContext *lex) pg_attribute_noreturn(); static int report_json_context(JsonLexContext *lex); static char *extract_mb_char(char *s); static void composite_to_json(Datum composite, StringInfo result, - bool use_line_feeds); + bool use_line_feeds); static void array_dim_to_json(StringInfo result, int dim, int ndims, int *dims, - Datum *vals, bool *nulls, int *valcount, - JsonTypeCategory tcategory, Oid outfuncoid, - bool use_line_feeds); + Datum *vals, bool *nulls, int *valcount, + JsonTypeCategory tcategory, Oid outfuncoid, + bool use_line_feeds); static void array_to_json_internal(Datum array, StringInfo result, - bool use_line_feeds); + bool use_line_feeds); static void json_categorize_type(Oid typoid, - JsonTypeCategory *tcategory, - Oid *outfuncoid); + JsonTypeCategory *tcategory, + Oid *outfuncoid); static void datum_to_json(Datum val, bool is_null, StringInfo result, - JsonTypeCategory tcategory, Oid outfuncoid, - bool key_scalar); + JsonTypeCategory tcategory, Oid outfuncoid, + bool key_scalar); static void add_json(Datum val, bool is_null, StringInfo result, - Oid val_type, bool key_scalar); + Oid val_type, bool key_scalar); static text *catenate_stringinfo_string(StringInfo buffer, const char *addon); /* the null action object used for pure validation */ @@ -207,12 +207,12 @@ IsValidJsonNumber(const char *str, int len) */ if (*str == '-') { - dummy_lex.input = (char *) str + 1; + dummy_lex.input = unconstify(char *, str) +1; dummy_lex.input_length = len - 1; } else { - dummy_lex.input = (char *) str; + dummy_lex.input = unconstify(char *, str); dummy_lex.input_length = len; } @@ -1506,7 +1506,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result, { char buf[MAXDATELEN + 1]; - JsonEncodeDateTime(buf, val, DATEOID); + JsonEncodeDateTime(buf, val, DATEOID, NULL); appendStringInfo(result, "\"%s\"", buf); } break; @@ -1514,7 +1514,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result, { char buf[MAXDATELEN + 1]; - JsonEncodeDateTime(buf, val, TIMESTAMPOID); + JsonEncodeDateTime(buf, val, TIMESTAMPOID, NULL); appendStringInfo(result, "\"%s\"", buf); } break; @@ -1522,7 +1522,7 @@ datum_to_json(Datum val, bool is_null, StringInfo result, { char buf[MAXDATELEN + 1]; - JsonEncodeDateTime(buf, val, TIMESTAMPTZOID); + JsonEncodeDateTime(buf, val, TIMESTAMPTZOID, NULL); appendStringInfo(result, "\"%s\"", buf); } break; @@ -1550,10 +1550,11 @@ datum_to_json(Datum val, bool is_null, StringInfo result, /* * Encode 'value' of datetime type 'typid' into JSON string in ISO format using - * optionally preallocated buffer 'buf'. + * optionally preallocated buffer 'buf'. Optional 'tzp' determines time-zone + * offset (in seconds) in which we want to show timestamptz. */ char * -JsonEncodeDateTime(char *buf, Datum value, Oid typid) +JsonEncodeDateTime(char *buf, Datum value, Oid typid, const int *tzp) { if (!buf) buf = palloc(MAXDATELEN + 1); @@ -1630,11 +1631,30 @@ JsonEncodeDateTime(char *buf, Datum value, Oid typid) const char *tzn = NULL; timestamp = DatumGetTimestampTz(value); + + /* + * If a time zone is specified, we apply the time-zone shift, + * convert timestamptz to pg_tm as if it were without a time + * zone, and then use the specified time zone for converting + * the timestamp into a string. + */ + if (tzp) + { + tz = *tzp; + timestamp -= (TimestampTz) tz * USECS_PER_SEC; + } + /* Same as timestamptz_out(), but forcing DateStyle */ if (TIMESTAMP_NOT_FINITE(timestamp)) EncodeSpecialTimestamp(timestamp, buf); - else if (timestamp2tm(timestamp, &tz, &tm, &fsec, &tzn, NULL) == 0) + else if (timestamp2tm(timestamp, tzp ? NULL : &tz, &tm, &fsec, + tzp ? NULL : &tzn, NULL) == 0) + { + if (tzp) + tm.tm_isdst = 1; /* set time-zone presence flag */ + EncodeDateTime(&tm, fsec, true, tz, tzn, USE_XSD_DATES, buf); + } else ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), @@ -2192,7 +2212,9 @@ json_build_object(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument list must have even number of elements"), - errhint("The arguments of json_build_object() must consist of alternating keys and values."))); + /* translator: %s is a SQL function name */ + errhint("The arguments of %s must consist of alternating keys and values.", + "json_build_object()"))); result = makeStringInfo(); diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c index 80d23cc0524..74b4bbe44c6 100644 --- a/src/backend/utils/adt/jsonb.c +++ b/src/backend/utils/adt/jsonb.c @@ -3,7 +3,7 @@ * jsonb.c * I/O routines for jsonb type * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/jsonb.c @@ -71,21 +71,21 @@ static void jsonb_in_object_field_start(void *pstate, char *fname, bool isnull); static void jsonb_put_escaped_value(StringInfo out, JsonbValue *scalarVal); static void jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype); static void jsonb_categorize_type(Oid typoid, - JsonbTypeCategory *tcategory, - Oid *outfuncoid); + JsonbTypeCategory *tcategory, + Oid *outfuncoid); static void composite_to_jsonb(Datum composite, JsonbInState *result); static void array_dim_to_jsonb(JsonbInState *result, int dim, int ndims, int *dims, - Datum *vals, bool *nulls, int *valcount, - JsonbTypeCategory tcategory, Oid outfuncoid); + Datum *vals, bool *nulls, int *valcount, + JsonbTypeCategory tcategory, Oid outfuncoid); static void array_to_jsonb_internal(Datum array, JsonbInState *result); static void jsonb_categorize_type(Oid typoid, - JsonbTypeCategory *tcategory, - Oid *outfuncoid); + JsonbTypeCategory *tcategory, + Oid *outfuncoid); static void datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, - JsonbTypeCategory tcategory, Oid outfuncoid, - bool key_scalar); + JsonbTypeCategory tcategory, Oid outfuncoid, + bool key_scalar); static void add_jsonb(Datum val, bool is_null, JsonbInState *result, - Oid val_type, bool key_scalar); + Oid val_type, bool key_scalar); static JsonbParseState *clone_parse_state(JsonbParseState *state); static char *JsonbToCStringWorker(StringInfo out, JsonbContainer *in, int estimated_len, bool indent); static void add_indent(StringInfo out, bool indent, int level); @@ -163,6 +163,73 @@ jsonb_send(PG_FUNCTION_ARGS) PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } +/* + * Get the type name of a jsonb container. + */ +static const char * +JsonbContainerTypeName(JsonbContainer *jbc) +{ + JsonbValue scalar; + + if (JsonbExtractScalar(jbc, &scalar)) + return JsonbTypeName(&scalar); + else if (JsonContainerIsArray(jbc)) + return "array"; + else if (JsonContainerIsObject(jbc)) + return "object"; + else + { + elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header); + return "unknown"; + } +} + +/* + * Get the type name of a jsonb value. + */ +const char * +JsonbTypeName(JsonbValue *jbv) +{ + switch (jbv->type) + { + case jbvBinary: + return JsonbContainerTypeName(jbv->val.binary.data); + case jbvObject: + return "object"; + case jbvArray: + return "array"; + case jbvNumeric: + return "number"; + case jbvString: + return "string"; + case jbvBool: + return "boolean"; + case jbvNull: + return "null"; + case jbvDatetime: + switch (jbv->val.datetime.typid) + { + case DATEOID: + return "date"; + case TIMEOID: + return "time without time zone"; + case TIMETZOID: + return "time with time zone"; + case TIMESTAMPOID: + return "timestamp without time zone"; + case TIMESTAMPTZOID: + return "timestamp with time zone"; + default: + elog(ERROR, "unrecognized jsonb value datetime type: %d", + jbv->val.datetime.typid); + } + return "unknown"; + default: + elog(ERROR, "unrecognized jsonb value type: %d", jbv->type); + return "unknown"; + } +} + /* * SQL function jsonb_typeof(jsonb) -> text * @@ -173,45 +240,7 @@ Datum jsonb_typeof(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); - JsonbIterator *it; - JsonbValue v; - char *result; - - if (JB_ROOT_IS_OBJECT(in)) - result = "object"; - else if (JB_ROOT_IS_ARRAY(in) && !JB_ROOT_IS_SCALAR(in)) - result = "array"; - else - { - Assert(JB_ROOT_IS_SCALAR(in)); - - it = JsonbIteratorInit(&in->root); - - /* - * A root scalar is stored as an array of one element, so we get the - * array and then its first (and only) member. - */ - (void) JsonbIteratorNext(&it, &v, true); - Assert(v.type == jbvArray); - (void) JsonbIteratorNext(&it, &v, true); - switch (v.type) - { - case jbvNull: - result = "null"; - break; - case jbvString: - result = "string"; - break; - case jbvNumeric: - result = "number"; - break; - case jbvBool: - result = "boolean"; - break; - default: - elog(ERROR, "unknown jsonb scalar type"); - } - } + const char *result = JsonbContainerTypeName(&in->root); PG_RETURN_TEXT_P(cstring_to_text(result)); } @@ -343,6 +372,7 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) { JsonbInState *_state = (JsonbInState *) pstate; JsonbValue v; + Datum numd; switch (tokentype) { @@ -361,18 +391,19 @@ jsonb_in_scalar(void *pstate, char *token, JsonTokenType tokentype) */ Assert(token != NULL); v.type = jbvNumeric; - v.val.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(token), 0, -1)); - + numd = DirectFunctionCall3(numeric_in, + CStringGetDatum(token), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + v.val.numeric = DatumGetNumeric(numd); break; case JSON_TOKEN_TRUE: v.type = jbvBool; v.val.boolean = true; - break; case JSON_TOKEN_FALSE: v.type = jbvBool; v.val.boolean = false; - break; case JSON_TOKEN_NULL: v.type = jbvNull; @@ -772,9 +803,14 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, strchr(outputstr, 'n') != NULL); if (!numeric_error) { - jb.type = jbvNumeric; - jb.val.numeric = DatumGetNumeric(DirectFunctionCall3(numeric_in, CStringGetDatum(outputstr), 0, -1)); + Datum numd; + jb.type = jbvNumeric; + numd = DirectFunctionCall3(numeric_in, + CStringGetDatum(outputstr), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + jb.val.numeric = DatumGetNumeric(numd); pfree(outputstr); } else @@ -787,17 +823,20 @@ datum_to_jsonb(Datum val, bool is_null, JsonbInState *result, break; case JSONBTYPE_DATE: jb.type = jbvString; - jb.val.string.val = JsonEncodeDateTime(NULL, val, DATEOID); + jb.val.string.val = JsonEncodeDateTime(NULL, val, + DATEOID, NULL); jb.val.string.len = strlen(jb.val.string.val); break; case JSONBTYPE_TIMESTAMP: jb.type = jbvString; - jb.val.string.val = JsonEncodeDateTime(NULL, val, TIMESTAMPOID); + jb.val.string.val = JsonEncodeDateTime(NULL, val, + TIMESTAMPOID, NULL); jb.val.string.len = strlen(jb.val.string.val); break; case JSONBTYPE_TIMESTAMPTZ: jb.type = jbvString; - jb.val.string.val = JsonEncodeDateTime(NULL, val, TIMESTAMPTZOID); + jb.val.string.val = JsonEncodeDateTime(NULL, val, + TIMESTAMPTZOID, NULL); jb.val.string.len = strlen(jb.val.string.val); break; case JSONBTYPE_JSONCAST: @@ -1137,7 +1176,9 @@ jsonb_build_object(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("argument list must have even number of elements"), - errhint("The arguments of jsonb_build_object() must consist of alternating keys and values."))); + /* translator: %s is a SQL function name */ + errhint("The arguments of %s must consist of alternating keys and values.", + "jsonb_build_object()"))); memset(&result, 0, sizeof(JsonbInState)); @@ -1850,7 +1891,7 @@ jsonb_object_agg_finalfn(PG_FUNCTION_ARGS) /* * Extract scalar value from raw-scalar pseudo-array jsonb. */ -static JsonbValue * +bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res) { JsonbIterator *it; @@ -1858,11 +1899,15 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res) JsonbValue tmp; if (!JsonContainerIsArray(jbc) || !JsonContainerIsScalar(jbc)) - return NULL; + { + /* inform caller about actual type of container */ + res->type = (JsonContainerIsArray(jbc)) ? jbvArray : jbvObject; + return false; + } /* - * A root scalar is stored as an array of one element, so we get the - * array and then its first (and only) member. + * A root scalar is stored as an array of one element, so we get the array + * and then its first (and only) member. */ it = JsonbIteratorInit(jbc); @@ -1871,16 +1916,49 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res) Assert(tmp.val.array.nElems == 1 && tmp.val.array.rawScalar); tok = JsonbIteratorNext(&it, res, true); - Assert (tok == WJB_ELEM); + Assert(tok == WJB_ELEM); Assert(IsAJsonbScalar(res)); tok = JsonbIteratorNext(&it, &tmp, true); - Assert (tok == WJB_END_ARRAY); + Assert(tok == WJB_END_ARRAY); tok = JsonbIteratorNext(&it, &tmp, true); Assert(tok == WJB_DONE); - return res; + return true; +} + +/* + * Emit correct, translatable cast error message + */ +static void +cannotCastJsonbValue(enum jbvType type, const char *sqltype) +{ + static const struct + { + enum jbvType type; + const char *msg; + } + messages[] = + { + {jbvNull, gettext_noop("cannot cast jsonb null to type %s")}, + {jbvString, gettext_noop("cannot cast jsonb string to type %s")}, + {jbvNumeric, gettext_noop("cannot cast jsonb numeric to type %s")}, + {jbvBool, gettext_noop("cannot cast jsonb boolean to type %s")}, + {jbvArray, gettext_noop("cannot cast jsonb array to type %s")}, + {jbvObject, gettext_noop("cannot cast jsonb object to type %s")}, + {jbvBinary, gettext_noop("cannot cast jsonb array or object to type %s")} + }; + int i; + + for (i = 0; i < lengthof(messages); i++) + if (messages[i].type == type) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg(messages[i].msg, sqltype))); + + /* should be unreachable */ + elog(ERROR, "unknown jsonb type: %d", (int) type); } Datum @@ -1890,9 +1968,7 @@ jsonb_bool(PG_FUNCTION_ARGS) JsonbValue v; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvBool) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be boolean"))); + cannotCastJsonbValue(v.type, "boolean"); PG_FREE_IF_COPY(in, 0); @@ -1907,12 +1983,11 @@ jsonb_numeric(PG_FUNCTION_ARGS) Numeric retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "numeric"); /* - * v.val.numeric points into jsonb body, so we need to make a copy to return + * v.val.numeric points into jsonb body, so we need to make a copy to + * return */ retValue = DatumGetNumericCopy(NumericGetDatum(v.val.numeric)); @@ -1925,13 +2000,11 @@ Datum jsonb_int2(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); - JsonbValue v; + JsonbValue v; Datum retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "smallint"); retValue = DirectFunctionCall1(numeric_int2, NumericGetDatum(v.val.numeric)); @@ -1945,13 +2018,11 @@ Datum jsonb_int4(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); - JsonbValue v; + JsonbValue v; Datum retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "integer"); retValue = DirectFunctionCall1(numeric_int4, NumericGetDatum(v.val.numeric)); @@ -1965,13 +2036,11 @@ Datum jsonb_int8(PG_FUNCTION_ARGS) { Jsonb *in = PG_GETARG_JSONB_P(0); - JsonbValue v; + JsonbValue v; Datum retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "bigint"); retValue = DirectFunctionCall1(numeric_int8, NumericGetDatum(v.val.numeric)); @@ -1989,9 +2058,7 @@ jsonb_float4(PG_FUNCTION_ARGS) Datum retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "real"); retValue = DirectFunctionCall1(numeric_float4, NumericGetDatum(v.val.numeric)); @@ -2009,9 +2076,7 @@ jsonb_float8(PG_FUNCTION_ARGS) Datum retValue; if (!JsonbExtractScalar(&in->root, &v) || v.type != jbvNumeric) - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("jsonb value must be numeric"))); + cannotCastJsonbValue(v.type, "double precision"); retValue = DirectFunctionCall1(numeric_float8, NumericGetDatum(v.val.numeric)); diff --git a/src/backend/utils/adt/jsonb_gin.c b/src/backend/utils/adt/jsonb_gin.c index c8a27451d2b..e8d54e70b84 100644 --- a/src/backend/utils/adt/jsonb_gin.c +++ b/src/backend/utils/adt/jsonb_gin.c @@ -3,23 +3,71 @@ * jsonb_gin.c * GIN support functions for jsonb * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * + * We provide two opclasses for jsonb indexing: jsonb_ops and jsonb_path_ops. + * For their description see json.sgml and comments in jsonb.h. + * + * The operators support, among the others, "jsonb @? jsonpath" and + * "jsonb @@ jsonpath". Expressions containing these operators are easily + * expressed through each other. + * + * jb @? 'path' <=> jb @@ 'EXISTS(path)' + * jb @@ 'expr' <=> jb @? '$ ? (expr)' + * + * Thus, we're going to consider only @@ operator, while regarding @? operator + * the same is true for jb @@ 'EXISTS(path)'. + * + * Result of jsonpath query extraction is a tree, which leaf nodes are index + * entries and non-leaf nodes are AND/OR logical expressions. Basically we + * extract following statements out of jsonpath: + * + * 1) "accessors_chain = const", + * 2) "EXISTS(accessors_chain)". + * + * Accessors chain may consist of .key, [*] and [index] accessors. jsonb_ops + * additionally supports .* and .**. + * + * For now, both jsonb_ops and jsonb_path_ops supports only statements of + * the 1st find. jsonb_ops might also support statements of the 2nd kind, + * but given we have no statistics keys extracted from accessors chain + * are likely non-selective. Therefore, we choose to not confuse optimizer + * and skip statements of the 2nd kind altogether. In future versions that + * might be changed. + * + * In jsonb_ops statement of the 1st kind is split into expression of AND'ed + * keys and const. Sometimes const might be interpreted as both value or key + * in jsonb_ops. Then statement of 1st kind is decomposed into the expression + * below. + * + * key1 AND key2 AND ... AND keyN AND (const_as_value OR const_as_key) + * + * jsonb_path_ops transforms each statement of the 1st kind into single hash + * entry below. + * + * HASH(key1, key2, ... , keyN, const) + * + * Despite statements of the 2nd kind are not supported by both jsonb_ops and + * jsonb_path_ops, EXISTS(path) expressions might be still supported, + * when statements of 1st kind could be extracted out of their filters. * * IDENTIFICATION * src/backend/utils/adt/jsonb_gin.c * *------------------------------------------------------------------------- */ + #include "postgres.h" #include "access/gin.h" -#include "access/hash.h" #include "access/stratnum.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" +#include "miscadmin.h" #include "utils/builtins.h" +#include "utils/hashutils.h" #include "utils/jsonb.h" +#include "utils/jsonpath.h" #include "utils/varlena.h" typedef struct PathHashStack @@ -28,9 +76,123 @@ typedef struct PathHashStack struct PathHashStack *parent; } PathHashStack; +/* Buffer for GIN entries */ +typedef struct GinEntries +{ + Datum *buf; + int count; + int allocated; +} GinEntries; + +typedef enum JsonPathGinNodeType +{ + JSP_GIN_OR, + JSP_GIN_AND, + JSP_GIN_ENTRY +} JsonPathGinNodeType; + +typedef struct JsonPathGinNode JsonPathGinNode; + +/* Node in jsonpath expression tree */ +struct JsonPathGinNode +{ + JsonPathGinNodeType type; + union + { + int nargs; /* valid for OR and AND nodes */ + int entryIndex; /* index in GinEntries array, valid for ENTRY + * nodes after entries output */ + Datum entryDatum; /* path hash or key name/scalar, valid for + * ENTRY nodes before entries output */ + } val; + JsonPathGinNode *args[FLEXIBLE_ARRAY_MEMBER]; /* valid for OR and AND + * nodes */ +}; + +/* + * jsonb_ops entry extracted from jsonpath item. Corresponding path item + * may be: '.key', '.*', '.**', '[index]' or '[*]'. + * Entry type is stored in 'type' field. + */ +typedef struct JsonPathGinPathItem +{ + struct JsonPathGinPathItem *parent; + Datum keyName; /* key name (for '.key' path item) or NULL */ + JsonPathItemType type; /* type of jsonpath item */ +} JsonPathGinPathItem; + +/* GIN representation of the extracted json path */ +typedef union JsonPathGinPath +{ + JsonPathGinPathItem *items; /* list of path items (jsonb_ops) */ + uint32 hash; /* hash of the path (jsonb_path_ops) */ +} JsonPathGinPath; + +typedef struct JsonPathGinContext JsonPathGinContext; + +/* Callback, which stores information about path item into JsonPathGinPath */ +typedef bool (*JsonPathGinAddPathItemFunc) (JsonPathGinPath *path, + JsonPathItem *jsp); + +/* + * Callback, which extracts set of nodes from statement of 1st kind + * (scalar != NULL) or statement of 2nd kind (scalar == NULL). + */ +typedef List *(*JsonPathGinExtractNodesFunc) (JsonPathGinContext *cxt, + JsonPathGinPath path, + JsonbValue *scalar, + List *nodes); + +/* Context for jsonpath entries extraction */ +struct JsonPathGinContext +{ + JsonPathGinAddPathItemFunc add_path_item; + JsonPathGinExtractNodesFunc extract_nodes; + bool lax; +}; + static Datum make_text_key(char flag, const char *str, int len); static Datum make_scalar_key(const JsonbValue *scalarVal, bool is_key); +static JsonPathGinNode *extract_jsp_bool_expr(JsonPathGinContext *cxt, + JsonPathGinPath path, JsonPathItem *jsp, bool not); + + +/* Initialize GinEntries struct */ +static void +init_gin_entries(GinEntries *entries, int preallocated) +{ + entries->allocated = preallocated; + entries->buf = preallocated ? palloc(sizeof(Datum) * preallocated) : NULL; + entries->count = 0; +} + +/* Add new entry to GinEntries */ +static int +add_gin_entry(GinEntries *entries, Datum entry) +{ + int id = entries->count; + + if (entries->count >= entries->allocated) + { + if (entries->allocated) + { + entries->allocated *= 2; + entries->buf = repalloc(entries->buf, + sizeof(Datum) * entries->allocated); + } + else + { + entries->allocated = 8; + entries->buf = palloc(sizeof(Datum) * entries->allocated); + } + } + + entries->buf[entries->count++] = entry; + + return id; +} + /* * * jsonb_ops GIN opclass support functions @@ -68,12 +230,11 @@ gin_extract_jsonb(PG_FUNCTION_ARGS) { Jsonb *jb = (Jsonb *) PG_GETARG_JSONB_P(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); - int total = 2 * JB_ROOT_COUNT(jb); + int total = JB_ROOT_COUNT(jb); JsonbIterator *it; JsonbValue v; JsonbIteratorToken r; - int i = 0; - Datum *entries; + GinEntries entries; /* If the root level is empty, we certainly have no keys */ if (total == 0) @@ -83,30 +244,23 @@ gin_extract_jsonb(PG_FUNCTION_ARGS) } /* Otherwise, use 2 * root count as initial estimate of result size */ - entries = (Datum *) palloc(sizeof(Datum) * total); + init_gin_entries(&entries, 2 * total); it = JsonbIteratorInit(&jb->root); while ((r = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) { - /* Since we recurse into the object, we might need more space */ - if (i >= total) - { - total *= 2; - entries = (Datum *) repalloc(entries, sizeof(Datum) * total); - } - switch (r) { case WJB_KEY: - entries[i++] = make_scalar_key(&v, true); + add_gin_entry(&entries, make_scalar_key(&v, true)); break; case WJB_ELEM: /* Pretend string array elements are keys, see jsonb.h */ - entries[i++] = make_scalar_key(&v, (v.type == jbvString)); + add_gin_entry(&entries, make_scalar_key(&v, v.type == jbvString)); break; case WJB_VALUE: - entries[i++] = make_scalar_key(&v, false); + add_gin_entry(&entries, make_scalar_key(&v, false)); break; default: /* we can ignore structural items */ @@ -114,9 +268,580 @@ gin_extract_jsonb(PG_FUNCTION_ARGS) } } - *nentries = i; + *nentries = entries.count; - PG_RETURN_POINTER(entries); + PG_RETURN_POINTER(entries.buf); +} + +/* Append JsonPathGinPathItem to JsonPathGinPath (jsonb_ops) */ +static bool +jsonb_ops__add_path_item(JsonPathGinPath *path, JsonPathItem *jsp) +{ + JsonPathGinPathItem *pentry; + Datum keyName; + + switch (jsp->type) + { + case jpiRoot: + path->items = NULL; /* reset path */ + return true; + + case jpiKey: + { + int len; + char *key = jspGetString(jsp, &len); + + keyName = make_text_key(JGINFLAG_KEY, key, len); + break; + } + + case jpiAny: + case jpiAnyKey: + case jpiAnyArray: + case jpiIndexArray: + keyName = PointerGetDatum(NULL); + break; + + default: + /* other path items like item methods are not supported */ + return false; + } + + pentry = palloc(sizeof(*pentry)); + + pentry->type = jsp->type; + pentry->keyName = keyName; + pentry->parent = path->items; + + path->items = pentry; + + return true; +} + +/* Combine existing path hash with next key hash (jsonb_path_ops) */ +static bool +jsonb_path_ops__add_path_item(JsonPathGinPath *path, JsonPathItem *jsp) +{ + switch (jsp->type) + { + case jpiRoot: + path->hash = 0; /* reset path hash */ + return true; + + case jpiKey: + { + JsonbValue jbv; + + jbv.type = jbvString; + jbv.val.string.val = jspGetString(jsp, &jbv.val.string.len); + + JsonbHashScalarValue(&jbv, &path->hash); + return true; + } + + case jpiIndexArray: + case jpiAnyArray: + return true; /* path hash is unchanged */ + + default: + /* other items (wildcard paths, item methods) are not supported */ + return false; + } +} + +static JsonPathGinNode * +make_jsp_entry_node(Datum entry) +{ + JsonPathGinNode *node = palloc(offsetof(JsonPathGinNode, args)); + + node->type = JSP_GIN_ENTRY; + node->val.entryDatum = entry; + + return node; +} + +static JsonPathGinNode * +make_jsp_entry_node_scalar(JsonbValue *scalar, bool iskey) +{ + return make_jsp_entry_node(make_scalar_key(scalar, iskey)); +} + +static JsonPathGinNode * +make_jsp_expr_node(JsonPathGinNodeType type, int nargs) +{ + JsonPathGinNode *node = palloc(offsetof(JsonPathGinNode, args) + + sizeof(node->args[0]) * nargs); + + node->type = type; + node->val.nargs = nargs; + + return node; +} + +static JsonPathGinNode * +make_jsp_expr_node_args(JsonPathGinNodeType type, List *args) +{ + JsonPathGinNode *node = make_jsp_expr_node(type, list_length(args)); + ListCell *lc; + int i = 0; + + foreach(lc, args) + node->args[i++] = lfirst(lc); + + return node; +} + +static JsonPathGinNode * +make_jsp_expr_node_binary(JsonPathGinNodeType type, + JsonPathGinNode *arg1, JsonPathGinNode *arg2) +{ + JsonPathGinNode *node = make_jsp_expr_node(type, 2); + + node->args[0] = arg1; + node->args[1] = arg2; + + return node; +} + +/* Append a list of nodes from the jsonpath (jsonb_ops). */ +static List * +jsonb_ops__extract_nodes(JsonPathGinContext *cxt, JsonPathGinPath path, + JsonbValue *scalar, List *nodes) +{ + JsonPathGinPathItem *pentry; + + if (scalar) + { + JsonPathGinNode *node; + + /* + * Append path entry nodes only if scalar is provided. See header + * comment for details. + */ + for (pentry = path.items; pentry; pentry = pentry->parent) + { + if (pentry->type == jpiKey) /* only keys are indexed */ + nodes = lappend(nodes, make_jsp_entry_node(pentry->keyName)); + } + + /* Append scalar node for equality queries. */ + if (scalar->type == jbvString) + { + JsonPathGinPathItem *last = path.items; + GinTernaryValue key_entry; + + /* + * Assuming that jsonb_ops interprets string array elements as + * keys, we may extract key or non-key entry or even both. In the + * latter case we create OR-node. It is possible in lax mode + * where arrays are automatically unwrapped, or in strict mode for + * jpiAny items. + */ + + if (cxt->lax) + key_entry = GIN_MAYBE; + else if (!last) /* root ($) */ + key_entry = GIN_FALSE; + else if (last->type == jpiAnyArray || last->type == jpiIndexArray) + key_entry = GIN_TRUE; + else if (last->type == jpiAny) + key_entry = GIN_MAYBE; + else + key_entry = GIN_FALSE; + + if (key_entry == GIN_MAYBE) + { + JsonPathGinNode *n1 = make_jsp_entry_node_scalar(scalar, true); + JsonPathGinNode *n2 = make_jsp_entry_node_scalar(scalar, false); + + node = make_jsp_expr_node_binary(JSP_GIN_OR, n1, n2); + } + else + { + node = make_jsp_entry_node_scalar(scalar, + key_entry == GIN_TRUE); + } + } + else + { + node = make_jsp_entry_node_scalar(scalar, false); + } + + nodes = lappend(nodes, node); + } + + return nodes; +} + +/* Append a list of nodes from the jsonpath (jsonb_path_ops). */ +static List * +jsonb_path_ops__extract_nodes(JsonPathGinContext *cxt, JsonPathGinPath path, + JsonbValue *scalar, List *nodes) +{ + if (scalar) + { + /* append path hash node for equality queries */ + uint32 hash = path.hash; + + JsonbHashScalarValue(scalar, &hash); + + return lappend(nodes, + make_jsp_entry_node(UInt32GetDatum(hash))); + } + else + { + /* jsonb_path_ops doesn't support EXISTS queries => nothing to append */ + return nodes; + } +} + +/* + * Extract a list of expression nodes that need to be AND-ed by the caller. + * Extracted expression is 'path == scalar' if 'scalar' is non-NULL, and + * 'EXISTS(path)' otherwise. + */ +static List * +extract_jsp_path_expr_nodes(JsonPathGinContext *cxt, JsonPathGinPath path, + JsonPathItem *jsp, JsonbValue *scalar) +{ + JsonPathItem next; + List *nodes = NIL; + + for (;;) + { + switch (jsp->type) + { + case jpiCurrent: + break; + + case jpiFilter: + { + JsonPathItem arg; + JsonPathGinNode *filter; + + jspGetArg(jsp, &arg); + + filter = extract_jsp_bool_expr(cxt, path, &arg, false); + + if (filter) + nodes = lappend(nodes, filter); + + break; + } + + default: + if (!cxt->add_path_item(&path, jsp)) + + /* + * Path is not supported by the index opclass, return only + * the extracted filter nodes. + */ + return nodes; + break; + } + + if (!jspGetNext(jsp, &next)) + break; + + jsp = &next; + } + + /* + * Append nodes from the path expression itself to the already extracted + * list of filter nodes. + */ + return cxt->extract_nodes(cxt, path, scalar, nodes); +} + +/* + * Extract an expression node from one of following jsonpath path expressions: + * EXISTS(jsp) (when 'scalar' is NULL) + * jsp == scalar (when 'scalar' is not NULL). + * + * The current path (@) is passed in 'path'. + */ +static JsonPathGinNode * +extract_jsp_path_expr(JsonPathGinContext *cxt, JsonPathGinPath path, + JsonPathItem *jsp, JsonbValue *scalar) +{ + /* extract a list of nodes to be AND-ed */ + List *nodes = extract_jsp_path_expr_nodes(cxt, path, jsp, scalar); + + if (list_length(nodes) <= 0) + /* no nodes were extracted => full scan is needed for this path */ + return NULL; + + if (list_length(nodes) == 1) + return linitial(nodes); /* avoid extra AND-node */ + + /* construct AND-node for path with filters */ + return make_jsp_expr_node_args(JSP_GIN_AND, nodes); +} + +/* Recursively extract nodes from the boolean jsonpath expression. */ +static JsonPathGinNode * +extract_jsp_bool_expr(JsonPathGinContext *cxt, JsonPathGinPath path, + JsonPathItem *jsp, bool not) +{ + check_stack_depth(); + + switch (jsp->type) + { + case jpiAnd: /* expr && expr */ + case jpiOr: /* expr || expr */ + { + JsonPathItem arg; + JsonPathGinNode *larg; + JsonPathGinNode *rarg; + JsonPathGinNodeType type; + + jspGetLeftArg(jsp, &arg); + larg = extract_jsp_bool_expr(cxt, path, &arg, not); + + jspGetRightArg(jsp, &arg); + rarg = extract_jsp_bool_expr(cxt, path, &arg, not); + + if (!larg || !rarg) + { + if (jsp->type == jpiOr) + return NULL; + + return larg ? larg : rarg; + } + + type = not ^ (jsp->type == jpiAnd) ? JSP_GIN_AND : JSP_GIN_OR; + + return make_jsp_expr_node_binary(type, larg, rarg); + } + + case jpiNot: /* !expr */ + { + JsonPathItem arg; + + jspGetArg(jsp, &arg); + + /* extract child expression inverting 'not' flag */ + return extract_jsp_bool_expr(cxt, path, &arg, !not); + } + + case jpiExists: /* EXISTS(path) */ + { + JsonPathItem arg; + + if (not) + return NULL; /* NOT EXISTS is not supported */ + + jspGetArg(jsp, &arg); + + return extract_jsp_path_expr(cxt, path, &arg, NULL); + } + + case jpiNotEqual: + + /* + * 'not' == true case is not supported here because '!(path != + * scalar)' is not equivalent to 'path == scalar' in the general + * case because of sequence comparison semantics: 'path == scalar' + * === 'EXISTS (path, @ == scalar)', '!(path != scalar)' === + * 'FOR_ALL(path, @ == scalar)'. So, we should translate '!(path + * != scalar)' into GIN query 'path == scalar || EMPTY(path)', but + * 'EMPTY(path)' queries are not supported by the both jsonb + * opclasses. However in strict mode we could omit 'EMPTY(path)' + * part if the path can return exactly one item (it does not + * contain wildcard accessors or item methods like .keyvalue() + * etc.). + */ + return NULL; + + case jpiEqual: /* path == scalar */ + { + JsonPathItem left_item; + JsonPathItem right_item; + JsonPathItem *path_item; + JsonPathItem *scalar_item; + JsonbValue scalar; + + if (not) + return NULL; + + jspGetLeftArg(jsp, &left_item); + jspGetRightArg(jsp, &right_item); + + if (jspIsScalar(left_item.type)) + { + scalar_item = &left_item; + path_item = &right_item; + } + else if (jspIsScalar(right_item.type)) + { + scalar_item = &right_item; + path_item = &left_item; + } + else + return NULL; /* at least one operand should be a scalar */ + + switch (scalar_item->type) + { + case jpiNull: + scalar.type = jbvNull; + break; + case jpiBool: + scalar.type = jbvBool; + scalar.val.boolean = !!*scalar_item->content.value.data; + break; + case jpiNumeric: + scalar.type = jbvNumeric; + scalar.val.numeric = + (Numeric) scalar_item->content.value.data; + break; + case jpiString: + scalar.type = jbvString; + scalar.val.string.val = scalar_item->content.value.data; + scalar.val.string.len = + scalar_item->content.value.datalen; + break; + default: + elog(ERROR, "invalid scalar jsonpath item type: %d", + scalar_item->type); + return NULL; + } + + return extract_jsp_path_expr(cxt, path, path_item, &scalar); + } + + default: + return NULL; /* not a boolean expression */ + } +} + +/* Recursively emit all GIN entries found in the node tree */ +static void +emit_jsp_gin_entries(JsonPathGinNode *node, GinEntries *entries) +{ + check_stack_depth(); + + switch (node->type) + { + case JSP_GIN_ENTRY: + /* replace datum with its index in the array */ + node->val.entryIndex = add_gin_entry(entries, node->val.entryDatum); + break; + + case JSP_GIN_OR: + case JSP_GIN_AND: + { + int i; + + for (i = 0; i < node->val.nargs; i++) + emit_jsp_gin_entries(node->args[i], entries); + + break; + } + } +} + +/* + * Recursively extract GIN entries from jsonpath query. + * Root expression node is put into (*extra_data)[0]. + */ +static Datum * +extract_jsp_query(JsonPath *jp, StrategyNumber strat, bool pathOps, + int32 *nentries, Pointer **extra_data) +{ + JsonPathGinContext cxt; + JsonPathItem root; + JsonPathGinNode *node; + JsonPathGinPath path = {0}; + GinEntries entries = {0}; + + cxt.lax = (jp->header & JSONPATH_LAX) != 0; + + if (pathOps) + { + cxt.add_path_item = jsonb_path_ops__add_path_item; + cxt.extract_nodes = jsonb_path_ops__extract_nodes; + } + else + { + cxt.add_path_item = jsonb_ops__add_path_item; + cxt.extract_nodes = jsonb_ops__extract_nodes; + } + + jspInit(&root, jp); + + node = strat == JsonbJsonpathExistsStrategyNumber + ? extract_jsp_path_expr(&cxt, path, &root, NULL) + : extract_jsp_bool_expr(&cxt, path, &root, false); + + if (!node) + { + *nentries = 0; + return NULL; + } + + emit_jsp_gin_entries(node, &entries); + + *nentries = entries.count; + if (!*nentries) + return NULL; + + *extra_data = palloc0(sizeof(**extra_data) * entries.count); + **extra_data = (Pointer) node; + + return entries.buf; +} + +/* + * Recursively execute jsonpath expression. + * 'check' is a bool[] or a GinTernaryValue[] depending on 'ternary' flag. + */ +static GinTernaryValue +execute_jsp_gin_node(JsonPathGinNode *node, void *check, bool ternary) +{ + GinTernaryValue res; + GinTernaryValue v; + int i; + + switch (node->type) + { + case JSP_GIN_AND: + res = GIN_TRUE; + for (i = 0; i < node->val.nargs; i++) + { + v = execute_jsp_gin_node(node->args[i], check, ternary); + if (v == GIN_FALSE) + return GIN_FALSE; + else if (v == GIN_MAYBE) + res = GIN_MAYBE; + } + return res; + + case JSP_GIN_OR: + res = GIN_FALSE; + for (i = 0; i < node->val.nargs; i++) + { + v = execute_jsp_gin_node(node->args[i], check, ternary); + if (v == GIN_TRUE) + return GIN_TRUE; + else if (v == GIN_MAYBE) + res = GIN_MAYBE; + } + return res; + + case JSP_GIN_ENTRY: + { + int index = node->val.entryIndex; + + if (ternary) + return ((GinTernaryValue *) check)[index]; + else + return ((bool *) check)[index] ? GIN_TRUE : GIN_FALSE; + } + + default: + elog(ERROR, "invalid jsonpath gin node type: %d", node->type); + return GIN_FALSE; /* keep compiler quiet */ + } } Datum @@ -181,6 +906,17 @@ gin_extract_jsonb_query(PG_FUNCTION_ARGS) if (j == 0 && strategy == JsonbExistsAllStrategyNumber) *searchMode = GIN_SEARCH_MODE_ALL; } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + JsonPath *jp = PG_GETARG_JSONPATH_P(0); + Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4); + + entries = extract_jsp_query(jp, strategy, false, nentries, extra_data); + + if (!entries) + *searchMode = GIN_SEARCH_MODE_ALL; + } else { elog(ERROR, "unrecognized strategy number: %d", strategy); @@ -199,7 +935,7 @@ gin_consistent_jsonb(PG_FUNCTION_ARGS) /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); - /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ + Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = true; int32 i; @@ -256,6 +992,18 @@ gin_consistent_jsonb(PG_FUNCTION_ARGS) } } } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + *recheck = true; + + if (nkeys > 0) + { + Assert(extra_data && extra_data[0]); + res = execute_jsp_gin_node((JsonPathGinNode *) extra_data[0], check, + false) != GIN_FALSE; + } + } else elog(ERROR, "unrecognized strategy number: %d", strategy); @@ -270,8 +1018,7 @@ gin_triconsistent_jsonb(PG_FUNCTION_ARGS) /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); - - /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ + Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); GinTernaryValue res = GIN_MAYBE; int32 i; @@ -308,6 +1055,20 @@ gin_triconsistent_jsonb(PG_FUNCTION_ARGS) } } } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + if (nkeys > 0) + { + Assert(extra_data && extra_data[0]); + res = execute_jsp_gin_node((JsonPathGinNode *) extra_data[0], check, + true); + + /* Should always recheck the result */ + if (res == GIN_TRUE) + res = GIN_MAYBE; + } + } else elog(ERROR, "unrecognized strategy number: %d", strategy); @@ -331,14 +1092,13 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS) { Jsonb *jb = PG_GETARG_JSONB_P(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); - int total = 2 * JB_ROOT_COUNT(jb); + int total = JB_ROOT_COUNT(jb); JsonbIterator *it; JsonbValue v; JsonbIteratorToken r; PathHashStack tail; PathHashStack *stack; - int i = 0; - Datum *entries; + GinEntries entries; /* If the root level is empty, we certainly have no keys */ if (total == 0) @@ -348,7 +1108,7 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS) } /* Otherwise, use 2 * root count as initial estimate of result size */ - entries = (Datum *) palloc(sizeof(Datum) * total); + init_gin_entries(&entries, 2 * total); /* We keep a stack of partial hashes corresponding to parent key levels */ tail.parent = NULL; @@ -361,13 +1121,6 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS) { PathHashStack *parent; - /* Since we recurse into the object, we might need more space */ - if (i >= total) - { - total *= 2; - entries = (Datum *) repalloc(entries, sizeof(Datum) * total); - } - switch (r) { case WJB_BEGIN_ARRAY: @@ -398,7 +1151,7 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS) /* mix the element or value's hash into the prepared hash */ JsonbHashScalarValue(&v, &stack->hash); /* and emit an index entry */ - entries[i++] = UInt32GetDatum(stack->hash); + add_gin_entry(&entries, UInt32GetDatum(stack->hash)); /* reset hash for next key, value, or sub-object */ stack->hash = stack->parent->hash; break; @@ -419,9 +1172,9 @@ gin_extract_jsonb_path(PG_FUNCTION_ARGS) } } - *nentries = i; + *nentries = entries.count; - PG_RETURN_POINTER(entries); + PG_RETURN_POINTER(entries.buf); } Datum @@ -432,18 +1185,34 @@ gin_extract_jsonb_query_path(PG_FUNCTION_ARGS) int32 *searchMode = (int32 *) PG_GETARG_POINTER(6); Datum *entries; - if (strategy != JsonbContainsStrategyNumber) - elog(ERROR, "unrecognized strategy number: %d", strategy); + if (strategy == JsonbContainsStrategyNumber) + { + /* Query is a jsonb, so just apply gin_extract_jsonb_path ... */ + entries = (Datum *) + DatumGetPointer(DirectFunctionCall2(gin_extract_jsonb_path, + PG_GETARG_DATUM(0), + PointerGetDatum(nentries))); - /* Query is a jsonb, so just apply gin_extract_jsonb_path ... */ - entries = (Datum *) - DatumGetPointer(DirectFunctionCall2(gin_extract_jsonb_path, - PG_GETARG_DATUM(0), - PointerGetDatum(nentries))); + /* ... although "contains {}" requires a full index scan */ + if (*nentries == 0) + *searchMode = GIN_SEARCH_MODE_ALL; + } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + JsonPath *jp = PG_GETARG_JSONPATH_P(0); + Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4); - /* ... although "contains {}" requires a full index scan */ - if (*nentries == 0) - *searchMode = GIN_SEARCH_MODE_ALL; + entries = extract_jsp_query(jp, strategy, true, nentries, extra_data); + + if (!entries) + *searchMode = GIN_SEARCH_MODE_ALL; + } + else + { + elog(ERROR, "unrecognized strategy number: %d", strategy); + entries = NULL; + } PG_RETURN_POINTER(entries); } @@ -456,32 +1225,46 @@ gin_consistent_jsonb_path(PG_FUNCTION_ARGS) /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); - - /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ + Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(5); bool res = true; int32 i; - if (strategy != JsonbContainsStrategyNumber) - elog(ERROR, "unrecognized strategy number: %d", strategy); - - /* - * jsonb_path_ops is necessarily lossy, not only because of hash - * collisions but also because it doesn't preserve complete information - * about the structure of the JSON object. Besides, there are some - * special rules around the containment of raw scalars in arrays that are - * not handled here. So we must always recheck a match. However, if not - * all of the keys are present, the tuple certainly doesn't match. - */ - *recheck = true; - for (i = 0; i < nkeys; i++) + if (strategy == JsonbContainsStrategyNumber) { - if (!check[i]) + /* + * jsonb_path_ops is necessarily lossy, not only because of hash + * collisions but also because it doesn't preserve complete + * information about the structure of the JSON object. Besides, there + * are some special rules around the containment of raw scalars in + * arrays that are not handled here. So we must always recheck a + * match. However, if not all of the keys are present, the tuple + * certainly doesn't match. + */ + *recheck = true; + for (i = 0; i < nkeys; i++) { - res = false; - break; + if (!check[i]) + { + res = false; + break; + } } } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + *recheck = true; + + if (nkeys > 0) + { + Assert(extra_data && extra_data[0]); + res = execute_jsp_gin_node((JsonPathGinNode *) extra_data[0], check, + false) != GIN_FALSE; + } + } + else + elog(ERROR, "unrecognized strategy number: %d", strategy); PG_RETURN_BOOL(res); } @@ -494,27 +1277,42 @@ gin_triconsistent_jsonb_path(PG_FUNCTION_ARGS) /* Jsonb *query = PG_GETARG_JSONB_P(2); */ int32 nkeys = PG_GETARG_INT32(3); - - /* Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); */ + Pointer *extra_data = (Pointer *) PG_GETARG_POINTER(4); GinTernaryValue res = GIN_MAYBE; int32 i; - if (strategy != JsonbContainsStrategyNumber) - elog(ERROR, "unrecognized strategy number: %d", strategy); - - /* - * Note that we never return GIN_TRUE, only GIN_MAYBE or GIN_FALSE; this - * corresponds to always forcing recheck in the regular consistent - * function, for the reasons listed there. - */ - for (i = 0; i < nkeys; i++) + if (strategy == JsonbContainsStrategyNumber) { - if (check[i] == GIN_FALSE) + /* + * Note that we never return GIN_TRUE, only GIN_MAYBE or GIN_FALSE; + * this corresponds to always forcing recheck in the regular + * consistent function, for the reasons listed there. + */ + for (i = 0; i < nkeys; i++) { - res = GIN_FALSE; - break; + if (check[i] == GIN_FALSE) + { + res = GIN_FALSE; + break; + } } } + else if (strategy == JsonbJsonpathPredicateStrategyNumber || + strategy == JsonbJsonpathExistsStrategyNumber) + { + if (nkeys > 0) + { + Assert(extra_data && extra_data[0]); + res = execute_jsp_gin_node((JsonPathGinNode *) extra_data[0], check, + true); + + /* Should always recheck the result */ + if (res == GIN_TRUE) + res = GIN_MAYBE; + } + } + else + elog(ERROR, "unrecognized strategy number: %d", strategy); PG_RETURN_GIN_TERNARY_VALUE(res); } diff --git a/src/backend/utils/adt/jsonb_op.c b/src/backend/utils/adt/jsonb_op.c index 4e86dfde93c..a64206eeb1a 100644 --- a/src/backend/utils/adt/jsonb_op.c +++ b/src/backend/utils/adt/jsonb_op.c @@ -3,7 +3,7 @@ * jsonb_op.c * Special operators for jsonb only, used by various index access methods * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 2524584d957..8b739031609 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -3,7 +3,7 @@ * jsonb_util.c * converting between Jsonb and JsonbValues, and iterating. * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -13,10 +13,13 @@ */ #include "postgres.h" -#include "access/hash.h" #include "catalog/pg_collation.h" +#include "catalog/pg_type.h" #include "miscadmin.h" #include "utils/builtins.h" +#include "utils/datetime.h" +#include "utils/hashutils.h" +#include "utils/jsonapi.h" #include "utils/jsonb.h" #include "utils/memutils.h" #include "utils/varlena.h" @@ -34,8 +37,8 @@ #define JSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK)) static void fillJsonbValue(JsonbContainer *container, int index, - char *base_addr, uint32 offset, - JsonbValue *result); + char *base_addr, uint32 offset, + JsonbValue *result); static bool equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b); static int compareJsonbScalarValue(JsonbValue *a, JsonbValue *b); static Jsonb *convertToJsonb(JsonbValue *val); @@ -56,11 +59,13 @@ static void appendKey(JsonbParseState *pstate, JsonbValue *scalarVal); static void appendValue(JsonbParseState *pstate, JsonbValue *scalarVal); static void appendElement(JsonbParseState *pstate, JsonbValue *scalarVal); static int lengthCompareJsonbStringValue(const void *a, const void *b); +static int lengthCompareJsonbString(const char *val1, int len1, + const char *val2, int len2); static int lengthCompareJsonbPair(const void *a, const void *b, void *arg); static void uniqueifyJsonbObject(JsonbValue *object); static JsonbValue *pushJsonbValueScalar(JsonbParseState **pstate, - JsonbIteratorToken seq, - JsonbValue *scalarVal); + JsonbIteratorToken seq, + JsonbValue *scalarVal); /* * Turn an in-memory JsonbValue into a Jsonb for on-disk storage. @@ -242,6 +247,10 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b) break; case jbvBinary: elog(ERROR, "unexpected jbvBinary value"); + break; + case jbvDatetime: + elog(ERROR, "unexpected jbvDatetime value"); + break; } } else @@ -329,7 +338,6 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, { JEntry *children = container->children; int count = JsonContainerSize(container); - JsonbValue *result; Assert((flags & ~(JB_FARRAY | JB_FOBJECT)) == 0); @@ -337,10 +345,9 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, if (count <= 0) return NULL; - result = palloc(sizeof(JsonbValue)); - if ((flags & JB_FARRAY) && JsonContainerIsArray(container)) { + JsonbValue *result = palloc(sizeof(JsonbValue)); char *base_addr = (char *) (children + count); uint32 offset = 0; int i; @@ -357,56 +364,90 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags, JBE_ADVANCE_OFFSET(offset, children[i]); } + + pfree(result); } else if ((flags & JB_FOBJECT) && JsonContainerIsObject(container)) { - /* Since this is an object, account for *Pairs* of Jentrys */ - char *base_addr = (char *) (children + count * 2); - uint32 stopLow = 0, - stopHigh = count; - /* Object key passed by caller must be a string */ Assert(key->type == jbvString); - /* Binary search on object/pair keys *only* */ - while (stopLow < stopHigh) - { - uint32 stopMiddle; - int difference; - JsonbValue candidate; + return getKeyJsonValueFromContainer(container, key->val.string.val, + key->val.string.len, NULL); + } + + /* Not found */ + return NULL; +} + +/* + * Find value by key in Jsonb object and fetch it into 'res', which is also + * returned. + * + * 'res' can be passed in as NULL, in which case it's newly palloc'ed here. + */ +JsonbValue * +getKeyJsonValueFromContainer(JsonbContainer *container, + const char *keyVal, int keyLen, JsonbValue *res) +{ + JEntry *children = container->children; + int count = JsonContainerSize(container); + char *baseAddr; + uint32 stopLow, + stopHigh; - stopMiddle = stopLow + (stopHigh - stopLow) / 2; + Assert(JsonContainerIsObject(container)); - candidate.type = jbvString; - candidate.val.string.val = - base_addr + getJsonbOffset(container, stopMiddle); - candidate.val.string.len = getJsonbLength(container, stopMiddle); + /* Quick out without a palloc cycle if object is empty */ + if (count <= 0) + return NULL; - difference = lengthCompareJsonbStringValue(&candidate, key); + /* + * Binary search the container. Since we know this is an object, account + * for *Pairs* of Jentrys + */ + baseAddr = (char *) (children + count * 2); + stopLow = 0; + stopHigh = count; + while (stopLow < stopHigh) + { + uint32 stopMiddle; + int difference; + const char *candidateVal; + int candidateLen; - if (difference == 0) - { - /* Found our key, return corresponding value */ - int index = stopMiddle + count; + stopMiddle = stopLow + (stopHigh - stopLow) / 2; - fillJsonbValue(container, index, base_addr, - getJsonbOffset(container, index), - result); + candidateVal = baseAddr + getJsonbOffset(container, stopMiddle); + candidateLen = getJsonbLength(container, stopMiddle); - return result; - } + difference = lengthCompareJsonbString(candidateVal, candidateLen, + keyVal, keyLen); + + if (difference == 0) + { + /* Found our key, return corresponding value */ + int index = stopMiddle + count; + + if (!res) + res = palloc(sizeof(JsonbValue)); + + fillJsonbValue(container, index, baseAddr, + getJsonbOffset(container, index), + res); + + return res; + } + else + { + if (difference < 0) + stopLow = stopMiddle + 1; else - { - if (difference < 0) - stopLow = stopMiddle + 1; - else - stopHigh = stopMiddle; - } + stopHigh = stopMiddle; } } /* Not found */ - pfree(result); return NULL; } @@ -510,7 +551,7 @@ fillJsonbValue(JsonbContainer *container, int index, * "raw scalar" pseudo array to append it - the actual scalar should be passed * next and it will be added as the only member of the array. * - * Values of type jvbBinary, which are rolled up arrays and objects, + * Values of type jbvBinary, which are rolled up arrays and objects, * are unpacked before being added to the result. */ JsonbValue * @@ -901,7 +942,7 @@ iteratorFromContainer(JsonbContainer *container, JsonbIterator *parent) { JsonbIterator *it; - it = palloc(sizeof(JsonbIterator)); + it = palloc0(sizeof(JsonbIterator)); it->container = container; it->parent = parent; it->nElems = JsonContainerSize(container); @@ -1009,6 +1050,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained) for (;;) { JsonbValue *lhsVal; /* lhsVal is from pair in lhs object */ + JsonbValue lhsValBuf; rcont = JsonbIteratorNext(mContained, &vcontained, false); @@ -1021,12 +1063,14 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained) return true; Assert(rcont == WJB_KEY); + Assert(vcontained.type == jbvString); /* First, find value by key... */ - lhsVal = findJsonbValueFromContainer((*val)->container, - JB_FOBJECT, - &vcontained); - + lhsVal = + getKeyJsonValueFromContainer((*val)->container, + vcontained.val.string.val, + vcontained.val.string.len, + &lhsValBuf); if (!lhsVal) return false; @@ -1318,7 +1362,7 @@ equalsJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar) } } elog(ERROR, "jsonb scalar type mismatch"); - return -1; + return false; } /* @@ -1363,7 +1407,7 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar) /* - * Functions for manipulating the resizeable buffer used by convertJsonb and + * Functions for manipulating the resizable buffer used by convertJsonb and * its subroutines. */ @@ -1728,6 +1772,14 @@ convertJsonbScalar(StringInfo buffer, JEntry *jentry, JsonbValue *scalarVal) break; case jbvNumeric: + /* replace numeric NaN with string "NaN" */ + if (numeric_is_nan(scalarVal->val.numeric)) + { + appendToBuffer(buffer, "NaN", 3); + *jentry = 3; + break; + } + numlen = VARSIZE_ANY(scalarVal->val.numeric); padlen = padBufferToInt(buffer); @@ -1741,6 +1793,22 @@ convertJsonbScalar(StringInfo buffer, JEntry *jentry, JsonbValue *scalarVal) JENTRY_ISBOOL_TRUE : JENTRY_ISBOOL_FALSE; break; + case jbvDatetime: + { + char buf[MAXDATELEN + 1]; + size_t len; + + JsonEncodeDateTime(buf, + scalarVal->val.datetime.value, + scalarVal->val.datetime.typid, + &scalarVal->val.datetime.tz); + len = strlen(buf); + appendToBuffer(buffer, buf, len); + + *jentry = len; + } + break; + default: elog(ERROR, "invalid jsonb scalar type"); } @@ -1763,21 +1831,27 @@ lengthCompareJsonbStringValue(const void *a, const void *b) { const JsonbValue *va = (const JsonbValue *) a; const JsonbValue *vb = (const JsonbValue *) b; - int res; Assert(va->type == jbvString); Assert(vb->type == jbvString); - if (va->val.string.len == vb->val.string.len) - { - res = memcmp(va->val.string.val, vb->val.string.val, va->val.string.len); - } - else - { - res = (va->val.string.len > vb->val.string.len) ? 1 : -1; - } + return lengthCompareJsonbString(va->val.string.val, va->val.string.len, + vb->val.string.val, vb->val.string.len); +} - return res; +/* + * Subroutine for lengthCompareJsonbStringValue + * + * This is also useful separately to implement binary search on + * JsonbContainers. + */ +static int +lengthCompareJsonbString(const char *val1, int len1, const char *val2, int len2) +{ + if (len1 == len2) + return memcmp(val1, val2, len1); + else + return len1 > len2 ? 1 : -1; } /* diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index 2f12d0325ab..3553a304b8c 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -3,7 +3,7 @@ * jsonfuncs.c * Functions to process JSON data types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -53,14 +53,15 @@ typedef struct OkeysState int sent_count; } OkeysState; -/* state for iterate_json_string_values function */ +/* state for iterate_json_values function */ typedef struct IterateJsonStringValuesState { JsonLexContext *lex; JsonIterateStringValuesAction action; /* an action that will be applied * to each json value */ void *action_state; /* any necessary context for iteration */ - uint32 flags; /* what kind of elements from a json we want to iterate */ + uint32 flags; /* what kind of elements from a json we want + * to iterate */ } IterateJsonStringValuesState; /* state for transform_json_string_values function */ @@ -224,13 +225,13 @@ struct RecordIOData ColumnIOData columns[FLEXIBLE_ARRAY_MEMBER]; }; -/* per-query cache for populate_recordset */ -typedef struct PopulateRecordsetCache +/* per-query cache for populate_record_worker and populate_recordset_worker */ +typedef struct PopulateRecordCache { Oid argtype; /* declared type of the record argument */ ColumnIOData c; /* metadata cache for populate_composite() */ MemoryContext fn_mcxt; /* where this is stored */ -} PopulateRecordsetCache; +} PopulateRecordCache; /* per-call state for populate_recordset */ typedef struct PopulateRecordsetState @@ -243,16 +244,9 @@ typedef struct PopulateRecordsetState JsonTokenType saved_token_type; Tuplestorestate *tuple_store; HeapTupleHeader rec; - PopulateRecordsetCache *cache; + PopulateRecordCache *cache; } PopulateRecordsetState; -/* structure to cache metadata needed for populate_record_worker() */ -typedef struct PopulateRecordCache -{ - Oid argtype; /* declared type of the record argument */ - ColumnIOData c; /* metadata cache for populate_composite() */ -} PopulateRecordCache; - /* common data for populate_array_json() and populate_array_dim_jsonb() */ typedef struct PopulateArrayContext { @@ -353,8 +347,9 @@ static void get_scalar(void *state, char *token, JsonTokenType tokentype); /* common worker function for json getter functions */ static Datum get_path_all(FunctionCallInfo fcinfo, bool as_text); static text *get_worker(text *json, char **tpath, int *ipath, int npath, - bool normalize_results); + bool normalize_results); static Datum get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text); +static text *JsonbValueAsText(JsonbValue *v); /* semantic action functions for json_array_length */ static void alen_object_start(void *state); @@ -364,7 +359,7 @@ static void alen_array_element_start(void *state, bool isnull); /* common workers for json{b}_each* functions */ static Datum each_worker(FunctionCallInfo fcinfo, bool as_text); static Datum each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, - bool as_text); + bool as_text); /* semantic action functions for json_each */ static void each_object_field_start(void *state, char *fname, bool isnull); @@ -374,9 +369,9 @@ static void each_scalar(void *state, char *token, JsonTokenType tokentype); /* common workers for json{b}_array_elements_* functions */ static Datum elements_worker(FunctionCallInfo fcinfo, const char *funcname, - bool as_text); + bool as_text); static Datum elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, - bool as_text); + bool as_text); /* semantic action functions for json_array_elements */ static void elements_object_start(void *state); @@ -420,59 +415,59 @@ static void sn_scalar(void *state, char *token, JsonTokenType tokentype); /* worker functions for populate_record, to_record, populate_recordset and to_recordset */ static Datum populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, - bool have_record_arg); + bool is_json, bool have_record_arg); static Datum populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, - bool have_record_arg); + bool is_json, bool have_record_arg); /* helper functions for populate_record[set] */ static HeapTupleHeader populate_record(TupleDesc tupdesc, RecordIOData **record_p, - HeapTupleHeader defaultval, MemoryContext mcxt, - JsObject *obj); + HeapTupleHeader defaultval, MemoryContext mcxt, + JsObject *obj); +static void get_record_type_from_argument(FunctionCallInfo fcinfo, + const char *funcname, + PopulateRecordCache *cache); +static void get_record_type_from_query(FunctionCallInfo fcinfo, + const char *funcname, + PopulateRecordCache *cache); static void JsValueToJsObject(JsValue *jsv, JsObject *jso); static Datum populate_composite(CompositeIOData *io, Oid typid, - const char *colname, MemoryContext mcxt, - HeapTupleHeader defaultval, JsValue *jsv, bool isnull); + const char *colname, MemoryContext mcxt, + HeapTupleHeader defaultval, JsValue *jsv, bool isnull); static Datum populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv); static void prepare_column_cache(ColumnIOData *column, Oid typid, int32 typmod, - MemoryContext mcxt, bool need_scalar); + MemoryContext mcxt, bool need_scalar); static Datum populate_record_field(ColumnIOData *col, Oid typid, int32 typmod, - const char *colname, MemoryContext mcxt, Datum defaultval, - JsValue *jsv, bool *isnull); + const char *colname, MemoryContext mcxt, Datum defaultval, + JsValue *jsv, bool *isnull); static RecordIOData *allocate_record_info(MemoryContext mcxt, int ncolumns); static bool JsObjectGetField(JsObject *obj, char *field, JsValue *jsv); static void populate_recordset_record(PopulateRecordsetState *state, JsObject *obj); static void populate_array_json(PopulateArrayContext *ctx, char *json, int len); static void populate_array_dim_jsonb(PopulateArrayContext *ctx, JsonbValue *jbv, - int ndim); + int ndim); static void populate_array_report_expected_array(PopulateArrayContext *ctx, int ndim); static void populate_array_assign_ndims(PopulateArrayContext *ctx, int ndims); static void populate_array_check_dimension(PopulateArrayContext *ctx, int ndim); static void populate_array_element(PopulateArrayContext *ctx, int ndim, JsValue *jsv); static Datum populate_array(ArrayIOData *aio, const char *colname, - MemoryContext mcxt, JsValue *jsv); + MemoryContext mcxt, JsValue *jsv); static Datum populate_domain(DomainIOData *io, Oid typid, const char *colname, - MemoryContext mcxt, JsValue *jsv, bool isnull); - -/* Worker that takes care of common setup for us */ -static JsonbValue *findJsonbValueFromContainerLen(JsonbContainer *container, - uint32 flags, - char *key, - uint32 keylen); + MemoryContext mcxt, JsValue *jsv, bool isnull); /* functions supporting jsonb_delete, jsonb_set and jsonb_concat */ static JsonbValue *IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, - JsonbParseState **state); + JsonbParseState **state); static JsonbValue *setPath(JsonbIterator **it, Datum *path_elems, - bool *path_nulls, int path_len, - JsonbParseState **st, int level, Jsonb *newval, - int op_type); + bool *path_nulls, int path_len, + JsonbParseState **st, int level, Jsonb *newval, + int op_type); static void setPathObject(JsonbIterator **it, Datum *path_elems, - bool *path_nulls, int path_len, JsonbParseState **st, - int level, - Jsonb *newval, uint32 npairs, int op_type); + bool *path_nulls, int path_len, JsonbParseState **st, + int level, + Jsonb *newval, uint32 npairs, int op_type); static void setPathArray(JsonbIterator **it, Datum *path_elems, - bool *path_nulls, int path_len, JsonbParseState **st, - int level, Jsonb *newval, uint32 nelems, int op_type); + bool *path_nulls, int path_len, JsonbParseState **st, + int level, Jsonb *newval, uint32 nelems, int op_type); static void addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb); /* function supporting iterate_json_values */ @@ -717,13 +712,15 @@ jsonb_object_field(PG_FUNCTION_ARGS) Jsonb *jb = PG_GETARG_JSONB_P(0); text *key = PG_GETARG_TEXT_PP(1); JsonbValue *v; + JsonbValue vbuf; if (!JB_ROOT_IS_OBJECT(jb)) PG_RETURN_NULL(); - v = findJsonbValueFromContainerLen(&jb->root, JB_FOBJECT, - VARDATA_ANY(key), - VARSIZE_ANY_EXHDR(key)); + v = getKeyJsonValueFromContainer(&jb->root, + VARDATA_ANY(key), + VARSIZE_ANY_EXHDR(key), + &vbuf); if (v != NULL) PG_RETURN_JSONB_P(JsonbValueToJsonb(v)); @@ -753,47 +750,18 @@ jsonb_object_field_text(PG_FUNCTION_ARGS) Jsonb *jb = PG_GETARG_JSONB_P(0); text *key = PG_GETARG_TEXT_PP(1); JsonbValue *v; + JsonbValue vbuf; if (!JB_ROOT_IS_OBJECT(jb)) PG_RETURN_NULL(); - v = findJsonbValueFromContainerLen(&jb->root, JB_FOBJECT, - VARDATA_ANY(key), - VARSIZE_ANY_EXHDR(key)); - - if (v != NULL) - { - text *result = NULL; - - switch (v->type) - { - case jbvNull: - break; - case jbvBool: - result = cstring_to_text(v->val.boolean ? "true" : "false"); - break; - case jbvString: - result = cstring_to_text_with_len(v->val.string.val, v->val.string.len); - break; - case jbvNumeric: - result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out, - PointerGetDatum(v->val.numeric)))); - break; - case jbvBinary: - { - StringInfo jtext = makeStringInfo(); - - (void) JsonbToCString(jtext, v->val.binary.data, -1); - result = cstring_to_text_with_len(jtext->data, jtext->len); - } - break; - default: - elog(ERROR, "unrecognized jsonb type: %d", (int) v->type); - } + v = getKeyJsonValueFromContainer(&jb->root, + VARDATA_ANY(key), + VARSIZE_ANY_EXHDR(key), + &vbuf); - if (result) - PG_RETURN_TEXT_P(result); - } + if (v != NULL && v->type != jbvNull) + PG_RETURN_TEXT_P(JsonbValueAsText(v)); PG_RETURN_NULL(); } @@ -878,39 +846,9 @@ jsonb_array_element_text(PG_FUNCTION_ARGS) } v = getIthJsonbValueFromContainer(&jb->root, element); - if (v != NULL) - { - text *result = NULL; - switch (v->type) - { - case jbvNull: - break; - case jbvBool: - result = cstring_to_text(v->val.boolean ? "true" : "false"); - break; - case jbvString: - result = cstring_to_text_with_len(v->val.string.val, v->val.string.len); - break; - case jbvNumeric: - result = cstring_to_text(DatumGetCString(DirectFunctionCall1(numeric_out, - PointerGetDatum(v->val.numeric)))); - break; - case jbvBinary: - { - StringInfo jtext = makeStringInfo(); - - (void) JsonbToCString(jtext, v->val.binary.data, -1); - result = cstring_to_text_with_len(jtext->data, jtext->len); - } - break; - default: - elog(ERROR, "unrecognized jsonb type: %d", (int) v->type); - } - - if (result) - PG_RETURN_TEXT_P(result); - } + if (v != NULL && v->type != jbvNull) + PG_RETURN_TEXT_P(JsonbValueAsText(v)); PG_RETURN_NULL(); } @@ -1388,7 +1326,6 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) { Jsonb *jb = PG_GETARG_JSONB_P(0); ArrayType *path = PG_GETARG_ARRAYTYPE_P(1); - Jsonb *res; Datum *pathtext; bool *pathnulls; int npath; @@ -1396,7 +1333,7 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) bool have_object = false, have_array = false; JsonbValue *jbvp = NULL; - JsonbValue tv; + JsonbValue jbvbuf; JsonbContainer *container; /* @@ -1454,10 +1391,10 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) { if (have_object) { - jbvp = findJsonbValueFromContainerLen(container, - JB_FOBJECT, - VARDATA(pathtext[i]), - VARSIZE(pathtext[i]) - VARHDRSZ); + jbvp = getKeyJsonValueFromContainer(container, + VARDATA(pathtext[i]), + VARSIZE(pathtext[i]) - VARHDRSZ, + &jbvbuf); } else if (have_array) { @@ -1508,46 +1445,82 @@ get_jsonb_path_all(FunctionCallInfo fcinfo, bool as_text) if (jbvp->type == jbvBinary) { - JsonbIterator *it = JsonbIteratorInit((JsonbContainer *) jbvp->val.binary.data); - JsonbIteratorToken r; - - r = JsonbIteratorNext(&it, &tv, true); - container = (JsonbContainer *) jbvp->val.binary.data; - have_object = r == WJB_BEGIN_OBJECT; - have_array = r == WJB_BEGIN_ARRAY; + container = jbvp->val.binary.data; + have_object = JsonContainerIsObject(container); + have_array = JsonContainerIsArray(container); + Assert(!JsonContainerIsScalar(container)); } else { - have_object = jbvp->type == jbvObject; - have_array = jbvp->type == jbvArray; + Assert(IsAJsonbScalar(jbvp)); + have_object = false; + have_array = false; } } if (as_text) { - /* special-case outputs for string and null values */ - if (jbvp->type == jbvString) - PG_RETURN_TEXT_P(cstring_to_text_with_len(jbvp->val.string.val, - jbvp->val.string.len)); if (jbvp->type == jbvNull) PG_RETURN_NULL(); - } - - res = JsonbValueToJsonb(jbvp); - if (as_text) - { - PG_RETURN_TEXT_P(cstring_to_text(JsonbToCString(NULL, - &res->root, - VARSIZE(res)))); + PG_RETURN_TEXT_P(JsonbValueAsText(jbvp)); } else { + Jsonb *res = JsonbValueToJsonb(jbvp); + /* not text mode - just hand back the jsonb */ PG_RETURN_JSONB_P(res); } } +/* + * Return the text representation of the given JsonbValue. + */ +static text * +JsonbValueAsText(JsonbValue *v) +{ + switch (v->type) + { + case jbvNull: + return NULL; + + case jbvBool: + return v->val.boolean ? + cstring_to_text_with_len("true", 4) : + cstring_to_text_with_len("false", 5); + + case jbvString: + return cstring_to_text_with_len(v->val.string.val, + v->val.string.len); + + case jbvNumeric: + { + Datum cstr; + + cstr = DirectFunctionCall1(numeric_out, + PointerGetDatum(v->val.numeric)); + + return cstring_to_text(DatumGetCString(cstr)); + } + + case jbvBinary: + { + StringInfoData jtext; + + initStringInfo(&jtext); + (void) JsonbToCString(&jtext, v->val.binary.data, + v->val.binary.len); + + return cstring_to_text_with_len(jtext.data, jtext.len); + } + + default: + elog(ERROR, "unrecognized jsonb type: %d", (int) v->type); + return NULL; + } +} + /* * SQL function json_array_length(json) -> int */ @@ -1745,6 +1718,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text) * matter what shape it is. */ r = JsonbIteratorNext(&it, &v, skipNested); + Assert(r != WJB_DONE); values[0] = PointerGetDatum(key); @@ -1757,26 +1731,7 @@ each_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, bool as_text) values[1] = (Datum) NULL; } else - { - text *sv; - - if (v.type == jbvString) - { - /* In text mode, scalar strings should be dequoted */ - sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len); - } - else - { - /* Turn anything else into a json string */ - StringInfo jtext = makeStringInfo(); - Jsonb *jb = JsonbValueToJsonb(&v); - - (void) JsonbToCString(jtext, &jb->root, 0); - sv = cstring_to_text_with_len(jtext->data, jtext->len); - } - - values[1] = PointerGetDatum(sv); - } + values[1] = PointerGetDatum(JsonbValueAsText(&v)); } else { @@ -2052,13 +2007,7 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, /* use the tmp context so we can clean up after each tuple is done */ old_cxt = MemoryContextSwitchTo(tmp_cxt); - if (!as_text) - { - Jsonb *val = JsonbValueToJsonb(&v); - - values[0] = PointerGetDatum(val); - } - else + if (as_text) { if (v.type == jbvNull) { @@ -2067,26 +2016,14 @@ elements_worker_jsonb(FunctionCallInfo fcinfo, const char *funcname, values[0] = (Datum) NULL; } else - { - text *sv; - - if (v.type == jbvString) - { - /* in text mode scalar strings should be dequoted */ - sv = cstring_to_text_with_len(v.val.string.val, v.val.string.len); - } - else - { - /* turn anything else into a json string */ - StringInfo jtext = makeStringInfo(); - Jsonb *jb = JsonbValueToJsonb(&v); - - (void) JsonbToCString(jtext, &jb->root, 0); - sv = cstring_to_text_with_len(jtext->data, jtext->len); - } + values[0] = PointerGetDatum(JsonbValueAsText(&v)); + } + else + { + /* Not in text mode, just return the Jsonb */ + Jsonb *val = JsonbValueToJsonb(&v); - values[0] = PointerGetDatum(sv); - } + values[0] = PointerGetDatum(val); } tuple = heap_form_tuple(ret_tdesc, values, nulls); @@ -2294,25 +2231,29 @@ elements_scalar(void *state, char *token, JsonTokenType tokentype) Datum jsonb_populate_record(PG_FUNCTION_ARGS) { - return populate_record_worker(fcinfo, "jsonb_populate_record", true); + return populate_record_worker(fcinfo, "jsonb_populate_record", + false, true); } Datum jsonb_to_record(PG_FUNCTION_ARGS) { - return populate_record_worker(fcinfo, "jsonb_to_record", false); + return populate_record_worker(fcinfo, "jsonb_to_record", + false, false); } Datum json_populate_record(PG_FUNCTION_ARGS) { - return populate_record_worker(fcinfo, "json_populate_record", true); + return populate_record_worker(fcinfo, "json_populate_record", + true, true); } Datum json_to_record(PG_FUNCTION_ARGS) { - return populate_record_worker(fcinfo, "json_to_record", false); + return populate_record_worker(fcinfo, "json_to_record", + true, false); } /* helper function for diagnostics */ @@ -2324,12 +2265,12 @@ populate_array_report_expected_array(PopulateArrayContext *ctx, int ndim) if (ctx->colname) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("expected json array"), + errmsg("expected JSON array"), errhint("See the value of key \"%s\".", ctx->colname))); else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("expected json array"))); + errmsg("expected JSON array"))); } else { @@ -2346,13 +2287,13 @@ populate_array_report_expected_array(PopulateArrayContext *ctx, int ndim) if (ctx->colname) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("expected json array"), + errmsg("expected JSON array"), errhint("See the array element %s of key \"%s\".", indices.data, ctx->colname))); else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("expected json array"), + errmsg("expected JSON array"), errhint("See the array element %s.", indices.data))); } @@ -2388,7 +2329,7 @@ populate_array_check_dimension(PopulateArrayContext *ctx, int ndim) else if (ctx->dims[ndim] != dim) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("malformed json array"), + errmsg("malformed JSON array"), errdetail("Multidimensional arrays must have " "sub-arrays with matching dimensions."))); @@ -2797,26 +2738,7 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv) json = jsv->val.json.str; Assert(json); - - /* already done the hard work in the json case */ - if ((typid == JSONOID || typid == JSONBOID) && - jsv->val.json.type == JSON_TOKEN_STRING) - { - /* - * Add quotes around string value (should be already escaped) if - * converting to json/jsonb. - */ - - if (len < 0) - len = strlen(json); - - str = palloc(len + sizeof(char) * 3); - str[0] = '"'; - memcpy(&str[1], json, len); - str[len + 1] = '"'; - str[len + 2] = '\0'; - } - else if (len >= 0) + if (len >= 0) { /* Need to copy non-null-terminated string */ str = palloc(len + 1 * sizeof(char)); @@ -2824,7 +2746,21 @@ populate_scalar(ScalarIOData *io, Oid typid, int32 typmod, JsValue *jsv) str[len] = '\0'; } else - str = json; /* null-terminated string */ + str = json; /* string is already null-terminated */ + + /* If converting to json/jsonb, make string into valid JSON literal */ + if ((typid == JSONOID || typid == JSONBOID) && + jsv->val.json.type == JSON_TOKEN_STRING) + { + StringInfoData buf; + + initStringInfo(&buf); + escape_json(&buf, str); + /* free temporary buffer */ + if (str != json) + pfree(str); + str = buf.data; + } } else { @@ -3085,8 +3021,8 @@ JsObjectGetField(JsObject *obj, char *field, JsValue *jsv) else { jsv->val.jsonb = !obj->val.jsonb_cont ? NULL : - findJsonbValueFromContainerLen(obj->val.jsonb_cont, JB_FOBJECT, - field, strlen(field)); + getKeyJsonValueFromContainer(obj->val.jsonb_cont, field, strlen(field), + NULL); return jsv->val.jsonb != NULL; } @@ -3201,12 +3137,79 @@ populate_record(TupleDesc tupdesc, return res->t_data; } +/* + * Setup for json{b}_populate_record{set}: result type will be same as first + * argument's type --- unless first argument is "null::record", which we can't + * extract type info from; we handle that later. + */ +static void +get_record_type_from_argument(FunctionCallInfo fcinfo, + const char *funcname, + PopulateRecordCache *cache) +{ + cache->argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); + prepare_column_cache(&cache->c, + cache->argtype, -1, + cache->fn_mcxt, false); + if (cache->c.typcat != TYPECAT_COMPOSITE && + cache->c.typcat != TYPECAT_COMPOSITE_DOMAIN) + ereport(ERROR, + (errcode(ERRCODE_DATATYPE_MISMATCH), + /* translator: %s is a function name, eg json_to_record */ + errmsg("first argument of %s must be a row type", + funcname))); +} + +/* + * Setup for json{b}_to_record{set}: result type is specified by calling + * query. We'll also use this code for json{b}_populate_record{set}, + * if we discover that the first argument is a null of type RECORD. + * + * Here it is syntactically impossible to specify the target type + * as domain-over-composite. + */ +static void +get_record_type_from_query(FunctionCallInfo fcinfo, + const char *funcname, + PopulateRecordCache *cache) +{ + TupleDesc tupdesc; + MemoryContext old_cxt; + + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + /* translator: %s is a function name, eg json_to_record */ + errmsg("could not determine row type for result of %s", + funcname), + errhint("Provide a non-null record argument, " + "or call the function in the FROM clause " + "using a column definition list."))); + + Assert(tupdesc); + cache->argtype = tupdesc->tdtypeid; + + /* If we go through this more than once, avoid memory leak */ + if (cache->c.io.composite.tupdesc) + FreeTupleDesc(cache->c.io.composite.tupdesc); + + /* Save identified tupdesc */ + old_cxt = MemoryContextSwitchTo(cache->fn_mcxt); + cache->c.io.composite.tupdesc = CreateTupleDescCopy(tupdesc); + cache->c.io.composite.base_typid = tupdesc->tdtypeid; + cache->c.io.composite.base_typmod = tupdesc->tdtypmod; + MemoryContextSwitchTo(old_cxt); +} + +/* + * common worker for json{b}_populate_record() and json{b}_to_record() + * is_json and have_record_arg identify the specific function + */ static Datum populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, - bool have_record_arg) + bool is_json, bool have_record_arg) { int json_arg_num = have_record_arg ? 1 : 0; - Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); JsValue jsv = {0}; HeapTupleHeader rec; Datum rettuple; @@ -3214,8 +3217,6 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, MemoryContext fnmcxt = fcinfo->flinfo->fn_mcxt; PopulateRecordCache *cache = fcinfo->flinfo->fn_extra; - Assert(jtype == JSONOID || jtype == JSONBOID); - /* * If first time through, identify input/result record type. Note that * this stanza looks only at fcinfo context, which can't change during the @@ -3225,63 +3226,24 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, { fcinfo->flinfo->fn_extra = cache = MemoryContextAllocZero(fnmcxt, sizeof(*cache)); + cache->fn_mcxt = fnmcxt; if (have_record_arg) - { - /* - * json{b}_populate_record case: result type will be same as first - * argument's. - */ - cache->argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); - prepare_column_cache(&cache->c, - cache->argtype, -1, - fnmcxt, false); - if (cache->c.typcat != TYPECAT_COMPOSITE && - cache->c.typcat != TYPECAT_COMPOSITE_DOMAIN) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("first argument of %s must be a row type", - funcname))); - } + get_record_type_from_argument(fcinfo, funcname, cache); else - { - /* - * json{b}_to_record case: result type is specified by calling - * query. Here it is syntactically impossible to specify the - * target type as domain-over-composite. - */ - TupleDesc tupdesc; - MemoryContext old_cxt; - - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"), - errhint("Try calling the function in the FROM clause " - "using a column definition list."))); - - Assert(tupdesc); - cache->argtype = tupdesc->tdtypeid; - - /* Save identified tupdesc */ - old_cxt = MemoryContextSwitchTo(fnmcxt); - cache->c.io.composite.tupdesc = CreateTupleDescCopy(tupdesc); - cache->c.io.composite.base_typid = tupdesc->tdtypeid; - cache->c.io.composite.base_typmod = tupdesc->tdtypmod; - MemoryContextSwitchTo(old_cxt); - } + get_record_type_from_query(fcinfo, funcname, cache); } /* Collect record arg if we have one */ - if (have_record_arg && !PG_ARGISNULL(0)) + if (!have_record_arg) + rec = NULL; /* it's json{b}_to_record() */ + else if (!PG_ARGISNULL(0)) { rec = PG_GETARG_HEAPTUPLEHEADER(0); /* * When declared arg type is RECORD, identify actual record type from - * the tuple itself. Note the lookup_rowtype_tupdesc call in - * update_cached_tupdesc will fail if we're unable to do this. + * the tuple itself. */ if (cache->argtype == RECORDOID) { @@ -3290,8 +3252,21 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, } } else + { rec = NULL; + /* + * When declared arg type is RECORD, identify actual record type from + * calling query, or fail if we can't. + */ + if (cache->argtype == RECORDOID) + { + get_record_type_from_query(fcinfo, funcname, cache); + /* This can't change argtype, which is important for next time */ + Assert(cache->argtype == RECORDOID); + } + } + /* If no JSON argument, just return the record (if any) unchanged */ if (PG_ARGISNULL(json_arg_num)) { @@ -3301,9 +3276,9 @@ populate_record_worker(FunctionCallInfo fcinfo, const char *funcname, PG_RETURN_NULL(); } - jsv.is_json = jtype == JSONOID; + jsv.is_json = is_json; - if (jsv.is_json) + if (is_json) { text *json = PG_GETARG_TEXT_PP(json_arg_num); @@ -3487,31 +3462,35 @@ hash_scalar(void *state, char *token, JsonTokenType tokentype) Datum jsonb_populate_recordset(PG_FUNCTION_ARGS) { - return populate_recordset_worker(fcinfo, "jsonb_populate_recordset", true); + return populate_recordset_worker(fcinfo, "jsonb_populate_recordset", + false, true); } Datum jsonb_to_recordset(PG_FUNCTION_ARGS) { - return populate_recordset_worker(fcinfo, "jsonb_to_recordset", false); + return populate_recordset_worker(fcinfo, "jsonb_to_recordset", + false, false); } Datum json_populate_recordset(PG_FUNCTION_ARGS) { - return populate_recordset_worker(fcinfo, "json_populate_recordset", true); + return populate_recordset_worker(fcinfo, "json_populate_recordset", + true, true); } Datum json_to_recordset(PG_FUNCTION_ARGS) { - return populate_recordset_worker(fcinfo, "json_to_recordset", false); + return populate_recordset_worker(fcinfo, "json_to_recordset", + true, false); } static void populate_recordset_record(PopulateRecordsetState *state, JsObject *obj) { - PopulateRecordsetCache *cache = state->cache; + PopulateRecordCache *cache = state->cache; HeapTupleHeader tuphead; HeapTupleData tuple; @@ -3542,18 +3521,18 @@ populate_recordset_record(PopulateRecordsetState *state, JsObject *obj) } /* - * common worker for json_populate_recordset() and json_to_recordset() + * common worker for json{b}_populate_recordset() and json{b}_to_recordset() + * is_json and have_record_arg identify the specific function */ static Datum populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, - bool have_record_arg) + bool is_json, bool have_record_arg) { int json_arg_num = have_record_arg ? 1 : 0; - Oid jtype = get_fn_expr_argtype(fcinfo->flinfo, json_arg_num); ReturnSetInfo *rsi; MemoryContext old_cxt; HeapTupleHeader rec; - PopulateRecordsetCache *cache = fcinfo->flinfo->fn_extra; + PopulateRecordCache *cache = fcinfo->flinfo->fn_extra; PopulateRecordsetState *state; rsi = (ReturnSetInfo *) fcinfo->resultinfo; @@ -3579,60 +3558,21 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, cache->fn_mcxt = fcinfo->flinfo->fn_mcxt; if (have_record_arg) - { - /* - * json{b}_populate_recordset case: result type will be same as - * first argument's. - */ - cache->argtype = get_fn_expr_argtype(fcinfo->flinfo, 0); - prepare_column_cache(&cache->c, - cache->argtype, -1, - cache->fn_mcxt, false); - if (cache->c.typcat != TYPECAT_COMPOSITE && - cache->c.typcat != TYPECAT_COMPOSITE_DOMAIN) - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("first argument of %s must be a row type", - funcname))); - } + get_record_type_from_argument(fcinfo, funcname, cache); else - { - /* - * json{b}_to_recordset case: result type is specified by calling - * query. Here it is syntactically impossible to specify the - * target type as domain-over-composite. - */ - TupleDesc tupdesc; - - if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("function returning record called in context " - "that cannot accept type record"), - errhint("Try calling the function in the FROM clause " - "using a column definition list."))); - - Assert(tupdesc); - cache->argtype = tupdesc->tdtypeid; - - /* Save identified tupdesc */ - old_cxt = MemoryContextSwitchTo(cache->fn_mcxt); - cache->c.io.composite.tupdesc = CreateTupleDescCopy(tupdesc); - cache->c.io.composite.base_typid = tupdesc->tdtypeid; - cache->c.io.composite.base_typmod = tupdesc->tdtypmod; - MemoryContextSwitchTo(old_cxt); - } + get_record_type_from_query(fcinfo, funcname, cache); } /* Collect record arg if we have one */ - if (have_record_arg && !PG_ARGISNULL(0)) + if (!have_record_arg) + rec = NULL; /* it's json{b}_to_recordset() */ + else if (!PG_ARGISNULL(0)) { rec = PG_GETARG_HEAPTUPLEHEADER(0); /* * When declared arg type is RECORD, identify actual record type from - * the tuple itself. Note the lookup_rowtype_tupdesc call in - * update_cached_tupdesc will fail if we're unable to do this. + * the tuple itself. */ if (cache->argtype == RECORDOID) { @@ -3641,12 +3581,31 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, } } else + { rec = NULL; + /* + * When declared arg type is RECORD, identify actual record type from + * calling query, or fail if we can't. + */ + if (cache->argtype == RECORDOID) + { + get_record_type_from_query(fcinfo, funcname, cache); + /* This can't change argtype, which is important for next time */ + Assert(cache->argtype == RECORDOID); + } + } + /* if the json is null send back an empty set */ if (PG_ARGISNULL(json_arg_num)) PG_RETURN_NULL(); + /* + * Forcibly update the cached tupdesc, to ensure we have the right tupdesc + * to return even if the JSON contains no rows. + */ + update_cached_tupdesc(&cache->c.io.composite, cache->fn_mcxt); + state = palloc0(sizeof(PopulateRecordsetState)); /* make tuplestore in a sufficiently long-lived memory context */ @@ -3660,7 +3619,7 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, state->cache = cache; state->rec = rec; - if (jtype == JSONOID) + if (is_json) { text *json = PG_GETARG_TEXT_PP(json_arg_num); JsonLexContext *lex; @@ -3691,8 +3650,6 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, bool skipNested = false; JsonbIteratorToken r; - Assert(jtype == JSONBOID); - if (JB_ROOT_IS_SCALAR(jb) || !JB_ROOT_IS_ARRAY(jb)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -3724,8 +3681,13 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname, } } + /* + * Note: we must copy the cached tupdesc because the executor will free + * the passed-back setDesc, but we want to hang onto the cache in case + * we're called again in the same query. + */ rsi->setResult = state->tuple_store; - rsi->setDesc = cache->c.io.composite.tupdesc; + rsi->setDesc = CreateTupleDescCopy(cache->c.io.composite.tupdesc); PG_RETURN_NULL(); } @@ -3884,22 +3846,6 @@ populate_recordset_object_field_end(void *state, char *fname, bool isnull) } } -/* - * findJsonbValueFromContainer() wrapper that sets up JsonbValue key string. - */ -static JsonbValue * -findJsonbValueFromContainerLen(JsonbContainer *container, uint32 flags, - char *key, uint32 keylen) -{ - JsonbValue k; - - k.type = jbvString; - k.val.string.val = key; - k.val.string.len = keylen; - - return findJsonbValueFromContainer(container, flags, &k); -} - /* * Semantic actions for json_strip_nulls. * @@ -4111,6 +4057,7 @@ addJsonbToParseState(JsonbParseState **jbps, Jsonb *jb) if (JB_ROOT_IS_SCALAR(jb)) { (void) JsonbIteratorNext(&it, &v, false); /* skip array header */ + Assert(v.type == jbvArray); (void) JsonbIteratorNext(&it, &v, false); /* fetch scalar value */ switch (o->type) @@ -4224,7 +4171,7 @@ jsonb_delete(PG_FUNCTION_ARGS) it = JsonbIteratorInit(&in->root); - while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0) + while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE) { skipNested = true; @@ -4234,7 +4181,7 @@ jsonb_delete(PG_FUNCTION_ARGS) { /* skip corresponding value as well */ if (r == WJB_KEY) - JsonbIteratorNext(&it, &v, true); + (void) JsonbIteratorNext(&it, &v, true); continue; } @@ -4289,7 +4236,7 @@ jsonb_delete_array(PG_FUNCTION_ARGS) it = JsonbIteratorInit(&in->root); - while ((r = JsonbIteratorNext(&it, &v, skipNested)) != 0) + while ((r = JsonbIteratorNext(&it, &v, skipNested)) != WJB_DONE) { skipNested = true; @@ -4319,7 +4266,7 @@ jsonb_delete_array(PG_FUNCTION_ARGS) { /* skip corresponding value as well */ if (r == WJB_KEY) - JsonbIteratorNext(&it, &v, true); + (void) JsonbIteratorNext(&it, &v, true); continue; } @@ -4385,7 +4332,7 @@ jsonb_delete_idx(PG_FUNCTION_ARGS) pushJsonbValue(&state, r, NULL); - while ((r = JsonbIteratorNext(&it, &v, true)) != 0) + while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) { if (r == WJB_ELEM) { @@ -4403,7 +4350,6 @@ jsonb_delete_idx(PG_FUNCTION_ARGS) /* * SQL function jsonb_set(jsonb, text[], jsonb, boolean) - * */ Datum jsonb_set(PG_FUNCTION_ARGS) @@ -4495,7 +4441,6 @@ jsonb_delete_path(PG_FUNCTION_ARGS) /* * SQL function jsonb_insert(jsonb, text[], jsonb, boolean) - * */ Datum jsonb_insert(PG_FUNCTION_ARGS) @@ -4576,7 +4521,7 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, * Append the all tokens from v2 to res, include last WJB_END_OBJECT * (the concatenation will be completed). */ - while ((r2 = JsonbIteratorNext(it2, &v2, true)) != 0) + while ((r2 = JsonbIteratorNext(it2, &v2, true)) != WJB_DONE) res = pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL); } @@ -4616,10 +4561,10 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, if (prepend) { pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); - while ((r1 = JsonbIteratorNext(it_object, &v1, true)) != 0) + while ((r1 = JsonbIteratorNext(it_object, &v1, true)) != WJB_DONE) pushJsonbValue(state, r1, r1 != WJB_END_OBJECT ? &v1 : NULL); - while ((r2 = JsonbIteratorNext(it_array, &v2, true)) != 0) + while ((r2 = JsonbIteratorNext(it_array, &v2, true)) != WJB_DONE) res = pushJsonbValue(state, r2, r2 != WJB_END_ARRAY ? &v2 : NULL); } else @@ -4628,7 +4573,7 @@ IteratorConcat(JsonbIterator **it1, JsonbIterator **it2, pushJsonbValue(state, r1, &v1); pushJsonbValue(state, WJB_BEGIN_OBJECT, NULL); - while ((r2 = JsonbIteratorNext(it_object, &v2, true)) != 0) + while ((r2 = JsonbIteratorNext(it_object, &v2, true)) != WJB_DONE) pushJsonbValue(state, r2, r2 != WJB_END_OBJECT ? &v2 : NULL); res = pushJsonbValue(state, WJB_END_ARRAY, NULL); @@ -4948,19 +4893,19 @@ setPathArray(JsonbIterator **it, Datum *path_elems, bool *path_nulls, uint32 parse_jsonb_index_flags(Jsonb *jb) { - JsonbIterator *it; - JsonbValue v; - JsonbIteratorToken type; - uint32 flags = 0; + JsonbIterator *it; + JsonbValue v; + JsonbIteratorToken type; + uint32 flags = 0; it = JsonbIteratorInit(&jb->root); type = JsonbIteratorNext(&it, &v, false); /* - * We iterate over array (scalar internally is represented as array, so, we - * will accept it too) to check all its elements. Flag's names are choosen - * the same as jsonb_typeof uses. + * We iterate over array (scalar internally is represented as array, so, + * we will accept it too) to check all its elements. Flag names are + * chosen the same as jsonb_typeof uses. */ if (type != WJB_BEGIN_ARRAY) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -4972,10 +4917,10 @@ parse_jsonb_index_flags(Jsonb *jb) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("flag array element is not a string"), - errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\" and \"all\""))); + errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"."))); if (v.val.string.len == 3 && - pg_strncasecmp(v.val.string.val, "all", 3) == 0) + pg_strncasecmp(v.val.string.val, "all", 3) == 0) flags |= jtiAll; else if (v.val.string.len == 3 && pg_strncasecmp(v.val.string.val, "key", 3) == 0) @@ -4994,15 +4939,17 @@ parse_jsonb_index_flags(Jsonb *jb) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("wrong flag in flag array: \"%s\"", pnstrdup(v.val.string.val, v.val.string.len)), - errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\" and \"all\""))); + errhint("Possible values are: \"string\", \"numeric\", \"boolean\", \"key\", and \"all\"."))); } - /* user should not get it */ + /* expect end of array now */ if (type != WJB_END_ARRAY) elog(ERROR, "unexpected end of flag array"); /* get final WJB_DONE and free iterator */ - JsonbIteratorNext(&it, &v, false); + type = JsonbIteratorNext(&it, &v, false); + if (type != WJB_DONE) + elog(ERROR, "unexpected end of flag array"); return flags; } @@ -5023,7 +4970,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, /* * Just recursively iterating over jsonb and call callback on all - * correspoding elements + * corresponding elements */ while ((type = JsonbIteratorNext(&it, &v, false)) != WJB_DONE) { @@ -5041,7 +4988,7 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, } /* JsonbValue is a value of object or element of array */ - switch(v.type) + switch (v.type) { case jbvString: if (flags & jtiString) @@ -5050,10 +4997,10 @@ iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, case jbvNumeric: if (flags & jtiNumeric) { - char *val; + char *val; val = DatumGetCString(DirectFunctionCall1(numeric_out, - NumericGetDatum(v.val.numeric))); + NumericGetDatum(v.val.numeric))); action(state, val, strlen(val)); pfree(val); @@ -5108,7 +5055,7 @@ iterate_values_scalar(void *state, char *token, JsonTokenType tokentype) { IterateJsonStringValuesState *_state = (IterateJsonStringValuesState *) state; - switch(tokentype) + switch (tokentype) { case JSON_TOKEN_STRING: if (_state->flags & jtiString) @@ -5136,7 +5083,8 @@ iterate_values_object_field_start(void *state, char *fname, bool isnull) if (_state->flags & jtiKey) { - char *val = pstrdup(fname); + char *val = pstrdup(fname); + _state->action(_state->action_state, val, strlen(val)); } } diff --git a/src/backend/utils/adt/jsonpath.c b/src/backend/utils/adt/jsonpath.c new file mode 100644 index 00000000000..e683cbef7c6 --- /dev/null +++ b/src/backend/utils/adt/jsonpath.c @@ -0,0 +1,1075 @@ +/*------------------------------------------------------------------------- + * + * jsonpath.c + * Input/output and supporting routines for jsonpath + * + * jsonpath expression is a chain of path items. First path item is $, $var, + * literal or arithmetic expression. Subsequent path items are accessors + * (.key, .*, [subscripts], [*]), filters (? (predicate)) and methods (.type(), + * .size() etc). + * + * For instance, structure of path items for simple expression: + * + * $.a[*].type() + * + * is pretty evident: + * + * $ => .a => [*] => .type() + * + * Some path items such as arithmetic operations, predicates or array + * subscripts may comprise subtrees. For instance, more complex expression + * + * ($.a + $[1 to 5, 7] ? (@ > 3).double()).type() + * + * have following structure of path items: + * + * + => .type() + * ___/ \___ + * / \ + * $ => .a $ => [] => ? => .double() + * _||_ | + * / \ > + * to to / \ + * / \ / @ 3 + * 1 5 7 + * + * Binary encoding of jsonpath constitutes a sequence of 4-bytes aligned + * variable-length path items connected by links. Every item has a header + * consisting of item type (enum JsonPathItemType) and offset of next item + * (zero means no next item). After the header, item may have payload + * depending on item type. For instance, payload of '.key' accessor item is + * length of key name and key name itself. Payload of '>' arithmetic operator + * item is offsets of right and left operands. + * + * So, binary representation of sample expression above is: + * (bottom arrows are next links, top lines are argument links) + * + * _____ + * _____ ___/____ \ __ + * _ /_ \ _____/__/____ \ \ __ _ /_ \ + * / / \ \ / / / \ \ \ / \ / / \ \ + * +(LR) $ .a $ [](* to *, * to *) 1 5 7 ?(A) >(LR) @ 3 .double() .type() + * | | ^ | ^| ^| ^ ^ + * | |__| |__||________________________||___________________| | + * |_______________________________________________________________________| + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/utils/adt/jsonpath.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "funcapi.h" +#include "lib/stringinfo.h" +#include "libpq/pqformat.h" +#include "miscadmin.h" +#include "utils/builtins.h" +#include "utils/json.h" +#include "utils/jsonpath.h" + + +static Datum jsonPathFromCstring(char *in, int len); +static char *jsonPathToCstring(StringInfo out, JsonPath *in, + int estimated_len); +static int flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item, + int nestingLevel, bool insideArraySubscript); +static void alignStringInfoInt(StringInfo buf); +static int32 reserveSpaceForItemPointer(StringInfo buf); +static void printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, + bool printBracketes); +static int operationPriority(JsonPathItemType op); + + +/**************************** INPUT/OUTPUT ********************************/ + +/* + * jsonpath type input function + */ +Datum +jsonpath_in(PG_FUNCTION_ARGS) +{ + char *in = PG_GETARG_CSTRING(0); + int len = strlen(in); + + return jsonPathFromCstring(in, len); +} + +/* + * jsonpath type recv function + * + * The type is sent as text in binary mode, so this is almost the same + * as the input function, but it's prefixed with a version number so we + * can change the binary format sent in future if necessary. For now, + * only version 1 is supported. + */ +Datum +jsonpath_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + int version = pq_getmsgint(buf, 1); + char *str; + int nbytes; + + if (version == JSONPATH_VERSION) + str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes); + else + elog(ERROR, "unsupported jsonpath version number: %d", version); + + return jsonPathFromCstring(str, nbytes); +} + +/* + * jsonpath type output function + */ +Datum +jsonpath_out(PG_FUNCTION_ARGS) +{ + JsonPath *in = PG_GETARG_JSONPATH_P(0); + + PG_RETURN_CSTRING(jsonPathToCstring(NULL, in, VARSIZE(in))); +} + +/* + * jsonpath type send function + * + * Just send jsonpath as a version number, then a string of text + */ +Datum +jsonpath_send(PG_FUNCTION_ARGS) +{ + JsonPath *in = PG_GETARG_JSONPATH_P(0); + StringInfoData buf; + StringInfoData jtext; + int version = JSONPATH_VERSION; + + initStringInfo(&jtext); + (void) jsonPathToCstring(&jtext, in, VARSIZE(in)); + + pq_begintypsend(&buf); + pq_sendint8(&buf, version); + pq_sendtext(&buf, jtext.data, jtext.len); + pfree(jtext.data); + + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + +/* + * Converts C-string to a jsonpath value. + * + * Uses jsonpath parser to turn string into an AST, then + * flattenJsonPathParseItem() does second pass turning AST into binary + * representation of jsonpath. + */ +static Datum +jsonPathFromCstring(char *in, int len) +{ + JsonPathParseResult *jsonpath = parsejsonpath(in, len); + JsonPath *res; + StringInfoData buf; + + initStringInfo(&buf); + enlargeStringInfo(&buf, 4 * len /* estimation */ ); + + appendStringInfoSpaces(&buf, JSONPATH_HDRSZ); + + if (!jsonpath) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", "jsonpath", + in))); + + flattenJsonPathParseItem(&buf, jsonpath->expr, 0, false); + + res = (JsonPath *) buf.data; + SET_VARSIZE(res, buf.len); + res->header = JSONPATH_VERSION; + if (jsonpath->lax) + res->header |= JSONPATH_LAX; + + PG_RETURN_JSONPATH_P(res); +} + +/* + * Converts jsonpath value to a C-string. + * + * If 'out' argument is non-null, the resulting C-string is stored inside the + * StringBuffer. The resulting string is always returned. + */ +static char * +jsonPathToCstring(StringInfo out, JsonPath *in, int estimated_len) +{ + StringInfoData buf; + JsonPathItem v; + + if (!out) + { + out = &buf; + initStringInfo(out); + } + enlargeStringInfo(out, estimated_len); + + if (!(in->header & JSONPATH_LAX)) + appendBinaryStringInfo(out, "strict ", 7); + + jspInit(&v, in); + printJsonPathItem(out, &v, false, true); + + return out->data; +} + +/* + * Recursive function converting given jsonpath parse item and all its + * children into a binary representation. + */ +static int +flattenJsonPathParseItem(StringInfo buf, JsonPathParseItem *item, + int nestingLevel, bool insideArraySubscript) +{ + /* position from beginning of jsonpath data */ + int32 pos = buf->len - JSONPATH_HDRSZ; + int32 chld; + int32 next; + int argNestingLevel = 0; + + check_stack_depth(); + CHECK_FOR_INTERRUPTS(); + + appendStringInfoChar(buf, (char) (item->type)); + + /* + * We align buffer to int32 because a series of int32 values often goes + * after the header, and we want to read them directly by dereferencing + * int32 pointer (see jspInitByBuffer()). + */ + alignStringInfoInt(buf); + + /* + * Reserve space for next item pointer. Actual value will be recorded + * later, after next and children items processing. + */ + next = reserveSpaceForItemPointer(buf); + + switch (item->type) + { + case jpiString: + case jpiVariable: + case jpiKey: + appendBinaryStringInfo(buf, (char *) &item->value.string.len, + sizeof(item->value.string.len)); + appendBinaryStringInfo(buf, item->value.string.val, + item->value.string.len); + appendStringInfoChar(buf, '\0'); + break; + case jpiNumeric: + appendBinaryStringInfo(buf, (char *) item->value.numeric, + VARSIZE(item->value.numeric)); + break; + case jpiBool: + appendBinaryStringInfo(buf, (char *) &item->value.boolean, + sizeof(item->value.boolean)); + break; + case jpiAnd: + case jpiOr: + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + case jpiAdd: + case jpiSub: + case jpiMul: + case jpiDiv: + case jpiMod: + case jpiStartsWith: + { + /* + * First, reserve place for left/right arg's positions, then + * record both args and sets actual position in reserved + * places. + */ + int32 left = reserveSpaceForItemPointer(buf); + int32 right = reserveSpaceForItemPointer(buf); + + chld = !item->value.args.left ? pos : + flattenJsonPathParseItem(buf, item->value.args.left, + nestingLevel + argNestingLevel, + insideArraySubscript); + *(int32 *) (buf->data + left) = chld - pos; + + chld = !item->value.args.right ? pos : + flattenJsonPathParseItem(buf, item->value.args.right, + nestingLevel + argNestingLevel, + insideArraySubscript); + *(int32 *) (buf->data + right) = chld - pos; + } + break; + case jpiLikeRegex: + { + int32 offs; + + appendBinaryStringInfo(buf, + (char *) &item->value.like_regex.flags, + sizeof(item->value.like_regex.flags)); + offs = reserveSpaceForItemPointer(buf); + appendBinaryStringInfo(buf, + (char *) &item->value.like_regex.patternlen, + sizeof(item->value.like_regex.patternlen)); + appendBinaryStringInfo(buf, item->value.like_regex.pattern, + item->value.like_regex.patternlen); + appendStringInfoChar(buf, '\0'); + + chld = flattenJsonPathParseItem(buf, item->value.like_regex.expr, + nestingLevel, + insideArraySubscript); + *(int32 *) (buf->data + offs) = chld - pos; + } + break; + case jpiFilter: + argNestingLevel++; + /* FALLTHROUGH */ + case jpiIsUnknown: + case jpiNot: + case jpiPlus: + case jpiMinus: + case jpiExists: + case jpiDatetime: + { + int32 arg = reserveSpaceForItemPointer(buf); + + chld = !item->value.arg ? pos : + flattenJsonPathParseItem(buf, item->value.arg, + nestingLevel + argNestingLevel, + insideArraySubscript); + *(int32 *) (buf->data + arg) = chld - pos; + } + break; + case jpiNull: + break; + case jpiRoot: + break; + case jpiAnyArray: + case jpiAnyKey: + break; + case jpiCurrent: + if (nestingLevel <= 0) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("@ is not allowed in root expressions"))); + break; + case jpiLast: + if (!insideArraySubscript) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("LAST is allowed only in array subscripts"))); + break; + case jpiIndexArray: + { + int32 nelems = item->value.array.nelems; + int offset; + int i; + + appendBinaryStringInfo(buf, (char *) &nelems, sizeof(nelems)); + + offset = buf->len; + + appendStringInfoSpaces(buf, sizeof(int32) * 2 * nelems); + + for (i = 0; i < nelems; i++) + { + int32 *ppos; + int32 topos; + int32 frompos = + flattenJsonPathParseItem(buf, + item->value.array.elems[i].from, + nestingLevel, true) - pos; + + if (item->value.array.elems[i].to) + topos = flattenJsonPathParseItem(buf, + item->value.array.elems[i].to, + nestingLevel, true) - pos; + else + topos = 0; + + ppos = (int32 *) &buf->data[offset + i * 2 * sizeof(int32)]; + + ppos[0] = frompos; + ppos[1] = topos; + } + } + break; + case jpiAny: + appendBinaryStringInfo(buf, + (char *) &item->value.anybounds.first, + sizeof(item->value.anybounds.first)); + appendBinaryStringInfo(buf, + (char *) &item->value.anybounds.last, + sizeof(item->value.anybounds.last)); + break; + case jpiType: + case jpiSize: + case jpiAbs: + case jpiFloor: + case jpiCeiling: + case jpiDouble: + case jpiKeyValue: + break; + default: + elog(ERROR, "unrecognized jsonpath item type: %d", item->type); + } + + if (item->next) + { + chld = flattenJsonPathParseItem(buf, item->next, nestingLevel, + insideArraySubscript) - pos; + *(int32 *) (buf->data + next) = chld; + } + + return pos; +} + +/* + * Align StringInfo to int by adding zero padding bytes + */ +static void +alignStringInfoInt(StringInfo buf) +{ + switch (INTALIGN(buf->len) - buf->len) + { + case 3: + appendStringInfoCharMacro(buf, 0); + /* FALLTHROUGH */ + case 2: + appendStringInfoCharMacro(buf, 0); + /* FALLTHROUGH */ + case 1: + appendStringInfoCharMacro(buf, 0); + /* FALLTHROUGH */ + default: + break; + } +} + +/* + * Reserve space for int32 JsonPathItem pointer. Now zero pointer is written, + * actual value will be recorded at '(int32 *) &buf->data[pos]' later. + */ +static int32 +reserveSpaceForItemPointer(StringInfo buf) +{ + int32 pos = buf->len; + int32 ptr = 0; + + appendBinaryStringInfo(buf, (char *) &ptr, sizeof(ptr)); + + return pos; +} + +/* + * Prints text representation of given jsonpath item and all its children. + */ +static void +printJsonPathItem(StringInfo buf, JsonPathItem *v, bool inKey, + bool printBracketes) +{ + JsonPathItem elem; + int i; + + check_stack_depth(); + CHECK_FOR_INTERRUPTS(); + + switch (v->type) + { + case jpiNull: + appendStringInfoString(buf, "null"); + break; + case jpiKey: + if (inKey) + appendStringInfoChar(buf, '.'); + escape_json(buf, jspGetString(v, NULL)); + break; + case jpiString: + escape_json(buf, jspGetString(v, NULL)); + break; + case jpiVariable: + appendStringInfoChar(buf, '$'); + escape_json(buf, jspGetString(v, NULL)); + break; + case jpiNumeric: + appendStringInfoString(buf, + DatumGetCString(DirectFunctionCall1(numeric_out, + NumericGetDatum(jspGetNumeric(v))))); + break; + case jpiBool: + if (jspGetBool(v)) + appendBinaryStringInfo(buf, "true", 4); + else + appendBinaryStringInfo(buf, "false", 5); + break; + case jpiAnd: + case jpiOr: + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + case jpiAdd: + case jpiSub: + case jpiMul: + case jpiDiv: + case jpiMod: + case jpiStartsWith: + if (printBracketes) + appendStringInfoChar(buf, '('); + jspGetLeftArg(v, &elem); + printJsonPathItem(buf, &elem, false, + operationPriority(elem.type) <= + operationPriority(v->type)); + appendStringInfoChar(buf, ' '); + appendStringInfoString(buf, jspOperationName(v->type)); + appendStringInfoChar(buf, ' '); + jspGetRightArg(v, &elem); + printJsonPathItem(buf, &elem, false, + operationPriority(elem.type) <= + operationPriority(v->type)); + if (printBracketes) + appendStringInfoChar(buf, ')'); + break; + case jpiLikeRegex: + if (printBracketes) + appendStringInfoChar(buf, '('); + + jspInitByBuffer(&elem, v->base, v->content.like_regex.expr); + printJsonPathItem(buf, &elem, false, + operationPriority(elem.type) <= + operationPriority(v->type)); + + appendBinaryStringInfo(buf, " like_regex ", 12); + + escape_json(buf, v->content.like_regex.pattern); + + if (v->content.like_regex.flags) + { + appendBinaryStringInfo(buf, " flag \"", 7); + + if (v->content.like_regex.flags & JSP_REGEX_ICASE) + appendStringInfoChar(buf, 'i'); + if (v->content.like_regex.flags & JSP_REGEX_DOTALL) + appendStringInfoChar(buf, 's'); + if (v->content.like_regex.flags & JSP_REGEX_MLINE) + appendStringInfoChar(buf, 'm'); + if (v->content.like_regex.flags & JSP_REGEX_WSPACE) + appendStringInfoChar(buf, 'x'); + if (v->content.like_regex.flags & JSP_REGEX_QUOTE) + appendStringInfoChar(buf, 'q'); + + appendStringInfoChar(buf, '"'); + } + + if (printBracketes) + appendStringInfoChar(buf, ')'); + break; + case jpiPlus: + case jpiMinus: + if (printBracketes) + appendStringInfoChar(buf, '('); + appendStringInfoChar(buf, v->type == jpiPlus ? '+' : '-'); + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, + operationPriority(elem.type) <= + operationPriority(v->type)); + if (printBracketes) + appendStringInfoChar(buf, ')'); + break; + case jpiFilter: + appendBinaryStringInfo(buf, "?(", 2); + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, false); + appendStringInfoChar(buf, ')'); + break; + case jpiNot: + appendBinaryStringInfo(buf, "!(", 2); + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, false); + appendStringInfoChar(buf, ')'); + break; + case jpiIsUnknown: + appendStringInfoChar(buf, '('); + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, false); + appendBinaryStringInfo(buf, ") is unknown", 12); + break; + case jpiExists: + appendBinaryStringInfo(buf, "exists (", 8); + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, false); + appendStringInfoChar(buf, ')'); + break; + case jpiCurrent: + Assert(!inKey); + appendStringInfoChar(buf, '@'); + break; + case jpiRoot: + Assert(!inKey); + appendStringInfoChar(buf, '$'); + break; + case jpiLast: + appendBinaryStringInfo(buf, "last", 4); + break; + case jpiAnyArray: + appendBinaryStringInfo(buf, "[*]", 3); + break; + case jpiAnyKey: + if (inKey) + appendStringInfoChar(buf, '.'); + appendStringInfoChar(buf, '*'); + break; + case jpiIndexArray: + appendStringInfoChar(buf, '['); + for (i = 0; i < v->content.array.nelems; i++) + { + JsonPathItem from; + JsonPathItem to; + bool range = jspGetArraySubscript(v, &from, &to, i); + + if (i) + appendStringInfoChar(buf, ','); + + printJsonPathItem(buf, &from, false, false); + + if (range) + { + appendBinaryStringInfo(buf, " to ", 4); + printJsonPathItem(buf, &to, false, false); + } + } + appendStringInfoChar(buf, ']'); + break; + case jpiAny: + if (inKey) + appendStringInfoChar(buf, '.'); + + if (v->content.anybounds.first == 0 && + v->content.anybounds.last == PG_UINT32_MAX) + appendBinaryStringInfo(buf, "**", 2); + else if (v->content.anybounds.first == v->content.anybounds.last) + { + if (v->content.anybounds.first == PG_UINT32_MAX) + appendStringInfo(buf, "**{last}"); + else + appendStringInfo(buf, "**{%u}", + v->content.anybounds.first); + } + else if (v->content.anybounds.first == PG_UINT32_MAX) + appendStringInfo(buf, "**{last to %u}", + v->content.anybounds.last); + else if (v->content.anybounds.last == PG_UINT32_MAX) + appendStringInfo(buf, "**{%u to last}", + v->content.anybounds.first); + else + appendStringInfo(buf, "**{%u to %u}", + v->content.anybounds.first, + v->content.anybounds.last); + break; + case jpiType: + appendBinaryStringInfo(buf, ".type()", 7); + break; + case jpiSize: + appendBinaryStringInfo(buf, ".size()", 7); + break; + case jpiAbs: + appendBinaryStringInfo(buf, ".abs()", 6); + break; + case jpiFloor: + appendBinaryStringInfo(buf, ".floor()", 8); + break; + case jpiCeiling: + appendBinaryStringInfo(buf, ".ceiling()", 10); + break; + case jpiDouble: + appendBinaryStringInfo(buf, ".double()", 9); + break; + case jpiDatetime: + appendBinaryStringInfo(buf, ".datetime(", 10); + if (v->content.arg) + { + jspGetArg(v, &elem); + printJsonPathItem(buf, &elem, false, false); + } + appendStringInfoChar(buf, ')'); + break; + case jpiKeyValue: + appendBinaryStringInfo(buf, ".keyvalue()", 11); + break; + default: + elog(ERROR, "unrecognized jsonpath item type: %d", v->type); + } + + if (jspGetNext(v, &elem)) + printJsonPathItem(buf, &elem, true, true); +} + +const char * +jspOperationName(JsonPathItemType type) +{ + switch (type) + { + case jpiAnd: + return "&&"; + case jpiOr: + return "||"; + case jpiEqual: + return "=="; + case jpiNotEqual: + return "!="; + case jpiLess: + return "<"; + case jpiGreater: + return ">"; + case jpiLessOrEqual: + return "<="; + case jpiGreaterOrEqual: + return ">="; + case jpiPlus: + case jpiAdd: + return "+"; + case jpiMinus: + case jpiSub: + return "-"; + case jpiMul: + return "*"; + case jpiDiv: + return "/"; + case jpiMod: + return "%"; + case jpiStartsWith: + return "starts with"; + case jpiLikeRegex: + return "like_regex"; + case jpiType: + return "type"; + case jpiSize: + return "size"; + case jpiKeyValue: + return "keyvalue"; + case jpiDouble: + return "double"; + case jpiAbs: + return "abs"; + case jpiFloor: + return "floor"; + case jpiCeiling: + return "ceiling"; + case jpiDatetime: + return "datetime"; + default: + elog(ERROR, "unrecognized jsonpath item type: %d", type); + return NULL; + } +} + +static int +operationPriority(JsonPathItemType op) +{ + switch (op) + { + case jpiOr: + return 0; + case jpiAnd: + return 1; + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + case jpiStartsWith: + return 2; + case jpiAdd: + case jpiSub: + return 3; + case jpiMul: + case jpiDiv: + case jpiMod: + return 4; + case jpiPlus: + case jpiMinus: + return 5; + default: + return 6; + } +} + +/******************* Support functions for JsonPath *************************/ + +/* + * Support macros to read stored values + */ + +#define read_byte(v, b, p) do { \ + (v) = *(uint8*)((b) + (p)); \ + (p) += 1; \ +} while(0) \ + +#define read_int32(v, b, p) do { \ + (v) = *(uint32*)((b) + (p)); \ + (p) += sizeof(int32); \ +} while(0) \ + +#define read_int32_n(v, b, p, n) do { \ + (v) = (void *)((b) + (p)); \ + (p) += sizeof(int32) * (n); \ +} while(0) \ + +/* + * Read root node and fill root node representation + */ +void +jspInit(JsonPathItem *v, JsonPath *js) +{ + Assert((js->header & ~JSONPATH_LAX) == JSONPATH_VERSION); + jspInitByBuffer(v, js->data, 0); +} + +/* + * Read node from buffer and fill its representation + */ +void +jspInitByBuffer(JsonPathItem *v, char *base, int32 pos) +{ + v->base = base + pos; + + read_byte(v->type, base, pos); + pos = INTALIGN((uintptr_t) (base + pos)) - (uintptr_t) base; + read_int32(v->nextPos, base, pos); + + switch (v->type) + { + case jpiNull: + case jpiRoot: + case jpiCurrent: + case jpiAnyArray: + case jpiAnyKey: + case jpiType: + case jpiSize: + case jpiAbs: + case jpiFloor: + case jpiCeiling: + case jpiDouble: + case jpiKeyValue: + case jpiLast: + break; + case jpiKey: + case jpiString: + case jpiVariable: + read_int32(v->content.value.datalen, base, pos); + /* FALLTHROUGH */ + case jpiNumeric: + case jpiBool: + v->content.value.data = base + pos; + break; + case jpiAnd: + case jpiOr: + case jpiAdd: + case jpiSub: + case jpiMul: + case jpiDiv: + case jpiMod: + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + case jpiStartsWith: + read_int32(v->content.args.left, base, pos); + read_int32(v->content.args.right, base, pos); + break; + case jpiLikeRegex: + read_int32(v->content.like_regex.flags, base, pos); + read_int32(v->content.like_regex.expr, base, pos); + read_int32(v->content.like_regex.patternlen, base, pos); + v->content.like_regex.pattern = base + pos; + break; + case jpiNot: + case jpiExists: + case jpiIsUnknown: + case jpiPlus: + case jpiMinus: + case jpiFilter: + case jpiDatetime: + read_int32(v->content.arg, base, pos); + break; + case jpiIndexArray: + read_int32(v->content.array.nelems, base, pos); + read_int32_n(v->content.array.elems, base, pos, + v->content.array.nelems * 2); + break; + case jpiAny: + read_int32(v->content.anybounds.first, base, pos); + read_int32(v->content.anybounds.last, base, pos); + break; + default: + elog(ERROR, "unrecognized jsonpath item type: %d", v->type); + } +} + +void +jspGetArg(JsonPathItem *v, JsonPathItem *a) +{ + Assert(v->type == jpiFilter || + v->type == jpiNot || + v->type == jpiIsUnknown || + v->type == jpiExists || + v->type == jpiPlus || + v->type == jpiMinus || + v->type == jpiDatetime); + + jspInitByBuffer(a, v->base, v->content.arg); +} + +bool +jspGetNext(JsonPathItem *v, JsonPathItem *a) +{ + if (jspHasNext(v)) + { + Assert(v->type == jpiString || + v->type == jpiNumeric || + v->type == jpiBool || + v->type == jpiNull || + v->type == jpiKey || + v->type == jpiAny || + v->type == jpiAnyArray || + v->type == jpiAnyKey || + v->type == jpiIndexArray || + v->type == jpiFilter || + v->type == jpiCurrent || + v->type == jpiExists || + v->type == jpiRoot || + v->type == jpiVariable || + v->type == jpiLast || + v->type == jpiAdd || + v->type == jpiSub || + v->type == jpiMul || + v->type == jpiDiv || + v->type == jpiMod || + v->type == jpiPlus || + v->type == jpiMinus || + v->type == jpiEqual || + v->type == jpiNotEqual || + v->type == jpiGreater || + v->type == jpiGreaterOrEqual || + v->type == jpiLess || + v->type == jpiLessOrEqual || + v->type == jpiAnd || + v->type == jpiOr || + v->type == jpiNot || + v->type == jpiIsUnknown || + v->type == jpiType || + v->type == jpiSize || + v->type == jpiAbs || + v->type == jpiFloor || + v->type == jpiCeiling || + v->type == jpiDouble || + v->type == jpiDatetime || + v->type == jpiKeyValue || + v->type == jpiStartsWith); + + if (a) + jspInitByBuffer(a, v->base, v->nextPos); + return true; + } + + return false; +} + +void +jspGetLeftArg(JsonPathItem *v, JsonPathItem *a) +{ + Assert(v->type == jpiAnd || + v->type == jpiOr || + v->type == jpiEqual || + v->type == jpiNotEqual || + v->type == jpiLess || + v->type == jpiGreater || + v->type == jpiLessOrEqual || + v->type == jpiGreaterOrEqual || + v->type == jpiAdd || + v->type == jpiSub || + v->type == jpiMul || + v->type == jpiDiv || + v->type == jpiMod || + v->type == jpiStartsWith); + + jspInitByBuffer(a, v->base, v->content.args.left); +} + +void +jspGetRightArg(JsonPathItem *v, JsonPathItem *a) +{ + Assert(v->type == jpiAnd || + v->type == jpiOr || + v->type == jpiEqual || + v->type == jpiNotEqual || + v->type == jpiLess || + v->type == jpiGreater || + v->type == jpiLessOrEqual || + v->type == jpiGreaterOrEqual || + v->type == jpiAdd || + v->type == jpiSub || + v->type == jpiMul || + v->type == jpiDiv || + v->type == jpiMod || + v->type == jpiStartsWith); + + jspInitByBuffer(a, v->base, v->content.args.right); +} + +bool +jspGetBool(JsonPathItem *v) +{ + Assert(v->type == jpiBool); + + return (bool) *v->content.value.data; +} + +Numeric +jspGetNumeric(JsonPathItem *v) +{ + Assert(v->type == jpiNumeric); + + return (Numeric) v->content.value.data; +} + +char * +jspGetString(JsonPathItem *v, int32 *len) +{ + Assert(v->type == jpiKey || + v->type == jpiString || + v->type == jpiVariable); + + if (len) + *len = v->content.value.datalen; + return v->content.value.data; +} + +bool +jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, JsonPathItem *to, + int i) +{ + Assert(v->type == jpiIndexArray); + + jspInitByBuffer(from, v->base, v->content.array.elems[i].from); + + if (!v->content.array.elems[i].to) + return false; + + jspInitByBuffer(to, v->base, v->content.array.elems[i].to); + + return true; +} diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c new file mode 100644 index 00000000000..a35f718b96e --- /dev/null +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -0,0 +1,2774 @@ +/*------------------------------------------------------------------------- + * + * jsonpath_exec.c + * Routines for SQL/JSON path execution. + * + * Jsonpath is executed in the global context stored in JsonPathExecContext, + * which is passed to almost every function involved into execution. Entry + * point for jsonpath execution is executeJsonPath() function, which + * initializes execution context including initial JsonPathItem and JsonbValue, + * flags, stack for calculation of @ in filters. + * + * The result of jsonpath query execution is enum JsonPathExecResult and + * if succeeded sequence of JsonbValue, written to JsonValueList *found, which + * is passed through the jsonpath items. When found == NULL, we're inside + * exists-query and we're interested only in whether result is empty. In this + * case execution is stopped once first result item is found, and the only + * execution result is JsonPathExecResult. The values of JsonPathExecResult + * are following: + * - jperOk -- result sequence is not empty + * - jperNotFound -- result sequence is empty + * - jperError -- error occurred during execution + * + * Jsonpath is executed recursively (see executeItem()) starting form the + * first path item (which in turn might be, for instance, an arithmetic + * expression evaluated separately). On each step single JsonbValue obtained + * from previous path item is processed. The result of processing is a + * sequence of JsonbValue (probably empty), which is passed to the next path + * item one by one. When there is no next path item, then JsonbValue is added + * to the 'found' list. When found == NULL, then execution functions just + * return jperOk (see executeNextItem()). + * + * Many of jsonpath operations require automatic unwrapping of arrays in lax + * mode. So, if input value is array, then corresponding operation is + * processed not on array itself, but on all of its members one by one. + * executeItemOptUnwrapTarget() function have 'unwrap' argument, which indicates + * whether unwrapping of array is needed. When unwrap == true, each of array + * members is passed to executeItemOptUnwrapTarget() again but with unwrap == false + * in order to evade subsequent array unwrapping. + * + * All boolean expressions (predicates) are evaluated by executeBoolItem() + * function, which returns tri-state JsonPathBool. When error is occurred + * during predicate execution, it returns jpbUnknown. According to standard + * predicates can be only inside filters. But we support their usage as + * jsonpath expression. This helps us to implement @@ operator. In this case + * resulting JsonPathBool is transformed into jsonb bool or null. + * + * Arithmetic and boolean expression are evaluated recursively from expression + * tree top down to the leaves. Therefore, for binary arithmetic expressions + * we calculate operands first. Then we check that results are numeric + * singleton lists, calculate the result and pass it to the next path item. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/utils/adt/jsonpath_exec.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "catalog/pg_collation.h" +#include "catalog/pg_type.h" +#include "funcapi.h" +#include "lib/stringinfo.h" +#include "miscadmin.h" +#include "regex/regex.h" +#include "utils/builtins.h" +#include "utils/datetime.h" +#include "utils/datum.h" +#include "utils/formatting.h" +#include "utils/float.h" +#include "utils/guc.h" +#include "utils/json.h" +#include "utils/jsonpath.h" +#include "utils/date.h" +#include "utils/timestamp.h" +#include "utils/varlena.h" + + +/* + * Represents "base object" and it's "id" for .keyvalue() evaluation. + */ +typedef struct JsonBaseObjectInfo +{ + JsonbContainer *jbc; + int id; +} JsonBaseObjectInfo; + +/* + * Context of jsonpath execution. + */ +typedef struct JsonPathExecContext +{ + Jsonb *vars; /* variables to substitute into jsonpath */ + JsonbValue *root; /* for $ evaluation */ + JsonbValue *current; /* for @ evaluation */ + JsonBaseObjectInfo baseObject; /* "base object" for .keyvalue() + * evaluation */ + int lastGeneratedObjectId; /* "id" counter for .keyvalue() + * evaluation */ + int innermostArraySize; /* for LAST array index evaluation */ + bool laxMode; /* true for "lax" mode, false for "strict" + * mode */ + bool ignoreStructuralErrors; /* with "true" structural errors such + * as absence of required json item or + * unexpected json item type are + * ignored */ + bool throwErrors; /* with "false" all suppressible errors are + * suppressed */ + bool useTz; +} JsonPathExecContext; + +/* Context for LIKE_REGEX execution. */ +typedef struct JsonLikeRegexContext +{ + text *regex; + int cflags; +} JsonLikeRegexContext; + +/* Result of jsonpath predicate evaluation */ +typedef enum JsonPathBool +{ + jpbFalse = 0, + jpbTrue = 1, + jpbUnknown = 2 +} JsonPathBool; + +/* Result of jsonpath expression evaluation */ +typedef enum JsonPathExecResult +{ + jperOk = 0, + jperNotFound = 1, + jperError = 2 +} JsonPathExecResult; + +#define jperIsError(jper) ((jper) == jperError) + +/* + * List of jsonb values with shortcut for single-value list. + */ +typedef struct JsonValueList +{ + JsonbValue *singleton; + List *list; +} JsonValueList; + +typedef struct JsonValueListIterator +{ + JsonbValue *value; + List *list; + ListCell *next; +} JsonValueListIterator; + +/* strict/lax flags is decomposed into four [un]wrap/error flags */ +#define jspStrictAbsenseOfErrors(cxt) (!(cxt)->laxMode) +#define jspAutoUnwrap(cxt) ((cxt)->laxMode) +#define jspAutoWrap(cxt) ((cxt)->laxMode) +#define jspIgnoreStructuralErrors(cxt) ((cxt)->ignoreStructuralErrors) +#define jspThrowErrors(cxt) ((cxt)->throwErrors) + +/* Convenience macro: return or throw error depending on context */ +#define RETURN_ERROR(throw_error) \ +do { \ + if (jspThrowErrors(cxt)) \ + throw_error; \ + else \ + return jperError; \ +} while (0) + +typedef JsonPathBool (*JsonPathPredicateCallback) (JsonPathItem *jsp, + JsonbValue *larg, + JsonbValue *rarg, + void *param); +typedef Numeric (*BinaryArithmFunc) (Numeric num1, Numeric num2, bool *error); + +static JsonPathExecResult executeJsonPath(JsonPath *path, Jsonb *vars, + Jsonb *json, bool throwErrors, + JsonValueList *result, bool useTz); +static JsonPathExecResult executeItem(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found); +static JsonPathExecResult executeItemOptUnwrapTarget(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, + JsonValueList *found, bool unwrap); +static JsonPathExecResult executeItemUnwrapTargetArray(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, + JsonValueList *found, bool unwrapElements); +static JsonPathExecResult executeNextItem(JsonPathExecContext *cxt, + JsonPathItem *cur, JsonPathItem *next, + JsonbValue *v, JsonValueList *found, bool copy); +static JsonPathExecResult executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, + bool unwrap, JsonValueList *found); +static JsonPathExecResult executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, bool unwrap, JsonValueList *found); +static JsonPathBool executeBoolItem(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, bool canHaveNext); +static JsonPathBool executeNestedBoolItem(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb); +static JsonPathExecResult executeAnyItem(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbContainer *jbc, JsonValueList *found, + uint32 level, uint32 first, uint32 last, + bool ignoreStructuralErrors, bool unwrapNext); +static JsonPathBool executePredicate(JsonPathExecContext *cxt, + JsonPathItem *pred, JsonPathItem *larg, JsonPathItem *rarg, + JsonbValue *jb, bool unwrapRightArg, + JsonPathPredicateCallback exec, void *param); +static JsonPathExecResult executeBinaryArithmExpr(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, + BinaryArithmFunc func, JsonValueList *found); +static JsonPathExecResult executeUnaryArithmExpr(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, PGFunction func, + JsonValueList *found); +static JsonPathBool executeStartsWith(JsonPathItem *jsp, + JsonbValue *whole, JsonbValue *initial, void *param); +static JsonPathBool executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, + JsonbValue *rarg, void *param); +static JsonPathExecResult executeNumericItemMethod(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, bool unwrap, PGFunction func, + JsonValueList *found); +static JsonPathExecResult executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found); +static JsonPathExecResult executeKeyValueMethod(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, JsonValueList *found); +static JsonPathExecResult appendBoolResult(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonValueList *found, JsonPathBool res); +static void getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, + JsonbValue *value); +static void getJsonPathVariable(JsonPathExecContext *cxt, + JsonPathItem *variable, Jsonb *vars, JsonbValue *value); +static int JsonbArraySize(JsonbValue *jb); +static JsonPathBool executeComparison(JsonPathItem *cmp, JsonbValue *lv, + JsonbValue *rv, void *p); +static JsonPathBool compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, + bool useTz); +static int compareNumeric(Numeric a, Numeric b); +static JsonbValue *copyJsonbValue(JsonbValue *src); +static JsonPathExecResult getArrayIndex(JsonPathExecContext *cxt, + JsonPathItem *jsp, JsonbValue *jb, int32 *index); +static JsonBaseObjectInfo setBaseObject(JsonPathExecContext *cxt, + JsonbValue *jbv, int32 id); +static void JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv); +static int JsonValueListLength(const JsonValueList *jvl); +static bool JsonValueListIsEmpty(JsonValueList *jvl); +static JsonbValue *JsonValueListHead(JsonValueList *jvl); +static List *JsonValueListGetList(JsonValueList *jvl); +static void JsonValueListInitIterator(const JsonValueList *jvl, + JsonValueListIterator *it); +static JsonbValue *JsonValueListNext(const JsonValueList *jvl, + JsonValueListIterator *it); +static int JsonbType(JsonbValue *jb); +static JsonbValue *JsonbInitBinary(JsonbValue *jbv, Jsonb *jb); +static int JsonbType(JsonbValue *jb); +static JsonbValue *getScalar(JsonbValue *scalar, enum jbvType type); +static JsonbValue *wrapItemsInArray(const JsonValueList *items); +static int compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, + bool useTz, bool *have_error); + +/****************** User interface to JsonPath executor ********************/ + +/* + * jsonb_path_exists + * Returns true if jsonpath returns at least one item for the specified + * jsonb value. This function and jsonb_path_match() are used to + * implement @? and @@ operators, which in turn are intended to have an + * index support. Thus, it's desirable to make it easier to achieve + * consistency between index scan results and sequential scan results. + * So, we throw as less errors as possible. Regarding this function, + * such behavior also matches behavior of JSON_EXISTS() clause of + * SQL/JSON. Regarding jsonb_path_match(), this function doesn't have + * an analogy in SQL/JSON, so we define its behavior on our own. + */ +static Datum +jsonb_path_exists_internal(FunctionCallInfo fcinfo, bool tz) +{ + Jsonb *jb = PG_GETARG_JSONB_P(0); + JsonPath *jp = PG_GETARG_JSONPATH_P(1); + JsonPathExecResult res; + Jsonb *vars = NULL; + bool silent = true; + + if (PG_NARGS() == 4) + { + vars = PG_GETARG_JSONB_P(2); + silent = PG_GETARG_BOOL(3); + } + + res = executeJsonPath(jp, vars, jb, !silent, NULL, tz); + + PG_FREE_IF_COPY(jb, 0); + PG_FREE_IF_COPY(jp, 1); + + if (jperIsError(res)) + PG_RETURN_NULL(); + + PG_RETURN_BOOL(res == jperOk); +} + +Datum +jsonb_path_exists(PG_FUNCTION_ARGS) +{ + return jsonb_path_exists_internal(fcinfo, false); +} + +Datum +jsonb_path_exists_tz(PG_FUNCTION_ARGS) +{ + return jsonb_path_exists_internal(fcinfo, true); +} + +/* + * jsonb_path_exists_opr + * Implementation of operator "jsonb @? jsonpath" (2-argument version of + * jsonb_path_exists()). + */ +Datum +jsonb_path_exists_opr(PG_FUNCTION_ARGS) +{ + /* just call the other one -- it can handle both cases */ + return jsonb_path_exists_internal(fcinfo, false); +} + +/* + * jsonb_path_match + * Returns jsonpath predicate result item for the specified jsonb value. + * See jsonb_path_exists() comment for details regarding error handling. + */ +static Datum +jsonb_path_match_internal(FunctionCallInfo fcinfo, bool tz) +{ + Jsonb *jb = PG_GETARG_JSONB_P(0); + JsonPath *jp = PG_GETARG_JSONPATH_P(1); + JsonValueList found = {0}; + Jsonb *vars = NULL; + bool silent = true; + + if (PG_NARGS() == 4) + { + vars = PG_GETARG_JSONB_P(2); + silent = PG_GETARG_BOOL(3); + } + + (void) executeJsonPath(jp, vars, jb, !silent, &found, tz); + + PG_FREE_IF_COPY(jb, 0); + PG_FREE_IF_COPY(jp, 1); + + if (JsonValueListLength(&found) == 1) + { + JsonbValue *jbv = JsonValueListHead(&found); + + if (jbv->type == jbvBool) + PG_RETURN_BOOL(jbv->val.boolean); + + if (jbv->type == jbvNull) + PG_RETURN_NULL(); + } + + if (!silent) + ereport(ERROR, + (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED), + errmsg("single boolean result is expected"))); + + PG_RETURN_NULL(); +} + +Datum +jsonb_path_match(PG_FUNCTION_ARGS) +{ + return jsonb_path_match_internal(fcinfo, false); +} + +Datum +jsonb_path_match_tz(PG_FUNCTION_ARGS) +{ + return jsonb_path_match_internal(fcinfo, true); +} + +/* + * jsonb_path_match_opr + * Implementation of operator "jsonb @@ jsonpath" (2-argument version of + * jsonb_path_match()). + */ +Datum +jsonb_path_match_opr(PG_FUNCTION_ARGS) +{ + /* just call the other one -- it can handle both cases */ + return jsonb_path_match_internal(fcinfo, false); +} + +/* + * jsonb_path_query + * Executes jsonpath for given jsonb document and returns result as + * rowset. + */ +static Datum +jsonb_path_query_internal(FunctionCallInfo fcinfo, bool tz) +{ + FuncCallContext *funcctx; + List *found; + JsonbValue *v; + ListCell *c; + + if (SRF_IS_FIRSTCALL()) + { + JsonPath *jp; + Jsonb *jb; + MemoryContext oldcontext; + Jsonb *vars; + bool silent; + JsonValueList found = {0}; + + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + jb = PG_GETARG_JSONB_P_COPY(0); + jp = PG_GETARG_JSONPATH_P_COPY(1); + vars = PG_GETARG_JSONB_P_COPY(2); + silent = PG_GETARG_BOOL(3); + + (void) executeJsonPath(jp, vars, jb, !silent, &found, tz); + + funcctx->user_fctx = JsonValueListGetList(&found); + + MemoryContextSwitchTo(oldcontext); + } + + funcctx = SRF_PERCALL_SETUP(); + found = funcctx->user_fctx; + + c = list_head(found); + + if (c == NULL) + SRF_RETURN_DONE(funcctx); + + v = lfirst(c); + funcctx->user_fctx = list_delete_first(found); + + SRF_RETURN_NEXT(funcctx, JsonbPGetDatum(JsonbValueToJsonb(v))); +} + +Datum +jsonb_path_query(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_internal(fcinfo, false); +} + +Datum +jsonb_path_query_tz(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_internal(fcinfo, true); +} + +/* + * jsonb_path_query_array + * Executes jsonpath for given jsonb document and returns result as + * jsonb array. + */ +static Datum +jsonb_path_query_array_internal(FunctionCallInfo fcinfo, bool tz) +{ + Jsonb *jb = PG_GETARG_JSONB_P(0); + JsonPath *jp = PG_GETARG_JSONPATH_P(1); + JsonValueList found = {0}; + Jsonb *vars = PG_GETARG_JSONB_P(2); + bool silent = PG_GETARG_BOOL(3); + + (void) executeJsonPath(jp, vars, jb, !silent, &found, tz); + + PG_RETURN_JSONB_P(JsonbValueToJsonb(wrapItemsInArray(&found))); +} + +Datum +jsonb_path_query_array(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_array_internal(fcinfo, false); +} + +Datum +jsonb_path_query_array_tz(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_array_internal(fcinfo, true); +} + +/* + * jsonb_path_query_first + * Executes jsonpath for given jsonb document and returns first result + * item. If there are no items, NULL returned. + */ +static Datum +jsonb_path_query_first_internal(FunctionCallInfo fcinfo, bool tz) +{ + Jsonb *jb = PG_GETARG_JSONB_P(0); + JsonPath *jp = PG_GETARG_JSONPATH_P(1); + JsonValueList found = {0}; + Jsonb *vars = PG_GETARG_JSONB_P(2); + bool silent = PG_GETARG_BOOL(3); + + (void) executeJsonPath(jp, vars, jb, !silent, &found, tz); + + if (JsonValueListLength(&found) >= 1) + PG_RETURN_JSONB_P(JsonbValueToJsonb(JsonValueListHead(&found))); + else + PG_RETURN_NULL(); +} + +Datum +jsonb_path_query_first(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_first_internal(fcinfo, false); +} + +Datum +jsonb_path_query_first_tz(PG_FUNCTION_ARGS) +{ + return jsonb_path_query_first_internal(fcinfo, true); +} + +/********************Execute functions for JsonPath**************************/ + +/* + * Interface to jsonpath executor + * + * 'path' - jsonpath to be executed + * 'vars' - variables to be substituted to jsonpath + * 'json' - target document for jsonpath evaluation + * 'throwErrors' - whether we should throw suppressible errors + * 'result' - list to store result items into + * + * Returns an error if a recoverable error happens during processing, or NULL + * on no error. + * + * Note, jsonb and jsonpath values should be available and untoasted during + * work because JsonPathItem, JsonbValue and result item could have pointers + * into input values. If caller needs to just check if document matches + * jsonpath, then it doesn't provide a result arg. In this case executor + * works till first positive result and does not check the rest if possible. + * In other case it tries to find all the satisfied result items. + */ +static JsonPathExecResult +executeJsonPath(JsonPath *path, Jsonb *vars, Jsonb *json, bool throwErrors, + JsonValueList *result, bool useTz) +{ + JsonPathExecContext cxt; + JsonPathExecResult res; + JsonPathItem jsp; + JsonbValue jbv; + + jspInit(&jsp, path); + + if (!JsonbExtractScalar(&json->root, &jbv)) + JsonbInitBinary(&jbv, json); + + if (vars && !JsonContainerIsObject(&vars->root)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"vars\" argument is not an object"), + errdetail("Jsonpath parameters should be encoded as key-value pairs of \"vars\" object."))); + } + + cxt.vars = vars; + cxt.laxMode = (path->header & JSONPATH_LAX) != 0; + cxt.ignoreStructuralErrors = cxt.laxMode; + cxt.root = &jbv; + cxt.current = &jbv; + cxt.baseObject.jbc = NULL; + cxt.baseObject.id = 0; + cxt.lastGeneratedObjectId = vars ? 2 : 1; + cxt.innermostArraySize = -1; + cxt.throwErrors = throwErrors; + cxt.useTz = useTz; + + if (jspStrictAbsenseOfErrors(&cxt) && !result) + { + /* + * In strict mode we must get a complete list of values to check that + * there are no errors at all. + */ + JsonValueList vals = {0}; + + res = executeItem(&cxt, &jsp, &jbv, &vals); + + if (jperIsError(res)) + return res; + + return JsonValueListIsEmpty(&vals) ? jperNotFound : jperOk; + } + + res = executeItem(&cxt, &jsp, &jbv, result); + + Assert(!throwErrors || !jperIsError(res)); + + return res; +} + +/* + * Execute jsonpath with automatic unwrapping of current item in lax mode. + */ +static JsonPathExecResult +executeItem(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found) +{ + return executeItemOptUnwrapTarget(cxt, jsp, jb, found, jspAutoUnwrap(cxt)); +} + +/* + * Main jsonpath executor function: walks on jsonpath structure, finds + * relevant parts of jsonb and evaluates expressions over them. + * When 'unwrap' is true current SQL/JSON item is unwrapped if it is an array. + */ +static JsonPathExecResult +executeItemOptUnwrapTarget(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found, bool unwrap) +{ + JsonPathItem elem; + JsonPathExecResult res = jperNotFound; + JsonBaseObjectInfo baseObject; + + check_stack_depth(); + CHECK_FOR_INTERRUPTS(); + + switch (jsp->type) + { + /* all boolean item types: */ + case jpiAnd: + case jpiOr: + case jpiNot: + case jpiIsUnknown: + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + case jpiExists: + case jpiStartsWith: + case jpiLikeRegex: + { + JsonPathBool st = executeBoolItem(cxt, jsp, jb, true); + + res = appendBoolResult(cxt, jsp, found, st); + break; + } + + case jpiKey: + if (JsonbType(jb) == jbvObject) + { + JsonbValue *v; + JsonbValue key; + + key.type = jbvString; + key.val.string.val = jspGetString(jsp, &key.val.string.len); + + v = findJsonbValueFromContainer(jb->val.binary.data, + JB_FOBJECT, &key); + + if (v != NULL) + { + res = executeNextItem(cxt, jsp, NULL, + v, found, false); + + /* free value if it was not added to found list */ + if (jspHasNext(jsp) || !found) + pfree(v); + } + else if (!jspIgnoreStructuralErrors(cxt)) + { + Assert(found); + + if (!jspThrowErrors(cxt)) + return jperError; + + ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), \ + errmsg("JSON object does not contain key \"%s\"", + pnstrdup(key.val.string.val, + key.val.string.len)))); + } + } + else if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false); + else if (!jspIgnoreStructuralErrors(cxt)) + { + Assert(found); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_MEMBER_NOT_FOUND), + errmsg("jsonpath member accessor can only be applied to an object")))); + } + break; + + case jpiRoot: + jb = cxt->root; + baseObject = setBaseObject(cxt, jb, 0); + res = executeNextItem(cxt, jsp, NULL, jb, found, true); + cxt->baseObject = baseObject; + break; + + case jpiCurrent: + res = executeNextItem(cxt, jsp, NULL, cxt->current, + found, true); + break; + + case jpiAnyArray: + if (JsonbType(jb) == jbvArray) + { + bool hasNext = jspGetNext(jsp, &elem); + + res = executeItemUnwrapTargetArray(cxt, hasNext ? &elem : NULL, + jb, found, jspAutoUnwrap(cxt)); + } + else if (jspAutoWrap(cxt)) + res = executeNextItem(cxt, jsp, NULL, jb, found, true); + else if (!jspIgnoreStructuralErrors(cxt)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND), + errmsg("jsonpath wildcard array accessor can only be applied to an array")))); + break; + + case jpiIndexArray: + if (JsonbType(jb) == jbvArray || jspAutoWrap(cxt)) + { + int innermostArraySize = cxt->innermostArraySize; + int i; + int size = JsonbArraySize(jb); + bool singleton = size < 0; + bool hasNext = jspGetNext(jsp, &elem); + + if (singleton) + size = 1; + + cxt->innermostArraySize = size; /* for LAST evaluation */ + + for (i = 0; i < jsp->content.array.nelems; i++) + { + JsonPathItem from; + JsonPathItem to; + int32 index; + int32 index_from; + int32 index_to; + bool range = jspGetArraySubscript(jsp, &from, + &to, i); + + res = getArrayIndex(cxt, &from, jb, &index_from); + + if (jperIsError(res)) + break; + + if (range) + { + res = getArrayIndex(cxt, &to, jb, &index_to); + + if (jperIsError(res)) + break; + } + else + index_to = index_from; + + if (!jspIgnoreStructuralErrors(cxt) && + (index_from < 0 || + index_from > index_to || + index_to >= size)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT), + errmsg("jsonpath array subscript is out of bounds")))); + + if (index_from < 0) + index_from = 0; + + if (index_to >= size) + index_to = size - 1; + + res = jperNotFound; + + for (index = index_from; index <= index_to; index++) + { + JsonbValue *v; + bool copy; + + if (singleton) + { + v = jb; + copy = true; + } + else + { + v = getIthJsonbValueFromContainer(jb->val.binary.data, + (uint32) index); + + if (v == NULL) + continue; + + copy = false; + } + + if (!hasNext && !found) + return jperOk; + + res = executeNextItem(cxt, jsp, &elem, v, found, + copy); + + if (jperIsError(res)) + break; + + if (res == jperOk && !found) + break; + } + + if (jperIsError(res)) + break; + + if (res == jperOk && !found) + break; + } + + cxt->innermostArraySize = innermostArraySize; + } + else if (!jspIgnoreStructuralErrors(cxt)) + { + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND), + errmsg("jsonpath array accessor can only be applied to an array")))); + } + break; + + case jpiLast: + { + JsonbValue tmpjbv; + JsonbValue *lastjbv; + int last; + bool hasNext = jspGetNext(jsp, &elem); + + if (cxt->innermostArraySize < 0) + elog(ERROR, "evaluating jsonpath LAST outside of array subscript"); + + if (!hasNext && !found) + { + res = jperOk; + break; + } + + last = cxt->innermostArraySize - 1; + + lastjbv = hasNext ? &tmpjbv : palloc(sizeof(*lastjbv)); + + lastjbv->type = jbvNumeric; + lastjbv->val.numeric = + DatumGetNumeric(DirectFunctionCall1(int4_numeric, + Int32GetDatum(last))); + + res = executeNextItem(cxt, jsp, &elem, + lastjbv, found, hasNext); + } + break; + + case jpiAnyKey: + if (JsonbType(jb) == jbvObject) + { + bool hasNext = jspGetNext(jsp, &elem); + + if (jb->type != jbvBinary) + elog(ERROR, "invalid jsonb object type: %d", jb->type); + + return executeAnyItem + (cxt, hasNext ? &elem : NULL, + jb->val.binary.data, found, 1, 1, 1, + false, jspAutoUnwrap(cxt)); + } + else if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false); + else if (!jspIgnoreStructuralErrors(cxt)) + { + Assert(found); + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND), + errmsg("jsonpath wildcard member accessor can only be applied to an object")))); + } + break; + + case jpiAdd: + return executeBinaryArithmExpr(cxt, jsp, jb, + numeric_add_opt_error, found); + + case jpiSub: + return executeBinaryArithmExpr(cxt, jsp, jb, + numeric_sub_opt_error, found); + + case jpiMul: + return executeBinaryArithmExpr(cxt, jsp, jb, + numeric_mul_opt_error, found); + + case jpiDiv: + return executeBinaryArithmExpr(cxt, jsp, jb, + numeric_div_opt_error, found); + + case jpiMod: + return executeBinaryArithmExpr(cxt, jsp, jb, + numeric_mod_opt_error, found); + + case jpiPlus: + return executeUnaryArithmExpr(cxt, jsp, jb, NULL, found); + + case jpiMinus: + return executeUnaryArithmExpr(cxt, jsp, jb, numeric_uminus, + found); + + case jpiFilter: + { + JsonPathBool st; + + if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, + false); + + jspGetArg(jsp, &elem); + st = executeNestedBoolItem(cxt, &elem, jb); + if (st != jpbTrue) + res = jperNotFound; + else + res = executeNextItem(cxt, jsp, NULL, + jb, found, true); + break; + } + + case jpiAny: + { + bool hasNext = jspGetNext(jsp, &elem); + + /* first try without any intermediate steps */ + if (jsp->content.anybounds.first == 0) + { + bool savedIgnoreStructuralErrors; + + savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors; + cxt->ignoreStructuralErrors = true; + res = executeNextItem(cxt, jsp, &elem, + jb, found, true); + cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors; + + if (res == jperOk && !found) + break; + } + + if (jb->type == jbvBinary) + res = executeAnyItem + (cxt, hasNext ? &elem : NULL, + jb->val.binary.data, found, + 1, + jsp->content.anybounds.first, + jsp->content.anybounds.last, + true, jspAutoUnwrap(cxt)); + break; + } + + case jpiNull: + case jpiBool: + case jpiNumeric: + case jpiString: + case jpiVariable: + { + JsonbValue vbuf; + JsonbValue *v; + bool hasNext = jspGetNext(jsp, &elem); + + if (!hasNext && !found) + { + res = jperOk; /* skip evaluation */ + break; + } + + v = hasNext ? &vbuf : palloc(sizeof(*v)); + + baseObject = cxt->baseObject; + getJsonPathItem(cxt, jsp, v); + + res = executeNextItem(cxt, jsp, &elem, + v, found, hasNext); + cxt->baseObject = baseObject; + } + break; + + case jpiType: + { + JsonbValue *jbv = palloc(sizeof(*jbv)); + + jbv->type = jbvString; + jbv->val.string.val = pstrdup(JsonbTypeName(jb)); + jbv->val.string.len = strlen(jbv->val.string.val); + + res = executeNextItem(cxt, jsp, NULL, jbv, + found, false); + } + break; + + case jpiSize: + { + int size = JsonbArraySize(jb); + + if (size < 0) + { + if (!jspAutoWrap(cxt)) + { + if (!jspIgnoreStructuralErrors(cxt)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_ARRAY_NOT_FOUND), + errmsg("jsonpath item method .%s() can only be applied to an array", + jspOperationName(jsp->type))))); + break; + } + + size = 1; + } + + jb = palloc(sizeof(*jb)); + + jb->type = jbvNumeric; + jb->val.numeric = + DatumGetNumeric(DirectFunctionCall1(int4_numeric, + Int32GetDatum(size))); + + res = executeNextItem(cxt, jsp, NULL, jb, found, false); + } + break; + + case jpiAbs: + return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_abs, + found); + + case jpiFloor: + return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_floor, + found); + + case jpiCeiling: + return executeNumericItemMethod(cxt, jsp, jb, unwrap, numeric_ceil, + found); + + case jpiDouble: + { + JsonbValue jbv; + + if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, + false); + + if (jb->type == jbvNumeric) + { + char *tmp = DatumGetCString(DirectFunctionCall1(numeric_out, + NumericGetDatum(jb->val.numeric))); + bool have_error = false; + + (void) float8in_internal_opt_error(tmp, + NULL, + "double precision", + tmp, + &have_error); + + if (have_error) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM), + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); + res = jperOk; + } + else if (jb->type == jbvString) + { + /* cast string as double */ + double val; + char *tmp = pnstrdup(jb->val.string.val, + jb->val.string.len); + bool have_error = false; + + val = float8in_internal_opt_error(tmp, + NULL, + "double precision", + tmp, + &have_error); + + if (have_error || isinf(val)) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM), + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); + + jb = &jbv; + jb->type = jbvNumeric; + jb->val.numeric = DatumGetNumeric(DirectFunctionCall1(float8_numeric, + Float8GetDatum(val))); + res = jperOk; + } + + if (res == jperNotFound) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM), + errmsg("jsonpath item method .%s() can only be applied to a string or numeric value", + jspOperationName(jsp->type))))); + + res = executeNextItem(cxt, jsp, NULL, jb, found, true); + } + break; + + case jpiDatetime: + if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false); + + return executeDateTimeMethod(cxt, jsp, jb, found); + + case jpiKeyValue: + if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false); + + return executeKeyValueMethod(cxt, jsp, jb, found); + + default: + elog(ERROR, "unrecognized jsonpath item type: %d", jsp->type); + } + + return res; +} + +/* + * Unwrap current array item and execute jsonpath for each of its elements. + */ +static JsonPathExecResult +executeItemUnwrapTargetArray(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found, + bool unwrapElements) +{ + if (jb->type != jbvBinary) + { + Assert(jb->type != jbvArray); + elog(ERROR, "invalid jsonb array value type: %d", jb->type); + } + + return executeAnyItem + (cxt, jsp, jb->val.binary.data, found, 1, 1, 1, + false, unwrapElements); +} + +/* + * Execute next jsonpath item if exists. Otherwise put "v" to the "found" + * list if provided. + */ +static JsonPathExecResult +executeNextItem(JsonPathExecContext *cxt, + JsonPathItem *cur, JsonPathItem *next, + JsonbValue *v, JsonValueList *found, bool copy) +{ + JsonPathItem elem; + bool hasNext; + + if (!cur) + hasNext = next != NULL; + else if (next) + hasNext = jspHasNext(cur); + else + { + next = &elem; + hasNext = jspGetNext(cur, next); + } + + if (hasNext) + return executeItem(cxt, next, v, found); + + if (found) + JsonValueListAppend(found, copy ? copyJsonbValue(v) : v); + + return jperOk; +} + +/* + * Same as executeItem(), but when "unwrap == true" automatically unwraps + * each array item from the resulting sequence in lax mode. + */ +static JsonPathExecResult +executeItemOptUnwrapResult(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, bool unwrap, + JsonValueList *found) +{ + if (unwrap && jspAutoUnwrap(cxt)) + { + JsonValueList seq = {0}; + JsonValueListIterator it; + JsonPathExecResult res = executeItem(cxt, jsp, jb, &seq); + JsonbValue *item; + + if (jperIsError(res)) + return res; + + JsonValueListInitIterator(&seq, &it); + while ((item = JsonValueListNext(&seq, &it))) + { + Assert(item->type != jbvArray); + + if (JsonbType(item) == jbvArray) + executeItemUnwrapTargetArray(cxt, NULL, item, found, false); + else + JsonValueListAppend(found, item); + } + + return jperOk; + } + + return executeItem(cxt, jsp, jb, found); +} + +/* + * Same as executeItemOptUnwrapResult(), but with error suppression. + */ +static JsonPathExecResult +executeItemOptUnwrapResultNoThrow(JsonPathExecContext *cxt, + JsonPathItem *jsp, + JsonbValue *jb, bool unwrap, + JsonValueList *found) +{ + JsonPathExecResult res; + bool throwErrors = cxt->throwErrors; + + cxt->throwErrors = false; + res = executeItemOptUnwrapResult(cxt, jsp, jb, unwrap, found); + cxt->throwErrors = throwErrors; + + return res; +} + +/* Execute boolean-valued jsonpath expression. */ +static JsonPathBool +executeBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, bool canHaveNext) +{ + JsonPathItem larg; + JsonPathItem rarg; + JsonPathBool res; + JsonPathBool res2; + + if (!canHaveNext && jspHasNext(jsp)) + elog(ERROR, "boolean jsonpath item cannot have next item"); + + switch (jsp->type) + { + case jpiAnd: + jspGetLeftArg(jsp, &larg); + res = executeBoolItem(cxt, &larg, jb, false); + + if (res == jpbFalse) + return jpbFalse; + + /* + * SQL/JSON says that we should check second arg in case of + * jperError + */ + + jspGetRightArg(jsp, &rarg); + res2 = executeBoolItem(cxt, &rarg, jb, false); + + return res2 == jpbTrue ? res : res2; + + case jpiOr: + jspGetLeftArg(jsp, &larg); + res = executeBoolItem(cxt, &larg, jb, false); + + if (res == jpbTrue) + return jpbTrue; + + jspGetRightArg(jsp, &rarg); + res2 = executeBoolItem(cxt, &rarg, jb, false); + + return res2 == jpbFalse ? res : res2; + + case jpiNot: + jspGetArg(jsp, &larg); + + res = executeBoolItem(cxt, &larg, jb, false); + + if (res == jpbUnknown) + return jpbUnknown; + + return res == jpbTrue ? jpbFalse : jpbTrue; + + case jpiIsUnknown: + jspGetArg(jsp, &larg); + res = executeBoolItem(cxt, &larg, jb, false); + return res == jpbUnknown ? jpbTrue : jpbFalse; + + case jpiEqual: + case jpiNotEqual: + case jpiLess: + case jpiGreater: + case jpiLessOrEqual: + case jpiGreaterOrEqual: + jspGetLeftArg(jsp, &larg); + jspGetRightArg(jsp, &rarg); + return executePredicate(cxt, jsp, &larg, &rarg, jb, true, + executeComparison, cxt); + + case jpiStartsWith: /* 'whole STARTS WITH initial' */ + jspGetLeftArg(jsp, &larg); /* 'whole' */ + jspGetRightArg(jsp, &rarg); /* 'initial' */ + return executePredicate(cxt, jsp, &larg, &rarg, jb, false, + executeStartsWith, NULL); + + case jpiLikeRegex: /* 'expr LIKE_REGEX pattern FLAGS flags' */ + { + /* + * 'expr' is a sequence-returning expression. 'pattern' is a + * regex string literal. SQL/JSON standard requires XQuery + * regexes, but we use Postgres regexes here. 'flags' is a + * string literal converted to integer flags at compile-time. + */ + JsonLikeRegexContext lrcxt = {0}; + + jspInitByBuffer(&larg, jsp->base, + jsp->content.like_regex.expr); + + return executePredicate(cxt, jsp, &larg, NULL, jb, false, + executeLikeRegex, &lrcxt); + } + + case jpiExists: + jspGetArg(jsp, &larg); + + if (jspStrictAbsenseOfErrors(cxt)) + { + /* + * In strict mode we must get a complete list of values to + * check that there are no errors at all. + */ + JsonValueList vals = {0}; + JsonPathExecResult res = + executeItemOptUnwrapResultNoThrow(cxt, &larg, jb, + false, &vals); + + if (jperIsError(res)) + return jpbUnknown; + + return JsonValueListIsEmpty(&vals) ? jpbFalse : jpbTrue; + } + else + { + JsonPathExecResult res = + executeItemOptUnwrapResultNoThrow(cxt, &larg, jb, + false, NULL); + + if (jperIsError(res)) + return jpbUnknown; + + return res == jperOk ? jpbTrue : jpbFalse; + } + + default: + elog(ERROR, "invalid boolean jsonpath item type: %d", jsp->type); + return jpbUnknown; + } +} + +/* + * Execute nested (filters etc.) boolean expression pushing current SQL/JSON + * item onto the stack. + */ +static JsonPathBool +executeNestedBoolItem(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb) +{ + JsonbValue *prev; + JsonPathBool res; + + prev = cxt->current; + cxt->current = jb; + res = executeBoolItem(cxt, jsp, jb, false); + cxt->current = prev; + + return res; +} + +/* + * Implementation of several jsonpath nodes: + * - jpiAny (.** accessor), + * - jpiAnyKey (.* accessor), + * - jpiAnyArray ([*] accessor) + */ +static JsonPathExecResult +executeAnyItem(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbContainer *jbc, + JsonValueList *found, uint32 level, uint32 first, uint32 last, + bool ignoreStructuralErrors, bool unwrapNext) +{ + JsonPathExecResult res = jperNotFound; + JsonbIterator *it; + int32 r; + JsonbValue v; + + check_stack_depth(); + + if (level > last) + return res; + + it = JsonbIteratorInit(jbc); + + /* + * Recursively iterate over jsonb objects/arrays + */ + while ((r = JsonbIteratorNext(&it, &v, true)) != WJB_DONE) + { + if (r == WJB_KEY) + { + r = JsonbIteratorNext(&it, &v, true); + Assert(r == WJB_VALUE); + } + + if (r == WJB_VALUE || r == WJB_ELEM) + { + + if (level >= first || + (first == PG_UINT32_MAX && last == PG_UINT32_MAX && + v.type != jbvBinary)) /* leaves only requested */ + { + /* check expression */ + if (jsp) + { + if (ignoreStructuralErrors) + { + bool savedIgnoreStructuralErrors; + + savedIgnoreStructuralErrors = cxt->ignoreStructuralErrors; + cxt->ignoreStructuralErrors = true; + res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext); + cxt->ignoreStructuralErrors = savedIgnoreStructuralErrors; + } + else + res = executeItemOptUnwrapTarget(cxt, jsp, &v, found, unwrapNext); + + if (jperIsError(res)) + break; + + if (res == jperOk && !found) + break; + } + else if (found) + JsonValueListAppend(found, copyJsonbValue(&v)); + else + return jperOk; + } + + if (level < last && v.type == jbvBinary) + { + res = executeAnyItem + (cxt, jsp, v.val.binary.data, found, + level + 1, first, last, + ignoreStructuralErrors, unwrapNext); + + if (jperIsError(res)) + break; + + if (res == jperOk && found == NULL) + break; + } + } + } + + return res; +} + +/* + * Execute unary or binary predicate. + * + * Predicates have existence semantics, because their operands are item + * sequences. Pairs of items from the left and right operand's sequences are + * checked. TRUE returned only if any pair satisfying the condition is found. + * In strict mode, even if the desired pair has already been found, all pairs + * still need to be examined to check the absence of errors. If any error + * occurs, UNKNOWN (analogous to SQL NULL) is returned. + */ +static JsonPathBool +executePredicate(JsonPathExecContext *cxt, JsonPathItem *pred, + JsonPathItem *larg, JsonPathItem *rarg, JsonbValue *jb, + bool unwrapRightArg, JsonPathPredicateCallback exec, + void *param) +{ + JsonPathExecResult res; + JsonValueListIterator lseqit; + JsonValueList lseq = {0}; + JsonValueList rseq = {0}; + JsonbValue *lval; + bool error = false; + bool found = false; + + /* Left argument is always auto-unwrapped. */ + res = executeItemOptUnwrapResultNoThrow(cxt, larg, jb, true, &lseq); + if (jperIsError(res)) + return jpbUnknown; + + if (rarg) + { + /* Right argument is conditionally auto-unwrapped. */ + res = executeItemOptUnwrapResultNoThrow(cxt, rarg, jb, + unwrapRightArg, &rseq); + if (jperIsError(res)) + return jpbUnknown; + } + + JsonValueListInitIterator(&lseq, &lseqit); + while ((lval = JsonValueListNext(&lseq, &lseqit))) + { + JsonValueListIterator rseqit; + JsonbValue *rval; + bool first = true; + + JsonValueListInitIterator(&rseq, &rseqit); + if (rarg) + rval = JsonValueListNext(&rseq, &rseqit); + else + rval = NULL; + + /* Loop over right arg sequence or do single pass otherwise */ + while (rarg ? (rval != NULL) : first) + { + JsonPathBool res = exec(pred, lval, rval, param); + + if (res == jpbUnknown) + { + if (jspStrictAbsenseOfErrors(cxt)) + return jpbUnknown; + + error = true; + } + else if (res == jpbTrue) + { + if (!jspStrictAbsenseOfErrors(cxt)) + return jpbTrue; + + found = true; + } + + first = false; + if (rarg) + rval = JsonValueListNext(&rseq, &rseqit); + } + } + + if (found) /* possible only in strict mode */ + return jpbTrue; + + if (error) /* possible only in lax mode */ + return jpbUnknown; + + return jpbFalse; +} + +/* + * Execute binary arithmetic expression on singleton numeric operands. + * Array operands are automatically unwrapped in lax mode. + */ +static JsonPathExecResult +executeBinaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, BinaryArithmFunc func, + JsonValueList *found) +{ + JsonPathExecResult jper; + JsonPathItem elem; + JsonValueList lseq = {0}; + JsonValueList rseq = {0}; + JsonbValue *lval; + JsonbValue *rval; + Numeric res; + + jspGetLeftArg(jsp, &elem); + + /* + * XXX: By standard only operands of multiplicative expressions are + * unwrapped. We extend it to other binary arithmetic expressions too. + */ + jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &lseq); + if (jperIsError(jper)) + return jper; + + jspGetRightArg(jsp, &elem); + + jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &rseq); + if (jperIsError(jper)) + return jper; + + if (JsonValueListLength(&lseq) != 1 || + !(lval = getScalar(JsonValueListHead(&lseq), jbvNumeric))) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED), + errmsg("left operand of jsonpath operator %s is not a single numeric value", + jspOperationName(jsp->type))))); + + if (JsonValueListLength(&rseq) != 1 || + !(rval = getScalar(JsonValueListHead(&rseq), jbvNumeric))) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED), + errmsg("right operand of jsonpath operator %s is not a single numeric value", + jspOperationName(jsp->type))))); + + if (jspThrowErrors(cxt)) + { + res = func(lval->val.numeric, rval->val.numeric, NULL); + } + else + { + bool error = false; + + res = func(lval->val.numeric, rval->val.numeric, &error); + + if (error) + return jperError; + } + + if (!jspGetNext(jsp, &elem) && !found) + return jperOk; + + lval = palloc(sizeof(*lval)); + lval->type = jbvNumeric; + lval->val.numeric = res; + + return executeNextItem(cxt, jsp, &elem, lval, found, false); +} + +/* + * Execute unary arithmetic expression for each numeric item in its operand's + * sequence. Array operand is automatically unwrapped in lax mode. + */ +static JsonPathExecResult +executeUnaryArithmExpr(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, PGFunction func, JsonValueList *found) +{ + JsonPathExecResult jper; + JsonPathExecResult jper2; + JsonPathItem elem; + JsonValueList seq = {0}; + JsonValueListIterator it; + JsonbValue *val; + bool hasNext; + + jspGetArg(jsp, &elem); + jper = executeItemOptUnwrapResult(cxt, &elem, jb, true, &seq); + + if (jperIsError(jper)) + return jper; + + jper = jperNotFound; + + hasNext = jspGetNext(jsp, &elem); + + JsonValueListInitIterator(&seq, &it); + while ((val = JsonValueListNext(&seq, &it))) + { + if ((val = getScalar(val, jbvNumeric))) + { + if (!found && !hasNext) + return jperOk; + } + else + { + if (!found && !hasNext) + continue; /* skip non-numerics processing */ + + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_NUMBER_NOT_FOUND), + errmsg("operand of unary jsonpath operator %s is not a numeric value", + jspOperationName(jsp->type))))); + } + + if (func) + val->val.numeric = + DatumGetNumeric(DirectFunctionCall1(func, + NumericGetDatum(val->val.numeric))); + + jper2 = executeNextItem(cxt, jsp, &elem, val, found, false); + + if (jperIsError(jper2)) + return jper2; + + if (jper2 == jperOk) + { + if (!found) + return jperOk; + jper = jperOk; + } + } + + return jper; +} + +/* + * STARTS_WITH predicate callback. + * + * Check if the 'whole' string starts from 'initial' string. + */ +static JsonPathBool +executeStartsWith(JsonPathItem *jsp, JsonbValue *whole, JsonbValue *initial, + void *param) +{ + if (!(whole = getScalar(whole, jbvString))) + return jpbUnknown; /* error */ + + if (!(initial = getScalar(initial, jbvString))) + return jpbUnknown; /* error */ + + if (whole->val.string.len >= initial->val.string.len && + !memcmp(whole->val.string.val, + initial->val.string.val, + initial->val.string.len)) + return jpbTrue; + + return jpbFalse; +} + +/* + * LIKE_REGEX predicate callback. + * + * Check if the string matches regex pattern. + */ +static JsonPathBool +executeLikeRegex(JsonPathItem *jsp, JsonbValue *str, JsonbValue *rarg, + void *param) +{ + JsonLikeRegexContext *cxt = param; + + if (!(str = getScalar(str, jbvString))) + return jpbUnknown; + + /* Cache regex text and converted flags. */ + if (!cxt->regex) + { + cxt->regex = + cstring_to_text_with_len(jsp->content.like_regex.pattern, + jsp->content.like_regex.patternlen); + cxt->cflags = jspConvertRegexFlags(jsp->content.like_regex.flags); + } + + if (RE_compile_and_execute(cxt->regex, str->val.string.val, + str->val.string.len, + cxt->cflags, DEFAULT_COLLATION_OID, 0, NULL)) + return jpbTrue; + + return jpbFalse; +} + +/* + * Execute numeric item methods (.abs(), .floor(), .ceil()) using the specified + * user function 'func'. + */ +static JsonPathExecResult +executeNumericItemMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, bool unwrap, PGFunction func, + JsonValueList *found) +{ + JsonPathItem next; + Datum datum; + + if (unwrap && JsonbType(jb) == jbvArray) + return executeItemUnwrapTargetArray(cxt, jsp, jb, found, false); + + if (!(jb = getScalar(jb, jbvNumeric))) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_NON_NUMERIC_SQL_JSON_ITEM), + errmsg("jsonpath item method .%s() can only be applied to a numeric value", + jspOperationName(jsp->type))))); + + datum = DirectFunctionCall1(func, NumericGetDatum(jb->val.numeric)); + + if (!jspGetNext(jsp, &next) && !found) + return jperOk; + + jb = palloc(sizeof(*jb)); + jb->type = jbvNumeric; + jb->val.numeric = DatumGetNumeric(datum); + + return executeNextItem(cxt, jsp, &next, jb, found, false); +} + +/* + * Implementation of the .datetime() method. + * + * Converts a string into a date/time value. The actual type is determined at run time. + * If an argument is provided, this argument is used as a template string. + * Otherwise, the first fitting ISO format is selected. + */ +static JsonPathExecResult +executeDateTimeMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found) +{ + JsonbValue jbvbuf; + Datum value; + text *datetime; + Oid typid; + int32 typmod = -1; + int tz = 0; + bool hasNext; + JsonPathExecResult res = jperNotFound; + JsonPathItem elem; + + if (!(jb = getScalar(jb, jbvString))) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION), + errmsg("jsonpath item method .%s() can only be applied to a string", + jspOperationName(jsp->type))))); + + datetime = cstring_to_text_with_len(jb->val.string.val, + jb->val.string.len); + + if (jsp->content.arg) + { + text *template; + char *template_str; + int template_len; + bool have_error = false; + + jspGetArg(jsp, &elem); + + if (elem.type != jpiString) + elog(ERROR, "invalid jsonpath item type for .datetime() argument"); + + template_str = jspGetString(&elem, &template_len); + + template = cstring_to_text_with_len(template_str, + template_len); + + value = parse_datetime(datetime, template, true, + &typid, &typmod, &tz, + jspThrowErrors(cxt) ? NULL : &have_error); + + if (have_error) + res = jperError; + else + res = jperOk; + } + else + { + /* + * According to SQL/JSON standard enumerate ISO formats for: date, + * timetz, time, timestamptz, timestamp. + */ + static const char *fmt_str[] = + { + "yyyy-mm-dd", + "HH24:MI:SS TZH:TZM", + "HH24:MI:SS TZH", + "HH24:MI:SS", + "yyyy-mm-dd HH24:MI:SS TZH:TZM", + "yyyy-mm-dd HH24:MI:SS TZH", + "yyyy-mm-dd HH24:MI:SS" + }; + + /* cache for format texts */ + static text *fmt_txt[lengthof(fmt_str)] = {0}; + int i; + + /* loop until datetime format fits */ + for (i = 0; i < lengthof(fmt_str); i++) + { + bool have_error = false; + + if (!fmt_txt[i]) + { + MemoryContext oldcxt = + MemoryContextSwitchTo(TopMemoryContext); + + fmt_txt[i] = cstring_to_text(fmt_str[i]); + MemoryContextSwitchTo(oldcxt); + } + + value = parse_datetime(datetime, fmt_txt[i], true, + &typid, &typmod, &tz, + &have_error); + + if (!have_error) + { + res = jperOk; + break; + } + } + + if (res == jperNotFound) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION), + errmsg("datetime format is not unrecognized"), + errhint("use datetime template argument for explicit format specification")))); + } + + pfree(datetime); + + if (jperIsError(res)) + return res; + + hasNext = jspGetNext(jsp, &elem); + + if (!hasNext && !found) + return res; + + jb = hasNext ? &jbvbuf : palloc(sizeof(*jb)); + + jb->type = jbvDatetime; + jb->val.datetime.value = value; + jb->val.datetime.typid = typid; + jb->val.datetime.typmod = typmod; + jb->val.datetime.tz = tz; + + return executeNextItem(cxt, jsp, &elem, jb, found, hasNext); +} + +/* + * Implementation of .keyvalue() method. + * + * .keyvalue() method returns a sequence of object's key-value pairs in the + * following format: '{ "key": key, "value": value, "id": id }'. + * + * "id" field is an object identifier which is constructed from the two parts: + * base object id and its binary offset in base object's jsonb: + * id = 10000000000 * base_object_id + obj_offset_in_base_object + * + * 10000000000 (10^10) -- is a first round decimal number greater than 2^32 + * (maximal offset in jsonb). Decimal multiplier is used here to improve the + * readability of identifiers. + * + * Base object is usually a root object of the path: context item '$' or path + * variable '$var', literals can't produce objects for now. But if the path + * contains generated objects (.keyvalue() itself, for example), then they + * become base object for the subsequent .keyvalue(). + * + * Id of '$' is 0. Id of '$var' is its ordinal (positive) number in the list + * of variables (see getJsonPathVariable()). Ids for generated objects + * are assigned using global counter JsonPathExecContext.lastGeneratedObjectId. + */ +static JsonPathExecResult +executeKeyValueMethod(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonbValue *jb, JsonValueList *found) +{ + JsonPathExecResult res = jperNotFound; + JsonPathItem next; + JsonbContainer *jbc; + JsonbValue key; + JsonbValue val; + JsonbValue idval; + JsonbValue keystr; + JsonbValue valstr; + JsonbValue idstr; + JsonbIterator *it; + JsonbIteratorToken tok; + int64 id; + bool hasNext; + + if (JsonbType(jb) != jbvObject || jb->type != jbvBinary) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_SQL_JSON_OBJECT_NOT_FOUND), + errmsg("jsonpath item method .%s() can only be applied to an object", + jspOperationName(jsp->type))))); + + jbc = jb->val.binary.data; + + if (!JsonContainerSize(jbc)) + return jperNotFound; /* no key-value pairs */ + + hasNext = jspGetNext(jsp, &next); + + keystr.type = jbvString; + keystr.val.string.val = "key"; + keystr.val.string.len = 3; + + valstr.type = jbvString; + valstr.val.string.val = "value"; + valstr.val.string.len = 5; + + idstr.type = jbvString; + idstr.val.string.val = "id"; + idstr.val.string.len = 2; + + /* construct object id from its base object and offset inside that */ + id = jb->type != jbvBinary ? 0 : + (int64) ((char *) jbc - (char *) cxt->baseObject.jbc); + id += (int64) cxt->baseObject.id * INT64CONST(10000000000); + + idval.type = jbvNumeric; + idval.val.numeric = DatumGetNumeric(DirectFunctionCall1(int8_numeric, + Int64GetDatum(id))); + + it = JsonbIteratorInit(jbc); + + while ((tok = JsonbIteratorNext(&it, &key, true)) != WJB_DONE) + { + JsonBaseObjectInfo baseObject; + JsonbValue obj; + JsonbParseState *ps; + JsonbValue *keyval; + Jsonb *jsonb; + + if (tok != WJB_KEY) + continue; + + res = jperOk; + + if (!hasNext && !found) + break; + + tok = JsonbIteratorNext(&it, &val, true); + Assert(tok == WJB_VALUE); + + ps = NULL; + pushJsonbValue(&ps, WJB_BEGIN_OBJECT, NULL); + + pushJsonbValue(&ps, WJB_KEY, &keystr); + pushJsonbValue(&ps, WJB_VALUE, &key); + + pushJsonbValue(&ps, WJB_KEY, &valstr); + pushJsonbValue(&ps, WJB_VALUE, &val); + + pushJsonbValue(&ps, WJB_KEY, &idstr); + pushJsonbValue(&ps, WJB_VALUE, &idval); + + keyval = pushJsonbValue(&ps, WJB_END_OBJECT, NULL); + + jsonb = JsonbValueToJsonb(keyval); + + JsonbInitBinary(&obj, jsonb); + + baseObject = setBaseObject(cxt, &obj, cxt->lastGeneratedObjectId++); + + res = executeNextItem(cxt, jsp, &next, &obj, found, true); + + cxt->baseObject = baseObject; + + if (jperIsError(res)) + return res; + + if (res == jperOk && !found) + break; + } + + return res; +} + +/* + * Convert boolean execution status 'res' to a boolean JSON item and execute + * next jsonpath. + */ +static JsonPathExecResult +appendBoolResult(JsonPathExecContext *cxt, JsonPathItem *jsp, + JsonValueList *found, JsonPathBool res) +{ + JsonPathItem next; + JsonbValue jbv; + + if (!jspGetNext(jsp, &next) && !found) + return jperOk; /* found singleton boolean value */ + + if (res == jpbUnknown) + { + jbv.type = jbvNull; + } + else + { + jbv.type = jbvBool; + jbv.val.boolean = res == jpbTrue; + } + + return executeNextItem(cxt, jsp, &next, &jbv, found, true); +} + +/* + * Convert jsonpath's scalar or variable node to actual jsonb value. + * + * If node is a variable then its id returned, otherwise 0 returned. + */ +static void +getJsonPathItem(JsonPathExecContext *cxt, JsonPathItem *item, + JsonbValue *value) +{ + switch (item->type) + { + case jpiNull: + value->type = jbvNull; + break; + case jpiBool: + value->type = jbvBool; + value->val.boolean = jspGetBool(item); + break; + case jpiNumeric: + value->type = jbvNumeric; + value->val.numeric = jspGetNumeric(item); + break; + case jpiString: + value->type = jbvString; + value->val.string.val = jspGetString(item, + &value->val.string.len); + break; + case jpiVariable: + getJsonPathVariable(cxt, item, cxt->vars, value); + return; + default: + elog(ERROR, "unexpected jsonpath item type"); + } +} + +/* + * Get the value of variable passed to jsonpath executor + */ +static void +getJsonPathVariable(JsonPathExecContext *cxt, JsonPathItem *variable, + Jsonb *vars, JsonbValue *value) +{ + char *varName; + int varNameLength; + JsonbValue tmp; + JsonbValue *v; + + if (!vars) + { + value->type = jbvNull; + return; + } + + Assert(variable->type == jpiVariable); + varName = jspGetString(variable, &varNameLength); + tmp.type = jbvString; + tmp.val.string.val = varName; + tmp.val.string.len = varNameLength; + + v = findJsonbValueFromContainer(&vars->root, JB_FOBJECT, &tmp); + + if (v) + { + *value = *v; + pfree(v); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("could not find jsonpath variable \"%s\"", + pnstrdup(varName, varNameLength)))); + } + + JsonbInitBinary(&tmp, vars); + setBaseObject(cxt, &tmp, 1); +} + +/**************** Support functions for JsonPath execution *****************/ + +/* + * Returns the size of an array item, or -1 if item is not an array. + */ +static int +JsonbArraySize(JsonbValue *jb) +{ + Assert(jb->type != jbvArray); + + if (jb->type == jbvBinary) + { + JsonbContainer *jbc = jb->val.binary.data; + + if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc)) + return JsonContainerSize(jbc); + } + + return -1; +} + +/* Comparison predicate callback. */ +static JsonPathBool +executeComparison(JsonPathItem *cmp, JsonbValue *lv, JsonbValue *rv, void *p) +{ + JsonPathExecContext *cxt = (JsonPathExecContext *) p; + + return compareItems(cmp->type, lv, rv, cxt->useTz); +} + +/* + * Perform per-byte comparison of two strings. + */ +static int +binaryCompareStrings(const char *s1, int len1, + const char *s2, int len2) +{ + int cmp; + + cmp = memcmp(s1, s2, Min(len1, len2)); + + if (cmp != 0) + return cmp; + + if (len1 == len2) + return 0; + + return len1 < len2 ? -1 : 1; +} + +/* + * Compare two strings in the current server encoding using Unicode codepoint + * collation. + */ +static int +compareStrings(const char *mbstr1, int mblen1, + const char *mbstr2, int mblen2) +{ + if (GetDatabaseEncoding() == PG_SQL_ASCII || + GetDatabaseEncoding() == PG_UTF8) + { + /* + * It's known property of UTF-8 strings that their per-byte comparison + * result matches codepoints comparison result. ASCII can be + * considered as special case of UTF-8. + */ + return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2); + } + else + { + char *utf8str1, + *utf8str2; + int cmp, + utf8len1, + utf8len2; + + /* + * We have to convert other encodings to UTF-8 first, then compare. + * Input strings may be not null-terminated and pg_server_to_any() may + * return them "as is". So, use strlen() only if there is real + * conversion. + */ + utf8str1 = pg_server_to_any(mbstr1, mblen1, PG_UTF8); + utf8str2 = pg_server_to_any(mbstr2, mblen2, PG_UTF8); + utf8len1 = (mbstr1 == utf8str1) ? mblen1 : strlen(utf8str1); + utf8len2 = (mbstr2 == utf8str2) ? mblen2 : strlen(utf8str2); + + cmp = binaryCompareStrings(utf8str1, utf8len1, utf8str2, utf8len2); + + /* + * If pg_server_to_any() did no real conversion, then we actually + * compared original strings. So, we already done. + */ + if (mbstr1 == utf8str1 && mbstr2 == utf8str2) + return cmp; + + /* Free memory if needed */ + if (mbstr1 != utf8str1) + pfree(utf8str1); + if (mbstr2 != utf8str2) + pfree(utf8str2); + + /* + * When all Unicode codepoints are equal, return result of binary + * comparison. In some edge cases, same characters may have different + * representations in encoding. Then our behavior could diverge from + * standard. However, that allow us to do simple binary comparison + * for "==" operator, which is performance critical in typical cases. + * In future to implement strict standard conformance, we can do + * normalization of input JSON strings. + */ + if (cmp == 0) + return binaryCompareStrings(mbstr1, mblen1, mbstr2, mblen2); + else + return cmp; + } +} + +/* + * Compare two SQL/JSON items using comparison operation 'op'. + */ +static JsonPathBool +compareItems(int32 op, JsonbValue *jb1, JsonbValue *jb2, bool useTz) +{ + int cmp; + bool res; + + if (jb1->type != jb2->type) + { + if (jb1->type == jbvNull || jb2->type == jbvNull) + + /* + * Equality and order comparison of nulls to non-nulls returns + * always false, but inequality comparison returns true. + */ + return op == jpiNotEqual ? jpbTrue : jpbFalse; + + /* Non-null items of different types are not comparable. */ + return jpbUnknown; + } + + switch (jb1->type) + { + case jbvNull: + cmp = 0; + break; + case jbvBool: + cmp = jb1->val.boolean == jb2->val.boolean ? 0 : + jb1->val.boolean ? 1 : -1; + break; + case jbvNumeric: + cmp = compareNumeric(jb1->val.numeric, jb2->val.numeric); + break; + case jbvString: + if (op == jpiEqual) + return jb1->val.string.len != jb2->val.string.len || + memcmp(jb1->val.string.val, + jb2->val.string.val, + jb1->val.string.len) ? jpbFalse : jpbTrue; + + cmp = compareStrings(jb1->val.string.val, jb1->val.string.len, + jb2->val.string.val, jb2->val.string.len); + break; + case jbvDatetime: + { + bool have_error = false; + + cmp = compareDatetime(jb1->val.datetime.value, + jb1->val.datetime.typid, + jb2->val.datetime.value, + jb2->val.datetime.typid, + useTz, + &have_error); + + if (have_error) + return jpbUnknown; + } + break; + + case jbvBinary: + case jbvArray: + case jbvObject: + return jpbUnknown; /* non-scalars are not comparable */ + + default: + elog(ERROR, "invalid jsonb value type %d", jb1->type); + } + + switch (op) + { + case jpiEqual: + res = (cmp == 0); + break; + case jpiNotEqual: + res = (cmp != 0); + break; + case jpiLess: + res = (cmp < 0); + break; + case jpiGreater: + res = (cmp > 0); + break; + case jpiLessOrEqual: + res = (cmp <= 0); + break; + case jpiGreaterOrEqual: + res = (cmp >= 0); + break; + default: + elog(ERROR, "unrecognized jsonpath operation: %d", op); + return jpbUnknown; + } + + return res ? jpbTrue : jpbFalse; +} + +/* Compare two numerics */ +static int +compareNumeric(Numeric a, Numeric b) +{ + return DatumGetInt32(DirectFunctionCall2(numeric_cmp, + NumericGetDatum(a), + NumericGetDatum(b))); +} + +static JsonbValue * +copyJsonbValue(JsonbValue *src) +{ + JsonbValue *dst = palloc(sizeof(*dst)); + + *dst = *src; + + return dst; +} + +/* + * Execute array subscript expression and convert resulting numeric item to + * the integer type with truncation. + */ +static JsonPathExecResult +getArrayIndex(JsonPathExecContext *cxt, JsonPathItem *jsp, JsonbValue *jb, + int32 *index) +{ + JsonbValue *jbv; + JsonValueList found = {0}; + JsonPathExecResult res = executeItem(cxt, jsp, jb, &found); + Datum numeric_index; + bool have_error = false; + + if (jperIsError(res)) + return res; + + if (JsonValueListLength(&found) != 1 || + !(jbv = getScalar(JsonValueListHead(&found), jbvNumeric))) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT), + errmsg("jsonpath array subscript is not a single numeric value")))); + + numeric_index = DirectFunctionCall2(numeric_trunc, + NumericGetDatum(jbv->val.numeric), + Int32GetDatum(0)); + + *index = numeric_int4_opt_error(DatumGetNumeric(numeric_index), + &have_error); + + if (have_error) + RETURN_ERROR(ereport(ERROR, + (errcode(ERRCODE_INVALID_SQL_JSON_SUBSCRIPT), + errmsg("jsonpath array subscript is out of integer range")))); + + return jperOk; +} + +/* Save base object and its id needed for the execution of .keyvalue(). */ +static JsonBaseObjectInfo +setBaseObject(JsonPathExecContext *cxt, JsonbValue *jbv, int32 id) +{ + JsonBaseObjectInfo baseObject = cxt->baseObject; + + cxt->baseObject.jbc = jbv->type != jbvBinary ? NULL : + (JsonbContainer *) jbv->val.binary.data; + cxt->baseObject.id = id; + + return baseObject; +} + +static void +JsonValueListAppend(JsonValueList *jvl, JsonbValue *jbv) +{ + if (jvl->singleton) + { + jvl->list = list_make2(jvl->singleton, jbv); + jvl->singleton = NULL; + } + else if (!jvl->list) + jvl->singleton = jbv; + else + jvl->list = lappend(jvl->list, jbv); +} + +static int +JsonValueListLength(const JsonValueList *jvl) +{ + return jvl->singleton ? 1 : list_length(jvl->list); +} + +static bool +JsonValueListIsEmpty(JsonValueList *jvl) +{ + return !jvl->singleton && list_length(jvl->list) <= 0; +} + +static JsonbValue * +JsonValueListHead(JsonValueList *jvl) +{ + return jvl->singleton ? jvl->singleton : linitial(jvl->list); +} + +static List * +JsonValueListGetList(JsonValueList *jvl) +{ + if (jvl->singleton) + return list_make1(jvl->singleton); + + return jvl->list; +} + +static void +JsonValueListInitIterator(const JsonValueList *jvl, JsonValueListIterator *it) +{ + if (jvl->singleton) + { + it->value = jvl->singleton; + it->list = NIL; + it->next = NULL; + } + else if (jvl->list != NIL) + { + it->value = (JsonbValue *) linitial(jvl->list); + it->list = jvl->list; + it->next = list_second_cell(jvl->list); + } + else + { + it->value = NULL; + it->list = NIL; + it->next = NULL; + } +} + +/* + * Get the next item from the sequence advancing iterator. + */ +static JsonbValue * +JsonValueListNext(const JsonValueList *jvl, JsonValueListIterator *it) +{ + JsonbValue *result = it->value; + + if (it->next) + { + it->value = lfirst(it->next); + it->next = lnext(it->list, it->next); + } + else + { + it->value = NULL; + } + + return result; +} + +/* + * Initialize a binary JsonbValue with the given jsonb container. + */ +static JsonbValue * +JsonbInitBinary(JsonbValue *jbv, Jsonb *jb) +{ + jbv->type = jbvBinary; + jbv->val.binary.data = &jb->root; + jbv->val.binary.len = VARSIZE_ANY_EXHDR(jb); + + return jbv; +} + +/* + * Returns jbv* type of of JsonbValue. Note, it never returns jbvBinary as is. + */ +static int +JsonbType(JsonbValue *jb) +{ + int type = jb->type; + + if (jb->type == jbvBinary) + { + JsonbContainer *jbc = (void *) jb->val.binary.data; + + /* Scalars should be always extracted during jsonpath execution. */ + Assert(!JsonContainerIsScalar(jbc)); + + if (JsonContainerIsObject(jbc)) + type = jbvObject; + else if (JsonContainerIsArray(jbc)) + type = jbvArray; + else + elog(ERROR, "invalid jsonb container type: 0x%08x", jbc->header); + } + + return type; +} + +/* Get scalar of given type or NULL on type mismatch */ +static JsonbValue * +getScalar(JsonbValue *scalar, enum jbvType type) +{ + /* Scalars should be always extracted during jsonpath execution. */ + Assert(scalar->type != jbvBinary || + !JsonContainerIsScalar(scalar->val.binary.data)); + + return scalar->type == type ? scalar : NULL; +} + +/* Construct a JSON array from the item list */ +static JsonbValue * +wrapItemsInArray(const JsonValueList *items) +{ + JsonbParseState *ps = NULL; + JsonValueListIterator it; + JsonbValue *jbv; + + pushJsonbValue(&ps, WJB_BEGIN_ARRAY, NULL); + + JsonValueListInitIterator(items, &it); + while ((jbv = JsonValueListNext(items, &it))) + pushJsonbValue(&ps, WJB_ELEM, jbv); + + return pushJsonbValue(&ps, WJB_END_ARRAY, NULL); +} + +/* + * Cross-type comparison of two datetime SQL/JSON items. If items are + * uncomparable, 'error' flag is set. + */ +static int +compareDatetime(Datum val1, Oid typid1, Datum val2, Oid typid2, + bool useTz, bool *have_error) +{ + PGFunction cmpfunc = NULL; + + switch (typid1) + { + case DATEOID: + switch (typid2) + { + case DATEOID: + cmpfunc = date_cmp; + + break; + + case TIMESTAMPOID: + val1 = TimestampGetDatum(date2timestamp_opt_error(DatumGetDateADT(val1), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMESTAMPTZOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "date", "timestamptz"), + errhint("use *_tz() function for timezone support"))); + val1 = TimestampTzGetDatum(date2timestamptz_opt_error(DatumGetDateADT(val1), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMEOID: + case TIMETZOID: + *have_error = true; + return 0; + } + break; + + case TIMEOID: + switch (typid2) + { + case TIMEOID: + cmpfunc = time_cmp; + + break; + + case TIMETZOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "time", "timetz"), + errhint("use *_tz() function for timezone support"))); + val1 = DirectFunctionCall1(time_timetz, val1); + cmpfunc = timetz_cmp; + + break; + + case DATEOID: + case TIMESTAMPOID: + case TIMESTAMPTZOID: + *have_error = true; + return 0; + } + break; + + case TIMETZOID: + switch (typid2) + { + case TIMEOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "time", "timetz"), + errhint("use *_tz() function for timezone support"))); + val2 = DirectFunctionCall1(time_timetz, val2); + cmpfunc = timetz_cmp; + + break; + + case TIMETZOID: + cmpfunc = timetz_cmp; + + break; + + case DATEOID: + case TIMESTAMPOID: + case TIMESTAMPTZOID: + *have_error = true; + return 0; + } + break; + + case TIMESTAMPOID: + switch (typid2) + { + case DATEOID: + val2 = TimestampGetDatum(date2timestamp_opt_error(DatumGetDateADT(val2), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMESTAMPOID: + cmpfunc = timestamp_cmp; + + break; + + case TIMESTAMPTZOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "timestamp", "timestamptz"), + errhint("use *_tz() function for timezone support"))); + val1 = TimestampTzGetDatum(timestamp2timestamptz_opt_error(DatumGetTimestamp(val1), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMEOID: + case TIMETZOID: + *have_error = true; + return 0; + } + break; + + case TIMESTAMPTZOID: + switch (typid2) + { + case DATEOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "date", "timestamptz"), + errhint("use *_tz() function for timezone support"))); + val2 = TimestampTzGetDatum(date2timestamptz_opt_error(DatumGetDateADT(val2), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMESTAMPOID: + if (!useTz) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert value from %s to %s without timezone usage", + "timestamp", "timestamptz"), + errhint("use *_tz() function for timezone support"))); + val2 = TimestampTzGetDatum(timestamp2timestamptz_opt_error(DatumGetTimestamp(val2), have_error)); + if (have_error && *have_error) + return 0; + cmpfunc = timestamp_cmp; + + break; + + case TIMESTAMPTZOID: + cmpfunc = timestamp_cmp; + + break; + + case TIMEOID: + case TIMETZOID: + *have_error = true; + return 0; + } + break; + + default: + elog(ERROR, "unrecognized SQL/JSON datetime type oid: %d", + typid1); + } + + if (*have_error) + return 0; + + if (!cmpfunc) + elog(ERROR, "unrecognized SQL/JSON datetime type oid: %d", + typid2); + + *have_error = false; + + return DatumGetInt32(DirectFunctionCall2(cmpfunc, val1, val2)); +} diff --git a/src/backend/utils/adt/jsonpath_gram.y b/src/backend/utils/adt/jsonpath_gram.y new file mode 100644 index 00000000000..252f7051f65 --- /dev/null +++ b/src/backend/utils/adt/jsonpath_gram.y @@ -0,0 +1,597 @@ +%{ +/*------------------------------------------------------------------------- + * + * jsonpath_gram.y + * Grammar definitions for jsonpath datatype + * + * Transforms tokenized jsonpath into tree of JsonPathParseItem structs. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/utils/adt/jsonpath_gram.y + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "catalog/pg_collation.h" +#include "fmgr.h" +#include "miscadmin.h" +#include "nodes/pg_list.h" +#include "regex/regex.h" +#include "utils/builtins.h" +#include "utils/jsonpath.h" + +/* struct JsonPathString is shared between scan and gram */ +typedef struct JsonPathString +{ + char *val; + int len; + int total; +} JsonPathString; + +union YYSTYPE; + +/* flex 2.5.4 doesn't bother with a decl for this */ +int jsonpath_yylex(union YYSTYPE *yylval_param); +int jsonpath_yyparse(JsonPathParseResult **result); +void jsonpath_yyerror(JsonPathParseResult **result, const char *message); + +static JsonPathParseItem *makeItemType(JsonPathItemType type); +static JsonPathParseItem *makeItemString(JsonPathString *s); +static JsonPathParseItem *makeItemVariable(JsonPathString *s); +static JsonPathParseItem *makeItemKey(JsonPathString *s); +static JsonPathParseItem *makeItemNumeric(JsonPathString *s); +static JsonPathParseItem *makeItemBool(bool val); +static JsonPathParseItem *makeItemBinary(JsonPathItemType type, + JsonPathParseItem *la, + JsonPathParseItem *ra); +static JsonPathParseItem *makeItemUnary(JsonPathItemType type, + JsonPathParseItem *a); +static JsonPathParseItem *makeItemList(List *list); +static JsonPathParseItem *makeIndexArray(List *list); +static JsonPathParseItem *makeAny(int first, int last); +static JsonPathParseItem *makeItemLikeRegex(JsonPathParseItem *expr, + JsonPathString *pattern, + JsonPathString *flags); + +/* + * Bison doesn't allocate anything that needs to live across parser calls, + * so we can easily have it use palloc instead of malloc. This prevents + * memory leaks if we error out during parsing. Note this only works with + * bison >= 2.0. However, in bison 1.875 the default is to use alloca() + * if possible, so there's not really much problem anyhow, at least if + * you're building with gcc. + */ +#define YYMALLOC palloc +#define YYFREE pfree + +%} + +/* BISON Declarations */ +%pure-parser +%expect 0 +%name-prefix="jsonpath_yy" +%error-verbose +%parse-param {JsonPathParseResult **result} + +%union { + JsonPathString str; + List *elems; /* list of JsonPathParseItem */ + List *indexs; /* list of integers */ + JsonPathParseItem *value; + JsonPathParseResult *result; + JsonPathItemType optype; + bool boolean; + int integer; +} + +%token TO_P NULL_P TRUE_P FALSE_P IS_P UNKNOWN_P EXISTS_P +%token IDENT_P STRING_P NUMERIC_P INT_P VARIABLE_P +%token OR_P AND_P NOT_P +%token LESS_P LESSEQUAL_P EQUAL_P NOTEQUAL_P GREATEREQUAL_P GREATER_P +%token ANY_P STRICT_P LAX_P LAST_P STARTS_P WITH_P LIKE_REGEX_P FLAG_P +%token ABS_P SIZE_P TYPE_P FLOOR_P DOUBLE_P CEILING_P KEYVALUE_P +%token DATETIME_P + +%type result + +%type scalar_value path_primary expr array_accessor + any_path accessor_op key predicate delimited_predicate + index_elem starts_with_initial expr_or_predicate + datetime_template opt_datetime_template + +%type accessor_expr + +%type index_list + +%type comp_op method + +%type mode + +%type key_name + +%type any_level + +%left OR_P +%left AND_P +%right NOT_P +%left '+' '-' +%left '*' '/' '%' +%left UMINUS +%nonassoc '(' ')' + +/* Grammar follows */ +%% + +result: + mode expr_or_predicate { + *result = palloc(sizeof(JsonPathParseResult)); + (*result)->expr = $2; + (*result)->lax = $1; + } + | /* EMPTY */ { *result = NULL; } + ; + +expr_or_predicate: + expr { $$ = $1; } + | predicate { $$ = $1; } + ; + +mode: + STRICT_P { $$ = false; } + | LAX_P { $$ = true; } + | /* EMPTY */ { $$ = true; } + ; + +scalar_value: + STRING_P { $$ = makeItemString(&$1); } + | NULL_P { $$ = makeItemString(NULL); } + | TRUE_P { $$ = makeItemBool(true); } + | FALSE_P { $$ = makeItemBool(false); } + | NUMERIC_P { $$ = makeItemNumeric(&$1); } + | INT_P { $$ = makeItemNumeric(&$1); } + | VARIABLE_P { $$ = makeItemVariable(&$1); } + ; + +comp_op: + EQUAL_P { $$ = jpiEqual; } + | NOTEQUAL_P { $$ = jpiNotEqual; } + | LESS_P { $$ = jpiLess; } + | GREATER_P { $$ = jpiGreater; } + | LESSEQUAL_P { $$ = jpiLessOrEqual; } + | GREATEREQUAL_P { $$ = jpiGreaterOrEqual; } + ; + +delimited_predicate: + '(' predicate ')' { $$ = $2; } + | EXISTS_P '(' expr ')' { $$ = makeItemUnary(jpiExists, $3); } + ; + +predicate: + delimited_predicate { $$ = $1; } + | expr comp_op expr { $$ = makeItemBinary($2, $1, $3); } + | predicate AND_P predicate { $$ = makeItemBinary(jpiAnd, $1, $3); } + | predicate OR_P predicate { $$ = makeItemBinary(jpiOr, $1, $3); } + | NOT_P delimited_predicate { $$ = makeItemUnary(jpiNot, $2); } + | '(' predicate ')' IS_P UNKNOWN_P + { $$ = makeItemUnary(jpiIsUnknown, $2); } + | expr STARTS_P WITH_P starts_with_initial + { $$ = makeItemBinary(jpiStartsWith, $1, $4); } + | expr LIKE_REGEX_P STRING_P { $$ = makeItemLikeRegex($1, &$3, NULL); } + | expr LIKE_REGEX_P STRING_P FLAG_P STRING_P + { $$ = makeItemLikeRegex($1, &$3, &$5); } + ; + +starts_with_initial: + STRING_P { $$ = makeItemString(&$1); } + | VARIABLE_P { $$ = makeItemVariable(&$1); } + ; + +path_primary: + scalar_value { $$ = $1; } + | '$' { $$ = makeItemType(jpiRoot); } + | '@' { $$ = makeItemType(jpiCurrent); } + | LAST_P { $$ = makeItemType(jpiLast); } + ; + +accessor_expr: + path_primary { $$ = list_make1($1); } + | '(' expr ')' accessor_op { $$ = list_make2($2, $4); } + | '(' predicate ')' accessor_op { $$ = list_make2($2, $4); } + | accessor_expr accessor_op { $$ = lappend($1, $2); } + ; + +expr: + accessor_expr { $$ = makeItemList($1); } + | '(' expr ')' { $$ = $2; } + | '+' expr %prec UMINUS { $$ = makeItemUnary(jpiPlus, $2); } + | '-' expr %prec UMINUS { $$ = makeItemUnary(jpiMinus, $2); } + | expr '+' expr { $$ = makeItemBinary(jpiAdd, $1, $3); } + | expr '-' expr { $$ = makeItemBinary(jpiSub, $1, $3); } + | expr '*' expr { $$ = makeItemBinary(jpiMul, $1, $3); } + | expr '/' expr { $$ = makeItemBinary(jpiDiv, $1, $3); } + | expr '%' expr { $$ = makeItemBinary(jpiMod, $1, $3); } + ; + +index_elem: + expr { $$ = makeItemBinary(jpiSubscript, $1, NULL); } + | expr TO_P expr { $$ = makeItemBinary(jpiSubscript, $1, $3); } + ; + +index_list: + index_elem { $$ = list_make1($1); } + | index_list ',' index_elem { $$ = lappend($1, $3); } + ; + +array_accessor: + '[' '*' ']' { $$ = makeItemType(jpiAnyArray); } + | '[' index_list ']' { $$ = makeIndexArray($2); } + ; + +any_level: + INT_P { $$ = pg_atoi($1.val, 4, 0); } + | LAST_P { $$ = -1; } + ; + +any_path: + ANY_P { $$ = makeAny(0, -1); } + | ANY_P '{' any_level '}' { $$ = makeAny($3, $3); } + | ANY_P '{' any_level TO_P any_level '}' + { $$ = makeAny($3, $5); } + ; + +accessor_op: + '.' key { $$ = $2; } + | '.' '*' { $$ = makeItemType(jpiAnyKey); } + | array_accessor { $$ = $1; } + | '.' any_path { $$ = $2; } + | '.' method '(' ')' { $$ = makeItemType($2); } + | '.' DATETIME_P '(' opt_datetime_template ')' + { $$ = makeItemUnary(jpiDatetime, $4); } + | '?' '(' predicate ')' { $$ = makeItemUnary(jpiFilter, $3); } + ; + +datetime_template: + STRING_P { $$ = makeItemString(&$1); } + ; + +opt_datetime_template: + datetime_template { $$ = $1; } + | /* EMPTY */ { $$ = NULL; } + ; + +key: + key_name { $$ = makeItemKey(&$1); } + ; + +key_name: + IDENT_P + | STRING_P + | TO_P + | NULL_P + | TRUE_P + | FALSE_P + | IS_P + | UNKNOWN_P + | EXISTS_P + | STRICT_P + | LAX_P + | ABS_P + | SIZE_P + | TYPE_P + | FLOOR_P + | DOUBLE_P + | CEILING_P + | DATETIME_P + | KEYVALUE_P + | LAST_P + | STARTS_P + | WITH_P + | LIKE_REGEX_P + | FLAG_P + ; + +method: + ABS_P { $$ = jpiAbs; } + | SIZE_P { $$ = jpiSize; } + | TYPE_P { $$ = jpiType; } + | FLOOR_P { $$ = jpiFloor; } + | DOUBLE_P { $$ = jpiDouble; } + | CEILING_P { $$ = jpiCeiling; } + | KEYVALUE_P { $$ = jpiKeyValue; } + ; +%% + +/* + * The helper functions below allocate and fill JsonPathParseItem's of various + * types. + */ + +static JsonPathParseItem * +makeItemType(JsonPathItemType type) +{ + JsonPathParseItem *v = palloc(sizeof(*v)); + + CHECK_FOR_INTERRUPTS(); + + v->type = type; + v->next = NULL; + + return v; +} + +static JsonPathParseItem * +makeItemString(JsonPathString *s) +{ + JsonPathParseItem *v; + + if (s == NULL) + { + v = makeItemType(jpiNull); + } + else + { + v = makeItemType(jpiString); + v->value.string.val = s->val; + v->value.string.len = s->len; + } + + return v; +} + +static JsonPathParseItem * +makeItemVariable(JsonPathString *s) +{ + JsonPathParseItem *v; + + v = makeItemType(jpiVariable); + v->value.string.val = s->val; + v->value.string.len = s->len; + + return v; +} + +static JsonPathParseItem * +makeItemKey(JsonPathString *s) +{ + JsonPathParseItem *v; + + v = makeItemString(s); + v->type = jpiKey; + + return v; +} + +static JsonPathParseItem * +makeItemNumeric(JsonPathString *s) +{ + JsonPathParseItem *v; + + v = makeItemType(jpiNumeric); + v->value.numeric = + DatumGetNumeric(DirectFunctionCall3(numeric_in, + CStringGetDatum(s->val), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1))); + + return v; +} + +static JsonPathParseItem * +makeItemBool(bool val) +{ + JsonPathParseItem *v = makeItemType(jpiBool); + + v->value.boolean = val; + + return v; +} + +static JsonPathParseItem * +makeItemBinary(JsonPathItemType type, JsonPathParseItem *la, JsonPathParseItem *ra) +{ + JsonPathParseItem *v = makeItemType(type); + + v->value.args.left = la; + v->value.args.right = ra; + + return v; +} + +static JsonPathParseItem * +makeItemUnary(JsonPathItemType type, JsonPathParseItem *a) +{ + JsonPathParseItem *v; + + if (type == jpiPlus && a->type == jpiNumeric && !a->next) + return a; + + if (type == jpiMinus && a->type == jpiNumeric && !a->next) + { + v = makeItemType(jpiNumeric); + v->value.numeric = + DatumGetNumeric(DirectFunctionCall1(numeric_uminus, + NumericGetDatum(a->value.numeric))); + return v; + } + + v = makeItemType(type); + + v->value.arg = a; + + return v; +} + +static JsonPathParseItem * +makeItemList(List *list) +{ + JsonPathParseItem *head, + *end; + ListCell *cell; + + head = end = (JsonPathParseItem *) linitial(list); + + if (list_length(list) == 1) + return head; + + /* append items to the end of already existing list */ + while (end->next) + end = end->next; + + for_each_cell(cell, list, list_second_cell(list)) + { + JsonPathParseItem *c = (JsonPathParseItem *) lfirst(cell); + + end->next = c; + end = c; + } + + return head; +} + +static JsonPathParseItem * +makeIndexArray(List *list) +{ + JsonPathParseItem *v = makeItemType(jpiIndexArray); + ListCell *cell; + int i = 0; + + Assert(list_length(list) > 0); + v->value.array.nelems = list_length(list); + + v->value.array.elems = palloc(sizeof(v->value.array.elems[0]) * + v->value.array.nelems); + + foreach(cell, list) + { + JsonPathParseItem *jpi = lfirst(cell); + + Assert(jpi->type == jpiSubscript); + + v->value.array.elems[i].from = jpi->value.args.left; + v->value.array.elems[i++].to = jpi->value.args.right; + } + + return v; +} + +static JsonPathParseItem * +makeAny(int first, int last) +{ + JsonPathParseItem *v = makeItemType(jpiAny); + + v->value.anybounds.first = (first >= 0) ? first : PG_UINT32_MAX; + v->value.anybounds.last = (last >= 0) ? last : PG_UINT32_MAX; + + return v; +} + +static JsonPathParseItem * +makeItemLikeRegex(JsonPathParseItem *expr, JsonPathString *pattern, + JsonPathString *flags) +{ + JsonPathParseItem *v = makeItemType(jpiLikeRegex); + int i; + int cflags; + + v->value.like_regex.expr = expr; + v->value.like_regex.pattern = pattern->val; + v->value.like_regex.patternlen = pattern->len; + + /* Parse the flags string, convert to bitmask. Duplicate flags are OK. */ + v->value.like_regex.flags = 0; + for (i = 0; flags && i < flags->len; i++) + { + switch (flags->val[i]) + { + case 'i': + v->value.like_regex.flags |= JSP_REGEX_ICASE; + break; + case 's': + v->value.like_regex.flags |= JSP_REGEX_DOTALL; + break; + case 'm': + v->value.like_regex.flags |= JSP_REGEX_MLINE; + break; + case 'x': + v->value.like_regex.flags |= JSP_REGEX_WSPACE; + break; + case 'q': + v->value.like_regex.flags |= JSP_REGEX_QUOTE; + break; + default: + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("unrecognized flag character \"%c\" in LIKE_REGEX predicate", + flags->val[i]))); + break; + } + } + + /* Convert flags to what RE_compile_and_cache needs */ + cflags = jspConvertRegexFlags(v->value.like_regex.flags); + + /* check regex validity */ + (void) RE_compile_and_cache(cstring_to_text_with_len(pattern->val, + pattern->len), + cflags, DEFAULT_COLLATION_OID); + + return v; +} + +/* + * Convert from XQuery regex flags to those recognized by our regex library. + */ +int +jspConvertRegexFlags(uint32 xflags) +{ + /* By default, XQuery is very nearly the same as Spencer's AREs */ + int cflags = REG_ADVANCED; + + /* Ignore-case means the same thing, too, modulo locale issues */ + if (xflags & JSP_REGEX_ICASE) + cflags |= REG_ICASE; + + /* Per XQuery spec, if 'q' is specified then 'm', 's', 'x' are ignored */ + if (xflags & JSP_REGEX_QUOTE) + { + cflags &= ~REG_ADVANCED; + cflags |= REG_QUOTE; + } + else + { + /* Note that dotall mode is the default in POSIX */ + if (!(xflags & JSP_REGEX_DOTALL)) + cflags |= REG_NLSTOP; + if (xflags & JSP_REGEX_MLINE) + cflags |= REG_NLANCH; + + /* + * XQuery's 'x' mode is related to Spencer's expanded mode, but it's + * not really enough alike to justify treating JSP_REGEX_WSPACE as + * REG_EXPANDED. For now we treat 'x' as unimplemented; perhaps in + * future we'll modify the regex library to have an option for + * XQuery-style ignore-whitespace mode. + */ + if (xflags & JSP_REGEX_WSPACE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("XQuery \"x\" flag (expanded regular expressions) is not implemented"))); + } + + return cflags; +} + +/* + * jsonpath_scan.l is compiled as part of jsonpath_gram.y. Currently, this is + * unavoidable because jsonpath_gram does not create a .h file to export its + * token symbols. If these files ever grow large enough to be worth compiling + * separately, that could be fixed; but for now it seems like useless + * complication. + */ + +#include "jsonpath_scan.c" diff --git a/src/backend/utils/adt/jsonpath_scan.l b/src/backend/utils/adt/jsonpath_scan.l new file mode 100644 index 00000000000..9650226f507 --- /dev/null +++ b/src/backend/utils/adt/jsonpath_scan.l @@ -0,0 +1,646 @@ +%{ +/*------------------------------------------------------------------------- + * + * jsonpath_scan.l + * Lexical parser for jsonpath datatype + * + * Splits jsonpath string into tokens represented as JsonPathString structs. + * Decodes unicode and hex escaped strings. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/utils/adt/jsonpath_scan.l + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "mb/pg_wchar.h" +#include "nodes/pg_list.h" + +static JsonPathString scanstring; + +/* Handles to the buffer that the lexer uses internally */ +static YY_BUFFER_STATE scanbufhandle; +static char *scanbuf; +static int scanbuflen; + +static void addstring(bool init, char *s, int l); +static void addchar(bool init, char s); +static enum yytokentype checkKeyword(void); +static void parseUnicode(char *s, int l); +static void parseHexChar(char *s); + +/* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */ +#undef fprintf +#define fprintf(file, fmt, msg) fprintf_to_ereport(fmt, msg) + +static void +fprintf_to_ereport(const char *fmt, const char *msg) +{ + ereport(ERROR, (errmsg_internal("%s", msg))); +} + +%} + +%option 8bit +%option never-interactive +%option nodefault +%option noinput +%option nounput +%option noyywrap +%option warn +%option prefix="jsonpath_yy" +%option bison-bridge +%option noyyalloc +%option noyyrealloc +%option noyyfree + +/* + * We use exclusive states for quoted and non-quoted strings, + * quoted variable names and C-style comments. + * Exclusive states: + * - quoted strings + * - non-quoted strings + * - quoted variable names + * - C-style comment + */ + +%x xq +%x xnq +%x xvq +%x xc + +special [\?\%\$\.\[\]\{\}\(\)\|\&\!\=\<\>\@\#\,\*:\-\+\/] +blank [ \t\n\r\f] +/* "other" means anything that's not special, blank, or '\' or '"' */ +other [^\?\%\$\.\[\]\{\}\(\)\|\&\!\=\<\>\@\#\,\*:\-\+\/\\\" \t\n\r\f] + +digit [0-9] +integer (0|[1-9]{digit}*) +decimal {integer}\.{digit}+ +decimalfail {integer}\. +real ({integer}|{decimal})[Ee][-+]?{digit}+ +realfail1 ({integer}|{decimal})[Ee] +realfail2 ({integer}|{decimal})[Ee][-+] + +hex_dig [0-9A-Fa-f] +unicode \\u({hex_dig}{4}|\{{hex_dig}{1,6}\}) +unicodefail \\u({hex_dig}{0,3}|\{{hex_dig}{0,6}) +hex_char \\x{hex_dig}{2} +hex_fail \\x{hex_dig}{0,1} + +%% + +{other}+ { + addstring(false, yytext, yyleng); + } + +{blank}+ { + yylval->str = scanstring; + BEGIN INITIAL; + return checkKeyword(); + } + +\/\* { + yylval->str = scanstring; + BEGIN xc; + } + +({special}|\") { + yylval->str = scanstring; + yyless(0); + BEGIN INITIAL; + return checkKeyword(); + } + +<> { + yylval->str = scanstring; + BEGIN INITIAL; + return checkKeyword(); + } + +\\b { addchar(false, '\b'); } + +\\f { addchar(false, '\f'); } + +\\n { addchar(false, '\n'); } + +\\r { addchar(false, '\r'); } + +\\t { addchar(false, '\t'); } + +\\v { addchar(false, '\v'); } + +{unicode}+ { parseUnicode(yytext, yyleng); } + +{hex_char} { parseHexChar(yytext); } + +{unicode}*{unicodefail} { yyerror(NULL, "invalid unicode sequence"); } + +{hex_fail} { yyerror(NULL, "invalid hex character sequence"); } + +{unicode}+\\ { + /* throw back the \\, and treat as unicode */ + yyless(yyleng - 1); + parseUnicode(yytext, yyleng); + } + +\\. { addchar(false, yytext[1]); } + +\\ { yyerror(NULL, "unexpected end after backslash"); } + +<> { yyerror(NULL, "unexpected end of quoted string"); } + +\" { + yylval->str = scanstring; + BEGIN INITIAL; + return STRING_P; + } + +\" { + yylval->str = scanstring; + BEGIN INITIAL; + return VARIABLE_P; + } + +[^\\\"]+ { addstring(false, yytext, yyleng); } + +\*\/ { BEGIN INITIAL; } + +[^\*]+ { } + +\* { } + +<> { yyerror(NULL, "unexpected end of comment"); } + +\&\& { return AND_P; } + +\|\| { return OR_P; } + +\! { return NOT_P; } + +\*\* { return ANY_P; } + +\< { return LESS_P; } + +\<\= { return LESSEQUAL_P; } + +\=\= { return EQUAL_P; } + +\<\> { return NOTEQUAL_P; } + +\!\= { return NOTEQUAL_P; } + +\>\= { return GREATEREQUAL_P; } + +\> { return GREATER_P; } + +\${other}+ { + addstring(true, yytext + 1, yyleng - 1); + addchar(false, '\0'); + yylval->str = scanstring; + return VARIABLE_P; + } + +\$\" { + addchar(true, '\0'); + BEGIN xvq; + } + +{special} { return *yytext; } + +{blank}+ { /* ignore */ } + +\/\* { + addchar(true, '\0'); + BEGIN xc; + } + +{real} { + addstring(true, yytext, yyleng); + addchar(false, '\0'); + yylval->str = scanstring; + return NUMERIC_P; + } + +{decimal} { + addstring(true, yytext, yyleng); + addchar(false, '\0'); + yylval->str = scanstring; + return NUMERIC_P; + } + +{integer} { + addstring(true, yytext, yyleng); + addchar(false, '\0'); + yylval->str = scanstring; + return INT_P; + } + +{decimalfail} { + /* throw back the ., and treat as integer */ + yyless(yyleng - 1); + addstring(true, yytext, yyleng); + addchar(false, '\0'); + yylval->str = scanstring; + return INT_P; + } + +({realfail1}|{realfail2}) { yyerror(NULL, "invalid floating point number"); } + +\" { + addchar(true, '\0'); + BEGIN xq; + } + +\\ { + yyless(0); + addchar(true, '\0'); + BEGIN xnq; + } + +{other}+ { + addstring(true, yytext, yyleng); + BEGIN xnq; + } + +<> { yyterminate(); } + +%% + +void +jsonpath_yyerror(JsonPathParseResult **result, const char *message) +{ + if (*yytext == YY_END_OF_BUFFER_CHAR) + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + /* translator: %s is typically "syntax error" */ + errmsg("%s at end of jsonpath input", _(message)))); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + /* translator: first %s is typically "syntax error" */ + errmsg("%s at or near \"%s\" of jsonpath input", + _(message), yytext))); + } +} + +typedef struct JsonPathKeyword +{ + int16 len; + bool lowercase; + int val; + const char *keyword; +} JsonPathKeyword; + +/* + * Array of key words should be sorted by length and then + * alphabetical order + */ +static const JsonPathKeyword keywords[] = { + { 2, false, IS_P, "is"}, + { 2, false, TO_P, "to"}, + { 3, false, ABS_P, "abs"}, + { 3, false, LAX_P, "lax"}, + { 4, false, FLAG_P, "flag"}, + { 4, false, LAST_P, "last"}, + { 4, true, NULL_P, "null"}, + { 4, false, SIZE_P, "size"}, + { 4, true, TRUE_P, "true"}, + { 4, false, TYPE_P, "type"}, + { 4, false, WITH_P, "with"}, + { 5, true, FALSE_P, "false"}, + { 5, false, FLOOR_P, "floor"}, + { 6, false, DOUBLE_P, "double"}, + { 6, false, EXISTS_P, "exists"}, + { 6, false, STARTS_P, "starts"}, + { 6, false, STRICT_P, "strict"}, + { 7, false, CEILING_P, "ceiling"}, + { 7, false, UNKNOWN_P, "unknown"}, + { 8, false, DATETIME_P, "datetime"}, + { 8, false, KEYVALUE_P, "keyvalue"}, + { 10,false, LIKE_REGEX_P, "like_regex"}, +}; + +/* Check if current scanstring value is a keyword */ +static enum yytokentype +checkKeyword() +{ + int res = IDENT_P; + int diff; + const JsonPathKeyword *StopLow = keywords, + *StopHigh = keywords + lengthof(keywords), + *StopMiddle; + + if (scanstring.len > keywords[lengthof(keywords) - 1].len) + return res; + + while (StopLow < StopHigh) + { + StopMiddle = StopLow + ((StopHigh - StopLow) >> 1); + + if (StopMiddle->len == scanstring.len) + diff = pg_strncasecmp(StopMiddle->keyword, scanstring.val, + scanstring.len); + else + diff = StopMiddle->len - scanstring.len; + + if (diff < 0) + StopLow = StopMiddle + 1; + else if (diff > 0) + StopHigh = StopMiddle; + else + { + if (StopMiddle->lowercase) + diff = strncmp(StopMiddle->keyword, scanstring.val, + scanstring.len); + + if (diff == 0) + res = StopMiddle->val; + + break; + } + } + + return res; +} + +/* + * Called before any actual parsing is done + */ +static void +jsonpath_scanner_init(const char *str, int slen) +{ + if (slen <= 0) + slen = strlen(str); + + /* + * Might be left over after ereport() + */ + yy_init_globals(); + + /* + * Make a scan buffer with special termination needed by flex. + */ + + scanbuflen = slen; + scanbuf = palloc(slen + 2); + memcpy(scanbuf, str, slen); + scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; + scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); + + BEGIN(INITIAL); +} + + +/* + * Called after parsing is done to clean up after jsonpath_scanner_init() + */ +static void +jsonpath_scanner_finish(void) +{ + yy_delete_buffer(scanbufhandle); + pfree(scanbuf); +} + +/* + * Resize scanstring so that it can append string of given length. + * Reinitialize if required. + */ +static void +resizeString(bool init, int appendLen) +{ + if (init) + { + scanstring.total = Max(32, appendLen); + scanstring.val = (char *) palloc(scanstring.total); + scanstring.len = 0; + } + else + { + if (scanstring.len + appendLen >= scanstring.total) + { + while (scanstring.len + appendLen >= scanstring.total) + scanstring.total *= 2; + scanstring.val = repalloc(scanstring.val, scanstring.total); + } + } +} + +/* Add set of bytes at "s" of length "l" to scanstring */ +static void +addstring(bool init, char *s, int l) +{ + resizeString(init, l + 1); + memcpy(scanstring.val + scanstring.len, s, l); + scanstring.len += l; +} + +/* Add single byte "c" to scanstring */ +static void +addchar(bool init, char c) +{ + resizeString(init, 1); + scanstring.val[scanstring.len] = c; + if (c != '\0') + scanstring.len++; +} + +/* Interface to jsonpath parser */ +JsonPathParseResult * +parsejsonpath(const char *str, int len) +{ + JsonPathParseResult *parseresult; + + jsonpath_scanner_init(str, len); + + if (jsonpath_yyparse((void *) &parseresult) != 0) + jsonpath_yyerror(NULL, "bogus input"); /* shouldn't happen */ + + jsonpath_scanner_finish(); + + return parseresult; +} + +/* Turn hex character into integer */ +static int +hexval(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 0xA; + if (c >= 'A' && c <= 'F') + return c - 'A' + 0xA; + jsonpath_yyerror(NULL, "invalid hexadecimal digit"); + return 0; /* not reached */ +} + +/* Add given unicode character to scanstring */ +static void +addUnicodeChar(int ch) +{ + /* + * For UTF8, replace the escape sequence by the actual + * utf8 character in lex->strval. Do this also for other + * encodings if the escape designates an ASCII character, + * otherwise raise an error. + */ + + if (ch == 0) + { + /* We can't allow this, since our TEXT type doesn't */ + ereport(ERROR, + (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER), + errmsg("unsupported Unicode escape sequence"), + errdetail("\\u0000 cannot be converted to text."))); + } + else if (GetDatabaseEncoding() == PG_UTF8) + { + char utf8str[5]; + int utf8len; + + unicode_to_utf8(ch, (unsigned char *) utf8str); + utf8len = pg_utf_mblen((unsigned char *) utf8str); + addstring(false, utf8str, utf8len); + } + else if (ch <= 0x007f) + { + /* + * This is the only way to designate things like a + * form feed character in JSON, so it's useful in all + * encodings. + */ + addchar(false, (char) ch); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("Unicode escape values cannot be used for code " + "point values above 007F when the server encoding " + "is not UTF8."))); + } +} + +/* Add unicode character and process its hi surrogate */ +static void +addUnicode(int ch, int *hi_surrogate) +{ + if (ch >= 0xd800 && ch <= 0xdbff) + { + if (*hi_surrogate != -1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("Unicode high surrogate must not follow " + "a high surrogate."))); + *hi_surrogate = (ch & 0x3ff) << 10; + return; + } + else if (ch >= 0xdc00 && ch <= 0xdfff) + { + if (*hi_surrogate == -1) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("Unicode low surrogate must follow a high " + "surrogate."))); + ch = 0x10000 + *hi_surrogate + (ch & 0x3ff); + *hi_surrogate = -1; + } + else if (*hi_surrogate != -1) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("Unicode low surrogate must follow a high " + "surrogate."))); + } + + addUnicodeChar(ch); +} + +/* + * parseUnicode was adopted from json_lex_string() in + * src/backend/utils/adt/json.c + */ +static void +parseUnicode(char *s, int l) +{ + int i = 2; + int hi_surrogate = -1; + + for (i = 2; i < l; i += 2) /* skip '\u' */ + { + int ch = 0; + int j; + + if (s[i] == '{') /* parse '\u{XX...}' */ + { + while (s[++i] != '}' && i < l) + ch = (ch << 4) | hexval(s[i]); + i++; /* skip '}' */ + } + else /* parse '\uXXXX' */ + { + for (j = 0; j < 4 && i < l; j++) + ch = (ch << 4) | hexval(s[i++]); + } + + addUnicode(ch, &hi_surrogate); + } + + if (hi_surrogate != -1) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s", "jsonpath"), + errdetail("Unicode low surrogate must follow a high " + "surrogate."))); + } +} + +/* Parse sequence of hex-encoded characters */ +static void +parseHexChar(char *s) +{ + int ch = (hexval(s[2]) << 4) | + hexval(s[3]); + + addUnicodeChar(ch); +} + +/* + * Interface functions to make flex use palloc() instead of malloc(). + * It'd be better to make these static, but flex insists otherwise. + */ + +void * +jsonpath_yyalloc(yy_size_t bytes) +{ + return palloc(bytes); +} + +void * +jsonpath_yyrealloc(void *ptr, yy_size_t bytes) +{ + if (ptr) + return repalloc(ptr, bytes); + else + return palloc(bytes); +} + +void +jsonpath_yyfree(void *ptr) +{ + if (ptr) + pfree(ptr); +} diff --git a/src/backend/utils/adt/levenshtein.c b/src/backend/utils/adt/levenshtein.c index dc4346a0391..d8db6abb431 100644 --- a/src/backend/utils/adt/levenshtein.c +++ b/src/backend/utils/adt/levenshtein.c @@ -16,7 +16,7 @@ * PHP 4.0.6 distribution for inspiration. Configurable penalty costs * extension is introduced by Volkan YAZICI (7/95). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -31,21 +31,21 @@ #define LIKE_ABORT (-1) -static int SB_MatchText(char *t, int tlen, char *p, int plen, - pg_locale_t locale, bool locale_is_c); +static int SB_MatchText(const char *t, int tlen, const char *p, int plen, + pg_locale_t locale, bool locale_is_c); static text *SB_do_like_escape(text *, text *); -static int MB_MatchText(char *t, int tlen, char *p, int plen, - pg_locale_t locale, bool locale_is_c); +static int MB_MatchText(const char *t, int tlen, const char *p, int plen, + pg_locale_t locale, bool locale_is_c); static text *MB_do_like_escape(text *, text *); -static int UTF8_MatchText(char *t, int tlen, char *p, int plen, - pg_locale_t locale, bool locale_is_c); +static int UTF8_MatchText(const char *t, int tlen, const char *p, int plen, + pg_locale_t locale, bool locale_is_c); -static int SB_IMatchText(char *t, int tlen, char *p, int plen, - pg_locale_t locale, bool locale_is_c); +static int SB_IMatchText(const char *t, int tlen, const char *p, int plen, + pg_locale_t locale, bool locale_is_c); -static int GenericMatchText(char *s, int slen, char *p, int plen); +static int GenericMatchText(const char *s, int slen, const char *p, int plen, Oid collation); static int Generic_Text_IC_like(text *str, text *pat, Oid collation); /*-------------------- @@ -54,7 +54,7 @@ static int Generic_Text_IC_like(text *str, text *pat, Oid collation); *-------------------- */ static inline int -wchareq(char *p1, char *p2) +wchareq(const char *p1, const char *p2) { int p1_len; @@ -148,8 +148,18 @@ SB_lower_char(unsigned char c, pg_locale_t locale, bool locale_is_c) /* Generic for all cases not requiring inline case-folding */ static inline int -GenericMatchText(char *s, int slen, char *p, int plen) +GenericMatchText(const char *s, int slen, const char *p, int plen, Oid collation) { + if (collation && !lc_ctype_is_c(collation) && collation != DEFAULT_COLLATION_OID) + { + pg_locale_t locale = pg_newlocale_from_collation(collation); + + if (locale && !locale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for LIKE"))); + } + if (pg_database_encoding_max_length() == 1) return SB_MatchText(s, slen, p, plen, 0, true); else if (GetDatabaseEncoding() == PG_UTF8) @@ -184,6 +194,11 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation) errhint("Use the COLLATE clause to set the collation explicitly."))); } locale = pg_newlocale_from_collation(collation); + + if (locale && !locale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for ILIKE"))); } /* @@ -196,7 +211,6 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation) if (pg_database_encoding_max_length() > 1 || (locale && locale->provider == COLLPROVIDER_ICU)) { - /* lower's result is never packed, so OK to use old macros here */ pat = DatumGetTextPP(DirectFunctionCall1Coll(lower, collation, PointerGetDatum(pat))); p = VARDATA_ANY(pat); @@ -240,7 +254,7 @@ namelike(PG_FUNCTION_ARGS) p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); - result = (GenericMatchText(s, slen, p, plen) == LIKE_TRUE); + result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) == LIKE_TRUE); PG_RETURN_BOOL(result); } @@ -261,7 +275,7 @@ namenlike(PG_FUNCTION_ARGS) p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); - result = (GenericMatchText(s, slen, p, plen) != LIKE_TRUE); + result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) != LIKE_TRUE); PG_RETURN_BOOL(result); } @@ -282,7 +296,7 @@ textlike(PG_FUNCTION_ARGS) p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); - result = (GenericMatchText(s, slen, p, plen) == LIKE_TRUE); + result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) == LIKE_TRUE); PG_RETURN_BOOL(result); } @@ -303,7 +317,7 @@ textnlike(PG_FUNCTION_ARGS) p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); - result = (GenericMatchText(s, slen, p, plen) != LIKE_TRUE); + result = (GenericMatchText(s, slen, p, plen, PG_GET_COLLATION()) != LIKE_TRUE); PG_RETURN_BOOL(result); } diff --git a/src/backend/utils/adt/like_match.c b/src/backend/utils/adt/like_match.c index 18428569a86..5b322559aa4 100644 --- a/src/backend/utils/adt/like_match.c +++ b/src/backend/utils/adt/like_match.c @@ -16,7 +16,7 @@ * do_like_escape - name of function if wanted - needs CHAREQ and CopyAdvChar * MATCH_LOWER - define for case (4) to specify case folding for 1-byte chars * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/like_match.c @@ -27,7 +27,8 @@ /* * Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. * Rich $alz is now . - * Special thanks to Lars Mathiesen for the LABORT code. + * Special thanks to Lars Mathiesen for the + * LIKE_ABORT code. * * This code was shamelessly stolen from the "pql" code by myself and * slightly modified :) @@ -76,7 +77,7 @@ #endif static int -MatchText(char *t, int tlen, char *p, int plen, +MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale, bool locale_is_c) { /* Fast path for match-everything pattern */ diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c new file mode 100644 index 00000000000..c8fec7863f4 --- /dev/null +++ b/src/backend/utils/adt/like_support.c @@ -0,0 +1,1743 @@ +/*------------------------------------------------------------------------- + * + * like_support.c + * Planner support functions for LIKE, regex, and related operators. + * + * These routines handle special optimization of operators that can be + * used with index scans even though they are not known to the executor's + * indexscan machinery. The key idea is that these operators allow us + * to derive approximate indexscan qual clauses, such that any tuples + * that pass the operator clause itself must also satisfy the simpler + * indexscan condition(s). Then we can use the indexscan machinery + * to avoid scanning as much of the table as we'd otherwise have to, + * while applying the original operator as a qpqual condition to ensure + * we deliver only the tuples we want. (In essence, we're using a regular + * index as if it were a lossy index.) + * + * An example of what we're doing is + * textfield LIKE 'abc%def' + * from which we can generate the indexscanable conditions + * textfield >= 'abc' AND textfield < 'abd' + * which allow efficient scanning of an index on textfield. + * (In reality, character set and collation issues make the transformation + * from LIKE to indexscan limits rather harder than one might think ... + * but that's the basic idea.) + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/like_support.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include + +#include "access/htup_details.h" +#include "access/stratnum.h" +#include "catalog/pg_collation.h" +#include "catalog/pg_opfamily.h" +#include "catalog/pg_statistic.h" +#include "catalog/pg_type.h" +#include "mb/pg_wchar.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/lsyscache.h" +#include "utils/pg_locale.h" +#include "utils/selfuncs.h" +#include "utils/varlena.h" + + +typedef enum +{ + Pattern_Type_Like, + Pattern_Type_Like_IC, + Pattern_Type_Regex, + Pattern_Type_Regex_IC, + Pattern_Type_Prefix +} Pattern_Type; + +typedef enum +{ + Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Prefix_Exact +} Pattern_Prefix_Status; + +static Node *like_regex_support(Node *rawreq, Pattern_Type ptype); +static List *match_pattern_prefix(Node *leftop, + Node *rightop, + Pattern_Type ptype, + Oid expr_coll, + Oid opfamily, + Oid indexcollation); +static double patternsel_common(PlannerInfo *root, + Oid oprid, + Oid opfuncid, + List *args, + int varRelid, + Oid collation, + Pattern_Type ptype, + bool negate); +static Pattern_Prefix_Status pattern_fixed_prefix(Const *patt, + Pattern_Type ptype, + Oid collation, + Const **prefix, + Selectivity *rest_selec); +static Selectivity prefix_selectivity(PlannerInfo *root, + VariableStatData *vardata, + Oid vartype, Oid opfamily, Const *prefixcon); +static Selectivity like_selectivity(const char *patt, int pattlen, + bool case_insensitive); +static Selectivity regex_selectivity(const char *patt, int pattlen, + bool case_insensitive, + int fixed_prefix_len); +static int pattern_char_isalpha(char c, bool is_multibyte, + pg_locale_t locale, bool locale_is_c); +static Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc, + Oid collation); +static Datum string_to_datum(const char *str, Oid datatype); +static Const *string_to_const(const char *str, Oid datatype); +static Const *string_to_bytea_const(const char *str, size_t str_len); + + +/* + * Planner support functions for LIKE, regex, and related operators + */ +Datum +textlike_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + + PG_RETURN_POINTER(like_regex_support(rawreq, Pattern_Type_Like)); +} + +Datum +texticlike_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + + PG_RETURN_POINTER(like_regex_support(rawreq, Pattern_Type_Like_IC)); +} + +Datum +textregexeq_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + + PG_RETURN_POINTER(like_regex_support(rawreq, Pattern_Type_Regex)); +} + +Datum +texticregexeq_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + + PG_RETURN_POINTER(like_regex_support(rawreq, Pattern_Type_Regex_IC)); +} + +/* Common code for the above */ +static Node * +like_regex_support(Node *rawreq, Pattern_Type ptype) +{ + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestSelectivity)) + { + /* + * Make a selectivity estimate for a function call, just as we'd do if + * the call was via the corresponding operator. + */ + SupportRequestSelectivity *req = (SupportRequestSelectivity *) rawreq; + Selectivity s1; + + if (req->is_join) + { + /* + * For the moment we just punt. If patternjoinsel is ever + * improved to do better, this should be made to call it. + */ + s1 = DEFAULT_MATCH_SEL; + } + else + { + /* Share code with operator restriction selectivity functions */ + s1 = patternsel_common(req->root, + InvalidOid, + req->funcid, + req->args, + req->varRelid, + req->inputcollid, + ptype, + false); + } + req->selectivity = s1; + ret = (Node *) req; + } + else if (IsA(rawreq, SupportRequestIndexCondition)) + { + /* Try to convert operator/function call to index conditions */ + SupportRequestIndexCondition *req = (SupportRequestIndexCondition *) rawreq; + + /* + * Currently we have no "reverse" match operators with the pattern on + * the left, so we only need consider cases with the indexkey on the + * left. + */ + if (req->indexarg != 0) + return NULL; + + if (is_opclause(req->node)) + { + OpExpr *clause = (OpExpr *) req->node; + + Assert(list_length(clause->args) == 2); + ret = (Node *) + match_pattern_prefix((Node *) linitial(clause->args), + (Node *) lsecond(clause->args), + ptype, + clause->inputcollid, + req->opfamily, + req->indexcollation); + } + else if (is_funcclause(req->node)) /* be paranoid */ + { + FuncExpr *clause = (FuncExpr *) req->node; + + Assert(list_length(clause->args) == 2); + ret = (Node *) + match_pattern_prefix((Node *) linitial(clause->args), + (Node *) lsecond(clause->args), + ptype, + clause->inputcollid, + req->opfamily, + req->indexcollation); + } + } + + return ret; +} + +/* + * match_pattern_prefix + * Try to generate an indexqual for a LIKE or regex operator. + */ +static List * +match_pattern_prefix(Node *leftop, + Node *rightop, + Pattern_Type ptype, + Oid expr_coll, + Oid opfamily, + Oid indexcollation) +{ + List *result; + Const *patt; + Const *prefix; + Pattern_Prefix_Status pstatus; + Oid ldatatype; + Oid rdatatype; + Oid oproid; + Expr *expr; + FmgrInfo ltproc; + Const *greaterstr; + + /* + * Can't do anything with a non-constant or NULL pattern argument. + * + * Note that since we restrict ourselves to cases with a hard constant on + * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry + * about verifying that. + */ + if (!IsA(rightop, Const) || + ((Const *) rightop)->constisnull) + return NIL; + patt = (Const *) rightop; + + /* + * Not supported if the expression collation is nondeterministic. The + * optimized equality or prefix tests use bytewise comparisons, which is + * not consistent with nondeterministic collations. The actual + * pattern-matching implementation functions will later error out that + * pattern-matching is not supported with nondeterministic collations. (We + * could also error out here, but by doing it later we get more precise + * error messages.) (It should be possible to support at least + * Pattern_Prefix_Exact, but no point as along as the actual + * pattern-matching implementations don't support it.) + * + * expr_coll is not set for a non-collation-aware data type such as bytea. + */ + if (expr_coll && !get_collation_isdeterministic(expr_coll)) + return NIL; + + /* + * Try to extract a fixed prefix from the pattern. + */ + pstatus = pattern_fixed_prefix(patt, ptype, expr_coll, + &prefix, NULL); + + /* fail if no fixed prefix */ + if (pstatus == Pattern_Prefix_None) + return NIL; + + /* + * Must also check that index's opfamily supports the operators we will + * want to apply. (A hash index, for example, will not support ">=".) + * Currently, only btree and spgist support the operators we need. + * + * Note: actually, in the Pattern_Prefix_Exact case, we only need "=" so a + * hash index would work. Currently it doesn't seem worth checking for + * that, however. + * + * We insist on the opfamily being one of the specific ones we expect, + * else we'd do the wrong thing if someone were to make a reverse-sort + * opfamily with the same operators. + * + * The non-pattern opclasses will not sort the way we need in most non-C + * locales. We can use such an index anyway for an exact match (simple + * equality), but not for prefix-match cases. Note that here we are + * looking at the index's collation, not the expression's collation -- + * this test is *not* dependent on the LIKE/regex operator's collation. + * + * While we're at it, identify the type the comparison constant(s) should + * have, based on the opfamily. + */ + switch (opfamily) + { + case TEXT_BTREE_FAM_OID: + if (!(pstatus == Pattern_Prefix_Exact || + lc_collate_is_c(indexcollation))) + return NIL; + rdatatype = TEXTOID; + break; + + case TEXT_PATTERN_BTREE_FAM_OID: + case TEXT_SPGIST_FAM_OID: + rdatatype = TEXTOID; + break; + + case BPCHAR_BTREE_FAM_OID: + if (!(pstatus == Pattern_Prefix_Exact || + lc_collate_is_c(indexcollation))) + return NIL; + rdatatype = BPCHAROID; + break; + + case BPCHAR_PATTERN_BTREE_FAM_OID: + rdatatype = BPCHAROID; + break; + + case BYTEA_BTREE_FAM_OID: + rdatatype = BYTEAOID; + break; + + default: + return NIL; + } + + /* OK, prepare to create the indexqual(s) */ + ldatatype = exprType(leftop); + + /* + * If necessary, coerce the prefix constant to the right type. The given + * prefix constant is either text or bytea type, therefore the only case + * where we need to do anything is when converting text to bpchar. Those + * two types are binary-compatible, so relabeling the Const node is + * sufficient. + */ + if (prefix->consttype != rdatatype) + { + Assert(prefix->consttype == TEXTOID && + rdatatype == BPCHAROID); + prefix->consttype = rdatatype; + } + + /* + * If we found an exact-match pattern, generate an "=" indexqual. + */ + if (pstatus == Pattern_Prefix_Exact) + { + oproid = get_opfamily_member(opfamily, ldatatype, rdatatype, + BTEqualStrategyNumber); + if (oproid == InvalidOid) + elog(ERROR, "no = operator for opfamily %u", opfamily); + expr = make_opclause(oproid, BOOLOID, false, + (Expr *) leftop, (Expr *) prefix, + InvalidOid, indexcollation); + result = list_make1(expr); + return result; + } + + /* + * Otherwise, we have a nonempty required prefix of the values. + * + * We can always say "x >= prefix". + */ + oproid = get_opfamily_member(opfamily, ldatatype, rdatatype, + BTGreaterEqualStrategyNumber); + if (oproid == InvalidOid) + elog(ERROR, "no >= operator for opfamily %u", opfamily); + expr = make_opclause(oproid, BOOLOID, false, + (Expr *) leftop, (Expr *) prefix, + InvalidOid, indexcollation); + result = list_make1(expr); + + /*------- + * If we can create a string larger than the prefix, we can say + * "x < greaterstr". NB: we rely on make_greater_string() to generate + * a guaranteed-greater string, not just a probably-greater string. + * In general this is only guaranteed in C locale, so we'd better be + * using a C-locale index collation. + *------- + */ + oproid = get_opfamily_member(opfamily, ldatatype, rdatatype, + BTLessStrategyNumber); + if (oproid == InvalidOid) + elog(ERROR, "no < operator for opfamily %u", opfamily); + fmgr_info(get_opcode(oproid), <proc); + greaterstr = make_greater_string(prefix, <proc, indexcollation); + if (greaterstr) + { + expr = make_opclause(oproid, BOOLOID, false, + (Expr *) leftop, (Expr *) greaterstr, + InvalidOid, indexcollation); + result = lappend(result, expr); + } + + return result; +} + + +/* + * patternsel_common - generic code for pattern-match restriction selectivity. + * + * To support using this from either the operator or function paths, caller + * may pass either operator OID or underlying function OID; we look up the + * latter from the former if needed. (We could just have patternsel() call + * get_opcode(), but the work would be wasted if we don't have a need to + * compare a fixed prefix to the pg_statistic data.) + * + * Note that oprid and/or opfuncid should be for the positive-match operator + * even when negate is true. + */ +static double +patternsel_common(PlannerInfo *root, + Oid oprid, + Oid opfuncid, + List *args, + int varRelid, + Oid collation, + Pattern_Type ptype, + bool negate) +{ + VariableStatData vardata; + Node *other; + bool varonleft; + Datum constval; + Oid consttype; + Oid vartype; + Oid opfamily; + Pattern_Prefix_Status pstatus; + Const *patt; + Const *prefix = NULL; + Selectivity rest_selec = 0; + double nullfrac = 0.0; + double result; + + /* + * Initialize result to the appropriate default estimate depending on + * whether it's a match or not-match operator. + */ + if (negate) + result = 1.0 - DEFAULT_MATCH_SEL; + else + result = DEFAULT_MATCH_SEL; + + /* + * If expression is not variable op constant, then punt and return the + * default estimate. + */ + if (!get_restriction_variable(root, args, varRelid, + &vardata, &other, &varonleft)) + return result; + if (!varonleft || !IsA(other, Const)) + { + ReleaseVariableStats(vardata); + return result; + } + + /* + * If the constant is NULL, assume operator is strict and return zero, ie, + * operator will never return TRUE. (It's zero even for a negator op.) + */ + if (((Const *) other)->constisnull) + { + ReleaseVariableStats(vardata); + return 0.0; + } + constval = ((Const *) other)->constvalue; + consttype = ((Const *) other)->consttype; + + /* + * The right-hand const is type text or bytea for all supported operators. + * We do not expect to see binary-compatible types here, since + * const-folding should have relabeled the const to exactly match the + * operator's declared type. + */ + if (consttype != TEXTOID && consttype != BYTEAOID) + { + ReleaseVariableStats(vardata); + return result; + } + + /* + * Similarly, the exposed type of the left-hand side should be one of + * those we know. (Do not look at vardata.atttype, which might be + * something binary-compatible but different.) We can use it to choose + * the index opfamily from which we must draw the comparison operators. + * + * NOTE: It would be more correct to use the PATTERN opfamilies than the + * simple ones, but at the moment ANALYZE will not generate statistics for + * the PATTERN operators. But our results are so approximate anyway that + * it probably hardly matters. + */ + vartype = vardata.vartype; + + switch (vartype) + { + case TEXTOID: + case NAMEOID: + opfamily = TEXT_BTREE_FAM_OID; + break; + case BPCHAROID: + opfamily = BPCHAR_BTREE_FAM_OID; + break; + case BYTEAOID: + opfamily = BYTEA_BTREE_FAM_OID; + break; + default: + ReleaseVariableStats(vardata); + return result; + } + + /* + * Grab the nullfrac for use below. + */ + if (HeapTupleIsValid(vardata.statsTuple)) + { + Form_pg_statistic stats; + + stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple); + nullfrac = stats->stanullfrac; + } + + /* + * Pull out any fixed prefix implied by the pattern, and estimate the + * fractional selectivity of the remainder of the pattern. Unlike many + * other selectivity estimators, we use the pattern operator's actual + * collation for this step. This is not because we expect the collation + * to make a big difference in the selectivity estimate (it seldom would), + * but because we want to be sure we cache compiled regexps under the + * right cache key, so that they can be re-used at runtime. + */ + patt = (Const *) other; + pstatus = pattern_fixed_prefix(patt, ptype, collation, + &prefix, &rest_selec); + + /* + * If necessary, coerce the prefix constant to the right type. + */ + if (prefix && prefix->consttype != vartype) + { + char *prefixstr; + + switch (prefix->consttype) + { + case TEXTOID: + prefixstr = TextDatumGetCString(prefix->constvalue); + break; + case BYTEAOID: + prefixstr = DatumGetCString(DirectFunctionCall1(byteaout, + prefix->constvalue)); + break; + default: + elog(ERROR, "unrecognized consttype: %u", + prefix->consttype); + ReleaseVariableStats(vardata); + return result; + } + prefix = string_to_const(prefixstr, vartype); + pfree(prefixstr); + } + + if (pstatus == Pattern_Prefix_Exact) + { + /* + * Pattern specifies an exact match, so pretend operator is '=' + */ + Oid eqopr = get_opfamily_member(opfamily, vartype, vartype, + BTEqualStrategyNumber); + + if (eqopr == InvalidOid) + elog(ERROR, "no = operator for opfamily %u", opfamily); + result = var_eq_const(&vardata, eqopr, prefix->constvalue, + false, true, false); + } + else + { + /* + * Not exact-match pattern. If we have a sufficiently large + * histogram, estimate selectivity for the histogram part of the + * population by counting matches in the histogram. If not, estimate + * selectivity of the fixed prefix and remainder of pattern + * separately, then combine the two to get an estimate of the + * selectivity for the part of the column population represented by + * the histogram. (For small histograms, we combine these + * approaches.) + * + * We then add up data for any most-common-values values; these are + * not in the histogram population, and we can get exact answers for + * them by applying the pattern operator, so there's no reason to + * approximate. (If the MCVs cover a significant part of the total + * population, this gives us a big leg up in accuracy.) + */ + Selectivity selec; + int hist_size; + FmgrInfo opproc; + double mcv_selec, + sumcommon; + + /* Try to use the histogram entries to get selectivity */ + if (!OidIsValid(opfuncid)) + opfuncid = get_opcode(oprid); + fmgr_info(opfuncid, &opproc); + + selec = histogram_selectivity(&vardata, &opproc, constval, true, + 10, 1, &hist_size); + + /* If not at least 100 entries, use the heuristic method */ + if (hist_size < 100) + { + Selectivity heursel; + Selectivity prefixsel; + + if (pstatus == Pattern_Prefix_Partial) + prefixsel = prefix_selectivity(root, &vardata, vartype, + opfamily, prefix); + else + prefixsel = 1.0; + heursel = prefixsel * rest_selec; + + if (selec < 0) /* fewer than 10 histogram entries? */ + selec = heursel; + else + { + /* + * For histogram sizes from 10 to 100, we combine the + * histogram and heuristic selectivities, putting increasingly + * more trust in the histogram for larger sizes. + */ + double hist_weight = hist_size / 100.0; + + selec = selec * hist_weight + heursel * (1.0 - hist_weight); + } + } + + /* In any case, don't believe extremely small or large estimates. */ + if (selec < 0.0001) + selec = 0.0001; + else if (selec > 0.9999) + selec = 0.9999; + + /* + * If we have most-common-values info, add up the fractions of the MCV + * entries that satisfy MCV OP PATTERN. These fractions contribute + * directly to the result selectivity. Also add up the total fraction + * represented by MCV entries. + */ + mcv_selec = mcv_selectivity(&vardata, &opproc, constval, true, + &sumcommon); + + /* + * Now merge the results from the MCV and histogram calculations, + * realizing that the histogram covers only the non-null values that + * are not listed in MCV. + */ + selec *= 1.0 - nullfrac - sumcommon; + selec += mcv_selec; + result = selec; + } + + /* now adjust if we wanted not-match rather than match */ + if (negate) + result = 1.0 - result - nullfrac; + + /* result should be in range, but make sure... */ + CLAMP_PROBABILITY(result); + + if (prefix) + { + pfree(DatumGetPointer(prefix->constvalue)); + pfree(prefix); + } + + ReleaseVariableStats(vardata); + + return result; +} + +/* + * Fix impedance mismatch between SQL-callable functions and patternsel_common + */ +static double +patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) +{ + PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); + Oid operator = PG_GETARG_OID(1); + List *args = (List *) PG_GETARG_POINTER(2); + int varRelid = PG_GETARG_INT32(3); + Oid collation = PG_GET_COLLATION(); + + /* + * If this is for a NOT LIKE or similar operator, get the corresponding + * positive-match operator and work with that. + */ + if (negate) + { + operator = get_negator(operator); + if (!OidIsValid(operator)) + elog(ERROR, "patternsel called for operator without a negator"); + } + + return patternsel_common(root, + operator, + InvalidOid, + args, + varRelid, + collation, + ptype, + negate); +} + +/* + * regexeqsel - Selectivity of regular-expression pattern match. + */ +Datum +regexeqsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, false)); +} + +/* + * icregexeqsel - Selectivity of case-insensitive regex match. + */ +Datum +icregexeqsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, false)); +} + +/* + * likesel - Selectivity of LIKE pattern match. + */ +Datum +likesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, false)); +} + +/* + * prefixsel - selectivity of prefix operator + */ +Datum +prefixsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Prefix, false)); +} + +/* + * + * iclikesel - Selectivity of ILIKE pattern match. + */ +Datum +iclikesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, false)); +} + +/* + * regexnesel - Selectivity of regular-expression pattern non-match. + */ +Datum +regexnesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, true)); +} + +/* + * icregexnesel - Selectivity of case-insensitive regex non-match. + */ +Datum +icregexnesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, true)); +} + +/* + * nlikesel - Selectivity of LIKE pattern non-match. + */ +Datum +nlikesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, true)); +} + +/* + * icnlikesel - Selectivity of ILIKE pattern non-match. + */ +Datum +icnlikesel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, true)); +} + +/* + * patternjoinsel - Generic code for pattern-match join selectivity. + */ +static double +patternjoinsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) +{ + /* For the moment we just punt. */ + return negate ? (1.0 - DEFAULT_MATCH_SEL) : DEFAULT_MATCH_SEL; +} + +/* + * regexeqjoinsel - Join selectivity of regular-expression pattern match. + */ +Datum +regexeqjoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, false)); +} + +/* + * icregexeqjoinsel - Join selectivity of case-insensitive regex match. + */ +Datum +icregexeqjoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, false)); +} + +/* + * likejoinsel - Join selectivity of LIKE pattern match. + */ +Datum +likejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, false)); +} + +/* + * prefixjoinsel - Join selectivity of prefix operator + */ +Datum +prefixjoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Prefix, false)); +} + +/* + * iclikejoinsel - Join selectivity of ILIKE pattern match. + */ +Datum +iclikejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, false)); +} + +/* + * regexnejoinsel - Join selectivity of regex non-match. + */ +Datum +regexnejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, true)); +} + +/* + * icregexnejoinsel - Join selectivity of case-insensitive regex non-match. + */ +Datum +icregexnejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, true)); +} + +/* + * nlikejoinsel - Join selectivity of LIKE pattern non-match. + */ +Datum +nlikejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, true)); +} + +/* + * icnlikejoinsel - Join selectivity of ILIKE pattern non-match. + */ +Datum +icnlikejoinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, true)); +} + + +/*------------------------------------------------------------------------- + * + * Pattern analysis functions + * + * These routines support analysis of LIKE and regular-expression patterns + * by the planner/optimizer. It's important that they agree with the + * regular-expression code in backend/regex/ and the LIKE code in + * backend/utils/adt/like.c. Also, the computation of the fixed prefix + * must be conservative: if we report a string longer than the true fixed + * prefix, the query may produce actually wrong answers, rather than just + * getting a bad selectivity estimate! + * + *------------------------------------------------------------------------- + */ + +/* + * Extract the fixed prefix, if any, for a pattern. + * + * *prefix is set to a palloc'd prefix string (in the form of a Const node), + * or to NULL if no fixed prefix exists for the pattern. + * If rest_selec is not NULL, *rest_selec is set to an estimate of the + * selectivity of the remainder of the pattern (without any fixed prefix). + * The prefix Const has the same type (TEXT or BYTEA) as the input pattern. + * + * The return value distinguishes no fixed prefix, a partial prefix, + * or an exact-match-only pattern. + */ + +static Pattern_Prefix_Status +like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation, + Const **prefix_const, Selectivity *rest_selec) +{ + char *match; + char *patt; + int pattlen; + Oid typeid = patt_const->consttype; + int pos, + match_pos; + bool is_multibyte = (pg_database_encoding_max_length() > 1); + pg_locale_t locale = 0; + bool locale_is_c = false; + + /* the right-hand const is type text or bytea */ + Assert(typeid == BYTEAOID || typeid == TEXTOID); + + if (case_insensitive) + { + if (typeid == BYTEAOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("case insensitive matching not supported on type bytea"))); + + /* If case-insensitive, we need locale info */ + if (lc_ctype_is_c(collation)) + locale_is_c = true; + else if (collation != DEFAULT_COLLATION_OID) + { + if (!OidIsValid(collation)) + { + /* + * This typically means that the parser could not resolve a + * conflict of implicit collations, so report it that way. + */ + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for ILIKE"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + } + locale = pg_newlocale_from_collation(collation); + } + } + + if (typeid != BYTEAOID) + { + patt = TextDatumGetCString(patt_const->constvalue); + pattlen = strlen(patt); + } + else + { + bytea *bstr = DatumGetByteaPP(patt_const->constvalue); + + pattlen = VARSIZE_ANY_EXHDR(bstr); + patt = (char *) palloc(pattlen); + memcpy(patt, VARDATA_ANY(bstr), pattlen); + Assert((Pointer) bstr == DatumGetPointer(patt_const->constvalue)); + } + + match = palloc(pattlen + 1); + match_pos = 0; + for (pos = 0; pos < pattlen; pos++) + { + /* % and _ are wildcard characters in LIKE */ + if (patt[pos] == '%' || + patt[pos] == '_') + break; + + /* Backslash escapes the next character */ + if (patt[pos] == '\\') + { + pos++; + if (pos >= pattlen) + break; + } + + /* Stop if case-varying character (it's sort of a wildcard) */ + if (case_insensitive && + pattern_char_isalpha(patt[pos], is_multibyte, locale, locale_is_c)) + break; + + match[match_pos++] = patt[pos]; + } + + match[match_pos] = '\0'; + + if (typeid != BYTEAOID) + *prefix_const = string_to_const(match, typeid); + else + *prefix_const = string_to_bytea_const(match, match_pos); + + if (rest_selec != NULL) + *rest_selec = like_selectivity(&patt[pos], pattlen - pos, + case_insensitive); + + pfree(patt); + pfree(match); + + /* in LIKE, an empty pattern is an exact match! */ + if (pos == pattlen) + return Pattern_Prefix_Exact; /* reached end of pattern, so exact */ + + if (match_pos > 0) + return Pattern_Prefix_Partial; + + return Pattern_Prefix_None; +} + +static Pattern_Prefix_Status +regex_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation, + Const **prefix_const, Selectivity *rest_selec) +{ + Oid typeid = patt_const->consttype; + char *prefix; + bool exact; + + /* + * Should be unnecessary, there are no bytea regex operators defined. As + * such, it should be noted that the rest of this function has *not* been + * made safe for binary (possibly NULL containing) strings. + */ + if (typeid == BYTEAOID) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("regular-expression matching not supported on type bytea"))); + + /* Use the regexp machinery to extract the prefix, if any */ + prefix = regexp_fixed_prefix(DatumGetTextPP(patt_const->constvalue), + case_insensitive, collation, + &exact); + + if (prefix == NULL) + { + *prefix_const = NULL; + + if (rest_selec != NULL) + { + char *patt = TextDatumGetCString(patt_const->constvalue); + + *rest_selec = regex_selectivity(patt, strlen(patt), + case_insensitive, + 0); + pfree(patt); + } + + return Pattern_Prefix_None; + } + + *prefix_const = string_to_const(prefix, typeid); + + if (rest_selec != NULL) + { + if (exact) + { + /* Exact match, so there's no additional selectivity */ + *rest_selec = 1.0; + } + else + { + char *patt = TextDatumGetCString(patt_const->constvalue); + + *rest_selec = regex_selectivity(patt, strlen(patt), + case_insensitive, + strlen(prefix)); + pfree(patt); + } + } + + pfree(prefix); + + if (exact) + return Pattern_Prefix_Exact; /* pattern specifies exact match */ + else + return Pattern_Prefix_Partial; +} + +static Pattern_Prefix_Status +pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation, + Const **prefix, Selectivity *rest_selec) +{ + Pattern_Prefix_Status result; + + switch (ptype) + { + case Pattern_Type_Like: + result = like_fixed_prefix(patt, false, collation, + prefix, rest_selec); + break; + case Pattern_Type_Like_IC: + result = like_fixed_prefix(patt, true, collation, + prefix, rest_selec); + break; + case Pattern_Type_Regex: + result = regex_fixed_prefix(patt, false, collation, + prefix, rest_selec); + break; + case Pattern_Type_Regex_IC: + result = regex_fixed_prefix(patt, true, collation, + prefix, rest_selec); + break; + case Pattern_Type_Prefix: + /* Prefix type work is trivial. */ + result = Pattern_Prefix_Partial; + *rest_selec = 1.0; /* all */ + *prefix = makeConst(patt->consttype, + patt->consttypmod, + patt->constcollid, + patt->constlen, + datumCopy(patt->constvalue, + patt->constbyval, + patt->constlen), + patt->constisnull, + patt->constbyval); + break; + default: + elog(ERROR, "unrecognized ptype: %d", (int) ptype); + result = Pattern_Prefix_None; /* keep compiler quiet */ + break; + } + return result; +} + +/* + * Estimate the selectivity of a fixed prefix for a pattern match. + * + * A fixed prefix "foo" is estimated as the selectivity of the expression + * "variable >= 'foo' AND variable < 'fop'" (see also indxpath.c). + * + * The selectivity estimate is with respect to the portion of the column + * population represented by the histogram --- the caller must fold this + * together with info about MCVs and NULLs. + * + * We use the >= and < operators from the specified btree opfamily to do the + * estimation. The given variable and Const must be of the associated + * datatype. + * + * XXX Note: we make use of the upper bound to estimate operator selectivity + * even if the locale is such that we cannot rely on the upper-bound string. + * The selectivity only needs to be approximately right anyway, so it seems + * more useful to use the upper-bound code than not. + */ +static Selectivity +prefix_selectivity(PlannerInfo *root, VariableStatData *vardata, + Oid vartype, Oid opfamily, Const *prefixcon) +{ + Selectivity prefixsel; + Oid cmpopr; + FmgrInfo opproc; + AttStatsSlot sslot; + Const *greaterstrcon; + Selectivity eq_sel; + + cmpopr = get_opfamily_member(opfamily, vartype, vartype, + BTGreaterEqualStrategyNumber); + if (cmpopr == InvalidOid) + elog(ERROR, "no >= operator for opfamily %u", opfamily); + fmgr_info(get_opcode(cmpopr), &opproc); + + prefixsel = ineq_histogram_selectivity(root, vardata, + &opproc, true, true, + prefixcon->constvalue, + prefixcon->consttype); + + if (prefixsel < 0.0) + { + /* No histogram is present ... return a suitable default estimate */ + return DEFAULT_MATCH_SEL; + } + + /*------- + * If we can create a string larger than the prefix, say + * "x < greaterstr". We try to generate the string referencing the + * collation of the var's statistics, but if that's not available, + * use DEFAULT_COLLATION_OID. + *------- + */ + if (HeapTupleIsValid(vardata->statsTuple) && + get_attstatsslot(&sslot, vardata->statsTuple, + STATISTIC_KIND_HISTOGRAM, InvalidOid, 0)) + /* sslot.stacoll is set up */ ; + else + sslot.stacoll = DEFAULT_COLLATION_OID; + cmpopr = get_opfamily_member(opfamily, vartype, vartype, + BTLessStrategyNumber); + if (cmpopr == InvalidOid) + elog(ERROR, "no < operator for opfamily %u", opfamily); + fmgr_info(get_opcode(cmpopr), &opproc); + greaterstrcon = make_greater_string(prefixcon, &opproc, sslot.stacoll); + if (greaterstrcon) + { + Selectivity topsel; + + topsel = ineq_histogram_selectivity(root, vardata, + &opproc, false, false, + greaterstrcon->constvalue, + greaterstrcon->consttype); + + /* ineq_histogram_selectivity worked before, it shouldn't fail now */ + Assert(topsel >= 0.0); + + /* + * Merge the two selectivities in the same way as for a range query + * (see clauselist_selectivity()). Note that we don't need to worry + * about double-exclusion of nulls, since ineq_histogram_selectivity + * doesn't count those anyway. + */ + prefixsel = topsel + prefixsel - 1.0; + } + + /* + * If the prefix is long then the two bounding values might be too close + * together for the histogram to distinguish them usefully, resulting in a + * zero estimate (plus or minus roundoff error). To avoid returning a + * ridiculously small estimate, compute the estimated selectivity for + * "variable = 'foo'", and clamp to that. (Obviously, the resultant + * estimate should be at least that.) + * + * We apply this even if we couldn't make a greater string. That case + * suggests that the prefix is near the maximum possible, and thus + * probably off the end of the histogram, and thus we probably got a very + * small estimate from the >= condition; so we still need to clamp. + */ + cmpopr = get_opfamily_member(opfamily, vartype, vartype, + BTEqualStrategyNumber); + if (cmpopr == InvalidOid) + elog(ERROR, "no = operator for opfamily %u", opfamily); + eq_sel = var_eq_const(vardata, cmpopr, prefixcon->constvalue, + false, true, false); + + prefixsel = Max(prefixsel, eq_sel); + + return prefixsel; +} + + +/* + * Estimate the selectivity of a pattern of the specified type. + * Note that any fixed prefix of the pattern will have been removed already, + * so actually we may be looking at just a fragment of the pattern. + * + * For now, we use a very simplistic approach: fixed characters reduce the + * selectivity a good deal, character ranges reduce it a little, + * wildcards (such as % for LIKE or .* for regex) increase it. + */ + +#define FIXED_CHAR_SEL 0.20 /* about 1/5 */ +#define CHAR_RANGE_SEL 0.25 +#define ANY_CHAR_SEL 0.9 /* not 1, since it won't match end-of-string */ +#define FULL_WILDCARD_SEL 5.0 +#define PARTIAL_WILDCARD_SEL 2.0 + +static Selectivity +like_selectivity(const char *patt, int pattlen, bool case_insensitive) +{ + Selectivity sel = 1.0; + int pos; + + /* Skip any leading wildcard; it's already factored into initial sel */ + for (pos = 0; pos < pattlen; pos++) + { + if (patt[pos] != '%' && patt[pos] != '_') + break; + } + + for (; pos < pattlen; pos++) + { + /* % and _ are wildcard characters in LIKE */ + if (patt[pos] == '%') + sel *= FULL_WILDCARD_SEL; + else if (patt[pos] == '_') + sel *= ANY_CHAR_SEL; + else if (patt[pos] == '\\') + { + /* Backslash quotes the next character */ + pos++; + if (pos >= pattlen) + break; + sel *= FIXED_CHAR_SEL; + } + else + sel *= FIXED_CHAR_SEL; + } + /* Could get sel > 1 if multiple wildcards */ + if (sel > 1.0) + sel = 1.0; + return sel; +} + +static Selectivity +regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive) +{ + Selectivity sel = 1.0; + int paren_depth = 0; + int paren_pos = 0; /* dummy init to keep compiler quiet */ + int pos; + + for (pos = 0; pos < pattlen; pos++) + { + if (patt[pos] == '(') + { + if (paren_depth == 0) + paren_pos = pos; /* remember start of parenthesized item */ + paren_depth++; + } + else if (patt[pos] == ')' && paren_depth > 0) + { + paren_depth--; + if (paren_depth == 0) + sel *= regex_selectivity_sub(patt + (paren_pos + 1), + pos - (paren_pos + 1), + case_insensitive); + } + else if (patt[pos] == '|' && paren_depth == 0) + { + /* + * If unquoted | is present at paren level 0 in pattern, we have + * multiple alternatives; sum their probabilities. + */ + sel += regex_selectivity_sub(patt + (pos + 1), + pattlen - (pos + 1), + case_insensitive); + break; /* rest of pattern is now processed */ + } + else if (patt[pos] == '[') + { + bool negclass = false; + + if (patt[++pos] == '^') + { + negclass = true; + pos++; + } + if (patt[pos] == ']') /* ']' at start of class is not special */ + pos++; + while (pos < pattlen && patt[pos] != ']') + pos++; + if (paren_depth == 0) + sel *= (negclass ? (1.0 - CHAR_RANGE_SEL) : CHAR_RANGE_SEL); + } + else if (patt[pos] == '.') + { + if (paren_depth == 0) + sel *= ANY_CHAR_SEL; + } + else if (patt[pos] == '*' || + patt[pos] == '?' || + patt[pos] == '+') + { + /* Ought to be smarter about quantifiers... */ + if (paren_depth == 0) + sel *= PARTIAL_WILDCARD_SEL; + } + else if (patt[pos] == '{') + { + while (pos < pattlen && patt[pos] != '}') + pos++; + if (paren_depth == 0) + sel *= PARTIAL_WILDCARD_SEL; + } + else if (patt[pos] == '\\') + { + /* backslash quotes the next character */ + pos++; + if (pos >= pattlen) + break; + if (paren_depth == 0) + sel *= FIXED_CHAR_SEL; + } + else + { + if (paren_depth == 0) + sel *= FIXED_CHAR_SEL; + } + } + /* Could get sel > 1 if multiple wildcards */ + if (sel > 1.0) + sel = 1.0; + return sel; +} + +static Selectivity +regex_selectivity(const char *patt, int pattlen, bool case_insensitive, + int fixed_prefix_len) +{ + Selectivity sel; + + /* If patt doesn't end with $, consider it to have a trailing wildcard */ + if (pattlen > 0 && patt[pattlen - 1] == '$' && + (pattlen == 1 || patt[pattlen - 2] != '\\')) + { + /* has trailing $ */ + sel = regex_selectivity_sub(patt, pattlen - 1, case_insensitive); + } + else + { + /* no trailing $ */ + sel = regex_selectivity_sub(patt, pattlen, case_insensitive); + sel *= FULL_WILDCARD_SEL; + } + + /* If there's a fixed prefix, discount its selectivity */ + if (fixed_prefix_len > 0) + sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len); + + /* Make sure result stays in range */ + CLAMP_PROBABILITY(sel); + return sel; +} + +/* + * Check whether char is a letter (and, hence, subject to case-folding) + * + * In multibyte character sets or with ICU, we can't use isalpha, and it does + * not seem worth trying to convert to wchar_t to use iswalpha or u_isalpha. + * Instead, just assume any non-ASCII char is potentially case-varying, and + * hard-wire knowledge of which ASCII chars are letters. + */ +static int +pattern_char_isalpha(char c, bool is_multibyte, + pg_locale_t locale, bool locale_is_c) +{ + if (locale_is_c) + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); + else if (is_multibyte && IS_HIGHBIT_SET(c)) + return true; + else if (locale && locale->provider == COLLPROVIDER_ICU) + return IS_HIGHBIT_SET(c) || + (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); +#ifdef HAVE_LOCALE_T + else if (locale && locale->provider == COLLPROVIDER_LIBC) + return isalpha_l((unsigned char) c, locale->info.lt); +#endif + else + return isalpha((unsigned char) c); +} + + +/* + * For bytea, the increment function need only increment the current byte + * (there are no multibyte characters to worry about). + */ +static bool +byte_increment(unsigned char *ptr, int len) +{ + if (*ptr >= 255) + return false; + (*ptr)++; + return true; +} + +/* + * Try to generate a string greater than the given string or any + * string it is a prefix of. If successful, return a palloc'd string + * in the form of a Const node; else return NULL. + * + * The caller must provide the appropriate "less than" comparison function + * for testing the strings, along with the collation to use. + * + * The key requirement here is that given a prefix string, say "foo", + * we must be able to generate another string "fop" that is greater than + * all strings "foobar" starting with "foo". We can test that we have + * generated a string greater than the prefix string, but in non-C collations + * that is not a bulletproof guarantee that an extension of the string might + * not sort after it; an example is that "foo " is less than "foo!", but it + * is not clear that a "dictionary" sort ordering will consider "foo!" less + * than "foo bar". CAUTION: Therefore, this function should be used only for + * estimation purposes when working in a non-C collation. + * + * To try to catch most cases where an extended string might otherwise sort + * before the result value, we determine which of the strings "Z", "z", "y", + * and "9" is seen as largest by the collation, and append that to the given + * prefix before trying to find a string that compares as larger. + * + * To search for a greater string, we repeatedly "increment" the rightmost + * character, using an encoding-specific character incrementer function. + * When it's no longer possible to increment the last character, we truncate + * off that character and start incrementing the next-to-rightmost. + * For example, if "z" were the last character in the sort order, then we + * could produce "foo" as a string greater than "fonz". + * + * This could be rather slow in the worst case, but in most cases we + * won't have to try more than one or two strings before succeeding. + * + * Note that it's important for the character incrementer not to be too anal + * about producing every possible character code, since in some cases the only + * way to get a larger string is to increment a previous character position. + * So we don't want to spend too much time trying every possible character + * code at the last position. A good rule of thumb is to be sure that we + * don't try more than 256*K values for a K-byte character (and definitely + * not 256^K, which is what an exhaustive search would approach). + */ +static Const * +make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation) +{ + Oid datatype = str_const->consttype; + char *workstr; + int len; + Datum cmpstr; + char *cmptxt = NULL; + mbcharacter_incrementer charinc; + + /* + * Get a modifiable copy of the prefix string in C-string format, and set + * up the string we will compare to as a Datum. In C locale this can just + * be the given prefix string, otherwise we need to add a suffix. Type + * BYTEA sorts bytewise so it never needs a suffix either. + */ + if (datatype == BYTEAOID) + { + bytea *bstr = DatumGetByteaPP(str_const->constvalue); + + len = VARSIZE_ANY_EXHDR(bstr); + workstr = (char *) palloc(len); + memcpy(workstr, VARDATA_ANY(bstr), len); + Assert((Pointer) bstr == DatumGetPointer(str_const->constvalue)); + cmpstr = str_const->constvalue; + } + else + { + if (datatype == NAMEOID) + workstr = DatumGetCString(DirectFunctionCall1(nameout, + str_const->constvalue)); + else + workstr = TextDatumGetCString(str_const->constvalue); + len = strlen(workstr); + if (lc_collate_is_c(collation) || len == 0) + cmpstr = str_const->constvalue; + else + { + /* If first time through, determine the suffix to use */ + static char suffixchar = 0; + static Oid suffixcollation = 0; + + if (!suffixchar || suffixcollation != collation) + { + char *best; + + best = "Z"; + if (varstr_cmp(best, 1, "z", 1, collation) < 0) + best = "z"; + if (varstr_cmp(best, 1, "y", 1, collation) < 0) + best = "y"; + if (varstr_cmp(best, 1, "9", 1, collation) < 0) + best = "9"; + suffixchar = *best; + suffixcollation = collation; + } + + /* And build the string to compare to */ + if (datatype == NAMEOID) + { + cmptxt = palloc(len + 2); + memcpy(cmptxt, workstr, len); + cmptxt[len] = suffixchar; + cmptxt[len + 1] = '\0'; + cmpstr = PointerGetDatum(cmptxt); + } + else + { + cmptxt = palloc(VARHDRSZ + len + 1); + SET_VARSIZE(cmptxt, VARHDRSZ + len + 1); + memcpy(VARDATA(cmptxt), workstr, len); + *(VARDATA(cmptxt) + len) = suffixchar; + cmpstr = PointerGetDatum(cmptxt); + } + } + } + + /* Select appropriate character-incrementer function */ + if (datatype == BYTEAOID) + charinc = byte_increment; + else + charinc = pg_database_encoding_character_incrementer(); + + /* And search ... */ + while (len > 0) + { + int charlen; + unsigned char *lastchar; + + /* Identify the last character --- for bytea, just the last byte */ + if (datatype == BYTEAOID) + charlen = 1; + else + charlen = len - pg_mbcliplen(workstr, len, len - 1); + lastchar = (unsigned char *) (workstr + len - charlen); + + /* + * Try to generate a larger string by incrementing the last character + * (for BYTEA, we treat each byte as a character). + * + * Note: the incrementer function is expected to return true if it's + * generated a valid-per-the-encoding new character, otherwise false. + * The contents of the character on false return are unspecified. + */ + while (charinc(lastchar, charlen)) + { + Const *workstr_const; + + if (datatype == BYTEAOID) + workstr_const = string_to_bytea_const(workstr, len); + else + workstr_const = string_to_const(workstr, datatype); + + if (DatumGetBool(FunctionCall2Coll(ltproc, + collation, + cmpstr, + workstr_const->constvalue))) + { + /* Successfully made a string larger than cmpstr */ + if (cmptxt) + pfree(cmptxt); + pfree(workstr); + return workstr_const; + } + + /* No good, release unusable value and try again */ + pfree(DatumGetPointer(workstr_const->constvalue)); + pfree(workstr_const); + } + + /* + * No luck here, so truncate off the last character and try to + * increment the next one. + */ + len -= charlen; + workstr[len] = '\0'; + } + + /* Failed... */ + if (cmptxt) + pfree(cmptxt); + pfree(workstr); + + return NULL; +} + +/* + * Generate a Datum of the appropriate type from a C string. + * Note that all of the supported types are pass-by-ref, so the + * returned value should be pfree'd if no longer needed. + */ +static Datum +string_to_datum(const char *str, Oid datatype) +{ + Assert(str != NULL); + + /* + * We cheat a little by assuming that CStringGetTextDatum() will do for + * bpchar and varchar constants too... + */ + if (datatype == NAMEOID) + return DirectFunctionCall1(namein, CStringGetDatum(str)); + else if (datatype == BYTEAOID) + return DirectFunctionCall1(byteain, CStringGetDatum(str)); + else + return CStringGetTextDatum(str); +} + +/* + * Generate a Const node of the appropriate type from a C string. + */ +static Const * +string_to_const(const char *str, Oid datatype) +{ + Datum conval = string_to_datum(str, datatype); + Oid collation; + int constlen; + + /* + * We only need to support a few datatypes here, so hard-wire properties + * instead of incurring the expense of catalog lookups. + */ + switch (datatype) + { + case TEXTOID: + case VARCHAROID: + case BPCHAROID: + collation = DEFAULT_COLLATION_OID; + constlen = -1; + break; + + case NAMEOID: + collation = C_COLLATION_OID; + constlen = NAMEDATALEN; + break; + + case BYTEAOID: + collation = InvalidOid; + constlen = -1; + break; + + default: + elog(ERROR, "unexpected datatype in string_to_const: %u", + datatype); + return NULL; + } + + return makeConst(datatype, -1, collation, constlen, + conval, false, false); +} + +/* + * Generate a Const node of bytea type from a binary C string and a length. + */ +static Const * +string_to_bytea_const(const char *str, size_t str_len) +{ + bytea *bstr = palloc(VARHDRSZ + str_len); + Datum conval; + + memcpy(VARDATA(bstr), str, str_len); + SET_VARSIZE(bstr, VARHDRSZ + str_len); + conval = PointerGetDatum(bstr); + + return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false); +} diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index 66c09a1f316..bc62c6eef75 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -3,7 +3,7 @@ * lockfuncs.c * Functions for SQL access to various lock-manager capabilities. * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/lockfuncs.c @@ -101,7 +101,7 @@ pg_lock_status(PG_FUNCTION_ARGS) /* build tupdesc for result tuples */ /* this had better match function's declaration in pg_proc.h */ - tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS, false); + tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database", @@ -655,15 +655,6 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS) #define SET_LOCKTAG_INT32(tag, key1, key2) \ SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, key1, key2, 2) -static void -PreventAdvisoryLocksInParallelMode(void) -{ - if (IsInParallelMode()) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_STATE), - errmsg("cannot use advisory locks during a parallel operation"))); -} - /* * pg_advisory_lock(int8) - acquire exclusive lock on an int8 key */ @@ -673,7 +664,6 @@ pg_advisory_lock_int8(PG_FUNCTION_ARGS) int64 key = PG_GETARG_INT64(0); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); (void) LockAcquire(&tag, ExclusiveLock, true, false); @@ -691,7 +681,6 @@ pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS) int64 key = PG_GETARG_INT64(0); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); (void) LockAcquire(&tag, ExclusiveLock, false, false); @@ -708,7 +697,6 @@ pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS) int64 key = PG_GETARG_INT64(0); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); (void) LockAcquire(&tag, ShareLock, true, false); @@ -726,7 +714,6 @@ pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS) int64 key = PG_GETARG_INT64(0); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); (void) LockAcquire(&tag, ShareLock, false, false); @@ -746,7 +733,6 @@ pg_try_advisory_lock_int8(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ExclusiveLock, true, true); @@ -767,7 +753,6 @@ pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ExclusiveLock, false, true); @@ -787,7 +772,6 @@ pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ShareLock, true, true); @@ -808,7 +792,6 @@ pg_try_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockAcquire(&tag, ShareLock, false, true); @@ -828,7 +811,6 @@ pg_advisory_unlock_int8(PG_FUNCTION_ARGS) LOCKTAG tag; bool res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockRelease(&tag, ExclusiveLock, true); @@ -848,7 +830,6 @@ pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS) LOCKTAG tag; bool res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT64(tag, key); res = LockRelease(&tag, ShareLock, true); @@ -866,7 +847,6 @@ pg_advisory_lock_int4(PG_FUNCTION_ARGS) int32 key2 = PG_GETARG_INT32(1); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); (void) LockAcquire(&tag, ExclusiveLock, true, false); @@ -885,7 +865,6 @@ pg_advisory_xact_lock_int4(PG_FUNCTION_ARGS) int32 key2 = PG_GETARG_INT32(1); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); (void) LockAcquire(&tag, ExclusiveLock, false, false); @@ -903,7 +882,6 @@ pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS) int32 key2 = PG_GETARG_INT32(1); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); (void) LockAcquire(&tag, ShareLock, true, false); @@ -922,7 +900,6 @@ pg_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS) int32 key2 = PG_GETARG_INT32(1); LOCKTAG tag; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); (void) LockAcquire(&tag, ShareLock, false, false); @@ -943,7 +920,6 @@ pg_try_advisory_lock_int4(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockAcquire(&tag, ExclusiveLock, true, true); @@ -965,7 +941,6 @@ pg_try_advisory_xact_lock_int4(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockAcquire(&tag, ExclusiveLock, false, true); @@ -986,7 +961,6 @@ pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockAcquire(&tag, ShareLock, true, true); @@ -1008,7 +982,6 @@ pg_try_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS) LOCKTAG tag; LockAcquireResult res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockAcquire(&tag, ShareLock, false, true); @@ -1029,7 +1002,6 @@ pg_advisory_unlock_int4(PG_FUNCTION_ARGS) LOCKTAG tag; bool res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockRelease(&tag, ExclusiveLock, true); @@ -1050,7 +1022,6 @@ pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS) LOCKTAG tag; bool res; - PreventAdvisoryLocksInParallelMode(); SET_LOCKTAG_INT32(tag, key1, key2); res = LockRelease(&tag, ShareLock, true); diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index 94703c8c1cb..3bfeb75fa2a 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -3,7 +3,7 @@ * mac.c * PostgreSQL type definitions for 6 byte, EUI-48, MAC addresses. * - * Portions Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1998-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/mac.c @@ -13,12 +13,12 @@ #include "postgres.h" -#include "access/hash.h" #include "lib/hyperloglog.h" #include "libpq/pqformat.h" #include "port/pg_bswap.h" #include "utils/builtins.h" #include "utils/guc.h" +#include "utils/hashutils.h" #include "utils/inet.h" #include "utils/sortsupport.h" diff --git a/src/backend/utils/adt/mac8.c b/src/backend/utils/adt/mac8.c index 6dd2febc268..0b1fe4978ea 100644 --- a/src/backend/utils/adt/mac8.c +++ b/src/backend/utils/adt/mac8.c @@ -11,7 +11,7 @@ * The following code is written with the assumption that the OUI field * size is 24 bits. * - * Portions Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1998-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/mac8.c @@ -21,9 +21,9 @@ #include "postgres.h" -#include "access/hash.h" #include "libpq/pqformat.h" #include "utils/builtins.h" +#include "utils/hashutils.h" #include "utils/inet.h" /* diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index b24dece23f8..d330a88e3c1 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -3,7 +3,7 @@ * misc.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,13 +15,12 @@ #include "postgres.h" #include -#include #include #include #include #include "access/sysattr.h" -#include "catalog/pg_authid.h" +#include "access/table.h" #include "catalog/catalog.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" @@ -35,13 +34,9 @@ #include "postmaster/syslogger.h" #include "rewrite/rewriteHandler.h" #include "storage/fd.h" -#include "storage/pmsignal.h" -#include "storage/proc.h" -#include "storage/procarray.h" #include "utils/lsyscache.h" #include "utils/ruleutils.h" #include "tcop/tcopprot.h" -#include "utils/acl.h" #include "utils/builtins.h" #include "utils/timestamp.h" @@ -198,194 +193,6 @@ current_query(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } -/* - * Send a signal to another backend. - * - * The signal is delivered if the user is either a superuser or the same - * role as the backend being signaled. For "dangerous" signals, an explicit - * check for superuser needs to be done prior to calling this function. - * - * Returns 0 on success, 1 on general failure, 2 on normal permission error - * and 3 if the caller needs to be a superuser. - * - * In the event of a general failure (return code 1), a warning message will - * be emitted. For permission errors, doing that is the responsibility of - * the caller. - */ -#define SIGNAL_BACKEND_SUCCESS 0 -#define SIGNAL_BACKEND_ERROR 1 -#define SIGNAL_BACKEND_NOPERMISSION 2 -#define SIGNAL_BACKEND_NOSUPERUSER 3 -static int -pg_signal_backend(int pid, int sig) -{ - PGPROC *proc = BackendPidGetProc(pid); - - /* - * BackendPidGetProc returns NULL if the pid isn't valid; but by the time - * we reach kill(), a process for which we get a valid proc here might - * have terminated on its own. There's no way to acquire a lock on an - * arbitrary process to prevent that. But since so far all the callers of - * this mechanism involve some request for ending the process anyway, that - * it might end on its own first is not a problem. - */ - if (proc == NULL) - { - /* - * This is just a warning so a loop-through-resultset will not abort - * if one backend terminated on its own during the run. - */ - ereport(WARNING, - (errmsg("PID %d is not a PostgreSQL server process", pid))); - return SIGNAL_BACKEND_ERROR; - } - - /* Only allow superusers to signal superuser-owned backends. */ - if (superuser_arg(proc->roleId) && !superuser()) - return SIGNAL_BACKEND_NOSUPERUSER; - - /* Users can signal backends they have role membership in. */ - if (!has_privs_of_role(GetUserId(), proc->roleId) && - !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) - return SIGNAL_BACKEND_NOPERMISSION; - - /* - * Can the process we just validated above end, followed by the pid being - * recycled for a new process, before reaching here? Then we'd be trying - * to kill the wrong thing. Seems near impossible when sequential pid - * assignment and wraparound is used. Perhaps it could happen on a system - * where pid re-use is randomized. That race condition possibility seems - * too unlikely to worry about. - */ - - /* If we have setsid(), signal the backend's whole process group */ -#ifdef HAVE_SETSID - if (kill(-pid, sig)) -#else - if (kill(pid, sig)) -#endif - { - /* Again, just a warning to allow loops */ - ereport(WARNING, - (errmsg("could not send signal to process %d: %m", pid))); - return SIGNAL_BACKEND_ERROR; - } - return SIGNAL_BACKEND_SUCCESS; -} - -/* - * Signal to cancel a backend process. This is allowed if you are a member of - * the role whose process is being canceled. - * - * Note that only superusers can signal superuser-owned processes. - */ -Datum -pg_cancel_backend(PG_FUNCTION_ARGS) -{ - int r = pg_signal_backend(PG_GETARG_INT32(0), SIGINT); - - if (r == SIGNAL_BACKEND_NOSUPERUSER) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a superuser to cancel superuser query")))); - - if (r == SIGNAL_BACKEND_NOPERMISSION) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a member of the role whose query is being canceled or member of pg_signal_backend")))); - - PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); -} - -/* - * Signal to terminate a backend process. This is allowed if you are a member - * of the role whose process is being terminated. - * - * Note that only superusers can signal superuser-owned processes. - */ -Datum -pg_terminate_backend(PG_FUNCTION_ARGS) -{ - int r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM); - - if (r == SIGNAL_BACKEND_NOSUPERUSER) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a superuser to terminate superuser process")))); - - if (r == SIGNAL_BACKEND_NOPERMISSION) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend")))); - - PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); -} - -/* - * Signal to reload the database configuration - * - * Permission checking for this function is managed through the normal - * GRANT system. - */ -Datum -pg_reload_conf(PG_FUNCTION_ARGS) -{ - if (kill(PostmasterPid, SIGHUP)) - { - ereport(WARNING, - (errmsg("failed to send signal to postmaster: %m"))); - PG_RETURN_BOOL(false); - } - - PG_RETURN_BOOL(true); -} - - -/* - * Rotate log file - * - * This function is kept to support adminpack 1.0. - */ -Datum -pg_rotate_logfile(PG_FUNCTION_ARGS) -{ - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be superuser to rotate log files with adminpack 1.0"), - errhint("Consider using pg_logfile_rotate(), which is part of core, instead.")))); - - if (!Logging_collector) - { - ereport(WARNING, - (errmsg("rotation not possible because log collection not active"))); - PG_RETURN_BOOL(false); - } - - SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE); - PG_RETURN_BOOL(true); -} - -/* - * Rotate log file - * - * Permission checking for this function is managed through the normal - * GRANT system. - */ -Datum -pg_rotate_logfile_v2(PG_FUNCTION_ARGS) -{ - if (!Logging_collector) - { - ereport(WARNING, - (errmsg("rotation not possible because log collection not active"))); - PG_RETURN_BOOL(false); - } - - SendPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE); - PG_RETURN_BOOL(true); -} - /* Function to find out which databases make use of a tablespace */ typedef struct @@ -573,7 +380,7 @@ pg_sleep(PG_FUNCTION_ARGS) break; (void) WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, delay_ms, WAIT_EVENT_PG_SLEEP); ResetLatch(MyLatch); @@ -596,7 +403,7 @@ pg_get_keywords(PG_FUNCTION_ARGS) funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode", @@ -611,15 +418,17 @@ pg_get_keywords(PG_FUNCTION_ARGS) funcctx = SRF_PERCALL_SETUP(); - if (funcctx->call_cntr < NumScanKeywords) + if (funcctx->call_cntr < ScanKeywords.num_keywords) { char *values[3]; HeapTuple tuple; /* cast-away-const is ugly but alternatives aren't much better */ - values[0] = (char *) ScanKeywords[funcctx->call_cntr].name; + values[0] = unconstify(char *, + GetScanKeyword(funcctx->call_cntr, + &ScanKeywords)); - switch (ScanKeywords[funcctx->call_cntr].category) + switch (ScanKeywordCategories[funcctx->call_cntr]) { case UNRESERVED_KEYWORD: values[1] = "U"; @@ -1013,9 +822,9 @@ pg_get_replica_identity_index(PG_FUNCTION_ARGS) Oid idxoid; Relation rel; - rel = heap_open(reloid, AccessShareLock); + rel = table_open(reloid, AccessShareLock); idxoid = RelationGetReplicaIndex(rel); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); if (OidIsValid(idxoid)) PG_RETURN_OID(idxoid); diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c deleted file mode 100644 index fae97135dbb..00000000000 --- a/src/backend/utils/adt/nabstime.c +++ /dev/null @@ -1,1571 +0,0 @@ -/*------------------------------------------------------------------------- - * - * nabstime.c - * Utilities for the built-in type "AbsoluteTime". - * Functions for the built-in type "RelativeTime". - * Functions for the built-in type "TimeInterval". - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/utils/adt/nabstime.c - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include -#include -#include -#include -#include -#include - -#include "libpq/pqformat.h" -#include "miscadmin.h" -#include "utils/builtins.h" -#include "utils/datetime.h" -#include "utils/nabstime.h" - -#define MIN_DAYNUM (-24856) /* December 13, 1901 */ -#define MAX_DAYNUM 24854 /* January 18, 2038 */ - -/* - * Unix epoch is Jan 1 00:00:00 1970. - * Postgres knows about times sixty-eight years on either side of that - * for these 4-byte types. - * - * "tinterval" is two 4-byte fields. - * Definitions for parsing tinterval. - */ - -#define IsSpace(C) ((C) == ' ') - -#define T_INTERVAL_INVAL 0 /* data represents no valid tinterval */ -#define T_INTERVAL_VALID 1 /* data represents a valid tinterval */ -/* - * ['Mon May 10 23:59:12 1943 PST' 'Sun Jan 14 03:14:21 1973 PST'] - * 0 1 2 3 4 5 6 - * 1234567890123456789012345678901234567890123456789012345678901234 - * - * we allocate some extra -- timezones are usually 3 characters but - * this is not in the POSIX standard... - */ -#define T_INTERVAL_LEN 80 -#define INVALID_INTERVAL_STR "Undefined Range" -#define INVALID_INTERVAL_STR_LEN (sizeof(INVALID_INTERVAL_STR)-1) - -#define ABSTIMEMIN(t1, t2) \ - (DatumGetBool(DirectFunctionCall2(abstimele, \ - AbsoluteTimeGetDatum(t1), \ - AbsoluteTimeGetDatum(t2))) ? (t1) : (t2)) -#define ABSTIMEMAX(t1, t2) \ - (DatumGetBool(DirectFunctionCall2(abstimelt, \ - AbsoluteTimeGetDatum(t1), \ - AbsoluteTimeGetDatum(t2))) ? (t2) : (t1)) - - -/* - * Function prototypes -- internal to this file only - */ - -static AbsoluteTime tm2abstime(struct pg_tm *tm, int tz); -static void reltime2tm(RelativeTime time, struct pg_tm *tm); -static void parsetinterval(char *i_string, - AbsoluteTime *i_start, - AbsoluteTime *i_end); - - -/* - * GetCurrentAbsoluteTime() - * - * Get the current system time (relative to Unix epoch). - * - * NB: this will overflow in 2038; it should be gone long before that. - */ -AbsoluteTime -GetCurrentAbsoluteTime(void) -{ - time_t now; - - now = time(NULL); - return (AbsoluteTime) now; -} - - -void -abstime2tm(AbsoluteTime _time, int *tzp, struct pg_tm *tm, char **tzn) -{ - pg_time_t time = (pg_time_t) _time; - struct pg_tm *tx; - - if (tzp != NULL) - tx = pg_localtime(&time, session_timezone); - else - tx = pg_gmtime(&time); - - tm->tm_year = tx->tm_year + 1900; - tm->tm_mon = tx->tm_mon + 1; - tm->tm_mday = tx->tm_mday; - tm->tm_hour = tx->tm_hour; - tm->tm_min = tx->tm_min; - tm->tm_sec = tx->tm_sec; - tm->tm_isdst = tx->tm_isdst; - - tm->tm_gmtoff = tx->tm_gmtoff; - tm->tm_zone = tx->tm_zone; - - if (tzp != NULL) - { - *tzp = -tm->tm_gmtoff; /* tm_gmtoff is Sun/DEC-ism */ - - /* - * XXX FreeBSD man pages indicate that this should work - tgl 97/04/23 - */ - if (tzn != NULL) - { - /* - * Copy no more than MAXTZLEN bytes of timezone to tzn, in case it - * contains an error message, which doesn't fit in the buffer - */ - StrNCpy(*tzn, tm->tm_zone, MAXTZLEN + 1); - if (strlen(tm->tm_zone) > MAXTZLEN) - ereport(WARNING, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid time zone name: \"%s\"", - tm->tm_zone))); - } - } - else - tm->tm_isdst = -1; -} - - -/* tm2abstime() - * Convert a tm structure to abstime. - * Note that tm has full year (not 1900-based) and 1-based month. - */ -static AbsoluteTime -tm2abstime(struct pg_tm *tm, int tz) -{ - int day; - AbsoluteTime sec; - - /* validate, before going out of range on some members */ - if (tm->tm_year < 1901 || tm->tm_year > 2038 || - tm->tm_mon < 1 || tm->tm_mon > MONTHS_PER_YEAR || - tm->tm_mday < 1 || tm->tm_mday > 31 || - tm->tm_hour < 0 || - tm->tm_hour > HOURS_PER_DAY || /* test for > 24:00:00 */ - (tm->tm_hour == HOURS_PER_DAY && (tm->tm_min > 0 || tm->tm_sec > 0)) || - tm->tm_min < 0 || tm->tm_min > MINS_PER_HOUR - 1 || - tm->tm_sec < 0 || tm->tm_sec > SECS_PER_MINUTE) - return INVALID_ABSTIME; - - day = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - UNIX_EPOCH_JDATE; - - /* check for time out of range */ - if (day < MIN_DAYNUM || day > MAX_DAYNUM) - return INVALID_ABSTIME; - - /* convert to seconds */ - sec = tm->tm_sec + tz + (tm->tm_min + (day * HOURS_PER_DAY + tm->tm_hour) * MINS_PER_HOUR) * SECS_PER_MINUTE; - - /* - * check for overflow. We need a little slop here because the H/M/S plus - * TZ offset could add up to more than 1 day. - */ - if ((day >= MAX_DAYNUM - 10 && sec < 0) || - (day <= MIN_DAYNUM + 10 && sec > 0)) - return INVALID_ABSTIME; - - /* check for reserved values (e.g. "current" on edge of usual range */ - if (!AbsoluteTimeIsReal(sec)) - return INVALID_ABSTIME; - - return sec; -} - - -/* abstimein() - * Decode date/time string and return abstime. - */ -Datum -abstimein(PG_FUNCTION_ARGS) -{ - char *str = PG_GETARG_CSTRING(0); - AbsoluteTime result; - fsec_t fsec; - int tz = 0; - struct pg_tm date, - *tm = &date; - int dterr; - char *field[MAXDATEFIELDS]; - char workbuf[MAXDATELEN + 1]; - int dtype; - int nf, - ftype[MAXDATEFIELDS]; - - dterr = ParseDateTime(str, workbuf, sizeof(workbuf), - field, ftype, MAXDATEFIELDS, &nf); - if (dterr == 0) - dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); - if (dterr != 0) - DateTimeParseError(dterr, str, "abstime"); - - switch (dtype) - { - case DTK_DATE: - result = tm2abstime(tm, tz); - break; - - case DTK_EPOCH: - - /* - * Don't bother retaining this as a reserved value, but instead - * just set to the actual epoch time (1970-01-01) - */ - result = 0; - break; - - case DTK_LATE: - result = NOEND_ABSTIME; - break; - - case DTK_EARLY: - result = NOSTART_ABSTIME; - break; - - case DTK_INVALID: - result = INVALID_ABSTIME; - break; - - default: - elog(ERROR, "unexpected dtype %d while parsing abstime \"%s\"", - dtype, str); - result = INVALID_ABSTIME; - break; - }; - - PG_RETURN_ABSOLUTETIME(result); -} - - -/* abstimeout() - * Given an AbsoluteTime return the English text version of the date - */ -Datum -abstimeout(PG_FUNCTION_ARGS) -{ - AbsoluteTime time = PG_GETARG_ABSOLUTETIME(0); - char *result; - int tz; - double fsec = 0; - struct pg_tm tt, - *tm = &tt; - char buf[MAXDATELEN + 1]; - char zone[MAXDATELEN + 1], - *tzn = zone; - - switch (time) - { - /* - * Note that timestamp no longer supports 'invalid'. Retain - * 'invalid' for abstime for now, but dump it someday. - */ - case INVALID_ABSTIME: - strcpy(buf, INVALID); - break; - case NOEND_ABSTIME: - strcpy(buf, LATE); - break; - case NOSTART_ABSTIME: - strcpy(buf, EARLY); - break; - default: - abstime2tm(time, &tz, tm, &tzn); - EncodeDateTime(tm, fsec, true, tz, tzn, DateStyle, buf); - break; - } - - result = pstrdup(buf); - PG_RETURN_CSTRING(result); -} - -/* - * abstimerecv - converts external binary format to abstime - */ -Datum -abstimerecv(PG_FUNCTION_ARGS) -{ - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - - PG_RETURN_ABSOLUTETIME((AbsoluteTime) pq_getmsgint(buf, sizeof(AbsoluteTime))); -} - -/* - * abstimesend - converts abstime to binary format - */ -Datum -abstimesend(PG_FUNCTION_ARGS) -{ - AbsoluteTime time = PG_GETARG_ABSOLUTETIME(0); - StringInfoData buf; - - pq_begintypsend(&buf); - pq_sendint32(&buf, time); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); -} - - -/* abstime_finite() - */ -Datum -abstime_finite(PG_FUNCTION_ARGS) -{ - AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); - - PG_RETURN_BOOL(abstime != INVALID_ABSTIME && - abstime != NOSTART_ABSTIME && - abstime != NOEND_ABSTIME); -} - - -/* - * abstime comparison routines - */ -static int -abstime_cmp_internal(AbsoluteTime a, AbsoluteTime b) -{ - /* - * We consider all INVALIDs to be equal and larger than any non-INVALID. - * This is somewhat arbitrary; the important thing is to have a consistent - * sort order. - */ - if (a == INVALID_ABSTIME) - { - if (b == INVALID_ABSTIME) - return 0; /* INVALID = INVALID */ - else - return 1; /* INVALID > non-INVALID */ - } - - if (b == INVALID_ABSTIME) - return -1; /* non-INVALID < INVALID */ - - if (a > b) - return 1; - else if (a == b) - return 0; - else - return -1; -} - -Datum -abstimeeq(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) == 0); -} - -Datum -abstimene(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) != 0); -} - -Datum -abstimelt(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) < 0); -} - -Datum -abstimegt(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) > 0); -} - -Datum -abstimele(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) <= 0); -} - -Datum -abstimege(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_BOOL(abstime_cmp_internal(t1, t2) >= 0); -} - -Datum -btabstimecmp(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - - PG_RETURN_INT32(abstime_cmp_internal(t1, t2)); -} - - -/* timestamp_abstime() - * Convert timestamp to abstime. - */ -Datum -timestamp_abstime(PG_FUNCTION_ARGS) -{ - Timestamp timestamp = PG_GETARG_TIMESTAMP(0); - AbsoluteTime result; - fsec_t fsec; - int tz; - struct pg_tm tt, - *tm = &tt; - - if (TIMESTAMP_IS_NOBEGIN(timestamp)) - result = NOSTART_ABSTIME; - else if (TIMESTAMP_IS_NOEND(timestamp)) - result = NOEND_ABSTIME; - else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) - { - tz = DetermineTimeZoneOffset(tm, session_timezone); - result = tm2abstime(tm, tz); - } - else - { - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); - result = INVALID_ABSTIME; - } - - PG_RETURN_ABSOLUTETIME(result); -} - -/* abstime_timestamp() - * Convert abstime to timestamp. - */ -Datum -abstime_timestamp(PG_FUNCTION_ARGS) -{ - AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); - Timestamp result; - struct pg_tm tt, - *tm = &tt; - int tz; - char zone[MAXDATELEN + 1], - *tzn = zone; - - switch (abstime) - { - case INVALID_ABSTIME: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert abstime \"invalid\" to timestamp"))); - TIMESTAMP_NOBEGIN(result); - break; - - case NOSTART_ABSTIME: - TIMESTAMP_NOBEGIN(result); - break; - - case NOEND_ABSTIME: - TIMESTAMP_NOEND(result); - break; - - default: - abstime2tm(abstime, &tz, tm, &tzn); - if (tm2timestamp(tm, 0, NULL, &result) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); - break; - }; - - PG_RETURN_TIMESTAMP(result); -} - - -/* timestamptz_abstime() - * Convert timestamp with time zone to abstime. - */ -Datum -timestamptz_abstime(PG_FUNCTION_ARGS) -{ - TimestampTz timestamp = PG_GETARG_TIMESTAMP(0); - AbsoluteTime result; - fsec_t fsec; - struct pg_tm tt, - *tm = &tt; - - if (TIMESTAMP_IS_NOBEGIN(timestamp)) - result = NOSTART_ABSTIME; - else if (TIMESTAMP_IS_NOEND(timestamp)) - result = NOEND_ABSTIME; - else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) == 0) - result = tm2abstime(tm, 0); - else - { - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); - result = INVALID_ABSTIME; - } - - PG_RETURN_ABSOLUTETIME(result); -} - -/* abstime_timestamptz() - * Convert abstime to timestamp with time zone. - */ -Datum -abstime_timestamptz(PG_FUNCTION_ARGS) -{ - AbsoluteTime abstime = PG_GETARG_ABSOLUTETIME(0); - TimestampTz result; - struct pg_tm tt, - *tm = &tt; - int tz; - char zone[MAXDATELEN + 1], - *tzn = zone; - - switch (abstime) - { - case INVALID_ABSTIME: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert abstime \"invalid\" to timestamp"))); - TIMESTAMP_NOBEGIN(result); - break; - - case NOSTART_ABSTIME: - TIMESTAMP_NOBEGIN(result); - break; - - case NOEND_ABSTIME: - TIMESTAMP_NOEND(result); - break; - - default: - abstime2tm(abstime, &tz, tm, &tzn); - if (tm2timestamp(tm, 0, &tz, &result) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); - break; - }; - - PG_RETURN_TIMESTAMP(result); -} - - -/***************************************************************************** - * USER I/O ROUTINES * - *****************************************************************************/ - -/* - * reltimein - converts a reltime string in an internal format - */ -Datum -reltimein(PG_FUNCTION_ARGS) -{ - char *str = PG_GETARG_CSTRING(0); - RelativeTime result; - struct pg_tm tt, - *tm = &tt; - fsec_t fsec; - int dtype; - int dterr; - char *field[MAXDATEFIELDS]; - int nf, - ftype[MAXDATEFIELDS]; - char workbuf[MAXDATELEN + 1]; - - dterr = ParseDateTime(str, workbuf, sizeof(workbuf), - field, ftype, MAXDATEFIELDS, &nf); - if (dterr == 0) - dterr = DecodeInterval(field, ftype, nf, INTERVAL_FULL_RANGE, - &dtype, tm, &fsec); - - /* if those functions think it's a bad format, try ISO8601 style */ - if (dterr == DTERR_BAD_FORMAT) - dterr = DecodeISO8601Interval(str, - &dtype, tm, &fsec); - - if (dterr != 0) - { - if (dterr == DTERR_FIELD_OVERFLOW) - dterr = DTERR_INTERVAL_OVERFLOW; - DateTimeParseError(dterr, str, "reltime"); - } - - switch (dtype) - { - case DTK_DELTA: - result = ((tm->tm_hour * MINS_PER_HOUR + tm->tm_min) * SECS_PER_MINUTE) + tm->tm_sec; - result += tm->tm_year * SECS_PER_YEAR + ((tm->tm_mon * DAYS_PER_MONTH) + tm->tm_mday) * SECS_PER_DAY; - break; - - default: - elog(ERROR, "unexpected dtype %d while parsing reltime \"%s\"", - dtype, str); - result = INVALID_RELTIME; - break; - } - - PG_RETURN_RELATIVETIME(result); -} - -/* - * reltimeout - converts the internal format to a reltime string - */ -Datum -reltimeout(PG_FUNCTION_ARGS) -{ - RelativeTime time = PG_GETARG_RELATIVETIME(0); - char *result; - struct pg_tm tt, - *tm = &tt; - char buf[MAXDATELEN + 1]; - - reltime2tm(time, tm); - EncodeInterval(tm, 0, IntervalStyle, buf); - - result = pstrdup(buf); - PG_RETURN_CSTRING(result); -} - -/* - * reltimerecv - converts external binary format to reltime - */ -Datum -reltimerecv(PG_FUNCTION_ARGS) -{ - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - - PG_RETURN_RELATIVETIME((RelativeTime) pq_getmsgint(buf, sizeof(RelativeTime))); -} - -/* - * reltimesend - converts reltime to binary format - */ -Datum -reltimesend(PG_FUNCTION_ARGS) -{ - RelativeTime time = PG_GETARG_RELATIVETIME(0); - StringInfoData buf; - - pq_begintypsend(&buf); - pq_sendint32(&buf, time); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); -} - - -static void -reltime2tm(RelativeTime time, struct pg_tm *tm) -{ - double dtime = time; - - FMODULO(dtime, tm->tm_year, 31557600); - FMODULO(dtime, tm->tm_mon, 2592000); - FMODULO(dtime, tm->tm_mday, SECS_PER_DAY); - FMODULO(dtime, tm->tm_hour, SECS_PER_HOUR); - FMODULO(dtime, tm->tm_min, SECS_PER_MINUTE); - FMODULO(dtime, tm->tm_sec, 1); -} - - -/* - * tintervalin - converts a tinterval string to internal format - */ -Datum -tintervalin(PG_FUNCTION_ARGS) -{ - char *tintervalstr = PG_GETARG_CSTRING(0); - TimeInterval tinterval; - AbsoluteTime i_start, - i_end, - t1, - t2; - - parsetinterval(tintervalstr, &t1, &t2); - - tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData)); - - if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) - tinterval->status = T_INTERVAL_INVAL; /* undefined */ - else - tinterval->status = T_INTERVAL_VALID; - - i_start = ABSTIMEMIN(t1, t2); - i_end = ABSTIMEMAX(t1, t2); - tinterval->data[0] = i_start; - tinterval->data[1] = i_end; - - PG_RETURN_TIMEINTERVAL(tinterval); -} - - -/* - * tintervalout - converts an internal tinterval format to a string - */ -Datum -tintervalout(PG_FUNCTION_ARGS) -{ - TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0); - char *i_str, - *p; - - i_str = (char *) palloc(T_INTERVAL_LEN); /* ["..." "..."] */ - strcpy(i_str, "[\""); - if (tinterval->status == T_INTERVAL_INVAL) - strcat(i_str, INVALID_INTERVAL_STR); - else - { - p = DatumGetCString(DirectFunctionCall1(abstimeout, - AbsoluteTimeGetDatum(tinterval->data[0]))); - strcat(i_str, p); - pfree(p); - strcat(i_str, "\" \""); - p = DatumGetCString(DirectFunctionCall1(abstimeout, - AbsoluteTimeGetDatum(tinterval->data[1]))); - strcat(i_str, p); - pfree(p); - } - strcat(i_str, "\"]"); - PG_RETURN_CSTRING(i_str); -} - -/* - * tintervalrecv - converts external binary format to tinterval - */ -Datum -tintervalrecv(PG_FUNCTION_ARGS) -{ - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - TimeInterval tinterval; - int32 status; - - tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData)); - - tinterval->status = pq_getmsgint(buf, sizeof(tinterval->status)); - tinterval->data[0] = pq_getmsgint(buf, sizeof(tinterval->data[0])); - tinterval->data[1] = pq_getmsgint(buf, sizeof(tinterval->data[1])); - - if (tinterval->data[0] == INVALID_ABSTIME || - tinterval->data[1] == INVALID_ABSTIME) - status = T_INTERVAL_INVAL; /* undefined */ - else - status = T_INTERVAL_VALID; - - if (status != tinterval->status) - ereport(ERROR, - (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), - errmsg("invalid status in external \"tinterval\" value"))); - - PG_RETURN_TIMEINTERVAL(tinterval); -} - -/* - * tintervalsend - converts tinterval to binary format - */ -Datum -tintervalsend(PG_FUNCTION_ARGS) -{ - TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0); - StringInfoData buf; - - pq_begintypsend(&buf); - pq_sendint32(&buf, tinterval->status); - pq_sendint32(&buf, tinterval->data[0]); - pq_sendint32(&buf, tinterval->data[1]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); -} - - -/***************************************************************************** - * PUBLIC ROUTINES * - *****************************************************************************/ - -Datum -interval_reltime(PG_FUNCTION_ARGS) -{ - Interval *interval = PG_GETARG_INTERVAL_P(0); - RelativeTime time; - int year, - month, - day; - TimeOffset span; - - year = interval->month / MONTHS_PER_YEAR; - month = interval->month % MONTHS_PER_YEAR; - day = interval->day; - - span = ((INT64CONST(365250000) * year + INT64CONST(30000000) * month + - INT64CONST(1000000) * day) * INT64CONST(86400)) + - interval->time; - span /= USECS_PER_SEC; - - if (span < INT_MIN || span > INT_MAX) - time = INVALID_RELTIME; - else - time = span; - - PG_RETURN_RELATIVETIME(time); -} - - -Datum -reltime_interval(PG_FUNCTION_ARGS) -{ - RelativeTime reltime = PG_GETARG_RELATIVETIME(0); - Interval *result; - int year, - month, - day; - - result = (Interval *) palloc(sizeof(Interval)); - - switch (reltime) - { - case INVALID_RELTIME: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert reltime \"invalid\" to interval"))); - result->time = 0; - result->day = 0; - result->month = 0; - break; - - default: - year = reltime / SECS_PER_YEAR; - reltime -= year * SECS_PER_YEAR; - month = reltime / (DAYS_PER_MONTH * SECS_PER_DAY); - reltime -= month * (DAYS_PER_MONTH * SECS_PER_DAY); - day = reltime / SECS_PER_DAY; - reltime -= day * SECS_PER_DAY; - - result->time = (reltime * USECS_PER_SEC); - result->month = MONTHS_PER_YEAR * year + month; - result->day = day; - break; - } - - PG_RETURN_INTERVAL_P(result); -} - - -/* - * mktinterval - creates a time interval with endpoints t1 and t2 - */ -Datum -mktinterval(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - AbsoluteTime t2 = PG_GETARG_ABSOLUTETIME(1); - AbsoluteTime tstart = ABSTIMEMIN(t1, t2); - AbsoluteTime tend = ABSTIMEMAX(t1, t2); - TimeInterval tinterval; - - tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData)); - - if (t1 == INVALID_ABSTIME || t2 == INVALID_ABSTIME) - tinterval->status = T_INTERVAL_INVAL; - - else - { - tinterval->status = T_INTERVAL_VALID; - tinterval->data[0] = tstart; - tinterval->data[1] = tend; - } - - PG_RETURN_TIMEINTERVAL(tinterval); -} - -/* - * timepl, timemi and abstimemi use the formula - * abstime + reltime = abstime - * so abstime - reltime = abstime - * and abstime - abstime = reltime - */ - -/* - * timepl - returns the value of (abstime t1 + reltime t2) - */ -Datum -timepl(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - if (AbsoluteTimeIsReal(t1) && - RelativeTimeIsValid(t2) && - ((t2 > 0 && t1 < NOEND_ABSTIME - t2) || - (t2 <= 0 && t1 > NOSTART_ABSTIME - t2))) /* prevent overflow */ - PG_RETURN_ABSOLUTETIME(t1 + t2); - - PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME); -} - - -/* - * timemi - returns the value of (abstime t1 - reltime t2) - */ -Datum -timemi(PG_FUNCTION_ARGS) -{ - AbsoluteTime t1 = PG_GETARG_ABSOLUTETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - if (AbsoluteTimeIsReal(t1) && - RelativeTimeIsValid(t2) && - ((t2 > 0 && t1 > NOSTART_ABSTIME + t2) || - (t2 <= 0 && t1 < NOEND_ABSTIME + t2))) /* prevent overflow */ - PG_RETURN_ABSOLUTETIME(t1 - t2); - - PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME); -} - - -/* - * intinterval - returns true iff absolute date is in the tinterval - */ -Datum -intinterval(PG_FUNCTION_ARGS) -{ - AbsoluteTime t = PG_GETARG_ABSOLUTETIME(0); - TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(1); - - if (tinterval->status == T_INTERVAL_VALID && t != INVALID_ABSTIME) - { - if (DatumGetBool(DirectFunctionCall2(abstimege, - AbsoluteTimeGetDatum(t), - AbsoluteTimeGetDatum(tinterval->data[0]))) && - DatumGetBool(DirectFunctionCall2(abstimele, - AbsoluteTimeGetDatum(t), - AbsoluteTimeGetDatum(tinterval->data[1])))) - PG_RETURN_BOOL(true); - } - PG_RETURN_BOOL(false); -} - -/* - * tintervalrel - returns relative time corresponding to tinterval - */ -Datum -tintervalrel(PG_FUNCTION_ARGS) -{ - TimeInterval tinterval = PG_GETARG_TIMEINTERVAL(0); - AbsoluteTime t1 = tinterval->data[0]; - AbsoluteTime t2 = tinterval->data[1]; - - if (tinterval->status != T_INTERVAL_VALID) - PG_RETURN_RELATIVETIME(INVALID_RELTIME); - - if (AbsoluteTimeIsReal(t1) && - AbsoluteTimeIsReal(t2)) - PG_RETURN_RELATIVETIME(t2 - t1); - - PG_RETURN_RELATIVETIME(INVALID_RELTIME); -} - - -/* - * timenow - returns time "now", internal format - * - * Now AbsoluteTime is time since Jan 1 1970 -mer 7 Feb 1992 - */ -Datum -timenow(PG_FUNCTION_ARGS) -{ - PG_RETURN_ABSOLUTETIME(GetCurrentAbsoluteTime()); -} - -/* - * reltime comparison routines - */ -static int -reltime_cmp_internal(RelativeTime a, RelativeTime b) -{ - /* - * We consider all INVALIDs to be equal and larger than any non-INVALID. - * This is somewhat arbitrary; the important thing is to have a consistent - * sort order. - */ - if (a == INVALID_RELTIME) - { - if (b == INVALID_RELTIME) - return 0; /* INVALID = INVALID */ - else - return 1; /* INVALID > non-INVALID */ - } - - if (b == INVALID_RELTIME) - return -1; /* non-INVALID < INVALID */ - - if (a > b) - return 1; - else if (a == b) - return 0; - else - return -1; -} - -Datum -reltimeeq(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) == 0); -} - -Datum -reltimene(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) != 0); -} - -Datum -reltimelt(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) < 0); -} - -Datum -reltimegt(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) > 0); -} - -Datum -reltimele(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) <= 0); -} - -Datum -reltimege(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_BOOL(reltime_cmp_internal(t1, t2) >= 0); -} - -Datum -btreltimecmp(PG_FUNCTION_ARGS) -{ - RelativeTime t1 = PG_GETARG_RELATIVETIME(0); - RelativeTime t2 = PG_GETARG_RELATIVETIME(1); - - PG_RETURN_INT32(reltime_cmp_internal(t1, t2)); -} - - -/* - * tintervalsame - returns true iff tinterval i1 is same as tinterval i2 - * Check begin and end time. - */ -Datum -tintervalsame(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL) - PG_RETURN_BOOL(false); - - if (DatumGetBool(DirectFunctionCall2(abstimeeq, - AbsoluteTimeGetDatum(i1->data[0]), - AbsoluteTimeGetDatum(i2->data[0]))) && - DatumGetBool(DirectFunctionCall2(abstimeeq, - AbsoluteTimeGetDatum(i1->data[1]), - AbsoluteTimeGetDatum(i2->data[1])))) - PG_RETURN_BOOL(true); - PG_RETURN_BOOL(false); -} - -/* - * tinterval comparison routines - * - * Note: comparison is based only on the lengths of the tintervals, not on - * endpoint values (as long as they're not INVALID). This is pretty bogus, - * but since it's only a legacy datatype, we're not going to change it. - * - * Some other bogus things that won't be changed for compatibility reasons: - * 1. The interval length computations overflow at 2^31 seconds, causing - * intervals longer than that to sort oddly compared to those shorter. - * 2. infinity and minus infinity (NOEND_ABSTIME and NOSTART_ABSTIME) are - * just ordinary integers. Since this code doesn't handle them specially, - * it's possible for [a b] to be considered longer than [c infinity] for - * finite abstimes a, b, c. In combination with the previous point, the - * interval [-infinity infinity] is treated as being shorter than many finite - * intervals :-( - * - * If tinterval is ever reimplemented atop timestamp, it'd be good to give - * some consideration to avoiding these problems. - */ -static int -tinterval_cmp_internal(TimeInterval a, TimeInterval b) -{ - bool a_invalid; - bool b_invalid; - AbsoluteTime a_len; - AbsoluteTime b_len; - - /* - * We consider all INVALIDs to be equal and larger than any non-INVALID. - * This is somewhat arbitrary; the important thing is to have a consistent - * sort order. - */ - a_invalid = a->status == T_INTERVAL_INVAL || - a->data[0] == INVALID_ABSTIME || - a->data[1] == INVALID_ABSTIME; - b_invalid = b->status == T_INTERVAL_INVAL || - b->data[0] == INVALID_ABSTIME || - b->data[1] == INVALID_ABSTIME; - - if (a_invalid) - { - if (b_invalid) - return 0; /* INVALID = INVALID */ - else - return 1; /* INVALID > non-INVALID */ - } - - if (b_invalid) - return -1; /* non-INVALID < INVALID */ - - a_len = a->data[1] - a->data[0]; - b_len = b->data[1] - b->data[0]; - - if (a_len > b_len) - return 1; - else if (a_len == b_len) - return 0; - else - return -1; -} - -Datum -tintervaleq(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) == 0); -} - -Datum -tintervalne(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) != 0); -} - -Datum -tintervallt(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) < 0); -} - -Datum -tintervalle(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) <= 0); -} - -Datum -tintervalgt(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) > 0); -} - -Datum -tintervalge(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_BOOL(tinterval_cmp_internal(i1, i2) >= 0); -} - -Datum -bttintervalcmp(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - PG_RETURN_INT32(tinterval_cmp_internal(i1, i2)); -} - - -/* - * tintervalleneq - returns true iff length of tinterval i is equal to - * reltime t - * tintervallenne - returns true iff length of tinterval i is not equal - * to reltime t - * tintervallenlt - returns true iff length of tinterval i is less than - * reltime t - * tintervallengt - returns true iff length of tinterval i is greater - * than reltime t - * tintervallenle - returns true iff length of tinterval i is less or - * equal than reltime t - * tintervallenge - returns true iff length of tinterval i is greater or - * equal than reltime t - */ -Datum -tintervalleneq(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt == t); -} - -Datum -tintervallenne(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt != t); -} - -Datum -tintervallenlt(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt < t); -} - -Datum -tintervallengt(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt > t); -} - -Datum -tintervallenle(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt <= t); -} - -Datum -tintervallenge(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - RelativeTime t = PG_GETARG_RELATIVETIME(1); - RelativeTime rt; - - if (i->status == T_INTERVAL_INVAL || t == INVALID_RELTIME) - PG_RETURN_BOOL(false); - rt = DatumGetRelativeTime(DirectFunctionCall1(tintervalrel, - TimeIntervalGetDatum(i))); - PG_RETURN_BOOL(rt != INVALID_RELTIME && rt >= t); -} - -/* - * tintervalct - returns true iff tinterval i1 contains tinterval i2 - */ -Datum -tintervalct(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL) - PG_RETURN_BOOL(false); - if (DatumGetBool(DirectFunctionCall2(abstimele, - AbsoluteTimeGetDatum(i1->data[0]), - AbsoluteTimeGetDatum(i2->data[0]))) && - DatumGetBool(DirectFunctionCall2(abstimege, - AbsoluteTimeGetDatum(i1->data[1]), - AbsoluteTimeGetDatum(i2->data[1])))) - PG_RETURN_BOOL(true); - PG_RETURN_BOOL(false); -} - -/* - * tintervalov - returns true iff tinterval i1 (partially) overlaps i2 - */ -Datum -tintervalov(PG_FUNCTION_ARGS) -{ - TimeInterval i1 = PG_GETARG_TIMEINTERVAL(0); - TimeInterval i2 = PG_GETARG_TIMEINTERVAL(1); - - if (i1->status == T_INTERVAL_INVAL || i2->status == T_INTERVAL_INVAL) - PG_RETURN_BOOL(false); - if (DatumGetBool(DirectFunctionCall2(abstimelt, - AbsoluteTimeGetDatum(i1->data[1]), - AbsoluteTimeGetDatum(i2->data[0]))) || - DatumGetBool(DirectFunctionCall2(abstimegt, - AbsoluteTimeGetDatum(i1->data[0]), - AbsoluteTimeGetDatum(i2->data[1])))) - PG_RETURN_BOOL(false); - PG_RETURN_BOOL(true); -} - -/* - * tintervalstart - returns the start of tinterval i - */ -Datum -tintervalstart(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - - if (i->status == T_INTERVAL_INVAL) - PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME); - PG_RETURN_ABSOLUTETIME(i->data[0]); -} - -/* - * tintervalend - returns the end of tinterval i - */ -Datum -tintervalend(PG_FUNCTION_ARGS) -{ - TimeInterval i = PG_GETARG_TIMEINTERVAL(0); - - if (i->status == T_INTERVAL_INVAL) - PG_RETURN_ABSOLUTETIME(INVALID_ABSTIME); - PG_RETURN_ABSOLUTETIME(i->data[1]); -} - - -/***************************************************************************** - * PRIVATE ROUTINES * - *****************************************************************************/ - -/* - * parsetinterval -- parse a tinterval string - * - * output parameters: - * i_start, i_end: tinterval margins - * - * Time interval: - * `[' {` '} `'' `'' {` '} `'' `'' {` '} `]' - * - * OR `Undefined Range' (see also INVALID_INTERVAL_STR) - * - * where satisfies the syntax of absolute time. - * - * e.g. [ ' Jan 18 1902' 'Jan 1 00:00:00 1970'] - */ -static void -parsetinterval(char *i_string, - AbsoluteTime *i_start, - AbsoluteTime *i_end) -{ - char *p, - *p1; - char c; - - p = i_string; - /* skip leading blanks up to '[' */ - while ((c = *p) != '\0') - { - if (IsSpace(c)) - p++; - else if (c != '[') - goto bogus; /* syntax error */ - else - break; - } - if (c == '\0') - goto bogus; /* syntax error */ - p++; - /* skip leading blanks up to '"' */ - while ((c = *p) != '\0') - { - if (IsSpace(c)) - p++; - else if (c != '"') - goto bogus; /* syntax error */ - else - break; - } - if (c == '\0') - goto bogus; /* syntax error */ - p++; - if (strncmp(INVALID_INTERVAL_STR, p, strlen(INVALID_INTERVAL_STR)) == 0) - goto bogus; /* undefined range, handled like a syntax err. */ - /* search for the end of the first date and change it to a \0 */ - p1 = p; - while ((c = *p1) != '\0') - { - if (c == '"') - break; - p1++; - } - if (c == '\0') - goto bogus; /* syntax error */ - *p1 = '\0'; - /* get the first date */ - *i_start = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein, - CStringGetDatum(p))); - /* undo change to \0 */ - *p1 = c; - p = ++p1; - /* skip blanks up to '"', beginning of second date */ - while ((c = *p) != '\0') - { - if (IsSpace(c)) - p++; - else if (c != '"') - goto bogus; /* syntax error */ - else - break; - } - if (c == '\0') - goto bogus; /* syntax error */ - p++; - /* search for the end of the second date and change it to a \0 */ - p1 = p; - while ((c = *p1) != '\0') - { - if (c == '"') - break; - p1++; - } - if (c == '\0') - goto bogus; /* syntax error */ - *p1 = '\0'; - /* get the second date */ - *i_end = DatumGetAbsoluteTime(DirectFunctionCall1(abstimein, - CStringGetDatum(p))); - /* undo change to \0 */ - *p1 = c; - p = ++p1; - /* skip blanks up to ']' */ - while ((c = *p) != '\0') - { - if (IsSpace(c)) - p++; - else if (c != ']') - goto bogus; /* syntax error */ - else - break; - } - if (c == '\0') - goto bogus; /* syntax error */ - p++; - c = *p; - if (c != '\0') - goto bogus; /* syntax error */ - - /* it seems to be a valid tinterval */ - return; - -bogus: - ereport(ERROR, - (errcode(ERRCODE_INVALID_DATETIME_FORMAT), - errmsg("invalid input syntax for type %s: \"%s\"", - "tinterval", i_string))); - *i_start = *i_end = INVALID_ABSTIME; /* keep compiler quiet */ -} - - -/***************************************************************************** - * - *****************************************************************************/ - -/* - * timeofday - - * returns the current time as a text. similar to timenow() but returns - * seconds with more precision (up to microsecs). (I need this to compare - * the Wisconsin benchmark with Illustra whose TimeNow() shows current - * time with precision up to microsecs.) - ay 3/95 - */ -Datum -timeofday(PG_FUNCTION_ARGS) -{ - struct timeval tp; - char templ[128]; - char buf[128]; - pg_time_t tt; - - gettimeofday(&tp, NULL); - tt = (pg_time_t) tp.tv_sec; - pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z", - pg_localtime(&tt, session_timezone)); - snprintf(buf, sizeof(buf), templ, tp.tv_usec); - - PG_RETURN_TEXT_P(cstring_to_text(buf)); -} diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index fe20448ac57..54425925edb 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -9,7 +9,7 @@ * always use NAMEDATALEN as the symbolic constant! - jolly 8/21/95 * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,6 +21,7 @@ #include "postgres.h" #include "catalog/namespace.h" +#include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "libpq/pqformat.h" #include "mb/pg_wchar.h" @@ -28,6 +29,7 @@ #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" +#include "utils/varlena.h" /***************************************************************************** @@ -113,30 +115,42 @@ namesend(PG_FUNCTION_ARGS) /***************************************************************************** - * PUBLIC ROUTINES * + * COMPARISON/SORTING ROUTINES * *****************************************************************************/ /* * nameeq - returns 1 iff arguments are equal * namene - returns 1 iff arguments are not equal - * - * BUGS: - * Assumes that "xy\0\0a" should be equal to "xy\0b". - * If not, can do the comparison backwards for efficiency. - * * namelt - returns 1 iff a < b * namele - returns 1 iff a <= b * namegt - returns 1 iff a > b * namege - returns 1 iff a >= b * + * Note that the use of strncmp with NAMEDATALEN limit is mostly historical; + * strcmp would do as well, because we do not allow NAME values that don't + * have a '\0' terminator. Whatever might be past the terminator is not + * considered relevant to comparisons. */ +static int +namecmp(Name arg1, Name arg2, Oid collid) +{ + /* Fast path for common case used in system catalogs */ + if (collid == C_COLLATION_OID) + return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN); + + /* Else rely on the varstr infrastructure */ + return varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)), + NameStr(*arg2), strlen(NameStr(*arg2)), + collid); +} + Datum nameeq(PG_FUNCTION_ARGS) { Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) == 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) == 0); } Datum @@ -145,7 +159,7 @@ namene(PG_FUNCTION_ARGS) Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) != 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) != 0); } Datum @@ -154,7 +168,7 @@ namelt(PG_FUNCTION_ARGS) Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) < 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) < 0); } Datum @@ -163,7 +177,7 @@ namele(PG_FUNCTION_ARGS) Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) <= 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) <= 0); } Datum @@ -172,7 +186,7 @@ namegt(PG_FUNCTION_ARGS) Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) > 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) > 0); } Datum @@ -181,14 +195,42 @@ namege(PG_FUNCTION_ARGS) Name arg1 = PG_GETARG_NAME(0); Name arg2 = PG_GETARG_NAME(1); - PG_RETURN_BOOL(strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN) >= 0); + PG_RETURN_BOOL(namecmp(arg1, arg2, PG_GET_COLLATION()) >= 0); } +Datum +btnamecmp(PG_FUNCTION_ARGS) +{ + Name arg1 = PG_GETARG_NAME(0); + Name arg2 = PG_GETARG_NAME(1); -/* (see char.c for comparison/operation routines) */ + PG_RETURN_INT32(namecmp(arg1, arg2, PG_GET_COLLATION())); +} + +Datum +btnamesortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + Oid collid = ssup->ssup_collation; + MemoryContext oldcontext; + + oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); + + /* Use generic string SortSupport */ + varstr_sortsupport(ssup, NAMEOID, collid); + + MemoryContextSwitchTo(oldcontext); + + PG_RETURN_VOID(); +} + + +/***************************************************************************** + * MISCELLANEOUS PUBLIC ROUTINES * + *****************************************************************************/ int -namecpy(Name n1, Name n2) +namecpy(Name n1, const NameData *n2) { if (!n1 || !n2) return -1; @@ -204,14 +246,6 @@ namecat(Name n1, Name n2) } #endif -#ifdef NOT_USED -int -namecmp(Name n1, Name n2) -{ - return strncmp(NameStr(*n1), NameStr(*n2), NAMEDATALEN); -} -#endif - int namestrcpy(Name name, const char *str) { @@ -243,6 +277,12 @@ namestrcat(Name name, const char *str) } #endif +/* + * Compare a NAME to a C string + * + * Assumes C collation always; be careful when using this for + * anything but equality checks! + */ int namestrcmp(Name name, const char *str) { @@ -322,3 +362,38 @@ current_schemas(PG_FUNCTION_ARGS) PG_RETURN_POINTER(array); } + +/* + * SQL-function nameconcatoid(name, oid) returns name + * + * This is used in the information_schema to produce specific_name columns, + * which are supposed to be unique per schema. We achieve that (in an ugly + * way) by appending the object's OID. The result is the same as + * ($1::text || '_' || $2::text)::name + * except that, if it would not fit in NAMEDATALEN, we make it do so by + * truncating the name input (not the oid). + */ +Datum +nameconcatoid(PG_FUNCTION_ARGS) +{ + Name nam = PG_GETARG_NAME(0); + Oid oid = PG_GETARG_OID(1); + Name result; + char suffix[20]; + int suflen; + int namlen; + + suflen = snprintf(suffix, sizeof(suffix), "_%u", oid); + namlen = strlen(NameStr(*nam)); + + /* Truncate oversize input by truncating name part, not suffix */ + if (namlen + suflen >= NAMEDATALEN) + namlen = pg_mbcliplen(NameStr(*nam), namlen, NAMEDATALEN - 1 - suflen); + + /* We use palloc0 here to ensure result is zero-padded */ + result = (Name) palloc0(NAMEDATALEN); + memcpy(NameStr(*result), NameStr(*nam), namlen); + memcpy(NameStr(*result) + namlen, suffix, suflen); + + PG_RETURN_NAME(result); +} diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index 350b1a63d21..a6dd8b75aa2 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -12,17 +12,59 @@ #include #include -#include "access/hash.h" +#include "access/stratnum.h" +#include "catalog/pg_opfamily.h" #include "catalog/pg_type.h" #include "common/ip.h" +#include "lib/hyperloglog.h" #include "libpq/libpq-be.h" #include "libpq/pqformat.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" +#include "utils/guc.h" +#include "utils/hashutils.h" #include "utils/inet.h" +#include "utils/lsyscache.h" +#include "utils/sortsupport.h" +/* + * An IPv4 netmask size is a value in the range of 0 - 32, which is + * represented with 6 bits in inet/cidr abbreviated keys where possible. + * + * An IPv4 inet/cidr abbreviated key can use up to 25 bits for subnet + * component. + */ +#define ABBREV_BITS_INET4_NETMASK_SIZE 6 +#define ABBREV_BITS_INET4_SUBNET 25 + +/* sortsupport for inet/cidr */ +typedef struct +{ + int64 input_count; /* number of non-null values seen */ + bool estimating; /* true if estimating cardinality */ + + hyperLogLogState abbr_card; /* cardinality estimator */ +} network_sortsupport_state; + static int32 network_cmp_internal(inet *a1, inet *a2); +static int network_fast_cmp(Datum x, Datum y, SortSupport ssup); +static int network_cmp_abbrev(Datum x, Datum y, SortSupport ssup); +static bool network_abbrev_abort(int memtupcount, SortSupport ssup); +static Datum network_abbrev_convert(Datum original, SortSupport ssup); +static List *match_network_function(Node *leftop, + Node *rightop, + int indexarg, + Oid funcid, + Oid opfamily); +static List *match_network_subset(Node *leftop, + Node *rightop, + bool is_eq, + Oid opfamily); static bool addressOK(unsigned char *a, int bits, int family); static inet *internal_inetpl(inet *ip, int64 addend); @@ -49,8 +91,8 @@ network_in(char *src, bool is_cidr) else ip_family(dst) = PGSQL_AF_INET; - bits = inet_net_pton(ip_family(dst), src, ip_addr(dst), - is_cidr ? ip_addrsize(dst) : -1); + bits = pg_inet_net_pton(ip_family(dst), src, ip_addr(dst), + is_cidr ? ip_addrsize(dst) : -1); if ((bits < 0) || (bits > ip_maxbits(dst))) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), @@ -103,8 +145,8 @@ network_out(inet *src, bool is_cidr) char *dst; int len; - dst = inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src), - tmp, sizeof(tmp)); + dst = pg_inet_net_ntop(ip_family(src), ip_addr(src), ip_bits(src), + tmp, sizeof(tmp)); if (dst == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), @@ -389,6 +431,379 @@ network_cmp(PG_FUNCTION_ARGS) PG_RETURN_INT32(network_cmp_internal(a1, a2)); } +/* + * SortSupport strategy routine + */ +Datum +network_sortsupport(PG_FUNCTION_ARGS) +{ + SortSupport ssup = (SortSupport) PG_GETARG_POINTER(0); + + ssup->comparator = network_fast_cmp; + ssup->ssup_extra = NULL; + + if (ssup->abbreviate) + { + network_sortsupport_state *uss; + MemoryContext oldcontext; + + oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); + + uss = palloc(sizeof(network_sortsupport_state)); + uss->input_count = 0; + uss->estimating = true; + initHyperLogLog(&uss->abbr_card, 10); + + ssup->ssup_extra = uss; + + ssup->comparator = network_cmp_abbrev; + ssup->abbrev_converter = network_abbrev_convert; + ssup->abbrev_abort = network_abbrev_abort; + ssup->abbrev_full_comparator = network_fast_cmp; + + MemoryContextSwitchTo(oldcontext); + } + + PG_RETURN_VOID(); +} + +/* + * SortSupport comparison func + */ +static int +network_fast_cmp(Datum x, Datum y, SortSupport ssup) +{ + inet *arg1 = DatumGetInetPP(x); + inet *arg2 = DatumGetInetPP(y); + + return network_cmp_internal(arg1, arg2); +} + +/* + * Abbreviated key comparison func + */ +static int +network_cmp_abbrev(Datum x, Datum y, SortSupport ssup) +{ + if (x > y) + return 1; + else if (x == y) + return 0; + else + return -1; +} + +/* + * Callback for estimating effectiveness of abbreviated key optimization. + * + * We pay no attention to the cardinality of the non-abbreviated data, because + * there is no equality fast-path within authoritative inet comparator. + */ +static bool +network_abbrev_abort(int memtupcount, SortSupport ssup) +{ + network_sortsupport_state *uss = ssup->ssup_extra; + double abbr_card; + + if (memtupcount < 10000 || uss->input_count < 10000 || !uss->estimating) + return false; + + abbr_card = estimateHyperLogLog(&uss->abbr_card); + + /* + * If we have >100k distinct values, then even if we were sorting many + * billion rows we'd likely still break even, and the penalty of undoing + * that many rows of abbrevs would probably not be worth it. At this point + * we stop counting because we know that we're now fully committed. + */ + if (abbr_card > 100000.0) + { +#ifdef TRACE_SORT + if (trace_sort) + elog(LOG, + "network_abbrev: estimation ends at cardinality %f" + " after " INT64_FORMAT " values (%d rows)", + abbr_card, uss->input_count, memtupcount); +#endif + uss->estimating = false; + return false; + } + + /* + * Target minimum cardinality is 1 per ~2k of non-null inputs. 0.5 row + * fudge factor allows us to abort earlier on genuinely pathological data + * where we've had exactly one abbreviated value in the first 2k + * (non-null) rows. + */ + if (abbr_card < uss->input_count / 2000.0 + 0.5) + { +#ifdef TRACE_SORT + if (trace_sort) + elog(LOG, + "network_abbrev: aborting abbreviation at cardinality %f" + " below threshold %f after " INT64_FORMAT " values (%d rows)", + abbr_card, uss->input_count / 2000.0 + 0.5, uss->input_count, + memtupcount); +#endif + return true; + } + +#ifdef TRACE_SORT + if (trace_sort) + elog(LOG, + "network_abbrev: cardinality %f after " INT64_FORMAT + " values (%d rows)", abbr_card, uss->input_count, memtupcount); +#endif + + return false; +} + +/* + * SortSupport conversion routine. Converts original inet/cidr representation + * to abbreviated key representation that works with simple 3-way unsigned int + * comparisons. The network_cmp_internal() rules for sorting inet/cidr datums + * are followed by abbreviated comparisons by an encoding scheme that + * conditions keys through careful use of padding. + * + * Some background: inet values have three major components (take for example + * the address 1.2.3.4/24): + * + * * A network, or netmasked bits (1.2.3.0). + * * A netmask size (/24). + * * A subnet, or bits outside of the netmask (0.0.0.4). + * + * cidr values are the same except that with only the first two components -- + * all their subnet bits *must* be zero (1.2.3.0/24). + * + * IPv4 and IPv6 are identical in this makeup, with the difference being that + * IPv4 addresses have a maximum of 32 bits compared to IPv6's 64 bits, so in + * IPv6 each part may be larger. + * + * inet/cidr types compare using these sorting rules. If inequality is detected + * at any step, comparison is finished. If any rule is a tie, the algorithm + * drops through to the next to break it: + * + * 1. IPv4 always appears before IPv6. + * 2. Network bits are compared. + * 3. Netmask size is compared. + * 4. All bits are compared (having made it here, we know that both + * netmasked bits and netmask size are equal, so we're in effect only + * comparing subnet bits). + * + * When generating abbreviated keys for SortSupport, we pack as much as we can + * into a datum while ensuring that when comparing those keys as integers, + * these rules will be respected. Exact contents depend on IP family and datum + * size. + * + * IPv4 + * ---- + * + * 4 byte datums: + * + * Start with 1 bit for the IP family (IPv4 or IPv6; this bit is present in + * every case below) followed by all but 1 of the netmasked bits. + * + * +----------+---------------------+ + * | 1 bit IP | 31 bits network | (1 bit network + * | family | (truncated) | omitted) + * +----------+---------------------+ + * + * 8 byte datums: + * + * We have space to store all netmasked bits, followed by the netmask size, + * followed by 25 bits of the subnet (25 bits is usually more than enough in + * practice). cidr datums always have all-zero subnet bits. + * + * +----------+-----------------------+--------------+--------------------+ + * | 1 bit IP | 32 bits network | 6 bits | 25 bits subnet | + * | family | (full) | network size | (truncated) | + * +----------+-----------------------+--------------+--------------------+ + * + * IPv6 + * ---- + * + * 4 byte datums: + * + * +----------+---------------------+ + * | 1 bit IP | 31 bits network | (up to 97 bits + * | family | (truncated) | network omitted) + * +----------+---------------------+ + * + * 8 byte datums: + * + * +----------+---------------------------------+ + * | 1 bit IP | 63 bits network | (up to 65 bits + * | family | (truncated) | network omitted) + * +----------+---------------------------------+ + */ +static Datum +network_abbrev_convert(Datum original, SortSupport ssup) +{ + network_sortsupport_state *uss = ssup->ssup_extra; + inet *authoritative = DatumGetInetPP(original); + Datum res, + ipaddr_datum, + subnet_bitmask, + network; + int subnet_size; + + Assert(ip_family(authoritative) == PGSQL_AF_INET || + ip_family(authoritative) == PGSQL_AF_INET6); + + /* + * Get an unsigned integer representation of the IP address by taking its + * first 4 or 8 bytes. Always take all 4 bytes of an IPv4 address. Take + * the first 8 bytes of an IPv6 address with an 8 byte datum and 4 bytes + * otherwise. + * + * We're consuming an array of unsigned char, so byteswap on little endian + * systems (an inet's ipaddr field stores the most significant byte + * first). + */ + if (ip_family(authoritative) == PGSQL_AF_INET) + { + uint32 ipaddr_datum32; + + memcpy(&ipaddr_datum32, ip_addr(authoritative), sizeof(uint32)); + + /* Must byteswap on little-endian machines */ +#ifndef WORDS_BIGENDIAN + ipaddr_datum = pg_bswap32(ipaddr_datum32); +#else + ipaddr_datum = ipaddr_datum32; +#endif + + /* Initialize result without setting ipfamily bit */ + res = (Datum) 0; + } + else + { + memcpy(&ipaddr_datum, ip_addr(authoritative), sizeof(Datum)); + + /* Must byteswap on little-endian machines */ + ipaddr_datum = DatumBigEndianToNative(ipaddr_datum); + + /* Initialize result with ipfamily (most significant) bit set */ + res = ((Datum) 1) << (SIZEOF_DATUM * BITS_PER_BYTE - 1); + } + + /* + * ipaddr_datum must be "split": high order bits go in "network" component + * of abbreviated key (often with zeroed bits at the end due to masking), + * while low order bits go in "subnet" component when there is space for + * one. This is often accomplished by generating a temp datum subnet + * bitmask, which we may reuse later when generating the subnet bits + * themselves. (Note that subnet bits are only used with IPv4 datums on + * platforms where datum is 8 bytes.) + * + * The number of bits in subnet is used to generate a datum subnet + * bitmask. For example, with a /24 IPv4 datum there are 8 subnet bits + * (since 32 - 24 is 8), so the final subnet bitmask is B'1111 1111'. We + * need explicit handling for cases where the ipaddr bits cannot all fit + * in a datum, though (otherwise we'd incorrectly mask the network + * component with IPv6 values). + */ + subnet_size = ip_maxbits(authoritative) - ip_bits(authoritative); + Assert(subnet_size >= 0); + /* subnet size must work with prefix ipaddr cases */ + subnet_size %= SIZEOF_DATUM * BITS_PER_BYTE; + if (ip_bits(authoritative) == 0) + { + /* Fit as many ipaddr bits as possible into subnet */ + subnet_bitmask = ((Datum) 0) - 1; + network = 0; + } + else if (ip_bits(authoritative) < SIZEOF_DATUM * BITS_PER_BYTE) + { + /* Split ipaddr bits between network and subnet */ + subnet_bitmask = (((Datum) 1) << subnet_size) - 1; + network = ipaddr_datum & ~subnet_bitmask; + } + else + { + /* Fit as many ipaddr bits as possible into network */ + subnet_bitmask = 0; + network = ipaddr_datum; + } + +#if SIZEOF_DATUM == 8 + if (ip_family(authoritative) == PGSQL_AF_INET) + { + /* + * IPv4 with 8 byte datums: keep all 32 netmasked bits, netmask size, + * and most significant 25 subnet bits + */ + Datum netmask_size = (Datum) ip_bits(authoritative); + Datum subnet; + + /* + * Shift left 31 bits: 6 bits netmask size + 25 subnet bits. + * + * We don't make any distinction between network bits that are zero + * due to masking and "true"/non-masked zero bits. An abbreviated + * comparison that is resolved by comparing a non-masked and non-zero + * bit to a masked/zeroed bit is effectively resolved based on + * ip_bits(), even though the comparison won't reach the netmask_size + * bits. + */ + network <<= (ABBREV_BITS_INET4_NETMASK_SIZE + + ABBREV_BITS_INET4_SUBNET); + + /* Shift size to make room for subnet bits at the end */ + netmask_size <<= ABBREV_BITS_INET4_SUBNET; + + /* Extract subnet bits without shifting them */ + subnet = ipaddr_datum & subnet_bitmask; + + /* + * If we have more than 25 subnet bits, we can't fit everything. Shift + * subnet down to avoid clobbering bits that are only supposed to be + * used for netmask_size. + * + * Discarding the least significant subnet bits like this is correct + * because abbreviated comparisons that are resolved at the subnet + * level must have had equal netmask_size/ip_bits() values in order to + * get that far. + */ + if (subnet_size > ABBREV_BITS_INET4_SUBNET) + subnet >>= subnet_size - ABBREV_BITS_INET4_SUBNET; + + /* + * Assemble the final abbreviated key without clobbering the ipfamily + * bit that must remain a zero. + */ + res |= network | netmask_size | subnet; + } + else +#endif + { + /* + * 4 byte datums, or IPv6 with 8 byte datums: Use as many of the + * netmasked bits as will fit in final abbreviated key. Avoid + * clobbering the ipfamily bit that was set earlier. + */ + res |= network >> 1; + } + + uss->input_count += 1; + + /* Hash abbreviated key */ + if (uss->estimating) + { + uint32 tmp; + +#if SIZEOF_DATUM == 8 + tmp = (uint32) res ^ (uint32) ((uint64) res >> 32); +#else /* SIZEOF_DATUM != 8 */ + tmp = (uint32) res; +#endif + + addHyperLogLog(&uss->abbr_card, DatumGetUInt32(hash_uint32(tmp))); + } + + return res; +} + /* * Boolean ordering tests. */ @@ -574,6 +989,198 @@ network_overlap(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } +/* + * Planner support function for network subset/superset operators + */ +Datum +network_subset_support(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestIndexCondition)) + { + /* Try to convert operator/function call to index conditions */ + SupportRequestIndexCondition *req = (SupportRequestIndexCondition *) rawreq; + + if (is_opclause(req->node)) + { + OpExpr *clause = (OpExpr *) req->node; + + Assert(list_length(clause->args) == 2); + ret = (Node *) + match_network_function((Node *) linitial(clause->args), + (Node *) lsecond(clause->args), + req->indexarg, + req->funcid, + req->opfamily); + } + else if (is_funcclause(req->node)) /* be paranoid */ + { + FuncExpr *clause = (FuncExpr *) req->node; + + Assert(list_length(clause->args) == 2); + ret = (Node *) + match_network_function((Node *) linitial(clause->args), + (Node *) lsecond(clause->args), + req->indexarg, + req->funcid, + req->opfamily); + } + } + + PG_RETURN_POINTER(ret); +} + +/* + * match_network_function + * Try to generate an indexqual for a network subset/superset function. + * + * This layer is just concerned with identifying the function and swapping + * the arguments if necessary. + */ +static List * +match_network_function(Node *leftop, + Node *rightop, + int indexarg, + Oid funcid, + Oid opfamily) +{ + switch (funcid) + { + case F_NETWORK_SUB: + /* indexkey must be on the left */ + if (indexarg != 0) + return NIL; + return match_network_subset(leftop, rightop, false, opfamily); + + case F_NETWORK_SUBEQ: + /* indexkey must be on the left */ + if (indexarg != 0) + return NIL; + return match_network_subset(leftop, rightop, true, opfamily); + + case F_NETWORK_SUP: + /* indexkey must be on the right */ + if (indexarg != 1) + return NIL; + return match_network_subset(rightop, leftop, false, opfamily); + + case F_NETWORK_SUPEQ: + /* indexkey must be on the right */ + if (indexarg != 1) + return NIL; + return match_network_subset(rightop, leftop, true, opfamily); + + default: + + /* + * We'd only get here if somebody attached this support function + * to an unexpected function. Maybe we should complain, but for + * now, do nothing. + */ + return NIL; + } +} + +/* + * match_network_subset + * Try to generate an indexqual for a network subset function. + */ +static List * +match_network_subset(Node *leftop, + Node *rightop, + bool is_eq, + Oid opfamily) +{ + List *result; + Datum rightopval; + Oid datatype = INETOID; + Oid opr1oid; + Oid opr2oid; + Datum opr1right; + Datum opr2right; + Expr *expr; + + /* + * Can't do anything with a non-constant or NULL comparison value. + * + * Note that since we restrict ourselves to cases with a hard constant on + * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry + * about verifying that. + */ + if (!IsA(rightop, Const) || + ((Const *) rightop)->constisnull) + return NIL; + rightopval = ((Const *) rightop)->constvalue; + + /* + * Must check that index's opfamily supports the operators we will want to + * apply. + * + * We insist on the opfamily being the specific one we expect, else we'd + * do the wrong thing if someone were to make a reverse-sort opfamily with + * the same operators. + */ + if (opfamily != NETWORK_BTREE_FAM_OID) + return NIL; + + /* + * create clause "key >= network_scan_first( rightopval )", or ">" if the + * operator disallows equality. + * + * Note: seeing that this function supports only fixed values for opfamily + * and datatype, we could just hard-wire the operator OIDs instead of + * looking them up. But for now it seems better to be general. + */ + if (is_eq) + { + opr1oid = get_opfamily_member(opfamily, datatype, datatype, + BTGreaterEqualStrategyNumber); + if (opr1oid == InvalidOid) + elog(ERROR, "no >= operator for opfamily %u", opfamily); + } + else + { + opr1oid = get_opfamily_member(opfamily, datatype, datatype, + BTGreaterStrategyNumber); + if (opr1oid == InvalidOid) + elog(ERROR, "no > operator for opfamily %u", opfamily); + } + + opr1right = network_scan_first(rightopval); + + expr = make_opclause(opr1oid, BOOLOID, false, + (Expr *) leftop, + (Expr *) makeConst(datatype, -1, + InvalidOid, /* not collatable */ + -1, opr1right, + false, false), + InvalidOid, InvalidOid); + result = list_make1(expr); + + /* create clause "key <= network_scan_last( rightopval )" */ + + opr2oid = get_opfamily_member(opfamily, datatype, datatype, + BTLessEqualStrategyNumber); + if (opr2oid == InvalidOid) + elog(ERROR, "no <= operator for opfamily %u", opfamily); + + opr2right = network_scan_last(rightopval); + + expr = make_opclause(opr2oid, BOOLOID, false, + (Expr *) leftop, + (Expr *) makeConst(datatype, -1, + InvalidOid, /* not collatable */ + -1, opr2right, + false, false), + InvalidOid, InvalidOid); + result = lappend(result, expr); + + return result; +} + + /* * Extract data from a network datatype. */ @@ -585,8 +1192,8 @@ network_host(PG_FUNCTION_ARGS) char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; /* force display of max bits, regardless of masklen... */ - if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), - tmp, sizeof(tmp)) == NULL) + if (pg_inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), + tmp, sizeof(tmp)) == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format inet value: %m"))); @@ -610,8 +1217,8 @@ network_show(PG_FUNCTION_ARGS) int len; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; - if (inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), - tmp, sizeof(tmp)) == NULL) + if (pg_inet_net_ntop(ip_family(ip), ip_addr(ip), ip_maxbits(ip), + tmp, sizeof(tmp)) == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("could not format inet value: %m"))); @@ -633,8 +1240,8 @@ inet_abbrev(PG_FUNCTION_ARGS) char *dst; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; - dst = inet_net_ntop(ip_family(ip), ip_addr(ip), - ip_bits(ip), tmp, sizeof(tmp)); + dst = pg_inet_net_ntop(ip_family(ip), ip_addr(ip), + ip_bits(ip), tmp, sizeof(tmp)); if (dst == NULL) ereport(ERROR, @@ -651,8 +1258,8 @@ cidr_abbrev(PG_FUNCTION_ARGS) char *dst; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; - dst = inet_cidr_ntop(ip_family(ip), ip_addr(ip), - ip_bits(ip), tmp, sizeof(tmp)); + dst = pg_inet_cidr_ntop(ip_family(ip), ip_addr(ip), + ip_bits(ip), tmp, sizeof(tmp)); if (dst == NULL) ereport(ERROR, @@ -1486,7 +2093,7 @@ inetmi(PG_FUNCTION_ARGS) * have to do proper sign extension. */ if (carry == 0 && byte < sizeof(int64)) - res |= ((int64) -1) << (byte * 8); + res |= ((uint64) (int64) -1) << (byte * 8); } PG_RETURN_INT64(res); diff --git a/src/backend/utils/adt/network_gist.c b/src/backend/utils/adt/network_gist.c index ba884a803bb..1a8dfb17721 100644 --- a/src/backend/utils/adt/network_gist.c +++ b/src/backend/utils/adt/network_gist.c @@ -34,7 +34,7 @@ * twice as fast as for a simpler design in which a single field doubles as * the common prefix length and the minimum ip_bits value. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/network_selfuncs.c b/src/backend/utils/adt/network_selfuncs.c index 6c365b34b16..5e0f0614ee8 100644 --- a/src/backend/utils/adt/network_selfuncs.c +++ b/src/backend/utils/adt/network_selfuncs.c @@ -7,7 +7,7 @@ * operators. Estimates are based on null fraction, most common values, * and histogram of inet/cidr columns. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -44,33 +44,33 @@ #define MAX_CONSIDERED_ELEMS 1024 static Selectivity networkjoinsel_inner(Oid operator, - VariableStatData *vardata1, VariableStatData *vardata2); + VariableStatData *vardata1, VariableStatData *vardata2); static Selectivity networkjoinsel_semi(Oid operator, - VariableStatData *vardata1, VariableStatData *vardata2); + VariableStatData *vardata1, VariableStatData *vardata2); static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues); static Selectivity inet_hist_value_sel(Datum *values, int nvalues, - Datum constvalue, int opr_codenum); + Datum constvalue, int opr_codenum); static Selectivity inet_mcv_join_sel(Datum *mcv1_values, - float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values, - float4 *mcv2_numbers, int mcv2_nvalues, Oid operator); + float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values, + float4 *mcv2_numbers, int mcv2_nvalues, Oid operator); static Selectivity inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, - int mcv_nvalues, Datum *hist_values, int hist_nvalues, - int opr_codenum); + int mcv_nvalues, Datum *hist_values, int hist_nvalues, + int opr_codenum); static Selectivity inet_hist_inclusion_join_sel(Datum *hist1_values, - int hist1_nvalues, - Datum *hist2_values, int hist2_nvalues, - int opr_codenum); + int hist1_nvalues, + Datum *hist2_values, int hist2_nvalues, + int opr_codenum); static Selectivity inet_semi_join_sel(Datum lhs_value, - bool mcv_exists, Datum *mcv_values, int mcv_nvalues, - bool hist_exists, Datum *hist_values, int hist_nvalues, - double hist_weight, - FmgrInfo *proc, int opr_codenum); + bool mcv_exists, Datum *mcv_values, int mcv_nvalues, + bool hist_exists, Datum *hist_values, int hist_nvalues, + double hist_weight, + FmgrInfo *proc, int opr_codenum); static int inet_opr_codenum(Oid operator); static int inet_inclusion_cmp(inet *left, inet *right, int opr_codenum); -static int inet_masklen_inclusion_cmp(inet *left, inet *right, - int opr_codenum); -static int inet_hist_match_divider(inet *boundary, inet *query, - int opr_codenum); +static int inet_masklen_inclusion_cmp(inet *left, inet *right, + int opr_codenum); +static int inet_hist_match_divider(inet *boundary, inet *query, + int opr_codenum); /* * Selectivity estimation for the subnet inclusion/overlap operators diff --git a/src/backend/utils/adt/network_spgist.c b/src/backend/utils/adt/network_spgist.c index e5250fe13e5..b1e268a4143 100644 --- a/src/backend/utils/adt/network_spgist.c +++ b/src/backend/utils/adt/network_spgist.c @@ -21,7 +21,7 @@ * the address family, everything goes into node 0 (which will probably * lead to creating an allTheSame tuple). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -40,8 +40,8 @@ static int inet_spg_node_number(const inet *val, int commonbits); -static int inet_spg_consistent_bitmap(const inet *prefix, int nkeys, - ScanKey scankeys, bool leaf); +static int inet_spg_consistent_bitmap(const inet *prefix, int nkeys, + ScanKey scankeys, bool leaf); /* * The SP-GiST configuration function diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index 6f400729713..a00db3ce7a8 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -11,7 +11,7 @@ * Transactions on Mathematical Software, Vol. 24, No. 4, December 1998, * pages 359-367. * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/numeric.c @@ -26,7 +26,6 @@ #include #include -#include "access/hash.h" #include "catalog/pg_type.h" #include "common/int.h" #include "funcapi.h" @@ -34,9 +33,12 @@ #include "libpq/pqformat.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/float.h" #include "utils/guc.h" +#include "utils/hashutils.h" #include "utils/int8.h" #include "utils/numeric.h" #include "utils/sortsupport.h" @@ -465,7 +467,7 @@ static void free_var(NumericVar *var); static void zero_var(NumericVar *var); static const char *set_var_from_str(const char *str, const char *cp, - NumericVar *dest); + NumericVar *dest); static void set_var_from_num(Numeric value, NumericVar *dest); static void init_var_from_num(Numeric num, NumericVar *dest); static void set_var_from_var(const NumericVar *value, NumericVar *dest); @@ -473,10 +475,11 @@ static char *get_str_from_var(const NumericVar *var); static char *get_str_from_var_sci(const NumericVar *var, int rscale); static Numeric make_result(const NumericVar *var); +static Numeric make_result_opt_error(const NumericVar *var, bool *error); static void apply_typmod(NumericVar *var, int32 typmod); -static int32 numericvar_to_int32(const NumericVar *var); +static bool numericvar_to_int32(const NumericVar *var, int32 *result); static bool numericvar_to_int64(const NumericVar *var, int64 *result); static void int64_to_numericvar(int64 val, NumericVar *var); #ifdef HAVE_INT128 @@ -492,29 +495,29 @@ static int numeric_fast_cmp(Datum x, Datum y, SortSupport ssup); static int numeric_cmp_abbrev(Datum x, Datum y, SortSupport ssup); static Datum numeric_abbrev_convert_var(const NumericVar *var, - NumericSortSupport *nss); + NumericSortSupport *nss); static int cmp_numerics(Numeric num1, Numeric num2); static int cmp_var(const NumericVar *var1, const NumericVar *var2); -static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits, - int var1weight, int var1sign, - const NumericDigit *var2digits, int var2ndigits, - int var2weight, int var2sign); +static int cmp_var_common(const NumericDigit *var1digits, int var1ndigits, + int var1weight, int var1sign, + const NumericDigit *var2digits, int var2ndigits, + int var2weight, int var2sign); static void add_var(const NumericVar *var1, const NumericVar *var2, - NumericVar *result); + NumericVar *result); static void sub_var(const NumericVar *var1, const NumericVar *var2, - NumericVar *result); + NumericVar *result); static void mul_var(const NumericVar *var1, const NumericVar *var2, - NumericVar *result, - int rscale); + NumericVar *result, + int rscale); static void div_var(const NumericVar *var1, const NumericVar *var2, - NumericVar *result, - int rscale, bool round); + NumericVar *result, + int rscale, bool round); static void div_var_fast(const NumericVar *var1, const NumericVar *var2, - NumericVar *result, int rscale, bool round); + NumericVar *result, int rscale, bool round); static int select_div_scale(const NumericVar *var1, const NumericVar *var2); static void mod_var(const NumericVar *var1, const NumericVar *var2, - NumericVar *result); + NumericVar *result); static void ceil_var(const NumericVar *var, NumericVar *result); static void floor_var(const NumericVar *var, NumericVar *result); @@ -523,26 +526,26 @@ static void exp_var(const NumericVar *arg, NumericVar *result, int rscale); static int estimate_ln_dweight(const NumericVar *var); static void ln_var(const NumericVar *arg, NumericVar *result, int rscale); static void log_var(const NumericVar *base, const NumericVar *num, - NumericVar *result); + NumericVar *result); static void power_var(const NumericVar *base, const NumericVar *exp, - NumericVar *result); + NumericVar *result); static void power_var_int(const NumericVar *base, int exp, NumericVar *result, - int rscale); + int rscale); static int cmp_abs(const NumericVar *var1, const NumericVar *var2); -static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, - int var1weight, - const NumericDigit *var2digits, int var2ndigits, - int var2weight); +static int cmp_abs_common(const NumericDigit *var1digits, int var1ndigits, + int var1weight, + const NumericDigit *var2digits, int var2ndigits, + int var2weight); static void add_abs(const NumericVar *var1, const NumericVar *var2, - NumericVar *result); + NumericVar *result); static void sub_abs(const NumericVar *var1, const NumericVar *var2, - NumericVar *result); + NumericVar *result); static void round_var(NumericVar *var, int rscale); static void trunc_var(NumericVar *var, int rscale); static void strip_var(NumericVar *var); static void compute_bucket(Numeric operand, Numeric bound1, Numeric bound2, - const NumericVar *count_var, NumericVar *result_var); + const NumericVar *count_var, NumericVar *result_var); static void accum_sum_add(NumericSumAccum *accum, const NumericVar *var1); static void accum_sum_rescale(NumericSumAccum *accum, const NumericVar *val); @@ -889,45 +892,53 @@ numeric_send(PG_FUNCTION_ARGS) /* - * numeric_transform() - + * numeric_support() + * + * Planner support function for the numeric() length coercion function. * - * Flatten calls to numeric's length coercion function that solely represent - * increases in allowable precision. Scale changes mutate every datum, so - * they are unoptimizable. Some values, e.g. 1E-1001, can only fit into an - * unconstrained numeric, so a change from an unconstrained numeric to any - * constrained numeric is also unoptimizable. + * Flatten calls that solely represent increases in allowable precision. + * Scale changes mutate every datum, so they are unoptimizable. Some values, + * e.g. 1E-1001, can only fit into an unconstrained numeric, so a change from + * an unconstrained numeric to any constrained numeric is also unoptimizable. */ Datum -numeric_transform(PG_FUNCTION_ARGS) +numeric_support(PG_FUNCTION_ARGS) { - FuncExpr *expr = castNode(FuncExpr, PG_GETARG_POINTER(0)); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); Node *ret = NULL; - Node *typmod; - Assert(list_length(expr->args) >= 2); + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + FuncExpr *expr = req->fcall; + Node *typmod; - typmod = (Node *) lsecond(expr->args); + Assert(list_length(expr->args) >= 2); - if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) - { - Node *source = (Node *) linitial(expr->args); - int32 old_typmod = exprTypmod(source); - int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); - int32 old_scale = (old_typmod - VARHDRSZ) & 0xffff; - int32 new_scale = (new_typmod - VARHDRSZ) & 0xffff; - int32 old_precision = (old_typmod - VARHDRSZ) >> 16 & 0xffff; - int32 new_precision = (new_typmod - VARHDRSZ) >> 16 & 0xffff; + typmod = (Node *) lsecond(expr->args); - /* - * If new_typmod < VARHDRSZ, the destination is unconstrained; that's - * always OK. If old_typmod >= VARHDRSZ, the source is constrained, - * and we're OK if the scale is unchanged and the precision is not - * decreasing. See further notes in function header comment. - */ - if (new_typmod < (int32) VARHDRSZ || - (old_typmod >= (int32) VARHDRSZ && - new_scale == old_scale && new_precision >= old_precision)) - ret = relabel_to_typmod(source, new_typmod); + if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) + { + Node *source = (Node *) linitial(expr->args); + int32 old_typmod = exprTypmod(source); + int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); + int32 old_scale = (old_typmod - VARHDRSZ) & 0xffff; + int32 new_scale = (new_typmod - VARHDRSZ) & 0xffff; + int32 old_precision = (old_typmod - VARHDRSZ) >> 16 & 0xffff; + int32 new_precision = (new_typmod - VARHDRSZ) >> 16 & 0xffff; + + /* + * If new_typmod < VARHDRSZ, the destination is unconstrained; + * that's always OK. If old_typmod >= VARHDRSZ, the source is + * constrained, and we're OK if the scale is unchanged and the + * precision is not decreasing. See further notes in function + * header comment. + */ + if (new_typmod < (int32) VARHDRSZ || + (old_typmod >= (int32) VARHDRSZ && + new_scale == old_scale && new_precision >= old_precision)) + ret = relabel_to_typmod(source, new_typmod); + } } PG_RETURN_POINTER(ret); @@ -1522,6 +1533,7 @@ width_bucket_numeric(PG_FUNCTION_ARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION), errmsg("lower bound cannot equal upper bound"))); + break; /* bound1 < bound2 */ case -1: @@ -1547,7 +1559,10 @@ width_bucket_numeric(PG_FUNCTION_ARGS) } /* if result exceeds the range of a legal int4, we ereport here */ - result = numericvar_to_int32(&result_var); + if (!numericvar_to_int32(&result_var, &result)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("integer out of range"))); free_var(&count_var); free_var(&result_var); @@ -2184,7 +2199,7 @@ in_range_numeric_numeric(PG_FUNCTION_ARGS) */ if (NUMERIC_IS_NAN(offset) || NUMERIC_SIGN(offset) == NUMERIC_NEG) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* @@ -2395,6 +2410,23 @@ numeric_add(PG_FUNCTION_ARGS) { Numeric num1 = PG_GETARG_NUMERIC(0); Numeric num2 = PG_GETARG_NUMERIC(1); + Numeric res; + + res = numeric_add_opt_error(num1, num2, NULL); + + PG_RETURN_NUMERIC(res); +} + +/* + * numeric_add_opt_error() - + * + * Internal version of numeric_add(). If "*have_error" flag is provided, + * on error it's set to true, NULL returned. This is helpful when caller + * need to handle errors by itself. + */ +Numeric +numeric_add_opt_error(Numeric num1, Numeric num2, bool *have_error) +{ NumericVar arg1; NumericVar arg2; NumericVar result; @@ -2404,7 +2436,7 @@ numeric_add(PG_FUNCTION_ARGS) * Handle NaN */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) - PG_RETURN_NUMERIC(make_result(&const_nan)); + return make_result(&const_nan); /* * Unpack the values, let add_var() compute the result and return it. @@ -2415,11 +2447,11 @@ numeric_add(PG_FUNCTION_ARGS) init_var(&result); add_var(&arg1, &arg2, &result); - res = make_result(&result); + res = make_result_opt_error(&result, have_error); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; } @@ -2433,6 +2465,24 @@ numeric_sub(PG_FUNCTION_ARGS) { Numeric num1 = PG_GETARG_NUMERIC(0); Numeric num2 = PG_GETARG_NUMERIC(1); + Numeric res; + + res = numeric_sub_opt_error(num1, num2, NULL); + + PG_RETURN_NUMERIC(res); +} + + +/* + * numeric_sub_opt_error() - + * + * Internal version of numeric_sub(). If "*have_error" flag is provided, + * on error it's set to true, NULL returned. This is helpful when caller + * need to handle errors by itself. + */ +Numeric +numeric_sub_opt_error(Numeric num1, Numeric num2, bool *have_error) +{ NumericVar arg1; NumericVar arg2; NumericVar result; @@ -2442,7 +2492,7 @@ numeric_sub(PG_FUNCTION_ARGS) * Handle NaN */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) - PG_RETURN_NUMERIC(make_result(&const_nan)); + return make_result(&const_nan); /* * Unpack the values, let sub_var() compute the result and return it. @@ -2453,11 +2503,11 @@ numeric_sub(PG_FUNCTION_ARGS) init_var(&result); sub_var(&arg1, &arg2, &result); - res = make_result(&result); + res = make_result_opt_error(&result, have_error); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; } @@ -2471,6 +2521,24 @@ numeric_mul(PG_FUNCTION_ARGS) { Numeric num1 = PG_GETARG_NUMERIC(0); Numeric num2 = PG_GETARG_NUMERIC(1); + Numeric res; + + res = numeric_mul_opt_error(num1, num2, NULL); + + PG_RETURN_NUMERIC(res); +} + + +/* + * numeric_mul_opt_error() - + * + * Internal version of numeric_mul(). If "*have_error" flag is provided, + * on error it's set to true, NULL returned. This is helpful when caller + * need to handle errors by itself. + */ +Numeric +numeric_mul_opt_error(Numeric num1, Numeric num2, bool *have_error) +{ NumericVar arg1; NumericVar arg2; NumericVar result; @@ -2480,7 +2548,7 @@ numeric_mul(PG_FUNCTION_ARGS) * Handle NaN */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) - PG_RETURN_NUMERIC(make_result(&const_nan)); + return make_result(&const_nan); /* * Unpack the values, let mul_var() compute the result and return it. @@ -2495,11 +2563,11 @@ numeric_mul(PG_FUNCTION_ARGS) init_var(&result); mul_var(&arg1, &arg2, &result, arg1.dscale + arg2.dscale); - res = make_result(&result); + res = make_result_opt_error(&result, have_error); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; } @@ -2513,17 +2581,38 @@ numeric_div(PG_FUNCTION_ARGS) { Numeric num1 = PG_GETARG_NUMERIC(0); Numeric num2 = PG_GETARG_NUMERIC(1); + Numeric res; + + res = numeric_div_opt_error(num1, num2, NULL); + + PG_RETURN_NUMERIC(res); +} + + +/* + * numeric_div_opt_error() - + * + * Internal version of numeric_div(). If "*have_error" flag is provided, + * on error it's set to true, NULL returned. This is helpful when caller + * need to handle errors by itself. + */ +Numeric +numeric_div_opt_error(Numeric num1, Numeric num2, bool *have_error) +{ NumericVar arg1; NumericVar arg2; NumericVar result; Numeric res; int rscale; + if (have_error) + *have_error = false; + /* * Handle NaN */ if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) - PG_RETURN_NUMERIC(make_result(&const_nan)); + return make_result(&const_nan); /* * Unpack the arguments @@ -2538,16 +2627,25 @@ numeric_div(PG_FUNCTION_ARGS) */ rscale = select_div_scale(&arg1, &arg2); + /* + * If "have_error" is provided, check for division by zero here + */ + if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0)) + { + *have_error = true; + return NULL; + } + /* * Do the divide and return the result */ div_var(&arg1, &arg2, &result, rscale, true); - res = make_result(&result); + res = make_result_opt_error(&result, have_error); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; } @@ -2604,25 +2702,55 @@ numeric_mod(PG_FUNCTION_ARGS) Numeric num1 = PG_GETARG_NUMERIC(0); Numeric num2 = PG_GETARG_NUMERIC(1); Numeric res; + + res = numeric_mod_opt_error(num1, num2, NULL); + + PG_RETURN_NUMERIC(res); +} + + +/* + * numeric_mod_opt_error() - + * + * Internal version of numeric_mod(). If "*have_error" flag is provided, + * on error it's set to true, NULL returned. This is helpful when caller + * need to handle errors by itself. + */ +Numeric +numeric_mod_opt_error(Numeric num1, Numeric num2, bool *have_error) +{ + Numeric res; NumericVar arg1; NumericVar arg2; NumericVar result; + if (have_error) + *have_error = false; + if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) - PG_RETURN_NUMERIC(make_result(&const_nan)); + return make_result(&const_nan); init_var_from_num(num1, &arg1); init_var_from_num(num2, &arg2); init_var(&result); + /* + * If "have_error" is provided, check for division by zero here + */ + if (have_error && (arg2.ndigits == 0 || arg2.digits[0] == 0)) + { + *have_error = true; + return NULL; + } + mod_var(&arg1, &arg2, &result); - res = make_result(&result); + res = make_result_opt_error(&result, NULL); free_var(&result); - PG_RETURN_NUMERIC(res); + return res; } @@ -2971,10 +3099,27 @@ numeric_power(PG_FUNCTION_ARGS) NumericVar result; /* - * Handle NaN + * Handle NaN cases. We follow the POSIX spec for pow(3), which says that + * NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other cases with NaN inputs + * yield NaN (with no error). */ - if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2)) + if (NUMERIC_IS_NAN(num1)) + { + if (!NUMERIC_IS_NAN(num2)) + { + init_var_from_num(num2, &arg2); + if (cmp_var(&arg2, &const_zero) == 0) + PG_RETURN_NUMERIC(make_result(&const_one)); + } + PG_RETURN_NUMERIC(make_result(&const_nan)); + } + if (NUMERIC_IS_NAN(num2)) + { + init_var_from_num(num1, &arg1); + if (cmp_var(&arg1, &const_one) == 0) + PG_RETURN_NUMERIC(make_result(&const_one)); PG_RETURN_NUMERIC(make_result(&const_nan)); + } /* * Initialize things @@ -3062,52 +3207,78 @@ int4_numeric(PG_FUNCTION_ARGS) PG_RETURN_NUMERIC(res); } - -Datum -numeric_int4(PG_FUNCTION_ARGS) +int32 +numeric_int4_opt_error(Numeric num, bool *have_error) { - Numeric num = PG_GETARG_NUMERIC(0); NumericVar x; int32 result; + if (have_error) + *have_error = false; + /* XXX would it be better to return NULL? */ if (NUMERIC_IS_NAN(num)) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot convert NaN to integer"))); + { + if (have_error) + { + *have_error = true; + return 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("cannot convert NaN to integer"))); + } + } /* Convert to variable format, then convert to int4 */ init_var_from_num(num, &x); - result = numericvar_to_int32(&x); - PG_RETURN_INT32(result); + + if (!numericvar_to_int32(&x, &result)) + { + if (have_error) + { + *have_error = true; + return 0; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("integer out of range"))); + } + } + + return result; +} + +Datum +numeric_int4(PG_FUNCTION_ARGS) +{ + Numeric num = PG_GETARG_NUMERIC(0); + + PG_RETURN_INT32(numeric_int4_opt_error(num, NULL)); } /* * Given a NumericVar, convert it to an int32. If the NumericVar - * exceeds the range of an int32, raise the appropriate error via - * ereport(). The input NumericVar is *not* free'd. + * exceeds the range of an int32, false is returned, otherwise true is returned. + * The input NumericVar is *not* free'd. */ -static int32 -numericvar_to_int32(const NumericVar *var) +static bool +numericvar_to_int32(const NumericVar *var, int32 *result) { - int32 result; int64 val; if (!numericvar_to_int64(var, &val)) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("integer out of range"))); + return false; /* Down-convert to int4 */ - result = (int32) val; + *result = (int32) val; /* Test for overflow by reverse-conversion. */ - if ((int64) result != val) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("integer out of range"))); - - return result; + return ((int64) *result == val); } Datum @@ -3817,8 +3988,8 @@ numeric_avg_deserialize(PG_FUNCTION_ARGS) /* sumX */ temp = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); init_var_from_num(DatumGetNumeric(temp), &tmp_var); accum_sum_add(&(result->sumX), &tmp_var); @@ -3940,16 +4111,16 @@ numeric_deserialize(PG_FUNCTION_ARGS) /* sumX */ temp = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); init_var_from_num(DatumGetNumeric(temp), &sumX_var); accum_sum_add(&(result->sumX), &sumX_var); /* sumX2 */ temp = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); init_var_from_num(DatumGetNumeric(temp), &sumX2_var); accum_sum_add(&(result->sumX2), &sumX2_var); @@ -4200,8 +4371,8 @@ numeric_poly_combine(PG_FUNCTION_ARGS) state1->sumX = state2->sumX; state1->sumX2 = state2->sumX2; #else - accum_sum_copy(&state2->sumX, &state1->sumX); - accum_sum_copy(&state2->sumX2, &state1->sumX2); + accum_sum_copy(&state1->sumX, &state2->sumX); + accum_sum_copy(&state1->sumX2, &state2->sumX2); #endif MemoryContextSwitchTo(old_context); @@ -4339,14 +4510,14 @@ numeric_poly_deserialize(PG_FUNCTION_ARGS) /* sumX */ sumX = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); /* sumX2 */ sumX2 = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); init_var_from_num(DatumGetNumeric(sumX), &sumX_var); #ifdef HAVE_INT128 @@ -4549,8 +4720,8 @@ int8_avg_deserialize(PG_FUNCTION_ARGS) /* sumX */ temp = DirectFunctionCall3(numeric_recv, PointerGetDatum(&buf), - InvalidOid, - -1); + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); init_var_from_num(DatumGetNumeric(temp), &num); #ifdef HAVE_INT128 numericvar_to_int128(&num, &result->sumX); @@ -6070,13 +6241,15 @@ get_str_from_var_sci(const NumericVar *var, int rscale) /* - * make_result() - + * make_result_opt_error() - * * Create the packed db numeric format in palloc()'d memory from - * a variable. + * a variable. If "*have_error" flag is provided, on error it's set to + * true, NULL returned. This is helpful when caller need to handle errors + * by itself. */ static Numeric -make_result(const NumericVar *var) +make_result_opt_error(const NumericVar *var, bool *have_error) { Numeric result; NumericDigit *digits = var->digits; @@ -6085,6 +6258,9 @@ make_result(const NumericVar *var) int n; Size len; + if (have_error) + *have_error = false; + if (sign == NUMERIC_NAN) { result = (Numeric) palloc(NUMERIC_HDRSZ_SHORT); @@ -6147,15 +6323,37 @@ make_result(const NumericVar *var) /* Check for overflow of int16 fields */ if (NUMERIC_WEIGHT(result) != weight || NUMERIC_DSCALE(result) != var->dscale) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("value overflows numeric format"))); + { + if (have_error) + { + *have_error = true; + return NULL; + } + else + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value overflows numeric format"))); + } + } dump_numeric("make_result()", result); return result; } +/* + * make_result() - + * + * An interface to make_result_opt_error() without "have_error" argument. + */ +static Numeric +make_result(const NumericVar *var) +{ + return make_result_opt_error(var, NULL); +} + + /* * apply_typmod() - * @@ -8335,7 +8533,7 @@ power_var_int(const NumericVar *base, int exp, NumericVar *result, int rscale) * While 0 ^ 0 can be either 1 or indeterminate (error), we treat * it as 1 because most programming languages do this. SQL:2003 * also requires a return value of 1. - * http://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power + * https://en.wikipedia.org/wiki/Exponentiation#Zero_to_the_zero_power */ set_var_from_var(&const_one, result); result->dscale = rscale; /* no need to round */ diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c index b5439f497cc..70138feb29e 100644 --- a/src/backend/utils/adt/numutils.c +++ b/src/backend/utils/adt/numutils.c @@ -3,7 +3,7 @@ * numutils.c * utility functions for I/O of built-in numeric types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -18,6 +18,7 @@ #include #include +#include "common/int.h" #include "utils/builtins.h" /* @@ -48,8 +49,8 @@ pg_atoi(const char *s, int size, int c) if (*s == 0) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for integer: \"%s\"", - s))); + errmsg("invalid input syntax for type %s: \"%s\"", + "integer", s))); errno = 0; l = strtol(s, &badp, 10); @@ -58,8 +59,8 @@ pg_atoi(const char *s, int size, int c) if (s == badp) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for integer: \"%s\"", - s))); + errmsg("invalid input syntax for type %s: \"%s\"", + "integer", s))); switch (size) { @@ -102,12 +103,164 @@ pg_atoi(const char *s, int size, int c) if (*badp && *badp != c) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for integer: \"%s\"", - s))); + errmsg("invalid input syntax for type %s: \"%s\"", + "integer", s))); return (int32) l; } +/* + * Convert input string to a signed 16 bit integer. + * + * Allows any number of leading or trailing whitespace characters. Will throw + * ereport() upon bad input format or overflow. + * + * NB: Accumulate input as a negative number, to deal with two's complement + * representation of the most negative number, which can't be represented as a + * positive number. + */ +int16 +pg_strtoint16(const char *s) +{ + const char *ptr = s; + int16 tmp = 0; + bool neg = false; + + /* skip leading spaces */ + while (likely(*ptr) && isspace((unsigned char) *ptr)) + ptr++; + + /* handle sign */ + if (*ptr == '-') + { + ptr++; + neg = true; + } + else if (*ptr == '+') + ptr++; + + /* require at least one digit */ + if (unlikely(!isdigit((unsigned char) *ptr))) + goto invalid_syntax; + + /* process digits */ + while (*ptr && isdigit((unsigned char) *ptr)) + { + int8 digit = (*ptr++ - '0'); + + if (unlikely(pg_mul_s16_overflow(tmp, 10, &tmp)) || + unlikely(pg_sub_s16_overflow(tmp, digit, &tmp))) + goto out_of_range; + } + + /* allow trailing whitespace, but not other trailing chars */ + while (*ptr != '\0' && isspace((unsigned char) *ptr)) + ptr++; + + if (unlikely(*ptr != '\0')) + goto invalid_syntax; + + if (!neg) + { + /* could fail if input is most negative number */ + if (unlikely(tmp == PG_INT16_MIN)) + goto out_of_range; + tmp = -tmp; + } + + return tmp; + +out_of_range: + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s", + s, "smallint"))); + +invalid_syntax: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", + "smallint", s))); + + return 0; /* keep compiler quiet */ +} + +/* + * Convert input string to a signed 32 bit integer. + * + * Allows any number of leading or trailing whitespace characters. Will throw + * ereport() upon bad input format or overflow. + * + * NB: Accumulate input as a negative number, to deal with two's complement + * representation of the most negative number, which can't be represented as a + * positive number. + */ +int32 +pg_strtoint32(const char *s) +{ + const char *ptr = s; + int32 tmp = 0; + bool neg = false; + + /* skip leading spaces */ + while (likely(*ptr) && isspace((unsigned char) *ptr)) + ptr++; + + /* handle sign */ + if (*ptr == '-') + { + ptr++; + neg = true; + } + else if (*ptr == '+') + ptr++; + + /* require at least one digit */ + if (unlikely(!isdigit((unsigned char) *ptr))) + goto invalid_syntax; + + /* process digits */ + while (*ptr && isdigit((unsigned char) *ptr)) + { + int8 digit = (*ptr++ - '0'); + + if (unlikely(pg_mul_s32_overflow(tmp, 10, &tmp)) || + unlikely(pg_sub_s32_overflow(tmp, digit, &tmp))) + goto out_of_range; + } + + /* allow trailing whitespace, but not other trailing chars */ + while (*ptr != '\0' && isspace((unsigned char) *ptr)) + ptr++; + + if (unlikely(*ptr != '\0')) + goto invalid_syntax; + + if (!neg) + { + /* could fail if input is most negative number */ + if (unlikely(tmp == PG_INT32_MIN)) + goto out_of_range; + tmp = -tmp; + } + + return tmp; + +out_of_range: + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value \"%s\" is out of range for type %s", + s, "integer"))); + +invalid_syntax: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", + "integer", s))); + + return 0; /* keep compiler quiet */ +} + /* * pg_itoa: converts a signed 16-bit integer to its string representation * diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c index b0670e0d9f7..778d186f5b8 100644 --- a/src/backend/utils/adt/oid.c +++ b/src/backend/utils/adt/oid.c @@ -3,7 +3,7 @@ * oid.c * Functions for the built-in type Oid ... also oidvector. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -256,8 +256,8 @@ oidvectorout(PG_FUNCTION_ARGS) Datum oidvectorrecv(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(locfcinfo, 3); StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - FunctionCallInfoData locfcinfo; oidvector *result; /* @@ -266,19 +266,19 @@ oidvectorrecv(PG_FUNCTION_ARGS) * fcinfo->flinfo->fn_extra. So we need to pass it our own flinfo * parameter. */ - InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, + InitFunctionCallInfoData(*locfcinfo, fcinfo->flinfo, 3, InvalidOid, NULL, NULL); - locfcinfo.arg[0] = PointerGetDatum(buf); - locfcinfo.arg[1] = ObjectIdGetDatum(OIDOID); - locfcinfo.arg[2] = Int32GetDatum(-1); - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.argnull[2] = false; + locfcinfo->args[0].value = PointerGetDatum(buf); + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = ObjectIdGetDatum(OIDOID); + locfcinfo->args[1].isnull = false; + locfcinfo->args[2].value = Int32GetDatum(-1); + locfcinfo->args[2].isnull = false; - result = (oidvector *) DatumGetPointer(array_recv(&locfcinfo)); + result = (oidvector *) DatumGetPointer(array_recv(locfcinfo)); - Assert(!locfcinfo.isnull); + Assert(!locfcinfo->isnull); /* sanity checks: oidvector must be 1-D, 0-based, no nulls */ if (ARR_NDIM(result) != 1 || @@ -308,7 +308,7 @@ oidvectorsend(PG_FUNCTION_ARGS) } /* - * oidparse - get OID from IConst/FConst node + * oidparse - get OID from ICONST/FCONST node */ Oid oidparse(Node *node) diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c index c827001ad31..0fdfee58253 100644 --- a/src/backend/utils/adt/oracle_compat.c +++ b/src/backend/utils/adt/oracle_compat.c @@ -2,7 +2,7 @@ * oracle_compat.c * Oracle compatible functions. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * Author: Edmund Mergl * Multibyte enhancement: Tatsuo Ishii @@ -22,8 +22,8 @@ static text *dotrim(const char *string, int stringlen, - const char *set, int setlen, - bool doltrim, bool dortrim); + const char *set, int setlen, + bool doltrim, bool dortrim); /******************************************************************** @@ -527,7 +527,7 @@ dotrim(const char *string, int stringlen, * * Syntax: * - * bytea byteatrim(byta string, bytea set) + * bytea byteatrim(bytea string, bytea set) * * Purpose: * diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c index ed36851fddf..4db2d0d0e17 100644 --- a/src/backend/utils/adt/orderedsetaggs.c +++ b/src/backend/utils/adt/orderedsetaggs.c @@ -3,7 +3,7 @@ * orderedsetaggs.c * Ordered-set aggregate functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,7 +14,6 @@ */ #include "postgres.h" -#include #include #include "catalog/pg_aggregate.h" @@ -23,7 +22,7 @@ #include "executor/executor.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/tlist.h" +#include "optimizer/optimizer.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -216,7 +215,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples) * Get a tupledesc corresponding to the aggregated inputs * (including sort expressions) of the agg. */ - qstate->tupdesc = ExecTypeFromTL(aggref->args, false); + qstate->tupdesc = ExecTypeFromTL(aggref->args); /* If we need a flag column, hack the tupledesc to include that */ if (ishypothetical) @@ -224,7 +223,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples) TupleDesc newdesc; int natts = qstate->tupdesc->natts; - newdesc = CreateTemplateTupleDesc(natts + 1, false); + newdesc = CreateTemplateTupleDesc(natts + 1); for (i = 1; i <= natts; i++) TupleDescCopyEntry(newdesc, i, qstate->tupdesc, i); @@ -240,7 +239,8 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples) } /* Create slot we'll use to store/retrieve rows */ - qstate->tupslot = MakeSingleTupleTableSlot(qstate->tupdesc); + qstate->tupslot = MakeSingleTupleTableSlot(qstate->tupdesc, + &TTSOpsMinimalTuple); } else { @@ -1084,7 +1084,7 @@ mode_final(PG_FUNCTION_ARGS) last_abbrev_val = abbrev_val; } else if (abbrev_val == last_abbrev_val && - DatumGetBool(FunctionCall2(equalfn, val, last_val))) + DatumGetBool(FunctionCall2Coll(equalfn, PG_GET_COLLATION(), val, last_val))) { /* value equal to previous value, count it */ if (last_val_is_mode) @@ -1310,7 +1310,15 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS) osastate = (OSAPerGroupState *) PG_GETARG_POINTER(0); econtext = osastate->qstate->econtext; if (!econtext) - osastate->qstate->econtext = econtext = CreateStandaloneExprContext(); + { + MemoryContext oldcontext; + + /* Make sure to we create econtext under correct parent context. */ + oldcontext = MemoryContextSwitchTo(osastate->qstate->qcontext); + osastate->qstate->econtext = CreateStandaloneExprContext(); + econtext = osastate->qstate->econtext; + MemoryContextSwitchTo(oldcontext); + } /* Adjust nargs to be the number of direct (or aggregated) args */ if (nargs % 2 != 0) @@ -1337,6 +1345,7 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS) numDistinctCols, sortColIdx, osastate->qstate->eqOperators, + osastate->qstate->sortCollations, NULL); MemoryContextSwitchTo(oldContext); osastate->qstate->compareTuple = compareTuple; @@ -1368,7 +1377,8 @@ hypothetical_dense_rank_final(PG_FUNCTION_ARGS) * previous row available for comparisons. This is accomplished by * swapping the slot pointer variables after each row. */ - extraslot = MakeSingleTupleTableSlot(osastate->qstate->tupdesc); + extraslot = MakeSingleTupleTableSlot(osastate->qstate->tupdesc, + &TTSOpsMinimalTuple); slot2 = extraslot; /* iterate till we find the hypothetical row */ diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c new file mode 100644 index 00000000000..e2e51563549 --- /dev/null +++ b/src/backend/utils/adt/partitionfuncs.c @@ -0,0 +1,252 @@ +/*------------------------------------------------------------------------- + * + * partitionfuncs.c + * Functions for accessing partition-related metadata + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/backend/utils/adt/partitionfuncs.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres.h" + +#include "access/htup_details.h" +#include "catalog/partition.h" +#include "catalog/pg_class.h" +#include "catalog/pg_inherits.h" +#include "catalog/pg_type.h" +#include "funcapi.h" +#include "utils/fmgrprotos.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" + +/* + * Checks if a given relation can be part of a partition tree. Returns + * false if the relation cannot be processed, in which case it is up to + * the caller to decide what to do, by either raising an error or doing + * something else. + */ +static bool +check_rel_can_be_partition(Oid relid) +{ + char relkind; + bool relispartition; + + /* Check if relation exists */ + if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid))) + return false; + + relkind = get_rel_relkind(relid); + relispartition = get_rel_relispartition(relid); + + /* Only allow relation types that can appear in partition trees. */ + if (!relispartition && + relkind != RELKIND_PARTITIONED_TABLE && + relkind != RELKIND_PARTITIONED_INDEX) + return false; + + return true; +} + +/* + * pg_partition_tree + * + * Produce a view with one row per member of a partition tree, beginning + * from the top-most parent given by the caller. This gives information + * about each partition, its immediate partitioned parent, if it is + * a leaf partition and its level in the hierarchy. + */ +Datum +pg_partition_tree(PG_FUNCTION_ARGS) +{ +#define PG_PARTITION_TREE_COLS 4 + Oid rootrelid = PG_GETARG_OID(0); + FuncCallContext *funcctx; + List *partitions; + + /* stuff done only on the first call of the function */ + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcxt; + TupleDesc tupdesc; + + /* create a function context for cross-call persistence */ + funcctx = SRF_FIRSTCALL_INIT(); + + if (!check_rel_can_be_partition(rootrelid)) + SRF_RETURN_DONE(funcctx); + + /* switch to memory context appropriate for multiple function calls */ + oldcxt = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + /* + * Find all members of inheritance set. We only need AccessShareLock + * on the children for the partition information lookup. + */ + partitions = find_all_inheritors(rootrelid, AccessShareLock, NULL); + + tupdesc = CreateTemplateTupleDesc(PG_PARTITION_TREE_COLS); + TupleDescInitEntry(tupdesc, (AttrNumber) 1, "relid", + REGCLASSOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 2, "parentid", + REGCLASSOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 3, "isleaf", + BOOLOID, -1, 0); + TupleDescInitEntry(tupdesc, (AttrNumber) 4, "level", + INT4OID, -1, 0); + + funcctx->tuple_desc = BlessTupleDesc(tupdesc); + + /* The only state we need is the partition list */ + funcctx->user_fctx = (void *) partitions; + + MemoryContextSwitchTo(oldcxt); + } + + /* stuff done on every call of the function */ + funcctx = SRF_PERCALL_SETUP(); + partitions = (List *) funcctx->user_fctx; + + if (funcctx->call_cntr < list_length(partitions)) + { + Datum result; + Datum values[PG_PARTITION_TREE_COLS]; + bool nulls[PG_PARTITION_TREE_COLS]; + HeapTuple tuple; + Oid parentid = InvalidOid; + Oid relid = list_nth_oid(partitions, funcctx->call_cntr); + char relkind = get_rel_relkind(relid); + int level = 0; + List *ancestors = get_partition_ancestors(relid); + ListCell *lc; + + /* + * Form tuple with appropriate data. + */ + MemSet(nulls, 0, sizeof(nulls)); + MemSet(values, 0, sizeof(values)); + + /* relid */ + values[0] = ObjectIdGetDatum(relid); + + /* parentid */ + if (ancestors != NIL) + parentid = linitial_oid(ancestors); + if (OidIsValid(parentid)) + values[1] = ObjectIdGetDatum(parentid); + else + nulls[1] = true; + + /* isleaf */ + values[2] = BoolGetDatum(relkind != RELKIND_PARTITIONED_TABLE && + relkind != RELKIND_PARTITIONED_INDEX); + + /* level */ + if (relid != rootrelid) + { + foreach(lc, ancestors) + { + level++; + if (lfirst_oid(lc) == rootrelid) + break; + } + } + values[3] = Int32GetDatum(level); + + tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + SRF_RETURN_NEXT(funcctx, result); + } + + /* done when there are no more elements left */ + SRF_RETURN_DONE(funcctx); +} + +/* + * pg_partition_root + * + * Returns the top-most parent of the partition tree to which a given + * relation belongs, or NULL if it's not (or cannot be) part of any + * partition tree. + */ +Datum +pg_partition_root(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + Oid rootrelid; + List *ancestors; + + if (!check_rel_can_be_partition(relid)) + PG_RETURN_NULL(); + + /* fetch the list of ancestors */ + ancestors = get_partition_ancestors(relid); + + /* + * If the input relation is already the top-most parent, just return + * itself. + */ + if (ancestors == NIL) + PG_RETURN_OID(relid); + + rootrelid = llast_oid(ancestors); + list_free(ancestors); + + /* + * "rootrelid" must contain a valid OID, given that the input relation is + * a valid partition tree member as checked above. + */ + Assert(OidIsValid(rootrelid)); + PG_RETURN_OID(rootrelid); +} + +/* + * pg_partition_ancestors + * + * Produces a view with one row per ancestor of the given partition, + * including the input relation itself. + */ +Datum +pg_partition_ancestors(PG_FUNCTION_ARGS) +{ + Oid relid = PG_GETARG_OID(0); + FuncCallContext *funcctx; + List *ancestors; + + if (SRF_IS_FIRSTCALL()) + { + MemoryContext oldcxt; + + funcctx = SRF_FIRSTCALL_INIT(); + + if (!check_rel_can_be_partition(relid)) + SRF_RETURN_DONE(funcctx); + + oldcxt = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + + ancestors = get_partition_ancestors(relid); + ancestors = lcons_oid(relid, ancestors); + + /* The only state we need is the ancestors list */ + funcctx->user_fctx = (void *) ancestors; + + MemoryContextSwitchTo(oldcxt); + } + + funcctx = SRF_PERCALL_SETUP(); + ancestors = (List *) funcctx->user_fctx; + + if (funcctx->call_cntr < list_length(ancestors)) + { + Oid relid = list_nth_oid(ancestors, funcctx->call_cntr); + + SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(relid)); + } + + SRF_RETURN_DONE(funcctx); +} diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index a3dc3be5a87..b2f08ead454 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -2,7 +2,7 @@ * * PostgreSQL locale utilities * - * Portions Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2002-2019, PostgreSQL Global Development Group * * src/backend/utils/adt/pg_locale.c * @@ -22,8 +22,9 @@ * settable at run-time. However, we don't actually set those locale * categories permanently. This would have bizarre effects like no * longer accepting standard floating-point literals in some locales. - * Instead, we only set the locales briefly when needed, cache the - * required information obtained from localeconv(), and set them back. + * Instead, we only set these locale categories briefly when needed, + * cache the required information obtained from localeconv() or + * strftime(), and then set the locale categories back to "C". * The cached information is only used by the formatting functions * (to_char, etc.) and the money type. For the user, this should all be * transparent. @@ -42,7 +43,7 @@ * will change the memory save is pointing at. To do this sort of thing * safely, you *must* pstrdup what setlocale returns the first time. * - * FYI, The Open Group locale standard is defined here: + * The POSIX locale standard is available here: * * http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap07.html *---------- @@ -58,6 +59,7 @@ #include "catalog/pg_control.h" #include "mb/pg_wchar.h" #include "utils/builtins.h" +#include "utils/formatting.h" #include "utils/hsearch.h" #include "utils/lsyscache.h" #include "utils/memutils.h" @@ -77,7 +79,7 @@ #undef StrNCpy #include #ifdef StrNCpy -#undef STrNCpy +#undef StrNCpy #endif #endif @@ -132,6 +134,9 @@ static HTAB *collation_cache = NULL; static char *IsoLocaleName(const char *); /* MSVC specific */ #endif +#ifdef USE_ICU +static void icu_set_collation_attributes(UCollator *collator, const char *loc); +#endif /* * pg_perm_setlocale @@ -486,7 +491,6 @@ PGLC_localeconv(void) static bool CurrentLocaleConvAllocated = false; struct lconv *extlconv; struct lconv worklconv; - bool trouble = false; char *save_lc_monetary; char *save_lc_numeric; #ifdef WIN32 @@ -518,42 +522,38 @@ PGLC_localeconv(void) */ memset(&worklconv, 0, sizeof(worklconv)); - /* Save user's values of monetary and numeric locales */ + /* Save prevailing values of monetary and numeric locales */ save_lc_monetary = setlocale(LC_MONETARY, NULL); - if (save_lc_monetary) - save_lc_monetary = pstrdup(save_lc_monetary); + if (!save_lc_monetary) + elog(ERROR, "setlocale(NULL) failed"); + save_lc_monetary = pstrdup(save_lc_monetary); save_lc_numeric = setlocale(LC_NUMERIC, NULL); - if (save_lc_numeric) - save_lc_numeric = pstrdup(save_lc_numeric); + if (!save_lc_numeric) + elog(ERROR, "setlocale(NULL) failed"); + save_lc_numeric = pstrdup(save_lc_numeric); #ifdef WIN32 /* - * Ideally, monetary and numeric local symbols could be returned in any - * server encoding. Unfortunately, the WIN32 API does not allow - * setlocale() to return values in a codepage/CTYPE that uses more than - * two bytes per character, such as UTF-8: - * - * http://msdn.microsoft.com/en-us/library/x99tb11d.aspx + * The POSIX standard explicitly says that it is undefined what happens if + * LC_MONETARY or LC_NUMERIC imply an encoding (codeset) different from + * that implied by LC_CTYPE. In practice, all Unix-ish platforms seem to + * believe that localeconv() should return strings that are encoded in the + * codeset implied by the LC_MONETARY or LC_NUMERIC locale name. Hence, + * once we have successfully collected the localeconv() results, we will + * convert them from that codeset to the desired server encoding. * - * Evidently, LC_CTYPE allows us to control the encoding used for strings - * returned by localeconv(). The Open Group standard, mentioned at the - * top of this C file, doesn't explicitly state this. - * - * Therefore, we set LC_CTYPE to match LC_NUMERIC or LC_MONETARY (which - * cannot be UTF8), call localeconv(), and then convert from the - * numeric/monetary LC_CTYPE to the server encoding. One example use of - * this is for the Euro symbol. - * - * Perhaps someday we will use GetLocaleInfoW() which returns values in - * UTF16 and convert from that. + * Windows, of course, resolutely does things its own way; on that + * platform LC_CTYPE has to match LC_MONETARY/LC_NUMERIC to get sane + * results. Hence, we must temporarily set that category as well. */ - /* save user's value of ctype locale */ + /* Save prevailing value of ctype locale */ save_lc_ctype = setlocale(LC_CTYPE, NULL); - if (save_lc_ctype) - save_lc_ctype = pstrdup(save_lc_ctype); + if (!save_lc_ctype) + elog(ERROR, "setlocale(NULL) failed"); + save_lc_ctype = pstrdup(save_lc_ctype); /* Here begins the critical section where we must not throw error */ @@ -597,27 +597,22 @@ PGLC_localeconv(void) worklconv.p_sign_posn = extlconv->p_sign_posn; worklconv.n_sign_posn = extlconv->n_sign_posn; - /* Try to restore internal settings */ - if (save_lc_monetary) - { - if (!setlocale(LC_MONETARY, save_lc_monetary)) - trouble = true; - } - - if (save_lc_numeric) - { - if (!setlocale(LC_NUMERIC, save_lc_numeric)) - trouble = true; - } - + /* + * Restore the prevailing locale settings; failure to do so is fatal. + * Possibly we could limp along with nondefault LC_MONETARY or LC_NUMERIC, + * but proceeding with the wrong value of LC_CTYPE would certainly be bad + * news; and considering that the prevailing LC_MONETARY and LC_NUMERIC + * are almost certainly "C", there's really no reason that restoring those + * should fail. + */ #ifdef WIN32 - /* Try to restore internal ctype settings */ - if (save_lc_ctype) - { - if (!setlocale(LC_CTYPE, save_lc_ctype)) - trouble = true; - } + if (!setlocale(LC_CTYPE, save_lc_ctype)) + elog(FATAL, "failed to restore LC_CTYPE to \"%s\"", save_lc_ctype); #endif + if (!setlocale(LC_MONETARY, save_lc_monetary)) + elog(FATAL, "failed to restore LC_MONETARY to \"%s\"", save_lc_monetary); + if (!setlocale(LC_NUMERIC, save_lc_numeric)) + elog(FATAL, "failed to restore LC_NUMERIC to \"%s\"", save_lc_numeric); /* * At this point we've done our best to clean up, and can call functions @@ -628,21 +623,11 @@ PGLC_localeconv(void) { int encoding; - /* - * Report it if we failed to restore anything. Perhaps this should be - * FATAL, rather than continuing with bad locale settings? - */ - if (trouble) - elog(WARNING, "failed to restore old locale"); - /* Release the pstrdup'd locale names */ - if (save_lc_monetary) - pfree(save_lc_monetary); - if (save_lc_numeric) - pfree(save_lc_numeric); + pfree(save_lc_monetary); + pfree(save_lc_numeric); #ifdef WIN32 - if (save_lc_ctype) - pfree(save_lc_ctype); + pfree(save_lc_ctype); #endif /* If any of the preceding strdup calls failed, complain now. */ @@ -653,15 +638,22 @@ PGLC_localeconv(void) /* * Now we must perform encoding conversion from whatever's associated - * with the locale into the database encoding. + * with the locales into the database encoding. If we can't identify + * the encoding implied by LC_NUMERIC or LC_MONETARY (ie we get -1), + * use PG_SQL_ASCII, which will result in just validating that the + * strings are OK in the database encoding. */ encoding = pg_get_encoding_from_locale(locale_numeric, true); + if (encoding < 0) + encoding = PG_SQL_ASCII; db_encoding_convert(encoding, &worklconv.decimal_point); db_encoding_convert(encoding, &worklconv.thousands_sep); /* grouping is not text and does not require conversion */ encoding = pg_get_encoding_from_locale(locale_monetary, true); + if (encoding < 0) + encoding = PG_SQL_ASCII; db_encoding_convert(encoding, &worklconv.int_curr_symbol); db_encoding_convert(encoding, &worklconv.currency_symbol); @@ -689,15 +681,15 @@ PGLC_localeconv(void) #ifdef WIN32 /* - * On WIN32, strftime() returns the encoding in CP_ACP (the default - * operating system codpage for that computer), which is likely different + * On Windows, strftime() returns its output in encoding CP_ACP (the default + * operating system codepage for the computer), which is likely different * from SERVER_ENCODING. This is especially important in Japanese versions * of Windows which will use SJIS encoding, which we don't support as a * server encoding. * * So, instead of using strftime(), use wcsftime() to return the value in - * wide characters (internally UTF16) and then convert it to the appropriate - * database encoding. + * wide characters (internally UTF16) and then convert to UTF8, which we + * know how to handle directly. * * Note that this only affects the calls to strftime() in this file, which are * used to get the locale-aware strings. Other parts of the backend use @@ -708,10 +700,13 @@ strftime_win32(char *dst, size_t dstlen, const char *format, const struct tm *tm) { size_t len; - wchar_t wformat[8]; /* formats used below need 3 bytes */ + wchar_t wformat[8]; /* formats used below need 3 chars */ wchar_t wbuf[MAX_L10N_DATA]; - /* get a wchar_t version of the format string */ + /* + * Get a wchar_t version of the format string. We only actually use + * plain-ASCII formats in this file, so we can say that they're UTF8. + */ len = MultiByteToWideChar(CP_UTF8, 0, format, -1, wformat, lengthof(wformat)); if (len == 0) @@ -722,7 +717,7 @@ strftime_win32(char *dst, size_t dstlen, if (len == 0) { /* - * strftime failed, possibly because the result would not fit in + * wcsftime failed, possibly because the result would not fit in * MAX_L10N_DATA. Return 0 with the contents of dst unspecified. */ return 0; @@ -735,17 +730,6 @@ strftime_win32(char *dst, size_t dstlen, GetLastError()); dst[len] = '\0'; - if (GetDatabaseEncoding() != PG_UTF8) - { - char *convstr = pg_any_to_server(dst, len, PG_UTF8); - - if (convstr != dst) - { - strlcpy(dst, convstr, dstlen); - len = strlen(dst); - pfree(convstr); - } - } return len; } @@ -754,29 +738,29 @@ strftime_win32(char *dst, size_t dstlen, #define strftime(a,b,c,d) strftime_win32(a,b,c,d) #endif /* WIN32 */ -/* Subroutine for cache_locale_time(). */ +/* + * Subroutine for cache_locale_time(). + * Convert the given string from encoding "encoding" to the database + * encoding, and store the result at *dst, replacing any previous value. + */ static void -cache_single_time(char **dst, const char *format, const struct tm *tm) +cache_single_string(char **dst, const char *src, int encoding) { - char buf[MAX_L10N_DATA]; char *ptr; + char *olddst; - /* - * MAX_L10N_DATA is sufficient buffer space for every known locale, and - * POSIX defines no strftime() errors. (Buffer space exhaustion is not an - * error.) An implementation might report errors (e.g. ENOMEM) by - * returning 0 (or, less plausibly, a negative value) and setting errno. - * Report errno just in case the implementation did that, but clear it in - * advance of the call so we don't emit a stale, unrelated errno. - */ - errno = 0; - if (strftime(buf, MAX_L10N_DATA, format, tm) <= 0) - elog(ERROR, "strftime(%s) failed: %m", format); + /* Convert the string to the database encoding, or validate it's OK */ + ptr = pg_any_to_server(src, strlen(src), encoding); - ptr = MemoryContextStrdup(TopMemoryContext, buf); - if (*dst) - pfree(*dst); - *dst = ptr; + /* Store the string in long-lived storage, replacing any previous value */ + olddst = *dst; + *dst = MemoryContextStrdup(TopMemoryContext, ptr); + if (olddst) + pfree(olddst); + + /* Might as well clean up any palloc'd conversion result, too */ + if (ptr != src) + pfree(ptr); } /* @@ -785,11 +769,14 @@ cache_single_time(char **dst, const char *format, const struct tm *tm) void cache_locale_time(void) { - char *save_lc_time; + char buf[(2 * 7 + 2 * 12) * MAX_L10N_DATA]; + char *bufptr; time_t timenow; struct tm *timeinfo; + bool strftimefail = false; + int encoding; int i; - + char *save_lc_time; #ifdef WIN32 char *save_lc_ctype; #endif @@ -800,26 +787,33 @@ cache_locale_time(void) elog(DEBUG3, "cache_locale_time() executed; locale: \"%s\"", locale_time); - /* save user's value of time locale */ + /* + * As in PGLC_localeconv(), it's critical that we not throw error while + * libc's locale settings have nondefault values. Hence, we just call + * strftime() within the critical section, and then convert and save its + * results afterwards. + */ + + /* Save prevailing value of time locale */ save_lc_time = setlocale(LC_TIME, NULL); - if (save_lc_time) - save_lc_time = pstrdup(save_lc_time); + if (!save_lc_time) + elog(ERROR, "setlocale(NULL) failed"); + save_lc_time = pstrdup(save_lc_time); #ifdef WIN32 /* - * On WIN32, there is no way to get locale-specific time values in a - * specified locale, like we do for monetary/numeric. We can only get - * CP_ACP (see strftime_win32) or UTF16. Therefore, we get UTF16 and - * convert it to the database locale. However, wcsftime() internally uses - * LC_CTYPE, so we set it here. See the WIN32 comment near the top of - * PGLC_localeconv(). + * On Windows, it appears that wcsftime() internally uses LC_CTYPE, so we + * must set it here. This code looks the same as what PGLC_localeconv() + * does, but the underlying reason is different: this does NOT determine + * the encoding we'll get back from strftime_win32(). */ - /* save user's value of ctype locale */ + /* Save prevailing value of ctype locale */ save_lc_ctype = setlocale(LC_CTYPE, NULL); - if (save_lc_ctype) - save_lc_ctype = pstrdup(save_lc_ctype); + if (!save_lc_ctype) + elog(ERROR, "setlocale(NULL) failed"); + save_lc_ctype = pstrdup(save_lc_ctype); /* use lc_time to set the ctype */ setlocale(LC_CTYPE, locale_time); @@ -827,15 +821,33 @@ cache_locale_time(void) setlocale(LC_TIME, locale_time); + /* We use times close to current time as data for strftime(). */ timenow = time(NULL); timeinfo = localtime(&timenow); + /* Store the strftime results in MAX_L10N_DATA-sized portions of buf[] */ + bufptr = buf; + + /* + * MAX_L10N_DATA is sufficient buffer space for every known locale, and + * POSIX defines no strftime() errors. (Buffer space exhaustion is not an + * error.) An implementation might report errors (e.g. ENOMEM) by + * returning 0 (or, less plausibly, a negative value) and setting errno. + * Report errno just in case the implementation did that, but clear it in + * advance of the calls so we don't emit a stale, unrelated errno. + */ + errno = 0; + /* localized days */ for (i = 0; i < 7; i++) { timeinfo->tm_wday = i; - cache_single_time(&localized_abbrev_days[i], "%a", timeinfo); - cache_single_time(&localized_full_days[i], "%A", timeinfo); + if (strftime(bufptr, MAX_L10N_DATA, "%a", timeinfo) <= 0) + strftimefail = true; + bufptr += MAX_L10N_DATA; + if (strftime(bufptr, MAX_L10N_DATA, "%A", timeinfo) <= 0) + strftimefail = true; + bufptr += MAX_L10N_DATA; } /* localized months */ @@ -843,27 +855,78 @@ cache_locale_time(void) { timeinfo->tm_mon = i; timeinfo->tm_mday = 1; /* make sure we don't have invalid date */ - cache_single_time(&localized_abbrev_months[i], "%b", timeinfo); - cache_single_time(&localized_full_months[i], "%B", timeinfo); + if (strftime(bufptr, MAX_L10N_DATA, "%b", timeinfo) <= 0) + strftimefail = true; + bufptr += MAX_L10N_DATA; + if (strftime(bufptr, MAX_L10N_DATA, "%B", timeinfo) <= 0) + strftimefail = true; + bufptr += MAX_L10N_DATA; } - /* try to restore internal settings */ - if (save_lc_time) + /* + * Restore the prevailing locale settings; as in PGLC_localeconv(), + * failure to do so is fatal. + */ +#ifdef WIN32 + if (!setlocale(LC_CTYPE, save_lc_ctype)) + elog(FATAL, "failed to restore LC_CTYPE to \"%s\"", save_lc_ctype); +#endif + if (!setlocale(LC_TIME, save_lc_time)) + elog(FATAL, "failed to restore LC_TIME to \"%s\"", save_lc_time); + + /* + * At this point we've done our best to clean up, and can throw errors, or + * call functions that might throw errors, with a clean conscience. + */ + if (strftimefail) + elog(ERROR, "strftime() failed: %m"); + + /* Release the pstrdup'd locale names */ + pfree(save_lc_time); +#ifdef WIN32 + pfree(save_lc_ctype); +#endif + +#ifndef WIN32 + + /* + * As in PGLC_localeconv(), we must convert strftime()'s output from the + * encoding implied by LC_TIME to the database encoding. If we can't + * identify the LC_TIME encoding, just perform encoding validation. + */ + encoding = pg_get_encoding_from_locale(locale_time, true); + if (encoding < 0) + encoding = PG_SQL_ASCII; + +#else + + /* + * On Windows, strftime_win32() always returns UTF8 data, so convert from + * that if necessary. + */ + encoding = PG_UTF8; + +#endif /* WIN32 */ + + bufptr = buf; + + /* localized days */ + for (i = 0; i < 7; i++) { - if (!setlocale(LC_TIME, save_lc_time)) - elog(WARNING, "failed to restore old locale"); - pfree(save_lc_time); + cache_single_string(&localized_abbrev_days[i], bufptr, encoding); + bufptr += MAX_L10N_DATA; + cache_single_string(&localized_full_days[i], bufptr, encoding); + bufptr += MAX_L10N_DATA; } -#ifdef WIN32 - /* try to restore internal ctype settings */ - if (save_lc_ctype) + /* localized months */ + for (i = 0; i < 12; i++) { - if (!setlocale(LC_CTYPE, save_lc_ctype)) - elog(WARNING, "failed to restore old locale"); - pfree(save_lc_ctype); + cache_single_string(&localized_abbrev_months[i], bufptr, encoding); + bufptr += MAX_L10N_DATA; + cache_single_string(&localized_full_months[i], bufptr, encoding); + bufptr += MAX_L10N_DATA; } -#endif CurrentLCTimeValid = true; } @@ -1308,6 +1371,7 @@ pg_newlocale_from_collation(Oid collid) /* We'll fill in the result struct locally before allocating memory */ memset(&result, 0, sizeof(result)); result.provider = collform->collprovider; + result.deterministic = collform->collisdeterministic; if (collform->collprovider == COLLPROVIDER_LIBC) { @@ -1380,6 +1444,9 @@ pg_newlocale_from_collation(Oid collid) (errmsg("could not open collator for locale \"%s\": %s", collcollate, u_errorName(status)))); + if (U_ICU_VERSION_MAJOR_NUM < 54) + icu_set_collation_attributes(collator, collcollate); + /* We will leak this string if we get an error below :-( */ result.info.icu.locale = MemoryContextStrdup(TopMemoryContext, collcollate); @@ -1536,7 +1603,7 @@ icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes) buff, nbytes, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) ereport(ERROR, - (errmsg("ucnv_toUChars failed: %s", u_errorName(status)))); + (errmsg("%s failed: %s", "ucnv_toUChars", u_errorName(status)))); *buff_uchar = palloc((len_uchar + 1) * sizeof(**buff_uchar)); @@ -1545,7 +1612,7 @@ icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes) buff, nbytes, &status); if (U_FAILURE(status)) ereport(ERROR, - (errmsg("ucnv_toUChars failed: %s", u_errorName(status)))); + (errmsg("%s failed: %s", "ucnv_toUChars", u_errorName(status)))); return len_uchar; } @@ -1574,7 +1641,8 @@ icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar) buff_uchar, len_uchar, &status); if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR) ereport(ERROR, - (errmsg("ucnv_fromUChars failed: %s", u_errorName(status)))); + (errmsg("%s failed: %s", "ucnv_fromUChars", + u_errorName(status)))); *result = palloc(len_result + 1); @@ -1583,11 +1651,111 @@ icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar) buff_uchar, len_uchar, &status); if (U_FAILURE(status)) ereport(ERROR, - (errmsg("ucnv_fromUChars failed: %s", u_errorName(status)))); + (errmsg("%s failed: %s", "ucnv_fromUChars", + u_errorName(status)))); return len_result; } +/* + * Parse collation attributes and apply them to the open collator. This takes + * a string like "und@colStrength=primary;colCaseLevel=yes" and parses and + * applies the key-value arguments. + * + * Starting with ICU version 54, the attributes are processed automatically by + * ucol_open(), so this is only necessary for emulating this behavior on older + * versions. + */ +pg_attribute_unused() +static void +icu_set_collation_attributes(UCollator *collator, const char *loc) +{ + char *str = asc_tolower(loc, strlen(loc)); + + str = strchr(str, '@'); + if (!str) + return; + str++; + + for (char *token = strtok(str, ";"); token; token = strtok(NULL, ";")) + { + char *e = strchr(token, '='); + + if (e) + { + char *name; + char *value; + UColAttribute uattr; + UColAttributeValue uvalue; + UErrorCode status; + + status = U_ZERO_ERROR; + + *e = '\0'; + name = token; + value = e + 1; + + /* + * See attribute name and value lists in ICU i18n/coll.cpp + */ + if (strcmp(name, "colstrength") == 0) + uattr = UCOL_STRENGTH; + else if (strcmp(name, "colbackwards") == 0) + uattr = UCOL_FRENCH_COLLATION; + else if (strcmp(name, "colcaselevel") == 0) + uattr = UCOL_CASE_LEVEL; + else if (strcmp(name, "colcasefirst") == 0) + uattr = UCOL_CASE_FIRST; + else if (strcmp(name, "colalternate") == 0) + uattr = UCOL_ALTERNATE_HANDLING; + else if (strcmp(name, "colnormalization") == 0) + uattr = UCOL_NORMALIZATION_MODE; + else if (strcmp(name, "colnumeric") == 0) + uattr = UCOL_NUMERIC_COLLATION; + else + /* ignore if unknown */ + continue; + + if (strcmp(value, "primary") == 0) + uvalue = UCOL_PRIMARY; + else if (strcmp(value, "secondary") == 0) + uvalue = UCOL_SECONDARY; + else if (strcmp(value, "tertiary") == 0) + uvalue = UCOL_TERTIARY; + else if (strcmp(value, "quaternary") == 0) + uvalue = UCOL_QUATERNARY; + else if (strcmp(value, "identical") == 0) + uvalue = UCOL_IDENTICAL; + else if (strcmp(value, "no") == 0) + uvalue = UCOL_OFF; + else if (strcmp(value, "yes") == 0) + uvalue = UCOL_ON; + else if (strcmp(value, "shifted") == 0) + uvalue = UCOL_SHIFTED; + else if (strcmp(value, "non-ignorable") == 0) + uvalue = UCOL_NON_IGNORABLE; + else if (strcmp(value, "lower") == 0) + uvalue = UCOL_LOWER_FIRST; + else if (strcmp(value, "upper") == 0) + uvalue = UCOL_UPPER_FIRST; + else + status = U_ILLEGAL_ARGUMENT_ERROR; + + if (status == U_ZERO_ERROR) + ucol_setAttribute(collator, uattr, uvalue, &status); + + /* + * Pretend the error came from ucol_open(), for consistent error + * message across ICU versions. + */ + if (U_FAILURE(status)) + ereport(ERROR, + (errmsg("could not open collator for locale \"%s\": %s", + loc, u_errorName(status)))); + } + } +} + #endif /* USE_ICU */ /* @@ -1748,7 +1916,7 @@ char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, * error message by letting pg_verifymbstr check the string. But it's * possible that the string is OK to us, and not OK to mbstowcs --- * this suggests that the LC_CTYPE locale is different from the - * database encoding. Give a generic error message if verifymbstr + * database encoding. Give a generic error message if pg_verifymbstr * can't find anything wrong. */ pg_verifymbstr(from, fromlen, false); /* might not return */ diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c index f4eae9d83da..728892e7098 100644 --- a/src/backend/utils/adt/pg_lsn.c +++ b/src/backend/utils/adt/pg_lsn.c @@ -3,7 +3,7 @@ * pg_lsn.c * Operations for the pg_lsn datatype. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,7 +13,6 @@ */ #include "postgres.h" -#include "access/hash.h" #include "funcapi.h" #include "libpq/pqformat.h" #include "utils/builtins.h" @@ -26,35 +25,54 @@ * Formatting and conversion routines. *---------------------------------------------------------*/ -Datum -pg_lsn_in(PG_FUNCTION_ARGS) +XLogRecPtr +pg_lsn_in_internal(const char *str, bool *have_error) { - char *str = PG_GETARG_CSTRING(0); int len1, len2; uint32 id, off; XLogRecPtr result; + Assert(have_error != NULL); + *have_error = false; + /* Sanity check input format. */ len1 = strspn(str, "0123456789abcdefABCDEF"); if (len1 < 1 || len1 > MAXPG_LSNCOMPONENT || str[len1] != '/') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - "pg_lsn", str))); + { + *have_error = true; + return InvalidXLogRecPtr; + } len2 = strspn(str + len1 + 1, "0123456789abcdefABCDEF"); if (len2 < 1 || len2 > MAXPG_LSNCOMPONENT || str[len1 + 1 + len2] != '\0') - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type %s: \"%s\"", - "pg_lsn", str))); + { + *have_error = true; + return InvalidXLogRecPtr; + } /* Decode result. */ id = (uint32) strtoul(str, NULL, 16); off = (uint32) strtoul(str + len1 + 1, NULL, 16); result = ((uint64) id << 32) | off; + return result; +} + +Datum +pg_lsn_in(PG_FUNCTION_ARGS) +{ + char *str = PG_GETARG_CSTRING(0); + XLogRecPtr result; + bool have_error = false; + + result = pg_lsn_in_internal(str, &have_error); + if (have_error) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type %s: \"%s\"", + "pg_lsn", str))); + PG_RETURN_LSN(result); } @@ -156,6 +174,24 @@ pg_lsn_ge(PG_FUNCTION_ARGS) PG_RETURN_BOOL(lsn1 >= lsn2); } +Datum +pg_lsn_larger(PG_FUNCTION_ARGS) +{ + XLogRecPtr lsn1 = PG_GETARG_LSN(0); + XLogRecPtr lsn2 = PG_GETARG_LSN(1); + + PG_RETURN_LSN((lsn1 > lsn2) ? lsn1 : lsn2); +} + +Datum +pg_lsn_smaller(PG_FUNCTION_ARGS) +{ + XLogRecPtr lsn1 = PG_GETARG_LSN(0); + XLogRecPtr lsn2 = PG_GETARG_LSN(1); + + PG_RETURN_LSN((lsn1 < lsn2) ? lsn1 : lsn2); +} + /* btree index opclass support */ Datum pg_lsn_cmp(PG_FUNCTION_ARGS) diff --git a/src/backend/utils/adt/pg_upgrade_support.c b/src/backend/utils/adt/pg_upgrade_support.c index 0c54b02542f..99db5ba3894 100644 --- a/src/backend/utils/adt/pg_upgrade_support.c +++ b/src/backend/utils/adt/pg_upgrade_support.c @@ -5,13 +5,14 @@ * to control oid and relfilenode assignment, and do other special * hacks needed for pg_upgrade. * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/backend/utils/adt/pg_upgrade_support.c */ #include "postgres.h" #include "catalog/binary_upgrade.h" +#include "catalog/heap.h" #include "catalog/namespace.h" #include "catalog/pg_type.h" #include "commands/extension.h" @@ -192,3 +193,18 @@ binary_upgrade_set_record_init_privs(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +Datum +binary_upgrade_set_missing_value(PG_FUNCTION_ARGS) +{ + Oid table_id = PG_GETARG_OID(0); + text *attname = PG_GETARG_TEXT_P(1); + text *value = PG_GETARG_TEXT_P(2); + char *cattname = text_to_cstring(attname); + char *cvalue = text_to_cstring(value); + + CHECK_IS_BINARY_UPGRADE; + SetAttrMissing(table_id, cattname, cvalue); + + PG_RETURN_VOID(); +} diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c index 6110e40d3e1..05240bfd142 100644 --- a/src/backend/utils/adt/pgstatfuncs.c +++ b/src/backend/utils/adt/pgstatfuncs.c @@ -3,7 +3,7 @@ * pgstatfuncs.c * Functions for accessing the statistics collector data * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/xlog.h" #include "catalog/pg_authid.h" #include "catalog/pg_type.h" #include "common/ip.h" @@ -468,6 +469,10 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) /* Translate command name into command type code. */ if (pg_strcasecmp(cmd, "VACUUM") == 0) cmdtype = PROGRESS_COMMAND_VACUUM; + else if (pg_strcasecmp(cmd, "CLUSTER") == 0) + cmdtype = PROGRESS_COMMAND_CLUSTER; + else if (pg_strcasecmp(cmd, "CREATE INDEX") == 0) + cmdtype = PROGRESS_COMMAND_CREATE_INDEX; else ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -541,7 +546,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS) Datum pg_stat_get_activity(PG_FUNCTION_ARGS) { -#define PG_STAT_GET_ACTIVITY_COLS 24 +#define PG_STAT_GET_ACTIVITY_COLS 29 int num_backends = pgstat_fetch_stat_numbackends(); int curr_backend; int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0); @@ -645,21 +650,6 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) else nulls[16] = true; - if (beentry->st_ssl) - { - values[18] = BoolGetDatum(true); /* ssl */ - values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version); - values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher); - values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits); - values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression); - values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_clientdn); - } - else - { - values[18] = BoolGetDatum(false); /* ssl */ - nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = true; - } - /* Values only available to role member or pg_read_all_stats */ if (has_privs_of_role(GetUserId(), beentry->st_userid) || is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_STATS)) @@ -813,7 +803,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) */ nulls[12] = true; nulls[13] = true; - values[14] = DatumGetInt32(-1); + values[14] = Int32GetDatum(-1); } else { @@ -837,6 +827,54 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) else values[17] = CStringGetTextDatum(pgstat_get_backend_desc(beentry->st_backendType)); + + /* SSL information */ + if (beentry->st_ssl) + { + values[18] = BoolGetDatum(true); /* ssl */ + values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version); + values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher); + values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits); + values[22] = BoolGetDatum(beentry->st_sslstatus->ssl_compression); + + if (beentry->st_sslstatus->ssl_client_dn[0]) + values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn); + else + nulls[23] = true; + + if (beentry->st_sslstatus->ssl_client_serial[0]) + values[24] = DirectFunctionCall3(numeric_in, + CStringGetDatum(beentry->st_sslstatus->ssl_client_serial), + ObjectIdGetDatum(InvalidOid), + Int32GetDatum(-1)); + else + nulls[24] = true; + + if (beentry->st_sslstatus->ssl_issuer_dn[0]) + values[25] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn); + else + nulls[25] = true; + } + else + { + values[18] = BoolGetDatum(false); /* ssl */ + nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = true; + } + + /* GSSAPI information */ + if (beentry->st_gss) + { + values[26] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */ + values[27] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ); + values[28] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */ + } + else + { + values[26] = BoolGetDatum(false); /* gss_auth */ + nulls[27] = true; /* No GSS principal */ + values[28] = BoolGetDatum(false); /* GSS Encryption not in + * use */ + } } else { @@ -853,6 +891,17 @@ pg_stat_get_activity(PG_FUNCTION_ARGS) nulls[13] = true; nulls[14] = true; nulls[17] = true; + nulls[18] = true; + nulls[19] = true; + nulls[20] = true; + nulls[21] = true; + nulls[22] = true; + nulls[23] = true; + nulls[24] = true; + nulls[25] = true; + nulls[26] = true; + nulls[27] = true; + nulls[28] = true; } tuplestore_putvalues(tupstore, tupdesc, values, nulls); @@ -1471,6 +1520,45 @@ pg_stat_get_db_deadlocks(PG_FUNCTION_ARGS) PG_RETURN_INT64(result); } +Datum +pg_stat_get_db_checksum_failures(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + int64 result; + PgStat_StatDBEntry *dbentry; + + if (!DataChecksumsEnabled()) + PG_RETURN_NULL(); + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = (int64) (dbentry->n_checksum_failures); + + PG_RETURN_INT64(result); +} + +Datum +pg_stat_get_db_checksum_last_failure(PG_FUNCTION_ARGS) +{ + Oid dbid = PG_GETARG_OID(0); + TimestampTz result; + PgStat_StatDBEntry *dbentry; + + if (!DataChecksumsEnabled()) + PG_RETURN_NULL(); + + if ((dbentry = pgstat_fetch_stat_dbentry(dbid)) == NULL) + result = 0; + else + result = dbentry->last_checksum_failure; + + if (result == 0) + PG_RETURN_NULL(); + else + PG_RETURN_TIMESTAMPTZ(result); +} + Datum pg_stat_get_db_blk_read_time(PG_FUNCTION_ARGS) { @@ -1829,7 +1917,7 @@ pg_stat_get_archiver(PG_FUNCTION_ARGS) MemSet(nulls, 0, sizeof(nulls)); /* Initialise attributes information in the tuple descriptor */ - tupdesc = CreateTemplateTupleDesc(7, false); + tupdesc = CreateTemplateTupleDesc(7); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count", INT8OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal", diff --git a/src/backend/utils/adt/pseudotypes.c b/src/backend/utils/adt/pseudotypes.c index dbe67cdb4cb..5c886cfe963 100644 --- a/src/backend/utils/adt/pseudotypes.c +++ b/src/backend/utils/adt/pseudotypes.c @@ -11,7 +11,7 @@ * we do better?) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -418,3 +418,4 @@ PSEUDOTYPE_DUMMY_IO_FUNCS(internal); PSEUDOTYPE_DUMMY_IO_FUNCS(opaque); PSEUDOTYPE_DUMMY_IO_FUNCS(anyelement); PSEUDOTYPE_DUMMY_IO_FUNCS(anynonarray); +PSEUDOTYPE_DUMMY_IO_FUNCS(table_am_handler); diff --git a/src/backend/utils/adt/quote.c b/src/backend/utils/adt/quote.c index 699ca4a4196..5bfa327d50a 100644 --- a/src/backend/utils/adt/quote.c +++ b/src/backend/utils/adt/quote.c @@ -3,7 +3,7 @@ * quote.c * Functions for quoting identifiers and literals * - * Portions Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index 5a5d0a0b8fc..e5c7e5c7eea 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -19,7 +19,7 @@ * value; we must detoast it first. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,12 +30,13 @@ */ #include "postgres.h" -#include "access/hash.h" +#include "access/tupmacs.h" #include "lib/stringinfo.h" #include "libpq/pqformat.h" #include "miscadmin.h" #include "utils/builtins.h" #include "utils/date.h" +#include "utils/hashutils.h" #include "utils/int8.h" #include "utils/lsyscache.h" #include "utils/rangetypes.h" @@ -55,19 +56,19 @@ typedef struct RangeIOData static RangeIOData *get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, - IOFuncSelector func); + IOFuncSelector func); static char range_parse_flags(const char *flags_str); static void range_parse(const char *input_str, char *flags, char **lbound_str, - char **ubound_str); + char **ubound_str); static const char *range_parse_bound(const char *string, const char *ptr, - char **bound_str, bool *infinite); + char **bound_str, bool *infinite); static char *range_deparse(char flags, const char *lbound_str, - const char *ubound_str); + const char *ubound_str); static char *range_bound_escape(const char *value); static Size datum_compute_size(Size sz, Datum datum, bool typbyval, - char typalign, int16 typlen, char typstorage); + char typalign, int16 typlen, char typstorage); static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, - char typalign, int16 typlen, char typstorage); + char typalign, int16 typlen, char typstorage); /* @@ -1430,13 +1431,15 @@ daterange_canonical(PG_FUNCTION_ARGS) if (empty) PG_RETURN_RANGE_P(r); - if (!lower.infinite && !lower.inclusive) + if (!lower.infinite && !DATE_NOT_FINITE(DatumGetDateADT(lower.val)) && + !lower.inclusive) { lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1)); lower.inclusive = true; } - if (!upper.infinite && upper.inclusive) + if (!upper.infinite && !DATE_NOT_FINITE(DatumGetDateADT(upper.val)) && + upper.inclusive) { upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1)); upper.inclusive = false; diff --git a/src/backend/utils/adt/rangetypes_gist.c b/src/backend/utils/adt/rangetypes_gist.c index 2fe61043d98..6f93ce64dab 100644 --- a/src/backend/utils/adt/rangetypes_gist.c +++ b/src/backend/utils/adt/rangetypes_gist.c @@ -3,7 +3,7 @@ * rangetypes_gist.c * GiST support for range types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,7 +16,8 @@ #include "access/gist.h" #include "access/stratnum.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" #include "utils/datum.h" #include "utils/rangetypes.h" @@ -134,37 +135,37 @@ typedef struct false, -1))) static RangeType *range_super_union(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); static bool range_gist_consistent_int(TypeCacheEntry *typcache, - StrategyNumber strategy, RangeType *key, - Datum query); + StrategyNumber strategy, RangeType *key, + Datum query); static bool range_gist_consistent_leaf(TypeCacheEntry *typcache, - StrategyNumber strategy, RangeType *key, - Datum query); + StrategyNumber strategy, RangeType *key, + Datum query); static void range_gist_fallback_split(TypeCacheEntry *typcache, - GistEntryVector *entryvec, - GIST_SPLITVEC *v); + GistEntryVector *entryvec, + GIST_SPLITVEC *v); static void range_gist_class_split(TypeCacheEntry *typcache, - GistEntryVector *entryvec, - GIST_SPLITVEC *v, - SplitLR *classes_groups); + GistEntryVector *entryvec, + GIST_SPLITVEC *v, + SplitLR *classes_groups); static void range_gist_single_sorting_split(TypeCacheEntry *typcache, - GistEntryVector *entryvec, - GIST_SPLITVEC *v, - bool use_upper_bound); + GistEntryVector *entryvec, + GIST_SPLITVEC *v, + bool use_upper_bound); static void range_gist_double_sorting_split(TypeCacheEntry *typcache, - GistEntryVector *entryvec, - GIST_SPLITVEC *v); + GistEntryVector *entryvec, + GIST_SPLITVEC *v); static void range_gist_consider_split(ConsiderSplitContext *context, - RangeBound *right_lower, int min_left_count, - RangeBound *left_upper, int max_left_count); + RangeBound *right_lower, int min_left_count, + RangeBound *left_upper, int max_left_count); static int get_gist_range_class(RangeType *range); static int single_bound_cmp(const void *a, const void *b, void *arg); static int interval_cmp_lower(const void *a, const void *b, void *arg); static int interval_cmp_upper(const void *a, const void *b, void *arg); static int common_entry_cmp(const void *i1, const void *i2); static float8 call_subtype_diff(TypeCacheEntry *typcache, - Datum val1, Datum val2); + Datum val1, Datum val2); /* GiST query consistency check */ diff --git a/src/backend/utils/adt/rangetypes_selfuncs.c b/src/backend/utils/adt/rangetypes_selfuncs.c index 59761ecf342..640c7f0bc6a 100644 --- a/src/backend/utils/adt/rangetypes_selfuncs.c +++ b/src/backend/utils/adt/rangetypes_selfuncs.c @@ -6,7 +6,7 @@ * Estimates are based on histograms of lower and upper bounds, and the * fraction of empty ranges. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,45 +17,48 @@ */ #include "postgres.h" +#include + #include "access/htup_details.h" #include "catalog/pg_operator.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" #include "utils/lsyscache.h" #include "utils/rangetypes.h" #include "utils/selfuncs.h" #include "utils/typcache.h" static double calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata, - RangeType *constval, Oid operator); + RangeType *constval, Oid operator); static double default_range_selectivity(Oid operator); static double calc_hist_selectivity(TypeCacheEntry *typcache, - VariableStatData *vardata, RangeType *constval, - Oid operator); + VariableStatData *vardata, RangeType *constval, + Oid operator); static double calc_hist_selectivity_scalar(TypeCacheEntry *typcache, - RangeBound *constbound, - RangeBound *hist, int hist_nvalues, - bool equal); -static int rbound_bsearch(TypeCacheEntry *typcache, RangeBound *value, - RangeBound *hist, int hist_length, bool equal); + RangeBound *constbound, + RangeBound *hist, int hist_nvalues, + bool equal); +static int rbound_bsearch(TypeCacheEntry *typcache, RangeBound *value, + RangeBound *hist, int hist_length, bool equal); static float8 get_position(TypeCacheEntry *typcache, RangeBound *value, - RangeBound *hist1, RangeBound *hist2); + RangeBound *hist1, RangeBound *hist2); static float8 get_len_position(double value, double hist1, double hist2); static float8 get_distance(TypeCacheEntry *typcache, RangeBound *bound1, - RangeBound *bound2); -static int length_hist_bsearch(Datum *length_hist_values, - int length_hist_nvalues, double value, bool equal); + RangeBound *bound2); +static int length_hist_bsearch(Datum *length_hist_values, + int length_hist_nvalues, double value, bool equal); static double calc_length_hist_frac(Datum *length_hist_values, - int length_hist_nvalues, double length1, double length2, bool equal); + int length_hist_nvalues, double length1, double length2, bool equal); static double calc_hist_selectivity_contained(TypeCacheEntry *typcache, - RangeBound *lower, RangeBound *upper, - RangeBound *hist_lower, int hist_nvalues, - Datum *length_hist_values, int length_hist_nvalues); + RangeBound *lower, RangeBound *upper, + RangeBound *hist_lower, int hist_nvalues, + Datum *length_hist_values, int length_hist_nvalues); static double calc_hist_selectivity_contains(TypeCacheEntry *typcache, - RangeBound *lower, RangeBound *upper, - RangeBound *hist_lower, int hist_nvalues, - Datum *length_hist_values, int length_hist_nvalues); + RangeBound *lower, RangeBound *upper, + RangeBound *hist_lower, int hist_nvalues, + Datum *length_hist_values, int length_hist_nvalues); /* * Returns a default selectivity estimate for given operator, when we don't @@ -749,19 +752,19 @@ get_position(TypeCacheEntry *typcache, RangeBound *value, RangeBound *hist1, static double get_len_position(double value, double hist1, double hist2) { - if (!is_infinite(hist1) && !is_infinite(hist2)) + if (!isinf(hist1) && !isinf(hist2)) { /* * Both bounds are finite. The value should be finite too, because it * lies somewhere between the bounds. If it doesn't, just return * something. */ - if (is_infinite(value)) + if (isinf(value)) return 0.5; return 1.0 - (hist2 - value) / (hist2 - hist1); } - else if (is_infinite(hist1) && !is_infinite(hist2)) + else if (isinf(hist1) && !isinf(hist2)) { /* * Lower bin boundary is -infinite, upper is finite. Return 1.0 to @@ -769,7 +772,7 @@ get_len_position(double value, double hist1, double hist2) */ return 1.0; } - else if (is_infinite(hist1) && is_infinite(hist2)) + else if (isinf(hist1) && isinf(hist2)) { /* same as above, but in reverse */ return 0.0; @@ -850,7 +853,7 @@ calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, return 0.0; /* shouldn't happen, but doesn't hurt to check */ /* All lengths in the table are <= infinite. */ - if (is_infinite(length2) && equal) + if (isinf(length2) && equal) return 1.0; /*---------- @@ -977,7 +980,7 @@ calc_length_hist_frac(Datum *length_hist_values, int length_hist_nvalues, * length2 is infinite. It's not clear what the correct value would be in * that case, so 0.5 seems as good as any value. */ - if (is_infinite(area) && is_infinite(length2)) + if (isinf(area) && isinf(length2)) frac = 0.5; else frac = area / (length2 - length1); diff --git a/src/backend/utils/adt/rangetypes_spgist.c b/src/backend/utils/adt/rangetypes_spgist.c index a7898c43667..8bb730ce8e5 100644 --- a/src/backend/utils/adt/rangetypes_spgist.c +++ b/src/backend/utils/adt/rangetypes_spgist.c @@ -25,7 +25,7 @@ * This implementation only uses the comparison function of the range element * datatype, therefore it works for any range type. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -44,14 +44,14 @@ #include "utils/rangetypes.h" static int16 getQuadrant(TypeCacheEntry *typcache, RangeType *centroid, - RangeType *tst); + RangeType *tst); static int bound_cmp(const void *a, const void *b, void *arg); -static int adjacent_inner_consistent(TypeCacheEntry *typcache, - RangeBound *arg, RangeBound *centroid, - RangeBound *prev); -static int adjacent_cmp_bounds(TypeCacheEntry *typcache, RangeBound *arg, - RangeBound *centroid); +static int adjacent_inner_consistent(TypeCacheEntry *typcache, + RangeBound *arg, RangeBound *centroid, + RangeBound *prev); +static int adjacent_cmp_bounds(TypeCacheEntry *typcache, RangeBound *arg, + RangeBound *centroid); /* * SP-GiST 'config' interface function. diff --git a/src/backend/utils/adt/rangetypes_typanalyze.c b/src/backend/utils/adt/rangetypes_typanalyze.c index f2c11f54bc4..d01d3032cca 100644 --- a/src/backend/utils/adt/rangetypes_typanalyze.c +++ b/src/backend/utils/adt/rangetypes_typanalyze.c @@ -1,6 +1,6 @@ /*------------------------------------------------------------------------- * - * ragetypes_typanalyze.c + * rangetypes_typanalyze.c * Functions for gathering statistics from range columns * * For a range type column, histograms of lower and upper bounds, and @@ -13,7 +13,7 @@ * come from different tuples. In theory, the standard scalar selectivity * functions could be used with the combined histogram. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -26,14 +26,15 @@ #include "catalog/pg_operator.h" #include "commands/vacuum.h" -#include "utils/builtins.h" +#include "utils/float.h" +#include "utils/fmgrprotos.h" #include "utils/lsyscache.h" #include "utils/rangetypes.h" static int float8_qsort_cmp(const void *a1, const void *a2); static int range_bound_qsort_cmp(const void *a1, const void *a2, void *arg); static void compute_range_stats(VacAttrStats *stats, - AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows); + AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows); /* * range_typanalyze -- typanalyze function for range columns @@ -319,6 +320,7 @@ compute_range_stats(VacAttrStats *stats, AnalyzeAttrFetchFunc fetchfunc, num_hist = 0; } stats->staop[slot_idx] = Float8LessOperator; + stats->stacoll[slot_idx] = InvalidOid; stats->stavalues[slot_idx] = length_hist_values; stats->numvalues[slot_idx] = num_hist; stats->statypid[slot_idx] = FLOAT8OID; diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c index 5025a449fb3..3d38aef820c 100644 --- a/src/backend/utils/adt/regexp.c +++ b/src/backend/utils/adt/regexp.c @@ -3,7 +3,7 @@ * regexp.c * Postgres' interface to the regular expression package. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -35,6 +35,7 @@ #include "regex/regex.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/memutils.h" #include "utils/varlena.h" #define PG_GETARG_TEXT_PP_IF_EXISTS(_n) \ @@ -61,6 +62,9 @@ typedef struct regexp_matches_ctx /* workspace for build_regexp_match_result() */ Datum *elems; /* has npatterns elements */ bool *nulls; /* has npatterns elements */ + pg_wchar *wide_str; /* wide-char version of original string */ + char *conv_buf; /* conversion buffer */ + int conv_bufsiz; /* size thereof */ } regexp_matches_ctx; /* @@ -108,11 +112,11 @@ static cached_re_str re_array[MAX_CACHED_RES]; /* cached re's */ /* Local functions */ static regexp_matches_ctx *setup_regexp_matches(text *orig_str, text *pattern, - pg_re_flags *flags, - Oid collation, - bool use_subpatterns, - bool ignore_degenerate); -static void cleanup_regexp_matches(regexp_matches_ctx *matchctx); + pg_re_flags *flags, + Oid collation, + bool use_subpatterns, + bool ignore_degenerate, + bool fetching_unmatched); static ArrayType *build_regexp_match_result(regexp_matches_ctx *matchctx); static Datum build_regexp_split_result(regexp_matches_ctx *splitctx); @@ -129,7 +133,7 @@ static Datum build_regexp_split_result(regexp_matches_ctx *splitctx); * Pattern is given in the database encoding. We internally convert to * an array of pg_wchar, which is what Spencer's regex package wants. */ -static regex_t * +regex_t * RE_compile_and_cache(text *text_re, int cflags, Oid collation) { int text_re_len = VARSIZE_ANY_EXHDR(text_re); @@ -335,7 +339,7 @@ RE_execute(regex_t *re, char *dat, int dat_len, * Both pattern and data are given in the database encoding. We internally * convert to array of pg_wchar which is what Spencer's regex package wants. */ -static bool +bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, int cflags, Oid collation, int nmatch, regmatch_t *pmatch) @@ -419,7 +423,7 @@ parse_re_flags(pg_re_flags *flags, text *opts) default: ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid regexp option: \"%c\"", + errmsg("invalid regular expression option: \"%c\"", opt_p[i]))); break; } @@ -650,15 +654,18 @@ textregexreplace(PG_FUNCTION_ARGS) } /* - * similar_escape() - * Convert a SQL:2008 regexp pattern to POSIX style, so it can be used by - * our regexp engine. + * similar_to_escape(), similar_escape() + * + * Convert a SQL "SIMILAR TO" regexp pattern to POSIX style, so it can be + * used by our regexp engine. + * + * similar_escape_internal() is the common workhorse for three SQL-exposed + * functions. esc_text can be passed as NULL to select the default escape + * (which is '\'), or as an empty string to select no escape character. */ -Datum -similar_escape(PG_FUNCTION_ARGS) +static text * +similar_escape_internal(text *pat_text, text *esc_text) { - text *pat_text; - text *esc_text; text *result; char *p, *e, @@ -669,13 +676,9 @@ similar_escape(PG_FUNCTION_ARGS) bool incharclass = false; int nquotes = 0; - /* This function is not strict, so must test explicitly */ - if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); - pat_text = PG_GETARG_TEXT_PP(0); p = VARDATA_ANY(pat_text); plen = VARSIZE_ANY_EXHDR(pat_text); - if (PG_ARGISNULL(1)) + if (esc_text == NULL) { /* No ESCAPE clause provided; default to backslash as escape */ e = "\\"; @@ -683,12 +686,11 @@ similar_escape(PG_FUNCTION_ARGS) } else { - esc_text = PG_GETARG_TEXT_PP(1); e = VARDATA_ANY(esc_text); elen = VARSIZE_ANY_EXHDR(esc_text); if (elen == 0) e = NULL; /* no escape character */ - else + else if (elen > 1) { int escape_mblen = pg_mbstrlen_with_len(e, elen); @@ -704,20 +706,42 @@ similar_escape(PG_FUNCTION_ARGS) * We surround the transformed input string with * ^(?: ... )$ * which requires some explanation. We need "^" and "$" to force - * the pattern to match the entire input string as per SQL99 spec. + * the pattern to match the entire input string as per the SQL spec. * The "(?:" and ")" are a non-capturing set of parens; we have to have * parens in case the string contains "|", else the "^" and "$" will * be bound into the first and last alternatives which is not what we * want, and the parens must be non capturing because we don't want them * to count when selecting output for SUBSTRING. + * + * When the pattern is divided into three parts by escape-double-quotes, + * what we emit is + * ^(?:part1){1,1}?(part2){1,1}(?:part3)$ + * which requires even more explanation. The "{1,1}?" on part1 makes it + * non-greedy so that it will match the smallest possible amount of text + * not the largest, as required by SQL. The plain parens around part2 + * are capturing parens so that that part is what controls the result of + * SUBSTRING. The "{1,1}" forces part2 to be greedy, so that it matches + * the largest possible amount of text; hence part3 must match the + * smallest amount of text, as required by SQL. We don't need an explicit + * greediness marker on part3. Note that this also confines the effects + * of any "|" characters to the respective part, which is what we want. + * + * The SQL spec says that SUBSTRING's pattern must contain exactly two + * escape-double-quotes, but we only complain if there's more than two. + * With none, we act as though part1 and part3 are empty; with one, we + * act as though part3 is empty. Both behaviors fall out of omitting + * the relevant part separators in the above expansion. If the result + * of this function is used in a plain regexp match (SIMILAR TO), the + * escape-double-quotes have no effect on the match behavior. *---------- */ /* - * We need room for the prefix/postfix plus as many as 3 output bytes per - * input byte; since the input is at most 1GB this can't overflow + * We need room for the prefix/postfix and part separators, plus as many + * as 3 output bytes per input byte; since the input is at most 1GB this + * can't overflow size_t. */ - result = (text *) palloc(VARHDRSZ + 6 + 3 * plen); + result = (text *) palloc(VARHDRSZ + 23 + 3 * (size_t) plen); r = VARDATA(result); *r++ = '^'; @@ -756,7 +780,7 @@ similar_escape(PG_FUNCTION_ARGS) } else if (e && elen == mblen && memcmp(e, p, mblen) == 0) { - /* SQL99 escape character; do not send to output */ + /* SQL escape character; do not send to output */ afterescape = true; } else @@ -780,10 +804,45 @@ similar_escape(PG_FUNCTION_ARGS) /* fast path */ if (afterescape) { - if (pchar == '"' && !incharclass) /* for SUBSTRING patterns */ - *r++ = ((nquotes++ % 2) == 0) ? '(' : ')'; + if (pchar == '"' && !incharclass) /* escape-double-quote? */ + { + /* emit appropriate part separator, per notes above */ + if (nquotes == 0) + { + *r++ = ')'; + *r++ = '{'; + *r++ = '1'; + *r++ = ','; + *r++ = '1'; + *r++ = '}'; + *r++ = '?'; + *r++ = '('; + } + else if (nquotes == 1) + { + *r++ = ')'; + *r++ = '{'; + *r++ = '1'; + *r++ = ','; + *r++ = '1'; + *r++ = '}'; + *r++ = '('; + *r++ = '?'; + *r++ = ':'; + } + else + ereport(ERROR, + (errcode(ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER), + errmsg("SQL regular expression may not contain more than two escape-double-quote separators"))); + nquotes++; + } else { + /* + * We allow any character at all to be escaped; notably, this + * allows access to POSIX character-class escapes such as + * "\d". The SQL spec is considerably more restrictive. + */ *r++ = '\\'; *r++ = pchar; } @@ -791,7 +850,7 @@ similar_escape(PG_FUNCTION_ARGS) } else if (e && pchar == *e) { - /* SQL99 escape character; do not send to output */ + /* SQL escape character; do not send to output */ afterescape = true; } else if (incharclass) @@ -837,6 +896,65 @@ similar_escape(PG_FUNCTION_ARGS) SET_VARSIZE(result, r - ((char *) result)); + return result; +} + +/* + * similar_to_escape(pattern, escape) + */ +Datum +similar_to_escape_2(PG_FUNCTION_ARGS) +{ + text *pat_text = PG_GETARG_TEXT_PP(0); + text *esc_text = PG_GETARG_TEXT_PP(1); + text *result; + + result = similar_escape_internal(pat_text, esc_text); + + PG_RETURN_TEXT_P(result); +} + +/* + * similar_to_escape(pattern) + * Inserts a default escape character. + */ +Datum +similar_to_escape_1(PG_FUNCTION_ARGS) +{ + text *pat_text = PG_GETARG_TEXT_PP(0); + text *result; + + result = similar_escape_internal(pat_text, NULL); + + PG_RETURN_TEXT_P(result); +} + +/* + * similar_escape(pattern, escape) + * + * Legacy function for compatibility with views stored using the + * pre-v13 expansion of SIMILAR TO. Unlike the above functions, this + * is non-strict, which leads to not-per-spec handling of "ESCAPE NULL". + */ +Datum +similar_escape(PG_FUNCTION_ARGS) +{ + text *pat_text; + text *esc_text; + text *result; + + /* This function is not strict, so must test explicitly */ + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + pat_text = PG_GETARG_TEXT_PP(0); + + if (PG_ARGISNULL(1)) + esc_text = NULL; /* use default escape character */ + else + esc_text = PG_GETARG_TEXT_PP(1); + + result = similar_escape_internal(pat_text, esc_text); + PG_RETURN_TEXT_P(result); } @@ -859,11 +977,13 @@ regexp_match(PG_FUNCTION_ARGS) if (re_flags.glob) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("regexp_match does not support the global option"), + /* translator: %s is a SQL function name */ + errmsg("%s does not support the \"global\" option", + "regexp_match()"), errhint("Use the regexp_matches function instead."))); matchctx = setup_regexp_matches(orig_str, pattern, &re_flags, - PG_GET_COLLATION(), true, false); + PG_GET_COLLATION(), true, false, false); if (matchctx->nmatches == 0) PG_RETURN_NULL(); @@ -911,7 +1031,7 @@ regexp_matches(PG_FUNCTION_ARGS) matchctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern, &re_flags, PG_GET_COLLATION(), - true, false); + true, false, false); /* Pre-create workspace that build_regexp_match_result needs */ matchctx->elems = (Datum *) palloc(sizeof(Datum) * matchctx->npatterns); @@ -933,9 +1053,6 @@ regexp_matches(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, PointerGetDatum(result_ary)); } - /* release space in multi-call ctx to avoid intraquery memory leak */ - cleanup_regexp_matches(matchctx); - SRF_RETURN_DONE(funcctx); } @@ -954,17 +1071,24 @@ regexp_matches_no_flags(PG_FUNCTION_ARGS) * all the matching in one swoop. The returned regexp_matches_ctx contains * the locations of all the substrings matching the pattern. * - * The two bool parameters have only two patterns (one for matching, one for + * The three bool parameters have only two patterns (one for matching, one for * splitting) but it seems clearer to distinguish the functionality this way - * than to key it all off one "is_split" flag. + * than to key it all off one "is_split" flag. We don't currently assume that + * fetching_unmatched is exclusive of fetching the matched text too; if it's + * set, the conversion buffer is large enough to fetch any single matched or + * unmatched string, but not any larger substring. (In practice, when splitting + * the matches are usually small anyway, and it didn't seem worth complicating + * the code further.) */ static regexp_matches_ctx * setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, Oid collation, bool use_subpatterns, - bool ignore_degenerate) + bool ignore_degenerate, + bool fetching_unmatched) { regexp_matches_ctx *matchctx = palloc0(sizeof(regexp_matches_ctx)); + int eml = pg_database_encoding_max_length(); int orig_len; pg_wchar *wide_str; int wide_len; @@ -974,7 +1098,9 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, int array_len; int array_idx; int prev_match_end; + int prev_valid_match_end; int start_search; + int maxlen = 0; /* largest fetch length in characters */ /* save original string --- we'll extract result substrings from it */ matchctx->orig_str = orig_str; @@ -1003,13 +1129,19 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, /* temporary output space for RE package */ pmatch = palloc(sizeof(regmatch_t) * pmatch_len); - /* the real output space (grown dynamically if needed) */ - array_len = re_flags->glob ? 256 : 32; + /* + * the real output space (grown dynamically if needed) + * + * use values 2^n-1, not 2^n, so that we hit the limit at 2^28-1 rather + * than at 2^27 + */ + array_len = re_flags->glob ? 255 : 31; matchctx->match_locs = (int *) palloc(sizeof(int) * array_len); array_idx = 0; /* search for the pattern, perhaps repeatedly */ prev_match_end = 0; + prev_valid_match_end = 0; start_search = 0; while (RE_wchar_execute(cpattern, wide_str, wide_len, start_search, pmatch_len, pmatch)) @@ -1024,9 +1156,13 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, pmatch[0].rm_eo > prev_match_end)) { /* enlarge output space if needed */ - while (array_idx + matchctx->npatterns * 2 > array_len) + while (array_idx + matchctx->npatterns * 2 + 1 > array_len) { - array_len *= 2; + array_len += array_len + 1; /* 2^n-1 => 2^(n+1)-1 */ + if (array_len > MaxAllocSize / sizeof(int)) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("too many regular expression matches"))); matchctx->match_locs = (int *) repalloc(matchctx->match_locs, sizeof(int) * array_len); } @@ -1038,16 +1174,37 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, for (i = 1; i <= matchctx->npatterns; i++) { - matchctx->match_locs[array_idx++] = pmatch[i].rm_so; - matchctx->match_locs[array_idx++] = pmatch[i].rm_eo; + int so = pmatch[i].rm_so; + int eo = pmatch[i].rm_eo; + + matchctx->match_locs[array_idx++] = so; + matchctx->match_locs[array_idx++] = eo; + if (so >= 0 && eo >= 0 && (eo - so) > maxlen) + maxlen = (eo - so); } } else { - matchctx->match_locs[array_idx++] = pmatch[0].rm_so; - matchctx->match_locs[array_idx++] = pmatch[0].rm_eo; + int so = pmatch[0].rm_so; + int eo = pmatch[0].rm_eo; + + matchctx->match_locs[array_idx++] = so; + matchctx->match_locs[array_idx++] = eo; + if (so >= 0 && eo >= 0 && (eo - so) > maxlen) + maxlen = (eo - so); } matchctx->nmatches++; + + /* + * check length of unmatched portion between end of previous valid + * (nondegenerate, or degenerate but not ignored) match and start + * of current one + */ + if (fetching_unmatched && + pmatch[0].rm_so >= 0 && + (pmatch[0].rm_so - prev_valid_match_end) > maxlen) + maxlen = (pmatch[0].rm_so - prev_valid_match_end); + prev_valid_match_end = pmatch[0].rm_eo; } prev_match_end = pmatch[0].rm_eo; @@ -1068,34 +1225,67 @@ setup_regexp_matches(text *orig_str, text *pattern, pg_re_flags *re_flags, break; } + /* + * check length of unmatched portion between end of last match and end of + * input string + */ + if (fetching_unmatched && + (wide_len - prev_valid_match_end) > maxlen) + maxlen = (wide_len - prev_valid_match_end); + + /* + * Keep a note of the end position of the string for the benefit of + * splitting code. + */ + matchctx->match_locs[array_idx] = wide_len; + + if (eml > 1) + { + int64 maxsiz = eml * (int64) maxlen; + int conv_bufsiz; + + /* + * Make the conversion buffer large enough for any substring of + * interest. + * + * Worst case: assume we need the maximum size (maxlen*eml), but take + * advantage of the fact that the original string length in bytes is + * an upper bound on the byte length of any fetched substring (and we + * know that len+1 is safe to allocate because the varlena header is + * longer than 1 byte). + */ + if (maxsiz > orig_len) + conv_bufsiz = orig_len + 1; + else + conv_bufsiz = maxsiz + 1; /* safe since maxsiz < 2^30 */ + + matchctx->conv_buf = palloc(conv_bufsiz); + matchctx->conv_bufsiz = conv_bufsiz; + matchctx->wide_str = wide_str; + } + else + { + /* No need to keep the wide string if we're in a single-byte charset. */ + pfree(wide_str); + matchctx->wide_str = NULL; + matchctx->conv_buf = NULL; + matchctx->conv_bufsiz = 0; + } + /* Clean up temp storage */ - pfree(wide_str); pfree(pmatch); return matchctx; } -/* - * cleanup_regexp_matches - release memory of a regexp_matches_ctx - */ -static void -cleanup_regexp_matches(regexp_matches_ctx *matchctx) -{ - pfree(matchctx->orig_str); - pfree(matchctx->match_locs); - if (matchctx->elems) - pfree(matchctx->elems); - if (matchctx->nulls) - pfree(matchctx->nulls); - pfree(matchctx); -} - /* * build_regexp_match_result - build output array for current match */ static ArrayType * build_regexp_match_result(regexp_matches_ctx *matchctx) { + char *buf = matchctx->conv_buf; + int bufsiz PG_USED_FOR_ASSERTS_ONLY = matchctx->conv_bufsiz; Datum *elems = matchctx->elems; bool *nulls = matchctx->nulls; int dims[1]; @@ -1115,6 +1305,16 @@ build_regexp_match_result(regexp_matches_ctx *matchctx) elems[i] = (Datum) 0; nulls[i] = true; } + else if (buf) + { + int len = pg_wchar2mb_with_len(matchctx->wide_str + so, + buf, + eo - so); + + Assert(len < bufsiz); + elems[i] = PointerGetDatum(cstring_to_text_with_len(buf, len)); + nulls[i] = false; + } else { elems[i] = DirectFunctionCall3(text_substr, @@ -1160,7 +1360,9 @@ regexp_split_to_table(PG_FUNCTION_ARGS) if (re_flags.glob) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("regexp_split_to_table does not support the global option"))); + /* translator: %s is a SQL function name */ + errmsg("%s does not support the \"global\" option", + "regexp_split_to_table()"))); /* But we find all the matches anyway */ re_flags.glob = true; @@ -1168,7 +1370,7 @@ regexp_split_to_table(PG_FUNCTION_ARGS) splitctx = setup_regexp_matches(PG_GETARG_TEXT_P_COPY(0), pattern, &re_flags, PG_GET_COLLATION(), - false, true); + false, true, true); MemoryContextSwitchTo(oldcontext); funcctx->user_fctx = (void *) splitctx; @@ -1185,9 +1387,6 @@ regexp_split_to_table(PG_FUNCTION_ARGS) SRF_RETURN_NEXT(funcctx, result); } - /* release space in multi-call ctx to avoid intraquery memory leak */ - cleanup_regexp_matches(splitctx); - SRF_RETURN_DONE(funcctx); } @@ -1216,7 +1415,9 @@ regexp_split_to_array(PG_FUNCTION_ARGS) if (re_flags.glob) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("regexp_split_to_array does not support the global option"))); + /* translator: %s is a SQL function name */ + errmsg("%s does not support the \"global\" option", + "regexp_split_to_array()"))); /* But we find all the matches anyway */ re_flags.glob = true; @@ -1224,7 +1425,7 @@ regexp_split_to_array(PG_FUNCTION_ARGS) PG_GETARG_TEXT_PP(1), &re_flags, PG_GET_COLLATION(), - false, true); + false, true, true); while (splitctx->next_match <= splitctx->nmatches) { @@ -1236,12 +1437,6 @@ regexp_split_to_array(PG_FUNCTION_ARGS) splitctx->next_match++; } - /* - * We don't call cleanup_regexp_matches here; it would try to pfree the - * input string, which we didn't copy. The space is not in a long-lived - * memory context anyway. - */ - PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext)); } @@ -1261,6 +1456,7 @@ regexp_split_to_array_no_flags(PG_FUNCTION_ARGS) static Datum build_regexp_split_result(regexp_matches_ctx *splitctx) { + char *buf = splitctx->conv_buf; int startpos; int endpos; @@ -1271,22 +1467,29 @@ build_regexp_split_result(regexp_matches_ctx *splitctx) if (startpos < 0) elog(ERROR, "invalid match ending position"); - if (splitctx->next_match < splitctx->nmatches) + if (buf) { + int bufsiz PG_USED_FOR_ASSERTS_ONLY = splitctx->conv_bufsiz; + int len; + endpos = splitctx->match_locs[splitctx->next_match * 2]; if (endpos < startpos) elog(ERROR, "invalid match starting position"); - return DirectFunctionCall3(text_substr, - PointerGetDatum(splitctx->orig_str), - Int32GetDatum(startpos + 1), - Int32GetDatum(endpos - startpos)); + len = pg_wchar2mb_with_len(splitctx->wide_str + startpos, + buf, + endpos - startpos); + Assert(len < bufsiz); + return PointerGetDatum(cstring_to_text_with_len(buf, len)); } else { - /* no more matches, return rest of string */ - return DirectFunctionCall2(text_substr_no_len, + endpos = splitctx->match_locs[splitctx->next_match * 2]; + if (endpos < startpos) + elog(ERROR, "invalid match starting position"); + return DirectFunctionCall3(text_substr, PointerGetDatum(splitctx->orig_str), - Int32GetDatum(startpos + 1)); + Int32GetDatum(startpos + 1), + Int32GetDatum(endpos - startpos)); } } diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index a0079821fef..17a7f6c9d83 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -8,7 +8,7 @@ * special I/O conversion routines. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -43,7 +43,7 @@ static char *format_operator_internal(Oid operator_oid, bool force_qualify); static char *format_procedure_internal(Oid procedure_oid, bool force_qualify); static void parseNameAndArgTypes(const char *string, bool allowNone, - List **names, int *nargs, Oid *argtypes); + List **names, int *nargs, Oid *argtypes); /***************************************************************************** diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index fc034ce6019..fb477d4fa01 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -1,4 +1,5 @@ -/* ---------- +/*------------------------------------------------------------------------- + * * ri_triggers.c * * Generic trigger procedures for referential integrity constraint @@ -13,25 +14,19 @@ * plan --- consider improving this someday. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/backend/utils/adt/ri_triggers.c * - * ---------- - */ - - -/* ---------- - * Internal TODO: - * - * Add MATCH PARTIAL logic. - * ---------- + *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/htup_details.h" #include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/xact.h" #include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" @@ -47,6 +42,7 @@ #include "storage/bufmgr.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/guc.h" #include "utils/inval.h" @@ -54,14 +50,13 @@ #include "utils/memutils.h" #include "utils/rel.h" #include "utils/rls.h" +#include "utils/ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" -/* ---------- +/* * Local definitions - * ---------- */ #define RI_MAX_NUMKEYS INDEX_MAX_KEYS @@ -97,12 +92,11 @@ #define RI_TRIGTYPE_DELETE 3 -/* ---------- +/* * RI_ConstraintInfo * - * Information extracted from an FK pg_constraint entry. This is cached in - * ri_constraint_cache. - * ---------- + * Information extracted from an FK pg_constraint entry. This is cached in + * ri_constraint_cache. */ typedef struct RI_ConstraintInfo { @@ -124,12 +118,10 @@ typedef struct RI_ConstraintInfo dlist_node valid_link; /* Link in list of valid entries */ } RI_ConstraintInfo; - -/* ---------- +/* * RI_QueryKey * - * The key identifying a prepared SPI plan in our query hashtable - * ---------- + * The key identifying a prepared SPI plan in our query hashtable */ typedef struct RI_QueryKey { @@ -137,10 +129,8 @@ typedef struct RI_QueryKey int32 constr_queryno; /* query type ID, see RI_PLAN_XXX above */ } RI_QueryKey; - -/* ---------- +/* * RI_QueryHashEntry - * ---------- */ typedef struct RI_QueryHashEntry { @@ -148,12 +138,10 @@ typedef struct RI_QueryHashEntry SPIPlanPtr plan; } RI_QueryHashEntry; - -/* ---------- +/* * RI_CompareKey * - * The key identifying an entry showing how to compare two values - * ---------- + * The key identifying an entry showing how to compare two values */ typedef struct RI_CompareKey { @@ -161,10 +149,8 @@ typedef struct RI_CompareKey Oid typeid; /* the data type to apply it to */ } RI_CompareKey; - -/* ---------- +/* * RI_CompareHashEntry - * ---------- */ typedef struct RI_CompareHashEntry { @@ -175,9 +161,8 @@ typedef struct RI_CompareHashEntry } RI_CompareHashEntry; -/* ---------- +/* * Local data - * ---------- */ static HTAB *ri_constraint_cache = NULL; static HTAB *ri_query_cache = NULL; @@ -186,33 +171,31 @@ static dlist_head ri_constraint_cache_valid_list; static int ri_constraint_cache_valid_count = 0; -/* ---------- +/* * Local function prototypes - * ---------- */ static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, - HeapTuple old_row, - const RI_ConstraintInfo *riinfo); + TupleTableSlot *oldslot, + const RI_ConstraintInfo *riinfo); static Datum ri_restrict(TriggerData *trigdata, bool is_no_action); -static Datum ri_setnull(TriggerData *trigdata); -static Datum ri_setdefault(TriggerData *trigdata); +static Datum ri_set(TriggerData *trigdata, bool is_set_null); static void quoteOneName(char *buffer, const char *name); static void quoteRelationName(char *buffer, Relation rel); static void ri_GenerateQual(StringInfo buf, - const char *sep, - const char *leftop, Oid leftoptype, - Oid opoid, - const char *rightop, Oid rightoptype); + const char *sep, + const char *leftop, Oid leftoptype, + Oid opoid, + const char *rightop, Oid rightoptype); static void ri_GenerateQualCollation(StringInfo buf, Oid collation); -static int ri_NullCheck(TupleDesc tupdesc, HeapTuple tup, - const RI_ConstraintInfo *riinfo, bool rel_is_pk); +static int ri_NullCheck(TupleDesc tupdesc, TupleTableSlot *slot, + const RI_ConstraintInfo *riinfo, bool rel_is_pk); static void ri_BuildQueryKey(RI_QueryKey *key, - const RI_ConstraintInfo *riinfo, - int32 constr_queryno); -static bool ri_KeysEqual(Relation rel, HeapTuple oldtup, HeapTuple newtup, - const RI_ConstraintInfo *riinfo, bool rel_is_pk); + const RI_ConstraintInfo *riinfo, + int32 constr_queryno); +static bool ri_KeysEqual(Relation rel, TupleTableSlot *oldslot, TupleTableSlot *newslot, + const RI_ConstraintInfo *riinfo, bool rel_is_pk); static bool ri_AttributesEqual(Oid eq_opr, Oid typeid, - Datum oldvalue, Datum newvalue); + Datum oldvalue, Datum newvalue); static void ri_InitHashTables(void); static void InvalidateConstraintCacheCallBack(Datum arg, int cacheid, uint32 hashvalue); @@ -221,32 +204,31 @@ static void ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan); static RI_CompareHashEntry *ri_HashCompareOp(Oid eq_opr, Oid typeid); static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, - int tgkind); + int tgkind); static const RI_ConstraintInfo *ri_FetchConstraintInfo(Trigger *trigger, - Relation trig_rel, bool rel_is_pk); + Relation trig_rel, bool rel_is_pk); static const RI_ConstraintInfo *ri_LoadConstraintInfo(Oid constraintOid); static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, Oid *argtypes, - RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel, - bool cache_plan); + RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel, + bool cache_plan); static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, - RI_QueryKey *qkey, SPIPlanPtr qplan, - Relation fk_rel, Relation pk_rel, - HeapTuple old_tuple, HeapTuple new_tuple, - bool detectNewRows, int expect_OK); -static void ri_ExtractValues(Relation rel, HeapTuple tup, - const RI_ConstraintInfo *riinfo, bool rel_is_pk, - Datum *vals, char *nulls); + RI_QueryKey *qkey, SPIPlanPtr qplan, + Relation fk_rel, Relation pk_rel, + TupleTableSlot *oldslot, TupleTableSlot *newslot, + bool detectNewRows, int expect_OK); +static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, + const RI_ConstraintInfo *riinfo, bool rel_is_pk, + Datum *vals, char *nulls); static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, - Relation pk_rel, Relation fk_rel, - HeapTuple violator, TupleDesc tupdesc, - int queryno) pg_attribute_noreturn(); + Relation pk_rel, Relation fk_rel, + TupleTableSlot *violatorslot, TupleDesc tupdesc, + int queryno, bool partgone) pg_attribute_noreturn(); -/* ---------- +/* * RI_FKey_check - * - * Check foreign key existence (combined for INSERT and UPDATE). - * ---------- + * Check foreign key existence (combined for INSERT and UPDATE). */ static Datum RI_FKey_check(TriggerData *trigdata) @@ -254,28 +236,17 @@ RI_FKey_check(TriggerData *trigdata) const RI_ConstraintInfo *riinfo; Relation fk_rel; Relation pk_rel; - HeapTuple new_row; - Buffer new_row_buf; + TupleTableSlot *newslot; RI_QueryKey qkey; SPIPlanPtr qplan; - int i; - /* - * Get arguments. - */ riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, trigdata->tg_relation, false); if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - { - new_row = trigdata->tg_newtuple; - new_row_buf = trigdata->tg_newtuplebuf; - } + newslot = trigdata->tg_newslot; else - { - new_row = trigdata->tg_trigtuple; - new_row_buf = trigdata->tg_trigtuplebuf; - } + newslot = trigdata->tg_trigslot; /* * We should not even consider checking the row if it is no longer valid, @@ -285,13 +256,8 @@ RI_FKey_check(TriggerData *trigdata) * and lock on the buffer to call HeapTupleSatisfiesVisibility. Caller * should be holding pin, but not lock. */ - LockBuffer(new_row_buf, BUFFER_LOCK_SHARE); - if (!HeapTupleSatisfiesVisibility(new_row, SnapshotSelf, new_row_buf)) - { - LockBuffer(new_row_buf, BUFFER_LOCK_UNLOCK); + if (!table_tuple_satisfies_snapshot(trigdata->tg_relation, newslot, SnapshotSelf)) return PointerGetDatum(NULL); - } - LockBuffer(new_row_buf, BUFFER_LOCK_UNLOCK); /* * Get the relation descriptors of the FK and PK tables. @@ -300,14 +266,9 @@ RI_FKey_check(TriggerData *trigdata) * SELECT FOR KEY SHARE will get on it. */ fk_rel = trigdata->tg_relation; - pk_rel = heap_open(riinfo->pk_relid, RowShareLock); - - if (riinfo->confmatchtype == FKCONSTR_MATCH_PARTIAL) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); + pk_rel = table_open(riinfo->pk_relid, RowShareLock); - switch (ri_NullCheck(RelationGetDescr(fk_rel), new_row, riinfo, false)) + switch (ri_NullCheck(RelationGetDescr(fk_rel), newslot, riinfo, false)) { case RI_KEYS_ALL_NULL: @@ -315,7 +276,7 @@ RI_FKey_check(TriggerData *trigdata) * No further check needed - an all-NULL key passes every type of * foreign key constraint. */ - heap_close(pk_rel, RowShareLock); + table_close(pk_rel, RowShareLock); return PointerGetDatum(NULL); case RI_KEYS_SOME_NULL: @@ -340,7 +301,7 @@ RI_FKey_check(TriggerData *trigdata) errdetail("MATCH FULL does not allow mixing of null and nonnull key values."), errtableconstraint(fk_rel, NameStr(riinfo->conname)))); - heap_close(pk_rel, RowShareLock); + table_close(pk_rel, RowShareLock); return PointerGetDatum(NULL); case FKCONSTR_MATCH_SIMPLE: @@ -349,9 +310,10 @@ RI_FKey_check(TriggerData *trigdata) * MATCH SIMPLE - if ANY column is null, the key passes * the constraint. */ - heap_close(pk_rel, RowShareLock); + table_close(pk_rel, RowShareLock); return PointerGetDatum(NULL); +#ifdef NOT_USED case FKCONSTR_MATCH_PARTIAL: /* @@ -360,16 +322,8 @@ RI_FKey_check(TriggerData *trigdata) * to only include non-null columns, or by writing a * special version here) */ - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - heap_close(pk_rel, RowShareLock); - return PointerGetDatum(NULL); - - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); break; +#endif } case RI_KEYS_NONE_NULL: @@ -384,9 +338,7 @@ RI_FKey_check(TriggerData *trigdata) if (SPI_connect() != SPI_OK_CONNECT) elog(ERROR, "SPI_connect failed"); - /* - * Fetch or prepare a saved plan for the real check - */ + /* Fetch or prepare a saved plan for the real check */ ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_CHECK_LOOKUPPK); if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) @@ -397,20 +349,24 @@ RI_FKey_check(TriggerData *trigdata) char paramname[16]; const char *querysep; Oid queryoids[RI_MAX_NUMKEYS]; + const char *pk_only; /* ---------- * The query string built is - * SELECT 1 FROM ONLY x WHERE pkatt1 = $1 [AND ...] + * SELECT 1 FROM [ONLY] x WHERE pkatt1 = $1 [AND ...] * FOR KEY SHARE OF x * The type id's for the $ parameters are those of the * corresponding FK attributes. * ---------- */ initStringInfo(&querybuf); + pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; quoteRelationName(pkrelname, pk_rel); - appendStringInfo(&querybuf, "SELECT 1 FROM ONLY %s x", pkrelname); + appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x", + pk_only, pkrelname); querysep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) + for (int i = 0; i < riinfo->nkeys; i++) { Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); @@ -437,84 +393,72 @@ RI_FKey_check(TriggerData *trigdata) */ ri_PerformCheck(riinfo, &qkey, qplan, fk_rel, pk_rel, - NULL, new_row, + NULL, newslot, false, SPI_OK_SELECT); if (SPI_finish() != SPI_OK_FINISH) elog(ERROR, "SPI_finish failed"); - heap_close(pk_rel, RowShareLock); + table_close(pk_rel, RowShareLock); return PointerGetDatum(NULL); } -/* ---------- +/* * RI_FKey_check_ins - * - * Check foreign key existence at insert event on FK table. - * ---------- + * Check foreign key existence at insert event on FK table. */ Datum RI_FKey_check_ins(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_check_ins", RI_TRIGTYPE_INSERT); - /* - * Share code with UPDATE case. - */ + /* Share code with UPDATE case. */ return RI_FKey_check((TriggerData *) fcinfo->context); } -/* ---------- +/* * RI_FKey_check_upd - * - * Check foreign key existence at update event on FK table. - * ---------- + * Check foreign key existence at update event on FK table. */ Datum RI_FKey_check_upd(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_check_upd", RI_TRIGTYPE_UPDATE); - /* - * Share code with INSERT case. - */ + /* Share code with INSERT case. */ return RI_FKey_check((TriggerData *) fcinfo->context); } -/* ---------- +/* * ri_Check_Pk_Match * * Check to see if another PK row has been created that provides the same - * key values as the "old_row" that's been modified or deleted in our trigger + * key values as the "oldslot" that's been modified or deleted in our trigger * event. Returns true if a match is found in the PK table. * - * We assume the caller checked that the old_row contains no NULL key values, + * We assume the caller checked that the oldslot contains no NULL key values, * since otherwise a match is impossible. - * ---------- */ static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, - HeapTuple old_row, + TupleTableSlot *oldslot, const RI_ConstraintInfo *riinfo) { SPIPlanPtr qplan; RI_QueryKey qkey; - int i; bool result; /* Only called for non-null rows */ - Assert(ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true) == RI_KEYS_NONE_NULL); + Assert(ri_NullCheck(RelationGetDescr(pk_rel), oldslot, riinfo, true) == RI_KEYS_NONE_NULL); if (SPI_connect() != SPI_OK_CONNECT) elog(ERROR, "SPI_connect failed"); @@ -532,21 +476,25 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, char attname[MAX_QUOTED_NAME_LEN]; char paramname[16]; const char *querysep; + const char *pk_only; Oid queryoids[RI_MAX_NUMKEYS]; /* ---------- * The query string built is - * SELECT 1 FROM ONLY x WHERE pkatt1 = $1 [AND ...] + * SELECT 1 FROM [ONLY] x WHERE pkatt1 = $1 [AND ...] * FOR KEY SHARE OF x * The type id's for the $ parameters are those of the * PK attributes themselves. * ---------- */ initStringInfo(&querybuf); + pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; quoteRelationName(pkrelname, pk_rel); - appendStringInfo(&querybuf, "SELECT 1 FROM ONLY %s x", pkrelname); + appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x", + pk_only, pkrelname); querysep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) + for (int i = 0; i < riinfo->nkeys; i++) { Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); @@ -572,7 +520,7 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, */ result = ri_PerformCheck(riinfo, &qkey, qplan, fk_rel, pk_rel, - old_row, NULL, + oldslot, NULL, true, /* treat like update */ SPI_OK_SELECT); @@ -583,106 +531,85 @@ ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, } -/* ---------- +/* * RI_FKey_noaction_del - * - * Give an error and roll back the current transaction if the - * delete has resulted in a violation of the given referential - * integrity constraint. - * ---------- + * Give an error and roll back the current transaction if the + * delete has resulted in a violation of the given referential + * integrity constraint. */ Datum RI_FKey_noaction_del(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_noaction_del", RI_TRIGTYPE_DELETE); - /* - * Share code with RESTRICT/UPDATE cases. - */ + /* Share code with RESTRICT/UPDATE cases. */ return ri_restrict((TriggerData *) fcinfo->context, true); } -/* ---------- +/* * RI_FKey_restrict_del - * - * Restrict delete from PK table to rows unreferenced by foreign key. + * Restrict delete from PK table to rows unreferenced by foreign key. * - * The SQL standard intends that this referential action occur exactly when - * the delete is performed, rather than after. This appears to be - * the only difference between "NO ACTION" and "RESTRICT". In Postgres - * we still implement this as an AFTER trigger, but it's non-deferrable. - * ---------- + * The SQL standard intends that this referential action occur exactly when + * the delete is performed, rather than after. This appears to be + * the only difference between "NO ACTION" and "RESTRICT". In Postgres + * we still implement this as an AFTER trigger, but it's non-deferrable. */ Datum RI_FKey_restrict_del(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_restrict_del", RI_TRIGTYPE_DELETE); - /* - * Share code with NO ACTION/UPDATE cases. - */ + /* Share code with NO ACTION/UPDATE cases. */ return ri_restrict((TriggerData *) fcinfo->context, false); } -/* ---------- +/* * RI_FKey_noaction_upd - * - * Give an error and roll back the current transaction if the - * update has resulted in a violation of the given referential - * integrity constraint. - * ---------- + * Give an error and roll back the current transaction if the + * update has resulted in a violation of the given referential + * integrity constraint. */ Datum RI_FKey_noaction_upd(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_noaction_upd", RI_TRIGTYPE_UPDATE); - /* - * Share code with RESTRICT/DELETE cases. - */ + /* Share code with RESTRICT/DELETE cases. */ return ri_restrict((TriggerData *) fcinfo->context, true); } -/* ---------- +/* * RI_FKey_restrict_upd - * - * Restrict update of PK to rows unreferenced by foreign key. + * Restrict update of PK to rows unreferenced by foreign key. * - * The SQL standard intends that this referential action occur exactly when - * the update is performed, rather than after. This appears to be - * the only difference between "NO ACTION" and "RESTRICT". In Postgres - * we still implement this as an AFTER trigger, but it's non-deferrable. - * ---------- + * The SQL standard intends that this referential action occur exactly when + * the update is performed, rather than after. This appears to be + * the only difference between "NO ACTION" and "RESTRICT". In Postgres + * we still implement this as an AFTER trigger, but it's non-deferrable. */ Datum RI_FKey_restrict_upd(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_restrict_upd", RI_TRIGTYPE_UPDATE); - /* - * Share code with NO ACTION/DELETE cases. - */ + /* Share code with NO ACTION/DELETE cases. */ return ri_restrict((TriggerData *) fcinfo->context, false); } -/* ---------- +/* * ri_restrict - * - * Common code for ON DELETE RESTRICT, ON DELETE NO ACTION, - * ON UPDATE RESTRICT, and ON UPDATE NO ACTION. - * ---------- + * Common code for ON DELETE RESTRICT, ON DELETE NO ACTION, + * ON UPDATE RESTRICT, and ON UPDATE NO ACTION. */ static Datum ri_restrict(TriggerData *trigdata, bool is_no_action) @@ -690,13 +617,10 @@ ri_restrict(TriggerData *trigdata, bool is_no_action) const RI_ConstraintInfo *riinfo; Relation fk_rel; Relation pk_rel; - HeapTuple old_row; + TupleTableSlot *oldslot; RI_QueryKey qkey; SPIPlanPtr qplan; - /* - * Get arguments. - */ riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, trigdata->tg_relation, true); @@ -706,169 +630,105 @@ ri_restrict(TriggerData *trigdata, bool is_no_action) * fk_rel is opened in RowShareLock mode since that's what our eventual * SELECT FOR KEY SHARE will get on it. */ - fk_rel = heap_open(riinfo->fk_relid, RowShareLock); + fk_rel = table_open(riinfo->fk_relid, RowShareLock); pk_rel = trigdata->tg_relation; - old_row = trigdata->tg_trigtuple; + oldslot = trigdata->tg_trigslot; - switch (riinfo->confmatchtype) + /* + * If another PK row now exists providing the old key values, we should + * not do anything. However, this check should only be made in the NO + * ACTION case; in RESTRICT cases we don't wish to allow another row to be + * substituted. + */ + if (is_no_action && + ri_Check_Pk_Match(pk_rel, fk_rel, oldslot, riinfo)) { - /* ---------- - * SQL:2008 15.17 - * General rules 9) a) iv): - * MATCH SIMPLE/FULL - * ... ON DELETE RESTRICT - * General rules 10) a) iv): - * MATCH SIMPLE/FULL - * ... ON UPDATE RESTRICT - * ---------- - */ - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true)) - { - case RI_KEYS_ALL_NULL: - case RI_KEYS_SOME_NULL: - - /* - * No check needed - there cannot be any reference to old - * key if it contains a NULL - */ - heap_close(fk_rel, RowShareLock); - return PointerGetDatum(NULL); - - case RI_KEYS_NONE_NULL: - - /* - * Have a full qualified key - continue below - */ - break; - } - - /* - * In UPDATE, no need to do anything if old and new keys are equal - */ - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - { - HeapTuple new_row = trigdata->tg_newtuple; - - if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true)) - { - heap_close(fk_rel, RowShareLock); - return PointerGetDatum(NULL); - } - } - - /* - * If another PK row now exists providing the old key values, we - * should not do anything. However, this check should only be - * made in the NO ACTION case; in RESTRICT cases we don't wish to - * allow another row to be substituted. - */ - if (is_no_action && - ri_Check_Pk_Match(pk_rel, fk_rel, old_row, riinfo)) - { - heap_close(fk_rel, RowShareLock); - return PointerGetDatum(NULL); - } - - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + table_close(fk_rel, RowShareLock); + return PointerGetDatum(NULL); + } - /* - * Fetch or prepare a saved plan for the restrict lookup (it's the - * same query for delete and update cases) - */ - ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_RESTRICT_CHECKREF); + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); - if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) - { - StringInfoData querybuf; - char fkrelname[MAX_QUOTED_REL_NAME_LEN]; - char attname[MAX_QUOTED_NAME_LEN]; - char paramname[16]; - const char *querysep; - Oid queryoids[RI_MAX_NUMKEYS]; - const char *fk_only; - int i; - - /* ---------- - * The query string built is - * SELECT 1 FROM [ONLY] x WHERE $1 = fkatt1 [AND ...] - * FOR KEY SHARE OF x - * The type id's for the $ parameters are those of the - * corresponding PK attributes. - * ---------- - */ - initStringInfo(&querybuf); - fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? - "" : "ONLY "; - quoteRelationName(fkrelname, fk_rel); - appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x", - fk_only, fkrelname); - querysep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) - { - Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); - Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); - - quoteOneName(attname, - RIAttName(fk_rel, riinfo->fk_attnums[i])); - sprintf(paramname, "$%d", i + 1); - ri_GenerateQual(&querybuf, querysep, - paramname, pk_type, - riinfo->pf_eq_oprs[i], - attname, fk_type); - querysep = "AND"; - queryoids[i] = pk_type; - } - appendStringInfoString(&querybuf, " FOR KEY SHARE OF x"); + /* + * Fetch or prepare a saved plan for the restrict lookup (it's the same + * query for delete and update cases) + */ + ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_RESTRICT_CHECKREF); - /* Prepare and save the plan */ - qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, - &qkey, fk_rel, pk_rel, true); - } + if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) + { + StringInfoData querybuf; + char fkrelname[MAX_QUOTED_REL_NAME_LEN]; + char attname[MAX_QUOTED_NAME_LEN]; + char paramname[16]; + const char *querysep; + Oid queryoids[RI_MAX_NUMKEYS]; + const char *fk_only; - /* - * We have a plan now. Run it to check for existing references. - */ - ri_PerformCheck(riinfo, &qkey, qplan, - fk_rel, pk_rel, - old_row, NULL, - true, /* must detect new rows */ - SPI_OK_SELECT); + /* ---------- + * The query string built is + * SELECT 1 FROM [ONLY] x WHERE $1 = fkatt1 [AND ...] + * FOR KEY SHARE OF x + * The type id's for the $ parameters are those of the + * corresponding PK attributes. + * ---------- + */ + initStringInfo(&querybuf); + fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + quoteRelationName(fkrelname, fk_rel); + appendStringInfo(&querybuf, "SELECT 1 FROM %s%s x", + fk_only, fkrelname); + querysep = "WHERE"; + for (int i = 0; i < riinfo->nkeys; i++) + { + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); + Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); + Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]); + Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]); - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + quoteOneName(attname, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + sprintf(paramname, "$%d", i + 1); + ri_GenerateQual(&querybuf, querysep, + paramname, pk_type, + riinfo->pf_eq_oprs[i], + attname, fk_type); + if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll)) + ri_GenerateQualCollation(&querybuf, pk_coll); + querysep = "AND"; + queryoids[i] = pk_type; + } + appendStringInfoString(&querybuf, " FOR KEY SHARE OF x"); - heap_close(fk_rel, RowShareLock); + /* Prepare and save the plan */ + qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, + &qkey, fk_rel, pk_rel, true); + } - return PointerGetDatum(NULL); + /* + * We have a plan now. Run it to check for existing references. + */ + ri_PerformCheck(riinfo, &qkey, qplan, + fk_rel, pk_rel, + oldslot, NULL, + true, /* must detect new rows */ + SPI_OK_SELECT); - /* - * Handle MATCH PARTIAL restrict delete or update. - */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - return PointerGetDatum(NULL); + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + table_close(fk_rel, RowShareLock); - /* Never reached */ return PointerGetDatum(NULL); } -/* ---------- +/* * RI_FKey_cascade_del - * - * Cascaded delete foreign key references at delete event on PK table. - * ---------- + * Cascaded delete foreign key references at delete event on PK table. */ Datum RI_FKey_cascade_del(PG_FUNCTION_ARGS) @@ -877,19 +737,13 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS) const RI_ConstraintInfo *riinfo; Relation fk_rel; Relation pk_rel; - HeapTuple old_row; + TupleTableSlot *oldslot; RI_QueryKey qkey; SPIPlanPtr qplan; - int i; - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_cascade_del", RI_TRIGTYPE_DELETE); - /* - * Get arguments. - */ riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, trigdata->tg_relation, true); @@ -899,136 +753,88 @@ RI_FKey_cascade_del(PG_FUNCTION_ARGS) * fk_rel is opened in RowExclusiveLock mode since that's what our * eventual DELETE will get on it. */ - fk_rel = heap_open(riinfo->fk_relid, RowExclusiveLock); + fk_rel = table_open(riinfo->fk_relid, RowExclusiveLock); pk_rel = trigdata->tg_relation; - old_row = trigdata->tg_trigtuple; + oldslot = trigdata->tg_trigslot; - switch (riinfo->confmatchtype) - { - /* ---------- - * SQL:2008 15.17 - * General rules 9) a) i): - * MATCH SIMPLE/FULL - * ... ON DELETE CASCADE - * ---------- - */ - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true)) - { - case RI_KEYS_ALL_NULL: - case RI_KEYS_SOME_NULL: + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); - /* - * No check needed - there cannot be any reference to old - * key if it contains a NULL - */ - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); + /* Fetch or prepare a saved plan for the cascaded delete */ + ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_CASCADE_DEL_DODELETE); - case RI_KEYS_NONE_NULL: + if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) + { + StringInfoData querybuf; + char fkrelname[MAX_QUOTED_REL_NAME_LEN]; + char attname[MAX_QUOTED_NAME_LEN]; + char paramname[16]; + const char *querysep; + Oid queryoids[RI_MAX_NUMKEYS]; + const char *fk_only; - /* - * Have a full qualified key - continue below - */ - break; - } + /* ---------- + * The query string built is + * DELETE FROM [ONLY] WHERE $1 = fkatt1 [AND ...] + * The type id's for the $ parameters are those of the + * corresponding PK attributes. + * ---------- + */ + initStringInfo(&querybuf); + fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + quoteRelationName(fkrelname, fk_rel); + appendStringInfo(&querybuf, "DELETE FROM %s%s", + fk_only, fkrelname); + querysep = "WHERE"; + for (int i = 0; i < riinfo->nkeys; i++) + { + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); + Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); + Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]); + Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]); - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + quoteOneName(attname, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + sprintf(paramname, "$%d", i + 1); + ri_GenerateQual(&querybuf, querysep, + paramname, pk_type, + riinfo->pf_eq_oprs[i], + attname, fk_type); + if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll)) + ri_GenerateQualCollation(&querybuf, pk_coll); + querysep = "AND"; + queryoids[i] = pk_type; + } - /* - * Fetch or prepare a saved plan for the cascaded delete - */ - ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_CASCADE_DEL_DODELETE); + /* Prepare and save the plan */ + qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, + &qkey, fk_rel, pk_rel, true); + } - if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) - { - StringInfoData querybuf; - char fkrelname[MAX_QUOTED_REL_NAME_LEN]; - char attname[MAX_QUOTED_NAME_LEN]; - char paramname[16]; - const char *querysep; - Oid queryoids[RI_MAX_NUMKEYS]; - const char *fk_only; - - /* ---------- - * The query string built is - * DELETE FROM [ONLY] WHERE $1 = fkatt1 [AND ...] - * The type id's for the $ parameters are those of the - * corresponding PK attributes. - * ---------- - */ - initStringInfo(&querybuf); - fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? - "" : "ONLY "; - quoteRelationName(fkrelname, fk_rel); - appendStringInfo(&querybuf, "DELETE FROM %s%s", - fk_only, fkrelname); - querysep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) - { - Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); - Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); - - quoteOneName(attname, - RIAttName(fk_rel, riinfo->fk_attnums[i])); - sprintf(paramname, "$%d", i + 1); - ri_GenerateQual(&querybuf, querysep, - paramname, pk_type, - riinfo->pf_eq_oprs[i], - attname, fk_type); - querysep = "AND"; - queryoids[i] = pk_type; - } - - /* Prepare and save the plan */ - qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, - &qkey, fk_rel, pk_rel, true); - } - - /* - * We have a plan now. Build up the arguments from the key values - * in the deleted PK tuple and delete the referencing rows - */ - ri_PerformCheck(riinfo, &qkey, qplan, - fk_rel, pk_rel, - old_row, NULL, - true, /* must detect new rows */ - SPI_OK_DELETE); - - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); - - heap_close(fk_rel, RowExclusiveLock); - - return PointerGetDatum(NULL); + /* + * We have a plan now. Build up the arguments from the key values in the + * deleted PK tuple and delete the referencing rows + */ + ri_PerformCheck(riinfo, &qkey, qplan, + fk_rel, pk_rel, + oldslot, NULL, + true, /* must detect new rows */ + SPI_OK_DELETE); - /* - * Handle MATCH PARTIAL cascaded delete. - */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - return PointerGetDatum(NULL); + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + table_close(fk_rel, RowExclusiveLock); - /* Never reached */ return PointerGetDatum(NULL); } -/* ---------- +/* * RI_FKey_cascade_upd - * - * Cascaded update foreign key references at update event on PK table. - * ---------- + * Cascaded update foreign key references at update event on PK table. */ Datum RI_FKey_cascade_upd(PG_FUNCTION_ARGS) @@ -1037,21 +843,14 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS) const RI_ConstraintInfo *riinfo; Relation fk_rel; Relation pk_rel; - HeapTuple new_row; - HeapTuple old_row; + TupleTableSlot *newslot; + TupleTableSlot *oldslot; RI_QueryKey qkey; SPIPlanPtr qplan; - int i; - int j; - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_cascade_upd", RI_TRIGTYPE_UPDATE); - /* - * Get arguments. - */ riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, trigdata->tg_relation, true); @@ -1062,213 +861,173 @@ RI_FKey_cascade_upd(PG_FUNCTION_ARGS) * fk_rel is opened in RowExclusiveLock mode since that's what our * eventual UPDATE will get on it. */ - fk_rel = heap_open(riinfo->fk_relid, RowExclusiveLock); + fk_rel = table_open(riinfo->fk_relid, RowExclusiveLock); pk_rel = trigdata->tg_relation; - new_row = trigdata->tg_newtuple; - old_row = trigdata->tg_trigtuple; - - switch (riinfo->confmatchtype) - { - /* ---------- - * SQL:2008 15.17 - * General rules 10) a) i): - * MATCH SIMPLE/FULL - * ... ON UPDATE CASCADE - * ---------- - */ - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true)) - { - case RI_KEYS_ALL_NULL: - case RI_KEYS_SOME_NULL: - - /* - * No check needed - there cannot be any reference to old - * key if it contains a NULL - */ - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); - - case RI_KEYS_NONE_NULL: - - /* - * Have a full qualified key - continue below - */ - break; - } - - /* - * No need to do anything if old and new keys are equal - */ - if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true)) - { - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); - } + newslot = trigdata->tg_newslot; + oldslot = trigdata->tg_trigslot; - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); - - /* - * Fetch or prepare a saved plan for the cascaded update - */ - ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_CASCADE_UPD_DOUPDATE); + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); - if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) - { - StringInfoData querybuf; - StringInfoData qualbuf; - char fkrelname[MAX_QUOTED_REL_NAME_LEN]; - char attname[MAX_QUOTED_NAME_LEN]; - char paramname[16]; - const char *querysep; - const char *qualsep; - Oid queryoids[RI_MAX_NUMKEYS * 2]; - const char *fk_only; - - /* ---------- - * The query string built is - * UPDATE [ONLY] SET fkatt1 = $1 [, ...] - * WHERE $n = fkatt1 [AND ...] - * The type id's for the $ parameters are those of the - * corresponding PK attributes. Note that we are assuming - * there is an assignment cast from the PK to the FK type; - * else the parser will fail. - * ---------- - */ - initStringInfo(&querybuf); - initStringInfo(&qualbuf); - fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? - "" : "ONLY "; - quoteRelationName(fkrelname, fk_rel); - appendStringInfo(&querybuf, "UPDATE %s%s SET", - fk_only, fkrelname); - querysep = ""; - qualsep = "WHERE"; - for (i = 0, j = riinfo->nkeys; i < riinfo->nkeys; i++, j++) - { - Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); - Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); - - quoteOneName(attname, - RIAttName(fk_rel, riinfo->fk_attnums[i])); - appendStringInfo(&querybuf, - "%s %s = $%d", - querysep, attname, i + 1); - sprintf(paramname, "$%d", j + 1); - ri_GenerateQual(&qualbuf, qualsep, - paramname, pk_type, - riinfo->pf_eq_oprs[i], - attname, fk_type); - querysep = ","; - qualsep = "AND"; - queryoids[i] = pk_type; - queryoids[j] = pk_type; - } - appendStringInfoString(&querybuf, qualbuf.data); + /* Fetch or prepare a saved plan for the cascaded update */ + ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_CASCADE_UPD_DOUPDATE); - /* Prepare and save the plan */ - qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys * 2, queryoids, - &qkey, fk_rel, pk_rel, true); - } + if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) + { + StringInfoData querybuf; + StringInfoData qualbuf; + char fkrelname[MAX_QUOTED_REL_NAME_LEN]; + char attname[MAX_QUOTED_NAME_LEN]; + char paramname[16]; + const char *querysep; + const char *qualsep; + Oid queryoids[RI_MAX_NUMKEYS * 2]; + const char *fk_only; - /* - * We have a plan now. Run it to update the existing references. - */ - ri_PerformCheck(riinfo, &qkey, qplan, - fk_rel, pk_rel, - old_row, new_row, - true, /* must detect new rows */ - SPI_OK_UPDATE); + /* ---------- + * The query string built is + * UPDATE [ONLY] SET fkatt1 = $1 [, ...] + * WHERE $n = fkatt1 [AND ...] + * The type id's for the $ parameters are those of the + * corresponding PK attributes. Note that we are assuming + * there is an assignment cast from the PK to the FK type; + * else the parser will fail. + * ---------- + */ + initStringInfo(&querybuf); + initStringInfo(&qualbuf); + fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + quoteRelationName(fkrelname, fk_rel); + appendStringInfo(&querybuf, "UPDATE %s%s SET", + fk_only, fkrelname); + querysep = ""; + qualsep = "WHERE"; + for (int i = 0, j = riinfo->nkeys; i < riinfo->nkeys; i++, j++) + { + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); + Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); + Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]); + Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]); - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + quoteOneName(attname, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + appendStringInfo(&querybuf, + "%s %s = $%d", + querysep, attname, i + 1); + sprintf(paramname, "$%d", j + 1); + ri_GenerateQual(&qualbuf, qualsep, + paramname, pk_type, + riinfo->pf_eq_oprs[i], + attname, fk_type); + if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll)) + ri_GenerateQualCollation(&querybuf, pk_coll); + querysep = ","; + qualsep = "AND"; + queryoids[i] = pk_type; + queryoids[j] = pk_type; + } + appendBinaryStringInfo(&querybuf, qualbuf.data, qualbuf.len); - heap_close(fk_rel, RowExclusiveLock); + /* Prepare and save the plan */ + qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys * 2, queryoids, + &qkey, fk_rel, pk_rel, true); + } - return PointerGetDatum(NULL); + /* + * We have a plan now. Run it to update the existing references. + */ + ri_PerformCheck(riinfo, &qkey, qplan, + fk_rel, pk_rel, + oldslot, newslot, + true, /* must detect new rows */ + SPI_OK_UPDATE); - /* - * Handle MATCH PARTIAL cascade update. - */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - return PointerGetDatum(NULL); + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + table_close(fk_rel, RowExclusiveLock); - /* Never reached */ return PointerGetDatum(NULL); } -/* ---------- +/* * RI_FKey_setnull_del - * - * Set foreign key references to NULL values at delete event on PK table. - * ---------- + * Set foreign key references to NULL values at delete event on PK table. */ Datum RI_FKey_setnull_del(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_setnull_del", RI_TRIGTYPE_DELETE); - /* - * Share code with UPDATE case - */ - return ri_setnull((TriggerData *) fcinfo->context); + /* Share code with UPDATE case */ + return ri_set((TriggerData *) fcinfo->context, true); } -/* ---------- +/* * RI_FKey_setnull_upd - * - * Set foreign key references to NULL at update event on PK table. - * ---------- + * Set foreign key references to NULL at update event on PK table. */ Datum RI_FKey_setnull_upd(PG_FUNCTION_ARGS) { - /* - * Check that this is a valid trigger call on the right time and event. - */ + /* Check that this is a valid trigger call on the right time and event. */ ri_CheckTrigger(fcinfo, "RI_FKey_setnull_upd", RI_TRIGTYPE_UPDATE); - /* - * Share code with DELETE case - */ - return ri_setnull((TriggerData *) fcinfo->context); + /* Share code with DELETE case */ + return ri_set((TriggerData *) fcinfo->context, true); } -/* ---------- - * ri_setnull - +/* + * RI_FKey_setdefault_del - * - * Common code for ON DELETE SET NULL and ON UPDATE SET NULL - * ---------- + * Set foreign key references to defaults at delete event on PK table. + */ +Datum +RI_FKey_setdefault_del(PG_FUNCTION_ARGS) +{ + /* Check that this is a valid trigger call on the right time and event. */ + ri_CheckTrigger(fcinfo, "RI_FKey_setdefault_del", RI_TRIGTYPE_DELETE); + + /* Share code with UPDATE case */ + return ri_set((TriggerData *) fcinfo->context, false); +} + +/* + * RI_FKey_setdefault_upd - + * + * Set foreign key references to defaults at update event on PK table. + */ +Datum +RI_FKey_setdefault_upd(PG_FUNCTION_ARGS) +{ + /* Check that this is a valid trigger call on the right time and event. */ + ri_CheckTrigger(fcinfo, "RI_FKey_setdefault_upd", RI_TRIGTYPE_UPDATE); + + /* Share code with DELETE case */ + return ri_set((TriggerData *) fcinfo->context, false); +} + +/* + * ri_set - + * + * Common code for ON DELETE SET NULL, ON DELETE SET DEFAULT, ON UPDATE SET + * NULL, and ON UPDATE SET DEFAULT. */ static Datum -ri_setnull(TriggerData *trigdata) +ri_set(TriggerData *trigdata, bool is_set_null) { const RI_ConstraintInfo *riinfo; Relation fk_rel; Relation pk_rel; - HeapTuple old_row; + TupleTableSlot *oldslot; RI_QueryKey qkey; SPIPlanPtr qplan; - int i; - /* - * Get arguments. - */ riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, trigdata->tg_relation, true); @@ -1278,650 +1037,573 @@ ri_setnull(TriggerData *trigdata) * fk_rel is opened in RowExclusiveLock mode since that's what our * eventual UPDATE will get on it. */ - fk_rel = heap_open(riinfo->fk_relid, RowExclusiveLock); + fk_rel = table_open(riinfo->fk_relid, RowExclusiveLock); pk_rel = trigdata->tg_relation; - old_row = trigdata->tg_trigtuple; - - switch (riinfo->confmatchtype) - { - /* ---------- - * SQL:2008 15.17 - * General rules 9) a) ii): - * MATCH SIMPLE/FULL - * ... ON DELETE SET NULL - * General rules 10) a) ii): - * MATCH SIMPLE/FULL - * ... ON UPDATE SET NULL - * ---------- - */ - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true)) - { - case RI_KEYS_ALL_NULL: - case RI_KEYS_SOME_NULL: + oldslot = trigdata->tg_trigslot; - /* - * No check needed - there cannot be any reference to old - * key if it contains a NULL - */ - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); - case RI_KEYS_NONE_NULL: + /* + * Fetch or prepare a saved plan for the set null/default operation (it's + * the same query for delete and update cases) + */ + ri_BuildQueryKey(&qkey, riinfo, + (is_set_null + ? RI_PLAN_SETNULL_DOUPDATE + : RI_PLAN_SETDEFAULT_DOUPDATE)); - /* - * Have a full qualified key - continue below - */ - break; - } + if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) + { + StringInfoData querybuf; + StringInfoData qualbuf; + char fkrelname[MAX_QUOTED_REL_NAME_LEN]; + char attname[MAX_QUOTED_NAME_LEN]; + char paramname[16]; + const char *querysep; + const char *qualsep; + Oid queryoids[RI_MAX_NUMKEYS]; + const char *fk_only; - /* - * In UPDATE, no need to do anything if old and new keys are equal - */ - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - { - HeapTuple new_row = trigdata->tg_newtuple; + /* ---------- + * The query string built is + * UPDATE [ONLY] SET fkatt1 = {NULL|DEFAULT} [, ...] + * WHERE $1 = fkatt1 [AND ...] + * The type id's for the $ parameters are those of the + * corresponding PK attributes. + * ---------- + */ + initStringInfo(&querybuf); + initStringInfo(&qualbuf); + fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + quoteRelationName(fkrelname, fk_rel); + appendStringInfo(&querybuf, "UPDATE %s%s SET", + fk_only, fkrelname); + querysep = ""; + qualsep = "WHERE"; + for (int i = 0; i < riinfo->nkeys; i++) + { + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); + Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); + Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]); + Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]); - if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true)) - { - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); - } - } + quoteOneName(attname, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + appendStringInfo(&querybuf, + "%s %s = %s", + querysep, attname, + is_set_null ? "NULL" : "DEFAULT"); + sprintf(paramname, "$%d", i + 1); + ri_GenerateQual(&qualbuf, qualsep, + paramname, pk_type, + riinfo->pf_eq_oprs[i], + attname, fk_type); + if (pk_coll != fk_coll && !get_collation_isdeterministic(pk_coll)) + ri_GenerateQualCollation(&querybuf, pk_coll); + querysep = ","; + qualsep = "AND"; + queryoids[i] = pk_type; + } + appendBinaryStringInfo(&querybuf, qualbuf.data, qualbuf.len); - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); + /* Prepare and save the plan */ + qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, + &qkey, fk_rel, pk_rel, true); + } - /* - * Fetch or prepare a saved plan for the set null operation (it's - * the same query for delete and update cases) - */ - ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_SETNULL_DOUPDATE); + /* + * We have a plan now. Run it to update the existing references. + */ + ri_PerformCheck(riinfo, &qkey, qplan, + fk_rel, pk_rel, + oldslot, NULL, + true, /* must detect new rows */ + SPI_OK_UPDATE); - if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) - { - StringInfoData querybuf; - StringInfoData qualbuf; - char fkrelname[MAX_QUOTED_REL_NAME_LEN]; - char attname[MAX_QUOTED_NAME_LEN]; - char paramname[16]; - const char *querysep; - const char *qualsep; - const char *fk_only; - Oid queryoids[RI_MAX_NUMKEYS]; - - /* ---------- - * The query string built is - * UPDATE [ONLY] SET fkatt1 = NULL [, ...] - * WHERE $1 = fkatt1 [AND ...] - * The type id's for the $ parameters are those of the - * corresponding PK attributes. - * ---------- - */ - initStringInfo(&querybuf); - initStringInfo(&qualbuf); - fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? - "" : "ONLY "; - quoteRelationName(fkrelname, fk_rel); - appendStringInfo(&querybuf, "UPDATE %s%s SET", - fk_only, fkrelname); - querysep = ""; - qualsep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) - { - Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); - Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); - - quoteOneName(attname, - RIAttName(fk_rel, riinfo->fk_attnums[i])); - appendStringInfo(&querybuf, - "%s %s = NULL", - querysep, attname); - sprintf(paramname, "$%d", i + 1); - ri_GenerateQual(&qualbuf, qualsep, - paramname, pk_type, - riinfo->pf_eq_oprs[i], - attname, fk_type); - querysep = ","; - qualsep = "AND"; - queryoids[i] = pk_type; - } - appendStringInfoString(&querybuf, qualbuf.data); + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - /* Prepare and save the plan */ - qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, - &qkey, fk_rel, pk_rel, true); - } + table_close(fk_rel, RowExclusiveLock); - /* - * We have a plan now. Run it to update the existing references. - */ - ri_PerformCheck(riinfo, &qkey, qplan, - fk_rel, pk_rel, - old_row, NULL, - true, /* must detect new rows */ - SPI_OK_UPDATE); + if (is_set_null) + return PointerGetDatum(NULL); + else + { + /* + * If we just deleted or updated the PK row whose key was equal to the + * FK columns' default values, and a referencing row exists in the FK + * table, we would have updated that row to the same values it already + * had --- and RI_FKey_fk_upd_check_required would hence believe no + * check is necessary. So we need to do another lookup now and in + * case a reference still exists, abort the operation. That is + * already implemented in the NO ACTION trigger, so just run it. (This + * recheck is only needed in the SET DEFAULT case, since CASCADE would + * remove such rows in case of a DELETE operation or would change the + * FK key values in case of an UPDATE, while SET NULL is certain to + * result in rows that satisfy the FK constraint.) + */ + return ri_restrict(trigdata, true); + } +} - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); - heap_close(fk_rel, RowExclusiveLock); +/* + * RI_FKey_pk_upd_check_required - + * + * Check if we really need to fire the RI trigger for an update or delete to a PK + * relation. This is called by the AFTER trigger queue manager to see if + * it can skip queuing an instance of an RI trigger. Returns true if the + * trigger must be fired, false if we can prove the constraint will still + * be satisfied. + * + * newslot will be NULL if this is called for a delete. + */ +bool +RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, + TupleTableSlot *oldslot, TupleTableSlot *newslot) +{ + const RI_ConstraintInfo *riinfo; - return PointerGetDatum(NULL); + riinfo = ri_FetchConstraintInfo(trigger, pk_rel, true); - /* - * Handle MATCH PARTIAL set null delete or update. - */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - return PointerGetDatum(NULL); + /* + * If any old key value is NULL, the row could not have been referenced by + * an FK row, so no check is needed. + */ + if (ri_NullCheck(RelationGetDescr(pk_rel), oldslot, riinfo, true) != RI_KEYS_NONE_NULL) + return false; - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + /* If all old and new key values are equal, no check is needed */ + if (newslot && ri_KeysEqual(pk_rel, oldslot, newslot, riinfo, true)) + return false; - /* Never reached */ - return PointerGetDatum(NULL); + /* Else we need to fire the trigger. */ + return true; } - -/* ---------- - * RI_FKey_setdefault_del - +/* + * RI_FKey_fk_upd_check_required - * - * Set foreign key references to defaults at delete event on PK table. - * ---------- + * Check if we really need to fire the RI trigger for an update to an FK + * relation. This is called by the AFTER trigger queue manager to see if + * it can skip queuing an instance of an RI trigger. Returns true if the + * trigger must be fired, false if we can prove the constraint will still + * be satisfied. */ -Datum -RI_FKey_setdefault_del(PG_FUNCTION_ARGS) +bool +RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, + TupleTableSlot *oldslot, TupleTableSlot *newslot) { + const RI_ConstraintInfo *riinfo; + int ri_nullcheck; + Datum xminDatum; + TransactionId xmin; + bool isnull; + + riinfo = ri_FetchConstraintInfo(trigger, fk_rel, false); + + ri_nullcheck = ri_NullCheck(RelationGetDescr(fk_rel), newslot, riinfo, false); + /* - * Check that this is a valid trigger call on the right time and event. + * If all new key values are NULL, the row satisfies the constraint, so no + * check is needed. */ - ri_CheckTrigger(fcinfo, "RI_FKey_setdefault_del", RI_TRIGTYPE_DELETE); + if (ri_nullcheck == RI_KEYS_ALL_NULL) + return false; /* - * Share code with UPDATE case + * If some new key values are NULL, the behavior depends on the match + * type. */ - return ri_setdefault((TriggerData *) fcinfo->context); -} + else if (ri_nullcheck == RI_KEYS_SOME_NULL) + { + switch (riinfo->confmatchtype) + { + case FKCONSTR_MATCH_SIMPLE: + + /* + * If any new key value is NULL, the row must satisfy the + * constraint, so no check is needed. + */ + return false; + + case FKCONSTR_MATCH_PARTIAL: + + /* + * Don't know, must run full check. + */ + break; + + case FKCONSTR_MATCH_FULL: + + /* + * If some new key values are NULL, the row fails the + * constraint. We must not throw error here, because the row + * might get invalidated before the constraint is to be + * checked, but we should queue the event to apply the check + * later. + */ + return true; + } + } -/* ---------- - * RI_FKey_setdefault_upd - - * - * Set foreign key references to defaults at update event on PK table. - * ---------- - */ -Datum -RI_FKey_setdefault_upd(PG_FUNCTION_ARGS) -{ /* - * Check that this is a valid trigger call on the right time and event. + * Continues here for no new key values are NULL, or we couldn't decide + * yet. */ - ri_CheckTrigger(fcinfo, "RI_FKey_setdefault_upd", RI_TRIGTYPE_UPDATE); /* - * Share code with DELETE case + * If the original row was inserted by our own transaction, we must fire + * the trigger whether or not the keys are equal. This is because our + * UPDATE will invalidate the INSERT so that the INSERT RI trigger will + * not do anything; so we had better do the UPDATE check. (We could skip + * this if we knew the INSERT trigger already fired, but there is no easy + * way to know that.) */ - return ri_setdefault((TriggerData *) fcinfo->context); + xminDatum = slot_getsysattr(oldslot, MinTransactionIdAttributeNumber, &isnull); + Assert(!isnull); + xmin = DatumGetTransactionId(xminDatum); + if (TransactionIdIsCurrentTransactionId(xmin)) + return true; + + /* If all old and new key values are equal, no check is needed */ + if (ri_KeysEqual(fk_rel, oldslot, newslot, riinfo, false)) + return false; + + /* Else we need to fire the trigger. */ + return true; } -/* ---------- - * ri_setdefault - +/* + * RI_Initial_Check - * - * Common code for ON DELETE SET DEFAULT and ON UPDATE SET DEFAULT - * ---------- + * Check an entire table for non-matching values using a single query. + * This is not a trigger procedure, but is called during ALTER TABLE + * ADD FOREIGN KEY to validate the initial table contents. + * + * We expect that the caller has made provision to prevent any problems + * caused by concurrent actions. This could be either by locking rel and + * pkrel at ShareRowExclusiveLock or higher, or by otherwise ensuring + * that triggers implementing the checks are already active. + * Hence, we do not need to lock individual rows for the check. + * + * If the check fails because the current user doesn't have permissions + * to read both tables, return false to let our caller know that they will + * need to do something else to check the constraint. */ -static Datum -ri_setdefault(TriggerData *trigdata) +bool +RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) { const RI_ConstraintInfo *riinfo; - Relation fk_rel; - Relation pk_rel; - HeapTuple old_row; - RI_QueryKey qkey; + StringInfoData querybuf; + char pkrelname[MAX_QUOTED_REL_NAME_LEN]; + char fkrelname[MAX_QUOTED_REL_NAME_LEN]; + char pkattname[MAX_QUOTED_NAME_LEN + 3]; + char fkattname[MAX_QUOTED_NAME_LEN + 3]; + RangeTblEntry *pkrte; + RangeTblEntry *fkrte; + const char *sep; + const char *fk_only; + const char *pk_only; + int save_nestlevel; + char workmembuf[32]; + int spi_result; SPIPlanPtr qplan; - /* - * Get arguments. - */ - riinfo = ri_FetchConstraintInfo(trigdata->tg_trigger, - trigdata->tg_relation, true); + riinfo = ri_FetchConstraintInfo(trigger, fk_rel, false); /* - * Get the relation descriptors of the FK and PK tables and the old tuple. + * Check to make sure current user has enough permissions to do the test + * query. (If not, caller can fall back to the trigger method, which + * works because it changes user IDs on the fly.) * - * fk_rel is opened in RowExclusiveLock mode since that's what our - * eventual UPDATE will get on it. + * XXX are there any other show-stopper conditions to check? */ - fk_rel = heap_open(riinfo->fk_relid, RowExclusiveLock); - pk_rel = trigdata->tg_relation; - old_row = trigdata->tg_trigtuple; - - switch (riinfo->confmatchtype) - { - /* ---------- - * SQL:2008 15.17 - * General rules 9) a) iii): - * MATCH SIMPLE/FULL - * ... ON DELETE SET DEFAULT - * General rules 10) a) iii): - * MATCH SIMPLE/FULL - * ... ON UPDATE SET DEFAULT - * ---------- - */ - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - switch (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true)) - { - case RI_KEYS_ALL_NULL: - case RI_KEYS_SOME_NULL: - - /* - * No check needed - there cannot be any reference to old - * key if it contains a NULL - */ - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); - - case RI_KEYS_NONE_NULL: - - /* - * Have a full qualified key - continue below - */ - break; - } - - /* - * In UPDATE, no need to do anything if old and new keys are equal - */ - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - { - HeapTuple new_row = trigdata->tg_newtuple; - - if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true)) - { - heap_close(fk_rel, RowExclusiveLock); - return PointerGetDatum(NULL); - } - } - - if (SPI_connect() != SPI_OK_CONNECT) - elog(ERROR, "SPI_connect failed"); - - /* - * Fetch or prepare a saved plan for the set default operation - * (it's the same query for delete and update cases) - */ - ri_BuildQueryKey(&qkey, riinfo, RI_PLAN_SETDEFAULT_DOUPDATE); - - if ((qplan = ri_FetchPreparedPlan(&qkey)) == NULL) - { - StringInfoData querybuf; - StringInfoData qualbuf; - char fkrelname[MAX_QUOTED_REL_NAME_LEN]; - char attname[MAX_QUOTED_NAME_LEN]; - char paramname[16]; - const char *querysep; - const char *qualsep; - Oid queryoids[RI_MAX_NUMKEYS]; - const char *fk_only; - int i; - - /* ---------- - * The query string built is - * UPDATE [ONLY] SET fkatt1 = DEFAULT [, ...] - * WHERE $1 = fkatt1 [AND ...] - * The type id's for the $ parameters are those of the - * corresponding PK attributes. - * ---------- - */ - initStringInfo(&querybuf); - initStringInfo(&qualbuf); - quoteRelationName(fkrelname, fk_rel); - fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? - "" : "ONLY "; - appendStringInfo(&querybuf, "UPDATE %s%s SET", - fk_only, fkrelname); - querysep = ""; - qualsep = "WHERE"; - for (i = 0; i < riinfo->nkeys; i++) - { - Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); - Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); - - quoteOneName(attname, - RIAttName(fk_rel, riinfo->fk_attnums[i])); - appendStringInfo(&querybuf, - "%s %s = DEFAULT", - querysep, attname); - sprintf(paramname, "$%d", i + 1); - ri_GenerateQual(&qualbuf, qualsep, - paramname, pk_type, - riinfo->pf_eq_oprs[i], - attname, fk_type); - querysep = ","; - qualsep = "AND"; - queryoids[i] = pk_type; - } - appendStringInfoString(&querybuf, qualbuf.data); + pkrte = makeNode(RangeTblEntry); + pkrte->rtekind = RTE_RELATION; + pkrte->relid = RelationGetRelid(pk_rel); + pkrte->relkind = pk_rel->rd_rel->relkind; + pkrte->rellockmode = AccessShareLock; + pkrte->requiredPerms = ACL_SELECT; - /* Prepare and save the plan */ - qplan = ri_PlanCheck(querybuf.data, riinfo->nkeys, queryoids, - &qkey, fk_rel, pk_rel, true); - } + fkrte = makeNode(RangeTblEntry); + fkrte->rtekind = RTE_RELATION; + fkrte->relid = RelationGetRelid(fk_rel); + fkrte->relkind = fk_rel->rd_rel->relkind; + fkrte->rellockmode = AccessShareLock; + fkrte->requiredPerms = ACL_SELECT; - /* - * We have a plan now. Run it to update the existing references. - */ - ri_PerformCheck(riinfo, &qkey, qplan, - fk_rel, pk_rel, - old_row, NULL, - true, /* must detect new rows */ - SPI_OK_UPDATE); + for (int i = 0; i < riinfo->nkeys; i++) + { + int attno; - if (SPI_finish() != SPI_OK_FINISH) - elog(ERROR, "SPI_finish failed"); + attno = riinfo->pk_attnums[i] - FirstLowInvalidHeapAttributeNumber; + pkrte->selectedCols = bms_add_member(pkrte->selectedCols, attno); - heap_close(fk_rel, RowExclusiveLock); + attno = riinfo->fk_attnums[i] - FirstLowInvalidHeapAttributeNumber; + fkrte->selectedCols = bms_add_member(fkrte->selectedCols, attno); + } - /* - * If we just deleted or updated the PK row whose key was equal to - * the FK columns' default values, and a referencing row exists in - * the FK table, we would have updated that row to the same values - * it already had --- and RI_FKey_fk_upd_check_required would - * hence believe no check is necessary. So we need to do another - * lookup now and in case a reference still exists, abort the - * operation. That is already implemented in the NO ACTION - * trigger, so just run it. (This recheck is only needed in the - * SET DEFAULT case, since CASCADE would remove such rows in case - * of a DELETE operation or would change the FK key values in case - * of an UPDATE, while SET NULL is certain to result in rows that - * satisfy the FK constraint.) - */ - return ri_restrict(trigdata, true); + if (!ExecCheckRTPerms(list_make2(fkrte, pkrte), false)) + return false; - /* - * Handle MATCH PARTIAL set default delete or update. - */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - return PointerGetDatum(NULL); + /* + * Also punt if RLS is enabled on either table unless this role has the + * bypassrls right or is the table owner of the table(s) involved which + * have RLS enabled. + */ + if (!has_bypassrls_privilege(GetUserId()) && + ((pk_rel->rd_rel->relrowsecurity && + !pg_class_ownercheck(pkrte->relid, GetUserId())) || + (fk_rel->rd_rel->relrowsecurity && + !pg_class_ownercheck(fkrte->relid, GetUserId())))) + return false; - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; + /*---------- + * The query string built is: + * SELECT fk.keycols FROM [ONLY] relname fk + * LEFT OUTER JOIN [ONLY] pkrelname pk + * ON (pk.pkkeycol1=fk.keycol1 [AND ...]) + * WHERE pk.pkkeycol1 IS NULL AND + * For MATCH SIMPLE: + * (fk.keycol1 IS NOT NULL [AND ...]) + * For MATCH FULL: + * (fk.keycol1 IS NOT NULL [OR ...]) + * + * We attach COLLATE clauses to the operators when comparing columns + * that have different collations. + *---------- + */ + initStringInfo(&querybuf); + appendStringInfoString(&querybuf, "SELECT "); + sep = ""; + for (int i = 0; i < riinfo->nkeys; i++) + { + quoteOneName(fkattname, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + appendStringInfo(&querybuf, "%sfk.%s", sep, fkattname); + sep = ", "; } - /* Never reached */ - return PointerGetDatum(NULL); -} + quoteRelationName(pkrelname, pk_rel); + quoteRelationName(fkrelname, fk_rel); + fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + pk_only = pk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? + "" : "ONLY "; + appendStringInfo(&querybuf, + " FROM %s%s fk LEFT OUTER JOIN %s%s pk ON", + fk_only, fkrelname, pk_only, pkrelname); + strcpy(pkattname, "pk."); + strcpy(fkattname, "fk."); + sep = "("; + for (int i = 0; i < riinfo->nkeys; i++) + { + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); + Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); + Oid pk_coll = RIAttCollation(pk_rel, riinfo->pk_attnums[i]); + Oid fk_coll = RIAttCollation(fk_rel, riinfo->fk_attnums[i]); -/* ---------- - * RI_FKey_pk_upd_check_required - - * - * Check if we really need to fire the RI trigger for an update to a PK - * relation. This is called by the AFTER trigger queue manager to see if - * it can skip queuing an instance of an RI trigger. Returns true if the - * trigger must be fired, false if we can prove the constraint will still - * be satisfied. - * ---------- - */ -bool -RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, - HeapTuple old_row, HeapTuple new_row) -{ - const RI_ConstraintInfo *riinfo; + quoteOneName(pkattname + 3, + RIAttName(pk_rel, riinfo->pk_attnums[i])); + quoteOneName(fkattname + 3, + RIAttName(fk_rel, riinfo->fk_attnums[i])); + ri_GenerateQual(&querybuf, sep, + pkattname, pk_type, + riinfo->pf_eq_oprs[i], + fkattname, fk_type); + if (pk_coll != fk_coll) + ri_GenerateQualCollation(&querybuf, pk_coll); + sep = "AND"; + } /* - * Get arguments. + * It's sufficient to test any one pk attribute for null to detect a join + * failure. */ - riinfo = ri_FetchConstraintInfo(trigger, pk_rel, true); + quoteOneName(pkattname, RIAttName(pk_rel, riinfo->pk_attnums[0])); + appendStringInfo(&querybuf, ") WHERE pk.%s IS NULL AND (", pkattname); - switch (riinfo->confmatchtype) + sep = ""; + for (int i = 0; i < riinfo->nkeys; i++) { - case FKCONSTR_MATCH_SIMPLE: - case FKCONSTR_MATCH_FULL: - - /* - * If any old key value is NULL, the row could not have been - * referenced by an FK row, so no check is needed. - */ - if (ri_NullCheck(RelationGetDescr(pk_rel), old_row, riinfo, true) != RI_KEYS_NONE_NULL) - return false; - - /* If all old and new key values are equal, no check is needed */ - if (ri_KeysEqual(pk_rel, old_row, new_row, riinfo, true)) - return false; + quoteOneName(fkattname, RIAttName(fk_rel, riinfo->fk_attnums[i])); + appendStringInfo(&querybuf, + "%sfk.%s IS NOT NULL", + sep, fkattname); + switch (riinfo->confmatchtype) + { + case FKCONSTR_MATCH_SIMPLE: + sep = " AND "; + break; + case FKCONSTR_MATCH_FULL: + sep = " OR "; + break; + } + } + appendStringInfoChar(&querybuf, ')'); - /* Else we need to fire the trigger. */ - return true; + /* + * Temporarily increase work_mem so that the check query can be executed + * more efficiently. It seems okay to do this because the query is simple + * enough to not use a multiple of work_mem, and one typically would not + * have many large foreign-key validations happening concurrently. So + * this seems to meet the criteria for being considered a "maintenance" + * operation, and accordingly we use maintenance_work_mem. + * + * We use the equivalent of a function SET option to allow the setting to + * persist for exactly the duration of the check query. guc.c also takes + * care of undoing the setting on error. + */ + save_nestlevel = NewGUCNestLevel(); - /* Handle MATCH PARTIAL check. */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - break; + snprintf(workmembuf, sizeof(workmembuf), "%d", maintenance_work_mem); + (void) set_config_option("work_mem", workmembuf, + PGC_USERSET, PGC_S_SESSION, + GUC_ACTION_SAVE, true, 0, false); - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + if (SPI_connect() != SPI_OK_CONNECT) + elog(ERROR, "SPI_connect failed"); - /* Never reached */ - return false; -} + /* + * Generate the plan. We don't need to cache it, and there are no + * arguments to the plan. + */ + qplan = SPI_prepare(querybuf.data, 0, NULL); -/* ---------- - * RI_FKey_fk_upd_check_required - - * - * Check if we really need to fire the RI trigger for an update to an FK - * relation. This is called by the AFTER trigger queue manager to see if - * it can skip queuing an instance of an RI trigger. Returns true if the - * trigger must be fired, false if we can prove the constraint will still - * be satisfied. - * ---------- - */ -bool -RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, - HeapTuple old_row, HeapTuple new_row) -{ - const RI_ConstraintInfo *riinfo; + if (qplan == NULL) + elog(ERROR, "SPI_prepare returned %s for %s", + SPI_result_code_string(SPI_result), querybuf.data); /* - * Get arguments. + * Run the plan. For safety we force a current snapshot to be used. (In + * transaction-snapshot mode, this arguably violates transaction isolation + * rules, but we really haven't got much choice.) We don't need to + * register the snapshot, because SPI_execute_snapshot will see to it. We + * need at most one tuple returned, so pass limit = 1. */ - riinfo = ri_FetchConstraintInfo(trigger, fk_rel, false); - - switch (riinfo->confmatchtype) - { - case FKCONSTR_MATCH_SIMPLE: - - /* - * If any new key value is NULL, the row must satisfy the - * constraint, so no check is needed. - */ - if (ri_NullCheck(RelationGetDescr(fk_rel), new_row, riinfo, false) != RI_KEYS_NONE_NULL) - return false; + spi_result = SPI_execute_snapshot(qplan, + NULL, NULL, + GetLatestSnapshot(), + InvalidSnapshot, + true, false, 1); - /* - * If the original row was inserted by our own transaction, we - * must fire the trigger whether or not the keys are equal. This - * is because our UPDATE will invalidate the INSERT so that the - * INSERT RI trigger will not do anything; so we had better do the - * UPDATE check. (We could skip this if we knew the INSERT - * trigger already fired, but there is no easy way to know that.) - */ - if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(old_row->t_data))) - return true; + /* Check result */ + if (spi_result != SPI_OK_SELECT) + elog(ERROR, "SPI_execute_snapshot returned %s", SPI_result_code_string(spi_result)); - /* If all old and new key values are equal, no check is needed */ - if (ri_KeysEqual(fk_rel, old_row, new_row, riinfo, false)) - return false; + /* Did we find a tuple violating the constraint? */ + if (SPI_processed > 0) + { + TupleTableSlot *slot; + HeapTuple tuple = SPI_tuptable->vals[0]; + TupleDesc tupdesc = SPI_tuptable->tupdesc; + RI_ConstraintInfo fake_riinfo; - /* Else we need to fire the trigger. */ - return true; + slot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual); - case FKCONSTR_MATCH_FULL: + heap_deform_tuple(tuple, tupdesc, + slot->tts_values, slot->tts_isnull); + ExecStoreVirtualTuple(slot); - /* - * If all new key values are NULL, the row must satisfy the - * constraint, so no check is needed. On the other hand, if only - * some of them are NULL, the row must fail the constraint. We - * must not throw error here, because the row might get - * invalidated before the constraint is to be checked, but we - * should queue the event to apply the check later. - */ - switch (ri_NullCheck(RelationGetDescr(fk_rel), new_row, riinfo, false)) - { - case RI_KEYS_ALL_NULL: - return false; - case RI_KEYS_SOME_NULL: - return true; - case RI_KEYS_NONE_NULL: - break; /* continue with the check */ - } + /* + * The columns to look at in the result tuple are 1..N, not whatever + * they are in the fk_rel. Hack up riinfo so that the subroutines + * called here will behave properly. + * + * In addition to this, we have to pass the correct tupdesc to + * ri_ReportViolation, overriding its normal habit of using the pk_rel + * or fk_rel's tupdesc. + */ + memcpy(&fake_riinfo, riinfo, sizeof(RI_ConstraintInfo)); + for (int i = 0; i < fake_riinfo.nkeys; i++) + fake_riinfo.fk_attnums[i] = i + 1; - /* - * If the original row was inserted by our own transaction, we - * must fire the trigger whether or not the keys are equal. This - * is because our UPDATE will invalidate the INSERT so that the - * INSERT RI trigger will not do anything; so we had better do the - * UPDATE check. (We could skip this if we knew the INSERT - * trigger already fired, but there is no easy way to know that.) - */ - if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmin(old_row->t_data))) - return true; + /* + * If it's MATCH FULL, and there are any nulls in the FK keys, + * complain about that rather than the lack of a match. MATCH FULL + * disallows partially-null FK rows. + */ + if (fake_riinfo.confmatchtype == FKCONSTR_MATCH_FULL && + ri_NullCheck(tupdesc, slot, &fake_riinfo, false) != RI_KEYS_NONE_NULL) + ereport(ERROR, + (errcode(ERRCODE_FOREIGN_KEY_VIOLATION), + errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"", + RelationGetRelationName(fk_rel), + NameStr(fake_riinfo.conname)), + errdetail("MATCH FULL does not allow mixing of null and nonnull key values."), + errtableconstraint(fk_rel, + NameStr(fake_riinfo.conname)))); - /* If all old and new key values are equal, no check is needed */ - if (ri_KeysEqual(fk_rel, old_row, new_row, riinfo, false)) - return false; + /* + * We tell ri_ReportViolation we were doing the RI_PLAN_CHECK_LOOKUPPK + * query, which isn't true, but will cause it to use + * fake_riinfo.fk_attnums as we need. + */ + ri_ReportViolation(&fake_riinfo, + pk_rel, fk_rel, + slot, tupdesc, + RI_PLAN_CHECK_LOOKUPPK, false); - /* Else we need to fire the trigger. */ - return true; + ExecDropSingleTupleTableSlot(slot); + } - /* Handle MATCH PARTIAL check. */ - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - break; + if (SPI_finish() != SPI_OK_FINISH) + elog(ERROR, "SPI_finish failed"); - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; - } + /* + * Restore work_mem. + */ + AtEOXact_GUC(true, save_nestlevel); - /* Never reached */ - return false; + return true; } -/* ---------- - * RI_Initial_Check - - * - * Check an entire table for non-matching values using a single query. - * This is not a trigger procedure, but is called during ALTER TABLE - * ADD FOREIGN KEY to validate the initial table contents. - * - * We expect that the caller has made provision to prevent any problems - * caused by concurrent actions. This could be either by locking rel and - * pkrel at ShareRowExclusiveLock or higher, or by otherwise ensuring - * that triggers implementing the checks are already active. - * Hence, we do not need to lock individual rows for the check. +/* + * RI_PartitionRemove_Check - * - * If the check fails because the current user doesn't have permissions - * to read both tables, return false to let our caller know that they will - * need to do something else to check the constraint. - * ---------- + * Verify no referencing values exist, when a partition is detached on + * the referenced side of a foreign key constraint. */ -bool -RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) +void +RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) { const RI_ConstraintInfo *riinfo; StringInfoData querybuf; + char *constraintDef; char pkrelname[MAX_QUOTED_REL_NAME_LEN]; char fkrelname[MAX_QUOTED_REL_NAME_LEN]; char pkattname[MAX_QUOTED_NAME_LEN + 3]; char fkattname[MAX_QUOTED_NAME_LEN + 3]; - RangeTblEntry *pkrte; - RangeTblEntry *fkrte; const char *sep; const char *fk_only; - int i; int save_nestlevel; char workmembuf[32]; int spi_result; SPIPlanPtr qplan; + int i; - /* Fetch constraint info. */ riinfo = ri_FetchConstraintInfo(trigger, fk_rel, false); /* - * Check to make sure current user has enough permissions to do the test - * query. (If not, caller can fall back to the trigger method, which - * works because it changes user IDs on the fly.) - * - * XXX are there any other show-stopper conditions to check? - */ - pkrte = makeNode(RangeTblEntry); - pkrte->rtekind = RTE_RELATION; - pkrte->relid = RelationGetRelid(pk_rel); - pkrte->relkind = pk_rel->rd_rel->relkind; - pkrte->requiredPerms = ACL_SELECT; - - fkrte = makeNode(RangeTblEntry); - fkrte->rtekind = RTE_RELATION; - fkrte->relid = RelationGetRelid(fk_rel); - fkrte->relkind = fk_rel->rd_rel->relkind; - fkrte->requiredPerms = ACL_SELECT; - - for (i = 0; i < riinfo->nkeys; i++) - { - int attno; - - attno = riinfo->pk_attnums[i] - FirstLowInvalidHeapAttributeNumber; - pkrte->selectedCols = bms_add_member(pkrte->selectedCols, attno); - - attno = riinfo->fk_attnums[i] - FirstLowInvalidHeapAttributeNumber; - fkrte->selectedCols = bms_add_member(fkrte->selectedCols, attno); - } - - if (!ExecCheckRTPerms(list_make2(fkrte, pkrte), false)) - return false; - - /* - * Also punt if RLS is enabled on either table unless this role has the - * bypassrls right or is the table owner of the table(s) involved which - * have RLS enabled. + * We don't check permissions before displaying the error message, on the + * assumption that the user detaching the partition must have enough + * privileges to examine the table contents anyhow. */ - if (!has_bypassrls_privilege(GetUserId()) && - ((pk_rel->rd_rel->relrowsecurity && - !pg_class_ownercheck(pkrte->relid, GetUserId())) || - (fk_rel->rd_rel->relrowsecurity && - !pg_class_ownercheck(fkrte->relid, GetUserId())))) - return false; /*---------- * The query string built is: - * SELECT fk.keycols FROM [ONLY] relname fk - * LEFT OUTER JOIN ONLY pkrelname pk - * ON (pk.pkkeycol1=fk.keycol1 [AND ...]) - * WHERE pk.pkkeycol1 IS NULL AND + * SELECT fk.keycols FROM [ONLY] relname fk + * JOIN pkrelname pk + * ON (pk.pkkeycol1=fk.keycol1 [AND ...]) + * WHERE () AND * For MATCH SIMPLE: - * (fk.keycol1 IS NOT NULL [AND ...]) + * (fk.keycol1 IS NOT NULL [AND ...]) * For MATCH FULL: - * (fk.keycol1 IS NOT NULL [OR ...]) + * (fk.keycol1 IS NOT NULL [OR ...]) * * We attach COLLATE clauses to the operators when comparing columns * that have different collations. @@ -1943,9 +1625,8 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) fk_only = fk_rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY "; appendStringInfo(&querybuf, - " FROM %s%s fk LEFT OUTER JOIN ONLY %s pk ON", + " FROM %s%s fk JOIN %s pk ON", fk_only, fkrelname, pkrelname); - strcpy(pkattname, "pk."); strcpy(fkattname, "fk."); sep = "("; @@ -1970,11 +1651,16 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) } /* - * It's sufficient to test any one pk attribute for null to detect a join - * failure. + * Start the WHERE clause with the partition constraint (except if this is + * the default partition and there's no other partition, because the + * partition constraint is the empty string in that case.) */ - quoteOneName(pkattname, RIAttName(pk_rel, riinfo->pk_attnums[0])); - appendStringInfo(&querybuf, ") WHERE pk.%s IS NULL AND (", pkattname); + constraintDef = pg_get_partconstrdef_string(RelationGetRelid(pk_rel), "pk"); + if (constraintDef && constraintDef[0] != '\0') + appendStringInfo(&querybuf, ") WHERE %s AND (", + constraintDef); + else + appendStringInfo(&querybuf, ") WHERE ("); sep = ""; for (i = 0; i < riinfo->nkeys; i++) @@ -1991,15 +1677,6 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) case FKCONSTR_MATCH_FULL: sep = " OR "; break; - case FKCONSTR_MATCH_PARTIAL: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("MATCH PARTIAL not yet implemented"))); - break; - default: - elog(ERROR, "unrecognized confmatchtype: %d", - riinfo->confmatchtype); - break; } } appendStringInfoChar(&querybuf, ')'); @@ -2053,17 +1730,24 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) if (spi_result != SPI_OK_SELECT) elog(ERROR, "SPI_execute_snapshot returned %s", SPI_result_code_string(spi_result)); - /* Did we find a tuple violating the constraint? */ + /* Did we find a tuple that would violate the constraint? */ if (SPI_processed > 0) { + TupleTableSlot *slot; HeapTuple tuple = SPI_tuptable->vals[0]; TupleDesc tupdesc = SPI_tuptable->tupdesc; RI_ConstraintInfo fake_riinfo; + slot = MakeSingleTupleTableSlot(tupdesc, &TTSOpsVirtual); + + heap_deform_tuple(tuple, tupdesc, + slot->tts_values, slot->tts_isnull); + ExecStoreVirtualTuple(slot); + /* * The columns to look at in the result tuple are 1..N, not whatever - * they are in the fk_rel. Hack up riinfo so that the subroutines - * called here will behave properly. + * they are in the fk_rel. Hack up riinfo so that ri_ReportViolation + * will behave properly. * * In addition to this, we have to pass the correct tupdesc to * ri_ReportViolation, overriding its normal habit of using the pk_rel @@ -2071,33 +1755,10 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) */ memcpy(&fake_riinfo, riinfo, sizeof(RI_ConstraintInfo)); for (i = 0; i < fake_riinfo.nkeys; i++) - fake_riinfo.fk_attnums[i] = i + 1; - - /* - * If it's MATCH FULL, and there are any nulls in the FK keys, - * complain about that rather than the lack of a match. MATCH FULL - * disallows partially-null FK rows. - */ - if (fake_riinfo.confmatchtype == FKCONSTR_MATCH_FULL && - ri_NullCheck(tupdesc, tuple, &fake_riinfo, false) != RI_KEYS_NONE_NULL) - ereport(ERROR, - (errcode(ERRCODE_FOREIGN_KEY_VIOLATION), - errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"", - RelationGetRelationName(fk_rel), - NameStr(fake_riinfo.conname)), - errdetail("MATCH FULL does not allow mixing of null and nonnull key values."), - errtableconstraint(fk_rel, - NameStr(fake_riinfo.conname)))); + fake_riinfo.pk_attnums[i] = i + 1; - /* - * We tell ri_ReportViolation we were doing the RI_PLAN_CHECK_LOOKUPPK - * query, which isn't true, but will cause it to use - * fake_riinfo.fk_attnums as we need. - */ - ri_ReportViolation(&fake_riinfo, - pk_rel, fk_rel, - tuple, tupdesc, - RI_PLAN_CHECK_LOOKUPPK); + ri_ReportViolation(&fake_riinfo, pk_rel, fk_rel, + slot, tupdesc, 0, true); } if (SPI_finish() != SPI_OK_FINISH) @@ -2107,8 +1768,6 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel) * Restore work_mem. */ AtEOXact_GUC(true, save_nestlevel); - - return true; } @@ -2320,6 +1979,24 @@ ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk) elog(ERROR, "wrong pg_constraint entry for trigger \"%s\" on table \"%s\"", trigger->tgname, RelationGetRelationName(trig_rel)); } + else + { + if (riinfo->fk_relid != RelationGetRelid(trig_rel) || + riinfo->pk_relid != trigger->tgconstrrelid) + elog(ERROR, "wrong pg_constraint entry for trigger \"%s\" on table \"%s\"", + trigger->tgname, RelationGetRelationName(trig_rel)); + } + + if (riinfo->confmatchtype != FKCONSTR_MATCH_FULL && + riinfo->confmatchtype != FKCONSTR_MATCH_PARTIAL && + riinfo->confmatchtype != FKCONSTR_MATCH_SIMPLE) + elog(ERROR, "unrecognized confmatchtype: %d", + riinfo->confmatchtype); + + if (riinfo->confmatchtype == FKCONSTR_MATCH_PARTIAL) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("MATCH PARTIAL not yet implemented"))); return riinfo; } @@ -2334,10 +2011,6 @@ ri_LoadConstraintInfo(Oid constraintOid) bool found; HeapTuple tup; Form_pg_constraint conForm; - Datum adatum; - bool isNull; - ArrayType *arr; - int numkeys; /* * On the first call initialize the hashtable @@ -2379,84 +2052,13 @@ ri_LoadConstraintInfo(Oid constraintOid) riinfo->confdeltype = conForm->confdeltype; riinfo->confmatchtype = conForm->confmatchtype; - /* - * We expect the arrays to be 1-D arrays of the right types; verify that. - * We don't need to use deconstruct_array() since the array data is just - * going to look like a C array of values. - */ - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conkey, &isNull); - if (isNull) - elog(ERROR, "null conkey for constraint %u", constraintOid); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - if (ARR_NDIM(arr) != 1 || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "conkey is not a 1-D smallint array"); - numkeys = ARR_DIMS(arr)[0]; - if (numkeys <= 0 || numkeys > RI_MAX_NUMKEYS) - elog(ERROR, "foreign key constraint cannot have %d columns", numkeys); - riinfo->nkeys = numkeys; - memcpy(riinfo->fk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16)); - if ((Pointer) arr != DatumGetPointer(adatum)) - pfree(arr); /* free de-toasted copy, if any */ - - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_confkey, &isNull); - if (isNull) - elog(ERROR, "null confkey for constraint %u", constraintOid); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - if (ARR_NDIM(arr) != 1 || - ARR_DIMS(arr)[0] != numkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "confkey is not a 1-D smallint array"); - memcpy(riinfo->pk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16)); - if ((Pointer) arr != DatumGetPointer(adatum)) - pfree(arr); /* free de-toasted copy, if any */ - - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conpfeqop, &isNull); - if (isNull) - elog(ERROR, "null conpfeqop for constraint %u", constraintOid); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - /* see TryReuseForeignKey if you change the test below */ - if (ARR_NDIM(arr) != 1 || - ARR_DIMS(arr)[0] != numkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conpfeqop is not a 1-D Oid array"); - memcpy(riinfo->pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); - if ((Pointer) arr != DatumGetPointer(adatum)) - pfree(arr); /* free de-toasted copy, if any */ - - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conppeqop, &isNull); - if (isNull) - elog(ERROR, "null conppeqop for constraint %u", constraintOid); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - if (ARR_NDIM(arr) != 1 || - ARR_DIMS(arr)[0] != numkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conppeqop is not a 1-D Oid array"); - memcpy(riinfo->pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); - if ((Pointer) arr != DatumGetPointer(adatum)) - pfree(arr); /* free de-toasted copy, if any */ - - adatum = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conffeqop, &isNull); - if (isNull) - elog(ERROR, "null conffeqop for constraint %u", constraintOid); - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - if (ARR_NDIM(arr) != 1 || - ARR_DIMS(arr)[0] != numkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conffeqop is not a 1-D Oid array"); - memcpy(riinfo->ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid)); - if ((Pointer) arr != DatumGetPointer(adatum)) - pfree(arr); /* free de-toasted copy, if any */ + DeconstructFkConstraintRow(tup, + &riinfo->nkeys, + riinfo->fk_attnums, + riinfo->pk_attnums, + riinfo->pf_eq_oprs, + riinfo->pp_eq_oprs, + riinfo->ff_eq_oprs); ReleaseSysCache(tup); @@ -2575,7 +2177,7 @@ static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, RI_QueryKey *qkey, SPIPlanPtr qplan, Relation fk_rel, Relation pk_rel, - HeapTuple old_tuple, HeapTuple new_tuple, + TupleTableSlot *oldslot, TupleTableSlot *newslot, bool detectNewRows, int expect_OK) { Relation query_rel, @@ -2618,17 +2220,17 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, } /* Extract the parameters to be passed into the query */ - if (new_tuple) + if (newslot) { - ri_ExtractValues(source_rel, new_tuple, riinfo, source_is_pk, + ri_ExtractValues(source_rel, newslot, riinfo, source_is_pk, vals, nulls); - if (old_tuple) - ri_ExtractValues(source_rel, old_tuple, riinfo, source_is_pk, + if (oldslot) + ri_ExtractValues(source_rel, oldslot, riinfo, source_is_pk, vals + riinfo->nkeys, nulls + riinfo->nkeys); } else { - ri_ExtractValues(source_rel, old_tuple, riinfo, source_is_pk, + ri_ExtractValues(source_rel, oldslot, riinfo, source_is_pk, vals, nulls); } @@ -2698,9 +2300,9 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, (SPI_processed == 0) == (qkey->constr_queryno == RI_PLAN_CHECK_LOOKUPPK)) ri_ReportViolation(riinfo, pk_rel, fk_rel, - new_tuple ? new_tuple : old_tuple, + newslot ? newslot : oldslot, NULL, - qkey->constr_queryno); + qkey->constr_queryno, false); return SPI_processed != 0; } @@ -2709,13 +2311,11 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo, * Extract fields from a tuple into Datum/nulls arrays */ static void -ri_ExtractValues(Relation rel, HeapTuple tup, +ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, Datum *vals, char *nulls) { - TupleDesc tupdesc = rel->rd_att; const int16 *attnums; - int i; bool isnull; if (rel_is_pk) @@ -2723,10 +2323,9 @@ ri_ExtractValues(Relation rel, HeapTuple tup, else attnums = riinfo->fk_attnums; - for (i = 0; i < riinfo->nkeys; i++) + for (int i = 0; i < riinfo->nkeys; i++) { - vals[i] = heap_getattr(tup, attnums[i], tupdesc, - &isnull); + vals[i] = slot_getattr(slot, attnums[i], &isnull); nulls[i] = isnull ? 'n' : ' '; } } @@ -2743,14 +2342,13 @@ ri_ExtractValues(Relation rel, HeapTuple tup, static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, - HeapTuple violator, TupleDesc tupdesc, - int queryno) + TupleTableSlot *violatorslot, TupleDesc tupdesc, + int queryno, bool partgone) { StringInfoData key_names; StringInfoData key_values; bool onfk; const int16 *attnums; - int idx; Oid rel_oid; AclResult aclresult; bool has_perm = true; @@ -2784,15 +2382,19 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo, * * Check table-level permissions next and, failing that, column-level * privileges. + * + * When a partition at the referenced side is being detached/dropped, we + * needn't check, since the user must be the table owner anyway. */ - - if (check_enable_rls(rel_oid, InvalidOid, true) != RLS_ENABLED) + if (partgone) + has_perm = true; + else if (check_enable_rls(rel_oid, InvalidOid, true) != RLS_ENABLED) { aclresult = pg_class_aclcheck(rel_oid, GetUserId(), ACL_SELECT); if (aclresult != ACLCHECK_OK) { /* Try for column-level permissions */ - for (idx = 0; idx < riinfo->nkeys; idx++) + for (int idx = 0; idx < riinfo->nkeys; idx++) { aclresult = pg_attribute_aclcheck(rel_oid, attnums[idx], GetUserId(), @@ -2815,15 +2417,27 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo, /* Get printable versions of the keys involved */ initStringInfo(&key_names); initStringInfo(&key_values); - for (idx = 0; idx < riinfo->nkeys; idx++) + for (int idx = 0; idx < riinfo->nkeys; idx++) { int fnum = attnums[idx]; + Form_pg_attribute att = TupleDescAttr(tupdesc, fnum - 1); char *name, *val; + Datum datum; + bool isnull; + + name = NameStr(att->attname); - name = SPI_fname(tupdesc, fnum); - val = SPI_getvalue(violator, tupdesc, fnum); - if (!val) + datum = slot_getattr(violatorslot, fnum, &isnull); + if (!isnull) + { + Oid foutoid; + bool typisvarlena; + + getTypeOutputInfo(att->atttypid, &foutoid, &typisvarlena); + val = OidOutputFunctionCall(foutoid, datum); + } + else val = "null"; if (idx > 0) @@ -2836,7 +2450,16 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo, } } - if (onfk) + if (partgone) + ereport(ERROR, + (errcode(ERRCODE_FOREIGN_KEY_VIOLATION), + errmsg("removing partition \"%s\" violates foreign key constraint \"%s\"", + RelationGetRelationName(pk_rel), + NameStr(riinfo->conname)), + errdetail("Key (%s)=(%s) is still referenced from table \"%s\".", + key_names.data, key_values.data, + RelationGetRelationName(fk_rel)))); + else if (onfk) ereport(ERROR, (errcode(ERRCODE_FOREIGN_KEY_VIOLATION), errmsg("insert or update on table \"%s\" violates foreign key constraint \"%s\"", @@ -2866,21 +2489,19 @@ ri_ReportViolation(const RI_ConstraintInfo *riinfo, } -/* ---------- +/* * ri_NullCheck - * - * Determine the NULL state of all key values in a tuple + * Determine the NULL state of all key values in a tuple * - * Returns one of RI_KEYS_ALL_NULL, RI_KEYS_NONE_NULL or RI_KEYS_SOME_NULL. - * ---------- + * Returns one of RI_KEYS_ALL_NULL, RI_KEYS_NONE_NULL or RI_KEYS_SOME_NULL. */ static int ri_NullCheck(TupleDesc tupDesc, - HeapTuple tup, + TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk) { const int16 *attnums; - int i; bool allnull = true; bool nonenull = true; @@ -2889,9 +2510,9 @@ ri_NullCheck(TupleDesc tupDesc, else attnums = riinfo->fk_attnums; - for (i = 0; i < riinfo->nkeys; i++) + for (int i = 0; i < riinfo->nkeys; i++) { - if (heap_attisnull(tup, attnums[i], tupDesc)) + if (slot_attisnull(slot, attnums[i])) nonenull = false; else allnull = false; @@ -2907,11 +2528,10 @@ ri_NullCheck(TupleDesc tupDesc, } -/* ---------- +/* * ri_InitHashTables - * - * Initialize our internal hash tables. - * ---------- + * Initialize our internal hash tables. */ static void ri_InitHashTables(void) @@ -2946,12 +2566,11 @@ ri_InitHashTables(void) } -/* ---------- +/* * ri_FetchPreparedPlan - * - * Lookup for a query key in our private hash table of prepared - * and saved SPI execution plans. Return the plan if found or NULL. - * ---------- + * Lookup for a query key in our private hash table of prepared + * and saved SPI execution plans. Return the plan if found or NULL. */ static SPIPlanPtr ri_FetchPreparedPlan(RI_QueryKey *key) @@ -3000,11 +2619,10 @@ ri_FetchPreparedPlan(RI_QueryKey *key) } -/* ---------- +/* * ri_HashPreparedPlan - * - * Add another plan to our private SPI query plan hashtable. - * ---------- + * Add another plan to our private SPI query plan hashtable. */ static void ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan) @@ -3030,38 +2648,29 @@ ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan) } -/* ---------- +/* * ri_KeysEqual - * - * Check if all key values in OLD and NEW are equal. + * Check if all key values in OLD and NEW are equal. * - * Note: at some point we might wish to redefine this as checking for - * "IS NOT DISTINCT" rather than "=", that is, allow two nulls to be - * considered equal. Currently there is no need since all callers have - * previously found at least one of the rows to contain no nulls. - * ---------- + * Note: at some point we might wish to redefine this as checking for + * "IS NOT DISTINCT" rather than "=", that is, allow two nulls to be + * considered equal. Currently there is no need since all callers have + * previously found at least one of the rows to contain no nulls. */ static bool -ri_KeysEqual(Relation rel, HeapTuple oldtup, HeapTuple newtup, +ri_KeysEqual(Relation rel, TupleTableSlot *oldslot, TupleTableSlot *newslot, const RI_ConstraintInfo *riinfo, bool rel_is_pk) { - TupleDesc tupdesc = RelationGetDescr(rel); const int16 *attnums; - const Oid *eq_oprs; - int i; if (rel_is_pk) - { attnums = riinfo->pk_attnums; - eq_oprs = riinfo->pp_eq_oprs; - } else - { attnums = riinfo->fk_attnums; - eq_oprs = riinfo->ff_eq_oprs; - } - for (i = 0; i < riinfo->nkeys; i++) + /* XXX: could be worthwhile to fetch all necessary attrs at once */ + for (int i = 0; i < riinfo->nkeys; i++) { Datum oldvalue; Datum newvalue; @@ -3070,36 +2679,55 @@ ri_KeysEqual(Relation rel, HeapTuple oldtup, HeapTuple newtup, /* * Get one attribute's oldvalue. If it is NULL - they're not equal. */ - oldvalue = heap_getattr(oldtup, attnums[i], tupdesc, &isnull); + oldvalue = slot_getattr(oldslot, attnums[i], &isnull); if (isnull) return false; /* * Get one attribute's newvalue. If it is NULL - they're not equal. */ - newvalue = heap_getattr(newtup, attnums[i], tupdesc, &isnull); + newvalue = slot_getattr(newslot, attnums[i], &isnull); if (isnull) return false; - /* - * Compare them with the appropriate equality operator. - */ - if (!ri_AttributesEqual(eq_oprs[i], RIAttType(rel, attnums[i]), - oldvalue, newvalue)) - return false; + if (rel_is_pk) + { + /* + * If we are looking at the PK table, then do a bytewise + * comparison. We must propagate PK changes if the value is + * changed to one that "looks" different but would compare as + * equal using the equality operator. This only makes a + * difference for ON UPDATE CASCADE, but for consistency we treat + * all changes to the PK the same. + */ + Form_pg_attribute att = TupleDescAttr(oldslot->tts_tupleDescriptor, attnums[i] - 1); + + if (!datum_image_eq(oldvalue, newvalue, att->attbyval, att->attlen)) + return false; + } + else + { + /* + * For the FK table, compare with the appropriate equality + * operator. Changes that compare equal will still satisfy the + * constraint after the update. + */ + if (!ri_AttributesEqual(riinfo->ff_eq_oprs[i], RIAttType(rel, attnums[i]), + oldvalue, newvalue)) + return false; + } } return true; } -/* ---------- +/* * ri_AttributesEqual - * - * Call the appropriate equality comparison operator for two values. + * Call the appropriate equality comparison operator for two values. * - * NB: we have already checked that neither value is null. - * ---------- + * NB: we have already checked that neither value is null. */ static bool ri_AttributesEqual(Oid eq_opr, Oid typeid, @@ -3121,19 +2749,27 @@ ri_AttributesEqual(Oid eq_opr, Oid typeid, } /* - * Apply the comparison operator. We assume it doesn't care about - * collations. - */ - return DatumGetBool(FunctionCall2(&entry->eq_opr_finfo, - oldvalue, newvalue)); + * Apply the comparison operator. + * + * Note: This function is part of a call stack that determines whether an + * update to a row is significant enough that it needs checking or action + * on the other side of a foreign-key constraint. Therefore, the + * comparison here would need to be done with the collation of the *other* + * table. For simplicity (e.g., we might not even have the other table + * open), we'll just use the default collation here, which could lead to + * some false negatives. All this would break if we ever allow + * database-wide collations to be nondeterministic. + */ + return DatumGetBool(FunctionCall2Coll(&entry->eq_opr_finfo, + DEFAULT_COLLATION_OID, + oldvalue, newvalue)); } -/* ---------- +/* * ri_HashCompareOp - * - * See if we know how to compare two values, and create a new hash entry - * if not. - * ---------- + * See if we know how to compare two values, and create a new hash entry + * if not. */ static RI_CompareHashEntry * ri_HashCompareOp(Oid eq_opr, Oid typeid) diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c index 5f729342f8d..ea3e40a3694 100644 --- a/src/backend/utils/adt/rowtypes.c +++ b/src/backend/utils/adt/rowtypes.c @@ -3,7 +3,7 @@ * rowtypes.c * I/O and comparison functions for generic composite types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,13 +16,14 @@ #include +#include "access/detoast.h" #include "access/htup_details.h" -#include "access/tuptoaster.h" #include "catalog/pg_type.h" #include "funcapi.h" #include "libpq/pqformat.h" #include "miscadmin.h" #include "utils/builtins.h" +#include "utils/datum.h" #include "utils/lsyscache.h" #include "utils/typcache.h" @@ -942,7 +943,7 @@ record_cmp(FunctionCallInfo fcinfo) */ if (!nulls1[i1] || !nulls2[i2]) { - FunctionCallInfoData locfcinfo; + LOCAL_FCINFO(locfcinfo, 2); int32 cmpresult; if (nulls1[i1]) @@ -959,14 +960,14 @@ record_cmp(FunctionCallInfo fcinfo) } /* Compare the pair of elements */ - InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->cmp_proc_finfo, 2, collation, NULL, NULL); - locfcinfo.arg[0] = values1[i1]; - locfcinfo.arg[1] = values2[i2]; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - cmpresult = DatumGetInt32(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = values1[i1]; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = values2[i2]; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + cmpresult = DatumGetInt32(FunctionCallInvoke(locfcinfo)); if (cmpresult < 0) { @@ -1119,11 +1120,11 @@ record_eq(PG_FUNCTION_ARGS) i1 = i2 = j = 0; while (i1 < ncolumns1 || i2 < ncolumns2) { + LOCAL_FCINFO(locfcinfo, 2); Form_pg_attribute att1; Form_pg_attribute att2; TypeCacheEntry *typentry; Oid collation; - FunctionCallInfoData locfcinfo; bool oprresult; /* @@ -1193,14 +1194,14 @@ record_eq(PG_FUNCTION_ARGS) } /* Compare the pair of elements */ - InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2, + InitFunctionCallInfoData(*locfcinfo, &typentry->eq_opr_finfo, 2, collation, NULL, NULL); - locfcinfo.arg[0] = values1[i1]; - locfcinfo.arg[1] = values2[i2]; - locfcinfo.argnull[0] = false; - locfcinfo.argnull[1] = false; - locfcinfo.isnull = false; - oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo)); + locfcinfo->args[0].value = values1[i1]; + locfcinfo->args[0].isnull = false; + locfcinfo->args[1].value = values2[i2]; + locfcinfo->args[1].isnull = false; + locfcinfo->isnull = false; + oprresult = DatumGetBool(FunctionCallInvoke(locfcinfo)); if (!oprresult) { result = false; @@ -1671,45 +1672,7 @@ record_image_eq(PG_FUNCTION_ARGS) } /* Compare the pair of elements */ - if (att1->attlen == -1) - { - Size len1, - len2; - - len1 = toast_raw_datum_size(values1[i1]); - len2 = toast_raw_datum_size(values2[i2]); - /* No need to de-toast if lengths don't match. */ - if (len1 != len2) - result = false; - else - { - struct varlena *arg1val; - struct varlena *arg2val; - - arg1val = PG_DETOAST_DATUM_PACKED(values1[i1]); - arg2val = PG_DETOAST_DATUM_PACKED(values2[i2]); - - result = (memcmp(VARDATA_ANY(arg1val), - VARDATA_ANY(arg2val), - len1 - VARHDRSZ) == 0); - - /* Only free memory if it's a copy made here. */ - if ((Pointer) arg1val != (Pointer) values1[i1]) - pfree(arg1val); - if ((Pointer) arg2val != (Pointer) values2[i2]) - pfree(arg2val); - } - } - else if (att1->attbyval) - { - result = (values1[i1] == values2[i2]); - } - else - { - result = (memcmp(DatumGetPointer(values1[i1]), - DatumGetPointer(values2[i2]), - att1->attlen) == 0); - } + result = datum_image_eq(values1[i1], values2[i2], att1->attbyval, att2->attlen); if (!result) break; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index b75a224ee8c..3e64390d819 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -4,7 +4,7 @@ * Functions to convert stored expressions/querytrees back to * source text * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,10 +21,11 @@ #include "access/amapi.h" #include "access/htup_details.h" +#include "access/relation.h" #include "access/sysattr.h" +#include "access/table.h" #include "catalog/dependency.h" #include "catalog/indexing.h" -#include "catalog/partition.h" #include "catalog/pg_aggregate.h" #include "catalog/pg_am.h" #include "catalog/pg_authid.h" @@ -48,7 +49,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/tlist.h" +#include "optimizer/optimizer.h" #include "parser/parse_node.h" #include "parser/parse_agg.h" #include "parser/parse_func.h" @@ -64,11 +65,11 @@ #include "utils/guc.h" #include "utils/hsearch.h" #include "utils/lsyscache.h" +#include "utils/partcache.h" #include "utils/rel.h" #include "utils/ruleutils.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #include "utils/typcache.h" #include "utils/varlena.h" #include "utils/xml.h" @@ -114,7 +115,7 @@ typedef struct List *windowTList; /* targetlist for resolving WINDOW clause */ int prettyFlags; /* enabling of pretty-print functions */ int wrapColumn; /* max line length, or -1 for no limit */ - int indentLevel; /* current indent level for prettyprint */ + int indentLevel; /* current indent level for pretty-print */ bool varprefix; /* true to print prefixes on Vars */ ParseExprKind special_exprkind; /* set only for exprkinds needing special * handling */ @@ -310,158 +311,159 @@ bool quote_all_identifiers = false; * ---------- */ static char *deparse_expression_pretty(Node *expr, List *dpcontext, - bool forceprefix, bool showimplicit, - int prettyFlags, int startIndent); + bool forceprefix, bool showimplicit, + int prettyFlags, int startIndent); static char *pg_get_viewdef_worker(Oid viewoid, - int prettyFlags, int wrapColumn); + int prettyFlags, int wrapColumn); static char *pg_get_triggerdef_worker(Oid trigid, bool pretty); -static void decompile_column_index_array(Datum column_index_array, Oid relId, - StringInfo buf); +static int decompile_column_index_array(Datum column_index_array, Oid relId, + StringInfo buf); static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags); static char *pg_get_indexdef_worker(Oid indexrelid, int colno, - const Oid *excludeOps, - bool attrsOnly, bool showTblSpc, bool inherits, - int prettyFlags, bool missing_ok); + const Oid *excludeOps, + bool attrsOnly, bool keysOnly, + bool showTblSpc, bool inherits, + int prettyFlags, bool missing_ok); static char *pg_get_statisticsobj_worker(Oid statextid, bool missing_ok); static char *pg_get_partkeydef_worker(Oid relid, int prettyFlags, - bool attrsOnly, bool missing_ok); + bool attrsOnly, bool missing_ok); static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, - int prettyFlags, bool missing_ok); + int prettyFlags, bool missing_ok); static text *pg_get_expr_worker(text *expr, Oid relid, const char *relname, - int prettyFlags); -static int print_function_arguments(StringInfo buf, HeapTuple proctup, - bool print_table_args, bool print_defaults); + int prettyFlags); +static int print_function_arguments(StringInfo buf, HeapTuple proctup, + bool print_table_args, bool print_defaults); static void print_function_rettype(StringInfo buf, HeapTuple proctup); static void print_function_trftypes(StringInfo buf, HeapTuple proctup); static void set_rtable_names(deparse_namespace *dpns, List *parent_namespaces, - Bitmapset *rels_used); + Bitmapset *rels_used); static void set_deparse_for_query(deparse_namespace *dpns, Query *query, - List *parent_namespaces); + List *parent_namespaces); static void set_simple_column_names(deparse_namespace *dpns); static bool has_dangerous_join_using(deparse_namespace *dpns, Node *jtnode); static void set_using_names(deparse_namespace *dpns, Node *jtnode, - List *parentUsing); + List *parentUsing); static void set_relation_column_names(deparse_namespace *dpns, - RangeTblEntry *rte, - deparse_columns *colinfo); + RangeTblEntry *rte, + deparse_columns *colinfo); static void set_join_column_names(deparse_namespace *dpns, RangeTblEntry *rte, - deparse_columns *colinfo); + deparse_columns *colinfo); static bool colname_is_unique(const char *colname, deparse_namespace *dpns, - deparse_columns *colinfo); + deparse_columns *colinfo); static char *make_colname_unique(char *colname, deparse_namespace *dpns, - deparse_columns *colinfo); + deparse_columns *colinfo); static void expand_colnames_array_to(deparse_columns *colinfo, int n); static void identify_join_columns(JoinExpr *j, RangeTblEntry *jrte, - deparse_columns *colinfo); + deparse_columns *colinfo); static void flatten_join_using_qual(Node *qual, - List **leftvars, List **rightvars); + List **leftvars, List **rightvars); static char *get_rtable_name(int rtindex, deparse_context *context); static void set_deparse_planstate(deparse_namespace *dpns, PlanState *ps); static void push_child_plan(deparse_namespace *dpns, PlanState *ps, - deparse_namespace *save_dpns); + deparse_namespace *save_dpns); static void pop_child_plan(deparse_namespace *dpns, - deparse_namespace *save_dpns); + deparse_namespace *save_dpns); static void push_ancestor_plan(deparse_namespace *dpns, ListCell *ancestor_cell, - deparse_namespace *save_dpns); + deparse_namespace *save_dpns); static void pop_ancestor_plan(deparse_namespace *dpns, - deparse_namespace *save_dpns); + deparse_namespace *save_dpns); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, - int prettyFlags); + int prettyFlags); static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, - int prettyFlags, int wrapColumn); + int prettyFlags, int wrapColumn); static void get_query_def(Query *query, StringInfo buf, List *parentnamespace, - TupleDesc resultDesc, - int prettyFlags, int wrapColumn, int startIndent); + TupleDesc resultDesc, + int prettyFlags, int wrapColumn, int startIndent); static void get_values_def(List *values_lists, deparse_context *context); static void get_with_clause(Query *query, deparse_context *context); static void get_select_query_def(Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc); static void get_insert_query_def(Query *query, deparse_context *context); static void get_update_query_def(Query *query, deparse_context *context); static void get_update_query_targetlist_def(Query *query, List *targetList, - deparse_context *context, - RangeTblEntry *rte); + deparse_context *context, + RangeTblEntry *rte); static void get_delete_query_def(Query *query, deparse_context *context); static void get_utility_query_def(Query *query, deparse_context *context); static void get_basic_select_query(Query *query, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc); static void get_target_list(List *targetList, deparse_context *context, - TupleDesc resultDesc); + TupleDesc resultDesc); static void get_setop_query(Node *setOp, Query *query, - deparse_context *context, - TupleDesc resultDesc); + deparse_context *context, + TupleDesc resultDesc); static Node *get_rule_sortgroupclause(Index ref, List *tlist, - bool force_colno, - deparse_context *context); + bool force_colno, + deparse_context *context); static void get_rule_groupingset(GroupingSet *gset, List *targetlist, - bool omit_parens, deparse_context *context); + bool omit_parens, deparse_context *context); static void get_rule_orderby(List *orderList, List *targetList, - bool force_colno, deparse_context *context); + bool force_colno, deparse_context *context); static void get_rule_windowclause(Query *query, deparse_context *context); static void get_rule_windowspec(WindowClause *wc, List *targetList, - deparse_context *context); + deparse_context *context); static char *get_variable(Var *var, int levelsup, bool istoplevel, - deparse_context *context); + deparse_context *context); static void get_special_variable(Node *node, deparse_context *context, - void *private); + void *private); static void resolve_special_varno(Node *node, deparse_context *context, - void *private, - void (*callback) (Node *, deparse_context *, void *)); + void *private, + void (*callback) (Node *, deparse_context *, void *)); static Node *find_param_referent(Param *param, deparse_context *context, - deparse_namespace **dpns_p, ListCell **ancestor_cell_p); + deparse_namespace **dpns_p, ListCell **ancestor_cell_p); static void get_parameter(Param *param, deparse_context *context); static const char *get_simple_binary_op_name(OpExpr *expr); static bool isSimpleNode(Node *node, Node *parentNode, int prettyFlags); static void appendContextKeyword(deparse_context *context, const char *str, - int indentBefore, int indentAfter, int indentPlus); + int indentBefore, int indentAfter, int indentPlus); static void removeStringInfoSpaces(StringInfo str); static void get_rule_expr(Node *node, deparse_context *context, - bool showimplicit); + bool showimplicit); static void get_rule_expr_toplevel(Node *node, deparse_context *context, - bool showimplicit); + bool showimplicit); static void get_rule_expr_funccall(Node *node, deparse_context *context, - bool showimplicit); + bool showimplicit); static bool looks_like_function(Node *node); static void get_oper_expr(OpExpr *expr, deparse_context *context); static void get_func_expr(FuncExpr *expr, deparse_context *context, - bool showimplicit); + bool showimplicit); static void get_agg_expr(Aggref *aggref, deparse_context *context, - Aggref *original_aggref); + Aggref *original_aggref); static void get_agg_combine_expr(Node *node, deparse_context *context, - void *private); + void *private); static void get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context); static void get_coercion_expr(Node *arg, deparse_context *context, - Oid resulttype, int32 resulttypmod, - Node *parentNode); + Oid resulttype, int32 resulttypmod, + Node *parentNode); static void get_const_expr(Const *constval, deparse_context *context, - int showtype); + int showtype); static void get_const_collation(Const *constval, deparse_context *context); static void simple_quote_literal(StringInfo buf, const char *val); static void get_sublink_expr(SubLink *sublink, deparse_context *context); static void get_tablefunc(TableFunc *tf, deparse_context *context, - bool showimplicit); + bool showimplicit); static void get_from_clause(Query *query, const char *prefix, - deparse_context *context); + deparse_context *context); static void get_from_clause_item(Node *jtnode, Query *query, - deparse_context *context); + deparse_context *context); static void get_column_alias_list(deparse_columns *colinfo, - deparse_context *context); + deparse_context *context); static void get_from_clause_coldeflist(RangeTblFunction *rtfunc, - deparse_columns *colinfo, - deparse_context *context); + deparse_columns *colinfo, + deparse_context *context); static void get_tablesample_def(TableSampleClause *tablesample, - deparse_context *context); + deparse_context *context); static void get_opclass_name(Oid opclass, Oid actual_datatype, - StringInfo buf); + StringInfo buf); static Node *processIndirection(Node *node, deparse_context *context); -static void printSubscripts(ArrayRef *aref, deparse_context *context); +static void printSubscripts(SubscriptingRef *sbsref, deparse_context *context); static char *get_relation_name(Oid relid); static char *generate_relation_name(Oid relid, List *namespaces); static char *generate_qualified_relation_name(Oid relid); static char *generate_function_name(Oid funcid, int nargs, - List *argnames, Oid *argtypes, - bool has_variadic, bool *use_variadic_p, - ParseExprKind special_exprkind); + List *argnames, Oid *argtypes, + bool has_variadic, bool *use_variadic_p, + ParseExprKind special_exprkind); static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2); static void add_cast_to(StringInfo buf, Oid typid); static char *generate_qualified_type_name(Oid typid); @@ -472,7 +474,7 @@ static char *flatten_reloptions(Oid relid); /* ---------- - * get_ruledef - Do it all and return a text + * pg_get_ruledef - Do it all and return a text * that could be used as a statement * to recreate the rule * ---------- @@ -592,7 +594,7 @@ pg_get_ruledef_worker(Oid ruleoid, int prettyFlags) /* ---------- - * get_viewdef - Mainly the same thing, but we + * pg_get_viewdef - Mainly the same thing, but we * only return the SELECT part of a view * ---------- */ @@ -787,7 +789,7 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) } /* ---------- - * get_triggerdef - Get the definition of a trigger + * pg_get_triggerdef - Get the definition of a trigger * ---------- */ Datum @@ -839,10 +841,10 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) /* * Fetch the pg_trigger tuple by the Oid of the trigger */ - tgrel = heap_open(TriggerRelationId, AccessShareLock); + tgrel = table_open(TriggerRelationId, AccessShareLock); ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_trigger_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(trigid)); @@ -854,7 +856,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) if (!HeapTupleIsValid(ht_trig)) { systable_endscan(tgscan); - heap_close(tgrel, AccessShareLock); + table_close(tgrel, AccessShareLock); return NULL; } @@ -953,22 +955,24 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) value = fastgetattr(ht_trig, Anum_pg_trigger_tgoldtable, tgrel->rd_att, &isnull); if (!isnull) - tgoldtable = NameStr(*((NameData *) DatumGetPointer(value))); + tgoldtable = NameStr(*DatumGetName(value)); else tgoldtable = NULL; value = fastgetattr(ht_trig, Anum_pg_trigger_tgnewtable, tgrel->rd_att, &isnull); if (!isnull) - tgnewtable = NameStr(*((NameData *) DatumGetPointer(value))); + tgnewtable = NameStr(*DatumGetName(value)); else tgnewtable = NULL; if (tgoldtable != NULL || tgnewtable != NULL) { appendStringInfoString(&buf, "REFERENCING "); if (tgoldtable != NULL) - appendStringInfo(&buf, "OLD TABLE AS %s ", tgoldtable); + appendStringInfo(&buf, "OLD TABLE AS %s ", + quote_identifier(tgoldtable)); if (tgnewtable != NULL) - appendStringInfo(&buf, "NEW TABLE AS %s ", tgnewtable); + appendStringInfo(&buf, "NEW TABLE AS %s ", + quote_identifier(tgnewtable)); } if (TRIGGER_FOR_ROW(trigrec->tgtype)) @@ -999,6 +1003,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) oldrte->rtekind = RTE_RELATION; oldrte->relid = trigrec->tgrelid; oldrte->relkind = relkind; + oldrte->rellockmode = AccessShareLock; oldrte->alias = makeAlias("old", NIL); oldrte->eref = oldrte->alias; oldrte->lateral = false; @@ -1009,6 +1014,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) newrte->rtekind = RTE_RELATION; newrte->relid = trigrec->tgrelid; newrte->relkind = relkind; + newrte->rellockmode = AccessShareLock; newrte->alias = makeAlias("new", NIL); newrte->eref = newrte->alias; newrte->lateral = false; @@ -1038,7 +1044,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) appendStringInfoString(&buf, ") "); } - appendStringInfo(&buf, "EXECUTE PROCEDURE %s(", + appendStringInfo(&buf, "EXECUTE FUNCTION %s(", generate_function_name(trigrec->tgfoid, 0, NIL, argtypes, false, NULL, EXPR_KIND_NONE)); @@ -1071,13 +1077,13 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty) /* Clean up */ systable_endscan(tgscan); - heap_close(tgrel, AccessShareLock); + table_close(tgrel, AccessShareLock); return buf.data; } /* ---------- - * get_indexdef - Get the definition of an index + * pg_get_indexdef - Get the definition of an index * * In the extended version, there is a colno argument as well as pretty bool. * if colno == 0, we want a complete index definition. @@ -1097,7 +1103,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS) prettyFlags = PRETTYFLAG_INDENT; - res = pg_get_indexdef_worker(indexrelid, 0, NULL, false, false, false, + res = pg_get_indexdef_worker(indexrelid, 0, NULL, + false, false, + false, false, prettyFlags, true); if (res == NULL) @@ -1117,8 +1125,10 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS) prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT; - res = pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, false, - false, prettyFlags, true); + res = pg_get_indexdef_worker(indexrelid, colno, NULL, + colno != 0, false, + false, false, + prettyFlags, true); if (res == NULL) PG_RETURN_NULL(); @@ -1134,10 +1144,13 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS) char * pg_get_indexdef_string(Oid indexrelid) { - return pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, true, 0, false); + return pg_get_indexdef_worker(indexrelid, 0, NULL, + false, false, + true, true, + 0, false); } -/* Internal version that just reports the column definitions */ +/* Internal version that just reports the key-column definitions */ char * pg_get_indexdef_columns(Oid indexrelid, bool pretty) { @@ -1145,7 +1158,9 @@ pg_get_indexdef_columns(Oid indexrelid, bool pretty) prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT; - return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false, false, + return pg_get_indexdef_worker(indexrelid, 0, NULL, + true, true, + false, false, prettyFlags, false); } @@ -1158,7 +1173,8 @@ pg_get_indexdef_columns(Oid indexrelid, bool pretty) static char * pg_get_indexdef_worker(Oid indexrelid, int colno, const Oid *excludeOps, - bool attrsOnly, bool showTblSpc, bool inherits, + bool attrsOnly, bool keysOnly, + bool showTblSpc, bool inherits, int prettyFlags, bool missing_ok) { /* might want a separate isConstraint parameter later */ @@ -1292,20 +1308,17 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, for (keyno = 0; keyno < idxrec->indnatts; keyno++) { AttrNumber attnum = idxrec->indkey.values[keyno]; - int16 opt = indoption->values[keyno]; Oid keycoltype; Oid keycolcollation; /* - * attrsOnly flag is used for building unique-constraint and - * exclusion-constraint error messages. Included attrs are meaningless - * there, so do not include them in the message. + * Ignore non-key attributes if told to. */ - if (attrsOnly && keyno >= idxrec->indnkeyatts) + if (keysOnly && keyno >= idxrec->indnkeyatts) break; - /* Report the INCLUDED attributes, if any. */ - if ((!attrsOnly) && keyno == idxrec->indnkeyatts) + /* Otherwise, print INCLUDE to divide key and non-key attrs. */ + if (!colno && keyno == idxrec->indnkeyatts) { appendStringInfoString(&buf, ") INCLUDE ("); sep = ""; @@ -1336,7 +1349,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, if (indexpr_item == NULL) elog(ERROR, "too few entries in indexprs list"); indexkey = (Node *) lfirst(indexpr_item); - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(indexprs, indexpr_item); /* Deparse */ str = deparse_expression_pretty(indexkey, context, false, false, prettyFlags, 0); @@ -1352,19 +1365,18 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, keycolcollation = exprCollation(indexkey); } - if (!attrsOnly && (!colno || colno == keyno + 1)) + /* Print additional decoration for (selected) key columns */ + if (!attrsOnly && keyno < idxrec->indnkeyatts && + (!colno || colno == keyno + 1)) { - Oid indcoll; + int16 opt = indoption->values[keyno]; + Oid indcoll = indcollation->values[keyno]; /* Add collation, if not default for column */ - indcoll = indcollation->values[keyno]; if (OidIsValid(indcoll) && indcoll != keycolcollation) appendStringInfo(&buf, " COLLATE %s", generate_collation_name((indcoll))); - if (keyno >= idxrec->indnkeyatts) - continue; - /* Add the operator class name, if not default */ get_opclass_name(indclass->values[keyno], keycoltype, &buf); @@ -1417,12 +1429,13 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, Oid tblspc; tblspc = get_rel_tablespace(indexrelid); - if (!OidIsValid(tblspc)) - tblspc = MyDatabaseTableSpace; - if (isConstraint) - appendStringInfoString(&buf, " USING INDEX"); - appendStringInfo(&buf, " TABLESPACE %s", - quote_identifier(get_tablespace_name(tblspc))); + if (OidIsValid(tblspc)) + { + if (isConstraint) + appendStringInfoString(&buf, " USING INDEX"); + appendStringInfo(&buf, " TABLESPACE %s", + quote_identifier(get_tablespace_name(tblspc))); + } } /* @@ -1496,6 +1509,7 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) bool isnull; bool ndistinct_enabled; bool dependencies_enabled; + bool mcv_enabled; int i; statexttup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(statextid)); @@ -1531,6 +1545,7 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) ndistinct_enabled = false; dependencies_enabled = false; + mcv_enabled = false; for (i = 0; i < ARR_DIMS(arr)[0]; i++) { @@ -1538,6 +1553,8 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) ndistinct_enabled = true; if (enabled[i] == STATS_EXT_DEPENDENCIES) dependencies_enabled = true; + if (enabled[i] == STATS_EXT_MCV) + mcv_enabled = true; } /* @@ -1547,13 +1564,27 @@ pg_get_statisticsobj_worker(Oid statextid, bool missing_ok) * statistics types on a newer postgres version, if the statistics had all * options enabled on the original version. */ - if (!ndistinct_enabled || !dependencies_enabled) + if (!ndistinct_enabled || !dependencies_enabled || !mcv_enabled) { + bool gotone = false; + appendStringInfoString(&buf, " ("); + if (ndistinct_enabled) + { appendStringInfoString(&buf, "ndistinct"); - else if (dependencies_enabled) - appendStringInfoString(&buf, "dependencies"); + gotone = true; + } + + if (dependencies_enabled) + { + appendStringInfo(&buf, "%sdependencies", gotone ? ", " : ""); + gotone = true; + } + + if (mcv_enabled) + appendStringInfo(&buf, "%smcv", gotone ? ", " : ""); + appendStringInfoChar(&buf, ')'); } @@ -1692,7 +1723,7 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags, { case PARTITION_STRATEGY_HASH: if (!attrsOnly) - appendStringInfo(&buf, "HASH"); + appendStringInfoString(&buf, "HASH"); break; case PARTITION_STRATEGY_LIST: if (!attrsOnly) @@ -1739,7 +1770,7 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags, if (partexpr_item == NULL) elog(ERROR, "too few entries in partexprs list"); partkey = (Node *) lfirst(partexpr_item); - partexpr_item = lnext(partexpr_item); + partexpr_item = lnext(partexprs, partexpr_item); /* Deparse */ str = deparse_expression_pretty(partkey, context, false, false, @@ -1805,6 +1836,24 @@ pg_get_partition_constraintdef(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(string_to_text(consrc)); } +/* + * pg_get_partconstrdef_string + * + * Returns the partition constraint as a C-string for the input relation, with + * the given alias. No pretty-printing. + */ +char * +pg_get_partconstrdef_string(Oid partitionId, char *aliasname) +{ + Expr *constr_expr; + List *context; + + constr_expr = get_partition_qual_relid(partitionId); + context = deparse_context_for(aliasname, partitionId); + + return deparse_expression((Node *) constr_expr, context, true, false); +} + /* * pg_get_constraintdef * @@ -1868,10 +1917,10 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, SysScanDesc scandesc; ScanKeyData scankey[1]; Snapshot snapshot = RegisterSnapshot(GetTransactionSnapshot()); - Relation relation = heap_open(ConstraintRelationId, AccessShareLock); + Relation relation = table_open(ConstraintRelationId, AccessShareLock); ScanKeyInit(&scankey[0], - ObjectIdAttributeNumber, + Anum_pg_constraint_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(constraintId)); @@ -1895,7 +1944,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, if (missing_ok) { systable_endscan(scandesc); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); return NULL; } elog(ERROR, "could not find tuple for constraint %u", constraintId); @@ -2047,6 +2096,8 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, Datum val; bool isnull; Oid indexId; + int keyatts; + HeapTuple indtup; /* Start off the constraint definition */ if (conForm->contype == CONSTRAINT_PRIMARY) @@ -2061,24 +2112,52 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, elog(ERROR, "null conkey for constraint %u", constraintId); - decompile_column_index_array(val, conForm->conrelid, &buf); + keyatts = decompile_column_index_array(val, conForm->conrelid, &buf); appendStringInfoChar(&buf, ')'); - /* Fetch and build including column list */ - isnull = true; - val = SysCacheGetAttr(CONSTROID, tup, - Anum_pg_constraint_conincluding, &isnull); - if (!isnull) + indexId = get_constraint_index(constraintId); + + /* Build including column list (from pg_index.indkeys) */ + indtup = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(indexId)); + if (!HeapTupleIsValid(indtup)) + elog(ERROR, "cache lookup failed for index %u", indexId); + val = SysCacheGetAttr(INDEXRELID, indtup, + Anum_pg_index_indnatts, &isnull); + if (isnull) + elog(ERROR, "null indnatts for index %u", indexId); + if (DatumGetInt32(val) > keyatts) { + Datum cols; + Datum *keys; + int nKeys; + int j; + appendStringInfoString(&buf, " INCLUDE ("); - decompile_column_index_array(val, conForm->conrelid, &buf); + cols = SysCacheGetAttr(INDEXRELID, indtup, + Anum_pg_index_indkey, &isnull); + if (isnull) + elog(ERROR, "null indkey for index %u", indexId); + + deconstruct_array(DatumGetArrayTypeP(cols), + INT2OID, 2, true, 's', + &keys, NULL, &nKeys); + + for (j = keyatts; j < nKeys; j++) + { + char *colName; + + colName = get_attname(conForm->conrelid, + DatumGetInt16(keys[j]), false); + if (j > keyatts) + appendStringInfoString(&buf, ", "); + appendStringInfoString(&buf, quote_identifier(colName)); + } appendStringInfoChar(&buf, ')'); } - - indexId = get_constraint_index(constraintId); + ReleaseSysCache(indtup); /* XXX why do we only print these bits if fullCommand? */ if (fullCommand && OidIsValid(indexId)) @@ -2092,6 +2171,12 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, pfree(options); } + /* + * Print the tablespace, unless it's the database default. + * This is to help ALTER TABLE usage of this facility, + * which needs this behavior to recreate exact catalog + * state. + */ tblspc = get_rel_tablespace(indexId); if (OidIsValid(tblspc)) appendStringInfo(&buf, " USING INDEX TABLESPACE %s", @@ -2197,6 +2282,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, false, false, false, + false, prettyFlags, false)); break; @@ -2215,7 +2301,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, /* Cleanup */ systable_endscan(scandesc); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); return buf.data; } @@ -2223,9 +2309,10 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand, /* * Convert an int16[] Datum into a comma-separated list of column names - * for the indicated relation; append the list to buf. + * for the indicated relation; append the list to buf. Returns the number + * of keys. */ -static void +static int decompile_column_index_array(Datum column_index_array, Oid relId, StringInfo buf) { @@ -2249,11 +2336,13 @@ decompile_column_index_array(Datum column_index_array, Oid relId, else appendStringInfo(buf, ", %s", quote_identifier(colName)); } + + return nKeys; } /* ---------- - * get_expr - Decompile an expression tree + * pg_get_expr - Decompile an expression tree * * Input: an expression tree in nodeToString form, and a relation OID * @@ -2351,7 +2440,7 @@ pg_get_expr_worker(text *expr, Oid relid, const char *relname, int prettyFlags) /* ---------- - * get_userbyid - Get a user name by roleid and + * pg_get_userbyid - Get a user name by roleid and * fallback to 'unknown (OID=n)' * ---------- */ @@ -2423,7 +2512,7 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS) column, tablerv->relname))); /* Search the dependency table for the dependent sequence */ - depRel = heap_open(DependRelationId, AccessShareLock); + depRel = table_open(DependRelationId, AccessShareLock); ScanKeyInit(&key[0], Anum_pg_depend_refclassid, @@ -2462,7 +2551,7 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS) } systable_endscan(scan); - heap_close(depRel, AccessShareLock); + table_close(depRel, AccessShareLock); if (OidIsValid(sequenceId)) { @@ -2591,6 +2680,21 @@ pg_get_functiondef(PG_FUNCTION_ARGS) if (proc->prorows > 0 && proc->prorows != 1000) appendStringInfo(&buf, " ROWS %g", proc->prorows); + if (proc->prosupport) + { + Oid argtypes[1]; + + /* + * We should qualify the support function's name if it wouldn't be + * resolved by lookup in the current search path. + */ + argtypes[0] = INTERNALOID; + appendStringInfo(&buf, " SUPPORT %s", + generate_function_name(proc->prosupport, 1, + NIL, argtypes, + false, NULL, EXPR_KIND_NONE)); + } + if (oldlen != buf.len) appendStringInfoChar(&buf, '\n'); @@ -2631,14 +2735,39 @@ pg_get_functiondef(PG_FUNCTION_ARGS) /* * Variables that are marked GUC_LIST_QUOTE were already fully * quoted by flatten_set_variable_args() before they were put - * into the proconfig array; we mustn't re-quote them or we'll - * make a mess. Variables that are not so marked should just - * be emitted as simple string literals. If the variable is - * not known to guc.c, we'll do the latter; this makes it - * unsafe to use GUC_LIST_QUOTE for extension variables. + * into the proconfig array. However, because the quoting + * rules used there aren't exactly like SQL's, we have to + * break the list value apart and then quote the elements as + * string literals. (The elements may be double-quoted as-is, + * but we can't just feed them to the SQL parser; it would do + * the wrong thing with elements that are zero-length or + * longer than NAMEDATALEN.) + * + * Variables that are not so marked should just be emitted as + * simple string literals. If the variable is not known to + * guc.c, we'll do that; this makes it unsafe to use + * GUC_LIST_QUOTE for extension variables. */ if (GetConfigOptionFlags(configitem, true) & GUC_LIST_QUOTE) - appendStringInfoString(&buf, pos); + { + List *namelist; + ListCell *lc; + + /* Parse string into list of identifiers */ + if (!SplitGUCList(pos, ',', &namelist)) + { + /* this shouldn't fail really */ + elog(ERROR, "invalid list syntax in proconfig item"); + } + foreach(lc, namelist) + { + char *curname = (char *) lfirst(lc); + + simple_quote_literal(&buf, curname); + if (lnext(namelist, lc)) + appendStringInfoString(&buf, ", "); + } + } else simple_quote_literal(&buf, pos); appendStringInfoChar(&buf, '\n'); @@ -2675,9 +2804,9 @@ pg_get_functiondef(PG_FUNCTION_ARGS) appendStringInfoChar(&dq, 'x'); appendStringInfoChar(&dq, '$'); - appendStringInfoString(&buf, dq.data); + appendBinaryStringInfo(&buf, dq.data, dq.len); appendStringInfoString(&buf, prosrc); - appendStringInfoString(&buf, dq.data); + appendBinaryStringInfo(&buf, dq.data, dq.len); appendStringInfoChar(&buf, '\n'); @@ -2801,7 +2930,7 @@ print_function_rettype(StringInfo buf, HeapTuple proctup) appendStringInfoString(&rbuf, format_type_be(proc->prorettype)); } - appendStringInfoString(buf, rbuf.data); + appendBinaryStringInfo(buf, rbuf.data, rbuf.len); } /* @@ -2824,6 +2953,7 @@ print_function_arguments(StringInfo buf, HeapTuple proctup, int argsprinted; int inputargno; int nlackdefaults; + List *argdefaults = NIL; ListCell *nextargdefault = NULL; int i; @@ -2842,7 +2972,6 @@ print_function_arguments(StringInfo buf, HeapTuple proctup, if (!isnull) { char *str; - List *argdefaults; str = TextDatumGetCString(proargdefaults); argdefaults = castNode(List, stringToNode(str)); @@ -2859,11 +2988,10 @@ print_function_arguments(StringInfo buf, HeapTuple proctup, HeapTuple aggtup; Form_pg_aggregate agg; - aggtup = SearchSysCache1(AGGFNOID, - ObjectIdGetDatum(HeapTupleGetOid(proctup))); + aggtup = SearchSysCache1(AGGFNOID, proc->oid); if (!HeapTupleIsValid(aggtup)) elog(ERROR, "cache lookup failed for aggregate %u", - HeapTupleGetOid(proctup)); + proc->oid); agg = (Form_pg_aggregate) GETSTRUCT(aggtup); if (AGGKIND_IS_ORDERED_SET(agg->aggkind)) insertorderbyat = agg->aggnumdirectargs; @@ -2933,7 +3061,7 @@ print_function_arguments(StringInfo buf, HeapTuple proctup, Assert(nextargdefault != NULL); expr = (Node *) lfirst(nextargdefault); - nextargdefault = lnext(nextargdefault); + nextargdefault = lnext(argdefaults, nextargdefault); appendStringInfo(buf, " DEFAULT %s", deparse_expression(expr, NIL, false, false)); @@ -3139,6 +3267,7 @@ deparse_context_for(const char *aliasname, Oid relid) rte->rtekind = RTE_RELATION; rte->relid = relid; rte->relkind = RELKIND_RELATION; /* no need for exactness here */ + rte->rellockmode = AccessShareLock; rte->alias = makeAlias(aliasname, NIL); rte->eref = rte->alias; rte->lateral = false; @@ -4634,16 +4763,14 @@ push_ancestor_plan(deparse_namespace *dpns, ListCell *ancestor_cell, deparse_namespace *save_dpns) { PlanState *ps = (PlanState *) lfirst(ancestor_cell); - List *ancestors; /* Save state for restoration later */ *save_dpns = *dpns; /* Build a new ancestor list with just this node's ancestors */ - ancestors = NIL; - while ((ancestor_cell = lnext(ancestor_cell)) != NULL) - ancestors = lappend(ancestors, lfirst(ancestor_cell)); - dpns->ancestors = ancestors; + dpns->ancestors = + list_copy_tail(dpns->ancestors, + list_cell_number(dpns->ancestors, ancestor_cell) + 1); /* Set attention on selected ancestor */ set_deparse_planstate(dpns, ps); @@ -4717,7 +4844,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, if (ev_action != NULL) actions = (List *) stringToNode(ev_action); - ev_relation = heap_open(ev_class, AccessShareLock); + ev_relation = table_open(ev_class, AccessShareLock); /* * Build the rules definition text @@ -4851,7 +4978,7 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, appendStringInfoChar(buf, ';'); } - heap_close(ev_relation, AccessShareLock); + table_close(ev_relation, AccessShareLock); } @@ -4918,13 +5045,13 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc, return; } - ev_relation = heap_open(ev_class, AccessShareLock); + ev_relation = table_open(ev_class, AccessShareLock); get_query_def(query, buf, NIL, RelationGetDescr(ev_relation), prettyFlags, wrapColumn, 0); appendStringInfoChar(buf, ';'); - heap_close(ev_relation, AccessShareLock); + table_close(ev_relation, AccessShareLock); } @@ -5094,7 +5221,19 @@ get_with_clause(Query *query, deparse_context *context) } appendStringInfoChar(buf, ')'); } - appendStringInfoString(buf, " AS ("); + appendStringInfoString(buf, " AS "); + switch (cte->ctematerialized) + { + case CTEMaterializeDefault: + break; + case CTEMaterializeAlways: + appendStringInfoString(buf, "MATERIALIZED "); + break; + case CTEMaterializeNever: + appendStringInfoString(buf, "NOT MATERIALIZED "); + break; + } + appendStringInfoChar(buf, '('); if (PRETTY_INDENT(context)) appendContextKeyword(context, "", 0, 0, 0); get_query_def((Query *) cte->ctequery, buf, context->namespaces, NULL, @@ -5543,7 +5682,7 @@ get_target_list(List *targetList, deparse_context *context, } /* Add the new field */ - appendStringInfoString(buf, targetbuf.data); + appendBinaryStringInfo(buf, targetbuf.data, targetbuf.len); } /* clean up */ @@ -6328,12 +6467,12 @@ get_update_query_targetlist_def(Query *query, List *targetList, { /* * We must dig down into the expr to see if it's a PARAM_MULTIEXPR - * Param. That could be buried under FieldStores and ArrayRefs - * and CoerceToDomains (cf processIndirection()), and underneath - * those there could be an implicit type coercion. Because we - * would ignore implicit type coercions anyway, we don't need to - * be as careful as processIndirection() is about descending past - * implicit CoerceToDomains. + * Param. That could be buried under FieldStores and + * SubscriptingRefs and CoerceToDomains (cf processIndirection()), + * and underneath those there could be an implicit type coercion. + * Because we would ignore implicit type coercions anyway, we + * don't need to be as careful as processIndirection() is about + * descending past implicit CoerceToDomains. */ expr = (Node *) tle->expr; while (expr) @@ -6344,13 +6483,14 @@ get_update_query_targetlist_def(Query *query, List *targetList, expr = (Node *) linitial(fstore->newvals); } - else if (IsA(expr, ArrayRef)) + else if (IsA(expr, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) expr; + SubscriptingRef *sbsref = (SubscriptingRef *) expr; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - expr = (Node *) aref->refassgnexpr; + + expr = (Node *) sbsref->refassgnexpr; } else if (IsA(expr, CoerceToDomain)) { @@ -6369,7 +6509,7 @@ get_update_query_targetlist_def(Query *query, List *targetList, ((Param *) expr)->paramkind == PARAM_MULTIEXPR) { cur_ma_sublink = (SubLink *) lfirst(next_ma_cell); - next_ma_cell = lnext(next_ma_cell); + next_ma_cell = lnext(ma_sublinks, next_ma_cell); remaining_ma_columns = count_nonjunk_tlist_entries( ((Query *) cur_ma_sublink->subselect)->targetList); Assert(((Param *) expr)->paramid == @@ -6671,8 +6811,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context) /* * Deparse a Var which references OUTER_VAR, INNER_VAR, or INDEX_VAR. This - * routine is actually a callback for get_special_varno, which handles finding - * the correct TargetEntry. We get the expression contained in that + * routine is actually a callback for resolve_special_varno, which handles + * finding the correct TargetEntry. We get the expression contained in that * TargetEntry and just need to deparse it, a job we can throw back on * get_rule_expr. */ @@ -6939,6 +7079,7 @@ get_name_for_var_field(Var *var, int fieldno, case RTE_RELATION: case RTE_VALUES: case RTE_NAMEDTUPLESTORE: + case RTE_RESULT: /* * This case should not occur: a column of a table, values list, @@ -7383,7 +7524,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) /* single words: always simple */ return true; - case T_ArrayRef: + case T_SubscriptingRef: case T_ArrayExpr: case T_RowExpr: case T_CoalesceExpr: @@ -7481,8 +7622,8 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) return false; } /* else do the same stuff as for T_SubLink et al. */ - /* FALL THROUGH */ } + /* FALLTHROUGH */ case T_SubLink: case T_NullTest: @@ -7501,7 +7642,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) return true; /* own parentheses */ } case T_BoolExpr: /* lower precedence */ - case T_ArrayRef: /* other separators */ + case T_SubscriptingRef: /* other separators */ case T_ArrayExpr: /* other separators */ case T_RowExpr: /* other separators */ case T_CoalesceExpr: /* own parentheses */ @@ -7551,7 +7692,7 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags) return false; return true; /* own parentheses */ } - case T_ArrayRef: /* other separators */ + case T_SubscriptingRef: /* other separators */ case T_ArrayExpr: /* other separators */ case T_RowExpr: /* other separators */ case T_CoalesceExpr: /* own parentheses */ @@ -7737,9 +7878,9 @@ get_rule_expr(Node *node, deparse_context *context, get_windowfunc_expr((WindowFunc *) node, context); break; - case T_ArrayRef: + case T_SubscriptingRef: { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; bool need_parens; /* @@ -7750,37 +7891,38 @@ get_rule_expr(Node *node, deparse_context *context, * here too, and display only the assignment source * expression. */ - if (IsA(aref->refexpr, CaseTestExpr)) + if (IsA(sbsref->refexpr, CaseTestExpr)) { - Assert(aref->refassgnexpr); - get_rule_expr((Node *) aref->refassgnexpr, + Assert(sbsref->refassgnexpr); + get_rule_expr((Node *) sbsref->refassgnexpr, context, showimplicit); break; } /* * Parenthesize the argument unless it's a simple Var or a - * FieldSelect. (In particular, if it's another ArrayRef, we - * *must* parenthesize to avoid confusion.) + * FieldSelect. (In particular, if it's another + * SubscriptingRef, we *must* parenthesize to avoid + * confusion.) */ - need_parens = !IsA(aref->refexpr, Var) && - !IsA(aref->refexpr, FieldSelect); + need_parens = !IsA(sbsref->refexpr, Var) && + !IsA(sbsref->refexpr, FieldSelect); if (need_parens) appendStringInfoChar(buf, '('); - get_rule_expr((Node *) aref->refexpr, context, showimplicit); + get_rule_expr((Node *) sbsref->refexpr, context, showimplicit); if (need_parens) appendStringInfoChar(buf, ')'); /* * If there's a refassgnexpr, we want to print the node in the - * format "array[subscripts] := refassgnexpr". This is not - * legal SQL, so decompilation of INSERT or UPDATE statements - * should always use processIndirection as part of the - * statement-level syntax. We should only see this when + * format "container[subscripts] := refassgnexpr". This is + * not legal SQL, so decompilation of INSERT or UPDATE + * statements should always use processIndirection as part of + * the statement-level syntax. We should only see this when * EXPLAIN tries to print the targetlist of a plan resulting * from such a statement. */ - if (aref->refassgnexpr) + if (sbsref->refassgnexpr) { Node *refassgnexpr; @@ -7796,8 +7938,8 @@ get_rule_expr(Node *node, deparse_context *context, } else { - /* Just an ordinary array fetch, so print subscripts */ - printSubscripts(aref, context); + /* Just an ordinary container fetch, so print subscripts */ + printSubscripts(sbsref, context); } } break; @@ -7890,7 +8032,7 @@ get_rule_expr(Node *node, deparse_context *context, { BoolExpr *expr = (BoolExpr *) node; Node *first_arg = linitial(expr->args); - ListCell *arg = lnext(list_head(expr->args)); + ListCell *arg = list_second_cell(expr->args); switch (expr->boolop) { @@ -7904,7 +8046,7 @@ get_rule_expr(Node *node, deparse_context *context, appendStringInfoString(buf, " AND "); get_rule_expr_paren((Node *) lfirst(arg), context, false, node); - arg = lnext(arg); + arg = lnext(expr->args, arg); } if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); @@ -7920,7 +8062,7 @@ get_rule_expr(Node *node, deparse_context *context, appendStringInfoString(buf, " OR "); get_rule_expr_paren((Node *) lfirst(arg), context, false, node); - arg = lnext(arg); + arg = lnext(expr->args, arg); } if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); @@ -7979,7 +8121,7 @@ get_rule_expr(Node *node, deparse_context *context, appendStringInfo(buf, "hashed %s", splan->plan_name); else appendStringInfoString(buf, splan->plan_name); - if (lnext(lc)) + if (lnext(asplan->subplans, lc)) appendStringInfoString(buf, " or "); } appendStringInfoChar(buf, ')'); @@ -7995,12 +8137,13 @@ get_rule_expr(Node *node, deparse_context *context, bool need_parens; /* - * Parenthesize the argument unless it's an ArrayRef or + * Parenthesize the argument unless it's an SubscriptingRef or * another FieldSelect. Note in particular that it would be * WRONG to not parenthesize a Var argument; simplicity is not * the issue here, having the right number of names is. */ - need_parens = !IsA(arg, ArrayRef) &&!IsA(arg, FieldSelect); + need_parens = !IsA(arg, SubscriptingRef) && + !IsA(arg, FieldSelect); if (need_parens) appendStringInfoChar(buf, '('); get_rule_expr(arg, context, true); @@ -9086,7 +9229,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context, { if (nargs++ > 0) appendStringInfoString(buf, ", "); - if (use_variadic && lnext(l) == NULL) + if (use_variadic && lnext(expr->args, l) == NULL) appendStringInfoString(buf, "VARIADIC "); get_rule_expr((Node *) lfirst(l), context, true); } @@ -9332,6 +9475,14 @@ get_coercion_expr(Node *arg, deparse_context *context, if (!PRETTY_PAREN(context)) appendStringInfoChar(buf, ')'); } + + /* + * Never emit resulttype(arg) functional notation. A pg_proc entry could + * take precedence, and a resulttype in pg_temp would require schema + * qualification that format_type_with_typemod() would usually omit. We've + * standardized on arg::resulttype, but CAST(arg AS resulttype) notation + * would work fine. + */ appendStringInfo(buf, "::%s", format_type_with_typemod(resulttype, resulttypmod)); } @@ -9423,11 +9574,6 @@ get_const_expr(Const *constval, deparse_context *context, int showtype) } break; - case BITOID: - case VARBITOID: - appendStringInfo(buf, "B'%s'", extval); - break; - case BOOLOID: if (strcmp(extval, "t") == 0) appendStringInfoString(buf, "true"); @@ -9677,17 +9823,17 @@ get_tablefunc(TableFunc *tf, deparse_context *context, bool showimplicit) forboth(lc1, tf->ns_uris, lc2, tf->ns_names) { Node *expr = (Node *) lfirst(lc1); - char *name = strVal(lfirst(lc2)); + Value *ns_node = (Value *) lfirst(lc2); if (!first) appendStringInfoString(buf, ", "); else first = false; - if (name != NULL) + if (ns_node != NULL) { get_rule_expr(expr, context, showimplicit); - appendStringInfo(buf, " AS %s", name); + appendStringInfo(buf, " AS %s", strVal(ns_node)); } else { @@ -9713,31 +9859,18 @@ get_tablefunc(TableFunc *tf, deparse_context *context, bool showimplicit) ListCell *l5; int colnum = 0; - l2 = list_head(tf->coltypes); - l3 = list_head(tf->coltypmods); - l4 = list_head(tf->colexprs); - l5 = list_head(tf->coldefexprs); - appendStringInfoString(buf, " COLUMNS "); - foreach(l1, tf->colnames) + forfive(l1, tf->colnames, l2, tf->coltypes, l3, tf->coltypmods, + l4, tf->colexprs, l5, tf->coldefexprs) { char *colname = strVal(lfirst(l1)); - Oid typid; - int32 typmod; - Node *colexpr; - Node *coldefexpr; - bool ordinality = tf->ordinalitycol == colnum; + Oid typid = lfirst_oid(l2); + int32 typmod = lfirst_int(l3); + Node *colexpr = (Node *) lfirst(l4); + Node *coldefexpr = (Node *) lfirst(l5); + bool ordinality = (tf->ordinalitycol == colnum); bool notnull = bms_is_member(colnum, tf->notnulls); - typid = lfirst_oid(l2); - l2 = lnext(l2); - typmod = lfirst_int(l3); - l3 = lnext(l3); - colexpr = (Node *) lfirst(l4); - l4 = lnext(l4); - coldefexpr = (Node *) lfirst(l5); - l5 = lnext(l5); - if (colnum > 0) appendStringInfoString(buf, ", "); colnum++; @@ -9862,7 +9995,7 @@ get_from_clause(Query *query, const char *prefix, deparse_context *context) } /* Add the new item */ - appendStringInfoString(buf, itembuf.data); + appendBinaryStringInfo(buf, itembuf.data, itembuf.len); /* clean up */ pfree(itembuf.data); @@ -9964,7 +10097,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc); List *args = ((FuncExpr *) rtfunc->funcexpr)->args; - allargs = list_concat(allargs, list_copy(args)); + allargs = list_concat(allargs, args); } appendStringInfoString(buf, "UNNEST("); @@ -10182,8 +10315,16 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context) /* Yes, it's correct to put alias after the right paren ... */ if (j->alias != NULL) { + /* + * Note that it's correct to emit an alias clause if and only if + * there was one originally. Otherwise we'd be converting a named + * join to unnamed or vice versa, which creates semantic + * subtleties we don't want. However, we might print a different + * alias name than was there originally. + */ appendStringInfo(buf, " %s", - quote_identifier(j->alias->aliasname)); + quote_identifier(get_rtable_name(j->rtindex, + context))); get_column_alias_list(colinfo, context); } } @@ -10251,12 +10392,11 @@ get_from_clause_coldeflist(RangeTblFunction *rtfunc, appendStringInfoChar(buf, '('); - /* there's no forfour(), so must chase one list the hard way */ i = 0; - l4 = list_head(rtfunc->funccolnames); - forthree(l1, rtfunc->funccoltypes, - l2, rtfunc->funccoltypmods, - l3, rtfunc->funccolcollations) + forfour(l1, rtfunc->funccoltypes, + l2, rtfunc->funccoltypmods, + l3, rtfunc->funccolcollations, + l4, rtfunc->funccolnames) { Oid atttypid = lfirst_oid(l1); int32 atttypmod = lfirst_int(l2); @@ -10280,7 +10420,6 @@ get_from_clause_coldeflist(RangeTblFunction *rtfunc, appendStringInfo(buf, " COLLATE %s", generate_collation_name(attcollation)); - l4 = lnext(l4); i++; } @@ -10369,7 +10508,7 @@ get_opclass_name(Oid opclass, Oid actual_datatype, /* * processIndirection - take care of array and subfield assignment * - * We strip any top-level FieldStore or assignment ArrayRef nodes that + * We strip any top-level FieldStore or assignment SubscriptingRef nodes that * appear in the input, printing them as decoration for the base column * name (which we assume the caller just printed). We might also need to * strip CoerceToDomain nodes, but only ones that appear above assignment @@ -10415,19 +10554,20 @@ processIndirection(Node *node, deparse_context *context) */ node = (Node *) linitial(fstore->newvals); } - else if (IsA(node, ArrayRef)) + else if (IsA(node, SubscriptingRef)) { - ArrayRef *aref = (ArrayRef *) node; + SubscriptingRef *sbsref = (SubscriptingRef *) node; - if (aref->refassgnexpr == NULL) + if (sbsref->refassgnexpr == NULL) break; - printSubscripts(aref, context); + + printSubscripts(sbsref, context); /* * We ignore refexpr since it should be an uninteresting reference * to the target column or subcolumn. */ - node = (Node *) aref->refassgnexpr; + node = (Node *) sbsref->refassgnexpr; } else if (IsA(node, CoerceToDomain)) { @@ -10455,14 +10595,14 @@ processIndirection(Node *node, deparse_context *context) } static void -printSubscripts(ArrayRef *aref, deparse_context *context) +printSubscripts(SubscriptingRef *sbsref, deparse_context *context) { StringInfo buf = context->buf; ListCell *lowlist_item; ListCell *uplist_item; - lowlist_item = list_head(aref->reflowerindexpr); /* could be NULL */ - foreach(uplist_item, aref->refupperindexpr) + lowlist_item = list_head(sbsref->reflowerindexpr); /* could be NULL */ + foreach(uplist_item, sbsref->refupperindexpr) { appendStringInfoChar(buf, '['); if (lowlist_item) @@ -10470,7 +10610,7 @@ printSubscripts(ArrayRef *aref, deparse_context *context) /* If subexpression is NULL, get_rule_expr prints nothing */ get_rule_expr((Node *) lfirst(lowlist_item), context, false); appendStringInfoChar(buf, ':'); - lowlist_item = lnext(lowlist_item); + lowlist_item = lnext(sbsref->reflowerindexpr, lowlist_item); } /* If subexpression is NULL, get_rule_expr prints nothing */ get_rule_expr((Node *) lfirst(uplist_item), context, false); @@ -10535,11 +10675,9 @@ quote_identifier(const char *ident) * Note: ScanKeywordLookup() does case-insensitive comparison, but * that's fine, since we already know we have all-lower-case. */ - const ScanKeyword *keyword = ScanKeywordLookup(ident, - ScanKeywords, - NumScanKeywords); + int kwnum = ScanKeywordLookup(ident, &ScanKeywords); - if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD) + if (kwnum >= 0 && ScanKeywordCategories[kwnum] != UNRESERVED_KEYWORD) safe = false; } @@ -10752,16 +10890,11 @@ generate_function_name(Oid funcid, int nargs, List *argnames, Oid *argtypes, * Determine whether VARIADIC should be printed. We must do this first * since it affects the lookup rules in func_get_detail(). * - * Currently, we always print VARIADIC if the function has a merged - * variadic-array argument. Note that this is always the case for - * functions taking a VARIADIC argument type other than VARIADIC ANY. - * - * In principle, if VARIADIC wasn't originally specified and the array - * actual argument is deconstructable, we could print the array elements - * separately and not print VARIADIC, thus more nearly reproducing the - * original input. For the moment that seems like too much complication - * for the benefit, and anyway we do not know whether VARIADIC was - * originally specified if it's a non-ANY type. + * We always print VARIADIC if the function has a merged variadic-array + * argument. Note that this is always the case for functions taking a + * VARIADIC argument type other than VARIADIC ANY. If we omitted VARIADIC + * and printed the array elements as separate arguments, the call could + * match a newer non-VARIADIC function. */ if (use_variadic_p) { @@ -11129,7 +11262,7 @@ flatten_reloptions(Oid relid) } /* - * get_one_range_partition_bound_string + * get_range_partbound_string * A C string representation of one range partition bound */ char * diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index fe606d72798..17101298fb0 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -10,7 +10,7 @@ * Index cost functions are located via the index AM's API struct, * which is obtained from the handler function registered in pg_am. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -87,58 +87,51 @@ * For both oprrest and oprjoin functions, the operator's input collation OID * (if any) is passed using the standard fmgr mechanism, so that the estimator * function can fetch it with PG_GET_COLLATION(). Note, however, that all - * statistics in pg_statistic are currently built using the database's default + * statistics in pg_statistic are currently built using the relevant column's * collation. Thus, in most cases where we are looking at statistics, we - * should ignore the actual operator collation and use DEFAULT_COLLATION_OID. + * should ignore the operator collation and use the stats entry's collation. * We expect that the error induced by doing this is usually not large enough - * to justify complicating matters. + * to justify complicating matters. In any case, doing otherwise would yield + * entirely garbage results for ordered stats data such as histograms. *---------- */ #include "postgres.h" #include -#include #include #include "access/brin.h" #include "access/gin.h" -#include "access/htup_details.h" -#include "access/sysattr.h" -#include "catalog/index.h" +#include "access/table.h" +#include "access/tableam.h" +#include "access/visibilitymap.h" #include "catalog/pg_am.h" #include "catalog/pg_collation.h" #include "catalog/pg_operator.h" -#include "catalog/pg_opfamily.h" #include "catalog/pg_statistic.h" #include "catalog/pg_statistic_ext.h" -#include "catalog/pg_type.h" -#include "executor/executor.h" -#include "mb/pg_wchar.h" +#include "executor/nodeAgg.h" #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/plancat.h" -#include "optimizer/predtest.h" -#include "optimizer/restrictinfo.h" -#include "optimizer/var.h" #include "parser/parse_clause.h" -#include "parser/parse_coerce.h" #include "parser/parsetree.h" #include "statistics/statistics.h" -#include "utils/acl.h" +#include "storage/bufmgr.h" #include "utils/builtins.h" -#include "utils/bytea.h" #include "utils/date.h" #include "utils/datum.h" #include "utils/fmgroids.h" #include "utils/index_selfuncs.h" #include "utils/lsyscache.h" -#include "utils/nabstime.h" +#include "utils/memutils.h" #include "utils/pg_locale.h" #include "utils/rel.h" #include "utils/selfuncs.h" @@ -146,9 +139,7 @@ #include "utils/spccache.h" #include "utils/syscache.h" #include "utils/timestamp.h" -#include "utils/tqual.h" #include "utils/typcache.h" -#include "utils/varlena.h" /* Hooks for plugins to get control when we ask for stats */ @@ -156,67 +147,66 @@ get_relation_stats_hook_type get_relation_stats_hook = NULL; get_index_stats_hook_type get_index_stats_hook = NULL; static double eqsel_internal(PG_FUNCTION_ARGS, bool negate); -static double var_eq_const(VariableStatData *vardata, Oid operator, - Datum constval, bool constisnull, - bool varonleft, bool negate); -static double var_eq_non_const(VariableStatData *vardata, Oid operator, - Node *other, - bool varonleft, bool negate); -static double ineq_histogram_selectivity(PlannerInfo *root, - VariableStatData *vardata, - FmgrInfo *opproc, bool isgt, bool iseq, - Datum constval, Oid consttype); -static double eqjoinsel_inner(Oid operator, - VariableStatData *vardata1, VariableStatData *vardata2); -static double eqjoinsel_semi(Oid operator, - VariableStatData *vardata1, VariableStatData *vardata2, - RelOptInfo *inner_rel); +static double eqjoinsel_inner(Oid opfuncoid, + VariableStatData *vardata1, VariableStatData *vardata2, + double nd1, double nd2, + bool isdefault1, bool isdefault2, + AttStatsSlot *sslot1, AttStatsSlot *sslot2, + Form_pg_statistic stats1, Form_pg_statistic stats2, + bool have_mcvs1, bool have_mcvs2); +static double eqjoinsel_semi(Oid opfuncoid, + VariableStatData *vardata1, VariableStatData *vardata2, + double nd1, double nd2, + bool isdefault1, bool isdefault2, + AttStatsSlot *sslot1, AttStatsSlot *sslot2, + Form_pg_statistic stats1, Form_pg_statistic stats2, + bool have_mcvs1, bool have_mcvs2, + RelOptInfo *inner_rel); static bool estimate_multivariate_ndistinct(PlannerInfo *root, - RelOptInfo *rel, List **varinfos, double *ndistinct); -static bool convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, - Datum lobound, Datum hibound, Oid boundstypid, - double *scaledlobound, double *scaledhibound); + RelOptInfo *rel, List **varinfos, double *ndistinct); +static bool convert_to_scalar(Datum value, Oid valuetypid, Oid collid, + double *scaledvalue, + Datum lobound, Datum hibound, Oid boundstypid, + double *scaledlobound, double *scaledhibound); static double convert_numeric_to_scalar(Datum value, Oid typid, bool *failure); static void convert_string_to_scalar(char *value, - double *scaledvalue, - char *lobound, - double *scaledlobound, - char *hibound, - double *scaledhibound); + double *scaledvalue, + char *lobound, + double *scaledlobound, + char *hibound, + double *scaledhibound); static void convert_bytea_to_scalar(Datum value, - double *scaledvalue, - Datum lobound, - double *scaledlobound, - Datum hibound, - double *scaledhibound); + double *scaledvalue, + Datum lobound, + double *scaledlobound, + Datum hibound, + double *scaledhibound); static double convert_one_string_to_scalar(char *value, - int rangelo, int rangehi); + int rangelo, int rangehi); static double convert_one_bytea_to_scalar(unsigned char *value, int valuelen, - int rangelo, int rangehi); -static char *convert_string_datum(Datum value, Oid typid, bool *failure); + int rangelo, int rangehi); +static char *convert_string_datum(Datum value, Oid typid, Oid collid, + bool *failure); static double convert_timevalue_to_scalar(Datum value, Oid typid, - bool *failure); + bool *failure); static void examine_simple_variable(PlannerInfo *root, Var *var, - VariableStatData *vardata); + VariableStatData *vardata); static bool get_variable_range(PlannerInfo *root, VariableStatData *vardata, - Oid sortop, Datum *min, Datum *max); + Oid sortop, Datum *min, Datum *max); static bool get_actual_variable_range(PlannerInfo *root, - VariableStatData *vardata, - Oid sortop, - Datum *min, Datum *max); + VariableStatData *vardata, + Oid sortop, + Datum *min, Datum *max); +static bool get_actual_variable_endpoint(Relation heapRel, + Relation indexRel, + ScanDirection indexscandir, + ScanKey scankeys, + int16 typLen, + bool typByVal, + TupleTableSlot *tableslot, + MemoryContext outercontext, + Datum *endpointDatum); static RelOptInfo *find_join_input_rel(PlannerInfo *root, Relids relids); -static Selectivity prefix_selectivity(PlannerInfo *root, - VariableStatData *vardata, - Oid vartype, Oid opfamily, Const *prefixcon); -static Selectivity like_selectivity(const char *patt, int pattlen, - bool case_insensitive); -static Selectivity regex_selectivity(const char *patt, int pattlen, - bool case_insensitive, - int fixed_prefix_len); -static Datum string_to_datum(const char *str, Oid datatype); -static Const *string_to_const(const char *str, Oid datatype); -static Const *string_to_bytea_const(const char *str, size_t str_len); -static List *add_predicate_to_quals(IndexOptInfo *index, List *indexQuals); /* @@ -292,9 +282,9 @@ eqsel_internal(PG_FUNCTION_ARGS, bool negate) /* * var_eq_const --- eqsel for var = const case * - * This is split out so that some other estimation functions can use it. + * This is exported so that some other estimation functions can use it. */ -static double +double var_eq_const(VariableStatData *vardata, Oid operator, Datum constval, bool constisnull, bool varonleft, bool negate) @@ -362,12 +352,12 @@ var_eq_const(VariableStatData *vardata, Oid operator, /* be careful to apply operator right way 'round */ if (varonleft) match = DatumGetBool(FunctionCall2Coll(&eqproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, sslot.values[i], constval)); else match = DatumGetBool(FunctionCall2Coll(&eqproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, constval, sslot.values[i])); if (match) @@ -445,8 +435,10 @@ var_eq_const(VariableStatData *vardata, Oid operator, /* * var_eq_non_const --- eqsel for var = something-other-than-const case + * + * This is exported so that some other estimation functions can use it. */ -static double +double var_eq_non_const(VariableStatData *vardata, Oid operator, Node *other, bool varonleft, bool negate) @@ -573,6 +565,81 @@ scalarineqsel(PlannerInfo *root, Oid operator, bool isgt, bool iseq, if (!HeapTupleIsValid(vardata->statsTuple)) { + /* + * No stats are available. Typically this means we have to fall back + * on the default estimate; but if the variable is CTID then we can + * make an estimate based on comparing the constant to the table size. + */ + if (vardata->var && IsA(vardata->var, Var) && + ((Var *) vardata->var)->varattno == SelfItemPointerAttributeNumber) + { + ItemPointer itemptr; + double block; + double density; + + /* + * If the relation's empty, we're going to include all of it. + * (This is mostly to avoid divide-by-zero below.) + */ + if (vardata->rel->pages == 0) + return 1.0; + + itemptr = (ItemPointer) DatumGetPointer(constval); + block = ItemPointerGetBlockNumberNoCheck(itemptr); + + /* + * Determine the average number of tuples per page (density). + * + * Since the last page will, on average, be only half full, we can + * estimate it to have half as many tuples as earlier pages. So + * give it half the weight of a regular page. + */ + density = vardata->rel->tuples / (vardata->rel->pages - 0.5); + + /* If target is the last page, use half the density. */ + if (block >= vardata->rel->pages - 1) + density *= 0.5; + + /* + * Using the average tuples per page, calculate how far into the + * page the itemptr is likely to be and adjust block accordingly, + * by adding that fraction of a whole block (but never more than a + * whole block, no matter how high the itemptr's offset is). Here + * we are ignoring the possibility of dead-tuple line pointers, + * which is fairly bogus, but we lack the info to do better. + */ + if (density > 0.0) + { + OffsetNumber offset = ItemPointerGetOffsetNumberNoCheck(itemptr); + + block += Min(offset / density, 1.0); + } + + /* + * Convert relative block number to selectivity. Again, the last + * page has only half weight. + */ + selec = block / (vardata->rel->pages - 0.5); + + /* + * The calculation so far gave us a selectivity for the "<=" case. + * We'll have one less tuple for "<" and one additional tuple for + * ">=", the latter of which we'll reverse the selectivity for + * below, so we can simply subtract one tuple for both cases. The + * cases that need this adjustment can be identified by iseq being + * equal to isgt. + */ + if (iseq == isgt && vardata->rel->tuples >= 1.0) + selec -= (1.0 / vardata->rel->tuples); + + /* Finally, reverse the selectivity for the ">", ">=" cases. */ + if (isgt) + selec = 1.0 - selec; + + CLAMP_PROBABILITY(selec); + return selec; + } + /* no stats available, so default result */ return DEFAULT_INEQ_SEL; } @@ -658,11 +725,11 @@ mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, { if (varonleft ? DatumGetBool(FunctionCall2Coll(opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, sslot.values[i], constval)) : DatumGetBool(FunctionCall2Coll(opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, constval, sslot.values[i]))) mcv_selec += sslot.numbers[i]; @@ -736,11 +803,11 @@ histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, { if (varonleft ? DatumGetBool(FunctionCall2Coll(opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, sslot.values[i], constval)) : DatumGetBool(FunctionCall2Coll(opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, constval, sslot.values[i]))) nmatch++; @@ -772,8 +839,10 @@ histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, * Note that the result disregards both the most-common-values (if any) and * null entries. The caller is expected to combine this result with * statistics for those portions of the column population. + * + * This is exported so that some other estimation functions can use it. */ -static double +double ineq_histogram_selectivity(PlannerInfo *root, VariableStatData *vardata, FmgrInfo *opproc, bool isgt, bool iseq, @@ -865,7 +934,7 @@ ineq_histogram_selectivity(PlannerInfo *root, &sslot.values[probe]); ltcmp = DatumGetBool(FunctionCall2Coll(opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, sslot.values[probe], constval)); if (isgt) @@ -950,7 +1019,8 @@ ineq_histogram_selectivity(PlannerInfo *root, * values to a uniform comparison scale, and do a linear * interpolation within this bin. */ - if (convert_to_scalar(constval, consttype, &val, + if (convert_to_scalar(constval, consttype, sslot.stacoll, + &val, sslot.values[i - 1], sslot.values[i], vardata->vartype, &low, &high)) @@ -1185,363 +1255,6 @@ scalargesel(PG_FUNCTION_ARGS) return scalarineqsel_wrapper(fcinfo, true, true); } -/* - * patternsel - Generic code for pattern-match selectivity. - */ -static double -patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) -{ - PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); - Oid operator = PG_GETARG_OID(1); - List *args = (List *) PG_GETARG_POINTER(2); - int varRelid = PG_GETARG_INT32(3); - Oid collation = PG_GET_COLLATION(); - VariableStatData vardata; - Node *other; - bool varonleft; - Datum constval; - Oid consttype; - Oid vartype; - Oid opfamily; - Pattern_Prefix_Status pstatus; - Const *patt; - Const *prefix = NULL; - Selectivity rest_selec = 0; - double nullfrac = 0.0; - double result; - - /* - * If this is for a NOT LIKE or similar operator, get the corresponding - * positive-match operator and work with that. Set result to the correct - * default estimate, too. - */ - if (negate) - { - operator = get_negator(operator); - if (!OidIsValid(operator)) - elog(ERROR, "patternsel called for operator without a negator"); - result = 1.0 - DEFAULT_MATCH_SEL; - } - else - { - result = DEFAULT_MATCH_SEL; - } - - /* - * If expression is not variable op constant, then punt and return a - * default estimate. - */ - if (!get_restriction_variable(root, args, varRelid, - &vardata, &other, &varonleft)) - return result; - if (!varonleft || !IsA(other, Const)) - { - ReleaseVariableStats(vardata); - return result; - } - - /* - * If the constant is NULL, assume operator is strict and return zero, ie, - * operator will never return TRUE. (It's zero even for a negator op.) - */ - if (((Const *) other)->constisnull) - { - ReleaseVariableStats(vardata); - return 0.0; - } - constval = ((Const *) other)->constvalue; - consttype = ((Const *) other)->consttype; - - /* - * The right-hand const is type text or bytea for all supported operators. - * We do not expect to see binary-compatible types here, since - * const-folding should have relabeled the const to exactly match the - * operator's declared type. - */ - if (consttype != TEXTOID && consttype != BYTEAOID) - { - ReleaseVariableStats(vardata); - return result; - } - - /* - * Similarly, the exposed type of the left-hand side should be one of - * those we know. (Do not look at vardata.atttype, which might be - * something binary-compatible but different.) We can use it to choose - * the index opfamily from which we must draw the comparison operators. - * - * NOTE: It would be more correct to use the PATTERN opfamilies than the - * simple ones, but at the moment ANALYZE will not generate statistics for - * the PATTERN operators. But our results are so approximate anyway that - * it probably hardly matters. - */ - vartype = vardata.vartype; - - switch (vartype) - { - case TEXTOID: - opfamily = TEXT_BTREE_FAM_OID; - break; - case BPCHAROID: - opfamily = BPCHAR_BTREE_FAM_OID; - break; - case NAMEOID: - opfamily = NAME_BTREE_FAM_OID; - break; - case BYTEAOID: - opfamily = BYTEA_BTREE_FAM_OID; - break; - default: - ReleaseVariableStats(vardata); - return result; - } - - /* - * Grab the nullfrac for use below. - */ - if (HeapTupleIsValid(vardata.statsTuple)) - { - Form_pg_statistic stats; - - stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple); - nullfrac = stats->stanullfrac; - } - - /* - * Pull out any fixed prefix implied by the pattern, and estimate the - * fractional selectivity of the remainder of the pattern. Unlike many of - * the other functions in this file, we use the pattern operator's actual - * collation for this step. This is not because we expect the collation - * to make a big difference in the selectivity estimate (it seldom would), - * but because we want to be sure we cache compiled regexps under the - * right cache key, so that they can be re-used at runtime. - */ - patt = (Const *) other; - pstatus = pattern_fixed_prefix(patt, ptype, collation, - &prefix, &rest_selec); - - /* - * If necessary, coerce the prefix constant to the right type. - */ - if (prefix && prefix->consttype != vartype) - { - char *prefixstr; - - switch (prefix->consttype) - { - case TEXTOID: - prefixstr = TextDatumGetCString(prefix->constvalue); - break; - case BYTEAOID: - prefixstr = DatumGetCString(DirectFunctionCall1(byteaout, - prefix->constvalue)); - break; - default: - elog(ERROR, "unrecognized consttype: %u", - prefix->consttype); - ReleaseVariableStats(vardata); - return result; - } - prefix = string_to_const(prefixstr, vartype); - pfree(prefixstr); - } - - if (pstatus == Pattern_Prefix_Exact) - { - /* - * Pattern specifies an exact match, so pretend operator is '=' - */ - Oid eqopr = get_opfamily_member(opfamily, vartype, vartype, - BTEqualStrategyNumber); - - if (eqopr == InvalidOid) - elog(ERROR, "no = operator for opfamily %u", opfamily); - result = var_eq_const(&vardata, eqopr, prefix->constvalue, - false, true, false); - } - else - { - /* - * Not exact-match pattern. If we have a sufficiently large - * histogram, estimate selectivity for the histogram part of the - * population by counting matches in the histogram. If not, estimate - * selectivity of the fixed prefix and remainder of pattern - * separately, then combine the two to get an estimate of the - * selectivity for the part of the column population represented by - * the histogram. (For small histograms, we combine these - * approaches.) - * - * We then add up data for any most-common-values values; these are - * not in the histogram population, and we can get exact answers for - * them by applying the pattern operator, so there's no reason to - * approximate. (If the MCVs cover a significant part of the total - * population, this gives us a big leg up in accuracy.) - */ - Selectivity selec; - int hist_size; - FmgrInfo opproc; - double mcv_selec, - sumcommon; - - /* Try to use the histogram entries to get selectivity */ - fmgr_info(get_opcode(operator), &opproc); - - selec = histogram_selectivity(&vardata, &opproc, constval, true, - 10, 1, &hist_size); - - /* If not at least 100 entries, use the heuristic method */ - if (hist_size < 100) - { - Selectivity heursel; - Selectivity prefixsel; - - if (pstatus == Pattern_Prefix_Partial) - prefixsel = prefix_selectivity(root, &vardata, vartype, - opfamily, prefix); - else - prefixsel = 1.0; - heursel = prefixsel * rest_selec; - - if (selec < 0) /* fewer than 10 histogram entries? */ - selec = heursel; - else - { - /* - * For histogram sizes from 10 to 100, we combine the - * histogram and heuristic selectivities, putting increasingly - * more trust in the histogram for larger sizes. - */ - double hist_weight = hist_size / 100.0; - - selec = selec * hist_weight + heursel * (1.0 - hist_weight); - } - } - - /* In any case, don't believe extremely small or large estimates. */ - if (selec < 0.0001) - selec = 0.0001; - else if (selec > 0.9999) - selec = 0.9999; - - /* - * If we have most-common-values info, add up the fractions of the MCV - * entries that satisfy MCV OP PATTERN. These fractions contribute - * directly to the result selectivity. Also add up the total fraction - * represented by MCV entries. - */ - mcv_selec = mcv_selectivity(&vardata, &opproc, constval, true, - &sumcommon); - - /* - * Now merge the results from the MCV and histogram calculations, - * realizing that the histogram covers only the non-null values that - * are not listed in MCV. - */ - selec *= 1.0 - nullfrac - sumcommon; - selec += mcv_selec; - result = selec; - } - - /* now adjust if we wanted not-match rather than match */ - if (negate) - result = 1.0 - result - nullfrac; - - /* result should be in range, but make sure... */ - CLAMP_PROBABILITY(result); - - if (prefix) - { - pfree(DatumGetPointer(prefix->constvalue)); - pfree(prefix); - } - - ReleaseVariableStats(vardata); - - return result; -} - -/* - * regexeqsel - Selectivity of regular-expression pattern match. - */ -Datum -regexeqsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, false)); -} - -/* - * icregexeqsel - Selectivity of case-insensitive regex match. - */ -Datum -icregexeqsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, false)); -} - -/* - * likesel - Selectivity of LIKE pattern match. - */ -Datum -likesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, false)); -} - -/* - * prefixsel - selectivity of prefix operator - */ -Datum -prefixsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Prefix, false)); -} - -/* - * - * iclikesel - Selectivity of ILIKE pattern match. - */ -Datum -iclikesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, false)); -} - -/* - * regexnesel - Selectivity of regular-expression pattern non-match. - */ -Datum -regexnesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex, true)); -} - -/* - * icregexnesel - Selectivity of case-insensitive regex non-match. - */ -Datum -icregexnesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Regex_IC, true)); -} - -/* - * nlikesel - Selectivity of LIKE pattern non-match. - */ -Datum -nlikesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like, true)); -} - -/* - * icnlikesel - Selectivity of ILIKE pattern non-match. - */ -Datum -icnlikesel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternsel(fcinfo, Pattern_Type_Like_IC, true)); -} - /* * boolvarsel - Selectivity of Boolean variable. * @@ -1566,17 +1279,6 @@ boolvarsel(PlannerInfo *root, Node *arg, int varRelid) selec = var_eq_const(&vardata, BooleanEqualOperator, BoolGetDatum(true), false, true, false); } - else if (is_funcclause(arg)) - { - /* - * If we have no stats and it's a function call, estimate 0.3333333. - * This seems a pretty unprincipled choice, but Postgres has been - * using that estimate for function calls since 1992. The hoariness - * of this behavior suggests that we should not be in too much hurry - * to use another value. - */ - selec = 0.3333333; - } else { /* Otherwise, the default estimate is 0.5 */ @@ -1787,6 +1489,15 @@ nulltestsel(PlannerInfo *root, NullTestType nulltesttype, Node *arg, return (Selectivity) 0; /* keep compiler quiet */ } } + else if (vardata.var && IsA(vardata.var, Var) && + ((Var *) vardata.var)->varattno < 0) + { + /* + * There are no stats for system columns, but we know they are never + * NULL. + */ + selec = (nulltesttype == IS_NULL) ? 0.0 : 1.0; + } else { /* @@ -2292,20 +2003,69 @@ eqjoinsel(PG_FUNCTION_ARGS) #endif SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) PG_GETARG_POINTER(4); double selec; + double selec_inner; VariableStatData vardata1; VariableStatData vardata2; + double nd1; + double nd2; + bool isdefault1; + bool isdefault2; + Oid opfuncoid; + AttStatsSlot sslot1; + AttStatsSlot sslot2; + Form_pg_statistic stats1 = NULL; + Form_pg_statistic stats2 = NULL; + bool have_mcvs1 = false; + bool have_mcvs2 = false; bool join_is_reversed; RelOptInfo *inner_rel; get_join_variables(root, args, sjinfo, &vardata1, &vardata2, &join_is_reversed); + nd1 = get_variable_numdistinct(&vardata1, &isdefault1); + nd2 = get_variable_numdistinct(&vardata2, &isdefault2); + + opfuncoid = get_opcode(operator); + + memset(&sslot1, 0, sizeof(sslot1)); + memset(&sslot2, 0, sizeof(sslot2)); + + if (HeapTupleIsValid(vardata1.statsTuple)) + { + /* note we allow use of nullfrac regardless of security check */ + stats1 = (Form_pg_statistic) GETSTRUCT(vardata1.statsTuple); + if (statistic_proc_security_check(&vardata1, opfuncoid)) + have_mcvs1 = get_attstatsslot(&sslot1, vardata1.statsTuple, + STATISTIC_KIND_MCV, InvalidOid, + ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS); + } + + if (HeapTupleIsValid(vardata2.statsTuple)) + { + /* note we allow use of nullfrac regardless of security check */ + stats2 = (Form_pg_statistic) GETSTRUCT(vardata2.statsTuple); + if (statistic_proc_security_check(&vardata2, opfuncoid)) + have_mcvs2 = get_attstatsslot(&sslot2, vardata2.statsTuple, + STATISTIC_KIND_MCV, InvalidOid, + ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS); + } + + /* We need to compute the inner-join selectivity in all cases */ + selec_inner = eqjoinsel_inner(opfuncoid, + &vardata1, &vardata2, + nd1, nd2, + isdefault1, isdefault2, + &sslot1, &sslot2, + stats1, stats2, + have_mcvs1, have_mcvs2); + switch (sjinfo->jointype) { case JOIN_INNER: case JOIN_LEFT: case JOIN_FULL: - selec = eqjoinsel_inner(operator, &vardata1, &vardata2); + selec = selec_inner; break; case JOIN_SEMI: case JOIN_ANTI: @@ -2319,12 +2079,40 @@ eqjoinsel(PG_FUNCTION_ARGS) inner_rel = find_join_input_rel(root, sjinfo->min_righthand); if (!join_is_reversed) - selec = eqjoinsel_semi(operator, &vardata1, &vardata2, + selec = eqjoinsel_semi(opfuncoid, + &vardata1, &vardata2, + nd1, nd2, + isdefault1, isdefault2, + &sslot1, &sslot2, + stats1, stats2, + have_mcvs1, have_mcvs2, inner_rel); else - selec = eqjoinsel_semi(get_commutator(operator), + { + Oid commop = get_commutator(operator); + Oid commopfuncoid = OidIsValid(commop) ? get_opcode(commop) : InvalidOid; + + selec = eqjoinsel_semi(commopfuncoid, &vardata2, &vardata1, + nd2, nd1, + isdefault2, isdefault1, + &sslot2, &sslot1, + stats2, stats1, + have_mcvs2, have_mcvs1, inner_rel); + } + + /* + * We should never estimate the output of a semijoin to be more + * rows than we estimate for an inner join with the same input + * rels and join condition; it's obviously impossible for that to + * happen. The former estimate is N1 * Ssemi while the latter is + * N1 * N2 * Sinner, so we may clamp Ssemi <= N2 * Sinner. Doing + * this is worthwhile because of the shakier estimation rules we + * use in eqjoinsel_semi, particularly in cases where it has to + * punt entirely. + */ + selec = Min(selec, inner_rel->rows * selec_inner); break; default: /* other values not expected here */ @@ -2334,6 +2122,9 @@ eqjoinsel(PG_FUNCTION_ARGS) break; } + free_attstatsslot(&sslot1); + free_attstatsslot(&sslot2); + ReleaseVariableStats(vardata1); ReleaseVariableStats(vardata2); @@ -2349,49 +2140,15 @@ eqjoinsel(PG_FUNCTION_ARGS) * that it's worth trying to distinguish them here. */ static double -eqjoinsel_inner(Oid operator, - VariableStatData *vardata1, VariableStatData *vardata2) +eqjoinsel_inner(Oid opfuncoid, + VariableStatData *vardata1, VariableStatData *vardata2, + double nd1, double nd2, + bool isdefault1, bool isdefault2, + AttStatsSlot *sslot1, AttStatsSlot *sslot2, + Form_pg_statistic stats1, Form_pg_statistic stats2, + bool have_mcvs1, bool have_mcvs2) { double selec; - double nd1; - double nd2; - bool isdefault1; - bool isdefault2; - Oid opfuncoid; - Form_pg_statistic stats1 = NULL; - Form_pg_statistic stats2 = NULL; - bool have_mcvs1 = false; - bool have_mcvs2 = false; - AttStatsSlot sslot1; - AttStatsSlot sslot2; - - nd1 = get_variable_numdistinct(vardata1, &isdefault1); - nd2 = get_variable_numdistinct(vardata2, &isdefault2); - - opfuncoid = get_opcode(operator); - - memset(&sslot1, 0, sizeof(sslot1)); - memset(&sslot2, 0, sizeof(sslot2)); - - if (HeapTupleIsValid(vardata1->statsTuple)) - { - /* note we allow use of nullfrac regardless of security check */ - stats1 = (Form_pg_statistic) GETSTRUCT(vardata1->statsTuple); - if (statistic_proc_security_check(vardata1, opfuncoid)) - have_mcvs1 = get_attstatsslot(&sslot1, vardata1->statsTuple, - STATISTIC_KIND_MCV, InvalidOid, - ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS); - } - - if (HeapTupleIsValid(vardata2->statsTuple)) - { - /* note we allow use of nullfrac regardless of security check */ - stats2 = (Form_pg_statistic) GETSTRUCT(vardata2->statsTuple); - if (statistic_proc_security_check(vardata2, opfuncoid)) - have_mcvs2 = get_attstatsslot(&sslot2, vardata2->statsTuple, - STATISTIC_KIND_MCV, InvalidOid, - ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS); - } if (have_mcvs1 && have_mcvs2) { @@ -2425,8 +2182,8 @@ eqjoinsel_inner(Oid operator, nmatches; fmgr_info(opfuncoid, &eqproc); - hasmatch1 = (bool *) palloc0(sslot1.nvalues * sizeof(bool)); - hasmatch2 = (bool *) palloc0(sslot2.nvalues * sizeof(bool)); + hasmatch1 = (bool *) palloc0(sslot1->nvalues * sizeof(bool)); + hasmatch2 = (bool *) palloc0(sslot2->nvalues * sizeof(bool)); /* * Note we assume that each MCV will match at most one member of the @@ -2436,21 +2193,21 @@ eqjoinsel_inner(Oid operator, */ matchprodfreq = 0.0; nmatches = 0; - for (i = 0; i < sslot1.nvalues; i++) + for (i = 0; i < sslot1->nvalues; i++) { int j; - for (j = 0; j < sslot2.nvalues; j++) + for (j = 0; j < sslot2->nvalues; j++) { if (hasmatch2[j]) continue; if (DatumGetBool(FunctionCall2Coll(&eqproc, - DEFAULT_COLLATION_OID, - sslot1.values[i], - sslot2.values[j]))) + sslot1->stacoll, + sslot1->values[i], + sslot2->values[j]))) { hasmatch1[i] = hasmatch2[j] = true; - matchprodfreq += sslot1.numbers[i] * sslot2.numbers[j]; + matchprodfreq += sslot1->numbers[i] * sslot2->numbers[j]; nmatches++; break; } @@ -2459,22 +2216,22 @@ eqjoinsel_inner(Oid operator, CLAMP_PROBABILITY(matchprodfreq); /* Sum up frequencies of matched and unmatched MCVs */ matchfreq1 = unmatchfreq1 = 0.0; - for (i = 0; i < sslot1.nvalues; i++) + for (i = 0; i < sslot1->nvalues; i++) { if (hasmatch1[i]) - matchfreq1 += sslot1.numbers[i]; + matchfreq1 += sslot1->numbers[i]; else - unmatchfreq1 += sslot1.numbers[i]; + unmatchfreq1 += sslot1->numbers[i]; } CLAMP_PROBABILITY(matchfreq1); CLAMP_PROBABILITY(unmatchfreq1); matchfreq2 = unmatchfreq2 = 0.0; - for (i = 0; i < sslot2.nvalues; i++) + for (i = 0; i < sslot2->nvalues; i++) { if (hasmatch2[i]) - matchfreq2 += sslot2.numbers[i]; + matchfreq2 += sslot2->numbers[i]; else - unmatchfreq2 += sslot2.numbers[i]; + unmatchfreq2 += sslot2->numbers[i]; } CLAMP_PROBABILITY(matchfreq2); CLAMP_PROBABILITY(unmatchfreq2); @@ -2499,15 +2256,15 @@ eqjoinsel_inner(Oid operator, * MCVs plus non-MCV values. */ totalsel1 = matchprodfreq; - if (nd2 > sslot2.nvalues) - totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2.nvalues); + if (nd2 > sslot2->nvalues) + totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - sslot2->nvalues); if (nd2 > nmatches) totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) / (nd2 - nmatches); /* Same estimate from the point of view of relation 2. */ totalsel2 = matchprodfreq; - if (nd1 > sslot1.nvalues) - totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1.nvalues); + if (nd1 > sslot1->nvalues) + totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - sslot1->nvalues); if (nd1 > nmatches) totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) / (nd1 - nmatches); @@ -2552,9 +2309,6 @@ eqjoinsel_inner(Oid operator, selec /= nd2; } - free_attstatsslot(&sslot1); - free_attstatsslot(&sslot2); - return selec; } @@ -2563,32 +2317,19 @@ eqjoinsel_inner(Oid operator, * * (Also used for anti join, which we are supposed to estimate the same way.) * Caller has ensured that vardata1 is the LHS variable. - * Unlike eqjoinsel_inner, we have to cope with operator being InvalidOid. + * Unlike eqjoinsel_inner, we have to cope with opfuncoid being InvalidOid. */ static double -eqjoinsel_semi(Oid operator, +eqjoinsel_semi(Oid opfuncoid, VariableStatData *vardata1, VariableStatData *vardata2, + double nd1, double nd2, + bool isdefault1, bool isdefault2, + AttStatsSlot *sslot1, AttStatsSlot *sslot2, + Form_pg_statistic stats1, Form_pg_statistic stats2, + bool have_mcvs1, bool have_mcvs2, RelOptInfo *inner_rel) { double selec; - double nd1; - double nd2; - bool isdefault1; - bool isdefault2; - Oid opfuncoid; - Form_pg_statistic stats1 = NULL; - bool have_mcvs1 = false; - bool have_mcvs2 = false; - AttStatsSlot sslot1; - AttStatsSlot sslot2; - - nd1 = get_variable_numdistinct(vardata1, &isdefault1); - nd2 = get_variable_numdistinct(vardata2, &isdefault2); - - opfuncoid = OidIsValid(operator) ? get_opcode(operator) : InvalidOid; - - memset(&sslot1, 0, sizeof(sslot1)); - memset(&sslot2, 0, sizeof(sslot2)); /* * We clamp nd2 to be not more than what we estimate the inner relation's @@ -2623,26 +2364,7 @@ eqjoinsel_semi(Oid operator, isdefault2 = false; } - if (HeapTupleIsValid(vardata1->statsTuple)) - { - /* note we allow use of nullfrac regardless of security check */ - stats1 = (Form_pg_statistic) GETSTRUCT(vardata1->statsTuple); - if (statistic_proc_security_check(vardata1, opfuncoid)) - have_mcvs1 = get_attstatsslot(&sslot1, vardata1->statsTuple, - STATISTIC_KIND_MCV, InvalidOid, - ATTSTATSSLOT_VALUES | ATTSTATSSLOT_NUMBERS); - } - - if (HeapTupleIsValid(vardata2->statsTuple) && - statistic_proc_security_check(vardata2, opfuncoid)) - { - have_mcvs2 = get_attstatsslot(&sslot2, vardata2->statsTuple, - STATISTIC_KIND_MCV, InvalidOid, - ATTSTATSSLOT_VALUES); - /* note: currently don't need stanumbers from RHS */ - } - - if (have_mcvs1 && have_mcvs2 && OidIsValid(operator)) + if (have_mcvs1 && have_mcvs2 && OidIsValid(opfuncoid)) { /* * We have most-common-value lists for both relations. Run through @@ -2665,15 +2387,15 @@ eqjoinsel_semi(Oid operator, /* * The clamping above could have resulted in nd2 being less than - * sslot2.nvalues; in which case, we assume that precisely the nd2 + * sslot2->nvalues; in which case, we assume that precisely the nd2 * most common values in the relation will appear in the join input, * and so compare to only the first nd2 members of the MCV list. Of * course this is frequently wrong, but it's the best bet we can make. */ - clamped_nvalues2 = Min(sslot2.nvalues, nd2); + clamped_nvalues2 = Min(sslot2->nvalues, nd2); fmgr_info(opfuncoid, &eqproc); - hasmatch1 = (bool *) palloc0(sslot1.nvalues * sizeof(bool)); + hasmatch1 = (bool *) palloc0(sslot1->nvalues * sizeof(bool)); hasmatch2 = (bool *) palloc0(clamped_nvalues2 * sizeof(bool)); /* @@ -2683,7 +2405,7 @@ eqjoinsel_semi(Oid operator, * and because the math wouldn't add up... */ nmatches = 0; - for (i = 0; i < sslot1.nvalues; i++) + for (i = 0; i < sslot1->nvalues; i++) { int j; @@ -2692,9 +2414,9 @@ eqjoinsel_semi(Oid operator, if (hasmatch2[j]) continue; if (DatumGetBool(FunctionCall2Coll(&eqproc, - DEFAULT_COLLATION_OID, - sslot1.values[i], - sslot2.values[j]))) + sslot1->stacoll, + sslot1->values[i], + sslot2->values[j]))) { hasmatch1[i] = hasmatch2[j] = true; nmatches++; @@ -2704,10 +2426,10 @@ eqjoinsel_semi(Oid operator, } /* Sum up frequencies of matched MCVs */ matchfreq1 = 0.0; - for (i = 0; i < sslot1.nvalues; i++) + for (i = 0; i < sslot1->nvalues; i++) { if (hasmatch1[i]) - matchfreq1 += sslot1.numbers[i]; + matchfreq1 += sslot1->numbers[i]; } CLAMP_PROBABILITY(matchfreq1); pfree(hasmatch1); @@ -2762,9 +2484,6 @@ eqjoinsel_semi(Oid operator, selec = 0.5 * (1.0 - nullfrac1); } - free_attstatsslot(&sslot1); - free_attstatsslot(&sslot2); - return selec; } @@ -2879,96 +2598,6 @@ scalargejoinsel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL); } -/* - * patternjoinsel - Generic code for pattern-match join selectivity. - */ -static double -patternjoinsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate) -{ - /* For the moment we just punt. */ - return negate ? (1.0 - DEFAULT_MATCH_SEL) : DEFAULT_MATCH_SEL; -} - -/* - * regexeqjoinsel - Join selectivity of regular-expression pattern match. - */ -Datum -regexeqjoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, false)); -} - -/* - * icregexeqjoinsel - Join selectivity of case-insensitive regex match. - */ -Datum -icregexeqjoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, false)); -} - -/* - * likejoinsel - Join selectivity of LIKE pattern match. - */ -Datum -likejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, false)); -} - -/* - * prefixjoinsel - Join selectivity of prefix operator - */ -Datum -prefixjoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Prefix, false)); -} - -/* - * iclikejoinsel - Join selectivity of ILIKE pattern match. - */ -Datum -iclikejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, false)); -} - -/* - * regexnejoinsel - Join selectivity of regex non-match. - */ -Datum -regexnejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex, true)); -} - -/* - * icregexnejoinsel - Join selectivity of case-insensitive regex non-match. - */ -Datum -icregexnejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Regex_IC, true)); -} - -/* - * nlikejoinsel - Join selectivity of LIKE pattern non-match. - */ -Datum -nlikejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like, true)); -} - -/* - * icnlikejoinsel - Join selectivity of ILIKE pattern non-match. - */ -Datum -icnlikejoinsel(PG_FUNCTION_ARGS) -{ - PG_RETURN_FLOAT8(patternjoinsel(fcinfo, Pattern_Type_Like_IC, true)); -} /* * mergejoinscansel - Scan selectivity of merge join. @@ -3308,15 +2937,10 @@ add_unique_group_var(PlannerInfo *root, List *varinfos, ndistinct = get_variable_numdistinct(vardata, &isdefault); - /* cannot use foreach here because of possible list_delete */ - lc = list_head(varinfos); - while (lc) + foreach(lc, varinfos) { varinfo = (GroupVarInfo *) lfirst(lc); - /* must advance lc before list_delete possibly pfree's it */ - lc = lnext(lc); - /* Drop exact duplicates */ if (equal(var, varinfo->var)) return varinfos; @@ -3336,7 +2960,7 @@ add_unique_group_var(PlannerInfo *root, List *varinfos, else { /* Delete the older item */ - varinfos = list_delete_ptr(varinfos, varinfo); + varinfos = foreach_delete_current(varinfos, lc); } } } @@ -3474,7 +3098,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, * pointless to worry too much about this without much better * estimates for SRF output rowcounts than we have today.) */ - this_srf_multiplier = expression_returns_set_rows(groupexpr); + this_srf_multiplier = expression_returns_set_rows(root, groupexpr); if (srf_multiplier < this_srf_multiplier) srf_multiplier = this_srf_multiplier; @@ -3577,20 +3201,20 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, * Split the list of varinfos in two - one for the current rel, one * for remaining Vars on other rels. */ - relvarinfos = lcons(varinfo1, relvarinfos); - for_each_cell(l, lnext(list_head(varinfos))) + relvarinfos = lappend(relvarinfos, varinfo1); + for_each_cell(l, varinfos, list_second_cell(varinfos)) { GroupVarInfo *varinfo2 = (GroupVarInfo *) lfirst(l); if (varinfo2->rel == varinfo1->rel) { /* varinfos on current rel */ - relvarinfos = lcons(varinfo2, relvarinfos); + relvarinfos = lappend(relvarinfos, varinfo2); } else { /* not time to process varinfo2 yet */ - newvarinfos = lcons(varinfo2, newvarinfos); + newvarinfos = lappend(newvarinfos, varinfo2); } } @@ -3884,6 +3508,43 @@ estimate_hash_bucket_stats(PlannerInfo *root, Node *hashkey, double nbuckets, ReleaseVariableStats(vardata); } +/* + * estimate_hashagg_tablesize + * estimate the number of bytes that a hash aggregate hashtable will + * require based on the agg_costs, path width and number of groups. + * + * We return the result as "double" to forestall any possible overflow + * problem in the multiplication by dNumGroups. + * + * XXX this may be over-estimating the size now that hashagg knows to omit + * unneeded columns from the hashtable. Also for mixed-mode grouping sets, + * grouping columns not in the hashed set are counted here even though hashagg + * won't store them. Is this a problem? + */ +double +estimate_hashagg_tablesize(Path *path, const AggClauseCosts *agg_costs, + double dNumGroups) +{ + Size hashentrysize; + + /* Estimate per-hash-entry space at tuple width... */ + hashentrysize = MAXALIGN(path->pathtarget->width) + + MAXALIGN(SizeofMinimalTupleHeader); + + /* plus space for pass-by-ref transition values... */ + hashentrysize += agg_costs->transitionSpace; + /* plus the per-hash-entry overhead */ + hashentrysize += hash_agg_entry_size(agg_costs->numAggs); + + /* + * Note that this disregards the effect of fill-factor and growth policy + * of the hash table. That's probably ok, given that the default + * fill-factor is relatively high. It'd be hard to meaningfully factor in + * "double-in-size" growth policies here. + */ + return hashentrysize * dNumGroups; +} + /*------------------------------------------------------------------------- * @@ -4050,7 +3711,7 @@ estimate_multivariate_ndistinct(PlannerInfo *root, RelOptInfo *rel, * converted to measurements expressed in seconds. */ static bool -convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, +convert_to_scalar(Datum value, Oid valuetypid, Oid collid, double *scaledvalue, Datum lobound, Datum hibound, Oid boundstypid, double *scaledlobound, double *scaledhibound) { @@ -4115,11 +3776,11 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, case NAMEOID: { char *valstr = convert_string_datum(value, valuetypid, - &failure); + collid, &failure); char *lostr = convert_string_datum(lobound, boundstypid, - &failure); + collid, &failure); char *histr = convert_string_datum(hibound, boundstypid, - &failure); + collid, &failure); /* * Bail out if any of the values is not of string type. We @@ -4157,11 +3818,8 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, */ case TIMESTAMPOID: case TIMESTAMPTZOID: - case ABSTIMEOID: case DATEOID: case INTERVALOID: - case RELTIMEOID: - case TINTERVALOID: case TIMEOID: case TIMETZOID: *scaledvalue = convert_timevalue_to_scalar(value, valuetypid, @@ -4391,7 +4049,7 @@ convert_one_string_to_scalar(char *value, int rangelo, int rangehi) * before continuing, so as to generate correct locale-specific results. */ static char * -convert_string_datum(Datum value, Oid typid, bool *failure) +convert_string_datum(Datum value, Oid typid, Oid collid, bool *failure) { char *val; @@ -4419,7 +4077,7 @@ convert_string_datum(Datum value, Oid typid, bool *failure) return NULL; } - if (!lc_collate_is_c(DEFAULT_COLLATION_OID)) + if (!lc_collate_is_c(collid)) { char *xfrmstr; size_t xfrmlen; @@ -4584,9 +4242,6 @@ convert_timevalue_to_scalar(Datum value, Oid typid, bool *failure) return DatumGetTimestamp(value); case TIMESTAMPTZOID: return DatumGetTimestampTz(value); - case ABSTIMEOID: - return DatumGetTimestamp(DirectFunctionCall1(abstime_timestamp, - value)); case DATEOID: return date2timestamp_no_overflow(DatumGetDateADT(value)); case INTERVALOID: @@ -4601,16 +4256,6 @@ convert_timevalue_to_scalar(Datum value, Oid typid, bool *failure) return interval->time + interval->day * (double) USECS_PER_DAY + interval->month * ((DAYS_PER_YEAR / (double) MONTHS_PER_YEAR) * USECS_PER_DAY); } - case RELTIMEOID: - return (DatumGetRelativeTime(value) * 1000000.0); - case TINTERVALOID: - { - TimeInterval tinterval = DatumGetTimeInterval(value); - - if (tinterval->status != 0) - return ((tinterval->data[1] - tinterval->data[0]) * 1000000.0); - return 0; /* for lack of a better idea */ - } case TIMEOID: return DatumGetTimeADT(value); case TIMETZOID: @@ -4868,6 +4513,10 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, * it to expressional index columns, in hopes of finding some * statistics. * + * Note that we consider all index columns including INCLUDE columns, + * since there could be stats for such columns. But the test for + * uniqueness needs to be warier. + * * XXX it's conceivable that there are multiple matches with different * index opfamilies; if so, we need to pick one that matches the * operator we are estimating for. FIXME later. @@ -4903,6 +4552,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, */ if (index->unique && index->nkeycolumns == 1 && + pos == 0 && (index->indpred == NIL || index->predOK)) vardata->isunique = true; @@ -4942,18 +4592,29 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, { /* Get index's table for permission check */ RangeTblEntry *rte; + Oid userid; rte = planner_rt_fetch(index->rel->relid, root); Assert(rte->rtekind == RTE_RELATION); + /* + * Use checkAsUser if it's set, in case we're + * accessing the table via a view. + */ + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + /* * For simplicity, we insist on the whole * table being selectable, rather than trying * to identify which column(s) the index - * depends on. + * depends on. Also require all rows to be + * selectable --- there must be no + * securityQuals from security barrier views + * or RLS policies. */ vardata->acl_ok = - (pg_class_aclcheck(rte->relid, GetUserId(), + rte->securityQuals == NIL && + (pg_class_aclcheck(rte->relid, userid, ACL_SELECT) == ACLCHECK_OK); } else @@ -4965,7 +4626,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid, if (vardata->statsTuple) break; } - indexpr_item = lnext(indexpr_item); + indexpr_item = lnext(index->indexprs, indexpr_item); } } if (vardata->statsTuple) @@ -5016,12 +4677,22 @@ examine_simple_variable(PlannerInfo *root, Var *var, if (HeapTupleIsValid(vardata->statsTuple)) { - /* check if user has permission to read this column */ + Oid userid; + + /* + * Check if user has permission to read this column. We require + * all rows to be accessible, so there must be no securityQuals + * from security barrier views or RLS policies. Use checkAsUser + * if it's set, in case we're accessing the table via a view. + */ + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); + vardata->acl_ok = - (pg_class_aclcheck(rte->relid, GetUserId(), - ACL_SELECT) == ACLCHECK_OK) || - (pg_attribute_aclcheck(rte->relid, var->varattno, GetUserId(), - ACL_SELECT) == ACLCHECK_OK); + rte->securityQuals == NIL && + ((pg_class_aclcheck(rte->relid, userid, + ACL_SELECT) == ACLCHECK_OK) || + (pg_attribute_aclcheck(rte->relid, var->varattno, userid, + ACL_SELECT) == ACLCHECK_OK)); } else { @@ -5234,7 +4905,6 @@ get_variable_numdistinct(VariableStatData *vardata, bool *isdefault) { switch (((Var *) vardata->var)->varattno) { - case ObjectIdAttributeNumber: case SelfItemPointerAttributeNumber: stadistinct = -1.0; /* unique (and all non null) */ break; @@ -5408,14 +5078,14 @@ get_variable_range(PlannerInfo *root, VariableStatData *vardata, Oid sortop, continue; } if (DatumGetBool(FunctionCall2Coll(&opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, sslot.values[i], tmin))) { tmin = sslot.values[i]; tmin_is_mcv = true; } if (DatumGetBool(FunctionCall2Coll(&opproc, - DEFAULT_COLLATION_OID, + sslot.stacoll, tmax, sslot.values[i]))) { tmax = sslot.values[i]; @@ -5513,49 +5183,35 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata, } /* - * Found a suitable index to extract data from. We'll need an EState - * and a bunch of other infrastructure. + * Found a suitable index to extract data from. Set up some data that + * can be used by both invocations of get_actual_variable_endpoint. */ { - EState *estate; - ExprContext *econtext; MemoryContext tmpcontext; MemoryContext oldcontext; Relation heapRel; Relation indexRel; - IndexInfo *indexInfo; TupleTableSlot *slot; int16 typLen; bool typByVal; ScanKeyData scankeys[1]; - IndexScanDesc index_scan; - HeapTuple tup; - Datum values[INDEX_MAX_KEYS]; - bool isnull[INDEX_MAX_KEYS]; - SnapshotData SnapshotNonVacuumable; - - estate = CreateExecutorState(); - econtext = GetPerTupleExprContext(estate); - /* Make sure any cruft is generated in the econtext's memory */ - tmpcontext = econtext->ecxt_per_tuple_memory; + + /* Make sure any cruft gets recycled when we're done */ + tmpcontext = AllocSetContextCreate(CurrentMemoryContext, + "get_actual_variable_range workspace", + ALLOCSET_DEFAULT_SIZES); oldcontext = MemoryContextSwitchTo(tmpcontext); /* * Open the table and index so we can read from them. We should - * already have at least AccessShareLock on the table, but not - * necessarily on the index. + * already have some type of lock on each. */ - heapRel = heap_open(rte->relid, NoLock); - indexRel = index_open(index->indexoid, AccessShareLock); - - /* extract index key information from the index's pg_index info */ - indexInfo = BuildIndexInfo(indexRel); + heapRel = table_open(rte->relid, NoLock); + indexRel = index_open(index->indexoid, NoLock); - /* some other stuff */ - slot = MakeSingleTupleTableSlot(RelationGetDescr(heapRel)); - econtext->ecxt_scantuple = slot; + /* build some stuff needed for indexscan execution */ + slot = table_slot_create(heapRel, NULL); get_typlenbyval(vardata->atttype, &typLen, &typByVal); - InitNonVacuumableSnapshot(SnapshotNonVacuumable, RecentGlobalXmin); /* set up an IS NOT NULL scan key so that we ignore nulls */ ScanKeyEntryInitialize(&scankeys[0], @@ -5567,108 +5223,48 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata, InvalidOid, /* no reg proc for this */ (Datum) 0); /* constant */ - have_data = true; - /* If min is requested ... */ if (min) { - /* - * In principle, we should scan the index with our current - * active snapshot, which is the best approximation we've got - * to what the query will see when executed. But that won't - * be exact if a new snap is taken before running the query, - * and it can be very expensive if a lot of recently-dead or - * uncommitted rows exist at the beginning or end of the index - * (because we'll laboriously fetch each one and reject it). - * Instead, we use SnapshotNonVacuumable. That will accept - * recently-dead and uncommitted rows as well as normal - * visible rows. On the other hand, it will reject known-dead - * rows, and thus not give a bogus answer when the extreme - * value has been deleted (unless the deletion was quite - * recent); that case motivates not using SnapshotAny here. - * - * A crucial point here is that SnapshotNonVacuumable, with - * RecentGlobalXmin as horizon, yields the inverse of the - * condition that the indexscan will use to decide that index - * entries are killable (see heap_hot_search_buffer()). - * Therefore, if the snapshot rejects a tuple and we have to - * continue scanning past it, we know that the indexscan will - * mark that index entry killed. That means that the next - * get_actual_variable_range() call will not have to visit - * that heap entry. In this way we avoid repetitive work when - * this function is used a lot during planning. - */ - index_scan = index_beginscan(heapRel, indexRel, - &SnapshotNonVacuumable, - 1, 0); - index_rescan(index_scan, scankeys, 1, NULL, 0); - - /* Fetch first tuple in sortop's direction */ - if ((tup = index_getnext(index_scan, - indexscandir)) != NULL) - { - /* Extract the index column values from the heap tuple */ - ExecStoreTuple(tup, slot, InvalidBuffer, false); - FormIndexDatum(indexInfo, slot, estate, - values, isnull); - - /* Shouldn't have got a null, but be careful */ - if (isnull[0]) - elog(ERROR, "found unexpected null value in index \"%s\"", - RelationGetRelationName(indexRel)); - - /* Copy the index column value out to caller's context */ - MemoryContextSwitchTo(oldcontext); - *min = datumCopy(values[0], typByVal, typLen); - MemoryContextSwitchTo(tmpcontext); - } - else - have_data = false; - - index_endscan(index_scan); + have_data = get_actual_variable_endpoint(heapRel, + indexRel, + indexscandir, + scankeys, + typLen, + typByVal, + slot, + oldcontext, + min); + } + else + { + /* If min not requested, assume index is nonempty */ + have_data = true; } /* If max is requested, and we didn't find the index is empty */ if (max && have_data) { - index_scan = index_beginscan(heapRel, indexRel, - &SnapshotNonVacuumable, - 1, 0); - index_rescan(index_scan, scankeys, 1, NULL, 0); - - /* Fetch first tuple in reverse direction */ - if ((tup = index_getnext(index_scan, - -indexscandir)) != NULL) - { - /* Extract the index column values from the heap tuple */ - ExecStoreTuple(tup, slot, InvalidBuffer, false); - FormIndexDatum(indexInfo, slot, estate, - values, isnull); - - /* Shouldn't have got a null, but be careful */ - if (isnull[0]) - elog(ERROR, "found unexpected null value in index \"%s\"", - RelationGetRelationName(indexRel)); - - /* Copy the index column value out to caller's context */ - MemoryContextSwitchTo(oldcontext); - *max = datumCopy(values[0], typByVal, typLen); - MemoryContextSwitchTo(tmpcontext); - } - else - have_data = false; - - index_endscan(index_scan); + /* scan in the opposite direction; all else is the same */ + have_data = get_actual_variable_endpoint(heapRel, + indexRel, + -indexscandir, + scankeys, + typLen, + typByVal, + slot, + oldcontext, + max); } /* Clean everything up */ ExecDropSingleTupleTableSlot(slot); - index_close(indexRel, AccessShareLock); - heap_close(heapRel, NoLock); + index_close(indexRel, NoLock); + table_close(heapRel, NoLock); MemoryContextSwitchTo(oldcontext); - FreeExecutorState(estate); + MemoryContextDelete(tmpcontext); /* And we're done */ break; @@ -5678,6 +5274,139 @@ get_actual_variable_range(PlannerInfo *root, VariableStatData *vardata, return have_data; } +/* + * Get one endpoint datum (min or max depending on indexscandir) from the + * specified index. Return true if successful, false if index is empty. + * On success, endpoint value is stored to *endpointDatum (and copied into + * outercontext). + * + * scankeys is a 1-element scankey array set up to reject nulls. + * typLen/typByVal describe the datatype of the index's first column. + * tableslot is a slot suitable to hold table tuples, in case we need + * to probe the heap. + * (We could compute these values locally, but that would mean computing them + * twice when get_actual_variable_range needs both the min and the max.) + */ +static bool +get_actual_variable_endpoint(Relation heapRel, + Relation indexRel, + ScanDirection indexscandir, + ScanKey scankeys, + int16 typLen, + bool typByVal, + TupleTableSlot *tableslot, + MemoryContext outercontext, + Datum *endpointDatum) +{ + bool have_data = false; + SnapshotData SnapshotNonVacuumable; + IndexScanDesc index_scan; + Buffer vmbuffer = InvalidBuffer; + ItemPointer tid; + Datum values[INDEX_MAX_KEYS]; + bool isnull[INDEX_MAX_KEYS]; + MemoryContext oldcontext; + + /* + * We use the index-only-scan machinery for this. With mostly-static + * tables that's a win because it avoids a heap visit. It's also a win + * for dynamic data, but the reason is less obvious; read on for details. + * + * In principle, we should scan the index with our current active + * snapshot, which is the best approximation we've got to what the query + * will see when executed. But that won't be exact if a new snap is taken + * before running the query, and it can be very expensive if a lot of + * recently-dead or uncommitted rows exist at the beginning or end of the + * index (because we'll laboriously fetch each one and reject it). + * Instead, we use SnapshotNonVacuumable. That will accept recently-dead + * and uncommitted rows as well as normal visible rows. On the other + * hand, it will reject known-dead rows, and thus not give a bogus answer + * when the extreme value has been deleted (unless the deletion was quite + * recent); that case motivates not using SnapshotAny here. + * + * A crucial point here is that SnapshotNonVacuumable, with + * RecentGlobalXmin as horizon, yields the inverse of the condition that + * the indexscan will use to decide that index entries are killable (see + * heap_hot_search_buffer()). Therefore, if the snapshot rejects a tuple + * (or more precisely, all tuples of a HOT chain) and we have to continue + * scanning past it, we know that the indexscan will mark that index entry + * killed. That means that the next get_actual_variable_endpoint() call + * will not have to re-consider that index entry. In this way we avoid + * repetitive work when this function is used a lot during planning. + * + * But using SnapshotNonVacuumable creates a hazard of its own. In a + * recently-created index, some index entries may point at "broken" HOT + * chains in which not all the tuple versions contain data matching the + * index entry. The live tuple version(s) certainly do match the index, + * but SnapshotNonVacuumable can accept recently-dead tuple versions that + * don't match. Hence, if we took data from the selected heap tuple, we + * might get a bogus answer that's not close to the index extremal value, + * or could even be NULL. We avoid this hazard because we take the data + * from the index entry not the heap. + */ + InitNonVacuumableSnapshot(SnapshotNonVacuumable, RecentGlobalXmin); + + index_scan = index_beginscan(heapRel, indexRel, + &SnapshotNonVacuumable, + 1, 0); + /* Set it up for index-only scan */ + index_scan->xs_want_itup = true; + index_rescan(index_scan, scankeys, 1, NULL, 0); + + /* Fetch first/next tuple in specified direction */ + while ((tid = index_getnext_tid(index_scan, indexscandir)) != NULL) + { + if (!VM_ALL_VISIBLE(heapRel, + ItemPointerGetBlockNumber(tid), + &vmbuffer)) + { + /* Rats, we have to visit the heap to check visibility */ + if (!index_fetch_heap(index_scan, tableslot)) + continue; /* no visible tuple, try next index entry */ + + /* We don't actually need the heap tuple for anything */ + ExecClearTuple(tableslot); + + /* + * We don't care whether there's more than one visible tuple in + * the HOT chain; if any are visible, that's good enough. + */ + } + + /* + * We expect that btree will return data in IndexTuple not HeapTuple + * format. It's not lossy either. + */ + if (!index_scan->xs_itup) + elog(ERROR, "no data returned for index-only scan"); + if (index_scan->xs_recheck) + elog(ERROR, "unexpected recheck indication from btree"); + + /* OK to deconstruct the index tuple */ + index_deform_tuple(index_scan->xs_itup, + index_scan->xs_itupdesc, + values, isnull); + + /* Shouldn't have got a null, but be careful */ + if (isnull[0]) + elog(ERROR, "found unexpected null value in index \"%s\"", + RelationGetRelationName(indexRel)); + + /* Copy the index column value out to caller's context */ + oldcontext = MemoryContextSwitchTo(outercontext); + *endpointDatum = datumCopy(values[0], typByVal, typLen); + MemoryContextSwitchTo(oldcontext); + have_data = true; + break; + } + + if (vmbuffer != InvalidBuffer) + ReleaseBuffer(vmbuffer); + index_endscan(index_scan); + + return have_data; +} + /* * find_join_input_rel * Look up the input relation for a join. @@ -5712,982 +5441,89 @@ find_join_input_rel(PlannerInfo *root, Relids relids) /*------------------------------------------------------------------------- * - * Pattern analysis functions - * - * These routines support analysis of LIKE and regular-expression patterns - * by the planner/optimizer. It's important that they agree with the - * regular-expression code in backend/regex/ and the LIKE code in - * backend/utils/adt/like.c. Also, the computation of the fixed prefix - * must be conservative: if we report a string longer than the true fixed - * prefix, the query may produce actually wrong answers, rather than just - * getting a bad selectivity estimate! - * - * Note that the prefix-analysis functions are called from - * backend/optimizer/path/indxpath.c as well as from routines in this file. + * Index cost estimation functions * *------------------------------------------------------------------------- */ /* - * Check whether char is a letter (and, hence, subject to case-folding) - * - * In multibyte character sets or with ICU, we can't use isalpha, and it does not seem - * worth trying to convert to wchar_t to use iswalpha. Instead, just assume - * any multibyte char is potentially case-varying. + * Extract the actual indexquals (as RestrictInfos) from an IndexClause list */ -static int -pattern_char_isalpha(char c, bool is_multibyte, - pg_locale_t locale, bool locale_is_c) +List * +get_quals_from_indexclauses(List *indexclauses) { - if (locale_is_c) - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - else if (is_multibyte && IS_HIGHBIT_SET(c)) - return true; - else if (locale && locale->provider == COLLPROVIDER_ICU) - return IS_HIGHBIT_SET(c) ? true : false; -#ifdef HAVE_LOCALE_T - else if (locale && locale->provider == COLLPROVIDER_LIBC) - return isalpha_l((unsigned char) c, locale->info.lt); -#endif - else - return isalpha((unsigned char) c); + List *result = NIL; + ListCell *lc; + + foreach(lc, indexclauses) + { + IndexClause *iclause = lfirst_node(IndexClause, lc); + ListCell *lc2; + + foreach(lc2, iclause->indexquals) + { + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2); + + result = lappend(result, rinfo); + } + } + return result; } /* - * Extract the fixed prefix, if any, for a pattern. - * - * *prefix is set to a palloc'd prefix string (in the form of a Const node), - * or to NULL if no fixed prefix exists for the pattern. - * If rest_selec is not NULL, *rest_selec is set to an estimate of the - * selectivity of the remainder of the pattern (without any fixed prefix). - * The prefix Const has the same type (TEXT or BYTEA) as the input pattern. + * Compute the total evaluation cost of the comparison operands in a list + * of index qual expressions. Since we know these will be evaluated just + * once per scan, there's no need to distinguish startup from per-row cost. * - * The return value distinguishes no fixed prefix, a partial prefix, - * or an exact-match-only pattern. + * This can be used either on the result of get_quals_from_indexclauses(), + * or directly on an indexorderbys list. In both cases, we expect that the + * index key expression is on the left side of binary clauses. */ - -static Pattern_Prefix_Status -like_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation, - Const **prefix_const, Selectivity *rest_selec) +Cost +index_other_operands_eval_cost(PlannerInfo *root, List *indexquals) { - char *match; - char *patt; - int pattlen; - Oid typeid = patt_const->consttype; - int pos, - match_pos; - bool is_multibyte = (pg_database_encoding_max_length() > 1); - pg_locale_t locale = 0; - bool locale_is_c = false; - - /* the right-hand const is type text or bytea */ - Assert(typeid == BYTEAOID || typeid == TEXTOID); - - if (case_insensitive) - { - if (typeid == BYTEAOID) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("case insensitive matching not supported on type bytea"))); - - /* If case-insensitive, we need locale info */ - if (lc_ctype_is_c(collation)) - locale_is_c = true; - else if (collation != DEFAULT_COLLATION_OID) - { - if (!OidIsValid(collation)) - { - /* - * This typically means that the parser could not resolve a - * conflict of implicit collations, so report it that way. - */ - ereport(ERROR, - (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for ILIKE"), - errhint("Use the COLLATE clause to set the collation explicitly."))); - } - locale = pg_newlocale_from_collation(collation); - } - } - - if (typeid != BYTEAOID) - { - patt = TextDatumGetCString(patt_const->constvalue); - pattlen = strlen(patt); - } - else - { - bytea *bstr = DatumGetByteaPP(patt_const->constvalue); - - pattlen = VARSIZE_ANY_EXHDR(bstr); - patt = (char *) palloc(pattlen); - memcpy(patt, VARDATA_ANY(bstr), pattlen); - Assert((Pointer) bstr == DatumGetPointer(patt_const->constvalue)); - } - - match = palloc(pattlen + 1); - match_pos = 0; - for (pos = 0; pos < pattlen; pos++) - { - /* % and _ are wildcard characters in LIKE */ - if (patt[pos] == '%' || - patt[pos] == '_') - break; - - /* Backslash escapes the next character */ - if (patt[pos] == '\\') - { - pos++; - if (pos >= pattlen) - break; - } - - /* Stop if case-varying character (it's sort of a wildcard) */ - if (case_insensitive && - pattern_char_isalpha(patt[pos], is_multibyte, locale, locale_is_c)) - break; - - match[match_pos++] = patt[pos]; - } - - match[match_pos] = '\0'; - - if (typeid != BYTEAOID) - *prefix_const = string_to_const(match, typeid); - else - *prefix_const = string_to_bytea_const(match, match_pos); - - if (rest_selec != NULL) - *rest_selec = like_selectivity(&patt[pos], pattlen - pos, - case_insensitive); - - pfree(patt); - pfree(match); - - /* in LIKE, an empty pattern is an exact match! */ - if (pos == pattlen) - return Pattern_Prefix_Exact; /* reached end of pattern, so exact */ - - if (match_pos > 0) - return Pattern_Prefix_Partial; - - return Pattern_Prefix_None; -} - -static Pattern_Prefix_Status -regex_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation, - Const **prefix_const, Selectivity *rest_selec) -{ - Oid typeid = patt_const->consttype; - char *prefix; - bool exact; - - /* - * Should be unnecessary, there are no bytea regex operators defined. As - * such, it should be noted that the rest of this function has *not* been - * made safe for binary (possibly NULL containing) strings. - */ - if (typeid == BYTEAOID) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("regular-expression matching not supported on type bytea"))); - - /* Use the regexp machinery to extract the prefix, if any */ - prefix = regexp_fixed_prefix(DatumGetTextPP(patt_const->constvalue), - case_insensitive, collation, - &exact); - - if (prefix == NULL) - { - *prefix_const = NULL; - - if (rest_selec != NULL) - { - char *patt = TextDatumGetCString(patt_const->constvalue); - - *rest_selec = regex_selectivity(patt, strlen(patt), - case_insensitive, - 0); - pfree(patt); - } - - return Pattern_Prefix_None; - } - - *prefix_const = string_to_const(prefix, typeid); - - if (rest_selec != NULL) - { - if (exact) - { - /* Exact match, so there's no additional selectivity */ - *rest_selec = 1.0; - } - else - { - char *patt = TextDatumGetCString(patt_const->constvalue); - - *rest_selec = regex_selectivity(patt, strlen(patt), - case_insensitive, - strlen(prefix)); - pfree(patt); - } - } - - pfree(prefix); - - if (exact) - return Pattern_Prefix_Exact; /* pattern specifies exact match */ - else - return Pattern_Prefix_Partial; -} - -Pattern_Prefix_Status -pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation, - Const **prefix, Selectivity *rest_selec) -{ - Pattern_Prefix_Status result; - - switch (ptype) - { - case Pattern_Type_Like: - result = like_fixed_prefix(patt, false, collation, - prefix, rest_selec); - break; - case Pattern_Type_Like_IC: - result = like_fixed_prefix(patt, true, collation, - prefix, rest_selec); - break; - case Pattern_Type_Regex: - result = regex_fixed_prefix(patt, false, collation, - prefix, rest_selec); - break; - case Pattern_Type_Regex_IC: - result = regex_fixed_prefix(patt, true, collation, - prefix, rest_selec); - break; - case Pattern_Type_Prefix: - /* Prefix type work is trivial. */ - result = Pattern_Prefix_Partial; - *rest_selec = 1.0; /* all */ - *prefix = makeConst(patt->consttype, - patt->consttypmod, - patt->constcollid, - patt->constlen, - datumCopy(patt->constvalue, - patt->constbyval, - patt->constlen), - patt->constisnull, - patt->constbyval); - break; - default: - elog(ERROR, "unrecognized ptype: %d", (int) ptype); - result = Pattern_Prefix_None; /* keep compiler quiet */ - break; - } - return result; -} - -/* - * Estimate the selectivity of a fixed prefix for a pattern match. - * - * A fixed prefix "foo" is estimated as the selectivity of the expression - * "variable >= 'foo' AND variable < 'fop'" (see also indxpath.c). - * - * The selectivity estimate is with respect to the portion of the column - * population represented by the histogram --- the caller must fold this - * together with info about MCVs and NULLs. - * - * We use the >= and < operators from the specified btree opfamily to do the - * estimation. The given variable and Const must be of the associated - * datatype. - * - * XXX Note: we make use of the upper bound to estimate operator selectivity - * even if the locale is such that we cannot rely on the upper-bound string. - * The selectivity only needs to be approximately right anyway, so it seems - * more useful to use the upper-bound code than not. - */ -static Selectivity -prefix_selectivity(PlannerInfo *root, VariableStatData *vardata, - Oid vartype, Oid opfamily, Const *prefixcon) -{ - Selectivity prefixsel; - Oid cmpopr; - FmgrInfo opproc; - Const *greaterstrcon; - Selectivity eq_sel; - - cmpopr = get_opfamily_member(opfamily, vartype, vartype, - BTGreaterEqualStrategyNumber); - if (cmpopr == InvalidOid) - elog(ERROR, "no >= operator for opfamily %u", opfamily); - fmgr_info(get_opcode(cmpopr), &opproc); - - prefixsel = ineq_histogram_selectivity(root, vardata, - &opproc, true, true, - prefixcon->constvalue, - prefixcon->consttype); - - if (prefixsel < 0.0) - { - /* No histogram is present ... return a suitable default estimate */ - return DEFAULT_MATCH_SEL; - } - - /*------- - * If we can create a string larger than the prefix, say - * "x < greaterstr". - *------- - */ - cmpopr = get_opfamily_member(opfamily, vartype, vartype, - BTLessStrategyNumber); - if (cmpopr == InvalidOid) - elog(ERROR, "no < operator for opfamily %u", opfamily); - fmgr_info(get_opcode(cmpopr), &opproc); - greaterstrcon = make_greater_string(prefixcon, &opproc, - DEFAULT_COLLATION_OID); - if (greaterstrcon) - { - Selectivity topsel; - - topsel = ineq_histogram_selectivity(root, vardata, - &opproc, false, false, - greaterstrcon->constvalue, - greaterstrcon->consttype); - - /* ineq_histogram_selectivity worked before, it shouldn't fail now */ - Assert(topsel >= 0.0); - - /* - * Merge the two selectivities in the same way as for a range query - * (see clauselist_selectivity()). Note that we don't need to worry - * about double-exclusion of nulls, since ineq_histogram_selectivity - * doesn't count those anyway. - */ - prefixsel = topsel + prefixsel - 1.0; - } - - /* - * If the prefix is long then the two bounding values might be too close - * together for the histogram to distinguish them usefully, resulting in a - * zero estimate (plus or minus roundoff error). To avoid returning a - * ridiculously small estimate, compute the estimated selectivity for - * "variable = 'foo'", and clamp to that. (Obviously, the resultant - * estimate should be at least that.) - * - * We apply this even if we couldn't make a greater string. That case - * suggests that the prefix is near the maximum possible, and thus - * probably off the end of the histogram, and thus we probably got a very - * small estimate from the >= condition; so we still need to clamp. - */ - cmpopr = get_opfamily_member(opfamily, vartype, vartype, - BTEqualStrategyNumber); - if (cmpopr == InvalidOid) - elog(ERROR, "no = operator for opfamily %u", opfamily); - eq_sel = var_eq_const(vardata, cmpopr, prefixcon->constvalue, - false, true, false); - - prefixsel = Max(prefixsel, eq_sel); - - return prefixsel; -} - - -/* - * Estimate the selectivity of a pattern of the specified type. - * Note that any fixed prefix of the pattern will have been removed already, - * so actually we may be looking at just a fragment of the pattern. - * - * For now, we use a very simplistic approach: fixed characters reduce the - * selectivity a good deal, character ranges reduce it a little, - * wildcards (such as % for LIKE or .* for regex) increase it. - */ - -#define FIXED_CHAR_SEL 0.20 /* about 1/5 */ -#define CHAR_RANGE_SEL 0.25 -#define ANY_CHAR_SEL 0.9 /* not 1, since it won't match end-of-string */ -#define FULL_WILDCARD_SEL 5.0 -#define PARTIAL_WILDCARD_SEL 2.0 - -static Selectivity -like_selectivity(const char *patt, int pattlen, bool case_insensitive) -{ - Selectivity sel = 1.0; - int pos; - - /* Skip any leading wildcard; it's already factored into initial sel */ - for (pos = 0; pos < pattlen; pos++) - { - if (patt[pos] != '%' && patt[pos] != '_') - break; - } - - for (; pos < pattlen; pos++) - { - /* % and _ are wildcard characters in LIKE */ - if (patt[pos] == '%') - sel *= FULL_WILDCARD_SEL; - else if (patt[pos] == '_') - sel *= ANY_CHAR_SEL; - else if (patt[pos] == '\\') - { - /* Backslash quotes the next character */ - pos++; - if (pos >= pattlen) - break; - sel *= FIXED_CHAR_SEL; - } - else - sel *= FIXED_CHAR_SEL; - } - /* Could get sel > 1 if multiple wildcards */ - if (sel > 1.0) - sel = 1.0; - return sel; -} - -static Selectivity -regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive) -{ - Selectivity sel = 1.0; - int paren_depth = 0; - int paren_pos = 0; /* dummy init to keep compiler quiet */ - int pos; - - for (pos = 0; pos < pattlen; pos++) - { - if (patt[pos] == '(') - { - if (paren_depth == 0) - paren_pos = pos; /* remember start of parenthesized item */ - paren_depth++; - } - else if (patt[pos] == ')' && paren_depth > 0) - { - paren_depth--; - if (paren_depth == 0) - sel *= regex_selectivity_sub(patt + (paren_pos + 1), - pos - (paren_pos + 1), - case_insensitive); - } - else if (patt[pos] == '|' && paren_depth == 0) - { - /* - * If unquoted | is present at paren level 0 in pattern, we have - * multiple alternatives; sum their probabilities. - */ - sel += regex_selectivity_sub(patt + (pos + 1), - pattlen - (pos + 1), - case_insensitive); - break; /* rest of pattern is now processed */ - } - else if (patt[pos] == '[') - { - bool negclass = false; - - if (patt[++pos] == '^') - { - negclass = true; - pos++; - } - if (patt[pos] == ']') /* ']' at start of class is not special */ - pos++; - while (pos < pattlen && patt[pos] != ']') - pos++; - if (paren_depth == 0) - sel *= (negclass ? (1.0 - CHAR_RANGE_SEL) : CHAR_RANGE_SEL); - } - else if (patt[pos] == '.') - { - if (paren_depth == 0) - sel *= ANY_CHAR_SEL; - } - else if (patt[pos] == '*' || - patt[pos] == '?' || - patt[pos] == '+') - { - /* Ought to be smarter about quantifiers... */ - if (paren_depth == 0) - sel *= PARTIAL_WILDCARD_SEL; - } - else if (patt[pos] == '{') - { - while (pos < pattlen && patt[pos] != '}') - pos++; - if (paren_depth == 0) - sel *= PARTIAL_WILDCARD_SEL; - } - else if (patt[pos] == '\\') - { - /* backslash quotes the next character */ - pos++; - if (pos >= pattlen) - break; - if (paren_depth == 0) - sel *= FIXED_CHAR_SEL; - } - else - { - if (paren_depth == 0) - sel *= FIXED_CHAR_SEL; - } - } - /* Could get sel > 1 if multiple wildcards */ - if (sel > 1.0) - sel = 1.0; - return sel; -} - -static Selectivity -regex_selectivity(const char *patt, int pattlen, bool case_insensitive, - int fixed_prefix_len) -{ - Selectivity sel; - - /* If patt doesn't end with $, consider it to have a trailing wildcard */ - if (pattlen > 0 && patt[pattlen - 1] == '$' && - (pattlen == 1 || patt[pattlen - 2] != '\\')) - { - /* has trailing $ */ - sel = regex_selectivity_sub(patt, pattlen - 1, case_insensitive); - } - else - { - /* no trailing $ */ - sel = regex_selectivity_sub(patt, pattlen, case_insensitive); - sel *= FULL_WILDCARD_SEL; - } - - /* If there's a fixed prefix, discount its selectivity */ - if (fixed_prefix_len > 0) - sel /= pow(FIXED_CHAR_SEL, fixed_prefix_len); - - /* Make sure result stays in range */ - CLAMP_PROBABILITY(sel); - return sel; -} - - -/* - * For bytea, the increment function need only increment the current byte - * (there are no multibyte characters to worry about). - */ -static bool -byte_increment(unsigned char *ptr, int len) -{ - if (*ptr >= 255) - return false; - (*ptr)++; - return true; -} - -/* - * Try to generate a string greater than the given string or any - * string it is a prefix of. If successful, return a palloc'd string - * in the form of a Const node; else return NULL. - * - * The caller must provide the appropriate "less than" comparison function - * for testing the strings, along with the collation to use. - * - * The key requirement here is that given a prefix string, say "foo", - * we must be able to generate another string "fop" that is greater than - * all strings "foobar" starting with "foo". We can test that we have - * generated a string greater than the prefix string, but in non-C collations - * that is not a bulletproof guarantee that an extension of the string might - * not sort after it; an example is that "foo " is less than "foo!", but it - * is not clear that a "dictionary" sort ordering will consider "foo!" less - * than "foo bar". CAUTION: Therefore, this function should be used only for - * estimation purposes when working in a non-C collation. - * - * To try to catch most cases where an extended string might otherwise sort - * before the result value, we determine which of the strings "Z", "z", "y", - * and "9" is seen as largest by the collation, and append that to the given - * prefix before trying to find a string that compares as larger. - * - * To search for a greater string, we repeatedly "increment" the rightmost - * character, using an encoding-specific character incrementer function. - * When it's no longer possible to increment the last character, we truncate - * off that character and start incrementing the next-to-rightmost. - * For example, if "z" were the last character in the sort order, then we - * could produce "foo" as a string greater than "fonz". - * - * This could be rather slow in the worst case, but in most cases we - * won't have to try more than one or two strings before succeeding. - * - * Note that it's important for the character incrementer not to be too anal - * about producing every possible character code, since in some cases the only - * way to get a larger string is to increment a previous character position. - * So we don't want to spend too much time trying every possible character - * code at the last position. A good rule of thumb is to be sure that we - * don't try more than 256*K values for a K-byte character (and definitely - * not 256^K, which is what an exhaustive search would approach). - */ -Const * -make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation) -{ - Oid datatype = str_const->consttype; - char *workstr; - int len; - Datum cmpstr; - text *cmptxt = NULL; - mbcharacter_incrementer charinc; - - /* - * Get a modifiable copy of the prefix string in C-string format, and set - * up the string we will compare to as a Datum. In C locale this can just - * be the given prefix string, otherwise we need to add a suffix. Types - * NAME and BYTEA sort bytewise so they don't need a suffix either. - */ - if (datatype == NAMEOID) - { - workstr = DatumGetCString(DirectFunctionCall1(nameout, - str_const->constvalue)); - len = strlen(workstr); - cmpstr = str_const->constvalue; - } - else if (datatype == BYTEAOID) - { - bytea *bstr = DatumGetByteaPP(str_const->constvalue); - - len = VARSIZE_ANY_EXHDR(bstr); - workstr = (char *) palloc(len); - memcpy(workstr, VARDATA_ANY(bstr), len); - Assert((Pointer) bstr == DatumGetPointer(str_const->constvalue)); - cmpstr = str_const->constvalue; - } - else - { - workstr = TextDatumGetCString(str_const->constvalue); - len = strlen(workstr); - if (lc_collate_is_c(collation) || len == 0) - cmpstr = str_const->constvalue; - else - { - /* If first time through, determine the suffix to use */ - static char suffixchar = 0; - static Oid suffixcollation = 0; - - if (!suffixchar || suffixcollation != collation) - { - char *best; - - best = "Z"; - if (varstr_cmp(best, 1, "z", 1, collation) < 0) - best = "z"; - if (varstr_cmp(best, 1, "y", 1, collation) < 0) - best = "y"; - if (varstr_cmp(best, 1, "9", 1, collation) < 0) - best = "9"; - suffixchar = *best; - suffixcollation = collation; - } - - /* And build the string to compare to */ - cmptxt = (text *) palloc(VARHDRSZ + len + 1); - SET_VARSIZE(cmptxt, VARHDRSZ + len + 1); - memcpy(VARDATA(cmptxt), workstr, len); - *(VARDATA(cmptxt) + len) = suffixchar; - cmpstr = PointerGetDatum(cmptxt); - } - } - - /* Select appropriate character-incrementer function */ - if (datatype == BYTEAOID) - charinc = byte_increment; - else - charinc = pg_database_encoding_character_incrementer(); + Cost qual_arg_cost = 0; + ListCell *lc; - /* And search ... */ - while (len > 0) + foreach(lc, indexquals) { - int charlen; - unsigned char *lastchar; - - /* Identify the last character --- for bytea, just the last byte */ - if (datatype == BYTEAOID) - charlen = 1; - else - charlen = len - pg_mbcliplen(workstr, len, len - 1); - lastchar = (unsigned char *) (workstr + len - charlen); - - /* - * Try to generate a larger string by incrementing the last character - * (for BYTEA, we treat each byte as a character). - * - * Note: the incrementer function is expected to return true if it's - * generated a valid-per-the-encoding new character, otherwise false. - * The contents of the character on false return are unspecified. - */ - while (charinc(lastchar, charlen)) - { - Const *workstr_const; - - if (datatype == BYTEAOID) - workstr_const = string_to_bytea_const(workstr, len); - else - workstr_const = string_to_const(workstr, datatype); - - if (DatumGetBool(FunctionCall2Coll(ltproc, - collation, - cmpstr, - workstr_const->constvalue))) - { - /* Successfully made a string larger than cmpstr */ - if (cmptxt) - pfree(cmptxt); - pfree(workstr); - return workstr_const; - } - - /* No good, release unusable value and try again */ - pfree(DatumGetPointer(workstr_const->constvalue)); - pfree(workstr_const); - } + Expr *clause = (Expr *) lfirst(lc); + Node *other_operand; + QualCost index_qual_cost; /* - * No luck here, so truncate off the last character and try to - * increment the next one. + * Index quals will have RestrictInfos, indexorderbys won't. Look + * through RestrictInfo if present. */ - len -= charlen; - workstr[len] = '\0'; - } - - /* Failed... */ - if (cmptxt) - pfree(cmptxt); - pfree(workstr); - - return NULL; -} - -/* - * Generate a Datum of the appropriate type from a C string. - * Note that all of the supported types are pass-by-ref, so the - * returned value should be pfree'd if no longer needed. - */ -static Datum -string_to_datum(const char *str, Oid datatype) -{ - Assert(str != NULL); - - /* - * We cheat a little by assuming that CStringGetTextDatum() will do for - * bpchar and varchar constants too... - */ - if (datatype == NAMEOID) - return DirectFunctionCall1(namein, CStringGetDatum(str)); - else if (datatype == BYTEAOID) - return DirectFunctionCall1(byteain, CStringGetDatum(str)); - else - return CStringGetTextDatum(str); -} - -/* - * Generate a Const node of the appropriate type from a C string. - */ -static Const * -string_to_const(const char *str, Oid datatype) -{ - Datum conval = string_to_datum(str, datatype); - Oid collation; - int constlen; - - /* - * We only need to support a few datatypes here, so hard-wire properties - * instead of incurring the expense of catalog lookups. - */ - switch (datatype) - { - case TEXTOID: - case VARCHAROID: - case BPCHAROID: - collation = DEFAULT_COLLATION_OID; - constlen = -1; - break; - - case NAMEOID: - collation = InvalidOid; - constlen = NAMEDATALEN; - break; - - case BYTEAOID: - collation = InvalidOid; - constlen = -1; - break; - - default: - elog(ERROR, "unexpected datatype in string_to_const: %u", - datatype); - return NULL; - } - - return makeConst(datatype, -1, collation, constlen, - conval, false, false); -} - -/* - * Generate a Const node of bytea type from a binary C string and a length. - */ -static Const * -string_to_bytea_const(const char *str, size_t str_len) -{ - bytea *bstr = palloc(VARHDRSZ + str_len); - Datum conval; - - memcpy(VARDATA(bstr), str, str_len); - SET_VARSIZE(bstr, VARHDRSZ + str_len); - conval = PointerGetDatum(bstr); - - return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false); -} - -/*------------------------------------------------------------------------- - * - * Index cost estimation functions - * - *------------------------------------------------------------------------- - */ - -List * -deconstruct_indexquals(IndexPath *path) -{ - List *result = NIL; - IndexOptInfo *index = path->indexinfo; - ListCell *lcc, - *lci; - - forboth(lcc, path->indexquals, lci, path->indexqualcols) - { - RestrictInfo *rinfo = lfirst_node(RestrictInfo, lcc); - int indexcol = lfirst_int(lci); - Expr *clause; - Node *leftop, - *rightop; - IndexQualInfo *qinfo; - - clause = rinfo->clause; - - qinfo = (IndexQualInfo *) palloc(sizeof(IndexQualInfo)); - qinfo->rinfo = rinfo; - qinfo->indexcol = indexcol; + if (IsA(clause, RestrictInfo)) + clause = ((RestrictInfo *) clause)->clause; if (IsA(clause, OpExpr)) { - qinfo->clause_op = ((OpExpr *) clause)->opno; - leftop = get_leftop(clause); - rightop = get_rightop(clause); - if (match_index_to_operand(leftop, indexcol, index)) - { - qinfo->varonleft = true; - qinfo->other_operand = rightop; - } - else - { - Assert(match_index_to_operand(rightop, indexcol, index)); - qinfo->varonleft = false; - qinfo->other_operand = leftop; - } + OpExpr *op = (OpExpr *) clause; + + other_operand = (Node *) lsecond(op->args); } else if (IsA(clause, RowCompareExpr)) { RowCompareExpr *rc = (RowCompareExpr *) clause; - qinfo->clause_op = linitial_oid(rc->opnos); - /* Examine only first columns to determine left/right sides */ - if (match_index_to_operand((Node *) linitial(rc->largs), - indexcol, index)) - { - qinfo->varonleft = true; - qinfo->other_operand = (Node *) rc->rargs; - } - else - { - Assert(match_index_to_operand((Node *) linitial(rc->rargs), - indexcol, index)); - qinfo->varonleft = false; - qinfo->other_operand = (Node *) rc->largs; - } + other_operand = (Node *) rc->rargs; } else if (IsA(clause, ScalarArrayOpExpr)) { ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; - qinfo->clause_op = saop->opno; - /* index column is always on the left in this case */ - Assert(match_index_to_operand((Node *) linitial(saop->args), - indexcol, index)); - qinfo->varonleft = true; - qinfo->other_operand = (Node *) lsecond(saop->args); + other_operand = (Node *) lsecond(saop->args); } else if (IsA(clause, NullTest)) { - qinfo->clause_op = InvalidOid; - Assert(match_index_to_operand((Node *) ((NullTest *) clause)->arg, - indexcol, index)); - qinfo->varonleft = true; - qinfo->other_operand = NULL; + other_operand = NULL; } else { elog(ERROR, "unsupported indexqual type: %d", (int) nodeTag(clause)); - } - - result = lappend(result, qinfo); - } - return result; -} - -/* - * Simple function to compute the total eval cost of the "other operands" - * in an IndexQualInfo list. Since we know these will be evaluated just - * once per scan, there's no need to distinguish startup from per-row cost. - */ -static Cost -other_operands_eval_cost(PlannerInfo *root, List *qinfos) -{ - Cost qual_arg_cost = 0; - ListCell *lc; - - foreach(lc, qinfos) - { - IndexQualInfo *qinfo = (IndexQualInfo *) lfirst(lc); - QualCost index_qual_cost; - - cost_qual_eval_node(&index_qual_cost, qinfo->other_operand, root); - qual_arg_cost += index_qual_cost.startup + index_qual_cost.per_tuple; - } - return qual_arg_cost; -} - -/* - * Get other-operand eval cost for an index orderby list. - * - * Index orderby expressions aren't represented as RestrictInfos (since they - * aren't boolean, usually). So we can't apply deconstruct_indexquals to - * them. However, they are much simpler to deal with since they are always - * OpExprs and the index column is always on the left. - */ -static Cost -orderby_operands_eval_cost(PlannerInfo *root, IndexPath *path) -{ - Cost qual_arg_cost = 0; - ListCell *lc; - - foreach(lc, path->indexorderbys) - { - Expr *clause = (Expr *) lfirst(lc); - Node *other_operand; - QualCost index_qual_cost; - - if (IsA(clause, OpExpr)) - { - other_operand = get_rightop(clause); - } - else - { - elog(ERROR, "unsupported indexorderby type: %d", - (int) nodeTag(clause)); other_operand = NULL; /* keep compiler quiet */ } @@ -6701,11 +5537,10 @@ void genericcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, - List *qinfos, GenericCosts *costs) { IndexOptInfo *index = path->indexinfo; - List *indexQuals = path->indexquals; + List *indexQuals = get_quals_from_indexclauses(path->indexclauses); List *indexOrderBys = path->indexorderbys; Cost indexStartupCost; Cost indexTotalCost; @@ -6727,7 +5562,7 @@ genericcostestimate(PlannerInfo *root, * given indexquals to produce a more accurate idea of the index * selectivity. */ - selectivityQuals = add_predicate_to_quals(index, indexQuals); + selectivityQuals = add_predicate_to_index_quals(index, indexQuals); /* * Check for ScalarArrayOpExpr index quals, and estimate the number of @@ -6870,8 +5705,8 @@ genericcostestimate(PlannerInfo *root, * Detecting that that might be needed seems more expensive than it's * worth, though, considering all the other inaccuracies here ... */ - qual_arg_cost = other_operands_eval_cost(root, qinfos) + - orderby_operands_eval_cost(root, path); + qual_arg_cost = index_other_operands_eval_cost(root, indexQuals) + + index_other_operands_eval_cost(root, indexOrderBys); qual_op_cost = cpu_operator_cost * (list_length(indexQuals) + list_length(indexOrderBys)); @@ -6916,8 +5751,8 @@ genericcostestimate(PlannerInfo *root, * predicate_implied_by() and clauselist_selectivity(), but might be * problematic if the result were passed to other things. */ -static List * -add_predicate_to_quals(IndexOptInfo *index, List *indexQuals) +List * +add_predicate_to_index_quals(IndexOptInfo *index, List *indexQuals) { List *predExtraQuals = NIL; ListCell *lc; @@ -6933,7 +5768,6 @@ add_predicate_to_quals(IndexOptInfo *index, List *indexQuals) if (!predicate_implied_by(oneQual, indexQuals, false)) predExtraQuals = list_concat(predExtraQuals, oneQual); } - /* list_concat avoids modifying the passed-in indexQuals list */ return list_concat(predExtraQuals, indexQuals); } @@ -6945,7 +5779,6 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *qinfos; GenericCosts costs; Oid relid; AttrNumber colnum; @@ -6960,9 +5793,6 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double num_sa_scans; ListCell *lc; - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); - /* * For a btree scan, only leading '=' quals plus inequality quals for the * immediately next attribute contribute to index selectivity (these are @@ -6986,64 +5816,81 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, found_saop = false; found_is_null_op = false; num_sa_scans = 1; - foreach(lc, qinfos) + foreach(lc, path->indexclauses) { - IndexQualInfo *qinfo = (IndexQualInfo *) lfirst(lc); - RestrictInfo *rinfo = qinfo->rinfo; - Expr *clause = rinfo->clause; - Oid clause_op; - int op_strategy; + IndexClause *iclause = lfirst_node(IndexClause, lc); + ListCell *lc2; - if (indexcol != qinfo->indexcol) + if (indexcol != iclause->indexcol) { /* Beginning of a new column's quals */ if (!eqQualHere) break; /* done if no '=' qual for indexcol */ eqQualHere = false; indexcol++; - if (indexcol != qinfo->indexcol) + if (indexcol != iclause->indexcol) break; /* no quals at all for indexcol */ } - if (IsA(clause, ScalarArrayOpExpr)) + /* Examine each indexqual associated with this index clause */ + foreach(lc2, iclause->indexquals) { - int alength = estimate_array_length(qinfo->other_operand); + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2); + Expr *clause = rinfo->clause; + Oid clause_op = InvalidOid; + int op_strategy; - found_saop = true; - /* count up number of SA scans induced by indexBoundQuals only */ - if (alength > 1) - num_sa_scans *= alength; - } - else if (IsA(clause, NullTest)) - { - NullTest *nt = (NullTest *) clause; + if (IsA(clause, OpExpr)) + { + OpExpr *op = (OpExpr *) clause; + + clause_op = op->opno; + } + else if (IsA(clause, RowCompareExpr)) + { + RowCompareExpr *rc = (RowCompareExpr *) clause; - if (nt->nulltesttype == IS_NULL) + clause_op = linitial_oid(rc->opnos); + } + else if (IsA(clause, ScalarArrayOpExpr)) { - found_is_null_op = true; - /* IS NULL is like = for selectivity determination purposes */ - eqQualHere = true; + ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause; + Node *other_operand = (Node *) lsecond(saop->args); + int alength = estimate_array_length(other_operand); + + clause_op = saop->opno; + found_saop = true; + /* count number of SA scans induced by indexBoundQuals only */ + if (alength > 1) + num_sa_scans *= alength; } - } + else if (IsA(clause, NullTest)) + { + NullTest *nt = (NullTest *) clause; - /* - * We would need to commute the clause_op if not varonleft, except - * that we only care if it's equality or not, so that refinement is - * unnecessary. - */ - clause_op = qinfo->clause_op; + if (nt->nulltesttype == IS_NULL) + { + found_is_null_op = true; + /* IS NULL is like = for selectivity purposes */ + eqQualHere = true; + } + } + else + elog(ERROR, "unsupported indexqual type: %d", + (int) nodeTag(clause)); - /* check for equality operator */ - if (OidIsValid(clause_op)) - { - op_strategy = get_op_opfamily_strategy(clause_op, - index->opfamily[indexcol]); - Assert(op_strategy != 0); /* not a member of opfamily?? */ - if (op_strategy == BTEqualStrategyNumber) - eqQualHere = true; - } + /* check for equality operator */ + if (OidIsValid(clause_op)) + { + op_strategy = get_op_opfamily_strategy(clause_op, + index->opfamily[indexcol]); + Assert(op_strategy != 0); /* not a member of opfamily?? */ + if (op_strategy == BTEqualStrategyNumber) + eqQualHere = true; + } - indexBoundQuals = lappend(indexBoundQuals, rinfo); + indexBoundQuals = lappend(indexBoundQuals, rinfo); + } } /* @@ -7068,7 +5915,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, * index-bound quals to produce a more accurate idea of the number of * rows covered by the bound conditions. */ - selectivityQuals = add_predicate_to_quals(index, indexBoundQuals); + selectivityQuals = add_predicate_to_index_quals(index, indexBoundQuals); btreeSelectivity = clauselist_selectivity(root, selectivityQuals, index->rel->relid, @@ -7090,7 +5937,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, MemSet(&costs, 0, sizeof(costs)); costs.numIndexTuples = numIndexTuples; - genericcostestimate(root, path, loop_count, qinfos, &costs); + genericcostestimate(root, path, loop_count, &costs); /* * Add a CPU-cost component to represent the costs of initial btree @@ -7213,7 +6060,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, if (index->reverse_sort[0]) varCorrelation = -varCorrelation; - if (index->ncolumns > 1) + if (index->nkeycolumns > 1) costs.indexCorrelation = varCorrelation * 0.75; else costs.indexCorrelation = varCorrelation; @@ -7237,15 +6084,11 @@ hashcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, Selectivity *indexSelectivity, double *indexCorrelation, double *indexPages) { - List *qinfos; GenericCosts costs; - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); - MemSet(&costs, 0, sizeof(costs)); - genericcostestimate(root, path, loop_count, qinfos, &costs); + genericcostestimate(root, path, loop_count, &costs); /* * A hash index has no descent costs as such, since the index AM can go @@ -7286,16 +6129,12 @@ gistcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *qinfos; GenericCosts costs; Cost descentCost; - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); - MemSet(&costs, 0, sizeof(costs)); - genericcostestimate(root, path, loop_count, qinfos, &costs); + genericcostestimate(root, path, loop_count, &costs); /* * We model index descent costs similarly to those for btree, but to do @@ -7347,16 +6186,12 @@ spgcostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *qinfos; GenericCosts costs; Cost descentCost; - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); - MemSet(&costs, 0, sizeof(costs)); - genericcostestimate(root, path, loop_count, qinfos, &costs); + genericcostestimate(root, path, loop_count, &costs); /* * We model index descent costs similarly to those for btree, but to do @@ -7437,6 +6272,8 @@ gincost_pattern(IndexOptInfo *index, int indexcol, int32 searchMode = GIN_SEARCH_MODE_DEFAULT; int32 i; + Assert(indexcol < index->nkeycolumns); + /* * Get the operator's strategy number and declared input data types within * the index opfamily. (We don't need the latter, but we use @@ -7525,18 +6362,12 @@ gincost_pattern(IndexOptInfo *index, int indexcol, static bool gincost_opexpr(PlannerInfo *root, IndexOptInfo *index, - IndexQualInfo *qinfo, + int indexcol, + OpExpr *clause, GinQualCounts *counts) { - int indexcol = qinfo->indexcol; - Oid clause_op = qinfo->clause_op; - Node *operand = qinfo->other_operand; - - if (!qinfo->varonleft) - { - /* must commute the operator */ - clause_op = get_commutator(clause_op); - } + Oid clause_op = clause->opno; + Node *operand = (Node *) lsecond(clause->args); /* aggressively reduce to a constant, and look through relabeling */ operand = estimate_expression_value(root, operand); @@ -7581,13 +6412,13 @@ gincost_opexpr(PlannerInfo *root, static bool gincost_scalararrayopexpr(PlannerInfo *root, IndexOptInfo *index, - IndexQualInfo *qinfo, + int indexcol, + ScalarArrayOpExpr *clause, double numIndexEntries, GinQualCounts *counts) { - int indexcol = qinfo->indexcol; - Oid clause_op = qinfo->clause_op; - Node *rightop = qinfo->other_operand; + Oid clause_op = clause->opno; + Node *rightop = (Node *) lsecond(clause->args); ArrayType *arrayval; int16 elmlen; bool elmbyval; @@ -7599,7 +6430,7 @@ gincost_scalararrayopexpr(PlannerInfo *root, int numPossible = 0; int i; - Assert(((ScalarArrayOpExpr *) qinfo->rinfo->clause)->useOr); + Assert(clause->useOr); /* aggressively reduce to a constant, and look through relabeling */ rightop = estimate_expression_value(root, rightop); @@ -7700,10 +6531,7 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *indexQuals = path->indexquals; - List *indexOrderBys = path->indexorderbys; - List *qinfos; - ListCell *l; + List *indexQuals = get_quals_from_indexclauses(path->indexclauses); List *selectivityQuals; double numPages = index->pages, numTuples = index->tuples; @@ -7723,9 +6551,7 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, outer_scans; Relation indexRel; GinStatsData ginStats; - - /* Do preliminary analysis of indexquals */ - qinfos = deconstruct_indexquals(path); + ListCell *lc; /* * Obtain statistical information from the meta page, if possible. Else @@ -7733,9 +6559,10 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, */ if (!index->hypothetical) { - indexRel = index_open(index->indexoid, AccessShareLock); + /* Lock should have already been obtained in plancat.c */ + indexRel = index_open(index->indexoid, NoLock); ginGetStats(indexRel, &ginStats); - index_close(indexRel, AccessShareLock); + index_close(indexRel, NoLock); } else { @@ -7803,26 +6630,11 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, numEntries = 1; /* - * Include predicate in selectivityQuals (should match - * genericcostestimate) + * If the index is partial, AND the index predicate with the index-bound + * quals to produce a more accurate idea of the number of rows covered by + * the bound conditions. */ - if (index->indpred != NIL) - { - List *predExtraQuals = NIL; - - foreach(l, index->indpred) - { - Node *predQual = (Node *) lfirst(l); - List *oneQual = list_make1(predQual); - - if (!predicate_implied_by(oneQual, indexQuals, false)) - predExtraQuals = list_concat(predExtraQuals, oneQual); - } - /* list_concat avoids modifying the passed-in indexQuals list */ - selectivityQuals = list_concat(predExtraQuals, indexQuals); - } - else - selectivityQuals = indexQuals; + selectivityQuals = add_predicate_to_index_quals(index, indexQuals); /* Estimate the fraction of main-table tuples that will be visited */ *indexSelectivity = clauselist_selectivity(root, selectivityQuals, @@ -7847,35 +6659,43 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, counts.arrayScans = 1; matchPossible = true; - foreach(l, qinfos) + foreach(lc, path->indexclauses) { - IndexQualInfo *qinfo = (IndexQualInfo *) lfirst(l); - Expr *clause = qinfo->rinfo->clause; + IndexClause *iclause = lfirst_node(IndexClause, lc); + ListCell *lc2; - if (IsA(clause, OpExpr)) + foreach(lc2, iclause->indexquals) { - matchPossible = gincost_opexpr(root, - index, - qinfo, - &counts); - if (!matchPossible) - break; - } - else if (IsA(clause, ScalarArrayOpExpr)) - { - matchPossible = gincost_scalararrayopexpr(root, - index, - qinfo, - numEntries, - &counts); - if (!matchPossible) - break; - } - else - { - /* shouldn't be anything else for a GIN index */ - elog(ERROR, "unsupported GIN indexqual type: %d", - (int) nodeTag(clause)); + RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2); + Expr *clause = rinfo->clause; + + if (IsA(clause, OpExpr)) + { + matchPossible = gincost_opexpr(root, + index, + iclause->indexcol, + (OpExpr *) clause, + &counts); + if (!matchPossible) + break; + } + else if (IsA(clause, ScalarArrayOpExpr)) + { + matchPossible = gincost_scalararrayopexpr(root, + index, + iclause->indexcol, + (ScalarArrayOpExpr *) clause, + numEntries, + &counts); + if (!matchPossible) + break; + } + else + { + /* shouldn't be anything else for a GIN index */ + elog(ERROR, "unsupported GIN indexqual type: %d", + (int) nodeTag(clause)); + } } } @@ -8002,12 +6822,11 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, dataPagesFetched * spc_random_page_cost; /* - * Add on index qual eval costs, much as in genericcostestimate + * Add on index qual eval costs, much as in genericcostestimate. But we + * can disregard indexorderbys, since GIN doesn't support those. */ - qual_arg_cost = other_operands_eval_cost(root, qinfos) + - orderby_operands_eval_cost(root, path); - qual_op_cost = cpu_operator_cost * - (list_length(indexQuals) + list_length(indexOrderBys)); + qual_arg_cost = index_other_operands_eval_cost(root, indexQuals); + qual_op_cost = cpu_operator_cost * list_length(indexQuals); *indexStartupCost += qual_arg_cost; *indexTotalCost += qual_arg_cost; @@ -8025,11 +6844,10 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, double *indexPages) { IndexOptInfo *index = path->indexinfo; - List *indexQuals = path->indexquals; + List *indexQuals = get_quals_from_indexclauses(path->indexclauses); double numPages = index->pages; RelOptInfo *baserel = index->rel; RangeTblEntry *rte = planner_rt_fetch(baserel->relid, root); - List *qinfos; Cost spc_seq_page_cost; Cost spc_random_page_cost; double qual_arg_cost; @@ -8051,11 +6869,12 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, &spc_seq_page_cost); /* - * Obtain some data from the index itself. + * Obtain some data from the index itself. A lock should have already + * been obtained on the index in plancat.c. */ - indexRel = index_open(index->indexoid, AccessShareLock); + indexRel = index_open(index->indexoid, NoLock); brinGetStats(indexRel, &statsData); - index_close(indexRel, AccessShareLock); + index_close(indexRel, NoLock); /* * Compute index correlation @@ -8067,11 +6886,10 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, */ *indexCorrelation = 0; - qinfos = deconstruct_indexquals(path); - foreach(l, qinfos) + foreach(l, path->indexclauses) { - IndexQualInfo *qinfo = (IndexQualInfo *) lfirst(l); - AttrNumber attnum = index->indexkeys[qinfo->indexcol]; + IndexClause *iclause = lfirst_node(IndexClause, l); + AttrNumber attnum = index->indexkeys[iclause->indexcol]; /* attempt to lookup stats in relation for this index column */ if (attnum != 0) @@ -8106,7 +6924,7 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, */ /* get the attnum from the 0-based index. */ - attnum = qinfo->indexcol + 1; + attnum = iclause->indexcol + 1; if (get_index_stats_hook && (*get_index_stats_hook) (root, index->indexoid, attnum, &vardata)) @@ -8185,10 +7003,10 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, /* * Compute the index qual costs, much as in genericcostestimate, to add to - * the index costs. + * the index costs. We can disregard indexorderbys, since BRIN doesn't + * support those. */ - qual_arg_cost = other_operands_eval_cost(root, qinfos) + - orderby_operands_eval_cost(root, path); + qual_arg_cost = index_other_operands_eval_cost(root, indexQuals); /* * Compute the startup cost as the cost to read the whole revmap diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index 41d540b46ec..039ddc86a85 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -3,7 +3,7 @@ * tid.c * Functions for the built-in type tuple id * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,6 +22,7 @@ #include "access/heapam.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "catalog/namespace.h" #include "catalog/pg_type.h" #include "libpq/pqformat.h" @@ -29,9 +30,9 @@ #include "parser/parsetree.h" #include "utils/acl.h" #include "utils/builtins.h" +#include "utils/hashutils.h" #include "utils/rel.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" #include "utils/varlena.h" @@ -239,6 +240,33 @@ tidsmaller(PG_FUNCTION_ARGS) PG_RETURN_ITEMPOINTER(ItemPointerCompare(arg1, arg2) <= 0 ? arg1 : arg2); } +Datum +hashtid(PG_FUNCTION_ARGS) +{ + ItemPointer key = PG_GETARG_ITEMPOINTER(0); + + /* + * While you'll probably have a lot of trouble with a compiler that + * insists on appending pad space to struct ItemPointerData, we can at + * least make this code work, by not using sizeof(ItemPointerData). + * Instead rely on knowing the sizes of the component fields. + */ + return hash_any((unsigned char *) key, + sizeof(BlockIdData) + sizeof(OffsetNumber)); +} + +Datum +hashtidextended(PG_FUNCTION_ARGS) +{ + ItemPointer key = PG_GETARG_ITEMPOINTER(0); + uint64 seed = PG_GETARG_INT64(1); + + /* As above */ + return hash_any_extended((unsigned char *) key, + sizeof(BlockIdData) + sizeof(OffsetNumber), + seed); +} + /* * Functions to get latest tid of a specified tuple. @@ -309,7 +337,7 @@ currtid_for_view(Relation viewrel, ItemPointer tid) rte = rt_fetch(var->varno, query->rtable); if (rte) { - heap_close(viewrel, AccessShareLock); + table_close(viewrel, AccessShareLock); return DirectFunctionCall2(currtid_byreloid, ObjectIdGetDatum(rte->relid), PointerGetDatum(tid)); } } @@ -330,6 +358,7 @@ currtid_byreloid(PG_FUNCTION_ARGS) Relation rel; AclResult aclresult; Snapshot snapshot; + TableScanDesc scan; result = (ItemPointer) palloc(sizeof(ItemPointerData)); if (!reloid) @@ -338,7 +367,7 @@ currtid_byreloid(PG_FUNCTION_ARGS) PG_RETURN_ITEMPOINTER(result); } - rel = heap_open(reloid, AccessShareLock); + rel = table_open(reloid, AccessShareLock); aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_SELECT); @@ -352,10 +381,12 @@ currtid_byreloid(PG_FUNCTION_ARGS) ItemPointerCopy(tid, result); snapshot = RegisterSnapshot(GetLatestSnapshot()); - heap_get_latest_tid(rel, snapshot, result); + scan = table_beginscan(rel, snapshot, 0, NULL); + table_tuple_get_latest_tid(scan, result); + table_endscan(scan); UnregisterSnapshot(snapshot); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); PG_RETURN_ITEMPOINTER(result); } @@ -370,9 +401,10 @@ currtid_byrelname(PG_FUNCTION_ARGS) Relation rel; AclResult aclresult; Snapshot snapshot; + TableScanDesc scan; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = heap_openrv(relrv, AccessShareLock); + rel = table_openrv(relrv, AccessShareLock); aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_SELECT); @@ -387,10 +419,12 @@ currtid_byrelname(PG_FUNCTION_ARGS) ItemPointerCopy(tid, result); snapshot = RegisterSnapshot(GetLatestSnapshot()); - heap_get_latest_tid(rel, snapshot, result); + scan = table_beginscan(rel, snapshot, 0, NULL); + table_tuple_get_latest_tid(scan, result); + table_endscan(scan); UnregisterSnapshot(snapshot); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); PG_RETURN_ITEMPOINTER(result); } diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index 103f91ae624..84bc97d40c3 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -3,7 +3,7 @@ * timestamp.c * Functions for the built-in SQL types "timestamp" and "interval". * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,11 +17,9 @@ #include #include -#include #include #include -#include "access/hash.h" #include "access/xact.h" #include "catalog/pg_type.h" #include "common/int128.h" @@ -30,10 +28,12 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "parser/scansup.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/datetime.h" +#include "utils/float.h" /* * gcc's -ffast-math switch breaks routines that expect exact results from @@ -70,7 +70,6 @@ typedef struct static TimeOffset time2t(const int hour, const int min, const int sec, const fsec_t fsec); static Timestamp dt2local(Timestamp dt, int timezone); -static void AdjustTimestampForTypmod(Timestamp *time, int32 typmod); static void AdjustIntervalForTypmod(Interval *interval, int32 typmod); static TimestampTz timestamp2timestamptz(Timestamp timestamp); static Timestamp timestamptz2timestamp(TimestampTz timestamp); @@ -188,14 +187,6 @@ timestamp_in(PG_FUNCTION_ARGS) TIMESTAMP_NOBEGIN(result); break; - case DTK_INVALID: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"%s\" is no longer supported", str))); - - TIMESTAMP_NOEND(result); - break; - default: elog(ERROR, "unexpected dtype %d while parsing timestamp \"%s\"", dtype, str); @@ -297,15 +288,26 @@ timestamptypmodout(PG_FUNCTION_ARGS) } -/* timestamp_transform() - * Flatten calls to timestamp_scale() and timestamptz_scale() that solely - * represent increases in allowed precision. +/* + * timestamp_support() + * + * Planner support function for the timestamp_scale() and timestamptz_scale() + * length coercion functions (we need not distinguish them here). */ Datum -timestamp_transform(PG_FUNCTION_ARGS) +timestamp_support(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(TemporalTransform(MAX_TIMESTAMP_PRECISION, - (Node *) PG_GETARG_POINTER(0))); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + + ret = TemporalSimplify(MAX_TIMESTAMP_PRECISION, (Node *) req->fcall); + } + + PG_RETURN_POINTER(ret); } /* timestamp_scale() @@ -327,11 +329,11 @@ timestamp_scale(PG_FUNCTION_ARGS) } /* - * AdjustTimestampForTypmod --- round off a timestamp to suit given typmod + * AdjustTimestampForTypmodError --- round off a timestamp to suit given typmod * Works for either timestamp or timestamptz. */ -static void -AdjustTimestampForTypmod(Timestamp *time, int32 typmod) +bool +AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error) { static const int64 TimestampScales[MAX_TIMESTAMP_PRECISION + 1] = { INT64CONST(1000000), @@ -357,10 +359,18 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod) && (typmod != -1) && (typmod != MAX_TIMESTAMP_PRECISION)) { if (typmod < 0 || typmod > MAX_TIMESTAMP_PRECISION) + { + if (error) + { + *error = true; + return false; + } + ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("timestamp(%d) precision must be between %d and %d", typmod, 0, MAX_TIMESTAMP_PRECISION))); + } if (*time >= INT64CONST(0)) { @@ -373,8 +383,15 @@ AdjustTimestampForTypmod(Timestamp *time, int32 typmod) * TimestampScales[typmod]); } } + + return true; } +void +AdjustTimestampForTypmod(Timestamp *time, int32 typmod) +{ + (void) AdjustTimestampForTypmodError(time, typmod, NULL); +} /* timestamptz_in() * Convert a string to internal form. @@ -428,14 +445,6 @@ timestamptz_in(PG_FUNCTION_ARGS) TIMESTAMP_NOBEGIN(result); break; - case DTK_INVALID: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"%s\" is no longer supported", str))); - - TIMESTAMP_NOEND(result); - break; - default: elog(ERROR, "unexpected dtype %d while parsing timestamptz \"%s\"", dtype, str); @@ -481,8 +490,8 @@ parse_sane_timezone(struct pg_tm *tm, text *zone) if (isdigit((unsigned char) *tzname)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid input syntax for numeric time zone: \"%s\"", - tzname), + errmsg("invalid input syntax for type %s: \"%s\"", + "numeric time zone", tzname), errhint("Numeric time zones must have \"-\" or \"+\" as first character."))); rt = DecodeTimezone(tzname, &tz); @@ -935,12 +944,6 @@ interval_in(PG_FUNCTION_ARGS) errmsg("interval out of range"))); break; - case DTK_INVALID: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("date/time value \"%s\" is no longer supported", str))); - break; - default: elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"", dtype, str); @@ -1235,59 +1238,69 @@ intervaltypmodleastfield(int32 typmod) } -/* interval_transform() +/* + * interval_support() + * + * Planner support function for interval_scale(). + * * Flatten superfluous calls to interval_scale(). The interval typmod is * complex to permit accepting and regurgitating all SQL standard variations. * For truncation purposes, it boils down to a single, simple granularity. */ Datum -interval_transform(PG_FUNCTION_ARGS) +interval_support(PG_FUNCTION_ARGS) { - FuncExpr *expr = castNode(FuncExpr, PG_GETARG_POINTER(0)); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); Node *ret = NULL; - Node *typmod; - Assert(list_length(expr->args) >= 2); + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + FuncExpr *expr = req->fcall; + Node *typmod; - typmod = (Node *) lsecond(expr->args); + Assert(list_length(expr->args) >= 2); - if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) - { - Node *source = (Node *) linitial(expr->args); - int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); - bool noop; + typmod = (Node *) lsecond(expr->args); - if (new_typmod < 0) - noop = true; - else + if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) { - int32 old_typmod = exprTypmod(source); - int old_least_field; - int new_least_field; - int old_precis; - int new_precis; - - old_least_field = intervaltypmodleastfield(old_typmod); - new_least_field = intervaltypmodleastfield(new_typmod); - if (old_typmod < 0) - old_precis = INTERVAL_FULL_PRECISION; + Node *source = (Node *) linitial(expr->args); + int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); + bool noop; + + if (new_typmod < 0) + noop = true; else - old_precis = INTERVAL_PRECISION(old_typmod); - new_precis = INTERVAL_PRECISION(new_typmod); - - /* - * Cast is a no-op if least field stays the same or decreases - * while precision stays the same or increases. But precision, - * which is to say, sub-second precision, only affects ranges that - * include SECOND. - */ - noop = (new_least_field <= old_least_field) && - (old_least_field > 0 /* SECOND */ || - new_precis >= MAX_INTERVAL_PRECISION || - new_precis >= old_precis); + { + int32 old_typmod = exprTypmod(source); + int old_least_field; + int new_least_field; + int old_precis; + int new_precis; + + old_least_field = intervaltypmodleastfield(old_typmod); + new_least_field = intervaltypmodleastfield(new_typmod); + if (old_typmod < 0) + old_precis = INTERVAL_FULL_PRECISION; + else + old_precis = INTERVAL_PRECISION(old_typmod); + new_precis = INTERVAL_PRECISION(new_typmod); + + /* + * Cast is a no-op if least field stays the same or decreases + * while precision stays the same or increases. But + * precision, which is to say, sub-second precision, only + * affects ranges that include SECOND. + */ + noop = (new_least_field <= old_least_field) && + (old_least_field > 0 /* SECOND */ || + new_precis >= MAX_INTERVAL_PRECISION || + new_precis >= old_precis); + } + if (noop) + ret = relabel_to_typmod(source, new_typmod); } - if (noop) - ret = relabel_to_typmod(source, new_typmod); } PG_RETURN_POINTER(ret); @@ -1359,7 +1372,7 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod) * can't do it consistently. (We cannot enforce a range limit on the * highest expected field, since we do not have any equivalent of * SQL's .) If we ever decide to - * revisit this, interval_transform will likely require adjusting. + * revisit this, interval_support will likely require adjusting. * * Note: before PG 8.4 we interpreted a limited set of fields as * actually causing a "modulo" operation on a given value, potentially @@ -1609,6 +1622,26 @@ GetSQLLocalTimestamp(int32 typmod) return ts; } +/* + * timeofday(*) -- returns the current time as a text. + */ +Datum +timeofday(PG_FUNCTION_ARGS) +{ + struct timeval tp; + char templ[128]; + char buf[128]; + pg_time_t tt; + + gettimeofday(&tp, NULL); + tt = (pg_time_t) tp.tv_sec; + pg_strftime(templ, sizeof(templ), "%a %b %d %H:%M:%S.%%06d %Y %Z", + pg_localtime(&tt, session_timezone)); + snprintf(buf, sizeof(buf), templ, tp.tv_usec); + + PG_RETURN_TEXT_P(cstring_to_text(buf)); +} + /* * TimestampDifference -- convert the difference between two timestamps * into integer seconds and microseconds @@ -1988,6 +2021,9 @@ GetEpochTime(struct pg_tm *tm) t0 = pg_gmtime(&epoch); + if (t0 == NULL) + elog(ERROR, "could not convert epoch to timestamp: %m"); + tm->tm_year = t0->tm_year; tm->tm_mon = t0->tm_mon; tm->tm_mday = t0->tm_mday; @@ -3280,7 +3316,7 @@ in_range_timestamptz_interval(PG_FUNCTION_ARGS) if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* We don't currently bother to avoid overflow hazards here */ @@ -3311,7 +3347,7 @@ in_range_timestamp_interval(PG_FUNCTION_ARGS) if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* We don't currently bother to avoid overflow hazards here */ @@ -3342,7 +3378,7 @@ in_range_interval_interval(PG_FUNCTION_ARGS) if (int128_compare(interval_cmp_value(offset), int64_to_int128(0)) < 0) ereport(ERROR, - (errcode(ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE), + (errcode(ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE), errmsg("invalid preceding or following size in window function"))); /* We don't currently bother to avoid overflow hazards here */ @@ -3830,12 +3866,14 @@ timestamp_trunc(PG_FUNCTION_ARGS) tm->tm_year = ((tm->tm_year + 999) / 1000) * 1000 - 999; else tm->tm_year = -((999 - (tm->tm_year - 1)) / 1000) * 1000 + 1; + /* FALL THRU */ case DTK_CENTURY: /* see comments in timestamptz_trunc */ if (tm->tm_year > 0) tm->tm_year = ((tm->tm_year + 99) / 100) * 100 - 99; else tm->tm_year = -((99 - (tm->tm_year - 1)) / 100) * 100 + 1; + /* FALL THRU */ case DTK_DECADE: /* see comments in timestamptz_trunc */ if (val != DTK_MILLENNIUM && val != DTK_CENTURY) @@ -3845,18 +3883,25 @@ timestamp_trunc(PG_FUNCTION_ARGS) else tm->tm_year = -((8 - (tm->tm_year - 1)) / 10) * 10; } + /* FALL THRU */ case DTK_YEAR: tm->tm_mon = 1; + /* FALL THRU */ case DTK_QUARTER: tm->tm_mon = (3 * ((tm->tm_mon - 1) / 3)) + 1; + /* FALL THRU */ case DTK_MONTH: tm->tm_mday = 1; + /* FALL THRU */ case DTK_DAY: tm->tm_hour = 0; + /* FALL THRU */ case DTK_HOUR: tm->tm_min = 0; + /* FALL THRU */ case DTK_MINUTE: tm->tm_sec = 0; + /* FALL THRU */ case DTK_SECOND: fsec = 0; break; @@ -3893,14 +3938,15 @@ timestamp_trunc(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMP(result); } -/* timestamptz_trunc() - * Truncate timestamp to specified units. +/* + * Common code for timestamptz_trunc() and timestamptz_trunc_zone(). + * + * tzp identifies the zone to truncate with respect to. We assume + * infinite timestamps have already been rejected. */ -Datum -timestamptz_trunc(PG_FUNCTION_ARGS) +static TimestampTz +timestamptz_trunc_internal(text *units, TimestampTz timestamp, pg_tz *tzp) { - text *units = PG_GETARG_TEXT_PP(0); - TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1); TimestampTz result; int tz; int type, @@ -3911,9 +3957,6 @@ timestamptz_trunc(PG_FUNCTION_ARGS) struct pg_tm tt, *tm = &tt; - if (TIMESTAMP_NOT_FINITE(timestamp)) - PG_RETURN_TIMESTAMPTZ(timestamp); - lowunits = downcase_truncate_identifier(VARDATA_ANY(units), VARSIZE_ANY_EXHDR(units), false); @@ -3922,7 +3965,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS) if (type == UNITS) { - if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, NULL) != 0) + if (timestamp2tm(timestamp, &tz, tm, &fsec, NULL, tzp) != 0) ereport(ERROR, (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), errmsg("timestamp out of range"))); @@ -4023,7 +4066,7 @@ timestamptz_trunc(PG_FUNCTION_ARGS) } if (redotz) - tz = DetermineTimeZoneOffset(tm, session_timezone); + tz = DetermineTimeZoneOffset(tm, tzp); if (tm2timestamp(tm, fsec, &tz, &result) != 0) ereport(ERROR, @@ -4039,6 +4082,83 @@ timestamptz_trunc(PG_FUNCTION_ARGS) result = 0; } + return result; +} + +/* timestamptz_trunc() + * Truncate timestamptz to specified units in session timezone. + */ +Datum +timestamptz_trunc(PG_FUNCTION_ARGS) +{ + text *units = PG_GETARG_TEXT_PP(0); + TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1); + TimestampTz result; + + if (TIMESTAMP_NOT_FINITE(timestamp)) + PG_RETURN_TIMESTAMPTZ(timestamp); + + result = timestamptz_trunc_internal(units, timestamp, session_timezone); + + PG_RETURN_TIMESTAMPTZ(result); +} + +/* timestamptz_trunc_zone() + * Truncate timestamptz to specified units in specified timezone. + */ +Datum +timestamptz_trunc_zone(PG_FUNCTION_ARGS) +{ + text *units = PG_GETARG_TEXT_PP(0); + TimestampTz timestamp = PG_GETARG_TIMESTAMPTZ(1); + text *zone = PG_GETARG_TEXT_PP(2); + TimestampTz result; + char tzname[TZ_STRLEN_MAX + 1]; + char *lowzone; + int type, + val; + pg_tz *tzp; + + /* + * timestamptz_zone() doesn't look up the zone for infinite inputs, so we + * don't do so here either. + */ + if (TIMESTAMP_NOT_FINITE(timestamp)) + PG_RETURN_TIMESTAMP(timestamp); + + /* + * Look up the requested timezone (see notes in timestamptz_zone()). + */ + text_to_cstring_buffer(zone, tzname, sizeof(tzname)); + + /* DecodeTimezoneAbbrev requires lowercase input */ + lowzone = downcase_truncate_identifier(tzname, + strlen(tzname), + false); + + type = DecodeTimezoneAbbrev(0, lowzone, &val, &tzp); + + if (type == TZ || type == DTZ) + { + /* fixed-offset abbreviation, get a pg_tz descriptor for that */ + tzp = pg_tzset_offset(-val); + } + else if (type == DYNTZ) + { + /* dynamic-offset abbreviation, use its referenced timezone */ + } + else + { + /* try it as a full zone name */ + tzp = pg_tzset(tzname); + if (!tzp) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("time zone \"%s\" not recognized", tzname))); + } + + result = timestamptz_trunc_internal(units, timestamp, tzp); + PG_RETURN_TIMESTAMPTZ(result); } @@ -4072,28 +4192,36 @@ interval_trunc(PG_FUNCTION_ARGS) { switch (val) { - /* fall through */ case DTK_MILLENNIUM: /* caution: C division may have negative remainder */ tm->tm_year = (tm->tm_year / 1000) * 1000; + /* FALL THRU */ case DTK_CENTURY: /* caution: C division may have negative remainder */ tm->tm_year = (tm->tm_year / 100) * 100; + /* FALL THRU */ case DTK_DECADE: /* caution: C division may have negative remainder */ tm->tm_year = (tm->tm_year / 10) * 10; + /* FALL THRU */ case DTK_YEAR: tm->tm_mon = 0; + /* FALL THRU */ case DTK_QUARTER: tm->tm_mon = 3 * (tm->tm_mon / 3); + /* FALL THRU */ case DTK_MONTH: tm->tm_mday = 0; + /* FALL THRU */ case DTK_DAY: tm->tm_hour = 0; + /* FALL THRU */ case DTK_HOUR: tm->tm_min = 0; + /* FALL THRU */ case DTK_MINUTE: tm->tm_sec = 0; + /* FALL THRU */ case DTK_SECOND: fsec = 0; break; @@ -4905,18 +5033,6 @@ interval_part(PG_FUNCTION_ARGS) } -/* timestamp_zone_transform() - * The original optimization here caused problems by relabeling Vars that - * could be matched to index entries. It might be possible to resurrect it - * at some point by teaching the planner to be less cavalier with RelabelType - * nodes, but that will take careful analysis. - */ -Datum -timestamp_zone_transform(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(NULL); -} - /* timestamp_zone() * Encode timestamp type with specified time zone. * This function is just timestamp2timestamptz() except instead of @@ -5010,18 +5126,6 @@ timestamp_zone(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMPTZ(result); } -/* timestamp_izone_transform() - * The original optimization here caused problems by relabeling Vars that - * could be matched to index entries. It might be possible to resurrect it - * at some point by teaching the planner to be less cavalier with RelabelType - * nodes, but that will take careful analysis. - */ -Datum -timestamp_izone_transform(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(NULL); -} - /* timestamp_izone() * Encode timestamp type with specified time interval as time zone. */ @@ -5055,6 +5159,23 @@ timestamp_izone(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMPTZ(result); } /* timestamp_izone() */ +/* TimestampTimestampTzRequiresRewrite() + * + * Returns false if the TimeZone GUC setting causes timestamp_timestamptz and + * timestamptz_timestamp to be no-ops, where the return value has the same + * bits as the argument. Since project convention is to assume a GUC changes + * no more often than STABLE functions change, the answer is valid that long. + */ +bool +TimestampTimestampTzRequiresRewrite(void) +{ + long offset; + + if (pg_get_timezone_offset(session_timezone, &offset) && offset == 0) + return false; + return true; +} + /* timestamp_timestamptz() * Convert local timestamp to timestamp at GMT */ @@ -5066,8 +5187,15 @@ timestamp_timestamptz(PG_FUNCTION_ARGS) PG_RETURN_TIMESTAMPTZ(timestamp2timestamptz(timestamp)); } -static TimestampTz -timestamp2timestamptz(Timestamp timestamp) +/* + * Convert timestamp to timestamp with time zone. + * + * If 'have_error' is NULL, then errors are thrown, else '*have_error' is set + * and zero is returned. + */ + +TimestampTz +timestamp2timestamptz_opt_error(Timestamp timestamp, bool *have_error) { TimestampTz result; struct pg_tm tt, @@ -5076,23 +5204,33 @@ timestamp2timestamptz(Timestamp timestamp) int tz; if (TIMESTAMP_NOT_FINITE(timestamp)) - result = timestamp; - else - { - if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); + return timestamp; + if (!timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL)) + { tz = DetermineTimeZoneOffset(tm, session_timezone); - if (tm2timestamp(tm, fsec, &tz, &result) != 0) - ereport(ERROR, - (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), - errmsg("timestamp out of range"))); + if (!tm2timestamp(tm, fsec, &tz, &result)) + return result; } - return result; + if (have_error) + *have_error = true; + else + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("timestamp out of range"))); + + return 0; +} + +/* + * Single-argument version of timestamp2timestamptz_opt_error(). + */ +static TimestampTz +timestamp2timestamptz(Timestamp timestamp) +{ + return timestamp2timestamptz_opt_error(timestamp, NULL); } /* timestamptz_timestamp() diff --git a/src/backend/utils/adt/trigfuncs.c b/src/backend/utils/adt/trigfuncs.c index 04605021d79..9a5586aff77 100644 --- a/src/backend/utils/adt/trigfuncs.c +++ b/src/backend/utils/adt/trigfuncs.c @@ -4,7 +4,7 @@ * Builtin functions for useful trigger support. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/utils/adt/trigfuncs.c @@ -66,17 +66,6 @@ suppress_redundant_updates_trigger(PG_FUNCTION_ARGS) newheader = newtuple->t_data; oldheader = oldtuple->t_data; - /* - * We are called before the OID, if any, has been transcribed from the old - * tuple to the new (in heap_update). To avoid a bogus compare failure, - * copy the OID now. But check that someone didn't already put another - * OID value into newtuple. (That's not actually possible at present, but - * maybe someday.) - */ - if (trigdata->tg_relation->rd_rel->relhasoids && - !OidIsValid(HeapTupleHeaderGetOid(newheader))) - HeapTupleHeaderSetOid(newheader, HeapTupleHeaderGetOid(oldheader)); - /* if the tuple payload is the same ... */ if (newtuple->t_len == oldtuple->t_len && newheader->t_hoff == oldheader->t_hoff && diff --git a/src/backend/utils/adt/tsginidx.c b/src/backend/utils/adt/tsginidx.c index 00e32b2570e..6ac47571c66 100644 --- a/src/backend/utils/adt/tsginidx.c +++ b/src/backend/utils/adt/tsginidx.c @@ -3,7 +3,7 @@ * tsginidx.c * GIN support functions for tsvector_ops * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c index 2d9ecc4bfdc..6ff71a49b8f 100644 --- a/src/backend/utils/adt/tsgistidx.c +++ b/src/backend/utils/adt/tsgistidx.c @@ -3,7 +3,7 @@ * tsgistidx.c * GiST support functions for tsvector_ops * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -15,7 +15,8 @@ #include "postgres.h" #include "access/gist.h" -#include "access/tuptoaster.h" +#include "access/heaptoast.h" +#include "port/pg_bitutils.h" #include "tsearch/ts_utils.h" #include "utils/builtins.h" #include "utils/pg_crc.h" @@ -70,26 +71,6 @@ typedef struct #define GETARR(x) ( (int32*)( (char*)(x)+GTHDRSIZE ) ) #define ARRNELEM(x) ( ( VARSIZE(x) - GTHDRSIZE )/sizeof(int32) ) -/* Number of one-bits in an unsigned byte */ -static const uint8 number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - static int32 sizebitvec(BITVECP sign); Datum @@ -503,12 +484,7 @@ gtsvector_same(PG_FUNCTION_ARGS) static int32 sizebitvec(BITVECP sign) { - int32 size = 0, - i; - - LOOPBYTE - size += number_of_ones[(unsigned char) sign[i]]; - return size; + return pg_popcount(sign, SIGLEN); } static int @@ -521,7 +497,8 @@ hemdistsign(BITVECP a, BITVECP b) LOOPBYTE { diff = (unsigned char) (a[i] ^ b[i]); - dist += number_of_ones[diff]; + /* Using the popcount functions here isn't likely to win */ + dist += pg_number_of_ones[diff]; } return dist; } diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c index 793c0e5dd1c..ab2b49fdc46 100644 --- a/src/backend/utils/adt/tsquery.c +++ b/src/backend/utils/adt/tsquery.c @@ -3,7 +3,7 @@ * tsquery.c * I/O functions for tsquery * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -63,9 +63,9 @@ typedef enum * *strval, *lenval and *weight are filled in when return value is PT_VAL * */ -typedef ts_tokentype (*ts_tokenizer)(TSQueryParserState state, int8 *operator, - int *lenval, char **strval, - int16 *weight, bool *prefix); +typedef ts_tokentype (*ts_tokenizer) (TSQueryParserState state, int8 *operator, + int *lenval, char **strval, + int16 *weight, bool *prefix); struct TSQueryParserStateData { @@ -233,7 +233,7 @@ parse_phrase_operator(TSQueryParserState pstate, int16 *distance) static bool parse_or_operator(TSQueryParserState pstate) { - char *ptr = pstate->buf; + char *ptr = pstate->buf; if (pstate->in_quotes) return false; @@ -245,26 +245,26 @@ parse_or_operator(TSQueryParserState pstate) ptr += 2; /* - * it shouldn't be a part of any word but somewhere later it should be some - * operand + * it shouldn't be a part of any word but somewhere later it should be + * some operand */ - if (*ptr == '\0') /* no operand */ + if (*ptr == '\0') /* no operand */ return false; /* it shouldn't be a part of any word */ - if (t_iseq(ptr, '-') || t_iseq(ptr, '_') || t_isalpha(ptr) || t_isdigit(ptr)) + if (t_iseq(ptr, '-') || t_iseq(ptr, '_') || t_isalpha(ptr) || t_isdigit(ptr)) return false; - for(;;) + for (;;) { ptr += pg_mblen(ptr); - if (*ptr == '\0') /* got end of string without operand */ + if (*ptr == '\0') /* got end of string without operand */ return false; /* - * Suppose, we found an operand, but could be a not correct operand. So - * we still treat OR literal as operation with possibly incorrect + * Suppose, we found an operand, but could be a not correct operand. + * So we still treat OR literal as operation with possibly incorrect * operand and will not search it as lexeme */ if (!t_isspace(ptr)) @@ -312,7 +312,10 @@ gettoken_query_standard(TSQueryParserState state, int8 *operator, } else if (!t_isspace(state->buf)) { - /* We rely on the tsvector parser to parse the value for us */ + /* + * We rely on the tsvector parser to parse the value for + * us + */ reset_tsvector_parser(state->valstate, state->buf); if (gettoken_tsvector(state->valstate, strval, lenval, NULL, NULL, &state->buf)) @@ -437,7 +440,10 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, } else if (!t_isspace(state->buf)) { - /* We rely on the tsvector parser to parse the value for us */ + /* + * We rely on the tsvector parser to parse the value for + * us + */ reset_tsvector_parser(state->valstate, state->buf); if (gettoken_tsvector(state->valstate, strval, lenval, NULL, NULL, &state->buf)) @@ -464,8 +470,8 @@ gettoken_query_websearch(TSQueryParserState state, int8 *operator, if (!state->in_quotes) { /* - * put implicit AND after an operand - * and handle this quote in WAITOPERAND + * put implicit AND after an operand and handle this + * quote in WAITOPERAND */ state->state = WAITOPERAND; *operator = OP_AND; diff --git a/src/backend/utils/adt/tsquery_cleanup.c b/src/backend/utils/adt/tsquery_cleanup.c index c146376e663..af075637e1d 100644 --- a/src/backend/utils/adt/tsquery_cleanup.c +++ b/src/backend/utils/adt/tsquery_cleanup.c @@ -4,7 +4,7 @@ * Cleanup query from NOT values and/or stopword * Utility functions to correct work. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_gist.c b/src/backend/utils/adt/tsquery_gist.c index bf8109b32fb..91200eecf6e 100644 --- a/src/backend/utils/adt/tsquery_gist.c +++ b/src/backend/utils/adt/tsquery_gist.c @@ -3,7 +3,7 @@ * tsquery_gist.c * GiST index support for tsquery * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_op.c b/src/backend/utils/adt/tsquery_op.c index 07bc609972d..1f63d9b6a96 100644 --- a/src/backend/utils/adt/tsquery_op.c +++ b/src/backend/utils/adt/tsquery_op.c @@ -3,7 +3,7 @@ * tsquery_op.c * Various operations with tsquery * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -296,8 +296,8 @@ collectTSQueryValues(TSQuery a, int *nvalues_p) static int cmp_string(const void *a, const void *b) { - const char *sa = *((const char **) a); - const char *sb = *((const char **) b); + const char *sa = *((char *const *) a); + const char *sb = *((char *const *) b); return strcmp(sa, sb); } diff --git a/src/backend/utils/adt/tsquery_rewrite.c b/src/backend/utils/adt/tsquery_rewrite.c index e3420e8d270..52be30548c1 100644 --- a/src/backend/utils/adt/tsquery_rewrite.c +++ b/src/backend/utils/adt/tsquery_rewrite.c @@ -3,7 +3,7 @@ * tsquery_rewrite.c * Utilities for reconstructing tsquery * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsquery_util.c b/src/backend/utils/adt/tsquery_util.c index cd310b87d59..de46a00ba83 100644 --- a/src/backend/utils/adt/tsquery_util.c +++ b/src/backend/utils/adt/tsquery_util.c @@ -3,7 +3,7 @@ * tsquery_util.c * Utilities for tsquery datatype * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsrank.c b/src/backend/utils/adt/tsrank.c index a0011a5f569..e28859d8e1c 100644 --- a/src/backend/utils/adt/tsrank.c +++ b/src/backend/utils/adt/tsrank.c @@ -3,7 +3,7 @@ * tsrank.c * rank tsvector by tsquery * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -738,7 +738,7 @@ get_docrep(TSVector txt, QueryRepresentation *qr, int *doclen) doc = (DocRepresentation *) palloc(sizeof(DocRepresentation) * len); /* - * Iterate through query to make DocRepresentaion for words and it's + * Iterate through query to make DocRepresentation for words and it's * entries satisfied by query */ for (i = 0; i < qr->query->size; i++) diff --git a/src/backend/utils/adt/tsvector.c b/src/backend/utils/adt/tsvector.c index 7a27bd12a31..ccfc4147fab 100644 --- a/src/backend/utils/adt/tsvector.c +++ b/src/backend/utils/adt/tsvector.c @@ -3,7 +3,7 @@ * tsvector.c * I/O functions for tsvector * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c index 258fe47a245..28d042273e3 100644 --- a/src/backend/utils/adt/tsvector_op.c +++ b/src/backend/utils/adt/tsvector_op.c @@ -3,7 +3,7 @@ * tsvector_op.c * operations over tsvector * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -25,6 +25,7 @@ #include "miscadmin.h" #include "parser/parse_coerce.h" #include "tsearch/ts_utils.h" +#include "utils/array.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/regproc.h" @@ -65,8 +66,6 @@ typedef struct StatEntry *root; } TSVectorStat; -#define STATHDRSIZE (offsetof(TSVectorStat, data)) - static Datum tsvector_update_trigger(PG_FUNCTION_ARGS, bool config_column); static int tsvector_bsearch(const TSVector tsv, char *lexeme, int lexeme_len); @@ -646,7 +645,7 @@ tsvector_unnest(PG_FUNCTION_ARGS) funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "lexeme", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "positions", @@ -1154,7 +1153,7 @@ tsvector_concat(PG_FUNCTION_ARGS) /* * Compare two strings by tsvector rules. * - * if isPrefix = true then it returns zero value iff b has prefix a + * if prefix = true then it returns zero value iff b has prefix a */ int32 tsCompareString(char *a, int lena, char *b, int lenb, bool prefix) @@ -2187,7 +2186,7 @@ ts_setup_firstcall(FunctionCallInfo fcinfo, FuncCallContext *funcctx, } Assert(stat->stackpos <= stat->maxdepth); - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ndoc", diff --git a/src/backend/utils/adt/tsvector_parser.c b/src/backend/utils/adt/tsvector_parser.c index fed411a842e..af041b81799 100644 --- a/src/backend/utils/adt/tsvector_parser.c +++ b/src/backend/utils/adt/tsvector_parser.c @@ -3,7 +3,7 @@ * tsvector_parser.c * Parser for tsvector * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c index 7974c0bd3d8..90b2c9b6948 100644 --- a/src/backend/utils/adt/txid.c +++ b/src/backend/utils/adt/txid.c @@ -10,7 +10,7 @@ * via functions such as SubTransGetTopmostTransaction(). * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * Author: Jan Wieck, Afilias USA INC. * 64-bit txids: Marko Kreen, Skype Technologies * @@ -91,7 +91,10 @@ typedef struct static void load_xid_epoch(TxidEpoch *state) { - GetNextXidAndEpoch(&state->last_xid, &state->epoch); + FullTransactionId fullXid = ReadNextFullTransactionId(); + + state->last_xid = XidFromFullTransactionId(fullXid); + state->epoch = EpochFromFullTransactionId(fullXid); } /* @@ -113,9 +116,12 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid) uint32 xid_epoch = (uint32) (xid_with_epoch >> 32); TransactionId xid = (TransactionId) xid_with_epoch; uint32 now_epoch; - TransactionId now_epoch_last_xid; + TransactionId now_epoch_next_xid; + FullTransactionId now_fullxid; - GetNextXidAndEpoch(&now_epoch_last_xid, &now_epoch); + now_fullxid = ReadNextFullTransactionId(); + now_epoch_next_xid = XidFromFullTransactionId(now_fullxid); + now_epoch = EpochFromFullTransactionId(now_fullxid); if (extracted_xid != NULL) *extracted_xid = xid; @@ -128,8 +134,7 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid) return true; /* If the transaction ID is in the future, throw an error. */ - if (xid_epoch > now_epoch - || (xid_epoch == now_epoch && xid > now_epoch_last_xid)) + if (xid_with_epoch >= U64FromFullTransactionId(now_fullxid)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("transaction ID %s is in the future", @@ -151,7 +156,7 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid) * CLOG entry is guaranteed to still exist. */ if (xid_epoch + 1 < now_epoch - || (xid_epoch + 1 == now_epoch && xid < now_epoch_last_xid) + || (xid_epoch + 1 == now_epoch && xid < now_epoch_next_xid) || TransactionIdPrecedes(xid, ShmemVariableCache->oldestClogXid)) return false; @@ -700,7 +705,7 @@ txid_snapshot_xip(PG_FUNCTION_ARGS) TxidSnapshot *snap; txid value; - /* on first call initialize snap_state and get copy of snapshot */ + /* on first call initialize fctx and get copy of snapshot */ if (SRF_IS_FIRSTCALL()) { TxidSnapshot *arg = (TxidSnapshot *) PG_GETARG_VARLENA_P(0); diff --git a/src/backend/utils/adt/uuid.c b/src/backend/utils/adt/uuid.c index 43674dbfab2..589c2d51dde 100644 --- a/src/backend/utils/adt/uuid.c +++ b/src/backend/utils/adt/uuid.c @@ -3,7 +3,7 @@ * uuid.c * Functions for the built-in type "uuid". * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/adt/uuid.c @@ -13,12 +13,12 @@ #include "postgres.h" -#include "access/hash.h" #include "lib/hyperloglog.h" #include "libpq/pqformat.h" #include "port/pg_bswap.h" #include "utils/builtins.h" #include "utils/guc.h" +#include "utils/hashutils.h" #include "utils/sortsupport.h" #include "utils/uuid.h" @@ -416,3 +416,23 @@ uuid_hash_extended(PG_FUNCTION_ARGS) return hash_any_extended(key->data, UUID_LEN, PG_GETARG_INT64(1)); } + +Datum +gen_random_uuid(PG_FUNCTION_ARGS) +{ + pg_uuid_t *uuid = palloc(UUID_LEN); + + if (!pg_strong_random(uuid, UUID_LEN)) + ereport(ERROR, + (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("could not generate random values"))); + + /* + * Set magic numbers for a "version 4" (pseudorandom) UUID, see + * http://tools.ietf.org/html/rfc4122#section-4.4 + */ + uuid->data[6] = (uuid->data[6] & 0x0f) | 0x40; /* time_hi_and_version */ + uuid->data[8] = (uuid->data[8] & 0x3f) | 0x80; /* clock_seq_hi_and_reserved */ + + PG_RETURN_UUID_P(uuid); +} diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index 6ba400b699c..c36d8ded40a 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -3,9 +3,24 @@ * varbit.c * Functions for the SQL datatypes BIT() and BIT VARYING(). * + * The data structure contains the following elements: + * header -- length of the whole data structure (incl header) + * in bytes (as with all varying length datatypes) + * data section -- private data section for the bits data structures + * bitlength -- length of the bit string in bits + * bitdata -- bit string, most significant byte first + * + * The length of the bitdata vector should always be exactly as many + * bytes as are needed for the given bitlength. If the bitlength is + * not a multiple of 8, the extra low-order padding bits of the last + * byte must be zeroes. + * + * attypmod is defined as the length of the bit string in bits, or for + * varying bits the maximum length. + * * Code originally contributed by Adriaan Joubert. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,15 +35,50 @@ #include "common/int.h" #include "libpq/pqformat.h" #include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "utils/array.h" #include "utils/builtins.h" #include "utils/varbit.h" #define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A')) +/* Mask off any bits that should be zero in the last byte of a bitstring */ +#define VARBIT_PAD(vb) \ + do { \ + int32 pad_ = VARBITPAD(vb); \ + Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \ + if (pad_ > 0) \ + *(VARBITS(vb) + VARBITBYTES(vb) - 1) &= BITMASK << pad_; \ + } while (0) + +/* + * Many functions work byte-by-byte, so they have a pointer handy to the + * last-plus-one byte, which saves a cycle or two. + */ +#define VARBIT_PAD_LAST(vb, ptr) \ + do { \ + int32 pad_ = VARBITPAD(vb); \ + Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \ + if (pad_ > 0) \ + *((ptr) - 1) &= BITMASK << pad_; \ + } while (0) + +/* Assert proper padding of a bitstring */ +#ifdef USE_ASSERT_CHECKING +#define VARBIT_CORRECTLY_PADDED(vb) \ + do { \ + int32 pad_ = VARBITPAD(vb); \ + Assert(pad_ >= 0 && pad_ < BITS_PER_BYTE); \ + Assert(pad_ == 0 || \ + (*(VARBITS(vb) + VARBITBYTES(vb) - 1) & ~(BITMASK << pad_)) == 0); \ + } while (0) +#else +#define VARBIT_CORRECTLY_PADDED(vb) ((void) 0) +#endif + static VarBit *bit_catenate(VarBit *arg1, VarBit *arg2); static VarBit *bitsubstring(VarBit *arg, int32 s, int32 l, - bool length_not_specified); + bool length_not_specified); static VarBit *bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl); @@ -86,24 +136,6 @@ anybit_typmodout(int32 typmod) } -/*---------- - * attypmod -- contains the length of the bit string in bits, or for - * varying bits the maximum length. - * - * The data structure contains the following elements: - * header -- length of the whole data structure (incl header) - * in bytes. (as with all varying length datatypes) - * data section -- private data section for the bits data structures - * bitlength -- length of the bit string in bits - * bitdata -- bit string, most significant byte first - * - * The length of the bitdata vector should always be exactly as many - * bytes as are needed for the given bitlength. If the bitlength is - * not a multiple of 8, the extra low-order padding bits of the last - * byte must be zeroes. - *---------- - */ - /* * bit_in - * converts a char string to the internal representation of a bitstring. @@ -263,6 +295,9 @@ bit_out(PG_FUNCTION_ARGS) len, bitlen; + /* Assertion to help catch any bit functions that don't pad correctly */ + VARBIT_CORRECTLY_PADDED(s); + bitlen = VARBITLEN(s); len = (bitlen + 3) / 4; result = (char *) palloc(len + 2); @@ -303,8 +338,6 @@ bit_recv(PG_FUNCTION_ARGS) VarBit *result; int len, bitlen; - int ipad; - bits8 mask; bitlen = pq_getmsgint(buf, sizeof(int32)); if (bitlen < 0 || bitlen > VARBITMAXLEN) @@ -329,13 +362,8 @@ bit_recv(PG_FUNCTION_ARGS) pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result)); - /* Make sure last byte is zero-padded if needed */ - ipad = VARBITPAD(result); - if (ipad > 0) - { - mask = BITMASK << ipad; - *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask; - } + /* Make sure last byte is correctly zero-padded */ + VARBIT_PAD(result); PG_RETURN_VARBIT_P(result); } @@ -366,8 +394,6 @@ bit(PG_FUNCTION_ARGS) bool isExplicit = PG_GETARG_BOOL(2); VarBit *result; int rlen; - int ipad; - bits8 mask; /* No work if typmod is invalid or supplied data matches it already */ if (len <= 0 || len > VARBITMAXLEN || len == VARBITLEN(arg)) @@ -393,12 +419,7 @@ bit(PG_FUNCTION_ARGS) * if source data was shorter than target length (we assume the last byte * of the source data was itself correctly zero-padded). */ - ipad = VARBITPAD(result); - if (ipad > 0) - { - mask = BITMASK << ipad; - *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask; - } + VARBIT_PAD(result); PG_RETURN_VARBIT_P(result); } @@ -573,6 +594,9 @@ varbit_out(PG_FUNCTION_ARGS) k, len; + /* Assertion to help catch any bit functions that don't pad correctly */ + VARBIT_CORRECTLY_PADDED(s); + len = VARBITLEN(s); result = (char *) palloc(len + 1); sp = VARBITS(s); @@ -619,8 +643,6 @@ varbit_recv(PG_FUNCTION_ARGS) VarBit *result; int len, bitlen; - int ipad; - bits8 mask; bitlen = pq_getmsgint(buf, sizeof(int32)); if (bitlen < 0 || bitlen > VARBITMAXLEN) @@ -645,13 +667,8 @@ varbit_recv(PG_FUNCTION_ARGS) pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result)); - /* Make sure last byte is zero-padded if needed */ - ipad = VARBITPAD(result); - if (ipad > 0) - { - mask = BITMASK << ipad; - *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask; - } + /* Make sure last byte is correctly zero-padded */ + VARBIT_PAD(result); PG_RETURN_VARBIT_P(result); } @@ -672,32 +689,41 @@ varbit_send(PG_FUNCTION_ARGS) } /* - * varbit_transform() - * Flatten calls to varbit's length coercion function that set the new maximum - * length >= the previous maximum length. We can ignore the isExplicit - * argument, since that only affects truncation cases. + * varbit_support() + * + * Planner support function for the varbit() length coercion function. + * + * Currently, the only interesting thing we can do is flatten calls that set + * the new maximum length >= the previous maximum length. We can ignore the + * isExplicit argument, since that only affects truncation cases. */ Datum -varbit_transform(PG_FUNCTION_ARGS) +varbit_support(PG_FUNCTION_ARGS) { - FuncExpr *expr = castNode(FuncExpr, PG_GETARG_POINTER(0)); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); Node *ret = NULL; - Node *typmod; - Assert(list_length(expr->args) >= 2); + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + FuncExpr *expr = req->fcall; + Node *typmod; - typmod = (Node *) lsecond(expr->args); + Assert(list_length(expr->args) >= 2); - if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) - { - Node *source = (Node *) linitial(expr->args); - int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); - int32 old_max = exprTypmod(source); - int32 new_max = new_typmod; - - /* Note: varbit() treats typmod 0 as invalid, so we do too */ - if (new_max <= 0 || (old_max > 0 && old_max <= new_max)) - ret = relabel_to_typmod(source, new_typmod); + typmod = (Node *) lsecond(expr->args); + + if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) + { + Node *source = (Node *) linitial(expr->args); + int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); + int32 old_max = exprTypmod(source); + int32 new_max = new_typmod; + + /* Note: varbit() treats typmod 0 as invalid, so we do too */ + if (new_max <= 0 || (old_max > 0 && old_max <= new_max)) + ret = relabel_to_typmod(source, new_typmod); + } } PG_RETURN_POINTER(ret); @@ -719,8 +745,6 @@ varbit(PG_FUNCTION_ARGS) bool isExplicit = PG_GETARG_BOOL(2); VarBit *result; int rlen; - int ipad; - bits8 mask; /* No work if typmod is invalid or supplied data matches it already */ if (len <= 0 || len >= VARBITLEN(arg)) @@ -739,13 +763,8 @@ varbit(PG_FUNCTION_ARGS) memcpy(VARBITS(result), VARBITS(arg), VARBITBYTES(result)); - /* Make sure last byte is zero-padded if needed */ - ipad = VARBITPAD(result); - if (ipad > 0) - { - mask = BITMASK << ipad; - *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask; - } + /* Make sure last byte is correctly zero-padded */ + VARBIT_PAD(result); PG_RETURN_VARBIT_P(result); } @@ -1003,6 +1022,8 @@ bit_catenate(VarBit *arg1, VarBit *arg2) } } + /* The pad bits should be already zero at this point */ + return result; } @@ -1036,14 +1057,12 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified) int bitlen, rbitlen, len, - ipad = 0, ishift, i; int e, s1, e1; - bits8 mask, - *r, + bits8 *r, *ps; bitlen = VARBITLEN(arg); @@ -1108,13 +1127,9 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified) r++; } } - /* Do we need to pad at the end? */ - ipad = VARBITPAD(result); - if (ipad > 0) - { - mask = BITMASK << ipad; - *(VARBITS(result) + len - 1) &= mask; - } + + /* Make sure last byte is correctly zero-padded */ + VARBIT_PAD(result); } return result; @@ -1236,7 +1251,7 @@ bit_and(PG_FUNCTION_ARGS) for (i = 0; i < VARBITBYTES(arg1); i++) *r++ = *p1++ & *p2++; - /* Padding is not needed as & of 0 pad is 0 */ + /* Padding is not needed as & of 0 pads is 0 */ PG_RETURN_VARBIT_P(result); } @@ -1258,7 +1273,6 @@ bit_or(PG_FUNCTION_ARGS) bits8 *p1, *p2, *r; - bits8 mask; bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); @@ -1277,13 +1291,7 @@ bit_or(PG_FUNCTION_ARGS) for (i = 0; i < VARBITBYTES(arg1); i++) *r++ = *p1++ | *p2++; - /* Pad the result */ - mask = BITMASK << VARBITPAD(result); - if (mask) - { - r--; - *r &= mask; - } + /* Padding is not needed as | of 0 pads is 0 */ PG_RETURN_VARBIT_P(result); } @@ -1305,7 +1313,6 @@ bitxor(PG_FUNCTION_ARGS) bits8 *p1, *p2, *r; - bits8 mask; bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); @@ -1325,13 +1332,7 @@ bitxor(PG_FUNCTION_ARGS) for (i = 0; i < VARBITBYTES(arg1); i++) *r++ = *p1++ ^ *p2++; - /* Pad the result */ - mask = BITMASK << VARBITPAD(result); - if (mask) - { - r--; - *r &= mask; - } + /* Padding is not needed as ^ of 0 pads is 0 */ PG_RETURN_VARBIT_P(result); } @@ -1347,7 +1348,6 @@ bitnot(PG_FUNCTION_ARGS) VarBit *result; bits8 *p, *r; - bits8 mask; result = (VarBit *) palloc(VARSIZE(arg)); SET_VARSIZE(result, VARSIZE(arg)); @@ -1358,13 +1358,8 @@ bitnot(PG_FUNCTION_ARGS) for (; p < VARBITEND(arg); p++) *r++ = ~*p; - /* Pad the result */ - mask = BITMASK << VARBITPAD(result); - if (mask) - { - r--; - *r &= mask; - } + /* Must zero-pad the result, because extra bits are surely 1's here */ + VARBIT_PAD_LAST(result, r); PG_RETURN_VARBIT_P(result); } @@ -1431,6 +1426,8 @@ bitshiftleft(PG_FUNCTION_ARGS) *r = 0; } + /* The pad bits should be already zero at this point */ + PG_RETURN_VARBIT_P(result); } @@ -1497,6 +1494,8 @@ bitshiftright(PG_FUNCTION_ARGS) if ((++r) < VARBITEND(result)) *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK; } + /* We may have shifted 1's into the pad bits, so fix that */ + VARBIT_PAD_LAST(result, r); } PG_RETURN_VARBIT_P(result); @@ -1539,11 +1538,11 @@ bitfromint4(PG_FUNCTION_ARGS) /* store first fractional byte */ if (destbitsleft > srcbitsleft) { - int val = (int) (a >> (destbitsleft - 8)); + unsigned int val = (unsigned int) (a >> (destbitsleft - 8)); /* Force sign-fill in case the compiler implements >> as zero-fill */ if (a < 0) - val |= (-1) << (srcbitsleft + 8 - destbitsleft); + val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft); *r++ = (bits8) (val & BITMASK); destbitsleft -= 8; } @@ -1619,11 +1618,11 @@ bitfromint8(PG_FUNCTION_ARGS) /* store first fractional byte */ if (destbitsleft > srcbitsleft) { - int val = (int) (a >> (destbitsleft - 8)); + unsigned int val = (unsigned int) (a >> (destbitsleft - 8)); /* Force sign-fill in case the compiler implements >> as zero-fill */ if (a < 0) - val |= (-1) << (srcbitsleft + 8 - destbitsleft); + val |= ((unsigned int) -1) << (srcbitsleft + 8 - destbitsleft); *r++ = (bits8) (val & BITMASK); destbitsleft -= 8; } diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 8f07b1e2729..e63a4e553b2 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -3,7 +3,7 @@ * varchar.c * Functions for the built-in types char(n) and varchar(n). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -14,14 +14,17 @@ */ #include "postgres.h" - -#include "access/hash.h" -#include "access/tuptoaster.h" +#include "access/detoast.h" #include "catalog/pg_collation.h" +#include "catalog/pg_type.h" #include "libpq/pqformat.h" #include "nodes/nodeFuncs.h" +#include "nodes/supportnodes.h" #include "utils/array.h" #include "utils/builtins.h" +#include "utils/hashutils.h" +#include "utils/lsyscache.h" +#include "utils/pg_locale.h" #include "utils/varlena.h" #include "mb/pg_wchar.h" @@ -546,32 +549,41 @@ varcharsend(PG_FUNCTION_ARGS) /* - * varchar_transform() - * Flatten calls to varchar's length coercion function that set the new maximum - * length >= the previous maximum length. We can ignore the isExplicit - * argument, since that only affects truncation cases. + * varchar_support() + * + * Planner support function for the varchar() length coercion function. + * + * Currently, the only interesting thing we can do is flatten calls that set + * the new maximum length >= the previous maximum length. We can ignore the + * isExplicit argument, since that only affects truncation cases. */ Datum -varchar_transform(PG_FUNCTION_ARGS) +varchar_support(PG_FUNCTION_ARGS) { - FuncExpr *expr = castNode(FuncExpr, PG_GETARG_POINTER(0)); + Node *rawreq = (Node *) PG_GETARG_POINTER(0); Node *ret = NULL; - Node *typmod; - Assert(list_length(expr->args) >= 2); + if (IsA(rawreq, SupportRequestSimplify)) + { + SupportRequestSimplify *req = (SupportRequestSimplify *) rawreq; + FuncExpr *expr = req->fcall; + Node *typmod; - typmod = (Node *) lsecond(expr->args); + Assert(list_length(expr->args) >= 2); - if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) - { - Node *source = (Node *) linitial(expr->args); - int32 old_typmod = exprTypmod(source); - int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); - int32 old_max = old_typmod - VARHDRSZ; - int32 new_max = new_typmod - VARHDRSZ; - - if (new_typmod < 0 || (old_typmod >= 0 && old_max <= new_max)) - ret = relabel_to_typmod(source, new_typmod); + typmod = (Node *) lsecond(expr->args); + + if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull) + { + Node *source = (Node *) linitial(expr->args); + int32 old_typmod = exprTypmod(source); + int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue); + int32 old_max = old_typmod - VARHDRSZ; + int32 new_max = new_typmod - VARHDRSZ; + + if (new_typmod < 0 || (old_typmod >= 0 && old_max <= new_max)) + ret = relabel_to_typmod(source, new_typmod); + } } PG_RETURN_POINTER(ret); @@ -707,6 +719,22 @@ bpcharoctetlen(PG_FUNCTION_ARGS) * need to be so careful. *****************************************************************************/ +static void +check_collation_set(Oid collid) +{ + if (!OidIsValid(collid)) + { + /* + * This typically means that the parser could not resolve a conflict + * of implicit collations, so report it that way. + */ + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string comparison"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + } +} + Datum bpchareq(PG_FUNCTION_ARGS) { @@ -715,18 +743,31 @@ bpchareq(PG_FUNCTION_ARGS) int len1, len2; bool result; + Oid collid = PG_GET_COLLATION(); + + check_collation_set(collid); len1 = bcTruelen(arg1); len2 = bcTruelen(arg2); - /* - * Since we only care about equality or not-equality, we can avoid all the - * expense of strcoll() here, and just do bitwise comparison. - */ - if (len1 != len2) - result = false; + if (lc_collate_is_c(collid) || + collid == DEFAULT_COLLATION_OID || + pg_newlocale_from_collation(collid)->deterministic) + { + /* + * Since we only care about equality or not-equality, we can avoid all + * the expense of strcoll() here, and just do bitwise comparison. + */ + if (len1 != len2) + result = false; + else + result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0); + } else - result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0); + { + result = (varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2, + collid) == 0); + } PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); @@ -742,18 +783,29 @@ bpcharne(PG_FUNCTION_ARGS) int len1, len2; bool result; + Oid collid = PG_GET_COLLATION(); len1 = bcTruelen(arg1); len2 = bcTruelen(arg2); - /* - * Since we only care about equality or not-equality, we can avoid all the - * expense of strcoll() here, and just do bitwise comparison. - */ - if (len1 != len2) - result = true; + if (lc_collate_is_c(collid) || + collid == DEFAULT_COLLATION_OID || + pg_newlocale_from_collation(collid)->deterministic) + { + /* + * Since we only care about equality or not-equality, we can avoid all + * the expense of strcoll() here, and just do bitwise comparison. + */ + if (len1 != len2) + result = true; + else + result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0); + } else - result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0); + { + result = (varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2, + collid) != 0); + } PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); @@ -876,7 +928,7 @@ bpchar_sortsupport(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); /* Use generic string SortSupport */ - varstr_sortsupport(ssup, collid, true); + varstr_sortsupport(ssup, BPCHAROID, collid); MemoryContextSwitchTo(oldcontext); @@ -923,23 +975,60 @@ bpchar_smaller(PG_FUNCTION_ARGS) /* * bpchar needs a specialized hash function because we want to ignore * trailing blanks in comparisons. - * - * Note: currently there is no need for locale-specific behavior here, - * but if we ever change the semantics of bpchar comparison to trust - * strcoll() completely, we'd need to do something different in non-C locales. */ Datum hashbpchar(PG_FUNCTION_ARGS) { BpChar *key = PG_GETARG_BPCHAR_PP(0); + Oid collid = PG_GET_COLLATION(); char *keydata; int keylen; + pg_locale_t mylocale = 0; Datum result; + if (!collid) + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string hashing"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + keydata = VARDATA_ANY(key); keylen = bcTruelen(key); - result = hash_any((unsigned char *) keydata, keylen); + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (!mylocale || mylocale->deterministic) + { + result = hash_any((unsigned char *) keydata, keylen); + } + else + { +#ifdef USE_ICU + if (mylocale->provider == COLLPROVIDER_ICU) + { + int32_t ulen = -1; + UChar *uchar = NULL; + Size bsize; + uint8_t *buf; + + ulen = icu_to_uchar(&uchar, keydata, keylen); + + bsize = ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, NULL, 0); + buf = palloc(bsize); + ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, buf, bsize); + + result = hash_any(buf, bsize); + + pfree(buf); + } + else +#endif + /* shouldn't happen */ + elog(ERROR, "unsupported collprovider: %c", mylocale->provider); + } /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); @@ -951,15 +1040,56 @@ Datum hashbpcharextended(PG_FUNCTION_ARGS) { BpChar *key = PG_GETARG_BPCHAR_PP(0); + Oid collid = PG_GET_COLLATION(); char *keydata; int keylen; + pg_locale_t mylocale = 0; Datum result; + if (!collid) + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string hashing"), + errhint("Use the COLLATE clause to set the collation explicitly."))); + keydata = VARDATA_ANY(key); keylen = bcTruelen(key); - result = hash_any_extended((unsigned char *) keydata, keylen, - PG_GETARG_INT64(1)); + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (!mylocale || mylocale->deterministic) + { + result = hash_any_extended((unsigned char *) keydata, keylen, + PG_GETARG_INT64(1)); + } + else + { +#ifdef USE_ICU + if (mylocale->provider == COLLPROVIDER_ICU) + { + int32_t ulen = -1; + UChar *uchar = NULL; + Size bsize; + uint8_t *buf; + + ulen = icu_to_uchar(&uchar, VARDATA_ANY(key), VARSIZE_ANY_EXHDR(key)); + + bsize = ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, NULL, 0); + buf = palloc(bsize); + ucol_getSortKey(mylocale->info.icu.ucol, + uchar, ulen, buf, bsize); + + result = hash_any_extended(buf, bsize, PG_GETARG_INT64(1)); + + pfree(buf); + } + else +#endif + /* shouldn't happen */ + elog(ERROR, "unsupported collprovider: %c", mylocale->provider); + } PG_FREE_IF_COPY(key, 0); @@ -1085,7 +1215,7 @@ btbpchar_pattern_sortsupport(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); /* Use generic string SortSupport, forcing "C" collation */ - varstr_sortsupport(ssup, C_COLLATION_OID, true); + varstr_sortsupport(ssup, BPCHAROID, C_COLLATION_OID); MemoryContextSwitchTo(oldcontext); diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index e8500b274dc..722b2c722d9 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3,7 +3,7 @@ * varlena.c * Functions for the variable-length built-in types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,8 +17,7 @@ #include #include -#include "access/hash.h" -#include "access/tuptoaster.h" +#include "access/detoast.h" #include "catalog/pg_collation.h" #include "catalog/pg_type.h" #include "common/int.h" @@ -30,6 +29,7 @@ #include "regex/regex.h" #include "utils/builtins.h" #include "utils/bytea.h" +#include "utils/hashutils.h" #include "utils/lsyscache.h" #include "utils/memutils.h" #include "utils/pg_locale.h" @@ -43,18 +43,33 @@ int bytea_output = BYTEA_OUTPUT_HEX; typedef struct varlena unknown; typedef struct varlena VarString; +/* + * State for text_position_* functions. + */ typedef struct { - bool use_wchar; /* T if multibyte encoding */ - char *str1; /* use these if not use_wchar */ - char *str2; /* note: these point to original texts */ - pg_wchar *wstr1; /* use these if use_wchar */ - pg_wchar *wstr2; /* note: these are palloc'd */ - int len1; /* string lengths in logical characters */ + bool is_multibyte; /* T if multibyte encoding */ + bool is_multibyte_char_in_char; + + char *str1; /* haystack string */ + char *str2; /* needle string */ + int len1; /* string lengths in bytes */ int len2; + /* Skip table for Boyer-Moore-Horspool search algorithm: */ int skiptablemask; /* mask for ANDing with skiptable subscripts */ int skiptable[256]; /* skip distance for given mismatched char */ + + char *last_match; /* pointer to last match in 'str1' */ + + /* + * Sometimes we need to convert the byte position of a match to a + * character position. These store the last position that was converted, + * so that on the next call, we can continue from that point, rather than + * count characters from the very beginning. + */ + char *refpoint; /* pointer within original haystack string */ + int refpos; /* 0-based character offset of the same point */ } TextPositionState; typedef struct @@ -69,7 +84,7 @@ typedef struct int last_returned; /* Last comparison result (cache) */ bool cache_blob; /* Does buf2 contain strxfrm() blob, etc? */ bool collate_c; - bool bpchar; /* Sorting bpchar, not varchar/text/bytea? */ + Oid typid; /* Actual datatype (text/bpchar/bytea/name) */ hyperLogLogState abbr_card; /* Abbreviated key cardinality state */ hyperLogLogState full_card; /* Full key cardinality state */ double prop_card; /* Required cardinality proportion */ @@ -93,45 +108,52 @@ typedef struct static int varstrfastcmp_c(Datum x, Datum y, SortSupport ssup); static int bpcharfastcmp_c(Datum x, Datum y, SortSupport ssup); -static int varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup); +static int namefastcmp_c(Datum x, Datum y, SortSupport ssup); +static int varlenafastcmp_locale(Datum x, Datum y, SortSupport ssup); +static int namefastcmp_locale(Datum x, Datum y, SortSupport ssup); +static int varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup); static int varstrcmp_abbrev(Datum x, Datum y, SortSupport ssup); static Datum varstr_abbrev_convert(Datum original, SortSupport ssup); static bool varstr_abbrev_abort(int memtupcount, SortSupport ssup); static int32 text_length(Datum str); static text *text_catenate(text *t1, text *t2); static text *text_substring(Datum str, - int32 start, - int32 length, - bool length_not_specified); + int32 start, + int32 length, + bool length_not_specified); static text *text_overlay(text *t1, text *t2, int sp, int sl); -static int text_position(text *t1, text *t2); -static void text_position_setup(text *t1, text *t2, TextPositionState *state); -static int text_position_next(int start_pos, TextPositionState *state); +static int text_position(text *t1, text *t2, Oid collid); +static void text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state); +static bool text_position_next(TextPositionState *state); +static char *text_position_next_internal(char *start_ptr, TextPositionState *state); +static char *text_position_get_match_ptr(TextPositionState *state); +static int text_position_get_match_pos(TextPositionState *state); static void text_position_cleanup(TextPositionState *state); +static void check_collation_set(Oid collid); static int text_cmp(text *arg1, text *arg2, Oid collid); static bytea *bytea_catenate(bytea *t1, bytea *t2); static bytea *bytea_substring(Datum str, - int S, - int L, - bool length_not_specified); + int S, + int L, + bool length_not_specified); static bytea *bytea_overlay(bytea *t1, bytea *t2, int sp, int sl); static void appendStringInfoText(StringInfo str, const text *t); static Datum text_to_array_internal(PG_FUNCTION_ARGS); static text *array_to_text_internal(FunctionCallInfo fcinfo, ArrayType *v, - const char *fldsep, const char *null_string); + const char *fldsep, const char *null_string); static StringInfo makeStringAggState(FunctionCallInfo fcinfo); static bool text_format_parse_digits(const char **ptr, const char *end_ptr, - int *value); + int *value); static const char *text_format_parse_format(const char *start_ptr, - const char *end_ptr, - int *argpos, int *widthpos, - int *flags, int *width); + const char *end_ptr, + int *argpos, int *widthpos, + int *flags, int *width); static void text_format_string_conversion(StringInfo buf, char conversion, - FmgrInfo *typOutputInfo, - Datum value, bool isNull, - int flags, int width); + FmgrInfo *typOutputInfo, + Datum value, bool isNull, + int flags, int width); static void text_format_append_string(StringInfo buf, const char *str, - int flags, int width); + int flags, int width); /***************************************************************************** @@ -182,7 +204,7 @@ char * text_to_cstring(const text *t) { /* must cast away the const, unfortunately */ - text *tunpacked = pg_detoast_datum_packed((struct varlena *) t); + text *tunpacked = pg_detoast_datum_packed(unconstify(text *, t)); int len = VARSIZE_ANY_EXHDR(tunpacked); char *result; @@ -213,7 +235,7 @@ void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len) { /* must cast away the const, unfortunately */ - text *srcunpacked = pg_detoast_datum_packed((struct varlena *) src); + text *srcunpacked = pg_detoast_datum_packed(unconstify(text *, src)); size_t src_len = VARSIZE_ANY_EXHDR(srcunpacked); if (dst_len > 0) @@ -1073,7 +1095,7 @@ textpos(PG_FUNCTION_ARGS) text *str = PG_GETARG_TEXT_PP(0); text *search_str = PG_GETARG_TEXT_PP(1); - PG_RETURN_INT32((int32) text_position(str, search_str)); + PG_RETURN_INT32((int32) text_position(str, search_str, PG_GET_COLLATION())); } /* @@ -1091,13 +1113,19 @@ textpos(PG_FUNCTION_ARGS) * functions. */ static int -text_position(text *t1, text *t2) +text_position(text *t1, text *t2, Oid collid) { TextPositionState state; int result; - text_position_setup(t1, t2, &state); - result = text_position_next(1, &state); + if (VARSIZE_ANY_EXHDR(t1) < 1 || VARSIZE_ANY_EXHDR(t2) < 1) + return 0; + + text_position_setup(t1, t2, collid, &state); + if (!text_position_next(&state)) + result = 0; + else + result = text_position_get_match_pos(&state); text_position_cleanup(&state); return result; } @@ -1109,44 +1137,69 @@ text_position(text *t1, text *t2) * * These are broken out so that a string can be efficiently searched for * multiple occurrences of the same pattern. text_position_next may be - * called multiple times with increasing values of start_pos, which is - * the 1-based character position to start the search from. The "state" - * variable is normally just a local variable in the caller. + * called multiple times, and it advances to the next match on each call. + * text_position_get_match_ptr() and text_position_get_match_pos() return + * a pointer or 1-based character position of the last match, respectively. + * + * The "state" variable is normally just a local variable in the caller. + * + * NOTE: text_position_next skips over the matched portion. For example, + * searching for "xx" in "xxx" returns only one match, not two. */ static void -text_position_setup(text *t1, text *t2, TextPositionState *state) +text_position_setup(text *t1, text *t2, Oid collid, TextPositionState *state) { int len1 = VARSIZE_ANY_EXHDR(t1); int len2 = VARSIZE_ANY_EXHDR(t2); + pg_locale_t mylocale = 0; + + check_collation_set(collid); + + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (mylocale && !mylocale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for substring searches"))); + + Assert(len1 > 0); + Assert(len2 > 0); + /* + * Even with a multi-byte encoding, we perform the search using the raw + * byte sequence, ignoring multibyte issues. For UTF-8, that works fine, + * because in UTF-8 the byte sequence of one character cannot contain + * another character. For other multi-byte encodings, we do the search + * initially as a simple byte search, ignoring multibyte issues, but + * verify afterwards that the match we found is at a character boundary, + * and continue the search if it was a false match. + */ if (pg_database_encoding_max_length() == 1) { - /* simple case - single byte encoding */ - state->use_wchar = false; - state->str1 = VARDATA_ANY(t1); - state->str2 = VARDATA_ANY(t2); - state->len1 = len1; - state->len2 = len2; + state->is_multibyte = false; + state->is_multibyte_char_in_char = false; + } + else if (GetDatabaseEncoding() == PG_UTF8) + { + state->is_multibyte = true; + state->is_multibyte_char_in_char = false; } else { - /* not as simple - multibyte encoding */ - pg_wchar *p1, - *p2; - - p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar)); - len1 = pg_mb2wchar_with_len(VARDATA_ANY(t1), p1, len1); - p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar)); - len2 = pg_mb2wchar_with_len(VARDATA_ANY(t2), p2, len2); - - state->use_wchar = true; - state->wstr1 = p1; - state->wstr2 = p2; - state->len1 = len1; - state->len2 = len2; + state->is_multibyte = true; + state->is_multibyte_char_in_char = true; } + state->str1 = VARDATA_ANY(t1); + state->str2 = VARDATA_ANY(t2); + state->len1 = len1; + state->len2 = len2; + state->last_match = NULL; + state->refpoint = state->str1; + state->refpos = 0; + /* * Prepare the skip table for Boyer-Moore-Horspool searching. In these * notes we use the terminology that the "haystack" is the string to be @@ -1163,6 +1216,7 @@ text_position_setup(text *t1, text *t2, TextPositionState *state) int skiptablemask; int last; int i; + const char *str2 = state->str2; /* * First we must determine how much of the skip table to use. The @@ -1209,164 +1263,197 @@ text_position_setup(text *t1, text *t2, TextPositionState *state) */ last = len2 - 1; - if (!state->use_wchar) - { - const char *str2 = state->str2; - - for (i = 0; i < last; i++) - state->skiptable[(unsigned char) str2[i] & skiptablemask] = last - i; - } - else - { - const pg_wchar *wstr2 = state->wstr2; - - for (i = 0; i < last; i++) - state->skiptable[wstr2[i] & skiptablemask] = last - i; - } + for (i = 0; i < last; i++) + state->skiptable[(unsigned char) str2[i] & skiptablemask] = last - i; } } -static int -text_position_next(int start_pos, TextPositionState *state) +/* + * Advance to the next match, starting from the end of the previous match + * (or the beginning of the string, on first call). Returns true if a match + * is found. + */ +static bool +text_position_next(TextPositionState *state) { - int haystack_len = state->len1; int needle_len = state->len2; - int skiptablemask = state->skiptablemask; - - Assert(start_pos > 0); /* else caller error */ + char *start_ptr; + char *matchptr; if (needle_len <= 0) - return start_pos; /* result for empty pattern */ + return false; /* result for empty pattern */ - start_pos--; /* adjust for zero based arrays */ + /* Start from the point right after the previous match. */ + if (state->last_match) + start_ptr = state->last_match + needle_len; + else + start_ptr = state->str1; - /* Done if the needle can't possibly fit */ - if (haystack_len < start_pos + needle_len) - return 0; +retry: + matchptr = text_position_next_internal(start_ptr, state); - if (!state->use_wchar) + if (!matchptr) + return false; + + /* + * Found a match for the byte sequence. If this is a multibyte encoding, + * where one character's byte sequence can appear inside a longer + * multi-byte character, we need to verify that the match was at a + * character boundary, not in the middle of a multi-byte character. + */ + if (state->is_multibyte_char_in_char) { - /* simple case - single byte encoding */ - const char *haystack = state->str1; - const char *needle = state->str2; - const char *haystack_end = &haystack[haystack_len]; - const char *hptr; + /* Walk one character at a time, until we reach the match. */ - if (needle_len == 1) + /* the search should never move backwards. */ + Assert(state->refpoint <= matchptr); + + while (state->refpoint < matchptr) { - /* No point in using B-M-H for a one-character needle */ - char nchar = *needle; + /* step to next character. */ + state->refpoint += pg_mblen(state->refpoint); + state->refpos++; - hptr = &haystack[start_pos]; - while (hptr < haystack_end) + /* + * If we stepped over the match's start position, then it was a + * false positive, where the byte sequence appeared in the middle + * of a multi-byte character. Skip it, and continue the search at + * the next character boundary. + */ + if (state->refpoint > matchptr) { - if (*hptr == nchar) - return hptr - haystack + 1; - hptr++; + start_ptr = state->refpoint; + goto retry; } } - else - { - const char *needle_last = &needle[needle_len - 1]; + } - /* Start at startpos plus the length of the needle */ - hptr = &haystack[start_pos + needle_len - 1]; - while (hptr < haystack_end) - { - /* Match the needle scanning *backward* */ - const char *nptr; - const char *p; + state->last_match = matchptr; + return true; +} - nptr = needle_last; - p = hptr; - while (*nptr == *p) - { - /* Matched it all? If so, return 1-based position */ - if (nptr == needle) - return p - haystack + 1; - nptr--, p--; - } +/* + * Subroutine of text_position_next(). This searches for the raw byte + * sequence, ignoring any multi-byte encoding issues. Returns the first + * match starting at 'start_ptr', or NULL if no match is found. + */ +static char * +text_position_next_internal(char *start_ptr, TextPositionState *state) +{ + int haystack_len = state->len1; + int needle_len = state->len2; + int skiptablemask = state->skiptablemask; + const char *haystack = state->str1; + const char *needle = state->str2; + const char *haystack_end = &haystack[haystack_len]; + const char *hptr; - /* - * No match, so use the haystack char at hptr to decide how - * far to advance. If the needle had any occurrence of that - * character (or more precisely, one sharing the same - * skiptable entry) before its last character, then we advance - * far enough to align the last such needle character with - * that haystack position. Otherwise we can advance by the - * whole needle length. - */ - hptr += state->skiptable[(unsigned char) *hptr & skiptablemask]; - } + Assert(start_ptr >= haystack && start_ptr <= haystack_end); + + if (needle_len == 1) + { + /* No point in using B-M-H for a one-character needle */ + char nchar = *needle; + + hptr = start_ptr; + while (hptr < haystack_end) + { + if (*hptr == nchar) + return (char *) hptr; + hptr++; } } else { - /* The multibyte char version. This works exactly the same way. */ - const pg_wchar *haystack = state->wstr1; - const pg_wchar *needle = state->wstr2; - const pg_wchar *haystack_end = &haystack[haystack_len]; - const pg_wchar *hptr; + const char *needle_last = &needle[needle_len - 1]; - if (needle_len == 1) + /* Start at startpos plus the length of the needle */ + hptr = start_ptr + needle_len - 1; + while (hptr < haystack_end) { - /* No point in using B-M-H for a one-character needle */ - pg_wchar nchar = *needle; + /* Match the needle scanning *backward* */ + const char *nptr; + const char *p; - hptr = &haystack[start_pos]; - while (hptr < haystack_end) + nptr = needle_last; + p = hptr; + while (*nptr == *p) { - if (*hptr == nchar) - return hptr - haystack + 1; - hptr++; + /* Matched it all? If so, return 1-based position */ + if (nptr == needle) + return (char *) p; + nptr--, p--; } + + /* + * No match, so use the haystack char at hptr to decide how far to + * advance. If the needle had any occurrence of that character + * (or more precisely, one sharing the same skiptable entry) + * before its last character, then we advance far enough to align + * the last such needle character with that haystack position. + * Otherwise we can advance by the whole needle length. + */ + hptr += state->skiptable[(unsigned char) *hptr & skiptablemask]; } - else - { - const pg_wchar *needle_last = &needle[needle_len - 1]; + } - /* Start at startpos plus the length of the needle */ - hptr = &haystack[start_pos + needle_len - 1]; - while (hptr < haystack_end) - { - /* Match the needle scanning *backward* */ - const pg_wchar *nptr; - const pg_wchar *p; + return 0; /* not found */ +} - nptr = needle_last; - p = hptr; - while (*nptr == *p) - { - /* Matched it all? If so, return 1-based position */ - if (nptr == needle) - return p - haystack + 1; - nptr--, p--; - } +/* + * Return a pointer to the current match. + * + * The returned pointer points into correct position in the original + * the haystack string. + */ +static char * +text_position_get_match_ptr(TextPositionState *state) +{ + return state->last_match; +} - /* - * No match, so use the haystack char at hptr to decide how - * far to advance. If the needle had any occurrence of that - * character (or more precisely, one sharing the same - * skiptable entry) before its last character, then we advance - * far enough to align the last such needle character with - * that haystack position. Otherwise we can advance by the - * whole needle length. - */ - hptr += state->skiptable[*hptr & skiptablemask]; - } +/* + * Return the offset of the current match. + * + * The offset is in characters, 1-based. + */ +static int +text_position_get_match_pos(TextPositionState *state) +{ + if (!state->is_multibyte) + return state->last_match - state->str1 + 1; + else + { + /* Convert the byte position to char position. */ + while (state->refpoint < state->last_match) + { + state->refpoint += pg_mblen(state->refpoint); + state->refpos++; } + Assert(state->refpoint == state->last_match); + return state->refpos + 1; } - - return 0; /* not found */ } static void text_position_cleanup(TextPositionState *state) { - if (state->use_wchar) + /* no cleanup needed */ +} + +static void +check_collation_set(Oid collid) +{ + if (!OidIsValid(collid)) { - pfree(state->wstr1); - pfree(state->wstr2); + /* + * This typically means that the parser could not resolve a conflict + * of implicit collations, so report it that way. + */ + ereport(ERROR, + (errcode(ERRCODE_INDETERMINATE_COLLATION), + errmsg("could not determine which collation to use for string comparison"), + errhint("Use the COLLATE clause to set the collation explicitly."))); } } @@ -1376,12 +1463,20 @@ text_position_cleanup(TextPositionState *state) * to allow null-termination for inputs to strcoll(). * Returns an integer less than, equal to, or greater than zero, indicating * whether arg1 is less than, equal to, or greater than arg2. + * + * Note: many functions that depend on this are marked leakproof; therefore, + * avoid reporting the actual contents of the input when throwing errors. + * All errors herein should be things that can't happen except on corrupt + * data, anyway; otherwise we will have trouble with indexing strings that + * would cause them. */ int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) { int result; + check_collation_set(collid); + /* * Unfortunately, there is no strncoll(), so in the non-C locale case we * have to do some memory copying. This turns out to be significantly @@ -1403,20 +1498,7 @@ varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) pg_locale_t mylocale = 0; if (collid != DEFAULT_COLLATION_OID) - { - if (!OidIsValid(collid)) - { - /* - * This typically means that the parser could not resolve a - * conflict of implicit collations, so report it that way. - */ - ereport(ERROR, - (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for string comparison"), - errhint("Use the COLLATE clause to set the collation explicitly."))); - } mylocale = pg_newlocale_from_collation(collid); - } /* * memcmp() can't tell us which of two unequal strings sorts first, @@ -1499,13 +1581,9 @@ varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) ereport(ERROR, (errmsg("could not compare Unicode strings: %m"))); - /* - * In some locales wcscoll() can claim that nonidentical strings - * are equal. Believing that would be bad news for a number of - * reasons, so we follow Perl's lead and sort "equal" strings - * according to strcmp (on the UTF-8 representation). - */ - if (result == 0) + /* Break tie if necessary. */ + if (result == 0 && + (!mylocale || mylocale->deterministic)) { result = memcmp(arg1, arg2, Min(len1, len2)); if ((result == 0) && (len1 != len2)) @@ -1590,13 +1668,9 @@ varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid) else result = strcoll(a1p, a2p); - /* - * In some locales strcoll() can claim that nonidentical strings are - * equal. Believing that would be bad news for a number of reasons, - * so we follow Perl's lead and sort "equal" strings according to - * strcmp(). - */ - if (result == 0) + /* Break tie if necessary. */ + if (result == 0 && + (!mylocale || mylocale->deterministic)) result = strcmp(a1p, a2p); if (a1p != a1buf) @@ -1640,33 +1714,52 @@ text_cmp(text *arg1, text *arg2, Oid collid) Datum texteq(PG_FUNCTION_ARGS) { - Datum arg1 = PG_GETARG_DATUM(0); - Datum arg2 = PG_GETARG_DATUM(1); + Oid collid = PG_GET_COLLATION(); bool result; - Size len1, - len2; - /* - * Since we only care about equality or not-equality, we can avoid all the - * expense of strcoll() here, and just do bitwise comparison. In fact, we - * don't even have to do a bitwise comparison if we can show the lengths - * of the strings are unequal; which might save us from having to detoast - * one or both values. - */ - len1 = toast_raw_datum_size(arg1); - len2 = toast_raw_datum_size(arg2); - if (len1 != len2) - result = false; + check_collation_set(collid); + + if (lc_collate_is_c(collid) || + collid == DEFAULT_COLLATION_OID || + pg_newlocale_from_collation(collid)->deterministic) + { + Datum arg1 = PG_GETARG_DATUM(0); + Datum arg2 = PG_GETARG_DATUM(1); + Size len1, + len2; + + /* + * Since we only care about equality or not-equality, we can avoid all + * the expense of strcoll() here, and just do bitwise comparison. In + * fact, we don't even have to do a bitwise comparison if we can show + * the lengths of the strings are unequal; which might save us from + * having to detoast one or both values. + */ + len1 = toast_raw_datum_size(arg1); + len2 = toast_raw_datum_size(arg2); + if (len1 != len2) + result = false; + else + { + text *targ1 = DatumGetTextPP(arg1); + text *targ2 = DatumGetTextPP(arg2); + + result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2), + len1 - VARHDRSZ) == 0); + + PG_FREE_IF_COPY(targ1, 0); + PG_FREE_IF_COPY(targ2, 1); + } + } else { - text *targ1 = DatumGetTextPP(arg1); - text *targ2 = DatumGetTextPP(arg2); + text *arg1 = PG_GETARG_TEXT_PP(0); + text *arg2 = PG_GETARG_TEXT_PP(1); - result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2), - len1 - VARHDRSZ) == 0); + result = (text_cmp(arg1, arg2, collid) == 0); - PG_FREE_IF_COPY(targ1, 0); - PG_FREE_IF_COPY(targ2, 1); + PG_FREE_IF_COPY(arg1, 0); + PG_FREE_IF_COPY(arg2, 1); } PG_RETURN_BOOL(result); @@ -1675,27 +1768,46 @@ texteq(PG_FUNCTION_ARGS) Datum textne(PG_FUNCTION_ARGS) { - Datum arg1 = PG_GETARG_DATUM(0); - Datum arg2 = PG_GETARG_DATUM(1); + Oid collid = PG_GET_COLLATION(); bool result; - Size len1, - len2; - /* See comment in texteq() */ - len1 = toast_raw_datum_size(arg1); - len2 = toast_raw_datum_size(arg2); - if (len1 != len2) - result = true; + check_collation_set(collid); + + if (lc_collate_is_c(collid) || + collid == DEFAULT_COLLATION_OID || + pg_newlocale_from_collation(collid)->deterministic) + { + Datum arg1 = PG_GETARG_DATUM(0); + Datum arg2 = PG_GETARG_DATUM(1); + Size len1, + len2; + + /* See comment in texteq() */ + len1 = toast_raw_datum_size(arg1); + len2 = toast_raw_datum_size(arg2); + if (len1 != len2) + result = true; + else + { + text *targ1 = DatumGetTextPP(arg1); + text *targ2 = DatumGetTextPP(arg2); + + result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2), + len1 - VARHDRSZ) != 0); + + PG_FREE_IF_COPY(targ1, 0); + PG_FREE_IF_COPY(targ2, 1); + } + } else { - text *targ1 = DatumGetTextPP(arg1); - text *targ2 = DatumGetTextPP(arg2); + text *arg1 = PG_GETARG_TEXT_PP(0); + text *arg2 = PG_GETARG_TEXT_PP(1); - result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2), - len1 - VARHDRSZ) != 0); + result = (text_cmp(arg1, arg2, collid) != 0); - PG_FREE_IF_COPY(targ1, 0); - PG_FREE_IF_COPY(targ2, 1); + PG_FREE_IF_COPY(arg1, 0); + PG_FREE_IF_COPY(arg2, 1); } PG_RETURN_BOOL(result); @@ -1766,17 +1878,29 @@ text_starts_with(PG_FUNCTION_ARGS) { Datum arg1 = PG_GETARG_DATUM(0); Datum arg2 = PG_GETARG_DATUM(1); + Oid collid = PG_GET_COLLATION(); + pg_locale_t mylocale = 0; bool result; Size len1, len2; + check_collation_set(collid); + + if (!lc_collate_is_c(collid) && collid != DEFAULT_COLLATION_OID) + mylocale = pg_newlocale_from_collation(collid); + + if (mylocale && !mylocale->deterministic) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("nondeterministic collations are not supported for substring searches"))); + len1 = toast_raw_datum_size(arg1); len2 = toast_raw_datum_size(arg2); if (len2 > len1) result = false; else { - text *targ1 = DatumGetTextPP(arg1); + text *targ1 = text_substring(arg1, 1, len2, false); text *targ2 = DatumGetTextPP(arg2); result = (memcmp(VARDATA_ANY(targ1), VARDATA_ANY(targ2), @@ -1814,7 +1938,7 @@ bttextsortsupport(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); /* Use generic string SortSupport */ - varstr_sortsupport(ssup, collid, false); + varstr_sortsupport(ssup, TEXTOID, collid); MemoryContextSwitchTo(oldcontext); @@ -1832,31 +1956,40 @@ bttextsortsupport(PG_FUNCTION_ARGS) * this will not work with any other collation, though. */ void -varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar) +varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid) { bool abbreviate = ssup->abbreviate; bool collate_c = false; VarStringSortSupport *sss; pg_locale_t locale = 0; + check_collation_set(collid); + /* * If possible, set ssup->comparator to a function which can be used to * directly compare two datums. If we can do this, we'll avoid the * overhead of a trip through the fmgr layer for every comparison, which * can be substantial. * - * Most typically, we'll set the comparator to varstrfastcmp_locale, which - * uses strcoll() to perform comparisons and knows about the special - * requirements of BpChar callers. However, if LC_COLLATE = C, we can - * make things quite a bit faster with varstrfastcmp_c or bpcharfastcmp_c, - * both of which use memcmp() rather than strcoll(). + * Most typically, we'll set the comparator to varlenafastcmp_locale, + * which uses strcoll() to perform comparisons. We use that for the + * BpChar case too, but type NAME uses namefastcmp_locale. However, if + * LC_COLLATE = C, we can make things quite a bit faster with + * varstrfastcmp_c, bpcharfastcmp_c, or namefastcmp_c, all of which use + * memcmp() rather than strcoll(). */ if (lc_collate_is_c(collid)) { - if (!bpchar) - ssup->comparator = varstrfastcmp_c; - else + if (typid == BPCHAROID) ssup->comparator = bpcharfastcmp_c; + else if (typid == NAMEOID) + { + ssup->comparator = namefastcmp_c; + /* Not supporting abbreviation with type NAME, for now */ + abbreviate = false; + } + else + ssup->comparator = varstrfastcmp_c; collate_c = true; } @@ -1868,20 +2001,7 @@ varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar) * result. */ if (collid != DEFAULT_COLLATION_OID) - { - if (!OidIsValid(collid)) - { - /* - * This typically means that the parser could not resolve a - * conflict of implicit collations, so report it that way. - */ - ereport(ERROR, - (errcode(ERRCODE_INDETERMINATE_COLLATION), - errmsg("could not determine which collation to use for string comparison"), - errhint("Use the COLLATE clause to set the collation explicitly."))); - } locale = pg_newlocale_from_collation(collid); - } /* * There is a further exception on Windows. When the database @@ -1897,7 +2017,17 @@ varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar) return; #endif - ssup->comparator = varstrfastcmp_locale; + /* + * We use varlenafastcmp_locale except for type NAME. + */ + if (typid == NAMEOID) + { + ssup->comparator = namefastcmp_locale; + /* Not supporting abbreviation with type NAME, for now */ + abbreviate = false; + } + else + ssup->comparator = varlenafastcmp_locale; } /* @@ -1928,7 +2058,7 @@ varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar) /* * If we're using abbreviated keys, or if we're using a locale-aware - * comparison, we need to initialize a StringSortSupport object. Both + * comparison, we need to initialize a VarStringSortSupport object. Both * cases will make use of the temporary buffers we initialize here for * scratch space (and to detect requirement for BpChar semantics from * caller), and the abbreviation case requires additional state. @@ -1963,7 +2093,7 @@ varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar) */ sss->cache_blob = true; sss->collate_c = collate_c; - sss->bpchar = bpchar; + sss->typid = typid; ssup->ssup_extra = sss; /* @@ -2055,17 +2185,25 @@ bpcharfastcmp_c(Datum x, Datum y, SortSupport ssup) } /* - * sortsupport comparison func (for locale case) + * sortsupport comparison func (for NAME C locale case) + */ +static int +namefastcmp_c(Datum x, Datum y, SortSupport ssup) +{ + Name arg1 = DatumGetName(x); + Name arg2 = DatumGetName(y); + + return strncmp(NameStr(*arg1), NameStr(*arg2), NAMEDATALEN); +} + +/* + * sortsupport comparison func (for locale case with all varlena types) */ static int -varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup) +varlenafastcmp_locale(Datum x, Datum y, SortSupport ssup) { VarString *arg1 = DatumGetVarStringPP(x); VarString *arg2 = DatumGetVarStringPP(y); - bool arg1_match; - VarStringSortSupport *sss = (VarStringSortSupport *) ssup->ssup_extra; - - /* working state */ char *a1p, *a2p; int len1, @@ -2078,6 +2216,41 @@ varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup) len1 = VARSIZE_ANY_EXHDR(arg1); len2 = VARSIZE_ANY_EXHDR(arg2); + result = varstrfastcmp_locale(a1p, len1, a2p, len2, ssup); + + /* We can't afford to leak memory here. */ + if (PointerGetDatum(arg1) != x) + pfree(arg1); + if (PointerGetDatum(arg2) != y) + pfree(arg2); + + return result; +} + +/* + * sortsupport comparison func (for locale case with NAME type) + */ +static int +namefastcmp_locale(Datum x, Datum y, SortSupport ssup) +{ + Name arg1 = DatumGetName(x); + Name arg2 = DatumGetName(y); + + return varstrfastcmp_locale(NameStr(*arg1), strlen(NameStr(*arg1)), + NameStr(*arg2), strlen(NameStr(*arg2)), + ssup); +} + +/* + * sortsupport comparison func for locale cases + */ +static int +varstrfastcmp_locale(char *a1p, int len1, char *a2p, int len2, SortSupport ssup) +{ + VarStringSortSupport *sss = (VarStringSortSupport *) ssup->ssup_extra; + int result; + bool arg1_match; + /* Fast pre-check for equality, as discussed in varstr_cmp() */ if (len1 == len2 && memcmp(a1p, a2p, len1) == 0) { @@ -2094,11 +2267,10 @@ varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup) * (not limited to padding), so we need make no distinction between * padding space characters and "real" space characters. */ - result = 0; - goto done; + return 0; } - if (sss->bpchar) + if (sss->typid == BPCHAROID) { /* Get true number of bytes, ignoring trailing spaces */ len1 = bpchartruelen(a1p, len1); @@ -2152,8 +2324,7 @@ varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup) else if (arg1_match && !sss->cache_blob) { /* Use result cached following last actual strcoll() call */ - result = sss->last_returned; - goto done; + return sss->last_returned; } if (sss->locale) @@ -2211,24 +2382,14 @@ varstrfastcmp_locale(Datum x, Datum y, SortSupport ssup) else result = strcoll(sss->buf1, sss->buf2); - /* - * In some locales strcoll() can claim that nonidentical strings are - * equal. Believing that would be bad news for a number of reasons, so we - * follow Perl's lead and sort "equal" strings according to strcmp(). - */ - if (result == 0) + /* Break tie if necessary. */ + if (result == 0 && + (!sss->locale || sss->locale->deterministic)) result = strcmp(sss->buf1, sss->buf2); /* Cache result, perhaps saving an expensive strcoll() call next time */ sss->cache_blob = false; sss->last_returned = result; -done: - /* We can't afford to leak memory here. */ - if (PointerGetDatum(arg1) != x) - pfree(arg1); - if (PointerGetDatum(arg2) != y) - pfree(arg2); - return result; } @@ -2240,7 +2401,7 @@ varstrcmp_abbrev(Datum x, Datum y, SortSupport ssup) { /* * When 0 is returned, the core system will call varstrfastcmp_c() - * (bpcharfastcmp_c() in BpChar case) or varstrfastcmp_locale(). Even a + * (bpcharfastcmp_c() in BpChar case) or varlenafastcmp_locale(). Even a * strcmp() on two non-truncated strxfrm() blobs cannot indicate *equality* * authoritatively, for the same reason that there is a strcoll() * tie-breaker call to strcmp() in varstr_cmp(). @@ -2279,7 +2440,7 @@ varstr_abbrev_convert(Datum original, SortSupport ssup) len = VARSIZE_ANY_EXHDR(authoritative); /* Get number of bytes, ignoring trailing spaces */ - if (sss->bpchar) + if (sss->typid == BPCHAROID) len = bpchartruelen(authoritative_data, len); /* @@ -2639,6 +2800,199 @@ text_smaller(PG_FUNCTION_ARGS) } +/* + * Cross-type comparison functions for types text and name. + */ + +Datum +nameeqtext(PG_FUNCTION_ARGS) +{ + Name arg1 = PG_GETARG_NAME(0); + text *arg2 = PG_GETARG_TEXT_PP(1); + size_t len1 = strlen(NameStr(*arg1)); + size_t len2 = VARSIZE_ANY_EXHDR(arg2); + Oid collid = PG_GET_COLLATION(); + bool result; + + check_collation_set(collid); + + if (collid == C_COLLATION_OID) + result = (len1 == len2 && + memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0); + else + result = (varstr_cmp(NameStr(*arg1), len1, + VARDATA_ANY(arg2), len2, + collid) == 0); + + PG_FREE_IF_COPY(arg2, 1); + + PG_RETURN_BOOL(result); +} + +Datum +texteqname(PG_FUNCTION_ARGS) +{ + text *arg1 = PG_GETARG_TEXT_PP(0); + Name arg2 = PG_GETARG_NAME(1); + size_t len1 = VARSIZE_ANY_EXHDR(arg1); + size_t len2 = strlen(NameStr(*arg2)); + Oid collid = PG_GET_COLLATION(); + bool result; + + check_collation_set(collid); + + if (collid == C_COLLATION_OID) + result = (len1 == len2 && + memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0); + else + result = (varstr_cmp(VARDATA_ANY(arg1), len1, + NameStr(*arg2), len2, + collid) == 0); + + PG_FREE_IF_COPY(arg1, 0); + + PG_RETURN_BOOL(result); +} + +Datum +namenetext(PG_FUNCTION_ARGS) +{ + Name arg1 = PG_GETARG_NAME(0); + text *arg2 = PG_GETARG_TEXT_PP(1); + size_t len1 = strlen(NameStr(*arg1)); + size_t len2 = VARSIZE_ANY_EXHDR(arg2); + Oid collid = PG_GET_COLLATION(); + bool result; + + check_collation_set(collid); + + if (collid == C_COLLATION_OID) + result = !(len1 == len2 && + memcmp(NameStr(*arg1), VARDATA_ANY(arg2), len1) == 0); + else + result = !(varstr_cmp(NameStr(*arg1), len1, + VARDATA_ANY(arg2), len2, + collid) == 0); + + PG_FREE_IF_COPY(arg2, 1); + + PG_RETURN_BOOL(result); +} + +Datum +textnename(PG_FUNCTION_ARGS) +{ + text *arg1 = PG_GETARG_TEXT_PP(0); + Name arg2 = PG_GETARG_NAME(1); + size_t len1 = VARSIZE_ANY_EXHDR(arg1); + size_t len2 = strlen(NameStr(*arg2)); + Oid collid = PG_GET_COLLATION(); + bool result; + + check_collation_set(collid); + + if (collid == C_COLLATION_OID) + result = !(len1 == len2 && + memcmp(VARDATA_ANY(arg1), NameStr(*arg2), len1) == 0); + else + result = !(varstr_cmp(VARDATA_ANY(arg1), len1, + NameStr(*arg2), len2, + collid) == 0); + + PG_FREE_IF_COPY(arg1, 0); + + PG_RETURN_BOOL(result); +} + +Datum +btnametextcmp(PG_FUNCTION_ARGS) +{ + Name arg1 = PG_GETARG_NAME(0); + text *arg2 = PG_GETARG_TEXT_PP(1); + int32 result; + + result = varstr_cmp(NameStr(*arg1), strlen(NameStr(*arg1)), + VARDATA_ANY(arg2), VARSIZE_ANY_EXHDR(arg2), + PG_GET_COLLATION()); + + PG_FREE_IF_COPY(arg2, 1); + + PG_RETURN_INT32(result); +} + +Datum +bttextnamecmp(PG_FUNCTION_ARGS) +{ + text *arg1 = PG_GETARG_TEXT_PP(0); + Name arg2 = PG_GETARG_NAME(1); + int32 result; + + result = varstr_cmp(VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1), + NameStr(*arg2), strlen(NameStr(*arg2)), + PG_GET_COLLATION()); + + PG_FREE_IF_COPY(arg1, 0); + + PG_RETURN_INT32(result); +} + +#define CmpCall(cmpfunc) \ + DatumGetInt32(DirectFunctionCall2Coll(cmpfunc, \ + PG_GET_COLLATION(), \ + PG_GETARG_DATUM(0), \ + PG_GETARG_DATUM(1))) + +Datum +namelttext(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(btnametextcmp) < 0); +} + +Datum +nameletext(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(btnametextcmp) <= 0); +} + +Datum +namegttext(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(btnametextcmp) > 0); +} + +Datum +namegetext(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(btnametextcmp) >= 0); +} + +Datum +textltname(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(bttextnamecmp) < 0); +} + +Datum +textlename(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(bttextnamecmp) <= 0); +} + +Datum +textgtname(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(bttextnamecmp) > 0); +} + +Datum +textgename(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(CmpCall(bttextnamecmp) >= 0); +} + +#undef CmpCall + + /* * The following operators support character-by-character comparison * of text datums, to allow building indexes suitable for LIKE clauses. @@ -2758,7 +3112,7 @@ bttext_pattern_sortsupport(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); /* Use generic string SortSupport, forcing "C" collation */ - varstr_sortsupport(ssup, C_COLLATION_OID, false); + varstr_sortsupport(ssup, TEXTOID, C_COLLATION_OID); MemoryContextSwitchTo(oldcontext); @@ -3503,6 +3857,118 @@ SplitDirectoriesString(char *rawstring, char separator, } +/* + * SplitGUCList --- parse a string containing identifiers or file names + * + * This is used to split the value of a GUC_LIST_QUOTE GUC variable, without + * presuming whether the elements will be taken as identifiers or file names. + * We assume the input has already been through flatten_set_variable_args(), + * so that we need never downcase (if appropriate, that was done already). + * Nor do we ever truncate, since we don't know the correct max length. + * We disallow embedded whitespace for simplicity (it shouldn't matter, + * because any embedded whitespace should have led to double-quoting). + * Otherwise the API is identical to SplitIdentifierString. + * + * XXX it's annoying to have so many copies of this string-splitting logic. + * However, it's not clear that having one function with a bunch of option + * flags would be much better. + * + * XXX there is a version of this function in src/bin/pg_dump/dumputils.c. + * Be sure to update that if you have to change this. + * + * Inputs: + * rawstring: the input string; must be overwritable! On return, it's + * been modified to contain the separated identifiers. + * separator: the separator punctuation expected between identifiers + * (typically '.' or ','). Whitespace may also appear around + * identifiers. + * Outputs: + * namelist: filled with a palloc'd list of pointers to identifiers within + * rawstring. Caller should list_free() this even on error return. + * + * Returns true if okay, false if there is a syntax error in the string. + */ +bool +SplitGUCList(char *rawstring, char separator, + List **namelist) +{ + char *nextp = rawstring; + bool done = false; + + *namelist = NIL; + + while (scanner_isspace(*nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* allow empty string */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *curname; + char *endp; + + if (*nextp == '"') + { + /* Quoted name --- collapse quote-quote pairs */ + curname = nextp + 1; + for (;;) + { + endp = strchr(nextp + 1, '"'); + if (endp == NULL) + return false; /* mismatched quotes */ + if (endp[1] != '"') + break; /* found end of quoted name */ + /* Collapse adjacent quotes into one quote, and look again */ + memmove(endp, endp + 1, strlen(endp)); + nextp = endp; + } + /* endp now points at the terminating quote */ + nextp = endp + 1; + } + else + { + /* Unquoted name --- extends to separator or whitespace */ + curname = nextp; + while (*nextp && *nextp != separator && + !scanner_isspace(*nextp)) + nextp++; + endp = nextp; + if (curname == nextp) + return false; /* empty unquoted name not allowed */ + } + + while (scanner_isspace(*nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (scanner_isspace(*nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating current name --- add it to list + */ + *namelist = lappend(*namelist, curname); + + /* Loop back if we didn't reach end of string */ + } while (!done); + + return true; +} + + /***************************************************************************** * Comparison Functions used for bytea * @@ -3686,7 +4152,7 @@ bytea_sortsupport(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(ssup->ssup_cxt); /* Use generic string SortSupport, forcing "C" collation */ - varstr_sortsupport(ssup, C_COLLATION_OID, false); + varstr_sortsupport(ssup, BYTEAOID, C_COLLATION_OID); MemoryContextSwitchTo(oldcontext); @@ -3723,39 +4189,32 @@ replace_text(PG_FUNCTION_ARGS) int from_sub_text_len; TextPositionState state; text *ret_text; - int start_posn; - int curr_posn; int chunk_len; + char *curr_ptr; char *start_ptr; StringInfoData str; + bool found; - text_position_setup(src_text, from_sub_text, &state); - - /* - * Note: we check the converted string length, not the original, because - * they could be different if the input contained invalid encoding. - */ - src_text_len = state.len1; - from_sub_text_len = state.len2; + src_text_len = VARSIZE_ANY_EXHDR(src_text); + from_sub_text_len = VARSIZE_ANY_EXHDR(from_sub_text); /* Return unmodified source string if empty source or pattern */ if (src_text_len < 1 || from_sub_text_len < 1) { - text_position_cleanup(&state); PG_RETURN_TEXT_P(src_text); } - start_posn = 1; - curr_posn = text_position_next(1, &state); + text_position_setup(src_text, from_sub_text, PG_GET_COLLATION(), &state); + + found = text_position_next(&state); /* When the from_sub_text is not found, there is nothing to do. */ - if (curr_posn == 0) + if (!found) { text_position_cleanup(&state); PG_RETURN_TEXT_P(src_text); } - - /* start_ptr points to the start_posn'th character of src_text */ + curr_ptr = text_position_get_match_ptr(&state); start_ptr = VARDATA_ANY(src_text); initStringInfo(&str); @@ -3765,19 +4224,18 @@ replace_text(PG_FUNCTION_ARGS) CHECK_FOR_INTERRUPTS(); /* copy the data skipped over by last text_position_next() */ - chunk_len = charlen_to_bytelen(start_ptr, curr_posn - start_posn); + chunk_len = curr_ptr - start_ptr; appendBinaryStringInfo(&str, start_ptr, chunk_len); appendStringInfoText(&str, to_sub_text); - start_posn = curr_posn; - start_ptr += chunk_len; - start_posn += from_sub_text_len; - start_ptr += charlen_to_bytelen(start_ptr, from_sub_text_len); + start_ptr = curr_ptr + from_sub_text_len; - curr_posn = text_position_next(start_posn, &state); + found = text_position_next(&state); + if (found) + curr_ptr = text_position_get_match_ptr(&state); } - while (curr_posn > 0); + while (found); /* copy trailing data */ chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr; @@ -4078,9 +4536,10 @@ split_text(PG_FUNCTION_ARGS) int inputstring_len; int fldsep_len; TextPositionState state; - int start_posn; - int end_posn; + char *start_ptr; + char *end_ptr; text *result_text; + bool found; /* field number is 1 based */ if (fldnum < 1) @@ -4088,21 +4547,12 @@ split_text(PG_FUNCTION_ARGS) (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("field position must be greater than zero"))); - text_position_setup(inputstring, fldsep, &state); - - /* - * Note: we check the converted string length, not the original, because - * they could be different if the input contained invalid encoding. - */ - inputstring_len = state.len1; - fldsep_len = state.len2; + inputstring_len = VARSIZE_ANY_EXHDR(inputstring); + fldsep_len = VARSIZE_ANY_EXHDR(fldsep); /* return empty string for empty input string */ if (inputstring_len < 1) - { - text_position_cleanup(&state); PG_RETURN_TEXT_P(cstring_to_text("")); - } /* empty field separator */ if (fldsep_len < 1) @@ -4115,12 +4565,14 @@ split_text(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(cstring_to_text("")); } + text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state); + /* identify bounds of first field */ - start_posn = 1; - end_posn = text_position_next(1, &state); + start_ptr = VARDATA_ANY(inputstring); + found = text_position_next(&state); /* special case if fldsep not found at all */ - if (end_posn == 0) + if (!found) { text_position_cleanup(&state); /* if field 1 requested, return input string, else empty string */ @@ -4129,12 +4581,15 @@ split_text(PG_FUNCTION_ARGS) else PG_RETURN_TEXT_P(cstring_to_text("")); } + end_ptr = text_position_get_match_ptr(&state); - while (end_posn > 0 && --fldnum > 0) + while (found && --fldnum > 0) { /* identify bounds of next field */ - start_posn = end_posn + fldsep_len; - end_posn = text_position_next(start_posn, &state); + start_ptr = end_ptr + fldsep_len; + found = text_position_next(&state); + if (found) + end_ptr = text_position_get_match_ptr(&state); } text_position_cleanup(&state); @@ -4144,20 +4599,19 @@ split_text(PG_FUNCTION_ARGS) /* N'th field separator not found */ /* if last field requested, return it, else empty string */ if (fldnum == 1) - result_text = text_substring(PointerGetDatum(inputstring), - start_posn, - -1, - true); + { + int last_len = start_ptr - VARDATA_ANY(inputstring); + + result_text = cstring_to_text_with_len(start_ptr, + inputstring_len - last_len); + } else result_text = cstring_to_text(""); } else { /* non-last field requested */ - result_text = text_substring(PointerGetDatum(inputstring), - start_posn, - end_posn - start_posn, - false); + result_text = cstring_to_text_with_len(start_ptr, end_ptr - start_ptr); } PG_RETURN_TEXT_P(result_text); @@ -4167,11 +4621,12 @@ split_text(PG_FUNCTION_ARGS) * Convenience function to return true when two text params are equal. */ static bool -text_isequal(text *txt1, text *txt2) +text_isequal(text *txt1, text *txt2, Oid collid) { - return DatumGetBool(DirectFunctionCall2(texteq, - PointerGetDatum(txt1), - PointerGetDatum(txt2))); + return DatumGetBool(DirectFunctionCall2Coll(texteq, + collid, + PointerGetDatum(txt1), + PointerGetDatum(txt2))); } /* @@ -4242,27 +4697,13 @@ text_to_array_internal(PG_FUNCTION_ARGS) * to search for occurrences of fldsep. */ TextPositionState state; - int fldnum; - int start_posn; - int end_posn; - int chunk_len; - text_position_setup(inputstring, fldsep, &state); - - /* - * Note: we check the converted string length, not the original, - * because they could be different if the input contained invalid - * encoding. - */ - inputstring_len = state.len1; - fldsep_len = state.len2; + inputstring_len = VARSIZE_ANY_EXHDR(inputstring); + fldsep_len = VARSIZE_ANY_EXHDR(fldsep); /* return empty array for empty input string */ if (inputstring_len < 1) - { - text_position_cleanup(&state); PG_RETURN_ARRAYTYPE_P(construct_empty_array(TEXTOID)); - } /* * empty field separator: return the input string as a one-element @@ -4275,9 +4716,8 @@ text_to_array_internal(PG_FUNCTION_ARGS) int dims[1]; int lbs[1]; - text_position_cleanup(&state); /* single element can be a NULL too */ - is_null = null_string ? text_isequal(inputstring, null_string) : false; + is_null = null_string ? text_isequal(inputstring, null_string, PG_GET_COLLATION()) : false; elems[0] = PointerGetDatum(inputstring); nulls[0] = is_null; @@ -4289,30 +4729,35 @@ text_to_array_internal(PG_FUNCTION_ARGS) TEXTOID, -1, false, 'i')); } - start_posn = 1; - /* start_ptr points to the start_posn'th character of inputstring */ + text_position_setup(inputstring, fldsep, PG_GET_COLLATION(), &state); + start_ptr = VARDATA_ANY(inputstring); - for (fldnum = 1;; fldnum++) /* field number is 1 based */ + for (;;) { - CHECK_FOR_INTERRUPTS(); + bool found; + char *end_ptr; + int chunk_len; - end_posn = text_position_next(start_posn, &state); + CHECK_FOR_INTERRUPTS(); - if (end_posn == 0) + found = text_position_next(&state); + if (!found) { /* fetch last field */ chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr; + end_ptr = NULL; /* not used, but some compilers complain */ } else { /* fetch non-last field */ - chunk_len = charlen_to_bytelen(start_ptr, end_posn - start_posn); + end_ptr = text_position_get_match_ptr(&state); + chunk_len = end_ptr - start_ptr; } /* must build a temp text datum to pass to accumArrayResult */ result_text = cstring_to_text_with_len(start_ptr, chunk_len); - is_null = null_string ? text_isequal(result_text, null_string) : false; + is_null = null_string ? text_isequal(result_text, null_string, PG_GET_COLLATION()) : false; /* stash away this field */ astate = accumArrayResult(astate, @@ -4323,13 +4768,10 @@ text_to_array_internal(PG_FUNCTION_ARGS) pfree(result_text); - if (end_posn == 0) + if (!found) break; - start_posn = end_posn; - start_ptr += chunk_len; - start_posn += fldsep_len; - start_ptr += charlen_to_bytelen(start_ptr, fldsep_len); + start_ptr = end_ptr + fldsep_len; } text_position_cleanup(&state); @@ -4357,7 +4799,7 @@ text_to_array_internal(PG_FUNCTION_ARGS) /* must build a temp text datum to pass to accumArrayResult */ result_text = cstring_to_text_with_len(start_ptr, chunk_len); - is_null = null_string ? text_isequal(result_text, null_string) : false; + is_null = null_string ? text_isequal(result_text, null_string, PG_GET_COLLATION()) : false; /* stash away this field */ astate = accumArrayResult(astate, @@ -4879,17 +5321,21 @@ text_concat_ws(PG_FUNCTION_ARGS) Datum text_left(PG_FUNCTION_ARGS) { - text *str = PG_GETARG_TEXT_PP(0); - const char *p = VARDATA_ANY(str); - int len = VARSIZE_ANY_EXHDR(str); int n = PG_GETARG_INT32(1); - int rlen; if (n < 0) - n = pg_mbstrlen_with_len(p, len) + n; - rlen = pg_mbcharcliplen(p, len, n); + { + text *str = PG_GETARG_TEXT_PP(0); + const char *p = VARDATA_ANY(str); + int len = VARSIZE_ANY_EXHDR(str); + int rlen; - PG_RETURN_TEXT_P(cstring_to_text_with_len(p, rlen)); + n = pg_mbstrlen_with_len(p, len) + n; + rlen = pg_mbcharcliplen(p, len, n); + PG_RETURN_TEXT_P(cstring_to_text_with_len(p, rlen)); + } + else + PG_RETURN_TEXT_P(text_substring(PG_GETARG_DATUM(0), 1, n, false)); } /* @@ -5155,8 +5601,8 @@ text_format(PG_FUNCTION_ARGS) str = OutputFunctionCall(&typoutputinfo_width, value); - /* pg_atoi will complain about bad data or overflow */ - width = pg_atoi(str, sizeof(int), '\0'); + /* pg_strtoint32 will complain about bad data or overflow */ + width = pg_strtoint32(str); pfree(str); } diff --git a/src/backend/utils/adt/version.c b/src/backend/utils/adt/version.c index d57fd98ee06..2b484159a28 100644 --- a/src/backend/utils/adt/version.c +++ b/src/backend/utils/adt/version.c @@ -3,7 +3,7 @@ * version.c * Returns the PostgreSQL version string * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * IDENTIFICATION * diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c index 40ba783572a..aa177df017b 100644 --- a/src/backend/utils/adt/windowfuncs.c +++ b/src/backend/utils/adt/windowfuncs.c @@ -3,7 +3,7 @@ * windowfuncs.c * Standard window functions defined in SQL spec. * - * Portions Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -37,7 +37,7 @@ typedef struct static bool rank_up(WindowObject winobj); static Datum leadlag_common(FunctionCallInfo fcinfo, - bool forward, bool withoffset, bool withdefault); + bool forward, bool withoffset, bool withdefault); /* diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c index 1e811faa9c9..7853e418654 100644 --- a/src/backend/utils/adt/xid.c +++ b/src/backend/utils/adt/xid.c @@ -3,7 +3,7 @@ * xid.c * POSTGRES transaction identifier and command identifier datatypes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 7cdb87ef85b..0280c2625c6 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -4,7 +4,7 @@ * XML data type support. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/backend/utils/adt/xml.c @@ -68,6 +68,7 @@ #endif /* USE_LIBXML */ #include "access/htup_details.h" +#include "access/table.h" #include "catalog/namespace.h" #include "catalog/pg_class.h" #include "catalog/pg_type.h" @@ -117,10 +118,10 @@ struct PgXmlErrorContext }; static xmlParserInputPtr xmlPgEntityLoader(const char *URL, const char *ID, - xmlParserCtxtPtr ctxt); + xmlParserCtxtPtr ctxt); static void xml_errorHandler(void *data, xmlErrorPtr error); static void xml_ereport_by_code(int level, int sqlcode, - const char *msg, int errcode); + const char *msg, int errcode); static void chopStringInfoNewlines(StringInfo str); static void appendStringInfoLineSeparator(StringInfo str); @@ -136,40 +137,41 @@ static char *xml_pstrdup(const char *string); #endif /* USE_LIBXMLCONTEXT */ static xmlChar *xml_text2xmlChar(text *in); -static int parse_xml_decl(const xmlChar *str, size_t *lenp, - xmlChar **version, xmlChar **encoding, int *standalone); +static int parse_xml_decl(const xmlChar *str, size_t *lenp, + xmlChar **version, xmlChar **encoding, int *standalone); static bool print_xml_decl(StringInfo buf, const xmlChar *version, - pg_enc encoding, int standalone); + pg_enc encoding, int standalone); +static bool xml_doctype_in_content(const xmlChar *str); static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, - bool preserve_whitespace, int encoding); + bool preserve_whitespace, int encoding); static text *xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt); -static int xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj, - ArrayBuildState *astate, - PgXmlErrorContext *xmlerrcxt); +static int xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj, + ArrayBuildState *astate, + PgXmlErrorContext *xmlerrcxt); static xmlChar *pg_xmlCharStrndup(const char *str, size_t len); #endif /* USE_LIBXML */ static void xmldata_root_element_start(StringInfo result, const char *eltname, - const char *xmlschema, const char *targetns, - bool top_level); + const char *xmlschema, const char *targetns, + bool top_level); static void xmldata_root_element_end(StringInfo result, const char *eltname); static StringInfo query_to_xml_internal(const char *query, char *tablename, - const char *xmlschema, bool nulls, bool tableforest, - const char *targetns, bool top_level); + const char *xmlschema, bool nulls, bool tableforest, + const char *targetns, bool top_level); static const char *map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, - bool nulls, bool tableforest, const char *targetns); + bool nulls, bool tableforest, const char *targetns); static const char *map_sql_schema_to_xmlschema_types(Oid nspid, - List *relid_list, bool nulls, - bool tableforest, const char *targetns); + List *relid_list, bool nulls, + bool tableforest, const char *targetns); static const char *map_sql_catalog_to_xmlschema_types(List *nspid_list, - bool nulls, bool tableforest, - const char *targetns); + bool nulls, bool tableforest, + const char *targetns); static const char *map_sql_type_to_xml_name(Oid typeoid, int typmod); static const char *map_sql_typecoll_to_xmlschema_types(List *tupdesc_list); static const char *map_sql_type_to_xmlschema_type(Oid typeoid, int typmod); static void SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, - char *tablename, bool nulls, bool tableforest, - const char *targetns, bool top_level); + char *tablename, bool nulls, bool tableforest, + const char *targetns, bool top_level); /* XMLTABLE support */ #ifdef USE_LIBXML @@ -193,13 +195,13 @@ typedef struct XmlTableBuilderData static void XmlTableInitOpaque(struct TableFuncScanState *state, int natts); static void XmlTableSetDocument(struct TableFuncScanState *state, Datum value); static void XmlTableSetNamespace(struct TableFuncScanState *state, const char *name, - const char *uri); + const char *uri); static void XmlTableSetRowFilter(struct TableFuncScanState *state, const char *path); static void XmlTableSetColumnFilter(struct TableFuncScanState *state, - const char *path, int colnum); + const char *path, int colnum); static bool XmlTableFetchRow(struct TableFuncScanState *state); static Datum XmlTableGetValue(struct TableFuncScanState *state, int colnum, - Oid typid, int32 typmod, bool *isnull); + Oid typid, int32 typmod, bool *isnull); static void XmlTableDestroyOpaque(struct TableFuncScanState *state); const TableFuncRoutine XmlTableRoutine = @@ -557,7 +559,7 @@ xmlconcat(List *args) 0, global_standalone); - appendStringInfoString(&buf2, buf.data); + appendBinaryStringInfo(&buf2, buf.data, buf.len); buf = buf2; } @@ -1175,6 +1177,36 @@ pg_xmlCharStrndup(const char *str, size_t len) return result; } +/* + * Copy xmlChar string to PostgreSQL-owned memory, freeing the input. + * + * The input xmlChar is freed regardless of success of the copy. + */ +static char * +xml_pstrdup_and_free(xmlChar *str) +{ + char *result; + + if (str) + { + PG_TRY(); + { + result = pstrdup((char *) str); + } + PG_CATCH(); + { + xmlFree(str); + PG_RE_THROW(); + } + PG_END_TRY(); + xmlFree(str); + } + else + result = NULL; + + return result; +} + /* * str is the null-terminated input string. Remaining arguments are * output arguments; each can be NULL if value is not wanted. @@ -1212,8 +1244,15 @@ parse_xml_decl(const xmlChar *str, size_t *lenp, if (xmlStrncmp(p, (xmlChar *) " */ - utf8len = strlen((const char *) (p + 5)); + /* + * If next char is a name char, it's a PI like + * rather than an XMLDecl, so we have done what we came to do and found no + * XMLDecl. + * + * We need an input length value for xmlGetUTF8Char, but there's no need + * to count the whole document size, so use strnlen not strlen. + */ + utf8len = strnlen((const char *) (p + 5), MAX_MULTIBYTE_CHAR_LEN); utf8char = xmlGetUTF8Char(p + 5, &utf8len); if (PG_XMLISNAMECHAR(utf8char)) goto finished; @@ -1384,6 +1423,84 @@ print_xml_decl(StringInfo buf, const xmlChar *version, return false; } +/* + * Test whether an input that is to be parsed as CONTENT contains a DTD. + * + * The SQL/XML:2003 definition of CONTENT ("XMLDecl? content") is not + * satisfied by a document with a DTD, which is a bit of a wart, as it means + * the CONTENT type is not a proper superset of DOCUMENT. SQL/XML:2006 and + * later fix that, by redefining content with reference to the "more + * permissive" Document Node of the XQuery/XPath Data Model, such that any + * DOCUMENT value is indeed also a CONTENT value. That definition is more + * useful, as CONTENT becomes usable for parsing input of unknown form (think + * pg_restore). + * + * As used below in parse_xml when parsing for CONTENT, libxml does not give + * us the 2006+ behavior, but only the 2003; it will choke if the input has + * a DTD. But we can provide the 2006+ definition of CONTENT easily enough, + * by detecting this case first and simply doing the parse as DOCUMENT. + * + * A DTD can be found arbitrarily far in, but that would be a contrived case; + * it will ordinarily start within a few dozen characters. The only things + * that can precede it are an XMLDecl (here, the caller will have called + * parse_xml_decl already), whitespace, comments, and processing instructions. + * This function need only return true if it sees a valid sequence of such + * things leading to must follow */ + p = xmlStrstr(p + 2, (xmlChar *) "--"); + if (!p || p[2] != '>') + return false; + /* advance over comment, and keep scanning */ + p += 3; + continue; + } + + /* otherwise, if it's not a PI , fail */ + if (*p != '?') + return false; + p++; + + /* find end of PI (the string ?> is forbidden within a PI) */ + e = xmlStrstr(p, (xmlChar *) "?>"); + if (!e) + return false; + + /* advance over PI, keep scanning */ + p = e + 2; + } +} + /* * Convert a C string to XML internal representation @@ -1419,6 +1536,12 @@ xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, /* Use a TRY block to ensure we clean up correctly */ PG_TRY(); { + bool parse_as_document = false; + int res_code; + size_t count = 0; + xmlChar *version = NULL; + int standalone = 0; + xmlInitParser(); ctxt = xmlNewParserCtxt(); @@ -1426,7 +1549,25 @@ xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate parser context"); + /* Decide whether to parse as document or content */ if (xmloption_arg == XMLOPTION_DOCUMENT) + parse_as_document = true; + else + { + /* Parse and skip over the XML declaration, if any */ + res_code = parse_xml_decl(utf8string, + &count, &version, NULL, &standalone); + if (res_code != 0) + xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT, + "invalid XML content: invalid XML declaration", + res_code); + + /* Is there a DOCTYPE element? */ + if (xml_doctype_in_content(utf8string + count)) + parse_as_document = true; + } + + if (parse_as_document) { /* * Note, that here we try to apply DTD defaults @@ -1441,23 +1582,18 @@ xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, XML_PARSE_NOENT | XML_PARSE_DTDATTR | (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS)); if (doc == NULL || xmlerrcxt->err_occurred) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT, - "invalid XML document"); + { + /* Use original option to decide which error code to throw */ + if (xmloption_arg == XMLOPTION_DOCUMENT) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_DOCUMENT, + "invalid XML document"); + else + xml_ereport(xmlerrcxt, ERROR, ERRCODE_INVALID_XML_CONTENT, + "invalid XML content"); + } } else { - int res_code; - size_t count; - xmlChar *version; - int standalone; - - res_code = parse_xml_decl(utf8string, - &count, &version, NULL, &standalone); - if (res_code != 0) - xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT, - "invalid XML content: invalid XML declaration", - res_code); - doc = xmlNewDoc(version); Assert(doc->encoding == NULL); doc->encoding = xmlStrdup((const xmlChar *) "UTF-8"); @@ -1696,7 +1832,10 @@ xml_errorHandler(void *data, xmlErrorPtr error) appendStringInfo(errorBuf, "line %d: ", error->line); if (name != NULL) appendStringInfo(errorBuf, "element %s: ", name); - appendStringInfoString(errorBuf, error->message); + if (error->message != NULL) + appendStringInfoString(errorBuf, error->message); + else + appendStringInfoString(errorBuf, "(no message provided)"); /* * Append context information to errorBuf. @@ -1740,7 +1879,8 @@ xml_errorHandler(void *data, xmlErrorPtr error) if (xmlerrcxt->strictness == PG_XML_STRICTNESS_LEGACY) { appendStringInfoLineSeparator(&xmlerrcxt->err_buf); - appendStringInfoString(&xmlerrcxt->err_buf, errorBuf->data); + appendBinaryStringInfo(&xmlerrcxt->err_buf, errorBuf->data, + errorBuf->len); pfree(errorBuf->data); pfree(errorBuf); @@ -1758,7 +1898,8 @@ xml_errorHandler(void *data, xmlErrorPtr error) if (level >= XML_ERR_ERROR) { appendStringInfoLineSeparator(&xmlerrcxt->err_buf); - appendStringInfoString(&xmlerrcxt->err_buf, errorBuf->data); + appendBinaryStringInfo(&xmlerrcxt->err_buf, errorBuf->data, + errorBuf->len); xmlerrcxt->err_occurred = true; } @@ -2583,10 +2724,10 @@ table_to_xmlschema(PG_FUNCTION_ARGS) const char *result; Relation rel; - rel = heap_open(relid, AccessShareLock); + rel = table_open(relid, AccessShareLock); result = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls, tableforest, targetns); - heap_close(rel, NoLock); + table_close(rel, NoLock); PG_RETURN_XML_P(cstring_to_xmltype(result)); } @@ -2657,10 +2798,10 @@ table_to_xml_and_xmlschema(PG_FUNCTION_ARGS) Relation rel; const char *xmlschema; - rel = heap_open(relid, AccessShareLock); + rel = table_open(relid, AccessShareLock); xmlschema = map_sql_table_to_xmlschema(rel->rd_att, relid, nulls, tableforest, targetns); - heap_close(rel, NoLock); + table_close(rel, NoLock); PG_RETURN_XML_P(stringinfo_to_xmltype(table_to_xml_internal(relid, xmlschema, nulls, tableforest, @@ -2735,7 +2876,7 @@ schema_to_xml_internal(Oid nspid, const char *xmlschema, bool nulls, subres = table_to_xml_internal(relid, NULL, nulls, tableforest, targetns, false); - appendStringInfoString(result, subres->data); + appendBinaryStringInfo(result, subres->data, subres->len); appendStringInfoChar(result, '\n'); } @@ -2818,9 +2959,9 @@ schema_to_xmlschema_internal(const char *schemaname, bool nulls, { Relation rel; - rel = heap_open(lfirst_oid(cell), AccessShareLock); + rel = table_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); - heap_close(rel, NoLock); + table_close(rel, NoLock); } appendStringInfoString(result, @@ -2910,7 +3051,7 @@ database_to_xml_internal(const char *xmlschema, bool nulls, subres = schema_to_xml_internal(nspid, NULL, nulls, tableforest, targetns, false); - appendStringInfoString(result, subres->data); + appendBinaryStringInfo(result, subres->data, subres->len); appendStringInfoChar(result, '\n'); } @@ -2958,9 +3099,9 @@ database_to_xmlschema_internal(bool nulls, bool tableforest, { Relation rel; - rel = heap_open(lfirst_oid(cell), AccessShareLock); + rel = table_open(lfirst_oid(cell), AccessShareLock); tupdesc_list = lappend(tupdesc_list, CreateTupleDescCopy(rel->rd_att)); - heap_close(rel, NoLock); + table_close(rel, NoLock); } appendStringInfoString(result, @@ -3674,45 +3815,69 @@ SPI_sql_row_to_xmlelement(uint64 rownum, StringInfo result, char *tablename, #ifdef USE_LIBXML /* - * Convert XML node to text (dump subtree in case of element, - * return value otherwise) + * Convert XML node to text. + * + * For attribute and text nodes, return the escaped text. For anything else, + * dump the whole subtree. */ static text * xml_xmlnodetoxmltype(xmlNodePtr cur, PgXmlErrorContext *xmlerrcxt) { xmltype *result; - if (cur->type == XML_ELEMENT_NODE) + if (cur->type != XML_ATTRIBUTE_NODE && cur->type != XML_TEXT_NODE) { - xmlBufferPtr buf; - xmlNodePtr cur_copy; + void (*volatile nodefree) (xmlNodePtr) = NULL; + volatile xmlBufferPtr buf = NULL; + volatile xmlNodePtr cur_copy = NULL; - buf = xmlBufferCreate(); + PG_TRY(); + { + int bytes; - /* - * The result of xmlNodeDump() won't contain namespace definitions - * from parent nodes, but xmlCopyNode() duplicates a node along with - * its required namespace definitions. - */ - cur_copy = xmlCopyNode(cur, 1); + buf = xmlBufferCreate(); + if (buf == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not allocate xmlBuffer"); - if (cur_copy == NULL) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, - "could not copy node"); + /* + * Produce a dump of the node that we can serialize. xmlNodeDump + * does that, but the result of that function won't contain + * namespace definitions from ancestor nodes, so we first do a + * xmlCopyNode() which duplicates the node along with its required + * namespace definitions. + * + * Some old libxml2 versions such as 2.7.6 produce partially + * broken XML_DOCUMENT_NODE nodes (unset content field) when + * copying them. xmlNodeDump of such a node works fine, but + * xmlFreeNode crashes; set us up to call xmlFreeDoc instead. + */ + cur_copy = xmlCopyNode(cur, 1); + if (cur_copy == NULL || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + nodefree = (cur_copy->type == XML_DOCUMENT_NODE) ? + (void (*) (xmlNodePtr)) xmlFreeDoc : xmlFreeNode; + + bytes = xmlNodeDump(buf, NULL, cur_copy, 0, 0); + if (bytes == -1 || xmlerrcxt->err_occurred) + xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, + "could not dump node"); - PG_TRY(); - { - xmlNodeDump(buf, NULL, cur_copy, 0, 1); result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { - xmlFreeNode(cur_copy); - xmlBufferFree(buf); + if (nodefree) + nodefree(cur_copy); + if (buf) + xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY(); - xmlFreeNode(cur_copy); + + if (nodefree) + nodefree(cur_copy); xmlBufferFree(buf); } else @@ -3822,7 +3987,7 @@ xml_xpathobjtoxmlarray(xmlXPathObjectPtr xpathobj, /* * Common code for xpath() and xmlexists() * - * Evaluate XPath expression and return number of nodes in res_items + * Evaluate XPath expression and return number of nodes in res_nitems * and array of XML values in astate. Either of those pointers can be * NULL if the corresponding result isn't wanted. * @@ -3934,10 +4099,7 @@ xpath_internal(text *xpath_expr_text, xmltype *data, ArrayType *namespaces, if (xpathctx == NULL || xmlerrcxt->err_occurred) xml_ereport(xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate XPath context"); - xpathctx->node = xmlDocGetRootElement(doc); - if (xpathctx->node == NULL || xmlerrcxt->err_occurred) - xml_ereport(xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR, - "could not find root XML element"); + xpathctx->node = (xmlNodePtr) doc; /* register namespaces, if any */ if (ns_count > 0) @@ -4276,10 +4438,7 @@ XmlTableSetDocument(TableFuncScanState *state, Datum value) if (xpathcxt == NULL || xtCxt->xmlerrcxt->err_occurred) xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_OUT_OF_MEMORY, "could not allocate XPath context"); - xpathcxt->node = xmlDocGetRootElement(doc); - if (xpathcxt->node == NULL || xtCxt->xmlerrcxt->err_occurred) - xml_ereport(xtCxt->xmlerrcxt, ERROR, ERRCODE_INTERNAL_ERROR, - "could not find root XML element"); + xpathcxt->node = (xmlNodePtr) doc; } PG_CATCH(); { @@ -4481,9 +4640,9 @@ XmlTableGetValue(TableFuncScanState *state, int colnum, /* * There are four possible cases, depending on the number of nodes * returned by the XPath expression and the type of the target column: - * a) XPath returns no nodes. b) One node is returned, and column is - * of type XML. c) One node, column type other than XML. d) Multiple - * nodes are returned. + * a) XPath returns no nodes. b) The target type is XML (return all + * as XML). For non-XML return types: c) One node (return content). + * d) Multiple nodes (error). */ if (xpathobj->type == XPATH_NODESET) { @@ -4496,80 +4655,69 @@ XmlTableGetValue(TableFuncScanState *state, int colnum, { *isnull = true; } - else if (count == 1 && typid == XMLOID) - { - text *textstr; - - /* simple case, result is one value */ - textstr = xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[0], - xtCxt->xmlerrcxt); - cstr = text_to_cstring(textstr); - } - else if (count == 1) + else { - xmlChar *str; - - str = xmlNodeListGetString(xtCxt->doc, - xpathobj->nodesetval->nodeTab[0]->xmlChildrenNode, - 1); - - if (str != NULL) + if (typid == XMLOID) { - PG_TRY(); - { - cstr = pstrdup((char *) str); - } - PG_CATCH(); + text *textstr; + StringInfoData str; + + /* Concatenate serialized values */ + initStringInfo(&str); + for (int i = 0; i < count; i++) { - xmlFree(str); - PG_RE_THROW(); + textstr = + xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i], + xtCxt->xmlerrcxt); + + appendStringInfoText(&str, textstr); } - PG_END_TRY(); - xmlFree(str); + cstr = str.data; } else { - /* - * This line ensure mapping of empty tags to PostgreSQL - * value. Usually we would to map a empty tag to empty - * string. But this mapping can create empty string when - * user doesn't expect it - when empty tag is enforced by - * libxml2 - when user uses a text() function for example. - */ - cstr = ""; + xmlChar *str; + + if (count > 1) + ereport(ERROR, + (errcode(ERRCODE_CARDINALITY_VIOLATION), + errmsg("more than one value returned by column XPath expression"))); + + str = xmlXPathCastNodeSetToString(xpathobj->nodesetval); + cstr = str ? xml_pstrdup_and_free(str) : ""; } } + } + else if (xpathobj->type == XPATH_STRING) + { + /* Content should be escaped when target will be XML */ + if (typid == XMLOID) + cstr = escape_xml((char *) xpathobj->stringval); else - { - StringInfoData str; - int i; + cstr = (char *) xpathobj->stringval; + } + else if (xpathobj->type == XPATH_BOOLEAN) + { + char typcategory; + bool typispreferred; + xmlChar *str; - Assert(count > 1); + /* Allow implicit casting from boolean to numbers */ + get_type_category_preferred(typid, &typcategory, &typispreferred); - /* - * When evaluating the XPath expression returns multiple - * nodes, the result is the concatenation of them all. The - * target type must be XML. - */ - if (typid != XMLOID) - ereport(ERROR, - (errcode(ERRCODE_CARDINALITY_VIOLATION), - errmsg("more than one value returned by column XPath expression"))); + if (typcategory != TYPCATEGORY_NUMERIC) + str = xmlXPathCastBooleanToString(xpathobj->boolval); + else + str = xmlXPathCastNumberToString(xmlXPathCastBooleanToNumber(xpathobj->boolval)); - /* Concatenate serialized values */ - initStringInfo(&str); - for (i = 0; i < count; i++) - { - appendStringInfoText(&str, - xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i], - xtCxt->xmlerrcxt)); - } - cstr = str.data; - } + cstr = xml_pstrdup_and_free(str); } - else if (xpathobj->type == XPATH_STRING) + else if (xpathobj->type == XPATH_NUMBER) { - cstr = (char *) xpathobj->stringval; + xmlChar *str; + + str = xmlXPathCastNumberToString(xpathobj->floatval); + cstr = xml_pstrdup_and_free(str); } else elog(ERROR, "unexpected XPath object type %u", xpathobj->type); diff --git a/src/backend/utils/cache/Makefile b/src/backend/utils/cache/Makefile index a943f8ea4bc..e6a6b9f395f 100644 --- a/src/backend/utils/cache/Makefile +++ b/src/backend/utils/cache/Makefile @@ -12,8 +12,8 @@ subdir = src/backend/utils/cache top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = attoptcache.o catcache.o evtcache.o inval.o plancache.o relcache.o \ - relmapper.o relfilenodemap.o spccache.o syscache.o lsyscache.o \ - typcache.o ts_cache.o +OBJS = attoptcache.o catcache.o evtcache.o inval.o lsyscache.o \ + partcache.o plancache.o relcache.o relmapper.o relfilenodemap.o \ + spccache.o syscache.o ts_cache.o typcache.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/cache/attoptcache.c b/src/backend/utils/cache/attoptcache.c index 92468472a40..aac5a2471dd 100644 --- a/src/backend/utils/cache/attoptcache.c +++ b/src/backend/utils/cache/attoptcache.c @@ -6,7 +6,7 @@ * Attribute options are cached separately from the fixed-size portion of * pg_attribute entries, which are handled by the relcache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,7 +24,7 @@ #include "utils/syscache.h" -/* Hash table for informations about each attribute's options */ +/* Hash table for information about each attribute's options */ static HTAB *AttoptCacheHash = NULL; /* attrelid and attnum form the lookup key, and must appear first */ diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c index 5ddbf6eab10..c3e7d94aa5b 100644 --- a/src/backend/utils/cache/catcache.c +++ b/src/backend/utils/cache/catcache.c @@ -3,7 +3,7 @@ * catcache.c * System catalog cache for tuples matching a key. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,13 +15,13 @@ #include "postgres.h" #include "access/genam.h" -#include "access/hash.h" -#include "access/heapam.h" +#include "access/heaptoast.h" #include "access/relscan.h" #include "access/sysattr.h" -#include "access/tuptoaster.h" +#include "access/table.h" #include "access/valid.h" #include "access/xact.h" +#include "catalog/pg_collation.h" #include "catalog/pg_operator.h" #include "catalog/pg_type.h" #include "miscadmin.h" @@ -38,7 +38,6 @@ #include "utils/rel.h" #include "utils/resowner_private.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* #define CACHEDEBUG */ /* turns DEBUG elogs on */ @@ -56,43 +55,33 @@ */ #ifdef CACHEDEBUG -#define CACHE1_elog(a,b) elog(a,b) -#define CACHE2_elog(a,b,c) elog(a,b,c) -#define CACHE3_elog(a,b,c,d) elog(a,b,c,d) -#define CACHE4_elog(a,b,c,d,e) elog(a,b,c,d,e) -#define CACHE5_elog(a,b,c,d,e,f) elog(a,b,c,d,e,f) -#define CACHE6_elog(a,b,c,d,e,f,g) elog(a,b,c,d,e,f,g) +#define CACHE_elog(...) elog(__VA_ARGS__) #else -#define CACHE1_elog(a,b) -#define CACHE2_elog(a,b,c) -#define CACHE3_elog(a,b,c,d) -#define CACHE4_elog(a,b,c,d,e) -#define CACHE5_elog(a,b,c,d,e,f) -#define CACHE6_elog(a,b,c,d,e,f,g) +#define CACHE_elog(...) #endif /* Cache management header --- pointer is NULL until created */ static CatCacheHeader *CacheHdr = NULL; static inline HeapTuple SearchCatCacheInternal(CatCache *cache, - int nkeys, - Datum v1, Datum v2, - Datum v3, Datum v4); + int nkeys, + Datum v1, Datum v2, + Datum v3, Datum v4); static pg_noinline HeapTuple SearchCatCacheMiss(CatCache *cache, - int nkeys, - uint32 hashValue, - Index hashIndex, - Datum v1, Datum v2, - Datum v3, Datum v4); + int nkeys, + uint32 hashValue, + Index hashIndex, + Datum v1, Datum v2, + Datum v3, Datum v4); static uint32 CatalogCacheComputeHashValue(CatCache *cache, int nkeys, - Datum v1, Datum v2, Datum v3, Datum v4); + Datum v1, Datum v2, Datum v3, Datum v4); static uint32 CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, - HeapTuple tuple); + HeapTuple tuple); static inline bool CatalogCacheCompareTuple(const CatCache *cache, int nkeys, - const Datum *cachekeys, - const Datum *searchkeys); + const Datum *cachekeys, + const Datum *searchkeys); #ifdef CATCACHE_STATS static void CatCachePrintStats(int code, Datum arg); @@ -101,14 +90,14 @@ static void CatCacheRemoveCTup(CatCache *cache, CatCTup *ct); static void CatCacheRemoveCList(CatCache *cache, CatCList *cl); static void CatalogCacheInitializeCache(CatCache *cache); static CatCTup *CatalogCacheCreateEntry(CatCache *cache, HeapTuple ntp, - Datum *arguments, - uint32 hashValue, Index hashIndex, - bool negative); + Datum *arguments, + uint32 hashValue, Index hashIndex, + bool negative); static void CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, - Datum *keys); + Datum *keys); static void CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, - Datum *srckeys, Datum *dstkeys); + Datum *srckeys, Datum *dstkeys); /* @@ -181,13 +170,18 @@ int4hashfast(Datum datum) static bool texteqfast(Datum a, Datum b) { - return DatumGetBool(DirectFunctionCall2(texteq, a, b)); + /* + * The use of DEFAULT_COLLATION_OID is fairly arbitrary here. We just + * want to take the fast "deterministic" path in texteq(). + */ + return DatumGetBool(DirectFunctionCall2Coll(texteq, DEFAULT_COLLATION_OID, a, b)); } static uint32 texthashfast(Datum datum) { - return DatumGetInt32(DirectFunctionCall1(hashtext, datum)); + /* analogously here as in texteqfast() */ + return DatumGetInt32(DirectFunctionCall1Coll(hashtext, DEFAULT_COLLATION_OID, datum)); } static bool @@ -280,10 +274,8 @@ CatalogCacheComputeHashValue(CatCache *cache, int nkeys, uint32 oneHash; CCHashFN *cc_hashfunc = cache->cc_hashfunc; - CACHE4_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p", - cache->cc_relname, - nkeys, - cache); + CACHE_elog(DEBUG2, "CatalogCacheComputeHashValue %s %d %p", + cache->cc_relname, nkeys, cache); switch (nkeys) { @@ -338,39 +330,31 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple) switch (nkeys) { case 4: - v4 = (cc_keyno[3] == ObjectIdAttributeNumber) - ? ObjectIdGetDatum(HeapTupleGetOid(tuple)) - : fastgetattr(tuple, - cc_keyno[3], - cc_tupdesc, - &isNull); + v4 = fastgetattr(tuple, + cc_keyno[3], + cc_tupdesc, + &isNull); Assert(!isNull); /* FALLTHROUGH */ case 3: - v3 = (cc_keyno[2] == ObjectIdAttributeNumber) - ? ObjectIdGetDatum(HeapTupleGetOid(tuple)) - : fastgetattr(tuple, - cc_keyno[2], - cc_tupdesc, - &isNull); + v3 = fastgetattr(tuple, + cc_keyno[2], + cc_tupdesc, + &isNull); Assert(!isNull); /* FALLTHROUGH */ case 2: - v2 = (cc_keyno[1] == ObjectIdAttributeNumber) - ? ObjectIdGetDatum(HeapTupleGetOid(tuple)) - : fastgetattr(tuple, - cc_keyno[1], - cc_tupdesc, - &isNull); + v2 = fastgetattr(tuple, + cc_keyno[1], + cc_tupdesc, + &isNull); Assert(!isNull); /* FALLTHROUGH */ case 1: - v1 = (cc_keyno[0] == ObjectIdAttributeNumber) - ? ObjectIdGetDatum(HeapTupleGetOid(tuple)) - : fastgetattr(tuple, - cc_keyno[0], - cc_tupdesc, - &isNull); + v1 = fastgetattr(tuple, + cc_keyno[0], + cc_tupdesc, + &isNull); Assert(!isNull); break; default: @@ -570,7 +554,7 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue) Index hashIndex; dlist_mutable_iter iter; - CACHE1_elog(DEBUG2, "CatCacheInvalidate: called"); + CACHE_elog(DEBUG2, "CatCacheInvalidate: called"); /* * We don't bother to check whether the cache has finished initialization @@ -610,7 +594,7 @@ CatCacheInvalidate(CatCache *cache, uint32 hashValue) } else CatCacheRemoveCTup(cache, ct); - CACHE1_elog(DEBUG2, "CatCacheInvalidate: invalidated"); + CACHE_elog(DEBUG2, "CatCacheInvalidate: invalidated"); #ifdef CATCACHE_STATS cache->cc_invals++; #endif @@ -706,7 +690,7 @@ ResetCatalogCaches(void) { slist_iter iter; - CACHE1_elog(DEBUG2, "ResetCatalogCaches called"); + CACHE_elog(DEBUG2, "ResetCatalogCaches called"); slist_foreach(iter, &CacheHdr->ch_caches) { @@ -715,7 +699,7 @@ ResetCatalogCaches(void) ResetCatalogCache(cache); } - CACHE1_elog(DEBUG2, "end of ResetCatalogCaches call"); + CACHE_elog(DEBUG2, "end of ResetCatalogCaches call"); } /* @@ -736,7 +720,7 @@ CatalogCacheFlushCatalog(Oid catId) { slist_iter iter; - CACHE2_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId); + CACHE_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId); slist_foreach(iter, &CacheHdr->ch_caches) { @@ -753,7 +737,7 @@ CatalogCacheFlushCatalog(Oid catId) } } - CACHE1_elog(DEBUG2, "end of CatalogCacheFlushCatalog call"); + CACHE_elog(DEBUG2, "end of CatalogCacheFlushCatalog call"); } /* @@ -945,7 +929,7 @@ CatalogCacheInitializeCache(CatCache *cache) CatalogCacheInitializeCache_DEBUG1; - relation = heap_open(cache->cc_reloid, AccessShareLock); + relation = table_open(cache->cc_reloid, AccessShareLock); /* * switch to the cache context so our allocations do not vanish at the end @@ -972,10 +956,10 @@ CatalogCacheInitializeCache(CatCache *cache) */ MemoryContextSwitchTo(oldcxt); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); - CACHE3_elog(DEBUG2, "CatalogCacheInitializeCache: %s, %d keys", - cache->cc_relname, cache->cc_nkeys); + CACHE_elog(DEBUG2, "CatalogCacheInitializeCache: %s, %d keys", + cache->cc_relname, cache->cc_nkeys); /* * initialize cache's key information @@ -998,8 +982,8 @@ CatalogCacheInitializeCache(CatCache *cache) } else { - if (cache->cc_keyno[i] != ObjectIdAttributeNumber) - elog(FATAL, "only sys attr supported in caches is OID"); + if (cache->cc_keyno[i] < 0) + elog(FATAL, "sys attributes are not supported in caches"); keytype = OIDOID; } @@ -1022,13 +1006,11 @@ CatalogCacheInitializeCache(CatCache *cache) /* Fill in sk_strategy as well --- always standard equality */ cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber; cache->cc_skey[i].sk_subtype = InvalidOid; - /* Currently, there are no catcaches on collation-aware data types */ - cache->cc_skey[i].sk_collation = InvalidOid; + /* If a catcache key requires a collation, it must be C collation */ + cache->cc_skey[i].sk_collation = C_COLLATION_OID; - CACHE4_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p", - cache->cc_relname, - i, - cache); + CACHE_elog(DEBUG2, "CatalogCacheInitializeCache %s %d %p", + cache->cc_relname, i, cache); } /* @@ -1292,8 +1274,8 @@ SearchCatCacheInternal(CatCache *cache, ct->refcount++; ResourceOwnerRememberCatCacheRef(CurrentResourceOwner, &ct->tuple); - CACHE3_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d", - cache->cc_relname, hashIndex); + CACHE_elog(DEBUG2, "SearchCatCache(%s): found in bucket %d", + cache->cc_relname, hashIndex); #ifdef CATCACHE_STATS cache->cc_hits++; @@ -1303,8 +1285,8 @@ SearchCatCacheInternal(CatCache *cache, } else { - CACHE3_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d", - cache->cc_relname, hashIndex); + CACHE_elog(DEBUG2, "SearchCatCache(%s): found neg entry in bucket %d", + cache->cc_relname, hashIndex); #ifdef CATCACHE_STATS cache->cc_neg_hits++; @@ -1364,7 +1346,7 @@ SearchCatCacheMiss(CatCache *cache, * * NOTE: it is possible for recursive cache lookups to occur while reading * the relation --- for example, due to shared-cache-inval messages being - * processed during heap_open(). This is OK. It's even possible for one + * processed during table_open(). This is OK. It's even possible for one * of those lookups to find and enter the very same tuple we are trying to * fetch here. If that happens, we will enter a second copy of the tuple * into the cache. The first copy will never be referenced again, and @@ -1372,7 +1354,7 @@ SearchCatCacheMiss(CatCache *cache, * This case is rare enough that it's not worth expending extra cycles to * detect. */ - relation = heap_open(cache->cc_reloid, AccessShareLock); + relation = table_open(cache->cc_reloid, AccessShareLock); scandesc = systable_beginscan(relation, cache->cc_indexoid, @@ -1397,7 +1379,7 @@ SearchCatCacheMiss(CatCache *cache, systable_endscan(scandesc); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* * If tuple was not found, we need to build a negative cache entry @@ -1418,10 +1400,10 @@ SearchCatCacheMiss(CatCache *cache, hashValue, hashIndex, true); - CACHE4_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples", - cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup); - CACHE3_elog(DEBUG2, "SearchCatCache(%s): put neg entry in bucket %d", - cache->cc_relname, hashIndex); + CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples", + cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup); + CACHE_elog(DEBUG2, "SearchCatCache(%s): put neg entry in bucket %d", + cache->cc_relname, hashIndex); /* * We are not returning the negative entry to the caller, so leave its @@ -1431,10 +1413,10 @@ SearchCatCacheMiss(CatCache *cache, return NULL; } - CACHE4_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples", - cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup); - CACHE3_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d", - cache->cc_relname, hashIndex); + CACHE_elog(DEBUG2, "SearchCatCache(%s): Contains %d/%d tuples", + cache->cc_relname, cache->cc_ntup, CacheHdr->ch_ntup); + CACHE_elog(DEBUG2, "SearchCatCache(%s): put in bucket %d", + cache->cc_relname, hashIndex); #ifdef CATCACHE_STATS cache->cc_newloads++; @@ -1605,8 +1587,8 @@ SearchCatCacheList(CatCache *cache, cl->refcount++; ResourceOwnerRememberCatCacheListRef(CurrentResourceOwner, cl); - CACHE2_elog(DEBUG2, "SearchCatCacheList(%s): found list", - cache->cc_relname); + CACHE_elog(DEBUG2, "SearchCatCacheList(%s): found list", + cache->cc_relname); #ifdef CATCACHE_STATS cache->cc_lhits++; @@ -1645,7 +1627,7 @@ SearchCatCacheList(CatCache *cache, cur_skey[2].sk_argument = v3; cur_skey[3].sk_argument = v4; - relation = heap_open(cache->cc_reloid, AccessShareLock); + relation = table_open(cache->cc_reloid, AccessShareLock); scandesc = systable_beginscan(relation, cache->cc_indexoid, @@ -1712,7 +1694,7 @@ SearchCatCacheList(CatCache *cache, systable_endscan(scandesc); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* Now we can build the CatCList entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); @@ -1785,8 +1767,8 @@ SearchCatCacheList(CatCache *cache, cl->refcount++; ResourceOwnerRememberCatCacheListRef(CurrentResourceOwner, cl); - CACHE3_elog(DEBUG2, "SearchCatCacheList(%s): made list of %d members", - cache->cc_relname, nmembers); + CACHE_elog(DEBUG2, "SearchCatCacheList(%s): made list of %d members", + cache->cc_relname, nmembers); return cl; } @@ -1935,9 +1917,7 @@ CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys) int attnum = attnos[i]; Form_pg_attribute att; - /* only valid system attribute is the oid, which is by value */ - if (attnum == ObjectIdAttributeNumber) - continue; + /* system attribute are not supported in caches */ Assert(attnum > 0); att = TupleDescAttr(tupdesc, attnum - 1); @@ -1966,33 +1946,25 @@ CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos, for (i = 0; i < nkeys; i++) { int attnum = attnos[i]; + Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1); + Datum src = srckeys[i]; + NameData srcname; - if (attnum == ObjectIdAttributeNumber) + /* + * Must be careful in case the caller passed a C string where a NAME + * is wanted: convert the given argument to a correctly padded NAME. + * Otherwise the memcpy() done by datumCopy() could fall off the end + * of memory. + */ + if (att->atttypid == NAMEOID) { - dstkeys[i] = srckeys[i]; + namestrcpy(&srcname, DatumGetCString(src)); + src = NameGetDatum(&srcname); } - else - { - Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1); - Datum src = srckeys[i]; - NameData srcname; - /* - * Must be careful in case the caller passed a C string where a - * NAME is wanted: convert the given argument to a correctly - * padded NAME. Otherwise the memcpy() done by datumCopy() could - * fall off the end of memory. - */ - if (att->atttypid == NAMEOID) - { - namestrcpy(&srcname, DatumGetCString(src)); - src = NameGetDatum(&srcname); - } - - dstkeys[i] = datumCopy(src, - att->attbyval, - att->attlen); - } + dstkeys[i] = datumCopy(src, + att->attbyval, + att->attlen); } } @@ -2040,7 +2012,7 @@ PrepareToInvalidateCacheTuple(Relation relation, slist_iter iter; Oid reloid; - CACHE1_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called"); + CACHE_elog(DEBUG2, "PrepareToInvalidateCacheTuple: called"); /* * sanity checks diff --git a/src/backend/utils/cache/evtcache.c b/src/backend/utils/cache/evtcache.c index 7c014d6092c..419bde567bd 100644 --- a/src/backend/utils/cache/evtcache.c +++ b/src/backend/utils/cache/evtcache.c @@ -3,7 +3,7 @@ * evtcache.c * Special-purpose cache for event trigger data. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,8 +14,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/relation.h" #include "catalog/pg_event_trigger.h" #include "catalog/indexing.h" #include "catalog/pg_type.h" @@ -50,7 +50,7 @@ static EventTriggerCacheStateType EventTriggerCacheState = ETCS_NEEDS_REBUILD; static void BuildEventTriggerCache(void); static void InvalidateEventCacheCallback(Datum arg, - int cacheid, uint32 hashvalue); + int cacheid, uint32 hashvalue); static int DecodeTextArrayToCString(Datum array, char ***cstringp); /* diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c index 955f5c7fdc5..f09e3a9affa 100644 --- a/src/backend/utils/cache/inval.c +++ b/src/backend/utils/cache/inval.c @@ -5,12 +5,12 @@ * * This is subtle stuff, so pay attention: * - * When a tuple is updated or deleted, our standard time qualification rules + * When a tuple is updated or deleted, our standard visibility rules * consider that it is *still valid* so long as we are in the same command, * ie, until the next CommandCounterIncrement() or transaction commit. - * (See utils/time/tqual.c, and note that system catalogs are generally - * scanned under the most current snapshot available, rather than the - * transaction snapshot.) At the command boundary, the old tuple stops + * (See access/heap/heapam_visibility.c, and note that system catalogs are + * generally scanned under the most current snapshot available, rather than + * the transaction snapshot.) At the command boundary, the old tuple stops * being valid and the new version, if any, becomes valid. Therefore, * we cannot simply flush a tuple from the system caches during heap_update() * or heap_delete(). The tuple is still good at that point; what's more, @@ -54,6 +54,7 @@ * Also, whenever we see an operation on a pg_class, pg_attribute, or * pg_index tuple, we register a relcache flush operation for the relation * described by that tuple (as specified in CacheInvalidateHeapTuple()). + * Likewise for pg_constraint tuples for foreign keys on relations. * * We keep the relcache flush requests in lists separate from the catcache * tuple flush requests. This allows us to issue all the pending catcache @@ -85,7 +86,7 @@ * problems can be overcome cheaply. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -100,6 +101,7 @@ #include "access/htup_details.h" #include "access/xact.h" #include "catalog/catalog.h" +#include "catalog/pg_constraint.h" #include "miscadmin.h" #include "storage/sinval.h" #include "storage/smgr.h" @@ -521,12 +523,12 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId) (void) GetCurrentCommandId(true); /* - * If the relation being invalidated is one of those cached in the local - * relcache init file, mark that we need to zap that file at commit. Same - * is true when we are invalidating whole relcache. + * If the relation being invalidated is one of those cached in a relcache + * init file, mark that we need to zap that file at commit. For simplicity + * invalidations for a specific database always invalidate the shared file + * as well. Also zap when we are invalidating whole relcache. */ - if (OidIsValid(dbId) && - (RelationIdIsInInitFile(relId) || relId == InvalidOid)) + if (relId == InvalidOid || RelationIdIsInInitFile(relId)) transInvalInfo->RelcacheInitFileInval = true; } @@ -708,7 +710,17 @@ AcceptInvalidationMessages(void) } } #elif defined(CLOBBER_CACHE_RECURSIVELY) - InvalidateSystemCaches(); + { + static int recursion_depth = 0; + + /* Maximum depth is arbitrary depending on your threshold of pain */ + if (recursion_depth < 3) + { + recursion_depth++; + InvalidateSystemCaches(); + recursion_depth--; + } + } #endif } @@ -881,18 +893,26 @@ ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, if (RelcacheInitFileInval) { + elog(trace_recovery(DEBUG4), "removing relcache init files for database %u", + dbid); + /* - * RelationCacheInitFilePreInvalidate requires DatabasePath to be set, - * but we should not use SetDatabasePath during recovery, since it is + * RelationCacheInitFilePreInvalidate, when the invalidation message + * is for a specific database, requires DatabasePath to be set, but we + * should not use SetDatabasePath during recovery, since it is * intended to be used only once by normal backends. Hence, a quick * hack: set DatabasePath directly then unset after use. */ - DatabasePath = GetDatabasePath(dbid, tsid); - elog(trace_recovery(DEBUG4), "removing relcache init file in \"%s\"", - DatabasePath); + if (OidIsValid(dbid)) + DatabasePath = GetDatabasePath(dbid, tsid); + RelationCacheInitFilePreInvalidate(); - pfree(DatabasePath); - DatabasePath = NULL; + + if (OidIsValid(dbid)) + { + pfree(DatabasePath); + DatabasePath = NULL; + } } SendSharedInvalidMessages(msgs, nmsgs); @@ -1148,7 +1168,7 @@ CacheInvalidateHeapTuple(Relation relation, { Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple); - relationId = HeapTupleGetOid(tuple); + relationId = classtup->oid; if (classtup->relisshared) databaseId = InvalidOid; else @@ -1185,6 +1205,23 @@ CacheInvalidateHeapTuple(Relation relation, relationId = indextup->indexrelid; databaseId = MyDatabaseId; } + else if (tupleRelId == ConstraintRelationId) + { + Form_pg_constraint constrtup = (Form_pg_constraint) GETSTRUCT(tuple); + + /* + * Foreign keys are part of relcache entries, too, so send out an + * inval for the table that the FK applies to. + */ + if (constrtup->contype == CONSTRAINT_FOREIGN && + OidIsValid(constrtup->conrelid)) + { + relationId = constrtup->conrelid; + databaseId = MyDatabaseId; + } + else + return; + } else return; @@ -1274,7 +1311,7 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple) PrepareInvalidationState(); - relationId = HeapTupleGetOid(classTuple); + relationId = classtup->oid; if (classtup->relisshared) databaseId = InvalidOid; else diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c index bba595ad1da..27602fa49c6 100644 --- a/src/backend/utils/cache/lsyscache.c +++ b/src/backend/utils/cache/lsyscache.c @@ -3,7 +3,7 @@ * lsyscache.c * Convenience routines for common queries in the system catalog cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -822,35 +822,33 @@ get_attnum(Oid relid, const char *attname) } /* - * get_attidentity + * get_attgenerated * * Given the relation id and the attribute name, - * return the "attidentity" field from the attribute relation. + * return the "attgenerated" field from the attribute relation. * - * Returns '\0' if not found. + * Errors if not found. * - * Since no identity is represented by '\0', this can also be used as a + * Since not generated is represented by '\0', this can also be used as a * Boolean test. */ char -get_attidentity(Oid relid, AttrNumber attnum) +get_attgenerated(Oid relid, AttrNumber attnum) { HeapTuple tp; + Form_pg_attribute att_tup; + char result; tp = SearchSysCache2(ATTNUM, ObjectIdGetDatum(relid), Int16GetDatum(attnum)); - if (HeapTupleIsValid(tp)) - { - Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); - char result; - - result = att_tup->attidentity; - ReleaseSysCache(tp); - return result; - } - else - return '\0'; + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for attribute %d of relation %u", + attnum, relid); + att_tup = (Form_pg_attribute) GETSTRUCT(tp); + result = att_tup->attgenerated; + ReleaseSysCache(tp); + return result; } /* @@ -880,40 +878,13 @@ get_atttype(Oid relid, AttrNumber attnum) return InvalidOid; } -/* - * get_atttypmod - * - * Given the relation id and the attribute number, - * return the "atttypmod" field from the attribute relation. - */ -int32 -get_atttypmod(Oid relid, AttrNumber attnum) -{ - HeapTuple tp; - - tp = SearchSysCache2(ATTNUM, - ObjectIdGetDatum(relid), - Int16GetDatum(attnum)); - if (HeapTupleIsValid(tp)) - { - Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp); - int32 result; - - result = att_tup->atttypmod; - ReleaseSysCache(tp); - return result; - } - else - return -1; -} - /* * get_atttypetypmodcoll * * A three-fer: given the relation id and the attribute number, * fetch atttypid, atttypmod, and attcollation in a single cache lookup. * - * Unlike the otherwise-similar get_atttype/get_atttypmod, this routine + * Unlike the otherwise-similar get_atttype, this routine * raises an error if it can't obtain the information. */ void @@ -967,6 +938,22 @@ get_collation_name(Oid colloid) return NULL; } +bool +get_collation_isdeterministic(Oid colloid) +{ + HeapTuple tp; + Form_pg_collation colltup; + bool result; + + tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid)); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for collation %u", colloid); + colltup = (Form_pg_collation) GETSTRUCT(tp); + result = colltup->collisdeterministic; + ReleaseSysCache(tp); + return result; +} + /* ---------- CONSTRAINT CACHE ---------- */ /* @@ -1067,6 +1054,32 @@ get_opclass_input_type(Oid opclass) return result; } +/* + * get_opclass_opfamily_and_input_type + * + * Returns the OID of the operator family the opclass belongs to, + * the OID of the datatype the opclass indexes + */ +bool +get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype) +{ + HeapTuple tp; + Form_pg_opclass cla_tup; + + tp = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass)); + if (!HeapTupleIsValid(tp)) + return false; + + cla_tup = (Form_pg_opclass) GETSTRUCT(tp); + + *opfamily = cla_tup->opcfamily; + *opcintype = cla_tup->opcintype; + + ReleaseSysCache(tp); + + return true; +} + /* ---------- OPERATOR CACHE ---------- */ /* @@ -1638,41 +1651,28 @@ get_func_leakproof(Oid funcid) } /* - * get_func_cost - * Given procedure id, return the function's procost field. - */ -float4 -get_func_cost(Oid funcid) -{ - HeapTuple tp; - float4 result; - - tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for function %u", funcid); - - result = ((Form_pg_proc) GETSTRUCT(tp))->procost; - ReleaseSysCache(tp); - return result; -} - -/* - * get_func_rows - * Given procedure id, return the function's prorows field. + * get_func_support + * + * Returns the support function OID associated with a given function, + * or InvalidOid if there is none. */ -float4 -get_func_rows(Oid funcid) +RegProcedure +get_func_support(Oid funcid) { HeapTuple tp; - float4 result; tp = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for function %u", funcid); + if (HeapTupleIsValid(tp)) + { + Form_pg_proc functup = (Form_pg_proc) GETSTRUCT(tp); + RegProcedure result; - result = ((Form_pg_proc) GETSTRUCT(tp))->prorows; - ReleaseSysCache(tp); - return result; + result = functup->prosupport; + ReleaseSysCache(tp); + return result; + } + else + return (RegProcedure) InvalidOid; } /* ---------- RELATION CACHE ---------- */ @@ -1686,7 +1686,7 @@ get_func_rows(Oid funcid) Oid get_relname_relid(const char *relname, Oid relnamespace) { - return GetSysCacheOid2(RELNAMENSP, + return GetSysCacheOid2(RELNAMENSP, Anum_pg_class_oid, PointerGetDatum(relname), ObjectIdGetDatum(relnamespace)); } @@ -1820,6 +1820,30 @@ get_rel_relkind(Oid relid) return '\0'; } +/* + * get_rel_relispartition + * + * Returns the relispartition flag associated with a given relation. + */ +bool +get_rel_relispartition(Oid relid) +{ + HeapTuple tp; + + tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid)); + if (HeapTupleIsValid(tp)) + { + Form_pg_class reltup = (Form_pg_class) GETSTRUCT(tp); + bool result; + + result = reltup->relispartition; + ReleaseSysCache(tp); + return result; + } + else + return false; +} + /* * get_rel_tablespace * @@ -2065,7 +2089,7 @@ getTypeIOParam(HeapTuple typeTuple) if (OidIsValid(typeStruct->typelem)) return typeStruct->typelem; else - return HeapTupleGetOid(typeTuple); + return typeStruct->oid; } /* @@ -2890,6 +2914,7 @@ get_attavgwidth(Oid relid, AttrNumber attnum) * * If a matching slot is found, true is returned, and *sslot is filled thus: * staop: receives the actual STAOP value. + * stacoll: receives the actual STACOLL value. * valuetype: receives actual datatype of the elements of stavalues. * values: receives pointer to an array of the slot's stavalues. * nvalues: receives number of stavalues. @@ -2902,6 +2927,10 @@ get_attavgwidth(Oid relid, AttrNumber attnum) * * If no matching slot is found, false is returned, and *sslot is zeroed. * + * Note that the current API doesn't allow for searching for a slot with + * a particular collation. If we ever actually support recording more than + * one collation, we'll have to extend the API, but for now simple is good. + * * The data referred to by the fields of sslot is locally palloc'd and * is independent of the original pg_statistic tuple. When the caller * is done with it, call free_attstatsslot to release the palloc'd data. @@ -2936,6 +2965,20 @@ get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, return false; /* not there */ sslot->staop = (&stats->staop1)[i]; + sslot->stacoll = (&stats->stacoll1)[i]; + + /* + * XXX Hopefully-temporary hack: if stacoll isn't set, inject the default + * collation. This won't matter for non-collation-aware datatypes. For + * those that are, this covers cases where stacoll has not been set. In + * the short term we need this because some code paths involving type NAME + * do not pass any collation to prefix_selectivity and related functions. + * Even when that's been fixed, it's likely that some add-on typanalyze + * functions won't get the word right away about filling stacoll during + * ANALYZE, so we'll probably need this for awhile. + */ + if (sslot->stacoll == InvalidOid) + sslot->stacoll = DEFAULT_COLLATION_OID; if (flags & ATTSTATSSLOT_VALUES) { @@ -3106,3 +3149,55 @@ get_range_subtype(Oid rangeOid) else return InvalidOid; } + +/* ---------- PG_INDEX CACHE ---------- */ + +/* + * get_index_column_opclass + * + * Given the index OID and column number, + * return opclass of the index column + * or InvalidOid if the index was not found + * or column is non-key one. + */ +Oid +get_index_column_opclass(Oid index_oid, int attno) +{ + HeapTuple tuple; + Form_pg_index rd_index PG_USED_FOR_ASSERTS_ONLY; + Datum datum; + bool isnull; + oidvector *indclass; + Oid opclass; + + /* First we need to know the column's opclass. */ + + tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(index_oid)); + if (!HeapTupleIsValid(tuple)) + return InvalidOid; + + rd_index = (Form_pg_index) GETSTRUCT(tuple); + + /* caller is supposed to guarantee this */ + Assert(attno > 0 && attno <= rd_index->indnatts); + + /* Non-key attributes don't have an opclass */ + if (attno > rd_index->indnkeyatts) + { + ReleaseSysCache(tuple); + return InvalidOid; + } + + datum = SysCacheGetAttr(INDEXRELID, tuple, + Anum_pg_index_indclass, &isnull); + Assert(!isnull); + + indclass = ((oidvector *) DatumGetPointer(datum)); + + Assert(attno <= indclass->dim1); + opclass = indclass->values[attno - 1]; + + ReleaseSysCache(tuple); + + return opclass; +} diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c new file mode 100644 index 00000000000..342ab4dbaa6 --- /dev/null +++ b/src/backend/utils/cache/partcache.c @@ -0,0 +1,409 @@ +/*------------------------------------------------------------------------- + * + * partcache.c + * Support routines for manipulating partition information cached in + * relcache + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/utils/cache/partcache.c + * + *------------------------------------------------------------------------- +*/ +#include "postgres.h" + +#include "access/hash.h" +#include "access/htup_details.h" +#include "access/nbtree.h" +#include "access/relation.h" +#include "catalog/partition.h" +#include "catalog/pg_inherits.h" +#include "catalog/pg_opclass.h" +#include "catalog/pg_partitioned_table.h" +#include "miscadmin.h" +#include "nodes/makefuncs.h" +#include "nodes/nodeFuncs.h" +#include "optimizer/optimizer.h" +#include "partitioning/partbounds.h" +#include "rewrite/rewriteHandler.h" +#include "utils/builtins.h" +#include "utils/datum.h" +#include "utils/lsyscache.h" +#include "utils/memutils.h" +#include "utils/partcache.h" +#include "utils/rel.h" +#include "utils/syscache.h" + + +static List *generate_partition_qual(Relation rel); + +/* + * RelationBuildPartitionKey + * Build partition key data of relation, and attach to relcache + * + * Partitioning key data is a complex structure; to avoid complicated logic to + * free individual elements whenever the relcache entry is flushed, we give it + * its own memory context, a child of CacheMemoryContext, which can easily be + * deleted on its own. To avoid leaking memory in that context in case of an + * error partway through this function, the context is initially created as a + * child of CurTransactionContext and only re-parented to CacheMemoryContext + * at the end, when no further errors are possible. Also, we don't make this + * context the current context except in very brief code sections, out of fear + * that some of our callees allocate memory on their own which would be leaked + * permanently. + */ +void +RelationBuildPartitionKey(Relation relation) +{ + Form_pg_partitioned_table form; + HeapTuple tuple; + bool isnull; + int i; + PartitionKey key; + AttrNumber *attrs; + oidvector *opclass; + oidvector *collation; + ListCell *partexprs_item; + Datum datum; + MemoryContext partkeycxt, + oldcxt; + int16 procnum; + + tuple = SearchSysCache1(PARTRELID, + ObjectIdGetDatum(RelationGetRelid(relation))); + + /* + * The following happens when we have created our pg_class entry but not + * the pg_partitioned_table entry yet. + */ + if (!HeapTupleIsValid(tuple)) + return; + + partkeycxt = AllocSetContextCreate(CurTransactionContext, + "partition key", + ALLOCSET_SMALL_SIZES); + MemoryContextCopyAndSetIdentifier(partkeycxt, + RelationGetRelationName(relation)); + + key = (PartitionKey) MemoryContextAllocZero(partkeycxt, + sizeof(PartitionKeyData)); + + /* Fixed-length attributes */ + form = (Form_pg_partitioned_table) GETSTRUCT(tuple); + key->strategy = form->partstrat; + key->partnatts = form->partnatts; + + /* + * We can rely on the first variable-length attribute being mapped to the + * relevant field of the catalog's C struct, because all previous + * attributes are non-nullable and fixed-length. + */ + attrs = form->partattrs.values; + + /* But use the hard way to retrieve further variable-length attributes */ + /* Operator class */ + datum = SysCacheGetAttr(PARTRELID, tuple, + Anum_pg_partitioned_table_partclass, &isnull); + Assert(!isnull); + opclass = (oidvector *) DatumGetPointer(datum); + + /* Collation */ + datum = SysCacheGetAttr(PARTRELID, tuple, + Anum_pg_partitioned_table_partcollation, &isnull); + Assert(!isnull); + collation = (oidvector *) DatumGetPointer(datum); + + /* Expressions */ + datum = SysCacheGetAttr(PARTRELID, tuple, + Anum_pg_partitioned_table_partexprs, &isnull); + if (!isnull) + { + char *exprString; + Node *expr; + + exprString = TextDatumGetCString(datum); + expr = stringToNode(exprString); + pfree(exprString); + + /* + * Run the expressions through const-simplification since the planner + * will be comparing them to similarly-processed qual clause operands, + * and may fail to detect valid matches without this step; fix + * opfuncids while at it. We don't need to bother with + * canonicalize_qual() though, because partition expressions should be + * in canonical form already (ie, no need for OR-merging or constant + * elimination). + */ + expr = eval_const_expressions(NULL, expr); + fix_opfuncids(expr); + + oldcxt = MemoryContextSwitchTo(partkeycxt); + key->partexprs = (List *) copyObject(expr); + MemoryContextSwitchTo(oldcxt); + } + + /* Allocate assorted arrays in the partkeycxt, which we'll fill below */ + oldcxt = MemoryContextSwitchTo(partkeycxt); + key->partattrs = (AttrNumber *) palloc0(key->partnatts * sizeof(AttrNumber)); + key->partopfamily = (Oid *) palloc0(key->partnatts * sizeof(Oid)); + key->partopcintype = (Oid *) palloc0(key->partnatts * sizeof(Oid)); + key->partsupfunc = (FmgrInfo *) palloc0(key->partnatts * sizeof(FmgrInfo)); + + key->partcollation = (Oid *) palloc0(key->partnatts * sizeof(Oid)); + key->parttypid = (Oid *) palloc0(key->partnatts * sizeof(Oid)); + key->parttypmod = (int32 *) palloc0(key->partnatts * sizeof(int32)); + key->parttyplen = (int16 *) palloc0(key->partnatts * sizeof(int16)); + key->parttypbyval = (bool *) palloc0(key->partnatts * sizeof(bool)); + key->parttypalign = (char *) palloc0(key->partnatts * sizeof(char)); + key->parttypcoll = (Oid *) palloc0(key->partnatts * sizeof(Oid)); + MemoryContextSwitchTo(oldcxt); + + /* determine support function number to search for */ + procnum = (key->strategy == PARTITION_STRATEGY_HASH) ? + HASHEXTENDED_PROC : BTORDER_PROC; + + /* Copy partattrs and fill other per-attribute info */ + memcpy(key->partattrs, attrs, key->partnatts * sizeof(int16)); + partexprs_item = list_head(key->partexprs); + for (i = 0; i < key->partnatts; i++) + { + AttrNumber attno = key->partattrs[i]; + HeapTuple opclasstup; + Form_pg_opclass opclassform; + Oid funcid; + + /* Collect opfamily information */ + opclasstup = SearchSysCache1(CLAOID, + ObjectIdGetDatum(opclass->values[i])); + if (!HeapTupleIsValid(opclasstup)) + elog(ERROR, "cache lookup failed for opclass %u", opclass->values[i]); + + opclassform = (Form_pg_opclass) GETSTRUCT(opclasstup); + key->partopfamily[i] = opclassform->opcfamily; + key->partopcintype[i] = opclassform->opcintype; + + /* Get a support function for the specified opfamily and datatypes */ + funcid = get_opfamily_proc(opclassform->opcfamily, + opclassform->opcintype, + opclassform->opcintype, + procnum); + if (!OidIsValid(funcid)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), + errmsg("operator class \"%s\" of access method %s is missing support function %d for type %s", + NameStr(opclassform->opcname), + (key->strategy == PARTITION_STRATEGY_HASH) ? + "hash" : "btree", + procnum, + format_type_be(opclassform->opcintype)))); + + fmgr_info_cxt(funcid, &key->partsupfunc[i], partkeycxt); + + /* Collation */ + key->partcollation[i] = collation->values[i]; + + /* Collect type information */ + if (attno != 0) + { + Form_pg_attribute att = TupleDescAttr(relation->rd_att, attno - 1); + + key->parttypid[i] = att->atttypid; + key->parttypmod[i] = att->atttypmod; + key->parttypcoll[i] = att->attcollation; + } + else + { + if (partexprs_item == NULL) + elog(ERROR, "wrong number of partition key expressions"); + + key->parttypid[i] = exprType(lfirst(partexprs_item)); + key->parttypmod[i] = exprTypmod(lfirst(partexprs_item)); + key->parttypcoll[i] = exprCollation(lfirst(partexprs_item)); + + partexprs_item = lnext(key->partexprs, partexprs_item); + } + get_typlenbyvalalign(key->parttypid[i], + &key->parttyplen[i], + &key->parttypbyval[i], + &key->parttypalign[i]); + + ReleaseSysCache(opclasstup); + } + + ReleaseSysCache(tuple); + + /* Assert that we're not leaking any old data during assignments below */ + Assert(relation->rd_partkeycxt == NULL); + Assert(relation->rd_partkey == NULL); + + /* + * Success --- reparent our context and make the relcache point to the + * newly constructed key + */ + MemoryContextSetParent(partkeycxt, CacheMemoryContext); + relation->rd_partkeycxt = partkeycxt; + relation->rd_partkey = key; +} + +/* + * RelationGetPartitionQual + * + * Returns a list of partition quals + */ +List * +RelationGetPartitionQual(Relation rel) +{ + /* Quick exit */ + if (!rel->rd_rel->relispartition) + return NIL; + + return generate_partition_qual(rel); +} + +/* + * get_partition_qual_relid + * + * Returns an expression tree describing the passed-in relation's partition + * constraint. + * + * If the relation is not found, or is not a partition, or there is no + * partition constraint, return NULL. We must guard against the first two + * cases because this supports a SQL function that could be passed any OID. + * The last case can happen even if relispartition is true, when a default + * partition is the only partition. + */ +Expr * +get_partition_qual_relid(Oid relid) +{ + Expr *result = NULL; + + /* Do the work only if this relation exists and is a partition. */ + if (get_rel_relispartition(relid)) + { + Relation rel = relation_open(relid, AccessShareLock); + List *and_args; + + and_args = generate_partition_qual(rel); + + /* Convert implicit-AND list format to boolean expression */ + if (and_args == NIL) + result = NULL; + else if (list_length(and_args) > 1) + result = makeBoolExpr(AND_EXPR, and_args, -1); + else + result = linitial(and_args); + + /* Keep the lock, to allow safe deparsing against the rel by caller. */ + relation_close(rel, NoLock); + } + + return result; +} + +/* + * generate_partition_qual + * + * Generate partition predicate from rel's partition bound expression. The + * function returns a NIL list if there is no predicate. + * + * We cache a copy of the result in the relcache entry, after constructing + * it using the caller's context. This approach avoids leaking any data + * into long-lived cache contexts, especially if we fail partway through. + */ +static List * +generate_partition_qual(Relation rel) +{ + HeapTuple tuple; + MemoryContext oldcxt; + Datum boundDatum; + bool isnull; + List *my_qual = NIL, + *result = NIL; + Relation parent; + bool found_whole_row; + + /* Guard against stack overflow due to overly deep partition tree */ + check_stack_depth(); + + /* If we already cached the result, just return a copy */ + if (rel->rd_partcheckvalid) + return copyObject(rel->rd_partcheck); + + /* Grab at least an AccessShareLock on the parent table */ + parent = relation_open(get_partition_parent(RelationGetRelid(rel)), + AccessShareLock); + + /* Get pg_class.relpartbound */ + tuple = SearchSysCache1(RELOID, RelationGetRelid(rel)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for relation %u", + RelationGetRelid(rel)); + + boundDatum = SysCacheGetAttr(RELOID, tuple, + Anum_pg_class_relpartbound, + &isnull); + if (!isnull) + { + PartitionBoundSpec *bound; + + bound = castNode(PartitionBoundSpec, + stringToNode(TextDatumGetCString(boundDatum))); + + my_qual = get_qual_from_partbound(rel, parent, bound); + } + + ReleaseSysCache(tuple); + + /* Add the parent's quals to the list (if any) */ + if (parent->rd_rel->relispartition) + result = list_concat(generate_partition_qual(parent), my_qual); + else + result = my_qual; + + /* + * Change Vars to have partition's attnos instead of the parent's. We do + * this after we concatenate the parent's quals, because we want every Var + * in it to bear this relation's attnos. It's safe to assume varno = 1 + * here. + */ + result = map_partition_varattnos(result, 1, rel, parent, + &found_whole_row); + /* There can never be a whole-row reference here */ + if (found_whole_row) + elog(ERROR, "unexpected whole-row reference found in partition key"); + + /* Assert that we're not leaking any old data during assignments below */ + Assert(rel->rd_partcheckcxt == NULL); + Assert(rel->rd_partcheck == NIL); + + /* + * Save a copy in the relcache. The order of these operations is fairly + * critical to avoid memory leaks and ensure that we don't leave a corrupt + * relcache entry if we fail partway through copyObject. + * + * If, as is definitely possible, the partcheck list is NIL, then we do + * not need to make a context to hold it. + */ + if (result != NIL) + { + rel->rd_partcheckcxt = AllocSetContextCreate(CacheMemoryContext, + "partition constraint", + ALLOCSET_SMALL_SIZES); + MemoryContextCopyAndSetIdentifier(rel->rd_partcheckcxt, + RelationGetRelationName(rel)); + oldcxt = MemoryContextSwitchTo(rel->rd_partcheckcxt); + rel->rd_partcheck = copyObject(result); + MemoryContextSwitchTo(oldcxt); + } + else + rel->rd_partcheck = NIL; + rel->rd_partcheckvalid = true; + + /* Keep the parent locked until commit */ + relation_close(parent, NoLock); + + /* Return the working copy to the caller */ + return result; +} diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index 0ad3e3c7366..abc30628920 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -27,18 +27,24 @@ * query to change output tupdesc on replan --- if so, it's up to the * caller to notice changes and cope with them. * - * Currently, we track exactly the dependencies of plans on relations and - * user-defined functions. On relcache invalidation events or pg_proc - * syscache invalidation events, we invalidate just those plans that depend - * on the particular object being modified. (Note: this scheme assumes - * that any table modification that requires replanning will generate a - * relcache inval event.) We also watch for inval events on certain other - * system catalogs, such as pg_namespace; but for them, our response is - * just to invalidate all plans. We expect updates on those catalogs to - * be infrequent enough that more-detailed tracking is not worth the effort. + * Currently, we track exactly the dependencies of plans on relations, + * user-defined functions, and domains. On relcache invalidation events or + * pg_proc or pg_type syscache invalidation events, we invalidate just those + * plans that depend on the particular object being modified. (Note: this + * scheme assumes that any table modification that requires replanning will + * generate a relcache inval event.) We also watch for inval events on + * certain other system catalogs, such as pg_namespace; but for them, our + * response is just to invalidate all plans. We expect updates on those + * catalogs to be infrequent enough that more-detailed tracking is not worth + * the effort. * + * In addition to full-fledged query plans, we provide a facility for + * detecting invalidations of simple scalar expressions. This is fairly + * bare-bones; it's the caller's responsibility to build a new expression + * if the old one gets invalidated. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -55,9 +61,7 @@ #include "executor/executor.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/cost.h" -#include "optimizer/planmain.h" -#include "optimizer/prep.h" +#include "optimizer/optimizer.h" #include "parser/analyze.h" #include "parser/parsetree.h" #include "storage/lmgr.h" @@ -82,19 +86,24 @@ /* * This is the head of the backend's list of "saved" CachedPlanSources (i.e., * those that are in long-lived storage and are examined for sinval events). - * We thread the structs manually instead of using List cells so that we can - * guarantee to save a CachedPlanSource without error. + * We use a dlist instead of separate List cells so that we can guarantee + * to save a CachedPlanSource without error. + */ +static dlist_head saved_plan_list = DLIST_STATIC_INIT(saved_plan_list); + +/* + * This is the head of the backend's list of CachedExpressions. */ -static CachedPlanSource *first_saved_plan = NULL; +static dlist_head cached_expression_list = DLIST_STATIC_INIT(cached_expression_list); static void ReleaseGenericPlan(CachedPlanSource *plansource); static List *RevalidateCachedQuery(CachedPlanSource *plansource, - QueryEnvironment *queryEnv); + QueryEnvironment *queryEnv); static bool CheckCachedPlan(CachedPlanSource *plansource); static CachedPlan *BuildCachedPlan(CachedPlanSource *plansource, List *qlist, - ParamListInfo boundParams, QueryEnvironment *queryEnv); + ParamListInfo boundParams, QueryEnvironment *queryEnv); static bool choose_custom_plan(CachedPlanSource *plansource, - ParamListInfo boundParams); + ParamListInfo boundParams); static double cached_plan_cost(CachedPlan *plan, bool include_planner); static Query *QueryListGetPrimaryStmt(List *stmts); static void AcquireExecutorLocks(List *stmt_list, bool acquire); @@ -103,9 +112,11 @@ static void ScanQueryForLocks(Query *parsetree, bool acquire); static bool ScanQueryWalker(Node *node, bool *acquire); static TupleDesc PlanCacheComputeResultDesc(List *stmt_list); static void PlanCacheRelCallback(Datum arg, Oid relid); -static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue); +static void PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue); static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue); +/* GUC parameter */ +int plan_cache_mode; /* * InitPlanCache: initialize module during InitPostgres. @@ -116,7 +127,8 @@ void InitPlanCache(void) { CacheRegisterRelcacheCallback(PlanCacheRelCallback, (Datum) 0); - CacheRegisterSyscacheCallback(PROCOID, PlanCacheFuncCallback, (Datum) 0); + CacheRegisterSyscacheCallback(PROCOID, PlanCacheObjectCallback, (Datum) 0); + CacheRegisterSyscacheCallback(TYPEOID, PlanCacheObjectCallback, (Datum) 0); CacheRegisterSyscacheCallback(NAMESPACEOID, PlanCacheSysCallback, (Datum) 0); CacheRegisterSyscacheCallback(OPEROID, PlanCacheSysCallback, (Datum) 0); CacheRegisterSyscacheCallback(AMOPOPID, PlanCacheSysCallback, (Datum) 0); @@ -204,7 +216,6 @@ CreateCachedPlan(RawStmt *raw_parse_tree, plansource->is_saved = false; plansource->is_valid = false; plansource->generation = 0; - plansource->next_saved = NULL; plansource->generic_cost = -1; plansource->total_custom_cost = 0; plansource->num_custom_plans = 0; @@ -272,7 +283,6 @@ CreateOneShotCachedPlan(RawStmt *raw_parse_tree, plansource->is_saved = false; plansource->is_valid = false; plansource->generation = 0; - plansource->next_saved = NULL; plansource->generic_cost = -1; plansource->total_custom_cost = 0; plansource->num_custom_plans = 0; @@ -469,8 +479,7 @@ SaveCachedPlan(CachedPlanSource *plansource) /* * Add the entry to the global list of cached plans. */ - plansource->next_saved = first_saved_plan; - first_saved_plan = plansource; + dlist_push_tail(&saved_plan_list, &plansource->node); plansource->is_saved = true; } @@ -491,25 +500,11 @@ DropCachedPlan(CachedPlanSource *plansource) /* If it's been saved, remove it from the list */ if (plansource->is_saved) { - if (first_saved_plan == plansource) - first_saved_plan = plansource->next_saved; - else - { - CachedPlanSource *psrc; - - for (psrc = first_saved_plan; psrc; psrc = psrc->next_saved) - { - if (psrc->next_saved == plansource) - { - psrc->next_saved = plansource->next_saved; - break; - } - } - } + dlist_delete(&plansource->node); plansource->is_saved = false; } - /* Decrement generic CachePlan's refcount and drop if no longer needed */ + /* Decrement generic CachedPlan's refcount and drop if no longer needed */ ReleaseGenericPlan(plansource); /* Mark it no longer valid */ @@ -1033,6 +1028,12 @@ choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams) if (IsTransactionStmtPlan(plansource)) return false; + /* Let settings force the decision */ + if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN) + return false; + if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN) + return true; + /* See if caller wants to force the decision */ if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN) return false; @@ -1391,7 +1392,6 @@ CopyCachedPlan(CachedPlanSource *plansource) newsource->is_saved = false; newsource->is_valid = plansource->is_valid; newsource->generation = plansource->generation; - newsource->next_saved = NULL; /* We may as well copy any acquired cost knowledge */ newsource->generic_cost = plansource->generic_cost; @@ -1450,6 +1450,85 @@ CachedPlanGetTargetList(CachedPlanSource *plansource, return FetchStatementTargetList((Node *) pstmt); } +/* + * GetCachedExpression: construct a CachedExpression for an expression. + * + * This performs the same transformations on the expression as + * expression_planner(), ie, convert an expression as emitted by parse + * analysis to be ready to pass to the executor. + * + * The result is stashed in a private, long-lived memory context. + * (Note that this might leak a good deal of memory in the caller's + * context before that.) The passed-in expr tree is not modified. + */ +CachedExpression * +GetCachedExpression(Node *expr) +{ + CachedExpression *cexpr; + List *relationOids; + List *invalItems; + MemoryContext cexpr_context; + MemoryContext oldcxt; + + /* + * Pass the expression through the planner, and collect dependencies. + * Everything built here is leaked in the caller's context; that's + * intentional to minimize the size of the permanent data structure. + */ + expr = (Node *) expression_planner_with_deps((Expr *) expr, + &relationOids, + &invalItems); + + /* + * Make a private memory context, and copy what we need into that. To + * avoid leaking a long-lived context if we fail while copying data, we + * initially make the context under the caller's context. + */ + cexpr_context = AllocSetContextCreate(CurrentMemoryContext, + "CachedExpression", + ALLOCSET_SMALL_SIZES); + + oldcxt = MemoryContextSwitchTo(cexpr_context); + + cexpr = (CachedExpression *) palloc(sizeof(CachedExpression)); + cexpr->magic = CACHEDEXPR_MAGIC; + cexpr->expr = copyObject(expr); + cexpr->is_valid = true; + cexpr->relationOids = copyObject(relationOids); + cexpr->invalItems = copyObject(invalItems); + cexpr->context = cexpr_context; + + MemoryContextSwitchTo(oldcxt); + + /* + * Reparent the expr's memory context under CacheMemoryContext so that it + * will live indefinitely. + */ + MemoryContextSetParent(cexpr_context, CacheMemoryContext); + + /* + * Add the entry to the global list of cached expressions. + */ + dlist_push_tail(&cached_expression_list, &cexpr->node); + + return cexpr; +} + +/* + * FreeCachedExpression + * Delete a CachedExpression. + */ +void +FreeCachedExpression(CachedExpression *cexpr) +{ + /* Sanity check */ + Assert(cexpr->magic == CACHEDEXPR_MAGIC); + /* Unlink from global list */ + dlist_delete(&cexpr->node); + /* Free all storage associated with CachedExpression */ + MemoryContextDelete(cexpr->context); +} + /* * QueryListGetPrimaryStmt * Get the "primary" stmt within a list, ie, the one marked canSetTag. @@ -1485,7 +1564,6 @@ AcquireExecutorLocks(List *stmt_list, bool acquire) foreach(lc1, stmt_list) { PlannedStmt *plannedstmt = lfirst_node(PlannedStmt, lc1); - int rt_index; ListCell *lc2; if (plannedstmt->commandType == CMD_UTILITY) @@ -1504,14 +1582,9 @@ AcquireExecutorLocks(List *stmt_list, bool acquire) continue; } - rt_index = 0; foreach(lc2, plannedstmt->rtable) { RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc2); - LOCKMODE lockmode; - PlanRowMark *rc; - - rt_index++; if (rte->rtekind != RTE_RELATION) continue; @@ -1522,19 +1595,10 @@ AcquireExecutorLocks(List *stmt_list, bool acquire) * fail if it's been dropped entirely --- we'll just transiently * acquire a non-conflicting lock. */ - if (list_member_int(plannedstmt->resultRelations, rt_index) || - list_member_int(plannedstmt->nonleafResultRelations, rt_index)) - lockmode = RowExclusiveLock; - else if ((rc = get_plan_rowmark(plannedstmt->rowMarks, rt_index)) != NULL && - RowMarkRequiresRowShareLock(rc->markType)) - lockmode = RowShareLock; - else - lockmode = AccessShareLock; - if (acquire) - LockRelationOid(rte->relid, lockmode); + LockRelationOid(rte->relid, rte->rellockmode); else - UnlockRelationOid(rte->relid, lockmode); + UnlockRelationOid(rte->relid, rte->rellockmode); } } } @@ -1576,7 +1640,6 @@ static void ScanQueryForLocks(Query *parsetree, bool acquire) { ListCell *lc; - int rt_index; /* Shouldn't get called on utility commands */ Assert(parsetree->commandType != CMD_UTILITY); @@ -1584,27 +1647,18 @@ ScanQueryForLocks(Query *parsetree, bool acquire) /* * First, process RTEs of the current query level. */ - rt_index = 0; foreach(lc, parsetree->rtable) { RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc); - LOCKMODE lockmode; - rt_index++; switch (rte->rtekind) { case RTE_RELATION: /* Acquire or release the appropriate type of lock */ - if (rt_index == parsetree->resultRelation) - lockmode = RowExclusiveLock; - else if (get_parse_rowmark(parsetree, rt_index) != NULL) - lockmode = RowShareLock; - else - lockmode = AccessShareLock; if (acquire) - LockRelationOid(rte->relid, lockmode); + LockRelationOid(rte->relid, rte->rellockmode); else - UnlockRelationOid(rte->relid, lockmode); + UnlockRelationOid(rte->relid, rte->rellockmode); break; case RTE_SUBQUERY: @@ -1680,12 +1734,12 @@ PlanCacheComputeResultDesc(List *stmt_list) case PORTAL_ONE_SELECT: case PORTAL_ONE_MOD_WITH: query = linitial_node(Query, stmt_list); - return ExecCleanTypeFromTL(query->targetList, false); + return ExecCleanTypeFromTL(query->targetList); case PORTAL_ONE_RETURNING: query = QueryListGetPrimaryStmt(stmt_list); Assert(query->returningList); - return ExecCleanTypeFromTL(query->returningList, false); + return ExecCleanTypeFromTL(query->returningList); case PORTAL_UTIL_SELECT: query = linitial_node(Query, stmt_list); @@ -1709,10 +1763,13 @@ PlanCacheComputeResultDesc(List *stmt_list) static void PlanCacheRelCallback(Datum arg, Oid relid) { - CachedPlanSource *plansource; + dlist_iter iter; - for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved) + dlist_foreach(iter, &saved_plan_list) { + CachedPlanSource *plansource = dlist_container(CachedPlanSource, + node, iter.cur); + Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); /* No work if it's already invalidated */ @@ -1759,25 +1816,43 @@ PlanCacheRelCallback(Datum arg, Oid relid) } } } + + /* Likewise check cached expressions */ + dlist_foreach(iter, &cached_expression_list) + { + CachedExpression *cexpr = dlist_container(CachedExpression, + node, iter.cur); + + Assert(cexpr->magic == CACHEDEXPR_MAGIC); + + /* No work if it's already invalidated */ + if (!cexpr->is_valid) + continue; + + if ((relid == InvalidOid) ? cexpr->relationOids != NIL : + list_member_oid(cexpr->relationOids, relid)) + { + cexpr->is_valid = false; + } + } } /* - * PlanCacheFuncCallback - * Syscache inval callback function for PROCOID cache + * PlanCacheObjectCallback + * Syscache inval callback function for PROCOID and TYPEOID caches * * Invalidate all plans mentioning the object with the specified hash value, * or all plans mentioning any member of this cache if hashvalue == 0. - * - * Note that the coding would support use for multiple caches, but right - * now only user-defined functions are tracked this way. */ static void -PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue) +PlanCacheObjectCallback(Datum arg, int cacheid, uint32 hashvalue) { - CachedPlanSource *plansource; + dlist_iter iter; - for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved) + dlist_foreach(iter, &saved_plan_list) { + CachedPlanSource *plansource = dlist_container(CachedPlanSource, + node, iter.cur); ListCell *lc; Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); @@ -1842,6 +1917,34 @@ PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue) } } } + + /* Likewise check cached expressions */ + dlist_foreach(iter, &cached_expression_list) + { + CachedExpression *cexpr = dlist_container(CachedExpression, + node, iter.cur); + ListCell *lc; + + Assert(cexpr->magic == CACHEDEXPR_MAGIC); + + /* No work if it's already invalidated */ + if (!cexpr->is_valid) + continue; + + foreach(lc, cexpr->invalItems) + { + PlanInvalItem *item = (PlanInvalItem *) lfirst(lc); + + if (item->cacheId != cacheid) + continue; + if (hashvalue == 0 || + item->hashValue == hashvalue) + { + cexpr->is_valid = false; + break; + } + } + } } /* @@ -1862,10 +1965,12 @@ PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue) void ResetPlanCache(void) { - CachedPlanSource *plansource; + dlist_iter iter; - for (plansource = first_saved_plan; plansource; plansource = plansource->next_saved) + dlist_foreach(iter, &saved_plan_list) { + CachedPlanSource *plansource = dlist_container(CachedPlanSource, + node, iter.cur); ListCell *lc; Assert(plansource->magic == CACHEDPLANSOURCE_MAGIC); @@ -1905,4 +2010,15 @@ ResetPlanCache(void) } } } + + /* Likewise invalidate cached expressions */ + dlist_foreach(iter, &cached_expression_list) + { + CachedExpression *cexpr = dlist_container(CachedExpression, + node, iter.cur); + + Assert(cexpr->magic == CACHEDEXPR_MAGIC); + + cexpr->is_valid = false; + } } diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index e81c4691ec2..585dcee5dbc 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -3,7 +3,7 @@ * relcache.c * POSTGRES relation descriptor cache code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -30,17 +30,17 @@ #include #include -#include "access/hash.h" #include "access/htup_details.h" #include "access/multixact.h" #include "access/nbtree.h" #include "access/reloptions.h" #include "access/sysattr.h" +#include "access/table.h" +#include "access/tableam.h" #include "access/tupdesc_details.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" -#include "catalog/index.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/partition.h" @@ -68,12 +68,11 @@ #include "commands/policy.h" #include "commands/trigger.h" #include "miscadmin.h" +#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" -#include "optimizer/clauses.h" -#include "optimizer/cost.h" -#include "optimizer/prep.h" -#include "optimizer/var.h" -#include "pgstat.h" +#include "optimizer/optimizer.h" +#include "partitioning/partbounds.h" +#include "partitioning/partdesc.h" #include "rewrite/rewriteDefine.h" #include "rewrite/rowsecurity.h" #include "storage/lmgr.h" @@ -85,15 +84,28 @@ #include "utils/inval.h" #include "utils/lsyscache.h" #include "utils/memutils.h" +#include "utils/partcache.h" #include "utils/relmapper.h" #include "utils/resowner_private.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" #define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */ +/* + * Default policy for whether to apply RECOVER_RELATION_BUILD_MEMORY: + * do so in clobber-cache builds but not otherwise. This choice can be + * overridden at compile time with -DRECOVER_RELATION_BUILD_MEMORY=1 or =0. + */ +#ifndef RECOVER_RELATION_BUILD_MEMORY +#if defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY) +#define RECOVER_RELATION_BUILD_MEMORY 1 +#else +#define RECOVER_RELATION_BUILD_MEMORY 0 +#endif +#endif + /* * hardcoded tuple descriptors, contents generated by genbki.pl */ @@ -248,24 +260,23 @@ static void RelationDestroyRelation(Relation relation, bool remember_tupdesc); static void RelationClearRelation(Relation relation, bool rebuild); static void RelationReloadIndexInfo(Relation relation); +static void RelationReloadNailed(Relation relation); static void RelationFlushRelation(Relation relation); static void RememberToFreeTupleDescAtEOX(TupleDesc td); static void AtEOXact_cleanup(Relation relation, bool isCommit); static void AtEOSubXact_cleanup(Relation relation, bool isCommit, - SubTransactionId mySubid, SubTransactionId parentSubid); + SubTransactionId mySubid, SubTransactionId parentSubid); static bool load_relcache_init_file(bool shared); static void write_relcache_init_file(bool shared); static void write_item(const void *data, Size len, FILE *fp); static void formrdesc(const char *relationName, Oid relationReltype, - bool isshared, bool hasoids, - int natts, const FormData_pg_attribute *attrs); + bool isshared, int natts, const FormData_pg_attribute *attrs); static HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic); static Relation AllocateRelationDesc(Form_pg_class relp); static void RelationParseRelOptions(Relation relation, HeapTuple tuple); static void RelationBuildTupleDesc(Relation relation); -static void RelationBuildPartitionKey(Relation relation); static Relation RelationBuildDesc(Oid targetRelId, bool insertIt); static void RelationInitPhysicalAddr(Relation relation); static void load_critical_index(Oid indexoid, Oid heapoid); @@ -274,20 +285,17 @@ static TupleDesc GetPgIndexDescriptor(void); static void AttrDefaultFetch(Relation relation); static void CheckConstraintFetch(Relation relation); static int CheckConstraintCmp(const void *a, const void *b); -static List *insert_ordered_oid(List *list, Oid datum); static void InitIndexAmRoutine(Relation relation); static void IndexSupportInitialize(oidvector *indclass, - RegProcedure *indexSupport, - Oid *opFamily, - Oid *opcInType, - StrategyNumber maxSupportNumber, - AttrNumber maxAttributeNumber); + RegProcedure *indexSupport, + Oid *opFamily, + Oid *opcInType, + StrategyNumber maxSupportNumber, + AttrNumber maxAttributeNumber); static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid, - StrategyNumber numSupport); + StrategyNumber numSupport); static void RelationCacheInitFileRemoveInDir(const char *tblspcpath); -static void unlink_initfile(const char *initfilename); -static bool equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1, - PartitionDesc partdesc2); +static void unlink_initfile(const char *initfilename, int elevel); /* @@ -326,7 +334,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic) * form a scan key */ ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_class_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(targetRelId)); @@ -336,7 +344,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic) * without a pg_internal.init file). The caller can also force a heap * scan by setting indexOK == false. */ - pg_class_desc = heap_open(RelationRelationId, AccessShareLock); + pg_class_desc = table_open(RelationRelationId, AccessShareLock); /* * The caller might need a tuple that's newer than the one the historic @@ -363,7 +371,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic) /* all done */ systable_endscan(pg_class_scan); - heap_close(pg_class_desc, AccessShareLock); + table_close(pg_class_desc, AccessShareLock); return pg_class_tuple; } @@ -412,8 +420,7 @@ AllocateRelationDesc(Form_pg_class relp) relation->rd_rel = relationForm; /* and allocate attribute tuple form storage */ - relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts, - relationForm->relhasoids); + relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts); /* which we mark as a reference-counted tupdesc */ relation->rd_att->tdrefcount = 1; @@ -428,7 +435,7 @@ AllocateRelationDesc(Form_pg_class relp) * * tuple is the real pg_class tuple (not rd_rel!) for relation * - * Note: rd_rel and (if an index) rd_amroutine must be valid already + * Note: rd_rel and (if an index) rd_indam must be valid already */ static void RelationParseRelOptions(Relation relation, HeapTuple tuple) @@ -453,7 +460,7 @@ RelationParseRelOptions(Relation relation, HeapTuple tuple) break; case RELKIND_INDEX: case RELKIND_PARTITIONED_INDEX: - amoptsfn = relation->rd_amroutine->amoptions; + amoptsfn = relation->rd_indam->amoptions; break; default: return; @@ -503,11 +510,11 @@ RelationBuildTupleDesc(Relation relation) /* copy some fields from pg_class row to rd_att */ relation->rd_att->tdtypeid = relation->rd_rel->reltype; relation->rd_att->tdtypmod = -1; /* unnecessary, but... */ - relation->rd_att->tdhasoid = relation->rd_rel->relhasoids; constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext, sizeof(TupleConstr)); constr->has_not_null = false; + constr->has_generated_stored = false; /* * Form a scan key that selects only user attributes (attnum > 0). @@ -528,7 +535,7 @@ RelationBuildTupleDesc(Relation relation) * built the critical relcache entries (this includes initdb and startup * without a pg_internal.init file). */ - pg_attribute_desc = heap_open(AttributeRelationId, AccessShareLock); + pg_attribute_desc = table_open(AttributeRelationId, AccessShareLock); pg_attribute_scan = systable_beginscan(pg_attribute_desc, AttributeRelidNumIndexId, criticalRelcachesBuilt, @@ -560,6 +567,8 @@ RelationBuildTupleDesc(Relation relation) /* Update constraint/default info */ if (attp->attnotnull) constr->has_not_null = true; + if (attp->attgenerated == ATTRIBUTE_GENERATED_STORED) + constr->has_generated_stored = true; /* If the column has a default, fill it into the attrdef array */ if (attp->atthasdef) @@ -612,18 +621,18 @@ RelationBuildTupleDesc(Relation relation) if (attp->attbyval) { /* for copy by val just copy the datum direct */ - attrmiss[attnum - 1].ammissing = missval; + attrmiss[attnum - 1].am_value = missval; } else { /* otherwise copy in the correct context */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - attrmiss[attnum - 1].ammissing = datumCopy(missval, - attp->attbyval, - attp->attlen); + attrmiss[attnum - 1].am_value = datumCopy(missval, + attp->attbyval, + attp->attlen); MemoryContextSwitchTo(oldcxt); } - attrmiss[attnum - 1].ammissingPresent = true; + attrmiss[attnum - 1].am_present = true; } } need--; @@ -635,7 +644,7 @@ RelationBuildTupleDesc(Relation relation) * end the scan and close the attribute relation */ systable_endscan(pg_attribute_scan); - heap_close(pg_attribute_desc, AccessShareLock); + table_close(pg_attribute_desc, AccessShareLock); if (need != 0) elog(ERROR, "catalog is missing %d attribute(s) for relid %u", @@ -742,7 +751,7 @@ RelationBuildRuleLock(Relation relation) ALLOCSET_SMALL_SIZES); relation->rd_rulescxt = rulescxt; MemoryContextCopyAndSetIdentifier(rulescxt, - RelationGetRelationName(relation)); + RelationGetRelationName(relation)); /* * allocate an array to hold the rewrite rules (the array is extended if @@ -769,7 +778,7 @@ RelationBuildRuleLock(Relation relation) * emergency-recovery operations (ie, IgnoreSystemIndexes). This in turn * ensures that rules will be fired in name order. */ - rewrite_desc = heap_open(RewriteRelationId, AccessShareLock); + rewrite_desc = table_open(RewriteRelationId, AccessShareLock); rewrite_tupdesc = RelationGetDescr(rewrite_desc); rewrite_scan = systable_beginscan(rewrite_desc, RewriteRelRulenameIndexId, @@ -787,7 +796,7 @@ RelationBuildRuleLock(Relation relation) rule = (RewriteRule *) MemoryContextAlloc(rulescxt, sizeof(RewriteRule)); - rule->ruleId = HeapTupleGetOid(rewrite_tuple); + rule->ruleId = rewrite_form->oid; rule->event = rewrite_form->ev_type - '0'; rule->enabled = rewrite_form->ev_enabled; @@ -850,7 +859,7 @@ RelationBuildRuleLock(Relation relation) * end the scan and close the attribute relation */ systable_endscan(rewrite_scan); - heap_close(rewrite_desc, AccessShareLock); + table_close(rewrite_desc, AccessShareLock); /* * there might not be any rules (if relhasrules is out-of-date) @@ -873,211 +882,6 @@ RelationBuildRuleLock(Relation relation) relation->rd_rules = rulelock; } -/* - * RelationBuildPartitionKey - * Build and attach to relcache partition key data of relation - * - * Partitioning key data is a complex structure; to avoid complicated logic to - * free individual elements whenever the relcache entry is flushed, we give it - * its own memory context, child of CacheMemoryContext, which can easily be - * deleted on its own. To avoid leaking memory in that context in case of an - * error partway through this function, the context is initially created as a - * child of CurTransactionContext and only re-parented to CacheMemoryContext - * at the end, when no further errors are possible. Also, we don't make this - * context the current context except in very brief code sections, out of fear - * that some of our callees allocate memory on their own which would be leaked - * permanently. - */ -static void -RelationBuildPartitionKey(Relation relation) -{ - Form_pg_partitioned_table form; - HeapTuple tuple; - bool isnull; - int i; - PartitionKey key; - AttrNumber *attrs; - oidvector *opclass; - oidvector *collation; - ListCell *partexprs_item; - Datum datum; - MemoryContext partkeycxt, - oldcxt; - int16 procnum; - - tuple = SearchSysCache1(PARTRELID, - ObjectIdGetDatum(RelationGetRelid(relation))); - - /* - * The following happens when we have created our pg_class entry but not - * the pg_partitioned_table entry yet. - */ - if (!HeapTupleIsValid(tuple)) - return; - - partkeycxt = AllocSetContextCreate(CurTransactionContext, - "partition key", - ALLOCSET_SMALL_SIZES); - MemoryContextCopyAndSetIdentifier(partkeycxt, - RelationGetRelationName(relation)); - - key = (PartitionKey) MemoryContextAllocZero(partkeycxt, - sizeof(PartitionKeyData)); - - /* Fixed-length attributes */ - form = (Form_pg_partitioned_table) GETSTRUCT(tuple); - key->strategy = form->partstrat; - key->partnatts = form->partnatts; - - /* - * We can rely on the first variable-length attribute being mapped to the - * relevant field of the catalog's C struct, because all previous - * attributes are non-nullable and fixed-length. - */ - attrs = form->partattrs.values; - - /* But use the hard way to retrieve further variable-length attributes */ - /* Operator class */ - datum = SysCacheGetAttr(PARTRELID, tuple, - Anum_pg_partitioned_table_partclass, &isnull); - Assert(!isnull); - opclass = (oidvector *) DatumGetPointer(datum); - - /* Collation */ - datum = SysCacheGetAttr(PARTRELID, tuple, - Anum_pg_partitioned_table_partcollation, &isnull); - Assert(!isnull); - collation = (oidvector *) DatumGetPointer(datum); - - /* Expressions */ - datum = SysCacheGetAttr(PARTRELID, tuple, - Anum_pg_partitioned_table_partexprs, &isnull); - if (!isnull) - { - char *exprString; - Node *expr; - - exprString = TextDatumGetCString(datum); - expr = stringToNode(exprString); - pfree(exprString); - - /* - * Run the expressions through const-simplification since the planner - * will be comparing them to similarly-processed qual clause operands, - * and may fail to detect valid matches without this step; fix - * opfuncids while at it. We don't need to bother with - * canonicalize_qual() though, because partition expressions should be - * in canonical form already (ie, no need for OR-merging or constant - * elimination). - */ - expr = eval_const_expressions(NULL, expr); - fix_opfuncids(expr); - - oldcxt = MemoryContextSwitchTo(partkeycxt); - key->partexprs = (List *) copyObject(expr); - MemoryContextSwitchTo(oldcxt); - } - - oldcxt = MemoryContextSwitchTo(partkeycxt); - key->partattrs = (AttrNumber *) palloc0(key->partnatts * sizeof(AttrNumber)); - key->partopfamily = (Oid *) palloc0(key->partnatts * sizeof(Oid)); - key->partopcintype = (Oid *) palloc0(key->partnatts * sizeof(Oid)); - key->partsupfunc = (FmgrInfo *) palloc0(key->partnatts * sizeof(FmgrInfo)); - - key->partcollation = (Oid *) palloc0(key->partnatts * sizeof(Oid)); - - /* Gather type and collation info as well */ - key->parttypid = (Oid *) palloc0(key->partnatts * sizeof(Oid)); - key->parttypmod = (int32 *) palloc0(key->partnatts * sizeof(int32)); - key->parttyplen = (int16 *) palloc0(key->partnatts * sizeof(int16)); - key->parttypbyval = (bool *) palloc0(key->partnatts * sizeof(bool)); - key->parttypalign = (char *) palloc0(key->partnatts * sizeof(char)); - key->parttypcoll = (Oid *) palloc0(key->partnatts * sizeof(Oid)); - MemoryContextSwitchTo(oldcxt); - - /* determine support function number to search for */ - procnum = (key->strategy == PARTITION_STRATEGY_HASH) ? - HASHEXTENDED_PROC : BTORDER_PROC; - - /* Copy partattrs and fill other per-attribute info */ - memcpy(key->partattrs, attrs, key->partnatts * sizeof(int16)); - partexprs_item = list_head(key->partexprs); - for (i = 0; i < key->partnatts; i++) - { - AttrNumber attno = key->partattrs[i]; - HeapTuple opclasstup; - Form_pg_opclass opclassform; - Oid funcid; - - /* Collect opfamily information */ - opclasstup = SearchSysCache1(CLAOID, - ObjectIdGetDatum(opclass->values[i])); - if (!HeapTupleIsValid(opclasstup)) - elog(ERROR, "cache lookup failed for opclass %u", opclass->values[i]); - - opclassform = (Form_pg_opclass) GETSTRUCT(opclasstup); - key->partopfamily[i] = opclassform->opcfamily; - key->partopcintype[i] = opclassform->opcintype; - - /* Get a support function for the specified opfamily and datatypes */ - funcid = get_opfamily_proc(opclassform->opcfamily, - opclassform->opcintype, - opclassform->opcintype, - procnum); - if (!OidIsValid(funcid)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_OBJECT_DEFINITION), - errmsg("operator class \"%s\" of access method %s is missing support function %d for type %s", - NameStr(opclassform->opcname), - (key->strategy == PARTITION_STRATEGY_HASH) ? - "hash" : "btree", - procnum, - format_type_be(opclassform->opcintype)))); - - fmgr_info(funcid, &key->partsupfunc[i]); - - /* Collation */ - key->partcollation[i] = collation->values[i]; - - /* Collect type information */ - if (attno != 0) - { - Form_pg_attribute att = TupleDescAttr(relation->rd_att, attno - 1); - - key->parttypid[i] = att->atttypid; - key->parttypmod[i] = att->atttypmod; - key->parttypcoll[i] = att->attcollation; - } - else - { - if (partexprs_item == NULL) - elog(ERROR, "wrong number of partition key expressions"); - - key->parttypid[i] = exprType(lfirst(partexprs_item)); - key->parttypmod[i] = exprTypmod(lfirst(partexprs_item)); - key->parttypcoll[i] = exprCollation(lfirst(partexprs_item)); - - partexprs_item = lnext(partexprs_item); - } - get_typlenbyvalalign(key->parttypid[i], - &key->parttyplen[i], - &key->parttypbyval[i], - &key->parttypalign[i]); - - ReleaseSysCache(opclasstup); - } - - ReleaseSysCache(tuple); - - /* - * Success --- reparent our context and make the relcache point to the - * newly constructed key - */ - MemoryContextSetParent(partkeycxt, CacheMemoryContext); - relation->rd_partkeycxt = partkeycxt; - relation->rd_partkey = key; -} - /* * equalRuleLocks * @@ -1205,60 +1009,6 @@ equalRSDesc(RowSecurityDesc *rsdesc1, RowSecurityDesc *rsdesc2) return true; } -/* - * equalPartitionDescs - * Compare two partition descriptors for logical equality - */ -static bool -equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1, - PartitionDesc partdesc2) -{ - int i; - - if (partdesc1 != NULL) - { - if (partdesc2 == NULL) - return false; - if (partdesc1->nparts != partdesc2->nparts) - return false; - - Assert(key != NULL || partdesc1->nparts == 0); - - /* - * Same oids? If the partitioning structure did not change, that is, - * no partitions were added or removed to the relation, the oids array - * should still match element-by-element. - */ - for (i = 0; i < partdesc1->nparts; i++) - { - if (partdesc1->oids[i] != partdesc2->oids[i]) - return false; - } - - /* - * Now compare partition bound collections. The logic to iterate over - * the collections is private to partition.c. - */ - if (partdesc1->boundinfo != NULL) - { - if (partdesc2->boundinfo == NULL) - return false; - - if (!partition_bounds_equal(key->partnatts, key->parttyplen, - key->parttypbyval, - partdesc1->boundinfo, - partdesc2->boundinfo)) - return false; - } - else if (partdesc2->boundinfo != NULL) - return false; - } - else if (partdesc2 != NULL) - return false; - - return true; -} - /* * RelationBuildDesc * @@ -1279,6 +1029,28 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) HeapTuple pg_class_tuple; Form_pg_class relp; + /* + * This function and its subroutines can allocate a good deal of transient + * data in CurrentMemoryContext. Traditionally we've just leaked that + * data, reasoning that the caller's context is at worst of transaction + * scope, and relcache loads shouldn't happen so often that it's essential + * to recover transient data before end of statement/transaction. However + * that's definitely not true in clobber-cache test builds, and perhaps + * it's not true in other cases. If RECOVER_RELATION_BUILD_MEMORY is not + * zero, arrange to allocate the junk in a temporary context that we'll + * free before returning. Make it a child of caller's context so that it + * will get cleaned up appropriately if we error out partway through. + */ +#if RECOVER_RELATION_BUILD_MEMORY + MemoryContext tmpcxt; + MemoryContext oldcxt; + + tmpcxt = AllocSetContextCreate(CurrentMemoryContext, + "RelationBuildDesc workspace", + ALLOCSET_DEFAULT_SIZES); + oldcxt = MemoryContextSwitchTo(tmpcxt); +#endif + /* * find the tuple in pg_class corresponding to the given relation id */ @@ -1288,13 +1060,20 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) * if no such tuple exists, return NULL */ if (!HeapTupleIsValid(pg_class_tuple)) + { +#if RECOVER_RELATION_BUILD_MEMORY + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); +#endif return NULL; + } /* * get information from the pg_class_tuple */ - relid = HeapTupleGetOid(pg_class_tuple); relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); + relid = relp->oid; Assert(relid == targetRelId); /* @@ -1395,17 +1174,43 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) } else { - relation->rd_partkeycxt = NULL; relation->rd_partkey = NULL; + relation->rd_partkeycxt = NULL; relation->rd_partdesc = NULL; relation->rd_pdcxt = NULL; } + /* ... but partcheck is not loaded till asked for */ + relation->rd_partcheck = NIL; + relation->rd_partcheckvalid = false; + relation->rd_partcheckcxt = NULL; /* - * if it's an index, initialize index-related information + * initialize access method information */ - if (OidIsValid(relation->rd_rel->relam)) - RelationInitIndexAccessInfo(relation); + switch (relation->rd_rel->relkind) + { + case RELKIND_INDEX: + case RELKIND_PARTITIONED_INDEX: + Assert(relation->rd_rel->relam != InvalidOid); + RelationInitIndexAccessInfo(relation); + break; + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: + Assert(relation->rd_rel->relam != InvalidOid); + RelationInitTableAccessMethod(relation); + break; + case RELKIND_SEQUENCE: + Assert(relation->rd_rel->relam == InvalidOid); + RelationInitTableAccessMethod(relation); + break; + case RELKIND_VIEW: + case RELKIND_COMPOSITE_TYPE: + case RELKIND_FOREIGN_TABLE: + case RELKIND_PARTITIONED_TABLE: + Assert(relation->rd_rel->relam == InvalidOid); + break; + } /* extract reloptions if any */ RelationParseRelOptions(relation, pg_class_tuple); @@ -1446,6 +1251,12 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) /* It's fully valid */ relation->rd_isvalid = true; +#if RECOVER_RELATION_BUILD_MEMORY + /* Return to caller's context, and blow away the temporary context */ + MemoryContextSwitchTo(oldcxt); + MemoryContextDelete(tmpcxt); +#endif + return relation; } @@ -1459,6 +1270,10 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) static void RelationInitPhysicalAddr(Relation relation) { + /* these relations kinds never have storage */ + if (!RELKIND_HAS_STORAGE(relation->rd_rel->relkind)) + return; + if (relation->rd_rel->reltablespace) relation->rd_node.spcNode = relation->rd_rel->reltablespace; else @@ -1535,7 +1350,7 @@ InitIndexAmRoutine(Relation relation) cached = (IndexAmRoutine *) MemoryContextAlloc(relation->rd_indexcxt, sizeof(IndexAmRoutine)); memcpy(cached, tmp, sizeof(IndexAmRoutine)); - relation->rd_amroutine = cached; + relation->rd_indam = cached; pfree(tmp); } @@ -1604,7 +1419,7 @@ RelationInitIndexAccessInfo(Relation relation) ALLOCSET_SMALL_SIZES); relation->rd_indexcxt = indexcxt; MemoryContextCopyAndSetIdentifier(indexcxt, - RelationGetRelationName(relation)); + RelationGetRelationName(relation)); /* * Now we can fetch the index AM's API struct @@ -1620,7 +1435,7 @@ RelationInitIndexAccessInfo(Relation relation) relation->rd_opcintype = (Oid *) MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid)); - amsupport = relation->rd_amroutine->amsupport; + amsupport = relation->rd_indam->amsupport; if (amsupport > 0) { int nsupport = indnatts * amsupport; @@ -1637,10 +1452,10 @@ RelationInitIndexAccessInfo(Relation relation) } relation->rd_indcollation = (Oid *) - MemoryContextAllocZero(indexcxt, indnatts * sizeof(Oid)); + MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(Oid)); relation->rd_indoption = (int16 *) - MemoryContextAllocZero(indexcxt, indnatts * sizeof(int16)); + MemoryContextAllocZero(indexcxt, indnkeyatts * sizeof(int16)); /* * indcollation cannot be referenced directly through the C struct, @@ -1653,7 +1468,7 @@ RelationInitIndexAccessInfo(Relation relation) &isnull); Assert(!isnull); indcoll = (oidvector *) DatumGetPointer(indcollDatum); - memcpy(relation->rd_indcollation, indcoll->values, indnatts * sizeof(Oid)); + memcpy(relation->rd_indcollation, indcoll->values, indnkeyatts * sizeof(Oid)); /* * indclass cannot be referenced directly through the C struct, because it @@ -1685,7 +1500,7 @@ RelationInitIndexAccessInfo(Relation relation) &isnull); Assert(!isnull); indoption = (int2vector *) DatumGetPointer(indoptionDatum); - memcpy(relation->rd_indoption, indoption->values, indnatts * sizeof(int16)); + memcpy(relation->rd_indoption, indoption->values, indnkeyatts * sizeof(int16)); /* * expressions, predicate, exclusion caches will be filled later @@ -1844,10 +1659,10 @@ LookupOpclassInfo(Oid operatorClassOid, * work while bootstrapping. */ ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, + Anum_pg_opclass_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(operatorClassOid)); - rel = heap_open(OperatorClassRelationId, AccessShareLock); + rel = table_open(OperatorClassRelationId, AccessShareLock); scan = systable_beginscan(rel, OpclassOidIndexId, indexOK, NULL, 1, skey); @@ -1862,7 +1677,7 @@ LookupOpclassInfo(Oid operatorClassOid, elog(ERROR, "could not find tuple for opclass %u", operatorClassOid); systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); /* * Scan pg_amproc to obtain support procs for the opclass. We only fetch @@ -1882,7 +1697,7 @@ LookupOpclassInfo(Oid operatorClassOid, Anum_pg_amproc_amprocrighttype, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(opcentry->opcintype)); - rel = heap_open(AccessMethodProcedureRelationId, AccessShareLock); + rel = table_open(AccessMethodProcedureRelationId, AccessShareLock); scan = systable_beginscan(rel, AccessMethodProcedureIndexId, indexOK, NULL, 3, skey); @@ -1900,13 +1715,72 @@ LookupOpclassInfo(Oid operatorClassOid, } systable_endscan(scan); - heap_close(rel, AccessShareLock); + table_close(rel, AccessShareLock); } opcentry->valid = true; return opcentry; } +/* + * Fill in the TableAmRoutine for a relation + * + * relation's rd_amhandler must be valid already. + */ +static void +InitTableAmRoutine(Relation relation) +{ + relation->rd_tableam = GetTableAmRoutine(relation->rd_amhandler); +} + +/* + * Initialize table access method support for a table like relation + */ +void +RelationInitTableAccessMethod(Relation relation) +{ + HeapTuple tuple; + Form_pg_am aform; + + if (relation->rd_rel->relkind == RELKIND_SEQUENCE) + { + /* + * Sequences are currently accessed like heap tables, but it doesn't + * seem prudent to show that in the catalog. So just overwrite it + * here. + */ + relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID; + } + else if (IsCatalogRelation(relation)) + { + /* + * Avoid doing a syscache lookup for catalog tables. + */ + Assert(relation->rd_rel->relam == HEAP_TABLE_AM_OID); + relation->rd_amhandler = HEAP_TABLE_AM_HANDLER_OID; + } + else + { + /* + * Look up the table access method, save the OID of its handler + * function. + */ + Assert(relation->rd_rel->relam != InvalidOid); + tuple = SearchSysCache1(AMOID, + ObjectIdGetDatum(relation->rd_rel->relam)); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "cache lookup failed for access method %u", + relation->rd_rel->relam); + aform = (Form_pg_am) GETSTRUCT(tuple); + relation->rd_amhandler = aform->amhandler; + ReleaseSysCache(tuple); + } + + /* + * Now we can fetch the table AM's API struct + */ + InitTableAmRoutine(relation); +} /* * formrdesc @@ -1928,7 +1802,7 @@ LookupOpclassInfo(Oid operatorClassOid, */ static void formrdesc(const char *relationName, Oid relationReltype, - bool isshared, bool hasoids, + bool isshared, int natts, const FormData_pg_attribute *attrs) { Relation relation; @@ -1992,8 +1866,8 @@ formrdesc(const char *relationName, Oid relationReltype, relation->rd_rel->reltuples = 0; relation->rd_rel->relallvisible = 0; relation->rd_rel->relkind = RELKIND_RELATION; - relation->rd_rel->relhasoids = hasoids; relation->rd_rel->relnatts = (int16) natts; + relation->rd_rel->relam = HEAP_TABLE_AM_OID; /* * initialize attribute tuple form @@ -2002,7 +1876,7 @@ formrdesc(const char *relationName, Oid relationReltype, * because it will never be replaced. The data comes from * src/include/catalog/ headers via genbki.pl. */ - relation->rd_att = CreateTemplateTupleDesc(natts, hasoids); + relation->rd_att = CreateTemplateTupleDesc(natts); relation->rd_att->tdrefcount = 1; /* mark as refcounted */ relation->rd_att->tdtypeid = relationReltype; @@ -2061,6 +1935,12 @@ formrdesc(const char *relationName, Oid relationReltype, */ RelationInitPhysicalAddr(relation); + /* + * initialize the table am handler + */ + relation->rd_rel->relam = HEAP_TABLE_AM_OID; + relation->rd_tableam = GetHeapamTableAmRoutine(); + /* * initialize the rel-has-index flag, using hardwired knowledge */ @@ -2135,7 +2015,16 @@ RelationIdGetRelation(Oid relationId) RelationReloadIndexInfo(rd); else RelationClearRelation(rd, true); - Assert(rd->rd_isvalid); + + /* + * Normally entries need to be valid here, but before the relcache + * has been initialized, not enough infrastructure exists to + * perform pg_class lookups. The structure of such entries doesn't + * change, but we still want to update the rd_rel entry. So + * rd_isvalid = false is left in place for a later lookup. + */ + Assert(rd->rd_isvalid || + (rd->rd_isnailed && !criticalRelcachesBuilt)); } return rd; } @@ -2339,6 +2228,81 @@ RelationReloadIndexInfo(Relation relation) relation->rd_isvalid = true; } +/* + * RelationReloadNailed - reload minimal information for nailed relations. + * + * The structure of a nailed relation can never change (which is good, because + * we rely on knowing their structure to be able to read catalog content). But + * some parts, e.g. pg_class.relfrozenxid, are still important to have + * accurate content for. Therefore those need to be reloaded after the arrival + * of invalidations. + */ +static void +RelationReloadNailed(Relation relation) +{ + Assert(relation->rd_isnailed); + + /* + * Redo RelationInitPhysicalAddr in case it is a mapped relation whose + * mapping changed. + */ + RelationInitPhysicalAddr(relation); + + /* flag as needing to be revalidated */ + relation->rd_isvalid = false; + + /* + * Can only reread catalog contents if in a transaction. If the relation + * is currently open (not counting the nailed refcount), do so + * immediately. Otherwise we've already marked the entry as possibly + * invalid, and it'll be fixed when next opened. + */ + if (!IsTransactionState() || relation->rd_refcnt <= 1) + return; + + if (relation->rd_rel->relkind == RELKIND_INDEX) + { + /* + * If it's a nailed-but-not-mapped index, then we need to re-read the + * pg_class row to see if its relfilenode changed. + */ + RelationReloadIndexInfo(relation); + } + else + { + /* + * Reload a non-index entry. We can't easily do so if relcaches + * aren't yet built, but that's fine because at that stage the + * attributes that need to be current (like relfrozenxid) aren't yet + * accessed. To ensure the entry will later be revalidated, we leave + * it in invalid state, but allow use (cf. RelationIdGetRelation()). + */ + if (criticalRelcachesBuilt) + { + HeapTuple pg_class_tuple; + Form_pg_class relp; + + /* + * NB: Mark the entry as valid before starting to scan, to avoid + * self-recursion when re-building pg_class. + */ + relation->rd_isvalid = true; + + pg_class_tuple = ScanPgRelation(RelationGetRelid(relation), + true, false); + relp = (Form_pg_class) GETSTRUCT(pg_class_tuple); + memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE); + heap_freetuple(pg_class_tuple); + + /* + * Again mark as valid, to protect against concurrently arriving + * invalidations. + */ + relation->rd_isvalid = true; + } + } +} + /* * RelationDestroyRelation * @@ -2384,17 +2348,19 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) list_free_deep(relation->rd_fkeylist); list_free(relation->rd_indexlist); bms_free(relation->rd_indexattr); - bms_free(relation->rd_projindexattr); bms_free(relation->rd_keyattr); bms_free(relation->rd_pkattr); bms_free(relation->rd_idattr); - bms_free(relation->rd_projidx); if (relation->rd_pubactions) pfree(relation->rd_pubactions); if (relation->rd_options) pfree(relation->rd_options); if (relation->rd_indextuple) pfree(relation->rd_indextuple); + if (relation->rd_amcache) + pfree(relation->rd_amcache); + if (relation->rd_fdwroutine) + pfree(relation->rd_fdwroutine); if (relation->rd_indexcxt) MemoryContextDelete(relation->rd_indexcxt); if (relation->rd_rulescxt) @@ -2405,10 +2371,8 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc) MemoryContextDelete(relation->rd_partkeycxt); if (relation->rd_pdcxt) MemoryContextDelete(relation->rd_pdcxt); - if (relation->rd_partcheck) - pfree(relation->rd_partcheck); - if (relation->rd_fdwroutine) - pfree(relation->rd_fdwroutine); + if (relation->rd_partcheckcxt) + MemoryContextDelete(relation->rd_partcheckcxt); pfree(relation); } @@ -2453,28 +2417,18 @@ RelationClearRelation(Relation relation, bool rebuild) */ RelationCloseSmgr(relation); + /* Free AM cached data, if any */ + if (relation->rd_amcache) + pfree(relation->rd_amcache); + relation->rd_amcache = NULL; + /* - * Never, never ever blow away a nailed-in system relation, because we'd - * be unable to recover. However, we must redo RelationInitPhysicalAddr - * in case it is a mapped relation whose mapping changed. - * - * If it's a nailed-but-not-mapped index, then we need to re-read the - * pg_class row to see if its relfilenode changed. We do that immediately - * if we're inside a valid transaction and the relation is open (not - * counting the nailed refcount). Otherwise just mark the entry as - * possibly invalid, and it'll be fixed when next opened. + * Treat nailed-in system relations separately, they always need to be + * accessible, so we can't blow them away. */ if (relation->rd_isnailed) { - RelationInitPhysicalAddr(relation); - - if (relation->rd_rel->relkind == RELKIND_INDEX || - relation->rd_rel->relkind == RELKIND_PARTITIONED_INDEX) - { - relation->rd_isvalid = false; /* needs to be revalidated */ - if (relation->rd_refcnt > 1 && IsTransactionState()) - RelationReloadIndexInfo(relation); - } + RelationReloadNailed(relation); return; } @@ -2605,6 +2559,7 @@ RelationClearRelation(Relation relation, bool rebuild) keep_tupdesc = equalTupleDescs(relation->rd_att, newrel->rd_att); keep_rules = equalRuleLocks(relation->rd_rules, newrel->rd_rules); keep_policies = equalRSDesc(relation->rd_rsdesc, newrel->rd_rsdesc); + /* partkey is immutable once set up, so we can always keep it */ keep_partkey = (relation->rd_partkey != NULL); keep_partdesc = equalPartitionDescs(relation->rd_partkey, relation->rd_partdesc, @@ -2649,7 +2604,7 @@ RelationClearRelation(Relation relation, bool rebuild) SWAPFIELD(Form_pg_class, rd_rel); /* ... but actually, we don't have to update newrel->rd_rel */ memcpy(relation->rd_rel, newrel->rd_rel, CLASS_TUPLE_SIZE); - /* preserve old tupledesc and rules if no logical change */ + /* preserve old tupledesc, rules, policies if no logical change */ if (keep_tupdesc) SWAPFIELD(TupleDesc, rd_att); if (keep_rules) @@ -2663,18 +2618,37 @@ RelationClearRelation(Relation relation, bool rebuild) SWAPFIELD(Oid, rd_toastoid); /* pgstat_info must be preserved */ SWAPFIELD(struct PgStat_TableStatus *, pgstat_info); - /* partition key must be preserved, if we have one */ + /* preserve old partitioning info if no logical change */ if (keep_partkey) { SWAPFIELD(PartitionKey, rd_partkey); SWAPFIELD(MemoryContext, rd_partkeycxt); } - /* preserve old partdesc if no logical change */ if (keep_partdesc) { SWAPFIELD(PartitionDesc, rd_partdesc); SWAPFIELD(MemoryContext, rd_pdcxt); } + else if (rebuild && newrel->rd_pdcxt != NULL) + { + /* + * We are rebuilding a partitioned relation with a non-zero + * reference count, so keep the old partition descriptor around, + * in case there's a PartitionDirectory with a pointer to it. + * Attach it to the new rd_pdcxt so that it gets cleaned up + * eventually. In the case where the reference count is 0, this + * code is not reached, which should be OK because in that case + * there should be no PartitionDirectory with a pointer to the old + * entry. + * + * Note that newrel and relation have already been swapped, so the + * "old" partition descriptor is actually the one hanging off of + * newrel. + */ + MemoryContextSetParent(newrel->rd_pdcxt, relation->rd_pdcxt); + newrel->rd_partdesc = NULL; + newrel->rd_pdcxt = NULL; + } #undef SWAPFIELD @@ -3090,19 +3064,6 @@ AtEOXact_cleanup(Relation relation, bool isCommit) * Likewise, reset the hint about the relfilenode being new. */ relation->rd_newRelfilenodeSubid = InvalidSubTransactionId; - - /* - * Flush any temporary index list. - */ - if (relation->rd_indexvalid == 2) - { - list_free(relation->rd_indexlist); - relation->rd_indexlist = NIL; - relation->rd_oidindex = InvalidOid; - relation->rd_pkindex = InvalidOid; - relation->rd_replidindex = InvalidOid; - relation->rd_indexvalid = 0; - } } /* @@ -3203,19 +3164,6 @@ AtEOSubXact_cleanup(Relation relation, bool isCommit, else relation->rd_newRelfilenodeSubid = InvalidSubTransactionId; } - - /* - * Flush any temporary index list. - */ - if (relation->rd_indexvalid == 2) - { - list_free(relation->rd_indexlist); - relation->rd_indexlist = NIL; - relation->rd_oidindex = InvalidOid; - relation->rd_pkindex = InvalidOid; - relation->rd_replidindex = InvalidOid; - relation->rd_indexvalid = 0; - } } @@ -3229,6 +3177,7 @@ RelationBuildLocalRelation(const char *relname, Oid relnamespace, TupleDesc tupDesc, Oid relid, + Oid accessmtd, Oid relfilenode, Oid reltablespace, bool shared_relation, @@ -3321,6 +3270,7 @@ RelationBuildLocalRelation(const char *relname, Form_pg_attribute datt = TupleDescAttr(rel->rd_att, i); datt->attidentity = satt->attidentity; + datt->attgenerated = satt->attgenerated; datt->attnotnull = satt->attnotnull; has_not_null |= satt->attnotnull; } @@ -3342,7 +3292,6 @@ RelationBuildLocalRelation(const char *relname, rel->rd_rel->relnamespace = relnamespace; rel->rd_rel->relkind = relkind; - rel->rd_rel->relhasoids = rel->rd_att->tdhasoid; rel->rd_rel->relnatts = natts; rel->rd_rel->reltype = InvalidOid; /* needed when bootstrapping: */ @@ -3373,8 +3322,8 @@ RelationBuildLocalRelation(const char *relname, else rel->rd_rel->relispopulated = true; - /* system relations and non-table objects don't have one */ - if (!IsSystemNamespace(relnamespace) && + /* set replica identity -- system catalogs and non-tables don't have one */ + if (!IsCatalogNamespace(relnamespace) && (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW || relkind == RELKIND_PARTITIONED_TABLE)) @@ -3409,6 +3358,14 @@ RelationBuildLocalRelation(const char *relname, RelationInitPhysicalAddr(rel); + rel->rd_rel->relam = accessmtd; + + if (relkind == RELKIND_RELATION || + relkind == RELKIND_SEQUENCE || + relkind == RELKIND_TOASTVALUE || + relkind == RELKIND_MATVIEW) + RelationInitTableAccessMethod(rel); + /* * Okay to insert into the relcache hash table. * @@ -3446,7 +3403,8 @@ RelationBuildLocalRelation(const char *relname, /* * RelationSetNewRelfilenode * - * Assign a new relfilenode (physical file name) to the relation. + * Assign a new relfilenode (physical file name), and possibly a new + * persistence setting, to the relation. * * This allows a full rewrite of the relation to be done with transactional * safety (since the filenode assignment can be rolled back). Note however @@ -3455,31 +3413,17 @@ RelationBuildLocalRelation(const char *relname, * such as TRUNCATE or rebuilding an index from scratch. * * Caller must already hold exclusive lock on the relation. - * - * The relation is marked with relfrozenxid = freezeXid (InvalidTransactionId - * must be passed for indexes and sequences). This should be a lower bound on - * the XIDs that will be put into the new relation contents. - * - * The new filenode's persistence is set to the given value. This is useful - * for the cases that are changing the relation's persistence; other callers - * need to pass the original relpersistence value. */ void -RelationSetNewRelfilenode(Relation relation, char persistence, - TransactionId freezeXid, MultiXactId minmulti) +RelationSetNewRelfilenode(Relation relation, char persistence) { Oid newrelfilenode; - RelFileNodeBackend newrnode; Relation pg_class; HeapTuple tuple; Form_pg_class classform; - - /* Indexes, sequences must have Invalid frozenxid; other rels must not */ - Assert((relation->rd_rel->relkind == RELKIND_INDEX || - relation->rd_rel->relkind == RELKIND_SEQUENCE) ? - freezeXid == InvalidTransactionId : - TransactionIdIsNormal(freezeXid)); - Assert(TransactionIdIsNormal(freezeXid) == MultiXactIdIsValid(minmulti)); + MultiXactId minmulti = InvalidMultiXactId; + TransactionId freezeXid = InvalidTransactionId; + RelFileNode newrnode; /* Allocate a new relfilenode */ newrelfilenode = GetNewRelFileNode(relation->rd_rel->reltablespace, NULL, @@ -3488,7 +3432,7 @@ RelationSetNewRelfilenode(Relation relation, char persistence, /* * Get a writable copy of the pg_class tuple for the given relation. */ - pg_class = heap_open(RelationRelationId, RowExclusiveLock); + pg_class = table_open(RelationRelationId, RowExclusiveLock); tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(RelationGetRelid(relation))); @@ -3498,55 +3442,111 @@ RelationSetNewRelfilenode(Relation relation, char persistence, classform = (Form_pg_class) GETSTRUCT(tuple); /* - * Create storage for the main fork of the new relfilenode. - * - * NOTE: any conflict in relfilenode value will be caught here, if - * GetNewRelFileNode messes up for any reason. + * Schedule unlinking of the old storage at transaction commit. */ - newrnode.node = relation->rd_node; - newrnode.node.relNode = newrelfilenode; - newrnode.backend = relation->rd_backend; - RelationCreateStorage(newrnode.node, persistence); - smgrclosenode(newrnode); + RelationDropStorage(relation); /* - * Schedule unlinking of the old storage at transaction commit. + * Create storage for the main fork of the new relfilenode. If it's a + * table-like object, call into the table AM to do so, which'll also + * create the table's init fork if needed. + * + * NOTE: If relevant for the AM, any conflict in relfilenode value will be + * caught here, if GetNewRelFileNode messes up for any reason. */ - RelationDropStorage(relation); + newrnode = relation->rd_node; + newrnode.relNode = newrelfilenode; + + switch (relation->rd_rel->relkind) + { + case RELKIND_INDEX: + case RELKIND_SEQUENCE: + { + /* handle these directly, at least for now */ + SMgrRelation srel; + + srel = RelationCreateStorage(newrnode, persistence); + smgrclose(srel); + } + break; + + case RELKIND_RELATION: + case RELKIND_TOASTVALUE: + case RELKIND_MATVIEW: + table_relation_set_new_filenode(relation, &newrnode, + persistence, + &freezeXid, &minmulti); + break; + + default: + /* we shouldn't be called for anything else */ + elog(ERROR, "relation \"%s\" does not have storage", + RelationGetRelationName(relation)); + break; + } /* - * Now update the pg_class row. However, if we're dealing with a mapped - * index, pg_class.relfilenode doesn't change; instead we have to send the - * update to the relation mapper. + * If we're dealing with a mapped index, pg_class.relfilenode doesn't + * change; instead we have to send the update to the relation mapper. + * + * For mapped indexes, we don't actually change the pg_class entry at all; + * this is essential when reindexing pg_class itself. That leaves us with + * possibly-inaccurate values of relpages etc, but those will be fixed up + * later. */ if (RelationIsMapped(relation)) + { + /* This case is only supported for indexes */ + Assert(relation->rd_rel->relkind == RELKIND_INDEX); + + /* Since we're not updating pg_class, these had better not change */ + Assert(classform->relfrozenxid == freezeXid); + Assert(classform->relminmxid == minmulti); + Assert(classform->relpersistence == persistence); + + /* + * In some code paths it's possible that the tuple update we'd + * otherwise do here is the only thing that would assign an XID for + * the current transaction. However, we must have an XID to delete + * files, so make sure one is assigned. + */ + (void) GetCurrentTransactionId(); + + /* Do the deed */ RelationMapUpdateMap(RelationGetRelid(relation), newrelfilenode, relation->rd_rel->relisshared, false); + + /* Since we're not updating pg_class, must trigger inval manually */ + CacheInvalidateRelcache(relation); + } else + { + /* Normal case, update the pg_class entry */ classform->relfilenode = newrelfilenode; - /* These changes are safe even for a mapped relation */ - if (relation->rd_rel->relkind != RELKIND_SEQUENCE) - { - classform->relpages = 0; /* it's empty until further notice */ - classform->reltuples = 0; - classform->relallvisible = 0; - } - classform->relfrozenxid = freezeXid; - classform->relminmxid = minmulti; - classform->relpersistence = persistence; + /* relpages etc. never change for sequences */ + if (relation->rd_rel->relkind != RELKIND_SEQUENCE) + { + classform->relpages = 0; /* it's empty until further notice */ + classform->reltuples = 0; + classform->relallvisible = 0; + } + classform->relfrozenxid = freezeXid; + classform->relminmxid = minmulti; + classform->relpersistence = persistence; - CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + CatalogTupleUpdate(pg_class, &tuple->t_self, tuple); + } heap_freetuple(tuple); - heap_close(pg_class, RowExclusiveLock); + table_close(pg_class, RowExclusiveLock); /* - * Make the pg_class row change visible, as well as the relation map - * change if any. This will cause the relcache entry to get updated, too. + * Make the pg_class row change or relation map change visible. This will + * cause the relcache entry to get updated, too. */ CommandCounterIncrement(); @@ -3642,15 +3642,15 @@ RelationCacheInitializePhase2(void) if (!load_relcache_init_file(true)) { formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true, - true, Natts_pg_database, Desc_pg_database); + Natts_pg_database, Desc_pg_database); formrdesc("pg_authid", AuthIdRelation_Rowtype_Id, true, - true, Natts_pg_authid, Desc_pg_authid); + Natts_pg_authid, Desc_pg_authid); formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id, true, - false, Natts_pg_auth_members, Desc_pg_auth_members); + Natts_pg_auth_members, Desc_pg_auth_members); formrdesc("pg_shseclabel", SharedSecLabelRelation_Rowtype_Id, true, - false, Natts_pg_shseclabel, Desc_pg_shseclabel); + Natts_pg_shseclabel, Desc_pg_shseclabel); formrdesc("pg_subscription", SubscriptionRelation_Rowtype_Id, true, - true, Natts_pg_subscription, Desc_pg_subscription); + Natts_pg_subscription, Desc_pg_subscription); #define NUM_CRITICAL_SHARED_RELS 5 /* fix if you change list above */ } @@ -3701,13 +3701,13 @@ RelationCacheInitializePhase3(void) needNewCacheFile = true; formrdesc("pg_class", RelationRelation_Rowtype_Id, false, - true, Natts_pg_class, Desc_pg_class); + Natts_pg_class, Desc_pg_class); formrdesc("pg_attribute", AttributeRelation_Rowtype_Id, false, - false, Natts_pg_attribute, Desc_pg_attribute); + Natts_pg_attribute, Desc_pg_attribute); formrdesc("pg_proc", ProcedureRelation_Rowtype_Id, false, - true, Natts_pg_proc, Desc_pg_proc); + Natts_pg_proc, Desc_pg_proc); formrdesc("pg_type", TypeRelation_Rowtype_Id, false, - true, Natts_pg_type, Desc_pg_type); + Natts_pg_type, Desc_pg_type); #define NUM_CRITICAL_LOCAL_RELS 4 /* fix if you change list above */ } @@ -3859,7 +3859,6 @@ RelationCacheInitializePhase3(void) */ Assert(relation->rd_att->tdtypeid == relp->reltype); Assert(relation->rd_att->tdtypmod == -1); - Assert(relation->rd_att->tdhasoid == relp->relhasoids); ReleaseSysCache(htup); @@ -3930,6 +3929,18 @@ RelationCacheInitializePhase3(void) restart = true; } + if (relation->rd_tableam == NULL && + (relation->rd_rel->relkind == RELKIND_RELATION || + relation->rd_rel->relkind == RELKIND_SEQUENCE || + relation->rd_rel->relkind == RELKIND_TOASTVALUE || + relation->rd_rel->relkind == RELKIND_MATVIEW)) + { + RelationInitTableAccessMethod(relation); + Assert(relation->rd_tableam != NULL); + + restart = true; + } + /* Release hold on the relation */ RelationDecrementReferenceCount(relation); @@ -4002,8 +4013,7 @@ load_critical_index(Oid indexoid, Oid heapoid) * extracting fields. */ static TupleDesc -BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs, - bool hasoids) +BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs) { TupleDesc result; MemoryContext oldcxt; @@ -4011,7 +4021,7 @@ BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs, oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - result = CreateTemplateTupleDesc(natts, hasoids); + result = CreateTemplateTupleDesc(natts); result->tdtypeid = RECORDOID; /* not right, but we don't care */ result->tdtypmod = -1; @@ -4040,8 +4050,7 @@ GetPgClassDescriptor(void) /* Already done? */ if (pgclassdesc == NULL) pgclassdesc = BuildHardcodedDescriptor(Natts_pg_class, - Desc_pg_class, - true); + Desc_pg_class); return pgclassdesc; } @@ -4054,8 +4063,7 @@ GetPgIndexDescriptor(void) /* Already done? */ if (pgindexdesc == NULL) pgindexdesc = BuildHardcodedDescriptor(Natts_pg_index, - Desc_pg_index, - false); + Desc_pg_index); return pgindexdesc; } @@ -4082,7 +4090,7 @@ AttrDefaultFetch(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - adrel = heap_open(AttrDefaultRelationId, AccessShareLock); + adrel = table_open(AttrDefaultRelationId, AccessShareLock); adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 1, &skey); found = 0; @@ -4127,7 +4135,7 @@ AttrDefaultFetch(Relation relation) } systable_endscan(adscan); - heap_close(adrel, AccessShareLock); + table_close(adrel, AccessShareLock); } /* @@ -4149,8 +4157,8 @@ CheckConstraintFetch(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - conrel = heap_open(ConstraintRelationId, AccessShareLock); - conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, + conrel = table_open(ConstraintRelationId, AccessShareLock); + conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, NULL, 1, skey); while (HeapTupleIsValid(htup = systable_getnext(conscan))) @@ -4190,7 +4198,7 @@ CheckConstraintFetch(Relation relation) } systable_endscan(conscan); - heap_close(conrel, AccessShareLock); + table_close(conrel, AccessShareLock); if (found != ncheck) elog(ERROR, "%d constraint record(s) missing for rel %s", @@ -4242,8 +4250,9 @@ RelationGetFKeyList(Relation relation) if (relation->rd_fkeyvalid) return relation->rd_fkeylist; - /* Fast path: if it doesn't have any triggers, it can't have FKs */ - if (!relation->rd_rel->relhastriggers) + /* Fast path: non-partitioned tables without triggers can't have FKs */ + if (!relation->rd_rel->relhastriggers && + relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE) return NIL; /* @@ -4260,86 +4269,36 @@ RelationGetFKeyList(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - conrel = heap_open(ConstraintRelationId, AccessShareLock); - conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, + conrel = table_open(ConstraintRelationId, AccessShareLock); + conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, NULL, 1, &skey); while (HeapTupleIsValid(htup = systable_getnext(conscan))) { Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup); ForeignKeyCacheInfo *info; - Datum adatum; - bool isnull; - ArrayType *arr; - int nelem; /* consider only foreign keys */ if (constraint->contype != CONSTRAINT_FOREIGN) continue; info = makeNode(ForeignKeyCacheInfo); + info->conoid = constraint->oid; info->conrelid = constraint->conrelid; info->confrelid = constraint->confrelid; - /* Extract data from conkey field */ - adatum = fastgetattr(htup, Anum_pg_constraint_conkey, - conrel->rd_att, &isnull); - if (isnull) - elog(ERROR, "null conkey for rel %s", - RelationGetRelationName(relation)); - - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem < 1 || - nelem > INDEX_MAX_KEYS || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "conkey is not a 1-D smallint array"); - - info->nkeys = nelem; - memcpy(info->conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber)); - - /* Likewise for confkey */ - adatum = fastgetattr(htup, Anum_pg_constraint_confkey, - conrel->rd_att, &isnull); - if (isnull) - elog(ERROR, "null confkey for rel %s", - RelationGetRelationName(relation)); - - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem != info->nkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != INT2OID) - elog(ERROR, "confkey is not a 1-D smallint array"); - - memcpy(info->confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber)); - - /* Likewise for conpfeqop */ - adatum = fastgetattr(htup, Anum_pg_constraint_conpfeqop, - conrel->rd_att, &isnull); - if (isnull) - elog(ERROR, "null conpfeqop for rel %s", - RelationGetRelationName(relation)); - - arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */ - nelem = ARR_DIMS(arr)[0]; - if (ARR_NDIM(arr) != 1 || - nelem != info->nkeys || - ARR_HASNULL(arr) || - ARR_ELEMTYPE(arr) != OIDOID) - elog(ERROR, "conpfeqop is not a 1-D OID array"); - - memcpy(info->conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid)); + DeconstructFkConstraintRow(htup, &info->nkeys, + info->conkey, + info->confkey, + info->conpfeqop, + NULL, NULL); /* Add FK's node to the result list */ result = lappend(result, info); } systable_endscan(conscan); - heap_close(conrel, AccessShareLock); + table_close(conrel, AccessShareLock); /* Now save a copy of the completed list in the relcache entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); @@ -4360,11 +4319,11 @@ RelationGetFKeyList(Relation relation) * The index list is created only if someone requests it. We scan pg_index * to find relevant indexes, and add the list to the relcache entry so that * we won't have to compute it again. Note that shared cache inval of a - * relcache entry will delete the old list and set rd_indexvalid to 0, + * relcache entry will delete the old list and set rd_indexvalid to false, * so that we must recompute the index list on next request. This handles * creation or deletion of an index. * - * Indexes that are marked not IndexIsLive are omitted from the returned list. + * Indexes that are marked not indislive are omitted from the returned list. * Such indexes are expected to be dropped momentarily, and should not be * touched at all by any caller of this function. * @@ -4380,11 +4339,6 @@ RelationGetFKeyList(Relation relation) * since the caller will typically be doing syscache lookups on the relevant * indexes, and syscache lookup could cause SI messages to be processed! * - * We also update rd_oidindex, which this module treats as effectively part - * of the index list. rd_oidindex is valid when rd_indexvalid isn't zero; - * it is the pg_class OID of a unique index on OID when the relation has one, - * and InvalidOid if there is no such index. - * * In exactly the same way, we update rd_pkindex, which is the OID of the * relation's primary key index if any, else InvalidOid; and rd_replidindex, * which is the pg_class OID of an index to be used as the relation's @@ -4400,13 +4354,12 @@ RelationGetIndexList(Relation relation) List *result; List *oldlist; char replident = relation->rd_rel->relreplident; - Oid oidIndex = InvalidOid; Oid pkeyIndex = InvalidOid; Oid candidateIndex = InvalidOid; MemoryContext oldcxt; /* Quick exit if we already computed the list. */ - if (relation->rd_indexvalid != 0) + if (relation->rd_indexvalid) return list_copy(relation->rd_indexlist); /* @@ -4416,7 +4369,6 @@ RelationGetIndexList(Relation relation) * if we get some sort of error partway through. */ result = NIL; - oidIndex = InvalidOid; /* Prepare to scan pg_index for entries having indrelid = this rel. */ ScanKeyInit(&skey, @@ -4424,16 +4376,13 @@ RelationGetIndexList(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - indrel = heap_open(IndexRelationId, AccessShareLock); + indrel = table_open(IndexRelationId, AccessShareLock); indscan = systable_beginscan(indrel, IndexIndrelidIndexId, true, NULL, 1, &skey); while (HeapTupleIsValid(htup = systable_getnext(indscan))) { Form_pg_index index = (Form_pg_index) GETSTRUCT(htup); - Datum indclassDatum; - oidvector *indclass; - bool isnull; /* * Ignore any indexes that are currently being dropped. This will @@ -4441,40 +4390,22 @@ RelationGetIndexList(Relation relation) * HOT-safety decisions. It's unsafe to touch such an index at all * since its catalog entries could disappear at any instant. */ - if (!IndexIsLive(index)) + if (!index->indislive) continue; - /* Add index's OID to result list in the proper order */ - result = insert_ordered_oid(result, index->indexrelid); - - /* - * indclass cannot be referenced directly through the C struct, - * because it comes after the variable-width indkey field. Must - * extract the datum the hard way... - */ - indclassDatum = heap_getattr(htup, - Anum_pg_index_indclass, - GetPgIndexDescriptor(), - &isnull); - Assert(!isnull); - indclass = (oidvector *) DatumGetPointer(indclassDatum); + /* add index's OID to result list */ + result = lappend_oid(result, index->indexrelid); /* * Invalid, non-unique, non-immediate or predicate indexes aren't * interesting for either oid indexes or replication identity indexes, * so don't check them. */ - if (!IndexIsValid(index) || !index->indisunique || + if (!index->indisvalid || !index->indisunique || !index->indimmediate || !heap_attisnull(htup, Anum_pg_index_indpred, NULL)) continue; - /* Check to see if is a usable btree index on OID */ - if (index->indnatts == 1 && - index->indkey.values[0] == ObjectIdAttributeNumber && - indclass->values[0] == OID_BTREE_OPS_OID) - oidIndex = index->indexrelid; - /* remember primary key index if any */ if (index->indisprimary) pkeyIndex = index->indexrelid; @@ -4486,13 +4417,15 @@ RelationGetIndexList(Relation relation) systable_endscan(indscan); - heap_close(indrel, AccessShareLock); + table_close(indrel, AccessShareLock); + + /* Sort the result list into OID order, per API spec. */ + list_sort(result, list_oid_cmp); /* Now save a copy of the completed list in the relcache entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); oldlist = relation->rd_indexlist; relation->rd_indexlist = list_copy(result); - relation->rd_oidindex = oidIndex; relation->rd_pkindex = pkeyIndex; if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex)) relation->rd_replidindex = pkeyIndex; @@ -4500,7 +4433,7 @@ RelationGetIndexList(Relation relation) relation->rd_replidindex = candidateIndex; else relation->rd_replidindex = InvalidOid; - relation->rd_indexvalid = 1; + relation->rd_indexvalid = true; MemoryContextSwitchTo(oldcxt); /* Don't leak the old list, if there is one */ @@ -4562,16 +4495,23 @@ RelationGetStatExtList(Relation relation) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(relation))); - indrel = heap_open(StatisticExtRelationId, AccessShareLock); + indrel = table_open(StatisticExtRelationId, AccessShareLock); indscan = systable_beginscan(indrel, StatisticExtRelidIndexId, true, NULL, 1, &skey); while (HeapTupleIsValid(htup = systable_getnext(indscan))) - result = insert_ordered_oid(result, HeapTupleGetOid(htup)); + { + Oid oid = ((Form_pg_statistic_ext) GETSTRUCT(htup))->oid; + + result = lappend_oid(result, oid); + } systable_endscan(indscan); - heap_close(indrel, AccessShareLock); + table_close(indrel, AccessShareLock); + + /* Sort the result list into OID order, per API spec. */ + list_sort(result, list_oid_cmp); /* Now save a copy of the completed list in the relcache entry. */ oldcxt = MemoryContextSwitchTo(CacheMemoryContext); @@ -4587,114 +4527,6 @@ RelationGetStatExtList(Relation relation) return result; } -/* - * insert_ordered_oid - * Insert a new Oid into a sorted list of Oids, preserving ordering - * - * Building the ordered list this way is O(N^2), but with a pretty small - * constant, so for the number of entries we expect it will probably be - * faster than trying to apply qsort(). Most tables don't have very many - * indexes... - */ -static List * -insert_ordered_oid(List *list, Oid datum) -{ - ListCell *prev; - - /* Does the datum belong at the front? */ - if (list == NIL || datum < linitial_oid(list)) - return lcons_oid(datum, list); - /* No, so find the entry it belongs after */ - prev = list_head(list); - for (;;) - { - ListCell *curr = lnext(prev); - - if (curr == NULL || datum < lfirst_oid(curr)) - break; /* it belongs after 'prev', before 'curr' */ - - prev = curr; - } - /* Insert datum into list after 'prev' */ - lappend_cell_oid(list, prev, datum); - return list; -} - -/* - * RelationSetIndexList -- externally force the index list contents - * - * This is used to temporarily override what we think the set of valid - * indexes is (including the presence or absence of an OID index). - * The forcing will be valid only until transaction commit or abort. - * - * This should only be applied to nailed relations, because in a non-nailed - * relation the hacked index list could be lost at any time due to SI - * messages. In practice it is only used on pg_class (see REINDEX). - * - * It is up to the caller to make sure the given list is correctly ordered. - * - * We deliberately do not change rd_indexattr here: even when operating - * with a temporary partial index list, HOT-update decisions must be made - * correctly with respect to the full index set. It is up to the caller - * to ensure that a correct rd_indexattr set has been cached before first - * calling RelationSetIndexList; else a subsequent inquiry might cause a - * wrong rd_indexattr set to get computed and cached. Likewise, we do not - * touch rd_keyattr, rd_pkattr or rd_idattr. - */ -void -RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex) -{ - MemoryContext oldcxt; - - Assert(relation->rd_isnailed); - /* Copy the list into the cache context (could fail for lack of mem) */ - oldcxt = MemoryContextSwitchTo(CacheMemoryContext); - indexIds = list_copy(indexIds); - MemoryContextSwitchTo(oldcxt); - /* Okay to replace old list */ - list_free(relation->rd_indexlist); - relation->rd_indexlist = indexIds; - relation->rd_oidindex = oidIndex; - - /* - * For the moment, assume the target rel hasn't got a pk or replica index. - * We'll load them on demand in the API that wraps access to them. - */ - relation->rd_pkindex = InvalidOid; - relation->rd_replidindex = InvalidOid; - relation->rd_indexvalid = 2; /* mark list as forced */ - /* Flag relation as needing eoxact cleanup (to reset the list) */ - EOXactListAdd(relation); -} - -/* - * RelationGetOidIndex -- get the pg_class OID of the relation's OID index - * - * Returns InvalidOid if there is no such index. - */ -Oid -RelationGetOidIndex(Relation relation) -{ - List *ilist; - - /* - * If relation doesn't have OIDs at all, caller is probably confused. (We - * could just silently return InvalidOid, but it seems better to throw an - * assertion.) - */ - Assert(relation->rd_rel->relhasoids); - - if (relation->rd_indexvalid == 0) - { - /* RelationGetIndexList does the heavy lifting. */ - ilist = RelationGetIndexList(relation); - list_free(ilist); - Assert(relation->rd_indexvalid != 0); - } - - return relation->rd_oidindex; -} - /* * RelationGetPrimaryKeyIndex -- get OID of the relation's primary key index * @@ -4705,12 +4537,12 @@ RelationGetPrimaryKeyIndex(Relation relation) { List *ilist; - if (relation->rd_indexvalid == 0) + if (!relation->rd_indexvalid) { /* RelationGetIndexList does the heavy lifting. */ ilist = RelationGetIndexList(relation); list_free(ilist); - Assert(relation->rd_indexvalid != 0); + Assert(relation->rd_indexvalid); } return relation->rd_pkindex; @@ -4726,12 +4558,12 @@ RelationGetReplicaIndex(Relation relation) { List *ilist; - if (relation->rd_indexvalid == 0) + if (!relation->rd_indexvalid) { /* RelationGetIndexList does the heavy lifting. */ ilist = RelationGetIndexList(relation); list_free(ilist); - Assert(relation->rd_indexvalid != 0); + Assert(relation->rd_indexvalid); } return relation->rd_replidindex; @@ -4867,73 +4699,6 @@ RelationGetIndexPredicate(Relation relation) return result; } -#define HEURISTIC_MAX_HOT_RECHECK_EXPR_COST 1000 - -/* - * Check if functional index is projection: index expression returns some subset - * of its argument values. During HOT update check we handle projection indexes - * differently: instead of checking if any of attributes used in indexed - * expression were updated, we calculate and compare values of index expression - * for old and new tuple values. - * - * Decision made by this function is based on two sources: - * 1. Calculated cost of index expression: if greater than some heuristic limit - then extra comparison of index expression values is expected to be too - expensive, so we don't attempt it by default. - * 2. "recheck_on_update" index option explicitly set by user, which overrides 1) - */ -static bool IsProjectionFunctionalIndex(Relation index, IndexInfo* ii) -{ - bool is_projection = false; - - if (ii->ii_Expressions) - { - HeapTuple tuple; - Datum reloptions; - bool isnull; - QualCost index_expr_cost; - - /* by default functional index is considered as non-injective */ - is_projection = true; - - cost_qual_eval(&index_expr_cost, ii->ii_Expressions, NULL); - - /* - * If index expression is too expensive, then disable projection - * optimization, because extra evaluation of index expression is - * expected to be more expensive than index update. Currently the - * projection optimization has to calculate index expression twice - * when the value of index expression has not changed and three times - * when values differ because the expression is recalculated when - * inserting a new index entry for the changed value. - */ - if ((index_expr_cost.startup + index_expr_cost.per_tuple) > - HEURISTIC_MAX_HOT_RECHECK_EXPR_COST) - is_projection = false; - - tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(RelationGetRelid(index))); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for relation %u", RelationGetRelid(index)); - - reloptions = SysCacheGetAttr(RELOID, tuple, - Anum_pg_class_reloptions, &isnull); - if (!isnull) - { - GenericIndexOpts *idxopts; - - idxopts = (GenericIndexOpts *) index_generic_reloptions(reloptions, false); - - if (idxopts != NULL) - { - is_projection = idxopts->recheck_on_update; - pfree(idxopts); - } - } - ReleaseSysCache(tuple); - } - return is_projection; -} - /* * RelationGetIndexAttrBitmap -- get a bitmap of index attribute numbers * @@ -4961,29 +4726,24 @@ static bool IsProjectionFunctionalIndex(Relation index, IndexInfo* ii) Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) { - Bitmapset *indexattrs; /* columns used in non-projection indexes */ - Bitmapset *projindexattrs; /* columns used in projection indexes */ + Bitmapset *indexattrs; /* indexed columns */ Bitmapset *uindexattrs; /* columns in unique indexes */ Bitmapset *pkindexattrs; /* columns in the primary index */ Bitmapset *idindexattrs; /* columns in the replica identity */ - Bitmapset *projindexes; /* projection indexes */ List *indexoidlist; List *newindexoidlist; Oid relpkindex; Oid relreplindex; ListCell *l; MemoryContext oldcxt; - int indexno; /* Quick exit if we already computed the result. */ if (relation->rd_indexattr != NULL) { switch (attrKind) { - case INDEX_ATTR_BITMAP_HOT: + case INDEX_ATTR_BITMAP_ALL: return bms_copy(relation->rd_indexattr); - case INDEX_ATTR_BITMAP_PROJ: - return bms_copy(relation->rd_projindexattr); case INDEX_ATTR_BITMAP_KEY: return bms_copy(relation->rd_keyattr); case INDEX_ATTR_BITMAP_PRIMARY_KEY: @@ -5030,17 +4790,17 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) * won't be returned at all by RelationGetIndexList. */ indexattrs = NULL; - projindexattrs = NULL; uindexattrs = NULL; pkindexattrs = NULL; idindexattrs = NULL; - projindexes = NULL; - indexno = 0; foreach(l, indexoidlist) { Oid indexOid = lfirst_oid(l); Relation indexDesc; - IndexInfo *indexInfo; + Datum datum; + bool isnull; + Node *indexExpressions; + Node *indexPredicate; int i; bool isKey; /* candidate key */ bool isPK; /* primary key */ @@ -5048,13 +4808,33 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) indexDesc = index_open(indexOid, AccessShareLock); - /* Extract index key information from the index's pg_index row */ - indexInfo = BuildIndexInfo(indexDesc); + /* + * Extract index expressions and index predicate. Note: Don't use + * RelationGetIndexExpressions()/RelationGetIndexPredicate(), because + * those might run constant expressions evaluation, which needs a + * snapshot, which we might not have here. (Also, it's probably more + * sound to collect the bitmaps before any transformations that might + * eliminate columns, but the practical impact of this is limited.) + */ + + datum = heap_getattr(indexDesc->rd_indextuple, Anum_pg_index_indexprs, + GetPgIndexDescriptor(), &isnull); + if (!isnull) + indexExpressions = stringToNode(TextDatumGetCString(datum)); + else + indexExpressions = NULL; + + datum = heap_getattr(indexDesc->rd_indextuple, Anum_pg_index_indpred, + GetPgIndexDescriptor(), &isnull); + if (!isnull) + indexPredicate = stringToNode(TextDatumGetCString(datum)); + else + indexPredicate = NULL; /* Can this index be referenced by a foreign key? */ - isKey = indexInfo->ii_Unique && - indexInfo->ii_Expressions == NIL && - indexInfo->ii_Predicate == NIL; + isKey = indexDesc->rd_index->indisunique && + indexExpressions == NULL && + indexPredicate == NULL; /* Is this a primary key? */ isPK = (indexOid == relpkindex); @@ -5063,9 +4843,9 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) isIDKey = (indexOid == relreplindex); /* Collect simple attribute references */ - for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++) + for (i = 0; i < indexDesc->rd_index->indnatts; i++) { - int attrnum = indexInfo->ii_KeyAttrNumbers[i]; + int attrnum = indexDesc->rd_index->indkey.values[i]; /* * Since we have covering indexes with non-key columns, we must @@ -5080,36 +4860,27 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) indexattrs = bms_add_member(indexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isKey && i < indexInfo->ii_NumIndexKeyAttrs) + if (isKey && i < indexDesc->rd_index->indnkeyatts) uindexattrs = bms_add_member(uindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isPK && i < indexInfo->ii_NumIndexKeyAttrs) + if (isPK && i < indexDesc->rd_index->indnkeyatts) pkindexattrs = bms_add_member(pkindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); - if (isIDKey && i < indexInfo->ii_NumIndexKeyAttrs) + if (isIDKey && i < indexDesc->rd_index->indnkeyatts) idindexattrs = bms_add_member(idindexattrs, attrnum - FirstLowInvalidHeapAttributeNumber); } } - /* Collect attributes used in expressions, too */ - if (IsProjectionFunctionalIndex(indexDesc, indexInfo)) - { - projindexes = bms_add_member(projindexes, indexno); - pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &projindexattrs); - } - else - { - /* Collect all attributes used in expressions, too */ - pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &indexattrs); - } + /* Collect all attributes used in expressions, too */ + pull_varattnos(indexExpressions, 1, &indexattrs); + /* Collect all attributes in the index predicate, too */ - pull_varattnos((Node *) indexInfo->ii_Predicate, 1, &indexattrs); + pull_varattnos(indexPredicate, 1, &indexattrs); index_close(indexDesc, AccessShareLock); - indexno += 1; } /* @@ -5136,8 +4907,6 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) bms_free(pkindexattrs); bms_free(idindexattrs); bms_free(indexattrs); - bms_free(projindexattrs); - bms_free(projindexes); goto restart; } @@ -5145,16 +4914,12 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) /* Don't leak the old values of these bitmaps, if any */ bms_free(relation->rd_indexattr); relation->rd_indexattr = NULL; - bms_free(relation->rd_projindexattr); - relation->rd_projindexattr = NULL; bms_free(relation->rd_keyattr); relation->rd_keyattr = NULL; bms_free(relation->rd_pkattr); relation->rd_pkattr = NULL; bms_free(relation->rd_idattr); relation->rd_idattr = NULL; - bms_free(relation->rd_projidx); - relation->rd_projidx = NULL; /* * Now save copies of the bitmaps in the relcache entry. We intentionally @@ -5168,21 +4933,17 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) relation->rd_pkattr = bms_copy(pkindexattrs); relation->rd_idattr = bms_copy(idindexattrs); relation->rd_indexattr = bms_copy(indexattrs); - relation->rd_projindexattr = bms_copy(projindexattrs); - relation->rd_projidx = bms_copy(projindexes); MemoryContextSwitchTo(oldcxt); /* We return our original working copy for caller to play with */ switch (attrKind) { - case INDEX_ATTR_BITMAP_HOT: + case INDEX_ATTR_BITMAP_ALL: return indexattrs; - case INDEX_ATTR_BITMAP_PROJ: - return projindexattrs; case INDEX_ATTR_BITMAP_KEY: return uindexattrs; case INDEX_ATTR_BITMAP_PRIMARY_KEY: - return bms_copy(relation->rd_pkattr); + return pkindexattrs; case INDEX_ATTR_BITMAP_IDENTITY_KEY: return idindexattrs; default: @@ -5238,14 +4999,18 @@ RelationGetExclusionInfo(Relation indexRelation, * Search pg_constraint for the constraint associated with the index. To * make this not too painfully slow, we use the index on conrelid; that * will hold the parent relation's OID not the index's own OID. + * + * Note: if we wanted to rely on the constraint name matching the index's + * name, we could just do a direct lookup using pg_constraint's unique + * index. For the moment it doesn't seem worth requiring that. */ ScanKeyInit(&skey[0], Anum_pg_constraint_conrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(indexRelation->rd_index->indrelid)); - conrel = heap_open(ConstraintRelationId, AccessShareLock); - conscan = systable_beginscan(conrel, ConstraintRelidIndexId, true, + conrel = table_open(ConstraintRelationId, AccessShareLock); + conscan = systable_beginscan(conrel, ConstraintRelidTypidNameIndexId, true, NULL, 1, skey); found = false; @@ -5288,7 +5053,7 @@ RelationGetExclusionInfo(Relation indexRelation, } systable_endscan(conscan); - heap_close(conrel, AccessShareLock); + table_close(conrel, AccessShareLock); if (!found) elog(ERROR, "exclusion constraint record missing for rel %s", @@ -5328,6 +5093,13 @@ GetRelationPublicationActions(Relation relation) MemoryContext oldcxt; PublicationActions *pubactions = palloc0(sizeof(PublicationActions)); + /* + * If not publishable, it publishes no actions. (pgoutput_change() will + * ignore it.) + */ + if (!is_publishable_relation(relation)) + return pubactions; + if (relation->rd_pubactions) return memcpy(pubactions, relation->rd_pubactions, sizeof(PublicationActions)); @@ -5596,8 +5368,7 @@ load_relcache_init_file(bool shared) rel->rd_rel = relform; /* initialize attribute tuple forms */ - rel->rd_att = CreateTemplateTupleDesc(relform->relnatts, - relform->relhasoids); + rel->rd_att = CreateTemplateTupleDesc(relform->relnatts); rel->rd_att->tdrefcount = 1; /* mark as refcounted */ rel->rd_att->tdtypeid = relform->reltype; @@ -5683,7 +5454,7 @@ load_relcache_init_file(bool shared) ALLOCSET_SMALL_SIZES); rel->rd_indexcxt = indexcxt; MemoryContextCopyAndSetIdentifier(indexcxt, - RelationGetRelationName(rel)); + RelationGetRelationName(rel)); /* * Now we can fetch the index AM's API struct. (We can't store @@ -5743,7 +5514,7 @@ load_relcache_init_file(bool shared) rel->rd_indoption = indoption; /* set up zeroed fmgr-info vector */ - nsupport = relform->relnatts * rel->rd_amroutine->amsupport; + nsupport = relform->relnatts * rel->rd_indam->amsupport; rel->rd_supportinfo = (FmgrInfo *) MemoryContextAllocZero(indexcxt, nsupport * sizeof(FmgrInfo)); } @@ -5753,10 +5524,17 @@ load_relcache_init_file(bool shared) if (rel->rd_isnailed) nailed_rels++; + /* Load table AM data */ + if (rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_SEQUENCE || + rel->rd_rel->relkind == RELKIND_TOASTVALUE || + rel->rd_rel->relkind == RELKIND_MATVIEW) + RelationInitTableAccessMethod(rel); + Assert(rel->rd_index == NULL); Assert(rel->rd_indextuple == NULL); Assert(rel->rd_indexcxt == NULL); - Assert(rel->rd_amroutine == NULL); + Assert(rel->rd_indam == NULL); Assert(rel->rd_opfamily == NULL); Assert(rel->rd_opcintype == NULL); Assert(rel->rd_support == NULL); @@ -5770,18 +5548,20 @@ load_relcache_init_file(bool shared) * format is complex and subject to change). They must be rebuilt if * needed by RelationCacheInitializePhase3. This is not expected to * be a big performance hit since few system catalogs have such. Ditto - * for RLS policy data, index expressions, predicates, exclusion info, - * and FDW info. + * for RLS policy data, partition info, index expressions, predicates, + * exclusion info, and FDW info. */ rel->rd_rules = NULL; rel->rd_rulescxt = NULL; rel->trigdesc = NULL; rel->rd_rsdesc = NULL; - rel->rd_partkeycxt = NULL; rel->rd_partkey = NULL; - rel->rd_pdcxt = NULL; + rel->rd_partkeycxt = NULL; rel->rd_partdesc = NULL; + rel->rd_pdcxt = NULL; rel->rd_partcheck = NIL; + rel->rd_partcheckvalid = false; + rel->rd_partcheckcxt = NULL; rel->rd_indexprs = NIL; rel->rd_indpred = NIL; rel->rd_exclops = NULL; @@ -5797,22 +5577,19 @@ load_relcache_init_file(bool shared) rel->rd_refcnt = 1; else rel->rd_refcnt = 0; - rel->rd_indexvalid = 0; - rel->rd_fkeylist = NIL; - rel->rd_fkeyvalid = false; + rel->rd_indexvalid = false; rel->rd_indexlist = NIL; - rel->rd_oidindex = InvalidOid; rel->rd_pkindex = InvalidOid; rel->rd_replidindex = InvalidOid; rel->rd_indexattr = NULL; - rel->rd_projindexattr = NULL; rel->rd_keyattr = NULL; rel->rd_pkattr = NULL; rel->rd_idattr = NULL; - rel->rd_projidx = NULL; rel->rd_pubactions = NULL; rel->rd_statvalid = false; rel->rd_statlist = NIL; + rel->rd_fkeyvalid = false; + rel->rd_fkeylist = NIL; rel->rd_createSubid = InvalidSubTransactionId; rel->rd_newRelfilenodeSubid = InvalidSubTransactionId; rel->rd_amcache = NULL; @@ -6037,7 +5814,7 @@ write_relcache_init_file(bool shared) /* next, write the vector of support procedure OIDs */ write_item(rel->rd_support, - relform->relnatts * (rel->rd_amroutine->amsupport * sizeof(RegProcedure)), + relform->relnatts * (rel->rd_indam->amsupport * sizeof(RegProcedure)), fp); /* next, write the vector of collation OIDs */ @@ -6110,72 +5887,32 @@ write_item(const void *data, Size len, FILE *fp) /* * Determine whether a given relation (identified by OID) is one of the ones - * we should store in the local relcache init file. + * we should store in a relcache init file. * * We must cache all nailed rels, and for efficiency we should cache every rel * that supports a syscache. The former set is almost but not quite a subset - * of the latter. Currently, we must special-case TriggerRelidNameIndexId, - * which RelationCacheInitializePhase3 chooses to nail for efficiency reasons, - * but which does not support any syscache. - * - * Note: this function is currently never called for shared rels. If it were, - * we'd probably also need a special case for DatabaseNameIndexId, which is - * critical but does not support a syscache. + * of the latter. The special cases are relations where + * RelationCacheInitializePhase2/3 chooses to nail for efficiency reasons, but + * which do not support any syscache. */ bool RelationIdIsInInitFile(Oid relationId) { - if (relationId == TriggerRelidNameIndexId) + if (relationId == SharedSecLabelRelationId || + relationId == TriggerRelidNameIndexId || + relationId == DatabaseNameIndexId || + relationId == SharedSecLabelObjectIndexId) { - /* If this Assert fails, we don't need this special case anymore. */ + /* + * If this Assert fails, we don't need the applicable special case + * anymore. + */ Assert(!RelationSupportsSysCache(relationId)); return true; } return RelationSupportsSysCache(relationId); } -/* - * Tells whether any index for the relation is unlogged. - * - * Note: There doesn't seem to be any way to have an unlogged index attached - * to a permanent table, but it seems best to keep this general so that it - * returns sensible results even when they seem obvious (like for an unlogged - * table) and to handle possible future unlogged indexes on permanent tables. - */ -bool -RelationHasUnloggedIndex(Relation rel) -{ - List *indexoidlist; - ListCell *indexoidscan; - bool result = false; - - indexoidlist = RelationGetIndexList(rel); - - foreach(indexoidscan, indexoidlist) - { - Oid indexoid = lfirst_oid(indexoidscan); - HeapTuple tp; - Form_pg_class reltup; - - tp = SearchSysCache1(RELOID, ObjectIdGetDatum(indexoid)); - if (!HeapTupleIsValid(tp)) - elog(ERROR, "cache lookup failed for relation %u", indexoid); - reltup = (Form_pg_class) GETSTRUCT(tp); - - if (reltup->relpersistence == RELPERSISTENCE_UNLOGGED) - result = true; - - ReleaseSysCache(tp); - - if (result == true) - break; - } - - list_free(indexoidlist); - - return result; -} - /* * Invalidate (remove) the init file during commit of a transaction that * changed one or more of the relation cache entries that are kept in the @@ -6197,38 +5934,30 @@ RelationHasUnloggedIndex(Relation rel) * We take the lock and do the unlink in RelationCacheInitFilePreInvalidate, * then release the lock in RelationCacheInitFilePostInvalidate. Caller must * send any pending SI messages between those calls. - * - * Notice this deals only with the local init file, not the shared init file. - * The reason is that there can never be a "significant" change to the - * relcache entry of a shared relation; the most that could happen is - * updates of noncritical fields such as relpages/reltuples. So, while - * it's worth updating the shared init file from time to time, it can never - * be invalid enough to make it necessary to remove it. */ void RelationCacheInitFilePreInvalidate(void) { - char initfilename[MAXPGPATH]; + char localinitfname[MAXPGPATH]; + char sharedinitfname[MAXPGPATH]; - snprintf(initfilename, sizeof(initfilename), "%s/%s", - DatabasePath, RELCACHE_INIT_FILENAME); + if (DatabasePath) + snprintf(localinitfname, sizeof(localinitfname), "%s/%s", + DatabasePath, RELCACHE_INIT_FILENAME); + snprintf(sharedinitfname, sizeof(sharedinitfname), "global/%s", + RELCACHE_INIT_FILENAME); LWLockAcquire(RelCacheInitLock, LW_EXCLUSIVE); - if (unlink(initfilename) < 0) - { - /* - * The file might not be there if no backend has been started since - * the last removal. But complain about failures other than ENOENT. - * Fortunately, it's not too late to abort the transaction if we can't - * get rid of the would-be-obsolete init file. - */ - if (errno != ENOENT) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not remove cache file \"%s\": %m", - initfilename))); - } + /* + * The files might not be there if no backend has been started since the + * last removal. But complain about failures other than ENOENT with + * ERROR. Fortunately, it's not too late to abort the transaction if we + * can't get rid of the would-be-obsolete init file. + */ + if (DatabasePath) + unlink_initfile(localinitfname, ERROR); + unlink_initfile(sharedinitfname, ERROR); } void @@ -6254,13 +5983,9 @@ RelationCacheInitFileRemove(void) struct dirent *de; char path[MAXPGPATH + 10 + sizeof(TABLESPACE_VERSION_DIRECTORY)]; - /* - * We zap the shared cache file too. In theory it can't get out of sync - * enough to be a problem, but in data-corruption cases, who knows ... - */ snprintf(path, sizeof(path), "global/%s", RELCACHE_INIT_FILENAME); - unlink_initfile(path); + unlink_initfile(path, LOG); /* Scan everything in the default tablespace */ RelationCacheInitFileRemoveInDir("base"); @@ -6300,7 +6025,7 @@ RelationCacheInitFileRemoveInDir(const char *tblspcpath) /* Try to remove the init file in each database */ snprintf(initfilename, sizeof(initfilename), "%s/%s/%s", tblspcpath, de->d_name, RELCACHE_INIT_FILENAME); - unlink_initfile(initfilename); + unlink_initfile(initfilename, LOG); } } @@ -6308,12 +6033,15 @@ RelationCacheInitFileRemoveInDir(const char *tblspcpath) } static void -unlink_initfile(const char *initfilename) +unlink_initfile(const char *initfilename, int elevel) { if (unlink(initfilename) < 0) { /* It might not be there, but log any error other than ENOENT */ if (errno != ENOENT) - elog(LOG, "could not remove cache file \"%s\": %m", initfilename); + ereport(elevel, + (errcode_for_file_access(), + errmsg("could not remove cache file \"%s\": %m", + initfilename))); } } diff --git a/src/backend/utils/cache/relfilenodemap.c b/src/backend/utils/cache/relfilenodemap.c index db6bb1c1fd4..c506dc9dec4 100644 --- a/src/backend/utils/cache/relfilenodemap.c +++ b/src/backend/utils/cache/relfilenodemap.c @@ -3,19 +3,19 @@ * relfilenodemap.c * relfilenode to oid mapping cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * src/backend/utils/cache/relfilenode.c + * src/backend/utils/cache/relfilenodemap.c * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_class.h" #include "catalog/pg_tablespace.h" @@ -29,7 +29,7 @@ #include "utils/relfilenodemap.h" #include "utils/relmapper.h" -/* Hash table for informations about each relfilenode <-> oid pair */ +/* Hash table for information about each relfilenode <-> oid pair */ static HTAB *RelfilenodeMapHash = NULL; /* built first time through in InitializeRelfilenodeMap */ @@ -192,7 +192,7 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode) */ /* check for plain relations by looking in pg_class */ - relation = heap_open(RelationRelationId, AccessShareLock); + relation = table_open(RelationRelationId, AccessShareLock); /* copy scankey to local copy, it will be modified during the scan */ memcpy(skey, relfilenode_skey, sizeof(skey)); @@ -212,33 +212,21 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode) while (HeapTupleIsValid(ntp = systable_getnext(scandesc))) { + Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp); + if (found) elog(ERROR, "unexpected duplicate for tablespace %u, relfilenode %u", reltablespace, relfilenode); found = true; -#ifdef USE_ASSERT_CHECKING - { - bool isnull; - Oid check; - - check = fastgetattr(ntp, Anum_pg_class_reltablespace, - RelationGetDescr(relation), - &isnull); - Assert(!isnull && check == reltablespace); - - check = fastgetattr(ntp, Anum_pg_class_relfilenode, - RelationGetDescr(relation), - &isnull); - Assert(!isnull && check == relfilenode); - } -#endif - relid = HeapTupleGetOid(ntp); + Assert(classform->reltablespace == reltablespace); + Assert(classform->relfilenode == relfilenode); + relid = classform->oid; } systable_endscan(scandesc); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); /* check for tables that are mapped but not shared */ if (!found) diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c index 99d095f2df3..42b0c48c2be 100644 --- a/src/backend/utils/cache/relmapper.c +++ b/src/backend/utils/cache/relmapper.c @@ -28,7 +28,7 @@ * all these files commit in a single map file update rather than being tied * to transaction commit. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -91,6 +91,16 @@ typedef struct RelMapFile int32 pad; /* to make the struct size be 512 exactly */ } RelMapFile; +/* + * State for serializing local and shared relmappings for parallel workers + * (active states only). See notes on active_* and pending_* updates state. + */ +typedef struct SerializedActiveRelMaps +{ + RelMapFile active_shared_updates; + RelMapFile active_local_updates; +} SerializedActiveRelMaps; + /* * The currently known contents of the shared map file and our database's * local map file are stored here. These can be reloaded from disk @@ -111,6 +121,9 @@ static RelMapFile local_map; * they will become active at the next CommandCounterIncrement. This setup * lets map updates act similarly to updates of pg_class rows, ie, they * become visible only at the next CommandCounterIncrement boundary. + * + * Active shared and active local updates are serialized by the parallel + * infrastructure, and deserialized within parallel workers. */ static RelMapFile active_shared_updates; static RelMapFile active_local_updates; @@ -120,13 +133,13 @@ static RelMapFile pending_local_updates; /* non-export function prototypes */ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode, - bool add_okay); + bool add_okay); static void merge_map_updates(RelMapFile *map, const RelMapFile *updates, - bool add_okay); + bool add_okay); static void load_relmap_file(bool shared); static void write_relmap_file(bool shared, RelMapFile *newmap, - bool write_wal, bool send_sinval, bool preserve_files, - Oid dbid, Oid tsid, const char *dbpath); + bool write_wal, bool send_sinval, bool preserve_files, + Oid dbid, Oid tsid, const char *dbpath); static void perform_relmap_update(bool shared, const RelMapFile *updates); @@ -263,13 +276,16 @@ RelationMapUpdateMap(Oid relationId, Oid fileNode, bool shared, else { /* - * We don't currently support map changes within subtransactions. This - * could be done with more bookkeeping infrastructure, but it doesn't - * presently seem worth it. + * We don't currently support map changes within subtransactions, or + * when in parallel mode. This could be done with more bookkeeping + * infrastructure, but it doesn't presently seem worth it. */ if (GetCurrentTransactionNestLevel() > 1) elog(ERROR, "cannot change relation mapping within subtransaction"); + if (IsInParallelMode()) + elog(ERROR, "cannot change relation mapping in parallel mode"); + if (immediate) { /* Make it active, but only locally */ @@ -452,11 +468,14 @@ AtCCI_RelationMap(void) * * During abort, we just have to throw away any pending map changes. * Normal post-abort cleanup will take care of fixing relcache entries. + * Parallel worker commit/abort is handled by resetting active mappings + * that may have been received from the leader process. (There should be + * no pending updates in parallel workers.) */ void -AtEOXact_RelationMap(bool isCommit) +AtEOXact_RelationMap(bool isCommit, bool isParallelWorker) { - if (isCommit) + if (isCommit && !isParallelWorker) { /* * We should not get here with any "pending" updates. (We could @@ -482,7 +501,10 @@ AtEOXact_RelationMap(bool isCommit) } else { - /* Abort --- drop all local and pending updates */ + /* Abort or parallel worker --- drop all local and pending updates */ + Assert(!isParallelWorker || pending_shared_updates.num_mappings == 0); + Assert(!isParallelWorker || pending_local_updates.num_mappings == 0); + active_shared_updates.num_mappings = 0; active_local_updates.num_mappings = 0; pending_shared_updates.num_mappings = 0; @@ -614,6 +636,56 @@ RelationMapInitializePhase3(void) load_relmap_file(false); } +/* + * EstimateRelationMapSpace + * + * Estimate space needed to pass active shared and local relmaps to parallel + * workers. + */ +Size +EstimateRelationMapSpace(void) +{ + return sizeof(SerializedActiveRelMaps); +} + +/* + * SerializeRelationMap + * + * Serialize active shared and local relmap state for parallel workers. + */ +void +SerializeRelationMap(Size maxSize, char *startAddress) +{ + SerializedActiveRelMaps *relmaps; + + Assert(maxSize >= EstimateRelationMapSpace()); + + relmaps = (SerializedActiveRelMaps *) startAddress; + relmaps->active_shared_updates = active_shared_updates; + relmaps->active_local_updates = active_local_updates; +} + +/* + * RestoreRelationMap + * + * Restore active shared and local relmap state within a parallel worker. + */ +void +RestoreRelationMap(char *startAddress) +{ + SerializedActiveRelMaps *relmaps; + + if (active_shared_updates.num_mappings != 0 || + active_local_updates.num_mappings != 0 || + pending_shared_updates.num_mappings != 0 || + pending_local_updates.num_mappings != 0) + elog(ERROR, "parallel worker has existing mappings"); + + relmaps = (SerializedActiveRelMaps *) startAddress; + active_shared_updates = relmaps->active_shared_updates; + active_local_updates = relmaps->active_local_updates; +} + /* * load_relmap_file -- load data from the shared or local map file * @@ -629,6 +701,7 @@ load_relmap_file(bool shared) char mapfilename[MAXPGPATH]; pg_crc32c crc; int fd; + int r; if (shared) { @@ -648,7 +721,7 @@ load_relmap_file(bool shared) if (fd < 0) ereport(FATAL, (errcode_for_file_access(), - errmsg("could not open relation mapping file \"%s\": %m", + errmsg("could not open file \"%s\": %m", mapfilename))); /* @@ -659,14 +732,26 @@ load_relmap_file(bool shared) * are able to access any relation that's affected by the change. */ pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ); - if (read(fd, map, sizeof(RelMapFile)) != sizeof(RelMapFile)) + r = read(fd, map, sizeof(RelMapFile)); + if (r != sizeof(RelMapFile)) + { + if (r < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", mapfilename))); + else + ereport(FATAL, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + mapfilename, r, sizeof(RelMapFile)))); + } + pgstat_report_wait_end(); + + if (CloseTransientFile(fd) != 0) ereport(FATAL, (errcode_for_file_access(), - errmsg("could not read relation mapping file \"%s\": %m", + errmsg("could not close file \"%s\": %m", mapfilename))); - pgstat_report_wait_end(); - - CloseTransientFile(fd); /* check for correct magic number, etc */ if (map->magic != RELMAPPER_FILEMAGIC || @@ -748,7 +833,7 @@ write_relmap_file(bool shared, RelMapFile *newmap, if (fd < 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not open relation mapping file \"%s\": %m", + errmsg("could not open file \"%s\": %m", mapfilename))); if (write_wal) @@ -782,7 +867,7 @@ write_relmap_file(bool shared, RelMapFile *newmap, errno = ENOSPC; ereport(ERROR, (errcode_for_file_access(), - errmsg("could not write to relation mapping file \"%s\": %m", + errmsg("could not write file \"%s\": %m", mapfilename))); } pgstat_report_wait_end(); @@ -795,16 +880,16 @@ write_relmap_file(bool shared, RelMapFile *newmap, */ pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_SYNC); if (pg_fsync(fd) != 0) - ereport(ERROR, + ereport(data_sync_elevel(ERROR), (errcode_for_file_access(), - errmsg("could not fsync relation mapping file \"%s\": %m", + errmsg("could not fsync file \"%s\": %m", mapfilename))); pgstat_report_wait_end(); - if (CloseTransientFile(fd)) + if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not close relation mapping file \"%s\": %m", + errmsg("could not close file \"%s\": %m", mapfilename))); /* diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c index 3be86576397..6309a017c18 100644 --- a/src/backend/utils/cache/spccache.c +++ b/src/backend/utils/cache/spccache.c @@ -8,7 +8,7 @@ * be a measurable performance gain from doing this, but that might change * in the future as we add more options. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,7 +22,7 @@ #include "catalog/pg_tablespace.h" #include "commands/tablespace.h" #include "miscadmin.h" -#include "optimizer/cost.h" +#include "optimizer/optimizer.h" #include "storage/bufmgr.h" #include "utils/catcache.h" #include "utils/hsearch.h" diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c index 2b381782a32..16297a52a19 100644 --- a/src/backend/utils/cache/syscache.c +++ b/src/backend/utils/cache/syscache.c @@ -3,7 +3,7 @@ * syscache.c * System cache management routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -62,6 +62,7 @@ #include "catalog/pg_replication_origin.h" #include "catalog/pg_statistic.h" #include "catalog/pg_statistic_ext.h" +#include "catalog/pg_statistic_ext_data.h" #include "catalog/pg_subscription.h" #include "catalog/pg_subscription_rel.h" #include "catalog/pg_tablespace.h" @@ -147,7 +148,7 @@ static const struct cachedesc cacheinfo[] = { AmOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_am_oid, 0, 0, 0 @@ -246,7 +247,7 @@ static const struct cachedesc cacheinfo[] = { AuthIdOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_authid_oid, 0, 0, 0 @@ -280,7 +281,7 @@ static const struct cachedesc cacheinfo[] = { OpclassOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_opclass_oid, 0, 0, 0 @@ -302,7 +303,7 @@ static const struct cachedesc cacheinfo[] = { CollationOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_collation_oid, 0, 0, 0 @@ -316,7 +317,7 @@ static const struct cachedesc cacheinfo[] = { Anum_pg_conversion_connamespace, Anum_pg_conversion_conforencoding, Anum_pg_conversion_contoencoding, - ObjectIdAttributeNumber, + Anum_pg_conversion_oid }, 8 }, @@ -335,7 +336,7 @@ static const struct cachedesc cacheinfo[] = { ConstraintOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_constraint_oid, 0, 0, 0 @@ -346,7 +347,7 @@ static const struct cachedesc cacheinfo[] = { ConversionOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_conversion_oid, 0, 0, 0 @@ -357,7 +358,7 @@ static const struct cachedesc cacheinfo[] = { DatabaseOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_database_oid, 0, 0, 0 @@ -379,7 +380,7 @@ static const struct cachedesc cacheinfo[] = { EnumOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_enum_oid, 0, 0, 0 @@ -412,7 +413,7 @@ static const struct cachedesc cacheinfo[] = { EventTriggerOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_event_trigger_oid, 0, 0, 0 @@ -434,7 +435,7 @@ static const struct cachedesc cacheinfo[] = { ForeignDataWrapperOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_foreign_data_wrapper_oid, 0, 0, 0 @@ -456,7 +457,7 @@ static const struct cachedesc cacheinfo[] = { ForeignServerOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_foreign_server_oid, 0, 0, 0 @@ -500,7 +501,7 @@ static const struct cachedesc cacheinfo[] = { LanguageOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_language_oid, 0, 0, 0 @@ -522,7 +523,7 @@ static const struct cachedesc cacheinfo[] = { NamespaceOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_namespace_oid, 0, 0, 0 @@ -544,7 +545,7 @@ static const struct cachedesc cacheinfo[] = { OperatorOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_operator_oid, 0, 0, 0 @@ -566,7 +567,7 @@ static const struct cachedesc cacheinfo[] = { OpfamilyOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_opfamily_oid, 0, 0, 0 @@ -599,7 +600,7 @@ static const struct cachedesc cacheinfo[] = { ProcedureOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_proc_oid, 0, 0, 0 @@ -621,7 +622,7 @@ static const struct cachedesc cacheinfo[] = { PublicationObjectIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_publication_oid, 0, 0, 0 @@ -632,7 +633,7 @@ static const struct cachedesc cacheinfo[] = { PublicationRelObjectIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_publication_rel_oid, 0, 0, 0 @@ -676,7 +677,7 @@ static const struct cachedesc cacheinfo[] = { ClassOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_class_oid, 0, 0, 0 @@ -727,6 +728,17 @@ static const struct cachedesc cacheinfo[] = { }, 32 }, + {StatisticExtDataRelationId, /* STATEXTDATASTXOID */ + StatisticExtDataStxoidIndexId, + 1, + { + Anum_pg_statistic_ext_data_stxoid, + 0, + 0, + 0 + }, + 4 + }, {StatisticExtRelationId, /* STATEXTNAMENSP */ StatisticExtNameIndexId, 2, @@ -742,7 +754,7 @@ static const struct cachedesc cacheinfo[] = { StatisticExtOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_statistic_ext_oid, 0, 0, 0 @@ -775,7 +787,7 @@ static const struct cachedesc cacheinfo[] = { SubscriptionObjectIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_subscription_oid, 0, 0, 0 @@ -797,7 +809,7 @@ static const struct cachedesc cacheinfo[] = { TablespaceOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_tablespace_oid, 0, 0, 0, @@ -808,7 +820,7 @@ static const struct cachedesc cacheinfo[] = { TransformOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_transform_oid, 0, 0, 0, @@ -852,7 +864,7 @@ static const struct cachedesc cacheinfo[] = { TSConfigOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_ts_config_oid, 0, 0, 0 @@ -874,7 +886,7 @@ static const struct cachedesc cacheinfo[] = { TSDictionaryOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_ts_dict_oid, 0, 0, 0 @@ -896,7 +908,7 @@ static const struct cachedesc cacheinfo[] = { TSParserOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_ts_parser_oid, 0, 0, 0 @@ -918,7 +930,7 @@ static const struct cachedesc cacheinfo[] = { TSTemplateOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_ts_template_oid, 0, 0, 0 @@ -940,7 +952,7 @@ static const struct cachedesc cacheinfo[] = { TypeOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_type_oid, 0, 0, 0 @@ -951,7 +963,7 @@ static const struct cachedesc cacheinfo[] = { UserMappingOidIndexId, 1, { - ObjectIdAttributeNumber, + Anum_pg_user_mapping_oid, 0, 0, 0 @@ -1213,24 +1225,29 @@ SearchSysCacheExists(int cacheId, /* * GetSysCacheOid * - * A convenience routine that does SearchSysCache and returns the OID - * of the found tuple, or InvalidOid if no tuple could be found. + * A convenience routine that does SearchSysCache and returns the OID in the + * oidcol column of the found tuple, or InvalidOid if no tuple could be found. * No lock is retained on the syscache entry. */ Oid GetSysCacheOid(int cacheId, + AttrNumber oidcol, Datum key1, Datum key2, Datum key3, Datum key4) { HeapTuple tuple; + bool isNull; Oid result; tuple = SearchSysCache(cacheId, key1, key2, key3, key4); if (!HeapTupleIsValid(tuple)) return InvalidOid; - result = HeapTupleGetOid(tuple); + result = heap_getattr(tuple, oidcol, + SysCache[cacheId]->cc_tupdesc, + &isNull); + Assert(!isNull); /* columns used as oids should never be NULL */ ReleaseSysCache(tuple); return result; } diff --git a/src/backend/utils/cache/ts_cache.c b/src/backend/utils/cache/ts_cache.c index f11cba4cced..68c04d87d51 100644 --- a/src/backend/utils/cache/ts_cache.c +++ b/src/backend/utils/cache/ts_cache.c @@ -17,7 +17,7 @@ * any database access. * * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/cache/ts_cache.c @@ -27,8 +27,8 @@ #include "postgres.h" #include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" +#include "access/table.h" #include "access/xact.h" #include "catalog/indexing.h" #include "catalog/namespace.h" @@ -38,6 +38,7 @@ #include "catalog/pg_ts_parser.h" #include "catalog/pg_ts_template.h" #include "commands/defrem.h" +#include "miscadmin.h" #include "tsearch/ts_cache.h" #include "utils/builtins.h" #include "utils/catcache.h" @@ -47,7 +48,6 @@ #include "utils/memutils.h" #include "utils/regproc.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -481,7 +481,7 @@ lookup_ts_config_cache(Oid cfgId) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(cfgId)); - maprel = heap_open(TSConfigMapRelationId, AccessShareLock); + maprel = table_open(TSConfigMapRelationId, AccessShareLock); mapidx = index_open(TSConfigMapIndexId, AccessShareLock); mapscan = systable_beginscan_ordered(maprel, mapidx, NULL, 1, &mapskey); @@ -522,7 +522,7 @@ lookup_ts_config_cache(Oid cfgId) systable_endscan_ordered(mapscan); index_close(mapidx, AccessShareLock); - heap_close(maprel, AccessShareLock); + table_close(maprel, AccessShareLock); if (ndicts > 0) { @@ -591,10 +591,11 @@ bool check_TSCurrentConfig(char **newval, void **extra, GucSource source) { /* - * If we aren't inside a transaction, we cannot do database access so - * cannot verify the config name. Must accept it on faith. + * If we aren't inside a transaction, or connected to a database, we + * cannot do the catalog accesses necessary to verify the config name. + * Must accept it on faith. */ - if (IsTransactionState()) + if (IsTransactionState() && MyDatabaseId != InvalidOid) { Oid cfgId; HeapTuple tuple; diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c index e38fd16eb09..11920db0d99 100644 --- a/src/backend/utils/cache/typcache.c +++ b/src/backend/utils/cache/typcache.c @@ -30,7 +30,7 @@ * Domain constraint changes are also tracked properly. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -43,11 +43,12 @@ #include #include "access/hash.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/nbtree.h" #include "access/parallel.h" +#include "access/relation.h" #include "access/session.h" +#include "access/table.h" #include "catalog/indexing.h" #include "catalog/pg_am.h" #include "catalog/pg_constraint.h" @@ -58,7 +59,7 @@ #include "commands/defrem.h" #include "executor/executor.h" #include "lib/dshash.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "storage/lwlock.h" #include "utils/builtins.h" #include "utils/catcache.h" @@ -150,7 +151,7 @@ typedef struct RecordCacheEntry /* * To deal with non-anonymous record types that are exchanged by backends - * involved in a parallel query, we also need a shared verion of the above. + * involved in a parallel query, we also need a shared version of the above. */ struct SharedRecordTypmodRegistry { @@ -300,10 +301,10 @@ static void load_enum_cache_data(TypeCacheEntry *tcache); static EnumItem *find_enumitem(TypeCacheEnumData *enumdata, Oid arg); static int enum_oid_cmp(const void *left, const void *right); static void shared_record_typmod_registry_detach(dsm_segment *segment, - Datum datum); + Datum datum); static TupleDesc find_or_make_matching_shared_tupledesc(TupleDesc tupdesc); static dsa_pointer share_tupledesc(dsa_area *area, TupleDesc tupdesc, - uint32 typmod); + uint32 typmod); /* @@ -388,6 +389,7 @@ lookup_type_cache(Oid type_id, int flags) typentry->typtype = typtup->typtype; typentry->typrelid = typtup->typrelid; typentry->typelem = typtup->typelem; + typentry->typcollation = typtup->typcollation; /* If it's a domain, immediately thread it into the domain cache list */ if (typentry->typtype == TYPTYPE_DOMAIN) @@ -913,7 +915,7 @@ load_domaintype_info(TypeCacheEntry *typentry) * constraints for not just this domain, but any ancestor domains, so the * outer loop crawls up the domain stack. */ - conRel = heap_open(ConstraintRelationId, AccessShareLock); + conRel = table_open(ConstraintRelationId, AccessShareLock); for (;;) { @@ -992,7 +994,16 @@ load_domaintype_info(TypeCacheEntry *typentry) check_expr = (Expr *) stringToNode(constring); - /* ExecInitExpr will assume we've planned the expression */ + /* + * Plan the expression, since ExecInitExpr will expect that. + * + * Note: caching the result of expression_planner() is not very + * good practice. Ideally we'd use a CachedExpression here so + * that we would react promptly to, eg, changes in inlined + * functions. However, because we don't support mutable domain + * CHECK constraints, it's not really clear that it's worth the + * extra overhead to do that. + */ check_expr = expression_planner(check_expr); r = makeNode(DomainConstraintState); @@ -1045,7 +1056,7 @@ load_domaintype_info(TypeCacheEntry *typentry) ReleaseSysCache(tup); } - heap_close(conRel, AccessShareLock); + table_close(conRel, AccessShareLock); /* * Only need to add one NOT NULL check regardless of how many domains in @@ -1869,7 +1880,7 @@ assign_record_type_identifier(Oid type_id, int32 typmod) } /* - * Return the amout of shmem required to hold a SharedRecordTypmodRegistry. + * Return the amount of shmem required to hold a SharedRecordTypmodRegistry. * This exists only to avoid exposing private innards of * SharedRecordTypmodRegistry in a header. */ @@ -2105,6 +2116,16 @@ TypeCacheRelCallback(Datum arg, Oid relid) if (--typentry->tupDesc->tdrefcount == 0) FreeTupleDesc(typentry->tupDesc); typentry->tupDesc = NULL; + + /* + * Also clear tupDesc_identifier, so that anything watching + * that will realize that the tupdesc has possibly changed. + * (Alternatively, we could specify that to detect possible + * tupdesc change, one must check for tupDesc != NULL as well + * as tupDesc_identifier being the same as what was previously + * seen. That seems error-prone.) + */ + typentry->tupDesc_identifier = 0; } /* Reset equality/comparison/hashing validity information */ @@ -2336,7 +2357,7 @@ load_enum_cache_data(TypeCacheEntry *tcache) BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(tcache->type_id)); - enum_rel = heap_open(EnumRelationId, AccessShareLock); + enum_rel = table_open(EnumRelationId, AccessShareLock); enum_scan = systable_beginscan(enum_rel, EnumTypIdLabelIndexId, true, NULL, @@ -2351,13 +2372,13 @@ load_enum_cache_data(TypeCacheEntry *tcache) maxitems *= 2; items = (EnumItem *) repalloc(items, sizeof(EnumItem) * maxitems); } - items[numitems].enum_oid = HeapTupleGetOid(enum_tuple); + items[numitems].enum_oid = en->oid; items[numitems].sort_order = en->enumsortorder; numitems++; } systable_endscan(enum_scan); - heap_close(enum_rel, AccessShareLock); + table_close(enum_rel, AccessShareLock); /* Sort the items into OID order */ qsort(items, numitems, sizeof(EnumItem), enum_oid_cmp); diff --git a/src/backend/utils/errcodes.txt b/src/backend/utils/errcodes.txt index 9871d1e7931..2bd283085e3 100644 --- a/src/backend/utils/errcodes.txt +++ b/src/backend/utils/errcodes.txt @@ -2,7 +2,7 @@ # errcodes.txt # PostgreSQL error codes # -# Copyright (c) 2003-2018, PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # # This list serves as the basis for generating source files containing error # codes. It is kept in a common format to make sure all these source files have @@ -18,7 +18,7 @@ # src/pl/tcl/pltclerrcodes.h # the same, for PL/Tcl # -# doc/src/sgml/errcodes-list.sgml +# doc/src/sgml/errcodes-table.sgml # a SGML table of error codes for inclusion in the documentation # # The format of this file is one error code per line, with the following @@ -177,7 +177,7 @@ Section: Class 22 - Data Exception 22P06 E ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER nonstandard_use_of_escape_character 22010 E ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE invalid_indicator_parameter_value 22023 E ERRCODE_INVALID_PARAMETER_VALUE invalid_parameter_value -22013 E ERRCODE_INVALID_PRECEDING_FOLLOWING_SIZE invalid_preceding_following_size +22013 E ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE invalid_preceding_or_following_size 2201B E ERRCODE_INVALID_REGULAR_EXPRESSION invalid_regular_expression 2201W E ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE invalid_row_count_in_limit_clause 2201X E ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE invalid_row_count_in_result_offset_clause @@ -206,6 +206,22 @@ Section: Class 22 - Data Exception 2200N E ERRCODE_INVALID_XML_CONTENT invalid_xml_content 2200S E ERRCODE_INVALID_XML_COMMENT invalid_xml_comment 2200T E ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION invalid_xml_processing_instruction +22030 E ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE duplicate_json_object_key_value +22031 E ERRCODE_INVALID_ARGUMENT_FOR_JSON_DATETIME_FUNCTION invalid_argument_for_json_datetime_function +22032 E ERRCODE_INVALID_JSON_TEXT invalid_json_text +22033 E ERRCODE_INVALID_SQL_JSON_SUBSCRIPT invalid_sql_json_subscript +22034 E ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM more_than_one_sql_json_item +22035 E ERRCODE_NO_SQL_JSON_ITEM no_sql_json_item +22036 E ERRCODE_NON_NUMERIC_SQL_JSON_ITEM non_numeric_sql_json_item +22037 E ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT non_unique_keys_in_a_json_object +22038 E ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED singleton_sql_json_item_required +22039 E ERRCODE_SQL_JSON_ARRAY_NOT_FOUND sql_json_array_not_found +2203A E ERRCODE_SQL_JSON_MEMBER_NOT_FOUND sql_json_member_not_found +2203B E ERRCODE_SQL_JSON_NUMBER_NOT_FOUND sql_json_number_not_found +2203C E ERRCODE_SQL_JSON_OBJECT_NOT_FOUND sql_json_object_not_found +2203D E ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS too_many_json_array_elements +2203E E ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS too_many_json_object_members +2203F E ERRCODE_SQL_JSON_SCALAR_REQUIRED sql_json_scalar_required Section: Class 23 - Integrity Constraint Violation @@ -401,6 +417,7 @@ Section: Class 55 - Object Not In Prerequisite State 55006 E ERRCODE_OBJECT_IN_USE object_in_use 55P02 E ERRCODE_CANT_CHANGE_RUNTIME_PARAM cant_change_runtime_param 55P03 E ERRCODE_LOCK_NOT_AVAILABLE lock_not_available +55P04 E ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE unsafe_new_enum_value_usage Section: Class 57 - Operator Intervention diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c index 115dbf692cc..2050b4355d1 100644 --- a/src/backend/utils/error/assert.c +++ b/src/backend/utils/error/assert.c @@ -3,7 +3,7 @@ * assert.c * Assert code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 16531f7a0f1..8b4720ef3ab 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -43,7 +43,7 @@ * overflow.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -177,9 +177,6 @@ static void write_csvlog(ErrorData *edata); static void send_message_to_server_log(ErrorData *edata); static void write_pipe_chunks(char *data, int len, int dest); static void send_message_to_frontend(ErrorData *edata); -static char *expand_fmt_string(const char *fmt, ErrorData *edata); -static const char *useful_strerror(int errnum); -static const char *get_errno_symbol(int errnum); static const char *error_severity(int elevel); static void append_with_tabs(StringInfo buf, const char *str); static bool is_log_level_output(int elevel, int log_min_level); @@ -472,9 +469,7 @@ errfinish(int dummy,...) * progress, so that we can report the message before dying. (Without * this, pq_putmessage will refuse to send the message at all, which is * what we want for NOTICE messages, but not for fatal exits.) This hack - * is necessary because of poor design of old-style copy protocol. Note - * we must do this even if client is fool enough to have set - * client_min_messages above FATAL, so don't look at output_to_client. + * is necessary because of poor design of old-style copy protocol. */ if (elevel >= FATAL && whereToSendOutput == DestRemote) pq_endcopyout(true); @@ -707,13 +702,10 @@ errcode_for_socket_access(void) */ #define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit) \ { \ - char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ if ((translateit) && !in_error_recursion_trouble()) \ fmt = dgettext((domain), fmt); \ - /* Expand %m in format string */ \ - fmtbuf = expand_fmt_string(fmt, edata); \ initStringInfo(&buf); \ if ((appendval) && edata->targetfield) { \ appendStringInfoString(&buf, edata->targetfield); \ @@ -724,15 +716,14 @@ errcode_for_socket_access(void) { \ va_list args; \ int needed; \ + errno = edata->saved_errno; \ va_start(args, fmt); \ - needed = appendStringInfoVA(&buf, fmtbuf, args); \ + needed = appendStringInfoVA(&buf, fmt, args); \ va_end(args); \ if (needed == 0) \ break; \ enlargeStringInfo(&buf, needed); \ } \ - /* Done with expanded fmt */ \ - pfree(fmtbuf); \ /* Save the completed message into the stack item */ \ if (edata->targetfield) \ pfree(edata->targetfield); \ @@ -748,15 +739,12 @@ errcode_for_socket_access(void) #define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval) \ { \ const char *fmt; \ - char *fmtbuf; \ StringInfoData buf; \ /* Internationalize the error format string */ \ if (!in_error_recursion_trouble()) \ fmt = dngettext((domain), fmt_singular, fmt_plural, n); \ else \ fmt = (n == 1 ? fmt_singular : fmt_plural); \ - /* Expand %m in format string */ \ - fmtbuf = expand_fmt_string(fmt, edata); \ initStringInfo(&buf); \ if ((appendval) && edata->targetfield) { \ appendStringInfoString(&buf, edata->targetfield); \ @@ -767,15 +755,14 @@ errcode_for_socket_access(void) { \ va_list args; \ int needed; \ + errno = edata->saved_errno; \ va_start(args, n); \ - needed = appendStringInfoVA(&buf, fmtbuf, args); \ + needed = appendStringInfoVA(&buf, fmt, args); \ va_end(args); \ if (needed == 0) \ break; \ enlargeStringInfo(&buf, needed); \ } \ - /* Done with expanded fmt */ \ - pfree(fmtbuf); \ /* Save the completed message into the stack item */ \ if (edata->targetfield) \ pfree(edata->targetfield); \ @@ -1758,12 +1745,7 @@ pg_re_throw(void) else edata->output_to_server = (FATAL >= log_min_messages); if (whereToSendOutput == DestRemote) - { - if (ClientAuthInProgress) - edata->output_to_client = true; - else - edata->output_to_client = (FATAL >= client_min_messages); - } + edata->output_to_client = true; /* * We can use errfinish() for the rest, but we don't want it to call @@ -3330,272 +3312,6 @@ send_message_to_frontend(ErrorData *edata) */ -/* - * expand_fmt_string --- process special format codes in a format string - * - * We must replace %m with the appropriate strerror string, since vsnprintf - * won't know what to do with it. - * - * The result is a palloc'd string. - */ -static char * -expand_fmt_string(const char *fmt, ErrorData *edata) -{ - StringInfoData buf; - const char *cp; - - initStringInfo(&buf); - - for (cp = fmt; *cp; cp++) - { - if (cp[0] == '%' && cp[1] != '\0') - { - cp++; - if (*cp == 'm') - { - /* - * Replace %m by system error string. If there are any %'s in - * the string, we'd better double them so that vsnprintf won't - * misinterpret. - */ - const char *cp2; - - cp2 = useful_strerror(edata->saved_errno); - for (; *cp2; cp2++) - { - if (*cp2 == '%') - appendStringInfoCharMacro(&buf, '%'); - appendStringInfoCharMacro(&buf, *cp2); - } - } - else - { - /* copy % and next char --- this avoids trouble with %%m */ - appendStringInfoCharMacro(&buf, '%'); - appendStringInfoCharMacro(&buf, *cp); - } - } - else - appendStringInfoCharMacro(&buf, *cp); - } - - return buf.data; -} - - -/* - * A slightly cleaned-up version of strerror() - */ -static const char * -useful_strerror(int errnum) -{ - /* this buffer is only used if strerror() and get_errno_symbol() fail */ - static char errorstr_buf[48]; - const char *str; - -#ifdef WIN32 - /* Winsock error code range, per WinError.h */ - if (errnum >= 10000 && errnum <= 11999) - return pgwin32_socket_strerror(errnum); -#endif - str = strerror(errnum); - - /* - * Some strerror()s return an empty string for out-of-range errno. This - * is ANSI C spec compliant, but not exactly useful. Also, we may get - * back strings of question marks if libc cannot transcode the message to - * the codeset specified by LC_CTYPE. If we get nothing useful, first try - * get_errno_symbol(), and if that fails, print the numeric errno. - */ - if (str == NULL || *str == '\0' || *str == '?') - str = get_errno_symbol(errnum); - - if (str == NULL) - { - snprintf(errorstr_buf, sizeof(errorstr_buf), - /*------ - translator: This string will be truncated at 47 - characters expanded. */ - _("operating system error %d"), errnum); - str = errorstr_buf; - } - - return str; -} - -/* - * Returns a symbol (e.g. "ENOENT") for an errno code. - * Returns NULL if the code is unrecognized. - */ -static const char * -get_errno_symbol(int errnum) -{ - switch (errnum) - { - case E2BIG: - return "E2BIG"; - case EACCES: - return "EACCES"; -#ifdef EADDRINUSE - case EADDRINUSE: - return "EADDRINUSE"; -#endif -#ifdef EADDRNOTAVAIL - case EADDRNOTAVAIL: - return "EADDRNOTAVAIL"; -#endif - case EAFNOSUPPORT: - return "EAFNOSUPPORT"; -#ifdef EAGAIN - case EAGAIN: - return "EAGAIN"; -#endif -#ifdef EALREADY - case EALREADY: - return "EALREADY"; -#endif - case EBADF: - return "EBADF"; -#ifdef EBADMSG - case EBADMSG: - return "EBADMSG"; -#endif - case EBUSY: - return "EBUSY"; - case ECHILD: - return "ECHILD"; -#ifdef ECONNABORTED - case ECONNABORTED: - return "ECONNABORTED"; -#endif - case ECONNREFUSED: - return "ECONNREFUSED"; -#ifdef ECONNRESET - case ECONNRESET: - return "ECONNRESET"; -#endif - case EDEADLK: - return "EDEADLK"; - case EDOM: - return "EDOM"; - case EEXIST: - return "EEXIST"; - case EFAULT: - return "EFAULT"; - case EFBIG: - return "EFBIG"; -#ifdef EHOSTUNREACH - case EHOSTUNREACH: - return "EHOSTUNREACH"; -#endif - case EIDRM: - return "EIDRM"; - case EINPROGRESS: - return "EINPROGRESS"; - case EINTR: - return "EINTR"; - case EINVAL: - return "EINVAL"; - case EIO: - return "EIO"; -#ifdef EISCONN - case EISCONN: - return "EISCONN"; -#endif - case EISDIR: - return "EISDIR"; -#ifdef ELOOP - case ELOOP: - return "ELOOP"; -#endif - case EMFILE: - return "EMFILE"; - case EMLINK: - return "EMLINK"; - case EMSGSIZE: - return "EMSGSIZE"; - case ENAMETOOLONG: - return "ENAMETOOLONG"; - case ENFILE: - return "ENFILE"; - case ENOBUFS: - return "ENOBUFS"; - case ENODEV: - return "ENODEV"; - case ENOENT: - return "ENOENT"; - case ENOEXEC: - return "ENOEXEC"; - case ENOMEM: - return "ENOMEM"; - case ENOSPC: - return "ENOSPC"; - case ENOSYS: - return "ENOSYS"; -#ifdef ENOTCONN - case ENOTCONN: - return "ENOTCONN"; -#endif - case ENOTDIR: - return "ENOTDIR"; -#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */ - case ENOTEMPTY: - return "ENOTEMPTY"; -#endif -#ifdef ENOTSOCK - case ENOTSOCK: - return "ENOTSOCK"; -#endif -#ifdef ENOTSUP - case ENOTSUP: - return "ENOTSUP"; -#endif - case ENOTTY: - return "ENOTTY"; - case ENXIO: - return "ENXIO"; -#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP)) - case EOPNOTSUPP: - return "EOPNOTSUPP"; -#endif -#ifdef EOVERFLOW - case EOVERFLOW: - return "EOVERFLOW"; -#endif - case EPERM: - return "EPERM"; - case EPIPE: - return "EPIPE"; - case EPROTONOSUPPORT: - return "EPROTONOSUPPORT"; - case ERANGE: - return "ERANGE"; -#ifdef EROFS - case EROFS: - return "EROFS"; -#endif - case ESRCH: - return "ESRCH"; -#ifdef ETIMEDOUT - case ETIMEDOUT: - return "ETIMEDOUT"; -#endif -#ifdef ETXTBSY - case ETXTBSY: - return "ETXTBSY"; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: - return "EWOULDBLOCK"; -#endif - case EXDEV: - return "EXDEV"; - } - - return NULL; -} - - /* * error_severity --- get string representing elevel * diff --git a/src/backend/utils/fmgr/README b/src/backend/utils/fmgr/README index 5a2331ff159..a4d6a07bddc 100644 --- a/src/backend/utils/fmgr/README +++ b/src/backend/utils/fmgr/README @@ -53,7 +53,7 @@ point to the expression parse tree for the function call; this can be used to extract parse-time knowledge about the actual arguments. Note that this field really is information about the arguments rather than information about the function, but it's proven to be more convenient to keep it in -FmgrInfo than in FunctionCallInfoData where it might more logically go. +FmgrInfo than in FunctionCallInfoBaseData where it might more logically go. During a call of a function, the following data structure is created @@ -67,10 +67,9 @@ typedef struct Oid fncollation; /* collation for function to use */ bool isnull; /* function must set true if result is NULL */ short nargs; /* # arguments actually passed */ - Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */ - bool argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */ -} FunctionCallInfoData; -typedef FunctionCallInfoData* FunctionCallInfo; + NullableDatum args[]; /* Arguments passed to function */ +} FunctionCallInfoBaseData; +typedef FunctionCallInfoBaseData* FunctionCallInfo; flinfo points to the lookup info used to make the call. Ordinary functions will probably ignore this field, but function class handlers will need it @@ -97,24 +96,24 @@ when there are no inputs of collatable types or they don't share a common collation. This is effectively a hidden additional argument, which collation-sensitive functions can use to determine their behavior. -nargs, arg[], and argnull[] hold the arguments being passed to the function. +nargs and args[] hold the arguments being passed to the function. Notice that all the arguments passed to a function (as well as its result value) will now uniformly be of type Datum. As discussed below, callers and callees should apply the standard Datum-to-and-from-whatever macros to convert to the actual argument types of a particular function. The -value in arg[i] is unspecified when argnull[i] is true. +value in args[i].value is unspecified when args[i].isnull is true. It is generally the responsibility of the caller to ensure that the number of arguments passed matches what the callee is expecting; except for callees that take a variable number of arguments, the callee will -typically ignore the nargs field and just grab values from arg[]. +typically ignore the nargs field and just grab values from args[]. The isnull field will be initialized to "false" before the call. On return from the function, isnull is the null flag for the function result: if it is true the function's result is NULL, regardless of the actual function return value. Note that simple "strict" functions can ignore -both isnull and argnull[], since they won't even get called when there -are any TRUE values in argnull[]. +both isnull and args[i].isnull, since they won't even get called when there +are any TRUE values in args[].isnull. FunctionCallInfo replaces FmgrValues plus a bunch of ad-hoc parameter conventions, global variables (fmgr_pl_finfo and CurrentTriggerData at @@ -157,7 +156,7 @@ again, it might come in handy to have this macro in place. A nonstrict function is responsible for checking whether each individual argument is null or not, which it can do with PG_ARGISNULL(n) (which is -just "fcinfo->argnull[n]"). It should avoid trying to fetch the value +just "fcinfo->args[n].isnull"). It should avoid trying to fetch the value of any argument that is null. Both strict and nonstrict functions can return NULL, if needed, with @@ -171,7 +170,7 @@ Argument values are ordinarily fetched using code like For float4, float8, and int8, the PG_GETARG macros will hide whether the types are pass-by-value or pass-by-reference. For example, if float8 is pass-by-reference then PG_GETARG_FLOAT8 expands to - (* (float8 *) DatumGetPointer(fcinfo->arg[number])) + (* (float8 *) DatumGetPointer(fcinfo->args[number].value)) and would typically be called like this: float8 arg = PG_GETARG_FLOAT8(0); For what are now historical reasons, the float-related typedefs and macros diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index 1b0dbad82c7..be684786d64 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -3,7 +3,7 @@ * dfmgr.c * Dynamic function manager code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,11 +16,24 @@ #include -#include "dynloader.h" +#ifdef HAVE_DLOPEN +#include + +/* + * On macOS, insists on including . If we're not + * using stdbool, undef bool to undo the damage. + */ +#ifndef USE_STDBOOL +#ifdef bool +#undef bool +#endif +#endif +#endif /* HAVE_DLOPEN */ + +#include "fmgr.h" #include "lib/stringinfo.h" #include "miscadmin.h" #include "storage/shmem.h" -#include "utils/dynamic_loader.h" #include "utils/hsearch.h" @@ -65,7 +78,7 @@ char *Dynamic_library_path; static void *internal_load_library(const char *libname); static void incompatible_module_error(const char *libname, - const Pg_magic_struct *module_magic_data) pg_attribute_noreturn(); + const Pg_magic_struct *module_magic_data) pg_attribute_noreturn(); static void internal_unload_library(const char *libname); static bool file_exists(const char *name); static char *expand_dynamic_library_name(const char *name); @@ -108,12 +121,8 @@ load_external_function(const char *filename, const char *funcname, if (filehandle) *filehandle = lib_handle; - /* - * Look up the function within the library. According to POSIX dlsym() - * should declare its second argument as "const char *", but older - * platforms might not, so for the time being we just cast away const. - */ - retval = (PGFunction) pg_dlsym(lib_handle, (char *) funcname); + /* Look up the function within the library. */ + retval = (PGFunction) dlsym(lib_handle, funcname); if (retval == NULL && signalNotFound) ereport(ERROR, @@ -161,8 +170,7 @@ load_file(const char *filename, bool restricted) PGFunction lookup_external_function(void *filehandle, const char *funcname) { - /* as above, cast away const for the time being */ - return (PGFunction) pg_dlsym(filehandle, (char *) funcname); + return (PGFunction) dlsym(filehandle, funcname); } @@ -228,10 +236,10 @@ internal_load_library(const char *libname) #endif file_scanner->next = NULL; - file_scanner->handle = pg_dlopen(file_scanner->filename); + file_scanner->handle = dlopen(file_scanner->filename, RTLD_NOW | RTLD_GLOBAL); if (file_scanner->handle == NULL) { - load_error = (char *) pg_dlerror(); + load_error = dlerror(); free((char *) file_scanner); /* errcode_for_file_access might not be appropriate here? */ ereport(ERROR, @@ -242,7 +250,7 @@ internal_load_library(const char *libname) /* Check the magic function to determine compatibility */ magic_func = (PGModuleMagicFunction) - pg_dlsym(file_scanner->handle, PG_MAGIC_FUNCTION_NAME_STRING); + dlsym(file_scanner->handle, PG_MAGIC_FUNCTION_NAME_STRING); if (magic_func) { const Pg_magic_struct *magic_data_ptr = (*magic_func) (); @@ -253,8 +261,8 @@ internal_load_library(const char *libname) /* copy data block before unlinking library */ Pg_magic_struct module_magic_data = *magic_data_ptr; - /* try to unlink library */ - pg_dlclose(file_scanner->handle); + /* try to close library */ + dlclose(file_scanner->handle); free((char *) file_scanner); /* issue suitable complaint */ @@ -263,8 +271,8 @@ internal_load_library(const char *libname) } else { - /* try to unlink library */ - pg_dlclose(file_scanner->handle); + /* try to close library */ + dlclose(file_scanner->handle); free((char *) file_scanner); /* complain */ ereport(ERROR, @@ -276,7 +284,7 @@ internal_load_library(const char *libname) /* * If the library has a _PG_init() function, call it. */ - PG_init = (PG_init_t) pg_dlsym(file_scanner->handle, "_PG_init"); + PG_init = (PG_init_t) dlsym(file_scanner->handle, "_PG_init"); if (PG_init) (*PG_init) (); @@ -436,12 +444,12 @@ internal_unload_library(const char *libname) /* * If the library has a _PG_fini() function, call it. */ - PG_fini = (PG_fini_t) pg_dlsym(file_scanner->handle, "_PG_fini"); + PG_fini = (PG_fini_t) dlsym(file_scanner->handle, "_PG_fini"); if (PG_fini) (*PG_fini) (); clear_external_function_hash(file_scanner->handle); - pg_dlclose(file_scanner->handle); + dlclose(file_scanner->handle); free((char *) file_scanner); /* prv does not change */ } diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c index aa188bdeffa..0484adb984a 100644 --- a/src/backend/utils/fmgr/fmgr.c +++ b/src/backend/utils/fmgr/fmgr.c @@ -3,7 +3,7 @@ * fmgr.c * The Postgres function manager. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -15,7 +15,7 @@ #include "postgres.h" -#include "access/tuptoaster.h" +#include "access/detoast.h" #include "catalog/pg_language.h" #include "catalog/pg_proc.h" #include "executor/functions.h" @@ -53,12 +53,13 @@ static HTAB *CFuncHash = NULL; static void fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, - bool ignore_security); + bool ignore_security); static void fmgr_info_C_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple); static void fmgr_info_other_lang(Oid functionId, FmgrInfo *finfo, HeapTuple procedureTuple); static CFuncHashTabEntry *lookup_C_func(HeapTuple procedureTuple); static void record_C_func(HeapTuple procedureTuple, - PGFunction user_fn, const Pg_finfo_record *inforec); + PGFunction user_fn, const Pg_finfo_record *inforec); + /* extern so it's callable via JIT */ extern Datum fmgr_security_definer(PG_FUNCTION_ARGS); @@ -74,12 +75,12 @@ fmgr_isbuiltin(Oid id) uint16 index; /* fast lookup only possible if original oid still assigned */ - if (id >= FirstBootstrapObjectId) + if (id > fmgr_last_builtin_oid) return NULL; /* * Lookup function data. If there's a miss in that range it's likely a - * nonexistant function, returning NULL here will trigger an ERROR later. + * nonexistent function, returning NULL here will trigger an ERROR later. */ index = fmgr_builtin_oid_index[id]; if (index == InvalidOidBuiltinMapping) @@ -216,7 +217,7 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt, /* * For an ordinary builtin function, we should never get here - * because the isbuiltin() search above will have succeeded. + * because the fmgr_isbuiltin() search above will have succeeded. * However, if the user has done a CREATE FUNCTION to create an * alias for a builtin function, we can end up here. In that case * we have to look up the function by name. The name of the @@ -297,7 +298,7 @@ fmgr_symbol(Oid functionId, char **mod, char **fn) !heap_attisnull(procedureTuple, Anum_pg_proc_proconfig, NULL) || FmgrHookIsNeeded(functionId)) { - *mod = NULL; /* core binary */ + *mod = NULL; /* core binary */ *fn = pstrdup("fmgr_security_definer"); ReleaseSysCache(procedureTuple); return; @@ -312,7 +313,7 @@ fmgr_symbol(Oid functionId, char **mod, char **fn) if (isnull) elog(ERROR, "null prosrc"); - *mod = NULL; /* core binary */ + *mod = NULL; /* core binary */ *fn = TextDatumGetCString(prosrcattr); break; @@ -336,13 +337,13 @@ fmgr_symbol(Oid functionId, char **mod, char **fn) break; case SQLlanguageId: - *mod = NULL; /* core binary */ + *mod = NULL; /* core binary */ *fn = pstrdup("fmgr_sql"); break; default: *mod = NULL; - *fn = NULL; /* unknown, pass pointer */ + *fn = NULL; /* unknown, pass pointer */ break; } @@ -528,7 +529,7 @@ fetch_finfo_record(void *filehandle, const char *funcname) static CFuncHashTabEntry * lookup_C_func(HeapTuple procedureTuple) { - Oid fn_oid = HeapTupleGetOid(procedureTuple); + Oid fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid; CFuncHashTabEntry *entry; if (CFuncHash == NULL) @@ -553,7 +554,7 @@ static void record_C_func(HeapTuple procedureTuple, PGFunction user_fn, const Pg_finfo_record *inforec) { - Oid fn_oid = HeapTupleGetOid(procedureTuple); + Oid fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid; CFuncHashTabEntry *entry; bool found; @@ -791,18 +792,18 @@ fmgr_security_definer(PG_FUNCTION_ARGS) Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 1); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 1, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 1, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.argnull[0] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -811,20 +812,20 @@ DirectFunctionCall1Coll(PGFunction func, Oid collation, Datum arg1) Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 2); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 2, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 2, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -834,22 +835,22 @@ Datum DirectFunctionCall3Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 3); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 3, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 3, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -859,24 +860,24 @@ Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 4); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 4, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 4, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -886,26 +887,26 @@ Datum DirectFunctionCall5Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 5); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 5, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 5, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -916,28 +917,28 @@ DirectFunctionCall6Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 6); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 6, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, NULL, 6, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -948,30 +949,30 @@ DirectFunctionCall7Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 7); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 7, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - - result = (*func) (&fcinfo); + InitFunctionCallInfoData(*fcinfo, NULL, 7, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -982,32 +983,32 @@ DirectFunctionCall8Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7, Datum arg8) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 8); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 8, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - - result = (*func) (&fcinfo); + InitFunctionCallInfoData(*fcinfo, NULL, 8, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + fcinfo->args[7].value = arg8; + fcinfo->args[7].isnull = false; + + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -1019,34 +1020,34 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum arg6, Datum arg7, Datum arg8, Datum arg9) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 9); Datum result; - InitFunctionCallInfoData(fcinfo, NULL, 9, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.arg[8] = arg9; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - fcinfo.argnull[8] = false; - - result = (*func) (&fcinfo); + InitFunctionCallInfoData(*fcinfo, NULL, 9, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + fcinfo->args[7].value = arg8; + fcinfo->args[7].isnull = false; + fcinfo->args[8].value = arg9; + fcinfo->args[8].isnull = false; + + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -1064,18 +1065,18 @@ DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg1, Datum arg2, Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 1); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.argnull[0] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -1084,20 +1085,20 @@ CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 2); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; - result = (*func) (&fcinfo); + result = (*func) (fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "function %p returned NULL", (void *) func); return result; @@ -1108,22 +1109,39 @@ CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, Oid collation, Datum * directly-computed parameter list. Note that neither arguments nor result * are allowed to be NULL. */ +Datum +FunctionCall0Coll(FmgrInfo *flinfo, Oid collation) +{ + LOCAL_FCINFO(fcinfo, 0); + Datum result; + + InitFunctionCallInfoData(*fcinfo, flinfo, 0, collation, NULL, NULL); + + result = FunctionCallInvoke(fcinfo); + + /* Check for null result, since caller is clearly not expecting one */ + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); + + return result; +} + Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 1); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 1, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 1, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.argnull[0] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1131,21 +1149,21 @@ FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1) Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 2); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 2, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 2, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1154,23 +1172,23 @@ Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 3); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 3, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 3, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1179,25 +1197,25 @@ Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 4); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 4, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 4, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1206,27 +1224,27 @@ Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 5); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 5, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 5, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1236,29 +1254,29 @@ FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 6); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 6, collation, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 6, collation, NULL, NULL); - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1268,31 +1286,31 @@ FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 7); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 7, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - - result = FunctionCallInvoke(&fcinfo); + InitFunctionCallInfoData(*fcinfo, flinfo, 7, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1302,33 +1320,33 @@ FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5, Datum arg6, Datum arg7, Datum arg8) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 8); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 8, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - - result = FunctionCallInvoke(&fcinfo); + InitFunctionCallInfoData(*fcinfo, flinfo, 8, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + fcinfo->args[7].value = arg8; + fcinfo->args[7].isnull = false; + + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1339,35 +1357,35 @@ FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2, Datum arg6, Datum arg7, Datum arg8, Datum arg9) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 9); Datum result; - InitFunctionCallInfoData(fcinfo, flinfo, 9, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.arg[8] = arg9; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - fcinfo.argnull[8] = false; - - result = FunctionCallInvoke(&fcinfo); + InitFunctionCallInfoData(*fcinfo, flinfo, 9, collation, NULL, NULL); + + fcinfo->args[0].value = arg1; + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = arg2; + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = arg3; + fcinfo->args[2].isnull = false; + fcinfo->args[3].value = arg4; + fcinfo->args[3].isnull = false; + fcinfo->args[4].value = arg5; + fcinfo->args[4].isnull = false; + fcinfo->args[5].value = arg6; + fcinfo->args[5].isnull = false; + fcinfo->args[6].value = arg7; + fcinfo->args[6].isnull = false; + fcinfo->args[7].value = arg8; + fcinfo->args[7].isnull = false; + fcinfo->args[8].value = arg9; + fcinfo->args[8].isnull = false; + + result = FunctionCallInvoke(fcinfo); /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", fcinfo.flinfo->fn_oid); + if (fcinfo->isnull) + elog(ERROR, "function %u returned NULL", flinfo->fn_oid); return result; } @@ -1384,68 +1402,30 @@ Datum OidFunctionCall0Coll(Oid functionId, Oid collation) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 0, collation, NULL, NULL); - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall0Coll(&flinfo, collation); } Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 1, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.argnull[0] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall1Coll(&flinfo, collation, arg1); } Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 2, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall2Coll(&flinfo, collation, arg1, arg2); } Datum @@ -1453,27 +1433,10 @@ OidFunctionCall3Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall3Coll(&flinfo, collation, arg1, arg2, arg3); } Datum @@ -1481,29 +1444,10 @@ OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 4, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall4Coll(&flinfo, collation, arg1, arg2, arg3, arg4); } Datum @@ -1511,31 +1455,10 @@ OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 5, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall5Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5); } Datum @@ -1544,33 +1467,11 @@ OidFunctionCall6Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg6) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 6, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall6Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, + arg6); } Datum @@ -1579,35 +1480,11 @@ OidFunctionCall7Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg6, Datum arg7) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 7, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall7Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, + arg6, arg7); } Datum @@ -1616,37 +1493,11 @@ OidFunctionCall8Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg6, Datum arg7, Datum arg8) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 8, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall8Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8); } Datum @@ -1656,39 +1507,11 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg9) { FmgrInfo flinfo; - FunctionCallInfoData fcinfo; - Datum result; fmgr_info(functionId, &flinfo); - InitFunctionCallInfoData(fcinfo, &flinfo, 9, collation, NULL, NULL); - - fcinfo.arg[0] = arg1; - fcinfo.arg[1] = arg2; - fcinfo.arg[2] = arg3; - fcinfo.arg[3] = arg4; - fcinfo.arg[4] = arg5; - fcinfo.arg[5] = arg6; - fcinfo.arg[6] = arg7; - fcinfo.arg[7] = arg8; - fcinfo.arg[8] = arg9; - fcinfo.argnull[0] = false; - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; - fcinfo.argnull[3] = false; - fcinfo.argnull[4] = false; - fcinfo.argnull[5] = false; - fcinfo.argnull[6] = false; - fcinfo.argnull[7] = false; - fcinfo.argnull[8] = false; - - result = FunctionCallInvoke(&fcinfo); - - /* Check for null result, since caller is clearly not expecting one */ - if (fcinfo.isnull) - elog(ERROR, "function %u returned NULL", flinfo.fn_oid); - - return result; + return FunctionCall9Coll(&flinfo, collation, arg1, arg2, arg3, arg4, arg5, + arg6, arg7, arg8, arg9); } @@ -1707,35 +1530,35 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 3); Datum result; if (str == NULL && flinfo->fn_strict) return (Datum) 0; /* just return null result */ - InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL); - fcinfo.arg[0] = CStringGetDatum(str); - fcinfo.arg[1] = ObjectIdGetDatum(typioparam); - fcinfo.arg[2] = Int32GetDatum(typmod); - fcinfo.argnull[0] = (str == NULL); - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; + fcinfo->args[0].value = CStringGetDatum(str); + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = ObjectIdGetDatum(typioparam); + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = Int32GetDatum(typmod); + fcinfo->args[2].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Should get null result if and only if str is NULL */ if (str == NULL) { - if (!fcinfo.isnull) + if (!fcinfo->isnull) elog(ERROR, "input function %u returned non-NULL", - fcinfo.flinfo->fn_oid); + flinfo->fn_oid); } else { - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "input function %u returned NULL", - fcinfo.flinfo->fn_oid); + flinfo->fn_oid); } return result; @@ -1766,35 +1589,35 @@ Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod) { - FunctionCallInfoData fcinfo; + LOCAL_FCINFO(fcinfo, 3); Datum result; if (buf == NULL && flinfo->fn_strict) return (Datum) 0; /* just return null result */ - InitFunctionCallInfoData(fcinfo, flinfo, 3, InvalidOid, NULL, NULL); + InitFunctionCallInfoData(*fcinfo, flinfo, 3, InvalidOid, NULL, NULL); - fcinfo.arg[0] = PointerGetDatum(buf); - fcinfo.arg[1] = ObjectIdGetDatum(typioparam); - fcinfo.arg[2] = Int32GetDatum(typmod); - fcinfo.argnull[0] = (buf == NULL); - fcinfo.argnull[1] = false; - fcinfo.argnull[2] = false; + fcinfo->args[0].value = PointerGetDatum(buf); + fcinfo->args[0].isnull = false; + fcinfo->args[1].value = ObjectIdGetDatum(typioparam); + fcinfo->args[1].isnull = false; + fcinfo->args[2].value = Int32GetDatum(typmod); + fcinfo->args[2].isnull = false; - result = FunctionCallInvoke(&fcinfo); + result = FunctionCallInvoke(fcinfo); /* Should get null result if and only if buf is NULL */ if (buf == NULL) { - if (!fcinfo.isnull) + if (!fcinfo->isnull) elog(ERROR, "receive function %u returned non-NULL", - fcinfo.flinfo->fn_oid); + flinfo->fn_oid); } else { - if (fcinfo.isnull) + if (fcinfo->isnull) elog(ERROR, "receive function %u returned NULL", - fcinfo.flinfo->fn_oid); + flinfo->fn_oid); } return result; diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index d5984b415ed..b7fac5d2954 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -4,7 +4,7 @@ * Utility and convenience functions for fmgr functions that return * sets and/or composite types, or deal with VARIADIC inputs. * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/fmgr/funcapi.c @@ -14,6 +14,7 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/relation.h" #include "catalog/namespace.h" #include "catalog/pg_proc.h" #include "catalog/pg_type.h" @@ -32,13 +33,13 @@ static void shutdown_MultiFuncCall(Datum arg); static TypeFuncClass internal_get_result_type(Oid funcid, - Node *call_expr, - ReturnSetInfo *rsinfo, - Oid *resultTypeId, - TupleDesc *resultTupleDesc); + Node *call_expr, + ReturnSetInfo *rsinfo, + Oid *resultTypeId, + TupleDesc *resultTupleDesc); static bool resolve_polymorphic_tupdesc(TupleDesc tupdesc, - oidvector *declared_args, - Node *call_expr); + oidvector *declared_args, + Node *call_expr); static TypeFuncClass get_type_func_class(Oid typid, Oid *base_typeid); @@ -88,7 +89,6 @@ init_MultiFuncCall(PG_FUNCTION_ARGS) */ retval->call_cntr = 0; retval->max_calls = 0; - retval->slot = NULL; retval->user_fctx = NULL; retval->attinmeta = NULL; retval->tuple_desc = NULL; @@ -129,21 +129,6 @@ per_MultiFuncCall(PG_FUNCTION_ARGS) { FuncCallContext *retval = (FuncCallContext *) fcinfo->flinfo->fn_extra; - /* - * Clear the TupleTableSlot, if present. This is for safety's sake: the - * Slot will be in a long-lived context (it better be, if the - * FuncCallContext is pointing to it), but in most usage patterns the - * tuples stored in it will be in the function's per-tuple context. So at - * the beginning of each call, the Slot will hold a dangling pointer to an - * already-recycled tuple. We clear it out here. - * - * Note: use of retval->slot is obsolete as of 8.0, and we expect that it - * will always be NULL. This is just here for backwards compatibility in - * case someone creates a slot anyway. - */ - if (retval->slot != NULL) - ExecClearTuple(retval->slot); - return retval; } @@ -1317,7 +1302,7 @@ build_function_result_tupdesc_d(char prokind, if (numoutargs < 2 && prokind != PROKIND_PROCEDURE) return NULL; - desc = CreateTemplateTupleDesc(numoutargs, false); + desc = CreateTemplateTupleDesc(numoutargs); for (i = 0; i < numoutargs; i++) { TupleDescInitEntry(desc, i + 1, @@ -1437,7 +1422,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases) /* OK, get the column alias */ attname = strVal(linitial(colaliases)); - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, attname, diff --git a/src/backend/utils/generate-errcodes.pl b/src/backend/utils/generate-errcodes.pl index e9f1715a0d7..e9120af85fc 100644 --- a/src/backend/utils/generate-errcodes.pl +++ b/src/backend/utils/generate-errcodes.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate the errcodes.h header from errcodes.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index 785e0faffb5..0dfbec8e3ec 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -41,7 +41,7 @@ * function must be supplied; comparison defaults to memcmp() and key copying * to memcpy() when a user-defined hashing function is selected. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -817,7 +817,7 @@ hash_destroy(HTAB *hashp) { /* allocation method must be one we know how to free, too */ Assert(hashp->alloc == DynaHashAlloc); - /* so this hashtable must have it's own context */ + /* so this hashtable must have its own context */ Assert(hashp->hcxt != NULL); hash_stats("destroy", hashp); diff --git a/src/backend/utils/hash/hashfn.c b/src/backend/utils/hash/hashfn.c index 9b7ddbad0b4..b8ecd75adc8 100644 --- a/src/backend/utils/hash/hashfn.c +++ b/src/backend/utils/hash/hashfn.c @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * hashfn.c - * Hash functions for use in dynahash.c hashtables + * Generic hashing functions, and hash functions for use in dynahash.c + * hashtables * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,10 +22,638 @@ */ #include "postgres.h" -#include "access/hash.h" +#include "fmgr.h" +#include "nodes/bitmapset.h" +#include "utils/hashutils.h" #include "utils/hsearch.h" +/* + * This hash function was written by Bob Jenkins + * (bob_jenkins@burtleburtle.net), and superficially adapted + * for PostgreSQL by Neil Conway. For more information on this + * hash function, see http://burtleburtle.net/bob/hash/doobs.html, + * or Bob's article in Dr. Dobb's Journal, Sept. 1997. + * + * In the current code, we have adopted Bob's 2006 update of his hash + * function to fetch the data a word at a time when it is suitably aligned. + * This makes for a useful speedup, at the cost of having to maintain + * four code paths (aligned vs unaligned, and little-endian vs big-endian). + * It also uses two separate mixing functions mix() and final(), instead + * of a slower multi-purpose function. + */ + +/* Get a bit mask of the bits set in non-uint32 aligned addresses */ +#define UINT32_ALIGN_MASK (sizeof(uint32) - 1) + +/* Rotate a uint32 value left by k bits - note multiple evaluation! */ +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/*---------- + * mix -- mix 3 32-bit values reversibly. + * + * This is reversible, so any information in (a,b,c) before mix() is + * still in (a,b,c) after mix(). + * + * If four pairs of (a,b,c) inputs are run through mix(), or through + * mix() in reverse, there are at least 32 bits of the output that + * are sometimes the same for one pair and different for another pair. + * This was tested for: + * * pairs that differed by one bit, by two bits, in any combination + * of top bits of (a,b,c), or in any combination of bottom bits of + * (a,b,c). + * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + * is commonly produced by subtraction) look like a single 1-bit + * difference. + * * the base values were pseudorandom, all zero but one bit set, or + * all zero plus a counter that starts at zero. + * + * This does not achieve avalanche. There are input bits of (a,b,c) + * that fail to affect some output bits of (a,b,c), especially of a. The + * most thoroughly mixed value is c, but it doesn't really even achieve + * avalanche in c. + * + * This allows some parallelism. Read-after-writes are good at doubling + * the number of bits affected, so the goal of mixing pulls in the opposite + * direction from the goal of parallelism. I did what I could. Rotates + * seem to cost as much as shifts on every machine I could lay my hands on, + * and rotates are much kinder to the top and bottom bits, so I used rotates. + *---------- + */ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/*---------- + * final -- final mixing of 3 32-bit values (a,b,c) into c + * + * Pairs of (a,b,c) values differing in only a few bits will usually + * produce values of c that look totally different. This was tested for + * * pairs that differed by one bit, by two bits, in any combination + * of top bits of (a,b,c), or in any combination of bottom bits of + * (a,b,c). + * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + * is commonly produced by subtraction) look like a single 1-bit + * difference. + * * the base values were pseudorandom, all zero but one bit set, or + * all zero plus a counter that starts at zero. + * + * The use of separate functions for mix() and final() allow for a + * substantial performance increase since final() does not need to + * do well in reverse, but is does need to affect all output bits. + * mix(), on the other hand, does not need to affect all output + * bits (affecting 32 bits is enough). The original hash function had + * a single mixing operation that had to satisfy both sets of requirements + * and was slower as a result. + *---------- + */ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c, 4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + +/* + * hash_any() -- hash a variable-length key into a 32-bit value + * k : the key (the unaligned variable-length array of bytes) + * len : the length of the key, counting by bytes + * + * Returns a uint32 value. Every bit of the key affects every bit of + * the return value. Every 1-bit and 2-bit delta achieves avalanche. + * About 6*len+35 instructions. The best hash table sizes are powers + * of 2. There is no need to do mod a prime (mod is sooo slow!). + * If you need less than 32 bits, use a bitmask. + * + * This procedure must never throw elog(ERROR); the ResourceOwner code + * relies on this not to fail. + * + * Note: we could easily change this function to return a 64-bit hash value + * by using the final values of both b and c. b is perhaps a little less + * well mixed than c, however. + */ +Datum +hash_any(const unsigned char *k, int keylen) +{ + uint32 a, + b, + c, + len; + + /* Set up the internal state */ + len = keylen; + a = b = c = 0x9e3779b9 + len + 3923095; + + /* If the source pointer is word-aligned, we use word-wide fetches */ + if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) + { + /* Code path for aligned source data */ + const uint32 *ka = (const uint32 *) k; + + /* handle most of the key */ + while (len >= 12) + { + a += ka[0]; + b += ka[1]; + c += ka[2]; + mix(a, b, c); + ka += 3; + len -= 12; + } + + /* handle the last 11 bytes */ + k = (const unsigned char *) ka; +#ifdef WORDS_BIGENDIAN + switch (len) + { + case 11: + c += ((uint32) k[10] << 8); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 24); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ka[1]; + a += ka[0]; + break; + case 7: + b += ((uint32) k[6] << 8); + /* fall through */ + case 6: + b += ((uint32) k[5] << 16); + /* fall through */ + case 5: + b += ((uint32) k[4] << 24); + /* fall through */ + case 4: + a += ka[0]; + break; + case 3: + a += ((uint32) k[2] << 8); + /* fall through */ + case 2: + a += ((uint32) k[1] << 16); + /* fall through */ + case 1: + a += ((uint32) k[0] << 24); + /* case 0: nothing left to add */ + } +#else /* !WORDS_BIGENDIAN */ + switch (len) + { + case 11: + c += ((uint32) k[10] << 24); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 8); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ka[1]; + a += ka[0]; + break; + case 7: + b += ((uint32) k[6] << 16); + /* fall through */ + case 6: + b += ((uint32) k[5] << 8); + /* fall through */ + case 5: + b += k[4]; + /* fall through */ + case 4: + a += ka[0]; + break; + case 3: + a += ((uint32) k[2] << 16); + /* fall through */ + case 2: + a += ((uint32) k[1] << 8); + /* fall through */ + case 1: + a += k[0]; + /* case 0: nothing left to add */ + } +#endif /* WORDS_BIGENDIAN */ + } + else + { + /* Code path for non-aligned source data */ + + /* handle most of the key */ + while (len >= 12) + { +#ifdef WORDS_BIGENDIAN + a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); + b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); + c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); +#else /* !WORDS_BIGENDIAN */ + a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); + b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); + c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); +#endif /* WORDS_BIGENDIAN */ + mix(a, b, c); + k += 12; + len -= 12; + } + + /* handle the last 11 bytes */ +#ifdef WORDS_BIGENDIAN + switch (len) + { + case 11: + c += ((uint32) k[10] << 8); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 24); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += k[7]; + /* fall through */ + case 7: + b += ((uint32) k[6] << 8); + /* fall through */ + case 6: + b += ((uint32) k[5] << 16); + /* fall through */ + case 5: + b += ((uint32) k[4] << 24); + /* fall through */ + case 4: + a += k[3]; + /* fall through */ + case 3: + a += ((uint32) k[2] << 8); + /* fall through */ + case 2: + a += ((uint32) k[1] << 16); + /* fall through */ + case 1: + a += ((uint32) k[0] << 24); + /* case 0: nothing left to add */ + } +#else /* !WORDS_BIGENDIAN */ + switch (len) + { + case 11: + c += ((uint32) k[10] << 24); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 8); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ((uint32) k[7] << 24); + /* fall through */ + case 7: + b += ((uint32) k[6] << 16); + /* fall through */ + case 6: + b += ((uint32) k[5] << 8); + /* fall through */ + case 5: + b += k[4]; + /* fall through */ + case 4: + a += ((uint32) k[3] << 24); + /* fall through */ + case 3: + a += ((uint32) k[2] << 16); + /* fall through */ + case 2: + a += ((uint32) k[1] << 8); + /* fall through */ + case 1: + a += k[0]; + /* case 0: nothing left to add */ + } +#endif /* WORDS_BIGENDIAN */ + } + + final(a, b, c); + + /* report the result */ + return UInt32GetDatum(c); +} + +/* + * hash_any_extended() -- hash into a 64-bit value, using an optional seed + * k : the key (the unaligned variable-length array of bytes) + * len : the length of the key, counting by bytes + * seed : a 64-bit seed (0 means no seed) + * + * Returns a uint64 value. Otherwise similar to hash_any. + */ +Datum +hash_any_extended(const unsigned char *k, int keylen, + uint64 seed) +{ + uint32 a, + b, + c, + len; + + /* Set up the internal state */ + len = keylen; + a = b = c = 0x9e3779b9 + len + 3923095; + + /* If the seed is non-zero, use it to perturb the internal state. */ + if (seed != 0) + { + /* + * In essence, the seed is treated as part of the data being hashed, + * but for simplicity, we pretend that it's padded with four bytes of + * zeroes so that the seed constitutes a 12-byte chunk. + */ + a += (uint32) (seed >> 32); + b += (uint32) seed; + mix(a, b, c); + } + + /* If the source pointer is word-aligned, we use word-wide fetches */ + if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) + { + /* Code path for aligned source data */ + const uint32 *ka = (const uint32 *) k; + + /* handle most of the key */ + while (len >= 12) + { + a += ka[0]; + b += ka[1]; + c += ka[2]; + mix(a, b, c); + ka += 3; + len -= 12; + } + + /* handle the last 11 bytes */ + k = (const unsigned char *) ka; +#ifdef WORDS_BIGENDIAN + switch (len) + { + case 11: + c += ((uint32) k[10] << 8); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 24); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ka[1]; + a += ka[0]; + break; + case 7: + b += ((uint32) k[6] << 8); + /* fall through */ + case 6: + b += ((uint32) k[5] << 16); + /* fall through */ + case 5: + b += ((uint32) k[4] << 24); + /* fall through */ + case 4: + a += ka[0]; + break; + case 3: + a += ((uint32) k[2] << 8); + /* fall through */ + case 2: + a += ((uint32) k[1] << 16); + /* fall through */ + case 1: + a += ((uint32) k[0] << 24); + /* case 0: nothing left to add */ + } +#else /* !WORDS_BIGENDIAN */ + switch (len) + { + case 11: + c += ((uint32) k[10] << 24); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 8); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ka[1]; + a += ka[0]; + break; + case 7: + b += ((uint32) k[6] << 16); + /* fall through */ + case 6: + b += ((uint32) k[5] << 8); + /* fall through */ + case 5: + b += k[4]; + /* fall through */ + case 4: + a += ka[0]; + break; + case 3: + a += ((uint32) k[2] << 16); + /* fall through */ + case 2: + a += ((uint32) k[1] << 8); + /* fall through */ + case 1: + a += k[0]; + /* case 0: nothing left to add */ + } +#endif /* WORDS_BIGENDIAN */ + } + else + { + /* Code path for non-aligned source data */ + + /* handle most of the key */ + while (len >= 12) + { +#ifdef WORDS_BIGENDIAN + a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); + b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); + c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); +#else /* !WORDS_BIGENDIAN */ + a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); + b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); + c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); +#endif /* WORDS_BIGENDIAN */ + mix(a, b, c); + k += 12; + len -= 12; + } + + /* handle the last 11 bytes */ +#ifdef WORDS_BIGENDIAN + switch (len) + { + case 11: + c += ((uint32) k[10] << 8); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 24); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += k[7]; + /* fall through */ + case 7: + b += ((uint32) k[6] << 8); + /* fall through */ + case 6: + b += ((uint32) k[5] << 16); + /* fall through */ + case 5: + b += ((uint32) k[4] << 24); + /* fall through */ + case 4: + a += k[3]; + /* fall through */ + case 3: + a += ((uint32) k[2] << 8); + /* fall through */ + case 2: + a += ((uint32) k[1] << 16); + /* fall through */ + case 1: + a += ((uint32) k[0] << 24); + /* case 0: nothing left to add */ + } +#else /* !WORDS_BIGENDIAN */ + switch (len) + { + case 11: + c += ((uint32) k[10] << 24); + /* fall through */ + case 10: + c += ((uint32) k[9] << 16); + /* fall through */ + case 9: + c += ((uint32) k[8] << 8); + /* fall through */ + case 8: + /* the lowest byte of c is reserved for the length */ + b += ((uint32) k[7] << 24); + /* fall through */ + case 7: + b += ((uint32) k[6] << 16); + /* fall through */ + case 6: + b += ((uint32) k[5] << 8); + /* fall through */ + case 5: + b += k[4]; + /* fall through */ + case 4: + a += ((uint32) k[3] << 24); + /* fall through */ + case 3: + a += ((uint32) k[2] << 16); + /* fall through */ + case 2: + a += ((uint32) k[1] << 8); + /* fall through */ + case 1: + a += k[0]; + /* case 0: nothing left to add */ + } +#endif /* WORDS_BIGENDIAN */ + } + + final(a, b, c); + + /* report the result */ + PG_RETURN_UINT64(((uint64) b << 32) | c); +} + +/* + * hash_uint32() -- hash a 32-bit value to a 32-bit value + * + * This has the same result as + * hash_any(&k, sizeof(uint32)) + * but is faster and doesn't force the caller to store k into memory. + */ +Datum +hash_uint32(uint32 k) +{ + uint32 a, + b, + c; + + a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; + a += k; + + final(a, b, c); + + /* report the result */ + return UInt32GetDatum(c); +} + +/* + * hash_uint32_extended() -- hash a 32-bit value to a 64-bit value, with a seed + * + * Like hash_uint32, this is a convenience function. + */ +Datum +hash_uint32_extended(uint32 k, uint64 seed) +{ + uint32 a, + b, + c; + + a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; + + if (seed != 0) + { + a += (uint32) (seed >> 32); + b += (uint32) seed; + mix(a, b, c); + } + + a += k; + + final(a, b, c); + + /* report the result */ + PG_RETURN_UINT64(((uint64) b << 32) | c); +} + /* * string_hash: hash function for keys that are NUL-terminated strings. * diff --git a/src/backend/utils/hash/pg_crc.c b/src/backend/utils/hash/pg_crc.c index 688ea0265f3..65bf8ff931e 100644 --- a/src/backend/utils/hash/pg_crc.c +++ b/src/backend/utils/hash/pg_crc.c @@ -7,7 +7,7 @@ * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from * http://www.ross.net/crc/download/crc_v3.txt or several other net sites. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c index 0a3163398f3..ab536504dcf 100644 --- a/src/backend/utils/init/globals.c +++ b/src/backend/utils/init/globals.c @@ -3,7 +3,7 @@ * globals.c * global variable declarations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -16,8 +16,6 @@ * *------------------------------------------------------------------------- */ -#include - #include "postgres.h" #include "common/file_perm.h" @@ -29,11 +27,11 @@ ProtocolVersion FrontendProtocol; -volatile bool InterruptPending = false; -volatile bool QueryCancelPending = false; -volatile bool ProcDiePending = false; -volatile bool ClientConnectionLost = false; -volatile bool IdleInTransactionSessionTimeoutPending = false; +volatile sig_atomic_t InterruptPending = false; +volatile sig_atomic_t QueryCancelPending = false; +volatile sig_atomic_t ProcDiePending = false; +volatile sig_atomic_t ClientConnectionLost = false; +volatile sig_atomic_t IdleInTransactionSessionTimeoutPending = false; volatile sig_atomic_t ConfigReloadPending = false; volatile uint32 InterruptHoldoffCount = 0; volatile uint32 QueryCancelHoldoffCount = 0; @@ -41,6 +39,7 @@ volatile uint32 CritSectionCount = 0; int MyProcPid; pg_time_t MyStartTime; +TimestampTz MyStartTimestamp; struct Port *MyProcPort; int32 MyCancelKey; int MyPMChildSlot; @@ -63,7 +62,7 @@ struct Latch *MyLatch; char *DataDir = NULL; /* - * Mode of the data directory. The default is 0700 but may it be changed in + * Mode of the data directory. The default is 0700 but it may be changed in * checkDataDir() to 0750 if the data directory actually has that mode. */ int data_directory_mode = PG_DIR_MODE_OWNER; @@ -109,6 +108,7 @@ pid_t PostmasterPid = 0; bool IsPostmasterEnvironment = false; bool IsUnderPostmaster = false; bool IsBinaryUpgrade = false; +bool IsOnlineUpgrade = false; bool IsBackgroundWorker = false; bool ExitOnAnyError = false; @@ -139,7 +139,7 @@ int VacuumCostPageHit = 1; /* GUC parameters for vacuum */ int VacuumCostPageMiss = 10; int VacuumCostPageDirty = 20; int VacuumCostLimit = 200; -int VacuumCostDelay = 0; +double VacuumCostDelay = 0; int VacuumPageHit = 0; int VacuumPageMiss = 0; diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 03b28c3604a..1099c0e2bdd 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -3,7 +3,7 @@ * miscinit.c * miscellaneous initialization support stuff * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -43,10 +43,12 @@ #include "storage/ipc.h" #include "storage/latch.h" #include "storage/pg_shmem.h" +#include "storage/pmsignal.h" #include "storage/proc.h" #include "storage/procarray.h" #include "utils/builtins.h" #include "utils/guc.h" +#include "utils/inval.h" #include "utils/memutils.h" #include "utils/pidfile.h" #include "utils/syscache.h" @@ -272,9 +274,7 @@ InitPostmasterChild(void) { IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); /* set our start time in case we call elog */ + InitProcessGlobals(); /* * make sure stderr is in binary mode before anything can possibly be @@ -304,6 +304,9 @@ InitPostmasterChild(void) if (setsid() < 0) elog(FATAL, "setsid() failed: %m"); #endif + + /* Request a signal if the postmaster dies, if possible. */ + PostmasterDeathSignalInit(); } /* @@ -316,9 +319,7 @@ InitStandaloneProcess(const char *argv0) { Assert(!IsPostmasterEnvironment); - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); /* set our start time in case we call elog */ + InitProcessGlobals(); /* Initialize process-local latch support */ InitializeLatchSupport(); @@ -590,6 +591,13 @@ InitializeSessionUserId(const char *rolename, Oid roleid) /* call only once */ AssertState(!OidIsValid(AuthenticatedUserId)); + /* + * Make sure syscache entries are flushed for recent catalog changes. This + * allows us to find roles that were created on-the-fly during + * authentication. + */ + AcceptInvalidationMessages(); + if (rolename != NULL) { roleTup = SearchSysCache1(AUTHNAME, PointerGetDatum(rolename)); @@ -608,7 +616,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid) } rform = (Form_pg_authid) GETSTRUCT(roleTup); - roleid = HeapTupleGetOid(roleTup); + roleid = rform->oid; rname = NameStr(rform->rolname); AuthenticatedUserId = roleid; @@ -852,6 +860,20 @@ UnlinkLockFiles(int status, Datum arg) (errmsg("database system is shut down"))); } + +static void +UnlinkPostmasterLock(int status, Datum arg) +{ + unlink("postmaster.pid"); +} + +void +RegisterUnlinkLockFileCallback(void) +{ + on_proc_exit(UnlinkPostmasterLock, 0); +} + + /* * Create a lockfile. * @@ -1058,14 +1080,10 @@ CreateLockFile(const char *filename, bool amPostmaster, if (PGSharedMemoryIsInUse(id1, id2)) ereport(FATAL, (errcode(ERRCODE_LOCK_FILE_EXISTS), - errmsg("pre-existing shared memory block " - "(key %lu, ID %lu) is still in use", + errmsg("pre-existing shared memory block (key %lu, ID %lu) is still in use", id1, id2), - errhint("If you're sure there are no old " - "server processes still running, remove " - "the shared memory block " - "or just delete the file \"%s\".", - filename))); + errhint("Terminate any old server processes associated with data directory \"%s\".", + refName))); } } diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 09e0df290dd..29c5ec7b58b 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -3,7 +3,7 @@ * postinit.c * postgres initialization utilities * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,10 +19,12 @@ #include #include +#include "access/genam.h" #include "access/heapam.h" #include "access/htup_details.h" #include "access/session.h" #include "access/sysattr.h" +#include "access/tableam.h" #include "access/xact.h" #include "access/xlog.h" #include "catalog/catalog.h" @@ -49,6 +51,7 @@ #include "storage/proc.h" #include "storage/sinvaladt.h" #include "storage/smgr.h" +#include "storage/sync.h" #include "tcop/tcopprot.h" #include "utils/acl.h" #include "utils/fmgroids.h" @@ -60,7 +63,6 @@ #include "utils/snapmgr.h" #include "utils/syscache.h" #include "utils/timeout.h" -#include "utils/tqual.h" static HeapTuple GetDatabaseTuple(const char *dbname); @@ -112,7 +114,7 @@ GetDatabaseTuple(const char *dbname) * built the critical shared relcache entries (i.e., we're starting up * without a shared relcache cache file). */ - relation = heap_open(DatabaseRelationId, AccessShareLock); + relation = table_open(DatabaseRelationId, AccessShareLock); scan = systable_beginscan(relation, DatabaseNameIndexId, criticalSharedRelcachesBuilt, NULL, @@ -126,7 +128,7 @@ GetDatabaseTuple(const char *dbname) /* all done */ systable_endscan(scan); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); return tuple; } @@ -146,7 +148,7 @@ GetDatabaseTupleByOid(Oid dboid) * form a scan key */ ScanKeyInit(&key[0], - ObjectIdAttributeNumber, + Anum_pg_database_oid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(dboid)); @@ -155,7 +157,7 @@ GetDatabaseTupleByOid(Oid dboid) * built the critical shared relcache entries (i.e., we're starting up * without a shared relcache cache file). */ - relation = heap_open(DatabaseRelationId, AccessShareLock); + relation = table_open(DatabaseRelationId, AccessShareLock); scan = systable_beginscan(relation, DatabaseOidIndexId, criticalSharedRelcachesBuilt, NULL, @@ -169,7 +171,7 @@ GetDatabaseTupleByOid(Oid dboid) /* all done */ systable_endscan(scan); - heap_close(relation, AccessShareLock); + table_close(relation, AccessShareLock); return tuple; } @@ -249,34 +251,56 @@ PerformAuthentication(Port *port) #ifdef USE_SSL if (port->ssl_in_use) ereport(LOG, - (errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")))); + (port->application_name != NULL + ? errmsg("replication connection authorized: user=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", + port->user_name, + port->application_name, + be_tls_get_version(port), + be_tls_get_cipher(port), + be_tls_get_cipher_bits(port), + be_tls_get_compression(port) ? _("on") : _("off")) + : errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", + port->user_name, + be_tls_get_version(port), + be_tls_get_cipher(port), + be_tls_get_cipher_bits(port), + be_tls_get_compression(port) ? _("on") : _("off")))); else #endif ereport(LOG, - (errmsg("replication connection authorized: user=%s", - port->user_name))); + (port->application_name != NULL + ? errmsg("replication connection authorized: user=%s application_name=%s", + port->user_name, + port->application_name) + : errmsg("replication connection authorized: user=%s", + port->user_name))); } else { #ifdef USE_SSL if (port->ssl_in_use) ereport(LOG, - (errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", - port->user_name, port->database_name, - be_tls_get_version(port), - be_tls_get_cipher(port), - be_tls_get_cipher_bits(port), - be_tls_get_compression(port) ? _("on") : _("off")))); + (port->application_name != NULL + ? errmsg("connection authorized: user=%s database=%s application_name=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", + port->user_name, port->database_name, port->application_name, + be_tls_get_version(port), + be_tls_get_cipher(port), + be_tls_get_cipher_bits(port), + be_tls_get_compression(port) ? _("on") : _("off")) + : errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, bits=%d, compression=%s)", + port->user_name, port->database_name, + be_tls_get_version(port), + be_tls_get_cipher(port), + be_tls_get_cipher_bits(port), + be_tls_get_compression(port) ? _("on") : _("off")))); else #endif ereport(LOG, - (errmsg("connection authorized: user=%s database=%s", - port->user_name, port->database_name))); + (port->application_name != NULL + ? errmsg("connection authorized: user=%s database=%s application_name=%s", + port->user_name, port->database_name, port->application_name) + : errmsg("connection authorized: user=%s database=%s", + port->user_name, port->database_name))); } } @@ -421,10 +445,10 @@ InitCommunication(void) if (!IsUnderPostmaster) /* postmaster already did this */ { /* - * We're running a postgres bootstrap process or a standalone backend. - * Create private "shmem" and semaphores. + * We're running a postgres bootstrap process or a standalone backend, + * so we need to set up shmem. */ - CreateSharedMemoryAndSemaphores(true, 0); + CreateSharedMemoryAndSemaphores(); } } @@ -505,7 +529,7 @@ InitializeMaxBackends(void) /* the extra unit accounts for the autovacuum launcher */ MaxBackends = MaxConnections + autovacuum_max_workers + 1 + - max_worker_processes; + max_worker_processes + max_wal_senders; /* internal error because the values were all checked previously */ if (MaxBackends > MAX_BACKENDS) @@ -532,6 +556,7 @@ BaseInit(void) /* Do local initialization of file, storage and buffer managers */ InitFileAccess(); + InitSync(); smgrinit(); InitBufferPoolAccess(); } @@ -632,8 +657,19 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, * We are either a bootstrap process or a standalone backend. Either * way, start up the XLOG machinery, and register to have it closed * down at exit. + * + * We don't yet have an aux-process resource owner, but StartupXLOG + * and ShutdownXLOG will need one. Hence, create said resource owner + * (and register a callback to clean it up after ShutdownXLOG runs). */ + CreateAuxProcessResourceOwner(); + StartupXLOG(); + /* Release (and warn about) any buffer pins leaked in StartupXLOG */ + ReleaseAuxProcessResources(true); + /* Reset CurrentResourceOwner to nothing for the moment */ + CurrentResourceOwner = NULL; + on_shmem_exit(ShutdownXLOG, 0); } @@ -778,12 +814,11 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, } /* - * The last few connection slots are reserved for superusers. Although - * replication connections currently require superuser privileges, we - * don't allow them to consume the reserved slots, which are intended for - * interactive use. + * The last few connection slots are reserved for superusers. Replication + * connections are drawn from slots reserved with max_wal_senders and not + * limited by max_connections or superuser_reserved_connections. */ - if ((!am_superuser || am_walsender) && + if (!am_superuser && !am_walsender && ReservedBackends > 0 && !HaveNFreeProcs(ReservedBackends)) ereport(FATAL, @@ -852,7 +887,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database \"%s\" does not exist", in_dbname))); dbform = (Form_pg_database) GETSTRUCT(tuple); - MyDatabaseId = HeapTupleGetOid(tuple); + MyDatabaseId = dbform->oid; MyDatabaseTableSpace = dbform->dattablespace; /* take database name from the caller, just for paranoia */ strlcpy(dbname, in_dbname, sizeof(dbname)); @@ -869,7 +904,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, (errcode(ERRCODE_UNDEFINED_DATABASE), errmsg("database %u does not exist", dboid))); dbform = (Form_pg_database) GETSTRUCT(tuple); - MyDatabaseId = HeapTupleGetOid(tuple); + MyDatabaseId = dbform->oid; MyDatabaseTableSpace = dbform->dattablespace; Assert(MyDatabaseId == dboid); strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname)); @@ -951,7 +986,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, tuple = GetDatabaseTuple(dbname); if (!HeapTupleIsValid(tuple) || - MyDatabaseId != HeapTupleGetOid(tuple) || + MyDatabaseId != ((Form_pg_database) GETSTRUCT(tuple))->oid || MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace) ereport(FATAL, (errcode(ERRCODE_UNDEFINED_DATABASE), @@ -1100,10 +1135,10 @@ process_startup_options(Port *port, bool am_superuser) char *value; name = lfirst(gucopts); - gucopts = lnext(gucopts); + gucopts = lnext(port->guc_options, gucopts); value = lfirst(gucopts); - gucopts = lnext(gucopts); + gucopts = lnext(port->guc_options, gucopts); SetConfigOption(name, value, gucctx, PGC_S_CLIENT); } @@ -1124,7 +1159,7 @@ process_settings(Oid databaseid, Oid roleid) if (!IsUnderPostmaster) return; - relsetting = heap_open(DbRoleSettingRelationId, AccessShareLock); + relsetting = table_open(DbRoleSettingRelationId, AccessShareLock); /* read all the settings under the same snapshot for efficiency */ snapshot = RegisterSnapshot(GetCatalogSnapshot(DbRoleSettingRelationId)); @@ -1136,7 +1171,7 @@ process_settings(Oid databaseid, Oid roleid) ApplySetting(snapshot, InvalidOid, InvalidOid, relsetting, PGC_S_GLOBAL); UnregisterSnapshot(snapshot); - heap_close(relsetting, AccessShareLock); + table_close(relsetting, AccessShareLock); } /* @@ -1213,16 +1248,16 @@ static bool ThereIsAtLeastOneRole(void) { Relation pg_authid_rel; - HeapScanDesc scan; + TableScanDesc scan; bool result; - pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock); + pg_authid_rel = table_open(AuthIdRelationId, AccessShareLock); - scan = heap_beginscan_catalog(pg_authid_rel, 0, NULL); + scan = table_beginscan_catalog(pg_authid_rel, 0, NULL); result = (heap_getnext(scan, ForwardScanDirection) != NULL); - heap_endscan(scan); - heap_close(pg_authid_rel, AccessShareLock); + table_endscan(scan); + table_close(pg_authid_rel, AccessShareLock); return result; } diff --git a/src/backend/utils/mb/Unicode/Makefile b/src/backend/utils/mb/Unicode/Makefile index 00a6256b66f..a97e1c6cd72 100644 --- a/src/backend/utils/mb/Unicode/Makefile +++ b/src/backend/utils/mb/Unicode/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/backend/utils/mb/Unicode # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/Makefile # diff --git a/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl b/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl index 4190ee5c7ba..bcdd29b686f 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_BIG5.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_BIG5.pl # @@ -48,12 +48,14 @@ && $code <= 0xf9dc) { push @$all, - { code => $code, + { + code => $code, ucs => $ucs, comment => $i->{comment}, direction => BOTH, f => $i->{f}, - l => $i->{l} }; + l => $i->{l} + }; } } @@ -62,9 +64,9 @@ my $code = $i->{code}; my $ucs = $i->{ucs}; -# BIG5.TXT maps several BIG5 characters to U+FFFD. The UTF-8 to BIG5 mapping can -# contain only one of them. XXX: Doesn't really make sense to include any of them, -# but for historical reasons, we map the first one of them. + # BIG5.TXT maps several BIG5 characters to U+FFFD. The UTF-8 to BIG5 mapping can + # contain only one of them. XXX: Doesn't really make sense to include any of them, + # but for historical reasons, we map the first one of them. if ($i->{ucs} == 0xFFFD && $i->{code} != 0xA15A) { $i->{direction} = TO_UNICODE; diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl index 2971e64a115..5b9fbd9b617 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # @@ -70,11 +70,13 @@ } push @mapping, - { ucs => $ucs, + { + ucs => $ucs, code => $code, direction => BOTH, f => $in_file, - l => $. }; + l => $. + }; } close($in); diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl index 1c1152e8203..1bbe7a7dd60 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_JIS_2004.pl # @@ -33,13 +33,15 @@ my $ucs2 = hex($u2); push @all, - { direction => BOTH, + { + direction => BOTH, ucs => $ucs1, ucs_second => $ucs2, code => $code, comment => $rest, f => $in_file, - l => $. }; + l => $. + }; } elsif ($line =~ /^0x(.*)[ \t]*U\+(.*)[ \t]*#(.*)$/) { @@ -52,12 +54,14 @@ next if ($code < 0x80 && $ucs < 0x80); push @all, - { direction => BOTH, + { + direction => BOTH, ucs => $ucs, code => $code, comment => $rest, f => $in_file, - l => $. }; + l => $. + }; } } close($in); diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl index 0ac1f172453..0d6e319aae1 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl # @@ -115,352 +115,524 @@ } push @mapping, ( - { direction => BOTH, + { + direction => BOTH, ucs => 0x4efc, code => 0x8ff4af, - comment => '# CJK(4EFC)' }, - { direction => BOTH, + comment => '# CJK(4EFC)' + }, + { + direction => BOTH, ucs => 0x50f4, code => 0x8ff4b0, - comment => '# CJK(50F4)' }, - { direction => BOTH, + comment => '# CJK(50F4)' + }, + { + direction => BOTH, ucs => 0x51EC, code => 0x8ff4b1, - comment => '# CJK(51EC)' }, - { direction => BOTH, + comment => '# CJK(51EC)' + }, + { + direction => BOTH, ucs => 0x5307, code => 0x8ff4b2, - comment => '# CJK(5307)' }, - { direction => BOTH, + comment => '# CJK(5307)' + }, + { + direction => BOTH, ucs => 0x5324, code => 0x8ff4b3, - comment => '# CJK(5324)' }, - { direction => BOTH, + comment => '# CJK(5324)' + }, + { + direction => BOTH, ucs => 0x548A, code => 0x8ff4b5, - comment => '# CJK(548A)' }, - { direction => BOTH, + comment => '# CJK(548A)' + }, + { + direction => BOTH, ucs => 0x5759, code => 0x8ff4b6, - comment => '# CJK(5759)' }, - { direction => BOTH, + comment => '# CJK(5759)' + }, + { + direction => BOTH, ucs => 0x589E, code => 0x8ff4b9, - comment => '# CJK(589E)' }, - { direction => BOTH, + comment => '# CJK(589E)' + }, + { + direction => BOTH, ucs => 0x5BEC, code => 0x8ff4ba, - comment => '# CJK(5BEC)' }, - { direction => BOTH, + comment => '# CJK(5BEC)' + }, + { + direction => BOTH, ucs => 0x5CF5, code => 0x8ff4bb, - comment => '# CJK(5CF5)' }, - { direction => BOTH, + comment => '# CJK(5CF5)' + }, + { + direction => BOTH, ucs => 0x5D53, code => 0x8ff4bc, - comment => '# CJK(5D53)' }, - { direction => BOTH, + comment => '# CJK(5D53)' + }, + { + direction => BOTH, ucs => 0x5FB7, code => 0x8ff4be, - comment => '# CJK(5FB7)' }, - { direction => BOTH, + comment => '# CJK(5FB7)' + }, + { + direction => BOTH, ucs => 0x6085, code => 0x8ff4bf, - comment => '# CJK(6085)' }, - { direction => BOTH, + comment => '# CJK(6085)' + }, + { + direction => BOTH, ucs => 0x6120, code => 0x8ff4c0, - comment => '# CJK(6120)' }, - { direction => BOTH, + comment => '# CJK(6120)' + }, + { + direction => BOTH, ucs => 0x654E, code => 0x8ff4c1, - comment => '# CJK(654E)' }, - { direction => BOTH, + comment => '# CJK(654E)' + }, + { + direction => BOTH, ucs => 0x663B, code => 0x8ff4c2, - comment => '# CJK(663B)' }, - { direction => BOTH, + comment => '# CJK(663B)' + }, + { + direction => BOTH, ucs => 0x6665, code => 0x8ff4c3, - comment => '# CJK(6665)' }, - { direction => BOTH, + comment => '# CJK(6665)' + }, + { + direction => BOTH, ucs => 0x6801, code => 0x8ff4c6, - comment => '# CJK(6801)' }, - { direction => BOTH, + comment => '# CJK(6801)' + }, + { + direction => BOTH, ucs => 0x6A6B, code => 0x8ff4c9, - comment => '# CJK(6A6B)' }, - { direction => BOTH, + comment => '# CJK(6A6B)' + }, + { + direction => BOTH, ucs => 0x6AE2, code => 0x8ff4ca, - comment => '# CJK(6AE2)' }, - { direction => BOTH, + comment => '# CJK(6AE2)' + }, + { + direction => BOTH, ucs => 0x6DF2, code => 0x8ff4cc, - comment => '# CJK(6DF2)' }, - { direction => BOTH, + comment => '# CJK(6DF2)' + }, + { + direction => BOTH, ucs => 0x6DF8, code => 0x8ff4cb, - comment => '# CJK(6DF8)' }, - { direction => BOTH, + comment => '# CJK(6DF8)' + }, + { + direction => BOTH, ucs => 0x7028, code => 0x8ff4cd, - comment => '# CJK(7028)' }, - { direction => BOTH, + comment => '# CJK(7028)' + }, + { + direction => BOTH, ucs => 0x70BB, code => 0x8ff4ae, - comment => '# CJK(70BB)' }, - { direction => BOTH, + comment => '# CJK(70BB)' + }, + { + direction => BOTH, ucs => 0x7501, code => 0x8ff4d0, - comment => '# CJK(7501)' }, - { direction => BOTH, + comment => '# CJK(7501)' + }, + { + direction => BOTH, ucs => 0x7682, code => 0x8ff4d1, - comment => '# CJK(7682)' }, - { direction => BOTH, + comment => '# CJK(7682)' + }, + { + direction => BOTH, ucs => 0x769E, code => 0x8ff4d2, - comment => '# CJK(769E)' }, - { direction => BOTH, + comment => '# CJK(769E)' + }, + { + direction => BOTH, ucs => 0x7930, code => 0x8ff4d4, - comment => '# CJK(7930)' }, - { direction => BOTH, + comment => '# CJK(7930)' + }, + { + direction => BOTH, ucs => 0x7AE7, code => 0x8ff4d9, - comment => '# CJK(7AE7)' }, - { direction => BOTH, + comment => '# CJK(7AE7)' + }, + { + direction => BOTH, ucs => 0x7DA0, code => 0x8ff4dc, - comment => '# CJK(7DA0)' }, - { direction => BOTH, + comment => '# CJK(7DA0)' + }, + { + direction => BOTH, ucs => 0x7DD6, code => 0x8ff4dd, - comment => '# CJK(7DD6)' }, - { direction => BOTH, + comment => '# CJK(7DD6)' + }, + { + direction => BOTH, ucs => 0x8362, code => 0x8ff4df, - comment => '# CJK(8362)' }, - { direction => BOTH, + comment => '# CJK(8362)' + }, + { + direction => BOTH, ucs => 0x85B0, code => 0x8ff4e1, - comment => '# CJK(85B0)' }, - { direction => BOTH, + comment => '# CJK(85B0)' + }, + { + direction => BOTH, ucs => 0x8807, code => 0x8ff4e4, - comment => '# CJK(8807)' }, - { direction => BOTH, + comment => '# CJK(8807)' + }, + { + direction => BOTH, ucs => 0x8B7F, code => 0x8ff4e6, - comment => '# CJK(8B7F)' }, - { direction => BOTH, + comment => '# CJK(8B7F)' + }, + { + direction => BOTH, ucs => 0x8CF4, code => 0x8ff4e7, - comment => '# CJK(8CF4)' }, - { direction => BOTH, + comment => '# CJK(8CF4)' + }, + { + direction => BOTH, ucs => 0x8D76, code => 0x8ff4e8, - comment => '# CJK(8D76)' }, - { direction => BOTH, + comment => '# CJK(8D76)' + }, + { + direction => BOTH, ucs => 0x90DE, code => 0x8ff4ec, - comment => '# CJK(90DE)' }, - { direction => BOTH, + comment => '# CJK(90DE)' + }, + { + direction => BOTH, ucs => 0x9115, code => 0x8ff4ee, - comment => '# CJK(9115)' }, - { direction => BOTH, + comment => '# CJK(9115)' + }, + { + direction => BOTH, ucs => 0x9592, code => 0x8ff4f1, - comment => '# CJK(9592)' }, - { direction => BOTH, + comment => '# CJK(9592)' + }, + { + direction => BOTH, ucs => 0x973B, code => 0x8ff4f4, - comment => '# CJK(973B)' }, - { direction => BOTH, + comment => '# CJK(973B)' + }, + { + direction => BOTH, ucs => 0x974D, code => 0x8ff4f5, - comment => '# CJK(974D)' }, - { direction => BOTH, + comment => '# CJK(974D)' + }, + { + direction => BOTH, ucs => 0x9751, code => 0x8ff4f6, - comment => '# CJK(9751)' }, - { direction => BOTH, + comment => '# CJK(9751)' + }, + { + direction => BOTH, ucs => 0x999E, code => 0x8ff4fa, - comment => '# CJK(999E)' }, - { direction => BOTH, + comment => '# CJK(999E)' + }, + { + direction => BOTH, ucs => 0x9AD9, code => 0x8ff4fb, - comment => '# CJK(9AD9)' }, - { direction => BOTH, + comment => '# CJK(9AD9)' + }, + { + direction => BOTH, ucs => 0x9B72, code => 0x8ff4fc, - comment => '# CJK(9B72)' }, - { direction => BOTH, + comment => '# CJK(9B72)' + }, + { + direction => BOTH, ucs => 0x9ED1, code => 0x8ff4fe, - comment => '# CJK(9ED1)' }, - { direction => BOTH, + comment => '# CJK(9ED1)' + }, + { + direction => BOTH, ucs => 0xF929, code => 0x8ff4c5, - comment => '# CJK COMPATIBILITY IDEOGRAPH-F929' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-F929' + }, + { + direction => BOTH, ucs => 0xF9DC, code => 0x8ff4f2, - comment => '# CJK COMPATIBILITY IDEOGRAPH-F9DC' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-F9DC' + }, + { + direction => BOTH, ucs => 0xFA0E, code => 0x8ff4b4, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA0E' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA0E' + }, + { + direction => BOTH, ucs => 0xFA0F, code => 0x8ff4b7, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA0F' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA0F' + }, + { + direction => BOTH, ucs => 0xFA10, code => 0x8ff4b8, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA10' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA10' + }, + { + direction => BOTH, ucs => 0xFA11, code => 0x8ff4bd, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA11' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA11' + }, + { + direction => BOTH, ucs => 0xFA12, code => 0x8ff4c4, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA12' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA12' + }, + { + direction => BOTH, ucs => 0xFA13, code => 0x8ff4c7, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA13' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA13' + }, + { + direction => BOTH, ucs => 0xFA14, code => 0x8ff4c8, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA14' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA14' + }, + { + direction => BOTH, ucs => 0xFA15, code => 0x8ff4ce, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA15' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA15' + }, + { + direction => BOTH, ucs => 0xFA16, code => 0x8ff4cf, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA16' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA16' + }, + { + direction => BOTH, ucs => 0xFA17, code => 0x8ff4d3, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA17' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA17' + }, + { + direction => BOTH, ucs => 0xFA18, code => 0x8ff4d5, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA18' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA18' + }, + { + direction => BOTH, ucs => 0xFA19, code => 0x8ff4d6, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA19' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA19' + }, + { + direction => BOTH, ucs => 0xFA1A, code => 0x8ff4d7, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1A' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1A' + }, + { + direction => BOTH, ucs => 0xFA1B, code => 0x8ff4d8, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1B' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1B' + }, + { + direction => BOTH, ucs => 0xFA1C, code => 0x8ff4da, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1C' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1C' + }, + { + direction => BOTH, ucs => 0xFA1D, code => 0x8ff4db, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1D' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1D' + }, + { + direction => BOTH, ucs => 0xFA1E, code => 0x8ff4de, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1E' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1E' + }, + { + direction => BOTH, ucs => 0xFA1F, code => 0x8ff4e0, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1F' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA1F' + }, + { + direction => BOTH, ucs => 0xFA20, code => 0x8ff4e2, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA20' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA20' + }, + { + direction => BOTH, ucs => 0xFA21, code => 0x8ff4e3, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA21' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA21' + }, + { + direction => BOTH, ucs => 0xFA22, code => 0x8ff4e5, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA22' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA22' + }, + { + direction => BOTH, ucs => 0xFA23, code => 0x8ff4e9, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA23' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA23' + }, + { + direction => BOTH, ucs => 0xFA24, code => 0x8ff4ea, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA24' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA24' + }, + { + direction => BOTH, ucs => 0xFA25, code => 0x8ff4eb, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA25' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA25' + }, + { + direction => BOTH, ucs => 0xFA26, code => 0x8ff4ed, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA26' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA26' + }, + { + direction => BOTH, ucs => 0xFA27, code => 0x8ff4ef, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA27' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA27' + }, + { + direction => BOTH, ucs => 0xFA28, code => 0x8ff4f0, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA28' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA28' + }, + { + direction => BOTH, ucs => 0xFA29, code => 0x8ff4f3, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA29' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA29' + }, + { + direction => BOTH, ucs => 0xFA2A, code => 0x8ff4f7, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2A' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2A' + }, + { + direction => BOTH, ucs => 0xFA2B, code => 0x8ff4f8, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2B' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2B' + }, + { + direction => BOTH, ucs => 0xFA2C, code => 0x8ff4f9, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2C' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2C' + }, + { + direction => BOTH, ucs => 0xFA2D, code => 0x8ff4fd, - comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2D' }, - { direction => BOTH, + comment => '# CJK COMPATIBILITY IDEOGRAPH-FA2D' + }, + { + direction => BOTH, ucs => 0xFF07, code => 0x8ff4a9, - comment => '# FULLWIDTH APOSTROPHE' }, - { direction => BOTH, + comment => '# FULLWIDTH APOSTROPHE' + }, + { + direction => BOTH, ucs => 0xFFE4, code => 0x8fa2c3, - comment => '# FULLWIDTH BROKEN BAR' }, + comment => '# FULLWIDTH BROKEN BAR' + }, # additional conversions for EUC_JP -> UTF-8 conversion - { direction => TO_UNICODE, + { + direction => TO_UNICODE, ucs => 0x2116, code => 0x8ff4ac, - comment => '# NUMERO SIGN' }, - { direction => TO_UNICODE, + comment => '# NUMERO SIGN' + }, + { + direction => TO_UNICODE, ucs => 0x2121, code => 0x8ff4ad, - comment => '# TELEPHONE SIGN' }, - { direction => TO_UNICODE, + comment => '# TELEPHONE SIGN' + }, + { + direction => TO_UNICODE, ucs => 0x3231, code => 0x8ff4ab, - comment => '# PARENTHESIZED IDEOGRAPH STOCK' }); + comment => '# PARENTHESIZED IDEOGRAPH STOCK' + }); print_conversion_tables($this_script, "EUC_JP", \@mapping); diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl index 4d6a3cabaae..c6894d3a551 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl # @@ -32,23 +32,29 @@ # Some extra characters that are not in KSX1001.TXT push @$mapping, - ( { direction => BOTH, + ( { + direction => BOTH, ucs => 0x20AC, code => 0xa2e6, comment => '# EURO SIGN', f => $this_script, - l => __LINE__ }, - { direction => BOTH, + l => __LINE__ + }, + { + direction => BOTH, ucs => 0x00AE, code => 0xa2e7, comment => '# REGISTERED SIGN', f => $this_script, - l => __LINE__ }, - { direction => BOTH, + l => __LINE__ + }, + { + direction => BOTH, ucs => 0x327E, code => 0xa2e8, comment => '# CIRCLED HANGUL IEUNG U', f => $this_script, - l => __LINE__ }); + l => __LINE__ + }); print_conversion_tables($this_script, "EUC_KR", $mapping); diff --git a/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl b/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl index 89f3cd70061..30bb03e6630 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl # @@ -53,12 +53,14 @@ if ($origcode >= 0x12121 && $origcode <= 0x20000) { push @extras, - { ucs => $i->{ucs}, + { + ucs => $i->{ucs}, code => ($i->{code} + 0x8ea10000), rest => $i->{rest}, direction => TO_UNICODE, f => $i->{f}, - l => $i->{l} }; + l => $i->{l} + }; } } diff --git a/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl b/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl index ec184d760f3..77b2c5b0e21 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_GB18030.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # @@ -36,11 +36,13 @@ if ($code >= 0x80 && $ucs >= 0x0080) { push @mapping, - { ucs => $ucs, + { + ucs => $ucs, code => $code, direction => BOTH, f => $in_file, - l => $. }; + l => $. + }; } } close($in); diff --git a/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl b/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl index b580373a5ca..222093dff22 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl # @@ -26,23 +26,29 @@ # Some extra characters that are not in JOHAB.TXT push @$mapping, - ( { direction => BOTH, + ( { + direction => BOTH, ucs => 0x20AC, code => 0xd9e6, comment => '# EURO SIGN', f => $this_script, - l => __LINE__ }, - { direction => BOTH, + l => __LINE__ + }, + { + direction => BOTH, ucs => 0x00AE, code => 0xd9e7, comment => '# REGISTERED SIGN', f => $this_script, - l => __LINE__ }, - { direction => BOTH, + l => __LINE__ + }, + { + direction => BOTH, ucs => 0x327E, code => 0xd9e8, comment => '# CIRCLED HANGUL IEUNG U', f => $this_script, - l => __LINE__ }); + l => __LINE__ + }); print_conversion_tables($this_script, "JOHAB", $mapping); diff --git a/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl b/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl index d153e4c8e63..a1e03023714 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_SHIFT_JIS_2004.pl # @@ -33,13 +33,15 @@ my $ucs2 = hex($u2); push @mapping, - { code => $code, + { + code => $code, ucs => $ucs1, ucs_second => $ucs2, comment => $rest, direction => BOTH, f => $in_file, - l => $. }; + l => $. + }; } elsif ($line =~ /^0x(.*)[ \t]*U\+(.*)[ \t]*#(.*)$/) { @@ -68,12 +70,14 @@ } push @mapping, - { code => $code, + { + code => $code, ucs => $ucs, comment => $rest, direction => $direction, f => $in_file, - l => $. }; + l => $. + }; } } close($in); diff --git a/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl b/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl index a50f6f39cdd..e6c67597797 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_SJIS.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_SJIS.pl # @@ -36,53 +36,69 @@ # Add these UTF8->SJIS pairs to the table. push @$mapping, - ( { direction => FROM_UNICODE, + ( { + direction => FROM_UNICODE, ucs => 0x00a2, code => 0x8191, comment => '# CENT SIGN', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x00a3, code => 0x8192, comment => '# POUND SIGN', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x00a5, code => 0x5c, comment => '# YEN SIGN', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x00ac, code => 0x81ca, comment => '# NOT SIGN', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x2016, code => 0x8161, comment => '# DOUBLE VERTICAL LINE', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x203e, code => 0x7e, comment => '# OVERLINE', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x2212, code => 0x817c, comment => '# MINUS SIGN', f => $this_script, - l => __LINE__ }, - { direction => FROM_UNICODE, + l => __LINE__ + }, + { + direction => FROM_UNICODE, ucs => 0x301c, code => 0x8160, comment => '# WAVE DASH', f => $this_script, - l => __LINE__ }); + l => __LINE__ + }); print_conversion_tables($this_script, "SJIS", $mapping); diff --git a/src/backend/utils/mb/Unicode/UCS_to_UHC.pl b/src/backend/utils/mb/Unicode/UCS_to_UHC.pl index dc9fb753b9c..da2bdbad175 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_UHC.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_UHC.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_GB18030.pl # @@ -39,22 +39,26 @@ if ($code >= 0x80 && $ucs >= 0x0080) { push @mapping, - { ucs => $ucs, + { + ucs => $ucs, code => $code, direction => BOTH, f => $in_file, - l => $. }; + l => $. + }; } } close($in); # One extra character that's not in the source file. push @mapping, - { direction => BOTH, + { + direction => BOTH, code => 0xa2e8, ucs => 0x327e, comment => 'CIRCLED HANGUL IEUNG U', f => $this_script, - l => __LINE__ }; + l => __LINE__ + }; print_conversion_tables($this_script, "UHC", \@mapping); diff --git a/src/backend/utils/mb/Unicode/UCS_to_most.pl b/src/backend/utils/mb/Unicode/UCS_to_most.pl index 445344932a3..647417b4bf8 100755 --- a/src/backend/utils/mb/Unicode/UCS_to_most.pl +++ b/src/backend/utils/mb/Unicode/UCS_to_most.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/UCS_to_most.pl # diff --git a/src/backend/utils/mb/Unicode/convutils.pm b/src/backend/utils/mb/Unicode/convutils.pm index 69494d0df32..a92ca5cd68a 100644 --- a/src/backend/utils/mb/Unicode/convutils.pm +++ b/src/backend/utils/mb/Unicode/convutils.pm @@ -1,5 +1,5 @@ # -# Copyright (c) 2001-2018, PostgreSQL Global Development Group +# Copyright (c) 2001-2019, PostgreSQL Global Development Group # # src/backend/utils/mb/Unicode/convutils.pm @@ -18,7 +18,8 @@ use constant { NONE => 0, TO_UNICODE => 1, FROM_UNICODE => 2, - BOTH => 3 }; + BOTH => 3 +}; ####################################################################### # read_source - common routine to read source file @@ -56,7 +57,8 @@ sub read_source comment => $4, direction => BOTH, f => $fname, - l => $. }; + l => $. + }; # Ignore pure ASCII mappings. PostgreSQL character conversion code # never even passes these to the conversion code. @@ -97,6 +99,7 @@ sub print_conversion_tables $charset); print_conversion_tables_direction($this_script, $csname, TO_UNICODE, $charset); + return; } ############################################################################# @@ -138,11 +141,11 @@ sub print_conversion_tables_direction print $out "/* src/backend/utils/mb/Unicode/$fname */\n"; print $out "/* This file is generated by $this_script */\n\n"; -# Collect regular, non-combined, mappings, and create the radix tree from them. + # Collect regular, non-combined, mappings, and create the radix tree from them. my $charmap = &make_charmap($out, $charset, $direction, 0); print_radix_table($out, $tblname, $charmap); - # Collect combined characters, and create combined character table (if any) + # Collect combined characters, and create combined character table (if any) my $charmap_combined = &make_charmap_combined($charset, $direction); if (scalar @{$charmap_combined} > 0) @@ -158,6 +161,7 @@ sub print_conversion_tables_direction } close($out); + return; } sub print_from_utf8_combined_map @@ -168,7 +172,7 @@ sub print_from_utf8_combined_map printf $out "\n/* Combined character map */\n"; printf $out -"static const pg_utf_to_local_combined ULmap${charset}_combined[ %d ] = {", + "static const pg_utf_to_local_combined ULmap${charset}_combined[ %d ] = {", scalar(@$table); my $first = 1; foreach my $i (sort { $a->{utf8} <=> $b->{utf8} } @$table) @@ -192,6 +196,7 @@ sub print_from_utf8_combined_map } print $out "\t/* $last_comment */" if ($verbose && $last_comment ne ""); print $out "\n};\n"; + return; } sub print_to_utf8_combined_map @@ -202,7 +207,7 @@ sub print_to_utf8_combined_map printf $out "\n/* Combined character map */\n"; printf $out -"static const pg_local_to_utf_combined LUmap${charset}_combined[ %d ] = {", + "static const pg_local_to_utf_combined LUmap${charset}_combined[ %d ] = {", scalar(@$table); my $first = 1; @@ -228,6 +233,7 @@ sub print_to_utf8_combined_map } print $out "\t/* $last_comment */" if ($verbose && $last_comment ne ""); print $out "\n};\n"; + return; } ####################################################################### @@ -254,18 +260,18 @@ sub print_radix_table { my $out = $c->{$in}; - if ($in < 0x100) + if ($in <= 0xff) { $b1map{$in} = $out; } - elsif ($in < 0x10000) + elsif ($in <= 0xffff) { my $b1 = $in >> 8; my $b2 = $in & 0xff; $b2map{$b1}{$b2} = $out; } - elsif ($in < 0x1000000) + elsif ($in <= 0xffffff) { my $b1 = $in >> 16; my $b2 = ($in >> 8) & 0xff; @@ -273,7 +279,7 @@ sub print_radix_table $b3map{$b1}{$b2}{$b3} = $out; } - elsif ($in < 0x100000000) + elsif ($in <= 0xffffffff) { my $b1 = $in >> 24; my $b2 = ($in >> 16) & 0xff; @@ -370,9 +376,11 @@ sub print_radix_table } unshift @segments, - { header => "Dummy map, for invalid values", + { + header => "Dummy map, for invalid values", min_idx => 0, - max_idx => $widest_range }; + max_idx => $widest_range + }; ### ### Eliminate overlapping zeros @@ -613,7 +621,7 @@ sub print_radix_table if ($seg->{overlaid_trail_zeros}) { printf $out -" /* $seg->{overlaid_trail_zeros} trailing zero values shared with next segment */\n"; + " /* $seg->{overlaid_trail_zeros} trailing zero values shared with next segment */\n"; } } @@ -621,6 +629,7 @@ sub print_radix_table if ($off != $tblsize) { die "table size didn't match!"; } print $out "};\n"; + return; } ### @@ -655,12 +664,14 @@ sub build_segments_recurse if ($level == $depth) { push @segments, - { header => $header . ", leaf: ${path}xx", + { + header => $header . ", leaf: ${path}xx", label => $label, level => $level, depth => $depth, path => $path, - values => $map }; + values => $map + }; } else { @@ -678,12 +689,14 @@ sub build_segments_recurse } push @segments, - { header => $header . ", byte #$level: ${path}xx", + { + header => $header . ", byte #$level: ${path}xx", label => $label, level => $level, depth => $depth, path => $path, - values => \%children }; + values => \%children + }; } return @segments; } @@ -728,7 +741,7 @@ sub make_charmap if (defined $charmap{$src}) { printf STDERR -"Error: duplicate source code on %s:%d: 0x%04x => 0x%04x, 0x%04x\n", + "Error: duplicate source code on %s:%d: 0x%04x => 0x%04x, 0x%04x\n", $c->{f}, $c->{l}, $src, $charmap{$src}, $dst; exit; } @@ -776,7 +789,8 @@ sub make_charmap_combined code => $c->{code}, comment => $c->{comment}, f => $c->{f}, - l => $c->{l} }; + l => $c->{l} + }; push @combined, $entry; } } diff --git a/src/backend/utils/mb/conv.c b/src/backend/utils/mb/conv.c index fb7c9253972..3ecc92b0a6a 100644 --- a/src/backend/utils/mb/conv.c +++ b/src/backend/utils/mb/conv.c @@ -2,7 +2,7 @@ * * Utility functions for conversion procs. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -132,51 +132,6 @@ mic2latin(const unsigned char *mic, unsigned char *p, int len, } -/* - * ASCII ---> MIC - * - * While ordinarily SQL_ASCII encoding is forgiving of high-bit-set - * characters, here we must take a hard line because we don't know - * the appropriate MIC equivalent. - */ -void -pg_ascii2mic(const unsigned char *l, unsigned char *p, int len) -{ - int c1; - - while (len > 0) - { - c1 = *l; - if (c1 == 0 || IS_HIGHBIT_SET(c1)) - report_invalid_encoding(PG_SQL_ASCII, (const char *) l, len); - *p++ = c1; - l++; - len--; - } - *p = '\0'; -} - -/* - * MIC ---> ASCII - */ -void -pg_mic2ascii(const unsigned char *mic, unsigned char *p, int len) -{ - int c1; - - while (len > 0) - { - c1 = *mic; - if (c1 == 0 || IS_HIGHBIT_SET(c1)) - report_untranslatable_char(PG_MULE_INTERNAL, PG_SQL_ASCII, - (const char *) mic, len); - *p++ = c1; - mic++; - len--; - } - *p = '\0'; -} - /* * latin2mic_with_table: a generic single byte charset encoding * conversion from a local charset to the mule internal code. diff --git a/src/backend/utils/mb/conversion_procs/.gitignore b/src/backend/utils/mb/conversion_procs/.gitignore deleted file mode 100644 index 3e30742a156..00000000000 --- a/src/backend/utils/mb/conversion_procs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/conversion_create.sql diff --git a/src/backend/utils/mb/conversion_procs/Makefile b/src/backend/utils/mb/conversion_procs/Makefile index 879467ea5e3..413aeb9861e 100644 --- a/src/backend/utils/mb/conversion_procs/Makefile +++ b/src/backend/utils/mb/conversion_procs/Makefile @@ -1,10 +1,11 @@ #------------------------------------------------------------------------- # -# Makefile-- -# Makefile for utils/mb/conversion_procs +# Makefile for backend/utils/mb/conversion_procs # -# IDENTIFICATION -# src/backend/utils/mb/conversion_procs/Makefile +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/backend/utils/mb/conversion_procs/Makefile # #------------------------------------------------------------------------- @@ -12,183 +13,13 @@ subdir = src/backend/utils/mb/conversion_procs top_builddir = ../../../../.. include $(top_builddir)/src/Makefile.global -SQLSCRIPT = conversion_create.sql - SUBDIRS = \ - ascii_and_mic cyrillic_and_mic euc_cn_and_mic euc_jp_and_sjis \ + cyrillic_and_mic euc_cn_and_mic euc_jp_and_sjis \ euc_kr_and_mic euc_tw_and_big5 latin2_and_win1250 latin_and_mic \ - utf8_and_ascii utf8_and_big5 utf8_and_cyrillic utf8_and_euc_cn \ + utf8_and_big5 utf8_and_cyrillic utf8_and_euc_cn \ utf8_and_euc_jp utf8_and_euc_kr utf8_and_euc_tw utf8_and_gb18030 \ utf8_and_gbk utf8_and_iso8859 utf8_and_iso8859_1 utf8_and_johab \ utf8_and_sjis utf8_and_win utf8_and_uhc \ utf8_and_euc2004 utf8_and_sjis2004 euc2004_sjis2004 $(recurse) - -# conversion_name source_encoding destination_encoding function object -CONVERSIONS = \ - ascii_to_mic SQL_ASCII MULE_INTERNAL ascii_to_mic ascii_and_mic \ - mic_to_ascii MULE_INTERNAL SQL_ASCII mic_to_ascii ascii_and_mic \ - koi8_r_to_mic KOI8R MULE_INTERNAL koi8r_to_mic cyrillic_and_mic \ - mic_to_koi8_r MULE_INTERNAL KOI8R mic_to_koi8r cyrillic_and_mic \ - iso_8859_5_to_mic ISO-8859-5 MULE_INTERNAL iso_to_mic cyrillic_and_mic \ - mic_to_iso_8859_5 MULE_INTERNAL ISO-8859-5 mic_to_iso cyrillic_and_mic \ - windows_1251_to_mic WIN1251 MULE_INTERNAL win1251_to_mic cyrillic_and_mic \ - mic_to_windows_1251 MULE_INTERNAL WIN1251 mic_to_win1251 cyrillic_and_mic \ - windows_866_to_mic WIN866 MULE_INTERNAL win866_to_mic cyrillic_and_mic \ - mic_to_windows_866 MULE_INTERNAL WIN866 mic_to_win866 cyrillic_and_mic \ - koi8_r_to_windows_1251 KOI8R WIN1251 koi8r_to_win1251 cyrillic_and_mic \ - windows_1251_to_koi8_r WIN1251 KOI8R win1251_to_koi8r cyrillic_and_mic \ - koi8_r_to_windows_866 KOI8R WIN866 koi8r_to_win866 cyrillic_and_mic \ - windows_866_to_koi8_r WIN866 KOI8R win866_to_koi8r cyrillic_and_mic \ - windows_866_to_windows_1251 WIN866 WIN1251 win866_to_win1251 cyrillic_and_mic \ - windows_1251_to_windows_866 WIN1251 WIN866 win1251_to_win866 cyrillic_and_mic \ - iso_8859_5_to_koi8_r ISO-8859-5 KOI8R iso_to_koi8r cyrillic_and_mic \ - koi8_r_to_iso_8859_5 KOI8R ISO-8859-5 koi8r_to_iso cyrillic_and_mic \ - iso_8859_5_to_windows_1251 ISO-8859-5 WIN1251 iso_to_win1251 cyrillic_and_mic \ - windows_1251_to_iso_8859_5 WIN1251 ISO-8859-5 win1251_to_iso cyrillic_and_mic \ - iso_8859_5_to_windows_866 ISO-8859-5 WIN866 iso_to_win866 cyrillic_and_mic \ - windows_866_to_iso_8859_5 WIN866 ISO-8859-5 win866_to_iso cyrillic_and_mic \ - euc_cn_to_mic EUC_CN MULE_INTERNAL euc_cn_to_mic euc_cn_and_mic \ - mic_to_euc_cn MULE_INTERNAL EUC_CN mic_to_euc_cn euc_cn_and_mic \ - euc_jp_to_sjis EUC_JP SJIS euc_jp_to_sjis euc_jp_and_sjis \ - sjis_to_euc_jp SJIS EUC_JP sjis_to_euc_jp euc_jp_and_sjis \ - euc_jp_to_mic EUC_JP MULE_INTERNAL euc_jp_to_mic euc_jp_and_sjis \ - sjis_to_mic SJIS MULE_INTERNAL sjis_to_mic euc_jp_and_sjis \ - mic_to_euc_jp MULE_INTERNAL EUC_JP mic_to_euc_jp euc_jp_and_sjis \ - mic_to_sjis MULE_INTERNAL SJIS mic_to_sjis euc_jp_and_sjis \ - euc_kr_to_mic EUC_KR MULE_INTERNAL euc_kr_to_mic euc_kr_and_mic \ - mic_to_euc_kr MULE_INTERNAL EUC_KR mic_to_euc_kr euc_kr_and_mic \ - euc_tw_to_big5 EUC_TW BIG5 euc_tw_to_big5 euc_tw_and_big5 \ - big5_to_euc_tw BIG5 EUC_TW big5_to_euc_tw euc_tw_and_big5 \ - euc_tw_to_mic EUC_TW MULE_INTERNAL euc_tw_to_mic euc_tw_and_big5 \ - big5_to_mic BIG5 MULE_INTERNAL big5_to_mic euc_tw_and_big5 \ - mic_to_euc_tw MULE_INTERNAL EUC_TW mic_to_euc_tw euc_tw_and_big5 \ - mic_to_big5 MULE_INTERNAL BIG5 mic_to_big5 euc_tw_and_big5 \ - iso_8859_2_to_mic LATIN2 MULE_INTERNAL latin2_to_mic latin2_and_win1250 \ - mic_to_iso_8859_2 MULE_INTERNAL LATIN2 mic_to_latin2 latin2_and_win1250 \ - windows_1250_to_mic WIN1250 MULE_INTERNAL win1250_to_mic latin2_and_win1250 \ - mic_to_windows_1250 MULE_INTERNAL WIN1250 mic_to_win1250 latin2_and_win1250 \ - iso_8859_2_to_windows_1250 LATIN2 WIN1250 latin2_to_win1250 latin2_and_win1250 \ - windows_1250_to_iso_8859_2 WIN1250 LATIN2 win1250_to_latin2 latin2_and_win1250 \ - iso_8859_1_to_mic LATIN1 MULE_INTERNAL latin1_to_mic latin_and_mic \ - mic_to_iso_8859_1 MULE_INTERNAL LATIN1 mic_to_latin1 latin_and_mic \ - iso_8859_3_to_mic LATIN3 MULE_INTERNAL latin3_to_mic latin_and_mic \ - mic_to_iso_8859_3 MULE_INTERNAL LATIN3 mic_to_latin3 latin_and_mic \ - iso_8859_4_to_mic LATIN4 MULE_INTERNAL latin4_to_mic latin_and_mic \ - mic_to_iso_8859_4 MULE_INTERNAL LATIN4 mic_to_latin4 latin_and_mic \ - ascii_to_utf8 SQL_ASCII UTF8 ascii_to_utf8 utf8_and_ascii \ - utf8_to_ascii UTF8 SQL_ASCII utf8_to_ascii utf8_and_ascii \ - big5_to_utf8 BIG5 UTF8 big5_to_utf8 utf8_and_big5 \ - utf8_to_big5 UTF8 BIG5 utf8_to_big5 utf8_and_big5 \ - utf8_to_koi8_r UTF8 KOI8R utf8_to_koi8r utf8_and_cyrillic \ - koi8_r_to_utf8 KOI8R UTF8 koi8r_to_utf8 utf8_and_cyrillic \ - utf8_to_koi8_u UTF8 KOI8U utf8_to_koi8u utf8_and_cyrillic \ - koi8_u_to_utf8 KOI8U UTF8 koi8u_to_utf8 utf8_and_cyrillic \ - utf8_to_windows_866 UTF8 WIN866 utf8_to_win utf8_and_win \ - windows_866_to_utf8 WIN866 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_874 UTF8 WIN874 utf8_to_win utf8_and_win \ - windows_874_to_utf8 WIN874 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1250 UTF8 WIN1250 utf8_to_win utf8_and_win \ - windows_1250_to_utf8 WIN1250 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1251 UTF8 WIN1251 utf8_to_win utf8_and_win \ - windows_1251_to_utf8 WIN1251 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1252 UTF8 WIN1252 utf8_to_win utf8_and_win \ - windows_1252_to_utf8 WIN1252 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1253 UTF8 WIN1253 utf8_to_win utf8_and_win \ - windows_1253_to_utf8 WIN1253 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1254 UTF8 WIN1254 utf8_to_win utf8_and_win \ - windows_1254_to_utf8 WIN1254 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1255 UTF8 WIN1255 utf8_to_win utf8_and_win \ - windows_1255_to_utf8 WIN1255 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1256 UTF8 WIN1256 utf8_to_win utf8_and_win \ - windows_1256_to_utf8 WIN1256 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1257 UTF8 WIN1257 utf8_to_win utf8_and_win \ - windows_1257_to_utf8 WIN1257 UTF8 win_to_utf8 utf8_and_win \ - utf8_to_windows_1258 UTF8 WIN1258 utf8_to_win utf8_and_win \ - windows_1258_to_utf8 WIN1258 UTF8 win_to_utf8 utf8_and_win \ - euc_cn_to_utf8 EUC_CN UTF8 euc_cn_to_utf8 utf8_and_euc_cn \ - utf8_to_euc_cn UTF8 EUC_CN utf8_to_euc_cn utf8_and_euc_cn \ - euc_jp_to_utf8 EUC_JP UTF8 euc_jp_to_utf8 utf8_and_euc_jp \ - utf8_to_euc_jp UTF8 EUC_JP utf8_to_euc_jp utf8_and_euc_jp \ - euc_kr_to_utf8 EUC_KR UTF8 euc_kr_to_utf8 utf8_and_euc_kr \ - utf8_to_euc_kr UTF8 EUC_KR utf8_to_euc_kr utf8_and_euc_kr \ - euc_tw_to_utf8 EUC_TW UTF8 euc_tw_to_utf8 utf8_and_euc_tw \ - utf8_to_euc_tw UTF8 EUC_TW utf8_to_euc_tw utf8_and_euc_tw \ - gb18030_to_utf8 GB18030 UTF8 gb18030_to_utf8 utf8_and_gb18030 \ - utf8_to_gb18030 UTF8 GB18030 utf8_to_gb18030 utf8_and_gb18030 \ - gbk_to_utf8 GBK UTF8 gbk_to_utf8 utf8_and_gbk \ - utf8_to_gbk UTF8 GBK utf8_to_gbk utf8_and_gbk \ - utf8_to_iso_8859_2 UTF8 LATIN2 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_2_to_utf8 LATIN2 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_3 UTF8 LATIN3 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_3_to_utf8 LATIN3 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_4 UTF8 LATIN4 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_4_to_utf8 LATIN4 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_9 UTF8 LATIN5 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_9_to_utf8 LATIN5 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_10 UTF8 LATIN6 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_10_to_utf8 LATIN6 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_13 UTF8 LATIN7 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_13_to_utf8 LATIN7 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_14 UTF8 LATIN8 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_14_to_utf8 LATIN8 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_15 UTF8 LATIN9 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_15_to_utf8 LATIN9 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_16 UTF8 LATIN10 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_16_to_utf8 LATIN10 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_5 UTF8 ISO-8859-5 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_5_to_utf8 ISO-8859-5 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_6 UTF8 ISO-8859-6 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_6_to_utf8 ISO-8859-6 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_7 UTF8 ISO-8859-7 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_7_to_utf8 ISO-8859-7 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - utf8_to_iso_8859_8 UTF8 ISO-8859-8 utf8_to_iso8859 utf8_and_iso8859 \ - iso_8859_8_to_utf8 ISO-8859-8 UTF8 iso8859_to_utf8 utf8_and_iso8859 \ - iso_8859_1_to_utf8 LATIN1 UTF8 iso8859_1_to_utf8 utf8_and_iso8859_1 \ - utf8_to_iso_8859_1 UTF8 LATIN1 utf8_to_iso8859_1 utf8_and_iso8859_1 \ - johab_to_utf8 JOHAB UTF8 johab_to_utf8 utf8_and_johab \ - utf8_to_johab UTF8 JOHAB utf8_to_johab utf8_and_johab \ - sjis_to_utf8 SJIS UTF8 sjis_to_utf8 utf8_and_sjis \ - utf8_to_sjis UTF8 SJIS utf8_to_sjis utf8_and_sjis \ - uhc_to_utf8 UHC UTF8 uhc_to_utf8 utf8_and_uhc \ - utf8_to_uhc UTF8 UHC utf8_to_uhc utf8_and_uhc \ - euc_jis_2004_to_utf8 EUC_JIS_2004 UTF8 euc_jis_2004_to_utf8 utf8_and_euc2004 \ - utf8_to_euc_jis_2004 UTF8 EUC_JIS_2004 utf8_to_euc_jis_2004 utf8_and_euc2004 \ - shift_jis_2004_to_utf8 SHIFT_JIS_2004 UTF8 shift_jis_2004_to_utf8 utf8_and_sjis2004 \ - utf8_to_shift_jis_2004 UTF8 SHIFT_JIS_2004 utf8_to_shift_jis_2004 utf8_and_sjis2004 \ - euc_jis_2004_to_shift_jis_2004 EUC_JIS_2004 SHIFT_JIS_2004 euc_jis_2004_to_shift_jis_2004 euc2004_sjis2004 \ - shift_jis_2004_to_euc_jis_2004 SHIFT_JIS_2004 EUC_JIS_2004 shift_jis_2004_to_euc_jis_2004 euc2004_sjis2004 - -all: $(SQLSCRIPT) - -$(SQLSCRIPT): Makefile - @set -e; \ - set $(CONVERSIONS) ; \ - while [ "$$#" -gt 0 ] ; \ - do \ - name=$$1;shift; \ - se=$$1;shift; \ - de=$$1; shift; \ - func=$$1; shift; \ - obj=$$1; shift; \ - echo "-- $$se --> $$de"; \ - echo "CREATE OR REPLACE FUNCTION $$func (INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) RETURNS VOID AS '$$"libdir"/$$obj', '$$func' LANGUAGE C STRICT PARALLEL SAFE;"; \ - echo "COMMENT ON FUNCTION $$func(INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) IS 'internal conversion function for $$se to $$de';"; \ - echo "DROP CONVERSION pg_catalog.$$name;"; \ - echo "CREATE DEFAULT CONVERSION pg_catalog.$$name FOR '$$se' TO '$$de' FROM $$func;"; \ - echo "COMMENT ON CONVERSION pg_catalog.$$name IS 'conversion for $$se to $$de';"; \ - echo; \ - done > $@ - -install: $(SQLSCRIPT) installdirs - $(INSTALL_DATA) $(SQLSCRIPT) '$(DESTDIR)$(datadir)' - -installdirs: - $(MKDIR_P) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(pkglibdir)' - -uninstall: - rm -f '$(DESTDIR)$(datadir)/$(SQLSCRIPT)' - -clean distclean maintainer-clean: - rm -f $(SQLSCRIPT) diff --git a/src/backend/utils/mb/conversion_procs/ascii_and_mic/Makefile b/src/backend/utils/mb/conversion_procs/ascii_and_mic/Makefile deleted file mode 100644 index fa65eba9fd7..00000000000 --- a/src/backend/utils/mb/conversion_procs/ascii_and_mic/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#------------------------------------------------------------------------- -# -# src/backend/utils/mb/conversion_procs/ascii_and_mic/Makefile -# -#------------------------------------------------------------------------- -subdir = src/backend/utils/mb/conversion_procs/ascii_and_mic -top_builddir = ../../../../../.. -include $(top_builddir)/src/Makefile.global - -NAME = ascii_and_mic -PGFILEDESC = "ascii <-> mic text conversions" - -include $(srcdir)/../proc.mk diff --git a/src/backend/utils/mb/conversion_procs/ascii_and_mic/ascii_and_mic.c b/src/backend/utils/mb/conversion_procs/ascii_and_mic/ascii_and_mic.c deleted file mode 100644 index 9f44d7e853a..00000000000 --- a/src/backend/utils/mb/conversion_procs/ascii_and_mic/ascii_and_mic.c +++ /dev/null @@ -1,60 +0,0 @@ -/*------------------------------------------------------------------------- - * - * ASCII and MULE_INTERNAL - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/backend/utils/mb/conversion_procs/ascii_and_mic/ascii_and_mic.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "fmgr.h" -#include "mb/pg_wchar.h" - -PG_MODULE_MAGIC; - -PG_FUNCTION_INFO_V1(ascii_to_mic); -PG_FUNCTION_INFO_V1(mic_to_ascii); - -/* ---------- - * conv_proc( - * INTEGER, -- source encoding id - * INTEGER, -- destination encoding id - * CSTRING, -- source string (null terminated C string) - * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; - * ---------- - */ - -Datum -ascii_to_mic(PG_FUNCTION_ARGS) -{ - unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); - unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); - int len = PG_GETARG_INT32(4); - - CHECK_ENCODING_CONVERSION_ARGS(PG_SQL_ASCII, PG_MULE_INTERNAL); - - pg_ascii2mic(src, dest, len); - - PG_RETURN_VOID(); -} - -Datum -mic_to_ascii(PG_FUNCTION_ARGS) -{ - unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); - unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); - int len = PG_GETARG_INT32(4); - - CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_SQL_ASCII); - - pg_mic2ascii(src, dest, len); - - PG_RETURN_VOID(); -} diff --git a/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c b/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c index a37156a071e..d5e8cadd75e 100644 --- a/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c @@ -2,7 +2,7 @@ * * Cyrillic and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c b/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c index e8df57f35c9..f870abc9897 100644 --- a/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c +++ b/src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c @@ -2,7 +2,7 @@ * * EUC_JIS_2004, SHIFT_JIS_2004 * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c diff --git a/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c b/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c index ad3f12870ba..52a5fcdb9f9 100644 --- a/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/euc_cn_and_mic/euc_cn_and_mic.c @@ -2,7 +2,7 @@ * * EUC_CN and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c index 5564b02986e..7ec682dd6c6 100644 --- a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c +++ b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c @@ -2,7 +2,7 @@ * * EUC_JP, SJIS and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/sjis.map b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/sjis.map index cfcfaefb06d..1062f834d61 100644 --- a/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/sjis.map +++ b/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/sjis.map @@ -1,4 +1,4 @@ -static struct +static const struct { unsigned short int nec; /* SJIS UDC (NEC selection IBM kanji) */ unsigned short int sjis; /* SJIS UDC (IBM kanji) */ diff --git a/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c b/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c index c48704f9b27..e23d3d9bfa1 100644 --- a/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/euc_kr_and_mic/euc_kr_and_mic.c @@ -2,7 +2,7 @@ * * EUC_KR and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c b/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c index 9b5a4085330..481efdffc0f 100644 --- a/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c +++ b/src/backend/utils/mb/conversion_procs/euc_tw_and_big5/euc_tw_and_big5.c @@ -2,7 +2,7 @@ * * EUC_TW, BIG5 and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c b/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c index 648aab4f956..f8278e582e1 100644 --- a/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c +++ b/src/backend/utils/mb/conversion_procs/latin2_and_win1250/latin2_and_win1250.c @@ -2,7 +2,7 @@ * * LATIN2 and WIN1250 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c b/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c index 29c01cf771f..1c745f483d6 100644 --- a/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c +++ b/src/backend/utils/mb/conversion_procs/latin_and_mic/latin_and_mic.c @@ -2,7 +2,7 @@ * * LATINn and MULE_INTERNAL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_ascii/Makefile b/src/backend/utils/mb/conversion_procs/utf8_and_ascii/Makefile deleted file mode 100644 index 7bd68e209b7..00000000000 --- a/src/backend/utils/mb/conversion_procs/utf8_and_ascii/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -#------------------------------------------------------------------------- -# -# src/backend/utils/mb/conversion_procs/utf8_and_ascii/Makefile -# -#------------------------------------------------------------------------- -subdir = src/backend/utils/mb/conversion_procs/utf8_and_ascii -top_builddir = ../../../../../.. -include $(top_builddir)/src/Makefile.global - -NAME = utf8_and_ascii -PGFILEDESC = "utf8 <-> ascii text conversions" - -include $(srcdir)/../proc.mk diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_ascii/utf8_and_ascii.c b/src/backend/utils/mb/conversion_procs/utf8_and_ascii/utf8_and_ascii.c deleted file mode 100644 index e1a5a970aea..00000000000 --- a/src/backend/utils/mb/conversion_procs/utf8_and_ascii/utf8_and_ascii.c +++ /dev/null @@ -1,62 +0,0 @@ -/*------------------------------------------------------------------------- - * - * ASCII <--> UTF8 - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/backend/utils/mb/conversion_procs/utf8_and_ascii/utf8_and_ascii.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" -#include "fmgr.h" -#include "mb/pg_wchar.h" - -PG_MODULE_MAGIC; - -PG_FUNCTION_INFO_V1(ascii_to_utf8); -PG_FUNCTION_INFO_V1(utf8_to_ascii); - -/* ---------- - * conv_proc( - * INTEGER, -- source encoding id - * INTEGER, -- destination encoding id - * CSTRING, -- source string (null terminated C string) - * CSTRING, -- destination string (null terminated C string) - * INTEGER -- source string length - * ) returns VOID; - * ---------- - */ - -Datum -ascii_to_utf8(PG_FUNCTION_ARGS) -{ - unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); - unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); - int len = PG_GETARG_INT32(4); - - CHECK_ENCODING_CONVERSION_ARGS(PG_SQL_ASCII, PG_UTF8); - - /* this looks wrong, but basically we're just rejecting high-bit-set */ - pg_ascii2mic(src, dest, len); - - PG_RETURN_VOID(); -} - -Datum -utf8_to_ascii(PG_FUNCTION_ARGS) -{ - unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); - unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); - int len = PG_GETARG_INT32(4); - - CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, PG_SQL_ASCII); - - /* this looks wrong, but basically we're just rejecting high-bit-set */ - pg_mic2ascii(src, dest, len); - - PG_RETURN_VOID(); -} diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c b/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c index 5562dff3d79..33cd1e8f2e9 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_big5/utf8_and_big5.c @@ -2,7 +2,7 @@ * * BIG5 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c b/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c index 41fe6c5c28b..10222d52258 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/utf8_and_cyrillic.c @@ -2,7 +2,7 @@ * * UTF8 and Cyrillic * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c index cc12708d652..eae710d1403 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc2004/utf8_and_euc2004.c @@ -2,7 +2,7 @@ * * EUC_JIS_2004 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c index e3f37a7b51a..dd98238f5d2 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/utf8_and_euc_cn.c @@ -2,7 +2,7 @@ * * EUC_CN <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c index 2f0f1117970..cfb5ff85f51 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/utf8_and_euc_jp.c @@ -2,7 +2,7 @@ * * EUC_JP <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c index a7f4d20f590..3a6b255dafe 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/utf8_and_euc_kr.c @@ -2,7 +2,7 @@ * * EUC_KR <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c b/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c index b2dfd550255..c969efbb752 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/utf8_and_euc_tw.c @@ -2,7 +2,7 @@ * * EUC_TW <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c b/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c index 6b8a2cac554..307d42f4fb5 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_gb18030/utf8_and_gb18030.c @@ -2,7 +2,7 @@ * * GB18030 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c b/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c index c0fd57aff57..ed5915090f2 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_gbk/utf8_and_gbk.c @@ -2,7 +2,7 @@ * * GBK <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c index d01b59467fd..e33ca424ef1 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859/utf8_and_iso8859.c @@ -2,7 +2,7 @@ * * ISO 8859 2-16 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c index f72329e33bc..a0726682ac6 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/utf8_and_iso8859_1.c @@ -2,7 +2,7 @@ * * ISO8859_1 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c b/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c index 1bc12145f62..2e0e7e5c6af 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_johab/utf8_and_johab.c @@ -2,7 +2,7 @@ * * JOHAB <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c b/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c index 561730a4207..318a304f846 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_sjis/utf8_and_sjis.c @@ -2,7 +2,7 @@ * * SJIS <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c b/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c index 0dea5a2805e..4b2421c98e5 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004/utf8_and_sjis2004.c @@ -2,7 +2,7 @@ * * SHIFT_JIS_2004 <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c b/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c index 738fd1191f6..415caf1c3f9 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_uhc/utf8_and_uhc.c @@ -2,7 +2,7 @@ * * UHC <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c b/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c index ec8221e89d3..ca6d9e830ab 100644 --- a/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c +++ b/src/backend/utils/mb/conversion_procs/utf8_and_win/utf8_and_win.c @@ -2,7 +2,7 @@ * * WIN <--> UTF8 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c index 8d80ffe78ba..bec54bb5cbc 100644 --- a/src/backend/utils/mb/mbutils.c +++ b/src/backend/utils/mb/mbutils.c @@ -23,7 +23,7 @@ * the result is validly encoded according to the destination encoding. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -86,7 +86,7 @@ static int pending_client_encoding = PG_SQL_ASCII; /* Internal functions */ static char *perform_default_encoding_conversion(const char *src, - int len, bool is_client_to_server); + int len, bool is_client_to_server); static int cliplen(const char *str, int len, int limit); @@ -203,8 +203,6 @@ SetClientEncoding(int encoding) int current_server_encoding; bool found; ListCell *lc; - ListCell *prev; - ListCell *next; if (!PG_VALID_FE_ENCODING(encoding)) return -1; @@ -238,13 +236,10 @@ SetClientEncoding(int encoding) * leak memory. */ found = false; - prev = NULL; - for (lc = list_head(ConvProcList); lc; lc = next) + foreach(lc, ConvProcList) { ConvProcInfo *convinfo = (ConvProcInfo *) lfirst(lc); - next = lnext(lc); - if (convinfo->s_encoding == current_server_encoding && convinfo->c_encoding == encoding) { @@ -259,13 +254,10 @@ SetClientEncoding(int encoding) else { /* Duplicate entry, release it */ - ConvProcList = list_delete_cell(ConvProcList, lc, prev); + ConvProcList = foreach_delete_current(ConvProcList, lc); pfree(convinfo); - continue; /* prev mustn't advance */ } } - - prev = lc; } if (found) @@ -464,7 +456,7 @@ pg_convert(PG_FUNCTION_ARGS) pg_verify_mbstr_len(src_encoding, src_str, len, false); /* perform conversion */ - dest_str = (char *) pg_do_encoding_conversion((unsigned char *) src_str, + dest_str = (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, src_str), len, src_encoding, dest_encoding); @@ -561,7 +553,7 @@ char * pg_any_to_server(const char *s, int len, int encoding) { if (len <= 0) - return (char *) s; /* empty string is always valid */ + return unconstify(char *, s); /* empty string is always valid */ if (encoding == DatabaseEncoding->encoding || encoding == PG_SQL_ASCII) @@ -570,7 +562,7 @@ pg_any_to_server(const char *s, int len, int encoding) * No conversion is needed, but we must still validate the data. */ (void) pg_verify_mbstr(DatabaseEncoding->encoding, s, len, false); - return (char *) s; + return unconstify(char *, s); } if (DatabaseEncoding->encoding == PG_SQL_ASCII) @@ -600,7 +592,7 @@ pg_any_to_server(const char *s, int len, int encoding) (unsigned char) s[i]))); } } - return (char *) s; + return unconstify(char *, s); } /* Fast path if we can use cached conversion function */ @@ -608,7 +600,7 @@ pg_any_to_server(const char *s, int len, int encoding) return perform_default_encoding_conversion(s, len, true); /* General case ... will not work outside transactions */ - return (char *) pg_do_encoding_conversion((unsigned char *) s, + return (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, s), len, encoding, DatabaseEncoding->encoding); @@ -634,17 +626,17 @@ char * pg_server_to_any(const char *s, int len, int encoding) { if (len <= 0) - return (char *) s; /* empty string is always valid */ + return unconstify(char *, s); /* empty string is always valid */ if (encoding == DatabaseEncoding->encoding || encoding == PG_SQL_ASCII) - return (char *) s; /* assume data is valid */ + return unconstify(char *, s); /* assume data is valid */ if (DatabaseEncoding->encoding == PG_SQL_ASCII) { /* No conversion is possible, but we must validate the result */ (void) pg_verify_mbstr(encoding, s, len, false); - return (char *) s; + return unconstify(char *, s); } /* Fast path if we can use cached conversion function */ @@ -652,7 +644,7 @@ pg_server_to_any(const char *s, int len, int encoding) return perform_default_encoding_conversion(s, len, false); /* General case ... will not work outside transactions */ - return (char *) pg_do_encoding_conversion((unsigned char *) s, + return (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, s), len, DatabaseEncoding->encoding, encoding); @@ -687,7 +679,7 @@ perform_default_encoding_conversion(const char *src, int len, } if (flinfo == NULL) - return (char *) src; + return unconstify(char *, src); /* * Allocate space for conversion result, being wary of integer overflow @@ -1046,11 +1038,16 @@ GetMessageEncoding(void) WCHAR * pgwin32_message_to_UTF16(const char *str, int len, int *utf16len) { + int msgenc = GetMessageEncoding(); WCHAR *utf16; int dstlen; UINT codepage; - codepage = pg_enc2name_tbl[GetMessageEncoding()].codepage; + if (msgenc == PG_SQL_ASCII) + /* No conversion is possible, and SQL_ASCII is never utf16. */ + return NULL; + + codepage = pg_enc2name_tbl[msgenc].codepage; /* * Use MultiByteToWideChar directly if there is a corresponding codepage, @@ -1075,7 +1072,7 @@ pgwin32_message_to_UTF16(const char *str, int len, int *utf16len) { utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str, len, - GetMessageEncoding(), + msgenc, PG_UTF8); if (utf8 != str) len = strlen(utf8); diff --git a/src/backend/utils/mb/wchar.c b/src/backend/utils/mb/wchar.c index a5fdda456e6..1b5ce1740c0 100644 --- a/src/backend/utils/mb/wchar.c +++ b/src/backend/utils/mb/wchar.c @@ -15,16 +15,23 @@ /* - * conversion to pg_wchar is done by "table driven." - * to add an encoding support, define mb2wchar_with_len(), mblen(), dsplen() - * for the particular encoding. Note that if the encoding is only - * supported in the client, you don't need to define - * mb2wchar_with_len() function (SJIS is the case). + * Operations on multi-byte encodings are driven by a table of helper + * functions. + * + * To add an encoding support, define mblen(), dsplen() and verifier() for + * the encoding. For server-encodings, also define mb2wchar() and wchar2mb() + * conversion functions. * * These functions generally assume that their input is validly formed. * The "verifier" functions, further down in the file, have to be more - * paranoid. We expect that mblen() does not need to examine more than - * the first byte of the character to discover the correct length. + * paranoid. + * + * We expect that mblen() does not need to examine more than the first byte + * of the character to discover the correct length. GB18030 is an exception + * to that rule, though, as it also looks at second byte. But even that + * behaves in a predictable way, if you only pass the first byte: it will + * treat 4-byte encoded characters as two 2-byte encoded characters, which is + * good enough for all current uses. * * Note: for the display output of psql to work properly, the return values * of the dsplen functions must conform to the Unicode standard. In particular @@ -638,40 +645,70 @@ ucs_wcwidth(pg_wchar ucs) { /* sorted list of non-overlapping intervals of non-spacing characters */ static const struct mbinterval combining[] = { - {0x0300, 0x034E}, {0x0360, 0x0362}, {0x0483, 0x0486}, - {0x0488, 0x0489}, {0x0591, 0x05A1}, {0x05A3, 0x05B9}, - {0x05BB, 0x05BD}, {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, - {0x05C4, 0x05C4}, {0x064B, 0x0655}, {0x0670, 0x0670}, - {0x06D6, 0x06E4}, {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, - {0x070F, 0x070F}, {0x0711, 0x0711}, {0x0730, 0x074A}, - {0x07A6, 0x07B0}, {0x0901, 0x0902}, {0x093C, 0x093C}, - {0x0941, 0x0948}, {0x094D, 0x094D}, {0x0951, 0x0954}, - {0x0962, 0x0963}, {0x0981, 0x0981}, {0x09BC, 0x09BC}, - {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, {0x09E2, 0x09E3}, - {0x0A02, 0x0A02}, {0x0A3C, 0x0A3C}, {0x0A41, 0x0A42}, - {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A70, 0x0A71}, - {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC5}, - {0x0AC7, 0x0AC8}, {0x0ACD, 0x0ACD}, {0x0B01, 0x0B01}, - {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B43}, - {0x0B4D, 0x0B4D}, {0x0B56, 0x0B56}, {0x0B82, 0x0B82}, - {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, {0x0C3E, 0x0C40}, - {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D}, {0x0C55, 0x0C56}, + {0x0300, 0x036F}, {0x0483, 0x0489}, {0x0591, 0x05BD}, + {0x05BF, 0x05BF}, {0x05C1, 0x05C2}, {0x05C4, 0x05C5}, + {0x05C7, 0x05C7}, {0x0610, 0x061A}, {0x064B, 0x065F}, + {0x0670, 0x0670}, {0x06D6, 0x06DC}, {0x06DF, 0x06E4}, + {0x06E7, 0x06E8}, {0x06EA, 0x06ED}, {0x0711, 0x0711}, + {0x0730, 0x074A}, {0x07A6, 0x07B0}, {0x07EB, 0x07F3}, + {0x07FD, 0x07FD}, {0x0816, 0x0819}, {0x081B, 0x0823}, + {0x0825, 0x0827}, {0x0829, 0x082D}, {0x0859, 0x085B}, + {0x08D3, 0x08E1}, {0x08E3, 0x0902}, {0x093A, 0x093A}, + {0x093C, 0x093C}, {0x0941, 0x0948}, {0x094D, 0x094D}, + {0x0951, 0x0957}, {0x0962, 0x0963}, {0x0981, 0x0981}, + {0x09BC, 0x09BC}, {0x09C1, 0x09C4}, {0x09CD, 0x09CD}, + {0x09E2, 0x09E3}, {0x09FE, 0x0A02}, {0x0A3C, 0x0A3C}, + {0x0A41, 0x0A51}, {0x0A70, 0x0A71}, {0x0A75, 0x0A75}, + {0x0A81, 0x0A82}, {0x0ABC, 0x0ABC}, {0x0AC1, 0x0AC8}, + {0x0ACD, 0x0ACD}, {0x0AE2, 0x0AE3}, {0x0AFA, 0x0B01}, + {0x0B3C, 0x0B3C}, {0x0B3F, 0x0B3F}, {0x0B41, 0x0B44}, + {0x0B4D, 0x0B56}, {0x0B62, 0x0B63}, {0x0B82, 0x0B82}, + {0x0BC0, 0x0BC0}, {0x0BCD, 0x0BCD}, {0x0C00, 0x0C00}, + {0x0C04, 0x0C04}, {0x0C3E, 0x0C40}, {0x0C46, 0x0C56}, + {0x0C62, 0x0C63}, {0x0C81, 0x0C81}, {0x0CBC, 0x0CBC}, {0x0CBF, 0x0CBF}, {0x0CC6, 0x0CC6}, {0x0CCC, 0x0CCD}, - {0x0D41, 0x0D43}, {0x0D4D, 0x0D4D}, {0x0DCA, 0x0DCA}, - {0x0DD2, 0x0DD4}, {0x0DD6, 0x0DD6}, {0x0E31, 0x0E31}, + {0x0CE2, 0x0CE3}, {0x0D00, 0x0D01}, {0x0D3B, 0x0D3C}, + {0x0D41, 0x0D44}, {0x0D4D, 0x0D4D}, {0x0D62, 0x0D63}, + {0x0DCA, 0x0DCA}, {0x0DD2, 0x0DD6}, {0x0E31, 0x0E31}, {0x0E34, 0x0E3A}, {0x0E47, 0x0E4E}, {0x0EB1, 0x0EB1}, - {0x0EB4, 0x0EB9}, {0x0EBB, 0x0EBC}, {0x0EC8, 0x0ECD}, - {0x0F18, 0x0F19}, {0x0F35, 0x0F35}, {0x0F37, 0x0F37}, - {0x0F39, 0x0F39}, {0x0F71, 0x0F7E}, {0x0F80, 0x0F84}, - {0x0F86, 0x0F87}, {0x0F90, 0x0F97}, {0x0F99, 0x0FBC}, - {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, {0x1032, 0x1032}, - {0x1036, 0x1037}, {0x1039, 0x1039}, {0x1058, 0x1059}, - {0x1160, 0x11FF}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6}, - {0x17C9, 0x17D3}, {0x180B, 0x180E}, {0x18A9, 0x18A9}, - {0x200B, 0x200F}, {0x202A, 0x202E}, {0x206A, 0x206F}, - {0x20D0, 0x20E3}, {0x302A, 0x302F}, {0x3099, 0x309A}, - {0xFB1E, 0xFB1E}, {0xFE20, 0xFE23}, {0xFEFF, 0xFEFF}, - {0xFFF9, 0xFFFB} + {0x0EB4, 0x0EBC}, {0x0EC8, 0x0ECD}, {0x0F18, 0x0F19}, + {0x0F35, 0x0F35}, {0x0F37, 0x0F37}, {0x0F39, 0x0F39}, + {0x0F71, 0x0F7E}, {0x0F80, 0x0F84}, {0x0F86, 0x0F87}, + {0x0F8D, 0x0FBC}, {0x0FC6, 0x0FC6}, {0x102D, 0x1030}, + {0x1032, 0x1037}, {0x1039, 0x103A}, {0x103D, 0x103E}, + {0x1058, 0x1059}, {0x105E, 0x1060}, {0x1071, 0x1074}, + {0x1082, 0x1082}, {0x1085, 0x1086}, {0x108D, 0x108D}, + {0x109D, 0x109D}, {0x135D, 0x135F}, {0x1712, 0x1714}, + {0x1732, 0x1734}, {0x1752, 0x1753}, {0x1772, 0x1773}, + {0x17B4, 0x17B5}, {0x17B7, 0x17BD}, {0x17C6, 0x17C6}, + {0x17C9, 0x17D3}, {0x17DD, 0x17DD}, {0x180B, 0x180D}, + {0x1885, 0x1886}, {0x18A9, 0x18A9}, {0x1920, 0x1922}, + {0x1927, 0x1928}, {0x1932, 0x1932}, {0x1939, 0x193B}, + {0x1A17, 0x1A18}, {0x1A1B, 0x1A1B}, {0x1A56, 0x1A56}, + {0x1A58, 0x1A60}, {0x1A62, 0x1A62}, {0x1A65, 0x1A6C}, + {0x1A73, 0x1A7F}, {0x1AB0, 0x1B03}, {0x1B34, 0x1B34}, + {0x1B36, 0x1B3A}, {0x1B3C, 0x1B3C}, {0x1B42, 0x1B42}, + {0x1B6B, 0x1B73}, {0x1B80, 0x1B81}, {0x1BA2, 0x1BA5}, + {0x1BA8, 0x1BA9}, {0x1BAB, 0x1BAD}, {0x1BE6, 0x1BE6}, + {0x1BE8, 0x1BE9}, {0x1BED, 0x1BED}, {0x1BEF, 0x1BF1}, + {0x1C2C, 0x1C33}, {0x1C36, 0x1C37}, {0x1CD0, 0x1CD2}, + {0x1CD4, 0x1CE0}, {0x1CE2, 0x1CE8}, {0x1CED, 0x1CED}, + {0x1CF4, 0x1CF4}, {0x1CF8, 0x1CF9}, {0x1DC0, 0x1DFF}, + {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2D7F, 0x2D7F}, + {0x2DE0, 0x2DFF}, {0x302A, 0x302D}, {0x3099, 0x309A}, + {0xA66F, 0xA672}, {0xA674, 0xA67D}, {0xA69E, 0xA69F}, + {0xA6F0, 0xA6F1}, {0xA802, 0xA802}, {0xA806, 0xA806}, + {0xA80B, 0xA80B}, {0xA825, 0xA826}, {0xA8C4, 0xA8C5}, + {0xA8E0, 0xA8F1}, {0xA8FF, 0xA8FF}, {0xA926, 0xA92D}, + {0xA947, 0xA951}, {0xA980, 0xA982}, {0xA9B3, 0xA9B3}, + {0xA9B6, 0xA9B9}, {0xA9BC, 0xA9BD}, {0xA9E5, 0xA9E5}, + {0xAA29, 0xAA2E}, {0xAA31, 0xAA32}, {0xAA35, 0xAA36}, + {0xAA43, 0xAA43}, {0xAA4C, 0xAA4C}, {0xAA7C, 0xAA7C}, + {0xAAB0, 0xAAB0}, {0xAAB2, 0xAAB4}, {0xAAB7, 0xAAB8}, + {0xAABE, 0xAABF}, {0xAAC1, 0xAAC1}, {0xAAEC, 0xAAED}, + {0xAAF6, 0xAAF6}, {0xABE5, 0xABE5}, {0xABE8, 0xABE8}, + {0xABED, 0xABED}, {0xFB1E, 0xFB1E}, {0xFE00, 0xFE0F}, + {0xFE20, 0xFE2F}, }; /* test for 8-bit control characters */ @@ -1073,6 +1110,17 @@ pg_uhc_dsplen(const unsigned char *s) * GB18030 * Added by Bill Huang , */ + +/* + * Unlike all other mblen() functions, this also looks at the second byte of + * the input. However, if you only pass the first byte of a multi-byte + * string, and \0 as the second byte, this still works in a predictable way: + * a 4-byte character will be reported as two 2-byte characters. That's + * enough for all current uses, as a client-only encoding. It works that + * way, because in any valid 4-byte GB18030-encoded character, the third and + * fourth byte look like a 2-byte encoded character, when looked at + * separately. + */ static int pg_gb18030_mblen(const unsigned char *s) { diff --git a/src/backend/utils/misc/Makefile b/src/backend/utils/misc/Makefile index a53fcdf1889..ec7ec131e5a 100644 --- a/src/backend/utils/misc/Makefile +++ b/src/backend/utils/misc/Makefile @@ -14,9 +14,9 @@ include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) -OBJS = backend_random.o guc.o help_config.o pg_config.o pg_controldata.o \ - pg_rusage.o ps_status.o queryenvironment.o rls.o sampling.o \ - superuser.o timeout.o tzparser.o +OBJS = guc.o help_config.o pg_config.o pg_controldata.o pg_rusage.o \ + ps_status.o queryenvironment.o rls.o sampling.o superuser.o \ + timeout.o tzparser.o # This location might depend on the installation directories. Therefore # we can't substitute it into pg_config.h. diff --git a/src/backend/utils/misc/backend_random.c b/src/backend/utils/misc/backend_random.c deleted file mode 100644 index a64f3ac3980..00000000000 --- a/src/backend/utils/misc/backend_random.c +++ /dev/null @@ -1,158 +0,0 @@ -/*------------------------------------------------------------------------- - * - * backend_random.c - * Backend random number generation routine. - * - * pg_backend_random() function fills a buffer with random bytes. Normally, - * it is just a thin wrapper around pg_strong_random(), but when compiled - * with --disable-strong-random, we provide a built-in implementation. - * - * This function is used for generating nonces in authentication, and for - * random salt generation in pgcrypto. The built-in implementation is not - * cryptographically strong, but if the user asked for it, we'll go ahead - * and use it anyway. - * - * The built-in implementation uses the standard erand48 algorithm, with - * a seed shared between all backends. - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/backend/utils/misc/backend_random.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres.h" - -#include - -#include "miscadmin.h" -#include "storage/lwlock.h" -#include "storage/shmem.h" -#include "utils/backend_random.h" -#include "utils/timestamp.h" - -#ifdef HAVE_STRONG_RANDOM - -Size -BackendRandomShmemSize(void) -{ - return 0; -} - -void -BackendRandomShmemInit(void) -{ - /* do nothing */ -} - -bool -pg_backend_random(char *dst, int len) -{ - /* should not be called in postmaster */ - Assert(IsUnderPostmaster || !IsPostmasterEnvironment); - - return pg_strong_random(dst, len); -} - -#else - -/* - * Seed for the PRNG, stored in shared memory. - * - * Protected by BackendRandomLock. - */ -typedef struct -{ - bool initialized; - unsigned short seed[3]; -} BackendRandomShmemStruct; - -static BackendRandomShmemStruct * BackendRandomShmem; - -Size -BackendRandomShmemSize(void) -{ - return sizeof(BackendRandomShmemStruct); -} - -void -BackendRandomShmemInit(void) -{ - bool found; - - BackendRandomShmem = (BackendRandomShmemStruct *) - ShmemInitStruct("Backend PRNG state", - BackendRandomShmemSize(), - &found); - - if (!IsUnderPostmaster) - { - Assert(!found); - - BackendRandomShmem->initialized = false; - } - else - Assert(found); -} - -bool -pg_backend_random(char *dst, int len) -{ - int i; - char *end = dst + len; - - /* should not be called in postmaster */ - Assert(IsUnderPostmaster || !IsPostmasterEnvironment); - - LWLockAcquire(BackendRandomLock, LW_EXCLUSIVE); - - /* - * Seed the PRNG on the first use. - */ - if (!BackendRandomShmem->initialized) - { - struct timeval now; - - gettimeofday(&now, NULL); - - BackendRandomShmem->seed[0] = now.tv_sec; - BackendRandomShmem->seed[1] = (unsigned short) (now.tv_usec); - BackendRandomShmem->seed[2] = (unsigned short) (now.tv_usec >> 16); - - /* - * Mix in the cancel key, generated by the postmaster. This adds what - * little entropy the postmaster had to the seed. - */ - BackendRandomShmem->seed[0] ^= (MyCancelKey); - BackendRandomShmem->seed[1] ^= (MyCancelKey >> 16); - - BackendRandomShmem->initialized = true; - } - - for (i = 0; dst < end; i++) - { - uint32 r; - int j; - - /* - * pg_jrand48 returns a 32-bit integer. Fill the next 4 bytes from it. - */ - r = (uint32) pg_jrand48(BackendRandomShmem->seed); - - for (j = 0; j < 4 && dst < end; j++) - { - *(dst++) = (char) (r & 0xFF); - r >>= 8; - } - } - LWLockRelease(BackendRandomLock); - - return true; -} - - -#endif /* HAVE_STRONG_RANDOM */ diff --git a/src/backend/utils/misc/check_guc b/src/backend/utils/misc/check_guc index d228bbed685..416a0875b6c 100755 --- a/src/backend/utils/misc/check_guc +++ b/src/backend/utils/misc/check_guc @@ -18,7 +18,7 @@ ## can be ignored INTENTIONALLY_NOT_INCLUDED="debug_deadlocks \ is_superuser lc_collate lc_ctype lc_messages lc_monetary lc_numeric lc_time \ -pre_auth_delay role seed server_encoding server_version server_version_int \ +pre_auth_delay role seed server_encoding server_version server_version_num \ session_authorization trace_lock_oidmin trace_lock_table trace_locks trace_lwlocks \ trace_notify trace_userlocks transaction_isolation transaction_read_only \ zero_damaged_pages" diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index afe4fe6d775..2aaab3d5f80 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -2,7 +2,7 @@ /* * Scanner for the configuration file * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/backend/utils/misc/guc-file.l */ @@ -567,6 +567,22 @@ ParseConfigFile(const char *config_file, bool strict, bool OK = true; FILE *fp; + /* + * Reject file name that is all-blank (including empty), as that leads to + * confusion --- we'd try to read the containing directory as a file. + */ + if (strspn(config_file, " \t\r\n") == strlen(config_file)) + { + ereport(elevel, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("empty configuration file name: \"%s\"", + config_file))); + record_config_file_error("empty configuration file name", + calling_file, calling_lineno, + head_p, tail_p); + return false; + } + /* * Reject too-deep include nesting depth. This is just a safety check to * avoid dumping core due to stack overflow if an include file loops back @@ -585,6 +601,26 @@ ParseConfigFile(const char *config_file, bool strict, } abs_path = AbsoluteConfigLocation(config_file, calling_file); + + /* + * Reject direct recursion. Indirect recursion is also possible, but it's + * harder to detect and so doesn't seem worth the trouble. (We test at + * this step because the canonicalization done by AbsoluteConfigLocation + * makes it more likely that a simple strcmp comparison will match.) + */ + if (calling_file && strcmp(abs_path, calling_file) == 0) + { + ereport(elevel, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("configuration file recursion in \"%s\"", + calling_file))); + record_config_file_error("configuration file recursion", + calling_file, calling_lineno, + head_p, tail_p); + pfree(abs_path); + return false; + } + fp = AllocateFile(abs_path, "r"); if (!fp) { @@ -933,6 +969,28 @@ ParseConfigDirectory(const char *includedir, int size_filenames; bool status; + /* + * Reject directory name that is all-blank (including empty), as that + * leads to confusion --- we'd read the containing directory, typically + * resulting in recursive inclusion of the same file(s). + */ + if (strspn(includedir, " \t\r\n") == strlen(includedir)) + { + ereport(elevel, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("empty configuration directory name: \"%s\"", + includedir))); + record_config_file_error("empty configuration directory name", + calling_file, calling_lineno, + head_p, tail_p); + return false; + } + + /* + * We don't check for recursion or too-deep nesting depth here; the + * subsequent calls to ParseConfigFile will take care of that. + */ + directory = AbsoluteConfigLocation(includedir, calling_file); d = AllocateDir(directory); if (d == NULL) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index fa92ce2e683..c77300d4cab 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -6,7 +6,7 @@ * See src/backend/utils/misc/README for more information. * * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * Written by Peter Eisentraut . * * IDENTIFICATION @@ -29,6 +29,7 @@ #include "access/commit_ts.h" #include "access/gin.h" #include "access/rmgr.h" +#include "access/tableam.h" #include "access/transam.h" #include "access/twophase.h" #include "access/xact.h" @@ -41,6 +42,7 @@ #include "commands/vacuum.h" #include "commands/variable.h" #include "commands/trigger.h" +#include "common/string.h" #include "funcapi.h" #include "jit/jit.h" #include "libpq/auth.h" @@ -49,6 +51,7 @@ #include "miscadmin.h" #include "optimizer/cost.h" #include "optimizer/geqo.h" +#include "optimizer/optimizer.h" #include "optimizer/paths.h" #include "optimizer/planmain.h" #include "parser/parse_expr.h" @@ -80,8 +83,10 @@ #include "utils/builtins.h" #include "utils/bytea.h" #include "utils/guc_tables.h" +#include "utils/float.h" #include "utils/memutils.h" #include "utils/pg_locale.h" +#include "utils/pg_lsn.h" #include "utils/plancache.h" #include "utils/portal.h" #include "utils/ps_status.h" @@ -136,25 +141,27 @@ char *GUC_check_errhint_string; static void do_serialize(char **destptr, Size *maxbytes, const char *fmt,...) pg_attribute_printf(3, 4); static void set_config_sourcefile(const char *name, char *sourcefile, - int sourceline); + int sourceline); static bool call_bool_check_hook(struct config_bool *conf, bool *newval, - void **extra, GucSource source, int elevel); + void **extra, GucSource source, int elevel); static bool call_int_check_hook(struct config_int *conf, int *newval, - void **extra, GucSource source, int elevel); + void **extra, GucSource source, int elevel); static bool call_real_check_hook(struct config_real *conf, double *newval, - void **extra, GucSource source, int elevel); + void **extra, GucSource source, int elevel); static bool call_string_check_hook(struct config_string *conf, char **newval, - void **extra, GucSource source, int elevel); + void **extra, GucSource source, int elevel); static bool call_enum_check_hook(struct config_enum *conf, int *newval, - void **extra, GucSource source, int elevel); + void **extra, GucSource source, int elevel); static bool check_log_destination(char **newval, void **extra, GucSource source); static void assign_log_destination(const char *newval, void *extra); static bool check_wal_consistency_checking(char **newval, void **extra, - GucSource source); + GucSource source); static void assign_wal_consistency_checking(const char *newval, void *extra); +static bool check_online_update_support(char **newval, void **extra, GucSource source); + #ifdef HAVE_SYSLOG static int syslog_facility = LOG_LOCAL0; #else @@ -177,12 +184,15 @@ static const char *show_archive_command(void); static void assign_tcp_keepalives_idle(int newval, void *extra); static void assign_tcp_keepalives_interval(int newval, void *extra); static void assign_tcp_keepalives_count(int newval, void *extra); +static void assign_tcp_user_timeout(int newval, void *extra); static const char *show_tcp_keepalives_idle(void); static const char *show_tcp_keepalives_interval(void); static const char *show_tcp_keepalives_count(void); +static const char *show_tcp_user_timeout(void); static bool check_maxconnections(int *newval, void **extra, GucSource source); static bool check_max_worker_processes(int *newval, void **extra, GucSource source); static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source); +static bool check_max_wal_senders(int *newval, void **extra, GucSource source); static bool check_autovacuum_work_mem(int *newval, void **extra, GucSource source); static bool check_effective_io_concurrency(int *newval, void **extra, GucSource source); static void assign_effective_io_concurrency(int newval, void *extra); @@ -193,10 +203,24 @@ static bool check_cluster_name(char **newval, void **extra, GucSource source); static const char *show_unix_socket_permissions(void); static const char *show_log_file_mode(void); static const char *show_data_directory_mode(void); +static bool check_recovery_target_timeline(char **newval, void **extra, GucSource source); +static void assign_recovery_target_timeline(const char *newval, void *extra); +static bool check_recovery_target(char **newval, void **extra, GucSource source); +static void assign_recovery_target(const char *newval, void *extra); +static bool check_recovery_target_xid(char **newval, void **extra, GucSource source); +static void assign_recovery_target_xid(const char *newval, void *extra); +static bool check_recovery_target_time(char **newval, void **extra, GucSource source); +static void assign_recovery_target_time(const char *newval, void *extra); +static bool check_recovery_target_name(char **newval, void **extra, GucSource source); +static void assign_recovery_target_name(const char *newval, void *extra); +static bool check_recovery_target_lsn(char **newval, void **extra, GucSource source); +static void assign_recovery_target_lsn(const char *newval, void *extra); +static bool check_primary_slot_name(char **newval, void **extra, GucSource source); +static bool check_default_with_oids(bool *newval, void **extra, GucSource source); /* Private functions in guc-file.l that need to be called from guc.c */ static ConfigVariable *ProcessConfigFileInternal(GucContext context, - bool applySettings, int elevel); + bool applySettings, int elevel); /* @@ -213,32 +237,31 @@ static const struct config_enum_entry bytea_output_options[] = { /* * We have different sets for client and server message level options because - * they sort slightly different (see "log" level) + * they sort slightly different (see "log" level), and because "fatal"/"panic" + * aren't sensible for client_min_messages. */ static const struct config_enum_entry client_message_level_options[] = { - {"debug", DEBUG2, true}, {"debug5", DEBUG5, false}, {"debug4", DEBUG4, false}, {"debug3", DEBUG3, false}, {"debug2", DEBUG2, false}, {"debug1", DEBUG1, false}, + {"debug", DEBUG2, true}, {"log", LOG, false}, {"info", INFO, true}, {"notice", NOTICE, false}, {"warning", WARNING, false}, {"error", ERROR, false}, - {"fatal", FATAL, true}, - {"panic", PANIC, true}, {NULL, 0, false} }; static const struct config_enum_entry server_message_level_options[] = { - {"debug", DEBUG2, true}, {"debug5", DEBUG5, false}, {"debug4", DEBUG4, false}, {"debug3", DEBUG3, false}, {"debug2", DEBUG2, false}, {"debug1", DEBUG1, false}, + {"debug", DEBUG2, true}, {"info", INFO, false}, {"notice", NOTICE, false}, {"warning", WARNING, false}, @@ -405,6 +428,13 @@ static const struct config_enum_entry force_parallel_mode_options[] = { {NULL, 0, false} }; +static const struct config_enum_entry plan_cache_mode_options[] = { + {"auto", PLAN_CACHE_MODE_AUTO, false}, + {"force_generic_plan", PLAN_CACHE_MODE_FORCE_GENERIC_PLAN, false}, + {"force_custom_plan", PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN, false}, + {NULL, 0, false} +}; + /* * password_encryption used to be a boolean, so accept all the likely * variants of "on", too. "off" used to store passwords in plaintext, @@ -420,11 +450,35 @@ static const struct config_enum_entry password_encryption_options[] = { {NULL, 0, false} }; +const struct config_enum_entry ssl_protocol_versions_info[] = { + {"", PG_TLS_ANY, false}, + {"TLSv1", PG_TLS1_VERSION, false}, + {"TLSv1.1", PG_TLS1_1_VERSION, false}, + {"TLSv1.2", PG_TLS1_2_VERSION, false}, + {"TLSv1.3", PG_TLS1_3_VERSION, false}, + {NULL, 0, false} +}; + +static struct config_enum_entry shared_memory_options[] = { +#ifndef WIN32 + {"sysv", SHMEM_TYPE_SYSV, false}, + {"posix", SHMEM_TYPE_POSIX, false}, +#endif +#ifndef EXEC_BACKEND + {"mmap", SHMEM_TYPE_MMAP, false}, +#endif +#ifdef WIN32 + {"windows", SHMEM_TYPE_WINDOWS, false}, +#endif + {NULL, 0, false} +}; + /* * Options for enum values stored in other modules */ extern const struct config_enum_entry wal_level_options[]; extern const struct config_enum_entry archive_mode_options[]; +extern const struct config_enum_entry recovery_target_action_options[]; extern const struct config_enum_entry sync_method_options[]; extern const struct config_enum_entry dynamic_shared_memory_options[]; @@ -447,6 +501,11 @@ char *event_source; bool row_security; bool check_function_bodies = true; + +/* + * This GUC exists solely for backward compatibility, check its definition for + * details. + */ bool default_with_oids = false; bool session_auth_is_superuser; @@ -455,6 +514,7 @@ int log_min_messages = WARNING; int client_min_messages = NOTICE; int log_min_duration_statement = -1; int log_temp_files = -1; +double log_xact_sample_rate = 0; int trace_recovery_messages = LOG; int temp_file_limit = -1; @@ -474,6 +534,7 @@ char *application_name; int tcp_keepalives_idle; int tcp_keepalives_interval; int tcp_keepalives_count; +int tcp_user_timeout; /* * SSL renegotiation was been removed in PostgreSQL 9.5, but we tolerate it @@ -506,7 +567,6 @@ static int server_version_num; static char *timezone_string; static char *log_timezone_string; static char *timezone_abbreviations_string; -static char *XactIsoLevel_string; static char *data_directory; static char *session_authorization_string; static int max_function_args; @@ -518,6 +578,12 @@ static int wal_block_size; static bool data_checksums; static bool integer_datetimes; static bool assert_enabled; +static char *recovery_target_timeline_string; +static char *recovery_target_string; +static char *recovery_target_xid_string; +static char *recovery_target_name_string; +static char *recovery_target_lsn_string; + /* should be static, but commands/variable.c needs to get at this */ char *role_string; @@ -601,6 +667,10 @@ const char *const config_group_names[] = gettext_noop("Write-Ahead Log / Checkpoints"), /* WAL_ARCHIVING */ gettext_noop("Write-Ahead Log / Archiving"), + /* WAL_ARCHIVE_RECOVERY */ + gettext_noop("Write-Ahead Log / Archive Recovery"), + /* WAL_RECOVERY_TARGET */ + gettext_noop("Write-Ahead Log / Recovery Target"), /* REPLICATION */ gettext_noop("Replication"), /* REPLICATION_SENDING */ @@ -690,13 +760,13 @@ const char *const config_type_names[] = * For each supported conversion from one unit to another, we have an entry * in the table. * - * To keep things simple, and to avoid intermediate-value overflows, + * To keep things simple, and to avoid possible roundoff error, * conversions are never chained. There needs to be a direct conversion * between all units (of the same type). * - * The conversions from each base unit must be kept in order from greatest - * to smallest unit; convert_from_base_unit() relies on that. (The order of - * the base units does not matter.) + * The conversions for each base unit must be kept in order from greatest to + * smallest human-friendly unit; convert_xxx_from_base_unit() rely on that. + * (The order of the base-unit groups does not matter.) */ #define MAX_UNIT_LEN 3 /* length of longest recognized unit string */ @@ -705,9 +775,7 @@ typedef struct char unit[MAX_UNIT_LEN + 1]; /* unit, as a string, like "kB" or * "min" */ int base_unit; /* GUC_UNIT_XXX */ - int multiplier; /* If positive, multiply the value with this - * for unit -> base_unit conversion. If - * negative, divide (with the absolute value) */ + double multiplier; /* Factor for converting unit -> base_unit */ } unit_conversion; /* Ensure that the constants in the tables don't overflow or underflow */ @@ -718,39 +786,44 @@ typedef struct #error XLOG_BLCKSZ must be between 1KB and 1MB #endif -static const char *memory_units_hint = gettext_noop("Valid units for this parameter are \"kB\", \"MB\", \"GB\", and \"TB\"."); +static const char *memory_units_hint = gettext_noop("Valid units for this parameter are \"B\", \"kB\", \"MB\", \"GB\", and \"TB\"."); static const unit_conversion memory_unit_conversion_table[] = { - {"GB", GUC_UNIT_BYTE, 1024 * 1024 * 1024}, - {"MB", GUC_UNIT_BYTE, 1024 * 1024}, - {"kB", GUC_UNIT_BYTE, 1024}, - {"B", GUC_UNIT_BYTE, 1}, - - {"TB", GUC_UNIT_KB, 1024 * 1024 * 1024}, - {"GB", GUC_UNIT_KB, 1024 * 1024}, - {"MB", GUC_UNIT_KB, 1024}, - {"kB", GUC_UNIT_KB, 1}, - - {"TB", GUC_UNIT_MB, 1024 * 1024}, - {"GB", GUC_UNIT_MB, 1024}, - {"MB", GUC_UNIT_MB, 1}, - {"kB", GUC_UNIT_MB, -1024}, - - {"TB", GUC_UNIT_BLOCKS, (1024 * 1024 * 1024) / (BLCKSZ / 1024)}, - {"GB", GUC_UNIT_BLOCKS, (1024 * 1024) / (BLCKSZ / 1024)}, - {"MB", GUC_UNIT_BLOCKS, 1024 / (BLCKSZ / 1024)}, - {"kB", GUC_UNIT_BLOCKS, -(BLCKSZ / 1024)}, - - {"TB", GUC_UNIT_XBLOCKS, (1024 * 1024 * 1024) / (XLOG_BLCKSZ / 1024)}, - {"GB", GUC_UNIT_XBLOCKS, (1024 * 1024) / (XLOG_BLCKSZ / 1024)}, - {"MB", GUC_UNIT_XBLOCKS, 1024 / (XLOG_BLCKSZ / 1024)}, - {"kB", GUC_UNIT_XBLOCKS, -(XLOG_BLCKSZ / 1024)}, + {"TB", GUC_UNIT_BYTE, 1024.0 * 1024.0 * 1024.0 * 1024.0}, + {"GB", GUC_UNIT_BYTE, 1024.0 * 1024.0 * 1024.0}, + {"MB", GUC_UNIT_BYTE, 1024.0 * 1024.0}, + {"kB", GUC_UNIT_BYTE, 1024.0}, + {"B", GUC_UNIT_BYTE, 1.0}, + + {"TB", GUC_UNIT_KB, 1024.0 * 1024.0 * 1024.0}, + {"GB", GUC_UNIT_KB, 1024.0 * 1024.0}, + {"MB", GUC_UNIT_KB, 1024.0}, + {"kB", GUC_UNIT_KB, 1.0}, + {"B", GUC_UNIT_KB, 1.0 / 1024.0}, + + {"TB", GUC_UNIT_MB, 1024.0 * 1024.0}, + {"GB", GUC_UNIT_MB, 1024.0}, + {"MB", GUC_UNIT_MB, 1.0}, + {"kB", GUC_UNIT_MB, 1.0 / 1024.0}, + {"B", GUC_UNIT_MB, 1.0 / (1024.0 * 1024.0)}, + + {"TB", GUC_UNIT_BLOCKS, (1024.0 * 1024.0 * 1024.0) / (BLCKSZ / 1024)}, + {"GB", GUC_UNIT_BLOCKS, (1024.0 * 1024.0) / (BLCKSZ / 1024)}, + {"MB", GUC_UNIT_BLOCKS, 1024.0 / (BLCKSZ / 1024)}, + {"kB", GUC_UNIT_BLOCKS, 1.0 / (BLCKSZ / 1024)}, + {"B", GUC_UNIT_BLOCKS, 1.0 / BLCKSZ}, + + {"TB", GUC_UNIT_XBLOCKS, (1024.0 * 1024.0 * 1024.0) / (XLOG_BLCKSZ / 1024)}, + {"GB", GUC_UNIT_XBLOCKS, (1024.0 * 1024.0) / (XLOG_BLCKSZ / 1024)}, + {"MB", GUC_UNIT_XBLOCKS, 1024.0 / (XLOG_BLCKSZ / 1024)}, + {"kB", GUC_UNIT_XBLOCKS, 1.0 / (XLOG_BLCKSZ / 1024)}, + {"B", GUC_UNIT_XBLOCKS, 1.0 / XLOG_BLCKSZ}, {""} /* end of table marker */ }; -static const char *time_units_hint = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\"."); +static const char *time_units_hint = gettext_noop("Valid units for this parameter are \"us\", \"ms\", \"s\", \"min\", \"h\", and \"d\"."); static const unit_conversion time_unit_conversion_table[] = { @@ -759,18 +832,21 @@ static const unit_conversion time_unit_conversion_table[] = {"min", GUC_UNIT_MS, 1000 * 60}, {"s", GUC_UNIT_MS, 1000}, {"ms", GUC_UNIT_MS, 1}, + {"us", GUC_UNIT_MS, 1.0 / 1000}, {"d", GUC_UNIT_S, 60 * 60 * 24}, {"h", GUC_UNIT_S, 60 * 60}, {"min", GUC_UNIT_S, 60}, {"s", GUC_UNIT_S, 1}, - {"ms", GUC_UNIT_S, -1000}, + {"ms", GUC_UNIT_S, 1.0 / 1000}, + {"us", GUC_UNIT_S, 1.0 / (1000 * 1000)}, {"d", GUC_UNIT_MIN, 60 * 24}, {"h", GUC_UNIT_MIN, 60}, {"min", GUC_UNIT_MIN, 1}, - {"s", GUC_UNIT_MIN, -60}, - {"ms", GUC_UNIT_MIN, -1000 * 60}, + {"s", GUC_UNIT_MIN, 1.0 / 60}, + {"ms", GUC_UNIT_MIN, 1.0 / (1000 * 60)}, + {"us", GUC_UNIT_MIN, 1.0 / (1000 * 1000 * 60)}, {""} /* end of table marker */ }; @@ -810,7 +886,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of sequential-scan plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_seqscan, true, @@ -819,7 +896,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_indexscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of index-scan plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_indexscan, true, @@ -828,7 +906,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_indexonlyscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of index-only-scan plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_indexonlyscan, true, @@ -837,7 +916,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of bitmap-scan plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_bitmapscan, true, @@ -846,7 +926,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of TID scan plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_tidscan, true, @@ -855,7 +936,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_sort", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of explicit sort steps."), - NULL + NULL, + GUC_EXPLAIN }, &enable_sort, true, @@ -864,7 +946,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_hashagg", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of hashed aggregation plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_hashagg, true, @@ -873,7 +956,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_material", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of materialization."), - NULL + NULL, + GUC_EXPLAIN }, &enable_material, true, @@ -882,7 +966,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_nestloop", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of nested-loop join plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_nestloop, true, @@ -891,7 +976,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_mergejoin", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of merge join plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_mergejoin, true, @@ -900,7 +986,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_hashjoin", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of hash join plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_hashjoin, true, @@ -909,7 +996,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_gathermerge", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of gather merge plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_gathermerge, true, @@ -918,7 +1006,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_partitionwise_join", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables partitionwise join."), - NULL + NULL, + GUC_EXPLAIN }, &enable_partitionwise_join, false, @@ -927,7 +1016,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_partitionwise_aggregate", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables partitionwise aggregation and grouping."), - NULL + NULL, + GUC_EXPLAIN }, &enable_partitionwise_aggregate, false, @@ -936,7 +1026,8 @@ static struct config_bool ConfigureNamesBool[] = { {"enable_parallel_append", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of parallel append plans."), - NULL + NULL, + GUC_EXPLAIN }, &enable_parallel_append, true, @@ -944,18 +1035,32 @@ static struct config_bool ConfigureNamesBool[] = }, { {"enable_parallel_hash", PGC_USERSET, QUERY_TUNING_METHOD, - gettext_noop("Enables the planner's user of parallel hash plans."), - NULL + gettext_noop("Enables the planner's use of parallel hash plans."), + NULL, + GUC_EXPLAIN }, &enable_parallel_hash, true, NULL, NULL, NULL }, + { + {"enable_partition_pruning", PGC_USERSET, QUERY_TUNING_METHOD, + gettext_noop("Enables plan-time and run-time partition pruning."), + gettext_noop("Allows the query planner and executor to compare partition " + "bounds to conditions in the query to determine which " + "partitions must be scanned."), + GUC_EXPLAIN + }, + &enable_partition_pruning, + true, + NULL, NULL, NULL + }, { {"geqo", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("Enables genetic query optimization."), gettext_noop("This algorithm attempts to do planning without " - "exhaustive searching.") + "exhaustive searching."), + GUC_EXPLAIN }, &enable_geqo, true, @@ -1092,6 +1197,26 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"wal_init_zero", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Writes zeroes to new WAL files before first use."), + NULL + }, + &wal_init_zero, + true, + NULL, NULL, NULL + }, + + { + {"wal_recycle", PGC_SUSET, WAL_SETTINGS, + gettext_noop("Recycles WAL files by renaming them."), + NULL + }, + &wal_recycle, + true, + NULL, NULL, NULL + }, + { {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs each checkpoint."), @@ -1475,14 +1600,21 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL, NULL }, + + /* + * WITH OIDS support, and consequently default_with_oids, was removed in + * PostgreSQL 12, but we tolerate the parameter being set to false to + * avoid unnecessarily breaking older dump files. + */ { {"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS, - gettext_noop("Create new tables with OIDs by default."), - NULL + gettext_noop("WITH OIDS is no longer supported; this can only be false."), + NULL, + GUC_NO_SHOW_ALL | GUC_NOT_IN_SAMPLE }, &default_with_oids, false, - NULL, NULL, NULL + check_default_with_oids, NULL, NULL }, { {"logging_collector", PGC_POSTMASTER, LOGGING_WHERE, @@ -1537,7 +1669,7 @@ static struct config_bool ConfigureNamesBool[] = "optimize_bounded_sort", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enable bounded sorting using heap sort."), NULL, - GUC_NOT_IN_SAMPLE + GUC_NOT_IN_SAMPLE | GUC_EXPLAIN }, &optimize_bounded_sort, true, @@ -1610,6 +1742,16 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"recovery_target_inclusive", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets whether to include or exclude transaction with recovery target."), + NULL + }, + &recoveryTargetInclusive, + true, + NULL, NULL, NULL + }, + { {"hot_standby", PGC_POSTMASTER, REPLICATION_STANDBY, gettext_noop("Allows connections and queries during recovery."), @@ -1718,7 +1860,8 @@ static struct config_bool ConfigureNamesBool[] = { {"parallel_leader_participation", PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Controls whether Gather and Gather Merge also run subplans."), - gettext_noop("Should gather nodes also run subplans, or just gather tuples?") + gettext_noop("Should gather nodes also run subplans, or just gather tuples?"), + GUC_EXPLAIN }, ¶llel_leader_participation, true, @@ -1728,7 +1871,8 @@ static struct config_bool ConfigureNamesBool[] = { {"jit", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Allow JIT compilation."), - NULL + NULL, + GUC_EXPLAIN }, &jit_enabled, true, @@ -1743,6 +1887,7 @@ static struct config_bool ConfigureNamesBool[] = }, &jit_debugging_support, false, + /* * This is not guaranteed to be available, but given it's a developer * oriented option, it doesn't seem worth adding code checking @@ -1781,6 +1926,7 @@ static struct config_bool ConfigureNamesBool[] = }, &jit_profiling_support, false, + /* * This is not guaranteed to be available, but given it's a developer * oriented option, it doesn't seem worth adding code checking @@ -1800,6 +1946,15 @@ static struct config_bool ConfigureNamesBool[] = NULL, NULL, NULL }, + { + {"data_sync_retry", PGC_POSTMASTER, ERROR_HANDLING_OPTIONS, + gettext_noop("Whether to continue running after a failure to sync data files."), + }, + &data_sync_retry, + false, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL @@ -1846,7 +2001,8 @@ static struct config_int ConfigureNamesInt[] = "are not collapsed."), gettext_noop("The planner will merge subqueries into upper " "queries if the resulting FROM list would have no more than " - "this many items.") + "this many items."), + GUC_EXPLAIN }, &from_collapse_limit, 8, 1, INT_MAX, @@ -1858,7 +2014,8 @@ static struct config_int ConfigureNamesInt[] = "constructs are not flattened."), gettext_noop("The planner will flatten explicit JOIN " "constructs into lists of FROM items whenever a " - "list of no more than this many items would result.") + "list of no more than this many items would result."), + GUC_EXPLAIN }, &join_collapse_limit, 8, 1, INT_MAX, @@ -1867,7 +2024,8 @@ static struct config_int ConfigureNamesInt[] = { {"geqo_threshold", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("Sets the threshold of FROM items beyond which GEQO is used."), - NULL + NULL, + GUC_EXPLAIN }, &geqo_threshold, 12, 2, INT_MAX, @@ -1876,7 +2034,8 @@ static struct config_int ConfigureNamesInt[] = { {"geqo_effort", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: effort is used to set the default for other GEQO parameters."), - NULL + NULL, + GUC_EXPLAIN }, &Geqo_effort, DEFAULT_GEQO_EFFORT, MIN_GEQO_EFFORT, MAX_GEQO_EFFORT, @@ -1885,7 +2044,8 @@ static struct config_int ConfigureNamesInt[] = { {"geqo_pool_size", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: number of individuals in the population."), - gettext_noop("Zero selects a suitable default value.") + gettext_noop("Zero selects a suitable default value."), + GUC_EXPLAIN }, &Geqo_pool_size, 0, 0, INT_MAX, @@ -1894,7 +2054,8 @@ static struct config_int ConfigureNamesInt[] = { {"geqo_generations", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: number of iterations of the algorithm."), - gettext_noop("Zero selects a suitable default value.") + gettext_noop("Zero selects a suitable default value."), + GUC_EXPLAIN }, &Geqo_generations, 0, 0, INT_MAX, @@ -1935,9 +2096,20 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"recovery_min_apply_delay", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Sets the minimum delay for applying changes during recovery."), + NULL, + GUC_UNIT_MS + }, + &recovery_min_apply_delay, + 0, 0, INT_MAX, + NULL, NULL, NULL + }, + { {"wal_receiver_status_interval", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum interval between WAL receiver status reports to the primary."), + gettext_noop("Sets the maximum interval between WAL receiver status reports to the sending server."), NULL, GUC_UNIT_S }, @@ -1948,7 +2120,7 @@ static struct config_int ConfigureNamesInt[] = { {"wal_receiver_timeout", PGC_SIGHUP, REPLICATION_STANDBY, - gettext_noop("Sets the maximum wait time to receive data from the primary."), + gettext_noop("Sets the maximum wait time to receive data from the sending server."), NULL, GUC_UNIT_MS }, @@ -1968,7 +2140,7 @@ static struct config_int ConfigureNamesInt[] = }, { - /* see max_connections and max_wal_senders */ + /* see max_connections */ {"superuser_reserved_connections", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the number of connection slots reserved for superusers."), NULL @@ -1997,7 +2169,7 @@ static struct config_int ConfigureNamesInt[] = {"temp_buffers", PGC_USERSET, RESOURCES_MEM, gettext_noop("Sets the maximum number of temporary buffers used by each session."), NULL, - GUC_UNIT_BLOCKS + GUC_UNIT_BLOCKS | GUC_EXPLAIN }, &num_temp_buffers, 1024, 100, INT_MAX / 2, @@ -2064,7 +2236,7 @@ static struct config_int ConfigureNamesInt[] = gettext_noop("This much memory can be used by each internal " "sort operation and hash table before switching to " "temporary disk files."), - GUC_UNIT_KB + GUC_UNIT_KB | GUC_EXPLAIN }, &work_mem, 4096, 64, MAX_KILOBYTES, @@ -2149,28 +2321,6 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, - { - {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY, - gettext_noop("Vacuum cost delay in milliseconds."), - NULL, - GUC_UNIT_MS - }, - &VacuumCostDelay, - 0, 0, 100, - NULL, NULL, NULL - }, - - { - {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM, - gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."), - NULL, - GUC_UNIT_MS - }, - &autovacuum_vac_cost_delay, - 20, -1, 100, - NULL, NULL, NULL - }, - { {"autovacuum_vacuum_cost_limit", PGC_SIGHUP, AUTOVACUUM, gettext_noop("Vacuum cost amount available before napping, for autovacuum."), @@ -2486,14 +2636,13 @@ static struct config_int ConfigureNamesInt[] = }, { - /* see max_connections and superuser_reserved_connections */ {"max_wal_senders", PGC_POSTMASTER, REPLICATION_SENDING, gettext_noop("Sets the maximum number of simultaneously running WAL sender processes."), NULL }, &max_wal_senders, 10, 0, MAX_BACKENDS, - NULL, NULL, NULL + check_max_wal_senders, NULL, NULL }, { @@ -2508,7 +2657,7 @@ static struct config_int ConfigureNamesInt[] = }, { - {"wal_sender_timeout", PGC_SIGHUP, REPLICATION_SENDING, + {"wal_sender_timeout", PGC_USERSET, REPLICATION_SENDING, gettext_noop("Sets the maximum time to wait for WAL replication."), NULL, GUC_UNIT_MS @@ -2545,11 +2694,12 @@ static struct config_int ConfigureNamesInt[] = {"extra_float_digits", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the number of digits displayed for floating-point values."), gettext_noop("This affects real, double precision, and geometric data types. " - "The parameter value is added to the standard number of digits " - "(FLT_DIG or DBL_DIG as appropriate).") + "A zero or negative parameter value is added to the standard " + "number of digits (FLT_DIG or DBL_DIG as appropriate). " + "Any value greater than zero selects precise output mode.") }, &extra_float_digits, - 0, -15, 3, + 1, -15, 3, NULL, NULL, NULL }, @@ -2614,14 +2764,16 @@ static struct config_int ConfigureNamesInt[] = PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Number of simultaneous requests that can be handled efficiently by the disk subsystem."), - gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array.") + gettext_noop("For RAID arrays, this should be approximately the number of drive spindles in the array."), + GUC_EXPLAIN }, &effective_io_concurrency, #ifdef USE_PREFETCH - 1, 0, MAX_IO_CONCURRENCY, + 1, #else - 0, 0, 0, + 0, #endif + 0, MAX_IO_CONCURRENCY, check_effective_io_concurrency, assign_effective_io_concurrency, NULL }, @@ -2858,7 +3010,8 @@ static struct config_int ConfigureNamesInt[] = { {"max_parallel_workers_per_gather", PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Sets the maximum number of parallel processes per executor node."), - NULL + NULL, + GUC_EXPLAIN }, &max_parallel_workers_per_gather, 2, 0, MAX_PARALLEL_WORKER_LIMIT, @@ -2868,7 +3021,8 @@ static struct config_int ConfigureNamesInt[] = { {"max_parallel_workers", PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Sets the maximum number of parallel workers that can be active at one time."), - NULL + NULL, + GUC_EXPLAIN }, &max_parallel_workers, 8, 0, MAX_PARALLEL_WORKER_LIMIT, @@ -2955,11 +3109,10 @@ static struct config_int ConfigureNamesInt[] = { {"effective_cache_size", PGC_USERSET, QUERY_TUNING_COST, - gettext_noop("Sets the planner's assumption about the size of the disk cache."), - gettext_noop("That is, the portion of the kernel's disk cache that " - "will be used for PostgreSQL data files. This is measured in disk " - "pages, which are normally 8 kB each."), - GUC_UNIT_BLOCKS, + gettext_noop("Sets the planner's assumption about the total size of the data caches."), + gettext_noop("That is, the total size of the caches (kernel cache and shared buffers) used for PostgreSQL data files. " + "This is measured in disk pages, which are normally 8 kB each."), + GUC_UNIT_BLOCKS | GUC_EXPLAIN, }, &effective_cache_size, DEFAULT_EFFECTIVE_CACHE_SIZE, 1, INT_MAX, @@ -2970,7 +3123,7 @@ static struct config_int ConfigureNamesInt[] = {"min_parallel_table_scan_size", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the minimum amount of table data for a parallel scan."), gettext_noop("If the planner estimates that it will read a number of table pages too small to reach this limit, a parallel scan will not be considered."), - GUC_UNIT_BLOCKS, + GUC_UNIT_BLOCKS | GUC_EXPLAIN, }, &min_parallel_table_scan_size, (8 * 1024 * 1024) / BLCKSZ, 0, INT_MAX / 3, @@ -2981,7 +3134,7 @@ static struct config_int ConfigureNamesInt[] = {"min_parallel_index_scan_size", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the minimum amount of index data for a parallel scan."), gettext_noop("If the planner estimates that it will read a number of index pages too small to reach this limit, a parallel scan will not be considered."), - GUC_UNIT_BLOCKS, + GUC_UNIT_BLOCKS | GUC_EXPLAIN, }, &min_parallel_index_scan_size, (512 * 1024) / BLCKSZ, 0, INT_MAX / 3, @@ -3033,6 +3186,17 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"tcp_user_timeout", PGC_USERSET, CLIENT_CONN_OTHER, + gettext_noop("TCP user timeout."), + gettext_noop("A value of 0 uses the system default."), + GUC_UNIT_MS + }, + &tcp_user_timeout, + 0, 0, INT_MAX, + NULL, assign_tcp_user_timeout, show_tcp_user_timeout + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL @@ -3046,7 +3210,8 @@ static struct config_real ConfigureNamesReal[] = {"seq_page_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of a " "sequentially fetched disk page."), - NULL + NULL, + GUC_EXPLAIN }, &seq_page_cost, DEFAULT_SEQ_PAGE_COST, 0, DBL_MAX, @@ -3056,7 +3221,8 @@ static struct config_real ConfigureNamesReal[] = {"random_page_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of a " "nonsequentially fetched disk page."), - NULL + NULL, + GUC_EXPLAIN }, &random_page_cost, DEFAULT_RANDOM_PAGE_COST, 0, DBL_MAX, @@ -3066,7 +3232,8 @@ static struct config_real ConfigureNamesReal[] = {"cpu_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of " "processing each tuple (row)."), - NULL + NULL, + GUC_EXPLAIN }, &cpu_tuple_cost, DEFAULT_CPU_TUPLE_COST, 0, DBL_MAX, @@ -3076,7 +3243,8 @@ static struct config_real ConfigureNamesReal[] = {"cpu_index_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of " "processing each index entry during an index scan."), - NULL + NULL, + GUC_EXPLAIN }, &cpu_index_tuple_cost, DEFAULT_CPU_INDEX_TUPLE_COST, 0, DBL_MAX, @@ -3086,7 +3254,8 @@ static struct config_real ConfigureNamesReal[] = {"cpu_operator_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of " "processing each operator or function call."), - NULL + NULL, + GUC_EXPLAIN }, &cpu_operator_cost, DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, @@ -3096,7 +3265,8 @@ static struct config_real ConfigureNamesReal[] = {"parallel_tuple_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of " "passing each tuple (row) from worker to master backend."), - NULL + NULL, + GUC_EXPLAIN }, ¶llel_tuple_cost, DEFAULT_PARALLEL_TUPLE_COST, 0, DBL_MAX, @@ -3106,7 +3276,8 @@ static struct config_real ConfigureNamesReal[] = {"parallel_setup_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Sets the planner's estimate of the cost of " "starting up worker processes for parallel query."), - NULL + NULL, + GUC_EXPLAIN }, ¶llel_setup_cost, DEFAULT_PARALLEL_SETUP_COST, 0, DBL_MAX, @@ -3116,7 +3287,8 @@ static struct config_real ConfigureNamesReal[] = { {"jit_above_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Perform JIT compilation if query is more expensive."), - gettext_noop("-1 disables JIT compilation.") + gettext_noop("-1 disables JIT compilation."), + GUC_EXPLAIN }, &jit_above_cost, 100000, -1, DBL_MAX, @@ -3126,7 +3298,8 @@ static struct config_real ConfigureNamesReal[] = { {"jit_optimize_above_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Optimize JITed functions if query is more expensive."), - gettext_noop("-1 disables optimization.") + gettext_noop("-1 disables optimization."), + GUC_EXPLAIN }, &jit_optimize_above_cost, 500000, -1, DBL_MAX, @@ -3136,7 +3309,8 @@ static struct config_real ConfigureNamesReal[] = { {"jit_inline_above_cost", PGC_USERSET, QUERY_TUNING_COST, gettext_noop("Perform JIT inlining if query is more expensive."), - gettext_noop("-1 disables inlining.") + gettext_noop("-1 disables inlining."), + GUC_EXPLAIN }, &jit_inline_above_cost, 500000, -1, DBL_MAX, @@ -3147,7 +3321,8 @@ static struct config_real ConfigureNamesReal[] = {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Sets the planner's estimate of the fraction of " "a cursor's rows that will be retrieved."), - NULL + NULL, + GUC_EXPLAIN }, &cursor_tuple_fraction, DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, @@ -3157,7 +3332,8 @@ static struct config_real ConfigureNamesReal[] = { {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: selective pressure within the population."), - NULL + NULL, + GUC_EXPLAIN }, &Geqo_selection_bias, DEFAULT_GEQO_SELECTION_BIAS, @@ -3167,7 +3343,8 @@ static struct config_real ConfigureNamesReal[] = { {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO, gettext_noop("GEQO: seed for random path selection."), - NULL + NULL, + GUC_EXPLAIN }, &Geqo_seed, 0.0, 0.0, 1.0, @@ -3195,6 +3372,28 @@ static struct config_real ConfigureNamesReal[] = check_random_seed, assign_random_seed, show_random_seed }, + { + {"vacuum_cost_delay", PGC_USERSET, RESOURCES_VACUUM_DELAY, + gettext_noop("Vacuum cost delay in milliseconds."), + NULL, + GUC_UNIT_MS + }, + &VacuumCostDelay, + 0, 0, 100, + NULL, NULL, NULL + }, + + { + {"autovacuum_vacuum_cost_delay", PGC_SIGHUP, AUTOVACUUM, + gettext_noop("Vacuum cost delay in milliseconds, for autovacuum."), + NULL, + GUC_UNIT_MS + }, + &autovacuum_vac_cost_delay, + 2, -1, 100, + NULL, NULL, NULL + }, + { {"autovacuum_vacuum_scale_factor", PGC_SIGHUP, AUTOVACUUM, gettext_noop("Number of tuple updates or deletes prior to vacuum as a fraction of reltuples."), @@ -3225,12 +3424,24 @@ static struct config_real ConfigureNamesReal[] = }, { - {"vacuum_cleanup_index_scale_factor", PGC_SIGHUP, AUTOVACUUM, + {"vacuum_cleanup_index_scale_factor", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Number of tuple inserts prior to index cleanup as a fraction of reltuples."), NULL }, &vacuum_cleanup_index_scale_factor, - 0.1, 0.0, 100.0, + 0.1, 0.0, 1e10, + NULL, NULL, NULL + }, + + { + {"log_transaction_sample_rate", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Set the fraction of transactions to log for new transactions."), + gettext_noop("Logs all statements from a fraction of transactions. " + "Use a value between 0.0 (never log) and 1.0 (log all " + "statements for all transactions).") + }, + &log_xact_sample_rate, + 0.0, 0.0, 1.0, NULL, NULL, NULL }, @@ -3254,84 +3465,223 @@ static struct config_string ConfigureNamesString[] = }, { - {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the client's character set encoding."), - NULL, - GUC_IS_NAME | GUC_REPORT + {"restore_command", PGC_POSTMASTER, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will retrieve an archived WAL file."), + NULL }, - &client_encoding_string, - "SQL_ASCII", - check_client_encoding, assign_client_encoding, NULL + &recoveryRestoreCommand, + "", + NULL, NULL, NULL }, { - {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Controls information prefixed to each log line."), - gettext_noop("If blank, no prefix is used.") + {"archive_cleanup_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be executed at every restart point."), + NULL }, - &Log_line_prefix, - "%m [%p] ", + &archiveCleanupCommand, + "", NULL, NULL, NULL }, { - {"log_timezone", PGC_SIGHUP, LOGGING_WHAT, - gettext_noop("Sets the time zone to use in log messages."), + {"recovery_end_command", PGC_SIGHUP, WAL_ARCHIVE_RECOVERY, + gettext_noop("Sets the shell command that will be executed once at the end of recovery."), NULL }, - &log_timezone_string, - "GMT", - check_log_timezone, assign_log_timezone, show_log_timezone + &recoveryEndCommand, + "", + NULL, NULL, NULL }, { - {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE, - gettext_noop("Sets the display format for date and time values."), - gettext_noop("Also controls interpretation of ambiguous " - "date inputs."), - GUC_LIST_INPUT | GUC_REPORT + {"recovery_target_timeline", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Specifies the timeline to recover into."), + NULL }, - &datestyle_string, - "ISO, MDY", - check_datestyle, assign_datestyle, NULL + &recovery_target_timeline_string, + "latest", + check_recovery_target_timeline, assign_recovery_target_timeline, NULL }, { - {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the default tablespace to create tables and indexes in."), - gettext_noop("An empty string selects the database's default tablespace."), - GUC_IS_NAME + {"recovery_target", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Set to \"immediate\" to end recovery as soon as a consistent state is reached."), + NULL }, - &default_tablespace, + &recovery_target_string, "", - check_default_tablespace, NULL, NULL + check_recovery_target, assign_recovery_target, NULL }, - { - {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."), - NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE + {"recovery_target_xid", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the transaction ID up to which recovery will proceed."), + NULL }, - &temp_tablespaces, + &recovery_target_xid_string, "", - check_temp_tablespaces, assign_temp_tablespaces, NULL + check_recovery_target_xid, assign_recovery_target_xid, NULL }, - { - {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, - gettext_noop("Sets the path for dynamically loadable modules."), - gettext_noop("If a dynamically loadable module needs to be opened and " - "the specified name does not have a directory component (i.e., the " - "name does not contain a slash), the system will search this path for " - "the specified file."), - GUC_SUPERUSER_ONLY + {"recovery_target_time", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the time stamp up to which recovery will proceed."), + NULL + }, + &recovery_target_time_string, + "", + check_recovery_target_time, assign_recovery_target_time, NULL + }, + { + {"recovery_target_name", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the named restore point up to which recovery will proceed."), + NULL + }, + &recovery_target_name_string, + "", + check_recovery_target_name, assign_recovery_target_name, NULL + }, + { + {"recovery_target_lsn", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the LSN of the write-ahead log location up to which recovery will proceed."), + NULL + }, + &recovery_target_lsn_string, + "", + check_recovery_target_lsn, assign_recovery_target_lsn, NULL + }, + + { + {"promote_trigger_file", PGC_SIGHUP, REPLICATION_STANDBY, + gettext_noop("Specifies a file name whose presence ends recovery in the standby."), + NULL + }, + &PromoteTriggerFile, + "", + NULL, NULL, NULL + }, + + { + {"primary_conninfo", PGC_POSTMASTER, REPLICATION_STANDBY, + gettext_noop("Sets the connection string to be used to connect to the sending server."), + NULL, + GUC_SUPERUSER_ONLY + }, + &PrimaryConnInfo, + "", + NULL, NULL, NULL + }, + + { + {"primary_slot_name", PGC_POSTMASTER, REPLICATION_STANDBY, + gettext_noop("Sets the name of the replication slot to use on the sending server."), + NULL + }, + &PrimarySlotName, + "", + check_primary_slot_name, NULL, NULL + }, + + { + {"client_encoding", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the client's character set encoding."), + NULL, + GUC_IS_NAME | GUC_REPORT + }, + &client_encoding_string, + "SQL_ASCII", + check_client_encoding, assign_client_encoding, NULL + }, + + { + {"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Controls information prefixed to each log line."), + gettext_noop("If blank, no prefix is used.") + }, + &Log_line_prefix, + "%m [%p] ", + NULL, NULL, NULL + }, + + { + {"log_timezone", PGC_SIGHUP, LOGGING_WHAT, + gettext_noop("Sets the time zone to use in log messages."), + NULL + }, + &log_timezone_string, + "GMT", + check_log_timezone, assign_log_timezone, show_log_timezone + }, + + { + {"DateStyle", PGC_USERSET, CLIENT_CONN_LOCALE, + gettext_noop("Sets the display format for date and time values."), + gettext_noop("Also controls interpretation of ambiguous " + "date inputs."), + GUC_LIST_INPUT | GUC_REPORT + }, + &datestyle_string, + "ISO, MDY", + check_datestyle, assign_datestyle, NULL + }, + + { + {"default_table_access_method", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default table access method for new tables."), + NULL, + GUC_IS_NAME + }, + &default_table_access_method, + DEFAULT_TABLE_ACCESS_METHOD, + check_default_table_access_method, NULL, NULL + }, + + { + {"default_tablespace", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the default tablespace to create tables and indexes in."), + gettext_noop("An empty string selects the database's default tablespace."), + GUC_IS_NAME + }, + &default_tablespace, + "", + check_default_tablespace, NULL, NULL + }, + + { + {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."), + NULL, + GUC_LIST_INPUT | GUC_LIST_QUOTE + }, + &temp_tablespaces, + "", + check_temp_tablespaces, assign_temp_tablespaces, NULL + }, + + { + {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, + gettext_noop("Sets the path for dynamically loadable modules."), + gettext_noop("If a dynamically loadable module needs to be opened and " + "the specified name does not have a directory component (i.e., the " + "name does not contain a slash), the system will search this path for " + "the specified file."), + GUC_SUPERUSER_ONLY }, &Dynamic_library_path, "$libdir", NULL, NULL, NULL }, + { + {"online_upgrade_path", PGC_SIGHUP, FILE_LOCATIONS, + gettext_noop("Specify path to binaries of new Postgres version for online upgrade"), + NULL, + GUC_SUPERUSER_ONLY + }, + &OnlineUpgradePath, + "", + check_online_update_support, NULL, NULL + }, + { {"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_AUTH, gettext_noop("Sets the location of the Kerberos server key file."), @@ -3454,7 +3804,7 @@ static struct config_string ConfigureNamesString[] = {"search_path", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the schema search order for names that are not schema-qualified."), NULL, - GUC_LIST_INPUT | GUC_LIST_QUOTE + GUC_LIST_INPUT | GUC_LIST_QUOTE | GUC_EXPLAIN }, &namespace_search_path, "\"$user\", public", @@ -3585,17 +3935,6 @@ static struct config_string ConfigureNamesString[] = check_timezone_abbreviations, assign_timezone_abbreviations, NULL }, - { - {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, - gettext_noop("Sets the current transaction's isolation level."), - NULL, - GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE - }, - &XactIsoLevel_string, - "default", - check_XactIsoLevel, assign_XactIsoLevel, show_XactIsoLevel - }, - { {"unix_socket_group", PGC_POSTMASTER, CONN_AUTH_SETTINGS, gettext_noop("Sets the owning group of the Unix-domain socket."), @@ -3692,6 +4031,21 @@ static struct config_string ConfigureNamesString[] = check_canonical_path, NULL, NULL }, + { + {"ssl_library", PGC_INTERNAL, PRESET_OPTIONS, + gettext_noop("Name of the SSL library."), + NULL, + GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &ssl_library, +#ifdef USE_SSL + "OpenSSL", +#else + "", +#endif + NULL, NULL, NULL + }, + { {"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SSL, gettext_noop("Location of the SSL server certificate file."), @@ -3771,7 +4125,7 @@ static struct config_string ConfigureNamesString[] = GUC_SUPERUSER_ONLY }, &SSLCipherSuites, -#ifdef USE_SSL +#ifdef USE_OPENSSL "HIGH:MEDIUM:+3DES:!aNULL", #else "none", @@ -3849,7 +4203,7 @@ static struct config_string ConfigureNamesString[] = }, { - {"jit_provider", PGC_POSTMASTER, FILE_LOCATIONS, + {"jit_provider", PGC_POSTMASTER, CLIENT_CONN_PRELOAD, gettext_noop("JIT provider to use."), NULL, GUC_SUPERUSER_ONLY @@ -3889,7 +4243,7 @@ static struct config_enum ConfigureNamesEnum[] = }, { - {"client_min_messages", PGC_USERSET, LOGGING_WHEN, + {"client_min_messages", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the message levels that are sent to the client."), gettext_noop("Each level includes all the levels that follow it. The later" " the level, the fewer messages are sent.") @@ -3903,7 +4257,8 @@ static struct config_enum ConfigureNamesEnum[] = {"constraint_exclusion", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Enables the planner to use constraints to optimize queries."), gettext_noop("Table scans will be skipped if their constraints" - " guarantee that no rows match the query.") + " guarantee that no rows match the query."), + GUC_EXPLAIN }, &constraint_exclusion, CONSTRAINT_EXCLUSION_PARTITION, constraint_exclusion_options, @@ -3920,6 +4275,17 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"transaction_isolation", PGC_USERSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the current transaction's isolation level."), + NULL, + GUC_NO_RESET_ALL | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE + }, + &XactIsoLevel, + XACT_READ_COMMITTED, isolation_level_options, + check_XactIsoLevel, NULL, NULL + }, + { {"IntervalStyle", PGC_USERSET, CLIENT_CONN_LOCALE, gettext_noop("Sets the display format for interval values."), @@ -4018,6 +4384,16 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"recovery_target_action", PGC_POSTMASTER, WAL_RECOVERY_TARGET, + gettext_noop("Sets the action to perform upon reaching the recovery target."), + NULL + }, + &recoveryTargetAction, + RECOVERY_TARGET_ACTION_PAUSE, recovery_target_action_options, + NULL, NULL, NULL + }, + { {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS, gettext_noop("Enables logging of recovery-related debugging information."), @@ -4064,6 +4440,16 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"shared_memory_type", PGC_POSTMASTER, RESOURCES_MEM, + gettext_noop("Selects the shared memory implementation used for the main shared memory region."), + NULL + }, + &shared_memory_type, + DEFAULT_SHARED_MEMORY_TYPE, shared_memory_options, + NULL, NULL, NULL + }, + { {"wal_sync_method", PGC_SIGHUP, WAL_SETTINGS, gettext_noop("Selects the method used for forcing WAL updates to disk."), @@ -4108,7 +4494,8 @@ static struct config_enum ConfigureNamesEnum[] = { {"force_parallel_mode", PGC_USERSET, QUERY_TUNING_OTHER, gettext_noop("Forces use of parallel query facilities."), - gettext_noop("If possible, run query using a parallel worker and with parallel restrictions.") + gettext_noop("If possible, run query using a parallel worker and with parallel restrictions."), + GUC_EXPLAIN }, &force_parallel_mode, FORCE_PARALLEL_OFF, force_parallel_mode_options, @@ -4127,6 +4514,43 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"plan_cache_mode", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Controls the planner's selection of custom or generic plan."), + gettext_noop("Prepared statements can have custom and generic plans, and the planner " + "will attempt to choose which is better. This can be set to override " + "the default behavior."), + GUC_EXPLAIN + }, + &plan_cache_mode, + PLAN_CACHE_MODE_AUTO, plan_cache_mode_options, + NULL, NULL, NULL + }, + + { + {"ssl_min_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the minimum SSL/TLS protocol version to use."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_min_protocol_version, + PG_TLS1_VERSION, + ssl_protocol_versions_info + 1, /* don't allow PG_TLS_ANY */ + NULL, NULL, NULL + }, + + { + {"ssl_max_protocol_version", PGC_SIGHUP, CONN_AUTH_SSL, + gettext_noop("Sets the maximum SSL/TLS protocol version to use."), + NULL, + GUC_SUPERUSER_ONLY + }, + &ssl_max_protocol_version, + PG_TLS_ANY, + ssl_protocol_versions_info, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL @@ -4157,6 +4581,9 @@ static struct config_generic **guc_variables; /* Current number of variables contained in the vector */ static int num_guc_variables; +/* Current number of variables marked with GUC_EXPLAIN */ +static int num_guc_explain_variables; + /* Vector capacity */ static int size_guc_variables; @@ -4175,18 +4602,18 @@ static void InitializeOneGUCOption(struct config_generic *gconf); static void push_old_value(struct config_generic *gconf, GucAction action); static void ReportGUCOption(struct config_generic *record); static void reapply_stacked_values(struct config_generic *variable, - struct config_string *pHolder, - GucStack *stack, - const char *curvalue, - GucContext curscontext, GucSource cursource); + struct config_string *pHolder, + GucStack *stack, + const char *curvalue, + GucContext curscontext, GucSource cursource); static void ShowGUCConfigOption(const char *name, DestReceiver *dest); static void ShowAllGUCConfig(DestReceiver *dest); static char *_ShowOption(struct config_generic *record, bool use_units); static bool validate_option_array_item(const char *name, const char *value, - bool skipIfNoPermissions); + bool skipIfNoPermissions); static void write_auto_conf_file(int fd, const char *filename, ConfigVariable *head_p); static void replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p, - const char *name, const char *value); + const char *name, const char *value); /* @@ -4420,6 +4847,7 @@ build_guc_variables(void) { int size_vars; int num_vars = 0; + int num_explain_vars = 0; struct config_generic **guc_vars; int i; @@ -4430,6 +4858,9 @@ build_guc_variables(void) /* Rather than requiring vartype to be filled in by hand, do this: */ conf->gen.vartype = PGC_BOOL; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesInt[i].gen.name; i++) @@ -4438,6 +4869,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_INT; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesReal[i].gen.name; i++) @@ -4446,6 +4880,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_REAL; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesString[i].gen.name; i++) @@ -4454,6 +4891,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_STRING; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } for (i = 0; ConfigureNamesEnum[i].gen.name; i++) @@ -4462,6 +4902,9 @@ build_guc_variables(void) conf->gen.vartype = PGC_ENUM; num_vars++; + + if (conf->gen.flags & GUC_EXPLAIN) + num_explain_vars++; } /* @@ -4493,6 +4936,7 @@ build_guc_variables(void) free(guc_variables); guc_variables = guc_vars; num_guc_variables = num_vars; + num_guc_explain_variables = num_explain_vars; size_guc_variables = size_vars; qsort((void *) guc_variables, num_guc_variables, sizeof(struct config_generic *), guc_var_compare); @@ -4575,7 +5019,7 @@ add_placeholder_variable(const char *name, int elevel) if (!add_guc_variable((struct config_generic *) var, elevel)) { - free((void *) gen->name); + free(unconstify(char *, gen->name)); free(var); return NULL; } @@ -4716,7 +5160,7 @@ InitializeGUCOptions(void) * Prevent any attempt to override the transaction modes from * non-interactive sources. */ - SetConfigOption("transaction_isolation", "default", + SetConfigOption("transaction_isolation", "read committed", PGC_POSTMASTER, PGC_S_OVERRIDE); SetConfigOption("transaction_read_only", "no", PGC_POSTMASTER, PGC_S_OVERRIDE); @@ -5378,6 +5822,7 @@ AtEOXact_GUC(bool isCommit, int nestLevel) { case GUC_SAVE: Assert(false); /* can't get here */ + break; case GUC_SET: /* next level always becomes SET */ @@ -5624,17 +6069,35 @@ ReportGUCOption(struct config_generic *record) /* * Convert a value from one of the human-friendly units ("kB", "min" etc.) * to the given base unit. 'value' and 'unit' are the input value and unit - * to convert from. The converted value is stored in *base_value. + * to convert from (there can be trailing spaces in the unit string). + * The converted value is stored in *base_value. + * It's caller's responsibility to round off the converted value as necessary + * and check for out-of-range. * * Returns true on success, false if the input unit is not recognized. */ static bool -convert_to_base_unit(int64 value, const char *unit, - int base_unit, int64 *base_value) +convert_to_base_unit(double value, const char *unit, + int base_unit, double *base_value) { + char unitstr[MAX_UNIT_LEN + 1]; + int unitlen; const unit_conversion *table; int i; + /* extract unit string to compare to table entries */ + unitlen = 0; + while (*unit != '\0' && !isspace((unsigned char) *unit) && + unitlen < MAX_UNIT_LEN) + unitstr[unitlen++] = *(unit++); + unitstr[unitlen] = '\0'; + /* allow whitespace after unit */ + while (isspace((unsigned char) *unit)) + unit++; + if (*unit != '\0') + return false; /* unit too long, or garbage after it */ + + /* now search the appropriate table */ if (base_unit & GUC_UNIT_MEMORY) table = memory_unit_conversion_table; else @@ -5643,12 +6106,21 @@ convert_to_base_unit(int64 value, const char *unit, for (i = 0; *table[i].unit; i++) { if (base_unit == table[i].base_unit && - strcmp(unit, table[i].unit) == 0) + strcmp(unitstr, table[i].unit) == 0) { - if (table[i].multiplier < 0) - *base_value = value / (-table[i].multiplier); - else - *base_value = value * table[i].multiplier; + double cvalue = value * table[i].multiplier; + + /* + * If the user gave a fractional value such as "30.1GB", round it + * off to the nearest multiple of the next smaller unit, if there + * is one. + */ + if (*table[i + 1].unit && + base_unit == table[i + 1].base_unit) + cvalue = rint(cvalue / table[i + 1].multiplier) * + table[i + 1].multiplier; + + *base_value = cvalue; return true; } } @@ -5656,14 +6128,15 @@ convert_to_base_unit(int64 value, const char *unit, } /* - * Convert a value in some base unit to a human-friendly unit. The output - * unit is chosen so that it's the greatest unit that can represent the value - * without loss. For example, if the base unit is GUC_UNIT_KB, 1024 is - * converted to 1 MB, but 1025 is represented as 1025 kB. + * Convert an integer value in some base unit to a human-friendly unit. + * + * The output unit is chosen so that it's the greatest unit that can represent + * the value without loss. For example, if the base unit is GUC_UNIT_KB, 1024 + * is converted to 1 MB, but 1025 is represented as 1025 kB. */ static void -convert_from_base_unit(int64 base_value, int base_unit, - int64 *value, const char **unit) +convert_int_from_base_unit(int64 base_value, int base_unit, + int64 *value, const char **unit) { const unit_conversion *table; int i; @@ -5680,43 +6153,137 @@ convert_from_base_unit(int64 base_value, int base_unit, if (base_unit == table[i].base_unit) { /* - * Accept the first conversion that divides the value evenly. We + * Accept the first conversion that divides the value evenly. We * assume that the conversions for each base unit are ordered from * greatest unit to the smallest! */ - if (table[i].multiplier < 0) + if (table[i].multiplier <= 1.0 || + base_value % (int64) table[i].multiplier == 0) { - *value = base_value * (-table[i].multiplier); + *value = (int64) rint(base_value / table[i].multiplier); *unit = table[i].unit; break; } - else if (base_value % table[i].multiplier == 0) - { - *value = base_value / table[i].multiplier; - *unit = table[i].unit; + } + } + + Assert(*unit != NULL); +} + +/* + * Convert a floating-point value in some base unit to a human-friendly unit. + * + * Same as above, except we have to do the math a bit differently, and + * there's a possibility that we don't find any exact divisor. + */ +static void +convert_real_from_base_unit(double base_value, int base_unit, + double *value, const char **unit) +{ + const unit_conversion *table; + int i; + + *unit = NULL; + + if (base_unit & GUC_UNIT_MEMORY) + table = memory_unit_conversion_table; + else + table = time_unit_conversion_table; + + for (i = 0; *table[i].unit; i++) + { + if (base_unit == table[i].base_unit) + { + /* + * Accept the first conversion that divides the value evenly; or + * if there is none, use the smallest (last) target unit. + * + * What we actually care about here is whether snprintf with "%g" + * will print the value as an integer, so the obvious test of + * "*value == rint(*value)" is too strict; roundoff error might + * make us choose an unreasonably small unit. As a compromise, + * accept a divisor that is within 1e-8 of producing an integer. + */ + *value = base_value / table[i].multiplier; + *unit = table[i].unit; + if (*value > 0 && + fabs((rint(*value) / *value) - 1.0) <= 1e-8) break; - } } } Assert(*unit != NULL); } +/* + * Return the name of a GUC's base unit (e.g. "ms") given its flags. + * Return NULL if the GUC is unitless. + */ +static const char * +get_config_unit_name(int flags) +{ + switch (flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)) + { + case 0: + return NULL; /* GUC has no units */ + case GUC_UNIT_BYTE: + return "B"; + case GUC_UNIT_KB: + return "kB"; + case GUC_UNIT_MB: + return "MB"; + case GUC_UNIT_BLOCKS: + { + static char bbuf[8]; + + /* initialize if first time through */ + if (bbuf[0] == '\0') + snprintf(bbuf, sizeof(bbuf), "%dkB", BLCKSZ / 1024); + return bbuf; + } + case GUC_UNIT_XBLOCKS: + { + static char xbuf[8]; + + /* initialize if first time through */ + if (xbuf[0] == '\0') + snprintf(xbuf, sizeof(xbuf), "%dkB", XLOG_BLCKSZ / 1024); + return xbuf; + } + case GUC_UNIT_MS: + return "ms"; + case GUC_UNIT_S: + return "s"; + case GUC_UNIT_MIN: + return "min"; + default: + elog(ERROR, "unrecognized GUC units value: %d", + flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)); + return NULL; + } +} + /* * Try to parse value as an integer. The accepted formats are the - * usual decimal, octal, or hexadecimal formats, optionally followed by - * a unit name if "flags" indicates a unit is allowed. + * usual decimal, octal, or hexadecimal formats, as well as floating-point + * formats (which will be rounded to integer after any units conversion). + * Optionally, the value can be followed by a unit name if "flags" indicates + * a unit is allowed. * * If the string parses okay, return true, else false. * If okay and result is not NULL, return the value in *result. * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable - * HINT message, or NULL if no hint provided. + * HINT message, or NULL if no hint provided. */ bool parse_int(const char *value, int *result, int flags, const char **hintmsg) { - int64 val; + /* + * We assume here that double is wide enough to represent any integer + * value with adequate precision. + */ + double val; char *endptr; /* To suppress compiler warnings, always set output params */ @@ -5725,47 +6292,42 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg) if (hintmsg) *hintmsg = NULL; - /* We assume here that int64 is at least as wide as long */ + /* + * Try to parse as an integer (allowing octal or hex input). If the + * conversion stops at a decimal point or 'e', or overflows, re-parse as + * float. This should work fine as long as we have no unit names starting + * with 'e'. If we ever do, the test could be extended to check for a + * sign or digit after 'e', but for now that's unnecessary. + */ errno = 0; val = strtol(value, &endptr, 0); - - if (endptr == value) - return false; /* no HINT for integer syntax error */ - - if (errno == ERANGE || val != (int64) ((int32) val)) + if (*endptr == '.' || *endptr == 'e' || *endptr == 'E' || + errno == ERANGE) { - if (hintmsg) - *hintmsg = gettext_noop("Value exceeds integer range."); - return false; + errno = 0; + val = strtod(value, &endptr); } - /* allow whitespace between integer and unit */ + if (endptr == value || errno == ERANGE) + return false; /* no HINT for these cases */ + + /* reject NaN (infinities will fail range check below) */ + if (isnan(val)) + return false; /* treat same as syntax error; no HINT */ + + /* allow whitespace between number and unit */ while (isspace((unsigned char) *endptr)) endptr++; /* Handle possible unit */ if (*endptr != '\0') { - char unit[MAX_UNIT_LEN + 1]; - int unitlen; - bool converted = false; - if ((flags & GUC_UNIT) == 0) return false; /* this setting does not accept a unit */ - unitlen = 0; - while (*endptr != '\0' && !isspace((unsigned char) *endptr) && - unitlen < MAX_UNIT_LEN) - unit[unitlen++] = *(endptr++); - unit[unitlen] = '\0'; - /* allow whitespace after unit */ - while (isspace((unsigned char) *endptr)) - endptr++; - - if (*endptr == '\0') - converted = convert_to_base_unit(val, unit, (flags & GUC_UNIT), - &val); - if (!converted) + if (!convert_to_base_unit(val, + endptr, (flags & GUC_UNIT), + &val)) { /* invalid unit, or garbage after the unit; set hint and fail. */ if (hintmsg) @@ -5777,14 +6339,16 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg) } return false; } + } - /* Check for overflow due to units conversion */ - if (val != (int64) ((int32) val)) - { - if (hintmsg) - *hintmsg = gettext_noop("Value exceeds integer range."); - return false; - } + /* Round to int, then check for overflow */ + val = rint(val); + + if (val > INT_MAX || val < INT_MIN) + { + if (hintmsg) + *hintmsg = gettext_noop("Value exceeds integer range."); + return false; } if (result) @@ -5792,32 +6356,63 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg) return true; } - - /* * Try to parse value as a floating point number in the usual format. + * Optionally, the value can be followed by a unit name if "flags" indicates + * a unit is allowed. + * * If the string parses okay, return true, else false. * If okay and result is not NULL, return the value in *result. + * If not okay and hintmsg is not NULL, *hintmsg is set to a suitable + * HINT message, or NULL if no hint provided. */ bool -parse_real(const char *value, double *result) +parse_real(const char *value, double *result, int flags, const char **hintmsg) { double val; char *endptr; + /* To suppress compiler warnings, always set output params */ if (result) - *result = 0; /* suppress compiler warning */ + *result = 0; + if (hintmsg) + *hintmsg = NULL; errno = 0; val = strtod(value, &endptr); + if (endptr == value || errno == ERANGE) - return false; + return false; /* no HINT for these cases */ + + /* reject NaN (infinities will fail range checks later) */ + if (isnan(val)) + return false; /* treat same as syntax error; no HINT */ - /* allow whitespace after number */ + /* allow whitespace between number and unit */ while (isspace((unsigned char) *endptr)) endptr++; + + /* Handle possible unit */ if (*endptr != '\0') - return false; + { + if ((flags & GUC_UNIT) == 0) + return false; /* this setting does not accept a unit */ + + if (!convert_to_base_unit(val, + endptr, (flags & GUC_UNIT), + &val)) + { + /* invalid unit, or garbage after the unit; set hint and fail. */ + if (hintmsg) + { + if (flags & GUC_UNIT_MEMORY) + *hintmsg = memory_units_hint; + else + *hintmsg = time_units_hint; + } + return false; + } + } if (result) *result = val; @@ -5984,10 +6579,15 @@ parse_and_validate_value(struct config_generic *record, if (newval->intval < conf->min || newval->intval > conf->max) { + const char *unit = get_config_unit_name(conf->gen.flags); + ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("%d is outside the valid range for parameter \"%s\" (%d .. %d)", - newval->intval, name, + errmsg("%d%s%s is outside the valid range for parameter \"%s\" (%d .. %d)", + newval->intval, + unit ? " " : "", + unit ? unit : "", + name, conf->min, conf->max))); return false; } @@ -6000,22 +6600,30 @@ parse_and_validate_value(struct config_generic *record, case PGC_REAL: { struct config_real *conf = (struct config_real *) record; + const char *hintmsg; - if (!parse_real(value, &newval->realval)) + if (!parse_real(value, &newval->realval, + conf->gen.flags, &hintmsg)) { ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("parameter \"%s\" requires a numeric value", - name))); + errmsg("invalid value for parameter \"%s\": \"%s\"", + name, value), + hintmsg ? errhint("%s", _(hintmsg)) : 0)); return false; } if (newval->realval < conf->min || newval->realval > conf->max) { + const char *unit = get_config_unit_name(conf->gen.flags); + ereport(elevel, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("%g is outside the valid range for parameter \"%s\" (%g .. %g)", - newval->realval, name, + errmsg("%g%s%s is outside the valid range for parameter \"%s\" (%g .. %g)", + newval->realval, + unit ? " " : "", + unit ? unit : "", + name, conf->min, conf->max))); return false; } @@ -6244,7 +6852,8 @@ set_config_option(const char *name, const char *value, name))); return 0; } - /* FALL THRU to process the same as PGC_BACKEND */ + /* fall through to process the same as PGC_BACKEND */ + /* FALLTHROUGH */ case PGC_BACKEND: if (context == PGC_SIGHUP) { @@ -6905,15 +7514,15 @@ SetConfigOption(const char *name, const char *value, * this cannot be distinguished from a string variable with a NULL value!), * otherwise throw an ereport and don't return. * - * If restrict_superuser is true, we also enforce that only superusers can - * see GUC_SUPERUSER_ONLY variables. This should only be passed as true - * in user-driven calls. + * If restrict_privileged is true, we also enforce that only superusers and + * members of the pg_read_all_settings role can see GUC_SUPERUSER_ONLY + * variables. This should only be passed as true in user-driven calls. * * The string is *not* allocated for modification and is really only * valid until the next call to configuration related functions. */ const char * -GetConfigOption(const char *name, bool missing_ok, bool restrict_superuser) +GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged) { struct config_generic *record; static char buffer[256]; @@ -6928,7 +7537,7 @@ GetConfigOption(const char *name, bool missing_ok, bool restrict_superuser) errmsg("unrecognized configuration parameter \"%s\"", name))); } - if (restrict_superuser && + if (restrict_privileged && (record->flags & GUC_SUPERUSER_ONLY) && !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) ereport(ERROR, @@ -7242,40 +7851,37 @@ replace_auto_config_value(ConfigVariable **head_p, ConfigVariable **tail_p, const char *name, const char *value) { ConfigVariable *item, + *next, *prev = NULL; - /* Search the list for an existing match (we assume there's only one) */ - for (item = *head_p; item != NULL; item = item->next) + /* + * Remove any existing match(es) for "name". Normally there'd be at most + * one, but if external tools have modified the config file, there could + * be more. + */ + for (item = *head_p; item != NULL; item = next) { - if (strcmp(item->name, name) == 0) + next = item->next; + if (guc_name_compare(item->name, name) == 0) { - /* found a match, replace it */ - pfree(item->value); - if (value != NULL) - { - /* update the parameter value */ - item->value = pstrdup(value); - } + /* found a match, delete it */ + if (prev) + prev->next = next; else - { - /* delete the configuration parameter from list */ - if (*head_p == item) - *head_p = item->next; - else - prev->next = item->next; - if (*tail_p == item) - *tail_p = prev; + *head_p = next; + if (next == NULL) + *tail_p = prev; - pfree(item->name); - pfree(item->filename); - pfree(item); - } - return; + pfree(item->name); + pfree(item->value); + pfree(item->filename); + pfree(item); } - prev = item; + else + prev = item; } - /* Not there; no work if we're trying to delete it */ + /* Done if we're trying to delete it */ if (value == NULL) return; @@ -8159,7 +8765,7 @@ GetPGVariableResultDesc(const char *name) if (guc_name_compare(name, "all") == 0) { /* need a tuple descriptor representing three TEXT columns */ - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", @@ -8175,7 +8781,7 @@ GetPGVariableResultDesc(const char *name) (void) GetConfigOptionByName(name, &varname, false); /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname, TEXTOID, -1, 0); } @@ -8198,12 +8804,12 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest) value = GetConfigOptionByName(name, &varname, false); /* need a tuple descriptor representing a single TEXT column */ - tupdesc = CreateTemplateTupleDesc(1, false); + tupdesc = CreateTemplateTupleDesc(1); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname, TEXTOID, -1, 0); /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc); + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); /* Send it */ do_text_output_oneline(tstate, value); @@ -8217,7 +8823,6 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest) static void ShowAllGUCConfig(DestReceiver *dest) { - bool am_superuser = superuser(); int i; TupOutputState *tstate; TupleDesc tupdesc; @@ -8225,7 +8830,7 @@ ShowAllGUCConfig(DestReceiver *dest) bool isnull[3] = {false, false, false}; /* need a tuple descriptor representing three TEXT columns */ - tupdesc = CreateTemplateTupleDesc(3, false); + tupdesc = CreateTemplateTupleDesc(3); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting", @@ -8233,49 +8838,148 @@ ShowAllGUCConfig(DestReceiver *dest) TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description", TEXTOID, -1, 0); - /* prepare for projection of tuples */ - tstate = begin_tup_output_tupdesc(dest, tupdesc); + /* prepare for projection of tuples */ + tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual); + + for (i = 0; i < num_guc_variables; i++) + { + struct config_generic *conf = guc_variables[i]; + char *setting; + + if ((conf->flags & GUC_NO_SHOW_ALL) || + ((conf->flags & GUC_SUPERUSER_ONLY) && + !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS))) + continue; + + /* assign to the values array */ + values[0] = PointerGetDatum(cstring_to_text(conf->name)); + + setting = _ShowOption(conf, true); + if (setting) + { + values[1] = PointerGetDatum(cstring_to_text(setting)); + isnull[1] = false; + } + else + { + values[1] = PointerGetDatum(NULL); + isnull[1] = true; + } + + values[2] = PointerGetDatum(cstring_to_text(conf->short_desc)); + + /* send it to dest */ + do_tup_output(tstate, values, isnull); + + /* clean up */ + pfree(DatumGetPointer(values[0])); + if (setting) + { + pfree(setting); + pfree(DatumGetPointer(values[1])); + } + pfree(DatumGetPointer(values[2])); + } + + end_tup_output(tstate); +} + +/* + * Returns an array of modified GUC options to show in EXPLAIN. Only options + * related to query planning (marked with GUC_EXPLAIN), with values different + * from built-in defaults. + */ +struct config_generic ** +get_explain_guc_options(int *num) +{ + int i; + struct config_generic **result; + + *num = 0; + + /* + * Allocate enough space to fit all GUC_EXPLAIN options. We may not need + * all the space, but there are fairly few such options so we don't waste + * a lot of memory. + */ + result = palloc(sizeof(struct config_generic *) * num_guc_explain_variables); + + for (i = 0; i < num_guc_variables; i++) + { + bool modified; + struct config_generic *conf = guc_variables[i]; + + /* return only options visible to the user */ + if ((conf->flags & GUC_NO_SHOW_ALL) || + ((conf->flags & GUC_SUPERUSER_ONLY) && + !is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS))) + continue; + + /* only parameters explicitly marked for inclusion in explain */ + if (!(conf->flags & GUC_EXPLAIN)) + continue; + + /* return only options that were modified (w.r.t. config file) */ + modified = false; + + switch (conf->vartype) + { + case PGC_BOOL: + { + struct config_bool *lconf = (struct config_bool *) conf; + + modified = (lconf->boot_val != *(lconf->variable)); + } + break; + + case PGC_INT: + { + struct config_int *lconf = (struct config_int *) conf; + + modified = (lconf->boot_val != *(lconf->variable)); + } + break; + + case PGC_REAL: + { + struct config_real *lconf = (struct config_real *) conf; + + modified = (lconf->boot_val != *(lconf->variable)); + } + break; - for (i = 0; i < num_guc_variables; i++) - { - struct config_generic *conf = guc_variables[i]; - char *setting; + case PGC_STRING: + { + struct config_string *lconf = (struct config_string *) conf; - if ((conf->flags & GUC_NO_SHOW_ALL) || - ((conf->flags & GUC_SUPERUSER_ONLY) && !am_superuser)) - continue; + modified = (strcmp(lconf->boot_val, *(lconf->variable)) != 0); + } + break; - /* assign to the values array */ - values[0] = PointerGetDatum(cstring_to_text(conf->name)); + case PGC_ENUM: + { + struct config_enum *lconf = (struct config_enum *) conf; - setting = _ShowOption(conf, true); - if (setting) - { - values[1] = PointerGetDatum(cstring_to_text(setting)); - isnull[1] = false; - } - else - { - values[1] = PointerGetDatum(NULL); - isnull[1] = true; + modified = (lconf->boot_val != *(lconf->variable)); + } + break; + + default: + elog(ERROR, "unexpected GUC type: %d", conf->vartype); } - values[2] = PointerGetDatum(cstring_to_text(conf->short_desc)); + /* skip GUC variables that match the built-in default */ + if (!modified) + continue; - /* send it to dest */ - do_tup_output(tstate, values, isnull); + /* assign to the values array */ + result[*num] = conf; + *num = *num + 1; - /* clean up */ - pfree(DatumGetPointer(values[0])); - if (setting) - { - pfree(setting); - pfree(DatumGetPointer(values[1])); - } - pfree(DatumGetPointer(values[2])); + Assert(*num <= num_guc_explain_variables); } - end_tup_output(tstate); + return result; } /* @@ -8346,61 +9050,20 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) /* name */ values[0] = conf->name; - /* setting : use _ShowOption in order to avoid duplicating the logic */ + /* setting: use _ShowOption in order to avoid duplicating the logic */ values[1] = _ShowOption(conf, false); - /* unit */ - if (conf->vartype == PGC_INT) - { - switch (conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)) - { - case GUC_UNIT_BYTE: - values[2] = "B"; - break; - case GUC_UNIT_KB: - values[2] = "kB"; - break; - case GUC_UNIT_MB: - values[2] = "MB"; - break; - case GUC_UNIT_BLOCKS: - snprintf(buffer, sizeof(buffer), "%dkB", BLCKSZ / 1024); - values[2] = pstrdup(buffer); - break; - case GUC_UNIT_XBLOCKS: - snprintf(buffer, sizeof(buffer), "%dkB", XLOG_BLCKSZ / 1024); - values[2] = pstrdup(buffer); - break; - case GUC_UNIT_MS: - values[2] = "ms"; - break; - case GUC_UNIT_S: - values[2] = "s"; - break; - case GUC_UNIT_MIN: - values[2] = "min"; - break; - case 0: - values[2] = NULL; - break; - default: - elog(ERROR, "unrecognized GUC units value: %d", - conf->flags & (GUC_UNIT_MEMORY | GUC_UNIT_TIME)); - values[2] = NULL; - break; - } - } - else - values[2] = NULL; + /* unit, if any (NULL is fine) */ + values[2] = get_config_unit_name(conf->flags); /* group */ - values[3] = config_group_names[conf->group]; + values[3] = _(config_group_names[conf->group]); /* short_desc */ - values[4] = conf->short_desc; + values[4] = _(conf->short_desc); /* extra_desc */ - values[5] = conf->long_desc; + values[5] = _(conf->long_desc); /* context */ values[6] = GucContext_Names[conf->context]; @@ -8568,9 +9231,10 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow) /* * If the setting came from a config file, set the source location. For * security reasons, we don't show source file/line number for - * non-superusers. + * insufficiently-privileged users. */ - if (conf->source == PGC_S_FILE && superuser()) + if (conf->source == PGC_S_FILE && + is_member_of_role(GetUserId(), DEFAULT_ROLE_READ_ALL_SETTINGS)) { values[14] = conf->sourcefile; snprintf(buffer, sizeof(buffer), "%d", conf->sourceline); @@ -8665,7 +9329,7 @@ show_all_settings(PG_FUNCTION_ARGS) * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns * of the appropriate types */ - tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false); + tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting", @@ -8805,7 +9469,7 @@ show_all_file_settings(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(per_query_ctx); /* Build a tuple descriptor for our result type */ - tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS, false); + tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "sourcefile", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "sourceline", @@ -8919,10 +9583,9 @@ _ShowOption(struct config_generic *record, bool use_units) const char *unit; if (use_units && result > 0 && (record->flags & GUC_UNIT)) - { - convert_from_base_unit(result, record->flags & GUC_UNIT, - &result, &unit); - } + convert_int_from_base_unit(result, + record->flags & GUC_UNIT, + &result, &unit); else unit = ""; @@ -8941,8 +9604,18 @@ _ShowOption(struct config_generic *record, bool use_units) val = conf->show_hook(); else { - snprintf(buffer, sizeof(buffer), "%g", - *conf->variable); + double result = *conf->variable; + const char *unit; + + if (use_units && result > 0 && (record->flags & GUC_UNIT)) + convert_real_from_base_unit(result, + record->flags & GUC_UNIT, + &result, &unit); + else + unit = ""; + + snprintf(buffer, sizeof(buffer), "%g%s", + result, unit); val = buffer; } } @@ -9384,20 +10057,15 @@ do_serialize(char **destptr, Size *maxbytes, const char *fmt,...) n = vsnprintf(*destptr, *maxbytes, fmt, vargs); va_end(vargs); - /* - * Cater to portability hazards in the vsnprintf() return value just like - * appendPQExpBufferVA() does. Note that this requires an extra byte of - * slack at the end of the buffer. Since serialize_variable() ends with a - * do_serialize_binary() rather than a do_serialize(), we'll always have - * that slack; estimate_variable_size() need not add a byte for it. - */ - if (n < 0 || n >= *maxbytes - 1) + if (n < 0) { - if (n < 0 && errno != 0 && errno != ENOMEM) - /* Shouldn't happen. Better show errno description. */ - elog(ERROR, "vsnprintf failed: %m"); - else - elog(ERROR, "not enough space to serialize GUC state"); + /* Shouldn't happen. Better show errno description. */ + elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt); + } + if (n >= *maxbytes) + { + /* This shouldn't happen either, really. */ + elog(ERROR, "not enough space to serialize GUC state"); } /* Shift the destptr ahead of the null terminator */ @@ -9595,6 +10263,8 @@ RestoreGUCState(void *gucstate) if (varsourcefile[0]) read_gucstate_binary(&srcptr, srcend, &varsourceline, sizeof(varsourceline)); + else + varsourceline = 0; read_gucstate_binary(&srcptr, srcend, &varsource, sizeof(varsource)); read_gucstate_binary(&srcptr, srcend, @@ -10585,11 +11255,28 @@ show_tcp_keepalives_count(void) return nbuf; } +static void +assign_tcp_user_timeout(int newval, void *extra) +{ + /* See comments in assign_tcp_keepalives_idle */ + (void) pq_settcpusertimeout(newval, MyProcPort); +} + +static const char * +show_tcp_user_timeout(void) +{ + /* See comments in assign_tcp_keepalives_idle */ + static char nbuf[16]; + + snprintf(nbuf, sizeof(nbuf), "%d", pq_gettcpusertimeout(MyProcPort)); + return nbuf; +} + static bool check_maxconnections(int *newval, void **extra, GucSource source) { if (*newval + autovacuum_max_workers + 1 + - max_worker_processes > MAX_BACKENDS) + max_worker_processes + max_wal_senders > MAX_BACKENDS) return false; return true; } @@ -10597,7 +11284,17 @@ check_maxconnections(int *newval, void **extra, GucSource source) static bool check_autovacuum_max_workers(int *newval, void **extra, GucSource source) { - if (MaxConnections + *newval + 1 + max_worker_processes > MAX_BACKENDS) + if (MaxConnections + *newval + 1 + + max_worker_processes + max_wal_senders > MAX_BACKENDS) + return false; + return true; +} + +static bool +check_max_wal_senders(int *newval, void **extra, GucSource source) +{ + if (MaxConnections + autovacuum_max_workers + 1 + + max_worker_processes + *newval > MAX_BACKENDS) return false; return true; } @@ -10628,7 +11325,8 @@ check_autovacuum_work_mem(int *newval, void **extra, GucSource source) static bool check_max_worker_processes(int *newval, void **extra, GucSource source) { - if (MaxConnections + autovacuum_max_workers + 1 + *newval > MAX_BACKENDS) + if (MaxConnections + autovacuum_max_workers + 1 + + *newval + max_wal_senders > MAX_BACKENDS) return false; return true; } @@ -10651,6 +11349,11 @@ check_effective_io_concurrency(int *newval, void **extra, GucSource source) else return false; #else + if (*newval != 0) + { + GUC_check_errdetail("effective_io_concurrency must be set to 0 on platforms that lack posix_fadvise()."); + return false; + } return true; #endif /* USE_PREFETCH */ } @@ -10696,13 +11399,7 @@ static bool check_application_name(char **newval, void **extra, GucSource source) { /* Only allow clean ASCII chars in the application name */ - char *p; - - for (p = *newval; *p; p++) - { - if (*p < 32 || *p > 126) - *p = '?'; - } + pg_clean_ascii(*newval); return true; } @@ -10718,13 +11415,7 @@ static bool check_cluster_name(char **newval, void **extra, GucSource source) { /* Only allow clean ASCII chars in the cluster name */ - char *p; - - for (p = *newval; *p; p++) - { - if (*p < 32 || *p > 126) - *p = '?'; - } + pg_clean_ascii(*newval); return true; } @@ -10756,4 +11447,301 @@ show_data_directory_mode(void) return buf; } +static bool +check_recovery_target_timeline(char **newval, void **extra, GucSource source) +{ + RecoveryTargetTimeLineGoal rttg; + RecoveryTargetTimeLineGoal *myextra; + + if (strcmp(*newval, "current") == 0) + rttg = RECOVERY_TARGET_TIMELINE_CONTROLFILE; + else if (strcmp(*newval, "latest") == 0) + rttg = RECOVERY_TARGET_TIMELINE_LATEST; + else + { + rttg = RECOVERY_TARGET_TIMELINE_NUMERIC; + + errno = 0; + strtoul(*newval, NULL, 0); + if (errno == EINVAL || errno == ERANGE) + { + GUC_check_errdetail("recovery_target_timeline is not a valid number."); + return false; + } + } + + myextra = (RecoveryTargetTimeLineGoal *) guc_malloc(ERROR, sizeof(RecoveryTargetTimeLineGoal)); + *myextra = rttg; + *extra = (void *) myextra; + + return true; +} + +static void +assign_recovery_target_timeline(const char *newval, void *extra) +{ + recoveryTargetTimeLineGoal = *((RecoveryTargetTimeLineGoal *) extra); + if (recoveryTargetTimeLineGoal == RECOVERY_TARGET_TIMELINE_NUMERIC) + recoveryTargetTLIRequested = (TimeLineID) strtoul(newval, NULL, 0); + else + recoveryTargetTLIRequested = 0; +} + +/* + * Recovery target settings: Only one of the several recovery_target* settings + * may be set. Setting a second one results in an error. The global variable + * recoveryTarget tracks which kind of recovery target was chosen. Other + * variables store the actual target value (for example a string or a xid). + * The assign functions of the parameters check whether a competing parameter + * was already set. But we want to allow setting the same parameter multiple + * times. We also want to allow unsetting a parameter and setting a different + * one, so we unset recoveryTarget when the parameter is set to an empty + * string. + */ + +static void +pg_attribute_noreturn() +error_multiple_recovery_targets(void) +{ + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("multiple recovery targets specified"), + errdetail("At most one of recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid may be set."))); +} + +static bool +check_recovery_target(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "immediate") != 0 && strcmp(*newval, "") != 0) + { + GUC_check_errdetail("The only allowed value is \"immediate\"."); + return false; + } + return true; +} + +static void +assign_recovery_target(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_IMMEDIATE) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + recoveryTarget = RECOVERY_TARGET_IMMEDIATE; + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +static bool +check_recovery_target_xid(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + TransactionId xid; + TransactionId *myextra; + + errno = 0; + xid = (TransactionId) strtoul(*newval, NULL, 0); + if (errno == EINVAL || errno == ERANGE) + return false; + + myextra = (TransactionId *) guc_malloc(ERROR, sizeof(TransactionId)); + *myextra = xid; + *extra = (void *) myextra; + } + return true; +} + +static void +assign_recovery_target_xid(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_XID) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_XID; + recoveryTargetXid = *((TransactionId *) extra); + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +/* + * The interpretation of the recovery_target_time string can depend on the + * time zone setting, so we need to wait until after all GUC processing is + * done before we can do the final parsing of the string. This check function + * only does a parsing pass to catch syntax errors, but we store the string + * and parse it again when we need to use it. + */ +static bool +check_recovery_target_time(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + /* reject some special values */ + if (strcmp(*newval, "now") == 0 || + strcmp(*newval, "today") == 0 || + strcmp(*newval, "tomorrow") == 0 || + strcmp(*newval, "yesterday") == 0) + { + return false; + } + + /* + * parse timestamp value (see also timestamptz_in()) + */ + { + char *str = *newval; + fsec_t fsec; + struct pg_tm tt, + *tm = &tt; + int tz; + int dtype; + int nf; + int dterr; + char *field[MAXDATEFIELDS]; + int ftype[MAXDATEFIELDS]; + char workbuf[MAXDATELEN + MAXDATEFIELDS]; + TimestampTz timestamp; + + dterr = ParseDateTime(str, workbuf, sizeof(workbuf), + field, ftype, MAXDATEFIELDS, &nf); + if (dterr == 0) + dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tz); + if (dterr != 0) + return false; + if (dtype != DTK_DATE) + return false; + + if (tm2timestamp(tm, fsec, &tz, ×tamp) != 0) + { + GUC_check_errdetail("timestamp out of range: \"%s\"", str); + return false; + } + } + } + return true; +} + +static void +assign_recovery_target_time(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_TIME) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + recoveryTarget = RECOVERY_TARGET_TIME; + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +static bool +check_recovery_target_name(char **newval, void **extra, GucSource source) +{ + /* Use the value of newval directly */ + if (strlen(*newval) >= MAXFNAMELEN) + { + GUC_check_errdetail("%s is too long (maximum %d characters).", + "recovery_target_name", MAXFNAMELEN - 1); + return false; + } + return true; +} + +static void +assign_recovery_target_name(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_NAME) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_NAME; + recoveryTargetName = newval; + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +static bool +check_recovery_target_lsn(char **newval, void **extra, GucSource source) +{ + if (strcmp(*newval, "") != 0) + { + XLogRecPtr lsn; + XLogRecPtr *myextra; + bool have_error = false; + + lsn = pg_lsn_in_internal(*newval, &have_error); + if (have_error) + return false; + + myextra = (XLogRecPtr *) guc_malloc(ERROR, sizeof(XLogRecPtr)); + *myextra = lsn; + *extra = (void *) myextra; + } + return true; +} + +static void +assign_recovery_target_lsn(const char *newval, void *extra) +{ + if (recoveryTarget != RECOVERY_TARGET_UNSET && + recoveryTarget != RECOVERY_TARGET_LSN) + error_multiple_recovery_targets(); + + if (newval && strcmp(newval, "") != 0) + { + recoveryTarget = RECOVERY_TARGET_LSN; + recoveryTargetLSN = *((XLogRecPtr *) extra); + } + else + recoveryTarget = RECOVERY_TARGET_UNSET; +} + +static bool +check_primary_slot_name(char **newval, void **extra, GucSource source) +{ + if (*newval && strcmp(*newval, "") != 0 && + !ReplicationSlotValidateName(*newval, WARNING)) + return false; + + return true; +} + +static bool +check_default_with_oids(bool *newval, void **extra, GucSource source) +{ + if (*newval) + { + /* check the GUC's definition for an explanation */ + GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED); + GUC_check_errmsg("tables declared WITH OIDS are not supported"); + + return false; + } + + return true; +} + +static bool +check_online_update_support(char **newval, void **extra, GucSource source) +{ + if (*newval && **newval != '\0') + { + if (shared_memory_type == SHMEM_TYPE_MMAP) + { + GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED); + GUC_check_errmsg("Online upgrade is not possible with shared_memory_type=mmap, please use sysv or posix"); + return false; + } + } + return true; +} + #include "guc-file.c" diff --git a/src/backend/utils/misc/help_config.c b/src/backend/utils/misc/help_config.c index 25f5c828046..29229ef2912 100644 --- a/src/backend/utils/misc/help_config.c +++ b/src/backend/utils/misc/help_config.c @@ -7,7 +7,7 @@ * or GUC_DISALLOW_IN_FILE are not displayed, unless the user specifically * requests that variable by name * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/misc/help_config.c @@ -16,7 +16,6 @@ */ #include "postgres.h" -#include #include #include diff --git a/src/backend/utils/misc/pg_config.c b/src/backend/utils/misc/pg_config.c index aa434bc3abb..2d178391ab5 100644 --- a/src/backend/utils/misc/pg_config.c +++ b/src/backend/utils/misc/pg_config.c @@ -3,7 +3,7 @@ * pg_config.c * Expose same output as pg_config except as an SRF * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c index 8ab7d1337fa..b42921800b7 100644 --- a/src/backend/utils/misc/pg_controldata.c +++ b/src/backend/utils/misc/pg_controldata.c @@ -5,7 +5,7 @@ * Routines to expose the contents of the control data file via * a set of SQL functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -15,13 +15,15 @@ #include "postgres.h" -#include "funcapi.h" -#include "miscadmin.h" #include "access/htup_details.h" +#include "access/transam.h" #include "access/xlog_internal.h" +#include "access/xlog.h" #include "catalog/pg_control.h" #include "catalog/pg_type.h" #include "common/controldata_utils.h" +#include "funcapi.h" +#include "miscadmin.h" #include "utils/builtins.h" #include "utils/pg_lsn.h" #include "utils/timestamp.h" @@ -40,7 +42,7 @@ pg_control_system(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(4, false); + tupdesc = CreateTemplateTupleDesc(4); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_control_version", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catalog_version_no", @@ -52,7 +54,7 @@ pg_control_system(PG_FUNCTION_ARGS) tupdesc = BlessTupleDesc(tupdesc); /* read the control file */ - ControlFile = get_controlfile(DataDir, NULL, &crc_ok); + ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) ereport(ERROR, (errmsg("calculated CRC checksum does not match value stored in file"))); @@ -90,7 +92,7 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(18, false); + tupdesc = CreateTemplateTupleDesc(18); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn", LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn", @@ -130,7 +132,7 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) tupdesc = BlessTupleDesc(tupdesc); /* Read the control file. */ - ControlFile = get_controlfile(DataDir, NULL, &crc_ok); + ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) ereport(ERROR, (errmsg("calculated CRC checksum does not match value stored in file"))); @@ -163,8 +165,8 @@ pg_control_checkpoint(PG_FUNCTION_ARGS) nulls[5] = false; values[6] = CStringGetTextDatum(psprintf("%u:%u", - ControlFile->checkPointCopy.nextXidEpoch, - ControlFile->checkPointCopy.nextXid)); + EpochFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid), + XidFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid))); nulls[6] = false; values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid); @@ -220,7 +222,7 @@ pg_control_recovery(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(5, false); + tupdesc = CreateTemplateTupleDesc(5); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn", LSNOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline", @@ -234,7 +236,7 @@ pg_control_recovery(PG_FUNCTION_ARGS) tupdesc = BlessTupleDesc(tupdesc); /* read the control file */ - ControlFile = get_controlfile(DataDir, NULL, &crc_ok); + ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) ereport(ERROR, (errmsg("calculated CRC checksum does not match value stored in file"))); @@ -273,7 +275,7 @@ pg_control_init(PG_FUNCTION_ARGS) * Construct a tuple descriptor for the result row. This must match this * function's pg_proc entry! */ - tupdesc = CreateTemplateTupleDesc(12, false); + tupdesc = CreateTemplateTupleDesc(12); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment", INT4OID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size", @@ -301,7 +303,7 @@ pg_control_init(PG_FUNCTION_ARGS) tupdesc = BlessTupleDesc(tupdesc); /* read the control file */ - ControlFile = get_controlfile(DataDir, NULL, &crc_ok); + ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) ereport(ERROR, (errmsg("calculated CRC checksum does not match value stored in file"))); diff --git a/src/backend/utils/misc/pg_rusage.c b/src/backend/utils/misc/pg_rusage.c index f135f1b134c..fc4ef1aeda2 100644 --- a/src/backend/utils/misc/pg_rusage.c +++ b/src/backend/utils/misc/pg_rusage.c @@ -4,7 +4,7 @@ * Resource usage measurement support routines. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 66d09388278..0fc23e3a612 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -73,8 +73,8 @@ #bonjour_name = '' # defaults to the computer name # (change requires restart) -# - TCP Keepalives - -# see "man 7 tcp" for details +# - TCP settings - +# see "man tcp" for details #tcp_keepalives_idle = 0 # TCP_KEEPIDLE, in seconds; # 0 selects the system default @@ -82,6 +82,8 @@ # 0 selects the system default #tcp_keepalives_count = 0 # TCP_KEEPCNT; # 0 selects the system default +#tcp_user_timeout = 0 # TCP_USER_TIMEOUT, in milliseconds; + # 0 selects the system default # - Authentication - @@ -103,6 +105,8 @@ #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers #ssl_prefer_server_ciphers = on #ssl_ecdh_curve = 'prime256v1' +#ssl_min_protocol_version = 'TLSv1' +#ssl_max_protocol_version = '' #ssl_dh_params_file = '' #ssl_passphrase_command = '' #ssl_passphrase_command_supports_reload = off @@ -127,13 +131,18 @@ #maintenance_work_mem = 64MB # min 1MB #autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem #max_stack_depth = 2MB # min 100kB +#shared_memory_type = mmap # the default is the first option + # supported by the operating system: + # mmap + # sysv + # windows + # (change requires restart) #dynamic_shared_memory_type = posix # the default is the first option # supported by the operating system: # posix # sysv # windows # mmap - # use none to disable dynamic shared memory # (change requires restart) # - Disk - @@ -141,14 +150,14 @@ #temp_file_limit = -1 # limits per-process temp file space # in kB, or -1 for no limit -# - Kernel Resource - +# - Kernel Resources - #max_files_per_process = 1000 # min 25 # (change requires restart) # - Cost-Based Vacuum Delay - -#vacuum_cost_delay = 0 # 0-100 milliseconds +#vacuum_cost_delay = 0 # 0-100 milliseconds (0 disables) #vacuum_cost_page_hit = 1 # 0-10000 credits #vacuum_cost_page_miss = 10 # 0-10000 credits #vacuum_cost_page_dirty = 20 # 0-10000 credits @@ -199,6 +208,8 @@ #wal_compression = off # enable compression of full-page writes #wal_log_hints = off # also do full page writes of non-critical updates # (change requires restart) +#wal_init_zero = on # zero-fill new WAL files +#wal_recycle = on # recycle WAL files #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers # (change requires restart) #wal_writer_delay = 200ms # 1-10000 milliseconds @@ -227,6 +238,42 @@ #archive_timeout = 0 # force a logfile segment switch after this # number of seconds; 0 disables +# - Archive Recovery - + +# These are only used in recovery mode. + +#restore_command = '' # command to use to restore an archived logfile segment + # placeholders: %p = path of file to restore + # %f = file name only + # e.g. 'cp /mnt/server/archivedir/%f %p' + # (change requires restart) +#archive_cleanup_command = '' # command to execute at every restartpoint +#recovery_end_command = '' # command to execute at completion of recovery + +# - Recovery Target - + +# Set these only when performing a targeted recovery. + +#recovery_target = '' # 'immediate' to end recovery as soon as a + # consistent state is reached + # (change requires restart) +#recovery_target_name = '' # the named restore point to which recovery will proceed + # (change requires restart) +#recovery_target_time = '' # the time stamp up to which recovery will proceed + # (change requires restart) +#recovery_target_xid = '' # the transaction ID up to which recovery will proceed + # (change requires restart) +#recovery_target_lsn = '' # the WAL LSN up to which recovery will proceed + # (change requires restart) +#recovery_target_inclusive = on # Specifies whether to stop: + # just after the specified recovery target (on) + # just before the recovery target (off) + # (change requires restart) +#recovery_target_timeline = 'latest' # 'current', 'latest', or timeline ID + # (change requires restart) +#recovery_target_action = 'pause' # 'pause', 'promote', 'shutdown' + # (change requires restart) + #------------------------------------------------------------------------------ # REPLICATION @@ -260,6 +307,11 @@ # These settings are ignored on a master server. +#primary_conninfo = '' # connection string to sending server + # (change requires restart) +#primary_slot_name = '' # replication slot on sending server + # (change requires restart) +#promote_trigger_file = '' # file name whose presence ends recovery #hot_standby = on # "off" disallows queries during recovery # (change requires restart) #max_standby_archive_delay = 30s # max delay before canceling queries @@ -277,6 +329,7 @@ # in milliseconds; 0 disables #wal_retrieve_retry_interval = 5s # time to wait before retrying to # retrieve WAL after a failed attempt +#recovery_min_apply_delay = 0 # minimum delay for applying changes during recovery # - Subscribers - @@ -308,6 +361,7 @@ #enable_partitionwise_join = off #enable_partitionwise_aggregate = off #enable_parallel_hash = on +#enable_partition_pruning = on # - Planner Cost Constants - @@ -320,11 +374,12 @@ #parallel_setup_cost = 1000.0 # same scale as above #jit_above_cost = 100000 # perform JIT compilation if available - # and query more expensive, -1 disables -#jit_optimize_above_cost = 500000 # optimize JITed functions if query is - # more expensive, -1 disables -#jit_inline_above_cost = 500000 # attempt to inline operators and - # functions if query is more expensive, + # and query more expensive than this; + # -1 disables +#jit_inline_above_cost = 500000 # inline small functions if query is + # more expensive than this; -1 disables +#jit_optimize_above_cost = 500000 # use expensive JIT optimizations if + # query is more expensive than this; # -1 disables #min_parallel_table_scan_size = 8MB @@ -350,6 +405,9 @@ #join_collapse_limit = 8 # 1 disables collapsing of explicit # JOIN clauses #force_parallel_mode = off +#jit = on # allow JIT compilation +#plan_cache_mode = auto # auto, force_generic_plan or + # force_custom_plan #------------------------------------------------------------------------------ @@ -402,17 +460,6 @@ # - When to Log - -#client_min_messages = notice # values in order of decreasing detail: - # debug5 - # debug4 - # debug3 - # debug2 - # debug1 - # log - # notice - # warning - # error - #log_min_messages = warning # values in order of decreasing detail: # debug5 # debug4 @@ -446,6 +493,9 @@ # statements running at least this number # of milliseconds +#log_transaction_sample_rate = 0.0 # Fraction of transactions whose statements + # are logged regardless of their duration. 1.0 logs all + # statements from all transactions, 0.0 never logs. # - What to Log - @@ -543,7 +593,7 @@ #autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age # before forced vacuum # (change requires restart) -#autovacuum_vacuum_cost_delay = 20ms # default vacuum cost delay for +#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for # autovacuum, in milliseconds; # -1 means use vacuum_cost_delay #autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for @@ -557,11 +607,22 @@ # - Statement Behavior - +#client_min_messages = notice # values in order of decreasing detail: + # debug5 + # debug4 + # debug3 + # debug2 + # debug1 + # log + # notice + # warning + # error #search_path = '"$user", public' # schema names #row_security = on #default_tablespace = '' # a tablespace name, '' uses the default #temp_tablespaces = '' # a list of tablespace names, '' uses # only default tablespace +#default_table_access_method = 'heap' #check_function_bodies = on #default_transaction_isolation = 'read committed' #default_transaction_read_only = off @@ -574,6 +635,9 @@ #vacuum_freeze_table_age = 150000000 #vacuum_multixact_freeze_min_age = 5000000 #vacuum_multixact_freeze_table_age = 150000000 +#vacuum_cleanup_index_scale_factor = 0.1 # fraction of total number of tuples + # before index cleanup, 0 always performs + # index cleanup #bytea_output = 'hex' # hex, escape #xmlbinary = 'base64' #xmloption = 'content' @@ -592,7 +656,8 @@ # India # You can create your own file in # share/timezonesets/. -#extra_float_digits = 0 # min -15, max 3 +#extra_float_digits = 1 # min -15, max 3; any value >0 actually + # selects precise output mode #client_encoding = sql_ascii # actually, defaults to database # encoding @@ -611,13 +676,12 @@ #shared_preload_libraries = '' # (change requires restart) #local_preload_libraries = '' #session_preload_libraries = '' +#jit_provider = 'llvmjit' # JIT library to use # - Other Defaults - #dynamic_library_path = '$libdir' -#jit = on # allow JIT compilation -#jit_provider = 'llvmjit' # JIT implementation to use #------------------------------------------------------------------------------ # LOCK MANAGEMENT @@ -642,7 +706,6 @@ #array_nulls = on #backslash_quote = safe_encoding # on, off, or safe_encoding -#default_with_oids = off #escape_string_warning = on #lo_compat_privileges = off #operator_precedence_warning = off @@ -661,6 +724,9 @@ #exit_on_error = off # terminate session on any error? #restart_after_crash = on # reinitialize after backend crash? +#data_sync_retry = off # retry or panic on failure to fsync + # data? + # (change requires restart) #------------------------------------------------------------------------------ @@ -668,12 +734,13 @@ #------------------------------------------------------------------------------ # These options allow settings to be loaded from files other than the -# default postgresql.conf. +# default postgresql.conf. Note that these are directives, not variable +# assignments, so they can usefully be given more than once. -#include_dir = 'conf.d' # include files ending in '.conf' from - # directory 'conf.d' -#include_if_exists = 'exists.conf' # include file only if it exists -#include = 'special.conf' # include file +#include_dir = '...' # include files ending in '.conf' from + # a directory, e.g., 'conf.d' +#include_if_exists = '...' # include file only if it exists +#include = '...' # include file #------------------------------------------------------------------------------ diff --git a/src/backend/utils/misc/ps_status.c b/src/backend/utils/misc/ps_status.c index 83a93d24056..67ba95c5f7d 100644 --- a/src/backend/utils/misc/ps_status.c +++ b/src/backend/utils/misc/ps_status.c @@ -7,7 +7,7 @@ * * src/backend/utils/misc/ps_status.c * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * various details abducted from various places *-------------------------------------------------------------------- */ @@ -38,6 +38,9 @@ bool update_process_title = true; /* * Alternative ways of updating ps display: * + * PS_USE_SETPROCTITLE_FAST + * use the function setproctitle_fast(const char *, ...) + * (newer FreeBSD systems) * PS_USE_SETPROCTITLE * use the function setproctitle(const char *, ...) * (newer BSD systems) @@ -59,7 +62,9 @@ bool update_process_title = true; * don't update ps display * (This is the default, as it is safest.) */ -#if defined(HAVE_SETPROCTITLE) +#if defined(HAVE_SETPROCTITLE_FAST) +#define PS_USE_SETPROCTITLE_FAST +#elif defined(HAVE_SETPROCTITLE) #define PS_USE_SETPROCTITLE #elif defined(HAVE_PSTAT) && defined(PSTAT_SETCMD) #define PS_USE_PSTAT @@ -286,7 +291,7 @@ init_ps_display(const char *username, const char *dbname, * Make fixed prefix of ps display. */ -#ifdef PS_USE_SETPROCTITLE +#if defined(PS_USE_SETPROCTITLE) || defined(PS_USE_SETPROCTITLE_FAST) /* * apparently setproctitle() already adds a `progname:' prefix to the ps @@ -349,6 +354,8 @@ set_ps_display(const char *activity, bool force) #ifdef PS_USE_SETPROCTITLE setproctitle("%s", ps_buffer); +#elif defined(PS_USE_SETPROCTITLE_FAST) + setproctitle_fast("%s", ps_buffer); #endif #ifdef PS_USE_PSTAT diff --git a/src/backend/utils/misc/queryenvironment.c b/src/backend/utils/misc/queryenvironment.c index bc2b1e81866..25001600282 100644 --- a/src/backend/utils/misc/queryenvironment.c +++ b/src/backend/utils/misc/queryenvironment.c @@ -11,18 +11,18 @@ * on callers, since this is an opaque structure. This is the reason to * require a create function. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION - * src/backend/backend/utils/misc/queryenvironment.c + * src/backend/utils/misc/queryenvironment.c * *------------------------------------------------------------------------- */ #include "postgres.h" -#include "access/heapam.h" +#include "access/table.h" #include "utils/queryenvironment.h" #include "utils/rel.h" @@ -135,9 +135,9 @@ ENRMetadataGetTupDesc(EphemeralNamedRelationMetadata enrmd) { Relation relation; - relation = heap_open(enrmd->reliddesc, NoLock); + relation = table_open(enrmd->reliddesc, NoLock); tupdesc = relation->rd_att; - heap_close(relation, NoLock); + table_close(relation, NoLock); } return tupdesc; diff --git a/src/backend/utils/misc/rls.c b/src/backend/utils/misc/rls.c index 94449c7e8a3..4f359117a06 100644 --- a/src/backend/utils/misc/rls.c +++ b/src/backend/utils/misc/rls.c @@ -3,7 +3,7 @@ * rls.c * RLS-related utility functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/sampling.c b/src/backend/utils/misc/sampling.c index e9e230df01d..d2a1537979c 100644 --- a/src/backend/utils/misc/sampling.c +++ b/src/backend/utils/misc/sampling.c @@ -3,7 +3,7 @@ * sampling.c * Relation block sampling routines. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/superuser.c b/src/backend/utils/misc/superuser.c index fbe83c9b3cc..56360817d9e 100644 --- a/src/backend/utils/misc/superuser.c +++ b/src/backend/utils/misc/superuser.c @@ -9,7 +9,7 @@ * the single-user case works. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/timeout.c b/src/backend/utils/misc/timeout.c index f99a63bd5b1..b56259c6920 100644 --- a/src/backend/utils/misc/timeout.c +++ b/src/backend/utils/misc/timeout.c @@ -3,7 +3,7 @@ * timeout.c * Routines to multiplex SIGALRM interrupts for multiple timeout reasons. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/backend/utils/misc/tzparser.c b/src/backend/utils/misc/tzparser.c index 3d07eb7265d..167db84c4de 100644 --- a/src/backend/utils/misc/tzparser.c +++ b/src/backend/utils/misc/tzparser.c @@ -11,7 +11,7 @@ * PG_TRY if necessary. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -35,11 +35,11 @@ static bool validateTzEntry(tzEntry *tzentry); static bool splitTzLine(const char *filename, int lineno, - char *line, tzEntry *tzentry); -static int addToArray(tzEntry **base, int *arraysize, int n, - tzEntry *entry, bool override); -static int ParseTzFile(const char *filename, int depth, - tzEntry **base, int *arraysize, int n); + char *line, tzEntry *tzentry); +static int addToArray(tzEntry **base, int *arraysize, int n, + tzEntry *entry, bool override); +static int ParseTzFile(const char *filename, int depth, + tzEntry **base, int *arraysize, int n); /* @@ -53,8 +53,7 @@ validateTzEntry(tzEntry *tzentry) unsigned char *p; /* - * Check restrictions imposed by datetkntbl storage format (see - * datetime.c) + * Check restrictions imposed by datetktbl storage format (see datetime.c) */ if (strlen(tzentry->abbrev) > TOKMAXLEN) { diff --git a/src/backend/utils/mmgr/README b/src/backend/utils/mmgr/README index a42e568d5c9..b9ba3fc7730 100644 --- a/src/backend/utils/mmgr/README +++ b/src/backend/utils/mmgr/README @@ -23,6 +23,10 @@ The basic operations on a memory context are: * reset a context (free all memory allocated in the context, but not the context object itself) +* inquire about the total amount of memory allocated to the context + (the raw memory from which the context allocates chunks; not the + chunks themselves) + Given a chunk of memory previously allocated from a context, one can free it or reallocate it larger or smaller (corresponding to standard C library's free() and realloc() routines). These operations return memory @@ -401,7 +405,7 @@ GetMemoryChunkContext()) and then invoke the corresponding method for the context - context->methods->free_p(p); + context->methods->free_p(pointer); More Control Over aset.c Behavior @@ -452,3 +456,33 @@ returns the memory when reset/deleted). These memory contexts were initially developed for ReorderBuffer, but may be useful elsewhere as long as the allocation patterns match. + + +Memory Accounting +----------------- + +One of the basic memory context operations is determining the amount of +memory used in the context (and it's children). We have multiple places +that implement their own ad hoc memory accounting, and this is meant to +provide a unified approach. Ad hoc accounting solutions work for places +with tight control over the allocations or when it's easy to determine +sizes of allocated chunks (e.g. places that only work with tuples). + +The accounting built into the memory contexts is transparent and works +transparently for all allocations as long as they end up in the right +memory context subtree. + +Consider for example aggregate functions - the aggregate state is often +represented by an arbitrary structure, allocated from the transition +function, so the ad hoc accounting is unlikely to work. The built-in +accounting will however handle such cases just fine. + +To minimize overhead, the accounting is done at the block level, not for +individual allocation chunks. + +The accounting is lazy - after a block is allocated (or freed), only the +context owning that block is updated. This means that when inquiring +about the memory usage in a given context, we have to walk all children +contexts recursively. This means the memory accounting is not intended +for cases with too many memory contexts (in the relevant subtree). + diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c index e3d2c4e2faa..3bbcb1c8946 100644 --- a/src/backend/utils/mmgr/aset.c +++ b/src/backend/utils/mmgr/aset.c @@ -7,7 +7,7 @@ * type. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -273,8 +273,8 @@ static void AllocSetDelete(MemoryContext context); static Size AllocSetGetChunkSpace(MemoryContext context, void *pointer); static bool AllocSetIsEmpty(MemoryContext context); static void AllocSetStats(MemoryContext context, - MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals); #ifdef MEMORY_CONTEXT_CHECKING static void AllocSetCheck(MemoryContext context); @@ -371,7 +371,7 @@ AllocSetFreeIndex(Size size) /* - * AllocSetContextCreateExtended + * AllocSetContextCreateInternal * Create a new AllocSet context. * * parent: parent context, or NULL if top-level context @@ -381,11 +381,13 @@ AllocSetFreeIndex(Size size) * maxBlockSize: maximum allocation block size * * Most callers should abstract the context size parameters using a macro - * such as ALLOCSET_DEFAULT_SIZES. (This is now *required* when going - * through the AllocSetContextCreate macro.) + * such as ALLOCSET_DEFAULT_SIZES. + * + * Note: don't call this directly; go through the wrapper macro + * AllocSetContextCreate. */ MemoryContext -AllocSetContextCreateExtended(MemoryContext parent, +AllocSetContextCreateInternal(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, @@ -456,6 +458,9 @@ AllocSetContextCreateExtended(MemoryContext parent, parent, name); + ((MemoryContext) set)->mem_allocated = + set->keeper->endptr - ((char *) set); + return (MemoryContext) set; } } @@ -544,6 +549,8 @@ AllocSetContextCreateExtended(MemoryContext parent, parent, name); + ((MemoryContext) set)->mem_allocated = firstBlockSize; + return (MemoryContext) set; } @@ -564,6 +571,8 @@ AllocSetReset(MemoryContext context) { AllocSet set = (AllocSet) context; AllocBlock block; + Size keepersize PG_USED_FOR_ASSERTS_ONLY + = set->keeper->endptr - ((char *) set); AssertArg(AllocSetIsValid(set)); @@ -602,6 +611,8 @@ AllocSetReset(MemoryContext context) else { /* Normal case, release the block */ + context->mem_allocated -= block->endptr - ((char*) block); + #ifdef CLOBBER_FREED_MEMORY wipe_mem(block, block->freeptr - ((char *) block)); #endif @@ -610,6 +621,8 @@ AllocSetReset(MemoryContext context) block = next; } + Assert(context->mem_allocated == keepersize); + /* Reset block size allocation sequence, too */ set->nextBlockSize = set->initBlockSize; } @@ -626,6 +639,8 @@ AllocSetDelete(MemoryContext context) { AllocSet set = (AllocSet) context; AllocBlock block = set->blocks; + Size keepersize PG_USED_FOR_ASSERTS_ONLY + = set->keeper->endptr - ((char *) set); AssertArg(AllocSetIsValid(set)); @@ -681,6 +696,9 @@ AllocSetDelete(MemoryContext context) { AllocBlock next = block->next; + if (block != set->keeper) + context->mem_allocated -= block->endptr - ((char *) block); + #ifdef CLOBBER_FREED_MEMORY wipe_mem(block, block->freeptr - ((char *) block)); #endif @@ -691,6 +709,8 @@ AllocSetDelete(MemoryContext context) block = next; } + Assert(context->mem_allocated == keepersize); + /* Finally, free the context header, including the keeper block */ free(set); } @@ -731,6 +751,9 @@ AllocSetAlloc(MemoryContext context, Size size) block = (AllocBlock) malloc(blksize); if (block == NULL) return NULL; + + context->mem_allocated += blksize; + block->aset = set; block->freeptr = block->endptr = ((char *) block) + blksize; @@ -913,7 +936,7 @@ AllocSetAlloc(MemoryContext context, Size size) /* * We could be asking for pretty big blocks here, so cope if malloc - * fails. But give up if there's less than a meg or so available... + * fails. But give up if there's less than 1 MB or so available... */ while (block == NULL && blksize > 1024 * 1024) { @@ -926,6 +949,8 @@ AllocSetAlloc(MemoryContext context, Size size) if (block == NULL) return NULL; + context->mem_allocated += blksize; + block->aset = set; block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ; block->endptr = ((char *) block) + blksize; @@ -1026,6 +1051,9 @@ AllocSetFree(MemoryContext context, void *pointer) set->blocks = block->next; if (block->next) block->next->prev = block->prev; + + context->mem_allocated -= block->endptr - ((char*) block); + #ifdef CLOBBER_FREED_MEMORY wipe_mem(block, block->freeptr - ((char *) block)); #endif @@ -1142,6 +1170,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) AllocBlock block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ); Size chksize; Size blksize; + Size oldblksize; /* * Try to verify that we have a sane block pointer: it should @@ -1157,6 +1186,8 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) /* Do the realloc */ chksize = MAXALIGN(size); blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ; + oldblksize = block->endptr - ((char *)block); + block = (AllocBlock) realloc(block, blksize); if (block == NULL) { @@ -1164,6 +1195,9 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size) VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN); return NULL; } + + context->mem_allocated += blksize - oldblksize; + block->freeptr = block->endptr = ((char *) block) + blksize; /* Update pointers since block has likely been moved */ @@ -1381,6 +1415,7 @@ AllocSetCheck(MemoryContext context) const char *name = set->header.name; AllocBlock prevblock; AllocBlock block; + int64 total_allocated = 0; for (prevblock = NULL, block = set->blocks; block != NULL; @@ -1391,6 +1426,11 @@ AllocSetCheck(MemoryContext context) long blk_data = 0; long nchunks = 0; + if (set->keeper == block) + total_allocated += block->endptr - ((char *) set); + else + total_allocated += block->endptr - ((char *) block); + /* * Empty block - empty can be keeper-block only */ @@ -1477,6 +1517,8 @@ AllocSetCheck(MemoryContext context) elog(WARNING, "problem in alloc set %s: found inconsistent memory block %p", name, block); } + + Assert(total_allocated == context->mem_allocated); } #endif /* MEMORY_CONTEXT_CHECKING */ diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c index f329fdd10f1..6590e55a241 100644 --- a/src/backend/utils/mmgr/dsa.c +++ b/src/backend/utils/mmgr/dsa.c @@ -39,7 +39,7 @@ * empty and be returned to the free page manager, and whole segments can * become empty and be returned to the operating system. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -65,7 +65,7 @@ * double this size, and so on. Larger segments may be created if necessary * to satisfy large requests. */ -#define DSA_INITIAL_SEGMENT_SIZE ((Size) (1 * 1024 * 1024)) +#define DSA_INITIAL_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024)) /* * How many segments to create before we double the segment size. If this is @@ -98,7 +98,7 @@ #define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1) /* The maximum size of a DSM segment. */ -#define DSA_MAX_SEGMENT_SIZE ((Size) 1 << DSA_OFFSET_WIDTH) +#define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH) /* Number of pages (see FPM_PAGE_SIZE) per regular superblock. */ #define DSA_PAGES_PER_SUPERBLOCK 16 @@ -121,7 +121,7 @@ #define DSA_EXTRACT_OFFSET(dp) ((dp) & DSA_OFFSET_BITMASK) /* The type used for index segment indexes (zero based). */ -typedef Size dsa_segment_index; +typedef size_t dsa_segment_index; /* Sentinel value for dsa_segment_index indicating 'none' or 'end'. */ #define DSA_SEGMENT_INDEX_NONE (~(dsa_segment_index)0) @@ -153,9 +153,9 @@ typedef struct /* Sanity check magic value. */ uint32 magic; /* Total number of pages in this segment (excluding metadata area). */ - Size usable_pages; + size_t usable_pages; /* Total size of this segment in bytes. */ - Size size; + size_t size; /* * Index of the segment that precedes this one in the same segment bin, or @@ -169,7 +169,7 @@ typedef struct */ dsa_segment_index next; /* The index of the bin that contains this segment. */ - Size bin; + size_t bin; /* * A flag raised to indicate that this segment is being returned to the @@ -197,7 +197,7 @@ typedef struct dsa_pointer prevspan; /* Previous span. */ dsa_pointer nextspan; /* Next span. */ dsa_pointer start; /* Starting address. */ - Size npages; /* Length of span in pages. */ + size_t npages; /* Length of span in pages. */ uint16 size_class; /* Size class. */ uint16 ninitialized; /* Maximum number of objects ever allocated. */ uint16 nallocatable; /* Number of objects currently allocatable. */ @@ -256,7 +256,7 @@ static const uint16 dsa_size_classes[] = { * round the size of the object up to the next multiple of 8 bytes, and then * index into this array. */ -static char dsa_size_class_map[] = { +static const uint8 dsa_size_class_map[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, @@ -308,9 +308,9 @@ typedef struct /* The object pools for each size class. */ dsa_area_pool pools[DSA_NUM_SIZE_CLASSES]; /* The total size of all active segments. */ - Size total_segment_size; + size_t total_segment_size; /* The maximum total size of backing storage we are allowed. */ - Size max_total_segment_size; + size_t max_total_segment_size; /* Highest used segment index in the history of this area. */ dsa_segment_index high_segment_index; /* The reference count for this area. */ @@ -318,7 +318,7 @@ typedef struct /* A flag indicating that this area has been pinned. */ bool pinned; /* The number of times that segments have been freed. */ - Size freed_segment_counter; + size_t freed_segment_counter; /* The LWLock tranche ID. */ int lwlock_tranche_id; /* The general lock (protects everything except object pools). */ @@ -362,7 +362,7 @@ struct dsa_area /* * This backend's array of segment maps, ordered by segment index * corresponding to control->segment_handles. Some of the area's segments - * may not be mapped in in this backend yet, and some slots may have been + * may not be mapped in this backend yet, and some slots may have been * freed and need to be detached; these operations happen on demand. */ dsa_segment_map segment_maps[DSA_MAX_SEGMENTS]; @@ -371,7 +371,7 @@ struct dsa_area dsa_segment_index high_segment_index; /* The last observed freed_segment_counter. */ - Size freed_segment_counter; + size_t freed_segment_counter; }; #define DSA_SPAN_NOTHING_FREE ((uint16) -1) @@ -382,29 +382,30 @@ struct dsa_area (segment_map_ptr - &area->segment_maps[0]) static void init_span(dsa_area *area, dsa_pointer span_pointer, - dsa_area_pool *pool, dsa_pointer start, Size npages, - uint16 size_class); + dsa_area_pool *pool, dsa_pointer start, size_t npages, + uint16 size_class); static bool transfer_first_span(dsa_area *area, dsa_area_pool *pool, - int fromclass, int toclass); + int fromclass, int toclass); static inline dsa_pointer alloc_object(dsa_area *area, int size_class); static bool ensure_active_superblock(dsa_area *area, dsa_area_pool *pool, - int size_class); + int size_class); static dsa_segment_map *get_segment_by_index(dsa_area *area, - dsa_segment_index index); + dsa_segment_index index); static void destroy_superblock(dsa_area *area, dsa_pointer span_pointer); static void unlink_span(dsa_area *area, dsa_area_span *span); static void add_span_to_fullness_class(dsa_area *area, dsa_area_span *span, - dsa_pointer span_pointer, int fclass); + dsa_pointer span_pointer, int fclass); static void unlink_segment(dsa_area *area, dsa_segment_map *segment_map); -static dsa_segment_map *get_best_segment(dsa_area *area, Size npages); -static dsa_segment_map *make_new_segment(dsa_area *area, Size requested_pages); +static dsa_segment_map *get_best_segment(dsa_area *area, size_t npages); +static dsa_segment_map *make_new_segment(dsa_area *area, size_t requested_pages); static dsa_area *create_internal(void *place, size_t size, - int tranche_id, - dsm_handle control_handle, - dsm_segment *control_segment); + int tranche_id, + dsm_handle control_handle, + dsm_segment *control_segment); static dsa_area *attach_internal(void *place, dsm_segment *segment, - dsa_handle handle); + dsa_handle handle); static void check_for_freed_segments(dsa_area *area); +static void check_for_freed_segments_locked(dsa_area *area); /* * Create a new shared area in a new DSM segment. Further DSM segments will @@ -649,7 +650,7 @@ dsa_pin_mapping(dsa_area *area) * will result in an ERROR. * * DSA_ALLOC_NO_OOM causes this function to return InvalidDsaPointer when - * no memory is available or a size limit established by set_dsa_size_limit + * no memory is available or a size limit established by dsa_set_size_limit * would be exceeded. Otherwise, such allocations will result in an ERROR. * * DSA_ALLOC_ZERO causes the allocated memory to be zeroed. Otherwise, the @@ -661,7 +662,7 @@ dsa_pin_mapping(dsa_area *area) * flags. */ dsa_pointer -dsa_allocate_extended(dsa_area *area, Size size, int flags) +dsa_allocate_extended(dsa_area *area, size_t size, int flags) { uint16 size_class; dsa_pointer start_pointer; @@ -684,15 +685,24 @@ dsa_allocate_extended(dsa_area *area, Size size, int flags) */ if (size > dsa_size_classes[lengthof(dsa_size_classes) - 1]) { - Size npages = fpm_size_to_pages(size); - Size first_page; + size_t npages = fpm_size_to_pages(size); + size_t first_page; dsa_pointer span_pointer; dsa_area_pool *pool = &area->control->pools[DSA_SCLASS_SPAN_LARGE]; /* Obtain a span object. */ span_pointer = alloc_object(area, DSA_SCLASS_BLOCK_OF_SPANS); if (!DsaPointerIsValid(span_pointer)) + { + /* Raise error unless asked not to. */ + if ((flags & DSA_ALLOC_NO_OOM) == 0) + ereport(ERROR, + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of memory"), + errdetail("Failed on DSA request of size %zu.", + size))); return InvalidDsaPointer; + } LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); @@ -789,12 +799,10 @@ dsa_allocate_extended(dsa_area *area, Size size, int flags) { /* Raise error unless asked not to. */ if ((flags & DSA_ALLOC_NO_OOM) == 0) - { ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of memory"), errdetail("Failed on DSA request of size %zu.", size))); - } return InvalidDsaPointer; } @@ -817,7 +825,7 @@ dsa_free(dsa_area *area, dsa_pointer dp) dsa_area_span *span; char *superblock; char *object; - Size size; + size_t size; int size_class; /* Make sure we don't have a stale segment in the slot 'dp' refers to. */ @@ -924,7 +932,7 @@ void * dsa_get_address(dsa_area *area, dsa_pointer dp) { dsa_segment_index index; - Size offset; + size_t offset; /* Convert InvalidDsaPointer to NULL. */ if (!DsaPointerIsValid(dp)) @@ -997,7 +1005,7 @@ dsa_unpin(dsa_area *area) * backends that have attached to them. */ void -dsa_set_size_limit(dsa_area *area, Size limit) +dsa_set_size_limit(dsa_area *area, size_t limit) { LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); area->control->max_total_segment_size = limit; @@ -1056,7 +1064,7 @@ dsa_trim(dsa_area *area) void dsa_dump(dsa_area *area) { - Size i, + size_t i, j; /* @@ -1065,6 +1073,7 @@ dsa_dump(dsa_area *area) */ LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); + check_for_freed_segments_locked(area); fprintf(stderr, "dsa_area handle %x:\n", area->control->handle); fprintf(stderr, " max_total_segment_size: %zu\n", area->control->max_total_segment_size); @@ -1156,10 +1165,10 @@ dsa_dump(dsa_area *area) * Return the smallest size that you can successfully provide to * dsa_create_in_place. */ -Size +size_t dsa_minimum_size(void) { - Size size; + size_t size; int pages = 0; size = MAXALIGN(sizeof(dsa_area_control)) + @@ -1187,9 +1196,9 @@ create_internal(void *place, size_t size, dsa_area_control *control; dsa_area *area; dsa_segment_map *segment_map; - Size usable_pages; - Size total_pages; - Size metadata_bytes; + size_t usable_pages; + size_t total_pages; + size_t metadata_bytes; int i; /* Sanity check on the space we have to work in. */ @@ -1222,7 +1231,7 @@ create_internal(void *place, size_t size, control->segment_header.freed = false; control->segment_header.size = DSA_INITIAL_SEGMENT_SIZE; control->handle = control_handle; - control->max_total_segment_size = (Size) -1; + control->max_total_segment_size = (size_t) -1; control->total_segment_size = size; memset(&control->segment_handles[0], 0, sizeof(dsm_handle) * DSA_MAX_SEGMENTS); @@ -1335,11 +1344,11 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle) static void init_span(dsa_area *area, dsa_pointer span_pointer, - dsa_area_pool *pool, dsa_pointer start, Size npages, + dsa_area_pool *pool, dsa_pointer start, size_t npages, uint16 size_class) { dsa_area_span *span = dsa_get_address(area, span_pointer); - Size obsize = dsa_size_classes[size_class]; + size_t obsize = dsa_size_classes[size_class]; /* * The per-pool lock must be held because we manipulate the span list for @@ -1435,7 +1444,7 @@ alloc_object(dsa_area *area, int size_class) dsa_pointer block; dsa_pointer result; char *object; - Size size; + size_t size; /* * Even though ensure_active_superblock can in turn call alloc_object if @@ -1521,12 +1530,12 @@ ensure_active_superblock(dsa_area *area, dsa_area_pool *pool, { dsa_pointer span_pointer; dsa_pointer start_pointer; - Size obsize = dsa_size_classes[size_class]; - Size nmax; + size_t obsize = dsa_size_classes[size_class]; + size_t nmax; int fclass; - Size npages = 1; - Size first_page; - Size i; + size_t npages = 1; + size_t first_page; + size_t i; dsa_segment_map *segment_map; Assert(LWLockHeldByMe(DSA_SCLASS_LOCK(area, size_class))); @@ -1667,13 +1676,15 @@ ensure_active_superblock(dsa_area *area, dsa_area_pool *pool, return false; } } + + /* + * This shouldn't happen: get_best_segment() or make_new_segment() + * promised that we can successfully allocate npages. + */ if (!FreePageManagerGet(segment_map->fpm, npages, &first_page)) - { - LWLockRelease(DSA_AREA_LOCK(area)); - if (size_class != DSA_SCLASS_BLOCK_OF_SPANS) - dsa_free(area, span_pointer); - return false; - } + elog(FATAL, + "dsa_allocate could not find %zu free pages for superblock", + npages); LWLockRelease(DSA_AREA_LOCK(area)); /* Compute the start of the superblock. */ @@ -1762,6 +1773,23 @@ get_segment_by_index(dsa_area *area, dsa_segment_index index) (DSA_SEGMENT_HEADER_MAGIC ^ area->control->handle ^ index)); } + /* + * Callers of dsa_get_address() and dsa_free() don't hold the area lock, + * but it's a bug in the calling code and undefined behavior if the + * address is not live (ie if the segment might possibly have been freed, + * they're trying to use a dangling pointer). + * + * For dsa.c code that holds the area lock to manipulate segment_bins + * lists, it would be a bug if we ever reach a freed segment here. After + * it's marked as freed, the only thing any backend should do with it is + * unmap it, and it should always have done that in + * check_for_freed_segments_locked() before arriving here to resolve an + * index to a segment_map. + * + * Either way we can assert that we aren't returning a freed segment. + */ + Assert(!area->segment_maps[index].header->freed); + return &area->segment_maps[index]; } @@ -1778,8 +1806,6 @@ destroy_superblock(dsa_area *area, dsa_pointer span_pointer) int size_class = span->size_class; dsa_segment_map *segment_map; - segment_map = - get_segment_by_index(area, DSA_EXTRACT_SEGMENT_NUMBER(span->start)); /* Remove it from its fullness class list. */ unlink_span(area, span); @@ -1790,6 +1816,9 @@ destroy_superblock(dsa_area *area, dsa_pointer span_pointer) * could deadlock. */ LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); + check_for_freed_segments_locked(area); + segment_map = + get_segment_by_index(area, DSA_EXTRACT_SEGMENT_NUMBER(span->start)); FreePageManagerPut(segment_map->fpm, DSA_EXTRACT_OFFSET(span->start) / FPM_PAGE_SIZE, span->npages); @@ -1939,11 +1968,12 @@ unlink_segment(dsa_area *area, dsa_segment_map *segment_map) * pages map. */ static dsa_segment_map * -get_best_segment(dsa_area *area, Size npages) +get_best_segment(dsa_area *area, size_t npages) { - Size bin; + size_t bin; Assert(LWLockHeldByMe(DSA_AREA_LOCK(area))); + check_for_freed_segments_locked(area); /* * Start searching from the first bin that *might* have enough contiguous @@ -1957,7 +1987,7 @@ get_best_segment(dsa_area *area, Size npages) * The minimum contiguous size that any segment in this bin should * have. We'll re-bin if we see segments with fewer. */ - Size threshold = (Size) 1 << (bin - 1); + size_t threshold = (size_t) 1 << (bin - 1); dsa_segment_index segment_index; /* Search this bin for a segment with enough contiguous space. */ @@ -1966,7 +1996,7 @@ get_best_segment(dsa_area *area, Size npages) { dsa_segment_map *segment_map; dsa_segment_index next_segment_index; - Size contiguous_pages; + size_t contiguous_pages; segment_map = get_segment_by_index(area, segment_index); next_segment_index = segment_map->header->next; @@ -1982,7 +2012,7 @@ get_best_segment(dsa_area *area, Size npages) /* Re-bin it if it's no longer in the appropriate bin. */ if (contiguous_pages < threshold) { - Size new_bin; + size_t new_bin; new_bin = contiguous_pages_to_segment_bin(contiguous_pages); @@ -2030,13 +2060,13 @@ get_best_segment(dsa_area *area, Size npages) * segments would be exceeded. */ static dsa_segment_map * -make_new_segment(dsa_area *area, Size requested_pages) +make_new_segment(dsa_area *area, size_t requested_pages) { dsa_segment_index new_index; - Size metadata_bytes; - Size total_size; - Size total_pages; - Size usable_pages; + size_t metadata_bytes; + size_t total_size; + size_t total_pages; + size_t usable_pages; dsa_segment_map *segment_map; dsm_segment *segment; @@ -2074,7 +2104,7 @@ make_new_segment(dsa_area *area, Size requested_pages) * pages we can fit. */ total_size = DSA_INITIAL_SEGMENT_SIZE * - ((Size) 1 << (new_index / DSA_NUM_SEGMENTS_AT_EACH_SIZE)); + ((size_t) 1 << (new_index / DSA_NUM_SEGMENTS_AT_EACH_SIZE)); total_size = Min(total_size, DSA_MAX_SEGMENT_SIZE); total_size = Min(total_size, area->control->max_total_segment_size - @@ -2201,12 +2231,12 @@ make_new_segment(dsa_area *area, Size requested_pages) static void check_for_freed_segments(dsa_area *area) { - Size freed_segment_counter; + size_t freed_segment_counter; /* * Any other process that has freed a segment has incremented - * free_segment_counter while holding an LWLock, and that must precede any - * backend creating a new segment in the same slot while holding an + * freed_segment_counter while holding an LWLock, and that must precede + * any backend creating a new segment in the same slot while holding an * LWLock, and that must precede the creation of any dsa_pointer pointing * into the new segment which might reach us here, and the caller must * have sent the dsa_pointer to this process using appropriate memory @@ -2220,10 +2250,30 @@ check_for_freed_segments(dsa_area *area) freed_segment_counter = area->control->freed_segment_counter; if (unlikely(area->freed_segment_counter != freed_segment_counter)) { - int i; - /* Check all currently mapped segments to find what's been freed. */ LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE); + check_for_freed_segments_locked(area); + LWLockRelease(DSA_AREA_LOCK(area)); + } +} + +/* + * Workhorse for check_for_freed_segments(), and also used directly in path + * where the area lock is already held. This should be called after acquiring + * the lock but before looking up any segment by index number, to make sure we + * unmap any stale segments that might have previously had the same index as a + * current segment. + */ +static void +check_for_freed_segments_locked(dsa_area *area) +{ + size_t freed_segment_counter; + int i; + + Assert(LWLockHeldByMe(DSA_AREA_LOCK(area))); + freed_segment_counter = area->control->freed_segment_counter; + if (unlikely(area->freed_segment_counter != freed_segment_counter)) + { for (i = 0; i <= area->high_segment_index; ++i) { if (area->segment_maps[i].header != NULL && @@ -2235,7 +2285,6 @@ check_for_freed_segments(dsa_area *area) area->segment_maps[i].mapped_address = NULL; } } - LWLockRelease(DSA_AREA_LOCK(area)); area->freed_segment_counter = freed_segment_counter; } } diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c index 5bddfefed45..ba3bc20ef17 100644 --- a/src/backend/utils/mmgr/freepage.c +++ b/src/backend/utils/mmgr/freepage.c @@ -42,7 +42,7 @@ * where memory fragmentation is very severe, only a tiny fraction of * the pages under management are consumed by this btree. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -126,41 +126,41 @@ typedef struct FreePageBtreeSearchResult /* Helper functions */ static void FreePageBtreeAdjustAncestorKeys(FreePageManager *fpm, - FreePageBtree *btp); + FreePageBtree *btp); static Size FreePageBtreeCleanup(FreePageManager *fpm); static FreePageBtree *FreePageBtreeFindLeftSibling(char *base, - FreePageBtree *btp); + FreePageBtree *btp); static FreePageBtree *FreePageBtreeFindRightSibling(char *base, - FreePageBtree *btp); + FreePageBtree *btp); static Size FreePageBtreeFirstKey(FreePageBtree *btp); static FreePageBtree *FreePageBtreeGetRecycled(FreePageManager *fpm); static void FreePageBtreeInsertInternal(char *base, FreePageBtree *btp, - Size index, Size first_page, FreePageBtree *child); + Size index, Size first_page, FreePageBtree *child); static void FreePageBtreeInsertLeaf(FreePageBtree *btp, Size index, - Size first_page, Size npages); + Size first_page, Size npages); static void FreePageBtreeRecycle(FreePageManager *fpm, Size pageno); static void FreePageBtreeRemove(FreePageManager *fpm, FreePageBtree *btp, - Size index); + Size index); static void FreePageBtreeRemovePage(FreePageManager *fpm, FreePageBtree *btp); static void FreePageBtreeSearch(FreePageManager *fpm, Size first_page, - FreePageBtreeSearchResult *result); + FreePageBtreeSearchResult *result); static Size FreePageBtreeSearchInternal(FreePageBtree *btp, Size first_page); static Size FreePageBtreeSearchLeaf(FreePageBtree *btp, Size first_page); static FreePageBtree *FreePageBtreeSplitPage(FreePageManager *fpm, - FreePageBtree *btp); + FreePageBtree *btp); static void FreePageBtreeUpdateParentPointers(char *base, FreePageBtree *btp); static void FreePageManagerDumpBtree(FreePageManager *fpm, FreePageBtree *btp, - FreePageBtree *parent, int level, StringInfo buf); + FreePageBtree *parent, int level, StringInfo buf); static void FreePageManagerDumpSpans(FreePageManager *fpm, - FreePageSpanLeader *span, Size expected_pages, - StringInfo buf); + FreePageSpanLeader *span, Size expected_pages, + StringInfo buf); static bool FreePageManagerGetInternal(FreePageManager *fpm, Size npages, - Size *first_page); + Size *first_page); static Size FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, - Size npages, bool soft); + Size npages, bool soft); static void FreePagePopSpanLeader(FreePageManager *fpm, Size pageno); static void FreePagePushSpanLeader(FreePageManager *fpm, Size first_page, - Size npages); + Size npages); static Size FreePageManagerLargestContiguous(FreePageManager *fpm); static void FreePageManagerUpdateLargest(FreePageManager *fpm); @@ -231,7 +231,7 @@ FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page) /* * FreePageManagerGetInternal may have set contiguous_pages_dirty. - * Recompute contigous_pages if so. + * Recompute contiguous_pages if so. */ FreePageManagerUpdateLargest(fpm); @@ -742,8 +742,8 @@ FreePageBtreeConsolidate(FreePageManager *fpm, FreePageBtree *btp) /* * If we can fit our keys onto our left sibling's page, consolidate. In - * this case, we move our keys onto the other page rather than visca - * versa, to avoid having to adjust ancestor keys. + * this case, we move our keys onto the other page rather than vice versa, + * to avoid having to adjust ancestor keys. */ np = FreePageBtreeFindLeftSibling(base, btp); if (np != NULL && btp->hdr.nused + np->hdr.nused <= max) @@ -1470,9 +1470,7 @@ FreePageManagerGetInternal(FreePageManager *fpm, Size npages, Size *first_page) * pages; if false, do it always. Returns 0 if the soft flag caused the * insertion to be skipped, or otherwise the size of the contiguous span * created by the insertion. This may be larger than npages if we're able - * to consolidate with an adjacent range. *internal_pages_used is set to - * true if the btree allocated pages for internal purposes, which might - * invalidate the current largest run requiring it to be recomputed. + * to consolidate with an adjacent range. */ static Size FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, @@ -1526,6 +1524,8 @@ FreePageManagerPutInternal(FreePageManager *fpm, Size first_page, Size npages, if (!relptr_is_null(fpm->btree_recycle)) root = FreePageBtreeGetRecycled(fpm); + else if (soft) + return 0; /* Should not allocate if soft. */ else if (FreePageManagerGetInternal(fpm, 1, &root_page)) root = (FreePageBtree *) fpm_page_to_pointer(base, root_page); else diff --git a/src/backend/utils/mmgr/generation.c b/src/backend/utils/mmgr/generation.c index 7ee3c481b34..2d24ab68bc0 100644 --- a/src/backend/utils/mmgr/generation.c +++ b/src/backend/utils/mmgr/generation.c @@ -6,7 +6,7 @@ * Generation is a custom MemoryContext implementation designed for cases of * chunks with similar lifespan. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mmgr/generation.c @@ -154,8 +154,8 @@ static void GenerationDelete(MemoryContext context); static Size GenerationGetChunkSpace(MemoryContext context, void *pointer); static bool GenerationIsEmpty(MemoryContext context); static void GenerationStats(MemoryContext context, - MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals); #ifdef MEMORY_CONTEXT_CHECKING static void GenerationCheck(MemoryContext context); @@ -297,6 +297,8 @@ GenerationReset(MemoryContext context) dlist_delete(miter.cur); + context->mem_allocated -= block->blksize; + #ifdef CLOBBER_FREED_MEMORY wipe_mem(block, block->blksize); #endif @@ -352,6 +354,8 @@ GenerationAlloc(MemoryContext context, Size size) if (block == NULL) return NULL; + context->mem_allocated += blksize; + /* block with a single (used) chunk */ block->blksize = blksize; block->nchunks = 1; @@ -407,6 +411,8 @@ GenerationAlloc(MemoryContext context, Size size) if (block == NULL) return NULL; + context->mem_allocated += blksize; + block->blksize = blksize; block->nchunks = 0; block->nfree = 0; @@ -522,6 +528,7 @@ GenerationFree(MemoryContext context, void *pointer) if (set->block == block) set->block = NULL; + context->mem_allocated -= block->blksize; free(block); } @@ -746,6 +753,7 @@ GenerationCheck(MemoryContext context) GenerationContext *gen = (GenerationContext *) context; const char *name = context->name; dlist_iter iter; + int64 total_allocated = 0; /* walk all blocks in this context */ dlist_foreach(iter, &gen->blocks) @@ -755,6 +763,8 @@ GenerationCheck(MemoryContext context) nchunks; char *ptr; + total_allocated += block->blksize; + /* * nfree > nchunks is surely wrong, and we don't expect to see * equality either, because such a block should have gotten freed. @@ -833,6 +843,8 @@ GenerationCheck(MemoryContext context) elog(WARNING, "problem in Generation %s: number of free chunks %d in block %p does not match header %d", name, nfree, block, block->nfree); } + + Assert(total_allocated == context->mem_allocated); } #endif /* MEMORY_CONTEXT_CHECKING */ diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index ebe0342f18e..7bbfabe0eab 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -9,7 +9,7 @@ * context's MemoryContextMethods struct. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -54,10 +54,10 @@ MemoryContext PortalContext = NULL; static void MemoryContextCallResetCallbacks(MemoryContext context); static void MemoryContextStatsInternal(MemoryContext context, int level, - bool print, int max_children, - MemoryContextCounters *totals); + bool print, int max_children, + MemoryContextCounters *totals); static void MemoryContextStatsPrint(MemoryContext context, void *passthru, - const char *stats_string); + const char *stats_string); /* * You should not do memory allocations within a critical section, because @@ -119,11 +119,11 @@ MemoryContextInit(void) * This should be the last step in this function, as elog.c assumes memory * management works once ErrorContext is non-null. */ - ErrorContext = AllocSetContextCreateExtended(TopMemoryContext, - "ErrorContext", - 8 * 1024, - 8 * 1024, - 8 * 1024); + ErrorContext = AllocSetContextCreate(TopMemoryContext, + "ErrorContext", + 8 * 1024, + 8 * 1024, + 8 * 1024); MemoryContextAllowInCriticalSection(ErrorContext, true); } @@ -462,6 +462,30 @@ MemoryContextIsEmpty(MemoryContext context) return context->methods->is_empty(context); } +/* + * Find the memory allocated to blocks for this memory context. If recurse is + * true, also include children. + */ +int64 +MemoryContextMemAllocated(MemoryContext context, bool recurse) +{ + int64 total = context->mem_allocated; + + AssertArg(MemoryContextIsValid(context)); + + if (recurse) + { + MemoryContext child = context->firstchild; + + for (child = context->firstchild; + child != NULL; + child = child->nextchild) + total += MemoryContextMemAllocated(child, true); + } + + return total; +} + /* * MemoryContextStats * Print statistics about the named context and all its descendants. @@ -736,6 +760,7 @@ MemoryContextCreate(MemoryContext node, node->methods = methods; node->parent = parent; node->firstchild = NULL; + node->mem_allocated = 0; node->prevchild = NULL; node->name = name; node->ident = NULL; diff --git a/src/backend/utils/mmgr/memdebug.c b/src/backend/utils/mmgr/memdebug.c index d45534d2938..8f8d72a11c3 100644 --- a/src/backend/utils/mmgr/memdebug.c +++ b/src/backend/utils/mmgr/memdebug.c @@ -5,10 +5,10 @@ * public API of the memory management subsystem. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/backend/utils/memdebug.c + * src/backend/utils/mmgr/memdebug.c * * * About CLOBBER_FREED_MEMORY: diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c index 53225d6f1b4..334e35bb6a3 100644 --- a/src/backend/utils/mmgr/portalmem.c +++ b/src/backend/utils/mmgr/portalmem.c @@ -8,7 +8,7 @@ * doesn't actually run the executor for them. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -108,8 +108,8 @@ EnablePortalManager(void) Assert(TopPortalContext == NULL); TopPortalContext = AllocSetContextCreate(TopMemoryContext, - "TopPortalContext", - ALLOCSET_DEFAULT_SIZES); + "TopPortalContext", + ALLOCSET_DEFAULT_SIZES); ctl.keysize = MAX_PORTALNAME_LEN; ctl.entrysize = sizeof(PortalHashEnt); @@ -630,8 +630,8 @@ static void HoldPortal(Portal portal) { /* - * Note that PersistHoldablePortal() must release all resources - * used by the portal that are local to the creating transaction. + * Note that PersistHoldablePortal() must release all resources used by + * the portal that are local to the creating transaction. */ PortalCreateHoldStore(portal); PersistHoldablePortal(portal); @@ -640,15 +640,15 @@ HoldPortal(Portal portal) PortalReleaseCachedPlan(portal); /* - * Any resources belonging to the portal will be released in the - * upcoming transaction-wide cleanup; the portal will no longer - * have its own resources. + * Any resources belonging to the portal will be released in the upcoming + * transaction-wide cleanup; the portal will no longer have its own + * resources. */ portal->resowner = NULL; /* - * Having successfully exported the holdable cursor, mark it as - * not belonging to this transaction. + * Having successfully exported the holdable cursor, mark it as not + * belonging to this transaction. */ portal->createSubid = InvalidSubTransactionId; portal->activeSubid = InvalidSubTransactionId; @@ -689,13 +689,23 @@ PreCommit_Portals(bool isPrepare) /* * Do not touch active portals --- this can only happen in the case of - * a multi-transaction utility command, such as VACUUM. + * a multi-transaction utility command, such as VACUUM, or a commit in + * a procedure. * * Note however that any resource owner attached to such a portal is - * still going to go away, so don't leave a dangling pointer. + * still going to go away, so don't leave a dangling pointer. Also + * unregister any snapshots held by the portal, mainly to avoid + * snapshot leak warnings from ResourceOwnerRelease(). */ if (portal->status == PORTAL_ACTIVE) { + if (portal->holdSnapshot) + { + if (portal->resowner) + UnregisterSnapshotFromOwner(portal->holdSnapshot, + portal->resowner); + portal->holdSnapshot = NULL; + } portal->resowner = NULL; continue; } @@ -1136,7 +1146,7 @@ pg_cursor(PG_FUNCTION_ARGS) * build tupdesc for result tuples. This must match the definition of the * pg_cursors view in system_views.sql */ - tupdesc = CreateTemplateTupleDesc(6, false); + tupdesc = CreateTemplateTupleDesc(6); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name", TEXTOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement", @@ -1216,13 +1226,19 @@ ThereAreNoReadyPortals(void) /* * Hold all pinned portals. * - * A procedural language implementation that uses pinned portals for its - * internally generated cursors can call this in its COMMIT command to convert - * those cursors to held cursors, so that they survive the transaction end. - * We mark those portals as "auto-held" so that exception exit knows to clean - * them up. (In normal, non-exception code paths, the PL needs to clean those - * portals itself, since transaction end won't do it anymore, but that should - * be normal practice anyway.) + * When initiating a COMMIT or ROLLBACK inside a procedure, this must be + * called to protect internally-generated cursors from being dropped during + * the transaction shutdown. Currently, SPI calls this automatically; PLs + * that initiate COMMIT or ROLLBACK some other way are on the hook to do it + * themselves. (Note that we couldn't do this in, say, AtAbort_Portals + * because we need to run user-defined code while persisting a portal. + * It's too late to do that once transaction abort has started.) + * + * We protect such portals by converting them to held cursors. We mark them + * as "auto-held" so that exception exit knows to clean them up. (In normal, + * non-exception code paths, the PL needs to clean such portals itself, since + * transaction end won't do it anymore; but that should be normal practice + * anyway.) */ void HoldPinnedPortals(void) @@ -1240,8 +1256,8 @@ HoldPinnedPortals(void) { /* * Doing transaction control, especially abort, inside a cursor - * loop that is not read-only, for example using UPDATE - * ... RETURNING, has weird semantics issues. Also, this + * loop that is not read-only, for example using UPDATE ... + * RETURNING, has weird semantics issues. Also, this * implementation wouldn't work, because such portals cannot be * held. (The core grammar enforces that only SELECT statements * can drive a cursor, but for example PL/pgSQL does not restrict @@ -1252,8 +1268,12 @@ HoldPinnedPortals(void) (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), errmsg("cannot perform transaction commands inside a cursor loop that is not read-only"))); - portal->autoHeld = true; + /* Verify it's in a suitable state to be held */ + if (portal->status != PORTAL_READY) + elog(ERROR, "pinned portal is not ready to be auto-held"); + HoldPortal(portal); + portal->autoHeld = true; } } } diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c index 26b0a156b6b..50deb354c28 100644 --- a/src/backend/utils/mmgr/slab.c +++ b/src/backend/utils/mmgr/slab.c @@ -7,7 +7,7 @@ * numbers of equally-sized objects are allocated (and freed). * * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/backend/utils/mmgr/slab.c @@ -40,7 +40,7 @@ * * For each block, we maintain pointer to the first free chunk - this is quite * cheap and allows us to skip all the preceding used chunks, eliminating - * a significant number of lookups in many common usage patters. In the worst + * a significant number of lookups in many common usage patterns. In the worst * case this performs as if the pointer was not maintained. * * We cache the freelist index for the blocks with the fewest free chunks @@ -132,8 +132,8 @@ static void SlabDelete(MemoryContext context); static Size SlabGetChunkSpace(MemoryContext context, void *pointer); static bool SlabIsEmpty(MemoryContext context); static void SlabStats(MemoryContext context, - MemoryStatsPrintFunc printfunc, void *passthru, - MemoryContextCounters *totals); + MemoryStatsPrintFunc printfunc, void *passthru, + MemoryContextCounters *totals); #ifdef MEMORY_CONTEXT_CHECKING static void SlabCheck(MemoryContext context); #endif @@ -182,7 +182,7 @@ static const MemoryContextMethods SlabMethods = { * chunkSize: allocation chunk size * * The chunkSize may not exceed: - * MAXALIGN_DOWN(SIZE_MAX) - MAXALIGN(sizeof(SlabBlock)) - SLAB_CHUNKHDRSZ + * MAXALIGN_DOWN(SIZE_MAX) - MAXALIGN(sizeof(SlabBlock)) - sizeof(SlabChunk) */ MemoryContext SlabContextCreate(MemoryContext parent, @@ -305,12 +305,14 @@ SlabReset(MemoryContext context) #endif free(block); slab->nblocks--; + context->mem_allocated -= slab->blockSize; } } slab->minFreeChunks = 0; Assert(slab->nblocks == 0); + Assert(context->mem_allocated == 0); } /* @@ -388,6 +390,7 @@ SlabAlloc(MemoryContext context, Size size) slab->minFreeChunks = slab->chunksPerBlock; slab->nblocks += 1; + context->mem_allocated += slab->blockSize; } /* grab the block from the freelist (even the new block is there) */ @@ -480,6 +483,9 @@ SlabAlloc(MemoryContext context, Size size) #endif SlabAllocInfo(slab, chunk); + + Assert(slab->nblocks * slab->blockSize == context->mem_allocated); + return SlabChunkGetPointer(chunk); } @@ -555,11 +561,13 @@ SlabFree(MemoryContext context, void *pointer) { free(block); slab->nblocks--; + context->mem_allocated -= slab->blockSize; } else dlist_push_head(&slab->freelist[block->nfree], &block->node); Assert(slab->nblocks >= 0); + Assert(slab->nblocks * slab->blockSize == context->mem_allocated); } /* @@ -782,6 +790,8 @@ SlabCheck(MemoryContext context) name, block->nfree, block, nfree); } } + + Assert(slab->nblocks * slab->blockSize == context->mem_allocated); } #endif /* MEMORY_CONTEXT_CHECKING */ diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d index ad06e8e2ea5..33ac627799c 100644 --- a/src/backend/utils/probes.d +++ b/src/backend/utils/probes.d @@ -1,7 +1,7 @@ /* ---------- * DTrace probes for PostgreSQL backend * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/backend/utils/probes.d * ---------- diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c index bce021e1001..7be11c48abe 100644 --- a/src/backend/utils/resowner/resowner.c +++ b/src/backend/utils/resowner/resowner.c @@ -9,7 +9,7 @@ * See utils/resowner/README for more info. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,10 +20,12 @@ */ #include "postgres.h" -#include "access/hash.h" #include "jit/jit.h" +#include "storage/bufmgr.h" +#include "storage/ipc.h" #include "storage/predicate.h" #include "storage/proc.h" +#include "utils/hashutils.h" #include "utils/memutils.h" #include "utils/rel.h" #include "utils/resowner_private.h" @@ -140,6 +142,7 @@ typedef struct ResourceOwnerData ResourceOwner CurrentResourceOwner = NULL; ResourceOwner CurTransactionResourceOwner = NULL; ResourceOwner TopTransactionResourceOwner = NULL; +ResourceOwner AuxProcessResourceOwner = NULL; /* * List of add-on callbacks for resource releasing @@ -162,9 +165,10 @@ static bool ResourceArrayRemove(ResourceArray *resarr, Datum value); static bool ResourceArrayGetAny(ResourceArray *resarr, Datum *value); static void ResourceArrayFree(ResourceArray *resarr); static void ResourceOwnerReleaseInternal(ResourceOwner owner, - ResourceReleasePhase phase, - bool isCommit, - bool isTopLevel); + ResourceReleasePhase phase, + bool isCommit, + bool isTopLevel); +static void ReleaseAuxProcessResourcesCallback(int code, Datum arg); static void PrintRelCacheLeakWarning(Relation rel); static void PrintPlanCacheLeakWarning(CachedPlan *plan); static void PrintTupleDescLeakWarning(TupleDesc tupdesc); @@ -562,7 +566,7 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, if (owner == TopTransactionResourceOwner) { ProcReleaseLocks(isCommit); - ReleasePredicateLocks(isCommit); + ReleasePredicateLocks(isCommit, false); } } else @@ -823,6 +827,60 @@ UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg) } } +/* + * Establish an AuxProcessResourceOwner for the current process. + */ +void +CreateAuxProcessResourceOwner(void) +{ + Assert(AuxProcessResourceOwner == NULL); + Assert(CurrentResourceOwner == NULL); + AuxProcessResourceOwner = ResourceOwnerCreate(NULL, "AuxiliaryProcess"); + CurrentResourceOwner = AuxProcessResourceOwner; + + /* + * Register a shmem-exit callback for cleanup of aux-process resource + * owner. (This needs to run after, e.g., ShutdownXLOG.) + */ + on_shmem_exit(ReleaseAuxProcessResourcesCallback, 0); + +} + +/* + * Convenience routine to release all resources tracked in + * AuxProcessResourceOwner (but that resowner is not destroyed here). + * Warn about leaked resources if isCommit is true. + */ +void +ReleaseAuxProcessResources(bool isCommit) +{ + /* + * At this writing, the only thing that could actually get released is + * buffer pins; but we may as well do the full release protocol. + */ + ResourceOwnerRelease(AuxProcessResourceOwner, + RESOURCE_RELEASE_BEFORE_LOCKS, + isCommit, true); + ResourceOwnerRelease(AuxProcessResourceOwner, + RESOURCE_RELEASE_LOCKS, + isCommit, true); + ResourceOwnerRelease(AuxProcessResourceOwner, + RESOURCE_RELEASE_AFTER_LOCKS, + isCommit, true); +} + +/* + * Shmem-exit callback for the same. + * Warn about leaked resources if process exit code is zero (ie normal). + */ +static void +ReleaseAuxProcessResourcesCallback(int code, Datum arg) +{ + bool isCommit = (code == 0); + + ReleaseAuxProcessResources(isCommit); +} + /* * Make sure there is room for at least one more entry in a ResourceOwner's @@ -830,15 +888,12 @@ UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg) * * This is separate from actually inserting an entry because if we run out * of memory, it's critical to do so *before* acquiring the resource. - * - * We allow the case owner == NULL because the bufmgr is sometimes invoked - * outside any transaction (for example, during WAL recovery). */ void ResourceOwnerEnlargeBuffers(ResourceOwner owner) { - if (owner == NULL) - return; + /* We used to allow pinning buffers without a resowner, but no more */ + Assert(owner != NULL); ResourceArrayEnlarge(&(owner->bufferarr)); } @@ -846,29 +901,19 @@ ResourceOwnerEnlargeBuffers(ResourceOwner owner) * Remember that a buffer pin is owned by a ResourceOwner * * Caller must have previously done ResourceOwnerEnlargeBuffers() - * - * We allow the case owner == NULL because the bufmgr is sometimes invoked - * outside any transaction (for example, during WAL recovery). */ void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer) { - if (owner == NULL) - return; ResourceArrayAdd(&(owner->bufferarr), BufferGetDatum(buffer)); } /* * Forget that a buffer pin is owned by a ResourceOwner - * - * We allow the case owner == NULL because the bufmgr is sometimes invoked - * outside any transaction (for example, during WAL recovery). */ void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer) { - if (owner == NULL) - return; if (!ResourceArrayRemove(&(owner->bufferarr), BufferGetDatum(buffer))) elog(ERROR, "buffer %d is not owned by resource owner %s", buffer, owner->name); diff --git a/src/backend/utils/sort/gen_qsort_tuple.pl b/src/backend/utils/sort/gen_qsort_tuple.pl index 6186d0a5bab..b6b2ffa7d0b 100644 --- a/src/backend/utils/sort/gen_qsort_tuple.pl +++ b/src/backend/utils/sort/gen_qsort_tuple.pl @@ -130,6 +130,8 @@ sub emit_qsort_boilerplate #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n) EOM + + return; } sub emit_qsort_implementation @@ -263,4 +265,6 @@ sub emit_qsort_implementation } } EOM + + return; } diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 05dde631ddc..8985b9e0955 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -47,8 +47,7 @@ * * To further make the I/Os more sequential, we can use a larger buffer * when reading, and read multiple blocks from the same tape in one go, - * whenever the buffer becomes empty. LogicalTapeAssignReadBufferSize() - * can be used to set the size of the read buffer. + * whenever the buffer becomes empty. * * To support the above policy of writing to the lowest free block, * ltsGetFreeBlock sorts the list of free block numbers into decreasing @@ -72,7 +71,7 @@ * There will always be the same number of runs as input tapes, and the same * number of input tapes as participants (worker Tuplesortstates). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -211,7 +210,7 @@ static void ltsReadBlock(LogicalTapeSet *lts, long blocknum, void *buffer); static long ltsGetFreeBlock(LogicalTapeSet *lts); static void ltsReleaseBlock(LogicalTapeSet *lts, long blocknum); static void ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, - SharedFileSet *fileset); + SharedFileSet *fileset); /* @@ -241,11 +240,11 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, void *buffer) */ while (blocknum > lts->nBlocksWritten) { - char zerobuf[BLCKSZ]; + PGAlignedBlock zerobuf; - MemSet(zerobuf, 0, sizeof(zerobuf)); + MemSet(zerobuf.data, 0, sizeof(zerobuf)); - ltsWriteBlock(lts, lts->nBlocksWritten, zerobuf); + ltsWriteBlock(lts, lts->nBlocksWritten, zerobuf.data); } /* Write the requested block */ @@ -427,11 +426,13 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, { char filename[MAXPGPATH]; BufFile *file; + int64 filesize; lt = <s->tapes[i]; pg_itoa(i, filename); file = BufFileOpenShared(fileset, filename); + filesize = BufFileSize(file); /* * Stash first BufFile, and concatenate subsequent BufFiles to that. @@ -448,8 +449,8 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, lt->offsetBlockNumber = BufFileAppend(lts->pfile, file); } /* Don't allocate more for read buffer than could possibly help */ - lt->max_size = Min(MaxAllocSize, shared[i].buffilesize); - tapeblocks = shared[i].buffilesize / BLCKSZ; + lt->max_size = Min(MaxAllocSize, filesize); + tapeblocks = filesize / BLCKSZ; nphysicalblocks += tapeblocks; } @@ -466,7 +467,7 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, * Compute number of hole blocks so that we can later work backwards, and * instrument number of physical blocks. We don't simply use physical * blocks directly for instrumentation because this would break if we ever - * subsequently wrote to worker tape. + * subsequently wrote to the leader tape. * * Working backwards like this keeps our options open. If shared BufFiles * ever support being written to post-export, logtape.c can automatically @@ -939,7 +940,6 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, TapeShare *share) { BufFileExportShared(lts->pfile); share->firstblocknumber = lt->firstBlockNumber; - share->buffilesize = BufFileSize(lts->pfile); } } diff --git a/src/backend/utils/sort/sharedtuplestore.c b/src/backend/utils/sort/sharedtuplestore.c index 3e47fbde8e7..7765a445c0c 100644 --- a/src/backend/utils/sort/sharedtuplestore.c +++ b/src/backend/utils/sort/sharedtuplestore.c @@ -10,11 +10,11 @@ * scan where each backend reads an arbitrary subset of the tuples that were * written. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * src/backend/util/sort/sharedtuplestore.c + * src/backend/utils/sort/sharedtuplestore.c * *------------------------------------------------------------------------- */ @@ -29,8 +29,6 @@ #include "storage/sharedfileset.h" #include "utils/sharedtuplestore.h" -#include - /* * The size of chunks, in pages. This is somewhat arbitrarily set to match * the size of HASH_CHUNK, so that Parallel Hash obtains new chunks of tuples @@ -47,7 +45,7 @@ typedef struct SharedTuplestoreChunk int ntuples; /* Number of tuples in this chunk. */ int overflow; /* If overflow, how many including this one? */ char data[FLEXIBLE_ARRAY_MEMBER]; -} SharedTuplestoreChunk; +} SharedTuplestoreChunk; /* Per-participant shared state. */ typedef struct SharedTuplestoreParticipant @@ -56,7 +54,7 @@ typedef struct SharedTuplestoreParticipant BlockNumber read_page; /* Page number for next read. */ BlockNumber npages; /* Number of pages written. */ bool writing; /* Used only for assertions. */ -} SharedTuplestoreParticipant; +} SharedTuplestoreParticipant; /* The control object that lives in shared memory. */ struct SharedTuplestore @@ -97,7 +95,7 @@ struct SharedTuplestoreAccessor }; static void sts_filename(char *name, SharedTuplestoreAccessor *accessor, - int participant); + int participant); /* * Return the amount of shared memory required to hold SharedTuplestore for a @@ -173,7 +171,7 @@ sts_initialize(SharedTuplestore *sts, int participants, } /* - * Attach to a SharedTupleStore that has been initialized by another backend, + * Attach to a SharedTuplestore that has been initialized by another backend, * so that this backend can read and write tuples. */ SharedTuplestoreAccessor * diff --git a/src/backend/utils/sort/sortsupport.c b/src/backend/utils/sort/sortsupport.c index 8c09fe4a430..9a771214dc2 100644 --- a/src/backend/utils/sort/sortsupport.c +++ b/src/backend/utils/sort/sortsupport.c @@ -4,7 +4,7 @@ * Support routines for accelerated sorting. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -26,16 +26,17 @@ /* Info needed to use an old-style comparison function as a sort comparator */ typedef struct { - FunctionCallInfoData fcinfo; /* reusable callinfo structure */ FmgrInfo flinfo; /* lookup data for comparison function */ + FunctionCallInfoBaseData fcinfo; /* reusable callinfo structure */ } SortShimExtra; +#define SizeForSortShimExtra(nargs) (offsetof(SortShimExtra, fcinfo) + SizeForFunctionCallInfo(nargs)) /* * Shim function for calling an old-style comparator * * This is essentially an inlined version of FunctionCall2Coll(), except - * we assume that the FunctionCallInfoData was already mostly set up by + * we assume that the FunctionCallInfoBaseData was already mostly set up by * PrepareSortSupportComparisonShim. */ static int @@ -44,8 +45,8 @@ comparison_shim(Datum x, Datum y, SortSupport ssup) SortShimExtra *extra = (SortShimExtra *) ssup->ssup_extra; Datum result; - extra->fcinfo.arg[0] = x; - extra->fcinfo.arg[1] = y; + extra->fcinfo.args[0].value = x; + extra->fcinfo.args[1].value = y; /* just for paranoia's sake, we reset isnull each time */ extra->fcinfo.isnull = false; @@ -69,7 +70,7 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup) SortShimExtra *extra; extra = (SortShimExtra *) MemoryContextAlloc(ssup->ssup_cxt, - sizeof(SortShimExtra)); + SizeForSortShimExtra(2)); /* Lookup the comparison function */ fmgr_info_cxt(cmpFunc, &extra->flinfo, ssup->ssup_cxt); @@ -77,8 +78,8 @@ PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup) /* We can initialize the callinfo just once and re-use it */ InitFunctionCallInfoData(extra->fcinfo, &extra->flinfo, 2, ssup->ssup_collation, NULL, NULL); - extra->fcinfo.argnull[0] = false; - extra->fcinfo.argnull[1] = false; + extra->fcinfo.args[0].isnull = false; + extra->fcinfo.args[1].isnull = false; ssup->ssup_extra = extra; ssup->comparator = comparison_shim; diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index a0c0d6f701a..ab55e69975c 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -83,7 +83,7 @@ * produce exactly one output run from their partial input. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -96,9 +96,9 @@ #include +#include "access/hash.h" #include "access/htup_details.h" #include "access/nbtree.h" -#include "access/hash.h" #include "catalog/index.h" #include "catalog/pg_am.h" #include "commands/tablespace.h" @@ -141,7 +141,8 @@ bool optimize_bounded_sort = true; * which is a separate palloc chunk --- we assume it is just one chunk and * can be freed by a simple pfree() (except during merge, when we use a * simple slab allocator). SortTuples also contain the tuple's first key - * column in Datum/nullflag format, and an index integer. + * column in Datum/nullflag format, and a source/input tape number that + * tracks which tape each heap element/slot belongs to during merging. * * Storing the first key column lets us save heap_getattr or index_getattr * calls during tuple comparisons. We could extract and save all the key @@ -162,16 +163,13 @@ bool optimize_bounded_sort = true; * either the same pointer as "tuple", or is an abbreviated key value as * described above. Accordingly, "tuple" is always used in preference to * datum1 as the authoritative value for pass-by-reference cases. - * - * tupindex holds the input tape number that each tuple in the heap was read - * from during merge passes. */ typedef struct { void *tuple; /* the tuple itself */ Datum datum1; /* value of first key column */ bool isnull1; /* is first key column NULL? */ - int tupindex; /* see notes above */ + int srctape; /* source tape number */ } SortTuple; /* @@ -574,10 +572,12 @@ struct Sharedsort * a lot better than what we were doing before 7.3. As of 9.6, a * separate memory context is used for caller passed tuples. Resetting * it at certain key increments significantly ameliorates fragmentation. - * Note that this places a responsibility on readtup and copytup routines - * to use the right memory context for these tuples (and to not use the - * reset context for anything whose lifetime needs to span multiple - * external sort runs). + * Note that this places a responsibility on copytup routines to use the + * correct memory context for these tuples (and to not use the reset + * context for anything whose lifetime needs to span multiple external + * sort runs). readtup routines use the slab allocator (they cannot use + * the reset context because it gets deleted at the point that merging + * begins). */ /* When using this macro, beware of double evaluation of len */ @@ -589,8 +589,8 @@ struct Sharedsort static Tuplesortstate *tuplesort_begin_common(int workMem, - SortCoordinate coordinate, - bool randomAccess); + SortCoordinate coordinate, + bool randomAccess); static void puttuple_common(Tuplesortstate *state, SortTuple *tuple); static bool consider_abort_common(Tuplesortstate *state); static void inittapes(Tuplesortstate *state, bool mergeruns); @@ -612,36 +612,36 @@ static void reversedirection(Tuplesortstate *state); static unsigned int getlen(Tuplesortstate *state, int tapenum, bool eofOK); static void markrunend(Tuplesortstate *state, int tapenum); static void *readtup_alloc(Tuplesortstate *state, Size tuplen); -static int comparetup_heap(const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); +static int comparetup_heap(const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); static void copytup_heap(Tuplesortstate *state, SortTuple *stup, void *tup); static void writetup_heap(Tuplesortstate *state, int tapenum, - SortTuple *stup); + SortTuple *stup); static void readtup_heap(Tuplesortstate *state, SortTuple *stup, - int tapenum, unsigned int len); -static int comparetup_cluster(const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); + int tapenum, unsigned int len); +static int comparetup_cluster(const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); static void copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup); static void writetup_cluster(Tuplesortstate *state, int tapenum, - SortTuple *stup); + SortTuple *stup); static void readtup_cluster(Tuplesortstate *state, SortTuple *stup, - int tapenum, unsigned int len); -static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); -static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); + int tapenum, unsigned int len); +static int comparetup_index_btree(const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); +static int comparetup_index_hash(const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); static void copytup_index(Tuplesortstate *state, SortTuple *stup, void *tup); static void writetup_index(Tuplesortstate *state, int tapenum, - SortTuple *stup); + SortTuple *stup); static void readtup_index(Tuplesortstate *state, SortTuple *stup, - int tapenum, unsigned int len); -static int comparetup_datum(const SortTuple *a, const SortTuple *b, - Tuplesortstate *state); + int tapenum, unsigned int len); +static int comparetup_datum(const SortTuple *a, const SortTuple *b, + Tuplesortstate *state); static void copytup_datum(Tuplesortstate *state, SortTuple *stup, void *tup); static void writetup_datum(Tuplesortstate *state, int tapenum, - SortTuple *stup); + SortTuple *stup); static void readtup_datum(Tuplesortstate *state, SortTuple *stup, - int tapenum, unsigned int len); + int tapenum, unsigned int len); static int worker_get_identifier(Tuplesortstate *state); static void worker_freeze_result_tape(Tuplesortstate *state); static void worker_nomergeruns(Tuplesortstate *state); @@ -884,7 +884,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, { Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate, randomAccess); - ScanKey indexScanKey; + BTScanInsert indexScanKey; MemoryContext oldcontext; int i; @@ -919,7 +919,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, state->tupDesc = tupDesc; /* assume we need not copy tupDesc */ - indexScanKey = _bt_mkscankey_nodata(indexRel); + indexScanKey = _bt_mkscankey(indexRel, NULL); if (state->indexInfo->ii_Expressions != NULL) { @@ -933,7 +933,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, * scantuple has to point to that slot, too. */ state->estate = CreateExecutorState(); - slot = MakeSingleTupleTableSlot(tupDesc); + slot = MakeSingleTupleTableSlot(tupDesc, &TTSOpsVirtual); econtext = GetPerTupleExprContext(state->estate); econtext->ecxt_scantuple = slot; } @@ -945,7 +945,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, for (i = 0; i < state->nKeys; i++) { SortSupport sortKey = state->sortKeys + i; - ScanKey scanKey = indexScanKey + i; + ScanKey scanKey = indexScanKey->scankeys + i; int16 strategy; sortKey->ssup_cxt = CurrentMemoryContext; @@ -964,7 +964,7 @@ tuplesort_begin_cluster(TupleDesc tupDesc, PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey); } - _bt_freeskey(indexScanKey); + pfree(indexScanKey); MemoryContextSwitchTo(oldcontext); @@ -981,7 +981,7 @@ tuplesort_begin_index_btree(Relation heapRel, { Tuplesortstate *state = tuplesort_begin_common(workMem, coordinate, randomAccess); - ScanKey indexScanKey; + BTScanInsert indexScanKey; MemoryContext oldcontext; int i; @@ -1014,7 +1014,7 @@ tuplesort_begin_index_btree(Relation heapRel, state->indexRel = indexRel; state->enforceUnique = enforceUnique; - indexScanKey = _bt_mkscankey_nodata(indexRel); + indexScanKey = _bt_mkscankey(indexRel, NULL); /* Prepare SortSupport data for each column */ state->sortKeys = (SortSupport) palloc0(state->nKeys * @@ -1023,7 +1023,7 @@ tuplesort_begin_index_btree(Relation heapRel, for (i = 0; i < state->nKeys; i++) { SortSupport sortKey = state->sortKeys + i; - ScanKey scanKey = indexScanKey + i; + ScanKey scanKey = indexScanKey->scankeys + i; int16 strategy; sortKey->ssup_cxt = CurrentMemoryContext; @@ -1042,7 +1042,7 @@ tuplesort_begin_index_btree(Relation heapRel, PrepareSortSupportFromIndexRel(indexRel, strategy, sortKey); } - _bt_freeskey(indexScanKey); + pfree(indexScanKey); MemoryContextSwitchTo(oldcontext); @@ -1148,9 +1148,9 @@ tuplesort_begin_datum(Oid datumType, Oid sortOperator, Oid sortCollation, * Abbreviation is possible here only for by-reference types. In theory, * a pass-by-value datatype could have an abbreviated form that is cheaper * to compare. In a tuple sort, we could support that, because we can - * always extract the original datum from the tuple is needed. Here, we + * always extract the original datum from the tuple as needed. Here, we * can't, because a datum sort only stores a single copy of the datum; the - * "tuple" field of each sortTuple is NULL. + * "tuple" field of each SortTuple is NULL. */ state->sortKeys->abbreviate = !typbyval; @@ -1186,21 +1186,22 @@ void tuplesort_set_bound(Tuplesortstate *state, int64 bound) { /* Assert we're called before loading any tuples */ - Assert(state->status == TSS_INITIAL); - Assert(state->memtupcount == 0); + Assert(state->status == TSS_INITIAL && state->memtupcount == 0); + /* Can't set the bound twice, either */ Assert(!state->bounded); + /* Also, this shouldn't be called in a parallel worker */ Assert(!WORKER(state)); + /* Parallel leader allows but ignores hint */ + if (LEADER(state)) + return; + #ifdef DEBUG_BOUNDED_SORT /* Honor GUC setting that disables the feature (for easy testing) */ if (!optimize_bounded_sort) return; #endif - /* Parallel leader ignores hint */ - if (LEADER(state)) - return; - /* We want to be able to compute bound * 2, so limit the setting */ if (bound > (int64) (INT_MAX / 2)) return; @@ -1259,11 +1260,11 @@ tuplesort_end(Tuplesortstate *state) if (trace_sort) { if (state->tapeset) - elog(LOG, "%s of %d ended, %ld disk blocks used: %s", + elog(LOG, "%s of worker %d ended, %ld disk blocks used: %s", SERIAL(state) ? "external sort" : "parallel external sort", state->worker, spaceUsed, pg_rusage_show(&state->ru_start)); else - elog(LOG, "%s of %d ended, %ld KB used: %s", + elog(LOG, "%s of worker %d ended, %ld KB used: %s", SERIAL(state) ? "internal sort" : "unperformed parallel sort", state->worker, spaceUsed, pg_rusage_show(&state->ru_start)); } @@ -1793,7 +1794,7 @@ tuplesort_performsort(Tuplesortstate *state) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "performsort of %d starting: %s", + elog(LOG, "performsort of worker %d starting: %s", state->worker, pg_rusage_show(&state->ru_start)); #endif @@ -1878,11 +1879,11 @@ tuplesort_performsort(Tuplesortstate *state) if (trace_sort) { if (state->status == TSS_FINALMERGE) - elog(LOG, "performsort of %d done (except %d-way final merge): %s", + elog(LOG, "performsort of worker %d done (except %d-way final merge): %s", state->worker, state->activeTapes, pg_rusage_show(&state->ru_start)); else - elog(LOG, "performsort of %d done: %s", + elog(LOG, "performsort of worker %d done: %s", state->worker, pg_rusage_show(&state->ru_start)); } #endif @@ -2091,7 +2092,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward, */ if (state->memtupcount > 0) { - int srcTape = state->memtuples[0].tupindex; + int srcTape = state->memtuples[0].srctape; SortTuple newtup; *stup = state->memtuples[0]; @@ -2122,7 +2123,7 @@ tuplesort_gettuple_common(Tuplesortstate *state, bool forward, LogicalTapeRewindForWrite(state->tapeset, srcTape); return true; } - newtup.tupindex = srcTape; + newtup.srctape = srcTape; tuplesort_heap_replace_top(state, &newtup); return true; } @@ -2410,7 +2411,7 @@ inittapes(Tuplesortstate *state, bool mergeruns) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d switching to external sort with %d tapes: %s", + elog(LOG, "worker %d switching to external sort with %d tapes: %s", state->worker, maxTapes, pg_rusage_show(&state->ru_start)); #endif @@ -2660,7 +2661,7 @@ mergeruns(Tuplesortstate *state) */ #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d using " INT64_FORMAT " KB of memory for read buffers among %d input tapes", + elog(LOG, "worker %d using " INT64_FORMAT " KB of memory for read buffers among %d input tapes", state->worker, state->availMem / 1024, numInputTapes); #endif @@ -2806,7 +2807,7 @@ mergeonerun(Tuplesortstate *state) SortTuple stup; /* write the tuple to destTape */ - srcTape = state->memtuples[0].tupindex; + srcTape = state->memtuples[0].srctape; WRITETUP(state, destTape, &state->memtuples[0]); /* recycle the slot of the tuple we just wrote out, for the next read */ @@ -2819,9 +2820,8 @@ mergeonerun(Tuplesortstate *state) */ if (mergereadnext(state, srcTape, &stup)) { - stup.tupindex = srcTape; + stup.srctape = srcTape; tuplesort_heap_replace_top(state, &stup); - } else tuplesort_heap_delete_top(state); @@ -2836,7 +2836,7 @@ mergeonerun(Tuplesortstate *state) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d finished %d-way merge step: %s", state->worker, + elog(LOG, "worker %d finished %d-way merge step: %s", state->worker, state->activeTapes, pg_rusage_show(&state->ru_start)); #endif } @@ -2885,7 +2885,7 @@ beginmerge(Tuplesortstate *state) if (mergereadnext(state, srcTape, &tup)) { - tup.tupindex = srcTape; + tup.srctape = srcTape; tuplesort_heap_insert(state, &tup); } } @@ -2971,7 +2971,7 @@ dumptuples(Tuplesortstate *state, bool alltuples) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d starting quicksort of run %d: %s", + elog(LOG, "worker %d starting quicksort of run %d: %s", state->worker, state->currentRun, pg_rusage_show(&state->ru_start)); #endif @@ -2984,7 +2984,7 @@ dumptuples(Tuplesortstate *state, bool alltuples) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d finished quicksort of run %d: %s", + elog(LOG, "worker %d finished quicksort of run %d: %s", state->worker, state->currentRun, pg_rusage_show(&state->ru_start)); #endif @@ -3012,7 +3012,7 @@ dumptuples(Tuplesortstate *state, bool alltuples) #ifdef TRACE_SORT if (trace_sort) - elog(LOG, "%d finished writing run %d to tape %d: %s", + elog(LOG, "worker %d finished writing run %d to tape %d: %s", state->worker, state->currentRun, state->destTape, pg_rusage_show(&state->ru_start)); #endif @@ -3718,7 +3718,7 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b, datum2; bool isnull1, isnull2; - AttrNumber leading = state->indexInfo->ii_KeyAttrNumbers[0]; + AttrNumber leading = state->indexInfo->ii_IndexAttrNumbers[0]; /* Be prepared to compare additional sort keys */ ltup = (HeapTuple) a->tuple; @@ -3761,7 +3761,7 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b, for (; nkey < state->nKeys; nkey++, sortKey++) { - AttrNumber attno = state->indexInfo->ii_KeyAttrNumbers[nkey]; + AttrNumber attno = state->indexInfo->ii_IndexAttrNumbers[nkey]; datum1 = heap_getattr(ltup, attno, tupDesc, &isnull1); datum2 = heap_getattr(rtup, attno, tupDesc, &isnull2); @@ -3792,11 +3792,11 @@ comparetup_cluster(const SortTuple *a, const SortTuple *b, ecxt_scantuple = GetPerTupleExprContext(state->estate)->ecxt_scantuple; - ExecStoreTuple(ltup, ecxt_scantuple, InvalidBuffer, false); + ExecStoreHeapTuple(ltup, ecxt_scantuple, false); FormIndexDatum(state->indexInfo, ecxt_scantuple, state->estate, l_index_values, l_index_isnull); - ExecStoreTuple(rtup, ecxt_scantuple, InvalidBuffer, false); + ExecStoreHeapTuple(rtup, ecxt_scantuple, false); FormIndexDatum(state->indexInfo, ecxt_scantuple, state->estate, r_index_values, r_index_isnull); @@ -3833,11 +3833,11 @@ copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup) * set up first-column key value, and potentially abbreviate, if it's a * simple column */ - if (state->indexInfo->ii_KeyAttrNumbers[0] == 0) + if (state->indexInfo->ii_IndexAttrNumbers[0] == 0) return; original = heap_getattr(tuple, - state->indexInfo->ii_KeyAttrNumbers[0], + state->indexInfo->ii_IndexAttrNumbers[0], state->tupDesc, &stup->isnull1); @@ -3881,7 +3881,7 @@ copytup_cluster(Tuplesortstate *state, SortTuple *stup, void *tup) tuple = (HeapTuple) mtup->tuple; mtup->datum1 = heap_getattr(tuple, - state->indexInfo->ii_KeyAttrNumbers[0], + state->indexInfo->ii_IndexAttrNumbers[0], state->tupDesc, &mtup->isnull1); } @@ -3935,9 +3935,9 @@ readtup_cluster(Tuplesortstate *state, SortTuple *stup, &tuplen, sizeof(tuplen)); stup->tuple = (void *) tuple; /* set up first-column key value, if it's a simple column */ - if (state->indexInfo->ii_KeyAttrNumbers[0] != 0) + if (state->indexInfo->ii_IndexAttrNumbers[0] != 0) stup->datum1 = heap_getattr(tuple, - state->indexInfo->ii_KeyAttrNumbers[0], + state->indexInfo->ii_IndexAttrNumbers[0], state->tupDesc, &stup->isnull1); } @@ -4057,9 +4057,10 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, } /* - * If key values are equal, we sort on ItemPointer. This does not affect - * validity of the finished index, but it may be useful to have index - * scans in physical order. + * If key values are equal, we sort on ItemPointer. This is required for + * btree indexes, since heap TID is treated as an implicit last key + * attribute in order to ensure that all keys in the index are physically + * unique. */ { BlockNumber blk1 = ItemPointerGetBlockNumber(&tuple1->t_tid); @@ -4076,6 +4077,9 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b, return (pos1 < pos2) ? -1 : 1; } + /* ItemPointer values should never be equal */ + Assert(false); + return 0; } @@ -4128,6 +4132,9 @@ comparetup_index_hash(const SortTuple *a, const SortTuple *b, return (pos1 < pos2) ? -1 : 1; } + /* ItemPointer values should never be equal */ + Assert(false); + return 0; } @@ -4395,7 +4402,6 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg) for (i = 0; i < nWorkers; i++) { shared->tapes[i].firstblocknumber = 0L; - shared->tapes[i].buffilesize = 0; } } diff --git a/src/backend/utils/sort/tuplestore.c b/src/backend/utils/sort/tuplestore.c index d602753ca96..3fc7f921821 100644 --- a/src/backend/utils/sort/tuplestore.c +++ b/src/backend/utils/sort/tuplestore.c @@ -43,7 +43,7 @@ * before switching to the other state or activating a different read pointer. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -234,8 +234,8 @@ struct Tuplestorestate static Tuplestorestate *tuplestore_begin_common(int eflags, - bool interXact, - int maxKBytes); + bool interXact, + int maxKBytes); static void tuplestore_puttuple_common(Tuplestorestate *state, void *tuple); static void dumptuples(Tuplestorestate *state); static unsigned int getlen(Tuplestorestate *state, bool eofOK); @@ -972,7 +972,7 @@ tuplestore_gettuple(Tuplestorestate *state, bool forward, (errcode_for_file_access(), errmsg("could not seek in tuplestore temporary file: %m"))); state->status = TSS_READFILE; - /* FALL THRU into READFILE case */ + /* FALLTHROUGH */ case TSS_READFILE: *should_free = true; diff --git a/src/backend/utils/time/Makefile b/src/backend/utils/time/Makefile index 5a6e6fa4c8e..f17b1c53249 100644 --- a/src/backend/utils/time/Makefile +++ b/src/backend/utils/time/Makefile @@ -12,6 +12,6 @@ subdir = src/backend/utils/time top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = combocid.o tqual.o snapmgr.o +OBJS = combocid.o snapmgr.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/time/combocid.c b/src/backend/utils/time/combocid.c index d789f02bfa7..deb9af5ee7a 100644 --- a/src/backend/utils/time/combocid.c +++ b/src/backend/utils/time/combocid.c @@ -30,7 +30,7 @@ * destroyed at the end of each transaction. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c index 4b45d3cccd2..47b0517596e 100644 --- a/src/backend/utils/time/snapmgr.c +++ b/src/backend/utils/time/snapmgr.c @@ -35,7 +35,7 @@ * stack is empty. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -48,6 +48,7 @@ #include #include +#include "access/subtrans.h" #include "access/transam.h" #include "access/xact.h" #include "access/xlog.h" @@ -66,7 +67,6 @@ #include "utils/resowner_private.h" #include "utils/snapmgr.h" #include "utils/syscache.h" -#include "utils/tqual.h" /* @@ -141,9 +141,11 @@ static volatile OldSnapshotControlData *oldSnapshotControl; * These SnapshotData structs are static to simplify memory allocation * (see the hack in GetSnapshotData to avoid repeated malloc/free). */ -static SnapshotData CurrentSnapshotData = {HeapTupleSatisfiesMVCC}; -static SnapshotData SecondarySnapshotData = {HeapTupleSatisfiesMVCC}; -SnapshotData CatalogSnapshotData = {HeapTupleSatisfiesMVCC}; +static SnapshotData CurrentSnapshotData = {SNAPSHOT_MVCC}; +static SnapshotData SecondarySnapshotData = {SNAPSHOT_MVCC}; +SnapshotData CatalogSnapshotData = {SNAPSHOT_MVCC}; +SnapshotData SnapshotSelfData = {SNAPSHOT_SELF}; +SnapshotData SnapshotAnyData = {SNAPSHOT_ANY}; /* Pointers to valid snapshots */ static Snapshot CurrentSnapshot = NULL; @@ -194,8 +196,8 @@ static ActiveSnapshotElt *OldestActiveSnapshot = NULL; * Currently registered Snapshots. Ordered in a heap by xmin, so that we can * quickly find the one with lowest xmin, to advance our MyPgXact->xmin. */ -static int xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, - void *arg); +static int xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, + void *arg); static pairingheap RegisteredSnapshots = {&xmin_cmp, NULL, NULL}; @@ -954,6 +956,36 @@ xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg) return 0; } +/* + * Get current RecentGlobalXmin value, as a FullTransactionId. + */ +FullTransactionId +GetFullRecentGlobalXmin(void) +{ + FullTransactionId nextxid_full; + uint32 nextxid_epoch; + TransactionId nextxid_xid; + uint32 epoch; + + Assert(TransactionIdIsNormal(RecentGlobalXmin)); + + /* + * Compute the epoch from the next XID's epoch. This relies on the fact + * that RecentGlobalXmin must be within the 2 billion XID horizon from the + * next XID. + */ + nextxid_full = ReadNextFullTransactionId(); + nextxid_epoch = EpochFromFullTransactionId(nextxid_full); + nextxid_xid = XidFromFullTransactionId(nextxid_full); + + if (RecentGlobalXmin > nextxid_xid) + epoch = nextxid_epoch - 1; + else + epoch = nextxid_epoch; + + return FullTransactionIdFromEpochAndXid(epoch, RecentGlobalXmin); +} + /* * SnapshotResetXmin * @@ -1087,11 +1119,11 @@ AtEOXact_Snapshot(bool isCommit, bool resetXmin) * it's too late to abort the transaction, and (2) leaving a leaked * file around has little real consequence anyway. * - * We also also need to remove the snapshots from RegisteredSnapshots - * to prevent a warning below. + * We also need to remove the snapshots from RegisteredSnapshots to + * prevent a warning below. * * As with the FirstXactSnapshot, we don't need to free resources of - * the snapshot iself as it will go away with the memory context. + * the snapshot itself as it will go away with the memory context. */ foreach(lc, exportedSnapshots) { @@ -1139,7 +1171,7 @@ AtEOXact_Snapshot(bool isCommit, bool resetXmin) /* * During normal commit processing, we call ProcArrayEndTransaction() to - * reset the PgXact->xmin. That call happens prior to the call to + * reset the MyPgXact->xmin. That call happens prior to the call to * AtEOXact_Snapshot(), so we need not touch xmin here at all. */ if (resetXmin) @@ -1507,6 +1539,8 @@ ImportSnapshot(const char *idstr) src_isolevel = parseIntFromText("iso:", &filebuf, path); src_readonly = parseIntFromText("ro:", &filebuf, path); + snapshot.snapshot_type = SNAPSHOT_MVCC; + snapshot.xmin = parseXidFromText("xmin:", &filebuf, path); snapshot.xmax = parseXidFromText("xmax:", &filebuf, path); @@ -2046,7 +2080,7 @@ EstimateSnapshotSpace(Snapshot snap) Size size; Assert(snap != InvalidSnapshot); - Assert(snap->satisfies == HeapTupleSatisfiesMVCC); + Assert(snap->snapshot_type == SNAPSHOT_MVCC); /* We allocate any XID arrays needed in the same palloc block. */ size = add_size(sizeof(SerializedSnapshotData), @@ -2143,7 +2177,7 @@ RestoreSnapshot(char *start_address) /* Copy all required fields */ snapshot = (Snapshot) MemoryContextAlloc(TopTransactionContext, size); - snapshot->satisfies = HeapTupleSatisfiesMVCC; + snapshot->snapshot_type = SNAPSHOT_MVCC; snapshot->xmin = serialized_snapshot.xmin; snapshot->xmax = serialized_snapshot.xmax; snapshot->xip = NULL; @@ -2192,3 +2226,125 @@ RestoreTransactionSnapshot(Snapshot snapshot, void *master_pgproc) { SetTransactionSnapshot(snapshot, NULL, InvalidPid, master_pgproc); } + +/* + * XidInMVCCSnapshot + * Is the given XID still-in-progress according to the snapshot? + * + * Note: GetSnapshotData never stores either top xid or subxids of our own + * backend into a snapshot, so these xids will not be reported as "running" + * by this function. This is OK for current uses, because we always check + * TransactionIdIsCurrentTransactionId first, except when it's known the + * XID could not be ours anyway. + */ +bool +XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot) +{ + uint32 i; + + /* + * Make a quick range check to eliminate most XIDs without looking at the + * xip arrays. Note that this is OK even if we convert a subxact XID to + * its parent below, because a subxact with XID < xmin has surely also got + * a parent with XID < xmin, while one with XID >= xmax must belong to a + * parent that was not yet committed at the time of this snapshot. + */ + + /* Any xid < xmin is not in-progress */ + if (TransactionIdPrecedes(xid, snapshot->xmin)) + return false; + /* Any xid >= xmax is in-progress */ + if (TransactionIdFollowsOrEquals(xid, snapshot->xmax)) + return true; + + /* + * Snapshot information is stored slightly differently in snapshots taken + * during recovery. + */ + if (!snapshot->takenDuringRecovery) + { + /* + * If the snapshot contains full subxact data, the fastest way to + * check things is just to compare the given XID against both subxact + * XIDs and top-level XIDs. If the snapshot overflowed, we have to + * use pg_subtrans to convert a subxact XID to its parent XID, but + * then we need only look at top-level XIDs not subxacts. + */ + if (!snapshot->suboverflowed) + { + /* we have full data, so search subxip */ + int32 j; + + for (j = 0; j < snapshot->subxcnt; j++) + { + if (TransactionIdEquals(xid, snapshot->subxip[j])) + return true; + } + + /* not there, fall through to search xip[] */ + } + else + { + /* + * Snapshot overflowed, so convert xid to top-level. This is safe + * because we eliminated too-old XIDs above. + */ + xid = SubTransGetTopmostTransaction(xid); + + /* + * If xid was indeed a subxact, we might now have an xid < xmin, + * so recheck to avoid an array scan. No point in rechecking + * xmax. + */ + if (TransactionIdPrecedes(xid, snapshot->xmin)) + return false; + } + + for (i = 0; i < snapshot->xcnt; i++) + { + if (TransactionIdEquals(xid, snapshot->xip[i])) + return true; + } + } + else + { + int32 j; + + /* + * In recovery we store all xids in the subxact array because it is by + * far the bigger array, and we mostly don't know which xids are + * top-level and which are subxacts. The xip array is empty. + * + * We start by searching subtrans, if we overflowed. + */ + if (snapshot->suboverflowed) + { + /* + * Snapshot overflowed, so convert xid to top-level. This is safe + * because we eliminated too-old XIDs above. + */ + xid = SubTransGetTopmostTransaction(xid); + + /* + * If xid was indeed a subxact, we might now have an xid < xmin, + * so recheck to avoid an array scan. No point in rechecking + * xmax. + */ + if (TransactionIdPrecedes(xid, snapshot->xmin)) + return false; + } + + /* + * We now have either a top-level xid higher than xmin or an + * indeterminate xid. We don't know whether it's top level or subxact + * but it doesn't matter. If it's present, the xid is visible. + */ + for (j = 0; j < snapshot->subxcnt; j++) + { + if (TransactionIdEquals(xid, snapshot->subxip[j])) + return true; + } + } + + return false; +} diff --git a/src/bin/Makefile b/src/bin/Makefile index 8c11060a2f5..903e58121f6 100644 --- a/src/bin/Makefile +++ b/src/bin/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin (client programs) # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/Makefile @@ -17,6 +17,7 @@ SUBDIRS = \ initdb \ pg_archivecleanup \ pg_basebackup \ + pg_checksums \ pg_config \ pg_controldata \ pg_ctl \ @@ -26,7 +27,6 @@ SUBDIRS = \ pg_test_fsync \ pg_test_timing \ pg_upgrade \ - pg_verify_checksums \ pg_waldump \ pgbench \ psql \ diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile index 8c239419300..7c404430a94 100644 --- a/src/bin/initdb/Makefile +++ b/src/bin/initdb/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/initdb # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/initdb/Makefile diff --git a/src/bin/initdb/findtimezone.c b/src/bin/initdb/findtimezone.c index 4c3a91a122c..786e78742dd 100644 --- a/src/bin/initdb/findtimezone.c +++ b/src/bin/initdb/findtimezone.c @@ -3,7 +3,7 @@ * findtimezone.c * Functions for determining the default timezone to use. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/initdb/findtimezone.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "pgtz.h" @@ -126,12 +127,22 @@ pg_load_tz(const char *name) * On most systems, we rely on trying to match the observable behavior of * the C library's localtime() function. The database zone that matches * furthest into the past is the one to use. Often there will be several - * zones with identical rankings (since the Olson database assigns multiple - * names to many zones). We break ties arbitrarily by preferring shorter, - * then alphabetically earlier zone names. + * zones with identical rankings (since the IANA database assigns multiple + * names to many zones). We break ties by first checking for "preferred" + * names (such as "UTC"), and then arbitrarily by preferring shorter, then + * alphabetically earlier zone names. (If we did not explicitly prefer + * "UTC", we would get the alias name "UCT" instead due to alphabetic + * ordering.) + * + * Many modern systems use the IANA database, so if we can determine the + * system's idea of which zone it is using and its behavior matches our zone + * of the same name, we can skip the rather-expensive search through all the + * zones in our database. This short-circuit path also ensures that we spell + * the zone name the same way the system setting does, even in the presence + * of multiple aliases for the same zone. * * Win32's native knowledge about timezones appears to be too incomplete - * and too different from the Olson database for the above matching strategy + * and too different from the IANA database for the above matching strategy * to be of any use. But there is just a limited number of timezones * available, so we can rely on a handmade mapping table instead. */ @@ -150,9 +161,11 @@ struct tztry time_t test_times[MAX_TEST_TIMES]; }; +static bool check_system_link_file(const char *linkname, struct tztry *tt, + char *bestzonename); static void scan_available_timezones(char *tzdir, char *tzdirsub, - struct tztry *tt, - int *bestscore, char *bestzonename); + struct tztry *tt, + int *bestscore, char *bestzonename); /* @@ -299,12 +312,19 @@ score_timezone(const char *tzname, struct tztry *tt) return i; } +/* + * Test whether given zone name is a perfect match to localtime() behavior + */ +static bool +perfect_timezone_match(const char *tzname, struct tztry *tt) +{ + return (score_timezone(tzname, tt) == tt->n_test_times); +} + /* * Try to identify a timezone name (in our terminology) that best matches the - * observed behavior of the system timezone library. We cannot assume that - * the system TZ environment setting (if indeed there is one) matches our - * terminology, so we ignore it and just look at what localtime() returns. + * observed behavior of the system localtime() function. */ static const char * identify_system_timezone(void) @@ -339,7 +359,7 @@ identify_system_timezone(void) * way of doing things, but experience has shown that system-supplied * timezone definitions are likely to have DST behavior that is right for * the recent past and not so accurate further back. Scoring in this way - * allows us to recognize zones that have some commonality with the Olson + * allows us to recognize zones that have some commonality with the IANA * database, without insisting on exact match. (Note: we probe Thursdays, * not Sundays, to avoid triggering DST-transition bugs in localtime * itself.) @@ -374,7 +394,18 @@ identify_system_timezone(void) tt.test_times[tt.n_test_times++] = t; } - /* Search for the best-matching timezone file */ + /* + * Try to avoid the brute-force search by seeing if we can recognize the + * system's timezone setting directly. + * + * Currently we just check /etc/localtime; there are other conventions for + * this, but that seems to be the only one used on enough platforms to be + * worth troubling over. + */ + if (check_system_link_file("/etc/localtime", &tt, resultbuf)) + return resultbuf; + + /* No luck, so search for the best-matching timezone file */ strlcpy(tmptzdir, pg_TZDIR(), sizeof(tmptzdir)); bestscore = -1; resultbuf[0] = '\0'; @@ -383,7 +414,7 @@ identify_system_timezone(void) &bestscore, resultbuf); if (bestscore > 0) { - /* Ignore Olson's rather silly "Factory" zone; use GMT instead */ + /* Ignore IANA's rather silly "Factory" zone; use GMT instead */ if (strcmp(resultbuf, "Factory") == 0) return NULL; return resultbuf; @@ -472,7 +503,7 @@ identify_system_timezone(void) /* * Did not find the timezone. Fallback to use a GMT zone. Note that the - * Olson timezone database names the GMT-offset zones in POSIX style: plus + * IANA timezone database names the GMT-offset zones in POSIX style: plus * is west of Greenwich. It's unfortunate that this is opposite of SQL * conventions. Should we therefore change the names? Probably not... */ @@ -486,6 +517,122 @@ identify_system_timezone(void) return resultbuf; } +/* + * Examine a system-provided symlink file to see if it tells us the timezone. + * + * Unfortunately, there is little standardization of how the system default + * timezone is determined in the absence of a TZ environment setting. + * But a common strategy is to create a symlink at a well-known place. + * If "linkname" identifies a readable symlink, and the tail of its contents + * matches a zone name we know, and the actual behavior of localtime() agrees + * with what we think that zone means, then we may use that zone name. + * + * We insist on a perfect behavioral match, which might not happen if the + * system has a different IANA database version than we do; but in that case + * it seems best to fall back to the brute-force search. + * + * linkname is the symlink file location to probe. + * + * tt tells about the system timezone behavior we need to match. + * + * If we successfully identify a zone name, store it in *bestzonename and + * return true; else return false. bestzonename must be a buffer of length + * TZ_STRLEN_MAX + 1. + */ +static bool +check_system_link_file(const char *linkname, struct tztry *tt, + char *bestzonename) +{ +#ifdef HAVE_READLINK + char link_target[MAXPGPATH]; + int len; + const char *cur_name; + + /* + * Try to read the symlink. If not there, not a symlink, etc etc, just + * quietly fail; the precise reason needn't concern us. + */ + len = readlink(linkname, link_target, sizeof(link_target)); + if (len < 0 || len >= sizeof(link_target)) + return false; + link_target[len] = '\0'; + +#ifdef DEBUG_IDENTIFY_TIMEZONE + fprintf(stderr, "symbolic link \"%s\" contains \"%s\"\n", + linkname, link_target); +#endif + + /* + * The symlink is probably of the form "/path/to/zones/zone/name", or + * possibly it is a relative path. Nobody puts their zone DB directly in + * the root directory, so we can definitely skip the first component; but + * after that it's trial-and-error to identify which path component begins + * the zone name. + */ + cur_name = link_target; + while (*cur_name) + { + /* Advance to next segment of path */ + cur_name = strchr(cur_name + 1, '/'); + if (cur_name == NULL) + break; + /* If there are consecutive slashes, skip all, as the kernel would */ + do + { + cur_name++; + } while (*cur_name == '/'); + + /* + * Test remainder of path to see if it is a matching zone name. + * Relative paths might contain ".."; we needn't bother testing if the + * first component is that. Also defend against overlength names. + */ + if (*cur_name && *cur_name != '.' && + strlen(cur_name) <= TZ_STRLEN_MAX && + perfect_timezone_match(cur_name, tt)) + { + /* Success! */ + strcpy(bestzonename, cur_name); + return true; + } + } + + /* Couldn't extract a matching zone name */ + return false; +#else + /* No symlinks? Forget it */ + return false; +#endif +} + +/* + * Given a timezone name, determine whether it should be preferred over other + * names which are equally good matches. The output is arbitrary but we will + * use 0 for "neutral" default preference; larger values are more preferred. + */ +static int +zone_name_pref(const char *zonename) +{ + /* + * Prefer UTC over alternatives such as UCT. Also prefer Etc/UTC over + * Etc/UCT; but UTC is preferred to Etc/UTC. + */ + if (strcmp(zonename, "UTC") == 0) + return 50; + if (strcmp(zonename, "Etc/UTC") == 0) + return 40; + + /* + * We don't want to pick "localtime" or "posixrules", unless we can find + * no other name for the prevailing zone. Those aren't real zone names. + */ + if (strcmp(zonename, "localtime") == 0 || + strcmp(zonename, "posixrules") == 0) + return -50; + + return 0; +} + /* * Recursively scan the timezone database looking for the best match to * the system timezone behavior. @@ -558,9 +705,14 @@ scan_available_timezones(char *tzdir, char *tzdirsub, struct tztry *tt, else if (score == *bestscore) { /* Consider how to break a tie */ - if (strlen(tzdirsub) < strlen(bestzonename) || - (strlen(tzdirsub) == strlen(bestzonename) && - strcmp(tzdirsub, bestzonename) < 0)) + int namepref = (zone_name_pref(tzdirsub) - + zone_name_pref(bestzonename)); + + if (namepref > 0 || + (namepref == 0 && + (strlen(tzdirsub) < strlen(bestzonename) || + (strlen(tzdirsub) == strlen(bestzonename) && + strcmp(tzdirsub, bestzonename) < 0)))) strlcpy(bestzonename, tzdirsub, TZ_STRLEN_MAX + 1); } } @@ -586,7 +738,7 @@ static const struct * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time * Zones on Windows 10 and Windows 7. * - * The zones have been matched to Olson timezones by looking at the cities + * The zones have been matched to IANA timezones by looking at the cities * listed in the win32 display name (in the comment here) in most cases. */ { diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index 4907a379038..88a261d9bda 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -38,7 +38,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/initdb/initdb.c @@ -65,6 +65,7 @@ #include "catalog/pg_collation_d.h" #include "common/file_perm.h" #include "common/file_utils.h" +#include "common/logging.h" #include "common/restricted_token.h" #include "common/username.h" #include "fe_utils/string_utils.h" @@ -155,11 +156,11 @@ static char *shdesc_file; static char *hba_file; static char *ident_file; static char *conf_file; -static char *conversion_file; static char *dictionary_file; static char *info_schema_file; static char *features_file; static char *system_views_file; +static bool success = false; static bool made_new_pgdata = false; static bool found_existing_pgdata = false; static bool made_new_xlogdir = false; @@ -173,7 +174,8 @@ static char *pgdata_native; /* defaults */ static int n_connections = 10; static int n_buffers = 50; -static char *dynamic_shared_memory_type = NULL; +static const char *dynamic_shared_memory_type = NULL; +static const char *default_timezone = NULL; /* * Warning messages for authentication methods @@ -183,7 +185,7 @@ static char *dynamic_shared_memory_type = NULL; "# allows any local user to connect as any PostgreSQL user, including\n" \ "# the database superuser. If you do not trust all your local users,\n" \ "# use another authentication method.\n" -static char *authwarning = NULL; +static bool authwarning = false; /* * Centralized knowledge of switches to pass to backend @@ -229,7 +231,7 @@ static char bin_path[MAXPGPATH]; static char backend_exec[MAXPGPATH]; static char **replace_token(char **lines, - const char *token, const char *replacement); + const char *token, const char *replacement); #ifndef HAVE_UNIX_SOCKETS static char **filter_lines_with_token(char **lines, const char *token); @@ -237,7 +239,6 @@ static char **filter_lines_with_token(char **lines, const char *token); static char **readfile(const char *path); static void writefile(char *path, char **lines); static FILE *popen_check(const char *command, const char *mode); -static void exit_nicely(void) pg_attribute_noreturn(); static char *get_id(void); static int get_encoding_id(const char *encoding_name); static void set_input(char **dest, const char *filename); @@ -253,7 +254,6 @@ static void setup_depend(FILE *cmdfd); static void setup_sysviews(FILE *cmdfd); static void setup_description(FILE *cmdfd); static void setup_collation(FILE *cmdfd); -static void setup_conversion(FILE *cmdfd); static void setup_dictionary(FILE *cmdfd); static void setup_privileges(FILE *cmdfd); static void set_info_version(void); @@ -265,9 +265,10 @@ static void make_postgres(FILE *cmdfd); static void trapsig(int signum); static void check_ok(void); static char *escape_quotes(const char *src); +static char *escape_quotes_bki(const char *src); static int locale_date_order(const char *locale); static void check_locale_name(int category, const char *locale, - char **canonname); + char **canonname); static bool check_locale_encoding(const char *locale, int encoding); static void setlocales(void); static void usage(const char *progname); @@ -291,13 +292,13 @@ void initialize_data_directory(void); do { \ cmdfd = popen_check(cmd, "w"); \ if (cmdfd == NULL) \ - exit_nicely(); /* message already printed by popen_check */ \ + exit(1); /* message already printed by popen_check */ \ } while (0) #define PG_CMD_CLOSE \ do { \ if (pclose_check(cmdfd)) \ - exit_nicely(); /* message already printed by pclose_check */ \ + exit(1); /* message already printed by pclose_check */ \ } while (0) #define PG_CMD_PUTS(line) \ @@ -306,24 +307,16 @@ do { \ output_failed = true, output_errno = errno; \ } while (0) -#define PG_CMD_PRINTF1(fmt, arg1) \ +#define PG_CMD_PRINTF(fmt, ...) \ do { \ - if (fprintf(cmdfd, fmt, arg1) < 0 || fflush(cmdfd) < 0) \ - output_failed = true, output_errno = errno; \ -} while (0) - -#define PG_CMD_PRINTF2(fmt, arg1, arg2) \ -do { \ - if (fprintf(cmdfd, fmt, arg1, arg2) < 0 || fflush(cmdfd) < 0) \ - output_failed = true, output_errno = errno; \ -} while (0) - -#define PG_CMD_PRINTF3(fmt, arg1, arg2, arg3) \ -do { \ - if (fprintf(cmdfd, fmt, arg1, arg2, arg3) < 0 || fflush(cmdfd) < 0) \ + if (fprintf(cmdfd, fmt, __VA_ARGS__) < 0 || fflush(cmdfd) < 0) \ output_failed = true, output_errno = errno; \ } while (0) +/* + * Escape single quotes and backslashes, suitably for insertions into + * configuration files or SQL E'' strings. + */ static char * escape_quotes(const char *src) { @@ -331,12 +324,58 @@ escape_quotes(const char *src) if (!result) { - fprintf(stderr, _("%s: out of memory\n"), progname); + pg_log_error("out of memory"); exit(1); } return result; } +/* + * Escape a field value to be inserted into the BKI data. + * Here, we first run the value through escape_quotes (which + * will be inverted by the backend's scanstr() function) and + * then overlay special processing of double quotes, which + * bootscanner.l will only accept as data if converted to octal + * representation ("\042"). We always wrap the value in double + * quotes, even if that isn't strictly necessary. + */ +static char * +escape_quotes_bki(const char *src) +{ + char *result; + char *data = escape_quotes(src); + char *resultp; + char *datap; + int nquotes = 0; + + /* count double quotes in data */ + datap = data; + while ((datap = strchr(datap, '"')) != NULL) + { + nquotes++; + datap++; + } + + result = (char *) pg_malloc(strlen(data) + 3 + nquotes * 3); + resultp = result; + *resultp++ = '"'; + for (datap = data; *datap; datap++) + { + if (*datap == '"') + { + strcpy(resultp, "\\042"); + resultp += 4; + } + else + *resultp++ = *datap; + } + *resultp++ = '"'; + *resultp = '\0'; + + free(data); + return result; +} + /* * make a copy of the array of lines, with token replaced by replacement * the first time it occurs on each line. @@ -441,9 +480,8 @@ readfile(const char *path) if ((infile = fopen(path, "r")) == NULL) { - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not open file \"%s\" for reading: %m", path); + exit(1); } /* pass over the file twice - the first time to size the result */ @@ -497,25 +535,22 @@ writefile(char *path, char **lines) if ((out_file = fopen(path, "w")) == NULL) { - fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not open file \"%s\" for writing: %m", path); + exit(1); } for (line = lines; *line != NULL; line++) { if (fputs(*line, out_file) < 0) { - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not write file \"%s\": %m", path); + exit(1); } free(*line); } if (fclose(out_file)) { - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not write file \"%s\": %m", path); + exit(1); } } @@ -532,8 +567,7 @@ popen_check(const char *command, const char *mode) errno = 0; cmdfd = popen(command, mode); if (cmdfd == NULL) - fprintf(stderr, _("%s: could not execute command \"%s\": %s\n"), - progname, command, strerror(errno)); + pg_log_error("could not execute command \"%s\": %m", command); return cmdfd; } @@ -542,61 +576,51 @@ popen_check(const char *command, const char *mode) * if we created the data directory remove it too */ static void -exit_nicely(void) +cleanup_directories_atexit(void) { + if (success) + return; + if (!noclean) { if (made_new_pgdata) { - fprintf(stderr, _("%s: removing data directory \"%s\"\n"), - progname, pg_data); + pg_log_info("removing data directory \"%s\"", pg_data); if (!rmtree(pg_data, true)) - fprintf(stderr, _("%s: failed to remove data directory\n"), - progname); + pg_log_error("failed to remove data directory"); } else if (found_existing_pgdata) { - fprintf(stderr, - _("%s: removing contents of data directory \"%s\"\n"), - progname, pg_data); + pg_log_info("removing contents of data directory \"%s\"", + pg_data); if (!rmtree(pg_data, false)) - fprintf(stderr, _("%s: failed to remove contents of data directory\n"), - progname); + pg_log_error("failed to remove contents of data directory"); } if (made_new_xlogdir) { - fprintf(stderr, _("%s: removing WAL directory \"%s\"\n"), - progname, xlog_dir); + pg_log_info("removing WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, true)) - fprintf(stderr, _("%s: failed to remove WAL directory\n"), - progname); + pg_log_error("failed to remove WAL directory"); } else if (found_existing_xlogdir) { - fprintf(stderr, - _("%s: removing contents of WAL directory \"%s\"\n"), - progname, xlog_dir); + pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, false)) - fprintf(stderr, _("%s: failed to remove contents of WAL directory\n"), - progname); + pg_log_error("failed to remove contents of WAL directory"); } /* otherwise died during startup, do nothing! */ } else { if (made_new_pgdata || found_existing_pgdata) - fprintf(stderr, - _("%s: data directory \"%s\" not removed at user's request\n"), - progname, pg_data); + pg_log_info("data directory \"%s\" not removed at user's request", + pg_data); if (made_new_xlogdir || found_existing_xlogdir) - fprintf(stderr, - _("%s: WAL directory \"%s\" not removed at user's request\n"), - progname, xlog_dir); + pg_log_info("WAL directory \"%s\" not removed at user's request", + xlog_dir); } - - exit(1); } /* @@ -612,12 +636,10 @@ get_id(void) #ifndef WIN32 if (geteuid() == 0) /* 0 is root's uid */ { + pg_log_error("cannot be run as root"); fprintf(stderr, - _("%s: cannot be run as root\n" - "Please log in (using, e.g., \"su\") as the " - "(unprivileged) user that will\n" - "own the server process.\n"), - progname); + _("Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" + "own the server process.\n")); exit(1); } #endif @@ -649,8 +671,8 @@ get_encoding_id(const char *encoding_name) if ((enc = pg_valid_server_encoding(encoding_name)) >= 0) return enc; } - fprintf(stderr, _("%s: \"%s\" is not a valid server encoding name\n"), - progname, encoding_name ? encoding_name : "(null)"); + pg_log_error("\"%s\" is not a valid server encoding name", + encoding_name ? encoding_name : "(null)"); exit(1); } @@ -666,6 +688,8 @@ struct tsearch_config_match static const struct tsearch_config_match tsearch_config_languages[] = { + {"arabic", "ar"}, + {"arabic", "Arabic"}, {"danish", "da"}, {"danish", "Danish"}, {"dutch", "nl"}, @@ -680,10 +704,20 @@ static const struct tsearch_config_match tsearch_config_languages[] = {"french", "French"}, {"german", "de"}, {"german", "German"}, + {"greek", "el"}, + {"greek", "Greek"}, {"hungarian", "hu"}, {"hungarian", "Hungarian"}, + {"indonesian", "id"}, + {"indonesian", "Indonesian"}, + {"irish", "ga"}, + {"irish", "Irish"}, {"italian", "it"}, {"italian", "Italian"}, + {"lithuanian", "lt"}, + {"lithuanian", "Lithuanian"}, + {"nepali", "ne"}, + {"nepali", "Nepali"}, {"norwegian", "no"}, {"norwegian", "Norwegian"}, {"portuguese", "pt"}, @@ -695,6 +729,8 @@ static const struct tsearch_config_match tsearch_config_languages[] = {"spanish", "Spanish"}, {"swedish", "sv"}, {"swedish", "Swedish"}, + {"tamil", "ta"}, + {"tamil", "Tamil"}, {"turkish", "tr"}, {"turkish", "Turkish"}, {NULL, NULL} /* end marker */ @@ -768,17 +804,14 @@ check_input(char *path) { if (errno == ENOENT) { - fprintf(stderr, - _("%s: file \"%s\" does not exist\n"), progname, path); + pg_log_error("file \"%s\" does not exist", path); fprintf(stderr, _("This might mean you have a corrupted installation or identified\n" "the wrong directory with the invocation option -L.\n")); } else { - fprintf(stderr, - _("%s: could not access file \"%s\": %s\n"), progname, path, - strerror(errno)); + pg_log_error("could not access file \"%s\": %m", path); fprintf(stderr, _("This might mean you have a corrupted installation or identified\n" "the wrong directory with the invocation option -L.\n")); @@ -787,8 +820,7 @@ check_input(char *path) } if (!S_ISREG(statbuf.st_mode)) { - fprintf(stderr, - _("%s: file \"%s\" is not a regular file\n"), progname, path); + pg_log_error("file \"%s\" is not a regular file", path); fprintf(stderr, _("This might mean you have a corrupted installation or identified\n" "the wrong directory with the invocation option -L.\n")); @@ -813,16 +845,14 @@ write_version_file(const char *extrapath) if ((version_file = fopen(path, PG_BINARY_W)) == NULL) { - fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not open file \"%s\" for writing: %m", path); + exit(1); } if (fprintf(version_file, "%s\n", PG_MAJORVERSION) < 0 || fclose(version_file)) { - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not write file \"%s\": %m", path); + exit(1); } free(path); } @@ -841,15 +871,13 @@ set_null_conf(void) conf_file = fopen(path, PG_BINARY_W); if (conf_file == NULL) { - fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not open file \"%s\" for writing: %m", path); + exit(1); } if (fclose(conf_file)) { - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not write file \"%s\": %m", path); + exit(1); } free(path); } @@ -865,12 +893,15 @@ set_null_conf(void) * the postmaster either, and configure the cluster for System V shared * memory instead. */ -static char * +static const char * choose_dsm_implementation(void) { #ifdef HAVE_SHM_OPEN int ntries = 10; + /* Initialize random(); this function is its only user in this program. */ + srandom((unsigned int) (getpid() ^ time(NULL))); + while (ntries > 0) { uint32 handle; @@ -901,9 +932,7 @@ choose_dsm_implementation(void) /* * Determine platform-specific config settings * - * Use reasonable values if kernel will let us, else scale back. Probe - * for max_connections first since it is subject to more constraints than - * shared_buffers. + * Use reasonable values if kernel will let us, else scale back. */ static void test_config_settings(void) @@ -932,7 +961,19 @@ test_config_settings(void) test_buffs, ok_buffers = 0; + /* + * Need to determine working DSM implementation first so that subsequent + * tests don't fail because DSM setting doesn't work. + */ + printf(_("selecting dynamic shared memory implementation ... ")); + fflush(stdout); + dynamic_shared_memory_type = choose_dsm_implementation(); + printf("%s\n", dynamic_shared_memory_type); + /* + * Probe for max_connections before shared_buffers, since it is subject to + * more constraints than shared_buffers. + */ printf(_("selecting default max_connections ... ")); fflush(stdout); @@ -945,10 +986,11 @@ test_config_settings(void) "\"%s\" --boot -x0 %s " "-c max_connections=%d " "-c shared_buffers=%d " - "-c dynamic_shared_memory_type=none " + "-c dynamic_shared_memory_type=%s " "< \"%s\" > \"%s\" 2>&1", backend_exec, boot_options, test_conns, test_buffs, + dynamic_shared_memory_type, DEVNULL, DEVNULL); status = system(cmd); if (status == 0) @@ -980,10 +1022,11 @@ test_config_settings(void) "\"%s\" --boot -x0 %s " "-c max_connections=%d " "-c shared_buffers=%d " - "-c dynamic_shared_memory_type=none " + "-c dynamic_shared_memory_type=%s " "< \"%s\" > \"%s\" 2>&1", backend_exec, boot_options, n_connections, test_buffs, + dynamic_shared_memory_type, DEVNULL, DEVNULL); status = system(cmd); if (status == 0) @@ -996,10 +1039,10 @@ test_config_settings(void) else printf("%dkB\n", n_buffers * (BLCKSZ / 1024)); - printf(_("selecting dynamic shared memory implementation ... ")); + printf(_("selecting default time zone ... ")); fflush(stdout); - dynamic_shared_memory_type = choose_dsm_implementation(); - printf("%s\n", dynamic_shared_memory_type); + default_timezone = select_default_timezone(share_path); + printf("%s\n", default_timezone ? default_timezone : "GMT"); } /* @@ -1028,7 +1071,6 @@ setup_config(void) char **conflines; char repltok[MAXPGPATH]; char path[MAXPGPATH]; - const char *default_timezone; char *autoconflines[3]; fputs(_("creating configuration files ... "), stdout); @@ -1110,7 +1152,6 @@ setup_config(void) "#default_text_search_config = 'pg_catalog.simple'", repltok); - default_timezone = select_default_timezone(share_path); if (default_timezone) { snprintf(repltok, sizeof(repltok), "timezone = '%s'", @@ -1185,9 +1226,8 @@ setup_config(void) writefile(path, conflines); if (chmod(path, pg_file_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of \"%s\": %m", path); + exit(1); } /* @@ -1205,9 +1245,8 @@ setup_config(void) writefile(path, autoconflines); if (chmod(path, pg_file_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of \"%s\": %m", path); + exit(1); } free(conflines); @@ -1244,7 +1283,7 @@ setup_config(void) err = WSAStartup(MAKEWORD(2, 2), &wsaData); #endif - /* for best results, this code should match parse_hba() */ + /* for best results, this code should match parse_hba_line() */ hints.ai_flags = AI_NUMERICHOST; hints.ai_family = AF_UNSPEC; hints.ai_socktype = 0; @@ -1292,9 +1331,8 @@ setup_config(void) writefile(path, conflines); if (chmod(path, pg_file_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of \"%s\": %m", path); + exit(1); } free(conflines); @@ -1308,9 +1346,8 @@ setup_config(void) writefile(path, conflines); if (chmod(path, pg_file_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of \"%s\": %m", path); + exit(1); } free(conflines); @@ -1343,12 +1380,12 @@ bootstrap_template1(void) if (strcmp(headerline, *bki_lines) != 0) { + pg_log_error("input file \"%s\" does not belong to PostgreSQL %s", + bki_file, PG_VERSION); fprintf(stderr, - _("%s: input file \"%s\" does not belong to PostgreSQL %s\n" - "Check your installation or specify the correct path " - "using the option -L.\n"), - progname, bki_file, PG_VERSION); - exit_nicely(); + _("Check your installation or specify the correct path " + "using the option -L.\n")); + exit(1); } /* Substitute for various symbols used in the BKI file */ @@ -1368,27 +1405,17 @@ bootstrap_template1(void) bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL", FLOAT8PASSBYVAL ? "true" : "false"); - bki_lines = replace_token(bki_lines, "POSTGRES", escape_quotes(username)); - - bki_lines = replace_token(bki_lines, "ENCODING", encodingid_to_string(encodingid)); + bki_lines = replace_token(bki_lines, "POSTGRES", + escape_quotes_bki(username)); - bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate)); + bki_lines = replace_token(bki_lines, "ENCODING", + encodingid_to_string(encodingid)); - bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype)); + bki_lines = replace_token(bki_lines, "LC_COLLATE", + escape_quotes_bki(lc_collate)); - /* - * Pass correct LC_xxx environment to bootstrap. - * - * The shell script arranged to restore the LC settings afterwards, but - * there doesn't seem to be any compelling reason to do that. - */ - snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate); - putenv(pg_strdup(cmd)); - - snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype); - putenv(pg_strdup(cmd)); - - unsetenv("LC_ALL"); + bki_lines = replace_token(bki_lines, "LC_CTYPE", + escape_quotes_bki(lc_ctype)); /* Also ensure backend isn't confused by this environment var: */ unsetenv("PGCLIENTENCODING"); @@ -1437,7 +1464,7 @@ setup_auth(FILE *cmdfd) PG_CMD_PUTS(*line); if (superuser_password) - PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n", + PG_CMD_PRINTF("ALTER USER \"%s\" WITH PASSWORD E'%s';\n\n", username, escape_quotes(superuser_password)); } @@ -1462,7 +1489,7 @@ get_su_pwd(void) if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); - exit_nicely(); + exit(1); } } else @@ -1480,19 +1507,19 @@ get_su_pwd(void) if (!pwf) { - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, pwfilename, strerror(errno)); - exit_nicely(); + pg_log_error("could not open file \"%s\" for reading: %m", + pwfilename); + exit(1); } if (!fgets(pwd1, sizeof(pwd1), pwf)) { if (ferror(pwf)) - fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"), - progname, pwfilename, strerror(errno)); + pg_log_error("could not read password from file \"%s\": %m", + pwfilename); else - fprintf(stderr, _("%s: password file \"%s\" is empty\n"), - progname, pwfilename); - exit_nicely(); + pg_log_error("password file \"%s\" is empty", + pwfilename); + exit(1); } fclose(pwf); @@ -1614,6 +1641,8 @@ setup_sysviews(FILE *cmdfd) free(*line); } + PG_CMD_PUTS("\n\n"); + free(sysviews_setup); } @@ -1627,9 +1656,9 @@ setup_description(FILE *cmdfd) " objoid oid, " " classname name, " " objsubid int4, " - " description text) WITHOUT OIDS;\n\n"); + " description text);\n\n"); - PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n\n", + PG_CMD_PRINTF("COPY tmp_pg_description FROM E'%s';\n\n", escape_quotes(desc_file)); PG_CMD_PUTS("INSERT INTO pg_description " @@ -1640,9 +1669,9 @@ setup_description(FILE *cmdfd) PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( " " objoid oid, " " classname name, " - " description text) WITHOUT OIDS;\n\n"); + " description text);\n\n"); - PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n\n", + PG_CMD_PRINTF("COPY tmp_pg_shdescription FROM E'%s';\n\n", escape_quotes(shdesc_file)); PG_CMD_PUTS("INSERT INTO pg_shdescription " @@ -1652,16 +1681,17 @@ setup_description(FILE *cmdfd) /* Create default descriptions for operator implementation functions */ PG_CMD_PUTS("WITH funcdescs AS ( " - "SELECT p.oid as p_oid, oprname, " - "coalesce(obj_description(o.oid, 'pg_operator'),'') as opdesc " + "SELECT p.oid as p_oid, o.oid as o_oid, oprname " "FROM pg_proc p JOIN pg_operator o ON oprcode = p.oid ) " "INSERT INTO pg_description " " SELECT p_oid, 'pg_proc'::regclass, 0, " " 'implementation of ' || oprname || ' operator' " " FROM funcdescs " - " WHERE opdesc NOT LIKE 'deprecated%' AND " - " NOT EXISTS (SELECT 1 FROM pg_description " - " WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass);\n\n"); + " WHERE NOT EXISTS (SELECT 1 FROM pg_description " + " WHERE objoid = p_oid AND classoid = 'pg_proc'::regclass) " + " AND NOT EXISTS (SELECT 1 FROM pg_description " + " WHERE objoid = o_oid AND classoid = 'pg_operator'::regclass" + " AND description LIKE 'deprecated%');\n\n"); /* * Even though the tables are temp, drop them explicitly so they don't get @@ -1682,33 +1712,14 @@ setup_collation(FILE *cmdfd) * in pg_collation.h. But add it before reading system collations, so * that it wins if libc defines a locale named ucs_basic. */ - PG_CMD_PRINTF3("INSERT INTO pg_collation (collname, collnamespace, collowner, collprovider, collencoding, collcollate, collctype) VALUES ('ucs_basic', 'pg_catalog'::regnamespace, %u, '%c', %d, 'C', 'C');\n\n", + PG_CMD_PRINTF("INSERT INTO pg_collation (oid, collname, collnamespace, collowner, collprovider, collisdeterministic, collencoding, collcollate, collctype)" + "VALUES (pg_nextoid('pg_catalog.pg_collation', 'oid', 'pg_catalog.pg_collation_oid_index'), 'ucs_basic', 'pg_catalog'::regnamespace, %u, '%c', true, %d, 'C', 'C');\n\n", BOOTSTRAP_SUPERUSERID, COLLPROVIDER_LIBC, PG_UTF8); /* Now import all collations we can find in the operating system */ PG_CMD_PUTS("SELECT pg_import_system_collations('pg_catalog');\n\n"); } -/* - * load conversion functions - */ -static void -setup_conversion(FILE *cmdfd) -{ - char **line; - char **conv_lines; - - conv_lines = readfile(conversion_file); - for (line = conv_lines; *line != NULL; line++) - { - if (strstr(*line, "DROP CONVERSION") != *line) - PG_CMD_PUTS(*line); - free(*line); - } - - free(conv_lines); -} - /* * load extra dictionaries (Snowball stemmers) */ @@ -1725,6 +1736,8 @@ setup_dictionary(FILE *cmdfd) free(*line); } + PG_CMD_PUTS("\n\n"); + free(conv_lines); } @@ -1781,7 +1794,7 @@ setup_privileges(FILE *cmdfd) " relacl IS NOT NULL" " AND relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_SEQUENCE) ");", + CppAsString2(RELKIND_SEQUENCE) ");\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1797,7 +1810,7 @@ setup_privileges(FILE *cmdfd) " pg_attribute.attacl IS NOT NULL" " AND pg_class.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " - CppAsString2(RELKIND_SEQUENCE) ");", + CppAsString2(RELKIND_SEQUENCE) ");\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1809,7 +1822,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_proc" " WHERE" - " proacl IS NOT NULL;", + " proacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1821,7 +1834,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_type" " WHERE" - " typacl IS NOT NULL;", + " typacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1833,7 +1846,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_language" " WHERE" - " lanacl IS NOT NULL;", + " lanacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1846,7 +1859,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_largeobject_metadata" " WHERE" - " lomacl IS NOT NULL;", + " lomacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1858,7 +1871,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_namespace" " WHERE" - " nspacl IS NOT NULL;", + " nspacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1871,7 +1884,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_foreign_data_wrapper" " WHERE" - " fdwacl IS NOT NULL;", + " fdwacl IS NOT NULL;\n\n", "INSERT INTO pg_init_privs " " (objoid, classoid, objsubid, initprivs, privtype)" " SELECT" @@ -1884,7 +1897,7 @@ setup_privileges(FILE *cmdfd) " FROM" " pg_foreign_server" " WHERE" - " srvacl IS NOT NULL;", + " srvacl IS NOT NULL;\n\n", NULL }; @@ -1939,14 +1952,16 @@ setup_schema(FILE *cmdfd) free(*line); } + PG_CMD_PUTS("\n\n"); + free(lines); - PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info " + PG_CMD_PRINTF("UPDATE information_schema.sql_implementation_info " " SET character_value = '%s' " " WHERE implementation_info_name = 'DBMS VERSION';\n\n", infoversion); - PG_CMD_PRINTF1("COPY information_schema.sql_features " + PG_CMD_PRINTF("COPY information_schema.sql_features " " (feature_id, feature_name, sub_feature_id, " " sub_feature_name, is_supported, comments) " " FROM E'%s';\n\n", @@ -1983,7 +1998,7 @@ make_template0(FILE *cmdfd) "CREATE DATABASE template0 IS_TEMPLATE = true ALLOW_CONNECTIONS = false;\n\n", /* - * We use the OID of template0 to determine lastsysoid + * We use the OID of template0 to determine datlastsysoid */ "UPDATE pg_database SET datlastsysoid = " " (SELECT oid FROM pg_database " @@ -2037,7 +2052,7 @@ make_postgres(FILE *cmdfd) * if you are handling SIGFPE. * * I avoided doing the forbidden things by setting a flag instead of calling - * exit_nicely() directly. + * exit() directly. * * Also note the behaviour of Windows with SIGINT, which says this: * Note SIGINT is not supported for any Win32 application, including @@ -2058,7 +2073,7 @@ trapsig(int signum) } /* - * call exit_nicely() if we got a signal, or else output "ok". + * call exit() if we got a signal, or else output "ok". */ static void check_ok(void) @@ -2067,14 +2082,14 @@ check_ok(void) { printf(_("caught signal\n")); fflush(stdout); - exit_nicely(); + exit(1); } else if (output_failed) { printf(_("could not write to child process: %s\n"), strerror(output_errno)); fflush(stdout); - exit_nicely(); + exit(1); } else { @@ -2169,8 +2184,7 @@ check_locale_name(int category, const char *locale, char **canonname) save = setlocale(category, NULL); if (!save) { - fprintf(stderr, _("%s: setlocale() failed\n"), - progname); + pg_log_error("setlocale() failed"); exit(1); } @@ -2191,8 +2205,7 @@ check_locale_name(int category, const char *locale, char **canonname) /* restore old value. */ if (!setlocale(category, save)) { - fprintf(stderr, _("%s: failed to restore old locale \"%s\"\n"), - progname, save); + pg_log_error("failed to restore old locale \"%s\"", save); exit(1); } free(save); @@ -2201,8 +2214,7 @@ check_locale_name(int category, const char *locale, char **canonname) if (res == NULL) { if (*locale) - fprintf(stderr, _("%s: invalid locale name \"%s\"\n"), - progname, locale); + pg_log_error("invalid locale name \"%s\"", locale); else { /* @@ -2213,8 +2225,7 @@ check_locale_name(int category, const char *locale, char **canonname) * setlocale's behavior is implementation-specific, it's hard to * be sure what it didn't like. Print a safe generic message. */ - fprintf(stderr, _("%s: invalid locale settings; check LANG and LC_* environment variables\n"), - progname); + pg_log_error("invalid locale settings; check LANG and LC_* environment variables"); } exit(1); } @@ -2241,7 +2252,7 @@ check_locale_encoding(const char *locale, int user_enc) #endif user_enc == PG_SQL_ASCII)) { - fprintf(stderr, _("%s: encoding mismatch\n"), progname); + pg_log_error("encoding mismatch"); fprintf(stderr, _("The encoding you selected (%s) and the encoding that the\n" "selected locale uses (%s) do not match. This would lead to\n" @@ -2351,7 +2362,7 @@ usage(const char *progname) printf(_(" -?, --help show this help, then exit\n")); printf(_("\nIf the data directory is not specified, the environment variable PGDATA\n" "is used.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } static void @@ -2359,9 +2370,7 @@ check_authmethod_unspecified(const char **authmethod) { if (*authmethod == NULL) { - authwarning = _("\nWARNING: enabling \"trust\" authentication for local connections\n" - "You can change this by editing pg_hba.conf or using the option -A, or\n" - "--auth-local and --auth-host, the next time you run initdb.\n"); + authwarning = true; *authmethod = "trust"; } } @@ -2381,8 +2390,8 @@ check_authmethod_valid(const char *authmethod, const char *const *valid_methods, return; } - fprintf(stderr, _("%s: invalid authentication method \"%s\" for \"%s\" connections\n"), - progname, authmethod, conntype); + pg_log_error("invalid authentication method \"%s\" for \"%s\" connections", + authmethod, conntype); exit(1); } @@ -2397,12 +2406,12 @@ check_need_password(const char *authmethodlocal, const char *authmethodhost) strcmp(authmethodhost, "scram-sha-256") == 0) && !(pwprompt || pwfilename)) { - fprintf(stderr, _("%s: must specify a password for the superuser to enable %s authentication\n"), progname, - (strcmp(authmethodlocal, "md5") == 0 || - strcmp(authmethodlocal, "password") == 0 || - strcmp(authmethodlocal, "scram-sha-256") == 0) - ? authmethodlocal - : authmethodhost); + pg_log_error("must specify a password for the superuser to enable %s authentication", + (strcmp(authmethodlocal, "md5") == 0 || + strcmp(authmethodlocal, "password") == 0 || + strcmp(authmethodlocal, "scram-sha-256") == 0) + ? authmethodlocal + : authmethodhost); exit(1); } } @@ -2424,12 +2433,11 @@ setup_pgdata(void) } else { + pg_log_error("no data directory specified"); fprintf(stderr, - _("%s: no data directory specified\n" - "You must identify the directory where the data for this database system\n" + _("You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" - "environment variable PGDATA.\n"), - progname); + "environment variable PGDATA.\n")); exit(1); } } @@ -2462,18 +2470,15 @@ setup_bin_paths(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) - fprintf(stderr, - _("The program \"postgres\" is needed by %s " - "but was not found in the\n" - "same directory as \"%s\".\n" - "Check your installation.\n"), - progname, full_path); + pg_log_error("The program \"postgres\" is needed by %s but was not found in the\n" + "same directory as \"%s\".\n" + "Check your installation.", + progname, full_path); else - fprintf(stderr, - _("The program \"postgres\" was found by \"%s\"\n" - "but was not the same version as %s.\n" - "Check your installation.\n"), - full_path, progname); + pg_log_error("The program \"postgres\" was found by \"%s\"\n" + "but was not the same version as %s.\n" + "Check your installation.", + full_path, progname); exit(1); } @@ -2489,7 +2494,7 @@ setup_bin_paths(const char *argv0) } else if (!is_absolute_path(share_path)) { - fprintf(stderr, _("%s: input file location must be an absolute path\n"), progname); + pg_log_error("input file location must be an absolute path"); exit(1); } @@ -2533,8 +2538,8 @@ setup_locale_encoding(void) if (ctype_enc == -1) { /* Couldn't recognize the locale's codeset */ - fprintf(stderr, _("%s: could not find suitable encoding for locale \"%s\"\n"), - progname, lc_ctype); + pg_log_error("could not find suitable encoding for locale \"%s\"", + lc_ctype); fprintf(stderr, _("Rerun %s with the -E option.\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); @@ -2554,9 +2559,8 @@ setup_locale_encoding(void) pg_encoding_to_char(ctype_enc), pg_encoding_to_char(encodingid)); #else - fprintf(stderr, - _("%s: locale \"%s\" requires unsupported encoding \"%s\"\n"), - progname, lc_ctype, pg_encoding_to_char(ctype_enc)); + pg_log_error("locale \"%s\" requires unsupported encoding \"%s\"", + lc_ctype, pg_encoding_to_char(ctype_enc)); fprintf(stderr, _("Encoding \"%s\" is not allowed as a server-side encoding.\n" "Rerun %s with a different locale selection.\n"), @@ -2590,7 +2594,6 @@ setup_data_file_paths(void) set_input(&hba_file, "pg_hba.conf.sample"); set_input(&ident_file, "pg_ident.conf.sample"); set_input(&conf_file, "postgresql.conf.sample"); - set_input(&conversion_file, "conversion_create.sql"); set_input(&dictionary_file, "snowball_create.sql"); set_input(&info_schema_file, "information_schema.sql"); set_input(&features_file, "sql_features.txt"); @@ -2621,7 +2624,6 @@ setup_data_file_paths(void) check_input(hba_file); check_input(ident_file); check_input(conf_file); - check_input(conversion_file); check_input(dictionary_file); check_input(info_schema_file); check_input(features_file); @@ -2637,8 +2639,8 @@ setup_text_search(void) default_text_search_config = find_matching_ts_config(lc_ctype); if (!default_text_search_config) { - printf(_("%s: could not find suitable text search configuration for locale \"%s\"\n"), - progname, lc_ctype); + pg_log_info("could not find suitable text search configuration for locale \"%s\"", + lc_ctype); default_text_search_config = "simple"; } } @@ -2648,13 +2650,13 @@ setup_text_search(void) if (checkmatch == NULL) { - printf(_("%s: warning: suitable text search configuration for locale \"%s\" is unknown\n"), - progname, lc_ctype); + pg_log_warning("suitable text search configuration for locale \"%s\" is unknown", + lc_ctype); } else if (strcmp(checkmatch, default_text_search_config) != 0) { - printf(_("%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n"), - progname, default_text_search_config, lc_ctype); + pg_log_warning("specified text search configuration \"%s\" might not match locale \"%s\"", + default_text_search_config, lc_ctype); } } @@ -2708,9 +2710,8 @@ create_data_directory(void) if (pg_mkdir_p(pg_data, pg_dir_create_mode) != 0) { - fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), - progname, pg_data, strerror(errno)); - exit_nicely(); + pg_log_error("could not create directory \"%s\": %m", pg_data); + exit(1); } else check_ok(); @@ -2726,9 +2727,9 @@ create_data_directory(void) if (chmod(pg_data, pg_dir_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"), - progname, pg_data, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of directory \"%s\": %m", + pg_data); + exit(1); } else check_ok(); @@ -2740,9 +2741,7 @@ create_data_directory(void) case 3: case 4: /* Present and not empty */ - fprintf(stderr, - _("%s: directory \"%s\" exists but is not empty\n"), - progname, pg_data); + pg_log_error("directory \"%s\" exists but is not empty", pg_data); if (ret != 4) warn_on_mount_point(ret); else @@ -2755,9 +2754,8 @@ create_data_directory(void) default: /* Trouble accessing directory */ - fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), - progname, pg_data, strerror(errno)); - exit_nicely(); + pg_log_error("could not access directory \"%s\": %m", pg_data); + exit(1); } } @@ -2779,8 +2777,8 @@ create_xlog_or_symlink(void) canonicalize_path(xlog_dir); if (!is_absolute_path(xlog_dir)) { - fprintf(stderr, _("%s: WAL directory location must be an absolute path\n"), progname); - exit_nicely(); + pg_log_error("WAL directory location must be an absolute path"); + exit(1); } /* check if the specified xlog directory exists/is empty */ @@ -2794,9 +2792,9 @@ create_xlog_or_symlink(void) if (pg_mkdir_p(xlog_dir, pg_dir_create_mode) != 0) { - fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), - progname, xlog_dir, strerror(errno)); - exit_nicely(); + pg_log_error("could not create directory \"%s\": %m", + xlog_dir); + exit(1); } else check_ok(); @@ -2812,9 +2810,9 @@ create_xlog_or_symlink(void) if (chmod(xlog_dir, pg_dir_create_mode) != 0) { - fprintf(stderr, _("%s: could not change permissions of directory \"%s\": %s\n"), - progname, xlog_dir, strerror(errno)); - exit_nicely(); + pg_log_error("could not change permissions of directory \"%s\": %m", + xlog_dir); + exit(1); } else check_ok(); @@ -2826,9 +2824,7 @@ create_xlog_or_symlink(void) case 3: case 4: /* Present and not empty */ - fprintf(stderr, - _("%s: directory \"%s\" exists but is not empty\n"), - progname, xlog_dir); + pg_log_error("directory \"%s\" exists but is not empty", xlog_dir); if (ret != 4) warn_on_mount_point(ret); else @@ -2836,25 +2832,24 @@ create_xlog_or_symlink(void) _("If you want to store the WAL there, either remove or empty the directory\n" "\"%s\".\n"), xlog_dir); - exit_nicely(); + exit(1); default: /* Trouble accessing directory */ - fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), - progname, xlog_dir, strerror(errno)); - exit_nicely(); + pg_log_error("could not access directory \"%s\": %m", xlog_dir); + exit(1); } #ifdef HAVE_SYMLINK if (symlink(xlog_dir, subdirloc) != 0) { - fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"), - progname, subdirloc, strerror(errno)); - exit_nicely(); + pg_log_error("could not create symbolic link \"%s\": %m", + subdirloc); + exit(1); } #else - fprintf(stderr, _("%s: symlinks are not supported on this platform")); - exit_nicely(); + pg_log_error("symlinks are not supported on this platform"); + exit(1); #endif } else @@ -2862,9 +2857,9 @@ create_xlog_or_symlink(void) /* Without -X option, just make the subdirectory normally */ if (mkdir(subdirloc, pg_dir_create_mode) < 0) { - fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), - progname, subdirloc, strerror(errno)); - exit_nicely(); + pg_log_error("could not create directory \"%s\": %m", + subdirloc); + exit(1); } } @@ -2924,9 +2919,8 @@ initialize_data_directory(void) */ if (mkdir(path, pg_dir_create_mode) < 0) { - fprintf(stderr, _("%s: could not create directory \"%s\": %s\n"), - progname, path, strerror(errno)); - exit_nicely(); + pg_log_error("could not create directory \"%s\": %m", path); + exit(1); } free(path); @@ -2981,8 +2975,6 @@ initialize_data_directory(void) setup_collation(cmdfd); - setup_conversion(cmdfd); - setup_dictionary(cmdfd); setup_privileges(cmdfd); @@ -3051,14 +3043,14 @@ main(int argc, char *argv[]) char pg_ctl_path[MAXPGPATH]; /* - * Ensure that buffering behavior of stdout and stderr matches what it is - * in interactive usage (at least on most platforms). This prevents + * Ensure that buffering behavior of stdout matches what it is in + * interactive usage (at least on most platforms). This prevents * unexpected output ordering when, eg, output is redirected to a file. * POSIX says we must do this before any other usage of these files. */ setvbuf(stdout, NULL, PG_IOLBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb")); @@ -3196,13 +3188,15 @@ main(int argc, char *argv[]) if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } + atexit(cleanup_directories_atexit); + /* If we only need to fsync, just do it and exit */ if (sync_only) { @@ -3211,21 +3205,20 @@ main(int argc, char *argv[]) /* must check that directory is readable */ if (pg_check_dir(pg_data) <= 0) { - fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), - progname, pg_data, strerror(errno)); - exit_nicely(); + pg_log_error("could not access directory \"%s\": %m", pg_data); + exit(1); } fputs(_("syncing data to disk ... "), stdout); fflush(stdout); - fsync_pgdata(pg_data, progname, PG_VERSION_NUM); + fsync_pgdata(pg_data, PG_VERSION_NUM); check_ok(); return 0; } if (pwprompt && pwfilename) { - fprintf(stderr, _("%s: password prompt and password file cannot be specified together\n"), progname); + pg_log_error("password prompt and password file cannot be specified together"); exit(1); } @@ -3250,21 +3243,17 @@ main(int argc, char *argv[]) /* verify that wal segment size is valid */ if (endptr == str_wal_segment_size_mb || *endptr != '\0') { - fprintf(stderr, - _("%s: argument of --wal-segsize must be a number\n"), - progname); + pg_log_error("argument of --wal-segsize must be a number"); exit(1); } if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024)) { - fprintf(stderr, - _("%s: argument of --wal-segsize must be a power of 2 between 1 and 1024\n"), - progname); + pg_log_error("argument of --wal-segsize must be a power of 2 between 1 and 1024"); exit(1); } } - get_restricted_token(progname); + get_restricted_token(); setup_pgdata(); @@ -3276,7 +3265,7 @@ main(int argc, char *argv[]) if (strncmp(username, "pg_", 3) == 0) { - fprintf(stderr, _("%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"\n"), progname, username); + pg_log_error("superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"", username); exit(1); } @@ -3311,14 +3300,19 @@ main(int argc, char *argv[]) { fputs(_("syncing data to disk ... "), stdout); fflush(stdout); - fsync_pgdata(pg_data, progname, PG_VERSION_NUM); + fsync_pgdata(pg_data, PG_VERSION_NUM); check_ok(); } else printf(_("\nSync to disk skipped.\nThe data directory might become corrupt if the operating system crashes.\n")); - if (authwarning != NULL) - fprintf(stderr, "%s", authwarning); + if (authwarning) + { + printf("\n"); + pg_log_warning("enabling \"trust\" authentication for local connections"); + fprintf(stderr, _("You can change this by editing pg_hba.conf or using the option -A, or\n" + "--auth-local and --auth-host, the next time you run initdb.\n")); + } /* * Build up a shell command to tell the user how to start the server @@ -3349,5 +3343,6 @@ main(int argc, char *argv[]) destroyPQExpBuffer(start_db_cmd); + success = true; return 0; } diff --git a/src/bin/initdb/nls.mk b/src/bin/initdb/nls.mk index 92ece204869..803388d4c7b 100644 --- a/src/bin/initdb/nls.mk +++ b/src/bin/initdb/nls.mk @@ -1,5 +1,6 @@ # src/bin/initdb/nls.mk CATALOG_NAME = initdb -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv zh_CN -GETTEXT_FILES = findtimezone.c initdb.c ../../common/exec.c ../../common/fe_memutils.c ../../common/file_utils.c ../../common/pgfnames.c ../../common/restricted_token.c ../../common/rmtree.c ../../common/username.c ../../common/wait_error.c ../../port/dirmod.c -GETTEXT_TRIGGERS = simple_prompt +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr vi zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) findtimezone.c initdb.c ../../common/exec.c ../../common/fe_memutils.c ../../common/file_utils.c ../../common/pgfnames.c ../../common/restricted_token.c ../../common/rmtree.c ../../common/username.c ../../common/wait_error.c ../../port/dirmod.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/initdb/po/de.po b/src/bin/initdb/po/de.po index bc18c740068..9359d9fa8ff 100644 --- a/src/bin/initdb/po/de.po +++ b/src/bin/initdb/po/de.po @@ -1,55 +1,76 @@ # German message translation file for initdb. -# Peter Eisentraut , 2003 - 2017. +# Peter Eisentraut , 2003 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-12 18:16+0000\n" -"PO-Revision-Date: 2017-05-12 15:21-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: Peter Eisentraut \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 20:47+0000\n" +"PO-Revision-Date: 2019-06-16 22:39+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %s" +msgid "fatal: " +msgstr "Fatal: " -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ungültige Programmdatei »%s«" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "konnte Programmdatei »%s« nicht lesen" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "konnte kein »%s« zum Ausführen finden" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: ../../common/exec.c:288 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "konnte nicht in Verzeichnis »%s« wechseln: %s" +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:541 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "konnte symbolische Verknüpfung »%s« nicht lesen" +msgid "pclose failed: %m" +msgstr "pclose fehlgeschlagen: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: initdb.c:339 #, c-format -msgid "pclose failed: %s" -msgstr "pclose fehlgeschlagen: %s" +msgid "out of memory" +msgstr "Speicher aufgebraucht" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -62,96 +83,86 @@ msgstr "Speicher aufgebraucht\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 #, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: konnte »stat« für Datei »%s« nicht ausführen: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" -#: ../../common/file_utils.c:162 +#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht öffnen: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" -#: ../../common/file_utils.c:198 +#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht öffnen: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht fsyncen: %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:377 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht in »%s« umbenennen: %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" -#: ../../common/pgfnames.c:45 +#: ../../common/pgfnames.c:74 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht öffnen: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: ../../common/pgfnames.c:72 +#: ../../common/restricted_token.c:69 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "cannot create restricted tokens on this platform" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden" -#: ../../common/pgfnames.c:84 +#: ../../common/restricted_token.c:78 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht schließen: %s\n" +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: WARNUNG: auf dieser Plattform können keine beschränkten Token erzeugt werden\n" - -#: ../../common/restricted_token.c:77 -#, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" - -#: ../../common/restricted_token.c:90 -#, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: konnte SIDs nicht erzeugen: Fehlercode %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: konnte beschränktes Token nicht erzeugen: Fehlercode %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" -#: ../../common/rmtree.c:77 +#: ../../common/rmtree.c:79 #, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %s\n" +msgid "could not stat file or directory \"%s\": %m" +msgstr "konnte »stat« für Datei oder Verzeichnis »%s« nicht ausführen: %m" -#: ../../common/rmtree.c:104 ../../common/rmtree.c:121 +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "konnte Datei oder Verzeichnis »%s« nicht entfernen: %s\n" +msgid "could not remove file or directory \"%s\": %m" +msgstr "konnte Datei oder Verzeichnis »%s« nicht entfernen: %m" #: ../../common/username.c:43 #, c-format @@ -182,22 +193,17 @@ msgstr "Befehl nicht gefunden" msgid "child process exited with exit code %d" msgstr "Kindprozess hat mit Code %d beendet" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" -#: ../../common/wait_error.c:71 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %s" -msgstr "Kindprozess wurde von Signal %s beendet" +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" -#: ../../common/wait_error.c:75 -#, c-format -msgid "child process was terminated by signal %d" -msgstr "Kindprozess wurde von Signal %d beendet" - -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "Kindprozess hat mit unbekanntem Status %d beendet" @@ -212,103 +218,101 @@ msgstr "konnte Junction für »%s« nicht erzeugen: %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "konnte Junction für »%s« nicht ermitteln: %s\n" -#: initdb.c:331 +#: initdb.c:495 initdb.c:1534 #, c-format -msgid "%s: out of memory\n" -msgstr "%s: Speicher aufgebraucht\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: initdb.c:441 initdb.c:1442 +#: initdb.c:550 initdb.c:858 initdb.c:884 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: konnte Datei »%s« nicht zum Lesen öffnen: %s\n" +msgid "could not open file \"%s\" for writing: %m" +msgstr "konnte Datei »%s« nicht zum Schreiben öffnen: %m" -#: initdb.c:497 initdb.c:813 initdb.c:841 +#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 #, c-format -msgid "%s: could not open file \"%s\" for writing: %s\n" -msgstr "%s: konnte Datei »%s« nicht zum Schreiben öffnen: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" -#: initdb.c:505 initdb.c:513 initdb.c:820 initdb.c:847 +#: initdb.c:582 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht schreiben: %s\n" +msgid "could not execute command \"%s\": %m" +msgstr "konnte Befehl »%s« nicht ausführen: %m" -#: initdb.c:532 +#: initdb.c:600 #, c-format -msgid "%s: could not execute command \"%s\": %s\n" -msgstr "%s: konnte Befehl »%s« nicht ausführen: %s\n" +msgid "removing data directory \"%s\"" +msgstr "entferne Datenverzeichnis »%s«" -#: initdb.c:548 +#: initdb.c:602 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s: entferne Datenverzeichnis »%s«\n" +msgid "failed to remove data directory" +msgstr "konnte Datenverzeichnis nicht entfernen" -#: initdb.c:551 +#: initdb.c:606 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s: konnte Datenverzeichnis nicht entfernen\n" +msgid "removing contents of data directory \"%s\"" +msgstr "entferne Inhalt des Datenverzeichnisses »%s«" -#: initdb.c:557 +#: initdb.c:609 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s: entferne Inhalt des Datenverzeichnisses »%s«\n" +msgid "failed to remove contents of data directory" +msgstr "konnte Inhalt des Datenverzeichnisses nicht entfernen" -#: initdb.c:560 +#: initdb.c:614 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s: konnte Inhalt des Datenverzeichnisses nicht entfernen\n" +msgid "removing WAL directory \"%s\"" +msgstr "entferne WAL-Verzeichnis »%s«" -#: initdb.c:566 +#: initdb.c:616 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s: entferne WAL-Verzeichnis »%s«\n" +msgid "failed to remove WAL directory" +msgstr "konnte WAL-Verzeichnis nicht entfernen" -#: initdb.c:569 +#: initdb.c:620 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s: konnte WAL-Verzeichnis nicht entfernen\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "entferne Inhalt des WAL-Verzeichnisses »%s«" -#: initdb.c:575 +#: initdb.c:622 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s: entferne Inhalt des WAL-Verzeichnisses »%s«\n" +msgid "failed to remove contents of WAL directory" +msgstr "konnte Inhalt des WAL-Verzeichnisses nicht entfernen" -#: initdb.c:578 +#: initdb.c:629 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s: konnte Inhalt des WAL-Verzeichnisses nicht entfernen\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" -#: initdb.c:587 +#: initdb.c:633 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s: Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" -#: initdb.c:592 +#: initdb.c:651 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s: WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt\n" +msgid "cannot be run as root" +msgstr "kann nicht als root ausgeführt werden" -#: initdb.c:613 +#: initdb.c:653 #, c-format msgid "" -"%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" "own the server process.\n" msgstr "" -"%s: kann nicht als root ausgeführt werden\n" "Bitte loggen Sie sich (z.B. mit »su«) als der (unprivilegierte) Benutzer\n" "ein, der Eigentümer des Serverprozesses sein soll.\n" -#: initdb.c:649 +#: initdb.c:686 #, c-format -msgid "%s: \"%s\" is not a valid server encoding name\n" -msgstr "%s: »%s« ist keine gültige Serverkodierung\n" +msgid "\"%s\" is not a valid server encoding name" +msgstr "»%s« ist keine gültige Serverkodierung" -#: initdb.c:769 +#: initdb.c:817 #, c-format -msgid "%s: file \"%s\" does not exist\n" -msgstr "%s: Datei »%s« existiert nicht\n" +msgid "file \"%s\" does not exist" +msgstr "Datei »%s« existiert nicht" -#: initdb.c:771 initdb.c:780 initdb.c:790 +#: initdb.c:819 initdb.c:826 initdb.c:835 #, c-format msgid "" "This might mean you have a corrupted installation or identified\n" @@ -317,119 +321,126 @@ msgstr "" "Das könnte bedeuten, dass Ihre Installation fehlerhaft ist oder dass Sie das\n" "falsche Verzeichnis mit der Kommandozeilenoption -L angegeben haben.\n" -#: initdb.c:777 +#: initdb.c:824 #, c-format -msgid "%s: could not access file \"%s\": %s\n" -msgstr "%s: konnte nicht auf Datei »%s« zugreifen: %s\n" +msgid "could not access file \"%s\": %m" +msgstr "konnte nicht auf Datei »%s« zugreifen: %m" -#: initdb.c:788 +#: initdb.c:833 #, c-format -msgid "%s: file \"%s\" is not a regular file\n" -msgstr "%s: Datei »%s« ist keine normale Datei\n" +msgid "file \"%s\" is not a regular file" +msgstr "Datei »%s« ist keine normale Datei" -#: initdb.c:933 +#: initdb.c:978 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "wähle Implementierung von dynamischem Shared Memory ... " + +#: initdb.c:987 #, c-format msgid "selecting default max_connections ... " msgstr "wähle Vorgabewert für max_connections ... " -#: initdb.c:963 +#: initdb.c:1018 #, c-format msgid "selecting default shared_buffers ... " msgstr "wähle Vorgabewert für shared_buffers ... " -#: initdb.c:996 +#: initdb.c:1052 #, c-format -msgid "selecting dynamic shared memory implementation ... " -msgstr "wähle Implementierung von dynamischem Shared Memory ... " +msgid "selecting default timezone ... " +msgstr "wähle Vorgabewert für timezone ... " -#: initdb.c:1014 +#: initdb.c:1086 msgid "creating configuration files ... " msgstr "erzeuge Konfigurationsdateien ... " -#: initdb.c:1146 initdb.c:1166 initdb.c:1253 initdb.c:1269 +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 #, c-format -msgid "%s: could not change permissions of \"%s\": %s\n" -msgstr "%s: konnte Zugriffsrechte von »%s« nicht ändern: %s\n" +msgid "could not change permissions of \"%s\": %m" +msgstr "konnte Zugriffsrechte von »%s« nicht ändern: %m" -#: initdb.c:1293 +#: initdb.c:1381 #, c-format msgid "running bootstrap script ... " msgstr "führe Bootstrap-Skript aus ... " -#: initdb.c:1309 +#: initdb.c:1393 #, c-format -msgid "" -"%s: input file \"%s\" does not belong to PostgreSQL %s\n" -"Check your installation or specify the correct path using the option -L.\n" +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "Eingabedatei »%s« gehört nicht zu PostgreSQL %s" + +#: initdb.c:1396 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" msgstr "" -"%s: Eingabedatei »%s« gehört nicht zu PostgreSQL %s\n" "Prüfen Sie Ihre Installation oder geben Sie den korrekten Pfad mit der\n" "Option -L an.\n" -#: initdb.c:1419 +#: initdb.c:1511 msgid "Enter new superuser password: " msgstr "Geben Sie das neue Superuser-Passwort ein: " -#: initdb.c:1420 +#: initdb.c:1512 msgid "Enter it again: " msgstr "Geben Sie es noch einmal ein: " -#: initdb.c:1423 +#: initdb.c:1515 #, c-format msgid "Passwords didn't match.\n" msgstr "Passwörter stimmten nicht überein.\n" -#: initdb.c:1449 +#: initdb.c:1541 #, c-format -msgid "%s: could not read password from file \"%s\": %s\n" -msgstr "%s: konnte Passwort nicht aus Datei »%s« lesen: %s\n" +msgid "could not read password from file \"%s\": %m" +msgstr "konnte Passwort nicht aus Datei »%s« lesen: %m" -#: initdb.c:1452 +#: initdb.c:1544 #, c-format -msgid "%s: password file \"%s\" is empty\n" -msgstr "%s: Passwortdatei »%s« ist leer\n" +msgid "password file \"%s\" is empty" +msgstr "Passwortdatei »%s« ist leer" -#: initdb.c:2012 +#: initdb.c:2107 #, c-format msgid "caught signal\n" msgstr "Signal abgefangen\n" -#: initdb.c:2018 +#: initdb.c:2113 #, c-format msgid "could not write to child process: %s\n" msgstr "konnte nicht an Kindprozess schreiben: %s\n" -#: initdb.c:2026 +#: initdb.c:2121 #, c-format msgid "ok\n" msgstr "ok\n" -#: initdb.c:2116 +#: initdb.c:2211 #, c-format -msgid "%s: setlocale() failed\n" -msgstr "%s: setlocale() fehlgeschlagen\n" +msgid "setlocale() failed" +msgstr "setlocale() fehlgeschlagen" -#: initdb.c:2134 +#: initdb.c:2232 #, c-format -msgid "%s: failed to restore old locale \"%s\"\n" -msgstr "%s: konnte alte Locale »%s« nicht wiederherstellen\n" +msgid "failed to restore old locale \"%s\"" +msgstr "konnte alte Locale »%s« nicht wiederherstellen" -#: initdb.c:2144 +#: initdb.c:2241 #, c-format -msgid "%s: invalid locale name \"%s\"\n" -msgstr "%s: ungültiger Locale-Name »%s«\n" +msgid "invalid locale name \"%s\"" +msgstr "ungültiger Locale-Name: »%s«" -#: initdb.c:2156 +#: initdb.c:2252 #, c-format -msgid "%s: invalid locale settings; check LANG and LC_* environment variables\n" -msgstr "%s: ungültige Locale-Einstellungen; prüfen Sie die Umgebungsvariablen LANG und LC_*\n" +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "ungültige Locale-Einstellungen; prüfen Sie die Umgebungsvariablen LANG und LC_*" -#: initdb.c:2184 +#: initdb.c:2279 #, c-format -msgid "%s: encoding mismatch\n" -msgstr "%s: unpassende Kodierungen\n" +msgid "encoding mismatch" +msgstr "unpassende Kodierungen" -#: initdb.c:2186 +#: initdb.c:2281 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -444,7 +455,7 @@ msgstr "" "führen. Starten Sie %s erneut und geben Sie entweder keine\n" "Kodierung explizit an oder wählen Sie eine passende Kombination.\n" -#: initdb.c:2258 +#: initdb.c:2353 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -453,17 +464,17 @@ msgstr "" "%s initialisiert einen PostgreSQL-Datenbankcluster.\n" "\n" -#: initdb.c:2259 +#: initdb.c:2354 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: initdb.c:2260 +#: initdb.c:2355 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [OPTION]... [DATENVERZEICHNIS]\n" -#: initdb.c:2261 +#: initdb.c:2356 #, c-format msgid "" "\n" @@ -472,41 +483,48 @@ msgstr "" "\n" "Optionen:\n" -#: initdb.c:2262 +#: initdb.c:2357 #, c-format msgid " -A, --auth=METHOD default authentication method for local connections\n" msgstr " -A, --auth=METHODE vorgegebene Authentifizierungsmethode für lokale Verbindungen\n" -#: initdb.c:2263 +#: initdb.c:2358 #, c-format msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" msgstr "" " --auth-host=METHODE vorgegebene Authentifizierungsmethode für lokale\n" " TCP/IP-Verbindungen\n" -#: initdb.c:2264 +#: initdb.c:2359 #, c-format msgid " --auth-local=METHOD default authentication method for local-socket connections\n" msgstr "" " --auth-local=METHODE vorgegebene Authentifizierungsmethode für Verbindungen\n" " auf lokalen Sockets\n" -#: initdb.c:2265 +#: initdb.c:2360 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]DATENVERZ Datenverzeichnis für diesen Datenbankcluster\n" -#: initdb.c:2266 +#: initdb.c:2361 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=KODIERUNG setze Standardkodierung für neue Datenbanken\n" -#: initdb.c:2267 +#: initdb.c:2362 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access Lese- und Ausführungsrechte am Datenverzeichnis\n" +" für Gruppe setzen\n" + +#: initdb.c:2363 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=LOCALE setze Standardlocale für neue Datenbanken\n" -#: initdb.c:2268 +#: initdb.c:2364 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -520,17 +538,17 @@ msgstr "" " für neue Datenbanken (Voreinstellung aus der\n" " Umgebung entnommen)\n" -#: initdb.c:2272 +#: initdb.c:2368 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale entspricht --locale=C\n" -#: initdb.c:2273 +#: initdb.c:2369 #, c-format msgid " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=DATEI lese Passwort des neuen Superusers aus Datei\n" -#: initdb.c:2274 +#: initdb.c:2370 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -539,22 +557,27 @@ msgstr "" " -T, --text-search-config=KFG\n" " Standardtextsuchekonfiguration\n" -#: initdb.c:2276 +#: initdb.c:2372 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=NAME Datenbank-Superusername\n" -#: initdb.c:2277 +#: initdb.c:2373 #, c-format msgid " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt frage nach Passwort für neuen Superuser\n" -#: initdb.c:2278 +#: initdb.c:2374 #, c-format msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" msgstr " -X, --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n" -#: initdb.c:2279 +#: initdb.c:2375 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=ZAHL Größe eines WAL-Segments, in Megabyte\n" + +#: initdb.c:2376 #, c-format msgid "" "\n" @@ -563,44 +586,44 @@ msgstr "" "\n" "Weniger häufig verwendete Optionen:\n" -#: initdb.c:2280 +#: initdb.c:2377 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug erzeuge eine Menge Debug-Ausgaben\n" -#: initdb.c:2281 +#: initdb.c:2378 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums Datenseitenprüfsummen verwenden\n" -#: initdb.c:2282 +#: initdb.c:2379 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L VERZEICHNIS wo sind die Eingabedateien zu finden\n" -#: initdb.c:2283 +#: initdb.c:2380 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean nach Fehlern nicht aufräumen\n" -#: initdb.c:2284 +#: initdb.c:2381 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr "" " -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" " geschrieben sind\n" -#: initdb.c:2285 +#: initdb.c:2382 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show zeige interne Einstellungen\n" -#: initdb.c:2286 +#: initdb.c:2383 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr " -S, --sync-only nur Datenverzeichnis synchronisieren\n" -#: initdb.c:2287 +#: initdb.c:2384 #, c-format msgid "" "\n" @@ -609,17 +632,17 @@ msgstr "" "\n" "Weitere Optionen:\n" -#: initdb.c:2288 +#: initdb.c:2385 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: initdb.c:2289 +#: initdb.c:2386 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: initdb.c:2290 +#: initdb.c:2387 #, c-format msgid "" "\n" @@ -630,84 +653,74 @@ msgstr "" "Wenn kein Datenverzeichnis angegeben ist, dann wird die Umgebungsvariable\n" "PGDATA verwendet.\n" -#: initdb.c:2292 +#: initdb.c:2389 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Berichten Sie Fehler an .\n" +"Berichten Sie Fehler an .\n" -#: initdb.c:2300 -msgid "" -"\n" -"WARNING: enabling \"trust\" authentication for local connections\n" -"You can change this by editing pg_hba.conf or using the option -A, or\n" -"--auth-local and --auth-host, the next time you run initdb.\n" -msgstr "" -"\n" -"WARNUNG: Authentifizierung für lokale Verbindungen auf »trust« gesetzt\n" -"Sie können dies ändern, indem Sie pg_hba.conf bearbeiten oder beim\n" -"nächsten Aufruf von initdb die Option -A, oder --auth-local und\n" -"--auth-host, verwenden.\n" +#: initdb.c:2417 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "ungültige Authentifizierungsmethode »%s« für »%s«-Verbindungen" -#: initdb.c:2322 +#: initdb.c:2433 #, c-format -msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" -msgstr "%s: ungültige Authentifizierungsmethode »%s« für »%s«-Verbindungen\n" +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "Superuser-Passwort muss angegeben werden um %s-Authentifizierung einzuschalten" -#: initdb.c:2338 +#: initdb.c:2460 #, c-format -msgid "%s: must specify a password for the superuser to enable %s authentication\n" -msgstr "%s: Superuser-Passwort muss angegeben werden um %s-Authentifizierung einzuschalten\n" +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" -#: initdb.c:2366 +#: initdb.c:2462 #, c-format msgid "" -"%s: no data directory specified\n" "You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" "environment variable PGDATA.\n" msgstr "" -"%s: kein Datenverzeichnis angegeben\n" "Sie müssen das Verzeichnis angeben, wo dieses Datenbanksystem abgelegt\n" "werden soll. Machen Sie dies entweder mit der Kommandozeilenoption -D\n" "oder mit der Umgebungsvariable PGDATA.\n" -#: initdb.c:2404 +#: initdb.c:2497 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Das Programm »postgres« wird von %s benötigt, aber wurde nicht im\n" "selben Verzeichnis wie »%s« gefunden.\n" -"Prüfen Sie Ihre Installation.\n" +"Prüfen Sie Ihre Installation." -#: initdb.c:2411 +#: initdb.c:2502 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Das Programm »postgres« wurde von %s gefunden,\n" "aber es hatte nicht die gleiche Version wie %s.\n" -"Prüfen Sie Ihre Installation.\n" +"Prüfen Sie Ihre Installation." -#: initdb.c:2430 +#: initdb.c:2521 #, c-format -msgid "%s: input file location must be an absolute path\n" -msgstr "%s: Eingabedatei muss absoluten Pfad haben\n" +msgid "input file location must be an absolute path" +msgstr "Eingabedatei muss absoluten Pfad haben" -#: initdb.c:2449 +#: initdb.c:2538 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "Der Datenbankcluster wird mit der Locale »%s« initialisiert werden.\n" -#: initdb.c:2452 +#: initdb.c:2541 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -726,22 +739,22 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2476 +#: initdb.c:2565 #, c-format -msgid "%s: could not find suitable encoding for locale \"%s\"\n" -msgstr "%s: konnte keine passende Kodierung für Locale »%s« finden\n" +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "konnte keine passende Kodierung für Locale »%s« finden" -#: initdb.c:2478 +#: initdb.c:2567 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "Führen Sie %s erneut mit der Option -E aus.\n" -#: initdb.c:2479 initdb.c:3103 initdb.c:3124 +#: initdb.c:2568 initdb.c:3196 initdb.c:3217 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: initdb.c:2491 +#: initdb.c:2581 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -750,12 +763,12 @@ msgstr "" "Die von der Locale gesetzte Kodierung »%s« ist nicht als serverseitige Kodierung erlaubt.\n" "Die Standarddatenbankkodierung wird stattdessen auf »%s« gesetzt.\n" -#: initdb.c:2499 +#: initdb.c:2586 #, c-format -msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" -msgstr "%s: Locale »%s« benötigt nicht unterstützte Kodierung »%s«\n" +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "Locale »%s« benötigt nicht unterstützte Kodierung »%s«" -#: initdb.c:2502 +#: initdb.c:2589 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -764,57 +777,57 @@ msgstr "" "Kodierung »%s« ist nicht als serverseitige Kodierung erlaubt.\n" "Starten Sie %s erneut mit einer anderen Locale-Wahl.\n" -#: initdb.c:2511 +#: initdb.c:2598 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "Die Standarddatenbankkodierung wurde entsprechend auf »%s« gesetzt.\n" -#: initdb.c:2582 +#: initdb.c:2666 #, c-format msgid "%s: could not find suitable text search configuration for locale \"%s\"\n" msgstr "%s: konnte keine passende Textsuchekonfiguration für Locale »%s« finden\n" -#: initdb.c:2593 +#: initdb.c:2677 #, c-format msgid "%s: warning: suitable text search configuration for locale \"%s\" is unknown\n" msgstr "%s: Warnung: passende Textsuchekonfiguration für Locale »%s« ist unbekannt\n" -#: initdb.c:2598 +#: initdb.c:2682 #, c-format msgid "%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n" msgstr "%s: Warnung: angegebene Textsuchekonfiguration »%s« passt möglicherweise nicht zur Locale »%s«\n" -#: initdb.c:2603 +#: initdb.c:2687 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "Die Standardtextsuchekonfiguration wird auf »%s« gesetzt.\n" -#: initdb.c:2647 initdb.c:2733 +#: initdb.c:2731 initdb.c:2813 #, c-format msgid "creating directory %s ... " msgstr "erzeuge Verzeichnis %s ... " -#: initdb.c:2653 initdb.c:2739 initdb.c:2807 initdb.c:2863 +#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht erzeugen: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: initdb.c:2665 initdb.c:2751 +#: initdb.c:2748 initdb.c:2831 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "berichtige Zugriffsrechte des bestehenden Verzeichnisses %s ... " -#: initdb.c:2671 initdb.c:2757 +#: initdb.c:2754 initdb.c:2837 #, c-format -msgid "%s: could not change permissions of directory \"%s\": %s\n" -msgstr "%s: konnte Rechte des Verzeichnisses »%s« nicht ändern: %s\n" +msgid "could not change permissions of directory \"%s\": %m" +msgstr "konnte Rechte des Verzeichnisses »%s« nicht ändern: %m" -#: initdb.c:2686 initdb.c:2772 +#: initdb.c:2768 initdb.c:2851 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s: Verzeichnis »%s« existiert aber ist nicht leer\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "Verzeichnis »%s« existiert aber ist nicht leer" -#: initdb.c:2692 +#: initdb.c:2773 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -825,17 +838,17 @@ msgstr "" "Sie das Verzeichnis »%s« or führen Sie %s\n" "mit einem anderen Argument als »%s« aus.\n" -#: initdb.c:2700 initdb.c:2785 initdb.c:3137 +#: initdb.c:2781 initdb.c:2863 initdb.c:3232 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" +msgid "could not access directory \"%s\": %m" +msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" -#: initdb.c:2724 +#: initdb.c:2804 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" -msgstr "%s: WAL-Verzeichnis muss absoluten Pfad haben\n" +msgid "WAL directory location must be an absolute path" +msgstr "WAL-Verzeichnis muss absoluten Pfad haben" -#: initdb.c:2778 +#: initdb.c:2856 #, c-format msgid "" "If you want to store the WAL there, either remove or empty the directory\n" @@ -844,27 +857,27 @@ msgstr "" "Wenn Sie dort den WAL ablegen wollen, entfernen oder leeren Sie das\n" "Verzeichnis »%s«.\n" -#: initdb.c:2793 +#: initdb.c:2870 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s: konnte symbolische Verknüpfung »%s« nicht erzeugen: %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" -#: initdb.c:2798 +#: initdb.c:2875 #, c-format -msgid "%s: symlinks are not supported on this platform" -msgstr "%s: symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" +msgid "symlinks are not supported on this platform" +msgstr "symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" -#: initdb.c:2822 +#: initdb.c:2899 #, c-format msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" msgstr "Es enthält eine unsichtbare Datei (beginnt mit Punkt), vielleicht weil es ein Einhängepunkt ist.\n" -#: initdb.c:2825 +#: initdb.c:2902 #, c-format msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" msgstr "Es enthält ein Verzeichnis »lost+found«, vielleicht weil es ein Einhängepunkt ist.\n" -#: initdb.c:2828 +#: initdb.c:2905 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -873,45 +886,55 @@ msgstr "" "Einen Einhängepunkt direkt als Datenverzeichnis zu verwenden wird nicht empfohlen.\n" "Erzeugen Sie ein Unterverzeichnis unter dem Einhängepunkt.\n" -#: initdb.c:2848 +#: initdb.c:2931 #, c-format msgid "creating subdirectories ... " msgstr "erzeuge Unterverzeichnisse ... " -#: initdb.c:2895 +#: initdb.c:2977 msgid "performing post-bootstrap initialization ... " msgstr "führe Post-Bootstrap-Initialisierung durch ... " -#: initdb.c:3047 +#: initdb.c:3134 #, c-format msgid "Running in debug mode.\n" msgstr "Debug-Modus ist an.\n" -#: initdb.c:3051 +#: initdb.c:3138 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "No-Clean-Modus ist an. Bei Fehlern wird nicht aufgeräumt.\n" -#: initdb.c:3122 +#: initdb.c:3215 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: initdb.c:3142 initdb.c:3208 +#: initdb.c:3236 initdb.c:3325 msgid "syncing data to disk ... " msgstr "synchronisiere Daten auf Festplatte ... " -#: initdb.c:3151 +#: initdb.c:3245 #, c-format -msgid "%s: password prompt and password file cannot be specified together\n" -msgstr "%s: Passwortprompt und Passwortdatei können nicht zusammen angegeben werden\n" +msgid "password prompt and password file cannot be specified together" +msgstr "Passwortprompt und Passwortdatei können nicht zusammen angegeben werden" -#: initdb.c:3175 +#: initdb.c:3270 #, c-format -msgid "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"\n" -msgstr "%s: Superuser-Name »%s« nicht erlaubt; Rollennamen können nicht mit »pg_« anfangen\n" +msgid "argument of --wal-segsize must be a number" +msgstr "Argument von --wal-segsize muss eine Zahl sein" -#: initdb.c:3179 +#: initdb.c:3275 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "Argument von --wal-segsize muss eine Zweierpotenz zwischen 1 und 1024 sein" + +#: initdb.c:3292 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "Superuser-Name »%s« nicht erlaubt; Rollennamen können nicht mit »pg_« anfangen" + +#: initdb.c:3296 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -922,17 +945,17 @@ msgstr "" "»%s« gehören. Diesem Benutzer muss auch der Serverprozess gehören.\n" "\n" -#: initdb.c:3195 +#: initdb.c:3312 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Datenseitenprüfsummen sind eingeschaltet.\n" -#: initdb.c:3197 +#: initdb.c:3314 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Datenseitenprüfsummen sind ausgeschaltet.\n" -#: initdb.c:3214 +#: initdb.c:3331 #, c-format msgid "" "\n" @@ -943,12 +966,27 @@ msgstr "" "Synchronisation auf Festplatte übersprungen.\n" "Das Datenverzeichnis könnte verfälscht werden, falls das Betriebssystem abstürzt.\n" +#: initdb.c:3336 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "Authentifizierung für lokale Verbindungen auf »trust« gesetzt" + +#: initdb.c:3337 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Sie können dies ändern, indem Sie pg_hba.conf bearbeiten oder beim\n" +"nächsten Aufruf von initdb die Option -A, oder --auth-local und\n" +"--auth-host, verwenden.\n" + #. translator: This is a placeholder in a shell command. -#: initdb.c:3240 +#: initdb.c:3362 msgid "logfile" msgstr "logdatei" -#: initdb.c:3242 +#: initdb.c:3364 #, c-format msgid "" "\n" diff --git a/src/bin/initdb/po/es.po b/src/bin/initdb/po/es.po index b9f16b18e10..7c5b832a03f 100644 --- a/src/bin/initdb/po/es.po +++ b/src/bin/initdb/po/es.po @@ -1,59 +1,80 @@ # Spanish translation of initdb. # -# Copyright (C) 2004-2014 PostgreSQL Global Development Group +# Copyright (c) 2004-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Ãlvaro Herrera , 2004-2013 -# Carlos Chapi , 2014 +# Carlos Chapi , 2014, 2018 # msgid "" msgstr "" -"Project-Id-Version: initdb (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:46+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Project-Id-Version: initdb (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:14+0000\n" +"PO-Revision-Date: 2019-06-06 17:21-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "fatal: " +msgstr "fatal: " -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar el directorio a «%s»: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "pclose failed: %m" +msgstr "pclose falló: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: initdb.c:339 +#, c-format +msgid "out of memory" +msgstr "memoria agotada" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -66,96 +87,86 @@ msgstr "memoria agotada\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "no se puede duplicar un puntero nulo (error interno)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 -#, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: no se pudo hacer stat del archivo «%s»: %s\n" - -#: ../../common/file_utils.c:162 -#, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: no se pudo abrir el directorio «%s»: %s\n" - -#: ../../common/file_utils.c:198 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: no se pudo leer el directorio «%s»: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo «%s»: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: no se pudo sincronizar (fsync) el archivo «%s»: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: no se pudo cambiar el nombre al archivo «%s» a «%s»: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" -#: ../../common/pgfnames.c:45 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "no se pudo abrir el directorio «%s»: %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" -#: ../../common/pgfnames.c:72 +#: ../../common/file_utils.c:377 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "no se pudo leer el directorio «%s»: %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" -#: ../../common/pgfnames.c:84 +#: ../../common/pgfnames.c:74 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "no se pudo cerrar el directorio «%s»: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:69 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" +msgid "cannot create restricted tokens on this platform" +msgstr "no se pueden crear tokens restrigidos en esta plataforma" -#: ../../common/restricted_token.c:77 +#: ../../common/restricted_token.c:78 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" -#: ../../common/restricted_token.c:90 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: no se pudo iniciar el proceso para la orden «%s»: código de error %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: no se pudo re-ejecutar con el token restringido: código de error %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: no se pudo obtener el código de salida del subproceso»: código de error %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" -#: ../../common/rmtree.c:77 +#: ../../common/rmtree.c:79 #, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "no se pudo hacer stat al archivo o directorio «%s»: %s\n" +msgid "could not stat file or directory \"%s\": %m" +msgstr "no se pudo hacer stat al archivo o directorio «%s»: %m" -#: ../../common/rmtree.c:104 ../../common/rmtree.c:121 +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "no se pudo borrar el archivo o el directorio «%s»: %s\n" +msgid "could not remove file or directory \"%s\": %m" +msgstr "no se pudo borrar el archivo o el directorio «%s»: %m" #: ../../common/username.c:43 #, c-format @@ -186,22 +197,17 @@ msgstr "orden no encontrada" msgid "child process exited with exit code %d" msgstr "el proceso hijo terminó con código de salida %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "el proceso hijo fue terminado por una excepción 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "el proceso hijo fue terminado por una señal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "el proceso hijo fue terminado por una señal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "el proceso hijo terminó con código no reconocido %d" @@ -216,103 +222,101 @@ msgstr "no se pudo definir un junction para «%s»: %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "no se pudo obtener junction para «%s»: %s\n" -#: initdb.c:331 +#: initdb.c:495 initdb.c:1534 #, c-format -msgid "%s: out of memory\n" -msgstr "%s: memoria agotada\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" -#: initdb.c:441 initdb.c:1442 +#: initdb.c:550 initdb.c:858 initdb.c:884 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: no se pudo abrir el archivo «%s» para lectura: %s\n" +msgid "could not open file \"%s\" for writing: %m" +msgstr "no se pudo abrir el archivo «%s» para escritura: %m" -#: initdb.c:497 initdb.c:813 initdb.c:841 +#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 #, c-format -msgid "%s: could not open file \"%s\" for writing: %s\n" -msgstr "%s: no se pudo abrir el archivo «%s» para escritura: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" -#: initdb.c:505 initdb.c:513 initdb.c:820 initdb.c:847 +#: initdb.c:582 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: no se pudo escribir el archivo «%s»: %s\n" +msgid "could not execute command \"%s\": %m" +msgstr "no se pudo ejecutar la orden «%s»: %m" -#: initdb.c:532 +#: initdb.c:600 #, c-format -msgid "%s: could not execute command \"%s\": %s\n" -msgstr "%s: no se pudo ejecutar la orden «%s»: %s\n" +msgid "removing data directory \"%s\"" +msgstr "eliminando el directorio de datos «%s»" -#: initdb.c:548 +#: initdb.c:602 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s: eliminando el directorio de datos «%s»\n" +msgid "failed to remove data directory" +msgstr "no se pudo eliminar el directorio de datos" -#: initdb.c:551 +#: initdb.c:606 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s: no se pudo eliminar el directorio de datos\n" +msgid "removing contents of data directory \"%s\"" +msgstr "eliminando el contenido del directorio «%s»" -#: initdb.c:557 +#: initdb.c:609 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s: eliminando el contenido del directorio «%s»\n" +msgid "failed to remove contents of data directory" +msgstr "no se pudo eliminar el contenido del directorio de datos" -#: initdb.c:560 +#: initdb.c:614 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s: no se pudo eliminar el contenido del directorio de datos\n" +msgid "removing WAL directory \"%s\"" +msgstr "eliminando el directorio de WAL «%s»" -#: initdb.c:566 +#: initdb.c:616 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s: eliminando el directorio WAL «%s»\n" +msgid "failed to remove WAL directory" +msgstr "no se pudo eliminar el directorio de WAL" -#: initdb.c:569 +#: initdb.c:620 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s: no se pudo eliminar el directorio WAL\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "eliminando el contenido del directorio de WAL «%s»" -#: initdb.c:575 +#: initdb.c:622 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s: eliminando el contenido del directorio WAL «%s»\n" +msgid "failed to remove contents of WAL directory" +msgstr "no se pudo eliminar el contenido del directorio de WAL" -#: initdb.c:578 +#: initdb.c:629 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s: no se pudo eliminar el contenido del directorio WAL\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "directorio de datos «%s» no eliminado a petición del usuario" -#: initdb.c:587 +#: initdb.c:633 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s: directorio de datos «%s» no eliminado a petición del usuario\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "directorio de WAL «%s» no eliminado a petición del usuario" -#: initdb.c:592 +#: initdb.c:651 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s: directorio WAL «%s» no eliminado a petición del usuario\n" +msgid "cannot be run as root" +msgstr "no se puede ejecutar como «root»" -#: initdb.c:613 +#: initdb.c:653 #, c-format msgid "" -"%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" "own the server process.\n" msgstr "" -"%s: no se puede ejecutar como «root»\n" "Por favor conéctese (usando, por ejemplo, «su») con un usuario no privilegiado,\n" "quien ejecutará el proceso servidor.\n" -#: initdb.c:649 +#: initdb.c:686 #, c-format -msgid "%s: \"%s\" is not a valid server encoding name\n" -msgstr "%s: «%s» no es un nombre válido de codificación\n" +msgid "\"%s\" is not a valid server encoding name" +msgstr "«%s» no es un nombre válido de codificación" -#: initdb.c:769 +#: initdb.c:817 #, c-format -msgid "%s: file \"%s\" does not exist\n" -msgstr "%s: el archivo «%s» no existe\n" +msgid "file \"%s\" does not exist" +msgstr "el archivo «%s» no existe" -#: initdb.c:771 initdb.c:780 initdb.c:790 +#: initdb.c:819 initdb.c:826 initdb.c:835 #, c-format msgid "" "This might mean you have a corrupted installation or identified\n" @@ -321,118 +325,124 @@ msgstr "" "Esto puede significar que tiene una instalación corrupta o ha\n" "identificado el directorio equivocado con la opción -L.\n" -#: initdb.c:777 +#: initdb.c:824 #, c-format -msgid "%s: could not access file \"%s\": %s\n" -msgstr "%s: no se pudo acceder al archivo «%s»: %s\n" +msgid "could not access file \"%s\": %m" +msgstr "no se pudo acceder al archivo «%s»: %m" -#: initdb.c:788 +#: initdb.c:833 #, c-format -msgid "%s: file \"%s\" is not a regular file\n" -msgstr "%s: el archivo «%s» no es un archivo regular\n" +msgid "file \"%s\" is not a regular file" +msgstr "el archivo «%s» no es un archivo regular" -#: initdb.c:933 +#: initdb.c:978 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "seleccionando implementación de memoria compartida dinámica ..." + +#: initdb.c:987 #, c-format msgid "selecting default max_connections ... " msgstr "seleccionando el valor para max_connections ... " -#: initdb.c:963 +#: initdb.c:1018 #, c-format msgid "selecting default shared_buffers ... " msgstr "seleccionando el valor para shared_buffers ... " -#: initdb.c:996 +#: initdb.c:1052 #, c-format -msgid "selecting dynamic shared memory implementation ... " -msgstr "seleccionando implementación de memoria compartida dinámica ..." +msgid "selecting default timezone ... " +msgstr "seleccionando el huso horario por omisión ... " -#: initdb.c:1014 +#: initdb.c:1086 msgid "creating configuration files ... " msgstr "creando archivos de configuración ... " -#: initdb.c:1146 initdb.c:1166 initdb.c:1253 initdb.c:1269 +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 #, c-format -msgid "%s: could not change permissions of \"%s\": %s\n" -msgstr "%s: no se pudo cambiar los permisos de «%s»: %s\n" +msgid "could not change permissions of \"%s\": %m" +msgstr "no se pudo cambiar los permisos de «%s»: %m" -#: initdb.c:1293 +#: initdb.c:1381 #, c-format msgid "running bootstrap script ... " msgstr "ejecutando script de inicio (bootstrap) ... " -#: initdb.c:1309 +#: initdb.c:1393 #, c-format -msgid "" -"%s: input file \"%s\" does not belong to PostgreSQL %s\n" -"Check your installation or specify the correct path using the option -L.\n" -msgstr "" -"%s: el archivo de entrada «%s» no pertenece a PostgreSQL %s\n" -"Verifique su instalación o especifique la ruta correcta usando la opción -L.\n" +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "el archivo de entrada «%s» no pertenece a PostgreSQL %s" -#: initdb.c:1419 +#: initdb.c:1396 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Verifique su instalación o especifique la ruta correcta usando la opción -L.\n" + +#: initdb.c:1511 msgid "Enter new superuser password: " msgstr "Ingrese la nueva contraseña del superusuario: " -#: initdb.c:1420 +#: initdb.c:1512 msgid "Enter it again: " msgstr "Ingrésela nuevamente: " -#: initdb.c:1423 +#: initdb.c:1515 #, c-format msgid "Passwords didn't match.\n" msgstr "Las constraseñas no coinciden.\n" -#: initdb.c:1449 +#: initdb.c:1541 #, c-format -msgid "%s: could not read password from file \"%s\": %s\n" -msgstr "%s: no se pudo leer la contraseña desde el archivo «%s»: %s\n" +msgid "could not read password from file \"%s\": %m" +msgstr "no se pudo leer la contraseña desde el archivo «%s»: %m" -#: initdb.c:1452 +#: initdb.c:1544 #, c-format -msgid "%s: password file \"%s\" is empty\n" -msgstr "%s: el archivo de contraseña «%s» está vacío\n" +msgid "password file \"%s\" is empty" +msgstr "el archivo de contraseña «%s» está vacío" -#: initdb.c:2012 +#: initdb.c:2107 #, c-format msgid "caught signal\n" msgstr "se ha capturado una señal\n" -#: initdb.c:2018 +#: initdb.c:2113 #, c-format msgid "could not write to child process: %s\n" msgstr "no se pudo escribir al proceso hijo: %s\n" -#: initdb.c:2026 +#: initdb.c:2121 #, c-format msgid "ok\n" msgstr "hecho\n" -#: initdb.c:2116 +#: initdb.c:2211 #, c-format -msgid "%s: setlocale() failed\n" -msgstr "%s: setlocale() falló\n" +msgid "setlocale() failed" +msgstr "setlocale() falló" -#: initdb.c:2134 +#: initdb.c:2232 #, c-format -msgid "%s: failed to restore old locale \"%s\"\n" -msgstr "%s: no se pudo restaurar la configuración regional anterior «%s»\n" +msgid "failed to restore old locale \"%s\"" +msgstr "no se pudo restaurar la configuración regional anterior «%s»" -#: initdb.c:2144 +#: initdb.c:2241 #, c-format -msgid "%s: invalid locale name \"%s\"\n" -msgstr "%s: nombre de configuración regional «%s» no es válido\n" +msgid "invalid locale name \"%s\"" +msgstr "nombre de configuración regional «%s» no es válido" -#: initdb.c:2156 +#: initdb.c:2252 #, c-format -msgid "%s: invalid locale settings; check LANG and LC_* environment variables\n" -msgstr "%s: configuración regional inválida; revise las variables de entorno LANG y LC_*\n" +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "configuración regional inválida; revise las variables de entorno LANG y LC_*" -#: initdb.c:2184 +#: initdb.c:2279 #, c-format -msgid "%s: encoding mismatch\n" -msgstr "%s: codificaciones no coinciden\n" +msgid "encoding mismatch" +msgstr "codificaciones no coinciden" -#: initdb.c:2186 +#: initdb.c:2281 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -447,7 +457,7 @@ msgstr "" "Ejecute %s nuevamente y no especifique una codificación, o bien especifique\n" "una combinación adecuada.\n" -#: initdb.c:2258 +#: initdb.c:2353 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -456,17 +466,17 @@ msgstr "" "%s inicializa un cluster de base de datos PostgreSQL.\n" "\n" -#: initdb.c:2259 +#: initdb.c:2354 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: initdb.c:2260 +#: initdb.c:2355 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [OPCIÓN]... [DATADIR]\n" -#: initdb.c:2261 +#: initdb.c:2356 #, c-format msgid "" "\n" @@ -475,45 +485,52 @@ msgstr "" "\n" "Opciones:\n" -#: initdb.c:2262 +#: initdb.c:2357 #, c-format msgid " -A, --auth=METHOD default authentication method for local connections\n" msgstr "" " -A, --auth=MÉTODO método de autentificación por omisión para\n" " conexiones locales\n" -#: initdb.c:2263 +#: initdb.c:2358 #, c-format msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" msgstr "" " --auth-host=MÉTODO método de autentificación por omisión para\n" " conexiones locales TCP/IP\n" -#: initdb.c:2264 +#: initdb.c:2359 #, c-format msgid " --auth-local=METHOD default authentication method for local-socket connections\n" msgstr "" " --auth-local=MÉTODO método de autentificación por omisión para\n" " conexiones de socket local\n" -#: initdb.c:2265 +#: initdb.c:2360 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]DATADIR ubicación para este cluster de bases de datos\n" -#: initdb.c:2266 +#: initdb.c:2361 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=CODIF codificación por omisión para nuevas bases de datos\n" -#: initdb.c:2267 +#: initdb.c:2362 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access dar al grupo permisos de lectura/ejecución sobre\n" +" el directorio de datos\n" + +#: initdb.c:2363 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr "" " --locale=LOCALE configuración regional por omisión para \n" " nuevas bases de datos\n" -#: initdb.c:2268 +#: initdb.c:2364 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -527,17 +544,17 @@ msgstr "" " en la categoría respectiva (el valor por omisión\n" " es tomado de variables de ambiente)\n" -#: initdb.c:2272 +#: initdb.c:2368 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale equivalente a --locale=C\n" -#: initdb.c:2273 +#: initdb.c:2369 #, c-format msgid " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=ARCHIVO leer contraseña del nuevo superusuario del archivo\n" -#: initdb.c:2274 +#: initdb.c:2370 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -546,22 +563,27 @@ msgstr "" " -T, --text-search-config=CONF\n" " configuración de búsqueda en texto por omisión\n" -#: initdb.c:2276 +#: initdb.c:2372 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=USUARIO nombre del superusuario del cluster\n" -#: initdb.c:2277 +#: initdb.c:2373 #, c-format msgid " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt pedir una contraseña para el nuevo superusuario\n" -#: initdb.c:2278 +#: initdb.c:2374 #, c-format msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" msgstr " -X, --waldir=WALDIR ubicación del directorio WAL\n" -#: initdb.c:2279 +#: initdb.c:2375 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAMAÑO tamaño de los segmentos de WAL, en megabytes\n" + +#: initdb.c:2376 #, c-format msgid "" "\n" @@ -570,42 +592,42 @@ msgstr "" "\n" "Opciones menos usadas:\n" -#: initdb.c:2280 +#: initdb.c:2377 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug genera mucha salida de depuración\n" -#: initdb.c:2281 +#: initdb.c:2378 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums activar sumas de verificación en páginas de datos\n" -#: initdb.c:2282 +#: initdb.c:2379 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L DIRECTORIO donde encontrar los archivos de entrada\n" -#: initdb.c:2283 +#: initdb.c:2380 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean no limpiar después de errores\n" -#: initdb.c:2284 +#: initdb.c:2381 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" -#: initdb.c:2285 +#: initdb.c:2382 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show muestra variables internas\n" -#: initdb.c:2286 +#: initdb.c:2383 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr " -S, --sync-only sólo sincronizar el directorio de datos\n" -#: initdb.c:2287 +#: initdb.c:2384 #, c-format msgid "" "\n" @@ -614,17 +636,17 @@ msgstr "" "\n" "Otras opciones:\n" -#: initdb.c:2288 +#: initdb.c:2385 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de version y salir\n" -#: initdb.c:2289 +#: initdb.c:2386 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: initdb.c:2290 +#: initdb.c:2387 #, c-format msgid "" "\n" @@ -635,84 +657,75 @@ msgstr "" "Si el directorio de datos no es especificado, se usa la variable de\n" "ambiente PGDATA.\n" -#: initdb.c:2292 +#: initdb.c:2389 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" -#: initdb.c:2300 -msgid "" -"\n" -"WARNING: enabling \"trust\" authentication for local connections\n" -"You can change this by editing pg_hba.conf or using the option -A, or\n" -"--auth-local and --auth-host, the next time you run initdb.\n" -msgstr "" -"\n" -"ATENCIÓN: activando autentificación «trust» para conexiones locales.\n" -"Puede cambiar esto editando pg_hba.conf o usando el parámetro -A,\n" -"o --auth-local y --auth-host la próxima vez que ejecute initdb.\n" - -#: initdb.c:2322 +#: initdb.c:2417 #, c-format -msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" -msgstr "%s: método de autentificación «%s» no válido para conexiones «%s»\n" +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "método de autentificación «%s» no válido para conexiones «%s»" -#: initdb.c:2338 +#: initdb.c:2433 #, c-format -msgid "%s: must specify a password for the superuser to enable %s authentication\n" +msgid "must specify a password for the superuser to enable %s authentication" msgstr "" -"%s: debe especificar una contraseña al superusuario para activar\n" -"autentificación %s\n" +"debe especificar una contraseña al superusuario para activar\n" +"autentificación %s" + +#: initdb.c:2460 +#, c-format +msgid "no data directory specified" +msgstr "no se especificó un directorio de datos" -#: initdb.c:2366 +#: initdb.c:2462 #, c-format msgid "" -"%s: no data directory specified\n" "You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" "environment variable PGDATA.\n" msgstr "" -"%s: no se especificó un directorio de datos.\n" -"Debe especificar el directorio donde residirán los datos para este cluster.\n" +"Debe especificar el directorio donde residirán los datos para este clúster.\n" "Hágalo usando la opción -D o la variable de ambiente PGDATA.\n" -#: initdb.c:2404 +#: initdb.c:2497 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "%s necesita el programa «postgres», pero no pudo encontrarlo en el mismo\n" "directorio que «%s».\n" -"Verifique su instalación.\n" +"Verifique su instalación." -#: initdb.c:2411 +#: initdb.c:2502 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "El programa «postgres» fue encontrado por %s, pero no es\n" "de la misma versión que «%s».\n" -"Verifique su instalación.\n" +"Verifique su instalación." -#: initdb.c:2430 +#: initdb.c:2521 #, c-format -msgid "%s: input file location must be an absolute path\n" -msgstr "%s: la ubicación de archivos de entrada debe ser una ruta absoluta\n" +msgid "input file location must be an absolute path" +msgstr "la ubicación de archivos de entrada debe ser una ruta absoluta" -#: initdb.c:2449 +#: initdb.c:2538 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "El cluster será inicializado con configuración regional «%s».\n" -#: initdb.c:2452 +#: initdb.c:2541 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -731,24 +744,24 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2476 +#: initdb.c:2565 #, c-format -msgid "%s: could not find suitable encoding for locale \"%s\"\n" +msgid "could not find suitable encoding for locale \"%s\"" msgstr "" -"%s: no se pudo encontrar una codificación apropiada para\n" -"la configuración regional «%s»\n" +"no se pudo encontrar una codificación apropiada para\n" +"la configuración regional «%s»" -#: initdb.c:2478 +#: initdb.c:2567 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "Ejecute %s con la opción -E.\n" -#: initdb.c:2479 initdb.c:3103 initdb.c:3124 +#: initdb.c:2568 initdb.c:3196 initdb.c:3217 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Use «%s --help» para obtener mayor información.\n" -#: initdb.c:2491 +#: initdb.c:2581 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -758,12 +771,12 @@ msgstr "" "no puede ser usada como codificación del lado del servidor.\n" "La codificación por omisión será «%s».\n" -#: initdb.c:2499 +#: initdb.c:2586 #, c-format -msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" -msgstr "%s: la configuración regional «%s» requiere la codificación no soportada «%s»\n" +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "la configuración regional «%s» requiere la codificación no soportada «%s»" -#: initdb.c:2502 +#: initdb.c:2589 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -773,63 +786,63 @@ msgstr "" "del servidor.\n" "Ejecute %s nuevamente con una selección de configuración regional diferente.\n" -#: initdb.c:2511 +#: initdb.c:2598 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "La codificación por omisión ha sido por lo tanto definida a «%s».\n" -#: initdb.c:2582 +#: initdb.c:2666 #, c-format msgid "%s: could not find suitable text search configuration for locale \"%s\"\n" msgstr "" "%s: no se pudo encontrar una configuración para búsqueda en texto apropiada\n" "para la configuración regional «%s»\n" -#: initdb.c:2593 +#: initdb.c:2677 #, c-format msgid "%s: warning: suitable text search configuration for locale \"%s\" is unknown\n" msgstr "" "%s: atención: la configuración de búsqueda en texto apropiada para\n" "la configuración regional «%s» es desconocida\n" -#: initdb.c:2598 +#: initdb.c:2682 #, c-format msgid "%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n" msgstr "" "%s: atención: la configuración de búsqueda en texto «%s» especificada\n" "podría no coincidir con la configuración regional «%s»\n" -#: initdb.c:2603 +#: initdb.c:2687 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "La configuración de búsqueda en texto ha sido definida a «%s».\n" -#: initdb.c:2647 initdb.c:2733 +#: initdb.c:2731 initdb.c:2813 #, c-format msgid "creating directory %s ... " msgstr "creando el directorio %s ... " -#: initdb.c:2653 initdb.c:2739 initdb.c:2807 initdb.c:2863 +#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s: no se pudo crear el directorio «%s»: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" -#: initdb.c:2665 initdb.c:2751 +#: initdb.c:2748 initdb.c:2831 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "corrigiendo permisos en el directorio existente %s ... " -#: initdb.c:2671 initdb.c:2757 +#: initdb.c:2754 initdb.c:2837 #, c-format -msgid "%s: could not change permissions of directory \"%s\": %s\n" -msgstr "%s: no se pudo cambiar los permisos del directorio «%s»: %s\n" +msgid "could not change permissions of directory \"%s\": %m" +msgstr "no se pudo cambiar los permisos del directorio «%s»: %m" -#: initdb.c:2686 initdb.c:2772 +#: initdb.c:2768 initdb.c:2851 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s: el directorio «%s» no está vacío\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "el directorio «%s» existe pero no está vacío" -#: initdb.c:2692 +#: initdb.c:2773 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -840,17 +853,17 @@ msgstr "" "el directorio «%s», o ejecute %s\n" "con un argumento distinto de «%s».\n" -#: initdb.c:2700 initdb.c:2785 initdb.c:3137 +#: initdb.c:2781 initdb.c:2863 initdb.c:3232 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" +msgid "could not access directory \"%s\": %m" +msgstr "no se pudo acceder al directorio «%s»: %m" -#: initdb.c:2724 +#: initdb.c:2804 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" -msgstr "%s: la ubicación del directorio WAL debe ser una ruta absoluta\n" +msgid "WAL directory location must be an absolute path" +msgstr "la ubicación del directorio de WAL debe ser una ruta absoluta" -#: initdb.c:2778 +#: initdb.c:2856 #, c-format msgid "" "If you want to store the WAL there, either remove or empty the directory\n" @@ -859,27 +872,27 @@ msgstr "" "Si quiere almacenar el WAL ahí, elimine o vacíe el directorio\n" "«%s».\n" -#: initdb.c:2793 +#: initdb.c:2870 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s: no se pudo crear el enlace simbólico «%s»: %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "no se pudo crear el enlace simbólico «%s»: %m" -#: initdb.c:2798 +#: initdb.c:2875 #, c-format -msgid "%s: symlinks are not supported on this platform" -msgstr "%s: los enlaces simbólicos no están soportados en esta plataforma" +msgid "symlinks are not supported on this platform" +msgstr "los enlaces simbólicos no están soportados en esta plataforma" -#: initdb.c:2822 +#: initdb.c:2899 #, c-format msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" msgstr "Contiene un archivo invisible, quizás por ser un punto de montaje.\n" -#: initdb.c:2825 +#: initdb.c:2902 #, c-format msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" msgstr "Contiene un directorio lost+found, quizás por ser un punto de montaje.\n" -#: initdb.c:2828 +#: initdb.c:2905 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -888,47 +901,57 @@ msgstr "" "Usar un punto de montaje directamente como directorio de datos no es\n" "recomendado. Cree un subdirectorio bajo el punto de montaje.\n" -#: initdb.c:2848 +#: initdb.c:2931 #, c-format msgid "creating subdirectories ... " msgstr "creando subdirectorios ... " -#: initdb.c:2895 +#: initdb.c:2977 msgid "performing post-bootstrap initialization ... " msgstr "realizando inicialización post-bootstrap ... " -#: initdb.c:3047 +#: initdb.c:3134 #, c-format msgid "Running in debug mode.\n" msgstr "Ejecutando en modo de depuración.\n" -#: initdb.c:3051 +#: initdb.c:3138 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "Ejecutando en modo no-clean. Los errores no serán limpiados.\n" -#: initdb.c:3122 +#: initdb.c:3215 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: initdb.c:3142 initdb.c:3208 +#: initdb.c:3236 initdb.c:3325 msgid "syncing data to disk ... " msgstr "sincronizando los datos a disco ... " -#: initdb.c:3151 +#: initdb.c:3245 #, c-format -msgid "%s: password prompt and password file cannot be specified together\n" +msgid "password prompt and password file cannot be specified together" msgstr "" -"%s: la petición de contraseña y el archivo de contraseña no pueden\n" -"ser especificados simultáneamente\n" +"la petición de contraseña y el archivo de contraseña no pueden\n" +"ser especificados simultáneamente" + +#: initdb.c:3270 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "el argumento de --wal-segsize debe ser un número" -#: initdb.c:3175 +#: initdb.c:3275 #, c-format -msgid "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"\n" -msgstr "%s: nombre de superusuario «%s» no permitido; los nombres de rol no pueden comenzar con «pg_»\n" +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "el argumento de --wal-segsize debe ser una potencia de 2 entre 1 y 1024" -#: initdb.c:3179 +#: initdb.c:3292 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "nombre de superusuario «%s» no permitido; los nombres de rol no pueden comenzar con «pg_»" + +#: initdb.c:3296 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -939,17 +962,17 @@ msgstr "" "Este usuario también debe ser quien ejecute el proceso servidor.\n" "\n" -#: initdb.c:3195 +#: initdb.c:3312 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Las sumas de verificación en páginas de datos han sido activadas.\n" -#: initdb.c:3197 +#: initdb.c:3314 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Las sumas de verificación en páginas de datos han sido desactivadas.\n" -#: initdb.c:3214 +#: initdb.c:3331 #, c-format msgid "" "\n" @@ -961,12 +984,26 @@ msgstr "" "El directorio de datos podría corromperse si el sistema operativo sufre\n" "una caída.\n" +#: initdb.c:3336 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "activando el método de autentificación «trust» para conexiones locales" + +#: initdb.c:3337 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Puede cambiar esto editando pg_hba.conf o usando el parámetro -A,\n" +"o --auth-local y --auth-host la próxima vez que ejecute initdb.\n" + #. translator: This is a placeholder in a shell command. -#: initdb.c:3240 +#: initdb.c:3362 msgid "logfile" msgstr "archivo_de_registro" -#: initdb.c:3242 +#: initdb.c:3364 #, c-format msgid "" "\n" @@ -980,80 +1017,3 @@ msgstr "" "\n" " %s\n" "\n" - -#~ msgid "creating template1 database in %s/base/1 ... " -#~ msgstr "creando base de datos template1 en %s/base/1 ... " - -#~ msgid "initializing pg_authid ... " -#~ msgstr "inicializando pg_authid ... " - -#~ msgid "setting password ... " -#~ msgstr "estableciendo contraseña ... " - -#~ msgid "initializing dependencies ... " -#~ msgstr "inicializando dependencias ... " - -#~ msgid "creating system views ... " -#~ msgstr "creando las vistas de sistema ... " - -#~ msgid "loading system objects' descriptions ... " -#~ msgstr "cargando las descripciones de los objetos del sistema ... " - -#~ msgid "creating collations ... " -#~ msgstr "creando algoritmos de ordenamiento ... " - -#~ msgid "not supported on this platform\n" -#~ msgstr "no está soportado en esta plataforma\n" - -#~ msgid "creating conversions ... " -#~ msgstr "creando conversiones ... " - -#~ msgid "creating dictionaries ... " -#~ msgstr "creando diccionarios ... " - -#~ msgid "setting privileges on built-in objects ... " -#~ msgstr "estableciendo privilegios en objetos predefinidos ... " - -#~ msgid "creating information schema ... " -#~ msgstr "creando el esquema de información ... " - -#~ msgid "loading PL/pgSQL server-side language ... " -#~ msgstr "instalando el lenguaje PL/pgSQL ... " - -#~ msgid "vacuuming database template1 ... " -#~ msgstr "haciendo vacuum a la base de datos template1 ... " - -#~ msgid "copying template1 to template0 ... " -#~ msgstr "copiando template1 a template0 ... " - -#~ msgid "copying template1 to postgres ... " -#~ msgstr "copiando template1 a postgres ... " - -#~ msgid "Use the option \"--debug\" to see details.\n" -#~ msgstr "Use la opción «--debug» para ver detalles.\n" - -#~ msgid "No usable system locales were found.\n" -#~ msgstr "No se encontraron configuraciones regionales utilizables.\n" - -#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" -#~ msgstr "%s: nombre de configuración regional tiene caracteres no ASCII, saltando: «%s»\n" - -#~ msgid "%s: locale name too long, skipped: \"%s\"\n" -#~ msgstr "%s: nombre de configuración regional demasiado largo, saltando: «%s»\n" - -#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" -#~ msgstr "" -#~ "%s: el directorio de registro de transacciones «%s» no fue eliminado \n" -#~ "a petición del usuario\n" - -#~ msgid "%s: failed to remove contents of transaction log directory\n" -#~ msgstr "%s: no se pudo eliminar el contenido del directorio de registro de transacciones\n" - -#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" -#~ msgstr "%s: eliminando el contenido del directorio de registro de transacciones «%s»\n" - -#~ msgid "%s: failed to remove transaction log directory\n" -#~ msgstr "%s: no se pudo eliminar el directorio de registro de transacciones\n" - -#~ msgid "%s: removing transaction log directory \"%s\"\n" -#~ msgstr "%s: eliminando el directorio de registro de transacciones «%s»\n" diff --git a/src/bin/initdb/po/fr.po b/src/bin/initdb/po/fr.po index ce1eb5a9b6b..77d08508e86 100644 --- a/src/bin/initdb/po/fr.po +++ b/src/bin/initdb/po/fr.po @@ -7,52 +7,73 @@ # Stéphane Schildknecht , 2009. msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-02 04:46+0000\n" -"PO-Revision-Date: 2017-07-02 18:12+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:17+0000\n" +"PO-Revision-Date: 2019-05-17 16:51+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "n'a pas pu identifier le répertoire courant : %s" +msgid "fatal: " +msgstr "fatal : " -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "binaire « %s » invalide" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "n'a pas pu lire le binaire « %s »" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "n'a pas pu trouver un « %s » à exécuter" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" + +#: ../../common/exec.c:288 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "n'a pas pu modifier le répertoire par « %s » : %s" +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:541 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "n'a pas pu lire le lien symbolique « %s »" +msgid "pclose failed: %m" +msgstr "échec de pclose : %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: initdb.c:339 #, c-format -msgid "pclose failed: %s" -msgstr "échec de pclose : %s" +msgid "out of memory" +msgstr "mémoire épuisée" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -65,98 +86,90 @@ msgstr "mémoire épuisée\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 #, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "n'a pas pu tester le fichier « %s » : %m" -#: ../../common/file_utils.c:162 +#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %m" -#: ../../common/file_utils.c:198 +#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "n'a pas pu lire le répertoire « %s » : %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:377 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m" -#: ../../common/pgfnames.c:45 +#: ../../common/pgfnames.c:74 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "n'a pas pu ouvrir le répertoire « %s » : %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "n'a pas pu fermer le répertoire « %s » : %m" -#: ../../common/pgfnames.c:72 +#: ../../common/restricted_token.c:69 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "n'a pas pu lire le répertoire « %s » : %s\n" +msgid "cannot create restricted tokens on this platform" +msgstr "ne peut pas créer les jetons restreints sur cette plateforme" -#: ../../common/pgfnames.c:84 +#: ../../common/restricted_token.c:78 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" +msgid "could not open process token: error code %lu" +msgstr "n'a pas pu ouvrir le jeton du processus : code d'erreur %lu" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s : ATTENTION : ne peut pas crér les jetons restreints sur cette plateforme\n" - -#: ../../common/restricted_token.c:77 -#, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s : n'a pas pu ouvrir le jeton du processus : code d'erreur %lu\n" - -#: ../../common/restricted_token.c:90 -#, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "n'a pas pu allouer les SID : code d'erreur %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s : n'a pas pu créer le jeton restreint : code d'erreur %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "n'a pas pu créer le jeton restreint : code d'erreur %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s : n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "" +"n'a pas pu démarrer le processus pour la commande « %s » : code d'erreur %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s : n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "n'a pas pu ré-exécuter le jeton restreint : code d'erreur %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s : n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "" +"n'a pas pu récupérer le code de statut du sous-processus : code d'erreur %lu" -#: ../../common/rmtree.c:77 +#: ../../common/rmtree.c:79 #, c-format -msgid "could not stat file or directory \"%s\": %s\n" +msgid "could not stat file or directory \"%s\": %m" msgstr "" "n'a pas pu récupérer les informations sur le fichier ou répertoire\n" -"« %s » : %s\n" +"« %s » : %m" -#: ../../common/rmtree.c:104 ../../common/rmtree.c:121 +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %s\n" +msgid "could not remove file or directory \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier ou répertoire « %s » : %m" #: ../../common/username.c:43 #, c-format @@ -187,22 +200,17 @@ msgstr "commande introuvable" msgid "child process exited with exit code %d" msgstr "le processus fils a quitté avec le code de sortie %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "le processus fils a été terminé par l'exception 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "le processus fils a été terminé par le signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "le processus fils a été terminé par le signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "le processus fils a quitté avec un statut %d non reconnu" @@ -217,103 +225,106 @@ msgstr "n'a pas pu configurer la jonction pour « %s » : %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "n'a pas pu obtenir la jonction pour « %s » : %s\n" -#: initdb.c:331 +#: initdb.c:495 initdb.c:1534 #, c-format -msgid "%s: out of memory\n" -msgstr "%s : mémoire épuisée\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" -#: initdb.c:441 initdb.c:1442 +#: initdb.c:550 initdb.c:858 initdb.c:884 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" +msgid "could not open file \"%s\" for writing: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » en écriture : %m" -#: initdb.c:497 initdb.c:813 initdb.c:841 +#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 #, c-format -msgid "%s: could not open file \"%s\" for writing: %s\n" -msgstr "%s : n'a pas pu ouvrir le fichier « %s » en écriture : %s\n" +msgid "could not write file \"%s\": %m" +msgstr "impossible d'écrire le fichier « %s » : %m" -#: initdb.c:505 initdb.c:513 initdb.c:820 initdb.c:847 +#: initdb.c:582 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s : n'a pas pu écrire le fichier « %s » : %s\n" +msgid "could not execute command \"%s\": %m" +msgstr "n'a pas pu exécuter la commande « %s » : %m" -#: initdb.c:532 +#: initdb.c:600 #, c-format -msgid "%s: could not execute command \"%s\": %s\n" -msgstr "%s : n'a pas pu exécuter la commande « %s » : %s\n" +msgid "removing data directory \"%s\"" +msgstr "suppression du répertoire des données « %s »" -#: initdb.c:548 +#: initdb.c:602 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s : suppression du répertoire des données « %s »\n" +msgid "failed to remove data directory" +msgstr "échec de la suppression du répertoire des données" -#: initdb.c:551 +#: initdb.c:606 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s : échec de la suppression du répertoire des données\n" +msgid "removing contents of data directory \"%s\"" +msgstr "suppression du contenu du répertoire des données « %s »" -#: initdb.c:557 +#: initdb.c:609 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s : suppression du contenu du répertoire des données « %s »\n" +msgid "failed to remove contents of data directory" +msgstr "échec de la suppression du contenu du répertoire des données" -#: initdb.c:560 +#: initdb.c:614 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s : échec de la suppression du contenu du répertoire des données\n" +msgid "removing WAL directory \"%s\"" +msgstr "suppression du répertoire des journaux de transactions « %s »" -#: initdb.c:566 +#: initdb.c:616 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s : suppression du répertoire des journaux de transactions « %s »\n" +msgid "failed to remove WAL directory" +msgstr "échec de la suppression du répertoire des journaux de transactions" -#: initdb.c:569 +#: initdb.c:620 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s : échec de la suppression du répertoire des journaux de transactions\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "" +"suppression du contenu du répertoire des journaux de transactions « %s »" -#: initdb.c:575 +#: initdb.c:622 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s : suppression du contenu du répertoire des journaux de transactions « %s »\n" +msgid "failed to remove contents of WAL directory" +msgstr "" +"échec de la suppression du contenu du répertoire des journaux de transactions" -#: initdb.c:578 +#: initdb.c:629 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transactions\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "" +"répertoire des données « %s » non supprimé à la demande de l'utilisateur" -#: initdb.c:587 +#: initdb.c:633 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s : répertoire des données « %s » non supprimé à la demande de l'utilisateur\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "" +"répertoire des journaux de transactions « %s » non supprimé à la demande de " +"l'utilisateur" -#: initdb.c:592 +#: initdb.c:651 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s : répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur\n" +msgid "cannot be run as root" +msgstr "ne peut pas être exécuté en tant que root" -#: initdb.c:613 +#: initdb.c:653 #, c-format msgid "" -"%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" "own the server process.\n" msgstr "" -"%s : ne peut pas être exécuté en tant qu'utilisateur root\n" "Connectez-vous (par exemple en utilisant « su ») sous l'utilisateur (non\n" " privilégié) qui sera propriétaire du processus serveur.\n" -#: initdb.c:649 +#: initdb.c:686 #, c-format -msgid "%s: \"%s\" is not a valid server encoding name\n" -msgstr "%s : « %s » n'est pas un nom d'encodage serveur valide\n" +msgid "\"%s\" is not a valid server encoding name" +msgstr "« %s » n'est pas un nom d'encodage serveur valide" -#: initdb.c:769 +#: initdb.c:817 #, c-format -msgid "%s: file \"%s\" does not exist\n" -msgstr "%s : le fichier « %s » n'existe pas\n" +msgid "file \"%s\" does not exist" +msgstr "le rôle « %s » n'existe pas" -#: initdb.c:771 initdb.c:780 initdb.c:790 +#: initdb.c:819 initdb.c:826 initdb.c:835 #, c-format msgid "" "This might mean you have a corrupted installation or identified\n" @@ -322,118 +333,128 @@ msgstr "" "Cela peut signifier que votre installation est corrompue ou que vous avez\n" "identifié le mauvais répertoire avec l'option -L.\n" -#: initdb.c:777 +#: initdb.c:824 #, c-format -msgid "%s: could not access file \"%s\": %s\n" -msgstr "%s : n'a pas pu accéder au fichier « %s » : %s\n" +msgid "could not access file \"%s\": %m" +msgstr "n'a pas pu accéder au fichier « %s » : %m" -#: initdb.c:788 +#: initdb.c:833 #, c-format -msgid "%s: file \"%s\" is not a regular file\n" -msgstr "%s : « %s » n'est pas un fichier\n" +msgid "file \"%s\" is not a regular file" +msgstr "le fichier « %s » n'est pas un fichier standard" + +#: initdb.c:978 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "sélection de l'implémentation de la mémoire partagée dynamique..." -#: initdb.c:933 +#: initdb.c:987 #, c-format msgid "selecting default max_connections ... " -msgstr "sélection de la valeur par défaut de max_connections... " +msgstr "sélection de la valeur par défaut pour max_connections... " -#: initdb.c:963 +#: initdb.c:1018 #, c-format msgid "selecting default shared_buffers ... " msgstr "sélection de la valeur par défaut pour shared_buffers... " -#: initdb.c:996 +#: initdb.c:1052 #, c-format -msgid "selecting dynamic shared memory implementation ... " -msgstr "sélection de l'implémentation de la mémoire partagée dynamique..." +msgid "selecting default timezone ... " +msgstr "sélection du fuseau horaire par défaut... " -#: initdb.c:1014 +#: initdb.c:1086 msgid "creating configuration files ... " msgstr "création des fichiers de configuration... " -#: initdb.c:1146 initdb.c:1166 initdb.c:1253 initdb.c:1269 +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 #, c-format -msgid "%s: could not change permissions of \"%s\": %s\n" -msgstr "%s : n'a pas pu modifier les droits de « %s » : %s\n" +msgid "could not change permissions of \"%s\": %m" +msgstr "n'a pas pu modifier les droits de « %s » : %m" -#: initdb.c:1293 +#: initdb.c:1381 #, c-format msgid "running bootstrap script ... " msgstr "lancement du script bootstrap..." -#: initdb.c:1309 +#: initdb.c:1393 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "le fichier en entrée « %s » n'appartient pas à PostgreSQL %s" + +#: initdb.c:1396 #, c-format msgid "" -"%s: input file \"%s\" does not belong to PostgreSQL %s\n" "Check your installation or specify the correct path using the option -L.\n" msgstr "" -"%s : le fichier « %s » n'appartient pas à PostgreSQL %s\n" "Vérifiez votre installation ou indiquez le bon chemin avec l'option -L.\n" -#: initdb.c:1419 +#: initdb.c:1511 msgid "Enter new superuser password: " msgstr "Saisissez le nouveau mot de passe du super-utilisateur : " -#: initdb.c:1420 +#: initdb.c:1512 msgid "Enter it again: " msgstr "Saisissez-le à nouveau : " -#: initdb.c:1423 +#: initdb.c:1515 #, c-format msgid "Passwords didn't match.\n" msgstr "Les mots de passe ne sont pas identiques.\n" -#: initdb.c:1449 +#: initdb.c:1541 #, c-format -msgid "%s: could not read password from file \"%s\": %s\n" -msgstr "%s : n'a pas pu lire le mot de passe à partir du fichier « %s » : %s\n" +msgid "could not read password from file \"%s\": %m" +msgstr "n'a pas pu lire le mot de passe à partir du fichier « %s » : %m" -#: initdb.c:1452 +#: initdb.c:1544 #, c-format -msgid "%s: password file \"%s\" is empty\n" -msgstr "%s : le fichier de mots de passe « %s » est vide\n" +msgid "password file \"%s\" is empty" +msgstr "le fichier de mots de passe « %s » est vide" -#: initdb.c:2027 +#: initdb.c:2107 #, c-format msgid "caught signal\n" msgstr "signal reçu\n" -#: initdb.c:2033 +#: initdb.c:2113 #, c-format msgid "could not write to child process: %s\n" msgstr "n'a pas pu écrire au processus fils : %s\n" -#: initdb.c:2041 +#: initdb.c:2121 #, c-format msgid "ok\n" msgstr "ok\n" -#: initdb.c:2131 +#: initdb.c:2211 #, c-format -msgid "%s: setlocale() failed\n" -msgstr "%s : échec de setlocale\n" +msgid "setlocale() failed" +msgstr "échec de setlocale()" -#: initdb.c:2149 +#: initdb.c:2232 #, c-format -msgid "%s: failed to restore old locale \"%s\"\n" -msgstr "%s : n'a pas pu restaurer l'ancienne locale « %s »\n" +msgid "failed to restore old locale \"%s\"" +msgstr "a échoué pour restaurer l'ancienne locale « %s »" -#: initdb.c:2159 +#: initdb.c:2241 #, c-format -msgid "%s: invalid locale name \"%s\"\n" -msgstr "%s : nom de locale invalide (« %s »)\n" +msgid "invalid locale name \"%s\"" +msgstr "nom de locale « %s » invalide" -#: initdb.c:2171 +#: initdb.c:2252 #, c-format -msgid "%s: invalid locale settings; check LANG and LC_* environment variables\n" -msgstr "%s : configuration invalide de la locale ; vérifiez les variables d'environnement LANG et LC_*\n" +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "" +"configuration invalide de la locale ; vérifiez les variables d'environnement " +"LANG et LC_*" -#: initdb.c:2199 +#: initdb.c:2279 #, c-format -msgid "%s: encoding mismatch\n" -msgstr "%s : différence d'encodage\n" +msgid "encoding mismatch" +msgstr "différence d'encodage" -#: initdb.c:2201 +#: initdb.c:2281 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -448,7 +469,7 @@ msgstr "" "Ré-exécutez %s sans préciser d'encodage, ou en choisissant une combinaison\n" "compatible.\n" -#: initdb.c:2273 +#: initdb.c:2353 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -457,17 +478,17 @@ msgstr "" "%s initialise un cluster PostgreSQL.\n" "\n" -#: initdb.c:2274 +#: initdb.c:2354 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: initdb.c:2275 +#: initdb.c:2355 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [OPTION]... [RÉP_DONNÉES]\n" -#: initdb.c:2276 +#: initdb.c:2356 #, c-format msgid "" "\n" @@ -476,52 +497,68 @@ msgstr "" "\n" "Options :\n" -#: initdb.c:2277 +#: initdb.c:2357 #, c-format -msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgid "" +" -A, --auth=METHOD default authentication method for local " +"connections\n" msgstr "" " -A, --auth=MÉTHODE méthode d'authentification par défaut pour les\n" " connexions locales\n" -#: initdb.c:2278 +#: initdb.c:2358 #, c-format -msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgid "" +" --auth-host=METHOD default authentication method for local TCP/IP " +"connections\n" msgstr "" " --auth-host=MÉTHODE méthode d'authentification par défaut pour les\n" " connexions locales TCP/IP\n" -#: initdb.c:2279 +#: initdb.c:2359 #, c-format -msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgid "" +" --auth-local=METHOD default authentication method for local-socket " +"connections\n" msgstr "" " --auth-local=MÉTHODE méthode d'authentification par défaut pour les\n" " connexions locales socket\n" -#: initdb.c:2280 +#: initdb.c:2360 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]RÉP_DONNÉES emplacement du cluster\n" -#: initdb.c:2281 +#: initdb.c:2361 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr "" " -E, --encoding=ENCODAGE initialise l'encodage par défaut des nouvelles\n" " bases de données\n" -#: initdb.c:2282 +#: initdb.c:2362 +#, c-format +msgid "" +" -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access autorise la lecture/écriture pour le groupe " +"sur\n" +" le répertoire des données\n" + +#: initdb.c:2363 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr "" " --locale=LOCALE initialise la locale par défaut pour les\n" " nouvelles bases de données\n" -#: initdb.c:2283 +#: initdb.c:2364 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" " --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" -" set default locale in the respective category for\n" +" set default locale in the respective category " +"for\n" " new databases (default taken from environment)\n" msgstr "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -531,19 +568,20 @@ msgstr "" " de données (les valeurs par défaut sont prises\n" " dans l'environnement)\n" -#: initdb.c:2287 +#: initdb.c:2368 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale équivalent à --locale=C\n" -#: initdb.c:2288 +#: initdb.c:2369 #, c-format -msgid " --pwfile=FILE read password for the new superuser from file\n" +msgid "" +" --pwfile=FILE read password for the new superuser from file\n" msgstr "" " --pwfile=NOMFICHIER lit le mot de passe du nouveau\n" " super-utilisateur à partir de ce fichier\n" -#: initdb.c:2289 +#: initdb.c:2370 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -553,24 +591,34 @@ msgstr "" " configuration par défaut de la recherche plein\n" " texte\n" -#: initdb.c:2291 +#: initdb.c:2372 #, c-format msgid " -U, --username=NAME database superuser name\n" -msgstr " -U, --username=NOM nom du super-utilisateur de la base de données\n" +msgstr "" +" -U, --username=NOM nom du super-utilisateur de la base de données\n" -#: initdb.c:2292 +#: initdb.c:2373 #, c-format -msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgid "" +" -W, --pwprompt prompt for a password for the new superuser\n" msgstr "" " -W, --pwprompt demande un mot de passe pour le nouveau\n" " super-utilisateur\n" -#: initdb.c:2293 +#: initdb.c:2374 #, c-format -msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" -msgstr " -X, --waldir=RÉP_WAL emplacement du répertoire des transactions\n" +msgid "" +" -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" -X, --waldir=RÉP_WAL emplacement du répertoire des journaux de\n" +" transactions\n" -#: initdb.c:2294 +#: initdb.c:2375 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAILLE taille des segments WAL, en mégaoctets\n" + +#: initdb.c:2376 #, c-format msgid "" "\n" @@ -579,44 +627,53 @@ msgstr "" "\n" "Options moins utilisées :\n" -#: initdb.c:2295 +#: initdb.c:2377 #, c-format msgid " -d, --debug generate lots of debugging output\n" -msgstr " -d, --debug engendre un grand nombre de traces de débogage\n" +msgstr "" +" -d, --debug engendre un grand nombre de traces de débogage\n" -#: initdb.c:2296 +#: initdb.c:2378 #, c-format msgid " -k, --data-checksums use data page checksums\n" -msgstr " -k, --data-checksums utilise les sommes de contrôles pour les pages de données\n" +msgstr "" +" -k, --data-checksums utilise les sommes de contrôle pour les pages " +"de données\n" -#: initdb.c:2297 +#: initdb.c:2379 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr "" " -L RÉPERTOIRE indique où trouver les fichiers servant à la\n" " création du cluster\n" -#: initdb.c:2298 +#: initdb.c:2380 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --noclean ne nettoie pas après des erreurs\n" -#: initdb.c:2299 +#: initdb.c:2381 #, c-format -msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" -msgstr " -N, --nosync n'attend pas que les modifications sont proprement écrites sur disque\n" +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --nosync n'attend pas que les modifications soient " +"proprement écrites sur disque\n" -#: initdb.c:2300 +#: initdb.c:2382 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show affiche la configuration interne\n" -#: initdb.c:2301 +#: initdb.c:2383 #, c-format msgid " -S, --sync-only only sync data directory\n" -msgstr " -S, --sync-only synchronise uniquement le répertoire des données\n" +msgstr "" +" -S, --sync-only synchronise uniquement le répertoire des " +"données\n" -#: initdb.c:2302 +#: initdb.c:2384 #, c-format msgid "" "\n" @@ -625,17 +682,17 @@ msgstr "" "\n" "Autres options :\n" -#: initdb.c:2303 +#: initdb.c:2385 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version puis quitte\n" -#: initdb.c:2304 +#: initdb.c:2386 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide puis quitte\n" -#: initdb.c:2305 +#: initdb.c:2387 #, c-format msgid "" "\n" @@ -646,89 +703,77 @@ msgstr "" "Si le répertoire des données n'est pas indiqué, la variable d'environnement\n" "PGDATA est utilisée.\n" -#: initdb.c:2307 +#: initdb.c:2389 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapporter les bogues à .\n" - -#: initdb.c:2315 -msgid "" -"\n" -"WARNING: enabling \"trust\" authentication for local connections\n" -"You can change this by editing pg_hba.conf or using the option -A, or\n" -"--auth-local and --auth-host, the next time you run initdb.\n" -msgstr "" -"\n" -"ATTENTION : active l'authentification « trust » pour les connexions\n" -"locales.\n" -"Vous pouvez changer cette configuration en éditant le fichier pg_hba.conf\n" -"ou en utilisant l'option -A, ou --auth-local et --auth-host au prochain\n" -"lancement d'initdb.\n" +"Rapporter les bogues à .\n" -#: initdb.c:2337 +#: initdb.c:2417 #, c-format -msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" -msgstr "%s : méthode d'authentification « %s » invalide pour « %s »\n" +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "méthode d'authentification « %s » invalide pour « %s » connexions" -#: initdb.c:2353 +#: initdb.c:2433 #, c-format -msgid "%s: must specify a password for the superuser to enable %s authentication\n" +msgid "must specify a password for the superuser to enable %s authentication" msgstr "" -"%s : vous devez indiquer un mot de passe pour le super-utilisateur pour\n" -"activer l'authentification %s\n" +"doit indiquer un mot de passe pour le super-utilisateur pour\n" +"activer l'authentification %s" -#: initdb.c:2381 +#: initdb.c:2460 +#, c-format +msgid "no data directory specified" +msgstr "aucun répertoire de données indiqué" + +#: initdb.c:2462 #, c-format msgid "" -"%s: no data directory specified\n" "You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" "environment variable PGDATA.\n" msgstr "" -"%s : aucun répertoire de données indiqué\n" "Vous devez identifier le répertoire où résideront les données pour ce\n" -"système de bases de données. Faites-le soit avec l'option -D soit en\n" -"initialisant la variable d'environnement PGDATA.\n" +"système de bases de données. Faites-le soit avec l'option -D soit avec\n" +"la variable d'environnement PGDATA.\n" -#: initdb.c:2419 +#: initdb.c:2497 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Le programme « postgres » est nécessaire à %s mais n'a pas été trouvé dans\n" "le même répertoire que « %s ».\n" -"Vérifiez votre installation.\n" +"Vérifiez votre installation." -#: initdb.c:2426 +#: initdb.c:2502 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Le programme « postgres » a été trouvé par « %s » mais n'est pas de la même\n" "version que « %s ».\n" -"Vérifiez votre installation.\n" +"Vérifiez votre installation." -#: initdb.c:2445 +#: initdb.c:2521 #, c-format -msgid "%s: input file location must be an absolute path\n" +msgid "input file location must be an absolute path" msgstr "" -"%s : l'emplacement du fichier d'entrées doit être indiqué avec un chemin\n" -"absolu\n" +"l'emplacement du fichier d'entrée doit être indiqué avec un chemin absolu" -#: initdb.c:2464 +#: initdb.c:2538 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "L'instance sera initialisée avec la locale « %s ».\n" -#: initdb.c:2467 +#: initdb.c:2541 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -747,36 +792,37 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2491 +#: initdb.c:2565 #, c-format -msgid "%s: could not find suitable encoding for locale \"%s\"\n" -msgstr "%s : n'a pas pu trouver un encodage adéquat pour la locale « %s »\n" +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "n'a pas pu trouver un encodage adéquat pour la locale « %s »" -#: initdb.c:2493 +#: initdb.c:2567 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "Relancez %s avec l'option -E.\n" -#: initdb.c:2494 initdb.c:3123 initdb.c:3144 +#: initdb.c:2568 initdb.c:3196 initdb.c:3217 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayer « %s --help » pour plus d'informations.\n" -#: initdb.c:2506 +#: initdb.c:2581 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" "The default database encoding will be set to \"%s\" instead.\n" msgstr "" -"L'encodage « %s » déduit de la locale n'est pas autorisé en tant qu'encodage serveur.\n" +"L'encodage « %s » a été déduit de la locale mais n'est pas autorisé en tant " +"qu'encodage serveur.\n" "L'encodage par défaut des bases de données sera configuré à « %s ».\n" -#: initdb.c:2514 +#: initdb.c:2586 #, c-format -msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" -msgstr "%s : la locale « %s » nécessite l'encodage « %s » non supporté\n" +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "la locale « %s » nécessite l'encodage « %s » non supporté" -#: initdb.c:2517 +#: initdb.c:2589 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -785,65 +831,71 @@ msgstr "" "L'encodage « %s » n'est pas autorisé en tant qu'encodage serveur.\n" "Ré-exécuter %s avec une locale différente.\n" -#: initdb.c:2526 +#: initdb.c:2598 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "" "L'encodage par défaut des bases de données a été configuré en conséquence\n" "avec « %s ».\n" -#: initdb.c:2597 +#: initdb.c:2666 #, c-format -msgid "%s: could not find suitable text search configuration for locale \"%s\"\n" +msgid "" +"%s: could not find suitable text search configuration for locale \"%s\"\n" msgstr "" "%s : n'a pas pu trouver la configuration de la recherche plein texte en\n" " adéquation avec la locale « %s »\n" -#: initdb.c:2608 +#: initdb.c:2677 #, c-format -msgid "%s: warning: suitable text search configuration for locale \"%s\" is unknown\n" +msgid "" +"%s: warning: suitable text search configuration for locale \"%s\" is " +"unknown\n" msgstr "" "%s : attention : pas de configuration de la recherche plein texte connue\n" "pour la locale « %s »\n" -#: initdb.c:2613 +#: initdb.c:2682 #, c-format -msgid "%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n" +msgid "" +"%s: warning: specified text search configuration \"%s\" might not match " +"locale \"%s\"\n" msgstr "" "%s : attention : la configuration indiquée pour la recherche plein texte,\n" "« %s », pourrait ne pas correspondre à la locale « %s »\n" -#: initdb.c:2618 +#: initdb.c:2687 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" -msgstr "La configuration de la recherche plein texte a été initialisée à « %s ».\n" +msgstr "" +"La configuration de la recherche plein texte a été initialisée à « %s ».\n" -#: initdb.c:2662 initdb.c:2748 +#: initdb.c:2731 initdb.c:2813 #, c-format msgid "creating directory %s ... " msgstr "création du répertoire %s... " -#: initdb.c:2668 initdb.c:2754 initdb.c:2822 initdb.c:2878 +#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s : n'a pas pu créer le répertoire « %s » : %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "n'a pas pu créer le répertoire « %s » : %m" -#: initdb.c:2680 initdb.c:2766 +#: initdb.c:2748 initdb.c:2831 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "correction des droits sur le répertoire existant %s... " -#: initdb.c:2686 initdb.c:2772 +#: initdb.c:2754 initdb.c:2837 #, c-format -msgid "%s: could not change permissions of directory \"%s\": %s\n" -msgstr "%s : n'a pas pu modifier les droits du répertoire « %s » : %s\n" +msgid "could not change permissions of directory \"%s\": %m" +msgstr "n'a pas pu modifier les droits du répertoire « %s » : %m" -#: initdb.c:2701 initdb.c:2787 +#: initdb.c:2768 initdb.c:2851 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s : le répertoire « %s » existe mais n'est pas vide\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "le répertoire « %s » existe mais n'est pas vide" -#: initdb.c:2707 +#: initdb.c:2773 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -854,19 +906,19 @@ msgstr "" "videz le répertoire « %s ».\n" "Vous pouvez aussi exécuter %s avec un argument autre que « %s ».\n" -#: initdb.c:2715 initdb.c:2800 initdb.c:3157 +#: initdb.c:2781 initdb.c:2863 initdb.c:3232 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" +msgid "could not access directory \"%s\": %m" +msgstr "n'a pas pu accéder au répertoire « %s » : %m" -#: initdb.c:2739 +#: initdb.c:2804 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" +msgid "WAL directory location must be an absolute path" msgstr "" -"%s : l'emplacement du répertoire des journaux de transactions doit être\n" -"indiqué avec un chemin absolu\n" +"l'emplacement du répertoire des journaux de transactions doit être indiqué " +"avec un chemin absolu" -#: initdb.c:2793 +#: initdb.c:2856 #, c-format msgid "" "If you want to store the WAL there, either remove or empty the directory\n" @@ -875,97 +927,122 @@ msgstr "" "Si vous voulez enregistrer ici le journal des transactions, supprimez ou\n" "videz le répertoire « %s ».\n" -#: initdb.c:2808 +#: initdb.c:2870 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "n'a pas pu créer le lien symbolique « %s » : %m" -#: initdb.c:2813 +#: initdb.c:2875 #, c-format -msgid "%s: symlinks are not supported on this platform" -msgstr "%s : les liens symboliques ne sont pas supportés sur cette plateforme" +msgid "symlinks are not supported on this platform" +msgstr "les liens symboliques ne sont pas supportés sur cette plateforme" -#: initdb.c:2837 +#: initdb.c:2899 #, c-format -msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" -msgstr "Il contient un fichier invisible, peut-être parce qu'il s'agit d'un point de montage.\n" +msgid "" +"It contains a dot-prefixed/invisible file, perhaps due to it being a mount " +"point.\n" +msgstr "" +"Il contient un fichier invisible, peut-être parce qu'il s'agit d'un point de " +"montage.\n" -#: initdb.c:2840 +#: initdb.c:2902 #, c-format -msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" -msgstr "Il contient un répertoire lost+found, peut-être parce qu'il s'agit d'un point de montage.\n" +msgid "" +"It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "" +"Il contient un répertoire lost+found, peut-être parce qu'il s'agit d'un " +"point de montage.\n" -#: initdb.c:2843 +#: initdb.c:2905 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" "Create a subdirectory under the mount point.\n" msgstr "" -"Utiliser un point de montage comme répertoire de données n'est pas recommandé.\n" +"Utiliser un point de montage comme répertoire des données n'est pas " +"recommandé.\n" "Créez un sous-répertoire sous le point de montage.\n" -#: initdb.c:2863 +#: initdb.c:2931 #, c-format msgid "creating subdirectories ... " msgstr "création des sous-répertoires... " -#: initdb.c:2910 +#: initdb.c:2977 msgid "performing post-bootstrap initialization ... " -msgstr "exécution de l'initialisation après bootstrap..." +msgstr "exécution de l'initialisation après bootstrap... " -#: initdb.c:3067 +#: initdb.c:3134 #, c-format msgid "Running in debug mode.\n" msgstr "Lancé en mode débogage.\n" -#: initdb.c:3071 +#: initdb.c:3138 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" -msgstr "Lancé en mode « sans nettoyage ». Les erreurs ne seront pas nettoyées.\n" +msgstr "" +"Lancé en mode « sans nettoyage ». Les erreurs ne seront pas nettoyées.\n" -#: initdb.c:3142 +#: initdb.c:3215 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" -#: initdb.c:3162 initdb.c:3228 +#: initdb.c:3236 initdb.c:3325 msgid "syncing data to disk ... " -msgstr "synchronisation des données sur disque" +msgstr "synchronisation des données sur disque... " -#: initdb.c:3171 +#: initdb.c:3245 #, c-format -msgid "%s: password prompt and password file cannot be specified together\n" +msgid "password prompt and password file cannot be specified together" msgstr "" -"%s : les options d'invite du mot de passe et le fichier de mots de passe ne\n" -" peuvent pas être indiquées simultanément\n" +"les options d'invite du mot de passe et de fichier de mots de passe ne\n" +"peuvent pas être indiquées simultanément" -#: initdb.c:3195 +#: initdb.c:3270 #, c-format -msgid "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"\n" -msgstr "%s : le nom de superutilisateur « %s » est non autorisé ; les noms de rôle ne peuvent pas commencer avec « pg_ »\n" +msgid "argument of --wal-segsize must be a number" +msgstr "l'argument de --wal-segsize doit être un nombre" -#: initdb.c:3199 +#: initdb.c:3275 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "" +"l'argument de --wal-segsize doit être une puissance de 2 comprise entre 1 et " +"1024" + +#: initdb.c:3292 +#, c-format +msgid "" +"superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "" +"le nom de superutilisateur « %s » n'est pas autorisé ; les noms de rôle ne " +"peuvent pas commencer par « pg_ »" + +#: initdb.c:3296 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" "This user must also own the server process.\n" "\n" msgstr "" -"Les fichiers de ce cluster appartiendront à l'utilisateur « %s ».\n" +"Les fichiers de ce système de bases de données appartiendront à " +"l'utilisateur « %s ».\n" "Le processus serveur doit également lui appartenir.\n" "\n" -#: initdb.c:3215 +#: initdb.c:3312 #, c-format msgid "Data page checksums are enabled.\n" -msgstr "Les sommes de contrôles des pages de données sont activées.\n" +msgstr "Les sommes de contrôle des pages de données sont activées.\n" -#: initdb.c:3217 +#: initdb.c:3314 #, c-format msgid "Data page checksums are disabled.\n" -msgstr "Les sommes de contrôles des pages de données sont désactivées.\n" +msgstr "Les sommes de contrôle des pages de données sont désactivées.\n" -#: initdb.c:3234 +#: initdb.c:3331 #, c-format msgid "" "\n" @@ -974,14 +1051,30 @@ msgid "" msgstr "" "\n" "Synchronisation sur disque ignorée.\n" -"Le répertoire des données pourrait être corrompu si le système d'exploitation s'arrêtait brutalement.\n" +"Le répertoire des données pourrait être corrompu si le système " +"d'exploitation s'arrêtait brutalement.\n" + +#: initdb.c:3336 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "activation de l'authentification « trust » pour les connexions locales" + +#: initdb.c:3337 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Vous pouvez changer cette configuration en éditant le fichier pg_hba.conf\n" +"ou en utilisant l'option -A, ou --auth-local et --auth-host au prochain\n" +"lancement d'initdb.\n" #. translator: This is a placeholder in a shell command. -#: initdb.c:3260 +#: initdb.c:3362 msgid "logfile" -msgstr "fichier de trace" +msgstr "fichier_de_trace" -#: initdb.c:3262 +#: initdb.c:3364 #, c-format msgid "" "\n" @@ -991,110 +1084,200 @@ msgid "" "\n" msgstr "" "\n" -"Succès. Vous pouvez maintenant lancer le serveur de bases de données en utilisant :\n" +"Succès. Vous pouvez maintenant lancer le serveur de bases de données en " +"utilisant :\n" "\n" " %s\n" "\n" -#~ msgid "creating template1 database in %s/base/1 ... " -#~ msgstr "création de la base de données template1 dans %s/base/1... " +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s : suppression du répertoire des journaux de transaction « %s »\n" -#~ msgid "initializing pg_authid ... " -#~ msgstr "initialisation de pg_authid... " +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "" +#~ "%s : échec de la suppression du répertoire des journaux de transaction\n" -#~ msgid "setting password ... " -#~ msgstr "initialisation du mot de passe... " +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "" +#~ "%s : suppression du contenu du répertoire des journaux de transaction « " +#~ "%s »\n" -#~ msgid "initializing dependencies ... " -#~ msgstr "initialisation des dépendances... " +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "" +#~ "%s : échec de la suppression du contenu du répertoire des journaux de " +#~ "transaction\n" -#~ msgid "creating system views ... " -#~ msgstr "création des vues système... " +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s : répertoire des journaux de transaction « %s » non supprimé à la " +#~ "demande\n" +#~ "de l'utilisateur\n" -#~ msgid "loading system objects' descriptions ... " -#~ msgstr "chargement de la description des objets système... " +#~ msgid "%s: locale name too long, skipped: \"%s\"\n" +#~ msgstr "%s : nom de locale trop long, ignoré : « %s »\n" -#~ msgid "creating collations ... " -#~ msgstr "création des collationnements... " +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "" +#~ "%s : le nom de la locale contient des caractères non ASCII, ignoré : « %s " +#~ "»\n" -#~ msgid "not supported on this platform\n" -#~ msgstr "non supporté sur cette plateforme\n" +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Aucune locale système utilisable n'a été trouvée.\n" -#~ msgid "creating conversions ... " -#~ msgstr "création des conversions... " +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Utilisez l'option « --debug » pour voir le détail.\n" -#~ msgid "creating dictionaries ... " -#~ msgstr "création des dictionnaires... " +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu fermer le répertoire « %s » : %s\n" -#~ msgid "setting privileges on built-in objects ... " -#~ msgstr "initialisation des droits sur les objets internes... " +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu obtenir d'informations sur l'utilisateur courant : %s\n" -#~ msgid "creating information schema ... " -#~ msgstr "création du schéma d'informations... " +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s : n'a pas pu obtenir le nom de l'utilisateur courant : %s\n" -#~ msgid "loading PL/pgSQL server-side language ... " -#~ msgstr "chargement du langage PL/pgSQL... " +#~ msgid "%s: unrecognized authentication method \"%s\"\n" +#~ msgstr "%s : méthode d'authentification « %s » inconnue.\n" -#~ msgid "vacuuming database template1 ... " -#~ msgstr "lancement du vacuum sur la base de données template1... " +#~ msgid "%s: could not determine valid short version string\n" +#~ msgstr "%s : n'a pas pu déterminer une chaîne de version courte valide\n" -#~ msgid "copying template1 to template0 ... " -#~ msgstr "copie de template1 vers template0... " +#~ msgid "" +#~ "%s: The password file was not generated. Please report this problem.\n" +#~ msgstr "" +#~ "%s : le fichier de mots de passe n'a pas été créé.\n" +#~ "Merci de rapporter ce problème.\n" -#~ msgid "copying template1 to postgres ... " -#~ msgstr "copie de template1 vers postgres... " +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" #~ msgid "%s: could not to allocate SIDs: error code %lu\n" #~ msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "n'a pas pu accéder au répertoire « %s »" +#~ msgid "copying template1 to postgres ... " +#~ msgstr "copie de template1 vers postgres... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "copie de template1 vers template0... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "lancement du vacuum sur la base de données template1... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "chargement du langage PL/pgSQL... " + +#~ msgid "creating information schema ... " +#~ msgstr "création du schéma d'informations... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "initialisation des droits sur les objets internes... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "création des dictionnaires... " + +#~ msgid "creating conversions ... " +#~ msgstr "création des conversions... " + +#~ msgid "not supported on this platform\n" +#~ msgstr "non supporté sur cette plateforme\n" + +#~ msgid "creating collations ... " +#~ msgstr "création des collationnements... " -#~ msgid "%s: The password file was not generated. Please report this problem.\n" +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "chargement de la description des objets système... " + +#~ msgid "creating system views ... " +#~ msgstr "création des vues système... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "initialisation des dépendances... " + +#~ msgid "setting password ... " +#~ msgstr "initialisation du mot de passe... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "initialisation de pg_authid... " + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "création de la base de données template1 dans %s/base/1... " + +#~ msgid "%s: symlinks are not supported on this platform\n" #~ msgstr "" -#~ "%s : le fichier de mots de passe n'a pas été créé.\n" -#~ "Merci de rapporter ce problème.\n" +#~ "%s : les liens symboliques ne sont pas supportés sur cette plateforme\n" -#~ msgid "%s: could not determine valid short version string\n" -#~ msgstr "%s : n'a pas pu déterminer une chaîne de version courte valide\n" +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n" -#~ msgid "%s: unrecognized authentication method \"%s\"\n" -#~ msgstr "%s : méthode d'authentification « %s » inconnue.\n" +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" -#~ msgid "%s: could not get current user name: %s\n" -#~ msgstr "%s : n'a pas pu obtenir le nom de l'utilisateur courant : %s\n" +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu créer le répertoire « %s » : %s\n" -#~ msgid "%s: could not obtain information about current user: %s\n" -#~ msgstr "%s : n'a pas pu obtenir d'informations sur l'utilisateur courant : %s\n" +#~ msgid "%s: invalid locale name \"%s\"\n" +#~ msgstr "%s : nom de locale invalide (« %s »)\n" -#~ msgid "%s: could not close directory \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu fermer le répertoire « %s » : %s\n" +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s : n'a pas pu restaurer l'ancienne locale « %s »\n" -#~ msgid "Use the option \"--debug\" to see details.\n" -#~ msgstr "Utilisez l'option « --debug » pour voir le détail.\n" +#~ msgid "%s: could not access file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu accéder au fichier « %s » : %s\n" -#~ msgid "No usable system locales were found.\n" -#~ msgstr "Aucune locale système utilisable n'a été trouvée.\n" +#~ msgid "%s: file \"%s\" does not exist\n" +#~ msgstr "%s : le fichier « %s » n'existe pas\n" -#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" -#~ msgstr "%s : le nom de la locale contient des caractères non ASCII, ignoré : « %s »\n" +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu exécuter la commande « %s » : %s\n" -#~ msgid "%s: locale name too long, skipped: \"%s\"\n" -#~ msgstr "%s : nom de locale trop long, ignoré : « %s »\n" +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu écrire le fichier « %s » : %s\n" -#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgid "%s: could not open file \"%s\" for writing: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en écriture : %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s : mémoire épuisée\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "could not stat file or directory \"%s\": %s\n" #~ msgstr "" -#~ "%s : répertoire des journaux de transaction « %s » non supprimé à la demande\n" -#~ "de l'utilisateur\n" +#~ "n'a pas pu récupérer les informations sur le fichier ou répertoire\n" +#~ "« %s » : %s\n" -#~ msgid "%s: failed to remove contents of transaction log directory\n" -#~ msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transaction\n" +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "n'a pas pu lire le répertoire « %s » : %s\n" -#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" -#~ msgstr "%s : suppression du contenu du répertoire des journaux de transaction « %s »\n" +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "n'a pas pu ouvrir le répertoire « %s » : %s\n" -#~ msgid "%s: failed to remove transaction log directory\n" -#~ msgstr "%s : échec de la suppression du répertoire des journaux de transaction\n" +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n" -#~ msgid "%s: removing transaction log directory \"%s\"\n" -#~ msgstr "%s : suppression du répertoire des journaux de transaction « %s »\n" +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu modifier le répertoire par « %s » : %s" diff --git a/src/bin/initdb/po/it.po b/src/bin/initdb/po/it.po index 2646032941f..c0eee5f2be7 100644 --- a/src/bin/initdb/po/it.po +++ b/src/bin/initdb/po/it.po @@ -1,24 +1,19 @@ # -# Translation of initdb to Italian -# PostgreSQL Project +# initdb.po +# Italian message translation file for initdb # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Gabriele Bartolini -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017 +# Flavio Spada , 2010 +# Ottavio Campana , 2007. +# Fabrizio Mazzoni , 2003. # -# Traduttori precedenti: -# * Flavio Spada , 2010 -# * Fabrizio Mazzoni , 2003. -# * Ottavio Campana , 2007. -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" @@ -27,7 +22,7 @@ msgstr "" "POT-Creation-Date: 2017-05-22 07:46+0000\n" "PO-Revision-Date: 2017-05-23 01:09+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/src/bin/initdb/po/ko.po b/src/bin/initdb/po/ko.po index 7415a28ae1c..8a518b9721a 100644 --- a/src/bin/initdb/po/ko.po +++ b/src/bin/initdb/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6 initdb\n" +"Project-Id-Version: PostgreSQL 10 initdb\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 16:16+0900\n" +"POT-Creation-Date: 2017-08-02 13:57+0900\n" +"PO-Revision-Date: 2017-08-02 15:59+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -61,6 +61,37 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 중복할 수 ì—†ìŒ (ë‚´ë¶€ 오류)\n" +#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì˜ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:162 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:198 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: \"%s\" íŒŒì¼ ì—´ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì— 대한 fsync ìž‘ì—…ì„ í•  수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" + #: ../../common/pgfnames.c:45 #, c-format msgid "could not open directory \"%s\": %s\n" @@ -121,51 +152,51 @@ msgstr "íŒŒì¼ ë˜ëŠ” 디렉터리 \"%s\"ì˜ ìƒíƒœë¥¼ 확ì¸í•  수 ì—†ìŒ: %s\ msgid "could not remove file or directory \"%s\": %s\n" msgstr "\"%s\" íŒŒì¼ ë˜ëŠ” 디렉터리를 지울 수 ì—†ìŒ: %s\n" -#: ../../common/username.c:45 +#: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "%ld UID를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: ../../common/username.c:47 +#: ../../common/username.c:45 msgid "user does not exist" msgstr "ì‚¬ìš©ìž ì—†ìŒ" -#: ../../common/username.c:62 +#: ../../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ì‚¬ìš©ìž ì´ë¦„ 찾기 실패: 오류 코드 %lu" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "해당 명령어 ì—†ìŒ" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 종료 코드 %d" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "0x%X 예외로 하위 프로세스가 종료ë˜ì—ˆìŒ." -#: ../../common/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "%s 시그ë„ì´ ê°ì§€ë˜ì–´ 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, ì‹œê·¸ë„ %d" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 알수 없는 ìƒíƒœ %d" @@ -180,108 +211,82 @@ msgstr "\"%s\" 파ì¼ì˜ ì—°ê²°ì„ ì„¤ì •í•  수 ì—†ìŒ: %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì˜ ì •ì…˜ì„ êµ¬í•  수 ì—†ìŒ: %s\n" -#: initdb.c:349 +#: initdb.c:331 #, c-format msgid "%s: out of memory\n" msgstr "%s: 메모리 부족\n" -#: initdb.c:459 initdb.c:1595 +#: initdb.c:441 initdb.c:1442 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì½ê¸° 모드로 열기 실패: %s\n" -#: initdb.c:515 initdb.c:1002 initdb.c:1030 +#: initdb.c:497 initdb.c:813 initdb.c:841 #, c-format msgid "%s: could not open file \"%s\" for writing: %s\n" msgstr "%s: \"%s\" 파ì¼ì„ 쓰기 모드로 열기 실패: %s\n" -#: initdb.c:523 initdb.c:531 initdb.c:1009 initdb.c:1036 +#: initdb.c:505 initdb.c:513 initdb.c:820 initdb.c:847 #, c-format msgid "%s: could not write file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì“°ê¸° 실패: %s\n" -#: initdb.c:562 -#, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" - -#: initdb.c:586 initdb.c:2321 -#, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì˜ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %s\n" - -#: initdb.c:598 -#, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" - -#: initdb.c:631 initdb.c:690 -#, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: \"%s\" íŒŒì¼ ì—´ 수 ì—†ìŒ: %s\n" - -#: initdb.c:702 -#, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì— 대한 fsync ìž‘ì—…ì„ í•  수 ì—†ìŒ: %s\n" - -#: initdb.c:721 +#: initdb.c:532 #, c-format msgid "%s: could not execute command \"%s\": %s\n" msgstr "%s: \"%s\" ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ: %s\n" -#: initdb.c:737 +#: initdb.c:548 #, c-format msgid "%s: removing data directory \"%s\"\n" msgstr "%s: \"%s\" ë°ì´í„° 디렉터리를 지우고 있습니다.\n" -#: initdb.c:740 +#: initdb.c:551 #, c-format msgid "%s: failed to remove data directory\n" msgstr "%s: ë°ì´í„° 디렉터리를 ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" -#: initdb.c:746 +#: initdb.c:557 #, c-format msgid "%s: removing contents of data directory \"%s\"\n" msgstr "%s: \"%s\" ë°ì´í„° 디렉터리 ì•ˆì˜ ë‚´ìš©ì„ ì§€ìš°ê³  있습니다.\n" -#: initdb.c:749 +#: initdb.c:560 #, c-format msgid "%s: failed to remove contents of data directory\n" msgstr "%s: ë°ì´í„° 디렉터리 ë‚´ìš©ì„ ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" -#: initdb.c:755 +#: initdb.c:566 #, c-format -msgid "%s: removing transaction log directory \"%s\"\n" -msgstr "%s: \"%s\" 트랜잭션 로그 디렉터리를 지우고 있습니다.\n" +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: \"%s\" WAL 디렉터리를 지우고 있습니다.\n" -#: initdb.c:758 +#: initdb.c:569 #, c-format -msgid "%s: failed to remove transaction log directory\n" -msgstr "%s: 트랜잭션 로그 디렉터리를 ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: WAL 디렉터리를 ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" -#: initdb.c:764 +#: initdb.c:575 #, c-format -msgid "%s: removing contents of transaction log directory \"%s\"\n" -msgstr "%s: \"%s\" 트랜잭션 로그 디렉터리 ì•ˆì˜ ë‚´ìš©ì„ ì§€ìš°ê³  있습니다.\n" +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: \"%s\" WAL 디렉터리 ì•ˆì˜ ë‚´ìš©ì„ ì§€ìš°ê³  있습니다.\n" -#: initdb.c:767 +#: initdb.c:578 #, c-format -msgid "%s: failed to remove contents of transaction log directory\n" -msgstr "%s: 트랜잭션 로그 디렉터리 ë‚´ìš©ì„ ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: WAL 디렉터리 ë‚´ìš©ì„ ì§€ìš°ëŠ”ë° ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤\n" -#: initdb.c:776 +#: initdb.c:587 #, c-format msgid "%s: data directory \"%s\" not removed at user's request\n" msgstr "%s: \"%s\" ë°ì´í„° 디렉터리가 사용ìžì˜ 요청으로 ì‚­ì œë˜ì§€ 않았습니다.\n" -#: initdb.c:781 +#: initdb.c:592 #, c-format -msgid "%s: transaction log directory \"%s\" not removed at user's request\n" -msgstr "" -"%s: \"%s\" 트랜잭션 로그 디렉터리가 사용ìžì˜ 요청으로 ì‚­ì œë˜ì§€ 않았습니다.\n" +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: \"%s\" WAL 디렉터리가 사용ìžì˜ 요청으로 ì‚­ì œë˜ì§€ 않았습니다.\n" -#: initdb.c:802 +#: initdb.c:613 #, c-format msgid "" "%s: cannot be run as root\n" @@ -292,17 +297,17 @@ msgstr "" "ì‹œìŠ¤í…œê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ”, ì„œë²„í”„ë¡œì„¸ìŠ¤ì˜ ì†Œìœ ì£¼ê°€ ë  ì¼ë°˜ 사용ìžë¡œ\n" "ë¡œê·¸ì¸ í•´ì„œ(\"su\", \"runas\" ê°™ì€ ëª…ë ¹ ì´ìš©) 실행하십시오.\n" -#: initdb.c:838 +#: initdb.c:649 #, c-format msgid "%s: \"%s\" is not a valid server encoding name\n" msgstr "%s: \"%s\" ì¸ì½”ë”©ì€ ì„œë²„ ì¸ì½”딩 ì´ë¦„ì„ ì‚¬ìš©í•  수 없습니다.\n" -#: initdb.c:958 +#: initdb.c:769 #, c-format msgid "%s: file \"%s\" does not exist\n" msgstr "%s: \"%s\" 파ì¼ì´ ì—†ìŒ\n" -#: initdb.c:960 initdb.c:969 initdb.c:979 +#: initdb.c:771 initdb.c:780 initdb.c:790 #, c-format msgid "" "This might mean you have a corrupted installation or identified\n" @@ -311,46 +316,46 @@ msgstr "" "설치가 잘못ë˜ì—ˆê±°ë‚˜ –L 호출 옵션으로 ì‹ë³„한 디렉터리가\n" "잘못ë˜ì—ˆì„ 수 있습니다.\n" -#: initdb.c:966 +#: initdb.c:777 #, c-format msgid "%s: could not access file \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì— 액세스할 수 ì—†ìŒ: %s\n" -#: initdb.c:977 +#: initdb.c:788 #, c-format msgid "%s: file \"%s\" is not a regular file\n" msgstr "%s: \"%s\" 파ì¼ì€ ì¼ë°˜ 파ì¼ì´ 아님\n" -#: initdb.c:1122 +#: initdb.c:933 #, c-format msgid "selecting default max_connections ... " msgstr "max_connections ì´ˆê¸°ê°’ì„ ì„ íƒí•˜ëŠ” 중 ..." -#: initdb.c:1152 +#: initdb.c:963 #, c-format msgid "selecting default shared_buffers ... " msgstr "기본 shared_buffers를 ì„ íƒí•˜ëŠ” 중... " -#: initdb.c:1185 +#: initdb.c:996 #, c-format msgid "selecting dynamic shared memory implementation ... " msgstr "사용할 ë™ì  공유 메모리 관리방ì‹ì„ ì„ íƒí•˜ëŠ” 중 ... " -#: initdb.c:1203 +#: initdb.c:1014 msgid "creating configuration files ... " msgstr "환경설정 파ì¼ì„ 만드는 중 ..." -#: initdb.c:1306 initdb.c:1326 initdb.c:1410 initdb.c:1426 +#: initdb.c:1146 initdb.c:1166 initdb.c:1253 initdb.c:1269 #, c-format msgid "%s: could not change permissions of \"%s\": %s\n" msgstr "%s: \"%s\" ì ‘ê·¼ ê¶Œí•œì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" -#: initdb.c:1450 +#: initdb.c:1293 #, c-format msgid "running bootstrap script ... " msgstr "부트스트랩 스í¬ë¦½íЏ 실행 중 ... " -#: initdb.c:1466 +#: initdb.c:1309 #, c-format msgid "" "%s: input file \"%s\" does not belong to PostgreSQL %s\n" @@ -359,98 +364,73 @@ msgstr "" "%s: \"%s\" ìž…ë ¥ 파ì¼ì€ PostgreSQL %s ìš©ì´ ì•„ë‹™ë‹ˆë‹¤.\n" "설치ìƒíƒœë¥¼ 확ì¸í•´ ë³´ê³ , -L 옵션으로 바른 경로를 지정하십시오.\n" -#: initdb.c:1570 +#: initdb.c:1419 msgid "Enter new superuser password: " msgstr "새 superuser 암호를 입력하십시오:" -#: initdb.c:1571 +#: initdb.c:1420 msgid "Enter it again: " msgstr "암호 확ì¸:" -#: initdb.c:1574 +#: initdb.c:1423 #, c-format msgid "Passwords didn't match.\n" msgstr "암호가 서로 틀립니다.\n" -#: initdb.c:1602 +#: initdb.c:1449 #, c-format msgid "%s: could not read password from file \"%s\": %s\n" msgstr "%s: file \"%s\" 파ì¼ì—서 암호를 ì½ì„ 수 없습니다: %s\n" -#: initdb.c:1605 +#: initdb.c:1452 #, c-format msgid "%s: password file \"%s\" is empty\n" msgstr "%s: \"%s\" 패스워드 파ì¼ì´ 비어있ìŒ\n" -#: initdb.c:1853 -#, c-format -msgid "%s: locale name too long, skipped: \"%s\"\n" -msgstr "%s: ë¡œì¼€ì¼ ì´ë¦„ì´ ë„ˆë¬´ 길어 무시함: \"%s\"\n" - -#: initdb.c:1878 -#, c-format -msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" -msgstr "%s: ë¡œì¼€ì¼ ì´ë¦„ì´ ASCII 문ìžë¡œ ë˜ì–´ìžˆì§€ 않아 무시함: \"%s\"\n" - -#: initdb.c:1951 -#, c-format -msgid "No usable system locales were found.\n" -msgstr "사용 가능한 시스템 로케ì¼ì´ ì—†ìŒ.\n" - -#: initdb.c:1952 -#, c-format -msgid "Use the option \"--debug\" to see details.\n" -msgstr "보다 ìžì„¸í•œ ë‚´ìš©ì„ ë³´ë ¤ë©´ \"--debug\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ì„¸ìš”.\n" - -#: initdb.c:2304 -msgid "syncing data to disk ... " -msgstr "ìžë£Œë¥¼ 디스í¬ì— ë™ê¸°í™” 하는 중 ... " - -#: initdb.c:2398 +#: initdb.c:2027 #, c-format msgid "caught signal\n" msgstr "ì‹œìŠ¤í…œì˜ ê°„ì„­ 신호(signal) 받았ìŒ\n" -#: initdb.c:2404 +#: initdb.c:2033 #, c-format msgid "could not write to child process: %s\n" msgstr "하위 í”„ë¡œì„¸ìŠ¤ì— ì“¸ 수 ì—†ìŒ: %s\n" -#: initdb.c:2412 +#: initdb.c:2041 #, c-format msgid "ok\n" msgstr "완료\n" # # search5 ë # # advance 부분 -#: initdb.c:2502 +#: initdb.c:2131 #, c-format msgid "%s: setlocale() failed\n" msgstr "%s: setlocale() 실패\n" -#: initdb.c:2520 +#: initdb.c:2149 #, c-format msgid "%s: failed to restore old locale \"%s\"\n" msgstr "%s: \"%s\" 옛 로케ì¼ë¡œ ë³µì›í•˜ì§€ 못했ìŒ\n" -#: initdb.c:2530 +#: initdb.c:2159 #, c-format msgid "%s: invalid locale name \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ë¡œìº˜ ì´ë¦„ \"%s\"\n" -#: initdb.c:2542 +#: initdb.c:2171 #, c-format msgid "" "%s: invalid locale settings; check LANG and LC_* environment variables\n" -msgstr "" -"%s: ìž˜ëª»ëœ ë¡œì¼€ì¼ ì„¤ì •; LANG ë˜ëŠ” LC_* OS 환경 변수를 확ì¸í•˜ì„¸ìš”\n" +msgstr "%s: ìž˜ëª»ëœ ë¡œì¼€ì¼ ì„¤ì •; LANG ë˜ëŠ” LC_* OS 환경 변수를 확ì¸í•˜ì„¸ìš”\n" -#: initdb.c:2570 +#: initdb.c:2199 #, c-format msgid "%s: encoding mismatch\n" msgstr "%s: ì¸ì½”딩 불ì¼ì¹˜\n" -#: initdb.c:2572 +#: initdb.c:2201 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -465,7 +445,7 @@ msgstr "" "%sì„(를) 다시 실행하고 ì¸ì½”ë”©ì„ ëª…ì‹œì ìœ¼ë¡œ 지정하지 않거나\n" "ì¼ì¹˜í•˜ëŠ” ì¡°í•©ì„ ì„ íƒí•˜ì‹­ì‹œì˜¤.\n" -#: initdb.c:2644 +#: initdb.c:2273 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -474,17 +454,17 @@ msgstr "" "%s PostgreSQL ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 초기화 하는 프로그램.\n" "\n" -#: initdb.c:2645 +#: initdb.c:2274 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: initdb.c:2646 +#: initdb.c:2275 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [옵션]... [DATADIR]\n" -#: initdb.c:2647 +#: initdb.c:2276 #, c-format msgid "" "\n" @@ -493,43 +473,43 @@ msgstr "" "\n" "옵션들:\n" -#: initdb.c:2648 +#: initdb.c:2277 #, c-format msgid "" " -A, --auth=METHOD default authentication method for local " "connections\n" msgstr " -A, --auth=METHOD 로컬 ì—°ê²°ì˜ ê¸°ë³¸ ì¸ì¦ 방법\n" -#: initdb.c:2649 +#: initdb.c:2278 #, c-format msgid "" " --auth-host=METHOD default authentication method for local TCP/IP " "connections\n" msgstr " --auth-host=METHOD local TCP/IP ì—°ê²°ì— ëŒ€í•œ 기본 ì¸ì¦ 방법\n" -#: initdb.c:2650 +#: initdb.c:2279 #, c-format msgid "" " --auth-local=METHOD default authentication method for local-socket " "connections\n" msgstr " --auth-local=METHOD local-socket ì—°ê²°ì— ëŒ€í•œ 기본 ì¸ì¦ 방법\n" -#: initdb.c:2651 +#: initdb.c:2280 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]DATADIR 새 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 만들 디렉터리\n" -#: initdb.c:2652 +#: initdb.c:2281 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=ENCODING 새 ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ ì¸ì½”딩\n" -#: initdb.c:2653 +#: initdb.c:2282 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=LOCALE 새 ë°ì´í„°ë² ì´ìŠ¤ì˜ ê¸°ë³¸ 로캘 설정\n" -#: initdb.c:2654 +#: initdb.c:2283 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -543,18 +523,18 @@ msgstr "" " 새 ë°ì´í„°ë² ì´ìŠ¤ì˜ ê° ë²”ì£¼ì— ê¸°ë³¸ 로캘 설정\n" " (환경ì—서 가져온 기본 ê°’)\n" -#: initdb.c:2658 +#: initdb.c:2287 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale -locale=C와 ê°™ìŒ\n" -#: initdb.c:2659 +#: initdb.c:2288 #, c-format msgid "" " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=FILE 파ì¼ì—서 새 superuserì˜ ì•”í˜¸ ì½ê¸°\n" -#: initdb.c:2660 +#: initdb.c:2289 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -563,24 +543,25 @@ msgstr "" " -T, --text-search-config=CFG\n" " 기본 í…스트 검색 구성\n" -#: initdb.c:2662 +#: initdb.c:2291 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=NAME ë°ì´í„°ë² ì´ìФ superuser ì´ë¦„\n" -#: initdb.c:2663 +#: initdb.c:2292 #, c-format msgid "" " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt 새 superuser 암호를 ìž…ë ¥ ë°›ìŒ\n" -#: initdb.c:2664 +#: initdb.c:2293 #, c-format msgid "" -" -X, --xlogdir=XLOGDIR location for the transaction log directory\n" -msgstr " -X, --xlogdir=XLOGDIR 트랜잭션 로그 디렉터리 위치\n" +" -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" -X, --waldir=WALDIR 트랜잭션 로그 디렉터리 위치\n" -#: initdb.c:2665 +#: initdb.c:2294 #, c-format msgid "" "\n" @@ -589,45 +570,45 @@ msgstr "" "\n" "ëœ ì¼ë°˜ì ìœ¼ë¡œ 사용ë˜ëŠ” 옵션들:\n" -#: initdb.c:2666 +#: initdb.c:2295 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug ë””ë²„ê¹…ì— í•„ìš”í•œ ì •ë³´ë“¤ë„ í•¨ê»˜ 출력함\n" -#: initdb.c:2667 +#: initdb.c:2296 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums ìžë£Œ 페ì´ì§€ ì²´í¬ì„¬ 사용\n" -#: initdb.c:2668 +#: initdb.c:2297 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L DIRECTORY 입력파ì¼ë“¤ì´ 있는 디렉터리\n" -#: initdb.c:2669 +#: initdb.c:2298 #, c-format -msgid " -n, --noclean do not clean up after errors\n" -msgstr " -n, --noclean 오류가 ë°œìƒë˜ì—ˆì„ 경우 그대로 ë‘ \n" +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean 오류가 ë°œìƒë˜ì—ˆì„ 경우 그대로 ë‘ \n" -#: initdb.c:2670 +#: initdb.c:2299 #, c-format msgid "" -" -N, --nosync do not wait for changes to be written safely to " +" -N, --no-sync do not wait for changes to be written safely to " "disk\n" msgstr "" -" -N, --nosync 작업 완료 ë’¤ ë””ìŠ¤í¬ ë™ê¸°í™” ìž‘ì—…ì„ í•˜ì§€ 않ìŒ\n" +" -N, --no-sync 작업 완료 ë’¤ ë””ìŠ¤í¬ ë™ê¸°í™” ìž‘ì—…ì„ í•˜ì§€ 않ìŒ\n" -#: initdb.c:2671 +#: initdb.c:2300 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show ë‚´ë¶€ ì„¤ì •ê°’ë“¤ì„ ë³´ì—¬ì¤Œ\n" -#: initdb.c:2672 +#: initdb.c:2301 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr " -S, --sync-only ë°ì´í„° 디렉터리만 ë™ê¸°í™”\n" -#: initdb.c:2673 +#: initdb.c:2302 #, c-format msgid "" "\n" @@ -636,17 +617,17 @@ msgstr "" "\n" "기타 옵션:\n" -#: initdb.c:2674 +#: initdb.c:2303 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: initdb.c:2675 +#: initdb.c:2304 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: initdb.c:2676 +#: initdb.c:2305 #, c-format msgid "" "\n" @@ -656,7 +637,7 @@ msgstr "" "\n" "ë°ì´í„° 디렉터리를 지정하지 않으면, PGDATA 환경 ë³€ìˆ˜ê°’ì„ ì‚¬ìš©í•©ë‹ˆë‹¤.\n" -#: initdb.c:2678 +#: initdb.c:2307 #, c-format msgid "" "\n" @@ -665,7 +646,7 @@ msgstr "" "\n" "오류보고: .\n" -#: initdb.c:2686 +#: initdb.c:2315 msgid "" "\n" "WARNING: enabling \"trust\" authentication for local connections\n" @@ -678,19 +659,19 @@ msgstr "" "다ìŒë²ˆ initdb ëª…ë ¹ì„ ì‚¬ìš©í•  때, -A 옵션 ë˜ëŠ” --auth-local,\n" "--auth-host ì˜µì…˜ì„ ì‚¬ìš©í•´ì„œ ì¸ì¦ ë°©ë²•ì„ ì§€ì •í•  수 있습니다.\n" -#: initdb.c:2708 +#: initdb.c:2337 #, c-format msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" msgstr "%s: \"%s\" ì¸ì¦ ë°©ë²•ì€ \"%s\" ì—°ê²°ì—서는 사용할 수 없습니다.\n" -#: initdb.c:2722 +#: initdb.c:2353 #, c-format msgid "" "%s: must specify a password for the superuser to enable %s authentication\n" msgstr "" "%s: %s ì¸ì¦ë°©ì‹ì„ 사용하려면, 반드시 superuserì˜ ì•”í˜¸ë¥¼ 지정해야합니다.\n" -#: initdb.c:2749 +#: initdb.c:2381 #, c-format msgid "" "%s: no data directory specified\n" @@ -703,7 +684,7 @@ msgstr "" "지정하는 ë°©ë²•ì€ -D ì˜µì…˜ì˜ ê°’ì´ë‚˜, PGDATA 환경 변수값으로 지정해 주면 ë©ë‹ˆ" "다.\n" -#: initdb.c:2787 +#: initdb.c:2419 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" @@ -714,7 +695,7 @@ msgstr "" "\"%s\" 파ì¼ì´ 있는 ë””ë ‰í„°ë¦¬ì•ˆì— ì—†ìŠµë‹ˆë‹¤.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: initdb.c:2794 +#: initdb.c:2426 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" @@ -725,17 +706,17 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì˜ ë²„ì „ê³¼ 틀립니다.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: initdb.c:2813 +#: initdb.c:2445 #, c-format msgid "%s: input file location must be an absolute path\n" msgstr "%s: ìž…ë ¥ íŒŒì¼ ìœ„ì¹˜ëŠ” 반드시 절대경로여야합니다.\n" -#: initdb.c:2832 +#: initdb.c:2464 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ëŠ” \"%s\" 로케ì¼ìœ¼ë¡œ ì´ˆê¸°í™”ë  ê²ƒìž…ë‹ˆë‹¤.\n" -#: initdb.c:2835 +#: initdb.c:2467 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -754,22 +735,22 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2859 +#: initdb.c:2491 #, c-format msgid "%s: could not find suitable encoding for locale \"%s\"\n" msgstr "%s: \"%s\" ë¡œìº˜ì— ì•Œë§žì€ ì¸ì½”ë”©ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: initdb.c:2861 +#: initdb.c:2493 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "-E 옵션으로 %s 지정해 주십시오.\n" -#: initdb.c:2862 initdb.c:3485 initdb.c:3506 +#: initdb.c:2494 initdb.c:3123 initdb.c:3144 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "보다 ìžì„¸í•œ 정보를 보려면 \"%s --help\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤.\n" -#: initdb.c:2874 +#: initdb.c:2506 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -778,12 +759,12 @@ msgstr "" "\"%s\" ì¸ì½”ë”©ì„ ì„œë²„ì¸¡ ì¸ì½”딩으로 사용할 수 없습니다.\n" "기본 ë°ì´í„°ë² ì´ìŠ¤ëŠ” \"%s\" ì¸ì½”딩으로 지정ë©ë‹ˆë‹¤.\n" -#: initdb.c:2882 +#: initdb.c:2514 #, c-format msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" msgstr "%s: \"%s\" 로케ì¼ì€ ì§€ì›í•˜ì§€ 않는 \"%s\" ì¸ì½”ë”©ì„ í•„ìš”ë¡œ 함\n" -#: initdb.c:2885 +#: initdb.c:2517 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -792,25 +773,25 @@ msgstr "" "\"%s\" ì¸ì½”ë”©ì„ ì„œë²„ì¸¡ ì¸ì½”딩으로 사용할 수 없습니다.\n" "다른 ë¡œìº˜ì„ ì„ íƒí•˜ê³  %sì„(를) 다시 실행하십시오.\n" -#: initdb.c:2894 +#: initdb.c:2526 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "기본 ë°ì´í„°ë² ì´ìФ ì¸ì½”ë”©ì€ \"%s\" ì¸ì½”딩으로 설정ë˜ì—ˆìŠµë‹ˆë‹¤.\n" -#: initdb.c:2965 +#: initdb.c:2597 #, c-format msgid "" "%s: could not find suitable text search configuration for locale \"%s\"\n" msgstr "%s: \"%s\" 로케ì¼ì— ì•Œë§žì€ ì „ë¬¸ê²€ìƒ‰ ì„¤ì •ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: initdb.c:2976 +#: initdb.c:2608 #, c-format msgid "" "%s: warning: suitable text search configuration for locale \"%s\" is " "unknown\n" msgstr "%s: 경고: \"%s\" ë¡œìº˜ì— ì•Œë§žì€ ì „ë¬¸ê²€ìƒ‰ ì„¤ì •ì„ ì•Œ 수 ì—†ìŒ\n" -#: initdb.c:2981 +#: initdb.c:2613 #, c-format msgid "" "%s: warning: specified text search configuration \"%s\" might not match " @@ -818,37 +799,37 @@ msgid "" msgstr "" "%s: 경고: 지정한 \"%s\" 전문검색 ì„¤ì •ì€ \"%s\" 로케ì¼ê³¼ ì¼ì¹˜í•˜ì§€ 않ìŒ\n" -#: initdb.c:2986 +#: initdb.c:2618 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "기본 í…스트 검색 êµ¬ì„±ì´ \"%s\"(으)로 설정ë©ë‹ˆë‹¤.\n" -#: initdb.c:3030 initdb.c:3116 +#: initdb.c:2662 initdb.c:2748 #, c-format msgid "creating directory %s ... " msgstr "%s 디렉터리 만드는 중 ..." -#: initdb.c:3036 initdb.c:3122 initdb.c:3190 initdb.c:3246 +#: initdb.c:2668 initdb.c:2754 initdb.c:2822 initdb.c:2878 #, c-format msgid "%s: could not create directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리 만들 수 ì—†ìŒ: %s\n" -#: initdb.c:3048 initdb.c:3134 +#: initdb.c:2680 initdb.c:2766 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "ì´ë¯¸ 있는 %s ë””ë ‰í„°ë¦¬ì˜ ì•¡ì„¸ìŠ¤ ê¶Œí•œì„ ê³ ì¹˜ëŠ” 중 ..." -#: initdb.c:3054 initdb.c:3140 +#: initdb.c:2686 initdb.c:2772 #, c-format msgid "%s: could not change permissions of directory \"%s\": %s\n" msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì˜ ì•¡ì„¸ìŠ¤ ê¶Œí•œì„ ë°”ê¿€ 수 없습니다: %s\n" -#: initdb.c:3069 initdb.c:3155 +#: initdb.c:2701 initdb.c:2787 #, c-format msgid "%s: directory \"%s\" exists but is not empty\n" msgstr "%s: \"%s\" 디렉터리가 있지만 비어 있지 않ìŒ\n" -#: initdb.c:3075 +#: initdb.c:2707 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -859,52 +840,51 @@ msgstr "" "\"%s\" 디렉터리를 제거하거나 비우십시오. ë˜ëŠ” %sì„(를)\n" "\"%s\" ì´ì™¸ì˜ ì¸ìˆ˜ë¥¼ 사용하여 실행하십시오.\n" -#: initdb.c:3083 initdb.c:3168 initdb.c:3519 +#: initdb.c:2715 initdb.c:2800 initdb.c:3157 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ: %s\n" -#: initdb.c:3107 +#: initdb.c:2739 #, c-format -msgid "%s: transaction log directory location must be an absolute path\n" +msgid "%s: WAL directory location must be an absolute path\n" msgstr "%s: 트랜잭션 로그 디렉터리 위치는 절대 경로여야 함\n" -#: initdb.c:3161 +#: initdb.c:2793 #, c-format msgid "" -"If you want to store the transaction log there, either\n" -"remove or empty the directory \"%s\".\n" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" msgstr "" "트랜잭션 로그를 해당 ìœ„ì¹˜ì— ì €ìž¥í•˜ë ¤ë©´\n" "\"%s\" 디렉터리를 제거하거나 비우십시오.\n" -#: initdb.c:3176 +#: initdb.c:2808 #, c-format msgid "%s: could not create symbolic link \"%s\": %s\n" msgstr "%s: \"%s\" 심벌릭 ë§í¬ë¥¼ 만들 수 ì—†ìŒ: %s\n" -#: initdb.c:3181 +#: initdb.c:2813 #, c-format msgid "%s: symlinks are not supported on this platform" msgstr "%s: ì´ í”Œëž«í¼ì—서는 심볼 ë§í¬ê°€ ì§€ì›ë˜ì§€ 않ìŒ" -#: initdb.c:3205 +#: initdb.c:2837 #, c-format msgid "" "It contains a dot-prefixed/invisible file, perhaps due to it being a mount " "point.\n" msgstr "" -"ì (.)으로 시작하는 ìˆ¨ì€ íŒŒì¼ì´ í¬í•¨ë˜ì–´ 있습니다. 마운트 최ìƒìœ„ 디렉터리 " -"같습니다.\n" +"ì (.)으로 시작하는 ìˆ¨ì€ íŒŒì¼ì´ í¬í•¨ë˜ì–´ 있습니다. 마운트 최ìƒìœ„ 디렉터리 같습" +"니다.\n" -#: initdb.c:3208 +#: initdb.c:2840 #, c-format msgid "" "It contains a lost+found directory, perhaps due to it being a mount point.\n" -msgstr "" -"lost-found 디렉터리가 있습니다. 마운트 최ìƒìœ„ 디렉터리 같습니다.\n" +msgstr "lost-found 디렉터리가 있습니다. 마운트 최ìƒìœ„ 디렉터리 같습니다.\n" -#: initdb.c:3211 +#: initdb.c:2843 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -913,47 +893,51 @@ msgstr "" "마운트 최ìƒìœ„ 디렉터리를 ë°ì´í„° 디렉터리로 사용하는 ê²ƒì€ ê¶Œìž¥í•˜ì§€ 않습니다.\n" "하위 디렉터리를 만들어서 ê·¸ê²ƒì„ ë°ì´í„° 디렉터리로 사용하세요.\n" -#: initdb.c:3231 +#: initdb.c:2863 #, c-format msgid "creating subdirectories ... " msgstr "하위 디렉터리 만드는 중 ..." -#: initdb.c:3278 +#: initdb.c:2910 msgid "performing post-bootstrap initialization ... " msgstr "부트스트랩 ë‹¤ìŒ ì´ˆê¸°í™” 작업 중 ... " -#: initdb.c:3429 +#: initdb.c:3067 #, c-format msgid "Running in debug mode.\n" msgstr "디버그 모드로 실행 중.\n" -#: initdb.c:3433 +#: initdb.c:3071 #, c-format -msgid "Running in noclean mode. Mistakes will not be cleaned up.\n" +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "지저분 모드로 실행 중. 오류가 ë°œìƒë˜ì–´ë„ 뒷정리를 안합니다.\n" -#: initdb.c:3504 +#: initdb.c:3142 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" -#: initdb.c:3530 +#: initdb.c:3162 initdb.c:3228 +msgid "syncing data to disk ... " +msgstr "ìžë£Œë¥¼ 디스í¬ì— ë™ê¸°í™” 하는 중 ... " + +#: initdb.c:3171 #, c-format msgid "%s: password prompt and password file cannot be specified together\n" msgstr "" "%s: 암호를 입력받는 옵션과 암호를 파ì¼ì—서 가져오는 ì˜µì…˜ì€ ë™ì‹œì— ì‚¬ìš©ë  ìˆ˜ " "없습니다\n" -#: initdb.c:3554 +#: initdb.c:3195 #, c-format msgid "" "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_" "\"\n" msgstr "" -"%s: \"%s\" 사용ìžëŠ” 슈í¼ìœ ì € ì´ë¦„으로 쓸 수 없습니다. \"pg_\"로 시작하는" -"롤 ì´ë¦„ì€ í—ˆìš©í•˜ì§€ 않습니다.\n" +"%s: \"%s\" 사용ìžëŠ” 슈í¼ìœ ì € ì´ë¦„으로 쓸 수 없습니다. \"pg_\"로 시작하는롤 ì´" +"ë¦„ì€ í—ˆìš©í•˜ì§€ 않습니다.\n" -#: initdb.c:3558 +#: initdb.c:3199 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -964,17 +948,17 @@ msgstr "" "ì§€ì •ë  ê²ƒìž…ë‹ˆë‹¤. ë˜í•œ ì´ ì‚¬ìš©ìžëŠ” 서버 í”„ë¡œì„¸ìŠ¤ì˜ ì†Œìœ ì£¼ê°€ ë©ë‹ˆë‹¤.\n" "\n" -#: initdb.c:3574 +#: initdb.c:3215 #, c-format msgid "Data page checksums are enabled.\n" msgstr "ìžë£Œ 페ì´ì§€ ì²´í¬ì„¬ 기능 사용함.\n" -#: initdb.c:3576 +#: initdb.c:3217 #, c-format msgid "Data page checksums are disabled.\n" msgstr "ìžë£Œ 페ì´ì§€ ì²´í¬ì„¬ 기능 사용 하지 않ìŒ\n" -#: initdb.c:3585 +#: initdb.c:3234 #, c-format msgid "" "\n" @@ -983,19 +967,25 @@ msgid "" msgstr "" "\n" "ë””ìŠ¤í¬ ë™ê¸°í™” ìž‘ì—…ì€ ìƒëžµí–ˆìŠµë‹ˆë‹¤.\n" -"ì´ ìƒíƒœì—서 OSê°€ ê°‘ìžê¸° 중지 ë˜ë©´ ë°ì´í„° 디렉토리 ì•ˆì— ìžˆëŠ” ìžë£Œê°€ 깨질 수 있습니다.\n" +"ì´ ìƒíƒœì—서 OSê°€ ê°‘ìžê¸° 중지 ë˜ë©´ ë°ì´í„° 디렉토리 ì•ˆì— ìžˆëŠ” ìžë£Œê°€ 깨질 수 있" +"습니다.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3260 +msgid "logfile" +msgstr "로그파ì¼" -#: initdb.c:3594 +#: initdb.c:3262 #, c-format msgid "" "\n" "Success. You can now start the database server using:\n" "\n" -" %s%s%spg_ctl%s -D %s%s%s -l logfile start\n" +" %s\n" "\n" msgstr "" "\n" "작업완료. ì´ì œ ë‹¤ìŒ ëª…ë ¹ì„ ì´ìš©í•´ì„œ 서버를 ê°€ë™ í•  수 있습니다:\n" "\n" -" %s%s%spg_ctl%s -D %s%s%s -l ë¡œê·¸íŒŒì¼ start\n" +" %s\n" "\n" diff --git a/src/bin/initdb/po/ru.po b/src/bin/initdb/po/ru.po index 8f3d42e55c5..3bc98c69462 100644 --- a/src/bin/initdb/po/ru.po +++ b/src/bin/initdb/po/ru.po @@ -7,13 +7,13 @@ # Andrey Sudnik , 2010. # Dmitriy Olshevskiy , 2014. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: initdb (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-02 23:46+0000\n" -"PO-Revision-Date: 2017-04-03 14:13+0300\n" +"POT-Creation-Date: 2017-08-17 23:15+0000\n" +"PO-Revision-Date: 2017-10-12 10:13+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -21,7 +21,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -268,23 +267,23 @@ msgstr "%s: ошибка при удалении Ñодержимого ката #: initdb.c:566 #, c-format -msgid "%s: removing transaction log directory \"%s\"\n" -msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: удаление каталога WAL \"%s\"\n" #: initdb.c:569 #, c-format -msgid "%s: failed to remove transaction log directory\n" -msgstr "%s: ошибка при удалении каталога журнала транзакций\n" +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: ошибка при удалении каталога WAL\n" #: initdb.c:575 #, c-format -msgid "%s: removing contents of transaction log directory \"%s\"\n" -msgstr "%s: очиÑтка каталога журнала транзакций \"%s\"\n" +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: удаление Ñодержимого каталога WAL \"%s\"\n" #: initdb.c:578 #, c-format -msgid "%s: failed to remove contents of transaction log directory\n" -msgstr "%s: ошибка при очиÑтке каталога журнала транзакций\n" +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: ошибка при удалении Ñодержимого каталога WAL\n" #: initdb.c:587 #, c-format @@ -293,9 +292,8 @@ msgstr "%s: каталог данных \"%s\" не был удалён по з #: initdb.c:592 #, c-format -msgid "%s: transaction log directory \"%s\" not removed at user's request\n" -msgstr "" -"%s: каталог журнала транзакций \"%s\" не был удалён по запроÑу пользователÑ\n" +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: каталог WAL \"%s\" не был удалён по запроÑу пользователÑ\n" #: initdb.c:613 #, c-format @@ -350,7 +348,7 @@ msgstr "выбираетÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ðµ shared_buffers... " #: initdb.c:996 #, c-format msgid "selecting dynamic shared memory implementation ... " -msgstr "выбор реализации динамичеÑкой разделÑемой памÑти ... " +msgstr "выбор реализации динамичеÑкой разделÑемой памÑти... " #: initdb.c:1014 msgid "creating configuration files ... " @@ -364,7 +362,7 @@ msgstr "%s: не удалоÑÑŒ поменÑть права Ð´Ð»Ñ \"%s\": %s\n" #: initdb.c:1293 #, c-format msgid "running bootstrap script ... " -msgstr "выполнÑетÑÑ Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¹ Ñкрипт ... " +msgstr "выполнÑетÑÑ Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¹ Ñкрипт... " #: initdb.c:1309 #, c-format @@ -399,49 +397,49 @@ msgstr "%s: не удалоÑÑŒ прочитать пароль из файла msgid "%s: password file \"%s\" is empty\n" msgstr "%s: файл Ð¿Ð°Ñ€Ð¾Ð»Ñ \"%s\" пуÑÑ‚\n" -#: initdb.c:2012 +#: initdb.c:2027 #, c-format msgid "caught signal\n" msgstr "получен Ñигнал\n" -#: initdb.c:2018 +#: initdb.c:2033 #, c-format msgid "could not write to child process: %s\n" msgstr "не удалоÑÑŒ запиÑать в поток дочернего процеÑÑа: %s\n" -#: initdb.c:2026 +#: initdb.c:2041 #, c-format msgid "ok\n" msgstr "ок\n" -#: initdb.c:2116 +#: initdb.c:2131 #, c-format msgid "%s: setlocale() failed\n" msgstr "%s: ошибка в setlocale()\n" -#: initdb.c:2134 +#: initdb.c:2149 #, c-format msgid "%s: failed to restore old locale \"%s\"\n" msgstr "%s: не удалоÑÑŒ воÑÑтановить Ñтарую локаль \"%s\"\n" -#: initdb.c:2144 +#: initdb.c:2159 #, c-format msgid "%s: invalid locale name \"%s\"\n" msgstr "%s: ошибочное Ð¸Ð¼Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\"\n" -#: initdb.c:2156 +#: initdb.c:2171 #, c-format msgid "" "%s: invalid locale settings; check LANG and LC_* environment variables\n" msgstr "" "%s: неверные уÑтановки локали; проверьте переменные Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ LANG и LC_*\n" -#: initdb.c:2184 +#: initdb.c:2199 #, c-format msgid "%s: encoding mismatch\n" msgstr "%s: неÑоответÑтвие кодировки\n" -#: initdb.c:2186 +#: initdb.c:2201 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -456,7 +454,7 @@ msgstr "" "Ð”Ð»Ñ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð¿ÑƒÑтите %s, не ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÑƒ Ñвно, \n" "либо выберите подходÑщее Ñочетание параметров локализации.\n" -#: initdb.c:2258 +#: initdb.c:2273 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -465,17 +463,17 @@ msgstr "" "%s инициализирует клаÑтер PostgreSQL.\n" "\n" -#: initdb.c:2259 +#: initdb.c:2274 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: initdb.c:2260 +#: initdb.c:2275 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [ПÐРÐМЕТР]... [КÐТÐЛОГ]\n" -#: initdb.c:2261 +#: initdb.c:2276 #, c-format msgid "" "\n" @@ -484,7 +482,7 @@ msgstr "" "\n" "Параметры:\n" -#: initdb.c:2262 +#: initdb.c:2277 #, c-format msgid "" " -A, --auth=METHOD default authentication method for local " @@ -493,7 +491,7 @@ msgstr "" " -A, --auth=МЕТОД метод проверки подлинноÑти по умолчанию\n" " Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… подключений\n" -#: initdb.c:2263 +#: initdb.c:2278 #, c-format msgid "" " --auth-host=METHOD default authentication method for local TCP/IP " @@ -502,7 +500,7 @@ msgstr "" " --auth-host=МЕТОД метод проверки подлинноÑти по умолчанию\n" " Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… TCP/IP-подключений\n" -#: initdb.c:2264 +#: initdb.c:2279 #, c-format msgid "" " --auth-local=METHOD default authentication method for local-socket " @@ -511,22 +509,22 @@ msgstr "" " --auth-local=МЕТОД метод проверки подлинноÑти по умолчанию\n" " Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ñ‹Ñ… подключений через Ñокет\n" -#: initdb.c:2265 +#: initdb.c:2280 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]КÐТÐЛОГ раÑположение данных Ñтого клаÑтера БД\n" -#: initdb.c:2266 +#: initdb.c:2281 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=КОДИРОВКРкодировка по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… баз\n" -#: initdb.c:2267 +#: initdb.c:2282 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=ЛОКÐЛЬ локаль по умолчанию Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… баз\n" -#: initdb.c:2268 +#: initdb.c:2283 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -540,19 +538,19 @@ msgstr "" " уÑтановить ÑоответÑтвующий параметр локали\n" " Ð´Ð»Ñ Ð½Ð¾Ð²Ñ‹Ñ… баз (вмеÑто Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð· окружениÑ)\n" -#: initdb.c:2272 +#: initdb.c:2287 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale Ñквивалентно --locale=C\n" -#: initdb.c:2273 +#: initdb.c:2288 #, c-format msgid "" " --pwfile=FILE read password for the new superuser from file\n" msgstr "" " --pwfile=ФÐЙЛ прочитать пароль ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð· файла\n" -#: initdb.c:2274 +#: initdb.c:2289 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -561,24 +559,24 @@ msgstr "" " -T, --text-search-config=КОÐФИГУРÐЦИЯ\n" " ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка по умолчанию\n" -#: initdb.c:2276 +#: initdb.c:2291 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=ИМЯ Ð¸Ð¼Ñ ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð‘Ð”\n" -#: initdb.c:2277 +#: initdb.c:2292 #, c-format msgid "" " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt запроÑить пароль ÑуперпользователÑ\n" -#: initdb.c:2278 +#: initdb.c:2293 #, c-format msgid "" " -X, --waldir=WALDIR location for the write-ahead log directory\n" -msgstr " -X, --waldir=КÐТÐЛОГ раÑположение журнала транзакций\n" +msgstr " -X, --waldir=КÐТÐЛОГ раÑположение журнала предзапиÑи\n" -#: initdb.c:2279 +#: initdb.c:2294 #, c-format msgid "" "\n" @@ -587,27 +585,27 @@ msgstr "" "\n" "Редко иÑпользуемые параметры:\n" -#: initdb.c:2280 +#: initdb.c:2295 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug выдавать много отладочных Ñообщений\n" -#: initdb.c:2281 +#: initdb.c:2296 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums включить контроль целоÑтноÑти Ñтраниц\n" -#: initdb.c:2282 +#: initdb.c:2297 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L КÐТÐЛОГ раÑположение входных файлов\n" -#: initdb.c:2283 +#: initdb.c:2298 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean не очищать поÑле ошибок\n" -#: initdb.c:2284 +#: initdb.c:2299 #, c-format msgid "" " -N, --no-sync do not wait for changes to be written safely to " @@ -615,18 +613,18 @@ msgid "" msgstr "" " -N, --no-sync не ждать Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на диÑке\n" -#: initdb.c:2285 +#: initdb.c:2300 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show показать внутренние уÑтановки\n" -#: initdb.c:2286 +#: initdb.c:2301 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr "" " -S, --sync-only только Ñинхронизировать Ñ Ð¤Ð¡ каталог данных\n" -#: initdb.c:2287 +#: initdb.c:2302 #, c-format msgid "" "\n" @@ -635,17 +633,17 @@ msgstr "" "\n" "Другие параметры:\n" -#: initdb.c:2288 +#: initdb.c:2303 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: initdb.c:2289 +#: initdb.c:2304 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: initdb.c:2290 +#: initdb.c:2305 #, c-format msgid "" "\n" @@ -655,7 +653,7 @@ msgstr "" "\n" "ЕÑли каталог данных не указан, иÑпользуетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: initdb.c:2292 +#: initdb.c:2307 #, c-format msgid "" "\n" @@ -664,7 +662,7 @@ msgstr "" "\n" "Об ошибках Ñообщайте по адреÑу .\n" -#: initdb.c:2300 +#: initdb.c:2315 msgid "" "\n" "WARNING: enabling \"trust\" authentication for local connections\n" @@ -678,20 +676,20 @@ msgstr "" "A,\n" "--auth-local или --auth-host при Ñледующем выполнении initdb.\n" -#: initdb.c:2322 +#: initdb.c:2337 #, c-format msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" msgstr "" "%s: нераÑпознанный метод проверки подлинноÑти \"%s\" Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ð¹ \"%s\"\n" -#: initdb.c:2338 +#: initdb.c:2353 #, c-format msgid "" "%s: must specify a password for the superuser to enable %s authentication\n" msgstr "" "%s: Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼ÐµÑ‚Ð¾Ð´Ð° %s необходимо указать пароль ÑуперпользователÑ\n" -#: initdb.c:2366 +#: initdb.c:2381 #, c-format msgid "" "%s: no data directory specified\n" @@ -704,7 +702,7 @@ msgstr "" "Это можно Ñделать, добавив ключ -D или уÑтановив переменную\n" "Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: initdb.c:2404 +#: initdb.c:2419 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" @@ -715,7 +713,7 @@ msgstr "" "в каталоге \"%s\".\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: initdb.c:2411 +#: initdb.c:2426 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" @@ -726,17 +724,17 @@ msgstr "" "но её верÑÐ¸Ñ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð°ÐµÑ‚ÑÑ Ð¾Ñ‚ верÑии %s.\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: initdb.c:2430 +#: initdb.c:2445 #, c-format msgid "%s: input file location must be an absolute path\n" msgstr "%s: раÑположение входных файлов должно задаватьÑÑ Ð°Ð±Ñолютным путём\n" -#: initdb.c:2449 +#: initdb.c:2464 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "КлаÑтер баз данных будет инициализирован Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÑŽ \"%s\".\n" -#: initdb.c:2452 +#: initdb.c:2467 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -755,22 +753,22 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2476 +#: initdb.c:2491 #, c-format msgid "%s: could not find suitable encoding for locale \"%s\"\n" msgstr "%s: не удалоÑÑŒ найти подходÑщую кодировку Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\"\n" -#: initdb.c:2478 +#: initdb.c:2493 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "ПерезапуÑтите %s Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -E.\n" -#: initdb.c:2479 initdb.c:3103 initdb.c:3124 +#: initdb.c:2494 initdb.c:3123 initdb.c:3144 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: initdb.c:2491 +#: initdb.c:2506 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -779,12 +777,12 @@ msgstr "" "Кодировка \"%s\", Ð¿Ð¾Ð´Ñ€Ð°Ð·ÑƒÐ¼ÐµÐ²Ð°ÐµÐ¼Ð°Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÑŽ, не годитÑÑ Ð´Ð»Ñ Ñервера.\n" "ВмеÑто неё в качеÑтве кодировки БД по умолчанию будет выбрана \"%s\".\n" -#: initdb.c:2499 +#: initdb.c:2514 #, c-format msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" msgstr "%s: Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\" требуетÑÑ Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° \"%s\"\n" -#: initdb.c:2502 +#: initdb.c:2517 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -793,13 +791,13 @@ msgstr "" "Кодировка \"%s\" недопуÑтима в качеÑтве кодировки Ñервера.\n" "ПерезапуÑтите %s, выбрав другую локаль.\n" -#: initdb.c:2511 +#: initdb.c:2526 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "" "Кодировка БД по умолчанию, Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ð°Ñ Ð² ÑоответÑтвии Ñ Ð½Ð°Ñтройками: \"%s\".\n" -#: initdb.c:2582 +#: initdb.c:2597 #, c-format msgid "" "%s: could not find suitable text search configuration for locale \"%s\"\n" @@ -807,7 +805,7 @@ msgstr "" "%s: не удалоÑÑŒ найти подходÑщую конфигурацию текÑтового поиÑка Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ " "\"%s\"\n" -#: initdb.c:2593 +#: initdb.c:2608 #, c-format msgid "" "%s: warning: suitable text search configuration for locale \"%s\" is " @@ -816,7 +814,7 @@ msgstr "" "%s: внимание: Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ \"%s\" нет извеÑтной конфигурации текÑтового " "поиÑка\n" -#: initdb.c:2598 +#: initdb.c:2613 #, c-format msgid "" "%s: warning: specified text search configuration \"%s\" might not match " @@ -825,37 +823,37 @@ msgstr "" "%s: внимание: ÑƒÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\" может не " "ÑоответÑтвовать локали \"%s\"\n" -#: initdb.c:2603 +#: initdb.c:2618 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "Выбрана ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка по умолчанию \"%s\".\n" -#: initdb.c:2647 initdb.c:2733 +#: initdb.c:2662 initdb.c:2748 #, c-format msgid "creating directory %s ... " msgstr "Ñоздание каталога %s... " -#: initdb.c:2653 initdb.c:2739 initdb.c:2807 initdb.c:2863 +#: initdb.c:2668 initdb.c:2754 initdb.c:2822 initdb.c:2878 #, c-format msgid "%s: could not create directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать каталог \"%s\": %s\n" -#: initdb.c:2665 initdb.c:2751 +#: initdb.c:2680 initdb.c:2766 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "иÑправление прав Ð´Ð»Ñ ÑущеÑтвующего каталога %s... " -#: initdb.c:2671 initdb.c:2757 +#: initdb.c:2686 initdb.c:2772 #, c-format msgid "%s: could not change permissions of directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ поменÑть права Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° \"%s\": %s\n" -#: initdb.c:2686 initdb.c:2772 +#: initdb.c:2701 initdb.c:2787 #, c-format msgid "%s: directory \"%s\" exists but is not empty\n" msgstr "%s: каталог \"%s\" ÑущеÑтвует, но он не пуÑÑ‚\n" -#: initdb.c:2692 +#: initdb.c:2707 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -866,38 +864,36 @@ msgstr "" "удалите или очиÑтите каталог \"%s\",\n" "либо при запуÑке %s в качеÑтве пути укажите не \"%s\".\n" -#: initdb.c:2700 initdb.c:2785 initdb.c:3137 +#: initdb.c:2715 initdb.c:2800 initdb.c:3157 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: нет доÑтупа к каталогу \"%s\": %s\n" -#: initdb.c:2724 +#: initdb.c:2739 #, c-format -msgid "%s: transaction log directory location must be an absolute path\n" -msgstr "" -"%s: раÑположение каталога журнала транзакций должно определÑтьÑÑ Ð°Ð±Ñолютным " -"путём\n" +msgid "%s: WAL directory location must be an absolute path\n" +msgstr "%s: раÑположение каталога WAL должно определÑтьÑÑ Ð°Ð±Ñолютным путём\n" -#: initdb.c:2778 +#: initdb.c:2793 #, c-format msgid "" -"If you want to store the transaction log there, either\n" -"remove or empty the directory \"%s\".\n" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" msgstr "" -"ЕÑли вы хотите хранить журнал транзакций здеÑÑŒ,\n" -"удалите или очиÑтите каталог \"%s\".\n" +"ЕÑли вы хотите хранить WAL здеÑÑŒ, удалите или очиÑтите каталог\n" +"\"%s\".\n" -#: initdb.c:2793 +#: initdb.c:2808 #, c-format msgid "%s: could not create symbolic link \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать ÑимволичеÑкую ÑÑылку \"%s\": %s\n" -#: initdb.c:2798 +#: initdb.c:2813 #, c-format msgid "%s: symlinks are not supported on this platform" msgstr "%s: ÑимволичеÑкие ÑÑылки не поддерживаютÑÑ Ð² Ñтой ОС" -#: initdb.c:2822 +#: initdb.c:2837 #, c-format msgid "" "It contains a dot-prefixed/invisible file, perhaps due to it being a mount " @@ -905,13 +901,13 @@ msgid "" msgstr "" "Он Ñодержит файл Ñ Ñ‚Ð¾Ñ‡ÐºÐ¾Ð¹ (невидимый), возможно Ñто точка монтированиÑ.\n" -#: initdb.c:2825 +#: initdb.c:2840 #, c-format msgid "" "It contains a lost+found directory, perhaps due to it being a mount point.\n" msgstr "Он Ñодержит подкаталог lost+found, возможно Ñто точка монтированиÑ.\n" -#: initdb.c:2828 +#: initdb.c:2843 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -921,42 +917,42 @@ msgstr "" "рекомендуетÑÑ.\n" "Создайте в монтируемом реÑурÑе подкаталог и иÑпользуйте его.\n" -#: initdb.c:2848 +#: initdb.c:2863 #, c-format msgid "creating subdirectories ... " msgstr "Ñоздание подкаталогов... " -#: initdb.c:2895 +#: initdb.c:2910 msgid "performing post-bootstrap initialization ... " -msgstr "выполнÑетÑÑ Ð·Ð°ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ ... " +msgstr "выполнÑетÑÑ Ð·Ð°ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ... " -#: initdb.c:3047 +#: initdb.c:3067 #, c-format msgid "Running in debug mode.\n" msgstr "Программа запущена в режиме отладки.\n" -#: initdb.c:3051 +#: initdb.c:3071 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "" "Программа запущена в режиме 'no-clean' - очиÑтки и иÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¾ÑˆÐ¸Ð±Ð¾Ðº не " "будет.\n" -#: initdb.c:3122 +#: initdb.c:3142 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: initdb.c:3142 initdb.c:3208 +#: initdb.c:3162 initdb.c:3228 msgid "syncing data to disk ... " msgstr "Ñохранение данных на диÑке... " -#: initdb.c:3151 +#: initdb.c:3171 #, c-format msgid "%s: password prompt and password file cannot be specified together\n" msgstr "%s: Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ð´Ð½Ð¾Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð¾ запроÑить пароль и прочитать пароль из файла\n" -#: initdb.c:3175 +#: initdb.c:3195 #, c-format msgid "" "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_" @@ -965,7 +961,7 @@ msgstr "" "%s: Ð¸Ð¼Ñ \"%s\" Ð´Ð»Ñ ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ допуÑкаетÑÑ; имена ролей не могут " "начинатьÑÑ Ñ \"pg_\"\n" -#: initdb.c:3179 +#: initdb.c:3199 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -976,17 +972,17 @@ msgstr "" "От его имени также будет запуÑкатьÑÑ Ð¿Ñ€Ð¾Ñ†ÐµÑÑ Ñервера.\n" "\n" -#: initdb.c:3195 +#: initdb.c:3215 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Контроль целоÑтноÑти Ñтраниц данных включён.\n" -#: initdb.c:3197 +#: initdb.c:3217 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Контроль целоÑтноÑти Ñтраниц данных отключён.\n" -#: initdb.c:3214 +#: initdb.c:3234 #, c-format msgid "" "\n" @@ -998,11 +994,11 @@ msgstr "" "Каталог данных может повредитьÑÑ Ð¿Ñ€Ð¸ Ñбое операционной ÑиÑтемы.\n" #. translator: This is a placeholder in a shell command. -#: initdb.c:3240 +#: initdb.c:3260 msgid "logfile" msgstr "файл_журнала" -#: initdb.c:3242 +#: initdb.c:3262 #, c-format msgid "" "\n" @@ -1017,6 +1013,23 @@ msgstr "" " %s\n" "\n" +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: ошибка при удалении каталога журнала транзакций\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: очиÑтка каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: ошибка при очиÑтке каталога журнала транзакций\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s: каталог журнала транзакций \"%s\" не был удалён по запроÑу " +#~ "пользователÑ\n" + #~ msgid "%s: locale name too long, skipped: \"%s\"\n" #~ msgstr "%s: Ñлишком длинное Ð¸Ð¼Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸, пропущено: \"%s\"\n" diff --git a/src/bin/initdb/po/sv.po b/src/bin/initdb/po/sv.po index 720fb64563b..648f41c702e 100644 --- a/src/bin/initdb/po/sv.po +++ b/src/bin/initdb/po/sv.po @@ -1,5 +1,5 @@ # Swedish message translation file for initdb -# Dennis Björklund , 2004, 2005, 2006, 2017. +# Dennis Björklund , 2004, 2005, 2006, 2017, 2018, 2019. # Magnus Hagander , 2007. # Peter Eisentraut , 2009. # Mats Erik Andersson , 2014. @@ -9,9 +9,9 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-13 23:46+0000\n" -"PO-Revision-Date: 2017-07-20 21:33+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-27 01:47+0000\n" +"PO-Revision-Date: 2019-04-27 14:46+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -19,40 +19,61 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "could not identify current directory: %s" -msgstr "kunde inte identifiera aktuell katalog: %s" +msgid "fatal: " +msgstr "fatalt: " -#: ../../common/exec.c:146 +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ogiltig binär \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "kunde inte läsa binär \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "kunde inte byta katalog till \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "kunde inte läsa symbolisk länk \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose misslyckades: %s" +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: initdb.c:339 +#, c-format +msgid "out of memory" +msgstr "slut pÃ¥ minne" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -65,96 +86,86 @@ msgstr "slut pÃ¥ minne\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kan inte duplicera null-pekare (internt fel)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 -#, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: kunde ta status pÃ¥ filen \"%s\": %s\n" - -#: ../../common/file_utils.c:162 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" -#: ../../common/file_utils.c:198 +#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: kunde inte öppna fil \"%s\": %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: kunde inte utföra fsync pÃ¥ filen \"%s\": %s\n" +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: kunde inte döpa om fil \"%s\" till \"%s\": %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "kunde inte fsync:a fil \"%s\": %m" -#: ../../common/pgfnames.c:45 +#: ../../common/file_utils.c:377 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "kunde inte öppna katalog \"%s\": %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" -#: ../../common/pgfnames.c:72 +#: ../../common/pgfnames.c:74 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "kunde inte läsa katalog \"%s\": %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" -#: ../../common/pgfnames.c:84 +#: ../../common/restricted_token.c:69 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "kunde inte stänga katalog \"%s\": %s\n" +msgid "cannot create restricted tokens on this platform" +msgstr "kan inte skapa token för begränsad Ã¥tkomst pÃ¥ denna plattorm" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:78 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: VARNING: \"Restricted Token\" stöds inte av plattformen.\n" +msgid "could not open process token: error code %lu" +msgstr "kunde inte öppna process-token: felkod %lu" -#: ../../common/restricted_token.c:77 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: kunde inte skapa processmärke (token): felkod %lu\n" - -#: ../../common/restricted_token.c:90 -#, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: kunde inte tilldela SID: felkod %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "kunde inte allokera SID: felkod %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "kunde inte skapa token för begränsad Ã¥tkomst: felkod %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "kunde inte starta process för kommando \"%s\": felkod %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: kunde inte upprepa med restriktivt styrmärke (token): felkod %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kunde inte köra igen med token för begränsad Ã¥tkomst: felkod %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: kunde inte utvinna statuskod för underprocess: felkod %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "kunde inte hämta statuskod för underprocess: felkod %lu" -#: ../../common/rmtree.c:77 +#: ../../common/rmtree.c:79 #, c-format -msgid "could not stat file or directory \"%s\": %s\n" -msgstr "kunde inte ta status pÃ¥ fil eller katalog \"%s\": %s\n" +msgid "could not stat file or directory \"%s\": %m" +msgstr "kunde inte ta status pÃ¥ fil eller katalog \"%s\": %m" -#: ../../common/rmtree.c:104 ../../common/rmtree.c:121 +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 #, c-format -msgid "could not remove file or directory \"%s\": %s\n" -msgstr "kunde inte ta bort fil eller katalog \"%s\": %s\n" +msgid "could not remove file or directory \"%s\": %m" +msgstr "kunde inte ta bort fil eller katalog \"%s\": %m" #: ../../common/username.c:43 #, c-format @@ -185,22 +196,17 @@ msgstr "kommandot kan ej hittas" msgid "child process exited with exit code %d" msgstr "barnprocess avslutade med kod %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "barnprocess terminerades med avbrott 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "barnprocess terminerades av signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "barnprocess terminerades av signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "barnprocess avslutade med okänd statuskod %d" @@ -215,103 +221,101 @@ msgstr "kunde inte sätta en knutpunkt (junction) för \"%s\": %s\n" msgid "could not get junction for \"%s\": %s\n" msgstr "kunde inte fÃ¥ en knutpunkt (junction) för \"%s\": %s\n" -#: initdb.c:331 +#: initdb.c:495 initdb.c:1534 #, c-format -msgid "%s: out of memory\n" -msgstr "%s: slut pÃ¥ minne\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" -#: initdb.c:441 initdb.c:1442 +#: initdb.c:550 initdb.c:858 initdb.c:884 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" +msgid "could not open file \"%s\" for writing: %m" +msgstr "kunde inte öppna fil \"%s\" för skrivning: %m" -#: initdb.c:497 initdb.c:813 initdb.c:841 +#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 #, c-format -msgid "%s: could not open file \"%s\" for writing: %s\n" -msgstr "%s: kunde inte öppna fil \"%s\" för skrivning: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" -#: initdb.c:505 initdb.c:513 initdb.c:820 initdb.c:847 +#: initdb.c:582 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: kunde inte skriva fil \"%s\": %s\n" +msgid "could not execute command \"%s\": %m" +msgstr "kunde inte köra kommandot \"%s\": %m" -#: initdb.c:532 +#: initdb.c:600 #, c-format -msgid "%s: could not execute command \"%s\": %s\n" -msgstr "%s: kunde inte utföra kommandot \"%s\": %s\n" +msgid "removing data directory \"%s\"" +msgstr "tar bort datakatalog \"%s\"" -#: initdb.c:548 +#: initdb.c:602 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s: tar bort datakatalog \"%s\".\n" +msgid "failed to remove data directory" +msgstr "misslyckades med att ta bort datakatalog" -#: initdb.c:551 +#: initdb.c:606 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s: misslyckades med att ta bort datakatalog.\n" +msgid "removing contents of data directory \"%s\"" +msgstr "tar bort innehÃ¥llet i datakatalog \"%s\"" -#: initdb.c:557 +#: initdb.c:609 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s: tömmer innehÃ¥llet i datakatalog \"%s\".\n" +msgid "failed to remove contents of data directory" +msgstr "misslyckades med att ta bort innehÃ¥llet i datakatalogen" -#: initdb.c:560 +#: initdb.c:614 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s: misslyckades med att tömma datakatalog.\n" +msgid "removing WAL directory \"%s\"" +msgstr "tar bort WAL-katalog \"%s\"" -#: initdb.c:566 +#: initdb.c:616 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s: tar bort WAL-katalog \"%s\"\n" +msgid "failed to remove WAL directory" +msgstr "misslyckades med att ta bort WAL-katalog" -#: initdb.c:569 +#: initdb.c:620 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s: misslyckades med att ta bort WAL-katalog.\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "tar bort innehÃ¥llet i WAL-katalog \"%s\"" -#: initdb.c:575 +#: initdb.c:622 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s: tömmer innehÃ¥llet i WAL-katalog \"%s\"\n" +msgid "failed to remove contents of WAL directory" +msgstr "misslyckades med att ta bort innehÃ¥llet i WAL-katalogen" -#: initdb.c:578 +#: initdb.c:629 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s: misslyckades med att tömma WAL-katalog\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "datakatalog \"%s\" är ej borttagen pÃ¥ användares begäran" -#: initdb.c:587 +#: initdb.c:633 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s: Datakatalog \"%s\" ej borttagen pÃ¥ användares begäran.\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-katalog \"%s\" är ej borttagen pÃ¥ användares begäran" -#: initdb.c:592 +#: initdb.c:651 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s: WAL-katalog \"%s\" ej borttagen pÃ¥ användares begäran.\n" +msgid "cannot be run as root" +msgstr "kan inte köras som root" -#: initdb.c:613 +#: initdb.c:653 #, c-format msgid "" -"%s: cannot be run as root\n" "Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" "own the server process.\n" msgstr "" -"%s: kan inte köras som root\n" "Logga in (t.ex. med \"su\") som den (opriviligerade) användare\n" -"vilken skall äga serverprocessen.\n" +"som skall äga serverprocessen.\n" -#: initdb.c:649 +#: initdb.c:686 #, c-format -msgid "%s: \"%s\" is not a valid server encoding name\n" -msgstr "%s: \"%s\" är inte en giltig teckenkodning för servern.\n" +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\" är inte en giltig teckenkodning för servern" -#: initdb.c:769 +#: initdb.c:817 #, c-format -msgid "%s: file \"%s\" does not exist\n" -msgstr "%s: Filen \"%s\" existerar inte.\n" +msgid "file \"%s\" does not exist" +msgstr "filen \"%s\" finns inte" -#: initdb.c:771 initdb.c:780 initdb.c:790 +#: initdb.c:819 initdb.c:826 initdb.c:835 #, c-format msgid "" "This might mean you have a corrupted installation or identified\n" @@ -320,122 +324,128 @@ msgstr "" "Detta kan betyda att du har en korrupt installation eller att du har\n" "angivit felaktig katalog till flaggan -L.\n" -#: initdb.c:777 +#: initdb.c:824 #, c-format -msgid "%s: could not access file \"%s\": %s\n" -msgstr "%s: kunde inte komma Ã¥t filen \"%s\": %s\n" +msgid "could not access file \"%s\": %m" +msgstr "kunde inte komma Ã¥t filen \"%s\": %m" -#: initdb.c:788 +#: initdb.c:833 #, c-format -msgid "%s: file \"%s\" is not a regular file\n" -msgstr "%s: \"%s\" är inte en normal fil.\n" +msgid "file \"%s\" is not a regular file" +msgstr "filen \"%s\" är inte en normal fil" -#: initdb.c:933 +#: initdb.c:978 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "väljer mekanism för dynamiskt, delat minne ... " + +#: initdb.c:987 #, c-format msgid "selecting default max_connections ... " msgstr "sätter förvalt värde för max_connections ... " -#: initdb.c:963 +#: initdb.c:1018 #, c-format msgid "selecting default shared_buffers ... " msgstr "sätter förvalt värde för shared_buffers ... " -#: initdb.c:996 +#: initdb.c:1052 #, c-format -msgid "selecting dynamic shared memory implementation ... " -msgstr "väljer mekanism för dynamiskt, delat minne ... " +msgid "selecting default timezone ... " +msgstr "sätter förvalt värde för timezone ... " -#: initdb.c:1014 +#: initdb.c:1086 msgid "creating configuration files ... " msgstr "skapar konfigurationsfiler ... " -#: initdb.c:1146 initdb.c:1166 initdb.c:1253 initdb.c:1269 +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 #, c-format -msgid "%s: could not change permissions of \"%s\": %s\n" -msgstr "%s: kunde inte ändra rättigheter pÃ¥ \"%s\": %s\n" +msgid "could not change permissions of \"%s\": %m" +msgstr "kunde inte ändra rättigheter pÃ¥ \"%s\": %m" -#: initdb.c:1293 +#: initdb.c:1381 #, c-format msgid "running bootstrap script ... " msgstr "kör uppsättningsskript..." +#: initdb.c:1393 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "indatafil \"%s\" tillhör inte PostgreSQL %s" + # The expected string length of bki_file (for the first "%s") # with a standard directory "/usr/local/pgsql", is such that # the translated message string produces a reasonable output. # -#: initdb.c:1309 +#: initdb.c:1396 #, c-format -msgid "" -"%s: input file \"%s\" does not belong to PostgreSQL %s\n" -"Check your installation or specify the correct path using the option -L.\n" -msgstr "" -"%s: Indatafilen \"%s\" hör inte till PostgreSQL %s.\n" -"Kontrollera din installation eller ange korrekt sökväg med flaggan -L.\n" +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Kontrollera din installation eller ange korrekt sökväg med flaggan -L.\n" -#: initdb.c:1419 +#: initdb.c:1511 msgid "Enter new superuser password: " msgstr "Mata in ett nytt lösenord för superanvändaren: " -#: initdb.c:1420 +#: initdb.c:1512 msgid "Enter it again: " msgstr "Mata in det igen: " -#: initdb.c:1423 +#: initdb.c:1515 #, c-format msgid "Passwords didn't match.\n" msgstr "Lösenorden stämde inte överens.\n" -#: initdb.c:1449 +#: initdb.c:1541 #, c-format -msgid "%s: could not read password from file \"%s\": %s\n" -msgstr "%s: kunde inte läsa lösenord i filen \"%s\": %s\n" +msgid "could not read password from file \"%s\": %m" +msgstr "kunde inte läsa lösenord i filen \"%s\": %m" -#: initdb.c:1452 +#: initdb.c:1544 #, c-format -msgid "%s: password file \"%s\" is empty\n" -msgstr "%s: lösenordsfilen \"%s\" är tom\n" +msgid "password file \"%s\" is empty" +msgstr "lösenordsfilen \"%s\" är tom" -#: initdb.c:2027 +#: initdb.c:2107 #, c-format msgid "caught signal\n" msgstr "mottog signal\n" -#: initdb.c:2033 +#: initdb.c:2113 #, c-format msgid "could not write to child process: %s\n" msgstr "kunde inte skriva till barnprocess: %s\n" -#: initdb.c:2041 +#: initdb.c:2121 #, c-format msgid "ok\n" msgstr "ok\n" -#: initdb.c:2131 +#: initdb.c:2211 #, c-format -msgid "%s: setlocale() failed\n" -msgstr "%s: setlocale() misslyckades\n" +msgid "setlocale() failed" +msgstr "setlocale() misslyckades" -#: initdb.c:2149 +#: initdb.c:2232 #, c-format -msgid "%s: failed to restore old locale \"%s\"\n" -msgstr "%s: misslyckades att Ã¥terställa lokalsprÃ¥k \"%s\"\n" +msgid "failed to restore old locale \"%s\"" +msgstr "misslyckades med att Ã¥terställa gamla lokalen \"%s\"" -#: initdb.c:2159 +#: initdb.c:2241 #, c-format -msgid "%s: invalid locale name \"%s\"\n" -msgstr "%s: okänt lokalnamn \"%s\".\n" +msgid "invalid locale name \"%s\"" +msgstr "ogiltigt lokalnamn \"%s\"" -#: initdb.c:2171 +#: initdb.c:2252 #, c-format -msgid "%s: invalid locale settings; check LANG and LC_* environment variables\n" -msgstr "%s: ogiltigt sprÃ¥kval. Kontrollera miljövariablerna LANG, LC_*.\n" +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "ogiltig lokalinställning. Kontrollera miljövariablerna LANG och LC_*" -#: initdb.c:2199 +#: initdb.c:2279 #, c-format -msgid "%s: encoding mismatch\n" -msgstr "%s: Oförenliga teckenkodningar.\n" +msgid "encoding mismatch" +msgstr "teckenkodning matchar inte" -#: initdb.c:2201 +#: initdb.c:2281 #, c-format msgid "" "The encoding you selected (%s) and the encoding that the\n" @@ -444,13 +454,13 @@ msgid "" "Rerun %s and either do not specify an encoding explicitly,\n" "or choose a matching combination.\n" msgstr "" -"Teckenkodningen du har valt (%s) och kodningen svarande\n" -"mot lokalnamnet (%s), de passar inte ihop. Detta kan leda\n" -"till problem för funktioner som arbetar med strängar. Detta\n" -"undgÃ¥s genom att utföra %s igen och dÃ¥ lÃ¥ta bli bli att\n" -"sätta kodning, eller i annat fall att välja bättre teckensats.\n" +"Teckenkodningen du har valt (%s) och teckenkodningen som\n" +"valda lokalen använder (%s) passar inte ihop. Detta kommer leda\n" +"till problem för funktioner som arbetar med strängar.\n" +"Kör %s igen och lÃ¥t bli ange teckenkodning eller välj\n" +"en kombination som passar ihop.\n" -#: initdb.c:2273 +#: initdb.c:2353 #, c-format msgid "" "%s initializes a PostgreSQL database cluster.\n" @@ -459,54 +469,61 @@ msgstr "" "%s initierar ett databaskluster för PostgreSQL.\n" "\n" -#: initdb.c:2274 +#: initdb.c:2354 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: initdb.c:2275 +#: initdb.c:2355 #, c-format msgid " %s [OPTION]... [DATADIR]\n" msgstr " %s [FLAGGA]... [DATAKATALOG]\n" -#: initdb.c:2276 +#: initdb.c:2356 #, c-format msgid "" "\n" "Options:\n" -msgstr "\nFlaggor:\n" +msgstr "" +"\n" +"Flaggor:\n" -#: initdb.c:2277 +#: initdb.c:2357 #, c-format msgid " -A, --auth=METHOD default authentication method for local connections\n" msgstr " -A, --auth=METOD förvald autentiseringsmetod för alla förbindelser\n" -#: initdb.c:2278 +#: initdb.c:2358 #, c-format msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" msgstr " --auth-host=METOD autentiseringsmetod för TCP/IP-förbindelser\n" -#: initdb.c:2279 +#: initdb.c:2359 #, c-format msgid " --auth-local=METHOD default authentication method for local-socket connections\n" msgstr " --auth-local=METOD autentiseringsmetod för förbindelser via unix-uttag\n" -#: initdb.c:2280 +#: initdb.c:2360 #, c-format msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" msgstr " [-D, --pgdata=]DATAKATALOG läge för detta databaskluster\n" -#: initdb.c:2281 +#: initdb.c:2361 #, c-format msgid " -E, --encoding=ENCODING set default encoding for new databases\n" msgstr " -E, --encoding=KODNING sätter teckenkodning för nya databaser\n" -#: initdb.c:2282 +#: initdb.c:2362 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr " -g, --allow-group-access tillÃ¥t läs/kör för grupp pÃ¥ datakatalogen\n" + +#: initdb.c:2363 #, c-format msgid " --locale=LOCALE set default locale for new databases\n" msgstr " --locale=LOKAL sätter standardlokal för nya databaser\n" -#: initdb.c:2283 +#: initdb.c:2364 #, c-format msgid "" " --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" @@ -519,17 +536,17 @@ msgstr "" " sätter standardlokal i utvald kategori för\n" " nya databaser (förval hämtas ur omgivningen)\n" -#: initdb.c:2287 +#: initdb.c:2368 #, c-format msgid " --no-locale equivalent to --locale=C\n" msgstr " --no-locale samma som --locale=C\n" -#: initdb.c:2288 +#: initdb.c:2369 #, c-format msgid " --pwfile=FILE read password for the new superuser from file\n" msgstr " --pwfile=FIL läser lösenord för superanvändare frÃ¥n fil\n" -#: initdb.c:2289 +#: initdb.c:2370 #, c-format msgid "" " -T, --text-search-config=CFG\n" @@ -538,81 +555,90 @@ msgstr "" " -T, --text-search-config=CFG\n" " standardkonfiguration för textsökning\n" -#: initdb.c:2291 +#: initdb.c:2372 #, c-format msgid " -U, --username=NAME database superuser name\n" msgstr " -U, --username=NAMN namn pÃ¥ databasens superanvändare\n" -#: initdb.c:2292 +#: initdb.c:2373 #, c-format msgid " -W, --pwprompt prompt for a password for the new superuser\n" msgstr " -W, --pwprompt efterfrÃ¥ga lösenord för superanvändare\n" -#: initdb.c:2293 +#: initdb.c:2374 #, c-format msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" msgstr " -X, --waldir=WALDIR katalog för write-ahead-log (WAL)\n" -#: initdb.c:2294 +#: initdb.c:2375 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=STORLEK storlek pÃ¥ WAL-segment i megabyte\n" + +#: initdb.c:2376 #, c-format msgid "" "\n" "Less commonly used options:\n" -msgstr "\nMindre vanliga flaggor:\n" +msgstr "" +"\n" +"Mindre vanliga flaggor:\n" -#: initdb.c:2295 +#: initdb.c:2377 #, c-format msgid " -d, --debug generate lots of debugging output\n" msgstr " -d, --debug generera massor med debug-utskrifter\n" -#: initdb.c:2296 +#: initdb.c:2378 #, c-format msgid " -k, --data-checksums use data page checksums\n" msgstr " -k, --data-checksums använd checksummor pÃ¥ datablock\n" -#: initdb.c:2297 +#: initdb.c:2379 #, c-format msgid " -L DIRECTORY where to find the input files\n" msgstr " -L KATALOG katalog där indatafiler skall sökas\n" -#: initdb.c:2298 +#: initdb.c:2380 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean städa inte upp efter fel\n" -#: initdb.c:2299 +#: initdb.c:2381 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr " -N, --no-sync vänta inte pÃ¥ att ändingar säkert skrivits till disk\n" -#: initdb.c:2300 +#: initdb.c:2382 #, c-format msgid " -s, --show show internal settings\n" msgstr " -s, --show visa interna inställningar\n" -#: initdb.c:2301 +#: initdb.c:2383 #, c-format msgid " -S, --sync-only only sync data directory\n" msgstr " -S, --sync-only synkning endast av datakatalog\n" -#: initdb.c:2302 +#: initdb.c:2384 #, c-format msgid "" "\n" "Other options:\n" -msgstr "\nAndra flaggor:\n" +msgstr "" +"\n" +"Andra flaggor:\n" -#: initdb.c:2303 +#: initdb.c:2385 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: initdb.c:2304 +#: initdb.c:2386 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: initdb.c:2305 +#: initdb.c:2387 #, c-format msgid "" "\n" @@ -622,85 +648,72 @@ msgstr "" "\n" "Om datakatalogen inte anges sÃ¥ tas den frÃ¥n omgivningsvariabeln PGDATA.\n" -#: initdb.c:2307 +#: initdb.c:2389 #, c-format msgid "" "\n" -"Report bugs to .\n" -msgstr "" -"\n" -"Rapportera fel till .\n" +"Report bugs to .\n" +msgstr "\nRapportera fel till .\n" -#: initdb.c:2315 -msgid "" -"\n" -"WARNING: enabling \"trust\" authentication for local connections\n" -"You can change this by editing pg_hba.conf or using the option -A, or\n" -"--auth-local and --auth-host, the next time you run initdb.\n" -msgstr "" -"\n" -"VARNING: Autentiseringsmetod \"trust\" är aktiv för nÃ¥gon uppkoppling.\n" -"Du kan ändra detta genom att redigera \"pg_hba.conf\" eller genom att sätta\n" -"flaggor -A eller --auth-local och --auth-host nästa gÃ¥ng du kör initdb.\n" +#: initdb.c:2417 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "ogiltig autentiseringsmetod \"%s\" för anslutning av typen \"%s\"" -#: initdb.c:2337 +#: initdb.c:2433 #, c-format -msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" -msgstr "%s: Ogiltig autentiseringsmetod \"%s\" vid förbindelseslag \"%s\".\n" +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "du mÃ¥ste ange ett lösenord för superanvändaren för att kunna slÃ¥ pÃ¥ autentisering %s" -#: initdb.c:2353 +#: initdb.c:2460 #, c-format -msgid "%s: must specify a password for the superuser to enable %s authentication\n" -msgstr "" -"%s: Du mÃ¥ste ange ett lösenord för superanvändaren för att\n" -"kunna slÃ¥ pÃ¥ autentisering \"%s\".\n" +msgid "no data directory specified" +msgstr "ingen datakatalog angiven" -#: initdb.c:2381 +#: initdb.c:2462 #, c-format msgid "" -"%s: no data directory specified\n" "You must identify the directory where the data for this database system\n" "will reside. Do this with either the invocation option -D or the\n" "environment variable PGDATA.\n" msgstr "" -"%s: Ingen datakatalog angiven.\n" "Du mÃ¥ste uppge den katalog där data för detta databassystem\n" "skall lagras. Gör det antingen med flaggan -D eller genom att\n" "sätta omgivningsvariabeln PGDATA.\n" -#: initdb.c:2419 +#: initdb.c:2497 #, c-format msgid "" "The program \"postgres\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Programmet \"postgres\" behövs av %s men kunde inte hittas\n" "i samma katalog som \"%s\".\n" -"Kontrollera din installation.\n" +"Kontrollera din installation." -#: initdb.c:2426 +#: initdb.c:2502 #, c-format msgid "" "The program \"postgres\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Programmet \"postgres\" hittades av \"%s\",\n" "men det är inte byggt i samma version som %s.\n" -"Kontrollera din installation.\n" +"Kontrollera din installation." -#: initdb.c:2445 +#: initdb.c:2521 #, c-format -msgid "%s: input file location must be an absolute path\n" -msgstr "%s: plats för indatafiler mÃ¥ste vara en absolut sökväg.\n" +msgid "input file location must be an absolute path" +msgstr "plats för indatafiler mÃ¥ste vara en absolut sökväg" -#: initdb.c:2464 +#: initdb.c:2538 #, c-format msgid "The database cluster will be initialized with locale \"%s\".\n" msgstr "Databasklustret kommer att skapas med lokalnamn \"%s\".\n" -#: initdb.c:2467 +#: initdb.c:2541 #, c-format msgid "" "The database cluster will be initialized with locales\n" @@ -719,22 +732,22 @@ msgstr "" " NUMERIC: %s\n" " TIME: %s\n" -#: initdb.c:2491 +#: initdb.c:2565 #, c-format -msgid "%s: could not find suitable encoding for locale \"%s\"\n" -msgstr "%s: kunde inte välja en lämplig kodning för lokalnamn \"%s\".\n" +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "kunde inte välja en lämplig kodning för lokal \"%s\"" -#: initdb.c:2493 +#: initdb.c:2567 #, c-format msgid "Rerun %s with the -E option.\n" msgstr "Upprepa %s, men nu med flaggan -E.\n" -#: initdb.c:2494 initdb.c:3123 initdb.c:3144 +#: initdb.c:2568 initdb.c:3196 initdb.c:3217 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: initdb.c:2506 +#: initdb.c:2581 #, c-format msgid "" "Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" @@ -743,12 +756,12 @@ msgstr "" "Teckenkodning \"%s\", tagen ur lokalnamnet, är inte godtagbar för servern.\n" "I dess ställe sättes databasens förvalda teckenkodning till \"%s\".\n" -#: initdb.c:2514 +#: initdb.c:2586 #, c-format -msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" -msgstr "%s: Lokalnamn \"%s\" kräver otillgänglig teckenkodning \"%s\".\n" +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "lokalen \"%s\" kräver ej supportad teckenkodning \"%s\"" -#: initdb.c:2517 +#: initdb.c:2589 #, c-format msgid "" "Encoding \"%s\" is not allowed as a server-side encoding.\n" @@ -757,59 +770,59 @@ msgstr "" "Teckenkodning \"%s\" är inte godtagbar för servern.\n" "Upprepa %s med annat lokalnamn.\n" -#: initdb.c:2526 +#: initdb.c:2598 #, c-format msgid "The default database encoding has accordingly been set to \"%s\".\n" msgstr "Förvald teckenkodning för databaser är satt till \"%s\".\n" -#: initdb.c:2597 +#: initdb.c:2666 #, c-format msgid "%s: could not find suitable text search configuration for locale \"%s\"\n" msgstr "%s: kunde inte hitta en lämplig textsökningskonfiguration för lokalnamn \"%s\".\n" -#: initdb.c:2608 +#: initdb.c:2677 #, c-format msgid "%s: warning: suitable text search configuration for locale \"%s\" is unknown\n" msgstr "%s: Varning: Ingen lämplig textsökningskonfiguration för lokalnamn \"%s\".\n" -#: initdb.c:2613 +#: initdb.c:2682 #, c-format msgid "%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n" msgstr "" "%s: Varning: Uppgiven textsökningskonfiguration \"%s\" passar\n" "kanske inte till lokalnamn \"%s\".\n" -#: initdb.c:2618 +#: initdb.c:2687 #, c-format msgid "The default text search configuration will be set to \"%s\".\n" msgstr "Förvald textsökningskonfiguration för databaser är satt till \"%s\".\n" -#: initdb.c:2662 initdb.c:2748 +#: initdb.c:2731 initdb.c:2813 #, c-format msgid "creating directory %s ... " msgstr "skapar katalog %s ... " -#: initdb.c:2668 initdb.c:2754 initdb.c:2822 initdb.c:2878 +#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s: kunde inte skapa katalogen \"%s\": %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" -#: initdb.c:2680 initdb.c:2766 +#: initdb.c:2748 initdb.c:2831 #, c-format msgid "fixing permissions on existing directory %s ... " msgstr "sätter rättigheter pÃ¥ existerande katalog %s ... " -#: initdb.c:2686 initdb.c:2772 +#: initdb.c:2754 initdb.c:2837 #, c-format -msgid "%s: could not change permissions of directory \"%s\": %s\n" -msgstr "%s: kunde inte ändra rättigheter pÃ¥ katalogen \"%s\": %s\n" +msgid "could not change permissions of directory \"%s\": %m" +msgstr "kunde inte ändra rättigheter pÃ¥ katalogen \"%s\": %m" -#: initdb.c:2701 initdb.c:2787 +#: initdb.c:2768 initdb.c:2851 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s: katalogen \"%s\" existerar men är inte tom.\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "katalogen \"%s\" existerar men är inte tom" -#: initdb.c:2707 +#: initdb.c:2773 #, c-format msgid "" "If you want to create a new database system, either remove or empty\n" @@ -820,17 +833,17 @@ msgstr "" "eller töm katalogen \"%s\" eller kör %s\n" "med annat argument än \"%s\".\n" -#: initdb.c:2715 initdb.c:2800 initdb.c:3157 +#: initdb.c:2781 initdb.c:2863 initdb.c:3232 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: kunde inte komma Ã¥t katalogen \"%s\": %s\n" +msgid "could not access directory \"%s\": %m" +msgstr "kunde inte komma Ã¥t katalog \"%s\": %m" -#: initdb.c:2739 +#: initdb.c:2804 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" -msgstr "%s: WAL-katalogen mÃ¥ste vara en absolut sökväg.\n" +msgid "WAL directory location must be an absolute path" +msgstr "WAL-katalogen mÃ¥ste vara en absolut sökväg" -#: initdb.c:2793 +#: initdb.c:2856 #, c-format msgid "" "If you want to store the WAL there, either remove or empty the directory\n" @@ -839,27 +852,27 @@ msgstr "" "Om du vill spara WAL där, antingen radera eller töm\n" "katalogen \"%s\".\n" -#: initdb.c:2808 +#: initdb.c:2870 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s: kunde inte skapa symbolisk länk \"%s\": %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "kan inte skapa symbolisk länk \"%s\": %m" -#: initdb.c:2813 +#: initdb.c:2875 #, c-format -msgid "%s: symlinks are not supported on this platform" -msgstr "%s: symboliska länkar stöds inte pÃ¥ denna plattform" +msgid "symlinks are not supported on this platform" +msgstr "symboliska länkar stöds inte pÃ¥ denna plattform" -#: initdb.c:2837 +#: initdb.c:2899 #, c-format msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" msgstr "Den innehÃ¥ller en gömd fil, med inledande punkt i namnet; kanske är detta en monteringspunkt.\n" -#: initdb.c:2840 +#: initdb.c:2902 #, c-format msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" msgstr "Den innehÃ¥ller \"lost+found\"; kanske är detta en monteringspunkt.\n" -#: initdb.c:2843 +#: initdb.c:2905 #, c-format msgid "" "Using a mount point directly as the data directory is not recommended.\n" @@ -868,45 +881,55 @@ msgstr "" "Att använda en monteringspunkt som datakatalog rekommenderas inte.\n" "Skapa först en underkatalog under monteringspunkten.\n" -#: initdb.c:2863 +#: initdb.c:2931 #, c-format msgid "creating subdirectories ... " msgstr "Skapar underkataloger ... " -#: initdb.c:2910 +#: initdb.c:2977 msgid "performing post-bootstrap initialization ... " msgstr "utför initiering efter uppstättning..." -#: initdb.c:3067 +#: initdb.c:3134 #, c-format msgid "Running in debug mode.\n" msgstr "Kör i debug-läge.\n" -#: initdb.c:3071 +#: initdb.c:3138 #, c-format msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" msgstr "Kör i no-clean-läge. Misstag kommer inte städas bort.\n" -#: initdb.c:3142 +#: initdb.c:3215 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: initdb.c:3162 initdb.c:3228 +#: initdb.c:3236 initdb.c:3325 msgid "syncing data to disk ... " msgstr "synkar data till disk ... " -#: initdb.c:3171 +#: initdb.c:3245 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "lösenordsfrÃ¥ga och lösenordsfil kan inte anges samtidigt" + +#: initdb.c:3270 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "argumentet till --wal-segsize mÃ¥ste vara ett tal" + +#: initdb.c:3275 #, c-format -msgid "%s: password prompt and password file cannot be specified together\n" -msgstr "%s: lösenordsfrÃ¥ga och lösenordsfil kan inte anges samtidigt.\n" +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "argumentet till --wal-segsize mÃ¥ste vara en tvÃ¥potens mellan 1 och 1024" -#: initdb.c:3195 +#: initdb.c:3292 #, c-format -msgid "%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"\n" -msgstr "%s: superuser-namn \"%s\" tillÃ¥ts inte; rollnamn fÃ¥r inte börja pÃ¥ \"pg_\"\n" +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "superuser-namn \"%s\" tillÃ¥ts inte; rollnamn fÃ¥r inte börja pÃ¥ \"pg_\"" -#: initdb.c:3199 +#: initdb.c:3296 #, c-format msgid "" "The files belonging to this database system will be owned by user \"%s\".\n" @@ -917,17 +940,17 @@ msgstr "" "Denna användare mÃ¥ste ocksÃ¥ vara ägare av server-processen.\n" "\n" -#: initdb.c:3215 +#: initdb.c:3312 #, c-format msgid "Data page checksums are enabled.\n" msgstr "Checksummor för datablock är aktiva.\n" -#: initdb.c:3217 +#: initdb.c:3314 #, c-format msgid "Data page checksums are disabled.\n" msgstr "Checksummor för datablock är avstängda.\n" -#: initdb.c:3234 +#: initdb.c:3331 #, c-format msgid "" "\n" @@ -938,12 +961,26 @@ msgstr "" "Avstod frÃ¥n synkning mot lagringsmedium.\n" "Datakatalogen kan komma att fördärvas om operativsystemet störtar.\n" +#: initdb.c:3336 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "slÃ¥r pÃ¥ autentiseringsmetod \"trust\" för lokala anslutningar" + +#: initdb.c:3337 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Du kan ändra detta genom att redigera pg_hba.conf eller genom att sätta\n" +"flaggor -A eller --auth-local och --auth-host nästa gÃ¥ng du kör initdb.\n" + #. translator: This is a placeholder in a shell command. -#: initdb.c:3260 +#: initdb.c:3362 msgid "logfile" msgstr "loggfil" -#: initdb.c:3262 +#: initdb.c:3364 #, c-format msgid "" "\n" @@ -958,86 +995,161 @@ msgstr "" " %s\n" "\n" -#~ msgid "%s: could not to allocate SIDs: error code %lu\n" -#~ msgstr "%s: kunde inte tilldela SID: felkod %lu\n" +#~ msgid "user name lookup failure: %s" +#~ msgstr "misslyckad sökning efter användarnamn: %s" -#~ msgid "copying template1 to postgres ... " -#~ msgstr "Kopierar template1 till postgres ... " +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte stänga katalog \"%s\": %s\n" -#~ msgid "copying template1 to template0 ... " -#~ msgstr "Kopierar template1 till template0 ... " +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: Tar bort transaktionsloggskatalog \"%s\".\n" -#~ msgid "vacuuming database template1 ... " -#~ msgstr "Kör vacuum pÃ¥ databasen template1 ... " +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: Misslyckades med att ta bort katalog för transaktionslogg.\n" -#~ msgid "loading PL/pgSQL server-side language ... " -#~ msgstr "Aktiverar serversprÃ¥ket PL/pgSQL ... " +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: Tömmer innehÃ¥llet ur katalogen för transaktionsloggar \"%s\".\n" -#~ msgid "creating information schema ... " -#~ msgstr "Skapar informationsschema ... " +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: Misslyckades med att tömma katalogen för transaktionsloggar.\n" -#~ msgid "setting privileges on built-in objects ... " -#~ msgstr "Sätter rättigheter för inbyggda objekt ... " +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: Katalogen för transaktionsloggar \"%s\" ej borttagen pÃ¥ användares begäran.\n" -#~ msgid "creating dictionaries ... " -#~ msgstr "Skapar kataloger ... " +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "Skapar databasen template1 i %s/base/1 ... " -#~ msgid "creating conversions ... " -#~ msgstr "Skapar konverteringar ... " +#~ msgid "initializing pg_authid ... " +#~ msgstr "Initierar pg_authid ... " -#~ msgid "not supported on this platform\n" -#~ msgstr "stöds icke för denna systemplattform\n" +#~ msgid "setting password ... " +#~ msgstr "Sparar lösenord ... " -#~ msgid "Use the option \"--debug\" to see details.\n" -#~ msgstr "Nyttja flaggan \"--debug\" för fler detaljer.\n" +#~ msgid "initializing dependencies ... " +#~ msgstr "Initierar beroenden ... " -#~ msgid "No usable system locales were found.\n" -#~ msgstr "Inga tjänliga lokalnamn kunde uppdagas.\n" +#~ msgid "creating system views ... " +#~ msgstr "Skapar systemvyer ... " -#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" -#~ msgstr "%s: lokalnamnet innehÃ¥ller annat än ASCII, förkastas: \"%s\"\n" +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "Laddar systemobjektens beskrivningar ... " + +#~ msgid "creating collations ... " +#~ msgstr "Skapar sorteringsregler ... " #~ msgid "%s: locale name too long, skipped: \"%s\"\n" #~ msgstr "%s: lokalnamnet är alltför lÃ¥ngt, förkastas: \"%s\"\n" -#~ msgid "creating collations ... " -#~ msgstr "Skapar sorteringsregler ... " +#~ msgid "%s: locale name has non-ASCII characters, skipped: \"%s\"\n" +#~ msgstr "%s: lokalnamnet innehÃ¥ller annat än ASCII, förkastas: \"%s\"\n" -#~ msgid "loading system objects' descriptions ... " -#~ msgstr "Laddar systemobjektens beskrivningar ... " +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Inga tjänliga lokalnamn kunde uppdagas.\n" -#~ msgid "creating system views ... " -#~ msgstr "Skapar systemvyer ... " +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Nyttja flaggan \"--debug\" för fler detaljer.\n" -#~ msgid "initializing dependencies ... " -#~ msgstr "Initierar beroenden ... " +#~ msgid "not supported on this platform\n" +#~ msgstr "stöds icke för denna systemplattform\n" -#~ msgid "setting password ... " -#~ msgstr "Sparar lösenord ... " +#~ msgid "creating conversions ... " +#~ msgstr "Skapar konverteringar ... " -#~ msgid "initializing pg_authid ... " -#~ msgstr "Initierar pg_authid ... " +#~ msgid "creating dictionaries ... " +#~ msgstr "Skapar kataloger ... " -#~ msgid "creating template1 database in %s/base/1 ... " -#~ msgstr "Skapar databasen template1 i %s/base/1 ... " +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "Sätter rättigheter för inbyggda objekt ... " -#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" -#~ msgstr "%s: Katalogen för transaktionsloggar \"%s\" ej borttagen pÃ¥ användares begäran.\n" +#~ msgid "creating information schema ... " +#~ msgstr "Skapar informationsschema ... " -#~ msgid "%s: failed to remove contents of transaction log directory\n" -#~ msgstr "%s: Misslyckades med att tömma katalogen för transaktionsloggar.\n" +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "Aktiverar serversprÃ¥ket PL/pgSQL ... " -#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" -#~ msgstr "%s: Tömmer innehÃ¥llet ur katalogen för transaktionsloggar \"%s\".\n" +#~ msgid "vacuuming database template1 ... " +#~ msgstr "Kör vacuum pÃ¥ databasen template1 ... " -#~ msgid "%s: failed to remove transaction log directory\n" -#~ msgstr "%s: Misslyckades med att ta bort katalog för transaktionslogg.\n" +#~ msgid "copying template1 to template0 ... " +#~ msgstr "Kopierar template1 till template0 ... " -#~ msgid "%s: removing transaction log directory \"%s\"\n" -#~ msgstr "%s: Tar bort transaktionsloggskatalog \"%s\".\n" +#~ msgid "copying template1 to postgres ... " +#~ msgstr "Kopierar template1 till postgres ... " -#~ msgid "%s: could not close directory \"%s\": %s\n" -#~ msgstr "%s: kunde inte stänga katalog \"%s\": %s\n" +#~ msgid "%s: could not to allocate SIDs: error code %lu\n" +#~ msgstr "%s: kunde inte tilldela SID: felkod %lu\n" -#~ msgid "user name lookup failure: %s" -#~ msgstr "misslyckad sökning efter användarnamn: %s" +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: symlänkar stöds inte pÃ¥ denna plattform\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa symbolisk länk \"%s\": %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte komma Ã¥t katalogen \"%s\": %s\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa katalogen \"%s\": %s\n" + +#~ msgid "%s: invalid locale name \"%s\"\n" +#~ msgstr "%s: okänt lokalnamn \"%s\".\n" + +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s: misslyckades att Ã¥terställa lokalsprÃ¥k \"%s\"\n" + +#~ msgid "%s: could not access file \"%s\": %s\n" +#~ msgstr "%s: kunde inte komma Ã¥t filen \"%s\": %s\n" + +#~ msgid "%s: file \"%s\" does not exist\n" +#~ msgstr "%s: Filen \"%s\" existerar inte.\n" + +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s: kunde inte utföra kommandot \"%s\": %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: kunde inte skriva fil \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\" for writing: %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\" för skrivning: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: slut pÃ¥ minne\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "barnprocess terminerades av signal %s" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "kunde inte ta status pÃ¥ fil eller katalog \"%s\": %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: kunde inte döpa om fil \"%s\" till \"%s\": %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: kunde inte utföra fsync pÃ¥ filen \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: kunde ta status pÃ¥ filen \"%s\": %s\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" diff --git a/src/bin/initdb/po/tr.po b/src/bin/initdb/po/tr.po new file mode 100644 index 00000000000..1f81079d686 --- /dev/null +++ b/src/bin/initdb/po/tr.po @@ -0,0 +1,1159 @@ +# translation of initdb.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2006, 2007. +# Nicolai Tufar , 2004, 2005, 2006, 2007. +# Abdullah GÜLNER , 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: initdb-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:47+0000\n" +"PO-Revision-Date: 2019-05-27 11:46+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: ../postgresql-8.0.3/src\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "geçerli dizin tespit edilemedi: %m" + +#: ../../common/exec.c:157 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "geçersiz ikili (binary) \"%s\"" + +#: ../../common/exec.c:207 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili (binary) dosyası okunamadı" + +#: ../../common/exec.c:215 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" çalıştırmak için bulunamadı" + +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %m" + +#: ../../common/exec.c:288 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" okuma hatası: %m" + +#: ../../common/exec.c:541 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose baÅŸarısız oldu: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: initdb.c:339 +#, c-format +msgid "out of memory" +msgstr "yetersiz bellek" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" dosyası durumlanamadı: %m" + +#: ../../common/file_utils.c:160 ../../common/pgfnames.c:48 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" dizini açılamıyor: %m" + +#: ../../common/file_utils.c:194 ../../common/pgfnames.c:69 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" dosyası fsync hatası: %m" + +#: ../../common/file_utils.c:377 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" -- \"%s\" ad deÄŸiÅŸtirme hatası: %m" + +#: ../../common/pgfnames.c:74 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" dizini kapatılamadı: %m" + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "bu platformda kısıtlı andaç (restricted token) oluÅŸturulamıyor" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "process token açma baÅŸarısız: hata kodu %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDler ayrılamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:110 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "kısıtlı andaç (restricted token) oluÅŸturulamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:131 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" komutu için iÅŸlem (process) baÅŸlatılamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:169 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kısıtlı andaç (restricted token) ile tekrar çalıştırılamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:185 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "alt-iÅŸlemden çıkış kodu alınamadı: hata kodu %lu" + +#: ../../common/rmtree.c:79 +#, c-format +msgid "could not stat file or directory \"%s\": %m" +msgstr "\"%s\" dosya ya da dizininin durumu görüntülenemedi (stat): %m" + +#: ../../common/rmtree.c:101 ../../common/rmtree.c:113 +#, c-format +msgid "could not remove file or directory \"%s\": %m" +msgstr "\"%s\" dosyası ya da dizini silinemedi: %m" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "geçerli kullanıcı ID si bulunamadı %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "kullanıcı mevcut deÄŸil" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "kullanıcı adı arama baÅŸarısız: hata kodu %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "komut çalıştırılabilir deÄŸil" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "komut bulunamadı" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "alt süreç %d çıkış koduyla sonuçlandırılmıştır" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "alt süreç 0x%X exception tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "alt süreç %d sinyali tarafından sonlandırılmıştır: %s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "alt süreç %d bilinmeyen durumu ile sonlandırılmıştır" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "\"%s\" için junction ayarlanamadı: %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "\"%s\" için junction bulunamadı: %s\n" + +#: initdb.c:495 initdb.c:1534 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" dosyası, okunmak için açılamadı: %m" + +#: initdb.c:550 initdb.c:858 initdb.c:884 +#, c-format +msgid "could not open file \"%s\" for writing: %m" +msgstr "\"%s\" dosyası, yazmak için açılamadı: %m" + +#: initdb.c:557 initdb.c:564 initdb.c:864 initdb.c:889 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" dosyasına yazma hatası: %m" + +#: initdb.c:582 +#, c-format +msgid "could not execute command \"%s\": %m" +msgstr "\"%s\" komutu yürütülemedi: %m" + +#: initdb.c:600 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "\"%s\" veri dizini siliniyor" + +#: initdb.c:602 +#, c-format +msgid "failed to remove data directory" +msgstr "veri dizini silme baÅŸarısız" + +#: initdb.c:606 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "\"%s\" veri dizininin içindekiler siliniyor" + +#: initdb.c:609 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "veri dizininin içindekileri silme iÅŸlemi baÅŸarısız" + +#: initdb.c:614 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "\"%s\" WAL dizini siliniyor" + +#: initdb.c:616 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL dizini silme baÅŸarısız" + +#: initdb.c:620 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "\"%s\" WAL dizininin içindekiler siliniyor" + +#: initdb.c:622 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL dizininin içeriÄŸini silme iÅŸlemi baÅŸarısız" + +#: initdb.c:629 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "\"%s\" veri dizini kullanıcının isteÄŸi üzerine silinmedi" + +#: initdb.c:633 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "\"%s\" WAL dizini kullanıcının isteÄŸi üzerine silinmedi" + +#: initdb.c:651 +#, c-format +msgid "cannot be run as root" +msgstr "root kullanıcısıyla çalıştırılamaz" + +#: initdb.c:653 +#, c-format +msgid "" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"Lütfen (örneÄŸin \"su\" kullanarak ) sunucu sürecinin sahibi olacak\n" +"(ayrıcalıksız) bir kullanıcıyla giriÅŸ yapın.\n" + +#: initdb.c:686 +#, c-format +msgid "\"%s\" is not a valid server encoding name" +msgstr "\"%s\" geçerli bir sunucu dil kodlaması adı deÄŸil" + +#: initdb.c:817 +#, c-format +msgid "file \"%s\" does not exist" +msgstr "\"%s\" dosyası mevcut deÄŸil" + +#: initdb.c:819 initdb.c:826 initdb.c:835 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Bu durum, bozulmus bir kurulumunuz olduÄŸu ya da\n" +"-L parametresi ile yanlış dizin belirttiÄŸiniz anlamına gelir.\n" + +#: initdb.c:824 +#, c-format +msgid "could not access file \"%s\": %m" +msgstr "\"%s\" dosyası eriÅŸim hatası: %m" + +#: initdb.c:833 +#, c-format +msgid "file \"%s\" is not a regular file" +msgstr "\"%s\" düzgün bir dosya deÄŸildir" + +#: initdb.c:978 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "dinamik paylaşılan bellek (shared memory) uygulaması seçimi ... " + +#: initdb.c:987 +#, c-format +msgid "selecting default max_connections ... " +msgstr "ön tanımlı max_connections seçiliyor ... " + +#: initdb.c:1018 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "öntanımlı shared_buffers deÄŸeri seçiliyor ... " + +#: initdb.c:1052 +#, c-format +msgid "selecting default timezone ... " +msgstr "ön tanımlı saat dilimi (timezone) seçiliyor ... " + +#: initdb.c:1086 +msgid "creating configuration files ... " +msgstr "yapılandırma dosyaları yaratılıyor ... " + +#: initdb.c:1239 initdb.c:1258 initdb.c:1344 initdb.c:1359 +#, c-format +msgid "could not change permissions of \"%s\": %m" +msgstr "\"%s\" için eriÅŸim hakları deÄŸiÅŸtirilemdi: %m" + +#: initdb.c:1381 +#, c-format +msgid "running bootstrap script ... " +msgstr "önyükleme komut dosyası çalıştırılıyor ..." + +#: initdb.c:1393 +#, c-format +msgid "input file \"%s\" does not belong to PostgreSQL %s" +msgstr "\"%s\" girdi dosyası PostgreSQL'e ait deÄŸil %s" + +#: initdb.c:1396 +#, c-format +msgid "Check your installation or specify the correct path using the option -L.\n" +msgstr "Kurulumunuzu kontrol edin ya da -L seçeneÄŸi ile doÄŸru dizini belirtin.\n" + +#: initdb.c:1511 +msgid "Enter new superuser password: " +msgstr "Yeni superuser parolasını giriniz: " + +#: initdb.c:1512 +msgid "Enter it again: " +msgstr "Bir kez daha giriniz: " + +#: initdb.c:1515 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Parolalar uyuÅŸmadı.\n" + +#: initdb.c:1541 +#, c-format +msgid "could not read password from file \"%s\": %m" +msgstr "\"%s\" dosyasından parola okunamadı: %m" + +#: initdb.c:1544 +#, c-format +msgid "password file \"%s\" is empty" +msgstr "\"%s\" parola dosyası boÅŸ" + +#: initdb.c:2107 +#, c-format +msgid "caught signal\n" +msgstr "sinyal yakalandı\n" + +#: initdb.c:2113 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "alt (child) sürece yazılamadı: %s\n" + +#: initdb.c:2121 +#, c-format +msgid "ok\n" +msgstr "tamam\n" + +#: initdb.c:2211 +#, c-format +msgid "setlocale() failed" +msgstr "setlocale() baÅŸarısız" + +#: initdb.c:2232 +#, c-format +msgid "failed to restore old locale \"%s\"" +msgstr "Eski \"%s\" yerel ayarlarını (locale) geri yükleme baÅŸarısız oldu" + +#: initdb.c:2241 +#, c-format +msgid "invalid locale name \"%s\"" +msgstr "geçersiz yerel ayar (locale) adı \"%s\"" + +#: initdb.c:2252 +#, c-format +msgid "invalid locale settings; check LANG and LC_* environment variables" +msgstr "geçersiz yerel ayarlar; LANG ve LC_ * ortam deÄŸiÅŸkenlerini kontrol edin" + +#: initdb.c:2279 +#, c-format +msgid "encoding mismatch" +msgstr "dil kodlaması uyuÅŸmazlığı" + +#: initdb.c:2281 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"SeçtiÄŸiniz (%s) dil kodlaması ve seçilen yerelin kullandığı dil \n" +"kodlaması (%s) uyuÅŸmamaktadır. Bu durum, çeÅŸitli metin iÅŸleme \n" +" fonksiyonlarının yanlış çalışmasına neden olabilir. Bu durumu \n" +" düzeltebilmek için %s komutunu yeniden çalıştırın ve de ya kodlama \n" +" belirtmeyin ya da eÅŸleÅŸtirilebilir bir kodlama seçin.\n" + +#: initdb.c:2353 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%sbir PostgreSQL Veritabanı kümesini ilklendirir.\n" +"\n" + +#: initdb.c:2354 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: initdb.c:2355 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [SEÇENEK]... [DATADIR]\n" + +#: initdb.c:2356 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: initdb.c:2357 +#, c-format +msgid " -A, --auth=METHOD default authentication method for local connections\n" +msgstr " -A, --auth=METHOD yerel baÄŸlantılar için ön tanımlı kimlik doÄŸrulama yöntemi\n" + +#: initdb.c:2358 +#, c-format +msgid " --auth-host=METHOD default authentication method for local TCP/IP connections\n" +msgstr " --auth-host=METHOD yerel TCP/IP baÄŸlantıları için ön tanımlı kimlik doÄŸrulama yöntemi\n" + +#: initdb.c:2359 +#, c-format +msgid " --auth-local=METHOD default authentication method for local-socket connections\n" +msgstr " --auth-local=METHOD yerel soket baÄŸlantıları için ön tanımlı kimlik doÄŸrulama yöntemi\n" + +#: initdb.c:2360 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr "[-D, --pgdata=]DATADIR bu veritabanı kümesi için yer\n" + +#: initdb.c:2361 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr " -E, --encoding=ENCODING yeni veritabanları için öntanımlı dil kodlamasını ayarlar\n" + +#: initdb.c:2362 +#, c-format +msgid " -g, --allow-group-access allow group read/execute on data directory\n" +msgstr " -g, --allow-group-access veri dizininde grup eriÅŸimine (okuma/yürütme) izin ver\n" + +#: initdb.c:2363 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr " --locale=LOCALE yeni veritabanı için öntanımlı yerel\n" + +#: initdb.c:2364 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" yeni veritabanları için ilgili kategorideki öntanımlı yerel bilgisini\n" +" çevre deÄŸiÅŸkenlerinden al\n" + +#: initdb.c:2368 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale --locale=C'ye eÅŸdeÄŸer\n" + +#: initdb.c:2369 +#, c-format +msgid " --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=DOSYA yeni superuser için parolayı dosyadan oku\n" + +#: initdb.c:2370 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\n" +" öntanımlı metin arama yapılandırması\n" + +#: initdb.c:2372 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NAME veritabanı superuser kullanıcısı adı\n" + +#: initdb.c:2373 +#, c-format +msgid " -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt yeni superuser için parola sorar\n" + +#: initdb.c:2374 +#, c-format +msgid " -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " -X, --waldir=WALDIR transaction log dizininin yeri\n" + +#: initdb.c:2375 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WAL segmentlerinin boyutu, megabayt olarak\n" + +#: initdb.c:2376 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Daha az kullanılan seçenekler:\n" + +#: initdb.c:2377 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr " -d, --debug bol miktarda debug çıktısı üretir\n" + +#: initdb.c:2378 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums veri sayfası (data page) doÄŸrulamasını kullan\n" + +#: initdb.c:2379 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY girdi dosyalarının nerede bulunacağını belirtir\n" + +#: initdb.c:2380 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean hatalardan sonra temizlik yapma\n" + +#: initdb.c:2381 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync deÄŸiÅŸikliklerin diske yazılmasını bekleme\n" + +#: initdb.c:2382 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show dahili ayarları gösterir\n" + +#: initdb.c:2383 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only sadece veri dizinini sync et\n" + +#: initdb.c:2384 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"DiÄŸer seçenekler:\n" + +#: initdb.c:2385 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini gösterir ve sonra çıkar\n" + +#: initdb.c:2386 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı gösterir ve sonra çıkar\n" + +#: initdb.c:2387 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"EÄŸer veri dizini belirtilmezse, PGDATA çevresel deÄŸiÅŸkeni kullanılacaktır\n" + +#: initdb.c:2389 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: initdb.c:2417 +#, c-format +msgid "invalid authentication method \"%s\" for \"%s\" connections" +msgstr "\"%2$s\"baÄŸlantıları için geçersiz kimlik doÄŸrulama yöntemi \"%1$s\"" + +#: initdb.c:2433 +#, c-format +msgid "must specify a password for the superuser to enable %s authentication" +msgstr "%s kimlik doÄŸrulamasını etkinleÅŸtirmek için superuser'a parola atamanız gerekmektedir." + +#: initdb.c:2460 +#, c-format +msgid "no data directory specified" +msgstr "hiçbir veri dizini belirtilmedi" + +#: initdb.c:2462 +#, c-format +msgid "" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"Bu veritabanı sistemi için verinin hangi dizinde duracağını belirtmeniz\n" +"gerekmektedir. Bunu ya -D komut satırı seçeneÄŸi ile ya da \n" +"PGDATA çevresel deÄŸiÅŸkeni ile yapabilirsiniz.\n" + +#: initdb.c:2497 +#, c-format +msgid "" +"The program \"postgres\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"%s, \"postgres\" programına gereksinim duymaktadır, ancak bu program \"%s\"\n" +"ile aynı dizinde bulunamadı.\n" +"Kurulumunuzu kontrol ediniz." + +#: initdb.c:2502 +#, c-format +msgid "" +"The program \"postgres\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"postgres\" programı \"%s\" tarafından bulundu; ancak bu program\n" +"%s ile aynı sürüm numarasına sahip deÄŸil.\n" +"Kurulumunuzu kontrol ediniz." + +#: initdb.c:2521 +#, c-format +msgid "input file location must be an absolute path" +msgstr "girdi dosyasının yeri mutlak bir yol olarak verilmeli" + +#: initdb.c:2538 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "Veritabanı kümesi \"%s\" yerel ayarları ile oluÅŸturulacak.\n" + +#: initdb.c:2541 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"Veritabanı kümesi aÅŸağıdaki yerellerle ilklendirilecek:\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2565 +#, c-format +msgid "could not find suitable encoding for locale \"%s\"" +msgstr "\"%s\" yerel ayarları için uygun dil kodlaması bulunamadı" + +#: initdb.c:2567 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "%s komutunu -E seçeneÄŸi ile yeniden çalıştırın.\n" + +#: initdb.c:2568 initdb.c:3196 initdb.c:3217 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Ayrıntılı bilgi için \"%s --help\" komutunu deneyebilirsiniz.\n" + +#: initdb.c:2581 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"\"%s\" dil kodlaması sunucu tarafında izin verilen bir dil kodlaması deÄŸildir\n" +"Bunun yerine, öntanımlı veritabanı dil kodlaması \"%s\" olacaktır.\n" + +#: initdb.c:2586 +#, c-format +msgid "locale \"%s\" requires unsupported encoding \"%s\"" +msgstr "\"%s\" yereli desteklenmeyen \"%s\" dil kodlamasını gerektirir" + +#: initdb.c:2589 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"\"%s\" dil kodlaması sunucu tarafında izin verilen bir dil kodlaması deÄŸildir\n" +" %s deÄŸiÅŸik bir yerel ayar (locale) ile tekrar çalıştırılmalı.\n" + +#: initdb.c:2598 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "Öntanımlı veritabanı dil kodlaması buna göre \"%s\" olarak ayarlandı.\n" + +#: initdb.c:2666 +#, c-format +msgid "%s: could not find suitable text search configuration for locale \"%s\"\n" +msgstr "%s: \"%s\" yereli için uygun metin arama yapılandırması bulunamadı\n" + +#: initdb.c:2677 +#, c-format +msgid "%s: warning: suitable text search configuration for locale \"%s\" is unknown\n" +msgstr "%s: uyarı: \"%s\" yereli için uygun metin arama yapılandırması bilinmiyor.\n" + +#: initdb.c:2682 +#, c-format +msgid "%s: warning: specified text search configuration \"%s\" might not match locale \"%s\"\n" +msgstr "%s: uyarı: belirtilen metin arama yapılandırması \"%s\", \"%s\" yereli ile eÅŸleÅŸmeyebilir\n" + +#: initdb.c:2687 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Öntanımlı metin arama yapılandırması \"%s\" olarak ayarlanacak.\n" + +#: initdb.c:2731 initdb.c:2813 +#, c-format +msgid "creating directory %s ... " +msgstr "%s dizini yaratılıyor ... " + +#: initdb.c:2737 initdb.c:2819 initdb.c:2884 initdb.c:2946 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" dizini oluÅŸturulamadı: %m" + +#: initdb.c:2748 initdb.c:2831 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "mevcut %s dizininin izinleri düzeltiliyor ... " + +#: initdb.c:2754 initdb.c:2837 +#, c-format +msgid "could not change permissions of directory \"%s\": %m" +msgstr "\"%s\" dizininin eriÅŸim hakları deÄŸiÅŸtirilemedi: %m" + +#: initdb.c:2768 initdb.c:2851 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "\"%s\" dizini mevcut, ama boÅŸ deÄŸil" + +#: initdb.c:2773 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Yeni bir veritabanı sistemi yaratmak istiyorsanız, ya \"%s\" dizinini \n" +"kaldırın, ya boÅŸaltın ya da ya da %s 'i \n" +"\"%s\" argümanından baÅŸka bir argüman ile çalıştırın.\n" + +#: initdb.c:2781 initdb.c:2863 initdb.c:3232 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" dizine eriÅŸim hatası: %m" + +#: initdb.c:2804 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL dizininin yeri mutlak bir yol olarak verilmeli" + +#: initdb.c:2856 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"EÄŸer transaction kayıt dosyasını saklamak istiyorsanız, \n" +"\"%s\" dizinini kaldırın ya da boÅŸaltın\n" + +#: initdb.c:2870 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" oluÅŸturma hatası: %m" + +#: initdb.c:2875 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "bu platformda sembolik baÄŸlantı (symlink) desteklenmemektedir" + +#: initdb.c:2899 +#, c-format +msgid "It contains a dot-prefixed/invisible file, perhaps due to it being a mount point.\n" +msgstr " noktayla baÅŸlayan/gizli dosya içeriyor, muhtemelen bu bir baÄŸlanma noktası (mount point) .\n" + +#: initdb.c:2902 +#, c-format +msgid "It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "" +"lost+found klasörü içeriyor, muhtemelen bu bir baÄŸlanma noktası (mount point) .\n" +"\n" + +#: initdb.c:2905 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Bir baÄŸlama noktasının doÄŸrudan veri dizini olarak kullanılması önerilmez.\n" +"BaÄŸlama noktası altında bir alt dizin oluÅŸturun.\n" + +#: initdb.c:2931 +#, c-format +msgid "creating subdirectories ... " +msgstr "alt dizinler oluÅŸturuluyor ... " + +#: initdb.c:2977 +msgid "performing post-bootstrap initialization ... " +msgstr "önyükleme sonrası baÅŸlatmayı gerçekleÅŸtirme ..." + +#: initdb.c:3134 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Debug modunda çalışıyor.\n" + +#: initdb.c:3138 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "noclean modunda çalışıyor. Hatalar temizlenmeyecektir.\n" + +#: initdb.c:3215 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı girdisi var (ilki \"%s\")" + +#: initdb.c:3236 initdb.c:3325 +msgid "syncing data to disk ... " +msgstr "veriyi diske senkronize etme ..." + +#: initdb.c:3245 +#, c-format +msgid "password prompt and password file cannot be specified together" +msgstr "parola istemi (prompt) ve parola dosyası birlikte belirtilemez" + +#: initdb.c:3270 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsize'ın argümanı bir sayı olmalıdır" + +#: initdb.c:3275 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsize'ın argümanı 2'nin 1 ve 1024 arasındaki bir üssü olmalıdır" + +#: initdb.c:3292 +#, c-format +msgid "superuser name \"%s\" is disallowed; role names cannot begin with \"pg_\"" +msgstr "superuser adı \"%s\"e izin verilmiyor; rol adları \"pg_\" ile baÅŸlayamaz" + +#: initdb.c:3296 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Bu veritabanı sistemine ait olan dosyaların sahibi \"%s\" kullanıcısı olacaktır.\n" +"Bu kullanıcı aynı zamanda sunucu sürecinin de sahibi olmalıdır.\n" +"\n" + +#: initdb.c:3312 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Veri sayfası (data page) doÄŸrulama etkinleÅŸtirilmiÅŸtir.\n" + +#: initdb.c:3314 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Veri sayfası (data page) doÄŸrulama devre dışı bırakılmıştır.\n" + +#: initdb.c:3331 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Diske senkronizasyon atlandı.\n" +"İşletim sistemi çökerse veri dizini bozulabilir.\n" + +#: initdb.c:3336 +#, c-format +msgid "enabling \"trust\" authentication for local connections" +msgstr "yerel baÄŸlantıları için \"trust\" kimlik doÄŸrulaması etkinleÅŸtiriliyor" + +#: initdb.c:3337 +#, c-format +msgid "" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"Bunu, pg_hba.conf dosyasını düzenleyerek ya da initdb'yi yeniden çalıştırdığınızda\n" +" -A parametresi ile veya --auth-local ve --auth-host ile deÄŸiÅŸtirebilirsiniz..\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3362 +msgid "logfile" +msgstr "logfile" + +#: initdb.c:3364 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"İşlem baÅŸarılı. Veritabanı sunucusunu aÅŸağıdaki gibi baÅŸlatabilirsiniz:\n" +"\n" +" %s\n" +"\n" +"\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" + +#~ msgid "%s: unrecognized authentication method \"%s\"\n" +#~ msgstr "%s: bilinmeyen yetkilendirme yöntemi\"%s\".\n" + +#~ msgid "copying template1 to postgres ... " +#~ msgstr "template1, postgres'e kopyalanıyor ... " + +#~ msgid "copying template1 to template0 ... " +#~ msgstr "template1 template0'a kopyalanıyor ... " + +#~ msgid "vacuuming database template1 ... " +#~ msgstr "template1 veritabanı vakumlanıyor ... " + +#~ msgid "loading PL/pgSQL server-side language ... " +#~ msgstr "PL/pgSQL sunucu tarafı dili yükleniyor ... " + +#~ msgid "creating information schema ... " +#~ msgstr "information schema yaratılıyor ... " + +#~ msgid "setting privileges on built-in objects ... " +#~ msgstr "gömülü nesnelerdeki izinler ayarlanıyor ... " + +#~ msgid "creating dictionaries ... " +#~ msgstr "sözlükler oluÅŸturuluyor ... " + +#~ msgid "creating conversions ... " +#~ msgstr "dönüşümler yükleniyor ... " + +#~ msgid "not supported on this platform\n" +#~ msgstr "bu platformda desteklenmiyor\n" + +#~ msgid "Use the option \"--debug\" to see details.\n" +#~ msgstr "Ayrıntıları görmek için \"--debug\" seçeneÄŸini kullanınız. \n" + +#~ msgid "No usable system locales were found.\n" +#~ msgstr "Kullanılabilir sistem yerelleri bulunamadı. \n" + +#~ msgid "%s: locale name has non-ASCII characters, skipped: %s\n" +#~ msgstr "%s:yerel adı ASCII olmayan karakterler içeriyor, atlanan: %s\n" + +#~ msgid "%s: locale name too long, skipped: %s\n" +#~ msgstr "%s:yerel adı çok uzun,: %s atlandı\n" + +#~ msgid "creating collations ... " +#~ msgstr "dönüşümler yükleniyor ..." + +#~ msgid "loading system objects' descriptions ... " +#~ msgstr "sistem nesnelerinin açıklamaları yükleniyor ... " + +#~ msgid "creating system views ... " +#~ msgstr "sistem viewları yaratılıyor ... " + +#~ msgid "initializing dependencies ... " +#~ msgstr "baÄŸlılıklar ilklendiriliyor ... " + +#~ msgid "setting password ... " +#~ msgstr "ÅŸifre ayarlanıyor ... " + +#~ msgid "initializing pg_authid ... " +#~ msgstr "pg_authid ilklendiriliyor ... " + +#~ msgid "creating template1 database in %s/base/1 ... " +#~ msgstr "%s/base/1 içinde template1 veritabanı yaratılıyor." + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s: geçerli kullanıcı adı alınamadı: %s\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s: geçerli kullanıcı hakkında bilgi alınamadı: %s\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: \"%s\" transaction log dizini kullanıcının isteÄŸi üzerine silinmedi\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: transaction log dizininin içindekilerinin silme iÅŸlemini baÅŸarısız\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: transaction log dizininin içindekileri siliniyor \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: transaction log dizini silme baÅŸarısız\n" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: transaction log dizini siliniyor \"%s\"\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: bu platformda sembolik baÄŸlantı (symlink) desteklenmemektedir\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: symbolic link \"%s\" oluÅŸturma hatası: %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizine eriÅŸim hatası: %s\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini oluÅŸturma baÅŸarısız: %s\n" + +#~ msgid "%s: invalid locale name \"%s\"\n" +#~ msgstr "%s: geçersiz yerel ayar (locale) adı \"%s\"\n" + +#~ msgid "%s: failed to restore old locale \"%s\"\n" +#~ msgstr "%s: \"%s\" eski yerel ayar (locale) dosyasının geri yüklenmesi baÅŸarısız\n" + +#~ msgid "%s: could not access file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasına eriÅŸim hatası: %s\n" + +#~ msgid "%s: file \"%s\" does not exist\n" +#~ msgstr "%s: \"%s\" dosyası mevcut deÄŸil\n" + +#~ msgid "%s: could not execute command \"%s\": %s\n" +#~ msgstr "%s: \"%s\" komutu yürütme baÅŸlatma hatası: %s\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasına yazılamadı: %s\n" + +#~ msgid "%s: could not open file \"%s\" for writing: %s\n" +#~ msgstr "%s: \"%s\" dosyası, yazılmak için açılamadı: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: \"%s\" dosyası, okunmak için açılamadı: %s\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: yetersiz bellek\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "alt süreç %s sinyali tarafından sonlandırılmıştır" + +#~ msgid "could not stat file or directory \"%s\": %s\n" +#~ msgstr "\"%s\" dosya ya da dizini bulunamadı: %s\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: process token açma baÅŸarısız: hata kodu %lu\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini okuma baÅŸarısız: %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini açma baÅŸarısız: %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "\"%s\": \"%s\" dosyasının adı \"%s\" olarak deÄŸiÅŸtirilemedi: %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası fsync iÅŸlemi baÅŸarısız: %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası açılamadı: %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini okunamadı: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini açılamadı: %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasının durumu görüntülenemedi (stat): %s\n" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "\"%s\" sembolik linki okunamadı" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %s" diff --git a/src/bin/initdb/po/vi.po b/src/bin/initdb/po/vi.po new file mode 100644 index 00000000000..0a9875fbc2c --- /dev/null +++ b/src/bin/initdb/po/vi.po @@ -0,0 +1,1044 @@ +# LANGUAGE message translation file for initdb +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the initdb (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: initdb (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:17+0000\n" +"PO-Revision-Date: 2018-04-29 00:02+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "không thể xác định thư mục hiện tại: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "tệp nhị phân không hợp lệ \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "không thể Ä‘á»c tệp nhị phân \"%s\"" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "không thể tìm thấy file \"%s\" để thá»±c thi" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "không thể thay đổi thư mục thành \"%s\": %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "không thể Ä‘á»c symbolic link \"%s\"" + +#: ../../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "pclose lá»—i: %s" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "hết bá»™ nhá»›\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "không thể nhân đôi con trá» null (lá»—i ná»™i bá»™)\n" + +#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: không thể hiện thị trạng thái tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:162 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: không thể mở thư mục \"%s\": %s\n" + +#: ../../common/file_utils.c:198 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: không thể Ä‘á»c thư mục \"%s\": %s\n" + +#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: không thể mở tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: không thể đồng bá»™ tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: không thể đổi tên tệp \"%s\" thành \"%s\": %s\n" + +#: ../../common/pgfnames.c:45 +#, c-format +msgid "could not open directory \"%s\": %s\n" +msgstr "không thể mở thư mục \"%s\": %s\n" + +#: ../../common/pgfnames.c:72 +#, c-format +msgid "could not read directory \"%s\": %s\n" +msgstr "không thể Ä‘á»c thư mục \"%s\": %s\n" + +#: ../../common/pgfnames.c:84 +#, c-format +msgid "could not close directory \"%s\": %s\n" +msgstr "không thể đóng thư mục \"%s\": %s\n" + +#: ../../common/restricted_token.c:68 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "" +"%s: CẢNH BÃO: không thể tạo restricted tokens trên hệ Ä‘iá»u hành hiện tại\n" + +#: ../../common/restricted_token.c:77 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: không thể mở process token: mã lá»—i %lu\n" + +#: ../../common/restricted_token.c:90 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: không thể cấp phát SIDs: mã lá»—i %lu\n" + +#: ../../common/restricted_token.c:110 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: không thể tạo restricted token: mã lá»—i %lu\n" + +#: ../../common/restricted_token.c:132 +#, c-format +msgid "%s: could not start process for command \"%s\": error code %lu\n" +msgstr "%s: không thể khởi động tiến trình cho câu lệnh \"%s\": mã lá»—i %lu\n" + +#: ../../common/restricted_token.c:170 +#, c-format +msgid "%s: could not re-execute with restricted token: error code %lu\n" +msgstr "%s: không thể thá»±c thi lại vá»›i restricted token: mã lá»—i %lu\n" + +#: ../../common/restricted_token.c:186 +#, c-format +msgid "%s: could not get exit code from subprocess: error code %lu\n" +msgstr "%s: không thể lấy giá trị trả vá» cá»§a tiến trình con: mã lá»—i %lu\n" + +#: ../../common/rmtree.c:77 +#, c-format +msgid "could not stat file or directory \"%s\": %s\n" +msgstr "không thể hiển thị trạng thái tệp hoặc thư mục \"%s\": %s\n" + +#: ../../common/rmtree.c:104 ../../common/rmtree.c:121 +#, c-format +msgid "could not remove file or directory \"%s\": %s\n" +msgstr "không thể xóa tệp hoặc thư mục \"%s\": %s\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "không thể tra cứu được ID cá»§a ngưá»i dùng có hiệu lá»±c %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "ngưá»i dùng không tồn tại" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "lá»—i tra cứu tên ngưá»i dùng: mã lá»—i %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "câu lệnh không thể thá»±c thi" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "không tìm thấy lệnh" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "tiến trình con đã thoát vá»›i giá trị trả vá» %d" + +#: ../../common/wait_error.c:61 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "tiến trình con đã bị kết thúc bởi exception 0x%X" + +#: ../../common/wait_error.c:71 +#, c-format +msgid "child process was terminated by signal %s" +msgstr "tiến trình con đã bị kết thúc bởi tín hiệu %s" + +#: ../../common/wait_error.c:75 +#, c-format +msgid "child process was terminated by signal %d" +msgstr "child process was terminated by signal %d" + +#: ../../common/wait_error.c:80 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "tiến trình con đã kết thúc vá»›i trạng thái không xác định %d" + +#: ../../port/dirmod.c:221 +#, c-format +msgid "could not set junction for \"%s\": %s\n" +msgstr "không thể thiết lập junction cho \"%s\": %s\n" + +#: ../../port/dirmod.c:298 +#, c-format +msgid "could not get junction for \"%s\": %s\n" +msgstr "không thể lấy được junction cho \"%s\": %s\n" + +#: initdb.c:339 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: hết bá»™ nhá»›\n" + +#: initdb.c:495 initdb.c:1538 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: không thể mở tệp \"%s\" để Ä‘á»c: %s\n" + +#: initdb.c:551 initdb.c:867 initdb.c:895 +#, c-format +msgid "%s: could not open file \"%s\" for writing: %s\n" +msgstr "%s: không thể mở tệp \"%s\" để ghi: %s\n" + +#: initdb.c:559 initdb.c:567 initdb.c:874 initdb.c:901 +#, c-format +msgid "%s: could not write file \"%s\": %s\n" +msgstr "%s: không thể ghi tệp \"%s\": %s\n" + +#: initdb.c:586 +#, c-format +msgid "%s: could not execute command \"%s\": %s\n" +msgstr "%s: không thể thá»±c hiện lệnh \"%s\": %s\n" + +#: initdb.c:602 +#, c-format +msgid "%s: removing data directory \"%s\"\n" +msgstr "%s: Ä‘ang xoá thư mục dữ liệu \"%s\"\n" + +#: initdb.c:605 +#, c-format +msgid "%s: failed to remove data directory\n" +msgstr "%s: không thể xóa thư mục dữ liệu\n" + +#: initdb.c:611 +#, c-format +msgid "%s: removing contents of data directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa ná»™i dung cá»§a thư mục dữ liệu \"%s\"\n" + +#: initdb.c:614 +#, c-format +msgid "%s: failed to remove contents of data directory\n" +msgstr "%s: không thể xóa ná»™i dung cá»§a thư mục dữ liệu\n" + +#: initdb.c:620 +#, c-format +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa thư mục WAL \"%s\"\n" + +#: initdb.c:623 +#, c-format +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: không thể xóa thư mục WAL\n" + +#: initdb.c:629 +#, c-format +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa ná»™i dung cá»§a thư mục WAL \"%s\"\n" + +#: initdb.c:632 +#, c-format +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: không thể xóa ná»™i dung cá»§a thư mục WAL\n" + +#: initdb.c:641 +#, c-format +msgid "%s: data directory \"%s\" not removed at user's request\n" +msgstr "%s: thư mục dữ liệu \"%s\" không bị xóa theo yêu cầu cá»§a ngưá»i dùng\n" + +#: initdb.c:646 +#, c-format +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: thư mục WAL \"%s\" không bị xóa theo yêu cầu cá»§a ngưá»i dùng\n" + +#: initdb.c:667 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: không thể chạy dưới quyá»n root\n" +"Vui lòng đăng nhập (sá»­ dụng, ví dụ: \"su\") bằng ngưá»i dùng không có đặc " +"quyá»n,\n" +"ngưá»i dùng này sẽ sở hữu tiến trình server.\n" + +#: initdb.c:703 +#, c-format +msgid "%s: \"%s\" is not a valid server encoding name\n" +msgstr "%s: \"%s\" không phải là server encoding hợp lệ\n" + +#: initdb.c:823 +#, c-format +msgid "%s: file \"%s\" does not exist\n" +msgstr "%s: tệp \"%s\" không tồn tại\n" + +#: initdb.c:825 initdb.c:834 initdb.c:844 +#, c-format +msgid "" +"This might mean you have a corrupted installation or identified\n" +"the wrong directory with the invocation option -L.\n" +msgstr "" +"Äiá»u này có nghÄ©a là bạn đã bị lá»—i trong quá trình cài đặt hoặc \n" +"chỉ định sai thư mục trong tùy chá»n -L.\n" + +#: initdb.c:831 +#, c-format +msgid "%s: could not access file \"%s\": %s\n" +msgstr "%s: không thể truy cập tệp \"%s\": %s\n" + +#: initdb.c:842 +#, c-format +msgid "%s: file \"%s\" is not a regular file\n" +msgstr "%s: tệp \"%s\" không phải là tệp thông thưá»ng\n" + +#: initdb.c:987 +#, c-format +msgid "selecting default max_connections ... " +msgstr "Ä‘ang chá»n giá trị mặc định cho max_connections ... " + +#: initdb.c:1017 +#, c-format +msgid "selecting default shared_buffers ... " +msgstr "Ä‘ang chá»n giá trị mặc định cho shared_buffers ... " + +#: initdb.c:1050 +#, c-format +msgid "selecting dynamic shared memory implementation ... " +msgstr "Ä‘ang chá»n triển khai bá»™ nhá»› chia sẻ động (DSM) ... " + +#: initdb.c:1085 +msgid "creating configuration files ... " +msgstr "Ä‘ang tạo tệp cấu hình ... " + +#: initdb.c:1239 initdb.c:1259 initdb.c:1346 initdb.c:1362 +#, c-format +msgid "%s: could not change permissions of \"%s\": %s\n" +msgstr "%s: không thể thay đổi quyá»n cá»§a \"%s\": %s\n" + +#: initdb.c:1385 +#, c-format +msgid "running bootstrap script ... " +msgstr "Ä‘ang chạy tập lệnh khởi động ... " + +#: initdb.c:1398 +#, c-format +msgid "" +"%s: input file \"%s\" does not belong to PostgreSQL %s\n" +"Check your installation or specify the correct path using the option -L.\n" +msgstr "" +"%s: tệp đầu vào \"%s\" không thuá»™c vá» PostgreSQL %s\n" +"Kiểm tra cài đặt cá»§a bạn hoặc chỉ định đưá»ng dẫn đúng bằng tùy chá»n -L.\n" + +#: initdb.c:1515 +msgid "Enter new superuser password: " +msgstr "Nhập mật khẩu cho superuser má»›i: " + +#: initdb.c:1516 +msgid "Enter it again: " +msgstr "Nhập lại: " + +#: initdb.c:1519 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Mật khẩu không khá»›p.\n" + +#: initdb.c:1545 +#, c-format +msgid "%s: could not read password from file \"%s\": %s\n" +msgstr "%s: không thể Ä‘á»c mật khẩu từ tệp \"%s\": %s\n" + +#: initdb.c:1548 +#, c-format +msgid "%s: password file \"%s\" is empty\n" +msgstr "%s: tệp mật khẩu \"%s\" trống\n" + +#: initdb.c:2123 +#, c-format +msgid "caught signal\n" +msgstr "nhận được tín hiệu\n" + +#: initdb.c:2129 +#, c-format +msgid "could not write to child process: %s\n" +msgstr "không thể ghi tá»›i tiến trình con: %s\n" + +#: initdb.c:2137 +#, c-format +msgid "ok\n" +msgstr "ok\n" + +#: initdb.c:2227 +#, c-format +msgid "%s: setlocale() failed\n" +msgstr "%s: setlocale() lá»—i\n" + +#: initdb.c:2249 +#, c-format +msgid "%s: failed to restore old locale \"%s\"\n" +msgstr "%s: lá»—i khi khôi phục ngôn ngữ cÅ© \"%s\"\n" + +#: initdb.c:2259 +#, c-format +msgid "%s: invalid locale name \"%s\"\n" +msgstr "%s: tên ngôn ngữ không hợp lệ \"%s\"\n" + +#: initdb.c:2271 +#, c-format +msgid "" +"%s: invalid locale settings; check LANG and LC_* environment variables\n" +msgstr "" +"%s: cài đặt ngôn ngữ không hợp lệ; kiểm tra biến môi trưá»ng LANG và LC_ *\n" + +#: initdb.c:2299 +#, c-format +msgid "%s: encoding mismatch\n" +msgstr "%s: mã hóa không khá»›p\n" + +#: initdb.c:2301 +#, c-format +msgid "" +"The encoding you selected (%s) and the encoding that the\n" +"selected locale uses (%s) do not match. This would lead to\n" +"misbehavior in various character string processing functions.\n" +"Rerun %s and either do not specify an encoding explicitly,\n" +"or choose a matching combination.\n" +msgstr "" +"Mã hóa bạn đã chá»n (%s) và mã hóa mà ngôn ngữ được chá»n \n" +"sá»­ dụng (%s) không khá»›p. Äiá»u này có thể dãn đến xá»­ lý không \n" +"đúng trong các hàm xá»­ lý chuá»—i ký tá»±. Chạy lại lệnh %s và không \n" +"chỉ định mã hóa, hoặc chá»n mã hóa phù hợp.\n" + +#: initdb.c:2373 +#, c-format +msgid "" +"%s initializes a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s khởi tạo thư mục dữ liệu cho PostgreSQL.\n" +"\n" + +#: initdb.c:2374 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: initdb.c:2375 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATADIR]\n" + +#: initdb.c:2376 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Tùy chá»n:\n" + +#: initdb.c:2377 +#, c-format +msgid "" +" -A, --auth=METHOD default authentication method for local " +"connections\n" +msgstr "" +" -A, --auth=METHOD phương pháp xác thá»±c mặc định cho kết nối cục " +"bá»™\n" + +#: initdb.c:2378 +#, c-format +msgid "" +" --auth-host=METHOD default authentication method for local TCP/IP " +"connections\n" +msgstr "" +" --auth-host=METHOD phương thức xác thá»±c mặc định cho các kết nối " +"TCP/IP cục bá»™\n" + +#: initdb.c:2379 +#, c-format +msgid "" +" --auth-local=METHOD default authentication method for local-socket " +"connections\n" +msgstr "" +" --auth-local=METHOD phương thức xác thá»±c mặc định cho các kết nối " +"socket cục bá»™\n" + +#: initdb.c:2380 +#, c-format +msgid " [-D, --pgdata=]DATADIR location for this database cluster\n" +msgstr " [-D, --pgdata=]DATADIR vị trí cho thư mục cÆ¡ sở dữ liệu này\n" + +#: initdb.c:2381 +#, c-format +msgid " -E, --encoding=ENCODING set default encoding for new databases\n" +msgstr "" +" -E, --encoding=ENCODING đặt mã hóa mặc định cho cÆ¡ sở dữ liệu má»›i\n" + +#: initdb.c:2382 +#, c-format +msgid "" +" -g, --allow-group-access allow group read/execute on data directory\n" +msgstr "" +" -g, --allow-group-access cho phép Ä‘á»c/thá»±c thi theo nhóm trên thư mục dữ " +"liệu\n" + +#: initdb.c:2383 +#, c-format +msgid " --locale=LOCALE set default locale for new databases\n" +msgstr "" +" --locale=LOCALE đặt ngôn ngữ mặc định cho cÆ¡ sở dữ liệu má»›i\n" + +#: initdb.c:2384 +#, c-format +msgid "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" set default locale in the respective category " +"for\n" +" new databases (default taken from environment)\n" +msgstr "" +" --lc-collate=, --lc-ctype=, --lc-messages=LOCALE\n" +" --lc-monetary=, --lc-numeric=, --lc-time=LOCALE\n" +" đặt ngôn ngữ mặc định trong danh mục tương " +"ứng \n" +" cho sở dữ liệu má»›i (mặc định được lấy từ môi " +"trưá»ng)\n" + +#: initdb.c:2388 +#, c-format +msgid " --no-locale equivalent to --locale=C\n" +msgstr " --no-locale tương đương vá»›i --locale=C\n" + +#: initdb.c:2389 +#, c-format +msgid "" +" --pwfile=FILE read password for the new superuser from file\n" +msgstr " --pwfile=FILE đặt mật khẩu cho superuser má»›i từ tệp\n" + +#: initdb.c:2390 +#, c-format +msgid "" +" -T, --text-search-config=CFG\n" +" default text search configuration\n" +msgstr "" +" -T, --text-search-config=CFG\n" +" cấu hình tìm kiếm văn bản mặc định\n" + +#: initdb.c:2392 +#, c-format +msgid " -U, --username=NAME database superuser name\n" +msgstr " -U, --username=NAME tên superuser cÆ¡ sở dữ liệu\n" + +#: initdb.c:2393 +#, c-format +msgid "" +" -W, --pwprompt prompt for a password for the new superuser\n" +msgstr " -W, --pwprompt yêu cầu nhập mật khẩu cho superuser má»›i\n" + +#: initdb.c:2394 +#, c-format +msgid "" +" -X, --waldir=WALDIR location for the write-ahead log directory\n" +msgstr "" +" -X, --waldir=WALDIR chỉ định vị trí cho thư mục write-ahead log " +"(WAL)\n" + +#: initdb.c:2395 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr "" +" --wal-segsize=SIZE kích thước cá»§a từng tệp WAL, tính bằng " +"megabyte\n" + +#: initdb.c:2396 +#, c-format +msgid "" +"\n" +"Less commonly used options:\n" +msgstr "" +"\n" +"Các tùy chá»n ít được sá»­ dụng hÆ¡n:\n" + +#: initdb.c:2397 +#, c-format +msgid " -d, --debug generate lots of debugging output\n" +msgstr "" +" -d, --debug xuất nhiá»u thông tin debug\n" +" \n" + +#: initdb.c:2398 +#, c-format +msgid " -k, --data-checksums use data page checksums\n" +msgstr " -k, --data-checksums sá»­ dụng checksums cho page dữ liệu\n" + +#: initdb.c:2399 +#, c-format +msgid " -L DIRECTORY where to find the input files\n" +msgstr " -L DIRECTORY nÆ¡i để tìm các tập tin đầu vào\n" + +#: initdb.c:2400 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean không dá»n dẹp sau khi lá»—i\n" + +#: initdb.c:2401 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync không thá»±c hiện đồng bá»™ (sync) dữ liệu xuống " +"đĩa luôn\n" + +#: initdb.c:2402 +#, c-format +msgid " -s, --show show internal settings\n" +msgstr " -s, --show hiển thị thiết lập ná»™i bá»™\n" + +#: initdb.c:2403 +#, c-format +msgid " -S, --sync-only only sync data directory\n" +msgstr " -S, --sync-only chỉ đồng bá»™ thư mục cÆ¡ sở dữ liệu\n" + +#: initdb.c:2404 +#, c-format +msgid "" +"\n" +"Other options:\n" +msgstr "" +"\n" +"Các tùy chá»n khác:\n" + +#: initdb.c:2405 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr "" +" -V, --version hiển thị thông tin phiên bản, sau đó thoát\n" + +#: initdb.c:2406 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr "" +" -?, --help hiển thị ná»™i dung hướng dẫn này, sau đó thoát\n" + +#: initdb.c:2407 +#, c-format +msgid "" +"\n" +"If the data directory is not specified, the environment variable PGDATA\n" +"is used.\n" +msgstr "" +"\n" +"Nếu thư mục dữ liệu không được chỉ định, thì biến môi trưá»ng PGDATA\n" +"sẽ được sá»­ dụng.\n" + +#: initdb.c:2409 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Báo cáo bugs qua email .\n" + +#: initdb.c:2417 +msgid "" +"\n" +"WARNING: enabling \"trust\" authentication for local connections\n" +"You can change this by editing pg_hba.conf or using the option -A, or\n" +"--auth-local and --auth-host, the next time you run initdb.\n" +msgstr "" +"\n" +"CẢNH BÃO: đã thiết lập xác thá»±c \"trust\" cho kết nối cục bá»™\n" +"Bạn có thể thay đổi Ä‘iá»u này bằng cách chỉnh sá»­a pg_hba.conf hoặc sá»­ dụng " +"tùy chá»n -A,\n" +"hoặc --auth-local và --auth-host cho lần chạy initdb sau.\n" + +#: initdb.c:2439 +#, c-format +msgid "%s: invalid authentication method \"%s\" for \"%s\" connections\n" +msgstr "%s: phương pháp xác thá»±c không hợp lệ \"%s\" cho kết nối \"%s\"\n" + +#: initdb.c:2455 +#, c-format +msgid "" +"%s: must specify a password for the superuser to enable %s authentication\n" +msgstr "%s: phải chỉ định mật khẩu cho superuser để thiết lập xác thá»±c %s\n" + +#: initdb.c:2483 +#, c-format +msgid "" +"%s: no data directory specified\n" +"You must identify the directory where the data for this database system\n" +"will reside. Do this with either the invocation option -D or the\n" +"environment variable PGDATA.\n" +msgstr "" +"%s: không có thư mục dữ liệu nào được chỉ định\n" +"Bạn phải xác định thư mục nÆ¡i chứa dữ liệu cho hệ thống cÆ¡ sở dữ liệu này.\n" +"Bạn có thể làm Ä‘iá»u này vá»›i tùy chá»n gá»i -D hoặc\n" +"biến môi trưá»ng PGDATA.\n" + +#: initdb.c:2521 +#, c-format +msgid "" +"The program \"postgres\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"Chương trình \"postgres\" là cần thiết bởi %s nhưng không được tìm thấy\n" +"trong cùng thư mục vá»›i \"%s\".\n" +"Xin vui lòng kiểm tra cài đặt cá»§a bạn.\n" + +#: initdb.c:2528 +#, c-format +msgid "" +"The program \"postgres\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"Chương trình \"postgres\" được tìm thấy bởi \"%s\"\n" +"nhưng không cùng phiên bản vá»›i %s.\n" +"Xin vui lòng kiểm tra cài đặt cá»§a bạn.\n" + +#: initdb.c:2547 +#, c-format +msgid "%s: input file location must be an absolute path\n" +msgstr "%s: vị trí tệp đầu vào phải là đưá»ng dẫn tuyệt đối\n" + +#: initdb.c:2564 +#, c-format +msgid "The database cluster will be initialized with locale \"%s\".\n" +msgstr "database cluster sẽ được khởi tạo vá»›i ngôn ngữ \"%s\".\n" + +#: initdb.c:2567 +#, c-format +msgid "" +"The database cluster will be initialized with locales\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" +msgstr "" +"database cluster sẽ được khởi tạo bằng ngôn ngữ\n" +" COLLATE: %s\n" +" CTYPE: %s\n" +" MESSAGES: %s\n" +" MONETARY: %s\n" +" NUMERIC: %s\n" +" TIME: %s\n" + +#: initdb.c:2591 +#, c-format +msgid "%s: could not find suitable encoding for locale \"%s\"\n" +msgstr "%s: không thể tìm thấy encoding phù hợp cho ngôn ngữ \"%s\"\n" + +#: initdb.c:2593 +#, c-format +msgid "Rerun %s with the -E option.\n" +msgstr "Chạy lại %s vá»›i tùy chá»n -E.\n" + +#: initdb.c:2594 initdb.c:3235 initdb.c:3256 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: initdb.c:2607 +#, c-format +msgid "" +"Encoding \"%s\" implied by locale is not allowed as a server-side " +"encoding.\n" +"The default database encoding will be set to \"%s\" instead.\n" +msgstr "" +"Encoding \"%s\" được ngụ ý bởi ngôn ngữ không được phép làm encoding cho " +"server.\n" +"Thay vào đó, mặc định encoding cho cÆ¡ sở dữ liệu sẽ được đặt thành \"%s\".\n" + +#: initdb.c:2613 +#, c-format +msgid "%s: locale \"%s\" requires unsupported encoding \"%s\"\n" +msgstr "%s: ngôn ngữ \"%s\" yêu cầu encoding không được há»— trợ \"%s\"\n" + +#: initdb.c:2616 +#, c-format +msgid "" +"Encoding \"%s\" is not allowed as a server-side encoding.\n" +"Rerun %s with a different locale selection.\n" +msgstr "" +"Encoding \"%s\" không được cho phép làm encoding cho server.\n" +"Chạy lại %s vá»›i má»™t lá»±a chá»n ngôn ngữ khác.\n" + +#: initdb.c:2625 +#, c-format +msgid "The default database encoding has accordingly been set to \"%s\".\n" +msgstr "Mặc định encoding cho cÆ¡ sở dữ liệu đã được đặt thành \"%s\".\n" + +#: initdb.c:2695 +#, c-format +msgid "" +"%s: could not find suitable text search configuration for locale \"%s\"\n" +msgstr "" +"%s: không thể tìm thấy cấu hình tìm kiếm văn bản phù hợp cho ngôn ngữ \"%s" +"\"\n" + +#: initdb.c:2706 +#, c-format +msgid "" +"%s: warning: suitable text search configuration for locale \"%s\" is " +"unknown\n" +msgstr "" +"%s: cảnh báo: cấu hình tìm kiếm văn bản phù hợp cho ngôn ngữ \"%s\" không " +"xác định\n" + +#: initdb.c:2711 +#, c-format +msgid "" +"%s: warning: specified text search configuration \"%s\" might not match " +"locale \"%s\"\n" +msgstr "" +"%s: cảnh báo: cấu hình tìm kiếm văn bản được chỉ định \"%s\" có thể không " +"khá»›p vá»›i ngôn ngữ \"%s\"\n" + +#: initdb.c:2716 +#, c-format +msgid "The default text search configuration will be set to \"%s\".\n" +msgstr "Cấu hình tìm kiếm văn bản mặc định sẽ được đặt thành \"%s\".\n" + +#: initdb.c:2760 initdb.c:2846 +#, c-format +msgid "creating directory %s ... " +msgstr "Ä‘ang tạo thư mục %s ... " + +#: initdb.c:2766 initdb.c:2852 initdb.c:2920 initdb.c:2982 +#, c-format +msgid "%s: could not create directory \"%s\": %s\n" +msgstr "%s: không thể tạo thư mục \"%s\": %s\n" + +#: initdb.c:2778 initdb.c:2864 +#, c-format +msgid "fixing permissions on existing directory %s ... " +msgstr "Ä‘ang sá»­a các quyá»n trên thư mục hiện tại %s ... " + +#: initdb.c:2784 initdb.c:2870 +#, c-format +msgid "%s: could not change permissions of directory \"%s\": %s\n" +msgstr "%s: không thể thay đổi quyá»n cá»§a thư mục \"%s\": %s\n" + +#: initdb.c:2799 initdb.c:2885 +#, c-format +msgid "%s: directory \"%s\" exists but is not empty\n" +msgstr "%s: thư mục \"%s\" tồn tại nhưng không trống\n" + +#: initdb.c:2805 +#, c-format +msgid "" +"If you want to create a new database system, either remove or empty\n" +"the directory \"%s\" or run %s\n" +"with an argument other than \"%s\".\n" +msgstr "" +"Nếu bạn muốn tạo hệ thống cÆ¡ sở dữ liệu má»›i, hãy xóa hoặc làm trống\n" +"thư mục \"%s\" hoặc chạy %s\n" +"vá»›i má»™t đối số khác vá»›i \"%s\".\n" + +#: initdb.c:2813 initdb.c:2898 initdb.c:3269 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: không thể truy cập thư mục \"%s\": %s\n" + +#: initdb.c:2837 +#, c-format +msgid "%s: WAL directory location must be an absolute path\n" +msgstr "%s: Vị trí thư mục WAL phải là đưá»ng dẫn tuyệt đối\n" + +#: initdb.c:2891 +#, c-format +msgid "" +"If you want to store the WAL there, either remove or empty the directory\n" +"\"%s\".\n" +msgstr "" +"Nếu bạn muốn lưu trữ WAL ở thư mục đã chỉ định, hãy xóa hoặc làm trống thư " +"mục\n" +"\"%s\".\n" + +#: initdb.c:2906 +#, c-format +msgid "%s: could not create symbolic link \"%s\": %s\n" +msgstr "%s: không thể tạo symbolic link \"%s\": %s\n" + +#: initdb.c:2911 +#, c-format +msgid "%s: symlinks are not supported on this platform" +msgstr "%s: symlinks không được há»— trợ trên hệ Ä‘iá»u hành này" + +#: initdb.c:2935 +#, c-format +msgid "" +"It contains a dot-prefixed/invisible file, perhaps due to it being a mount " +"point.\n" +msgstr "" +"ÄÆ°á»ng dẫn chứa tập tin có tiá»n tố . hoặc vô hình, có lẽ do nó là má»™t mount " +"point.\n" + +#: initdb.c:2938 +#, c-format +msgid "" +"It contains a lost+found directory, perhaps due to it being a mount point.\n" +msgstr "ÄÆ°á»ng dẫn chứa thư mục lost+found, có lẽ do nó là má»™t mount point.\n" + +#: initdb.c:2941 +#, c-format +msgid "" +"Using a mount point directly as the data directory is not recommended.\n" +"Create a subdirectory under the mount point.\n" +msgstr "" +"Sá»­ dụng trá»±c tiếp mount point cho thư mục dữ liệu là không được khuyến " +"nghị.\n" +"Tạo má»™t thư mục con dưới mount point.\n" + +#: initdb.c:2967 +#, c-format +msgid "creating subdirectories ... " +msgstr "tạo thư mục con ... " + +#: initdb.c:3014 +msgid "performing post-bootstrap initialization ... " +msgstr "thá»±c hiện khởi tạo sau-bootstrap ... " + +#: initdb.c:3173 +#, c-format +msgid "Running in debug mode.\n" +msgstr "Chạy trong chế độ debug.\n" + +#: initdb.c:3177 +#, c-format +msgid "Running in no-clean mode. Mistakes will not be cleaned up.\n" +msgstr "Chạy ở chế độ không dá»n dẹp. lá»—i xảy ra sẽ khá»™ng được dá»n dẹp.\n" + +#: initdb.c:3254 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: quá nhiá»u đối số cho câu lệnh (đầu tiên là \"%s\")\n" + +#: initdb.c:3274 initdb.c:3367 +msgid "syncing data to disk ... " +msgstr "đồng bá»™ dữ liệu xuống đĩa cứng ... " + +#: initdb.c:3283 +#, c-format +msgid "%s: password prompt and password file cannot be specified together\n" +msgstr "%s: không thể chỉ định yêu cầu mật khẩu và tệp mật khẩu cùng lúc\n" + +#: initdb.c:3309 +#, c-format +msgid "%s: argument of --wal-segsize must be a number\n" +msgstr "%s: đối số cá»§a --wal-segsize phải là má»™t số\n" + +#: initdb.c:3316 +#, c-format +msgid "" +"%s: argument of --wal-segsize must be a power of 2 between 1 and 1024\n" +msgstr "%s: đối số cá»§a --wal-segsize phải là lÅ©y thừa cá»§a 2 từ 1 đến 1024\n" + +#: initdb.c:3334 +#, c-format +msgid "" +"%s: superuser name \"%s\" is disallowed; role names cannot begin with \"pg_" +"\"\n" +msgstr "" +"%s: tên superuser \"%s\" không được phép, tên role không thể bắt đầu bằng " +"\"pg_\"\n" + +#: initdb.c:3338 +#, c-format +msgid "" +"The files belonging to this database system will be owned by user \"%s\".\n" +"This user must also own the server process.\n" +"\n" +msgstr "" +"Các tệp thuá»™c hệ thống cÆ¡ sở dữ liệu này sẽ được sở hữu bởi ngưá»i dùng \"%s" +"\".\n" +"Ngưá»i dùng này cÅ©ng phải sở hữu tiến trình server.\n" +"\n" + +#: initdb.c:3354 +#, c-format +msgid "Data page checksums are enabled.\n" +msgstr "Checksums cho page dữ liệu đã được thiết lập.\n" + +#: initdb.c:3356 +#, c-format +msgid "Data page checksums are disabled.\n" +msgstr "Thiết lập checksums cho page dữ liệu đã bị há»§y.\n" + +#: initdb.c:3373 +#, c-format +msgid "" +"\n" +"Sync to disk skipped.\n" +"The data directory might become corrupt if the operating system crashes.\n" +msgstr "" +"\n" +"Äồng bá»™ hóa xuống đĩa cứng bị bá» qua.\n" +"Thư mục dữ liệu có thể bị há»ng nếu hệ Ä‘iá»u hành bị sá»± cố.\n" + +#. translator: This is a placeholder in a shell command. +#: initdb.c:3399 +msgid "logfile" +msgstr "logfile" + +#: initdb.c:3401 +#, c-format +msgid "" +"\n" +"Success. You can now start the database server using:\n" +"\n" +" %s\n" +"\n" +msgstr "" +"\n" +"Thành công. Bây giá» bạn có thể khởi động hệ thống cÆ¡ sở dữ liệu bằng cách " +"sá»­ dụng:\n" +"\n" +" %s\n" +"\n" diff --git a/src/bin/initdb/t/001_initdb.pl b/src/bin/initdb/t/001_initdb.pl index 8609d2ecbcc..8387b945d36 100644 --- a/src/bin/initdb/t/001_initdb.pl +++ b/src/bin/initdb/t/001_initdb.pl @@ -1,4 +1,4 @@ -# To test successful data directory creation with a additional feature, first +# To test successful data directory creation with an additional feature, first # try to elaborate the "successful creation" test instead of adding a test. # Successful initdb consumes much time and I/O. @@ -8,7 +8,7 @@ use File::stat qw{lstat}; use PostgresNode; use TestLib; -use Test::More tests => 18; +use Test::More tests => 22; my $tempdir = TestLib::tempdir; my $xlogdir = "$tempdir/pgxlog"; @@ -49,21 +49,35 @@ 'successful creation'); # Permissions on PGDATA should be default - SKIP: + SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive($datadir, 0700, 0600), - "check PGDATA permissions"); + "check PGDATA permissions"); } } + +# Control file should tell that data checksums are disabled by default. +command_like( + [ 'pg_controldata', $datadir ], + qr/Data page checksum version:.*0/, + 'checksums are disabled in control file'); +# pg_checksums fails with checksums disabled by default. This is +# not part of the tests included in pg_checksums to save from +# the creation of an extra instance. +command_fails([ 'pg_checksums', '-D', $datadir ], + "pg_checksums fails with data checksum disabled"); + command_ok([ 'initdb', '-S', $datadir ], 'sync only'); command_fails([ 'initdb', $datadir ], 'existing data directory'); # Check group access on PGDATA SKIP: { - skip "unix-style permissions not supported on Windows", 2 if ($windows_os); + skip "unix-style permissions not supported on Windows", 2 + if ($windows_os); # Init a new db with group access my $datadir_group = "$tempdir/data_group"; diff --git a/src/bin/pg_archivecleanup/nls.mk b/src/bin/pg_archivecleanup/nls.mk index 154a94162e9..c2d625c52ff 100644 --- a/src/bin/pg_archivecleanup/nls.mk +++ b/src/bin/pg_archivecleanup/nls.mk @@ -1,4 +1,6 @@ # src/bin/pg_archivecleanup/nls.mk CATALOG_NAME = pg_archivecleanup -AVAIL_LANGUAGES =de es fr pl ru sv -GETTEXT_FILES = pg_archivecleanup.c +AVAIL_LANGUAGES =de es fr ja ko pl ru sv tr vi +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_archivecleanup.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c index d017f5793ba..bb4257ff188 100644 --- a/src/bin/pg_archivecleanup/pg_archivecleanup.c +++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c @@ -1,14 +1,10 @@ /* - * src/bin/pg_archivecleanup/pg_archivecleanup.c - * * pg_archivecleanup.c * - * Production-ready example of an archive_cleanup_command - * used to clean an archive when using standby_mode = on in 9.0 - * or for standalone use for any version of PostgreSQL 8.0+. + * To be used as archive_cleanup_command to clean an archive when using + * standby mode. * - * Original author: Simon Riggs simon@2ndquadrant.com - * Current maintainer: Simon Riggs + * src/bin/pg_archivecleanup/pg_archivecleanup.c */ #include "postgres_fe.h" @@ -21,18 +17,18 @@ #include "pg_getopt.h" +#include "common/logging.h" + #include "access/xlog_internal.h" const char *progname; /* Options and defaults */ -bool debug = false; /* are we debugging? */ bool dryrun = false; /* are we performing a dry-run operation? */ char *additional_ext = NULL; /* Extension to remove from filenames */ char *archiveLocation; /* where to find the archive? */ char *restartWALFileName; /* the file from which we can restart restore */ -char WALFilePath[MAXPGPATH * 2]; /* the file path including archive */ char exclusiveCleanupFileName[MAXFNAMELEN]; /* the oldest file we want * to remain in archive */ @@ -47,7 +43,7 @@ char exclusiveCleanupFileName[MAXFNAMELEN]; /* the oldest file we want * accessible directory. If you want to make other assumptions, * such as using a vendor-specific archive and access API, these * routines are the ones you'll need to change. You're - * encouraged to submit any changes to pgsql-hackers@postgresql.org + * encouraged to submit any changes to pgsql-hackers@lists.postgresql.org * or personally to the current maintainer. Those changes may be * folded in to later versions of this program. */ @@ -69,8 +65,8 @@ Initialize(void) if (stat(archiveLocation, &stat_buf) != 0 || !S_ISDIR(stat_buf.st_mode)) { - fprintf(stderr, _("%s: archive location \"%s\" does not exist\n"), - progname, archiveLocation); + pg_log_error("archive location \"%s\" does not exist", + archiveLocation); exit(2); } } @@ -127,6 +123,9 @@ CleanupPriorWALFiles(void) if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) && strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0) { + char WALFilePath[MAXPGPATH * 2]; /* the file path + * including archive */ + /* * Use the original file name again now, including any * extension that might have been chopped off before testing @@ -143,37 +142,32 @@ CleanupPriorWALFiles(void) * user can pipe the output into some other program. */ printf("%s\n", WALFilePath); - if (debug) - fprintf(stderr, - _("%s: file \"%s\" would be removed\n"), - progname, WALFilePath); + pg_log_debug("file \"%s\" would be removed", WALFilePath); continue; } - if (debug) - fprintf(stderr, _("%s: removing file \"%s\"\n"), - progname, WALFilePath); + pg_log_debug("removing file \"%s\"", WALFilePath); rc = unlink(WALFilePath); if (rc != 0) { - fprintf(stderr, _("%s: ERROR: could not remove file \"%s\": %s\n"), - progname, WALFilePath, strerror(errno)); + pg_log_error("could not remove file \"%s\": %m", + WALFilePath); break; } } } if (errno) - fprintf(stderr, _("%s: could not read archive location \"%s\": %s\n"), - progname, archiveLocation, strerror(errno)); + pg_log_error("could not read archive location \"%s\": %m", + archiveLocation); if (closedir(xldir)) - fprintf(stderr, _("%s: could not close archive location \"%s\": %s\n"), - progname, archiveLocation, strerror(errno)); + pg_log_error("could not close archive location \"%s\": %m", + archiveLocation); } else - fprintf(stderr, _("%s: could not open archive location \"%s\": %s\n"), - progname, archiveLocation, strerror(errno)); + pg_log_error("could not open archive location \"%s\": %m", + archiveLocation); } /* @@ -245,7 +239,7 @@ SetWALFileNameForCleanup(void) if (!fnameOK) { - fprintf(stderr, _("%s: invalid file name argument\n"), progname); + pg_log_error("invalid file name argument"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(2); } @@ -269,7 +263,7 @@ usage(void) printf(_(" -x EXT clean up files if they have this extension\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\n" - "For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" + "For use as archive_cleanup_command in postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" "e.g.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n")); @@ -277,7 +271,7 @@ usage(void) "Or for use as a standalone archive cleaner:\n" "e.g.\n" " pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } /*------------ MAIN ----------------------------------------*/ @@ -286,6 +280,7 @@ main(int argc, char **argv) { int c; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_archivecleanup")); progname = get_progname(argv[0]); @@ -308,7 +303,7 @@ main(int argc, char **argv) switch (c) { case 'd': /* Debug mode */ - debug = true; + pg_logging_set_level(PG_LOG_DEBUG); break; case 'n': /* Dry-Run mode */ dryrun = true; @@ -338,7 +333,7 @@ main(int argc, char **argv) } else { - fprintf(stderr, _("%s: must specify archive location\n"), progname); + pg_log_error("must specify archive location"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(2); } @@ -350,14 +345,14 @@ main(int argc, char **argv) } else { - fprintf(stderr, _("%s: must specify oldest kept WAL file\n"), progname); + pg_log_error("must specify oldest kept WAL file"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(2); } if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments\n"), progname); + pg_log_error("too many command-line arguments"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(2); } @@ -372,13 +367,8 @@ main(int argc, char **argv) */ SetWALFileNameForCleanup(); - if (debug) - { - snprintf(WALFilePath, MAXPGPATH, "%s/%s", + pg_log_debug("keeping WAL file \"%s/%s\" and later", archiveLocation, exclusiveCleanupFileName); - fprintf(stderr, _("%s: keeping WAL file \"%s\" and later\n"), - progname, WALFilePath); - } /* * Remove WAL files older than cut-off diff --git a/src/bin/pg_archivecleanup/po/de.po b/src/bin/pg_archivecleanup/po/de.po index fed9050b35f..f4bc079d6fa 100644 --- a/src/bin/pg_archivecleanup/po/de.po +++ b/src/bin/pg_archivecleanup/po/de.po @@ -1,68 +1,73 @@ # pg_archivecleanup message translation file for pg_archivecleanup -# Copyright (C) 2017 PostgreSQL Global Development Group +# Copyright (C) 2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2017. +# Peter Eisentraut , 2019. # msgid "" msgstr "" -"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 21:16+0000\n" -"PO-Revision-Date: 2017-08-04 18:13-0400\n" -"Last-Translator: Peter Eisentraut \n" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-27 13:48+0000\n" +"PO-Revision-Date: 2019-04-27 16:54+0200\n" +"Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pg_archivecleanup.c:72 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "%s: archive location \"%s\" does not exist\n" -msgstr "%s: Archivverzeichnis »%s« existiert nicht\n" +msgid "fatal: " +msgstr "Fatal: " -#: pg_archivecleanup.c:148 +#: ../../../src/fe_utils/logging.c:189 #, c-format -msgid "%s: file \"%s\" would be removed\n" -msgstr "%s: Datei »%s« würde entfernt werden\n" +msgid "error: " +msgstr "Fehler: " -#: pg_archivecleanup.c:154 +#: ../../../src/fe_utils/logging.c:196 #, c-format -msgid "%s: removing file \"%s\"\n" -msgstr "%s: Datei »%s« wird entfernt\n" +msgid "warning: " +msgstr "Warnung: " -#: pg_archivecleanup.c:160 +#: pg_archivecleanup.c:68 #, c-format -msgid "%s: ERROR: could not remove file \"%s\": %s\n" -msgstr "%s: FEHLER: konnte Datei »%s« nicht entfernen: %s\n" +msgid "archive location \"%s\" does not exist" +msgstr "Archivverzeichnis »%s« existiert nicht" -#: pg_archivecleanup.c:168 +#: pg_archivecleanup.c:153 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" + +#: pg_archivecleanup.c:161 #, c-format -msgid "%s: could not read archive location \"%s\": %s\n" -msgstr "%s: konnte Archivverzeichnis »%s« nicht lesen: %s\n" +msgid "could not read archive location \"%s\": %m" +msgstr "konnte Archivverzeichnis »%s« nicht lesen: %m" -#: pg_archivecleanup.c:171 +#: pg_archivecleanup.c:164 #, c-format -msgid "%s: could not close archive location \"%s\": %s\n" -msgstr "%s: konnte Archivverzeichnis »%s« nicht schließen: %s\n" +msgid "could not close archive location \"%s\": %m" +msgstr "konnte Archivverzeichnis »%s« nicht schließen: %m" -#: pg_archivecleanup.c:175 +#: pg_archivecleanup.c:168 #, c-format -msgid "%s: could not open archive location \"%s\": %s\n" -msgstr "%s: konnte Archivverzeichnis »%s« nicht öffnen: %s\n" +msgid "could not open archive location \"%s\": %m" +msgstr "konnte Archivverzeichnis »%s« nicht öffnen: %m" -#: pg_archivecleanup.c:248 +#: pg_archivecleanup.c:241 #, c-format -msgid "%s: invalid filename input\n" -msgstr "%s: ungültiger Dateiname\n" +msgid "invalid file name argument" +msgstr "ungültiges Dateinamenargument" -#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 -#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#: pg_archivecleanup.c:242 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:255 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -71,17 +76,17 @@ msgstr "" "%s entfernt alte WAL-Dateien aus PostgreSQL-Archiven.\n" "\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:256 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:257 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [OPTION]... ARCHIVVERZEICHNIS ÄLTESTE-ZU-BEHALTENE-WALDATEI\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:258 #, c-format msgid "" "\n" @@ -90,47 +95,47 @@ msgstr "" "\n" "Optionen:\n" -#: pg_archivecleanup.c:266 +#: pg_archivecleanup.c:259 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d Debug-Ausgaben erzeugen (Verbose-Modus)\n" -#: pg_archivecleanup.c:267 +#: pg_archivecleanup.c:260 #, c-format msgid " -n dry run, show the names of the files that would be removed\n" msgstr " -n Probelauf, Namen der Dateien anzeigen, die entfernt würden\n" -#: pg_archivecleanup.c:268 +#: pg_archivecleanup.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_archivecleanup.c:269 +#: pg_archivecleanup.c:262 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x ERW Dateien mit dieser Erweiterung aufräumen\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:263 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_archivecleanup.c:271 +#: pg_archivecleanup.c:264 #, c-format msgid "" "\n" -"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" +"For use as archive_cleanup_command in postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" "e.g.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" msgstr "" "\n" -"Verwendung als archive_cleanup_command in recovery.conf mit standby_mode = on:\n" +"Verwendung als archive_cleanup_command in postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVVERZ %%r'\n" "z.B.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiv %%r'\n" -#: pg_archivecleanup.c:276 +#: pg_archivecleanup.c:269 #, c-format msgid "" "\n" @@ -143,31 +148,24 @@ msgstr "" "z.B.\n" " pg_archivecleanup /mnt/server/archiv 000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:280 +#: pg_archivecleanup.c:273 #, c-format msgid "" "\n" -"Report bugs to .\n" -msgstr "" -"\n" -"Berichten Sie Fehler an .\n" - -#: pg_archivecleanup.c:341 -#, c-format -msgid "%s: must specify archive location\n" -msgstr "%s: Archivverzeichnis muss angegeben werden\n" +"Report bugs to .\n" +msgstr "\nBerichten Sie Fehler an .\n" -#: pg_archivecleanup.c:353 +#: pg_archivecleanup.c:335 #, c-format -msgid "%s: must specify restartfilename\n" -msgstr "%s: Restart-Dateiname muss angegeben werden\n" +msgid "must specify archive location" +msgstr "Archivverzeichnis muss angegeben werden" -#: pg_archivecleanup.c:360 +#: pg_archivecleanup.c:347 #, c-format -msgid "%s: too many parameters\n" -msgstr "%s: zu viele Parameter\n" +msgid "must specify oldest kept WAL file" +msgstr "älteste zu behaltene WAL-Datei muss angegeben werden" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:354 #, c-format -msgid "%s: keep WAL file \"%s\" and later\n" -msgstr "%s: WAL-Datei »%s« und spätere werden behalten\n" +msgid "too many command-line arguments" +msgstr "zu viele Kommandozeilenargumente" diff --git a/src/bin/pg_archivecleanup/po/es.po b/src/bin/pg_archivecleanup/po/es.po index f179c6f1ece..6ef05a84703 100644 --- a/src/bin/pg_archivecleanup/po/es.po +++ b/src/bin/pg_archivecleanup/po/es.po @@ -1,70 +1,76 @@ # Spanish message translation file for pg_archivecleanup -# Copyright (C) 2017 PostgreSQL Global Development Group + +# Copyright (c) 2017-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Carlos Chapi , 2017. # msgid "" msgstr "" -"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 00:16+0000\n" -"PO-Revision-Date: 2017-07-10 12:15-0400\n" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:15+0000\n" +"PO-Revision-Date: 2019-06-06 17:21-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" -#: pg_archivecleanup.c:72 +#: ../../../src/common/logging.c:188 #, c-format -msgid "%s: archive location \"%s\" does not exist\n" -msgstr "%s: ubicación de archivador «%s» no existe\n" +msgid "fatal: " +msgstr "fatal: " -#: pg_archivecleanup.c:148 +#: ../../../src/common/logging.c:195 #, c-format -msgid "%s: file \"%s\" would be removed\n" -msgstr "%s: el archivo «%s» se eliminaría\n" +msgid "error: " +msgstr "error: " -#: pg_archivecleanup.c:154 +#: ../../../src/common/logging.c:202 #, c-format -msgid "%s: removing file \"%s\"\n" -msgstr "%s: eliminado archivo «%s»\n" +msgid "warning: " +msgstr "precaución: " -#: pg_archivecleanup.c:160 +#: pg_archivecleanup.c:68 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "ubicación de archivador «%s» no existe" + +#: pg_archivecleanup.c:154 #, c-format -msgid "%s: ERROR: could not remove file \"%s\": %s\n" -msgstr "%s: ERROR: no se pudo eliminar el archivo «%s»: %s\n" +msgid "could not remove file \"%s\": %m" +msgstr "no se pudo eliminar el archivo «%s»: %m" -#: pg_archivecleanup.c:168 +#: pg_archivecleanup.c:162 #, c-format -msgid "%s: could not read archive location \"%s\": %s\n" -msgstr "%s: no se pudo leer la ubicación del archivador «%s»: %s\n" +msgid "could not read archive location \"%s\": %m" +msgstr "no se pudo leer la ubicación del archivador «%s»: %m" -#: pg_archivecleanup.c:171 +#: pg_archivecleanup.c:165 #, c-format -msgid "%s: could not close archive location \"%s\": %s\n" -msgstr "%s: no se pudo cerrar la ubicación del archivador «%s»: %s\n" +msgid "could not close archive location \"%s\": %m" +msgstr "no se pudo cerrar la ubicación del archivador «%s»: %m" -#: pg_archivecleanup.c:175 +#: pg_archivecleanup.c:169 #, c-format -msgid "%s: could not open archive location \"%s\": %s\n" -msgstr "%s: no se pudo abrir la ubicación del archivador «%s»: %s\n" +msgid "could not open archive location \"%s\": %m" +msgstr "no se pudo abrir la ubicación del archivador «%s»: %m" -#: pg_archivecleanup.c:248 +#: pg_archivecleanup.c:242 #, c-format -msgid "%s: invalid filename input\n" -msgstr "%s: el nombre de archivo ingresado no es válido\n" +msgid "invalid file name argument" +msgstr "el nombre de archivo usado como argumento no es válido" -#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 -#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#: pg_archivecleanup.c:243 pg_archivecleanup.c:316 pg_archivecleanup.c:337 +#: pg_archivecleanup.c:349 pg_archivecleanup.c:356 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Pruebe «%s --help» para mayor información.\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:256 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -73,17 +79,17 @@ msgstr "" "%s elimina archivos de WAL antiguos del archivador de PostgreSQL.\n" "\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:257 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:258 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [OPCIÓN].... UBICACIÓNARCHIVADOR WALMÃSANTIGUOAMANTENER\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:259 #, c-format msgid "" "\n" @@ -92,47 +98,47 @@ msgstr "" "\n" "Opciones:\n" -#: pg_archivecleanup.c:266 +#: pg_archivecleanup.c:260 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d genera salida de depuración (modo verboso)\n" -#: pg_archivecleanup.c:267 +#: pg_archivecleanup.c:261 #, c-format msgid " -n dry run, show the names of the files that would be removed\n" msgstr " -n simulacro, muestra el nombre de los archivos que se eliminarían\n" -#: pg_archivecleanup.c:268 +#: pg_archivecleanup.c:262 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version muestra información de la versión, luego sale\n" -#: pg_archivecleanup.c:269 +#: pg_archivecleanup.c:263 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x EXT hace limpieza de archivos que tengan esta extensión\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:264 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help muestra esta ayuda, luego sale\n" -#: pg_archivecleanup.c:271 +#: pg_archivecleanup.c:265 #, c-format msgid "" "\n" -"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" +"For use as archive_cleanup_command in postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" "e.g.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" msgstr "" "\n" -"Para usar como archive_cleanup_command en recovery.conf cuando standby_mode = on:\n" +"Para usar como archive_cleanup_command en postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPCIÓN]... UBICACIÓNARCHIVADOR %%r'\n" -"e.g.\n" +"por ej.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/servidor/directorioarchivador %%r'\n" -#: pg_archivecleanup.c:276 +#: pg_archivecleanup.c:270 #, c-format msgid "" "\n" @@ -142,34 +148,29 @@ msgid "" msgstr "" "\n" "O para usar como un limpiador de archivador de forma independiente:\n" -"e.g.\n" +"por ej.\n" " pg_archivecleanup /mnt/servidor/directorioarchivador 000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:280 +#: pg_archivecleanup.c:274 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" - -#: pg_archivecleanup.c:341 -#, c-format -msgid "%s: must specify archive location\n" -msgstr "%s: debe especificar la ubicación del archivador\n" +"Reporte errores a .\n" -#: pg_archivecleanup.c:353 +#: pg_archivecleanup.c:336 #, c-format -msgid "%s: must specify restartfilename\n" -msgstr "%s: debe especificar restartfilename\n" +msgid "must specify archive location" +msgstr "debe especificar la ubicación del archivador" -#: pg_archivecleanup.c:360 +#: pg_archivecleanup.c:348 #, c-format -msgid "%s: too many parameters\n" -msgstr "%s: demasiados parámetros\n" +msgid "must specify oldest kept WAL file" +msgstr "debe especificar el fichero WAL más antiguo a mantener" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:355 #, c-format -msgid "%s: keep WAL file \"%s\" and later\n" -msgstr "%s: mantiene el WAL «%s» y posteriores\n" +msgid "too many command-line arguments" +msgstr "demasiados argumentos de línea de órdenes" diff --git a/src/bin/pg_archivecleanup/po/fr.po b/src/bin/pg_archivecleanup/po/fr.po index 94345cbc358..14aa6d726ac 100644 --- a/src/bin/pg_archivecleanup/po/fr.po +++ b/src/bin/pg_archivecleanup/po/fr.po @@ -6,64 +6,69 @@ msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-02 04:46+0000\n" -"PO-Revision-Date: 2017-07-03 06:59+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:17+0000\n" +"PO-Revision-Date: 2019-05-17 15:55+0200\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: \n" -"Language-Team: \n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: pg_archivecleanup.c:72 +#: ../../../src/common/logging.c:188 #, c-format -msgid "%s: archive location \"%s\" does not exist\n" -msgstr "%s : l'emplacement d'archivage « %s » n'existe pas\n" +msgid "fatal: " +msgstr "fatal : " -#: pg_archivecleanup.c:148 +#: ../../../src/common/logging.c:195 #, c-format -msgid "%s: file \"%s\" would be removed\n" -msgstr "%s : le fichier « %s » serait supprimé\n" +msgid "error: " +msgstr "erreur : " -#: pg_archivecleanup.c:154 +#: ../../../src/common/logging.c:202 #, c-format -msgid "%s: removing file \"%s\"\n" -msgstr "%s : suppression du fichier « %s »\n" +msgid "warning: " +msgstr "attention : " -#: pg_archivecleanup.c:160 +#: pg_archivecleanup.c:68 #, c-format -msgid "%s: ERROR: could not remove file \"%s\": %s\n" -msgstr "%s : ERREUR : n'a pas pu supprimer le fichier « %s » : %s\n" +msgid "archive location \"%s\" does not exist" +msgstr "l'emplacement d'archivage « %s » n'existe pas" -#: pg_archivecleanup.c:168 +#: pg_archivecleanup.c:153 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "n'a pas pu supprimer le fichier « %s » : %m" + +#: pg_archivecleanup.c:161 #, c-format -msgid "%s: could not read archive location \"%s\": %s\n" -msgstr "%s : n'a pas pu lire l'emplacement de l'archive « %s » : %s\n" +msgid "could not read archive location \"%s\": %m" +msgstr "n'a pas pu lire l'emplacement de l'archive « %s » : %m" -#: pg_archivecleanup.c:171 +#: pg_archivecleanup.c:164 #, c-format -msgid "%s: could not close archive location \"%s\": %s\n" -msgstr "%s : n'a pas pu fermer l'emplacement de l'archive « %s » : %s\n" +msgid "could not close archive location \"%s\": %m" +msgstr "n'a pas pu fermer l'emplacement de l'archive « %s » : %m" -#: pg_archivecleanup.c:175 +#: pg_archivecleanup.c:168 #, c-format -msgid "%s: could not open archive location \"%s\": %s\n" -msgstr "%s : n'a pas pu fermer l'emplacement de l'archive « %s » : %s\n" +msgid "could not open archive location \"%s\": %m" +msgstr "n'a pas pu ouvrir l'emplacement de l'archive « %s » : %m" -#: pg_archivecleanup.c:248 +#: pg_archivecleanup.c:241 #, c-format -msgid "%s: invalid filename input\n" -msgstr "%s : nom de fichier invalide\n" +msgid "invalid file name argument" +msgstr "argument du nom de fichier invalide" -#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 -#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#: pg_archivecleanup.c:242 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:255 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -72,17 +77,17 @@ msgstr "" "%s supprime les anciens fichiers WAL des archives de PostgreSQL.\n" "\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:256 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:257 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [OPTION]... EMPLACEMENTARCHIVE PLUSANCIENFICHIERWALCONSERVÉ\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:258 #, c-format msgid "" "\n" @@ -91,84 +96,104 @@ msgstr "" "\n" "Options :\n" -#: pg_archivecleanup.c:266 +#: pg_archivecleanup.c:259 #, c-format msgid " -d generate debug output (verbose mode)\n" -msgstr " -d affiche des informations de débugage (mode verbeux)\n" +msgstr "" +" -d affiche des informations de débugage (mode verbeux)\n" -#: pg_archivecleanup.c:267 +#: pg_archivecleanup.c:260 #, c-format -msgid " -n dry run, show the names of the files that would be removed\n" -msgstr " -n test, affiche le nom des fichiers qui seraient supprimés\n" +msgid "" +" -n dry run, show the names of the files that would be " +"removed\n" +msgstr "" +" -n test, affiche le nom des fichiers qui seraient supprimés\n" -#: pg_archivecleanup.c:268 +#: pg_archivecleanup.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version et quitte\n" -#: pg_archivecleanup.c:269 +#: pg_archivecleanup.c:262 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x EXT nettoie les fichiers s'ils ont cette extension\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:263 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide et quitte\n" -#: pg_archivecleanup.c:271 +#: pg_archivecleanup.c:264 #, c-format msgid "" "\n" -"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" -" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION " +"%%r'\n" "e.g.\n" -" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir " +"%%r'\n" msgstr "" "\n" -"Pour utiliser comme archive_cleanup_command dans recovery.conf quand standby_mode = on :\n" -" archive_cleanup_command = 'pg_archivecleanup [OPTION]... EMPLACEMENTARCHIVE %%r'\n" +"Pour utiliser comme archive_cleanup_command dans postgresql.conf :\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... " +"EMPLACEMENTARCHIVE %%r'\n" "e.g.\n" -" archive_cleanup_command = 'pg_archivecleanup /mnt/serveur/reparchives %%r'\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/serveur/reparchives " +"%%r'\n" -#: pg_archivecleanup.c:276 +#: pg_archivecleanup.c:269 #, c-format msgid "" "\n" "Or for use as a standalone archive cleaner:\n" "e.g.\n" -" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" msgstr "" "\n" "Ou pour utiliser comme nettoyeur autonome d'archives :\n" "e.g.\n" -" pg_archivecleanup /mnt/serveur/reparchives 000000010000000000000010.00000020.backup\n" +" pg_archivecleanup /mnt/serveur/reparchives " +"000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:280 +#: pg_archivecleanup.c:273 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapporter les bogues à .\n" +"Rapporter les bogues à .\n" -#: pg_archivecleanup.c:341 +#: pg_archivecleanup.c:335 #, c-format -msgid "%s: must specify archive location\n" -msgstr "%s : doit spécifier l'emplacement de l'archive\n" +msgid "must specify archive location" +msgstr "doit spécifier l'emplacement de l'archive" -#: pg_archivecleanup.c:353 +#: pg_archivecleanup.c:347 #, c-format -msgid "%s: must specify restartfilename\n" -msgstr "%s : doit spécifier restartfilename\n" +msgid "must specify oldest kept WAL file" +msgstr "doit spécifier le plus ancien journal de transactions conservé" -#: pg_archivecleanup.c:360 +#: pg_archivecleanup.c:354 #, c-format -msgid "%s: too many parameters\n" -msgstr "%s : trop de paramètres\n" +msgid "too many command-line arguments" +msgstr "trop d'arguments en ligne de commande" -#: pg_archivecleanup.c:379 -#, c-format -msgid "%s: keep WAL file \"%s\" and later\n" -msgstr "%s : conserve fichier WAL « %s » et les suivants\n" +#~ msgid "%s: too many parameters\n" +#~ msgstr "%s : trop de paramètres\n" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s : conservation du fichier WAL « %s » et des suivants\n" + +#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" +#~ msgstr "%s : ERREUR : n'a pas pu supprimer le fichier « %s » : %s\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s : suppression du fichier « %s »\n" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s : le fichier « %s » serait supprimé\n" diff --git a/src/bin/pg_archivecleanup/po/ja.po b/src/bin/pg_archivecleanup/po/ja.po new file mode 100644 index 00000000000..0dfc5859df6 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/ja.po @@ -0,0 +1,174 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-01-30 15:01+0900\n" +"PO-Revision-Date: 2018-01-30 16:08+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Last-Translator: Michihide Hotta \n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.6\n" + +#: pg_archivecleanup.c:72 +#, c-format +msgid "%s: archive location \"%s\" does not exist\n" +msgstr "%s: アーカイブã®å ´æ‰€ \"%s\" ãŒå­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: pg_archivecleanup.c:148 +#, c-format +msgid "%s: file \"%s\" would be removed\n" +msgstr "%s: ファイル \"%s\" ã¯å‰Šé™¤ã•れã¾ã™\n" + +#: pg_archivecleanup.c:154 +#, c-format +msgid "%s: removing file \"%s\"\n" +msgstr "%s: ファイル \"%s\" を削除ã—ã¦ã„ã¾ã™\n" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "%s: ERROR: could not remove file \"%s\": %s\n" +msgstr "%s: エラー: ファイル \"%s\" を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_archivecleanup.c:168 +#, c-format +msgid "%s: could not read archive location \"%s\": %s\n" +msgstr "%s: アーカイブã®å ´æ‰€ \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_archivecleanup.c:171 +#, c-format +msgid "%s: could not close archive location \"%s\": %s\n" +msgstr "%s: アーカイブã®å ´æ‰€ \"%s\" をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_archivecleanup.c:175 +#, c-format +msgid "%s: could not open archive location \"%s\": %s\n" +msgstr "%s: アーカイブã®å ´æ‰€ \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_archivecleanup.c:248 +#, c-format +msgid "%s: invalid file name argument\n" +msgstr "%s: ファイルå引数ãŒç„¡åйã§ã™\n" + +#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 +#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\" ã§è©³ç´°ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s 㯠PostgreSQL ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã‹ã‚‰å¤ã„ WAL ファイルを削除ã—ã¾ã™ã€‚\n" +"\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "Usage:\n" +msgstr "使用法:\n" + +#: pg_archivecleanup.c:264 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr "%s [オプション] ... {アーカイブã®å ´æ‰€} {ä¿å­˜ã•れã¦ã„る最å¤ã® WAL ファイルå}\n" + +#: pg_archivecleanup.c:265 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_archivecleanup.c:266 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d デãƒãƒƒã‚°æƒ…報を生æˆã—ã¾ã™ï¼ˆå†—長出力モード)\n" + +#: pg_archivecleanup.c:267 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n リãƒãƒ¼ã‚µãƒ«ã€‚削除対象ã®ãƒ•ァイルåを表示ã—ã¾ã™\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を出力ã—ã¦çµ‚了ã—ã¾ã™\n" + +#: pg_archivecleanup.c:269 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT ã“ã®æ‹¡å¼µãŒã‚ã‚‹å ´åˆã¯ãƒ•ァイルをクリーンアップã—ã¾ã™\n" + +#: pg_archivecleanup.c:270 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦çµ‚了ã—ã¾ã™\n" + +#: pg_archivecleanup.c:271 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"standby_mode = on ã®å ´åˆã€recovery.conf ã§ archive_cleanup_command を利用ã—ã¾ã™ã€‚\n" +" archive_cleanup_command = 'pg_archivecleanup [オプション]... アーカイブã®å ´æ‰€ %%r'\n" +"使用例\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" + +#: pg_archivecleanup.c:276 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"ã‚‚ã—ãã¯ã‚¹ã‚¿ãƒ³ãƒ‰ã‚¢ãƒ­ãƒ³ã®ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–クリーナーã¨ã—ã¦ä½¿ã„ã¾ã™:\n" +"使用例\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:280 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ãƒã‚°ãŒã‚れ㰠ã«å ±å‘Šã—ã¦ãã ã•ã„。\n" + +#: pg_archivecleanup.c:341 +#, c-format +msgid "%s: must specify archive location\n" +msgstr "%s: アーカイブã®å ´æ‰€ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: pg_archivecleanup.c:353 +#, c-format +msgid "%s: must specify oldest kept WAL file\n" +msgstr "%s: ä¿å­˜ã•ã‚ŒãŸæœ€å¤ã® WAL ファイルを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: pg_archivecleanup.c:360 +#, c-format +msgid "%s: too many command-line arguments\n" +msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™\n" + +#: pg_archivecleanup.c:379 +#, c-format +msgid "%s: keeping WAL file \"%s\" and later\n" +msgstr "%s: WAL file \"%s\" ã¨ãれ以é™ã®åˆ†ã‚’ä¿å­˜ã—ã¦ã„ã¾ã™\n" diff --git a/src/bin/pg_archivecleanup/po/ko.po b/src/bin/pg_archivecleanup/po/ko.po new file mode 100644 index 00000000000..38da0164739 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/ko.po @@ -0,0 +1,179 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:29+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: pg_archivecleanup.c:72 +#, c-format +msgid "%s: archive location \"%s\" does not exist\n" +msgstr "%s: \"%s\" ì´ë¦„ì˜ ì•„ì¹´ì´ë¸Œ 위치가 ì—†ìŒ\n" + +#: pg_archivecleanup.c:148 +#, c-format +msgid "%s: file \"%s\" would be removed\n" +msgstr "%s: \"%s\" 파ì¼ì´ 지워질 예정\n" + +#: pg_archivecleanup.c:154 +#, c-format +msgid "%s: removing file \"%s\"\n" +msgstr "%s: \"%s\" 파ì¼ì„ 지우는 중\n" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "%s: ERROR: could not remove file \"%s\": %s\n" +msgstr "%s: 오류: \"%s\" íŒŒì¼ ì‚­ì œ 불가: %s\n" + +#: pg_archivecleanup.c:168 +#, c-format +msgid "%s: could not read archive location \"%s\": %s\n" +msgstr "%s: \"%s\" ì•„ì¹´ì´ë¸Œ 위치를 ì½ì„ 수 ì—†ìŒ: %s\n" + +#: pg_archivecleanup.c:171 +#, c-format +msgid "%s: could not close archive location \"%s\": %s\n" +msgstr "%s: \"%s\" ì•„ì¹´ì´ë¸Œ 위치를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" + +#: pg_archivecleanup.c:175 +#, c-format +msgid "%s: could not open archive location \"%s\": %s\n" +msgstr "%s: \"%s\" ì•„ì¹´ì´ë¸Œ 위치를 ì—´ 수 ì—†ìŒ: %s\n" + +#: pg_archivecleanup.c:248 +#, c-format +msgid "%s: invalid file name argument\n" +msgstr "%s: ìž˜ëª»ëœ íŒŒì¼ ì´ë¦„ 매개변수\n" + +#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 +#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 ìžì„¸í•œ 정보는 \"%s --help\" ëª…ë ¹ì„ ì°¸ì¡°í•˜ì„¸ìš”.\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "" +"%s ëª…ë ¹ì€ PostgreSQL ì•„ì¹´ì´ë¸Œ 보관소ì—서 오래ëœ\n" +"WAL 파ì¼ì„ ì§€ì›ë‹ˆë‹¤.\n" +"\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_archivecleanup.c:264 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [옵션]... ì•„ì¹´ì´ë¸Œìœ„치 보관할제ì¼ì˜¤ëž˜ëœíŒŒì¼\n" + +#: pg_archivecleanup.c:265 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: pg_archivecleanup.c:266 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d 보다 ìžì„¸í•œ 작업 ë‚´ìš© 출력\n" + +#: pg_archivecleanup.c:267 +#, c-format +msgid "" +" -n dry run, show the names of the files that would be removed\n" +msgstr " -n 지울 대ìƒë§Œ 확ì¸í•˜ê³  지우지는 않ìŒ\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: pg_archivecleanup.c:269 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT 해당 í™•ìž¥ìž íŒŒì¼ë“¤ì„ 작업 대ìƒìœ¼ë¡œ 함\n" + +#: pg_archivecleanup.c:270 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ë„움ë§ì„ 보여주고 마침\n" + +#: pg_archivecleanup.c:271 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION " +"%%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"recovery.conf 파ì¼ì—서 standby_mode = on ì˜µì…˜ì„ ì‚¬ìš©í•˜ëŠ” 경우:\n" +" archive_cleanup_command = 'pg_archivecleanup [옵션]... ì•„ì¹´ì´ë¸Œìœ„치 %%r'\n" +"사용예:\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" + +#: pg_archivecleanup.c:276 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"ë˜ëŠ” 명령행ì—서 ë…립ì ìœ¼ë¡œ 사용하는 경우:\n" +"사용예:\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:280 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ë¬¸ì œì  ë³´ê³  .\n" + +#: pg_archivecleanup.c:341 +#, c-format +msgid "%s: must specify archive location\n" +msgstr "%s: ì•„ì¹´ì´ë¸Œ 위치는 지정해야 합니다.\n" + +#: pg_archivecleanup.c:353 +#, c-format +msgid "%s: must specify oldest kept WAL file\n" +msgstr "%s: 남길 가장 ì˜¤ëž˜ëœ WAL 파ì¼ì€ 지정해야 합니다.\n" + +#: pg_archivecleanup.c:360 +#, c-format +msgid "%s: too many command-line arguments\n" +msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìžë¥¼ 지정했ìŒ.\n" + +#: pg_archivecleanup.c:379 +#, c-format +msgid "%s: keeping WAL file \"%s\" and later\n" +msgstr "%s: \"%s\" 파ì¼ê³¼ ê·¸ ì´í›„ WAL 파ì¼ì„ 보관함\n" diff --git a/src/bin/pg_archivecleanup/po/ru.po b/src/bin/pg_archivecleanup/po/ru.po index cfd4601a3ae..383cc0516f4 100644 --- a/src/bin/pg_archivecleanup/po/ru.po +++ b/src/bin/pg_archivecleanup/po/ru.po @@ -1,70 +1,69 @@ # Russian message translation file for pg_archivecleanup # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander LAW , 2017. -# +# Alexander Lakhin , 2017. msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-04 04:16+0000\n" -"PO-Revision-Date: 2017-04-10 11:43+0300\n" +"POT-Creation-Date: 2017-08-23 14:45+0000\n" +"PO-Revision-Date: 2017-08-20 14:05+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Alexander Lakhin \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: pg_archivecleanup.c:73 +#: pg_archivecleanup.c:72 #, c-format msgid "%s: archive location \"%s\" does not exist\n" msgstr "%s: раÑположение архива \"%s\" не ÑущеÑтвует\n" -#: pg_archivecleanup.c:149 +#: pg_archivecleanup.c:148 #, c-format msgid "%s: file \"%s\" would be removed\n" msgstr "%s: файл \"%s\" не будет удалён\n" -#: pg_archivecleanup.c:155 +#: pg_archivecleanup.c:154 #, c-format msgid "%s: removing file \"%s\"\n" msgstr "%s: удаление файла \"%s\"\n" -#: pg_archivecleanup.c:161 +#: pg_archivecleanup.c:160 #, c-format msgid "%s: ERROR: could not remove file \"%s\": %s\n" msgstr "%s: ОШИБКÐ: не удалоÑÑŒ Ñтереть файл \"%s\": %s\n" -#: pg_archivecleanup.c:169 +#: pg_archivecleanup.c:168 #, c-format msgid "%s: could not read archive location \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ прочитать раÑположение архива \"%s\": %s\n" -#: pg_archivecleanup.c:172 +#: pg_archivecleanup.c:171 #, c-format msgid "%s: could not close archive location \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ закрыть раÑположение архива \"%s\": %s\n" -#: pg_archivecleanup.c:176 +#: pg_archivecleanup.c:175 #, c-format msgid "%s: could not open archive location \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть раÑположение архива \"%s\": %s\n" -#: pg_archivecleanup.c:249 +#: pg_archivecleanup.c:248 #, c-format -msgid "%s: invalid filename input\n" -msgstr "%s: введено неправильное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°\n" +msgid "%s: invalid file name argument\n" +msgstr "%s: неверный аргумент Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ файла\n" -#: pg_archivecleanup.c:250 pg_archivecleanup.c:322 pg_archivecleanup.c:343 -#: pg_archivecleanup.c:355 pg_archivecleanup.c:362 +#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 +#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:262 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -73,18 +72,18 @@ msgstr "" "%s удалÑет Ñтарые файлы WAL из архивов PostgreSQL.\n" "\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:263 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:264 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr "" " %s [ПÐРÐМЕТР]... РÐСПОЛОЖЕÐИЕ_ÐРХИВРСТÐРЕЙШИЙ_СОХРÐÐЯЕМЫЙ_ФÐЙЛ_WAL\n" -#: pg_archivecleanup.c:266 +#: pg_archivecleanup.c:265 #, c-format msgid "" "\n" @@ -93,12 +92,12 @@ msgstr "" "\n" "Параметры:\n" -#: pg_archivecleanup.c:267 +#: pg_archivecleanup.c:266 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d генерировать подробные ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (отладочный режим)\n" -#: pg_archivecleanup.c:268 +#: pg_archivecleanup.c:267 #, c-format msgid "" " -n dry run, show the names of the files that would be removed\n" @@ -106,23 +105,23 @@ msgstr "" " -n холоÑтой запуÑк, только показать имена файлов, которые " "будут удалены\n" -#: pg_archivecleanup.c:269 +#: pg_archivecleanup.c:268 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" # well-spelled: РСШ -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:269 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x РСШ убрать файлы Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¼ раÑширением\n" -#: pg_archivecleanup.c:271 +#: pg_archivecleanup.c:270 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_archivecleanup.c:272 +#: pg_archivecleanup.c:271 #, c-format msgid "" "\n" @@ -140,7 +139,7 @@ msgstr "" "например:\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" -#: pg_archivecleanup.c:277 +#: pg_archivecleanup.c:276 #, c-format msgid "" "\n" @@ -155,7 +154,7 @@ msgstr "" " pg_archivecleanup /mnt/server/archiverdir " "000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:281 +#: pg_archivecleanup.c:280 #, c-format msgid "" "\n" @@ -164,22 +163,22 @@ msgstr "" "\n" "Об ошибках Ñообщайте по адреÑу .\n" -#: pg_archivecleanup.c:342 +#: pg_archivecleanup.c:341 #, c-format msgid "%s: must specify archive location\n" msgstr "%s: необходимо задать раÑположение архива\n" -#: pg_archivecleanup.c:354 +#: pg_archivecleanup.c:353 #, c-format -msgid "%s: must specify restartfilename\n" +msgid "%s: must specify oldest kept WAL file\n" msgstr "%s: необходимо задать Ð¸Ð¼Ñ Ñтарейшего ÑохранÑемого файла WAL\n" -#: pg_archivecleanup.c:361 +#: pg_archivecleanup.c:360 #, c-format -msgid "%s: too many parameters\n" -msgstr "%s: Ñлишком много параметров\n" +msgid "%s: too many command-line arguments\n" +msgstr "%s: Ñлишком много аргументов командной Ñтроки\n" -#: pg_archivecleanup.c:380 +#: pg_archivecleanup.c:379 #, c-format -msgid "%s: keep WAL file \"%s\" and later\n" +msgid "%s: keeping WAL file \"%s\" and later\n" msgstr "%s: будет Ñохранён файл WAL \"%s\" и поÑледующие\n" diff --git a/src/bin/pg_archivecleanup/po/sv.po b/src/bin/pg_archivecleanup/po/sv.po index 7f898c6a4c8..08a8f1ff09d 100644 --- a/src/bin/pg_archivecleanup/po/sv.po +++ b/src/bin/pg_archivecleanup/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for pg_archivecleanup # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" "Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-05 02:15+0000\n" -"PO-Revision-Date: 2017-08-05 07:55+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-27 01:47+0000\n" +"PO-Revision-Date: 2019-04-27 14:52+0200\n" "Last-Translator: FDennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -16,53 +16,58 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pg_archivecleanup.c:72 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "%s: archive location \"%s\" does not exist\n" -msgstr "'%s: arkivplats \"%s\" finns inte\n" +msgid "fatal: " +msgstr "fatalt: " -#: pg_archivecleanup.c:148 +#: ../../../src/fe_utils/logging.c:189 #, c-format -msgid "%s: file \"%s\" would be removed\n" -msgstr "%s: filen \"%s\" hade tagits bort\n" +msgid "error: " +msgstr "fel: " -#: pg_archivecleanup.c:154 +#: ../../../src/fe_utils/logging.c:196 #, c-format -msgid "%s: removing file \"%s\"\n" -msgstr "%s: tar bort filen \"%s\"\n" +msgid "warning: " +msgstr "varning: " -#: pg_archivecleanup.c:160 +#: pg_archivecleanup.c:68 #, c-format -msgid "%s: ERROR: could not remove file \"%s\": %s\n" -msgstr "%s: FEL: kunde inte ta bort filen \"%s\": %s\n" +msgid "archive location \"%s\" does not exist" +msgstr "arkivplats \"%s\" finns inte" -#: pg_archivecleanup.c:168 +#: pg_archivecleanup.c:153 #, c-format -msgid "%s: could not read archive location \"%s\": %s\n" -msgstr "%s: kunde inte läsa arkivplats \"%s\": %s\n" +msgid "could not remove file \"%s\": %m" +msgstr "kunde inte ta bort fil \"%s\": %m" -#: pg_archivecleanup.c:171 +#: pg_archivecleanup.c:161 #, c-format -msgid "%s: could not close archive location \"%s\": %s\n" -msgstr "%s: kunde inte stänga arkivplats \"%s\": %s\n" +msgid "could not read archive location \"%s\": %m" +msgstr "kunde inte läsa arkivplats \"%s\": %m" -#: pg_archivecleanup.c:175 +#: pg_archivecleanup.c:164 #, c-format -msgid "%s: could not open archive location \"%s\": %s\n" -msgstr "%s: kunde inte öppna arkivplats \"%s\": %s\n" +msgid "could not close archive location \"%s\": %m" +msgstr "kunde inte stänga arkivplats \"%s\": %m" -#: pg_archivecleanup.c:248 +#: pg_archivecleanup.c:168 #, c-format -msgid "%s: invalid file name argument\n" -msgstr "%s: ogiltigt filnamnsargument\n" +msgid "could not open archive location \"%s\": %m" +msgstr "kunde inte öppna arkivplats \"%s\": %m" -#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 -#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#: pg_archivecleanup.c:241 +#, c-format +msgid "invalid file name argument" +msgstr "ogiltigt filnamnsargument" + +#: pg_archivecleanup.c:242 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_archivecleanup.c:262 +#: pg_archivecleanup.c:255 #, c-format msgid "" "%s removes older WAL files from PostgreSQL archives.\n" @@ -71,17 +76,17 @@ msgstr "" "%s tar bort gamla WAL-filer frÃ¥n PostgreSQLs arkiv.\n" "\n" -#: pg_archivecleanup.c:263 +#: pg_archivecleanup.c:256 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_archivecleanup.c:264 +#: pg_archivecleanup.c:257 #, c-format msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" msgstr " %s [FLAGGA]... ARKIVPLATS ÄLDSTASPARADEWALFIL\n" -#: pg_archivecleanup.c:265 +#: pg_archivecleanup.c:258 #, c-format msgid "" "\n" @@ -90,47 +95,47 @@ msgstr "" "\n" "Flaggor:\n" -#: pg_archivecleanup.c:266 +#: pg_archivecleanup.c:259 #, c-format msgid " -d generate debug output (verbose mode)\n" msgstr " -d generera debugutskrift (utförligt läge)\n" -#: pg_archivecleanup.c:267 +#: pg_archivecleanup.c:260 #, c-format msgid " -n dry run, show the names of the files that would be removed\n" msgstr " -n gör inga ändringar visa namn pÃ¥ de filer som skulle ha tagits bort\n" -#: pg_archivecleanup.c:268 +#: pg_archivecleanup.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_archivecleanup.c:269 +#: pg_archivecleanup.c:262 #, c-format msgid " -x EXT clean up files if they have this extension\n" msgstr " -x SUF städa upp filer om de har detta suffix\n" -#: pg_archivecleanup.c:270 +#: pg_archivecleanup.c:263 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: pg_archivecleanup.c:271 +#: pg_archivecleanup.c:264 #, c-format msgid "" "\n" -"For use as archive_cleanup_command in recovery.conf when standby_mode = on:\n" +"For use as archive_cleanup_command in postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" "e.g.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" msgstr "" "\n" -"För att använda som archive_cleanup_command i recovery.conf när standby_mode = on:\n" +"För att använda som archive_cleanup_command i postgresql.conf:\n" " archive_cleanup_command = 'pg_archivecleanup [FLAGGA]... ARKIVPLATS %%r'\n" "t.ex.\n" " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" -#: pg_archivecleanup.c:276 +#: pg_archivecleanup.c:269 #, c-format msgid "" "\n" @@ -143,34 +148,39 @@ msgstr "" "t.ex.\n" " pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" -#: pg_archivecleanup.c:280 +#: pg_archivecleanup.c:273 #, c-format msgid "" "\n" -"Report bugs to .\n" -msgstr "" -"\n" -"Rapportera fel till .\n" - -#: pg_archivecleanup.c:341 -#, c-format -msgid "%s: must specify archive location\n" -msgstr "%s: mÃ¥ste ange en arkivplats\n" +"Report bugs to .\n" +msgstr "\nRapportera fel till .\n" -#: pg_archivecleanup.c:353 +#: pg_archivecleanup.c:335 #, c-format -msgid "%s: must specify oldest kept WAL file\n" -msgstr "%s: mÃ¥ste ange äldsta sparade WAL-filen\n" +msgid "must specify archive location" +msgstr "mÃ¥ste ange en arkivplats" -#: pg_archivecleanup.c:360 +#: pg_archivecleanup.c:347 #, c-format -msgid "%s: too many command-line arguments\n" -msgstr "%s: för mÃ¥nga kommandoradsargument\n" +msgid "must specify oldest kept WAL file" +msgstr "mÃ¥ste ange äldsta sparade WAL-filen" -#: pg_archivecleanup.c:379 +#: pg_archivecleanup.c:354 #, c-format -msgid "%s: keeping WAL file \"%s\" and later\n" -msgstr "%s: behÃ¥ller WAL-fil \"%s\" och senare\n" +msgid "too many command-line arguments" +msgstr "för mÃ¥nga kommandoradsargument" #~ msgid "%s: too many parameters\n" #~ msgstr "%s: för mÃ¥nga parametrar\n" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s: behÃ¥ller WAL-fil \"%s\" och senare\n" + +#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" +#~ msgstr "%s: FEL: kunde inte ta bort filen \"%s\": %s\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s: tar bort filen \"%s\"\n" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s: filen \"%s\" hade tagits bort\n" diff --git a/src/bin/pg_archivecleanup/po/tr.po b/src/bin/pg_archivecleanup/po/tr.po new file mode 100644 index 00000000000..c61889af826 --- /dev/null +++ b/src/bin/pg_archivecleanup/po/tr.po @@ -0,0 +1,185 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# FIRST AUTHOR , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:48+0000\n" +"PO-Revision-Date: 2019-05-28 10:30+0300\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: pg_archivecleanup.c:68 +#, c-format +msgid "archive location \"%s\" does not exist" +msgstr "\"%s\" arÅŸiv lokasyonu mevcut deÄŸil" + +#: pg_archivecleanup.c:153 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "\"%s\" dosyası silinemedi: %m" + +#: pg_archivecleanup.c:161 +#, c-format +msgid "could not read archive location \"%s\": %m" +msgstr "\"%s\" arÅŸiv lokasyonu okunamadı: %m" + +#: pg_archivecleanup.c:164 +#, c-format +msgid "could not close archive location \"%s\": %m" +msgstr "\"%s\" arÅŸiv lokasyonu kapatılamadı: %m" + +#: pg_archivecleanup.c:168 +#, c-format +msgid "could not open archive location \"%s\": %m" +msgstr "\"%s\" arÅŸiv lokasyonu açılamadı: %m" + +#: pg_archivecleanup.c:241 +#, c-format +msgid "invalid file name argument" +msgstr "geçersiz dosya adı argümanı" + +#: pg_archivecleanup.c:242 pg_archivecleanup.c:315 pg_archivecleanup.c:336 +#: pg_archivecleanup.c:348 pg_archivecleanup.c:355 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: pg_archivecleanup.c:255 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "%s daha eski WAL dosyalarını PostgreSQL arÅŸivlerinden kaldırır.\n" + +#: pg_archivecleanup.c:256 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_archivecleanup.c:257 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [SECENEK]... ARSIVLOKASYONU TUTULANENESKIWALDOSYASI\n" + +#: pg_archivecleanup.c:258 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: pg_archivecleanup.c:259 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d hata ayıklama çıktısı oluÅŸtur (ayrıntılı açıklamalı mod)\n" + +#: pg_archivecleanup.c:260 +#, c-format +msgid " -n dry run, show the names of the files that would be removed\n" +msgstr " -n tatbikat modu, sadece kaldırılacak dosyaların adlarını göster\n" + +#: pg_archivecleanup.c:261 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT bu uzantıya sahip dosyaları temizle\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_archivecleanup.c:264 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in postgresql.conf:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +msgstr "" +"\n" +"postgresql.conf'da archive_cleanup_command olarak kullanmak için:\n" +" archive_cleanup_command = 'pg_archivecleanup [SECENEK]... ARSIVLOKASYONU %%r'\n" +"örnek:\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n" +"\n" + +#: pg_archivecleanup.c:269 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"Veya bağımsız bir arÅŸiv temizleyici olarak kullanmak için: \n" +"örnek:\n" +" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:273 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: pg_archivecleanup.c:335 +#, c-format +msgid "must specify archive location" +msgstr "arÅŸiv lokasyonu belirtilmeli" + +#: pg_archivecleanup.c:347 +#, c-format +msgid "must specify oldest kept WAL file" +msgstr "tutulan en eski WAL dosyası belirtilmeli" + +#: pg_archivecleanup.c:354 +#, c-format +msgid "too many command-line arguments" +msgstr "çok fazla komut-satırı argümanı" + +#~ msgid "%s: keeping WAL file \"%s\" and later\n" +#~ msgstr "%s: \"%s\" ve sonrasındaki WAl dosyaları tutuluyor\n" + +#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n" +#~ msgstr "%s: HATA: \"%s\" dosyası kaldırılamadı: %s\n" + +#~ msgid "%s: removing file \"%s\"\n" +#~ msgstr "%s: \"%s\" dosyası kaldırılıyor\n" + +#~ msgid "%s: file \"%s\" would be removed\n" +#~ msgstr "%s: \"%s\" dosyası kaldırılacak\n" diff --git a/src/bin/pg_archivecleanup/po/vi.po b/src/bin/pg_archivecleanup/po/vi.po new file mode 100644 index 00000000000..e35f8181a4b --- /dev/null +++ b/src/bin/pg_archivecleanup/po/vi.po @@ -0,0 +1,183 @@ +# LANGUAGE message translation file for pg_archivecleanup +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_archivecleanup (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-23 02:27+0900\n" +"PO-Revision-Date: 2018-05-04 22:03+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: pg_archivecleanup.c:72 +#, c-format +msgid "%s: archive location \"%s\" does not exist\n" +msgstr "%s: vị trí lưu trữ \"%s\" không tồn tại\n" + +#: pg_archivecleanup.c:148 +#, c-format +msgid "%s: file \"%s\" would be removed\n" +msgstr "%s: tệp \"%s\" sẽ bị xóa\n" + +#: pg_archivecleanup.c:154 +#, c-format +msgid "%s: removing file \"%s\"\n" +msgstr "%s: Ä‘ang xóa tệp \"%s\"\n" + +#: pg_archivecleanup.c:160 +#, c-format +msgid "%s: ERROR: could not remove file \"%s\": %s\n" +msgstr "%s: Lá»–I: không thể xóa tệp \"%s\": %s\n" + +#: pg_archivecleanup.c:168 +#, c-format +msgid "%s: could not read archive location \"%s\": %s\n" +msgstr "%s: không thể Ä‘á»c vị trí lưu trữ \"%s\": %s\n" + +#: pg_archivecleanup.c:171 +#, c-format +msgid "%s: could not close archive location \"%s\": %s\n" +msgstr "%s: không thể đóng vị trí lưu trữ \"%s\": %s\n" + +#: pg_archivecleanup.c:175 +#, c-format +msgid "%s: could not open archive location \"%s\": %s\n" +msgstr "%s: không thể mở vị trí lưu trữ \"%s\": %s\n" + +#: pg_archivecleanup.c:248 +#, c-format +msgid "%s: invalid file name argument\n" +msgstr "%s: đối số tên tệp không hợp lệ\n" + +#: pg_archivecleanup.c:249 pg_archivecleanup.c:321 pg_archivecleanup.c:342 +#: pg_archivecleanup.c:354 pg_archivecleanup.c:361 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_archivecleanup.c:262 +#, c-format +msgid "" +"%s removes older WAL files from PostgreSQL archives.\n" +"\n" +msgstr "%s xóa các tệp WAL cÅ© hÆ¡n khá»i lưu trữ PostgreSQL.\n" + +#: pg_archivecleanup.c:263 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: pg_archivecleanup.c:264 +#, c-format +msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" +msgstr " %s [Tùy chá»n]... ARCHIVELOCATION OLDESTKEPTWALFILE\n" + +#: pg_archivecleanup.c:265 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Tùy chá»n:\n" + +#: pg_archivecleanup.c:266 +#, c-format +msgid " -d generate debug output (verbose mode)\n" +msgstr " -d xuất debug log (chế độ chi tiết)\n" + +#: pg_archivecleanup.c:267 +#, c-format +msgid "" +" -n dry run, show the names of the files that would be " +"removed\n" +msgstr " -n chạy khô, hiển thị tên cá»§a các tệp sẽ bị xóa\n" + +#: pg_archivecleanup.c:268 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version xuất thông tin bản, sau đó kết thúc\n" + +#: pg_archivecleanup.c:269 +#, c-format +msgid " -x EXT clean up files if they have this extension\n" +msgstr " -x EXT dá»n dẹp các tập tin nếu chúng có phần mở rá»™ng này\n" + +#: pg_archivecleanup.c:270 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help hiển thị trợ giúp này, sau đó thoát\n" + +#: pg_archivecleanup.c:271 +#, c-format +msgid "" +"\n" +"For use as archive_cleanup_command in recovery.conf when standby_mode = " +"on:\n" +" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION " +"%%r'\n" +"e.g.\n" +" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir " +"%%r'\n" +msgstr "" +"\n" +"Äể sá»­ dụng như archive_cleanup_command trong recovery.conf khi " +"standby_mode = on:\n" +" archive_cleanup_command = 'pg_archivecleanup [TÙY CHỌN] ... " +"ARCHIVELOCATION %%r'\n" +"ví dụ.\n" +" archive_cleanup_command = 'pg_archivecleanup/mnt/server/archiverdir " +"%%r'\n" + +#: pg_archivecleanup.c:276 +#, c-format +msgid "" +"\n" +"Or for use as a standalone archive cleaner:\n" +"e.g.\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" +msgstr "" +"\n" +"Hoặc để sá»­ dụng như má»™t trình dá»n dẹp lưu trữ độc lập:\n" +"ví dụ.\n" +" pg_archivecleanup /mnt/server/archiverdir " +"000000010000000000000010.00000020.backup\n" + +#: pg_archivecleanup.c:280 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Báo cáo bugs qua email .\n" + +#: pg_archivecleanup.c:341 +#, c-format +msgid "%s: must specify archive location\n" +msgstr "%s: phải chỉ định vị trí lưu trữ\n" + +#: pg_archivecleanup.c:353 +#, c-format +msgid "%s: must specify oldest kept WAL file\n" +msgstr "%s: phải chỉ định tệp WAL được giữ lâu nhất\n" + +#: pg_archivecleanup.c:360 +#, c-format +msgid "%s: too many command-line arguments\n" +msgstr "%s: có quá nhiá»u đối số dòng lệnh\n" + +#: pg_archivecleanup.c:379 +#, c-format +msgid "%s: keeping WAL file \"%s\" and later\n" +msgstr "%s: giữ tệp WAL \"%s\" và những tệp tiếp theo\n" diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl index 1d3a1e4fb92..22782d30420 100644 --- a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl +++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl @@ -10,11 +10,8 @@ my $tempdir = TestLib::tempdir; my @walfiles = ( - '00000001000000370000000C.gz', - '00000001000000370000000D', - '00000001000000370000000E', - '00000001000000370000000F.partial', -); + '00000001000000370000000C.gz', '00000001000000370000000D', + '00000001000000370000000E', '00000001000000370000000F.partial',); sub create_files { @@ -24,36 +21,46 @@ sub create_files print $file 'CONTENT'; close $file; } + return; } create_files(); -command_fails_like(['pg_archivecleanup'], - qr/must specify archive location/, - 'fails if archive location is not specified'); +command_fails_like( + ['pg_archivecleanup'], + qr/must specify archive location/, + 'fails if archive location is not specified'); -command_fails_like(['pg_archivecleanup', $tempdir], - qr/must specify oldest kept WAL file/, - 'fails if oldest kept WAL file name is not specified'); +command_fails_like( + [ 'pg_archivecleanup', $tempdir ], + qr/must specify oldest kept WAL file/, + 'fails if oldest kept WAL file name is not specified'); -command_fails_like(['pg_archivecleanup', 'notexist', 'foo'], - qr/archive location .* does not exist/, - 'fails if archive location does not exist'); +command_fails_like( + [ 'pg_archivecleanup', 'notexist', 'foo' ], + qr/archive location .* does not exist/, + 'fails if archive location does not exist'); -command_fails_like(['pg_archivecleanup', $tempdir, 'foo', 'bar'], - qr/too many command-line arguments/, - 'fails with too many command-line arguments'); +command_fails_like( + [ 'pg_archivecleanup', $tempdir, 'foo', 'bar' ], + qr/too many command-line arguments/, + 'fails with too many command-line arguments'); -command_fails_like(['pg_archivecleanup', $tempdir, 'foo'], - qr/invalid file name argument/, - 'fails with invalid restart file name'); +command_fails_like( + [ 'pg_archivecleanup', $tempdir, 'foo' ], + qr/invalid file name argument/, + 'fails with invalid restart file name'); { # like command_like but checking stderr my $stderr; - my $result = IPC::Run::run ['pg_archivecleanup', '-d', '-n', $tempdir, $walfiles[2]], '2>', \$stderr; + my $result = IPC::Run::run [ 'pg_archivecleanup', '-d', '-n', $tempdir, + $walfiles[2] ], '2>', \$stderr; ok($result, "pg_archivecleanup dry run: exit code 0"); - like($stderr, qr/$walfiles[1].*would be removed/, "pg_archivecleanup dry run: matches"); + like( + $stderr, + qr/$walfiles[1].*would be removed/, + "pg_archivecleanup dry run: matches"); foreach my $fn (@walfiles) { ok(-f "$tempdir/$fn", "$fn not removed"); @@ -66,16 +73,26 @@ sub run_check create_files(); - command_ok(['pg_archivecleanup', '-x', '.gz', $tempdir, $walfiles[2] . $suffix], - "$test_name: runs"); - - ok(! -f "$tempdir/$walfiles[0]", "$test_name: first older WAL file was cleaned up"); - ok(! -f "$tempdir/$walfiles[1]", "$test_name: second older WAL file was cleaned up"); - ok(-f "$tempdir/$walfiles[2]", "$test_name: restartfile was not cleaned up"); - ok(-f "$tempdir/$walfiles[3]", "$test_name: newer WAL file was not cleaned up"); - ok(-f "$tempdir/unrelated_file", "$test_name: unrelated file was not cleaned up"); + command_ok( + [ + 'pg_archivecleanup', '-x', '.gz', $tempdir, + $walfiles[2] . $suffix + ], + "$test_name: runs"); + + ok(!-f "$tempdir/$walfiles[0]", + "$test_name: first older WAL file was cleaned up"); + ok(!-f "$tempdir/$walfiles[1]", + "$test_name: second older WAL file was cleaned up"); + ok(-f "$tempdir/$walfiles[2]", + "$test_name: restartfile was not cleaned up"); + ok(-f "$tempdir/$walfiles[3]", + "$test_name: newer WAL file was not cleaned up"); + ok(-f "$tempdir/unrelated_file", + "$test_name: unrelated file was not cleaned up"); + return; } -run_check('', 'pg_archivecleanup'); -run_check('.partial', 'pg_archivecleanup with .partial file'); +run_check('', 'pg_archivecleanup'); +run_check('.partial', 'pg_archivecleanup with .partial file'); run_check('.00000020.backup', 'pg_archivecleanup with .backup file'); diff --git a/src/bin/pg_basebackup/Makefile b/src/bin/pg_basebackup/Makefile index 74dfb7ab33f..d7a081b9bb6 100644 --- a/src/bin/pg_basebackup/Makefile +++ b/src/bin/pg_basebackup/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_basebackup # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_basebackup/Makefile diff --git a/src/bin/pg_basebackup/nls.mk b/src/bin/pg_basebackup/nls.mk index 63996b62941..fece5551bda 100644 --- a/src/bin/pg_basebackup/nls.mk +++ b/src/bin/pg_basebackup/nls.mk @@ -1,5 +1,6 @@ # src/bin/pg_basebackup/nls.mk CATALOG_NAME = pg_basebackup -AVAIL_LANGUAGES = de es fr he it ko pl pt_BR ru zh_CN -GETTEXT_FILES = pg_basebackup.c pg_receivewal.c pg_recvlogical.c receivelog.c streamutil.c walmethods.c ../../common/fe_memutils.c ../../common/file_utils.c -GETTEXT_TRIGGERS = simple_prompt tar_set_error +AVAIL_LANGUAGES = de es fr he it ja ko pl pt_BR ru sv tr vi zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_basebackup.c pg_receivewal.c pg_recvlogical.c receivelog.c streamutil.c walmethods.c ../../common/fe_memutils.c ../../common/file_utils.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt tar_set_error +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index 58f780c0691..55ef13926da 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -4,7 +4,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_basebackup.c @@ -29,7 +29,9 @@ #include "access/xlog_internal.h" #include "common/file_perm.h" #include "common/file_utils.h" +#include "common/logging.h" #include "common/string.h" +#include "fe_utils/recovery_gen.h" #include "fe_utils/string_utils.h" #include "getopt_long.h" #include "libpq-fe.h" @@ -109,7 +111,7 @@ static bool made_tablespace_dirs = false; static bool found_tablespace_dirs = false; /* Progress counters */ -static uint64 totalsize; +static uint64 totalsize_kb; static uint64 totaldone; static int tablespacecount; @@ -131,23 +133,20 @@ static int has_xlogendptr = 0; static volatile LONG has_xlogendptr = 0; #endif -/* Contents of recovery.conf to be generated */ +/* Contents of configuration file to be generated */ static PQExpBuffer recoveryconfcontents = NULL; /* Function headers */ static void usage(void); -static void disconnect_and_exit(int code) pg_attribute_noreturn(); static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found); static void progress_report(int tablespacenum, const char *filename, bool force); static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum); static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum); -static void GenerateRecoveryConf(PGconn *conn); -static void WriteRecoveryConf(void); static void BaseBackup(void); static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, - bool segment_finished); + bool segment_finished); static const char *get_tablespace_mapping(const char *dir); static void tablespace_list_append(const char *arg); @@ -163,79 +162,63 @@ cleanup_directories_atexit(void) { if (made_new_pgdata) { - fprintf(stderr, _("%s: removing data directory \"%s\"\n"), - progname, basedir); + pg_log_info("removing data directory \"%s\"", basedir); if (!rmtree(basedir, true)) - fprintf(stderr, _("%s: failed to remove data directory\n"), - progname); + pg_log_error("failed to remove data directory"); } else if (found_existing_pgdata) { - fprintf(stderr, - _("%s: removing contents of data directory \"%s\"\n"), - progname, basedir); + pg_log_info("removing contents of data directory \"%s\"", basedir); if (!rmtree(basedir, false)) - fprintf(stderr, _("%s: failed to remove contents of data directory\n"), - progname); + pg_log_error("failed to remove contents of data directory"); } if (made_new_xlogdir) { - fprintf(stderr, _("%s: removing WAL directory \"%s\"\n"), - progname, xlog_dir); + pg_log_info("removing WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, true)) - fprintf(stderr, _("%s: failed to remove WAL directory\n"), - progname); + pg_log_error("failed to remove WAL directory"); } else if (found_existing_xlogdir) { - fprintf(stderr, - _("%s: removing contents of WAL directory \"%s\"\n"), - progname, xlog_dir); + pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, false)) - fprintf(stderr, _("%s: failed to remove contents of WAL directory\n"), - progname); + pg_log_error("failed to remove contents of WAL directory"); } } else { if ((made_new_pgdata || found_existing_pgdata) && !checksum_failure) - fprintf(stderr, - _("%s: data directory \"%s\" not removed at user's request\n"), - progname, basedir); + pg_log_info("data directory \"%s\" not removed at user's request", basedir); if (made_new_xlogdir || found_existing_xlogdir) - fprintf(stderr, - _("%s: WAL directory \"%s\" not removed at user's request\n"), - progname, xlog_dir); + pg_log_info("WAL directory \"%s\" not removed at user's request", xlog_dir); } if ((made_tablespace_dirs || found_tablespace_dirs) && !checksum_failure) - fprintf(stderr, - _("%s: changes to tablespace directories will not be undone\n"), - progname); + pg_log_info("changes to tablespace directories will not be undone"); } static void -disconnect_and_exit(int code) +disconnect_atexit(void) { if (conn != NULL) PQfinish(conn); +} #ifndef WIN32 - - /* - * On windows, our background thread dies along with the process. But on - * Unix, if we have started a subprocess, we want to kill it off so it - * doesn't remain running trying to stream data. - */ +/* + * On windows, our background thread dies along with the process. But on + * Unix, if we have started a subprocess, we want to kill it off so it + * doesn't remain running trying to stream data. + */ +static void +kill_bgchild_atexit(void) +{ if (bgchild > 0) kill(bgchild, SIGTERM); -#endif - - exit(code); } - +#endif /* * Split argument into old_dir and new_dir and append to tablespace mapping @@ -254,7 +237,7 @@ tablespace_list_append(const char *arg) { if (dst_ptr - dst >= MAXPGPATH) { - fprintf(stderr, _("%s: directory name too long\n"), progname); + pg_log_error("directory name too long"); exit(1); } @@ -264,7 +247,7 @@ tablespace_list_append(const char *arg) { if (*cell->new_dir) { - fprintf(stderr, _("%s: multiple \"=\" signs in tablespace mapping\n"), progname); + pg_log_error("multiple \"=\" signs in tablespace mapping"); exit(1); } else @@ -276,9 +259,7 @@ tablespace_list_append(const char *arg) if (!*cell->old_dir || !*cell->new_dir) { - fprintf(stderr, - _("%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n"), - progname, arg); + pg_log_error("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg); exit(1); } @@ -290,15 +271,15 @@ tablespace_list_append(const char *arg) */ if (!is_absolute_path(cell->old_dir)) { - fprintf(stderr, _("%s: old directory is not an absolute path in tablespace mapping: %s\n"), - progname, cell->old_dir); + pg_log_error("old directory is not an absolute path in tablespace mapping: %s", + cell->old_dir); exit(1); } if (!is_absolute_path(cell->new_dir)) { - fprintf(stderr, _("%s: new directory is not an absolute path in tablespace mapping: %s\n"), - progname, cell->new_dir); + pg_log_error("new directory is not an absolute path in tablespace mapping: %s", + cell->new_dir); exit(1); } @@ -346,7 +327,7 @@ usage(void) printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" " (in kB/s, or use suffix \"k\" or \"M\")\n")); printf(_(" -R, --write-recovery-conf\n" - " write recovery.conf for replication\n")); + " write configuration for replication\n")); printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " relocate tablespace in OLDDIR to NEWDIR\n")); printf(_(" --waldir=WALDIR location for the write-ahead log directory\n")); @@ -363,11 +344,11 @@ usage(void) printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n")); printf(_(" -P, --progress show progress information\n")); printf(_(" -S, --slot=SLOTNAME replication slot to use\n")); - printf(_(" --no-slot prevent creation of temporary replication slot\n")); - printf(_(" -k, --no-verify-checksums\n" - " do not verify checksums\n")); printf(_(" -v, --verbose output verbose messages\n")); printf(_(" -V, --version output version information, then exit\n")); + printf(_(" --no-slot prevent creation of temporary replication slot\n")); + printf(_(" --no-verify-checksums\n" + " do not verify checksums\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\nConnection options:\n")); printf(_(" -d, --dbname=CONNSTR connection string\n")); @@ -378,7 +359,7 @@ usage(void) printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -w, --no-password never prompt for password\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } @@ -421,16 +402,14 @@ reached_end_position(XLogRecPtr segendpos, uint32 timeline, r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1); if (r < 0) { - fprintf(stderr, _("%s: could not read from ready pipe: %s\n"), - progname, strerror(errno)); + pg_log_error("could not read from ready pipe: %m"); exit(1); } if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse write-ahead log location \"%s\"\n"), - progname, xlogend); + pg_log_error("could not parse write-ahead log location \"%s\"", + xlogend); exit(1); } xlogendptr = ((uint64) hi) << 32 | lo; @@ -501,15 +480,18 @@ LogStreamerMain(logstreamer_param *param) #endif stream.standby_message_timeout = standby_message_timeout; stream.synchronous = false; - stream.do_sync = do_sync; + /* fsync happens at the end of pg_basebackup for all data */ + stream.do_sync = false; stream.mark_done = true; stream.partial_suffix = NULL; stream.replication_slot = replication_slot; if (format == 'p') - stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0, do_sync); + stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0, + stream.do_sync); else - stream.walmethod = CreateWalTarMethod(param->xlog, compresslevel, do_sync); + stream.walmethod = CreateWalTarMethod(param->xlog, compresslevel, + stream.do_sync); if (!ReceiveXlogStream(param->bgconn, &stream)) @@ -522,9 +504,7 @@ LogStreamerMain(logstreamer_param *param) if (!stream.walmethod->finish()) { - fprintf(stderr, - _("%s: could not finish writing WAL files: %s\n"), - progname, strerror(errno)); + pg_log_error("could not finish writing WAL files: %m"); return 1; } @@ -559,10 +539,9 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) /* Convert the starting position */ if (sscanf(startpos, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse write-ahead log location \"%s\"\n"), - progname, startpos); - disconnect_and_exit(1); + pg_log_error("could not parse write-ahead log location \"%s\"", + startpos); + exit(1); } param->startptr = ((uint64) hi) << 32 | lo; /* Round off to even segment position */ @@ -572,10 +551,8 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) /* Create our background pipe */ if (pipe(bgpipe) < 0) { - fprintf(stderr, - _("%s: could not create pipe for background process: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create pipe for background process: %m"); + exit(1); } #endif @@ -604,16 +581,16 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) { if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL, temp_replication_slot, true, true, false)) - disconnect_and_exit(1); + exit(1); if (verbose) { if (temp_replication_slot) - fprintf(stderr, _("%s: created temporary replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("created temporary replication slot \"%s\"", + replication_slot); else - fprintf(stderr, _("%s: created replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("created replication slot \"%s\"", + replication_slot); } } @@ -632,10 +609,8 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 && errno != EEXIST) { - fprintf(stderr, - _("%s: could not create directory \"%s\": %s\n"), - progname, statusdir, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create directory \"%s\": %m", statusdir); + exit(1); } } @@ -652,21 +627,20 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) } else if (bgchild < 0) { - fprintf(stderr, _("%s: could not create background process: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create background process: %m"); + exit(1); } /* * Else we are in the parent process and all is well. */ + atexit(kill_bgchild_atexit); #else /* WIN32 */ bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL); if (bgchild == 0) { - fprintf(stderr, _("%s: could not create background thread: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create background thread: %m"); + exit(1); } #endif } @@ -688,10 +662,8 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) */ if (pg_mkdir_p(dirname, pg_dir_create_mode) == -1) { - fprintf(stderr, - _("%s: could not create directory \"%s\": %s\n"), - progname, dirname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create directory \"%s\": %m", dirname); + exit(1); } if (created) *created = true; @@ -711,18 +683,15 @@ verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) /* * Exists, not empty */ - fprintf(stderr, - _("%s: directory \"%s\" exists but is not empty\n"), - progname, dirname); - disconnect_and_exit(1); + pg_log_error("directory \"%s\" exists but is not empty", dirname); + exit(1); case -1: /* * Access problem */ - fprintf(stderr, _("%s: could not access directory \"%s\": %s\n"), - progname, dirname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not access directory \"%s\": %m", dirname); + exit(1); } } @@ -750,7 +719,7 @@ progress_report(int tablespacenum, const char *filename, bool force) return; /* Max once per second */ last_progress_report = now; - percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0; + percent = totalsize_kb ? (int) ((totaldone / 1024) * 100 / totalsize_kb) : 0; /* * Avoid overflowing past 100% or the full size. This may make the total @@ -760,8 +729,8 @@ progress_report(int tablespacenum, const char *filename, bool force) */ if (percent > 100) percent = 100; - if (totaldone / 1024 > totalsize) - totalsize = totaldone / 1024; + if (totaldone / 1024 > totalsize_kb) + totalsize_kb = totaldone / 1024; /* * Separate step to keep platform-dependent format code out of @@ -770,7 +739,7 @@ progress_report(int tablespacenum, const char *filename, bool force) */ snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT, totaldone / 1024); - snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize); + snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize_kb); #define VERBOSE_FILENAME_LENGTH 35 if (verbose) @@ -834,16 +803,12 @@ parse_max_rate(char *src) result = strtod(src, &after_num); if (src == after_num) { - fprintf(stderr, - _("%s: transfer rate \"%s\" is not a valid value\n"), - progname, src); + pg_log_error("transfer rate \"%s\" is not a valid value", src); exit(1); } if (errno != 0) { - fprintf(stderr, - _("%s: invalid transfer rate \"%s\": %s\n"), - progname, src, strerror(errno)); + pg_log_error("invalid transfer rate \"%s\": %m", src); exit(1); } @@ -852,8 +817,7 @@ parse_max_rate(char *src) /* * Reject obviously wrong values here. */ - fprintf(stderr, _("%s: transfer rate must be greater than zero\n"), - progname); + pg_log_error("transfer rate must be greater than zero"); exit(1); } @@ -885,18 +849,14 @@ parse_max_rate(char *src) if (*after_num != '\0') { - fprintf(stderr, - _("%s: invalid --max-rate unit: \"%s\"\n"), - progname, suffix); + pg_log_error("invalid --max-rate unit: \"%s\"", suffix); exit(1); } /* Valid integer? */ if ((uint64) result != (uint64) ((uint32) result)) { - fprintf(stderr, - _("%s: transfer rate \"%s\" exceeds integer range\n"), - progname, src); + pg_log_error("transfer rate \"%s\" exceeds integer range", src); exit(1); } @@ -906,9 +866,7 @@ parse_max_rate(char *src) */ if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER) { - fprintf(stderr, - _("%s: transfer rate \"%s\" is out of range\n"), - progname, src); + pg_log_error("transfer rate \"%s\" is out of range", src); exit(1); } @@ -930,10 +888,9 @@ writeTarData( { if (gzwrite(ztarfile, buf, r) != r) { - fprintf(stderr, - _("%s: could not write to compressed file \"%s\": %s\n"), - progname, current_file, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not write to compressed file \"%s\": %s", + current_file, get_gz_error(ztarfile)); + exit(1); } } else @@ -941,9 +898,8 @@ writeTarData( { if (fwrite(buf, r, 1, tarfile) != 1) { - fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), - progname, current_file, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not write to file \"%s\": %m", current_file); + exit(1); } } } @@ -974,6 +930,10 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) bool basetablespace = PQgetisnull(res, rownum, 0); bool in_tarhdr = true; bool skip_file = false; + bool is_recovery_guc_supported = true; + bool is_postgresql_auto_conf = false; + bool found_postgresql_auto_conf = false; + int file_padding_len = 0; size_t tarhdrsz = 0; pgoff_t filesz = 0; @@ -981,6 +941,10 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) gzFile ztarfile = NULL; #endif + /* recovery.conf is integrated into postgresql.conf in 12 and newer */ + if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) + is_recovery_guc_supported = false; + if (basetablespace) { /* @@ -999,10 +963,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { - fprintf(stderr, - _("%s: could not set compression level %d: %s\n"), - progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not set compression level %d: %s", + compresslevel, get_gz_error(ztarfile)); + exit(1); } } else @@ -1020,10 +983,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { - fprintf(stderr, - _("%s: could not set compression level %d: %s\n"), - progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not set compression level %d: %s", + compresslevel, get_gz_error(ztarfile)); + exit(1); } } else @@ -1048,10 +1010,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (gzsetparams(ztarfile, compresslevel, Z_DEFAULT_STRATEGY) != Z_OK) { - fprintf(stderr, - _("%s: could not set compression level %d: %s\n"), - progname, compresslevel, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not set compression level %d: %s", + compresslevel, get_gz_error(ztarfile)); + exit(1); } } else @@ -1069,10 +1030,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (!ztarfile) { /* Compression is in use */ - fprintf(stderr, - _("%s: could not create compressed file \"%s\": %s\n"), - progname, filename, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not create compressed file \"%s\": %s", + filename, get_gz_error(ztarfile)); + exit(1); } } else @@ -1081,9 +1041,8 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) /* Either no zlib support, or zlib support but compresslevel = 0 */ if (!tarfile) { - fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create file \"%s\": %m", filename); + exit(1); } } @@ -1093,9 +1052,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT) { - fprintf(stderr, _("%s: could not get COPY data stream: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not get COPY data stream: %s", + PQerrorMessage(conn)); + exit(1); } while (1) @@ -1113,8 +1072,8 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { /* * End of chunk. If requested, and this is the base tablespace, - * write recovery.conf into the tarfile. When done, close the file - * (but not stdout). + * write configuration file into the tarfile. When done, close the + * file (but not stdout). * * Also, write two completely empty blocks at the end of the tar * file, as required by some tar programs. @@ -1126,19 +1085,48 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (basetablespace && writerecoveryconf) { char header[512]; - int padding; - tarCreateHeader(header, "recovery.conf", NULL, - recoveryconfcontents->len, - pg_file_create_mode, 04000, 02000, - time(NULL)); + /* + * If postgresql.auto.conf has not been found in the streamed + * data, add recovery configuration to postgresql.auto.conf if + * recovery parameters are GUCs. If the instance connected to + * is older than 12, create recovery.conf with this data + * otherwise. + */ + if (!found_postgresql_auto_conf || !is_recovery_guc_supported) + { + int padding; + + tarCreateHeader(header, + is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf", + NULL, + recoveryconfcontents->len, + pg_file_create_mode, 04000, 02000, + time(NULL)); + + padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len; + + WRITE_TAR_DATA(header, sizeof(header)); + WRITE_TAR_DATA(recoveryconfcontents->data, + recoveryconfcontents->len); + if (padding) + WRITE_TAR_DATA(zerobuf, padding); + } - padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len; + /* + * standby.signal is supported only if recovery parameters are + * GUCs. + */ + if (is_recovery_guc_supported) + { + tarCreateHeader(header, "standby.signal", NULL, + 0, /* zero-length file */ + pg_file_create_mode, 04000, 02000, + time(NULL)); - WRITE_TAR_DATA(header, sizeof(header)); - WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len); - if (padding) - WRITE_TAR_DATA(zerobuf, padding); + WRITE_TAR_DATA(header, sizeof(header)); + WRITE_TAR_DATA(zerobuf, 511); + } } /* 2 * 512 bytes empty data at end of file */ @@ -1149,10 +1137,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { if (gzclose(ztarfile) != 0) { - fprintf(stderr, - _("%s: could not close compressed file \"%s\": %s\n"), - progname, filename, get_gz_error(ztarfile)); - disconnect_and_exit(1); + pg_log_error("could not close compressed file \"%s\": %s", + filename, get_gz_error(ztarfile)); + exit(1); } } else @@ -1162,10 +1149,9 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { if (fclose(tarfile) != 0) { - fprintf(stderr, - _("%s: could not close file \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not close file \"%s\": %m", + filename); + exit(1); } } } @@ -1174,16 +1160,16 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) } else if (r == -2) { - fprintf(stderr, _("%s: could not read COPY data: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not read COPY data: %s", + PQerrorMessage(conn)); + exit(1); } if (!writerecoveryconf || !basetablespace) { /* - * When not writing recovery.conf, or when not working on the base - * tablespace, we never have to look for an existing recovery.conf + * When not writing config file, or when not working on the base + * tablespace, we never have to look for an existing configuration * file in the stream. */ WRITE_TAR_DATA(copybuf, r); @@ -1191,7 +1177,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) else { /* - * Look for a recovery.conf in the existing tar stream. If it's + * Look for a config file in the existing tar stream. If it's * there, we must skip it so we can later overwrite it with our * own version of the file. * @@ -1235,29 +1221,54 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) { /* * We have the complete header structure in tarhdr, - * look at the file metadata: - the subsequent file - * contents have to be skipped if the filename is - * recovery.conf - find out the size of the file - * padded to the next multiple of 512 + * look at the file metadata: we may want append + * recovery info into postgresql.auto.conf and skip + * standby.signal file if recovery parameters are + * integrated as GUCs, and recovery.conf otherwise. In + * both cases we must calculate tar padding. */ - int padding; - - skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0); + if (is_recovery_guc_supported) + { + skip_file = (strcmp(&tarhdr[0], "standby.signal") == 0); + is_postgresql_auto_conf = (strcmp(&tarhdr[0], "postgresql.auto.conf") == 0); + } + else + skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0); filesz = read_tar_number(&tarhdr[124], 12); + file_padding_len = ((filesz + 511) & ~511) - filesz; + + if (is_recovery_guc_supported && + is_postgresql_auto_conf && + writerecoveryconf) + { + /* replace tar header */ + char header[512]; + + tarCreateHeader(header, "postgresql.auto.conf", NULL, + filesz + recoveryconfcontents->len, + pg_file_create_mode, 04000, 02000, + time(NULL)); - padding = ((filesz + 511) & ~511) - filesz; - filesz += padding; + WRITE_TAR_DATA(header, sizeof(header)); + } + else + { + /* copy stream with padding */ + filesz += file_padding_len; + + if (!skip_file) + { + /* + * If we're not skipping the file, write the + * tar header unmodified. + */ + WRITE_TAR_DATA(tarhdr, 512); + } + } /* Next part is the file, not the header */ in_tarhdr = false; - - /* - * If we're not skipping the file, write the tar - * header unmodified. - */ - if (!skip_file) - WRITE_TAR_DATA(tarhdr, 512); } } else @@ -1281,6 +1292,34 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) pos += bytes2write; filesz -= bytes2write; } + else if (is_recovery_guc_supported && + is_postgresql_auto_conf && + writerecoveryconf) + { + /* append recovery config to postgresql.auto.conf */ + int padding; + int tailsize; + + tailsize = (512 - file_padding_len) + recoveryconfcontents->len; + padding = ((tailsize + 511) & ~511) - tailsize; + + WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len); + + if (padding) + { + char zerobuf[512]; + + MemSet(zerobuf, 0, sizeof(zerobuf)); + WRITE_TAR_DATA(zerobuf, padding); + } + + /* skip original file padding */ + is_postgresql_auto_conf = false; + skip_file = true; + filesz += file_padding_len; + + found_postgresql_auto_conf = true; + } else { /* @@ -1289,6 +1328,7 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) */ in_tarhdr = true; skip_file = false; + is_postgresql_auto_conf = false; tarhdrsz = 0; filesz = 0; } @@ -1303,9 +1343,10 @@ ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) if (copybuf != NULL) PQfreemem(copybuf); - /* sync the resulting tar file, errors are not considered fatal */ - if (do_sync && strcmp(basedir, "-") != 0) - (void) fsync_fname(filename, false, progname); + /* + * Do not sync the resulting tar file yet, all files are synced once at + * the end. + */ } @@ -1366,9 +1407,9 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT) { - fprintf(stderr, _("%s: could not get COPY data stream: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not get COPY data stream: %s", + PQerrorMessage(conn)); + exit(1); } while (1) @@ -1395,30 +1436,33 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) } else if (r == -2) { - fprintf(stderr, _("%s: could not read COPY data: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not read COPY data: %s", + PQerrorMessage(conn)); + exit(1); } if (file == NULL) { +#ifndef WIN32 int filemode; +#endif /* * No current file, so this must be the header for a new file */ if (r != 512) { - fprintf(stderr, _("%s: invalid tar block header size: %d\n"), - progname, r); - disconnect_and_exit(1); + pg_log_error("invalid tar block header size: %d", r); + exit(1); } totaldone += 512; current_len_left = read_tar_number(©buf[124], 12); +#ifndef WIN32 /* Set permissions on the file */ filemode = read_tar_number(©buf[100], 8); +#endif /* * All files are padded up to 512 bytes @@ -1458,17 +1502,15 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) pg_str_endswith(filename, "/archive_status")) && errno == EEXIST)) { - fprintf(stderr, - _("%s: could not create directory \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create directory \"%s\": %m", + filename); + exit(1); } } #ifndef WIN32 if (chmod(filename, (mode_t) filemode)) - fprintf(stderr, - _("%s: could not set permissions on directory \"%s\": %s\n"), - progname, filename, strerror(errno)); + pg_log_error("could not set permissions on directory \"%s\": %m", + filename); #endif } else if (copybuf[156] == '2') @@ -1490,19 +1532,16 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) mapped_tblspc_path = get_tablespace_mapping(©buf[157]); if (symlink(mapped_tblspc_path, filename) != 0) { - fprintf(stderr, - _("%s: could not create symbolic link from \"%s\" to \"%s\": %s\n"), - progname, filename, mapped_tblspc_path, - strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create symbolic link from \"%s\" to \"%s\": %m", + filename, mapped_tblspc_path); + exit(1); } } else { - fprintf(stderr, - _("%s: unrecognized link indicator \"%c\"\n"), - progname, copybuf[156]); - disconnect_and_exit(1); + pg_log_error("unrecognized link indicator \"%c\"", + copybuf[156]); + exit(1); } continue; /* directory or link handled */ } @@ -1513,15 +1552,14 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) file = fopen(filename, "wb"); if (!file) { - fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create file \"%s\": %m", filename); + exit(1); } #ifndef WIN32 if (chmod(filename, (mode_t) filemode)) - fprintf(stderr, _("%s: could not set permissions on file \"%s\": %s\n"), - progname, filename, strerror(errno)); + pg_log_error("could not set permissions on file \"%s\": %m", + filename); #endif if (current_len_left == 0) @@ -1553,9 +1591,8 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) if (fwrite(copybuf, r, 1, file) != 1) { - fprintf(stderr, _("%s: could not write to file \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not write to file \"%s\": %m", filename); + exit(1); } totaldone += r; progress_report(rownum, filename, false); @@ -1578,17 +1615,15 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) if (file != NULL) { - fprintf(stderr, - _("%s: COPY stream ended before last file was finished\n"), - progname); - disconnect_and_exit(1); + pg_log_error("COPY stream ended before last file was finished"); + exit(1); } if (copybuf != NULL) PQfreemem(copybuf); if (basetablespace && writerecoveryconf) - WriteRecoveryConf(); + WriteRecoveryConfig(conn, basedir, recoveryconfcontents); /* * No data is synced here, everything is done for all tablespaces at the @@ -1596,137 +1631,6 @@ ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) */ } -/* - * Escape a string so that it can be used as a value in a key-value pair - * a configuration file. - */ -static char * -escape_quotes(const char *src) -{ - char *result = escape_single_quotes_ascii(src); - - if (!result) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - exit(1); - } - return result; -} - -/* - * Create a recovery.conf file in memory using a PQExpBuffer - */ -static void -GenerateRecoveryConf(PGconn *conn) -{ - PQconninfoOption *connOptions; - PQconninfoOption *option; - PQExpBufferData conninfo_buf; - char *escaped; - - recoveryconfcontents = createPQExpBuffer(); - if (!recoveryconfcontents) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - disconnect_and_exit(1); - } - - connOptions = PQconninfo(conn); - if (connOptions == NULL) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - disconnect_and_exit(1); - } - - appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n"); - - initPQExpBuffer(&conninfo_buf); - for (option = connOptions; option && option->keyword; option++) - { - /* - * Do not emit this setting if: - the setting is "replication", - * "dbname" or "fallback_application_name", since these would be - * overridden by the libpqwalreceiver module anyway. - not set or - * empty. - */ - if (strcmp(option->keyword, "replication") == 0 || - strcmp(option->keyword, "dbname") == 0 || - strcmp(option->keyword, "fallback_application_name") == 0 || - (option->val == NULL) || - (option->val != NULL && option->val[0] == '\0')) - continue; - - /* Separate key-value pairs with spaces */ - if (conninfo_buf.len != 0) - appendPQExpBufferChar(&conninfo_buf, ' '); - - /* - * Write "keyword=value" pieces, the value string is escaped and/or - * quoted if necessary. - */ - appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword); - appendConnStrVal(&conninfo_buf, option->val); - } - - /* - * Escape the connection string, so that it can be put in the config file. - * Note that this is different from the escaping of individual connection - * options above! - */ - escaped = escape_quotes(conninfo_buf.data); - appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped); - free(escaped); - - if (replication_slot) - { - escaped = escape_quotes(replication_slot); - appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", replication_slot); - free(escaped); - } - - if (PQExpBufferBroken(recoveryconfcontents) || - PQExpBufferDataBroken(conninfo_buf)) - { - fprintf(stderr, _("%s: out of memory\n"), progname); - disconnect_and_exit(1); - } - - termPQExpBuffer(&conninfo_buf); - - PQconninfoFree(connOptions); -} - - -/* - * Write a recovery.conf file into the directory specified in basedir, - * with the contents already collected in memory. - */ -static void -WriteRecoveryConf(void) -{ - char filename[MAXPGPATH]; - FILE *cf; - - sprintf(filename, "%s/recovery.conf", basedir); - - cf = fopen(filename, "w"); - if (cf == NULL) - { - fprintf(stderr, _("%s: could not create file \"%s\": %s\n"), progname, filename, strerror(errno)); - disconnect_and_exit(1); - } - - if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1) - { - fprintf(stderr, - _("%s: could not write to file \"%s\": %s\n"), - progname, filename, strerror(errno)); - disconnect_and_exit(1); - } - - fclose(cf); -} - static void BaseBackup(void) @@ -1760,9 +1664,9 @@ BaseBackup(void) { const char *serverver = PQparameterStatus(conn, "server_version"); - fprintf(stderr, _("%s: incompatible server version %s\n"), - progname, serverver ? serverver : "'unknown'"); - disconnect_and_exit(1); + pg_log_error("incompatible server version %s", + serverver ? serverver : "'unknown'"); + exit(1); } /* @@ -1775,21 +1679,21 @@ BaseBackup(void) * Error message already written in CheckServerVersionForStreaming(), * but add a hint about using -X none. */ - fprintf(stderr, _("HINT: use -X none or -X fetch to disable log streaming\n")); - disconnect_and_exit(1); + pg_log_info("HINT: use -X none or -X fetch to disable log streaming"); + exit(1); } /* - * Build contents of recovery.conf if requested + * Build contents of configuration file if requested */ if (writerecoveryconf) - GenerateRecoveryConf(conn); + recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot); /* * Run IDENTIFY_SYSTEM so we can get the timeline */ if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL)) - disconnect_and_exit(1); + exit(1); /* * Start the actual backup @@ -1800,9 +1704,7 @@ BaseBackup(void) maxrate_clause = psprintf("MAX_RATE %u", maxrate); if (verbose) - fprintf(stderr, - _("%s: initiating base backup, waiting for checkpoint to complete\n"), - progname); + pg_log_info("initiating base backup, waiting for checkpoint to complete"); if (showprogress && !verbose) { @@ -1826,9 +1728,9 @@ BaseBackup(void) if (PQsendQuery(conn, basebkp) == 0) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, "BASE_BACKUP", PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not send replication command \"%s\": %s", + "BASE_BACKUP", PQerrorMessage(conn)); + exit(1); } /* @@ -1837,22 +1739,21 @@ BaseBackup(void) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not initiate base backup: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not initiate base backup: %s", + PQerrorMessage(conn)); + exit(1); } if (PQntuples(res) != 1) { - fprintf(stderr, - _("%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 2); - disconnect_and_exit(1); + pg_log_error("server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields", + PQntuples(res), PQnfields(res), 1, 2); + exit(1); } strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart)); if (verbose) - fprintf(stderr, _("%s: checkpoint completed\n"), progname); + pg_log_info("checkpoint completed"); /* * 9.3 and later sends the TLI of the starting point. With older servers, @@ -1867,8 +1768,8 @@ BaseBackup(void) MemSet(xlogend, 0, sizeof(xlogend)); if (verbose && includewal != NO_WAL) - fprintf(stderr, _("%s: write-ahead log start point: %s on timeline %u\n"), - progname, xlogstart, starttli); + pg_log_info("write-ahead log start point: %s on timeline %u", + xlogstart, starttli); /* * Get the header @@ -1876,24 +1777,24 @@ BaseBackup(void) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not get backup header: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not get backup header: %s", + PQerrorMessage(conn)); + exit(1); } if (PQntuples(res) < 1) { - fprintf(stderr, _("%s: no data returned from server\n"), progname); - disconnect_and_exit(1); + pg_log_error("no data returned from server"); + exit(1); } /* * Sum up the total size, for progress reporting */ - totalsize = totaldone = 0; + totalsize_kb = totaldone = 0; tablespacecount = PQntuples(res); for (i = 0; i < PQntuples(res); i++) { - totalsize += atol(PQgetvalue(res, i, 2)); + totalsize_kb += atol(PQgetvalue(res, i, 2)); /* * Verify tablespace directories are empty. Don't bother with the @@ -1902,7 +1803,7 @@ BaseBackup(void) */ if (format == 'p' && !PQgetisnull(res, i, 1)) { - char *path = (char *) get_tablespace_mapping(PQgetvalue(res, i, 1)); + char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1))); verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs); } @@ -1913,10 +1814,9 @@ BaseBackup(void) */ if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1) { - fprintf(stderr, - _("%s: can only write single tablespace to stdout, database has %d\n"), - progname, PQntuples(res)); - disconnect_and_exit(1); + pg_log_error("can only write single tablespace to stdout, database has %d", + PQntuples(res)); + exit(1); } /* @@ -1926,8 +1826,7 @@ BaseBackup(void) if (includewal == STREAM_WAL) { if (verbose) - fprintf(stderr, _("%s: starting background WAL receiver\n"), - progname); + pg_log_info("starting background WAL receiver"); StartLogStreamer(xlogstart, starttli, sysidentifier); } @@ -1957,21 +1856,18 @@ BaseBackup(void) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, - _("%s: could not get write-ahead log end position from server: %s"), - progname, PQerrorMessage(conn)); - disconnect_and_exit(1); + pg_log_error("could not get write-ahead log end position from server: %s", + PQerrorMessage(conn)); + exit(1); } if (PQntuples(res) != 1) { - fprintf(stderr, - _("%s: no write-ahead log end position returned from server\n"), - progname); - disconnect_and_exit(1); + pg_log_error("no write-ahead log end position returned from server"); + exit(1); } strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend)); if (verbose && includewal != NO_WAL) - fprintf(stderr, _("%s: write-ahead log end point: %s\n"), progname, xlogend); + pg_log_info("write-ahead log end point: %s", xlogend); PQclear(res); res = PQgetResult(conn); @@ -1982,23 +1878,22 @@ BaseBackup(void) if (sqlstate && strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0) { - fprintf(stderr, _("%s: checksum error occured\n"), - progname); + pg_log_error("checksum error occurred"); checksum_failure = true; } else { - fprintf(stderr, _("%s: final receive failed: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("final receive failed: %s", + PQerrorMessage(conn)); } - disconnect_and_exit(1); + exit(1); } if (bgchild > 0) { #ifndef WIN32 int status; - int r; + pid_t r; #else DWORD status; @@ -2012,43 +1907,31 @@ BaseBackup(void) #endif if (verbose) - fprintf(stderr, - _("%s: waiting for background process to finish streaming ...\n"), progname); + pg_log_info("waiting for background process to finish streaming ..."); #ifndef WIN32 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend)) { - fprintf(stderr, - _("%s: could not send command to background pipe: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_info("could not send command to background pipe: %m"); + exit(1); } /* Just wait for the background process to exit */ r = waitpid(bgchild, &status, 0); - if (r == -1) + if (r == (pid_t) -1) { - fprintf(stderr, _("%s: could not wait for child process: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not wait for child process: %m"); + exit(1); } if (r != bgchild) { - fprintf(stderr, _("%s: child %d died, expected %d\n"), - progname, r, (int) bgchild); - disconnect_and_exit(1); - } - if (!WIFEXITED(status)) - { - fprintf(stderr, _("%s: child process did not exit normally\n"), - progname); - disconnect_and_exit(1); + pg_log_error("child %d died, expected %d", (int) r, (int) bgchild); + exit(1); } - if (WEXITSTATUS(status) != 0) + if (status != 0) { - fprintf(stderr, _("%s: child process exited with error %d\n"), - progname, WEXITSTATUS(status)); - disconnect_and_exit(1); + pg_log_error("%s", wait_result_to_str(status)); + exit(1); } /* Exited normally, we're happy! */ #else /* WIN32 */ @@ -2060,10 +1943,9 @@ BaseBackup(void) */ if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse write-ahead log location \"%s\"\n"), - progname, xlogend); - disconnect_and_exit(1); + pg_log_error("could not parse write-ahead log location \"%s\"", + xlogend); + exit(1); } xlogendptr = ((uint64) hi) << 32 | lo; InterlockedIncrement(&has_xlogendptr); @@ -2073,28 +1955,26 @@ BaseBackup(void) WAIT_OBJECT_0) { _dosmaperr(GetLastError()); - fprintf(stderr, _("%s: could not wait for child thread: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not wait for child thread: %m"); + exit(1); } if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0) { _dosmaperr(GetLastError()); - fprintf(stderr, _("%s: could not get child thread exit status: %s\n"), - progname, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not get child thread exit status: %m"); + exit(1); } if (status != 0) { - fprintf(stderr, _("%s: child thread exited with error %u\n"), - progname, (unsigned int) status); - disconnect_and_exit(1); + pg_log_error("child thread exited with error %u", + (unsigned int) status); + exit(1); } /* Exited normally, we're happy */ #endif } - /* Free the recovery.conf contents */ + /* Free the configuration file contents */ destroyPQExpBuffer(recoveryconfcontents); /* @@ -2102,29 +1982,32 @@ BaseBackup(void) */ PQclear(res); PQfinish(conn); + conn = NULL; /* * Make data persistent on disk once backup is completed. For tar format - * once syncing the parent directory is fine, each tar file created per - * tablespace has been already synced. In plain format, all the data of - * the base directory is synced, taking into account all the tablespaces. + * sync the parent directory and all its contents as each tar file was not + * synced after being completed. In plain format, all the data of the + * base directory is synced, taking into account all the tablespaces. * Errors are not considered fatal. */ if (do_sync) { + if (verbose) + pg_log_info("syncing data to disk ..."); if (format == 't') { if (strcmp(basedir, "-") != 0) - (void) fsync_fname(basedir, true, progname); + (void) fsync_dir_recurse(basedir); } else { - (void) fsync_pgdata(basedir, progname, serverVersion); + (void) fsync_pgdata(basedir, serverVersion); } } if (verbose) - fprintf(stderr, _("%s: base backup completed\n"), progname); + pg_log_info("base backup completed"); } @@ -2159,13 +2042,14 @@ main(int argc, char **argv) {"progress", no_argument, NULL, 'P'}, {"waldir", required_argument, NULL, 1}, {"no-slot", no_argument, NULL, 2}, - {"no-verify-checksums", no_argument, NULL, 'k'}, + {"no-verify-checksums", no_argument, NULL, 3}, {NULL, 0, NULL, 0} }; int c; int option_index; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup")); @@ -2204,9 +2088,8 @@ main(int argc, char **argv) format = 't'; else { - fprintf(stderr, - _("%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n"), - progname, optarg); + pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"", + optarg); exit(1); } break; @@ -2249,9 +2132,8 @@ main(int argc, char **argv) } else { - fprintf(stderr, - _("%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n"), - progname, optarg); + pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"", + optarg); exit(1); } break; @@ -2278,8 +2160,7 @@ main(int argc, char **argv) compresslevel = atoi(optarg); if (compresslevel < 0 || compresslevel > 9) { - fprintf(stderr, _("%s: invalid compression level \"%s\"\n"), - progname, optarg); + pg_log_error("invalid compression level \"%s\"", optarg); exit(1); } break; @@ -2290,8 +2171,8 @@ main(int argc, char **argv) fastcheckpoint = false; else { - fprintf(stderr, _("%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n"), - progname, optarg); + pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"", + optarg); exit(1); } break; @@ -2317,8 +2198,7 @@ main(int argc, char **argv) standby_message_timeout = atoi(optarg) * 1000; if (standby_message_timeout < 0) { - fprintf(stderr, _("%s: invalid status interval \"%s\"\n"), - progname, optarg); + pg_log_error("invalid status interval \"%s\"", optarg); exit(1); } break; @@ -2328,7 +2208,7 @@ main(int argc, char **argv) case 'P': showprogress = true; break; - case 'k': + case 3: verify_checksums = false; break; default: @@ -2347,9 +2227,8 @@ main(int argc, char **argv) */ if (optind < argc) { - fprintf(stderr, - _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2360,7 +2239,7 @@ main(int argc, char **argv) */ if (basedir == NULL) { - fprintf(stderr, _("%s: no target directory specified\n"), progname); + pg_log_error("no target directory specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2371,9 +2250,7 @@ main(int argc, char **argv) */ if (format == 'p' && compresslevel != 0) { - fprintf(stderr, - _("%s: only tar mode backups can be compressed\n"), - progname); + pg_log_error("only tar mode backups can be compressed"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2381,9 +2258,7 @@ main(int argc, char **argv) if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0) { - fprintf(stderr, - _("%s: cannot stream write-ahead logs in tar mode to stdout\n"), - progname); + pg_log_error("cannot stream write-ahead logs in tar mode to stdout"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2391,9 +2266,7 @@ main(int argc, char **argv) if (replication_slot && includewal != STREAM_WAL) { - fprintf(stderr, - _("%s: replication slots can only be used with WAL streaming\n"), - progname); + pg_log_error("replication slots can only be used with WAL streaming"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2403,9 +2276,7 @@ main(int argc, char **argv) { if (replication_slot) { - fprintf(stderr, - _("%s: --no-slot cannot be used with slot name\n"), - progname); + pg_log_error("--no-slot cannot be used with slot name"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2417,9 +2288,8 @@ main(int argc, char **argv) { if (!replication_slot) { - fprintf(stderr, - _("%s: --create-slot needs a slot to be specified using --slot\n"), - progname); + pg_log_error("%s needs a slot to be specified using --slot", + "--create-slot"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2427,9 +2297,7 @@ main(int argc, char **argv) if (no_slot) { - fprintf(stderr, - _("%s: --create-slot and --no-slot are incompatible options\n"), - progname); + pg_log_error("--create-slot and --no-slot are incompatible options"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2440,9 +2308,7 @@ main(int argc, char **argv) { if (format != 'p') { - fprintf(stderr, - _("%s: WAL directory location can only be specified in plain mode\n"), - progname); + pg_log_error("WAL directory location can only be specified in plain mode"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2452,8 +2318,7 @@ main(int argc, char **argv) canonicalize_path(xlog_dir); if (!is_absolute_path(xlog_dir)) { - fprintf(stderr, _("%s: WAL directory location must be " - "an absolute path\n"), progname); + pg_log_error("WAL directory location must be an absolute path"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -2463,9 +2328,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBZ if (compresslevel != 0) { - fprintf(stderr, - _("%s: this build does not support compression\n"), - progname); + pg_log_error("this build does not support compression"); exit(1); } #endif @@ -2477,6 +2340,7 @@ main(int argc, char **argv) /* Error message already written in GetConnection() */ exit(1); } + atexit(disconnect_atexit); /* * Set umask so that directories/files are created with the same @@ -2498,7 +2362,7 @@ main(int argc, char **argv) /* determine remote server's xlog segment size */ if (!RetrieveWalSegSize(conn)) - disconnect_and_exit(1); + exit(1); /* Create pg_wal symlink, if required */ if (xlog_dir) @@ -2518,13 +2382,12 @@ main(int argc, char **argv) #ifdef HAVE_SYMLINK if (symlink(xlog_dir, linkloc) != 0) { - fprintf(stderr, _("%s: could not create symbolic link \"%s\": %s\n"), - progname, linkloc, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not create symbolic link \"%s\": %m", linkloc); + exit(1); } #else - fprintf(stderr, _("%s: symlinks are not supported on this platform\n")); - disconnect_and_exit(1); + pg_log_error("symlinks are not supported on this platform"); + exit(1); #endif free(linkloc); } diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c index 535355ebdad..f39c1339d72 100644 --- a/src/bin/pg_basebackup/pg_receivewal.c +++ b/src/bin/pg_basebackup/pg_receivewal.c @@ -5,7 +5,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_receivewal.c @@ -20,6 +20,7 @@ #include #include "common/file_perm.h" +#include "common/logging.h" #include "libpq-fe.h" #include "access/xlog_internal.h" #include "getopt_long.h" @@ -53,13 +54,14 @@ static void close_destination_dir(DIR *dest_dir, char *dest_folder); static XLogRecPtr FindStreamingStart(uint32 *tli); static void StreamLog(void); static bool stop_streaming(XLogRecPtr segendpos, uint32 timeline, - bool segment_finished); + bool segment_finished); -#define disconnect_and_exit(code) \ - { \ - if (conn != NULL) PQfinish(conn); \ - exit(code); \ - } +static void +disconnect_atexit(void) +{ + if (conn != NULL) + PQfinish(conn); +} /* Routines to evaluate segment file format */ #define IsCompressXLogFileName(fname) \ @@ -102,7 +104,7 @@ usage(void) printf(_("\nOptional actions:\n")); printf(_(" --create-slot create a new replication slot (for the slot's name see --slot)\n")); printf(_(" --drop-slot drop the replication slot (for the slot's name see --slot)\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } static bool @@ -113,16 +115,16 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished) /* we assume that we get called once at the end of each segment */ if (verbose && segment_finished) - fprintf(stderr, _("%s: finished segment at %X/%X (timeline %u)\n"), - progname, (uint32) (xlogpos >> 32), (uint32) xlogpos, - timeline); + pg_log_info("finished segment at %X/%X (timeline %u)", + (uint32) (xlogpos >> 32), (uint32) xlogpos, + timeline); if (!XLogRecPtrIsInvalid(endpos) && endpos < xlogpos) { if (verbose) - fprintf(stderr, _("%s: stopped streaming at %X/%X (timeline %u)\n"), - progname, (uint32) (xlogpos >> 32), (uint32) xlogpos, - timeline); + pg_log_info("stopped log streaming at %X/%X (timeline %u)", + (uint32) (xlogpos >> 32), (uint32) xlogpos, + timeline); time_to_stop = true; return true; } @@ -136,9 +138,9 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished) * timeline, but it's close enough for reporting purposes. */ if (verbose && prevtimeline != 0 && prevtimeline != timeline) - fprintf(stderr, _("%s: switched to timeline %u at %X/%X\n"), - progname, timeline, - (uint32) (prevpos >> 32), (uint32) prevpos); + pg_log_info("switched to timeline %u at %X/%X", + timeline, + (uint32) (prevpos >> 32), (uint32) prevpos); prevtimeline = timeline; prevpos = xlogpos; @@ -146,8 +148,7 @@ stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished) if (time_to_stop) { if (verbose) - fprintf(stderr, _("%s: received interrupt signal, exiting\n"), - progname); + pg_log_info("received interrupt signal, exiting"); return true; } return false; @@ -166,9 +167,8 @@ get_destination_dir(char *dest_folder) dir = opendir(dest_folder); if (dir == NULL) { - fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), - progname, basedir, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not open directory \"%s\": %m", basedir); + exit(1); } return dir; @@ -184,9 +184,8 @@ close_destination_dir(DIR *dest_dir, char *dest_folder) Assert(dest_dir != NULL && dest_folder != NULL); if (closedir(dest_dir)) { - fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"), - progname, dest_folder, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not close directory \"%s\": %m", dest_folder); + exit(1); } } @@ -265,16 +264,14 @@ FindStreamingStart(uint32 *tli) snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name); if (stat(fullpath, &statbuf) != 0) { - fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), - progname, fullpath, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not stat file \"%s\": %m", fullpath); + exit(1); } if (statbuf.st_size != WalSegSz) { - fprintf(stderr, - _("%s: segment file \"%s\" has incorrect size %d, skipping\n"), - progname, dirent->d_name, (int) statbuf.st_size); + pg_log_warning("segment file \"%s\" has incorrect size %d, skipping", + dirent->d_name, (int) statbuf.st_size); continue; } } @@ -284,27 +281,33 @@ FindStreamingStart(uint32 *tli) char buf[4]; int bytes_out; char fullpath[MAXPGPATH * 2]; + int r; snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name); - fd = open(fullpath, O_RDONLY | PG_BINARY); + fd = open(fullpath, O_RDONLY | PG_BINARY, 0); if (fd < 0) { - fprintf(stderr, _("%s: could not open compressed file \"%s\": %s\n"), - progname, fullpath, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not open compressed file \"%s\": %m", + fullpath); + exit(1); } if (lseek(fd, (off_t) (-4), SEEK_END) < 0) { - fprintf(stderr, _("%s: could not seek in compressed file \"%s\": %s\n"), - progname, fullpath, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not seek in compressed file \"%s\": %m", + fullpath); + exit(1); } - if (read(fd, (char *) buf, sizeof(buf)) != sizeof(buf)) + r = read(fd, (char *) buf, sizeof(buf)); + if (r != sizeof(buf)) { - fprintf(stderr, _("%s: could not read compressed file \"%s\": %s\n"), - progname, fullpath, strerror(errno)); - disconnect_and_exit(1); + if (r < 0) + pg_log_error("could not read compressed file \"%s\": %m", + fullpath); + else + pg_log_error("could not read compressed file \"%s\": read %d of %zu", + fullpath, r, sizeof(buf)); + exit(1); } close(fd); @@ -313,9 +316,8 @@ FindStreamingStart(uint32 *tli) if (bytes_out != WalSegSz) { - fprintf(stderr, - _("%s: compressed segment file \"%s\" has incorrect uncompressed size %d, skipping\n"), - progname, dirent->d_name, bytes_out); + pg_log_warning("compressed segment file \"%s\" has incorrect uncompressed size %d, skipping", + dirent->d_name, bytes_out); continue; } } @@ -333,9 +335,8 @@ FindStreamingStart(uint32 *tli) if (errno) { - fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), - progname, basedir, strerror(errno)); - disconnect_and_exit(1); + pg_log_error("could not read directory \"%s\": %m", basedir); + exit(1); } close_destination_dir(dir, basedir); @@ -352,7 +353,7 @@ FindStreamingStart(uint32 *tli) if (!high_ispartial) high_segno++; - XLogSegNoOffsetToRecPtr(high_segno, 0, high_ptr, WalSegSz); + XLogSegNoOffsetToRecPtr(high_segno, 0, WalSegSz, high_ptr); *tli = high_tli; return high_ptr; @@ -389,7 +390,7 @@ StreamLog(void) * There's no hope of recovering from a version mismatch, so don't * retry. */ - disconnect_and_exit(1); + exit(1); } /* @@ -398,7 +399,7 @@ StreamLog(void) * existing output directory. */ if (!RunIdentifySystem(conn, NULL, &servertli, &serverpos, NULL)) - disconnect_and_exit(1); + exit(1); /* * Figure out where to start streaming. @@ -419,10 +420,9 @@ StreamLog(void) * Start the replication */ if (verbose) - fprintf(stderr, - _("%s: starting log streaming at %X/%X (timeline %u)\n"), - progname, (uint32) (stream.startpos >> 32), (uint32) stream.startpos, - stream.timeline); + pg_log_info("starting log streaming at %X/%X (timeline %u)", + (uint32) (stream.startpos >> 32), (uint32) stream.startpos, + stream.timeline); stream.stream_stop = stop_streaming; stream.stop_socket = PGINVALID_SOCKET; @@ -439,13 +439,12 @@ StreamLog(void) if (!stream.walmethod->finish()) { - fprintf(stderr, - _("%s: could not finish writing WAL files: %s\n"), - progname, strerror(errno)); + pg_log_info("could not finish writing WAL files: %m"); return; } PQfinish(conn); + conn = NULL; FreeWalDirectoryMethod(); pg_free(stream.walmethod); @@ -500,6 +499,7 @@ main(int argc, char **argv) uint32 hi, lo; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup")); @@ -535,8 +535,7 @@ main(int argc, char **argv) case 'p': if (atoi(optarg) <= 0) { - fprintf(stderr, _("%s: invalid port number \"%s\"\n"), - progname, optarg); + pg_log_error("invalid port number \"%s\"", optarg); exit(1); } dbport = pg_strdup(optarg); @@ -554,8 +553,7 @@ main(int argc, char **argv) standby_message_timeout = atoi(optarg) * 1000; if (standby_message_timeout < 0) { - fprintf(stderr, _("%s: invalid status interval \"%s\"\n"), - progname, optarg); + pg_log_error("invalid status interval \"%s\"", optarg); exit(1); } break; @@ -565,9 +563,7 @@ main(int argc, char **argv) case 'E': if (sscanf(optarg, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse end position \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse end position \"%s\"", optarg); exit(1); } endpos = ((uint64) hi) << 32 | lo; @@ -582,8 +578,7 @@ main(int argc, char **argv) compresslevel = atoi(optarg); if (compresslevel < 0 || compresslevel > 9) { - fprintf(stderr, _("%s: invalid compression level \"%s\"\n"), - progname, optarg); + pg_log_error("invalid compression level \"%s\"", optarg); exit(1); } break; @@ -619,9 +614,8 @@ main(int argc, char **argv) */ if (optind < argc) { - fprintf(stderr, - _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -629,7 +623,7 @@ main(int argc, char **argv) if (do_drop_slot && do_create_slot) { - fprintf(stderr, _("%s: cannot use --create-slot together with --drop-slot\n"), progname); + pg_log_error("cannot use --create-slot together with --drop-slot"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -638,8 +632,8 @@ main(int argc, char **argv) if (replication_slot == NULL && (do_drop_slot || do_create_slot)) { /* translator: second %s is an option name */ - fprintf(stderr, _("%s: %s needs a slot to be specified using --slot\n"), progname, - do_drop_slot ? "--drop-slot" : "--create-slot"); + pg_log_error("%s needs a slot to be specified using --slot", + do_drop_slot ? "--drop-slot" : "--create-slot"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -647,7 +641,7 @@ main(int argc, char **argv) if (synchronous && !do_sync) { - fprintf(stderr, _("%s: cannot use --synchronous together with --no-sync\n"), progname); + pg_log_error("cannot use --synchronous together with --no-sync"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -658,7 +652,7 @@ main(int argc, char **argv) */ if (basedir == NULL && !do_drop_slot && !do_create_slot) { - fprintf(stderr, _("%s: no target directory specified\n"), progname); + pg_log_error("no target directory specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -667,9 +661,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBZ if (compresslevel != 0) { - fprintf(stderr, - _("%s: this build does not support compression\n"), - progname); + pg_log_error("this build does not support compression"); exit(1); } #endif @@ -695,6 +687,7 @@ main(int argc, char **argv) if (!conn) /* error message already written in GetConnection() */ exit(1); + atexit(disconnect_atexit); /* * Run IDENTIFY_SYSTEM to make sure we've successfully have established a @@ -702,7 +695,7 @@ main(int argc, char **argv) * connection. */ if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name)) - disconnect_and_exit(1); + exit(1); /* * Set umask so that directories/files are created with the same @@ -716,7 +709,7 @@ main(int argc, char **argv) /* determine remote server's xlog segment size */ if (!RetrieveWalSegSize(conn)) - disconnect_and_exit(1); + exit(1); /* * Check that there is a database associated with connection, none should @@ -724,10 +717,9 @@ main(int argc, char **argv) */ if (db_name) { - fprintf(stderr, - _("%s: replication connection using slot \"%s\" is unexpectedly database specific\n"), - progname, replication_slot); - disconnect_and_exit(1); + pg_log_error("replication connection using slot \"%s\" is unexpectedly database specific", + replication_slot); + exit(1); } /* @@ -736,27 +728,23 @@ main(int argc, char **argv) if (do_drop_slot) { if (verbose) - fprintf(stderr, - _("%s: dropping replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("dropping replication slot \"%s\"", replication_slot); if (!DropReplicationSlot(conn, replication_slot)) - disconnect_and_exit(1); - disconnect_and_exit(0); + exit(1); + exit(0); } /* Create a replication slot */ if (do_create_slot) { if (verbose) - fprintf(stderr, - _("%s: creating replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("creating replication slot \"%s\"", replication_slot); if (!CreateReplicationSlot(conn, replication_slot, NULL, false, true, false, slot_exists_ok)) - disconnect_and_exit(1); - disconnect_and_exit(0); + exit(1); + exit(0); } /* @@ -777,15 +765,14 @@ main(int argc, char **argv) } else if (noloop) { - fprintf(stderr, _("%s: disconnected\n"), progname); + pg_log_error("disconnected"); exit(1); } else { - fprintf(stderr, /* translator: check source for value for %d */ - _("%s: disconnected; waiting %d seconds to try again\n"), - progname, RECONNECT_SLEEP_TIME); + pg_log_info("disconnected; waiting %d seconds to try again", + RECONNECT_SLEEP_TIME); pg_usleep(RECONNECT_SLEEP_TIME * 1000000); } } diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c index ef85c9af4c7..af29dd7651a 100644 --- a/src/bin/pg_basebackup/pg_recvlogical.c +++ b/src/bin/pg_basebackup/pg_recvlogical.c @@ -3,7 +3,7 @@ * pg_recvlogical.c - receive data from a logical decoding slot in a streaming * fashion and write it to a local file. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/pg_recvlogical.c @@ -25,6 +25,7 @@ #include "access/xlog_internal.h" #include "common/file_perm.h" #include "common/fe_memutils.h" +#include "common/logging.h" #include "getopt_long.h" #include "libpq-fe.h" #include "libpq/pqsignal.h" @@ -65,10 +66,9 @@ static XLogRecPtr output_fsync_lsn = InvalidXLogRecPtr; static void usage(void); static void StreamLogicalLog(void); -static void disconnect_and_exit(int code) pg_attribute_noreturn(); static bool flushAndSendFeedback(PGconn *conn, TimestampTz *now); static void prepareToTerminate(PGconn *conn, XLogRecPtr endpos, - bool keepalive, XLogRecPtr lsn); + bool keepalive, XLogRecPtr lsn); static void usage(void) @@ -106,7 +106,7 @@ usage(void) printf(_(" -U, --username=NAME connect as specified database user\n")); printf(_(" -w, --no-password never prompt for password\n")); printf(_(" -W, --password force password prompt (should happen automatically)\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } /* @@ -132,12 +132,10 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested) return true; if (verbose) - fprintf(stderr, - _("%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n"), - progname, - (uint32) (output_written_lsn >> 32), (uint32) output_written_lsn, - (uint32) (output_fsync_lsn >> 32), (uint32) output_fsync_lsn, - replication_slot); + pg_log_info("confirming write up to %X/%X, flush to %X/%X (slot %s)", + (uint32) (output_written_lsn >> 32), (uint32) output_written_lsn, + (uint32) (output_fsync_lsn >> 32), (uint32) output_fsync_lsn, + replication_slot); replybuf[len] = 'r'; len += 1; @@ -158,8 +156,8 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested) if (PQputCopyData(conn, replybuf, len) <= 0 || PQflush(conn)) { - fprintf(stderr, _("%s: could not send feedback packet: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not send feedback packet: %s", + PQerrorMessage(conn)); return false; } @@ -167,12 +165,10 @@ sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested) } static void -disconnect_and_exit(int code) +disconnect_atexit(void) { if (conn != NULL) PQfinish(conn); - - exit(code); } static bool @@ -196,10 +192,8 @@ OutputFsync(TimestampTz now) if (fsync(outfd) != 0) { - fprintf(stderr, - _("%s: could not fsync log file \"%s\": %s\n"), - progname, outfile, strerror(errno)); - return false; + pg_log_fatal("could not fsync file \"%s\": %m", outfile); + exit(1); } return true; @@ -235,10 +229,9 @@ StreamLogicalLog(void) * Start the replication */ if (verbose) - fprintf(stderr, - _("%s: starting log streaming at %X/%X (slot %s)\n"), - progname, (uint32) (startpos >> 32), (uint32) startpos, - replication_slot); + pg_log_info("starting log streaming at %X/%X (slot %s)", + (uint32) (startpos >> 32), (uint32) startpos, + replication_slot); /* Initiate the replication stream at specified location */ appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X", @@ -268,8 +261,8 @@ StreamLogicalLog(void) res = PQexec(conn, query->data); if (PQresultStatus(res) != PGRES_COPY_BOTH) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, query->data, PQresultErrorMessage(res)); + pg_log_error("could not send replication command \"%s\": %s", + query->data, PQresultErrorMessage(res)); PQclear(res); goto error; } @@ -277,9 +270,7 @@ StreamLogicalLog(void) resetPQExpBuffer(query); if (verbose) - fprintf(stderr, - _("%s: streaming initiated\n"), - progname); + pg_log_info("streaming initiated"); while (!time_to_abort) { @@ -343,16 +334,12 @@ StreamLogicalLog(void) S_IRUSR | S_IWUSR); if (outfd == -1) { - fprintf(stderr, - _("%s: could not open log file \"%s\": %s\n"), - progname, outfile, strerror(errno)); + pg_log_error("could not open log file \"%s\": %m", outfile); goto error; } if (fstat(outfd, &statbuf) != 0) - fprintf(stderr, - _("%s: could not stat file \"%s\": %s\n"), - progname, outfile, strerror(errno)); + pg_log_error("could not stat file \"%s\": %m", outfile); output_isfile = S_ISREG(statbuf.st_mode) && !isatty(outfd); } @@ -373,9 +360,7 @@ StreamLogicalLog(void) if (PQsocket(conn) < 0) { - fprintf(stderr, - _("%s: invalid socket: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("invalid socket: %s", PQerrorMessage(conn)); goto error; } @@ -428,17 +413,15 @@ StreamLogicalLog(void) } else if (r < 0) { - fprintf(stderr, _("%s: select() failed: %s\n"), - progname, strerror(errno)); + pg_log_error("select() failed: %m"); goto error; } /* Else there is actually data on the socket */ if (PQconsumeInput(conn) == 0) { - fprintf(stderr, - _("%s: could not receive data from WAL stream: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not receive data from WAL stream: %s", + PQerrorMessage(conn)); goto error; } continue; @@ -451,8 +434,8 @@ StreamLogicalLog(void) /* Failure while reading the copy stream */ if (r == -2) { - fprintf(stderr, _("%s: could not read COPY data: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not read COPY data: %s", + PQerrorMessage(conn)); goto error; } @@ -479,8 +462,7 @@ StreamLogicalLog(void) if (r < pos + 1) { - fprintf(stderr, _("%s: streaming header too small: %d\n"), - progname, r); + pg_log_error("streaming header too small: %d", r); goto error; } replyRequested = copybuf[pos]; @@ -515,8 +497,8 @@ StreamLogicalLog(void) } else if (copybuf[0] != 'w') { - fprintf(stderr, _("%s: unrecognized streaming header: \"%c\"\n"), - progname, copybuf[0]); + pg_log_error("unrecognized streaming header: \"%c\"", + copybuf[0]); goto error; } @@ -531,8 +513,7 @@ StreamLogicalLog(void) hdr_len += 8; /* sendTime */ if (r < hdr_len + 1) { - fprintf(stderr, _("%s: streaming header too small: %d\n"), - progname, r); + pg_log_error("streaming header too small: %d", r); goto error; } @@ -570,10 +551,8 @@ StreamLogicalLog(void) if (ret < 0) { - fprintf(stderr, - _("%s: could not write %u bytes to log file \"%s\": %s\n"), - progname, bytes_left, outfile, - strerror(errno)); + pg_log_error("could not write %u bytes to log file \"%s\": %m", + bytes_left, outfile); goto error; } @@ -584,10 +563,8 @@ StreamLogicalLog(void) if (write(outfd, "\n", 1) != 1) { - fprintf(stderr, - _("%s: could not write %u bytes to log file \"%s\": %s\n"), - progname, 1, outfile, - strerror(errno)); + pg_log_error("could not write %u bytes to log file \"%s\": %m", + 1, outfile); goto error; } @@ -614,9 +591,8 @@ StreamLogicalLog(void) } else if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, - _("%s: unexpected termination of replication stream: %s"), - progname, PQresultErrorMessage(res)); + pg_log_error("unexpected termination of replication stream: %s", + PQresultErrorMessage(res)); goto error; } PQclear(res); @@ -629,8 +605,7 @@ StreamLogicalLog(void) OutputFsync(t); if (close(outfd) != 0) - fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), - progname, outfile, strerror(errno)); + pg_log_error("could not close file \"%s\": %m", outfile); } outfd = -1; error: @@ -708,6 +683,7 @@ main(int argc, char **argv) lo; char *db_name; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup")); @@ -739,8 +715,7 @@ main(int argc, char **argv) fsync_interval = atoi(optarg) * 1000; if (fsync_interval < 0) { - fprintf(stderr, _("%s: invalid fsync interval \"%s\"\n"), - progname, optarg); + pg_log_error("invalid fsync interval \"%s\"", optarg); exit(1); } break; @@ -760,8 +735,7 @@ main(int argc, char **argv) case 'p': if (atoi(optarg) <= 0) { - fprintf(stderr, _("%s: invalid port number \"%s\"\n"), - progname, optarg); + pg_log_error("invalid port number \"%s\"", optarg); exit(1); } dbport = pg_strdup(optarg); @@ -779,9 +753,7 @@ main(int argc, char **argv) case 'I': if (sscanf(optarg, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse start position \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse start position \"%s\"", optarg); exit(1); } startpos = ((uint64) hi) << 32 | lo; @@ -789,9 +761,7 @@ main(int argc, char **argv) case 'E': if (sscanf(optarg, "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse end position \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse end position \"%s\"", optarg); exit(1); } endpos = ((uint64) hi) << 32 | lo; @@ -823,8 +793,7 @@ main(int argc, char **argv) standby_message_timeout = atoi(optarg) * 1000; if (standby_message_timeout < 0) { - fprintf(stderr, _("%s: invalid status interval \"%s\"\n"), - progname, optarg); + pg_log_error("invalid status interval \"%s\"", optarg); exit(1); } break; @@ -861,9 +830,8 @@ main(int argc, char **argv) */ if (optind < argc) { - fprintf(stderr, - _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -874,7 +842,7 @@ main(int argc, char **argv) */ if (replication_slot == NULL) { - fprintf(stderr, _("%s: no slot specified\n"), progname); + pg_log_error("no slot specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -882,7 +850,7 @@ main(int argc, char **argv) if (do_start_slot && outfile == NULL) { - fprintf(stderr, _("%s: no target file specified\n"), progname); + pg_log_error("no target file specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -890,7 +858,7 @@ main(int argc, char **argv) if (!do_drop_slot && dbname == NULL) { - fprintf(stderr, _("%s: no database specified\n"), progname); + pg_log_error("no database specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -898,7 +866,7 @@ main(int argc, char **argv) if (!do_drop_slot && !do_create_slot && !do_start_slot) { - fprintf(stderr, _("%s: at least one action needs to be specified\n"), progname); + pg_log_error("at least one action needs to be specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -906,7 +874,7 @@ main(int argc, char **argv) if (do_drop_slot && (do_create_slot || do_start_slot)) { - fprintf(stderr, _("%s: cannot use --create-slot or --start together with --drop-slot\n"), progname); + pg_log_error("cannot use --create-slot or --start together with --drop-slot"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -914,7 +882,7 @@ main(int argc, char **argv) if (startpos != InvalidXLogRecPtr && (do_create_slot || do_drop_slot)) { - fprintf(stderr, _("%s: cannot use --create-slot or --drop-slot together with --startpos\n"), progname); + pg_log_error("cannot use --create-slot or --drop-slot together with --startpos"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -922,9 +890,7 @@ main(int argc, char **argv) if (endpos != InvalidXLogRecPtr && !do_start_slot) { - fprintf(stderr, - _("%s: --endpos may only be specified with --start\n"), - progname); + pg_log_error("--endpos may only be specified with --start"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -944,20 +910,19 @@ main(int argc, char **argv) if (!conn) /* Error message already written in GetConnection() */ exit(1); + atexit(disconnect_atexit); /* * Run IDENTIFY_SYSTEM to make sure we connected using a database specific * replication connection. */ if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name)) - disconnect_and_exit(1); + exit(1); if (db_name == NULL) { - fprintf(stderr, - _("%s: could not establish database-specific replication connection\n"), - progname); - disconnect_and_exit(1); + pg_log_error("could not establish database-specific replication connection"); + exit(1); } /* @@ -974,30 +939,26 @@ main(int argc, char **argv) if (do_drop_slot) { if (verbose) - fprintf(stderr, - _("%s: dropping replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("dropping replication slot \"%s\"", replication_slot); if (!DropReplicationSlot(conn, replication_slot)) - disconnect_and_exit(1); + exit(1); } /* Create a replication slot. */ if (do_create_slot) { if (verbose) - fprintf(stderr, - _("%s: creating replication slot \"%s\"\n"), - progname, replication_slot); + pg_log_info("creating replication slot \"%s\"", replication_slot); if (!CreateReplicationSlot(conn, replication_slot, plugin, false, false, false, slot_exists_ok)) - disconnect_and_exit(1); + exit(1); startpos = InvalidXLogRecPtr; } if (!do_start_slot) - disconnect_and_exit(0); + exit(0); /* Stream loop */ while (true) @@ -1009,19 +970,18 @@ main(int argc, char **argv) * We've been Ctrl-C'ed or reached an exit limit condition. That's * not an error, so exit without an errorcode. */ - disconnect_and_exit(0); + exit(0); } else if (noloop) { - fprintf(stderr, _("%s: disconnected\n"), progname); + pg_log_error("disconnected"); exit(1); } else { - fprintf(stderr, /* translator: check source for value for %d */ - _("%s: disconnected; waiting %d seconds to try again\n"), - progname, RECONNECT_SLEEP_TIME); + pg_log_info("disconnected; waiting %d seconds to try again", + RECONNECT_SLEEP_TIME); pg_usleep(RECONNECT_SLEEP_TIME * 1000000); } } @@ -1060,13 +1020,11 @@ prepareToTerminate(PGconn *conn, XLogRecPtr endpos, bool keepalive, XLogRecPtr l if (verbose) { if (keepalive) - fprintf(stderr, "%s: endpos %X/%X reached by keepalive\n", - progname, - (uint32) (endpos >> 32), (uint32) endpos); + pg_log_info("end position %X/%X reached by keepalive", + (uint32) (endpos >> 32), (uint32) endpos); else - fprintf(stderr, "%s: endpos %X/%X reached by record at %X/%X\n", - progname, (uint32) (endpos >> 32), (uint32) (endpos), - (uint32) (lsn >> 32), (uint32) lsn); - + pg_log_info("end position %X/%X reached by WAL record at %X/%X", + (uint32) (endpos >> 32), (uint32) (endpos), + (uint32) (lsn >> 32), (uint32) lsn); } } diff --git a/src/bin/pg_basebackup/po/de.po b/src/bin/pg_basebackup/po/de.po index 2ed355883be..78b006a1748 100644 --- a/src/bin/pg_basebackup/po/de.po +++ b/src/bin/pg_basebackup/po/de.po @@ -1,24 +1,39 @@ # German message translation file for pg_basebackup -# Copyright (C) 2011 - 2017 PostgreSQL Global Development Group +# Copyright (C) 2011 - 2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2011 - 2017. +# Peter Eisentraut , 2011 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 16:45+0000\n" -"PO-Revision-Date: 2017-08-04 16:00-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: Peter Eisentraut \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-16 16:16+0000\n" +"PO-Revision-Date: 2019-06-16 22:49+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " + #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 #, c-format @@ -30,120 +45,120 @@ msgstr "Speicher aufgebraucht\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 -#: pg_receivewal.c:252 pg_recvlogical.c:353 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#: pg_receivewal.c:267 pg_recvlogical.c:342 #, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: konnte »stat« für Datei »%s« nicht ausführen: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" -#: ../../common/file_utils.c:162 pg_receivewal.c:153 +#: ../../common/file_utils.c:160 pg_receivewal.c:170 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht öffnen: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" -#: ../../common/file_utils.c:198 pg_receivewal.c:320 +#: ../../common/file_utils.c:194 pg_receivewal.c:338 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 pg_basebackup.c:1761 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht öffnen: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 -#: receivelog.c:802 receivelog.c:1059 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#: pg_recvlogical.c:195 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht fsyncen: %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:377 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht in »%s« umbenennen: %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m" -#: pg_basebackup.c:159 +#: pg_basebackup.c:171 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s: entferne Datenverzeichnis »%s«\n" +msgid "removing data directory \"%s\"" +msgstr "entferne Datenverzeichnis »%s«" -#: pg_basebackup.c:162 +#: pg_basebackup.c:173 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s: konnte Datenverzeichnis nicht entfernen\n" +msgid "failed to remove data directory" +msgstr "konnte Datenverzeichnis nicht entfernen" -#: pg_basebackup.c:168 +#: pg_basebackup.c:177 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s: entferne Inhalt des Datenverzeichnisses »%s«\n" +msgid "removing contents of data directory \"%s\"" +msgstr "entferne Inhalt des Datenverzeichnisses »%s«" -#: pg_basebackup.c:171 +#: pg_basebackup.c:179 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s: konnte Inhalt des Datenverzeichnisses nicht entfernen\n" +msgid "failed to remove contents of data directory" +msgstr "konnte Inhalt des Datenverzeichnisses nicht entfernen" -#: pg_basebackup.c:177 +#: pg_basebackup.c:184 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s: entferne WAL-Verzeichnis »%s«\n" +msgid "removing WAL directory \"%s\"" +msgstr "entferne WAL-Verzeichnis »%s«" -#: pg_basebackup.c:180 +#: pg_basebackup.c:186 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s: konnte WAL-Verzeichnis nicht entfernen\n" +msgid "failed to remove WAL directory" +msgstr "konnte WAL-Verzeichnis nicht entfernen" -#: pg_basebackup.c:186 +#: pg_basebackup.c:190 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s: entferne Inhalt des WAL-Verzeichnisses »%s«\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "entferne Inhalt des WAL-Verzeichnisses »%s«" -#: pg_basebackup.c:189 +#: pg_basebackup.c:192 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s: konnte Inhalt des WAL-Verzeichnisses nicht entfernen\n" +msgid "failed to remove contents of WAL directory" +msgstr "konnte Inhalt des WAL-Verzeichnisses nicht entfernen" -#: pg_basebackup.c:197 +#: pg_basebackup.c:198 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s: Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" -#: pg_basebackup.c:202 +#: pg_basebackup.c:201 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s: WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt" -#: pg_basebackup.c:208 +#: pg_basebackup.c:205 #, c-format -msgid "%s: changes to tablespace directories will not be undone\n" -msgstr "%s: Änderungen in Tablespace-Verzeichnissen werden nicht rückgängig gemacht\n" +msgid "changes to tablespace directories will not be undone" +msgstr "Änderungen in Tablespace-Verzeichnissen werden nicht rückgängig gemacht" -#: pg_basebackup.c:250 +#: pg_basebackup.c:246 #, c-format -msgid "%s: directory name too long\n" -msgstr "%s: Verzeichnisname zu lang\n" +msgid "directory name too long" +msgstr "Verzeichnisname zu lang" -#: pg_basebackup.c:260 +#: pg_basebackup.c:256 #, c-format -msgid "%s: multiple \"=\" signs in tablespace mapping\n" -msgstr "%s: mehrere »=«-Zeichen im Tablespace-Mapping\n" +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "mehrere »=«-Zeichen im Tablespace-Mapping" -#: pg_basebackup.c:273 +#: pg_basebackup.c:268 #, c-format -msgid "%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" -msgstr "%s: ungültiges Tablespace-Mapping-Format »%s«, muss »ALTES_VERZ=NEUES_VERZ« sein\n" +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "ungültiges Tablespace-Mapping-Format »%s«, muss »ALTES_VERZ=NEUES_VERZ« sein" -#: pg_basebackup.c:286 +#: pg_basebackup.c:280 #, c-format -msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s: altes Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s\n" +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "altes Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" -#: pg_basebackup.c:293 +#: pg_basebackup.c:287 #, c-format -msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s: neues Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s\n" +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "neues Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s" -#: pg_basebackup.c:327 +#: pg_basebackup.c:326 #, c-format msgid "" "%s takes a base backup of a running PostgreSQL server.\n" @@ -152,36 +167,34 @@ msgstr "" "%s erzeugt eine Basissicherung eines laufenden PostgreSQL-Servers.\n" "\n" -#: pg_basebackup.c:329 pg_receivewal.c:76 pg_recvlogical.c:77 +#: pg_basebackup.c:328 pg_receivewal.c:81 pg_recvlogical.c:78 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_basebackup.c:330 pg_receivewal.c:77 pg_recvlogical.c:78 +#: pg_basebackup.c:329 pg_receivewal.c:82 pg_recvlogical.c:79 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPTION]...\n" -#: pg_basebackup.c:331 +#: pg_basebackup.c:330 #, c-format msgid "" "\n" "Options controlling the output:\n" -msgstr "" -"\n" -"Optionen, die die Ausgabe kontrollieren:\n" +msgstr "\nOptionen die die Ausgabe kontrollieren:\n" -#: pg_basebackup.c:332 +#: pg_basebackup.c:331 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" msgstr " -D, --pgdata=VERZ Basissicherung in dieses Verzeichnis empfangen\n" -#: pg_basebackup.c:333 +#: pg_basebackup.c:332 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" msgstr " -F, --format=p|t Ausgabeformat (plain (Voreinstellung), tar)\n" -#: pg_basebackup.c:334 +#: pg_basebackup.c:333 #, c-format msgid "" " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" @@ -190,26 +203,16 @@ msgstr "" " -r, --max-rate=RATE maximale Transferrate für Übertragung des Datenver-\n" " zeichnisses (in kB/s, oder Suffix »k« oder »M« abgeben)\n" -#: pg_basebackup.c:336 +#: pg_basebackup.c:335 #, c-format msgid "" " -R, --write-recovery-conf\n" -" write recovery.conf for replication\n" +" write configuration for replication\n" msgstr "" " -R, --write-recovery-conf\n" -" recovery.conf für Replikation schreiben\n" - -#: pg_basebackup.c:338 pg_receivewal.c:84 -#, c-format -msgid " -S, --slot=SLOTNAME replication slot to use\n" -msgstr " -S, --slot=SLOTNAME zu verwendender Replikations-Slot\n" +" Konfiguration für Replikation schreiben\n" -#: pg_basebackup.c:339 -#, c-format -msgid " --no-slot prevent creation of temporary replication slot\n" -msgstr " --no-slot keinen temporären Replikations-Slot erzeugen\n" - -#: pg_basebackup.c:340 +#: pg_basebackup.c:337 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -218,7 +221,12 @@ msgstr "" " -T, --tablespace-mapping=ALTES_VERZ=NEUES_VERZ\n" " Tablespace in ALTES_VERZ nach NEUES_VERZ verlagern\n" -#: pg_basebackup.c:342 +#: pg_basebackup.c:339 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n" + +#: pg_basebackup.c:340 #, c-format msgid "" " -X, --wal-method=none|fetch|stream\n" @@ -227,22 +235,17 @@ msgstr "" " -X, --wal-method=none|fetch|stream\n" " benötigte WAL-Dateien mit angegebener Methode einbeziehen\n" -#: pg_basebackup.c:344 -#, c-format -msgid " --waldir=WALDIR location for the write-ahead log directory\n" -msgstr " --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n" - -#: pg_basebackup.c:345 +#: pg_basebackup.c:342 #, c-format msgid " -z, --gzip compress tar output\n" msgstr " -z, --gzip Tar-Ausgabe komprimieren\n" -#: pg_basebackup.c:346 +#: pg_basebackup.c:343 #, c-format msgid " -Z, --compress=0-9 compress tar output with given compression level\n" msgstr " -Z, --compress=0-9 Tar-Ausgabe mit angegebenem Niveau komprimieren\n" -#: pg_basebackup.c:347 +#: pg_basebackup.c:344 #, c-format msgid "" "\n" @@ -251,7 +254,7 @@ msgstr "" "\n" "Allgemeine Optionen:\n" -#: pg_basebackup.c:348 +#: pg_basebackup.c:345 #, c-format msgid "" " -c, --checkpoint=fast|spread\n" @@ -260,44 +263,68 @@ msgstr "" " -c, --checkpoint=fast|spread\n" " schnelles oder verteiltes Checkpointing einstellen\n" -#: pg_basebackup.c:350 +#: pg_basebackup.c:347 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot Replikations-Slot erzeugen\n" + +#: pg_basebackup.c:348 #, c-format msgid " -l, --label=LABEL set backup label\n" msgstr " -l, --label=LABEL Backup-Label setzen\n" -#: pg_basebackup.c:351 +#: pg_basebackup.c:349 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean nach Fehlern nicht aufräumen\n" -#: pg_basebackup.c:352 +#: pg_basebackup.c:350 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" msgstr "" " -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" " geschrieben sind\n" -#: pg_basebackup.c:353 +#: pg_basebackup.c:351 #, c-format msgid " -P, --progress show progress information\n" msgstr " -P, --progress Fortschrittsinformationen zeigen\n" -#: pg_basebackup.c:354 pg_receivewal.c:86 pg_recvlogical.c:98 +#: pg_basebackup.c:352 pg_receivewal.c:91 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=SLOTNAME zu verwendender Replikations-Slot\n" + +#: pg_basebackup.c:353 pg_receivewal.c:93 pg_recvlogical.c:99 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose »Verbose«-Modus\n" -#: pg_basebackup.c:355 pg_receivewal.c:87 pg_recvlogical.c:99 +#: pg_basebackup.c:354 pg_receivewal.c:94 pg_recvlogical.c:100 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_basebackup.c:356 pg_receivewal.c:89 pg_recvlogical.c:100 +#: pg_basebackup.c:355 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot keinen temporären Replikations-Slot erzeugen\n" + +#: pg_basebackup.c:356 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" Prüfsummen nicht überprüfen\n" + +#: pg_basebackup.c:358 pg_receivewal.c:96 pg_recvlogical.c:101 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_basebackup.c:357 pg_receivewal.c:90 pg_recvlogical.c:101 +#: pg_basebackup.c:359 pg_receivewal.c:97 pg_recvlogical.c:102 #, c-format msgid "" "\n" @@ -306,22 +333,22 @@ msgstr "" "\n" "Verbindungsoptionen:\n" -#: pg_basebackup.c:358 pg_receivewal.c:91 +#: pg_basebackup.c:360 pg_receivewal.c:98 #, c-format msgid " -d, --dbname=CONNSTR connection string\n" msgstr " -d, --dbname=VERBDG Verbindungsparameter\n" -#: pg_basebackup.c:359 pg_receivewal.c:92 pg_recvlogical.c:103 +#: pg_basebackup.c:361 pg_receivewal.c:99 pg_recvlogical.c:104 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: pg_basebackup.c:360 pg_receivewal.c:93 pg_recvlogical.c:104 +#: pg_basebackup.c:362 pg_receivewal.c:100 pg_recvlogical.c:105 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT Portnummer des Datenbankservers\n" -#: pg_basebackup.c:361 +#: pg_basebackup.c:363 #, c-format msgid "" " -s, --status-interval=INTERVAL\n" @@ -330,434 +357,461 @@ msgstr "" " -s, --status-interval=INTERVALL\n" " Zeit zwischen an Server gesendeten Statuspaketen (in Sekunden)\n" -#: pg_basebackup.c:363 pg_receivewal.c:94 pg_recvlogical.c:105 +#: pg_basebackup.c:365 pg_receivewal.c:101 pg_recvlogical.c:106 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: pg_basebackup.c:364 pg_receivewal.c:95 pg_recvlogical.c:106 +#: pg_basebackup.c:366 pg_receivewal.c:102 pg_recvlogical.c:107 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: pg_basebackup.c:365 pg_receivewal.c:96 pg_recvlogical.c:107 +#: pg_basebackup.c:367 pg_receivewal.c:103 pg_recvlogical.c:108 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" -#: pg_basebackup.c:366 pg_receivewal.c:100 pg_recvlogical.c:108 +#: pg_basebackup.c:368 pg_receivewal.c:107 pg_recvlogical.c:109 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Berichten Sie Fehler an .\n" +"Berichten Sie Fehler an .\n" + +#: pg_basebackup.c:411 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "konnte nicht aus bereiter Pipe lesen: %m" + +#: pg_basebackup.c:417 pg_basebackup.c:545 pg_basebackup.c:2099 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "konnte Write-Ahead-Log-Position »%s« nicht interpretieren" -#: pg_basebackup.c:409 +#: pg_basebackup.c:510 pg_receivewal.c:442 #, c-format -msgid "%s: could not read from ready pipe: %s\n" -msgstr "%s: konnte nicht aus bereiter Pipe lesen: %s\n" +msgid "could not finish writing WAL files: %m" +msgstr "konnte WAL-Dateien nicht zu Ende schreiben: %m" -#: pg_basebackup.c:417 pg_basebackup.c:552 pg_basebackup.c:2005 -#: streamutil.c:286 +#: pg_basebackup.c:557 #, c-format -msgid "%s: could not parse write-ahead log location \"%s\"\n" -msgstr "%s: konnte Write-Ahead-Log-Position »%s« nicht interpretieren\n" +msgid "could not create pipe for background process: %m" +msgstr "konnte Pipe für Hintergrundprozess nicht erzeugen: %m" -#: pg_basebackup.c:515 pg_receivewal.c:428 +#: pg_basebackup.c:592 #, c-format -msgid "%s: could not finish writing WAL files: %s\n" -msgstr "%s: konnte WAL-Dateien nicht zu Ende schreiben: %s\n" +msgid "created temporary replication slot \"%s\"" +msgstr "temporärer Replikations-Slot »%s« wurde erzeugt" -#: pg_basebackup.c:565 +#: pg_basebackup.c:595 #, c-format -msgid "%s: could not create pipe for background process: %s\n" -msgstr "%s: konnte Pipe für Hintergrundprozess nicht erzeugen: %s\n" +msgid "created replication slot \"%s\"" +msgstr "Replikations-Slot »%s« wurde erzeugt" -#: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1423 +#: pg_basebackup.c:615 pg_basebackup.c:668 pg_basebackup.c:1503 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht erzeugen: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: pg_basebackup.c:624 +#: pg_basebackup.c:633 #, c-format -msgid "%s: could not create background process: %s\n" -msgstr "%s: konnte Hintergrundprozess nicht erzeugen: %s\n" +msgid "could not create background process: %m" +msgstr "konnte Hintergrundprozess nicht erzeugen: %m" -#: pg_basebackup.c:636 +#: pg_basebackup.c:645 #, c-format -msgid "%s: could not create background thread: %s\n" -msgstr "%s: konnte Hintergrund-Thread nicht erzeugen: %s\n" +msgid "could not create background thread: %m" +msgstr "konnte Hintergrund-Thread nicht erzeugen: %m" -#: pg_basebackup.c:684 +#: pg_basebackup.c:689 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s: Verzeichnis »%s« existiert aber ist nicht leer\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "Verzeichnis »%s« existiert aber ist nicht leer" -#: pg_basebackup.c:692 +#: pg_basebackup.c:696 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" +msgid "could not access directory \"%s\": %m" +msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m" -#: pg_basebackup.c:754 +#: pg_basebackup.c:757 #, c-format msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" msgstr[0] "%*s/%s kB (100%%), %d/%d Tablespace %*s" msgstr[1] "%*s/%s kB (100%%), %d/%d Tablespaces %*s" -#: pg_basebackup.c:766 +#: pg_basebackup.c:769 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace (%s%-*.*s)" msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces (%s%-*.*s)" -#: pg_basebackup.c:782 +#: pg_basebackup.c:785 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace" msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces" -#: pg_basebackup.c:804 +#: pg_basebackup.c:809 #, c-format -msgid "%s: transfer rate \"%s\" is not a valid value\n" -msgstr "%s: Transferrate »%s« ist kein gültiger Wert\n" +msgid "transfer rate \"%s\" is not a valid value" +msgstr "Transferrate »%s« ist kein gültiger Wert" -#: pg_basebackup.c:811 +#: pg_basebackup.c:814 #, c-format -msgid "%s: invalid transfer rate \"%s\": %s\n" -msgstr "%s: ungültige Transferrate »%s«: %s\n" +msgid "invalid transfer rate \"%s\": %m" +msgstr "ungültige Transferrate »%s«: %m" -#: pg_basebackup.c:821 +#: pg_basebackup.c:823 #, c-format -msgid "%s: transfer rate must be greater than zero\n" -msgstr "%s: Transferrate muss größer als null sein\n" +msgid "transfer rate must be greater than zero" +msgstr "Transferrate muss größer als null sein" #: pg_basebackup.c:855 #, c-format -msgid "%s: invalid --max-rate unit: \"%s\"\n" -msgstr "%s: ungültige Einheit für --max-rate: »%s«\n" +msgid "invalid --max-rate unit: \"%s\"" +msgstr "ungültige Einheit für --max-rate: »%s«" -#: pg_basebackup.c:864 +#: pg_basebackup.c:862 #, c-format -msgid "%s: transfer rate \"%s\" exceeds integer range\n" -msgstr "%s: Transferrate »%s« überschreitet Bereich für ganze Zahlen\n" +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "Transferrate »%s« überschreitet Bereich für ganze Zahlen" -#: pg_basebackup.c:876 +#: pg_basebackup.c:872 #, c-format -msgid "%s: transfer rate \"%s\" is out of range\n" -msgstr "%s: Transferrate »%s« ist außerhalb des gültigen Bereichs\n" +msgid "transfer rate \"%s\" is out of range" +msgstr "Transferrate »%s« ist außerhalb des gültigen Bereichs" -#: pg_basebackup.c:900 +#: pg_basebackup.c:894 #, c-format -msgid "%s: could not write to compressed file \"%s\": %s\n" -msgstr "%s: konnte nicht in komprimierte Datei »%s« schreiben: %s\n" +msgid "could not write to compressed file \"%s\": %s" +msgstr "konnte nicht in komprimierte Datei »%s« schreiben: %s" -#: pg_basebackup.c:910 pg_basebackup.c:1517 pg_basebackup.c:1683 +#: pg_basebackup.c:904 pg_basebackup.c:1592 pg_basebackup.c:1767 #, c-format -msgid "%s: could not write to file \"%s\": %s\n" -msgstr "%s: konnte nicht in Datei »%s« schreiben: %s\n" +msgid "could not write to file \"%s\": %m" +msgstr "konnte nicht in Datei »%s« schreiben: %m" -#: pg_basebackup.c:969 pg_basebackup.c:990 pg_basebackup.c:1018 +#: pg_basebackup.c:969 pg_basebackup.c:989 pg_basebackup.c:1016 #, c-format -msgid "%s: could not set compression level %d: %s\n" -msgstr "%s: konnte Komprimierungsniveau %d nicht setzen: %s\n" +msgid "could not set compression level %d: %s" +msgstr "konnte Komprimierungsniveau %d nicht setzen: %s" -#: pg_basebackup.c:1039 +#: pg_basebackup.c:1036 #, c-format -msgid "%s: could not create compressed file \"%s\": %s\n" -msgstr "%s: konnte komprimierte Datei »%s« nicht erzeugen: %s\n" +msgid "could not create compressed file \"%s\": %s" +msgstr "konnte komprimierte Datei »%s« nicht erzeugen: %s" -#: pg_basebackup.c:1050 pg_basebackup.c:1477 pg_basebackup.c:1676 +#: pg_basebackup.c:1047 pg_basebackup.c:1553 pg_basebackup.c:1779 #, c-format -msgid "%s: could not create file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht erzeugen: %s\n" +msgid "could not create file \"%s\": %m" +msgstr "konnte Datei »%s« nicht erstellen: %m" -#: pg_basebackup.c:1062 pg_basebackup.c:1330 +#: pg_basebackup.c:1058 pg_basebackup.c:1412 #, c-format -msgid "%s: could not get COPY data stream: %s" -msgstr "%s: konnte COPY-Datenstrom nicht empfangen: %s" +msgid "could not get COPY data stream: %s" +msgstr "konnte COPY-Datenstrom nicht empfangen: %s" -#: pg_basebackup.c:1119 +#: pg_basebackup.c:1143 #, c-format -msgid "%s: could not close compressed file \"%s\": %s\n" -msgstr "%s: konnte komprimierte Datei »%s« nicht schließen: %s\n" +msgid "could not close compressed file \"%s\": %s" +msgstr "konnte komprimierte Datei »%s« nicht schließen: %s" -#: pg_basebackup.c:1132 pg_recvlogical.c:631 receivelog.c:221 receivelog.c:306 -#: receivelog.c:712 +#: pg_basebackup.c:1155 pg_recvlogical.c:608 #, c-format -msgid "%s: could not close file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht schließen: %s\n" +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" -#: pg_basebackup.c:1143 pg_basebackup.c:1359 pg_recvlogical.c:453 -#: receivelog.c:1007 +#: pg_basebackup.c:1166 pg_basebackup.c:1441 pg_recvlogical.c:437 +#: receivelog.c:968 #, c-format -msgid "%s: could not read COPY data: %s" -msgstr "%s: konnte COPY-Daten nicht lesen: %s" +msgid "could not read COPY data: %s" +msgstr "konnte COPY-Daten nicht lesen: %s" -#: pg_basebackup.c:1373 +#: pg_basebackup.c:1455 #, c-format -msgid "%s: invalid tar block header size: %d\n" -msgstr "%s: ungültige Tar-Block-Kopf-Größe: %d\n" +msgid "invalid tar block header size: %d" +msgstr "ungültige Tar-Block-Kopf-Größe: %d" -#: pg_basebackup.c:1431 +#: pg_basebackup.c:1510 #, c-format -msgid "%s: could not set permissions on directory \"%s\": %s\n" -msgstr "%s: konnte Zugriffsrechte des Verzeichnisses »%s« nicht setzen: %s\n" +msgid "could not set permissions on directory \"%s\": %m" +msgstr "konnte Zugriffsrechte für Verzeichnis »%s« nicht setzen: %m" -#: pg_basebackup.c:1455 +#: pg_basebackup.c:1533 #, c-format -msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" -msgstr "%s: konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %s\n" +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m" -#: pg_basebackup.c:1464 +#: pg_basebackup.c:1540 #, c-format -msgid "%s: unrecognized link indicator \"%c\"\n" -msgstr "%s: unbekannter Verknüpfungsindikator »%c«\n" +msgid "unrecognized link indicator \"%c\"" +msgstr "unbekannter Verknüpfungsindikator »%c«" -#: pg_basebackup.c:1484 +#: pg_basebackup.c:1559 #, c-format -msgid "%s: could not set permissions on file \"%s\": %s\n" -msgstr "%s: konnte Rechte der Datei »%s« nicht setzen: %s\n" +msgid "could not set permissions on file \"%s\": %m" +msgstr "konnte Zugriffsrechte von Datei »%s« nicht setzen: %m" -#: pg_basebackup.c:1543 +#: pg_basebackup.c:1616 #, c-format -msgid "%s: COPY stream ended before last file was finished\n" -msgstr "%s: COPY-Strom endete vor dem Ende der letzten Datei\n" +msgid "COPY stream ended before last file was finished" +msgstr "COPY-Strom endete vor dem Ende der letzten Datei" -#: pg_basebackup.c:1571 pg_basebackup.c:1591 pg_basebackup.c:1598 -#: pg_basebackup.c:1651 +#: pg_basebackup.c:1643 pg_basebackup.c:1663 pg_basebackup.c:1677 +#: pg_basebackup.c:1728 #, c-format -msgid "%s: out of memory\n" -msgstr "%s: Speicher aufgebraucht\n" +msgid "out of memory" +msgstr "Speicher aufgebraucht" -#: pg_basebackup.c:1724 +#: pg_basebackup.c:1820 #, c-format -msgid "%s: incompatible server version %s\n" -msgstr "%s: inkompatible Serverversion %s\n" +msgid "incompatible server version %s" +msgstr "inkompatible Serverversion %s" -#: pg_basebackup.c:1739 +#: pg_basebackup.c:1835 #, c-format -msgid "HINT: use -X none or -X fetch to disable log streaming\n" -msgstr "TIPP: -X none oder -X fetch verwenden um Log-Streaming abzuschalten\n" +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "TIPP: -X none oder -X fetch verwenden um Log-Streaming abzuschalten" -#: pg_basebackup.c:1765 +#: pg_basebackup.c:1860 #, c-format -msgid "%s: initiating base backup, waiting for checkpoint to complete\n" -msgstr "%s: Basissicherung eingeleitet, warte auf Abschluss des Checkpoints\n" +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "Basissicherung eingeleitet, warte auf Abschluss des Checkpoints" -#: pg_basebackup.c:1783 pg_recvlogical.c:270 receivelog.c:490 receivelog.c:561 -#: receivelog.c:601 streamutil.c:256 streamutil.c:364 streamutil.c:410 +#: pg_basebackup.c:1884 pg_recvlogical.c:264 receivelog.c:484 receivelog.c:533 +#: receivelog.c:572 streamutil.c:299 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 #, c-format -msgid "%s: could not send replication command \"%s\": %s" -msgstr "%s: konnte Replikationsbefehl »%s« nicht senden: %s" +msgid "could not send replication command \"%s\": %s" +msgstr "konnte Replikationsbefehl »%s« nicht senden: %s" -#: pg_basebackup.c:1794 +#: pg_basebackup.c:1895 #, c-format -msgid "%s: could not initiate base backup: %s" -msgstr "%s: konnte Basissicherung nicht starten: %s" +msgid "could not initiate base backup: %s" +msgstr "konnte Basissicherung nicht starten: %s" -#: pg_basebackup.c:1801 +#: pg_basebackup.c:1901 #, c-format -msgid "%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: unerwartete Antwort auf Befehl BASE_BACKUP: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet\n" +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Antwort auf Befehl BASE_BACKUP: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: pg_basebackup.c:1809 +#: pg_basebackup.c:1909 #, c-format -msgid "%s: checkpoint completed\n" -msgstr "%s: Checkpoint abgeschlossen\n" +msgid "checkpoint completed" +msgstr "Checkpoint abgeschlossen" -#: pg_basebackup.c:1824 +#: pg_basebackup.c:1924 #, c-format -msgid "%s: write-ahead log start point: %s on timeline %u\n" -msgstr "%s: Write-Ahead-Log-Startpunkt: %s auf Zeitleiste %u\n" +msgid "write-ahead log start point: %s on timeline %u" +msgstr "Write-Ahead-Log-Startpunkt: %s auf Zeitleiste %u" -#: pg_basebackup.c:1833 +#: pg_basebackup.c:1933 #, c-format -msgid "%s: could not get backup header: %s" -msgstr "%s: konnte Kopf der Sicherung nicht empfangen: %s" +msgid "could not get backup header: %s" +msgstr "konnte Kopf der Sicherung nicht empfangen: %s" -#: pg_basebackup.c:1839 +#: pg_basebackup.c:1939 #, c-format -msgid "%s: no data returned from server\n" -msgstr "%s: keine Daten vom Server zurückgegeben\n" +msgid "no data returned from server" +msgstr "keine Daten vom Server zurückgegeben" -#: pg_basebackup.c:1871 +#: pg_basebackup.c:1970 #, c-format -msgid "%s: can only write single tablespace to stdout, database has %d\n" -msgstr "%s: kann nur einen einzelnen Tablespace auf die Standardausgabe schreiben, Datenbank hat %d\n" +msgid "can only write single tablespace to stdout, database has %d" +msgstr "kann nur einen einzelnen Tablespace auf die Standardausgabe schreiben, Datenbank hat %d" -#: pg_basebackup.c:1883 +#: pg_basebackup.c:1982 #, c-format -msgid "%s: starting background WAL receiver\n" -msgstr "%s: Hintergrund-WAL-Receiver wird gestartet\n" +msgid "starting background WAL receiver" +msgstr "Hintergrund-WAL-Receiver wird gestartet" -#: pg_basebackup.c:1914 +#: pg_basebackup.c:2012 #, c-format -msgid "%s: could not get write-ahead log end position from server: %s" -msgstr "%s: konnte Write-Ahead-Log-Endposition nicht vom Server empfangen: %s" +msgid "could not get write-ahead log end position from server: %s" +msgstr "konnte Write-Ahead-Log-Endposition nicht vom Server empfangen: %s" -#: pg_basebackup.c:1921 +#: pg_basebackup.c:2018 #, c-format -msgid "%s: no write-ahead log end position returned from server\n" -msgstr "%s: keine Write-Ahead-Log-Endposition vom Server zurückgegeben\n" +msgid "no write-ahead log end position returned from server" +msgstr "keine Write-Ahead-Log-Endposition vom Server zurückgegeben" -#: pg_basebackup.c:1927 +#: pg_basebackup.c:2023 #, c-format -msgid "%s: write-ahead log end point: %s\n" -msgstr "%s: Write-Ahead-Log-Endposition: %s\n" +msgid "write-ahead log end point: %s" +msgstr "Write-Ahead-Log-Endposition: %s" -#: pg_basebackup.c:1933 +#: pg_basebackup.c:2034 #, c-format -msgid "%s: final receive failed: %s" -msgstr "%s: letztes Empfangen fehlgeschlagen: %s" +msgid "checksum error occurred" +msgstr "ein Prüfsummenfehler ist aufgetreten" -#: pg_basebackup.c:1957 +#: pg_basebackup.c:2039 #, c-format -msgid "%s: waiting for background process to finish streaming ...\n" -msgstr "%s: warte bis Hintergrundprozess Streaming beendet hat ...\n" +msgid "final receive failed: %s" +msgstr "letztes Empfangen fehlgeschlagen: %s" -#: pg_basebackup.c:1963 +#: pg_basebackup.c:2063 #, c-format -msgid "%s: could not send command to background pipe: %s\n" -msgstr "%s: konnte Befehl nicht an Hintergrund-Pipe senden: %s\n" +msgid "waiting for background process to finish streaming ..." +msgstr "warte bis Hintergrundprozess Streaming beendet hat ..." -#: pg_basebackup.c:1972 +#: pg_basebackup.c:2068 #, c-format -msgid "%s: could not wait for child process: %s\n" -msgstr "%s: konnte nicht auf Kindprozess warten: %s\n" +msgid "could not send command to background pipe: %m" +msgstr "konnte Befehl nicht an Hintergrund-Pipe senden: %m" -#: pg_basebackup.c:1978 +#: pg_basebackup.c:2076 #, c-format -msgid "%s: child %d died, expected %d\n" -msgstr "%s: Kindprozess %d endete, aber %d wurde erwartet\n" +msgid "could not wait for child process: %m" +msgstr "konnte nicht auf Kindprozess warten: %m" -#: pg_basebackup.c:1984 +#: pg_basebackup.c:2081 #, c-format -msgid "%s: child process did not exit normally\n" -msgstr "%s: Kindprozess hat nicht normal beendet\n" +msgid "child %d died, expected %d" +msgstr "Kindprozess %d endete, aber %d wurde erwartet" -#: pg_basebackup.c:1990 +#: pg_basebackup.c:2086 streamutil.c:94 #, c-format -msgid "%s: child process exited with error %d\n" -msgstr "%s: Kindprozess hat mit Fehler %d beendet\n" +msgid "%s" +msgstr "%s" -#: pg_basebackup.c:2017 +#: pg_basebackup.c:2111 #, c-format -msgid "%s: could not wait for child thread: %s\n" -msgstr "%s: konnte nicht auf Kind-Thread warten: %s\n" +msgid "could not wait for child thread: %m" +msgstr "konnte nicht auf Kind-Thread warten: %m" -#: pg_basebackup.c:2024 +#: pg_basebackup.c:2117 #, c-format -msgid "%s: could not get child thread exit status: %s\n" -msgstr "%s: konnte Statuscode des Kind-Threads nicht ermitteln: %s\n" +msgid "could not get child thread exit status: %m" +msgstr "konnte Statuscode des Kind-Threads nicht ermitteln: %m" -#: pg_basebackup.c:2030 +#: pg_basebackup.c:2122 #, c-format -msgid "%s: child thread exited with error %u\n" -msgstr "%s: Kind-Thread hat mit Fehler %u beendet\n" +msgid "child thread exited with error %u" +msgstr "Kind-Thread hat mit Fehler %u beendet" -#: pg_basebackup.c:2068 +#: pg_basebackup.c:2150 +#, c-format +msgid "syncing data to disk ..." +msgstr "synchronisiere Daten auf Festplatte ..." + +#: pg_basebackup.c:2163 #, c-format -msgid "%s: base backup completed\n" -msgstr "%s: Basissicherung abgeschlossen\n" +msgid "base backup completed" +msgstr "Basissicherung abgeschlossen" -#: pg_basebackup.c:2145 +#: pg_basebackup.c:2244 #, c-format -msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" -msgstr "%s: ungültiges Ausgabeformat »%s«, muss »plain« oder »tar« sein\n" +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "ungültiges Ausgabeformat »%s«, muss »plain« oder »tar« sein\n" -#: pg_basebackup.c:2190 +#: pg_basebackup.c:2288 #, c-format -msgid "%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n" -msgstr "%s: ungültige Option »%s« für --wal-method, muss »fetch«, »stream« oder »none« sein\n" +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "ungültige Option »%s« für --wal-method, muss »fetch«, »stream« oder »none« sein" -#: pg_basebackup.c:2218 pg_receivewal.c:556 +#: pg_basebackup.c:2316 #, c-format -msgid "%s: invalid compression level \"%s\"\n" -msgstr "%s: ungültiges Komprimierungsniveau »%s«\n" +msgid "invalid compression level \"%s\"\n" +msgstr "ungültiges Komprimierungsniveau »%s«\n" -#: pg_basebackup.c:2230 +#: pg_basebackup.c:2327 #, c-format -msgid "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" -msgstr "%s: ungültiges Checkpoint-Argument »%s«, muss »fast« oder »spread« sein\n" +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "ungültiges Checkpoint-Argument »%s«, muss »fast« oder »spread« sein" -#: pg_basebackup.c:2257 pg_receivewal.c:538 pg_recvlogical.c:825 +#: pg_basebackup.c:2354 pg_receivewal.c:556 pg_recvlogical.c:796 #, c-format -msgid "%s: invalid status interval \"%s\"\n" -msgstr "%s: ungültiges Statusintervall »%s«\n" +msgid "invalid status interval \"%s\"" +msgstr "ungültiges Statusintervall »%s«" -#: pg_basebackup.c:2273 pg_basebackup.c:2287 pg_basebackup.c:2298 -#: pg_basebackup.c:2311 pg_basebackup.c:2321 pg_basebackup.c:2331 -#: pg_basebackup.c:2343 pg_basebackup.c:2357 pg_basebackup.c:2368 -#: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 -#: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 -#: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 -#: pg_recvlogical.c:893 pg_recvlogical.c:901 pg_recvlogical.c:909 -#: pg_recvlogical.c:917 pg_recvlogical.c:927 +#: pg_basebackup.c:2372 pg_basebackup.c:2385 pg_basebackup.c:2396 +#: pg_basebackup.c:2407 pg_basebackup.c:2415 pg_basebackup.c:2423 +#: pg_basebackup.c:2433 pg_basebackup.c:2446 pg_basebackup.c:2454 +#: pg_basebackup.c:2465 pg_basebackup.c:2475 pg_receivewal.c:606 +#: pg_receivewal.c:619 pg_receivewal.c:627 pg_receivewal.c:637 +#: pg_receivewal.c:645 pg_receivewal.c:656 pg_recvlogical.c:822 +#: pg_recvlogical.c:835 pg_recvlogical.c:846 pg_recvlogical.c:854 +#: pg_recvlogical.c:862 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_basebackup.c:2285 pg_receivewal.c:591 pg_recvlogical.c:864 +#: pg_basebackup.c:2383 pg_receivewal.c:617 pg_recvlogical.c:833 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_basebackup.c:2395 pg_receivewal.c:655 +#, c-format +msgid "no target directory specified" +msgstr "kein Zielverzeichnis angegeben" + +#: pg_basebackup.c:2406 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "only tar mode backups can be compressed" +msgstr "nur Sicherungen im Tar-Modus können komprimiert werden" -#: pg_basebackup.c:2297 pg_receivewal.c:621 +#: pg_basebackup.c:2414 #, c-format -msgid "%s: no target directory specified\n" -msgstr "%s: kein Zielverzeichnis angegeben\n" +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "im Tar-Modus können Write-Ahead-Logs nicht auf Standardausgabe geschrieben werden" -#: pg_basebackup.c:2309 +#: pg_basebackup.c:2422 #, c-format -msgid "%s: only tar mode backups can be compressed\n" -msgstr "%s: nur Sicherungen im Tar-Modus können komprimiert werden\n" +msgid "replication slots can only be used with WAL streaming" +msgstr "Replikations-Slots können nur mit WAL-Streaming verwendet werden" -#: pg_basebackup.c:2319 +#: pg_basebackup.c:2432 #, c-format -msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" -msgstr "%s: im Tar-Modus können Write-Ahead-Logs nicht auf Standardausgabe geschrieben werden\n" +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot kann nicht zusammen mit einem Slot-Namen verwendet werden" -#: pg_basebackup.c:2329 +#. translator: second %s is an option name +#: pg_basebackup.c:2444 pg_receivewal.c:635 #, c-format -msgid "%s: replication slots can only be used with WAL streaming\n" -msgstr "%s: Replikations-Slots können nur mit WAL-Streaming verwendet werden\n" +msgid "%s needs a slot to be specified using --slot" +msgstr "für %s muss ein Slot mit --slot angegeben werden" -#: pg_basebackup.c:2341 +#: pg_basebackup.c:2453 #, c-format -msgid "%s: --no-slot cannot be used with slot name\n" -msgstr "%s: --no-slot kann nicht zusammen mit einem Slot-Namen verwendet werden\n" +msgid "--create-slot and --no-slot are incompatible options" +msgstr "--create-slot und --no-slot sind inkompatible Optionen" -#: pg_basebackup.c:2355 +#: pg_basebackup.c:2464 #, c-format -msgid "%s: WAL directory location can only be specified in plain mode\n" -msgstr "%s: WAL-Verzeichnis kann nur im »plain«-Modus angegeben werden\n" +msgid "WAL directory location can only be specified in plain mode" +msgstr "WAL-Verzeichnis kann nur im »plain«-Modus angegeben werden" -#: pg_basebackup.c:2366 +#: pg_basebackup.c:2474 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" -msgstr "%s: WAL-Verzeichnis muss absoluten Pfad haben\n" +msgid "WAL directory location must be an absolute path" +msgstr "WAL-Verzeichnis muss absoluten Pfad haben" -#: pg_basebackup.c:2378 pg_receivewal.c:631 +#: pg_basebackup.c:2484 pg_receivewal.c:664 #, c-format -msgid "%s: this build does not support compression\n" -msgstr "%s: diese Installation unterstützt keine Komprimierung\n" +msgid "this build does not support compression" +msgstr "diese Installation unterstützt keine Komprimierung" -#: pg_basebackup.c:2418 +#: pg_basebackup.c:2538 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s: konnte symbolische Verknüpfung »%s« nicht erzeugen: %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" -#: pg_basebackup.c:2423 +#: pg_basebackup.c:2542 #, c-format -msgid "%s: symlinks are not supported on this platform\n" -msgstr "%s: symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt\n" +msgid "symlinks are not supported on this platform" +msgstr "symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" -#: pg_receivewal.c:74 +#: pg_receivewal.c:79 #, c-format msgid "" "%s receives PostgreSQL streaming write-ahead logs.\n" @@ -766,7 +820,7 @@ msgstr "" "%s empfängt PostgreSQL-Write-Ahead-Logs.\n" "\n" -#: pg_receivewal.c:78 pg_recvlogical.c:83 +#: pg_receivewal.c:83 pg_recvlogical.c:84 #, c-format msgid "" "\n" @@ -775,22 +829,34 @@ msgstr "" "\n" "Optionen:\n" -#: pg_receivewal.c:79 +#: pg_receivewal.c:84 #, c-format msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr " -D, --directory=VERZ Write-Ahead-Log-Dateien in dieses Verzeichnis empfangen\n" -#: pg_receivewal.c:80 pg_recvlogical.c:88 +#: pg_receivewal.c:85 pg_recvlogical.c:85 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN nach Empfang der angegebenen LSN beenden\n" + +#: pg_receivewal.c:86 pg_recvlogical.c:89 #, c-format msgid " --if-not-exists do not error if slot already exists when creating a slot\n" msgstr " --if-not-exists keinen Fehler ausgeben, wenn Slot beim Erzeugen schon existiert\n" -#: pg_receivewal.c:81 pg_recvlogical.c:90 +#: pg_receivewal.c:87 pg_recvlogical.c:91 #, c-format msgid " -n, --no-loop do not loop on connection lost\n" msgstr " -n, --no-loop bei Verbindungsverlust nicht erneut probieren\n" -#: pg_receivewal.c:82 pg_recvlogical.c:95 +#: pg_receivewal.c:88 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_receivewal.c:89 pg_recvlogical.c:96 #, c-format msgid "" " -s, --status-interval=SECS\n" @@ -799,17 +865,17 @@ msgstr "" " -s, --status-interval=SEK\n" " Zeit zwischen an Server gesendeten Statuspaketen (Standard: %d)\n" -#: pg_receivewal.c:85 +#: pg_receivewal.c:92 #, c-format msgid " --synchronous flush write-ahead log immediately after writing\n" msgstr " --synchronous Write-Ahead-Log sofort nach dem Schreiben flushen\n" -#: pg_receivewal.c:88 +#: pg_receivewal.c:95 #, c-format msgid " -Z, --compress=0-9 compress logs with given compression level\n" msgstr " -Z, --compress=0-9 Logs mit angegebenem Niveau komprimieren\n" -#: pg_receivewal.c:97 +#: pg_receivewal.c:104 #, c-format msgid "" "\n" @@ -818,109 +884,128 @@ msgstr "" "\n" "Optionale Aktionen:\n" -#: pg_receivewal.c:98 pg_recvlogical.c:80 +#: pg_receivewal.c:105 pg_recvlogical.c:81 #, c-format msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" msgstr " --create-slot neuen Replikations-Slot erzeugen (Slot-Name siehe --slot)\n" -#: pg_receivewal.c:99 pg_recvlogical.c:81 +#: pg_receivewal.c:106 pg_recvlogical.c:82 #, c-format msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" msgstr " --drop-slot Replikations-Slot löschen (Slot-Name siehe --slot)\n" -#: pg_receivewal.c:111 +#: pg_receivewal.c:118 #, c-format -msgid "%s: finished segment at %X/%X (timeline %u)\n" -msgstr "%s: Segment bei %X/%X abgeschlossen (Zeitleiste %u)\n" +msgid "finished segment at %X/%X (timeline %u)" +msgstr "Segment bei %X/%X abgeschlossen (Zeitleiste %u)" -#: pg_receivewal.c:124 +#: pg_receivewal.c:125 #, c-format -msgid "%s: switched to timeline %u at %X/%X\n" -msgstr "%s: auf Zeitleiste %u umgeschaltet bei %X/%X\n" +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "Log-Streaming gestoppt bei %X/%X (Zeitleiste %u)" -#: pg_receivewal.c:133 +#: pg_receivewal.c:141 #, c-format -msgid "%s: received interrupt signal, exiting\n" -msgstr "%s: Interrupt-Signal erhalten, beende\n" +msgid "switched to timeline %u at %X/%X" +msgstr "auf Zeitleiste %u umgeschaltet bei %X/%X" -#: pg_receivewal.c:171 +#: pg_receivewal.c:151 #, c-format -msgid "%s: could not close directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht schließen: %s\n" +msgid "received interrupt signal, exiting" +msgstr "Interrupt-Signal erhalten, beende" -#: pg_receivewal.c:260 +#: pg_receivewal.c:187 #, c-format -msgid "%s: segment file \"%s\" has incorrect size %d, skipping\n" -msgstr "%s: Segmentdatei »%s« hat falsche Größe %d, wird übersprungen\n" +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: pg_receivewal.c:277 +#: pg_receivewal.c:273 #, c-format -msgid "%s: could not open compressed file \"%s\": %s\n" -msgstr "%s: konnte komprimierte Datei »%s« nicht öffnen: %s\n" +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "Segmentdatei »%s« hat falsche Größe %d, wird übersprungen" -#: pg_receivewal.c:283 +#: pg_receivewal.c:291 #, c-format -msgid "%s: could not seek compressed file \"%s\": %s\n" -msgstr "%s: konnte Positionszeiger in komprimierter Datei »%s« nicht setzen: %s\n" +msgid "could not open compressed file \"%s\": %m" +msgstr "konnte komprimierte Datei »%s« nicht öffnen: %m" -#: pg_receivewal.c:289 +#: pg_receivewal.c:297 #, c-format -msgid "%s: could not read compressed file \"%s\": %s\n" -msgstr "%s: konnte komprimierte Datei »%s« nicht lesen: %s\n" +msgid "could not seek in compressed file \"%s\": %m" +msgstr "konnte Positionszeiger in komprimierter Datei »%s« nicht setzen: %m" -#: pg_receivewal.c:301 +#: pg_receivewal.c:305 #, c-format -msgid "%s: compressed segment file \"%s\" has incorrect uncompressed size %d, skipping\n" -msgstr "%s: komprimierte Segmentdatei »%s« hat falsche unkomprimierte Größe %d, wird übersprungen\n" +msgid "could not read compressed file \"%s\": %m" +msgstr "konnte komprimierte Datei »%s« nicht lesen: %m" -#: pg_receivewal.c:407 +#: pg_receivewal.c:308 #, c-format -msgid "%s: starting log streaming at %X/%X (timeline %u)\n" -msgstr "%s: starte Log-Streaming bei %X/%X (Zeitleiste %u)\n" +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" -#: pg_receivewal.c:519 pg_recvlogical.c:762 +#: pg_receivewal.c:319 #, c-format -msgid "%s: invalid port number \"%s\"\n" -msgstr "%s: ungültige Portnummer »%s«\n" +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "komprimierte Segmentdatei »%s« hat falsche unkomprimierte Größe %d, wird übersprungen" -#: pg_receivewal.c:600 +#: pg_receivewal.c:423 #, c-format -msgid "%s: cannot use --create-slot together with --drop-slot\n" -msgstr "%s: --create-slot kann nicht zusammen mit --drop-slot verwendet werden\n" +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "starte Log-Streaming bei %X/%X (Zeitleiste %u)" -#. translator: second %s is an option name -#: pg_receivewal.c:609 +#: pg_receivewal.c:538 pg_recvlogical.c:738 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "ungültige Portnummer »%s«" + +#: pg_receivewal.c:566 pg_recvlogical.c:764 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "konnte Endposition »%s« nicht parsen" + +#: pg_receivewal.c:581 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "ungültiges Komprimierungsniveau »%s«" + +#: pg_receivewal.c:626 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot kann nicht zusammen mit --drop-slot verwendet werden" + +#: pg_receivewal.c:644 #, c-format -msgid "%s: %s needs a slot to be specified using --slot\n" -msgstr "%s: für %s muss ein Slot mit --slot angegeben werden\n" +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous kann nicht zusammen mit --no-sync verwendet werden" -#: pg_receivewal.c:674 +#: pg_receivewal.c:720 #, c-format -msgid "%s: replication connection using slot \"%s\" is unexpectedly database specific\n" -msgstr "%s: Replikationsverbindung, die Slot »%s« verwendet, ist unerwarteterweise datenbankspezifisch\n" +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "Replikationsverbindung, die Slot »%s« verwendet, ist unerwarteterweise datenbankspezifisch" -#: pg_receivewal.c:686 pg_recvlogical.c:967 +#: pg_receivewal.c:731 pg_recvlogical.c:942 #, c-format -msgid "%s: dropping replication slot \"%s\"\n" -msgstr "%s: lösche Replikations-Slot »%s«\n" +msgid "dropping replication slot \"%s\"" +msgstr "lösche Replikations-Slot »%s«" -#: pg_receivewal.c:699 pg_recvlogical.c:979 +#: pg_receivewal.c:742 pg_recvlogical.c:952 #, c-format -msgid "%s: creating replication slot \"%s\"\n" -msgstr "%s: erzeuge Replikations-Slot »%s«\n" +msgid "creating replication slot \"%s\"" +msgstr "erzeuge Replikations-Slot »%s«" -#: pg_receivewal.c:726 pg_recvlogical.c:1005 +#: pg_receivewal.c:768 pg_recvlogical.c:977 #, c-format -msgid "%s: disconnected\n" -msgstr "%s: Verbindung beendet\n" +msgid "disconnected" +msgstr "Verbindung beendet" #. translator: check source for value for %d -#: pg_receivewal.c:733 pg_recvlogical.c:1012 +#: pg_receivewal.c:774 pg_recvlogical.c:983 #, c-format -msgid "%s: disconnected; waiting %d seconds to try again\n" -msgstr "%s: Verbindung beendet; erneuter Versuch in %d Sekunden\n" +msgid "disconnected; waiting %d seconds to try again" +msgstr "Verbindung beendet; erneuter Versuch in %d Sekunden" -#: pg_recvlogical.c:75 +#: pg_recvlogical.c:76 #, c-format msgid "" "%s controls PostgreSQL logical decoding streams.\n" @@ -929,7 +1014,7 @@ msgstr "" "%s kontrolliert logische Dekodierungsströme von PostgreSQL.\n" "\n" -#: pg_recvlogical.c:79 +#: pg_recvlogical.c:80 #, c-format msgid "" "\n" @@ -938,22 +1023,17 @@ msgstr "" "\n" "Auszuführende Aktion:\n" -#: pg_recvlogical.c:82 +#: pg_recvlogical.c:83 #, c-format msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" msgstr " --start Streaming in einem Replikations-Slot starten (Slot-Name siehe --slot)\n" -#: pg_recvlogical.c:84 -#, c-format -msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" -msgstr " -E, --endpos=LSN nach Empfang der angegebenen LSN beenden\n" - -#: pg_recvlogical.c:85 +#: pg_recvlogical.c:86 #, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" msgstr " -f, --file=DATEI Log in diese Datei empfangen, - für Standardausgabe\n" -#: pg_recvlogical.c:86 +#: pg_recvlogical.c:87 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -962,12 +1042,12 @@ msgstr "" " -F --fsync-interval=SEK\n" " Zeit zwischen Fsyncs der Ausgabedatei (Standard: %d)\n" -#: pg_recvlogical.c:89 +#: pg_recvlogical.c:90 #, c-format msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" msgstr " -I, --startpos=LSN wo in einem bestehenden Slot das Streaming starten soll\n" -#: pg_recvlogical.c:91 +#: pg_recvlogical.c:92 #, c-format msgid "" " -o, --option=NAME[=VALUE]\n" @@ -978,339 +1058,377 @@ msgstr "" " Option NAME mit optionalem Wert WERT an den\n" " Ausgabe-Plugin übergeben\n" -#: pg_recvlogical.c:94 +#: pg_recvlogical.c:95 #, c-format msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" msgstr " -P, --plugin=PLUGIN Ausgabe-Plugin PLUGIN verwenden (Standard: %s)\n" -#: pg_recvlogical.c:97 +#: pg_recvlogical.c:98 #, c-format msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" msgstr " -S, --slot=SLOTNAME Name des logischen Replikations-Slots\n" -#: pg_recvlogical.c:102 +#: pg_recvlogical.c:103 #, c-format msgid " -d, --dbname=DBNAME database to connect to\n" msgstr " -d, --dbname=DBNAME Datenbank, mit der verbunden werden soll\n" #: pg_recvlogical.c:135 #, c-format -msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" -msgstr "%s: bestätige Schreiben bis %X/%X, Flush bis %X/%X (Slot %s)\n" +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "bestätige Schreiben bis %X/%X, Flush bis %X/%X (Slot %s)" -#: pg_recvlogical.c:160 receivelog.c:349 +#: pg_recvlogical.c:159 receivelog.c:346 #, c-format -msgid "%s: could not send feedback packet: %s" -msgstr "%s: konnte Rückmeldungspaket nicht senden: %s" +msgid "could not send feedback packet: %s" +msgstr "konnte Rückmeldungspaket nicht senden: %s" -#: pg_recvlogical.c:199 +#: pg_recvlogical.c:232 #, c-format -msgid "%s: could not fsync log file \"%s\": %s\n" -msgstr "%s: konnte Logdatei »%s« nicht fsyncen: %s\n" +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "starte Log-Streaming bei %X/%X (Slot %s)" -#: pg_recvlogical.c:238 +#: pg_recvlogical.c:273 #, c-format -msgid "%s: starting log streaming at %X/%X (slot %s)\n" -msgstr "%s: starte Log-Streaming bei %X/%X (Slot %s)\n" +msgid "streaming initiated" +msgstr "Streaming eingeleitet" -#: pg_recvlogical.c:280 +#: pg_recvlogical.c:337 #, c-format -msgid "%s: streaming initiated\n" -msgstr "%s: Streaming eingeleitet\n" +msgid "could not open log file \"%s\": %m" +msgstr "konnte Logdatei »%s« nicht öffnen: %m" -#: pg_recvlogical.c:346 +#: pg_recvlogical.c:363 receivelog.c:876 #, c-format -msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%s: konnte Logdatei »%s« nicht öffnen: %s\n" +msgid "invalid socket: %s" +msgstr "ungültiges Socket: %s" -#: pg_recvlogical.c:376 receivelog.c:912 +#: pg_recvlogical.c:416 receivelog.c:904 #, c-format -msgid "%s: invalid socket: %s" -msgstr "%s: ungültiges Socket: %s" +msgid "select() failed: %m" +msgstr "select() fehlgeschlagen: %m" -#: pg_recvlogical.c:430 receivelog.c:941 +#: pg_recvlogical.c:423 receivelog.c:954 #, c-format -msgid "%s: select() failed: %s\n" -msgstr "%s: select() fehlgeschlagen: %s\n" +msgid "could not receive data from WAL stream: %s" +msgstr "konnte keine Daten vom WAL-Stream empfangen: %s" -#: pg_recvlogical.c:439 receivelog.c:993 +#: pg_recvlogical.c:465 pg_recvlogical.c:516 receivelog.c:998 receivelog.c:1064 #, c-format -msgid "%s: could not receive data from WAL stream: %s" -msgstr "%s: konnte keine Daten vom WAL-Stream empfangen: %s" +msgid "streaming header too small: %d" +msgstr "Streaming-Header zu klein: %d" -#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1038 -#: receivelog.c:1105 +#: pg_recvlogical.c:500 receivelog.c:836 #, c-format -msgid "%s: streaming header too small: %d\n" -msgstr "%s: Streaming-Header zu klein: %d\n" +msgid "unrecognized streaming header: \"%c\"" +msgstr "unbekannter Streaming-Header: »%c«" -#: pg_recvlogical.c:517 receivelog.c:872 +#: pg_recvlogical.c:554 pg_recvlogical.c:566 #, c-format -msgid "%s: unrecognized streaming header: \"%c\"\n" -msgstr "%s: unbekannter Streaming-Header: »%c«\n" +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "konnte %u Bytes nicht in Logdatei »%s« schreiben: %m" -#: pg_recvlogical.c:573 pg_recvlogical.c:587 +#: pg_recvlogical.c:594 receivelog.c:632 receivelog.c:669 #, c-format -msgid "%s: could not write %u bytes to log file \"%s\": %s\n" -msgstr "%s: konnte %u Bytes nicht in Logdatei »%s« schreiben: %s\n" +msgid "unexpected termination of replication stream: %s" +msgstr "unerwarteter Abbruch des Replikations-Streams: %s" -#: pg_recvlogical.c:617 receivelog.c:665 receivelog.c:703 +#: pg_recvlogical.c:718 #, c-format -msgid "%s: unexpected termination of replication stream: %s" -msgstr "%s: unerwarteter Abbruch des Replikations-Streams: %s" +msgid "invalid fsync interval \"%s\"" +msgstr "ungültiges Fsync-Intervall »%s«" -#: pg_recvlogical.c:741 +#: pg_recvlogical.c:756 #, c-format -msgid "%s: invalid fsync interval \"%s\"\n" -msgstr "%s: ungültiges Fsync-Intervall »%s«\n" +msgid "could not parse start position \"%s\"" +msgstr "konnte Startposition »%s« nicht parsen" -#: pg_recvlogical.c:782 +#: pg_recvlogical.c:845 #, c-format -msgid "%s: could not parse start position \"%s\"\n" -msgstr "%s: konnte Startposition »%s« nicht parsen\n" +msgid "no slot specified" +msgstr "kein Slot angegeben" -#: pg_recvlogical.c:792 +#: pg_recvlogical.c:853 #, c-format -msgid "%s: could not parse end position \"%s\"\n" -msgstr "%s: konnte Endposition »%s« nicht parsen\n" +msgid "no target file specified" +msgstr "keine Zieldatei angegeben" -#: pg_recvlogical.c:876 +#: pg_recvlogical.c:861 #, c-format -msgid "%s: no slot specified\n" -msgstr "%s: kein Slot angegeben\n" +msgid "no database specified" +msgstr "keine Datenbank angegeben" -#: pg_recvlogical.c:884 +#: pg_recvlogical.c:869 #, c-format -msgid "%s: no target file specified\n" -msgstr "%s: keine Zieldatei angegeben\n" +msgid "at least one action needs to be specified" +msgstr "mindestens eine Aktion muss angegeben werden" -#: pg_recvlogical.c:892 +#: pg_recvlogical.c:877 #, c-format -msgid "%s: no database specified\n" -msgstr "%s: keine Datenbank angegeben\n" +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "--create-slot oder --start kann nicht zusammen mit --drop-slot verwendet werden" -#: pg_recvlogical.c:900 +#: pg_recvlogical.c:885 #, c-format -msgid "%s: at least one action needs to be specified\n" -msgstr "%s: mindestens eine Aktion muss angegeben werden\n" +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "--create-slot oder --drop-slot kann nicht zusammen mit --startpos verwendet werden" -#: pg_recvlogical.c:908 +#: pg_recvlogical.c:893 #, c-format -msgid "%s: cannot use --create-slot or --start together with --drop-slot\n" -msgstr "%s: --create-slot oder --start kann nicht zusammen mit --drop-slot verwendet werden\n" +msgid "--endpos may only be specified with --start" +msgstr "--endpos kann nur zusammen mit --start angegeben werden" -#: pg_recvlogical.c:916 +#: pg_recvlogical.c:924 #, c-format -msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" -msgstr "%s: --create-slot oder --drop-slot kann nicht zusammen mit --startpos verwendet werden\n" +msgid "could not establish database-specific replication connection" +msgstr "konnte keine datenbankspezifische Replikationsverbindung herstellen" -#: pg_recvlogical.c:925 +#: pg_recvlogical.c:1023 #, c-format -msgid "%s: --endpos may only be specified with --start\n" -msgstr "%s: --endpos kann nur zusammen mit --start angegeben werden\n" +msgid "endpos %X/%X reached by keepalive" +msgstr "Endposition %X/%X durch Keepalive erreicht" -#: pg_recvlogical.c:957 +#: pg_recvlogical.c:1026 #, c-format -msgid "%s: could not establish database-specific replication connection\n" -msgstr "%s: konnte keine datenbankspezifische Replikationsverbindung herstellen\n" +msgid "endpos %X/%X reached by record at %X/%X" +msgstr "Endposition %X/%X erreicht durch Eintrag bei %X/%X" -#: receivelog.c:71 +#: receivelog.c:72 #, c-format -msgid "%s: could not create archive status file \"%s\": %s\n" -msgstr "%s: konnte Archivstatusdatei »%s« nicht erzeugen: %s\n" +msgid "could not create archive status file \"%s\": %s" +msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %s" #: receivelog.c:119 #, c-format -msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" -msgstr "%s: konnte Größe der Write-Ahead-Log-Datei »%s« nicht ermittlen: %s\n" +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "konnte Größe der Write-Ahead-Log-Datei »%s« nicht ermittlen: %s" + +#: receivelog.c:129 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht öffnen: %s" -#: receivelog.c:130 +#: receivelog.c:137 #, c-format -msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" -msgstr "%s: konnte bestehende Write-Ahead-Log-Datei »%s« nicht öffnen: %s\n" +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht fsyncen: %s" -#: receivelog.c:139 +#: receivelog.c:151 #, c-format -msgid "%s: could not sync existing write-ahead log file \"%s\": %s\n" -msgstr "%s: konnte bestehende Write-Ahead-Log-Datei »%s« nicht syncen: %s\n" +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "Write-Ahead-Log-Datei »%s« hat %d Byte, sollte 0 oder %d sein" +msgstr[1] "Write-Ahead-Log-Datei »%s« hat %d Bytes, sollte 0 oder %d sein" -#: receivelog.c:154 +#: receivelog.c:166 #, c-format -msgid "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" -msgstr "%s: Write-Ahead-Log-Datei »%s« hat %d Bytes, sollte 0 oder %d sein\n" +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %s" -#: receivelog.c:167 +#: receivelog.c:192 #, c-format -msgid "%s: could not open write-ahead log file \"%s\": %s\n" -msgstr "%s: konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %s\n" +msgid "could not determine seek position in file \"%s\": %s" +msgstr "konnte Positionszeiger in Datei »%s« nicht ermitteln: %s" -#: receivelog.c:194 +#: receivelog.c:206 #, c-format -msgid "%s: could not determine seek position in file \"%s\": %s\n" -msgstr "%s: konnte Positionszeiger in Datei »%s« nicht ermitteln: %s\n" +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "»%s%s« wird nicht umbenannt, Segment ist noch nicht vollständig" -#: receivelog.c:209 +#: receivelog.c:218 receivelog.c:303 receivelog.c:678 #, c-format -msgid "%s: not renaming \"%s%s\", segment is not complete\n" -msgstr "%s: »%s%s« wird nicht umbenannt, Segment ist noch nicht vollständig\n" +msgid "could not close file \"%s\": %s" +msgstr "konnte Datei »%s« nicht schließen: %s" -#: receivelog.c:278 +#: receivelog.c:275 #, c-format -msgid "%s: server reported unexpected history file name for timeline %u: %s\n" -msgstr "%s: Server berichtete unerwarteten History-Dateinamen für Zeitleiste %u: %s\n" +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "Server berichtete unerwarteten History-Dateinamen für Zeitleiste %u: %s" -#: receivelog.c:286 +#: receivelog.c:283 #, c-format -msgid "%s: could not create timeline history file \"%s\": %s\n" -msgstr "%s: konnte Zeitleisten-History-Datei »%s« nicht erzeugen: %s\n" +msgid "could not create timeline history file \"%s\": %s" +msgstr "konnte Zeitleisten-History-Datei »%s« nicht erzeugen: %s" -#: receivelog.c:293 +#: receivelog.c:290 #, c-format -msgid "%s: could not write timeline history file \"%s\": %s\n" -msgstr "%s: konnte Zeitleisten-History-Datei »%s« nicht schreiben: %s\n" +msgid "could not write timeline history file \"%s\": %s" +msgstr "konnte Zeitleisten-History-Datei »%s« nicht schreiben: %s" -#: receivelog.c:383 +#: receivelog.c:380 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions older than %s\n" -msgstr "%s: inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen älter als %s\n" +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen älter als %s" -#: receivelog.c:393 +#: receivelog.c:389 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions newer than %s\n" -msgstr "%s: inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen neuer als %s\n" +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen neuer als %s" -#: receivelog.c:498 streamutil.c:265 streamutil.c:304 +#: receivelog.c:491 streamutil.c:430 streamutil.c:467 #, c-format -msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" -msgstr "%s: konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet\n" +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet." -#: receivelog.c:506 +#: receivelog.c:498 #, c-format -msgid "%s: system identifier does not match between base backup and streaming connection\n" -msgstr "%s: Systemidentifikator stimmt nicht zwischen Basissicherung und Streaming-Verbindung überein\n" +msgid "system identifier does not match between base backup and streaming connection" +msgstr "Systemidentifikator stimmt nicht zwischen Basissicherung und Streaming-Verbindung überein" -#: receivelog.c:514 +#: receivelog.c:504 #, c-format -msgid "%s: starting timeline %u is not present in the server\n" -msgstr "%s: Startzeitleiste %u ist auf dem Server nicht vorhanden\n" +msgid "starting timeline %u is not present in the server" +msgstr "Startzeitleiste %u ist auf dem Server nicht vorhanden" -#: receivelog.c:533 +#: receivelog.c:545 #, c-format -msgid "%s: could not create temporary replication slot \"%s\": %s" -msgstr "%s: konnte temporären Replikations-Slot »%s« nicht erzeugen: %s" +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Antwort auf Befehl TIMELINE_HISTORY: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: receivelog.c:574 +#: receivelog.c:616 #, c-format -msgid "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: unerwartete Antwort auf Befehl TIMELINE_HISTORY: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet\n" +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "Server berichtete unerwartete nächste Zeitleiste %u, folgend auf Zeitleiste %u" -#: receivelog.c:646 +#: receivelog.c:622 #, c-format -msgid "%s: server reported unexpected next timeline %u, following timeline %u\n" -msgstr "%s: Server berichtete unerwartete nächste Zeitleiste %u, folgend auf Zeitleiste %u\n" +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "Server beendete Streaming von Zeitleiste %u bei %X/%X, aber gab an, dass nächste Zeitleiste %u bei %X/%X beginnt" -#: receivelog.c:653 +#: receivelog.c:662 #, c-format -msgid "%s: server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X\n" -msgstr "%s: Server beendete Streaming von Zeitleiste %u bei %X/%X, aber gab an, dass nächste Zeitleiste %u bei %X/%X beginnt\n" +msgid "replication stream was terminated before stop point" +msgstr "Replikationsstrom wurde vor Stopppunkt abgebrochen" -#: receivelog.c:694 +#: receivelog.c:708 #, c-format -msgid "%s: replication stream was terminated before stop point\n" -msgstr "%s: Replikationsstrom wurde vor Stopppunkt abgebrochen\n" +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "unerwartete Ergebnismenge nach Ende der Zeitleiste: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: receivelog.c:743 +#: receivelog.c:717 #, c-format -msgid "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: unerwartete Ergebnismenge nach Ende der Zeitleiste: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet\n" +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "konnte Startpunkt der nächsten Zeitleiste (»%s«) nicht interpretieren" -#: receivelog.c:753 +#: receivelog.c:766 receivelog.c:1018 #, c-format -msgid "%s: could not parse next timeline's starting point \"%s\"\n" -msgstr "%s: konnte Startpunkt der nächsten Zeitleiste (»%s«) nicht interpretieren\n" +msgid "could not fsync file \"%s\": %s" +msgstr "konnte Datei »%s« nicht fsyncen: %s" -#: receivelog.c:1124 +#: receivelog.c:1081 #, c-format -msgid "%s: received write-ahead log record for offset %u with no file open\n" -msgstr "%s: Write-Ahead-Log-Eintrag für Offset %u erhalten ohne offene Datei\n" +msgid "received write-ahead log record for offset %u with no file open" +msgstr "Write-Ahead-Log-Eintrag für Offset %u erhalten ohne offene Datei" -#: receivelog.c:1135 +#: receivelog.c:1091 #, c-format -msgid "%s: got WAL data offset %08x, expected %08x\n" -msgstr "%s: WAL-Daten-Offset %08x erhalten, %08x erwartet\n" +msgid "got WAL data offset %08x, expected %08x" +msgstr "WAL-Daten-Offset %08x erhalten, %08x erwartet" -#: receivelog.c:1170 +#: receivelog.c:1125 #, c-format -msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" -msgstr "%s: konnte %u Bytes nicht in WAL-Datei »%s« schreiben: %s\n" +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "konnte %u Bytes nicht in WAL-Datei »%s« schreiben: %s" -#: receivelog.c:1195 receivelog.c:1236 receivelog.c:1267 +#: receivelog.c:1150 receivelog.c:1190 receivelog.c:1221 #, c-format -msgid "%s: could not send copy-end packet: %s" -msgstr "%s: konnte COPY-Ende-Paket nicht senden: %s" +msgid "could not send copy-end packet: %s" +msgstr "konnte COPY-Ende-Paket nicht senden: %s" -#: streamutil.c:149 +#: streamutil.c:162 msgid "Password: " msgstr "Passwort: " -#: streamutil.c:174 +#: streamutil.c:187 +#, c-format +msgid "could not connect to server" +msgstr "konnte nicht mit Server verbinden" + +#: streamutil.c:204 +#, c-format +msgid "could not connect to server: %s" +msgstr "konnte nicht mit Server verbinden: %s" + +#: streamutil.c:233 +#, c-format +msgid "could not clear search_path: %s" +msgstr "konnte search_path nicht auf leer setzen: %s" + +#: streamutil.c:249 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "konnte Servereinstellung für integer_datetimes nicht ermitteln" + +#: streamutil.c:256 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "Kompilieroption »integer_datetimes« stimmt nicht mit Server überein" + +#: streamutil.c:307 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "konnte WAL-Segmentgröße nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" + +#: streamutil.c:317 #, c-format -msgid "%s: could not connect to server\n" -msgstr "%s: konnte nicht mit Server verbinden\n" +msgid "WAL segment size could not be parsed" +msgstr "WAL-Segmentgröße konnte nicht interpretiert werden" -#: streamutil.c:192 +#: streamutil.c:332 #, c-format -msgid "%s: could not connect to server: %s" -msgstr "%s: konnte nicht mit Server verbinden: %s" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Bytes an" -#: streamutil.c:216 +#: streamutil.c:378 #, c-format -msgid "%s: could not determine server setting for integer_datetimes\n" -msgstr "%s: konnte Servereinstellung für integer_datetimes nicht ermitteln\n" +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "konnte Gruppenzugriffseinstellung nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet" -#: streamutil.c:225 +#: streamutil.c:387 #, c-format -msgid "%s: integer_datetimes compile flag does not match server\n" -msgstr "%s: Kompilieroption »integer_datetimes« stimmt nicht mit Server überein\n" +msgid "group access flag could not be parsed: %s" +msgstr "Gruppenzugriffseinstellung konnte nicht interpretiert werden: %s" -#: streamutil.c:376 +#: streamutil.c:544 #, c-format -msgid "%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet\n" +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: streamutil.c:421 +#: streamutil.c:588 #, c-format -msgid "%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: konnte Replikations-Slot »%s« nicht löschen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet\n" +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "konnte Replikations-Slot »%s« nicht löschen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet" -#: walmethods.c:435 walmethods.c:904 -msgid "deflate failed" -msgstr "deflate fehlgeschlagen" +#: walmethods.c:439 walmethods.c:928 +msgid "could not compress data" +msgstr "konnte Daten nicht komprimieren" -#: walmethods.c:459 -msgid "deflateReset failed" -msgstr "deflateReset fehlgeschlagen" +#: walmethods.c:471 +msgid "could not reset compression stream" +msgstr "konnte Komprimierungsstrom nicht zurücksetzen" -#: walmethods.c:560 -msgid "deflateInit2 failed" -msgstr "deflateInit2 fehlgeschlagen" +#: walmethods.c:569 +msgid "could not initialize compression library" +msgstr "konnte Komprimierungsbibliothek nicht initialisieren" -#: walmethods.c:572 -msgid "implementation error: tar files can't have more than one open file\n" -msgstr "Implementierungsfehler: Tar-Dateien können nicht mehr als eine offene Datei haben\n" +#: walmethods.c:581 +msgid "implementation error: tar files can't have more than one open file" +msgstr "Implementierungsfehler: Tar-Dateien können nicht mehr als eine offene Datei haben" -#: walmethods.c:586 +#: walmethods.c:595 msgid "could not create tar header" msgstr "konnte Tar-Dateikopf nicht erzeugen" -#: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 -msgid "deflateParams failed" -msgstr "deflateParams fehlgeschlagen" +#: walmethods.c:609 walmethods.c:649 walmethods.c:844 walmethods.c:855 +msgid "could not change compression parameters" +msgstr "konnte Komprimierungsparameter nicht ändern" -#: walmethods.c:720 +#: walmethods.c:731 msgid "unlink not supported with compression" msgstr "Unlink wird bei Komprimierung nicht unterstützt" -#: walmethods.c:920 -msgid "deflateEnd failed" -msgstr "deflateEnd fehlgeschlagen" +#: walmethods.c:953 +msgid "could not close compression stream" +msgstr "konnte Komprimierungsstrom nicht schließen" diff --git a/src/bin/pg_basebackup/po/es.po b/src/bin/pg_basebackup/po/es.po index 042d5dca78f..5c5d7f1d005 100644 --- a/src/bin/pg_basebackup/po/es.po +++ b/src/bin/pg_basebackup/po/es.po @@ -1,24 +1,40 @@ # Spanish message translation file for pg_basebackup # -# Copyright (C) 2011-2014 PostgreSQL Global Development Group +# Copyright (c) 2011-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Ãlvaro Herrera , 2011-2014. +# Carlos Chapi , 2017. # msgid "" msgstr "" -"Project-Id-Version: pg_basebackup (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:15+0000\n" -"PO-Revision-Date: 2017-07-10 12:13-0400\n" +"Project-Id-Version: pg_basebackup (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:14+0000\n" +"PO-Revision-Date: 2019-06-06 17:22-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: Spanish \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -31,120 +47,120 @@ msgstr "memoria agotada\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "no se puede duplicar un puntero nulo (error interno)\n" -#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 -#: pg_receivewal.c:252 pg_recvlogical.c:353 +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#: pg_receivewal.c:267 pg_recvlogical.c:342 #, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: no se pudo hacer stat del archivo «%s»: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" -#: ../../common/file_utils.c:162 pg_receivewal.c:153 +#: ../../common/file_utils.c:160 pg_receivewal.c:170 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: no se pudo abrir el directorio «%s»: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: ../../common/file_utils.c:198 pg_receivewal.c:320 +#: ../../common/file_utils.c:194 pg_receivewal.c:338 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: no se pudo leer el directorio «%s»: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" -#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 -#: ../../common/file_utils.c:367 +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 pg_basebackup.c:1761 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo «%s»: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:802 -#: receivelog.c:1059 +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#: pg_recvlogical.c:195 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: no se pudo sincronizar (fsync) el archivo «%s»: %s\n" +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" -#: ../../common/file_utils.c:387 +#: ../../common/file_utils.c:377 #, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: no se pudo cambiar el nombre al archivo «%s» a «%s»: %s\n" +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m" -#: pg_basebackup.c:159 +#: pg_basebackup.c:171 #, c-format -msgid "%s: removing data directory \"%s\"\n" -msgstr "%s: eliminando el directorio de datos «%s»\n" +msgid "removing data directory \"%s\"" +msgstr "eliminando el directorio de datos «%s»" -#: pg_basebackup.c:162 +#: pg_basebackup.c:173 #, c-format -msgid "%s: failed to remove data directory\n" -msgstr "%s: no se pudo eliminar el directorio de datos\n" +msgid "failed to remove data directory" +msgstr "no se pudo eliminar el directorio de datos" -#: pg_basebackup.c:168 +#: pg_basebackup.c:177 #, c-format -msgid "%s: removing contents of data directory \"%s\"\n" -msgstr "%s: eliminando el contenido del directorio «%s»\n" +msgid "removing contents of data directory \"%s\"" +msgstr "eliminando el contenido del directorio «%s»" -#: pg_basebackup.c:171 +#: pg_basebackup.c:179 #, c-format -msgid "%s: failed to remove contents of data directory\n" -msgstr "%s: no se pudo eliminar el contenido del directorio de datos\n" +msgid "failed to remove contents of data directory" +msgstr "no se pudo eliminar el contenido del directorio de datos" -#: pg_basebackup.c:177 +#: pg_basebackup.c:184 #, c-format -msgid "%s: removing WAL directory \"%s\"\n" -msgstr "%s: eliminando el directorio de WAL «%s»\n" +msgid "removing WAL directory \"%s\"" +msgstr "eliminando el directorio de WAL «%s»" -#: pg_basebackup.c:180 +#: pg_basebackup.c:186 #, c-format -msgid "%s: failed to remove WAL directory\n" -msgstr "%s: no se pudo eliminar el directorio de WAL\n" +msgid "failed to remove WAL directory" +msgstr "no se pudo eliminar el directorio de WAL" -#: pg_basebackup.c:186 +#: pg_basebackup.c:190 #, c-format -msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s: eliminando el contenido del directorio de WAL «%s»\n" +msgid "removing contents of WAL directory \"%s\"" +msgstr "eliminando el contenido del directorio de WAL «%s»" -#: pg_basebackup.c:189 +#: pg_basebackup.c:192 #, c-format -msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s: no se pudo eliminar el contenido del directorio de WAL\n" +msgid "failed to remove contents of WAL directory" +msgstr "no se pudo eliminar el contenido del directorio de WAL" -#: pg_basebackup.c:197 +#: pg_basebackup.c:198 #, c-format -msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s: directorio de datos «%s» no eliminado a petición del usuario\n" +msgid "data directory \"%s\" not removed at user's request" +msgstr "directorio de datos «%s» no eliminado a petición del usuario" -#: pg_basebackup.c:202 +#: pg_basebackup.c:201 #, c-format -msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s: directorio de WAL «%s» no eliminado a petición del usuario\n" +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "directorio de WAL «%s» no eliminado a petición del usuario" -#: pg_basebackup.c:208 +#: pg_basebackup.c:205 #, c-format -msgid "%s: changes to tablespace directories will not be undone\n" -msgstr "%s: los cambios a los directorios de tablespaces no se desharán\n" +msgid "changes to tablespace directories will not be undone" +msgstr "los cambios a los directorios de tablespaces no se desharán" -#: pg_basebackup.c:250 +#: pg_basebackup.c:246 #, c-format -msgid "%s: directory name too long\n" -msgstr "%s: nombre de directorio demasiado largo\n" +msgid "directory name too long" +msgstr "nombre de directorio demasiado largo" -#: pg_basebackup.c:260 +#: pg_basebackup.c:256 #, c-format -msgid "%s: multiple \"=\" signs in tablespace mapping\n" -msgstr "%s: múltiples signos «=» en mapeo de tablespace\n" +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "múltiples signos «=» en mapeo de tablespace" -#: pg_basebackup.c:273 +#: pg_basebackup.c:268 #, c-format -msgid "%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" -msgstr "%s: formato de mapeo de tablespace «%s» no válido, debe ser «ANTIGUO=NUEVO»\n" +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "formato de mapeo de tablespace «%s» no válido, debe ser «ANTIGUO=NUEVO»" -#: pg_basebackup.c:286 +#: pg_basebackup.c:280 #, c-format -msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s: directorio antiguo no es una ruta absoluta en mapeo de tablespace: %s\n" +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "directorio antiguo no es una ruta absoluta en mapeo de tablespace: %s" -#: pg_basebackup.c:293 +#: pg_basebackup.c:287 #, c-format -msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s: directorio nuevo no es una ruta absoluta en mapeo de tablespace: %s\n" +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "directorio nuevo no es una ruta absoluta en mapeo de tablespace: %s" -#: pg_basebackup.c:327 +#: pg_basebackup.c:326 #, c-format msgid "" "%s takes a base backup of a running PostgreSQL server.\n" @@ -153,17 +169,17 @@ msgstr "" "%s obtiene un respaldo base a partir de un servidor PostgreSQL en ejecución.\n" "\n" -#: pg_basebackup.c:329 pg_receivewal.c:76 pg_recvlogical.c:77 +#: pg_basebackup.c:328 pg_receivewal.c:81 pg_recvlogical.c:78 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_basebackup.c:330 pg_receivewal.c:77 pg_recvlogical.c:78 +#: pg_basebackup.c:329 pg_receivewal.c:82 pg_recvlogical.c:79 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPCIÓN]...\n" -#: pg_basebackup.c:331 +#: pg_basebackup.c:330 #, c-format msgid "" "\n" @@ -172,79 +188,69 @@ msgstr "" "\n" "Opciones que controlan la salida:\n" -#: pg_basebackup.c:332 +#: pg_basebackup.c:331 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" -msgstr " -D, --pgdata=DIRECTORIO recibir el respaldo base en directorio\n" +msgstr " -D, --pgdata=DIR directorio en el cual recibir el respaldo base\n" -#: pg_basebackup.c:333 +#: pg_basebackup.c:332 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" -msgstr " -F, --format=p|t formato de salida (plano (por omisión), tar)\n" +msgstr " -F, --format=p|t formato de salida (plano (por omisión), tar)\n" -#: pg_basebackup.c:334 +#: pg_basebackup.c:333 #, c-format msgid "" " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" " (in kB/s, or use suffix \"k\" or \"M\")\n" msgstr "" -" -r, --max-rate=TASA máxima tasa a la que transferir el directorio de datos\n" -" (en kB/s, o use sufijos «k» o «M»)\n" +" -r, --max-rate=TASA máxima tasa a la que transferir el directorio de datos\n" +" (en kB/s, o use sufijos «k» o «M»)\n" -#: pg_basebackup.c:336 +#: pg_basebackup.c:335 #, c-format msgid "" " -R, --write-recovery-conf\n" -" write recovery.conf for replication\n" +" write configuration for replication\n" msgstr "" " -R, --write-recovery-conf\n" -" escribe recovery.conf para replicación\n" - -#: pg_basebackup.c:338 pg_receivewal.c:84 -#, c-format -msgid " -S, --slot=SLOTNAME replication slot to use\n" -msgstr " -S, --slot=NOMBRE slot de replicación a usar\n" +" escribe configuración para replicación\n" -#: pg_basebackup.c:339 -#, c-format -msgid " --no-slot prevent creation of temporary replication slot\n" -msgstr " --no-slot evitar la creación de un slot de replicación temporal\n" - -#: pg_basebackup.c:340 +#: pg_basebackup.c:337 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " relocate tablespace in OLDDIR to NEWDIR\n" msgstr "" " -T, --tablespace-mapping=ANTIGUO=NUEVO\n" -" reubicar el directorio de tablespace de ANTIGUO a NUEVO\n" +" reubicar el directorio de tablespace de ANTIGUO a NUEVO\n" -#: pg_basebackup.c:342 +#: pg_basebackup.c:339 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=DIRWAL ubicación para el directorio WAL\n" + +#: pg_basebackup.c:340 #, c-format msgid "" " -X, --wal-method=none|fetch|stream\n" " include required WAL files with specified method\n" msgstr "" " -X, --wal-method=none|fetch|stream\n" -" incluye los archivos WAL necesarios,\n" -" en el modo especificado\n" - -#: pg_basebackup.c:344 -#, c-format -msgid " --waldir=WALDIR location for the write-ahead log directory\n" -msgstr " --waldir=DIRWAL ubicación para el directorio WAL\n" +" incluye los archivos WAL necesarios,\n" +" en el modo especificado\n" -#: pg_basebackup.c:345 +#: pg_basebackup.c:342 #, c-format msgid " -z, --gzip compress tar output\n" -msgstr " -z, --gzip comprimir la salida de tar\n" +msgstr " -z, --gzip comprimir la salida de tar\n" -#: pg_basebackup.c:346 +#: pg_basebackup.c:343 #, c-format msgid " -Z, --compress=0-9 compress tar output with given compression level\n" -msgstr " -Z, --compress=0-9 comprimir salida tar con el nivel de compresión dado\n" +msgstr " -Z, --compress=0-9 comprimir salida tar con el nivel de compresión dado\n" -#: pg_basebackup.c:347 +#: pg_basebackup.c:344 #, c-format msgid "" "\n" @@ -253,51 +259,75 @@ msgstr "" "\n" "Opciones generales:\n" -#: pg_basebackup.c:348 +#: pg_basebackup.c:345 #, c-format msgid "" " -c, --checkpoint=fast|spread\n" " set fast or spread checkpointing\n" msgstr "" " -c, --checkpoint=fast|spread\n" -" utilizar checkpoint rápido o extendido\n" +" utilizar checkpoint rápido o extendido\n" -#: pg_basebackup.c:350 +#: pg_basebackup.c:347 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot crear un slot de replicación\n" + +#: pg_basebackup.c:348 #, c-format msgid " -l, --label=LABEL set backup label\n" -msgstr " -l, --label=ETIQUETA establecer etiqueta del respaldo\n" +msgstr " -l, --label=ETIQUETA establecer etiqueta del respaldo\n" -#: pg_basebackup.c:351 +#: pg_basebackup.c:349 #, c-format msgid " -n, --no-clean do not clean up after errors\n" -msgstr " -n, --no-clean no hacer limpieza tras errores\n" +msgstr " -n, --no-clean no hacer limpieza tras errores\n" -#: pg_basebackup.c:352 +#: pg_basebackup.c:350 #, c-format msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" -msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" -#: pg_basebackup.c:353 +#: pg_basebackup.c:351 #, c-format msgid " -P, --progress show progress information\n" -msgstr " -P, --progress mostrar información de progreso\n" +msgstr " -P, --progress mostrar información de progreso\n" + +#: pg_basebackup.c:352 pg_receivewal.c:91 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=NOMBRE slot de replicación a usar\n" -#: pg_basebackup.c:354 pg_receivewal.c:86 pg_recvlogical.c:98 +#: pg_basebackup.c:353 pg_receivewal.c:93 pg_recvlogical.c:99 #, c-format msgid " -v, --verbose output verbose messages\n" -msgstr " -v, --verbose desplegar mensajes verbosos\n" +msgstr " -v, --verbose desplegar mensajes verbosos\n" -#: pg_basebackup.c:355 pg_receivewal.c:87 pg_recvlogical.c:99 +#: pg_basebackup.c:354 pg_receivewal.c:94 pg_recvlogical.c:100 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version mostrar información de versión, luego salir\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" + +#: pg_basebackup.c:355 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot evitar la creación de un slot de replicación temporal\n" -#: pg_basebackup.c:356 pg_receivewal.c:89 pg_recvlogical.c:100 +#: pg_basebackup.c:356 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" no verificar checksums\n" + +#: pg_basebackup.c:358 pg_receivewal.c:96 pg_recvlogical.c:101 #, c-format msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help mostrar esta ayuda, luego salir\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" -#: pg_basebackup.c:357 pg_receivewal.c:90 pg_recvlogical.c:101 +#: pg_basebackup.c:359 pg_receivewal.c:97 pg_recvlogical.c:102 #, c-format msgid "" "\n" @@ -306,460 +336,487 @@ msgstr "" "\n" "Opciones de conexión:\n" -#: pg_basebackup.c:358 pg_receivewal.c:91 +#: pg_basebackup.c:360 pg_receivewal.c:98 #, c-format msgid " -d, --dbname=CONNSTR connection string\n" -msgstr " -s, --dbname=CONSTR cadena de conexión\n" +msgstr " -s, --dbname=CONSTR cadena de conexión\n" -#: pg_basebackup.c:359 pg_receivewal.c:92 pg_recvlogical.c:103 +#: pg_basebackup.c:361 pg_receivewal.c:99 pg_recvlogical.c:104 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" -msgstr " -h, --host=ANFITRIÓN dirección del servidor o directorio del socket\n" +msgstr " -h, --host=ANFITRIÓN dirección del servidor o directorio del socket\n" -#: pg_basebackup.c:360 pg_receivewal.c:93 pg_recvlogical.c:104 +#: pg_basebackup.c:362 pg_receivewal.c:100 pg_recvlogical.c:105 #, c-format msgid " -p, --port=PORT database server port number\n" -msgstr " -p, --port=PORT número de port del servidor\n" +msgstr " -p, --port=PORT número de port del servidor\n" -#: pg_basebackup.c:361 +#: pg_basebackup.c:363 #, c-format msgid "" " -s, --status-interval=INTERVAL\n" " time between status packets sent to server (in seconds)\n" msgstr "" " -s, --status-interval=INTERVALO (segundos)\n" -" tiempo entre envíos de paquetes de estado al servidor\n" +" tiempo entre envíos de paquetes de estado al servidor\n" -#: pg_basebackup.c:363 pg_receivewal.c:94 pg_recvlogical.c:105 +#: pg_basebackup.c:365 pg_receivewal.c:101 pg_recvlogical.c:106 #, c-format msgid " -U, --username=NAME connect as specified database user\n" -msgstr " -U, --username=NOMBRE conectarse con el usuario especificado\n" +msgstr " -U, --username=NOMBRE conectarse con el usuario especificado\n" -#: pg_basebackup.c:364 pg_receivewal.c:95 pg_recvlogical.c:106 +#: pg_basebackup.c:366 pg_receivewal.c:102 pg_recvlogical.c:107 #, c-format msgid " -w, --no-password never prompt for password\n" -msgstr " -w, --no-password nunca pedir contraseña\n" +msgstr " -w, --no-password nunca pedir contraseña\n" -#: pg_basebackup.c:365 pg_receivewal.c:96 pg_recvlogical.c:107 +#: pg_basebackup.c:367 pg_receivewal.c:103 pg_recvlogical.c:108 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr "" -" -W, --password forzar un prompt para la contraseña\n" -" (debería ser automático)\n" +" -W, --password forzar un prompt para la contraseña\n" +" (debería ser automático)\n" -#: pg_basebackup.c:366 pg_receivewal.c:100 pg_recvlogical.c:108 +#: pg_basebackup.c:368 pg_receivewal.c:107 pg_recvlogical.c:109 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" + +#: pg_basebackup.c:411 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "no se pudo leer desde la tubería: %m" -#: pg_basebackup.c:409 +#: pg_basebackup.c:417 pg_basebackup.c:545 pg_basebackup.c:2099 +#: streamutil.c:450 #, c-format -msgid "%s: could not read from ready pipe: %s\n" -msgstr "%s: no se pudo leer desde la tubería: %s\n" +msgid "could not parse write-ahead log location \"%s\"" +msgstr "no se pudo interpretar la ubicación del WAL «%s»" -#: pg_basebackup.c:417 pg_basebackup.c:552 pg_basebackup.c:2001 -#: streamutil.c:285 +#: pg_basebackup.c:510 pg_receivewal.c:442 #, c-format -msgid "%s: could not parse write-ahead log location \"%s\"\n" -msgstr "%s: no se pudo interpretar la ubicación del WAL «%s»\n" +msgid "could not finish writing WAL files: %m" +msgstr "no se pudo completar la escritura de archivos WAL: %m" -#: pg_basebackup.c:515 pg_receivewal.c:428 +#: pg_basebackup.c:557 #, c-format -msgid "%s: could not finish writing WAL files: %s\n" -msgstr "%s: no se pudo completar la escritura de archivos WAL: %s\n" +msgid "could not create pipe for background process: %m" +msgstr "no se pudo crear la tubería para el proceso en segundo plano: %m" -#: pg_basebackup.c:565 +#: pg_basebackup.c:592 #, c-format -msgid "%s: could not create pipe for background process: %s\n" -msgstr "%s: no se pudo crear la tubería para el proceso en segundo plano: %s\n" +msgid "created temporary replication slot \"%s\"" +msgstr "se creó slot temporal de replicación «%s»" -#: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1419 +#: pg_basebackup.c:595 #, c-format -msgid "%s: could not create directory \"%s\": %s\n" -msgstr "%s: no se pudo crear el directorio «%s»: %s\n" +msgid "created replication slot \"%s\"" +msgstr "se creó el slot de replicación «%s»" -#: pg_basebackup.c:624 +#: pg_basebackup.c:615 pg_basebackup.c:668 pg_basebackup.c:1503 #, c-format -msgid "%s: could not create background process: %s\n" -msgstr "%s: no se pudo lanzar el proceso en segundo plano: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" -#: pg_basebackup.c:636 +#: pg_basebackup.c:633 #, c-format -msgid "%s: could not create background thread: %s\n" -msgstr "%s: no se pudo lanzar el hilo en segundo plano: %s\n" +msgid "could not create background process: %m" +msgstr "no se pudo lanzar el proceso en segundo plano: %m" -#: pg_basebackup.c:684 +#: pg_basebackup.c:645 #, c-format -msgid "%s: directory \"%s\" exists but is not empty\n" -msgstr "%s: el directorio «%s» existe pero no está vacío\n" +msgid "could not create background thread: %m" +msgstr "no se pudo lanzar el hilo en segundo plano: %m" -#: pg_basebackup.c:692 +#: pg_basebackup.c:689 #, c-format -msgid "%s: could not access directory \"%s\": %s\n" -msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" +msgid "directory \"%s\" exists but is not empty" +msgstr "el directorio «%s» existe pero no está vacío" -#: pg_basebackup.c:754 +#: pg_basebackup.c:696 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "no se pudo acceder al directorio «%s»: %m" + +#: pg_basebackup.c:757 #, c-format msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s" msgstr[1] "%*s/%s kB (100%%), %d/%d tablespaces %*s" -#: pg_basebackup.c:766 +#: pg_basebackup.c:769 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" -#: pg_basebackup.c:782 +#: pg_basebackup.c:785 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces" -#: pg_basebackup.c:804 +#: pg_basebackup.c:809 #, c-format -msgid "%s: transfer rate \"%s\" is not a valid value\n" -msgstr "%s: tasa de transferencia «%s» no es un valor válido\n" +msgid "transfer rate \"%s\" is not a valid value" +msgstr "tasa de transferencia «%s» no es un valor válido" -#: pg_basebackup.c:811 +#: pg_basebackup.c:814 #, c-format -msgid "%s: invalid transfer rate \"%s\": %s\n" -msgstr "%s: tasa de transferencia «%s» no válida: %s\n" +msgid "invalid transfer rate \"%s\": %m" +msgstr "tasa de transferencia «%s» no válida: %m" -#: pg_basebackup.c:821 +#: pg_basebackup.c:823 #, c-format -msgid "%s: transfer rate must be greater than zero\n" -msgstr "%s: tasa de transferencia debe ser mayor que cero\n" +msgid "transfer rate must be greater than zero" +msgstr "tasa de transferencia debe ser mayor que cero" #: pg_basebackup.c:855 #, c-format -msgid "%s: invalid --max-rate unit: \"%s\"\n" -msgstr "%s: unidad de --max-rato no válida: «%s»\n" +msgid "invalid --max-rate unit: \"%s\"" +msgstr "unidad de --max-rato no válida: «%s»" -#: pg_basebackup.c:864 +#: pg_basebackup.c:862 #, c-format -msgid "%s: transfer rate \"%s\" exceeds integer range\n" -msgstr "%s: la tasa de transferencia «%s» excede el rango de enteros\n" +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "la tasa de transferencia «%s» excede el rango de enteros" -#: pg_basebackup.c:876 +#: pg_basebackup.c:872 #, c-format -msgid "%s: transfer rate \"%s\" is out of range\n" -msgstr "%s: la tasa de transferencia «%s» está fuera de rango\n" +msgid "transfer rate \"%s\" is out of range" +msgstr "la tasa de transferencia «%s» está fuera de rango" -#: pg_basebackup.c:900 +#: pg_basebackup.c:894 #, c-format -msgid "%s: could not write to compressed file \"%s\": %s\n" -msgstr "%s: no se pudo escribir al archivo comprimido «%s»: %s\n" +msgid "could not write to compressed file \"%s\": %s" +msgstr "no se pudo escribir al archivo comprimido «%s»: %s" -#: pg_basebackup.c:910 pg_basebackup.c:1513 pg_basebackup.c:1679 +#: pg_basebackup.c:904 pg_basebackup.c:1592 pg_basebackup.c:1767 #, c-format -msgid "%s: could not write to file \"%s\": %s\n" -msgstr "%s: no se pudo escribir al archivo «%s»: %s\n" +msgid "could not write to file \"%s\": %m" +msgstr "no se pudo escribir a archivo «%s»: %m" -#: pg_basebackup.c:965 pg_basebackup.c:986 pg_basebackup.c:1014 +#: pg_basebackup.c:969 pg_basebackup.c:989 pg_basebackup.c:1016 #, c-format -msgid "%s: could not set compression level %d: %s\n" -msgstr "%s: no se pudo definir el nivel de compresión %d: %s\n" +msgid "could not set compression level %d: %s" +msgstr "no se pudo definir el nivel de compresión %d: %s" -#: pg_basebackup.c:1035 +#: pg_basebackup.c:1036 #, c-format -msgid "%s: could not create compressed file \"%s\": %s\n" -msgstr "%s: no se pudo crear el archivo comprimido «%s»: %s\n" +msgid "could not create compressed file \"%s\": %s" +msgstr "no se pudo crear el archivo comprimido «%s»: %s" -#: pg_basebackup.c:1046 pg_basebackup.c:1473 pg_basebackup.c:1672 +#: pg_basebackup.c:1047 pg_basebackup.c:1553 pg_basebackup.c:1779 #, c-format -msgid "%s: could not create file \"%s\": %s\n" -msgstr "%s: no se pudo crear el archivo «%s»: %s\n" +msgid "could not create file \"%s\": %m" +msgstr "no se pudo crear archivo «%s»: %m" -#: pg_basebackup.c:1058 pg_basebackup.c:1326 +#: pg_basebackup.c:1058 pg_basebackup.c:1412 #, c-format -msgid "%s: could not get COPY data stream: %s" -msgstr "%s: no se pudo obtener un flujo de datos COPY: %s" +msgid "could not get COPY data stream: %s" +msgstr "no se pudo obtener un flujo de datos COPY: %s" -#: pg_basebackup.c:1115 +#: pg_basebackup.c:1143 #, c-format -msgid "%s: could not close compressed file \"%s\": %s\n" -msgstr "%s: no se pudo cerrar el archivo comprimido «%s»: %s\n" +msgid "could not close compressed file \"%s\": %s" +msgstr "no se pudo cerrar el archivo comprimido «%s»: %s" -#: pg_basebackup.c:1128 pg_recvlogical.c:631 receivelog.c:221 receivelog.c:306 -#: receivelog.c:712 +#: pg_basebackup.c:1155 pg_recvlogical.c:608 #, c-format -msgid "%s: could not close file \"%s\": %s\n" -msgstr "%s: no se pudo cerrar el archivo «%s»: %s\n" +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" -#: pg_basebackup.c:1139 pg_basebackup.c:1355 pg_recvlogical.c:453 -#: receivelog.c:1007 +#: pg_basebackup.c:1166 pg_basebackup.c:1441 pg_recvlogical.c:437 +#: receivelog.c:968 #, c-format -msgid "%s: could not read COPY data: %s" -msgstr "%s: no fue posible leer datos COPY: %s" +msgid "could not read COPY data: %s" +msgstr "no fue posible leer datos COPY: %s" -#: pg_basebackup.c:1369 +#: pg_basebackup.c:1455 #, c-format -msgid "%s: invalid tar block header size: %d\n" -msgstr "%s: tamaño de bloque de cabecera de tar no válido: %d\n" +msgid "invalid tar block header size: %d" +msgstr "tamaño de bloque de cabecera de tar no válido: %d" -#: pg_basebackup.c:1427 +#: pg_basebackup.c:1510 #, c-format -msgid "%s: could not set permissions on directory \"%s\": %s\n" -msgstr "%s: no se pudo definir los permisos en el directorio «%s»: %s\n" +msgid "could not set permissions on directory \"%s\": %m" +msgstr "no se pudo definir los permisos del directorio «%s»: %m" -#: pg_basebackup.c:1451 +#: pg_basebackup.c:1533 #, c-format -msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" -msgstr "%s: no se pudo crear un enlace simbólico desde «%s» a «%s»: %s\n" +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "no se pudo crear un enlace simbólico desde «%s» a «%s»: %m" -#: pg_basebackup.c:1460 +#: pg_basebackup.c:1540 #, c-format -msgid "%s: unrecognized link indicator \"%c\"\n" -msgstr "%s: indicador de enlace «%c» no reconocido\n" +msgid "unrecognized link indicator \"%c\"" +msgstr "indicador de enlace «%c» no reconocido" -#: pg_basebackup.c:1480 +#: pg_basebackup.c:1559 #, c-format -msgid "%s: could not set permissions on file \"%s\": %s\n" -msgstr "%s: no se pudo definir los permisos al archivo «%s»: %s\n" +msgid "could not set permissions on file \"%s\": %m" +msgstr "no se pudo definir los permisos al archivo «%s»: %m" -#: pg_basebackup.c:1539 +#: pg_basebackup.c:1616 #, c-format -msgid "%s: COPY stream ended before last file was finished\n" -msgstr "%s: el flujo COPY terminó antes que el último archivo estuviera completo\n" +msgid "COPY stream ended before last file was finished" +msgstr "el flujo COPY terminó antes que el último archivo estuviera completo" -#: pg_basebackup.c:1567 pg_basebackup.c:1587 pg_basebackup.c:1594 -#: pg_basebackup.c:1647 +#: pg_basebackup.c:1643 pg_basebackup.c:1663 pg_basebackup.c:1677 +#: pg_basebackup.c:1728 #, c-format -msgid "%s: out of memory\n" -msgstr "%s: memoria agotada\n" +msgid "out of memory" +msgstr "memoria agotada" -#: pg_basebackup.c:1720 +#: pg_basebackup.c:1820 #, c-format -msgid "%s: incompatible server version %s\n" -msgstr "%s: versión del servidor %s incompatible\n" +msgid "incompatible server version %s" +msgstr "versión del servidor %s incompatible" -#: pg_basebackup.c:1735 +#: pg_basebackup.c:1835 #, c-format -msgid "HINT: use -X none or -X fetch to disable log streaming\n" -msgstr "SUGERENCIA: use -X none o -X fetch para deshabilitar el flujo de log\n" +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "SUGERENCIA: use -X none o -X fetch para deshabilitar el flujo de log" -#: pg_basebackup.c:1761 +#: pg_basebackup.c:1860 #, c-format -msgid "%s: initiating base backup, waiting for checkpoint to complete\n" -msgstr "%s: iniciando el respaldo base, esperando que el checkpoint se complete\n" +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "iniciando el respaldo base, esperando que el checkpoint se complete" -#: pg_basebackup.c:1779 pg_recvlogical.c:270 receivelog.c:490 receivelog.c:561 -#: receivelog.c:601 streamutil.c:255 streamutil.c:363 streamutil.c:409 +#: pg_basebackup.c:1884 pg_recvlogical.c:264 receivelog.c:484 receivelog.c:533 +#: receivelog.c:572 streamutil.c:299 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 #, c-format -msgid "%s: could not send replication command \"%s\": %s" -msgstr "%s: no se pudo ejecutar la orden de replicación «%s»: %s" +msgid "could not send replication command \"%s\": %s" +msgstr "no se pudo ejecutar la orden de replicación «%s»: %s" -#: pg_basebackup.c:1790 +#: pg_basebackup.c:1895 #, c-format -msgid "%s: could not initiate base backup: %s" -msgstr "%s: no se pudo iniciar el respaldo base: %s" +msgid "could not initiate base backup: %s" +msgstr "no se pudo iniciar el respaldo base: %s" -#: pg_basebackup.c:1797 +#: pg_basebackup.c:1901 #, c-format -msgid "%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: el servidor envió una respuesta inesperada a la orden BASE_BACKUP; se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos\n" +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "el servidor envió una respuesta inesperada a la orden BASE_BACKUP; se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" -#: pg_basebackup.c:1805 +#: pg_basebackup.c:1909 #, c-format -msgid "%s: checkpoint completed\n" -msgstr "%s: el checkpoint se ha completado\n" +msgid "checkpoint completed" +msgstr "el checkpoint se ha completado" -#: pg_basebackup.c:1820 +#: pg_basebackup.c:1924 #, c-format -msgid "%s: write-ahead log start point: %s on timeline %u\n" -msgstr "%s: punto de inicio del WAL: %s en el timeline %u\n" +msgid "write-ahead log start point: %s on timeline %u" +msgstr "punto de inicio del WAL: %s en el timeline %u" -#: pg_basebackup.c:1829 +#: pg_basebackup.c:1933 #, c-format -msgid "%s: could not get backup header: %s" -msgstr "%s: no se pudo obtener la cabecera de respaldo: %s" +msgid "could not get backup header: %s" +msgstr "no se pudo obtener la cabecera de respaldo: %s" -#: pg_basebackup.c:1835 +#: pg_basebackup.c:1939 +#, c-format +msgid "no data returned from server" +msgstr "el servidor no retornó datos" + +#: pg_basebackup.c:1970 #, c-format -msgid "%s: no data returned from server\n" -msgstr "%s: el servidor no retornó datos\n" +msgid "can only write single tablespace to stdout, database has %d" +msgstr "sólo se puede escribir un tablespace a stdout, la base de datos tiene %d" -#: pg_basebackup.c:1867 +#: pg_basebackup.c:1982 #, c-format -msgid "%s: can only write single tablespace to stdout, database has %d\n" -msgstr "%s: sólo se puede escribir un tablespace a stdout, la base de datos tiene %d\n" +msgid "starting background WAL receiver" +msgstr "iniciando el receptor de WAL en segundo plano" -#: pg_basebackup.c:1879 +#: pg_basebackup.c:2012 #, c-format -msgid "%s: starting background WAL receiver\n" -msgstr "%s: iniciando el receptor de WAL en segundo plano\n" +msgid "could not get write-ahead log end position from server: %s" +msgstr "no se pudo obtener la posición final del WAL del servidor: %s" -#: pg_basebackup.c:1910 +#: pg_basebackup.c:2018 #, c-format -msgid "%s: could not get write-ahead log end position from server: %s" -msgstr "%s: no se pudo obtener la posición final del WAL del servidor: %s" +msgid "no write-ahead log end position returned from server" +msgstr "el servidor no retornó la posición final del WAL" -#: pg_basebackup.c:1917 +#: pg_basebackup.c:2023 #, c-format -msgid "%s: no write-ahead log end position returned from server\n" -msgstr "%s: el servidor no retornó la posición final del WAL\n" +msgid "write-ahead log end point: %s" +msgstr "posición final del WAL: %s" -#: pg_basebackup.c:1923 +#: pg_basebackup.c:2034 #, c-format -msgid "%s: write-ahead log end point: %s\n" -msgstr "%s: posición final del WAL: %s\n" +msgid "checksum error occurred" +msgstr "ocurrió un error de checksums" -#: pg_basebackup.c:1929 +#: pg_basebackup.c:2039 #, c-format -msgid "%s: final receive failed: %s" -msgstr "%s: la recepción final falló: %s" +msgid "final receive failed: %s" +msgstr "la recepción final falló: %s" -#: pg_basebackup.c:1953 +#: pg_basebackup.c:2063 #, c-format -msgid "%s: waiting for background process to finish streaming ...\n" -msgstr "%s: esperando que el proceso en segundo plano complete el flujo...\n" +msgid "waiting for background process to finish streaming ..." +msgstr "esperando que el proceso en segundo plano complete el flujo..." -#: pg_basebackup.c:1959 +#: pg_basebackup.c:2068 #, c-format -msgid "%s: could not send command to background pipe: %s\n" -msgstr "%s: no se pudo enviar una orden a la tubería de segundo plano: %s\n" +msgid "could not send command to background pipe: %m" +msgstr "no se pudo enviar una orden a la tubería de segundo plano: %m" -#: pg_basebackup.c:1968 +#: pg_basebackup.c:2076 #, c-format -msgid "%s: could not wait for child process: %s\n" -msgstr "%s: no se pudo esperar al proceso hijo: %s\n" +msgid "could not wait for child process: %m" +msgstr "no se pudo esperar al proceso hijo: %m" -#: pg_basebackup.c:1974 +#: pg_basebackup.c:2081 #, c-format -msgid "%s: child %d died, expected %d\n" -msgstr "%s: el hijo %d murió, pero se esperaba al %d\n" +msgid "child %d died, expected %d" +msgstr "el hijo %d murió, pero se esperaba al %d" -#: pg_basebackup.c:1980 +#: pg_basebackup.c:2086 streamutil.c:94 #, c-format -msgid "%s: child process did not exit normally\n" -msgstr "%s: el proceso hijo no terminó normalmente\n" +msgid "%s" +msgstr "%s" -#: pg_basebackup.c:1986 +#: pg_basebackup.c:2111 #, c-format -msgid "%s: child process exited with error %d\n" -msgstr "%s: el proceso hijo terminó con código de salida %d\n" +msgid "could not wait for child thread: %m" +msgstr "no se pudo esperar el hilo hijo: %m" -#: pg_basebackup.c:2013 +#: pg_basebackup.c:2117 #, c-format -msgid "%s: could not wait for child thread: %s\n" -msgstr "%s: no se pudo esperar el hilo hijo: %s\n" +msgid "could not get child thread exit status: %m" +msgstr "no se pudo obtener la cabecera de respaldo: %m" -#: pg_basebackup.c:2020 +#: pg_basebackup.c:2122 #, c-format -msgid "%s: could not get child thread exit status: %s\n" -msgstr "%s: no se pudo obtener la cabecera de respaldo: %s\n" +msgid "child thread exited with error %u" +msgstr "el hilo hijo terminó con error %u" -#: pg_basebackup.c:2026 +#: pg_basebackup.c:2150 #, c-format -msgid "%s: child thread exited with error %u\n" -msgstr "%s: el hilo hijo terminó con error %u\n" +msgid "syncing data to disk ..." +msgstr "sincronizando datos a disco ..." -#: pg_basebackup.c:2064 +#: pg_basebackup.c:2163 #, c-format -msgid "%s: base backup completed\n" -msgstr "%s: el respaldo base se ha completado\n" +msgid "base backup completed" +msgstr "el respaldo base se ha completado" -#: pg_basebackup.c:2141 +#: pg_basebackup.c:2244 #, c-format -msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" -msgstr "%s: formato de salida «%s» no válido, debe ser «plain» o «tar»\n" +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "formato de salida «%s» no válido, debe ser «plain» o «tar»\n" -#: pg_basebackup.c:2186 +#: pg_basebackup.c:2288 #, c-format -msgid "%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n" -msgstr "%s: opción de wal-method «%s» no válida, debe ser «fetch», «stream» o «none»\n" +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "opción de wal-method «%s» no válida, debe ser «fetch», «stream» o «none»" -#: pg_basebackup.c:2214 pg_receivewal.c:556 +#: pg_basebackup.c:2316 #, c-format -msgid "%s: invalid compression level \"%s\"\n" -msgstr "%s: valor de compresión «%s» no válido\n" +msgid "invalid compression level \"%s\"\n" +msgstr "valor de compresión «%s» no válido\n" -#: pg_basebackup.c:2226 +#: pg_basebackup.c:2327 #, c-format -msgid "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" -msgstr "%s: argumento de checkpoint «%s» no válido, debe ser «fast» o «spread»\n" +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "argumento de checkpoint «%s» no válido, debe ser «fast» o «spread»" -#: pg_basebackup.c:2253 pg_receivewal.c:538 pg_recvlogical.c:825 +#: pg_basebackup.c:2354 pg_receivewal.c:556 pg_recvlogical.c:796 #, c-format -msgid "%s: invalid status interval \"%s\"\n" -msgstr "%s: intervalo de estado «%s» no válido\n" +msgid "invalid status interval \"%s\"" +msgstr "intervalo de estado «%s» no válido" -#: pg_basebackup.c:2269 pg_basebackup.c:2283 pg_basebackup.c:2294 -#: pg_basebackup.c:2307 pg_basebackup.c:2317 pg_basebackup.c:2327 -#: pg_basebackup.c:2339 pg_basebackup.c:2353 pg_basebackup.c:2364 -#: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 -#: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 -#: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 -#: pg_recvlogical.c:893 pg_recvlogical.c:901 pg_recvlogical.c:909 -#: pg_recvlogical.c:917 pg_recvlogical.c:927 +#: pg_basebackup.c:2372 pg_basebackup.c:2385 pg_basebackup.c:2396 +#: pg_basebackup.c:2407 pg_basebackup.c:2415 pg_basebackup.c:2423 +#: pg_basebackup.c:2433 pg_basebackup.c:2446 pg_basebackup.c:2454 +#: pg_basebackup.c:2465 pg_basebackup.c:2475 pg_receivewal.c:606 +#: pg_receivewal.c:619 pg_receivewal.c:627 pg_receivewal.c:637 +#: pg_receivewal.c:645 pg_receivewal.c:656 pg_recvlogical.c:822 +#: pg_recvlogical.c:835 pg_recvlogical.c:846 pg_recvlogical.c:854 +#: pg_recvlogical.c:862 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Use «%s --help» para obtener más información.\n" -#: pg_basebackup.c:2281 pg_receivewal.c:591 pg_recvlogical.c:864 +#: pg_basebackup.c:2383 pg_receivewal.c:617 pg_recvlogical.c:833 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos en la línea de órdenes (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_basebackup.c:2293 pg_receivewal.c:621 +#: pg_basebackup.c:2395 pg_receivewal.c:655 #, c-format -msgid "%s: no target directory specified\n" -msgstr "%s: no se especificó un directorio de salida\n" +msgid "no target directory specified" +msgstr "no se especificó un directorio de salida" -#: pg_basebackup.c:2305 +#: pg_basebackup.c:2406 #, c-format -msgid "%s: only tar mode backups can be compressed\n" -msgstr "%s: sólo los respaldos de modo tar pueden ser comprimidos\n" +msgid "only tar mode backups can be compressed" +msgstr "sólo los respaldos de modo tar pueden ser comprimidos" -#: pg_basebackup.c:2315 +#: pg_basebackup.c:2414 #, c-format -msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" -msgstr "%s: no se puede enviar WALs en modo tar a stdout\n" +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "no se puede enviar WALs en modo tar a stdout" -#: pg_basebackup.c:2325 +#: pg_basebackup.c:2422 #, c-format -msgid "%s: replication slots can only be used with WAL streaming\n" -msgstr "%s: los slots de replicación sólo pueden usarse con flujo de WAL\n" +msgid "replication slots can only be used with WAL streaming" +msgstr "los slots de replicación sólo pueden usarse con flujo de WAL" -#: pg_basebackup.c:2337 +#: pg_basebackup.c:2432 #, c-format -msgid "%s: --no-slot cannot be used with slot name\n" -msgstr "%s: no se puede usar --no-slot junto con nombre de slot\n" +msgid "--no-slot cannot be used with slot name" +msgstr "no se puede usar --no-slot junto con nombre de slot" -#: pg_basebackup.c:2351 +#. translator: second %s is an option name +#: pg_basebackup.c:2444 pg_receivewal.c:635 #, c-format -msgid "%s: WAL directory location can only be specified in plain mode\n" -msgstr "%s: la ubicación del directorio de WAL sólo puede especificarse en modo «plain»\n" +msgid "%s needs a slot to be specified using --slot" +msgstr "la opcón %s necesita que se especifique un slot con --slot" -#: pg_basebackup.c:2362 +#: pg_basebackup.c:2453 #, c-format -msgid "%s: WAL directory location must be an absolute path\n" -msgstr "%s: la ubicación del directorio de WAL debe ser una ruta absoluta\n" +msgid "--create-slot and --no-slot are incompatible options" +msgstr "--create-slot y --no-slot son opciones incompatibles" -#: pg_basebackup.c:2374 pg_receivewal.c:631 +#: pg_basebackup.c:2464 #, c-format -msgid "%s: this build does not support compression\n" -msgstr "%s: esta instalación no soporta compresión\n" +msgid "WAL directory location can only be specified in plain mode" +msgstr "la ubicación del directorio de WAL sólo puede especificarse en modo «plain»" -#: pg_basebackup.c:2414 +#: pg_basebackup.c:2474 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "la ubicación del directorio de WAL debe ser una ruta absoluta" + +#: pg_basebackup.c:2484 pg_receivewal.c:664 +#, c-format +msgid "this build does not support compression" +msgstr "esta instalación no soporta compresión" + +#: pg_basebackup.c:2538 #, c-format -msgid "%s: could not create symbolic link \"%s\": %s\n" -msgstr "%s: no se pudo crear el enlace simbólico «%s»: %s\n" +msgid "could not create symbolic link \"%s\": %m" +msgstr "no se pudo crear el enlace simbólico «%s»: %m" -#: pg_basebackup.c:2419 +#: pg_basebackup.c:2542 #, c-format -msgid "%s: symlinks are not supported on this platform\n" -msgstr "%s: los enlaces simbólicos no están soportados en esta plataforma\n" +msgid "symlinks are not supported on this platform" +msgstr "los enlaces simbólicos no están soportados en esta plataforma" -#: pg_receivewal.c:74 +#: pg_receivewal.c:79 #, c-format msgid "" "%s receives PostgreSQL streaming write-ahead logs.\n" @@ -768,7 +825,7 @@ msgstr "" "%s recibe flujos del WAL de PostgreSQL.\n" "\n" -#: pg_receivewal.c:78 pg_recvlogical.c:83 +#: pg_receivewal.c:83 pg_recvlogical.c:84 #, c-format msgid "" "\n" @@ -777,22 +834,32 @@ msgstr "" "\n" "Opciones:\n" -#: pg_receivewal.c:79 +#: pg_receivewal.c:84 #, c-format msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr " -D, --directory=DIR recibir los archivos de WAL en este directorio\n" -#: pg_receivewal.c:80 pg_recvlogical.c:88 +#: pg_receivewal.c:85 pg_recvlogical.c:85 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN salir luego de recibir el LSN especificado\n" + +#: pg_receivewal.c:86 pg_recvlogical.c:89 #, c-format msgid " --if-not-exists do not error if slot already exists when creating a slot\n" msgstr " --if-not-exists no abandonar si el slot ya existe al crear un slot\n" -#: pg_receivewal.c:81 pg_recvlogical.c:90 +#: pg_receivewal.c:87 pg_recvlogical.c:91 #, c-format msgid " -n, --no-loop do not loop on connection lost\n" msgstr " -n, --no-loop no entrar en bucle al perder la conexión\n" -#: pg_receivewal.c:82 pg_recvlogical.c:95 +#: pg_receivewal.c:88 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_receivewal.c:89 pg_recvlogical.c:96 #, c-format msgid "" " -s, --status-interval=SECS\n" @@ -802,17 +869,17 @@ msgstr "" " tiempo entre envíos de paquetes de estado al servidor\n" " (por omisión: %d)\n" -#: pg_receivewal.c:85 +#: pg_receivewal.c:92 #, c-format msgid " --synchronous flush write-ahead log immediately after writing\n" msgstr " --synchronous sincronizar el WAL inmediatamente después de escribir\n" -#: pg_receivewal.c:88 +#: pg_receivewal.c:95 #, c-format msgid " -Z, --compress=0-9 compress logs with given compression level\n" msgstr " -Z, --compress=0-9 comprimir los segmentos con el nivel de compresión especificado\n" -#: pg_receivewal.c:97 +#: pg_receivewal.c:104 #, c-format msgid "" "\n" @@ -821,109 +888,128 @@ msgstr "" "\n" "Acciones optativas:\n" -#: pg_receivewal.c:98 pg_recvlogical.c:80 +#: pg_receivewal.c:105 pg_recvlogical.c:81 #, c-format msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" msgstr " --create-slot crear un nuevo slot de replicación (para el nombre, vea --slot)\n" -#: pg_receivewal.c:99 pg_recvlogical.c:81 +#: pg_receivewal.c:106 pg_recvlogical.c:82 #, c-format msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" msgstr " --drop-slot eliminar un slot de replicación (para el nombre, vea --slot)\n" -#: pg_receivewal.c:111 +#: pg_receivewal.c:118 #, c-format -msgid "%s: finished segment at %X/%X (timeline %u)\n" -msgstr "%s: terminó el segmento en %X/%X (timeline %u)\n" +msgid "finished segment at %X/%X (timeline %u)" +msgstr "terminó el segmento en %X/%X (timeline %u)" -#: pg_receivewal.c:124 +#: pg_receivewal.c:125 #, c-format -msgid "%s: switched to timeline %u at %X/%X\n" -msgstr "%s: cambiado al timeline %u en %X/%X\n" +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "detenido el flujo de log en %X/%X (timeline %u)" -#: pg_receivewal.c:133 +#: pg_receivewal.c:141 #, c-format -msgid "%s: received interrupt signal, exiting\n" -msgstr "%s: se recibió una señal de interrupción, saliendo\n" +msgid "switched to timeline %u at %X/%X" +msgstr "cambiado al timeline %u en %X/%X" -#: pg_receivewal.c:171 +#: pg_receivewal.c:151 #, c-format -msgid "%s: could not close directory \"%s\": %s\n" -msgstr "%s: no se pudo cerrar el directorio «%s»: %s\n" +msgid "received interrupt signal, exiting" +msgstr "se recibió una señal de interrupción, saliendo" -#: pg_receivewal.c:260 +#: pg_receivewal.c:187 #, c-format -msgid "%s: segment file \"%s\" has incorrect size %d, skipping\n" -msgstr "%s: el archivo de segmento «%s» tiene tamaño incorrecto %d, ignorando\n" +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: pg_receivewal.c:277 +#: pg_receivewal.c:273 #, c-format -msgid "%s: could not open compressed file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo comprimido «%s»: %s\n" +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %d, ignorando" -#: pg_receivewal.c:283 +#: pg_receivewal.c:291 #, c-format -msgid "%s: could not seek compressed file \"%s\": %s\n" -msgstr "%s: no se pudo buscar el archivo comprimido «%s»: %s\n" +msgid "could not open compressed file \"%s\": %m" +msgstr "no se pudo abrir el archivo comprimido «%s»: %m" -#: pg_receivewal.c:289 +#: pg_receivewal.c:297 #, c-format -msgid "%s: could not read compressed file \"%s\": %s\n" -msgstr "%s: no se pudo leer el archivo comprimido «%s»: %s\n" +msgid "could not seek in compressed file \"%s\": %m" +msgstr "no se pudo buscar en el archivo comprimido «%s»: %m" -#: pg_receivewal.c:301 +#: pg_receivewal.c:305 #, c-format -msgid "%s: compressed segment file \"%s\" has incorrect uncompressed size %d, skipping\n" -msgstr "%s: el archivo de segmento «%s» tiene tamaño incorrecto %d al descomprimirse, ignorando\n" +msgid "could not read compressed file \"%s\": %m" +msgstr "no se pudo leer el archivo comprimido «%s»: %m" -#: pg_receivewal.c:407 +#: pg_receivewal.c:308 #, c-format -msgid "%s: starting log streaming at %X/%X (timeline %u)\n" -msgstr "%s: iniciando el flujo de log en %X/%X (timeline %u)\n" +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo comprimido «%s»: leídos %d de %zu" -#: pg_receivewal.c:519 pg_recvlogical.c:762 +#: pg_receivewal.c:319 #, c-format -msgid "%s: invalid port number \"%s\"\n" -msgstr "%s: número de puerto «%s» no válido\n" +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %d al descomprimirse, ignorando" -#: pg_receivewal.c:600 +#: pg_receivewal.c:423 #, c-format -msgid "%s: cannot use --create-slot together with --drop-slot\n" -msgstr "%s: no puede usarse --create-slot junto con --drop-slot\n" +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "iniciando el flujo de log en %X/%X (timeline %u)" -#. translator: second %s is an option name -#: pg_receivewal.c:609 +#: pg_receivewal.c:538 pg_recvlogical.c:738 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "número de puerto «%s» no válido" + +#: pg_receivewal.c:566 pg_recvlogical.c:764 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "no se pudo interpretar la posición final «%s»" + +#: pg_receivewal.c:581 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "valor de compresión «%s» no válido" + +#: pg_receivewal.c:626 #, c-format -msgid "%s: %s needs a slot to be specified using --slot\n" -msgstr "%s: la opcón %s necesita que se especifique un slot con --slot\n" +msgid "cannot use --create-slot together with --drop-slot" +msgstr "no puede usarse --create-slot junto con --drop-slot" -#: pg_receivewal.c:674 +#: pg_receivewal.c:644 #, c-format -msgid "%s: replication connection using slot \"%s\" is unexpectedly database specific\n" -msgstr "%s: la conexión de replicación usando el slot «%s» es inesperadamente específica a una base de datos\n" +msgid "cannot use --synchronous together with --no-sync" +msgstr "no puede usarse --synchronous junto con --no-sync" -#: pg_receivewal.c:686 pg_recvlogical.c:967 +#: pg_receivewal.c:720 #, c-format -msgid "%s: dropping replication slot \"%s\"\n" -msgstr "%s: eliminando el slot de replicación «%s»\n" +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "la conexión de replicación usando el slot «%s» es inesperadamente específica a una base de datos" -#: pg_receivewal.c:699 pg_recvlogical.c:979 +#: pg_receivewal.c:731 pg_recvlogical.c:942 #, c-format -msgid "%s: creating replication slot \"%s\"\n" -msgstr "%s: creando el slot de replicación «%s»\n" +msgid "dropping replication slot \"%s\"" +msgstr "eliminando el slot de replicación «%s»" -#: pg_receivewal.c:726 pg_recvlogical.c:1005 +#: pg_receivewal.c:742 pg_recvlogical.c:952 #, c-format -msgid "%s: disconnected\n" -msgstr "%s: desconectado\n" +msgid "creating replication slot \"%s\"" +msgstr "creando el slot de replicación «%s»" + +#: pg_receivewal.c:768 pg_recvlogical.c:977 +#, c-format +msgid "disconnected" +msgstr "desconectado" #. translator: check source for value for %d -#: pg_receivewal.c:733 pg_recvlogical.c:1012 +#: pg_receivewal.c:774 pg_recvlogical.c:983 #, c-format -msgid "%s: disconnected; waiting %d seconds to try again\n" -msgstr "%s: desconectado; esperando %d segundos para intentar nuevamente\n" +msgid "disconnected; waiting %d seconds to try again" +msgstr "desconectado; esperando %d segundos para intentar nuevamente" -#: pg_recvlogical.c:75 +#: pg_recvlogical.c:76 #, c-format msgid "" "%s controls PostgreSQL logical decoding streams.\n" @@ -932,7 +1018,7 @@ msgstr "" "%s controla flujos de decodificación lógica de PostgreSQL.\n" "\n" -#: pg_recvlogical.c:79 +#: pg_recvlogical.c:80 #, c-format msgid "" "\n" @@ -941,22 +1027,17 @@ msgstr "" "\n" "Acciones a ejecutar:\n" -#: pg_recvlogical.c:82 +#: pg_recvlogical.c:83 #, c-format msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" -msgstr " --start inicie flujo en un slot de replicación (para el nombre, vea --slot)\n" - -#: pg_recvlogical.c:84 -#, c-format -msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" -msgstr " -E, --endpos=LSN salir luego de recibir el LSN especificado\n" +msgstr " --start iniciar flujo en un slot de replicación (para el nombre, vea --slot)\n" -#: pg_recvlogical.c:85 +#: pg_recvlogical.c:86 #, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" -msgstr " -f, --file=ARCHIVO recibe el log en este archivo, - para stdout\n" +msgstr " -f, --file=ARCHIVO recibir el log en este archivo, - para stdout\n" -#: pg_recvlogical.c:86 +#: pg_recvlogical.c:87 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -965,12 +1046,12 @@ msgstr "" " -F, --fsync-interval=SEGS\n" " tiempo entre fsyncs del archivo de salida (omisión: %d)\n" -#: pg_recvlogical.c:89 +#: pg_recvlogical.c:90 #, c-format msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" -msgstr " -I, --startpos=LSN dónde en un slot existente debe empezar el flujo\n" +msgstr " -I, --startpos=LSN dónde en un slot existente debe empezar el flujo\n" -#: pg_recvlogical.c:91 +#: pg_recvlogical.c:92 #, c-format msgid "" " -o, --option=NAME[=VALUE]\n" @@ -981,342 +1062,377 @@ msgstr "" " pasar opción NOMBRE con valor opcional VALOR al\n" " plugin de salida\n" -#: pg_recvlogical.c:94 +#: pg_recvlogical.c:95 #, c-format msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" -msgstr " -P, --plugin=PLUGIN use plugin de salida PLUGIN (omisión: %s)\n" +msgstr " -P, --plugin=PLUGIN usar plug-in de salida PLUGIN (omisión: %s)\n" -#: pg_recvlogical.c:97 +#: pg_recvlogical.c:98 #, c-format msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" -msgstr " -S, --slot=NOMBRE-SLOT nombre del slot de replicación lógica\n" +msgstr " -S, --slot=NOMBRE-SLOT nombre del slot de replicación lógica\n" -#: pg_recvlogical.c:102 +#: pg_recvlogical.c:103 #, c-format msgid " -d, --dbname=DBNAME database to connect to\n" -msgstr " -d, --dbname=BASE base de datos a la cual conectarse\n" +msgstr " -d, --dbname=BASE base de datos a la cual conectarse\n" #: pg_recvlogical.c:135 #, c-format -msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" -msgstr "%s: confirmando escritura hasta %X/%X, fsync hasta %X/%X (slot %s)\n" +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "confirmando escritura hasta %X/%X, fsync hasta %X/%X (slot %s)" -#: pg_recvlogical.c:160 receivelog.c:349 +#: pg_recvlogical.c:159 receivelog.c:346 #, c-format -msgid "%s: could not send feedback packet: %s" -msgstr "%s: no se pudo enviar el paquete de retroalimentación: %s" +msgid "could not send feedback packet: %s" +msgstr "no se pudo enviar el paquete de retroalimentación: %s" -#: pg_recvlogical.c:199 +#: pg_recvlogical.c:232 #, c-format -msgid "%s: could not fsync log file \"%s\": %s\n" -msgstr "%s: no se pudo sincronizar (fsync) el archivo de registro «%s»: %s\n" +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "iniciando el flujo de log en %X/%X (slot %s)" -#: pg_recvlogical.c:238 +#: pg_recvlogical.c:273 #, c-format -msgid "%s: starting log streaming at %X/%X (slot %s)\n" -msgstr "%s: iniciando el flujo de log en %X/%X (slot %s)\n" +msgid "streaming initiated" +msgstr "flujo iniciado" -#: pg_recvlogical.c:280 +#: pg_recvlogical.c:337 #, c-format -msgid "%s: streaming initiated\n" -msgstr "%s: flujo iniciado\n" +msgid "could not open log file \"%s\": %m" +msgstr "no se pudo abrir el archivo de registro «%s»: %m" -#: pg_recvlogical.c:346 +#: pg_recvlogical.c:363 receivelog.c:876 #, c-format -msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%s: no se pudo abrir archivo de log «%s»: %s\n" +msgid "invalid socket: %s" +msgstr "el socket no es válido: %s" -#: pg_recvlogical.c:376 receivelog.c:912 +#: pg_recvlogical.c:416 receivelog.c:904 #, c-format -msgid "%s: invalid socket: %s" -msgstr "%s: el socket no es válido: %s" +msgid "select() failed: %m" +msgstr "select() falló: %m" -#: pg_recvlogical.c:430 receivelog.c:941 +#: pg_recvlogical.c:423 receivelog.c:954 #, c-format -msgid "%s: select() failed: %s\n" -msgstr "%s: select() falló: %s\n" +msgid "could not receive data from WAL stream: %s" +msgstr "no se pudo recibir datos desde el flujo de WAL: %s" -#: pg_recvlogical.c:439 receivelog.c:993 +#: pg_recvlogical.c:465 pg_recvlogical.c:516 receivelog.c:998 receivelog.c:1064 #, c-format -msgid "%s: could not receive data from WAL stream: %s" -msgstr "%s: no se pudo recibir datos desde el flujo de WAL: %s" +msgid "streaming header too small: %d" +msgstr "cabecera de flujo demasiado pequeña: %d" -#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1038 -#: receivelog.c:1105 +#: pg_recvlogical.c:500 receivelog.c:836 #, c-format -msgid "%s: streaming header too small: %d\n" -msgstr "%s: cabecera de flujo demasiado pequeña: %d\n" +msgid "unrecognized streaming header: \"%c\"" +msgstr "cabecera de flujo no reconocida: «%c»" -#: pg_recvlogical.c:517 receivelog.c:872 +#: pg_recvlogical.c:554 pg_recvlogical.c:566 #, c-format -msgid "%s: unrecognized streaming header: \"%c\"\n" -msgstr "%s: cabecera de flujo no reconocida: «%c»\n" +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "no se pudo escribir %u bytes al archivo de registro «%s»: %m" -#: pg_recvlogical.c:573 pg_recvlogical.c:587 +#: pg_recvlogical.c:594 receivelog.c:632 receivelog.c:669 #, c-format -msgid "%s: could not write %u bytes to log file \"%s\": %s\n" -msgstr "%s: no se pudo escribir %u bytes al archivo de registro «%s»: %s\n" +msgid "unexpected termination of replication stream: %s" +msgstr "término inesperado del flujo de replicación: %s" -#: pg_recvlogical.c:617 receivelog.c:665 receivelog.c:703 +#: pg_recvlogical.c:718 #, c-format -msgid "%s: unexpected termination of replication stream: %s" -msgstr "%s: término inesperado del flujo de replicación: %s" +msgid "invalid fsync interval \"%s\"" +msgstr "intervalo de fsync «%s» no válido" -#: pg_recvlogical.c:741 +#: pg_recvlogical.c:756 #, c-format -msgid "%s: invalid fsync interval \"%s\"\n" -msgstr "%s: intervalo de fsync «%s» no válido\n" +msgid "could not parse start position \"%s\"" +msgstr "no se pudo interpretar la posición de inicio «%s»" -#: pg_recvlogical.c:782 +#: pg_recvlogical.c:845 #, c-format -msgid "%s: could not parse start position \"%s\"\n" -msgstr "%s: no se pudo interpretar la posición de inicio «%s»\n" +msgid "no slot specified" +msgstr "no se especificó slot" -#: pg_recvlogical.c:792 +#: pg_recvlogical.c:853 #, c-format -msgid "%s: could not parse end position \"%s\"\n" -msgstr "%s: no se pudo interpretar la posición final «%s»\n" +msgid "no target file specified" +msgstr "no se especificó un archivo de destino" -#: pg_recvlogical.c:876 +#: pg_recvlogical.c:861 #, c-format -msgid "%s: no slot specified\n" -msgstr "%s: no se especificó slot\n" +msgid "no database specified" +msgstr "no se especificó una base de datos" -#: pg_recvlogical.c:884 +#: pg_recvlogical.c:869 #, c-format -msgid "%s: no target file specified\n" -msgstr "%s: no se especificó un archivo de destino\n" +msgid "at least one action needs to be specified" +msgstr "debe especificarse al menos una operación" -#: pg_recvlogical.c:892 +#: pg_recvlogical.c:877 #, c-format -msgid "%s: no database specified\n" -msgstr "%s: no se especificó una base de datos\n" +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "no puede usarse --create-slot o --start junto con --drop-slot" -#: pg_recvlogical.c:900 +#: pg_recvlogical.c:885 #, c-format -msgid "%s: at least one action needs to be specified\n" -msgstr "%s: debe especificarse al menos una operación\n" +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "no puede usarse --create-slot o --drop-slot junto con --startpos" -#: pg_recvlogical.c:908 +#: pg_recvlogical.c:893 #, c-format -msgid "%s: cannot use --create-slot or --start together with --drop-slot\n" -msgstr "%s: no puede usarse --create-slot o --start junto con --drop-slot\n" +msgid "--endpos may only be specified with --start" +msgstr "--endpos solo se puede utilizar con --start" -#: pg_recvlogical.c:916 +#: pg_recvlogical.c:924 #, c-format -msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" -msgstr "%s: no puede usarse --create-slot o --drop-slot junto con --startpos\n" +msgid "could not establish database-specific replication connection" +msgstr "no se pudo establecer una conexión de replicación específica a una base de datos" -#: pg_recvlogical.c:925 +#: pg_recvlogical.c:1023 #, c-format -msgid "%s: --endpos may only be specified with --start\n" -msgstr "%s: --endpos solo se puede utilizar con --start\n" +msgid "endpos %X/%X reached by keepalive" +msgstr "ubicación de término %X/%X alcanzado por «keep-alive»" -#: pg_recvlogical.c:957 +#: pg_recvlogical.c:1026 #, c-format -msgid "%s: could not establish database-specific replication connection\n" -msgstr "%s: no se pudo establecer una conexión de replicación específica a una base de datos\n" +msgid "endpos %X/%X reached by record at %X/%X" +msgstr "ubicación de término %X/%X alcanzado por registro en %X/%X" -#: receivelog.c:71 +#: receivelog.c:72 #, c-format -msgid "%s: could not create archive status file \"%s\": %s\n" -msgstr "%s: no se pudo crear el archivo de estado «%s»: %s\n" +msgid "could not create archive status file \"%s\": %s" +msgstr "no se pudo crear el archivo de estado «%s»: %s" #: receivelog.c:119 #, c-format -msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" -msgstr "%s: no se pudo obtener el tamaño del archivo de WAL «%s»: %s\n" +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "no se pudo obtener el tamaño del archivo de WAL «%s»: %s" -#: receivelog.c:130 +#: receivelog.c:129 #, c-format -msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo de WAL «%s»: %s\n" +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "no se pudo abrir el archivo de WAL «%s»: %s" -#: receivelog.c:139 +#: receivelog.c:137 #, c-format -msgid "%s: could not sync existing write-ahead log file \"%s\": %s\n" -msgstr "%s: no se pudo sincronizar (fsync) el archivo de WAL «%s»: %s\n" +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "no se pudo sincronizar (fsync) el archivo de WAL «%s»: %s" -#: receivelog.c:154 +#: receivelog.c:151 #, c-format -msgid "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" -msgstr "%s: el archivo de WAL «%s» mide %d bytes, debería ser 0 o %d\n" +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "el archivo de WAL «%s» mide %d byte, debería ser 0 o %d" +msgstr[1] "el archivo de WAL «%s» mide %d bytes, debería ser 0 o %d" -#: receivelog.c:167 +#: receivelog.c:166 #, c-format -msgid "%s: could not open write-ahead log file \"%s\": %s\n" -msgstr "%s: no se pudo abrir archivo de WAL «%s»: %s\n" +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "no se pudo abrir archivo de WAL «%s»: %s" -#: receivelog.c:194 +#: receivelog.c:192 #, c-format -msgid "%s: could not determine seek position in file \"%s\": %s\n" -msgstr "%s: no se pudo determinar la posición (seek) en el archivo «%s»: %s\n" +msgid "could not determine seek position in file \"%s\": %s" +msgstr "no se pudo determinar la posición (seek) en el archivo «%s»: %s" -#: receivelog.c:209 +#: receivelog.c:206 #, c-format -msgid "%s: not renaming \"%s%s\", segment is not complete\n" -msgstr "%s: no se cambiará el nombre a «%s%s», el segmento no está completo\n" +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "no se cambiará el nombre a «%s%s», el segmento no está completo" -#: receivelog.c:278 +#: receivelog.c:218 receivelog.c:303 receivelog.c:678 #, c-format -msgid "%s: server reported unexpected history file name for timeline %u: %s\n" -msgstr "%s: el servidor reportó un nombre inesperado para el archivo de historia de timeline %u: %s\n" +msgid "could not close file \"%s\": %s" +msgstr "no se pudo cerrar el archivo «%s»: %s" -#: receivelog.c:286 +#: receivelog.c:275 #, c-format -msgid "%s: could not create timeline history file \"%s\": %s\n" -msgstr "%s: no se pudo crear el archivo de historia de timeline «%s»: %s\n" +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "el servidor reportó un nombre inesperado para el archivo de historia de timeline %u: %s" -#: receivelog.c:293 +#: receivelog.c:283 #, c-format -msgid "%s: could not write timeline history file \"%s\": %s\n" -msgstr "%s: no se pudo escribir al archivo de historia de timeline «%s»: %s\n" +msgid "could not create timeline history file \"%s\": %s" +msgstr "no se pudo crear el archivo de historia de timeline «%s»: %s" -#: receivelog.c:383 +#: receivelog.c:290 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions older than %s\n" -msgstr "%s: versión de servidor %s incompatible; el cliente no soporta flujos de servidores anteriores a la versión %s\n" +msgid "could not write timeline history file \"%s\": %s" +msgstr "no se pudo escribir al archivo de historia de timeline «%s»: %s" -#: receivelog.c:393 +#: receivelog.c:380 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions newer than %s\n" -msgstr "%s: versión de servidor %s incompatible; el cliente no soporta flujos de servidores posteriores a %s\n" +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores anteriores a la versión %s" -#: receivelog.c:498 streamutil.c:264 streamutil.c:303 +#: receivelog.c:389 #, c-format -msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" -msgstr "%s: no se pudo identificar al sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos\n" +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores posteriores a %s" -#: receivelog.c:506 +#: receivelog.c:491 streamutil.c:430 streamutil.c:467 #, c-format -msgid "%s: system identifier does not match between base backup and streaming connection\n" -msgstr "%s: el identificador de sistema no coincide entre el respaldo base y la conexión de flujo\n" +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo identificar al sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos" -#: receivelog.c:514 +#: receivelog.c:498 #, c-format -msgid "%s: starting timeline %u is not present in the server\n" -msgstr "%s: el timeline de inicio %u no está presente en el servidor\n" +msgid "system identifier does not match between base backup and streaming connection" +msgstr "el identificador de sistema no coincide entre el respaldo base y la conexión de flujo" -#: receivelog.c:533 +#: receivelog.c:504 #, c-format -msgid "%s: could not create temporary replication slot \"%s\": %s" -msgstr "%s: no se pudo crear slot temporal de replicación «%s»: %s" +msgid "starting timeline %u is not present in the server" +msgstr "el timeline de inicio %u no está presente en el servidor" -#: receivelog.c:574 +#: receivelog.c:545 #, c-format -msgid "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: respuesta inesperada a la orden TIMELINE_HISTORY: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos\n" +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "respuesta inesperada a la orden TIMELINE_HISTORY: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" -#: receivelog.c:646 +#: receivelog.c:616 #, c-format -msgid "%s: server reported unexpected next timeline %u, following timeline %u\n" -msgstr "%s: el servidor reportó un timeline siguiente %u inesperado, a continuación del timeline %u\n" +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "el servidor reportó un timeline siguiente %u inesperado, a continuación del timeline %u" -#: receivelog.c:653 +#: receivelog.c:622 #, c-format -msgid "%s: server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X\n" -msgstr "%s: el servidor paró la transmisión del timeline %u en %X/%X, pero reportó que el siguiente timeline %u comienza en %X/%X\n" +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "el servidor paró la transmisión del timeline %u en %X/%X, pero reportó que el siguiente timeline %u comienza en %X/%X" -#: receivelog.c:694 +#: receivelog.c:662 #, c-format -msgid "%s: replication stream was terminated before stop point\n" -msgstr "%s: el flujo de replicación terminó antes del punto de término\n" +msgid "replication stream was terminated before stop point" +msgstr "el flujo de replicación terminó antes del punto de término" -#: receivelog.c:743 +#: receivelog.c:708 #, c-format -msgid "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: respuesta inesperada después del fin-de-timeline: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos\n" +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "respuesta inesperada después del fin-de-timeline: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" -#: receivelog.c:753 +#: receivelog.c:717 #, c-format -msgid "%s: could not parse next timeline's starting point \"%s\"\n" -msgstr "%s: no se pudo interpretar el punto de inicio del siguiente timeline «%s»\n" +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "no se pudo interpretar el punto de inicio del siguiente timeline «%s»" -#: receivelog.c:1124 +#: receivelog.c:766 receivelog.c:1018 #, c-format -msgid "%s: received write-ahead log record for offset %u with no file open\n" -msgstr "%s: se recibió un registro de WAL para el desplazamiento %u sin ningún archivo abierto\n" +msgid "could not fsync file \"%s\": %s" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %s" -#: receivelog.c:1135 +#: receivelog.c:1081 #, c-format -msgid "%s: got WAL data offset %08x, expected %08x\n" -msgstr "%s: se obtuvo desplazamiento de datos WAL %08x, se esperaba %08x\n" +msgid "received write-ahead log record for offset %u with no file open" +msgstr "se recibió un registro de WAL para el desplazamiento %u sin ningún archivo abierto" -#: receivelog.c:1170 +#: receivelog.c:1091 #, c-format -msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" -msgstr "%s: no se pudo escribir %u bytes al archivo WAL «%s»: %s\n" +msgid "got WAL data offset %08x, expected %08x" +msgstr "se obtuvo desplazamiento de datos WAL %08x, se esperaba %08x" -#: receivelog.c:1195 receivelog.c:1236 receivelog.c:1267 +#: receivelog.c:1125 #, c-format -msgid "%s: could not send copy-end packet: %s" -msgstr "%s: no se pudo enviar el paquete copy-end: %s" +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "no se pudo escribir %u bytes al archivo WAL «%s»: %s" -#: streamutil.c:148 +#: receivelog.c:1150 receivelog.c:1190 receivelog.c:1221 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "no se pudo enviar el paquete copy-end: %s" + +#: streamutil.c:162 msgid "Password: " msgstr "Contraseña: " -#: streamutil.c:173 +#: streamutil.c:187 +#, c-format +msgid "could not connect to server" +msgstr "no se pudo conectar al servidor" + +#: streamutil.c:204 #, c-format -msgid "%s: could not connect to server\n" -msgstr "%s: no se pudo conectar al servidor\n" +msgid "could not connect to server: %s" +msgstr "no se pudo conectar al servidor: %s" -#: streamutil.c:191 +#: streamutil.c:233 #, c-format -msgid "%s: could not connect to server: %s" -msgstr "%s: no se pudo conectar al servidor: %s" +msgid "could not clear search_path: %s" +msgstr "no se pudo limpiar search_path: %s" -#: streamutil.c:215 +#: streamutil.c:249 #, c-format -msgid "%s: could not determine server setting for integer_datetimes\n" -msgstr "%s: no se pudo determinar la opción integer_datetimes del servidor\n" +msgid "could not determine server setting for integer_datetimes" +msgstr "no se pudo determinar la opción integer_datetimes del servidor" -#: streamutil.c:224 +#: streamutil.c:256 #, c-format -msgid "%s: integer_datetimes compile flag does not match server\n" -msgstr "%s: la opción de compilación integer_datetimes no coincide con el servidor\n" +msgid "integer_datetimes compile flag does not match server" +msgstr "la opción de compilación integer_datetimes no coincide con el servidor" -#: streamutil.c:375 +#: streamutil.c:307 #, c-format -msgid "%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: no se pudo create el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos\n" +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo obtener el tamaño del segmento de WAL: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos" -#: streamutil.c:420 +#: streamutil.c:317 #, c-format -msgid "%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s: no se pudo eliminar el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos\n" +msgid "WAL segment size could not be parsed" +msgstr "el tamaño de segmento de WAL no pudo ser analizado" -#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n" -#~ msgstr "" -#~ " -x, --xlog incluye los archivos WAL necesarios en el respaldo\n" -#~ " (modo fetch)\n" +#: streamutil.c:332 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d byte" +msgstr[1] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d bytes" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "no se pudo obtener el indicador de acceso de grupo: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos" -#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" -#~ msgstr "%s: no se puede tanto --xlog como --xlog-method\n" +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "el indicador de acceso de grupo no pudo ser analizado: %s" -#~ msgid "%s: WAL streaming can only be used in plain mode\n" -#~ msgstr "%s: el flujo de WAL sólo puede usar en modo «plain»\n" +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "no se pudo create el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "no se pudo eliminar el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos" -#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" -#~ msgstr "%s: no se pudo hacer stat del archivo de transacción «%s»: %s\n" +#: walmethods.c:439 walmethods.c:928 +msgid "could not compress data" +msgstr "no se pudo comprimir datos" -#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" -#~ msgstr "%s: no se pudo rellenar (pad) el archivo de transacción «%s»: %s\n" +#: walmethods.c:471 +msgid "could not reset compression stream" +msgstr "no se pudo restablecer el flujo comprimido" -#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" -#~ msgstr "%s: no se pudo posicionar (seek) al inicio del archivo de transacción «%s»: %s\n" +#: walmethods.c:569 +msgid "could not initialize compression library" +msgstr "no se pudo inicializar la biblioteca de compresión" -#~ msgid "%s: could not rename file \"%s\": %s\n" -#~ msgstr "%s: no se pudo cambiar el nombre al archivo «%s»: %s\n" +#: walmethods.c:581 +msgid "implementation error: tar files can't have more than one open file" +msgstr "error de implementación: los archivos tar no pueden tener abierto más de un fichero" -#~ msgid "%s: could not open timeline history file \"%s\": %s\n" -#~ msgstr "%s: no se pudo abrir el archivo de historia de timeline «%s»: %s\n" +#: walmethods.c:595 +msgid "could not create tar header" +msgstr "no se pudo crear la cabecera del archivo tar" -#~ msgid "%s: socket not open" -#~ msgstr "%s: socket no abierto" +#: walmethods.c:609 walmethods.c:649 walmethods.c:844 walmethods.c:855 +msgid "could not change compression parameters" +msgstr "no se pudo cambiar los parámetros de compresión" -#~ msgid "%s: could not parse file mode\n" -#~ msgstr "%s: nose pudo interpretar el modo del archivo\n" +#: walmethods.c:731 +msgid "unlink not supported with compression" +msgstr "unlink no soportado con compresión" -#~ msgid "%s: could not parse file size\n" -#~ msgstr "%s: no se pudo interpretar el tamaño del archivo\n" +#: walmethods.c:953 +msgid "could not close compression stream" +msgstr "no se pudo cerrar el flujo comprimido" diff --git a/src/bin/pg_basebackup/po/fr.po b/src/bin/pg_basebackup/po/fr.po index b1d3a4fc59d..fddb683bbdf 100644 --- a/src/bin/pg_basebackup/po/fr.po +++ b/src/bin/pg_basebackup/po/fr.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 02:44+0000\n" -"PO-Revision-Date: 2017-08-04 19:55+0200\n" +"POT-Creation-Date: 2017-08-07 14:15+0000\n" +"PO-Revision-Date: 2017-08-07 18:13+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" @@ -33,7 +33,8 @@ msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" #: pg_receivewal.c:252 pg_recvlogical.c:353 #, c-format msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" +msgstr "" +"%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n" #: ../../common/file_utils.c:162 pg_receivewal.c:153 #, c-format @@ -51,8 +52,8 @@ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n" msgid "%s: could not open file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:802 -#: receivelog.c:1059 +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: receivelog.c:804 receivelog.c:1061 #, c-format msgid "%s: could not fsync file \"%s\": %s\n" msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n" @@ -90,32 +91,43 @@ msgstr "%s : suppression du répertoire des journaux de transactions « %s »\n" #: pg_basebackup.c:180 #, c-format msgid "%s: failed to remove WAL directory\n" -msgstr "%s : échec de la suppression du répertoire des journaux de transactions\n" +msgstr "" +"%s : échec de la suppression du répertoire des journaux de transactions\n" #: pg_basebackup.c:186 #, c-format msgid "%s: removing contents of WAL directory \"%s\"\n" -msgstr "%s : suppression du contenu du répertoire des journaux de transactions « %s »\n" +msgstr "" +"%s : suppression du contenu du répertoire des journaux de transactions « %s " +"»\n" #: pg_basebackup.c:189 #, c-format msgid "%s: failed to remove contents of WAL directory\n" -msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transactions\n" +msgstr "" +"%s : échec de la suppression du contenu du répertoire des journaux de " +"transactions\n" #: pg_basebackup.c:197 #, c-format msgid "%s: data directory \"%s\" not removed at user's request\n" -msgstr "%s : répertoire des données « %s » non supprimé à la demande de l'utilisateur\n" +msgstr "" +"%s : répertoire des données « %s » non supprimé à la demande de " +"l'utilisateur\n" #: pg_basebackup.c:202 #, c-format msgid "%s: WAL directory \"%s\" not removed at user's request\n" -msgstr "%s : répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur\n" +msgstr "" +"%s : répertoire des journaux de transactions « %s » non supprimé à la " +"demande de l'utilisateur\n" #: pg_basebackup.c:208 #, c-format msgid "%s: changes to tablespace directories will not be undone\n" -msgstr "%s : les modifications des répertoires des tablespaces ne seront pas annulées\n" +msgstr "" +"%s : les modifications des répertoires des tablespaces ne seront pas " +"annulées\n" #: pg_basebackup.c:250 #, c-format @@ -129,18 +141,25 @@ msgstr "%s : multiple signes « = » dans la correspondance de tablespace\n" #: pg_basebackup.c:273 #, c-format -msgid "%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" -msgstr "%s : format de correspondance de tablespace « %s » invalide, doit être « ANCIENREPERTOIRE=NOUVEAUREPERTOIRE »\n" +msgid "" +"%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" +msgstr "" +"%s : format de correspondance de tablespace « %s » invalide, doit être « " +"ANCIENREPERTOIRE=NOUVEAUREPERTOIRE »\n" #: pg_basebackup.c:286 #, c-format msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s : l'ancien répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s\n" +msgstr "" +"%s : l'ancien répertoire n'est pas un chemin absolu dans la correspondance " +"de tablespace : %s\n" #: pg_basebackup.c:293 #, c-format msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" -msgstr "%s : le nouveau répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s\n" +msgstr "" +"%s : le nouveau répertoire n'est pas un chemin absolu dans la " +"correspondance de tablespace : %s\n" #: pg_basebackup.c:327 #, c-format @@ -148,7 +167,8 @@ msgid "" "%s takes a base backup of a running PostgreSQL server.\n" "\n" msgstr "" -"%s prend une sauvegarde binaire d'un serveur PostgreSQL en cours d'exécution.\n" +"%s prend une sauvegarde binaire d'un serveur PostgreSQL en cours " +"d'exécution.\n" "\n" #: pg_basebackup.c:329 pg_receivewal.c:76 pg_recvlogical.c:77 @@ -173,12 +193,15 @@ msgstr "" #: pg_basebackup.c:332 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" -msgstr " -D, --pgdata=RÉPERTOIRE reçoit la sauvegarde de base dans ce répertoire\n" +msgstr "" +" -D, --pgdata=RÉPERTOIRE reçoit la sauvegarde de base dans ce " +"répertoire\n" #: pg_basebackup.c:333 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" -msgstr " -F, --format=p|t format en sortie (plain (par défaut), tar)\n" +msgstr "" +" -F, --format=p|t format en sortie (plain (par défaut), tar)\n" #: pg_basebackup.c:334 #, c-format @@ -187,7 +210,8 @@ msgid "" " (in kB/s, or use suffix \"k\" or \"M\")\n" msgstr "" " -r, --max-rate=TAUX taux maximum de transfert du répertoire de\n" -" données (en Ko/s, ou utiliser le suffixe « k »\n" +" données (en Ko/s, ou utiliser le suffixe « k " +"»\n" " ou « M »)\n" #: pg_basebackup.c:336 @@ -195,7 +219,8 @@ msgstr "" msgid "" " -R, --write-recovery-conf\n" " write recovery.conf for replication\n" -msgstr " -R, --write-recovery-conf écrit le recovery.conf pour la réplication\n" +msgstr "" +" -R, --write-recovery-conf écrit le recovery.conf pour la réplication\n" #: pg_basebackup.c:338 pg_receivewal.c:84 #, c-format @@ -204,8 +229,11 @@ msgstr " -S, --slot=NOMREP slot de réplication à utiliser\n" #: pg_basebackup.c:339 #, c-format -msgid " --no-slot prevent creation of temporary replication slot\n" -msgstr " --no-slot empêche la création de slots de réplication temporaires\n" +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr "" +" --no-slot empêche la création de slots de réplication " +"temporaires\n" #: pg_basebackup.c:340 #, c-format @@ -214,7 +242,8 @@ msgid "" " relocate tablespace in OLDDIR to NEWDIR\n" msgstr "" " -T, --tablespace-mapping=ANCIENREP=NOUVEAUREP\n" -" déplacer le répertoire ANCIENREP en NOUVEAUREP\n" +" déplacer le répertoire ANCIENREP en " +"NOUVEAUREP\n" #: pg_basebackup.c:342 #, c-format @@ -223,7 +252,8 @@ msgid "" " include required WAL files with specified method\n" msgstr "" " -X, --wal-method=none|fetch|stream\n" -" inclut les journaux de transactions requis avec\n" +" inclut les journaux de transactions requis " +"avec\n" " la méthode spécifiée\n" #: pg_basebackup.c:344 @@ -240,7 +270,8 @@ msgstr " -z, --gzip compresse la sortie tar\n" #: pg_basebackup.c:346 #, c-format -msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgid "" +" -Z, --compress=0-9 compress tar output with given compression level\n" msgstr "" " -Z, --compress=0-9 compresse la sortie tar avec le niveau de\n" " compression indiqué\n" @@ -259,7 +290,8 @@ msgstr "" msgid "" " -c, --checkpoint=fast|spread\n" " set fast or spread checkpointing\n" -msgstr " -c, --checkpoint=fast|spread exécute un CHECKPOINT rapide ou réparti\n" +msgstr "" +" -c, --checkpoint=fast|spread exécute un CHECKPOINT rapide ou réparti\n" #: pg_basebackup.c:350 #, c-format @@ -273,13 +305,18 @@ msgstr " -n, --no-clean ne nettoie pas en cas d'erreur\n" #: pg_basebackup.c:352 #, c-format -msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" -msgstr " -N, --no-sync n'attend pas que les modifications soient proprement écrites sur disque\n" +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync n'attend pas que les modifications soient " +"proprement écrites sur disque\n" #: pg_basebackup.c:353 #, c-format msgid " -P, --progress show progress information\n" -msgstr " -P, --progress affiche la progression de la sauvegarde\n" +msgstr "" +" -P, --progress affiche la progression de la sauvegarde\n" #: pg_basebackup.c:354 pg_receivewal.c:86 pg_recvlogical.c:98 #, c-format @@ -328,9 +365,11 @@ msgstr "" #, c-format msgid "" " -s, --status-interval=INTERVAL\n" -" time between status packets sent to server (in seconds)\n" +" time between status packets sent to server (in " +"seconds)\n" msgstr "" -" -s, --status-interval=INTERVAL durée entre l'envoi de paquets de statut au\n" +" -s, --status-interval=INTERVAL durée entre l'envoi de paquets de statut " +"au\n" " serveur (en secondes)\n" #: pg_basebackup.c:363 pg_receivewal.c:94 pg_recvlogical.c:105 @@ -345,9 +384,12 @@ msgstr " -w, --no-password ne demande jamais le mot de passe\n" #: pg_basebackup.c:365 pg_receivewal.c:96 pg_recvlogical.c:107 #, c-format -msgid " -W, --password force password prompt (should happen automatically)\n" +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" msgstr "" -" -W, --password force la demande du mot de passe (devrait arriver\n" +" -W, --password force la demande du mot de passe (devrait " +"arriver\n" " automatiquement)\n" #: pg_basebackup.c:366 pg_receivewal.c:100 pg_recvlogical.c:108 @@ -368,17 +410,20 @@ msgstr "%s : n'a pas pu lire à partir du tube : %s\n" #: streamutil.c:286 #, c-format msgid "%s: could not parse write-ahead log location \"%s\"\n" -msgstr "%s : n'a pas pu analyser l'emplacement du journal des transactions « %s »\n" +msgstr "" +"%s : n'a pas pu analyser l'emplacement du journal des transactions « %s »\n" #: pg_basebackup.c:515 pg_receivewal.c:428 #, c-format msgid "%s: could not finish writing WAL files: %s\n" -msgstr "%s : n'a pas pu finir l'écriture dans les fichiers de transactions : %s\n" +msgstr "" +"%s : n'a pas pu finir l'écriture dans les fichiers de transactions : %s\n" #: pg_basebackup.c:565 #, c-format msgid "%s: could not create pipe for background process: %s\n" -msgstr "%s : n'a pas pu créer un tube pour le processus en tâche de fond : %s\n" +msgstr "" +"%s : n'a pas pu créer un tube pour le processus en tâche de fond : %s\n" #: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1423 #, c-format @@ -429,7 +474,8 @@ msgstr[1] "%*s/%s Ko (%d%%), %d/%d tablespaces" #: pg_basebackup.c:804 #, c-format msgid "%s: transfer rate \"%s\" is not a valid value\n" -msgstr "%s : le taux de transfert « %s » ne correspond pas à une valeur valide\n" +msgstr "" +"%s : le taux de transfert « %s » ne correspond pas à une valeur valide\n" #: pg_basebackup.c:811 #, c-format @@ -491,14 +537,14 @@ msgstr "%s : n'a pas pu obtenir le flux de données de COPY : %s" msgid "%s: could not close compressed file \"%s\": %s\n" msgstr "%s : n'a pas pu fermer le fichier compressé « %s » : %s\n" -#: pg_basebackup.c:1132 pg_recvlogical.c:631 receivelog.c:221 receivelog.c:306 -#: receivelog.c:712 +#: pg_basebackup.c:1132 pg_recvlogical.c:631 receivelog.c:223 receivelog.c:308 +#: receivelog.c:714 #, c-format msgid "%s: could not close file \"%s\": %s\n" msgstr "%s : n'a pas pu fermer le fichier « %s » : %s\n" #: pg_basebackup.c:1143 pg_basebackup.c:1359 pg_recvlogical.c:453 -#: receivelog.c:1007 +#: receivelog.c:1009 #, c-format msgid "%s: could not read COPY data: %s" msgstr "%s : n'a pas pu lire les données du COPY : %s" @@ -531,7 +577,8 @@ msgstr "%s : n'a pas pu configurer les droits sur le fichier « %s » : %s\n" #: pg_basebackup.c:1543 #, c-format msgid "%s: COPY stream ended before last file was finished\n" -msgstr "%s : le flux COPY s'est terminé avant que le dernier fichier soit terminé\n" +msgstr "" +"%s : le flux COPY s'est terminé avant que le dernier fichier soit terminé\n" #: pg_basebackup.c:1571 pg_basebackup.c:1591 pg_basebackup.c:1598 #: pg_basebackup.c:1651 @@ -547,15 +594,18 @@ msgstr "%s : version « %s » du serveur incompatible\n" #: pg_basebackup.c:1739 #, c-format msgid "HINT: use -X none or -X fetch to disable log streaming\n" -msgstr "ASTUCE : utilisez -X none ou -X fetch pour désactiver la réplication en flux\n" +msgstr "" +"ASTUCE : utilisez -X none ou -X fetch pour désactiver la réplication en " +"flux\n" #: pg_basebackup.c:1765 #, c-format msgid "%s: initiating base backup, waiting for checkpoint to complete\n" -msgstr "%s : début de la sauvegarde de base, en attente de la fin du checkpoint\n" +msgstr "" +"%s : début de la sauvegarde de base, en attente de la fin du checkpoint\n" -#: pg_basebackup.c:1783 pg_recvlogical.c:270 receivelog.c:490 receivelog.c:561 -#: receivelog.c:601 streamutil.c:256 streamutil.c:364 streamutil.c:410 +#: pg_basebackup.c:1783 pg_recvlogical.c:270 receivelog.c:492 receivelog.c:563 +#: receivelog.c:603 streamutil.c:256 streamutil.c:364 streamutil.c:410 #, c-format msgid "%s: could not send replication command \"%s\": %s" msgstr "%s : n'a pas pu envoyer la commande de réplication « %s » : %s" @@ -567,8 +617,13 @@ msgstr "%s : n'a pas pu initier la sauvegarde de base : %s" #: pg_basebackup.c:1801 #, c-format -msgid "%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s : le serveur a renvoyé une réponse inattendue à la commande BASE_BACKUP ; a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs\n" +msgid "" +"%s: server returned unexpected response to BASE_BACKUP command; got %d rows " +"and %d fields, expected %d rows and %d fields\n" +msgstr "" +"%s : le serveur a renvoyé une réponse inattendue à la commande " +"BASE_BACKUP ; a récupéré %d lignes et %d champs, alors qu'il attendait %d " +"lignes et %d champs\n" #: pg_basebackup.c:1809 #, c-format @@ -578,7 +633,8 @@ msgstr "%s : checkpoint terminé\n" #: pg_basebackup.c:1824 #, c-format msgid "%s: write-ahead log start point: %s on timeline %u\n" -msgstr "%s : point de départ du journal de transactions : %s sur la timeline %u\n" +msgstr "" +"%s : point de départ du journal de transactions : %s sur la timeline %u\n" #: pg_basebackup.c:1833 #, c-format @@ -593,12 +649,15 @@ msgstr "%s : aucune donnée renvoyée du serveur\n" #: pg_basebackup.c:1871 #, c-format msgid "%s: can only write single tablespace to stdout, database has %d\n" -msgstr "%s : peut seulement écrire un tablespace sur la sortie standard, la base en a %d\n" +msgstr "" +"%s : peut seulement écrire un tablespace sur la sortie standard, la base en " +"a %d\n" #: pg_basebackup.c:1883 #, c-format msgid "%s: starting background WAL receiver\n" -msgstr "%s : lance le récepteur de journaux de transactions en tâche de fond\n" +msgstr "" +"%s : lance le récepteur de journaux de transactions en tâche de fond\n" #: pg_basebackup.c:1914 #, c-format @@ -610,7 +669,9 @@ msgstr "" #: pg_basebackup.c:1921 #, c-format msgid "%s: no write-ahead log end position returned from server\n" -msgstr "%s : aucune position de fin du journal de transactions renvoyée par le serveur\n" +msgstr "" +"%s : aucune position de fin du journal de transactions renvoyée par le " +"serveur\n" #: pg_basebackup.c:1927 #, c-format @@ -625,7 +686,8 @@ msgstr "%s : échec lors de la réception finale : %s" #: pg_basebackup.c:1957 #, c-format msgid "%s: waiting for background process to finish streaming ...\n" -msgstr "%s : en attente que le processus en tâche de fond termine le flux...\n" +msgstr "" +"%s : en attente que le processus en tâche de fond termine le flux...\n" #: pg_basebackup.c:1963 #, c-format @@ -675,13 +737,18 @@ msgstr "%s : sauvegarde de base terminée\n" #: pg_basebackup.c:2145 #, c-format msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" -msgstr "%s : format de sortie « %s » invalide, doit être soit « plain » soit « tar »\n" +msgstr "" +"%s : format de sortie « %s » invalide, doit être soit « plain » soit « tar " +"»\n" #: pg_basebackup.c:2190 #, c-format -msgid "%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n" +msgid "" +"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or " +"\"none\"\n" msgstr "" -"%s : option wal-method « %s » invalide, doit être soit « fetch » soit « stream »\n" +"%s : option wal-method « %s » invalide, doit être soit « fetch » soit « " +"stream »\n" "soit « none »\n" #: pg_basebackup.c:2218 pg_receivewal.c:556 @@ -691,7 +758,8 @@ msgstr "%s : niveau de compression « %s » invalide\n" #: pg_basebackup.c:2230 #, c-format -msgid "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" +msgid "" +"%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" msgstr "" "%s : argument « %s » invalide pour le CHECKPOINT, doit être soit « fast »\n" "soit « spread »\n" @@ -716,7 +784,8 @@ msgstr "Essayer « %s --help » pour plus d'informations.\n" #: pg_basebackup.c:2285 pg_receivewal.c:591 pg_recvlogical.c:864 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" +msgstr "" +"%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" #: pg_basebackup.c:2297 pg_receivewal.c:621 #, c-format @@ -731,12 +800,16 @@ msgstr "%s : seules les sauvegardes en mode tar peuvent être compressées\n" #: pg_basebackup.c:2319 #, c-format msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" -msgstr "%s : ne peut pas envoyer les journaux de transactions vers stdout en mode tar\n" +msgstr "" +"%s : ne peut pas envoyer les journaux de transactions vers stdout en mode " +"tar\n" #: pg_basebackup.c:2329 #, c-format msgid "%s: replication slots can only be used with WAL streaming\n" -msgstr "%s : les slots de réplications peuvent seulement être utilisés avec la réplication en flux des WAL\n" +msgstr "" +"%s : les slots de réplications peuvent seulement être utilisés avec la " +"réplication en flux des WAL\n" #: pg_basebackup.c:2341 #, c-format @@ -770,7 +843,8 @@ msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n" #: pg_basebackup.c:2423 #, c-format msgid "%s: symlinks are not supported on this platform\n" -msgstr "%s : les liens symboliques ne sont pas supportés sur cette plateforme\n" +msgstr "" +"%s : les liens symboliques ne sont pas supportés sur cette plateforme\n" #: pg_receivewal.c:74 #, c-format @@ -792,37 +866,46 @@ msgstr "" #: pg_receivewal.c:79 #, c-format -msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgid "" +" -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr "" " -D, --directory=RÉP reçoit les journaux de transactions dans ce\n" " répertoire\n" #: pg_receivewal.c:80 pg_recvlogical.c:88 #, c-format -msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgid "" +" --if-not-exists do not error if slot already exists when creating " +"a slot\n" msgstr "" -" --if-not-exists ne pas renvoyer une erreur si le slot existe\\n\n" +" --if-not-exists ne pas renvoyer une erreur si le slot existe" +"\\n\n" " déjà lors de sa création\n" #: pg_receivewal.c:81 pg_recvlogical.c:90 #, c-format msgid " -n, --no-loop do not loop on connection lost\n" -msgstr " -n, --no-loop ne boucle pas en cas de perte de la connexion\n" +msgstr "" +" -n, --no-loop ne boucle pas en cas de perte de la " +"connexion\n" #: pg_receivewal.c:82 pg_recvlogical.c:95 #, c-format msgid "" " -s, --status-interval=SECS\n" -" time between status packets sent to server (default: %d)\n" +" time between status packets sent to server " +"(default: %d)\n" msgstr "" " -s, --status-interval=SECS durée entre l'envoi de paquets de statut au\n" " (par défaut %d)\n" #: pg_receivewal.c:85 #, c-format -msgid " --synchronous flush write-ahead log immediately after writing\n" +msgid "" +" --synchronous flush write-ahead log immediately after writing\n" msgstr "" -" --synchronous vide le journal de transactions immédiatement\n" +" --synchronous vide le journal de transactions " +"immédiatement\n" " après son écriture\n" #: pg_receivewal.c:88 @@ -843,16 +926,22 @@ msgstr "" #: pg_receivewal.c:98 pg_recvlogical.c:80 #, c-format -msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgid "" +" --create-slot create a new replication slot (for the slot's name " +"see --slot)\n" msgstr "" -" --create-slot créer un nouveau slot de réplication (pour le\n" +" --create-slot créer un nouveau slot de réplication (pour " +"le\n" " nom du slot, voir --slot)\n" #: pg_receivewal.c:99 pg_recvlogical.c:81 #, c-format -msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgid "" +" --drop-slot drop the replication slot (for the slot's name see " +"--slot)\n" msgstr "" -" --drop-slot supprimer un nouveau slot de réplication (pour\n" +" --drop-slot supprimer un nouveau slot de réplication " +"(pour\n" " le nom du slot, voir --slot)\n" #: pg_receivewal.c:111 @@ -887,7 +976,7 @@ msgstr "%s : n'a pas pu ouvrir le fichier compressé « %s » : %s\n" #: pg_receivewal.c:283 #, c-format -msgid "%s: could not seek compressed file \"%s\": %s\n" +msgid "%s: could not seek in compressed file \"%s\": %s\n" msgstr "%s : n'a pas pu chercher dans le fichier compressé « %s » : %s\n" #: pg_receivewal.c:289 @@ -897,8 +986,12 @@ msgstr "%s : n'a pas pu lire le fichier compressé « %s » : %s\n" #: pg_receivewal.c:301 #, c-format -msgid "%s: compressed segment file \"%s\" has incorrect uncompressed size %d, skipping\n" -msgstr "%s : le segment compressé « %s » a une taille %d non compressé incorrecte, ignoré\n" +msgid "" +"%s: compressed segment file \"%s\" has incorrect uncompressed size %d, " +"skipping\n" +msgstr "" +"%s : le segment compressé « %s » a une taille %d non compressé incorrecte, " +"ignoré\n" #: pg_receivewal.c:407 #, c-format @@ -923,7 +1016,9 @@ msgstr "%s : %s a besoin du slot avec l'option --slot\n" #: pg_receivewal.c:674 #, c-format -msgid "%s: replication connection using slot \"%s\" is unexpectedly database specific\n" +msgid "" +"%s: replication connection using slot \"%s\" is unexpectedly database " +"specific\n" msgstr "" "%s : la connexion de réplication utilisant le slot « %s » est spécifique à\n" "une base, ce qui est inattendu\n" @@ -947,7 +1042,8 @@ msgstr "%s : déconnecté\n" #: pg_receivewal.c:733 pg_recvlogical.c:1012 #, c-format msgid "%s: disconnected; waiting %d seconds to try again\n" -msgstr "%s : déconnecté, attente de %d secondes avant une nouvelle tentative\n" +msgstr "" +"%s : déconnecté, attente de %d secondes avant une nouvelle tentative\n" #: pg_recvlogical.c:75 #, c-format @@ -969,9 +1065,12 @@ msgstr "" #: pg_recvlogical.c:82 #, c-format -msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgid "" +" --start start streaming in a replication slot (for the " +"slot's name see --slot)\n" msgstr "" -" --start lance le flux dans un slot de réplication (pour\n" +" --start lance le flux dans un slot de réplication " +"(pour\n" " le nom du slot, voir --slot)\n" #: pg_recvlogical.c:84 @@ -982,20 +1081,26 @@ msgstr " -E, --endpos=LSN quitte après avoir reçu le LSN spécifié\n" #: pg_recvlogical.c:85 #, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" -msgstr " -f, --file=NOMFICHIER trace la réception dans ce fichier, - pour stdout\n" +msgstr "" +" -f, --file=NOMFICHIER trace la réception dans ce fichier, - pour " +"stdout\n" #: pg_recvlogical.c:86 #, c-format msgid "" " -F --fsync-interval=SECS\n" -" time between fsyncs to the output file (default: %d)\n" +" time between fsyncs to the output file (default: " +"%d)\n" msgstr "" -" -F --fsync-interval=SECS durée entre les fsyncs vers le fichier de sortie\n" +" -F --fsync-interval=SECS durée entre les fsyncs vers le fichier de " +"sortie\n" " (par défaut %d)\n" #: pg_recvlogical.c:89 #, c-format -msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgid "" +" -I, --startpos=LSN where in an existing slot should the streaming " +"start\n" msgstr "" " -I, --startpos=LSN position de début du streaming dans le slot\n" " existant\n" @@ -1007,7 +1112,8 @@ msgid "" " pass option NAME with optional value VALUE to the\n" " output plugin\n" msgstr "" -" -o, --option=NOM[=VALEUR] passe l'option NAME avec la valeur optionnelle\n" +" -o, --option=NOM[=VALEUR] passe l'option NAME avec la valeur " +"optionnelle\n" " VALEUR au plugin en sortie\n" #: pg_recvlogical.c:94 @@ -1030,9 +1136,11 @@ msgstr " -d, --dbname=NOMBASE base de données de connexion\n" #: pg_recvlogical.c:135 #, c-format msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" -msgstr "%s : confirmation d'écriture jusqu'à %X/%X et de synchronisation jusqu'à %X/%X (slot %s)\n" +msgstr "" +"%s : confirmation d'écriture jusqu'à %X/%X et de synchronisation jusqu'à %X/" +"%X (slot %s)\n" -#: pg_recvlogical.c:160 receivelog.c:349 +#: pg_recvlogical.c:160 receivelog.c:351 #, c-format msgid "%s: could not send feedback packet: %s" msgstr "%s : n'a pas pu envoyer le paquet d'informations en retour : %s" @@ -1057,28 +1165,28 @@ msgstr "%s : flux lancé\n" msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n" -#: pg_recvlogical.c:376 receivelog.c:912 +#: pg_recvlogical.c:376 receivelog.c:914 #, c-format msgid "%s: invalid socket: %s" msgstr "%s : socket invalide : %s" -#: pg_recvlogical.c:430 receivelog.c:941 +#: pg_recvlogical.c:430 receivelog.c:943 #, c-format msgid "%s: select() failed: %s\n" msgstr "%s : échec de select() : %s\n" -#: pg_recvlogical.c:439 receivelog.c:993 +#: pg_recvlogical.c:439 receivelog.c:995 #, c-format msgid "%s: could not receive data from WAL stream: %s" msgstr "%s : n'a pas pu recevoir des données du flux de WAL : %s" -#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1038 -#: receivelog.c:1105 +#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1040 +#: receivelog.c:1107 #, c-format msgid "%s: streaming header too small: %d\n" msgstr "%s : en-tête de flux trop petit : %d\n" -#: pg_recvlogical.c:517 receivelog.c:872 +#: pg_recvlogical.c:517 receivelog.c:874 #, c-format msgid "%s: unrecognized streaming header: \"%c\"\n" msgstr "%s : entête non reconnu du flux : « %c »\n" @@ -1086,9 +1194,11 @@ msgstr "%s : entête non reconnu du flux : « %c »\n" #: pg_recvlogical.c:573 pg_recvlogical.c:587 #, c-format msgid "%s: could not write %u bytes to log file \"%s\": %s\n" -msgstr "%s : n'a pas pu écrire %u octets dans le journal de transactions « %s » : %s\n" +msgstr "" +"%s : n'a pas pu écrire %u octets dans le journal de transactions « %s » : " +"%s\n" -#: pg_recvlogical.c:617 receivelog.c:665 receivelog.c:703 +#: pg_recvlogical.c:617 receivelog.c:667 receivelog.c:705 #, c-format msgid "%s: unexpected termination of replication stream: %s" msgstr "%s : fin inattendue du flux de réplication : %s" @@ -1136,7 +1246,8 @@ msgstr "%s : ne peut pas utiliser --create-slot ou --start avec --drop-slot\n" #: pg_recvlogical.c:916 #, c-format msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" -msgstr "%s : ne peut pas utiliser --create-slot ou --drop-slot avec --startpos\n" +msgstr "" +"%s : ne peut pas utiliser --create-slot ou --drop-slot avec --startpos\n" #: pg_recvlogical.c:925 #, c-format @@ -1146,7 +1257,8 @@ msgstr "%s: --endpos peut seulement être spécifié avec --start\n" #: pg_recvlogical.c:957 #, c-format msgid "%s: could not establish database-specific replication connection\n" -msgstr "%s : n'a pas pu établir une connexion de réplication spécifique à la base\n" +msgstr "" +"%s : n'a pas pu établir une connexion de réplication spécifique à la base\n" #: receivelog.c:71 #, c-format @@ -1156,137 +1268,190 @@ msgstr "%s : n'a pas pu créer le fichier de statut d'archivage « %s » : %s\n" #: receivelog.c:119 #, c-format msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" -msgstr "%s : n'a pas pu obtenir la taille du journal de transactions « %s » : %s\n" +msgstr "" +"%s : n'a pas pu obtenir la taille du journal de transactions « %s » : %s\n" #: receivelog.c:130 #, c-format msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" -msgstr "%s : n'a pas pu ouvrir le journal des transactions « %s » existant : %s\n" +msgstr "" +"%s : n'a pas pu ouvrir le journal des transactions « %s » existant : %s\n" #: receivelog.c:139 #, c-format -msgid "%s: could not sync existing write-ahead log file \"%s\": %s\n" -msgstr "%s : n'a pas pu synchroniser sur disque le journal de transactions « %s » existant : %s\n" +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" +msgstr "" +"%s : n'a pas pu synchroniser sur disque le journal de transactions « %s » " +"existant : %s\n" #: receivelog.c:154 #, c-format -msgid "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" -msgstr "" -"%s : le segment « %s » du journal de transactions comprend %d octets, cela\n" -"devrait être 0 ou %d\n" +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "" +"%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "" +"%s : le journal de transactions « %s » comprend %d octet, cela devrait être " +"0 ou %d\n" +msgstr[1] "" +"%s : le journal de transactions « %s » comprend %d octets, cela devrait " +"être 0 ou %d\n" -#: receivelog.c:167 +#: receivelog.c:169 #, c-format msgid "%s: could not open write-ahead log file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le journal de transactions « %s » : %s\n" -#: receivelog.c:194 +#: receivelog.c:196 #, c-format msgid "%s: could not determine seek position in file \"%s\": %s\n" -msgstr "%s : n'a pas pu déterminer la position de recherche dans le fichier d'archive « %s » : %s\n" +msgstr "" +"%s : n'a pas pu déterminer la position de recherche dans le fichier " +"d'archive « %s » : %s\n" -#: receivelog.c:209 +#: receivelog.c:211 #, c-format msgid "%s: not renaming \"%s%s\", segment is not complete\n" msgstr "%s : pas de renommage de « %s%s », le segment n'est pas complet\n" -#: receivelog.c:278 +#: receivelog.c:280 #, c-format msgid "%s: server reported unexpected history file name for timeline %u: %s\n" -msgstr "%s : le serveur a renvoyé un nom de fichier historique inattendu pour la timeline %u : %s\n" +msgstr "" +"%s : le serveur a renvoyé un nom de fichier historique inattendu pour la " +"timeline %u : %s\n" -#: receivelog.c:286 +#: receivelog.c:288 #, c-format msgid "%s: could not create timeline history file \"%s\": %s\n" -msgstr "%s : n'a pas pu créer le fichier historique de la timeline « %s » : %s\n" +msgstr "" +"%s : n'a pas pu créer le fichier historique de la timeline « %s » : %s\n" -#: receivelog.c:293 +#: receivelog.c:295 #, c-format msgid "%s: could not write timeline history file \"%s\": %s\n" -msgstr "%s : n'a pas pu écrire dans le fichier historique de la timeline « %s » : %s\n" +msgstr "" +"%s : n'a pas pu écrire dans le fichier historique de la timeline « %s » : " +"%s\n" -#: receivelog.c:383 +#: receivelog.c:385 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions older than %s\n" -msgstr "%s : version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus anciennes que %s\n" +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions older than %s\n" +msgstr "" +"%s : version %s du serveur incompatible ; le client ne supporte pas le " +"streaming de versions plus anciennes que %s\n" -#: receivelog.c:393 +#: receivelog.c:395 #, c-format -msgid "%s: incompatible server version %s; client does not support streaming from server versions newer than %s\n" -msgstr "%s : version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus récentes que %s\n" +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions newer than %s\n" +msgstr "" +"%s : version %s du serveur incompatible ; le client ne supporte pas le " +"streaming de versions plus récentes que %s\n" -#: receivelog.c:498 streamutil.c:265 streamutil.c:304 +#: receivelog.c:500 streamutil.c:265 streamutil.c:304 #, c-format -msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" +msgid "" +"%s: could not identify system: got %d rows and %d fields, expected %d rows " +"and %d or more fields\n" msgstr "" "%s : n'a pas pu identifier le système, a récupéré %d lignes et %d champs,\n" "attendait %d lignes et %d champs (ou plus)\n" -#: receivelog.c:506 +#: receivelog.c:508 #, c-format -msgid "%s: system identifier does not match between base backup and streaming connection\n" +msgid "" +"%s: system identifier does not match between base backup and streaming " +"connection\n" msgstr "" -"%s : l'identifiant système ne correspond pas entre la sauvegarde des fichiers\n" +"%s : l'identifiant système ne correspond pas entre la sauvegarde des " +"fichiers\n" "et la connexion de réplication\n" -#: receivelog.c:514 +#: receivelog.c:516 #, c-format msgid "%s: starting timeline %u is not present in the server\n" msgstr "%s : la timeline %u de départ n'est pas dans le serveur\n" -#: receivelog.c:533 +#: receivelog.c:535 #, c-format msgid "%s: could not create temporary replication slot \"%s\": %s" msgstr "%s : n'a pas pu créer le slot de réplication temporaire « %s » : %s" -#: receivelog.c:574 +#: receivelog.c:576 #, c-format -msgid "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s : réponse inattendue à la commande TIMELINE_HISTORY : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs\n" +msgid "" +"%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d " +"fields, expected %d rows and %d fields\n" +msgstr "" +"%s : réponse inattendue à la commande TIMELINE_HISTORY : a récupéré %d " +"lignes et %d champs, alors qu'il attendait %d lignes et %d champs\n" -#: receivelog.c:646 +#: receivelog.c:648 #, c-format -msgid "%s: server reported unexpected next timeline %u, following timeline %u\n" -msgstr "%s: le serveur a renvoyé une timeline suivante %u inattendue, après la timeline %u\n" +msgid "" +"%s: server reported unexpected next timeline %u, following timeline %u\n" +msgstr "" +"%s: le serveur a renvoyé une timeline suivante %u inattendue, après la " +"timeline %u\n" -#: receivelog.c:653 +#: receivelog.c:655 #, c-format -msgid "%s: server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X\n" -msgstr "%s : le serveur a arrêté l'envoi de la timeline %u à %X/%X, mais a indiqué que la timeline suivante, %u, commence à %X/%X\n" +msgid "" +"%s: server stopped streaming timeline %u at %X/%X, but reported next " +"timeline %u to begin at %X/%X\n" +msgstr "" +"%s : le serveur a arrêté l'envoi de la timeline %u à %X/%X, mais a indiqué " +"que la timeline suivante, %u, commence à %X/%X\n" -#: receivelog.c:694 +#: receivelog.c:696 #, c-format msgid "%s: replication stream was terminated before stop point\n" -msgstr "%s : le flux de réplication a été abandonné avant d'arriver au point d'arrêt\n" +msgstr "" +"%s : le flux de réplication a été abandonné avant d'arriver au point " +"d'arrêt\n" -#: receivelog.c:743 +#: receivelog.c:745 #, c-format -msgid "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields\n" -msgstr "%s : ensemble de résultats inattendu après la fin de la timeline : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs\n" +msgid "" +"%s: unexpected result set after end-of-timeline: got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s : ensemble de résultats inattendu après la fin de la timeline : a " +"récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d " +"champs\n" -#: receivelog.c:753 +#: receivelog.c:755 #, c-format msgid "%s: could not parse next timeline's starting point \"%s\"\n" -msgstr "%s : n'a pas pu analyser la position de départ de la prochaine timeline « %s »\n" +msgstr "" +"%s : n'a pas pu analyser la position de départ de la prochaine timeline « " +"%s »\n" -#: receivelog.c:1124 +#: receivelog.c:1126 #, c-format msgid "%s: received write-ahead log record for offset %u with no file open\n" msgstr "" -"%s : a reçu l'enregistrement du journal de transactions pour le décalage %u\n" +"%s : a reçu l'enregistrement du journal de transactions pour le décalage " +"%u\n" "sans fichier ouvert\n" -#: receivelog.c:1135 +#: receivelog.c:1137 #, c-format msgid "%s: got WAL data offset %08x, expected %08x\n" -msgstr "%s : a obtenu le décalage %08x pour les données du journal, attendait %08x\n" +msgstr "" +"%s : a obtenu le décalage %08x pour les données du journal, attendait %08x\n" -#: receivelog.c:1170 +#: receivelog.c:1172 #, c-format msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" -msgstr "%s : n'a pas pu écrire %u octets dans le journal de transactions « %s » : %s\n" +msgstr "" +"%s : n'a pas pu écrire %u octets dans le journal de transactions « %s » : " +"%s\n" -#: receivelog.c:1195 receivelog.c:1236 receivelog.c:1267 +#: receivelog.c:1197 receivelog.c:1238 receivelog.c:1269 #, c-format msgid "%s: could not send copy-end packet: %s" msgstr "%s : n'a pas pu envoyer le paquet de fin de copie : %s" @@ -1308,154 +1473,200 @@ msgstr "%s : n'a pas pu se connecter au serveur : %s" #: streamutil.c:216 #, c-format msgid "%s: could not determine server setting for integer_datetimes\n" -msgstr "%s : n'a pas pu déterminer la configuration serveur de integer_datetimes\n" +msgstr "" +"%s : n'a pas pu déterminer la configuration serveur de integer_datetimes\n" #: streamutil.c:225 #, c-format msgid "%s: integer_datetimes compile flag does not match server\n" -msgstr "%s : l'option de compilation integer_datetimes ne correspond pas au serveur\n" +msgstr "" +"%s : l'option de compilation integer_datetimes ne correspond pas au " +"serveur\n" #: streamutil.c:376 #, c-format -msgid "%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" +msgid "" +"%s: could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" msgstr "" -"%s : n'a pas pu créer le slot de réplication « %s » : a récupéré %d lignes et %d champs,\n" +"%s : n'a pas pu créer le slot de réplication « %s » : a récupéré %d lignes " +"et %d champs,\n" "attendait %d lignes et %d champs\n" #: streamutil.c:421 #, c-format -msgid "%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" +msgid "" +"%s: could not drop replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" msgstr "" -"%s : n'a pas pu supprimer le slot de réplication « %s » : a récupéré %d lignes et %d champs,\n" +"%s : n'a pas pu supprimer le slot de réplication « %s » : a récupéré %d " +"lignes et %d champs,\n" "attendait %d lignes et %d champs\n" #: walmethods.c:435 walmethods.c:904 -msgid "deflate failed" -msgstr "échec en décompression" +msgid "could not compress data" +msgstr "n'a pas pu compresser les données" #: walmethods.c:459 -msgid "deflateReset failed" -msgstr "échec de deflateReset" +msgid "could not reset compression stream" +msgstr "n'a pas pu réinitialiser le flux de compression" #: walmethods.c:560 -msgid "deflateInit2 failed" -msgstr "échec de deflateInit2" +msgid "could not initialize compression library" +msgstr "n'a pas pu initialiser la bibliothèque de compression" #: walmethods.c:572 -msgid "implementation error: tar files can't have more than one open file\n" -msgstr "erreur d'implémentation : les fichiers tar ne peuvent pas avoir plus d'un fichier ouvert\n" +msgid "implementation error: tar files can't have more than one open file" +msgstr "" +"erreur d'implémentation : les fichiers tar ne peuvent pas avoir plus d'un " +"fichier ouvert" #: walmethods.c:586 msgid "could not create tar header" msgstr "n'a pas pu créer l'en-tête du fichier tar" #: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 -msgid "deflateParams failed" -msgstr "échec de deflateParams" +msgid "could not change compression parameters" +msgstr "n'a pas pu modifier les paramètres de compression" #: walmethods.c:720 msgid "unlink not supported with compression" msgstr "suppression non supportée avec la compression" #: walmethods.c:920 -msgid "deflateEnd failed" -msgstr "échec de deflateEnd" +msgid "could not close compression stream" +msgstr "n'a pas pu fermer le flux de compression" + +#~ msgid "%s: socket not open" +#~ msgstr "%s : socket non ouvert" + +#~ msgid "%s: no start point returned from server\n" +#~ msgstr "%s : aucun point de redémarrage renvoyé du serveur\n" -#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n" +#~ msgid "" +#~ "%s: timeline does not match between base backup and streaming " +#~ "connection\n" #~ msgstr "" -#~ " -x, --xlog inclut les journaux de transactions nécessaires\n" -#~ " dans la sauvegarde (mode fetch)\n" +#~ "%s : la timeline ne correspond pas entre la sauvegarde des fichiers et " +#~ "la\n" +#~ "connexion de réplication\n" -#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" -#~ msgstr "%s : ne peut pas spécifier à la fois --xlog et --xlog-method\n" +#~ msgid "%s: keepalive message has incorrect size %d\n" +#~ msgstr "%s : le message keepalive a une taille %d incorrecte\n" -#~ msgid "%s: WAL streaming can only be used in plain mode\n" -#~ msgstr "%s : le flux de journaux de transactions peut seulement être utilisé en mode plain\n" +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version et quitte\n" -#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide et quitte\n" + +#~ msgid "%s: could not read copy data: %s\n" +#~ msgstr "%s : n'a pas pu lire les données du COPY : %s\n" + +#~ msgid "%s: could not get current position in file %s: %s\n" #~ msgstr "" -#~ "%s : n'a pas pu récupérer les informations sur le journal de transactions\n" -#~ "« %s » : %s\n" +#~ "%s : n'a pas pu obtenir la position courant dans le fichier %s : %s\n" -#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu remplir de zéros le journal de transactions « %s » : %s\n" +#~ msgid "%s: could not seek back to beginning of WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu se déplacer au début du segment WAL %s : %s\n" -#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu rechercher le début du journal de transaction « %s » : %s\n" +#~ msgid "%s: could not pad WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu terminer le segment WAL %s : %s\n" -#~ msgid "%s: could not rename file \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu renommer le fichier « %s » : %s\n" +#~ msgid "%s: could not stat WAL segment %s: %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu récupérer les informations sur le segment WAL %s : %s\n" -#~ msgid "%s: could not open timeline history file \"%s\": %s\n" -#~ msgstr "%s : n'a pas pu ouvrir le journal historique de la timeline « %s » : %s\n" +#~ msgid "%s: could not open WAL segment %s: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le segment WAL %s : %s\n" -#~ msgid "%s: could not parse file size\n" -#~ msgstr "%s : n'a pas pu analyser la taille du fichier\n" +#~ msgid "%s: could not parse log start position from value \"%s\"\n" +#~ msgstr "" +#~ "%s : n'a pas pu analyser la position de départ des WAL à partir de la " +#~ "valeur « %s »\n" -#~ msgid "%s: could not parse file mode\n" -#~ msgstr "%s : n'a pas pu analyser le mode du fichier\n" +#~ msgid "%s: could not identify system: %s\n" +#~ msgstr "%s : n'a pas pu identifier le système : %s\n" -#~ msgid "%s: could not parse transaction log file name \"%s\"\n" -#~ msgstr "%s : n'a pas pu analyser le nom du journal de transactions « %s »\n" +#~ msgid "%s: could not send base backup command: %s" +#~ msgstr "%s : n'a pas pu envoyer la commande de sauvegarde de base : %s" -#~ msgid "%s: could not close file %s: %s\n" -#~ msgstr "%s : n'a pas pu fermer le fichier %s : %s\n" +#~ msgid "%s: could not identify system: %s" +#~ msgstr "%s : n'a pas pu identifier le système : %s" -#~ msgid " -V, --version output version information, then exit\n" -#~ msgstr " -V, --version affiche la version puis quitte\n" +#~ msgid "%s: invalid format of xlog location: %s\n" +#~ msgstr "" +#~ "%s : format invalide de l'emplacement du journal de transactions : %s\n" #~ msgid " -?, --help show this help, then exit\n" #~ msgstr " -?, --help affiche cette aide puis quitte\n" -#~ msgid "%s: invalid format of xlog location: %s\n" -#~ msgstr "%s : format invalide de l'emplacement du journal de transactions : %s\n" +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version affiche la version puis quitte\n" -#~ msgid "%s: could not identify system: %s" -#~ msgstr "%s : n'a pas pu identifier le système : %s" +#~ msgid "%s: could not close file %s: %s\n" +#~ msgstr "%s : n'a pas pu fermer le fichier %s : %s\n" -#~ msgid "%s: could not send base backup command: %s" -#~ msgstr "%s : n'a pas pu envoyer la commande de sauvegarde de base : %s" +#~ msgid "%s: could not parse transaction log file name \"%s\"\n" +#~ msgstr "" +#~ "%s : n'a pas pu analyser le nom du journal de transactions « %s »\n" -#~ msgid "%s: could not identify system: %s\n" -#~ msgstr "%s : n'a pas pu identifier le système : %s\n" +#~ msgid "%s: could not parse file mode\n" +#~ msgstr "%s : n'a pas pu analyser le mode du fichier\n" -#~ msgid "%s: could not parse log start position from value \"%s\"\n" -#~ msgstr "%s : n'a pas pu analyser la position de départ des WAL à partir de la valeur « %s »\n" +#~ msgid "%s: could not parse file size\n" +#~ msgstr "%s : n'a pas pu analyser la taille du fichier\n" -#~ msgid "%s: could not open WAL segment %s: %s\n" -#~ msgstr "%s : n'a pas pu ouvrir le segment WAL %s : %s\n" +#~ msgid "%s: could not open timeline history file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu ouvrir le journal historique de la timeline « %s » : %s\n" -#~ msgid "%s: could not stat WAL segment %s: %s\n" -#~ msgstr "%s : n'a pas pu récupérer les informations sur le segment WAL %s : %s\n" +#~ msgid "%s: could not rename file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu renommer le fichier « %s » : %s\n" -#~ msgid "%s: could not pad WAL segment %s: %s\n" -#~ msgstr "%s : n'a pas pu terminer le segment WAL %s : %s\n" +#~ msgid "" +#~ "%s: could not seek to beginning of transaction log file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu rechercher le début du journal de transaction « %s » : " +#~ "%s\n" -#~ msgid "%s: could not seek back to beginning of WAL segment %s: %s\n" -#~ msgstr "%s : n'a pas pu se déplacer au début du segment WAL %s : %s\n" +#~ msgid "%s: could not pad transaction log file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu remplir de zéros le journal de transactions « %s » : %s\n" -#~ msgid "%s: could not get current position in file %s: %s\n" -#~ msgstr "%s : n'a pas pu obtenir la position courant dans le fichier %s : %s\n" +#~ msgid "%s: could not stat transaction log file \"%s\": %s\n" +#~ msgstr "" +#~ "%s : n'a pas pu récupérer les informations sur le journal de " +#~ "transactions\n" +#~ "« %s » : %s\n" -#~ msgid "%s: could not read copy data: %s\n" -#~ msgstr "%s : n'a pas pu lire les données du COPY : %s\n" +#~ msgid "%s: WAL streaming can only be used in plain mode\n" +#~ msgstr "" +#~ "%s : le flux de journaux de transactions peut seulement être utilisé en " +#~ "mode plain\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help affiche cette aide et quitte\n" +#~ msgid "%s: cannot specify both --xlog and --xlog-method\n" +#~ msgstr "%s : ne peut pas spécifier à la fois --xlog et --xlog-method\n" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version affiche la version et quitte\n" +#~ msgid "" +#~ " -x, --xlog include required WAL files in backup (fetch " +#~ "mode)\n" +#~ msgstr "" +#~ " -x, --xlog inclut les journaux de transactions " +#~ "nécessaires\n" +#~ " dans la sauvegarde (mode fetch)\n" -#~ msgid "%s: keepalive message has incorrect size %d\n" -#~ msgstr "%s : le message keepalive a une taille %d incorrecte\n" +#~ msgid "deflateEnd failed" +#~ msgstr "échec de deflateEnd" -#~ msgid "%s: timeline does not match between base backup and streaming connection\n" -#~ msgstr "" -#~ "%s : la timeline ne correspond pas entre la sauvegarde des fichiers et la\n" -#~ "connexion de réplication\n" +#~ msgid "deflateParams failed" +#~ msgstr "échec de deflateParams" -#~ msgid "%s: no start point returned from server\n" -#~ msgstr "%s : aucun point de redémarrage renvoyé du serveur\n" +#~ msgid "deflateInit2 failed" +#~ msgstr "échec de deflateInit2" -#~ msgid "%s: socket not open" -#~ msgstr "%s : socket non ouvert" +#~ msgid "deflateReset failed" +#~ msgstr "échec de deflateReset" + +#~ msgid "deflate failed" +#~ msgstr "échec en décompression" diff --git a/src/bin/pg_basebackup/po/it.po b/src/bin/pg_basebackup/po/it.po index 98786e153fa..e9695987bc9 100644 --- a/src/bin/pg_basebackup/po/it.po +++ b/src/bin/pg_basebackup/po/it.po @@ -1,22 +1,30 @@ -# Italian message translation file for pg_basebackup -# Copyright (C) 2012 PostgreSQL Global Development Group +# +# pg_basebackup.po +# Italian message translation file for pg_basebackup +# +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it +# +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# +# Daniele Varrazzo , 2012-2017 +# # This file is distributed under the same license as the PostgreSQL package. -# Daniele Varrazzo , 2012. # msgid "" msgstr "" "Project-Id-Version: pg_basebackup (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:46+0000\n" -"PO-Revision-Date: 2017-05-23 01:51+0100\n" +"POT-Creation-Date: 2017-08-30 21:44+0000\n" +"PO-Revision-Date: 2018-06-25 08:58+0200\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 1.5.4\n" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -51,8 +59,8 @@ msgstr "%s: lettura della directory \"%s\" fallita: %s\n" msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: apertura del file \"%s\" fallita: %s\n" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:802 -#: receivelog.c:1059 +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: receivelog.c:804 receivelog.c:1061 #, c-format msgid "%s: could not fsync file \"%s\": %s\n" msgstr "%s: fsync del file \"%s\" fallito: %s\n" @@ -359,8 +367,8 @@ msgstr "" msgid "%s: could not read from ready pipe: %s\n" msgstr "%s: lettura dalla pipe pronta fallita: %s\n" -#: pg_basebackup.c:417 pg_basebackup.c:552 pg_basebackup.c:2001 -#: streamutil.c:285 +#: pg_basebackup.c:417 pg_basebackup.c:552 pg_basebackup.c:2005 +#: streamutil.c:286 #, c-format msgid "%s: could not parse write-ahead log location \"%s\"\n" msgstr "" @@ -377,7 +385,7 @@ msgstr "%s: non è stato possibile finire di scrivere i file WAL: %s\n" msgid "%s: could not create pipe for background process: %s\n" msgstr "%s: creazione della pipe per il processo in background fallita: %s\n" -#: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1419 +#: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1423 #, c-format msgid "%s: could not create directory \"%s\": %s\n" msgstr "%s: creazione della directory \"%s\" fallita: %s\n" @@ -458,243 +466,243 @@ msgstr "%s: il transfer rate \"%s\" è fuori dall'intervallo consentito\n" msgid "%s: could not write to compressed file \"%s\": %s\n" msgstr "%s: scrittura nel file compresso \"%s\" fallita: %s\n" -#: pg_basebackup.c:910 pg_basebackup.c:1513 pg_basebackup.c:1679 +#: pg_basebackup.c:910 pg_basebackup.c:1517 pg_basebackup.c:1683 #, c-format msgid "%s: could not write to file \"%s\": %s\n" msgstr "%s: scrittura nel file \"%s\" fallita: %s\n" -#: pg_basebackup.c:965 pg_basebackup.c:986 pg_basebackup.c:1014 +#: pg_basebackup.c:969 pg_basebackup.c:990 pg_basebackup.c:1018 #, c-format msgid "%s: could not set compression level %d: %s\n" msgstr "%s: impostazione del livello di compressione %d fallito: %s\n" -#: pg_basebackup.c:1035 +#: pg_basebackup.c:1039 #, c-format msgid "%s: could not create compressed file \"%s\": %s\n" msgstr "%s: creazione del file compresso \"%s\" fallita: %s\n" -#: pg_basebackup.c:1046 pg_basebackup.c:1473 pg_basebackup.c:1672 +#: pg_basebackup.c:1050 pg_basebackup.c:1477 pg_basebackup.c:1676 #, c-format msgid "%s: could not create file \"%s\": %s\n" msgstr "%s: creazione del file \"%s\" fallita: %s\n" -#: pg_basebackup.c:1058 pg_basebackup.c:1326 +#: pg_basebackup.c:1062 pg_basebackup.c:1330 #, c-format msgid "%s: could not get COPY data stream: %s" msgstr "%s: non è stato possibile ottenere lo stream di dati COPY: %s" -#: pg_basebackup.c:1115 +#: pg_basebackup.c:1119 #, c-format msgid "%s: could not close compressed file \"%s\": %s\n" msgstr "%s: chiusura del file compresso \"%s\" fallita: %s\n" -#: pg_basebackup.c:1128 pg_recvlogical.c:631 receivelog.c:221 receivelog.c:306 -#: receivelog.c:712 +#: pg_basebackup.c:1132 pg_recvlogical.c:631 receivelog.c:223 receivelog.c:308 +#: receivelog.c:714 #, c-format msgid "%s: could not close file \"%s\": %s\n" msgstr "%s: chiusura del file \"%s\" fallita: %s\n" -#: pg_basebackup.c:1139 pg_basebackup.c:1355 pg_recvlogical.c:453 -#: receivelog.c:1007 +#: pg_basebackup.c:1143 pg_basebackup.c:1359 pg_recvlogical.c:453 +#: receivelog.c:1009 #, c-format msgid "%s: could not read COPY data: %s" msgstr "%s: lettura dei dati COPY fallita: %s" -#: pg_basebackup.c:1369 +#: pg_basebackup.c:1373 #, c-format msgid "%s: invalid tar block header size: %d\n" msgstr "%s: dimensione del blocco di intestazione del file tar non valida: %d\n" -#: pg_basebackup.c:1427 +#: pg_basebackup.c:1431 #, c-format msgid "%s: could not set permissions on directory \"%s\": %s\n" msgstr "%s: impostazione dei permessi sulla directory \"%s\" fallita: %s\n" -#: pg_basebackup.c:1451 +#: pg_basebackup.c:1455 #, c-format msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" msgstr "%s: creazione del link simbolico da \"%s\" a \"%s\" fallita: %s\n" -#: pg_basebackup.c:1460 +#: pg_basebackup.c:1464 #, c-format msgid "%s: unrecognized link indicator \"%c\"\n" msgstr "%s: indicatore di link sconosciuto \"%c\"\n" -#: pg_basebackup.c:1480 +#: pg_basebackup.c:1484 #, c-format msgid "%s: could not set permissions on file \"%s\": %s\n" msgstr "%s: impostazione dei permessi sul file \"%s\" fallita: %s\n" -#: pg_basebackup.c:1539 +#: pg_basebackup.c:1543 #, c-format msgid "%s: COPY stream ended before last file was finished\n" msgstr "%s: lo stream COPY è terminato prima che l'ultimo file fosse finito\n" -#: pg_basebackup.c:1567 pg_basebackup.c:1587 pg_basebackup.c:1594 -#: pg_basebackup.c:1647 +#: pg_basebackup.c:1571 pg_basebackup.c:1591 pg_basebackup.c:1598 +#: pg_basebackup.c:1651 #, c-format msgid "%s: out of memory\n" msgstr "%s: memoria esaurita\n" -#: pg_basebackup.c:1720 +#: pg_basebackup.c:1724 #, c-format msgid "%s: incompatible server version %s\n" msgstr "%s: versione del server incompatibile %s\n" -#: pg_basebackup.c:1735 +#: pg_basebackup.c:1739 #, c-format msgid "HINT: use -X none or -X fetch to disable log streaming\n" msgstr "CONSIGLIO: usa -X none or -X fetch per disabilitare lo streaming dei log\n" -#: pg_basebackup.c:1761 +#: pg_basebackup.c:1765 #, c-format msgid "%s: initiating base backup, waiting for checkpoint to complete\n" msgstr "%s: avvio del backup di base, in attesa del completamento del checkpoint\n" -#: pg_basebackup.c:1779 pg_recvlogical.c:270 receivelog.c:490 receivelog.c:561 -#: receivelog.c:601 streamutil.c:255 streamutil.c:363 streamutil.c:409 +#: pg_basebackup.c:1783 pg_recvlogical.c:270 receivelog.c:492 receivelog.c:563 +#: receivelog.c:603 streamutil.c:256 streamutil.c:364 streamutil.c:410 #, c-format msgid "%s: could not send replication command \"%s\": %s" msgstr "%s: invio del comando di replica \"%s\" fallito: %s" -#: pg_basebackup.c:1790 +#: pg_basebackup.c:1794 #, c-format msgid "%s: could not initiate base backup: %s" msgstr "%s: avvio del backup di base fallito: %s" -#: pg_basebackup.c:1797 +#: pg_basebackup.c:1801 #, c-format msgid "%s: server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields\n" msgstr "%s: il server ha restituito una risposta imprevista al comando BASE_BACKUP; ricevute %d righe e %d campi, attese %d righe e %d campi\n" -#: pg_basebackup.c:1805 +#: pg_basebackup.c:1809 #, c-format msgid "%s: checkpoint completed\n" msgstr "%s: checkpoint completato\n" -#: pg_basebackup.c:1820 +#: pg_basebackup.c:1824 #, c-format msgid "%s: write-ahead log start point: %s on timeline %u\n" msgstr "%s: punto di inizio del write-ahead log: %s sulla timeline %u\n" -#: pg_basebackup.c:1829 +#: pg_basebackup.c:1833 #, c-format msgid "%s: could not get backup header: %s" msgstr "%s: non è stato possibile ottenere l'intestazione del backup: %s" -#: pg_basebackup.c:1835 +#: pg_basebackup.c:1839 #, c-format msgid "%s: no data returned from server\n" msgstr "%s: nessun dato restituito dal server\n" -#: pg_basebackup.c:1867 +#: pg_basebackup.c:1871 #, c-format msgid "%s: can only write single tablespace to stdout, database has %d\n" msgstr "%s: è possibile scrivere solo un singolo tablespace su stdout, il database ne ha %d\n" -#: pg_basebackup.c:1879 +#: pg_basebackup.c:1883 #, c-format msgid "%s: starting background WAL receiver\n" msgstr "%s: avvio del ricevitore dei WAL in background\n" -#: pg_basebackup.c:1910 +#: pg_basebackup.c:1914 #, c-format msgid "%s: could not get write-ahead log end position from server: %s" msgstr "%s: non è stato possibile ottenere la posizione finale del write-ahead log dal server: %s" -#: pg_basebackup.c:1917 +#: pg_basebackup.c:1921 #, c-format msgid "%s: no write-ahead log end position returned from server\n" msgstr "%s: il server non ha restituito una posizione per il write-ahead log\n" -#: pg_basebackup.c:1923 +#: pg_basebackup.c:1927 #, c-format msgid "%s: write-ahead log end point: %s\n" msgstr "%s: punto finale del write-ahead log: %s\n" -#: pg_basebackup.c:1929 +#: pg_basebackup.c:1933 #, c-format msgid "%s: final receive failed: %s" msgstr "%s: ricezione finale fallita: %s" -#: pg_basebackup.c:1953 +#: pg_basebackup.c:1957 #, c-format msgid "%s: waiting for background process to finish streaming ...\n" msgstr "%s: in attesa che il processo in background finisca lo streaming ...\n" -#: pg_basebackup.c:1959 +#: pg_basebackup.c:1963 #, c-format msgid "%s: could not send command to background pipe: %s\n" msgstr "%s invio del comando alla pipe di background fallita: %s\n" -#: pg_basebackup.c:1968 +#: pg_basebackup.c:1972 #, c-format msgid "%s: could not wait for child process: %s\n" msgstr "%s: errore nell'attesa del processo figlio: %s\n" -#: pg_basebackup.c:1974 +#: pg_basebackup.c:1978 #, c-format msgid "%s: child %d died, expected %d\n" msgstr "%s: il processo figlio %d interrotto, atteso %d\n" -#: pg_basebackup.c:1980 +#: pg_basebackup.c:1984 #, c-format msgid "%s: child process did not exit normally\n" msgstr "%s: il processo figlio non è terminato normalmente\n" -#: pg_basebackup.c:1986 +#: pg_basebackup.c:1990 #, c-format msgid "%s: child process exited with error %d\n" msgstr "%s: il processo figlio è terminato con errore %d\n" -#: pg_basebackup.c:2013 +#: pg_basebackup.c:2017 #, c-format msgid "%s: could not wait for child thread: %s\n" msgstr "%s: errore nell'attesa del thread figlio: %s\n" -#: pg_basebackup.c:2020 +#: pg_basebackup.c:2024 #, c-format msgid "%s: could not get child thread exit status: %s\n" msgstr "%s: non è stato possibile ottenere il codice di uscita del thread figlio: %s\n" -#: pg_basebackup.c:2026 +#: pg_basebackup.c:2030 #, c-format msgid "%s: child thread exited with error %u\n" msgstr "%s: il thread figlio è terminato con errore %u\n" -#: pg_basebackup.c:2064 +#: pg_basebackup.c:2068 #, c-format msgid "%s: base backup completed\n" msgstr "%s: backup di base completato\n" -#: pg_basebackup.c:2141 +#: pg_basebackup.c:2145 #, c-format msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" msgstr "%s: formato di output \"%s\" non valido, deve essere \"plain\" oppure \"tar\"\n" -#: pg_basebackup.c:2186 +#: pg_basebackup.c:2190 #, c-format -msgid "%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\" or \"none\"\n" +msgid "%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"\n" msgstr "%s: opzione wal-method \"%s\" non valida, deve essere \"fetch\", \"stream\" oppure \"none\"\n" -#: pg_basebackup.c:2214 pg_receivewal.c:556 +#: pg_basebackup.c:2218 pg_receivewal.c:556 #, c-format msgid "%s: invalid compression level \"%s\"\n" msgstr "%s: livello di compressione non valido \"%s\"\n" -#: pg_basebackup.c:2226 +#: pg_basebackup.c:2230 #, c-format msgid "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" msgstr "%s: argomento di checkpoint \"%s\" non valido, deve essere \"fast\" oppure \"spread\"\n" -#: pg_basebackup.c:2253 pg_receivewal.c:538 pg_recvlogical.c:825 +#: pg_basebackup.c:2257 pg_receivewal.c:538 pg_recvlogical.c:825 #, c-format msgid "%s: invalid status interval \"%s\"\n" msgstr "%s: intervallo di status \"%s\" non valido\n" -#: pg_basebackup.c:2269 pg_basebackup.c:2283 pg_basebackup.c:2294 -#: pg_basebackup.c:2307 pg_basebackup.c:2317 pg_basebackup.c:2327 -#: pg_basebackup.c:2339 pg_basebackup.c:2353 pg_basebackup.c:2364 +#: pg_basebackup.c:2273 pg_basebackup.c:2287 pg_basebackup.c:2298 +#: pg_basebackup.c:2311 pg_basebackup.c:2321 pg_basebackup.c:2331 +#: pg_basebackup.c:2343 pg_basebackup.c:2357 pg_basebackup.c:2368 #: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 #: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 #: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 @@ -704,57 +712,57 @@ msgstr "%s: intervallo di status \"%s\" non valido\n" msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: pg_basebackup.c:2281 pg_receivewal.c:591 pg_recvlogical.c:864 +#: pg_basebackup.c:2285 pg_receivewal.c:591 pg_recvlogical.c:864 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: troppi argomenti nella riga di comando (il primo è \"%s\")\n" -#: pg_basebackup.c:2293 pg_receivewal.c:621 +#: pg_basebackup.c:2297 pg_receivewal.c:621 #, c-format msgid "%s: no target directory specified\n" msgstr "%s: nessuna directory di destinazione specificata\n" -#: pg_basebackup.c:2305 +#: pg_basebackup.c:2309 #, c-format msgid "%s: only tar mode backups can be compressed\n" msgstr "%s: solo i backup in modalità tar possono essere compressi\n" -#: pg_basebackup.c:2315 +#: pg_basebackup.c:2319 #, c-format msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" msgstr "%s: non è possibile eseguire lo stream dei write-ahead log in modalità tar su stdout\n" -#: pg_basebackup.c:2325 +#: pg_basebackup.c:2329 #, c-format msgid "%s: replication slots can only be used with WAL streaming\n" msgstr "%s: gli slot di replica possono essere usati solo con lo streaming dei WAL\n" -#: pg_basebackup.c:2337 +#: pg_basebackup.c:2341 #, c-format msgid "%s: --no-slot cannot be used with slot name\n" msgstr "%s: --no-slot non può essere usato col nome di uno slot\n" -#: pg_basebackup.c:2351 +#: pg_basebackup.c:2355 #, c-format msgid "%s: WAL directory location can only be specified in plain mode\n" msgstr "%s: la posizione della directory dei WAL può essere specificata solo in modalità plain\n" -#: pg_basebackup.c:2362 +#: pg_basebackup.c:2366 #, c-format msgid "%s: WAL directory location must be an absolute path\n" msgstr "%s: la posizione della directory dei WAL deve essere un percorso assoluto\n" -#: pg_basebackup.c:2374 pg_receivewal.c:631 +#: pg_basebackup.c:2378 pg_receivewal.c:631 #, c-format msgid "%s: this build does not support compression\n" msgstr "%s: questo binario compilato non supporta la compressione\n" -#: pg_basebackup.c:2414 +#: pg_basebackup.c:2418 #, c-format msgid "%s: could not create symbolic link \"%s\": %s\n" msgstr "%s: creazione del link simbolico \"%s\" fallita: %s\n" -#: pg_basebackup.c:2419 +#: pg_basebackup.c:2423 #, c-format msgid "%s: symlinks are not supported on this platform\n" msgstr "%s: questa piattaforma non supporta i link simbolici\n" @@ -782,7 +790,7 @@ msgstr "" msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr " -D, --directory=DIR ricevi i file di write-ahead log in questa directory\n" -#: pg_receivewal.c:80 pg_recvlogical.c:87 +#: pg_receivewal.c:80 pg_recvlogical.c:88 #, c-format msgid " --if-not-exists do not error if slot already exists when creating a slot\n" msgstr " --if-not-exists non dare un errore se esiste già uno slot con lo stesso nome\n" @@ -863,8 +871,8 @@ msgstr "%s: apertura del file compresso \"%s\" fallita: %s:\n" #: pg_receivewal.c:283 #, c-format -msgid "%s: could not seek compressed file \"%s\": %s\n" -msgstr "%s: spostamento nel file compresso \"%s\" fallita: %s\n" +msgid "%s: could not seek in compressed file \"%s\": %s\n" +msgstr "%s: spostamento nel file compresso \"%s\" fallito: %s\n" #: pg_receivewal.c:289 #, c-format @@ -928,9 +936,7 @@ msgstr "%s: disconnesso; aspetterò %d secondi prima di riprovare\n" msgid "" "%s controls PostgreSQL logical decoding streams.\n" "\n" -msgstr "" -"%s controlla i flussi di decodifica logica di PostgreSQ.\n" -"\n" +msgstr "%s controlla i flussi di decodifica logica di PostgreSQL.\n\n" #: pg_recvlogical.c:79 #, c-format @@ -948,10 +954,15 @@ msgstr " --start avvia lo streaming in uno slot di replica (per #: pg_recvlogical.c:84 #, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN esci dopo aver ricevuto la posizione LSN specificata\n" + +#: pg_recvlogical.c:85 +#, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" msgstr " -f, --file=FILE riceve i log in questo file, - per stdout\n" -#: pg_recvlogical.c:85 +#: pg_recvlogical.c:86 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -960,16 +971,11 @@ msgstr "" " -F --fsync-interval=SEC\n" " tempo tra i sync del file di output (default: %d)\n" -#: pg_recvlogical.c:88 +#: pg_recvlogical.c:89 #, c-format msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" msgstr " -I, --startpos=LSN dove deve partire lo streaming in uno slot esistente\n" -#: pg_recvlogical.c:89 -#, c-format -msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" -msgstr " -E, --endpos=LSN esci dopo aver ricevuto la posizione LSN specificata\n" - #: pg_recvlogical.c:91 #, c-format msgid "" @@ -1001,7 +1007,7 @@ msgstr " -d, --dbname=NOMEDB database a cui connettersi\n" msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" msgstr "%s: scritture confermate fino a %X/%X, flush a %X/%X (slot %s)\n" -#: pg_recvlogical.c:160 receivelog.c:349 +#: pg_recvlogical.c:160 receivelog.c:351 #, c-format msgid "%s: could not send feedback packet: %s" msgstr "%s: invio del pacchetto di feedback fallito: %s" @@ -1026,28 +1032,28 @@ msgstr "%s: streaming iniziato\n" msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: apertura del file di log \"%s\" fallita: %s\n" -#: pg_recvlogical.c:376 receivelog.c:912 +#: pg_recvlogical.c:376 receivelog.c:914 #, c-format msgid "%s: invalid socket: %s" msgstr "%s: socket non valido: %s" -#: pg_recvlogical.c:430 receivelog.c:941 +#: pg_recvlogical.c:430 receivelog.c:943 #, c-format msgid "%s: select() failed: %s\n" msgstr "%s: select() fallita: %s\n" -#: pg_recvlogical.c:439 receivelog.c:993 +#: pg_recvlogical.c:439 receivelog.c:995 #, c-format msgid "%s: could not receive data from WAL stream: %s" msgstr "%s: ricezione dati dallo stream WAL fallita: %s" -#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1038 -#: receivelog.c:1105 +#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1040 +#: receivelog.c:1107 #, c-format msgid "%s: streaming header too small: %d\n" msgstr "%s: intestazione dello streaming troppo piccola: %d\n" -#: pg_recvlogical.c:517 receivelog.c:872 +#: pg_recvlogical.c:517 receivelog.c:874 #, c-format msgid "%s: unrecognized streaming header: \"%c\"\n" msgstr "%s: intestazione dello streaming sconosciuta: \"%c\"\n" @@ -1057,7 +1063,7 @@ msgstr "%s: intestazione dello streaming sconosciuta: \"%c\"\n" msgid "%s: could not write %u bytes to log file \"%s\": %s\n" msgstr "%s: scrittura di %u byte nel file di log \"%s\" fallita: %s\n" -#: pg_recvlogical.c:617 receivelog.c:665 receivelog.c:703 +#: pg_recvlogical.c:617 receivelog.c:667 receivelog.c:705 #, c-format msgid "%s: unexpected termination of replication stream: %s" msgstr "%s: terminazione inaspettata dello stream di replica: %s" @@ -1134,154 +1140,188 @@ msgstr "%s: apertura del file di write-ahead log esistente \"%s\" fallita: %s\n" #: receivelog.c:139 #, c-format -msgid "%s: could not sync existing write-ahead log file \"%s\": %s\n" -msgstr "%s: sync del file di write-ahead log esistente \"%s\" fallita: %s\n" +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" +msgstr "%s: fsync del file di write-ahead log esistente \"%s\" fallita: %s\n" #: receivelog.c:154 #, c-format -msgid "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" -msgstr "%s: il file di write-ahead log \"%s\" è lungo %d byte, dovrebbe essere 0 oppure %d\n" +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "%s: il file di write-ahead log \"%s\" è lungo %d byte, dovrebbe essere 0 oppure %d\n" +msgstr[1] "%s: il file di write-ahead log \"%s\" è lungo %d byte, dovrebbe essere 0 oppure %d\n" -#: receivelog.c:167 +#: receivelog.c:169 #, c-format msgid "%s: could not open write-ahead log file \"%s\": %s\n" msgstr "%s: apertura del file di write-ahead log \"%s\" fallita: %s\n" -#: receivelog.c:194 +#: receivelog.c:196 #, c-format msgid "%s: could not determine seek position in file \"%s\": %s\n" msgstr "%s: determinazione della posizione dove muoversi nel file \"%s\" fallita: %s\n" -#: receivelog.c:209 +#: receivelog.c:211 #, c-format msgid "%s: not renaming \"%s%s\", segment is not complete\n" msgstr "%s: \"%s%s\" non rinominato, il segmento non è completo\n" -#: receivelog.c:278 +#: receivelog.c:280 #, c-format msgid "%s: server reported unexpected history file name for timeline %u: %s\n" msgstr "%s: il server ha riportato un nome di file della storia imprevisto per la timeline %u: %s\n" -#: receivelog.c:286 +#: receivelog.c:288 #, c-format msgid "%s: could not create timeline history file \"%s\": %s\n" msgstr "%s: creazione del file di storia della timeline \"%s\" fallita: %s\n" -#: receivelog.c:293 +#: receivelog.c:295 #, c-format msgid "%s: could not write timeline history file \"%s\": %s\n" msgstr "%s: scrittura del file di storia della timeline \"%s\" fallita: %s\n" -#: receivelog.c:383 +#: receivelog.c:385 #, c-format msgid "%s: incompatible server version %s; client does not support streaming from server versions older than %s\n" msgstr "%s: server di versione %s non compatibile; il client non supporta lo streaming da server di versione precedente a %s\n" -#: receivelog.c:393 +#: receivelog.c:395 #, c-format msgid "%s: incompatible server version %s; client does not support streaming from server versions newer than %s\n" msgstr "%s: server di versione %s non compatibile; il client non supporta lo streaming da server di versione successiva a %s\n" -#: receivelog.c:498 streamutil.c:264 streamutil.c:303 +#: receivelog.c:500 streamutil.c:265 streamutil.c:304 #, c-format msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" msgstr "%s: identificazione del sistema fallita: ricevute %d righe e %d campi, attese %d righe e %d campi o più\n" -#: receivelog.c:506 +#: receivelog.c:508 #, c-format msgid "%s: system identifier does not match between base backup and streaming connection\n" msgstr "%s: l'identificativo di sistema non combacia tra il backup di base e la connessione in streaming\n" -#: receivelog.c:514 +#: receivelog.c:516 #, c-format msgid "%s: starting timeline %u is not present in the server\n" msgstr "%s: la timeline di inizio %u non è presente nel server\n" -#: receivelog.c:533 +#: receivelog.c:535 #, c-format msgid "%s: could not create temporary replication slot \"%s\": %s" msgstr "%s: creazione dello slot temporaneo di replica \"%s\" fallito: %s" -#: receivelog.c:574 +#: receivelog.c:576 #, c-format msgid "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields\n" msgstr "%s: risposta inattesa al comando TIMELINE_HISTORY: ricevute %d righe e %d campi, attese %d righe e %d campi\n" -#: receivelog.c:646 +#: receivelog.c:648 #, c-format msgid "%s: server reported unexpected next timeline %u, following timeline %u\n" msgstr "%s: il server ha riportato la timeline successiva imprevista %u, a seguito della timeline %u\n" -#: receivelog.c:653 +#: receivelog.c:655 #, c-format msgid "%s: server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X\n" msgstr "%s: il server ha interrotto lo streaming della timeline %u a %X/%X, ma ha riportato l'inizio della timeline successiva %u a %X/%X\n" -#: receivelog.c:694 +#: receivelog.c:696 #, c-format msgid "%s: replication stream was terminated before stop point\n" msgstr "%s: lo stream di replica è terminato prima del punto di arresto\n" -#: receivelog.c:743 +#: receivelog.c:745 #, c-format msgid "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields\n" msgstr "%s: risultato imprevisto dopo la fine della timeline: ricevute %d righe e %d campi, attese %d righe e %d campi\n" -#: receivelog.c:753 +#: receivelog.c:755 #, c-format msgid "%s: could not parse next timeline's starting point \"%s\"\n" msgstr "%s: interpretazione del punto d'inizio della nuova timeline \"%s\" fallita\n" -#: receivelog.c:1124 +#: receivelog.c:1126 #, c-format msgid "%s: received write-ahead log record for offset %u with no file open\n" msgstr "%s: ricevuto un record di write-ahead log per l'offset %u senza alcun file aperto\n" -#: receivelog.c:1135 +#: receivelog.c:1137 #, c-format msgid "%s: got WAL data offset %08x, expected %08x\n" msgstr "%s: ricevuto offset dati WAL %08x, atteso %08x\n" -#: receivelog.c:1170 +#: receivelog.c:1172 #, c-format msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" msgstr "%s: scrittura di %u byte nel file WAL \"%s\" fallita: %s\n" -#: receivelog.c:1195 receivelog.c:1236 receivelog.c:1267 +#: receivelog.c:1197 receivelog.c:1238 receivelog.c:1269 #, c-format msgid "%s: could not send copy-end packet: %s" msgstr "%s: invio del pacchetto di fine copia fallito: %s" -#: streamutil.c:148 +#: streamutil.c:149 msgid "Password: " msgstr "Password: " -#: streamutil.c:173 +#: streamutil.c:174 #, c-format msgid "%s: could not connect to server\n" msgstr "%s: connessione al server fallita\n" -#: streamutil.c:191 +#: streamutil.c:192 #, c-format msgid "%s: could not connect to server: %s" msgstr "%s: connessione al server fallita: %s" -#: streamutil.c:215 +#: streamutil.c:216 #, c-format msgid "%s: could not determine server setting for integer_datetimes\n" msgstr "%s: non è stato possibile determinare l'impostazione integer_datetimes del server\n" -#: streamutil.c:224 +#: streamutil.c:225 #, c-format msgid "%s: integer_datetimes compile flag does not match server\n" msgstr "%s: l'opzione di compilazione integer_datetimes non combacia con quella del server\n" -#: streamutil.c:375 +#: streamutil.c:376 #, c-format msgid "%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" msgstr "%s: creazione dello slot di replica \"%s\" fallita: ricevute %d righe e %d campi, attesi %d righe e %d campi\n" -#: streamutil.c:420 +#: streamutil.c:421 #, c-format msgid "%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n" msgstr "%s: eliminazione dello slot di replica \"%s\" fallita: ricevute %d righe e %d campi, attesi %d righe e %d campi\n" + +#: walmethods.c:435 walmethods.c:904 +msgid "could not compress data" +msgstr "compressione dei dati fallita" + +#: walmethods.c:459 +msgid "could not reset compression stream" +msgstr "reset dello stream di compressione fallito" + +#: walmethods.c:560 +msgid "could not initialize compression library" +msgstr "inizializzazione della libreria di compressione fallita" + +#: walmethods.c:572 +msgid "implementation error: tar files can't have more than one open file" +msgstr "errore di implementazione: i file tar non possono avere più di un file aperto" + +#: walmethods.c:586 +msgid "could not create tar header" +msgstr "creazione dell'intestazione del tar fallita" + +#: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 +msgid "could not change compression parameters" +msgstr "modifica dei parametri di compressione fallita" + +#: walmethods.c:720 +msgid "unlink not supported with compression" +msgstr "unlink non supportato con la compressione" + +#: walmethods.c:920 +msgid "could not close compression stream" +msgstr "chiusura dello stream di compressione fallita" diff --git a/src/bin/pg_basebackup/po/ja.po b/src/bin/pg_basebackup/po/ja.po new file mode 100644 index 00000000000..5ffc5a42773 --- /dev/null +++ b/src/bin/pg_basebackup/po/ja.po @@ -0,0 +1,1449 @@ +# LANGUAGE message translation file for pg_basebackup +# Copyright (C) 2011 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-02-02 11:15+0900\n" +"PO-Revision-Date: 2018-02-06 09:37+0900\n" +"Last-Translator: Michihide Hotta \n" +"Language-Team: jpug-doc \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "メモリä¸è¶³ã§ã™\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ãƒã‚¤ãƒ³ã‚¿ã‚’複製ã§ãã¾ã›ã‚“(内部エラー)。\n" + +#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#: pg_receivewal.c:252 pg_recvlogical.c:353 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\"ファイルをstatã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../../common/file_utils.c:162 pg_receivewal.c:153 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../../common/file_utils.c:198 pg_receivewal.c:320 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"を読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" + +#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:804 +#: receivelog.c:1061 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: ../../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã®åå‰ã‚’\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:159 +#, c-format +msgid "%s: removing data directory \"%s\"\n" +msgstr "%s: データディレクトリ\"%s\"を削除ã—ã¦ã„ã¾ã™\n" + +#: pg_basebackup.c:162 +#, c-format +msgid "%s: failed to remove data directory\n" +msgstr "%s: データディレクトリã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:168 +#, c-format +msgid "%s: removing contents of data directory \"%s\"\n" +msgstr "%s: データディレクトリ\"%s\"ã®å†…容を削除ã—ã¦ã„ã¾ã™\n" + +#: pg_basebackup.c:171 +#, c-format +msgid "%s: failed to remove contents of data directory\n" +msgstr "%s: データディレクトリã®ä¸­èº«ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:177 +#, c-format +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: WAL ディレクトリ\"%s\"を削除ã—ã¦ã„ã¾ã™\n" + +#: pg_basebackup.c:180 +#, c-format +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: WAL ディレクトリã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:186 +#, c-format +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: WAL ディレクトリ\"%s\"ã®ä¸­èº«ã‚’削除ã—ã¦ã„ã¾ã™\n" + +#: pg_basebackup.c:189 +#, c-format +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: WAL ディレクトリã®ä¸­èº«ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:197 +#, c-format +msgid "%s: data directory \"%s\" not removed at user's request\n" +msgstr "%s: ユーザãŒè¦æ±‚ã—ãŸãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"を削除ã—ã¾ã›ã‚“\n" + +#: pg_basebackup.c:202 +#, c-format +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: ユーザãŒè¦æ±‚ã—㟠WAL ディレクトリ\"%s\"を削除ã—ã¾ã›ã‚“\n" + +#: pg_basebackup.c:208 +#, c-format +msgid "%s: changes to tablespace directories will not be undone\n" +msgstr "%s: テーブル空間用ディレクトリã¸ã®å¤‰æ›´ã¯å–り消ã•れã¾ã›ã‚“\n" + +#: pg_basebackup.c:250 +#, c-format +msgid "%s: directory name too long\n" +msgstr "%s: ディレクトリåãŒé•·ã™ãŽã¾ã™\n" + +#: pg_basebackup.c:260 +#, c-format +msgid "%s: multiple \"=\" signs in tablespace mapping\n" +msgstr "%s: テーブル空間ã®ãƒžãƒƒãƒ”ング内ã«è¤‡æ•°ã®\"=\"記å·ãŒå­˜åœ¨ã—ã¾ã™\n" + +#: pg_basebackup.c:273 +#, c-format +msgid "" +"%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" +msgstr "" +"%s: テーブル空間ã®ãƒžãƒƒãƒ”ング形å¼\"%s\"ãŒç„¡åйã§ã™ã€‚\"æ—§DIR=æ–°DIR\"ã§ãªã‘れã°ãª" +"りã¾ã›ã‚“\n" + +#: pg_basebackup.c:286 +#, c-format +msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" +msgstr "" +"%s: テーブル空間ã®ãƒžãƒƒãƒ”ングã«ãŠã„ã¦ã€æ—§ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒçµ¶å¯¾ãƒ‘スã§ã¯ã‚りã¾ã›" +"ã‚“: %s\n" + +#: pg_basebackup.c:293 +#, c-format +msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" +msgstr "" +"%s: テーブル空間ã®ãƒžãƒƒãƒ”ングã«ãŠã„ã¦ã€æ–°ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒçµ¶å¯¾ãƒ‘スã§ã¯ã‚りã¾ã›" +"ã‚“: %s\n" + +#: pg_basebackup.c:332 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%sã¯å®Ÿè¡Œä¸­ã®PostgreSQLサーãƒã®ãƒ™ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’å–å¾—ã—ã¾ã™ã€‚\n" +"\n" + +#: pg_basebackup.c:334 pg_receivewal.c:76 pg_recvlogical.c:77 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_basebackup.c:335 pg_receivewal.c:77 pg_recvlogical.c:78 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [オプション]...\n" + +#: pg_basebackup.c:336 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"出力を制御ã™ã‚‹ã‚ªãƒ—ション:\n" + +#: pg_basebackup.c:337 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr "" +" -D, --pgdata=DIRECTORY ディレクトリ内ã«ãƒ™ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’æ ¼ç´ã—ã¾ã™\n" + +#: pg_basebackup.c:338 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr "" +" -F, --format=p|t 出力フォーマット(プレイン(デフォルト)ã¾ãŸã¯" +"tar)\n" + +#: pg_basebackup.c:339 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=RATE データディレクトリã¸è»¢é€ã™ã‚‹éš›ã®æœ€å¤§è»¢é€é€Ÿåº¦\n" +" (kB/s å˜ä½ã€ã¾ãŸã¯ 接尾辞 \"k\" ã‹\"M\" を使用)\n" + +#: pg_basebackup.c:341 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write recovery.conf for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" レプリケーション用ã«recovery.confを書ã出ã™\n" + +#: pg_basebackup.c:343 pg_receivewal.c:84 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=スロットå 使用ã™ã‚‹ãƒ¬ãƒ—リケーションスロット\n" + +#: pg_basebackup.c:344 +#, c-format +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr "" +" --no-slot 一時的ãªãƒ¬ãƒ—リケーションスロットã®ä½œæˆã‚’行ã‚ãªã„\n" + +#: pg_basebackup.c:345 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=æ—§DIR=æ–°DIR\n" +" テーブル空間を旧DIRã‹ã‚‰æ–°DIRã«ç§»å‹•ã™ã‚‹\n" + +#: pg_basebackup.c:347 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" è¦æ±‚ã•れ㟠WAL ファイルを指定ã®ãƒ¡ã‚½ãƒƒãƒ‰ã‚’使ã£ã¦ãƒãƒƒ" +"クアップã«å«ã‚ã‚‹\n" + +#: pg_basebackup.c:349 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR 先行書ãè¾¼ã¿ãƒ­ã‚°ç”¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ä½ç½®\n" + +#: pg_basebackup.c:350 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip tar ã®å‡ºåŠ›ã‚’åœ§ç¸®ã™ã‚‹\n" + +#: pg_basebackup.c:351 +#, c-format +msgid "" +" -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 指定ã—ãŸåœ§ç¸®ãƒ¬ãƒ™ãƒ«ã§ tar ã®å‡ºåŠ›ã‚’åœ§ç¸®ã™ã‚‹\n" + +#: pg_basebackup.c:352 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"汎用オプション:\n" + +#: pg_basebackup.c:353 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" 高速ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆå‡¦ç†ã¾ãŸã¯åˆ†æ•£ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆ" +"処ç†ã®è¨­å®š\n" + +#: pg_basebackup.c:355 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ラベルã®è¨­å®š\n" + +#: pg_basebackup.c:356 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr "" +" -n, --noclean エラー発生後も仕掛り中ファイルã®å‰Šé™¤ã‚’行ã‚ãªã„\n" + +#: pg_basebackup.c:357 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --nosync ディスクã¸ã®å®‰å…¨ãªæ›¸ãè¾¼ã¿ã¾ã§ã®å¾…機を行ã‚ãªã„\n" + +#: pg_basebackup.c:358 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress 進行状æ³ã®è¡¨ç¤º\n" + +#: pg_basebackup.c:359 pg_receivewal.c:86 pg_recvlogical.c:98 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose 冗長メッセージã®å‡ºåŠ›\n" + +#: pg_basebackup.c:360 pg_receivewal.c:87 pg_recvlogical.c:99 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã—ã¾ã™\n" + +#: pg_basebackup.c:361 pg_receivewal.c:89 pg_recvlogical.c:100 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦çµ‚了ã—ã¾ã™\n" + +#: pg_basebackup.c:362 pg_receivewal.c:90 pg_recvlogical.c:101 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"接続オプション:\n" + +#: pg_basebackup.c:363 pg_receivewal.c:91 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR 接続文字列\n" + +#: pg_basebackup.c:364 pg_receivewal.c:92 pg_recvlogical.c:103 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr "" +" -h, --host=HOSTNAME データベースサーãƒãƒ›ã‚¹ãƒˆã¾ãŸã¯ã‚½ã‚±ãƒƒãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆ" +"リ\n" + +#: pg_basebackup.c:365 pg_receivewal.c:93 pg_recvlogical.c:104 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT データベースサーãƒã®ãƒãƒ¼ãƒˆç•ªå·\n" + +#: pg_basebackup.c:366 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in " +"seconds)\n" +msgstr "" +" -s, --status-interval=INTERVAL\n" +" サーãƒã¸çŠ¶æ…‹ãƒ‘ã‚±ãƒƒãƒˆã‚’é€ä¿¡ã™ã‚‹é–“隔(秒å˜ä½ï¼‰\n" + +#: pg_basebackup.c:368 pg_receivewal.c:94 pg_recvlogical.c:105 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAME 指定ã—ãŸãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ¦ãƒ¼ã‚¶ã§æŽ¥ç¶š\n" + +#: pg_basebackup.c:369 pg_receivewal.c:95 pg_recvlogical.c:106 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password パスワードã®å…¥åŠ›ã‚’å—ã‘付ã‘ãªã„\n" + +#: pg_basebackup.c:370 pg_receivewal.c:96 pg_recvlogical.c:107 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr "" +" -W, --password 強制的ã«ãƒ‘スワード入力を促ã™ï¼ˆè‡ªå‹•çš„ã«è¡Œã‚れるã¯ãš" +"ã§ã™ï¼‰\n" + +#: pg_basebackup.c:371 pg_receivewal.c:100 pg_recvlogical.c:108 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ä¸å…·åˆãŒã‚れã°å®›ã¦ã«å ±å‘Šã—ã¦ãã ã•ã„。\n" + +#: pg_basebackup.c:414 +#, c-format +msgid "%s: could not read from ready pipe: %s\n" +msgstr "%s: 準備ã•れãŸãƒ‘イプã‹ã‚‰èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:422 pg_basebackup.c:557 pg_basebackup.c:2015 +#: streamutil.c:286 +#, c-format +msgid "%s: could not parse write-ahead log location \"%s\"\n" +msgstr "%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ã®ä½ç½® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_basebackup.c:520 pg_receivewal.c:428 +#, c-format +msgid "%s: could not finish writing WAL files: %s\n" +msgstr "%s: WALãƒ•ã‚¡ã‚¤ãƒ«ã®æ›¸ãè¾¼ã¿ã‚’終了ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:570 +#, c-format +msgid "%s: could not create pipe for background process: %s\n" +msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ—ロセス用ã®ãƒ‘イプを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: \"%s\"\n" + +#: pg_basebackup.c:610 pg_basebackup.c:666 pg_basebackup.c:1433 +#, c-format +msgid "%s: could not create directory \"%s\": %s\n" +msgstr "%s: ディレクトリ \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:629 +#, c-format +msgid "%s: could not create background process: %s\n" +msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ—ロセスを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:641 +#, c-format +msgid "%s: could not create background thread: %s\n" +msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:689 +#, c-format +msgid "%s: directory \"%s\" exists but is not empty\n" +msgstr "%s: ディレクトリ \"%s\" ã¯å­˜åœ¨ã—ã¾ã™ãŒç©ºã§ã¯ã‚りã¾ã›ã‚“\n" + +#: pg_basebackup.c:697 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ディレクトリ \"%s\" ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:759 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d テーブル空間 %*s" + +#: pg_basebackup.c:771 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間 (%s%-*.*s)" + +#: pg_basebackup.c:787 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間" + +#: pg_basebackup.c:809 +#, c-format +msgid "%s: transfer rate \"%s\" is not a valid value\n" +msgstr "%s: 転é€é€Ÿåº¦\"%s\"ãŒç„¡åйãªå€¤ã§ã™\n" + +#: pg_basebackup.c:816 +#, c-format +msgid "%s: invalid transfer rate \"%s\": %s\n" +msgstr "%s: 転é€é€Ÿåº¦\"%s\"ãŒç„¡åйãªå€¤ã§ã™: %s\n" + +#: pg_basebackup.c:826 +#, c-format +msgid "%s: transfer rate must be greater than zero\n" +msgstr "%s: 転é€é€Ÿåº¦ã¯0以上ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: pg_basebackup.c:860 +#, c-format +msgid "%s: invalid --max-rate unit: \"%s\"\n" +msgstr "%s: --max-rate ã®å˜ä½ãŒæœ‰åйã§ã¯ã‚りã¾ã›ã‚“: \"%s\"\n" + +#: pg_basebackup.c:869 +#, c-format +msgid "%s: transfer rate \"%s\" exceeds integer range\n" +msgstr "%s: 転é€é€Ÿåº¦\"%s\"ãŒintegerã®ç¯„囲を超ãˆã¦ã„ã¾ã™\n" + +#: pg_basebackup.c:881 +#, c-format +msgid "%s: transfer rate \"%s\" is out of range\n" +msgstr "%s: 転é€é€Ÿåº¦\"%s\"ãŒç¯„囲外ã§ã™\n" + +#: pg_basebackup.c:905 +#, c-format +msgid "%s: could not write to compressed file \"%s\": %s\n" +msgstr "%s: 圧縮ファイル \"%s\" ã«æ›¸ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:915 pg_basebackup.c:1527 pg_basebackup.c:1693 +#, c-format +msgid "%s: could not write to file \"%s\": %s\n" +msgstr "%s: ファイル \"%s\" ã«æ›¸ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:974 pg_basebackup.c:995 pg_basebackup.c:1023 +#, c-format +msgid "%s: could not set compression level %d: %s\n" +msgstr "%s: 圧縮レベルを%dã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1044 +#, c-format +msgid "%s: could not create compressed file \"%s\": %s\n" +msgstr "%s: \"%s\"圧縮ファイルを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1055 pg_basebackup.c:1487 pg_basebackup.c:1686 +#, c-format +msgid "%s: could not create file \"%s\": %s\n" +msgstr "%s: ファイル \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1067 pg_basebackup.c:1340 +#, c-format +msgid "%s: could not get COPY data stream: %s" +msgstr "%s: COPYデータストリームをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1124 +#, c-format +msgid "%s: could not close compressed file \"%s\": %s\n" +msgstr "%s: 圧縮ファイル \"%s\" ã‚’é–‰ã˜ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1137 pg_recvlogical.c:631 receivelog.c:223 receivelog.c:308 +#: receivelog.c:714 +#, c-format +msgid "%s: could not close file \"%s\": %s\n" +msgstr "%s: ファイル\"%s\"ã‚’é–‰ã˜ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1148 pg_basebackup.c:1369 pg_recvlogical.c:453 +#: receivelog.c:1009 +#, c-format +msgid "%s: could not read COPY data: %s" +msgstr "%s: COPYデータを読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1383 +#, c-format +msgid "%s: invalid tar block header size: %d\n" +msgstr "%s: 無効ãªtarブロックヘッダサイズ: %d\n" + +#: pg_basebackup.c:1441 +#, c-format +msgid "%s: could not set permissions on directory \"%s\": %s\n" +msgstr "%s: \"%s\"ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1465 +#, c-format +msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" +msgstr "%s: \"%s\"ã‹ã‚‰\"%s\"ã¸ã®ã‚·ãƒ³ãƒœãƒªãƒƒã‚¯ãƒªãƒ³ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1474 +#, c-format +msgid "%s: unrecognized link indicator \"%c\"\n" +msgstr "%s: ãƒªãƒ³ã‚¯æŒ‡ç¤ºå­ \"%c\" ã‚’èªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_basebackup.c:1494 +#, c-format +msgid "%s: could not set permissions on file \"%s\": %s\n" +msgstr "%s: ファイル \"%s\" ã®æ¨©é™ã‚’設定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1553 +#, c-format +msgid "%s: COPY stream ended before last file was finished\n" +msgstr "%s: 最後ã®ãƒ•ァイルãŒçµ‚ã‚ã‚‹å‰ã«COPYストリームãŒå®Œäº†ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:1581 pg_basebackup.c:1601 pg_basebackup.c:1608 +#: pg_basebackup.c:1661 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: メモリä¸è¶³ã§ã™\n" + +#: pg_basebackup.c:1734 +#, c-format +msgid "%s: incompatible server version %s\n" +msgstr "%s: äº’æ›æ€§ãŒãªã„サーãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³\"%s\"\n" + +#: pg_basebackup.c:1749 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming\n" +msgstr "" +"ヒント: ログストリーミングを無効ã«ã™ã‚‹ã«ã¯ -X none ã¾ãŸã¯ -X fetch を使ã£ã¦ã" +"ã ã•ã„\n" + +#: pg_basebackup.c:1775 +#, c-format +msgid "%s: initiating base backup, waiting for checkpoint to complete\n" +msgstr "" +"%s: ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®åˆæœŸåŒ–中 - ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®å®Œäº†ã‚’待機中ã§ã™\n" + +#: pg_basebackup.c:1793 pg_recvlogical.c:270 receivelog.c:492 receivelog.c:563 +#: receivelog.c:603 streamutil.c:256 streamutil.c:364 streamutil.c:410 +#, c-format +msgid "%s: could not send replication command \"%s\": %s" +msgstr "%s: レプリケーションコマンド\"%s\"ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1804 +#, c-format +msgid "%s: could not initiate base backup: %s" +msgstr "%s: ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1811 +#, c-format +msgid "" +"%s: server returned unexpected response to BASE_BACKUP command; got %d rows " +"and %d fields, expected %d rows and %d fields\n" +msgstr "" +"%s: サーãƒã¯BASE_BACKUPã‚³ãƒžãƒ³ãƒ‰ã«æƒ³å®šå¤–ã®å¿œç­”ã‚’è¿”ã—ã¾ã—ãŸ: %d行ã¨%dフィールド" +"ã‚’å—ä¿¡ã—ã¾ã—ãŸã€‚期待ã™ã‚‹å€¤ã¯%d行ã¨%dフィールドã§ã—ãŸ\n" + +#: pg_basebackup.c:1819 +#, c-format +msgid "%s: checkpoint completed\n" +msgstr "%s: ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆãŒå®Œäº†ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:1834 +#, c-format +msgid "%s: write-ahead log start point: %s on timeline %u\n" +msgstr "%1$s: 先行書ãè¾¼ã¿ãƒ­ã‚°ã®é–‹å§‹ãƒã‚¤ãƒ³ãƒˆ: タイムライン%3$u上ã®%2$s\n" + +#: pg_basebackup.c:1843 +#, c-format +msgid "%s: could not get backup header: %s" +msgstr "%s: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ヘッダをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1849 +#, c-format +msgid "%s: no data returned from server\n" +msgstr "%s: サーãƒã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ãŒè¿”ã•れã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_basebackup.c:1881 +#, c-format +msgid "%s: can only write single tablespace to stdout, database has %d\n" +msgstr "" +"%s: æ¨™æº–å‡ºåŠ›ã«æ›¸ã出ã›ã‚‹ãƒ†ãƒ¼ãƒ–ル空間ã¯ï¼‘ã¤ã ã‘ã§ã™ãŒã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã¯%d個ã‚" +"りã¾ã™\n" + +#: pg_basebackup.c:1893 +#, c-format +msgid "%s: starting background WAL receiver\n" +msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰WALå—信処ç†ã‚’é–‹å§‹ã—ã¾ã™\n" + +#: pg_basebackup.c:1924 +#, c-format +msgid "%s: could not get write-ahead log end position from server: %s" +msgstr "%s: サーãƒã‹ã‚‰å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ã®çµ‚了ä½ç½®ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_basebackup.c:1931 +#, c-format +msgid "%s: no write-ahead log end position returned from server\n" +msgstr "%s: サーãƒã‹ã‚‰å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ã®çµ‚了ä½ç½®ãŒè¿”ã•れã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_basebackup.c:1937 +#, c-format +msgid "%s: write-ahead log end point: %s\n" +msgstr "%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ã®çµ‚了ãƒã‚¤ãƒ³ãƒˆ: %s\n" + +#: pg_basebackup.c:1943 +#, c-format +msgid "%s: final receive failed: %s" +msgstr "%s: 最終å—ä¿¡ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: pg_basebackup.c:1967 +#, c-format +msgid "%s: waiting for background process to finish streaming ...\n" +msgstr "" +"%s: ストリーミング処ç†ãŒçµ‚ã‚ã‚‹ã¾ã§ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ãƒ—ロセスを待機ã—ã¾ã™ ...\n" + +#: pg_basebackup.c:1973 +#, c-format +msgid "%s: could not send command to background pipe: %s\n" +msgstr "%s: ãƒãƒƒã‚¯ã‚°ãƒ©ãƒ³ãƒ‰ã¸ã®ãƒ‘イプã«ã‚³ãƒžãƒ³ãƒ‰ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1982 +#, c-format +msgid "%s: could not wait for child process: %s\n" +msgstr "%s: å­ãƒ—ロセスを待機ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:1988 +#, c-format +msgid "%s: child %d died, expected %d\n" +msgstr "%s: å­ãƒ—ロセス%d ãŒçµ‚äº†ã€æœŸå¾…値ã¯%dã§ã—ãŸ\n" + +#: pg_basebackup.c:1994 +#, c-format +msgid "%s: child process did not exit normally\n" +msgstr "%s: å­ãƒ—ãƒ­ã‚»ã‚¹ãŒæ­£å¸¸ã«çµ‚了ã—ã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_basebackup.c:2000 +#, c-format +msgid "%s: child process exited with error %d\n" +msgstr "%s: å­ãƒ—ロセスãŒçµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:2027 +#, c-format +msgid "%s: could not wait for child thread: %s\n" +msgstr "%s: å­ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’待機ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:2034 +#, c-format +msgid "%s: could not get child thread exit status: %s\n" +msgstr "%s: å­ã‚¹ãƒ¬ãƒƒãƒ‰ã®çµ‚了ステータスをå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:2040 +#, c-format +msgid "%s: child thread exited with error %u\n" +msgstr "%s: å­ã‚¹ãƒ¬ãƒƒãƒ‰ãŒã‚¨ãƒ©ãƒ¼%uã§çµ‚了ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:2078 +#, c-format +msgid "%s: base backup completed\n" +msgstr "%s: ベースãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ãŒå®Œäº†ã—ã¾ã—ãŸ\n" + +#: pg_basebackup.c:2155 +#, c-format +msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "" +"%s: 出力フォーマット \"%s\" ã¯ç„¡åйã§ã™ã€‚\"plain\"ã‹\"tar\"ã§ãªã‘れã°ãªã‚Šã¾ã›" +"ã‚“\n" + +#: pg_basebackup.c:2200 +#, c-format +msgid "" +"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or " +"\"none\"\n" +msgstr "" +"%s: wal-method オプション \"%s\" ã¯ç„¡åйã§ã™ã€‚\"fetch\", \"stream\", \"none\" " +"ã®ã„ãšã‚Œã‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: pg_basebackup.c:2228 pg_receivewal.c:556 +#, c-format +msgid "%s: invalid compression level \"%s\"\n" +msgstr "%s: 圧縮レベル \"%s\" ã¯ç„¡åйã§ã™\n" + +#: pg_basebackup.c:2240 +#, c-format +msgid "" +"%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" +msgstr "" +"%s: checkpoint ã®å¼•æ•° \"%s\" ã¯ç„¡åйã§ã™ã€‚\"fast\"ã¾ãŸã¯\"spreadã§ãªã‘れã°ãªã‚Š" +"ã¾ã›ã‚“\n" + +#: pg_basebackup.c:2267 pg_receivewal.c:538 pg_recvlogical.c:825 +#, c-format +msgid "%s: invalid status interval \"%s\"\n" +msgstr "%s: status-interval 値 \"%s\" ã¯ç„¡åйã§ã™\n" + +#: pg_basebackup.c:2283 pg_basebackup.c:2297 pg_basebackup.c:2308 +#: pg_basebackup.c:2321 pg_basebackup.c:2331 pg_basebackup.c:2341 +#: pg_basebackup.c:2353 pg_basebackup.c:2367 pg_basebackup.c:2378 +#: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 +#: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 +#: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 +#: pg_recvlogical.c:893 pg_recvlogical.c:901 pg_recvlogical.c:909 +#: pg_recvlogical.c:917 pg_recvlogical.c:927 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細ã¯\"%s --help\"ã§ç¢ºèªã—ã¦ãã ã•ã„。\n" + +#: pg_basebackup.c:2295 pg_receivewal.c:591 pg_recvlogical.c:864 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数ãŒå¤šéŽãŽã¾ã™(先頭ã¯\"%s\"ã§ã™)\n" + +#: pg_basebackup.c:2307 pg_receivewal.c:621 +#, c-format +msgid "%s: no target directory specified\n" +msgstr "%s: å¯¾è±¡ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_basebackup.c:2319 +#, c-format +msgid "%s: only tar mode backups can be compressed\n" +msgstr "%s: tarモードã®ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã®ã¿åœ§ç¸®ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™\n" + +#: pg_basebackup.c:2329 +#, c-format +msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" +msgstr "" +"%s: tar モードã§ã¯æ›¸ãè¾¼ã¿å…ˆè¡Œãƒ­ã‚°ã‚’標準出力ã«ã‚¹ãƒˆãƒªãƒ¼ãƒ ã¨ã—ã¦æ›¸ã出ã›ã¾ã›" +"ã‚“\n" + +#: pg_basebackup.c:2339 +#, c-format +msgid "%s: replication slots can only be used with WAL streaming\n" +msgstr "%s: WAL ストリーミングã§ã¯ãƒ¬ãƒ—リケーションスロットã ã‘ãŒä½¿ç”¨ã§ãã¾ã™\n" + +#: pg_basebackup.c:2351 +#, c-format +msgid "%s: --no-slot cannot be used with slot name\n" +msgstr "%s: --no-slot ã¯ã‚¹ãƒ­ãƒƒãƒˆåã¨åŒæ™‚ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“\n" + +#: pg_basebackup.c:2365 +#, c-format +msgid "%s: WAL directory location can only be specified in plain mode\n" +msgstr "%s: WAL ディレクトリã®ä½ç½®ã¯ plainモードã§ã®ã¿æŒ‡å®šã§ãã¾ã™\n" + +#: pg_basebackup.c:2376 +#, c-format +msgid "%s: WAL directory location must be an absolute path\n" +msgstr "%s: WAL ディレクトリã®ä½ç½®ã¯ã€çµ¶å¯¾ãƒ‘スã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: pg_basebackup.c:2388 pg_receivewal.c:631 +#, c-format +msgid "%s: this build does not support compression\n" +msgstr "%s: ã“ã®å®Ÿè¡Œãƒã‚¤ãƒŠãƒªã§ã¯åœ§ç¸®æ©Ÿèƒ½ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“\n" + +#: pg_basebackup.c:2428 +#, c-format +msgid "%s: could not create symbolic link \"%s\": %s\n" +msgstr "%s: シンボリックリンク\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_basebackup.c:2433 +#, c-format +msgid "%s: symlinks are not supported on this platform\n" +msgstr "" +"%s: シンボリックリンクã¯ã“ã®ãƒ—ラットフォームã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_receivewal.c:74 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%sã¯PostgreSQLã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‚’å—ä¿¡ã—ã¾ã™ã€‚\n" +"\n" + +#: pg_receivewal.c:78 pg_recvlogical.c:83 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_receivewal.c:79 +#, c-format +msgid "" +" -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr "" +" -D, --directory=DIR å—ä¿¡ã—ãŸå…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ã®æ ¼ç´ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: pg_receivewal.c:80 pg_recvlogical.c:88 +#, c-format +msgid "" +" --if-not-exists do not error if slot already exists when creating a " +"slot\n" +msgstr "" +"   --if-not-exists スロットã®ä½œæˆæ™‚ã€ã‚¹ãƒ­ãƒƒãƒˆãŒæ—¢ã«å­˜åœ¨ã—ã¦ã„ã¦ã‚‚エラー" +"ã¨ã—ãªã„\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:90 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop 接続ãŒå¤±ã‚れãŸã‚‰ãƒ«ãƒ¼ãƒ—ã—ãªã„ã„\n" + +#: pg_receivewal.c:82 pg_recvlogical.c:95 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server " +"(default: %d)\n" +msgstr "" +" -s, --status-interval=SECS\n" +" サーãƒã¸çŠ¶æ…‹ãƒ‘ã‚±ãƒƒãƒˆã‚’é€ä¿¡ã™ã‚‹é–“隔(デフォルト: " +"%d)\n" + +#: pg_receivewal.c:85 +#, c-format +msgid "" +" --synchronous flush write-ahead log immediately after writing\n" +msgstr "" +" --synchronous 先行書ãè¾¼ã¿ãƒ­ã‚°ã¯æ›¸ãè¾¼ã¿å¾Œã™ãã«ãƒ•ラッシュã™ã‚‹\n" + +#: pg_receivewal.c:88 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 指定ã—ãŸåœ§ç¸®ãƒ¬ãƒ™ãƒ«ã§ãƒ­ã‚°ã‚’圧縮ã—ã¾ã™\n" + +#: pg_receivewal.c:97 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"追加æ“作:\n" + +#: pg_receivewal.c:98 pg_recvlogical.c:80 +#, c-format +msgid "" +" --create-slot create a new replication slot (for the slot's name " +"see --slot)\n" +msgstr "" +" --create-slot æ–°ã—ã„レプリケーションスロットを作æˆã™ã‚‹(スロットåã«" +"ã¤ã„ã¦ã¯ --slot ã‚’å‚ç…§)\n" + +#: pg_receivewal.c:99 pg_recvlogical.c:81 +#, c-format +msgid "" +" --drop-slot drop the replication slot (for the slot's name see " +"--slot)\n" +msgstr "" +" --drop-slotp レプリケーションスロットを削除ã™ã‚‹ (スロットåを見" +"ã‚‹ã«ã¯ --slot)\n" + +#: pg_receivewal.c:111 +#, c-format +msgid "%s: finished segment at %X/%X (timeline %u)\n" +msgstr "%s: %X/%X (タイムライン %u)ã§ã‚»ã‚°ãƒ¡ãƒ³ãƒˆãŒå®Œäº†\n" + +#: pg_receivewal.c:124 +#, c-format +msgid "%s: switched to timeline %u at %X/%X\n" +msgstr "%s: タイムライン%uã«%X/%Xã§åˆ‡ã‚Šæ›¿ã‚りã¾ã—ãŸ\n" + +#: pg_receivewal.c:133 +#, c-format +msgid "%s: received interrupt signal, exiting\n" +msgstr "%s: 割り込ã¿ã‚·ã‚°ãƒŠãƒ«ã‚’å—ã‘å–りã¾ã—ãŸã€‚終了ã—ã¾ã™\n" + +#: pg_receivewal.c:171 +#, c-format +msgid "%s: could not close directory \"%s\": %s\n" +msgstr "%s: ディレクトリ \"%s\" をクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_receivewal.c:260 +#, c-format +msgid "%s: segment file \"%s\" has incorrect size %d, skipping\n" +msgstr "%s: セグメントファイル\"%s\"ã®ã‚µã‚¤ã‚º%dãŒä¸æ­£ã§ã™ã€‚スキップã—ã¾ã™\n" + +#: pg_receivewal.c:277 +#, c-format +msgid "%s: could not open compressed file \"%s\": %s\n" +msgstr "%s: 圧縮ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_receivewal.c:283 +#, c-format +msgid "%s: could not seek in compressed file \"%s\": %s\n" +msgstr "%s: 圧縮ファイル \"%s\" ã‚’ seek ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_receivewal.c:289 +#, c-format +msgid "%s: could not read compressed file \"%s\": %s\n" +msgstr "%s: 圧縮ファイル \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_receivewal.c:301 +#, c-format +msgid "" +"%s: compressed segment file \"%s\" has incorrect uncompressed size %d, " +"skipping\n" +msgstr "" +"%s: セグメントファイル\"%s\"ã®å±•開後サイズ%dãŒä¸æ­£ã§ã™ã€‚スキップã—ã¾ã™\n" + +#: pg_receivewal.c:407 +#, c-format +msgid "%s: starting log streaming at %X/%X (timeline %u)\n" +msgstr "%s: %X/%X (タイムライン %u)ã§ãƒ­ã‚°ã®ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’å§‹ã‚ã¾ã™\n" + +#: pg_receivewal.c:519 pg_recvlogical.c:762 +#, c-format +msgid "%s: invalid port number \"%s\"\n" +msgstr "%s: 無効ãªãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"\n" + +#: pg_receivewal.c:600 +#, c-format +msgid "%s: cannot use --create-slot together with --drop-slot\n" +msgstr "%s: --create-slot 㯠--drop-slot ã¨ä¸€ç·’ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“\n" + +#. translator: second %s is an option name +#: pg_receivewal.c:609 +#, c-format +msgid "%s: %s needs a slot to be specified using --slot\n" +msgstr "%s: オプションå %s 㯠--slot ã§ã‚¹ãƒ­ãƒƒãƒˆã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: pg_receivewal.c:674 +#, c-format +msgid "" +"%s: replication connection using slot \"%s\" is unexpectedly database " +"specific\n" +msgstr "" +"%s: スロット \"%s\" を使用ã™ã‚‹ãƒ¬ãƒ—リケーション接続ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦" +"ãŠã‚Šã€ã“ã‚Œã¯æƒ³å®šå¤–ã§ã™\n" + +#: pg_receivewal.c:686 pg_recvlogical.c:967 +#, c-format +msgid "%s: dropping replication slot \"%s\"\n" +msgstr "%s: レプリケーションスロット\"%s\"を削除ã—ã¦ã„ã¾ã™\n" + +#: pg_receivewal.c:699 pg_recvlogical.c:979 +#, c-format +msgid "%s: creating replication slot \"%s\"\n" +msgstr "%s: レプリケーションスロット\"%s\"を作æˆã—ã¦ã„ã¾ã™\n" + +#: pg_receivewal.c:726 pg_recvlogical.c:1005 +#, c-format +msgid "%s: disconnected\n" +msgstr "%s: 切断ã—ã¾ã—ãŸ\n" + +#. translator: check source for value for %d +#: pg_receivewal.c:733 pg_recvlogical.c:1012 +#, c-format +msgid "%s: disconnected; waiting %d seconds to try again\n" +msgstr "%s: 切断ã—ã¾ã—ãŸã€‚%d秒待機ã—ã¦å†è©¦è¡Œã—ã¾ã™\n" + +#: pg_recvlogical.c:75 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s ã¯PostgreSQLã®è«–ç†å¾©å·ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‚’制御ã—ã¾ã™ã€‚\n" +"\n" + +#: pg_recvlogical.c:79 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"実行ã•れるã¹ãæ“作:\n" + +#: pg_recvlogical.c:82 +#, c-format +msgid "" +" --start start streaming in a replication slot (for the " +"slot's name see --slot)\n" +msgstr "" +" --start レプリケーションスロットã§ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’é–‹å§‹ã™ã‚‹ " +"(スロットåを見るã«ã¯ --slot)\n" + +#: pg_recvlogical.c:84 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN 指定 LSN ã®å—信後ã«çµ‚了ã—ã¾ã™\n" + +#: pg_recvlogical.c:85 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr "" +" -f, --file=FILE ã“ã®ãƒ•ァイルã«ãƒ­ã‚°ã‚’å—ã‘å–りã¾ã™ã€‚ - ã§æ¨™æº–出力ã«å‡º" +"力ã—ã¾ã™\n" + +#: pg_recvlogical.c:86 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: " +"%d)\n" +msgstr "" +" -F --fsync-interval=SECS\n" +" 出力ファイルã¸ã®fsyncs 時間間隔(デフォルト: %d)\n" + +#: pg_recvlogical.c:89 +#, c-format +msgid "" +" -I, --startpos=LSN where in an existing slot should the streaming " +"start\n" +msgstr "" +" -I, --startpos=LSN 既存スロット内ã§ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’回ä½ã™ã‚‹ã¹ãä½ç½®\n" + +#: pg_recvlogical.c:91 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAME[=VALUE]\n" +" オプションå NAME ã¨ã‚ªãƒ—ション値 VALUE を出力プラグイ" +"ンã«\n" +" 渡ã™\n" + +#: pg_recvlogical.c:94 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr "" +" -P, --plugin=PLUGIN 出力プラグイン PLUGIN を使ã†(デフォルト: %s)\n" + +#: pg_recvlogical.c:97 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTå è«–ç†ãƒ¬ãƒ—リケーションスロットå\n" + +#: pg_recvlogical.c:102 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å æŽ¥ç¶šã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\n" + +#: pg_recvlogical.c:135 +#, c-format +msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" +msgstr "" +"%s: %X/%Xã¾ã§ã®æ›¸ãè¾¼ã¿ã¨ã€%X/%X (スロット %s)ã¾ã§ã®ãƒ•ラッシュを確èªã—ã¦ã„" +"ã¾ã™\n" + +#: pg_recvlogical.c:160 receivelog.c:351 +#, c-format +msgid "%s: could not send feedback packet: %s" +msgstr "%s: フィードãƒãƒƒã‚¯ãƒ‘ケットをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_recvlogical.c:199 +#, c-format +msgid "%s: could not fsync log file \"%s\": %s\n" +msgstr "%s: ログファイル\"%s\"ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_recvlogical.c:238 +#, c-format +msgid "%s: starting log streaming at %X/%X (slot %s)\n" +msgstr "%s: %X/%X (スロット %s)ã§ãƒ­ã‚°ã®ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’é–‹å§‹ã—ã¾ã™\n" + +#: pg_recvlogical.c:280 +#, c-format +msgid "%s: streaming initiated\n" +msgstr "%s: ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’åˆæœŸåŒ–ã—ã¾ã—ãŸ\n" + +#: pg_recvlogical.c:346 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: ログファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_recvlogical.c:376 receivelog.c:914 +#, c-format +msgid "%s: invalid socket: %s" +msgstr "%s: 無効ãªã‚½ã‚±ãƒƒãƒˆã§ã™: %s" + +#: pg_recvlogical.c:430 receivelog.c:943 +#, c-format +msgid "%s: select() failed: %s\n" +msgstr "%s: select()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: pg_recvlogical.c:439 receivelog.c:995 +#, c-format +msgid "%s: could not receive data from WAL stream: %s" +msgstr "%s: WALストリームã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1040 +#: receivelog.c:1107 +#, c-format +msgid "%s: streaming header too small: %d\n" +msgstr "%s: ストリーミングヘッダãŒå°ã•éŽãŽã¾ã™: %d\n" + +#: pg_recvlogical.c:517 receivelog.c:874 +#, c-format +msgid "%s: unrecognized streaming header: \"%c\"\n" +msgstr "%s: ストリーミングヘッダ \"%c\" ã‚’èªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_recvlogical.c:573 pg_recvlogical.c:587 +#, c-format +msgid "%s: could not write %u bytes to log file \"%s\": %s\n" +msgstr "%s: %u ãƒã‚¤ãƒˆã‚’ログファイル \"%s\" ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_recvlogical.c:617 receivelog.c:667 receivelog.c:705 +#, c-format +msgid "%s: unexpected termination of replication stream: %s" +msgstr "%s: レプリケーションストリームãŒçªç„¶çµ‚了ã—ã¾ã—ãŸ: %s" + +#: pg_recvlogical.c:741 +#, c-format +msgid "%s: invalid fsync interval \"%s\"\n" +msgstr "%s: fsyncã®é–“éš” \"%s\" ã¯ç„¡åйã§ã™\n" + +#: pg_recvlogical.c:782 +#, c-format +msgid "%s: could not parse start position \"%s\"\n" +msgstr "%s: é–‹å§‹ä½ç½® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_recvlogical.c:792 +#, c-format +msgid "%s: could not parse end position \"%s\"\n" +msgstr "%s: 終了ä½ç½® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_recvlogical.c:876 +#, c-format +msgid "%s: no slot specified\n" +msgstr "%s: ã‚¹ãƒ­ãƒƒãƒˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_recvlogical.c:884 +#, c-format +msgid "%s: no target file specified\n" +msgstr "%s: ã‚¿ãƒ¼ã‚²ãƒƒãƒˆãƒ•ã‚¡ã‚¤ãƒ«ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_recvlogical.c:892 +#, c-format +msgid "%s: no database specified\n" +msgstr "%s: ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_recvlogical.c:900 +#, c-format +msgid "%s: at least one action needs to be specified\n" +msgstr "%s: å°‘ãªãã¨ã‚‚一ã¤ã®ã‚¢ã‚¯ã‚·ãƒ§ãƒ³ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™\n" + +#: pg_recvlogical.c:908 +#, c-format +msgid "%s: cannot use --create-slot or --start together with --drop-slot\n" +msgstr "%s: --create-slot ã‚„ --start 㯠--drop-slot ã¨ä¸€ç·’ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“\n" + +#: pg_recvlogical.c:916 +#, c-format +msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" +msgstr "" +"%s: --create-slot ã‚„ --drop-slot 㯠--startpos ã¨ä¸€ç·’ã«ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“\n" + +#: pg_recvlogical.c:925 +#, c-format +msgid "%s: --endpos may only be specified with --start\n" +msgstr "%s: --start ã¨åŒæ™‚ã«æŒ‡å®šã§ãã‚‹ã®ã¯ --endpos ã ã‘ã§ã™\n" + +#: pg_recvlogical.c:957 +#, c-format +msgid "%s: could not establish database-specific replication connection\n" +msgstr "%s: データベース指定ã®ãƒ¬ãƒ—リケーション接続ãŒç¢ºç«‹ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: receivelog.c:71 +#, c-format +msgid "%s: could not create archive status file \"%s\": %s\n" +msgstr "%s: アーカイブ状態ファイル \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:119 +#, c-format +msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" +msgstr "" +"%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル \"%s\" ã®ã‚µã‚¤ã‚ºã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:130 +#, c-format +msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" +msgstr "" +"%s: 既存ã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:139 +#, c-format +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" +msgstr "%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル \"%s\" ã‚’fsyncã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:154 +#, c-format +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "" +"%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "" +"%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル\"%s\"ã®é•·ã•ãŒ%dãƒã‚¤ãƒˆã§ã™ã€‚ã“れã¯0ã¾ãŸã¯%dã§ãªã‘" +"れã°ãªã‚Šã¾ã›ã‚“\n" + +#: receivelog.c:169 +#, c-format +msgid "%s: could not open write-ahead log file \"%s\": %s\n" +msgstr "%s: 先行書ãè¾¼ã¿ãƒ­ã‚°ãƒ•ァイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:196 +#, c-format +msgid "%s: could not determine seek position in file \"%s\": %s\n" +msgstr "%s: ファイル \"%s\" 内ã§ã‚·ãƒ¼ã‚¯ä½ç½®ã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:211 +#, c-format +msgid "%s: not renaming \"%s%s\", segment is not complete\n" +msgstr "%s: \"%s%s\"ã®åå‰ã‚’変更ã—ã¾ã›ã‚“。セグメントãŒå®Œäº†ã—ã¦ã„ã¾ã›ã‚“。\n" + +#: receivelog.c:280 +#, c-format +msgid "%s: server reported unexpected history file name for timeline %u: %s\n" +msgstr "" +"%s: サーãƒã¯ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%u用ã®å±¥æ­´ãƒ•ァイルåãŒæœŸå¾…ã—ãªã„値ã§ã‚ã‚‹ã“ã¨ã‚’報告ã—" +"ã¾ã—ãŸ: %s\n" + +#: receivelog.c:288 +#, c-format +msgid "%s: could not create timeline history file \"%s\": %s\n" +msgstr "%s: タイムライン履歴ファイル \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:295 +#, c-format +msgid "%s: could not write timeline history file \"%s\": %s\n" +msgstr "" +"%s: タイムライン履歴ファイル \"%s\" ã«æ›¸ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: receivelog.c:385 +#, c-format +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions older than %s\n" +msgstr "" +"%s: äº’æ›æ€§ã®ãªã„サーãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã§ã™ã€‚クライアントã¯%sよりå¤ã„サーãƒãƒãƒ¼" +"ジョンã‹ã‚‰ã®ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“\n" + +#: receivelog.c:395 +#, c-format +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions newer than %s\n" +msgstr "" +"%s: äº’æ›æ€§ã®ãªã„サーãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³%sã§ã™ã€‚クライアントã¯%sより新ã—ã„サーãƒãƒãƒ¼" +"ジョンã‹ã‚‰ã®ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“\n" + +#: receivelog.c:500 streamutil.c:265 streamutil.c:304 +#, c-format +msgid "" +"%s: could not identify system: got %d rows and %d fields, expected %d rows " +"and %d or more fields\n" +msgstr "" +"%s: システムを識別ã§ãã¾ã›ã‚“ã§ã—ãŸ: å—ä¿¡ã—ãŸã®ã¯ %d 行㧠%d ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã€æœŸå¾…" +"ã—ã¦ã„ãŸã®ã¯%d 行㧠%d 以上ã®ãƒ•ィールドã§ã—ãŸ\n" + +#: receivelog.c:508 +#, c-format +msgid "" +"%s: system identifier does not match between base backup and streaming " +"connection\n" +msgstr "" +"%s: システム識別å­ãŒãƒ™ãƒ¼ã‚¹ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã¨ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°æŽ¥ç¶šã®é–“ã§ä¸€è‡´ã—ã¾ã›" +"ã‚“\n" + +#: receivelog.c:516 +#, c-format +msgid "%s: starting timeline %u is not present in the server\n" +msgstr "%s: é–‹å§‹ã™ã‚‹ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uãŒã‚µãƒ¼ãƒä¸Šã«å­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: receivelog.c:535 +#, c-format +msgid "%s: could not create temporary replication slot \"%s\": %s" +msgstr "%s: 一時的ãªãƒ¬ãƒ—リケーションスロット \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: receivelog.c:576 +#, c-format +msgid "" +"%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d " +"fields, expected %d rows and %d fields\n" +msgstr "" +"%s: TIMELINE_HISTORYコマンドã¸ã®æƒ³å®šå¤–ã®å¿œç­”: å—ä¿¡ã—ãŸã®ã¯%d行ã§%dフィール" +"ãƒ‰ã€æƒ³å®šã—ã¦ã„ãŸã®ã¯%d行ã§%dフィールドã§ã—ãŸ\n" + +#: receivelog.c:648 +#, c-format +msgid "" +"%s: server reported unexpected next timeline %u, following timeline %u\n" +msgstr "" +"%1$s: サーãƒãŒã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%3$uã®æ¬¡ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%2$uãŒæƒ³å®šå¤–ã§ã‚ã‚‹ã“ã¨ã‚’報告" +"ã—ã¾ã—ãŸ\n" + +#: receivelog.c:655 +#, c-format +msgid "" +"%s: server stopped streaming timeline %u at %X/%X, but reported next " +"timeline %u to begin at %X/%X\n" +msgstr "" +"%s: サーãƒã¯ã‚¹ãƒˆãƒªãƒ¼ãƒŸãƒ³ã‚°ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³%uã‚’%X%Xã§åœæ­¢ã—ã¾ã—ãŸã€‚ã—ã‹ã—次ã®ã‚¿ã‚¤" +"ムライン%uãŒ%X%Xã§å§‹ã¾ã‚Šã¾ã—ãŸ\n" + +#: receivelog.c:696 +#, c-format +msgid "%s: replication stream was terminated before stop point\n" +msgstr "%s: レプリケーションストリームãŒåœæ­¢ãƒã‚¤ãƒ³ãƒˆã‚ˆã‚Šå‰ã§çµ‚了ã—ã¾ã—ãŸ\n" + +#: receivelog.c:745 +#, c-format +msgid "" +"%s: unexpected result set after end-of-timeline: got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³çµ‚äº†å¾Œã«æƒ³å®šå¤–ã®çµæžœã‚»ãƒƒãƒˆ: å—ä¿¡ã—ãŸã®ã¯%d行ã§%dフィールドã€" +"想定ã—ã¦ã„ãŸã®ã¯%d行ã§%dフィールドã§ã—ãŸ\n" + +#: receivelog.c:755 +#, c-format +msgid "%s: could not parse next timeline's starting point \"%s\"\n" +msgstr "%s: 次ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³ã®é–‹å§‹ãƒã‚¤ãƒ³ãƒˆ\"%s\"ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: receivelog.c:1126 +#, c-format +msgid "%s: received write-ahead log record for offset %u with no file open\n" +msgstr "" +"%s: ファイルãŒã‚ªãƒ¼ãƒ—ンã•れã¦ã„ãªã„状態ã§ã€ã‚ªãƒ•セット%uã«å¯¾ã™ã‚‹å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­" +"グレコードをå—ä¿¡ã—ã¾ã—ãŸ\n" + +#: receivelog.c:1137 +#, c-format +msgid "%s: got WAL data offset %08x, expected %08x\n" +msgstr "%s: WALデータオフセット%08xã‚’å—信。想定値ã¯%08xã§ã—ãŸ\n" + +#: receivelog.c:1172 +#, c-format +msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" +msgstr "" +"%1$s: WALファイル\"%3$s\"ã«%2$uãƒã‚¤ãƒˆæ›¸ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %4$s\n" + +#: receivelog.c:1197 receivelog.c:1238 receivelog.c:1269 +#, c-format +msgid "%s: could not send copy-end packet: %s" +msgstr "%s: コピーエンドパケットをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: streamutil.c:149 +msgid "Password: " +msgstr "パスワード: " + +#: streamutil.c:174 +#, c-format +msgid "%s: could not connect to server\n" +msgstr "%s: サーãƒã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: streamutil.c:192 +#, c-format +msgid "%s: could not connect to server: %s" +msgstr "%s: サーãƒã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: streamutil.c:216 +#, c-format +msgid "%s: could not determine server setting for integer_datetimes\n" +msgstr "%s: integer_datetimesã®ã‚µãƒ¼ãƒè¨­å®šã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: streamutil.c:225 +#, c-format +msgid "%s: integer_datetimes compile flag does not match server\n" +msgstr "%s: integer_datetimesコンパイルフラグãŒã‚µãƒ¼ãƒã¨ä¸€è‡´ã—ã¾ã›ã‚“\n" + +#: streamutil.c:376 +#, c-format +msgid "" +"%s: could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: レプリケーションスロット\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å—信値:%d行ã¨%d" +"ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã€æœŸå¾…値:%d行ã¨%dフィールドã§ã—ãŸ\n" + +#: streamutil.c:421 +#, c-format +msgid "" +"%s: could not drop replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: レプリケーションスロット\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚å—信値 %d行ã¨%d" +"ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã€æœŸå¾…値:%d行ã¨%dフィールドã§ã—ãŸ\n" + +#: walmethods.c:435 walmethods.c:904 +msgid "could not compress data" +msgstr "データを圧縮ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: walmethods.c:459 +msgid "could not reset compression stream" +msgstr "圧縮ストリームをリセットã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: walmethods.c:560 +msgid "could not initialize compression library" +msgstr "åœ§ç¸®ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: walmethods.c:572 +msgid "implementation error: tar files can't have more than one open file" +msgstr "実装エラー:tar ファイルãŒè¤‡æ•°ã®ã‚ªãƒ¼ãƒ—ンã•れãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’ä¿æŒã§ãã¾ã›ã‚“" + +#: walmethods.c:586 +msgid "could not create tar header" +msgstr "tar ヘッダを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 +msgid "could not change compression parameters" +msgstr "圧縮用パラメーターを変更ã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: walmethods.c:720 +msgid "unlink not supported with compression" +msgstr "圧縮モードã«ãŠã‘ã‚‹ unlink ã¯ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" + +#: walmethods.c:920 +msgid "could not close compression stream" +msgstr "圧縮ストリームをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ" diff --git a/src/bin/pg_basebackup/po/ko.po b/src/bin/pg_basebackup/po/ko.po index 485703923d1..c0fe0c96fb1 100644 --- a/src/bin/pg_basebackup/po/ko.po +++ b/src/bin/pg_basebackup/po/ko.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_basebackup (PostgreSQL) 9.5\n" +"Project-Id-Version: pg_basebackup (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2015-12-25 19:20+0900\n" -"PO-Revision-Date: 2015-12-25 23:10+0900\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:25+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -28,17 +28,105 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 복제할 수 ì—†ìŒ(ë‚´ë¶€ 오류)\n" -#: pg_basebackup.c:154 +#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#: pg_receivewal.c:252 pg_recvlogical.c:353 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: \"%s\" íŒŒì¼ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:162 pg_receivewal.c:153 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:198 pg_receivewal.c:320 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 +#: receivelog.c:804 receivelog.c:1061 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ fsync í•  수 ì—†ìŒ: %s\n" + +#: ../../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" + +#: pg_basebackup.c:159 +#, c-format +msgid "%s: removing data directory \"%s\"\n" +msgstr "%s: \"%s\" 디렉터리를 지우는 중\n" + +#: pg_basebackup.c:162 +#, c-format +msgid "%s: failed to remove data directory\n" +msgstr "%s: ë°ì´í„° 디렉터리 ì‚­ì œ 실패\n" + +#: pg_basebackup.c:168 +#, c-format +msgid "%s: removing contents of data directory \"%s\"\n" +msgstr "%s: \"%s\" ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ë‚´ìš©ì„ ì§€ìš°ëŠ” 중\n" + +#: pg_basebackup.c:171 +#, c-format +msgid "%s: failed to remove contents of data directory\n" +msgstr "%s: ë°ì´í„° ë””ë ‰í„°ë¦¬ì˜ ë‚´ìš©ì„ ì§€ìš¸ 수 ì—†ìŒ\n" + +#: pg_basebackup.c:177 +#, c-format +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: \"%s\" WAL 디렉터리를 지우는 중\n" + +#: pg_basebackup.c:180 +#, c-format +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: WAL 디렉터리 ì‚­ì œ 실패\n" + +#: pg_basebackup.c:186 +#, c-format +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: \"%s\" WAL 디렉터리 ë‚´ìš©ì„ ì§€ìš°ëŠ” 중\n" + +#: pg_basebackup.c:189 +#, c-format +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: WAL ë””ë ‰í„°ë¦¬ì˜ ë‚´ìš©ì„ ì§€ìš¸ 수 ì—†ìŒ\n" + +#: pg_basebackup.c:197 +#, c-format +msgid "%s: data directory \"%s\" not removed at user's request\n" +msgstr "%s: ì‚¬ìš©ìž ìš”ì²­ìœ¼ë¡œ \"%s\" ë°ì´í„° 디렉터리를 지우지 않았ìŒ\n" + +#: pg_basebackup.c:202 +#, c-format +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: ì‚¬ìš©ìž ìš”ì²­ìœ¼ë¡œ \"%s\" WAL 디렉터리를 지우지 않았ìŒ\n" + +#: pg_basebackup.c:208 +#, c-format +msgid "%s: changes to tablespace directories will not be undone\n" +msgstr "%s: ì•„ì§ ë§ˆë¬´ë¦¬ ë˜ì§€ ì•Šì€ í…Œì´ë¸”스페ì´ìФ 디렉터리 변경함\n" + +#: pg_basebackup.c:250 #, c-format msgid "%s: directory name too long\n" msgstr "%s: 디렉터리 ì´ë¦„ì´ ë„ˆë¬´ ê¹€\n" -#: pg_basebackup.c:164 +#: pg_basebackup.c:260 #, c-format msgid "%s: multiple \"=\" signs in tablespace mapping\n" msgstr "%s: í…Œì´ë¸”스페ì´ìФ 맵핑 하는 ê³³ì—서 \"=\" 문ìžê°€ 중복 ë˜ì–´ 있ìŒ\n" -#: pg_basebackup.c:177 +#: pg_basebackup.c:273 #, c-format msgid "" "%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" @@ -46,17 +134,17 @@ msgstr "" "%s: \"%s\" 형ì‹ì˜ í…Œì´ë¸”스페ì´ìФ ë§µí•‘ì´ ìž˜ëª» ë˜ì—ˆìŒ, \"OLDDIR=NEWDIR\" 형ì‹ì´" "어야 함\n" -#: pg_basebackup.c:190 +#: pg_basebackup.c:286 #, c-format msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" msgstr "%s: í…Œì´ë¸”스페ì´ìФ 맵핑용 옛 디렉터리가 절대 경로가 아님: %s\n" -#: pg_basebackup.c:197 +#: pg_basebackup.c:293 #, c-format msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" msgstr "%s: í…Œì´ë¸”스페ì´ìФ 맵핑용 새 디렉터리가 절대 경로가 아님: %s\n" -#: pg_basebackup.c:231 +#: pg_basebackup.c:327 #, c-format msgid "" "%s takes a base backup of a running PostgreSQL server.\n" @@ -66,17 +154,17 @@ msgstr "" "다.\n" "\n" -#: pg_basebackup.c:233 pg_receivexlog.c:66 pg_recvlogical.c:69 +#: pg_basebackup.c:329 pg_receivewal.c:76 pg_recvlogical.c:77 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: pg_basebackup.c:234 pg_receivexlog.c:67 pg_recvlogical.c:70 +#: pg_basebackup.c:330 pg_receivewal.c:77 pg_recvlogical.c:78 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [옵션]...\n" -#: pg_basebackup.c:235 +#: pg_basebackup.c:331 #, c-format msgid "" "\n" @@ -85,17 +173,17 @@ msgstr "" "\n" "ì¶œë ¥ë¬¼ì„ ì œì–´ì•¼í•˜ëŠ” 옵션들:\n" -#: pg_basebackup.c:236 +#: pg_basebackup.c:332 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" msgstr " -D, --pgdata=디렉터리 ë² ì´ìФ 백업 ê²°ê³¼ë¬¼ì´ ì €ìž¥ë  ë””ë ‰í„°ë¦¬\n" -#: pg_basebackup.c:237 +#: pg_basebackup.c:333 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" msgstr " -F, --format=p|t 출력 í˜•ì‹ (plain (초기값), tar)\n" -#: pg_basebackup.c:238 +#: pg_basebackup.c:334 #, c-format msgid "" " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" @@ -105,16 +193,27 @@ msgstr "" " (단위는 kB/s, ë˜ëŠ” ìˆ«ìž ë’¤ì— \"k\" ë˜ëŠ” \"M\" 단위 " "ë¬¸ìž ì§€ì • 가능)\n" -#: pg_basebackup.c:240 +#: pg_basebackup.c:336 #, c-format msgid "" " -R, --write-recovery-conf\n" -" write recovery.conf after backup\n" +" write recovery.conf for replication\n" msgstr "" " -R, --write-recovery-conf\n" -" ë°±ì—…ì´ ë나고 recovery.conf 파ì¼ë„ 만듬\n" +" 복제용 recovery.conf 파ì¼ë„ 만듬\n" + +#: pg_basebackup.c:338 pg_receivewal.c:84 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=슬롯ì´ë¦„ 지정한 복제 ìŠ¬ë¡¯ì„ ì‚¬ìš©í•¨\n" + +#: pg_basebackup.c:339 +#, c-format +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot 임시 복제 슬롯 만들지 않ìŒ\n" -#: pg_basebackup.c:242 +#: pg_basebackup.c:340 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -123,39 +222,32 @@ msgstr "" " -T, --tablespace-mapping=옛DIR=새DIR\n" " í…Œì´ë¸”스페ì´ìФ 디렉터리 새 맵핑\n" -#: pg_basebackup.c:244 +#: pg_basebackup.c:342 #, c-format msgid "" -" -x, --xlog include required WAL files in backup (fetch mode)\n" -msgstr "" -" -x, --xlog 백업 ì•ˆì— í•„ìš”í•œ WAL 파ì¼ë„ í¬í•¨í•¨ (fetch mode)\n" - -#: pg_basebackup.c:245 -#, c-format -msgid "" -" -X, --xlog-method=fetch|stream\n" +" -X, --wal-method=none|fetch|stream\n" " include required WAL files with specified method\n" msgstr "" -" -X, --xlog-method=fetch|stream\n" +" -X, --wal-method=none|fetch|stream\n" " 필요한 WAL 파ì¼ì„ 백업하는 방법\n" -#: pg_basebackup.c:247 +#: pg_basebackup.c:344 #, c-format -msgid " --xlogdir=XLOGDIR location for the transaction log directory\n" -msgstr " --xlogdir=XLOGDIR 트랜잭션 로그 디렉터리 지정\n" +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR 트랜잭션 로그 디렉터리 지정\n" -#: pg_basebackup.c:248 +#: pg_basebackup.c:345 #, c-format msgid " -z, --gzip compress tar output\n" msgstr " -z, --gzip tar ì¶œë ¥ë¬¼ì„ ì••ì¶•\n" -#: pg_basebackup.c:249 +#: pg_basebackup.c:346 #, c-format msgid "" " -Z, --compress=0-9 compress tar output with given compression level\n" msgstr " -Z, --compress=0-9 ì••ì¶•ëœ tar 파ì¼ì˜ ì••ì¶• 수위 지정\n" -#: pg_basebackup.c:250 +#: pg_basebackup.c:347 #, c-format msgid "" "\n" @@ -164,7 +256,7 @@ msgstr "" "\n" "ì¼ë°˜ 옵션들:\n" -#: pg_basebackup.c:251 +#: pg_basebackup.c:348 #, c-format msgid "" " -c, --checkpoint=fast|spread\n" @@ -173,32 +265,44 @@ msgstr "" " -c, --checkpoint=fast|spread\n" " ì²´í¬í¬ì¸íЏ 방법\n" -#: pg_basebackup.c:253 +#: pg_basebackup.c:350 #, c-format msgid " -l, --label=LABEL set backup label\n" msgstr " -l, --label=ë¼ë²¨ 백업 ë¼ë²¨ 지정\n" -#: pg_basebackup.c:254 +#: pg_basebackup.c:351 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean 오류 ë°œìƒ ì‹œ 정리하지 않ìŒ\n" + +#: pg_basebackup.c:352 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr " -N, --no-sync ë””ìŠ¤í¬ ì“°ê¸° ë’¤ sync 작업 ìƒëžµ\n" + +#: pg_basebackup.c:353 #, c-format msgid " -P, --progress show progress information\n" msgstr " -P, --progress ì§„í–‰ 과정 보여줌\n" -#: pg_basebackup.c:255 pg_receivexlog.c:76 pg_recvlogical.c:89 +#: pg_basebackup.c:354 pg_receivewal.c:86 pg_recvlogical.c:98 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose ìžì„¸í•œ 작업 메시지 보여줌\n" -#: pg_basebackup.c:256 pg_receivexlog.c:77 pg_recvlogical.c:90 +#: pg_basebackup.c:355 pg_receivewal.c:87 pg_recvlogical.c:99 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" -#: pg_basebackup.c:257 pg_receivexlog.c:78 pg_recvlogical.c:91 +#: pg_basebackup.c:356 pg_receivewal.c:89 pg_recvlogical.c:100 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: pg_basebackup.c:258 pg_receivexlog.c:79 pg_recvlogical.c:92 +#: pg_basebackup.c:357 pg_receivewal.c:90 pg_recvlogical.c:101 #, c-format msgid "" "\n" @@ -207,22 +311,22 @@ msgstr "" "\n" "ì—°ê²° 옵션들:\n" -#: pg_basebackup.c:259 pg_receivexlog.c:80 +#: pg_basebackup.c:358 pg_receivewal.c:91 #, c-format msgid " -d, --dbname=CONNSTR connection string\n" msgstr " -d, --dbname=ì ‘ì†ë¬¸ìžì—´ 서버 ì ‘ì† ë¬¸ìžì—´\n" -#: pg_basebackup.c:260 pg_receivexlog.c:81 pg_recvlogical.c:94 +#: pg_basebackup.c:359 pg_receivewal.c:92 pg_recvlogical.c:103 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=호스트ì´ë¦„ ì ‘ì†í•  ë°ì´í„°ë² ì´ìФ 서버나 소켓 디렉터리\n" -#: pg_basebackup.c:261 pg_receivexlog.c:82 pg_recvlogical.c:95 +#: pg_basebackup.c:360 pg_receivewal.c:93 pg_recvlogical.c:104 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=í¬íЏ ë°ì´í„°ë² ì´ìФ 서버 í¬íЏ 번호\n" -#: pg_basebackup.c:262 +#: pg_basebackup.c:361 #, c-format msgid "" " -s, --status-interval=INTERVAL\n" @@ -232,17 +336,17 @@ msgstr "" " -s, --status-interval=ì´ˆ\n" " ì´ˆ 단위 매번 서버로 ìƒíƒœ íŒ¨í‚·ì„ ë³´ëƒ„\n" -#: pg_basebackup.c:264 pg_receivexlog.c:83 pg_recvlogical.c:96 +#: pg_basebackup.c:363 pg_receivewal.c:94 pg_recvlogical.c:105 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=ì‚¬ìš©ìž ì ‘ì†í•  특정 ë°ì´í„°ë² ì´ìФ 사용ìž\n" -#: pg_basebackup.c:265 pg_receivexlog.c:84 pg_recvlogical.c:97 +#: pg_basebackup.c:364 pg_receivewal.c:95 pg_recvlogical.c:106 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password 비밀번호 물어 ë³´ì§€ 않ìŒ\n" -#: pg_basebackup.c:266 pg_receivexlog.c:85 pg_recvlogical.c:98 +#: pg_basebackup.c:365 pg_receivewal.c:96 pg_recvlogical.c:107 #, c-format msgid "" " -W, --password force password prompt (should happen " @@ -250,7 +354,7 @@ msgid "" msgstr "" " -W, --password í•­ìƒ ë¹„ë°€ë²ˆí˜¸ 프롬프트 ë³´ìž„ (ìžë™ìœ¼ë¡œ íŒë‹¨ 함)\n" -#: pg_basebackup.c:267 pg_receivexlog.c:89 pg_recvlogical.c:99 +#: pg_basebackup.c:366 pg_receivewal.c:100 pg_recvlogical.c:108 #, c-format msgid "" "\n" @@ -259,195 +363,212 @@ msgstr "" "\n" "오류보고: .\n" -#: pg_basebackup.c:310 +#: pg_basebackup.c:409 #, c-format msgid "%s: could not read from ready pipe: %s\n" msgstr "%s: ì¤€ë¹„ëœ íŒŒì´í”„로부터 ì½ê¸° 실패: %s\n" -#: pg_basebackup.c:318 pg_basebackup.c:411 pg_basebackup.c:1869 -#: streamutil.c:285 +#: pg_basebackup.c:417 pg_basebackup.c:552 pg_basebackup.c:2005 +#: streamutil.c:286 #, c-format -msgid "%s: could not parse transaction log location \"%s\"\n" +msgid "%s: could not parse write-ahead log location \"%s\"\n" msgstr "%s: 트랜잭션 로그 위치 \"%s\" ë¶„ì„ ì‹¤íŒ¨\n" -#: pg_basebackup.c:424 +#: pg_basebackup.c:515 pg_receivewal.c:428 +#, c-format +msgid "%s: could not finish writing WAL files: %s\n" +msgstr "%s: WAL íŒŒì¼ ì“°ê¸° 마무리 실패: %s\n" + +#: pg_basebackup.c:565 #, c-format msgid "%s: could not create pipe for background process: %s\n" msgstr "%s: 백그ë¼ìš´ë“œ 프로세스를 위한 파ì´í”„ 만들기 실패: %s\n" -#: pg_basebackup.c:449 pg_basebackup.c:504 pg_basebackup.c:1252 +#: pg_basebackup.c:605 pg_basebackup.c:661 pg_basebackup.c:1423 #, c-format msgid "%s: could not create directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리 만들 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:467 +#: pg_basebackup.c:624 #, c-format msgid "%s: could not create background process: %s\n" msgstr "%s: 백그ë¼ìš´ë“œ 프로세스 만들기 실패: %s\n" -#: pg_basebackup.c:479 +#: pg_basebackup.c:636 #, c-format msgid "%s: could not create background thread: %s\n" msgstr "%s: 백그ë¼ìš´ë“œ 스래드 만들기 실패: %s\n" -#: pg_basebackup.c:523 +#: pg_basebackup.c:684 #, c-format msgid "%s: directory \"%s\" exists but is not empty\n" msgstr "%s: \"%s\" 디렉터리가 있지만 비어 있지 않ìŒ\n" -#: pg_basebackup.c:531 +#: pg_basebackup.c:692 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:593 +#: pg_basebackup.c:754 #, c-format msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" msgstr[0] "%*s/%s kB (100%%), %d/%d í…Œì´ë¸”스페ì´ìФ %*s" -#: pg_basebackup.c:605 +#: pg_basebackup.c:766 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" msgstr[0] "%*s/%s kB (%d%%), %d/%d í…Œì´ë¸”스페ì´ìФ (%s%-*.*s)" -#: pg_basebackup.c:621 +#: pg_basebackup.c:782 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" msgstr[0] "%*s/%s kB (%d%%), %d/%d í…Œì´ë¸”스페ì´ìФ" -#: pg_basebackup.c:643 +#: pg_basebackup.c:804 #, c-format msgid "%s: transfer rate \"%s\" is not a valid value\n" msgstr "%s: \"%s\" 전송 ì†ë„는 ìž˜ëª»ëœ ê°’ìž„\n" -#: pg_basebackup.c:650 +#: pg_basebackup.c:811 #, c-format msgid "%s: invalid transfer rate \"%s\": %s\n" msgstr "%s: ìž˜ëª»ëœ ì „ì†¡ ì†ë„ \"%s\": %s\n" -#: pg_basebackup.c:660 +#: pg_basebackup.c:821 #, c-format msgid "%s: transfer rate must be greater than zero\n" msgstr "%s: 전송 ì†ë„는 0보다 커야 함\n" -#: pg_basebackup.c:694 +#: pg_basebackup.c:855 #, c-format msgid "%s: invalid --max-rate unit: \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ --max-rate 단위: \"%s\"\n" -#: pg_basebackup.c:703 +#: pg_basebackup.c:864 #, c-format msgid "%s: transfer rate \"%s\" exceeds integer range\n" msgstr "%s: \"%s\" 전송 ì†ë„는 정수형 범위가 아님\n" -#: pg_basebackup.c:715 +#: pg_basebackup.c:876 #, c-format msgid "%s: transfer rate \"%s\" is out of range\n" msgstr "%s: \"%s\" 전송 ì†ë„는 범위 초과\n" -#: pg_basebackup.c:739 +#: pg_basebackup.c:900 #, c-format msgid "%s: could not write to compressed file \"%s\": %s\n" msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ì“°ê¸° 실패: %s\n" -#: pg_basebackup.c:749 pg_basebackup.c:1346 pg_basebackup.c:1564 +#: pg_basebackup.c:910 pg_basebackup.c:1517 pg_basebackup.c:1683 #, c-format msgid "%s: could not write to file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì“°ê¸° 실패: %s\n" -#: pg_basebackup.c:804 pg_basebackup.c:825 pg_basebackup.c:853 +#: pg_basebackup.c:969 pg_basebackup.c:990 pg_basebackup.c:1018 #, c-format msgid "%s: could not set compression level %d: %s\n" msgstr "%s: ìž˜ëª»ëœ ì••ì¶• 수위 %d: %s\n" -#: pg_basebackup.c:874 +#: pg_basebackup.c:1039 #, c-format msgid "%s: could not create compressed file \"%s\": %s\n" msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ë§Œë“¤ê¸° 실패: %s\n" -#: pg_basebackup.c:885 pg_basebackup.c:1306 pg_basebackup.c:1557 +#: pg_basebackup.c:1050 pg_basebackup.c:1477 pg_basebackup.c:1676 #, c-format msgid "%s: could not create file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ë§Œë“¤ê¸° 실패: %s\n" -#: pg_basebackup.c:897 pg_basebackup.c:1161 +#: pg_basebackup.c:1062 pg_basebackup.c:1330 #, c-format msgid "%s: could not get COPY data stream: %s" msgstr "%s: COPY ë°ì´í„° ìŠ¤íŠ¸ë¦¼ì„ ì‚¬ìš©í•  수 ì—†ìŒ: %s" -#: pg_basebackup.c:954 +#: pg_basebackup.c:1119 #, c-format msgid "%s: could not close compressed file \"%s\": %s\n" msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ë‹«ê¸° 실패: %s\n" -#: pg_basebackup.c:967 pg_recvlogical.c:569 receivelog.c:213 receivelog.c:362 -#: receivelog.c:754 +#: pg_basebackup.c:1132 pg_recvlogical.c:631 receivelog.c:223 receivelog.c:308 +#: receivelog.c:714 #, c-format msgid "%s: could not close file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ë‹«ê¸° 실패: %s\n" -#: pg_basebackup.c:978 pg_basebackup.c:1190 pg_recvlogical.c:435 -#: receivelog.c:1044 +#: pg_basebackup.c:1143 pg_basebackup.c:1359 pg_recvlogical.c:453 +#: receivelog.c:1009 #, c-format msgid "%s: could not read COPY data: %s" msgstr "%s: COPY ìžë£Œë¥¼ ì½ì„ 수 ì—†ìŒ: %s" -#: pg_basebackup.c:1204 +#: pg_basebackup.c:1373 #, c-format msgid "%s: invalid tar block header size: %d\n" msgstr "%s: ìž˜ëª»ëœ ë¸”ëŸ­ í—¤ë” í¬ê¸°: %d\n" -#: pg_basebackup.c:1260 +#: pg_basebackup.c:1431 #, c-format msgid "%s: could not set permissions on directory \"%s\": %s\n" msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì˜ ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•  수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1284 +#: pg_basebackup.c:1455 #, c-format msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì„ \"%s\" 심볼릭 ë§í¬ë¡œ 만들 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1293 +#: pg_basebackup.c:1464 #, c-format msgid "%s: unrecognized link indicator \"%c\"\n" msgstr "%s: 알 수 없는 ë§í¬ ì§€ì‹œìž \"%c\"\n" -#: pg_basebackup.c:1313 +#: pg_basebackup.c:1484 #, c-format msgid "%s: could not set permissions on file \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì˜ ì ‘ê·¼ê¶Œí•œì„ ì§€ì •í•  수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1372 +#: pg_basebackup.c:1543 #, c-format msgid "%s: COPY stream ended before last file was finished\n" msgstr "%s: 마지막 파ì¼ì„ ë내기 ì „ì— COPY ìŠ¤íŠ¸ë¦¼ì´ ë났ìŒ\n" -#: pg_basebackup.c:1458 pg_basebackup.c:1478 pg_basebackup.c:1485 -#: pg_basebackup.c:1532 +#: pg_basebackup.c:1571 pg_basebackup.c:1591 pg_basebackup.c:1598 +#: pg_basebackup.c:1651 #, c-format msgid "%s: out of memory\n" msgstr "%s: 메모리 부족\n" -#: pg_basebackup.c:1609 +#: pg_basebackup.c:1724 #, c-format msgid "%s: incompatible server version %s\n" msgstr "%s: 호환하지 않는 서버 버전 %s\n" -#: pg_basebackup.c:1656 pg_recvlogical.c:261 receivelog.c:549 receivelog.c:600 -#: receivelog.c:641 streamutil.c:255 streamutil.c:353 streamutil.c:399 +#: pg_basebackup.c:1739 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming\n" +msgstr "" +"힌트: 트랜잭션 로그 스트리ë°ì„ 사용하지 않으려면 -X none ë˜ëŠ” -X fetch 옵션" +"ì„ ì‚¬ìš©í•˜ì„¸ìš”.\n" + +#: pg_basebackup.c:1765 +#, c-format +msgid "%s: initiating base backup, waiting for checkpoint to complete\n" +msgstr "%s: ë² ì´ìФ ë°±ì—…ì„ ì´ˆê¸°í™” 중, ì²´í¬í¬ì¸íЏ 완료를 기다리는 중\n" + +#: pg_basebackup.c:1783 pg_recvlogical.c:270 receivelog.c:492 receivelog.c:563 +#: receivelog.c:603 streamutil.c:256 streamutil.c:364 streamutil.c:410 #, c-format msgid "%s: could not send replication command \"%s\": %s" msgstr "%s: \"%s\" 복제 ëª…ë ¹ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s" -#: pg_basebackup.c:1667 +#: pg_basebackup.c:1794 #, c-format msgid "%s: could not initiate base backup: %s" msgstr "%s: ë² ì´ìФ ë°±ì—…ì„ ì´ˆê¸°í™” í•  수 ì—†ìŒ: %s" -#: pg_basebackup.c:1674 +#: pg_basebackup.c:1801 #, c-format msgid "" "%s: server returned unexpected response to BASE_BACKUP command; got %d rows " @@ -456,196 +577,217 @@ msgstr "" "%s: 서버가 BASE_BACKUP ëª…ë ¹ì— ëŒ€í•´ì„œ ìž˜ëª»ëœ ì‘ë‹µì„ í–ˆìŠµë‹ˆë‹¤; ì‘답값: %d 로" "ìš°, %d 필드, (기대값: %d 로우, %d 필드)\n" -#: pg_basebackup.c:1694 +#: pg_basebackup.c:1809 #, c-format -msgid "transaction log start point: %s on timeline %u\n" -msgstr "트랙잭션 로그 시작 위치: %s, 타임ë¼ì¸: %u\n" +msgid "%s: checkpoint completed\n" +msgstr "%s: ì²´í¬í¬ì¸íЏ 완료\n" -#: pg_basebackup.c:1703 +#: pg_basebackup.c:1824 +#, c-format +msgid "%s: write-ahead log start point: %s on timeline %u\n" +msgstr "%s: 트랙잭션 로그 시작 위치: %s, 타임ë¼ì¸: %u\n" + +#: pg_basebackup.c:1833 #, c-format msgid "%s: could not get backup header: %s" msgstr "%s: 백업 í—¤ë”를 구할 수 ì—†ìŒ: %s" -#: pg_basebackup.c:1709 +#: pg_basebackup.c:1839 #, c-format msgid "%s: no data returned from server\n" msgstr "%s: 서버가 아무런 ìžë£Œë„ 주지 않았ìŒ\n" -#: pg_basebackup.c:1741 +#: pg_basebackup.c:1871 #, c-format msgid "%s: can only write single tablespace to stdout, database has %d\n" msgstr "" "%s: 표준 출력으로는 í•˜ë‚˜ì˜ í…Œì´ë¸”스페ì´ìŠ¤ë§Œ 쓸 수 있ìŒ, ë°ì´í„°ë² ì´ìŠ¤ëŠ” %d ê°œ" "ì˜ í…Œì´ë¸” 스페ì´ìŠ¤ê°€ 있ìŒ\n" -#: pg_basebackup.c:1753 +#: pg_basebackup.c:1883 #, c-format msgid "%s: starting background WAL receiver\n" msgstr "%s: 백그ë¼ìš´ë“œ WAL ìˆ˜ì‹ ìž ì‹œìž‘ 중\n" -#: pg_basebackup.c:1784 +#: pg_basebackup.c:1914 #, c-format -msgid "%s: could not get transaction log end position from server: %s" +msgid "%s: could not get write-ahead log end position from server: %s" msgstr "%s: 서버ì—서 트랜잭션 로그 마지막 위치를 구할 수 ì—†ìŒ: %s" -#: pg_basebackup.c:1791 +#: pg_basebackup.c:1921 #, c-format -msgid "%s: no transaction log end position returned from server\n" +msgid "%s: no write-ahead log end position returned from server\n" msgstr "%s: 서버ì—서 트랜잭션 로그 마지막 위치가 수신 ë˜ì§€ 않았ìŒ\n" -#: pg_basebackup.c:1803 +#: pg_basebackup.c:1927 +#, c-format +msgid "%s: write-ahead log end point: %s\n" +msgstr "%s: 트랜잭션 로그 마지막 위치: %s\n" + +#: pg_basebackup.c:1933 #, c-format msgid "%s: final receive failed: %s" msgstr "%s: 수신 작업 마무리 실패: %s" -#: pg_basebackup.c:1821 +#: pg_basebackup.c:1957 #, c-format msgid "%s: waiting for background process to finish streaming ...\n" msgstr "%s: 스트리ë°ì„ ë내기 위해서 백그ë¼ìš´ë“œ 프로세스를 기다리는 중 ...\n" -#: pg_basebackup.c:1827 +#: pg_basebackup.c:1963 #, c-format msgid "%s: could not send command to background pipe: %s\n" msgstr "%s: 백그ë¼ìš´ë“œ 파ì´í”„로 ëª…ë ¹ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1836 +#: pg_basebackup.c:1972 #, c-format msgid "%s: could not wait for child process: %s\n" msgstr "%s: 하위 프로세스를 기다릴 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1842 +#: pg_basebackup.c:1978 #, c-format msgid "%s: child %d died, expected %d\n" msgstr "%s: %d ê°œì˜ í•˜ìœ„ 프로세스가 종료ë¨, 기대값 %d\n" -#: pg_basebackup.c:1848 +#: pg_basebackup.c:1984 #, c-format msgid "%s: child process did not exit normally\n" msgstr "%s: 하위 프로세스가 ì •ìƒ ì¢…ë£Œë˜ì§€ 못했ìŒ\n" -#: pg_basebackup.c:1854 +#: pg_basebackup.c:1990 #, c-format msgid "%s: child process exited with error %d\n" msgstr "%s: 하위 프로세스가 ë¹„ì •ìƒ ì¢…ë£Œë¨: 오류 코드 %d\n" -#: pg_basebackup.c:1881 +#: pg_basebackup.c:2017 #, c-format msgid "%s: could not wait for child thread: %s\n" msgstr "%s: 하위 스레드를 기다릴 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:1888 +#: pg_basebackup.c:2024 #, c-format msgid "%s: could not get child thread exit status: %s\n" msgstr "%s: 하위 스레드 종료 ìƒíƒœê°€ ì •ìƒì ì´ì§€ 않ìŒ: %s\n" -#: pg_basebackup.c:1894 +#: pg_basebackup.c:2030 #, c-format msgid "%s: child thread exited with error %u\n" msgstr "%s: 하위 스레드가 ë¹„ì •ìƒ ì¢…ë£Œë¨: 오류 코드 %u\n" -#: pg_basebackup.c:1983 +#: pg_basebackup.c:2068 +#, c-format +msgid "%s: base backup completed\n" +msgstr "%s: ë² ì´ìФ 백업 완료\n" + +#: pg_basebackup.c:2145 #, c-format msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" msgstr "" "%s: \"%s\" ê°’ì€ ìž˜ëª»ëœ ì¶œë ¥ 형ì‹, \"plain\" ë˜ëŠ” \"tar\" ë§Œ 사용 가능\n" -#: pg_basebackup.c:2001 pg_basebackup.c:2013 -#, c-format -msgid "%s: cannot specify both --xlog and --xlog-method\n" -msgstr "%s: --xlog 옵션과 --xlog-method ì˜µì…˜ì€ í•¨ê»˜ 쓸 수 ì—†ìŒ\n" - -#: pg_basebackup.c:2028 +#: pg_basebackup.c:2190 #, c-format msgid "" -"%s: invalid xlog-method option \"%s\", must be \"fetch\" or \"stream\"\n" +"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or " +"\"none\"\n" msgstr "" -"%s: \"%s\" ê°’ì€ ìž˜ëª»ëœ xlog-method 옵션값, \"fetch\" ë˜ëŠ” \"stream\" ë§Œ 사용 " -"가능\n" +"%s: \"%s\" ê°’ì€ ìž˜ëª»ëœ wal-method 옵션값, \"fetch\", \"stream\" ë˜ëŠ” \"none" +"\"ë§Œ 사용 가능\n" -#: pg_basebackup.c:2050 +#: pg_basebackup.c:2218 pg_receivewal.c:556 #, c-format msgid "%s: invalid compression level \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ì••ì¶• 수위 \"%s\"\n" -#: pg_basebackup.c:2062 +#: pg_basebackup.c:2230 #, c-format msgid "" "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" msgstr "" "%s: ìž˜ëª»ëœ ì²´í¬í¬ì¸íЏ 옵션값 \"%s\", \"fast\" ë˜ëŠ” \"spread\"ë§Œ 사용 가능\n" -#: pg_basebackup.c:2089 pg_receivexlog.c:439 pg_recvlogical.c:752 +#: pg_basebackup.c:2257 pg_receivewal.c:538 pg_recvlogical.c:825 #, c-format msgid "%s: invalid status interval \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ìƒíƒœê°’ 전단 간격: \"%s\"\n" -#: pg_basebackup.c:2105 pg_basebackup.c:2119 pg_basebackup.c:2130 -#: pg_basebackup.c:2143 pg_basebackup.c:2153 pg_basebackup.c:2165 -#: pg_basebackup.c:2176 pg_receivexlog.c:471 pg_receivexlog.c:485 -#: pg_receivexlog.c:493 pg_receivexlog.c:503 pg_receivexlog.c:514 -#: pg_recvlogical.c:779 pg_recvlogical.c:793 pg_recvlogical.c:804 -#: pg_recvlogical.c:812 pg_recvlogical.c:820 pg_recvlogical.c:828 -#: pg_recvlogical.c:836 pg_recvlogical.c:844 +#: pg_basebackup.c:2273 pg_basebackup.c:2287 pg_basebackup.c:2298 +#: pg_basebackup.c:2311 pg_basebackup.c:2321 pg_basebackup.c:2331 +#: pg_basebackup.c:2343 pg_basebackup.c:2357 pg_basebackup.c:2368 +#: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 +#: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 +#: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 +#: pg_recvlogical.c:893 pg_recvlogical.c:901 pg_recvlogical.c:909 +#: pg_recvlogical.c:917 pg_recvlogical.c:927 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "ìžì œí•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보십시오.\n" -#: pg_basebackup.c:2117 pg_receivexlog.c:483 pg_recvlogical.c:791 +#: pg_basebackup.c:2285 pg_receivewal.c:591 pg_recvlogical.c:864 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" -#: pg_basebackup.c:2129 pg_receivexlog.c:513 +#: pg_basebackup.c:2297 pg_receivewal.c:621 #, c-format msgid "%s: no target directory specified\n" msgstr "%s: ëŒ€ìƒ ë””ë ‰í„°ë¦¬ë¥¼ 지정하지 않ìŒ\n" -#: pg_basebackup.c:2141 +#: pg_basebackup.c:2309 #, c-format msgid "%s: only tar mode backups can be compressed\n" msgstr "%s: tar 형ì‹ë§Œ ì••ì¶•ì„ ì‚¬ìš©í•  수 있ìŒ\n" -#: pg_basebackup.c:2151 +#: pg_basebackup.c:2319 #, c-format -msgid "%s: WAL streaming can only be used in plain mode\n" -msgstr "%s: WAL 스트리ë°ì€ plain 모드ì—서만 사용할 수 있ìŒ\n" +msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" +msgstr "%s: tar ë°©ì‹ì—서 stdout으로 트랜잭션 로그 ìŠ¤íŠ¸ë¦¬ë° ë¶ˆê°€\n" -#: pg_basebackup.c:2163 +#: pg_basebackup.c:2329 #, c-format -msgid "" -"%s: transaction log directory location can only be specified in plain mode\n" +msgid "%s: replication slots can only be used with WAL streaming\n" +msgstr "%s: 복제 ìŠ¬ë¡¯ì€ WAL ìŠ¤íŠ¸ë¦¬ë° ë°©ì‹ì—서만 사용할 수 있ìŒ\n" + +#: pg_basebackup.c:2341 +#, c-format +msgid "%s: --no-slot cannot be used with slot name\n" +msgstr "%s: 슬롯 ì´ë¦„ì„ ì§€ì •í•œ 경우 --no-slot ì˜µì…˜ì„ ì‚¬ìš©í•  수 ì—†ìŒ\n" + +#: pg_basebackup.c:2355 +#, c-format +msgid "%s: WAL directory location can only be specified in plain mode\n" msgstr "%s: 트랜잭션 로그 디렉터리 위치는 plain 모드ì—서만 사용할 수 있ìŒ\n" -#: pg_basebackup.c:2174 +#: pg_basebackup.c:2366 #, c-format -msgid "%s: transaction log directory location must be an absolute path\n" +msgid "%s: WAL directory location must be an absolute path\n" msgstr "%s: 트랜잭션 로그 디렉터리 위치는 절대 경로여야 함\n" -#: pg_basebackup.c:2186 +#: pg_basebackup.c:2378 pg_receivewal.c:631 #, c-format msgid "%s: this build does not support compression\n" msgstr "%s: ì´ ë²„ì „ì€ ì••ì¶• 하는 ê¸°ëŠ¥ì„ í¬í•¨ 하지 않고 빌드 ë˜ì—ˆìŠµë‹ˆë‹¤.\n" -#: pg_basebackup.c:2213 +#: pg_basebackup.c:2418 #, c-format msgid "%s: could not create symbolic link \"%s\": %s\n" msgstr "%s: \"%s\" 심벌릭 ë§í¬ë¥¼ 만들 수 ì—†ìŒ: %s\n" -#: pg_basebackup.c:2218 +#: pg_basebackup.c:2423 #, c-format msgid "%s: symlinks are not supported on this platform\n" msgstr "%s: ì´ ìš´ì˜ì²´ì œì—서는 심볼릭 ë§í¬ ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: pg_receivexlog.c:64 +#: pg_receivewal.c:74 #, c-format msgid "" -"%s receives PostgreSQL streaming transaction logs.\n" +"%s receives PostgreSQL streaming write-ahead logs.\n" "\n" msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ìŠ¤íŠ¸ë¦¬ë° íŠ¸ëžœìž­ì…˜ 로그를 수신하는 ë„구입니다.\n" "\n" -#: pg_receivexlog.c:68 pg_recvlogical.c:75 +#: pg_receivewal.c:78 pg_recvlogical.c:83 #, c-format msgid "" "\n" @@ -654,14 +796,14 @@ msgstr "" "\n" "옵션들:\n" -#: pg_receivexlog.c:69 +#: pg_receivewal.c:79 #, c-format msgid "" -" -D, --directory=DIR receive transaction log files into this directory\n" +" -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr "" " -D, --directory=DIR 지정한 디렉터리로 트랜잭션 로그 파ì¼ì„ 백업함\n" -#: pg_receivexlog.c:70 pg_recvlogical.c:79 +#: pg_receivewal.c:80 pg_recvlogical.c:88 #, c-format msgid "" " --if-not-exists do not error if slot already exists when creating a " @@ -669,12 +811,12 @@ msgid "" msgstr "" " --if-not-exists ìŠ¬ë¡¯ì„ ìƒˆë¡œ 만들 때 ì´ë¯¸ ìžˆì–´ë„ ì˜¤ë¥˜ ë‚´ì§€ 않ìŒ\n" -#: pg_receivexlog.c:71 pg_recvlogical.c:81 +#: pg_receivewal.c:81 pg_recvlogical.c:90 #, c-format msgid " -n, --no-loop do not loop on connection lost\n" msgstr " -n, --no-loop ì ‘ì†ì´ ëŠê²¼ì„ 때 재연결 하지 않ìŒ\n" -#: pg_receivexlog.c:72 pg_recvlogical.c:86 +#: pg_receivewal.c:82 pg_recvlogical.c:95 #, c-format msgid "" " -s, --status-interval=SECS\n" @@ -685,18 +827,18 @@ msgstr "" " 지정한 ì´ˆ 간격으로 서버로 ìƒíƒœ íŒ¨í‚·ì„ ë³´ëƒ„ (초기값: " "%d)\n" -#: pg_receivexlog.c:74 -#, c-format -msgid " -S, --slot=SLOTNAME replication slot to use\n" -msgstr " -S, --slot=슬롯ì´ë¦„ 지정한 복제 ìŠ¬ë¡¯ì„ ì‚¬ìš©í•¨\n" - -#: pg_receivexlog.c:75 +#: pg_receivewal.c:85 #, c-format msgid "" -" --synchronous flush transaction log immediately after writing\n" +" --synchronous flush write-ahead log immediately after writing\n" msgstr " --synchronous 쓰기 작업 후 즉시 트랜잭션 로그를 플러시 함\n" -#: pg_receivexlog.c:86 +#: pg_receivewal.c:88 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 ì••ì¶•ëœ ë¡œê·¸ 파ì¼ì˜ ì••ì¶• 수위 지정\n" + +#: pg_receivewal.c:97 #, c-format msgid "" "\n" @@ -705,7 +847,7 @@ msgstr "" "\n" "추가 기능:\n" -#: pg_receivexlog.c:87 pg_recvlogical.c:72 +#: pg_receivewal.c:98 pg_recvlogical.c:80 #, c-format msgid "" " --create-slot create a new replication slot (for the slot's name " @@ -714,7 +856,7 @@ msgstr "" " --create-slot 새 복제 ìŠ¬ë¡¯ì„ ë§Œë“¬ (--slot 옵션ì—서 슬롯 ì´ë¦„ ì§€" "ì •)\n" -#: pg_receivexlog.c:88 pg_recvlogical.c:73 +#: pg_receivewal.c:99 pg_recvlogical.c:81 #, c-format msgid "" " --drop-slot drop the replication slot (for the slot's name see " @@ -722,68 +864,75 @@ msgid "" msgstr "" " --drop-slot 복제 슬롯 ì‚­ì œ (--slot 옵션ì—서 슬롯 ì´ë¦„ 지정)\n" -#: pg_receivexlog.c:100 +#: pg_receivewal.c:111 #, c-format msgid "%s: finished segment at %X/%X (timeline %u)\n" msgstr "%s: ë§ˆë¬´ë¦¬ëœ ì„¸ê·¸ë¨¼íŠ¸ 위치: %X/%X (타임ë¼ì¸ %u)\n" -#: pg_receivexlog.c:113 +#: pg_receivewal.c:124 #, c-format msgid "%s: switched to timeline %u at %X/%X\n" msgstr "%s: 전환ë¨: 타임ë¼ì¸ %u, 위치 %X/%X\n" -#: pg_receivexlog.c:122 +#: pg_receivewal.c:133 #, c-format msgid "%s: received interrupt signal, exiting\n" msgstr "%s: ì¸í„°ëŸ½í„° 시그ë„ì„ ë°›ìŒ, 종료함\n" -#: pg_receivexlog.c:142 -#, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" - -#: pg_receivexlog.c:160 +#: pg_receivewal.c:171 #, c-format msgid "%s: could not close directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_receivexlog.c:218 pg_recvlogical.c:343 -#, c-format -msgid "%s: could not stat file \"%s\": %s\n" -msgstr "%s: \"%s\" íŒŒì¼ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %s\n" - -#: pg_receivexlog.c:226 +#: pg_receivewal.c:260 #, c-format msgid "%s: segment file \"%s\" has incorrect size %d, skipping\n" msgstr "%s: \"%s\" ì¡°ê° íŒŒì¼ì€ ìž˜ëª»ëœ í¬ê¸°ìž„: %d, 무시함\n" -#: pg_receivexlog.c:245 +#: pg_receivewal.c:277 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" +msgid "%s: could not open compressed file \"%s\": %s\n" +msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ì—´ê¸° 실패: %s\n" -#: pg_receivexlog.c:331 +#: pg_receivewal.c:283 +#, c-format +msgid "%s: could not seek in compressed file \"%s\": %s\n" +msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ìž‘ì—… 위치 찾기 실패: %s\n" + +#: pg_receivewal.c:289 +#, c-format +msgid "%s: could not read compressed file \"%s\": %s\n" +msgstr "%s: \"%s\" ì••ì¶• íŒŒì¼ ì½ê¸° 실패: %s\n" + +#: pg_receivewal.c:301 +#, c-format +msgid "" +"%s: compressed segment file \"%s\" has incorrect uncompressed size %d, " +"skipping\n" +msgstr "%s: \"%s\" ì••ì¶• 파ì¼ì€ ì••ì¶• í’€ì—ˆì„ ë•Œ ìž˜ëª»ëœ í¬ê¸°ìž„: %d, 무시함\n" + +#: pg_receivewal.c:407 #, c-format msgid "%s: starting log streaming at %X/%X (timeline %u)\n" msgstr "%s: 로그 ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 위치: %X/%X (타임ë¼ì¸ %u)\n" -#: pg_receivexlog.c:420 pg_recvlogical.c:699 +#: pg_receivewal.c:519 pg_recvlogical.c:762 #, c-format msgid "%s: invalid port number \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ í¬íЏ 번호 \"%s\"\n" -#: pg_receivexlog.c:492 +#: pg_receivewal.c:600 #, c-format msgid "%s: cannot use --create-slot together with --drop-slot\n" msgstr "%s: --create-slot 옵션과 --drop-slot ì˜µì…˜ì„ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" #. translator: second %s is an option name -#: pg_receivexlog.c:501 +#: pg_receivewal.c:609 #, c-format msgid "%s: %s needs a slot to be specified using --slot\n" msgstr "%s: %s ì˜µì…˜ì€ --slot ì˜µì…˜ì„ í•¨ê»˜ 사용해야 함\n" -#: pg_receivexlog.c:556 +#: pg_receivewal.c:674 #, c-format msgid "" "%s: replication connection using slot \"%s\" is unexpectedly database " @@ -791,28 +940,28 @@ msgid "" msgstr "" "%s: \"%s\" ìŠ¬ë¡¯ì„ ì´ìš©í•œ 복제 ì—°ê²°ì€ ì´ ë°ì´í„°ë² ì´ìФì—서 사용할 수 ì—†ìŒ\n" -#: pg_receivexlog.c:568 pg_recvlogical.c:884 +#: pg_receivewal.c:686 pg_recvlogical.c:967 #, c-format msgid "%s: dropping replication slot \"%s\"\n" msgstr "%s: \"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì„ ì‚­ì œ 중\n" -#: pg_receivexlog.c:581 pg_recvlogical.c:896 +#: pg_receivewal.c:699 pg_recvlogical.c:979 #, c-format msgid "%s: creating replication slot \"%s\"\n" msgstr "%s: \"%s\" ì´ë¦„ì˜ ë³µì œ ìŠ¬ë¡¯ì„ ë§Œë“œëŠ” 중\n" -#: pg_receivexlog.c:608 pg_recvlogical.c:922 +#: pg_receivewal.c:726 pg_recvlogical.c:1005 #, c-format msgid "%s: disconnected\n" msgstr "%s: ì—°ê²° ëŠê¹€\n" #. translator: check source for value for %d -#: pg_receivexlog.c:615 pg_recvlogical.c:929 +#: pg_receivewal.c:733 pg_recvlogical.c:1012 #, c-format msgid "%s: disconnected; waiting %d seconds to try again\n" msgstr "%s: ì—°ê²° ëŠê¹€; 다시 ì—°ê²° 하기 위해 %d 초를 기다리는 중\n" -#: pg_recvlogical.c:67 +#: pg_recvlogical.c:75 #, c-format msgid "" "%s controls PostgreSQL logical decoding streams.\n" @@ -821,7 +970,7 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ ë…¼ë¦¬ 디코딩 ìŠ¤íŠ¸ë¦¼ì„ ì œì–´í•˜ëŠ” ë„구입니다.\n" "\n" -#: pg_recvlogical.c:71 +#: pg_recvlogical.c:79 #, c-format msgid "" "\n" @@ -830,7 +979,7 @@ msgstr "" "\n" "ì„±ëŠ¥ì— ê´€ê³„ëœ ê¸°ëŠ¥ë“¤:\n" -#: pg_recvlogical.c:74 +#: pg_recvlogical.c:82 #, c-format msgid "" " --start start streaming in a replication slot (for the " @@ -839,12 +988,17 @@ msgstr "" " --start 복제 ìŠ¬ë¡¯ì„ ì´ìš©í•œ ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ (--slot 옵션ì—서 슬" "롯 ì´ë¦„ 지정)\n" -#: pg_recvlogical.c:76 +#: pg_recvlogical.c:84 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN 지정한 LSN까지 받고 종료함\n" + +#: pg_recvlogical.c:85 #, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" msgstr " -f, --file=íŒŒì¼ ìž‘ì—… 로그를 해당 파ì¼ì— 기ë¡, 표준 ì¶œë ¥ì€ -\n" -#: pg_recvlogical.c:77 +#: pg_recvlogical.c:86 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -855,14 +1009,14 @@ msgstr "" " 지정한 ì´ˆ 간격으로 íŒŒì¼ fsync ìž‘ì—…ì„ í•¨ (초기값: " "%d)\n" -#: pg_recvlogical.c:80 +#: pg_recvlogical.c:89 #, c-format msgid "" " -I, --startpos=LSN where in an existing slot should the streaming " "start\n" msgstr " -I, --startpos=LSN 스트리ë°ì„ 시작할 기존 슬롯 위치\n" -#: pg_recvlogical.c:82 +#: pg_recvlogical.c:91 #, c-format msgid "" " -o, --option=NAME[=VALUE]\n" @@ -873,209 +1027,205 @@ msgstr "" " 출력 플러그ì¸ì—서 사용할 ì˜µì…˜ë“¤ì˜ ì˜µì…˜ ì´ë¦„ê³¼ ê·¸ " "ê°’\n" -#: pg_recvlogical.c:85 +#: pg_recvlogical.c:94 #, c-format msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" msgstr " -P, --plugin=PLUGIN 사용할 출력 í”ŒëŸ¬ê·¸ì¸ (초기값: %s)\n" -#: pg_recvlogical.c:88 +#: pg_recvlogical.c:97 #, c-format msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" msgstr " -S, --slot=슬롯ì´ë¦„ 논리 복제 슬롯 ì´ë¦„\n" -#: pg_recvlogical.c:93 +#: pg_recvlogical.c:102 #, c-format msgid " -d, --dbname=DBNAME database to connect to\n" msgstr " -d, --dbname=디비ì´ë¦„ ì ‘ì†í•  ë°ì´í„°ë² ì´ìФ\n" -#: pg_recvlogical.c:126 +#: pg_recvlogical.c:135 #, c-format msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" msgstr "%s: 쓰기 í™•ì¸ ìœ„ì¹˜: %X/%X, 플러시 위치 %X/%X (슬롯 %s)\n" -#: pg_recvlogical.c:151 receivelog.c:415 +#: pg_recvlogical.c:160 receivelog.c:351 #, c-format msgid "%s: could not send feedback packet: %s" msgstr "%s: 피드백 íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s" -#: pg_recvlogical.c:190 +#: pg_recvlogical.c:199 #, c-format msgid "%s: could not fsync log file \"%s\": %s\n" msgstr "%s: \"%s\" 로그 íŒŒì¼ fsync 실패: %s\n" -#: pg_recvlogical.c:229 +#: pg_recvlogical.c:238 #, c-format msgid "%s: starting log streaming at %X/%X (slot %s)\n" msgstr "%s: 로그 ìŠ¤íŠ¸ë¦¬ë° ì‹œìž‘ 함, 위치: %X/%X (슬롯 %s)\n" -#: pg_recvlogical.c:271 +#: pg_recvlogical.c:280 #, c-format msgid "%s: streaming initiated\n" msgstr "%s: ìŠ¤íŠ¸ë¦¬ë° ì´ˆê¸°í™” ë¨\n" -#: pg_recvlogical.c:336 +#: pg_recvlogical.c:346 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: \"%s\" 로그 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_recvlogical.c:412 receivelog.c:980 +#: pg_recvlogical.c:376 receivelog.c:914 +#, c-format +msgid "%s: invalid socket: %s" +msgstr "%s: ìž˜ëª»ëœ ì†Œì¼“: %s" + +#: pg_recvlogical.c:430 receivelog.c:943 #, c-format msgid "%s: select() failed: %s\n" msgstr "%s: select() 실패: %s\n" -#: pg_recvlogical.c:421 receivelog.c:1030 +#: pg_recvlogical.c:439 receivelog.c:995 #, c-format msgid "%s: could not receive data from WAL stream: %s" msgstr "%s: WAL 스트림ì—서 ìžë£Œ 받기 실패: %s" -#: pg_recvlogical.c:462 pg_recvlogical.c:501 receivelog.c:1075 -#: receivelog.c:1144 +#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1040 +#: receivelog.c:1107 #, c-format msgid "%s: streaming header too small: %d\n" msgstr "%s: ìŠ¤íŠ¸ë¦¬ë° í—¤ë” í¬ê¸°ê°€ 너무 ìž‘ìŒ: %d\n" -#: pg_recvlogical.c:484 receivelog.c:924 +#: pg_recvlogical.c:517 receivelog.c:874 #, c-format msgid "%s: unrecognized streaming header: \"%c\"\n" msgstr "%s: 알 수 없는 ìŠ¤íŠ¸ë¦¬ë° í—¤ë”: \"%c\"\n" -#: pg_recvlogical.c:530 pg_recvlogical.c:544 +#: pg_recvlogical.c:573 pg_recvlogical.c:587 #, c-format msgid "%s: could not write %u bytes to log file \"%s\": %s\n" msgstr "%s: %u ë°”ì´íЏ 쓰기 실패, ë¡œê·¸íŒŒì¼ \"%s\": %s\n" -#: pg_recvlogical.c:555 receivelog.c:707 receivelog.c:745 +#: pg_recvlogical.c:617 receivelog.c:667 receivelog.c:705 #, c-format msgid "%s: unexpected termination of replication stream: %s" msgstr "%s: 복제 ìŠ¤íŠ¸ë¦¼ì˜ ì˜ˆìƒì¹˜ 못한 종료: %s" -#: pg_recvlogical.c:678 +#: pg_recvlogical.c:741 #, c-format msgid "%s: invalid fsync interval \"%s\"\n" msgstr "%s: \"%s\" ê°’ì€ ìž˜ëª»ëœ fsync 반복주기 ìž„\n" -#: pg_recvlogical.c:719 +#: pg_recvlogical.c:782 #, c-format msgid "%s: could not parse start position \"%s\"\n" msgstr "%s: 시작 위치 êµ¬ë¬¸ì´ ìž˜ëª»ë¨ \"%s\"\n" -#: pg_recvlogical.c:803 +#: pg_recvlogical.c:792 +#, c-format +msgid "%s: could not parse end position \"%s\"\n" +msgstr "%s: 시작 위치 êµ¬ë¬¸ì´ ìž˜ëª»ë¨ \"%s\"\n" + +#: pg_recvlogical.c:876 #, c-format msgid "%s: no slot specified\n" msgstr "%s: ìŠ¬ë¡¯ì„ ì§€ì •í•˜ì§€ 않았ìŒ\n" -#: pg_recvlogical.c:811 +#: pg_recvlogical.c:884 #, c-format msgid "%s: no target file specified\n" msgstr "%s: ëŒ€ìƒ íŒŒì¼ì„ 지정하지 않았ìŒ\n" -#: pg_recvlogical.c:819 +#: pg_recvlogical.c:892 #, c-format msgid "%s: no database specified\n" msgstr "%s: ë°ì´í„°ë² ì´ìФ 지정하지 않았ìŒ\n" -#: pg_recvlogical.c:827 +#: pg_recvlogical.c:900 #, c-format msgid "%s: at least one action needs to be specified\n" msgstr "%s: ì ì–´ë„ 하나 ì´ìƒì˜ 작업 ë°©ë²•ì„ ì§€ì •í•´ì•¼ 함\n" -#: pg_recvlogical.c:835 +#: pg_recvlogical.c:908 #, c-format msgid "%s: cannot use --create-slot or --start together with --drop-slot\n" msgstr "" "%s: --create-slot 옵션 ë˜ëŠ” --start ì˜µì…˜ì€ --drop-slot 옵션과 함께 사용할 수 " "ì—†ìŒ\n" -#: pg_recvlogical.c:843 +#: pg_recvlogical.c:916 #, c-format msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" msgstr "" "%s: --create-slot 옵션ì´ë‚˜ --drop-slot ì˜µì…˜ì€ --startpos 옵션과 함께 쓸 수 ì—†" "ìŒ\n" -#: pg_recvlogical.c:874 +#: pg_recvlogical.c:925 +#, c-format +msgid "%s: --endpos may only be specified with --start\n" +msgstr "%s: --endpos ì˜µì…˜ì€ --start 옵션과 함께 사용해야 함\n" + +#: pg_recvlogical.c:957 #, c-format msgid "%s: could not establish database-specific replication connection\n" msgstr "%s: ë°ì´í„°ë² ì´ìФ ì˜ì¡´ì ì¸ 복제 ì—°ê²°ì„ í•  수 ì—†ìŒ\n" -#: receivelog.c:75 +#: receivelog.c:71 #, c-format msgid "%s: could not create archive status file \"%s\": %s\n" msgstr "%s: \"%s\" ì•„ì¹´ì´ë¸Œ ìƒíƒœ 파ì¼ì„ 만들 수 ì—†ìŒ: %s\n" -#: receivelog.c:82 receivelog.c:206 receivelog.c:355 receivelog.c:848 -#: receivelog.c:1096 +#: receivelog.c:119 #, c-format -msgid "%s: could not fsync file \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì„ fsync í•  수 ì—†ìŒ: %s\n" +msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" +msgstr "%s: \"%s\" WAL íŒŒì¼ í¬ê¸°ë¥¼ 알 수 ì—†ìŒ: %s\n" -#: receivelog.c:121 +#: receivelog.c:130 #, c-format -msgid "%s: could not open transaction log file \"%s\": %s\n" -msgstr "%s: \"%s\" 트랜잭션 로그 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" +msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" +msgstr "%s: ì´ë¯¸ 있는 \"%s\" 트랜잭션 로그 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: receivelog.c:133 +#: receivelog.c:139 #, c-format -msgid "%s: could not stat transaction log file \"%s\": %s\n" -msgstr "%s: \"%s\" 트랜잭션 로그 파ì¼ì˜ ìƒíƒœë¥¼ 알 수 ì—†ìŒ: %s\n" +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" +msgstr "%s: ì´ë¯¸ 있는 \"%s\" WAL íŒŒì¼ fsync 실패: %s\n" -#: receivelog.c:147 +#: receivelog.c:154 #, c-format -msgid "%s: transaction log file \"%s\" has %d bytes, should be 0 or %d\n" -msgstr "" +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "" +"%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "" "%s: \"%s\" 트랜잭션 로그파ì¼ì˜ í¬ê¸°ê°€ %d ë°”ì´íŠ¸ìž„, 0 ë˜ëŠ” %d ë°”ì´íŠ¸ì—¬ì•¼ 함\n" -#: receivelog.c:160 +#: receivelog.c:169 #, c-format -msgid "%s: could not pad transaction log file \"%s\": %s\n" -msgstr "%s: \"%s\" 트랜잭션 로그 파ì¼ì„ 채울 수 ì—†ìŒ: %s\n" +msgid "%s: could not open write-ahead log file \"%s\": %s\n" +msgstr "%s: \"%s\" WAL 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: receivelog.c:173 -#, c-format -msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n" -msgstr "%s: \"%s\" 트랜잭션 로그파ì¼ì˜ 시작위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s\n" - -#: receivelog.c:199 +#: receivelog.c:196 #, c-format msgid "%s: could not determine seek position in file \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì˜ 시작 위치를 ê²°ì •í•  수 ì—†ìŒ: %s\n" -#: receivelog.c:232 -#, c-format -msgid "%s: could not rename file \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì˜ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" - -#: receivelog.c:239 +#: receivelog.c:211 #, c-format msgid "%s: not renaming \"%s%s\", segment is not complete\n" msgstr "%s: \"%s%s\" ì´ë¦„ 변경 실패, 세그먼트가 완료ë˜ì§€ 않았ìŒ\n" -#: receivelog.c:285 -#, c-format -msgid "%s: could not open timeline history file \"%s\": %s\n" -msgstr "%s: \"%s\" 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" - -#: receivelog.c:313 +#: receivelog.c:280 #, c-format msgid "%s: server reported unexpected history file name for timeline %u: %s\n" msgstr "%s: 타임ë¼ì¸ %u ë²ˆì„ ìœ„í•œ ë‚´ì—­ íŒŒì¼ ì´ë¦„ì´ ìž˜ëª» ë˜ì—ˆìŒ: %s\n" -#: receivelog.c:330 +#: receivelog.c:288 #, c-format msgid "%s: could not create timeline history file \"%s\": %s\n" msgstr "%s: \"%s\" 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì„ 만들 수 ì—†ìŒ: %s\n" -#: receivelog.c:347 +#: receivelog.c:295 #, c-format msgid "%s: could not write timeline history file \"%s\": %s\n" msgstr "%s: \"%s\" 타임ë¼ì¸ ë‚´ì—­ 파ì¼ì— 쓸 수 ì—†ìŒ: %s\n" -#: receivelog.c:372 -#, c-format -msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì„ \"%s\" 파ì¼ë¡œ ì´ë¦„ì„ ë°”ê¿€ 수 ì—†ìŒ: %s\n" - -#: receivelog.c:449 +#: receivelog.c:385 #, c-format msgid "" "%s: incompatible server version %s; client does not support streaming from " @@ -1084,7 +1234,7 @@ msgstr "" "%s: %s 서버 ë²„ì „ì€ í˜¸í™˜ë˜ì§€ 않ìŒ; í´ë¼ì´ì–¸íŠ¸ëŠ” %s 버전 보다 ì˜¤ëž˜ëœ ì„œë²„ì˜ ìŠ¤" "트리ë°ì€ ì§€ì›í•˜ì§€ 않ìŒ\n" -#: receivelog.c:459 +#: receivelog.c:395 #, c-format msgid "" "%s: incompatible server version %s; client does not support streaming from " @@ -1093,7 +1243,7 @@ msgstr "" "%s: %s 서버 ë²„ì „ì€ í˜¸í™˜ë˜ì§€ 않ìŒ; í´ë¼ì´ì–¸íŠ¸ëŠ” %s 버전 보다 새로운 ì„œë²„ì˜ ìŠ¤" "트리ë°ì€ ì§€ì›í•˜ì§€ 않ìŒ\n" -#: receivelog.c:557 streamutil.c:264 streamutil.c:299 +#: receivelog.c:500 streamutil.c:265 streamutil.c:304 #, c-format msgid "" "%s: could not identify system: got %d rows and %d fields, expected %d rows " @@ -1102,19 +1252,24 @@ msgstr "" "%s: ì‹œìŠ¤í…œì„ ì‹ë³„í•  수 ì—†ìŒ: 로우수 %d, 필드수 %d, 예ìƒê°’: 로우수 %d, 필드수 " "%d ì´ìƒ\n" -#: receivelog.c:565 +#: receivelog.c:508 #, c-format msgid "" "%s: system identifier does not match between base backup and streaming " "connection\n" msgstr "%s: 시스템 ì‹ë³„ìžê°€ ë² ì´ìФ 백업과 ìŠ¤íŠ¸ë¦¬ë° ì—°ê²°ì—서 서로 다름\n" -#: receivelog.c:573 +#: receivelog.c:516 #, c-format msgid "%s: starting timeline %u is not present in the server\n" msgstr "%s: %u 타임ë¼ì¸ìœ¼ë¡œ 시작하는 ê²ƒì„ ì„œë²„ì—서 제공 하지 않ìŒ\n" -#: receivelog.c:613 +#: receivelog.c:535 +#, c-format +msgid "%s: could not create temporary replication slot \"%s\": %s" +msgstr "%s: \"%s\" 임시 복제 ìŠ¬ë¡¯ì„ ë§Œë“¤ 수 ì—†ìŒ: %s" + +#: receivelog.c:576 #, c-format msgid "" "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d " @@ -1123,14 +1278,14 @@ msgstr "" "%s: TIMELINE_HISTORY 명령 결과가 잘못ë¨: ë°›ì€ ê°’: 로우수 %d, 필드수 %d, 예ìƒ" "ê°’: 로우수 %d, 필드수 %d\n" -#: receivelog.c:688 +#: receivelog.c:648 #, c-format msgid "" "%s: server reported unexpected next timeline %u, following timeline %u\n" msgstr "" "%s: 서버가 ìž˜ëª»ëœ ë‹¤ìŒ íƒ€ìž„ë¼ì¸ 번호 %u 보고함, ì´ì „ 타임ë¼ì¸ 번호 %u\n" -#: receivelog.c:695 +#: receivelog.c:655 #, c-format msgid "" "%s: server stopped streaming timeline %u at %X/%X, but reported next " @@ -1139,12 +1294,12 @@ msgstr "" "%s: ì„œë²„ì˜ ì¤‘ì§€ 위치: 타임ë¼ì¸ %u, 위치 %X/%X, 하지만 ë³´ê³  ë°›ì€ ìœ„ì¹˜: 타임ë¼" "ì¸ %u 위치 %X/%X\n" -#: receivelog.c:736 +#: receivelog.c:696 #, c-format msgid "%s: replication stream was terminated before stop point\n" msgstr "%s: 복제 ìŠ¤íŠ¸ë¦¼ì´ ì¤‘ì§€ 위치 ì „ì— ì¢…ë£Œ ë˜ì—ˆìŒ\n" -#: receivelog.c:785 +#: receivelog.c:745 #, c-format msgid "" "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, " @@ -1153,61 +1308,56 @@ msgstr "" "%s: 타임ë¼ì¸ ëì— ìž˜ëª»ëœ ê²°ê³¼ê°€ 발견 ë¨: 로우수 %d, 필드수 %d / 예ìƒê°’: 로우" "수 %d, 필드수 %d\n" -#: receivelog.c:795 +#: receivelog.c:755 #, c-format msgid "%s: could not parse next timeline's starting point \"%s\"\n" msgstr "%s: ë‹¤ìŒ íƒ€ìž„ë¼ì¸ 시작 위치 ë¶„ì„ ì‹¤íŒ¨ \"%s\"\n" -#: receivelog.c:959 -#, c-format -msgid "%s: socket not open" -msgstr "%s: 소켓 ì—´ 수 ì—†ìŒ" - -#: receivelog.c:1163 +#: receivelog.c:1126 #, c-format -msgid "%s: received transaction log record for offset %u with no file open\n" +msgid "%s: received write-ahead log record for offset %u with no file open\n" msgstr "%s: %u ìœ„ì¹˜ì˜ ìˆ˜ì‹ ëœ íŠ¸ëžœìž­ì…˜ 로그 ë ˆì½”ë“œì— íŒŒì¼ì„ ì—´ 수 ì—†ìŒ\n" -#: receivelog.c:1175 +#: receivelog.c:1137 #, c-format msgid "%s: got WAL data offset %08x, expected %08x\n" msgstr "%s: ìž˜ëª»ëœ WAL ìžë£Œ 위치 %08x, 기대값 %08x\n" -#: receivelog.c:1212 +#: receivelog.c:1172 #, c-format msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" msgstr "%s: %u ë°”ì´íŠ¸ë¥¼ \"%s\" WAL 파ì¼ì— 쓸 수 ì—†ìŒ: %s\n" -#: receivelog.c:1237 receivelog.c:1279 receivelog.c:1311 +#: receivelog.c:1197 receivelog.c:1238 receivelog.c:1269 #, c-format msgid "%s: could not send copy-end packet: %s" msgstr "%s: copy-end íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s" -#: streamutil.c:145 +#: streamutil.c:149 msgid "Password: " msgstr "암호: " -#: streamutil.c:169 +#: streamutil.c:174 #, c-format msgid "%s: could not connect to server\n" msgstr "%s: ì„œë²„ì— ì ‘ì†í•  수 ì—†ìŒ\n" -#: streamutil.c:187 +#: streamutil.c:192 #, c-format msgid "%s: could not connect to server: %s" msgstr "%s: ì„œë²„ì— ì ‘ì†í•  수 ì—†ìŒ: %s" -#: streamutil.c:211 +#: streamutil.c:216 #, c-format msgid "%s: could not determine server setting for integer_datetimes\n" msgstr "%s: integer_datetimes 서버 ì„¤ì •ì„ ì•Œ 수 ì—†ìŒ\n" -#: streamutil.c:224 +#: streamutil.c:225 #, c-format msgid "%s: integer_datetimes compile flag does not match server\n" msgstr "%s: integer_datetimes ì»´íŒŒì¼ í”Œëž˜ê·¸ê°€ 서버와 ì¼ì¹˜í•˜ì§€ 않ìŒ\n" -#: streamutil.c:365 +#: streamutil.c:376 #, c-format msgid "" "%s: could not create replication slot \"%s\": got %d rows and %d fields, " @@ -1216,7 +1366,7 @@ msgstr "" "%s: \"%s\" 복제 ìŠ¬ë¡¯ì„ ë§Œë“¤ 수 ì—†ìŒ: 로우수 %d, 필드수 %d, 기대값 로우수 %d, " "필드수 %d\n" -#: streamutil.c:410 +#: streamutil.c:421 #, c-format msgid "" "%s: could not drop replication slot \"%s\": got %d rows and %d fields, " @@ -1224,3 +1374,35 @@ msgid "" msgstr "" "%s: \"%s\" 복제 ìŠ¬ë¡¯ì„ ì‚­ì œí•  수 ì—†ìŒ: 로우수 %d, 필드수 %d, 기대값 로우수 " "%d, 필드수 %d\n" + +#: walmethods.c:435 walmethods.c:904 +msgid "could not compress data" +msgstr "ìžë£Œë¥¼ ì••ì¶•í•  수 ì—†ìŒ" + +#: walmethods.c:459 +msgid "could not reset compression stream" +msgstr "ì••ì¶• ìŠ¤íŠ¸ë¦¼ì„ ë¦¬ì…‹í•  수 ì—†ìŒ" + +#: walmethods.c:560 +msgid "could not initialize compression library" +msgstr "ì••ì¶• ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 초기화할 수 ì—†ìŒ" + +#: walmethods.c:572 +msgid "implementation error: tar files can't have more than one open file" +msgstr "구현 오류: tar 파ì¼ì€ 하나 ì´ìƒ ì—´ 수 ì—†ìŒ" + +#: walmethods.c:586 +msgid "could not create tar header" +msgstr "tar í•´ë”를 만들 수 ì—†ìŒ" + +#: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 +msgid "could not change compression parameters" +msgstr "ì••ì¶• 매개 변수를 바꿀 수 ì—†ìŒ" + +#: walmethods.c:720 +msgid "unlink not supported with compression" +msgstr "ì••ì¶• ìƒíƒœì—서 íŒŒì¼ ì‚­ì œëŠ” ì§€ì›í•˜ì§€ 않ìŒ" + +#: walmethods.c:920 +msgid "could not close compression stream" +msgstr "ì••ì¶• ìŠ¤íŠ¸ë¦¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ" diff --git a/src/bin/pg_basebackup/po/ru.po b/src/bin/pg_basebackup/po/ru.po index 0653e385ba8..2511952f8fc 100644 --- a/src/bin/pg_basebackup/po/ru.po +++ b/src/bin/pg_basebackup/po/ru.po @@ -2,13 +2,13 @@ # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: pg_basebackup (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:45+0000\n" -"PO-Revision-Date: 2017-04-03 16:01+0300\n" +"POT-Creation-Date: 2017-11-07 09:03+0300\n" +"PO-Revision-Date: 2017-08-20 14:14+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,7 +16,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"Last-Translator: Alexander Lakhin \n" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -51,8 +50,8 @@ msgstr "%s: не удалоÑÑŒ прочитать каталог \"%s\": %s\n" msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть файл \"%s\": %s\n" -#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:791 -#: receivelog.c:1034 +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:804 +#: receivelog.c:1061 #, c-format msgid "%s: could not fsync file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñинхронизировать Ñ Ð¤Ð¡ файл \"%s\": %s\n" @@ -84,23 +83,23 @@ msgstr "%s: ошибка при удалении Ñодержимого ката #: pg_basebackup.c:177 #, c-format -msgid "%s: removing transaction log directory \"%s\"\n" -msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: удаление каталога WAL \"%s\"\n" #: pg_basebackup.c:180 #, c-format -msgid "%s: failed to remove transaction log directory\n" -msgstr "%s: ошибка при удалении каталога журнала транзакций\n" +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: ошибка при удалении каталога WAL\n" #: pg_basebackup.c:186 #, c-format -msgid "%s: removing contents of transaction log directory \"%s\"\n" -msgstr "%s: очиÑтка каталога журнала транзакций \"%s\"\n" +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: удаление Ñодержимого каталога WAL \"%s\"\n" #: pg_basebackup.c:189 #, c-format -msgid "%s: failed to remove contents of transaction log directory\n" -msgstr "%s: ошибка при очиÑтке каталога журнала транзакций\n" +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: ошибка при удалении Ñодержимого каталога WAL\n" #: pg_basebackup.c:197 #, c-format @@ -109,9 +108,8 @@ msgstr "%s: каталог данных \"%s\" не был удалён по з #: pg_basebackup.c:202 #, c-format -msgid "%s: transaction log directory \"%s\" not removed at user's request\n" -msgstr "" -"%s: каталог журнала транзакций \"%s\" не был удалён по запроÑу пользователÑ\n" +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: каталог данных WAL \"%s\" не был удалён по запроÑу пользователÑ\n" #: pg_basebackup.c:208 #, c-format @@ -150,7 +148,7 @@ msgstr "" "%s: новый каталог в ÑопоÑтавлении табл. проÑтранÑтва задан не абÑолютным " "путём: %s\n" -#: pg_basebackup.c:327 +#: pg_basebackup.c:332 #, c-format msgid "" "%s takes a base backup of a running PostgreSQL server.\n" @@ -159,17 +157,17 @@ msgstr "" "%s делает базовую резервную копию работающего Ñервера PostgreSQL.\n" "\n" -#: pg_basebackup.c:329 pg_receivewal.c:76 pg_recvlogical.c:77 +#: pg_basebackup.c:334 pg_receivewal.c:76 pg_recvlogical.c:77 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: pg_basebackup.c:330 pg_receivewal.c:77 pg_recvlogical.c:78 +#: pg_basebackup.c:335 pg_receivewal.c:77 pg_recvlogical.c:78 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [ПÐРÐМЕТР]...\n" -#: pg_basebackup.c:331 +#: pg_basebackup.c:336 #, c-format msgid "" "\n" @@ -178,19 +176,19 @@ msgstr "" "\n" "Параметры, управлÑющие выводом:\n" -#: pg_basebackup.c:332 +#: pg_basebackup.c:337 #, c-format msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" msgstr " -D, --pgdata=КÐТÐЛОГ Ñохранить базовую копию в указанный каталог\n" -#: pg_basebackup.c:333 +#: pg_basebackup.c:338 #, c-format msgid " -F, --format=p|t output format (plain (default), tar)\n" msgstr "" " -F, --format=p|t формат вывода (p (по умолчанию) - проÑтой, t - " "tar)\n" -#: pg_basebackup.c:334 +#: pg_basebackup.c:339 #, c-format msgid "" " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" @@ -199,7 +197,7 @@ msgstr "" " -r, --max-rate=СКОРОСТЬ макÑ. ÑкороÑть передачи данных в целевой каталог\n" " (в КБ/Ñ, либо добавьте ÑÑƒÑ„Ñ„Ð¸ÐºÑ \"k\" или \"M\")\n" -#: pg_basebackup.c:336 +#: pg_basebackup.c:341 #, c-format msgid "" " -R, --write-recovery-conf\n" @@ -208,19 +206,19 @@ msgstr "" " -R, --write-recovery-conf\n" " запиÑать recovery.conf Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸\n" -#: pg_basebackup.c:338 pg_receivewal.c:84 +#: pg_basebackup.c:343 pg_receivewal.c:84 #, c-format msgid " -S, --slot=SLOTNAME replication slot to use\n" msgstr " -S, --slot=ИМЯ_СЛОТРиÑпользовать заданный Ñлот репликации\n" -#: pg_basebackup.c:339 +#: pg_basebackup.c:344 #, c-format msgid "" " --no-slot prevent creation of temporary replication slot\n" msgstr "" " --no-slot предотвратить Ñоздание временного Ñлота репликации\n" -#: pg_basebackup.c:340 +#: pg_basebackup.c:345 #, c-format msgid "" " -T, --tablespace-mapping=OLDDIR=NEWDIR\n" @@ -231,7 +229,7 @@ msgstr "" "каталога\n" " в новый\n" -#: pg_basebackup.c:342 +#: pg_basebackup.c:347 #, c-format msgid "" " -X, --wal-method=none|fetch|stream\n" @@ -241,25 +239,25 @@ msgstr "" " включить в копию требуемые файлы WAL, иÑпользуÑ\n" " заданный метод\n" -#: pg_basebackup.c:344 +#: pg_basebackup.c:349 #, c-format -msgid " --waldir=WALDIR location for the transaction log directory\n" +msgid " --waldir=WALDIR location for the write-ahead log directory\n" msgstr "" " --waldir=КÐТÐЛОГ_WAL\n" -" раÑположение каталога Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð¾Ð¼ транзакций\n" +" раÑположение каталога Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð¾Ð¼ предзапиÑи\n" -#: pg_basebackup.c:345 +#: pg_basebackup.c:350 #, c-format msgid " -z, --gzip compress tar output\n" msgstr " -z, --gzip Ñжать выходной tar\n" -#: pg_basebackup.c:346 +#: pg_basebackup.c:351 #, c-format msgid "" " -Z, --compress=0-9 compress tar output with given compression level\n" msgstr " -Z, --compress=0-9 уÑтановить уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ архива\n" -#: pg_basebackup.c:347 +#: pg_basebackup.c:352 #, c-format msgid "" "\n" @@ -268,7 +266,7 @@ msgstr "" "\n" "Общие параметры:\n" -#: pg_basebackup.c:348 +#: pg_basebackup.c:353 #, c-format msgid "" " -c, --checkpoint=fast|spread\n" @@ -277,17 +275,17 @@ msgstr "" " -c, --checkpoint=fast|spread\n" " режим быÑтрых или раÑпределённых контрольных точек\n" -#: pg_basebackup.c:350 +#: pg_basebackup.c:355 #, c-format msgid " -l, --label=LABEL set backup label\n" msgstr " -l, --label=МЕТКРуÑтановить метку резервной копии\n" -#: pg_basebackup.c:351 +#: pg_basebackup.c:356 #, c-format msgid " -n, --no-clean do not clean up after errors\n" msgstr " -n, --no-clean не очищать поÑле ошибок\n" -#: pg_basebackup.c:352 +#: pg_basebackup.c:357 #, c-format msgid "" " -N, --no-sync do not wait for changes to be written safely to " @@ -295,27 +293,27 @@ msgid "" msgstr "" " -N, --no-sync не ждать Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… на диÑке\n" -#: pg_basebackup.c:353 +#: pg_basebackup.c:358 #, c-format msgid " -P, --progress show progress information\n" msgstr " -P, --progress показывать прогреÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸\n" -#: pg_basebackup.c:354 pg_receivewal.c:86 pg_recvlogical.c:98 +#: pg_basebackup.c:359 pg_receivewal.c:86 pg_recvlogical.c:98 #, c-format msgid " -v, --verbose output verbose messages\n" msgstr " -v, --verbose выводить подробные ÑообщениÑ\n" -#: pg_basebackup.c:355 pg_receivewal.c:87 pg_recvlogical.c:99 +#: pg_basebackup.c:360 pg_receivewal.c:87 pg_recvlogical.c:99 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: pg_basebackup.c:356 pg_receivewal.c:89 pg_recvlogical.c:100 +#: pg_basebackup.c:361 pg_receivewal.c:89 pg_recvlogical.c:100 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_basebackup.c:357 pg_receivewal.c:90 pg_recvlogical.c:101 +#: pg_basebackup.c:362 pg_receivewal.c:90 pg_recvlogical.c:101 #, c-format msgid "" "\n" @@ -324,22 +322,22 @@ msgstr "" "\n" "Параметры подключениÑ:\n" -#: pg_basebackup.c:358 pg_receivewal.c:91 +#: pg_basebackup.c:363 pg_receivewal.c:91 #, c-format msgid " -d, --dbname=CONNSTR connection string\n" msgstr " -d, --dbname=СТРОКРÑтрока подключениÑ\n" -#: pg_basebackup.c:359 pg_receivewal.c:92 pg_recvlogical.c:103 +#: pg_basebackup.c:364 pg_receivewal.c:92 pg_recvlogical.c:103 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=ИМЯ Ð¸Ð¼Ñ Ñервера баз данных или каталог Ñокетов\n" -#: pg_basebackup.c:360 pg_receivewal.c:93 pg_recvlogical.c:104 +#: pg_basebackup.c:365 pg_receivewal.c:93 pg_recvlogical.c:104 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=ПОРТ номер порта Ñервера БД\n" -#: pg_basebackup.c:361 +#: pg_basebackup.c:366 #, c-format msgid "" " -s, --status-interval=INTERVAL\n" @@ -350,19 +348,19 @@ msgstr "" " интервал между передаваемыми Ñерверу\n" " пакетами ÑоÑтоÑÐ½Ð¸Ñ (в Ñекундах)\n" -#: pg_basebackup.c:363 pg_receivewal.c:94 pg_recvlogical.c:105 +#: pg_basebackup.c:368 pg_receivewal.c:94 pg_recvlogical.c:105 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr "" " -U, --username=NAME connect as specified database user\n" " -U, --username=ИМЯ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±Ð°Ð· данных\n" -#: pg_basebackup.c:364 pg_receivewal.c:95 pg_recvlogical.c:106 +#: pg_basebackup.c:369 pg_receivewal.c:95 pg_recvlogical.c:106 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password не запрашивать пароль\n" -#: pg_basebackup.c:365 pg_receivewal.c:96 pg_recvlogical.c:107 +#: pg_basebackup.c:370 pg_receivewal.c:96 pg_recvlogical.c:107 #, c-format msgid "" " -W, --password force password prompt (should happen " @@ -370,7 +368,7 @@ msgid "" msgstr "" " -W, --password запрашивать пароль вÑегда (обычно не требуетÑÑ)\n" -#: pg_basebackup.c:366 pg_receivewal.c:100 pg_recvlogical.c:108 +#: pg_basebackup.c:371 pg_receivewal.c:100 pg_recvlogical.c:108 #, c-format msgid "" "\n" @@ -379,53 +377,53 @@ msgstr "" "\n" "Об ошибках Ñообщайте по адреÑу .\n" -#: pg_basebackup.c:409 +#: pg_basebackup.c:414 #, c-format msgid "%s: could not read from ready pipe: %s\n" msgstr "%s: не удалоÑÑŒ прочитать из готового канала: %s\n" -#: pg_basebackup.c:417 pg_basebackup.c:547 pg_basebackup.c:1996 -#: streamutil.c:285 +#: pg_basebackup.c:422 pg_basebackup.c:557 pg_basebackup.c:2015 +#: streamutil.c:286 #, c-format -msgid "%s: could not parse transaction log location \"%s\"\n" -msgstr "%s: не удалоÑÑŒ разобрать положение в журнале транзакций \"%s\"\n" +msgid "%s: could not parse write-ahead log location \"%s\"\n" +msgstr "%s: не удалоÑÑŒ разобрать положение в журнале предзапиÑи \"%s\"\n" -#: pg_basebackup.c:510 pg_receivewal.c:427 +#: pg_basebackup.c:520 pg_receivewal.c:428 #, c-format msgid "%s: could not finish writing WAL files: %s\n" msgstr "%s: не удалоÑÑŒ завершить запиÑÑŒ файлов WAL: %s\n" -#: pg_basebackup.c:560 +#: pg_basebackup.c:570 #, c-format msgid "%s: could not create pipe for background process: %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать канал Ð´Ð»Ñ Ñ„Ð¾Ð½Ð¾Ð²Ð¾Ð³Ð¾ процеÑÑа: %s\n" -#: pg_basebackup.c:600 pg_basebackup.c:656 pg_basebackup.c:1414 +#: pg_basebackup.c:610 pg_basebackup.c:666 pg_basebackup.c:1433 #, c-format msgid "%s: could not create directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать каталог \"%s\": %s\n" -#: pg_basebackup.c:619 +#: pg_basebackup.c:629 #, c-format msgid "%s: could not create background process: %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать фоновый процеÑÑ: %s\n" -#: pg_basebackup.c:631 +#: pg_basebackup.c:641 #, c-format msgid "%s: could not create background thread: %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать фоновый поток выполнениÑ: %s\n" -#: pg_basebackup.c:679 +#: pg_basebackup.c:689 #, c-format msgid "%s: directory \"%s\" exists but is not empty\n" msgstr "%s: каталог \"%s\" ÑущеÑтвует, но он не пуÑÑ‚\n" -#: pg_basebackup.c:687 +#: pg_basebackup.c:697 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: нет доÑтупа к каталогу \"%s\": %s\n" -#: pg_basebackup.c:749 +#: pg_basebackup.c:759 #, c-format msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" @@ -433,7 +431,7 @@ msgstr[0] "%*s/%s КБ (100%%), табличное проÑтранÑтво %d/% msgstr[1] "%*s/%s КБ (100%%), табличное проÑтранÑтво %d/%d %*s" msgstr[2] "%*s/%s КБ (100%%), табличное проÑтранÑтво %d/%d %*s" -#: pg_basebackup.c:761 +#: pg_basebackup.c:771 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" @@ -441,7 +439,7 @@ msgstr[0] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d msgstr[1] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d (%s%-*.*s)" msgstr[2] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d (%s%-*.*s)" -#: pg_basebackup.c:777 +#: pg_basebackup.c:787 #, c-format msgid "%*s/%s kB (%d%%), %d/%d tablespace" msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" @@ -449,149 +447,149 @@ msgstr[0] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d msgstr[1] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d" msgstr[2] "%*s/%s КБ (%d%%), табличное проÑтранÑтво %d/%d" -#: pg_basebackup.c:799 +#: pg_basebackup.c:809 #, c-format msgid "%s: transfer rate \"%s\" is not a valid value\n" msgstr "%s: неверное значение (\"%s\") Ð´Ð»Ñ ÑкороÑти передачи данных\n" -#: pg_basebackup.c:806 +#: pg_basebackup.c:816 #, c-format msgid "%s: invalid transfer rate \"%s\": %s\n" msgstr "%s: Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑкороÑть передачи данных \"%s\": %s\n" -#: pg_basebackup.c:816 +#: pg_basebackup.c:826 #, c-format msgid "%s: transfer rate must be greater than zero\n" msgstr "%s: ÑкороÑть передачи должна быть больше 0\n" -#: pg_basebackup.c:850 +#: pg_basebackup.c:860 #, c-format msgid "%s: invalid --max-rate unit: \"%s\"\n" msgstr "%s: Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐµÐ´Ð¸Ð½Ð¸Ñ†Ð° Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð² --max-rate: \"%s\"\n" -#: pg_basebackup.c:859 +#: pg_basebackup.c:869 #, c-format msgid "%s: transfer rate \"%s\" exceeds integer range\n" msgstr "%s: ÑкороÑть передачи \"%s\" вне целочиÑленного диапазона\n" -#: pg_basebackup.c:871 +#: pg_basebackup.c:881 #, c-format msgid "%s: transfer rate \"%s\" is out of range\n" msgstr "%s: ÑкороÑть передачи \"%s\" вне диапазона\n" -#: pg_basebackup.c:895 +#: pg_basebackup.c:905 #, c-format msgid "%s: could not write to compressed file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл Ñжатого архива \"%s\": %s\n" -#: pg_basebackup.c:905 pg_basebackup.c:1508 pg_basebackup.c:1674 +#: pg_basebackup.c:915 pg_basebackup.c:1527 pg_basebackup.c:1693 #, c-format msgid "%s: could not write to file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл \"%s\": %s\n" -#: pg_basebackup.c:960 pg_basebackup.c:981 pg_basebackup.c:1009 +#: pg_basebackup.c:974 pg_basebackup.c:995 pg_basebackup.c:1023 #, c-format msgid "%s: could not set compression level %d: %s\n" msgstr "%s: не удалоÑÑŒ уÑтановить уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ %d: %s\n" -#: pg_basebackup.c:1030 +#: pg_basebackup.c:1044 #, c-format msgid "%s: could not create compressed file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл Ñжатого архива \"%s\": %s\n" -#: pg_basebackup.c:1041 pg_basebackup.c:1468 pg_basebackup.c:1667 +#: pg_basebackup.c:1055 pg_basebackup.c:1487 pg_basebackup.c:1686 #, c-format msgid "%s: could not create file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл \"%s\": %s\n" -#: pg_basebackup.c:1053 pg_basebackup.c:1321 +#: pg_basebackup.c:1067 pg_basebackup.c:1340 #, c-format msgid "%s: could not get COPY data stream: %s" msgstr "%s: не удалоÑÑŒ получить поток данных COPY: %s" -#: pg_basebackup.c:1110 +#: pg_basebackup.c:1124 #, c-format msgid "%s: could not close compressed file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ закрыть Ñжатый файл \"%s\": %s\n" -#: pg_basebackup.c:1123 pg_recvlogical.c:631 receivelog.c:217 receivelog.c:302 -#: receivelog.c:701 +#: pg_basebackup.c:1137 pg_recvlogical.c:631 receivelog.c:223 receivelog.c:308 +#: receivelog.c:714 #, c-format msgid "%s: could not close file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ закрыть файл \"%s\": %s\n" -#: pg_basebackup.c:1134 pg_basebackup.c:1350 pg_recvlogical.c:453 -#: receivelog.c:982 +#: pg_basebackup.c:1148 pg_basebackup.c:1369 pg_recvlogical.c:453 +#: receivelog.c:1009 #, c-format msgid "%s: could not read COPY data: %s" msgstr "%s: не удалоÑÑŒ прочитать данные COPY: %s" -#: pg_basebackup.c:1364 +#: pg_basebackup.c:1383 #, c-format msgid "%s: invalid tar block header size: %d\n" msgstr "%s: неверный размер заголовка блока tar: %d\n" -#: pg_basebackup.c:1422 +#: pg_basebackup.c:1441 #, c-format msgid "%s: could not set permissions on directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ уÑтановить права Ð´Ð»Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° \"%s\": %s\n" -#: pg_basebackup.c:1446 +#: pg_basebackup.c:1465 #, c-format msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать ÑимволичеÑкую ÑÑылку \"%s\" в \"%s\": %s\n" -#: pg_basebackup.c:1455 +#: pg_basebackup.c:1474 #, c-format msgid "%s: unrecognized link indicator \"%c\"\n" msgstr "%s: нераÑпознанный индикатор ÑвÑзи \"%c\"\n" -#: pg_basebackup.c:1475 +#: pg_basebackup.c:1494 #, c-format msgid "%s: could not set permissions on file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ уÑтановить права доÑтупа Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\": %s\n" -#: pg_basebackup.c:1534 +#: pg_basebackup.c:1553 #, c-format msgid "%s: COPY stream ended before last file was finished\n" msgstr "%s: поток COPY закончилÑÑ Ð´Ð¾ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾Ñледнего файла\n" -#: pg_basebackup.c:1562 pg_basebackup.c:1582 pg_basebackup.c:1589 -#: pg_basebackup.c:1642 +#: pg_basebackup.c:1581 pg_basebackup.c:1601 pg_basebackup.c:1608 +#: pg_basebackup.c:1661 #, c-format msgid "%s: out of memory\n" msgstr "%s: нехватка памÑти\n" -#: pg_basebackup.c:1715 +#: pg_basebackup.c:1734 #, c-format msgid "%s: incompatible server version %s\n" msgstr "%s: неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ñервера %s\n" -#: pg_basebackup.c:1730 +#: pg_basebackup.c:1749 #, c-format msgid "HINT: use -X none or -X fetch to disable log streaming\n" msgstr "" "ПОДСКÐЗКÐ: укажите -X none или -X fetch Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ñ‚Ñ€Ð°Ð½ÑлÑции журнала\n" -#: pg_basebackup.c:1756 +#: pg_basebackup.c:1775 #, c-format msgid "%s: initiating base backup, waiting for checkpoint to complete\n" msgstr "" "%s: начинаетÑÑ Ð±Ð°Ð·Ð¾Ð²Ð¾Ðµ резервное копирование, ожидаетÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ðµ " "контрольной точки\n" -#: pg_basebackup.c:1774 pg_recvlogical.c:270 receivelog.c:479 receivelog.c:550 -#: receivelog.c:590 streamutil.c:255 streamutil.c:363 streamutil.c:409 +#: pg_basebackup.c:1793 pg_recvlogical.c:270 receivelog.c:492 receivelog.c:563 +#: receivelog.c:603 streamutil.c:256 streamutil.c:364 streamutil.c:410 #, c-format msgid "%s: could not send replication command \"%s\": %s" msgstr "%s: не удалоÑÑŒ передать команду репликации \"%s\": %s" -#: pg_basebackup.c:1785 +#: pg_basebackup.c:1804 #, c-format msgid "%s: could not initiate base backup: %s" msgstr "%s: не удалоÑÑŒ инициализировать базовое резервное копирование: %s" -#: pg_basebackup.c:1792 +#: pg_basebackup.c:1811 #, c-format msgid "" "%s: server returned unexpected response to BASE_BACKUP command; got %d rows " @@ -600,129 +598,129 @@ msgstr "" "%s: Ñервер вернул неожиданный ответ на команду BASE_BACKUP; получено Ñтрок: " "%d, полей: %d, а ожидалоÑÑŒ Ñтрок: %d, полей: %d\n" -#: pg_basebackup.c:1800 +#: pg_basebackup.c:1819 #, c-format msgid "%s: checkpoint completed\n" msgstr "%s: ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° завершена\n" -#: pg_basebackup.c:1815 +#: pg_basebackup.c:1834 #, c-format -msgid "%s: transaction log start point: %s on timeline %u\n" -msgstr "%s: ÑÑ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° журнала транзакций: %s на линии времени %u\n" +msgid "%s: write-ahead log start point: %s on timeline %u\n" +msgstr "%s: ÑÑ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° в журнале предзапиÑи: %s на линии времени %u\n" -#: pg_basebackup.c:1824 +#: pg_basebackup.c:1843 #, c-format msgid "%s: could not get backup header: %s" msgstr "%s: не удалоÑÑŒ получить заголовок резервной копии: %s" -#: pg_basebackup.c:1830 +#: pg_basebackup.c:1849 #, c-format msgid "%s: no data returned from server\n" msgstr "%s: Ñервер не вернул данные\n" -#: pg_basebackup.c:1862 +#: pg_basebackup.c:1881 #, c-format msgid "%s: can only write single tablespace to stdout, database has %d\n" msgstr "" "%s: в stdout можно вывеÑти только одно табличное проÑтранÑтво, вÑего в СУБД " "их %d\n" -#: pg_basebackup.c:1874 +#: pg_basebackup.c:1893 #, c-format msgid "%s: starting background WAL receiver\n" msgstr "%s: запуÑк фонового процеÑÑа ÑÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ WAL\n" -#: pg_basebackup.c:1905 +#: pg_basebackup.c:1924 #, c-format -msgid "%s: could not get transaction log end position from server: %s" +msgid "%s: could not get write-ahead log end position from server: %s" msgstr "" -"%s: не удалоÑÑŒ получить конечную позицию в журнале транзакций Ñ Ñервера: %s" +"%s: не удалоÑÑŒ получить конечную позицию в журнале предзапиÑи Ñ Ñервера: %s" -#: pg_basebackup.c:1912 +#: pg_basebackup.c:1931 #, c-format -msgid "%s: no transaction log end position returned from server\n" -msgstr "%s: Ñервер не вернул конечную позицию в журнале транзакций\n" +msgid "%s: no write-ahead log end position returned from server\n" +msgstr "%s: Ñервер не вернул конечную позицию в журнале предзапиÑи\n" -#: pg_basebackup.c:1918 +#: pg_basebackup.c:1937 #, c-format -msgid "%s: transaction log end point: %s\n" -msgstr "%s: ÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° журнала транзакций: %s\n" +msgid "%s: write-ahead log end point: %s\n" +msgstr "%s: ÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° в журнале предзапиÑи: %s\n" -#: pg_basebackup.c:1924 +#: pg_basebackup.c:1943 #, c-format msgid "%s: final receive failed: %s" msgstr "%s: ошибка в конце передачи: %s" -#: pg_basebackup.c:1948 +#: pg_basebackup.c:1967 #, c-format msgid "%s: waiting for background process to finish streaming ...\n" msgstr "%s: ожидание Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÐ¾Ð²Ð¾Ð¹ передачи фоновым процеÑÑом...\n" -#: pg_basebackup.c:1954 +#: pg_basebackup.c:1973 #, c-format msgid "%s: could not send command to background pipe: %s\n" msgstr "%s: не удалоÑÑŒ отправить команду в канал фонового процеÑÑа: %s\n" -#: pg_basebackup.c:1963 +#: pg_basebackup.c:1982 #, c-format msgid "%s: could not wait for child process: %s\n" msgstr "%s: Ñбой при ожидании дочернего процеÑÑа: %s\n" -#: pg_basebackup.c:1969 +#: pg_basebackup.c:1988 #, c-format msgid "%s: child %d died, expected %d\n" msgstr "%s: завершилÑÑ Ð´Ð¾Ñ‡ÐµÑ€Ð½Ð¸Ð¹ процеÑÑ %d вмеÑто ожидаемого %d\n" -#: pg_basebackup.c:1975 +#: pg_basebackup.c:1994 #, c-format msgid "%s: child process did not exit normally\n" msgstr "%s: дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½ ненормально\n" -#: pg_basebackup.c:1981 +#: pg_basebackup.c:2000 #, c-format msgid "%s: child process exited with error %d\n" msgstr "%s: дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ %d\n" -#: pg_basebackup.c:2008 +#: pg_basebackup.c:2027 #, c-format msgid "%s: could not wait for child thread: %s\n" msgstr "%s: Ñбой при ожидании дочернего потока: %s\n" -#: pg_basebackup.c:2015 +#: pg_basebackup.c:2034 #, c-format msgid "%s: could not get child thread exit status: %s\n" msgstr "%s: не удалоÑÑŒ получить ÑоÑтоÑние Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð´Ð¾Ñ‡ÐµÑ€Ð½ÐµÐ³Ð¾ потока: %s\n" -#: pg_basebackup.c:2021 +#: pg_basebackup.c:2040 #, c-format msgid "%s: child thread exited with error %u\n" msgstr "%s: дочерний поток завершилÑÑ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ %u\n" -#: pg_basebackup.c:2059 +#: pg_basebackup.c:2078 #, c-format msgid "%s: base backup completed\n" msgstr "%s: базовое резервное копирование завершено\n" -#: pg_basebackup.c:2136 +#: pg_basebackup.c:2155 #, c-format msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" msgstr "%s: неверный формат вывода \"%s\", должен быть \"plain\" или \"tar\"\n" -#: pg_basebackup.c:2181 +#: pg_basebackup.c:2200 #, c-format msgid "" -"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\" or \"none" -"\"\n" +"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or " +"\"none\"\n" msgstr "" "%s: неверный аргумент Ð´Ð»Ñ wal-method - \"%s\", допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ \"fetch\", " "\"stream\" или \"none\"\n" -#: pg_basebackup.c:2209 pg_receivewal.c:555 +#: pg_basebackup.c:2228 pg_receivewal.c:556 #, c-format msgid "%s: invalid compression level \"%s\"\n" msgstr "%s: неверный уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ \"%s\"\n" -#: pg_basebackup.c:2221 +#: pg_basebackup.c:2240 #, c-format msgid "" "%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" @@ -730,16 +728,16 @@ msgstr "" "%s: неверный аргумент режима контрольных точек \"%s\", должен быть \"fast\" " "или \"spread\"\n" -#: pg_basebackup.c:2248 pg_receivewal.c:537 pg_recvlogical.c:825 +#: pg_basebackup.c:2267 pg_receivewal.c:538 pg_recvlogical.c:825 #, c-format msgid "%s: invalid status interval \"%s\"\n" msgstr "%s: неверный интервал Ñообщений о ÑоÑтоÑнии \"%s\"\n" -#: pg_basebackup.c:2264 pg_basebackup.c:2278 pg_basebackup.c:2289 -#: pg_basebackup.c:2302 pg_basebackup.c:2312 pg_basebackup.c:2322 -#: pg_basebackup.c:2334 pg_basebackup.c:2348 pg_basebackup.c:2359 -#: pg_receivewal.c:578 pg_receivewal.c:592 pg_receivewal.c:600 -#: pg_receivewal.c:610 pg_receivewal.c:621 pg_recvlogical.c:852 +#: pg_basebackup.c:2283 pg_basebackup.c:2297 pg_basebackup.c:2308 +#: pg_basebackup.c:2321 pg_basebackup.c:2331 pg_basebackup.c:2341 +#: pg_basebackup.c:2353 pg_basebackup.c:2367 pg_basebackup.c:2378 +#: pg_receivewal.c:579 pg_receivewal.c:593 pg_receivewal.c:601 +#: pg_receivewal.c:611 pg_receivewal.c:622 pg_recvlogical.c:852 #: pg_recvlogical.c:866 pg_recvlogical.c:877 pg_recvlogical.c:885 #: pg_recvlogical.c:893 pg_recvlogical.c:901 pg_recvlogical.c:909 #: pg_recvlogical.c:917 pg_recvlogical.c:927 @@ -747,64 +745,61 @@ msgstr "%s: неверный интервал Ñообщений о ÑоÑÑ‚Ð¾Ñ msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_basebackup.c:2276 pg_receivewal.c:590 pg_recvlogical.c:864 +#: pg_basebackup.c:2295 pg_receivewal.c:591 pg_recvlogical.c:864 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: pg_basebackup.c:2288 pg_receivewal.c:620 +#: pg_basebackup.c:2307 pg_receivewal.c:621 #, c-format msgid "%s: no target directory specified\n" msgstr "%s: целевой каталог не указан\n" -#: pg_basebackup.c:2300 +#: pg_basebackup.c:2319 #, c-format msgid "%s: only tar mode backups can be compressed\n" msgstr "%s: Ñжимать можно только резервные копии в архиве tar\n" -#: pg_basebackup.c:2310 +#: pg_basebackup.c:2329 #, c-format -msgid "%s: cannot stream transaction logs in tar mode to stdout\n" +msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" msgstr "" -"%s: транÑлировать журналы транзакций в режиме tar в поток stdout нельзÑ\n" +"%s: транÑлировать журналы предзапиÑи в режиме tar в поток stdout нельзÑ\n" -#: pg_basebackup.c:2320 +#: pg_basebackup.c:2339 #, c-format msgid "%s: replication slots can only be used with WAL streaming\n" msgstr "" "%s: Ñлоты репликации можно иÑпользовать только при потоковой передаче WAL\n" -#: pg_basebackup.c:2332 +#: pg_basebackup.c:2351 #, c-format msgid "%s: --no-slot cannot be used with slot name\n" msgstr "%s: --no-slot Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ñлота\n" -#: pg_basebackup.c:2346 +#: pg_basebackup.c:2365 #, c-format -msgid "" -"%s: transaction log directory location can only be specified in plain mode\n" +msgid "%s: WAL directory location can only be specified in plain mode\n" msgstr "" -"%s: раÑположение каталога журнала транзакций можно указать только в режиме " -"plain\n" +"%s: раÑположение каталога журнала WAL можно указать только в режиме plain\n" -#: pg_basebackup.c:2357 +#: pg_basebackup.c:2376 #, c-format -msgid "%s: transaction log directory location must be an absolute path\n" +msgid "%s: WAL directory location must be an absolute path\n" msgstr "" -"%s: раÑположение каталога журнала транзакций должно определÑтьÑÑ Ð°Ð±Ñолютным " -"путём\n" +"%s: раÑположение каталога журнала WAL должно определÑтьÑÑ Ð°Ð±Ñолютным путём\n" -#: pg_basebackup.c:2369 pg_receivewal.c:630 +#: pg_basebackup.c:2388 pg_receivewal.c:631 #, c-format msgid "%s: this build does not support compression\n" msgstr "%s: Ñта Ñборка программы не поддерживает Ñжатие\n" -#: pg_basebackup.c:2409 +#: pg_basebackup.c:2428 #, c-format msgid "%s: could not create symbolic link \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать ÑимволичеÑкую ÑÑылку \"%s\": %s\n" -#: pg_basebackup.c:2414 +#: pg_basebackup.c:2433 #, c-format msgid "%s: symlinks are not supported on this platform\n" msgstr "%s: ÑимволичеÑкие ÑÑылки не поддерживаютÑÑ Ð² Ñтой ОС\n" @@ -812,10 +807,10 @@ msgstr "%s: ÑимволичеÑкие ÑÑылки не поддерживаю #: pg_receivewal.c:74 #, c-format msgid "" -"%s receives PostgreSQL streaming transaction logs.\n" +"%s receives PostgreSQL streaming write-ahead logs.\n" "\n" msgstr "" -"%s получает транÑлируемые журналы транзакций PostgreSQL.\n" +"%s получает транÑлируемые журналы предзапиÑи PostgreSQL.\n" "\n" #: pg_receivewal.c:78 pg_recvlogical.c:83 @@ -830,12 +825,12 @@ msgstr "" #: pg_receivewal.c:79 #, c-format msgid "" -" -D, --directory=DIR receive transaction log files into this directory\n" +" -D, --directory=DIR receive write-ahead log files into this directory\n" msgstr "" -" -D, --directory=ПУТЬ ÑохранÑть файлы журналов транзакций в данный " +" -D, --directory=ПУТЬ ÑохранÑть файлы журнала предзапиÑи в данный " "каталог\n" -#: pg_receivewal.c:80 pg_recvlogical.c:87 +#: pg_receivewal.c:80 pg_recvlogical.c:88 #, c-format msgid "" " --if-not-exists do not error if slot already exists when creating a " @@ -863,9 +858,9 @@ msgstr "" #: pg_receivewal.c:85 #, c-format msgid "" -" --synchronous flush transaction log immediately after writing\n" +" --synchronous flush write-ahead log immediately after writing\n" msgstr "" -" --synchronous ÑбраÑывать журнал транзакций Ñразу поÑле запиÑи\n" +" --synchronous ÑбраÑывать журнал предзапиÑи Ñразу поÑле запиÑи\n" #: pg_receivewal.c:88 #, c-format @@ -932,7 +927,7 @@ msgstr "%s: не удалоÑÑŒ открыть Ñжатый файл \"%s\": %s\ #: pg_receivewal.c:283 #, c-format -msgid "%s: could not seek compressed file \"%s\": %s\n" +msgid "%s: could not seek in compressed file \"%s\": %s\n" msgstr "%s: ошибка Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² Ñжатом файле \"%s\": %s\n" #: pg_receivewal.c:289 @@ -954,23 +949,23 @@ msgstr "" msgid "%s: starting log streaming at %X/%X (timeline %u)\n" msgstr "%s: начало передачи журнала Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ð¸ %X/%X (Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ %u)\n" -#: pg_receivewal.c:518 pg_recvlogical.c:762 +#: pg_receivewal.c:519 pg_recvlogical.c:762 #, c-format msgid "%s: invalid port number \"%s\"\n" msgstr "%s: неверный номер порта \"%s\"\n" -#: pg_receivewal.c:599 +#: pg_receivewal.c:600 #, c-format msgid "%s: cannot use --create-slot together with --drop-slot\n" msgstr "%s: --create-slot Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½Ñть вмеÑте Ñ --drop-slot\n" #. translator: second %s is an option name -#: pg_receivewal.c:608 +#: pg_receivewal.c:609 #, c-format msgid "%s: %s needs a slot to be specified using --slot\n" msgstr "%s: Ð´Ð»Ñ %s необходимо задать Ñлот Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ параметра --slot\n" -#: pg_receivewal.c:673 +#: pg_receivewal.c:674 #, c-format msgid "" "%s: replication connection using slot \"%s\" is unexpectedly database " @@ -979,23 +974,23 @@ msgstr "" "%s: подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ через Ñлот \"%s\" оказалоÑÑŒ привÑзано к базе " "данных\n" -#: pg_receivewal.c:685 pg_recvlogical.c:967 +#: pg_receivewal.c:686 pg_recvlogical.c:967 #, c-format msgid "%s: dropping replication slot \"%s\"\n" msgstr "%s: удаление Ñлота репликации \"%s\"\n" -#: pg_receivewal.c:698 pg_recvlogical.c:979 +#: pg_receivewal.c:699 pg_recvlogical.c:979 #, c-format msgid "%s: creating replication slot \"%s\"\n" msgstr "%s: Ñоздание Ñлота репликации \"%s\"\n" -#: pg_receivewal.c:725 pg_recvlogical.c:1005 +#: pg_receivewal.c:726 pg_recvlogical.c:1005 #, c-format msgid "%s: disconnected\n" msgstr "%s: отключение\n" #. translator: check source for value for %d -#: pg_receivewal.c:732 pg_recvlogical.c:1012 +#: pg_receivewal.c:733 pg_recvlogical.c:1012 #, c-format msgid "%s: disconnected; waiting %d seconds to try again\n" msgstr "%s: отключение; через %d Ñек. поÑледует повторное подключение\n" @@ -1029,11 +1024,18 @@ msgstr "" #: pg_recvlogical.c:84 #, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr "" +" -E, --endpos=LSN определÑет позицию, поÑле которой нужно " +"оÑтановитьÑÑ\n" + +#: pg_recvlogical.c:85 +#, c-format msgid " -f, --file=FILE receive log into this file, - for stdout\n" msgstr "" " -f, --file=ФÐЙЛ ÑохранÑть журнал в Ñтот файл, - обозначает stdout\n" -#: pg_recvlogical.c:85 +#: pg_recvlogical.c:86 #, c-format msgid "" " -F --fsync-interval=SECS\n" @@ -1044,7 +1046,7 @@ msgstr "" " периодичноÑть ÑброÑа на диÑк выходного файла (по " "умолчанию: %d)\n" -#: pg_recvlogical.c:88 +#: pg_recvlogical.c:89 #, c-format msgid "" " -I, --startpos=LSN where in an existing slot should the streaming " @@ -1053,13 +1055,6 @@ msgstr "" " -I, --startpos=LSN определÑет, Ñ ÐºÐ°ÐºÐ¾Ð¹ позиции в ÑущеÑтвующем Ñлоте " "начнётÑÑ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð°\n" -#: pg_recvlogical.c:89 -#, c-format -msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" -msgstr "" -" -E, --endpos=LSN определÑет позицию, поÑле которой нужно " -"оÑтановитьÑÑ\n" - #: pg_recvlogical.c:91 #, c-format msgid "" @@ -1095,7 +1090,7 @@ msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" msgstr "" "%s: подтверждаетÑÑ Ð·Ð°Ð¿Ð¸ÑÑŒ до %X/%X, ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ð¤Ð¡ до %X/%X (Ñлот %s)\n" -#: pg_recvlogical.c:160 receivelog.c:345 +#: pg_recvlogical.c:160 receivelog.c:351 #, c-format msgid "%s: could not send feedback packet: %s" msgstr "%s: не удалоÑÑŒ отправить пакет отзыва: %s" @@ -1120,28 +1115,28 @@ msgstr "%s: передача запущена\n" msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть файл журнала \"%s\": %s\n" -#: pg_recvlogical.c:376 receivelog.c:896 +#: pg_recvlogical.c:376 receivelog.c:914 #, c-format msgid "%s: invalid socket: %s" msgstr "%s: неверный Ñокет: %s" -#: pg_recvlogical.c:430 receivelog.c:918 +#: pg_recvlogical.c:430 receivelog.c:943 #, c-format msgid "%s: select() failed: %s\n" msgstr "%s: ошибка в select(): %s\n" -#: pg_recvlogical.c:439 receivelog.c:968 +#: pg_recvlogical.c:439 receivelog.c:995 #, c-format msgid "%s: could not receive data from WAL stream: %s" msgstr "%s: не удалоÑÑŒ получить данные из потока WAL: %s" -#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1013 -#: receivelog.c:1080 +#: pg_recvlogical.c:481 pg_recvlogical.c:533 receivelog.c:1040 +#: receivelog.c:1107 #, c-format msgid "%s: streaming header too small: %d\n" msgstr "%s: заголовок потока Ñлишком мал: %d\n" -#: pg_recvlogical.c:517 receivelog.c:861 +#: pg_recvlogical.c:517 receivelog.c:874 #, c-format msgid "%s: unrecognized streaming header: \"%c\"\n" msgstr "%s: нераÑпознанный заголовок потока: \"%c\"\n" @@ -1151,7 +1146,7 @@ msgstr "%s: нераÑпознанный заголовок потока: \"%c\" msgid "%s: could not write %u bytes to log file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать %u байт в файл журнала \"%s\": %s\n" -#: pg_recvlogical.c:617 receivelog.c:654 receivelog.c:692 +#: pg_recvlogical.c:617 receivelog.c:667 receivelog.c:705 #, c-format msgid "%s: unexpected termination of replication stream: %s" msgstr "%s: неожиданный конец потока репликации: %s" @@ -1214,61 +1209,74 @@ msgstr "" "%s: не удалоÑÑŒ уÑтановить подключение Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸ к определённой базе " "данных\n" -#: receivelog.c:70 +#: receivelog.c:71 #, c-format msgid "%s: could not create archive status file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл ÑтатуÑа архива \"%s\": %s\n" -#: receivelog.c:118 +#: receivelog.c:119 #, c-format -msgid "%s: could not get size of transaction log file \"%s\": %s\n" -msgstr "%s: не удалоÑÑŒ получить размер файла журнала транзакций \"%s\": %s\n" +msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" +msgstr "%s: не удалоÑÑŒ получить размер файла журнала предзапиÑи \"%s\": %s\n" -#: receivelog.c:129 +#: receivelog.c:130 #, c-format -msgid "%s: could not open existing transaction log file \"%s\": %s\n" +msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" msgstr "" -"%s: не удалоÑÑŒ открыть ÑущеÑтвующий файл журнала транзакций \"%s\": %s\n" +"%s: не удалоÑÑŒ открыть ÑущеÑтвующий файл журнала предзапиÑи \"%s\": %s\n" -#: receivelog.c:150 +#: receivelog.c:139 #, c-format -msgid "%s: transaction log file \"%s\" has %d bytes, should be 0 or %d\n" +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" msgstr "" -"%s: файл журнала транзакций \"%s\" имеет размер %d Б, а должен - 0 или %d\n" +"%s: не удалоÑÑŒ ÑброÑить на диÑк ÑущеÑтвующий файл журнала предзапиÑи \"%s\": " +"%s\n" -#: receivelog.c:163 +#: receivelog.c:154 #, c-format -msgid "%s: could not open transaction log file \"%s\": %s\n" -msgstr "%s: не удалоÑÑŒ открыть файл журнала транзакций \"%s\": %s\n" +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "" +"%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "" +"%s: файл журнала предзапиÑи \"%s\" имеет размер %d Б, а должен - 0 или %d\n" +msgstr[1] "" +"%s: файл журнала предзапиÑи \"%s\" имеет размер %d Б, а должен - 0 или %d\n" +msgstr[2] "" +"%s: файл журнала предзапиÑи \"%s\" имеет размер %d Б, а должен - 0 или %d\n" -#: receivelog.c:190 +#: receivelog.c:169 +#, c-format +msgid "%s: could not open write-ahead log file \"%s\": %s\n" +msgstr "%s: не удалоÑÑŒ открыть файл журнала предзапиÑи \"%s\": %s\n" + +#: receivelog.c:196 #, c-format msgid "%s: could not determine seek position in file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ определить текущую позицию в файле \"%s\": %s\n" -#: receivelog.c:205 +#: receivelog.c:211 #, c-format msgid "%s: not renaming \"%s%s\", segment is not complete\n" msgstr "" "%s: файл \"%s%s\" не переименовываетÑÑ, так как Ñто не полный Ñегмент\n" -#: receivelog.c:274 +#: receivelog.c:280 #, c-format msgid "%s: server reported unexpected history file name for timeline %u: %s\n" msgstr "" "%s: Ñервер Ñообщил неожиданное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° иÑтории Ð´Ð»Ñ Ð»Ð¸Ð½Ð¸Ð¸ времени %u: %s\n" -#: receivelog.c:282 +#: receivelog.c:288 #, c-format msgid "%s: could not create timeline history file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл иÑтории линии времени \"%s\": %s\n" -#: receivelog.c:289 +#: receivelog.c:295 #, c-format msgid "%s: could not write timeline history file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл иÑтории линии времени \"%s\": %s\n" -#: receivelog.c:379 +#: receivelog.c:385 #, c-format msgid "" "%s: incompatible server version %s; client does not support streaming from " @@ -1277,7 +1285,7 @@ msgstr "" "%s: неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ñервера %s; клиент не поддерживает репликацию Ñ " "Ñерверов верÑии ниже %s\n" -#: receivelog.c:389 +#: receivelog.c:395 #, c-format msgid "" "%s: incompatible server version %s; client does not support streaming from " @@ -1286,7 +1294,7 @@ msgstr "" "%s: неÑовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ñервера %s; клиент не поддерживает репликацию Ñ " "Ñерверов верÑии выше %s\n" -#: receivelog.c:487 streamutil.c:264 streamutil.c:303 +#: receivelog.c:500 streamutil.c:265 streamutil.c:304 #, c-format msgid "" "%s: could not identify system: got %d rows and %d fields, expected %d rows " @@ -1295,7 +1303,7 @@ msgstr "" "%s: не удалоÑÑŒ идентифицировать ÑиÑтему, получено Ñтрок: %d, полей: %d " "(ожидалоÑÑŒ: %d и %d (или более))\n" -#: receivelog.c:495 +#: receivelog.c:508 #, c-format msgid "" "%s: system identifier does not match between base backup and streaming " @@ -1304,17 +1312,17 @@ msgstr "" "%s: ÑиÑтемный идентификатор базовой резервной копии отличаетÑÑ Ð¾Ñ‚ " "идентификатора потоковой передачи\n" -#: receivelog.c:503 +#: receivelog.c:516 #, c-format msgid "%s: starting timeline %u is not present in the server\n" msgstr "%s: на Ñервере нет начальной линии времени %u\n" -#: receivelog.c:522 +#: receivelog.c:535 #, c-format msgid "%s: could not create temporary replication slot \"%s\": %s" msgstr "%s: не удалоÑÑŒ Ñоздать временный Ñлот репликации \"%s\": %s" -#: receivelog.c:563 +#: receivelog.c:576 #, c-format msgid "" "%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d " @@ -1323,14 +1331,14 @@ msgstr "" "%s: Ñервер вернул неожиданный ответ на команду TIMELINE_HISTORY; получено " "Ñтрок: %d, полей: %d, а ожидалоÑÑŒ Ñтрок: %d, полей: %d\n" -#: receivelog.c:635 +#: receivelog.c:648 #, c-format msgid "" "%s: server reported unexpected next timeline %u, following timeline %u\n" msgstr "" "%s: Ñервер неожиданно Ñообщил линию времени %u поÑле линии времени %u\n" -#: receivelog.c:642 +#: receivelog.c:655 #, c-format msgid "" "%s: server stopped streaming timeline %u at %X/%X, but reported next " @@ -1339,12 +1347,12 @@ msgstr "" "%s: Ñервер прекратил передачу линии времени %u в %X/%X, но Ñообщил, что " "ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð»Ð¸Ð½Ð¸Ð¸ времени %u начнётÑÑ Ð² %X/%X\n" -#: receivelog.c:683 +#: receivelog.c:696 #, c-format msgid "%s: replication stream was terminated before stop point\n" msgstr "%s: поток репликации закончилÑÑ Ð´Ð¾ точки оÑтанова\n" -#: receivelog.c:732 +#: receivelog.c:745 #, c-format msgid "" "%s: unexpected result set after end-of-timeline: got %d rows and %d fields, " @@ -1353,59 +1361,59 @@ msgstr "" "%s: Ñервер вернул неожиданный набор данных поÑле конца линии времени - " "получено Ñтрок: %d, полей: %d, а ожидалоÑÑŒ Ñтрок: %d, полей: %d\n" -#: receivelog.c:742 +#: receivelog.c:755 #, c-format msgid "%s: could not parse next timeline's starting point \"%s\"\n" msgstr "" "%s: не удалоÑÑŒ разобрать начальную точку Ñледующей линии времени \"%s\"\n" -#: receivelog.c:1099 +#: receivelog.c:1126 #, c-format -msgid "%s: received transaction log record for offset %u with no file open\n" +msgid "%s: received write-ahead log record for offset %u with no file open\n" msgstr "" -"%s: получена запиÑÑŒ журнала транзакций по Ñмещению %u, но файл не открыт\n" +"%s: получена запиÑÑŒ журнала предзапиÑи по Ñмещению %u, но файл не открыт\n" -#: receivelog.c:1110 +#: receivelog.c:1137 #, c-format msgid "%s: got WAL data offset %08x, expected %08x\n" msgstr "%s: получено Ñмещение данных WAL %08x, но ожидалоÑÑŒ %08x\n" -#: receivelog.c:1145 +#: receivelog.c:1172 #, c-format msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать %u байт в файл WAL \"%s\": %s\n" -#: receivelog.c:1170 receivelog.c:1211 receivelog.c:1242 +#: receivelog.c:1197 receivelog.c:1238 receivelog.c:1269 #, c-format msgid "%s: could not send copy-end packet: %s" msgstr "%s: не удалоÑÑŒ отправить пакет \"конец COPY\": %s" -#: streamutil.c:148 +#: streamutil.c:149 msgid "Password: " msgstr "Пароль: " -#: streamutil.c:173 +#: streamutil.c:174 #, c-format msgid "%s: could not connect to server\n" msgstr "%s: не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу\n" -#: streamutil.c:191 +#: streamutil.c:192 #, c-format msgid "%s: could not connect to server: %s" msgstr "%s: не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу: %s" -#: streamutil.c:215 +#: streamutil.c:216 #, c-format msgid "%s: could not determine server setting for integer_datetimes\n" msgstr "%s: не удалоÑÑŒ получить наÑтройку Ñервера integer_datetimes\n" -#: streamutil.c:224 +#: streamutil.c:225 #, c-format msgid "%s: integer_datetimes compile flag does not match server\n" msgstr "" "%s: флаг компилÑции integer_datetimes не ÑоответÑтвует наÑтройке Ñервера\n" -#: streamutil.c:375 +#: streamutil.c:376 #, c-format msgid "" "%s: could not create replication slot \"%s\": got %d rows and %d fields, " @@ -1414,7 +1422,7 @@ msgstr "" "%s: не удалоÑÑŒ Ñоздать Ñлот репликации \"%s\"; получено Ñтрок: %d, полей: %d " "(ожидалоÑÑŒ: %d и %d)\n" -#: streamutil.c:420 +#: streamutil.c:421 #, c-format msgid "" "%s: could not drop replication slot \"%s\": got %d rows and %d fields, " @@ -1423,6 +1431,59 @@ msgstr "" "%s: не удалоÑÑŒ удалить Ñлот репликации \"%s\"; получено Ñтрок: %d, полей: %d " "(ожидалоÑÑŒ: %d и %d)\n" +#: walmethods.c:435 walmethods.c:904 +msgid "could not compress data" +msgstr "не удалоÑÑŒ Ñжать данные" + +#: walmethods.c:459 +msgid "could not reset compression stream" +msgstr "не удалоÑÑŒ ÑброÑить поток Ñжатых данных" + +#: walmethods.c:560 +msgid "could not initialize compression library" +msgstr "не удалоÑÑŒ инициализировать библиотеку ÑжатиÑ" + +#: walmethods.c:572 +msgid "implementation error: tar files can't have more than one open file" +msgstr "" +"ошибка реализации: в файлах tar не может быть больше одно открытого файла" + +#: walmethods.c:586 +msgid "could not create tar header" +msgstr "не удалоÑÑŒ Ñоздать заголовок tar" + +#: walmethods.c:600 walmethods.c:638 walmethods.c:827 walmethods.c:838 +msgid "could not change compression parameters" +msgstr "не удалоÑÑŒ изменить параметры ÑжатиÑ" + +#: walmethods.c:720 +msgid "unlink not supported with compression" +msgstr "Ñо Ñжатием закрытие файла Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸ÐµÐ¼ не поддерживаетÑÑ" + +#: walmethods.c:920 +msgid "could not close compression stream" +msgstr "не удалоÑÑŒ закрыть поток Ñжатых данных" + +#~ msgid "%s: removing transaction log directory \"%s\"\n" +#~ msgstr "%s: удаление каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove transaction log directory\n" +#~ msgstr "%s: ошибка при удалении каталога журнала транзакций\n" + +#~ msgid "%s: removing contents of transaction log directory \"%s\"\n" +#~ msgstr "%s: очиÑтка каталога журнала транзакций \"%s\"\n" + +#~ msgid "%s: failed to remove contents of transaction log directory\n" +#~ msgstr "%s: ошибка при очиÑтке каталога журнала транзакций\n" + +#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n" +#~ msgstr "" +#~ "%s: каталог журнала транзакций \"%s\" не был удалён по запроÑу " +#~ "пользователÑ\n" + +#~ msgid "%s: could not open transaction log file \"%s\": %s\n" +#~ msgstr "%s: не удалоÑÑŒ открыть файл журнала транзакций \"%s\": %s\n" + #~ msgid "" #~ " -x, --xlog include required WAL files in backup (fetch " #~ "mode)\n" @@ -1516,6 +1577,3 @@ msgstr "" #~ msgid "%s: could not get current position in file %s: %s\n" #~ msgstr "%s: не удалоÑÑŒ получить текущую позицию в файле %s: %s\n" - -#~ msgid "%s: could not read copy data: %s\n" -#~ msgstr "%s: не удалоÑÑŒ прочитать данные COPY: %s\n" diff --git a/src/bin/pg_basebackup/po/sv.po b/src/bin/pg_basebackup/po/sv.po new file mode 100644 index 00000000000..3e155201867 --- /dev/null +++ b/src/bin/pg_basebackup/po/sv.po @@ -0,0 +1,1572 @@ +# SWEDISH message translation file for pg_basebackup +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Dennis Björklund , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-27 17:46+0000\n" +"PO-Revision-Date: 2019-04-28 22:26+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: SWEDISH \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "slut pÃ¥ minne\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "kan inte duplicera null-pekare (internt fel)\n" + +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#: pg_receivewal.c:267 pg_recvlogical.c:342 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" + +#: ../../common/file_utils.c:160 pg_receivewal.c:170 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" + +#: ../../common/file_utils.c:194 pg_receivewal.c:338 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" + +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 pg_basebackup.c:1761 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" + +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#: pg_recvlogical.c:195 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "kunde inte fsync:a fil \"%s\": %m" + +#: ../../common/file_utils.c:377 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m" + +#: pg_basebackup.c:171 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "tar bort datakatalog \"%s\"" + +#: pg_basebackup.c:173 +#, c-format +msgid "failed to remove data directory" +msgstr "misslyckades med att ta bort datakatalog" + +#: pg_basebackup.c:177 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "tar bort innehÃ¥llet i datakatalog \"%s\"" + +#: pg_basebackup.c:179 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "misslyckades med att ta bort innehÃ¥llet i datakatalogen" + +#: pg_basebackup.c:184 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "tar bort WAL-katalog \"%s\"" + +#: pg_basebackup.c:186 +#, c-format +msgid "failed to remove WAL directory" +msgstr "misslyckades med att ta bort WAL-katalog" + +#: pg_basebackup.c:190 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "tar bort innehÃ¥llet i WAL-katalog \"%s\"" + +#: pg_basebackup.c:192 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "misslyckades med att ta bort innehÃ¥llet i WAL-katalogen" + +#: pg_basebackup.c:198 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "datakatalog \"%s\" är ej borttagen pÃ¥ användares begäran" + +#: pg_basebackup.c:201 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "WAL-katalog \"%s\" är ej borttagen pÃ¥ användares begäran" + +#: pg_basebackup.c:205 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "ändringar av tablespace-kataloger kan inte backas" + +#: pg_basebackup.c:246 +#, c-format +msgid "directory name too long" +msgstr "katalognamn för lÃ¥ngt" + +#: pg_basebackup.c:256 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "multipla \"=\"-tecken i tablespace-mappning" + +#: pg_basebackup.c:268 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "ogiltigt tablespace-mappningsformat \"%s\", mÃ¥ste vara \"OLDDIR=NEWDIR\"" + +#: pg_basebackup.c:280 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "gammal katalog är inte en absolut sökväg i tablespace-mappning: %s" + +#: pg_basebackup.c:287 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "ny katalog är inte en absolut sökväg i tablespace-mappning: %s" + +#: pg_basebackup.c:326 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s tar en basbackup av en körande PostgreSQL-server.\n" +"\n" + +#: pg_basebackup.c:328 pg_receivewal.c:81 pg_recvlogical.c:78 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: pg_basebackup.c:329 pg_receivewal.c:82 pg_recvlogical.c:79 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [FLAGGA]...\n" + +#: pg_basebackup.c:330 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Flaggor som styr utmatning:\n" + +#: pg_basebackup.c:331 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=KATALOG ta emot basbackup till katalog\n" + +#: pg_basebackup.c:332 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t utdataformat (plain (standard), tar)\n" + +#: pg_basebackup.c:333 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=RATE maximal överföringshastighet för att överföra datakatalog\n" +" (i kB/s, eller använd suffix \"k\" resp. \"M\")\n" + +#: pg_basebackup.c:335 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" skriv konfiguration för replikering\n" + +#: pg_basebackup.c:337 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=GAMMALKAT=NYKAT\n" +" flytta tablespace i GAMMALKAT till NYKAT\n" + +#: pg_basebackup.c:339 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALKAT plats för write-ahead-logg-katalog\n" + +#: pg_basebackup.c:340 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" inkludera behövda WAL-filer med angiven metod\n" + +#: pg_basebackup.c:342 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip komprimera tar-utdata\n" + +#: pg_basebackup.c:343 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 komprimera tar-utdata med given komprimeringsnivÃ¥\n" + +#: pg_basebackup.c:344 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Allmänna flaggor:\n" + +#: pg_basebackup.c:345 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" ställ in \"fast\" eller \"spread\" checkpoint-metod\n" + +#: pg_basebackup.c:347 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " --create-slot skapa en replikeringsslot\n" + +#: pg_basebackup.c:348 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=ETIKETT sätt backup-etikett\n" + +#: pg_basebackup.c:349 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean städa inte upp efter fel\n" + +#: pg_basebackup.c:350 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync vänta inte pÃ¥ att ändringar skall skrivas säkert till disk\n" + +#: pg_basebackup.c:351 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress visa förloppsinformation\n" + +#: pg_basebackup.c:352 pg_receivewal.c:91 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=SLOTNAMN replikerings-slot att använda\n" + +#: pg_basebackup.c:353 pg_receivewal.c:93 pg_recvlogical.c:99 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose mata ut utförliga meddelanden\n" + +#: pg_basebackup.c:354 pg_receivewal.c:94 pg_recvlogical.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: pg_basebackup.c:355 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot förhindra skapande av temporär replikerings-slot\n" + +#: pg_basebackup.c:356 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" verifiera inte checksummor\n" + +#: pg_basebackup.c:358 pg_receivewal.c:96 pg_recvlogical.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" + +#: pg_basebackup.c:359 pg_receivewal.c:97 pg_recvlogical.c:102 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Flaggor för anslutning:\n" + +#: pg_basebackup.c:360 pg_receivewal.c:98 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR anslutningssträng\n" + +#: pg_basebackup.c:361 pg_receivewal.c:99 pg_recvlogical.c:104 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAMN databasserverns värdnamn eller socket-katalog\n" + +#: pg_basebackup.c:362 pg_receivewal.c:100 pg_recvlogical.c:105 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT databasserverns postnummer\n" + +#: pg_basebackup.c:363 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=INTERVAL\n" +" tid mellan att statuspaket skickas till servern (i sekunder)\n" + +#: pg_basebackup.c:365 pg_receivewal.c:101 pg_recvlogical.c:106 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=NAMN ansluta som angiven databasanvändare\n" + +#: pg_basebackup.c:366 pg_receivewal.c:102 pg_recvlogical.c:107 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password frÃ¥ga aldrig efter lösenord\n" + +#: pg_basebackup.c:367 pg_receivewal.c:103 pg_recvlogical.c:108 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password tvinga fram lösenordsfrÃ¥ga (skall ske automatiskt)\n" + +#: pg_basebackup.c:368 pg_receivewal.c:107 pg_recvlogical.c:109 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Rapportera fel till .\n" + +#: pg_basebackup.c:411 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "kunde inte läsa frÃ¥n rör (pipe) som har data: %m" + +#: pg_basebackup.c:417 pg_basebackup.c:545 pg_basebackup.c:2099 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "kunde inte parsa write-ahead-logg-plats \"%s\"" + +#: pg_basebackup.c:510 pg_receivewal.c:442 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "kunde inte slutföra skrivning av WAL-filer: %m" + +#: pg_basebackup.c:557 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "kunde inte skapa rör (pipe) för bakgrundsprocess: %m" + +#: pg_basebackup.c:592 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "skapade en temporär replikeringsslot \"%s\"" + +#: pg_basebackup.c:595 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "skapade en replikeringsslot \"%s\"" + +#: pg_basebackup.c:615 pg_basebackup.c:668 pg_basebackup.c:1503 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" + +#: pg_basebackup.c:633 +#, c-format +msgid "could not create background process: %m" +msgstr "kunde inte skapa bakgrundsprocess: %m" + +#: pg_basebackup.c:645 +#, c-format +msgid "could not create background thread: %m" +msgstr "kunde inte skapa bakgrundstrÃ¥d: %m" + +#: pg_basebackup.c:689 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "katalogen \"%s\" existerar men är inte tom" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "kunde inte komma Ã¥t katalog \"%s\": %m" + +#: pg_basebackup.c:757 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgstr[1] "%*s/%s kB (100%%), %d/%d tablespace %*s" + +#: pg_basebackup.c:769 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" + +#: pg_basebackup.c:785 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" +msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace" + +#: pg_basebackup.c:809 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "överföringshastighet \"%s\" är inte ett giltigt värde" + +#: pg_basebackup.c:814 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "ogiltig överföringshastighet \"%s\": %m" + +#: pg_basebackup.c:823 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "överföringshastigheten mÃ¥ste vara större än noll" + +#: pg_basebackup.c:855 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "ogiltig enhet för --max-rate: \"%s\"" + +#: pg_basebackup.c:862 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "överföringshastighet \"%s\" överskrider heltalsintervall" + +#: pg_basebackup.c:872 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "överföringshastighet \"%s\" är utanför sitt intervall" + +#: pg_basebackup.c:894 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "kunde inte skriva till komprimerad fil \"%s\": %s" + +#: pg_basebackup.c:904 pg_basebackup.c:1592 pg_basebackup.c:1767 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "kunde inte skriva till fil \"%s\": %m" + +#: pg_basebackup.c:969 pg_basebackup.c:989 pg_basebackup.c:1016 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "kunde inte sätta komprimeringsnivÃ¥ %d: %s" + +#: pg_basebackup.c:1036 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "kunde inte skapa komprimerad fil \"%s\": %s" + +#: pg_basebackup.c:1047 pg_basebackup.c:1553 pg_basebackup.c:1779 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "kunde inte skapa fil \"%s\": %m" + +#: pg_basebackup.c:1058 pg_basebackup.c:1412 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "kunde inte hämta COPY-data-ström: %s" + +#: pg_basebackup.c:1143 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "kunde inte stänga komprimerad fil \"%s\": %s" + +#: pg_basebackup.c:1155 pg_recvlogical.c:608 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: pg_basebackup.c:1166 pg_basebackup.c:1441 pg_recvlogical.c:437 +#: receivelog.c:968 +#, c-format +msgid "could not read COPY data: %s" +msgstr "kunde inte läsa COPY-data: %s" + +#: pg_basebackup.c:1455 +#, c-format +msgid "invalid tar block header size: %d" +msgstr "ogiltig tar-block-header-storlek: %d" + +#: pg_basebackup.c:1510 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "kunde inte sätta rättigheter pÃ¥ katalogen \"%s\": %m" + +#: pg_basebackup.c:1533 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "kunde inte skapa symbolisk länk frÃ¥n \"%s\" till \"%s\": %m" + +#: pg_basebackup.c:1540 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "okänd länkindikator \"%c\"" + +#: pg_basebackup.c:1559 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "kunde inte sätta rättigheter pÃ¥ filen \"%s\": %m" + +#: pg_basebackup.c:1616 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "COPY-ström avslutade innan sista filen var klar" + +#: pg_basebackup.c:1643 pg_basebackup.c:1663 pg_basebackup.c:1677 +#: pg_basebackup.c:1728 +#, c-format +msgid "out of memory" +msgstr "slut pÃ¥ minne" + +#: pg_basebackup.c:1820 +#, c-format +msgid "incompatible server version %s" +msgstr "inkompatibel serverversion %s" + +#: pg_basebackup.c:1835 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "TIPS: använd -X none eller -X fetch för att stänga av logg-strömning" + +#: pg_basebackup.c:1860 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "initierar basbackup, väntar pÃ¥ att checkpoint skall gÃ¥ klart" + +#: pg_basebackup.c:1884 pg_recvlogical.c:264 receivelog.c:484 receivelog.c:533 +#: receivelog.c:572 streamutil.c:299 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "kunde inte skicka replikeringskommando \"%s\": %s" + +#: pg_basebackup.c:1895 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "kunde inte initiera basbackup: %s" + +#: pg_basebackup.c:1901 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "servern retunerade ett oväntat svar pÃ¥ BASE_BACKUP-kommandot; fick %d rader och %d fält, förväntade %d rader och %d fält" + +#: pg_basebackup.c:1909 +#, c-format +msgid "checkpoint completed" +msgstr "checkpoint klar" + +#: pg_basebackup.c:1924 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "write-ahead-loggens startposition: %s pÃ¥ tidslinje %u" + +#: pg_basebackup.c:1933 +#, c-format +msgid "could not get backup header: %s" +msgstr "kunde inte hämta backup-header: %s" + +#: pg_basebackup.c:1939 +#, c-format +msgid "no data returned from server" +msgstr "ingen data returnerades frÃ¥n servern" + +#: pg_basebackup.c:1970 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "kunde bara skriva en endaste tablespace till stdout, databasen har %d" + +#: pg_basebackup.c:1982 +#, c-format +msgid "starting background WAL receiver" +msgstr "startar bakgrunds-WAL-mottagare" + +#: pg_basebackup.c:2012 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "kunde inte hämta write-ahead-loggens slutposition frÃ¥n servern: %s" + +#: pg_basebackup.c:2018 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "ingen write-ahead-logg-slutposition returnerad frÃ¥n servern" + +#: pg_basebackup.c:2023 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "write-ahead-logg-slutposition: %s" + +#: pg_basebackup.c:2034 +#, c-format +msgid "checksum error occurred" +msgstr "felaktig kontrollsumma upptäcktes" + +#: pg_basebackup.c:2039 +#, c-format +msgid "final receive failed: %s" +msgstr "sista mottagning misslyckades: %s" + +#: pg_basebackup.c:2063 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "väntat pÃ¥ att bakgrundsprocess skall avsluta strömmande ..." + +#: pg_basebackup.c:2068 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "kunde inte skicka kommando till bakgrundsrör (pipe): %m" + +#: pg_basebackup.c:2076 +#, c-format +msgid "could not wait for child process: %m" +msgstr "kunde inte vänta pÃ¥ barnprocess: %m" + +#: pg_basebackup.c:2081 +#, c-format +msgid "child %d died, expected %d" +msgstr "barn %d dog, förväntade %d" + +#: pg_basebackup.c:2086 streamutil.c:94 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2111 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "kunde inte vänta pÃ¥ barntrÃ¥d: %m" + +#: pg_basebackup.c:2117 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "kunde inte hämta barntrÃ¥dens slutstatus: %m" + +#: pg_basebackup.c:2122 +#, c-format +msgid "child thread exited with error %u" +msgstr "barntrÃ¥d avslutade med fel %u" + +#: pg_basebackup.c:2150 +#, c-format +msgid "syncing data to disk ..." +msgstr "synkar data till disk ..." + +#: pg_basebackup.c:2163 +#, c-format +msgid "base backup completed" +msgstr "basbackup klar" + +#: pg_basebackup.c:2244 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "ogiltigt utdataformat \"%s\", mÃ¥ste vara \"plain\" eller \"tar\"\n" + +#: pg_basebackup.c:2288 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "ogiltig wal-metod-flagga \"%s\", mÃ¥ste vara \"fetch\", \"stream\" eller \"none\"" + +#: pg_basebackup.c:2316 +#, c-format +msgid "invalid compression level \"%s\"\n" +msgstr "ogiltig komprimeringsnivÃ¥ \"%s\"\n" + +#: pg_basebackup.c:2327 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "ogiltigt checkpoint-argument \"%s\", mÃ¥ste vara \"fast\" eller \"spread\"" + +#: pg_basebackup.c:2354 pg_receivewal.c:556 pg_recvlogical.c:796 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "ogiltigt status-intervall \"%s\"" + +#: pg_basebackup.c:2372 pg_basebackup.c:2385 pg_basebackup.c:2396 +#: pg_basebackup.c:2407 pg_basebackup.c:2415 pg_basebackup.c:2423 +#: pg_basebackup.c:2433 pg_basebackup.c:2446 pg_basebackup.c:2454 +#: pg_basebackup.c:2465 pg_basebackup.c:2475 pg_receivewal.c:606 +#: pg_receivewal.c:619 pg_receivewal.c:627 pg_receivewal.c:637 +#: pg_receivewal.c:645 pg_receivewal.c:656 pg_recvlogical.c:822 +#: pg_recvlogical.c:835 pg_recvlogical.c:846 pg_recvlogical.c:854 +#: pg_recvlogical.c:862 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: pg_basebackup.c:2383 pg_receivewal.c:617 pg_recvlogical.c:833 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" + +#: pg_basebackup.c:2395 pg_receivewal.c:655 +#, c-format +msgid "no target directory specified" +msgstr "ingen mÃ¥lkatalog angiven" + +#: pg_basebackup.c:2406 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "bara backupper i tar-läge kan komprimeras" + +#: pg_basebackup.c:2414 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "kan inte strömma write-ahead-logg i tar-läge till stdout" + +#: pg_basebackup.c:2422 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "replikerings-slot kan bara användas med WAL-strömning" + +#: pg_basebackup.c:2432 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot kan inte användas tillsammans med slot-namn" + +#. translator: second %s is an option name +#: pg_basebackup.c:2444 pg_receivewal.c:635 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "%s kräver att en slot anges med --slot" + +#: pg_basebackup.c:2453 +#, c-format +msgid "--create-slot and --no-slot are incompatible options" +msgstr "--create-slot och --no-slot är inkompatibla flaggor" + +#: pg_basebackup.c:2464 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "WAL-katalogplats kan bara anges i läget \"plain\"" + +#: pg_basebackup.c:2474 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL-katalogen mÃ¥ste vara en absolut sökväg" + +#: pg_basebackup.c:2484 pg_receivewal.c:664 +#, c-format +msgid "this build does not support compression" +msgstr "detta bygge stöder inte komprimering" + +#: pg_basebackup.c:2538 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "kan inte skapa symbolisk länk \"%s\": %m" + +#: pg_basebackup.c:2542 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "symboliska länkar stöds inte pÃ¥ denna plattform" + +#: pg_receivewal.c:79 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s tar emot PostgreSQL-strömning-write-ahead-logg.\n" +"\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:84 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Flaggor:\n" + +#: pg_receivewal.c:84 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=KAT ta emot write-ahead-logg-filer till denna katalog\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:85 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr " -E, --endpos=LSN avsluta efter att ha taget emot den angivna LSN\n" + +#: pg_receivewal.c:86 pg_recvlogical.c:89 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr " --if-not-exists inget fel om slot:en redan finns när vi skapar slot:en\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:91 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop loopa inte om anslutning tappas\n" + +#: pg_receivewal.c:88 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync vänta inte pÃ¥ att ändringar skall skrivas säkert till disk\n" + +#: pg_receivewal.c:89 pg_recvlogical.c:96 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SEKS\n" +" tid mellan att statuspaket skickas till serverb (standard: %d)\n" + +#: pg_receivewal.c:92 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous flush:a write-ahead-logg direkt efter skrivning\n" + +#: pg_receivewal.c:95 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 komprimera loggar med angiven komprimeringsnivÃ¥\n" + +#: pg_receivewal.c:104 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Valfria handlingar:\n" + +#: pg_receivewal.c:105 pg_recvlogical.c:81 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr " --create-slot skapa en ny replikeringsslot (angÃ¥ende slot:ens namn, se --slot)\n" + +#: pg_receivewal.c:106 pg_recvlogical.c:82 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr " --drop-slot släng replikeringsslot (angÃ¥ende slot:ens namn, se --slot)\n" + +#: pg_receivewal.c:118 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "slutförde segment vid %X/%X (tidslinje %u)" + +#: pg_receivewal.c:125 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "stoppade logg-strömning vid %X/%X (tidslinje %u)" + +#: pg_receivewal.c:141 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "bytte till tidslinje %u vid %X/%X" + +#: pg_receivewal.c:151 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "mottog avbrottsignal, avslutar" + +#: pg_receivewal.c:187 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" + +#: pg_receivewal.c:273 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "segmentfil \"%s\" har inkorrekt storlek %d, hoppar över" + +#: pg_receivewal.c:291 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "kunde inte öppna komprimerad fil \"%s\": %m" + +#: pg_receivewal.c:297 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "kunde inte söka i komprimerad fil \"%s\": %m" + +#: pg_receivewal.c:305 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "kunde inte läsa komprimerad fil \"%s\": %m" + +#: pg_receivewal.c:308 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "kunde inte läsa komprimerad fil \"%s\": läste %d av %zu" + +#: pg_receivewal.c:319 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "komprimerad segmentfil \"%s\" har inkorrekt okomprimerad storlek %d, hoppar över" + +#: pg_receivewal.c:423 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "startar logg-strömning vid %X/%X (tidslinje %u)" + +#: pg_receivewal.c:538 pg_recvlogical.c:738 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "ogiltigt portnummer \"%s\"" + +#: pg_receivewal.c:566 pg_recvlogical.c:764 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "kunde inte parsa slutposition \"%s\"" + +#: pg_receivewal.c:581 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "ogiltig komprimeringsnivÃ¥ \"%s\"" + +#: pg_receivewal.c:626 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "kan inte använda --create-slot tillsammans med --drop-slot" + +#: pg_receivewal.c:644 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "kan inte använda --synchronous tillsammans med --no-sync" + +#: pg_receivewal.c:720 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "replikeringsanslutning som använder slot \"%s\" är oväntat databasspecifik" + +#: pg_receivewal.c:731 pg_recvlogical.c:942 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "slänger replikeringsslot \"%s\"" + +#: pg_receivewal.c:742 pg_recvlogical.c:952 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "skapar replikeringsslot \"%s\"" + +#: pg_receivewal.c:768 pg_recvlogical.c:977 +#, c-format +msgid "disconnected" +msgstr "nerkopplad" + +#. translator: check source for value for %d +#: pg_receivewal.c:774 pg_recvlogical.c:983 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "nerkopplad; väntar %d sekunder för att försöka igen" + +#: pg_recvlogical.c:76 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s styr PostgreSQL:s logiskt avkodade strömmar.\n" +"\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Handling att utföra:\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr " --start starta strömning i en replikeringsslot (angÃ¥ende slot:ens namn, se --slot)\n" + +#: pg_recvlogical.c:86 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=FIL ta emot logg till denna fil, - för stdout\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F --fsync-interval=SEK\n" +" tid mellan fsync av utdatafil (standard: %d)\n" + +#: pg_recvlogical.c:90 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN var i en existerande slot skall strömningen starta\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAMN[=VÄRDE]\n" +" skicka vidare flaggan NAMN med ev. värde VÄRDE till\n" +" utmatnings-plugin:en\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=PLUGIN använd utmatnings-plugin:en PLUGIN (standard: %s)\n" + +#: pg_recvlogical.c:98 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTNAMN namn pÃ¥ den logiska replikerings-slotten\n" + +#: pg_recvlogical.c:103 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=DBNAMN databas att ansluta till\n" + +#: pg_recvlogical.c:135 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "bekräftar skrivning fram till %X/%X, flush till %X/%X (slot %s)" + +#: pg_recvlogical.c:159 receivelog.c:346 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "kunde inte skicka feedback-paket: %s" + +#: pg_recvlogical.c:232 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "startar logg-strömning vid %X/%X (slot %s)" + +#: pg_recvlogical.c:273 +#, c-format +msgid "streaming initiated" +msgstr "strömning initierad" + +#: pg_recvlogical.c:337 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "kunde inte öppna loggfil \"%s\": %m" + +#: pg_recvlogical.c:363 receivelog.c:876 +#, c-format +msgid "invalid socket: %s" +msgstr "ogiltigt uttag: %s" + +#: pg_recvlogical.c:416 receivelog.c:904 +#, c-format +msgid "select() failed: %m" +msgstr "select() misslyckades: %m" + +#: pg_recvlogical.c:423 receivelog.c:954 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "kunde inte ta emot data frÃ¥n WAL-ström: %s" + +#: pg_recvlogical.c:465 pg_recvlogical.c:516 receivelog.c:998 receivelog.c:1064 +#, c-format +msgid "streaming header too small: %d" +msgstr "strömningsheader för liten: %d" + +#: pg_recvlogical.c:500 receivelog.c:836 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "okänd strömningsheader: \"%c\"" + +#: pg_recvlogical.c:554 pg_recvlogical.c:566 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "kunde inte skriva %u byte till loggfil \"%s\": %m" + +#: pg_recvlogical.c:594 receivelog.c:632 receivelog.c:669 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "oväntad terminering av replikeringsström: %s" + +#: pg_recvlogical.c:718 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "ogiltigt fsync-intervall \"%s\"" + +#: pg_recvlogical.c:756 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "kunde inte parsa startposition \"%s\"" + +#: pg_recvlogical.c:845 +#, c-format +msgid "no slot specified" +msgstr "ingen slot angiven" + +#: pg_recvlogical.c:853 +#, c-format +msgid "no target file specified" +msgstr "ingen mÃ¥lfil angiven" + +#: pg_recvlogical.c:861 +#, c-format +msgid "no database specified" +msgstr "ingen databas angiven" + +#: pg_recvlogical.c:869 +#, c-format +msgid "at least one action needs to be specified" +msgstr "minst en handling mÃ¥ste anges" + +#: pg_recvlogical.c:877 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "kan inte använda --create-slot eller --start tillsammans med --drop-slot" + +#: pg_recvlogical.c:885 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "kan inte använda --create-slot eller --drop-slot tillsammans med --startpos" + +#: pg_recvlogical.c:893 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos fÃ¥r bara anges tillsammans med --start" + +#: pg_recvlogical.c:924 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "kunde inte upprätta databasspecifik replikeringsanslutning" + +#: pg_recvlogical.c:1023 +#, c-format +msgid "endpos %X/%X reached by keepalive" +msgstr "endpos %X/%X nÃ¥dd av keepalive" + +#: pg_recvlogical.c:1026 +#, c-format +msgid "endpos %X/%X reached by record at %X/%X" +msgstr "endpos %X/%X nÃ¥dd av port vid %X/%X" + +#: receivelog.c:72 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "kunde inte skapa arkiveringsstatusfil \"%s\": %s" + +#: receivelog.c:119 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "kunde inte hämta storleken pÃ¥ write-ahead-logg-fil \"%s\": %s" + +#: receivelog.c:129 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "kunde inte öppna existerande write-ahead-logg-fil \"%s\": %s" + +#: receivelog.c:137 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "kunde inte fsync:a befintlig write-ahead-logg-fil \"%s\": %s" + +#: receivelog.c:151 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "write-ahead-logg-fil \"%s\" har %d byte, skall vara 0 eller %d" +msgstr[1] "write-ahead-logg-fil \"%s\" har %d byte, skall vara 0 eller %d" + +#: receivelog.c:166 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "kunde inte öppna write-ahead-logg-fil \"%s\": %s" + +#: receivelog.c:192 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "kunde inte fastställa sökposition i fil \"%s\": %s" + +#: receivelog.c:206 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "byter inte namn pÃ¥ \"%s%s\", segmentet är inte komplett" + +#: receivelog.c:218 receivelog.c:303 receivelog.c:678 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "kunde inte stänga fil \"%s\": %s" + +#: receivelog.c:275 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "servern rapporterade oväntat historikfilnamn för tidslinje %u: %s" + +#: receivelog.c:283 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "kunde inte skapa tidslinjehistorikfil \"%s\": %s" + +#: receivelog.c:290 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "kunde inte skriva tidslinjehistorikfil \"%s\": %s" + +#: receivelog.c:380 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "inkompatibel serverversion %s; klienten stöder inte stömning frÃ¥n serverversioner äldre än %s" + +#: receivelog.c:389 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "inkompatibel serverversion %s; klienten stöder inte stömning frÃ¥n serverversioner nyare än %s" + +#: receivelog.c:491 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "kunde inte identifiera system: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält" + +#: receivelog.c:498 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "systemidentifieraren matchar inte mellan basbackup och strömningsanslutning" + +#: receivelog.c:504 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "starttidslinje %u finns inte tillgänglig i servern" + +#: receivelog.c:545 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "oväntat svar pÃ¥ TIMELINE_HISTORY-kommando: fick %d rader och %d fält, förväntade %d rader och %d fält" + +#: receivelog.c:616 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "servern rapporterade oväntad nästa tidslinje %u, följer pÃ¥ tidslinje %u" + +#: receivelog.c:622 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "servern stoppade strömning av tidslinje %u vid %X/%X men rapporterade nästa tidslinje %u skulle börja vid %X/%X" + +#: receivelog.c:662 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "replikeringsström avslutades innan stoppunkt" + +#: receivelog.c:708 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "oväntad resultatmängd efter slut-pÃ¥-tidslinje: fick %d rader och %d fält, förväntade %d rader och %d fält" + +#: receivelog.c:717 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "kunde inte parsa nästa tidslinjens startpunkt \"%s\"" + +#: receivelog.c:766 receivelog.c:1018 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "kunde inte fsync:a fil \"%s\": %s" + +#: receivelog.c:1081 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "tog emot write-ahead-logg-post för offset %u utan att ha nÃ¥gon öppen fil" + +#: receivelog.c:1091 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "fick WAL-data-offset %08x, förväntade %08x" + +#: receivelog.c:1125 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "kunde inte skriva %u byte till WAL-fil \"%s\": %s" + +#: receivelog.c:1150 receivelog.c:1190 receivelog.c:1221 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "kunde inte skicka \"copy-end\"-paket: %s" + +#: streamutil.c:162 +msgid "Password: " +msgstr "Lösenord: " + +#: streamutil.c:187 +#, c-format +msgid "could not connect to server" +msgstr "kunde inte ansluta till server" + +#: streamutil.c:204 +#, c-format +msgid "could not connect to server: %s" +msgstr "kunde inte ansluta till server: %s" + +#: streamutil.c:233 +#, c-format +msgid "could not clear search_path: %s" +msgstr "kunde inte nollställa search_path: %s" + +#: streamutil.c:249 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "kunde inte lista ut serverns inställning för integer_datetimes" + +#: streamutil.c:256 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "kompileringsflaggan integer_datetimes matchar inte servern" + +#: streamutil.c:307 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "kunde inte hämta WAL-segmentstorlek: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält" + +#: streamutil.c:317 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "WAL-segment-storlek kunde inte parsas" + +#: streamutil.c:332 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men fjärrservern rapporterade värdet %d byte" +msgstr[1] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men fjärrservern rapporterade värdet %d byte" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "kunde inte hämta gruppaccessflagga: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "gruppaccessflagga kunde inte parsas: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "kunde inte skapa replikeringsslot \"%s\": fick %d rader och %d fält, förväntade %d rader och %d fält" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "kunde inte slänga replikeringsslot \"%s\": fick %d rader och %d fält, förväntade %d rader och %d fält" + +#: walmethods.c:439 walmethods.c:928 +msgid "could not compress data" +msgstr "kunde inte komprimera data" + +#: walmethods.c:471 +msgid "could not reset compression stream" +msgstr "kunde inte nollställa komprimeringsström" + +#: walmethods.c:569 +msgid "could not initialize compression library" +msgstr "kunde inte initierar komprimeringsbibliotek" + +#: walmethods.c:581 +msgid "implementation error: tar files can't have more than one open file" +msgstr "implementationsfel: tar-filer kan inte ha mer än en öppen fil" + +#: walmethods.c:595 +msgid "could not create tar header" +msgstr "kunde inte skapa tar-header" + +#: walmethods.c:609 walmethods.c:649 walmethods.c:844 walmethods.c:855 +msgid "could not change compression parameters" +msgstr "kunde inte ändra komprimeringsparametrar" + +#: walmethods.c:731 +msgid "unlink not supported with compression" +msgstr "unlink stöds inte med komprimering" + +#: walmethods.c:953 +msgid "could not close compression stream" +msgstr "kunde inte stänga komprimeringsström" + +#~ msgid "%s: --create-slot needs a slot to be specified using --slot\n" +#~ msgstr "%s: --create-slot kräver att en slot angivits med flaggan --slot\n" + +#~ msgid "%s: could not send replication command \"%s\": %s\n" +#~ msgstr "%s: kunde inte skicka replikeringskommando \"%s\": %s\n" + +#~ msgid "%s: could not clear search_path: %s" +#~ msgstr "%s: kunde inte nollställa search_path: %s" + +#~ msgid "%s: could not connect to server: %s" +#~ msgstr "%s: kunde inte ansluta till server: %s" + +#~ msgid "%s: could not connect to server\n" +#~ msgstr "%s: kunde inte ansluta till server\n" + +#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" +#~ msgstr "%s: kunde inte identifiera systemet: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält\n" + +#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna write-ahead-logg-fil \"%s\": %s\n" + +#~ msgid "%s: could not create archive status file \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa arkivstatusfil \"%s\": %s\n" + +#~ msgid "%s: could not receive data from WAL stream: %s" +#~ msgstr "%s: kunde inte ta emot data frÃ¥n WAL-ström: %s" + +#~ msgid "%s: select() failed: %s\n" +#~ msgstr "%s: select() misslyckades: %s\n" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna logg-fil \"%s\": %s\n" + +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s: kunde inte fsync:a loggfil \"%s\": %s\n" + +#~ msgid "%s: invalid port number \"%s\"\n" +#~ msgstr "%s: ogiltigt portnummer \"%s\"\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte stänga katalog \"%s\": %s\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: symlänkar stöds inte pÃ¥ denna plattform\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa symbolisk länk \"%s\": %s\n" + +#~ msgid "%s: WAL directory location must be an absolute path\n" +#~ msgstr "%s: WAL-katalogen mÃ¥ste vara en absolut sökväg.\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" + +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s: barnprocess avslutade med fel %d\n" + +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s: barnprocess avslutade inte normalt\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: slut pÃ¥ minne\n" + +#~ msgid "%s: could not set permissions on file \"%s\": %s\n" +#~ msgstr "%s: kunde inte sätta rättigheter pÃ¥ fil \"%s\": %s\n" + +#~ msgid "%s: could not set permissions on directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte sätta rättigheter pÃ¥ katalog \"%s\": %s\n" + +#~ msgid "%s: could not close file \"%s\": %s\n" +#~ msgstr "%s: kunde inte stänga fil \"%s\": %s\n" + +#~ msgid "%s: could not create file \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa fil \"%s\": %s\n" + +#~ msgid "%s: could not write to file \"%s\": %s\n" +#~ msgstr "%s: kunde inte skriva till fil \"%s\": %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte komma Ã¥t katalogen \"%s\": %s\n" + +#~ msgid "%s: directory \"%s\" exists but is not empty\n" +#~ msgstr "%s: katalogen \"%s\" existerar men är inte tom.\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte skapa katalogen \"%s\": %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapportera fel till .\n" + +#~ msgid "%s: WAL directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: WAL-katalog \"%s\" ej borttagen pÃ¥ användares begäran.\n" + +#~ msgid "%s: data directory \"%s\" not removed at user's request\n" +#~ msgstr "%s: Datakatalog \"%s\" ej borttagen pÃ¥ användares begäran.\n" + +#~ msgid "%s: failed to remove contents of WAL directory\n" +#~ msgstr "%s: misslyckades med att tömma WAL-katalog\n" + +#~ msgid "%s: removing contents of WAL directory \"%s\"\n" +#~ msgstr "%s: tömmer innehÃ¥llet i WAL-katalog \"%s\"\n" + +#~ msgid "%s: failed to remove WAL directory\n" +#~ msgstr "%s: misslyckades med att ta bort WAL-katalog.\n" + +#~ msgid "%s: removing WAL directory \"%s\"\n" +#~ msgstr "%s: tar bort WAL-katalog \"%s\"\n" + +#~ msgid "%s: failed to remove contents of data directory\n" +#~ msgstr "%s: misslyckades med att tömma datakatalog.\n" + +#~ msgid "%s: removing contents of data directory \"%s\"\n" +#~ msgstr "%s: tömmer innehÃ¥llet i datakatalog \"%s\".\n" + +#~ msgid "%s: failed to remove data directory\n" +#~ msgstr "%s: misslyckades med att ta bort datakatalog.\n" + +#~ msgid "%s: removing data directory \"%s\"\n" +#~ msgstr "%s: tar bort datakatalog \"%s\".\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: kunde inte döpa om fil \"%s\" till \"%s\": %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: kunde inte utföra fsync pÃ¥ filen \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: kunde ta status pÃ¥ filen \"%s\": %s\n" diff --git a/src/bin/pg_basebackup/po/tr.po b/src/bin/pg_basebackup/po/tr.po new file mode 100644 index 00000000000..92e0513da04 --- /dev/null +++ b/src/bin/pg_basebackup/po/tr.po @@ -0,0 +1,1535 @@ +# LANGUAGE message translation file for pg_basebackup +# Copyright (C) 2011 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 9.2\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:46+0000\n" +"PO-Revision-Date: 2019-05-28 13:56+0300\n" +"Last-Translator: Abdullah G. GÜLNER \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/file_utils.c:81 ../../common/file_utils.c:183 +#: pg_receivewal.c:267 pg_recvlogical.c:342 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" dosyası durumlanamadı: %m" + +#: ../../common/file_utils.c:160 pg_receivewal.c:170 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" dizini açılamıyor: %m" + +#: ../../common/file_utils.c:194 pg_receivewal.c:338 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: ../../common/file_utils.c:226 ../../common/file_utils.c:285 +#: ../../common/file_utils.c:359 pg_basebackup.c:1761 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: ../../common/file_utils.c:297 ../../common/file_utils.c:367 +#: pg_recvlogical.c:195 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "\"%s\" dosyası fsync hatası: %m" + +#: ../../common/file_utils.c:377 +#, c-format +msgid "could not rename file \"%s\" to \"%s\": %m" +msgstr "\"%s\" -- \"%s\" ad deÄŸiÅŸtirme hatası: %m" + +#: pg_basebackup.c:171 +#, c-format +msgid "removing data directory \"%s\"" +msgstr "\"%s\" veri dizini siliniyor" + +#: pg_basebackup.c:173 +#, c-format +msgid "failed to remove data directory" +msgstr "veri dizini silme baÅŸarısız" + +#: pg_basebackup.c:177 +#, c-format +msgid "removing contents of data directory \"%s\"" +msgstr "\"%s\" veri dizininin içindekiler siliniyor" + +#: pg_basebackup.c:179 +#, c-format +msgid "failed to remove contents of data directory" +msgstr "veri dizininin içindekileri silme iÅŸlemi baÅŸarısız" + +#: pg_basebackup.c:184 +#, c-format +msgid "removing WAL directory \"%s\"" +msgstr "\"%s\" WAL dizini siliniyor" + +#: pg_basebackup.c:186 +#, c-format +msgid "failed to remove WAL directory" +msgstr "WAL dizini silme baÅŸarısız" + +#: pg_basebackup.c:190 +#, c-format +msgid "removing contents of WAL directory \"%s\"" +msgstr "\"%s\" WAL dizininin içindekiler siliniyor" + +#: pg_basebackup.c:192 +#, c-format +msgid "failed to remove contents of WAL directory" +msgstr "WAL dizininin içindekileri silme iÅŸlemi baÅŸarısız" + +#: pg_basebackup.c:198 +#, c-format +msgid "data directory \"%s\" not removed at user's request" +msgstr "\"%s\" veri dizini kullanıcının isteÄŸi üzerine silinmedi" + +#: pg_basebackup.c:201 +#, c-format +msgid "WAL directory \"%s\" not removed at user's request" +msgstr "\"%s\" WAL dizini kullanıcının isteÄŸi üzerine silinmedi" + +#: pg_basebackup.c:205 +#, c-format +msgid "changes to tablespace directories will not be undone" +msgstr "tablespace dzinlerine yapılacak deÄŸiÅŸiklikler geri alınamayacak" + +#: pg_basebackup.c:246 +#, c-format +msgid "directory name too long" +msgstr "dizin adı çok uzun" + +#: pg_basebackup.c:256 +#, c-format +msgid "multiple \"=\" signs in tablespace mapping" +msgstr "tablespace eÅŸleÅŸtirmesinde birden fazla \"=\" iÅŸareti" + +#: pg_basebackup.c:268 +#, c-format +msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"" +msgstr "geçersiz tablespace eÅŸleÅŸtirme biçimi \"%s\", \"ESKIDIZIN=YENIDIZIN\" olmalı" + +#: pg_basebackup.c:280 +#, c-format +msgid "old directory is not an absolute path in tablespace mapping: %s" +msgstr "tablespace eÅŸleÅŸtirmesinde eski dizin mutlak bir yol deÄŸil: %s" + +#: pg_basebackup.c:287 +#, c-format +msgid "new directory is not an absolute path in tablespace mapping: %s" +msgstr "tablespace eÅŸleÅŸtirmesinde yeni dizin mutlak bir yol deÄŸil: %s" + +#: pg_basebackup.c:326 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s çalışan bir PostgreSQL sunucusunun temel yedeÄŸini (base backup) alır. \n" +"\n" + +#: pg_basebackup.c:328 pg_receivewal.c:81 pg_recvlogical.c:78 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_basebackup.c:329 pg_receivewal.c:82 pg_recvlogical.c:79 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [SEÇENEK]...\n" + +#: pg_basebackup.c:330 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Çıktıyı kontrol eden seçenekler: \n" + +#: pg_basebackup.c:331 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=DİZİN temel yedeÄŸin alınacağı dizin\n" + +#: pg_basebackup.c:332 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t çıktı formatı (düz metin(varsayılan), tar)\n" + +#: pg_basebackup.c:333 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=HIZ very dizinini aktarma için azami transfer hızı\n" +" ( kB/s olarak , veya \"k\" ya da \"M\" sonekini kullanın)\n" + +#: pg_basebackup.c:335 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write configuration for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" replikasyon için yapılandırmayı yaz\n" + +#: pg_basebackup.c:337 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" eski dizindeki tablespace yerini NEWDIR yeni dizin olarak deÄŸiÅŸtir \n" + +#: pg_basebackup.c:339 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR write-ahead log dizini\n" + +#: pg_basebackup.c:340 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" gerekli WAL dosyalarını belirtilen yöntemle dahil et\n" + +#: pg_basebackup.c:342 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr "" +" -z, --gzip tar çıktısını sıkıştır\n" +"\n" + +#: pg_basebackup.c:343 +#, c-format +msgid " -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr " -Z, --compress=0-9 tar çıktısını belirtilen sıkıştırma seviyesinde sıkıştır\n" + +#: pg_basebackup.c:344 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Genel seçenekler:\n" + +#: pg_basebackup.c:345 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" checkpoint iÅŸlemini fast ya da spread olarak ayarla\n" + +#: pg_basebackup.c:347 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot replikasyon slotu oluÅŸtur\n" + +#: pg_basebackup.c:348 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=ETİKET yedek etiketini ayarla\n" + +#: pg_basebackup.c:349 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean hatalardan sonar temizlik yapma\n" + +#: pg_basebackup.c:350 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync deÄŸiÅŸikliklerin diske yazılmasını bekleme\n" + +#: pg_basebackup.c:351 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress ilerleme bilgisini göster\n" + +#: pg_basebackup.c:352 pg_receivewal.c:91 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=SLOTADI kullanılacak replikasyon slotu\n" + +#: pg_basebackup.c:353 pg_receivewal.c:93 pg_recvlogical.c:99 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose detaylı (verbose) mesajlar göster\n" + +#: pg_basebackup.c:354 pg_receivewal.c:94 pg_recvlogical.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_basebackup.c:355 +#, c-format +msgid " --no-slot prevent creation of temporary replication slot\n" +msgstr " --no-slot geçici replikasyon slotlarının oluÅŸturulmasını engelle\n" + +#: pg_basebackup.c:356 +#, c-format +msgid "" +" --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" --no-verify-checksums\n" +" saÄŸlamaları (checksum) doÄŸrulama\n" + +#: pg_basebackup.c:358 pg_receivewal.c:96 pg_recvlogical.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_basebackup.c:359 pg_receivewal.c:97 pg_recvlogical.c:102 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"BaÄŸlantı Seçenekleri:\n" + +#: pg_basebackup.c:360 pg_receivewal.c:98 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR baÄŸlantı dizesi\n" + +#: pg_basebackup.c:361 pg_receivewal.c:99 pg_recvlogical.c:104 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME veritabanı sunucusu adresi ya da soket dizini\n" + +#: pg_basebackup.c:362 pg_receivewal.c:100 pg_recvlogical.c:105 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT veritabanı sunucusunun port numarası\n" + +#: pg_basebackup.c:363 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in seconds)\n" +msgstr "" +" -s, --status-interval=SURE\n" +" sunucuya yollanan durum paketleri arasındaki süre (saniye)\n" + +#: pg_basebackup.c:365 pg_receivewal.c:101 pg_recvlogical.c:106 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı\n" + +#: pg_basebackup.c:366 pg_receivewal.c:102 pg_recvlogical.c:107 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password baÄŸlanmak için parola sorma\n" + +#: pg_basebackup.c:367 pg_receivewal.c:103 pg_recvlogical.c:108 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password ÅŸifre sor (otomatik olarak her zaman açık)\n" + +#: pg_basebackup.c:368 pg_receivewal.c:107 pg_recvlogical.c:109 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: pg_basebackup.c:411 +#, c-format +msgid "could not read from ready pipe: %m" +msgstr "ready pipe'tan okunamadı: %m" + +#: pg_basebackup.c:417 pg_basebackup.c:545 pg_basebackup.c:2099 +#: streamutil.c:450 +#, c-format +msgid "could not parse write-ahead log location \"%s\"" +msgstr "\"%s\" write-ahead log konumu ayrıştırılamadı" + +#: pg_basebackup.c:510 pg_receivewal.c:442 +#, c-format +msgid "could not finish writing WAL files: %m" +msgstr "WAL dosyalarının yazılması bitirilemedi: %m" + +#: pg_basebackup.c:557 +#, c-format +msgid "could not create pipe for background process: %m" +msgstr "artalan süreçleri için pipe oluÅŸturulamadı: %m" + +#: pg_basebackup.c:592 +#, c-format +msgid "created temporary replication slot \"%s\"" +msgstr "geçici replikasyon slotu \"%s\" oluÅŸturuldu" + +#: pg_basebackup.c:595 +#, c-format +msgid "created replication slot \"%s\"" +msgstr "replikasyon slotu \"%s\" oluÅŸturuldu" + +#: pg_basebackup.c:615 pg_basebackup.c:668 pg_basebackup.c:1503 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" dizini oluÅŸturulamadı: %m" + +#: pg_basebackup.c:633 +#, c-format +msgid "could not create background process: %m" +msgstr "artalan süreci oluÅŸturulamadı: %m" + +#: pg_basebackup.c:645 +#, c-format +msgid "could not create background thread: %m" +msgstr "artalan iÅŸ parçacığı (thread) oluÅŸturulamadı: %m" + +#: pg_basebackup.c:689 +#, c-format +msgid "directory \"%s\" exists but is not empty" +msgstr "\"%s\" dizini mevcut, ama boÅŸ deÄŸil" + +#: pg_basebackup.c:696 +#, c-format +msgid "could not access directory \"%s\": %m" +msgstr "\"%s\" dizine eriÅŸim hatası: %m" + +#: pg_basebackup.c:757 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s" + +#: pg_basebackup.c:769 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" + +#: pg_basebackup.c:785 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" + +#: pg_basebackup.c:809 +#, c-format +msgid "transfer rate \"%s\" is not a valid value" +msgstr "\"%s\" aktarım hızı geçerli bir deÄŸer deÄŸil" + +#: pg_basebackup.c:814 +#, c-format +msgid "invalid transfer rate \"%s\": %m" +msgstr "geçersiz aktarım hızı \"%s\": %m" + +#: pg_basebackup.c:823 +#, c-format +msgid "transfer rate must be greater than zero" +msgstr "aktarım hızı sıfırdan büyük ya da eÅŸit olmalı" + +#: pg_basebackup.c:855 +#, c-format +msgid "invalid --max-rate unit: \"%s\"" +msgstr "geçersiz --max-rate (azami hız) birimi: \"%s\"" + +#: pg_basebackup.c:862 +#, c-format +msgid "transfer rate \"%s\" exceeds integer range" +msgstr "\"%s\" aktarım hızı tamsayı aralığını aşıyor" + +#: pg_basebackup.c:872 +#, c-format +msgid "transfer rate \"%s\" is out of range" +msgstr "\"%s\" aktarım hızı aralık dışındadır" + +#: pg_basebackup.c:894 +#, c-format +msgid "could not write to compressed file \"%s\": %s" +msgstr "\"%s\" sıkıştırılmış dosyasına yazılamadı: %s" + +#: pg_basebackup.c:904 pg_basebackup.c:1592 pg_basebackup.c:1767 +#, c-format +msgid "could not write to file \"%s\": %m" +msgstr "\"%s\" dosyası yazma hatası: %m" + +#: pg_basebackup.c:969 pg_basebackup.c:989 pg_basebackup.c:1016 +#, c-format +msgid "could not set compression level %d: %s" +msgstr "%d sıkıştırma seviyesi ayarlanamadı: %s" + +#: pg_basebackup.c:1036 +#, c-format +msgid "could not create compressed file \"%s\": %s" +msgstr "\"%s\" sıkıştırılmış dosyası yaratılamadı: %s" + +#: pg_basebackup.c:1047 pg_basebackup.c:1553 pg_basebackup.c:1779 +#, c-format +msgid "could not create file \"%s\": %m" +msgstr "\"%s\" dosyası oluÅŸturulamıyor: %m" + +#: pg_basebackup.c:1058 pg_basebackup.c:1412 +#, c-format +msgid "could not get COPY data stream: %s" +msgstr "COPY veri akımı (stream) alınamadı: %s" + +#: pg_basebackup.c:1143 +#, c-format +msgid "could not close compressed file \"%s\": %s" +msgstr "\"%s\" sıkıştırılmış dosyası kapatılamadı: %s" + +#: pg_basebackup.c:1155 pg_recvlogical.c:608 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" dosyası kapatılamıyor: %m" + +#: pg_basebackup.c:1166 pg_basebackup.c:1441 pg_recvlogical.c:437 +#: receivelog.c:968 +#, c-format +msgid "could not read COPY data: %s" +msgstr "COPY verisi okunamadı: %s" + +#: pg_basebackup.c:1455 +#, c-format +msgid "invalid tar block header size: %d" +msgstr "geçersiz tar blok baÅŸlık boyutu: %d" + +#: pg_basebackup.c:1510 +#, c-format +msgid "could not set permissions on directory \"%s\": %m" +msgstr "dizin \"%s\" için eriÅŸim hakları ayarlanamadı: %m" + +#: pg_basebackup.c:1533 +#, c-format +msgid "could not create symbolic link from \"%s\" to \"%s\": %m" +msgstr "\"%s\" dosyasından \"%s\" dosyasına sembolik baÄŸlantı oluÅŸturulamadı: %m" + +#: pg_basebackup.c:1540 +#, c-format +msgid "unrecognized link indicator \"%c\"" +msgstr "tanımlanamayan baÄŸlantı göstergesi \"%c\"" + +#: pg_basebackup.c:1559 +#, c-format +msgid "could not set permissions on file \"%s\": %m" +msgstr "\"%s\" dosyasının eriÅŸim hakları atanamıyor: %m" + +#: pg_basebackup.c:1616 +#, c-format +msgid "COPY stream ended before last file was finished" +msgstr "COPY akımı (stream) son dosya tamamlanmadan sona erdi" + +#: pg_basebackup.c:1643 pg_basebackup.c:1663 pg_basebackup.c:1677 +#: pg_basebackup.c:1728 +#, c-format +msgid "out of memory" +msgstr "yetersiz bellek" + +#: pg_basebackup.c:1820 +#, c-format +msgid "incompatible server version %s" +msgstr "uyumsuz sunucu sürümü %s" + +#: pg_basebackup.c:1835 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming" +msgstr "İPUCU: log akışını (streaming) devre dışı bırakmak için -X none veya -X fetch kullanın" + +#: pg_basebackup.c:1860 +#, c-format +msgid "initiating base backup, waiting for checkpoint to complete" +msgstr "yedekleme (base backup) baÅŸlatılıyor, checkpoint iÅŸleminin tamamlanması bekleniyor" + +#: pg_basebackup.c:1884 pg_recvlogical.c:264 receivelog.c:484 receivelog.c:533 +#: receivelog.c:572 streamutil.c:299 streamutil.c:370 streamutil.c:422 +#: streamutil.c:533 streamutil.c:578 +#, c-format +msgid "could not send replication command \"%s\": %s" +msgstr "\"%s\" replikasyon komutu gönderilemedi: %s" + +#: pg_basebackup.c:1895 +#, c-format +msgid "could not initiate base backup: %s" +msgstr "yedek (base backup) baÅŸlatılamadı: %s" + +#: pg_basebackup.c:1901 +#, c-format +msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields" +msgstr "sunucu BASE_BACKUP komutuna beklenmedik cevap döndü; %d satır ve %d alan alındı, %d satır ve %d alan bekleniyordu" + +#: pg_basebackup.c:1909 +#, c-format +msgid "checkpoint completed" +msgstr "checkpoint tamamlandı" + +#: pg_basebackup.c:1924 +#, c-format +msgid "write-ahead log start point: %s on timeline %u" +msgstr "write-ahead log baÅŸlama noktası: %2$u zaman çizelgesinde %1$s" + +#: pg_basebackup.c:1933 +#, c-format +msgid "could not get backup header: %s" +msgstr "yedek baÅŸlığı alınamadı: %s" + +#: pg_basebackup.c:1939 +#, c-format +msgid "no data returned from server" +msgstr "sunucudan veri dönmedi" + +#: pg_basebackup.c:1970 +#, c-format +msgid "can only write single tablespace to stdout, database has %d" +msgstr "stdout'a sadece bir tablespace yazılabilir, veritabanında %d var" + +#: pg_basebackup.c:1982 +#, c-format +msgid "starting background WAL receiver" +msgstr "artalan WAL alıcısı baÅŸlatılıyor" + +#: pg_basebackup.c:2012 +#, c-format +msgid "could not get write-ahead log end position from server: %s" +msgstr "sunucudan write-ahead log bitiÅŸ pozisyonu alınamadı: %s" + +#: pg_basebackup.c:2018 +#, c-format +msgid "no write-ahead log end position returned from server" +msgstr "sunucudan write-ahead log bitiÅŸ pozisyonu dönmedi" + +#: pg_basebackup.c:2023 +#, c-format +msgid "write-ahead log end point: %s" +msgstr "write-ahead log bitiÅŸ noktası (end point): %s" + +#: pg_basebackup.c:2034 +#, c-format +msgid "checksum error occurred" +msgstr "saÄŸlama (checksum) hatası oluÅŸtu" + +#: pg_basebackup.c:2039 +#, c-format +msgid "final receive failed: %s" +msgstr "son alma iÅŸlemi baÅŸarısız oldu: %s" + +#: pg_basebackup.c:2063 +#, c-format +msgid "waiting for background process to finish streaming ..." +msgstr "artalan sürecinin akımı (streaming) bitirmesi bekleniyor ..." + +#: pg_basebackup.c:2068 +#, c-format +msgid "could not send command to background pipe: %m" +msgstr "artalan pipe'ına komut gönderilemedi: %m" + +#: pg_basebackup.c:2076 +#, c-format +msgid "could not wait for child process: %m" +msgstr "alt süreç için beklenemedi: %m" + +#: pg_basebackup.c:2081 +#, c-format +msgid "child %d died, expected %d" +msgstr "alt süreç %d sonlandı, beklenen %d" + +#: pg_basebackup.c:2086 streamutil.c:94 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_basebackup.c:2111 +#, c-format +msgid "could not wait for child thread: %m" +msgstr "alt iÅŸ parçacığı (thread) için beklenemedi: %m" + +#: pg_basebackup.c:2117 +#, c-format +msgid "could not get child thread exit status: %m" +msgstr "alt iÅŸ parçacığı (thread) bitiÅŸ durumu alınamadı %m" + +#: pg_basebackup.c:2122 +#, c-format +msgid "child thread exited with error %u" +msgstr "alt iÅŸ parçacığı (thread) %u hata kodu ile sonlandı" + +#: pg_basebackup.c:2150 +#, c-format +msgid "syncing data to disk ..." +msgstr "veri diske yazılıyor (syncing) ... " + +#: pg_basebackup.c:2163 +#, c-format +msgid "base backup completed" +msgstr "temel (base) yedek tamamlandı" + +#: pg_basebackup.c:2244 +#, c-format +msgid "invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "geçersiz çıktı biçimi \"%s\", \"plain\" ya da \"tar\" olmalı\n" + +#: pg_basebackup.c:2288 +#, c-format +msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"" +msgstr "geçersiz wal-yöntemi seçeneÄŸi \"%s\", \"fetch\", \"stream\" ya da \"none\" olmalı" + +#: pg_basebackup.c:2316 +#, c-format +msgid "invalid compression level \"%s\"\n" +msgstr "geçersiz sıkıştırma seviyesi \"%s\"\n" + +#: pg_basebackup.c:2327 +#, c-format +msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"" +msgstr "geçersiz checkpoint argümanı \"%s\", \"fast\" ya da \"spread\" olmalı" + +#: pg_basebackup.c:2354 pg_receivewal.c:556 pg_recvlogical.c:796 +#, c-format +msgid "invalid status interval \"%s\"" +msgstr "geçersiz durum aralığı \"%s\"" + +#: pg_basebackup.c:2372 pg_basebackup.c:2385 pg_basebackup.c:2396 +#: pg_basebackup.c:2407 pg_basebackup.c:2415 pg_basebackup.c:2423 +#: pg_basebackup.c:2433 pg_basebackup.c:2446 pg_basebackup.c:2454 +#: pg_basebackup.c:2465 pg_basebackup.c:2475 pg_receivewal.c:606 +#: pg_receivewal.c:619 pg_receivewal.c:627 pg_receivewal.c:637 +#: pg_receivewal.c:645 pg_receivewal.c:656 pg_recvlogical.c:822 +#: pg_recvlogical.c:835 pg_recvlogical.c:846 pg_recvlogical.c:854 +#: pg_recvlogical.c:862 pg_recvlogical.c:870 pg_recvlogical.c:878 +#: pg_recvlogical.c:886 pg_recvlogical.c:894 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Ayrıntılı bilgi için \"%s --help\" komutunu deneyebilirsiniz.\n" + +#: pg_basebackup.c:2383 pg_receivewal.c:617 pg_recvlogical.c:833 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı girdisi var (ilki \"%s\")" + +#: pg_basebackup.c:2395 pg_receivewal.c:655 +#, c-format +msgid "no target directory specified" +msgstr "hedef dizin belirtilmedi" + +#: pg_basebackup.c:2406 +#, c-format +msgid "only tar mode backups can be compressed" +msgstr "sadece tar mod yedekleri sıkıştırılabilir" + +#: pg_basebackup.c:2414 +#, c-format +msgid "cannot stream write-ahead logs in tar mode to stdout" +msgstr "tar modunda write-ahead logları stdout'a stream edilemiyor" + +#: pg_basebackup.c:2422 +#, c-format +msgid "replication slots can only be used with WAL streaming" +msgstr "replikasyon slotları sadece WAL streaming ile kullanılabilir" + +#: pg_basebackup.c:2432 +#, c-format +msgid "--no-slot cannot be used with slot name" +msgstr "--no-slot slot adıyla birlikte kullanılamaz" + +#. translator: second %s is an option name +#: pg_basebackup.c:2444 pg_receivewal.c:635 +#, c-format +msgid "%s needs a slot to be specified using --slot" +msgstr "%s bir slotun --slot kullanılarak tanımlanmasını gerektirir" + +#: pg_basebackup.c:2453 +#, c-format +msgid "--create-slot and --no-slot are incompatible options" +msgstr "--create-slot ve --no-slot uyumsuz seçeneklerdir" + +#: pg_basebackup.c:2464 +#, c-format +msgid "WAL directory location can only be specified in plain mode" +msgstr "WAL dizini lokasyonu sadece plain modunda belitrilebilir" + +#: pg_basebackup.c:2474 +#, c-format +msgid "WAL directory location must be an absolute path" +msgstr "WAL dizini mutlak bir yol olmalıdır" + +#: pg_basebackup.c:2484 pg_receivewal.c:664 +#, c-format +msgid "this build does not support compression" +msgstr "bu kurulum sıkıştırmayı desteklemiyor" + +#: pg_basebackup.c:2538 +#, c-format +msgid "could not create symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" oluÅŸturma hatası: %m" + +#: pg_basebackup.c:2542 +#, c-format +msgid "symlinks are not supported on this platform" +msgstr "bu platformda sembolik baÄŸlantı (symlink) desteklenmemektedir" + +#: pg_receivewal.c:79 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s stream eden PostgreSQL write-ahead loglarını alır.\n" +"\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:84 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: pg_receivewal.c:84 +#, c-format +msgid " -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=DIZIN write-ahead logları bu dizine al\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:85 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr "" +" -E, --endpos=LSN belirtilen LSN alındıktan sonra çık\n" +"\n" + +#: pg_receivewal.c:86 pg_recvlogical.c:89 +#, c-format +msgid " --if-not-exists do not error if slot already exists when creating a slot\n" +msgstr " --if-not-exists zaten mevcut olan bir slot oluÅŸturulmaya çalışıldığında hata verme\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:91 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop baÄŸlantı sunucusunda loop yapma\n" + +#: pg_receivewal.c:88 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr " --no-sync deÄŸiÅŸikliklerin diske yazılmasını bekleme\n" + +#: pg_receivewal.c:89 pg_recvlogical.c:96 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server (default: %d)\n" +msgstr "" +" -s, --status-interval=SECS\n" +" sunucuya yollanan durum paketleri arasındaki süre (varsayılan: %d)\n" + +#: pg_receivewal.c:92 +#, c-format +msgid " --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous write-ahead logu yazıldıktan hemen sonra temizle\n" + +#: pg_receivewal.c:95 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 logları belirtilen sıkıştırma seviyesinde sıkıştır\n" + +#: pg_receivewal.c:104 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Opsiyonel eylemler:\n" + +#: pg_receivewal.c:105 pg_recvlogical.c:81 +#, c-format +msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n" +msgstr " --create-slot yeni bir replikasyon slotu oluÅŸtur(slotun adı için bkz. --slot)\n" + +#: pg_receivewal.c:106 pg_recvlogical.c:82 +#, c-format +msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n" +msgstr " --drop-slot replikasyon slotunu sil (slotun adı için bkz. --slot)\n" + +#: pg_receivewal.c:118 +#, c-format +msgid "finished segment at %X/%X (timeline %u)" +msgstr "segment %X/%X de bitirildi (zaman çizelgesi %u)" + +#: pg_receivewal.c:125 +#, c-format +msgid "stopped log streaming at %X/%X (timeline %u)" +msgstr "log streaming %X/%X de durduruldu (zaman çizelgesi %u)" + +#: pg_receivewal.c:141 +#, c-format +msgid "switched to timeline %u at %X/%X" +msgstr "%2$X/%3$X konumunda%1$u zaman çizelgesine geçildi" + +#: pg_receivewal.c:151 +#, c-format +msgid "received interrupt signal, exiting" +msgstr "kesme sinyali alındı, çıkılıyor" + +#: pg_receivewal.c:187 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" dizini kapatılamadı: %m" + +#: pg_receivewal.c:273 +#, c-format +msgid "segment file \"%s\" has incorrect size %d, skipping" +msgstr "\"%s\" segment dosyasının boyutu %d yanlış, atlanıyor" + +#: pg_receivewal.c:291 +#, c-format +msgid "could not open compressed file \"%s\": %m" +msgstr "\"%s\" sıkıştırılmış dosyası açılamadı: %m" + +#: pg_receivewal.c:297 +#, c-format +msgid "could not seek in compressed file \"%s\": %m" +msgstr "\"%s\" sıkıştırılmış dosyasında arama yapılamadı: %m" + +#: pg_receivewal.c:305 +#, c-format +msgid "could not read compressed file \"%s\": %m" +msgstr "\"%s\" sıkıştırılmış dosyası okunamadı: %m" + +#: pg_receivewal.c:308 +#, c-format +msgid "could not read compressed file \"%s\": read %d of %zu" +msgstr "\"%1$s\" sıkıştırılmış dosyası okuma hatası: %3$zu nun %2$d si okundu" + +#: pg_receivewal.c:319 +#, c-format +msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping" +msgstr "%s sıkıştırılmış segment dosyasının sıkıştırılmamış boyutu %d yanlış, atlanıyor" + +#: pg_receivewal.c:423 +#, c-format +msgid "starting log streaming at %X/%X (timeline %u)" +msgstr "%X/%X de log streaming baÅŸlatılıyor (zaman çizelgesi %u)" + +#: pg_receivewal.c:538 pg_recvlogical.c:738 +#, c-format +msgid "invalid port number \"%s\"" +msgstr "geçersiz port numarası \"%s\"" + +#: pg_receivewal.c:566 pg_recvlogical.c:764 +#, c-format +msgid "could not parse end position \"%s\"" +msgstr "\"%s\" bitiÅŸ pozisyonu ayrıştırılamadı" + +#: pg_receivewal.c:581 +#, c-format +msgid "invalid compression level \"%s\"" +msgstr "geçersiz sıkıştırma seviyesi \"%s\"" + +#: pg_receivewal.c:626 +#, c-format +msgid "cannot use --create-slot together with --drop-slot" +msgstr "--create-slot ile --drop-slot beraber kullanılamaz" + +#: pg_receivewal.c:644 +#, c-format +msgid "cannot use --synchronous together with --no-sync" +msgstr "--synchronous ile --no-sync beraber kullanılamaz" + +#: pg_receivewal.c:720 +#, c-format +msgid "replication connection using slot \"%s\" is unexpectedly database specific" +msgstr "\"%s\" slotunu kullanan replikasyon baÄŸlantısı beklenmedik ÅŸekilde veritabanı spesifik" + +#: pg_receivewal.c:731 pg_recvlogical.c:942 +#, c-format +msgid "dropping replication slot \"%s\"" +msgstr "\"%s\" replikasyon slotu siliniyor" + +#: pg_receivewal.c:742 pg_recvlogical.c:952 +#, c-format +msgid "creating replication slot \"%s\"" +msgstr "\"%s\" replikasyon slotu oluÅŸturuluyor" + +#: pg_receivewal.c:768 pg_recvlogical.c:977 +#, c-format +msgid "disconnected" +msgstr "baÄŸlantı kesildi" + +#. translator: check source for value for %d +#: pg_receivewal.c:774 pg_recvlogical.c:983 +#, c-format +msgid "disconnected; waiting %d seconds to try again" +msgstr "baÄŸlantı kesildi; tekrar denemek için %d saniye bekleniyor" + +#: pg_recvlogical.c:76 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "%s PostgreSQL mantıksal kod çözme akımlarını (stream) kontrol eder\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"GerçekleÅŸtirilecek eylem:\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n" +msgstr " --start bir replikasyon slotunda streaming'i baÅŸlat (slotun ismi için bkz. --slot)\n" + +#: pg_recvlogical.c:86 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr "" +" -f, --file=DOSYAADI logu bu dosyaya al, - stdout için\n" +" \n" + +#: pg_recvlogical.c:87 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: %d)\n" +msgstr "" +" -F --fsync-interval=SANIYE\n" +" çıktı dosyasına yapılan fsync iÅŸlemleri arasındaki, süre (varsayılan: %d)\n" + +#: pg_recvlogical.c:90 +#, c-format +msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n" +msgstr " -I, --startpos=LSN mevcut bir slot'ta streaming iÅŸÅŸleminin baÅŸlayacağı konum\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAME[=VALUE]\n" +" çıktı eklentisine NAME seçeneÄŸini VALUE opsiyonel\n" +" deÄŸeriyle geçir\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr " -P, --plugin=EKLENTI EKLENTI çıktı eklentisini kullan(varsayılan: %s)\n" + +#: pg_recvlogical.c:98 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTADI mantıksal replikasyon slot'unun adı\n" + +#: pg_recvlogical.c:103 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=VERITABANI_ADI baÄŸlanılacak veritabanı adı\n" + +#: pg_recvlogical.c:135 +#, c-format +msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)" +msgstr "%X/%X e kadar yazma, %X/%X'e kadar boÅŸaltma (flush) için onaylama (slot %s)" + +#: pg_recvlogical.c:159 receivelog.c:346 +#, c-format +msgid "could not send feedback packet: %s" +msgstr "geribesleme (feedback) paketi gönderilemedi: %s" + +#: pg_recvlogical.c:232 +#, c-format +msgid "starting log streaming at %X/%X (slot %s)" +msgstr "%X/%X de log streaming iÅŸlemi baÅŸlatılıyor (slot %s)" + +#: pg_recvlogical.c:273 +#, c-format +msgid "streaming initiated" +msgstr "streaming iÅŸlemi baÅŸlatıldı" + +#: pg_recvlogical.c:337 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "\"%s\" log dosyası açılamadı: %m" + +#: pg_recvlogical.c:363 receivelog.c:876 +#, c-format +msgid "invalid socket: %s" +msgstr "geçersiz soket: %s" + +#: pg_recvlogical.c:416 receivelog.c:904 +#, c-format +msgid "select() failed: %m" +msgstr "select() baÅŸarısız oldu: %m" + +#: pg_recvlogical.c:423 receivelog.c:954 +#, c-format +msgid "could not receive data from WAL stream: %s" +msgstr "Sunucudan WAL stream alınamadı: %s" + +#: pg_recvlogical.c:465 pg_recvlogical.c:516 receivelog.c:998 receivelog.c:1064 +#, c-format +msgid "streaming header too small: %d" +msgstr "streaming üst bilgisi (header) çok küçük: %d" + +#: pg_recvlogical.c:500 receivelog.c:836 +#, c-format +msgid "unrecognized streaming header: \"%c\"" +msgstr "tanınmayan streaming üst bilgisi (header): \"%c\"" + +#: pg_recvlogical.c:554 pg_recvlogical.c:566 +#, c-format +msgid "could not write %u bytes to log file \"%s\": %m" +msgstr "%u bayt \"%s\" log dosyasına yazılamadı: %m" + +#: pg_recvlogical.c:594 receivelog.c:632 receivelog.c:669 +#, c-format +msgid "unexpected termination of replication stream: %s" +msgstr "replikasyon akımında (stream) beklenmeyen sonlanma: %s" + +#: pg_recvlogical.c:718 +#, c-format +msgid "invalid fsync interval \"%s\"" +msgstr "geçersiz fsync süresi \"%s\"" + +#: pg_recvlogical.c:756 +#, c-format +msgid "could not parse start position \"%s\"" +msgstr "\"%s\" baÅŸlama pozisyonu ayrıştırılamadı" + +#: pg_recvlogical.c:845 +#, c-format +msgid "no slot specified" +msgstr "slot belirtilmedi" + +#: pg_recvlogical.c:853 +#, c-format +msgid "no target file specified" +msgstr "hedef dosya belirtilmedi" + +#: pg_recvlogical.c:861 +#, c-format +msgid "no database specified" +msgstr "veritabanı belirtilmedi" + +#: pg_recvlogical.c:869 +#, c-format +msgid "at least one action needs to be specified" +msgstr "en az bir eylem belirtilmesi gerekiyor" + +#: pg_recvlogical.c:877 +#, c-format +msgid "cannot use --create-slot or --start together with --drop-slot" +msgstr "--create slot veya --start together --drop slot ile beraber kullanılamaz" + +#: pg_recvlogical.c:885 +#, c-format +msgid "cannot use --create-slot or --drop-slot together with --startpos" +msgstr "--create slot veya --drop slot --startpos ile beraber kullanılamaz" + +#: pg_recvlogical.c:893 +#, c-format +msgid "--endpos may only be specified with --start" +msgstr "--endpos sadece --start ile birlikte belirtilebilir" + +#: pg_recvlogical.c:924 +#, c-format +msgid "could not establish database-specific replication connection" +msgstr "veritabanına özel replikasyon baÄŸlantısı kurulamadı" + +#: pg_recvlogical.c:1023 +#, c-format +msgid "endpos %X/%X reached by keepalive" +msgstr "keepalive tarafından endpos %X/%X'a ulaşıldı" + +#: pg_recvlogical.c:1026 +#, c-format +msgid "endpos %X/%X reached by record at %X/%X" +msgstr "%3$X/%4$X deki kayıt tarafından endpos %1$X/%2$X'e ulaşıldı" + +#: receivelog.c:72 +#, c-format +msgid "could not create archive status file \"%s\": %s" +msgstr "\"%s\" arÅŸiv durum dosyası oluÅŸturulamadı: %s" + +#: receivelog.c:119 +#, c-format +msgid "could not get size of write-ahead log file \"%s\": %s" +msgstr "\"%s\" write-ahead log dosyasının boyutu alınamadı: %s" + +#: receivelog.c:129 +#, c-format +msgid "could not open existing write-ahead log file \"%s\": %s" +msgstr "\"%s\" mevcut write-ahead log dosyası açılamadı: %s" + +#: receivelog.c:137 +#, c-format +msgid "could not fsync existing write-ahead log file \"%s\": %s" +msgstr "\"%s\" mevcut write-ahead log dosyası fsync edilemedi: %s" + +#: receivelog.c:151 +#, c-format +msgid "write-ahead log file \"%s\" has %d byte, should be 0 or %d" +msgid_plural "write-ahead log file \"%s\" has %d bytes, should be 0 or %d" +msgstr[0] "\"%s\" write-ahead log dosyası %d bayt, 0 veya %d olmalı" + +#: receivelog.c:166 +#, c-format +msgid "could not open write-ahead log file \"%s\": %s" +msgstr "\"%s\" write-ahead log dosyası açma hatası: %s" + +#: receivelog.c:192 +#, c-format +msgid "could not determine seek position in file \"%s\": %s" +msgstr "\"%s\" dosyasınde arama pozisyonu belirlenemedi: %s" + +#: receivelog.c:206 +#, c-format +msgid "not renaming \"%s%s\", segment is not complete" +msgstr "\"%s%s\" isim deÄŸiÅŸikliÄŸi yapılmıyor, segment tamam deÄŸil" + +#: receivelog.c:218 receivelog.c:303 receivelog.c:678 +#, c-format +msgid "could not close file \"%s\": %s" +msgstr "\"%s\" dosyası kapatılamadı: %s" + +#: receivelog.c:275 +#, c-format +msgid "server reported unexpected history file name for timeline %u: %s" +msgstr "sunucu %u zaman çizelgesi için beklenmeyen geçmiÅŸ dosyası adı bildirdi: %s" + +#: receivelog.c:283 +#, c-format +msgid "could not create timeline history file \"%s\": %s" +msgstr "\"%s\" zaman çizelgesi geçmiÅŸ dosyası yaratılamadı: %s" + +#: receivelog.c:290 +#, c-format +msgid "could not write timeline history file \"%s\": %s" +msgstr "\"%s\" zaman çizelgesi geçmiÅŸ dosyasına yazılamadı: %s" + +#: receivelog.c:380 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions older than %s" +msgstr "uyumsuz sunucu sürümü %s; istemci %s den daha eski sunucu sürümlerinden streaming iÅŸlemini desteklemiyor" + +#: receivelog.c:389 +#, c-format +msgid "incompatible server version %s; client does not support streaming from server versions newer than %s" +msgstr "uyumsuz sunucu sürümü %s; istemci %s den daha yeni sunucu sürümlerinden streaming iÅŸlemini desteklemiyor" + +#: receivelog.c:491 streamutil.c:430 streamutil.c:467 +#, c-format +msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "sistem belirlenemedi: %d satır ve %d alan alındı, beklenen %d satır ve %d veya daha fazla alan" + +#: receivelog.c:498 +#, c-format +msgid "system identifier does not match between base backup and streaming connection" +msgstr "system tanımlayıcısı temel yedek ve streaming baÄŸlantısı ile eÅŸleÅŸmiyor" + +#: receivelog.c:504 +#, c-format +msgid "starting timeline %u is not present in the server" +msgstr "baÅŸlama zaman çizelgesi %u sunucuda mevcut deÄŸil" + +#: receivelog.c:545 +#, c-format +msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "TIMELINE_HISTORY komutuna beklenmedik cevap; %d satır ve %d alan alındı, %d satır ve %d alan bekleniyordu" + +#: receivelog.c:616 +#, c-format +msgid "server reported unexpected next timeline %u, following timeline %u" +msgstr "sunucu %2$u zaman çizelgesini takiben beklenmedik sonraki zaman çizelgesi %1$u bildirdi" + +#: receivelog.c:622 +#, c-format +msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X" +msgstr "sunucu %u streaming zaman çizelgesini %X/%X de durdurdu, fakat sonraki %u zaman çizelgesinin %X/%X de baÅŸlayacağını bildirdi" + +#: receivelog.c:662 +#, c-format +msgid "replication stream was terminated before stop point" +msgstr "replikasyon akımı durma nokatasından önce sonlandırıldı" + +#: receivelog.c:708 +#, c-format +msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields" +msgstr "zaman çizelgesi sonundan sonra beklenmedik sonuç kümesi: %d satır ve %d alan alındı, %d satır ve %d alan bekleniyordu" + +#: receivelog.c:717 +#, c-format +msgid "could not parse next timeline's starting point \"%s\"" +msgstr "bir sonraki zaman çizelgesinin (timeline) baÅŸlama noktası \"%s\" ayrıştırılamadı" + +#: receivelog.c:766 receivelog.c:1018 +#, c-format +msgid "could not fsync file \"%s\": %s" +msgstr "\"%s\" dosyası fsync hatası: %s" + +#: receivelog.c:1081 +#, c-format +msgid "received write-ahead log record for offset %u with no file open" +msgstr "açık dosya yokken %u offset için write-ahead log kaydı alındı" + +#: receivelog.c:1091 +#, c-format +msgid "got WAL data offset %08x, expected %08x" +msgstr "%08x WAL data offset'i alındı , %08x bekleniyordu" + +#: receivelog.c:1125 +#, c-format +msgid "could not write %u bytes to WAL file \"%s\": %s" +msgstr "%u bayt, \"%s\" WAL dosyasına yazılamadı: %s" + +#: receivelog.c:1150 receivelog.c:1190 receivelog.c:1221 +#, c-format +msgid "could not send copy-end packet: %s" +msgstr "copy-end paketi gönderilemedi: %s" + +#: streamutil.c:162 +msgid "Password: " +msgstr "Åžifre: " + +#: streamutil.c:187 +#, c-format +msgid "could not connect to server" +msgstr "sunucuya baÄŸlanamadı" + +#: streamutil.c:204 +#, c-format +msgid "could not connect to server: %s" +msgstr "sunucuya baÄŸlanamadı: %s" + +#: streamutil.c:233 +#, c-format +msgid "could not clear search_path: %s" +msgstr "search_path temizlenemedi: %s" + +#: streamutil.c:249 +#, c-format +msgid "could not determine server setting for integer_datetimes" +msgstr "integer_datetimes için sunucu ayarı belirlenemedi" + +#: streamutil.c:256 +#, c-format +msgid "integer_datetimes compile flag does not match server" +msgstr "integer_datetimes derleme seçeneÄŸi sunucu ile eÅŸleÅŸmiyor" + +#: streamutil.c:307 +#, c-format +msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "WAL segment boyutu belirlenemedi: %d satır ve %d alan alındı, %d satır ve %d veya daha fazla alan bekleniyordu" + +#: streamutil.c:317 +#, c-format +msgid "WAL segment size could not be parsed" +msgstr "WAL segment boyutu ayrıştırılamadı" + +#: streamutil.c:332 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes" +msgstr[0] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat uzak sunucu %d bayt bildirdi" + +#: streamutil.c:378 +#, c-format +msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields" +msgstr "grup eriÅŸim ayarı belirlenemedi: %d satır ve %d alan alındı, %d satır ve %d veya daha fazla alan bekleniyordu" + +#: streamutil.c:387 +#, c-format +msgid "group access flag could not be parsed: %s" +msgstr "grup eriÅŸim ayarı ayrıştırılamadı: %s" + +#: streamutil.c:544 +#, c-format +msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "\"%s\" replikasyon slot'u oluÅŸturulamadı: %d satır ve %d alan alındı,%d satır ve %d alan bekleniyordu" + +#: streamutil.c:588 +#, c-format +msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields" +msgstr "\"%s\" replikasyon slot'u silinemedi: %d satır ve %d alan alındı, %d satır ve %d alan bekleniyordu" + +#: walmethods.c:439 walmethods.c:928 +msgid "could not compress data" +msgstr "veri sıkıştırılamadı" + +#: walmethods.c:471 +msgid "could not reset compression stream" +msgstr "sıkıştırma akımı sıfırlanamadı (reset)" + +#: walmethods.c:569 +msgid "could not initialize compression library" +msgstr "sıkıştırma kütüphanesi ilklendirilemedi" + +#: walmethods.c:581 +msgid "implementation error: tar files can't have more than one open file" +msgstr "uygulama hatası: tar dosyalarının birden fazla açık dosyası olamaz" + +#: walmethods.c:595 +msgid "could not create tar header" +msgstr "tar baÅŸlığı (header) oluÅŸturulamadı" + +#: walmethods.c:609 walmethods.c:649 walmethods.c:844 walmethods.c:855 +msgid "could not change compression parameters" +msgstr "sıkıştırma parametreleri deÄŸiÅŸtirilemedi" + +#: walmethods.c:731 +msgid "unlink not supported with compression" +msgstr "unlink, sıkıştırma seçeneÄŸi ile desteklenmiyor" + +#: walmethods.c:953 +msgid "could not close compression stream" +msgstr "sıkıştırma akımı kapatılamadı" + +#~ msgid "%s: no start point returned from server\n" +#~ msgstr "%s:sunucudan bir baÅŸlangıç noktası dönmedi\n" + +#~ msgid "%s: could not parse file mode\n" +#~ msgstr "%s: dosya modu ayıklanamadı\n" + +#~ msgid "%s: could not parse file size\n" +#~ msgstr "%s: dosya boyutu ayıklanamadı\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini gösterir ve çıkar\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı gösterir ve çıkar\n" + +#~ msgid "%s: could not clear search_path: %s" +#~ msgstr "%s: search_path temizlenemedi: %s" + +#~ msgid "%s: could not connect to server: %s" +#~ msgstr "%s: sunucuya baÄŸlanılamadı: %s" + +#~ msgid "%s: could not connect to server\n" +#~ msgstr "%s: sunucuya baÄŸlanılamadı\n" + +#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n" +#~ msgstr "%s: sistem belirlenemedi: %d satır ve %d alan alındı, %d satır ve %d veya daha fazla alan bekleniyordu\n" + +#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" write-ahead log dosyası açılamadı: %s\n" + +#~ msgid "%s: could not create archive status file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" arÅŸiv durum dosyası oluÅŸturulamadı: %s\n" + +#~ msgid "%s: could not receive data from WAL stream: %s" +#~ msgstr "%s: WAL stream'den veri alınamadı: %s" + +#~ msgid "%s: select() failed: %s\n" +#~ msgstr "%s: select() baÅŸarısız oldu: %s\n" + +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" kayıt dosyası açılamıyor: %s\n" + +#~ msgid "%s: could not fsync log file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası fsync edilemiyor: %s\n" + +#~ msgid "%s: invalid port number \"%s\"\n" +#~ msgstr "%s: geçersiz port numarası: \"%s\"\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini kapatılamadı: %s\n" + +#~ msgid "%s: symlinks are not supported on this platform\n" +#~ msgstr "%s: bu platformda sembolik baÄŸlantı (symlink) desteklenmemektedir\n" + +#~ msgid "%s: could not create symbolic link \"%s\": %s\n" +#~ msgstr "%s: symbolic link \"%s\" oluÅŸturma hatası: %s\n" + +#~ msgid "%s: child process exited with error %d\n" +#~ msgstr "%s: alt süreç %d hata kodu ile sonlandı\n" + +#~ msgid "%s: child process did not exit normally\n" +#~ msgstr "%s: alt süreç normal olarak sonlanmadı\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: yetersiz bellek\n" + +#~ msgid "%s: could not set permissions on file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasının izinleri ayarlanamadı: %s\n" + +#~ msgid "%s: could not set permissions on directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizininde izinler ayarlanamadı: %s\n" + +#~ msgid "%s: could not close file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası kapatılamadı: %s\n" + +#~ msgid "%s: could not create file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası yaratılamadı: %s\n" + +#~ msgid "%s: could not write to file \"%s\": %s\n" +#~ msgstr "%s: \"%s\":dosyasına yazılamadı: %s\n" + +#~ msgid "%s: could not access directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizine eriÅŸim hatası: %s\n" + +#~ msgid "%s: could not create directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini oluÅŸturma baÅŸarısız: %s\n" + +#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasının ismi \"%s\" olarak deÄŸiÅŸtirilemedi : %s\n" + +#~ msgid "%s: could not fsync file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası fsync iÅŸlemi baÅŸarısız: %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası açılamadı: %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini okuma baÅŸarısız: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini açılamadı: %s\n" + +#~ msgid "%s: could not stat file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasının durumu görüntülenemedi (stat): %s\n" diff --git a/src/bin/pg_basebackup/po/vi.po b/src/bin/pg_basebackup/po/vi.po new file mode 100644 index 00000000000..19fcce3c253 --- /dev/null +++ b/src/bin/pg_basebackup/po/vi.po @@ -0,0 +1,1520 @@ +# LANGUAGE message translation file for pg_basebackup +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_basebackup (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_basebackup (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:16+0000\n" +"PO-Revision-Date: 2018-05-06 01:24+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Language: vi_VN\n" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "hết bá»™ nhá»›\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "không thể nhân đôi con trá» null (lá»—i ná»™i bá»™)\n" + +#: ../../common/file_utils.c:82 ../../common/file_utils.c:186 +#: pg_receivewal.c:268 pg_recvlogical.c:354 +#, c-format +msgid "%s: could not stat file \"%s\": %s\n" +msgstr "%s: không thể lấy thông tin trạng thái tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:162 pg_receivewal.c:169 +#, c-format +msgid "%s: could not open directory \"%s\": %s\n" +msgstr "%s: không thể mở thư mục \"%s\": %s\n" + +#: ../../common/file_utils.c:198 pg_receivewal.c:336 +#, c-format +msgid "%s: could not read directory \"%s\": %s\n" +msgstr "%s: không thể Ä‘á»c thư mục \"%s\": %s\n" + +#: ../../common/file_utils.c:231 ../../common/file_utils.c:291 +#: ../../common/file_utils.c:367 +#, c-format +msgid "%s: could not open file \"%s\": %s\n" +msgstr "%s: không thể mở tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:304 ../../common/file_utils.c:376 receivelog.c:788 +#: receivelog.c:1045 +#, c-format +msgid "%s: could not fsync file \"%s\": %s\n" +msgstr "%s: không thể đồng bá»™ (fsync) tệp \"%s\": %s\n" + +#: ../../common/file_utils.c:387 +#, c-format +msgid "%s: could not rename file \"%s\" to \"%s\": %s\n" +msgstr "%s: không thể đổi tên tệp \"%s\" thành \"%s\": %s\n" + +#: pg_basebackup.c:166 +#, c-format +msgid "%s: removing data directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa thư mục \"%s\"\n" + +#: pg_basebackup.c:169 +#, c-format +msgid "%s: failed to remove data directory\n" +msgstr "%s: không thể xóa thư mục dữ liệu\n" + +#: pg_basebackup.c:175 +#, c-format +msgid "%s: removing contents of data directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa ná»™i dung cá»§a thư mục dữ liệu \"%s\"\n" + +#: pg_basebackup.c:178 +#, c-format +msgid "%s: failed to remove contents of data directory\n" +msgstr "%s: không thể xóa ná»™i dung thư mục dữ liệu\n" + +#: pg_basebackup.c:184 +#, c-format +msgid "%s: removing WAL directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa thư mục WAL \"%s\"\n" + +#: pg_basebackup.c:187 +#, c-format +msgid "%s: failed to remove WAL directory\n" +msgstr "%s: không thể xóa thư mục WAL\n" + +#: pg_basebackup.c:193 +#, c-format +msgid "%s: removing contents of WAL directory \"%s\"\n" +msgstr "%s: Ä‘ang xóa ná»™i dung thư mục WAL \"%s\"\n" + +#: pg_basebackup.c:196 +#, c-format +msgid "%s: failed to remove contents of WAL directory\n" +msgstr "%s: không thể xóa ná»™i dung thư mục WAL\n" + +#: pg_basebackup.c:204 +#, c-format +msgid "%s: data directory \"%s\" not removed at user's request\n" +msgstr "%s: thư mục dữ liệu \"%s\" không bị xóa theo yêu cầu cá»§a ngưá»i dùng\n" + +#: pg_basebackup.c:209 +#, c-format +msgid "%s: WAL directory \"%s\" not removed at user's request\n" +msgstr "%s: thư mục WAL \"%s\" không bị xóa theo yêu cầu cá»§a ngưá»i dùng\n" + +#: pg_basebackup.c:215 +#, c-format +msgid "%s: changes to tablespace directories will not be undone\n" +msgstr "%s: các thay đổi đối vá»›i thư mục tablespace sẽ không được hoàn tác\n" + +#: pg_basebackup.c:257 +#, c-format +msgid "%s: directory name too long\n" +msgstr "%s: tên thư mục quá dài\n" + +#: pg_basebackup.c:267 +#, c-format +msgid "%s: multiple \"=\" signs in tablespace mapping\n" +msgstr "%s: nhiá»u dấu \"=\" trong ánh xạ tablespace\n" + +#: pg_basebackup.c:280 +#, c-format +msgid "" +"%s: invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"\n" +msgstr "" +"%s: định dạng ánh xạ tablespace không hợp lệ \"%s\", phải là \"OLDDIR=NEWDIR" +"\"\n" + +#: pg_basebackup.c:293 +#, c-format +msgid "%s: old directory is not an absolute path in tablespace mapping: %s\n" +msgstr "" +"%s: thư mục cÅ© không phải là đưá»ng dẫn tuyệt đối trong ánh xạ tablespace: " +"%s\n" + +#: pg_basebackup.c:300 +#, c-format +msgid "%s: new directory is not an absolute path in tablespace mapping: %s\n" +msgstr "" +"%s: thư mục má»›i không phải là đưá»ng dẫn tuyệt đối trong ánh xạ tablespace: " +"%s\n" + +#: pg_basebackup.c:339 +#, c-format +msgid "" +"%s takes a base backup of a running PostgreSQL server.\n" +"\n" +msgstr "" +"%s lấy bản sao lưu cÆ¡ sở cá»§a PostgreSQL server Ä‘ang chạy.\n" +"\n" + +#: pg_basebackup.c:341 pg_receivewal.c:79 pg_recvlogical.c:78 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: pg_basebackup.c:342 pg_receivewal.c:80 pg_recvlogical.c:79 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [TÙYCHỌN]...\n" + +#: pg_basebackup.c:343 +#, c-format +msgid "" +"\n" +"Options controlling the output:\n" +msgstr "" +"\n" +"Tùy chá»n kiểm soát đầu ra:\n" + +#: pg_basebackup.c:344 +#, c-format +msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n" +msgstr " -D, --pgdata=DIRECTORY chỉ định thư mục lưu bản sao lưu cÆ¡ sở\n" + +#: pg_basebackup.c:345 +#, c-format +msgid " -F, --format=p|t output format (plain (default), tar)\n" +msgstr " -F, --format=p|t định dạng đầu ra (plain (mặc định), tar)\n" + +#: pg_basebackup.c:346 +#, c-format +msgid "" +" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" +" (in kB/s, or use suffix \"k\" or \"M\")\n" +msgstr "" +" -r, --max-rate=RATE tốc độ truyá»n tối Ä‘a khi chuyển thư mục dữ liệu\n" +" (đơn vị kB/s, hoặc sá»­ dụng hậu tố \"k\" hay \"M\")\n" + +#: pg_basebackup.c:348 +#, c-format +msgid "" +" -R, --write-recovery-conf\n" +" write recovery.conf for replication\n" +msgstr "" +" -R, --write-recovery-conf\n" +" viết tệp recovery.conf cho replication\n" + +#: pg_basebackup.c:350 +#, c-format +msgid "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" relocate tablespace in OLDDIR to NEWDIR\n" +msgstr "" +" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" +" định vị lại tablespace trong OLDDIR thành NEWDIR\n" + +#: pg_basebackup.c:352 +#, c-format +msgid " --waldir=WALDIR location for the write-ahead log directory\n" +msgstr " --waldir=WALDIR chỉ định cho thư mục WAL\n" + +#: pg_basebackup.c:353 +#, c-format +msgid "" +" -X, --wal-method=none|fetch|stream\n" +" include required WAL files with specified method\n" +msgstr "" +" -X, --wal-method=none|fetch|stream\n" +" lưu các tệp WAL được yêu cầu vá»›i phương thức\n" +" được chỉ định\n" + +#: pg_basebackup.c:355 +#, c-format +msgid " -z, --gzip compress tar output\n" +msgstr " -z, --gzip nén đầu ra định dạng tar\n" + +#: pg_basebackup.c:356 +#, c-format +msgid "" +" -Z, --compress=0-9 compress tar output with given compression level\n" +msgstr "" +" -Z, --compress=0-9 nén đầu ra định dạng tar vá»›i mức nén nhất định\n" + +#: pg_basebackup.c:357 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Tùy chá»n chung:\n" + +#: pg_basebackup.c:358 +#, c-format +msgid "" +" -c, --checkpoint=fast|spread\n" +" set fast or spread checkpointing\n" +msgstr "" +" -c, --checkpoint=fast|spread\n" +" thiết lập chế độ checkpoint là nhanh(fast)\n" +" hay dàn trải(spread)\n" + +#: pg_basebackup.c:360 +#, c-format +msgid " -C, --create-slot create replication slot\n" +msgstr " -C, --create-slot tạo slot cho replication\n" + +#: pg_basebackup.c:361 +#, c-format +msgid " -l, --label=LABEL set backup label\n" +msgstr " -l, --label=LABEL chỉ định backup label\n" + +#: pg_basebackup.c:362 +#, c-format +msgid " -n, --no-clean do not clean up after errors\n" +msgstr " -n, --no-clean không dá»n dẹp sau khi có lá»—i\n" + +#: pg_basebackup.c:363 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" -N, --no-sync không đợi những thay đổi được ghi má»™t cách an toàn\n" +" vào đĩa\n" + +#: pg_basebackup.c:364 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress hiển thị thông tin vá» tiến độ\n" + +#: pg_basebackup.c:365 pg_receivewal.c:89 +#, c-format +msgid " -S, --slot=SLOTNAME replication slot to use\n" +msgstr " -S, --slot=SLOTNAME chỉ định replication slot\n" + +#: pg_basebackup.c:366 +#, c-format +msgid "" +" --no-slot prevent creation of temporary replication slot\n" +msgstr "" +" --no-slot ngăn chặn tạo ra các slot tạm thá»i cho replication\n" + +#: pg_basebackup.c:367 +#, c-format +msgid "" +" -k, --no-verify-checksums\n" +" do not verify checksums\n" +msgstr "" +" -k, --no-verify-checksums\n" +" không xác minh checksum\n" + +#: pg_basebackup.c:369 pg_receivewal.c:91 pg_recvlogical.c:99 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose xuất thông báo chi tiết\n" + +#: pg_basebackup.c:370 pg_receivewal.c:92 pg_recvlogical.c:100 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version hiển thị thông tin phiên bản, sau đó thoát\n" + +#: pg_basebackup.c:371 pg_receivewal.c:94 pg_recvlogical.c:101 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help hiển thị trợ giúp này, sau đó thoát\n" + +#: pg_basebackup.c:372 pg_receivewal.c:95 pg_recvlogical.c:102 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Tùy chá»n kết nối:\n" + +#: pg_basebackup.c:373 pg_receivewal.c:96 +#, c-format +msgid " -d, --dbname=CONNSTR connection string\n" +msgstr " -d, --dbname=CONNSTR chuá»—i kết nối\n" + +#: pg_basebackup.c:374 pg_receivewal.c:97 pg_recvlogical.c:104 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME host cá»§a database server hay thư mục socket\n" + +#: pg_basebackup.c:375 pg_receivewal.c:98 pg_recvlogical.c:105 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p, --port=PORT số port cá»§a database server\n" + +#: pg_basebackup.c:376 +#, c-format +msgid "" +" -s, --status-interval=INTERVAL\n" +" time between status packets sent to server (in " +"seconds)\n" +msgstr "" +" -s, --status-interval=INTERVAL\n" +" thá»i gian giữa các gói trạng thái được gá»­i tá»›i\n" +" server (tính bằng giây)\n" + +#: pg_basebackup.c:378 pg_receivewal.c:99 pg_recvlogical.c:106 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr "" +" -U, --username=NAME kết nối vá»›i ngưá»i dùng cÆ¡ sở dữ liệu được chỉ định\n" + +#: pg_basebackup.c:379 pg_receivewal.c:100 pg_recvlogical.c:107 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password không bao giá» nhắc mật khẩu\n" + +#: pg_basebackup.c:380 pg_receivewal.c:101 pg_recvlogical.c:108 +#, c-format +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" +msgstr " -W, --password yêu cầu nhập mật khẩu (sẽ xảy ra tá»± động)\n" + +#: pg_basebackup.c:381 pg_receivewal.c:105 pg_recvlogical.c:109 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Báo cáo lá»—i tá»›i .\n" + +#: pg_basebackup.c:424 +#, c-format +msgid "%s: could not read from ready pipe: %s\n" +msgstr "%s: không thể Ä‘á»c từ pipe đã sẵn sàng: %s\n" + +#: pg_basebackup.c:432 pg_basebackup.c:563 pg_basebackup.c:2064 +#: streamutil.c:458 +#, c-format +msgid "%s: could not parse write-ahead log location \"%s\"\n" +msgstr "%s: không thể phân tích cú pháp vị trí WAL \"%s\"\n" + +#: pg_basebackup.c:526 pg_receivewal.c:443 +#, c-format +msgid "%s: could not finish writing WAL files: %s\n" +msgstr "%s: không thể kết thúc việc ghi tệp WAL: %s\n" + +#: pg_basebackup.c:576 +#, c-format +msgid "%s: could not create pipe for background process: %s\n" +msgstr "%s: không thể tạo pipe cho tiến trình ná»n: %s\n" + +#: pg_basebackup.c:612 +#, c-format +msgid "%s: created temporary replication slot \"%s\"\n" +msgstr "%s: đã tạo slot tạm thá»i cho replication \"%s\"\n" + +#: pg_basebackup.c:615 +#, c-format +msgid "%s: created replication slot \"%s\"\n" +msgstr "%s: đã tạo replication slot \"%s\"\n" + +#: pg_basebackup.c:636 pg_basebackup.c:692 pg_basebackup.c:1462 +#, c-format +msgid "%s: could not create directory \"%s\": %s\n" +msgstr "%s: không thể tạo thư mục \"%s\": %s\n" + +#: pg_basebackup.c:655 +#, c-format +msgid "%s: could not create background process: %s\n" +msgstr "%s: không thể tạo tiến trình ná»n: %s\n" + +#: pg_basebackup.c:667 +#, c-format +msgid "%s: could not create background thread: %s\n" +msgstr "%s: không thể tạo luồng ná»n: %s\n" + +#: pg_basebackup.c:715 +#, c-format +msgid "%s: directory \"%s\" exists but is not empty\n" +msgstr "%s: thư mục \"%s\" tồn tại nhưng không trống\n" + +#: pg_basebackup.c:723 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: không thể truy cập thư mục \"%s\": %s\n" + +#: pg_basebackup.c:785 +#, c-format +msgid "%*s/%s kB (100%%), %d/%d tablespace %*s" +msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s" +msgstr[0] "%*s/%s kB (100%%), %d/%d tablespaces %*s" + +#: pg_basebackup.c:797 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)" + +#: pg_basebackup.c:813 +#, c-format +msgid "%*s/%s kB (%d%%), %d/%d tablespace" +msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces" +msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace" + +#: pg_basebackup.c:838 +#, c-format +msgid "%s: transfer rate \"%s\" is not a valid value\n" +msgstr "%s: tốc độ truyá»n \"%s\" không phải là giá trị hợp lệ\n" + +#: pg_basebackup.c:845 +#, c-format +msgid "%s: invalid transfer rate \"%s\": %s\n" +msgstr "%s: tốc độ truyá»n không hợp lệ \"%s\": %s\n" + +#: pg_basebackup.c:855 +#, c-format +msgid "%s: transfer rate must be greater than zero\n" +msgstr "%s: tốc độ truyá»n phải lá»›n hÆ¡n 0\n" + +#: pg_basebackup.c:889 +#, c-format +msgid "%s: invalid --max-rate unit: \"%s\"\n" +msgstr "%s: đơn vị --max-rate không hợp lệ: \"%s\"\n" + +#: pg_basebackup.c:898 +#, c-format +msgid "%s: transfer rate \"%s\" exceeds integer range\n" +msgstr "%s: tốc độ truyá»n \"%s\" vượt quá phạm vi integer\n" + +#: pg_basebackup.c:910 +#, c-format +msgid "%s: transfer rate \"%s\" is out of range\n" +msgstr "%s: tốc độ truyá»n \"%s\" ngoài phạm vi\n" + +#: pg_basebackup.c:934 +#, c-format +msgid "%s: could not write to compressed file \"%s\": %s\n" +msgstr "%s: không thể ghi vào tệp nén \"%s\": %s\n" + +#: pg_basebackup.c:944 pg_basebackup.c:1556 pg_basebackup.c:1722 +#, c-format +msgid "%s: could not write to file \"%s\": %s\n" +msgstr "%s: không thể ghi vào tệp \"%s\": %s\n" + +#: pg_basebackup.c:1003 pg_basebackup.c:1024 pg_basebackup.c:1052 +#, c-format +msgid "%s: could not set compression level %d: %s\n" +msgstr "%s: không thể thiết lập mức nén %d: %s\n" + +#: pg_basebackup.c:1073 +#, c-format +msgid "%s: could not create compressed file \"%s\": %s\n" +msgstr "%s: không thể tạo tệp nén \"%s\": %s\n" + +#: pg_basebackup.c:1084 pg_basebackup.c:1516 pg_basebackup.c:1715 +#, c-format +msgid "%s: could not create file \"%s\": %s\n" +msgstr "%s: không thể tạo tệp \"%s\": %s\n" + +#: pg_basebackup.c:1096 pg_basebackup.c:1369 +#, c-format +msgid "%s: could not get COPY data stream: %s" +msgstr "%s: không thể nhận luồng dữ liệu COPY: %s" + +#: pg_basebackup.c:1153 +#, c-format +msgid "%s: could not close compressed file \"%s\": %s\n" +msgstr "%s: không thể đóng tệp nén \"%s\": %s\n" + +#: pg_basebackup.c:1166 pg_recvlogical.c:632 receivelog.c:224 receivelog.c:309 +#: receivelog.c:698 +#, c-format +msgid "%s: could not close file \"%s\": %s\n" +msgstr "%s: không thể đóng tệp \"%s\": %s\n" + +#: pg_basebackup.c:1177 pg_basebackup.c:1398 pg_recvlogical.c:454 +#: receivelog.c:993 +#, c-format +msgid "%s: could not read COPY data: %s" +msgstr "%s: không thể Ä‘á»c dữ liệu COPY: %s" + +#: pg_basebackup.c:1412 +#, c-format +msgid "%s: invalid tar block header size: %d\n" +msgstr "%s: kích thước tiêu đỠkhối tar không hợp lệ: %d\n" + +#: pg_basebackup.c:1470 +#, c-format +msgid "%s: could not set permissions on directory \"%s\": %s\n" +msgstr "%s: không thể đặt quyá»n cho thư mục \"%s\": %s\n" + +#: pg_basebackup.c:1494 +#, c-format +msgid "%s: could not create symbolic link from \"%s\" to \"%s\": %s\n" +msgstr "%s: không thể tạo symbolic link từ \"%s\" tá»›i \"%s\": %s\n" + +#: pg_basebackup.c:1503 +#, c-format +msgid "%s: unrecognized link indicator \"%c\"\n" +msgstr "%s: không thể nhận ra liên kết indicator \"%c\"\n" + +#: pg_basebackup.c:1523 +#, c-format +msgid "%s: could not set permissions on file \"%s\": %s\n" +msgstr "%s: không thể đặt quyá»n đối vá»›i tệp \"%s\": %s\n" + +#: pg_basebackup.c:1582 +#, c-format +msgid "%s: COPY stream ended before last file was finished\n" +msgstr "%s: Dòng COPY đã kết thúc trước khi tệp cuối cùng được hoàn tất\n" + +#: pg_basebackup.c:1610 pg_basebackup.c:1630 pg_basebackup.c:1637 +#: pg_basebackup.c:1690 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: hết bá»™ nhá»›\n" + +#: pg_basebackup.c:1763 +#, c-format +msgid "%s: incompatible server version %s\n" +msgstr "%s: phiên bản server không tương thích %s\n" + +#: pg_basebackup.c:1778 +#, c-format +msgid "HINT: use -X none or -X fetch to disable log streaming\n" +msgstr "Gợi ý: sá»­ dụng -X none hay -X fetch để tắt tính năng log streaming\n" + +#: pg_basebackup.c:1804 +#, c-format +msgid "%s: initiating base backup, waiting for checkpoint to complete\n" +msgstr "%s: bắt đầu sao lưu cÆ¡ sở, chá» checkpoint để hoàn thành\n" + +#: pg_basebackup.c:1829 pg_recvlogical.c:271 receivelog.c:493 receivelog.c:546 +#: receivelog.c:586 streamutil.c:428 streamutil.c:542 streamutil.c:588 +#, c-format +msgid "%s: could not send replication command \"%s\": %s" +msgstr "%s: không thể gá»­i lệnh replication \"%s\": %s" + +#: pg_basebackup.c:1840 +#, c-format +msgid "%s: could not initiate base backup: %s" +msgstr "%s: không thể bắt đầu sao lưu cÆ¡ sở: %s" + +#: pg_basebackup.c:1847 +#, c-format +msgid "" +"%s: server returned unexpected response to BASE_BACKUP command; got %d rows " +"and %d fields, expected %d rows and %d fields\n" +msgstr "" +"%s: server trả vá» phản hồi không mong muốn cho lệnh BASE_BACKUP, có %d hàng " +"và %d trưá»ng, dá»± kiến %d hàng và %d trưá»ng\n" + +#: pg_basebackup.c:1855 +#, c-format +msgid "%s: checkpoint completed\n" +msgstr "%s: checkpoint hoàn thành\n" + +#: pg_basebackup.c:1870 +#, c-format +msgid "%s: write-ahead log start point: %s on timeline %u\n" +msgstr "%s: Äiểm bắt đầu WAL: %s ở timeline %u\n" + +#: pg_basebackup.c:1879 +#, c-format +msgid "%s: could not get backup header: %s" +msgstr "%s: không thể lấy tiêu đỠbackup: %s" + +#: pg_basebackup.c:1885 +#, c-format +msgid "%s: no data returned from server\n" +msgstr "%s: không có dữ liệu nào được trả vá» từ server\n" + +#: pg_basebackup.c:1917 +#, c-format +msgid "%s: can only write single tablespace to stdout, database has %d\n" +msgstr "%s: chỉ có thể ghi tablespace đơn qua stdout, cÆ¡ sở dữ liệu có %d\n" + +#: pg_basebackup.c:1929 +#, c-format +msgid "%s: starting background WAL receiver\n" +msgstr "%s: khởi động tiến trình ná»n để nhận WAL\n" + +#: pg_basebackup.c:1961 +#, c-format +msgid "%s: could not get write-ahead log end position from server: %s" +msgstr "%s: không thể nhận được vị trí kết thúc WAL từ server: %s" + +#: pg_basebackup.c:1968 +#, c-format +msgid "%s: no write-ahead log end position returned from server\n" +msgstr "%s: vị trí cuối cá»§a WAL không được trả vá» từ server\n" + +#: pg_basebackup.c:1974 +#, c-format +msgid "%s: write-ahead log end point: %s\n" +msgstr "%s: Ä‘iểm kết thúc WAL: %s\n" + +#: pg_basebackup.c:1985 +#, c-format +msgid "%s: checksum error occured\n" +msgstr "%s: xảy ra lá»—i checksum\n" + +#: pg_basebackup.c:1991 +#, c-format +msgid "%s: final receive failed: %s" +msgstr "%s: lá»—i khi nhận cuối cùng: %s" + +#: pg_basebackup.c:2016 +#, c-format +msgid "%s: waiting for background process to finish streaming ...\n" +msgstr "%s: Ä‘ang chá» tiến trình ná»n hoàn thành truyá»n ...\n" + +#: pg_basebackup.c:2022 +#, c-format +msgid "%s: could not send command to background pipe: %s\n" +msgstr "%s: không thể gá»­i lệnh tá»›i pipe cá»§a tiến trình ná»n: %s\n" + +#: pg_basebackup.c:2031 +#, c-format +msgid "%s: could not wait for child process: %s\n" +msgstr "%s: không thể chá» tiến trình con: %s\n" + +#: pg_basebackup.c:2037 +#, c-format +msgid "%s: child %d died, expected %d\n" +msgstr "%s: tiến trình con %d bị kết thúc, kỳ vá»ng %d\n" + +#: pg_basebackup.c:2043 +#, c-format +msgid "%s: child process did not exit normally\n" +msgstr "%s: tiến trình con kết thúc không bình thưá»ng\n" + +#: pg_basebackup.c:2049 +#, c-format +msgid "%s: child process exited with error %d\n" +msgstr "%s: tiến trình con đã thoát vá»›i lá»—i %d\n" + +#: pg_basebackup.c:2076 +#, c-format +msgid "%s: could not wait for child thread: %s\n" +msgstr "%s: không thể đợi luồng con: %s\n" + +#: pg_basebackup.c:2083 +#, c-format +msgid "%s: could not get child thread exit status: %s\n" +msgstr "%s: không thể nhận được trạng thái kết thúc cá»§a luồng con: %s\n" + +#: pg_basebackup.c:2089 +#, c-format +msgid "%s: child thread exited with error %u\n" +msgstr "%s: luồng con kết thúc vá»›i lá»—i %u\n" + +#: pg_basebackup.c:2127 +#, c-format +msgid "%s: base backup completed\n" +msgstr "%s: sao lưu cÆ¡ sở đã hoàn thành\n" + +#: pg_basebackup.c:2208 +#, c-format +msgid "%s: invalid output format \"%s\", must be \"plain\" or \"tar\"\n" +msgstr "" +"%s: định dạng đầu ra không hợp lệ \"%s\", phải là \"plain\" hoặc \"tar\"\n" + +#: pg_basebackup.c:2253 +#, c-format +msgid "" +"%s: invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or " +"\"none\"\n" +msgstr "" +"%s: tùy chá»n phương thức wal không hợp lệ \"%s\", phải là \"fetch\", \"stream" +"\" hoặc \"none\"\n" + +#: pg_basebackup.c:2281 pg_receivewal.c:585 +#, c-format +msgid "%s: invalid compression level \"%s\"\n" +msgstr "%s: mức độ nén không hợp lệ \"%s\"\n" + +#: pg_basebackup.c:2293 +#, c-format +msgid "" +"%s: invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"\n" +msgstr "" +"%s: đối số cho checkpoint không hợp lệ \"%s\", phải là \"fast\" hoặc \"spread" +"\"\n" + +#: pg_basebackup.c:2320 pg_receivewal.c:557 pg_recvlogical.c:826 +#, c-format +msgid "%s: invalid status interval \"%s\"\n" +msgstr "%s: giá trị status-interval không hợp lệ \"%s\"\n" + +#: pg_basebackup.c:2339 pg_basebackup.c:2353 pg_basebackup.c:2364 +#: pg_basebackup.c:2377 pg_basebackup.c:2387 pg_basebackup.c:2397 +#: pg_basebackup.c:2409 pg_basebackup.c:2423 pg_basebackup.c:2433 +#: pg_basebackup.c:2446 pg_basebackup.c:2457 pg_receivewal.c:611 +#: pg_receivewal.c:625 pg_receivewal.c:633 pg_receivewal.c:643 +#: pg_receivewal.c:651 pg_receivewal.c:662 pg_recvlogical.c:853 +#: pg_recvlogical.c:867 pg_recvlogical.c:878 pg_recvlogical.c:886 +#: pg_recvlogical.c:894 pg_recvlogical.c:902 pg_recvlogical.c:910 +#: pg_recvlogical.c:918 pg_recvlogical.c:928 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_basebackup.c:2351 pg_receivewal.c:623 pg_recvlogical.c:865 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: quá nhiá»u đối số dòng lệnh (đầu tiên là \"%s\")\n" + +#: pg_basebackup.c:2363 pg_receivewal.c:661 +#, c-format +msgid "%s: no target directory specified\n" +msgstr "%s: không có thư mục đích được chỉ định\n" + +#: pg_basebackup.c:2375 +#, c-format +msgid "%s: only tar mode backups can be compressed\n" +msgstr "%s: chỉ có chế độ backup dạng tar má»›i có thể được nén\n" + +#: pg_basebackup.c:2385 +#, c-format +msgid "%s: cannot stream write-ahead logs in tar mode to stdout\n" +msgstr "%s: không thể truyá»n WAL ở chế độ tar qua stdout\n" + +#: pg_basebackup.c:2395 +#, c-format +msgid "%s: replication slots can only be used with WAL streaming\n" +msgstr "" +"%s: các replication slots chỉ có thể được sá»­ dụng vá»›i việc truyá»n WAL\n" + +#: pg_basebackup.c:2407 +#, c-format +msgid "%s: --no-slot cannot be used with slot name\n" +msgstr "%s: --no-slot không thể được sá»­ dụng vá»›i tên slot\n" + +#: pg_basebackup.c:2421 +#, c-format +msgid "%s: --create-slot needs a slot to be specified using --slot\n" +msgstr "%s: --create-slot cần má»™t slot được chỉ định để sá»­ dụng --slot\n" + +#: pg_basebackup.c:2431 +#, c-format +msgid "%s: --create-slot and --no-slot are incompatible options\n" +msgstr "%s: --create-slot và --no-slot là các tùy chá»n không tương thích\n" + +#: pg_basebackup.c:2444 +#, c-format +msgid "%s: WAL directory location can only be specified in plain mode\n" +msgstr "%s: Vị trí thư mục WAL chỉ được chỉ định ở chế độ plain\n" + +#: pg_basebackup.c:2455 +#, c-format +msgid "%s: WAL directory location must be an absolute path\n" +msgstr "%s: Vị trí thư mục WAL phải là đưá»ng dẫn tuyệt đối\n" + +#: pg_basebackup.c:2467 pg_receivewal.c:671 +#, c-format +msgid "%s: this build does not support compression\n" +msgstr "%s: phiên bản binary này không há»— trợ nén\n" + +#: pg_basebackup.c:2521 +#, c-format +msgid "%s: could not create symbolic link \"%s\": %s\n" +msgstr "%s: không thể tạo symbolic link \"%s\": %s\n" + +#: pg_basebackup.c:2526 +#, c-format +msgid "%s: symlinks are not supported on this platform\n" +msgstr "%s: symlink không được há»— trợ trên hệ Ä‘iá»u hành này\n" + +#: pg_receivewal.c:77 +#, c-format +msgid "" +"%s receives PostgreSQL streaming write-ahead logs.\n" +"\n" +msgstr "" +"%s nhận PostgreSQL WAL.\n" +"\n" + +#: pg_receivewal.c:81 pg_recvlogical.c:84 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Tùy chá»n:\n" + +#: pg_receivewal.c:82 +#, c-format +msgid "" +" -D, --directory=DIR receive write-ahead log files into this directory\n" +msgstr " -D, --directory=DIR nhận tệp WAL vào thư mục này\n" + +#: pg_receivewal.c:83 pg_recvlogical.c:85 +#, c-format +msgid " -E, --endpos=LSN exit after receiving the specified LSN\n" +msgstr "" +" -E, --endpos=LSN kết thúc trước khi nhật LSN đã được chỉ định\n" + +#: pg_receivewal.c:84 pg_recvlogical.c:89 +#, c-format +msgid "" +" --if-not-exists do not error if slot already exists when creating a " +"slot\n" +msgstr " --if-not-exists không xuất lá»—i khi tạo slot đã có sẵn\n" + +#: pg_receivewal.c:85 pg_recvlogical.c:91 +#, c-format +msgid " -n, --no-loop do not loop on connection lost\n" +msgstr " -n, --no-loop không lặp khi bị mất kết nối\n" + +#: pg_receivewal.c:86 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely to " +"disk\n" +msgstr "" +" --no-sync không đợi những thay đổi được ghi má»™t cách an toàn\n" +" vào đĩa\n" + +#: pg_receivewal.c:87 pg_recvlogical.c:96 +#, c-format +msgid "" +" -s, --status-interval=SECS\n" +" time between status packets sent to server " +"(default: %d)\n" +msgstr "" +" -s, --status-interval=SECS\n" +" thá»i gian giữa các gói trạng thái được gá»­i tá»›i\n" +" server (mặc định: %d)\n" + +#: pg_receivewal.c:90 +#, c-format +msgid "" +" --synchronous flush write-ahead log immediately after writing\n" +msgstr " --synchronous flush WAL ngay sau khi write\n" + +#: pg_receivewal.c:93 +#, c-format +msgid " -Z, --compress=0-9 compress logs with given compression level\n" +msgstr " -Z, --compress=0-9 nén log vá»›i mức độ nén được chỉ định\n" + +#: pg_receivewal.c:102 +#, c-format +msgid "" +"\n" +"Optional actions:\n" +msgstr "" +"\n" +"Tác vụ tùy chá»n:\n" + +#: pg_receivewal.c:103 pg_recvlogical.c:81 +#, c-format +msgid "" +" --create-slot create a new replication slot (for the slot's name " +"see --slot)\n" +msgstr "" +" --create-slot tạo replication slot má»›i (vá» tên slot xem --slot)\n" + +#: pg_receivewal.c:104 pg_recvlogical.c:82 +#, c-format +msgid "" +" --drop-slot drop the replication slot (for the slot's name see " +"--slot)\n" +msgstr "" +" --drop-slot xóa replication slot (vá» tên slot xem --slot)\n" + +#: pg_receivewal.c:116 +#, c-format +msgid "%s: finished segment at %X/%X (timeline %u)\n" +msgstr "%s: kết thúc phân Ä‘oạn tại %X/%X (timeline %u)\n" + +#: pg_receivewal.c:123 +#, c-format +msgid "%s: stopped streaming at %X/%X (timeline %u)\n" +msgstr "%s: kết thúc truyá»n tại %X/%X (timeline %u)\n" + +#: pg_receivewal.c:139 +#, c-format +msgid "%s: switched to timeline %u at %X/%X\n" +msgstr "%s: chuyển qua timeline %u tại %X/%X\n" + +#: pg_receivewal.c:149 +#, c-format +msgid "%s: received interrupt signal, exiting\n" +msgstr "%s: nhận được tín hiệu ngắt, Ä‘ang thoát\n" + +#: pg_receivewal.c:187 +#, c-format +msgid "%s: could not close directory \"%s\": %s\n" +msgstr "%s: không thể đóng thư mục \"%s\": %s\n" + +#: pg_receivewal.c:276 +#, c-format +msgid "%s: segment file \"%s\" has incorrect size %d, skipping\n" +msgstr "%s: tệp phân Ä‘oạn \"%s\" có kích thước không đúng %d, bá» qua\n" + +#: pg_receivewal.c:293 +#, c-format +msgid "%s: could not open compressed file \"%s\": %s\n" +msgstr "%s: không thể mở tệp nén \"%s\": %s\n" + +#: pg_receivewal.c:299 +#, c-format +msgid "%s: could not seek in compressed file \"%s\": %s\n" +msgstr "%s: không thể tìm kiếm trong tệp nén \"%s\": %s\n" + +#: pg_receivewal.c:305 +#, c-format +msgid "%s: could not read compressed file \"%s\": %s\n" +msgstr "%s: không thể Ä‘á»c tệp nén \"%s\": %s\n" + +#: pg_receivewal.c:317 +#, c-format +msgid "" +"%s: compressed segment file \"%s\" has incorrect uncompressed size %d, " +"skipping\n" +msgstr "" +"%s: tệp phân Ä‘oạn nén \"%s\" có kích thước giải nén không đúng %d, bá» qua\n" + +#: pg_receivewal.c:423 +#, c-format +msgid "%s: starting log streaming at %X/%X (timeline %u)\n" +msgstr "%s: bắt đầu truyá»n log tại %X/%X (timeline %u)\n" + +#: pg_receivewal.c:538 pg_recvlogical.c:763 +#, c-format +msgid "%s: invalid port number \"%s\"\n" +msgstr "%s: số port không hợp lệ \"%s\"\n" + +#: pg_receivewal.c:569 pg_recvlogical.c:793 +#, c-format +msgid "%s: could not parse end position \"%s\"\n" +msgstr "%s: không thể phân tích cú pháp vị trí kết thúc \"%s\"\n" + +#: pg_receivewal.c:632 +#, c-format +msgid "%s: cannot use --create-slot together with --drop-slot\n" +msgstr "%s: không thể sá»­ dụng --create-slot cùng vá»›i --drop-slot\n" + +#. translator: second %s is an option name +#: pg_receivewal.c:641 +#, c-format +msgid "%s: %s needs a slot to be specified using --slot\n" +msgstr "%s: %s cần má»™t slot được chỉ định để sá»­ dụng --slot\n" + +#: pg_receivewal.c:650 +#, c-format +msgid "%s: cannot use --synchronous together with --no-sync\n" +msgstr "%s: không thể sá»­ dụng --synchronous cùng vá»›i --no-sync\n" + +#: pg_receivewal.c:728 +#, c-format +msgid "" +"%s: replication connection using slot \"%s\" is unexpectedly database " +"specific\n" +msgstr "" +"%s: kết nối replication sá»­ dụng slot \"%s\" không mong đợi database-" +"specific\n" + +#: pg_receivewal.c:740 pg_recvlogical.c:978 +#, c-format +msgid "%s: dropping replication slot \"%s\"\n" +msgstr "%s: Ä‘ang xóa replication slot \"%s\"\n" + +#: pg_receivewal.c:753 pg_recvlogical.c:990 +#, c-format +msgid "%s: creating replication slot \"%s\"\n" +msgstr "%s: Ä‘ang tạo replication slot \"%s\"\n" + +#: pg_receivewal.c:780 pg_recvlogical.c:1016 +#, c-format +msgid "%s: disconnected\n" +msgstr "%s: đã ngắt kết nối\n" + +#. translator: check source for value for %d +#: pg_receivewal.c:787 pg_recvlogical.c:1023 +#, c-format +msgid "%s: disconnected; waiting %d seconds to try again\n" +msgstr "%s: đã ngắt kết nối; đợi %d giây để thá»­ lại\n" + +#: pg_recvlogical.c:76 +#, c-format +msgid "" +"%s controls PostgreSQL logical decoding streams.\n" +"\n" +msgstr "" +"%s kiểm soát luồng PostgreSQL logical decoding.\n" +"\n" + +#: pg_recvlogical.c:80 +#, c-format +msgid "" +"\n" +"Action to be performed:\n" +msgstr "" +"\n" +"Hành động được thá»±c hiện:\n" + +#: pg_recvlogical.c:83 +#, c-format +msgid "" +" --start start streaming in a replication slot (for the " +"slot's name see --slot)\n" +msgstr "" +" --start bắt đầu truyá»n trong má»™t replication slot\n" +" (vá» tên slot xem --slot)\n" + +#: pg_recvlogical.c:86 +#, c-format +msgid " -f, --file=FILE receive log into this file, - for stdout\n" +msgstr " -f, --file=FILE nhận log vào tệp này, - cho stdout\n" + +#: pg_recvlogical.c:87 +#, c-format +msgid "" +" -F --fsync-interval=SECS\n" +" time between fsyncs to the output file (default: " +"%d)\n" +msgstr "" +" -F --fsync-interval=SECS\n" +" thá»i gian giữa các fsync cho tệp xuất (mặc định: " +"%d)\n" + +#: pg_recvlogical.c:90 +#, c-format +msgid "" +" -I, --startpos=LSN where in an existing slot should the streaming " +"start\n" +msgstr " -I, --startpos=LSN nÆ¡i trong má»™t slot cho Ä‘iểm bắt đầu truyá»n\n" + +#: pg_recvlogical.c:92 +#, c-format +msgid "" +" -o, --option=NAME[=VALUE]\n" +" pass option NAME with optional value VALUE to the\n" +" output plugin\n" +msgstr "" +" -o, --option=NAME[=VALUE]\n" +" đặt tùy chá»n NAME vá»›i giá trị tùy chá»n VALUE vào\n" +" plugin đầu ra\n" + +#: pg_recvlogical.c:95 +#, c-format +msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n" +msgstr "" +" -P, --plugin=PLUGIN sá»­ dụng plugin đầu ra là PLUGIN (mặc định: %s)\n" + +#: pg_recvlogical.c:98 +#, c-format +msgid " -S, --slot=SLOTNAME name of the logical replication slot\n" +msgstr " -S, --slot=SLOTNAME tên cá»§a logical replication slot\n" + +#: pg_recvlogical.c:103 +#, c-format +msgid " -d, --dbname=DBNAME database to connect to\n" +msgstr " -d, --dbname=DBNAME cở sở dữ liệu kết nối tá»›i\n" + +#: pg_recvlogical.c:136 +#, c-format +msgid "%s: confirming write up to %X/%X, flush to %X/%X (slot %s)\n" +msgstr "%s: xác nhận ghi đến %X/%X, flush đến %X/%X (slot %s)\n" + +#: pg_recvlogical.c:161 receivelog.c:352 +#, c-format +msgid "%s: could not send feedback packet: %s" +msgstr "%s: không thể gá»­i gói phản hồi: %s" + +#: pg_recvlogical.c:200 +#, c-format +msgid "%s: could not fsync log file \"%s\": %s\n" +msgstr "%s: không thể fsync tệp log \"%s\": %s\n" + +#: pg_recvlogical.c:239 +#, c-format +msgid "%s: starting log streaming at %X/%X (slot %s)\n" +msgstr "%s: bắt đầu truyá»n log ở %X /%X (slot %s)\n" + +#: pg_recvlogical.c:281 +#, c-format +msgid "%s: streaming initiated\n" +msgstr "%s: khởi tạo luồng truyá»n\n" + +#: pg_recvlogical.c:347 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: không thể mở tệp log \"%s\": %s\n" + +#: pg_recvlogical.c:377 receivelog.c:898 +#, c-format +msgid "%s: invalid socket: %s" +msgstr "%s: socket không hợp lệ: %s" + +#: pg_recvlogical.c:431 receivelog.c:927 +#, c-format +msgid "%s: select() failed: %s\n" +msgstr "%s: lá»—i select(): %s\n" + +#: pg_recvlogical.c:440 receivelog.c:979 +#, c-format +msgid "%s: could not receive data from WAL stream: %s" +msgstr "%s: không thể nhận dữ liệu từ luồng truyá»n WAL: %s" + +#: pg_recvlogical.c:482 pg_recvlogical.c:534 receivelog.c:1024 +#: receivelog.c:1091 +#, c-format +msgid "%s: streaming header too small: %d\n" +msgstr "%s: tiêu đỠcá»§a luồng truyá»n quá nhá»: %d\n" + +#: pg_recvlogical.c:518 receivelog.c:858 +#, c-format +msgid "%s: unrecognized streaming header: \"%c\"\n" +msgstr "%s: không thể xác định tiêu đỠluồng truyá»n: \"%c\"\n" + +#: pg_recvlogical.c:574 pg_recvlogical.c:588 +#, c-format +msgid "%s: could not write %u bytes to log file \"%s\": %s\n" +msgstr "%s: không thể ghi %u byte vào tệp log \"%s\": %s\n" + +#: pg_recvlogical.c:618 receivelog.c:650 receivelog.c:689 +#, c-format +msgid "%s: unexpected termination of replication stream: %s" +msgstr "%s: luồng truyá»n replication kết thúc không mong đợi: %s" + +#: pg_recvlogical.c:742 +#, c-format +msgid "%s: invalid fsync interval \"%s\"\n" +msgstr "%s: khoảng thá»i gian fsync không hợp lệ \"%s\"\n" + +#: pg_recvlogical.c:783 +#, c-format +msgid "%s: could not parse start position \"%s\"\n" +msgstr "%s: không thể phân tích cú pháp vị trí bắt đầu \"%s\"\n" + +#: pg_recvlogical.c:877 +#, c-format +msgid "%s: no slot specified\n" +msgstr "%s: không có slot nào được chỉ định\n" + +#: pg_recvlogical.c:885 +#, c-format +msgid "%s: no target file specified\n" +msgstr "%s: không có tệp đích nào được chỉ định\n" + +#: pg_recvlogical.c:893 +#, c-format +msgid "%s: no database specified\n" +msgstr "%s: không có cÆ¡ sở dữ liệu nào được chỉ định\n" + +#: pg_recvlogical.c:901 +#, c-format +msgid "%s: at least one action needs to be specified\n" +msgstr "%s: cần chỉ định ít nhất má»™t hành động\n" + +#: pg_recvlogical.c:909 +#, c-format +msgid "%s: cannot use --create-slot or --start together with --drop-slot\n" +msgstr "%s: không thể sá»­ dụng --create-slot hay --start cùng vá»›i --drop-slot\n" + +#: pg_recvlogical.c:917 +#, c-format +msgid "%s: cannot use --create-slot or --drop-slot together with --startpos\n" +msgstr "" +"%s: không thể sá»­ dụng --create-slot hay --drop-slot cùng vá»›i --startpos\n" + +#: pg_recvlogical.c:926 +#, c-format +msgid "%s: --endpos may only be specified with --start\n" +msgstr "%s: --endpos có thể chỉ được chỉ định vá»›i --start\n" + +#: pg_recvlogical.c:958 +#, c-format +msgid "%s: could not establish database-specific replication connection\n" +msgstr "%s: không thể thiết lập kết nối database-specific replication\n" + +#: receivelog.c:71 +#, c-format +msgid "%s: could not create archive status file \"%s\": %s\n" +msgstr "%s: không thể tạo tệp trạng thái archive \"%s\": %s\n" + +#: receivelog.c:119 +#, c-format +msgid "%s: could not get size of write-ahead log file \"%s\": %s\n" +msgstr "%s: không thể xác định được kích thước cá»§a tệp WAL \"%s\": %s\n" + +#: receivelog.c:130 +#, c-format +msgid "%s: could not open existing write-ahead log file \"%s\": %s\n" +msgstr "%s: không thể mở tệp WAL Ä‘ang tồn tại \"%s\": %s\n" + +#: receivelog.c:139 +#, c-format +msgid "%s: could not fsync existing write-ahead log file \"%s\": %s\n" +msgstr "%s: không thể đồng bá»™ (fsync) tệp WAL Ä‘ang tồn tại \"%s\": %s\n" + +#: receivelog.c:154 +#, c-format +msgid "%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n" +msgid_plural "" +"%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n" +msgstr[0] "%s: Tệp WAL \"%s\" có %d byte, phải nên là 0 hoặc %d\n" + +#: receivelog.c:170 +#, c-format +msgid "%s: could not open write-ahead log file \"%s\": %s\n" +msgstr "%s: không thể mở tệp WAL \"%s\": %s\n" + +#: receivelog.c:197 +#, c-format +msgid "%s: could not determine seek position in file \"%s\": %s\n" +msgstr "%s: không thể xác định vị trí tìm kiếm trong tệp \"%s\": %s\n" + +#: receivelog.c:212 +#, c-format +msgid "%s: not renaming \"%s%s\", segment is not complete\n" +msgstr "%s: không đổi tên \"%s%s\", phân Ä‘oạn chưa hoàn thành\n" + +#: receivelog.c:281 +#, c-format +msgid "%s: server reported unexpected history file name for timeline %u: %s\n" +msgstr "" +"%s: server báo cáo tên tệp lịch sá»­ không mong đợi cho timeline %u: %s\n" + +#: receivelog.c:289 +#, c-format +msgid "%s: could not create timeline history file \"%s\": %s\n" +msgstr "%s: không thể tạo tệp lịch sá»­ cho timeline \"%s\": %s\n" + +#: receivelog.c:296 +#, c-format +msgid "%s: could not write timeline history file \"%s\": %s\n" +msgstr "%s: không thể ghi tệp lịch sá»­ timeline \"%s\": %s\n" + +#: receivelog.c:386 +#, c-format +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions older than %s\n" +msgstr "" +"%s: phiên bản server không tương thích %s; client không há»— trợ truyá»n từ " +"phiên bản server cÅ© hÆ¡n %s\n" + +#: receivelog.c:396 +#, c-format +msgid "" +"%s: incompatible server version %s; client does not support streaming from " +"server versions newer than %s\n" +msgstr "" +"%s: phiên bản server không tương thích %s; client không há»— trợ truyá»n từ " +"phiên bản server má»›i hÆ¡n %s\n" +"\n" + +#: receivelog.c:501 streamutil.c:437 streamutil.c:476 +#, c-format +msgid "" +"%s: could not identify system: got %d rows and %d fields, expected %d rows " +"and %d or more fields\n" +msgstr "" +"%s: không thể xác định hệ thống: có %d hàng và %d trưá»ng, kỳ vá»ng %d hàng và " +"%d hay nhiá»u hÆ¡n trưá»ng\n" + +#: receivelog.c:509 +#, c-format +msgid "" +"%s: system identifier does not match between base backup and streaming " +"connection\n" +msgstr "" +"%s: số nhận dạng hệ thống không khá»›p giữa sao lưu cÆ¡ sở và kết nối luồng " +"truyá»n\n" + +#: receivelog.c:517 +#, c-format +msgid "%s: starting timeline %u is not present in the server\n" +msgstr "%s: timeline bắt đầu %u không tồn tại trong server\n" + +#: receivelog.c:559 +#, c-format +msgid "" +"%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d " +"fields, expected %d rows and %d fields\n" +msgstr "" +"%s: phản hồi không mong muốn đối vá»›i lệnh TIMELINE_HISTORY: có %d hàng và %d " +"trưá»ng, kỳ vá»ng %d hàng và %d trưá»ng\n" + +#: receivelog.c:631 +#, c-format +msgid "" +"%s: server reported unexpected next timeline %u, following timeline %u\n" +msgstr "" +"%s: server báo cáo không mong đợi timeline tiếp theo %u, timeline sau %u\n" + +#: receivelog.c:638 +#, c-format +msgid "" +"%s: server stopped streaming timeline %u at %X/%X, but reported next " +"timeline %u to begin at %X/%X\n" +msgstr "" +"%s: server ngừng phát timeline %u ở %X/%X, nhưng đã báo cáo timeline tiếp " +"theo %u để bắt đầu ở %X/%X\n" +"\n" + +#: receivelog.c:680 +#, c-format +msgid "%s: replication stream was terminated before stop point\n" +msgstr "%s: luồng replication đã bị chấm dứt trước Ä‘iểm dừng\n" + +#: receivelog.c:729 +#, c-format +msgid "" +"%s: unexpected result set after end-of-timeline: got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: tập hợp kết quả không mong muốn sau end-of-timeline: có %d hàng và %d " +"trưá»ng, kỳ vá»ng %d hàng và %d trưá»ng\n" + +#: receivelog.c:739 +#, c-format +msgid "%s: could not parse next timeline's starting point \"%s\"\n" +msgstr "" +"%s: không thể phân tích cú pháp Ä‘iểm bắt đầu cá»§a timeline tiếp theo \"%s\"\n" + +#: receivelog.c:1110 +#, c-format +msgid "%s: received write-ahead log record for offset %u with no file open\n" +msgstr "%s: đã nhận bản ghi WAL cho offset %u vá»›i không tệp mở nào\n" + +#: receivelog.c:1121 +#, c-format +msgid "%s: got WAL data offset %08x, expected %08x\n" +msgstr "%s: có dữ liệu WAL offset %08x, kỳ vá»ng %08x\n" + +#: receivelog.c:1156 +#, c-format +msgid "%s: could not write %u bytes to WAL file \"%s\": %s\n" +msgstr "%s: không thể viết %u byte vào tệp WAL \"%s\": %s\n" + +#: receivelog.c:1181 receivelog.c:1222 receivelog.c:1253 +#, c-format +msgid "%s: could not send copy-end packet: %s" +msgstr "%s: không thể gá»­i gói tin copy-end: %s" + +#: streamutil.c:161 +msgid "Password: " +msgstr "Mật khẩu: " + +#: streamutil.c:186 +#, c-format +msgid "%s: could not connect to server\n" +msgstr "%s: không thể kết nối tá»›i server\n" + +#: streamutil.c:204 +#, c-format +msgid "%s: could not connect to server: %s" +msgstr "%s: không thể kết nối tá»›i server: %s" + +#: streamutil.c:233 +#, c-format +msgid "%s: could not clear search_path: %s\n" +msgstr "%s: không thể xóa search_path: %s\n" + +#: streamutil.c:250 +#, c-format +msgid "%s: could not determine server setting for integer_datetimes\n" +msgstr "%s: không thể xác định thiết lập ở server cho integer_datetimes\n" + +#: streamutil.c:259 +#, c-format +msgid "%s: integer_datetimes compile flag does not match server\n" +msgstr "%s: flag biên dịch integer_datetimes không khá»›p vá»›i server\n" + +#: streamutil.c:303 streamutil.c:375 +#, c-format +msgid "%s: could not send replication command \"%s\": %s\n" +msgstr "%s: không thể gá»­i lệnh replication \"%s\": %s\n" + +#: streamutil.c:312 +#, c-format +msgid "" +"%s: could not fetch WAL segment size: got %d rows and %d fields, expected %d " +"rows and %d or more fields\n" +msgstr "" +"%s: không thể fetch kích thước phân Ä‘oạn WAL: có %d hàng và %d trưá»ng, kỳ " +"vá»ng %d hàng và %d hoặc nhiá»u hÆ¡n trưá»ng\n" + +#: streamutil.c:322 +#, c-format +msgid "%s: WAL segment size could not be parsed\n" +msgstr "%s: Không thể phân tích cú pháp kích thước phân Ä‘oạn WAL\n" + +#: streamutil.c:339 +#, c-format +msgid "" +"%s: WAL segment size must be a power of two between 1MB and 1GB, but the " +"remote server reported a value of %d bytes\n" +msgstr "" +"%s: kích thước phân Ä‘oạn WAL phải là lÅ©y thừa cá»§a hai giữa 1MB và 1GB, nhưng " +"remote server đã báo cáo giá trị %d byte\n" + +#: streamutil.c:384 +#, c-format +msgid "" +"%s: could not fetch group access flag: got %d rows and %d fields, expected " +"%d rows and %d or more fields\n" +msgstr "" +"%s: không thể fetch cá» truy cập nhóm: có %d hàng và %d trưá»ng, kỳ vá»ng %d " +"hàng và %d hoặc nhiá»u hÆ¡n trưá»ng\n" + +#: streamutil.c:393 +#, c-format +msgid "%s: group access flag could not be parsed: %s\n" +msgstr "%s: không thể phân tích cú pháp cá» truy cập nhóm: %s\n" + +#: streamutil.c:554 +#, c-format +msgid "" +"%s: could not create replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: không thể tạo replication slot \"%s\": có %d hàng và %d trưá»ng, kỳ vá»ng " +"%d hàng và %d trưá»ng\n" + +#: streamutil.c:599 +#, c-format +msgid "" +"%s: could not drop replication slot \"%s\": got %d rows and %d fields, " +"expected %d rows and %d fields\n" +msgstr "" +"%s: không thể xóa replication slot \"%s\": có %d hàng và %d trưá»ng, kỳ vá»ng " +"%d hàng và %d trưá»ng\n" + +#: walmethods.c:436 walmethods.c:906 +msgid "could not compress data" +msgstr "không thể nén dữ liệu" + +#: walmethods.c:460 +msgid "could not reset compression stream" +msgstr "không thể đặt lại luồng nén" + +#: walmethods.c:562 +msgid "could not initialize compression library" +msgstr "không thể khởi tạo thư viện nén" + +#: walmethods.c:574 +msgid "implementation error: tar files can't have more than one open file" +msgstr "lá»—i triển khai: tệp tar không thể có nhiá»u hÆ¡n má»™t tệp mở" + +#: walmethods.c:588 +msgid "could not create tar header" +msgstr "không thể tạo tiêu đỠtar" + +#: walmethods.c:602 walmethods.c:640 walmethods.c:829 walmethods.c:840 +msgid "could not change compression parameters" +msgstr "không thể thay đổi thông số nén" + +#: walmethods.c:722 +msgid "unlink not supported with compression" +msgstr "há»§y liên kết không được há»— trợ vá»›i nén" + +#: walmethods.c:922 +msgid "could not close compression stream" +msgstr "không thể đóng luồng nén" diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c index 10768786301..d73f6145c1a 100644 --- a/src/bin/pg_basebackup/receivelog.c +++ b/src/bin/pg_basebackup/receivelog.c @@ -5,7 +5,7 @@ * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/receivelog.c @@ -27,6 +27,7 @@ #include "libpq-fe.h" #include "access/xlog_internal.h" #include "common/file_utils.h" +#include "common/logging.h" /* fd and filename for currently open WAL file */ @@ -38,23 +39,23 @@ static XLogRecPtr lastFlushPosition = InvalidXLogRecPtr; static bool still_sending = true; /* feedback still needs to be sent? */ static PGresult *HandleCopyStream(PGconn *conn, StreamCtl *stream, - XLogRecPtr *stoppos); + XLogRecPtr *stoppos); static int CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket); -static int CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, - char **buffer); +static int CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, + char **buffer); static bool ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, - int len, XLogRecPtr blockpos, TimestampTz *last_status); + int len, XLogRecPtr blockpos, TimestampTz *last_status); static bool ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, - XLogRecPtr *blockpos); + XLogRecPtr *blockpos); static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf, - XLogRecPtr blockpos, XLogRecPtr *stoppos); + XLogRecPtr blockpos, XLogRecPtr *stoppos); static bool CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, - XLogRecPtr *stoppos); + XLogRecPtr *stoppos); static long CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout, - TimestampTz last_status); + TimestampTz last_status); static bool ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, - uint32 *timeline); + uint32 *timeline); static bool mark_file_as_archived(StreamCtl *stream, const char *fname) @@ -68,8 +69,8 @@ mark_file_as_archived(StreamCtl *stream, const char *fname) f = stream->walmethod->open_for_write(tmppath, NULL, 0); if (f == NULL) { - fprintf(stderr, _("%s: could not create archive status file \"%s\": %s\n"), - progname, tmppath, stream->walmethod->getlasterror()); + pg_log_error("could not create archive status file \"%s\": %s", + tmppath, stream->walmethod->getlasterror()); return false; } @@ -115,9 +116,8 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint) size = stream->walmethod->get_file_size(fn); if (size < 0) { - fprintf(stderr, - _("%s: could not get size of write-ahead log file \"%s\": %s\n"), - progname, fn, stream->walmethod->getlasterror()); + pg_log_error("could not get size of write-ahead log file \"%s\": %s", + fn, stream->walmethod->getlasterror()); return false; } if (size == WalSegSz) @@ -126,20 +126,18 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint) f = stream->walmethod->open_for_write(current_walfile_name, stream->partial_suffix, 0); if (f == NULL) { - fprintf(stderr, - _("%s: could not open existing write-ahead log file \"%s\": %s\n"), - progname, fn, stream->walmethod->getlasterror()); + pg_log_error("could not open existing write-ahead log file \"%s\": %s", + fn, stream->walmethod->getlasterror()); return false; } /* fsync file in case of a previous crash */ if (stream->walmethod->sync(f) != 0) { - fprintf(stderr, - _("%s: could not fsync existing write-ahead log file \"%s\": %s\n"), - progname, fn, stream->walmethod->getlasterror()); + pg_log_fatal("could not fsync existing write-ahead log file \"%s\": %s", + fn, stream->walmethod->getlasterror()); stream->walmethod->close(f, CLOSE_UNLINK); - return false; + exit(1); } walfile = f; @@ -150,11 +148,10 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint) /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; - fprintf(stderr, - ngettext("%s: write-ahead log file \"%s\" has %d byte, should be 0 or %d\n", - "%s: write-ahead log file \"%s\" has %d bytes, should be 0 or %d\n", - size), - progname, fn, (int) size, WalSegSz); + pg_log_error(ngettext("write-ahead log file \"%s\" has %d byte, should be 0 or %d", + "write-ahead log file \"%s\" has %d bytes, should be 0 or %d", + size), + fn, (int) size, WalSegSz); return false; } /* File existed and was empty, so fall through and open */ @@ -166,9 +163,8 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint) stream->partial_suffix, WalSegSz); if (f == NULL) { - fprintf(stderr, - _("%s: could not open write-ahead log file \"%s\": %s\n"), - progname, fn, stream->walmethod->getlasterror()); + pg_log_error("could not open write-ahead log file \"%s\": %s", + fn, stream->walmethod->getlasterror()); return false; } @@ -193,9 +189,8 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos) currpos = stream->walmethod->get_current_pos(walfile); if (currpos == -1) { - fprintf(stderr, - _("%s: could not determine seek position in file \"%s\": %s\n"), - progname, current_walfile_name, stream->walmethod->getlasterror()); + pg_log_error("could not determine seek position in file \"%s\": %s", + current_walfile_name, stream->walmethod->getlasterror()); stream->walmethod->close(walfile, CLOSE_UNLINK); walfile = NULL; @@ -208,9 +203,8 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos) r = stream->walmethod->close(walfile, CLOSE_NORMAL); else { - fprintf(stderr, - _("%s: not renaming \"%s%s\", segment is not complete\n"), - progname, current_walfile_name, stream->partial_suffix); + pg_log_info("not renaming \"%s%s\", segment is not complete", + current_walfile_name, stream->partial_suffix); r = stream->walmethod->close(walfile, CLOSE_NO_RENAME); } } @@ -221,8 +215,8 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos) if (r != 0) { - fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), - progname, current_walfile_name, stream->walmethod->getlasterror()); + pg_log_error("could not close file \"%s\": %s", + current_walfile_name, stream->walmethod->getlasterror()); return false; } @@ -278,23 +272,23 @@ writeTimeLineHistoryFile(StreamCtl *stream, char *filename, char *content) TLHistoryFileName(histfname, stream->timeline); if (strcmp(histfname, filename) != 0) { - fprintf(stderr, _("%s: server reported unexpected history file name for timeline %u: %s\n"), - progname, stream->timeline, filename); + pg_log_error("server reported unexpected history file name for timeline %u: %s", + stream->timeline, filename); return false; } f = stream->walmethod->open_for_write(histfname, ".tmp", 0); if (f == NULL) { - fprintf(stderr, _("%s: could not create timeline history file \"%s\": %s\n"), - progname, histfname, stream->walmethod->getlasterror()); + pg_log_error("could not create timeline history file \"%s\": %s", + histfname, stream->walmethod->getlasterror()); return false; } if ((int) stream->walmethod->write(f, content, size) != size) { - fprintf(stderr, _("%s: could not write timeline history file \"%s\": %s\n"), - progname, histfname, stream->walmethod->getlasterror()); + pg_log_error("could not write timeline history file \"%s\": %s", + histfname, stream->walmethod->getlasterror()); /* * If we fail to make the file, delete it to release disk space @@ -306,8 +300,8 @@ writeTimeLineHistoryFile(StreamCtl *stream, char *filename, char *content) if (stream->walmethod->close(f, CLOSE_NORMAL) != 0) { - fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), - progname, histfname, stream->walmethod->getlasterror()); + pg_log_error("could not close file \"%s\": %s", + histfname, stream->walmethod->getlasterror()); return false; } @@ -349,8 +343,8 @@ sendFeedback(PGconn *conn, XLogRecPtr blockpos, TimestampTz now, bool replyReque if (PQputCopyData(conn, replybuf, len) <= 0 || PQflush(conn)) { - fprintf(stderr, _("%s: could not send feedback packet: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not send feedback packet: %s", + PQerrorMessage(conn)); return false; } @@ -383,20 +377,18 @@ CheckServerVersionForStreaming(PGconn *conn) { const char *serverver = PQparameterStatus(conn, "server_version"); - fprintf(stderr, _("%s: incompatible server version %s; client does not support streaming from server versions older than %s\n"), - progname, - serverver ? serverver : "'unknown'", - "9.3"); + pg_log_error("incompatible server version %s; client does not support streaming from server versions older than %s", + serverver ? serverver : "'unknown'", + "9.3"); return false; } else if (serverMajor > maxServerMajor) { const char *serverver = PQparameterStatus(conn, "server_version"); - fprintf(stderr, _("%s: incompatible server version %s; client does not support streaming from server versions newer than %s\n"), - progname, - serverver ? serverver : "'unknown'", - PG_VERSION); + pg_log_error("incompatible server version %s; client does not support streaming from server versions newer than %s", + serverver ? serverver : "'unknown'", + PG_VERSION); return false; } return true; @@ -489,33 +481,28 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) res = PQexec(conn, "IDENTIFY_SYSTEM"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, - _("%s: could not send replication command \"%s\": %s"), - progname, "IDENTIFY_SYSTEM", PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + "IDENTIFY_SYSTEM", PQerrorMessage(conn)); PQclear(res); return false; } if (PQntuples(res) != 1 || PQnfields(res) < 3) { - fprintf(stderr, - _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 3); + pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields", + PQntuples(res), PQnfields(res), 1, 3); PQclear(res); return false; } if (strcmp(stream->sysidentifier, PQgetvalue(res, 0, 0)) != 0) { - fprintf(stderr, - _("%s: system identifier does not match between base backup and streaming connection\n"), - progname); + pg_log_error("system identifier does not match between base backup and streaming connection"); PQclear(res); return false; } if (stream->timeline > atoi(PQgetvalue(res, 0, 1))) { - fprintf(stderr, - _("%s: starting timeline %u is not present in the server\n"), - progname, stream->timeline); + pg_log_error("starting timeline %u is not present in the server", + stream->timeline); PQclear(res); return false; } @@ -543,8 +530,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) if (PQresultStatus(res) != PGRES_TUPLES_OK) { /* FIXME: we might send it ok, but get an error */ - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, "TIMELINE_HISTORY", PQresultErrorMessage(res)); + pg_log_error("could not send replication command \"%s\": %s", + "TIMELINE_HISTORY", PQresultErrorMessage(res)); PQclear(res); return false; } @@ -555,9 +542,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) */ if (PQnfields(res) != 2 || PQntuples(res) != 1) { - fprintf(stderr, - _("%s: unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 2); + pg_log_warning("unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields", + PQntuples(res), PQnfields(res), 1, 2); } /* Write the history file to disk */ @@ -583,8 +569,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) res = PQexec(conn, query); if (PQresultStatus(res) != PGRES_COPY_BOTH) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, "START_REPLICATION", PQresultErrorMessage(res)); + pg_log_error("could not send replication command \"%s\": %s", + "START_REPLICATION", PQresultErrorMessage(res)); PQclear(res); return false; } @@ -627,18 +613,15 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) /* Sanity check the values the server gave us */ if (newtimeline <= stream->timeline) { - fprintf(stderr, - _("%s: server reported unexpected next timeline %u, following timeline %u\n"), - progname, newtimeline, stream->timeline); + pg_log_error("server reported unexpected next timeline %u, following timeline %u", + newtimeline, stream->timeline); goto error; } if (stream->startpos > stoppos) { - fprintf(stderr, - _("%s: server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X\n"), - progname, - stream->timeline, (uint32) (stoppos >> 32), (uint32) stoppos, - newtimeline, (uint32) (stream->startpos >> 32), (uint32) stream->startpos); + pg_log_error("server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X", + stream->timeline, (uint32) (stoppos >> 32), (uint32) stoppos, + newtimeline, (uint32) (stream->startpos >> 32), (uint32) stream->startpos); goto error; } @@ -646,9 +629,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, - _("%s: unexpected termination of replication stream: %s"), - progname, PQresultErrorMessage(res)); + pg_log_error("unexpected termination of replication stream: %s", + PQresultErrorMessage(res)); PQclear(res); goto error; } @@ -677,17 +659,15 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) return true; else { - fprintf(stderr, _("%s: replication stream was terminated before stop point\n"), - progname); + pg_log_error("replication stream was terminated before stop point"); goto error; } } else { /* Server returned an error. */ - fprintf(stderr, - _("%s: unexpected termination of replication stream: %s"), - progname, PQresultErrorMessage(res)); + pg_log_error("unexpected termination of replication stream: %s", + PQresultErrorMessage(res)); PQclear(res); goto error; } @@ -695,8 +675,8 @@ ReceiveXlogStream(PGconn *conn, StreamCtl *stream) error: if (walfile != NULL && stream->walmethod->close(walfile, CLOSE_NO_RENAME) != 0) - fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), - progname, current_walfile_name, stream->walmethod->getlasterror()); + pg_log_error("could not close file \"%s\": %s", + current_walfile_name, stream->walmethod->getlasterror()); walfile = NULL; return false; } @@ -725,9 +705,8 @@ ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, uint32 *timeline) */ if (PQnfields(res) < 2 || PQntuples(res) != 1) { - fprintf(stderr, - _("%s: unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 2); + pg_log_error("unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields", + PQntuples(res), PQnfields(res), 1, 2); return false; } @@ -735,9 +714,8 @@ ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, uint32 *timeline) if (sscanf(PQgetvalue(res, 0, 1), "%X/%X", &startpos_xlogid, &startpos_xrecoff) != 2) { - fprintf(stderr, - _("%s: could not parse next timeline's starting point \"%s\"\n"), - progname, PQgetvalue(res, 0, 1)); + pg_log_error("could not parse next timeline's starting point \"%s\"", + PQgetvalue(res, 0, 1)); return false; } *startpos = ((uint64) startpos_xlogid << 32) | startpos_xrecoff; @@ -785,9 +763,9 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream, { if (stream->walmethod->sync(walfile) != 0) { - fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"), - progname, current_walfile_name, stream->walmethod->getlasterror()); - goto error; + pg_log_fatal("could not fsync file \"%s\": %s", + current_walfile_name, stream->walmethod->getlasterror()); + exit(1); } lastFlushPosition = blockpos; @@ -855,8 +833,8 @@ HandleCopyStream(PGconn *conn, StreamCtl *stream, } else { - fprintf(stderr, _("%s: unrecognized streaming header: \"%c\"\n"), - progname, copybuf[0]); + pg_log_error("unrecognized streaming header: \"%c\"", + copybuf[0]); goto error; } @@ -895,8 +873,7 @@ CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket) connsocket = PQsocket(conn); if (connsocket < 0) { - fprintf(stderr, _("%s: invalid socket: %s"), progname, - PQerrorMessage(conn)); + pg_log_error("invalid socket: %s", PQerrorMessage(conn)); return -1; } @@ -924,8 +901,7 @@ CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket) { if (errno == EINTR) return 0; /* Got a signal, so not an error */ - fprintf(stderr, _("%s: select() failed: %s\n"), - progname, strerror(errno)); + pg_log_error("select() failed: %m"); return -1; } if (ret > 0 && FD_ISSET(connsocket, &input_mask)) @@ -975,9 +951,8 @@ CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, /* Now there is actually data on the socket */ if (PQconsumeInput(conn) == 0) { - fprintf(stderr, - _("%s: could not receive data from WAL stream: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not receive data from WAL stream: %s", + PQerrorMessage(conn)); return -1; } @@ -990,8 +965,7 @@ CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket, return -2; if (rawlen == -2) { - fprintf(stderr, _("%s: could not read COPY data: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not read COPY data: %s", PQerrorMessage(conn)); return -1; } @@ -1021,8 +995,7 @@ ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, if (len < pos + 1) { - fprintf(stderr, _("%s: streaming header too small: %d\n"), - progname, len); + pg_log_error("streaming header too small: %d", len); return false; } replyRequested = copybuf[pos]; @@ -1042,9 +1015,9 @@ ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, */ if (stream->walmethod->sync(walfile) != 0) { - fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"), - progname, current_walfile_name, stream->walmethod->getlasterror()); - return false; + pg_log_fatal("could not fsync file \"%s\": %s", + current_walfile_name, stream->walmethod->getlasterror()); + exit(1); } lastFlushPosition = blockpos; } @@ -1088,8 +1061,7 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, hdr_len += 8; /* sendTime */ if (len < hdr_len) { - fprintf(stderr, _("%s: streaming header too small: %d\n"), - progname, len); + pg_log_error("streaming header too small: %d", len); return false; } *blockpos = fe_recvint64(©buf[1]); @@ -1106,9 +1078,8 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, /* No file open yet */ if (xlogoff != 0) { - fprintf(stderr, - _("%s: received write-ahead log record for offset %u with no file open\n"), - progname, xlogoff); + pg_log_error("received write-ahead log record for offset %u with no file open", + xlogoff); return false; } } @@ -1117,9 +1088,8 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, /* More data in existing segment */ if (stream->walmethod->get_current_pos(walfile) != xlogoff) { - fprintf(stderr, - _("%s: got WAL data offset %08x, expected %08x\n"), - progname, xlogoff, (int) stream->walmethod->get_current_pos(walfile)); + pg_log_error("got WAL data offset %08x, expected %08x", + xlogoff, (int) stream->walmethod->get_current_pos(walfile)); return false; } } @@ -1152,10 +1122,9 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, if (stream->walmethod->write(walfile, copybuf + hdr_len + bytes_written, bytes_to_write) != bytes_to_write) { - fprintf(stderr, - _("%s: could not write %u bytes to WAL file \"%s\": %s\n"), - progname, bytes_to_write, current_walfile_name, - stream->walmethod->getlasterror()); + pg_log_error("could not write %u bytes to WAL file \"%s\": %s", + bytes_to_write, current_walfile_name, + stream->walmethod->getlasterror()); return false; } @@ -1178,8 +1147,8 @@ ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len, { if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn)) { - fprintf(stderr, _("%s: could not send copy-end packet: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not send copy-end packet: %s", + PQerrorMessage(conn)); return false; } still_sending = false; @@ -1218,9 +1187,8 @@ HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf, { if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn)) { - fprintf(stderr, - _("%s: could not send copy-end packet: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not send copy-end packet: %s", + PQerrorMessage(conn)); PQclear(res); return NULL; } @@ -1250,8 +1218,8 @@ CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos, } if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn)) { - fprintf(stderr, _("%s: could not send copy-end packet: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("could not send copy-end packet: %s", + PQerrorMessage(conn)); return false; } still_sending = false; diff --git a/src/bin/pg_basebackup/receivelog.h b/src/bin/pg_basebackup/receivelog.h index a636cf3fa01..b6e2743f554 100644 --- a/src/bin/pg_basebackup/receivelog.h +++ b/src/bin/pg_basebackup/receivelog.h @@ -2,7 +2,7 @@ * * receivelog.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/receivelog.h @@ -53,6 +53,6 @@ typedef struct StreamCtl extern bool CheckServerVersionForStreaming(PGconn *conn); extern bool ReceiveXlogStream(PGconn *conn, - StreamCtl *stream); + StreamCtl *stream); #endif /* RECEIVELOG_H */ diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c index 4fd536931b1..8d8ac11b664 100644 --- a/src/bin/pg_basebackup/streamutil.c +++ b/src/bin/pg_basebackup/streamutil.c @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * streamutil.c - utility functions for pg_basebackup, pg_receivewal and - * pg_recvlogical + * pg_recvlogical * * Author: Magnus Hagander * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/streamutil.c @@ -24,6 +24,7 @@ #include "access/xlog_internal.h" #include "common/fe_memutils.h" #include "common/file_perm.h" +#include "common/logging.h" #include "datatype/timestamp.h" #include "fe_utils/connect.h" #include "port/pg_bswap.h" @@ -90,7 +91,7 @@ GetConnection(void) conn_opts = PQconninfoParse(connection_string, &err_msg); if (conn_opts == NULL) { - fprintf(stderr, "%s: %s", progname, err_msg); + pg_log_error("%s", err_msg); exit(1); } @@ -183,8 +184,7 @@ GetConnection(void) */ if (!tmpconn) { - fprintf(stderr, _("%s: could not connect to server\n"), - progname); + pg_log_error("could not connect to server"); exit(1); } @@ -201,8 +201,8 @@ GetConnection(void) if (PQstatus(tmpconn) != CONNECTION_OK) { - fprintf(stderr, _("%s: could not connect to server: %s"), - progname, PQerrorMessage(tmpconn)); + pg_log_error("could not connect to server: %s", + PQerrorMessage(tmpconn)); PQfinish(tmpconn); free(values); free(keywords); @@ -219,19 +219,19 @@ GetConnection(void) /* * Set always-secure search path, so malicious users can't get control. - * The capacity to run normal SQL queries was added in PostgreSQL - * 10, so the search path cannot be changed (by us or attackers) on - * earlier versions. + * The capacity to run normal SQL queries was added in PostgreSQL 10, so + * the search path cannot be changed (by us or attackers) on earlier + * versions. */ - if (dbname != NULL && PQserverVersion(conn) >= 100000) + if (dbname != NULL && PQserverVersion(tmpconn) >= 100000) { PGresult *res; res = PQexec(tmpconn, ALWAYS_SECURE_SEARCH_PATH_SQL); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not clear search_path: %s\n"), - progname, PQerrorMessage(tmpconn)); + pg_log_error("could not clear search_path: %s", + PQerrorMessage(tmpconn)); PQclear(res); PQfinish(tmpconn); exit(1); @@ -246,18 +246,14 @@ GetConnection(void) tmpparam = PQparameterStatus(tmpconn, "integer_datetimes"); if (!tmpparam) { - fprintf(stderr, - _("%s: could not determine server setting for integer_datetimes\n"), - progname); + pg_log_error("could not determine server setting for integer_datetimes"); PQfinish(tmpconn); exit(1); } if (strcmp(tmpparam, "on") != 0) { - fprintf(stderr, - _("%s: integer_datetimes compile flag does not match server\n"), - progname); + pg_log_error("integer_datetimes compile flag does not match server"); PQfinish(tmpconn); exit(1); } @@ -300,17 +296,16 @@ RetrieveWalSegSize(PGconn *conn) res = PQexec(conn, "SHOW wal_segment_size"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s\n"), - progname, "SHOW wal_segment_size", PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + "SHOW wal_segment_size", PQerrorMessage(conn)); PQclear(res); return false; } if (PQntuples(res) != 1 || PQnfields(res) < 1) { - fprintf(stderr, - _("%s: could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 1); + pg_log_error("could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields", + PQntuples(res), PQnfields(res), 1, 1); PQclear(res); return false; @@ -319,8 +314,7 @@ RetrieveWalSegSize(PGconn *conn) /* fetch xlog value and unit from the result */ if (sscanf(PQgetvalue(res, 0, 0), "%d%s", &xlog_val, xlog_unit) != 2) { - fprintf(stderr, _("%s: WAL segment size could not be parsed\n"), - progname); + pg_log_error("WAL segment size could not be parsed"); return false; } @@ -335,9 +329,10 @@ RetrieveWalSegSize(PGconn *conn) if (!IsValidWalSegSize(WalSegSz)) { - fprintf(stderr, - _("%s: WAL segment size must be a power of two between 1MB and 1GB, but the remote server reported a value of %d bytes\n"), - progname, WalSegSz); + pg_log_error(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte", + "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes", + WalSegSz), + WalSegSz); return false; } @@ -372,17 +367,16 @@ RetrieveDataDirCreatePerm(PGconn *conn) res = PQexec(conn, "SHOW data_directory_mode"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s\n"), - progname, "SHOW data_directory_mode", PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + "SHOW data_directory_mode", PQerrorMessage(conn)); PQclear(res); return false; } if (PQntuples(res) != 1 || PQnfields(res) < 1) { - fprintf(stderr, - _("%s: could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 1); + pg_log_error("could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields", + PQntuples(res), PQnfields(res), 1, 1); PQclear(res); return false; @@ -390,8 +384,8 @@ RetrieveDataDirCreatePerm(PGconn *conn) if (sscanf(PQgetvalue(res, 0, 0), "%o", &data_directory_mode) != 1) { - fprintf(stderr, _("%s: group access flag could not be parsed: %s\n"), - progname, PQgetvalue(res, 0, 0)); + pg_log_error("group access flag could not be parsed: %s", + PQgetvalue(res, 0, 0)); PQclear(res); return false; @@ -425,17 +419,16 @@ RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, res = PQexec(conn, "IDENTIFY_SYSTEM"); if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, "IDENTIFY_SYSTEM", PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + "IDENTIFY_SYSTEM", PQerrorMessage(conn)); PQclear(res); return false; } if (PQntuples(res) != 1 || PQnfields(res) < 3) { - fprintf(stderr, - _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 3); + pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields", + PQntuples(res), PQnfields(res), 1, 3); PQclear(res); return false; @@ -454,9 +447,8 @@ RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, { if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2) { - fprintf(stderr, - _("%s: could not parse write-ahead log location \"%s\"\n"), - progname, PQgetvalue(res, 0, 2)); + pg_log_error("could not parse write-ahead log location \"%s\"", + PQgetvalue(res, 0, 2)); PQclear(res); return false; @@ -472,9 +464,8 @@ RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, { if (PQnfields(res) < 4) { - fprintf(stderr, - _("%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"), - progname, PQntuples(res), PQnfields(res), 1, 4); + pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields", + PQntuples(res), PQnfields(res), 1, 4); PQclear(res); return false; @@ -509,19 +500,19 @@ CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin, /* Build query */ appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\"", slot_name); if (is_temporary) - appendPQExpBuffer(query, " TEMPORARY"); + appendPQExpBufferStr(query, " TEMPORARY"); if (is_physical) { - appendPQExpBuffer(query, " PHYSICAL"); + appendPQExpBufferStr(query, " PHYSICAL"); if (reserve_wal) - appendPQExpBuffer(query, " RESERVE_WAL"); + appendPQExpBufferStr(query, " RESERVE_WAL"); } else { appendPQExpBuffer(query, " LOGICAL \"%s\"", plugin); if (PQserverVersion(conn) >= 100000) /* pg_recvlogical doesn't use an exported snapshot, so suppress */ - appendPQExpBuffer(query, " NOEXPORT_SNAPSHOT"); + appendPQExpBufferStr(query, " NOEXPORT_SNAPSHOT"); } res = PQexec(conn, query->data); @@ -539,8 +530,8 @@ CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin, } else { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, query->data, PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + query->data, PQerrorMessage(conn)); destroyPQExpBuffer(query); PQclear(res); @@ -550,10 +541,9 @@ CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin, if (PQntuples(res) != 1 || PQnfields(res) != 4) { - fprintf(stderr, - _("%s: could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n"), - progname, slot_name, - PQntuples(res), PQnfields(res), 1, 4); + pg_log_error("could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields", + slot_name, + PQntuples(res), PQnfields(res), 1, 4); destroyPQExpBuffer(query); PQclear(res); @@ -585,8 +575,8 @@ DropReplicationSlot(PGconn *conn, const char *slot_name) res = PQexec(conn, query->data); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: could not send replication command \"%s\": %s"), - progname, query->data, PQerrorMessage(conn)); + pg_log_error("could not send replication command \"%s\": %s", + query->data, PQerrorMessage(conn)); destroyPQExpBuffer(query); PQclear(res); @@ -595,10 +585,9 @@ DropReplicationSlot(PGconn *conn, const char *slot_name) if (PQntuples(res) != 0 || PQnfields(res) != 0) { - fprintf(stderr, - _("%s: could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields\n"), - progname, slot_name, - PQntuples(res), PQnfields(res), 0, 0); + pg_log_error("could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields", + slot_name, + PQntuples(res), PQnfields(res), 0, 0); destroyPQExpBuffer(query); PQclear(res); diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h index 6854bbc31d9..a756eee262c 100644 --- a/src/bin/pg_basebackup/streamutil.h +++ b/src/bin/pg_basebackup/streamutil.h @@ -2,7 +2,7 @@ * * streamutil.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/streamutil.h @@ -33,21 +33,21 @@ extern PGconn *GetConnection(void); /* Replication commands */ extern bool CreateReplicationSlot(PGconn *conn, const char *slot_name, - const char *plugin, bool is_temporary, - bool is_physical, bool reserve_wal, - bool slot_exists_ok); + const char *plugin, bool is_temporary, + bool is_physical, bool reserve_wal, + bool slot_exists_ok); extern bool DropReplicationSlot(PGconn *conn, const char *slot_name); extern bool RunIdentifySystem(PGconn *conn, char **sysid, - TimeLineID *starttli, - XLogRecPtr *startpos, - char **db_name); + TimeLineID *starttli, + XLogRecPtr *startpos, + char **db_name); extern bool RetrieveWalSegSize(PGconn *conn); extern TimestampTz feGetCurrentTimestamp(void); extern void feTimestampDifference(TimestampTz start_time, TimestampTz stop_time, - long *secs, int *microsecs); + long *secs, int *microsecs); extern bool feTimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, - int msec); + int msec); extern void fe_sendint64(int64 i, char *buf); extern int64 fe_recvint64(char *buf); diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl index 0cd510eeea4..b7d36b65dd7 100644 --- a/src/bin/pg_basebackup/t/010_pg_basebackup.pl +++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl @@ -20,7 +20,7 @@ umask(0077); # Initialize node without replication settings -$node->init(extra => [ '--data-checksums' ]); +$node->init(extra => ['--data-checksums']); $node->start; my $pgdata = $node->data_dir; @@ -44,10 +44,10 @@ ok(!-d "$tempdir/backup", 'backup directory was cleaned up'); -# Create a backup directory that is not empty so the next commnd will fail +# Create a backup directory that is not empty so the next command will fail # but leave the data directory behind mkdir("$tempdir/backup") - or BAIL_OUT("unable to create $tempdir/backup"); + or BAIL_OUT("unable to create $tempdir/backup"); append_to_file("$tempdir/backup/dir-not-empty.txt", "Some data"); $node->command_fails([ 'pg_basebackup', '-D', "$tempdir/backup", '-n' ], @@ -86,13 +86,14 @@ # Make sure main and init forks exist ok(-f "$pgdata/${baseUnloggedPath}_init", 'unlogged init fork in base'); -ok(-f "$pgdata/$baseUnloggedPath", 'unlogged main fork in base'); +ok(-f "$pgdata/$baseUnloggedPath", 'unlogged main fork in base'); # Create files that look like temporary relations to ensure they are ignored. my $postgresOid = $node->safe_psql('postgres', q{select oid from pg_database where datname = 'postgres'}); -my @tempRelationFiles = qw(t999_999 t9999_999.1 t999_9999_vm t99999_99999_vm.1); +my @tempRelationFiles = + qw(t999_999 t9999_999.1 t999_9999_vm t99999_99999_vm.1); foreach my $filename (@tempRelationFiles) { @@ -107,10 +108,11 @@ # Permissions on backup should be default SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive("$tempdir/backup", 0700, 0600), - "check backup dir permissions"); + "check backup dir permissions"); } # Only archive_status directory should be copied in pg_wal/. @@ -133,8 +135,7 @@ # These files should not be copied. foreach my $filename ( qw(postgresql.auto.conf.tmp postmaster.opts postmaster.pid tablespace_map current_logfiles.tmp - global/pg_internal.init) - ) + global/pg_internal.init)) { ok(!-f "$tempdir/backup/$filename", "$filename not copied"); } @@ -142,14 +143,14 @@ # Unlogged relation forks other than init should not be copied ok(-f "$tempdir/backup/${baseUnloggedPath}_init", 'unlogged init fork in backup'); -ok(!-f "$tempdir/backup/$baseUnloggedPath", +ok( !-f "$tempdir/backup/$baseUnloggedPath", 'unlogged main fork not in backup'); # Temp relations should not be copied. foreach my $filename (@tempRelationFiles) { - ok(!-f "$tempdir/backup/base/$postgresOid/$filename", - "base/$postgresOid/$filename not copied"); + ok( !-f "$tempdir/backup/base/$postgresOid/$filename", + "base/$postgresOid/$filename not copied"); } # Make sure existing backup_label was ignored. @@ -158,8 +159,10 @@ rmtree("$tempdir/backup"); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backup2", '--waldir', - "$tempdir/xlog2" ], + [ + 'pg_basebackup', '-D', "$tempdir/backup2", '--waldir', + "$tempdir/xlog2" + ], 'separate xlog directory'); ok(-f "$tempdir/backup2/PG_VERSION", 'backup was created'); ok(-d "$tempdir/xlog2/", 'xlog directory was created'); @@ -178,8 +181,10 @@ [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ], '-T with empty new directory fails'); $node->command_fails( - [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', - "-T/foo=/bar=/baz" ], + [ + 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', + "-T/foo=/bar=/baz" + ], '-T with multiple = fails'); $node->command_fails( [ 'pg_basebackup', '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ], @@ -246,22 +251,25 @@ # Create an unlogged table to test that forks other than init are not copied. $node->safe_psql('postgres', - 'CREATE UNLOGGED TABLE tblspc1_unlogged (id int) TABLESPACE tblspc1;'); + 'CREATE UNLOGGED TABLE tblspc1_unlogged (id int) TABLESPACE tblspc1;' + ); - my $tblspc1UnloggedPath = $node->safe_psql( - 'postgres', q{select pg_relation_filepath('tblspc1_unlogged')}); + my $tblspc1UnloggedPath = $node->safe_psql('postgres', + q{select pg_relation_filepath('tblspc1_unlogged')}); # Make sure main and init forks exist - ok(-f "$pgdata/${tblspc1UnloggedPath}_init", + ok( -f "$pgdata/${tblspc1UnloggedPath}_init", 'unlogged init fork in tablespace'); - ok(-f "$pgdata/$tblspc1UnloggedPath", - 'unlogged main fork in tablespace'); + ok(-f "$pgdata/$tblspc1UnloggedPath", 'unlogged main fork in tablespace'); # Create files that look like temporary relations to ensure they are ignored # in a tablespace. my @tempRelationFiles = qw(t888_888 t888888_888888_vm.1); - my $tblSpc1Id = basename(dirname(dirname($node->safe_psql('postgres', - q{select pg_relation_filepath('test1')})))); + my $tblSpc1Id = basename( + dirname( + dirname( + $node->safe_psql( + 'postgres', q{select pg_relation_filepath('test1')})))); foreach my $filename (@tempRelationFiles) { @@ -275,8 +283,10 @@ 'plain format with tablespaces fails without tablespace mapping'); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp', - "-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" ], + [ + 'pg_basebackup', '-D', "$tempdir/backup1", '-Fp', + "-T$shorter_tempdir/tblspc1=$tempdir/tbackup/tblspc1" + ], 'plain format with tablespaces succeeds with tablespace mapping'); ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated'); opendir(my $dh, "$pgdata/pg_tblspc") or die; @@ -284,16 +294,17 @@ -l "$tempdir/backup1/pg_tblspc/$_" and readlink "$tempdir/backup1/pg_tblspc/$_" eq "$tempdir/tbackup/tblspc1" - } readdir($dh)), + } readdir($dh)), "tablespace symlink was updated"); closedir $dh; # Group access should be enabled on all backup files ok(check_mode_recursive("$tempdir/backup1", 0750, 0640), - "check backup dir permissions"); + "check backup dir permissions"); # Unlogged relation forks other than init should not be copied - my ($tblspc1UnloggedBackupPath) = $tblspc1UnloggedPath =~ /[^\/]*\/[^\/]*\/[^\/]*$/g; + my ($tblspc1UnloggedBackupPath) = + $tblspc1UnloggedPath =~ /[^\/]*\/[^\/]*\/[^\/]*$/g; ok(-f "$tempdir/tbackup/tblspc1/${tblspc1UnloggedBackupPath}_init", 'unlogged init fork in tablespace backup'); @@ -303,15 +314,15 @@ # Temp relations should not be copied. foreach my $filename (@tempRelationFiles) { - ok(!-f "$tempdir/tbackup/tblspc1/$tblSpc1Id/$postgresOid/$filename", - "[tblspc1]/$postgresOid/$filename not copied"); + ok( !-f "$tempdir/tbackup/tblspc1/$tblSpc1Id/$postgresOid/$filename", + "[tblspc1]/$postgresOid/$filename not copied"); # Also remove temp relation files or tablespace drop will fail. my $filepath = - "$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename"; + "$shorter_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename"; unlink($filepath) - or BAIL_OUT("unable to unlink $filepath"); + or BAIL_OUT("unable to unlink $filepath"); } ok( -d "$tempdir/backup1/pg_replslot", @@ -325,8 +336,10 @@ $node->safe_psql('postgres', "CREATE TABLESPACE tblspc2 LOCATION '$shorter_tempdir/tbl=spc2';"); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backup3", '-Fp', - "-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" ], + [ + 'pg_basebackup', '-D', "$tempdir/backup3", '-Fp', + "-T$shorter_tempdir/tbl\\=spc2=$tempdir/tbackup/tbl\\=spc2" + ], 'mapping tablespace with = sign in path'); ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated'); @@ -345,19 +358,16 @@ $node->command_ok([ 'pg_basebackup', '-D', "$tempdir/backupR", '-R' ], 'pg_basebackup -R runs'); -ok(-f "$tempdir/backupR/recovery.conf", 'recovery.conf was created'); -my $recovery_conf = slurp_file "$tempdir/backupR/recovery.conf"; +ok(-f "$tempdir/backupR/postgresql.auto.conf", 'postgresql.auto.conf exists'); +ok(-f "$tempdir/backupR/standby.signal", 'standby.signal was created'); +my $recovery_conf = slurp_file "$tempdir/backupR/postgresql.auto.conf"; rmtree("$tempdir/backupR"); my $port = $node->port; -like( - $recovery_conf, - qr/^standby_mode = 'on'\n/m, - 'recovery.conf sets standby_mode'); like( $recovery_conf, qr/^primary_conninfo = '.*port=$port.*'\n/m, - 'recovery.conf sets primary_conninfo'); + 'postgresql.auto.conf sets primary_conninfo'); $node->command_ok( [ 'pg_basebackup', '-D', "$tempdir/backupxd" ], @@ -384,41 +394,57 @@ ok(-f "$tempdir/backupxst/pg_wal.tar", "tar file was created"); rmtree("$tempdir/backupxst"); $node->command_ok( - [ 'pg_basebackup', '-D', + [ + 'pg_basebackup', '-D', "$tempdir/backupnoslot", '-X', - 'stream', '--no-slot' ], + 'stream', '--no-slot' + ], 'pg_basebackup -X stream runs with --no-slot'); rmtree("$tempdir/backupnoslot"); $node->command_fails( - [ 'pg_basebackup', '-D', + [ + 'pg_basebackup', '-D', "$tempdir/backupxs_sl_fail", '-X', 'stream', '-S', - 'slot0' ], + 'slot0' + ], 'pg_basebackup fails with nonexistent replication slot'); $node->command_fails( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C' ], + [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C' ], 'pg_basebackup -C fails without slot name'); $node->command_fails( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C', '-S', 'slot0', '--no-slot' ], + [ + 'pg_basebackup', '-D', + "$tempdir/backupxs_slot", '-C', + '-S', 'slot0', + '--no-slot' + ], 'pg_basebackup fails with -C -S --no-slot'); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C', '-S', 'slot0' ], + [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot", '-C', '-S', 'slot0' ], 'pg_basebackup -C runs'); rmtree("$tempdir/backupxs_slot"); -is($node->safe_psql('postgres', q{SELECT slot_name FROM pg_replication_slots WHERE slot_name = 'slot0'}), - 'slot0', - 'replication slot was created'); -isnt($node->safe_psql('postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot0'}), - '', - 'restart LSN of new slot is not null'); +is( $node->safe_psql( + 'postgres', + q{SELECT slot_name FROM pg_replication_slots WHERE slot_name = 'slot0'} + ), + 'slot0', + 'replication slot was created'); +isnt( + $node->safe_psql( + 'postgres', + q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot0'} + ), + '', + 'restart LSN of new slot is not null'); $node->command_fails( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot1", '-C', '-S', 'slot0' ], + [ 'pg_basebackup', '-D', "$tempdir/backupxs_slot1", '-C', '-S', 'slot0' ], 'pg_basebackup fails with -C -S and a previously existing slot'); $node->safe_psql('postgres', @@ -431,8 +457,10 @@ [ 'pg_basebackup', '-D', "$tempdir/fail", '-S', 'slot1', '-X', 'none' ], 'pg_basebackup with replication slot fails without WAL streaming'); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', - 'stream', '-S', 'slot1' ], + [ + 'pg_basebackup', '-D', "$tempdir/backupxs_sl", '-X', + 'stream', '-S', 'slot1' + ], 'pg_basebackup -X stream with replication slot runs'); $lsn = $node->safe_psql('postgres', q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'} @@ -441,13 +469,15 @@ rmtree("$tempdir/backupxs_sl"); $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', - 'stream', '-S', 'slot1', '-R' ], + [ + 'pg_basebackup', '-D', "$tempdir/backupxs_sl_R", '-X', + 'stream', '-S', 'slot1', '-R' + ], 'pg_basebackup with replication slot and -R runs'); like( - slurp_file("$tempdir/backupxs_sl_R/recovery.conf"), + slurp_file("$tempdir/backupxs_sl_R/postgresql.auto.conf"), qr/^primary_slot_name = 'slot1'\n/m, - 'recovery.conf sets primary_slot_name'); + 'recovery conf file sets primary_slot_name'); my $checksum = $node->safe_psql('postgres', 'SHOW data_checksums;'); is($checksum, 'on', 'checksums are enabled'); @@ -455,10 +485,10 @@ # create tables to corrupt and get their relfilenodes my $file_corrupt1 = $node->safe_psql('postgres', - q{SELECT a INTO corrupt1 FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')} + q{SELECT a INTO corrupt1 FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')} ); my $file_corrupt2 = $node->safe_psql('postgres', - q{SELECT b INTO corrupt2 FROM generate_series(1,2) AS b; ALTER TABLE corrupt2 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt2')} + q{SELECT b INTO corrupt2 FROM generate_series(1,2) AS b; ALTER TABLE corrupt2 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt2')} ); # set page header and block sizes @@ -469,56 +499,60 @@ system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; open $file, '+<', "$pgdata/$file_corrupt1"; seek($file, $pageheader_size, 0); -syswrite($file, '\0\0\0\0\0\0\0\0\0'); +syswrite($file, "\0\0\0\0\0\0\0\0\0"); close $file; system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; -$node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt"], +$node->command_checks_all( + [ 'pg_basebackup', '-D', "$tempdir/backup_corrupt" ], 1, [qr{^$}], [qr/^WARNING.*checksum verification failed/s], - 'pg_basebackup reports checksum mismatch' -); + 'pg_basebackup reports checksum mismatch'); rmtree("$tempdir/backup_corrupt"); # induce further corruption in 5 more blocks system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; open $file, '+<', "$pgdata/$file_corrupt1"; -for my $i ( 1..5 ) { - my $offset = $pageheader_size + $i * $block_size; - seek($file, $offset, 0); - syswrite($file, '\0\0\0\0\0\0\0\0\0'); +for my $i (1 .. 5) +{ + my $offset = $pageheader_size + $i * $block_size; + seek($file, $offset, 0); + syswrite($file, "\0\0\0\0\0\0\0\0\0"); } close $file; system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; -$node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt2"], - 1, - [qr{^$}], - [qr/^WARNING.*further.*failures.*will.not.be.reported/s], - 'pg_basebackup does not report more than 5 checksum mismatches' -); +$node->command_checks_all( + [ 'pg_basebackup', '-D', "$tempdir/backup_corrupt2" ], + 1, + [qr{^$}], + [qr/^WARNING.*further.*failures.*will.not.be.reported/s], + 'pg_basebackup does not report more than 5 checksum mismatches'); rmtree("$tempdir/backup_corrupt2"); # induce corruption in a second file system_or_bail 'pg_ctl', '-D', $pgdata, 'stop'; open $file, '+<', "$pgdata/$file_corrupt2"; -seek($file, 4000, 0); -syswrite($file, '\0\0\0\0\0\0\0\0\0'); +seek($file, $pageheader_size, 0); +syswrite($file, "\0\0\0\0\0\0\0\0\0"); close $file; system_or_bail 'pg_ctl', '-D', $pgdata, 'start'; -$node->command_checks_all([ 'pg_basebackup', '-D', "$tempdir/backup_corrupt3"], - 1, - [qr{^$}], - [qr/^WARNING.*7 total checksum verification failures/s], - 'pg_basebackup correctly report the total number of checksum mismatches' -); +$node->command_checks_all( + [ 'pg_basebackup', '-D', "$tempdir/backup_corrupt3" ], + 1, + [qr{^$}], + [qr/^WARNING.*7 total checksum verification failures/s], + 'pg_basebackup correctly report the total number of checksum mismatches'); rmtree("$tempdir/backup_corrupt3"); # do not verify checksums, should return ok $node->command_ok( - [ 'pg_basebackup', '-D', "$tempdir/backup_corrupt4", '-k' ], + [ + 'pg_basebackup', '-D', + "$tempdir/backup_corrupt4", '--no-verify-checksums' + ], 'pg_basebackup with -k does not report checksum mismatch'); rmtree("$tempdir/backup_corrupt4"); diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl index 19c106d9f59..6e2f0511877 100644 --- a/src/bin/pg_basebackup/t/020_pg_receivewal.pl +++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl @@ -41,7 +41,8 @@ is($slot->{'restart_lsn'}, '', 'restart LSN of new slot is null'); $primary->command_ok([ 'pg_receivewal', '--slot', $slot_name, '--drop-slot' ], 'dropping a replication slot'); -is($primary->slot($slot_name)->{'slot_type'}, '', 'replication slot was removed'); +is($primary->slot($slot_name)->{'slot_type'}, + '', 'replication slot was removed'); # Generate some WAL. Use --synchronous at the same time to add more # code coverage. Switch to the next segment first so that subsequent @@ -56,15 +57,18 @@ # Stream up to the given position. $primary->command_ok( - [ 'pg_receivewal', '-D', $stream_dir, '--verbose', - '--endpos', $nextlsn, '--synchronous', '--no-loop' ], + [ + 'pg_receivewal', '-D', $stream_dir, '--verbose', + '--endpos', $nextlsn, '--synchronous', '--no-loop' + ], 'streaming some WAL with --synchronous'); # Permissions on WAL files should be default SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive($stream_dir, 0700, 0600), - "check stream dir permissions"); + "check stream dir permissions"); } diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl index e9d09410022..99154bcf398 100644 --- a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl +++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl @@ -29,15 +29,19 @@ $node->command_fails([ 'pg_recvlogical', '-S', 'test', '-d', 'postgres' ], 'pg_recvlogical needs an action'); $node->command_fails( - [ 'pg_recvlogical', '-S', + [ + 'pg_recvlogical', '-S', 'test', '-d', - $node->connstr('postgres'), '--start' ], + $node->connstr('postgres'), '--start' + ], 'no destination file'); $node->command_ok( - [ 'pg_recvlogical', '-S', + [ + 'pg_recvlogical', '-S', 'test', '-d', - $node->connstr('postgres'), '--create-slot' ], + $node->connstr('postgres'), '--create-slot' + ], 'slot created'); my $slot = $node->slot('test'); @@ -51,6 +55,8 @@ chomp($nextlsn); $node->command_ok( - [ 'pg_recvlogical', '-S', 'test', '-d', $node->connstr('postgres'), - '--start', '--endpos', "$nextlsn", '--no-loop', '-f', '-' ], + [ + 'pg_recvlogical', '-S', 'test', '-d', $node->connstr('postgres'), + '--start', '--endpos', "$nextlsn", '--no-loop', '-f', '-' + ], 'replayed a transaction'); diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c index 267a40debbf..8ec12e6f723 100644 --- a/src/bin/pg_basebackup/walmethods.c +++ b/src/bin/pg_basebackup/walmethods.c @@ -5,7 +5,7 @@ * NOTE! The caller must ensure that only one method is instantiated in * any given program, and that it's only instantiated once! * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/walmethods.c @@ -116,23 +116,26 @@ dir_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ /* Do pre-padding on non-compressed files */ if (pad_to_size && dir_data->compression == 0) { - char *zerobuf; + PGAlignedXLogBlock zerobuf; int bytes; - zerobuf = pg_malloc0(XLOG_BLCKSZ); + memset(zerobuf.data, 0, XLOG_BLCKSZ); for (bytes = 0; bytes < pad_to_size; bytes += XLOG_BLCKSZ) { - if (write(fd, zerobuf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + errno = 0; + if (write(fd, zerobuf.data, XLOG_BLCKSZ) != XLOG_BLCKSZ) { int save_errno = errno; - pg_free(zerobuf); close(fd); - errno = save_errno; + + /* + * If write didn't set errno, assume problem is no disk space. + */ + errno = save_errno ? save_errno : ENOSPC; return NULL; } } - pg_free(zerobuf); if (lseek(fd, 0, SEEK_SET) != 0) { @@ -152,8 +155,8 @@ dir_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ */ if (dir_data->sync) { - if (fsync_fname(tmppath, false, progname) != 0 || - fsync_parent_path(tmppath, progname) != 0) + if (fsync_fname(tmppath, false) != 0 || + fsync_parent_path(tmppath) != 0) { #ifdef HAVE_LIBZ if (dir_data->compression > 0) @@ -241,7 +244,7 @@ dir_close(Walfile f, WalCloseMethod method) snprintf(tmppath2, sizeof(tmppath2), "%s/%s%s", dir_data->basedir, df->pathname, dir_data->compression > 0 ? ".gz" : ""); - r = durable_rename(tmppath, tmppath2, progname); + r = durable_rename(tmppath, tmppath2); } else if (method == CLOSE_UNLINK) { @@ -261,9 +264,9 @@ dir_close(Walfile f, WalCloseMethod method) */ if (dir_data->sync) { - r = fsync_fname(df->fullpath, false, progname); + r = fsync_fname(df->fullpath, false); if (r == 0) - r = fsync_parent_path(df->fullpath, progname); + r = fsync_parent_path(df->fullpath); } } } @@ -336,7 +339,7 @@ dir_finish(void) * Files are fsynced when they are closed, but we need to fsync the * directory entry here as well. */ - if (fsync_fname(dir_data->basedir, true, progname) != 0) + if (fsync_fname(dir_data->basedir, true) != 0) return false; } return true; @@ -441,8 +444,16 @@ tar_write_compressed_data(void *buf, size_t count, bool flush) { size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out; + errno = 0; if (write(tar_data->fd, tar_data->zlibOut, len) != len) + { + /* + * If write didn't set errno, assume problem is no disk space. + */ + if (errno == 0) + errno = ENOSPC; return false; + } tar_data->zp->next_out = tar_data->zlibOut; tar_data->zp->avail_out = ZLIB_OUT_SIZE; @@ -485,7 +496,7 @@ tar_write(Walfile f, const void *buf, size_t count) #ifdef HAVE_LIBZ else { - if (!tar_write_compressed_data((void *) buf, count, false)) + if (!tar_write_compressed_data(unconstify(void *, buf), count, false)) return -1; ((TarMethodFile *) f)->currpos += count; return count; @@ -500,24 +511,20 @@ tar_write(Walfile f, const void *buf, size_t count) static bool tar_write_padding_data(TarMethodFile *f, size_t bytes) { - char *zerobuf = pg_malloc0(XLOG_BLCKSZ); + PGAlignedXLogBlock zerobuf; size_t bytesleft = bytes; + memset(zerobuf.data, 0, XLOG_BLCKSZ); while (bytesleft) { - size_t bytestowrite = bytesleft > XLOG_BLCKSZ ? XLOG_BLCKSZ : bytesleft; - - ssize_t r = tar_write(f, zerobuf, bytestowrite); + size_t bytestowrite = Min(bytesleft, XLOG_BLCKSZ); + ssize_t r = tar_write(f, zerobuf.data, bytestowrite); if (r < 0) - { - pg_free(zerobuf); return false; - } bytesleft -= r; } - pg_free(zerobuf); return true; } @@ -618,12 +625,14 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_ if (!tar_data->compression) { + errno = 0; if (write(tar_data->fd, tar_data->currentfile->header, 512) != 512) { save_errno = errno; pg_free(tar_data->currentfile); tar_data->currentfile = NULL; - errno = save_errno; + /* if write didn't set errno, assume problem is no disk space */ + errno = save_errno ? save_errno : ENOSPC; return NULL; } } @@ -817,8 +826,14 @@ tar_close(Walfile f, WalCloseMethod method) return -1; if (!tar_data->compression) { + errno = 0; if (write(tar_data->fd, tf->header, 512) != 512) + { + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; return -1; + } } #ifdef HAVE_LIBZ else @@ -848,7 +863,8 @@ tar_close(Walfile f, WalCloseMethod method) return -1; /* Always fsync on close, so the padding gets fsynced */ - tar_sync(f); + if (tar_sync(f) < 0) + exit(1); /* Clean up and done */ pg_free(tf->pathname); @@ -879,12 +895,18 @@ tar_finish(void) return false; } - /* A tarfile always ends with two empty blocks */ + /* A tarfile always ends with two empty blocks */ MemSet(zerobuf, 0, sizeof(zerobuf)); if (!tar_data->compression) { + errno = 0; if (write(tar_data->fd, zerobuf, sizeof(zerobuf)) != sizeof(zerobuf)) + { + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; return false; + } } #ifdef HAVE_LIBZ else @@ -910,8 +932,17 @@ tar_finish(void) { size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out; + errno = 0; if (write(tar_data->fd, tar_data->zlibOut, len) != len) + { + /* + * If write didn't set errno, assume problem is no disk + * space. + */ + if (errno == 0) + errno = ENOSPC; return false; + } } if (r == Z_STREAM_END) break; @@ -927,7 +958,10 @@ tar_finish(void) /* sync the empty blocks as well, since they're after the last file */ if (tar_data->sync) - fsync(tar_data->fd); + { + if (fsync(tar_data->fd) != 0) + return false; + } if (close(tar_data->fd) != 0) return false; @@ -936,9 +970,9 @@ tar_finish(void) if (tar_data->sync) { - if (fsync_fname(tar_data->tarfilename, false, progname) != 0) + if (fsync_fname(tar_data->tarfilename, false) != 0) return false; - if (fsync_parent_path(tar_data->tarfilename, progname) != 0) + if (fsync_parent_path(tar_data->tarfilename) != 0) return false; } diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h index 2d1a10fc631..eb5bef8c3cc 100644 --- a/src/bin/pg_basebackup/walmethods.h +++ b/src/bin/pg_basebackup/walmethods.h @@ -2,7 +2,7 @@ * * walmethods.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_basebackup/walmethods.h @@ -81,12 +81,12 @@ struct WalWriteMethod /* * Available WAL methods: * - WalDirectoryMethod - write WAL to regular files in a standard pg_wal - * - TarDirectoryMethod - write WAL to a tarfile corresponding to pg_wal + * - WalTarMethod - write WAL to a tarfile corresponding to pg_wal * (only implements the methods required for pg_basebackup, * not all those required for pg_receivewal) */ WalWriteMethod *CreateWalDirectoryMethod(const char *basedir, - int compression, bool sync); + int compression, bool sync); WalWriteMethod *CreateWalTarMethod(const char *tarbase, int compression, bool sync); /* Cleanup routines for previously-created methods */ diff --git a/src/bin/pg_checksums/.gitignore b/src/bin/pg_checksums/.gitignore new file mode 100644 index 00000000000..78886250942 --- /dev/null +++ b/src/bin/pg_checksums/.gitignore @@ -0,0 +1,3 @@ +/pg_checksums + +/tmp_check/ diff --git a/src/bin/pg_checksums/Makefile b/src/bin/pg_checksums/Makefile new file mode 100644 index 00000000000..278b7a0f2ec --- /dev/null +++ b/src/bin/pg_checksums/Makefile @@ -0,0 +1,42 @@ +#------------------------------------------------------------------------- +# +# Makefile for src/bin/pg_checksums +# +# Copyright (c) 1998-2019, PostgreSQL Global Development Group +# +# src/bin/pg_checksums/Makefile +# +#------------------------------------------------------------------------- + +PGFILEDESC = "pg_checksums - verify data checksums in an offline cluster" +PGAPPICON=win32 + +subdir = src/bin/pg_checksums +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global + +OBJS= pg_checksums.o $(WIN32RES) + +all: pg_checksums + +pg_checksums: $(OBJS) | submake-libpgport + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) + +install: all installdirs + $(INSTALL_PROGRAM) pg_checksums$(X) '$(DESTDIR)$(bindir)/pg_checksums$(X)' + +installdirs: + $(MKDIR_P) '$(DESTDIR)$(bindir)' + +uninstall: + rm -f '$(DESTDIR)$(bindir)/pg_checksums$(X)' + +clean distclean maintainer-clean: + rm -f pg_checksums$(X) $(OBJS) + rm -rf tmp_check + +check: + $(prove_check) + +installcheck: + $(prove_installcheck) diff --git a/src/bin/pg_checksums/nls.mk b/src/bin/pg_checksums/nls.mk new file mode 100644 index 00000000000..b2bc50fb388 --- /dev/null +++ b/src/bin/pg_checksums/nls.mk @@ -0,0 +1,6 @@ +# src/bin/pg_checksums/nls.mk +CATALOG_NAME = pg_checksums +AVAIL_LANGUAGES =de es sv +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_checksums.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_checksums/pg_checksums.c b/src/bin/pg_checksums/pg_checksums.c new file mode 100644 index 00000000000..971ae73f544 --- /dev/null +++ b/src/bin/pg_checksums/pg_checksums.c @@ -0,0 +1,610 @@ +/*------------------------------------------------------------------------- + * + * pg_checksums.c + * Checks, enables or disables page level checksums for an offline + * cluster + * + * Copyright (c) 2010-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/bin/pg_checksums/pg_checksums.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres_fe.h" + +#include +#include +#include +#include + +#include "access/xlog_internal.h" +#include "common/controldata_utils.h" +#include "common/file_perm.h" +#include "common/file_utils.h" +#include "common/logging.h" +#include "getopt_long.h" +#include "pg_getopt.h" +#include "storage/bufpage.h" +#include "storage/checksum.h" +#include "storage/checksum_impl.h" + + +static int64 files = 0; +static int64 blocks = 0; +static int64 badblocks = 0; +static ControlFileData *ControlFile; + +static char *only_filenode = NULL; +static bool do_sync = true; +static bool verbose = false; +static bool showprogress = false; + +typedef enum +{ + PG_MODE_CHECK, + PG_MODE_DISABLE, + PG_MODE_ENABLE +} PgChecksumMode; + +/* + * Filename components. + * + * XXX: fd.h is not declared here as frontend side code is not able to + * interact with the backend-side definitions for the various fsync + * wrappers. + */ +#define PG_TEMP_FILES_DIR "pgsql_tmp" +#define PG_TEMP_FILE_PREFIX "pgsql_tmp" + +static PgChecksumMode mode = PG_MODE_CHECK; + +static const char *progname; + +/* + * Progress status information. + */ +int64 total_size = 0; +int64 current_size = 0; +static pg_time_t last_progress_report = 0; + +static void +usage(void) +{ + printf(_("%s enables, disables, or verifies data checksums in a PostgreSQL database cluster.\n\n"), progname); + printf(_("Usage:\n")); + printf(_(" %s [OPTION]... [DATADIR]\n"), progname); + printf(_("\nOptions:\n")); + printf(_(" [-D, --pgdata=]DATADIR data directory\n")); + printf(_(" -c, --check check data checksums (default)\n")); + printf(_(" -d, --disable disable data checksums\n")); + printf(_(" -e, --enable enable data checksums\n")); + printf(_(" -f, --filenode=FILENODE check only relation with specified filenode\n")); + printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n")); + printf(_(" -P, --progress show progress information\n")); + printf(_(" -v, --verbose output verbose messages\n")); + printf(_(" -V, --version output version information, then exit\n")); + printf(_(" -?, --help show this help, then exit\n")); + printf(_("\nIf no data directory (DATADIR) is specified, " + "the environment variable PGDATA\nis used.\n\n")); + printf(_("Report bugs to .\n")); +} + +/* + * List of files excluded from checksum validation. + * + * Note: this list should be kept in sync with what basebackup.c includes. + */ +static const char *const skip[] = { + "pg_control", + "pg_filenode.map", + "pg_internal.init", + "PG_VERSION", +#ifdef EXEC_BACKEND + "config_exec_params", + "config_exec_params.new", +#endif + NULL, +}; + +/* + * Report current progress status. Parts borrowed from + * src/bin/pg_basebackup/pg_basebackup.c. + */ +static void +progress_report(bool force) +{ + int percent; + char total_size_str[32]; + char current_size_str[32]; + pg_time_t now; + + Assert(showprogress); + + now = time(NULL); + if (now == last_progress_report && !force) + return; /* Max once per second */ + + /* Save current time */ + last_progress_report = now; + + /* Adjust total size if current_size is larger */ + if (current_size > total_size) + total_size = current_size; + + /* Calculate current percentage of size done */ + percent = total_size ? (int) ((current_size) * 100 / total_size) : 0; + + /* + * Separate step to keep platform-dependent format code out of + * translatable strings. And we only test for INT64_FORMAT availability + * in snprintf, not fprintf. + */ + snprintf(total_size_str, sizeof(total_size_str), INT64_FORMAT, + total_size / (1024 * 1024)); + snprintf(current_size_str, sizeof(current_size_str), INT64_FORMAT, + current_size / (1024 * 1024)); + + fprintf(stderr, _("%*s/%s MB (%d%%) computed"), + (int) strlen(current_size_str), current_size_str, total_size_str, + percent); + + /* Stay on the same line if reporting to a terminal */ + fprintf(stderr, isatty(fileno(stderr)) ? "\r" : "\n"); +} + +static bool +skipfile(const char *fn) +{ + const char *const *f; + + for (f = skip; *f; f++) + if (strcmp(*f, fn) == 0) + return true; + + return false; +} + +static void +scan_file(const char *fn, BlockNumber segmentno) +{ + PGAlignedBlock buf; + PageHeader header = (PageHeader) buf.data; + int f; + BlockNumber blockno; + int flags; + + Assert(mode == PG_MODE_ENABLE || + mode == PG_MODE_CHECK); + + flags = (mode == PG_MODE_ENABLE) ? O_RDWR : O_RDONLY; + f = open(fn, PG_BINARY | flags, 0); + + if (f < 0) + { + pg_log_error("could not open file \"%s\": %m", fn); + exit(1); + } + + files++; + + for (blockno = 0;; blockno++) + { + uint16 csum; + int r = read(f, buf.data, BLCKSZ); + + if (r == 0) + break; + if (r != BLCKSZ) + { + if (r < 0) + pg_log_error("could not read block %u in file \"%s\": %m", + blockno, fn); + else + pg_log_error("could not read block %u in file \"%s\": read %d of %d", + blockno, fn, r, BLCKSZ); + exit(1); + } + blocks++; + + /* New pages have no checksum yet */ + if (PageIsNew(header)) + continue; + + csum = pg_checksum_page(buf.data, blockno + segmentno * RELSEG_SIZE); + current_size += r; + if (mode == PG_MODE_CHECK) + { + if (csum != header->pd_checksum) + { + if (ControlFile->data_checksum_version == PG_DATA_CHECKSUM_VERSION) + pg_log_error("checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X", + fn, blockno, csum, header->pd_checksum); + badblocks++; + } + } + else if (mode == PG_MODE_ENABLE) + { + int w; + + /* Set checksum in page header */ + header->pd_checksum = csum; + + /* Seek back to beginning of block */ + if (lseek(f, -BLCKSZ, SEEK_CUR) < 0) + { + pg_log_error("seek failed for block %u in file \"%s\": %m", blockno, fn); + exit(1); + } + + /* Write block with checksum */ + w = write(f, buf.data, BLCKSZ); + if (w != BLCKSZ) + { + if (w < 0) + pg_log_error("could not write block %u in file \"%s\": %m", + blockno, fn); + else + pg_log_error("could not write block %u in file \"%s\": wrote %d of %d", + blockno, fn, w, BLCKSZ); + exit(1); + } + } + + if (showprogress) + progress_report(false); + } + + if (verbose) + { + if (mode == PG_MODE_CHECK) + pg_log_info("checksums verified in file \"%s\"", fn); + if (mode == PG_MODE_ENABLE) + pg_log_info("checksums enabled in file \"%s\"", fn); + } + + close(f); +} + +/* + * Scan the given directory for items which can be checksummed and + * operate on each one of them. If "sizeonly" is true, the size of + * all the items which have checksums is computed and returned back + * to the caller without operating on the files. This is used to compile + * the total size of the data directory for progress reports. + */ +static int64 +scan_directory(const char *basedir, const char *subdir, bool sizeonly) +{ + int64 dirsize = 0; + char path[MAXPGPATH]; + DIR *dir; + struct dirent *de; + + snprintf(path, sizeof(path), "%s/%s", basedir, subdir); + dir = opendir(path); + if (!dir) + { + pg_log_error("could not open directory \"%s\": %m", path); + exit(1); + } + while ((de = readdir(dir)) != NULL) + { + char fn[MAXPGPATH]; + struct stat st; + + if (strcmp(de->d_name, ".") == 0 || + strcmp(de->d_name, "..") == 0) + continue; + + /* Skip temporary files */ + if (strncmp(de->d_name, + PG_TEMP_FILE_PREFIX, + strlen(PG_TEMP_FILE_PREFIX)) == 0) + continue; + + /* Skip temporary folders */ + if (strncmp(de->d_name, + PG_TEMP_FILES_DIR, + strlen(PG_TEMP_FILES_DIR)) == 0) + continue; + + snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name); + if (lstat(fn, &st) < 0) + { + pg_log_error("could not stat file \"%s\": %m", fn); + exit(1); + } + if (S_ISREG(st.st_mode)) + { + char fnonly[MAXPGPATH]; + char *forkpath, + *segmentpath; + BlockNumber segmentno = 0; + + if (skipfile(de->d_name)) + continue; + + /* + * Cut off at the segment boundary (".") to get the segment number + * in order to mix it into the checksum. Then also cut off at the + * fork boundary, to get the filenode the file belongs to for + * filtering. + */ + strlcpy(fnonly, de->d_name, sizeof(fnonly)); + segmentpath = strchr(fnonly, '.'); + if (segmentpath != NULL) + { + *segmentpath++ = '\0'; + segmentno = atoi(segmentpath); + if (segmentno == 0) + { + pg_log_error("invalid segment number %d in file name \"%s\"", + segmentno, fn); + exit(1); + } + } + + forkpath = strchr(fnonly, '_'); + if (forkpath != NULL) + *forkpath++ = '\0'; + + if (only_filenode && strcmp(only_filenode, fnonly) != 0) + /* filenode not to be included */ + continue; + + dirsize += st.st_size; + + /* + * No need to work on the file when calculating only the size of + * the items in the data folder. + */ + if (!sizeonly) + scan_file(fn, segmentno); + } +#ifndef WIN32 + else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) +#else + else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn)) +#endif + dirsize += scan_directory(path, de->d_name, sizeonly); + } + closedir(dir); + return dirsize; +} + +int +main(int argc, char *argv[]) +{ + static struct option long_options[] = { + {"check", no_argument, NULL, 'c'}, + {"pgdata", required_argument, NULL, 'D'}, + {"disable", no_argument, NULL, 'd'}, + {"enable", no_argument, NULL, 'e'}, + {"filenode", required_argument, NULL, 'f'}, + {"no-sync", no_argument, NULL, 'N'}, + {"progress", no_argument, NULL, 'P'}, + {"verbose", no_argument, NULL, 'v'}, + {NULL, 0, NULL, 0} + }; + + char *DataDir = NULL; + int c; + int option_index; + bool crc_ok; + + pg_logging_init(argv[0]); + set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_checksums")); + progname = get_progname(argv[0]); + + if (argc > 1) + { + if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) + { + usage(); + exit(0); + } + if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) + { + puts("pg_checksums (PostgreSQL) " PG_VERSION); + exit(0); + } + } + + while ((c = getopt_long(argc, argv, "cD:deNPf:v", long_options, &option_index)) != -1) + { + switch (c) + { + case 'c': + mode = PG_MODE_CHECK; + break; + case 'd': + mode = PG_MODE_DISABLE; + break; + case 'e': + mode = PG_MODE_ENABLE; + break; + case 'f': + if (atoi(optarg) == 0) + { + pg_log_error("invalid filenode specification, must be numeric: %s", optarg); + exit(1); + } + only_filenode = pstrdup(optarg); + break; + case 'N': + do_sync = false; + break; + case 'v': + verbose = true; + break; + case 'D': + DataDir = optarg; + break; + case 'P': + showprogress = true; + break; + default: + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + } + + if (DataDir == NULL) + { + if (optind < argc) + DataDir = argv[optind++]; + else + DataDir = getenv("PGDATA"); + + /* If no DataDir was specified, and none could be found, error out */ + if (DataDir == NULL) + { + pg_log_error("no data directory specified"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + } + + /* Complain if any arguments remain */ + if (optind < argc) + { + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), + progname); + exit(1); + } + + /* filenode checking only works in --check mode */ + if (mode != PG_MODE_CHECK && only_filenode) + { + pg_log_error("option -f/--filenode can only be used with --check"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), + progname); + exit(1); + } + + /* Read the control file and check compatibility */ + ControlFile = get_controlfile(DataDir, &crc_ok); + if (!crc_ok) + { + pg_log_error("pg_control CRC value is incorrect"); + exit(1); + } + + if (ControlFile->pg_control_version != PG_CONTROL_VERSION) + { + pg_log_error("cluster is not compatible with this version of pg_checksums"); + exit(1); + } + + if (ControlFile->blcksz != BLCKSZ) + { + pg_log_error("database cluster is not compatible"); + fprintf(stderr, _("The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n"), + ControlFile->blcksz, BLCKSZ); + exit(1); + } + + /* + * Check if cluster is running. A clean shutdown is required to avoid + * random checksum failures caused by torn pages. Note that this doesn't + * guard against someone starting the cluster concurrently. + */ + if (ControlFile->state != DB_SHUTDOWNED && + ControlFile->state != DB_SHUTDOWNED_IN_RECOVERY) + { + pg_log_error("cluster must be shut down"); + exit(1); + } + + if (ControlFile->data_checksum_version == 0 && + mode == PG_MODE_CHECK) + { + pg_log_error("data checksums are not enabled in cluster"); + exit(1); + } + + if (ControlFile->data_checksum_version == 0 && + mode == PG_MODE_DISABLE) + { + pg_log_error("data checksums are already disabled in cluster"); + exit(1); + } + + if (ControlFile->data_checksum_version > 0 && + mode == PG_MODE_ENABLE) + { + pg_log_error("data checksums are already enabled in cluster"); + exit(1); + } + + /* Operate on all files if checking or enabling checksums */ + if (mode == PG_MODE_CHECK || mode == PG_MODE_ENABLE) + { + /* + * If progress status information is requested, we need to scan the + * directory tree twice: once to know how much total data needs to be + * processed and once to do the real work. + */ + if (showprogress) + { + total_size = scan_directory(DataDir, "global", true); + total_size += scan_directory(DataDir, "base", true); + total_size += scan_directory(DataDir, "pg_tblspc", true); + } + + (void) scan_directory(DataDir, "global", false); + (void) scan_directory(DataDir, "base", false); + (void) scan_directory(DataDir, "pg_tblspc", false); + + if (showprogress) + { + progress_report(true); + fprintf(stderr, "\n"); /* Need to move to next line */ + } + + printf(_("Checksum operation completed\n")); + printf(_("Files scanned: %s\n"), psprintf(INT64_FORMAT, files)); + printf(_("Blocks scanned: %s\n"), psprintf(INT64_FORMAT, blocks)); + if (mode == PG_MODE_CHECK) + { + printf(_("Bad checksums: %s\n"), psprintf(INT64_FORMAT, badblocks)); + printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); + + if (badblocks > 0) + exit(1); + } + } + + /* + * Finally make the data durable on disk if enabling or disabling + * checksums. Flush first the data directory for safety, and then update + * the control file to keep the switch consistent. + */ + if (mode == PG_MODE_ENABLE || mode == PG_MODE_DISABLE) + { + ControlFile->data_checksum_version = + (mode == PG_MODE_ENABLE) ? PG_DATA_CHECKSUM_VERSION : 0; + + if (do_sync) + { + pg_log_info("syncing data directory"); + fsync_pgdata(DataDir, PG_VERSION_NUM); + } + + pg_log_info("updating control file"); + update_controlfile(DataDir, ControlFile, do_sync); + + if (verbose) + printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); + if (mode == PG_MODE_ENABLE) + printf(_("Checksums enabled in cluster\n")); + else + printf(_("Checksums disabled in cluster\n")); + } + + return 0; +} diff --git a/src/bin/pg_checksums/po/de.po b/src/bin/pg_checksums/po/de.po new file mode 100644 index 00000000000..a879eb3e9fb --- /dev/null +++ b/src/bin/pg_checksums/po/de.po @@ -0,0 +1,294 @@ +# German message translation file for pg_checksums +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Peter Eisentraut , 2018 - 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-13 03:16+0000\n" +"PO-Revision-Date: 2019-06-14 17:06+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: pg_checksums.c:75 +#, fuzzy, c-format +msgid "" +"%s enables, disables or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "%s überprüft die Datenprüfsummen in einem PostgreSQL-Datenbankcluster.\n\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPTION]... [DATENVERZEICHNIS]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Optionen:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]VERZ Datenbankverzeichnis\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check Datenprüfsummen prüfen (Voreinstellung)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable Datenprüfsummen ausschalten\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable Datenprüfsummen einschalten\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE nur Relation mit angegebenem Filenode prüfen\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress Fortschrittsinformationen zeigen\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose »Verbose«-Modus\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Wenn kein Datenverzeichnis angegeben ist, wird die Umgebungsvariable\n" +"PGDATA verwendet.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to .\n" +msgstr "Berichten Sie Fehler an .\n" + +#: pg_checksums.c:149 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) berechnet" + +#: pg_checksums.c:186 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: pg_checksums.c:201 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "konnte Block %u in Datei »%s« nicht lesen: %d von %d gelesen" + +#: pg_checksums.c:218 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "Prüfsummenprüfung fehlgeschlagen in Datei »%s«, Block %u: berechnete Prüfsumme ist %X, aber der Block enthält %X" + +#: pg_checksums.c:231 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "seek fehlgeschlagen für Block %u in Datei »%s«: %m" + +#: pg_checksums.c:238 +#, fuzzy, c-format +#| msgid "could not seek to block %u in file \"%s\": %m" +msgid "could not update checksum of block %u in file \"%s\": %m" +msgstr "konnte Positionszeiger nicht auf Block %u in Datei »%s« setzen: %m" + +#: pg_checksums.c:251 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "Prüfsummen wurden überprüft in Datei »%s«" + +#: pg_checksums.c:253 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "Prüfsummen wurden eingeschaltet in Datei »%s«" + +#: pg_checksums.c:278 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" + +#: pg_checksums.c:305 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" + +#: pg_checksums.c:332 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "ungültige Segmentnummer %d in Dateiname »%s«" + +#: pg_checksums.c:420 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "ungültige Relfilenode-Angabe, muss numerisch sein: %s" + +#: pg_checksums.c:438 pg_checksums.c:454 pg_checksums.c:464 pg_checksums.c:473 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_checksums.c:453 +#, c-format +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" + +#: pg_checksums.c:462 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_checksums.c:472 +#, c-format +msgid "--filenode option only possible with --check" +msgstr "Option --filenode kann nur mit --check verwendet werden" + +#: pg_checksums.c:482 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "CRC-Wert in pg_control ist falsch" + +#: pg_checksums.c:488 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "die Cluster sind nicht mit dieser Version von pg_checksums kompatibel" + +#: pg_checksums.c:494 +#, c-format +msgid "database cluster is not compatible" +msgstr "Datenbank-Cluster ist nicht kompatibel" + +#: pg_checksums.c:495 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "Der Datenbank-Cluster wurde mit Blockgröße %u initialisiert, aber pg_checksums wurde mit Blockgröße %u kompiliert.\n" + +#: pg_checksums.c:508 +#, c-format +msgid "cluster must be shut down" +msgstr "Cluster muss heruntergefahren sein" + +#: pg_checksums.c:515 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "Datenprüfsummen sind im Cluster nicht eingeschaltet" + +#: pg_checksums.c:522 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "Datenprüfsummen sind im Cluster bereits ausgeschaltet" + +#: pg_checksums.c:529 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "Datenprüfsummen sind im Cluster bereits eingeschaltet" + +#: pg_checksums.c:558 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Prüfsummenoperation abgeschlossen\n" + +#: pg_checksums.c:559 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Überprüfte Dateien: %s\n" + +#: pg_checksums.c:560 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Überprüfte Blöcke: %s\n" + +#: pg_checksums.c:563 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Falsche Prüfsummen: %s\n" + +#: pg_checksums.c:564 pg_checksums.c:591 +#, c-format +msgid "Data checksum version: %d\n" +msgstr "Datenprüfsummenversion: %d\n" + +#: pg_checksums.c:583 +#, c-format +msgid "syncing data directory" +msgstr "synchronisiere Datenverzeichnis" + +#: pg_checksums.c:587 +#, c-format +msgid "updating control file" +msgstr "aktualisiere Kontrolldatei" + +#: pg_checksums.c:593 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Prüfsummen wurden im Cluster eingeschaltet\n" + +#: pg_checksums.c:595 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Prüfsummen wurden im Cluster ausgeschaltet\n" diff --git a/src/bin/pg_checksums/po/es.po b/src/bin/pg_checksums/po/es.po new file mode 100644 index 00000000000..4a2784740f3 --- /dev/null +++ b/src/bin/pg_checksums/po/es.po @@ -0,0 +1,295 @@ +# Spanish message translation file for pg_checksums +# +# Copyright (c) 2019-2019, PostgreSQL Global Development Group +# +# This file is distributed under the same license as the pg_checksums (PostgreSQL) package. +# Ãlvaro Herrera , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_checksums (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:16+0000\n" +"PO-Revision-Date: 2019-06-06 17:22-0400\n" +"Last-Translator: Ãlvaro Herrera \n" +"Language-Team: pgsql-es-ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s activa, desactiva o verifica checksums de datos en un clúster PostgreSQL.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [OPCIÓN]... [DATADIR]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Opciones:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check verificar checksums (por omisión)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable desactivar checksums\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable activar checksums\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILENODE verificar sólo la relación con el filenode dado\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress mostrar información de progreso\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose desplegar mensajes verbosos\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Si no se especifica un directorio de datos (DATADIR), se utilizará\n" +"la variable de entorno PGDATA.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to .\n" +msgstr "Reporte errores a .\n" + +#: pg_checksums.c:149 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) calculado" + +#: pg_checksums.c:186 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: pg_checksums.c:201 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "no se pudo leer bloque %u en archivo «%s»: leídos %d de %d" + +#: pg_checksums.c:218 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "verificación de checksums falló en archivo «%s», bloque %u: checksum calculado %X pero bloque contiene %X" + +#: pg_checksums.c:231 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "posicionamiento (seek) falló para el bloque %u en archivo «%s»: %m" + +#: pg_checksums.c:238 +#, c-format +msgid "could not update checksum of block %u in file \"%s\": %m" +msgstr "no se pudo actualizar el checksum del bloque %u en archivo «%s»: %m" + +#: pg_checksums.c:251 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "checksums verificados en archivo «%s»" + +#: pg_checksums.c:253 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "checksums activados en archivo «%s»" + +#: pg_checksums.c:278 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" + +#: pg_checksums.c:305 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" + +#: pg_checksums.c:332 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "número de segmento %d no válido en nombre de archivo «%s»" + +#: pg_checksums.c:420 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "especificación de filenode no válida: deben ser numérica: %s" + +#: pg_checksums.c:438 pg_checksums.c:454 pg_checksums.c:464 pg_checksums.c:473 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: pg_checksums.c:453 +#, c-format +msgid "no data directory specified" +msgstr "no se especificó el directorio de datos" + +#: pg_checksums.c:462 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" + +#: pg_checksums.c:472 +#, c-format +msgid "--filenode option only possible with --check" +msgstr "la opción --filenode sólo es posible con --check" + +#: pg_checksums.c:482 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "el valor de CRC de pg_control es incorrecto" + +#: pg_checksums.c:488 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "el clúster no es compatible con esta versión de pg_checksums" + +#: pg_checksums.c:494 +#, c-format +msgid "database cluster is not compatible" +msgstr "el clúster de bases de datos no es compatible" + +#: pg_checksums.c:495 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "El clúster fue inicializado con tamaño de bloque %u, pero pg_checksums fue compilado con tamaño de bloques %u.\n" + +#: pg_checksums.c:503 +#, c-format +msgid "cluster must be shut down" +msgstr "el clúster debe estar apagado" + +#: pg_checksums.c:510 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "los checksums de datos no están activados en el clúster" + +#: pg_checksums.c:517 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "los checksums de datos ya están desactivados en el clúster" + +#: pg_checksums.c:524 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "los checksums de datos ya están activados en el clúster" + +#: pg_checksums.c:553 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Operación de checksums completa\n" + +#: pg_checksums.c:554 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Archivos recorridos: %s\n" + +#: pg_checksums.c:555 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Bloques recorridos: %s\n" + +#: pg_checksums.c:558 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Checksums incorrectos: %s\n" + +#: pg_checksums.c:559 pg_checksums.c:586 +#, c-format +msgid "Data checksum version: %d\n" +msgstr "Versión de checksums de datos: %d\n" + +#: pg_checksums.c:578 +#, c-format +msgid "syncing data directory" +msgstr "sincronizando directorio de datos" + +#: pg_checksums.c:582 +#, c-format +msgid "updating control file" +msgstr "actualizando archivo de control" + +#: pg_checksums.c:588 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Checksums activos en el clúster\n" + +#: pg_checksums.c:590 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Checksums inactivos en el clúster\n" diff --git a/src/bin/pg_checksums/po/sv.po b/src/bin/pg_checksums/po/sv.po new file mode 100644 index 00000000000..7c9d76066bf --- /dev/null +++ b/src/bin/pg_checksums/po/sv.po @@ -0,0 +1,302 @@ +# Swedish message translation file for pg_checksums +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_checksums (PostgreSQL) package. +# Dennis Björklund , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_checksums (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-07 12:16+0000\n" +"PO-Revision-Date: 2019-06-07 23:17+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: pg_checksums.c:75 +#, c-format +msgid "" +"%s enables, disables or verifies data checksums in a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s slÃ¥r pÃ¥, slÃ¥r av eller verifierar datakontrollsummor i ett PostgreSQL databaskluster.\n" +"\n" + +#: pg_checksums.c:76 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: pg_checksums.c:77 +#, c-format +msgid " %s [OPTION]... [DATADIR]\n" +msgstr " %s [FLAGGA]... [DATAKATALOG]\n" + +#: pg_checksums.c:78 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Flaggor:\n" + +#: pg_checksums.c:79 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATAKAT datakatalog\n" + +#: pg_checksums.c:80 +#, c-format +msgid " -c, --check check data checksums (default)\n" +msgstr " -c, --check kontrollera datakontrollsummor (standard)\n" + +#: pg_checksums.c:81 +#, c-format +msgid " -d, --disable disable data checksums\n" +msgstr " -d, --disable slÃ¥ av datakontrollsummor\n" + +#: pg_checksums.c:82 +#, c-format +msgid " -e, --enable enable data checksums\n" +msgstr " -e, --enable slÃ¥ pÃ¥ datakontrollsummor\n" + +#: pg_checksums.c:83 +#, c-format +msgid " -f, --filenode=FILENODE check only relation with specified filenode\n" +msgstr " -f, --filenode=FILNOD kontrollera bara relation med angiven filnod\n" + +#: pg_checksums.c:84 +#, c-format +msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgstr " -N, --no-sync vänta inte pÃ¥ att ändingar säkert skrivits till disk\n" + +#: pg_checksums.c:85 +#, c-format +msgid " -P, --progress show progress information\n" +msgstr " -P, --progress visa förloppsinformation\n" + +#: pg_checksums.c:86 +#, c-format +msgid " -v, --verbose output verbose messages\n" +msgstr " -v, --verbose visa utförliga meddelanden\n" + +#: pg_checksums.c:87 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: pg_checksums.c:88 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp, avsluta sedan\n" + +#: pg_checksums.c:89 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Om ingen datakatalog (DATAKATALOG) har angivits sÃ¥ nyttjas omgivningsvariabeln\n" +"PGDATA för detta syfte.\n" +"\n" + +#: pg_checksums.c:91 +#, c-format +msgid "Report bugs to .\n" +msgstr "Rapportera buggar till .\n" + +#: pg_checksums.c:149 +#, c-format +msgid "%*s/%s MB (%d%%) computed" +msgstr "%*s/%s MB (%d%%) beräknad" + +#: pg_checksums.c:186 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" + +#: pg_checksums.c:201 +#, c-format +msgid "could not read block %u in file \"%s\": read %d of %d" +msgstr "kunde inte läsa block %u i fil \"%s\": läste %d av %d" + +#: pg_checksums.c:218 +#, c-format +msgid "checksum verification failed in file \"%s\", block %u: calculated checksum %X but block contains %X" +msgstr "verifiering av kontrollsumma misslyckades i fil \"%s\", block %u: beräknad kontrollsumma är %X men blocket innehÃ¥ller %X" + +#: pg_checksums.c:231 +#, c-format +msgid "seek failed for block %u in file \"%s\": %m" +msgstr "seek misslyckades för block %u i fil \"%s\": %m" + +#: pg_checksums.c:238 +#, c-format +msgid "could not update checksum of block %u in file \"%s\": %m" +msgstr "kunde inte uppdatera kontrollsumma för block %u i fil \"%s\": %m" + +#: pg_checksums.c:251 +#, c-format +msgid "checksums verified in file \"%s\"" +msgstr "kontrollsummor verifierade i fil \"%s\"" + +#: pg_checksums.c:253 +#, c-format +msgid "checksums enabled in file \"%s\"" +msgstr "kontrollsummor pÃ¥slagen i fil \"%s\"" + +#: pg_checksums.c:278 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" + +#: pg_checksums.c:305 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" + +#: pg_checksums.c:332 +#, c-format +msgid "invalid segment number %d in file name \"%s\"" +msgstr "ogiltigt segmentnummer %d i filnamn \"%s\"" + +#: pg_checksums.c:420 +#, c-format +msgid "invalid filenode specification, must be numeric: %s" +msgstr "ogiltigt angiven filnod, mÃ¥ste vara numerisk: %s" + +#: pg_checksums.c:438 pg_checksums.c:454 pg_checksums.c:464 pg_checksums.c:473 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +#: pg_checksums.c:453 +#, c-format +msgid "no data directory specified" +msgstr "ingen datakatalog angiven" + +#: pg_checksums.c:462 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" + +#: pg_checksums.c:472 +#, c-format +msgid "--filenode option only possible with --check" +msgstr "inställningen --filenode tillÃ¥ts bara med --check" + +#: pg_checksums.c:482 +#, c-format +msgid "pg_control CRC value is incorrect" +msgstr "pg_control CRC-värde är inkorrekt" + +#: pg_checksums.c:488 +#, c-format +msgid "cluster is not compatible with this version of pg_checksums" +msgstr "klustret är inte kompatibelt med denna version av pg_checksums" + +#: pg_checksums.c:494 +#, c-format +msgid "database cluster is not compatible" +msgstr "databasklustret är inte kompatibelt" + +#: pg_checksums.c:495 +#, c-format +msgid "The database cluster was initialized with block size %u, but pg_checksums was compiled with block size %u.\n" +msgstr "Databasklustret initierades med blockstorlek %u men pg_checksums kompilerades med blockstorlek %u.\n" + +#: pg_checksums.c:508 +#, c-format +msgid "cluster must be shut down" +msgstr "klustret mÃ¥ste stängas ner" + +#: pg_checksums.c:515 +#, c-format +msgid "data checksums are not enabled in cluster" +msgstr "datakontrollsummor är inte pÃ¥slaget i klustret" + +#: pg_checksums.c:522 +#, c-format +msgid "data checksums are already disabled in cluster" +msgstr "datakontrollsummor är redan avslaget i klustret" + +#: pg_checksums.c:529 +#, c-format +msgid "data checksums are already enabled in cluster" +msgstr "datakontrollsummor är redan pÃ¥slagna i klustret" + +#: pg_checksums.c:558 +#, c-format +msgid "Checksum operation completed\n" +msgstr "Kontrollsummeoperation avslutad\n" + +#: pg_checksums.c:559 +#, c-format +msgid "Files scanned: %s\n" +msgstr "Skannade filer: %s\n" + +#: pg_checksums.c:560 +#, c-format +msgid "Blocks scanned: %s\n" +msgstr "Skannade block: %s\n" + +#: pg_checksums.c:563 +#, c-format +msgid "Bad checksums: %s\n" +msgstr "Felaktiga kontrollsummor: %s\n" + +#: pg_checksums.c:564 pg_checksums.c:591 +#, c-format +msgid "Data checksum version: %d\n" +msgstr "Datakontrollsummeversion: %d\n" + +#: pg_checksums.c:583 +#, c-format +msgid "syncing data directory" +msgstr "synkar datakatalogen" + +#: pg_checksums.c:587 +#, c-format +msgid "updating control file" +msgstr "uppdaterar kontrollfil" + +#: pg_checksums.c:593 +#, c-format +msgid "Checksums enabled in cluster\n" +msgstr "Kontrollsummor pÃ¥slaget i klustret\n" + +#: pg_checksums.c:595 +#, c-format +msgid "Checksums disabled in cluster\n" +msgstr "Kontrollsummor avslaget i klustret\n" + +#~ msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +#~ msgstr " -N, --no-sync vänta inte pÃ¥ att ändringar skall skrivas säkert till disk\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" diff --git a/src/bin/pg_checksums/t/001_basic.pl b/src/bin/pg_checksums/t/001_basic.pl new file mode 100644 index 00000000000..4334c806061 --- /dev/null +++ b/src/bin/pg_checksums/t/001_basic.pl @@ -0,0 +1,8 @@ +use strict; +use warnings; +use TestLib; +use Test::More tests => 8; + +program_help_ok('pg_checksums'); +program_version_ok('pg_checksums'); +program_options_handling_ok('pg_checksums'); diff --git a/src/bin/pg_checksums/t/002_actions.pl b/src/bin/pg_checksums/t/002_actions.pl new file mode 100644 index 00000000000..59228b916cb --- /dev/null +++ b/src/bin/pg_checksums/t/002_actions.pl @@ -0,0 +1,228 @@ +# Do basic sanity checks supported by pg_checksums using +# an initialized cluster. + +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 62; + + +# Utility routine to create and check a table with corrupted checksums +# on a wanted tablespace. Note that this stops and starts the node +# multiple times to perform the checks, leaving the node started +# at the end. +sub check_relation_corruption +{ + my $node = shift; + my $table = shift; + my $tablespace = shift; + my $pgdata = $node->data_dir; + + $node->safe_psql( + 'postgres', + "SELECT a INTO $table FROM generate_series(1,10000) AS a; + ALTER TABLE $table SET (autovacuum_enabled=false);"); + + $node->safe_psql('postgres', + "ALTER TABLE " . $table . " SET TABLESPACE " . $tablespace . ";"); + + my $file_corrupted = + $node->safe_psql('postgres', "SELECT pg_relation_filepath('$table');"); + my $relfilenode_corrupted = $node->safe_psql('postgres', + "SELECT relfilenode FROM pg_class WHERE relname = '$table';"); + + # Set page header and block size + my $pageheader_size = 24; + my $block_size = $node->safe_psql('postgres', 'SHOW block_size;'); + $node->stop; + + # Checksums are correct for single relfilenode as the table is not + # corrupted yet. + command_ok( + [ + 'pg_checksums', '--check', + '-D', $pgdata, + '--filenode', $relfilenode_corrupted + ], + "succeeds for single relfilenode on tablespace $tablespace with offline cluster" + ); + + # Time to create some corruption + open my $file, '+<', "$pgdata/$file_corrupted"; + seek($file, $pageheader_size, 0); + syswrite($file, "\0\0\0\0\0\0\0\0\0"); + close $file; + + # Checksum checks on single relfilenode fail + $node->command_checks_all( + [ + 'pg_checksums', '--check', + '-D', $pgdata, + '--filenode', $relfilenode_corrupted + ], + 1, + [qr/Bad checksums:.*1/], + [qr/checksum verification failed/], + "fails with corrupted data for single relfilenode on tablespace $tablespace" + ); + + # Global checksum checks fail as well + $node->command_checks_all( + [ 'pg_checksums', '--check', '-D', $pgdata ], + 1, + [qr/Bad checksums:.*1/], + [qr/checksum verification failed/], + "fails with corrupted data on tablespace $tablespace"); + + # Drop corrupted table again and make sure there is no more corruption. + $node->start; + $node->safe_psql('postgres', "DROP TABLE $table;"); + $node->stop; + $node->command_ok([ 'pg_checksums', '--check', '-D', $pgdata ], + "succeeds again after table drop on tablespace $tablespace"); + + $node->start; + return; +} + +# Initialize node with checksums disabled. +my $node = get_new_node('node_checksum'); +$node->init(); +my $pgdata = $node->data_dir; + +# Control file should know that checksums are disabled. +command_like( + [ 'pg_controldata', $pgdata ], + qr/Data page checksum version:.*0/, + 'checksums disabled in control file'); + +# These are correct but empty files, so they should pass through. +append_to_file "$pgdata/global/99999", ""; +append_to_file "$pgdata/global/99999.123", ""; +append_to_file "$pgdata/global/99999_fsm", ""; +append_to_file "$pgdata/global/99999_init", ""; +append_to_file "$pgdata/global/99999_vm", ""; +append_to_file "$pgdata/global/99999_init.123", ""; +append_to_file "$pgdata/global/99999_fsm.123", ""; +append_to_file "$pgdata/global/99999_vm.123", ""; + +# These are temporary files and folders with dummy contents, which +# should be ignored by the scan. +append_to_file "$pgdata/global/pgsql_tmp_123", "foo"; +mkdir "$pgdata/global/pgsql_tmp"; +append_to_file "$pgdata/global/pgsql_tmp/1.1", "foo"; + +# Enable checksums. +command_ok([ 'pg_checksums', '--enable', '--no-sync', '-D', $pgdata ], + "checksums successfully enabled in cluster"); + +# Successive attempt to enable checksums fails. +command_fails([ 'pg_checksums', '--enable', '--no-sync', '-D', $pgdata ], + "enabling checksums fails if already enabled"); + +# Control file should know that checksums are enabled. +command_like( + [ 'pg_controldata', $pgdata ], + qr/Data page checksum version:.*1/, + 'checksums enabled in control file'); + +# Disable checksums again. Flush result here as that should be cheap. +command_ok( + [ 'pg_checksums', '--disable', '-D', $pgdata ], + "checksums successfully disabled in cluster"); + +# Successive attempt to disable checksums fails. +command_fails( + [ 'pg_checksums', '--disable', '--no-sync', '-D', $pgdata ], + "disabling checksums fails if already disabled"); + +# Control file should know that checksums are disabled. +command_like( + [ 'pg_controldata', $pgdata ], + qr/Data page checksum version:.*0/, + 'checksums disabled in control file'); + +# Enable checksums again for follow-up tests. +command_ok([ 'pg_checksums', '--enable', '--no-sync', '-D', $pgdata ], + "checksums successfully enabled in cluster"); + +# Control file should know that checksums are enabled. +command_like( + [ 'pg_controldata', $pgdata ], + qr/Data page checksum version:.*1/, + 'checksums enabled in control file'); + +# Checksums pass on a newly-created cluster +command_ok([ 'pg_checksums', '--check', '-D', $pgdata ], + "succeeds with offline cluster"); + +# Checksums are verified if no other arguments are specified +command_ok( + [ 'pg_checksums', '-D', $pgdata ], + "verifies checksums as default action"); + +# Specific relation files cannot be requested when action is --disable +# or --enable. +command_fails( + [ 'pg_checksums', '--disable', '--filenode', '1234', '-D', $pgdata ], + "fails when relfilenodes are requested and action is --disable"); +command_fails( + [ 'pg_checksums', '--enable', '--filenode', '1234', '-D', $pgdata ], + "fails when relfilenodes are requested and action is --enable"); + +# Checks cannot happen with an online cluster +$node->start; +command_fails([ 'pg_checksums', '--check', '-D', $pgdata ], + "fails with online cluster"); + +# Check corruption of table on default tablespace. +check_relation_corruption($node, 'corrupt1', 'pg_default'); + +# Create tablespace to check corruptions in a non-default tablespace. +my $basedir = $node->basedir; +my $tablespace_dir = "$basedir/ts_corrupt_dir"; +mkdir($tablespace_dir); +$tablespace_dir = TestLib::perl2host($tablespace_dir); +$node->safe_psql('postgres', + "CREATE TABLESPACE ts_corrupt LOCATION '$tablespace_dir';"); +check_relation_corruption($node, 'corrupt2', 'ts_corrupt'); + +# Utility routine to check that pg_checksums is able to detect +# correctly-named relation files filled with some corrupted data. +sub fail_corrupt +{ + my $node = shift; + my $file = shift; + my $pgdata = $node->data_dir; + + # Create the file with some dummy data in it. + my $file_name = "$pgdata/global/$file"; + append_to_file $file_name, "foo"; + + $node->command_checks_all( + [ 'pg_checksums', '--check', '-D', $pgdata ], + 1, + [qr/^$/], + [qr/could not read block 0 in file.*$file\":/], + "fails for corrupted data in $file"); + + # Remove file to prevent future lookup errors on conflicts. + unlink $file_name; + return; +} + +# Stop instance for the follow-up checks. +$node->stop; + +# Authorized relation files filled with corrupted data cause the +# checksum checks to fail. Make sure to use file names different +# than the previous ones. +fail_corrupt($node, "99990"); +fail_corrupt($node, "99990.123"); +fail_corrupt($node, "99990_fsm"); +fail_corrupt($node, "99990_init"); +fail_corrupt($node, "99990_vm"); +fail_corrupt($node, "99990_init.123"); +fail_corrupt($node, "99990_fsm.123"); +fail_corrupt($node, "99990_vm.123"); diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile index 02e6f9da0e0..b915c2388a8 100644 --- a/src/bin/pg_config/Makefile +++ b/src/bin/pg_config/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_config # -# Copyright (c) 1998-2018, PostgreSQL Global Development Group +# Copyright (c) 1998-2019, PostgreSQL Global Development Group # # src/bin/pg_config/Makefile # diff --git a/src/bin/pg_config/nls.mk b/src/bin/pg_config/nls.mk index 057f4f520ca..1d41f90ee05 100644 --- a/src/bin/pg_config/nls.mk +++ b/src/bin/pg_config/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_config/nls.mk CATALOG_NAME = pg_config -AVAIL_LANGUAGES = cs de es fr he it ja ko nb pl pt_BR ro ru sv ta tr zh_CN zh_TW +AVAIL_LANGUAGES = cs de es fr he it ja ko nb pl pt_BR ro ru sv ta tr vi zh_CN zh_TW GETTEXT_FILES = pg_config.c ../../common/config_info.c ../../common/exec.c diff --git a/src/bin/pg_config/pg_config.c b/src/bin/pg_config/pg_config.c index a341b756de3..5279e7fd797 100644 --- a/src/bin/pg_config/pg_config.c +++ b/src/bin/pg_config/pg_config.c @@ -15,7 +15,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/bin/pg_config/pg_config.c * @@ -102,7 +102,7 @@ help(void) printf(_(" --version show the PostgreSQL version\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\nWith no arguments, all known items are shown.\n\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } static void diff --git a/src/bin/pg_config/po/cs.po b/src/bin/pg_config/po/cs.po index 16c2b54185d..1d00981a80c 100644 --- a/src/bin/pg_config/po/cs.po +++ b/src/bin/pg_config/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_config-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-03-17 18:46+0000\n" -"PO-Revision-Date: 2013-04-28 19:26+0200\n" +"POT-Creation-Date: 2018-07-13 19:45+0000\n" +"PO-Revision-Date: 2018-07-13 23:47+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,51 +16,52 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 +msgid "not recorded" +msgstr "nezaznamenáno" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" msgstr "nelze získat aktuální adresář: %s" -#: ../../port/exec.c:146 +#: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" msgstr "neplatný binární soubor\"%s\"" -#: ../../port/exec.c:195 +#: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "nelze Äíst binární soubor \"%s\"" -#: ../../port/exec.c:202 +#: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" -msgstr "nelze najít spustitelný soubor \"%s\"" +msgstr "nelze najít soubor \"%s\" ke spuÅ¡tÄ›ní" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "nelze zmÄ›nit adresář na \"%s\" : %s" -#: ../../port/exec.c:272 +#: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "nelze Äíst symbolický link \"%s\"" -#: ../../port/exec.c:523 +#: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "volání pclose selhalo: %s" -#: pg_config.c:243 pg_config.c:259 pg_config.c:275 pg_config.c:291 -#: pg_config.c:307 pg_config.c:323 pg_config.c:339 pg_config.c:355 -#: pg_config.c:371 -#, c-format -msgid "not recorded\n" -msgstr "nezaznamenáno\n" - -#: pg_config.c:428 +#: pg_config.c:74 #, c-format msgid "" "\n" @@ -71,12 +72,12 @@ msgstr "" "%s poskytuje informace o nainstalované verzi PostgreSQL.\n" "\n" -#: pg_config.c:429 +#: pg_config.c:75 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: pg_config.c:430 +#: pg_config.c:76 #, c-format msgid "" " %s [OPTION]...\n" @@ -85,70 +86,71 @@ msgstr "" " %s [PŘEPÃNAÄŒ]...\n" "\n" -#: pg_config.c:431 +#: pg_config.c:77 #, c-format msgid "Options:\n" msgstr "PÅ™epínaÄe:\n" -#: pg_config.c:432 +#: pg_config.c:78 #, c-format msgid " --bindir show location of user executables\n" msgstr " --bindir ukáže umístÄ›ní spustitelných souborů\n" -#: pg_config.c:433 +#: pg_config.c:79 #, c-format msgid " --docdir show location of documentation files\n" msgstr " --docdir ukáže umístÄ›ní souborů s dokumentací\n" -#: pg_config.c:434 +#: pg_config.c:80 #, c-format msgid " --htmldir show location of HTML documentation files\n" msgstr " --htmldir ukáže umístÄ›ní souborl s HTML dokumentací\n" -#: pg_config.c:435 +#: pg_config.c:81 #, c-format msgid "" " --includedir show location of C header files of the client\n" " interfaces\n" msgstr "" -" --includedir ukáže umístÄ›ní C hlaviÄkových souborů klientských\n" +" --includedir ukáže umístÄ›ní C hlaviÄkových souborů klientských\n" " rozhraní\n" -#: pg_config.c:437 +#: pg_config.c:83 #, c-format msgid " --pkgincludedir show location of other C header files\n" msgstr "" " --pkgincludedir ukáže umístÄ›ní dalších C hlaviÄkových souborů\n" -#: pg_config.c:438 +#: pg_config.c:84 #, c-format msgid "" " --includedir-server show location of C header files for the server\n" msgstr "" " --includedir-server ukáže umístÄ›ní C hlaviÄkových souborů pro server\n" -#: pg_config.c:439 +#: pg_config.c:85 #, c-format msgid " --libdir show location of object code libraries\n" msgstr " --libdir ukáže umístÄ›ní knihoven\n" -#: pg_config.c:440 +#: pg_config.c:86 #, c-format -msgid " --pkglibdir show location of dynamically loadable modules\n" +msgid "" +" --pkglibdir show location of dynamically loadable modules\n" msgstr " --pkglibdir ukáže umístÄ›ní dynamicky zavádÄ›ných modulů\n" -#: pg_config.c:441 +#: pg_config.c:87 #, c-format msgid " --localedir show location of locale support files\n" msgstr " --localedir ukáže umístÄ›ní souborů pro podporu locale\n" -#: pg_config.c:442 +#: pg_config.c:88 #, c-format msgid " --mandir show location of manual pages\n" msgstr "" " --mandir ukáže umístÄ›ní souborů s manuálovými stránkami\n" -#: pg_config.c:443 +#: pg_config.c:89 #, c-format msgid "" " --sharedir show location of architecture-independent support " @@ -157,7 +159,7 @@ msgstr "" " --sharedir ukáže umístÄ›ní podpůrných souborů nezávislých na " "architektuÅ™e\n" -#: pg_config.c:444 +#: pg_config.c:90 #, c-format msgid "" " --sysconfdir show location of system-wide configuration files\n" @@ -165,51 +167,56 @@ msgstr "" " --sysconfdir ukáže umístÄ›ní konfiguraÄních souborů platných pro " "celý systém\n" -#: pg_config.c:445 +#: pg_config.c:91 #, c-format msgid " --pgxs show location of extension makefile\n" msgstr "" " --pgxs ukáže umístÄ›ní makefile souboru pro rozšíření\n" -#: pg_config.c:446 +#: pg_config.c:92 #, c-format msgid "" " --configure show options given to \"configure\" script when\n" " PostgreSQL was built\n" msgstr "" -" --configure ukáže pÅ™epínaÄe použité pro \"configure\" skript ke\n" +" --configure ukáže pÅ™epínaÄe použité pro \"configure\" skript " +"ke\n" " kompilaci PostgreSQL\n" -#: pg_config.c:448 +#: pg_config.c:94 #, c-format -msgid " --cc show CC value used when PostgreSQL was built\n" +msgid "" +" --cc show CC value used when PostgreSQL was built\n" msgstr "" " --cc ukáže hodnotu CC použitou pÅ™i buildu PostgreSQL\n" -#: pg_config.c:449 +#: pg_config.c:95 #, c-format msgid "" -" --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +" --cppflags show CPPFLAGS value used when PostgreSQL was " +"built\n" msgstr "" " --cppflags ukáže hodnotu CPPFLAGS použitou pÅ™i buildu " "PostgreSQL\n" -#: pg_config.c:450 +#: pg_config.c:96 #, c-format msgid "" " --cflags show CFLAGS value used when PostgreSQL was built\n" msgstr "" -" --cflags ukáže hodnotu CFLAGS použitou pÅ™i buildu PostgreSQL\n" +" --cflags ukáže hodnotu CFLAGS použitou pÅ™i buildu " +"PostgreSQL\n" -#: pg_config.c:451 +#: pg_config.c:97 #, c-format msgid "" -" --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +" --cflags_sl show CFLAGS_SL value used when PostgreSQL was " +"built\n" msgstr "" " --cflags_sl ukáže hodnotu CFLAGS_SL použitou pÅ™i buildu " "PostgreSQL\n" -#: pg_config.c:452 +#: pg_config.c:98 #, c-format msgid "" " --ldflags show LDFLAGS value used when PostgreSQL was built\n" @@ -217,7 +224,7 @@ msgstr "" " --ldflags ukáže hodnotu LDFLAGS použitou pÅ™i buildu " "PostgreSQL\n" -#: pg_config.c:453 +#: pg_config.c:99 #, c-format msgid "" " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " @@ -226,7 +233,7 @@ msgstr "" " --ldflags_ex ukáže hodnotu LDFLAGS_EX použitou pÅ™i buildu " "PostgreSQL\n" -#: pg_config.c:454 +#: pg_config.c:100 #, c-format msgid "" " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " @@ -235,24 +242,24 @@ msgstr "" " --ldflags_sl ukáže hodnotu LDFLAGS_SL použitou pÅ™i buildu " "PostgreSQL\n" -#: pg_config.c:455 +#: pg_config.c:101 #, c-format msgid "" " --libs show LIBS value used when PostgreSQL was built\n" msgstr "" " --libs ukáže hodnotu LIBS použitou pÅ™i buildu PostgreSQL\n" -#: pg_config.c:456 +#: pg_config.c:102 #, c-format msgid " --version show the PostgreSQL version\n" msgstr " --version ukáže verzi PostgreSQL\n" -#: pg_config.c:457 +#: pg_config.c:103 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ukáže tuto nápovÄ›du, a skonÄí\n" -#: pg_config.c:458 +#: pg_config.c:104 #, c-format msgid "" "\n" @@ -263,22 +270,22 @@ msgstr "" "Bez argumentů jsou vypsány vÅ¡echny známé položky.\n" "\n" -#: pg_config.c:459 +#: pg_config.c:105 #, c-format msgid "Report bugs to .\n" msgstr "Oznámení o chybách zasílejte na .\n" -#: pg_config.c:465 +#: pg_config.c:111 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_config.c:504 +#: pg_config.c:153 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: nelze najít vlastní spustitelný soubor\n" -#: pg_config.c:527 +#: pg_config.c:180 #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: neplatný parametr: %s\n" diff --git a/src/bin/pg_config/po/es.po b/src/bin/pg_config/po/es.po index 17bdb2ba5ba..77b0b7ab4dd 100644 --- a/src/bin/pg_config/po/es.po +++ b/src/bin/pg_config/po/es.po @@ -1,66 +1,70 @@ # pg_config spanish translation # -# Copyright (C) 2004-2013 PostgreSQL Global Development Group +# Copyright (c) 2004-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Alvaro Herrera , 2004-2013 # msgid "" msgstr "" -"Project-Id-Version: pg_config (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:45+0000\n" -"PO-Revision-Date: 2017-07-10 12:13-0400\n" +"Project-Id-Version: pg_config (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:13+0000\n" +"PO-Revision-Date: 2019-06-06 17:22-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: es \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7\n" -#: ../../common/config_info.c:131 ../../common/config_info.c:139 -#: ../../common/config_info.c:147 ../../common/config_info.c:155 -#: ../../common/config_info.c:163 ../../common/config_info.c:171 -#: ../../common/config_info.c:179 ../../common/config_info.c:187 -#: ../../common/config_info.c:195 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 msgid "not recorded" msgstr "no registrado" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar el directorio a «%s»: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "pclose failed: %m" +msgstr "pclose falló: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "memoria agotada" #: pg_config.c:74 #, c-format @@ -261,8 +265,8 @@ msgstr "" #: pg_config.c:105 #, c-format -msgid "Report bugs to .\n" -msgstr "Reporte errores a .\n" +msgid "Report bugs to .\n" +msgstr "Reporte errores a .\n" #: pg_config.c:111 #, c-format diff --git a/src/bin/pg_config/po/fr.po b/src/bin/pg_config/po/fr.po index 8cb7adae277..bc98b37c46a 100644 --- a/src/bin/pg_config/po/fr.po +++ b/src/bin/pg_config/po/fr.po @@ -7,60 +7,64 @@ # Stéphane Schildknecht , 2009. msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-05-08 21:13+0000\n" -"PO-Revision-Date: 2016-05-09 10:19+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:16+0000\n" +"PO-Revision-Date: 2019-05-17 15:08+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.2.1\n" -#: ../../common/config_info.c:131 ../../common/config_info.c:139 -#: ../../common/config_info.c:147 ../../common/config_info.c:155 -#: ../../common/config_info.c:163 ../../common/config_info.c:171 -#: ../../common/config_info.c:179 ../../common/config_info.c:187 -#: ../../common/config_info.c:195 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 msgid "not recorded" msgstr "non enregistré" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "n'a pas pu identifier le répertoire courant : %s" +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "binaire « %s » invalide" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "n'a pas pu lire le binaire « %s »" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "n'a pas pu trouver un « %s » à exécuter" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "n'a pas pu changer le répertoire par « %s » : %s" +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "n'a pas pu lire le lien symbolique « %s »" +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "échec de pclose : %s" +msgid "pclose failed: %m" +msgstr "échec de pclose : %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "mémoire épuisée" #: pg_config.c:74 #, c-format @@ -95,18 +99,23 @@ msgstr "Options :\n" #: pg_config.c:78 #, c-format msgid " --bindir show location of user executables\n" -msgstr " --bindir affiche l'emplacement des exécutables utilisateur\n" +msgstr "" +" --bindir affiche l'emplacement des exécutables " +"utilisateur\n" #: pg_config.c:79 #, c-format msgid " --docdir show location of documentation files\n" -msgstr " --docdir affiche l'emplacement des fichiers de documentation\n" +msgstr "" +" --docdir affiche l'emplacement des fichiers de " +"documentation\n" #: pg_config.c:80 #, c-format msgid " --htmldir show location of HTML documentation files\n" msgstr "" -" --htmldir affiche l'emplacement des fichiers de documentation\n" +" --htmldir affiche l'emplacement des fichiers de " +"documentation\n" " HTML\n" #: pg_config.c:81 @@ -122,14 +131,17 @@ msgstr "" #, c-format msgid " --pkgincludedir show location of other C header files\n" msgstr "" -" --pkgincludedir affiche l'emplacement des autres fichiers d'en-tête\n" +" --pkgincludedir affiche l'emplacement des autres fichiers d'en-" +"tête\n" " C\n" #: pg_config.c:84 #, c-format -msgid " --includedir-server show location of C header files for the server\n" +msgid "" +" --includedir-server show location of C header files for the server\n" msgstr "" -" --includedir-server affiche l'emplacement des fichiers d'en-tête C du\n" +" --includedir-server affiche l'emplacement des fichiers d'en-tête C " +"du\n" " serveur\n" #: pg_config.c:85 @@ -139,7 +151,8 @@ msgstr " --libdir affiche l'emplacement des bibliothèques\n" #: pg_config.c:86 #, c-format -msgid " --pkglibdir show location of dynamically loadable modules\n" +msgid "" +" --pkglibdir show location of dynamically loadable modules\n" msgstr "" " --pkglibdir affiche l'emplacement des modules chargeables\n" " dynamiquement\n" @@ -148,7 +161,8 @@ msgstr "" #, c-format msgid " --localedir show location of locale support files\n" msgstr "" -" --localedir affiche l'emplacement des fichiers de support de la\n" +" --localedir affiche l'emplacement des fichiers de support de " +"la\n" " locale\n" #: pg_config.c:88 @@ -158,22 +172,27 @@ msgstr " --mandir affiche l'emplacement des pages man\n" #: pg_config.c:89 #, c-format -msgid " --sharedir show location of architecture-independent support files\n" +msgid "" +" --sharedir show location of architecture-independent support " +"files\n" msgstr "" " --sharedir affiche l'emplacement des fichiers de support\n" " indépendants de l'architecture\n" #: pg_config.c:90 #, c-format -msgid " --sysconfdir show location of system-wide configuration files\n" +msgid "" +" --sysconfdir show location of system-wide configuration files\n" msgstr "" -" --sysconfdir affiche l'emplacement des fichiers de configuration\n" +" --sysconfdir affiche l'emplacement des fichiers de " +"configuration\n" " globaux du système\n" #: pg_config.c:91 #, c-format msgid " --pgxs show location of extension makefile\n" -msgstr " --pgxs affiche l'emplacement du makefile des extensions\n" +msgstr "" +" --pgxs affiche l'emplacement du makefile des extensions\n" #: pg_config.c:92 #, c-format @@ -181,61 +200,80 @@ msgid "" " --configure show options given to \"configure\" script when\n" " PostgreSQL was built\n" msgstr "" -" --configure affiche les options passées au script « configure »\n" +" --configure affiche les options passées au script « configure " +"»\n" " à la construction de PostgreSQL\n" #: pg_config.c:94 #, c-format -msgid " --cc show CC value used when PostgreSQL was built\n" +msgid "" +" --cc show CC value used when PostgreSQL was built\n" msgstr "" " --cc affiche la valeur de CC utilisée lors de la\n" " construction de PostgreSQL\n" #: pg_config.c:95 #, c-format -msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgid "" +" --cppflags show CPPFLAGS value used when PostgreSQL was " +"built\n" msgstr "" -" --cppflags affiche la valeur de CPPFLAGS utilisée lors de la\n" +" --cppflags affiche la valeur de CPPFLAGS utilisée lors de " +"la\n" " construction de PostgreSQL\n" #: pg_config.c:96 #, c-format -msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" +msgid "" +" --cflags show CFLAGS value used when PostgreSQL was built\n" msgstr "" " --cflags affiche la valeur de CFLAGS utilisée lors de la\n" " construction de PostgreSQL\n" #: pg_config.c:97 #, c-format -msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgid "" +" --cflags_sl show CFLAGS_SL value used when PostgreSQL was " +"built\n" msgstr "" -" --cflags_sl affiche la valeur de CFLAGS_SL utilisée lors de la\n" +" --cflags_sl affiche la valeur de CFLAGS_SL utilisée lors de " +"la\n" " construction de PostgreSQL\n" #: pg_config.c:98 #, c-format -msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgid "" +" --ldflags show LDFLAGS value used when PostgreSQL was " +"built\n" msgstr "" -" --ldflags affiche la valeur de LDFLAGS utilisée à lors de la\n" +" --ldflags affiche la valeur de LDFLAGS utilisée à lors de " +"la\n" " construction de PostgreSQL\n" #: pg_config.c:99 #, c-format -msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" +msgid "" +" --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " +"built\n" msgstr "" -" --ldflags_ex affiche la valeur de LDFLAGS_EX utilisée lors de la\n" +" --ldflags_ex affiche la valeur de LDFLAGS_EX utilisée lors de " +"la\n" " construction de PostgreSQL\n" #: pg_config.c:100 #, c-format -msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" +msgid "" +" --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " +"built\n" msgstr "" -" --ldflags_sl affiche la valeur de LDFLAGS_SL utilisée lors de la\n" +" --ldflags_sl affiche la valeur de LDFLAGS_SL utilisée lors de " +"la\n" " construction de PostgreSQL\n" #: pg_config.c:101 #, c-format -msgid " --libs show LIBS value used when PostgreSQL was built\n" +msgid "" +" --libs show LIBS value used when PostgreSQL was built\n" msgstr "" " --libs affiche la valeur de LIBS utilisée lors de la\n" " construction de PostgreSQL\n" @@ -263,8 +301,8 @@ msgstr "" #: pg_config.c:105 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapporter les bogues à .\n" +msgid "Report bugs to .\n" +msgstr "Rapporter les bogues à .\n" #: pg_config.c:111 #, c-format @@ -281,23 +319,29 @@ msgstr "%s : n'a pas pu trouver son propre exécutable\n" msgid "%s: invalid argument: %s\n" msgstr "%s : argument invalide : %s\n" -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "n'a pas pu accéder au répertoire « %s »" +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help affiche cette aide puis quitte\n" -#~ msgid "child process exited with exit code %d" -#~ msgstr "le processus fils a quitté avec le code de sortie %d" +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "le processus fils a quitté avec un statut %d non reconnu" -#~ msgid "child process was terminated by exception 0x%X" -#~ msgstr "le processus fils a été terminé par l'exception 0x%X" +#~ msgid "child process was terminated by signal %d" +#~ msgstr "le processus fils a été terminé par le signal %d" #~ msgid "child process was terminated by signal %s" #~ msgstr "le processus fils a été terminé par le signal %s" -#~ msgid "child process was terminated by signal %d" -#~ msgstr "le processus fils a été terminé par le signal %d" +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "le processus fils a été terminé par l'exception 0x%X" -#~ msgid "child process exited with unrecognized status %d" -#~ msgstr "le processus fils a quitté avec un statut %d non reconnu" +#~ msgid "child process exited with exit code %d" +#~ msgstr "le processus fils a quitté avec le code de sortie %d" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help affiche cette aide puis quitte\n" +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "n'a pas pu accéder au répertoire « %s »" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu changer le répertoire par « %s » : %s" diff --git a/src/bin/pg_config/po/it.po b/src/bin/pg_config/po/it.po index 5e855db53c2..b90719522d4 100644 --- a/src/bin/pg_config/po/it.po +++ b/src/bin/pg_config/po/it.po @@ -1,19 +1,17 @@ # -# Translation of pg_config to Italian -# PostgreSQL Project +# pg_config.po +# Italian message translation file for pg_config # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Cosimo D'Arcangelo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017 +# Cosimo D'Arcangelo 2010 # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" @@ -22,7 +20,7 @@ msgstr "" "POT-Creation-Date: 2017-04-22 22:45+0000\n" "PO-Revision-Date: 2017-04-23 03:04+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/src/bin/pg_config/po/ja.po b/src/bin/pg_config/po/ja.po index ec2b4e584e8..d4edc63f0bd 100644 --- a/src/bin/pg_config/po/ja.po +++ b/src/bin/pg_config/po/ja.po @@ -5,59 +5,61 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.0 beta 3\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 11:27+0900\n" -"PO-Revision-Date: 2012-08-11 16:53+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-08-31 16:21+0900\n" +"PO-Revision-Date: 2018-08-27 12:15+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 +msgid "not recorded" +msgstr "記録ã•れã¦ã„ã¾ã›ã‚“" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" msgstr "ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’èªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../../port/exec.c:146 +#: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"ã¯ç„¡åйã§ã™" -#: ../../port/exec.c:195 +#: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ" -#: ../../port/exec.c:202 +#: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" msgstr "実行ã™ã‚‹\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../../port/exec.c:272 +#: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "シンボリックリンク\"%s\"を読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: ../../port/exec.c:523 +#: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "pcloseãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: pg_config.c:243 pg_config.c:259 pg_config.c:275 pg_config.c:291 -#: pg_config.c:307 pg_config.c:323 pg_config.c:339 pg_config.c:355 -#: pg_config.c:371 -#, c-format -msgid "not recorded\n" -msgstr "記録ã•れã¦ã„ã¾ã›ã‚“\n" - -#: pg_config.c:428 +#: pg_config.c:74 #, c-format msgid "" "\n" @@ -68,12 +70,12 @@ msgstr "" "%sã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れãŸãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®PostgreSQLã«é–¢ã™ã‚‹æƒ…報をæä¾›ã—ã¾ã™ã€‚\n" "\n" -#: pg_config.c:429 +#: pg_config.c:75 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_config.c:430 +#: pg_config.c:76 #, c-format msgid "" " %s [OPTION]...\n" @@ -82,136 +84,136 @@ msgstr "" " %s [オプション]...\n" "\n" -#: pg_config.c:431 +#: pg_config.c:77 #, c-format msgid "Options:\n" msgstr "オプション:\n" -#: pg_config.c:432 +#: pg_config.c:78 #, c-format msgid " --bindir show location of user executables\n" msgstr " --bindir ユーザ実行ファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:433 +#: pg_config.c:79 #, c-format msgid " --docdir show location of documentation files\n" msgstr " --docdir 文書ファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:434 +#: pg_config.c:80 #, c-format msgid " --htmldir show location of HTML documentation files\n" msgstr " --htmldir html文書ファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:435 +#: pg_config.c:81 #, c-format msgid "" " --includedir show location of C header files of the client\n" " interfaces\n" msgstr " --includedir クライアントインタフェース用Cヘッダファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:437 +#: pg_config.c:83 #, c-format msgid " --pkgincludedir show location of other C header files\n" msgstr " --pkgincludedir ãã®ä»–ã®Cヘッダファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:438 +#: pg_config.c:84 #, c-format msgid " --includedir-server show location of C header files for the server\n" msgstr " --includedir-server サーãƒç”¨Cヘッダファイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:439 +#: pg_config.c:85 #, c-format msgid " --libdir show location of object code libraries\n" msgstr " --libdir オブジェクトコードライブラリã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:440 +#: pg_config.c:86 #, c-format msgid " --pkglibdir show location of dynamically loadable modules\n" msgstr " --pkglibdir 動的ロードå¯èƒ½ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:441 +#: pg_config.c:87 #, c-format msgid " --localedir show location of locale support files\n" msgstr " --localedir ロケールサãƒãƒ¼ãƒˆãƒ•ァイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:442 +#: pg_config.c:88 #, c-format msgid " --mandir show location of manual pages\n" msgstr " --mandir マニュアルページã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:443 +#: pg_config.c:89 #, c-format msgid " --sharedir show location of architecture-independent support files\n" msgstr " --sharedir アーキテクãƒãƒ£ã«ä¾å­˜ã—ãªã„サãƒãƒ¼ãƒˆãƒ•ァイルã®å ´æ‰€ã‚’表示ã—ã¾ã™ã€‚\n" -#: pg_config.c:444 +#: pg_config.c:90 #, c-format msgid " --sysconfdir show location of system-wide configuration files\n" msgstr " --sysconfdir システム全体ã®è¨­å®šãƒ•ァイルã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:445 +#: pg_config.c:91 #, c-format msgid " --pgxs show location of extension makefile\n" msgstr " --pgxs æ‹¡å¼µmakefileã®å ´æ‰€ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:446 +#: pg_config.c:92 #, c-format msgid "" " --configure show options given to \"configure\" script when\n" " PostgreSQL was built\n" msgstr " --configure PostgreSQL構築時ã®\"configure\"ã‚¹ã‚¯ãƒªãƒ—ãƒˆã§æŒ‡å®šã—ãŸã‚ªãƒ—ションを表示ã—ã¾ã™\n" -#: pg_config.c:448 +#: pg_config.c:94 #, c-format msgid " --cc show CC value used when PostgreSQL was built\n" msgstr " --cc PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸCCã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:449 +#: pg_config.c:95 #, c-format msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" msgstr " --cppflags PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸCPPFLAGSã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:450 +#: pg_config.c:96 #, c-format msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" msgstr " --cflags PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸCFLAGSã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:451 +#: pg_config.c:97 #, c-format msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" msgstr " --cflags_sl PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸCFLAGS_SLã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:452 +#: pg_config.c:98 #, c-format msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸLDFLAGSã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:453 +#: pg_config.c:99 #, c-format msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" msgstr " --ldflags_ex PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸLDFLAGS_EXã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:454 +#: pg_config.c:100 #, c-format msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" msgstr " --ldflags_sl PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸLDFLAGS_SLã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:455 +#: pg_config.c:101 #, c-format msgid " --libs show LIBS value used when PostgreSQL was built\n" msgstr " --libs PostgreSQL構築時ã«ä½¿ç”¨ã—ãŸLIBSã®å€¤ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:456 +#: pg_config.c:102 #, c-format msgid " --version show the PostgreSQL version\n" msgstr " --version PostgreSQLã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’表示ã—ã¾ã™\n" -#: pg_config.c:457 +#: pg_config.c:103 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" -#: pg_config.c:458 +#: pg_config.c:104 #, c-format msgid "" "\n" @@ -222,43 +224,43 @@ msgstr "" "引数ãŒãªã„å ´åˆã€æ—¢çŸ¥ã®é …目をã™ã¹ã¦è¡¨ç¤ºã—ã¾ã™ã€‚\n" "\n" -#: pg_config.c:459 +#: pg_config.c:105 #, c-format msgid "Report bugs to .\n" msgstr "ä¸å…·åˆã¯ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" -#: pg_config.c:465 +#: pg_config.c:111 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "詳細ã¯\"%s --help\"を行ã£ã¦ãã ã•ã„\n" -#: pg_config.c:504 +#: pg_config.c:153 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: 実行ファイル自体ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ\n" -#: pg_config.c:527 +#: pg_config.c:180 #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: 無効ãªå¼•æ•°ã§ã™: %s\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help ヘルプを表示ã—ã€çµ‚了ã—ã¾ã™\n" +#~ msgid "child process was terminated by signal %d" +#~ msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ" -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ" +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "å­ãƒ—ãƒ­ã‚»ã‚¹ãŒæœªçŸ¥ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹%dã§çµ‚了ã—ã¾ã—ãŸ" -#~ msgid "child process was terminated by signal %s" -#~ msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%sã§çµ‚了ã—ã¾ã—ãŸ" +#~ msgid "child process exited with exit code %d" +#~ msgstr "å­ãƒ—ロセスãŒçµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" #~ msgid "child process was terminated by exception 0x%X" #~ msgstr "å­ãƒ—ロセスãŒä¾‹å¤–0x%Xã§çµ‚了ã—ã¾ã—ãŸ" -#~ msgid "child process exited with exit code %d" -#~ msgstr "å­ãƒ—ロセスãŒçµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" +#~ msgid "child process was terminated by signal %s" +#~ msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%sã§çµ‚了ã—ã¾ã—ãŸ" -#~ msgid "child process exited with unrecognized status %d" -#~ msgstr "å­ãƒ—ãƒ­ã‚»ã‚¹ãŒæœªçŸ¥ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹%dã§çµ‚了ã—ã¾ã—ãŸ" +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "child process was terminated by signal %d" -#~ msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ" +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help ヘルプを表示ã—ã€çµ‚了ã—ã¾ã™\n" diff --git a/src/bin/pg_config/po/ko.po b/src/bin/pg_config/po/ko.po index 82a89314b48..f60c0d506a8 100644 --- a/src/bin/pg_config/po/ko.po +++ b/src/bin/pg_config/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6 pg_config\n" +"Project-Id-Version: pg_config (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 16:47+0900\n" +"POT-Creation-Date: 2017-08-02 13:57+0900\n" +"PO-Revision-Date: 2017-08-17 13:16+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean team \n" "Language: ko\n" @@ -15,11 +15,11 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../../common/config_info.c:131 ../../common/config_info.c:139 -#: ../../common/config_info.c:147 ../../common/config_info.c:155 -#: ../../common/config_info.c:163 ../../common/config_info.c:171 -#: ../../common/config_info.c:179 ../../common/config_info.c:187 -#: ../../common/config_info.c:195 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 msgid "not recorded" msgstr "기ë¡ë˜ì–´ 있지 않ìŒ" diff --git a/src/bin/pg_config/po/ru.po b/src/bin/pg_config/po/ru.po index b28bdfaa133..bbbe88b40fe 100644 --- a/src/bin/pg_config/po/ru.po +++ b/src/bin/pg_config/po/ru.po @@ -5,13 +5,12 @@ # Serguei A. Mokhov , 2004-2005. # Sergey Burladyan , 2009, 2012. # Andrey Sudnik , 2010. -# Alexander Lakhin , 2012-2016. -# +# Alexander Lakhin , 2012-2016, 2017. msgid "" msgstr "" "Project-Id-Version: pg_config (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-20 18:13+0000\n" +"POT-Creation-Date: 2017-08-17 23:14+0000\n" "PO-Revision-Date: 2016-09-20 12:00+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" @@ -22,11 +21,11 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: ../../common/config_info.c:131 ../../common/config_info.c:139 -#: ../../common/config_info.c:147 ../../common/config_info.c:155 -#: ../../common/config_info.c:163 ../../common/config_info.c:171 -#: ../../common/config_info.c:179 ../../common/config_info.c:187 -#: ../../common/config_info.c:195 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 msgid "not recorded" msgstr "не запиÑано" diff --git a/src/bin/pg_config/po/sv.po b/src/bin/pg_config/po/sv.po index 85f230ea679..dd76ac3e483 100644 --- a/src/bin/pg_config/po/sv.po +++ b/src/bin/pg_config/po/sv.po @@ -1,13 +1,13 @@ # Swedish message translation file for pg_config. -# Dennis Björklund , 2004, 2005, 2006, 2017. +# Dennis Björklund , 2004, 2005, 2006, 2017, 2018, 2019. # Mats Erik Andersson , 2014. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-13 23:45+0000\n" -"PO-Revision-Date: 2017-07-20 21:37+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 07:16+0000\n" +"PO-Revision-Date: 2019-04-29 13:31+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -23,40 +23,44 @@ msgstr "" msgid "not recorded" msgstr "ej sparad" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "kunde inte identifiera aktuell katalog: %s" +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ogiltig binär \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "kunde inte läsa binär \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "kunde inte byta katalog till \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "kunde inte läsa symbolisk länk \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose misslyckades: %s" +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "slut pÃ¥ minne" #: pg_config.c:74 #, c-format @@ -229,8 +233,8 @@ msgstr "" #: pg_config.c:105 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapportera fel till .\n" +msgid "Report bugs to .\n" +msgstr "Rapportera buggar till .\n" #: pg_config.c:111 #, c-format @@ -246,3 +250,18 @@ msgstr "%s: kunde inte hitta det egna programmets körbara fil\n" #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: ogiltigt argument: %s\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapportera fel till .\n" + +#~ msgid "pclose failed: %s" +#~ msgstr "pclose misslyckades: %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "kunde inte identifiera aktuell katalog: %s" diff --git a/src/bin/pg_config/po/tr.po b/src/bin/pg_config/po/tr.po index c7e21305bfc..61e838f2ffb 100644 --- a/src/bin/pg_config/po/tr.po +++ b/src/bin/pg_config/po/tr.po @@ -1,37 +1,66 @@ # translation of pg_config-tr.po to Turkish # Devrim GUNDUZ , 2004, 2005, 2007. # Nicolai Tufar , 2005, 2007. +# Abdullah Gülner , 2018. # msgid "" msgstr "" "Project-Id-Version: pg_config-tr\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2010-08-31 20:02+0000\n" -"PO-Revision-Date: 2013-09-04 20:49-0400\n" -"Last-Translator: Devrim GÜNDÜZ \n" +"POT-Creation-Date: 2018-11-27 07:44+0000\n" +"PO-Revision-Date: 2018-11-27 16:29+0300\n" +"Last-Translator: Abdullah Gülner\n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" -"X-Poedit-Language: Turkish\n" -"X-Poedit-Country: TURKEY\n" +"X-Generator: Poedit 1.8.7.1\n" -#: pg_config.c:243 -#: pg_config.c:259 -#: pg_config.c:275 -#: pg_config.c:291 -#: pg_config.c:307 -#: pg_config.c:323 -#: pg_config.c:339 -#: pg_config.c:355 -#: pg_config.c:371 +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 +msgid "not recorded" +msgstr "kayıtlı deÄŸil" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "geçerli dizin tespit edilemedi: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "geçersiz ikili (binary) \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili (binary) dosyası okunamadı" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" çalıştırmak için bulunamadı" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "symbolic link \"%s\" okuma hatası" + +#: ../../common/exec.c:523 #, c-format -msgid "not recorded\n" -msgstr "kayıtlı deÄŸil\n" +msgid "pclose failed: %s" +msgstr "pclose baÅŸarısız oldu: %s" -#: pg_config.c:428 +#: pg_config.c:74 #, c-format msgid "" "\n" @@ -42,12 +71,12 @@ msgstr "" "%s kurulu PostgreSQL sürümü hakkında bilgi verir.\n" "\n" -#: pg_config.c:429 +#: pg_config.c:75 #, c-format msgid "Usage:\n" msgstr "Kullanımı:\n" -#: pg_config.c:430 +#: pg_config.c:76 #, c-format msgid "" " %s [OPTION]...\n" @@ -56,27 +85,27 @@ msgstr "" " %s [SEÇENEK]...\n" "\n" -#: pg_config.c:431 +#: pg_config.c:77 #, c-format msgid "Options:\n" msgstr "Seçenekler:\n" -#: pg_config.c:432 +#: pg_config.c:78 #, c-format msgid " --bindir show location of user executables\n" msgstr " --bindir kullanıcı tarafından çalıştırılabilir dosyaların yerlerini göster\n" -#: pg_config.c:433 +#: pg_config.c:79 #, c-format msgid " --docdir show location of documentation files\n" msgstr " --docdir dokümantasyon dosyaların yerini göster\n" -#: pg_config.c:434 +#: pg_config.c:80 #, c-format msgid " --htmldir show location of HTML documentation files\n" msgstr " --docdir HTML belge dosyalarının yerini göster\n" -#: pg_config.c:435 +#: pg_config.c:81 #, c-format msgid "" " --includedir show location of C header files of the client\n" @@ -85,52 +114,52 @@ msgstr "" " --includedir İstemci arabirimlerinin C baÅŸlık dosyalarının yerlerini\n" " göster\n" -#: pg_config.c:437 +#: pg_config.c:83 #, c-format msgid " --pkgincludedir show location of other C header files\n" msgstr " --pkgincludedir diÄŸer C baÅŸlık dosyalarının yerlerini göster\n" -#: pg_config.c:438 +#: pg_config.c:84 #, c-format msgid " --includedir-server show location of C header files for the server\n" msgstr " --includedir-server Sunucu için C baÅŸlık dosyalarının yerlerini göster\n" -#: pg_config.c:439 +#: pg_config.c:85 #, c-format msgid " --libdir show location of object code libraries\n" msgstr " --libdir nesne kod kütüphanelerinin yerini göster\n" -#: pg_config.c:440 +#: pg_config.c:86 #, c-format msgid " --pkglibdir show location of dynamically loadable modules\n" msgstr " --pkglibdir Dinamik olarak yüklenebilen modüllerin yerlerini göster\n" -#: pg_config.c:441 +#: pg_config.c:87 #, c-format msgid " --localedir show location of locale support files\n" msgstr " --localedir yerel dil destek dosyalarının yerini göster\n" -#: pg_config.c:442 +#: pg_config.c:88 #, c-format msgid " --mandir show location of manual pages\n" msgstr " --mandir kullanıcı kılavuzu (man) dosyaların yerini göster\n" -#: pg_config.c:443 +#: pg_config.c:89 #, c-format msgid " --sharedir show location of architecture-independent support files\n" msgstr " --sharedir platform bağımsız dosyaların yerini göster\n" -#: pg_config.c:444 +#: pg_config.c:90 #, c-format msgid " --sysconfdir show location of system-wide configuration files\n" msgstr " --sysconfdir sistem geneli parametre dosyaların yerini göster\n" -#: pg_config.c:445 +#: pg_config.c:91 #, c-format msgid " --pgxs show location of extension makefile\n" msgstr " --pgxs extension makefile dosyasının yerini göster\n" -#: pg_config.c:446 +#: pg_config.c:92 #, c-format msgid "" " --configure show options given to \"configure\" script when\n" @@ -139,57 +168,57 @@ msgstr "" " --configure PostgreSQL yapılandırıldığında \"configure\" betiÄŸine verilen\n" " seçeneklerin listesini göster\n" -#: pg_config.c:448 +#: pg_config.c:94 #, c-format msgid " --cc show CC value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan CC deÄŸerini göster\n" -#: pg_config.c:449 +#: pg_config.c:95 #, c-format msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan CPPFLAGS deÄŸerini göster\n" -#: pg_config.c:450 +#: pg_config.c:96 #, c-format msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan CFLAGS deÄŸerini göster\n" -#: pg_config.c:451 +#: pg_config.c:97 #, c-format msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan CFLAGS_SL deÄŸerini göster\n" -#: pg_config.c:452 +#: pg_config.c:98 #, c-format msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan LDFLAGS deÄŸerini göster\n" -#: pg_config.c:453 +#: pg_config.c:99 #, c-format msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" msgstr " --ldflags_ex PostgreSQL derlemesi sırasında kullanılan LDFLAGS_EX deÄŸerini göster\n" -#: pg_config.c:454 +#: pg_config.c:100 #, c-format msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" msgstr " --ldflags PostgreSQL derleme sırasında kullanılan LDFLAGS_SL deÄŸerini göster\n" -#: pg_config.c:455 +#: pg_config.c:101 #, c-format msgid " --libs show LIBS value used when PostgreSQL was built\n" msgstr " --libs PostgreSQL derleme sırasında kullanılan LIBS deÄŸerini göster\n" -#: pg_config.c:456 +#: pg_config.c:102 #, c-format msgid " --version show the PostgreSQL version\n" msgstr " --version PostgreSQL sürümünü göster ve çık\n" -#: pg_config.c:457 +#: pg_config.c:103 #, c-format -msgid " --help show this help, then exit\n" -msgstr " --help bu yardımı göster ve çık\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" -#: pg_config.c:458 +#: pg_config.c:104 #, c-format msgid "" "\n" @@ -200,87 +229,53 @@ msgstr "" "Parametre verilmediyse, tüm deÄŸerleri gösterilmektedir.\n" "\n" -#: pg_config.c:459 +#: pg_config.c:105 #, c-format msgid "Report bugs to .\n" msgstr "Hataları adresine bildirebilirsiniz.\n" -#: pg_config.c:465 +#: pg_config.c:111 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Daha fazla bilgi için\"%s --help\" parametresini kullanabilirsiniz\n" -#: pg_config.c:504 +#: pg_config.c:153 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: çalıştırılabilir dosya bulunamadı\n" -#: pg_config.c:527 +#: pg_config.c:180 #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: geçersiz argüman: %s\n" -#: ../../port/exec.c:125 -#: ../../port/exec.c:239 -#: ../../port/exec.c:282 -#, c-format -msgid "could not identify current directory: %s" -msgstr "geçerli dizin tespit edilemedi: %s" - -#: ../../port/exec.c:144 -#, c-format -msgid "invalid binary \"%s\"" -msgstr "geçersiz ikili (binary) \"%s\"" +#~ msgid "" +#~ " %s [ OPTION ... ]\n" +#~ "\n" +#~ msgstr "" +#~ " %s [ SEÇENEK ... ]\n" +#~ "\n" -#: ../../port/exec.c:193 -#, c-format -msgid "could not read binary \"%s\"" -msgstr "\"%s\" ikili (binary) dosyası okunamadı" +#~ msgid "child process exited with unrecognized status %d" +#~ msgstr "alt süreç %d bilinmeyen durumu ile sonlandırıldı" -#: ../../port/exec.c:200 -#, c-format -msgid "could not find a \"%s\" to execute" -msgstr "\"%s\" çalıştırmak için bulunamadı" +#~ msgid "child process was terminated by signal %d" +#~ msgstr "alt süreç %d sinyali tarafından sonlandırıldı" -#: ../../port/exec.c:255 -#: ../../port/exec.c:291 -#, c-format -msgid "could not change directory to \"%s\"" -msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" +#~ msgid "child process was terminated by signal %s" +#~ msgstr "alt süreç %s sinyali tarafından sonlandırıldı" -#: ../../port/exec.c:270 -#, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "symbolic link \"%s\" okuma hatası" - -#: ../../port/exec.c:516 -#, c-format -msgid "child process exited with exit code %d" -msgstr "alt süreç %d çıkış koduyla sonuçlandı" +#~ msgid "child process was terminated by exception 0x%X" +#~ msgstr "alt süreç 0x%X exception tarafından sonlandırıldı" -#: ../../port/exec.c:520 -#, c-format -msgid "child process was terminated by exception 0x%X" -msgstr "alt süreç 0x%X exception tarafından sonlandırıldı" +#~ msgid "child process exited with exit code %d" +#~ msgstr "alt süreç %d çıkış koduyla sonuçlandı" -#: ../../port/exec.c:529 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "alt süreç %s sinyali tarafından sonlandırıldı" - -#: ../../port/exec.c:532 -#, c-format -msgid "child process was terminated by signal %d" -msgstr "alt süreç %d sinyali tarafından sonlandırıldı" +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" -#: ../../port/exec.c:536 -#, c-format -msgid "child process exited with unrecognized status %d" -msgstr "alt süreç %d bilinmeyen durumu ile sonlandırıldı" +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve çık\n" -#~ msgid "" -#~ " %s [ OPTION ... ]\n" -#~ "\n" -#~ msgstr "" -#~ " %s [ SEÇENEK ... ]\n" -#~ "\n" +#~ msgid "not recorded\n" +#~ msgstr "kayıtlı deÄŸil\n" diff --git a/src/bin/pg_config/po/vi.po b/src/bin/pg_config/po/vi.po new file mode 100644 index 00000000000..cd87cd756a1 --- /dev/null +++ b/src/bin/pg_config/po/vi.po @@ -0,0 +1,300 @@ +# LANGUAGE message translation file for pg_config +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_config (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_config (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:15+0000\n" +"PO-Revision-Date: 2018-05-04 22:18+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 +msgid "not recorded" +msgstr "không được ghi lại" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "không thể xác định thư mục hiện tại: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "tệp nhị phân không hợp lệ \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "không thể Ä‘á»c tệp nhị phân \"%s\"" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "không thể tìm thấy tệp \"%s\" để thá»±c thi" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "không thể thay đổi thư mục thành \"%s\": %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "không thể Ä‘á»c symbolic link \"%s\"" + +#: ../../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "pclose lá»—i: %s" + +#: pg_config.c:74 +#, c-format +msgid "" +"\n" +"%s provides information about the installed version of PostgreSQL.\n" +"\n" +msgstr "" +"\n" +"%s cung cấp thông tin vá» phiên bản đã cài đặt cá»§a PostgreSQL.\n" +"\n" + +#: pg_config.c:75 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: pg_config.c:76 +#, c-format +msgid "" +" %s [OPTION]...\n" +"\n" +msgstr "" +" %s [TÙY CHỌN]...\n" +"\n" + +#: pg_config.c:77 +#, c-format +msgid "Options:\n" +msgstr "Tùy chá»n:\n" + +#: pg_config.c:78 +#, c-format +msgid " --bindir show location of user executables\n" +msgstr "" +" --bindir hiển thị vị trí thư mục tệp thá»±c thi cá»§a ngưá»i " +"dùng\n" + +#: pg_config.c:79 +#, c-format +msgid " --docdir show location of documentation files\n" +msgstr " --docdir hiển thị vị trí cá»§a các tệp tài liệu\n" + +#: pg_config.c:80 +#, c-format +msgid " --htmldir show location of HTML documentation files\n" +msgstr " --htmldir hiển thị vị trí cá»§a các tệp tài liệu HTML\n" + +#: pg_config.c:81 +#, c-format +msgid "" +" --includedir show location of C header files of the client\n" +" interfaces\n" +msgstr "" +" --includedir hiển thị vị trí cá»§a tệp header ngôn ngữ C cá»§a\n" +" giao diện phía client\n" + +#: pg_config.c:83 +#, c-format +msgid " --pkgincludedir show location of other C header files\n" +msgstr "" +" --pkgincludedir hiện thị vị trí cá»§a các tệp header cho ngôn ngữ C " +"khác\n" + +#: pg_config.c:84 +#, c-format +msgid "" +" --includedir-server show location of C header files for the server\n" +msgstr "" +" --includedir-server hiện thị vị trí cá»§a các tệp header ngôn ngữ C " +"phía server\n" + +#: pg_config.c:85 +#, c-format +msgid " --libdir show location of object code libraries\n" +msgstr "" +" --libdir hiện thị ví trí cá»§a các tệp thư viện chương " +"trình\n" + +#: pg_config.c:86 +#, c-format +msgid "" +" --pkglibdir show location of dynamically loadable modules\n" +msgstr "" +" --pkglibdir hiển thị vị trí cá»§a các mô-Ä‘un có thể nạp động\n" + +#: pg_config.c:87 +#, c-format +msgid " --localedir show location of locale support files\n" +msgstr " --localedir hiển thị vị trí cá»§a tệp há»— trợ ngôn ngữ\n" + +#: pg_config.c:88 +#, c-format +msgid " --mandir show location of manual pages\n" +msgstr " --mandir hiển thị vị trí cá»§a các trang hướng dẫn\n" + +#: pg_config.c:89 +#, c-format +msgid "" +" --sharedir show location of architecture-independent support " +"files\n" +msgstr "" +" --sharedir hiển thị vị trí cá»§a các tệp há»— trợ kiến trúc độc " +"lập\n" + +#: pg_config.c:90 +#, c-format +msgid "" +" --sysconfdir show location of system-wide configuration files\n" +msgstr "" +" --sysconfdir hiển thị vị trí cá»§a tệp cấu hình trên toàn hệ " +"thống\n" + +#: pg_config.c:91 +#, c-format +msgid " --pgxs show location of extension makefile\n" +msgstr "" +" --pgxs hiển thị vị trí tệp makefile cá»§a extension\n" + +#: pg_config.c:92 +#, c-format +msgid "" +" --configure show options given to \"configure\" script when\n" +" PostgreSQL was built\n" +msgstr "" +" --configure hiện thị tùy chá»n chỉ định trong script " +"\"configure\" \n" +" khi built PostgreSQL\n" + +#: pg_config.c:94 +#, c-format +msgid "" +" --cc show CC value used when PostgreSQL was built\n" +msgstr "" +" --cc hiển thị giá trị CC được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:95 +#, c-format +msgid "" +" --cppflags show CPPFLAGS value used when PostgreSQL was " +"built\n" +msgstr "" +" --cppflags hiện thị giá trị CPPFLAGS được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:96 +#, c-format +msgid "" +" --cflags show CFLAGS value used when PostgreSQL was built\n" +msgstr "" +" --cflags hiện thị giá trị CFLAGS được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:97 +#, c-format +msgid "" +" --cflags_sl show CFLAGS_SL value used when PostgreSQL was " +"built\n" +msgstr "" +" --cflags_sl hiện thị giá trị CFLAGS_SL được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:98 +#, c-format +msgid "" +" --ldflags show LDFLAGS value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags hiện thị giá trị LDFLAGS được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:99 +#, c-format +msgid "" +" --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags_ex hiện thị giá trị LDFLAGS_EX được sá»­ dụng khi " +"built PostgreSQL\n" + +#: pg_config.c:100 +#, c-format +msgid "" +" --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " +"built\n" +msgstr "" +" --ldflags_sl hiện thị giá trị LDFLAGS_SL được sá»­ dụng khi " +"built PostgreSQL\n" + +#: pg_config.c:101 +#, c-format +msgid "" +" --libs show LIBS value used when PostgreSQL was built\n" +msgstr "" +" --libs hiện thị giá trị LIBS được sá»­ dụng khi built " +"PostgreSQL\n" + +#: pg_config.c:102 +#, c-format +msgid " --version show the PostgreSQL version\n" +msgstr " --version hiển thị phiên bản PostgreSQL\n" + +#: pg_config.c:103 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help hiển thị trợ giúp này, sau đó thoát\n" + +#: pg_config.c:104 +#, c-format +msgid "" +"\n" +"With no arguments, all known items are shown.\n" +"\n" +msgstr "" +"\n" +"Nếu không có đối số, tất cả các mục sẽ được hiện thị.\n" +"\n" + +#: pg_config.c:105 +#, c-format +msgid "Report bugs to .\n" +msgstr "Báo cáo lá»—i tá»›i .\n" + +#: pg_config.c:111 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_config.c:153 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: không thể tìm thấy chương trình có thể thá»±c thi\n" + +#: pg_config.c:180 +#, c-format +msgid "%s: invalid argument: %s\n" +msgstr "%s: đối số không hợp lệ: %s\n" diff --git a/src/bin/pg_config/po/zh_CN.po b/src/bin/pg_config/po/zh_CN.po index faa24598a43..12f52fce92e 100644 --- a/src/bin/pg_config/po/zh_CN.po +++ b/src/bin/pg_config/po/zh_CN.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_config (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-09-02 00:26+0000\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:13+0000\n" "PO-Revision-Date: 2013-09-02 13:17+0800\n" "Last-Translator: Xiong He \n" "Language-Team: Chinese (Simplified)\n" @@ -16,53 +16,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 -#, c-format -msgid "could not identify current directory: %s" +#: ../../common/config_info.c:130 ../../common/config_info.c:138 +#: ../../common/config_info.c:146 ../../common/config_info.c:154 +#: ../../common/config_info.c:162 ../../common/config_info.c:170 +#: ../../common/config_info.c:178 ../../common/config_info.c:186 +#: ../../common/config_info.c:194 +msgid "not recorded" +msgstr "没有被记录" + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, fuzzy, c-format +#| msgid "could not identify current directory: %s" +msgid "could not identify current directory: %m" msgstr "无法确认当å‰ç›®å½•: %s" # command.c:122 -#: ../../port/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "æ— æ•ˆçš„äºŒè¿›åˆ¶ç  \"%s\"" # command.c:1103 -#: ../../port/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "无法读å–äºŒè¿›åˆ¶ç  \"%s\"" -#: ../../port/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "未能找到一个 \"%s\" æ¥æ‰§è¡Œ" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -#| msgid "could not change directory to \"%s\": %m" -msgid "could not change directory to \"%s\": %s" -msgstr "无法跳转到目录 \"%s\" 中: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "无法跳转到目录 \"%s\" 中: %m" -#: ../../port/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "无法读å–符å·é“¾ç»“ \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "无法读å–符å·é“¾æŽ¥ \"%s\": %m" -#: ../../port/exec.c:523 -#, c-format -#| msgid "query failed: %s" -msgid "pclose failed: %s" +#: ../../common/exec.c:541 +#, fuzzy, c-format +#| msgid "pclose failed: %s" +msgid "pclose failed: %m" msgstr "pclose调用失败: %s" -#: pg_config.c:243 pg_config.c:259 pg_config.c:275 pg_config.c:291 -#: pg_config.c:307 pg_config.c:323 pg_config.c:339 pg_config.c:355 -#: pg_config.c:371 -#, c-format -msgid "not recorded\n" -msgstr "没有记录\n" +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "内存用尽" -#: pg_config.c:428 +#: pg_config.c:74 #, c-format msgid "" "\n" @@ -73,39 +78,39 @@ msgstr "" "%s æä¾› PostgreSQL 的安装信æ¯.\n" "\n" -#: pg_config.c:429 +#: pg_config.c:75 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_config.c:430 +#: pg_config.c:76 #, c-format msgid "" " %s [OPTION]...\n" "\n" msgstr " %s [选项]...\n" -#: pg_config.c:431 +#: pg_config.c:77 #, c-format msgid "Options:\n" msgstr "选项:\n" -#: pg_config.c:432 +#: pg_config.c:78 #, c-format msgid " --bindir show location of user executables\n" msgstr " --bindir 显示执行文件所在ä½ç½®\n" -#: pg_config.c:433 +#: pg_config.c:79 #, c-format msgid " --docdir show location of documentation files\n" msgstr " --docdir 显示文档所在ä½ç½®\n" -#: pg_config.c:434 +#: pg_config.c:80 #, c-format msgid " --htmldir show location of HTML documentation files\n" msgstr " --htmldir 显示HTML文档文件所在ä½ç½®\n" -#: pg_config.c:435 +#: pg_config.c:81 #, c-format msgid "" " --includedir show location of C header files of the client\n" @@ -114,56 +119,52 @@ msgstr "" " --includedir æ˜¾ç¤ºå®¢æˆ·ç«¯æŽ¥å£ C 头文件所在\n" " ä½ç½®\n" -#: pg_config.c:437 +#: pg_config.c:83 #, c-format msgid " --pkgincludedir show location of other C header files\n" msgstr " --pkgincludedir 显示其它C语言头文件所在的ä½ç½®\n" -#: pg_config.c:438 +#: pg_config.c:84 #, c-format -msgid "" -" --includedir-server show location of C header files for the server\n" +msgid " --includedir-server show location of C header files for the server\n" msgstr " --includedir-server 显示æœåŠ¡ç«¯ C 头文件所在ä½ç½®\n" -#: pg_config.c:439 +#: pg_config.c:85 #, c-format msgid " --libdir show location of object code libraries\n" msgstr " --libdir 显示目标代ç åº“文件所在ä½ç½®\n" -#: pg_config.c:440 +#: pg_config.c:86 #, c-format msgid " --pkglibdir show location of dynamically loadable modules\n" msgstr " --pkglibdir 显示动æ€åŠ è½½åº“æ‰€åœ¨ä½ç½®\n" -#: pg_config.c:441 +#: pg_config.c:87 #, c-format msgid " --localedir show location of locale support files\n" msgstr " --localedir æ˜¾ç¤ºè¯­è¨€çŽ¯å¢ƒæ”¯æŒæ–‡ä»¶æ‰€åœ¨ä½ç½®\n" -#: pg_config.c:442 +#: pg_config.c:88 #, c-format msgid " --mandir show location of manual pages\n" msgstr " --mandir 显示å‚考手册所在ä½ç½®\n" -#: pg_config.c:443 +#: pg_config.c:89 #, c-format -msgid "" -" --sharedir show location of architecture-independent support " -"files\n" +msgid " --sharedir show location of architecture-independent support files\n" msgstr " --sharedir æ˜¾ç¤ºç‹¬ç«‹æž¶æž„æ”¯æŒæ–‡ä»¶æ‰€åœ¨ä½ç½®\n" -#: pg_config.c:444 +#: pg_config.c:90 #, c-format -msgid "" -" --sysconfdir show location of system-wide configuration files\n" +msgid " --sysconfdir show location of system-wide configuration files\n" msgstr " --sysconfdir 显示系统范围的é…置文件的所在ä½ç½®\n" -#: pg_config.c:445 +#: pg_config.c:91 #, c-format msgid " --pgxs show location of extension makefile\n" msgstr " --pgxs 显示扩展 makefile 所在ä½ç½®\n" -#: pg_config.c:446 +#: pg_config.c:92 #, c-format msgid "" " --configure show options given to \"configure\" script when\n" @@ -172,66 +173,57 @@ msgstr "" " --configure 显示编译 PostgreSQL æ—¶ \"configure\"\n" " 的选项\n" -#: pg_config.c:448 +#: pg_config.c:94 #, c-format msgid " --cc show CC value used when PostgreSQL was built\n" msgstr " --cc 显示在创建PostgreSQL时所使用的CC值\n" -#: pg_config.c:449 +#: pg_config.c:95 #, c-format -msgid "" -" --cppflags show CPPFLAGS value used when PostgreSQL was built\n" +msgid " --cppflags show CPPFLAGS value used when PostgreSQL was built\n" msgstr " --cppflags 当创建PostgreSQL时显示CPPFLAGS的值\n" -#: pg_config.c:450 +#: pg_config.c:96 #, c-format -msgid "" -" --cflags show CFLAGS value used when PostgreSQL was built\n" +msgid " --cflags show CFLAGS value used when PostgreSQL was built\n" msgstr " --cflags 显示在创建PostgreSQL时所使用的CFLAG值\n" -#: pg_config.c:451 +#: pg_config.c:97 #, c-format -msgid "" -" --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" +msgid " --cflags_sl show CFLAGS_SL value used when PostgreSQL was built\n" msgstr " --cflags_sl 当创建PostgreSQL时显示CFLAGS_SL的值\n" -#: pg_config.c:452 +#: pg_config.c:98 #, c-format -msgid "" -" --ldflags show LDFLAGS value used when PostgreSQL was built\n" +msgid " --ldflags show LDFLAGS value used when PostgreSQL was built\n" msgstr " --ldflags 显示在创建PostgreSQL时所使用的LDFLAG值\n" -#: pg_config.c:453 +#: pg_config.c:99 #, c-format -msgid "" -" --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was " -"built\n" +msgid " --ldflags_ex show LDFLAGS_EX value used when PostgreSQL was built\n" msgstr " --ldflags_ex 当创建PostgreSQL时显示LDFLAGS_EX的值\n" -#: pg_config.c:454 +#: pg_config.c:100 #, c-format -msgid "" -" --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was " -"built\n" +msgid " --ldflags_sl show LDFLAGS_SL value used when PostgreSQL was built\n" msgstr " --ldflags_sl 当创建PostgreSQL时显示LDFLAGS_SL的值\n" -#: pg_config.c:455 +#: pg_config.c:101 #, c-format -msgid "" -" --libs show LIBS value used when PostgreSQL was built\n" +msgid " --libs show LIBS value used when PostgreSQL was built\n" msgstr " --libs 显示在创建PostgreSQL时所使用的LIBS值\n" -#: pg_config.c:456 +#: pg_config.c:102 #, c-format msgid " --version show the PostgreSQL version\n" msgstr " --version 显示PostgreSQL的版本信æ¯\n" -#: pg_config.c:457 +#: pg_config.c:103 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help 显示帮助, ç„¶åŽé€€å‡º\n" -#: pg_config.c:458 +#: pg_config.c:104 #, c-format msgid "" "\n" @@ -242,65 +234,23 @@ msgstr "" "æ²¡æœ‰å‚æ•°,将显示所有已知的æˆå‘˜.\n" "\n" -#: pg_config.c:459 -#, c-format -msgid "Report bugs to .\n" +#: pg_config.c:105 +#, fuzzy, c-format +#| msgid "Report bugs to .\n" +msgid "Report bugs to .\n" msgstr "臭虫报告至 .\n" -#: pg_config.c:465 +#: pg_config.c:111 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "请用 \"%s --help\" èŽ·å–æ›´å¤šçš„ä¿¡æ¯.\n" -#: pg_config.c:504 +#: pg_config.c:153 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: 无法找到执行文件\n" -#: pg_config.c:527 +#: pg_config.c:180 #, c-format msgid "%s: invalid argument: %s\n" msgstr "%s: æ— æ•ˆå‚æ•°: %s\n" - -#~ msgid " --help show this help, then exit\n" -#~ msgstr "" -#~ " --help 显示此帮助信æ¯, ç„¶åŽé€€å‡º\n" -#~ "\n" - -#~ msgid "" -#~ " %s OPTION...\n" -#~ "\n" -#~ msgstr "" -#~ " %s 选项...\n" -#~ "\n" - -#~ msgid "" -#~ "\n" -#~ "Try \"%s --help\" for more information\n" -#~ msgstr "" -#~ "\n" -#~ "试用 \"%s --help\" èŽ·å–æ›´å¤šçš„ä¿¡æ¯\n" - -#~ msgid "%s: argument required\n" -#~ msgstr "%s: 需è¦å‚æ•°\n" - -#~ msgid "%s: could not find own executable\n" -#~ msgstr "%s: 找ä¸åˆ°æ‰§è¡Œæ–‡ä»¶\n" - -#~ msgid "child process exited with unrecognized status %d" -#~ msgstr "å­è¿›ç¨‹å·²é€€å‡º, æœªçŸ¥çŠ¶æ€ %d" - -#~ msgid "child process was terminated by signal %d" -#~ msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %d 终止" - -#~ msgid "child process was terminated by signal %s" -#~ msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %s 终止" - -#~ msgid "child process was terminated by exception 0x%X" -#~ msgstr "å­è¿›ç¨‹è¢«ä¾‹å¤–(exception) 0x%X 终止" - -#~ msgid "child process exited with exit code %d" -#~ msgstr "å­è¿›ç¨‹å·²é€€å‡º, 退出ç ä¸º %d" - -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "无法进入目录 \"%s\"" diff --git a/src/bin/pg_controldata/Makefile b/src/bin/pg_controldata/Makefile index 28d6d666fea..2d5c5621318 100644 --- a/src/bin/pg_controldata/Makefile +++ b/src/bin/pg_controldata/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_controldata # -# Copyright (c) 1998-2018, PostgreSQL Global Development Group +# Copyright (c) 1998-2019, PostgreSQL Global Development Group # # src/bin/pg_controldata/Makefile # diff --git a/src/bin/pg_controldata/nls.mk b/src/bin/pg_controldata/nls.mk index 23c2950fc24..c466de8bc21 100644 --- a/src/bin/pg_controldata/nls.mk +++ b/src/bin/pg_controldata/nls.mk @@ -1,4 +1,6 @@ # src/bin/pg_controldata/nls.mk CATALOG_NAME = pg_controldata -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv zh_CN +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr vi zh_CN GETTEXT_FILES = pg_controldata.c ../../common/controldata_utils.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 7d435ffa578..ff17804723e 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -4,7 +4,7 @@ * reads the data from $PGDATA/global/pg_control * * copyright (c) Oliver Elphick , 2001; - * licence: BSD + * license: BSD * * src/bin/pg_controldata/pg_controldata.c */ @@ -20,10 +20,12 @@ #include +#include "access/transam.h" #include "access/xlog.h" #include "access/xlog_internal.h" #include "catalog/pg_control.h" #include "common/controldata_utils.h" +#include "common/logging.h" #include "pg_getopt.h" #include "getopt_long.h" @@ -35,12 +37,12 @@ usage(const char *progname) printf(_("Usage:\n")); printf(_(" %s [OPTION] [DATADIR]\n"), progname); printf(_("\nOptions:\n")); - printf(_(" [-D,--pgdata=]DATADIR data directory\n")); - printf(_(" -V, --version output version information, then exit\n")); - printf(_(" -?, --help show this help, then exit\n")); + printf(_(" [-D, --pgdata=]DATADIR data directory\n")); + printf(_(" -V, --version output version information, then exit\n")); + printf(_(" -?, --help show this help, then exit\n")); printf(_("\nIf no data directory (DATADIR) is specified, " "the environment variable PGDATA\nis used.\n\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } @@ -97,7 +99,6 @@ main(int argc, char *argv[]) time_t time_tmp; char pgctime_str[128]; char ckpttime_str[128]; - char sysident_str[32]; char mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1]; const char *strftime_fmt = "%c"; const char *progname; @@ -106,8 +107,8 @@ main(int argc, char *argv[]) int i; int WalSegSz; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_controldata")); - progname = get_progname(argv[0]); if (argc > 1) @@ -149,8 +150,8 @@ main(int argc, char *argv[]) /* Complain if any arguments remain */ if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -158,13 +159,13 @@ main(int argc, char *argv[]) if (DataDir == NULL) { - fprintf(stderr, _("%s: no data directory specified\n"), progname); + pg_log_error("no data directory specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } /* get a copy of the control file */ - ControlFile = get_controlfile(DataDir, progname, &crc_ok); + ControlFile = get_controlfile(DataDir, &crc_ok); if (!crc_ok) printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n" "Either the file is corrupt, or it has a different layout than this program\n" @@ -174,11 +175,17 @@ main(int argc, char *argv[]) WalSegSz = ControlFile->xlog_seg_size; if (!IsValidWalSegSize(WalSegSz)) - printf(_("WARNING: invalid WAL segment size\n" - "The WAL segment size stored in the file, %d bytes, is not a power of two\n" - "between 1 MB and 1 GB. The file is corrupt and the results below are\n" - "untrustworthy.\n\n"), + { + printf(_("WARNING: invalid WAL segment size\n")); + printf(ngettext("The WAL segment size stored in the file, %d byte, is not a power of two\n" + "between 1 MB and 1 GB. The file is corrupt and the results below are\n" + "untrustworthy.\n\n", + "The WAL segment size stored in the file, %d bytes, is not a power of two\n" + "between 1 MB and 1 GB. The file is corrupt and the results below are\n" + "untrustworthy.\n\n", + WalSegSz), WalSegSz); + } /* * This slightly-chintzy coding will work as long as the control file @@ -214,13 +221,6 @@ main(int argc, char *argv[]) else strcpy(xlogfilename, _("???")); - /* - * Format system_identifier and mock_authentication_nonce separately to - * keep platform-dependent format code out of the translatable message - * string. - */ - snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT, - ControlFile->system_identifier); for (i = 0; i < MOCK_AUTH_NONCE_LEN; i++) snprintf(&mock_auth_nonce_str[i * 2], 3, "%02x", (unsigned char) ControlFile->mock_authentication_nonce[i]); @@ -229,8 +229,8 @@ main(int argc, char *argv[]) ControlFile->pg_control_version); printf(_("Catalog version number: %u\n"), ControlFile->catalog_version_no); - printf(_("Database system identifier: %s\n"), - sysident_str); + printf(_("Database system identifier: %llu\n"), + (unsigned long long) ControlFile->system_identifier); printf(_("Database cluster state: %s\n"), dbState(ControlFile->state)); printf(_("pg_control last modified: %s\n"), @@ -250,8 +250,8 @@ main(int argc, char *argv[]) printf(_("Latest checkpoint's full_page_writes: %s\n"), ControlFile->checkPointCopy.fullPageWrites ? _("on") : _("off")); printf(_("Latest checkpoint's NextXID: %u:%u\n"), - ControlFile->checkPointCopy.nextXidEpoch, - ControlFile->checkPointCopy.nextXid); + EpochFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid), + XidFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid)); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile->checkPointCopy.nextOid); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), @@ -298,6 +298,8 @@ main(int argc, char *argv[]) ControlFile->MaxConnections); printf(_("max_worker_processes setting: %d\n"), ControlFile->max_worker_processes); + printf(_("max_wal_senders setting: %d\n"), + ControlFile->max_wal_senders); printf(_("max_prepared_xacts setting: %d\n"), ControlFile->max_prepared_xacts); printf(_("max_locks_per_xact setting: %d\n"), diff --git a/src/bin/pg_controldata/po/cs.po b/src/bin/pg_controldata/po/cs.po index b535ad98214..8c2c69c80b3 100644 --- a/src/bin/pg_controldata/po/cs.po +++ b/src/bin/pg_controldata/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_controldata-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-09-23 20:20+0000\n" -"PO-Revision-Date: 2013-09-24 20:38+0200\n" +"POT-Creation-Date: 2018-07-13 19:47+0000\n" +"PO-Revision-Date: 2018-07-14 17:04+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,7 +16,44 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" + +#: ../../common/controldata_utils.c:62 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: nelze otevřít soubor \"%s\" pro Ätení: %s\n" + +#: ../../common/controldata_utils.c:78 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: nelze Äíst soubor \"%s\": %s\n" + +#: ../../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: nelze Äíst soubor \"%s\": naÄteno %d z %d\n" + +#: ../../common/controldata_utils.c:112 +msgid "byte ordering mismatch" +msgstr "poÅ™adí bytů nesouhlasí" + +#: ../../common/controldata_utils.c:114 +#, c-format +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the " +"one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data " +"directory.\n" +msgstr "" +"VAROVÃNÃ: možný nesoulad v poÅ™adí bytů\n" +"PoÅ™adí bytů používané pro uložení pg_control souboru nemusí odpovídat " +"tomu\n" +"používanému tímto programem. V tom případÄ› by výsledky uvedené níže byly " +"chybné, a\n" +"PostgreSQL instalace by byla nekompatibilní s tímto datovým adresářem.\n" #: pg_controldata.c:34 #, c-format @@ -24,7 +61,7 @@ msgid "" "%s displays control information of a PostgreSQL database cluster.\n" "\n" msgstr "" -"%s ukáže kontrolní informace o PostgreSQL databázi.\n" +"%s vypíše kontrolní informace o PostgreSQL databázi.\n" "\n" #: pg_controldata.c:35 @@ -35,7 +72,7 @@ msgstr "Použití:\n" #: pg_controldata.c:36 #, c-format msgid " %s [OPTION] [DATADIR]\n" -msgstr " %s [VOLBY] [DATOVÃADRESÃŘ]\n" +msgstr " %s [VOLBY] [DATOVÃ-ADRESÃŘ]\n" #: pg_controldata.c:37 #, c-format @@ -48,16 +85,21 @@ msgstr "" #: pg_controldata.c:38 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version vypíše informaci o verzi, pak skonÄí\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR datový adresář\n" #: pg_controldata.c:39 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ukáže tuto nápovÄ›du, a skonÄí\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version vypiÅ¡ informaci o verzi, potom skonÄi\n" #: pg_controldata.c:40 #, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help vypiÅ¡ tuto nápovÄ›du, potom skonÄi\n" + +#: pg_controldata.c:41 +#, c-format msgid "" "\n" "If no data directory (DATADIR) is specified, the environment variable " @@ -70,347 +112,392 @@ msgstr "" "PGDATA.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:43 #, c-format msgid "Report bugs to .\n" msgstr "Oznámení o chybách zasílejte na .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:53 msgid "starting up" msgstr "startování" -#: pg_controldata.c:54 +#: pg_controldata.c:55 msgid "shut down" msgstr "ukonÄení" -#: pg_controldata.c:56 +#: pg_controldata.c:57 msgid "shut down in recovery" msgstr "ukonÄení (shut down) bÄ›hem obnovy" -#: pg_controldata.c:58 +#: pg_controldata.c:59 msgid "shutting down" msgstr "ukonÄování" -#: pg_controldata.c:60 +#: pg_controldata.c:61 msgid "in crash recovery" msgstr "probíhá zotavení z pádu" -#: pg_controldata.c:62 +#: pg_controldata.c:63 msgid "in archive recovery" msgstr "probíhá obnova z archivu" -#: pg_controldata.c:64 +#: pg_controldata.c:65 msgid "in production" msgstr "v provozu" -#: pg_controldata.c:66 +#: pg_controldata.c:67 msgid "unrecognized status code" msgstr "neznámý stavový kód" -#: pg_controldata.c:81 +#: pg_controldata.c:82 msgid "unrecognized wal_level" msgstr "neznámý wal_level" -#: pg_controldata.c:126 -#, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: není specifikován datový adresář\n" - -#: pg_controldata.c:127 +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_controldata.c:135 +#: pg_controldata.c:152 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: nelze otevřít soubor \"%s\" pro Ätení: %s\n" +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: příliÅ¡ mnoho argumentů v příkazové řádce (první je \"%s\")\n" -#: pg_controldata.c:142 +#: pg_controldata.c:161 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: nelze Äíst soubor \"%s\": %s\n" +msgid "%s: no data directory specified\n" +msgstr "%s: není specifikován datový adresář\n" -#: pg_controldata.c:156 +#: pg_controldata.c:169 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" -"Either the file is corrupt, or it has a different layout than this program\n" +"Either the file is corrupt, or it has a different layout than this " +"program\n" "is expecting. The results below are untrustworthy.\n" "\n" msgstr "" -"UPOZORNÄšNÃ: SpoÄítaný CRC kontrolní souÄet nesouhlasí s hodnotou uloženou\n" -"v souboru. BuÄ je soubor poÅ¡kozen nebo má jinou strukturu než tento program\n" +"UPOZORNÄšNÃ: SpoÄítaný CRC kontrolní souÄet nesouhlasí s hodnotou " +"uloženou\n" +"v souboru. BuÄ je soubor poÅ¡kozen nebo má jinou strukturu než tento " +"program\n" "oÄekává. Níže uvedené výsledky jsou nedůvÄ›ryhodné.\n" "\n" -#: pg_controldata.c:190 +#: pg_controldata.c:178 #, c-format -msgid "pg_control version number: %u\n" -msgstr "Äíslo verze pg_controlu: %u\n" +msgid "WARNING: invalid WAL segment size\n" +msgstr "WARNING: neplatná velikost WAL segmentu\n" -#: pg_controldata.c:193 +#: pg_controldata.c:179 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" -"The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, " -"and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" -msgstr "" -"VAROVÃNÃ: možný nesoulad v poÅ™adí bytů\n" -"PoÅ™adí bytů používané pro uložení pg_control souboru nemusí odpovídat tomu\n" -"používanému tímto programem. V tom případÄ› by výsledky uvedené níže byly " -"chybné, a\n" -"PostgreSQL instalace by byla nekompatibilní s tímto datovým adresářem.\n" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Velikost WAL segmentu uloženého v souboru, %d byte, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poÅ¡kozený a výsledky uvedené níže jsou\n" +"nedůvÄ›ryhodné.\n" +"\n" +msgstr[1] "" +"Velikost WAL segmentu uloženého v souboru, %d bytů, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poÅ¡kozený a výsledky uvedené níže jsou\n" +"nedůvÄ›ryhodné.\n" +"\n" +msgstr[2] "" +"Velikost WAL segmentu uloženého v souboru, %d bytů, není mocnina dvou\n" +"mezi 1 MB a 1 GB. Soubor je poÅ¡kozený a výsledky uvedené níže jsou\n" +"nedůvÄ›ryhodné.\n" +"\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "Číslo verze pg_controlu: %u\n" -#: pg_controldata.c:197 +#: pg_controldata.c:236 #, c-format msgid "Catalog version number: %u\n" -msgstr "Číslo verze katalogu: %u\n" +msgstr "Číslo verze katalogu: %u\n" -#: pg_controldata.c:199 +#: pg_controldata.c:238 #, c-format msgid "Database system identifier: %s\n" -msgstr "Identifikátor databázového systému: %s\n" +msgstr "Identifikátor databázového systému: %s\n" -#: pg_controldata.c:201 +#: pg_controldata.c:240 #, c-format msgid "Database cluster state: %s\n" -msgstr "Status databázového klastru: %s\n" +msgstr "Status databázového klastru: %s\n" -#: pg_controldata.c:203 +#: pg_controldata.c:242 #, c-format msgid "pg_control last modified: %s\n" -msgstr "poslední modifikace pg_control: %s\n" +msgstr "Poslední modifikace pg_control: %s\n" -#: pg_controldata.c:205 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint location: %X/%X\n" -msgstr "Poslední umístÄ›ní checkpointu: %X/%X\n" - -#: pg_controldata.c:208 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "PÅ™edeÅ¡lé umístÄ›ní checkpointu: %X/%X\n" +msgstr "Poslední umístÄ›ní checkpointu: %X/%X\n" -#: pg_controldata.c:211 +#: pg_controldata.c:247 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" -msgstr "Poslední umístÄ›ní REDO checkpointu: %X/%X\n" +msgstr "Poslední umístÄ›ní REDO checkpointu: %X/%X\n" -#: pg_controldata.c:214 +#: pg_controldata.c:250 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" -msgstr "REDO WAL file posledního checkpointu: %s\n" +msgstr "REDO WAL file posledního checkpointu: %s\n" -#: pg_controldata.c:216 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" -msgstr "TimeLineID posledního checkpointu: %u\n" +msgstr "TimeLineID posledního checkpointu: %u\n" -#: pg_controldata.c:218 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" -msgstr "PrevTimeLineID posledního checkpointu: %u\n" +msgstr "PrevTimeLineID posledního checkpointu: %u\n" -#: pg_controldata.c:220 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" -msgstr "Poslední full_page_writes checkpointu: %s\n" +msgstr "Poslední full_page_writes checkpointu: %s\n" -#: pg_controldata.c:221 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "off" msgstr "vypnuto" -#: pg_controldata.c:221 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "on" msgstr "zapnuto" -#: pg_controldata.c:222 +#: pg_controldata.c:258 #, c-format -msgid "Latest checkpoint's NextXID: %u/%u\n" -msgstr "Poslední umístÄ›ní NextXID checkpointu: %u/%u\n" +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID posledního checkpointu: %u:%u\n" -#: pg_controldata.c:225 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's NextOID: %u\n" -msgstr "Poslední umístÄ›ní NextOID checkpointu: %u\n" +msgstr "Poslední umístÄ›ní NextOID checkpointu: %u\n" -#: pg_controldata.c:227 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" -msgstr "NextMultiXactId posledního checkpointu: %u\n" +msgstr "NextMultiXactId posledního checkpointu: %u\n" -#: pg_controldata.c:229 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" -msgstr "NextMultiOffset posledního checkpointu: %u\n" +msgstr "NextMultiOffset posledního checkpointu: %u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID posledního checkpointu: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" -msgstr "DB k oldestXID posledního checkpointu: %u\n" +msgstr "DB k oldestXID posledního checkpointu: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" -msgstr "oldestActiveXID posledního checkpointu: %u\n" +msgstr "oldestActiveXID posledního checkpointu: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" -msgstr "oldestMultiXid posledního checkpointu: %u\n" +msgstr "oldestMultiXid posledního checkpointu: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" -msgstr "oldestMulti's DB posledního checkpointu: %u\n" +msgstr "DB k oldestMulti posledního checkpointu: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:277 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "oldestCommitTsXid posledního checkpointu: %u\n" + +#: pg_controldata.c:279 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "newestCommitTsXid posledního checkpointu: %u\n" + +#: pg_controldata.c:281 #, c-format msgid "Time of latest checkpoint: %s\n" -msgstr "ÄŒas posledního checkpointu: %s\n" +msgstr "ÄŒas posledního checkpointu: %s\n" -#: pg_controldata.c:243 +#: pg_controldata.c:283 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" -msgstr "FaleÅ¡né LSN poÄítadlo pro unlogged relace: %X/%X\n" +msgstr "FaleÅ¡né LSN poÄítadlo pro unlogged relace: %X/%X\n" -#: pg_controldata.c:246 +#: pg_controldata.c:286 #, c-format msgid "Minimum recovery ending location: %X/%X\n" -msgstr "Minimální pozice ukonÄení obnovy: %X/%X\n" +msgstr "Minimální pozice ukonÄení obnovy: %X/%X\n" -#: pg_controldata.c:249 +#: pg_controldata.c:289 #, c-format msgid "Min recovery ending loc's timeline: %u\n" -msgstr "Timeline minimální pozice ukonÄení obnovy: %u\n" +msgstr "Timeline minimální pozice ukonÄení obnovy: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:291 #, c-format msgid "Backup start location: %X/%X\n" -msgstr "Pozice poÄátku backupu: %X/%X\n" +msgstr "Pozice poÄátku backupu: %X/%X\n" -#: pg_controldata.c:254 +#: pg_controldata.c:294 #, c-format msgid "Backup end location: %X/%X\n" -msgstr "Koncová pozice zálohy: %X/%X\n" +msgstr "Koncová pozice zálohy: %X/%X\n" -#: pg_controldata.c:257 +#: pg_controldata.c:297 #, c-format msgid "End-of-backup record required: %s\n" -msgstr "Vyžadován záznam konce backupu: %s\n" +msgstr "Vyžadován záznam konce backupu: %s\n" -#: pg_controldata.c:258 +#: pg_controldata.c:298 msgid "no" msgstr "ne" -#: pg_controldata.c:258 +#: pg_controldata.c:298 msgid "yes" msgstr "ano" -#: pg_controldata.c:259 +#: pg_controldata.c:299 #, c-format -msgid "Current wal_level setting: %s\n" -msgstr "Aktuální nastavení wal_level: %s\n" +msgid "wal_level setting: %s\n" +msgstr "wal_level hodnota: %s\n" -#: pg_controldata.c:261 +#: pg_controldata.c:301 #, c-format -msgid "Current max_connections setting: %d\n" -msgstr "Aktuální nastavení max_connections: %d\n" +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hints hodnota: %s\n" -#: pg_controldata.c:263 +#: pg_controldata.c:303 #, c-format -msgid "Current max_prepared_xacts setting: %d\n" -msgstr "Aktuální nastavení max_prepared_xacts: %d\n" +msgid "max_connections setting: %d\n" +msgstr "max_connections hodnota: %d\n" -#: pg_controldata.c:265 +#: pg_controldata.c:305 #, c-format -msgid "Current max_locks_per_xact setting: %d\n" -msgstr "Aktuální nastavení max_locks_per_xact: %d\n" +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processes hodnota: %d\n" -#: pg_controldata.c:267 +#: pg_controldata.c:307 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xacts hodnota: %d\n" + +#: pg_controldata.c:309 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xact hodnota: %d\n" + +#: pg_controldata.c:311 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestamp hodnota: %s\n" + +#: pg_controldata.c:313 #, c-format msgid "Maximum data alignment: %u\n" -msgstr "Maximální zarovnání dat: %u\n" +msgstr "Maximální zarovnání dat: %u\n" -#: pg_controldata.c:270 +#: pg_controldata.c:316 #, c-format msgid "Database block size: %u\n" -msgstr "Velikost databázového bloku: %u\n" +msgstr "Velikost databázového bloku: %u\n" -#: pg_controldata.c:272 +#: pg_controldata.c:318 #, c-format msgid "Blocks per segment of large relation: %u\n" -msgstr "Bloků v segmentu velké relace: %u\n" +msgstr "Bloků v segmentu velké relace: %u\n" -#: pg_controldata.c:274 +#: pg_controldata.c:320 #, c-format msgid "WAL block size: %u\n" -msgstr "Velikost WAL bloku: %u\n" +msgstr "Velikost WAL bloku: %u\n" -#: pg_controldata.c:276 +#: pg_controldata.c:322 #, c-format msgid "Bytes per WAL segment: %u\n" -msgstr "Bytů ve WAL segmentu: %u\n" +msgstr "Bytů ve WAL segmentu: %u\n" -#: pg_controldata.c:278 +#: pg_controldata.c:324 #, c-format msgid "Maximum length of identifiers: %u\n" -msgstr "Maximální délka identifikátorů: %u\n" +msgstr "Maximální délka identifikátorů: %u\n" -#: pg_controldata.c:280 +#: pg_controldata.c:326 #, c-format msgid "Maximum columns in an index: %u\n" -msgstr "Maximální poÄet sloupců v indexu: %u\n" +msgstr "Maximální poÄet sloupců v indexu: %u\n" -#: pg_controldata.c:282 +#: pg_controldata.c:328 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" -msgstr "Maximální velikost úseku TOAST: %u\n" +msgstr "Maximální velikost úseku TOAST: %u\n" + +#: pg_controldata.c:330 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Velikost large-object chunku: %u\n" -#: pg_controldata.c:284 +#: pg_controldata.c:333 #, c-format msgid "Date/time type storage: %s\n" -msgstr "Způsob uložení typu date/time: %s\n" +msgstr "Způsob uložení typu date/time: %s\n" -#: pg_controldata.c:285 +#: pg_controldata.c:334 msgid "64-bit integers" msgstr "64-bitová Äísla" -#: pg_controldata.c:285 -msgid "floating-point numbers" -msgstr "Äísla s plovoucí řádovou Äárkou" - -#: pg_controldata.c:286 +#: pg_controldata.c:335 #, c-format msgid "Float4 argument passing: %s\n" -msgstr "Způsob pÅ™edávání float4 hodnot: %s\n" +msgstr "Způsob pÅ™edávání float4 hodnot: %s\n" -#: pg_controldata.c:287 pg_controldata.c:289 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by reference" msgstr "odkazem" -#: pg_controldata.c:287 pg_controldata.c:289 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by value" msgstr "hodnotou" -#: pg_controldata.c:288 +#: pg_controldata.c:337 #, c-format msgid "Float8 argument passing: %s\n" -msgstr "Způsob pÅ™edávání float8 hodnot: %s\n" +msgstr "Způsob pÅ™edávání float8 hodnot: %s\n" -#: pg_controldata.c:290 +#: pg_controldata.c:339 #, c-format -#| msgid "Catalog version number: %u\n" msgid "Data page checksum version: %u\n" -msgstr "Verze kontrolních souÄtů datových stránek: %u\n" +msgstr "Verze kontrolních souÄtů datových stránek: %u\n" + +#: pg_controldata.c:341 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "ZkuÅ¡ební authentizaÄní nonce: %s\n" #~ msgid "" #~ "Usage:\n" @@ -426,3 +513,12 @@ msgstr "Verze kontrolních souÄtů datových stránek: %u\n" #~ "PÅ™epínaÄe:\n" #~ " --help ukáže tuto nápovÄ›du a skonÄí\n" #~ " --version ukáže verzi tohoto programu a skonÄí\n" + +#~ msgid "floating-point numbers" +#~ msgstr "Äísla s plovoucí řádovou Äárkou" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ukáže tuto nápovÄ›du, a skonÄí\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version vypíše informaci o verzi, pak skonÄí\n" diff --git a/src/bin/pg_controldata/po/de.po b/src/bin/pg_controldata/po/de.po index a5a55bb3d86..ccf21858ef4 100644 --- a/src/bin/pg_controldata/po/de.po +++ b/src/bin/pg_controldata/po/de.po @@ -1,50 +1,76 @@ # German message translation file for pg_controldata -# Peter Eisentraut , 2002 - 2017. +# Peter Eisentraut , 2002 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 21:46+0000\n" -"PO-Revision-Date: 2017-08-04 18:16-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-13 17:47+0000\n" +"PO-Revision-Date: 2019-05-13 22:26+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:73 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: konnte Datei »%s« nicht zum Lesen öffnen: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:89 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht lesen: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" + +#: ../../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "falsche Byte-Reihenfolge" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:137 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" +"possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" "used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" +"the PostgreSQL installation would be incompatible with this data directory." msgstr "" -"WARNUNG: möglicherweise falsche Byte-Reihenfolge\n" +"möglicherweise falsche Byte-Reihenfolge\n" "Die Byte-Reihenfolge, die zur Speicherung der Datei pg_control verwendet wurde,\n" "stimmt möglicherweise nicht mit der von diesem Programm verwendeten überein. In\n" "diesem Fall wären die Ergebnisse unten falsch und die PostgreSQL-Installation\n" -"wäre inkompatibel mit diesem Datenverzeichnis.\n" +"wäre inkompatibel mit diesem Datenverzeichnis." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "konnte Datei »%s« nicht fsyncen: %m" -#: pg_controldata.c:33 +#: pg_controldata.c:36 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -53,17 +79,17 @@ msgstr "" "%s zeigt Kontrollinformationen über einen PostgreSQL-Datenbankcluster.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:37 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:38 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [OPTION] [DATENVERZEICHNIS]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:39 #, c-format msgid "" "\n" @@ -72,22 +98,22 @@ msgstr "" "\n" "Optionen:\n" -#: pg_controldata.c:37 +#: pg_controldata.c:40 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATENVERZ Datenbankverzeichnis\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]VERZ Datenbankverzeichnis\n" -#: pg_controldata.c:38 +#: pg_controldata.c:41 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_controldata.c:39 +#: pg_controldata.c:42 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_controldata.c:40 +#: pg_controldata.c:43 #, c-format msgid "" "\n" @@ -100,63 +126,63 @@ msgstr "" "PGDATA verwendet.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:45 #, c-format -msgid "Report bugs to .\n" -msgstr "Berichten Sie Fehler an .\n" +msgid "Report bugs to .\n" +msgstr "Berichten Sie Fehler an .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:55 msgid "starting up" msgstr "startet" -#: pg_controldata.c:54 +#: pg_controldata.c:57 msgid "shut down" msgstr "heruntergefahren" -#: pg_controldata.c:56 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "in der Wiederherstellung heruntergefahren" -#: pg_controldata.c:58 +#: pg_controldata.c:61 msgid "shutting down" msgstr "fährt herunter" -#: pg_controldata.c:60 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "bei der Wiederherstellung nach Absturz" -#: pg_controldata.c:62 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "bei der Archivwiederherstellung" -#: pg_controldata.c:64 +#: pg_controldata.c:67 msgid "in production" msgstr "im Produktionsmodus" -#: pg_controldata.c:66 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "nicht erkannter Statuscode" -#: pg_controldata.c:81 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "unbekanntes wal_level" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:138 pg_controldata.c:156 pg_controldata.c:164 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_controldata.c:146 +#: pg_controldata.c:154 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: pg_controldata.c:155 +#: pg_controldata.c:163 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: kein Datenverzeichnis angegeben\n" +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" -#: pg_controldata.c:163 +#: pg_controldata.c:171 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -170,285 +196,317 @@ msgstr "" "verlässlich.\n" "\n" -#: pg_controldata.c:201 +#: pg_controldata.c:180 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "WARNUNG: ungültige WAL-Segmentgröße\n" + +#: pg_controldata.c:181 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Die in der Datei gespeicherte WAL-Segmentgröße, %d Byte, ist keine\n" +"Zweierpotenz zwischen 1 MB und 1 GB. Die Datei ist kaputt und die\n" +"Ergebnisse unten sind nicht verlässlich.\n" +"\n" +msgstr[1] "" +"Die in der Datei gespeicherte WAL-Segmentgröße, %d Bytes, ist keine\n" +"Zweierpotenz zwischen 1 MB und 1 GB. Die Datei ist kaputt und die\n" +"Ergebnisse unten sind nicht verlässlich.\n" +"\n" + +#: pg_controldata.c:223 +msgid "???" +msgstr "???" + +#: pg_controldata.c:236 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control-Versionsnummer: %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:238 #, c-format msgid "Catalog version number: %u\n" msgstr "Katalogversionsnummer: %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:240 #, c-format msgid "Database system identifier: %s\n" msgstr "Datenbanksystemidentifikation: %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:242 #, c-format msgid "Database cluster state: %s\n" msgstr "Datenbank-Cluster-Status: %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:244 #, c-format msgid "pg_control last modified: %s\n" msgstr "pg_control zuletzt geändert: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Position des letzten Checkpoints: %X/%X\n" -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Position des vorletzten Checkpoints: %X/%X\n" - -#: pg_controldata.c:217 +#: pg_controldata.c:249 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "REDO-Position des letzten Checkpoints: %X/%X\n" -#: pg_controldata.c:220 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "REDO-WAL-Datei des letzten Checkpoints: %s\n" -#: pg_controldata.c:222 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID des letzten Checkpoints: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "PrevTimeLineID des letzten Checkpoints: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes des letzten Checkpoints: %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "off" msgstr "aus" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "on" msgstr "an" -#: pg_controldata.c:228 +#: pg_controldata.c:260 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID des letzten Checkpoints: %u:%u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID des letzten Checkpoints: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId des letzten Checkpoints: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset des letzten Checkpoints: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB der oldestXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID des letzten Checkpoints: %u\n" -#: pg_controldata.c:243 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:245 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB des oldestMulti des letzten Checkpoints: %u\n" -#: pg_controldata.c:247 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:249 +#: pg_controldata.c:281 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:283 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Zeit des letzten Checkpoints: %s\n" -#: pg_controldata.c:253 +#: pg_controldata.c:285 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Fake-LSN-Zähler für ungeloggte Relationen: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:288 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Minimaler Wiederherstellungsendpunkt: %X/%X\n" -#: pg_controldata.c:259 +#: pg_controldata.c:291 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Zeitleiste des minimalen Wiederherstellungsendpunkts: %u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:293 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Backup-Startpunkt: %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:296 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Backup-Endpunkt: %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:299 #, c-format msgid "End-of-backup record required: %s\n" msgstr "End-of-Backup-Eintrag erforderlich: %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "no" msgstr "nein" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "yes" msgstr "ja" -#: pg_controldata.c:269 +#: pg_controldata.c:301 #, c-format msgid "wal_level setting: %s\n" msgstr "wal_level-Einstellung: %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:303 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "wal_log_hints-Einstellung: %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:305 #, c-format msgid "max_connections setting: %d\n" msgstr "max_connections-Einstellung: %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:307 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "max_worker_processes-Einstellung: %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:309 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "max_wal_senders-Einstellung: %d\n" + +#: pg_controldata.c:311 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "max_prepared_xacts-Einstellung: %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:313 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "max_locks_per_xact-Einstellung: %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:315 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "track_commit_timestamp-Einstellung: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:317 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximale Datenausrichtung (Alignment): %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:320 #, c-format msgid "Database block size: %u\n" msgstr "Datenbankblockgröße: %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:322 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blöcke pro Segment: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:324 #, c-format msgid "WAL block size: %u\n" msgstr "WAL-Blockgröße: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:326 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes pro WAL-Segment: %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:328 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximale Bezeichnerlänge: %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:330 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximale Spalten in einem Index: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:332 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximale Größe eines Stücks TOAST: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:334 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Größe eines Large-Object-Chunks: %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:337 #, c-format msgid "Date/time type storage: %s\n" msgstr "Speicherung von Datum/Zeit-Typen: %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:338 msgid "64-bit integers" msgstr "64-Bit-Ganzzahlen" -#: pg_controldata.c:305 +#: pg_controldata.c:339 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Übergabe von Float4-Argumenten: %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by reference" msgstr "Referenz" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by value" msgstr "Wert" -#: pg_controldata.c:307 +#: pg_controldata.c:341 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Übergabe von Float8-Argumenten: %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:343 #, c-format msgid "Data page checksum version: %u\n" msgstr "Datenseitenprüfsummenversion: %u\n" -#: pg_controldata.c:311 +#: pg_controldata.c:345 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Mock-Authentifizierungs-Nonce: %s\n" diff --git a/src/bin/pg_controldata/po/es.po b/src/bin/pg_controldata/po/es.po index 945b5aadca7..c40dc2da557 100644 --- a/src/bin/pg_controldata/po/es.po +++ b/src/bin/pg_controldata/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for pg_controldata # -# Copyright (C) 2002-2013 PostgreSQL Global Development Group +# Copyright (c) 2002-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Karim Mribti , 2002. @@ -9,47 +9,73 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_controldata (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-10 12:13-0400\n" +"Project-Id-Version: pg_controldata (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:15+0000\n" +"PO-Revision-Date: 2019-06-06 17:23-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: Castellano \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:73 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: no se pudo abrir el archivo «%s» para lectura: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:89 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: no se pudo leer el archivo «%s»: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "discordancia en orden de bytes" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:137 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" +"possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" "used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" +"the PostgreSQL installation would be incompatible with this data directory." msgstr "" -"ATENCIÓN: posible discordancia en orden de bytes\n" -"El orden de bytes usado para almacenar el archivo pg_control puede no\n" -"coincidir con el que usa este programa. En tal caso, los resultados de abajo\n" -"serán incorrectos, y esta instalación de PostgreSQL será incompatible con\n" -"este directorio de datos.\n" +"posible discordancia en orden de bytes\n" +"El ordenamiento de bytes usado para almacenar el archivo pg_control puede no\n" +"coincidir con el usado por este programa. En tal caso los resultados de abajo\n" +"serían erróneos, y la instalación de PostgreSQL sería incompatible con este\n" +"directorio de datos." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m" -#: pg_controldata.c:33 +#: pg_controldata.c:36 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -58,17 +84,17 @@ msgstr "" "%s muestra información de control del cluster de PostgreSQL.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:37 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:38 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [OPCIÓN] [DATADIR]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:39 #, c-format msgid "" "\n" @@ -77,22 +103,22 @@ msgstr "" "\n" "Opciones:\n" -#: pg_controldata.c:37 +#: pg_controldata.c:40 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR directorio de datos\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" -#: pg_controldata.c:38 +#: pg_controldata.c:41 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version muestra información de la versión, luego sale\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión, luego salir\n" -#: pg_controldata.c:39 +#: pg_controldata.c:42 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help muestra esta ayuda, luego sale\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda, luego salir\n" -#: pg_controldata.c:40 +#: pg_controldata.c:43 #, c-format msgid "" "\n" @@ -105,63 +131,63 @@ msgstr "" "la variable de entorno PGDATA.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:45 #, c-format -msgid "Report bugs to .\n" -msgstr "Reporte errores a .\n" +msgid "Report bugs to .\n" +msgstr "Reporte errores a .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:55 msgid "starting up" msgstr "iniciando" -#: pg_controldata.c:54 +#: pg_controldata.c:57 msgid "shut down" msgstr "apagado" -#: pg_controldata.c:56 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "apagado durante recuperación" -#: pg_controldata.c:58 +#: pg_controldata.c:61 msgid "shutting down" msgstr "apagándose" -#: pg_controldata.c:60 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "en recuperación" -#: pg_controldata.c:62 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "en recuperación desde archivo" -#: pg_controldata.c:64 +#: pg_controldata.c:67 msgid "in production" msgstr "en producción" -#: pg_controldata.c:66 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "código de estado no reconocido" -#: pg_controldata.c:81 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "wal_level no reconocido" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:138 pg_controldata.c:156 pg_controldata.c:164 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Intente «%s --help» para mayor información.\n" -#: pg_controldata.c:146 +#: pg_controldata.c:154 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_controldata.c:155 +#: pg_controldata.c:163 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: no se ha especificado un directorio de datos\n" +msgid "no data directory specified" +msgstr "no se especificó el directorio de datos" -#: pg_controldata.c:163 +#: pg_controldata.c:171 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -175,291 +201,315 @@ msgstr "" "esperando. Los resultados presentados a continuación no son confiables.\n" "\n" -#: pg_controldata.c:201 +#: pg_controldata.c:180 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "PRECAUCIÓN: tamaño de segmento de WAL no válido\n" + +#: pg_controldata.c:181 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"El tamaño de segmento de WAL almacenado en el archivo, %d byte,\n" +"no es una potencia de dos entre 1 MB y 1 GB. El archivo está corrupto y los\n" +"resultados de abajo no son confiables.\n" +msgstr[1] "" +"El tamaño de segmento de WAL almacenado en el archivo, %d bytes,\n" +"no es una potencia de dos entre 1 MB y 1 GB. El archivo está corrupto y los\n" +"resultados de abajo no son confiables.\n" + +#: pg_controldata.c:223 +msgid "???" +msgstr "???" + +#: pg_controldata.c:236 #, c-format msgid "pg_control version number: %u\n" msgstr "Número de versión de pg_control: %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:238 #, c-format msgid "Catalog version number: %u\n" msgstr "Número de versión del catálogo: %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:240 #, c-format msgid "Database system identifier: %s\n" msgstr "Identificador de sistema: %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:242 #, c-format msgid "Database cluster state: %s\n" msgstr "Estado del sistema de base de datos: %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:244 #, c-format msgid "pg_control last modified: %s\n" msgstr "Última modificación de pg_control: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Ubicación del último checkpoint: %X/%X\n" -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Ubicación del checkpoint anterior: %X/%X\n" - -#: pg_controldata.c:217 +#: pg_controldata.c:249 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "Ubicación de REDO de último checkpoint: %X/%X\n" -#: pg_controldata.c:220 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "Ubicación de REDO de último checkpoint: %s\n" -#: pg_controldata.c:222 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID del último checkpoint: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "PrevTimeLineID del último checkpoint: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes del último checkpoint: %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "off" msgstr "desactivado" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "on" msgstr "activado" -#: pg_controldata.c:228 +#: pg_controldata.c:260 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID de último checkpoint: %u/%u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID de último checkpoint: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId de último checkpoint: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset de último checkpoint: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID del último checkpoint: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB del oldestXID del último checkpoint: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID del último checkpoint: %u\n" -#: pg_controldata.c:243 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid del último checkpoint: %u\n" -#: pg_controldata.c:245 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB del oldestMultiXid del últ. checkpoint: %u\n" -#: pg_controldata.c:247 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid del último checkpoint: %u\n" -#: pg_controldata.c:249 +#: pg_controldata.c:281 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid del último checkpoint: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:283 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Instante de último checkpoint: %s\n" -#: pg_controldata.c:253 +#: pg_controldata.c:285 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Contador de LSN falsas para rels. unlogged: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:288 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Punto final mínimo de recuperación: %X/%X\n" -#: pg_controldata.c:259 +#: pg_controldata.c:291 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Timeline de dicho punto final mínimo: %u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:293 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Ubicación del inicio de backup: %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:296 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Ubicación del fin de backup: %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:299 #, c-format msgid "End-of-backup record required: %s\n" msgstr "Registro fin-de-backup requerido: %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "no" msgstr "no" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "yes" msgstr "sí" -#: pg_controldata.c:269 +#: pg_controldata.c:301 #, c-format msgid "wal_level setting: %s\n" msgstr "Parámetro wal_level: %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:303 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "Parámetro wal_log_hings: %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:305 #, c-format msgid "max_connections setting: %d\n" msgstr "Parámetro max_connections: %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:307 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "Parámetro max_worker_processes: %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:309 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "Parámetro max_wal_senders: %d\n" + +#: pg_controldata.c:311 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "Parámetro max_prepared_xacts: %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:313 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "Parámetro max_locks_per_xact: %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:315 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "Parámetro track_commit_timestamp: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:317 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Alineamiento máximo de datos: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:320 #, c-format msgid "Database block size: %u\n" msgstr "Tamaño de bloque de la base de datos: %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:322 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Bloques por segmento en relación grande: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:324 #, c-format msgid "WAL block size: %u\n" msgstr "Tamaño del bloque de WAL: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:326 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes por segmento WAL: %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:328 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Máxima longitud de identificadores: %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:330 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Máximo número de columnas de un índice: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:332 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Longitud máxima de un trozo TOAST: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:334 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Longitud máx. de un trozo de objeto grande: %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:337 #, c-format msgid "Date/time type storage: %s\n" msgstr "Tipo de almacenamiento de horas y fechas: %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:338 msgid "64-bit integers" msgstr "enteros de 64 bits" -#: pg_controldata.c:305 +#: pg_controldata.c:339 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Paso de parámetros float4: %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by reference" msgstr "por referencia" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by value" msgstr "por valor" -#: pg_controldata.c:307 +#: pg_controldata.c:341 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Paso de parámetros float8: %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:343 #, c-format msgid "Data page checksum version: %u\n" msgstr "Versión de sumas de verificación de datos: %u\n" -#: pg_controldata.c:311 +#: pg_controldata.c:345 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Nonce para autentificación simulada: %s\n" - -#~ msgid "calculated CRC checksum does not match value stored in file" -#~ msgstr "la suma de verificación calculada no coincide con el valor almacenado en el archivo" - -#~ msgid "floating-point numbers" -#~ msgstr "números de punto flotante" diff --git a/src/bin/pg_controldata/po/fr.po b/src/bin/pg_controldata/po/fr.po index f0729688439..4ac78c15707 100644 --- a/src/bin/pg_controldata/po/fr.po +++ b/src/bin/pg_controldata/po/fr.po @@ -8,47 +8,74 @@ # Stéphane Schildknecht , 2009. msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-06 14:46+0000\n" -"PO-Revision-Date: 2017-07-06 18:24+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:18+0000\n" +"PO-Revision-Date: 2019-05-17 15:31+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:73 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %m" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:89 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s : n'a pas pu lire le fichier « %s » : %s\n" +msgid "could not read file \"%s\": %m" +msgstr "n'a pas pu lire le fichier « %s » : %m" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "n'a pas pu fermer le fichier « %s » : %m" + +#: ../../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "différence de l'ordre des octets" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:137 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" +"possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data directory." msgstr "" "ATTENTION : possible incohérence dans l'ordre des octets\n" "L'ordre des octets utilisé pour enregistrer le fichier pg_control peut ne\n" "pas correspondre à celui utilisé par ce programme. Dans ce cas, les\n" -"résultats ci-dessous sont incorrects, et l'installation PostgreSQL\n" -"incompatible avec ce répertoire des données.\n" +"résultats ci-dessous sont incorrects, et l'installation de PostgreSQL\n" +"est incompatible avec ce répertoire des données." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "n'a pas pu ouvrir le fichier « %s » : %m" -#: pg_controldata.c:33 +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "impossible d'écrire le fichier « %s » : %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m" + +#: pg_controldata.c:36 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -58,17 +85,17 @@ msgstr "" "PostgreSQL.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:37 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: pg_controldata.c:35 +#: pg_controldata.c:38 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [OPTION] [RÉP_DONNÉES]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:39 #, c-format msgid "" "\n" @@ -77,26 +104,27 @@ msgstr "" "\n" "Options :\n" -#: pg_controldata.c:37 +#: pg_controldata.c:40 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] RÉPDONNEES répertoire de la base de données\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata] RÉPDONNEES répertoire de la base de données\n" -#: pg_controldata.c:38 +#: pg_controldata.c:41 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version affiche la version et quitte\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version affiche la version puis quitte\n" -#: pg_controldata.c:39 +#: pg_controldata.c:42 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help affiche cette aide et quitte\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help affiche cette aide puis quitte\n" -#: pg_controldata.c:40 +#: pg_controldata.c:43 #, c-format msgid "" "\n" -"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" "is used.\n" "\n" msgstr "" @@ -105,63 +133,63 @@ msgstr "" "d'environnement PGDATA est utilisée.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:45 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapporter les bogues à .\n" +msgid "Report bugs to .\n" +msgstr "Rapporter les bogues à .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:55 msgid "starting up" msgstr "démarrage en cours" -#: pg_controldata.c:54 +#: pg_controldata.c:57 msgid "shut down" msgstr "arrêt" -#: pg_controldata.c:56 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "arrêt pendant la restauration" -#: pg_controldata.c:58 +#: pg_controldata.c:61 msgid "shutting down" msgstr "arrêt en cours" -#: pg_controldata.c:60 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "restauration en cours (suite à un arrêt brutal)" -#: pg_controldata.c:62 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "restauration en cours (à partir des archives)" -#: pg_controldata.c:64 +#: pg_controldata.c:67 msgid "in production" msgstr "en production" -#: pg_controldata.c:66 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "code de statut inconnu" -#: pg_controldata.c:81 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "wal_level non reconnu" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:138 pg_controldata.c:156 pg_controldata.c:164 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayer « %s --help » pour plus d'informations.\n" -#: pg_controldata.c:146 +#: pg_controldata.c:154 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" -#: pg_controldata.c:155 +#: pg_controldata.c:163 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s : aucun répertoire de données indiqué\n" +msgid "no data directory specified" +msgstr "aucun répertoire de données indiqué" -#: pg_controldata.c:163 +#: pg_controldata.c:171 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -176,289 +204,330 @@ msgstr "" "Les résultats ci-dessous ne sont pas dignes de confiance.\n" "\n" -#: pg_controldata.c:201 +#: pg_controldata.c:180 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "ATTENTION : taille invalide du segment WAL\n" + +#: pg_controldata.c:181 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"La taille d'un segment WAL enregistré dans le fichier, %d octet, n'est pas " +"une puissance de deux entre 1 Mo et 1 Go. Le fichier est corrompu et les " +"résultats ci-dessous ne proviennent pas d'une source fiable.\n" +"\n" +msgstr[1] "" +"La taille d'un segment WAL enregistré dans le fichier, %d octets, n'est pas " +"une puissance de deux entre 1 Mo et 1 Go. Le fichier est corrompu et les " +"résultats ci-dessous ne proviennent pas d'une source fiable.\n" +"\n" + +#: pg_controldata.c:223 +msgid "???" +msgstr "???" + +#: pg_controldata.c:236 #, c-format msgid "pg_control version number: %u\n" msgstr "Numéro de version de pg_control : %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:238 #, c-format msgid "Catalog version number: %u\n" msgstr "Numéro de version du catalogue : %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:240 #, c-format msgid "Database system identifier: %s\n" msgstr "Identifiant du système de base de données : %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:242 #, c-format msgid "Database cluster state: %s\n" msgstr "État du cluster de base de données : %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:244 #, c-format msgid "pg_control last modified: %s\n" msgstr "Dernière modification de pg_control : %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Dernier point de contrôle : %X/%X\n" -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Point de contrôle précédent : %X/%X\n" - -#: pg_controldata.c:217 +#: pg_controldata.c:249 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "Dernier REDO (reprise) du point de contrôle : %X/%X\n" -#: pg_controldata.c:220 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "Dernier fichier WAL du rejeu du point de restauration : %s\n" -#: pg_controldata.c:222 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "Dernier TimeLineID du point de contrôle : %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "Dernier PrevTimeLineID du point de restauration : %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "Dernier full_page_writes du point de contrôle : %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "off" msgstr "désactivé" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "on" msgstr "activé" -#: pg_controldata.c:228 +#: pg_controldata.c:260 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "Dernier NextXID du point de contrôle : %u:%u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "Dernier NextOID du point de contrôle : %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "Dernier NextMultiXactId du point de contrôle : %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "Dernier NextMultiOffset du point de contrôle : %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "Dernier oldestXID du point de contrôle : %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "Dernier oldestXID du point de contrôle de la base : %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "Dernier oldestActiveXID du point de contrôle : %u\n" -#: pg_controldata.c:243 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "Dernier oldestMultiXid du point de restauration : %u\n" -#: pg_controldata.c:245 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "Dernier oldestMulti du point de restauration de base : %u\n" -#: pg_controldata.c:247 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "Dernier oldestCommitTsXid du point de restauration : %u\n" -#: pg_controldata.c:249 +#: pg_controldata.c:281 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "Dernier newestCommitTsXid du point de restauration : %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:283 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Heure du dernier point de contrôle : %s\n" -#: pg_controldata.c:253 +#: pg_controldata.c:285 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Faux compteur LSN pour les relations non journalisés : %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:288 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Emplacement de fin de la récupération minimale : %X/%X\n" -#: pg_controldata.c:259 +#: pg_controldata.c:291 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Timeline de l'emplacement de fin de restauration : %u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:293 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Début de la sauvegarde : %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:296 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Fin de la sauvegarde : %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:299 #, c-format msgid "End-of-backup record required: %s\n" msgstr "Enregistrement de fin de sauvegarde requis : %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "no" msgstr "non" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "yes" msgstr "oui" -#: pg_controldata.c:269 +#: pg_controldata.c:301 #, c-format msgid "wal_level setting: %s\n" msgstr "Paramètrage actuel de wal_level : %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:303 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "Paramétrage actuel de wal_log_hints : %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:305 #, c-format msgid "max_connections setting: %d\n" msgstr "Paramètrage actuel de max_connections : %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:307 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "Paramétrage actuel de max_worker_processes : %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:309 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "Paramètrage actuel de max_wal_senders : %d\n" + +#: pg_controldata.c:311 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "Paramètrage actuel de max_prepared_xacts : %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:313 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "Paramètrage actuel de max_locks_per_xact : %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:315 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "Paramètrage actuel de track_commit_timestamp : %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:317 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Alignement maximal des données : %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:320 #, c-format msgid "Database block size: %u\n" msgstr "Taille du bloc de la base de données : %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:322 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blocs par segment des relations volumineuses : %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:324 #, c-format msgid "WAL block size: %u\n" msgstr "Taille de bloc du journal de transaction : %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:326 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Octets par segment du journal de transaction : %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:328 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Longueur maximale des identifiants : %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:330 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Nombre maximum de colonnes d'un index: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:332 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Longueur maximale d'un morceau TOAST : %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:334 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Taille d'un morceau de Large Object : %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:337 #, c-format msgid "Date/time type storage: %s\n" msgstr "Stockage du type date/heure : %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:338 msgid "64-bit integers" msgstr "entiers 64-bits" -#: pg_controldata.c:305 +#: pg_controldata.c:339 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Passage d'argument float4 : %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by reference" msgstr "par référence" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by value" msgstr "par valeur" -#: pg_controldata.c:307 +#: pg_controldata.c:341 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Passage d'argument float8 : %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:343 #, c-format msgid "Data page checksum version: %u\n" msgstr "Version des sommes de contrôle des pages de données : %u\n" -#: pg_controldata.c:311 +#: pg_controldata.c:345 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Nonce pour simuler une identité: %s\n" +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version affiche la version et quitte\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help affiche cette aide et quitte\n" + +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "Point de contrôle précédent : %X/%X\n" + #~ msgid "" #~ "Usage:\n" #~ " %s [OPTION] [DATADIR]\n" @@ -478,4 +547,15 @@ msgstr "Nonce pour simuler une identité: %s\n" #~ msgstr "nombres à virgule flottante" #~ msgid "calculated CRC checksum does not match value stored in file" -#~ msgstr "la somme de contrôle CRC calculée ne correspond par à la valeur enregistrée dans le fichier" +#~ msgstr "" +#~ "la somme de contrôle CRC calculée ne correspond par à la valeur " +#~ "enregistrée dans le fichier" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "%s : n'a pas pu lire le fichier « %s » : a lu %d sur %d\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s : n'a pas pu lire le fichier « %s » : %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » en lecture : %s\n" diff --git a/src/bin/pg_controldata/po/it.po b/src/bin/pg_controldata/po/it.po index 18682251a08..e1697bb6689 100644 --- a/src/bin/pg_controldata/po/it.po +++ b/src/bin/pg_controldata/po/it.po @@ -1,55 +1,55 @@ # -# Translation of pg_controldata to Italian -# PostgreSQL Project +# pg_controldata.po +# Italian message translation file for pg_controldata # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Cosimo D'Arcangelo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Gabriele Bartolini -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017 +# Cosimo D'Arcangelo 2010 +# Mirko Tebaldi , 2004 # -# Traduttori precedenti: -# * Mirko Tebaldi , 2004. -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: pg_controldata (PostgreSQL) 10\n" +"Project-Id-Version: pg_controldata (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:47+0000\n" -"PO-Revision-Date: 2017-04-23 04:34+0100\n" +"POT-Creation-Date: 2018-10-08 14:16+0000\n" +"PO-Revision-Date: 2018-10-08 22:03+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: utf-8\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: apertura del file \"%s\" per la lettura fallita: %s\n" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: lettura del file \"%s\" fallita: %s\n" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: lettura del file \"%s\" fallita: letti %d di %d\n" + +#: ../../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "ordinamento dei byte non combaciante" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -63,7 +63,7 @@ msgstr "" "seguenti non sarebbero corretti e l'installazione di PostgreSQL sarebbe\n" "incompatibile con questa directory di dati.\n" -#: pg_controldata.c:33 +#: pg_controldata.c:34 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -72,17 +72,17 @@ msgstr "" "%s mostra informazioni di controllo su un cluster di database PostgreSQL.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:35 #, c-format msgid "Usage:\n" msgstr "Utilizzo:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:36 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [OPZIONE] [DATADIR]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:37 #, c-format msgid "" "\n" @@ -91,23 +91,23 @@ msgstr "" "\n" "Opzioni:\n" -#: pg_controldata.c:37 -#, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR directory dei dati\n" - #: pg_controldata.c:38 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version mostra informazioni sulla versione ed esci\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directory dei dati\n" #: pg_controldata.c:39 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help mostra questo aiuto ed esci\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostra informazioni sulla versione ed esci\n" #: pg_controldata.c:40 #, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostra questo aiuto ed esci\n" + +#: pg_controldata.c:41 +#, c-format msgid "" "\n" "If no data directory (DATADIR) is specified, the environment variable PGDATA\n" @@ -119,63 +119,63 @@ msgstr "" "variabile d'ambiente PGDATA.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:43 #, c-format msgid "Report bugs to .\n" msgstr "Puoi segnalare eventuali bug a .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:53 msgid "starting up" msgstr "avvio in corso" -#: pg_controldata.c:54 +#: pg_controldata.c:55 msgid "shut down" msgstr "spento" -#: pg_controldata.c:56 +#: pg_controldata.c:57 msgid "shut down in recovery" msgstr "arresto durante il ripristino" -#: pg_controldata.c:58 +#: pg_controldata.c:59 msgid "shutting down" msgstr "arresto in corso" -#: pg_controldata.c:60 +#: pg_controldata.c:61 msgid "in crash recovery" msgstr "in fase di recupero da un crash" -#: pg_controldata.c:62 +#: pg_controldata.c:63 msgid "in archive recovery" msgstr "in fase di recupero di un archivio" -#: pg_controldata.c:64 +#: pg_controldata.c:65 msgid "in production" msgstr "in produzione" -#: pg_controldata.c:66 +#: pg_controldata.c:67 msgid "unrecognized status code" msgstr "codice di stato sconosciuto" -#: pg_controldata.c:81 +#: pg_controldata.c:82 msgid "unrecognized wal_level" msgstr "wal_level sconosciuto" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: pg_controldata.c:146 +#: pg_controldata.c:152 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: troppi argomenti di riga di comando (il primo è \"%s\")\n" -#: pg_controldata.c:155 +#: pg_controldata.c:161 #, c-format msgid "%s: no data directory specified\n" msgstr "%s: non è stata specificata una directory per i dati\n" -#: pg_controldata.c:163 +#: pg_controldata.c:169 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -188,285 +188,312 @@ msgstr "" "questo programma si aspetta. I risultati seguenti non sono affidabili.\n" "\n" -#: pg_controldata.c:201 +#: pg_controldata.c:178 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "ATTENZIONE: dimensione del segmento WAL non valida\n" + +#: pg_controldata.c:179 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"La dimensione del segmento WAL memorizzata nel file, %d byte, non è una\n" +"potenza di 2 tra 1 MB e 1 GB. Il file è corrotto e i risultati\n" +"sottostanti non sono affidabili.\n" +"\n" +msgstr[1] "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 #, c-format msgid "pg_control version number: %u\n" msgstr "Numero di versione di pg_control: %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:236 #, c-format msgid "Catalog version number: %u\n" msgstr "Numero di versione del catalogo: %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:238 #, c-format msgid "Database system identifier: %s\n" msgstr "Identificatore di sistema del database: %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:240 #, c-format msgid "Database cluster state: %s\n" msgstr "Stato del cluster di database: %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:242 #, c-format msgid "pg_control last modified: %s\n" msgstr "Ultima modifica a pg_control: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Ultima posizione del checkpoint: %X/%X\n" -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Posizione precedente del checkpoint: %X/%X\n" - -#: pg_controldata.c:217 +#: pg_controldata.c:247 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "Locazione di REDO dell'ultimo checkpoint: %X/%X\n" -#: pg_controldata.c:220 +#: pg_controldata.c:250 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "File WAL di REDO dell'ultimo checkpoint: %s\n" -#: pg_controldata.c:222 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineId dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "PrevTimeLineID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes dell'ultimo checkpoint: %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "off" msgstr "disattivato" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "on" msgstr "attivato" -#: pg_controldata.c:228 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID dell'ultimo checkpoint: %u:%u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB dell'oldestXID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:243 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXID dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:245 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB dell'oldestMulti dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:247 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:249 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid dell'ultimo checkpoint: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:281 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Orario ultimo checkpoint: %s\n" -#: pg_controldata.c:253 +#: pg_controldata.c:283 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Falso contatore LSN per rel. non loggate: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:286 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Posizione del minimum recovery ending: %X/%X\n" -#: pg_controldata.c:259 +#: pg_controldata.c:289 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Timeline posiz. minimum recovery ending: %u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:291 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Posizione dell'inizio del backup: %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:294 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Posizione della fine del backup: %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:297 #, c-format msgid "End-of-backup record required: %s\n" msgstr "Record di fine backup richiesto: %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:298 msgid "no" msgstr "no" -#: pg_controldata.c:268 +#: pg_controldata.c:298 msgid "yes" msgstr "sì" -#: pg_controldata.c:269 +#: pg_controldata.c:299 #, c-format msgid "wal_level setting: %s\n" msgstr "Impostazione di wal_level: %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:301 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "Impostazione di wal_log_hints: %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:303 #, c-format msgid "max_connections setting: %d\n" msgstr "Impostazione di max_connections: %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:305 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "Impostazione di max_worker_processes: %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:307 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "Impostazione di max_prepared_xacts: %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:309 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "Impostazione di max_locks_per_xact: %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:311 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "Impostazione di track_commit_timestamp: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:313 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Massimo allineamento dei dati: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:316 #, c-format msgid "Database block size: %u\n" msgstr "Dimensione blocco database: %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:318 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blocchi per ogni segmento grosse tabelle: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:320 #, c-format msgid "WAL block size: %u\n" msgstr "Dimensione blocco WAL: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:322 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Byte per segmento WAL: %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:324 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Lunghezza massima degli identificatori: %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:326 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Massimo numero di colonne in un indice: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:328 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Massima dimensione di un segmento TOAST: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:330 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Dimensione di un blocco large-object: %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:333 #, c-format msgid "Date/time type storage: %s\n" msgstr "Memorizzazione per tipi data/ora: %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:334 msgid "64-bit integers" msgstr "interi a 64 bit" -#: pg_controldata.c:305 +#: pg_controldata.c:335 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Passaggio di argomenti Float4: %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by reference" msgstr "per riferimento" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by value" msgstr "per valore" -#: pg_controldata.c:307 +#: pg_controldata.c:337 #, c-format msgid "Float8 argument passing: %s\n" msgstr "passaggio di argomenti Float8: %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:339 #, c-format msgid "Data page checksum version: %u\n" msgstr "Versione somma di controllo dati pagine: %u\n" -#: pg_controldata.c:311 +#: pg_controldata.c:341 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Finto nonce di autenticazione: %s\n" diff --git a/src/bin/pg_controldata/po/ja.po b/src/bin/pg_controldata/po/ja.po index 9e3f33215d1..6250442530c 100644 --- a/src/bin/pg_controldata/po/ja.po +++ b/src/bin/pg_controldata/po/ja.po @@ -3,17 +3,50 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0 beta 3\n" +"Project-Id-Version: PostgreSQL 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 11:29+0900\n" -"PO-Revision-Date: 2013-08-18 11:36+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-08-31 16:21+0900\n" +"PO-Revision-Date: 2018-08-20 16:29+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../../common/controldata_utils.c:62 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: 読ã¿å–り用ã®\"%s\"ファイルã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: ../../common/controldata_utils.c:78 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: \"%s\"ファイルã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: ../../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%1$s: ファイル\"%2$s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %4$dãƒã‚¤ãƒˆã®ã†ã¡%3$dãƒã‚¤ãƒˆã‚’読ã¿è¾¼ã¿ã¾ã—ãŸ\n" + +#: ../../common/controldata_utils.c:112 +msgid "byte ordering mismatch" +msgstr "ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ã®ä¸æ•´åˆ" + +#: ../../common/controldata_utils.c:114 +#, c-format +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory.\n" +msgstr "" +"警告:ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒç•°ãªã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n" +"pg_controlファイルを格ç´ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒæœ¬ãƒ—ログラムã§ä½¿ç”¨\n" +"ã•れるもã®ã¨ç•°ãªã‚Šã¾ã™ã€‚ã“ã®å ´åˆä»¥ä¸‹ã®çµæžœã¯ä¸æ­£ç¢ºã«ãªã‚Šã¾ã™ã€‚ã¾ãŸã€PostgreSQL\n" +"インストレーションã¯ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨äº’æ›æ€§ãŒãªããªã‚Šã¾ã™ã€‚\n" #: pg_controldata.c:34 #, c-format @@ -45,16 +78,21 @@ msgstr "" #: pg_controldata.c:38 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR データディレクトリ\n" #: pg_controldata.c:39 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã—ã¾ã™\n" #: pg_controldata.c:40 #, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦çµ‚了ã—ã¾ã™\n" + +#: pg_controldata.c:41 +#, c-format msgid "" "\n" "If no data directory (DATADIR) is specified, the environment variable PGDATA\n" @@ -65,68 +103,63 @@ msgstr "" "データディレクトリ(DATADIR)ãŒæŒ‡å®šã•れãªã„å ´åˆã€PGDATA環境変数ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:43 #, c-format msgid "Report bugs to .\n" msgstr "ä¸å…·åˆã¯ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" -#: pg_controldata.c:52 +#: pg_controldata.c:53 msgid "starting up" msgstr "èµ·å‹•" -#: pg_controldata.c:54 +#: pg_controldata.c:55 msgid "shut down" msgstr "シャットダウン" -#: pg_controldata.c:56 +#: pg_controldata.c:57 msgid "shut down in recovery" -msgstr "リカãƒãƒªã—ãªãŒã‚‰ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ä¸­" +msgstr "リカãƒãƒªä¸­ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³" -#: pg_controldata.c:58 +#: pg_controldata.c:59 msgid "shutting down" msgstr "シャットダウン中" -#: pg_controldata.c:60 +#: pg_controldata.c:61 msgid "in crash recovery" msgstr "クラッシュリカãƒãƒªä¸­" -#: pg_controldata.c:62 +#: pg_controldata.c:63 msgid "in archive recovery" msgstr "アーカイブリカãƒãƒªä¸­" -#: pg_controldata.c:64 +#: pg_controldata.c:65 msgid "in production" msgstr "é‹ç”¨ä¸­" -#: pg_controldata.c:66 +#: pg_controldata.c:67 msgid "unrecognized status code" msgstr "未知ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚³ãƒ¼ãƒ‰" -#: pg_controldata.c:81 +#: pg_controldata.c:82 msgid "unrecognized wal_level" msgstr "wal_level ã‚’èªè­˜ã§ãã¾ã›ã‚“" -#: pg_controldata.c:126 -#, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" - -#: pg_controldata.c:127 +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "詳細ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„\n" -#: pg_controldata.c:135 +#: pg_controldata.c:152 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: 読ã¿å–り用ã®\"%s\"ファイルã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™ã€‚(å§‹ã‚ã¯\"%s\")\n" -#: pg_controldata.c:142 +#: pg_controldata.c:161 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: \"%s\"ファイルã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgid "%s: no data directory specified\n" +msgstr "%s: ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" -#: pg_controldata.c:156 +#: pg_controldata.c:169 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -139,294 +172,316 @@ msgstr "" "å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚以下ã®çµæžœã¯ä¿¡ç”¨ã§ãã¾ã›ã‚“。\n" "\n" -#: pg_controldata.c:190 +#: pg_controldata.c:178 #, c-format -msgid "pg_control version number: %u\n" -msgstr "pg_controlãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·: %u\n" +msgid "WARNING: invalid WAL segment size\n" +msgstr "警告: 䏿­£ãªWALセグメントサイズ\n" -#: pg_controldata.c:193 +#: pg_controldata.c:179 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" -"The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" -msgstr "" -"警告:ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒç•°ãªã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n" -"pg_controlファイルを格ç´ã™ã‚‹ãŸã‚ã«ä½¿ç”¨ã™ã‚‹ãƒã‚¤ãƒˆã‚ªãƒ¼ãƒ€ãŒæœ¬ãƒ—ログラムã§ä½¿ç”¨\n" -"ã•れるもã®ã¨ç•°ãªã‚Šã¾ã™ã€‚ã“ã®å ´åˆä»¥ä¸‹ã®çµæžœã¯ä¸æ­£ç¢ºã«ãªã‚Šã¾ã™ã€‚ã¾ãŸã€PostgreSQL\n" -"インストレーションã¯ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¨äº’æ›æ€§ãŒãªããªã‚Šã¾ã™ã€‚\n" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"ファイル中ã®WALセグメントサイズ㯠%d ãƒã‚¤ãƒˆã¨ãªã£ã¦ã„ã¾ã™ãŒã€ã“れã¯\n" +"1MBã‹ã‚‰1GBã¾ã§ã®2ã®ç´¯ä¹—ã§ã¯ã‚りã¾ã›ã‚“。ã“ã®ãƒ•ァイルã¯å£Šã‚Œã¦ãŠã‚Šã€\n" +"ä»¥ä¸‹ã®æƒ…å ±ã¯ä¿¡é ¼ã§ãã¾ã›ã‚“。\n" +"\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_controlãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·: %u\n" -#: pg_controldata.c:197 +#: pg_controldata.c:236 #, c-format msgid "Catalog version number: %u\n" -msgstr "カタログãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·: %u\n" +msgstr "カタログãƒãƒ¼ã‚¸ãƒ§ãƒ³ç•ªå·: %u\n" -#: pg_controldata.c:199 +#: pg_controldata.c:238 #, c-format msgid "Database system identifier: %s\n" -msgstr "データベースシステム識別å­: %s\n" +msgstr "データベースシステム識別å­: %s\n" -#: pg_controldata.c:201 +#: pg_controldata.c:240 #, c-format msgid "Database cluster state: %s\n" -msgstr "データベースクラスタã®çŠ¶æ…‹: %s\n" +msgstr "データベースクラスタã®çŠ¶æ…‹: %s\n" -#: pg_controldata.c:203 +#: pg_controldata.c:242 #, c-format msgid "pg_control last modified: %s\n" -msgstr "pg_control最終更新: %s\n" +msgstr "pg_control最終更新: %s\n" -#: pg_controldata.c:205 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint location: %X/%X\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä½ç½®: %X/%X\n" - -#: pg_controldata.c:208 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "å‰å›žã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä½ç½®: %X/%X\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä½ç½®: %X/%X\n" -#: pg_controldata.c:211 +#: pg_controldata.c:247 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®REDOä½ç½®: %X/%X\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®REDOä½ç½®: %X/%X\n" -#: pg_controldata.c:214 +#: pg_controldata.c:250 #, c-format -#| msgid "Latest checkpoint's REDO location: %X/%X\n" msgid "Latest checkpoint's REDO WAL file: %s\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®REDO WALファイル: %s\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®REDO WALファイル: %s\n" -#: pg_controldata.c:216 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®æ™‚系列ID: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®æ™‚系列ID: %u\n" -#: pg_controldata.c:218 +#: pg_controldata.c:254 #, c-format -#| msgid "Latest checkpoint's TimeLineID: %u\n" msgid "Latest checkpoint's PrevTimeLineID: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®PrevTimeLineID: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®PrevTimeLineID: %u\n" -#: pg_controldata.c:220 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®full_page_writes %s\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®full_page_writes: %s\n" -#: pg_controldata.c:221 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "off" msgstr "オフ" -#: pg_controldata.c:221 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "on" msgstr "オン" -#: pg_controldata.c:222 +#: pg_controldata.c:258 #, c-format -msgid "Latest checkpoint's NextXID: %u/%u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextXID: %u/%u\n" +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextXID: %u:%u\n" -#: pg_controldata.c:225 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's NextOID: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextOID: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextOID: %u\n" -#: pg_controldata.c:227 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextMultiXactId: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextMultiXactId: %u\n" -#: pg_controldata.c:229 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextMultiOffset: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®NextMultiOffset: %u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestXID: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestXID: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestXIDã®DB: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestXIDã®DB: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestActiveXID: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestActiveXID: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:273 #, c-format -#| msgid "Latest checkpoint's oldestActiveXID: %u\n" msgid "Latest checkpoint's oldestMultiXid: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestMultiXid: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestMultiXid: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:275 #, c-format -#| msgid "Latest checkpoint's oldestXID's DB: %u\n" msgid "Latest checkpoint's oldestMulti's DB: %u\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestMulti'sã®DB: %u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestMulti'sã®DB: %u\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®oldestCommitTsXid: %u\n" + +#: pg_controldata.c:279 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã®newestCommitTsXid: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:281 #, c-format msgid "Time of latest checkpoint: %s\n" -msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆæ™‚刻: %s\n" +msgstr "最終ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆæ™‚刻: %s\n" -#: pg_controldata.c:243 +#: pg_controldata.c:283 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" -msgstr "ログをå–らãªã„リレーションå‘ã‘ã®å½ã®LSNカウンタ: %X/%X\n" +msgstr "UNLOGGEDリレーションã®å½ã®LSNカウンタ: %X/%X\n" -#: pg_controldata.c:246 +#: pg_controldata.c:286 #, c-format msgid "Minimum recovery ending location: %X/%X\n" -msgstr "最å°ãƒªã‚«ãƒãƒªçµ‚了ä½ç½®: %X/%X\n" +msgstr "最å°ãƒªã‚«ãƒãƒªçµ‚了ä½ç½®: %X/%X\n" -#: pg_controldata.c:249 +#: pg_controldata.c:289 #, c-format -#| msgid "Minimum recovery ending location: %X/%X\n" msgid "Min recovery ending loc's timeline: %u\n" -msgstr "最å°ãƒªã‚«ãƒãƒªçµ‚了ä½ç½®ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³: %u\n" +msgstr "最å°ãƒªã‚«ãƒãƒªçµ‚了ä½ç½®ã®ã‚¿ã‚¤ãƒ ãƒ©ã‚¤ãƒ³: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:291 #, c-format msgid "Backup start location: %X/%X\n" -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—é–‹å§‹ä½ç½®: %X/%X\n" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—é–‹å§‹ä½ç½®: %X/%X\n" -#: pg_controldata.c:254 +#: pg_controldata.c:294 #, c-format msgid "Backup end location: %X/%X\n" -msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—終了ä½ç½®: %X/%X\n" +msgstr "ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—終了ä½ç½®: %X/%X\n" -#: pg_controldata.c:257 +#: pg_controldata.c:297 #, c-format msgid "End-of-backup record required: %s\n" -msgstr "å¿…è¦ãªãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—最終レコード: %s\n" +msgstr "å¿…è¦ãªãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—最終レコード: %s\n" -#: pg_controldata.c:258 +#: pg_controldata.c:298 msgid "no" msgstr "no" -#: pg_controldata.c:258 +#: pg_controldata.c:298 msgid "yes" msgstr "yes" -#: pg_controldata.c:259 +#: pg_controldata.c:299 #, c-format -msgid "Current wal_level setting: %s\n" -msgstr "wal_level ã®ç¾åœ¨è¨­å®š %s\n" +msgid "wal_level setting: %s\n" +msgstr "wal_level ã®ç¾åœ¨ã®è¨­å®š: %s\n" -#: pg_controldata.c:261 +#: pg_controldata.c:301 #, c-format -msgid "Current max_connections setting: %d\n" -msgstr "max_connections ã®ç¾åœ¨è¨­å®šï¼š %d\n" +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hints ã®ç¾åœ¨ã®è¨­å®š: %s\n" -#: pg_controldata.c:263 +#: pg_controldata.c:303 #, c-format -#| msgid "Current max_prepared_xacts setting: %d\n" -msgid "Current max_worker_processes setting: %d\n" -msgstr "max_worker_processesã®ç¾åœ¨è¨­å®šï¼š %d\n" +msgid "max_connections setting: %d\n" +msgstr "max_connections ã®ç¾åœ¨ã®è¨­å®š: %d\n" -#: pg_controldata.c:265 +#: pg_controldata.c:305 #, c-format -msgid "Current max_prepared_xacts setting: %d\n" -msgstr "max_prepared_xacts ã®ç¾åœ¨è¨­å®šï¼š %d\n" +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processes ã®ç¾åœ¨ã®è¨­å®š: %d\n" -#: pg_controldata.c:267 +#: pg_controldata.c:307 #, c-format -msgid "Current max_locks_per_xact setting: %d\n" -msgstr "max_locks_per_xact ã®ç¾åœ¨è¨­å®šï¼š %d\n" +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xacts ã®ç¾åœ¨ã®è¨­å®š: %d\n" -#: pg_controldata.c:269 +#: pg_controldata.c:309 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xact ã®ç¾åœ¨ã®è¨­å®š: %d\n" + +#: pg_controldata.c:311 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestamp ã®ç¾åœ¨ã®è¨­å®š: %s\n" + +#: pg_controldata.c:313 #, c-format msgid "Maximum data alignment: %u\n" -msgstr "最大データアラインメント %u\n" +msgstr "最大データアラインメント: %u\n" -#: pg_controldata.c:272 +#: pg_controldata.c:316 #, c-format msgid "Database block size: %u\n" -msgstr "データベースã®ãƒ–ロックサイズ: %u\n" +msgstr "データベースã®ãƒ–ロックサイズ: %u\n" -#: pg_controldata.c:274 +#: pg_controldata.c:318 #, c-format msgid "Blocks per segment of large relation: %u\n" -msgstr "ラージリレーションã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆå½“ãŸã‚Šã®ãƒ–ロック数: %u\n" +msgstr "大ããªãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆæ¯Žã®ãƒ–ロック数: %u\n" -#: pg_controldata.c:276 +#: pg_controldata.c:320 #, c-format msgid "WAL block size: %u\n" -msgstr "WALブロックã®ã‚µã‚¤ã‚º: %u\n" +msgstr "WALã®ãƒ–ロックサイズ: %u\n" -#: pg_controldata.c:278 +#: pg_controldata.c:322 #, c-format msgid "Bytes per WAL segment: %u\n" -msgstr "WALセグメント当ãŸã‚Šã®ãƒã‚¤ãƒˆæ•°: %u\n" +msgstr "WALセグメント当ãŸã‚Šã®ãƒã‚¤ãƒˆæ•°: %u\n" -#: pg_controldata.c:280 +#: pg_controldata.c:324 #, c-format msgid "Maximum length of identifiers: %u\n" -msgstr "識別å­ã®æœ€å¤§é•·: %u\n" +msgstr "識別å­ã®æœ€å¤§é•·: %u\n" -#: pg_controldata.c:282 +#: pg_controldata.c:326 #, c-format msgid "Maximum columns in an index: %u\n" -msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å†…ã®æœ€å¤§åˆ—æ•°: %u\n" +msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å†…ã®æœ€å¤§åˆ—æ•°: %u\n" -#: pg_controldata.c:284 +#: pg_controldata.c:328 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" -msgstr "TOASTãƒãƒ£ãƒ³ã‚¯ã®æœ€å¤§ã‚µã‚¤ã‚º: %u\n" +msgstr "TOASTãƒãƒ£ãƒ³ã‚¯ã®æœ€å¤§ã‚µã‚¤ã‚º: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:330 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "ラージオブジェクトãƒãƒ£ãƒ³ã‚¯ã®ã‚µã‚¤ã‚º: %u\n" + +#: pg_controldata.c:333 #, c-format msgid "Date/time type storage: %s\n" -msgstr "日付/æ™‚åˆ»åž‹ã®æ ¼ç´æ–¹å¼: %s\n" +msgstr "日付/æ™‚åˆ»åž‹ã®æ ¼ç´æ–¹å¼: %s\n" -#: pg_controldata.c:287 +#: pg_controldata.c:334 msgid "64-bit integers" msgstr "64ビット整数" -#: pg_controldata.c:287 -msgid "floating-point numbers" -msgstr "æµ®å‹•å°æ•°ç‚¹æ•°" - -#: pg_controldata.c:288 +#: pg_controldata.c:335 #, c-format msgid "Float4 argument passing: %s\n" -msgstr "Float4 å¼•æ•°ã®æ¸¡ã—方: %s\n" +msgstr "Float4 å¼•æ•°ã®æ¸¡ã—æ–¹: %s\n" -#: pg_controldata.c:289 pg_controldata.c:291 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by reference" msgstr "å‚照渡ã—" -#: pg_controldata.c:289 pg_controldata.c:291 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by value" msgstr "値渡ã—" -#: pg_controldata.c:290 +#: pg_controldata.c:337 #, c-format msgid "Float8 argument passing: %s\n" -msgstr "Float8 å¼•æ•°ã®æ¸¡ã—方: %s\n" +msgstr "Float8 å¼•æ•°ã®æ¸¡ã—æ–¹: %s\n" -#: pg_controldata.c:292 +#: pg_controldata.c:339 #, c-format -#| msgid "Catalog version number: %u\n" msgid "Data page checksum version: %u\n" -msgstr "データベージãƒã‚§ãƒƒã‚¯ã‚µãƒ ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³: %u\n" - -#~ msgid "" -#~ "Usage:\n" -#~ " %s [OPTION] [DATADIR]\n" -#~ "\n" -#~ "Options:\n" -#~ " --help show this help, then exit\n" -#~ " --version output version information, then exit\n" -#~ msgstr "" -#~ "使用方法:\n" -#~ " %s [OPTION] [DATADIR]\n" -#~ "\n" -#~ "オプション:\n" -#~ " --help ヘルプを表示ã—ã€çµ‚了ã—ã¾ã™\n" -#~ " --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr "データベージãƒã‚§ãƒƒã‚¯ã‚µãƒ ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³: %u\n" + +#: pg_controldata.c:341 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "èªè¨¼ç”¨ã®ç–‘ä¼¼nonce: %s\n" + +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "å‰å›žã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆä½ç½®: %X/%X\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" diff --git a/src/bin/pg_controldata/po/ko.po b/src/bin/pg_controldata/po/ko.po index 2916cea85b5..477d1bfd988 100644 --- a/src/bin/pg_controldata/po/ko.po +++ b/src/bin/pg_controldata/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6 pg_controldata\n" +"Project-Id-Version: pg_controldata (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 16:51+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 15:15+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" "Language: ko\n" @@ -15,53 +15,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: ../../common/controldata_utils.c:56 +#: ../../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: \"%s\" 파ì¼ì„ ì½ê¸° 모드로 ì—´ 수 없습니다: %s\n" -#: ../../common/controldata_utils.c:69 +#: ../../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 없습니다: %s\n" -#: ../../common/controldata_utils.c:86 -msgid "calculated CRC checksum does not match value stored in file" -msgstr "ê³„ì‚°ëœ CRC ì²´í¬ì„¬ ê°’ì´ íŒŒì¼ì— ì €ìž¥ëœ ê°’ê³¼ 다름" - -#: ../../common/controldata_utils.c:88 +#: ../../common/controldata_utils.c:90 #, c-format -msgid "" -"WARNING: Calculated CRC checksum does not match value stored in file.\n" -"Either the file is corrupt, or it has a different layout than this program\n" -"is expecting. The results below are untrustworthy.\n" -"\n" -msgstr "" -"경고: ê³„ì‚°ëœ CRC ì²´í¬ì„¬ê°’ì´ íŒŒì¼ì— 있는 ê°’ê³¼ 틀립니다.\n" -"ì´ ê²½ìš°ëŠ” 파ì¼ì´ ì†ìƒë˜ì—ˆê±°ë‚˜, ì´ í”„ë¡œê·¸ëž¨ê³¼ 컨트롤 파ì¼ì˜ ë²„ì „ì´ í‹€ë¦°\n" -"경우입니다. ê²°ê³¼ê°’ë“¤ì€ ë¯¿ì§€ 못할 ê°’ë“¤ì´ ì¶œë ¥ë  ìˆ˜ 있습니다.\n" -"\n" +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %d ì½ìŒ, ì „ì²´ %d\n" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "ë°”ì´íЏ 순서 불ì¼ì¹˜" -#: ../../common/controldata_utils.c:99 +#: ../../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" -"used by this program. In that case the results below would be incorrect, " -"and\n" +"used by this program. In that case the results below would be incorrect, and\n" "the PostgreSQL installation would be incompatible with this data directory.\n" msgstr "" "경고: ë°”ì´íЏ 순서가 ì¼ì¹˜í•˜ì§€ 않습니다.\n" "pg_control 파ì¼ì„ 저장하는 ë° ì‚¬ìš©ëœ ë°”ì´íЏ 순서는 \n" -"ì´ í”„ë¡œê·¸ëž¨ì—서 사용하는 순서와 ì¼ì¹˜í•´ì•¼ 합니다. ì´ ê²½ìš° 아래 결과는 올바르" -"ì§€ 않으며\n" +"ì´ í”„ë¡œê·¸ëž¨ì—서 사용하는 순서와 ì¼ì¹˜í•´ì•¼ 합니다. ì´ ê²½ìš° 아래 결과는 올바르지 않으며\n" "ì´ ë°ì´í„° ë””ë ‰í„°ë¦¬ì— PostgreSQLì„ ì„¤ì¹˜í•  수 없습니다.\n" -#: pg_controldata.c:33 +#: pg_controldata.c:34 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -70,17 +56,17 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ì˜ ì œì–´ì •ë³´ë¥¼ 보여줌.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:35 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:36 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [옵션] [DATADIR]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:37 #, c-format msgid "" "\n" @@ -89,27 +75,26 @@ msgstr "" "\n" "옵션들:\n" -#: pg_controldata.c:37 -#, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR ë°ì´í„° 디렉터리\n" - #: pg_controldata.c:38 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR ë°ì´í„° 디렉터리\n" #: pg_controldata.c:39 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" #: pg_controldata.c:40 #, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" + +#: pg_controldata.c:41 +#, c-format msgid "" "\n" -"If no data directory (DATADIR) is specified, the environment variable " -"PGDATA\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" "is used.\n" "\n" msgstr "" @@ -118,340 +103,387 @@ msgstr "" "사용합니다.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:43 #, c-format msgid "Report bugs to .\n" msgstr "오류보고: .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:53 msgid "starting up" msgstr "시작 중" -#: pg_controldata.c:54 +#: pg_controldata.c:55 msgid "shut down" msgstr "중지ë¨" -#: pg_controldata.c:56 +#: pg_controldata.c:57 msgid "shut down in recovery" msgstr "복구 작업 중 중지ë¨" -#: pg_controldata.c:58 +#: pg_controldata.c:59 msgid "shutting down" msgstr "중지 중" -#: pg_controldata.c:60 +#: pg_controldata.c:61 msgid "in crash recovery" msgstr "ë¹„ì •ìƒ ì¢…ë£Œ 복구 중" -#: pg_controldata.c:62 +#: pg_controldata.c:63 msgid "in archive recovery" msgstr "ìžë£Œ 복구 중" -#: pg_controldata.c:64 +#: pg_controldata.c:65 msgid "in production" msgstr "ì •ìƒê°€ë™ì¤‘" -#: pg_controldata.c:66 +#: pg_controldata.c:67 msgid "unrecognized status code" msgstr "알수 없는 ìƒíƒœ 코드" -#: pg_controldata.c:81 +#: pg_controldata.c:82 msgid "unrecognized wal_level" msgstr "알 수 없는 wal_level" -#: pg_controldata.c:127 pg_controldata.c:145 pg_controldata.c:153 +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "보다 ìžì„¸í•œ 정보는 \"%s --help\"\n" -#: pg_controldata.c:143 +#: pg_controldata.c:152 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" -#: pg_controldata.c:152 +#: pg_controldata.c:161 #, c-format msgid "%s: no data directory specified\n" msgstr "%s: ë°ì´í„° 디렉터리를 지정하지 않았습니다\n" -#: pg_controldata.c:190 +#: pg_controldata.c:169 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"경고: ê³„ì‚°ëœ CRC ì²´í¬ì„¬ê°’ì´ íŒŒì¼ì— 있는 ê°’ê³¼ 틀립니다.\n" +"ì´ ê²½ìš°ëŠ” 파ì¼ì´ ì†ìƒë˜ì—ˆê±°ë‚˜, ì´ í”„ë¡œê·¸ëž¨ê³¼ 컨트롤 파ì¼ì˜ ë²„ì „ì´ í‹€ë¦°\n" +"경우입니다. ê²°ê³¼ê°’ë“¤ì€ ë¯¿ì§€ 못할 ê°’ë“¤ì´ ì¶œë ¥ë  ìˆ˜ 있습니다.\n" +"\n" + +#: pg_controldata.c:178 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "경고: ìž˜ëª»ëœ WAL ì¡°ê° í¬ê¸°\n" + +#: pg_controldata.c:179 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"ì €ìž¥ëœ WAL ì¡°ê° íŒŒì¼ì˜ í¬ê¸°ëŠ” %d ë°”ì´íŠ¸ìž…ë‹ˆë‹¤. ì´ ê°’ì€ 1MB부터 1GB사ì´\n" +"2^n ê°’ì´ ì•„ë‹™ë‹ˆë‹¤. 파ì¼ì´ ì†ìƒë˜ì—ˆìœ¼ë©°, ê²°ê³¼ ë˜í•œ ë¯¿ì„ ìˆ˜ 없습니다.\n" +"\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control 버전 번호: %u\n" -#: pg_controldata.c:192 +#: pg_controldata.c:236 #, c-format msgid "Catalog version number: %u\n" msgstr "카탈로그 버전 번호: %u\n" -#: pg_controldata.c:194 +#: pg_controldata.c:238 #, c-format msgid "Database system identifier: %s\n" msgstr "ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„ìž: %s\n" -#: pg_controldata.c:196 +#: pg_controldata.c:240 #, c-format msgid "Database cluster state: %s\n" msgstr "ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„° ìƒíƒœ: %s\n" -#: pg_controldata.c:198 +#: pg_controldata.c:242 #, c-format msgid "pg_control last modified: %s\n" msgstr "pg_control 마지막 변경시간: %s\n" -#: pg_controldata.c:200 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ 위치: %X/%X\n" -#: pg_controldata.c:203 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "ì´ì „ ì²´í¬í¬ì¸íЏ 위치: %X/%X\n" - -#: pg_controldata.c:206 +#: pg_controldata.c:247 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ REDO 위치: %X/%X\n" -#: pg_controldata.c:209 +#: pg_controldata.c:250 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ REDO WAL 파ì¼: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ TimeLineID: %u\n" -#: pg_controldata.c:213 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ PrevTimeLineID: %u\n" -#: pg_controldata.c:215 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ full_page_writes: %s\n" -#: pg_controldata.c:216 pg_controldata.c:261 pg_controldata.c:271 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "off" msgstr "off" -#: pg_controldata.c:216 pg_controldata.c:261 pg_controldata.c:271 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "on" msgstr "on" -#: pg_controldata.c:217 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextXID: %u:%u\n" -#: pg_controldata.c:220 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextOID: %u\n" -#: pg_controldata.c:222 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextMultiXactId: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextMultiOffset: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœXID: %u\n" -#: pg_controldata.c:228 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœXIDì˜ DB: %u\n" -#: pg_controldata.c:230 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœActiveXID:%u\n" -#: pg_controldata.c:232 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœMultiXid: %u\n" -#: pg_controldata.c:234 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœë©€í‹°Xid DB:%u\n" -#: pg_controldata.c:236 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ì˜¤ëž˜ëœCommitTsXid:%u\n" -#: pg_controldata.c:238 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ 최신CommitTsXid: %u\n" -#: pg_controldata.c:240 +#: pg_controldata.c:281 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ 시간: %s\n" -#: pg_controldata.c:242 +#: pg_controldata.c:283 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "언로그 릴레ì´ì…˜ì˜ 가짜 LSN ì¹´ìš´í„°: %X/%X\n" -#: pg_controldata.c:245 +#: pg_controldata.c:286 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "최소 복구 마지막 위치: %X/%X\n" -#: pg_controldata.c:248 +#: pg_controldata.c:289 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "최소 복구 종료 ìœ„ì¹˜ì˜ íƒ€ìž„ë¼ì¸: %u\n" -#: pg_controldata.c:250 +#: pg_controldata.c:291 #, c-format msgid "Backup start location: %X/%X\n" msgstr "백업 시작 위치: %X/%X\n" -#: pg_controldata.c:253 +#: pg_controldata.c:294 #, c-format msgid "Backup end location: %X/%X\n" msgstr "백업 종료 위치: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:297 #, c-format msgid "End-of-backup record required: %s\n" msgstr "백업 종료 레코드 í•„ìš” 여부: %s\n" -#: pg_controldata.c:257 +#: pg_controldata.c:298 msgid "no" msgstr "아니오" -#: pg_controldata.c:257 +#: pg_controldata.c:298 msgid "yes" msgstr "예" -#: pg_controldata.c:258 +#: pg_controldata.c:299 #, c-format msgid "wal_level setting: %s\n" msgstr "wal_level 설정값: %s\n" -#: pg_controldata.c:260 +#: pg_controldata.c:301 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "wal_log_hints 설정값: %s\n" -#: pg_controldata.c:262 +#: pg_controldata.c:303 #, c-format msgid "max_connections setting: %d\n" msgstr "max_connections 설정값: %d\n" -#: pg_controldata.c:264 +#: pg_controldata.c:305 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "max_worker_processes 설정값: %d\n" -#: pg_controldata.c:266 +#: pg_controldata.c:307 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "max_prepared_xacts 설정값: %d\n" -#: pg_controldata.c:268 +#: pg_controldata.c:309 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "max_locks_per_xact 설정값: %d\n" -#: pg_controldata.c:270 +#: pg_controldata.c:311 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "track_commit_timestamp 설정값: %s\n" -#: pg_controldata.c:272 +#: pg_controldata.c:313 #, c-format msgid "Maximum data alignment: %u\n" msgstr "최대 ìžë£Œ ì •ë ¬: %u\n" -#: pg_controldata.c:275 +#: pg_controldata.c:316 #, c-format msgid "Database block size: %u\n" msgstr "ë°ì´í„°ë² ì´ìФ ë¸”ë¡ í¬ê¸°: %u\n" -#: pg_controldata.c:277 +#: pg_controldata.c:318 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "대형 릴레ì´ì…˜ì˜ 세그먼트당 블럭 개수: %u\n" -#: pg_controldata.c:279 +#: pg_controldata.c:320 #, c-format msgid "WAL block size: %u\n" msgstr "WAL ë¸”ë¡ í¬ê¸°: %u\n" -#: pg_controldata.c:281 +#: pg_controldata.c:322 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "WAL ì„¸ê·¸ë¨¼íŠ¸ì˜ í¬ê¸°(byte): %u\n" -#: pg_controldata.c:283 +#: pg_controldata.c:324 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "ì‹ë³„ìž ìµœëŒ€ 길ì´: %u\n" -#: pg_controldata.c:285 +#: pg_controldata.c:326 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "ì¸ë±ìФì—서 사용하는 최대 ì—´ 수: %u\n" -#: pg_controldata.c:287 +#: pg_controldata.c:328 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "TOAST ì²­í¬ ìµœëŒ€ í¬ê¸°: %u\n" -#: pg_controldata.c:289 +#: pg_controldata.c:330 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "대형 ê°ì²´ ì²­í¬ í¬ê¸°: %u\n" -#: pg_controldata.c:291 +#: pg_controldata.c:333 #, c-format msgid "Date/time type storage: %s\n" msgstr "ë‚ ì§œ/시간형 ìžë£Œì˜ 저장방ì‹: %s\n" -#: pg_controldata.c:292 +#: pg_controldata.c:334 msgid "64-bit integers" msgstr "64-비트 정수" -#: pg_controldata.c:292 -msgid "floating-point numbers" -msgstr "ë¶€ë™ì†Œìˆ˜" - -#: pg_controldata.c:293 +#: pg_controldata.c:335 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Float4 ì¸ìˆ˜ 전달: %s\n" -#: pg_controldata.c:294 pg_controldata.c:296 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by reference" msgstr "참조별" -#: pg_controldata.c:294 pg_controldata.c:296 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by value" msgstr "값별" -#: pg_controldata.c:295 +#: pg_controldata.c:337 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Float8 ì¸ìˆ˜ 전달: %s\n" -#: pg_controldata.c:297 +#: pg_controldata.c:339 #, c-format msgid "Data page checksum version: %u\n" msgstr "ë°ì´í„° 페ì´ì§€ ì²´í¬ì„¬ 버전: %u\n" + +#: pg_controldata.c:341 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "임시 ëª¨ì˜ ì¸ì¦: %s\n" + +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "ì´ì „ ì²´í¬í¬ì¸íЏ 위치: %X/%X\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" + +#~ msgid " [-D] DATADIR data directory\n" +#~ msgstr " [-D] DATADIR ë°ì´í„° 디렉터리\n" diff --git a/src/bin/pg_controldata/po/ru.po b/src/bin/pg_controldata/po/ru.po index dcfbc47ae0e..ec613b9ddd0 100644 --- a/src/bin/pg_controldata/po/ru.po +++ b/src/bin/pg_controldata/po/ru.po @@ -4,14 +4,14 @@ # Serguei A. Mokhov , 2002-2004. # Oleg Bartunov , 2004. # Andrey Sudnik , 2011. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: pg_controldata (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:46+0000\n" -"PO-Revision-Date: 2017-04-03 10:51+0300\n" +"POT-Creation-Date: 2018-10-05 21:51+0300\n" +"PO-Revision-Date: 2018-10-02 16:23+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -19,23 +19,27 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:62 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %s\n" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:78 #, c-format msgid "%s: could not read file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\": %s\n" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\" (прочитано байт: %d из %d)\n" + +#: ../../common/controldata_utils.c:112 msgid "byte ordering mismatch" msgstr "неÑоответÑтвие порÑдка байт" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:114 #, c-format msgid "" "WARNING: possible byte ordering mismatch\n" @@ -49,7 +53,7 @@ msgstr "" "Ñтой программой. Ð’ Ñтом Ñлучае результаты будут неверными и\n" "уÑтановленный PostgreSQL будет неÑовмеÑтим Ñ Ñтим каталогом данных.\n" -#: pg_controldata.c:33 +#: pg_controldata.c:34 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -58,17 +62,17 @@ msgstr "" "%s показывает информацию о работе клаÑтера баз PostgreSQL.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:35 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:36 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [ПÐРÐМЕТР] [КÐТ_ДÐÐÐЫХ]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:37 #, c-format msgid "" "\n" @@ -77,23 +81,23 @@ msgstr "" "\n" "Параметры:\n" -#: pg_controldata.c:37 -#, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] КÐТ_ДÐÐÐЫХ каталог данных\n" - #: pg_controldata.c:38 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version показать верÑию и выйти\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]КÐТ_ДÐÐÐЫХ каталог данных\n" #: pg_controldata.c:39 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help показать Ñту Ñправку и выйти\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать верÑию и выйти\n" #: pg_controldata.c:40 #, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать Ñту Ñправку и выйти\n" + +#: pg_controldata.c:41 +#, c-format msgid "" "\n" "If no data directory (DATADIR) is specified, the environment variable " @@ -106,63 +110,63 @@ msgstr "" "PGDATA.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:43 #, c-format msgid "Report bugs to .\n" msgstr "Об ошибках Ñообщайте по адреÑу .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:53 msgid "starting up" msgstr "запуÑкаетÑÑ" -#: pg_controldata.c:54 +#: pg_controldata.c:55 msgid "shut down" msgstr "выключен" -#: pg_controldata.c:56 +#: pg_controldata.c:57 msgid "shut down in recovery" msgstr "выключен при воÑÑтановлении" -#: pg_controldata.c:58 +#: pg_controldata.c:59 msgid "shutting down" msgstr "выключение" -#: pg_controldata.c:60 +#: pg_controldata.c:61 msgid "in crash recovery" msgstr "воÑÑтановление поÑле ÑбоÑ" -#: pg_controldata.c:62 +#: pg_controldata.c:63 msgid "in archive recovery" msgstr "воÑÑтановление из архива" -#: pg_controldata.c:64 +#: pg_controldata.c:65 msgid "in production" msgstr "в работе" -#: pg_controldata.c:66 +#: pg_controldata.c:67 msgid "unrecognized status code" msgstr "нераÑпознанный код ÑоÑтоÑниÑ" -#: pg_controldata.c:81 +#: pg_controldata.c:82 msgid "unrecognized wal_level" msgstr "нераÑпознанный уровень WAL" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_controldata.c:146 +#: pg_controldata.c:152 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: pg_controldata.c:155 +#: pg_controldata.c:161 #, c-format msgid "%s: no data directory specified\n" msgstr "%s: каталог данных не указан\n" -#: pg_controldata.c:163 +#: pg_controldata.c:169 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -176,312 +180,350 @@ msgstr "" "Ð¡Ð»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶ÐµÑ‚ быть недоÑтоверной.\n" "\n" -#: pg_controldata.c:201 +#: pg_controldata.c:178 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "ПРЕДУПРЕЖДЕÐИЕ: неверный размер Ñегмента WAL\n" + +#: pg_controldata.c:179 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Сохранённый в Ñтом файле размер Ñегмента WAL (байт: %d) не ÑвлÑетÑÑ " +"Ñтепенью\n" +"двух между 1 МБ и 1 ГБ. Файл иÑпорчен, Ð²Ñ‹Ð²Ð¾Ð´Ð¸Ð¼Ð°Ñ Ð½Ð¸Ð¶Ðµ информациÑ\n" +"подлежит Ñомнению.\n" +"\n" +msgstr[1] "" +"Сохранённый в Ñтом файле размер Ñегмента WAL (байт: %d) не ÑвлÑетÑÑ " +"Ñтепенью\n" +"двух между 1 МБ и 1 ГБ. Файл иÑпорчен, Ð²Ñ‹Ð²Ð¾Ð´Ð¸Ð¼Ð°Ñ Ð½Ð¸Ð¶Ðµ информациÑ\n" +"подлежит Ñомнению.\n" +"\n" +msgstr[2] "" +"Сохранённый в Ñтом файле размер Ñегмента WAL (байт: %d) не ÑвлÑетÑÑ " +"Ñтепенью\n" +"двух между 1 МБ и 1 ГБ. Файл иÑпорчен, Ð²Ñ‹Ð²Ð¾Ð´Ð¸Ð¼Ð°Ñ Ð½Ð¸Ð¶Ðµ информациÑ\n" +"подлежит Ñомнению.\n" +"\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 #, c-format msgid "pg_control version number: %u\n" msgstr "Ðомер верÑии pg_control: %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:236 #, c-format msgid "Catalog version number: %u\n" msgstr "Ðомер верÑии каталога: %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:238 #, c-format msgid "Database system identifier: %s\n" msgstr "Идентификатор ÑиÑтемы баз данных: %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:240 #, c-format msgid "Database cluster state: %s\n" msgstr "СоÑтоÑние клаÑтера БД: %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:242 #, c-format msgid "pg_control last modified: %s\n" msgstr "ПоÑледнее обновление pg_control: %s\n" # skip-rule: capital-letter-first -#: pg_controldata.c:211 +#: pg_controldata.c:244 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "Положение поÑледней конт. точки: %X/%X\n" # skip-rule: capital-letter-first -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Положение предыдущей конт. точки: %X/%X\n" - -# skip-rule: capital-letter-first -#: pg_controldata.c:217 +#: pg_controldata.c:247 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "Положение REDO поÑледней конт. точки: %X/%X\n" # skip-rule: capital-letter-first -#: pg_controldata.c:220 +#: pg_controldata.c:250 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "Файл WAL c REDO поÑледней к. Ñ‚.: %s\n" # skip-rule: capital-letter-first -#: pg_controldata.c:222 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "Ð›Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:224 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "Пред. Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ поÑледней к. Ñ‚.: %u\n" # skip-rule: no-space-after-period -#: pg_controldata.c:226 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "Режим full_page_writes поÑледней к.Ñ‚: %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "off" msgstr "выкл." -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 msgid "on" msgstr "вкл." # skip-rule: capital-letter-first -#: pg_controldata.c:228 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID поÑледней конт. точки: %u:%u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:231 +#: pg_controldata.c:261 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:233 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId поÑлед. конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:235 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset поÑлед. конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:237 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:239 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "БД Ñ oldestXID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:241 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID поÑледней к. Ñ‚.: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:243 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid поÑледней конт. точки: %u\n" # skip-rule: double-space, capital-letter-first -#: pg_controldata.c:245 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "БД Ñ oldestMulti поÑледней к. Ñ‚.: %u\n" # skip-rule: double-space, capital-letter-first -#: pg_controldata.c:247 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid поÑледней к. Ñ‚.: %u\n" # skip-rule: capital-letter-first, double-space -#: pg_controldata.c:249 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid поÑледней к. Ñ‚.: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:281 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледней контрольной точки: %s\n" # skip-rule: capital-letter-first # well-spelled: нежурналир -#: pg_controldata.c:253 +#: pg_controldata.c:283 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Фиктивный LSN Ð´Ð»Ñ Ð½ÐµÐ¶ÑƒÑ€Ð½Ð°Ð»Ð¸Ñ€. таблиц: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:286 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "Мин. положение конца воÑÑтановлениÑ: %X/%X\n" # skip-rule: capital-letter-first -#: pg_controldata.c:259 +#: pg_controldata.c:289 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "Ð›Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ мин. Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ðº. в.: %u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:291 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Положение начала копии: %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:294 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Положение конца копии: %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:297 #, c-format msgid "End-of-backup record required: %s\n" msgstr "ТребуетÑÑ Ð·Ð°Ð¿Ð¸ÑÑŒ конец-копии: %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:298 msgid "no" msgstr "нет" -#: pg_controldata.c:268 +#: pg_controldata.c:298 msgid "yes" msgstr "да" -#: pg_controldata.c:269 +#: pg_controldata.c:299 #, c-format msgid "wal_level setting: %s\n" msgstr "Значение wal_level: %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:301 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "Значение wal_log_hints: %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:303 #, c-format msgid "max_connections setting: %d\n" msgstr "Значение max_connections: %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:305 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "Значение max_worker_processes: %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:307 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "Значение max_prepared_xacts: %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:309 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "Значение max_locks_per_xact: %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:311 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "Значение track_commit_timestamp: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:313 #, c-format msgid "Maximum data alignment: %u\n" msgstr "МакÑ. предел Ð²Ñ‹Ñ€Ð°Ð²Ð½Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:316 #, c-format msgid "Database block size: %u\n" msgstr "Размер блока БД: %u\n" # skip-rule: double-space -#: pg_controldata.c:288 +#: pg_controldata.c:318 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Блоков в макÑ. Ñегменте отношений: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:320 #, c-format msgid "WAL block size: %u\n" msgstr "Размер блока WAL: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:322 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Байт в Ñегменте WAL: %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:324 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° идентификаторов: %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:326 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "МакÑ. чиÑло Ñтолбцов в индекÑе: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:328 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "МакÑимальный размер порции TOAST: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:330 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Размер порции большого объекта: %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:333 #, c-format msgid "Date/time type storage: %s\n" msgstr "Формат Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‹/времени: %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:334 msgid "64-bit integers" msgstr "64-битные целые" -#: pg_controldata.c:305 +#: pg_controldata.c:335 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Передача аргумента Float4: %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by reference" msgstr "по ÑÑылке" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:336 pg_controldata.c:338 msgid "by value" msgstr "по значению" -#: pg_controldata.c:307 +#: pg_controldata.c:337 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Передача аргумента Float8: %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:339 #, c-format msgid "Data page checksum version: %u\n" msgstr "ВерÑÐ¸Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… Ñумм Ñтраниц: %u\n" # skip-rule: capital-letter-first -#: pg_controldata.c:311 +#: pg_controldata.c:341 #, c-format msgid "Mock authentication nonce: %s\n" msgstr "Случ. чиÑло Ð´Ð»Ñ Ð¿Ñевдоаутентификации: %s\n" +# skip-rule: capital-letter-first +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "Положение предыдущей конт. точки: %X/%X\n" + #~ msgid "calculated CRC checksum does not match value stored in file" #~ msgstr "" #~ "вычиÑÐ»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма (CRC) не ÑоответÑтвует значению, " diff --git a/src/bin/pg_controldata/po/sv.po b/src/bin/pg_controldata/po/sv.po index 4bed78de03a..0899504edce 100644 --- a/src/bin/pg_controldata/po/sv.po +++ b/src/bin/pg_controldata/po/sv.po @@ -1,51 +1,77 @@ # Swedish message translation file for pg_controldata # This file is put in the public domain. -# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. # Mats Erik Andersson , 2014. # # Use these quotes: "%s" # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-19 12:46+0000\n" -"PO-Revision-Date: 2017-07-20 21:40+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-10 19:18+0000\n" +"PO-Revision-Date: 2019-05-10 22:32+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/controldata_utils.c:61 +#: ../../common/controldata_utils.c:73 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" -#: ../../common/controldata_utils.c:74 +#: ../../common/controldata_utils.c:89 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: kunde inte läsa fil \"%s\": %s\n" +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" -#: ../../common/controldata_utils.c:95 +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" + +#: ../../common/controldata_utils.c:135 msgid "byte ordering mismatch" msgstr "byte-ordning stämmer inte" -#: ../../common/controldata_utils.c:97 +#: ../../common/controldata_utils.c:137 #, c-format msgid "" -"WARNING: possible byte ordering mismatch\n" +"possible byte ordering mismatch\n" "The byte ordering used to store the pg_control file might not match the one\n" "used by this program. In that case the results below would be incorrect, and\n" -"the PostgreSQL installation would be incompatible with this data directory.\n" +"the PostgreSQL installation would be incompatible with this data directory." msgstr "" -"VARNING: möjligt fel i talordning\n" -"Den endian-ordning med vilken pg_control lagrar filer passar kanske\n" -"inte detta program. I sÃ¥ fall kan nedanstÃ¥ende utfall vara oriktigt\n" -"och det installerade PostgreSQL vara oförenligt med databaskatalogen.\n" +"möjligt fel i byteordning\n" +"Den byteordning som filen frÃ¥n pg_control lagrats med passar kanske\n" +"inte detta program. I sÃ¥ fall kan nedanstÃ¥ende resultat vara felaktiga\n" +"och PostgreSQL-installationen vara inkompatibel med databaskatalogen." + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" -#: pg_controldata.c:33 +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "kunde inte fsync:a fil \"%s\": %m" + +#: pg_controldata.c:36 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -54,39 +80,41 @@ msgstr "" "%s visar kontrollinformation om ett databaskluster för PostgreSQL.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:37 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:38 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [FLAGGA] [DATAKATALOG]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:39 #, c-format msgid "" "\n" "Options:\n" -msgstr "\nFlaggor:\n" +msgstr "" +"\n" +"Flaggor:\n" -#: pg_controldata.c:37 +#: pg_controldata.c:40 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR datakatalog\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR datakatalog\n" -#: pg_controldata.c:38 +#: pg_controldata.c:41 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version visa versionsinformation, avsluta sedan\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_controldata.c:39 +#: pg_controldata.c:42 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help visa denna hjälp, avsluta sedan\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" -#: pg_controldata.c:40 +#: pg_controldata.c:43 #, c-format msgid "" "\n" @@ -99,63 +127,63 @@ msgstr "" "PGDATA för detta syfte.\n" "\n" -#: pg_controldata.c:42 +#: pg_controldata.c:45 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapportera fel till .\n" +msgid "Report bugs to .\n" +msgstr "Rapportera buggar till .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:55 msgid "starting up" msgstr "startar" -#: pg_controldata.c:54 +#: pg_controldata.c:57 msgid "shut down" msgstr "avstängt" -#: pg_controldata.c:56 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "avslutat med Ã¥terställning" -#: pg_controldata.c:58 +#: pg_controldata.c:61 msgid "shutting down" msgstr "stänger ner" -#: pg_controldata.c:60 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "Ã¥terställer efter krash" -#: pg_controldata.c:62 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "utför arkivÃ¥terställning" -#: pg_controldata.c:64 +#: pg_controldata.c:67 msgid "in production" msgstr "i full drift" -#: pg_controldata.c:66 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "okänd statuskod" -#: pg_controldata.c:81 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "okänd wal_level" -#: pg_controldata.c:130 pg_controldata.c:148 pg_controldata.c:156 +#: pg_controldata.c:138 pg_controldata.c:156 pg_controldata.c:164 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_controldata.c:146 +#: pg_controldata.c:154 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: pg_controldata.c:155 +#: pg_controldata.c:163 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: ingen datakatalog angiven.\n" +msgid "no data directory specified" +msgstr "ingen datakatalog angiven" -#: pg_controldata.c:163 +#: pg_controldata.c:171 #, c-format msgid "" "WARNING: Calculated CRC checksum does not match value stored in file.\n" @@ -168,294 +196,341 @@ msgstr "" "program förväntade sig. Resultatet nedan är inte helt tillförlitligt.\n" "\n" +#: pg_controldata.c:180 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "VARNING: ogiltig WAL-segmentstorlek\n" + +#: pg_controldata.c:181 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"WAL-segmentstorleken sparad i filen, %d byte, är inte en tvÃ¥potens\n" +"mellan 1 MB och 1 GB. Filen är trasig och resultatet nedan gÃ¥r\n" +"ej att lita pÃ¥.\n" +"\n" +msgstr[1] "" +"WAL-segmentstorleken sparad i filen, %d byte, är inte en tvÃ¥potens\n" +"mellan 1 MB och 1 GB. Filen är trasig och resultatet nedan gÃ¥r\n" +"ej att lita pÃ¥.\n" +"\n" + +#: pg_controldata.c:223 +msgid "???" +msgstr "???" + # Sep. 6th, 2014: # Insert additional spaces in translated strings for the # purpose of alignment. Of lingustic reasons the separation # used for English is insufficient for Swedish. New indenting # is consistent for all reporting statements: six additional # space characters. -#: pg_controldata.c:201 +#: pg_controldata.c:236 #, c-format msgid "pg_control version number: %u\n" msgstr "Versionsnummer för pg_control: %u\n" -#: pg_controldata.c:203 +#: pg_controldata.c:238 #, c-format msgid "Catalog version number: %u\n" msgstr "Katalogversion: %u\n" -#: pg_controldata.c:205 +#: pg_controldata.c:240 #, c-format msgid "Database system identifier: %s\n" msgstr "Databasens systemidentifierare: %s\n" -#: pg_controldata.c:207 +#: pg_controldata.c:242 #, c-format msgid "Database cluster state: %s\n" msgstr "Databasklustrets tillstÃ¥nd: %s\n" -#: pg_controldata.c:209 +#: pg_controldata.c:244 #, c-format msgid "pg_control last modified: %s\n" msgstr "pg_control ändrades senast: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint location: %X/%X\n" -msgstr "Läge för senaste kontrollpunkt: %X/%X\n" - -#: pg_controldata.c:214 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "Närmast föregÃ¥ende kontrollpunkt: %X/%X\n" +msgstr "Läge för senaste checkpoint: %X/%X\n" -#: pg_controldata.c:217 +#: pg_controldata.c:249 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" -msgstr "REDO-läge för senaste kontrollpunkt: %X/%X\n" +msgstr "REDO-läge för senaste checkpoint: %X/%X\n" -#: pg_controldata.c:220 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" -msgstr "REDO-WAL-fil vid senaste kontrollpunkt: %s\n" +msgstr "REDO-WAL-fil vid senaste checkpoint: %s\n" -#: pg_controldata.c:222 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" -msgstr "TimeLineID vid senaste kontrollpunkt: %u\n" +msgstr "TimeLineID vid senaste checkpoint: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" -msgstr "PrevTimeLineID vid senaste kontrollpunkt: %u\n" +msgstr "PrevTimeLineID vid senaste checkpoint: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" -msgstr "Senaste kontrollpunktens full_page_writes: %s\n" +msgstr "Senaste checkpoint:ens full_page_writes: %s\n" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "off" msgstr "av" -#: pg_controldata.c:227 pg_controldata.c:272 pg_controldata.c:282 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "on" msgstr "pÃ¥" -#: pg_controldata.c:228 +#: pg_controldata.c:260 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" -msgstr "NextXID vid senaste kontrollpunkt: %u:%u\n" +msgstr "NextXID vid senaste checkpoint: %u:%u\n" -#: pg_controldata.c:231 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextOID: %u\n" -msgstr "NextOID vid senaste kontrollpunkt: %u\n" +msgstr "NextOID vid senaste checkpoint: %u\n" -#: pg_controldata.c:233 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" -msgstr "NextMultiXactId vid senaste kontrollpunkt: %u\n" +msgstr "NextMultiXactId vid senaste checkpoint: %u\n" -#: pg_controldata.c:235 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" -msgstr "NextMultiOffset vid senaste kontrollpunkt: %u\n" +msgstr "NextMultiOffset vid senaste checkpoint: %u\n" -#: pg_controldata.c:237 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" -msgstr "oldestXID vid senaste kontrollpunkt: %u\n" +msgstr "oldestXID vid senaste checkpoint: %u\n" -#: pg_controldata.c:239 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" -msgstr "DB för oldestXID vid senaste kontrollpunkt: %u\n" +msgstr "DB för oldestXID vid senaste checkpoint: %u\n" -#: pg_controldata.c:241 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" -msgstr "oldestActiveXID vid senaste kontrollpunkt: %u\n" +msgstr "oldestActiveXID vid senaste checkpoint: %u\n" -#: pg_controldata.c:243 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" -msgstr "oldestMultiXid vid senaste kontrollpunkt: %u\n" +msgstr "oldestMultiXid vid senaste checkpoint: %u\n" -#: pg_controldata.c:245 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" -msgstr "DB för oldestMulti vid senaste kontrollpkt: %u\n" +msgstr "DB för oldestMulti vid senaste checkpoint: %u\n" -#: pg_controldata.c:247 +#: pg_controldata.c:279 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" -msgstr "oldestCommitTsXid vid senaste kontrollpunkt:%u\n" +msgstr "oldestCommitTsXid vid senaste checkpoint: %u\n" -#: pg_controldata.c:249 +#: pg_controldata.c:281 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" -msgstr "newestCommitTsXid vid senaste kontrollpunkt:%u\n" +msgstr "newestCommitTsXid vid senaste checkpoint: %u\n" -#: pg_controldata.c:251 +#: pg_controldata.c:283 #, c-format msgid "Time of latest checkpoint: %s\n" -msgstr "Tidpunkt för senaste kontrollpunkt: %s\n" +msgstr "Tidpunkt för senaste checkpoint: %s\n" -#: pg_controldata.c:253 +#: pg_controldata.c:285 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "Beräknat LSN-tal av ologgade relationer: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:288 #, c-format msgid "Minimum recovery ending location: %X/%X\n" -msgstr "Slutläge för minsta Ã¥terställning: %X/%X\n" +msgstr "Minsta slutposition vid Ã¥terställning: %X/%X\n" -#: pg_controldata.c:259 +#: pg_controldata.c:291 #, c-format msgid "Min recovery ending loc's timeline: %u\n" -msgstr "Sluttid för minsta Ã¥terställning: %u\n" +msgstr "Tidslinje för min slutpos vid Ã¥terställning:%u\n" -#: pg_controldata.c:261 +#: pg_controldata.c:293 #, c-format msgid "Backup start location: %X/%X\n" msgstr "Startpunkt för backup: %X/%X\n" -#: pg_controldata.c:264 +#: pg_controldata.c:296 #, c-format msgid "Backup end location: %X/%X\n" msgstr "Slutpunkt för backup: %X/%X\n" -#: pg_controldata.c:267 +#: pg_controldata.c:299 #, c-format msgid "End-of-backup record required: %s\n" msgstr "Tvingande markering av backupslut: %s\n" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "no" msgstr "nej" -#: pg_controldata.c:268 +#: pg_controldata.c:300 msgid "yes" msgstr "ja" -#: pg_controldata.c:269 +#: pg_controldata.c:301 #, c-format msgid "wal_level setting: %s\n" msgstr "Värde pÃ¥ wal_level: %s\n" -#: pg_controldata.c:271 +#: pg_controldata.c:303 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "Värde pÃ¥ wal_log_hints: %s\n" -#: pg_controldata.c:273 +#: pg_controldata.c:305 #, c-format msgid "max_connections setting: %d\n" msgstr "Värde pÃ¥ max_connections: %d\n" -#: pg_controldata.c:275 +#: pg_controldata.c:307 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "Värde pÃ¥ max_worker_processes: %d\n" -#: pg_controldata.c:277 +#: pg_controldata.c:309 +#, c-format +msgid "max_wal_senders setting: %d\n" +msgstr "Värde pÃ¥ max_wal_senders setting %d\n" + +#: pg_controldata.c:311 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "Värde pÃ¥ max_prepared_xacts: %d\n" -#: pg_controldata.c:279 +#: pg_controldata.c:313 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "Nuvarande max_locks_per_xact: %d\n" -#: pg_controldata.c:281 +#: pg_controldata.c:315 #, c-format msgid "track_commit_timestamp setting: %s\n" -msgstr "Värde pÃ¥ track_commit_timestamp: %s\n" +msgstr "Värde pÃ¥ track_commit_timestamp: %s\n" -#: pg_controldata.c:283 +#: pg_controldata.c:317 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximal jämkning av data (alignment): %u\n" -#: pg_controldata.c:286 +#: pg_controldata.c:320 #, c-format msgid "Database block size: %u\n" msgstr "Databasens blockstorlek: %u\n" -#: pg_controldata.c:288 +#: pg_controldata.c:322 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Block per segment i en stor relation: %u\n" -#: pg_controldata.c:290 +#: pg_controldata.c:324 #, c-format msgid "WAL block size: %u\n" msgstr "Blockstorlek i transaktionsloggen: %u\n" -#: pg_controldata.c:292 +#: pg_controldata.c:326 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Segmentstorlek i transaktionsloggen: %u\n" -#: pg_controldata.c:294 +#: pg_controldata.c:328 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximal längd för identifierare: %u\n" -#: pg_controldata.c:296 +#: pg_controldata.c:330 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximalt antal kolonner i ett index: %u\n" -#: pg_controldata.c:298 +#: pg_controldata.c:332 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximal storlek för en TOAST-enhet: %u\n" -#: pg_controldata.c:300 +#: pg_controldata.c:334 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Storlek för large-object-enheter: %u\n" -#: pg_controldata.c:303 +#: pg_controldata.c:337 #, c-format msgid "Date/time type storage: %s\n" msgstr "Representation av dag och tid: %s\n" -#: pg_controldata.c:304 +#: pg_controldata.c:338 msgid "64-bit integers" msgstr "64-bitars heltal" -#: pg_controldata.c:305 +#: pg_controldata.c:339 #, c-format msgid "Float4 argument passing: %s\n" -msgstr "Ã…tkomst till float4-argument: %s\n" +msgstr "Överföring av float4-argument: %s\n" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by reference" -msgstr "referens" +msgstr "med referens" -#: pg_controldata.c:306 pg_controldata.c:308 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by value" -msgstr "värdeÃ¥tkomst" +msgstr "med värde" -#: pg_controldata.c:307 +#: pg_controldata.c:341 #, c-format msgid "Float8 argument passing: %s\n" -msgstr "Ã…tkomst till float8-argument: %s\n" +msgstr "Överföring av float8-argument: %s\n" -#: pg_controldata.c:309 +#: pg_controldata.c:343 #, c-format msgid "Data page checksum version: %u\n" msgstr "Checksummaversion för datasidor: %u\n" -#: pg_controldata.c:311 +#: pg_controldata.c:345 #, c-format msgid "Mock authentication nonce: %s\n" -msgstr "Fejkat authentiseringsvärde: %s\n" +msgstr "Fejkat authentiseringsvärde: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa fil \"%s\": %s\n" + +#~ msgid "%s: could not read file \"%s\": read %d of %d\n" +#~ msgstr "%s: kunde inte läsa fil \"%s\": läste %d av %d\n" + +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapportera fel till .\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" -#~ msgid "floating-point numbers" -#~ msgstr "flyttal" +#~ msgid "%s: no data directory specified\n" +#~ msgstr "%s: ingen datakatalog angiven.\n" diff --git a/src/bin/pg_controldata/po/tr.po b/src/bin/pg_controldata/po/tr.po new file mode 100644 index 00000000000..528889f2803 --- /dev/null +++ b/src/bin/pg_controldata/po/tr.po @@ -0,0 +1,555 @@ +# translation of pg_controldata.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2006. +# Nicolai TUFAR , 2004, 2005, 2006. +# Abdullah Gülner , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-11-27 07:46+0000\n" +"PO-Revision-Date: 2018-11-27 16:39+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../common/controldata_utils.c:62 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: \"%s\" dosyası okunmak için açılamadı: %s\n" + +#: ../../common/controldata_utils.c:78 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: \"%s\" dosyası okunamadı: %s\n" + +#: ../../common/controldata_utils.c:90 +#, c-format +msgid "%s: could not read file \"%s\": read %d of %d\n" +msgstr "" +"%1$s: \"%2$s\" dosyası okuma hatası: %4$d nin %3$d si okundu\n" + +#: ../../common/controldata_utils.c:112 +msgid "byte ordering mismatch" +msgstr "byte sıralama uyuÅŸmazlığı" + +#: ../../common/controldata_utils.c:114 +#, c-format +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not " +"match the one\n" +"used by this program. In that case the results below would be " +"incorrect, and\n" +"the PostgreSQL installation would be incompatible with this " +"data directory.\n" +msgstr "" +"UYARI: olası bayt sıralama uyumsuzluÄŸu\n" +"pg_control dosyasını saklamak için kullanılan bayt sıralaması, " +"bu program\n" +"tarafından kullanılan sıralama ile uyuÅŸmayabilir. Bu durumda " +"aÅŸağıdaki\n" +"sonuçlar yanlış olacak ve PostgreSQL kurulumu bu veri dizini " +"ile uyumsuz\n" +"olacaktır.\n" + +#: pg_controldata.c:34 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database " +"cluster.\n" +"\n" +msgstr "" +"%s PostgreSQL veritabanı kümesinin kontrol bilgisini " +"gösterir.\n" +"\n" + +#: pg_controldata.c:35 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_controldata.c:36 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [SEÇENEK] [DATADIR]\n" + +#: pg_controldata.c:37 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: pg_controldata.c:38 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR veri dizini\n" + +#: pg_controldata.c:39 +#, c-format +msgid "" +" -V, --version output version information, then " +"exit\n" +msgstr "" +" -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_controldata.c:41 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment " +"variable PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"EÄŸer hiçbir veri dizini (DATADIR) belirtilmezse, PGDATA " +"çevresel deÄŸiÅŸkeni\n" +"kullanılır.\n" +"\n" + +#: pg_controldata.c:43 +#, c-format +msgid "Report bugs to .\n" +msgstr "" +"Hataları adresine " +"bildirebilirsiniz.\n" + +#: pg_controldata.c:53 +msgid "starting up" +msgstr "baÅŸlıyor" + +#: pg_controldata.c:55 +msgid "shut down" +msgstr "kapat" + +#: pg_controldata.c:57 +msgid "shut down in recovery" +msgstr "kurtarma modunda kapatma" + +#: pg_controldata.c:59 +msgid "shutting down" +msgstr "kapanıyor" + +#: pg_controldata.c:61 +msgid "in crash recovery" +msgstr "çöküş (crash) kurtarma modunda" + +#: pg_controldata.c:63 +msgid "in archive recovery" +msgstr "arÅŸiv kurtarma modunda" + +#: pg_controldata.c:65 +msgid "in production" +msgstr "üretim modunda" + +#: pg_controldata.c:67 +msgid "unrecognized status code" +msgstr "tanımlayamayan durum kodu" + +#: pg_controldata.c:82 +msgid "unrecognized wal_level" +msgstr "tanımsız wal_level deÄŸeri" + +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "" +"Ayrıntılı bilgi için \"%s --help\" komutunu " +"kullanabilirsiniz.\n" + +#: pg_controldata.c:152 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: Çok fazla komut satırı girdisi var (ilki \"%s\")\n" + +#: pg_controldata.c:161 +#, c-format +msgid "%s: no data directory specified\n" +msgstr "%s: hiçbir veri dizini belirtilmedi\n" + +#: pg_controldata.c:169 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored " +"in file.\n" +"Either the file is corrupt, or it has a different layout than " +"this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"UYARI: Hesaplanan CRC kontrol toplamı dosyadakinden farklı.\n" +"Dosya zarar görmüş ya da bu programın beklediÄŸinden farklı \n" +"bir yapıya sahip olabilir. AÅŸağıdaki sonuçlar güvenilir " +"deÄŸildir.\n" +"\n" + +#: pg_controldata.c:178 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "UYARI: geçersiz WAL kesim boyutu (segment size)\n" + +#: pg_controldata.c:179 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a " +"power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results " +"below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a " +"power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results " +"below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +"Dosyada tutulan WAL segment boyutu, %d bayt, 1MB ve 1GB \n" +"arasında ikinin bir üssü deÄŸil. Dosya bozuk ve aÅŸağıdaki " +"sonuçlar\n" +"güvenilmez.\n" +msgstr[1] "" +"Dosyada tutulan WAL segment boyutu, %d bayt, 1MB ve 1GB \n" +"arasında ikinin bir üssü deÄŸil. Dosya bozuk ve aÅŸağıdaki " +"sonuçlar\n" +"güvenilmez.\n" + +#: pg_controldata.c:221 +msgid "???" +msgstr "???" + +#: pg_controldata.c:234 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_control sürüm numarası: %u\n" + +#: pg_controldata.c:236 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Katalog sürüm numarası: %u\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Database system identifier: %s\n" +msgstr "Veritabanı sistem belirteci: %s\n" + +#: pg_controldata.c:240 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Veritabanı kümesinin durumu: %s\n" + +#: pg_controldata.c:242 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "pg_control son düzenlenme tarihi: %s\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "En son checkpoint yeri: %X/%X\n" + +#: pg_controldata.c:247 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "En son checkpoint'in REDO yeri: %X/%X\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "En son checkpoint'in REDO WAL dosyası: %s\n" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "En son checkpoint'in TimeLineID'si: %u\n" + +#: pg_controldata.c:254 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "En son checkpoint'in PrevTimeLineID'si: %u\n" + +#: pg_controldata.c:256 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "En son checkpoint'in full_page_writes'ı: %s\n" + +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 +msgid "off" +msgstr "kapalı" + +#: pg_controldata.c:257 pg_controldata.c:302 pg_controldata.c:312 +msgid "on" +msgstr "açık" + +#: pg_controldata.c:258 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "En son checkpoint'in NextXID'si: %u:%u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "En son checkpoint'in NextOID'si: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "En son checkpoint'in NextMultiXactId'si: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "En son checkpoint'in NextMultiOffset'i: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "En son checkpoint'in oldestXID'si: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "En son checkpoint'in oldestXID'sini DB'si: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "En son checkpoint'in odestActiveXID'si: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "En son checkpoint'in oldestMultiXid'si: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "En son checkpoint'in oldestMulti'sinin DB'si: %u\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "En son checkpoint'in oldestCommitTsXid'si: %u\n" + +#: pg_controldata.c:279 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "En son checkpoint'in newestCommitTsXid'si: %u\n" + +#: pg_controldata.c:281 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "En son checkpoint'in zamanı: %s\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Loglanmayan nesneler için sahte LSN sayacı: %X/%X\n" + +#: pg_controldata.c:286 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Minimum kurtarma sonlandırma yeri: %X/%X\n" + +#: pg_controldata.c:289 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "" +"Minimum kurtarma sonlandırma yerinin zaman çizelgesi: %u\n" + +#: pg_controldata.c:291 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Yedek baÅŸlama yeri: %X/%X\n" + +#: pg_controldata.c:294 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Yedek bitiÅŸ yeri: %X/%X\n" + +#: pg_controldata.c:297 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Yedek sonu kaydı gerekiyor: %s\n" + +#: pg_controldata.c:298 +msgid "no" +msgstr "hayır" + +#: pg_controldata.c:298 +msgid "yes" +msgstr "evet" + +#: pg_controldata.c:299 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "wal_level ayarı: %s\n" + +#: pg_controldata.c:301 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "wal_log_hints ayarı: %s\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "max_connections ayarı: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "max_worker_processes ayarı: %d\n" + +#: pg_controldata.c:307 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "max_prepared_xacts ayarı: %d\n" + +#: pg_controldata.c:309 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "max_locks_per_xact ayarı: %d\n" + +#: pg_controldata.c:311 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "track_commit_timestamp ayarı: %s\n" + +#: pg_controldata.c:313 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Azami veri hizalama: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "Database block size: %u\n" +msgstr "Veritabanı blok boyutu: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Büyük iliÅŸkilerin parçası başına blok sayısı: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WAL blok boyutu: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "" +"Her bir WAL parçası başına byte sayısı: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Belirteçlerin en fazla uzunluÄŸu: %u\n" + +#: pg_controldata.c:326 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "İndekste en fazla kolon sayısı: %u\n" + +#: pg_controldata.c:328 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOAST parçasının en yüksek boyutu: %u\n" + +#: pg_controldata.c:330 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Bir büyük-nesne parçasının boyutu: %u\n" + +#: pg_controldata.c:333 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Tarih/zaman tipi saklanması: %s\n" + +#: pg_controldata.c:334 +msgid "64-bit integers" +msgstr "64-bit tamsayı" + +#: pg_controldata.c:335 +#, c-format +msgid "Float4 argument passing: %s\n" +msgstr "Float4 argument passing: %s\n" + +#: pg_controldata.c:336 pg_controldata.c:338 +msgid "by reference" +msgstr "referans ile" + +#: pg_controldata.c:336 pg_controldata.c:338 +msgid "by value" +msgstr "deÄŸer ile" + +#: pg_controldata.c:337 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8 argument passing: %s\n" + +#: pg_controldata.c:339 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "" +"Veri sayfası saÄŸlama (checksum) sürümü: %u\n" + +#: pg_controldata.c:341 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Sahte (mock) kimlik doÄŸrulaması nonce'u: %s\n" + +#~ msgid "" +#~ "Usage:\n" +#~ " %s [OPTION] [DATADIR]\n" +#~ "\n" +#~ "Options:\n" +#~ " --help show this help, then exit\n" +#~ " --version output version information, then exit\n" +#~ msgstr "" +#~ "Kullanımı:\n" +#~ " %s [SEÇENEK] [VERİ_DİZİNİ]\n" +#~ "\n" +#~ "SEÇENEKLER:\n" +#~ " --help bu yardımı gösterir ve sonra çıkar\n" +#~ " --version sürüm bilgisini gösterir ve çıkar\n" + +#~ msgid "floating-point numbers" +#~ msgstr "kayan noktalı sayılar" + +#~ msgid "Maximum length of locale name: %u\n" +#~ msgstr "Yerel adının en fazla büyüklüğü: %u\n" + +#~ msgid "LC_COLLATE: %s\n" +#~ msgstr "LC_COLLATE: %s\n" + +#~ msgid "LC_CTYPE: %s\n" +#~ msgstr "LC_CTYPE: %s\n" + +#~ msgid "Prior checkpoint location: %X/%X\n" +#~ msgstr "Önceki checkpoint yeri: %X/%X\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#~ msgid "" +#~ " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#~ msgid " [-D] DATADIR data directory\n" +#~ msgstr " [-D] DATADIR veri dizini\n" diff --git a/src/bin/pg_controldata/po/vi.po b/src/bin/pg_controldata/po/vi.po new file mode 100644 index 00000000000..019b7b05d86 --- /dev/null +++ b/src/bin/pg_controldata/po/vi.po @@ -0,0 +1,476 @@ +# LANGUAGE message translation file for pg_controldata +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_controldata (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_controldata (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:17+0000\n" +"PO-Revision-Date: 2018-05-04 22:20+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: ../../common/controldata_utils.c:61 +#, c-format +msgid "%s: could not open file \"%s\" for reading: %s\n" +msgstr "%s: không thể mở tệp \"%s\" để Ä‘á»c: %s\n" + +#: ../../common/controldata_utils.c:74 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: không Ä‘á»c được tệp \"%s\": %s\n" + +#: ../../common/controldata_utils.c:95 +msgid "byte ordering mismatch" +msgstr "thứ tá»± byte không khá»›p" + +#: ../../common/controldata_utils.c:97 +#, c-format +msgid "" +"WARNING: possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the " +"one\n" +"used by this program. In that case the results below would be incorrect, " +"and\n" +"the PostgreSQL installation would be incompatible with this data " +"directory.\n" +msgstr "" +"CẢNH BÃO: có thể sắp xếp thứ tá»± byte không khá»›p\n" +"Thứ tá»± byte được sá»­ dụng để lưu trữ tệp pg_control có thể không khá»›p vá»›i\n" +"cái được sá»­ dụng bởi chương trình này. Trong trưá»ng hợp đó, kết quả bên\n" +"dưới sẽ không chính xác và cài đặt PostgreSQL sẽ không tương thích vá»›i \n" +"thư mục dữ liệu này.\n" + +#: pg_controldata.c:34 +#, c-format +msgid "" +"%s displays control information of a PostgreSQL database cluster.\n" +"\n" +msgstr "" +"%s hiển thị thông tin Ä‘iá»u khiển cá»§a hệ thống cÆ¡ sở dữ liệu PostgreSQL.\n" +"\n" + +#: pg_controldata.c:35 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: pg_controldata.c:36 +#, c-format +msgid " %s [OPTION] [DATADIR]\n" +msgstr " %s [TÙY CHỌN] [DATADIR]\n" + +#: pg_controldata.c:37 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Options:\n" + +#: pg_controldata.c:38 +#, c-format +msgid " [-D,--pgdata=]DATADIR data directory\n" +msgstr " [-D,--pgdata=]DATADIR thư mục dữ liệu\n" + +#: pg_controldata.c:39 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr "" +" -V, --version hiện thị thông tin phiên bản, sau đó kết thúc\n" + +#: pg_controldata.c:40 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr "" +" -?, --help hiện thị ná»™i dung trợ giúp này, sau đó kết thúc\n" + +#: pg_controldata.c:41 +#, c-format +msgid "" +"\n" +"If no data directory (DATADIR) is specified, the environment variable " +"PGDATA\n" +"is used.\n" +"\n" +msgstr "" +"\n" +"Nếu thư mục cÆ¡ sở dữ liệu(DATADIR) không được chỉ định, biến môi trưá»ng \n" +"PGDATA sẽ được sá»­ dụng.\n" +"\n" + +#: pg_controldata.c:43 +#, c-format +msgid "Report bugs to .\n" +msgstr "Báo cáo lá»—i tá»›i .\n" + +#: pg_controldata.c:53 +msgid "starting up" +msgstr "Ä‘ang khởi động" + +#: pg_controldata.c:55 +msgid "shut down" +msgstr "Ä‘ang ngưng hoạt động" + +#: pg_controldata.c:57 +msgid "shut down in recovery" +msgstr "Ä‘ang ngưng hoạt động ở chế độ khôi phục" + +#: pg_controldata.c:59 +msgid "shutting down" +msgstr "Ä‘ang tắt" + +#: pg_controldata.c:61 +msgid "in crash recovery" +msgstr "Ä‘ang trong chế độ khôi phục sá»± cố" + +#: pg_controldata.c:63 +msgid "in archive recovery" +msgstr "Ä‘ang trong chế độ phục hồi từ archive log" + +#: pg_controldata.c:65 +msgid "in production" +msgstr "Ä‘ang hoạt động" + +#: pg_controldata.c:67 +msgid "unrecognized status code" +msgstr "mã trạng thái không được công nhận" + +#: pg_controldata.c:82 +msgid "unrecognized wal_level" +msgstr "wal_level không được công nhận" + +#: pg_controldata.c:136 pg_controldata.c:154 pg_controldata.c:162 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_controldata.c:152 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: quá nhiá»u đối số dòng lệnh (đầu tiên là \"%s\")\n" + +#: pg_controldata.c:161 +#, c-format +msgid "%s: no data directory specified\n" +msgstr "%s: không có thư mục dữ liệu nào được chỉ định\n" + +#: pg_controldata.c:169 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this " +"program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"WARNING: Giá trị kiểm tra CRC checksum không khá»›p vá»›i giá trị lưu trữ \n" +"trong tệp . Có thể tệp bị há»ng hoặc có bố cục khác vá»›i sá»± mong đợi cá»§a\n" +"chương trình này. Các kết quả dưới đây là không đáng tin cậy.\n" +"\n" + +#: pg_controldata.c:177 +#, c-format +msgid "" +"WARNING: invalid WAL segment size\n" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr "" +"CẢNH BÃO: kích thước phân Ä‘oạn WAL không hợp lệ\n" +"Kích thước phân Ä‘oạn WAL được lưu trữ trong tệp, %d byte, không phải \n" +"là lÅ©y thừa cá»§a hai từ 1 MB đến 1 GB. Có thể tệp bị há»ng và kết quả bên\n" +"dưới là không đáng tin cậy.\n" +"\n" + +#: pg_controldata.c:215 +msgid "???" +msgstr "???" + +#: pg_controldata.c:228 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "phiên bản pg_control: %u\n" + +#: pg_controldata.c:230 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Phiên bản catalog: %u\n" + +#: pg_controldata.c:232 +#, c-format +msgid "Database system identifier: %s\n" +msgstr "Số định dạng hệ thống database: %s\n" + +#: pg_controldata.c:234 +#, c-format +msgid "Database cluster state: %s\n" +msgstr "Trạng thái hệ thống database: %s\n" + +#: pg_controldata.c:236 +#, c-format +msgid "pg_control last modified: %s\n" +msgstr "pg_control sá»­a đổi lần cuối: %s\n" + +#: pg_controldata.c:238 +#, c-format +msgid "Latest checkpoint location: %X/%X\n" +msgstr "Vị trí checkpoint má»›i nhất: %X/%X\n" + +#: pg_controldata.c:241 +#, c-format +msgid "Latest checkpoint's REDO location: %X/%X\n" +msgstr "Vị trí REDO cá»§a checkpoint gần nhất: %X/%X\n" + +#: pg_controldata.c:244 +#, c-format +msgid "Latest checkpoint's REDO WAL file: %s\n" +msgstr "Tệp REDO WAL cá»§a checkpoint gần nhất: %s\n" + +#: pg_controldata.c:246 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "TimeLineID cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:248 +#, c-format +msgid "Latest checkpoint's PrevTimeLineID: %u\n" +msgstr "PrevTimeLineID cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:250 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Full_page_writes cá»§a checkpoint gần nhất: %s\n" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:306 +msgid "off" +msgstr "off" + +#: pg_controldata.c:251 pg_controldata.c:296 pg_controldata.c:306 +msgid "on" +msgstr "on" + +#: pg_controldata.c:252 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "NextXID cá»§a checkpoint gần nhất: %u:%u\n" + +#: pg_controldata.c:255 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "NextOID cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:257 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "NextMultiXactId cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:259 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "NextMultiOffset cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:261 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "OldestXID cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:263 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "OldestXID DB cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:265 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "OldestActiveXID cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:267 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "OldestMultiXid cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:269 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "OldestMulti DB cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:271 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "OldestCommitTsXid DB cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:273 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "NewestCommitTsXid cá»§a checkpoint gần nhất: %u\n" + +#: pg_controldata.c:275 +#, c-format +msgid "Time of latest checkpoint: %s\n" +msgstr "Thá»i gian cá»§a lần checkpoint gần nhấ: %s\n" + +#: pg_controldata.c:277 +#, c-format +msgid "Fake LSN counter for unlogged rels: %X/%X\n" +msgstr "Bá»™ đếm LSN giả cho các unlogged relations: %X/%X\n" + +#: pg_controldata.c:280 +#, c-format +msgid "Minimum recovery ending location: %X/%X\n" +msgstr "Tối thiểu hóa vị trí kết thúc cho phụ hồi: %X/%X\n" + +#: pg_controldata.c:283 +#, c-format +msgid "Min recovery ending loc's timeline: %u\n" +msgstr "Timeline cá»§a vị trí kết thúc phục hồi tối thiểu: %u\n" + +#: pg_controldata.c:285 +#, c-format +msgid "Backup start location: %X/%X\n" +msgstr "Vị trí bắt đầu Backup: %X/%X\n" + +#: pg_controldata.c:288 +#, c-format +msgid "Backup end location: %X/%X\n" +msgstr "Vị trí kết thúc Backup: %X/%X\n" + +#: pg_controldata.c:291 +#, c-format +msgid "End-of-backup record required: %s\n" +msgstr "Yêu cầu bản ghi kết thúc-backup : %s\n" + +#: pg_controldata.c:292 +msgid "no" +msgstr "no" + +#: pg_controldata.c:292 +msgid "yes" +msgstr "yes" + +#: pg_controldata.c:293 +#, c-format +msgid "wal_level setting: %s\n" +msgstr "giá trị thiết lập wal_level: %s\n" + +#: pg_controldata.c:295 +#, c-format +msgid "wal_log_hints setting: %s\n" +msgstr "giá trị thiết lập wal_log_hints: %s\n" + +#: pg_controldata.c:297 +#, c-format +msgid "max_connections setting: %d\n" +msgstr "giá trị thiết lập max_connections: %d\n" + +#: pg_controldata.c:299 +#, c-format +msgid "max_worker_processes setting: %d\n" +msgstr "giá trị thiết lập max_worker_processes: %d\n" + +#: pg_controldata.c:301 +#, c-format +msgid "max_prepared_xacts setting: %d\n" +msgstr "giá trị thiết lập max_prepared_xacts: %d\n" + +#: pg_controldata.c:303 +#, c-format +msgid "max_locks_per_xact setting: %d\n" +msgstr "giá trị thiết lập max_locks_per_xact: %d\n" + +#: pg_controldata.c:305 +#, c-format +msgid "track_commit_timestamp setting: %s\n" +msgstr "giá trị thiết lập track_commit_timestamp: %s\n" + +#: pg_controldata.c:307 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Căn chỉnh dữ liệu tối Ä‘a: %u\n" + +#: pg_controldata.c:310 +#, c-format +msgid "Database block size: %u\n" +msgstr "Kích thước block cÆ¡ sở dữ liệu: %u\n" + +#: pg_controldata.c:312 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "Số block cho má»—i phân Ä‘oạn cá»§a relation lá»›n: %u\n" + +#: pg_controldata.c:314 +#, c-format +msgid "WAL block size: %u\n" +msgstr "Kích thước block cá»§a WAL: %u\n" + +#: pg_controldata.c:316 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "Số byte cho má»—i phân Ä‘oạn WAL: %u\n" + +#: pg_controldata.c:318 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Äá»™ dài tối Ä‘a cho má»—i số nhận dạng: %u\n" + +#: pg_controldata.c:320 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Số lượng cá»™t tối Ä‘a cho má»™t index: %u\n" + +#: pg_controldata.c:322 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "Kích thước tối Ä‘a cá»§a Ä‘oạn TOAST: %u\n" + +#: pg_controldata.c:324 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Kích thước cá»§a má»™t Ä‘oạn đối tượng lá»›n: %u\n" + +#: pg_controldata.c:327 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Lưu trữ kiểu Date/time: %s\n" + +#: pg_controldata.c:328 +msgid "64-bit integers" +msgstr "64-bit integers" + +#: pg_controldata.c:329 +#, c-format +msgid "Float4 argument passing: %s\n" +msgstr "Thiết lập đối số float4: %s\n" + +#: pg_controldata.c:330 pg_controldata.c:332 +msgid "by reference" +msgstr "bằng cách tham chiếu" + +#: pg_controldata.c:330 pg_controldata.c:332 +msgid "by value" +msgstr "theo giá trị" + +#: pg_controldata.c:331 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Thiết lập đối số float8: %s\n" + +#: pg_controldata.c:333 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Phiên bản checksum page dữ liệu: %u\n" + +#: pg_controldata.c:335 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "Xác thá»±c giả tạm thá»i: %s\n" diff --git a/src/bin/pg_controldata/po/zh_CN.po b/src/bin/pg_controldata/po/zh_CN.po index 560c83a0790..a2cfd9ef6c4 100644 --- a/src/bin/pg_controldata/po/zh_CN.po +++ b/src/bin/pg_controldata/po/zh_CN.po @@ -4,8 +4,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_controldata (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:45+0000\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:15+0000\n" "PO-Revision-Date: 2016-05-19 20:40+0800\n" "Last-Translator: Yuwei Peng \n" "Language-Team: Chinese (Simplified) \n" @@ -15,7 +15,64 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.7\n" -#: pg_controldata.c:33 +#: ../../common/controldata_utils.c:73 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "为了读å–, 无法打开文件 \"%s\": %m" + +#: ../../common/controldata_utils.c:89 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %m" + +#: ../../common/controldata_utils.c:101 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "æ— æ³•è¯»å–æ–‡ä»¶\"%1$s\":读å–了%3$zu中的%2$d" + +#: ../../common/controldata_utils.c:117 ../../common/controldata_utils.c:259 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "无法关闭文件 \"%s\": %m" + +#: ../../common/controldata_utils.c:135 +msgid "byte ordering mismatch" +msgstr "字节排åºä¸åŒ¹é…" + +#: ../../common/controldata_utils.c:137 +#, fuzzy, c-format +#| msgid "" +#| "WARNING: possible byte ordering mismatch\n" +#| "The byte ordering used to store the pg_control file might not match the one\n" +#| "used by this program. In that case the results below would be incorrect, and\n" +#| "the PostgreSQL installation would be incompatible with this data directory.\n" +msgid "" +"possible byte ordering mismatch\n" +"The byte ordering used to store the pg_control file might not match the one\n" +"used by this program. In that case the results below would be incorrect, and\n" +"the PostgreSQL installation would be incompatible with this data directory." +msgstr "" +"警告: å¯èƒ½å­—节顺åºä¸åŒ¹é…\n" +"用于存储文件pg_control的字节顺åºå¯èƒ½ä¸Žç¨‹åºä½¿ç”¨çš„ä¸åŒ¹é…\n" +"åœ¨é‚£ç§æƒ…å†µä¸‹ç»“æžœå°†ä¼šæ˜¯ä¸æ­£ç¡®çš„,并且所安装的PostgreSQL\n" +"将会与这个数æ®ç›®å½•ä¸å…¼å®¹\n" + +#: ../../common/controldata_utils.c:203 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "无法打开文件 \"%s\": %m" + +#: ../../common/controldata_utils.c:224 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "无法写入文件 \"%s\": %m" + +#: ../../common/controldata_utils.c:245 +#, c-format +msgid "could not fsync file \"%s\": %m" +msgstr "无法 fsync 文件 \"%s\": %m" + +#: pg_controldata.c:36 #, c-format msgid "" "%s displays control information of a PostgreSQL database cluster.\n" @@ -24,17 +81,17 @@ msgstr "" "%s 显示 PostgreSQL æ•°æ®åº“簇控制信æ¯.\n" "\n" -#: pg_controldata.c:34 +#: pg_controldata.c:37 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_controldata.c:35 +#: pg_controldata.c:38 #, c-format msgid " %s [OPTION] [DATADIR]\n" msgstr " %s [选项][DATADIR]\n" -#: pg_controldata.c:36 +#: pg_controldata.c:39 #, c-format msgid "" "\n" @@ -43,27 +100,26 @@ msgstr "" "\n" "选项:\n" -#: pg_controldata.c:37 +#: pg_controldata.c:40 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR æ•°æ®ç›®å½•\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR æ•°æ®ç›®å½•\n" -#: pg_controldata.c:38 +#: pg_controldata.c:41 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version 输出版本信æ¯ï¼Œç„¶åŽé€€å‡º\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 输出版本信æ¯, ç„¶åŽé€€å‡º\n" -#: pg_controldata.c:39 +#: pg_controldata.c:42 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help 显示帮助信æ¯ï¼Œç„¶åŽé€€å‡º\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help 显示帮助, ç„¶åŽé€€å‡º\n" -#: pg_controldata.c:40 +#: pg_controldata.c:43 #, c-format msgid "" "\n" -"If no data directory (DATADIR) is specified, the environment variable " -"PGDATA\n" +"If no data directory (DATADIR) is specified, the environment variable PGDATA\n" "is used.\n" "\n" msgstr "" @@ -72,407 +128,384 @@ msgstr "" "环境å˜é‡PGDATA.\n" "\n" -#: pg_controldata.c:42 -#, c-format -msgid "Report bugs to .\n" +#: pg_controldata.c:45 +#, fuzzy, c-format +#| msgid "Report bugs to .\n" +msgid "Report bugs to .\n" msgstr "报告错误至 .\n" -#: pg_controldata.c:52 +#: pg_controldata.c:55 msgid "starting up" msgstr "正在å¯åЍ" -#: pg_controldata.c:54 +#: pg_controldata.c:57 msgid "shut down" msgstr "关闭" -#: pg_controldata.c:56 +#: pg_controldata.c:59 msgid "shut down in recovery" msgstr "在æ¢å¤è¿‡ç¨‹ä¸­å…³é—­æ•°æ®åº“" -#: pg_controldata.c:58 +#: pg_controldata.c:61 msgid "shutting down" msgstr "正在关闭" -#: pg_controldata.c:60 +#: pg_controldata.c:63 msgid "in crash recovery" msgstr "在æ¢å¤ä¸­" -#: pg_controldata.c:62 +#: pg_controldata.c:65 msgid "in archive recovery" msgstr "正在归档æ¢å¤" -#: pg_controldata.c:64 +#: pg_controldata.c:67 msgid "in production" msgstr "在è¿è¡Œä¸­" -#: pg_controldata.c:66 +#: pg_controldata.c:69 msgid "unrecognized status code" msgstr "ä¸è¢«è®¤å¯çš„状æ€ç " -#: pg_controldata.c:81 +#: pg_controldata.c:84 msgid "unrecognized wal_level" msgstr "傿•°wal_level的值无法识别" -#: pg_controldata.c:127 pg_controldata.c:145 pg_controldata.c:153 +#: pg_controldata.c:138 pg_controldata.c:156 pg_controldata.c:164 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "用 \"%s --help\" 显示更多的信æ¯.\n" -#: pg_controldata.c:143 -#, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" +#: pg_controldata.c:154 +#, fuzzy, c-format +#| msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" msgstr "%s: å‘½ä»¤è¡Œå‚æ•°å¤ªå¤š (第一个是 \"%s\")\n" -#: pg_controldata.c:152 -#, c-format -msgid "%s: no data directory specified\n" +#: pg_controldata.c:163 +#, fuzzy, c-format +#| msgid "%s: no data directory specified\n" +msgid "no data directory specified" msgstr "%s: 没有指定数æ®ç›®å½•\n" -#: pg_controldata.c:190 +#: pg_controldata.c:171 +#, c-format +msgid "" +"WARNING: Calculated CRC checksum does not match value stored in file.\n" +"Either the file is corrupt, or it has a different layout than this program\n" +"is expecting. The results below are untrustworthy.\n" +"\n" +msgstr "" +"警告: 计算出æ¥çš„CRC校验值与已ä¿å­˜åœ¨æ–‡ä»¶ä¸­çš„值ä¸åŒ¹é….\n" +"䏿˜¯æ–‡ä»¶å了,就是设计与程åºçš„æœŸæœ›å€¼ä¸åŒ.\n" +"下é¢çš„结果是ä¸å¯é çš„.\n" +"\n" + +#: pg_controldata.c:180 +#, c-format +msgid "WARNING: invalid WAL segment size\n" +msgstr "警告: 无效的WAL段大å°\n" + +#: pg_controldata.c:181 +#, c-format +msgid "" +"The WAL segment size stored in the file, %d byte, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgid_plural "" +"The WAL segment size stored in the file, %d bytes, is not a power of two\n" +"between 1 MB and 1 GB. The file is corrupt and the results below are\n" +"untrustworthy.\n" +"\n" +msgstr[0] "" +msgstr[1] "" + +#: pg_controldata.c:223 +msgid "???" +msgstr "???" + +#: pg_controldata.c:236 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control 版本: %u\n" -#: pg_controldata.c:192 +#: pg_controldata.c:238 #, c-format msgid "Catalog version number: %u\n" msgstr "Catalog 版本: %u\n" -#: pg_controldata.c:194 +#: pg_controldata.c:240 #, c-format msgid "Database system identifier: %s\n" msgstr "æ•°æ®åº“系统标识符: %s\n" -#: pg_controldata.c:196 +#: pg_controldata.c:242 #, c-format msgid "Database cluster state: %s\n" msgstr "æ•°æ®åº“簇状æ€: %s\n" -#: pg_controldata.c:198 +#: pg_controldata.c:244 #, c-format msgid "pg_control last modified: %s\n" msgstr "pg_control 最åŽä¿®æ”¹: %s\n" -#: pg_controldata.c:200 +#: pg_controldata.c:246 #, c-format msgid "Latest checkpoint location: %X/%X\n" msgstr "最新检查点ä½ç½®: %X/%X\n" -#: pg_controldata.c:203 -#, c-format -msgid "Prior checkpoint location: %X/%X\n" -msgstr "优先检查点ä½ç½®: %X/%X\n" - -#: pg_controldata.c:206 +#: pg_controldata.c:249 #, c-format msgid "Latest checkpoint's REDO location: %X/%X\n" msgstr "最新检查点的 REDO ä½ç½®: %X/%X\n" -#: pg_controldata.c:209 +#: pg_controldata.c:252 #, c-format msgid "Latest checkpoint's REDO WAL file: %s\n" msgstr "最新检查点的é‡åšæ—¥å¿—æ–‡ä»¶: %s\n" -#: pg_controldata.c:211 +#: pg_controldata.c:254 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "最新检查点的 TimeLineID: %u\n" -#: pg_controldata.c:213 +#: pg_controldata.c:256 #, c-format msgid "Latest checkpoint's PrevTimeLineID: %u\n" msgstr "最新检查点的PrevTimeLineID: %u\n" -#: pg_controldata.c:215 +#: pg_controldata.c:258 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "最新检查点的full_page_writes: %s\n" # help.c:48 -#: pg_controldata.c:216 pg_controldata.c:261 pg_controldata.c:271 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "off" msgstr "关闭" # help.c:48 -#: pg_controldata.c:216 pg_controldata.c:261 pg_controldata.c:271 +#: pg_controldata.c:259 pg_controldata.c:304 pg_controldata.c:316 msgid "on" msgstr "å¼€å¯" -#: pg_controldata.c:217 +#: pg_controldata.c:260 #, c-format -#| msgid "Latest checkpoint's NextXID: %u/%u\n" msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "最新检查点的NextXID: %u:%u\n" -#: pg_controldata.c:220 +#: pg_controldata.c:263 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "最新检查点的 NextOID: %u\n" -#: pg_controldata.c:222 +#: pg_controldata.c:265 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "最新检查点的NextMultiXactId: %u\n" -#: pg_controldata.c:224 +#: pg_controldata.c:267 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "最新检查点的NextMultiOffsetD: %u\n" -#: pg_controldata.c:226 +#: pg_controldata.c:269 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "最新检查点的oldestXID: %u\n" -#: pg_controldata.c:228 +#: pg_controldata.c:271 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "最新检查点的oldestXID所在的数æ®åº“:%u\n" -#: pg_controldata.c:230 +#: pg_controldata.c:273 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "最新检查点的oldestActiveXID: %u\n" -#: pg_controldata.c:232 +#: pg_controldata.c:275 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "最新检查点的oldestMultiXid: %u\n" -#: pg_controldata.c:234 +#: pg_controldata.c:277 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "最新检查点的oldestMulti所在的数æ®åº“:%u\n" -#: pg_controldata.c:236 +#: pg_controldata.c:279 #, c-format -#| msgid "Latest checkpoint's oldestCommitTs: %u\n" msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "最新检查点的oldestCommitTsXid:%u\n" -#: pg_controldata.c:238 +#: pg_controldata.c:281 #, c-format -#| msgid "Latest checkpoint's newestCommitTs: %u\n" msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "最新检查点的newestCommitTsXid:%u\n" -#: pg_controldata.c:240 +#: pg_controldata.c:283 #, c-format msgid "Time of latest checkpoint: %s\n" msgstr "最新检查点的时间: %s\n" -#: pg_controldata.c:242 +#: pg_controldata.c:285 #, c-format msgid "Fake LSN counter for unlogged rels: %X/%X\n" msgstr "ä¸å¸¦æ—¥å¿—的关系: %X/%X使用虚å‡çš„LSN计数器\n" -#: pg_controldata.c:245 +#: pg_controldata.c:288 #, c-format msgid "Minimum recovery ending location: %X/%X\n" msgstr "æœ€å°æ¢å¤ç»“æŸä½ç½®: %X/%X\n" -#: pg_controldata.c:248 +#: pg_controldata.c:291 #, c-format msgid "Min recovery ending loc's timeline: %u\n" msgstr "æœ€å°æ¢å¤ç»“æŸä½ç½®æ—¶é—´è¡¨: %u\n" -#: pg_controldata.c:250 +#: pg_controldata.c:293 #, c-format msgid "Backup start location: %X/%X\n" msgstr "开始进行备份的点ä½ç½®: %X/%X\n" -#: pg_controldata.c:253 +#: pg_controldata.c:296 #, c-format msgid "Backup end location: %X/%X\n" msgstr "备份的最终ä½ç½®: %X/%X\n" -#: pg_controldata.c:256 +#: pg_controldata.c:299 #, c-format msgid "End-of-backup record required: %s\n" msgstr "需è¦ç»ˆæ­¢å¤‡ä»½çš„记录: %s\n" -#: pg_controldata.c:257 +#: pg_controldata.c:300 msgid "no" msgstr "å¦" -#: pg_controldata.c:257 +#: pg_controldata.c:300 msgid "yes" msgstr "是" -#: pg_controldata.c:258 +#: pg_controldata.c:301 #, c-format msgid "wal_level setting: %s\n" msgstr "wal_level设置: %s\n" -#: pg_controldata.c:260 +#: pg_controldata.c:303 #, c-format msgid "wal_log_hints setting: %s\n" msgstr "wal_log_hints设置: %s\n" -#: pg_controldata.c:262 +#: pg_controldata.c:305 #, c-format msgid "max_connections setting: %d\n" msgstr "max_connections设置: %d\n" -#: pg_controldata.c:264 +#: pg_controldata.c:307 #, c-format msgid "max_worker_processes setting: %d\n" msgstr "max_worker_processes设置: %d\n" -#: pg_controldata.c:266 +#: pg_controldata.c:309 +#, fuzzy, c-format +#| msgid "max_connections setting: %d\n" +msgid "max_wal_senders setting: %d\n" +msgstr "max_connections设置: %d\n" + +#: pg_controldata.c:311 #, c-format msgid "max_prepared_xacts setting: %d\n" msgstr "max_prepared_xacts设置: %d\n" -#: pg_controldata.c:268 +#: pg_controldata.c:313 #, c-format msgid "max_locks_per_xact setting: %d\n" msgstr "max_locks_per_xact设置: %d\n" -#: pg_controldata.c:270 +#: pg_controldata.c:315 #, c-format msgid "track_commit_timestamp setting: %s\n" msgstr "track_commit_timestamp设置: %s\n" -#: pg_controldata.c:272 +#: pg_controldata.c:317 #, c-format msgid "Maximum data alignment: %u\n" msgstr "æœ€å¤§æ•°æ®æ ¡å‡†: %u\n" -#: pg_controldata.c:275 +#: pg_controldata.c:320 #, c-format msgid "Database block size: %u\n" msgstr "æ•°æ®åº“å—大å°: %u\n" -#: pg_controldata.c:277 +#: pg_controldata.c:322 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "å¤§å…³ç³»çš„æ¯æ®µå—æ•°: %u\n" -#: pg_controldata.c:279 +#: pg_controldata.c:324 #, c-format msgid "WAL block size: %u\n" msgstr "WALçš„å—大å°: %u\n" -#: pg_controldata.c:281 +#: pg_controldata.c:326 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "æ¯ä¸€ä¸ª WAL 段字节数: %u\n" -#: pg_controldata.c:283 +#: pg_controldata.c:328 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "标识符的最大长度: %u\n" -#: pg_controldata.c:285 +#: pg_controldata.c:330 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "在索引中å¯å…许使用最大的列数: %u\n" -#: pg_controldata.c:287 +#: pg_controldata.c:332 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "TOAST区å—的最大长度: %u\n" -#: pg_controldata.c:289 +#: pg_controldata.c:334 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "大对象区å—的大å°: %u\n" -#: pg_controldata.c:291 +#: pg_controldata.c:337 #, c-format msgid "Date/time type storage: %s\n" msgstr "日期/æ—¶é—´ 类型存储: %s\n" -#: pg_controldata.c:292 +#: pg_controldata.c:338 msgid "64-bit integers" msgstr "64使•´æ•°" -#: pg_controldata.c:292 -msgid "floating-point numbers" -msgstr "浮点数" - -#: pg_controldata.c:293 +#: pg_controldata.c:339 #, c-format msgid "Float4 argument passing: %s\n" msgstr "正在传递Flloat4ç±»åž‹çš„å‚æ•°: %s\n" -#: pg_controldata.c:294 pg_controldata.c:296 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by reference" msgstr "由引用" -#: pg_controldata.c:294 pg_controldata.c:296 +#: pg_controldata.c:340 pg_controldata.c:342 msgid "by value" msgstr "由值" -#: pg_controldata.c:295 +#: pg_controldata.c:341 #, c-format msgid "Float8 argument passing: %s\n" msgstr "正在传递Flloat8ç±»åž‹çš„å‚æ•°: %s\n" -#: pg_controldata.c:297 +#: pg_controldata.c:343 #, c-format msgid "Data page checksum version: %u\n" msgstr "æ•°æ®é¡µæ ¡éªŒå’Œç‰ˆæœ¬: %u\n" -#~ msgid "Latest checkpoint's StartUpID: %u\n" -#~ msgstr "最新检查点的 StartUpID: %u\n" - -#~ msgid "LC_CTYPE: %s\n" -#~ msgstr "LC_CTYPE: %s\n" - -#~ msgid "LC_COLLATE: %s\n" -#~ msgstr "LC_COLLATE: %s\n" - -#~ msgid "Maximum number of function arguments: %u\n" -#~ msgstr "å‡½æ•°å‚æ•°çš„æœ€å¤§ä¸ªæ•°: %u\n" - -#~ msgid "Latest checkpoint's UNDO location: %X/%X\n" -#~ msgstr "最新检查点的 UNDO ä½ç½®: %X/%X\n" - -#~ msgid "" -#~ "Usage:\n" -#~ " %s [OPTION] [DATADIR]\n" -#~ "\n" -#~ "Options:\n" -#~ " --help show this help, then exit\n" -#~ " --version output version information, then exit\n" -#~ msgstr "" -#~ "使用方法:\n" -#~ " %s [选项] [æ•°æ®ç›®å½•]\n" -#~ "\n" -#~ "选项:\n" -#~ " --help 显示此帮助信æ¯, ç„¶åŽé€€å‡º\n" -#~ " --version 显示 pg_controldata 的版本, ç„¶åŽé€€å‡º\n" - -#~ msgid "" -#~ "WARNING: possible byte ordering mismatch\n" -#~ "The byte ordering used to store the pg_control file might not match the " -#~ "one\n" -#~ "used by this program. In that case the results below would be incorrect, " -#~ "and\n" -#~ "the PostgreSQL installation would be incompatible with this data " -#~ "directory.\n" -#~ msgstr "" -#~ "警告: å¯èƒ½å­—节顺åºä¸åŒ¹é…\n" -#~ "用于存储文件pg_control的字节顺åºå¯èƒ½ä¸Žç¨‹åºä½¿ç”¨çš„ä¸åŒ¹é…\n" -#~ "åœ¨é‚£ç§æƒ…å†µä¸‹ç»“æžœå°†ä¼šæ˜¯ä¸æ­£ç¡®çš„,并且所安装的PostgreSQL\n" -#~ "将会与这个数æ®ç›®å½•ä¸å…¼å®¹\n" - -#~ msgid "" -#~ "WARNING: Calculated CRC checksum does not match value stored in file.\n" -#~ "Either the file is corrupt, or it has a different layout than this " -#~ "program\n" -#~ "is expecting. The results below are untrustworthy.\n" -#~ "\n" -#~ msgstr "" -#~ "警告: 计算出æ¥çš„CRC校验值与已ä¿å­˜åœ¨æ–‡ä»¶ä¸­çš„值ä¸åŒ¹é….\n" -#~ "䏿˜¯æ–‡ä»¶å了,就是设计与程åºçš„æœŸæœ›å€¼ä¸åŒ.\n" -#~ "下é¢çš„结果是ä¸å¯é çš„.\n" -#~ "\n" - -#~ msgid "%s: could not read file \"%s\": %s\n" -#~ msgstr "%s: æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %s\n" - -#~ msgid "%s: could not open file \"%s\" for reading: %s\n" -#~ msgstr "%s: 无法打开文件 \"%s\" 读å–ä¿¡æ¯: %s\n" +#: pg_controldata.c:345 +#, c-format +msgid "Mock authentication nonce: %s\n" +msgstr "当å‰èº«ä»½éªŒè¯: %s\n" diff --git a/src/bin/pg_controldata/t/001_pg_controldata.pl b/src/bin/pg_controldata/t/001_pg_controldata.pl index af9fad7a38b..3b63ad230fc 100644 --- a/src/bin/pg_controldata/t/001_pg_controldata.pl +++ b/src/bin/pg_controldata/t/001_pg_controldata.pl @@ -21,17 +21,21 @@ # check with a corrupted pg_control my $pg_control = $node->data_dir . '/global/pg_control'; -my $size = (stat($pg_control))[7]; +my $size = (stat($pg_control))[7]; open my $fh, '>', $pg_control or BAIL_OUT($!); binmode $fh; + # fill file with zeros print $fh pack("x[$size]"); close $fh; -command_checks_all([ 'pg_controldata', $node->data_dir ], - 0, - [ qr/WARNING: Calculated CRC checksum does not match value stored in file/, - qr/WARNING: invalid WAL segment size/ ], - [ qr/^$/ ], - 'pg_controldata with corrupted pg_control'); +command_checks_all( + [ 'pg_controldata', $node->data_dir ], + 0, + [ + qr/WARNING: Calculated CRC checksum does not match value stored in file/, + qr/WARNING: invalid WAL segment size/ + ], + [qr/^$/], + 'pg_controldata with corrupted pg_control'); diff --git a/src/bin/pg_ctl/Makefile b/src/bin/pg_ctl/Makefile index 02028538715..83cbf97ed88 100644 --- a/src/bin/pg_ctl/Makefile +++ b/src/bin/pg_ctl/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_ctl # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_ctl/Makefile diff --git a/src/bin/pg_ctl/nls.mk b/src/bin/pg_ctl/nls.mk index 0d8543e59ad..bc2059af037 100644 --- a/src/bin/pg_ctl/nls.mk +++ b/src/bin/pg_ctl/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_ctl/nls.mk CATALOG_NAME = pg_ctl -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv zh_CN +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN GETTEXT_FILES = pg_ctl.c ../../common/exec.c ../../common/fe_memutils.c ../../common/wait_error.c ../../port/path.c diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c index 143021de05f..dd76be6dd2e 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -2,7 +2,7 @@ * * pg_ctl --- start/stops/restarts the PostgreSQL server * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/bin/pg_ctl/pg_ctl.c * @@ -26,6 +26,8 @@ #include "catalog/pg_control.h" #include "common/controldata_utils.h" #include "common/file_perm.h" +#include "common/logging.h" +#include "common/string.h" #include "getopt_long.h" #include "utils/pidfile.h" @@ -61,6 +63,7 @@ typedef enum RELOAD_COMMAND, STATUS_COMMAND, PROMOTE_COMMAND, + LOGROTATE_COMMAND, KILL_COMMAND, REGISTER_COMMAND, UNREGISTER_COMMAND, @@ -100,13 +103,15 @@ static char version_file[MAXPGPATH]; static char pid_file[MAXPGPATH]; static char backup_file[MAXPGPATH]; static char promote_file[MAXPGPATH]; +static char logrotate_file[MAXPGPATH]; + +static volatile pgpid_t postmasterPID = -1; #ifdef WIN32 static DWORD pgctl_start_type = SERVICE_AUTO_START; static SERVICE_STATUS status; static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0; static HANDLE shutdownHandles[2]; -static pid_t postmasterPID = -1; #define shutdownEvent shutdownHandles[0] #define postmasterProcess shutdownHandles[1] @@ -125,6 +130,7 @@ static void do_restart(void); static void do_reload(void); static void do_status(void); static void do_promote(void); +static void do_logrotate(void); static void do_kill(pgpid_t pid); static void print_msg(const char *msg); static void adjust_data_dir(void); @@ -468,6 +474,20 @@ start_postmaster(void) /* fork succeeded, in child */ + /* + * If possible, detach the postmaster process from the launching process + * group and make it a group leader, so that it doesn't get signaled along + * with the current group that launched it. + */ +#ifdef HAVE_SETSID + if (setsid() < 0) + { + write_stderr(_("%s: could not start server due to setsid() failure: %s\n"), + progname, strerror(errno)); + exit(1); + } +#endif + /* * Since there might be quotes to handle here, it is easier simply to pass * everything to a shell to process them. Use exec so that the postmaster @@ -716,6 +736,30 @@ read_post_opts(void) } } +/* + * SIGINT signal handler used while waiting for postmaster to start up. + * Forwards the SIGINT to the postmaster process, asking it to shut down, + * before terminating pg_ctl itself. This way, if the user hits CTRL-C while + * waiting for the server to start up, the server launch is aborted. + */ +static void +trap_sigint_during_startup(int sig) +{ + if (postmasterPID != -1) + { + if (kill(postmasterPID, SIGINT) != 0) + write_stderr(_("%s: could not send stop signal (PID: %ld): %s\n"), + progname, (pgpid_t) postmasterPID, strerror(errno)); + } + + /* + * Clear the signal handler, and send the signal again, to terminate the + * process as normal. + */ + pqsignal(SIGINT, SIG_DFL); + raise(SIGINT); +} + static char * find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr) { @@ -824,6 +868,17 @@ do_start(void) if (do_wait) { + /* + * If the user interrupts the startup (e.g. with CTRL-C), we'd like to + * abort the server launch. Install a signal handler that will + * forward SIGINT to the postmaster process, while we wait. + * + * (We don't bother to reset the signal handler after the launch, as + * we're about to exit, anyway.) + */ + postmasterPID = pm_pid; + pqsignal(SIGINT, trap_sigint_during_startup); + print_msg(_("waiting for server to start...")); switch (wait_for_postmaster(pm_pid, false)) @@ -1171,6 +1226,62 @@ do_promote(void) print_msg(_("server promoting\n")); } +/* + * log rotate + */ + +static void +do_logrotate(void) +{ + FILE *logrotatefile; + pgpid_t pid; + + pid = get_pgpid(false); + + if (pid == 0) /* no pid file */ + { + write_stderr(_("%s: PID file \"%s\" does not exist\n"), progname, pid_file); + write_stderr(_("Is server running?\n")); + exit(1); + } + else if (pid < 0) /* standalone backend, not postmaster */ + { + pid = -pid; + write_stderr(_("%s: cannot rotate log file; " + "single-user server is running (PID: %ld)\n"), + progname, pid); + exit(1); + } + + snprintf(logrotate_file, MAXPGPATH, "%s/logrotate", pg_data); + + if ((logrotatefile = fopen(logrotate_file, "w")) == NULL) + { + write_stderr(_("%s: could not create log rotation signal file \"%s\": %s\n"), + progname, logrotate_file, strerror(errno)); + exit(1); + } + if (fclose(logrotatefile)) + { + write_stderr(_("%s: could not write log rotation signal file \"%s\": %s\n"), + progname, logrotate_file, strerror(errno)); + exit(1); + } + + sig = SIGUSR1; + if (kill((pid_t) pid, sig) != 0) + { + write_stderr(_("%s: could not send log rotation signal (PID: %ld): %s\n"), + progname, pid, strerror(errno)); + if (unlink(logrotate_file) != 0) + write_stderr(_("%s: could not remove log rotation signal file \"%s\": %s\n"), + progname, logrotate_file, strerror(errno)); + exit(1); + } + + print_msg(_("server signaled to rotate log file\n")); +} + /* * utility routines @@ -1371,14 +1482,14 @@ pgwin32_CommandLine(bool registration) appendPQExpBuffer(cmdLine, " -e \"%s\"", event_source); if (registration && do_wait) - appendPQExpBuffer(cmdLine, " -w"); + appendPQExpBufferStr(cmdLine, " -w"); /* Don't propagate a value from an environment variable. */ if (registration && wait_seconds_arg && wait_seconds != DEFAULT_WAIT) appendPQExpBuffer(cmdLine, " -t %d", wait_seconds); if (registration && silent_mode) - appendPQExpBuffer(cmdLine, " -s"); + appendPQExpBufferStr(cmdLine, " -s"); if (post_opts) { @@ -1615,7 +1726,7 @@ pgwin32_doRunAsService(void) /* * Mingw headers are incomplete, and so are the libraries. So we have to load * a whole lot of API functions dynamically. Since we have to do this anyway, - * also load the couple of functions that *do* exist in minwg headers but not + * also load the couple of functions that *do* exist in mingw headers but not * on NT4. That way, we don't break on NT4. */ typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ATTRIBUTES, DWORD, PLUID_AND_ATTRIBUTES, DWORD, PSID_AND_ATTRIBUTES, PHANDLE); @@ -1846,7 +1957,8 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, bool as_ser static PTOKEN_PRIVILEGES GetPrivilegesToDelete(HANDLE hToken) { - int i, j; + int i, + j; DWORD length; PTOKEN_PRIVILEGES tokenPrivs; LUID luidLockPages; @@ -1868,7 +1980,8 @@ GetPrivilegesToDelete(HANDLE hToken) return NULL; } - tokenPrivs = (PTOKEN_PRIVILEGES) malloc(length); + tokenPrivs = (PTOKEN_PRIVILEGES) pg_malloc_extended(length, + MCXT_ALLOC_NO_OOM); if (tokenPrivs == NULL) { write_stderr(_("%s: out of memory\n"), progname); @@ -1911,19 +2024,20 @@ do_help(void) { printf(_("%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n\n"), progname); printf(_("Usage:\n")); - printf(_(" %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n"), progname); - printf(_(" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" - " [-o OPTIONS] [-p PATH] [-c]\n"), progname); - printf(_(" %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"), progname); - printf(_(" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" - " [-o OPTIONS] [-c]\n"), progname); - printf(_(" %s reload [-D DATADIR] [-s]\n"), progname); - printf(_(" %s status [-D DATADIR]\n"), progname); - printf(_(" %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n"), progname); - printf(_(" %s kill SIGNALNAME PID\n"), progname); + printf(_(" %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n"), progname); + printf(_(" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" + " [-o OPTIONS] [-p PATH] [-c]\n"), progname); + printf(_(" %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n"), progname); + printf(_(" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" + " [-o OPTIONS] [-c]\n"), progname); + printf(_(" %s reload [-D DATADIR] [-s]\n"), progname); + printf(_(" %s status [-D DATADIR]\n"), progname); + printf(_(" %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n"), progname); + printf(_(" %s logrotate [-D DATADIR] [-s]\n"), progname); + printf(_(" %s kill SIGNALNAME PID\n"), progname); #ifdef WIN32 - printf(_(" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" - " [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n"), progname); + printf(_(" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" + " [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n"), progname); printf(_(" %s unregister [-N SERVICENAME]\n"), progname); #endif @@ -1973,7 +2087,7 @@ do_help(void) printf(_(" demand start service on demand\n")); #endif - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } @@ -2105,9 +2219,8 @@ adjust_data_dir(void) pclose(fd); free(my_exec_path); - /* Remove trailing newline */ - if (strchr(filename, '\n') != NULL) - *strchr(filename, '\n') = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(filename); free(pg_data); pg_data = pg_strdup(filename); @@ -2120,7 +2233,7 @@ get_control_dbstate(void) { DBState ret; bool crc_ok; - ControlFileData *control_file_data = get_controlfile(pg_data, progname, &crc_ok); + ControlFileData *control_file_data = get_controlfile(pg_data, &crc_ok); if (!crc_ok) { @@ -2157,10 +2270,7 @@ main(int argc, char **argv) int c; pgpid_t killproc = 0; -#ifdef WIN32 - setvbuf(stderr, NULL, _IONBF, 0); -#endif - + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl")); start_time = time(NULL); @@ -2336,6 +2446,8 @@ main(int argc, char **argv) ctl_command = STATUS_COMMAND; else if (strcmp(argv[optind], "promote") == 0) ctl_command = PROMOTE_COMMAND; + else if (strcmp(argv[optind], "logrotate") == 0) + ctl_command = LOGROTATE_COMMAND; else if (strcmp(argv[optind], "kill") == 0) { if (argc - optind < 3) @@ -2442,6 +2554,9 @@ main(int argc, char **argv) case PROMOTE_COMMAND: do_promote(); break; + case LOGROTATE_COMMAND: + do_logrotate(); + break; case KILL_COMMAND: do_kill(killproc); break; diff --git a/src/bin/pg_ctl/po/cs.po b/src/bin/pg_ctl/po/cs.po index 4a36b67f140..f2d765bf1ec 100644 --- a/src/bin/pg_ctl/po/cs.po +++ b/src/bin/pg_ctl/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_ctl-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-09-23 20:18+0000\n" -"PO-Revision-Date: 2013-12-01 20:46-0500\n" +"POT-Creation-Date: 2018-07-13 19:45+0000\n" +"PO-Revision-Date: 2018-07-13 23:48+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,147 +16,151 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" -#: ../../common/fe_memutils.c:33 ../../common/fe_memutils.c:60 -#: ../../common/fe_memutils.c:83 -#, c-format -msgid "out of memory\n" -msgstr "nedostatek pamÄ›ti\n" - -#: ../../common/fe_memutils.c:77 -#, c-format -msgid "cannot duplicate null pointer (internal error)\n" -msgstr "nelze duplikovat null pointer (interní chyba)\n" - -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" -msgstr "nelze získat aktuální adresář: %s" +msgstr "nelze identifikovat aktuální adresář: %s" -#: ../../port/exec.c:146 +#: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" msgstr "neplatný binární soubor\"%s\"" -#: ../../port/exec.c:195 +#: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "nelze Äíst binární soubor \"%s\"" -#: ../../port/exec.c:202 +#: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" -msgstr "nelze najít spustitelný soubor \"%s\"" +msgstr "nelze najít soubor \"%s\" ke spuÅ¡tÄ›ní" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "nelze zmÄ›nit adresář na \"%s\" : %s" -#: ../../port/exec.c:272 +#: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "nelze Äíst symbolický link \"%s\"" -#: ../../port/exec.c:523 +#: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "volání pclose selhalo: %s" -#: ../../port/wait_error.c:47 +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 +#: ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek pamÄ›ti\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "příkaz není spustitelný" -#: ../../port/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "příkaz nenalezen" -#: ../../port/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "potomek skonÄil s návratovým kódem %d" -#: ../../port/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "potomek byl ukonÄen vyjímkou 0x%X" -#: ../../port/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "potomek byl ukonÄen signálem %s" -#: ../../port/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "potomek byl ukonÄen signálem %d" -#: ../../port/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "potomek skonÄil s nerozponaným stavem %d" -#: pg_ctl.c:253 +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "nelze získat aktuální pracovní adresář: %s\n" + +#: pg_ctl.c:257 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: adresář \"%s\" neexistuje\n" + +#: pg_ctl.c:260 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: nelze otevřít adresář \"%s\": %s\n" + +#: pg_ctl.c:273 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: adresář \"%s\" není datový adresář databázového clusteru\n" + +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: nelze otevřít PID soubor \"%s\": %s\n" -#: pg_ctl.c:262 +#: pg_ctl.c:295 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: PID soubor \"%s\" je prázdný\n" -#: pg_ctl.c:265 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: neplatná data v PID souboru \"%s\"\n" -#: pg_ctl.c:477 -#, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: -w volba není podporována pÅ™i startu pre-9.1 serveru\n" - -#: pg_ctl.c:547 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: -w volba nemůže používat relativnÄ› zadaný adresář socketu\n" +msgid "%s: could not start server: %s\n" +msgstr "%s: nelze nastartovat server: %s\n" -#: pg_ctl.c:595 +#: pg_ctl.c:511 #, c-format -msgid "" -"\n" -"%s: this data directory appears to be running a pre-existing postmaster\n" -msgstr "" -"\n" -"%s: zdá se že v tomto datovém adresáři již běží existující postmaster\n" +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: nelze nastartovat server: chybový kód %lu\n" -#: pg_ctl.c:645 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: nelze nastavit limit pro core soubor; zakázáno hard limitem\n" -#: pg_ctl.c:670 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: nelze Äíst soubor \"%s\"\n" -#: pg_ctl.c:675 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: soubor s volbami \"%s\" musí mít pÅ™esnÄ› jednu řádku\n" -#: pg_ctl.c:723 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -167,7 +171,7 @@ msgstr "" "adresáři jako \"%s\".\n" "Zkontrolujte vaÅ¡i instalaci.\n" -#: pg_ctl.c:729 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -178,42 +182,38 @@ msgstr "" "ale nebyl ve stejné verzi jako %s.\n" "Zkontrolujte vaÅ¡i instalaci.\n" -#: pg_ctl.c:762 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: inicializace databáze selhala\n" -#: pg_ctl.c:777 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: další server možná běží; i tak zkouším start\n" -#: pg_ctl.c:814 -#, c-format -msgid "%s: could not start server: exit code was %d\n" -msgstr "%s: nelze nastartovat server: návratový kód byl %d\n" - -#: pg_ctl.c:821 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "Äekám na start serveru ..." -#: pg_ctl.c:826 pg_ctl.c:927 pg_ctl.c:1018 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr " hotovo\n" -#: pg_ctl.c:827 +#: pg_ctl.c:833 msgid "server started\n" msgstr "server spuÅ¡tÄ›n\n" -#: pg_ctl.c:830 pg_ctl.c:834 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " pÅ™estávám Äekat\n" -#: pg_ctl.c:831 -msgid "server is still starting up\n" -msgstr "server stále startuje\n" +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: server nenastartoval v Äasovém limitu\n" -#: pg_ctl.c:835 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -222,44 +222,35 @@ msgstr "" "%s: nelze spustit server\n" "Zkontrolujte záznam v logu.\n" -#: pg_ctl.c:841 pg_ctl.c:919 pg_ctl.c:1009 -msgid " failed\n" -msgstr " selhalo\n" - -#: pg_ctl.c:842 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: nelze Äekat na server kvůli chybné konfiguraci\n" - -#: pg_ctl.c:848 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "server startuje\n" -#: pg_ctl.c:863 pg_ctl.c:949 pg_ctl.c:1039 pg_ctl.c:1079 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: PID soubor \"%s\" neexistuje\n" -#: pg_ctl.c:864 pg_ctl.c:951 pg_ctl.c:1040 pg_ctl.c:1080 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "Běží server?\n" -#: pg_ctl.c:870 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "" "%s: nemohu zastavit server; postgres běží v single-user módu (PID: %ld)\n" -#: pg_ctl.c:878 pg_ctl.c:973 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: nelze poslat stop signál (PID: %ld): %s\n" -#: pg_ctl.c:885 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "server se ukonÄuje\n" -#: pg_ctl.c:900 pg_ctl.c:988 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -269,16 +260,20 @@ msgstr "" "Shutdown nebude ukonÄen dokud nebude zavolán pg_stop_backup().\n" "\n" -#: pg_ctl.c:904 pg_ctl.c:992 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "Äekám na ukonÄení serveru ..." -#: pg_ctl.c:921 pg_ctl.c:1011 +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr " selhalo\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: server se neukonÄuje\n" -#: pg_ctl.c:923 pg_ctl.c:1013 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -286,269 +281,304 @@ msgstr "" "TIP: Volba \"-m fast\" okamžitÄ› ukonÄí sezení namísto aby Äekala\n" "na odpojení iniciované přímo session.\n" -#: pg_ctl.c:929 pg_ctl.c:1019 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "server zastaven\n" -#: pg_ctl.c:952 pg_ctl.c:1025 -msgid "starting server anyway\n" -msgstr "pÅ™esto server spouÅ¡tím\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "pÅ™esto zkouším server spustit\n" -#: pg_ctl.c:961 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "" "%s: nemohu restartovat server; postgres běží v single-user módu (PID: %ld)\n" -#: pg_ctl.c:964 pg_ctl.c:1049 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" msgstr "Prosím ukonÄete single-user postgres a zkuste to znovu.\n" -#: pg_ctl.c:1023 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: starý proces serveru (PID: %ld) zÅ™ejmÄ› skonÄil\n" -#: pg_ctl.c:1046 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "pÅ™esto server spouÅ¡tím\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "" "%s: nemohu znovunaÄíst server; server běží v single-user módu (PID: %ld)\n" -#: pg_ctl.c:1055 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: nelze poslat signál pro reload (PID: %ld): %s\n" -#: pg_ctl.c:1060 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "server obdržel signál\n" -#: pg_ctl.c:1086 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "" "%s: nelze povýšit (promote) server; server běží v single-user módu (PID: " "%ld)\n" -#: pg_ctl.c:1095 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: nelze povýšit (promote) server; server není ve standby módu\n" -#: pg_ctl.c:1110 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" -msgstr "%s: nelze vytvoÅ™it signální soubor pro povýšení (promote) \"%s\": %s\n" +msgstr "" +"%s: nelze vytvoÅ™it signální soubor pro povýšení (promote) \"%s\": %s\n" -#: pg_ctl.c:1116 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "" "%s: nelze zapsat do signálního souboru pro povýšení (promote) \"%s\": %s\n" -#: pg_ctl.c:1124 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: nelze poslat signál pro povýšení (promote, PID: %ld): %s\n" -#: pg_ctl.c:1127 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "" "%s: nelze odstranit signální soubor pro povýšení (promote) \"%s\": %s\n" -#: pg_ctl.c:1132 +#: pg_ctl.c:1146 +msgid "waiting for server to promote..." +msgstr "Äekám na promote serveru ..." + +#: pg_ctl.c:1160 +msgid "server promoted\n" +msgstr "server je povyÅ¡ován (promote)\n" + +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: server neprovedl promote v Äasovém intervalu\n" + +#: pg_ctl.c:1171 msgid "server promoting\n" msgstr "server je povyÅ¡ován (promote)\n" -#: pg_ctl.c:1179 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: server běží v single-user módu (PID: %ld)\n" -#: pg_ctl.c:1191 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: server běží (PID: %ld)\n" -#: pg_ctl.c:1202 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: žádný server neběží\n" -#: pg_ctl.c:1220 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: nelze poslat signál pro reload %d (PID: %ld): %s\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: nelze najít vlastní spustitelný soubor\n" -#: pg_ctl.c:1264 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: nelze najít spustitelný program postgres\n" -#: pg_ctl.c:1329 pg_ctl.c:1361 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: nelze otevřít manažera služeb\n" -#: pg_ctl.c:1335 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: služba \"%s\" je již registrována\n" -#: pg_ctl.c:1346 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: nelze zaregistrovat službu \"%s\": chybový kód %lu\n" -#: pg_ctl.c:1367 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: služba \"%s\" není registrována\n" -#: pg_ctl.c:1374 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: nelze otevřít službu \"%s\": chybový kód %lu\n" -#: pg_ctl.c:1381 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: nelze odregistrovat službu \"%s\": chybový kód %lu\n" -#: pg_ctl.c:1466 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" -msgstr "Äekám na start serveru ...\n" +msgstr "ÄŒekám na start serveru ...\n" -#: pg_ctl.c:1469 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "ÄŒasový limit pro Äekání na start serveru vyprÅ¡el\n" -#: pg_ctl.c:1473 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "Server nastartoval a pÅ™ijímá spojení\n" -#: pg_ctl.c:1517 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: nelze nastartovat službu \"%s\": chybový kód %lu\n" -#: pg_ctl.c:1589 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: VAROVÃNÃ: na této platformÄ› nelze vytvoÅ™it tajné tokeny\n" -#: pg_ctl.c:1598 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: nelze otevřít token procesu: chybový kód %lu\n" -#: pg_ctl.c:1611 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: nelze alokovat SIDs: chybový kód %lu\n" -#: pg_ctl.c:1630 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: nelze vytvoÅ™it vyhrazený token: chybový kód %lu\n" -#: pg_ctl.c:1668 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "" "%s: VAROVÃNÃ: v systémovém API nelze najít vÅ¡echny \"job object\" funkce\n" -#: pg_ctl.c:1754 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: nelze získat seznam LUID pro privilegia: chybový kód %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: nelze získat informace o tokenu: chybový kód %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: nedostatek pamÄ›ti\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: pg_ctl.c:1762 +#: pg_ctl.c:1913 #, c-format msgid "" -"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"%s is a utility to initialize, start, stop, or control a PostgreSQL " +"server.\n" "\n" msgstr "" "%s je nástroj pro inicializaci, spuÅ¡tÄ›ní, zastavení, nebo ovládání " "PostgreSQL serveru.\n" "\n" -#: pg_ctl.c:1763 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: pg_ctl.c:1764 +#: pg_ctl.c:1915 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n" -msgstr " %s init[db] [-D ADRESÃŘ] [-s] [-o \"PŘEPÃNAÄŒE\"]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D ADRESÃŘ] [-s] [-o PŘEPÃNAÄŒE]\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1916 #, c-format msgid "" -" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" -"\"]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-w] [-t SECS] [-D ADRESÃŘ] [-s] [-l SOUBOR] [-o \"PŘEPÃNAÄŒE" -"\"]\n" +" %s start [-D ADRESÃŘ] [-l SOUBOR] [-W] [-t SECS] [-s]\n" +" [-o VOLBY] [-p CESTA] [-c]\n" -#: pg_ctl.c:1766 +#: pg_ctl.c:1918 #, c-format -msgid " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -msgstr " %s stop [-W] [-t SECS] [-D ADRESÃŘ] [-s] [-m MÓD-UKONÄŒENÃ]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D ADRESÃŘ] [-m MÓD-UKONÄŒENÃ] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1767 +#: pg_ctl.c:1919 #, c-format msgid "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-w] [-t SECS] [-D ADRESÃŘ] [-s] [-m MÓD-UKONÄŒENÃ]\n" -" [-o \"PŘEPÃNAÄŒE\"]\n" +" %s restart [-D ADRESÃŘ] [-m MÓD-UKONÄŒENÃ] [-W] [-t SECS] [-s]\n" +" [-o VOLBY] [-c]\n" -#: pg_ctl.c:1769 +#: pg_ctl.c:1921 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D ADRESÃŘ] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D ADRESÃŘ] [-s]\n" -#: pg_ctl.c:1770 +#: pg_ctl.c:1922 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D ADRESÃŘ]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D ADRESÃŘ]\n" -#: pg_ctl.c:1771 +#: pg_ctl.c:1923 #, c-format -#| msgid " %s reload [-D DATADIR] [-s]\n" -msgid " %s promote [-D DATADIR] [-s]\n" -msgstr " %s promote [-D ADRESÃŘ] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D ADRESÃŘ] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1772 +#: pg_ctl.c:1924 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill SIGNÃL IDPROCESU\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNÃL IDPROCESU\n" -#: pg_ctl.c:1774 +#: pg_ctl.c:1926 #, c-format msgid "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" msgstr "" -" %s register [-N NÃZEVSLUŽBY] [-U UŽIVATEL] [-P HESLO] [-D ADRESÃŘ]\n" -" [-w] [-o \"VOLBY\"]\n" +" %s register [-D ADRESÃŘ] [-N NÃZEVSLUŽBY] [-U UŽIVATEL] [-P HESLO]\n" +" [-S MÓD-STARTU] [-e ZDROJ] [-W] [-t SECS] [-s] [-o " +"VOLBY]\n" -#: pg_ctl.c:1776 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N SERVICENAME]\n" -#: pg_ctl.c:1779 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" @@ -557,58 +587,60 @@ msgstr "" "\n" "SpoleÄné pÅ™epínaÄe:\n" -#: pg_ctl.c:1780 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=ADRESÃŘ umístÄ›ní úložiÅ¡tÄ› databáze\n" -#: pg_ctl.c:1781 +#: pg_ctl.c:1934 +#, c-format +msgid "" +" -e SOURCE event source for logging when running as a " +"service\n" +msgstr "" +" -e SOURCE název zdroje pro logování pÅ™i bÄ›hu jako služba\n" + +#: pg_ctl.c:1936 #, c-format -msgid " -s, --silent only print errors, no informational messages\n" +msgid "" +" -s, --silent only print errors, no informational messages\n" msgstr "" " -s, --silent vypisuj jen chyby, žádné informativní zprávy\n" -#: pg_ctl.c:1782 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr "" " -t, --timeout=SECS poÄet vteÅ™in pro Äekání pÅ™i využití volby -w\n" -#: pg_ctl.c:1783 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version vypsat informace o verzi, potom skonÄit\n" -#: pg_ctl.c:1784 +#: pg_ctl.c:1939 #, c-format -msgid " -w wait until operation completes\n" -msgstr " -w Äekat na dokonÄení operace\n" +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait Äekat na dokonÄení operace (výchozí)\n" -#: pg_ctl.c:1785 +#: pg_ctl.c:1940 #, c-format -msgid " -W do not wait until operation completes\n" -msgstr " -W neÄekat na dokonÄení operace\n" +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait neÄekat na dokonÄení operace\n" -#: pg_ctl.c:1786 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help vypsat tuto nápovÄ›du, potom skonÄit\n" -#: pg_ctl.c:1787 +#: pg_ctl.c:1942 #, c-format msgid "" -"(The default is to wait for shutdown, but not for start or restart.)\n" -"\n" +"If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "" -"(Implicitní chování je Äekat na ukonÄení, ale ne pÅ™i startu nebo restartu.)\n" -"\n" - -#: pg_ctl.c:1788 -#, c-format -msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" -msgstr "Pokud je vynechán parametr -D, použije se promÄ›nná prostÅ™edí PGDATA.\n" +"Pokud je vynechán parametr -D, použije se promÄ›nná prostÅ™edí PGDATA.\n" -#: pg_ctl.c:1790 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" @@ -617,54 +649,54 @@ msgstr "" "\n" "PÅ™epínaÄe pro start nebo restart:\n" -#: pg_ctl.c:1792 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files povolit postgresu vytvářet core soubory\n" -#: pg_ctl.c:1794 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files nepoužitelné pro tuto platformu\n" -#: pg_ctl.c:1796 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr "" -" -l, --log=SOUBOR zapisuj (nebo pÅ™ipoj na konec) log serveru do " +" -l, --log=SOUBOR zapisuj (nebo pÅ™ipoj na konec) log serveru do " "SOUBORU.\n" -#: pg_ctl.c:1797 +#: pg_ctl.c:1951 #, c-format msgid "" -" -o OPTIONS command line options to pass to postgres\n" +" -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n" msgstr "" -" -o PŘEPÃNAÄŒE pÅ™epínaÄe, které budou pÅ™edány postgresu\n" -" (spustitelnému souboru PostgreSQL) Äi initdb\n" +" -o, --options=VOLBY pÅ™epínaÄe, které budou pÅ™edány postgresu\n" +" (spustitelnému souboru PostgreSQL) Äi initdb\n" -#: pg_ctl.c:1799 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" -msgstr " -p CESTA-K-POSTGRESU za normálních okolností není potÅ™eba\n" +msgstr " -p CESTA-K-POSTGRESU za normálních okolností není potÅ™eba\n" -#: pg_ctl.c:1800 +#: pg_ctl.c:1954 #, c-format msgid "" "\n" -"Options for stop, restart, or promote:\n" +"Options for stop or restart:\n" msgstr "" "\n" -"PÅ™epínaÄe pro zastavení, restart a promote:\n" +"PÅ™epínaÄe pro start nebo restart:\n" -#: pg_ctl.c:1801 +#: pg_ctl.c:1955 #, c-format msgid "" " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr "" " -m, --mode=MODE může být \"smart\", \"fast\", or \"immediate\"\n" -#: pg_ctl.c:1803 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -673,26 +705,27 @@ msgstr "" "\n" "Módy ukonÄení jsou:\n" -#: pg_ctl.c:1804 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart skonÄi potom, co se odpojí vÅ¡ichni klienti\n" -#: pg_ctl.c:1805 +#: pg_ctl.c:1959 #, c-format -msgid " fast quit directly, with proper shutdown\n" -msgstr " fast skonÄi okamžitÄ›, s korektním zastavením serveru\n" +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr "" +" fast skonÄi okamžitÄ›, s korektním zastavením serveru (výchozí)\n" -#: pg_ctl.c:1806 +#: pg_ctl.c:1960 #, c-format msgid "" " immediate quit without complete shutdown; will lead to recovery on " "restart\n" msgstr "" -" immediate skonÄi bez kompletního zastavení; další start " -"provede obnovu po pádu (crash recovery)\n" +" immediate skonÄi bez kompletního zastavení; po restartu se provede\n" +" obnova po pádu (crash recovery)\n" -#: pg_ctl.c:1808 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -701,7 +734,7 @@ msgstr "" "\n" "Povolené signály pro \"kill\":\n" -#: pg_ctl.c:1812 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" @@ -710,30 +743,31 @@ msgstr "" "\n" "PÅ™epínaÄe pro register nebo unregister:\n" -#: pg_ctl.c:1813 +#: pg_ctl.c:1967 #, c-format msgid "" " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr "" " -N SERVICENAME jméno služby, pod kterým registrovat PostgreSQL server\n" -#: pg_ctl.c:1814 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P PASSWORD heslo k úÄtu pro registraci PostgreSQL serveru\n" -#: pg_ctl.c:1815 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" -msgstr " -U USERNAME uživatelské jméno pro registraci PostgreSQL server\n" +msgstr "" +" -U USERNAME uživatelské jméno pro registraci PostgreSQL server\n" -#: pg_ctl.c:1816 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr "" " -S TYP-STARTU typ spuÅ¡tÄ›ní služby pro registraci PostgreSQL serveru\n" -#: pg_ctl.c:1818 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" @@ -742,19 +776,19 @@ msgstr "" "\n" "Módy spuÅ¡tÄ›ní jsou:\n" -#: pg_ctl.c:1819 +#: pg_ctl.c:1973 #, c-format msgid "" " auto start service automatically during system startup (default)\n" msgstr "" " auto spusÅ¥ službu automaticky bÄ›hem startu systému (implicitní)\n" -#: pg_ctl.c:1820 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" msgstr " demand spusÅ¥ službu na vyžádání\n" -#: pg_ctl.c:1823 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -763,27 +797,32 @@ msgstr "" "\n" "Chyby hlaste na adresu .\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: neplatný mód ukonÄení mode \"%s\"\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: neplatné jméno signálu \"%s\"\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: neplatný typ spuÅ¡tÄ›ní \"%s\"\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: nelze najít datový adresář pomocí příkazu \"%s\"\n" -#: pg_ctl.c:2023 +#: pg_ctl.c:2128 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: control file se zdá být poÅ¡kozený\n" + +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -794,32 +833,32 @@ msgstr "" "Prosím pÅ™ihlaste se jako (neprivilegovaný) uživatel, který bude vlastníkem\n" "serverového procesu (například pomocí příkazu \"su\").\n" -#: pg_ctl.c:2094 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: -S nepoužitelné pro tuto platformu\n" -#: pg_ctl.c:2136 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: příliÅ¡ mnoho argumentů v příkazové řádce (první je \"%s\")\n" -#: pg_ctl.c:2160 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: chýbÄ›jící parametr pro \"kill\" mód\n" -#: pg_ctl.c:2178 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: neplatný mód operace \"%s\"\n" -#: pg_ctl.c:2188 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: není specifikována operace\n" -#: pg_ctl.c:2209 +#: pg_ctl.c:2393 #, c-format msgid "" "%s: no database directory specified and environment variable PGDATA unset\n" @@ -827,6 +866,55 @@ msgstr "" "%s: není zadán datový adresář a ani není nastavena promÄ›nná prostÅ™edí " "PGDATA\n" +#~ msgid "" +#~ "\n" +#~ "%s: -w option is not supported when starting a pre-9.1 server\n" +#~ msgstr "" +#~ "\n" +#~ "%s: -w volba není podporována pÅ™i startu pre-9.1 serveru\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option cannot use a relative socket directory specification\n" +#~ msgstr "" +#~ "\n" +#~ "%s: -w volba nemůže používat relativnÄ› zadaný adresář socketu\n" + +#~ msgid "" +#~ "\n" +#~ "%s: this data directory appears to be running a pre-existing postmaster\n" +#~ msgstr "" +#~ "\n" +#~ "%s: zdá se že v tomto datovém adresáři již běží existující postmaster\n" + +#~ msgid "server is still starting up\n" +#~ msgstr "server stále startuje\n" + +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "%s: nelze Äekat na server kvůli chybné konfiguraci\n" + +#~ msgid "" +#~ " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" +#~ "\"]\n" +#~ msgstr "" +#~ " %s start [-w] [-t SECS] [-D ADRESÃŘ] [-s] [-l SOUBOR] [-o \"PŘEPÃNAÄŒE" +#~ "\"]\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(Implicitní chování je Äekat na ukonÄení, ale ne pÅ™i startu nebo " +#~ "restartu.)\n" +#~ "\n" + +#~ msgid "" +#~ "\n" +#~ "Options for stop, restart, or promote:\n" +#~ msgstr "" +#~ "\n" +#~ "PÅ™epínaÄe pro zastavení, restart a promote:\n" + #~ msgid " smart promote after performing a checkpoint\n" #~ msgstr " smart promote po provedení checkpointu\n" diff --git a/src/bin/pg_ctl/po/de.po b/src/bin/pg_ctl/po/de.po index fc9ec974fd1..489c628b4da 100644 --- a/src/bin/pg_ctl/po/de.po +++ b/src/bin/pg_ctl/po/de.po @@ -1,14 +1,14 @@ # German message translation file for pg_ctl -# Peter Eisentraut , 2004 - 2017. +# Peter Eisentraut , 2004 - 2018. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" +"Project-Id-Version: PostgreSQL 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 16:44+0000\n" -"PO-Revision-Date: 2017-08-04 13:48-0400\n" +"POT-Creation-Date: 2018-05-07 00:45+0000\n" +"PO-Revision-Date: 2018-05-06 21:19-0400\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: Peter Eisentraut \n" "Language: de\n" @@ -103,62 +103,62 @@ msgstr "Kindprozess hat mit unbekanntem Status %d beendet" msgid "could not get current working directory: %s\n" msgstr "konnte aktuelles Arbeitsverzeichnis nicht ermitteln: %s\n" -#: pg_ctl.c:263 +#: pg_ctl.c:257 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: Verzeichnis »%s« existiert nicht\n" -#: pg_ctl.c:266 +#: pg_ctl.c:260 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: konnte nicht auf Verzeichnis »%s« zugreifen: %s\n" -#: pg_ctl.c:279 +#: pg_ctl.c:273 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: Verzeichnis »%s« ist kein Datenbankclusterverzeichnis\n" -#: pg_ctl.c:292 +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: konnte PID-Datei »%s« nicht öffnen: %s\n" -#: pg_ctl.c:301 +#: pg_ctl.c:295 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: die PID-Datei »%s« ist leer\n" -#: pg_ctl.c:304 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: ungültige Daten in PID-Datei »%s«\n" -#: pg_ctl.c:465 pg_ctl.c:493 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: konnte Server nicht starten: %s\n" -#: pg_ctl.c:517 +#: pg_ctl.c:511 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: konnte Server nicht starten: Fehlercode %lu\n" -#: pg_ctl.c:664 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: kann Grenzwert für Core-Datei-Größe nicht setzen; durch harten Grenzwert verboten\n" -#: pg_ctl.c:690 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: konnte Datei »%s« nicht lesen\n" -#: pg_ctl.c:695 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: Optionsdatei »%s« muss genau eine Zeile haben\n" -#: pg_ctl.c:741 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -169,7 +169,7 @@ msgstr "" "selben Verzeichnis wie »%s« gefunden.\n" "Prüfen Sie Ihre Installation.\n" -#: pg_ctl.c:747 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -180,38 +180,38 @@ msgstr "" "aber es hatte nicht die gleiche Version wie %s.\n" "Prüfen Sie Ihre Installation.\n" -#: pg_ctl.c:780 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: Initialisierung des Datenbanksystems fehlgeschlagen\n" -#: pg_ctl.c:795 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: ein anderer Server läuft möglicherweise; versuche trotzdem zu starten\n" -#: pg_ctl.c:833 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "warte auf Start des Servers..." -#: pg_ctl.c:838 pg_ctl.c:943 pg_ctl.c:1035 pg_ctl.c:1165 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr " fertig\n" -#: pg_ctl.c:839 +#: pg_ctl.c:833 msgid "server started\n" msgstr "Server gestartet\n" -#: pg_ctl.c:842 pg_ctl.c:848 pg_ctl.c:1170 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " Warten beendet\n" -#: pg_ctl.c:843 +#: pg_ctl.c:837 #, c-format msgid "%s: server did not start in time\n" msgstr "%s: Starten des Servers hat nicht rechtzeitig abgeschlossen\n" -#: pg_ctl.c:849 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -220,34 +220,34 @@ msgstr "" "%s: konnte Server nicht starten\n" "Prüfen Sie die Logausgabe.\n" -#: pg_ctl.c:857 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "Server startet\n" -#: pg_ctl.c:878 pg_ctl.c:965 pg_ctl.c:1056 pg_ctl.c:1095 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: PID-Datei »%s« existiert nicht\n" -#: pg_ctl.c:879 pg_ctl.c:967 pg_ctl.c:1057 pg_ctl.c:1096 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "Läuft der Server?\n" -#: pg_ctl.c:885 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: kann Server nicht anhalten; Einzelbenutzerserver läuft (PID: %ld)\n" -#: pg_ctl.c:893 pg_ctl.c:989 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: konnte Stopp-Signal nicht senden (PID: %ld): %s\n" -#: pg_ctl.c:900 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "Server fährt herunter\n" -#: pg_ctl.c:915 pg_ctl.c:1004 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -257,20 +257,20 @@ msgstr "" "Herunterfahren wird erst abgeschlossen werden, wenn pg_stop_backup() aufgerufen wird.\n" "\n" -#: pg_ctl.c:919 pg_ctl.c:1008 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "warte auf Herunterfahren des Servers..." -#: pg_ctl.c:935 pg_ctl.c:1026 +#: pg_ctl.c:929 pg_ctl.c:1020 msgid " failed\n" msgstr " Fehler\n" -#: pg_ctl.c:937 pg_ctl.c:1028 +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: Server fährt nicht herunter\n" -#: pg_ctl.c:939 pg_ctl.c:1030 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -278,197 +278,216 @@ msgstr "" "TIPP: Die Option »-m fast« beendet Sitzungen sofort, statt auf das Beenden\n" "durch die Sitzungen selbst zu warten.\n" -#: pg_ctl.c:945 pg_ctl.c:1036 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "Server angehalten\n" -#: pg_ctl.c:968 pg_ctl.c:1042 -msgid "starting server anyway\n" -msgstr "starte Server trotzdem\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "versuche Server trotzdem zu starten\n" -#: pg_ctl.c:977 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "%s: kann Server nicht neu starten; Einzelbenutzerserver läuft (PID: %ld)\n" -#: pg_ctl.c:980 pg_ctl.c:1066 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" msgstr "Bitte beenden Sie den Einzelbenutzerserver und versuchen Sie es noch einmal.\n" -#: pg_ctl.c:1040 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: alter Serverprozess (PID: %ld) scheint verschwunden zu sein\n" -#: pg_ctl.c:1063 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "starte Server trotzdem\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "%s: kann Server nicht neu laden; Einzelbenutzerserver läuft (PID: %ld)\n" -#: pg_ctl.c:1072 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: konnte Signal zum Neuladen nicht senden (PID: %ld): %s\n" -#: pg_ctl.c:1077 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "Signal an Server gesendet\n" -#: pg_ctl.c:1102 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "%s: kann Server nicht befördern; Einzelbenutzerserver läuft (PID: %ld)\n" -#: pg_ctl.c:1110 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: kann Server nicht befördern; Server ist nicht im Standby-Modus\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht erzeugen: %s\n" -#: pg_ctl.c:1131 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht schreiben: %s\n" -#: pg_ctl.c:1139 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: konnte Signal zum Befördern nicht senden (PID: %ld): %s\n" -#: pg_ctl.c:1142 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: konnte Signaldatei zum Befördern »%s« nicht entfernen: %s\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1146 msgid "waiting for server to promote..." msgstr "warte auf Befördern des Servers..." -#: pg_ctl.c:1166 +#: pg_ctl.c:1160 msgid "server promoted\n" msgstr "Server wurde befördert\n" -#: pg_ctl.c:1171 +#: pg_ctl.c:1165 #, c-format msgid "%s: server did not promote in time\n" msgstr "%s: Befördern des Servers hat nicht rechtzeitig abgeschlossen\n" -#: pg_ctl.c:1177 +#: pg_ctl.c:1171 msgid "server promoting\n" msgstr "Server wird befördert\n" -#: pg_ctl.c:1224 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: Einzelbenutzerserver läuft (PID: %ld)\n" -#: pg_ctl.c:1238 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: Server läuft (PID: %ld)\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: kein Server läuft\n" -#: pg_ctl.c:1271 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: konnte Signal %d nicht senden (PID: %ld): %s\n" -#: pg_ctl.c:1328 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: konnte eigene Programmdatei nicht finden\n" -#: pg_ctl.c:1338 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: konnte »postgres« Programmdatei nicht finden\n" -#: pg_ctl.c:1408 pg_ctl.c:1442 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: konnte Servicemanager nicht öffnen\n" -#: pg_ctl.c:1414 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: Systemdienst »%s« ist bereits registriert\n" -#: pg_ctl.c:1425 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: konnte Systemdienst »%s« nicht registrieren: Fehlercode %lu\n" -#: pg_ctl.c:1448 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: Systemdienst »%s« ist nicht registriert\n" -#: pg_ctl.c:1455 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: konnte Systemdienst »%s« nicht öffnen: Fehlercode %lu\n" -#: pg_ctl.c:1464 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: konnte Systemdienst »%s« nicht deregistrieren: Fehlercode %lu\n" -#: pg_ctl.c:1551 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" msgstr "Warte auf Start des Servers...\n" -#: pg_ctl.c:1554 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "Zeitüberschreitung beim Warten auf Start des Servers\n" -#: pg_ctl.c:1558 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "Server wurde gestartet und nimmt Verbindungen an\n" -#: pg_ctl.c:1613 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: konnte Systemdienst »%s« nicht starten: Fehlercode %lu\n" -#: pg_ctl.c:1687 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: WARNUNG: auf dieser Plattform können keine beschränkten Token erzeugt werden\n" -#: pg_ctl.c:1700 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" -#: pg_ctl.c:1714 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: konnte SIDs nicht erzeugen: Fehlercode %lu\n" -#: pg_ctl.c:1734 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: konnte beschränktes Token nicht erzeugen: Fehlercode %lu\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: WARNUNG: konnte nicht alle Job-Objekt-Funtionen in der System-API finden\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: konnte LUIDs für Privilegien nicht ermitteln: Fehlercode %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: konnte Token-Informationen nicht ermitteln: Fehlercode %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: Speicher aufgebraucht\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_ctl.c:1856 +#: pg_ctl.c:1913 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -478,17 +497,17 @@ msgstr "" "starten, anzuhalten oder zu steuern.\n" "\n" -#: pg_ctl.c:1857 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_ctl.c:1858 +#: pg_ctl.c:1915 #, c-format msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" msgstr " %s init[db] [-D DATENVERZ] [-s] [-o \"OPTIONEN\"]\n" -#: pg_ctl.c:1859 +#: pg_ctl.c:1916 #, c-format msgid "" " %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" @@ -497,12 +516,12 @@ msgstr "" " %s start [-D DATENVERZ] [-l DATEINAME] [-W] [-t SEK] [-s]\n" " [-o \"OPTIONEN\"] [-p PFAD] [-c]\n" -#: pg_ctl.c:1861 +#: pg_ctl.c:1918 #, c-format msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" msgstr " %s stop [-D DATENVERZ] [-m SHUTDOWN-MODUS] [-W] [-t SEK] [-s]\n" -#: pg_ctl.c:1862 +#: pg_ctl.c:1919 #, c-format msgid "" " %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" @@ -511,27 +530,27 @@ msgstr "" " %s restart [-D DATENVERZ] [-m SHUTDOWN-MODUS] [-W] [-t SEK] [-s]\n" " [-o \"OPTIONEN\"] [-c]\n" -#: pg_ctl.c:1864 +#: pg_ctl.c:1921 #, c-format msgid " %s reload [-D DATADIR] [-s]\n" msgstr " %s reload [-D DATENVERZ] [-s]\n" -#: pg_ctl.c:1865 +#: pg_ctl.c:1922 #, c-format msgid " %s status [-D DATADIR]\n" msgstr " %s status [-D DATENVERZ]\n" -#: pg_ctl.c:1866 +#: pg_ctl.c:1923 #, c-format msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" msgstr " %s promote [-D DATENVERZ] [-W] [-t SEK] [-s]\n" -#: pg_ctl.c:1867 +#: pg_ctl.c:1924 #, c-format msgid " %s kill SIGNALNAME PID\n" msgstr " %s kill SIGNALNAME PID\n" -#: pg_ctl.c:1869 +#: pg_ctl.c:1926 #, c-format msgid "" " %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" @@ -540,12 +559,12 @@ msgstr "" " %s register [-D DATENVERZ] [-N DIENSTNAME] [-U BENUTZERNAME] [-P PASSWORT]\n" " [-S STARTTYP] [-e QUELLE] [-W] [-t SEK] [-s] [-o \"OPTIONEN\"]\n" -#: pg_ctl.c:1871 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N DIENSTNAME]\n" -#: pg_ctl.c:1874 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" @@ -554,56 +573,56 @@ msgstr "" "\n" "Optionen für alle Modi:\n" -#: pg_ctl.c:1875 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=DATENVERZ Datenbankverzeichnis\n" -#: pg_ctl.c:1877 +#: pg_ctl.c:1934 #, c-format msgid " -e SOURCE event source for logging when running as a service\n" msgstr "" " -e QUELLE Ereignisquelle fürs Loggen, wenn als Systemdienst\n" " gestartet\n" -#: pg_ctl.c:1879 +#: pg_ctl.c:1936 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent nur Fehler zeigen, keine Informationsmeldungen\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SEK Sekunden zu warten bei Option -w\n" -#: pg_ctl.c:1881 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_ctl.c:1882 +#: pg_ctl.c:1939 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait warten bis Operation abgeschlossen ist (Voreinstellung)\n" -#: pg_ctl.c:1883 +#: pg_ctl.c:1940 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait nicht warten bis Operation abgeschlossen ist\n" -#: pg_ctl.c:1884 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_ctl.c:1885 +#: pg_ctl.c:1942 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "" "Wenn die Option -D weggelassen wird, dann wird die Umgebungsvariable\n" "PGDATA verwendet.\n" -#: pg_ctl.c:1887 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" @@ -612,24 +631,24 @@ msgstr "" "\n" "Optionen für Start oder Neustart:\n" -#: pg_ctl.c:1889 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files erlaubt postgres Core-Dateien zu erzeugen\n" -#: pg_ctl.c:1891 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files betrifft diese Plattform nicht\n" -#: pg_ctl.c:1893 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr "" " -l, --log=DATEINAME Serverlog in DATEINAME schreiben (wird an bestehende\n" " Datei angehängt)\n" -#: pg_ctl.c:1894 +#: pg_ctl.c:1951 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -638,12 +657,12 @@ msgstr "" " -o, --optons=OPTIONEN Kommandozeilenoptionen für postgres (PostgreSQL-\n" " Serverprogramm) oder initdb\n" -#: pg_ctl.c:1896 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p PFAD-ZU-POSTGRES normalerweise nicht notwendig\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:1954 #, c-format msgid "" "\n" @@ -652,12 +671,12 @@ msgstr "" "\n" "Optionen für Anhalten oder Neustart:\n" -#: pg_ctl.c:1898 +#: pg_ctl.c:1955 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr " -m, --mode=MODUS MODUS kann »smart«, »fast« oder »immediate« sein\n" -#: pg_ctl.c:1900 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -666,24 +685,24 @@ msgstr "" "\n" "Shutdown-Modi sind:\n" -#: pg_ctl.c:1901 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart beenden nachdem alle Clientverbindungen geschlossen sind\n" -#: pg_ctl.c:1902 +#: pg_ctl.c:1959 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" msgstr " fast sofort beenden, mit richtigem Shutdown (Voreinstellung)\n" -#: pg_ctl.c:1903 +#: pg_ctl.c:1960 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr "" " immediate beenden ohne vollständigen Shutdown; führt zu Recovery-Lauf\n" " beim Neustart\n" -#: pg_ctl.c:1905 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -692,7 +711,7 @@ msgstr "" "\n" "Erlaubte Signalnamen für »kill«:\n" -#: pg_ctl.c:1909 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" @@ -701,27 +720,27 @@ msgstr "" "\n" "Optionen für »register« und »unregister«:\n" -#: pg_ctl.c:1910 +#: pg_ctl.c:1967 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N DIENSTNAME Systemdienstname für Registrierung des PostgreSQL-Servers\n" -#: pg_ctl.c:1911 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P PASSWORD Passwort des Benutzers für Registrierung des PostgreSQL-Servers\n" -#: pg_ctl.c:1912 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U USERNAME Benutzername für Registrierung des PostgreSQL-Servers\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S STARTTYP Systemdienst-Starttyp für PostgreSQL-Server\n" -#: pg_ctl.c:1915 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" @@ -730,19 +749,19 @@ msgstr "" "\n" "Starttypen sind:\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:1973 #, c-format msgid " auto start service automatically during system startup (default)\n" msgstr "" " auto Dienst automatisch starten beim Start des Betriebssystems\n" " (Voreinstellung)\n" -#: pg_ctl.c:1917 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" msgstr " demand Dienst bei Bedarf starten\n" -#: pg_ctl.c:1920 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -751,32 +770,32 @@ msgstr "" "\n" "Berichten Sie Fehler an .\n" -#: pg_ctl.c:1945 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: unbekannter Shutdown-Modus »%s«\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: unbekannter Signalname »%s«\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: unbekannter Starttyp »%s«\n" -#: pg_ctl.c:2049 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: konnte das Datenverzeichnis mit Befehl »%s« nicht ermitteln\n" -#: pg_ctl.c:2074 +#: pg_ctl.c:2128 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: Kontrolldatei scheint kaputt zu sein\n" -#: pg_ctl.c:2144 +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -787,32 +806,32 @@ msgstr "" "Bitte loggen Sie sich (z.B. mit »su«) als der (unprivilegierte) Benutzer\n" "ein, der Eigentümer des Serverprozesses sein soll.\n" -#: pg_ctl.c:2228 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: Option -S wird auf dieser Plattform nicht unterstützt\n" -#: pg_ctl.c:2265 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" -#: pg_ctl.c:2289 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: fehlende Argumente für »kill«-Modus\n" -#: pg_ctl.c:2307 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: unbekannter Operationsmodus »%s«\n" -#: pg_ctl.c:2317 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: keine Operation angegeben\n" -#: pg_ctl.c:2338 +#: pg_ctl.c:2393 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: kein Datenbankverzeichnis angegeben und Umgebungsvariable PGDATA nicht gesetzt\n" diff --git a/src/bin/pg_ctl/po/es.po b/src/bin/pg_ctl/po/es.po index 2bf824b2911..f19b1aaf34a 100644 --- a/src/bin/pg_ctl/po/es.po +++ b/src/bin/pg_ctl/po/es.po @@ -1,6 +1,6 @@ # Spanish translation of pg_ctl. # -# Copyright (C) 2004-2013 PostgreSQL Global Development Group +# Copyright (c) 2004-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Alvaro Herrera , 2004-2013 @@ -8,52 +8,56 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_ctl (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-11 21:15+0000\n" -"PO-Revision-Date: 2017-07-12 11:12-0500\n" +"Project-Id-Version: pg_ctl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:13+0000\n" +"PO-Revision-Date: 2019-06-06 17:23-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL Español \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.2\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar el directorio a «%s»: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "pclose failed: %m" +msgstr "pclose falló: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "memoria agotada" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 @@ -82,22 +86,17 @@ msgstr "orden no encontrada" msgid "child process exited with exit code %d" msgstr "el proceso hijo terminó con código de salida %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "el proceso hijo fue terminado por una excepción 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "el proceso hijo fue terminado por una señal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "el proceso hijo fue terminado por una señal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "el proceso hijo terminó con código no reconocido %d" @@ -107,64 +106,74 @@ msgstr "el proceso hijo terminó con código no reconocido %d" msgid "could not get current working directory: %s\n" msgstr "no se pudo obtener el directorio de trabajo actual: %s\n" -#: pg_ctl.c:263 +#: pg_ctl.c:262 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: el directorio «%s» no existe\n" -#: pg_ctl.c:266 +#: pg_ctl.c:265 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: no se pudo acceder al directorio «%s»: %s\n" -#: pg_ctl.c:279 +#: pg_ctl.c:278 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: el directorio «%s» no es un directorio de base de datos\n" -#: pg_ctl.c:292 +#: pg_ctl.c:291 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: no se pudo abrir el archivo de PID «%s»: %s\n" -#: pg_ctl.c:301 +#: pg_ctl.c:300 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: el archivo de PID «%s» está vacío\n" -#: pg_ctl.c:304 +#: pg_ctl.c:303 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: datos no válidos en archivo de PID «%s»\n" -#: pg_ctl.c:465 pg_ctl.c:493 +#: pg_ctl.c:464 pg_ctl.c:506 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: no se pudo iniciar el servidor: %s\n" -#: pg_ctl.c:517 +#: pg_ctl.c:484 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: no se pudo iniciar el servidor debido a falla en setsid(): %s\n" + +#: pg_ctl.c:530 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: no se pudo iniciar el servidor: código de error %lu\n" -#: pg_ctl.c:664 +#: pg_ctl.c:677 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "" "%s: no se puede establecer el límite de archivos de volcado;\n" "impedido por un límite duro\n" -#: pg_ctl.c:690 +#: pg_ctl.c:703 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: no se pudo leer el archivo «%s»\n" -#: pg_ctl.c:695 +#: pg_ctl.c:708 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: archivo de opciones «%s» debe tener exactamente una línea\n" -#: pg_ctl.c:741 +#: pg_ctl.c:750 pg_ctl.c:941 pg_ctl.c:1037 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: falló la señal de detención (PID: %ld): %s\n" + +#: pg_ctl.c:778 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -175,7 +184,7 @@ msgstr "" "directorio que «%s».\n" "Verifique su instalación.\n" -#: pg_ctl.c:747 +#: pg_ctl.c:784 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -186,38 +195,38 @@ msgstr "" "de la misma versión que «%s».\n" "Verifique su instalación.\n" -#: pg_ctl.c:780 +#: pg_ctl.c:817 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: falló la creación de la base de datos\n" -#: pg_ctl.c:795 +#: pg_ctl.c:832 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: otro servidor puede estar en ejecución; tratando de iniciarlo de todas formas.\n" -#: pg_ctl.c:833 +#: pg_ctl.c:881 msgid "waiting for server to start..." msgstr "esperando que el servidor se inicie..." -#: pg_ctl.c:838 pg_ctl.c:943 pg_ctl.c:1035 pg_ctl.c:1165 +#: pg_ctl.c:886 pg_ctl.c:991 pg_ctl.c:1083 pg_ctl.c:1213 msgid " done\n" msgstr " listo\n" -#: pg_ctl.c:839 +#: pg_ctl.c:887 msgid "server started\n" msgstr "servidor iniciado\n" -#: pg_ctl.c:842 pg_ctl.c:848 pg_ctl.c:1170 +#: pg_ctl.c:890 pg_ctl.c:896 pg_ctl.c:1218 msgid " stopped waiting\n" msgstr " abandonando la espera\n" -#: pg_ctl.c:843 +#: pg_ctl.c:891 #, c-format msgid "%s: server did not start in time\n" msgstr "%s: el servidor no inició a tiempo\n" -#: pg_ctl.c:849 +#: pg_ctl.c:897 #, c-format msgid "" "%s: could not start server\n" @@ -226,36 +235,31 @@ msgstr "" "%s: no se pudo iniciar el servidor.\n" "Examine el registro del servidor.\n" -#: pg_ctl.c:857 +#: pg_ctl.c:905 msgid "server starting\n" msgstr "servidor iniciándose\n" -#: pg_ctl.c:878 pg_ctl.c:965 pg_ctl.c:1056 pg_ctl.c:1095 +#: pg_ctl.c:926 pg_ctl.c:1013 pg_ctl.c:1104 pg_ctl.c:1143 pg_ctl.c:1242 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: el archivo de PID «%s» no existe\n" -#: pg_ctl.c:879 pg_ctl.c:967 pg_ctl.c:1057 pg_ctl.c:1096 +#: pg_ctl.c:927 pg_ctl.c:1015 pg_ctl.c:1105 pg_ctl.c:1144 pg_ctl.c:1243 msgid "Is server running?\n" msgstr "¿Está el servidor en ejecución?\n" -#: pg_ctl.c:885 +#: pg_ctl.c:933 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "" "%s: no se puede detener el servidor;\n" "un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" -#: pg_ctl.c:893 pg_ctl.c:989 -#, c-format -msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "%s: falló la señal de detención (PID: %ld): %s\n" - -#: pg_ctl.c:900 +#: pg_ctl.c:948 msgid "server shutting down\n" msgstr "servidor deteniéndose\n" -#: pg_ctl.c:915 pg_ctl.c:1004 +#: pg_ctl.c:963 pg_ctl.c:1052 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -265,20 +269,20 @@ msgstr "" "El apagado no se completará hasta que se invoque la función pg_stop_backup().\n" "\n" -#: pg_ctl.c:919 pg_ctl.c:1008 +#: pg_ctl.c:967 pg_ctl.c:1056 msgid "waiting for server to shut down..." msgstr "esperando que el servidor se detenga..." -#: pg_ctl.c:935 pg_ctl.c:1026 +#: pg_ctl.c:983 pg_ctl.c:1074 msgid " failed\n" msgstr " falló\n" -#: pg_ctl.c:937 pg_ctl.c:1028 +#: pg_ctl.c:985 pg_ctl.c:1076 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: el servidor no se detiene\n" -#: pg_ctl.c:939 pg_ctl.c:1030 +#: pg_ctl.c:987 pg_ctl.c:1078 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -286,205 +290,253 @@ msgstr "" "SUGERENCIA: La opción «-m fast» desconecta las sesiones inmediatamente\n" "en lugar de esperar que cada sesión finalice por sí misma.\n" -#: pg_ctl.c:945 pg_ctl.c:1036 +#: pg_ctl.c:993 pg_ctl.c:1084 msgid "server stopped\n" msgstr "servidor detenido\n" -#: pg_ctl.c:968 pg_ctl.c:1042 -msgid "starting server anyway\n" -msgstr "iniciando el servidor de todas maneras\n" +#: pg_ctl.c:1016 +msgid "trying to start server anyway\n" +msgstr "intentando iniciae el servidor de todas maneras\n" -#: pg_ctl.c:977 +#: pg_ctl.c:1025 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "" "%s: no se puede reiniciar el servidor;\n" "un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" -#: pg_ctl.c:980 pg_ctl.c:1066 +#: pg_ctl.c:1028 pg_ctl.c:1114 msgid "Please terminate the single-user server and try again.\n" msgstr "Por favor termine el servidor mono-usuario e intente nuevamente.\n" -#: pg_ctl.c:1040 +#: pg_ctl.c:1088 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: el proceso servidor antiguo (PID: %ld) parece no estar\n" -#: pg_ctl.c:1063 +#: pg_ctl.c:1090 +msgid "starting server anyway\n" +msgstr "iniciando el servidor de todas maneras\n" + +#: pg_ctl.c:1111 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "" "%s: no se puede recargar el servidor;\n" "un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" -#: pg_ctl.c:1072 +#: pg_ctl.c:1120 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: la señal de recarga falló (PID: %ld): %s\n" -#: pg_ctl.c:1077 +#: pg_ctl.c:1125 msgid "server signaled\n" msgstr "se ha enviado una señal al servidor\n" -#: pg_ctl.c:1102 +#: pg_ctl.c:1150 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "" "%s: no se puede promover el servidor;\n" "un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" -#: pg_ctl.c:1110 +#: pg_ctl.c:1158 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "" "%s: no se puede promover el servidor;\n" "el servidor no está en modo «standby»\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1173 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: no se pudo crear el archivo de señal de promoción «%s»: %s\n" -#: pg_ctl.c:1131 +#: pg_ctl.c:1179 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: no se pudo escribir al archivo de señal de promoción «%s»: %s\n" -#: pg_ctl.c:1139 +#: pg_ctl.c:1187 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: no se pudo enviar la señal de promoción (PID: %ld): %s\n" -#: pg_ctl.c:1142 +#: pg_ctl.c:1190 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: no se pudo eliminar el archivo de señal de promoción «%s»: %s\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1200 msgid "waiting for server to promote..." msgstr "esperando que el servidor se promueva..." -#: pg_ctl.c:1166 +#: pg_ctl.c:1214 msgid "server promoted\n" msgstr "servidor promovido\n" -#: pg_ctl.c:1171 +#: pg_ctl.c:1219 #, c-format msgid "%s: server did not promote in time\n" msgstr "%s: el servidor no se promovió a tiempo\n" -#: pg_ctl.c:1177 +#: pg_ctl.c:1225 msgid "server promoting\n" msgstr "servidor promoviendo\n" -#: pg_ctl.c:1224 +#: pg_ctl.c:1249 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: no se puede rotar el archivo de log; un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" + +#: pg_ctl.c:1259 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo crear el archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1265 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo escribir al archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1273 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: no se pudo enviar la señal de rotación de log (PID: %ld): %s\n" + +#: pg_ctl.c:1276 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: no se pudo eliminar el archivo de señal de rotación de log «%s»: %s\n" + +#: pg_ctl.c:1281 +msgid "server signaled to rotate log file\n" +msgstr "se ha enviado una señal de rotación de log al servidor\n" + +#: pg_ctl.c:1328 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: un servidor en modo mono-usuario está en ejecución (PID: %ld)\n" -#: pg_ctl.c:1238 +#: pg_ctl.c:1342 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: el servidor está en ejecución (PID: %ld)\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1358 #, c-format msgid "%s: no server running\n" msgstr "%s: no hay servidor en ejecución\n" -#: pg_ctl.c:1271 +#: pg_ctl.c:1375 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: no se pudo enviar la señal %d (PID: %ld): %s\n" -#: pg_ctl.c:1328 +#: pg_ctl.c:1432 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: no se pudo encontrar el ejecutable propio\n" -#: pg_ctl.c:1338 +#: pg_ctl.c:1442 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: no se pudo encontrar el ejecutable postgres\n" -#: pg_ctl.c:1408 pg_ctl.c:1442 +#: pg_ctl.c:1512 pg_ctl.c:1546 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: no se pudo abrir el gestor de servicios\n" -#: pg_ctl.c:1414 +#: pg_ctl.c:1518 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: el servicio «%s» ya está registrado\n" -#: pg_ctl.c:1425 +#: pg_ctl.c:1529 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: no se pudo registrar el servicio «%s»: código de error %lu\n" -#: pg_ctl.c:1448 +#: pg_ctl.c:1552 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: el servicio «%s» no ha sido registrado\n" -#: pg_ctl.c:1455 +#: pg_ctl.c:1559 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: no se pudo abrir el servicio «%s»: código de error %lu\n" -#: pg_ctl.c:1464 +#: pg_ctl.c:1568 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: no se pudo dar de baja el servicio «%s»: código de error %lu\n" -#: pg_ctl.c:1551 +#: pg_ctl.c:1655 msgid "Waiting for server startup...\n" msgstr "Esperando que el servidor se inicie...\n" -#: pg_ctl.c:1554 +#: pg_ctl.c:1658 msgid "Timed out waiting for server startup\n" msgstr "Se agotó el tiempo de espera al inicio del servidor\n" -#: pg_ctl.c:1558 +#: pg_ctl.c:1662 msgid "Server started and accepting connections\n" msgstr "Servidor iniciado y aceptando conexiones\n" -#: pg_ctl.c:1613 +#: pg_ctl.c:1717 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: no se pudo iniciar el servicio «%s»: código de error %lu\n" -#: pg_ctl.c:1687 +#: pg_ctl.c:1787 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" -#: pg_ctl.c:1700 +#: pg_ctl.c:1800 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" -#: pg_ctl.c:1714 +#: pg_ctl.c:1814 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" -#: pg_ctl.c:1734 +#: pg_ctl.c:1841 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1872 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: ATENCIÓN: no fue posible encontrar todas las funciones de gestión de tareas en la API del sistema\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:1969 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: no se pudo obtener LUIDs para privilegios: código de error %lu\n" + +#: pg_ctl.c:1977 pg_ctl.c:1992 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: no se pudo obtener información de token: código de error %lu\n" + +#: pg_ctl.c:1986 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: memoria agotada\n" + +#: pg_ctl.c:2016 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Use «%s --help» para obtener más información.\n" -#: pg_ctl.c:1856 +#: pg_ctl.c:2024 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -494,74 +546,79 @@ msgstr "" "un servidor PostgreSQL.\n" "\n" -#: pg_ctl.c:1857 +#: pg_ctl.c:2025 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_ctl.c:1858 +#: pg_ctl.c:2026 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" -msgstr " %s init[db] [-D DATADIR] [-s] [-o OPCIONES]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATADIR] [-s] [-o OPCIONES]\n" -#: pg_ctl.c:1859 +#: pg_ctl.c:2027 #, c-format msgid "" -" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-p PATH] [-c]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-D DATADIR] [-l ARCHIVO] [-W] [-t SEGS] [-s]\n" -" [-o OPCIONES] [-p RUTA] [-c]\n" +" %s start [-D DATADIR] [-l ARCHIVO] [-W] [-t SEGS] [-s]\n" +" [-o OPCIONES] [-p RUTA] [-c]\n" -#: pg_ctl.c:1861 +#: pg_ctl.c:2029 #, c-format -msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -msgstr " %s stop [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" -#: pg_ctl.c:1862 +#: pg_ctl.c:2030 #, c-format msgid "" -" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-c]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" -" [-o OPCIONES]\n" +" %s restart [-D DATADIR] [-m MODO-DETENCIÓN] [-W] [-t SEGS] [-s]\n" +" [-o OPCIONES]\n" + +#: pg_ctl.c:2032 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATADIR] [-s]\n" -#: pg_ctl.c:1864 +#: pg_ctl.c:2033 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D DATADIR] [-s]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" -#: pg_ctl.c:1865 +#: pg_ctl.c:2034 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D DATADIR]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATADIR] [-W] [-t SEGS] [-s]\n" -#: pg_ctl.c:1866 +#: pg_ctl.c:2035 #, c-format -msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" -msgstr " %s promote [-D DATADIR] [-W] [-t SEGS] [-s]\n" +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATADIR] [-s]\n" -#: pg_ctl.c:1867 +#: pg_ctl.c:2036 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill NOMBRE-SEÑAL ID-DE-PROCESO\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill NOMBRE-SEÑAL ID-DE-PROCESO\n" -#: pg_ctl.c:1869 +#: pg_ctl.c:2038 #, c-format msgid "" -" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" -" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr "" " %s register [-D DATADIR] [-N SERVICIO] [-U USUARIO] [-P PASSWORD]\n" " [-S TIPO-INICIO] [-e ORIGEN] [-W] [-t SEGS] [-o OPCIONES]\n" -#: pg_ctl.c:1871 +#: pg_ctl.c:2040 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N SERVICIO]\n" -#: pg_ctl.c:1874 +#: pg_ctl.c:2043 #, c-format msgid "" "\n" @@ -570,52 +627,52 @@ msgstr "" "\n" "Opciones comunes:\n" -#: pg_ctl.c:1875 +#: pg_ctl.c:2044 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata DATADIR ubicación del área de almacenamiento de datos\n" -#: pg_ctl.c:1877 +#: pg_ctl.c:2046 #, c-format msgid " -e SOURCE event source for logging when running as a service\n" msgstr " -e ORIGEN origen para el log de eventos cuando se ejecuta como servicio\n" -#: pg_ctl.c:1879 +#: pg_ctl.c:2048 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent mostrar sólo errores, no mensajes de información\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:2049 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SEGS segundos a esperar cuando se use la opción -w\n" -#: pg_ctl.c:1881 +#: pg_ctl.c:2050 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión, luego salir\n" -#: pg_ctl.c:1882 +#: pg_ctl.c:2051 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait esperar hasta que la operación se haya completado (por omisión)\n" -#: pg_ctl.c:1883 +#: pg_ctl.c:2052 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait no esperar hasta que la operación se haya completado\n" -#: pg_ctl.c:1884 +#: pg_ctl.c:2053 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda, luego salir\n" -#: pg_ctl.c:1885 +#: pg_ctl.c:2054 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "Si la opción -D es omitida, se usa la variable de ambiente PGDATA.\n" -#: pg_ctl.c:1887 +#: pg_ctl.c:2056 #, c-format msgid "" "\n" @@ -624,24 +681,24 @@ msgstr "" "\n" "Opciones para inicio y reinicio:\n" -#: pg_ctl.c:1889 +#: pg_ctl.c:2058 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr "" " -c, --core-files permite que postgres produzca archivos\n" " de volcado (core)\n" -#: pg_ctl.c:1891 +#: pg_ctl.c:2060 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files no aplicable en esta plataforma\n" -#: pg_ctl.c:1893 +#: pg_ctl.c:2062 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l --log=ARCHIVO guardar el registro del servidor en ARCHIVO.\n" -#: pg_ctl.c:1894 +#: pg_ctl.c:2063 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -650,12 +707,12 @@ msgstr "" " -o, --options=OPCIONES parámetros de línea de órdenes a pasar a postgres\n" " (ejecutable del servidor de PostgreSQL) o initdb\n" -#: pg_ctl.c:1896 +#: pg_ctl.c:2065 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p RUTA-A-POSTGRES normalmente no es necesario\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:2066 #, c-format msgid "" "\n" @@ -664,12 +721,12 @@ msgstr "" "\n" "Opciones para detener o reiniciar:\n" -#: pg_ctl.c:1898 +#: pg_ctl.c:2067 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr " -m, --mode=MODO puede ser «smart», «fast» o «immediate»\n" -#: pg_ctl.c:1900 +#: pg_ctl.c:2069 #, c-format msgid "" "\n" @@ -678,24 +735,24 @@ msgstr "" "\n" "Modos de detención son:\n" -#: pg_ctl.c:1901 +#: pg_ctl.c:2070 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart salir después que todos los clientes se hayan desconectado\n" -#: pg_ctl.c:1902 +#: pg_ctl.c:2071 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" msgstr " fast salir directamente, con apagado apropiado (por omisión)\n" -#: pg_ctl.c:1903 +#: pg_ctl.c:2072 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr "" " immediate salir sin apagado completo; se ejecutará recuperación\n" " en el próximo inicio\n" -#: pg_ctl.c:1905 +#: pg_ctl.c:2074 #, c-format msgid "" "\n" @@ -704,7 +761,7 @@ msgstr "" "\n" "Nombres de señales permitidos para kill:\n" -#: pg_ctl.c:1909 +#: pg_ctl.c:2078 #, c-format msgid "" "\n" @@ -713,35 +770,35 @@ msgstr "" "\n" "Opciones para registrar y dar de baja:\n" -#: pg_ctl.c:1910 +#: pg_ctl.c:2079 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr "" " -N SERVICIO nombre de servicio con el cual registrar\n" " el servidor PostgreSQL\n" -#: pg_ctl.c:1911 +#: pg_ctl.c:2080 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr "" " -P CONTRASEÑA contraseña de la cuenta con la cual registrar\n" " el servidor PostgreSQL\n" -#: pg_ctl.c:1912 +#: pg_ctl.c:2081 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr "" " -U USUARIO nombre de usuario de la cuenta con la cual\n" " registrar el servidor PostgreSQL\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:2082 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr "" " -S TIPO-INICIO tipo de inicio de servicio con que registrar\n" " el servidor PostgreSQL\n" -#: pg_ctl.c:1915 +#: pg_ctl.c:2084 #, c-format msgid "" "\n" @@ -750,51 +807,51 @@ msgstr "" "\n" "Tipos de inicio del servicio son:\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:2085 #, c-format msgid " auto start service automatically during system startup (default)\n" msgstr " auto iniciar automáticamente al inicio del sistema (por omisión)\n" -#: pg_ctl.c:1917 +#: pg_ctl.c:2086 #, c-format msgid " demand start service on demand\n" msgstr " demand iniciar el servicio en demanda\n" -#: pg_ctl.c:1920 +#: pg_ctl.c:2089 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" -#: pg_ctl.c:1945 +#: pg_ctl.c:2114 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: modo de apagado «%s» no reconocido\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2143 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: nombre de señal «%s» no reconocido\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:2160 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: tipo de inicio «%s» no reconocido\n" -#: pg_ctl.c:2049 +#: pg_ctl.c:2215 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: no se pudo determinar el directorio de datos usando la orden «%s»\n" -#: pg_ctl.c:2074 +#: pg_ctl.c:2240 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: el archivo de control parece estar corrupto\n" -#: pg_ctl.c:2144 +#: pg_ctl.c:2308 #, c-format msgid "" "%s: cannot be run as root\n" @@ -805,79 +862,32 @@ msgstr "" "Por favor conéctese (usando, por ejemplo, «su») con un usuario no privilegiado,\n" "quien ejecutará el proceso servidor.\n" -#: pg_ctl.c:2228 +#: pg_ctl.c:2392 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: la opción -S no está soportada en esta plataforma\n" -#: pg_ctl.c:2265 +#: pg_ctl.c:2429 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" -#: pg_ctl.c:2289 +#: pg_ctl.c:2455 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: argumentos faltantes para envío de señal\n" -#: pg_ctl.c:2307 +#: pg_ctl.c:2473 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: modo de operación «%s» no reconocido\n" -#: pg_ctl.c:2317 +#: pg_ctl.c:2483 #, c-format msgid "%s: no operation specified\n" msgstr "%s: no se especificó operación\n" -#: pg_ctl.c:2338 +#: pg_ctl.c:2504 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: no se especificó directorio de datos y la variable PGDATA no está definida\n" - -#~ msgid "" -#~ "\n" -#~ "%s: -w option is not supported when starting a pre-9.1 server\n" -#~ msgstr "" -#~ "\n" -#~ "%s: la opción -w no está soportada cuando se inicia un servidor anterior a 9.1\n" - -#~ msgid "" -#~ "\n" -#~ "%s: -w option cannot use a relative socket directory specification\n" -#~ msgstr "" -#~ "\n" -#~ "%s: la opción -w no puede usar una especificación relativa de directorio\n" - -#~ msgid "%s: could not wait for server because of misconfiguration\n" -#~ msgstr "%s: no se pudo esperar al servidor debido a un error de configuración\n" - -#~ msgid "" -#~ "\n" -#~ "%s: could not stat file \"%s\": %s\n" -#~ msgstr "" -#~ "\n" -#~ "%s: no se pudo hacer «stat» al archivo «%s»: %s\n" - -#~ msgid "" -#~ "\n" -#~ "%s: this data directory appears to be running a pre-existing postmaster\n" -#~ msgstr "" -#~ "\n" -#~ "%s: este directorio de datos parece estar ejecutando un postmaster pre-existente\n" - -#~ msgid "%s: could not start server: exit code was %d\n" -#~ msgstr "%s: no se pudo iniciar el servidor: el código de retorno fue %d\n" - -#~ msgid "" -#~ "(The default is to wait for shutdown, but not for start or restart.)\n" -#~ "\n" -#~ msgstr "" -#~ "(Por omisión se espera para las detenciones, pero no los inicios o reinicios)\n" -#~ "\n" - -#~ msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" -#~ msgstr " %s start [-w] [-t SEGS] [-D DATADIR] [-s] [-l ARCHIVO] [-o \"OPCIONES\"]\n" - -#~ msgid "server is still starting up\n" -#~ msgstr "servidor aún iniciándose\n" diff --git a/src/bin/pg_ctl/po/fr.po b/src/bin/pg_ctl/po/fr.po index 82b10926125..df582f9d47c 100644 --- a/src/bin/pg_ctl/po/fr.po +++ b/src/bin/pg_ctl/po/fr.po @@ -7,52 +7,56 @@ # Stéphane Schildknecht , 2009. msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-06 14:45+0000\n" -"PO-Revision-Date: 2017-07-06 18:04+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:16+0000\n" +"PO-Revision-Date: 2019-05-17 15:44+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "n'a pas pu identifier le répertoire courant : %s" +msgid "could not identify current directory: %m" +msgstr "n'a pas pu identifier le répertoire courant : %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "binaire « %s » invalide" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "n'a pas pu lire le binaire « %s »" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "n'a pas pu trouver un « %s » à exécuter" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "n'a pas pu modifier le répertoire par « %s » : %s" +msgid "could not change directory to \"%s\": %m" +msgstr "n'a pas pu modifier le répertoire par « %s » : %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "n'a pas pu lire le lien symbolique « %s »" +msgid "could not read symbolic link \"%s\": %m" +msgstr "n'a pas pu lire le lien symbolique « %s » : %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "échec de pclose : %s" +msgid "pclose failed: %m" +msgstr "échec de pclose : %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "mémoire épuisée" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 @@ -81,22 +85,17 @@ msgstr "commande introuvable" msgid "child process exited with exit code %d" msgstr "le processus fils a quitté avec le code de sortie %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "le processus fils a été terminé par l'exception 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "le processus fils a été terminé par le signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "le processus fils a été terminé par le signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "le processus fils a été terminé par le signal %d : %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "le processus fils a quitté avec un statut %d non reconnu" @@ -106,64 +105,76 @@ msgstr "le processus fils a quitté avec un statut %d non reconnu" msgid "could not get current working directory: %s\n" msgstr "n'a pas pu obtenir le répertoire de travail : %s\n" -#: pg_ctl.c:263 +#: pg_ctl.c:262 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s : le répertoire « %s » n'existe pas\n" -#: pg_ctl.c:266 +#: pg_ctl.c:265 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n" -#: pg_ctl.c:279 +#: pg_ctl.c:278 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s : le répertoire « %s » n'est pas un répertoire d'instance\n" -#: pg_ctl.c:292 +#: pg_ctl.c:291 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le fichier de PID « %s » : %s\n" -#: pg_ctl.c:301 +#: pg_ctl.c:300 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s : le fichier PID « %s » est vide\n" -#: pg_ctl.c:304 +#: pg_ctl.c:303 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s : données invalides dans le fichier de PID « %s »\n" -#: pg_ctl.c:465 pg_ctl.c:493 +#: pg_ctl.c:464 pg_ctl.c:506 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s : n'a pas pu démarrer le serveur : %s\n" -#: pg_ctl.c:517 +#: pg_ctl.c:484 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "" +"%s : n'a pas pu démarrer le serveur à cause d'un échec de setsid() : %s\n" + +#: pg_ctl.c:530 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s : n'a pas pu démarrer le serveur : code d'erreur %lu\n" -#: pg_ctl.c:664 +#: pg_ctl.c:677 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "" "%s : n'a pas pu initialiser la taille des fichiers core, ceci est interdit\n" "par une limite dure\n" -#: pg_ctl.c:690 +#: pg_ctl.c:703 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s : n'a pas pu lire le fichier « %s »\n" -#: pg_ctl.c:695 +#: pg_ctl.c:708 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" -msgstr "%s : le fichier d'options « %s » ne doit comporter qu'une seule ligne\n" +msgstr "" +"%s : le fichier d'options « %s » ne doit comporter qu'une seule ligne\n" + +#: pg_ctl.c:750 pg_ctl.c:941 pg_ctl.c:1037 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s : n'a pas pu envoyer le signal d'arrêt (PID : %ld) : %s\n" -#: pg_ctl.c:741 +#: pg_ctl.c:778 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -174,7 +185,7 @@ msgstr "" "dans le même répertoire que « %s ».\n" "Vérifiez votre installation.\n" -#: pg_ctl.c:747 +#: pg_ctl.c:784 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -185,40 +196,40 @@ msgstr "" "que %s.\n" "Vérifiez votre installation.\n" -#: pg_ctl.c:780 +#: pg_ctl.c:817 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s : l'initialisation du système a échoué\n" -#: pg_ctl.c:795 +#: pg_ctl.c:832 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "" "%s : un autre serveur semble en cours d'exécution ; le démarrage du serveur\n" "va toutefois être tenté\n" -#: pg_ctl.c:833 +#: pg_ctl.c:881 msgid "waiting for server to start..." msgstr "en attente du démarrage du serveur..." -#: pg_ctl.c:838 pg_ctl.c:943 pg_ctl.c:1035 pg_ctl.c:1165 +#: pg_ctl.c:886 pg_ctl.c:991 pg_ctl.c:1083 pg_ctl.c:1213 msgid " done\n" msgstr " effectué\n" -#: pg_ctl.c:839 +#: pg_ctl.c:887 msgid "server started\n" msgstr "serveur démarré\n" -#: pg_ctl.c:842 pg_ctl.c:848 pg_ctl.c:1170 +#: pg_ctl.c:890 pg_ctl.c:896 pg_ctl.c:1218 msgid " stopped waiting\n" msgstr " attente arrêtée\n" -#: pg_ctl.c:843 +#: pg_ctl.c:891 #, c-format msgid "%s: server did not start in time\n" msgstr "%s : le serveur ne s'est pas lancé à temps\n" -#: pg_ctl.c:849 +#: pg_ctl.c:897 #, c-format msgid "" "%s: could not start server\n" @@ -227,36 +238,31 @@ msgstr "" "%s : n'a pas pu démarrer le serveur\n" "Examinez le journal applicatif.\n" -#: pg_ctl.c:857 +#: pg_ctl.c:905 msgid "server starting\n" msgstr "serveur en cours de démarrage\n" -#: pg_ctl.c:878 pg_ctl.c:965 pg_ctl.c:1056 pg_ctl.c:1095 +#: pg_ctl.c:926 pg_ctl.c:1013 pg_ctl.c:1104 pg_ctl.c:1143 pg_ctl.c:1242 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s : le fichier de PID « %s » n'existe pas\n" -#: pg_ctl.c:879 pg_ctl.c:967 pg_ctl.c:1057 pg_ctl.c:1096 +#: pg_ctl.c:927 pg_ctl.c:1015 pg_ctl.c:1105 pg_ctl.c:1144 pg_ctl.c:1243 msgid "Is server running?\n" msgstr "Le serveur est-il en cours d'exécution ?\n" -#: pg_ctl.c:885 +#: pg_ctl.c:933 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "" "%s : ne peut pas arrêter le serveur ; le serveur mono-utilisateur est en\n" "cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:893 pg_ctl.c:989 -#, c-format -msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "%s : n'a pas pu envoyer le signal d'arrêt (PID : %ld) : %s\n" - -#: pg_ctl.c:900 +#: pg_ctl.c:948 msgid "server shutting down\n" msgstr "serveur en cours d'arrêt\n" -#: pg_ctl.c:915 pg_ctl.c:1004 +#: pg_ctl.c:963 pg_ctl.c:1052 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -266,224 +272,293 @@ msgstr "" "L'arrêt ne surviendra qu'au moment où pg_stop_backup() sera appelé.\n" "\n" -#: pg_ctl.c:919 pg_ctl.c:1008 +#: pg_ctl.c:967 pg_ctl.c:1056 msgid "waiting for server to shut down..." msgstr "en attente de l'arrêt du serveur..." -#: pg_ctl.c:935 pg_ctl.c:1026 +#: pg_ctl.c:983 pg_ctl.c:1074 msgid " failed\n" msgstr " a échoué\n" -#: pg_ctl.c:937 pg_ctl.c:1028 +#: pg_ctl.c:985 pg_ctl.c:1076 #, c-format msgid "%s: server does not shut down\n" msgstr "%s : le serveur ne s'est pas arrêté\n" -#: pg_ctl.c:939 pg_ctl.c:1030 +#: pg_ctl.c:987 pg_ctl.c:1078 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" msgstr "" -"ASTUCE : l'option « -m fast » déconnecte immédiatement les sessions plutôt que\n" +"ASTUCE : l'option « -m fast » déconnecte immédiatement les sessions plutôt " +"que\n" "d'attendre la déconnexion des sessions déjà présentes.\n" -#: pg_ctl.c:945 pg_ctl.c:1036 +#: pg_ctl.c:993 pg_ctl.c:1084 msgid "server stopped\n" msgstr "serveur arrêté\n" -#: pg_ctl.c:968 pg_ctl.c:1042 -msgid "starting server anyway\n" -msgstr "lancement du serveur malgré tout\n" +#: pg_ctl.c:1016 +msgid "trying to start server anyway\n" +msgstr "tentative de lancement du serveur malgré tout\n" -#: pg_ctl.c:977 +#: pg_ctl.c:1025 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "" "%s : ne peut pas relancer le serveur ; le serveur mono-utilisateur est en\n" "cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:980 pg_ctl.c:1066 +#: pg_ctl.c:1028 pg_ctl.c:1114 msgid "Please terminate the single-user server and try again.\n" msgstr "Merci d'arrêter le serveur mono-utilisateur et de réessayer.\n" -#: pg_ctl.c:1040 +#: pg_ctl.c:1088 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s : l'ancien processus serveur (PID : %ld) semble être parti\n" -#: pg_ctl.c:1063 +#: pg_ctl.c:1090 +msgid "starting server anyway\n" +msgstr "lancement du serveur malgré tout\n" + +#: pg_ctl.c:1111 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "" "%s : ne peut pas recharger le serveur ; le serveur mono-utilisateur est en\n" "cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:1072 +#: pg_ctl.c:1120 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s : n'a pas pu envoyer le signal de rechargement (PID : %ld) : %s\n" -#: pg_ctl.c:1077 +#: pg_ctl.c:1125 msgid "server signaled\n" msgstr "envoi d'un signal au serveur\n" -#: pg_ctl.c:1102 +#: pg_ctl.c:1150 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "" "%s : ne peut pas promouvoir le serveur ; le serveur mono-utilisateur est en\n" "cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:1110 +#: pg_ctl.c:1158 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" -msgstr "%s : ne peut pas promouvoir le serveur ; le serveur n'est pas en standby\n" +msgstr "" +"%s : ne peut pas promouvoir le serveur ; le serveur n'est pas en standby\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1173 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s : n'a pas pu créer le fichier « %s » signalant la promotion : %s\n" -#: pg_ctl.c:1131 +#: pg_ctl.c:1179 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s : n'a pas pu écrire le fichier « %s » signalant la promotion : %s\n" -#: pg_ctl.c:1139 +#: pg_ctl.c:1187 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s : n'a pas pu envoyer le signal de promotion (PID : %ld) : %s\n" -#: pg_ctl.c:1142 +#: pg_ctl.c:1190 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" -msgstr "%s : n'a pas pu supprimer le fichier « %s » signalant la promotion : %s\n" +msgstr "" +"%s : n'a pas pu supprimer le fichier « %s » signalant la promotion : %s\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1200 msgid "waiting for server to promote..." msgstr "en attente du serveur à promouvoir..." -#: pg_ctl.c:1166 +#: pg_ctl.c:1214 msgid "server promoted\n" msgstr "serveur promu\n" -#: pg_ctl.c:1171 +#: pg_ctl.c:1219 #, c-format msgid "%s: server did not promote in time\n" msgstr "%s : le serveur ne s'est pas promu à temps\n" -#: pg_ctl.c:1177 +#: pg_ctl.c:1225 msgid "server promoting\n" msgstr "serveur en cours de promotion\n" -#: pg_ctl.c:1224 +#: pg_ctl.c:1249 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "" +"%s : ne peut pas faire une rotation de fichier de traces ; le serveur mono-" +"utilisateur est en\n" +"cours d'exécution (PID : %ld)\n" + +#: pg_ctl.c:1259 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "" +"%s : n'a pas pu créer le fichier « %s » de demande de rotation des fichiers " +"de trace : %s\n" + +#: pg_ctl.c:1265 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "" +"%s : n'a pas pu écrire le fichier « %s » de demande de rotation des fichiers " +"de trace : %s\n" + +#: pg_ctl.c:1273 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "" +"%s : n'a pas pu envoyer le signal de rotation des fichiers de trace (PID : " +"%ld) : %s\n" + +#: pg_ctl.c:1276 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "" +"%s : n'a pas pu supprimer le fichier « %s » signalant la demande de rotation " +"des fichiers de trace : %s\n" + +#: pg_ctl.c:1281 +msgid "server signaled to rotate log file\n" +msgstr "envoi d'un signal au serveur pour faire une rotation des traces\n" + +#: pg_ctl.c:1328 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" -msgstr "%s : le serveur mono-utilisateur est en cours d'exécution (PID : %ld)\n" +msgstr "" +"%s : le serveur mono-utilisateur est en cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:1238 +#: pg_ctl.c:1342 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s : le serveur est en cours d'exécution (PID : %ld)\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1358 #, c-format msgid "%s: no server running\n" msgstr "%s : aucun serveur en cours d'exécution\n" -#: pg_ctl.c:1271 +#: pg_ctl.c:1375 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s : n'a pas pu envoyer le signal %d (PID : %ld) : %s\n" -#: pg_ctl.c:1328 +#: pg_ctl.c:1432 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s : n'a pas pu trouver l'exécutable du programme\n" -#: pg_ctl.c:1338 +#: pg_ctl.c:1442 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s : n'a pas pu trouver l'exécutable postgres\n" -#: pg_ctl.c:1408 pg_ctl.c:1442 +#: pg_ctl.c:1512 pg_ctl.c:1546 #, c-format msgid "%s: could not open service manager\n" msgstr "%s : n'a pas pu ouvrir le gestionnaire de services\n" -#: pg_ctl.c:1414 +#: pg_ctl.c:1518 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s : le service « %s » est déjà enregistré\n" -#: pg_ctl.c:1425 +#: pg_ctl.c:1529 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s : n'a pas pu enregistrer le service « %s » : code d'erreur %lu\n" -#: pg_ctl.c:1448 +#: pg_ctl.c:1552 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s : le service « %s » n'est pas enregistré\n" -#: pg_ctl.c:1455 +#: pg_ctl.c:1559 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s : n'a pas pu ouvrir le service « %s » : code d'erreur %lu\n" -#: pg_ctl.c:1464 +#: pg_ctl.c:1568 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s : n'a pas pu supprimer le service « %s » : code d'erreur %lu\n" -#: pg_ctl.c:1551 +#: pg_ctl.c:1655 msgid "Waiting for server startup...\n" msgstr "En attente du démarrage du serveur...\n" -#: pg_ctl.c:1554 +#: pg_ctl.c:1658 msgid "Timed out waiting for server startup\n" msgstr "Dépassement du délai pour le démarrage du serveur\n" -#: pg_ctl.c:1558 +#: pg_ctl.c:1662 msgid "Server started and accepting connections\n" msgstr "Serveur lancé et acceptant les connexions\n" -#: pg_ctl.c:1613 +#: pg_ctl.c:1717 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s : n'a pas pu démarrer le service « %s » : code d'erreur %lu\n" -#: pg_ctl.c:1687 +#: pg_ctl.c:1787 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s : ATTENTION : ne peut pas crér les jetons restreints sur cette plateforme\n" +msgstr "" +"%s : ATTENTION : ne peut pas créer les jetons restreints sur cette " +"plateforme\n" -#: pg_ctl.c:1700 +#: pg_ctl.c:1800 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s : n'a pas pu ouvrir le jeton du processus : code d'erreur %lu\n" -#: pg_ctl.c:1714 +#: pg_ctl.c:1814 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s : n'a pas pu allouer les SID : code d'erreur %lu\n" -#: pg_ctl.c:1734 +#: pg_ctl.c:1841 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s : n'a pas pu créer le jeton restreint : code d'erreur %lu\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1872 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" -msgstr "%s : ATTENTION : n'a pas pu localiser toutes les fonctions objet de job dans l'API système\n" +msgstr "" +"%s : ATTENTION : n'a pas pu localiser toutes les fonctions objet de job dans " +"l'API système\n" + +#: pg_ctl.c:1969 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "" +"%s : n'a pas pu obtenir les LUID pour les droits : code d'erreur %lu\n" + +#: pg_ctl.c:1977 pg_ctl.c:1992 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "" +"%s : n'a pas pu obtenir l'information sur le jeton : code d'erreur %lu\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:1986 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s : mémoire épuisée\n" + +#: pg_ctl.c:2016 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayer « %s --help » pour plus d'informations.\n" -#: pg_ctl.c:1856 +#: pg_ctl.c:2024 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -493,74 +568,82 @@ msgstr "" "PostgreSQL.\n" "\n" -#: pg_ctl.c:1857 +#: pg_ctl.c:2025 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: pg_ctl.c:1858 +#: pg_ctl.c:2026 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" msgstr " %s init[db] [-D RÉP_DONNÉES] [-s] [-o OPTIONS]\n" -#: pg_ctl.c:1859 +#: pg_ctl.c:2027 #, c-format msgid "" -" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-p PATH] [-c]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" " %s start [-D RÉP_DONNÉES] [-l NOM_FICHIER] [-W] [-t SECS] [-s]\n" " [-o OPTIONS] [-p CHEMIN] [-c]\n" -#: pg_ctl.c:1861 +#: pg_ctl.c:2029 #, c-format -msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" msgstr " %s stop [-D RÉP_DONNÉES] [-m MODE_ARRÊT] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1862 +#: pg_ctl.c:2030 #, c-format msgid "" -" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-c]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" " %s restart [-D RÉP_DONNÉES] [-m MODE_ARRÊT] [-W] [-t SECS] [-s]\n" " [-o OPTIONS] [-c]\n" -#: pg_ctl.c:1864 +#: pg_ctl.c:2032 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" msgstr " %s reload [-D RÉP_DONNÉES] [-s]\n" -#: pg_ctl.c:1865 +#: pg_ctl.c:2033 #, c-format -msgid " %s status [-D DATADIR]\n" +msgid " %s status [-D DATADIR]\n" msgstr " %s status [-D RÉP_DONNÉES]\n" -#: pg_ctl.c:1866 +#: pg_ctl.c:2034 #, c-format -msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" msgstr " %s promote [-D RÉP_DONNÉES] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1867 +#: pg_ctl.c:2035 #, c-format -msgid " %s kill SIGNALNAME PID\n" +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s reload [-D RÉP_DONNÉES] [-s]\n" + +#: pg_ctl.c:2036 +#, c-format +msgid " %s kill SIGNALNAME PID\n" msgstr " %s kill NOM_SIGNAL PID\n" -#: pg_ctl.c:1869 +#: pg_ctl.c:2038 #, c-format msgid "" -" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" -" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" msgstr "" -" %s register [-D RÉP_DONNÉES] [-N NOM_SERVICE] [-U NOM_UTILISATEUR] [-P MOT_DE_PASSE]\n" -" [-S TYPE_DÉMARRAGE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +" %s register [-D RÉP_DONNÉES] [-N NOM_SERVICE] [-U NOM_UTILISATEUR] [-P " +"MOT_DE_PASSE]\n" +" [-S TYPE_DÉMARRAGE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" -#: pg_ctl.c:1871 +#: pg_ctl.c:2040 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N NOM_SERVICE]\n" -#: pg_ctl.c:1874 +#: pg_ctl.c:2043 #, c-format msgid "" "\n" @@ -569,58 +652,60 @@ msgstr "" "\n" "Options générales :\n" -#: pg_ctl.c:1875 +#: pg_ctl.c:2044 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=RÉP_DONNÉES emplacement de stockage du cluster\n" -#: pg_ctl.c:1877 +#: pg_ctl.c:2046 #, c-format -msgid " -e SOURCE event source for logging when running as a service\n" +msgid "" +" -e SOURCE event source for logging when running as a service\n" msgstr "" " -e SOURCE source de l'événement pour la trace lors de\n" " l'exécution en tant que service\n" -#: pg_ctl.c:1879 +#: pg_ctl.c:2048 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr "" " -s, --silent affiche uniquement les erreurs, aucun message\n" " d'informations\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:2049 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr "" " -t, --timeout=SECS durée en secondes à attendre lors de\n" " l'utilisation de l'option -w\n" -#: pg_ctl.c:1881 +#: pg_ctl.c:2050 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version puis quitte\n" -#: pg_ctl.c:1882 +#: pg_ctl.c:2051 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait attend la fin de l'opération (par défaut)\n" -#: pg_ctl.c:1883 +#: pg_ctl.c:2052 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait n'attend pas la fin de l'opération\n" -#: pg_ctl.c:1884 +#: pg_ctl.c:2053 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide puis quitte\n" -#: pg_ctl.c:1885 +#: pg_ctl.c:2054 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" -msgstr "Si l'option -D est omise, la variable d'environnement PGDATA est utilisée.\n" +msgstr "" +"Si l'option -D est omise, la variable d'environnement PGDATA est utilisée.\n" -#: pg_ctl.c:1887 +#: pg_ctl.c:2056 #, c-format msgid "" "\n" @@ -629,24 +714,25 @@ msgstr "" "\n" "Options pour le démarrage ou le redémarrage :\n" -#: pg_ctl.c:1889 +#: pg_ctl.c:2058 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" -msgstr " -c, --core-files autorise postgres à produire des fichiers core\n" +msgstr "" +" -c, --core-files autorise postgres à produire des fichiers core\n" -#: pg_ctl.c:1891 +#: pg_ctl.c:2060 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files non applicable à cette plateforme\n" -#: pg_ctl.c:1893 +#: pg_ctl.c:2062 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr "" " -l, --log=NOM_FICHIER écrit (ou ajoute) le journal du serveur dans\n" " NOM_FICHIER\n" -#: pg_ctl.c:1894 +#: pg_ctl.c:2063 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -656,12 +742,12 @@ msgstr "" " postgres (exécutable du serveur PostgreSQL)\n" " ou à initdb\n" -#: pg_ctl.c:1896 +#: pg_ctl.c:2065 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p CHEMIN_POSTGRES normalement pas nécessaire\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:2066 #, c-format msgid "" "\n" @@ -670,14 +756,15 @@ msgstr "" "\n" "Options pour l'arrêt ou le redémarrage :\n" -#: pg_ctl.c:1898 +#: pg_ctl.c:2067 #, c-format -msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgid "" +" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr "" " -m, --mode=MODE MODE peut valoir « smart », « fast » ou\n" " « immediate »\n" -#: pg_ctl.c:1900 +#: pg_ctl.c:2069 #, c-format msgid "" "\n" @@ -686,24 +773,29 @@ msgstr "" "\n" "Les modes d'arrêt sont :\n" -#: pg_ctl.c:1901 +#: pg_ctl.c:2070 #, c-format msgid " smart quit after all clients have disconnected\n" -msgstr " smart quitte après déconnexion de tous les clients\n" +msgstr "" +" smart quitte après déconnexion de tous les clients\n" -#: pg_ctl.c:1902 +#: pg_ctl.c:2071 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" -msgstr " fast quitte directement, et arrête correctement (par défaut)\n" +msgstr "" +" fast quitte directement, et arrête correctement (par " +"défaut)\n" -#: pg_ctl.c:1903 +#: pg_ctl.c:2072 #, c-format -msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgid "" +" immediate quit without complete shutdown; will lead to recovery on " +"restart\n" msgstr "" " immediate quitte sans arrêt complet ; entraîne une\n" " restauration au démarrage suivant\n" -#: pg_ctl.c:1905 +#: pg_ctl.c:2074 #, c-format msgid "" "\n" @@ -712,7 +804,7 @@ msgstr "" "\n" "Signaux autorisés pour kill :\n" -#: pg_ctl.c:1909 +#: pg_ctl.c:2078 #, c-format msgid "" "\n" @@ -721,35 +813,36 @@ msgstr "" "\n" "Options d'enregistrement ou de dés-enregistrement :\n" -#: pg_ctl.c:1910 +#: pg_ctl.c:2079 #, c-format -msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgid "" +" -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr "" " -N NOM_SERVICE nom du service utilisé pour l'enregistrement du\n" " serveur PostgreSQL\n" -#: pg_ctl.c:1911 +#: pg_ctl.c:2080 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr "" " -P MOT_DE_PASSE mot de passe du compte utilisé pour\n" " l'enregistrement du serveur PostgreSQL\n" -#: pg_ctl.c:1912 +#: pg_ctl.c:2081 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr "" " -U NOM_UTILISATEUR nom de l'utilisateur du compte utilisé pour\n" " l'enregistrement du serveur PostgreSQL\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:2082 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr "" " -S TYPE_DÉMARRAGE type de démarrage du service pour enregistrer le\n" " serveur PostgreSQL\n" -#: pg_ctl.c:1915 +#: pg_ctl.c:2084 #, c-format msgid "" "\n" @@ -758,53 +851,57 @@ msgstr "" "\n" "Les types de démarrage sont :\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:2085 #, c-format -msgid " auto start service automatically during system startup (default)\n" +msgid "" +" auto start service automatically during system startup (default)\n" msgstr "" -" auto démarre le service automatiquement lors du démarrage du système\n" +" auto démarre le service automatiquement lors du démarrage du " +"système\n" " (par défaut)\n" -#: pg_ctl.c:1917 +#: pg_ctl.c:2086 #, c-format msgid " demand start service on demand\n" msgstr " demand démarre le service à la demande\n" -#: pg_ctl.c:1920 +#: pg_ctl.c:2089 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapporter les bogues à .\n" +"Rapporter les bogues à .\n" -#: pg_ctl.c:1945 +#: pg_ctl.c:2114 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s : mode d'arrêt non reconnu « %s »\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2143 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s : signal non reconnu « %s »\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:2160 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s : type de redémarrage « %s » non reconnu\n" -#: pg_ctl.c:2049 +#: pg_ctl.c:2215 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" -msgstr "%s : n'a pas déterminer le répertoire des données en utilisant la commande « %s »\n" +msgstr "" +"%s : n'a pas déterminer le répertoire des données en utilisant la commande « " +"%s »\n" -#: pg_ctl.c:2074 +#: pg_ctl.c:2240 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s : le fichier de contrôle semble corrompu\n" -#: pg_ctl.c:2144 +#: pg_ctl.c:2308 #, c-format msgid "" "%s: cannot be run as root\n" @@ -815,34 +912,35 @@ msgstr "" "Connectez-vous (par exemple en utilisant « su ») sous l'utilisateur (non\n" " privilégié) qui sera propriétaire du processus serveur.\n" -#: pg_ctl.c:2228 +#: pg_ctl.c:2392 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s : option -S non supportée sur cette plateforme\n" -#: pg_ctl.c:2265 +#: pg_ctl.c:2429 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" -#: pg_ctl.c:2289 +#: pg_ctl.c:2455 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s : arguments manquant pour le mode kill\n" -#: pg_ctl.c:2307 +#: pg_ctl.c:2473 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s : mode d'opération « %s » non reconnu\n" -#: pg_ctl.c:2317 +#: pg_ctl.c:2483 #, c-format msgid "%s: no operation specified\n" msgstr "%s : aucune opération indiquée\n" -#: pg_ctl.c:2338 +#: pg_ctl.c:2504 #, c-format -msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgid "" +"%s: no database directory specified and environment variable PGDATA unset\n" msgstr "" "%s : aucun répertoire de bases de données indiqué et variable\n" "d'environnement PGDATA non initialisée\n" @@ -852,20 +950,25 @@ msgstr "" #~ "%s: -w option is not supported when starting a pre-9.1 server\n" #~ msgstr "" #~ "\n" -#~ "%s : l'option -w n'est pas supportée lors du démarrage d'un serveur pré-9.1\n" +#~ "%s : l'option -w n'est pas supportée lors du démarrage d'un serveur " +#~ "pré-9.1\n" #~ msgid "" #~ "\n" #~ "%s: -w option cannot use a relative socket directory specification\n" #~ msgstr "" #~ "\n" -#~ "%s : l'option -w ne peut pas utiliser un chemin relatif vers le répertoire de\n" +#~ "%s : l'option -w ne peut pas utiliser un chemin relatif vers le " +#~ "répertoire de\n" #~ "la socket\n" #~ msgid "%s: could not wait for server because of misconfiguration\n" -#~ msgstr "%s : n'a pas pu attendre le serveur à cause d'une mauvaise configuration\n" +#~ msgstr "" +#~ "%s : n'a pas pu attendre le serveur à cause d'une mauvaise configuration\n" -#~ msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" +#~ msgid "" +#~ " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" +#~ "\"]\n" #~ msgstr "" #~ " %s start [-w] [-t SECS] [-D RÉP_DONNÉES] [-s] [-l NOM_FICHIER]\n" #~ " [-o \"OPTIONS\"]\n" @@ -888,16 +991,16 @@ msgstr "" #~ msgid "could not change directory to \"%s\"" #~ msgstr "n'a pas pu accéder au répertoire « %s »" -#~ msgid "%s: out of memory\n" -#~ msgstr "%s : mémoire épuisée\n" - #~ msgid "" #~ "%s is a utility to start, stop, restart, reload configuration files,\n" -#~ "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n" +#~ "report the status of a PostgreSQL server, or signal a PostgreSQL " +#~ "process.\n" #~ "\n" #~ msgstr "" -#~ "%s est un outil qui permet de démarrer, arrêter, redémarrer, recharger les\n" -#~ "les fichiers de configuration, rapporter le statut d'un serveur PostgreSQL\n" +#~ "%s est un outil qui permet de démarrer, arrêter, redémarrer, recharger " +#~ "les\n" +#~ "les fichiers de configuration, rapporter le statut d'un serveur " +#~ "PostgreSQL\n" #~ "ou d'envoyer un signal à un processus PostgreSQL\n" #~ "\n" @@ -918,7 +1021,17 @@ msgstr "" #~ "%s: this data directory appears to be running a pre-existing postmaster\n" #~ msgstr "" #~ "\n" -#~ "%s : ce répertoire des données semble être utilisé par un postmaster déjà existant\n" +#~ "%s : ce répertoire des données semble être utilisé par un postmaster déjà " +#~ "existant\n" #~ msgid "server is still starting up\n" #~ msgstr "le serveur est toujours en cours de démarrage\n" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "le processus fils a été terminé par le signal %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "n'a pas pu lire le lien symbolique « %s »" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "n'a pas pu modifier le répertoire par « %s » : %s" diff --git a/src/bin/pg_ctl/po/he.po b/src/bin/pg_ctl/po/he.po index b73b44a0134..420e2f2a4e7 100644 --- a/src/bin/pg_ctl/po/he.po +++ b/src/bin/pg_ctl/po/he.po @@ -142,7 +142,7 @@ msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות להפעיל שרת: %s\n" #: pg_ctl.c:495 #, c-format msgid "%s: could not start server: error code %lu\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות להפעיל שרת: קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות להפעיל שרת: קוד שגי××” %lu\n" #: pg_ctl.c:572 #, c-format @@ -263,12 +263,12 @@ msgstr "×”×× ×”×©×¨×ª פועל?\n" #: pg_ctl.c:967 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" -msgstr "תכנית %s: ×œ× ×™×›×•×œ להפסיק ×ת השרת; מופעל שרת למשתמש יחיד (PID: % ld)\n" +msgstr "תכנית %s: ×œ× ×™×›×•×œ להפסיק ×ת השרת; מופעל שרת למשתמש יחיד (PID: %ld)\n" #: pg_ctl.c:975 pg_ctl.c:1070 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות עצירה (PID: % ld): %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות עצירה (PID: %ld): %s\n" #: pg_ctl.c:982 msgid "server shutting down\n" @@ -312,7 +312,7 @@ msgstr "מ×תחל לשרת בכל מקרה\n" #: pg_ctl.c:1058 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" -msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להפעיל מחדש ×ת השרת; מופעל שרת למשתמש יחיד (PID: % ld)\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להפעיל מחדש ×ת השרת; מופעל שרת למשתמש יחיד (PID: %ld)\n" #: pg_ctl.c:1061 pg_ctl.c:1146 msgid "Please terminate the single-user server and try again.\n" @@ -321,17 +321,17 @@ msgstr "×× × ×›×‘×” ×ת שרת המשתמש היחיד ונסה שוב\n" #: pg_ctl.c:1120 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" -msgstr "תכנית %s: תהליך השרת הישן (PID: % ld) כנר××” פועל\n" +msgstr "תכנית %s: תהליך השרת הישן (PID: %ld) כנר××” פועל\n" #: pg_ctl.c:1143 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" -msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להפעיל מחדש ×ת השרת; מופעל שרת למשתמש יחיד (PID: % ld)\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להפעיל מחדש ×ת השרת; מופעל שרת למשתמש יחיד (PID: %ld)\n" #: pg_ctl.c:1152 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות להפעלה מחדש (PID: % ld): %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות להפעלה מחדש (PID: %ld): %s\n" #: pg_ctl.c:1157 msgid "server signaled\n" @@ -340,7 +340,7 @@ msgstr "שרת ×יתת\n" #: pg_ctl.c:1182 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" -msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ ×œ×§×“× ×©×¨×ª; מופעל שרת למשתמש יחיד (PID: % ld)\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ ×œ×§×“× ×©×¨×ª; מופעל שרת למשתמש יחיד (PID: %ld)\n" #: pg_ctl.c:1190 #, c-format @@ -360,7 +360,7 @@ msgstr "תכנית %s: ×œ× ×ž×¦×œ×™×— לכתוב לקובץ ×”×ות לקידו #: pg_ctl.c:1219 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ת ×”×ות לקד×(PID: % ld): %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ת ×”×ות לקד×(PID: %ld): %s\n" #: pg_ctl.c:1222 #, c-format @@ -386,12 +386,12 @@ msgstr "שרת בקידו×\n" #: pg_ctl.c:1301 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" -msgstr "תכנית %s: שרת משתמש יחיד פועל (PID: % ld)\n" +msgstr "תכנית %s: שרת משתמש יחיד פועל (PID: %ld)\n" #: pg_ctl.c:1314 #, c-format msgid "%s: server is running (PID: %ld)\n" -msgstr "תכנית %s: שרת פועל (PID: % ld)\n" +msgstr "תכנית %s: שרת פועל (PID: %ld)\n" #: pg_ctl.c:1330 #, c-format @@ -401,7 +401,7 @@ msgstr "תכנית %s: ×ין ×©×¨×ª×™× ×¤×¢×™×œ×™×\n" #: pg_ctl.c:1348 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות %d (PID: % ld): %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לשלוח ×ות %d (PID: %ld): %s\n" #: pg_ctl.c:1405 #, c-format @@ -426,7 +426,7 @@ msgstr "תכנית %s: שירות '%s' כבר רשו×\n" #: pg_ctl.c:1502 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" -msgstr "תכנית %s: ×ין ×פשרות ×œ×¨×©×•× ×ת השירות \"%s\": קוד שגי××” % lu\n" +msgstr "תכנית %s: ×ין ×פשרות ×œ×¨×©×•× ×ת השירות \"%s\": קוד שגי××” %lu\n" #: pg_ctl.c:1525 #, c-format @@ -436,12 +436,12 @@ msgstr "תכנית %s: שירות '%s' ×ינו רשו×\n" #: pg_ctl.c:1532 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לפתוח שירות '%s': קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לפתוח שירות '%s': קוד שגי××” %lu\n" #: pg_ctl.c:1541 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" -msgstr "תכנית %s: ×œ× ×™×›×•×œ לבטל ×ת השירות \"%s\": קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× ×™×›×•×œ לבטל ×ת השירות \"%s\": קוד שגי××” %lu\n" #: pg_ctl.c:1628 msgid "Waiting for server startup...\n" @@ -458,7 +458,7 @@ msgstr "שרת עלה ומקבל חיבורי×\n" #: pg_ctl.c:1690 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" -msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות להפעיל שירות '%s': קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות להפעיל שירות '%s': קוד שגי××” %lu\n" #: pg_ctl.c:1764 #, c-format @@ -468,12 +468,12 @@ msgstr "תכנית %s: ×זהרה: ×ין ×פשרות ליצור ×סימונ #: pg_ctl.c:1777 #, c-format msgid "%s: could not open process token: error code %lu\n" -msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ לפתוח ×ת התהליך token: קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ לפתוח ×ת התהליך token: קוד שגי××” %lu\n" #: pg_ctl.c:1791 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להקצות SID: קוד שגי××” % lu\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להקצות SID: קוד שגי××” %lu\n" #: pg_ctl.c:1811 #, c-format diff --git a/src/bin/pg_ctl/po/it.po b/src/bin/pg_ctl/po/it.po index 640de07ec88..825ec8e8bf0 100644 --- a/src/bin/pg_ctl/po/it.po +++ b/src/bin/pg_ctl/po/it.po @@ -1,35 +1,33 @@ # -# Translation of pg_ctl to Italian -# PostgreSQL Project +# pg_ctl.po +# Italian message translation file for pg_ctl # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Emanuele Zamprogno +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017. +# Emanuele Zamprogno , 2010. # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: pg_ctl (PostgreSQL) 10\n" +"Project-Id-Version: pg_ctl (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-22 22:45+0000\n" -"PO-Revision-Date: 2017-05-29 17:04+0100\n" +"POT-Creation-Date: 2018-10-08 14:15+0000\n" +"PO-Revision-Date: 2018-10-08 21:53+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: utf-8\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -118,80 +116,62 @@ msgstr "processo figlio uscito con stato non riconosciuto %d" msgid "could not get current working directory: %s\n" msgstr "determinazione della directory corrente fallita: %s\n" -#: pg_ctl.c:251 +#: pg_ctl.c:257 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: la directory \"%s\" non esiste\n" -#: pg_ctl.c:254 +#: pg_ctl.c:260 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: accesso alla directory \"%s\" fallito: %s\n" -#: pg_ctl.c:268 +#: pg_ctl.c:273 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: la directory \"%s\" non è la directory di un cluster di database\n" -#: pg_ctl.c:281 +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: apertura del file PID \"%s\" fallita: %s\n" -#: pg_ctl.c:290 +#: pg_ctl.c:295 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: il file PID \"%s\" è vuoto\n" -#: pg_ctl.c:293 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: dati non validi nel file PID \"%s\"\n" -#: pg_ctl.c:443 pg_ctl.c:471 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: errore di avvio del server: %s\n" -#: pg_ctl.c:495 +#: pg_ctl.c:511 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: errore di avvio del server: codice dell'errore %lu\n" -#: pg_ctl.c:572 -#, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: l'opzione -w non è supportata per avviare un server pre-9.1\n" - -#: pg_ctl.c:637 -#, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: l'opzione -w non può specificare una directory socket relativa\n" - -#: pg_ctl.c:739 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: non è possibile configurare il limite di grandezza dei core file; impedito dall'hard limit\n" -#: pg_ctl.c:764 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: lettura del file \"%s\" fallita\n" -#: pg_ctl.c:769 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: il file di opzione \"%s\" deve avere esattamente una riga\n" -#: pg_ctl.c:820 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -202,7 +182,7 @@ msgstr "" "nella stessa directory di \"%s\".\n" "Verifica che l'installazione sia corretta.\n" -#: pg_ctl.c:826 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -213,37 +193,38 @@ msgstr "" "la stessa versione di %s.\n" "Verifica che l'installazione sia corretta.\n" -#: pg_ctl.c:859 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: inizializzazione del sistema di database fallita\n" -#: pg_ctl.c:874 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: un altro server potrebbe essere in esecuzione; si sta provando ad avviare il server ugualmente\n" -#: pg_ctl.c:912 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "in attesa che il server si avvii..." -#: pg_ctl.c:917 pg_ctl.c:1024 pg_ctl.c:1115 pg_ctl.c:1244 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr " fatto\n" -#: pg_ctl.c:918 +#: pg_ctl.c:833 msgid "server started\n" msgstr "il server è stato avviato\n" -#: pg_ctl.c:921 pg_ctl.c:925 pg_ctl.c:1249 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " attesa interrotta\n" -#: pg_ctl.c:922 -msgid "server is still starting up\n" -msgstr "il server si sta ancora avviando\n" +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: il server non è partito nel tempo previsto\n" -#: pg_ctl.c:926 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -252,43 +233,34 @@ msgstr "" "%s: l'avvio del server è fallito\n" "Esamina il log di output.\n" -#: pg_ctl.c:932 pg_ctl.c:1016 pg_ctl.c:1106 -msgid " failed\n" -msgstr " fallito\n" - -#: pg_ctl.c:933 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: non è stato possibile attendere il server a causa di configurazione errata\n" - -#: pg_ctl.c:939 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "il server si sta avviando\n" -#: pg_ctl.c:960 pg_ctl.c:1046 pg_ctl.c:1136 pg_ctl.c:1175 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: il file PID \"%s\" non esiste\n" -#: pg_ctl.c:961 pg_ctl.c:1048 pg_ctl.c:1137 pg_ctl.c:1176 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "Il server è in esecuzione?\n" -#: pg_ctl.c:967 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" -msgstr "%s: non è possibile fermare il server; il server è in esecuzione in modalità a singolo utente (PID: %ld)\n" +msgstr "%s: non è possibile fermare il server; il server è in esecuzione in modalità a utente singolo (PID: %ld)\n" -#: pg_ctl.c:975 pg_ctl.c:1070 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: invio del segnale di arresto fallito (PID: %ld): %s\n" -#: pg_ctl.c:982 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "il server è in fase di arresto\n" -#: pg_ctl.c:997 pg_ctl.c:1085 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -298,16 +270,20 @@ msgstr "" "L'arresto non sarà completato finché non sarà chiamata pg_stop_backup().\n" "\n" -#: pg_ctl.c:1001 pg_ctl.c:1089 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "in attesa dell'arresto del server...." -#: pg_ctl.c:1018 pg_ctl.c:1108 +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr " fallito\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: il server non si è arrestato\n" -#: pg_ctl.c:1020 pg_ctl.c:1110 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -315,196 +291,216 @@ msgstr "" "NOTA: L'opzione \"-m fast\" disconnette le sessioni immediatamente invece di\n" "attendere che siano le sessioni a disconnettersi.\n" -#: pg_ctl.c:1026 pg_ctl.c:1116 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "il server è stato arrestato\n" -#: pg_ctl.c:1049 pg_ctl.c:1122 -msgid "starting server anyway\n" -msgstr "il server si sta avviando comunque\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "si sta provando ad avviare il server ugualmente\n" -#: pg_ctl.c:1058 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" -msgstr "%s: non è possibile riavviare il server; il server è in esecuzione in modalità a singolo utente (PID: %ld)\n" +msgstr "%s: non è possibile riavviare il server; il server è in esecuzione in modalità a utente singolo (PID: %ld)\n" -#: pg_ctl.c:1061 pg_ctl.c:1146 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" -msgstr "Si prega di terminare il server in modalità singolo utente e di riprovare.\n" +msgstr "Si prega di terminare il server in modalità utente singolo e di riprovare.\n" -#: pg_ctl.c:1120 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: il vecchio processo del server (PID: %ld) sembra non essere più attivo\n" -#: pg_ctl.c:1143 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "il server si sta avviando comunque\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" -msgstr "%s: non è possibile eseguire il reload del server; il server è in esecuzione in modalità a singolo utente (PID: %ld)\n" +msgstr "%s: non è possibile eseguire il reload del server; il server è in esecuzione in modalità a utente singolo (PID: %ld)\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: invio segnale di reload fallito (PID: %ld): %s\n" -#: pg_ctl.c:1157 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "segnale inviato al server\n" -#: pg_ctl.c:1182 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" -msgstr "%s: non è possibile promuovere il server: il server è in esecuzione in modalità a singolo utente (PID: %ld)\n" +msgstr "%s: non è possibile promuovere il server: il server è in esecuzione in modalità a utente singolo (PID: %ld)\n" -#: pg_ctl.c:1190 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: non è possibile promuovere il server: il server non è in modalità standby\n" -#: pg_ctl.c:1205 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: creazione del file di segnale di promozione \"%s\" fallito: %s\n" -#: pg_ctl.c:1211 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: scrittura del file di segnale di promozione \"%s\" fallita: %s\n" -#: pg_ctl.c:1219 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: invio del segnale di promozione fallito (PID: %ld): %s\n" -#: pg_ctl.c:1222 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: rimozione del file di segnale di promozione \"%s\" fallita: %s\n" -#: pg_ctl.c:1231 +#: pg_ctl.c:1146 msgid "waiting for server to promote..." msgstr "in attesa della promozione del server..." -#: pg_ctl.c:1245 +#: pg_ctl.c:1160 msgid "server promoted\n" msgstr "server promosso\n" -#: pg_ctl.c:1250 -msgid "server is still promoting\n" -msgstr "il server è in fase di promozione\n" +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: il server non è stato promosso nel tempo previsto\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1171 msgid "server promoting\n" msgstr "il server sta venendo promosso\n" -#: pg_ctl.c:1301 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" -msgstr "%s: il server è in esecuzione in modalità a singolo utente (PID: %ld)\n" +msgstr "%s: il server è in esecuzione in modalità a utente singolo (PID: %ld)\n" -#: pg_ctl.c:1314 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: il server è in esecuzione (PID: %ld)\n" -#: pg_ctl.c:1330 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: nessun server in esecuzione\n" -#: pg_ctl.c:1348 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: invio del segnale %d fallito (PID: %ld): %s\n" -#: pg_ctl.c:1405 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: il proprio programma eseguibile non è stato trovato\n" -#: pg_ctl.c:1415 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: il programma eseguibile postgres non è stato trovato\n" -#: pg_ctl.c:1485 pg_ctl.c:1519 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: apertura del service manager fallita\n" -#: pg_ctl.c:1491 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: il servizio \"%s\" è già registrato\n" -#: pg_ctl.c:1502 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: registrazione del servizio \"%s\" fallita: codice errore %lu\n" -#: pg_ctl.c:1525 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: il servizio \"%s\" non è registrato\n" -#: pg_ctl.c:1532 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: apertura del servizio \"%s\" fallita: codice errore %lu\n" -#: pg_ctl.c:1541 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: rimozione della registrazione del servizio \"%s\" fallita: codice errore %lu\n" -#: pg_ctl.c:1628 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" msgstr "In attesa che il server si avvii...\n" -#: pg_ctl.c:1631 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "Il tempo di attesa per l'avvio del server è scaduto\n" -#: pg_ctl.c:1635 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "Il server è avviato e accetta connessioni\n" -#: pg_ctl.c:1690 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: non è possibile avviare il servizio \"%s\": codice errore %lu\n" -#: pg_ctl.c:1764 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: ATTENZIONE: non è possibile creare token ristretti su questa piattaforma\n" -#: pg_ctl.c:1777 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: apertura del token di processo fallita: codice errore %lu\n" -#: pg_ctl.c:1791 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: allocazione dei SID fallita: codice errore %lu\n" -#: pg_ctl.c:1811 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: creazione del token ristretto fallita: codice errore %lu\n" -#: pg_ctl.c:1842 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: ATTENZIONE: non tutte le funzioni di controllo dei job nella API di sistema sono state trovate\n" -#: pg_ctl.c:1925 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: errore nella lettura dei LUID per i privilegi: codice di errore %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: errore nella lettura del token di informazione: codice di errore %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: memoria esaurita\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: pg_ctl.c:1933 +#: pg_ctl.c:1913 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -513,17 +509,17 @@ msgstr "" "%s è un programma per inizializzare, avviare, fermare o controllare un server PostgreSQL.\n" "\n" -#: pg_ctl.c:1934 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "Utilizzo:\n" -#: pg_ctl.c:1935 +#: pg_ctl.c:1915 #, c-format msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" msgstr " %s init[db] [-D DATADIR] [-s] [-o OPZIONI]\n" -#: pg_ctl.c:1936 +#: pg_ctl.c:1916 #, c-format msgid "" " %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" @@ -532,12 +528,12 @@ msgstr "" " %s start [-D DATADIR] [-l NOMEFILE] [-W] [-t SEC] [-s]\n" " [-o OPZIONI] [-p PERCORSO] [-c]\n" -#: pg_ctl.c:1938 +#: pg_ctl.c:1918 #, c-format msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" msgstr " %s stop [-D DATADIR] [-m MODO-ARRESTO] [-W] [-t SEC] [-s]\n" -#: pg_ctl.c:1939 +#: pg_ctl.c:1919 #, c-format msgid "" " %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" @@ -546,27 +542,27 @@ msgstr "" " %s restart [-D DATADIR] [-m MODO-ARRESTO] [-W] [-t SEC] [-s]\n" " [-o OPTIONS] [-c]\n" -#: pg_ctl.c:1941 +#: pg_ctl.c:1921 #, c-format msgid " %s reload [-D DATADIR] [-s]\n" msgstr " %s reload [-D DATADIR] [-s]\n" -#: pg_ctl.c:1942 +#: pg_ctl.c:1922 #, c-format msgid " %s status [-D DATADIR]\n" msgstr " %s status [-D DATADIR]\n" -#: pg_ctl.c:1943 +#: pg_ctl.c:1923 #, c-format msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" msgstr " %s promote [-D DATADIR] [-W] [-t SEC] [-s]\n" -#: pg_ctl.c:1944 +#: pg_ctl.c:1924 #, c-format msgid " %s kill SIGNALNAME PID\n" msgstr " %s kill SEGNALE PID\n" -#: pg_ctl.c:1946 +#: pg_ctl.c:1926 #, c-format msgid "" " %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" @@ -575,12 +571,12 @@ msgstr "" " %s register [-D DATADIR] [-N SERVIZIO] [-U UTENTE] [-P PASSWORD]\n" " [-S TIPO-AVVIO] [-e SORGENTE] [-W] [-t SEC] [-s] [-o OPZIONI]\n" -#: pg_ctl.c:1948 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N SERVIZIO]\n" -#: pg_ctl.c:1951 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" @@ -589,52 +585,52 @@ msgstr "" "\n" "Opzioni comuni:\n" -#: pg_ctl.c:1952 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata DATADIR posizione dell'area di archiviazione del database\n" -#: pg_ctl.c:1954 +#: pg_ctl.c:1934 #, c-format msgid " -e SOURCE event source for logging when running as a service\n" msgstr " -e SORGENTE sorgente eventi per il log quando eseguito come servizio\n" -#: pg_ctl.c:1956 +#: pg_ctl.c:1936 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent mostra solo gli errori, non i messaggi di informazione\n" -#: pg_ctl.c:1957 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SEC secondi da aspettare quando si usa l'opzione -w\n" -#: pg_ctl.c:1958 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostra informazioni sulla versione ed esci\n" -#: pg_ctl.c:1959 +#: pg_ctl.c:1939 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait aspetta fino al completamento dell'operazione (default)\n" -#: pg_ctl.c:1960 +#: pg_ctl.c:1940 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait non aspettare fino al completamento dell'operazione\n" -#: pg_ctl.c:1961 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostra questo aiuto ed esci\n" -#: pg_ctl.c:1962 +#: pg_ctl.c:1942 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "Se l'opzione -D è omessa, viene usata la variabile d'ambiente PGDATA.\n" -#: pg_ctl.c:1964 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" @@ -643,22 +639,22 @@ msgstr "" "\n" "Opzioni per l'avvio o il riavvio:\n" -#: pg_ctl.c:1966 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files permette a postgres di produrre core file\n" -#: pg_ctl.c:1968 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files non disponibile su questa piattaforma\n" -#: pg_ctl.c:1970 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log NOMEFILE scrivi (o accoda) il log del server in NOMEFILE\n" -#: pg_ctl.c:1971 +#: pg_ctl.c:1951 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -667,12 +663,12 @@ msgstr "" " -o, --options=OPZIONI opzioni da riga di comando da passare a postgres\n" " (programma eseguibile del server PostgreSQL) o initdb\n" -#: pg_ctl.c:1973 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p PATH-TO-POSTGRES normalmente non necessario\n" -#: pg_ctl.c:1974 +#: pg_ctl.c:1954 #, c-format msgid "" "\n" @@ -681,12 +677,12 @@ msgstr "" "\n" "Opzioni per l'arresto o il riavvio:\n" -#: pg_ctl.c:1975 +#: pg_ctl.c:1955 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr " -m, --mode=MODE MODE può essere \"smart\", \"fast\" o \"immediate\"\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -695,24 +691,24 @@ msgstr "" "\n" "I modi di spegnimento sono:\n" -#: pg_ctl.c:1978 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart termina dopo che tutti i client si sono disconnessi\n" -#: pg_ctl.c:1979 +#: pg_ctl.c:1959 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" msgstr " fast termina direttamente, con una corretta procedura di arresto (default)\n" -#: pg_ctl.c:1980 +#: pg_ctl.c:1960 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr "" " immediate termina senza un arresto completo: ciò porterà ad un recupero\n" " dei dati al riavvio\n" -#: pg_ctl.c:1982 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -721,7 +717,7 @@ msgstr "" "\n" "Nomi di segnali permessi per kill:\n" -#: pg_ctl.c:1986 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" @@ -730,27 +726,27 @@ msgstr "" "\n" "Opzioni per register e unregister:\n" -#: pg_ctl.c:1987 +#: pg_ctl.c:1967 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N SERVIZIO nome del servizio con cui registrare il server PostgreSQL\n" -#: pg_ctl.c:1988 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P PASSWORD password per l'account con cui registrare il server PostgreSQL\n" -#: pg_ctl.c:1989 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U UTENTE nome utente dell'account con cui registrare il server PostgreSQL\n" -#: pg_ctl.c:1990 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S TIPO-AVVIO tipo di avvio del servizio con cui registrare il server PostgreSQL\n" -#: pg_ctl.c:1992 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" @@ -759,17 +755,17 @@ msgstr "" "\n" "I tipi di avvio sono:\n" -#: pg_ctl.c:1993 +#: pg_ctl.c:1973 #, c-format msgid " auto start service automatically during system startup (default)\n" msgstr " auto avvia il servizio automaticamente durante l'avvio del sistema (predefinito)\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" msgstr " demand avvia il servizio quando richiesto\n" -#: pg_ctl.c:1997 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -778,32 +774,32 @@ msgstr "" "\n" "Puoi segnalare eventuali bug a .\n" -#: pg_ctl.c:2022 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: modalità di arresto sconosciuta \"%s\"\n" -#: pg_ctl.c:2054 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: nome del segnale sconosciuto \"%s\"\n" -#: pg_ctl.c:2071 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: tipo di avvio sconosciuto \"%s\"\n" -#: pg_ctl.c:2126 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: non è stato possibile determinare la directory dei dati usando il comando \"%s\"\n" -#: pg_ctl.c:2151 +#: pg_ctl.c:2128 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: il file di controllo sembra corrotto\n" -#: pg_ctl.c:2221 +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -814,32 +810,32 @@ msgstr "" "Effettua il login (usando per esempio \"su\") con l'utente\n" "(non privilegiato) che controllerà il processo server.\n" -#: pg_ctl.c:2305 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: l'opzione -S non è supportata su questa piattaforma\n" -#: pg_ctl.c:2342 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: troppi argomenti nella riga di comando (il primo è \"%s\")\n" -#: pg_ctl.c:2366 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: mancano gli argomenti per la modalità di kill\n" -#: pg_ctl.c:2384 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: modalità di operazione sconosciuta \"%s\"\n" -#: pg_ctl.c:2394 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: nessuna operazione specificata\n" -#: pg_ctl.c:2415 +#: pg_ctl.c:2393 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: nessuna directory del database è stata specificata e la variabile d'ambiente PGDATA non è configurata\n" diff --git a/src/bin/pg_ctl/po/ja.po b/src/bin/pg_ctl/po/ja.po index f32ab81a8c7..86334a302e9 100644 --- a/src/bin/pg_ctl/po/ja.po +++ b/src/bin/pg_ctl/po/ja.po @@ -5,156 +5,160 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.0 beta 3\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 11:37+0900\n" -"PO-Revision-Date: 2013-08-18 11:39+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-08-31 16:21+0900\n" +"PO-Revision-Date: 2018-08-20 16:31+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" -#: ../../common/fe_memutils.c:33 ../../common/fe_memutils.c:60 -#: ../../common/fe_memutils.c:83 -#, c-format -msgid "out of memory\n" -msgstr "メモリä¸è¶³ã§ã™\n" - -#: ../../common/fe_memutils.c:77 -#, c-format -msgid "cannot duplicate null pointer (internal error)\n" -msgstr "null ãƒã‚¤ãƒ³ã‚¿ã‚’複製ã§ãã¾ã›ã‚“(内部エラー)。\n" - -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" -msgstr "ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’èªè­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgstr "ç¾åœ¨ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../../port/exec.c:146 +#: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"ã¯ç„¡åйã§ã™" -#: ../../port/exec.c:195 +#: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "ãƒã‚¤ãƒŠãƒª\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ" -#: ../../port/exec.c:202 +#: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" msgstr "実行ã™ã‚‹\"%s\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../../port/exec.c:272 +#: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "シンボリックリンク\"%s\"ã®èª­ã¿å–りã«å¤±æ•—ã—ã¾ã—ãŸ" -#: ../../port/exec.c:523 +#: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "pcloseãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: ../../port/wait_error.c:47 +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 +#: ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "メモリä¸è¶³ã§ã™\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null ãƒã‚¤ãƒ³ã‚¿ã‚’複製ã§ãã¾ã›ã‚“(内部エラー)。\n" + +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "コマンドã¯å®Ÿè¡Œå½¢å¼ã§ã¯ã‚りã¾ã›ã‚“" -#: ../../port/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "コマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: ../../port/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "å­ãƒ—ロセスãŒçµ‚了コード%dã§çµ‚了ã—ã¾ã—ãŸ" -#: ../../port/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "å­ãƒ—ロセスãŒä¾‹å¤–0x%Xã§çµ‚了ã—ã¾ã—ãŸ" -#: ../../port/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%sã§çµ‚了ã—ã¾ã—ãŸ" -#: ../../port/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ«%dã§çµ‚了ã—ã¾ã—ãŸ" -#: ../../port/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "å­ãƒ—ãƒ­ã‚»ã‚¹ãŒæœªçŸ¥ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹%dã§çµ‚了ã—ã¾ã—ãŸ" -#: pg_ctl.c:253 +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "ç¾åœ¨ã®ä½œæ¥­ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_ctl.c:257 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: ディレクトリ \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: pg_ctl.c:260 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: ディレクトリ\"%s\"ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_ctl.c:273 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: ディレクトリ\"%s\"ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¯ãƒ©ã‚¹ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“\n" + +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: PIDファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: pg_ctl.c:262 +#: pg_ctl.c:295 #, c-format -#| msgid "%s: PID file \"%s\" does not exist\n" msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: PIDファイル\"%s\"ãŒç©ºã§ã™\n" -#: pg_ctl.c:265 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: PIDファイル\"%s\"内ã«ç„¡åйãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™\n" -#: pg_ctl.c:477 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: 9.1よりå‰ã®ã‚µãƒ¼ãƒã‚’èµ·å‹•ã™ã‚‹éš›ã«-wオプションã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“\n" - -#: pg_ctl.c:547 -#, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: -wオプションã§ã¯ç›¸å¯¾ã‚½ã‚±ãƒƒãƒˆãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªæŒ‡å®šã‚’使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n" +msgid "%s: could not start server: %s\n" +msgstr "%s: サーãƒã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: pg_ctl.c:595 +#: pg_ctl.c:511 #, c-format -msgid "" -"\n" -"%s: this data directory appears to be running a pre-existing postmaster\n" -msgstr "" -"\n" -"%s: ã“ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯æ—¢å­˜ã®postmasterãŒå®Ÿè¡Œã—ã¦ã„るよã†ã§ã™ã€‚\n" +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: サーãƒã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:645 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: コアファイルã®ã‚µã‚¤ã‚ºåˆ¶é™ã‚’設定ã§ãã¾ã›ã‚“:固定ã®åˆ¶é™ã«ã‚ˆã‚Šè¨±ã•れã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:670 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: ファイル\"%s\"を読ã¿å–ã‚‹ã“ã¨ã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:675 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: オプションファイル\"%s\"ã¯1行ã®ã¿ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: pg_ctl.c:723 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -165,7 +169,7 @@ msgstr "" "ã«ã‚りã¾ã›ã‚“ã§ã—ãŸã€‚\n" "インストール状æ³ã‚’確èªã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:729 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -176,42 +180,38 @@ msgstr "" "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸã€‚\n" "インストレーションを検査ã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:762 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: データベースシステムãŒåˆæœŸåŒ–ã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:777 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: ä»–ã®ã‚µãƒ¼ãƒãŒå‹•作中ã®å¯èƒ½æ€§ãŒã‚りã¾ã™ãŒã€ã¨ã«ã‹ãpostmasterã®èµ·å‹•を試ã¿ã¾ã™ã€‚\n" -#: pg_ctl.c:814 -#, c-format -msgid "%s: could not start server: exit code was %d\n" -msgstr "%s: サーãƒã‚’èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚終了コードã¯%dã§ã—ãŸã€‚\n" - -#: pg_ctl.c:821 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "サーãƒã®èµ·å‹•完了を待ã£ã¦ã„ã¾ã™..." -#: pg_ctl.c:826 pg_ctl.c:927 pg_ctl.c:1018 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr "完了\n" -#: pg_ctl.c:827 +#: pg_ctl.c:833 msgid "server started\n" msgstr "サーãƒèµ·å‹•完了\n" -#: pg_ctl.c:830 pg_ctl.c:834 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " 待機処ç†ãŒåœæ­¢ã•れã¾ã—ãŸ\n" -#: pg_ctl.c:831 -msgid "server is still starting up\n" -msgstr "サーãƒã¯ä¾ç„¶èµ·å‹•中ã§ã™ã€‚\n" +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: サーãƒã¯æ™‚間内ã«åœæ­¢ã—ã¾ã›ã‚“ã§ã—ãŸ\n" -#: pg_ctl.c:835 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -220,43 +220,34 @@ msgstr "" "%s: サーãƒã‚’èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" "ログ出力を確èªã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:841 pg_ctl.c:919 pg_ctl.c:1009 -msgid " failed\n" -msgstr "失敗ã—ã¾ã—ãŸ\n" - -#: pg_ctl.c:842 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: 誤設定ã®ãŸã‚サーãƒã‚’待機ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n" - -#: pg_ctl.c:848 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "サーãƒã¯èµ·å‹•中ã§ã™ã€‚\n" -#: pg_ctl.c:863 pg_ctl.c:949 pg_ctl.c:1039 pg_ctl.c:1079 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: PIDファイル\"%s\"ãŒã‚りã¾ã›ã‚“\n" -#: pg_ctl.c:864 pg_ctl.c:951 pg_ctl.c:1040 pg_ctl.c:1080 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "サーãƒãŒå‹•作ã—ã¦ã„ã¾ã™ã‹?\n" -#: pg_ctl.c:870 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: サーãƒã‚’åœæ­¢ã§ãã¾ã›ã‚“。シングルユーザサーãƒ(PID: %ld)ãŒå‹•作ã—ã¦ã„ã¾ã™ã€‚\n" -#: pg_ctl.c:878 pg_ctl.c:973 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: åœæ­¢ã‚·ã‚°ãƒŠãƒ«ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚(PID: %ld): %s\n" -#: pg_ctl.c:885 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "サーãƒã®åœæ­¢ä¸­ã§ã™\n" -#: pg_ctl.c:900 pg_ctl.c:988 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -266,16 +257,20 @@ msgstr "" "pg_stop_backup()ãŒå‘¼ã³å‡ºã•れるã¾ã§ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã¯å®Œäº†ã—ã¾ã›ã‚“\n" "\n" -#: pg_ctl.c:904 pg_ctl.c:992 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "サーãƒåœæ­¢å‡¦ç†ã®å®Œäº†ã‚’å¾…ã£ã¦ã„ã¾ã™..." -#: pg_ctl.c:921 pg_ctl.c:1011 +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr "失敗ã—ã¾ã—ãŸ\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: サーãƒã¯åœæ­¢ã—ã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:923 pg_ctl.c:1013 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -283,366 +278,398 @@ msgstr "" "ヒント: \"-m fast\"オプションã¯ã€ã‚»ãƒƒã‚·ãƒ§ãƒ³åˆ‡æ–­ãŒå§‹ã¾ã‚‹ã¾ã§å¾…機ã™ã‚‹ã®ã§ã¯ãªã\n" "å³åº§ã«ã‚»ãƒƒã‚·ãƒ§ãƒ³ã‚’切断ã—ã¾ã™ã€‚\n" -#: pg_ctl.c:929 pg_ctl.c:1019 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "サーãƒã¯åœæ­¢ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:952 pg_ctl.c:1025 -msgid "starting server anyway\n" -msgstr "ã¨ã«ã‹ãサーãƒã‚’èµ·å‹•ã—ã¦ã„ã¾ã™\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "ã¨ã«ã‹ãサーãƒã®èµ·å‹•を試ã¿ã¾ã™\n" -#: pg_ctl.c:961 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "%s: サーãƒã‚’å†èµ·å‹•ã§ãã¾ã›ã‚“。シングルユーザサーãƒ(PID: %ld)ãŒå‹•作中ã§ã™ã€‚\n" -#: pg_ctl.c:964 pg_ctl.c:1049 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" msgstr "シングルユーザサーãƒã‚’終了ã•ã›ã¦ã‹ã‚‰ã€å†åº¦å®Ÿè¡Œã—ã¦ãã ã•ã„\n" -#: pg_ctl.c:1023 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: å¤ã„サーãƒãƒ—ロセス(PID: %ld)ãŒå‹•作ã—ã¦ã„ãªã„よã†ã§ã™\n" -#: pg_ctl.c:1046 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "ã¨ã«ã‹ãサーãƒã‚’èµ·å‹•ã—ã¦ã„ã¾ã™\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "%s: サーãƒã‚’リロードã§ãã¾ã›ã‚“。シングルユーザサーãƒ(PID: %ld)ãŒå‹•作中ã§ã™\n" -#: pg_ctl.c:1055 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: リロードシグナルをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚(PID: %ld): %s\n" -#: pg_ctl.c:1060 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "サーãƒã«ã‚·ã‚°ãƒŠãƒ«ã‚’é€ä¿¡ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:1086 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" -msgstr "%s: サーãƒã‚’昇進ã§ãã¾ã›ã‚“。シングルユーザサーãƒ(PID: %ld)ãŒå‹•作中ã§ã™\n" +msgstr "%s: サーãƒã‚’昇格ã§ãã¾ã›ã‚“; シングルユーザサーãƒ(PID: %ld)ãŒå‹•作中ã§ã™\n" -#: pg_ctl.c:1095 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" -msgstr "%s: サーãƒã‚’昇進ã§ãã¾ã›ã‚“。サーãƒã¯ã‚¹ã‚¿ãƒ³ãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“。\n" +msgstr "%s: サーãƒã‚’昇格ã§ãã¾ã›ã‚“; サーãƒã¯ã‚¹ã‚¿ãƒ³ãƒã‚¤ãƒ¢ãƒ¼ãƒ‰ã§ã¯ã‚りã¾ã›ã‚“\n" -#: pg_ctl.c:1111 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" -msgstr "%s: \"%s\"昇進通知ファイルを作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"を作æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: pg_ctl.c:1117 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" -msgstr "%s: \"%s\"昇進通知ファイルを書ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"ã«æ›¸ã出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" -msgstr "%s: 昇進シグナルをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚(PID: %ld): %s\n" +msgstr "%s: 昇格シグナルをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—㟠(PID: %ld): %s\n" -#: pg_ctl.c:1128 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" -msgstr "%s: \"%s\"昇進通知ファイルを削除ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "%s: 昇格指示ファイル\"%s\"ã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: pg_ctl.c:1133 +#: pg_ctl.c:1146 +msgid "waiting for server to promote..." +msgstr "サーãƒã®æ˜‡æ ¼ã‚’å¾…ã£ã¦ã„ã¾ã™..." + +#: pg_ctl.c:1160 +msgid "server promoted\n" +msgstr "サーãƒã¯æ˜‡æ ¼ã—ã¾ã—ãŸ\n" + +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: サーãƒã¯æ™‚é–“å†…ã«æ˜‡æ ¼ã—ã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_ctl.c:1171 msgid "server promoting\n" -msgstr "サーãƒã‚’昇進中ã§ã™ã€‚\n" +msgstr "サーãƒã‚’昇格中ã§ã™\n" -#: pg_ctl.c:1180 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: シングルユーザサーãƒãŒå‹•作中ã§ã™(PID: %ld)\n" -#: pg_ctl.c:1192 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: サーãƒãŒå‹•作中ã§ã™(PID: %ld)\n" -#: pg_ctl.c:1203 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: サーãƒãŒå‹•作ã—ã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:1220 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: シグナル%dã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ(PID: %ld): %s\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: 本プログラムã®å®Ÿè¡Œãƒ•ã‚¡ã‚¤ãƒ«ã®æ¤œç´¢ã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:1264 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: postgres ã®å®Ÿè¡Œãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n" -#: pg_ctl.c:1329 pg_ctl.c:1361 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: サービスマãƒãƒ¼ã‚¸ãƒ£ã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: pg_ctl.c:1335 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: サービス\\\"%s\\\"ã¯ç™»éŒ²æ¸ˆã¿ã§ã™\n" -#: pg_ctl.c:1346 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: サービス\"%s\"ã®ç™»éŒ²ã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1367 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: サービス\"%s\"ã¯ç™»éŒ²ã•れã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:1374 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: サービス\"%s\"ã®ã‚ªãƒ¼ãƒ—ンã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1381 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: サービス\"%s\"ã®ç™»éŒ²å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1466 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" msgstr "サーãƒã®èµ·å‹•完了を待ã£ã¦ã„ã¾ã™...\n" -#: pg_ctl.c:1469 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "サーãƒã®èµ·å‹•待機ãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ\n" -#: pg_ctl.c:1473 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "サーãƒã¯èµ·å‹•ã—ã€æŽ¥ç¶šã‚’å—ã‘付ã‘ã¦ã„ã¾ã™\n" -#: pg_ctl.c:1517 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: サービス\"%s\"ã®èµ·å‹•ã«å¤±æ•—ã—ã¾ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1589 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: 警告: ã“ã®ãƒ—ラットフォームã§ã¯åˆ¶é™ä»˜ãトークンを作æˆã§ãã¾ã›ã‚“\n" -#: pg_ctl.c:1598 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: プロセストークンをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1611 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: SIDを割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1630 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: 制é™ä»˜ãトークンを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" -#: pg_ctl.c:1668 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: 警告: システムAPI内ã«ã™ã¹ã¦ã®ã‚¸ãƒ§ãƒ–オブジェクト関数を格ç´ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: pg_ctl.c:1754 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: 権é™ã® LUID ã‚’å–å¾—ã§ãã¾ã›ã‚“: エラーコード %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: トークン情報をå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸ: エラーコード %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: メモリä¸è¶³ã§ã™\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "詳細ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:1762 +#: pg_ctl.c:1913 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" "\n" msgstr "%sã¯PostgreSQLサーãƒã®åˆæœŸåŒ–ã€èµ·å‹•ã€åœæ­¢ã€åˆ¶å¾¡ã‚’行ã†ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ã§ã™ã€‚\n" -#: pg_ctl.c:1763 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_ctl.c:1764 +#: pg_ctl.c:1915 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n" -msgstr " %s init[db] [-D DATADIR] [-s] [-o \"オプション\"]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1916 #, c-format -msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" -msgstr " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" -#: pg_ctl.c:1766 +#: pg_ctl.c:1918 #, c-format -msgid " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -msgstr " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1767 +#: pg_ctl.c:1919 #, c-format msgid "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" -#: pg_ctl.c:1769 +#: pg_ctl.c:1921 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D DATADIR] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATADIR] [-s]\n" -#: pg_ctl.c:1770 +#: pg_ctl.c:1922 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D DATADIR]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATADIR]\n" -#: pg_ctl.c:1771 +#: pg_ctl.c:1923 #, c-format -msgid " %s promote [-D DATADIR] [-s]\n" -msgstr " %s promote [-D DATADIR] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" -#: pg_ctl.c:1772 +#: pg_ctl.c:1924 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill SIGNALNAME PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNALNAME PID\n" -#: pg_ctl.c:1774 +#: pg_ctl.c:1926 #, c-format msgid "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" -#: pg_ctl.c:1776 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N SERVICENAME]\n" -#: pg_ctl.c:1779 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" "Common options:\n" msgstr "" "\n" -"一般的ãªã‚ªãƒ—ション:\n" +"共通ã®ã‚ªãƒ—ション:\n" -#: pg_ctl.c:1780 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" -msgstr " -D, --pgdata DATADIR データベース格ç´é ˜åŸŸã®å ´æ‰€ã§ã™\n" +msgstr " -D, --pgdata=DATADIR データベース格ç´é ˜åŸŸã®å ´æ‰€\n" + +#: pg_ctl.c:1934 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE サービスã¨ã—ã¦èµ·å‹•ã•ã›ãŸã¨ãã®ãƒ­ã‚°ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚½ãƒ¼ã‚¹\n" -#: pg_ctl.c:1781 +#: pg_ctl.c:1936 #, c-format msgid " -s, --silent only print errors, no informational messages\n" -msgstr " -s, --silent エラーメッセージã®ã¿ã‚’表示ã—ã€æƒ…報メッセージã¯è¡¨ç¤ºã—ã¾ã›ã‚“\n" +msgstr "" +" -s, --silent エラーメッセージã®ã¿ã‚’表示ã—ã€æƒ…報メッセージã¯è¡¨ç¤ºã—ã¾\n" +" ã›ã‚“\n" -#: pg_ctl.c:1782 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SECS -wオプションを使用ã™ã‚‹æ™‚ã«å¾…機ã™ã‚‹ç§’æ•°\n" -#: pg_ctl.c:1783 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" -#: pg_ctl.c:1784 +#: pg_ctl.c:1939 #, c-format -msgid " -w wait until operation completes\n" -msgstr " -w 作業ãŒå®Œäº†ã™ã‚‹ã¾ã§å¾…機ã—ã¾ã™\n" +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait æ“作ãŒå®Œäº†ã™ã‚‹ã¾ã§å¾…機ã—ã¾ã™ (デフォルト)\n" -#: pg_ctl.c:1785 +#: pg_ctl.c:1940 #, c-format -msgid " -W do not wait until operation completes\n" -msgstr " -W 作業ã®å®Œäº†ã¾ã§å¾…機ã—ã¾ã›ã‚“\n" +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait 作業ã®å®Œäº†ã‚’å¾…ã¡ã¾ã›ã‚“\n" -#: pg_ctl.c:1786 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" - -#: pg_ctl.c:1787 -#, c-format -msgid "" -"(The default is to wait for shutdown, but not for start or restart.)\n" -"\n" -msgstr "" -"(デフォルトã§ã¯ã€ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³æ™‚ã¯å¾…機ã—ã€èµ·å‹•ã¨å†èµ·å‹•ã®æ™‚ã¯å¾…機ã—\n" -"ã¾ã›ã‚“。)\n" -"\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" -#: pg_ctl.c:1788 +#: pg_ctl.c:1942 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" -msgstr "-Dオプションã®çœç•¥æ™‚ã€PGDATA環境変数ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n" +msgstr "-Dオプションã®çœç•¥æ™‚ã¯PGDATA環境変数ãŒä½¿ç”¨ã•れã¾ã™ã€‚\n" -#: pg_ctl.c:1790 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" "Options for start or restart:\n" msgstr "" "\n" -"èµ·å‹•ã€å†èµ·å‹•用ã®ã‚ªãƒ—ション\n" +"èµ·å‹•ã€å†èµ·å‹•ã®ã‚ªãƒ—ション\n" -#: pg_ctl.c:1792 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" -msgstr " -c, --core-files postgresã¯ã‚³ã‚¢ãƒ•ァイルを生æˆã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" +msgstr " -c, --core-files postgresã®ã‚³ã‚¢ãƒ•ァイル生æˆã‚’許å¯ã—ã¾ã™\n" -#: pg_ctl.c:1794 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" -msgstr " -c, --core-files ã“ã®ãƒ—ラットフォームã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“\n" +msgstr " -c, --core-files ã“ã®ãƒ—ラットフォームã§ã¯æŒ‡å®šã§ãã¾ã›ã‚“\n" -#: pg_ctl.c:1796 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log FILENAME サーãƒãƒ­ã‚°ã‚’FILENAMEã¸å‡ºåŠ›(ã‚ã‚‹ã„ã¯è¿½åŠ )ã—ã¾ã™\n" -#: pg_ctl.c:1797 +#: pg_ctl.c:1951 #, c-format msgid "" -" -o OPTIONS command line options to pass to postgres\n" +" -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n" msgstr "" -" -o オプション postgres(PostgreSQLサーãƒå®Ÿè¡Œãƒ•ァイル)ã¾ãŸã¯\n" +" -o, --options=OPTIONS postgres(PostgreSQLサーãƒå®Ÿè¡Œãƒ•ァイル)ã¾ãŸã¯\n" " initdb ã«æ¸¡ã™ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚ªãƒ—ション\n" -#: pg_ctl.c:1799 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p PATH-TO-POSTGRES 通常ã¯ä¸è¦ã§ã™\n" -#: pg_ctl.c:1800 +#: pg_ctl.c:1954 #, c-format -#| msgid "" -#| "\n" -#| "Options for stop or restart:\n" msgid "" "\n" -"Options for stop, restart, or promote:\n" -msgstr "\nåœæ­¢ã€å†èµ·å‹•ã€æ˜‡é€²ç”¨ã®ã‚ªãƒ—ション:\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"åœæ­¢ã€å†èµ·å‹•ã®ã‚ªãƒ—ション\n" -#: pg_ctl.c:1801 +#: pg_ctl.c:1955 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" -msgstr " -m, --mode=MODE MODEã¯\"smart\"ã€\"fast\"ã€\"immediate\"ã®ã„ãšã‚Œã‹ã§ã™\n" +msgstr " -m, --mode=MODE MODEã¯\"smart\"ã€\"fast\"ã€\"immediate\"ã®ã„ãšã‚Œã‹ã§ã™\n" -#: pg_ctl.c:1803 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -651,22 +678,22 @@ msgstr "" "\n" "シャットダウンモードã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:\n" -#: pg_ctl.c:1804 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart å…¨ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã®æŽ¥ç¶šåˆ‡æ–­å¾Œã«åœæ­¢ã—ã¾ã™\n" -#: pg_ctl.c:1805 +#: pg_ctl.c:1959 #, c-format -msgid " fast quit directly, with proper shutdown\n" -msgstr " fast シャットダウン手続ã後ã«åœæ­¢ã—ã¾ã™\n" +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast æ­£ã—ã„æ‰‹é †ã§ç›´ã¡ã«åœæ­¢ã—ã¾ã™(デフォルト)\n" -#: pg_ctl.c:1806 +#: pg_ctl.c:1960 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" -msgstr " immediate シャットダウン手続ãを行ã‚ãšã«åœæ­¢ã—ã¾ã™ã€‚å†èµ·å‹•時ã«ãƒªã‚«ãƒãƒªçŠ¶æ…‹ã«ãªã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™\n" +msgstr " immediate æ­£ã—ã„æ‰‹é †ã‚’スキップã—ã¦åœæ­¢ã—ã¾ã™ã€‚å†èµ·å‹•時ã«ã¯ãƒªã‚«ãƒãƒªã‚’行ã„ã¾ã™\n" -#: pg_ctl.c:1808 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -675,55 +702,55 @@ msgstr "" "\n" "killモードã§åˆ©ç”¨ã§ãるシグナルå:\n" -#: pg_ctl.c:1812 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" "Options for register and unregister:\n" msgstr "" "\n" -"登録ã€ç™»éŒ²è§£é™¤ç”¨ã®ã‚ªãƒ—ション:\n" +"登録ã€ç™»éŒ²è§£é™¤ã®ã‚ªãƒ—ション:\n" -#: pg_ctl.c:1813 +#: pg_ctl.c:1967 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" -msgstr " -N SERVICENAME PostgreSQLサーãƒã‚’登録ã™ã‚‹ãŸã‚ã®ã‚µãƒ¼ãƒ“スåã§ã™\n" +msgstr " -N SERVICENAME PostgreSQLサーãƒã‚’登録ã™ã‚‹éš›ã®ã®ã‚µãƒ¼ãƒ“スåã§ã™\n" -#: pg_ctl.c:1814 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" -msgstr " -P PASSWORD PostgreSQLサーãƒã‚’登録ã™ã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ‘スワードã§ã™\n" +msgstr " -P PASSWORD PostgreSQLサーãƒã‚’登録ã™ã‚‹ãŸã‚ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ‘スワードã§ã™\n" -#: pg_ctl.c:1815 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" -msgstr " -U USERNAME PostgreSQLサーãƒã‚’登録ã™ã‚‹ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã®ãƒ¦ãƒ¼ã‚¶åã§ã™\n" +msgstr " -U USERNAME PostgreSQLサーãƒã‚’登録ã™ã‚‹ãŸã‚ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆåã§ã™\n" -#: pg_ctl.c:1816 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" -msgstr " -S START-TYPE PostgreSQLサーãƒã‚’登録ã™ã‚‹ãŸã‚ã®ã‚µãƒ¼ãƒ“ス起動種類ã§ã™\n" +msgstr " -S START-TYPE PostgreSQLサーãƒã‚’登録ã™ã‚‹éš›ã®ã‚µãƒ¼ãƒ“ス起動タイプã§ã™\n" -#: pg_ctl.c:1818 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" "Start types are:\n" msgstr "" "\n" -"起動種類ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:\n" +"起動タイプã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:\n" -#: pg_ctl.c:1819 +#: pg_ctl.c:1973 #, c-format msgid " auto start service automatically during system startup (default)\n" -msgstr " auto システムã®èµ·å‹•時ã«ã‚µãƒ¼ãƒ“スを自動的ã«é–‹å§‹ã—ã¾ã™ï¼ˆãƒ‡ãƒ•ォルト)\n" +msgstr " auto システムã®èµ·å‹•時ã«ã‚µãƒ¼ãƒ“スを自動的ã«é–‹å§‹ã—ã¾ã™(デフォルト)\n" -#: pg_ctl.c:1820 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" -msgstr " demand å¿…è¦ã«å¿œã˜ã¦ã‚µãƒ¼ãƒ“スを開始ã—ã¾ã™\n" +msgstr " demand è¦æ±‚ã«å¿œã˜ã¦ã‚µãƒ¼ãƒ“スを開始ã—ã¾ã™\n" -#: pg_ctl.c:1823 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -732,27 +759,32 @@ msgstr "" "\n" "ä¸å…·åˆã¯ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" -msgstr "%s: シャットダウンモード\"%s\"ã¯ä¸æ˜Žã§ã™\n" +msgstr "%s: 䏿­£ãªã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ãƒ¢ãƒ¼ãƒ‰\"%s\"\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" -msgstr "%s: シグナルå\"%s\"ã¯ä¸æ˜Žã§ã™\n" +msgstr "%s: 䏿­£ãªã‚·ã‚°ãƒŠãƒ«å\"%s\"\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" -msgstr "%s: 起動種類\"%s\"ã¯ä¸æ˜Žã§ã™\n" +msgstr "%s: 䏿­£ãªèµ·å‹•タイプ\"%s\"\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: コマンド\"%s\"を使用ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’決定ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: pg_ctl.c:2022 +#: pg_ctl.c:2128 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: 制御ファイルãŒå£Šã‚Œã¦ã„るよã†ã§ã™\n" + +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -760,65 +792,35 @@ msgid "" "own the server process.\n" msgstr "" "%s: rootã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“\n" -"サーãƒãƒ—ãƒ­ã‚»ã‚¹ã®æ‰€æœ‰è€…ã¨ãªã‚‹(éžç‰¹æ¨©)ユーザã¨ã—ã¦(例ãˆã°\"su\"を使用ã—ã¦)\n" +"サーãƒãƒ—ãƒ­ã‚»ã‚¹ã®æ‰€æœ‰è€…ã¨ãªã‚‹(éžç‰¹æ¨©)ユーザã¨ã—ã¦(\"su\"ãªã©ã‚’使用ã—ã¦)\n" "ログインã—ã¦ãã ã•ã„。\n" -#: pg_ctl.c:2093 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: -Sオプションã¯ã“ã®ãƒ—ラットフォームã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:2135 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™(先頭ã¯\"%s\")\n" -#: pg_ctl.c:2159 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: killモード用ã®å¼•æ•°ãŒã‚りã¾ã›ã‚“\n" -#: pg_ctl.c:2177 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: æ“作モード\"%s\"ã¯ä¸æ˜Žã§ã™\n" -#: pg_ctl.c:2187 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: æ“ä½œãƒ¢ãƒ¼ãƒ‰ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" -#: pg_ctl.c:2208 +#: pg_ctl.c:2393 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æŒ‡å®šã‚‚ã€PGDATA環境変数ã®è¨­å®šã‚‚ã‚りã¾ã›ã‚“\n" - -#~ msgid "%s: could not create restricted token: %lu\n" -#~ msgstr "%s: 制é™ä»˜ãトークンを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %lu\n" - -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "ディレクトリを\"%s\"ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help ヘルプを表示ã—ã€çµ‚了ã—ã¾ã™\n" - -#~ msgid "%s: could not open process token: %lu\n" -#~ msgstr "%s: プロセストークンをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %lu\n" - -#~ msgid "" -#~ "%s is a utility to start, stop, restart, reload configuration files,\n" -#~ "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n" -#~ "\n" -#~ msgstr "" -#~ "%sã¯PostgreSQLサーãƒã®èµ·å‹•ã€åœæ­¢ã€å†èµ·å‹•ã€è¨­å®šãƒ•ァイルã®ãƒªãƒ­ãƒ¼ãƒ‰ã€çжæ³å ±å‘Š\n" -#~ "を行ã†ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ã§ã™ã€‚ã¾ãŸã€PostgreSQLプロセスã¸ã‚·ã‚°ãƒŠãƒ«ã‚‚é€ä¿¡ã—ã¾ã™ã€‚\n" -#~ "\n" - -#~ msgid "%s: out of memory\n" -#~ msgstr "%s: メモリä¸è¶³ã§ã™\n" - -#~ msgid "%s: could not allocate SIDs: %lu\n" -#~ msgstr "%s: SIDを割り当ã¦ã‚‰ã‚Œã¾ã›ã‚“ã§ã—ãŸ: %lu\n" - -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" diff --git a/src/bin/pg_ctl/po/ko.po b/src/bin/pg_ctl/po/ko.po index 8b545b3952f..cf6d19a4ac7 100644 --- a/src/bin/pg_ctl/po/ko.po +++ b/src/bin/pg_ctl/po/ko.po @@ -3,15 +3,15 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: pg_ctl (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 17:02+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 15:18+0900\n" "Last-Translator: Ioseph Kim \n" -"Language-Team: Korean \n" +"Language-Team: Korean Team \n" "Language: ko\n" "MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" +"Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" @@ -62,37 +62,37 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 복제할 수 ì—†ìŒ(ë‚´ë¶€ 오류)\n" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "명령어를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 종료 코드 %d" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "0x%X 예외처리로 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "%s ì‹œê·¸ë„ ê°ì§€ë¡œ 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, ì‹œê·¸ë„ %d" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 알수 없는 ìƒíƒœ %d" @@ -102,82 +102,62 @@ msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 알수 없는 ìƒíƒœ %d" msgid "could not get current working directory: %s\n" msgstr "현재 작업 디렉터리를 알 수 ì—†ìŒ: %s\n" -#: pg_ctl.c:252 +#: pg_ctl.c:257 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: \"%s\" 디렉터리 ì—†ìŒ\n" -#: pg_ctl.c:255 +#: pg_ctl.c:260 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: \"%s\" ë””ë ‰í„°ë¦¬ì— ì•¡ì„¸ìŠ¤í•  수 ì—†ìŒ: %s\n" -#: pg_ctl.c:269 +#: pg_ctl.c:273 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: 지정한 \"%s\" 디렉터리는 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤íŠ¸ 디렉터리가 아님\n" -#: pg_ctl.c:282 +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: \"%s\" PID 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_ctl.c:291 +#: pg_ctl.c:295 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: \"%s\" PID 파ì¼ì— ë‚´ìš©ì´ ì—†ìŠµë‹ˆë‹¤\n" -#: pg_ctl.c:294 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: \"%s\" PID 파ì¼ì´ 비었ìŒ\n" -#: pg_ctl.c:444 pg_ctl.c:472 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: 서버를 시작 í•  수 ì—†ìŒ: %s\n" -#: pg_ctl.c:496 +#: pg_ctl.c:511 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: 서버를 시작할 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:573 -#, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: -w ì˜µì…˜ì€ 9.1 ì´ì „ ë²„ì „ì˜ ì„œë²„ë¥¼ 실행할 때는 ì§€ì›í•˜ì§€ 않ìŒ\n" - -#: pg_ctl.c:638 -#, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: -w ì˜µì…˜ì€ ì†Œì¼“ 디렉터리로 ìƒëŒ€ 경로를 사용할 수 ì—†ìŒ\n" - -#: pg_ctl.c:740 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" -msgstr "" -"%s: 코어 íŒŒì¼ í¬ê¸° 한ë„를 설정할 수 ì—†ìŒ, 하드 ë””ìŠ¤í¬ ìš©ëŸ‰ 초과로 허용ë˜ì§€ 않" -"ìŒ\n" +msgstr "%s: 코어 íŒŒì¼ í¬ê¸° 한ë„를 설정할 수 ì—†ìŒ, 하드 ë””ìŠ¤í¬ ìš©ëŸ‰ 초과로 허용ë˜ì§€ 않ìŒ\n" -#: pg_ctl.c:765 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ\n" -#: pg_ctl.c:770 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: \"%s\" 환경설정파ì¼ì€ 반드시 한 ì¤„ì„ ê°€ì ¸ì•¼í•œë‹¤?\n" -#: pg_ctl.c:821 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -188,7 +168,7 @@ msgstr "" "\"%s\" 디렉터리 ì•ˆì— ì—†ìŠµë‹ˆë‹¤.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: pg_ctl.c:827 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -199,37 +179,38 @@ msgstr "" "%s 버전과 같지 않습니다.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: pg_ctl.c:860 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: ë°ì´í„°ë² ì´ìФ 초기화 실패\n" -#: pg_ctl.c:875 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: 다른 서버가 ê°€ë™ ì¤‘ì¸ ê²ƒ ê°™ìŒ; 어째든 서버 ê°€ë™ì„ 시ë„함\n" -#: pg_ctl.c:913 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "서버를 시작하기 위해 기다리는 중..." -#: pg_ctl.c:918 pg_ctl.c:1025 pg_ctl.c:1116 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr " 완료\n" -#: pg_ctl.c:919 +#: pg_ctl.c:833 msgid "server started\n" msgstr "서버 시작ë¨\n" -#: pg_ctl.c:922 pg_ctl.c:926 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " 중지 기다리는 중\n" -#: pg_ctl.c:923 -msgid "server is still starting up\n" -msgstr "서버가 여전히 시작 중입니다\n" +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: 서버가 ì œ ì‹œê°„ì— ì‹œìž‘ë˜ì§€ 못했ìŒ\n" -#: pg_ctl.c:927 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -238,43 +219,34 @@ msgstr "" "%s: 서버를 시작 í•  수 ì—†ìŒ\n" "로그 ì¶œë ¥ì„ ì‚´íŽ´ë³´ì‹­ì‹œì˜¤.\n" -#: pg_ctl.c:933 pg_ctl.c:1017 pg_ctl.c:1107 -msgid " failed\n" -msgstr " 실패\n" - -#: pg_ctl.c:934 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: ìž˜ëª»ëœ í™˜ê²½ 설정 ë•Œë¬¸ì— ëŒ€ê¸°ë¥¼ ë” ì´ìƒ í•  수 ì—†ìŒ\n" - -#: pg_ctl.c:940 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "서버를 시작합니다\n" -#: pg_ctl.c:961 pg_ctl.c:1047 pg_ctl.c:1137 pg_ctl.c:1177 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: \"%s\" PID 파ì¼ì´ 없습니다\n" -#: pg_ctl.c:962 pg_ctl.c:1049 pg_ctl.c:1138 pg_ctl.c:1178 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "서버가 실행 중입니까?\n" -#: pg_ctl.c:968 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: 서버 중지 실패; ë‹¨ì¼ ì‚¬ìš©ìž ì„œë²„ê°€ 실행 중 (PID: %ld)\n" -#: pg_ctl.c:976 pg_ctl.c:1071 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: stop 시그ë„ì„ ë³´ë‚¼ 수 ì—†ìŒ (PID: %ld): %s\n" -#: pg_ctl.c:983 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "서버를 멈춥니다\n" -#: pg_ctl.c:998 pg_ctl.c:1086 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -284,16 +256,20 @@ msgstr "" "pg_stop_backup()ì´ í˜¸ì¶œë  ë•Œê¹Œì§€ 종료가 완료ë˜ì§€ 않습니다.\n" "\n" -#: pg_ctl.c:1002 pg_ctl.c:1090 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "서버를 멈추기 위해 기다리는 중..." -#: pg_ctl.c:1019 pg_ctl.c:1109 +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr " 실패\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: 서버를 멈추지 못했ìŒ\n" -#: pg_ctl.c:1021 pg_ctl.c:1111 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -301,187 +277,216 @@ msgstr "" "힌트: \"-m fast\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ë©´ ì ‘ì†í•œ ì„¸ì…˜ë“¤ì„ ì¦‰ì‹œ 정리합니다.\n" "ì´ ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ 않으면 ì ‘ì†í•œ 세션들 스스로 ëŠì„ 때까지 기다립니다.\n" -#: pg_ctl.c:1027 pg_ctl.c:1117 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "서버 멈추었ìŒ\n" -#: pg_ctl.c:1050 pg_ctl.c:1123 -msgid "starting server anyway\n" -msgstr "어째든 서버를 시작합니다\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "어째든 서버를 시작해 봅니다\n" -#: pg_ctl.c:1059 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" -msgstr "" -"%s: 서버를 다시 시작 í•  수 ì—†ìŒ; 단ì¼ì‚¬ìš©ìž 서버가 실행 중임 (PID: %ld)\n" +msgstr "%s: 서버를 다시 시작 í•  수 ì—†ìŒ; 단ì¼ì‚¬ìš©ìž 서버가 실행 중임 (PID: %ld)\n" -#: pg_ctl.c:1062 pg_ctl.c:1147 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" msgstr "ë‹¨ì¼ ì‚¬ìš©ìž ì„œë²„ë¥¼ 멈추고 다시 시ë„하십시오.\n" -#: pg_ctl.c:1121 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: ì´ì „ 서버 프로세스(PID: %ld)ê°€ 없어졌습니다\n" -#: pg_ctl.c:1144 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "어째든 서버를 시작합니다\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" -msgstr "" -"%s: 서버 í™˜ê²½ì„¤ì •ì„ ë‹¤ì‹œ 불러올 수 ì—†ìŒ; ë‹¨ì¼ ì‚¬ìš©ìž ì„œë²„ê°€ 실행 중임 (PID: " -"%ld)\n" +msgstr "%s: 서버 í™˜ê²½ì„¤ì •ì„ ë‹¤ì‹œ 불러올 수 ì—†ìŒ; ë‹¨ì¼ ì‚¬ìš©ìž ì„œë²„ê°€ 실행 중임 (PID: %ld)\n" -#: pg_ctl.c:1153 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: reload 시그ë„ì„ ë³´ë‚¼ 수 ì—†ìŒ (PID: %ld): %s\n" -#: pg_ctl.c:1158 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "서버가 시스템 시그ë„ì„ ë°›ì•˜ìŒ\n" -#: pg_ctl.c:1184 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "%s: ìš´ì˜ì„œë²„ 전환 실패; 단ì¼ì‚¬ìš©ìž 서버가 실행 중(PID: %ld)\n" -#: pg_ctl.c:1193 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: ìš´ì˜ì„œë²„ 전환 실패; 서버가 대기 모드로 ìƒíƒœê°€ 아님\n" -#: pg_ctl.c:1208 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: ìš´ì˜ì „환 ì‹œê·¸ë„ íŒŒì¼ì¸ \"%s\" 파ì¼ì„ 만들 수 ì—†ìŒ: %s\n" -#: pg_ctl.c:1214 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: ìš´ì˜ì „환 ì‹œê·¸ë„ íŒŒì¼ì¸ \"%s\" 파ì¼ì— 쓰기 실패: %s\n" -#: pg_ctl.c:1222 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: ìš´ì˜ì „환 시그ë„ì„ ì„œë²„(PID: %ld)로 보낼 수 ì—†ìŒ: %s\n" -#: pg_ctl.c:1225 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: ìš´ì˜ì „환 ì‹œê·¸ë„ íŒŒì¼ì¸ \"%s\" 파ì¼ì„ 지울 수 ì—†ìŒ: %s\n" -#: pg_ctl.c:1230 +#: pg_ctl.c:1146 +msgid "waiting for server to promote..." +msgstr "서버를 ìš´ì˜ ëª¨ë“œë¡œ 전환하는 중 ..." + +#: pg_ctl.c:1160 +msgid "server promoted\n" +msgstr "ìš´ì˜ ëª¨ë“œ 전환 완료\n" + +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: 서버를 ì œ ì‹œê°„ì— ìš´ì˜ ëª¨ë“œë¡œ 전환하지 못했ìŒ\n" + +#: pg_ctl.c:1171 msgid "server promoting\n" msgstr "서버를 ìš´ì˜ ëª¨ë“œë¡œ 전환합니다\n" -#: pg_ctl.c:1277 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: 단ì¼ì‚¬ìš©ìž 서버가 실행 중임 (PID: %ld)\n" -#: pg_ctl.c:1290 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: 서버가 실행 중임 (PID: %ld)\n" -#: pg_ctl.c:1306 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: ê°€ë™ ì¤‘ì¸ ì„œë²„ê°€ ì—†ìŒ\n" -#: pg_ctl.c:1324 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: %d 시그ë„ì„ ë³´ë‚¼ 수 ì—†ìŒ (PID: %ld): %s\n" -#: pg_ctl.c:1381 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: 실행 가능한 í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ 없습니다\n" -#: pg_ctl.c:1391 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: 실행 가능한 postgres í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_ctl.c:1461 pg_ctl.c:1495 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: 서비스 관리ìžë¥¼ ì—´ 수 ì—†ìŒ\n" -#: pg_ctl.c:1467 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: \"%s\" 서비스가 ì´ë¯¸ ë“±ë¡ ë˜ì–´ 있ìŒ\n" -#: pg_ctl.c:1478 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: \"%s\" 서비스를 등ë¡í•  수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1501 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: \"%s\" 서비스가 등ë¡ë˜ì–´ 있지 않ìŒ\n" -#: pg_ctl.c:1508 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: \"%s\" 서비스를 ì—´ 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1517 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: \"%s\" 서비스를 서비스 목ë¡ì—서 뺄 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1604 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" msgstr "서버를 시작하기 위해 기다리는 중...\n" -#: pg_ctl.c:1607 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "서버 ì‹œìž‘ì„ ê¸°ë‹¤ë¦¬ëŠ” ë™ì•ˆ 시간 초과ë¨\n" -#: pg_ctl.c:1611 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "서버가 시작ë˜ì—ˆìœ¼ë©° ì—°ê²°ì„ í—ˆìš©í•¨\n" -#: pg_ctl.c:1666 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: \"%s\" 서비스를 시작할 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1740 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: 경고: ì´ ìš´ì˜ì²´ì œì—서 restricted tokenì„ ë§Œë“¤ 수 ì—†ìŒ\n" -#: pg_ctl.c:1753 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: 프로세스 토í°ì„ ì—´ 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1767 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: SID를 할당할 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1787 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: restricted tokenì„ ë§Œë“¤ 수 ì—†ìŒ: 오류 코드 %lu\n" -#: pg_ctl.c:1818 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: 경고: 시스템 APIì—서 모든 job ê°ì²´ 함수를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_ctl.c:1901 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: ì ‘ê·¼ 권한용 LUID를 구할 수 ì—†ìŒ: 오류 코드 %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: í† í° ì •ë³´ë¥¼ 구할 수 ì—†ìŒ: 오류 코드 %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: 메모리 부족\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "보다 ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\"\n" -#: pg_ctl.c:1909 +#: pg_ctl.c:1913 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -490,75 +495,74 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL 서버를 초기화, 시작, 중지, 제어하는 ë„구입니다.\n" "\n" -#: pg_ctl.c:1910 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: pg_ctl.c:1911 +#: pg_ctl.c:1915 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n" -msgstr " %s init[db] [-D ë°ì´í„°ë””렉터리] [-s] [-o \"옵션\"]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D ë°ì´í„°ë””렉터리] [-s] [-o 옵션]\n" -#: pg_ctl.c:1912 +#: pg_ctl.c:1916 #, c-format msgid "" -" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" -"\"]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-w] [-t ì´ˆ] [-D ë°ì´í„°ë””렉터리] [-s] [-l 로그파ì¼] [-o \"옵션" -"\"]\n" +" %s start [-D ë°ì´í„°ë””렉터리] [-l 파ì¼ì´ë¦„] [-W] [-t ì´ˆ] [-s]\n" +" [-o 옵션] [-p 경로] [-c]\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:1918 #, c-format -msgid " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -msgstr " %s stop [-W] [-t ì´ˆ] [-D ë°ì´í„°ë””렉터리] [-s] [-m 중지모드]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D ë°ì´í„°ë””렉터리] [-m 중지방법] [-W] [-t ì´ˆ] [-s]\n" -#: pg_ctl.c:1914 +#: pg_ctl.c:1919 #, c-format msgid "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-w] [-t ì´ˆ] [-D ë°ì´í„°ë””렉터리] [-s] [-m 중지모드]\n" -" [-o \"옵션\"]\n" +" %s restart [-D ë°ì´í„°ë””렉터리] [-m 중지방법] [-W] [-t ì´ˆ] [-s]\n" +" [-o 옵션] [-c]\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:1921 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D ë°ì´í„°ë””렉터리] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D ë°ì´í„°ë””렉터리] [-s]\n" -#: pg_ctl.c:1917 +#: pg_ctl.c:1922 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D ë°ì´í„°ë””렉터리]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D ë°ì´í„°ë””렉터리]\n" -#: pg_ctl.c:1918 +#: pg_ctl.c:1923 #, c-format -msgid " %s promote [-D DATADIR] [-s]\n" -msgstr " %s promote [-D ë°ì´í„°ë””렉터리] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D ë°ì´í„°ë””렉터리] [-W] [-t ì´ˆ] [-s]\n" -#: pg_ctl.c:1919 +#: pg_ctl.c:1924 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill 시그ë„ì´ë¦„ PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill 시그ë„ì´ë¦„ PID\n" -#: pg_ctl.c:1921 +#: pg_ctl.c:1926 #, c-format msgid "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr "" -" %s register [-N 서비스ì´ë¦„] [-U 사용ìžì´ë¦„] [-P 암호] [-D ë°ì´í„°ë””렉터" -"리]\n" -" [-S 시작형태] [-w] [-t ì´ˆ] [-o \"옵션\"]\n" +" %s register [-D ë°ì´í„°ë””렉터리] [-N 서비스ì´ë¦„] [-U 사용ìžì´ë¦„] [-P 암호]\n" +" [-S 시작형태] [-e SOURCE] [-w] [-t ì´ˆ] [-o 옵션]\n" -#: pg_ctl.c:1923 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N 서비스ì´ë¦„]\n" -#: pg_ctl.c:1926 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" @@ -567,64 +571,52 @@ msgstr "" "\n" "ì¼ë°˜ 옵션들:\n" -#: pg_ctl.c:1927 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" -msgstr "" -" -D, --pgdata=ë°ì´í„°ë””렉터리 ë°ì´í„°ë² ì´ìФ ìžë£Œê°€ 저장ë˜ì–´ìžˆëŠ” 디렉터리\n" +msgstr " -D, --pgdata=ë°ì´í„°ë””렉터리 ë°ì´í„°ë² ì´ìФ ìžë£Œê°€ 저장ë˜ì–´ìžˆëŠ” 디렉터리\n" -#: pg_ctl.c:1929 +#: pg_ctl.c:1934 #, c-format -msgid "" -" -e SOURCE event source for logging when running as a service\n" -msgstr "" -" -e SOURCE 서비스가 실행 중ì¼ë•Œ ìŒ“ì„ ë¡œê·¸ë¥¼ 위한 ì´ë²¤íЏ 소스\n" +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE 서비스가 실행 중ì¼ë•Œ ìŒ“ì„ ë¡œê·¸ë¥¼ 위한 ì´ë²¤íЏ 소스\n" -#: pg_ctl.c:1931 +#: pg_ctl.c:1936 #, c-format msgid " -s, --silent only print errors, no informational messages\n" -msgstr "" -" -s, --silent ì¼ë°˜ì ì¸ 메시지는 ë³´ì´ì§€ 않고, 오류만 보여줌\n" +msgstr " -s, --silent ì¼ë°˜ì ì¸ 메시지는 ë³´ì´ì§€ 않고, 오류만 보여줌\n" -#: pg_ctl.c:1932 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=ì´ˆ -w 옵션 사용 시 대기 시간(ì´ˆ)\n" -#: pg_ctl.c:1933 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: pg_ctl.c:1934 +#: pg_ctl.c:1939 #, c-format -msgid " -w wait until operation completes\n" -msgstr " -w ìž‘ì—…ì´ ëë‚  때까지 기다림\n" +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait ìž‘ì—…ì´ ëë‚  때까지 기다림 (기본값)\n" -#: pg_ctl.c:1935 +#: pg_ctl.c:1940 #, c-format -msgid " -W do not wait until operation completes\n" -msgstr " -W ìž‘ì—…ì´ ëë‚  때까지 기다리지 않ìŒ\n" +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait ìž‘ì—…ì´ ëë‚  때까지 기다리지 않ìŒ\n" -#: pg_ctl.c:1936 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: pg_ctl.c:1937 -#, c-format -msgid "" -"(The default is to wait for shutdown, but not for start or restart.)\n" -"\n" -msgstr "" -"(기본 ì„¤ì •ì€ ì¤‘ì§€ í•  때는 기다리고, 시작ì´ë‚˜ 재시작할 때는 안 기다림.)\n" - -#: pg_ctl.c:1938 +#: pg_ctl.c:1942 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "-D ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ 않으면, PGDATA í™˜ê²½ë³€ìˆ˜ê°’ì„ ì‚¬ìš©í•¨.\n" -#: pg_ctl.c:1940 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" @@ -633,36 +625,36 @@ msgstr "" "\n" "start, restart 때 사용할 수 있는 옵션들:\n" -#: pg_ctl.c:1942 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files 코어 ë¤í”„ 파ì¼ì„ 만듬\n" -#: pg_ctl.c:1944 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files ì´ í”Œëž«í¼ì—서는 사용할 수 ì—†ìŒ\n" -#: pg_ctl.c:1946 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log=ë¡œê·¸íŒŒì¼ ì„œë²„ 로그를 ì´ ë¡œê·¸íŒŒì¼ì— 기ë¡í•¨\n" -#: pg_ctl.c:1947 +#: pg_ctl.c:1951 #, c-format msgid "" -" -o OPTIONS command line options to pass to postgres\n" +" -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n" msgstr "" -" -o 옵션들 PostgreSQL ì„œë²„í”„ë¡œê·¸ëž¨ì¸ postgres나 initdb\n" +" -o, --options=옵션들 PostgreSQL ì„œë²„í”„ë¡œê·¸ëž¨ì¸ postgres나 initdb\n" " 명령ì—서 사용할 명령행 옵션들\n" -#: pg_ctl.c:1949 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p PATH-TO-POSTGRES ë³´í†µì€ í•„ìš”ì¹˜ 않ìŒ\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:1954 #, c-format msgid "" "\n" @@ -671,14 +663,12 @@ msgstr "" "\n" "stop, restart 때 사용 í•  수 있는 옵션들:\n" -#: pg_ctl.c:1951 +#: pg_ctl.c:1955 #, c-format -msgid "" -" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" -msgstr "" -" -m, --mode=모드 모드는 \"smart\", \"fast\", \"immediate\" 중 하나\n" +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=모드 모드는 \"smart\", \"fast\", \"immediate\" 중 하나\n" -#: pg_ctl.c:1953 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -687,25 +677,22 @@ msgstr "" "\n" "중지방법 설명:\n" -#: pg_ctl.c:1954 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart 모든 í´ë¼ì´ì–¸íŠ¸ì˜ ì—°ê²°ì´ ëŠê¸°ê²Œ ë˜ë©´ 중지 ë¨\n" -#: pg_ctl.c:1955 +#: pg_ctl.c:1959 #, c-format -msgid " fast quit directly, with proper shutdown\n" -msgstr " fast í´ë¼ì´ì–¸íŠ¸ì˜ ì—°ê²°ì„ ê°•ì œë¡œ ëŠê³  ì •ìƒì ìœ¼ë¡œ 중지 ë¨\n" +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast í´ë¼ì´ì–¸íŠ¸ì˜ ì—°ê²°ì„ ê°•ì œë¡œ ëŠê³  ì •ìƒì ìœ¼ë¡œ 중지 ë¨ (기본값)\n" -#: pg_ctl.c:1956 +#: pg_ctl.c:1960 #, c-format -msgid "" -" immediate quit without complete shutdown; will lead to recovery on " -"restart\n" -msgstr "" -" immediate 그냥 무조건 중지함; 다시 시작할 때 복구 ìž‘ì—…ì„ í•  ìˆ˜ë„ ìžˆìŒ\n" +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr " immediate 그냥 무조건 중지함; 다시 시작할 때 복구 ìž‘ì—…ì„ í•  ìˆ˜ë„ ìžˆìŒ\n" -#: pg_ctl.c:1958 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -714,7 +701,7 @@ msgstr "" "\n" "사용할 수 있는 중지용(for kill) ì‹œê·¸ë„ ì´ë¦„:\n" -#: pg_ctl.c:1962 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" @@ -723,28 +710,27 @@ msgstr "" "\n" "서비스 등ë¡/제거용 옵션들:\n" -#: pg_ctl.c:1963 +#: pg_ctl.c:1967 #, c-format -msgid "" -" -N SERVICENAME service name with which to register PostgreSQL server\n" +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N SERVICENAME 서비스 목ë¡ì— 등ë¡ë  PostgreSQL 서비스 ì´ë¦„\n" -#: pg_ctl.c:1964 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P PASSWORD ì´ ì„œë¹„ìŠ¤ë¥¼ 실행할 사용ìžì˜ 암호\n" -#: pg_ctl.c:1965 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U USERNAME ì´ ì„œë¹„ìŠ¤ë¥¼ 실행할 ì‚¬ìš©ìž ì´ë¦„\n" -#: pg_ctl.c:1966 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S 시작형태 서비스로 등ë¡ëœ PostgreSQL 서버 시작 방법\n" -#: pg_ctl.c:1968 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" @@ -753,18 +739,17 @@ msgstr "" "\n" "시작형태 설명:\n" -#: pg_ctl.c:1969 +#: pg_ctl.c:1973 #, c-format -msgid "" -" auto start service automatically during system startup (default)\n" +msgid " auto start service automatically during system startup (default)\n" msgstr " auto ì‹œìŠ¤í…œì´ ì‹œìž‘ë˜ë©´ ìžë™ìœ¼ë¡œ 서비스가 ì‹œìž‘ë¨ (초기값)\n" -#: pg_ctl.c:1970 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" msgstr " demand ìˆ˜ë™ ì‹œìž‘\n" -#: pg_ctl.c:1973 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -773,27 +758,32 @@ msgstr "" "\n" "오류보고: .\n" -#: pg_ctl.c:1998 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ì¤‘ì§€ 방법 \"%s\"\n" -#: pg_ctl.c:2030 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ì‹œê·¸ë„ ì´ë¦„ \"%s\"\n" -#: pg_ctl.c:2047 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: 알 수 없는 시작형태 \"%s\"\n" -#: pg_ctl.c:2102 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: \"%s\" 명령ì—서 사용할 ë°ì´í„° 디렉터리를 알 수 ì—†ìŒ\n" -#: pg_ctl.c:2175 +#: pg_ctl.c:2128 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: 컨트롤 파ì¼ì´ 깨졌ìŒ\n" + +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -804,33 +794,32 @@ msgstr "" "ì‹œìŠ¤í…œê´€ë¦¬ìž ê¶Œí•œì´ ì—†ëŠ”, ì„œë²„í”„ë¡œì„¸ìŠ¤ì˜ ì†Œìœ ì£¼ê°€ ë  ì¼ë°˜ 사용ìžë¡œ\n" "ë¡œê·¸ì¸ í•´ì„œ(\"su\", \"runas\" ê°™ì€ ëª…ë ¹ ì´ìš©) 실행하십시오.\n" -#: pg_ctl.c:2258 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: -S ì˜µì…˜ì€ ì´ ìš´ì˜ì²´ì œì—서는 ì§€ì›í•˜ì§€ 않ìŒ\n" -#: pg_ctl.c:2297 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë“¤ (시작 \"%s\")\n" -#: pg_ctl.c:2321 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: kill ìž‘ì—…ì— í•„ìš”í•œ ì¸ìˆ˜ê°€ 빠졌습니다\n" -#: pg_ctl.c:2339 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: 알 수 없는 작업 모드 \"%s\"\n" -#: pg_ctl.c:2349 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: 수행할 ìž‘ì—…ì„ ì§€ì •í•˜ì§€ 않았습니다\n" -#: pg_ctl.c:2370 +#: pg_ctl.c:2393 #, c-format -msgid "" -"%s: no database directory specified and environment variable PGDATA unset\n" +msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: -D ì˜µì…˜ë„ ì—†ê³ , PGDATA í™˜ê²½ë³€ìˆ˜ê°’ë„ ì§€ì •ë˜ì–´ 있지 않습니다.\n" diff --git a/src/bin/pg_ctl/po/ru.po b/src/bin/pg_ctl/po/ru.po index 9f67cbc6649..4f7edba9cb1 100644 --- a/src/bin/pg_ctl/po/ru.po +++ b/src/bin/pg_ctl/po/ru.po @@ -6,14 +6,14 @@ # Sergey Burladyan , 2009, 2012. # Andrey Sudnik , 2010. # Dmitriy Olshevskiy , 2014. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: pg_ctl (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:45+0000\n" -"PO-Revision-Date: 2017-03-29 13:38+0300\n" +"POT-Creation-Date: 2018-10-05 21:51+0300\n" +"PO-Revision-Date: 2018-11-19 16:18+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -21,7 +21,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -110,82 +109,64 @@ msgstr "дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ñ Ð½ÐµÑ€Ð°Ñпоз msgid "could not get current working directory: %s\n" msgstr "не удалоÑÑŒ определить текущий рабочий каталог: %s\n" -#: pg_ctl.c:251 +#: pg_ctl.c:257 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: каталог \"%s\" не ÑущеÑтвует\n" -#: pg_ctl.c:254 +#: pg_ctl.c:260 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: нет доÑтупа к каталогу \"%s\": %s\n" -#: pg_ctl.c:268 +#: pg_ctl.c:273 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: каталог \"%s\" не Ñодержит Ñтруктуры клаÑтера баз данных\n" -#: pg_ctl.c:281 +#: pg_ctl.c:286 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть файл PID \"%s\": %s\n" -#: pg_ctl.c:290 +#: pg_ctl.c:295 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: файл PID \"%s\" пуÑÑ‚\n" -#: pg_ctl.c:293 +#: pg_ctl.c:298 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: неверные данные в файле PID \"%s\"\n" -#: pg_ctl.c:443 pg_ctl.c:471 +#: pg_ctl.c:459 pg_ctl.c:487 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: не удалоÑÑŒ запуÑтить Ñервер: %s\n" -#: pg_ctl.c:495 +#: pg_ctl.c:511 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: не удалоÑÑŒ запуÑтить Ñервер (код ошибки: %lu)\n" -#: pg_ctl.c:572 -#, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: параметр -w не поддерживаетÑÑ Ð¿Ñ€Ð¸ запуÑке Ñервера до верÑии 9.1\n" - -#: pg_ctl.c:637 -#, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: в параметре -w Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ отноÑительный путь к каталогу Ñокетов\n" - -#: pg_ctl.c:739 +#: pg_ctl.c:658 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "" "%s: не удалоÑÑŒ ограничить размер дампа памÑти; запрещено жёÑтким " "ограничением\n" -#: pg_ctl.c:764 +#: pg_ctl.c:684 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\"\n" -#: pg_ctl.c:769 +#: pg_ctl.c:689 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: в файле параметров \"%s\" должна быть ровно одна Ñтрока\n" -#: pg_ctl.c:820 +#: pg_ctl.c:735 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -196,7 +177,7 @@ msgstr "" "в каталоге \"%s\".\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_ctl.c:826 +#: pg_ctl.c:741 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -207,39 +188,40 @@ msgstr "" "но её верÑÐ¸Ñ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð°ÐµÑ‚ÑÑ Ð¾Ñ‚ верÑии %s.\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_ctl.c:859 +#: pg_ctl.c:774 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: Ñбой при инициализации ÑиÑтемы баз данных\n" -#: pg_ctl.c:874 +#: pg_ctl.c:789 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "" "%s: возможно, уже работает другой Ñервер; вÑÑ‘ же пробуем запуÑтить Ñтот " "Ñервер\n" -#: pg_ctl.c:912 +#: pg_ctl.c:827 msgid "waiting for server to start..." msgstr "ожидание запуÑка Ñервера..." -#: pg_ctl.c:917 pg_ctl.c:1024 pg_ctl.c:1115 pg_ctl.c:1244 +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 msgid " done\n" msgstr " готово\n" -#: pg_ctl.c:918 +#: pg_ctl.c:833 msgid "server started\n" msgstr "Ñервер запущен\n" -#: pg_ctl.c:921 pg_ctl.c:925 pg_ctl.c:1249 +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 msgid " stopped waiting\n" msgstr " прекращение ожиданиÑ\n" -#: pg_ctl.c:922 -msgid "server is still starting up\n" -msgstr "Ñервер вÑÑ‘ ещё запуÑкаетÑÑ\n" +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: Ñервер не запуÑтилÑÑ Ð·Ð° отведённое времÑ\n" -#: pg_ctl.c:926 +#: pg_ctl.c:843 #, c-format msgid "" "%s: could not start server\n" @@ -248,44 +230,35 @@ msgstr "" "%s: не удалоÑÑŒ запуÑтить Ñервер\n" "Изучите протокол выполнениÑ.\n" -#: pg_ctl.c:932 pg_ctl.c:1016 pg_ctl.c:1106 -msgid " failed\n" -msgstr " ошибка\n" - -#: pg_ctl.c:933 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: не удалоÑÑŒ дождатьÑÑ Ñервера вÑледÑтвие ошибки конфигурации\n" - -#: pg_ctl.c:939 +#: pg_ctl.c:851 msgid "server starting\n" msgstr "Ñервер запуÑкаетÑÑ\n" -#: pg_ctl.c:960 pg_ctl.c:1046 pg_ctl.c:1136 pg_ctl.c:1175 +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: файл PID \"%s\" не ÑущеÑтвует\n" -#: pg_ctl.c:961 pg_ctl.c:1048 pg_ctl.c:1137 pg_ctl.c:1176 +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 msgid "Is server running?\n" msgstr "Запущен ли Ñервер?\n" -#: pg_ctl.c:967 +#: pg_ctl.c:879 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "" "%s: оÑтановить Ñервер Ñ PID %ld Ð½ÐµÐ»ÑŒÐ·Ñ - он запущен в монопольном режиме\n" -#: pg_ctl.c:975 pg_ctl.c:1070 +#: pg_ctl.c:887 pg_ctl.c:983 #, c-format msgid "%s: could not send stop signal (PID: %ld): %s\n" msgstr "%s: не удалоÑÑŒ отправить Ñигнал оÑтановки (PID: %ld): %s\n" -#: pg_ctl.c:982 +#: pg_ctl.c:894 msgid "server shutting down\n" msgstr "Ñервер оÑтанавливаетÑÑ\n" -#: pg_ctl.c:997 pg_ctl.c:1085 +#: pg_ctl.c:909 pg_ctl.c:998 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -295,16 +268,20 @@ msgstr "" "Выключение произойдёт только при вызове pg_stop_backup().\n" "\n" -#: pg_ctl.c:1001 pg_ctl.c:1089 +#: pg_ctl.c:913 pg_ctl.c:1002 msgid "waiting for server to shut down..." msgstr "ожидание Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñервера..." -#: pg_ctl.c:1018 pg_ctl.c:1108 +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr " ошибка\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: Ñервер не оÑтанавливаетÑÑ\n" -#: pg_ctl.c:1020 pg_ctl.c:1110 +#: pg_ctl.c:933 pg_ctl.c:1024 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -312,201 +289,221 @@ msgstr "" "ПОДСКÐЗКÐ: Параметр \"-m fast\" может ÑброÑить ÑеанÑÑ‹ принудительно,\n" "не дожидаÑÑÑŒ, пока они завершатÑÑ Ñами.\n" -#: pg_ctl.c:1026 pg_ctl.c:1116 +#: pg_ctl.c:939 pg_ctl.c:1030 msgid "server stopped\n" msgstr "Ñервер оÑтановлен\n" -#: pg_ctl.c:1049 pg_ctl.c:1122 -msgid "starting server anyway\n" -msgstr "Ñервер запуÑкаетÑÑ, неÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° Ñто\n" +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "производитÑÑ Ð¿Ð¾Ð¿Ñ‹Ñ‚ÐºÐ° запуÑка Ñервера в любом Ñлучае\n" -#: pg_ctl.c:1058 +#: pg_ctl.c:971 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "" "%s: перезапуÑтить Ñервер Ñ PID %ld Ð½ÐµÐ»ÑŒÐ·Ñ - он запущен в монопольном режиме\n" -#: pg_ctl.c:1061 pg_ctl.c:1146 +#: pg_ctl.c:974 pg_ctl.c:1060 msgid "Please terminate the single-user server and try again.\n" msgstr "ПожалуйÑта, оÑтановите его и повторите попытку.\n" -#: pg_ctl.c:1120 +#: pg_ctl.c:1034 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: похоже, что Ñтарый Ñерверный процеÑÑ (PID: %ld) иÑчез\n" -#: pg_ctl.c:1143 +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "Ñервер запуÑкаетÑÑ, неÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° Ñто\n" + +#: pg_ctl.c:1057 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "" "%s: перезагрузить Ñервер Ñ PID %ld Ð½ÐµÐ»ÑŒÐ·Ñ - он запущен в монопольном режиме\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1066 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: не удалоÑÑŒ отправить Ñигнал перезагрузки (PID: %ld): %s\n" -#: pg_ctl.c:1157 +#: pg_ctl.c:1071 msgid "server signaled\n" msgstr "Ñигнал отправлен Ñерверу\n" -#: pg_ctl.c:1182 +#: pg_ctl.c:1096 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "" "%s: повыÑить Ñервер Ñ PID %ld Ð½ÐµÐ»ÑŒÐ·Ñ - он выполнÑетÑÑ Ð² монопольном режиме\n" -#: pg_ctl.c:1190 +#: pg_ctl.c:1104 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: повыÑить Ñервер Ð½ÐµÐ»ÑŒÐ·Ñ - он работает не в режиме резерва\n" -#: pg_ctl.c:1205 +#: pg_ctl.c:1119 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл \"%s\" Ñ Ñигналом к повышению: %s\n" -#: pg_ctl.c:1211 +#: pg_ctl.c:1125 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл \"%s\" Ñ Ñигналом к повышению: %s\n" -#: pg_ctl.c:1219 +#: pg_ctl.c:1133 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: не удалоÑÑŒ отправить Ñигнал к повышению (PID: %ld): %s\n" -#: pg_ctl.c:1222 +#: pg_ctl.c:1136 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: ошибка при удалении файла \"%s\" Ñ Ñигналом к повышению: %s\n" -#: pg_ctl.c:1231 +#: pg_ctl.c:1146 msgid "waiting for server to promote..." msgstr "ожидание Ð¿Ð¾Ð²Ñ‹ÑˆÐµÐ½Ð¸Ñ Ñервера..." -#: pg_ctl.c:1245 +#: pg_ctl.c:1160 msgid "server promoted\n" msgstr "Ñервер повышен\n" -#: pg_ctl.c:1250 -msgid "server is still promoting\n" -msgstr "Ñервер вÑÑ‘ ещё повышаетÑÑ\n" +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: повышение Ñервера не завершилоÑÑŒ за отведённое времÑ\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1171 msgid "server promoting\n" msgstr "Ñервер повышаетÑÑ\n" -#: pg_ctl.c:1301 +#: pg_ctl.c:1218 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: Ñервер работает в монопольном режиме (PID: %ld)\n" -#: pg_ctl.c:1314 +#: pg_ctl.c:1232 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: Ñервер работает (PID: %ld)\n" -#: pg_ctl.c:1330 +#: pg_ctl.c:1248 #, c-format msgid "%s: no server running\n" msgstr "%s: Ñервер не работает\n" -#: pg_ctl.c:1348 +#: pg_ctl.c:1265 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: не удалоÑÑŒ отправить Ñигнал %d (PID: %ld): %s\n" -#: pg_ctl.c:1405 +#: pg_ctl.c:1322 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: не удалоÑÑŒ найти Ñвой иÑполнÑемый файл\n" -#: pg_ctl.c:1415 +#: pg_ctl.c:1332 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: не удалоÑÑŒ найти иÑполнÑемый файл postgres\n" -#: pg_ctl.c:1485 pg_ctl.c:1519 +#: pg_ctl.c:1402 pg_ctl.c:1436 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: не удалоÑÑŒ открыть менеджер Ñлужб\n" -#: pg_ctl.c:1491 +#: pg_ctl.c:1408 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: Ñлужба \"%s\" уже зарегиÑтрирована\n" -#: pg_ctl.c:1502 +#: pg_ctl.c:1419 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: не удалоÑÑŒ зарегиÑтрировать Ñлужбу \"%s\" (код ошибки: %lu)\n" -#: pg_ctl.c:1525 +#: pg_ctl.c:1442 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: Ñлужба \"%s\" не зарегиÑтрирована\n" -#: pg_ctl.c:1532 +#: pg_ctl.c:1449 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: не удалоÑÑŒ открыть Ñлужбу \"%s\" (код ошибки: %lu)\n" -#: pg_ctl.c:1541 +#: pg_ctl.c:1458 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: ошибка при удалении Ñлужбы \"%s\" (код ошибки: %lu)\n" -#: pg_ctl.c:1628 +#: pg_ctl.c:1545 msgid "Waiting for server startup...\n" msgstr "Ожидание запуÑка Ñервера...\n" -#: pg_ctl.c:1631 +#: pg_ctl.c:1548 msgid "Timed out waiting for server startup\n" msgstr "Превышено Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿ÑƒÑка Ñервера\n" -#: pg_ctl.c:1635 +#: pg_ctl.c:1552 msgid "Server started and accepting connections\n" msgstr "Сервер запущен и принимает подключениÑ\n" -#: pg_ctl.c:1690 +#: pg_ctl.c:1607 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: не удалоÑÑŒ запуÑтить Ñлужбу \"%s\" (код ошибки: %lu)\n" -#: pg_ctl.c:1764 +#: pg_ctl.c:1677 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: ПРЕДУПРЕЖДЕÐИЕ: в Ñтой ОС Ð½ÐµÐ»ÑŒÐ·Ñ Ñоздавать ограниченные маркеры\n" -#: pg_ctl.c:1777 +#: pg_ctl.c:1690 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: не удалоÑÑŒ открыть маркер процеÑÑа (код ошибки: %lu)\n" -#: pg_ctl.c:1791 +#: pg_ctl.c:1704 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: не удалоÑÑŒ подготовить Ñтруктуры SID (код ошибки: %lu)\n" -#: pg_ctl.c:1811 +#: pg_ctl.c:1731 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: не удалоÑÑŒ Ñоздать ограниченный маркер (код ошибки: %lu)\n" -#: pg_ctl.c:1842 +#: pg_ctl.c:1762 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "" "%s: ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ найти вÑе функции Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð·Ð°Ð´Ð°Ñ‡Ð°Ð¼Ð¸ в " "ÑиÑтемном API\n" -#: pg_ctl.c:1925 +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: не удалоÑÑŒ получить LUID Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð²Ð¸Ð»ÐµÐ³Ð¸Ð¹ (код ошибки: %lu)\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: не удалоÑÑŒ получить информацию о маркере (код ошибки: %lu)\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: нехватка памÑти\n" + +#: pg_ctl.c:1905 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_ctl.c:1933 +#: pg_ctl.c:1913 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -516,77 +513,77 @@ msgstr "" "PostgreSQL.\n" "\n" -#: pg_ctl.c:1934 +#: pg_ctl.c:1914 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: pg_ctl.c:1935 +#: pg_ctl.c:1915 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n" -msgstr "" -" %s init[db] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-o \"ПÐРÐМЕТРЫ\"]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-o ПÐРÐМЕТРЫ]\n" -#: pg_ctl.c:1936 +#: pg_ctl.c:1916 #, c-format msgid "" -" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" -"\"]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-w] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-l ИМЯ-ФÐЙЛÐ]\n" -" [-o \"ПÐРÐМЕТРЫ\"]\n" +" %s start [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-l ИМЯ-ФÐЙЛÐ] [-W] [-t СЕК] [-s]\n" +" [-o ПÐРÐМЕТРЫ] [-p ПУТЬ] [-c]\n" -#: pg_ctl.c:1937 +#: pg_ctl.c:1918 #, c-format -msgid " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" msgstr "" -" %s stop [-W] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-m РЕЖИМ-ОСТÐÐОВКИ]\n" +" %s stop [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-m РЕЖИМ-ОСТÐÐОВКИ] [-W] [-t СЕК] [-s]\n" -#: pg_ctl.c:1938 +#: pg_ctl.c:1919 #, c-format msgid "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-w] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-m РЕЖИМ-ОСТÐÐОВКИ]\n" -" [-o \"ПÐРÐМЕТРЫ\"]\n" +" %s restart [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-m РЕЖИМ-ОСТÐÐОВКИ] [-W] [-t СЕК] [-s]\n" +" [-o ПÐРÐМЕТРЫ] [-c]\n" -#: pg_ctl.c:1940 +#: pg_ctl.c:1921 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s]\n" -#: pg_ctl.c:1941 +#: pg_ctl.c:1922 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D КÐТÐЛОГ-ДÐÐÐЫХ]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D КÐТÐЛОГ-ДÐÐÐЫХ]\n" -#: pg_ctl.c:1942 +#: pg_ctl.c:1923 #, c-format -msgid " %s promote [-w] [-t SECS] [-D DATADIR] [-s]\n" -msgstr " %s promote [-w] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-W] [-t СЕК] [-s]\n" -#: pg_ctl.c:1943 +#: pg_ctl.c:1924 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill СИГÐÐЛ PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill СИГÐÐЛ PID\n" -#: pg_ctl.c:1945 +#: pg_ctl.c:1926 #, c-format msgid "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o " +"OPTIONS]\n" msgstr "" -" %s register [-N ИМЯ-СЛУЖБЫ] [-U ПОЛЬЗОВÐТЕЛЬ] [-P ПÐРОЛЬ]\n" -" [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-S ТИП-ЗÐПУСКÐ] [-w] [-t СЕК]\n" -" [-o \"ПÐРÐМЕТРЫ\"]\n" +" %s register [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-N ИМЯ-СЛУЖБЫ] [-U ПОЛЬЗОВÐТЕЛЬ]\n" +" [-P ПÐРОЛЬ] [-S ТИП-ЗÐПУСКÐ] [-e ИСТОЧÐИК]\n" +" [-W] [-t СЕК] [-s] [-o ПÐРÐМЕТРЫ]\n" -#: pg_ctl.c:1947 +#: pg_ctl.c:1928 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N ИМЯ-СЛУЖБЫ]\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:1931 #, c-format msgid "" "\n" @@ -595,12 +592,12 @@ msgstr "" "\n" "Общие параметры:\n" -#: pg_ctl.c:1951 +#: pg_ctl.c:1932 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=КÐТÐЛОГ раÑположение хранилища баз данных\n" -#: pg_ctl.c:1953 +#: pg_ctl.c:1934 #, c-format msgid "" " -e SOURCE event source for logging when running as a service\n" @@ -609,54 +606,45 @@ msgstr "" "журнал,\n" " когда Ñервер работает в виде Ñлужбы\n" -#: pg_ctl.c:1955 +#: pg_ctl.c:1936 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr "" " -s, --silent выводить только ошибки, без информационных " "Ñообщений\n" -#: pg_ctl.c:1956 +#: pg_ctl.c:1937 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr "" " -t, --timeout=СЕК Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸ иÑпользовании параметра -w\n" -#: pg_ctl.c:1957 +#: pg_ctl.c:1938 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: pg_ctl.c:1958 +#: pg_ctl.c:1939 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait ждать Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸ (по умолчанию)\n" -#: pg_ctl.c:1959 +#: pg_ctl.c:1940 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait не ждать Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ð¸\n" -#: pg_ctl.c:1960 +#: pg_ctl.c:1941 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_ctl.c:1961 -#, c-format -msgid "" -"(The default is to wait for shutdown, but not for start or restart.)\n" -"\n" -msgstr "" -"(По умолчанию ожидание имеет меÑто при оÑтановке, но не при (пере)запуÑке.)\n" -"\n" - -#: pg_ctl.c:1962 +#: pg_ctl.c:1942 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "ЕÑли параметр -D опущен, иÑпользуетÑÑ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA.\n" -#: pg_ctl.c:1964 +#: pg_ctl.c:1944 #, c-format msgid "" "\n" @@ -665,24 +653,24 @@ msgstr "" "\n" "Параметры запуÑка и перезапуÑка:\n" -#: pg_ctl.c:1966 +#: pg_ctl.c:1946 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files указать postgres Ñоздавать дампы памÑти\n" -#: pg_ctl.c:1968 +#: pg_ctl.c:1948 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files неприменимо на Ñтой платформе\n" -#: pg_ctl.c:1970 +#: pg_ctl.c:1950 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr "" -" -l, --log=ФÐЙЛ запиÑывать (или добавлÑть) протокол Ñервера в " -"ФÐЙЛ.\n" +" -l, --log=ФÐЙЛ запиÑывать (или добавлÑть) протокол Ñервера в ФÐЙЛ." +"\n" -#: pg_ctl.c:1971 +#: pg_ctl.c:1951 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -692,12 +680,12 @@ msgstr "" "PostgreSQL)\n" " или initdb параметры командной Ñтроки\n" -#: pg_ctl.c:1973 +#: pg_ctl.c:1953 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p ПУТЬ-К-POSTGRES обычно не требуетÑÑ\n" -#: pg_ctl.c:1974 +#: pg_ctl.c:1954 #, c-format msgid "" "\n" @@ -706,14 +694,14 @@ msgstr "" "\n" "Параметры оÑтановки и перезапуÑка:\n" -#: pg_ctl.c:1975 +#: pg_ctl.c:1955 #, c-format msgid "" " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr "" " -m, --mode=РЕЖИМ может быть \"smart\", \"fast\" или \"immediate\"\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:1957 #, c-format msgid "" "\n" @@ -722,17 +710,17 @@ msgstr "" "\n" "Режимы оÑтановки:\n" -#: pg_ctl.c:1978 +#: pg_ctl.c:1958 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart закончить работу поÑле Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð²Ñех клиентов\n" -#: pg_ctl.c:1979 +#: pg_ctl.c:1959 #, c-format -msgid " fast quit directly, with proper shutdown\n" -msgstr " fast закончить Ñразу, в штатном режиме\n" +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast закончить Ñразу, в штатном режиме (по умолчанию)\n" -#: pg_ctl.c:1980 +#: pg_ctl.c:1960 #, c-format msgid "" " immediate quit without complete shutdown; will lead to recovery on " @@ -741,7 +729,7 @@ msgstr "" " immediate закончить немедленно, в ÑкÑтренном режиме; влечёт за Ñобой\n" " воÑÑтановление при перезапуÑке\n" -#: pg_ctl.c:1982 +#: pg_ctl.c:1962 #, c-format msgid "" "\n" @@ -750,7 +738,7 @@ msgstr "" "\n" "Разрешённые Ñигналы Ð´Ð»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ‹ kill:\n" -#: pg_ctl.c:1986 +#: pg_ctl.c:1966 #, c-format msgid "" "\n" @@ -759,30 +747,30 @@ msgstr "" "\n" "Параметры Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации и удалениÑ:\n" -#: pg_ctl.c:1987 +#: pg_ctl.c:1967 #, c-format msgid "" " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N ИМЯ-СЛУЖБЫ Ð¸Ð¼Ñ Ñлужбы Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации Ñервера PostgreSQL\n" -#: pg_ctl.c:1988 +#: pg_ctl.c:1968 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr "" " -P ПÐРОЛЬ пароль учётной запиÑи Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации Ñервера PostgreSQL\n" -#: pg_ctl.c:1989 +#: pg_ctl.c:1969 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr "" " -U ПОЛЬЗОВÐТЕЛЬ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ñ€ÐµÐ³Ð¸Ñтрации Ñервера PostgreSQL\n" -#: pg_ctl.c:1990 +#: pg_ctl.c:1970 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S ТИП-ЗÐПУСКРтип запуÑка Ñлужбы Ñервера PostgreSQL\n" -#: pg_ctl.c:1992 +#: pg_ctl.c:1972 #, c-format msgid "" "\n" @@ -791,20 +779,20 @@ msgstr "" "\n" "Типы запуÑка:\n" -#: pg_ctl.c:1993 +#: pg_ctl.c:1973 #, c-format msgid "" " auto start service automatically during system startup (default)\n" msgstr "" -" auto запуÑкать Ñлужбу автоматичеÑки при Ñтарте ÑиÑтемы (по " -"умолчанию)\n" +" auto запуÑкать Ñлужбу автоматичеÑки при Ñтарте ÑиÑтемы (по умолчанию)" +"\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:1974 #, c-format msgid " demand start service on demand\n" msgstr " demand запуÑкать Ñлужбу по требованию\n" -#: pg_ctl.c:1997 +#: pg_ctl.c:1977 #, c-format msgid "" "\n" @@ -813,32 +801,32 @@ msgstr "" "\n" "Об ошибках Ñообщайте по адреÑу .\n" -#: pg_ctl.c:2022 +#: pg_ctl.c:2002 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: неизвеÑтный режим оÑтановки \"%s\"\n" -#: pg_ctl.c:2054 +#: pg_ctl.c:2031 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: нераÑпознанное Ð¸Ð¼Ñ Ñигнала \"%s\"\n" -#: pg_ctl.c:2071 +#: pg_ctl.c:2048 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: нераÑпознанный тип запуÑка \"%s\"\n" -#: pg_ctl.c:2126 +#: pg_ctl.c:2103 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: не удалоÑÑŒ определить каталог данных Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команды \"%s\"\n" -#: pg_ctl.c:2151 +#: pg_ctl.c:2128 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: управлÑющий файл, по-видимому, иÑпорчен\n" -#: pg_ctl.c:2221 +#: pg_ctl.c:2199 #, c-format msgid "" "%s: cannot be run as root\n" @@ -849,32 +837,32 @@ msgstr "" "ПожалуйÑта, переключитеÑÑŒ на обычного Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (например,\n" "иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ \"su\"), который будет запуÑкать Ñерверный процеÑÑ.\n" -#: pg_ctl.c:2304 +#: pg_ctl.c:2283 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: параметр -S не поддерживаетÑÑ Ð² Ñтой ОС\n" -#: pg_ctl.c:2341 +#: pg_ctl.c:2320 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: pg_ctl.c:2365 +#: pg_ctl.c:2344 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: отÑутÑтвуют аргументы Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ð° kill\n" -#: pg_ctl.c:2383 +#: pg_ctl.c:2362 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: нераÑпознанный режим работы \"%s\"\n" -#: pg_ctl.c:2393 +#: pg_ctl.c:2372 #, c-format msgid "%s: no operation specified\n" msgstr "%s: команда не указана\n" -#: pg_ctl.c:2414 +#: pg_ctl.c:2393 #, c-format msgid "" "%s: no database directory specified and environment variable PGDATA unset\n" @@ -882,6 +870,45 @@ msgstr "" "%s: каталог баз данных не указан и Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PGDATA не " "уÑтановлена\n" +#~ msgid "" +#~ "\n" +#~ "%s: -w option is not supported when starting a pre-9.1 server\n" +#~ msgstr "" +#~ "\n" +#~ "%s: параметр -w не поддерживаетÑÑ Ð¿Ñ€Ð¸ запуÑке Ñервера до верÑии 9.1\n" + +#~ msgid "" +#~ "\n" +#~ "%s: -w option cannot use a relative socket directory specification\n" +#~ msgstr "" +#~ "\n" +#~ "%s: в параметре -w Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ отноÑительный путь к каталогу " +#~ "Ñокетов\n" + +#~ msgid "server is still starting up\n" +#~ msgstr "Ñервер вÑÑ‘ ещё запуÑкаетÑÑ\n" + +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "%s: не удалоÑÑŒ дождатьÑÑ Ñервера вÑледÑтвие ошибки конфигурации\n" + +#~ msgid "" +#~ " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o " +#~ "\"OPTIONS\"]\n" +#~ msgstr "" +#~ " %s start [-w] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-l ИМЯ-ФÐЙЛÐ]\n" +#~ " [-o \"ПÐРÐМЕТРЫ\"]\n" + +#~ msgid " %s promote [-w] [-t SECS] [-D DATADIR] [-s]\n" +#~ msgstr " %s promote [-w] [-t СЕК] [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s]\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(По умолчанию ожидание имеет меÑто при оÑтановке, но не при (пере)" +#~ "запуÑке.)\n" +#~ "\n" + #~ msgid "" #~ "\n" #~ "%s: could not stat file \"%s\": %s\n" @@ -921,9 +948,6 @@ msgstr "" #~ " -I, --idempotent не Ñчитать ошибкой, еÑли он уже запущен или " #~ "оÑтановлен\n" -#~ msgid " %s promote [-D DATADIR] [-s] [-m PROMOTION-MODE]\n" -#~ msgstr " %s promote [-D КÐТÐЛОГ-ДÐÐÐЫХ] [-s] [-m РЕЖИМ-ПОВЫШЕÐИЯ]\n" - #~ msgid "" #~ "\n" #~ "Promotion modes are:\n" diff --git a/src/bin/pg_ctl/po/sv.po b/src/bin/pg_ctl/po/sv.po index 55a86013312..df540bf001e 100644 --- a/src/bin/pg_ctl/po/sv.po +++ b/src/bin/pg_ctl/po/sv.po @@ -1,5 +1,5 @@ # Swedish message translation file for pg_ctl -# Dennis Björklund , 2004, 2005, 2006, 2017. +# Dennis Björklund , 2004, 2005, 2006, 2017, 2018, 2019. # Magnus Hagander , 2010. # Mats Erik Andersson , 2013, 2014. # @@ -7,10 +7,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-19 06:45+0000\n" -"PO-Revision-Date: 2017-07-20 21:38+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 07:16+0000\n" +"PO-Revision-Date: 2019-04-29 13:37+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -18,40 +18,44 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 #, c-format -msgid "could not identify current directory: %s" -msgstr "kunde inte identifiera aktuell katalog: %s" +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ogiltig binär \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "kunde inte läsa binär \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "kunde inte byta katalog till \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "kunde inte läsa symbolisk länk \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose misslyckades: %s" +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "slut pÃ¥ minne" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 @@ -80,22 +84,17 @@ msgstr "kommandot kan ej hittas" msgid "child process exited with exit code %d" msgstr "barnprocess avslutade med kod %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "barnprocess terminerades med avbrott 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "barnprocess terminerades av signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "barnprocess terminerades av signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "barnprocess avslutade med okänd statuskod %d" @@ -105,62 +104,72 @@ msgstr "barnprocess avslutade med okänd statuskod %d" msgid "could not get current working directory: %s\n" msgstr "kunde inte fastställa nuvarande arbetskatalog: %s\n" -#: pg_ctl.c:263 +#: pg_ctl.c:262 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: katalogen \"%s\" existerar inte\n" -#: pg_ctl.c:266 +#: pg_ctl.c:265 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: kunde inte komma Ã¥t katalogen \"%s\": %s\n" -#: pg_ctl.c:279 +#: pg_ctl.c:278 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: katalogen \"%s\" innehÃ¥ller inte nÃ¥got databaskluster.\n" -#: pg_ctl.c:292 +#: pg_ctl.c:291 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: kunde inte öppna PID-fil \"%s\": %s\n" -#: pg_ctl.c:301 +#: pg_ctl.c:300 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: PID-filen \"%s\" är tom\n" -#: pg_ctl.c:304 +#: pg_ctl.c:303 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: ogiltig data i PID-fil \"%s\"\n" -#: pg_ctl.c:465 pg_ctl.c:493 +#: pg_ctl.c:464 pg_ctl.c:506 #, c-format msgid "%s: could not start server: %s\n" msgstr "%s: kunde inte starta servern: %s\n" -#: pg_ctl.c:517 +#: pg_ctl.c:484 +#, c-format +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: kunde inte starta servern dÃ¥ setsid() misslyckades: %s\n" + +#: pg_ctl.c:530 #, c-format msgid "%s: could not start server: error code %lu\n" msgstr "%s: kunde inte starta servern: felkod %lu\n" -#: pg_ctl.c:664 +#: pg_ctl.c:677 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: kan inte sätta storleksgränsning pÃ¥ core-fil; tillÃ¥ts inte av hÃ¥rd gräns\n" -#: pg_ctl.c:690 +#: pg_ctl.c:703 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: kunde inte läsa filen \"%s\"\n" -#: pg_ctl.c:695 +#: pg_ctl.c:708 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: inställningsfilen \"%s\" mÃ¥ste bestÃ¥ av en enda rad.\n" -#: pg_ctl.c:741 +#: pg_ctl.c:750 pg_ctl.c:941 pg_ctl.c:1037 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: kunde inte skicka stopp-signal (PID: %ld): %s\n" + +#: pg_ctl.c:778 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -171,7 +180,7 @@ msgstr "" "katalog som \"%s\".\n" "Kontrollera din installation.\n" -#: pg_ctl.c:747 +#: pg_ctl.c:784 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -182,38 +191,38 @@ msgstr "" "men är inte av samma version som %s.\n" "Kontrollera din installation.\n" -#: pg_ctl.c:780 +#: pg_ctl.c:817 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: skapande av databaskluster misslyckades\n" -#: pg_ctl.c:795 +#: pg_ctl.c:832 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: en annan server verkar köra; försöker starta servern ändÃ¥.\n" -#: pg_ctl.c:833 +#: pg_ctl.c:881 msgid "waiting for server to start..." msgstr "väntar pÃ¥ att servern skall starta..." -#: pg_ctl.c:838 pg_ctl.c:943 pg_ctl.c:1035 pg_ctl.c:1165 +#: pg_ctl.c:886 pg_ctl.c:991 pg_ctl.c:1083 pg_ctl.c:1213 msgid " done\n" msgstr " klar\n" -#: pg_ctl.c:839 +#: pg_ctl.c:887 msgid "server started\n" msgstr "servern startad\n" -#: pg_ctl.c:842 pg_ctl.c:848 pg_ctl.c:1170 +#: pg_ctl.c:890 pg_ctl.c:896 pg_ctl.c:1218 msgid " stopped waiting\n" msgstr " avslutade väntan\n" -#: pg_ctl.c:843 +#: pg_ctl.c:891 #, c-format msgid "%s: server did not start in time\n" msgstr "%s: servern startade inte i tid\n" -#: pg_ctl.c:849 +#: pg_ctl.c:897 #, c-format msgid "" "%s: could not start server\n" @@ -222,34 +231,29 @@ msgstr "" "%s: kunde inte starta servern\n" "Undersök logg-utskriften.\n" -#: pg_ctl.c:857 +#: pg_ctl.c:905 msgid "server starting\n" msgstr "servern startar\n" -#: pg_ctl.c:878 pg_ctl.c:965 pg_ctl.c:1056 pg_ctl.c:1095 +#: pg_ctl.c:926 pg_ctl.c:1013 pg_ctl.c:1104 pg_ctl.c:1143 pg_ctl.c:1242 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: PID-filen \"%s\" finns inte\n" -#: pg_ctl.c:879 pg_ctl.c:967 pg_ctl.c:1057 pg_ctl.c:1096 +#: pg_ctl.c:927 pg_ctl.c:1015 pg_ctl.c:1105 pg_ctl.c:1144 pg_ctl.c:1243 msgid "Is server running?\n" msgstr "Kör servern?\n" -#: pg_ctl.c:885 +#: pg_ctl.c:933 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: Kan inte stanna servern. En-användar-server i drift (PID: %ld).\n" -#: pg_ctl.c:893 pg_ctl.c:989 -#, c-format -msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "%s: kunde inte skicka stopp-signal (PID: %ld): %s\n" - -#: pg_ctl.c:900 +#: pg_ctl.c:948 msgid "server shutting down\n" msgstr "servern stänger ner\n" -#: pg_ctl.c:915 pg_ctl.c:1004 +#: pg_ctl.c:963 pg_ctl.c:1052 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -259,20 +263,20 @@ msgstr "" "Nedstängning är inte fullständig förrän pg_stop_backup() har anropats.\n" "\n" -#: pg_ctl.c:919 pg_ctl.c:1008 +#: pg_ctl.c:967 pg_ctl.c:1056 msgid "waiting for server to shut down..." msgstr "väntar pÃ¥ att servern skall stänga ner..." -#: pg_ctl.c:935 pg_ctl.c:1026 +#: pg_ctl.c:983 pg_ctl.c:1074 msgid " failed\n" msgstr " misslyckades\n" -#: pg_ctl.c:937 pg_ctl.c:1028 +#: pg_ctl.c:985 pg_ctl.c:1076 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: servern stänger inte ner\n" -#: pg_ctl.c:939 pg_ctl.c:1030 +#: pg_ctl.c:987 pg_ctl.c:1078 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -280,197 +284,245 @@ msgstr "" "TIPS: Flaggan \"-m fast\" avslutar sessioner omedelbart, i stället för att\n" "vänta pÃ¥ deras självvalda avslut.\n" -#: pg_ctl.c:945 pg_ctl.c:1036 +#: pg_ctl.c:993 pg_ctl.c:1084 msgid "server stopped\n" msgstr "servern är stoppad\n" -#: pg_ctl.c:968 pg_ctl.c:1042 -msgid "starting server anyway\n" -msgstr "startar servern ändÃ¥\n" +#: pg_ctl.c:1016 +msgid "trying to start server anyway\n" +msgstr "försöker starta servern ändÃ¥\n" -#: pg_ctl.c:977 +#: pg_ctl.c:1025 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "%s: kan inte starta om servern. En-användar-server kör (PID: %ld).\n" -#: pg_ctl.c:980 pg_ctl.c:1066 +#: pg_ctl.c:1028 pg_ctl.c:1114 msgid "Please terminate the single-user server and try again.\n" msgstr "Var vänlig att stanna en-användar-servern och försök sedan igen.\n" -#: pg_ctl.c:1040 +#: pg_ctl.c:1088 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: gamla serverprocessen (PID: %ld) verkar vara borta\n" -#: pg_ctl.c:1063 +#: pg_ctl.c:1090 +msgid "starting server anyway\n" +msgstr "startar servern ändÃ¥\n" + +#: pg_ctl.c:1111 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" msgstr "%s: kan inte ladda om servern; en-användar-server kör (PID: %ld)\n" -#: pg_ctl.c:1072 +#: pg_ctl.c:1120 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: kunde inte skicka signalen \"reload\" (PID: %ld): %s\n" -#: pg_ctl.c:1077 +#: pg_ctl.c:1125 msgid "server signaled\n" -msgstr "servern är singalerad\n" +msgstr "servern är signalerad\n" -#: pg_ctl.c:1102 +#: pg_ctl.c:1150 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" msgstr "%s: kan inte befordra servern; en-användar-server kör (PID: %ld)\n" -#: pg_ctl.c:1110 +#: pg_ctl.c:1158 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: kan inte befordra servern; servern är inte i beredskapsläge.\n" -#: pg_ctl.c:1125 +#: pg_ctl.c:1173 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: kunde inte skapa befordringssignalfil \"%s\": %s\n" -#: pg_ctl.c:1131 +#: pg_ctl.c:1179 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: kunde inte skriva befordringssignalfil \"%s\": %s\n" -#: pg_ctl.c:1139 +#: pg_ctl.c:1187 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: kunde inte skicka befordringssignal (PID: %ld): %s\n" -#: pg_ctl.c:1142 +#: pg_ctl.c:1190 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: kunde inte ta bort befordringssignalfil \"%s\": %s\n" -#: pg_ctl.c:1152 +#: pg_ctl.c:1200 msgid "waiting for server to promote..." msgstr "väntar pÃ¥ att servern skall befordras..." -#: pg_ctl.c:1166 +#: pg_ctl.c:1214 msgid "server promoted\n" msgstr "servern befordrad\n" -#: pg_ctl.c:1171 +#: pg_ctl.c:1219 #, c-format msgid "%s: server did not promote in time\n" msgstr "%s: servern befordrades inte i tid\n" -#: pg_ctl.c:1177 +#: pg_ctl.c:1225 msgid "server promoting\n" msgstr "servern befordras\n" -#: pg_ctl.c:1224 +#: pg_ctl.c:1249 +#, c-format +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: kan inte rotera loggfil; en-användar-server kör (PID: %ld)\n" + +#: pg_ctl.c:1259 +#, c-format +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: kunde inte skapa loggroteringssignalfil \"%s\": %s\n" + +#: pg_ctl.c:1265 +#, c-format +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: kunde inte skriva loggroteringssignalfil \"%s\": %s\n" + +#: pg_ctl.c:1273 +#, c-format +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: kunde inte skicka signalen för loggrotering (PID: %ld): %s\n" + +#: pg_ctl.c:1276 +#, c-format +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: kunde inte ta bort loggroteringssignalfil \"%s\": %s\n" + +#: pg_ctl.c:1281 +msgid "server signaled to rotate log file\n" +msgstr "servern är signalerad att rotera loggfil\n" + +#: pg_ctl.c:1328 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: en-användar-server kör. (PID: %ld)\n" -#: pg_ctl.c:1238 +#: pg_ctl.c:1342 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: servern kör (PID: %ld)\n" -#: pg_ctl.c:1254 +#: pg_ctl.c:1358 #, c-format msgid "%s: no server running\n" msgstr "%s: ingen server kör\n" -#: pg_ctl.c:1271 +#: pg_ctl.c:1375 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: kunde inte skicka signal %d (PID: %ld): %s\n" -#: pg_ctl.c:1328 +#: pg_ctl.c:1432 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: kunde inte hitta det egna programmets körbara fil\n" -#: pg_ctl.c:1338 +#: pg_ctl.c:1442 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: kunde inte hitta körbar postgres.\n" -#: pg_ctl.c:1408 pg_ctl.c:1442 +#: pg_ctl.c:1512 pg_ctl.c:1546 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: kunde inte öppna tjänstehanteraren\n" -#: pg_ctl.c:1414 +#: pg_ctl.c:1518 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: tjänsten \"%s\" är redan registrerad\n" -#: pg_ctl.c:1425 +#: pg_ctl.c:1529 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: kunde inte registrera tjänsten \"%s\": felkod %lu\n" -#: pg_ctl.c:1448 +#: pg_ctl.c:1552 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: tjänsten \"%s\" är inte registrerad\n" -#: pg_ctl.c:1455 +#: pg_ctl.c:1559 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: kunde inte öppna tjänsten \"%s\": felkod %lu\n" -#: pg_ctl.c:1464 +#: pg_ctl.c:1568 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: kunde inte avregistrera tjänsten \"%s\": felkod %lu\n" -#: pg_ctl.c:1551 +#: pg_ctl.c:1655 msgid "Waiting for server startup...\n" msgstr "Väntar pÃ¥ serverstart...\n" -#: pg_ctl.c:1554 +#: pg_ctl.c:1658 msgid "Timed out waiting for server startup\n" msgstr "Tidsfristen ute vid väntan pÃ¥ serverstart\n" -#: pg_ctl.c:1558 +#: pg_ctl.c:1662 msgid "Server started and accepting connections\n" msgstr "Server startad och accepterar nu anslutningar\n" -#: pg_ctl.c:1613 +#: pg_ctl.c:1717 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: kunde inte starta tjänsten \"%s\": felkod %lu\n" -#: pg_ctl.c:1687 +#: pg_ctl.c:1787 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: VARNING: \"Restricted Token\" stöds inte av plattformen.\n" -#: pg_ctl.c:1700 +#: pg_ctl.c:1800 #, c-format msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: kunde inte skapa processmärke (token): felkod %lu\n" +msgstr "%s: kunde inte öppna process-token: felkod %lu\n" -#: pg_ctl.c:1714 +#: pg_ctl.c:1814 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: kunde inte tilldela SID: felkod %lu\n" -#: pg_ctl.c:1734 +#: pg_ctl.c:1841 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" -#: pg_ctl.c:1765 +#: pg_ctl.c:1872 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: VARNING: kunde inte hitta alla jobb-funktioner system-API:et.\n" -#: pg_ctl.c:1848 +#: pg_ctl.c:1969 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: kunde inte hämta LUID:er för rättigheter: felkod %lu\n" + +#: pg_ctl.c:1977 pg_ctl.c:1991 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: kunde inte hämta token-information: felkod %lu\n" + +#: pg_ctl.c:1985 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: slut pÃ¥ minne\n" + +#: pg_ctl.c:2015 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_ctl.c:1856 +#: pg_ctl.c:2023 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -480,148 +532,157 @@ msgstr "" "PostgreSQL-tjänsten.\n" "\n" -#: pg_ctl.c:1857 +#: pg_ctl.c:2024 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_ctl.c:1858 +#: pg_ctl.c:2025 #, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" -msgstr " %s init[db] [-D DATAKAT] [-s] [-o FLAGGOR]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D DATAKAT] [-s] [-o FLAGGOR]\n" -#: pg_ctl.c:1859 +#: pg_ctl.c:2026 #, c-format msgid "" -" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-p PATH] [-c]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-D DATAKAT] [-l FILNAMN] [-W] [-t SEK] [-s]\n" -" [-o FLAGGOR] [-p SOKVÄG] [-c]\n" +" %s start [-D DATAKAT] [-l FILNAMN] [-W] [-t SEK] [-s]\n" +" [-o FLAGGOR] [-p SOKVÄG] [-c]\n" -#: pg_ctl.c:1861 +#: pg_ctl.c:2028 #, c-format -msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -msgstr " %s stop [-D DATAKAT] [-m STÄNGNINGSMETOD] [-W] [-t SEK] [-s]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D DATAKAT] [-m STÄNGNINGSMETOD] [-W] [-t SEK] [-s]\n" -#: pg_ctl.c:1862 +#: pg_ctl.c:2029 #, c-format msgid "" -" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" -" [-o OPTIONS] [-c]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-D DATAKAT] [-m STÄNGNINGSMETOD] [-W] [-t SEK] [-s]\n" -" [-o FLAGGOR] [-c]\n" +" %s restart [-D DATAKAT] [-m STÄNGNINGSMETOD] [-W] [-t SEK] [-s]\n" +" [-o FLAGGOR] [-c]\n" + +#: pg_ctl.c:2031 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D DATAKAT] [-s]\n" -#: pg_ctl.c:1864 +#: pg_ctl.c:2032 #, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D DATAKAT] [-s]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D DATAKAT]\n" -#: pg_ctl.c:1865 +#: pg_ctl.c:2033 #, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D DATAKAT]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D DATAKAT] [-W] [-t SEK] [-s]\n" -#: pg_ctl.c:1866 +#: pg_ctl.c:2034 #, c-format -msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" -msgstr " %s promote [-D DATAKAT] [-W] [-t SEK] [-s]\n" +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s logrotate [-D DATAKAT] [-s]\n" -#: pg_ctl.c:1867 +#: pg_ctl.c:2035 #, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill SIGNALNAMN PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SIGNALNAMN PID\n" -#: pg_ctl.c:1869 +#: pg_ctl.c:2037 #, c-format msgid "" -" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" -" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr "" -" %s register [-D DATAKAT] [-N TJÄNSTENAMN] [-U ANVÄNDARNAMN] [-P LÖSENORD]\n" -" [-S STARTTYPE] [-e KÄLLA] [-W] [-t SEK] [-s] [-o FLAGGOR]\n" +" %s register [-D DATAKAT] [-N TJÄNSTENAMN] [-U ANVÄNDARNAMN] [-P LÖSENORD]\n" +" [-S STARTTYPE] [-e KÄLLA] [-W] [-t SEK] [-s] [-o FLAGGOR]\n" -#: pg_ctl.c:1871 +#: pg_ctl.c:2039 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N TJÄNSTNAMN]\n" -#: pg_ctl.c:1874 +#: pg_ctl.c:2042 #, c-format msgid "" "\n" "Common options:\n" -msgstr "\nGemensamma flaggor:\n" +msgstr "" +"\n" +"Gemensamma flaggor:\n" -#: pg_ctl.c:1875 +#: pg_ctl.c:2043 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=DATAKAT plats för databasens lagringsarea\n" -#: pg_ctl.c:1877 +#: pg_ctl.c:2045 #, c-format msgid " -e SOURCE event source for logging when running as a service\n" msgstr " -e KÄLLA händelsekälla för loggning när vi kör som en tjänst\n" -#: pg_ctl.c:1879 +#: pg_ctl.c:2047 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent skriv bara ut fel, inga informationsmeddelanden\n" -#: pg_ctl.c:1880 +#: pg_ctl.c:2048 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SEK antal sekunder att vänta när växeln -w används\n" -#: pg_ctl.c:1881 +#: pg_ctl.c:2049 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_ctl.c:1882 +#: pg_ctl.c:2050 #, c-format msgid " -w, --wait wait until operation completes (default)\n" msgstr " -w, --wait vänta pÃ¥ att operationen slutförs (standard)\n" -#: pg_ctl.c:1883 +#: pg_ctl.c:2051 #, c-format msgid " -W, --no-wait do not wait until operation completes\n" msgstr " -W, --no-wait vänta inte pÃ¥ att operationen slutförs\n" -#: pg_ctl.c:1884 +#: pg_ctl.c:2052 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" -#: pg_ctl.c:1885 +#: pg_ctl.c:2053 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "Om flaggan -D inte har angivits sÃ¥ används omgivningsvariabeln PGDATA.\n" -#: pg_ctl.c:1887 +#: pg_ctl.c:2055 #, c-format msgid "" "\n" "Options for start or restart:\n" -msgstr "\nFlaggor för start eller omstart:\n" +msgstr "" +"\n" +"Flaggor för start eller omstart:\n" -#: pg_ctl.c:1889 +#: pg_ctl.c:2057 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files tillÃ¥t postgres att skapa core-filer\n" -#: pg_ctl.c:1891 +#: pg_ctl.c:2059 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files inte giltig för denna plattform\n" -#: pg_ctl.c:1893 +#: pg_ctl.c:2061 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log=FILNAMN skriv, eller tillfoga, server-loggen till FILNAMN\n" -#: pg_ctl.c:1894 +#: pg_ctl.c:2062 #, c-format msgid "" " -o, --options=OPTIONS command line options to pass to postgres\n" @@ -630,26 +691,28 @@ msgstr "" " -o, --options=OPTIONS kommandoradsflaggor som skickas vidare till postgres\n" " (PostgreSQL-serverns körbara fil) eller till initdb\n" -#: pg_ctl.c:1896 +#: pg_ctl.c:2064 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr "" " -p SÖKVÄG-TILL-POSTGRES\n" " behövs normalt inte\n" -#: pg_ctl.c:1897 +#: pg_ctl.c:2065 #, c-format msgid "" "\n" "Options for stop or restart:\n" -msgstr "\nFlaggor för stopp eller omstart:\n" +msgstr "" +"\n" +"Flaggor för stopp eller omstart:\n" -#: pg_ctl.c:1898 +#: pg_ctl.c:2066 #, c-format msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" msgstr " -m, --mode=METOD METOD kan vara \"smart\", \"fast\" eller \"immediate\"\n" -#: pg_ctl.c:1900 +#: pg_ctl.c:2068 #, c-format msgid "" "\n" @@ -658,56 +721,60 @@ msgstr "" "\n" "Stängningsmetoder är:\n" -#: pg_ctl.c:1901 +#: pg_ctl.c:2069 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart stäng när alla klienter har avslutat\n" -#: pg_ctl.c:1902 +#: pg_ctl.c:2070 #, c-format msgid " fast quit directly, with proper shutdown (default)\n" msgstr " fast stäng omedelbart, med en kontrollerad nedstängning (standard)\n" -#: pg_ctl.c:1903 +#: pg_ctl.c:2071 #, c-format msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr " immediate stäng utan kontroller; kommer leda till Ã¥terställning vid omstart\n" -#: pg_ctl.c:1905 +#: pg_ctl.c:2073 #, c-format msgid "" "\n" "Allowed signal names for kill:\n" -msgstr "\nTillÃ¥tna signalnamn för kommando \"kill\":\n" +msgstr "" +"\n" +"TillÃ¥tna signalnamn för kommando \"kill\":\n" -#: pg_ctl.c:1909 +#: pg_ctl.c:2077 #, c-format msgid "" "\n" "Options for register and unregister:\n" -msgstr "\nFlaggor för registrering och avregistrering:\n" +msgstr "" +"\n" +"Flaggor för registrering och avregistrering:\n" -#: pg_ctl.c:1910 +#: pg_ctl.c:2078 #, c-format msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N TJÄNSTENAMN tjänstenamn att registrera PostgreSQL-servern med\n" -#: pg_ctl.c:1911 +#: pg_ctl.c:2079 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P LÖSENORD lösenord för konto vid registrering av PostgreSQL-servern\n" -#: pg_ctl.c:1912 +#: pg_ctl.c:2080 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U NAMN användarnamn för konto vid registrering av PostgreSQL-servern\n" -#: pg_ctl.c:1913 +#: pg_ctl.c:2081 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S STARTSÄTT sätt att registrera PostgreSQL-servern vid tjänstestart\n" -#: pg_ctl.c:1915 +#: pg_ctl.c:2083 #, c-format msgid "" "\n" @@ -716,51 +783,51 @@ msgstr "" "\n" "Startmetoder är:\n" -#: pg_ctl.c:1916 +#: pg_ctl.c:2084 #, c-format msgid " auto start service automatically during system startup (default)\n" msgstr " auto starta tjänsten automatiskt vid systemstart (förval)\n" -#: pg_ctl.c:1917 +#: pg_ctl.c:2085 #, c-format msgid " demand start service on demand\n" msgstr " demand starta tjänsten vid behov\n" -#: pg_ctl.c:1920 +#: pg_ctl.c:2088 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapportera fel till .\n" +"Rapportera fel till .\n" -#: pg_ctl.c:1945 +#: pg_ctl.c:2113 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: ogiltig stängningsmetod \"%s\"\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2142 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: ogiltigt signalnamn \"%s\"\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:2159 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: ogiltigt startvillkor \"%s\"\n" -#: pg_ctl.c:2049 +#: pg_ctl.c:2214 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: kunde inte bestämma databaskatalogen frÃ¥n kommandot \"%s\"\n" -#: pg_ctl.c:2074 +#: pg_ctl.c:2239 #, c-format msgid "%s: control file appears to be corrupt\n" msgstr "%s: kontrollfilen verkar vara trasig\n" -#: pg_ctl.c:2144 +#: pg_ctl.c:2307 #, c-format msgid "" "%s: cannot be run as root\n" @@ -771,32 +838,32 @@ msgstr "" "Logga in (t.ex. med \"su\") som den (opriviligerade) användare\n" "vilken skall äga serverprocessen.\n" -#: pg_ctl.c:2228 +#: pg_ctl.c:2391 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: flaggan -S stöds inte pÃ¥ denna plattform.\n" -#: pg_ctl.c:2265 +#: pg_ctl.c:2428 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" -#: pg_ctl.c:2289 +#: pg_ctl.c:2454 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: saknar argument för \"kill\"-kommando.\n" -#: pg_ctl.c:2307 +#: pg_ctl.c:2472 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: okänd operationsmetod \"%s\"\n" -#: pg_ctl.c:2317 +#: pg_ctl.c:2482 #, c-format msgid "%s: no operation specified\n" msgstr "%s: ingen operation angiven\n" -#: pg_ctl.c:2338 +#: pg_ctl.c:2503 #, c-format msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: ingen databaskatalog angiven och omgivningsvariabeln PGDATA är inte satt\n" @@ -841,3 +908,28 @@ msgstr "%s: ingen databaskatalog angiven och omgivningsvariabeln PGDATA är inte #~ msgstr "" #~ "\n" #~ "%s: växeln -w stöds inte av server i version före 9.1\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapportera fel till .\n" + +#~ msgid "child process was terminated by signal %d" +#~ msgstr "barnprocess terminerades av signal %d" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "barnprocess terminerades av signal %s" + +#~ msgid "pclose failed: %s" +#~ msgstr "pclose misslyckades: %s" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" + +#~ msgid "could not identify current directory: %s" +#~ msgstr "kunde inte identifiera aktuell katalog: %s" diff --git a/src/bin/pg_ctl/po/tr.po b/src/bin/pg_ctl/po/tr.po new file mode 100644 index 00000000000..f65c378198a --- /dev/null +++ b/src/bin/pg_ctl/po/tr.po @@ -0,0 +1,869 @@ +# translation of pg_ctl-tr.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2007. +# Nicolai Tufar , 2004, 2005, 2007. +# Abdullah Gülner , 2018. +msgid "" +msgstr "" +"Project-Id-Version: pg_ctl-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-10-10 21:15+0000\n" +"PO-Revision-Date: 2018-10-15 12:14+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "geçerli dizin tespit edilemedi: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "geçersiz ikili (binary) \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili (binary) dosyası okunamadı" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" çalıştırmak için bulunamadı" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "symbolic link \"%s\" okuma hatası" + +#: ../../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "pclose baÅŸarısız oldu: %s" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 +#: ../../port/path.c:687 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "komut çalıştırılabilir deÄŸil" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "komut bulunamadı" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "alt süreç %d çıkış koduyla sonuçlandırılmıştır" + +#: ../../common/wait_error.c:61 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "alt süreç 0x%X exception tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:71 +#, c-format +msgid "child process was terminated by signal %s" +msgstr "alt süreç %s sinyali tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:75 +#, c-format +msgid "child process was terminated by signal %d" +msgstr "alt süreç %d sinyali tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:80 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "alt süreç %d bilinmeyen durumu ile sonlandırılmıştır" + +#: ../../port/path.c:654 +#, c-format +msgid "could not get current working directory: %s\n" +msgstr "geçerli dizin belirlenemedi: %s\n" + +#: pg_ctl.c:257 +#, c-format +msgid "%s: directory \"%s\" does not exist\n" +msgstr "%s: \"%s\" dizini mevcut deÄŸil\n" + +#: pg_ctl.c:260 +#, c-format +msgid "%s: could not access directory \"%s\": %s\n" +msgstr "%s: \"%s\" dizine eriÅŸim hatası: %s\n" + +#: pg_ctl.c:273 +#, c-format +msgid "%s: directory \"%s\" is not a database cluster directory\n" +msgstr "%s: \"%s\" dizini bir veritabanı kümesi dizini deÄŸil\n" + +#: pg_ctl.c:286 +#, c-format +msgid "%s: could not open PID file \"%s\": %s\n" +msgstr "%s: \"%s\" PID dosyası açılamadı: %s\n" + +#: pg_ctl.c:295 +#, c-format +msgid "%s: the PID file \"%s\" is empty\n" +msgstr "%s: \"%s\" PID dosyası boÅŸtur\n" + +#: pg_ctl.c:298 +#, c-format +msgid "%s: invalid data in PID file \"%s\"\n" +msgstr "%s: \"%s\" PID dosyasında geçersiz veri\n" + +#: pg_ctl.c:459 pg_ctl.c:487 +#, c-format +msgid "%s: could not start server: %s\n" +msgstr "%s: sunucu baÅŸlatılamadı: %s\n" + +#: pg_ctl.c:511 +#, c-format +msgid "%s: could not start server: error code %lu\n" +msgstr "%s: sunucu baÅŸlatılamadı: hata kodu %lu\n" + +#: pg_ctl.c:658 +#, c-format +msgid "%s: cannot set core file size limit; disallowed by hard limit\n" +msgstr "%s: core boyutu ayarlanamadı; hard limit tarafından sınırlanmış.\n" + +#: pg_ctl.c:684 +#, c-format +msgid "%s: could not read file \"%s\"\n" +msgstr "%s: \"%s\" dosyası okunamadı\n" + +#: pg_ctl.c:689 +#, c-format +msgid "%s: option file \"%s\" must have exactly one line\n" +msgstr "%s: \"%s\" seçenek dosyası sadece 1 satır olmalıdır\n" + +#: pg_ctl.c:735 +#, c-format +msgid "" +"The program \"%s\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"\"%s\" programına %s tarafından gereksinim duyuluyor, ancak \n" +"\"%s\" ile aynı dizinde bulunamadı.\n" +"Kurulumunuzu kontrol ediniz.\n" + +#: pg_ctl.c:741 +#, c-format +msgid "" +"The program \"%s\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"\"%s\" programı \"%s\" tarafından\n" +"bulundu ancak %s ile aynı sürüm numarasına sahip deÄŸil.\n" +"Kurulumunuzu kontrol ediniz.\n" + +#: pg_ctl.c:774 +#, c-format +msgid "%s: database system initialization failed\n" +msgstr "%s: veritabanı ilklendirme baÅŸarısız oldu\n" + +#: pg_ctl.c:789 +#, c-format +msgid "%s: another server might be running; trying to start server anyway\n" +msgstr "%s: baÅŸka bir sunucu çalışıyor olabilir; yine de baÅŸlatmaya çalışılıyor.\n" + +#: pg_ctl.c:827 +msgid "waiting for server to start..." +msgstr "sunucunun baÅŸlaması bekleniyor..." + +#: pg_ctl.c:832 pg_ctl.c:937 pg_ctl.c:1029 pg_ctl.c:1159 +msgid " done\n" +msgstr " tamam\n" + +#: pg_ctl.c:833 +msgid "server started\n" +msgstr "sunucu baÅŸlatıldı\n" + +#: pg_ctl.c:836 pg_ctl.c:842 pg_ctl.c:1164 +msgid " stopped waiting\n" +msgstr "bekleme durduruldu\n" + +#: pg_ctl.c:837 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: sunucu zamanında baÅŸlamadı\n" + +#: pg_ctl.c:843 +#, c-format +msgid "" +"%s: could not start server\n" +"Examine the log output.\n" +msgstr "" +"%s: sunucu baÅŸlatılamadı\n" +"Kayıt dosyasını inceleyiniz\n" + +#: pg_ctl.c:851 +msgid "server starting\n" +msgstr "sunucu baÅŸlıyor\n" + +#: pg_ctl.c:872 pg_ctl.c:959 pg_ctl.c:1050 pg_ctl.c:1089 +#, c-format +msgid "%s: PID file \"%s\" does not exist\n" +msgstr "%s: \"%s\" PID dosyası bulunamadı\n" + +#: pg_ctl.c:873 pg_ctl.c:961 pg_ctl.c:1051 pg_ctl.c:1090 +msgid "Is server running?\n" +msgstr "Sunucu çalışıyor mu?\n" + +#: pg_ctl.c:879 +#, c-format +msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" +msgstr "%s: sunucu durdurulamadı; tek kullanıcılı sunucu çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:887 pg_ctl.c:983 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s:durdurma sinyali baÅŸarısız oldu (PID: %ld): %s\n" + +#: pg_ctl.c:894 +msgid "server shutting down\n" +msgstr "sunucu kapatılıyor\n" + +#: pg_ctl.c:909 pg_ctl.c:998 +msgid "" +"WARNING: online backup mode is active\n" +"Shutdown will not complete until pg_stop_backup() is called.\n" +"\n" +msgstr "" +"WARNING: çevrimiçi yedekleme modu etkin\n" +"pg_stop_backup() çalıştırılmadam sunucu kapatılmayacaktır.\n" +"\n" + +#: pg_ctl.c:913 pg_ctl.c:1002 +msgid "waiting for server to shut down..." +msgstr "sunucunun kapanması bekleniyor..." + +#: pg_ctl.c:929 pg_ctl.c:1020 +msgid " failed\n" +msgstr " baÅŸarısız oldu\n" + +#: pg_ctl.c:931 pg_ctl.c:1022 +#, c-format +msgid "%s: server does not shut down\n" +msgstr "%s: sunucu kapanmıyor\n" + +#: pg_ctl.c:933 pg_ctl.c:1024 +msgid "" +"HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" +"waiting for session-initiated disconnection.\n" +msgstr "" +"İPUCU: \"-m fast\" seçeneÄŸi oturumların kendilerinin bitmesini beklemektense\n" +"oturumları aniden keser.\n" + +#: pg_ctl.c:939 pg_ctl.c:1030 +msgid "server stopped\n" +msgstr "sunucu durduruldu\n" + +#: pg_ctl.c:962 +msgid "trying to start server anyway\n" +msgstr "sunucu yine de baÅŸlatılmaya çalışılıyor\n" + +#: pg_ctl.c:971 +#, c-format +msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" +msgstr "%s: sunucu baÅŸlatılamadı; tek kullanıcılı sunucu çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:974 pg_ctl.c:1060 +msgid "Please terminate the single-user server and try again.\n" +msgstr "Lütfen tek kullanıcılı sunucuyu durdurun ve yeniden deneyin.\n" + +#: pg_ctl.c:1034 +#, c-format +msgid "%s: old server process (PID: %ld) seems to be gone\n" +msgstr "%s: eski sunucu süreci (PID: %ld) kaybolmuÅŸtur\n" + +#: pg_ctl.c:1036 +msgid "starting server anyway\n" +msgstr "sunucu yine de baÅŸlatılıyor\n" + +#: pg_ctl.c:1057 +#, c-format +msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgstr "%s: sunucu yeniden yüklenemedi, tek kullanıcılı sunucu çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:1066 +#, c-format +msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgstr "%s: yeniden yükleme sinyali gönderilemedi (PID: %ld): %s\n" + +#: pg_ctl.c:1071 +msgid "server signaled\n" +msgstr "sunucuya sinyal gönderildi\n" + +#: pg_ctl.c:1096 +#, c-format +msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" +msgstr "%s: sunucu yükseltilemedi (promote), tek kullanıcılı sunucu çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:1104 +#, c-format +msgid "%s: cannot promote server; server is not in standby mode\n" +msgstr "%s: sunucu yükseltilemiyor (promote), sunucu yedek (standby) modda deÄŸil\n" + +#: pg_ctl.c:1119 +#, c-format +msgid "%s: could not create promote signal file \"%s\": %s\n" +msgstr "%s: \"%s\" yükseltme (promote) sinyal dosyası yaratılamadı: %s\n" + +#: pg_ctl.c:1125 +#, c-format +msgid "%s: could not write promote signal file \"%s\": %s\n" +msgstr "%s: \"%s\" yükseltme (promote) sinyal dosyasına yazılamadı: %s\n" + +#: pg_ctl.c:1133 +#, c-format +msgid "%s: could not send promote signal (PID: %ld): %s\n" +msgstr "%s: yükseltme (promote) sinyali gönderilemedi (PID: %ld): %s\n" + +#: pg_ctl.c:1136 +#, c-format +msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgstr "%s: \"%s\" yükseltme (promote) sinyal dosyası slinemedi: %s\n" + +#: pg_ctl.c:1146 +msgid "waiting for server to promote..." +msgstr "sunucunun yükseltilmesi (promote) bekleniyor..." + +#: pg_ctl.c:1160 +msgid "server promoted\n" +msgstr "sunucu yükseltildi (promote)\n" + +#: pg_ctl.c:1165 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: sunucu zamanında yükseltilemedi (promote)\n" + +#: pg_ctl.c:1171 +msgid "server promoting\n" +msgstr "sunucu yükeltiliyor (promote)\n" + +#: pg_ctl.c:1218 +#, c-format +msgid "%s: single-user server is running (PID: %ld)\n" +msgstr "%s: sunucu, tek kullanıcı biçiminde çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:1232 +#, c-format +msgid "%s: server is running (PID: %ld)\n" +msgstr "%s: sunucu çalışıyor (PID: %ld)\n" + +#: pg_ctl.c:1248 +#, c-format +msgid "%s: no server running\n" +msgstr "%s: çalışan sunucu yok\n" + +#: pg_ctl.c:1265 +#, c-format +msgid "%s: could not send signal %d (PID: %ld): %s\n" +msgstr "%s: %d reload sinyali gönderilemedi (PID: %ld): %s\n" + +#: pg_ctl.c:1322 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s:Çalıştırılabilir dosya bulunamadı\n" + +#: pg_ctl.c:1332 +#, c-format +msgid "%s: could not find postgres program executable\n" +msgstr "%s: çalıştırılabilir postgres programı bulunamadı\n" + +#: pg_ctl.c:1402 pg_ctl.c:1436 +#, c-format +msgid "%s: could not open service manager\n" +msgstr "%s: servis yöneticisi açılamadı\n" + +#: pg_ctl.c:1408 +#, c-format +msgid "%s: service \"%s\" already registered\n" +msgstr "%s: \"%s\" servisi daha önce kaydedilmiÅŸtir\n" + +#: pg_ctl.c:1419 +#, c-format +msgid "%s: could not register service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" servisi kayıt edilemedi: hata kodu %lu\n" + +#: pg_ctl.c:1442 +#, c-format +msgid "%s: service \"%s\" not registered\n" +msgstr "%s: \"%s\" servisi kayıtlı deÄŸil\n" + +#: pg_ctl.c:1449 +#, c-format +msgid "%s: could not open service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" servisi açılamadı: hata kodu %lu\n" + +#: pg_ctl.c:1458 +#, c-format +msgid "%s: could not unregister service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" servisinin kaydı silinemedi: hata kodu %lu\n" + +#: pg_ctl.c:1545 +msgid "Waiting for server startup...\n" +msgstr "Sunucunun baÅŸlaması bekleniyor...\n" + +#: pg_ctl.c:1548 +msgid "Timed out waiting for server startup\n" +msgstr "Sunucu baÅŸlarken zaman aşımı oldu\n" + +#: pg_ctl.c:1552 +msgid "Server started and accepting connections\n" +msgstr "Sunucu baÅŸladı ve baÄŸlantı kabul ediyor\n" + +#: pg_ctl.c:1607 +#, c-format +msgid "%s: could not start service \"%s\": error code %lu\n" +msgstr "%s: \"%s\" servisi baÅŸlatılamadı: Hata kodu %lu\n" + +#: pg_ctl.c:1677 +#, c-format +msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +msgstr "%s: UYARI: bu platformda restricted token oluÅŸturulamıyor\n" + +#: pg_ctl.c:1690 +#, c-format +msgid "%s: could not open process token: error code %lu\n" +msgstr "%s: process token açma baÅŸarısız: hata kodu %lu\n" + +#: pg_ctl.c:1704 +#, c-format +msgid "%s: could not allocate SIDs: error code %lu\n" +msgstr "%s: SIDler ayrılamadı: Hata kodu %lu\n" + +#: pg_ctl.c:1731 +#, c-format +msgid "%s: could not create restricted token: error code %lu\n" +msgstr "%s: kısıtlı andaç (restricted token) oluÅŸturulamıyor: hata kodu %lu\n" + +#: pg_ctl.c:1762 +#, c-format +msgid "%s: WARNING: could not locate all job object functions in system API\n" +msgstr "%s: UYARI: sistem API içinde tüm iÅŸ nesnesi fonksiyonlarının yeri belirlenemedi\n" + +#: pg_ctl.c:1859 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: yetkiler için LUID'ler alınamadı: hata kodu %lu\n" + +#: pg_ctl.c:1867 pg_ctl.c:1881 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: andaç (token) bilgisi alınamadı: hata kodu %lu\n" + +#: pg_ctl.c:1875 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: yetersiz bellek\n" + +#: pg_ctl.c:1905 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" komutunu kullanabilirsiniz.\n" + +#: pg_ctl.c:1913 +#, c-format +msgid "" +"%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" +"\n" +msgstr "" +"%s bir PostgreSQL sunucusunu ilklendirmek, baÅŸlatmak, durdurmak ya da kontrol etmek için bir araçtır.\n" +"\n" + +#: pg_ctl.c:1914 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_ctl.c:1915 +#, c-format +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D VERİDİZİN] [-s] [-o SEÇENEKLER]\n" + +#: pg_ctl.c:1916 +#, c-format +msgid "" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" +msgstr "" +" %s start [-D VERİDİZİN] [-l DOSYAADI] [-W] [-t SANİYE] [-s]\n" +" [-o SECENEKLER] [-p YOL] [-c]\n" + +#: pg_ctl.c:1918 +#, c-format +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr "" +" %s stop [-D VERİDİZİNİ] [-m KAPATMA_MODU] [-W] [-t SANİYE] [-s]\n" +"\n" + +#: pg_ctl.c:1919 +#, c-format +msgid "" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" +msgstr "" +" %s restart [-D VERİDİZİNİ] [-m KAPATMA-MODU] [-W] [-t SANİYE] [-s]\n" +" [-o SEÇENEKLER] [-c]\n" +"\n" + +#: pg_ctl.c:1921 +#, c-format +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D VERİ_DİZİNİ] [-s]\n" + +#: pg_ctl.c:1922 +#, c-format +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D VERİ_DİZİNİ]\n" + +#: pg_ctl.c:1923 +#, c-format +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr "" +" %s promote [-D VERİDİZİNİ] [-W] [-t SANİYE] [-s]\n" +"\n" + +#: pg_ctl.c:1924 +#, c-format +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill SİNYAL_ADI SÜREÇ_NUMARASI\n" + +#: pg_ctl.c:1926 +#, c-format +msgid "" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" +msgstr "" +" %s register [-D VERİDİZİNİ] [-N SERVISADI] [-U KULLANICIADI] [-P PAROLA]\n" +" [-S BAÅžLATMA-TİPİ] [-e KAYNAK] [-W] [-t SANİYE] [-s] [-o SEÇENEKLER]\n" + +#: pg_ctl.c:1928 +#, c-format +msgid " %s unregister [-N SERVICENAME]\n" +msgstr " %s unregister [-N SERVİS_ADI]\n" + +#: pg_ctl.c:1931 +#, c-format +msgid "" +"\n" +"Common options:\n" +msgstr "" +"\n" +"Ortak seçenekler:\n" + +#: pg_ctl.c:1932 +#, c-format +msgid " -D, --pgdata=DATADIR location of the database storage area\n" +msgstr " -D, --pgdata=VERİDİZİNİ verinin tutulacağı alan\n" + +#: pg_ctl.c:1934 +#, c-format +msgid " -e SOURCE event source for logging when running as a service\n" +msgstr " -e SOURCE servis olarak çalışırken loglama için olay (event) kaynağı\n" + +#: pg_ctl.c:1936 +#, c-format +msgid " -s, --silent only print errors, no informational messages\n" +msgstr " -s, --silent sadece hataları yazar, hiç bir bilgi mesajı yazmaz\n" + +#: pg_ctl.c:1937 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when using -w option\n" +msgstr " -t, --timeout=SANİYE -w seçeneÄŸini kullanırken beklenecek saniye\n" + +#: pg_ctl.c:1938 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_ctl.c:1939 +#, c-format +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait iÅŸlem bitene kadar bekle (varsayılan)\n" + +#: pg_ctl.c:1940 +#, c-format +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait iÅŸlem bitene kadar bekleme\n" + +#: pg_ctl.c:1941 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_ctl.c:1942 +#, c-format +msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" +msgstr "EÄŸer -D seçeneÄŸi gözardı edilirse, PGDATA çevresel deÄŸiÅŸkeni kullanılacaktır.\n" + +#: pg_ctl.c:1944 +#, c-format +msgid "" +"\n" +"Options for start or restart:\n" +msgstr "" +"\n" +"BaÅŸlamak ya da yeniden baÅŸlamak için seçenekler:\n" + +#: pg_ctl.c:1946 +#, c-format +msgid " -c, --core-files allow postgres to produce core files\n" +msgstr " -c, --core-files postgres'in core dosyaları oluÅŸturmasına izin ver\n" + +#: pg_ctl.c:1948 +#, c-format +msgid " -c, --core-files not applicable on this platform\n" +msgstr " -c, --core-files bu platformda uygulanmaz\n" + +#: pg_ctl.c:1950 +#, c-format +msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" +msgstr " -l, --log=DOSYA_ADI sunucu loglarını DOSYA_ADI dosyasına yaz (ya da dosyanın sonuna ekle).\n" + +#: pg_ctl.c:1951 +#, c-format +msgid "" +" -o, --options=OPTIONS command line options to pass to postgres\n" +" (PostgreSQL server executable) or initdb\n" +msgstr "" +" -o, --options=SEÇENEKLER postgres'e (PostgreSQL sunucusu çalıştırılabilir dosyası)\n" +" ya da initdb'ye geçilecek komut satırı seçenekleri\n" + +#: pg_ctl.c:1953 +#, c-format +msgid " -p PATH-TO-POSTGRES normally not necessary\n" +msgstr " -p PATH-TO-POSTGRES normalde gerekli deÄŸildir\n" + +#: pg_ctl.c:1954 +#, c-format +msgid "" +"\n" +"Options for stop or restart:\n" +msgstr "" +"\n" +"Durdurmak ya da yeniden baÅŸlatmak için seçenekler:\n" + +#: pg_ctl.c:1955 +#, c-format +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MOD MOD \"smart\", \"fast\", veya \"immediate\" olabilir\n" + +#: pg_ctl.c:1957 +#, c-format +msgid "" +"\n" +"Shutdown modes are:\n" +msgstr "" +"\n" +"Kapatma modları:\n" + +#: pg_ctl.c:1958 +#, c-format +msgid " smart quit after all clients have disconnected\n" +msgstr " smart tüm istemciler baÄŸlantılarını kestikten sonra dur\n" + +#: pg_ctl.c:1959 +#, c-format +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast düzgünce kapanarak direk olarak dur (varsayılan)\n" + +#: pg_ctl.c:1960 +#, c-format +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" +msgstr " immediate tam bir kapanma gerçekleÅŸmeden dur; yeniden baÅŸladığında kurtarma modunda açılır\n" + +#: pg_ctl.c:1962 +#, c-format +msgid "" +"\n" +"Allowed signal names for kill:\n" +msgstr "" +"\n" +"kill için izin verilen sinyal adları:\n" + +#: pg_ctl.c:1966 +#, c-format +msgid "" +"\n" +"Options for register and unregister:\n" +msgstr "" +"\n" +"Kaydetmek ya da kaydı silmek için seçenekler:\n" + +#: pg_ctl.c:1967 +#, c-format +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" +msgstr " -N SERVICENAME PostgreSQL sunucusunu kaydedeceÄŸiniz servis adı\n" + +#: pg_ctl.c:1968 +#, c-format +msgid " -P PASSWORD password of account to register PostgreSQL server\n" +msgstr " -P PASSWORD PostgreSQL sunucusunu kaydetmek için hesabın ÅŸifresi\n" + +#: pg_ctl.c:1969 +#, c-format +msgid " -U USERNAME user name of account to register PostgreSQL server\n" +msgstr " -U USERNAME PostgreSQL sunucusunu kaydetmek için gerekli kullanıcı adı\n" + +#: pg_ctl.c:1970 +#, c-format +msgid " -S START-TYPE service start type to register PostgreSQL server\n" +msgstr " -S START-TYPE PostgreSQL sunucusunu kaydedeceÄŸiniz servis baÅŸlama tipi\n" + +#: pg_ctl.c:1972 +#, c-format +msgid "" +"\n" +"Start types are:\n" +msgstr "" +"\n" +"BaÅŸlama tipleri: \n" + +#: pg_ctl.c:1973 +#, c-format +msgid " auto start service automatically during system startup (default)\n" +msgstr " auto sistem açılışında servisi otomatik baÅŸlat (varsayılan)\n" + +#: pg_ctl.c:1974 +#, c-format +msgid " demand start service on demand\n" +msgstr " demand hizmeti talep üzerine baÅŸlat\n" + +#: pg_ctl.c:1977 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildiriniz.\n" + +#: pg_ctl.c:2002 +#, c-format +msgid "%s: unrecognized shutdown mode \"%s\"\n" +msgstr "%s: geçersiz kapanma modu \"%s\"\n" + +#: pg_ctl.c:2031 +#, c-format +msgid "%s: unrecognized signal name \"%s\"\n" +msgstr "%s: geçersiz sinyal adı \"%s\"\n" + +#: pg_ctl.c:2048 +#, c-format +msgid "%s: unrecognized start type \"%s\"\n" +msgstr "%s: geçersiz baÅŸlama tipi \"%s\"\n" + +#: pg_ctl.c:2103 +#, c-format +msgid "%s: could not determine the data directory using command \"%s\"\n" +msgstr "%s: \"%s\" komutu kullanılarak veri dizini belirlenemedi\n" + +#: pg_ctl.c:2128 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: kontrol dosyası bozuk görünüyor\n" + +#: pg_ctl.c:2199 +#, c-format +msgid "" +"%s: cannot be run as root\n" +"Please log in (using, e.g., \"su\") as the (unprivileged) user that will\n" +"own the server process.\n" +msgstr "" +"%s: root olarak çalıştırılamaz\n" +"Lütfen (yani \"su\" kullanarak) sunucu sürecine sahip olacak (yetkisiz) kullanıcı\n" +"ile sisteme giriÅŸ yapınız.\n" + +#: pg_ctl.c:2283 +#, c-format +msgid "%s: -S option not supported on this platform\n" +msgstr "%s: -S seçeneÄŸi bu platformda desteklenmiyor.\n" + +#: pg_ctl.c:2320 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: çok fazla komut satırı argümanı (ilki : \"%s\")\n" + +#: pg_ctl.c:2344 +#, c-format +msgid "%s: missing arguments for kill mode\n" +msgstr "%s: kill modu için eksik argümanlar\n" + +#: pg_ctl.c:2362 +#, c-format +msgid "%s: unrecognized operation mode \"%s\"\n" +msgstr "%s: geçersiz iÅŸlem modu \"%s\"\n" + +#: pg_ctl.c:2372 +#, c-format +msgid "%s: no operation specified\n" +msgstr "%s: hiçbir iÅŸlem belirtilmedi\n" + +#: pg_ctl.c:2393 +#, c-format +msgid "%s: no database directory specified and environment variable PGDATA unset\n" +msgstr "%s: Hiçbir veritabanı dizini belirtilmemiÅŸ ve PGDATA çevresel deÄŸiÅŸkeni boÅŸ\n" + +#~ msgid "%s: could not start server: exit code was %d\n" +#~ msgstr "%s: sunucu baÅŸlatılamadı: çıkış kodu: %d\n" + +#~ msgid "server is still starting up\n" +#~ msgstr "sunucu hala baÅŸlıyor\n" + +#, fuzzy +#~ msgid "%s: could not wait for server because of misconfiguration\n" +#~ msgstr "geçersiz ayarlarından dolayı autovacuum çalıştırılamadı" + +#~ msgid " %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n" +#~ msgstr " %s start [-w] [-t saniye] [-D VERİ_DİZİNİ] [-s] [-l DOSYA_ADI] [-o \"SEÇENEKLER\"]\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help Bu yardımı göster ve çık\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm numarasını yazar ve çıkar\n" + +#~ msgid "" +#~ "(The default is to wait for shutdown, but not for start or restart.)\n" +#~ "\n" +#~ msgstr "" +#~ "(Ön tanımlı iÅŸlem kapanmak için beklemektir; baÅŸlamak ya da yeniden baÅŸlamak deÄŸildir.)\n" +#~ "\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" + +#~ msgid "" +#~ "%s is a utility to start, stop, restart, reload configuration files,\n" +#~ "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n" +#~ "\n" +#~ msgstr "" +#~ "%s baÅŸlatmak, durdurmak, yeniden baÅŸlatmak, yapılandırma dosyalarını yeniden yüklemek\n" +#~ "PostgreSQL sunucusunun durumunu bildirmek, ya da PostgreSQL sürecini öldürmek için bir yardımcı programdır\n" +#~ "\n" diff --git a/src/bin/pg_ctl/po/zh_CN.po b/src/bin/pg_ctl/po/zh_CN.po index c62a5221ad9..9f0cdde713a 100644 --- a/src/bin/pg_ctl/po/zh_CN.po +++ b/src/bin/pg_ctl/po/zh_CN.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_ctl (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2015-11-26 18:43+0000\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:13+0000\n" "PO-Revision-Date: 2015-12-01 19:30+0800\n" "Last-Translator: Yuwei Peng \n" "Language-Team: Chinese (Simplified)\n" @@ -16,46 +16,52 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.7\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 -#, c-format -msgid "could not identify current directory: %s" +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, fuzzy, c-format +#| msgid "could not identify current directory: %s" +msgid "could not identify current directory: %m" msgstr "无法确认当å‰ç›®å½•: %s" # command.c:122 -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "æ— æ•ˆçš„äºŒè¿›åˆ¶ç  \"%s\"" # command.c:1103 -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "无法读å–äºŒè¿›åˆ¶ç  \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "未能找到一个 \"%s\" æ¥æ‰§è¡Œ" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "无法跳转到目录 \"%s\" 中: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "无法跳转到目录 \"%s\" 中: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "无法读å–符å·é“¾ç»“ \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "无法读å–符å·é“¾æŽ¥ \"%s\": %m" -#: ../../common/exec.c:523 -#, c-format -msgid "pclose failed: %s" +#: ../../common/exec.c:541 +#, fuzzy, c-format +#| msgid "pclose failed: %s" +msgid "pclose failed: %m" msgstr "pclose调用失败: %s" +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "内存用尽" + #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 ../../port/path.c:598 ../../port/path.c:636 -#: ../../port/path.c:653 +#: ../../common/fe_memutils.c:98 ../../port/path.c:632 ../../port/path.c:670 +#: ../../port/path.c:687 #, c-format msgid "out of memory\n" msgstr "内存溢出\n" @@ -66,122 +72,109 @@ msgstr "内存溢出\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "无法å¤åˆ¶ç©ºæŒ‡é’ˆ (内部错误)\n" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "无法执行命令" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "没有找到命令" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "å­è¿›ç¨‹å·²é€€å‡º, 退出ç ä¸º %d" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "å­è¿›ç¨‹è¢«ä¾‹å¤–(exception) 0x%X 终止" -#: ../../common/wait_error.c:73 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %s 终止" - -#: ../../common/wait_error.c:77 -#, c-format -msgid "child process was terminated by signal %d" +#: ../../common/wait_error.c:66 +#, fuzzy, c-format +#| msgid "child process was terminated by signal %d" +msgid "child process was terminated by signal %d: %s" msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %d 终止" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "å­è¿›ç¨‹å·²é€€å‡º, æœªçŸ¥çŠ¶æ€ %d" -#: ../../port/path.c:620 +#: ../../port/path.c:654 #, c-format msgid "could not get current working directory: %s\n" msgstr "无法得到当å‰å·¥ä½œç›®å½•: %s\n" -#: pg_ctl.c:258 +#: pg_ctl.c:262 #, c-format msgid "%s: directory \"%s\" does not exist\n" msgstr "%s: 目录 \"%s\" ä¸å­˜åœ¨\n" -#: pg_ctl.c:261 +#: pg_ctl.c:265 #, c-format msgid "%s: could not access directory \"%s\": %s\n" msgstr "%s: 无法访问目录 \"%s\": %s\n" -#: pg_ctl.c:275 +#: pg_ctl.c:278 #, c-format msgid "%s: directory \"%s\" is not a database cluster directory\n" msgstr "%s: 目录 \"%s\"䏿˜¯ä¸€ä¸ªæ•°æ®åº“集群目录\n" -#: pg_ctl.c:288 +#: pg_ctl.c:291 #, c-format msgid "%s: could not open PID file \"%s\": %s\n" msgstr "%s: 无法打开 PID 文件 \"%s\": %s\n" -#: pg_ctl.c:297 +#: pg_ctl.c:300 #, c-format msgid "%s: the PID file \"%s\" is empty\n" msgstr "%s: PID 文件 \"%s\" 为空\n" -#: pg_ctl.c:300 +#: pg_ctl.c:303 #, c-format msgid "%s: invalid data in PID file \"%s\"\n" msgstr "%s: PID文件 \"%s\" 中存在无效数æ®\n" -#: pg_ctl.c:450 pg_ctl.c:478 +#: pg_ctl.c:464 pg_ctl.c:506 #, c-format -#| msgid "could not start server\n" msgid "%s: could not start server: %s\n" msgstr "%s: 无法å¯åЍæœåŠ¡å™¨ï¼š%s\n" -#: pg_ctl.c:502 +#: pg_ctl.c:484 +#, fuzzy, c-format +#| msgid "%s: could not start server: %s\n" +msgid "%s: could not start server due to setsid() failure: %s\n" +msgstr "%s: 无法å¯åЍæœåŠ¡å™¨ï¼š%s\n" + +#: pg_ctl.c:530 #, c-format -#| msgid "%s: could not start service \"%s\": error code %lu\n" msgid "%s: could not start server: error code %lu\n" msgstr "%s:无法å¯åЍæœåŠ¡å™¨ï¼šé”™è¯¯ä»£ç %lu\n" -#: pg_ctl.c:579 -#, c-format -msgid "" -"\n" -"%s: -w option is not supported when starting a pre-9.1 server\n" -msgstr "" -"\n" -"%s: -w 选项ä¸èƒ½ç”¨äºŽ9.1以å‰ç‰ˆæœ¬çš„æœåŠ¡å™¨å¯åЍ\n" - -#: pg_ctl.c:644 -#, c-format -msgid "" -"\n" -"%s: -w option cannot use a relative socket directory specification\n" -msgstr "" -"\n" -"%s: -w 选项ä¸èƒ½ç”¨äºŽç›¸å¯¹å¥—接字目录\n" - -#: pg_ctl.c:746 +#: pg_ctl.c:677 #, c-format msgid "%s: cannot set core file size limit; disallowed by hard limit\n" msgstr "%s: ä¸èƒ½è®¾ç½®æ ¸å¿ƒæ–‡ä»¶å¤§å°çš„é™åˆ¶;ç£ç›˜é™é¢ä¸å…许\n" -#: pg_ctl.c:771 +#: pg_ctl.c:703 #, c-format msgid "%s: could not read file \"%s\"\n" msgstr "%s: æ— æ³•è¯»å–æ–‡ä»¶ \"%s\"\n" -#: pg_ctl.c:776 +#: pg_ctl.c:708 #, c-format msgid "%s: option file \"%s\" must have exactly one line\n" msgstr "%s: 选项文件 \"%s\" åªèƒ½æœ‰ä¸€è¡Œ\n" -#: pg_ctl.c:827 +#: pg_ctl.c:750 pg_ctl.c:941 pg_ctl.c:1037 +#, c-format +msgid "%s: could not send stop signal (PID: %ld): %s\n" +msgstr "%s: 无法å‘é€åœæ­¢ä¿¡å· (PID: %ld): %s\n" + +#: pg_ctl.c:778 #, c-format msgid "" "The program \"%s\" is needed by %s but was not found in the\n" @@ -192,7 +185,7 @@ msgstr "" "\n" "请检查您的安装.\n" -#: pg_ctl.c:833 +#: pg_ctl.c:784 #, c-format msgid "" "The program \"%s\" was found by \"%s\"\n" @@ -203,37 +196,38 @@ msgstr "" "\n" "检查您的安装.\n" -#: pg_ctl.c:866 +#: pg_ctl.c:817 #, c-format msgid "%s: database system initialization failed\n" msgstr "%s: æ•°æ®åº“系统åˆå§‹åŒ–失败\n" -#: pg_ctl.c:881 +#: pg_ctl.c:832 #, c-format msgid "%s: another server might be running; trying to start server anyway\n" msgstr "%s: å…¶ä»–æœåŠ¡å™¨è¿›ç¨‹å¯èƒ½æ­£åœ¨è¿è¡Œ; å°è¯•å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" -#: pg_ctl.c:919 +#: pg_ctl.c:881 msgid "waiting for server to start..." msgstr "等待æœåŠ¡å™¨è¿›ç¨‹å¯åЍ ..." -#: pg_ctl.c:924 pg_ctl.c:1031 pg_ctl.c:1122 +#: pg_ctl.c:886 pg_ctl.c:991 pg_ctl.c:1083 pg_ctl.c:1213 msgid " done\n" msgstr " 完æˆ\n" -#: pg_ctl.c:925 +#: pg_ctl.c:887 msgid "server started\n" msgstr "æœåŠ¡å™¨è¿›ç¨‹å·²ç»å¯åЍ\n" -#: pg_ctl.c:928 pg_ctl.c:932 +#: pg_ctl.c:890 pg_ctl.c:896 pg_ctl.c:1218 msgid " stopped waiting\n" msgstr " å·²åœæ­¢ç­‰å¾…\n" -#: pg_ctl.c:929 -msgid "server is still starting up\n" -msgstr "æœåС噍ä»åœ¨å¯åŠ¨è¿‡ç¨‹ä¸­\n" +#: pg_ctl.c:891 +#, c-format +msgid "%s: server did not start in time\n" +msgstr "%s: æœåŠ¡æ²¡æœ‰åŠæ—¶å¯åЍ\n" -#: pg_ctl.c:933 +#: pg_ctl.c:897 #, c-format msgid "" "%s: could not start server\n" @@ -242,43 +236,29 @@ msgstr "" "%s: 无法å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" "检查日志输出.\n" -#: pg_ctl.c:939 pg_ctl.c:1023 pg_ctl.c:1113 -msgid " failed\n" -msgstr " 失败\n" - -#: pg_ctl.c:940 -#, c-format -msgid "%s: could not wait for server because of misconfiguration\n" -msgstr "%s: 因为é…制错误,而无法等待æœåС噍\n" - -#: pg_ctl.c:946 +#: pg_ctl.c:905 msgid "server starting\n" msgstr "正在å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" -#: pg_ctl.c:967 pg_ctl.c:1053 pg_ctl.c:1143 pg_ctl.c:1183 +#: pg_ctl.c:926 pg_ctl.c:1013 pg_ctl.c:1104 pg_ctl.c:1143 pg_ctl.c:1242 #, c-format msgid "%s: PID file \"%s\" does not exist\n" msgstr "%s: PID 文件 \"%s\" ä¸å­˜åœ¨\n" -#: pg_ctl.c:968 pg_ctl.c:1055 pg_ctl.c:1144 pg_ctl.c:1184 +#: pg_ctl.c:927 pg_ctl.c:1015 pg_ctl.c:1105 pg_ctl.c:1144 pg_ctl.c:1243 msgid "Is server running?\n" msgstr "æœåŠ¡å™¨è¿›ç¨‹æ˜¯å¦æ­£åœ¨è¿è¡Œ?\n" -#: pg_ctl.c:974 +#: pg_ctl.c:933 #, c-format msgid "%s: cannot stop server; single-user server is running (PID: %ld)\n" msgstr "%s: æ— æ³•åœæ­¢æœåŠ¡å™¨è¿›ç¨‹; 正在è¿è¡Œ å•ç”¨æˆ·æ¨¡å¼æœåŠ¡å™¨è¿›ç¨‹(PID: %ld)\n" -#: pg_ctl.c:982 pg_ctl.c:1077 -#, c-format -msgid "%s: could not send stop signal (PID: %ld): %s\n" -msgstr "%s: 无法å‘é€åœæ­¢ä¿¡å· (PID: %ld): %s\n" - -#: pg_ctl.c:989 +#: pg_ctl.c:948 msgid "server shutting down\n" msgstr "正在关闭æœåŠ¡å™¨è¿›ç¨‹\n" -#: pg_ctl.c:1004 pg_ctl.c:1092 +#: pg_ctl.c:963 pg_ctl.c:1052 msgid "" "WARNING: online backup mode is active\n" "Shutdown will not complete until pg_stop_backup() is called.\n" @@ -287,16 +267,20 @@ msgstr "" "警告: 在线备份模å¼å¤„于激活状æ€\n" "关闭命令将ä¸ä¼šå®Œæˆï¼Œç›´åˆ°è°ƒç”¨äº†pg_stop_backup().\n" -#: pg_ctl.c:1008 pg_ctl.c:1096 +#: pg_ctl.c:967 pg_ctl.c:1056 msgid "waiting for server to shut down..." msgstr "等待æœåŠ¡å™¨è¿›ç¨‹å…³é—­ ..." -#: pg_ctl.c:1025 pg_ctl.c:1115 +#: pg_ctl.c:983 pg_ctl.c:1074 +msgid " failed\n" +msgstr " 失败\n" + +#: pg_ctl.c:985 pg_ctl.c:1076 #, c-format msgid "%s: server does not shut down\n" msgstr "%s: server进程没有关闭\n" -#: pg_ctl.c:1027 pg_ctl.c:1117 +#: pg_ctl.c:987 pg_ctl.c:1078 msgid "" "HINT: The \"-m fast\" option immediately disconnects sessions rather than\n" "waiting for session-initiated disconnection.\n" @@ -304,186 +288,252 @@ msgstr "" "æç¤º: \"-m fast\" 选项å¯ä»¥ç«‹å³æ–­å¼€ä¼šè¯, 而ä¸ç”¨\n" "等待会è¯å‘起的断连.\n" -#: pg_ctl.c:1033 pg_ctl.c:1123 +#: pg_ctl.c:993 pg_ctl.c:1084 msgid "server stopped\n" msgstr "æœåŠ¡å™¨è¿›ç¨‹å·²ç»å…³é—­\n" -#: pg_ctl.c:1056 pg_ctl.c:1129 -msgid "starting server anyway\n" -msgstr "正在å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" +#: pg_ctl.c:1016 +msgid "trying to start server anyway\n" +msgstr "å°è¯•å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" -#: pg_ctl.c:1065 +#: pg_ctl.c:1025 #, c-format msgid "%s: cannot restart server; single-user server is running (PID: %ld)\n" msgstr "%s: 无法é‡å¯æœåŠ¡å™¨è¿›ç¨‹; å•ç”¨æˆ·æ¨¡å¼æœåŠ¡å™¨è¿›ç¨‹æ­£åœ¨è¿è¡Œ (PID: %ld)\n" -#: pg_ctl.c:1068 pg_ctl.c:1153 +#: pg_ctl.c:1028 pg_ctl.c:1114 msgid "Please terminate the single-user server and try again.\n" msgstr "请终止å•ç”¨æˆ·æ¨¡å¼æœåŠ¡å™¨è¿›ç¨‹ï¼Œç„¶åŽå†é‡è¯•.\n" -#: pg_ctl.c:1127 +#: pg_ctl.c:1088 #, c-format msgid "%s: old server process (PID: %ld) seems to be gone\n" msgstr "%s: 原有的进程(PID: %ld)å¯èƒ½å·²ç»ä¸å­˜åœ¨äº†\n" -#: pg_ctl.c:1150 +#: pg_ctl.c:1090 +msgid "starting server anyway\n" +msgstr "正在å¯åЍæœåŠ¡å™¨è¿›ç¨‹\n" + +#: pg_ctl.c:1111 #, c-format msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" -msgstr "" -"%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æ­£åœ¨è¿è¡Œå•用户模å¼çš„æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" +msgstr "%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æ­£åœ¨è¿è¡Œå•用户模å¼çš„æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" -#: pg_ctl.c:1159 +#: pg_ctl.c:1120 #, c-format msgid "%s: could not send reload signal (PID: %ld): %s\n" msgstr "%s: 无法å‘é€é‡è½½ä¿¡å· (PID: %ld): %s\n" -#: pg_ctl.c:1164 +#: pg_ctl.c:1125 msgid "server signaled\n" msgstr "æœåŠ¡å™¨è¿›ç¨‹å‘出信å·\n" -#: pg_ctl.c:1190 +#: pg_ctl.c:1150 #, c-format msgid "%s: cannot promote server; single-user server is running (PID: %ld)\n" -msgstr "" -"%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æ­£åœ¨è¿è¡Œå•用户模å¼çš„æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" +msgstr "%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æ­£åœ¨è¿è¡Œå•用户模å¼çš„æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" -#: pg_ctl.c:1199 +#: pg_ctl.c:1158 #, c-format msgid "%s: cannot promote server; server is not in standby mode\n" msgstr "%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æœåŠ¡å™¨æ²¡æœ‰è¿è¡Œåœ¨standby模å¼ä¸‹\n" -#: pg_ctl.c:1214 +#: pg_ctl.c:1173 #, c-format msgid "%s: could not create promote signal file \"%s\": %s\n" msgstr "%s: æ— æ³•åˆ›å»ºé‡æ–°åŠ è½½ä¿¡å·æ–‡ä»¶ \"%s\": %s\n" -#: pg_ctl.c:1220 +#: pg_ctl.c:1179 #, c-format msgid "%s: could not write promote signal file \"%s\": %s\n" msgstr "%s: æ— æ³•å†™å…¥é‡æ–°åŠ è½½æ–‡ä»¶ \"%s\": %s\n" -#: pg_ctl.c:1228 +#: pg_ctl.c:1187 #, c-format msgid "%s: could not send promote signal (PID: %ld): %s\n" msgstr "%s: 无法å‘é€é‡è½½ä¿¡å·(PID: %ld): %s\n" -#: pg_ctl.c:1231 +#: pg_ctl.c:1190 #, c-format msgid "%s: could not remove promote signal file \"%s\": %s\n" msgstr "%s: æ— æ³•ç§»åŠ¨é‡æ–°åŠ è½½ä¿¡å·æ–‡ä»¶ \"%s\": %s\n" -#: pg_ctl.c:1236 +#: pg_ctl.c:1200 +msgid "waiting for server to promote..." +msgstr "等待æœåŠ¡å™¨è¿›ç¨‹åŠ è½½ ..." + +#: pg_ctl.c:1214 +msgid "server promoted\n" +msgstr "æœåŠ¡å™¨åŠ è½½å®Œæ¯•\n" + +#: pg_ctl.c:1219 +#, c-format +msgid "%s: server did not promote in time\n" +msgstr "%s: æœåŠ¡è¿›ç¨‹æ²¡æœ‰åŠæ—¶åŠ è½½\n" + +#: pg_ctl.c:1225 msgid "server promoting\n" msgstr "æœåС噍釿–°åŠ è½½ä¸­\n" -#: pg_ctl.c:1283 +#: pg_ctl.c:1249 +#, fuzzy, c-format +#| msgid "%s: cannot reload server; single-user server is running (PID: %ld)\n" +msgid "%s: cannot rotate log file; single-user server is running (PID: %ld)\n" +msgstr "%s: æ— æ³•é‡æ–°åŠ è½½æœåŠ¡å™¨è¿›ç¨‹ï¼›æ­£åœ¨è¿è¡Œå•用户模å¼çš„æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" + +#: pg_ctl.c:1259 +#, fuzzy, c-format +#| msgid "%s: could not create promote signal file \"%s\": %s\n" +msgid "%s: could not create log rotation signal file \"%s\": %s\n" +msgstr "%s: æ— æ³•åˆ›å»ºé‡æ–°åŠ è½½ä¿¡å·æ–‡ä»¶ \"%s\": %s\n" + +#: pg_ctl.c:1265 +#, fuzzy, c-format +#| msgid "%s: could not write promote signal file \"%s\": %s\n" +msgid "%s: could not write log rotation signal file \"%s\": %s\n" +msgstr "%s: æ— æ³•å†™å…¥é‡æ–°åŠ è½½æ–‡ä»¶ \"%s\": %s\n" + +#: pg_ctl.c:1273 +#, fuzzy, c-format +#| msgid "%s: could not send reload signal (PID: %ld): %s\n" +msgid "%s: could not send log rotation signal (PID: %ld): %s\n" +msgstr "%s: 无法å‘é€é‡è½½ä¿¡å· (PID: %ld): %s\n" + +#: pg_ctl.c:1276 +#, fuzzy, c-format +#| msgid "%s: could not remove promote signal file \"%s\": %s\n" +msgid "%s: could not remove log rotation signal file \"%s\": %s\n" +msgstr "%s: æ— æ³•ç§»åŠ¨é‡æ–°åŠ è½½ä¿¡å·æ–‡ä»¶ \"%s\": %s\n" + +#: pg_ctl.c:1281 +#, fuzzy +#| msgid "server signaled\n" +msgid "server signaled to rotate log file\n" +msgstr "æœåŠ¡å™¨è¿›ç¨‹å‘出信å·\n" + +#: pg_ctl.c:1328 #, c-format msgid "%s: single-user server is running (PID: %ld)\n" msgstr "%s: 正在è¿è¡Œå•ç”¨æˆ·æ¨¡å¼æœåŠ¡å™¨è¿›ç¨‹ (PID: %ld)\n" -#: pg_ctl.c:1296 +#: pg_ctl.c:1342 #, c-format msgid "%s: server is running (PID: %ld)\n" msgstr "%s: 正在è¿è¡ŒæœåŠ¡å™¨è¿›ç¨‹(PID: %ld)\n" -#: pg_ctl.c:1312 +#: pg_ctl.c:1358 #, c-format msgid "%s: no server running\n" msgstr "%s:没有æœåŠ¡å™¨è¿›ç¨‹æ­£åœ¨è¿è¡Œ\n" -#: pg_ctl.c:1330 +#: pg_ctl.c:1375 #, c-format msgid "%s: could not send signal %d (PID: %ld): %s\n" msgstr "%s: 无法å‘é€ä¿¡å· %d (PID: %ld): %s\n" -#: pg_ctl.c:1387 +#: pg_ctl.c:1432 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: 无法找到执行文件\n" -#: pg_ctl.c:1397 +#: pg_ctl.c:1442 #, c-format msgid "%s: could not find postgres program executable\n" msgstr "%s: 无法找到postgres程åºçš„æ‰§è¡Œæ–‡ä»¶\n" -#: pg_ctl.c:1480 pg_ctl.c:1514 +#: pg_ctl.c:1512 pg_ctl.c:1546 #, c-format msgid "%s: could not open service manager\n" msgstr "%s: 无法打开æœåŠ¡ç®¡ç†å™¨\n" -#: pg_ctl.c:1486 +#: pg_ctl.c:1518 #, c-format msgid "%s: service \"%s\" already registered\n" msgstr "%s: æœåŠ¡ \"%s\" å·²ç»æ³¨å†Œäº†\n" -#: pg_ctl.c:1497 +#: pg_ctl.c:1529 #, c-format msgid "%s: could not register service \"%s\": error code %lu\n" msgstr "%s: 无法注册æœåŠ¡ \"%s\": é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1520 +#: pg_ctl.c:1552 #, c-format msgid "%s: service \"%s\" not registered\n" msgstr "%s: æœåŠ¡ \"%s\" 没有注册\n" -#: pg_ctl.c:1527 +#: pg_ctl.c:1559 #, c-format msgid "%s: could not open service \"%s\": error code %lu\n" msgstr "%s: 无法打开æœåŠ¡ \"%s\": é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1536 +#: pg_ctl.c:1568 #, c-format msgid "%s: could not unregister service \"%s\": error code %lu\n" msgstr "%s: 无法注销æœåŠ¡ \"%s\": é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1623 +#: pg_ctl.c:1655 msgid "Waiting for server startup...\n" msgstr "等待æœåŠ¡å™¨è¿›ç¨‹å¯åЍ ...\n" -#: pg_ctl.c:1626 +#: pg_ctl.c:1658 msgid "Timed out waiting for server startup\n" msgstr "在等待æœåС噍å¯åŠ¨æ—¶è¶…æ—¶\n" -#: pg_ctl.c:1630 +#: pg_ctl.c:1662 msgid "Server started and accepting connections\n" msgstr "æœåŠ¡å™¨è¿›ç¨‹å·²å¯åŠ¨å¹¶ä¸”æŽ¥å—连接\n" -#: pg_ctl.c:1685 +#: pg_ctl.c:1717 #, c-format msgid "%s: could not start service \"%s\": error code %lu\n" msgstr "%s: 无法å¯åЍæœåŠ¡ \"%s\": é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1759 +#: pg_ctl.c:1787 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" msgstr "%s: 警告: 该平å°ä¸Šæ— æ³•创建å—é™ä»¤ç‰Œ\n" -#: pg_ctl.c:1774 +#: pg_ctl.c:1800 #, c-format msgid "%s: could not open process token: error code %lu\n" msgstr "%s: 无法打开进程令牌 (token): é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1788 +#: pg_ctl.c:1814 #, c-format msgid "%s: could not allocate SIDs: error code %lu\n" msgstr "%s: 无法分é…SID: é”™è¯¯ç  %lu\n" -#: pg_ctl.c:1808 +#: pg_ctl.c:1841 #, c-format msgid "%s: could not create restricted token: error code %lu\n" msgstr "%s: 无法创建继承套接字: 错误ç ä¸º %lu\n" -#: pg_ctl.c:1842 +#: pg_ctl.c:1872 #, c-format msgid "%s: WARNING: could not locate all job object functions in system API\n" msgstr "%s: 警告: 系统APIä¸­æ— æ³•å®šä½æ‰€æœ‰å·¥ä½œå¯¹è±¡å‡½æ•°\n" -#: pg_ctl.c:1925 +#: pg_ctl.c:1969 +#, c-format +msgid "%s: could not get LUIDs for privileges: error code %lu\n" +msgstr "%s: 由于æƒé™æ— æ³•获å–LUID: é”™è¯¯ç  %lu\n" + +#: pg_ctl.c:1977 pg_ctl.c:1992 +#, c-format +msgid "%s: could not get token information: error code %lu\n" +msgstr "%s: 无法获得令牌信æ¯: é”™è¯¯ç  %lu\n" + +#: pg_ctl.c:1986 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: 内存溢出\n" + +#: pg_ctl.c:2016 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "试用 \"%s --help\" èŽ·å–æ›´å¤šçš„ä¿¡æ¯.\n" -#: pg_ctl.c:1933 +#: pg_ctl.c:2024 #, c-format msgid "" "%s is a utility to initialize, start, stop, or control a PostgreSQL server.\n" @@ -492,73 +542,95 @@ msgstr "" "%s 是一个用于åˆå§‹åŒ–ã€å¯åЍã€åœæ­¢æˆ–控制PostgreSQLæœåŠ¡å™¨çš„å·¥å…·.\n" "\n" -#: pg_ctl.c:1934 +#: pg_ctl.c:2025 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" -#: pg_ctl.c:1935 -#, c-format -msgid " %s init[db] [-D DATADIR] [-s] [-o \"OPTIONS\"]\n" -msgstr " %s init[db] [-D æ•°æ®ç›®å½•] [-s] [-o \"选项\"]\n" - -#: pg_ctl.c:1936 -#, c-format +#: pg_ctl.c:2026 +#, fuzzy, c-format +#| msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgid " %s init[db] [-D DATADIR] [-s] [-o OPTIONS]\n" +msgstr " %s init[db] [-D æ•°æ®ç›®å½•] [-s] [-o 选项]\n" + +#: pg_ctl.c:2027 +#, fuzzy, c-format +#| msgid "" +#| " %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +#| " [-o OPTIONS] [-p PATH] [-c]\n" msgid "" -" %s start [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS" -"\"]\n" +" %s start [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-p PATH] [-c]\n" msgstr "" -" %s start [-w] [-t ç§’æ•°] [-D æ•°æ®ç›®å½•] [-s] [-l 文件å] [-o \"选项\"]\n" - -#: pg_ctl.c:1937 -#, c-format -msgid " %s stop [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -msgstr " %s stop [-W] [-t ç§’æ•°] [-D æ•°æ®ç›®å½•] [-s] [-m 关闭模å¼]\n" - -#: pg_ctl.c:1938 -#, c-format +" %s start [-D æ•°æ®ç›®å½•] [-l 文件å] [-W] [-t ç§’æ•°] [-s]\n" +" [-o 选项] [-p 路径] [-c]\n" + +#: pg_ctl.c:2029 +#, fuzzy, c-format +#| msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgid " %s stop [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +msgstr " %s stop [-D æ•°æ®ç›®å½•] [-m æ•°æ®ç›®å½•] [-W] [-t ç§’æ•°] [-s]\n" + +#: pg_ctl.c:2030 +#, fuzzy, c-format +#| msgid "" +#| " %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +#| " [-o OPTIONS] [-c]\n" msgid "" -" %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n" -" [-o \"OPTIONS\"]\n" +" %s restart [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]\n" +" [-o OPTIONS] [-c]\n" msgstr "" -" %s restart [-w] [-t ç§’æ•°] [-D æ•°æ®ç›®å½•] [-s] [-m 关闭模å¼]\n" -" [-o \"选项\"]\n" - -#: pg_ctl.c:1940 -#, c-format -msgid " %s reload [-D DATADIR] [-s]\n" -msgstr " %s reload [-D æ•°æ®ç›®å½•] [-s]\n" - -#: pg_ctl.c:1941 -#, c-format -msgid " %s status [-D DATADIR]\n" -msgstr " %s status [-D æ•°æ®ç›®å½•]\n" - -#: pg_ctl.c:1942 -#, c-format -msgid " %s promote [-D DATADIR] [-s]\n" -msgstr " %s promote [-D æ•°æ®ç›®å½•] [-s]\n" - -#: pg_ctl.c:1943 -#, c-format -msgid " %s kill SIGNALNAME PID\n" -msgstr " %s kill ä¿¡å·åç§° 进程å·\n" - -#: pg_ctl.c:1945 -#, c-format +" %s restart [-D æ•°æ®ç›®å½•] [-m æ•°æ®ç›®å½•] [-W] [-t ç§’æ•°] [-s]\n" +" [-o 选项] [-c]\n" + +#: pg_ctl.c:2032 +#, fuzzy, c-format +#| msgid " %s reload [-D DATADIR] [-s]\n" +msgid " %s reload [-D DATADIR] [-s]\n" +msgstr " %s reload [-D æ•°æ®ç›®å½•] [-s]\n" + +#: pg_ctl.c:2033 +#, fuzzy, c-format +#| msgid " %s status [-D DATADIR]\n" +msgid " %s status [-D DATADIR]\n" +msgstr " %s status [-D æ•°æ®ç›®å½•]\n" + +#: pg_ctl.c:2034 +#, fuzzy, c-format +#| msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgid " %s promote [-D DATADIR] [-W] [-t SECS] [-s]\n" +msgstr " %s promote [-D æ•°æ®ç›®å½•] [-W] [-t ç§’æ•°] [-s]\n" + +#: pg_ctl.c:2035 +#, fuzzy, c-format +#| msgid " %s reload [-D DATADIR] [-s]\n" +msgid " %s logrotate [-D DATADIR] [-s]\n" +msgstr " %s reload [-D æ•°æ®ç›®å½•] [-s]\n" + +#: pg_ctl.c:2036 +#, fuzzy, c-format +#| msgid " %s kill SIGNALNAME PID\n" +msgid " %s kill SIGNALNAME PID\n" +msgstr " %s kill ä¿¡å·åç§° 进程å·\n" + +#: pg_ctl.c:2038 +#, fuzzy, c-format +#| msgid "" +#| " %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +#| " [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgid "" -" %s register [-N SERVICENAME] [-U USERNAME] [-P PASSWORD] [-D DATADIR]\n" -" [-S START-TYPE] [-w] [-t SECS] [-o \"OPTIONS\"]\n" +" %s register [-D DATADIR] [-N SERVICENAME] [-U USERNAME] [-P PASSWORD]\n" +" [-S START-TYPE] [-e SOURCE] [-W] [-t SECS] [-s] [-o OPTIONS]\n" msgstr "" -" %s register [-N æœåŠ¡åç§°] [-U 用户å] [-P å£ä»¤] [-D æ•°æ®ç›®å½•]\n" -" [-S å¯åŠ¨ç±»åž‹] [-w] [-t ç§’æ•°] [-o \"选项\"]\n" +" %s register [-D æ•°æ®ç›®å½•] [-N æœåŠ¡åç§°] [-U 用户å] [-P å£ä»¤]\n" +" [-S å¯åŠ¨ç±»åž‹] [-e æº] [-W] [-t ç§’æ•°] [-s] [-o 选项]\n" -#: pg_ctl.c:1947 +#: pg_ctl.c:2040 #, c-format msgid " %s unregister [-N SERVICENAME]\n" msgstr " %s unregister [-N æœåŠ¡åç§°]\n" -#: pg_ctl.c:1950 +#: pg_ctl.c:2043 #, c-format msgid "" "\n" @@ -567,62 +639,52 @@ msgstr "" "\n" "普通选项:\n" -#: pg_ctl.c:1951 +#: pg_ctl.c:2044 #, c-format msgid " -D, --pgdata=DATADIR location of the database storage area\n" msgstr " -D, --pgdata=æ•°æ®ç›®å½• æ•°æ®åº“存储区域的ä½ç½®\n" -#: pg_ctl.c:1953 +#: pg_ctl.c:2046 #, c-format -msgid "" -" -e SOURCE event source for logging when running as a service\n" +msgid " -e SOURCE event source for logging when running as a service\n" msgstr " -e SOURCE 当作为一个æœåŠ¡è¿è¡Œæ—¶è¦è®°å½•çš„äº‹ä»¶çš„æ¥æº\n" -#: pg_ctl.c:1955 +#: pg_ctl.c:2048 #, c-format msgid " -s, --silent only print errors, no informational messages\n" msgstr " -s, --silent åªæ‰“å°é”™è¯¯ä¿¡æ¯, 没有其他信æ¯\n" -#: pg_ctl.c:1956 +#: pg_ctl.c:2049 #, c-format msgid " -t, --timeout=SECS seconds to wait when using -w option\n" msgstr " -t, --timeout=SECS 当使用-w 选项时需è¦ç­‰å¾…的秒数\n" -#: pg_ctl.c:1957 +#: pg_ctl.c:2050 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 输出版本信æ¯, ç„¶åŽé€€å‡º\n" -#: pg_ctl.c:1958 +#: pg_ctl.c:2051 #, c-format -msgid " -w wait until operation completes\n" -msgstr " -w 等待直到æ“作完æˆ\n" +msgid " -w, --wait wait until operation completes (default)\n" +msgstr " -w, --wait 等待直到æ“作完æˆ(默认)\n" -#: pg_ctl.c:1959 +#: pg_ctl.c:2052 #, c-format -msgid " -W do not wait until operation completes\n" -msgstr " -W ä¸ç”¨ç­‰å¾…æ“作完æˆ\n" +msgid " -W, --no-wait do not wait until operation completes\n" +msgstr " -W, --no-wait ä¸ç”¨ç­‰å¾…æ“作完æˆ\n" -#: pg_ctl.c:1960 +#: pg_ctl.c:2053 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help 显示此帮助, ç„¶åŽé€€å‡º\n" -#: pg_ctl.c:1961 -#, c-format -msgid "" -"(The default is to wait for shutdown, but not for start or restart.)\n" -"\n" -msgstr "" -"(默认为关闭等待, 但䏿˜¯å¯åŠ¨æˆ–é‡å¯.)\n" -"\n" - -#: pg_ctl.c:1962 +#: pg_ctl.c:2054 #, c-format msgid "If the -D option is omitted, the environment variable PGDATA is used.\n" msgstr "如果çœç•¥äº† -D 选项, 将使用 PGDATA 环境å˜é‡.\n" -#: pg_ctl.c:1964 +#: pg_ctl.c:2056 #, c-format msgid "" "\n" @@ -631,36 +693,36 @@ msgstr "" "\n" "å¯åŠ¨æˆ–é‡å¯çš„选项:\n" -#: pg_ctl.c:1966 +#: pg_ctl.c:2058 #, c-format msgid " -c, --core-files allow postgres to produce core files\n" msgstr " -c, --core-files å…许postgres进程产生核心文件\n" -#: pg_ctl.c:1968 +#: pg_ctl.c:2060 #, c-format msgid " -c, --core-files not applicable on this platform\n" msgstr " -c, --core-files 在这ç§å¹³å°ä¸Šä¸å¯ç”¨\n" -#: pg_ctl.c:1970 +#: pg_ctl.c:2062 #, c-format msgid " -l, --log=FILENAME write (or append) server log to FILENAME\n" msgstr " -l, --log=FILENAME 写入 (或追加) æœåŠ¡å™¨æ—¥å¿—åˆ°æ–‡ä»¶FILENAME\n" -#: pg_ctl.c:1971 +#: pg_ctl.c:2063 #, c-format msgid "" -" -o OPTIONS command line options to pass to postgres\n" +" -o, --options=OPTIONS command line options to pass to postgres\n" " (PostgreSQL server executable) or initdb\n" msgstr "" -" -o OPTIONS 传递给postgres的命令行选项\n" -" (PostgreSQL æœåŠ¡å™¨æ‰§è¡Œæ–‡ä»¶)或initdb\n" +" -o, --options=OPTIONS 传递给postgres的命令行选项\n" +" (PostgreSQL æœåŠ¡å™¨æ‰§è¡Œæ–‡ä»¶)或initdb\n" -#: pg_ctl.c:1973 +#: pg_ctl.c:2065 #, c-format msgid " -p PATH-TO-POSTGRES normally not necessary\n" msgstr " -p PATH-TO-POSTMASTER 正常情况ä¸å¿…è¦\n" -#: pg_ctl.c:1974 +#: pg_ctl.c:2066 #, c-format msgid "" "\n" @@ -669,14 +731,12 @@ msgstr "" "\n" "åœæ­¢æˆ–é‡å¯çš„选项:\n" -#: pg_ctl.c:1975 +#: pg_ctl.c:2067 #, c-format -msgid "" -" -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" -msgstr "" -" -m, --mode=MODE å¯ä»¥æ˜¯ \"smart\", \"fast\", 或者 \"immediate\"\n" +msgid " -m, --mode=MODE MODE can be \"smart\", \"fast\", or \"immediate\"\n" +msgstr " -m, --mode=MODE å¯ä»¥æ˜¯ \"smart\", \"fast\", 或者 \"immediate\"\n" -#: pg_ctl.c:1977 +#: pg_ctl.c:2069 #, c-format msgid "" "\n" @@ -685,24 +745,22 @@ msgstr "" "\n" "å…³é—­æ¨¡å¼æœ‰å¦‚下几ç§:\n" -#: pg_ctl.c:1978 +#: pg_ctl.c:2070 #, c-format msgid " smart quit after all clients have disconnected\n" msgstr " smart 所有客户端断开连接åŽé€€å‡º\n" -#: pg_ctl.c:1979 +#: pg_ctl.c:2071 #, c-format -msgid " fast quit directly, with proper shutdown\n" -msgstr " fast 直接退出, 正确的关闭\n" +msgid " fast quit directly, with proper shutdown (default)\n" +msgstr " fast 直接退出, 正确的关闭(默认)\n" -#: pg_ctl.c:1980 +#: pg_ctl.c:2072 #, c-format -msgid "" -" immediate quit without complete shutdown; will lead to recovery on " -"restart\n" +msgid " immediate quit without complete shutdown; will lead to recovery on restart\n" msgstr " immediate ä¸å®Œå…¨çš„关闭退出; é‡å¯åŽæ¢å¤\n" -#: pg_ctl.c:1982 +#: pg_ctl.c:2074 #, c-format msgid "" "\n" @@ -711,7 +769,7 @@ msgstr "" "\n" "å…许关闭的信å·åç§°:\n" -#: pg_ctl.c:1986 +#: pg_ctl.c:2078 #, c-format msgid "" "\n" @@ -720,28 +778,27 @@ msgstr "" "\n" "注册或注销的选项:\n" -#: pg_ctl.c:1987 +#: pg_ctl.c:2079 #, c-format -msgid "" -" -N SERVICENAME service name with which to register PostgreSQL server\n" +msgid " -N SERVICENAME service name with which to register PostgreSQL server\n" msgstr " -N æœåŠ¡åç§° 注册到 PostgreSQL æœåŠ¡å™¨çš„æœåŠ¡åç§°\n" -#: pg_ctl.c:1988 +#: pg_ctl.c:2080 #, c-format msgid " -P PASSWORD password of account to register PostgreSQL server\n" msgstr " -P å£ä»¤ 注册到 PostgreSQL æœåС噍叿ˆ·çš„å£ä»¤\n" -#: pg_ctl.c:1989 +#: pg_ctl.c:2081 #, c-format msgid " -U USERNAME user name of account to register PostgreSQL server\n" msgstr " -U ç”¨æˆ·å æ³¨å†Œåˆ° PostgreSQL æœåС噍叿ˆ·çš„用户å\n" -#: pg_ctl.c:1990 +#: pg_ctl.c:2082 #, c-format msgid " -S START-TYPE service start type to register PostgreSQL server\n" msgstr " -S START-TYPE 注册到PostgreSQLæœåŠ¡å™¨çš„æœåŠ¡å¯åŠ¨ç±»åž‹\n" -#: pg_ctl.c:1992 +#: pg_ctl.c:2084 #, c-format msgid "" "\n" @@ -750,47 +807,54 @@ msgstr "" "\n" "å¯åŠ¨ç±»åž‹æœ‰:\n" -#: pg_ctl.c:1993 +#: pg_ctl.c:2085 #, c-format -msgid "" -" auto start service automatically during system startup (default)\n" +msgid " auto start service automatically during system startup (default)\n" msgstr " auto 在系统å¯åŠ¨æ—¶è‡ªåŠ¨å¯åЍæœåŠ¡(默认选项)\n" -#: pg_ctl.c:1994 +#: pg_ctl.c:2086 #, c-format msgid " demand start service on demand\n" msgstr " demand 按需å¯åЍæœåŠ¡\n" -#: pg_ctl.c:1997 -#, c-format +#: pg_ctl.c:2089 +#, fuzzy, c-format +#| msgid "" +#| "\n" +#| "Report bugs to .\n" msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" "臭虫报告至 .\n" -#: pg_ctl.c:2022 +#: pg_ctl.c:2114 #, c-format msgid "%s: unrecognized shutdown mode \"%s\"\n" msgstr "%s: æ— æ•ˆçš„å…³é—­æ¨¡å¼ \"%s\"\n" -#: pg_ctl.c:2054 +#: pg_ctl.c:2143 #, c-format msgid "%s: unrecognized signal name \"%s\"\n" msgstr "%s: 无效信å·åç§° \"%s\"\n" -#: pg_ctl.c:2071 +#: pg_ctl.c:2160 #, c-format msgid "%s: unrecognized start type \"%s\"\n" msgstr "%s: 无法识别的å¯åŠ¨ç±»åž‹ \"%s\"\n" -#: pg_ctl.c:2126 +#: pg_ctl.c:2215 #, c-format msgid "%s: could not determine the data directory using command \"%s\"\n" msgstr "%s: 使用命令 \"%s\"无法确定数æ®ç›®å½•\n" -#: pg_ctl.c:2198 +#: pg_ctl.c:2240 +#, c-format +msgid "%s: control file appears to be corrupt\n" +msgstr "%s: 控制文件似乎已æŸå\n" + +#: pg_ctl.c:2308 #, c-format msgid "" "%s: cannot be run as root\n" @@ -801,92 +865,32 @@ msgstr "" "请以æœåŠ¡å™¨è¿›ç¨‹æ‰€å±žç”¨æˆ· (éžç‰¹æƒç”¨æˆ·) 登录 (或使用 \"su\")\n" "\n" -#: pg_ctl.c:2277 +#: pg_ctl.c:2392 #, c-format msgid "%s: -S option not supported on this platform\n" msgstr "%s: -S 选项在该平å°ä¸Šä¸æ”¯æŒ\n" -#: pg_ctl.c:2315 +#: pg_ctl.c:2429 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: å‘½ä»¤è¡Œå‚æ•°å¤ªå¤š (第一个是 \"%s\")\n" -#: pg_ctl.c:2339 +#: pg_ctl.c:2455 #, c-format msgid "%s: missing arguments for kill mode\n" msgstr "%s: 缺少 kill 模å¼å‚æ•°\n" -#: pg_ctl.c:2357 +#: pg_ctl.c:2473 #, c-format msgid "%s: unrecognized operation mode \"%s\"\n" msgstr "%s: 无效的æ“ä½œæ¨¡å¼ \"%s\"\n" -#: pg_ctl.c:2367 +#: pg_ctl.c:2483 #, c-format msgid "%s: no operation specified\n" msgstr "%s: 没有指定æ“作\n" -#: pg_ctl.c:2388 +#: pg_ctl.c:2504 #, c-format -msgid "" -"%s: no database directory specified and environment variable PGDATA unset\n" +msgid "%s: no database directory specified and environment variable PGDATA unset\n" msgstr "%s: 没有指定数æ®ç›®å½•, 并且没有设置 PGDATA 环境å˜é‡\n" - -#~ msgid "" -#~ "%s is a utility to start, stop, restart, reload configuration files,\n" -#~ "report the status of a PostgreSQL server, or signal a PostgreSQL " -#~ "process.\n" -#~ "\n" -#~ msgstr "" -#~ "%s 是一个å¯åЍ, åœæ­¢, é‡å¯, é‡è½½é…置文件, 报告 PostgreSQL æœåŠ¡å™¨çŠ¶æ€,\n" -#~ "æˆ–è€…æ€æŽ‰ PostgreSQL 进程的工具\n" -#~ "\n" - -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help 显示此帮助信æ¯, ç„¶åŽé€€å‡º\n" - -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version 显示版本信æ¯, ç„¶åŽé€€å‡º\n" - -#~ msgid "" -#~ "The program \"postmaster\" is needed by %s but was not found in the\n" -#~ "same directory as \"%s\".\n" -#~ "Check your installation.\n" -#~ msgstr "" -#~ "ç¨‹åº \"postmaster\" 是 %s 需è¦çš„, 但没有在åŒä¸€ä¸ªç›®å½• \"%s\" å‘现.\n" -#~ "\n" -#~ "检查您的安装.\n" - -#~ msgid "" -#~ "The program \"postmaster\" was found by \"%s\"\n" -#~ "but was not the same version as %s.\n" -#~ "Check your installation.\n" -#~ msgstr "" -#~ "%s æ‰¾åˆ°ç¨‹åº \"postmaster\", 但版本和 \"%s\" ä¸ä¸€è‡´.\n" -#~ "\n" -#~ "检查您的安装.\n" - -#~ msgid "%s: neither postmaster nor postgres running\n" -#~ msgstr "%s: postmaster 或者 postgres 没有è¿è¡Œ\n" - -#~ msgid "%s: a standalone backend \"postgres\" is running (PID: %ld)\n" -#~ msgstr "%s: 一个独立的åŽç«¯ \"postgres\" 正在è¿è¡Œ (PID: %ld)\n" - -#~ msgid "%s: invalid option %s\n" -#~ msgstr "%s: 无效选项 %s\n" - -#~ msgid "%s: out of memory\n" -#~ msgstr "%s: 内存溢出\n" - -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "无法进入目录 \"%s\"" - -#~ msgid "%s: could not start server: exit code was %d\n" -#~ msgstr "%s: 无法å¯åЍæœåŠ¡å™¨è¿›ç¨‹: 退出ç ä¸º %d\n" - -#~ msgid "" -#~ "\n" -#~ "%s: this data directory appears to be running a pre-existing postmaster\n" -#~ msgstr "" -#~ "\n" -#~ "%s: æ•°æ®ç›®å½•里å¯èƒ½æ­£åœ¨è¿è¡Œç€ä¸€ä¸ªå·²ç»å­˜åœ¨çš„postmaster进程\n" diff --git a/src/bin/pg_ctl/t/001_start_stop.pl b/src/bin/pg_ctl/t/001_start_stop.pl index 2f9dfa7b81b..e5d46a6f257 100644 --- a/src/bin/pg_ctl/t/001_start_stop.pl +++ b/src/bin/pg_ctl/t/001_start_stop.pl @@ -24,6 +24,9 @@ 'configure authentication'); open my $conf, '>>', "$tempdir/data/postgresql.conf"; print $conf "fsync = off\n"; +print $conf TestLib::slurp_file($ENV{TEMP_CONFIG}) + if defined $ENV{TEMP_CONFIG}; + if (!$windows_os) { print $conf "listen_addresses = ''\n"; @@ -36,7 +39,8 @@ close $conf; my $ctlcmd = [ 'pg_ctl', 'start', '-D', "$tempdir/data", '-l', - "$TestLib::log_path/001_start_stop_server.log" ]; + "$TestLib::log_path/001_start_stop_server.log" +]; if ($Config{osname} ne 'msys') { command_like($ctlcmd, qr/done.*server started/s, 'pg_ctl start'); @@ -63,14 +67,14 @@ # Windows but we still want to do the restart test. my $logFileName = "$tempdir/data/perm-test-600.log"; -command_ok( - [ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-l', $logFileName ], +command_ok([ 'pg_ctl', 'restart', '-D', "$tempdir/data", '-l', $logFileName ], 'pg_ctl restart with server not running'); # Permissions on log file should be default SKIP: { - skip "unix-style permissions not supported on Windows", 2 if ($windows_os); + skip "unix-style permissions not supported on Windows", 2 + if ($windows_os); ok(-f $logFileName); ok(check_mode_recursive("$tempdir/data", 0700, 0600)); diff --git a/src/bin/pg_ctl/t/004_logrotate.pl b/src/bin/pg_ctl/t/004_logrotate.pl new file mode 100644 index 00000000000..71dbfd20301 --- /dev/null +++ b/src/bin/pg_ctl/t/004_logrotate.pl @@ -0,0 +1,93 @@ +use strict; +use warnings; + +use PostgresNode; +use TestLib; +use Test::More tests => 4; +use Time::HiRes qw(usleep); + +# Set up node with logging collector +my $node = get_new_node('primary'); +$node->init(); +$node->append_conf( + 'postgresql.conf', qq( +logging_collector = on +lc_messages = 'C' +)); + +$node->start(); + +# Verify that log output gets to the file + +$node->psql('postgres', 'SELECT 1/0'); + +my $current_logfiles = slurp_file($node->data_dir . '/current_logfiles'); + +note "current_logfiles = $current_logfiles"; + +like( + $current_logfiles, + qr|^stderr log/postgresql-.*log$|, + 'current_logfiles is sane'); + +my $lfname = $current_logfiles; +$lfname =~ s/^stderr //; +chomp $lfname; + +# might need to retry if logging collector process is slow... +my $max_attempts = 180 * 10; + +my $first_logfile; +for (my $attempts = 0; $attempts < $max_attempts; $attempts++) +{ + $first_logfile = slurp_file($node->data_dir . '/' . $lfname); + last if $first_logfile =~ m/division by zero/; + usleep(100_000); +} + +like($first_logfile, qr/division by zero/, 'found expected log file content'); + +# Sleep 2 seconds and ask for log rotation; this should result in +# output into a different log file name. +sleep(2); +$node->logrotate(); + +# pg_ctl logrotate doesn't wait for rotation request to be completed. +# Allow a bit of time for it to happen. +my $new_current_logfiles; +for (my $attempts = 0; $attempts < $max_attempts; $attempts++) +{ + $new_current_logfiles = slurp_file($node->data_dir . '/current_logfiles'); + last if $new_current_logfiles ne $current_logfiles; + usleep(100_000); +} + +note "now current_logfiles = $new_current_logfiles"; + +like( + $new_current_logfiles, + qr|^stderr log/postgresql-.*log$|, + 'new current_logfiles is sane'); + +$lfname = $new_current_logfiles; +$lfname =~ s/^stderr //; +chomp $lfname; + +# Verify that log output gets to this file, too + +$node->psql('postgres', 'fee fi fo fum'); + +my $second_logfile; +for (my $attempts = 0; $attempts < $max_attempts; $attempts++) +{ + $second_logfile = slurp_file($node->data_dir . '/' . $lfname); + last if $second_logfile =~ m/syntax error/; + usleep(100_000); +} + +like( + $second_logfile, + qr/syntax error/, + 'found expected log file content in new log file'); + +$node->stop(); diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile index c46804ab8b9..d3c1dce178e 100644 --- a/src/bin/pg_dump/Makefile +++ b/src/bin/pg_dump/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_dump # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/pg_dump/Makefile diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index e7db78b0ff1..02a865f456f 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -4,7 +4,7 @@ * Catalog routines used by pg_dump; long ago these were shared * by another dump tool, but not anymore. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -67,18 +67,18 @@ static ExtensionMemberId *extmembers; static int numextmembers; static void flagInhTables(Archive *fout, TableInfo *tbinfo, int numTables, - InhInfo *inhinfo, int numInherits); + InhInfo *inhinfo, int numInherits); static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables); static void flagInhAttrs(DumpOptions *dopt, TableInfo *tblinfo, int numTables); static DumpableObject **buildIndexArray(void *objArray, int numObjs, - Size objSize); + Size objSize); static int DOCatalogIdCompare(const void *p1, const void *p2); static int ExtensionMemberIdCompare(const void *p1, const void *p2); static void findParentsByOid(TableInfo *self, - InhInfo *inhinfo, int numInherits); + InhInfo *inhinfo, int numInherits); static int strInArray(const char *pattern, char **arr, int arr_size); static IndxInfo *findIndexByOid(Oid oid, DumpableObject **idxinfoindex, - int numIndexes); + int numIndexes); /* @@ -120,17 +120,14 @@ getSchemaData(Archive *fout, int *numTablesPtr) * extension membership needs to be consultable during decisions about * whether other objects are to be dumped. */ - if (g_verbose) - write_msg(NULL, "reading extensions\n"); + pg_log_info("reading extensions"); extinfo = getExtensions(fout, &numExtensions); extinfoindex = buildIndexArray(extinfo, numExtensions, sizeof(ExtensionInfo)); - if (g_verbose) - write_msg(NULL, "identifying extension members\n"); + pg_log_info("identifying extension members"); getExtensionMembership(fout, extinfo, numExtensions); - if (g_verbose) - write_msg(NULL, "reading schemas\n"); + pg_log_info("reading schemas"); nspinfo = getNamespaces(fout, &numNamespaces); nspinfoindex = buildIndexArray(nspinfo, numNamespaces, sizeof(NamespaceInfo)); @@ -140,160 +137,124 @@ getSchemaData(Archive *fout, int *numTablesPtr) * However, we have to do getNamespaces first because the tables get * linked to their containing namespaces during getTables. */ - if (g_verbose) - write_msg(NULL, "reading user-defined tables\n"); + pg_log_info("reading user-defined tables"); tblinfo = getTables(fout, &numTables); tblinfoindex = buildIndexArray(tblinfo, numTables, sizeof(TableInfo)); /* Do this after we've built tblinfoindex */ getOwnedSeqs(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading user-defined functions\n"); + pg_log_info("reading user-defined functions"); funinfo = getFuncs(fout, &numFuncs); funinfoindex = buildIndexArray(funinfo, numFuncs, sizeof(FuncInfo)); /* this must be after getTables and getFuncs */ - if (g_verbose) - write_msg(NULL, "reading user-defined types\n"); + pg_log_info("reading user-defined types"); typinfo = getTypes(fout, &numTypes); typinfoindex = buildIndexArray(typinfo, numTypes, sizeof(TypeInfo)); /* this must be after getFuncs, too */ - if (g_verbose) - write_msg(NULL, "reading procedural languages\n"); + pg_log_info("reading procedural languages"); getProcLangs(fout, &numProcLangs); - if (g_verbose) - write_msg(NULL, "reading user-defined aggregate functions\n"); + pg_log_info("reading user-defined aggregate functions"); getAggregates(fout, &numAggregates); - if (g_verbose) - write_msg(NULL, "reading user-defined operators\n"); + pg_log_info("reading user-defined operators"); oprinfo = getOperators(fout, &numOperators); oprinfoindex = buildIndexArray(oprinfo, numOperators, sizeof(OprInfo)); - if (g_verbose) - write_msg(NULL, "reading user-defined access methods\n"); + pg_log_info("reading user-defined access methods"); getAccessMethods(fout, &numAccessMethods); - if (g_verbose) - write_msg(NULL, "reading user-defined operator classes\n"); + pg_log_info("reading user-defined operator classes"); getOpclasses(fout, &numOpclasses); - if (g_verbose) - write_msg(NULL, "reading user-defined operator families\n"); + pg_log_info("reading user-defined operator families"); getOpfamilies(fout, &numOpfamilies); - if (g_verbose) - write_msg(NULL, "reading user-defined text search parsers\n"); + pg_log_info("reading user-defined text search parsers"); getTSParsers(fout, &numTSParsers); - if (g_verbose) - write_msg(NULL, "reading user-defined text search templates\n"); + pg_log_info("reading user-defined text search templates"); getTSTemplates(fout, &numTSTemplates); - if (g_verbose) - write_msg(NULL, "reading user-defined text search dictionaries\n"); + pg_log_info("reading user-defined text search dictionaries"); getTSDictionaries(fout, &numTSDicts); - if (g_verbose) - write_msg(NULL, "reading user-defined text search configurations\n"); + pg_log_info("reading user-defined text search configurations"); getTSConfigurations(fout, &numTSConfigs); - if (g_verbose) - write_msg(NULL, "reading user-defined foreign-data wrappers\n"); + pg_log_info("reading user-defined foreign-data wrappers"); getForeignDataWrappers(fout, &numForeignDataWrappers); - if (g_verbose) - write_msg(NULL, "reading user-defined foreign servers\n"); + pg_log_info("reading user-defined foreign servers"); getForeignServers(fout, &numForeignServers); - if (g_verbose) - write_msg(NULL, "reading default privileges\n"); + pg_log_info("reading default privileges"); getDefaultACLs(fout, &numDefaultACLs); - if (g_verbose) - write_msg(NULL, "reading user-defined collations\n"); + pg_log_info("reading user-defined collations"); collinfo = getCollations(fout, &numCollations); collinfoindex = buildIndexArray(collinfo, numCollations, sizeof(CollInfo)); - if (g_verbose) - write_msg(NULL, "reading user-defined conversions\n"); + pg_log_info("reading user-defined conversions"); getConversions(fout, &numConversions); - if (g_verbose) - write_msg(NULL, "reading type casts\n"); + pg_log_info("reading type casts"); getCasts(fout, &numCasts); - if (g_verbose) - write_msg(NULL, "reading transforms\n"); + pg_log_info("reading transforms"); getTransforms(fout, &numTransforms); - if (g_verbose) - write_msg(NULL, "reading table inheritance information\n"); + pg_log_info("reading table inheritance information"); inhinfo = getInherits(fout, &numInherits); - if (g_verbose) - write_msg(NULL, "reading event triggers\n"); + pg_log_info("reading event triggers"); getEventTriggers(fout, &numEventTriggers); /* Identify extension configuration tables that should be dumped */ - if (g_verbose) - write_msg(NULL, "finding extension tables\n"); + pg_log_info("finding extension tables"); processExtensionTables(fout, extinfo, numExtensions); /* Link tables to parents, mark parents of target tables interesting */ - if (g_verbose) - write_msg(NULL, "finding inheritance relationships\n"); + pg_log_info("finding inheritance relationships"); flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits); - if (g_verbose) - write_msg(NULL, "reading column info for interesting tables\n"); + pg_log_info("reading column info for interesting tables"); getTableAttrs(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "flagging inherited columns in subtables\n"); + pg_log_info("flagging inherited columns in subtables"); flagInhAttrs(fout->dopt, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading indexes\n"); + pg_log_info("reading indexes"); getIndexes(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "flagging indexes in partitioned tables\n"); + pg_log_info("flagging indexes in partitioned tables"); flagInhIndexes(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading extended statistics\n"); + pg_log_info("reading extended statistics"); getExtendedStatistics(fout); - if (g_verbose) - write_msg(NULL, "reading constraints\n"); + pg_log_info("reading constraints"); getConstraints(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading triggers\n"); + pg_log_info("reading triggers"); getTriggers(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading rewrite rules\n"); + pg_log_info("reading rewrite rules"); getRules(fout, &numRules); - if (g_verbose) - write_msg(NULL, "reading policies\n"); + pg_log_info("reading policies"); getPolicies(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading publications\n"); + pg_log_info("reading publications"); getPublications(fout); - if (g_verbose) - write_msg(NULL, "reading publication membership\n"); + pg_log_info("reading publication membership"); getPublicationTables(fout, tblinfo, numTables); - if (g_verbose) - write_msg(NULL, "reading subscriptions\n"); + pg_log_info("reading subscriptions"); getSubscriptions(fout); *numTablesPtr = numTables; @@ -350,8 +311,8 @@ flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, findParentsByOid(&tblinfo[i], inhinfo, numInherits); /* - * If needed, mark the parents as interesting for getTableAttrs - * and getIndexes. + * If needed, mark the parents as interesting for getTableAttrs and + * getIndexes. */ if (mark_parents) { @@ -366,15 +327,15 @@ flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables, /* * flagInhIndexes - - * Create AttachIndexInfo objects for partitioned indexes, and add + * Create IndexAttachInfo objects for partitioned indexes, and add * appropriate dependency links. */ static void flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables) { - int i, - j, - k; + int i, + j, + k; DumpableObject ***parentIndexArray; parentIndexArray = (DumpableObject ***) @@ -382,7 +343,7 @@ flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables) for (i = 0; i < numTables; i++) { - TableInfo *parenttbl; + TableInfo *parenttbl; IndexAttachInfo *attachinfo; if (!tblinfo[i].ispartition || tblinfo[i].numParents == 0) @@ -425,17 +386,31 @@ flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables) attachinfo[k].dobj.catId.oid = 0; AssignDumpId(&attachinfo[k].dobj); attachinfo[k].dobj.name = pg_strdup(index->dobj.name); + attachinfo[k].dobj.namespace = index->indextable->dobj.namespace; attachinfo[k].parentIdx = parentidx; attachinfo[k].partitionIdx = index; /* - * We want dependencies from parent to partition (so that the - * partition index is created first), and another one from - * attach object to parent (so that the partition index is - * attached once the parent index has been created). + * We must state the DO_INDEX_ATTACH object's dependencies + * explicitly, since it will not match anything in pg_depend. + * + * Give it dependencies on both the partition index and the parent + * index, so that it will not be executed till both of those + * exist. (There's no need to care what order those are created + * in.) + * + * In addition, give it dependencies on the indexes' underlying + * tables. This does nothing of great value so far as serial + * restore ordering goes, but it ensures that a parallel restore + * will not try to run the ATTACH concurrently with other + * operations on those tables. */ - addObjectDependency(&parentidx->dobj, index->dobj.dumpId); + addObjectDependency(&attachinfo[k].dobj, index->dobj.dumpId); addObjectDependency(&attachinfo[k].dobj, parentidx->dobj.dumpId); + addObjectDependency(&attachinfo[k].dobj, + index->indextable->dobj.dumpId); + addObjectDependency(&attachinfo[k].dobj, + parentidx->indextable->dobj.dumpId); k++; } @@ -1045,10 +1020,10 @@ findParentsByOid(TableInfo *self, parent = findTableByOid(inhinfo[i].inhparent); if (parent == NULL) { - write_msg(NULL, "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n", - inhinfo[i].inhparent, - self->dobj.name, - oid); + pg_log_error("failed sanity check, parent OID %u of table \"%s\" (OID %u) not found", + inhinfo[i].inhparent, + self->dobj.name, + oid); exit_nicely(1); } self->parents[j++] = parent; @@ -1087,7 +1062,7 @@ parseOidArray(const char *str, Oid *array, int arraysize) { if (argNum >= arraysize) { - write_msg(NULL, "could not parse numeric array \"%s\": too many numbers\n", str); + pg_log_error("could not parse numeric array \"%s\": too many numbers", str); exit_nicely(1); } temp[j] = '\0'; @@ -1102,7 +1077,7 @@ parseOidArray(const char *str, Oid *array, int arraysize) if (!(isdigit((unsigned char) s) || s == '-') || j >= sizeof(temp) - 1) { - write_msg(NULL, "could not parse numeric array \"%s\": invalid character in number\n", str); + pg_log_error("could not parse numeric array \"%s\": invalid character in number", str); exit_nicely(1); } temp[j++] = s; diff --git a/src/bin/pg_dump/compress_io.c b/src/bin/pg_dump/compress_io.c index a96da15dc11..03c3e73ad04 100644 --- a/src/bin/pg_dump/compress_io.c +++ b/src/bin/pg_dump/compress_io.c @@ -4,7 +4,7 @@ * Routines for archivers to write an uncompressed or compressed data * stream. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This file includes two APIs for dealing with compressed data. The first @@ -74,27 +74,24 @@ struct CompressorState #endif }; -/* translator: this is a module name */ -static const char *modulename = gettext_noop("compress_io"); - static void ParseCompressionOption(int compression, CompressionAlgorithm *alg, - int *level); + int *level); /* Routines that support zlib compressed data I/O */ #ifdef HAVE_LIBZ static void InitCompressorZlib(CompressorState *cs, int level); static void DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, - bool flush); + bool flush); static void ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF); static void WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs, - const char *data, size_t dLen); + const char *data, size_t dLen); static void EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs); #endif /* Routines that support uncompressed data I/O */ static void ReadDataFromArchiveNone(ArchiveHandle *AH, ReadFunc readF); static void WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs, - const char *data, size_t dLen); + const char *data, size_t dLen); /* * Interprets a numeric 'compression' value. The algorithm implied by the @@ -111,8 +108,7 @@ ParseCompressionOption(int compression, CompressionAlgorithm *alg, int *level) *alg = COMPR_ALG_NONE; else { - exit_horribly(modulename, "invalid compression code: %d\n", - compression); + fatal("invalid compression code: %d", compression); *alg = COMPR_ALG_NONE; /* keep compiler quiet */ } @@ -135,7 +131,7 @@ AllocateCompressor(int compression, WriteFunc writeF) #ifndef HAVE_LIBZ if (alg == COMPR_ALG_LIBZ) - exit_horribly(modulename, "not built with zlib support\n"); + fatal("not built with zlib support"); #endif cs = (CompressorState *) pg_malloc0(sizeof(CompressorState)); @@ -171,7 +167,7 @@ ReadDataFromArchive(ArchiveHandle *AH, int compression, ReadFunc readF) #ifdef HAVE_LIBZ ReadDataFromArchiveZlib(AH, readF); #else - exit_horribly(modulename, "not built with zlib support\n"); + fatal("not built with zlib support"); #endif } } @@ -189,7 +185,7 @@ WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs, #ifdef HAVE_LIBZ WriteDataToArchiveZlib(AH, cs, data, dLen); #else - exit_horribly(modulename, "not built with zlib support\n"); + fatal("not built with zlib support"); #endif break; case COMPR_ALG_NONE: @@ -238,9 +234,8 @@ InitCompressorZlib(CompressorState *cs, int level) cs->zlibOutSize = ZLIB_OUT_SIZE; if (deflateInit(zp, level) != Z_OK) - exit_horribly(modulename, - "could not initialize compression library: %s\n", - zp->msg); + fatal("could not initialize compression library: %s", + zp->msg); /* Just be paranoid - maybe End is called after Start, with no Write */ zp->next_out = (void *) cs->zlibOut; @@ -259,8 +254,7 @@ EndCompressorZlib(ArchiveHandle *AH, CompressorState *cs) DeflateCompressorZlib(AH, cs, true); if (deflateEnd(zp) != Z_OK) - exit_horribly(modulename, - "could not close compression stream: %s\n", zp->msg); + fatal("could not close compression stream: %s", zp->msg); free(cs->zlibOut); free(cs->zp); @@ -277,8 +271,7 @@ DeflateCompressorZlib(ArchiveHandle *AH, CompressorState *cs, bool flush) { res = deflate(zp, flush ? Z_FINISH : Z_NO_FLUSH); if (res == Z_STREAM_ERROR) - exit_horribly(modulename, - "could not compress data: %s\n", zp->msg); + fatal("could not compress data: %s", zp->msg); if ((flush && (zp->avail_out < cs->zlibOutSize)) || (zp->avail_out == 0) || (zp->avail_in != 0) @@ -312,7 +305,7 @@ static void WriteDataToArchiveZlib(ArchiveHandle *AH, CompressorState *cs, const char *data, size_t dLen) { - cs->zp->next_in = (void *) data; + cs->zp->next_in = (void *) unconstify(char *, data); cs->zp->avail_in = dLen; DeflateCompressorZlib(AH, cs, false); @@ -340,9 +333,8 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) out = pg_malloc(ZLIB_OUT_SIZE + 1); if (inflateInit(zp) != Z_OK) - exit_horribly(modulename, - "could not initialize compression library: %s\n", - zp->msg); + fatal("could not initialize compression library: %s", + zp->msg); /* no minimal chunk size for zlib */ while ((cnt = readF(AH, &buf, &buflen))) @@ -357,8 +349,7 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) res = inflate(zp, 0); if (res != Z_OK && res != Z_STREAM_END) - exit_horribly(modulename, - "could not uncompress data: %s\n", zp->msg); + fatal("could not uncompress data: %s", zp->msg); out[ZLIB_OUT_SIZE - zp->avail_out] = '\0'; ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH); @@ -373,16 +364,14 @@ ReadDataFromArchiveZlib(ArchiveHandle *AH, ReadFunc readF) zp->avail_out = ZLIB_OUT_SIZE; res = inflate(zp, 0); if (res != Z_OK && res != Z_STREAM_END) - exit_horribly(modulename, - "could not uncompress data: %s\n", zp->msg); + fatal("could not uncompress data: %s", zp->msg); out[ZLIB_OUT_SIZE - zp->avail_out] = '\0'; ahwrite(out, 1, ZLIB_OUT_SIZE - zp->avail_out, AH); } if (inflateEnd(zp) != Z_OK) - exit_horribly(modulename, - "could not close compression library: %s\n", zp->msg); + fatal("could not close compression library: %s", zp->msg); free(buf); free(out); @@ -516,7 +505,7 @@ cfopen_write(const char *path, const char *mode, int compression) fp = cfopen(fname, mode, compression); free_keep_errno(fname); #else - exit_horribly(modulename, "not built with zlib support\n"); + fatal("not built with zlib support"); fp = NULL; /* keep compiler quiet */ #endif } @@ -559,7 +548,7 @@ cfopen(const char *path, const char *mode, int compression) fp = NULL; } #else - exit_horribly(modulename, "not built with zlib support\n"); + fatal("not built with zlib support"); #endif } else @@ -596,9 +585,8 @@ cfread(void *ptr, int size, cfp *fp) int errnum; const char *errmsg = gzerror(fp->compressedfp, &errnum); - exit_horribly(modulename, - "could not read from input file: %s\n", - errnum == Z_ERRNO ? strerror(errno) : errmsg); + fatal("could not read from input file: %s", + errnum == Z_ERRNO ? strerror(errno) : errmsg); } } else @@ -634,11 +622,9 @@ cfgetc(cfp *fp) if (ret == EOF) { if (!gzeof(fp->compressedfp)) - exit_horribly(modulename, - "could not read from input file: %s\n", strerror(errno)); + fatal("could not read from input file: %s", strerror(errno)); else - exit_horribly(modulename, - "could not read from input file: end of file\n"); + fatal("could not read from input file: end of file"); } } else diff --git a/src/bin/pg_dump/compress_io.h b/src/bin/pg_dump/compress_io.h index 10fde8bdef5..69f7c8d94ea 100644 --- a/src/bin/pg_dump/compress_io.h +++ b/src/bin/pg_dump/compress_io.h @@ -3,7 +3,7 @@ * compress_io.h * Interface to compress_io.c routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -48,9 +48,9 @@ typedef struct CompressorState CompressorState; extern CompressorState *AllocateCompressor(int compression, WriteFunc writeF); extern void ReadDataFromArchive(ArchiveHandle *AH, int compression, - ReadFunc readF); + ReadFunc readF); extern void WriteDataToArchive(ArchiveHandle *AH, CompressorState *cs, - const void *data, size_t dLen); + const void *data, size_t dLen); extern void EndCompressor(ArchiveHandle *AH, CompressorState *cs); diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 875545f6995..2c49b0ff367 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -5,7 +5,7 @@ * Basically this is stuff that is useful in both pg_dump and pg_dumpall. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/dumputils.c @@ -14,17 +14,19 @@ */ #include "postgres_fe.h" +#include + #include "dumputils.h" #include "fe_utils/string_utils.h" static bool parseAclItem(const char *item, const char *type, - const char *name, const char *subname, int remoteVersion, - PQExpBuffer grantee, PQExpBuffer grantor, - PQExpBuffer privs, PQExpBuffer privswgo); + const char *name, const char *subname, int remoteVersion, + PQExpBuffer grantee, PQExpBuffer grantor, + PQExpBuffer privs, PQExpBuffer privswgo); static char *copyAclUserName(PQExpBuffer output, char *input); static void AddAcl(PQExpBuffer aclbuf, const char *keyword, - const char *subname); + const char *subname); /* @@ -93,6 +95,8 @@ buildACLCommands(const char *name, const char *subname, const char *nspname, { if (!parsePGArray(racls, &raclitems, &nraclitems)) { + if (aclitems) + free(aclitems); if (raclitems) free(raclitems); return false; @@ -421,7 +425,7 @@ buildDefaultACLCommands(const char *type, const char *nspname, if (strlen(initacls) != 0 || strlen(initracls) != 0) { - appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n"); + appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n"); if (!buildACLCommands("", NULL, NULL, type, initacls, initracls, owner, prefix->data, remoteVersion, sql)) @@ -429,7 +433,7 @@ buildDefaultACLCommands(const char *type, const char *nspname, destroyPQExpBuffer(prefix); return false; } - appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n"); + appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n"); } if (!buildACLCommands("", NULL, NULL, type, @@ -477,15 +481,13 @@ parseAclItem(const char *item, const char *type, char *slpos; char *pos; - buf = strdup(item); - if (!buf) - return false; + buf = pg_strdup(item); /* user or group name is string up to = */ eqpos = copyAclUserName(grantee, buf); if (*eqpos != '=') { - free(buf); + pg_free(buf); return false; } @@ -497,13 +499,13 @@ parseAclItem(const char *item, const char *type, slpos = copyAclUserName(grantor, slpos); if (*slpos != '\0') { - free(buf); + pg_free(buf); return false; } } else { - free(buf); + pg_free(buf); return false; } @@ -613,7 +615,7 @@ do { \ appendPQExpBuffer(privs, "(%s)", subname); } - free(buf); + pg_free(buf); return true; } @@ -873,6 +875,115 @@ variable_is_guc_list_quote(const char *name) return false; } +/* + * SplitGUCList --- parse a string containing identifiers or file names + * + * This is used to split the value of a GUC_LIST_QUOTE GUC variable, without + * presuming whether the elements will be taken as identifiers or file names. + * See comparable code in src/backend/utils/adt/varlena.c. + * + * Inputs: + * rawstring: the input string; must be overwritable! On return, it's + * been modified to contain the separated identifiers. + * separator: the separator punctuation expected between identifiers + * (typically '.' or ','). Whitespace may also appear around + * identifiers. + * Outputs: + * namelist: receives a malloc'd, null-terminated array of pointers to + * identifiers within rawstring. Caller should free this + * even on error return. + * + * Returns true if okay, false if there is a syntax error in the string. + */ +bool +SplitGUCList(char *rawstring, char separator, + char ***namelist) +{ + char *nextp = rawstring; + bool done = false; + char **nextptr; + + /* + * Since we disallow empty identifiers, this is a conservative + * overestimate of the number of pointers we could need. Allow one for + * list terminator. + */ + *namelist = nextptr = (char **) + pg_malloc((strlen(rawstring) / 2 + 2) * sizeof(char *)); + *nextptr = NULL; + + while (isspace((unsigned char) *nextp)) + nextp++; /* skip leading whitespace */ + + if (*nextp == '\0') + return true; /* allow empty string */ + + /* At the top of the loop, we are at start of a new identifier. */ + do + { + char *curname; + char *endp; + + if (*nextp == '"') + { + /* Quoted name --- collapse quote-quote pairs */ + curname = nextp + 1; + for (;;) + { + endp = strchr(nextp + 1, '"'); + if (endp == NULL) + return false; /* mismatched quotes */ + if (endp[1] != '"') + break; /* found end of quoted name */ + /* Collapse adjacent quotes into one quote, and look again */ + memmove(endp, endp + 1, strlen(endp)); + nextp = endp; + } + /* endp now points at the terminating quote */ + nextp = endp + 1; + } + else + { + /* Unquoted name --- extends to separator or whitespace */ + curname = nextp; + while (*nextp && *nextp != separator && + !isspace((unsigned char) *nextp)) + nextp++; + endp = nextp; + if (curname == nextp) + return false; /* empty unquoted name not allowed */ + } + + while (isspace((unsigned char) *nextp)) + nextp++; /* skip trailing whitespace */ + + if (*nextp == separator) + { + nextp++; + while (isspace((unsigned char) *nextp)) + nextp++; /* skip leading whitespace for next */ + /* we expect another name, so done remains false */ + } + else if (*nextp == '\0') + done = true; + else + return false; /* invalid syntax */ + + /* Now safe to overwrite separator with a null */ + *endp = '\0'; + + /* + * Finished isolating current name --- add it to output array + */ + *nextptr++ = curname; + + /* Loop back if we didn't reach end of string */ + } while (!done); + + *nextptr = NULL; + return true; +} + /* * Helper function for dumping "ALTER DATABASE/ROLE SET ..." commands. * @@ -912,14 +1023,35 @@ makeAlterConfigCommand(PGconn *conn, const char *configitem, /* * Variables that are marked GUC_LIST_QUOTE were already fully quoted by * flatten_set_variable_args() before they were put into the setconfig - * array; we mustn't re-quote them or we'll make a mess. Variables that - * are not so marked should just be emitted as simple string literals. If - * the variable is not known to variable_is_guc_list_quote(), we'll do the - * latter; this makes it unsafe to use GUC_LIST_QUOTE for extension - * variables. + * array. However, because the quoting rules used there aren't exactly + * like SQL's, we have to break the list value apart and then quote the + * elements as string literals. (The elements may be double-quoted as-is, + * but we can't just feed them to the SQL parser; it would do the wrong + * thing with elements that are zero-length or longer than NAMEDATALEN.) + * + * Variables that are not so marked should just be emitted as simple + * string literals. If the variable is not known to + * variable_is_guc_list_quote(), we'll do that; this makes it unsafe to + * use GUC_LIST_QUOTE for extension variables. */ if (variable_is_guc_list_quote(mine)) - appendPQExpBufferStr(buf, pos); + { + char **namelist; + char **nameptr; + + /* Parse string into list of identifiers */ + /* this shouldn't fail really */ + if (SplitGUCList(pos, ',', &namelist)) + { + for (nameptr = namelist; *nameptr; nameptr++) + { + if (nameptr != namelist) + appendPQExpBufferStr(buf, ", "); + appendStringLiteralConn(buf, *nameptr, conn); + } + } + pg_free(namelist); + } else appendStringLiteralConn(buf, pos, conn); diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h index 7bd3e1d5eb0..7ec5df9513f 100644 --- a/src/bin/pg_dump/dumputils.h +++ b/src/bin/pg_dump/dumputils.h @@ -5,7 +5,7 @@ * Basically this is stuff that is useful in both pg_dump and pg_dumpall. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/dumputils.h @@ -37,30 +37,33 @@ extern bool buildACLCommands(const char *name, const char *subname, const char *nspname, - const char *type, const char *acls, const char *racls, - const char *owner, const char *prefix, int remoteVersion, - PQExpBuffer sql); + const char *type, const char *acls, const char *racls, + const char *owner, const char *prefix, int remoteVersion, + PQExpBuffer sql); extern bool buildDefaultACLCommands(const char *type, const char *nspname, - const char *acls, const char *racls, - const char *initacls, const char *initracls, - const char *owner, - int remoteVersion, - PQExpBuffer sql); + const char *acls, const char *racls, + const char *initacls, const char *initracls, + const char *owner, + int remoteVersion, + PQExpBuffer sql); extern void buildShSecLabelQuery(PGconn *conn, const char *catalog_name, - Oid objectId, PQExpBuffer sql); + Oid objectId, PQExpBuffer sql); extern void emitShSecLabels(PGconn *conn, PGresult *res, - PQExpBuffer buffer, const char *objtype, const char *objname); + PQExpBuffer buffer, const char *objtype, const char *objname); extern void buildACLQueries(PQExpBuffer acl_subquery, PQExpBuffer racl_subquery, - PQExpBuffer init_acl_subquery, PQExpBuffer init_racl_subquery, - const char *acl_column, const char *acl_owner, - const char *obj_kind, bool binary_upgrade); + PQExpBuffer init_acl_subquery, PQExpBuffer init_racl_subquery, + const char *acl_column, const char *acl_owner, + const char *obj_kind, bool binary_upgrade); extern bool variable_is_guc_list_quote(const char *name); +extern bool SplitGUCList(char *rawstring, char separator, + char ***namelist); + extern void makeAlterConfigCommand(PGconn *conn, const char *configitem, - const char *type, const char *name, - const char *type2, const char *name2, - PQExpBuffer buf); + const char *type, const char *name, + const char *type2, const char *name2, + PQExpBuffer buf); #endif /* DUMPUTILS_H */ diff --git a/src/bin/pg_dump/nls.mk b/src/bin/pg_dump/nls.mk index 9a8c5e9fb4c..2a6fd597cb1 100644 --- a/src/bin/pg_dump/nls.mk +++ b/src/bin/pg_dump/nls.mk @@ -1,7 +1,8 @@ # src/bin/pg_dump/nls.mk CATALOG_NAME = pg_dump -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv zh_CN -GETTEXT_FILES = pg_backup_archiver.c pg_backup_db.c pg_backup_custom.c \ +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ + pg_backup_archiver.c pg_backup_db.c pg_backup_custom.c \ pg_backup_null.c pg_backup_tar.c \ pg_backup_directory.c dumputils.c compress_io.c \ pg_dump.c common.c pg_dump_sort.c \ @@ -9,10 +10,9 @@ GETTEXT_FILES = pg_backup_archiver.c pg_backup_db.c pg_backup_custom.c \ parallel.c parallel.h pg_backup_utils.c pg_backup_utils.h \ ../../common/exec.c ../../common/fe_memutils.c \ ../../common/wait_error.c -GETTEXT_TRIGGERS = write_msg:2 exit_horribly:2 simple_prompt \ - ExecuteSqlCommand:3 ahlog:3 warn_or_exit_horribly:3 -GETTEXT_FLAGS = \ - write_msg:2:c-format \ - exit_horribly:2:c-format \ - ahlog:3:c-format \ - warn_or_exit_horribly:3:c-format +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \ + fatal simple_prompt \ + ExecuteSqlCommand:3 warn_or_exit_horribly:2 +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) \ + fatal:1:c-format \ + warn_or_exit_horribly:2:c-format diff --git a/src/bin/pg_dump/parallel.c b/src/bin/pg_dump/parallel.c index 02e79f2f275..03479f1a13c 100644 --- a/src/bin/pg_dump/parallel.c +++ b/src/bin/pg_dump/parallel.c @@ -4,7 +4,7 @@ * * Parallel support for pg_dump and pg_restore * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -197,8 +197,6 @@ bool parallel_init_done = false; DWORD mainThreadId; #endif /* WIN32 */ -static const char *modulename = gettext_noop("parallel archiver"); - /* Local function prototypes */ static ParallelSlot *GetMyPSlot(ParallelState *pstate); static void archive_close_connection(int code, void *arg); @@ -213,20 +211,18 @@ static bool HasEveryWorkerTerminated(ParallelState *pstate); static void lockTableForWorker(ArchiveHandle *AH, TocEntry *te); static void WaitForCommands(ArchiveHandle *AH, int pipefd[2]); static bool ListenToWorkers(ArchiveHandle *AH, ParallelState *pstate, - bool do_wait); + bool do_wait); static char *getMessageFromMaster(int pipefd[2]); static void sendMessageToMaster(int pipefd[2], const char *str); static int select_loop(int maxFd, fd_set *workerset); static char *getMessageFromWorker(ParallelState *pstate, - bool do_wait, int *worker); + bool do_wait, int *worker); static void sendMessageToWorker(ParallelState *pstate, - int worker, const char *str); + int worker, const char *str); static char *readMessageFromPipe(int fd); #define messageStartsWith(msg, prefix) \ (strncmp(msg, prefix, strlen(prefix)) == 0) -#define messageEquals(msg, pattern) \ - (strcmp(msg, pattern) == 0) /* @@ -264,7 +260,7 @@ init_parallel_dump_utils(void) err = WSAStartup(MAKEWORD(2, 2), &wsaData); if (err != 0) { - fprintf(stderr, _("%s: WSAStartup failed: %d\n"), progname, err); + pg_log_error("WSAStartup failed: %d", err); exit_nicely(1); } /* ... and arrange to shut it down at exit */ @@ -406,8 +402,8 @@ archive_close_connection(int code, void *arg) * Forcibly shut down any remaining workers, waiting for them to finish. * * Note that we don't expect to come here during normal exit (the workers - * should be long gone, and the ParallelState too). We're only here in an - * exit_horribly() situation, so intervening to cancel active commands is + * should be long gone, and the ParallelState too). We're only here in a + * fatal() situation, so intervening to cancel active commands is * appropriate. */ static void @@ -699,7 +695,7 @@ consoleHandler(DWORD dwCtrlType) /* * Report we're quitting, using nothing more complicated than - * write(2). (We might be able to get away with using write_msg() + * write(2). (We might be able to get away with using pg_log_*() * here, but since we terminated other threads uncleanly above, it * seems better to assume as little as possible.) */ @@ -969,9 +965,7 @@ ParallelBackupStart(ArchiveHandle *AH) /* Create communication pipes for this worker */ if (pgpipe(pipeMW) < 0 || pgpipe(pipeWM) < 0) - exit_horribly(modulename, - "could not create communication channels: %s\n", - strerror(errno)); + fatal("could not create communication channels: %m"); pstate->te[i] = NULL; /* just for safety */ @@ -1034,9 +1028,7 @@ ParallelBackupStart(ArchiveHandle *AH) else if (pid < 0) { /* fork failed */ - exit_horribly(modulename, - "could not create worker process: %s\n", - strerror(errno)); + fatal("could not create worker process: %m"); } /* In Master after successful fork */ @@ -1165,9 +1157,8 @@ parseWorkerCommand(ArchiveHandle *AH, TocEntry **te, T_Action *act, Assert(*te != NULL); } else - exit_horribly(modulename, - "unrecognized command received from master: \"%s\"\n", - msg); + fatal("unrecognized command received from master: \"%s\"", + msg); } /* @@ -1209,9 +1200,8 @@ parseWorkerResponse(ArchiveHandle *AH, TocEntry *te, AH->public.n_errors += n_errors; } else - exit_horribly(modulename, - "invalid message received from worker: \"%s\"\n", - msg); + fatal("invalid message received from worker: \"%s\"", + msg); return status; } @@ -1334,7 +1324,7 @@ lockTableForWorker(ArchiveHandle *AH, TocEntry *te) query = createPQExpBuffer(); - qualId = fmtQualifiedId(AH->public.remoteVersion, te->namespace, te->tag); + qualId = fmtQualifiedId(te->namespace, te->tag); appendPQExpBuffer(query, "LOCK TABLE %s IN ACCESS SHARE MODE NOWAIT", qualId); @@ -1342,11 +1332,10 @@ lockTableForWorker(ArchiveHandle *AH, TocEntry *te) res = PQexec(AH->connection, query->data); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) - exit_horribly(modulename, - "could not obtain lock on relation \"%s\"\n" - "This usually means that someone requested an ACCESS EXCLUSIVE lock " - "on the table after the pg_dump parent process had gotten the " - "initial ACCESS SHARE lock on the table.\n", qualId); + fatal("could not obtain lock on relation \"%s\"\n" + "This usually means that someone requested an ACCESS EXCLUSIVE lock " + "on the table after the pg_dump parent process had gotten the " + "initial ACCESS SHARE lock on the table.", qualId); PQclear(res); destroyPQExpBuffer(query); @@ -1432,7 +1421,7 @@ ListenToWorkers(ArchiveHandle *AH, ParallelState *pstate, bool do_wait) { /* If do_wait is true, we must have detected EOF on some socket */ if (do_wait) - exit_horribly(modulename, "a worker process died unexpectedly\n"); + fatal("a worker process died unexpectedly"); return false; } @@ -1449,9 +1438,8 @@ ListenToWorkers(ArchiveHandle *AH, ParallelState *pstate, bool do_wait) pstate->te[worker] = NULL; } else - exit_horribly(modulename, - "invalid message received from worker: \"%s\"\n", - msg); + fatal("invalid message received from worker: \"%s\"", + msg); /* Free the string returned from getMessageFromWorker */ free(msg); @@ -1555,9 +1543,7 @@ sendMessageToMaster(int pipefd[2], const char *str) int len = strlen(str) + 1; if (pipewrite(pipefd[PIPE_WRITE], str, len) != len) - exit_horribly(modulename, - "could not write to the communication channel: %s\n", - strerror(errno)); + fatal("could not write to the communication channel: %m"); } /* @@ -1634,7 +1620,7 @@ getMessageFromWorker(ParallelState *pstate, bool do_wait, int *worker) } if (i < 0) - exit_horribly(modulename, "select() failed: %s\n", strerror(errno)); + fatal("select() failed: %m"); for (i = 0; i < pstate->numWorkers; i++) { @@ -1673,9 +1659,7 @@ sendMessageToWorker(ParallelState *pstate, int worker, const char *str) if (pipewrite(pstate->parallelSlot[worker].pipeWrite, str, len) != len) { - exit_horribly(modulename, - "could not write to the communication channel: %s\n", - strerror(errno)); + fatal("could not write to the communication channel: %m"); } } @@ -1759,8 +1743,8 @@ pgpipe(int handles[2]) */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == PGINVALID_SOCKET) { - write_msg(modulename, "pgpipe: could not create socket: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not create socket: error code %d", + WSAGetLastError()); return -1; } @@ -1770,22 +1754,22 @@ pgpipe(int handles[2]) serv_addr.sin_addr.s_addr = pg_hton32(INADDR_LOOPBACK); if (bind(s, (SOCKADDR *) &serv_addr, len) == SOCKET_ERROR) { - write_msg(modulename, "pgpipe: could not bind: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not bind: error code %d", + WSAGetLastError()); closesocket(s); return -1; } if (listen(s, 1) == SOCKET_ERROR) { - write_msg(modulename, "pgpipe: could not listen: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not listen: error code %d", + WSAGetLastError()); closesocket(s); return -1; } if (getsockname(s, (SOCKADDR *) &serv_addr, &len) == SOCKET_ERROR) { - write_msg(modulename, "pgpipe: getsockname() failed: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: getsockname() failed: error code %d", + WSAGetLastError()); closesocket(s); return -1; } @@ -1795,8 +1779,8 @@ pgpipe(int handles[2]) */ if ((tmp_sock = socket(AF_INET, SOCK_STREAM, 0)) == PGINVALID_SOCKET) { - write_msg(modulename, "pgpipe: could not create second socket: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not create second socket: error code %d", + WSAGetLastError()); closesocket(s); return -1; } @@ -1804,8 +1788,8 @@ pgpipe(int handles[2]) if (connect(handles[1], (SOCKADDR *) &serv_addr, len) == SOCKET_ERROR) { - write_msg(modulename, "pgpipe: could not connect socket: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not connect socket: error code %d", + WSAGetLastError()); closesocket(handles[1]); handles[1] = -1; closesocket(s); @@ -1813,8 +1797,8 @@ pgpipe(int handles[2]) } if ((tmp_sock = accept(s, (SOCKADDR *) &serv_addr, &len)) == PGINVALID_SOCKET) { - write_msg(modulename, "pgpipe: could not accept connection: error code %d\n", - WSAGetLastError()); + pg_log_error("pgpipe: could not accept connection: error code %d", + WSAGetLastError()); closesocket(handles[1]); handles[1] = -1; closesocket(s); diff --git a/src/bin/pg_dump/parallel.h b/src/bin/pg_dump/parallel.h index 1577400622a..b51ed92430b 100644 --- a/src/bin/pg_dump/parallel.h +++ b/src/bin/pg_dump/parallel.h @@ -4,7 +4,7 @@ * * Parallel support for pg_dump and pg_restore * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -54,15 +54,15 @@ extern void init_parallel_dump_utils(void); extern bool IsEveryWorkerIdle(ParallelState *pstate); extern void WaitForWorkers(ArchiveHandle *AH, ParallelState *pstate, - WFW_WaitOption mode); + WFW_WaitOption mode); extern ParallelState *ParallelBackupStart(ArchiveHandle *AH); extern void DispatchJobForTocEntry(ArchiveHandle *AH, - ParallelState *pstate, - TocEntry *te, - T_Action act, - ParallelCompletionPtr callback, - void *callback_data); + ParallelState *pstate, + TocEntry *te, + T_Action act, + ParallelCompletionPtr callback, + void *callback_data); extern void ParallelBackupEnd(ArchiveHandle *AH, ParallelState *pstate); extern void set_archive_cancel_info(ArchiveHandle *AH, PGconn *conn); diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h index ceedd481fb4..8c0cedcd983 100644 --- a/src/bin/pg_dump/pg_backup.h +++ b/src/bin/pg_dump/pg_backup.h @@ -11,7 +11,7 @@ * as this notice is not removed. * * The author is not responsible for loss or damages that may - * result from it's use. + * result from its use. * * * IDENTIFICATION @@ -131,7 +131,6 @@ typedef struct _dumpOptions const char *pghost; const char *pgport; const char *username; - bool oids; int binary_upgrade; @@ -141,10 +140,10 @@ typedef struct _dumpOptions int dumpSections; /* bitmask of chosen sections */ bool aclsSkip; const char *lockWaitTimeout; + int dump_inserts; /* 0 = COPY, otherwise rows per INSERT */ /* flags for various command-line long options */ int disable_dollar_quoting; - int dump_inserts; int column_inserts; int if_exists; int no_comments; @@ -154,7 +153,6 @@ typedef struct _dumpOptions int no_synchronized_snapshots; int no_unlogged_table_data; int serializable_deferrable; - int quote_all_identifiers; int disable_triggers; int outputNoTablespaces; int use_setsessauth; @@ -172,6 +170,7 @@ typedef struct _dumpOptions char *outputSuperuser; int sequence_data; /* dump sequence data even in schema-only mode */ + int do_nothing; } DumpOptions; /* @@ -243,26 +242,14 @@ typedef void (*SetupWorkerPtrType) (Archive *AH); */ extern void ConnectDatabase(Archive *AH, - const char *dbname, - const char *pghost, - const char *pgport, - const char *username, - trivalue prompt_password); + const char *dbname, + const char *pghost, + const char *pgport, + const char *username, + trivalue prompt_password); extern void DisconnectDatabase(Archive *AHX); extern PGconn *GetConnection(Archive *AHX); -/* Called to add a TOC entry */ -extern void ArchiveEntry(Archive *AHX, - CatalogId catalogId, DumpId dumpId, - const char *tag, - const char *namespace, const char *tablespace, - const char *owner, bool withOids, - const char *desc, teSection section, - const char *defn, - const char *dropStmt, const char *copyStmt, - const DumpId *deps, int nDeps, - DataDumperPtr dumpFn, void *dumpArg); - /* Called to write *data* to the archive */ extern void WriteData(Archive *AH, const void *data, size_t dLen); @@ -282,8 +269,8 @@ extern Archive *OpenArchive(const char *FileSpec, const ArchiveFormat fmt); /* Create a new archive */ extern Archive *CreateArchive(const char *FileSpec, const ArchiveFormat fmt, - const int compression, bool dosync, ArchiveMode mode, - SetupWorkerPtrType setupDumpWorker); + const int compression, bool dosync, ArchiveMode mode, + SetupWorkerPtrType setupDumpWorker); /* The --list option */ extern void PrintTOCSummary(Archive *AH); diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index 83c976eaf71..6c739ce6633 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -49,25 +49,40 @@ typedef struct _outputContext int gzOut; } OutputContext; -/* translator: this is a module name */ -static const char *modulename = gettext_noop("archiver"); +/* + * State for tracking TocEntrys that are ready to process during a parallel + * restore. (This used to be a list, and we still call it that, though now + * it's really an array so that we can apply qsort to it.) + * + * tes[] is sized large enough that we can't overrun it. + * The valid entries are indexed first_te .. last_te inclusive. + * We periodically sort the array to bring larger-by-dataLength entries to + * the front; "sorted" is true if the valid entries are known sorted. + */ +typedef struct _parallelReadyList +{ + TocEntry **tes; /* Ready-to-dump TocEntrys */ + int first_te; /* index of first valid entry in tes[] */ + int last_te; /* index of last valid entry in tes[] */ + bool sorted; /* are valid entries currently sorted? */ +} ParallelReadyList; static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt, - const int compression, bool dosync, ArchiveMode mode, - SetupWorkerPtrType setupWorkerPtr); + const int compression, bool dosync, ArchiveMode mode, + SetupWorkerPtrType setupWorkerPtr); static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, - ArchiveHandle *AH); + ArchiveHandle *AH); static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData); -static char *replace_line_endings(const char *str); +static char *sanitize_line(const char *str, bool want_hyphen); static void _doSetFixedOutputState(ArchiveHandle *AH); static void _doSetSessionAuth(ArchiveHandle *AH, const char *user); -static void _doSetWithOids(ArchiveHandle *AH, const bool withOids); static void _reconnectToDB(ArchiveHandle *AH, const char *dbname); static void _becomeUser(ArchiveHandle *AH, const char *user); static void _becomeOwner(ArchiveHandle *AH, TocEntry *te); static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName); static void _selectTablespace(ArchiveHandle *AH, const char *tablespace); +static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam); static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te); static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te); static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te); @@ -89,34 +104,41 @@ static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext); static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel); static void restore_toc_entries_prefork(ArchiveHandle *AH, - TocEntry *pending_list); + TocEntry *pending_list); static void restore_toc_entries_parallel(ArchiveHandle *AH, - ParallelState *pstate, - TocEntry *pending_list); + ParallelState *pstate, + TocEntry *pending_list); static void restore_toc_entries_postfork(ArchiveHandle *AH, - TocEntry *pending_list); -static void par_list_header_init(TocEntry *l); -static void par_list_append(TocEntry *l, TocEntry *te); -static void par_list_remove(TocEntry *te); -static void move_to_ready_list(TocEntry *pending_list, TocEntry *ready_list, - RestorePass pass); -static TocEntry *get_next_work_item(ArchiveHandle *AH, - TocEntry *ready_list, - ParallelState *pstate); + TocEntry *pending_list); +static void pending_list_header_init(TocEntry *l); +static void pending_list_append(TocEntry *l, TocEntry *te); +static void pending_list_remove(TocEntry *te); +static void ready_list_init(ParallelReadyList *ready_list, int tocCount); +static void ready_list_free(ParallelReadyList *ready_list); +static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te); +static void ready_list_remove(ParallelReadyList *ready_list, int i); +static void ready_list_sort(ParallelReadyList *ready_list); +static int TocEntrySizeCompare(const void *p1, const void *p2); +static void move_to_ready_list(TocEntry *pending_list, + ParallelReadyList *ready_list, + RestorePass pass); +static TocEntry *pop_next_work_item(ArchiveHandle *AH, + ParallelReadyList *ready_list, + ParallelState *pstate); static void mark_dump_job_done(ArchiveHandle *AH, - TocEntry *te, - int status, - void *callback_data); + TocEntry *te, + int status, + void *callback_data); static void mark_restore_job_done(ArchiveHandle *AH, - TocEntry *te, - int status, - void *callback_data); + TocEntry *te, + int status, + void *callback_data); static void fix_dependencies(ArchiveHandle *AH); static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2); static void repoint_table_dependencies(ArchiveHandle *AH); static void identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te); static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, - TocEntry *ready_list); + ParallelReadyList *ready_list); static void mark_create_done(ArchiveHandle *AH, TocEntry *te); static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te); @@ -247,8 +269,7 @@ CloseArchive(Archive *AHX) res = fclose(AH->OF); if (res != 0) - exit_horribly(modulename, "could not close output file: %s\n", - strerror(errno)); + fatal("could not close output file: %m"); } /* Public */ @@ -292,20 +313,18 @@ ProcessArchiveRestoreOptions(Archive *AHX) break; case SECTION_PRE_DATA: if (curSection != SECTION_PRE_DATA) - write_msg(modulename, - "WARNING: archive items not in correct section order\n"); + pg_log_warning("archive items not in correct section order"); break; case SECTION_DATA: if (curSection == SECTION_POST_DATA) - write_msg(modulename, - "WARNING: archive items not in correct section order\n"); + pg_log_warning("archive items not in correct section order"); break; case SECTION_POST_DATA: /* ok no matter which section we were in */ break; default: - exit_horribly(modulename, "unexpected section code %d\n", - (int) te->section); + fatal("unexpected section code %d", + (int) te->section); break; } } @@ -333,15 +352,6 @@ RestoreArchive(Archive *AHX) AH->stage = STAGE_INITIALIZING; - /* - * Check for nonsensical option combinations. - * - * -C is not compatible with -1, because we can't create a database inside - * a transaction block. - */ - if (ropt->createDB && ropt->single_txn) - exit_horribly(modulename, "-C and -1 are incompatible options\n"); - /* * If we're going to do parallel restore, there are some restrictions. */ @@ -350,11 +360,11 @@ RestoreArchive(Archive *AHX) { /* We haven't got round to making this work for all archive formats */ if (AH->ClonePtr == NULL || AH->ReopenPtr == NULL) - exit_horribly(modulename, "parallel restore is not supported with this archive file format\n"); + fatal("parallel restore is not supported with this archive file format"); /* Doesn't work if the archive represents dependencies as OIDs */ if (AH->version < K_VERS_1_8) - exit_horribly(modulename, "parallel restore is not supported with archives made by pre-8.0 pg_dump\n"); + fatal("parallel restore is not supported with archives made by pre-8.0 pg_dump"); /* * It's also not gonna work if we can't reopen the input file, so @@ -372,7 +382,7 @@ RestoreArchive(Archive *AHX) for (te = AH->toc->next; te != AH->toc; te = te->next) { if (te->hadDumper && (te->reqs & REQ_DATA) != 0) - exit_horribly(modulename, "cannot restore from compressed archive (compression not supported in this installation)\n"); + fatal("cannot restore from compressed archive (compression not supported in this installation)"); } } #endif @@ -389,9 +399,9 @@ RestoreArchive(Archive *AHX) */ if (ropt->useDB) { - ahlog(AH, 1, "connecting to database for restore\n"); + pg_log_info("connecting to database for restore"); if (AH->version < K_VERS_1_3) - exit_horribly(modulename, "direct database connections are not supported in pre-1.3 archives\n"); + fatal("direct database connections are not supported in pre-1.3 archives"); /* * We don't want to guess at whether the dump will successfully @@ -436,7 +446,7 @@ RestoreArchive(Archive *AHX) if (impliedDataOnly) { ropt->dataOnly = impliedDataOnly; - ahlog(AH, 1, "implied data-only restore\n"); + pg_log_info("implied data-only restore"); } } @@ -502,7 +512,7 @@ RestoreArchive(Archive *AHX) /* Otherwise, drop anything that's selected and has a dropStmt */ if (((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt) { - ahlog(AH, 1, "dropping %s %s\n", te->desc, te->tag); + pg_log_info("dropping %s %s", te->desc, te->tag); /* Select owner and schema as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); @@ -544,8 +554,8 @@ RestoreArchive(Archive *AHX) */ if (strncmp(dropStmt, "ALTER TABLE", 11) == 0) { - appendPQExpBuffer(ftStmt, - "ALTER TABLE IF EXISTS"); + appendPQExpBufferStr(ftStmt, + "ALTER TABLE IF EXISTS"); dropStmt = dropStmt + 11; } @@ -597,9 +607,8 @@ RestoreArchive(Archive *AHX) else { /* complain and emit unmodified command */ - write_msg(modulename, - "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n", - dropStmtOrig); + pg_log_warning("could not find where to insert IF EXISTS in statement \"%s\"", + dropStmtOrig); appendPQExpBufferStr(ftStmt, dropStmt); } } @@ -639,7 +648,11 @@ RestoreArchive(Archive *AHX) ParallelState *pstate; TocEntry pending_list; - par_list_header_init(&pending_list); + /* The archive format module may need some setup for this */ + if (AH->PrepParallelRestorePtr) + AH->PrepParallelRestorePtr(AH); + + pending_list_header_init(&pending_list); /* This runs PRE_DATA items and then disconnects from the database */ restore_toc_entries_prefork(AH, &pending_list); @@ -750,9 +763,9 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0) { if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0) - write_msg(modulename, "warning from original dump file: %s\n", te->defn); + pg_log_warning("warning from original dump file: %s", te->defn); else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0) - write_msg(modulename, "warning from original dump file: %s\n", te->copyStmt); + pg_log_warning("warning from original dump file: %s", te->copyStmt); } /* Work out what, if anything, we want from this entry */ @@ -767,10 +780,11 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) { /* Show namespace in log message if available */ if (te->namespace) - ahlog(AH, 1, "creating %s \"%s.%s\"\n", - te->desc, te->namespace, te->tag); + pg_log_info("creating %s \"%s.%s\"", + te->desc, te->namespace, te->tag); else - ahlog(AH, 1, "creating %s \"%s\"\n", te->desc, te->tag); + pg_log_info("creating %s \"%s\"", + te->desc, te->tag); _printTocEntry(AH, te, false); defnDumped = true; @@ -826,7 +840,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) appendConnStrVal(&connstr, te->tag); /* Abandon struct, but keep its buffer until process exit. */ - ahlog(AH, 1, "connecting to new database \"%s\"\n", te->tag); + pg_log_info("connecting to new database \"%s\"", te->tag); _reconnectToDB(AH, te->tag); ropt->dbname = connstr.data; } @@ -854,7 +868,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) if (strcmp(te->desc, "BLOBS") == 0 || strcmp(te->desc, "BLOB COMMENTS") == 0) { - ahlog(AH, 1, "processing %s\n", te->desc); + pg_log_info("processing %s", te->desc); _selectOutputSchema(AH, "pg_catalog"); @@ -874,8 +888,8 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); - ahlog(AH, 1, "processing data for table \"%s.%s\"\n", - te->namespace, te->tag); + pg_log_info("processing data for table \"%s.%s\"", + te->namespace, te->tag); /* * In parallel restore, if we created the table earlier in @@ -901,9 +915,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) ahprintf(AH, "TRUNCATE TABLE %s%s;\n\n", (PQserverVersion(AH->connection) >= 80400 ? "ONLY " : ""), - fmtQualifiedId(PQserverVersion(AH->connection), - te->namespace, - te->tag)); + fmtQualifiedId(te->namespace, te->tag)); } /* @@ -938,7 +950,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel) else if (!defnDumped) { /* If we haven't already dumped the defn part, do so now */ - ahlog(AH, 1, "executing %s %s\n", te->desc, te->tag); + pg_log_info("executing %s %s", te->desc, te->tag); _printTocEntry(AH, te, false); } } @@ -977,7 +989,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te) if (!ropt->dataOnly || !ropt->disable_triggers) return; - ahlog(AH, 1, "disabling triggers for %s\n", te->tag); + pg_log_info("disabling triggers for %s", te->tag); /* * Become superuser if possible, since they are the only ones who can @@ -991,9 +1003,7 @@ _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te) * Disable them. */ ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n", - fmtQualifiedId(PQserverVersion(AH->connection), - te->namespace, - te->tag)); + fmtQualifiedId(te->namespace, te->tag)); } static void @@ -1005,7 +1015,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te) if (!ropt->dataOnly || !ropt->disable_triggers) return; - ahlog(AH, 1, "enabling triggers for %s\n", te->tag); + pg_log_info("enabling triggers for %s", te->tag); /* * Become superuser if possible, since they are the only ones who can @@ -1019,9 +1029,7 @@ _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te) * Enable them. */ ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n", - fmtQualifiedId(PQserverVersion(AH->connection), - te->namespace, - te->tag)); + fmtQualifiedId(te->namespace, te->tag)); } /* @@ -1035,7 +1043,7 @@ WriteData(Archive *AHX, const void *data, size_t dLen) ArchiveHandle *AH = (ArchiveHandle *) AHX; if (!AH->currToc) - exit_horribly(modulename, "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n"); + fatal("internal error -- WriteData cannot be called outside the context of a DataDumper routine"); AH->WriteDataPtr(AH, data, dLen); @@ -1045,21 +1053,16 @@ WriteData(Archive *AHX, const void *data, size_t dLen) /* * Create a new TOC entry. The TOC was designed as a TOC, but is now the * repository for all metadata. But the name has stuck. + * + * The new entry is added to the Archive's TOC list. Most callers can ignore + * the result value because nothing else need be done, but a few want to + * manipulate the TOC entry further. */ /* Public */ -void -ArchiveEntry(Archive *AHX, - CatalogId catalogId, DumpId dumpId, - const char *tag, - const char *namespace, - const char *tablespace, - const char *owner, bool withOids, - const char *desc, teSection section, - const char *defn, - const char *dropStmt, const char *copyStmt, - const DumpId *deps, int nDeps, - DataDumperPtr dumpFn, void *dumpArg) +TocEntry * +ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId, + ArchiveOpts *opts) { ArchiveHandle *AH = (ArchiveHandle *) AHX; TocEntry *newToc; @@ -1077,23 +1080,23 @@ ArchiveEntry(Archive *AHX, newToc->catalogId = catalogId; newToc->dumpId = dumpId; - newToc->section = section; - - newToc->tag = pg_strdup(tag); - newToc->namespace = namespace ? pg_strdup(namespace) : NULL; - newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL; - newToc->owner = pg_strdup(owner); - newToc->withOids = withOids; - newToc->desc = pg_strdup(desc); - newToc->defn = pg_strdup(defn); - newToc->dropStmt = pg_strdup(dropStmt); - newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL; - - if (nDeps > 0) + newToc->section = opts->section; + + newToc->tag = pg_strdup(opts->tag); + newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL; + newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL; + newToc->tableam = opts->tableam ? pg_strdup(opts->tableam) : NULL; + newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL; + newToc->desc = pg_strdup(opts->description); + newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL; + newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL; + newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL; + + if (opts->nDeps > 0) { - newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId)); - memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId)); - newToc->nDeps = nDeps; + newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId)); + memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId)); + newToc->nDeps = opts->nDeps; } else { @@ -1101,14 +1104,17 @@ ArchiveEntry(Archive *AHX, newToc->nDeps = 0; } - newToc->dataDumper = dumpFn; - newToc->dataDumperArg = dumpArg; - newToc->hadDumper = dumpFn ? true : false; + newToc->dataDumper = opts->dumpFn; + newToc->dataDumperArg = opts->dumpArg; + newToc->hadDumper = opts->dumpFn ? true : false; newToc->formatData = NULL; + newToc->dataLength = 0; if (AH->ArchiveEntryPtr != NULL) AH->ArchiveEntryPtr(AH, newToc); + + return newToc; } /* Public */ @@ -1133,7 +1139,7 @@ PrintTOCSummary(Archive *AHX) ahprintf(AH, ";\n; Archive created at %s\n", stamp_str); ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n", - replace_line_endings(AH->archdbname), + sanitize_line(AH->archdbname, false), AH->tocCount, AH->compression); switch (AH->format) @@ -1178,21 +1184,10 @@ PrintTOCSummary(Archive *AHX) char *sanitized_owner; /* - * As in _printTocEntry(), sanitize strings that might contain - * newlines, to ensure that each logical output line is in fact - * one physical output line. This prevents confusion when the - * file is read by "pg_restore -L". Note that we currently don't - * bother to quote names, meaning that the name fields aren't - * automatically parseable. "pg_restore -L" doesn't care because - * it only examines the dumpId field, but someday we might want to - * try harder. */ - sanitized_name = replace_line_endings(te->tag); - if (te->namespace) - sanitized_schema = replace_line_endings(te->namespace); - else - sanitized_schema = pg_strdup("-"); - sanitized_owner = replace_line_endings(te->owner); + sanitized_name = sanitize_line(te->tag, false); + sanitized_schema = sanitize_line(te->namespace, true); + sanitized_owner = sanitize_line(te->owner, false); ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId, te->catalogId.tableoid, te->catalogId.oid, @@ -1233,7 +1228,7 @@ StartBlob(Archive *AHX, Oid oid) ArchiveHandle *AH = (ArchiveHandle *) AHX; if (!AH->StartBlobPtr) - exit_horribly(modulename, "large-object output not supported in chosen format\n"); + fatal("large-object output not supported in chosen format"); AH->StartBlobPtr(AH, AH->currToc, oid); @@ -1291,10 +1286,10 @@ EndRestoreBlobs(ArchiveHandle *AH) ahprintf(AH, "COMMIT;\n\n"); } - ahlog(AH, 1, ngettext("restored %d large object\n", - "restored %d large objects\n", - AH->blobCount), - AH->blobCount); + pg_log_info(ngettext("restored %d large object", + "restored %d large objects", + AH->blobCount), + AH->blobCount); } @@ -1312,7 +1307,7 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop) /* Initialize the LO Buffer */ AH->lo_buf_used = 0; - ahlog(AH, 1, "restoring large object with OID %u\n", oid); + pg_log_info("restoring large object with OID %u", oid); /* With an old archive we must do drop and create logic here */ if (old_blob_style && drop) @@ -1324,13 +1319,13 @@ StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop) { loOid = lo_create(AH->connection, oid); if (loOid == 0 || loOid != oid) - exit_horribly(modulename, "could not create large object %u: %s", - oid, PQerrorMessage(AH->connection)); + fatal("could not create large object %u: %s", + oid, PQerrorMessage(AH->connection)); } AH->loFd = lo_open(AH->connection, oid, INV_WRITE); if (AH->loFd == -1) - exit_horribly(modulename, "could not open large object %u: %s", - oid, PQerrorMessage(AH->connection)); + fatal("could not open large object %u: %s", + oid, PQerrorMessage(AH->connection)); } else { @@ -1381,14 +1376,12 @@ SortTocFromFile(Archive *AHX) bool incomplete_line; /* Allocate space for the 'wanted' array, and init it */ - ropt->idWanted = (bool *) pg_malloc(sizeof(bool) * AH->maxDumpId); - memset(ropt->idWanted, 0, sizeof(bool) * AH->maxDumpId); + ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId); /* Setup the file */ fh = fopen(ropt->tocFile, PG_BINARY_R); if (!fh) - exit_horribly(modulename, "could not open TOC file \"%s\": %s\n", - ropt->tocFile, strerror(errno)); + fatal("could not open TOC file \"%s\": %m", ropt->tocFile); incomplete_line = false; while (fgets(buf, sizeof(buf), fh) != NULL) @@ -1428,15 +1421,15 @@ SortTocFromFile(Archive *AHX) if (endptr == buf || id <= 0 || id > AH->maxDumpId || ropt->idWanted[id - 1]) { - write_msg(modulename, "WARNING: line ignored: %s\n", buf); + pg_log_warning("line ignored: %s", buf); continue; } /* Find TOC entry */ te = getTocEntryByDumpId(AH, id); if (!te) - exit_horribly(modulename, "could not find entry for ID %d\n", - id); + fatal("could not find entry for ID %d", + id); /* Mark it wanted */ ropt->idWanted[id - 1] = true; @@ -1456,8 +1449,7 @@ SortTocFromFile(Archive *AHX) } if (fclose(fh) != 0) - exit_horribly(modulename, "could not close TOC file: %s\n", - strerror(errno)); + fatal("could not close TOC file: %m"); } /********************** @@ -1477,6 +1469,7 @@ archputs(const char *s, Archive *AH) int archprintf(Archive *AH, const char *fmt,...) { + int save_errno = errno; char *p; size_t len = 128; /* initial assumption about buffer size */ size_t cnt; @@ -1489,6 +1482,7 @@ archprintf(Archive *AH, const char *fmt,...) p = (char *) pg_malloc(len); /* Try to format the data. */ + errno = save_errno; va_start(args, fmt); cnt = pvsnprintf(p, len, fmt, args); va_end(args); @@ -1517,7 +1511,12 @@ SetOutput(ArchiveHandle *AH, const char *filename, int compression) int fn; if (filename) - fn = -1; + { + if (strcmp(filename, "-") == 0) + fn = fileno(stdout); + else + fn = -1; + } else if (AH->FH) fn = fileno(AH->FH); else if (AH->fSpec) @@ -1565,11 +1564,9 @@ SetOutput(ArchiveHandle *AH, const char *filename, int compression) if (!AH->OF) { if (filename) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - filename, strerror(errno)); + fatal("could not open output file \"%s\": %m", filename); else - exit_horribly(modulename, "could not open output file: %s\n", - strerror(errno)); + fatal("could not open output file: %m"); } } @@ -1595,8 +1592,7 @@ RestoreOutput(ArchiveHandle *AH, OutputContext savedContext) res = fclose(AH->OF); if (res != 0) - exit_horribly(modulename, "could not close output file: %s\n", - strerror(errno)); + fatal("could not close output file: %m"); AH->gzOut = savedContext.gzOut; AH->OF = savedContext.OF; @@ -1610,6 +1606,7 @@ RestoreOutput(ArchiveHandle *AH, OutputContext savedContext) int ahprintf(ArchiveHandle *AH, const char *fmt,...) { + int save_errno = errno; char *p; size_t len = 128; /* initial assumption about buffer size */ size_t cnt; @@ -1622,6 +1619,7 @@ ahprintf(ArchiveHandle *AH, const char *fmt,...) p = (char *) pg_malloc(len); /* Try to format the data. */ + errno = save_errno; va_start(args, fmt); cnt = pvsnprintf(p, len, fmt, args); va_end(args); @@ -1639,19 +1637,6 @@ ahprintf(ArchiveHandle *AH, const char *fmt,...) return (int) cnt; } -void -ahlog(ArchiveHandle *AH, int level, const char *fmt,...) -{ - va_list ap; - - if (AH->debugLevel < level && (!AH->public.verbose || level > 1)) - return; - - va_start(ap, fmt); - vwrite_msg(NULL, fmt, ap); - va_end(ap); -} - /* * Single place for logic which says 'We are restoring to a direct DB connection'. */ @@ -1674,14 +1659,13 @@ dump_lo_buf(ArchiveHandle *AH) size_t res; res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used); - ahlog(AH, 5, ngettext("wrote %lu byte of large object data (result = %lu)\n", - "wrote %lu bytes of large object data (result = %lu)\n", + pg_log_debug(ngettext("wrote %lu byte of large object data (result = %lu)", + "wrote %lu bytes of large object data (result = %lu)", AH->lo_buf_used), - (unsigned long) AH->lo_buf_used, (unsigned long) res); + (unsigned long) AH->lo_buf_used, (unsigned long) res); if (res != AH->lo_buf_used) - exit_horribly(modulename, - "could not write to large object (result: %lu, expected: %lu)\n", - (unsigned long) res, (unsigned long) AH->lo_buf_used); + fatal("could not write to large object (result: %lu, expected: %lu)", + (unsigned long) res, (unsigned long) AH->lo_buf_used); } else { @@ -1759,8 +1743,7 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH) /* on some error, we may decide to go on... */ void -warn_or_exit_horribly(ArchiveHandle *AH, - const char *modulename, const char *fmt,...) +warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...) { va_list ap; @@ -1773,31 +1756,34 @@ warn_or_exit_horribly(ArchiveHandle *AH, case STAGE_INITIALIZING: if (AH->stage != AH->lastErrorStage) - write_msg(modulename, "Error while INITIALIZING:\n"); + pg_log_generic(PG_LOG_INFO, "while INITIALIZING:"); break; case STAGE_PROCESSING: if (AH->stage != AH->lastErrorStage) - write_msg(modulename, "Error while PROCESSING TOC:\n"); + pg_log_generic(PG_LOG_INFO, "while PROCESSING TOC:"); break; case STAGE_FINALIZING: if (AH->stage != AH->lastErrorStage) - write_msg(modulename, "Error while FINALIZING:\n"); + pg_log_generic(PG_LOG_INFO, "while FINALIZING:"); break; } if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE) { - write_msg(modulename, "Error from TOC entry %d; %u %u %s %s %s\n", - AH->currentTE->dumpId, - AH->currentTE->catalogId.tableoid, AH->currentTE->catalogId.oid, - AH->currentTE->desc, AH->currentTE->tag, AH->currentTE->owner); + pg_log_generic(PG_LOG_INFO, "from TOC entry %d; %u %u %s %s %s", + AH->currentTE->dumpId, + AH->currentTE->catalogId.tableoid, + AH->currentTE->catalogId.oid, + AH->currentTE->desc ? AH->currentTE->desc : "(no desc)", + AH->currentTE->tag ? AH->currentTE->tag : "(no tag)", + AH->currentTE->owner ? AH->currentTE->owner : "(no owner)"); } AH->lastErrorStage = AH->stage; AH->lastErrorTE = AH->currentTE; va_start(ap, fmt); - vwrite_msg(modulename, fmt, ap); + pg_log_generic_v(PG_LOG_ERROR, fmt, ap); va_end(ap); if (AH->public.exit_on_error) @@ -1861,7 +1847,7 @@ buildTocEntryArrays(ArchiveHandle *AH) { /* this check is purely paranoia, maxDumpId should be correct */ if (te->dumpId <= 0 || te->dumpId > maxDumpId) - exit_horribly(modulename, "bad dumpId\n"); + fatal("bad dumpId"); /* tocsByDumpId indexes all TOCs by their dump ID */ AH->tocsByDumpId[te->dumpId] = te; @@ -1882,7 +1868,7 @@ buildTocEntryArrays(ArchiveHandle *AH) * item's dump ID, so there should be a place for it in the array. */ if (tableId <= 0 || tableId > maxDumpId) - exit_horribly(modulename, "bad table dumpId for TABLE DATA item\n"); + fatal("bad table dumpId for TABLE DATA item"); AH->tableDataId[tableId] = te->dumpId; } @@ -1974,7 +1960,7 @@ ReadOffset(ArchiveHandle *AH, pgoff_t * o) break; default: - exit_horribly(modulename, "unexpected data offset flag %d\n", offsetFlg); + fatal("unexpected data offset flag %d", offsetFlg); } /* @@ -1987,7 +1973,7 @@ ReadOffset(ArchiveHandle *AH, pgoff_t * o) else { if (AH->ReadBytePtr(AH) != 0) - exit_horribly(modulename, "file offset in dump file is too large\n"); + fatal("file offset in dump file is too large"); } } @@ -2003,7 +1989,7 @@ WriteInt(ArchiveHandle *AH, int i) * This is a bit yucky, but I don't want to make the binary format very * dependent on representation, and not knowing much about it, I write out * a sign byte. If you change this, don't forget to change the file - * version #, and modify readInt to read the new format AS WELL AS the old + * version #, and modify ReadInt to read the new format AS WELL AS the old * formats. */ @@ -2099,9 +2085,7 @@ _discoverArchiveFormat(ArchiveHandle *AH) size_t cnt; int wantClose = 0; -#if 0 - write_msg(modulename, "attempting to ascertain archive format\n"); -#endif + pg_log_debug("attempting to ascertain archive format"); if (AH->lookahead) free(AH->lookahead); @@ -2126,8 +2110,8 @@ _discoverArchiveFormat(ArchiveHandle *AH) char buf[MAXPGPATH]; if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH) - exit_horribly(modulename, "directory name too long: \"%s\"\n", - AH->fSpec); + fatal("directory name too long: \"%s\"", + AH->fSpec); if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) { AH->format = archDirectory; @@ -2136,41 +2120,39 @@ _discoverArchiveFormat(ArchiveHandle *AH) #ifdef HAVE_LIBZ if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH) - exit_horribly(modulename, "directory name too long: \"%s\"\n", - AH->fSpec); + fatal("directory name too long: \"%s\"", + AH->fSpec); if (stat(buf, &st) == 0 && S_ISREG(st.st_mode)) { AH->format = archDirectory; return AH->format; } #endif - exit_horribly(modulename, "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n", - AH->fSpec); + fatal("directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)", + AH->fSpec); fh = NULL; /* keep compiler quiet */ } else { fh = fopen(AH->fSpec, PG_BINARY_R); if (!fh) - exit_horribly(modulename, "could not open input file \"%s\": %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open input file \"%s\": %m", AH->fSpec); } } else { fh = stdin; if (!fh) - exit_horribly(modulename, "could not open input file: %s\n", - strerror(errno)); + fatal("could not open input file: %m"); } if ((cnt = fread(sig, 1, 5, fh)) != 5) { if (ferror(fh)) - exit_horribly(modulename, "could not read input file: %s\n", strerror(errno)); + fatal("could not read input file: %m"); else - exit_horribly(modulename, "input file is too short (read %lu, expected 5)\n", - (unsigned long) cnt); + fatal("input file is too short (read %lu, expected 5)", + (unsigned long) cnt); } /* Save it, just in case we need it later */ @@ -2254,19 +2236,19 @@ _discoverArchiveFormat(ArchiveHandle *AH) * looks like it's probably a text format dump. so suggest they * try psql */ - exit_horribly(modulename, "input file appears to be a text format dump. Please use psql.\n"); + fatal("input file appears to be a text format dump. Please use psql."); } if (AH->lookaheadLen != 512) { if (feof(fh)) - exit_horribly(modulename, "input file does not appear to be a valid archive (too short?)\n"); + fatal("input file does not appear to be a valid archive (too short?)"); else READ_ERROR_EXIT(fh); } if (!isValidTarHeader(AH->lookahead)) - exit_horribly(modulename, "input file does not appear to be a valid archive\n"); + fatal("input file does not appear to be a valid archive"); AH->format = archTar; } @@ -2286,8 +2268,7 @@ _discoverArchiveFormat(ArchiveHandle *AH) /* Close the file */ if (wantClose) if (fclose(fh) != 0) - exit_horribly(modulename, "could not close input file: %s\n", - strerror(errno)); + fatal("could not close input file: %m"); return AH->format; } @@ -2303,14 +2284,10 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, { ArchiveHandle *AH; -#if 0 - write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt); -#endif + pg_log_debug("allocating AH for %s, format %d", FileSpec, fmt); AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle)); - /* AH->debugLevel = 100; */ - AH->version = K_VERS_SELF; /* initialize for backwards compatible string processing */ @@ -2344,7 +2321,7 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, AH->currUser = NULL; /* unknown */ AH->currSchema = NULL; /* ditto */ AH->currTablespace = NULL; /* ditto */ - AH->currWithOids = -1; /* force SET */ + AH->currTableAm = NULL; /* ditto */ AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry)); @@ -2405,7 +2382,7 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt, break; default: - exit_horribly(modulename, "unrecognized file format \"%d\"\n", fmt); + fatal("unrecognized file format \"%d\"", fmt); } return AH; @@ -2419,32 +2396,59 @@ WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate) { TocEntry *te; - for (te = AH->toc->next; te != AH->toc; te = te->next) + if (pstate && pstate->numWorkers > 1) { - if (!te->dataDumper) - continue; - - if ((te->reqs & REQ_DATA) == 0) - continue; + /* + * In parallel mode, this code runs in the master process. We + * construct an array of candidate TEs, then sort it into decreasing + * size order, then dispatch each TE to a data-transfer worker. By + * dumping larger tables first, we avoid getting into a situation + * where we're down to one job and it's big, losing parallelism. + */ + TocEntry **tes; + int ntes; - if (pstate && pstate->numWorkers > 1) + tes = (TocEntry **) pg_malloc(AH->tocCount * sizeof(TocEntry *)); + ntes = 0; + for (te = AH->toc->next; te != AH->toc; te = te->next) { - /* - * If we are in a parallel backup, then we are always the master - * process. Dispatch each data-transfer job to a worker. - */ - DispatchJobForTocEntry(AH, pstate, te, ACT_DUMP, - mark_dump_job_done, NULL); + /* Consider only TEs with dataDumper functions ... */ + if (!te->dataDumper) + continue; + /* ... and ignore ones not enabled for dump */ + if ((te->reqs & REQ_DATA) == 0) + continue; + + tes[ntes++] = te; } - else - WriteDataChunksForTocEntry(AH, te); - } - /* - * If parallel, wait for workers to finish. - */ - if (pstate && pstate->numWorkers > 1) + if (ntes > 1) + qsort((void *) tes, ntes, sizeof(TocEntry *), + TocEntrySizeCompare); + + for (int i = 0; i < ntes; i++) + DispatchJobForTocEntry(AH, pstate, tes[i], ACT_DUMP, + mark_dump_job_done, NULL); + + pg_free(tes); + + /* Now wait for workers to finish. */ WaitForWorkers(AH, pstate, WFW_ALL_IDLE); + } + else + { + /* Non-parallel mode: just dump all candidate TEs sequentially. */ + for (te = AH->toc->next; te != AH->toc; te = te->next) + { + /* Must have same filter conditions as above */ + if (!te->dataDumper) + continue; + if ((te->reqs & REQ_DATA) == 0) + continue; + + WriteDataChunksForTocEntry(AH, te); + } + } } @@ -2460,12 +2464,12 @@ mark_dump_job_done(ArchiveHandle *AH, int status, void *callback_data) { - ahlog(AH, 1, "finished item %d %s %s\n", - te->dumpId, te->desc, te->tag); + pg_log_info("finished item %d %s %s", + te->dumpId, te->desc, te->tag); if (status != 0) - exit_horribly(modulename, "worker process failed: exit code %d\n", - status); + fatal("worker process failed: exit code %d", + status); } @@ -2544,8 +2548,9 @@ WriteToc(ArchiveHandle *AH) WriteStr(AH, te->copyStmt); WriteStr(AH, te->namespace); WriteStr(AH, te->tablespace); + WriteStr(AH, te->tableam); WriteStr(AH, te->owner); - WriteStr(AH, te->withOids ? "true" : "false"); + WriteStr(AH, "false"); /* Dump list of dependencies */ for (i = 0; i < te->nDeps; i++) @@ -2583,9 +2588,8 @@ ReadToc(ArchiveHandle *AH) /* Sanity check */ if (te->dumpId <= 0) - exit_horribly(modulename, - "entry ID %d out of range -- perhaps a corrupt TOC\n", - te->dumpId); + fatal("entry ID %d out of range -- perhaps a corrupt TOC", + te->dumpId); te->hadDumper = ReadInt(AH); @@ -2646,16 +2650,12 @@ ReadToc(ArchiveHandle *AH) if (AH->version >= K_VERS_1_10) te->tablespace = ReadStr(AH); + if (AH->version >= K_VERS_1_14) + te->tableam = ReadStr(AH); + te->owner = ReadStr(AH); - if (AH->version >= K_VERS_1_9) - { - if (strcmp(ReadStr(AH), "true") == 0) - te->withOids = true; - else - te->withOids = false; - } - else - te->withOids = true; + if (AH->version < K_VERS_1_9 || strcmp(ReadStr(AH), "true") == 0) + pg_log_warning("restoring tables WITH OIDS is not supported anymore"); /* Read TOC entry dependencies */ if (AH->version >= K_VERS_1_5) @@ -2696,12 +2696,13 @@ ReadToc(ArchiveHandle *AH) te->dependencies = NULL; te->nDeps = 0; } + te->dataLength = 0; if (AH->ReadExtraTocPtr) AH->ReadExtraTocPtr(AH, te); - ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n", - i, te->dumpId, te->desc, te->tag); + pg_log_debug("read TOC entry %d (ID %d) for %s %s", + i, te->dumpId, te->desc, te->tag); /* link completed entry into TOC circular list */ te->prev = AH->toc->prev; @@ -2736,13 +2737,13 @@ processEncodingEntry(ArchiveHandle *AH, TocEntry *te) *ptr2 = '\0'; encoding = pg_char_to_encoding(ptr1); if (encoding < 0) - exit_horribly(modulename, "unrecognized encoding \"%s\"\n", - ptr1); + fatal("unrecognized encoding \"%s\"", + ptr1); AH->public.encoding = encoding; } else - exit_horribly(modulename, "invalid ENCODING item: %s\n", - te->defn); + fatal("invalid ENCODING item: %s", + te->defn); free(defn); } @@ -2759,8 +2760,8 @@ processStdStringsEntry(ArchiveHandle *AH, TocEntry *te) else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0) AH->public.std_strings = false; else - exit_horribly(modulename, "invalid STDSTRINGS item: %s\n", - te->defn); + fatal("invalid STDSTRINGS item: %s", + te->defn); } static void @@ -2784,35 +2785,35 @@ StrictNamesCheck(RestoreOptions *ropt) { missing_name = simple_string_list_not_touched(&ropt->schemaNames); if (missing_name != NULL) - exit_horribly(modulename, "schema \"%s\" not found\n", missing_name); + fatal("schema \"%s\" not found", missing_name); } if (ropt->tableNames.head != NULL) { missing_name = simple_string_list_not_touched(&ropt->tableNames); if (missing_name != NULL) - exit_horribly(modulename, "table \"%s\" not found\n", missing_name); + fatal("table \"%s\" not found", missing_name); } if (ropt->indexNames.head != NULL) { missing_name = simple_string_list_not_touched(&ropt->indexNames); if (missing_name != NULL) - exit_horribly(modulename, "index \"%s\" not found\n", missing_name); + fatal("index \"%s\" not found", missing_name); } if (ropt->functionNames.head != NULL) { missing_name = simple_string_list_not_touched(&ropt->functionNames); if (missing_name != NULL) - exit_horribly(modulename, "function \"%s\" not found\n", missing_name); + fatal("function \"%s\" not found", missing_name); } if (ropt->triggerNames.head != NULL) { missing_name = simple_string_list_not_touched(&ropt->triggerNames); if (missing_name != NULL) - exit_horribly(modulename, "trigger \"%s\" not found\n", missing_name); + fatal("trigger \"%s\" not found", missing_name); } } @@ -2861,8 +2862,13 @@ _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH) if (ropt->no_comments && strcmp(te->desc, "COMMENT") == 0) return 0; - /* If it's a publication, maybe ignore it */ - if (ropt->no_publications && strcmp(te->desc, "PUBLICATION") == 0) + /* + * If it's a publication or a table part of a publication, maybe ignore + * it. + */ + if (ropt->no_publications && + (strcmp(te->desc, "PUBLICATION") == 0 || + strcmp(te->desc, "PUBLICATION TABLE") == 0)) return 0; /* If it's a security label, maybe ignore it */ @@ -3140,6 +3146,9 @@ _doSetFixedOutputState(ArchiveHandle *AH) /* Make sure function checking is disabled */ ahprintf(AH, "SET check_function_bodies = false;\n"); + /* Ensure that all valid XML data will be accepted */ + ahprintf(AH, "SET xmloption = content;\n"); + /* Avoid annoying notices etc */ ahprintf(AH, "SET client_min_messages = warning;\n"); if (!AH->public.std_strings) @@ -3183,40 +3192,8 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user) if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) /* NOT warn_or_exit_horribly... use -O instead to skip this. */ - exit_horribly(modulename, "could not set session user to \"%s\": %s", - user, PQerrorMessage(AH->connection)); - - PQclear(res); - } - else - ahprintf(AH, "%s\n\n", cmd->data); - - destroyPQExpBuffer(cmd); -} - - -/* - * Issue a SET default_with_oids command. Caller is responsible - * for updating state if appropriate. - */ -static void -_doSetWithOids(ArchiveHandle *AH, const bool withOids) -{ - PQExpBuffer cmd = createPQExpBuffer(); - - appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ? - "true" : "false"); - - if (RestoringToDB(AH)) - { - PGresult *res; - - res = PQexec(AH->connection, cmd->data); - - if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) - warn_or_exit_horribly(AH, modulename, - "could not set default_with_oids: %s", - PQerrorMessage(AH->connection)); + fatal("could not set session user to \"%s\": %s", + user, PQerrorMessage(AH->connection)); PQclear(res); } @@ -3271,7 +3248,6 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname) if (AH->currTablespace) free(AH->currTablespace); AH->currTablespace = NULL; - AH->currWithOids = -1; /* re-establish fixed state */ _doSetFixedOutputState(AH); @@ -3318,20 +3294,6 @@ _becomeOwner(ArchiveHandle *AH, TocEntry *te) } -/* - * Set the proper default_with_oids value for the table. - */ -static void -_setWithOids(ArchiveHandle *AH, TocEntry *te) -{ - if (AH->currWithOids != te->withOids) - { - _doSetWithOids(AH, te->withOids); - AH->currWithOids = te->withOids; - } -} - - /* * Issue the commands to select the specified schema as the current schema * in the target database. @@ -3368,7 +3330,7 @@ _selectOutputSchema(ArchiveHandle *AH, const char *schemaName) res = PQexec(AH->connection, qry->data); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) - warn_or_exit_horribly(AH, modulename, + warn_or_exit_horribly(AH, "could not set search_path to \"%s\": %s", schemaName, PQerrorMessage(AH->connection)); @@ -3430,7 +3392,7 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace) res = PQexec(AH->connection, qry->data); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) - warn_or_exit_horribly(AH, modulename, + warn_or_exit_horribly(AH, "could not set default_tablespace to %s: %s", fmtId(want), PQerrorMessage(AH->connection)); @@ -3446,6 +3408,49 @@ _selectTablespace(ArchiveHandle *AH, const char *tablespace) destroyPQExpBuffer(qry); } +/* + * Set the proper default_table_access_method value for the table. + */ +static void +_selectTableAccessMethod(ArchiveHandle *AH, const char *tableam) +{ + PQExpBuffer cmd; + const char *want, + *have; + + have = AH->currTableAm; + want = tableam; + + if (!want) + return; + + if (have && strcmp(want, have) == 0) + return; + + cmd = createPQExpBuffer(); + appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want)); + + if (RestoringToDB(AH)) + { + PGresult *res; + + res = PQexec(AH->connection, cmd->data); + + if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) + warn_or_exit_horribly(AH, + "could not set default_table_access_method: %s", + PQerrorMessage(AH->connection)); + + PQclear(res); + } + else + ahprintf(AH, "%s\n\n", cmd->data); + + destroyPQExpBuffer(cmd); + + AH->currTableAm = pg_strdup(want); +} + /* * Extract an object description for a TOC entry, and append it to buf. * @@ -3525,8 +3530,8 @@ _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH) return; } - write_msg(modulename, "WARNING: don't know how to set owner for object type \"%s\"\n", - type); + pg_log_warning("don't know how to set owner for object type \"%s\"", + type); } /* @@ -3541,14 +3546,11 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) { RestoreOptions *ropt = AH->public.ropt; - /* Select owner, schema, and tablespace as necessary */ + /* Select owner, schema, tablespace and default AM as necessary */ _becomeOwner(AH, te); _selectOutputSchema(AH, te->namespace); _selectTablespace(AH, te->tablespace); - - /* Set up OID mode too */ - if (strcmp(te->desc, "TABLE") == 0) - _setWithOids(AH, te); + _selectTableAccessMethod(AH, te->tableam); /* Emit header comment for item */ if (!AH->noTocComments) @@ -3579,21 +3581,9 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) } } - /* - * Zap any line endings embedded in user-supplied fields, to prevent - * corruption of the dump (which could, in the worst case, present an - * SQL injection vulnerability if someone were to incautiously load a - * dump containing objects with maliciously crafted names). - */ - sanitized_name = replace_line_endings(te->tag); - if (te->namespace) - sanitized_schema = replace_line_endings(te->namespace); - else - sanitized_schema = pg_strdup("-"); - if (!ropt->noOwner) - sanitized_owner = replace_line_endings(te->owner); - else - sanitized_owner = pg_strdup("-"); + sanitized_name = sanitize_line(te->tag, false); + sanitized_schema = sanitize_line(te->namespace, true); + sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true); ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s", pfx, sanitized_name, te->desc, sanitized_schema, @@ -3607,7 +3597,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) { char *sanitized_tablespace; - sanitized_tablespace = replace_line_endings(te->tablespace); + sanitized_tablespace = sanitize_line(te->tablespace, false); ahprintf(AH, "; Tablespace: %s", sanitized_tablespace); free(sanitized_tablespace); } @@ -3631,7 +3621,7 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) } else { - if (strlen(te->defn) > 0) + if (te->defn && strlen(te->defn) > 0) ahprintf(AH, "%s\n\n", te->defn); } @@ -3642,7 +3632,8 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) * with DROP commands must appear in one list or the other. */ if (!ropt->noOwner && !ropt->use_setsessauth && - strlen(te->owner) > 0 && strlen(te->dropStmt) > 0) + te->owner && strlen(te->owner) > 0 && + te->dropStmt && strlen(te->dropStmt) > 0) { if (strcmp(te->desc, "AGGREGATE") == 0 || strcmp(te->desc, "BLOB") == 0 || @@ -3697,8 +3688,8 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) } else { - write_msg(modulename, "WARNING: don't know how to set owner for object type \"%s\"\n", - te->desc); + pg_log_warning("don't know how to set owner for object type \"%s\"", + te->desc); } } @@ -3715,16 +3706,30 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData) } /* - * Sanitize a string to be included in an SQL comment or TOC listing, - * by replacing any newlines with spaces. - * The result is a freshly malloc'd string. + * Sanitize a string to be included in an SQL comment or TOC listing, by + * replacing any newlines with spaces. This ensures each logical output line + * is in fact one physical output line, to prevent corruption of the dump + * (which could, in the worst case, present an SQL injection vulnerability + * if someone were to incautiously load a dump containing objects with + * maliciously crafted names). + * + * The result is a freshly malloc'd string. If the input string is NULL, + * return a malloc'ed empty string, unless want_hyphen, in which case return a + * malloc'ed hyphen. + * + * Note that we currently don't bother to quote names, meaning that the name + * fields aren't automatically parseable. "pg_restore -L" doesn't care because + * it only examines the dumpId field, but someday we might want to try harder. */ static char * -replace_line_endings(const char *str) +sanitize_line(const char *str, bool want_hyphen) { char *result; char *s; + if (!str) + return pg_strdup(want_hyphen ? "-" : ""); + result = pg_strdup(str); for (s = result; *s != '\0'; s++) @@ -3787,7 +3792,7 @@ ReadHead(ArchiveHandle *AH) AH->ReadBufPtr(AH, tmpMag, 5); if (strncmp(tmpMag, "PGDMP", 5) != 0) - exit_horribly(modulename, "did not find magic string in file header\n"); + fatal("did not find magic string in file header"); vmaj = AH->ReadBytePtr(AH); vmin = AH->ReadBytePtr(AH); @@ -3800,16 +3805,16 @@ ReadHead(ArchiveHandle *AH) AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev); if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX) - exit_horribly(modulename, "unsupported version (%d.%d) in file header\n", - vmaj, vmin); + fatal("unsupported version (%d.%d) in file header", + vmaj, vmin); AH->intSize = AH->ReadBytePtr(AH); if (AH->intSize > 32) - exit_horribly(modulename, "sanity check on integer size (%lu) failed\n", - (unsigned long) AH->intSize); + fatal("sanity check on integer size (%lu) failed", + (unsigned long) AH->intSize); if (AH->intSize > sizeof(int)) - write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n"); + pg_log_warning("archive was made on a machine with larger integers, some operations might fail"); if (AH->version >= K_VERS_1_7) AH->offSize = AH->ReadBytePtr(AH); @@ -3819,8 +3824,8 @@ ReadHead(ArchiveHandle *AH) fmt = AH->ReadBytePtr(AH); if (AH->format != fmt) - exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n", - AH->format, fmt); + fatal("expected format (%d) differs from format found in file (%d)", + AH->format, fmt); } if (AH->version >= K_VERS_1_2) @@ -3835,7 +3840,7 @@ ReadHead(ArchiveHandle *AH) #ifndef HAVE_LIBZ if (AH->compression != 0) - write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n"); + pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available"); #endif if (AH->version >= K_VERS_1_4) @@ -3853,7 +3858,7 @@ ReadHead(ArchiveHandle *AH) AH->createDate = mktime(&crtm); if (AH->createDate == (time_t) -1) - write_msg(modulename, "WARNING: invalid creation date in header\n"); + pg_log_warning("invalid creation date in header"); } if (AH->version >= K_VERS_1_10) @@ -3926,7 +3931,7 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list) bool skipped_some; TocEntry *next_work_item; - ahlog(AH, 2, "entering restore_toc_entries_prefork\n"); + pg_log_debug("entering restore_toc_entries_prefork"); /* Adjust dependency information */ fix_dependencies(AH); @@ -3990,9 +3995,9 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list) if (do_now) { /* OK, restore the item and update its dependencies */ - ahlog(AH, 1, "processing item %d %s %s\n", - next_work_item->dumpId, - next_work_item->desc, next_work_item->tag); + pg_log_info("processing item %d %s %s", + next_work_item->dumpId, + next_work_item->desc, next_work_item->tag); (void) restore_toc_entry(AH, next_work_item, false); @@ -4002,7 +4007,7 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list) else { /* Nope, so add it to pending_list */ - par_list_append(pending_list, next_work_item); + pending_list_append(pending_list, next_work_item); } } @@ -4023,7 +4028,9 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list) if (AH->currTablespace) free(AH->currTablespace); AH->currTablespace = NULL; - AH->currWithOids = -1; + if (AH->currTableAm) + free(AH->currTableAm); + AH->currTableAm = NULL; } /* @@ -4041,10 +4048,13 @@ static void restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list) { - TocEntry ready_list; + ParallelReadyList ready_list; TocEntry *next_work_item; - ahlog(AH, 2, "entering restore_toc_entries_parallel\n"); + pg_log_debug("entering restore_toc_entries_parallel"); + + /* Set up ready_list with enough room for all known TocEntrys */ + ready_list_init(&ready_list, AH->tocCount); /* * The pending_list contains all items that we need to restore. Move all @@ -4054,7 +4064,6 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate, * contains items that have no remaining dependencies and are OK to * process in the current restore pass. */ - par_list_header_init(&ready_list); AH->restorePass = RESTORE_PASS_MAIN; move_to_ready_list(pending_list, &ready_list, AH->restorePass); @@ -4065,34 +4074,31 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate, * left to be done. Note invariant: at top of loop, there should always * be at least one worker available to dispatch a job to. */ - ahlog(AH, 1, "entering main parallel loop\n"); + pg_log_info("entering main parallel loop"); for (;;) { /* Look for an item ready to be dispatched to a worker */ - next_work_item = get_next_work_item(AH, &ready_list, pstate); + next_work_item = pop_next_work_item(AH, &ready_list, pstate); if (next_work_item != NULL) { /* If not to be restored, don't waste time launching a worker */ if ((next_work_item->reqs & (REQ_SCHEMA | REQ_DATA)) == 0) { - ahlog(AH, 1, "skipping item %d %s %s\n", - next_work_item->dumpId, - next_work_item->desc, next_work_item->tag); - /* Drop it from ready_list, and update its dependencies */ - par_list_remove(next_work_item); + pg_log_info("skipping item %d %s %s", + next_work_item->dumpId, + next_work_item->desc, next_work_item->tag); + /* Update its dependencies as though we'd completed it */ reduce_dependencies(AH, next_work_item, &ready_list); /* Loop around to see if anything else can be dispatched */ continue; } - ahlog(AH, 1, "launching item %d %s %s\n", - next_work_item->dumpId, - next_work_item->desc, next_work_item->tag); - - /* Remove it from ready_list, and dispatch to some worker */ - par_list_remove(next_work_item); + pg_log_info("launching item %d %s %s", + next_work_item->dumpId, + next_work_item->desc, next_work_item->tag); + /* Dispatch to some worker */ DispatchJobForTocEntry(AH, pstate, next_work_item, ACT_RESTORE, mark_restore_job_done, &ready_list); } @@ -4138,9 +4144,11 @@ restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate, } /* There should now be nothing in ready_list. */ - Assert(ready_list.par_next == &ready_list); + Assert(ready_list.first_te > ready_list.last_te); + + ready_list_free(&ready_list); - ahlog(AH, 1, "finished main parallel loop\n"); + pg_log_info("finished main parallel loop"); } /* @@ -4158,7 +4166,7 @@ restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list) RestoreOptions *ropt = AH->public.ropt; TocEntry *te; - ahlog(AH, 2, "entering restore_toc_entries_postfork\n"); + pg_log_debug("entering restore_toc_entries_postfork"); /* * Now reconnect the single parent connection. @@ -4176,10 +4184,10 @@ restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list) * connection. We don't sweat about RestorePass ordering; it's likely we * already violated that. */ - for (te = pending_list->par_next; te != pending_list; te = te->par_next) + for (te = pending_list->pending_next; te != pending_list; te = te->pending_next) { - ahlog(AH, 1, "processing missed item %d %s %s\n", - te->dumpId, te->desc, te->tag); + pg_log_info("processing missed item %d %s %s", + te->dumpId, te->desc, te->tag); (void) restore_toc_entry(AH, te, false); } } @@ -4207,36 +4215,130 @@ has_lock_conflicts(TocEntry *te1, TocEntry *te2) /* - * Initialize the header of a parallel-processing list. + * Initialize the header of the pending-items list. * - * These are circular lists with a dummy TocEntry as header, just like the + * This is a circular list with a dummy TocEntry as header, just like the * main TOC list; but we use separate list links so that an entry can be in - * the main TOC list as well as in a parallel-processing list. + * the main TOC list as well as in the pending list. + */ +static void +pending_list_header_init(TocEntry *l) +{ + l->pending_prev = l->pending_next = l; +} + +/* Append te to the end of the pending-list headed by l */ +static void +pending_list_append(TocEntry *l, TocEntry *te) +{ + te->pending_prev = l->pending_prev; + l->pending_prev->pending_next = te; + l->pending_prev = te; + te->pending_next = l; +} + +/* Remove te from the pending-list */ +static void +pending_list_remove(TocEntry *te) +{ + te->pending_prev->pending_next = te->pending_next; + te->pending_next->pending_prev = te->pending_prev; + te->pending_prev = NULL; + te->pending_next = NULL; +} + + +/* + * Initialize the ready_list with enough room for up to tocCount entries. + */ +static void +ready_list_init(ParallelReadyList *ready_list, int tocCount) +{ + ready_list->tes = (TocEntry **) + pg_malloc(tocCount * sizeof(TocEntry *)); + ready_list->first_te = 0; + ready_list->last_te = -1; + ready_list->sorted = false; +} + +/* + * Free storage for a ready_list. */ static void -par_list_header_init(TocEntry *l) +ready_list_free(ParallelReadyList *ready_list) +{ + pg_free(ready_list->tes); +} + +/* Add te to the ready_list */ +static void +ready_list_insert(ParallelReadyList *ready_list, TocEntry *te) { - l->par_prev = l->par_next = l; + ready_list->tes[++ready_list->last_te] = te; + /* List is (probably) not sorted anymore. */ + ready_list->sorted = false; } -/* Append te to the end of the parallel-processing list headed by l */ +/* Remove the i'th entry in the ready_list */ static void -par_list_append(TocEntry *l, TocEntry *te) +ready_list_remove(ParallelReadyList *ready_list, int i) { - te->par_prev = l->par_prev; - l->par_prev->par_next = te; - l->par_prev = te; - te->par_next = l; + int f = ready_list->first_te; + + Assert(i >= f && i <= ready_list->last_te); + + /* + * In the typical case where the item to be removed is the first ready + * entry, we need only increment first_te to remove it. Otherwise, move + * the entries before it to compact the list. (This preserves sortedness, + * if any.) We could alternatively move the entries after i, but there + * are typically many more of those. + */ + if (i > f) + { + TocEntry **first_te_ptr = &ready_list->tes[f]; + + memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *)); + } + ready_list->first_te++; } -/* Remove te from whatever parallel-processing list it's in */ +/* Sort the ready_list into the desired order */ static void -par_list_remove(TocEntry *te) +ready_list_sort(ParallelReadyList *ready_list) +{ + if (!ready_list->sorted) + { + int n = ready_list->last_te - ready_list->first_te + 1; + + if (n > 1) + qsort(ready_list->tes + ready_list->first_te, n, + sizeof(TocEntry *), + TocEntrySizeCompare); + ready_list->sorted = true; + } +} + +/* qsort comparator for sorting TocEntries by dataLength */ +static int +TocEntrySizeCompare(const void *p1, const void *p2) { - te->par_prev->par_next = te->par_next; - te->par_next->par_prev = te->par_prev; - te->par_prev = NULL; - te->par_next = NULL; + const TocEntry *te1 = *(const TocEntry *const *) p1; + const TocEntry *te2 = *(const TocEntry *const *) p2; + + /* Sort by decreasing dataLength */ + if (te1->dataLength > te2->dataLength) + return -1; + if (te1->dataLength < te2->dataLength) + return 1; + + /* For equal dataLengths, sort by dumpId, just to be stable */ + if (te1->dumpId < te2->dumpId) + return -1; + if (te1->dumpId > te2->dumpId) + return 1; + + return 0; } @@ -4248,77 +4350,55 @@ par_list_remove(TocEntry *te) * which applies the same logic one-at-a-time.) */ static void -move_to_ready_list(TocEntry *pending_list, TocEntry *ready_list, +move_to_ready_list(TocEntry *pending_list, + ParallelReadyList *ready_list, RestorePass pass) { TocEntry *te; TocEntry *next_te; - for (te = pending_list->par_next; te != pending_list; te = next_te) + for (te = pending_list->pending_next; te != pending_list; te = next_te) { - /* must save list link before possibly moving te to other list */ - next_te = te->par_next; + /* must save list link before possibly removing te from list */ + next_te = te->pending_next; if (te->depCount == 0 && _tocEntryRestorePass(te) == pass) { /* Remove it from pending_list ... */ - par_list_remove(te); + pending_list_remove(te); /* ... and add to ready_list */ - par_list_append(ready_list, te); + ready_list_insert(ready_list, te); } } } /* - * Find the next work item (if any) that is capable of being run now. + * Find the next work item (if any) that is capable of being run now, + * and remove it from the ready_list. + * + * Returns the item, or NULL if nothing is runnable. * * To qualify, the item must have no remaining dependencies * and no requirements for locks that are incompatible with * items currently running. Items in the ready_list are known to have * no remaining dependencies, but we have to check for lock conflicts. - * - * Note that the returned item has *not* been removed from ready_list. - * The caller must do that after successfully dispatching the item. - * - * pref_non_data is for an alternative selection algorithm that gives - * preference to non-data items if there is already a data load running. - * It is currently disabled. */ static TocEntry * -get_next_work_item(ArchiveHandle *AH, TocEntry *ready_list, +pop_next_work_item(ArchiveHandle *AH, ParallelReadyList *ready_list, ParallelState *pstate) { - bool pref_non_data = false; /* or get from AH->ropt */ - TocEntry *data_te = NULL; - TocEntry *te; - int i, - k; - /* - * Bogus heuristics for pref_non_data + * Sort the ready_list so that we'll tackle larger jobs first. */ - if (pref_non_data) - { - int count = 0; - - for (k = 0; k < pstate->numWorkers; k++) - { - TocEntry *running_te = pstate->te[k]; - - if (running_te != NULL && - running_te->section == SECTION_DATA) - count++; - } - if (pstate->numWorkers == 0 || count * 4 < pstate->numWorkers) - pref_non_data = false; - } + ready_list_sort(ready_list); /* * Search the ready_list until we find a suitable item. */ - for (te = ready_list->par_next; te != ready_list; te = te->par_next) + for (int i = ready_list->first_te; i <= ready_list->last_te; i++) { + TocEntry *te = ready_list->tes[i]; bool conflicts = false; /* @@ -4326,9 +4406,9 @@ get_next_work_item(ArchiveHandle *AH, TocEntry *ready_list, * that a currently running item also needs lock on, or vice versa. If * so, we don't want to schedule them together. */ - for (i = 0; i < pstate->numWorkers; i++) + for (int k = 0; k < pstate->numWorkers; k++) { - TocEntry *running_te = pstate->te[i]; + TocEntry *running_te = pstate->te[k]; if (running_te == NULL) continue; @@ -4343,21 +4423,12 @@ get_next_work_item(ArchiveHandle *AH, TocEntry *ready_list, if (conflicts) continue; - if (pref_non_data && te->section == SECTION_DATA) - { - if (data_te == NULL) - data_te = te; - continue; - } - /* passed all tests, so this item can run */ + ready_list_remove(ready_list, i); return te; } - if (data_te != NULL) - return data_te; - - ahlog(AH, 2, "no item ready\n"); + pg_log_debug("no item ready"); return NULL; } @@ -4399,10 +4470,10 @@ mark_restore_job_done(ArchiveHandle *AH, int status, void *callback_data) { - TocEntry *ready_list = (TocEntry *) callback_data; + ParallelReadyList *ready_list = (ParallelReadyList *) callback_data; - ahlog(AH, 1, "finished item %d %s %s\n", - te->dumpId, te->desc, te->tag); + pg_log_info("finished item %d %s %s", + te->dumpId, te->desc, te->tag); if (status == WORKER_CREATE_DONE) mark_create_done(AH, te); @@ -4414,8 +4485,8 @@ mark_restore_job_done(ArchiveHandle *AH, else if (status == WORKER_IGNORED_ERRORS) AH->public.n_errors++; else if (status != 0) - exit_horribly(modulename, "worker process failed: exit code %d\n", - status); + fatal("worker process failed: exit code %d", + status); reduce_dependencies(AH, te, ready_list); } @@ -4449,8 +4520,8 @@ fix_dependencies(ArchiveHandle *AH) te->depCount = te->nDeps; te->revDeps = NULL; te->nRevDeps = 0; - te->par_prev = NULL; - te->par_next = NULL; + te->pending_prev = NULL; + te->pending_next = NULL; } /* @@ -4557,6 +4628,12 @@ fix_dependencies(ArchiveHandle *AH) /* * Change dependencies on table items to depend on table data items instead, * but only in POST_DATA items. + * + * Also, for any item having such dependency(s), set its dataLength to the + * largest dataLength of the table data items it depends on. This ensures + * that parallel restore will prioritize larger jobs (index builds, FK + * constraint checks, etc) over smaller ones, avoiding situations where we + * end a restore with only one active job working on a large table. */ static void repoint_table_dependencies(ArchiveHandle *AH) @@ -4575,9 +4652,13 @@ repoint_table_dependencies(ArchiveHandle *AH) if (olddep <= AH->maxDumpId && AH->tableDataId[olddep] != 0) { - te->dependencies[i] = AH->tableDataId[olddep]; - ahlog(AH, 2, "transferring dependency %d -> %d to %d\n", - te->dumpId, olddep, AH->tableDataId[olddep]); + DumpId tabledataid = AH->tableDataId[olddep]; + TocEntry *tabledatate = AH->tocsByDumpId[tabledataid]; + + te->dependencies[i] = tabledataid; + te->dataLength = Max(te->dataLength, tabledatate->dataLength); + pg_log_debug("transferring dependency %d -> %d to %d", + te->dumpId, olddep, tabledataid); } } } @@ -4595,16 +4676,24 @@ identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te) int nlockids; int i; + /* + * We only care about this for POST_DATA items. PRE_DATA items are not + * run in parallel, and DATA items are all independent by assumption. + */ + if (te->section != SECTION_POST_DATA) + return; + /* Quick exit if no dependencies at all */ if (te->nDeps == 0) return; - /* Exit if this entry doesn't need exclusive lock on other objects */ - if (!(strcmp(te->desc, "CONSTRAINT") == 0 || - strcmp(te->desc, "CHECK CONSTRAINT") == 0 || - strcmp(te->desc, "FK CONSTRAINT") == 0 || - strcmp(te->desc, "RULE") == 0 || - strcmp(te->desc, "TRIGGER") == 0)) + /* + * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that, + * and hence require exclusive lock. However, we know that CREATE INDEX + * does not. (Maybe someday index-creating CONSTRAINTs will fall in that + * category too ... but today is not that day.) + */ + if (strcmp(te->desc, "INDEX") == 0) return; /* @@ -4645,11 +4734,12 @@ identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te) * becomes ready should be moved to the ready_list, if that's provided. */ static void -reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list) +reduce_dependencies(ArchiveHandle *AH, TocEntry *te, + ParallelReadyList *ready_list) { int i; - ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId); + pg_log_debug("reducing dependencies for %d", te->dumpId); for (i = 0; i < te->nRevDeps; i++) { @@ -4668,13 +4758,13 @@ reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list) */ if (otherte->depCount == 0 && _tocEntryRestorePass(otherte) == AH->restorePass && - otherte->par_prev != NULL && + otherte->pending_prev != NULL && ready_list != NULL) { /* Remove it from pending list ... */ - par_list_remove(otherte); + pending_list_remove(otherte); /* ... and add to ready_list */ - par_list_append(ready_list, otherte); + ready_list_insert(ready_list, otherte); } } } @@ -4701,8 +4791,8 @@ mark_create_done(ArchiveHandle *AH, TocEntry *te) static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te) { - ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n", - te->tag); + pg_log_info("table \"%s\" could not be created, will not restore its data", + te->tag); if (AH->tableDataId[te->dumpId] != 0) { @@ -4736,7 +4826,6 @@ CloneArchive(ArchiveHandle *AH) clone->currUser = NULL; clone->currSchema = NULL; clone->currTablespace = NULL; - clone->currWithOids = -1; /* savedPassword must be local in case we change it while connecting */ if (clone->savedPassword) @@ -4781,7 +4870,7 @@ CloneArchive(ArchiveHandle *AH) * any data to/from the database. */ initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, PQdb(AH->connection)); pghost = PQhost(AH->connection); pgport = PQport(AH->connection); @@ -4827,6 +4916,8 @@ DeCloneArchive(ArchiveHandle *AH) free(AH->currSchema); if (AH->currTablespace) free(AH->currTablespace); + if (AH->currTableAm) + free(AH->currTableAm); if (AH->savedPassword) free(AH->savedPassword); diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h index 8dd19159989..fa2c6eff5ad 100644 --- a/src/bin/pg_dump/pg_backup_archiver.h +++ b/src/bin/pg_dump/pg_backup_archiver.h @@ -13,7 +13,7 @@ * as this notice is not removed. * * The author is not responsible for loss or damages that may - * result from it's use. + * result from its use. * * * IDENTIFICATION @@ -94,10 +94,11 @@ typedef z_stream *z_streamp; * entries */ #define K_VERS_1_13 MAKE_ARCHIVE_VERSION(1, 13, 0) /* change search_path * behavior */ +#define K_VERS_1_14 MAKE_ARCHIVE_VERSION(1, 14, 0) /* add tableam */ /* Current archive version number (the format we can output) */ #define K_VERS_MAJOR 1 -#define K_VERS_MINOR 13 +#define K_VERS_MINOR 14 #define K_VERS_REV 0 #define K_VERS_SELF MAKE_ARCHIVE_VERSION(K_VERS_MAJOR, K_VERS_MINOR, K_VERS_REV); @@ -126,17 +127,14 @@ struct ParallelState; #define READ_ERROR_EXIT(fd) \ do { \ if (feof(fd)) \ - exit_horribly(modulename, \ - "could not read from input file: end of file\n"); \ + fatal("could not read from input file: end of file"); \ else \ - exit_horribly(modulename, \ - "could not read from input file: %s\n", strerror(errno)); \ + fatal("could not read from input file: %m"); \ } while (0) #define WRITE_ERROR_EXIT \ do { \ - exit_horribly(modulename, "could not write to output file: %s\n", \ - strerror(errno)); \ + fatal("could not write to output file: %m"); \ } while (0) typedef enum T_Action @@ -162,12 +160,12 @@ typedef int (*WriteBytePtrType) (ArchiveHandle *AH, const int i); typedef int (*ReadBytePtrType) (ArchiveHandle *AH); typedef void (*WriteBufPtrType) (ArchiveHandle *AH, const void *c, size_t len); typedef void (*ReadBufPtrType) (ArchiveHandle *AH, void *buf, size_t len); -typedef void (*SaveArchivePtrType) (ArchiveHandle *AH); typedef void (*WriteExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te); typedef void (*ReadExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te); typedef void (*PrintExtraTocPtrType) (ArchiveHandle *AH, TocEntry *te); typedef void (*PrintTocDataPtrType) (ArchiveHandle *AH, TocEntry *te); +typedef void (*PrepParallelRestorePtrType) (ArchiveHandle *AH); typedef void (*ClonePtrType) (ArchiveHandle *AH); typedef void (*DeClonePtrType) (ArchiveHandle *AH); @@ -246,8 +244,6 @@ struct _archiveHandle char *archiveDumpVersion; /* When reading an archive, the version of * the dumper */ - int debugLevel; /* Used for logging (currently only by - * --verbose) */ size_t intSize; /* Size of an integer in the archive */ size_t offSize; /* Size of a file offset in the archive - * Added V1.7 */ @@ -297,6 +293,7 @@ struct _archiveHandle WorkerJobDumpPtrType WorkerJobDumpPtr; WorkerJobRestorePtrType WorkerJobRestorePtr; + PrepParallelRestorePtrType PrepParallelRestorePtr; ClonePtrType ClonePtr; /* Clone format-specific fields */ DeClonePtrType DeClonePtr; /* Clean up cloned fields */ @@ -346,7 +343,7 @@ struct _archiveHandle char *currUser; /* current username, or NULL if unknown */ char *currSchema; /* current schema, or NULL */ char *currTablespace; /* current tablespace, or NULL */ - bool currWithOids; /* current default_with_oids setting */ + char *currTableAm; /* current table access method, or NULL */ void *lo_buf; size_t lo_buf_used; @@ -373,8 +370,8 @@ struct _tocEntry char *namespace; /* null or empty string if not in a schema */ char *tablespace; /* null if not in a tablespace; empty string * means use database default */ + char *tableam; /* table access method, only for TABLE tags */ char *owner; - bool withOids; /* Used only by "TABLE" tags */ char *desc; char *defn; char *dropStmt; @@ -387,12 +384,13 @@ struct _tocEntry void *formatData; /* TOC Entry data specific to file format */ /* working state while dumping/restoring */ + pgoff_t dataLength; /* item's data size; 0 if none or unknown */ teReqs reqs; /* do we need schema and/or data of object */ bool created; /* set for DATA member if TABLE was created */ /* working state (needed only for parallel restore) */ - struct _tocEntry *par_prev; /* list links for pending/ready items; */ - struct _tocEntry *par_next; /* these are NULL if not in either list */ + struct _tocEntry *pending_prev; /* list links for pending-items list; */ + struct _tocEntry *pending_next; /* NULL if not in that list */ int depCount; /* number of dependencies not yet restored */ DumpId *revDeps; /* dumpIds of objects depending on this one */ int nRevDeps; /* number of such dependencies */ @@ -403,10 +401,31 @@ struct _tocEntry extern int parallel_restore(ArchiveHandle *AH, TocEntry *te); extern void on_exit_close_archive(Archive *AHX); -extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...) pg_attribute_printf(3, 4); +extern void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...) pg_attribute_printf(2, 3); + +/* Options for ArchiveEntry */ +typedef struct _archiveOpts +{ + const char *tag; + const char *namespace; + const char *tablespace; + const char *tableam; + const char *owner; + const char *description; + teSection section; + const char *createStmt; + const char *dropStmt; + const char *copyStmt; + const DumpId *deps; + int nDeps; + DataDumperPtr dumpFn; + void *dumpArg; +} ArchiveOpts; +#define ARCHIVE_OPTS(...) &(ArchiveOpts){__VA_ARGS__} +/* Called to add a TOC entry */ +extern TocEntry *ArchiveEntry(Archive *AHX, CatalogId catalogId, + DumpId dumpId, ArchiveOpts *opts); -extern void WriteTOC(ArchiveHandle *AH); -extern void ReadTOC(ArchiveHandle *AH); extern void WriteHead(ArchiveHandle *AH); extern void ReadHead(ArchiveHandle *AH); extern void WriteToc(ArchiveHandle *AH); @@ -456,6 +475,4 @@ extern void DropBlobIfExists(ArchiveHandle *AH, Oid oid); void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH); int ahprintf(ArchiveHandle *AH, const char *fmt,...) pg_attribute_printf(2, 3); -void ahlog(ArchiveHandle *AH, int level, const char *fmt,...) pg_attribute_printf(3, 4); - #endif diff --git a/src/bin/pg_dump/pg_backup_custom.c b/src/bin/pg_dump/pg_backup_custom.c index ad18a6c684b..497b81b6840 100644 --- a/src/bin/pg_dump/pg_backup_custom.c +++ b/src/bin/pg_dump/pg_backup_custom.c @@ -30,6 +30,7 @@ #include "pg_backup_utils.h" #include "common/file_utils.h" + /*-------- * Routines in the format interface *-------- @@ -59,6 +60,8 @@ static void _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid); static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid); static void _EndBlobs(ArchiveHandle *AH, TocEntry *te); static void _LoadBlobs(ArchiveHandle *AH, bool drop); + +static void _PrepParallelRestore(ArchiveHandle *AH); static void _Clone(ArchiveHandle *AH); static void _DeClone(ArchiveHandle *AH); @@ -89,10 +92,6 @@ static pgoff_t _getFilePos(ArchiveHandle *AH, lclContext *ctx); static void _CustomWriteFunc(ArchiveHandle *AH, const char *buf, size_t len); static size_t _CustomReadFunc(ArchiveHandle *AH, char **buf, size_t *buflen); -/* translator: this is a module name */ -static const char *modulename = gettext_noop("custom archiver"); - - /* * Init routine required by ALL formats. This is a global routine @@ -129,6 +128,8 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) AH->StartBlobPtr = _StartBlob; AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; + + AH->PrepParallelRestorePtr = _PrepParallelRestore; AH->ClonePtr = _Clone; AH->DeClonePtr = _DeClone; @@ -155,15 +156,13 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) { AH->FH = fopen(AH->fSpec, PG_BINARY_W); if (!AH->FH) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open output file \"%s\": %m", AH->fSpec); } else { AH->FH = stdout; if (!AH->FH) - exit_horribly(modulename, "could not open output file: %s\n", - strerror(errno)); + fatal("could not open output file: %m"); } ctx->hasSeek = checkSeek(AH->FH); @@ -174,15 +173,13 @@ InitArchiveFmt_Custom(ArchiveHandle *AH) { AH->FH = fopen(AH->fSpec, PG_BINARY_R); if (!AH->FH) - exit_horribly(modulename, "could not open input file \"%s\": %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open input file \"%s\": %m", AH->fSpec); } else { AH->FH = stdin; if (!AH->FH) - exit_horribly(modulename, "could not open input file: %s\n", - strerror(errno)); + fatal("could not open input file: %m"); } ctx->hasSeek = checkSeek(AH->FH); @@ -377,7 +374,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) lclContext *ctx = (lclContext *) AH->formatData; if (oid == 0) - exit_horribly(modulename, "invalid OID for large object\n"); + fatal("invalid OID for large object"); WriteInt(AH, oid); @@ -447,9 +444,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te) break; default: /* Always have a default */ - exit_horribly(modulename, - "unrecognized data block type (%d) while searching archive\n", - blkType); + fatal("unrecognized data block type (%d) while searching archive", + blkType); break; } _readBlockHeader(AH, &blkType, &id); @@ -459,8 +455,7 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te) { /* We can just seek to the place we need to be. */ if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0) - exit_horribly(modulename, "error during file seek: %s\n", - strerror(errno)); + fatal("error during file seek: %m"); _readBlockHeader(AH, &blkType, &id); } @@ -469,25 +464,25 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te) if (blkType == EOF) { if (tctx->dataState == K_OFFSET_POS_NOT_SET) - exit_horribly(modulename, "could not find block ID %d in archive -- " - "possibly due to out-of-order restore request, " - "which cannot be handled due to lack of data offsets in archive\n", - te->dumpId); + fatal("could not find block ID %d in archive -- " + "possibly due to out-of-order restore request, " + "which cannot be handled due to lack of data offsets in archive", + te->dumpId); else if (!ctx->hasSeek) - exit_horribly(modulename, "could not find block ID %d in archive -- " - "possibly due to out-of-order restore request, " - "which cannot be handled due to non-seekable input file\n", - te->dumpId); + fatal("could not find block ID %d in archive -- " + "possibly due to out-of-order restore request, " + "which cannot be handled due to non-seekable input file", + te->dumpId); else /* huh, the dataPos led us to EOF? */ - exit_horribly(modulename, "could not find block ID %d in archive -- " - "possibly corrupt archive\n", - te->dumpId); + fatal("could not find block ID %d in archive -- " + "possibly corrupt archive", + te->dumpId); } /* Are we sane? */ if (id != te->dumpId) - exit_horribly(modulename, "found unexpected block ID (%d) when reading data -- expected %d\n", - id, te->dumpId); + fatal("found unexpected block ID (%d) when reading data -- expected %d", + id, te->dumpId); switch (blkType) { @@ -500,8 +495,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te) break; default: /* Always have a default */ - exit_horribly(modulename, "unrecognized data block type %d while restoring archive\n", - blkType); + fatal("unrecognized data block type %d while restoring archive", + blkType); break; } } @@ -580,11 +575,9 @@ _skipData(ArchiveHandle *AH) if ((cnt = fread(buf, 1, blkLen, AH->FH)) != blkLen) { if (feof(AH->FH)) - exit_horribly(modulename, - "could not read from input file: end of file\n"); + fatal("could not read from input file: end of file"); else - exit_horribly(modulename, - "could not read from input file: %s\n", strerror(errno)); + fatal("could not read from input file: %m"); } ctx->filePos += blkLen; @@ -702,8 +695,7 @@ _CloseArchive(ArchiveHandle *AH) /* Remember TOC's seek position for use below */ tpos = ftello(AH->FH); if (tpos < 0 && ctx->hasSeek) - exit_horribly(modulename, "could not determine seek position in archive file: %s\n", - strerror(errno)); + fatal("could not determine seek position in archive file: %m"); WriteToc(AH); ctx->dataStart = _getFilePos(AH, ctx); WriteDataChunks(AH, NULL); @@ -720,11 +712,11 @@ _CloseArchive(ArchiveHandle *AH) } if (fclose(AH->FH) != 0) - exit_horribly(modulename, "could not close archive file: %s\n", strerror(errno)); + fatal("could not close archive file: %m"); /* Sync the output file if one is defined */ if (AH->dosync && AH->mode == archModeWrite && AH->fSpec) - (void) fsync_fname(AH->fSpec, false, progname); + (void) fsync_fname(AH->fSpec, false); AH->FH = NULL; } @@ -743,36 +735,91 @@ _ReopenArchive(ArchiveHandle *AH) pgoff_t tpos; if (AH->mode == archModeWrite) - exit_horribly(modulename, "can only reopen input archives\n"); + fatal("can only reopen input archives"); /* * These two cases are user-facing errors since they represent unsupported * (but not invalid) use-cases. Word the error messages appropriately. */ if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0) - exit_horribly(modulename, "parallel restore from standard input is not supported\n"); + fatal("parallel restore from standard input is not supported"); if (!ctx->hasSeek) - exit_horribly(modulename, "parallel restore from non-seekable file is not supported\n"); + fatal("parallel restore from non-seekable file is not supported"); tpos = ftello(AH->FH); if (tpos < 0) - exit_horribly(modulename, "could not determine seek position in archive file: %s\n", - strerror(errno)); + fatal("could not determine seek position in archive file: %m"); #ifndef WIN32 if (fclose(AH->FH) != 0) - exit_horribly(modulename, "could not close archive file: %s\n", - strerror(errno)); + fatal("could not close archive file: %m"); #endif AH->FH = fopen(AH->fSpec, PG_BINARY_R); if (!AH->FH) - exit_horribly(modulename, "could not open input file \"%s\": %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open input file \"%s\": %m", AH->fSpec); if (fseeko(AH->FH, tpos, SEEK_SET) != 0) - exit_horribly(modulename, "could not set seek position in archive file: %s\n", - strerror(errno)); + fatal("could not set seek position in archive file: %m"); +} + +/* + * Prepare for parallel restore. + * + * The main thing that needs to happen here is to fill in TABLE DATA and BLOBS + * TOC entries' dataLength fields with appropriate values to guide the + * ordering of restore jobs. The source of said data is format-dependent, + * as is the exact meaning of the values. + * + * A format module might also choose to do other setup here. + */ +static void +_PrepParallelRestore(ArchiveHandle *AH) +{ + lclContext *ctx = (lclContext *) AH->formatData; + TocEntry *prev_te = NULL; + lclTocEntry *prev_tctx = NULL; + TocEntry *te; + + /* + * Knowing that the data items were dumped out in TOC order, we can + * reconstruct the length of each item as the delta to the start offset of + * the next data item. + */ + for (te = AH->toc->next; te != AH->toc; te = te->next) + { + lclTocEntry *tctx = (lclTocEntry *) te->formatData; + + /* + * Ignore entries without a known data offset; if we were unable to + * seek to rewrite the TOC when creating the archive, this'll be all + * of them, and we'll end up with no size estimates. + */ + if (tctx->dataState != K_OFFSET_POS_SET) + continue; + + /* Compute previous data item's length */ + if (prev_te) + { + if (tctx->dataPos > prev_tctx->dataPos) + prev_te->dataLength = tctx->dataPos - prev_tctx->dataPos; + } + + prev_te = te; + prev_tctx = tctx; + } + + /* If OK to seek, we can determine the length of the last item */ + if (prev_te && ctx->hasSeek) + { + pgoff_t endpos; + + if (fseeko(AH->FH, 0, SEEK_END) != 0) + fatal("error during file seek: %m"); + endpos = ftello(AH->FH); + if (endpos > prev_tctx->dataPos) + prev_te->dataLength = endpos - prev_tctx->dataPos; + } } /* @@ -789,7 +836,7 @@ _Clone(ArchiveHandle *AH) /* sanity check, shouldn't happen */ if (ctx->cs != NULL) - exit_horribly(modulename, "compressor active\n"); + fatal("compressor active"); /* * Note: we do not make a local lo_buf because we expect at most one BLOBS @@ -841,11 +888,10 @@ _getFilePos(ArchiveHandle *AH, lclContext *ctx) */ pos = ftello(AH->FH); if (pos < 0) - exit_horribly(modulename, "could not determine seek position in archive file: %s\n", - strerror(errno)); + fatal("could not determine seek position in archive file: %m"); if (pos != ctx->filePos) - write_msg(modulename, "WARNING: ftell mismatch with expected position -- ftell used\n"); + pg_log_warning("ftell mismatch with expected position -- ftell used"); } else pos = ctx->filePos; @@ -864,11 +910,11 @@ _readBlockHeader(ArchiveHandle *AH, int *type, int *id) int byt; /* - * Note: if we are at EOF with a pre-1.3 input file, we'll exit_horribly - * inside ReadInt rather than returning EOF. It doesn't seem worth - * jumping through hoops to deal with that case better, because no such - * files are likely to exist in the wild: only some 7.1 development - * versions of pg_dump ever generated such files. + * Note: if we are at EOF with a pre-1.3 input file, we'll fatal() inside + * ReadInt rather than returning EOF. It doesn't seem worth jumping + * through hoops to deal with that case better, because no such files are + * likely to exist in the wild: only some 7.1 development versions of + * pg_dump ever generated such files. */ if (AH->version < K_VERS_1_3) *type = BLK_DATA; diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c index 5e32ee8a5b0..ee822c52497 100644 --- a/src/bin/pg_dump/pg_backup_db.c +++ b/src/bin/pg_dump/pg_backup_db.c @@ -11,9 +11,10 @@ */ #include "postgres_fe.h" -#include "dumputils.h" #include "fe_utils/connect.h" #include "fe_utils/string_utils.h" + +#include "dumputils.h" #include "parallel.h" #include "pg_backup_archiver.h" #include "pg_backup_db.h" @@ -26,9 +27,6 @@ #endif -/* translator: this is a module name */ -static const char *modulename = gettext_noop("archiver (db)"); - static void _check_database_version(ArchiveHandle *AH); static PGconn *_connectDB(ArchiveHandle *AH, const char *newdbname, const char *newUser); static void notice_processor(void *arg, const char *message); @@ -43,7 +41,7 @@ _check_database_version(ArchiveHandle *AH) remoteversion_str = PQparameterStatus(AH->connection, "server_version"); remoteversion = PQserverVersion(AH->connection); if (remoteversion == 0 || !remoteversion_str) - exit_horribly(modulename, "could not get server_version from libpq\n"); + fatal("could not get server_version from libpq"); AH->public.remoteVersionStr = pg_strdup(remoteversion_str); AH->public.remoteVersion = remoteversion; @@ -54,9 +52,9 @@ _check_database_version(ArchiveHandle *AH) && (remoteversion < AH->public.minRemoteVersion || remoteversion > AH->public.maxRemoteVersion)) { - write_msg(NULL, "server version: %s; %s version: %s\n", - remoteversion_str, progname, PG_VERSION); - exit_horribly(NULL, "aborting because of server version mismatch\n"); + pg_log_error("server version: %s; %s version: %s", + remoteversion_str, progname, PG_VERSION); + fatal("aborting because of server version mismatch"); } /* @@ -139,8 +137,8 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) else newuser = requser; - ahlog(AH, 1, "connecting to database \"%s\" as user \"%s\"\n", - newdb, newuser); + pg_log_info("connecting to database \"%s\" as user \"%s\"", + newdb, newuser); password = AH->savedPassword; @@ -151,7 +149,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) } initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, newdb); do @@ -178,13 +176,13 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) newConn = PQconnectdbParams(keywords, values, true); if (!newConn) - exit_horribly(modulename, "failed to reconnect to database\n"); + fatal("could not reconnect to database"); if (PQstatus(newConn) == CONNECTION_BAD) { if (!PQconnectionNeedsPassword(newConn)) - exit_horribly(modulename, "could not reconnect to database: %s", - PQerrorMessage(newConn)); + fatal("could not reconnect to database: %s", + PQerrorMessage(newConn)); PQfinish(newConn); if (password) @@ -199,7 +197,7 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser) password = passbuf; } else - exit_horribly(modulename, "connection needs password\n"); + fatal("connection needs password"); new_pass = true; } @@ -250,7 +248,7 @@ ConnectDatabase(Archive *AHX, bool new_pass; if (AH->connection) - exit_horribly(modulename, "already connected to a database\n"); + fatal("already connected to a database"); password = AH->savedPassword; @@ -289,7 +287,7 @@ ConnectDatabase(Archive *AHX, AH->connection = PQconnectdbParams(keywords, values, true); if (!AH->connection) - exit_horribly(modulename, "failed to connect to database\n"); + fatal("could not connect to database"); if (PQstatus(AH->connection) == CONNECTION_BAD && PQconnectionNeedsPassword(AH->connection) && @@ -305,9 +303,9 @@ ConnectDatabase(Archive *AHX, /* check to see that the backend connection was successfully made */ if (PQstatus(AH->connection) == CONNECTION_BAD) - exit_horribly(modulename, "connection to database \"%s\" failed: %s", - PQdb(AH->connection) ? PQdb(AH->connection) : "", - PQerrorMessage(AH->connection)); + fatal("connection to database \"%s\" failed: %s", + PQdb(AH->connection) ? PQdb(AH->connection) : "", + PQerrorMessage(AH->connection)); /* Start strict; later phases may override this. */ PQclear(ExecuteSqlQueryForSingleRow((Archive *) AH, @@ -351,7 +349,7 @@ DisconnectDatabase(Archive *AHX) /* * If we have an active query, send a cancel before closing, ignoring * any errors. This is of no use for a normal exit, but might be - * helpful during exit_horribly(). + * helpful during fatal(). */ if (PQtransactionStatus(AH->connection) == PQTRANS_ACTIVE) (void) PQcancel(AH->connCancel, errbuf, sizeof(errbuf)); @@ -377,16 +375,16 @@ GetConnection(Archive *AHX) static void notice_processor(void *arg, const char *message) { - write_msg(NULL, "%s", message); + pg_log_generic(PG_LOG_INFO, "%s", message); } -/* Like exit_horribly(), but with a complaint about a particular query. */ +/* Like fatal(), but with a complaint about a particular query. */ static void -die_on_query_failure(ArchiveHandle *AH, const char *modulename, const char *query) +die_on_query_failure(ArchiveHandle *AH, const char *query) { - write_msg(modulename, "query failed: %s", - PQerrorMessage(AH->connection)); - exit_horribly(modulename, "query was: %s\n", query); + pg_log_error("query failed: %s", + PQerrorMessage(AH->connection)); + fatal("query was: %s", query); } void @@ -397,7 +395,7 @@ ExecuteSqlStatement(Archive *AHX, const char *query) res = PQexec(AH->connection, query); if (PQresultStatus(res) != PGRES_COMMAND_OK) - die_on_query_failure(AH, modulename, query); + die_on_query_failure(AH, query); PQclear(res); } @@ -409,7 +407,7 @@ ExecuteSqlQuery(Archive *AHX, const char *query, ExecStatusType status) res = PQexec(AH->connection, query); if (PQresultStatus(res) != status) - die_on_query_failure(AH, modulename, query); + die_on_query_failure(AH, query); return res; } @@ -427,11 +425,10 @@ ExecuteSqlQueryForSingleRow(Archive *fout, const char *query) /* Expecting a single result only */ ntups = PQntuples(res); if (ntups != 1) - exit_horribly(NULL, - ngettext("query returned %d row instead of one: %s\n", - "query returned %d rows instead of one: %s\n", - ntups), - ntups, query); + fatal(ngettext("query returned %d row instead of one: %s", + "query returned %d rows instead of one: %s", + ntups), + ntups, query); return res; } @@ -464,7 +461,7 @@ ExecuteSqlCommand(ArchiveHandle *AH, const char *qry, const char *desc) break; default: /* trouble */ - warn_or_exit_horribly(AH, modulename, "%s: %s Command was: %s\n", + warn_or_exit_horribly(AH, "%s: %sCommand was: %s", desc, PQerrorMessage(conn), qry); break; } @@ -573,8 +570,8 @@ ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen) */ if (AH->pgCopyIn && PQputCopyData(AH->connection, buf, bufLen) <= 0) - exit_horribly(modulename, "error returned by PQputCopyData: %s", - PQerrorMessage(AH->connection)); + fatal("error returned by PQputCopyData: %s", + PQerrorMessage(AH->connection)); } else if (AH->outputKind == OUTPUT_OTHERDATA) { @@ -622,20 +619,20 @@ EndDBCopyMode(Archive *AHX, const char *tocEntryTag) PGresult *res; if (PQputCopyEnd(AH->connection, NULL) <= 0) - exit_horribly(modulename, "error returned by PQputCopyEnd: %s", - PQerrorMessage(AH->connection)); + fatal("error returned by PQputCopyEnd: %s", + PQerrorMessage(AH->connection)); /* Check command status and return to normal libpq state */ res = PQgetResult(AH->connection); if (PQresultStatus(res) != PGRES_COMMAND_OK) - warn_or_exit_horribly(AH, modulename, "COPY failed for table \"%s\": %s", + warn_or_exit_horribly(AH, "COPY failed for table \"%s\": %s", tocEntryTag, PQerrorMessage(AH->connection)); PQclear(res); /* Do this to ensure we've pumped libpq back to idle state */ if (PQgetResult(AH->connection) != NULL) - write_msg(NULL, "WARNING: unexpected extra results during COPY of table \"%s\"\n", - tocEntryTag); + pg_log_warning("unexpected extra results during COPY of table \"%s\"", + tocEntryTag); AH->pgCopyIn = false; } diff --git a/src/bin/pg_dump/pg_backup_db.h b/src/bin/pg_dump/pg_backup_db.h index a79f5283fe5..8888dd34b9b 100644 --- a/src/bin/pg_dump/pg_backup_db.h +++ b/src/bin/pg_dump/pg_backup_db.h @@ -15,7 +15,7 @@ extern int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen); extern void ExecuteSqlStatement(Archive *AHX, const char *query); extern PGresult *ExecuteSqlQuery(Archive *AHX, const char *query, - ExecStatusType status); + ExecStatusType status); extern PGresult *ExecuteSqlQueryForSingleRow(Archive *fout, const char *query); extern void EndDBCopyMode(Archive *AHX, const char *tocEntryTag); diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index 4aabb40f595..e1afecfa6e0 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -17,7 +17,7 @@ * sync. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 2000, Philip Warner * @@ -25,7 +25,7 @@ * as this notice is not removed. * * The author is not responsible for loss or damages that may - * result from it's use. + * result from its use. * * IDENTIFICATION * src/bin/pg_dump/pg_backup_directory.c @@ -61,9 +61,6 @@ typedef struct char *filename; /* filename excluding the directory (basename) */ } lclTocEntry; -/* translator: this is a module name */ -static const char *modulename = gettext_noop("directory archiver"); - /* prototypes for private functions */ static void _ArchiveEntry(ArchiveHandle *AH, TocEntry *te); static void _StartData(ArchiveHandle *AH, TocEntry *te); @@ -87,6 +84,7 @@ static void _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid); static void _EndBlobs(ArchiveHandle *AH, TocEntry *te); static void _LoadBlobs(ArchiveHandle *AH); +static void _PrepParallelRestore(ArchiveHandle *AH); static void _Clone(ArchiveHandle *AH); static void _DeClone(ArchiveHandle *AH); @@ -94,7 +92,7 @@ static int _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te); static int _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te); static void setFilePath(ArchiveHandle *AH, char *buf, - const char *relativeFilename); + const char *relativeFilename); /* * Init routine required by ALL formats. This is a global routine @@ -132,6 +130,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) AH->EndBlobPtr = _EndBlob; AH->EndBlobsPtr = _EndBlobs; + AH->PrepParallelRestorePtr = _PrepParallelRestore; AH->ClonePtr = _Clone; AH->DeClonePtr = _DeClone; @@ -154,7 +153,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) */ if (!AH->fSpec || strcmp(AH->fSpec, "") == 0) - exit_horribly(modulename, "no output directory specified\n"); + fatal("no output directory specified"); ctx->directory = AH->fSpec; @@ -183,18 +182,18 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) } if (errno) - exit_horribly(modulename, "could not read directory \"%s\": %s\n", - ctx->directory, strerror(errno)); + fatal("could not read directory \"%s\": %m", + ctx->directory); if (closedir(dir)) - exit_horribly(modulename, "could not close directory \"%s\": %s\n", - ctx->directory, strerror(errno)); + fatal("could not close directory \"%s\": %m", + ctx->directory); } } if (!is_empty && mkdir(ctx->directory, 0700) < 0) - exit_horribly(modulename, "could not create directory \"%s\": %s\n", - ctx->directory, strerror(errno)); + fatal("could not create directory \"%s\": %m", + ctx->directory); } else { /* Read Mode */ @@ -205,9 +204,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) tocFH = cfopen_read(fname, PG_BINARY_R); if (tocFH == NULL) - exit_horribly(modulename, - "could not open input file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not open input file \"%s\": %m", fname); ctx->dataFH = tocFH; @@ -222,8 +219,7 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) /* Nothing else in the file, so close it again... */ if (cfclose(tocFH) != 0) - exit_horribly(modulename, "could not close TOC file: %s\n", - strerror(errno)); + fatal("could not close TOC file: %m"); ctx->dataFH = NULL; } } @@ -240,13 +236,13 @@ _ArchiveEntry(ArchiveHandle *AH, TocEntry *te) char fn[MAXPGPATH]; tctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry)); - if (te->dataDumper) + if (strcmp(te->desc, "BLOBS") == 0) + tctx->filename = pg_strdup("blobs.toc"); + else if (te->dataDumper) { snprintf(fn, MAXPGPATH, "%d.dat", te->dumpId); tctx->filename = pg_strdup(fn); } - else if (strcmp(te->desc, "BLOBS") == 0) - tctx->filename = pg_strdup("blobs.toc"); else tctx->filename = NULL; @@ -333,8 +329,7 @@ _StartData(ArchiveHandle *AH, TocEntry *te) ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression); if (ctx->dataFH == NULL) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not open output file \"%s\": %m", fname); } /* @@ -352,8 +347,8 @@ _WriteData(ArchiveHandle *AH, const void *data, size_t dLen) lclContext *ctx = (lclContext *) AH->formatData; if (dLen > 0 && cfwrite(data, dLen, ctx->dataFH) != dLen) - exit_horribly(modulename, "could not write to output file: %s\n", - get_cfp_error(ctx->dataFH)); + fatal("could not write to output file: %s", + get_cfp_error(ctx->dataFH)); return; @@ -393,8 +388,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename) cfp = cfopen_read(filename, PG_BINARY_R); if (!cfp) - exit_horribly(modulename, "could not open input file \"%s\": %s\n", - filename, strerror(errno)); + fatal("could not open input file \"%s\": %m", filename); buf = pg_malloc(ZLIB_OUT_SIZE); buflen = ZLIB_OUT_SIZE; @@ -406,8 +400,7 @@ _PrintFileData(ArchiveHandle *AH, char *filename) free(buf); if (cfclose(cfp) !=0) - exit_horribly(modulename, "could not close data file: %s\n", - strerror(errno)); + fatal("could not close data file: %m"); } /* @@ -447,8 +440,8 @@ _LoadBlobs(ArchiveHandle *AH) ctx->blobsTocFH = cfopen_read(fname, PG_BINARY_R); if (ctx->blobsTocFH == NULL) - exit_horribly(modulename, "could not open large object TOC file \"%s\" for input: %s\n", - fname, strerror(errno)); + fatal("could not open large object TOC file \"%s\" for input: %m", + fname); /* Read the blobs TOC file line-by-line, and process each blob */ while ((cfgets(ctx->blobsTocFH, line, MAXPGPATH)) != NULL) @@ -458,8 +451,8 @@ _LoadBlobs(ArchiveHandle *AH) /* Can't overflow because line and fname are the same length. */ if (sscanf(line, "%u %s\n", &oid, fname) != 2) - exit_horribly(modulename, "invalid line in large object TOC file \"%s\": \"%s\"\n", - fname, line); + fatal("invalid line in large object TOC file \"%s\": \"%s\"", + fname, line); StartRestoreBlob(AH, oid, AH->public.ropt->dropSchema); snprintf(path, MAXPGPATH, "%s/%s", ctx->directory, fname); @@ -467,12 +460,12 @@ _LoadBlobs(ArchiveHandle *AH) EndRestoreBlob(AH, oid); } if (!cfeof(ctx->blobsTocFH)) - exit_horribly(modulename, "error reading large object TOC file \"%s\"\n", - fname); + fatal("error reading large object TOC file \"%s\"", + fname); if (cfclose(ctx->blobsTocFH) != 0) - exit_horribly(modulename, "could not close large object TOC file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not close large object TOC file \"%s\": %m", + fname); ctx->blobsTocFH = NULL; @@ -492,8 +485,8 @@ _WriteByte(ArchiveHandle *AH, const int i) lclContext *ctx = (lclContext *) AH->formatData; if (cfwrite(&c, 1, ctx->dataFH) != 1) - exit_horribly(modulename, "could not write to output file: %s\n", - get_cfp_error(ctx->dataFH)); + fatal("could not write to output file: %s", + get_cfp_error(ctx->dataFH)); return 1; } @@ -522,8 +515,8 @@ _WriteBuf(ArchiveHandle *AH, const void *buf, size_t len) lclContext *ctx = (lclContext *) AH->formatData; if (cfwrite(buf, len, ctx->dataFH) != len) - exit_horribly(modulename, "could not write to output file: %s\n", - get_cfp_error(ctx->dataFH)); + fatal("could not write to output file: %s", + get_cfp_error(ctx->dataFH)); return; } @@ -543,8 +536,7 @@ _ReadBuf(ArchiveHandle *AH, void *buf, size_t len) * exit on short reads. */ if (cfread(buf, len, ctx->dataFH) != len) - exit_horribly(modulename, - "could not read from input file: end of file\n"); + fatal("could not read from input file: end of file"); return; } @@ -579,8 +571,7 @@ _CloseArchive(ArchiveHandle *AH) /* The TOC is always created uncompressed */ tocFH = cfopen_write(fname, PG_BINARY_W, 0); if (tocFH == NULL) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not open output file \"%s\": %m", fname); ctx->dataFH = tocFH; /* @@ -593,8 +584,7 @@ _CloseArchive(ArchiveHandle *AH) AH->format = archDirectory; WriteToc(AH); if (cfclose(tocFH) != 0) - exit_horribly(modulename, "could not close TOC file: %s\n", - strerror(errno)); + fatal("could not close TOC file: %m"); WriteDataChunks(AH, ctx->pstate); ParallelBackupEnd(AH, ctx->pstate); @@ -604,7 +594,7 @@ _CloseArchive(ArchiveHandle *AH) * individually. Just recurse once through all the files generated. */ if (AH->dosync) - fsync_dir_recurse(ctx->directory, progname); + fsync_dir_recurse(ctx->directory); } AH->FH = NULL; } @@ -644,8 +634,7 @@ _StartBlobs(ArchiveHandle *AH, TocEntry *te) /* The blob TOC file is never compressed */ ctx->blobsTocFH = cfopen_write(fname, "ab", 0); if (ctx->blobsTocFH == NULL) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not open output file \"%s\": %m", fname); } /* @@ -664,8 +653,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) ctx->dataFH = cfopen_write(fname, PG_BINARY_W, AH->compression); if (ctx->dataFH == NULL) - exit_horribly(modulename, "could not open output file \"%s\": %s\n", - fname, strerror(errno)); + fatal("could not open output file \"%s\": %m", fname); } /* @@ -687,7 +675,7 @@ _EndBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) /* register the blob in blobs.toc */ len = snprintf(buf, sizeof(buf), "%u blob_%u.dat\n", oid, oid); if (cfwrite(buf, len, ctx->blobsTocFH) != len) - exit_horribly(modulename, "could not write to blobs TOC file\n"); + fatal("could not write to blobs TOC file"); } /* @@ -719,13 +707,75 @@ setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename) dname = ctx->directory; if (strlen(dname) + 1 + strlen(relativeFilename) + 1 > MAXPGPATH) - exit_horribly(modulename, "file name too long: \"%s\"\n", dname); + fatal("file name too long: \"%s\"", dname); strcpy(buf, dname); strcat(buf, "/"); strcat(buf, relativeFilename); } +/* + * Prepare for parallel restore. + * + * The main thing that needs to happen here is to fill in TABLE DATA and BLOBS + * TOC entries' dataLength fields with appropriate values to guide the + * ordering of restore jobs. The source of said data is format-dependent, + * as is the exact meaning of the values. + * + * A format module might also choose to do other setup here. + */ +static void +_PrepParallelRestore(ArchiveHandle *AH) +{ + TocEntry *te; + + for (te = AH->toc->next; te != AH->toc; te = te->next) + { + lclTocEntry *tctx = (lclTocEntry *) te->formatData; + char fname[MAXPGPATH]; + struct stat st; + + /* + * A dumpable object has set tctx->filename, any other object has not. + * (see _ArchiveEntry). + */ + if (tctx->filename == NULL) + continue; + + /* We may ignore items not due to be restored */ + if ((te->reqs & REQ_DATA) == 0) + continue; + + /* + * Stat the file and, if successful, put its size in dataLength. When + * using compression, the physical file size might not be a very good + * guide to the amount of work involved in restoring the file, but we + * only need an approximate indicator of that. + */ + setFilePath(AH, fname, tctx->filename); + + if (stat(fname, &st) == 0) + te->dataLength = st.st_size; + else + { + /* It might be compressed */ + strlcat(fname, ".gz", sizeof(fname)); + if (stat(fname, &st) == 0) + te->dataLength = st.st_size; + } + + /* + * If this is the BLOBS entry, what we stat'd was blobs.toc, which + * most likely is a lot smaller than the actual blob data. We don't + * have a cheap way to estimate how much smaller, but fortunately it + * doesn't matter too much as long as we get the blobs processed + * reasonably early. Arbitrarily scale up by a factor of 1K. + */ + if (strcmp(te->desc, "BLOBS") == 0) + te->dataLength *= 1024; + } +} + /* * Clone format-specific fields during parallel restoration. */ diff --git a/src/bin/pg_dump/pg_backup_null.c b/src/bin/pg_dump/pg_backup_null.c index 62f6e624f0b..32c911a365f 100644 --- a/src/bin/pg_dump/pg_backup_null.c +++ b/src/bin/pg_dump/pg_backup_null.c @@ -13,7 +13,7 @@ * as this notice is not removed. * * The author is not responsible for loss or damages that may - * result from it's use. + * result from its use. * * * IDENTIFICATION @@ -72,7 +72,7 @@ InitArchiveFmt_Null(ArchiveHandle *AH) * Now prevent reading... */ if (AH->mode == archModeRead) - exit_horribly(NULL, "this format cannot be read\n"); + fatal("this format cannot be read"); } /* @@ -147,7 +147,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) bool old_blob_style = (AH->version < K_VERS_1_12); if (oid == 0) - exit_horribly(NULL, "invalid OID for large object\n"); + fatal("invalid OID for large object"); /* With an old archive we must do drop and create logic here */ if (old_blob_style && AH->public.ropt->dropSchema) diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c index 007be1298fb..dead8fc5803 100644 --- a/src/bin/pg_dump/pg_backup_tar.c +++ b/src/bin/pg_dump/pg_backup_tar.c @@ -19,7 +19,7 @@ * as this notice is not removed. * * The author is not responsible for loss or damages that may - * result from it's use. + * result from its use. * * * IDENTIFICATION @@ -99,9 +99,6 @@ typedef struct char *filename; } lclTocEntry; -/* translator: this is a module name */ -static const char *modulename = gettext_noop("tar archiver"); - static void _LoadBlobs(ArchiveHandle *AH); static TAR_MEMBER *tarOpen(ArchiveHandle *AH, const char *filename, char mode); @@ -177,17 +174,14 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_W); if (ctx->tarFH == NULL) - exit_horribly(modulename, - "could not open TOC file \"%s\" for output: %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open TOC file \"%s\" for output: %m", + AH->fSpec); } else { ctx->tarFH = stdout; if (ctx->tarFH == NULL) - exit_horribly(modulename, - "could not open TOC file for output: %s\n", - strerror(errno)); + fatal("could not open TOC file for output: %m"); } ctx->tarFHpos = 0; @@ -206,8 +200,7 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) * positioning. */ if (AH->compression != 0) - exit_horribly(modulename, - "compression is not supported by tar archive format\n"); + fatal("compression is not supported by tar archive format"); } else { /* Read Mode */ @@ -215,15 +208,14 @@ InitArchiveFmt_Tar(ArchiveHandle *AH) { ctx->tarFH = fopen(AH->fSpec, PG_BINARY_R); if (ctx->tarFH == NULL) - exit_horribly(modulename, "could not open TOC file \"%s\" for input: %s\n", - AH->fSpec, strerror(errno)); + fatal("could not open TOC file \"%s\" for input: %m", + AH->fSpec); } else { ctx->tarFH = stdin; if (ctx->tarFH == NULL) - exit_horribly(modulename, "could not open TOC file for input: %s\n", - strerror(errno)); + fatal("could not open TOC file for input: %m"); } /* @@ -349,7 +341,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) * Couldn't find the requested file. Future: do SEEK(0) and * retry. */ - exit_horribly(modulename, "could not find file \"%s\" in archive\n", filename); + fatal("could not find file \"%s\" in archive", filename); } else { @@ -363,7 +355,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) if (AH->compression == 0) tm->nFH = ctx->tarFH; else - exit_horribly(modulename, "compression is not supported by tar archive format\n"); + fatal("compression is not supported by tar archive format"); /* tm->zFH = gzdopen(dup(fileno(ctx->tarFH)), "rb"); */ #else tm->nFH = ctx->tarFH; @@ -415,7 +407,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) #endif if (tm->tmpFH == NULL) - exit_horribly(modulename, "could not generate temporary file name: %s\n", strerror(errno)); + fatal("could not generate temporary file name: %m"); umask(old_umask); @@ -426,7 +418,7 @@ tarOpen(ArchiveHandle *AH, const char *filename, char mode) sprintf(fmode, "wb%d", AH->compression); tm->zFH = gzdopen(dup(fileno(tm->tmpFH)), fmode); if (tm->zFH == NULL) - exit_horribly(modulename, "could not open temporary file\n"); + fatal("could not open temporary file"); } else tm->nFH = tm->tmpFH; @@ -453,7 +445,7 @@ tarClose(ArchiveHandle *AH, TAR_MEMBER *th) */ if (AH->compression != 0) if (GZCLOSE(th->zFH) != 0) - exit_horribly(modulename, "could not close tar member\n"); + fatal("could not close tar member"); if (th->mode == 'w') _tarAddFile(AH, th); /* This will close the temp file */ @@ -560,13 +552,11 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh) int errnum; const char *errmsg = gzerror(th->zFH, &errnum); - exit_horribly(modulename, - "could not read from input file: %s\n", - errnum == Z_ERRNO ? strerror(errno) : errmsg); + fatal("could not read from input file: %s", + errnum == Z_ERRNO ? strerror(errno) : errmsg); #else - exit_horribly(modulename, - "could not read from input file: %s\n", - strerror(errno)); + fatal("could not read from input file: %s", + strerror(errno)); #endif } } @@ -578,7 +568,7 @@ _tarReadRaw(ArchiveHandle *AH, void *buf, size_t len, TAR_MEMBER *th, FILE *fh) } } else - exit_horribly(modulename, "internal error -- neither th nor fh specified in tarReadRaw()\n"); + fatal("internal error -- neither th nor fh specified in _tarReadRaw()"); } ctx->tarFHpos += res + used; @@ -700,9 +690,8 @@ _PrintTocData(ArchiveHandle *AH, TocEntry *te) pos1 = (int) strlen(te->copyStmt) - 13; if (pos1 < 6 || strncmp(te->copyStmt, "COPY ", 5) != 0 || strcmp(te->copyStmt + pos1, " FROM stdin;\n") != 0) - exit_horribly(modulename, - "unexpected COPY statement syntax: \"%s\"\n", - te->copyStmt); + fatal("unexpected COPY statement syntax: \"%s\"", + te->copyStmt); /* Emit all but the FROM part ... */ ahwrite(te->copyStmt, 1, pos1, AH); @@ -746,7 +735,7 @@ _LoadBlobs(ArchiveHandle *AH) oid = atooid(&th->targetFile[5]); if (oid != 0) { - ahlog(AH, 1, "restoring large object with OID %u\n", oid); + pg_log_info("restoring large object with OID %u", oid); StartRestoreBlob(AH, oid, AH->public.ropt->dropSchema); @@ -803,8 +792,7 @@ _ReadByte(ArchiveHandle *AH) res = tarRead(&c, 1, ctx->FH); if (res != 1) /* We already would have exited for errors on reads, must be EOF */ - exit_horribly(modulename, - "could not read from input file: end of file\n"); + fatal("could not read from input file: end of file"); ctx->filePos += 1; return c; } @@ -827,8 +815,7 @@ _ReadBuf(ArchiveHandle *AH, void *buf, size_t len) if (tarRead(buf, len, ctx->FH) != len) /* We already would have exited for errors on reads, must be EOF */ - exit_horribly(modulename, - "could not read from input file: end of file\n"); + fatal("could not read from input file: end of file"); ctx->filePos += len; return; @@ -917,7 +904,7 @@ _CloseArchive(ArchiveHandle *AH) /* Sync the output file if one is defined */ if (AH->dosync && AH->fSpec) - (void) fsync_fname(AH->fSpec, false, progname); + (void) fsync_fname(AH->fSpec, false); } AH->FH = NULL; @@ -971,7 +958,7 @@ _StartBlob(ArchiveHandle *AH, TocEntry *te, Oid oid) char *sfx; if (oid == 0) - exit_horribly(modulename, "invalid OID for large object (%u)\n", oid); + fatal("invalid OID for large object (%u)", oid); if (AH->compression != 0) sfx = ".gz"; @@ -1026,6 +1013,7 @@ _EndBlobs(ArchiveHandle *AH, TocEntry *te) static int tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) { + int save_errno = errno; char *p; size_t len = 128; /* initial assumption about buffer size */ size_t cnt; @@ -1038,6 +1026,7 @@ tarPrintf(ArchiveHandle *AH, TAR_MEMBER *th, const char *fmt,...) p = (char *) pg_malloc(len); /* Try to format the data. */ + errno = save_errno; va_start(args, fmt); cnt = pvsnprintf(p, len, fmt, args); va_end(args); @@ -1099,8 +1088,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) fseeko(tmp, 0, SEEK_END); th->fileLen = ftello(tmp); if (th->fileLen < 0) - exit_horribly(modulename, "could not determine seek position in archive file: %s\n", - strerror(errno)); + fatal("could not determine seek position in archive file: %m"); fseeko(tmp, 0, SEEK_SET); _tarWriteHeader(th); @@ -1115,8 +1103,7 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) READ_ERROR_EXIT(tmp); if (fclose(tmp) != 0) /* This *should* delete it... */ - exit_horribly(modulename, "could not close temporary file: %s\n", - strerror(errno)); + fatal("could not close temporary file: %m"); if (len != th->fileLen) { @@ -1125,8 +1112,8 @@ _tarAddFile(ArchiveHandle *AH, TAR_MEMBER *th) snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) len); snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) th->fileLen); - exit_horribly(modulename, "actual file length (%s) does not match expected (%s)\n", - buf1, buf2); + fatal("actual file length (%s) does not match expected (%s)", + buf1, buf2); } pad = ((len + 511) & ~511) - len; @@ -1162,8 +1149,8 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) snprintf(buf1, sizeof(buf1), INT64_FORMAT, (int64) ctx->tarFHpos); snprintf(buf2, sizeof(buf2), INT64_FORMAT, (int64) ctx->tarNextMember); - ahlog(AH, 4, "moving from position %s to next member at file position %s\n", - buf1, buf2); + pg_log_debug("moving from position %s to next member at file position %s", + buf1, buf2); while (ctx->tarFHpos < ctx->tarNextMember) _tarReadRaw(AH, &c, 1, NULL, ctx->tarFH); @@ -1173,7 +1160,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) char buf[100]; snprintf(buf, sizeof(buf), INT64_FORMAT, (int64) ctx->tarFHpos); - ahlog(AH, 4, "now at file position %s\n", buf); + pg_log_debug("now at file position %s", buf); } /* We are at the start of the file, or at the next member */ @@ -1182,7 +1169,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) if (!_tarGetHeader(AH, th)) { if (filename) - exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename); + fatal("could not find header for file \"%s\" in tar archive", filename); else { /* @@ -1196,13 +1183,13 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) while (filename != NULL && strcmp(th->targetFile, filename) != 0) { - ahlog(AH, 4, "skipping tar member %s\n", th->targetFile); + pg_log_debug("skipping tar member %s", th->targetFile); id = atoi(th->targetFile); if ((TocIDRequired(AH, id) & REQ_DATA) != 0) - exit_horribly(modulename, "restoring data out of order is not supported in this archive format: " - "\"%s\" is required, but comes before \"%s\" in the archive file.\n", - th->targetFile, filename); + fatal("restoring data out of order is not supported in this archive format: " + "\"%s\" is required, but comes before \"%s\" in the archive file.", + th->targetFile, filename); /* Header doesn't match, so read to next header */ len = ((th->fileLen + 511) & ~511); /* Padded length */ @@ -1212,7 +1199,7 @@ _tarPositionTo(ArchiveHandle *AH, const char *filename) _tarReadRaw(AH, &header[0], 512, NULL, ctx->tarFH); if (!_tarGetHeader(AH, th)) - exit_horribly(modulename, "could not find header for file \"%s\" in tar archive\n", filename); + fatal("could not find header for file \"%s\" in tar archive", filename); } ctx->tarNextMember = ctx->tarFHpos + ((th->fileLen + 511) & ~511); @@ -1245,11 +1232,10 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) return 0; if (len != 512) - exit_horribly(modulename, - ngettext("incomplete tar header found (%lu byte)\n", - "incomplete tar header found (%lu bytes)\n", - len), - (unsigned long) len); + fatal(ngettext("incomplete tar header found (%lu byte)", + "incomplete tar header found (%lu bytes)", + len), + (unsigned long) len); /* Calc checksum */ chk = tarChecksum(h); @@ -1287,8 +1273,8 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, (uint64) hPos); snprintf(lenbuf, sizeof(lenbuf), UINT64_FORMAT, (uint64) len); - ahlog(AH, 3, "TOC Entry %s at %s (length %s, checksum %d)\n", - tag, posbuf, lenbuf, sum); + pg_log_debug("TOC Entry %s at %s (length %s, checksum %d)", + tag, posbuf, lenbuf, sum); } if (chk != sum) @@ -1297,10 +1283,8 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th) snprintf(posbuf, sizeof(posbuf), UINT64_FORMAT, (uint64) ftello(ctx->tarFH)); - exit_horribly(modulename, - "corrupt tar header found in %s " - "(expected %d, computed %d) file position %s\n", - tag, sum, chk, posbuf); + fatal("corrupt tar header found in %s (expected %d, computed %d) file position %s", + tag, sum, chk, posbuf); } th->targetFile = pg_strdup(tag); diff --git a/src/bin/pg_dump/pg_backup_utils.c b/src/bin/pg_dump/pg_backup_utils.c index df5fe708ba4..6f87c6d6847 100644 --- a/src/bin/pg_dump/pg_backup_utils.c +++ b/src/bin/pg_dump/pg_backup_utils.c @@ -4,7 +4,7 @@ * Utility routines shared by pg_dump and pg_restore * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_backup_utils.c @@ -51,8 +51,7 @@ set_dump_section(const char *arg, int *dumpSections) *dumpSections |= DUMP_POST_DATA; else { - fprintf(stderr, _("%s: unrecognized section name: \"%s\"\n"), - progname, arg); + pg_log_error("unrecognized section name: \"%s\"", arg); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -60,62 +59,15 @@ set_dump_section(const char *arg, int *dumpSections) } -/* - * Write a printf-style message to stderr. - * - * The program name is prepended, if "progname" has been set. - * Also, if modulename isn't NULL, that's included too. - * Note that we'll try to translate the modulename and the fmt string. - */ -void -write_msg(const char *modulename, const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - vwrite_msg(modulename, fmt, ap); - va_end(ap); -} - -/* - * As write_msg, but pass a va_list not variable arguments. - */ -void -vwrite_msg(const char *modulename, const char *fmt, va_list ap) -{ - if (progname) - { - if (modulename) - fprintf(stderr, "%s: [%s] ", progname, _(modulename)); - else - fprintf(stderr, "%s: ", progname); - } - vfprintf(stderr, _(fmt), ap); -} - -/* - * Fail and die, with a message to stderr. Parameters as for write_msg. - * - * Note that on_exit_nicely callbacks will get run. - */ -void -exit_horribly(const char *modulename, const char *fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - vwrite_msg(modulename, fmt, ap); - va_end(ap); - - exit_nicely(1); -} - /* Register a callback to be run when exit_nicely is invoked. */ void on_exit_nicely(on_exit_nicely_callback function, void *arg) { if (on_exit_nicely_index >= MAX_ON_EXIT_NICELY) - exit_horribly(NULL, "out of on_exit_nicely slots\n"); + { + pg_log_fatal("out of on_exit_nicely slots"); + exit_nicely(1); + } on_exit_nicely_list[on_exit_nicely_index].function = function; on_exit_nicely_list[on_exit_nicely_index].arg = arg; on_exit_nicely_index++; diff --git a/src/bin/pg_dump/pg_backup_utils.h b/src/bin/pg_dump/pg_backup_utils.h index 6eaf302fc76..619c9fe08c8 100644 --- a/src/bin/pg_dump/pg_backup_utils.h +++ b/src/bin/pg_dump/pg_backup_utils.h @@ -4,7 +4,7 @@ * Utility routines shared by pg_dump and pg_restore. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_backup_utils.h @@ -15,6 +15,8 @@ #ifndef PG_BACKUP_UTILS_H #define PG_BACKUP_UTILS_H +#include "common/logging.h" + typedef enum /* bits returned by set_dump_section */ { DUMP_PRE_DATA = 0x01, @@ -28,11 +30,9 @@ typedef void (*on_exit_nicely_callback) (int code, void *arg); extern const char *progname; extern void set_dump_section(const char *arg, int *dumpSections); -extern void write_msg(const char *modulename, const char *fmt,...) pg_attribute_printf(2, 3); -extern void vwrite_msg(const char *modulename, const char *fmt, va_list ap) pg_attribute_printf(2, 0); extern void on_exit_nicely(on_exit_nicely_callback function, void *arg); extern void exit_nicely(int code) pg_attribute_noreturn(); -extern void exit_horribly(const char *modulename, const char *fmt,...) pg_attribute_printf(2, 3) pg_attribute_noreturn(); +#define fatal(...) do { pg_log_error(__VA_ARGS__); exit_nicely(1); } while(0) #endif /* PG_BACKUP_UTILS_H */ diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 93c869fd686..f01fea5b913 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -4,7 +4,7 @@ * pg_dump is a utility for dumping out a postgres database * into a script file. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * pg_dump will read the system catalogs in a database and dump out a @@ -33,6 +33,7 @@ #include #include +#include #ifdef HAVE_TERMIOS_H #include #endif @@ -54,6 +55,7 @@ #include "catalog/pg_trigger_d.h" #include "catalog/pg_type_d.h" #include "libpq/libpq-fs.h" +#include "storage/block.h" #include "dumputils.h" #include "parallel.h" @@ -90,8 +92,6 @@ typedef enum OidOptions } OidOptions; /* global decls */ -bool g_verbose; /* User wants verbose narration of our - * activities. */ static bool dosync = true; /* Issue fsync() to make dump durable on disk. */ /* subquery used to convert user ID (eg, datdba) to user name */ @@ -133,43 +133,51 @@ char g_comment_end[10]; static const CatalogId nilCatalogId = {0, 0}; +/* override for standard extra_float_digits setting */ +static bool have_extra_float_digits = false; +static int extra_float_digits; + +/* + * The default number of rows per INSERT when + * --inserts is specified without --rows-per-insert + */ +#define DUMP_DEFAULT_ROWS_PER_INSERT 1 + /* * Macro for producing quoted, schema-qualified name of a dumpable object. - * Note implicit dependence on "fout"; we should get rid of that argument. */ #define fmtQualifiedDumpable(obj) \ - fmtQualifiedId(fout->remoteVersion, \ - (obj)->dobj.namespace->dobj.name, \ + fmtQualifiedId((obj)->dobj.namespace->dobj.name, \ (obj)->dobj.name) static void help(const char *progname); static void setup_connection(Archive *AH, - const char *dumpencoding, const char *dumpsnapshot, - char *use_role); + const char *dumpencoding, const char *dumpsnapshot, + char *use_role); static ArchiveFormat parseArchiveFormat(const char *format, ArchiveMode *mode); static void expand_schema_name_patterns(Archive *fout, - SimpleStringList *patterns, - SimpleOidList *oids, - bool strict_names); + SimpleStringList *patterns, + SimpleOidList *oids, + bool strict_names); static void expand_table_name_patterns(Archive *fout, - SimpleStringList *patterns, - SimpleOidList *oids, - bool strict_names); + SimpleStringList *patterns, + SimpleOidList *oids, + bool strict_names); static NamespaceInfo *findNamespace(Archive *fout, Oid nsoid); static void dumpTableData(Archive *fout, TableDataInfo *tdinfo); static void refreshMatViewData(Archive *fout, TableDataInfo *tdinfo); static void guessConstraintInheritance(TableInfo *tblinfo, int numTables); static void dumpComment(Archive *fout, const char *type, const char *name, - const char *namespace, const char *owner, - CatalogId catalogId, int subid, DumpId dumpId); -static int findComments(Archive *fout, Oid classoid, Oid objoid, - CommentItem **items); + const char *namespace, const char *owner, + CatalogId catalogId, int subid, DumpId dumpId); +static int findComments(Archive *fout, Oid classoid, Oid objoid, + CommentItem **items); static int collectComments(Archive *fout, CommentItem **items); static void dumpSecLabel(Archive *fout, const char *type, const char *name, - const char *namespace, const char *owner, - CatalogId catalogId, int subid, DumpId dumpId); -static int findSecLabels(Archive *fout, Oid classoid, Oid objoid, - SecLabelItem **items); + const char *namespace, const char *owner, + CatalogId catalogId, int subid, DumpId dumpId); +static int findSecLabels(Archive *fout, Oid classoid, Oid objoid, + SecLabelItem **items); static int collectSecLabels(Archive *fout, SecLabelItem **items); static void dumpDumpableObject(Archive *fout, DumpableObject *dobj); static void dumpNamespace(Archive *fout, NamespaceInfo *nspinfo); @@ -214,44 +222,44 @@ static void dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo); static void dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo); static void dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo); static void dumpUserMappings(Archive *fout, - const char *servername, const char *namespace, - const char *owner, CatalogId catalogId, DumpId dumpId); + const char *servername, const char *namespace, + const char *owner, CatalogId catalogId, DumpId dumpId); static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo); static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId, - const char *type, const char *name, const char *subname, - const char *nspname, const char *owner, - const char *acls, const char *racls, - const char *initacls, const char *initracls); + const char *type, const char *name, const char *subname, + const char *nspname, const char *owner, + const char *acls, const char *racls, + const char *initacls, const char *initracls); static void getDependencies(Archive *fout); static void BuildArchiveDependencies(Archive *fout); static void findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj, - DumpId **dependencies, int *nDeps, int *allocDeps); + DumpId **dependencies, int *nDeps, int *allocDeps); static DumpableObject *createBoundaryObjects(void); static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs, - DumpableObject *boundaryObjs); + DumpableObject *boundaryObjs); static void getDomainConstraints(Archive *fout, TypeInfo *tyinfo); -static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, bool oids, char relkind); -static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo, bool oids); +static void getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind); +static void makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo); static void buildMatViewRefreshDependencies(Archive *fout); static void getTableDataFKConstraints(void); static char *format_function_arguments(FuncInfo *finfo, char *funcargs, - bool is_agg); + bool is_agg); static char *format_function_arguments_old(Archive *fout, - FuncInfo *finfo, int nallargs, - char **allargtypes, - char **argmodes, - char **argnames); + FuncInfo *finfo, int nallargs, + char **allargtypes, + char **argmodes, + char **argnames); static char *format_function_signature(Archive *fout, - FuncInfo *finfo, bool honor_quotes); + FuncInfo *finfo, bool honor_quotes); static char *convertRegProcReference(Archive *fout, - const char *proc); + const char *proc); static char *getFormattedOperatorName(Archive *fout, const char *oproid); static char *convertTSFunction(Archive *fout, Oid funcOid); -static Oid findLastBuiltinOid_V71(Archive *fout, const char *); +static Oid findLastBuiltinOid_V71(Archive *fout); static char *getFormattedTypeName(Archive *fout, Oid oid, OidOptions opts); static void getBlobs(Archive *fout); static void dumpBlob(Archive *fout, BlobInfo *binfo); @@ -262,29 +270,29 @@ static void dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo); static void dumpSubscription(Archive *fout, SubscriptionInfo *subinfo); static void dumpDatabase(Archive *AH); static void dumpDatabaseConfig(Archive *AH, PQExpBuffer outbuf, - const char *dbname, Oid dboid); + const char *dbname, Oid dboid); static void dumpEncoding(Archive *AH); static void dumpStdStrings(Archive *AH); static void dumpSearchPath(Archive *AH); static void binary_upgrade_set_type_oids_by_type_oid(Archive *fout, - PQExpBuffer upgrade_buffer, - Oid pg_type_oid, - bool force_array_type); + PQExpBuffer upgrade_buffer, + Oid pg_type_oid, + bool force_array_type); static bool binary_upgrade_set_type_oids_by_rel_oid(Archive *fout, - PQExpBuffer upgrade_buffer, Oid pg_rel_oid); + PQExpBuffer upgrade_buffer, Oid pg_rel_oid); static void binary_upgrade_set_pg_class_oids(Archive *fout, - PQExpBuffer upgrade_buffer, - Oid pg_class_oid, bool is_index); + PQExpBuffer upgrade_buffer, + Oid pg_class_oid, bool is_index); static void binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, - DumpableObject *dobj, - const char *objtype, - const char *objname, - const char *objnamespace); + DumpableObject *dobj, + const char *objtype, + const char *objname, + const char *objnamespace); static const char *getAttrName(int attrnum, TableInfo *tblInfo); static const char *fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer); static bool nonemptyReloptions(const char *reloptions); static void appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, - const char *prefix, Archive *fout); + const char *prefix, Archive *fout); static char *get_synchronized_snapshot(Archive *fout); static void setupDumpWorker(Archive *AHX); static TableInfo *getRootTableInfo(TableInfo *tbinfo); @@ -303,11 +311,14 @@ main(int argc, char **argv) DumpableObject *boundaryObjs; int i; int optindex; + char *endptr; RestoreOptions *ropt; Archive *fout; /* the script file */ + bool g_verbose = false; const char *dumpencoding = NULL; const char *dumpsnapshot = NULL; char *use_role = NULL; + long rowsPerInsert; int numWorkers = 1; trivalue prompt_password = TRI_DEFAULT; int compressLevel = -1; @@ -329,7 +340,6 @@ main(int argc, char **argv) {"host", required_argument, NULL, 'h'}, {"jobs", 1, NULL, 'j'}, {"no-reconnect", no_argument, NULL, 'R'}, - {"oids", no_argument, NULL, 'o'}, {"no-owner", no_argument, NULL, 'O'}, {"port", required_argument, NULL, 'p'}, {"schema", required_argument, NULL, 'n'}, @@ -359,8 +369,9 @@ main(int argc, char **argv) {"disable-triggers", no_argument, &dopt.disable_triggers, 1}, {"enable-row-security", no_argument, &dopt.enable_row_security, 1}, {"exclude-table-data", required_argument, NULL, 4}, + {"extra-float-digits", required_argument, NULL, 8}, {"if-exists", no_argument, &dopt.if_exists, 1}, - {"inserts", no_argument, &dopt.dump_inserts, 1}, + {"inserts", no_argument, NULL, 9}, {"lock-wait-timeout", required_argument, NULL, 2}, {"no-tablespaces", no_argument, &dopt.outputNoTablespaces, 1}, {"quote-all-identifiers", no_argument, "e_all_identifiers, 1}, @@ -378,10 +389,14 @@ main(int argc, char **argv) {"no-unlogged-table-data", no_argument, &dopt.no_unlogged_table_data, 1}, {"no-subscriptions", no_argument, &dopt.no_subscriptions, 1}, {"no-sync", no_argument, NULL, 7}, + {"on-conflict-do-nothing", no_argument, &dopt.do_nothing, 1}, + {"rows-per-insert", required_argument, NULL, 10}, {NULL, 0, NULL, 0} }; + pg_logging_init(argv[0]); + pg_logging_set_level(PG_LOG_WARNING); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump")); /* @@ -390,8 +405,6 @@ main(int argc, char **argv) */ init_parallel_dump_utils(); - g_verbose = false; - strcpy(g_comment_start, "-- "); g_comment_end[0] = '\0'; strcpy(g_opaque_type, "opaque"); @@ -414,7 +427,7 @@ main(int argc, char **argv) InitDumpOptions(&dopt); - while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:oOp:RsS:t:T:U:vwWxZ:", + while ((c = getopt_long(argc, argv, "abBcCd:E:f:F:h:j:n:N:Op:RsS:t:T:U:vwWxZ:", long_options, &optindex)) != -1) { switch (c) @@ -472,10 +485,6 @@ main(int argc, char **argv) simple_string_list_append(&schema_exclude_patterns, optarg); break; - case 'o': /* Dump oids */ - dopt.oids = true; - break; - case 'O': /* Don't reconnect to match owner */ dopt.outputNoOwner = 1; break; @@ -511,6 +520,7 @@ main(int argc, char **argv) case 'v': /* verbose */ g_verbose = true; + pg_logging_set_level(PG_LOG_INFO); break; case 'w': @@ -529,7 +539,7 @@ main(int argc, char **argv) compressLevel = atoi(optarg); if (compressLevel < 0 || compressLevel > 9) { - write_msg(NULL, "compression level must be in range 0..9\n"); + pg_log_error("compression level must be in range 0..9"); exit_nicely(1); } break; @@ -562,6 +572,41 @@ main(int argc, char **argv) dosync = false; break; + case 8: + have_extra_float_digits = true; + extra_float_digits = atoi(optarg); + if (extra_float_digits < -15 || extra_float_digits > 3) + { + pg_log_error("extra_float_digits must be in range -15..3"); + exit_nicely(1); + } + break; + + case 9: /* inserts */ + + /* + * dump_inserts also stores --rows-per-insert, careful not to + * overwrite that. + */ + if (dopt.dump_inserts == 0) + dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT; + break; + + case 10: /* rows per insert */ + errno = 0; + rowsPerInsert = strtol(optarg, &endptr, 10); + + if (endptr == optarg || *endptr != '\0' || + rowsPerInsert <= 0 || rowsPerInsert > INT_MAX || + errno == ERANGE) + { + pg_log_error("rows-per-insert must be in range %d..%d", + 1, INT_MAX); + exit_nicely(1); + } + dopt.dump_inserts = (int) rowsPerInsert; + break; + default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -578,16 +623,16 @@ main(int argc, char **argv) /* Complain if any arguments remain */ if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); } /* --column-inserts implies --inserts */ - if (dopt.column_inserts) - dopt.dump_inserts = 1; + if (dopt.column_inserts && dopt.dump_inserts == 0) + dopt.dump_inserts = DUMP_DEFAULT_ROWS_PER_INSERT; /* * Binary upgrade mode implies dumping sequence data even in schema-only @@ -599,25 +644,25 @@ main(int argc, char **argv) if (dopt.dataOnly && dopt.schemaOnly) { - write_msg(NULL, "options -s/--schema-only and -a/--data-only cannot be used together\n"); + pg_log_error("options -s/--schema-only and -a/--data-only cannot be used together"); exit_nicely(1); } if (dopt.dataOnly && dopt.outputClean) { - write_msg(NULL, "options -c/--clean and -a/--data-only cannot be used together\n"); - exit_nicely(1); - } - - if (dopt.dump_inserts && dopt.oids) - { - write_msg(NULL, "options --inserts/--column-inserts and -o/--oids cannot be used together\n"); - write_msg(NULL, "(The INSERT command cannot set OIDs.)\n"); + pg_log_error("options -c/--clean and -a/--data-only cannot be used together"); exit_nicely(1); } if (dopt.if_exists && !dopt.outputClean) - exit_horribly(NULL, "option --if-exists requires option -c/--clean\n"); + fatal("option --if-exists requires option -c/--clean"); + + /* + * --inserts are already implied above if --column-inserts or + * --rows-per-insert were specified. + */ + if (dopt.do_nothing && dopt.dump_inserts == 0) + fatal("option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts"); /* Identify archive format to emit */ archiveFormat = parseArchiveFormat(format, &archiveMode); @@ -639,8 +684,7 @@ main(int argc, char **argv) #ifndef HAVE_LIBZ if (compressLevel != 0) - write_msg(NULL, "WARNING: requested compression not available in this " - "installation -- archive will be uncompressed\n"); + pg_log_warning("requested compression not available in this installation -- archive will be uncompressed"); compressLevel = 0; #endif @@ -661,11 +705,11 @@ main(int argc, char **argv) || numWorkers > MAXIMUM_WAIT_OBJECTS #endif ) - exit_horribly(NULL, "invalid number of parallel jobs\n"); + fatal("invalid number of parallel jobs"); /* Parallel backup only in the directory archive format so far */ if (archiveFormat != archDirectory && numWorkers > 1) - exit_horribly(NULL, "parallel backup only supported by the directory format\n"); + fatal("parallel backup only supported by the directory format"); /* Open the output file */ fout = CreateArchive(filename, archiveFormat, compressLevel, dosync, @@ -680,6 +724,7 @@ main(int argc, char **argv) /* Let the archiver know how noisy to be */ fout->verbose = g_verbose; + /* * We allow the server to be back to 8.0, and up to any minor release of * our own major version. (See also version check in pg_dumpall.c.) @@ -719,15 +764,13 @@ main(int argc, char **argv) /* check the version for the synchronized snapshots feature */ if (numWorkers > 1 && fout->remoteVersion < 90200 && !dopt.no_synchronized_snapshots) - exit_horribly(NULL, - "Synchronized snapshots are not supported by this server version.\n" - "Run with --no-synchronized-snapshots instead if you do not need\n" - "synchronized snapshots.\n"); + fatal("Synchronized snapshots are not supported by this server version.\n" + "Run with --no-synchronized-snapshots instead if you do not need\n" + "synchronized snapshots."); /* check the version when a snapshot is explicitly specified by user */ if (dumpsnapshot && fout->remoteVersion < 90200) - exit_horribly(NULL, - "Exported snapshots are not supported by this server version.\n"); + fatal("Exported snapshots are not supported by this server version."); /* * Find the last built-in OID, if needed (prior to 8.1) @@ -735,13 +778,11 @@ main(int argc, char **argv) * With 8.1 and above, we can just use FirstNormalObjectId - 1. */ if (fout->remoteVersion < 80100) - g_last_builtin_oid = findLastBuiltinOid_V71(fout, - PQdb(GetConnection(fout))); + g_last_builtin_oid = findLastBuiltinOid_V71(fout); else g_last_builtin_oid = FirstNormalObjectId - 1; - if (g_verbose) - write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid); + pg_log_info("last built-in OID is %u", g_last_builtin_oid); /* Expand schema selection patterns into OID lists */ if (schema_include_patterns.head != NULL) @@ -750,7 +791,7 @@ main(int argc, char **argv) &schema_include_oids, strict_names); if (schema_include_oids.head == NULL) - exit_horribly(NULL, "no matching schemas were found\n"); + fatal("no matching schemas were found"); } expand_schema_name_patterns(fout, &schema_exclude_patterns, &schema_exclude_oids, @@ -764,7 +805,7 @@ main(int argc, char **argv) &table_include_oids, strict_names); if (table_include_oids.head == NULL) - exit_horribly(NULL, "no matching tables were found\n"); + fatal("no matching tables were found"); } expand_table_name_patterns(fout, &table_exclude_patterns, &table_exclude_oids, @@ -799,14 +840,14 @@ main(int argc, char **argv) if (!dopt.schemaOnly) { - getTableData(&dopt, tblinfo, numTables, dopt.oids, 0); + getTableData(&dopt, tblinfo, numTables, 0); buildMatViewRefreshDependencies(fout); if (dopt.dataOnly) getTableDataFKConstraints(); } if (dopt.schemaOnly && dopt.sequence_data) - getTableData(&dopt, tblinfo, numTables, dopt.oids, RELKIND_SEQUENCE); + getTableData(&dopt, tblinfo, numTables, RELKIND_SEQUENCE); /* * In binary-upgrade mode, we do not have to worry about the actual blob @@ -844,10 +885,6 @@ main(int argc, char **argv) */ sortDumpableObjectsByTypeName(dobjs, numObjs); - /* If we do a parallel dump, we want the largest tables to go first */ - if (archiveFormat == archDirectory && numWorkers > 1) - sortDataAndIndexObjectsBySize(dobjs, numObjs); - sortDumpableObjects(dobjs, numObjs, boundaryObjs[0].dumpId, boundaryObjs[1].dumpId); @@ -963,15 +1000,14 @@ help(const char *progname) printf(_(" -c, --clean clean (drop) database objects before recreating\n")); printf(_(" -C, --create include commands to create database in dump\n")); printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n")); - printf(_(" -n, --schema=SCHEMA dump the named schema(s) only\n")); - printf(_(" -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n")); - printf(_(" -o, --oids include OIDs in dump\n")); + printf(_(" -n, --schema=PATTERN dump the specified schema(s) only\n")); + printf(_(" -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)\n")); printf(_(" -O, --no-owner skip restoration of object ownership in\n" " plain-text format\n")); printf(_(" -s, --schema-only dump only the schema, no data\n")); printf(_(" -S, --superuser=NAME superuser user name to use in plain-text format\n")); - printf(_(" -t, --table=TABLE dump the named table(s) only\n")); - printf(_(" -T, --exclude-table=TABLE do NOT dump the named table(s)\n")); + printf(_(" -t, --table=PATTERN dump the specified table(s) only\n")); + printf(_(" -T, --exclude-table=PATTERN do NOT dump the specified table(s)\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" --binary-upgrade for use by upgrade utilities only\n")); printf(_(" --column-inserts dump data as INSERT commands with column names\n")); @@ -979,9 +1015,11 @@ help(const char *progname) printf(_(" --disable-triggers disable triggers during data-only restore\n")); printf(_(" --enable-row-security enable row security (dump only content user has\n" " access to)\n")); - printf(_(" --exclude-table-data=TABLE do NOT dump data for the named table(s)\n")); + printf(_(" --exclude-table-data=PATTERN do NOT dump data for the specified table(s)\n")); + printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n")); printf(_(" --if-exists use IF EXISTS when dropping objects\n")); printf(_(" --inserts dump data as INSERT commands, rather than COPY\n")); + printf(_(" --load-via-partition-root load partitions via the root table\n")); printf(_(" --no-comments do not dump comments\n")); printf(_(" --no-publications do not dump publications\n")); printf(_(" --no-security-labels do not dump security label assignments\n")); @@ -989,8 +1027,9 @@ help(const char *progname) printf(_(" --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n")); printf(_(" --no-tablespaces do not dump tablespace assignments\n")); printf(_(" --no-unlogged-table-data do not dump unlogged table data\n")); + printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n")); printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n")); - printf(_(" --load-via-partition-root load partitions via the root table\n")); + printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n")); printf(_(" --section=SECTION dump named section (pre-data, data, or post-data)\n")); printf(_(" --serializable-deferrable wait until the dump can run without anomalies\n")); printf(_(" --snapshot=SNAPSHOT use given snapshot for the dump\n")); @@ -1011,7 +1050,7 @@ help(const char *progname) printf(_("\nIf no database name is supplied, then the PGDATABASE environment\n" "variable value is used.\n\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } static void @@ -1030,8 +1069,8 @@ setup_connection(Archive *AH, const char *dumpencoding, if (dumpencoding) { if (PQsetClientEncoding(conn, dumpencoding) < 0) - exit_horribly(NULL, "invalid client encoding \"%s\" specified\n", - dumpencoding); + fatal("invalid client encoding \"%s\" specified", + dumpencoding); } /* @@ -1073,10 +1112,20 @@ setup_connection(Archive *AH, const char *dumpencoding, ExecuteSqlStatement(AH, "SET INTERVALSTYLE = POSTGRES"); /* - * Set extra_float_digits so that we can dump float data exactly (given - * correctly implemented float I/O code, anyway) + * Use an explicitly specified extra_float_digits if it has been provided. + * Otherwise, set extra_float_digits so that we can dump float data + * exactly (given correctly implemented float I/O code, anyway). */ - if (AH->remoteVersion >= 90000) + if (have_extra_float_digits) + { + PQExpBuffer q = createPQExpBuffer(); + + appendPQExpBuffer(q, "SET extra_float_digits TO %d", + extra_float_digits); + ExecuteSqlStatement(AH, q->data); + destroyPQExpBuffer(q); + } + else if (AH->remoteVersion >= 90000) ExecuteSqlStatement(AH, "SET extra_float_digits TO 3"); else ExecuteSqlStatement(AH, "SET extra_float_digits TO 2"); @@ -1156,7 +1205,7 @@ setup_connection(Archive *AH, const char *dumpencoding, { PQExpBuffer query = createPQExpBuffer(); - appendPQExpBuffer(query, "SET TRANSACTION SNAPSHOT "); + appendPQExpBufferStr(query, "SET TRANSACTION SNAPSHOT "); appendStringLiteralConn(query, AH->sync_snapshot_id, conn); ExecuteSqlStatement(AH, query->data); destroyPQExpBuffer(query); @@ -1166,10 +1215,9 @@ setup_connection(Archive *AH, const char *dumpencoding, !dopt->no_synchronized_snapshots) { if (AH->isStandby && AH->remoteVersion < 100000) - exit_horribly(NULL, - "Synchronized snapshots on standby servers are not supported by this server version.\n" - "Run with --no-synchronized-snapshots instead if you do not need\n" - "synchronized snapshots.\n"); + fatal("Synchronized snapshots on standby servers are not supported by this server version.\n" + "Run with --no-synchronized-snapshots instead if you do not need\n" + "synchronized snapshots."); AH->sync_snapshot_id = get_synchronized_snapshot(AH); @@ -1236,7 +1284,7 @@ parseArchiveFormat(const char *format, ArchiveMode *mode) else if (pg_strcasecmp(format, "tar") == 0) archiveFormat = archTar; else - exit_horribly(NULL, "invalid output format \"%s\" specified\n", format); + fatal("invalid output format \"%s\" specified", format); return archiveFormat; } @@ -1267,14 +1315,14 @@ expand_schema_name_patterns(Archive *fout, for (cell = patterns->head; cell; cell = cell->next) { - appendPQExpBuffer(query, - "SELECT oid FROM pg_catalog.pg_namespace n\n"); + appendPQExpBufferStr(query, + "SELECT oid FROM pg_catalog.pg_namespace n\n"); processSQLNamePattern(GetConnection(fout), query, cell->val, false, false, NULL, "n.nspname", NULL, NULL); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); if (strict_names && PQntuples(res) == 0) - exit_horribly(NULL, "no matching schemas were found for pattern \"%s\"\n", cell->val); + fatal("no matching schemas were found for pattern \"%s\"", cell->val); for (i = 0; i < PQntuples(res); i++) { @@ -1290,7 +1338,8 @@ expand_schema_name_patterns(Archive *fout, /* * Find the OIDs of all tables matching the given list of patterns, - * and append them to the given OID list. + * and append them to the given OID list. See also expand_dbname_patterns() + * in pg_dumpall.c */ static void expand_table_name_patterns(Archive *fout, @@ -1338,7 +1387,7 @@ expand_table_name_patterns(Archive *fout, PQclear(ExecuteSqlQueryForSingleRow(fout, ALWAYS_SECURE_SEARCH_PATH_SQL)); if (strict_names && PQntuples(res) == 0) - exit_horribly(NULL, "no matching tables were found for pattern \"%s\"\n", cell->val); + fatal("no matching tables were found for pattern \"%s\"", cell->val); for (i = 0; i < PQntuples(res); i++) { @@ -1739,8 +1788,6 @@ dumpTableData_copy(Archive *fout, void *dcontext) TableDataInfo *tdinfo = (TableDataInfo *) dcontext; TableInfo *tbinfo = tdinfo->tdtable; const char *classname = tbinfo->dobj.name; - const bool hasoids = tbinfo->hasoids; - const bool oids = tdinfo->oids; PQExpBuffer q = createPQExpBuffer(); /* @@ -1754,9 +1801,8 @@ dumpTableData_copy(Archive *fout, void *dcontext) char *copybuf; const char *column_list; - if (g_verbose) - write_msg(NULL, "dumping contents of table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, classname); + pg_log_info("dumping contents of table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, classname); /* * Specify the column list explicitly so that we have no possibility of @@ -1766,13 +1812,7 @@ dumpTableData_copy(Archive *fout, void *dcontext) */ column_list = fmtCopyColumnList(tbinfo, clistBuf); - if (oids && hasoids) - { - appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;", - fmtQualifiedDumpable(tbinfo), - column_list); - } - else if (tdinfo->filtercond) + if (tdinfo->filtercond) { /* Note: this syntax is only supported in 8.2 and up */ appendPQExpBufferStr(q, "COPY (SELECT "); @@ -1862,9 +1902,9 @@ dumpTableData_copy(Archive *fout, void *dcontext) if (ret == -2) { /* copy data transfer failed */ - write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n", classname); - write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn)); - write_msg(NULL, "The command was: %s\n", q->data); + pg_log_error("Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.", classname); + pg_log_error("Error message from server: %s", PQerrorMessage(conn)); + pg_log_error("The command was: %s", q->data); exit_nicely(1); } @@ -1872,17 +1912,17 @@ dumpTableData_copy(Archive *fout, void *dcontext) res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK) { - write_msg(NULL, "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n", classname); - write_msg(NULL, "Error message from server: %s", PQerrorMessage(conn)); - write_msg(NULL, "The command was: %s\n", q->data); + pg_log_error("Dumping the contents of table \"%s\" failed: PQgetResult() failed.", classname); + pg_log_error("Error message from server: %s", PQerrorMessage(conn)); + pg_log_error("The command was: %s", q->data); exit_nicely(1); } PQclear(res); /* Do this to ensure we've pumped libpq back to idle state */ if (PQgetResult(conn) != NULL) - write_msg(NULL, "WARNING: unexpected extra results during COPY of table \"%s\"\n", - classname); + pg_log_warning("unexpected extra results during COPY of table \"%s\"", + classname); destroyPQExpBuffer(q); return 1; @@ -1905,9 +1945,9 @@ dumpTableData_insert(Archive *fout, void *dcontext) PQExpBuffer q = createPQExpBuffer(); PQExpBuffer insertStmt = NULL; PGresult *res; - int tuple; int nfields; - int field; + int rows_per_statement = dopt->dump_inserts; + int rows_this_statement = 0; appendPQExpBuffer(q, "DECLARE _pg_dump_cursor CURSOR FOR " "SELECT * FROM ONLY %s", @@ -1922,72 +1962,96 @@ dumpTableData_insert(Archive *fout, void *dcontext) res = ExecuteSqlQuery(fout, "FETCH 100 FROM _pg_dump_cursor", PGRES_TUPLES_OK); nfields = PQnfields(res); - for (tuple = 0; tuple < PQntuples(res); tuple++) + + /* + * First time through, we build as much of the INSERT statement as + * possible in "insertStmt", which we can then just print for each + * statement. If the table happens to have zero columns then this will + * be a complete statement, otherwise it will end in "VALUES" and be + * ready to have the row's column values printed. + */ + if (insertStmt == NULL) { - /* - * First time through, we build as much of the INSERT statement as - * possible in "insertStmt", which we can then just print for each - * line. If the table happens to have zero columns then this will - * be a complete statement, otherwise it will end in "VALUES(" and - * be ready to have the row's column values appended. - */ - if (insertStmt == NULL) - { - TableInfo *targettab; + TableInfo *targettab; - insertStmt = createPQExpBuffer(); + insertStmt = createPQExpBuffer(); - /* - * When load-via-partition-root is set, get the root table - * name for the partition table, so that we can reload data - * through the root table. - */ - if (dopt->load_via_partition_root && tbinfo->ispartition) - targettab = getRootTableInfo(tbinfo); - else - targettab = tbinfo; + /* + * When load-via-partition-root is set, get the root table name + * for the partition table, so that we can reload data through the + * root table. + */ + if (dopt->load_via_partition_root && tbinfo->ispartition) + targettab = getRootTableInfo(tbinfo); + else + targettab = tbinfo; - appendPQExpBuffer(insertStmt, "INSERT INTO %s ", - fmtQualifiedDumpable(targettab)); + appendPQExpBuffer(insertStmt, "INSERT INTO %s ", + fmtQualifiedDumpable(targettab)); - /* corner case for zero-column table */ - if (nfields == 0) - { - appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n"); - } - else + /* corner case for zero-column table */ + if (nfields == 0) + { + appendPQExpBufferStr(insertStmt, "DEFAULT VALUES;\n"); + } + else + { + /* append the list of column names if required */ + if (dopt->column_inserts) { - /* append the list of column names if required */ - if (dopt->column_inserts) + appendPQExpBufferChar(insertStmt, '('); + for (int field = 0; field < nfields; field++) { - appendPQExpBufferChar(insertStmt, '('); - for (field = 0; field < nfields; field++) - { - if (field > 0) - appendPQExpBufferStr(insertStmt, ", "); - appendPQExpBufferStr(insertStmt, - fmtId(PQfname(res, field))); - } - appendPQExpBufferStr(insertStmt, ") "); + if (field > 0) + appendPQExpBufferStr(insertStmt, ", "); + appendPQExpBufferStr(insertStmt, + fmtId(PQfname(res, field))); } + appendPQExpBufferStr(insertStmt, ") "); + } - if (tbinfo->needs_override) - appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE "); + if (tbinfo->needs_override) + appendPQExpBufferStr(insertStmt, "OVERRIDING SYSTEM VALUE "); - appendPQExpBufferStr(insertStmt, "VALUES ("); - } + appendPQExpBufferStr(insertStmt, "VALUES"); } + } - archputs(insertStmt->data, fout); + for (int tuple = 0; tuple < PQntuples(res); tuple++) + { + /* Write the INSERT if not in the middle of a multi-row INSERT. */ + if (rows_this_statement == 0) + archputs(insertStmt->data, fout); - /* if it is zero-column table then we're done */ + /* + * If it is zero-column table then we've already written the + * complete statement, which will mean we've disobeyed + * --rows-per-insert when it's set greater than 1. We do support + * a way to make this multi-row with: SELECT UNION ALL SELECT + * UNION ALL ... but that's non-standard so we should avoid it + * given that using INSERTs is mostly only ever needed for + * cross-database exports. + */ if (nfields == 0) continue; - for (field = 0; field < nfields; field++) + /* Emit a row heading */ + if (rows_per_statement == 1) + archputs(" (", fout); + else if (rows_this_statement > 0) + archputs(",\n\t(", fout); + else + archputs("\n\t(", fout); + + for (int field = 0; field < nfields; field++) { if (field > 0) archputs(", ", fout); + if (tbinfo->attgenerated[field]) + { + archputs("DEFAULT", fout); + continue; + } if (PQgetisnull(res, tuple, field)) { archputs("NULL", fout); @@ -2048,7 +2112,20 @@ dumpTableData_insert(Archive *fout, void *dcontext) break; } } - archputs(");\n", fout); + + /* Terminate the row ... */ + archputs(")", fout); + + /* ... and the statement, if the target no. of rows is reached */ + if (++rows_this_statement >= rows_per_statement) + { + if (dopt->do_nothing) + archputs(" ON CONFLICT DO NOTHING;\n", fout); + else + archputs(";\n", fout); + /* Reset the row counter */ + rows_this_statement = 0; + } } if (PQntuples(res) <= 0) @@ -2059,6 +2136,15 @@ dumpTableData_insert(Archive *fout, void *dcontext) PQclear(res); } + /* Terminate any statements that didn't make the row count. */ + if (rows_this_statement > 0) + { + if (dopt->do_nothing) + archputs(" ON CONFLICT DO NOTHING;\n", fout); + else + archputs(";\n", fout); + } + archputs("\n\n", fout); ExecuteSqlStatement(fout, "CLOSE _pg_dump_cursor"); @@ -2132,9 +2218,8 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo) /* must use 2 steps here 'cause fmtId is nonreentrant */ appendPQExpBuffer(copyBuf, "COPY %s ", copyFrom); - appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n", - fmtCopyColumnList(tbinfo, clistBuf), - (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : ""); + appendPQExpBuffer(copyBuf, "%s FROM stdin;\n", + fmtCopyColumnList(tbinfo, clistBuf)); copyStmt = copyBuf->data; } else @@ -2150,13 +2235,32 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo) * See comments for BuildArchiveDependencies. */ if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA) - ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId, - tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name, - NULL, tbinfo->rolname, - false, "TABLE DATA", SECTION_DATA, - "", "", copyStmt, - &(tbinfo->dobj.dumpId), 1, - dumpFn, tdinfo); + { + TocEntry *te; + + te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId, + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "TABLE DATA", + .section = SECTION_DATA, + .copyStmt = copyStmt, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1, + .dumpFn = dumpFn, + .dumpArg = tdinfo)); + + /* + * Set the TocEntry's dataLength in case we are doing a parallel dump + * and want to order dump jobs by table size. We choose to measure + * dataLength in table pages during dump, so no scaling is needed. + * However, relpages is declared as "integer" in pg_class, and hence + * also in TableInfo, but it's really BlockNumber a/k/a unsigned int. + * Cast so that we get the right interpretation of table sizes + * exceeding INT_MAX pages. + */ + te->dataLength = (BlockNumber) tbinfo->relpages; + } destroyPQExpBuffer(copyBuf); destroyPQExpBuffer(clistBuf); @@ -2188,20 +2292,14 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo) ArchiveEntry(fout, tdinfo->dobj.catId, /* catalog ID */ tdinfo->dobj.dumpId, /* dump ID */ - tbinfo->dobj.name, /* Name */ - tbinfo->dobj.namespace->dobj.name, /* Namespace */ - NULL, /* Tablespace */ - tbinfo->rolname, /* Owner */ - false, /* with oids */ - "MATERIALIZED VIEW DATA", /* Desc */ - SECTION_POST_DATA, /* Section */ - q->data, /* Create */ - "", /* Del */ - NULL, /* Copy */ - tdinfo->dobj.dependencies, /* Deps */ - tdinfo->dobj.nDeps, /* # Deps */ - NULL, /* Dumper */ - NULL); /* Dumper Arg */ + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "MATERIALIZED VIEW DATA", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .deps = tdinfo->dobj.dependencies, + .nDeps = tdinfo->dobj.nDeps)); destroyPQExpBuffer(q); } @@ -2211,7 +2309,7 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo) * set up dumpable objects representing the contents of tables */ static void -getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, bool oids, char relkind) +getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, char relkind) { int i; @@ -2219,7 +2317,7 @@ getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, bool oids, ch { if (tblinfo[i].dobj.dump & DUMP_COMPONENT_DATA && (!relkind || tblinfo[i].relkind == relkind)) - makeTableDataInfo(dopt, &(tblinfo[i]), oids); + makeTableDataInfo(dopt, &(tblinfo[i])); } } @@ -2230,7 +2328,7 @@ getTableData(DumpOptions *dopt, TableInfo *tblinfo, int numTables, bool oids, ch * table data; the "dump" flag in such objects isn't used. */ static void -makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo, bool oids) +makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo) { TableDataInfo *tdinfo; @@ -2281,7 +2379,6 @@ makeTableDataInfo(DumpOptions *dopt, TableInfo *tbinfo, bool oids) tdinfo->dobj.name = tbinfo->dobj.name; tdinfo->dobj.namespace = tbinfo->dobj.namespace; tdinfo->tdtable = tbinfo; - tdinfo->oids = oids; tdinfo->filtercond = NULL; /* might get set later */ addObjectDependency(&tdinfo->dobj, tbinfo->dobj.dumpId); @@ -2538,6 +2635,7 @@ dumpDatabase(Archive *fout) PGresult *res; int i_tableoid, i_oid, + i_datname, i_dba, i_encoding, i_collate, @@ -2565,39 +2663,55 @@ dumpDatabase(Archive *fout) minmxid; char *qdatname; - datname = PQdb(conn); - qdatname = pg_strdup(fmtId(datname)); + pg_log_info("saving database definition"); - if (g_verbose) - write_msg(NULL, "saving database definition\n"); - - /* Fetch the database-level properties for this database */ + /* + * Fetch the database-level properties for this database. + * + * The order in which privileges are in the ACL string (the order they + * have been GRANT'd in, which the backend maintains) must be preserved to + * ensure that GRANTs WITH GRANT OPTION and subsequent GRANTs based on + * those are dumped in the correct order. Note that initial privileges + * (pg_init_privs) are not supported on databases, so this logic cannot + * make use of buildACLQueries(). + */ if (fout->remoteVersion >= 90600) { - appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " + appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "datcollate, datctype, datfrozenxid, datminmxid, " - "(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( " - " SELECT unnest(coalesce(datacl,acldefault('d',datdba))) AS acl " - " EXCEPT SELECT unnest(acldefault('d',datdba))) as datacls)" + "(SELECT array_agg(acl ORDER BY row_n) FROM " + " (SELECT acl, row_n FROM " + " unnest(coalesce(datacl,acldefault('d',datdba))) " + " WITH ORDINALITY AS perm(acl,row_n) " + " WHERE NOT EXISTS ( " + " SELECT 1 " + " FROM unnest(acldefault('d',datdba)) " + " AS init(init_acl) " + " WHERE acl = init_acl)) AS datacls) " " AS datacl, " - "(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( " - " SELECT unnest(acldefault('d',datdba)) AS acl " - " EXCEPT SELECT unnest(coalesce(datacl,acldefault('d',datdba)))) as rdatacls)" + "(SELECT array_agg(acl ORDER BY row_n) FROM " + " (SELECT acl, row_n FROM " + " unnest(acldefault('d',datdba)) " + " WITH ORDINALITY AS initp(acl,row_n) " + " WHERE NOT EXISTS ( " + " SELECT 1 " + " FROM unnest(coalesce(datacl,acldefault('d',datdba))) " + " AS permp(orig_acl) " + " WHERE acl = orig_acl)) AS rdatacls) " " AS rdatacl, " "datistemplate, datconnlimit, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, " "shobj_description(oid, 'pg_database') AS description " "FROM pg_database " - "WHERE datname = ", + "WHERE datname = current_database()", username_subquery); - appendStringLiteralAH(dbQry, datname, fout); } else if (fout->remoteVersion >= 90300) { - appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " + appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "datcollate, datctype, datfrozenxid, datminmxid, " @@ -2606,13 +2720,12 @@ dumpDatabase(Archive *fout) "shobj_description(oid, 'pg_database') AS description " "FROM pg_database " - "WHERE datname = ", + "WHERE datname = current_database()", username_subquery); - appendStringLiteralAH(dbQry, datname, fout); } else if (fout->remoteVersion >= 80400) { - appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " + appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "datcollate, datctype, datfrozenxid, 0 AS datminmxid, " @@ -2621,13 +2734,12 @@ dumpDatabase(Archive *fout) "shobj_description(oid, 'pg_database') AS description " "FROM pg_database " - "WHERE datname = ", + "WHERE datname = current_database()", username_subquery); - appendStringLiteralAH(dbQry, datname, fout); } else if (fout->remoteVersion >= 80200) { - appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " + appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, " @@ -2636,13 +2748,12 @@ dumpDatabase(Archive *fout) "shobj_description(oid, 'pg_database') AS description " "FROM pg_database " - "WHERE datname = ", + "WHERE datname = current_database()", username_subquery); - appendStringLiteralAH(dbQry, datname, fout); } else { - appendPQExpBuffer(dbQry, "SELECT tableoid, oid, " + appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, " "(%s datdba) AS dba, " "pg_encoding_to_char(encoding) AS encoding, " "NULL AS datcollate, NULL AS datctype, datfrozenxid, 0 AS datminmxid, " @@ -2650,15 +2761,15 @@ dumpDatabase(Archive *fout) "-1 as datconnlimit, " "(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace " "FROM pg_database " - "WHERE datname = ", + "WHERE datname = current_database()", username_subquery); - appendStringLiteralAH(dbQry, datname, fout); } res = ExecuteSqlQueryForSingleRow(fout, dbQry->data); i_tableoid = PQfnumber(res, "tableoid"); i_oid = PQfnumber(res, "oid"); + i_datname = PQfnumber(res, "datname"); i_dba = PQfnumber(res, "dba"); i_encoding = PQfnumber(res, "encoding"); i_collate = PQfnumber(res, "datcollate"); @@ -2673,6 +2784,7 @@ dumpDatabase(Archive *fout) dbCatId.tableoid = atooid(PQgetvalue(res, 0, i_tableoid)); dbCatId.oid = atooid(PQgetvalue(res, 0, i_oid)); + datname = PQgetvalue(res, 0, i_datname); dba = PQgetvalue(res, 0, i_dba); encoding = PQgetvalue(res, 0, i_encoding); collate = PQgetvalue(res, 0, i_collate); @@ -2685,6 +2797,8 @@ dumpDatabase(Archive *fout) datconnlimit = PQgetvalue(res, 0, i_datconnlimit); tablespace = PQgetvalue(res, 0, i_tablespace); + qdatname = pg_strdup(fmtId(datname)); + /* * Prepare the CREATE DATABASE command. We must specify encoding, locale, * and tablespace since those can't be altered later. Other DB properties @@ -2698,15 +2812,23 @@ dumpDatabase(Archive *fout) appendPQExpBufferStr(creaQry, " ENCODING = "); appendStringLiteralAH(creaQry, encoding, fout); } - if (strlen(collate) > 0) + if (strlen(collate) > 0 && strcmp(collate, ctype) == 0) { - appendPQExpBufferStr(creaQry, " LC_COLLATE = "); + appendPQExpBufferStr(creaQry, " LOCALE = "); appendStringLiteralAH(creaQry, collate, fout); } - if (strlen(ctype) > 0) + else { - appendPQExpBufferStr(creaQry, " LC_CTYPE = "); - appendStringLiteralAH(creaQry, ctype, fout); + if (strlen(collate) > 0) + { + appendPQExpBufferStr(creaQry, " LC_COLLATE = "); + appendStringLiteralAH(creaQry, collate, fout); + } + if (strlen(ctype) > 0) + { + appendPQExpBufferStr(creaQry, " LC_CTYPE = "); + appendStringLiteralAH(creaQry, ctype, fout); + } } /* @@ -2731,20 +2853,12 @@ dumpDatabase(Archive *fout) ArchiveEntry(fout, dbCatId, /* catalog ID */ dbDumpId, /* dump ID */ - datname, /* Name */ - NULL, /* Namespace */ - NULL, /* Tablespace */ - dba, /* Owner */ - false, /* with oids */ - "DATABASE", /* Desc */ - SECTION_PRE_DATA, /* Section */ - creaQry->data, /* Create */ - delQry->data, /* Del */ - NULL, /* Copy */ - NULL, /* Deps */ - 0, /* # Deps */ - NULL, /* Dumper */ - NULL); /* Dumper Arg */ + ARCHIVE_OPTS(.tag = datname, + .owner = dba, + .description = "DATABASE", + .section = SECTION_PRE_DATA, + .createStmt = creaQry->data, + .dropStmt = delQry->data)); /* Compute correct tag for archive entry */ appendPQExpBuffer(labelq, "DATABASE %s", qdatname); @@ -2772,11 +2886,13 @@ dumpDatabase(Archive *fout) appendPQExpBufferStr(dbQry, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), - labelq->data, NULL, NULL, dba, - false, "COMMENT", SECTION_NONE, - dbQry->data, "", NULL, - &(dbDumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = labelq->data, + .owner = dba, + .description = "COMMENT", + .section = SECTION_NONE, + .createStmt = dbQry->data, + .deps = &dbDumpId, + .nDeps = 1)); } } else @@ -2799,11 +2915,13 @@ dumpDatabase(Archive *fout) emitShSecLabels(conn, shres, seclabelQry, "DATABASE", datname); if (seclabelQry->len > 0) ArchiveEntry(fout, nilCatalogId, createDumpId(), - labelq->data, NULL, NULL, dba, - false, "SECURITY LABEL", SECTION_NONE, - seclabelQry->data, "", NULL, - &(dbDumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = labelq->data, + .owner = dba, + .description = "SECURITY LABEL", + .section = SECTION_NONE, + .createStmt = seclabelQry->data, + .deps = &dbDumpId, + .nDeps = 1)); destroyPQExpBuffer(seclabelQry); PQclear(shres); } @@ -2869,15 +2987,17 @@ dumpDatabase(Archive *fout) if (creaQry->len > 0) ArchiveEntry(fout, nilCatalogId, createDumpId(), - datname, NULL, NULL, dba, - false, "DATABASE PROPERTIES", SECTION_PRE_DATA, - creaQry->data, delQry->data, NULL, - &(dbDumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = datname, + .owner = dba, + .description = "DATABASE PROPERTIES", + .section = SECTION_PRE_DATA, + .createStmt = creaQry->data, + .dropStmt = delQry->data, + .deps = &dbDumpId)); /* - * pg_largeobject and pg_largeobject_metadata come from the old system - * intact, so set their relfrozenxids and relminmxids. + * pg_largeobject comes from the old system intact, so set its + * relfrozenxids and relminmxids. */ if (dopt->binary_upgrade) { @@ -2914,55 +3034,13 @@ dumpDatabase(Archive *fout) atooid(PQgetvalue(lo_res, 0, i_relminmxid)), LargeObjectRelationId); ArchiveEntry(fout, nilCatalogId, createDumpId(), - "pg_largeobject", NULL, NULL, "", - false, "pg_largeobject", SECTION_PRE_DATA, - loOutQry->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = "pg_largeobject", + .description = "pg_largeobject", + .section = SECTION_PRE_DATA, + .createStmt = loOutQry->data)); PQclear(lo_res); - /* - * pg_largeobject_metadata - */ - if (fout->remoteVersion >= 90000) - { - resetPQExpBuffer(loFrozenQry); - resetPQExpBuffer(loOutQry); - - if (fout->remoteVersion >= 90300) - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, relminmxid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid = %u;\n", - LargeObjectMetadataRelationId); - else - appendPQExpBuffer(loFrozenQry, "SELECT relfrozenxid, 0 AS relminmxid\n" - "FROM pg_catalog.pg_class\n" - "WHERE oid = %u;\n", - LargeObjectMetadataRelationId); - - lo_res = ExecuteSqlQueryForSingleRow(fout, loFrozenQry->data); - - i_relfrozenxid = PQfnumber(lo_res, "relfrozenxid"); - i_relminmxid = PQfnumber(lo_res, "relminmxid"); - - appendPQExpBufferStr(loOutQry, "\n-- For binary upgrade, set pg_largeobject_metadata relfrozenxid and relminmxid\n"); - appendPQExpBuffer(loOutQry, "UPDATE pg_catalog.pg_class\n" - "SET relfrozenxid = '%u', relminmxid = '%u'\n" - "WHERE oid = %u;\n", - atooid(PQgetvalue(lo_res, 0, i_relfrozenxid)), - atooid(PQgetvalue(lo_res, 0, i_relminmxid)), - LargeObjectMetadataRelationId); - ArchiveEntry(fout, nilCatalogId, createDumpId(), - "pg_largeobject_metadata", NULL, NULL, "", - false, "pg_largeobject_metadata", SECTION_PRE_DATA, - loOutQry->data, "", NULL, - NULL, 0, - NULL, NULL); - - PQclear(lo_res); - } - destroyPQExpBuffer(loFrozenQry); destroyPQExpBuffer(loOutQry); } @@ -3057,19 +3135,17 @@ dumpEncoding(Archive *AH) const char *encname = pg_encoding_to_char(AH->encoding); PQExpBuffer qry = createPQExpBuffer(); - if (g_verbose) - write_msg(NULL, "saving encoding = %s\n", encname); + pg_log_info("saving encoding = %s", encname); appendPQExpBufferStr(qry, "SET client_encoding = "); appendStringLiteralAH(qry, encname, AH); appendPQExpBufferStr(qry, ";\n"); ArchiveEntry(AH, nilCatalogId, createDumpId(), - "ENCODING", NULL, NULL, "", - false, "ENCODING", SECTION_PRE_DATA, - qry->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = "ENCODING", + .description = "ENCODING", + .section = SECTION_PRE_DATA, + .createStmt = qry->data)); destroyPQExpBuffer(qry); } @@ -3084,19 +3160,17 @@ dumpStdStrings(Archive *AH) const char *stdstrings = AH->std_strings ? "on" : "off"; PQExpBuffer qry = createPQExpBuffer(); - if (g_verbose) - write_msg(NULL, "saving standard_conforming_strings = %s\n", - stdstrings); + pg_log_info("saving standard_conforming_strings = %s", + stdstrings); appendPQExpBuffer(qry, "SET standard_conforming_strings = '%s';\n", stdstrings); ArchiveEntry(AH, nilCatalogId, createDumpId(), - "STDSTRINGS", NULL, NULL, "", - false, "STDSTRINGS", SECTION_PRE_DATA, - qry->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = "STDSTRINGS", + .description = "STDSTRINGS", + .section = SECTION_PRE_DATA, + .createStmt = qry->data)); destroyPQExpBuffer(qry); } @@ -3125,7 +3199,7 @@ dumpSearchPath(Archive *AH) "SELECT pg_catalog.current_schemas(false)"); if (!parsePGArray(PQgetvalue(res, 0, 0), &schemanames, &nschemanames)) - exit_horribly(NULL, "could not parse result of current_schemas()\n"); + fatal("could not parse result of current_schemas()"); /* * We use set_config(), not a simple "SET search_path" command, because @@ -3144,15 +3218,13 @@ dumpSearchPath(Archive *AH) appendStringLiteralAH(qry, path->data, AH); appendPQExpBufferStr(qry, ", false);\n"); - if (g_verbose) - write_msg(NULL, "saving search_path = %s\n", path->data); + pg_log_info("saving search_path = %s", path->data); ArchiveEntry(AH, nilCatalogId, createDumpId(), - "SEARCHPATH", NULL, NULL, "", - false, "SEARCHPATH", SECTION_PRE_DATA, - qry->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = "SEARCHPATH", + .description = "SEARCHPATH", + .section = SECTION_PRE_DATA, + .createStmt = qry->data)); /* Also save it in AH->searchpath, in case we're doing plain text dump */ AH->searchpath = pg_strdup(qry->data); @@ -3186,9 +3258,7 @@ getBlobs(Archive *fout) int i_initlomacl; int i_initrlomacl; - /* Verbose message */ - if (g_verbose) - write_msg(NULL, "reading large objects\n"); + pg_log_info("reading large objects"); /* Fetch BLOB OIDs, and owner/ACL data if >= 9.0 */ if (fout->remoteVersion >= 90600) @@ -3276,18 +3346,14 @@ getBlobs(Archive *fout) binfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; /* - * In binary-upgrade mode for blobs, we do *not* dump out the data or - * the ACLs, should any exist. The data and ACL (if any) will be - * copied by pg_upgrade, which simply copies the pg_largeobject and - * pg_largeobject_metadata tables. - * - * We *do* dump out the definition of the blob because we need that to - * make the restoration of the comments, and anything else, work since - * pg_upgrade copies the files behind pg_largeobject and - * pg_largeobject_metadata after the dump is restored. + * In binary-upgrade mode for blobs, we do *not* dump out the blob + * data, as it will be copied by pg_upgrade, which simply copies the + * pg_largeobject table. We *do* however dump out anything but the + * data, as pg_upgrade copies just pg_largeobject, but not + * pg_largeobject_metadata, after the dump is restored. */ if (dopt->binary_upgrade) - binfo[i].dobj.dump &= ~(DUMP_COMPONENT_DATA | DUMP_COMPONENT_ACL); + binfo[i].dobj.dump &= ~DUMP_COMPONENT_DATA; } /* @@ -3328,13 +3394,12 @@ dumpBlob(Archive *fout, BlobInfo *binfo) if (binfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, binfo->dobj.catId, binfo->dobj.dumpId, - binfo->dobj.name, - NULL, NULL, - binfo->rolname, false, - "BLOB", SECTION_PRE_DATA, - cquery->data, dquery->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = binfo->dobj.name, + .owner = binfo->rolname, + .description = "BLOB", + .section = SECTION_PRE_DATA, + .createStmt = cquery->data, + .dropStmt = dquery->data)); /* Dump comment if any */ if (binfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -3375,17 +3440,20 @@ dumpBlobs(Archive *fout, void *arg) int i; int cnt; - if (g_verbose) - write_msg(NULL, "saving large objects\n"); + pg_log_info("saving large objects"); /* * Currently, we re-fetch all BLOB OIDs using a cursor. Consider scanning * the already-in-memory dumpable objects instead... */ if (fout->remoteVersion >= 90000) - blobQry = "DECLARE bloboid CURSOR FOR SELECT oid FROM pg_largeobject_metadata"; + blobQry = + "DECLARE bloboid CURSOR FOR " + "SELECT oid FROM pg_largeobject_metadata ORDER BY 1"; else - blobQry = "DECLARE bloboid CURSOR FOR SELECT DISTINCT loid FROM pg_largeobject"; + blobQry = + "DECLARE bloboid CURSOR FOR " + "SELECT DISTINCT loid FROM pg_largeobject ORDER BY 1"; ExecuteSqlStatement(fout, blobQry); @@ -3408,8 +3476,8 @@ dumpBlobs(Archive *fout, void *arg) /* Open the BLOB */ loFd = lo_open(conn, blobOid, INV_READ); if (loFd == -1) - exit_horribly(NULL, "could not open large object %u: %s", - blobOid, PQerrorMessage(conn)); + fatal("could not open large object %u: %s", + blobOid, PQerrorMessage(conn)); StartBlob(fout, blobOid); @@ -3418,8 +3486,8 @@ dumpBlobs(Archive *fout, void *arg) { cnt = lo_read(conn, loFd, buf, LOBBUFSIZE); if (cnt < 0) - exit_horribly(NULL, "error reading large object %u: %s", - blobOid, PQerrorMessage(conn)); + fatal("error reading large object %u: %s", + blobOid, PQerrorMessage(conn)); WriteData(fout, buf, cnt); } while (cnt > 0); @@ -3470,15 +3538,14 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) if (!(tbinfo->dobj.dump & DUMP_COMPONENT_POLICY)) continue; - if (g_verbose) - write_msg(NULL, "reading row security enabled for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading row security enabled for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); /* * Get row security enabled information for the table. We represent - * RLS enabled on a table by creating PolicyInfo object with an empty - * policy. + * RLS being enabled on a table by creating a PolicyInfo object with + * null polname. */ if (tbinfo->rowsec) { @@ -3502,10 +3569,9 @@ getPolicies(Archive *fout, TableInfo tblinfo[], int numTables) polinfo->polwithcheck = NULL; } - if (g_verbose) - write_msg(NULL, "reading policies for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading policies for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(query); @@ -3619,18 +3685,23 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo) query = createPQExpBuffer(); appendPQExpBuffer(query, "ALTER TABLE %s ENABLE ROW LEVEL SECURITY;", - fmtQualifiedDumpable(polinfo)); + fmtQualifiedDumpable(tbinfo)); + /* + * We must emit the ROW SECURITY object's dependency on its table + * explicitly, because it will not match anything in pg_depend (unlike + * the case for other PolicyInfo objects). + */ if (polinfo->dobj.dump & DUMP_COMPONENT_POLICY) ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId, - polinfo->dobj.name, - polinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "ROW SECURITY", SECTION_POST_DATA, - query->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = polinfo->dobj.name, + .namespace = polinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "ROW SECURITY", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); destroyPQExpBuffer(query); return; @@ -3648,8 +3719,8 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo) cmd = " FOR DELETE"; else { - write_msg(NULL, "unexpected policy command type: %c\n", - polinfo->polcmd); + pg_log_error("unexpected policy command type: %c", + polinfo->polcmd); exit_nicely(1); } @@ -3670,7 +3741,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo) if (polinfo->polwithcheck != NULL) appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithcheck); - appendPQExpBuffer(query, ";\n"); + appendPQExpBufferStr(query, ";\n"); appendPQExpBuffer(delqry, "DROP POLICY %s", fmtId(polinfo->polname)); appendPQExpBuffer(delqry, " ON %s;\n", fmtQualifiedDumpable(tbinfo)); @@ -3679,14 +3750,13 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo) if (polinfo->dobj.dump & DUMP_COMPONENT_POLICY) ArchiveEntry(fout, polinfo->dobj.catId, polinfo->dobj.dumpId, - tag, - polinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "POLICY", SECTION_POST_DATA, - query->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = polinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "POLICY", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .dropStmt = delqry->data)); free(tag); destroyPQExpBuffer(query); @@ -3776,8 +3846,8 @@ getPublications(Archive *fout) (strcmp(PQgetvalue(res, i, i_pubtruncate), "t") == 0); if (strlen(pubinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of publication \"%s\" appears to be invalid\n", - pubinfo[i].dobj.name); + pg_log_warning("owner of publication \"%s\" appears to be invalid", + pubinfo[i].dobj.name); /* Decide whether we want to dump it */ selectDumpableObject(&(pubinfo[i].dobj), fout); @@ -3853,14 +3923,12 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo) appendPQExpBufferStr(query, "');\n"); ArchiveEntry(fout, pubinfo->dobj.catId, pubinfo->dobj.dumpId, - pubinfo->dobj.name, - NULL, - NULL, - pubinfo->rolname, false, - "PUBLICATION", SECTION_POST_DATA, - query->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = pubinfo->dobj.name, + .owner = pubinfo->rolname, + .description = "PUBLICATION", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .dropStmt = delq->data)); if (pubinfo->dobj.dump & DUMP_COMPONENT_COMMENT) dumpComment(fout, "PUBLICATION", qpubname, @@ -3887,6 +3955,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) PQExpBuffer query; PGresult *res; PublicationRelInfo *pubrinfo; + DumpOptions *dopt = fout->dopt; int i_tableoid; int i_oid; int i_pubname; @@ -3894,7 +3963,7 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) j, ntups; - if (fout->remoteVersion < 100000) + if (dopt->no_publications || fout->remoteVersion < 100000) return; query = createPQExpBuffer(); @@ -3914,10 +3983,9 @@ getPublicationTables(Archive *fout, TableInfo tblinfo[], int numTables) if (!(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) continue; - if (g_verbose) - write_msg(NULL, "reading publication membership for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading publication membership for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(query); @@ -3991,18 +4059,15 @@ dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo) fmtQualifiedDumpable(tbinfo)); /* - * There is no point in creating drop query as drop query as the drop is - * done by table drop. + * There is no point in creating drop query as the drop is done by table + * drop. */ ArchiveEntry(fout, pubrinfo->dobj.catId, pubrinfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - "", false, - "PUBLICATION TABLE", SECTION_POST_DATA, - query->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .description = "PUBLICATION TABLE", + .section = SECTION_POST_DATA, + .createStmt = query->data)); free(tag); destroyPQExpBuffer(query); @@ -4061,7 +4126,7 @@ getSubscriptions(Archive *fout) PGRES_TUPLES_OK); n = atoi(PQgetvalue(res, 0, 0)); if (n > 0) - write_msg(NULL, "WARNING: subscriptions not dumped because current user is not a superuser\n"); + pg_log_warning("subscriptions not dumped because current user is not a superuser"); PQclear(res); return; } @@ -4115,8 +4180,8 @@ getSubscriptions(Archive *fout) pg_strdup(PQgetvalue(res, i, i_subpublications)); if (strlen(subinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of subscription \"%s\" appears to be invalid\n", - subinfo[i].dobj.name); + pg_log_warning("owner of subscription \"%s\" appears to be invalid", + subinfo[i].dobj.name); /* Decide whether we want to dump it */ selectDumpableObject(&(subinfo[i].dobj), fout); @@ -4159,8 +4224,7 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo) /* Build list of quoted publications and append them to query. */ if (!parsePGArray(subinfo->subpublications, &pubnames, &npubnames)) { - write_msg(NULL, - "WARNING: could not parse subpublications array\n"); + pg_log_warning("could not parse subpublications array"); if (pubnames) free(pubnames); pubnames = NULL; @@ -4188,14 +4252,12 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo) appendPQExpBufferStr(query, ");\n"); ArchiveEntry(fout, subinfo->dobj.catId, subinfo->dobj.dumpId, - subinfo->dobj.name, - NULL, - NULL, - subinfo->rolname, false, - "SUBSCRIPTION", SECTION_POST_DATA, - query->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = subinfo->dobj.name, + .owner = subinfo->rolname, + .description = "SUBSCRIPTION", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .dropStmt = delq->data)); if (subinfo->dobj.dump & DUMP_COMPONENT_COMMENT) dumpComment(fout, "SUBSCRIPTION", qsubname, @@ -4295,14 +4357,20 @@ binary_upgrade_set_type_oids_by_rel_oid(Archive *fout, Oid pg_type_oid; bool toast_set = false; - /* we only support old >= 8.3 for binary upgrades */ + /* + * We only support old >= 8.3 for binary upgrades. + * + * We purposefully ignore toast OIDs for partitioned tables; the reason is + * that versions 10 and 11 have them, but 12 does not, so emitting them + * causes the upgrade to fail. + */ appendPQExpBuffer(upgrade_query, "SELECT c.reltype AS crel, t.reltype AS trel " "FROM pg_catalog.pg_class c " "LEFT JOIN pg_catalog.pg_class t ON " - " (c.reltoastrelid = t.oid) " + " (c.reltoastrelid = t.oid AND c.relkind <> '%c') " "WHERE c.oid = '%u'::pg_catalog.oid;", - pg_rel_oid); + RELKIND_PARTITIONED_TABLE, pg_rel_oid); upgrade_res = ExecuteSqlQueryForSingleRow(fout, upgrade_query->data); @@ -4428,8 +4496,8 @@ binary_upgrade_extension_member(PQExpBuffer upgrade_buffer, extobj = NULL; } if (extobj == NULL) - exit_horribly(NULL, "could not find parent extension for %s %s\n", - objtype, objname); + fatal("could not find parent extension for %s %s", + objtype, objname); appendPQExpBufferStr(upgrade_buffer, "\n-- For binary upgrade, handle extension membership the hard way\n"); @@ -4500,7 +4568,7 @@ getNamespaces(Archive *fout, int *numNamespaces) init_acl_subquery->data, init_racl_subquery->data); - appendPQExpBuffer(query, ") "); + appendPQExpBufferStr(query, ") "); destroyPQExpBuffer(acl_subquery); destroyPQExpBuffer(racl_subquery); @@ -4560,8 +4628,8 @@ getNamespaces(Archive *fout, int *numNamespaces) nsinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; if (strlen(nsinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of schema \"%s\" appears to be invalid\n", - nsinfo[i].dobj.name); + pg_log_warning("owner of schema \"%s\" appears to be invalid", + nsinfo[i].dobj.name); } PQclear(res); @@ -4583,7 +4651,7 @@ findNamespace(Archive *fout, Oid nsoid) nsinfo = findNamespaceByOid(nsoid); if (nsinfo == NULL) - exit_horribly(NULL, "schema with OID %u does not exist\n", nsoid); + fatal("schema with OID %u does not exist", nsoid); return nsinfo; } @@ -4908,8 +4976,8 @@ getTypes(Archive *fout, int *numTypes) } if (strlen(tyinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of data type \"%s\" appears to be invalid\n", - tyinfo[i].dobj.name); + pg_log_warning("owner of data type \"%s\" appears to be invalid", + tyinfo[i].dobj.name); } *numTypes = ntups; @@ -4993,8 +5061,8 @@ getOperators(Archive *fout, int *numOprs) oprinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; if (strlen(oprinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of operator \"%s\" appears to be invalid\n", - oprinfo[i].dobj.name); + pg_log_warning("owner of operator \"%s\" appears to be invalid", + oprinfo[i].dobj.name); } PQclear(res); @@ -5188,9 +5256,9 @@ getAccessMethods(Archive *fout, int *numAccessMethods) query = createPQExpBuffer(); /* Select all access methods from pg_am table */ - appendPQExpBuffer(query, "SELECT tableoid, oid, amname, amtype, " - "amhandler::pg_catalog.regproc AS amhandler " - "FROM pg_am"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, amname, amtype, " + "amhandler::pg_catalog.regproc AS amhandler " + "FROM pg_am"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -5295,8 +5363,8 @@ getOpclasses(Archive *fout, int *numOpclasses) opcinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; if (strlen(opcinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of operator class \"%s\" appears to be invalid\n", - opcinfo[i].dobj.name); + pg_log_warning("owner of operator class \"%s\" appears to be invalid", + opcinfo[i].dobj.name); } PQclear(res); @@ -5379,8 +5447,8 @@ getOpfamilies(Archive *fout, int *numOpfamilies) opfinfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; if (strlen(opfinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of operator family \"%s\" appears to be invalid\n", - opfinfo[i].dobj.name); + pg_log_warning("owner of operator family \"%s\" appears to be invalid", + opfinfo[i].dobj.name); } PQclear(res); @@ -5548,8 +5616,8 @@ getAggregates(Archive *fout, int *numAggs) atooid(PQgetvalue(res, i, i_aggnamespace))); agginfo[i].aggfn.rolname = pg_strdup(PQgetvalue(res, i, i_rolname)); if (strlen(agginfo[i].aggfn.rolname) == 0) - write_msg(NULL, "WARNING: owner of aggregate function \"%s\" appears to be invalid\n", - agginfo[i].aggfn.dobj.name); + pg_log_warning("owner of aggregate function \"%s\" appears to be invalid", + agginfo[i].aggfn.dobj.name); agginfo[i].aggfn.lang = InvalidOid; /* not currently interesting */ agginfo[i].aggfn.prorettype = InvalidOid; /* not saved */ agginfo[i].aggfn.proacl = pg_strdup(PQgetvalue(res, i, i_aggacl)); @@ -5808,9 +5876,8 @@ getFuncs(Archive *fout, int *numFuncs) finfo[i].dobj.dump &= ~DUMP_COMPONENT_ACL; if (strlen(finfo[i].rolname) == 0) - write_msg(NULL, - "WARNING: owner of function \"%s\" appears to be invalid\n", - finfo[i].dobj.name); + pg_log_warning("owner of function \"%s\" appears to be invalid", + finfo[i].dobj.name); } PQclear(res); @@ -5874,6 +5941,7 @@ getTables(Archive *fout, int *numTables) int i_partkeydef; int i_ispartition; int i_partbound; + int i_amname; /* * Find all the tables and table-like objects. @@ -5893,6 +5961,10 @@ getTables(Archive *fout, int *numTables) * information about each table, basically just enough to decide if it is * interesting. We must fetch all tables in this phase because otherwise * we cannot correctly identify inherited columns, owned sequences, etc. + * + * We purposefully ignore toast OIDs for partitioned tables; the reason is + * that versions 10 and 11 have them, but 12 does not, so emitting them + * causes the upgrade to fail. */ if (fout->remoteVersion >= 90600) @@ -5900,6 +5972,7 @@ getTables(Archive *fout, int *numTables) char *partkeydef = "NULL"; char *ispartition = "false"; char *partbound = "NULL"; + char *relhasoids = "c.relhasoids"; PQExpBuffer acl_subquery = createPQExpBuffer(); PQExpBuffer racl_subquery = createPQExpBuffer(); @@ -5923,6 +5996,10 @@ getTables(Archive *fout, int *numTables) partbound = "pg_get_expr(c.relpartbound, c.oid)"; } + /* In PG12 upwards WITH OIDS does not exist anymore. */ + if (fout->remoteVersion >= 120000) + relhasoids = "'f'::bool"; + /* * Left join to pick up dependency info linking sequences to their * owning column, if any (note this dependency is AUTO as of 8.2) @@ -5948,13 +6025,13 @@ getTables(Archive *fout, int *numTables) "c.relkind, c.relnamespace, " "(%s c.relowner) AS rolname, " "c.relchecks, c.relhastriggers, " - "c.relhasindex, c.relhasrules, c.relhasoids, " + "c.relhasindex, c.relhasrules, %s AS relhasoids, " "c.relrowsecurity, c.relforcerowsecurity, " "c.relfrozenxid, c.relminmxid, tc.oid AS toid, " "tc.relfrozenxid AS tfrozenxid, " "tc.relminmxid AS tminmxid, " "c.relpersistence, c.relispopulated, " - "c.relreplident, c.relpages, " + "c.relreplident, c.relpages, am.amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -5984,7 +6061,8 @@ getTables(Archive *fout, int *numTables) "d.classid = c.tableoid AND d.objid = c.oid AND " "d.objsubid = 0 AND " "d.refclassid = c.tableoid AND d.deptype IN ('a', 'i')) " - "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid) " + "LEFT JOIN pg_class tc ON (c.reltoastrelid = tc.oid AND c.relkind <> '%c') " + "LEFT JOIN pg_am am ON (c.relam = am.oid) " "LEFT JOIN pg_init_privs pip ON " "(c.oid = pip.objoid " "AND pip.classoid = 'pg_class'::regclass " @@ -5996,6 +6074,7 @@ getTables(Archive *fout, int *numTables) initacl_subquery->data, initracl_subquery->data, username_subquery, + relhasoids, RELKIND_SEQUENCE, attacl_subquery->data, attracl_subquery->data, @@ -6005,6 +6084,7 @@ getTables(Archive *fout, int *numTables) ispartition, partbound, RELKIND_SEQUENCE, + RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, RELKIND_COMPOSITE_TYPE, RELKIND_MATVIEW, RELKIND_FOREIGN_TABLE, @@ -6041,6 +6121,7 @@ getTables(Archive *fout, int *numTables) "tc.relminmxid AS tminmxid, " "c.relpersistence, c.relispopulated, " "c.relreplident, c.relpages, " + "NULL AS amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6090,6 +6171,7 @@ getTables(Archive *fout, int *numTables) "tc.relminmxid AS tminmxid, " "c.relpersistence, c.relispopulated, " "c.relreplident, c.relpages, " + "NULL AS amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6139,6 +6221,7 @@ getTables(Archive *fout, int *numTables) "tc.relminmxid AS tminmxid, " "c.relpersistence, c.relispopulated, " "'d' AS relreplident, c.relpages, " + "NULL AS amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6188,6 +6271,7 @@ getTables(Archive *fout, int *numTables) "0 AS tminmxid, " "c.relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " + "NULL AS amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6235,6 +6319,7 @@ getTables(Archive *fout, int *numTables) "0 AS tminmxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " + "NULL AS amname, " "CASE WHEN c.reloftype <> 0 THEN c.reloftype::pg_catalog.regtype ELSE NULL END AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6281,6 +6366,7 @@ getTables(Archive *fout, int *numTables) "0 AS tminmxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " + "NULL AS amname, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6327,6 +6413,7 @@ getTables(Archive *fout, int *numTables) "0 AS tminmxid, " "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, c.relpages, " + "NULL AS amname, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6372,6 +6459,7 @@ getTables(Archive *fout, int *numTables) "0 AS tfrozenxid, 0 AS tminmxid," "'p' AS relpersistence, 't' as relispopulated, " "'d' AS relreplident, relpages, " + "NULL AS amname, " "NULL AS reloftype, " "d.refobjid AS owning_tab, " "d.refobjsubid AS owning_col, " @@ -6451,6 +6539,7 @@ getTables(Archive *fout, int *numTables) i_partkeydef = PQfnumber(res, "partkeydef"); i_ispartition = PQfnumber(res, "ispartition"); i_partbound = PQfnumber(res, "partbound"); + i_amname = PQfnumber(res, "amname"); if (dopt->lockWaitTimeout) { @@ -6520,6 +6609,10 @@ getTables(Archive *fout, int *numTables) else tblinfo[i].checkoption = pg_strdup(PQgetvalue(res, i, i_checkoption)); tblinfo[i].toast_reloptions = pg_strdup(PQgetvalue(res, i, i_toastreloptions)); + if (PQgetisnull(res, i, i_amname)) + tblinfo[i].amname = NULL; + else + tblinfo[i].amname = pg_strdup(PQgetvalue(res, i, i_amname)); /* other fields were zeroed above */ @@ -6587,8 +6680,8 @@ getTables(Archive *fout, int *numTables) /* Emit notice if join for owner failed */ if (strlen(tblinfo[i].rolname) == 0) - write_msg(NULL, "WARNING: owner of table \"%s\" appears to be invalid\n", - tblinfo[i].dobj.name); + pg_log_warning("owner of table \"%s\" appears to be invalid", + tblinfo[i].dobj.name); } if (dopt->lockWaitTimeout) @@ -6629,12 +6722,24 @@ getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables) owning_tab = findTableByOid(seqinfo->owning_tab); if (owning_tab == NULL) - exit_horribly(NULL, "failed sanity check, parent table with OID %u of sequence with OID %u not found\n", - seqinfo->owning_tab, seqinfo->dobj.catId.oid); + fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found", + seqinfo->owning_tab, seqinfo->dobj.catId.oid); + + /* + * Only dump identity sequences if we're going to dump the table that + * it belongs to. + */ + if (owning_tab->dobj.dump == DUMP_COMPONENT_NONE && + seqinfo->is_identity_sequence) + { + seqinfo->dobj.dump = DUMP_COMPONENT_NONE; + continue; + } /* - * We need to dump the components that are being dumped for the table - * and any components which the sequence is explicitly marked with. + * Otherwise we need to dump the components that are being dumped for + * the table and any components which the sequence is explicitly + * marked with. * * We can't simply use the set of components which are being dumped * for the table as the table might be in an extension (and only the @@ -6675,9 +6780,7 @@ getInherits(Archive *fout, int *numInherits) /* * Find all the inheritance information, excluding implicit inheritance - * via partitioning. We handle that case using getPartitions(), because - * we want more information about partitions than just the parent-child - * relationship. + * via partitioning. */ appendPQExpBufferStr(query, "SELECT inhrelid, inhparent FROM pg_inherits"); @@ -6726,7 +6829,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_indexname, i_parentidx, i_indexdef, - i_indnnkeyatts, + i_indnkeyatts, i_indnatts, i_indkey, i_indisclustered, @@ -6740,7 +6843,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_condef, i_tablespace, i_indreloptions, - i_relpages; + i_indstatcols, + i_indstatvals; int ntups; for (i = 0; i < numTables; i++) @@ -6760,10 +6864,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) !tbinfo->interesting) continue; - if (g_verbose) - write_msg(NULL, "reading indexes for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading indexes for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); /* * The point of the messy-looking outer join is to find a constraint @@ -6786,16 +6889,23 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "i.indnkeyatts AS indnkeyatts, " "i.indnatts AS indnatts, " - "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "i.indisreplident, t.relpages, " + "i.indisreplident, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " "c.oid AS conoid, " "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "t.reloptions AS indreloptions " + "t.reloptions AS indreloptions, " + "(SELECT pg_catalog.array_agg(attnum ORDER BY attnum) " + " FROM pg_catalog.pg_attribute " + " WHERE attrelid = i.indexrelid AND " + " attstattarget >= 0) AS indstatcols," + "(SELECT pg_catalog.array_agg(attstattarget ORDER BY attnum) " + " FROM pg_catalog.pg_attribute " + " WHERE attrelid = i.indexrelid AND " + " attstattarget >= 0) AS indstatvals " "FROM pg_catalog.pg_index i " "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " "JOIN pg_catalog.pg_class t2 ON (t2.oid = i.indrelid) " @@ -6824,16 +6934,17 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "i.indnatts AS indnkeyatts, " "i.indnatts AS indnatts, " - "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "i.indisreplident, t.relpages, " + "i.indisreplident, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " "c.oid AS conoid, " "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "t.reloptions AS indreloptions " + "t.reloptions AS indreloptions, " + "'' AS indstatcols, " + "'' AS indstatvals " "FROM pg_catalog.pg_index i " "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " "LEFT JOIN pg_catalog.pg_constraint c " @@ -6858,16 +6969,17 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "i.indnatts AS indnkeyatts, " "i.indnatts AS indnatts, " - "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "false AS indisreplident, t.relpages, " + "false AS indisreplident, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " "c.oid AS conoid, " "pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "t.reloptions AS indreloptions " + "t.reloptions AS indreloptions, " + "'' AS indstatcols, " + "'' AS indstatvals " "FROM pg_catalog.pg_index i " "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " "LEFT JOIN pg_catalog.pg_constraint c " @@ -6888,16 +7000,17 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " "i.indnatts AS indnkeyatts, " "i.indnatts AS indnatts, " - "t.relnatts AS indnkeys, " "i.indkey, i.indisclustered, " - "false AS indisreplident, t.relpages, " + "false AS indisreplident, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " "c.oid AS conoid, " "null AS condef, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "t.reloptions AS indreloptions " + "t.reloptions AS indreloptions, " + "'' AS indstatcols, " + "'' AS indstatvals " "FROM pg_catalog.pg_index i " "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " "LEFT JOIN pg_catalog.pg_depend d " @@ -6919,16 +7032,19 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) "t.relname AS indexname, " "0 AS parentidx, " "pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, " - "t.relnatts AS indnkeys, " + "t.relnatts AS indnkeyatts, " + "t.relnatts AS indnatts, " "i.indkey, i.indisclustered, " - "false AS indisreplident, t.relpages, " + "false AS indisreplident, " "c.contype, c.conname, " "c.condeferrable, c.condeferred, " "c.tableoid AS contableoid, " "c.oid AS conoid, " "null AS condef, " "(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, " - "null AS indreloptions " + "null AS indreloptions, " + "'' AS indstatcols, " + "'' AS indstatvals " "FROM pg_catalog.pg_index i " "JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) " "LEFT JOIN pg_catalog.pg_depend d " @@ -6952,12 +7068,11 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_indexname = PQfnumber(res, "indexname"); i_parentidx = PQfnumber(res, "parentidx"); i_indexdef = PQfnumber(res, "indexdef"); - i_indnnkeyatts = PQfnumber(res, "indnkeyatts"); + i_indnkeyatts = PQfnumber(res, "indnkeyatts"); i_indnatts = PQfnumber(res, "indnatts"); i_indkey = PQfnumber(res, "indkey"); i_indisclustered = PQfnumber(res, "indisclustered"); i_indisreplident = PQfnumber(res, "indisreplident"); - i_relpages = PQfnumber(res, "relpages"); i_contype = PQfnumber(res, "contype"); i_conname = PQfnumber(res, "conname"); i_condeferrable = PQfnumber(res, "condeferrable"); @@ -6967,6 +7082,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) i_condef = PQfnumber(res, "condef"); i_tablespace = PQfnumber(res, "tablespace"); i_indreloptions = PQfnumber(res, "indreloptions"); + i_indstatcols = PQfnumber(res, "indstatcols"); + i_indstatvals = PQfnumber(res, "indstatvals"); tbinfo->indexes = indxinfo = (IndxInfo *) pg_malloc(ntups * sizeof(IndxInfo)); @@ -6986,17 +7103,18 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables) indxinfo[j].dobj.namespace = tbinfo->dobj.namespace; indxinfo[j].indextable = tbinfo; indxinfo[j].indexdef = pg_strdup(PQgetvalue(res, j, i_indexdef)); - indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnnkeyatts)); + indxinfo[j].indnkeyattrs = atoi(PQgetvalue(res, j, i_indnkeyatts)); indxinfo[j].indnattrs = atoi(PQgetvalue(res, j, i_indnatts)); indxinfo[j].tablespace = pg_strdup(PQgetvalue(res, j, i_tablespace)); indxinfo[j].indreloptions = pg_strdup(PQgetvalue(res, j, i_indreloptions)); + indxinfo[j].indstatcols = pg_strdup(PQgetvalue(res, j, i_indstatcols)); + indxinfo[j].indstatvals = pg_strdup(PQgetvalue(res, j, i_indstatvals)); indxinfo[j].indkeys = (Oid *) pg_malloc(indxinfo[j].indnattrs * sizeof(Oid)); parseOidArray(PQgetvalue(res, j, i_indkey), indxinfo[j].indkeys, indxinfo[j].indnattrs); indxinfo[j].indisclustered = (PQgetvalue(res, j, i_indisclustered)[0] == 't'); indxinfo[j].indisreplident = (PQgetvalue(res, j, i_indisreplident)[0] == 't'); indxinfo[j].parentidx = atooid(PQgetvalue(res, j, i_parentidx)); - indxinfo[j].relpages = atoi(PQgetvalue(res, j, i_relpages)); contype = *(PQgetvalue(res, j, i_contype)); if (contype == 'p' || contype == 'u' || contype == 'x') @@ -7060,6 +7178,7 @@ getExtendedStatistics(Archive *fout) int i_stxname; int i_stxnamespace; int i_rolname; + int i_stattarget; int i; /* Extended statistics were new in v10 */ @@ -7068,10 +7187,16 @@ getExtendedStatistics(Archive *fout) query = createPQExpBuffer(); - appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, " - "stxnamespace, (%s stxowner) AS rolname " - "FROM pg_catalog.pg_statistic_ext", - username_subquery); + if (fout->remoteVersion < 130000) + appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, " + "stxnamespace, (%s stxowner) AS rolname, (-1) AS stxstattarget " + "FROM pg_catalog.pg_statistic_ext", + username_subquery); + else + appendPQExpBuffer(query, "SELECT tableoid, oid, stxname, " + "stxnamespace, (%s stxowner) AS rolname, stxstattarget " + "FROM pg_catalog.pg_statistic_ext", + username_subquery); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -7082,6 +7207,7 @@ getExtendedStatistics(Archive *fout) i_stxname = PQfnumber(res, "stxname"); i_stxnamespace = PQfnumber(res, "stxnamespace"); i_rolname = PQfnumber(res, "rolname"); + i_stattarget = PQfnumber(res, "stxstattarget"); statsextinfo = (StatsExtInfo *) pg_malloc(ntups * sizeof(StatsExtInfo)); @@ -7096,6 +7222,7 @@ getExtendedStatistics(Archive *fout) findNamespace(fout, atooid(PQgetvalue(res, i, i_stxnamespace))); statsextinfo[i].rolname = pg_strdup(PQgetvalue(res, i, i_rolname)); + statsextinfo[i].stattarget = atoi(PQgetvalue(res, i, i_stattarget)); /* Decide whether we want to dump it */ selectDumpableObject(&(statsextinfo[i].dobj), fout); @@ -7138,14 +7265,18 @@ getConstraints(Archive *fout, TableInfo tblinfo[], int numTables) { TableInfo *tbinfo = &tblinfo[i]; - if (!tbinfo->hastriggers || + /* + * For partitioned tables, foreign keys have no triggers so they must + * be included anyway in case some foreign keys are defined. + */ + if ((!tbinfo->hastriggers && + tbinfo->relkind != RELKIND_PARTITIONED_TABLE) || !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) continue; - if (g_verbose) - write_msg(NULL, "reading foreign key constraints for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading foreign key constraints for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(query); if (fout->remoteVersion >= 110000) @@ -7362,8 +7493,8 @@ getRules(Archive *fout, int *numRules) ruletableoid = atooid(PQgetvalue(res, i, i_ruletable)); ruleinfo[i].ruletable = findTableByOid(ruletableoid); if (ruleinfo[i].ruletable == NULL) - exit_horribly(NULL, "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n", - ruletableoid, ruleinfo[i].dobj.catId.oid); + fatal("failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found", + ruletableoid, ruleinfo[i].dobj.catId.oid); ruleinfo[i].dobj.namespace = ruleinfo[i].ruletable->dobj.namespace; ruleinfo[i].dobj.dump = ruleinfo[i].ruletable->dobj.dump; ruleinfo[i].ev_type = *(PQgetvalue(res, i, i_ev_type)); @@ -7445,10 +7576,9 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables) !(tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)) continue; - if (g_verbose) - write_msg(NULL, "reading triggers for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("reading triggers for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(query); if (fout->remoteVersion >= 90000) @@ -7579,10 +7709,10 @@ getTriggers(Archive *fout, TableInfo tblinfo[], int numTables) if (OidIsValid(tginfo[j].tgconstrrelid)) { if (PQgetisnull(res, j, i_tgconstrrelname)) - exit_horribly(NULL, "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n", - tginfo[j].dobj.name, - tbinfo->dobj.name, - tginfo[j].tgconstrrelid); + fatal("query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)", + tginfo[j].dobj.name, + tbinfo->dobj.name, + tginfo[j].tgconstrrelid); tginfo[j].tgconstrrelname = pg_strdup(PQgetvalue(res, j, i_tgconstrrelname)); } else @@ -8013,10 +8143,10 @@ getTransforms(Archive *fout, int *numTransforms) query = createPQExpBuffer(); - appendPQExpBuffer(query, "SELECT tableoid, oid, " - "trftype, trflang, trffromsql::oid, trftosql::oid " - "FROM pg_transform " - "ORDER BY 3,4"); + appendPQExpBufferStr(query, "SELECT tableoid, oid, " + "trftype, trflang, trffromsql::oid, trftosql::oid " + "FROM pg_transform " + "ORDER BY 3,4"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -8103,6 +8233,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) int i_attnotnull; int i_atthasdef; int i_attidentity; + int i_attgenerated; int i_attisdropped; int i_attlen; int i_attalign; @@ -8110,6 +8241,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) int i_attoptions; int i_attcollation; int i_attfdwoptions; + int i_attmissingval; PGresult *res; int ntups; bool hasdefaults; @@ -8132,125 +8264,92 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) * we must read the attribute names in attribute number order! because * we will use the attnum to index into the attnames array later. */ - if (g_verbose) - write_msg(NULL, "finding the columns and types of table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("finding the columns and types of table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(q); + appendPQExpBufferStr(q, + "SELECT\n" + "a.attnum,\n" + "a.attname,\n" + "a.atttypmod,\n" + "a.attstattarget,\n" + "a.attstorage,\n" + "t.typstorage,\n" + "a.attnotnull,\n" + "a.atthasdef,\n" + "a.attisdropped,\n" + "a.attlen,\n" + "a.attalign,\n" + "a.attislocal,\n" + "pg_catalog.format_type(t.oid, a.atttypmod) AS atttypname,\n"); + + if (fout->remoteVersion >= 120000) + appendPQExpBufferStr(q, + "a.attgenerated,\n"); + else + appendPQExpBufferStr(q, + "'' AS attgenerated,\n"); + + if (fout->remoteVersion >= 110000) + appendPQExpBufferStr(q, + "CASE WHEN a.atthasmissing AND NOT a.attisdropped " + "THEN a.attmissingval ELSE null END AS attmissingval,\n"); + else + appendPQExpBufferStr(q, + "NULL AS attmissingval,\n"); + if (fout->remoteVersion >= 100000) + appendPQExpBufferStr(q, + "a.attidentity,\n"); + else + appendPQExpBufferStr(q, + "'' AS attidentity,\n"); + + if (fout->remoteVersion >= 90200) + appendPQExpBufferStr(q, + "pg_catalog.array_to_string(ARRAY(" + "SELECT pg_catalog.quote_ident(option_name) || " + "' ' || pg_catalog.quote_literal(option_value) " + "FROM pg_catalog.pg_options_to_table(attfdwoptions) " + "ORDER BY option_name" + "), E',\n ') AS attfdwoptions,\n"); + else + appendPQExpBufferStr(q, + "'' AS attfdwoptions,\n"); + + if (fout->remoteVersion >= 90100) { /* - * attidentity is new in version 10. - */ - appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " - "a.attstattarget, a.attstorage, t.typstorage, " - "a.attnotnull, a.atthasdef, a.attisdropped, " - "a.attlen, a.attalign, a.attislocal, " - "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, " - "array_to_string(a.attoptions, ', ') AS attoptions, " - "CASE WHEN a.attcollation <> t.typcollation " - "THEN a.attcollation ELSE 0 END AS attcollation, " - "a.attidentity, " - "pg_catalog.array_to_string(ARRAY(" - "SELECT pg_catalog.quote_ident(option_name) || " - "' ' || pg_catalog.quote_literal(option_value) " - "FROM pg_catalog.pg_options_to_table(attfdwoptions) " - "ORDER BY option_name" - "), E',\n ') AS attfdwoptions " - "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " - "ON a.atttypid = t.oid " - "WHERE a.attrelid = '%u'::pg_catalog.oid " - "AND a.attnum > 0::pg_catalog.int2 " - "ORDER BY a.attnum", - tbinfo->dobj.catId.oid); - } - else if (fout->remoteVersion >= 90200) - { - /* - * attfdwoptions is new in 9.2. - */ - appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " - "a.attstattarget, a.attstorage, t.typstorage, " - "a.attnotnull, a.atthasdef, a.attisdropped, " - "a.attlen, a.attalign, a.attislocal, " - "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, " - "array_to_string(a.attoptions, ', ') AS attoptions, " - "CASE WHEN a.attcollation <> t.typcollation " - "THEN a.attcollation ELSE 0 END AS attcollation, " - "pg_catalog.array_to_string(ARRAY(" - "SELECT pg_catalog.quote_ident(option_name) || " - "' ' || pg_catalog.quote_literal(option_value) " - "FROM pg_catalog.pg_options_to_table(attfdwoptions) " - "ORDER BY option_name" - "), E',\n ') AS attfdwoptions " - "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " - "ON a.atttypid = t.oid " - "WHERE a.attrelid = '%u'::pg_catalog.oid " - "AND a.attnum > 0::pg_catalog.int2 " - "ORDER BY a.attnum", - tbinfo->dobj.catId.oid); - } - else if (fout->remoteVersion >= 90100) - { - /* - * attcollation is new in 9.1. Since we only want to dump COLLATE - * clauses for attributes whose collation is different from their - * type's default, we use a CASE here to suppress uninteresting - * attcollations cheaply. + * Since we only want to dump COLLATE clauses for attributes whose + * collation is different from their type's default, we use a CASE + * here to suppress uninteresting attcollations cheaply. */ - appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " - "a.attstattarget, a.attstorage, t.typstorage, " - "a.attnotnull, a.atthasdef, a.attisdropped, " - "a.attlen, a.attalign, a.attislocal, " - "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, " - "array_to_string(a.attoptions, ', ') AS attoptions, " - "CASE WHEN a.attcollation <> t.typcollation " - "THEN a.attcollation ELSE 0 END AS attcollation, " - "NULL AS attfdwoptions " - "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " - "ON a.atttypid = t.oid " - "WHERE a.attrelid = '%u'::pg_catalog.oid " - "AND a.attnum > 0::pg_catalog.int2 " - "ORDER BY a.attnum", - tbinfo->dobj.catId.oid); - } - else if (fout->remoteVersion >= 90000) - { - /* attoptions is new in 9.0 */ - appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " - "a.attstattarget, a.attstorage, t.typstorage, " - "a.attnotnull, a.atthasdef, a.attisdropped, " - "a.attlen, a.attalign, a.attislocal, " - "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, " - "array_to_string(a.attoptions, ', ') AS attoptions, " - "0 AS attcollation, " - "NULL AS attfdwoptions " - "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " - "ON a.atttypid = t.oid " - "WHERE a.attrelid = '%u'::pg_catalog.oid " - "AND a.attnum > 0::pg_catalog.int2 " - "ORDER BY a.attnum", - tbinfo->dobj.catId.oid); + appendPQExpBufferStr(q, + "CASE WHEN a.attcollation <> t.typcollation " + "THEN a.attcollation ELSE 0 END AS attcollation,\n"); } else - { - /* need left join here to not fail on dropped columns ... */ - appendPQExpBuffer(q, "SELECT a.attnum, a.attname, a.atttypmod, " - "a.attstattarget, a.attstorage, t.typstorage, " - "a.attnotnull, a.atthasdef, a.attisdropped, " - "a.attlen, a.attalign, a.attislocal, " - "pg_catalog.format_type(t.oid,a.atttypmod) AS atttypname, " - "'' AS attoptions, 0 AS attcollation, " - "NULL AS attfdwoptions " - "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " - "ON a.atttypid = t.oid " - "WHERE a.attrelid = '%u'::pg_catalog.oid " - "AND a.attnum > 0::pg_catalog.int2 " - "ORDER BY a.attnum", - tbinfo->dobj.catId.oid); - } + appendPQExpBufferStr(q, + "0 AS attcollation,\n"); + + if (fout->remoteVersion >= 90000) + appendPQExpBufferStr(q, + "array_to_string(a.attoptions, ', ') AS attoptions\n"); + else + appendPQExpBufferStr(q, + "'' AS attoptions\n"); + + /* need left join here to not fail on dropped columns ... */ + appendPQExpBuffer(q, + "FROM pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_type t " + "ON a.atttypid = t.oid\n" + "WHERE a.attrelid = '%u'::pg_catalog.oid " + "AND a.attnum > 0::pg_catalog.int2\n" + "ORDER BY a.attnum", + tbinfo->dobj.catId.oid); res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK); @@ -8266,6 +8365,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) i_attnotnull = PQfnumber(res, "attnotnull"); i_atthasdef = PQfnumber(res, "atthasdef"); i_attidentity = PQfnumber(res, "attidentity"); + i_attgenerated = PQfnumber(res, "attgenerated"); i_attisdropped = PQfnumber(res, "attisdropped"); i_attlen = PQfnumber(res, "attlen"); i_attalign = PQfnumber(res, "attalign"); @@ -8273,6 +8373,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) i_attoptions = PQfnumber(res, "attoptions"); i_attcollation = PQfnumber(res, "attcollation"); i_attfdwoptions = PQfnumber(res, "attfdwoptions"); + i_attmissingval = PQfnumber(res, "attmissingval"); tbinfo->numatts = ntups; tbinfo->attnames = (char **) pg_malloc(ntups * sizeof(char *)); @@ -8282,6 +8383,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->attstorage = (char *) pg_malloc(ntups * sizeof(char)); tbinfo->typstorage = (char *) pg_malloc(ntups * sizeof(char)); tbinfo->attidentity = (char *) pg_malloc(ntups * sizeof(char)); + tbinfo->attgenerated = (char *) pg_malloc(ntups * sizeof(char)); tbinfo->attisdropped = (bool *) pg_malloc(ntups * sizeof(bool)); tbinfo->attlen = (int *) pg_malloc(ntups * sizeof(int)); tbinfo->attalign = (char *) pg_malloc(ntups * sizeof(char)); @@ -8289,6 +8391,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->attoptions = (char **) pg_malloc(ntups * sizeof(char *)); tbinfo->attcollation = (Oid *) pg_malloc(ntups * sizeof(Oid)); tbinfo->attfdwoptions = (char **) pg_malloc(ntups * sizeof(char *)); + tbinfo->attmissingval = (char **) pg_malloc(ntups * sizeof(char *)); tbinfo->notnull = (bool *) pg_malloc(ntups * sizeof(bool)); tbinfo->inhNotNull = (bool *) pg_malloc(ntups * sizeof(bool)); tbinfo->attrdefs = (AttrDefInfo **) pg_malloc(ntups * sizeof(AttrDefInfo *)); @@ -8297,16 +8400,16 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) for (j = 0; j < ntups; j++) { if (j + 1 != atoi(PQgetvalue(res, j, i_attnum))) - exit_horribly(NULL, - "invalid column numbering in table \"%s\"\n", - tbinfo->dobj.name); + fatal("invalid column numbering in table \"%s\"", + tbinfo->dobj.name); tbinfo->attnames[j] = pg_strdup(PQgetvalue(res, j, i_attname)); tbinfo->atttypnames[j] = pg_strdup(PQgetvalue(res, j, i_atttypname)); tbinfo->atttypmod[j] = atoi(PQgetvalue(res, j, i_atttypmod)); tbinfo->attstattarget[j] = atoi(PQgetvalue(res, j, i_attstattarget)); tbinfo->attstorage[j] = *(PQgetvalue(res, j, i_attstorage)); tbinfo->typstorage[j] = *(PQgetvalue(res, j, i_typstorage)); - tbinfo->attidentity[j] = (i_attidentity >= 0 ? *(PQgetvalue(res, j, i_attidentity)) : '\0'); + tbinfo->attidentity[j] = *(PQgetvalue(res, j, i_attidentity)); + tbinfo->attgenerated[j] = *(PQgetvalue(res, j, i_attgenerated)); tbinfo->needs_override = tbinfo->needs_override || (tbinfo->attidentity[j] == ATTRIBUTE_IDENTITY_ALWAYS); tbinfo->attisdropped[j] = (PQgetvalue(res, j, i_attisdropped)[0] == 't'); tbinfo->attlen[j] = atoi(PQgetvalue(res, j, i_attlen)); @@ -8316,6 +8419,7 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) tbinfo->attoptions[j] = pg_strdup(PQgetvalue(res, j, i_attoptions)); tbinfo->attcollation[j] = atooid(PQgetvalue(res, j, i_attcollation)); tbinfo->attfdwoptions[j] = pg_strdup(PQgetvalue(res, j, i_attfdwoptions)); + tbinfo->attmissingval[j] = pg_strdup(PQgetvalue(res, j, i_attmissingval)); tbinfo->attrdefs[j] = NULL; /* fix below */ if (PQgetvalue(res, j, i_atthasdef)[0] == 't') hasdefaults = true; @@ -8333,10 +8437,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) AttrDefInfo *attrdefs; int numDefaults; - if (g_verbose) - write_msg(NULL, "finding default expressions of table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("finding default expressions of table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); printfPQExpBuffer(q, "SELECT tableoid, oid, adnum, " "pg_catalog.pg_get_expr(adbin, adrelid) AS adsrc " @@ -8356,9 +8459,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) adnum = atoi(PQgetvalue(res, j, 2)); if (adnum <= 0 || adnum > ntups) - exit_horribly(NULL, - "invalid adnum value %d for table \"%s\"\n", - adnum, tbinfo->dobj.name); + fatal("invalid adnum value %d for table \"%s\"", + adnum, tbinfo->dobj.name); /* * dropped columns shouldn't have defaults, but just in case, @@ -8422,10 +8524,9 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) ConstraintInfo *constrs; int numConstrs; - if (g_verbose) - write_msg(NULL, "finding check constraints for table \"%s.%s\"\n", - tbinfo->dobj.namespace->dobj.name, - tbinfo->dobj.name); + pg_log_info("finding check constraints for table \"%s.%s\"", + tbinfo->dobj.namespace->dobj.name, + tbinfo->dobj.name); resetPQExpBuffer(q); if (fout->remoteVersion >= 90200) @@ -8472,11 +8573,11 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) numConstrs = PQntuples(res); if (numConstrs != tbinfo->ncheck) { - write_msg(NULL, ngettext("expected %d check constraint on table \"%s\" but found %d\n", - "expected %d check constraints on table \"%s\" but found %d\n", - tbinfo->ncheck), - tbinfo->ncheck, tbinfo->dobj.name, numConstrs); - write_msg(NULL, "(The system catalogs might be corrupted.)\n"); + pg_log_error(ngettext("expected %d check constraint on table \"%s\" but found %d", + "expected %d check constraints on table \"%s\" but found %d", + tbinfo->ncheck), + tbinfo->ncheck, tbinfo->dobj.name, numConstrs); + pg_log_error("(The system catalogs might be corrupted.)"); exit_nicely(1); } @@ -8545,9 +8646,12 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables) * Normally this is always true, but it's false for dropped columns, as well * as those that were inherited without any local definition. (If we print * such a column it will mistakenly get pg_attribute.attislocal set to true.) - * However, in binary_upgrade mode, we must print all such columns anyway and - * fix the attislocal/attisdropped state later, so as to keep control of the - * physical column order. + * For partitions, it's always true, because we want the partitions to be + * created independently and ATTACH PARTITION used afterwards. + * + * In binary_upgrade mode, we must print all columns and fix the attislocal/ + * attisdropped state later, so as to keep control of the physical column + * order. * * This function exists because there are scattered nonobvious places that * must be kept in sync with this decision. @@ -8557,7 +8661,9 @@ shouldPrintColumn(DumpOptions *dopt, TableInfo *tbinfo, int colno) { if (dopt->binary_upgrade) return true; - return (tbinfo->attislocal[colno] && !tbinfo->attisdropped[colno]); + if (tbinfo->attisdropped[colno]) + return false; + return (tbinfo->attislocal[colno] || tbinfo->ispartition); } @@ -9418,11 +9524,14 @@ dumpComment(Archive *fout, const char *type, const char *name, * post-data. */ ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, namespace, NULL, owner, - false, "COMMENT", SECTION_NONE, - query->data, "", NULL, - &(dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = namespace, + .owner = owner, + .description = "COMMENT", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &dumpId, + .nDeps = 1)); destroyPQExpBuffer(query); destroyPQExpBuffer(tag); @@ -9484,13 +9593,14 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, - tbinfo->dobj.namespace->dobj.name, - NULL, tbinfo->rolname, - false, "COMMENT", SECTION_NONE, - query->data, "", NULL, - &(tbinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "COMMENT", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); } else if (objsubid > 0 && objsubid <= tbinfo->numatts) { @@ -9508,13 +9618,14 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo, appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, - tbinfo->dobj.namespace->dobj.name, - NULL, tbinfo->rolname, - false, "COMMENT", SECTION_NONE, - query->data, "", NULL, - &(tbinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "COMMENT", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); } comments++; @@ -9787,12 +9898,30 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj) break; case DO_BLOB_DATA: if (dobj->dump & DUMP_COMPONENT_DATA) - ArchiveEntry(fout, dobj->catId, dobj->dumpId, - dobj->name, NULL, NULL, "", - false, "BLOBS", SECTION_DATA, - "", "", NULL, - NULL, 0, - dumpBlobs, NULL); + { + TocEntry *te; + + te = ArchiveEntry(fout, dobj->catId, dobj->dumpId, + ARCHIVE_OPTS(.tag = dobj->name, + .description = "BLOBS", + .section = SECTION_DATA, + .dumpFn = dumpBlobs)); + + /* + * Set the TocEntry's dataLength in case we are doing a + * parallel dump and want to order dump jobs by table size. + * (We need some size estimate for every TocEntry with a + * DataDumper function.) We don't currently have any cheap + * way to estimate the size of blobs, but it doesn't matter; + * let's just set the size to a large value so parallel dumps + * will launch this job first. If there's lots of blobs, we + * win, and if there aren't, we don't lose much. (If you want + * to improve on this, really what you should be thinking + * about is allowing blob dumping to be parallelized, not just + * getting a smarter estimate for the single TOC entry.) + */ + te->dataLength = MaxBlockNumber; + } break; case DO_POLICY: dumpPolicy(fout, (PolicyInfo *) dobj); @@ -9844,13 +9973,12 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo) if (nspinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, - nspinfo->dobj.name, - NULL, NULL, - nspinfo->rolname, - false, "SCHEMA", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = nspinfo->dobj.name, + .owner = nspinfo->rolname, + .description = "SCHEMA", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Schema Comments and Security Labels */ if (nspinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -9980,13 +10108,11 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo) if (extinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, extinfo->dobj.catId, extinfo->dobj.dumpId, - extinfo->dobj.name, - NULL, NULL, - "", - false, "EXTENSION", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = extinfo->dobj.name, + .description = "EXTENSION", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Extension Comments and Security Labels */ if (extinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10032,8 +10158,8 @@ dumpType(Archive *fout, TypeInfo *tyinfo) else if (tyinfo->typtype == TYPTYPE_PSEUDO && !tyinfo->isDefined) dumpUndefinedType(fout, tyinfo); else - write_msg(NULL, "WARNING: typtype of data type \"%s\" appears to be invalid\n", - tyinfo->dobj.name); + pg_log_warning("typtype of data type \"%s\" appears to be invalid", + tyinfo->dobj.name); } /* @@ -10130,14 +10256,13 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "TYPE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Type Comments and Security Labels */ if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10257,14 +10382,13 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "TYPE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Type Comments and Security Labels */ if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10330,14 +10454,13 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "TYPE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Type Comments and Security Labels */ if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10612,14 +10735,13 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "TYPE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Type Comments and Security Labels */ if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10769,14 +10891,13 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "DOMAIN", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "DOMAIN", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Domain Comments and Security Labels */ if (tyinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -10991,14 +11112,13 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo) if (tyinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, - tyinfo->dobj.name, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "TYPE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tyinfo->dobj.name, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Type Comments and Security Labels */ @@ -11127,13 +11247,14 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo) appendPQExpBufferStr(query, ";\n"); ArchiveEntry(fout, nilCatalogId, createDumpId(), - target->data, - tyinfo->dobj.namespace->dobj.name, - NULL, tyinfo->rolname, - false, "COMMENT", SECTION_NONE, - query->data, "", NULL, - &(tyinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = target->data, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "COMMENT", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &(tyinfo->dobj.dumpId), + .nDeps = 1)); } comments++; @@ -11182,14 +11303,12 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo) if (stinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, stinfo->dobj.catId, stinfo->dobj.dumpId, - stinfo->dobj.name, - stinfo->dobj.namespace->dobj.name, - NULL, - stinfo->baseType->rolname, false, - "SHELL TYPE", SECTION_PRE_DATA, - q->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = stinfo->dobj.name, + .namespace = stinfo->dobj.namespace->dobj.name, + .owner = stinfo->baseType->rolname, + .description = "SHELL TYPE", + .section = SECTION_PRE_DATA, + .createStmt = q->data)); destroyPQExpBuffer(q); } @@ -11294,12 +11413,13 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang) if (plang->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId, - plang->dobj.name, - NULL, NULL, plang->lanowner, - false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA, - defqry->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = plang->dobj.name, + .owner = plang->lanowner, + .description = "PROCEDURAL LANGUAGE", + .section = SECTION_PRE_DATA, + .createStmt = defqry->data, + .dropStmt = delqry->data, + )); /* Dump Proc Lang Comments and Security Labels */ if (plang->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -11392,7 +11512,7 @@ format_function_arguments_old(Archive *fout, argmode = "INOUT "; break; default: - write_msg(NULL, "WARNING: bogus value in proargmodes array\n"); + pg_log_warning("bogus value in proargmodes array"); argmode = ""; break; } @@ -11488,6 +11608,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) char *proconfig; char *procost; char *prorows; + char *prosupport; char *proparallel; char *lanname; char *rettypename; @@ -11510,7 +11631,26 @@ dumpFunc(Archive *fout, FuncInfo *finfo) asPart = createPQExpBuffer(); /* Fetch function-specific details */ - if (fout->remoteVersion >= 110000) + if (fout->remoteVersion >= 120000) + { + /* + * prosupport was added in 12 + */ + appendPQExpBuffer(query, + "SELECT proretset, prosrc, probin, " + "pg_catalog.pg_get_function_arguments(oid) AS funcargs, " + "pg_catalog.pg_get_function_identity_arguments(oid) AS funciargs, " + "pg_catalog.pg_get_function_result(oid) AS funcresult, " + "array_to_string(protrftypes, ' ') AS protrftypes, " + "prokind, provolatile, proisstrict, prosecdef, " + "proleakproof, proconfig, procost, prorows, " + "prosupport, proparallel, " + "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " + "FROM pg_catalog.pg_proc " + "WHERE oid = '%u'::pg_catalog.oid", + finfo->dobj.catId.oid); + } + else if (fout->remoteVersion >= 110000) { /* * prokind was added in 11 @@ -11523,7 +11663,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "array_to_string(protrftypes, ' ') AS protrftypes, " "prokind, provolatile, proisstrict, prosecdef, " "proleakproof, proconfig, procost, prorows, " - "proparallel, " + "'-' AS prosupport, proparallel, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11543,7 +11683,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind, " "provolatile, proisstrict, prosecdef, " "proleakproof, proconfig, procost, prorows, " - "proparallel, " + "'-' AS prosupport, proparallel, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11563,6 +11703,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind, " "provolatile, proisstrict, prosecdef, " "proleakproof, proconfig, procost, prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11581,6 +11722,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "CASE WHEN proiswindow THEN 'w' ELSE 'f' END AS prokind, " "provolatile, proisstrict, prosecdef, " "proleakproof, proconfig, procost, prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11601,6 +11743,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "provolatile, proisstrict, prosecdef, " "false AS proleakproof, " " proconfig, procost, prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11615,6 +11758,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "provolatile, proisstrict, prosecdef, " "false AS proleakproof, " "proconfig, procost, prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11629,6 +11773,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "provolatile, proisstrict, prosecdef, " "false AS proleakproof, " "null AS proconfig, 0 AS procost, 0 AS prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11645,6 +11790,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) "provolatile, proisstrict, prosecdef, " "false AS proleakproof, " "null AS proconfig, 0 AS procost, 0 AS prorows, " + "'-' AS prosupport, " "(SELECT lanname FROM pg_catalog.pg_language WHERE oid = prolang) AS lanname " "FROM pg_catalog.pg_proc " "WHERE oid = '%u'::pg_catalog.oid", @@ -11682,6 +11828,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) proconfig = PQgetvalue(res, 0, PQfnumber(res, "proconfig")); procost = PQgetvalue(res, 0, PQfnumber(res, "procost")); prorows = PQgetvalue(res, 0, PQfnumber(res, "prorows")); + prosupport = PQgetvalue(res, 0, PQfnumber(res, "prosupport")); if (PQfnumber(res, "proparallel") != -1) proparallel = PQgetvalue(res, 0, PQfnumber(res, "proparallel")); @@ -11737,7 +11884,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) if (!parsePGArray(proallargtypes, &allargtypes, &nitems) || nitems < finfo->nargs) { - write_msg(NULL, "WARNING: could not parse proallargtypes array\n"); + pg_log_warning("could not parse proallargtypes array"); if (allargtypes) free(allargtypes); allargtypes = NULL; @@ -11753,7 +11900,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) if (!parsePGArray(proargmodes, &argmodes, &nitems) || nitems != nallargs) { - write_msg(NULL, "WARNING: could not parse proargmodes array\n"); + pg_log_warning("could not parse proargmodes array"); if (argmodes) free(argmodes); argmodes = NULL; @@ -11767,7 +11914,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) if (!parsePGArray(proargnames, &argnames, &nitems) || nitems != nallargs) { - write_msg(NULL, "WARNING: could not parse proargnames array\n"); + pg_log_warning("could not parse proargnames array"); if (argnames) free(argnames); argnames = NULL; @@ -11778,7 +11925,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo) { if (!parsePGArray(proconfig, &configitems, &nconfigitems)) { - write_msg(NULL, "WARNING: could not parse proconfig array\n"); + pg_log_warning("could not parse proconfig array"); if (configitems) free(configitems); configitems = NULL; @@ -11858,8 +12005,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) else if (provolatile[0] == PROVOLATILE_STABLE) appendPQExpBufferStr(q, " STABLE"); else if (provolatile[0] != PROVOLATILE_VOLATILE) - exit_horribly(NULL, "unrecognized provolatile value for function \"%s\"\n", - finfo->dobj.name); + fatal("unrecognized provolatile value for function \"%s\"", + finfo->dobj.name); } if (proisstrict[0] == 't') @@ -11895,6 +12042,12 @@ dumpFunc(Archive *fout, FuncInfo *finfo) strcmp(prorows, "0") != 0 && strcmp(prorows, "1000") != 0) appendPQExpBuffer(q, " ROWS %s", prorows); + if (strcmp(prosupport, "-") != 0) + { + /* We rely on regprocout to provide quoting and qualification */ + appendPQExpBuffer(q, " SUPPORT %s", prosupport); + } + if (proparallel != NULL && proparallel[0] != PROPARALLEL_UNSAFE) { if (proparallel[0] == PROPARALLEL_SAFE) @@ -11902,8 +12055,8 @@ dumpFunc(Archive *fout, FuncInfo *finfo) else if (proparallel[0] == PROPARALLEL_RESTRICTED) appendPQExpBufferStr(q, " PARALLEL RESTRICTED"); else if (proparallel[0] != PROPARALLEL_UNSAFE) - exit_horribly(NULL, "unrecognized proparallel value for function \"%s\"\n", - finfo->dobj.name); + fatal("unrecognized proparallel value for function \"%s\"", + finfo->dobj.name); } for (i = 0; i < nconfigitems; i++) @@ -11921,14 +12074,36 @@ dumpFunc(Archive *fout, FuncInfo *finfo) /* * Variables that are marked GUC_LIST_QUOTE were already fully quoted * by flatten_set_variable_args() before they were put into the - * proconfig array; we mustn't re-quote them or we'll make a mess. + * proconfig array. However, because the quoting rules used there + * aren't exactly like SQL's, we have to break the list value apart + * and then quote the elements as string literals. (The elements may + * be double-quoted as-is, but we can't just feed them to the SQL + * parser; it would do the wrong thing with elements that are + * zero-length or longer than NAMEDATALEN.) + * * Variables that are not so marked should just be emitted as simple * string literals. If the variable is not known to - * variable_is_guc_list_quote(), we'll do the latter; this makes it - * unsafe to use GUC_LIST_QUOTE for extension variables. + * variable_is_guc_list_quote(), we'll do that; this makes it unsafe + * to use GUC_LIST_QUOTE for extension variables. */ if (variable_is_guc_list_quote(configitem)) - appendPQExpBufferStr(q, pos); + { + char **namelist; + char **nameptr; + + /* Parse string into list of identifiers */ + /* this shouldn't fail really */ + if (SplitGUCList(pos, ',', &namelist)) + { + for (nameptr = namelist; *nameptr; nameptr++) + { + if (nameptr != namelist) + appendPQExpBufferStr(q, ", "); + appendStringLiteralAH(q, *nameptr, fout); + } + } + pg_free(namelist); + } else appendStringLiteralAH(q, pos, fout); } @@ -11942,14 +12117,13 @@ dumpFunc(Archive *fout, FuncInfo *finfo) if (finfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, finfo->dobj.catId, finfo->dobj.dumpId, - funcsig_tag, - finfo->dobj.namespace->dobj.name, - NULL, - finfo->rolname, false, - keyword, SECTION_PRE_DATA, - q->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = funcsig_tag, + .namespace = finfo->dobj.namespace->dobj.name, + .owner = finfo->rolname, + .description = keyword, + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delqry->data)); /* Dump Function Comments and Security Labels */ if (finfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -12014,8 +12188,8 @@ dumpCast(Archive *fout, CastInfo *cast) { funcInfo = findFuncByOid(cast->castfunc); if (funcInfo == NULL) - exit_horribly(NULL, "could not find function definition for function with OID %u\n", - cast->castfunc); + fatal("could not find function definition for function with OID %u", + cast->castfunc); } defqry = createPQExpBuffer(); @@ -12053,10 +12227,10 @@ dumpCast(Archive *fout, CastInfo *cast) free(fsig); } else - write_msg(NULL, "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n"); + pg_log_warning("bogus value in pg_cast.castfunc or pg_cast.castmethod field"); break; default: - write_msg(NULL, "WARNING: bogus value in pg_cast.castmethod field\n"); + pg_log_warning("bogus value in pg_cast.castmethod field"); } if (cast->castcontext == 'a') @@ -12077,12 +12251,11 @@ dumpCast(Archive *fout, CastInfo *cast) if (cast->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId, - labelq->data, - NULL, NULL, "", - false, "CAST", SECTION_PRE_DATA, - defqry->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = labelq->data, + .description = "CAST", + .section = SECTION_PRE_DATA, + .createStmt = defqry->data, + .dropStmt = delqry->data)); /* Dump Cast Comments */ if (cast->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -12124,15 +12297,15 @@ dumpTransform(Archive *fout, TransformInfo *transform) { fromsqlFuncInfo = findFuncByOid(transform->trffromsql); if (fromsqlFuncInfo == NULL) - exit_horribly(NULL, "could not find function definition for function with OID %u\n", - transform->trffromsql); + fatal("could not find function definition for function with OID %u", + transform->trffromsql); } if (OidIsValid(transform->trftosql)) { tosqlFuncInfo = findFuncByOid(transform->trftosql); if (tosqlFuncInfo == NULL) - exit_horribly(NULL, "could not find function definition for function with OID %u\n", - transform->trftosql); + fatal("could not find function definition for function with OID %u", + transform->trftosql); } defqry = createPQExpBuffer(); @@ -12150,7 +12323,7 @@ dumpTransform(Archive *fout, TransformInfo *transform) transformType, lanname); if (!transform->trffromsql && !transform->trftosql) - write_msg(NULL, "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n"); + pg_log_warning("bogus transform definition, at least one of trffromsql and trftosql should be nonzero"); if (transform->trffromsql) { @@ -12167,13 +12340,13 @@ dumpTransform(Archive *fout, TransformInfo *transform) free(fsig); } else - write_msg(NULL, "WARNING: bogus value in pg_transform.trffromsql field\n"); + pg_log_warning("bogus value in pg_transform.trffromsql field"); } if (transform->trftosql) { if (transform->trffromsql) - appendPQExpBuffer(defqry, ", "); + appendPQExpBufferStr(defqry, ", "); if (tosqlFuncInfo) { @@ -12188,10 +12361,10 @@ dumpTransform(Archive *fout, TransformInfo *transform) free(fsig); } else - write_msg(NULL, "WARNING: bogus value in pg_transform.trftosql field\n"); + pg_log_warning("bogus value in pg_transform.trftosql field"); } - appendPQExpBuffer(defqry, ");\n"); + appendPQExpBufferStr(defqry, ");\n"); appendPQExpBuffer(labelq, "TRANSFORM FOR %s LANGUAGE %s", transformType, lanname); @@ -12205,12 +12378,13 @@ dumpTransform(Archive *fout, TransformInfo *transform) if (transform->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId, - labelq->data, - NULL, NULL, "", - false, "TRANSFORM", SECTION_PRE_DATA, - defqry->data, delqry->data, NULL, - transform->dobj.dependencies, transform->dobj.nDeps, - NULL, NULL); + ARCHIVE_OPTS(.tag = labelq->data, + .description = "TRANSFORM", + .section = SECTION_PRE_DATA, + .createStmt = defqry->data, + .dropStmt = delqry->data, + .deps = transform->dobj.dependencies, + .nDeps = transform->dobj.nDeps)); /* Dump Transform Comments */ if (transform->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -12340,7 +12514,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) oprregproc = convertRegProcReference(fout, oprcode); if (oprregproc) { - appendPQExpBuffer(details, " PROCEDURE = %s", oprregproc); + appendPQExpBuffer(details, " FUNCTION = %s", oprregproc); free(oprregproc); } @@ -12418,14 +12592,13 @@ dumpOpr(Archive *fout, OprInfo *oprinfo) if (oprinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, oprinfo->dobj.catId, oprinfo->dobj.dumpId, - oprinfo->dobj.name, - oprinfo->dobj.namespace->dobj.name, - NULL, - oprinfo->rolname, - false, "OPERATOR", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = oprinfo->dobj.name, + .namespace = oprinfo->dobj.namespace->dobj.name, + .owner = oprinfo->rolname, + .description = "OPERATOR", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Operator Comments */ if (oprinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -12504,8 +12677,8 @@ getFormattedOperatorName(Archive *fout, const char *oproid) oprInfo = findOprByOid(atooid(oproid)); if (oprInfo == NULL) { - write_msg(NULL, "WARNING: could not find operator with OID %s\n", - oproid); + pg_log_warning("could not find operator with OID %s", + oproid); return NULL; } @@ -12566,11 +12739,14 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo) switch (aminfo->amtype) { case AMTYPE_INDEX: - appendPQExpBuffer(q, "TYPE INDEX "); + appendPQExpBufferStr(q, "TYPE INDEX "); + break; + case AMTYPE_TABLE: + appendPQExpBufferStr(q, "TYPE TABLE "); break; default: - write_msg(NULL, "WARNING: invalid type \"%c\" of access method \"%s\"\n", - aminfo->amtype, qamname); + pg_log_warning("invalid type \"%c\" of access method \"%s\"", + aminfo->amtype, qamname); destroyPQExpBuffer(q); destroyPQExpBuffer(delq); free(qamname); @@ -12588,14 +12764,11 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo) if (aminfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, aminfo->dobj.catId, aminfo->dobj.dumpId, - aminfo->dobj.name, - NULL, - NULL, - "", - false, "ACCESS METHOD", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = aminfo->dobj.name, + .description = "ACCESS METHOD", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Access Method Comments */ if (aminfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -12954,14 +13127,13 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo) if (opcinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, opcinfo->dobj.catId, opcinfo->dobj.dumpId, - opcinfo->dobj.name, - opcinfo->dobj.namespace->dobj.name, - NULL, - opcinfo->rolname, - false, "OPERATOR CLASS", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = opcinfo->dobj.name, + .namespace = opcinfo->dobj.namespace->dobj.name, + .owner = opcinfo->rolname, + .description = "OPERATOR CLASS", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Operator Class Comments */ if (opcinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -13221,14 +13393,13 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo) if (opfinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, opfinfo->dobj.catId, opfinfo->dobj.dumpId, - opfinfo->dobj.name, - opfinfo->dobj.namespace->dobj.name, - NULL, - opfinfo->rolname, - false, "OPERATOR FAMILY", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = opfinfo->dobj.name, + .namespace = opfinfo->dobj.namespace->dobj.name, + .owner = opfinfo->rolname, + .description = "OPERATOR FAMILY", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Operator Family Comments */ if (opfinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -13259,6 +13430,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo) char *qcollname; PGresult *res; int i_collprovider; + int i_collisdeterministic; int i_collcollate; int i_collctype; const char *collprovider; @@ -13276,28 +13448,35 @@ dumpCollation(Archive *fout, CollInfo *collinfo) qcollname = pg_strdup(fmtId(collinfo->dobj.name)); /* Get collation-specific details */ + appendPQExpBufferStr(query, "SELECT "); + if (fout->remoteVersion >= 100000) - appendPQExpBuffer(query, "SELECT " - "collprovider, " - "collcollate, " - "collctype, " - "collversion " - "FROM pg_catalog.pg_collation c " - "WHERE c.oid = '%u'::pg_catalog.oid", - collinfo->dobj.catId.oid); + appendPQExpBufferStr(query, + "collprovider, " + "collversion, "); else - appendPQExpBuffer(query, "SELECT " - "'c' AS collprovider, " - "collcollate, " - "collctype, " - "NULL AS collversion " - "FROM pg_catalog.pg_collation c " - "WHERE c.oid = '%u'::pg_catalog.oid", - collinfo->dobj.catId.oid); + appendPQExpBufferStr(query, + "'c' AS collprovider, " + "NULL AS collversion, "); + + if (fout->remoteVersion >= 120000) + appendPQExpBufferStr(query, + "collisdeterministic, "); + else + appendPQExpBufferStr(query, + "true AS collisdeterministic, "); + + appendPQExpBuffer(query, + "collcollate, " + "collctype " + "FROM pg_catalog.pg_collation c " + "WHERE c.oid = '%u'::pg_catalog.oid", + collinfo->dobj.catId.oid); res = ExecuteSqlQueryForSingleRow(fout, query->data); i_collprovider = PQfnumber(res, "collprovider"); + i_collisdeterministic = PQfnumber(res, "collisdeterministic"); i_collcollate = PQfnumber(res, "collcollate"); i_collctype = PQfnumber(res, "collctype"); @@ -13320,9 +13499,11 @@ dumpCollation(Archive *fout, CollInfo *collinfo) /* to allow dumping pg_catalog; not accepted on input */ appendPQExpBufferStr(q, "default"); else - exit_horribly(NULL, - "unrecognized collation provider: %s\n", - collprovider); + fatal("unrecognized collation provider: %s", + collprovider); + + if (strcmp(PQgetvalue(res, 0, i_collisdeterministic), "f") == 0) + appendPQExpBufferStr(q, ", deterministic = false"); if (strcmp(collcollate, collctype) == 0) { @@ -13364,14 +13545,13 @@ dumpCollation(Archive *fout, CollInfo *collinfo) if (collinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, collinfo->dobj.catId, collinfo->dobj.dumpId, - collinfo->dobj.name, - collinfo->dobj.namespace->dobj.name, - NULL, - collinfo->rolname, - false, "COLLATION", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = collinfo->dobj.name, + .namespace = collinfo->dobj.namespace->dobj.name, + .owner = collinfo->rolname, + .description = "COLLATION", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Collation Comments */ if (collinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -13459,14 +13639,13 @@ dumpConversion(Archive *fout, ConvInfo *convinfo) if (convinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, convinfo->dobj.catId, convinfo->dobj.dumpId, - convinfo->dobj.name, - convinfo->dobj.namespace->dobj.name, - NULL, - convinfo->rolname, - false, "CONVERSION", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = convinfo->dobj.name, + .namespace = convinfo->dobj.namespace->dobj.name, + .owner = convinfo->rolname, + .description = "CONVERSION", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Conversion Comments */ if (convinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -13501,7 +13680,7 @@ format_aggregate_signature(AggInfo *agginfo, Archive *fout, bool honor_quotes) appendPQExpBufferStr(&buf, agginfo->aggfn.dobj.name); if (agginfo->aggfn.nargs == 0) - appendPQExpBuffer(&buf, "(*)"); + appendPQExpBufferStr(&buf, "(*)"); else { appendPQExpBufferChar(&buf, '('); @@ -13792,8 +13971,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo) if (!convertok) { - write_msg(NULL, "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n", - aggsig); + pg_log_warning("aggregate function %s could not be dumped correctly for this database version; ignored", + aggsig); if (aggfullsig) free(aggfullsig); @@ -13840,15 +14019,15 @@ dumpAgg(Archive *fout, AggInfo *agginfo) case AGGMODIFY_READ_ONLY: appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_ONLY"); break; - case AGGMODIFY_SHARABLE: - appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHARABLE"); + case AGGMODIFY_SHAREABLE: + appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = SHAREABLE"); break; case AGGMODIFY_READ_WRITE: appendPQExpBufferStr(details, ",\n FINALFUNC_MODIFY = READ_WRITE"); break; default: - exit_horribly(NULL, "unrecognized aggfinalmodify value for aggregate \"%s\"\n", - agginfo->aggfn.dobj.name); + fatal("unrecognized aggfinalmodify value for aggregate \"%s\"", + agginfo->aggfn.dobj.name); break; } } @@ -13896,15 +14075,15 @@ dumpAgg(Archive *fout, AggInfo *agginfo) case AGGMODIFY_READ_ONLY: appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_ONLY"); break; - case AGGMODIFY_SHARABLE: - appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHARABLE"); + case AGGMODIFY_SHAREABLE: + appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = SHAREABLE"); break; case AGGMODIFY_READ_WRITE: appendPQExpBufferStr(details, ",\n MFINALFUNC_MODIFY = READ_WRITE"); break; default: - exit_horribly(NULL, "unrecognized aggmfinalmodify value for aggregate \"%s\"\n", - agginfo->aggfn.dobj.name); + fatal("unrecognized aggmfinalmodify value for aggregate \"%s\"", + agginfo->aggfn.dobj.name); break; } } @@ -13928,8 +14107,8 @@ dumpAgg(Archive *fout, AggInfo *agginfo) else if (proparallel[0] == PROPARALLEL_RESTRICTED) appendPQExpBufferStr(details, ",\n PARALLEL = restricted"); else if (proparallel[0] != PROPARALLEL_UNSAFE) - exit_horribly(NULL, "unrecognized proparallel value for function \"%s\"\n", - agginfo->aggfn.dobj.name); + fatal("unrecognized proparallel value for function \"%s\"", + agginfo->aggfn.dobj.name); } appendPQExpBuffer(delq, "DROP AGGREGATE %s.%s;\n", @@ -13948,14 +14127,13 @@ dumpAgg(Archive *fout, AggInfo *agginfo) if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId, - aggsig_tag, - agginfo->aggfn.dobj.namespace->dobj.name, - NULL, - agginfo->aggfn.rolname, - false, "AGGREGATE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = aggsig_tag, + .namespace = agginfo->aggfn.dobj.namespace->dobj.name, + .owner = agginfo->aggfn.rolname, + .description = "AGGREGATE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Aggregate Comments */ if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14046,14 +14224,12 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo) if (prsinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, prsinfo->dobj.catId, prsinfo->dobj.dumpId, - prsinfo->dobj.name, - prsinfo->dobj.namespace->dobj.name, - NULL, - "", - false, "TEXT SEARCH PARSER", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = prsinfo->dobj.name, + .namespace = prsinfo->dobj.namespace->dobj.name, + .description = "TEXT SEARCH PARSER", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Parser Comments */ if (prsinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14126,14 +14302,13 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo) if (dictinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, dictinfo->dobj.catId, dictinfo->dobj.dumpId, - dictinfo->dobj.name, - dictinfo->dobj.namespace->dobj.name, - NULL, - dictinfo->rolname, - false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = dictinfo->dobj.name, + .namespace = dictinfo->dobj.namespace->dobj.name, + .owner = dictinfo->rolname, + .description = "TEXT SEARCH DICTIONARY", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Dictionary Comments */ if (dictinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14187,14 +14362,12 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo) if (tmplinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tmplinfo->dobj.catId, tmplinfo->dobj.dumpId, - tmplinfo->dobj.name, - tmplinfo->dobj.namespace->dobj.name, - NULL, - "", - false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tmplinfo->dobj.name, + .namespace = tmplinfo->dobj.namespace->dobj.name, + .description = "TEXT SEARCH TEMPLATE", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Template Comments */ if (tmplinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14307,14 +14480,13 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo) if (cfginfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, cfginfo->dobj.catId, cfginfo->dobj.dumpId, - cfginfo->dobj.name, - cfginfo->dobj.namespace->dobj.name, - NULL, - cfginfo->rolname, - false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = cfginfo->dobj.name, + .namespace = cfginfo->dobj.namespace->dobj.name, + .owner = cfginfo->rolname, + .description = "TEXT SEARCH CONFIGURATION", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Configuration Comments */ if (cfginfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14373,14 +14545,12 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo) if (fdwinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId, - fdwinfo->dobj.name, - NULL, - NULL, - fdwinfo->rolname, - false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = fdwinfo->dobj.name, + .owner = fdwinfo->rolname, + .description = "FOREIGN DATA WRAPPER", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Foreign Data Wrapper Comments */ if (fdwinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14464,14 +14634,12 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo) if (srvinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId, - srvinfo->dobj.name, - NULL, - NULL, - srvinfo->rolname, - false, "SERVER", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = srvinfo->dobj.name, + .owner = srvinfo->rolname, + .description = "SERVER", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Foreign Server Comments */ if (srvinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -14582,14 +14750,13 @@ dumpUserMappings(Archive *fout, usename, servername); ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, - namespace, - NULL, - owner, false, - "USER MAPPING", SECTION_PRE_DATA, - q->data, delq->data, NULL, - &dumpId, 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = namespace, + .owner = owner, + .description = "USER MAPPING", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); } PQclear(res); @@ -14637,9 +14804,8 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo) break; default: /* shouldn't get here */ - exit_horribly(NULL, - "unrecognized object type in default privileges: %d\n", - (int) daclinfo->defaclobjtype); + fatal("unrecognized object type in default privileges: %d", + (int) daclinfo->defaclobjtype); type = ""; /* keep compiler quiet */ } @@ -14656,19 +14822,18 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo) daclinfo->defaclrole, fout->remoteVersion, q)) - exit_horribly(NULL, "could not parse default ACL list (%s)\n", - daclinfo->defaclacl); + fatal("could not parse default ACL list (%s)", + daclinfo->defaclacl); if (daclinfo->dobj.dump & DUMP_COMPONENT_ACL) ArchiveEntry(fout, daclinfo->dobj.catId, daclinfo->dobj.dumpId, - tag->data, - daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL, - NULL, - daclinfo->defaclrole, - false, "DEFAULT ACL", SECTION_POST_DATA, - q->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = daclinfo->dobj.namespace ? + daclinfo->dobj.namespace->dobj.name : NULL, + .owner = daclinfo->defaclrole, + .description = "DEFAULT ACL", + .section = SECTION_POST_DATA, + .createStmt = q->data)); destroyPQExpBuffer(tag); destroyPQExpBuffer(q); @@ -14733,22 +14898,20 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId, */ if (strlen(initacls) != 0 || strlen(initracls) != 0) { - appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n"); + appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(true);\n"); if (!buildACLCommands(name, subname, nspname, type, initacls, initracls, owner, "", fout->remoteVersion, sql)) - exit_horribly(NULL, - "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n", - initacls, initracls, name, type); - appendPQExpBuffer(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n"); + fatal("could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)", + initacls, initracls, name, type); + appendPQExpBufferStr(sql, "SELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\n"); } if (!buildACLCommands(name, subname, nspname, type, acls, racls, owner, "", fout->remoteVersion, sql)) - exit_horribly(NULL, - "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n", - acls, racls, name, type); + fatal("could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)", + acls, racls, name, type); if (sql->len > 0) { @@ -14760,13 +14923,14 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId, appendPQExpBuffer(tag, "%s %s", type, name); ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, nspname, - NULL, - owner ? owner : "", - false, "ACL", SECTION_NONE, - sql->data, "", NULL, - &(objDumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = nspname, + .owner = owner, + .description = "ACL", + .section = SECTION_NONE, + .createStmt = sql->data, + .deps = &objDumpId, + .nDeps = 1)); destroyPQExpBuffer(tag); } @@ -14848,11 +15012,14 @@ dumpSecLabel(Archive *fout, const char *type, const char *name, appendPQExpBuffer(tag, "%s %s", type, name); ArchiveEntry(fout, nilCatalogId, createDumpId(), - tag->data, namespace, NULL, owner, - false, "SECURITY LABEL", SECTION_NONE, - query->data, "", NULL, - &(dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag->data, + .namespace = namespace, + .owner = owner, + .description = "SECURITY LABEL", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &dumpId, + .nDeps = 1)); destroyPQExpBuffer(tag); } @@ -14928,13 +15095,14 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename) appendPQExpBuffer(target, "%s %s", reltypename, fmtId(tbinfo->dobj.name)); ArchiveEntry(fout, nilCatalogId, createDumpId(), - target->data, - tbinfo->dobj.namespace->dobj.name, - NULL, tbinfo->rolname, - false, "SECURITY LABEL", SECTION_NONE, - query->data, "", NULL, - &(tbinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = target->data, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "SECURITY LABEL", + .section = SECTION_NONE, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); } destroyPQExpBuffer(query); destroyPQExpBuffer(target); @@ -15241,18 +15409,18 @@ createViewAsClause(Archive *fout, TableInfo *tbinfo) if (PQntuples(res) != 1) { if (PQntuples(res) < 1) - exit_horribly(NULL, "query to obtain definition of view \"%s\" returned no data\n", - tbinfo->dobj.name); + fatal("query to obtain definition of view \"%s\" returned no data", + tbinfo->dobj.name); else - exit_horribly(NULL, "query to obtain definition of view \"%s\" returned more than one definition\n", - tbinfo->dobj.name); + fatal("query to obtain definition of view \"%s\" returned more than one definition", + tbinfo->dobj.name); } len = PQgetlength(res, 0, 0); if (len == 0) - exit_horribly(NULL, "definition of view \"%s\" appears to be empty (length zero)\n", - tbinfo->dobj.name); + fatal("definition of view \"%s\" appears to be empty (length zero)", + tbinfo->dobj.name); /* Strip off the trailing semicolon so that other things may follow. */ Assert(PQgetvalue(res, 0, 0)[len - 1] == ';'); @@ -15325,14 +15493,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) int actual_atts; /* number of attrs in this CREATE statement */ const char *reltypename; char *storage; - char *srvname; - char *ftoptions; int j, k; qrelname = pg_strdup(fmtId(tbinfo->dobj.name)); qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo)); + + if (tbinfo->hasoids) + pg_log_warning("WITH OIDS is not supported anymore (table \"%s\")", + qrelname); + if (dopt->binary_upgrade) binary_upgrade_set_type_oids_by_rel_oid(fout, q, tbinfo->dobj.catId.oid); @@ -15377,6 +15548,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } else { + char *ftoptions = NULL; + char *srvname = NULL; + switch (tbinfo->relkind) { case RELKIND_FOREIGN_TABLE: @@ -15413,13 +15587,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } case RELKIND_MATVIEW: reltypename = "MATERIALIZED VIEW"; - srvname = NULL; - ftoptions = NULL; break; default: reltypename = "TABLE"; - srvname = NULL; - ftoptions = NULL; } numParents = tbinfo->numParents; @@ -15444,27 +15614,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (tbinfo->reloftype && !dopt->binary_upgrade) appendPQExpBuffer(q, " OF %s", tbinfo->reloftype); - /* - * If the table is a partition, dump it as such; except in the case of - * a binary upgrade, we dump the table normally and attach it to the - * parent afterward. - */ - if (tbinfo->ispartition && !dopt->binary_upgrade) - { - TableInfo *parentRel = tbinfo->parents[0]; - - /* - * With partitions, unlike inheritance, there can only be one - * parent. - */ - if (tbinfo->numParents != 1) - exit_horribly(NULL, "invalid number of parents %d for table \"%s\"\n", - tbinfo->numParents, tbinfo->dobj.name); - - appendPQExpBuffer(q, " PARTITION OF %s", - fmtQualifiedDumpable(parentRel)); - } - if (tbinfo->relkind != RELKIND_MATVIEW) { /* Dump the attributes */ @@ -15479,26 +15628,30 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) */ if (shouldPrintColumn(dopt, tbinfo, j)) { + bool print_default; + bool print_notnull; + /* * Default value --- suppress if to be printed separately. */ - bool has_default = (tbinfo->attrdefs[j] != NULL && - !tbinfo->attrdefs[j]->separate); + print_default = (tbinfo->attrdefs[j] != NULL && + !tbinfo->attrdefs[j]->separate); /* * Not Null constraint --- suppress if inherited, except - * in binary-upgrade case where that won't work. + * if partition, or in binary-upgrade case where that + * won't work. */ - bool has_notnull = (tbinfo->notnull[j] && - (!tbinfo->inhNotNull[j] || - dopt->binary_upgrade)); + print_notnull = (tbinfo->notnull[j] && + (!tbinfo->inhNotNull[j] || + tbinfo->ispartition || dopt->binary_upgrade)); /* - * Skip column if fully defined by reloftype or the - * partition parent. + * Skip column if fully defined by reloftype, except in + * binary upgrade */ - if ((tbinfo->reloftype || tbinfo->ispartition) && - !has_default && !has_notnull && !dopt->binary_upgrade) + if (tbinfo->reloftype && !print_default && !print_notnull && + !dopt->binary_upgrade) continue; /* Format properly if not first attr */ @@ -15521,25 +15674,35 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) * clean things up later. */ appendPQExpBufferStr(q, " INTEGER /* dummy */"); - /* Skip all the rest, too */ + /* and skip to the next column */ continue; } /* - * Attribute type - * - * In binary-upgrade mode, we always include the type. If - * we aren't in binary-upgrade mode, then we skip the type - * when creating a typed table ('OF type_name') or a - * partition ('PARTITION OF'), since the type comes from - * the parent/partitioned table. + * Attribute type; print it except when creating a typed + * table ('OF type_name'), but in binary-upgrade mode, + * print it in that case too. */ - if (dopt->binary_upgrade || (!tbinfo->reloftype && !tbinfo->ispartition)) + if (dopt->binary_upgrade || !tbinfo->reloftype) { appendPQExpBuffer(q, " %s", tbinfo->atttypnames[j]); } + if (print_default) + { + if (tbinfo->attgenerated[j] == ATTRIBUTE_GENERATED_STORED) + appendPQExpBuffer(q, " GENERATED ALWAYS AS (%s) STORED", + tbinfo->attrdefs[j]->adef_expr); + else + appendPQExpBuffer(q, " DEFAULT %s", + tbinfo->attrdefs[j]->adef_expr); + } + + + if (print_notnull) + appendPQExpBufferStr(q, " NOT NULL"); + /* Add collation if not default for the type */ if (OidIsValid(tbinfo->attcollation[j])) { @@ -15550,24 +15713,23 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) appendPQExpBuffer(q, " COLLATE %s", fmtQualifiedDumpable(coll)); } - - if (has_default) - appendPQExpBuffer(q, " DEFAULT %s", - tbinfo->attrdefs[j]->adef_expr); - - if (has_notnull) - appendPQExpBufferStr(q, " NOT NULL"); } } /* * Add non-inherited CHECK constraints, if any. + * + * For partitions, we need to include check constraints even if + * they're not defined locally, because the ALTER TABLE ATTACH + * PARTITION that we'll emit later expects the constraint to be + * there. (No need to fix conislocal: ATTACH PARTITION does that) */ for (j = 0; j < tbinfo->ncheck; j++) { ConstraintInfo *constr = &(tbinfo->checkexprs[j]); - if (constr->separate || !constr->conislocal) + if (constr->separate || + (!constr->conislocal && !tbinfo->ispartition)) continue; if (actual_atts == 0) @@ -15584,25 +15746,20 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) if (actual_atts) appendPQExpBufferStr(q, "\n)"); - else if (!((tbinfo->reloftype || tbinfo->ispartition) && - !dopt->binary_upgrade)) + else if (!(tbinfo->reloftype && !dopt->binary_upgrade)) { /* - * We must have a parenthesized attribute list, even though - * empty, when not using the OF TYPE or PARTITION OF syntax. + * No attributes? we must have a parenthesized attribute list, + * even though empty, when not using the OF TYPE syntax. */ appendPQExpBufferStr(q, " (\n)"); } - if (tbinfo->ispartition && !dopt->binary_upgrade) - { - appendPQExpBufferChar(q, '\n'); - appendPQExpBufferStr(q, tbinfo->partbound); - } - - /* Emit the INHERITS clause, except if this is a partition. */ - if (numParents > 0 && - !tbinfo->ispartition && + /* + * Emit the INHERITS clause (not for partitions), except in + * binary-upgrade mode. + */ + if (numParents > 0 && !tbinfo->ispartition && !dopt->binary_upgrade) { appendPQExpBufferStr(q, "\nINHERITS ("); @@ -15665,6 +15822,29 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) else appendPQExpBufferStr(q, ";\n"); + /* + * in binary upgrade mode, update the catalog with any missing values + * that might be present. + */ + if (dopt->binary_upgrade) + { + for (j = 0; j < tbinfo->numatts; j++) + { + if (tbinfo->attmissingval[j][0] != '\0') + { + appendPQExpBufferStr(q, "\n-- set missing value.\n"); + appendPQExpBufferStr(q, + "SELECT pg_catalog.binary_upgrade_set_missing_value("); + appendStringLiteralAH(q, qualrelname, fout); + appendPQExpBufferStr(q, "::pg_catalog.regclass,"); + appendStringLiteralAH(q, tbinfo->attnames[j], fout); + appendPQExpBufferStr(q, ","); + appendStringLiteralAH(q, tbinfo->attmissingval[j], fout); + appendPQExpBufferStr(q, ");\n\n"); + } + } + } + /* * To create binary-compatible heap files, we have to ensure the same * physical column order, including dropped columns, as in the @@ -15730,11 +15910,17 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } } + /* + * Add inherited CHECK constraints, if any. + * + * For partitions, they were already dumped, and conislocal + * doesn't need fixing. + */ for (k = 0; k < tbinfo->ncheck; k++) { ConstraintInfo *constr = &(tbinfo->checkexprs[k]); - if (constr->separate || constr->conislocal) + if (constr->separate || constr->conislocal || tbinfo->ispartition) continue; appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inherited constraint.\n"); @@ -15752,30 +15938,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) appendPQExpBufferStr(q, "::pg_catalog.regclass;\n"); } - if (numParents > 0) + if (numParents > 0 && !tbinfo->ispartition) { - appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance and partitioning this way.\n"); + appendPQExpBufferStr(q, "\n-- For binary upgrade, set up inheritance this way.\n"); for (k = 0; k < numParents; k++) { TableInfo *parentRel = parents[k]; - /* In the partitioning case, we alter the parent */ - if (tbinfo->ispartition) - appendPQExpBuffer(q, - "ALTER TABLE ONLY %s ATTACH PARTITION ", - fmtQualifiedDumpable(parentRel)); - else - appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT ", - qualrelname); - - /* Partition needs specifying the bounds */ - if (tbinfo->ispartition) - appendPQExpBuffer(q, "%s %s;\n", - qualrelname, - tbinfo->partbound); - else - appendPQExpBuffer(q, "%s;\n", - fmtQualifiedDumpable(parentRel)); + appendPQExpBuffer(q, "ALTER TABLE ONLY %s INHERIT %s;\n", + qualrelname, + fmtQualifiedDumpable(parentRel)); } } @@ -15788,6 +15960,27 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } } + /* + * For partitioned tables, emit the ATTACH PARTITION clause. Note + * that we always want to create partitions this way instead of using + * CREATE TABLE .. PARTITION OF, mainly to preserve a possible column + * layout discrepancy with the parent, but also to ensure it gets the + * correct tablespace setting if it differs from the parent's. + */ + if (tbinfo->ispartition) + { + /* With partitions there can only be one parent */ + if (tbinfo->numParents != 1) + fatal("invalid number of parents %d for table \"%s\"", + tbinfo->numParents, tbinfo->dobj.name); + + /* Perform ALTER TABLE on the parent */ + appendPQExpBuffer(q, + "ALTER TABLE ONLY %s ATTACH PARTITION %s %s;\n", + fmtQualifiedDumpable(parents[0]), + qualrelname, tbinfo->partbound); + } + /* * In binary_upgrade mode, arrange to restore the old relfrozenxid and * relminmxid of all vacuumable relations. (While vacuum.c processes @@ -15920,7 +16113,7 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) /* * Dump per-column attributes. */ - if (tbinfo->attoptions[j] && tbinfo->attoptions[j][0] != '\0') + if (tbinfo->attoptions[j][0] != '\0') { appendPQExpBuffer(q, "ALTER TABLE ONLY %s ", qualrelname); @@ -15934,7 +16127,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) * Dump per-column fdw options. */ if (tbinfo->relkind == RELKIND_FOREIGN_TABLE && - tbinfo->attfdwoptions[j] && tbinfo->attfdwoptions[j][0] != '\0') { appendPQExpBuffer(q, "ALTER FOREIGN TABLE %s ", @@ -15945,6 +16137,11 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) tbinfo->attfdwoptions[j]); } } + + if (ftoptions) + free(ftoptions); + if (srvname) + free(srvname); } /* @@ -15971,10 +16168,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) } } - if (tbinfo->relkind == RELKIND_FOREIGN_TABLE && tbinfo->hasoids) - appendPQExpBuffer(q, "\nALTER TABLE ONLY %s SET WITH OIDS;\n", - qualrelname); - if (tbinfo->forcerowsec) appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n", qualrelname); @@ -15985,19 +16178,26 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo) tbinfo->dobj.namespace->dobj.name); if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) - ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, - tbinfo->dobj.name, - tbinfo->dobj.namespace->dobj.name, - (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace, - tbinfo->rolname, - (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false, - reltypename, - tbinfo->postponed_def ? - SECTION_POST_DATA : SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + { + char *tableam = NULL; + if (tbinfo->relkind == RELKIND_RELATION || + tbinfo->relkind == RELKIND_MATVIEW) + tableam = tbinfo->amname; + + ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .tablespace = (tbinfo->relkind == RELKIND_VIEW) ? + NULL : tbinfo->reltablespace, + .tableam = tableam, + .owner = tbinfo->rolname, + .description = reltypename, + .section = tbinfo->postponed_def ? + SECTION_POST_DATA : SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); + } /* Dump Table Comments */ if (tbinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -16067,14 +16267,13 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo) if (adinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, adinfo->dobj.catId, adinfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, - false, "DEFAULT", SECTION_PRE_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "DEFAULT", + .section = SECTION_PRE_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); free(tag); destroyPQExpBuffer(q); @@ -16098,8 +16297,6 @@ getAttrName(int attrnum, TableInfo *tblInfo) { case SelfItemPointerAttributeNumber: return "ctid"; - case ObjectIdAttributeNumber: - return "oid"; case MinTransactionIdAttributeNumber: return "xmin"; case MinCommandIdAttributeNumber: @@ -16111,8 +16308,8 @@ getAttrName(int attrnum, TableInfo *tblInfo) case TableOidAttributeNumber: return "tableoid"; } - exit_horribly(NULL, "invalid column number %d for table \"%s\"\n", - attrnum, tblInfo->dobj.name); + fatal("invalid column number %d for table \"%s\"", + attrnum, tblInfo->dobj.name); return NULL; /* keep compiler quiet */ } @@ -16147,6 +16344,13 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) */ if (!is_constraint) { + char *indstatcols = indxinfo->indstatcols; + char *indstatvals = indxinfo->indstatvals; + char **indstatcolsarray = NULL; + char **indstatvalsarray = NULL; + int nstatcols; + int nstatvals; + if (dopt->binary_upgrade) binary_upgrade_set_pg_class_oids(fout, q, indxinfo->dobj.catId.oid, true); @@ -16154,6 +16358,12 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) /* Plain secondary index */ appendPQExpBuffer(q, "%s;\n", indxinfo->indexdef); + /* + * Append ALTER TABLE commands as needed to set properties that we + * only have ALTER TABLE syntax for. Keep this in sync with the + * similar code in dumpConstraint! + */ + /* If the index is clustered, we need to record that. */ if (indxinfo->indisclustered) { @@ -16164,6 +16374,32 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) qindxname); } + /* + * If the index has any statistics on some of its columns, generate + * the associated ALTER INDEX queries. + */ + if (parsePGArray(indstatcols, &indstatcolsarray, &nstatcols) && + parsePGArray(indstatvals, &indstatvalsarray, &nstatvals) && + nstatcols == nstatvals) + { + int j; + + for (j = 0; j < nstatcols; j++) + { + appendPQExpBuffer(q, "ALTER INDEX %s ", + fmtQualifiedDumpable(indxinfo)); + + /* + * Note that this is a column number, so no quotes should be + * used. + */ + appendPQExpBuffer(q, "ALTER COLUMN %s ", + indstatcolsarray[j]); + appendPQExpBuffer(q, "SET STATISTICS %s;\n", + indstatvalsarray[j]); + } + } + /* If the index defines identity, we need to record that. */ if (indxinfo->indisreplident) { @@ -16179,14 +16415,19 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo) if (indxinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, indxinfo->dobj.catId, indxinfo->dobj.dumpId, - indxinfo->dobj.name, - tbinfo->dobj.namespace->dobj.name, - indxinfo->tablespace, - tbinfo->rolname, false, - "INDEX", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = indxinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .tablespace = indxinfo->tablespace, + .owner = tbinfo->rolname, + .description = "INDEX", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); + + if (indstatcolsarray) + free(indstatcolsarray); + if (indstatvalsarray) + free(indstatvalsarray); } /* Dump Index Comments */ @@ -16217,19 +16458,17 @@ dumpIndexAttach(Archive *fout, IndexAttachInfo *attachinfo) { PQExpBuffer q = createPQExpBuffer(); - appendPQExpBuffer(q, "\nALTER INDEX %s ", + appendPQExpBuffer(q, "ALTER INDEX %s ", fmtQualifiedDumpable(attachinfo->parentIdx)); appendPQExpBuffer(q, "ATTACH PARTITION %s;\n", fmtQualifiedDumpable(attachinfo->partitionIdx)); ArchiveEntry(fout, attachinfo->dobj.catId, attachinfo->dobj.dumpId, - attachinfo->dobj.name, - NULL, NULL, - "", - false, "INDEX ATTACH", SECTION_POST_DATA, - q->data, "", NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = attachinfo->dobj.name, + .namespace = attachinfo->dobj.namespace->dobj.name, + .description = "INDEX ATTACH", + .section = SECTION_POST_DATA, + .createStmt = q->data)); destroyPQExpBuffer(q); } @@ -16271,20 +16510,32 @@ dumpStatisticsExt(Archive *fout, StatsExtInfo *statsextinfo) /* Result of pg_get_statisticsobjdef is complete except for semicolon */ appendPQExpBuffer(q, "%s;\n", stxdef); + /* + * We only issue an ALTER STATISTICS statement if the stxstattarget entry + * for this statictics object is non-negative (i.e. it's not the default + * value). + */ + if (statsextinfo->stattarget >= 0) + { + appendPQExpBuffer(q, "ALTER STATISTICS %s ", + fmtQualifiedDumpable(statsextinfo)); + appendPQExpBuffer(q, "SET STATISTICS %d;\n", + statsextinfo->stattarget); + } + appendPQExpBuffer(delq, "DROP STATISTICS %s;\n", fmtQualifiedDumpable(statsextinfo)); if (statsextinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, statsextinfo->dobj.catId, statsextinfo->dobj.dumpId, - statsextinfo->dobj.name, - statsextinfo->dobj.namespace->dobj.name, - NULL, - statsextinfo->rolname, false, - "STATISTICS", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = statsextinfo->dobj.name, + .namespace = statsextinfo->dobj.namespace->dobj.name, + .owner = statsextinfo->rolname, + .description = "STATISTICS", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); /* Dump Statistics Comments */ if (statsextinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -16332,8 +16583,8 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) indxinfo = (IndxInfo *) findObjectByDumpId(coninfo->conindex); if (indxinfo == NULL) - exit_horribly(NULL, "missing index for constraint \"%s\"\n", - coninfo->dobj.name); + fatal("missing index for constraint \"%s\"", + coninfo->dobj.name); if (dopt->binary_upgrade) binary_upgrade_set_pg_class_oids(fout, q, @@ -16368,7 +16619,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) } if (indxinfo->indnkeyattrs < indxinfo->indnattrs) - appendPQExpBuffer(q, ") INCLUDE ("); + appendPQExpBufferStr(q, ") INCLUDE ("); for (k = indxinfo->indnkeyattrs; k < indxinfo->indnattrs; k++) { @@ -16403,6 +16654,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) appendPQExpBufferStr(q, ";\n"); } + /* + * Append ALTER TABLE commands as needed to set properties that we + * only have ALTER TABLE syntax for. Keep this in sync with the + * similar code in dumpIndex! + */ + /* If the index is clustered, we need to record that. */ if (indxinfo->indisclustered) { @@ -16413,6 +16670,16 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) fmtId(indxinfo->dobj.name)); } + /* If the index defines identity, we need to record that. */ + if (indxinfo->indisreplident) + { + appendPQExpBuffer(q, "\nALTER TABLE ONLY %s REPLICA IDENTITY USING", + fmtQualifiedDumpable(tbinfo)); + /* index name is not qualified in this syntax */ + appendPQExpBuffer(q, " INDEX %s;\n", + fmtId(indxinfo->dobj.name)); + } + appendPQExpBuffer(delq, "ALTER TABLE ONLY %s ", fmtQualifiedDumpable(tbinfo)); appendPQExpBuffer(delq, "DROP CONSTRAINT %s;\n", @@ -16422,24 +16689,24 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - indxinfo->tablespace, - tbinfo->rolname, false, - "CONSTRAINT", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .tablespace = indxinfo->tablespace, + .owner = tbinfo->rolname, + .description = "CONSTRAINT", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); } else if (coninfo->contype == 'f') { - char *only; + char *only; /* - * Foreign keys on partitioned tables are always declared as inheriting - * to partitions; for all other cases, emit them as applying ONLY - * directly to the named table, because that's how they work for - * regular inherited tables. + * Foreign keys on partitioned tables are always declared as + * inheriting to partitions; for all other cases, emit them as + * applying ONLY directly to the named table, because that's how they + * work for regular inherited tables. */ only = tbinfo->relkind == RELKIND_PARTITIONED_TABLE ? "" : "ONLY "; @@ -16462,14 +16729,13 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "FK CONSTRAINT", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "FK CONSTRAINT", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); } else if (coninfo->contype == 'c' && tbinfo) { @@ -16494,14 +16760,13 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "CHECK CONSTRAINT", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "CHECK CONSTRAINT", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); } } else if (coninfo->contype == 'c' && tbinfo == NULL) @@ -16527,20 +16792,19 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo) if (coninfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, coninfo->dobj.catId, coninfo->dobj.dumpId, - tag, - tyinfo->dobj.namespace->dobj.name, - NULL, - tyinfo->rolname, false, - "CHECK CONSTRAINT", SECTION_POST_DATA, - q->data, delq->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tyinfo->dobj.namespace->dobj.name, + .owner = tyinfo->rolname, + .description = "CHECK CONSTRAINT", + .section = SECTION_POST_DATA, + .createStmt = q->data, + .dropStmt = delq->data)); } } else { - exit_horribly(NULL, "unrecognized constraint type: %c\n", - coninfo->contype); + fatal("unrecognized constraint type: %c", + coninfo->contype); } /* Dump Constraint Comments --- only works for table constraints */ @@ -16589,23 +16853,19 @@ dumpTableConstraintComment(Archive *fout, ConstraintInfo *coninfo) * find the last built in oid * * For 7.1 through 8.0, we do this by retrieving datlastsysoid from the - * pg_database entry for the current database. + * pg_database entry for the current database. (Note: current_database() + * requires 7.3; pg_dump requires 8.0 now.) */ static Oid -findLastBuiltinOid_V71(Archive *fout, const char *dbname) +findLastBuiltinOid_V71(Archive *fout) { PGresult *res; Oid last_oid; - PQExpBuffer query = createPQExpBuffer(); - resetPQExpBuffer(query); - appendPQExpBufferStr(query, "SELECT datlastsysoid from pg_database where datname = "); - appendStringLiteralAH(query, dbname, fout); - - res = ExecuteSqlQueryForSingleRow(fout, query->data); + res = ExecuteSqlQueryForSingleRow(fout, + "SELECT datlastsysoid FROM pg_database WHERE datname = current_database()"); last_oid = atooid(PQgetvalue(res, 0, PQfnumber(res, "datlastsysoid"))); PQclear(res); - destroyPQExpBuffer(query); return last_oid; } @@ -16675,10 +16935,10 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) if (PQntuples(res) != 1) { - write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n", - "query to get data of sequence \"%s\" returned %d rows (expected 1)\n", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); + pg_log_error(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", + "query to get data of sequence \"%s\" returned %d rows (expected 1)", + PQntuples(res)), + tbinfo->dobj.name, PQntuples(res)); exit_nicely(1); } @@ -16709,7 +16969,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) } else { - exit_horribly(NULL, "unrecognized sequence type: %s\n", seqtype); + fatal("unrecognized sequence type: %s", seqtype); default_minv = default_maxv = 0; /* keep compiler quiet */ } @@ -16756,9 +17016,9 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) "ALTER COLUMN %s ADD GENERATED ", fmtId(owning_tab->attnames[tbinfo->owning_col - 1])); if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_ALWAYS) - appendPQExpBuffer(query, "ALWAYS"); + appendPQExpBufferStr(query, "ALWAYS"); else if (owning_tab->attidentity[tbinfo->owning_col - 1] == ATTRIBUTE_IDENTITY_BY_DEFAULT) - appendPQExpBuffer(query, "BY DEFAULT"); + appendPQExpBufferStr(query, "BY DEFAULT"); appendPQExpBuffer(query, " AS IDENTITY (\n SEQUENCE NAME %s\n", fmtQualifiedDumpable(tbinfo)); } @@ -16805,14 +17065,13 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId, - tbinfo->dobj.name, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, - false, "SEQUENCE", SECTION_PRE_DATA, - query->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "SEQUENCE", + .section = SECTION_PRE_DATA, + .createStmt = query->data, + .dropStmt = delqry->data)); /* * If the sequence is owned by a table column, emit the ALTER for it as a @@ -16831,8 +17090,8 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) TableInfo *owning_tab = findTableByOid(tbinfo->owning_tab); if (owning_tab == NULL) - exit_horribly(NULL, "failed sanity check, parent table with OID %u of sequence with OID %u not found\n", - tbinfo->owning_tab, tbinfo->dobj.catId.oid); + fatal("failed sanity check, parent table with OID %u of sequence with OID %u not found", + tbinfo->owning_tab, tbinfo->dobj.catId.oid); if (owning_tab->dobj.dump & DUMP_COMPONENT_DEFINITION) { @@ -16846,14 +17105,14 @@ dumpSequence(Archive *fout, TableInfo *tbinfo) if (tbinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, nilCatalogId, createDumpId(), - tbinfo->dobj.name, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, - false, "SEQUENCE OWNED BY", SECTION_PRE_DATA, - query->data, "", NULL, - &(tbinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "SEQUENCE OWNED BY", + .section = SECTION_PRE_DATA, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); } } @@ -16896,10 +17155,10 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo) if (PQntuples(res) != 1) { - write_msg(NULL, ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)\n", - "query to get data of sequence \"%s\" returned %d rows (expected 1)\n", - PQntuples(res)), - tbinfo->dobj.name, PQntuples(res)); + pg_log_error(ngettext("query to get data of sequence \"%s\" returned %d row (expected 1)", + "query to get data of sequence \"%s\" returned %d rows (expected 1)", + PQntuples(res)), + tbinfo->dobj.name, PQntuples(res)); exit_nicely(1); } @@ -16914,14 +17173,14 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo) if (tdinfo->dobj.dump & DUMP_COMPONENT_DATA) ArchiveEntry(fout, nilCatalogId, createDumpId(), - tbinfo->dobj.name, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, - false, "SEQUENCE SET", SECTION_DATA, - query->data, "", NULL, - &(tbinfo->dobj.dumpId), 1, - NULL, NULL); + ARCHIVE_OPTS(.tag = tbinfo->dobj.name, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "SEQUENCE SET", + .section = SECTION_DATA, + .createStmt = query->data, + .deps = &(tbinfo->dobj.dumpId), + .nDeps = 1)); PQclear(res); @@ -16992,7 +17251,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) appendPQExpBufferStr(query, "INSTEAD OF"); else { - write_msg(NULL, "unexpected tgtype value: %d\n", tginfo->tgtype); + pg_log_error("unexpected tgtype value: %d", tginfo->tgtype); exit_nicely(1); } @@ -17052,7 +17311,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) appendPQExpBufferStr(query, " FOR EACH STATEMENT\n "); /* regproc output is already sufficiently quoted */ - appendPQExpBuffer(query, "EXECUTE PROCEDURE %s(", + appendPQExpBuffer(query, "EXECUTE FUNCTION %s(", tginfo->tgfname); tgargs = (char *) PQunescapeBytea((unsigned char *) tginfo->tgargs, @@ -17066,10 +17325,10 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) if (p + tlen >= tgargs + lentgargs) { /* hm, not found before end of bytea value... */ - write_msg(NULL, "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n", - tginfo->tgargs, - tginfo->dobj.name, - tbinfo->dobj.name); + pg_log_error("invalid argument string (%s) for trigger \"%s\" on table \"%s\"", + tginfo->tgargs, + tginfo->dobj.name, + tbinfo->dobj.name); exit_nicely(1); } @@ -17113,14 +17372,13 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo) if (tginfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, tginfo->dobj.catId, tginfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "TRIGGER", SECTION_POST_DATA, - query->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "TRIGGER", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .dropStmt = delqry->data)); if (tginfo->dobj.dump & DUMP_COMPONENT_COMMENT) dumpComment(fout, trigprefix->data, qtabname, @@ -17167,7 +17425,7 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo) appendPQExpBufferChar(query, ')'); } - appendPQExpBufferStr(query, "\n EXECUTE PROCEDURE "); + appendPQExpBufferStr(query, "\n EXECUTE FUNCTION "); appendPQExpBufferStr(query, evtinfo->evtfname); appendPQExpBufferStr(query, "();\n"); @@ -17196,14 +17454,18 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo) appendPQExpBuffer(delqry, "DROP EVENT TRIGGER %s;\n", qevtname); + if (dopt->binary_upgrade) + binary_upgrade_extension_member(query, &evtinfo->dobj, + "EVENT TRIGGER", qevtname, NULL); + if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId, - evtinfo->dobj.name, NULL, NULL, - evtinfo->evtowner, false, - "EVENT TRIGGER", SECTION_POST_DATA, - query->data, delqry->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = evtinfo->dobj.name, + .owner = evtinfo->evtowner, + .description = "EVENT TRIGGER", + .section = SECTION_POST_DATA, + .createStmt = query->data, + .dropStmt = delqry->data)); if (evtinfo->dobj.dump & DUMP_COMPONENT_COMMENT) dumpComment(fout, "EVENT TRIGGER", qevtname, @@ -17292,8 +17554,8 @@ dumpRule(Archive *fout, RuleInfo *rinfo) if (PQntuples(res) != 1) { - write_msg(NULL, "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n", - rinfo->dobj.name, tbinfo->dobj.name); + pg_log_error("query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned", + rinfo->dobj.name, tbinfo->dobj.name); exit_nicely(1); } @@ -17356,14 +17618,13 @@ dumpRule(Archive *fout, RuleInfo *rinfo) if (rinfo->dobj.dump & DUMP_COMPONENT_DEFINITION) ArchiveEntry(fout, rinfo->dobj.catId, rinfo->dobj.dumpId, - tag, - tbinfo->dobj.namespace->dobj.name, - NULL, - tbinfo->rolname, false, - "RULE", SECTION_POST_DATA, - cmd->data, delcmd->data, NULL, - NULL, 0, - NULL, NULL); + ARCHIVE_OPTS(.tag = tag, + .namespace = tbinfo->dobj.namespace->dobj.name, + .owner = tbinfo->rolname, + .description = "RULE", + .section = SECTION_POST_DATA, + .createStmt = cmd->data, + .dropStmt = delcmd->data)); /* Dump rule comments */ if (rinfo->dobj.dump & DUMP_COMPONENT_COMMENT) @@ -17455,7 +17716,7 @@ getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], if (ext == NULL) { /* shouldn't happen */ - fprintf(stderr, "could not find referenced extension %u\n", extId); + pg_log_warning("could not find referenced extension %u", extId); continue; } @@ -17579,12 +17840,7 @@ processExtensionTables(Archive *fout, ExtensionInfo extinfo[], if (dumpobj) { - /* - * Note: config tables are dumped without OIDs regardless - * of the --oids setting. This is because row filtering - * conditions aren't compatible with dumping OIDs. - */ - makeTableDataInfo(dopt, configtbl, false); + makeTableDataInfo(dopt, configtbl); if (configtbl->dataObj != NULL) { if (strlen(extconditionarray[j]) > 0) @@ -17600,7 +17856,7 @@ processExtensionTables(Archive *fout, ExtensionInfo extinfo[], } /* - * Now that all the TableInfoData objects have been created for all the + * Now that all the TableDataInfo objects have been created for all the * extensions, check their FK dependencies and register them to try and * dump the data out in an order that they can be restored in. * @@ -17672,20 +17928,57 @@ getDependencies(Archive *fout) DumpableObject *dobj, *refdobj; - if (g_verbose) - write_msg(NULL, "reading dependency data\n"); + pg_log_info("reading dependency data"); query = createPQExpBuffer(); /* + * Messy query to collect the dependency data we need. Note that we + * ignore the sub-object column, so that dependencies of or on a column + * look the same as dependencies of or on a whole table. + * * PIN dependencies aren't interesting, and EXTENSION dependencies were * already processed by getExtensionMembership. */ appendPQExpBufferStr(query, "SELECT " "classid, objid, refclassid, refobjid, deptype " "FROM pg_depend " - "WHERE deptype != 'p' AND deptype != 'e' " - "ORDER BY 1,2"); + "WHERE deptype != 'p' AND deptype != 'e'\n"); + + /* + * Since we don't treat pg_amop entries as separate DumpableObjects, we + * have to translate their dependencies into dependencies of their parent + * opfamily. Ignore internal dependencies though, as those will point to + * their parent opclass, which we needn't consider here (and if we did, + * it'd just result in circular dependencies). Also, "loose" opfamily + * entries will have dependencies on their parent opfamily, which we + * should drop since they'd likewise become useless self-dependencies. + * (But be sure to keep deps on *other* opfamilies; see amopsortfamily.) + * + * Skip this for pre-8.3 source servers: pg_opfamily doesn't exist there, + * and the (known) cases where it would matter to have these dependencies + * can't arise anyway. + */ + if (fout->remoteVersion >= 80300) + { + appendPQExpBufferStr(query, "UNION ALL\n" + "SELECT 'pg_opfamily'::regclass AS classid, amopfamily AS objid, refclassid, refobjid, deptype " + "FROM pg_depend d, pg_amop o " + "WHERE deptype NOT IN ('p', 'e', 'i') AND " + "classid = 'pg_amop'::regclass AND objid = o.oid " + "AND NOT (refclassid = 'pg_opfamily'::regclass AND amopfamily = refobjid)\n"); + + /* Likewise for pg_amproc entries */ + appendPQExpBufferStr(query, "UNION ALL\n" + "SELECT 'pg_opfamily'::regclass AS classid, amprocfamily AS objid, refclassid, refobjid, deptype " + "FROM pg_depend d, pg_amproc p " + "WHERE deptype NOT IN ('p', 'e', 'i') AND " + "classid = 'pg_amproc'::regclass AND objid = p.oid " + "AND NOT (refclassid = 'pg_opfamily'::regclass AND amprocfamily = refobjid)\n"); + } + + /* Sort the output for efficiency below */ + appendPQExpBufferStr(query, "ORDER BY 1,2"); res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -17728,8 +18021,8 @@ getDependencies(Archive *fout) if (dobj == NULL) { #ifdef NOT_USED - fprintf(stderr, "no referencing object %u %u\n", - objId.tableoid, objId.oid); + pg_log_warning("no referencing object %u %u", + objId.tableoid, objId.oid); #endif continue; } @@ -17739,8 +18032,8 @@ getDependencies(Archive *fout) if (refdobj == NULL) { #ifdef NOT_USED - fprintf(stderr, "no referenced object %u %u\n", - refobjId.tableoid, refobjId.oid); + pg_log_warning("no referenced object %u %u", + refobjId.tableoid, refobjId.oid); #endif continue; } @@ -18058,6 +18351,7 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer) int numatts = ti->numatts; char **attnames = ti->attnames; bool *attisdropped = ti->attisdropped; + char *attgenerated = ti->attgenerated; bool needComma; int i; @@ -18067,6 +18361,8 @@ fmtCopyColumnList(const TableInfo *ti, PQExpBuffer buffer) { if (attisdropped[i]) continue; + if (attgenerated[i]) + continue; if (needComma) appendPQExpBufferStr(buffer, ", "); appendPQExpBufferStr(buffer, fmtId(attnames[i])); @@ -18104,5 +18400,5 @@ appendReloptionsArrayAH(PQExpBuffer buffer, const char *reloptions, res = appendReloptionsArray(buffer, reloptions, prefix, fout->encoding, fout->std_strings); if (!res) - write_msg(NULL, "WARNING: could not parse reloptions array\n"); + pg_log_warning("could not parse reloptions array"); } diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index e96c662b1e9..ec5a924b8fa 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -3,7 +3,7 @@ * pg_dump.h * Common header file for the pg_dump utility * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_dump/pg_dump.h @@ -18,10 +18,6 @@ #define oidcmp(x,y) ( ((x) < (y) ? -1 : ((x) > (y)) ? 1 : 0) ) -#define oideq(x,y) ( (x) == (y) ) -#define oidle(x,y) ( (x) <= (y) ) -#define oidge(x,y) ( (x) >= (y) ) -#define oidzero(x) ( (x) == 0 ) /* * The data structures used to store system catalog information. Every @@ -310,12 +306,14 @@ typedef struct _tableInfo char *typstorage; /* type storage scheme */ bool *attisdropped; /* true if attr is dropped; don't dump it */ char *attidentity; + char *attgenerated; int *attlen; /* attribute length, used by binary_upgrade */ char *attalign; /* attribute align, used by binary_upgrade */ bool *attislocal; /* true if attr has local definition */ char **attoptions; /* per-attribute options */ Oid *attcollation; /* per-attribute collation selection */ char **attfdwoptions; /* per-attribute fdw options */ + char **attmissingval; /* per attribute missing value */ bool *notnull; /* NOT NULL constraints on attributes */ bool *inhNotNull; /* true if NOT NULL is inherited */ struct _attrDefInfo **attrdefs; /* DEFAULT expressions */ @@ -323,6 +321,7 @@ typedef struct _tableInfo char *partkeydef; /* partition key definition */ char *partbound; /* partition bound definition */ bool needs_override; /* has GENERATED ALWAYS AS IDENTITY */ + char *amname; /* relation access method */ /* * Stuff computed only for dumpable tables. @@ -349,7 +348,6 @@ typedef struct _tableDataInfo { DumpableObject dobj; TableInfo *tdtable; /* link to table to dump */ - bool oids; /* include OIDs in data? */ char *filtercond; /* WHERE condition to limit rows dumped */ } TableDataInfo; @@ -360,6 +358,8 @@ typedef struct _indxInfo char *indexdef; char *tablespace; /* tablespace in which index is stored */ char *indreloptions; /* options specified by WITH (...) */ + char *indstatcols; /* column numbers with statistics */ + char *indstatvals; /* statistic values for columns */ int indnkeyattrs; /* number of index key attributes */ int indnattrs; /* total number of index attributes */ Oid *indkeys; /* In spite of the name 'indkeys' this field @@ -369,7 +369,6 @@ typedef struct _indxInfo Oid parentidx; /* if partitioned, parent index OID */ /* if there is an associated constraint object, its dumpId: */ DumpId indexconstraint; - int relpages; /* relpages of the underlying table */ } IndxInfo; typedef struct _indexAttachInfo @@ -383,6 +382,7 @@ typedef struct _statsExtInfo { DumpableObject dobj; char *rolname; /* name of owner, or empty string */ + int stattarget; /* statistics target */ } StatsExtInfo; typedef struct _ruleInfo @@ -634,10 +634,6 @@ typedef struct _extensionMemberId ExtensionInfo *ext; /* owning extension */ } ExtensionMemberId; -/* global decls */ -extern bool force_quotes; /* double-quotes for identifiers flag */ -extern bool g_verbose; /* verbose flag */ - /* placeholders for comment starting and ending delimiters */ extern char g_comment_start[10]; extern char g_comment_end[10]; @@ -674,9 +670,8 @@ extern ExtensionInfo *findOwningExtension(CatalogId catalogId); extern void parseOidArray(const char *str, Oid *array, int arraysize); extern void sortDumpableObjects(DumpableObject **objs, int numObjs, - DumpId preBoundaryId, DumpId postBoundaryId); + DumpId preBoundaryId, DumpId postBoundaryId); extern void sortDumpableObjectsByTypeName(DumpableObject **objs, int numObjs); -extern void sortDataAndIndexObjectsBySize(DumpableObject **objs, int numObjs); /* * version specific routines @@ -710,19 +705,19 @@ extern TSDictInfo *getTSDictionaries(Archive *fout, int *numTSDicts); extern TSTemplateInfo *getTSTemplates(Archive *fout, int *numTSTemplates); extern TSConfigInfo *getTSConfigurations(Archive *fout, int *numTSConfigs); extern FdwInfo *getForeignDataWrappers(Archive *fout, - int *numForeignDataWrappers); + int *numForeignDataWrappers); extern ForeignServerInfo *getForeignServers(Archive *fout, - int *numForeignServers); + int *numForeignServers); extern DefaultACLInfo *getDefaultACLs(Archive *fout, int *numDefaultACLs); extern void getExtensionMembership(Archive *fout, ExtensionInfo extinfo[], - int numExtensions); + int numExtensions); extern void processExtensionTables(Archive *fout, ExtensionInfo extinfo[], - int numExtensions); + int numExtensions); extern EventTriggerInfo *getEventTriggers(Archive *fout, int *numEventTriggers); extern void getPolicies(Archive *fout, TableInfo tblinfo[], int numTables); extern void getPublications(Archive *fout); extern void getPublicationTables(Archive *fout, TableInfo tblinfo[], - int numTables); + int numTables); extern void getSubscriptions(Archive *fout); #endif /* PG_DUMP_H */ diff --git a/src/bin/pg_dump/pg_dump_sort.c b/src/bin/pg_dump/pg_dump_sort.c index d2b0949d6b3..31fc06a2557 100644 --- a/src/bin/pg_dump/pg_dump_sort.c +++ b/src/bin/pg_dump/pg_dump_sort.c @@ -4,7 +4,7 @@ * Sort the items of a dump into a safe order for dumping * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,9 +21,6 @@ #include "catalog/pg_class_d.h" -/* translator: this is a module name */ -static const char *modulename = gettext_noop("sorter"); - /* * Sort priority for database object types. * Objects are sorted by type, and within a type by name. @@ -35,10 +32,6 @@ static const char *modulename = gettext_noop("sorter"); * pg_dump.c; that is, PRE_DATA objects must sort before DO_PRE_DATA_BOUNDARY, * POST_DATA objects must sort after DO_POST_DATA_BOUNDARY, and DATA objects * must sort between them. - * - * Note: sortDataAndIndexObjectsBySize wants to have all DO_TABLE_DATA and - * DO_INDEX objects in contiguous chunks, so do not reuse the values for those - * for other object types. */ static const int dbObjectTypePriority[] = { @@ -94,113 +87,23 @@ static DumpId postDataBoundId; static int DOTypeNameCompare(const void *p1, const void *p2); static bool TopoSort(DumpableObject **objs, - int numObjs, - DumpableObject **ordering, - int *nOrdering); + int numObjs, + DumpableObject **ordering, + int *nOrdering); static void addHeapElement(int val, int *heap, int heapLength); static int removeHeapElement(int *heap, int heapLength); static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs); -static int findLoop(DumpableObject *obj, - DumpId startPoint, - bool *processed, - DumpId *searchFailed, - DumpableObject **workspace, - int depth); +static int findLoop(DumpableObject *obj, + DumpId startPoint, + bool *processed, + DumpId *searchFailed, + DumpableObject **workspace, + int depth); static void repairDependencyLoop(DumpableObject **loop, - int nLoop); + int nLoop); static void describeDumpableObject(DumpableObject *obj, - char *buf, int bufsize); - -static int DOSizeCompare(const void *p1, const void *p2); - -static int -findFirstEqualType(DumpableObjectType type, DumpableObject **objs, int numObjs) -{ - int i; - - for (i = 0; i < numObjs; i++) - if (objs[i]->objType == type) - return i; - return -1; -} - -static int -findFirstDifferentType(DumpableObjectType type, DumpableObject **objs, int numObjs, int start) -{ - int i; - - for (i = start; i < numObjs; i++) - if (objs[i]->objType != type) - return i; - return numObjs - 1; -} - -/* - * When we do a parallel dump, we want to start with the largest items first. - * - * Say we have the objects in this order: - * ....DDDDD....III.... - * - * with D = Table data, I = Index, . = other object - * - * This sorting function now takes each of the D or I blocks and sorts them - * according to their size. - */ -void -sortDataAndIndexObjectsBySize(DumpableObject **objs, int numObjs) -{ - int startIdx, - endIdx; - void *startPtr; - - if (numObjs <= 1) - return; - - startIdx = findFirstEqualType(DO_TABLE_DATA, objs, numObjs); - if (startIdx >= 0) - { - endIdx = findFirstDifferentType(DO_TABLE_DATA, objs, numObjs, startIdx); - startPtr = objs + startIdx; - qsort(startPtr, endIdx - startIdx, sizeof(DumpableObject *), - DOSizeCompare); - } - - startIdx = findFirstEqualType(DO_INDEX, objs, numObjs); - if (startIdx >= 0) - { - endIdx = findFirstDifferentType(DO_INDEX, objs, numObjs, startIdx); - startPtr = objs + startIdx; - qsort(startPtr, endIdx - startIdx, sizeof(DumpableObject *), - DOSizeCompare); - } -} - -static int -DOSizeCompare(const void *p1, const void *p2) -{ - DumpableObject *obj1 = *(DumpableObject **) p1; - DumpableObject *obj2 = *(DumpableObject **) p2; - int obj1_size = 0; - int obj2_size = 0; - - if (obj1->objType == DO_TABLE_DATA) - obj1_size = ((TableDataInfo *) obj1)->tdtable->relpages; - if (obj1->objType == DO_INDEX) - obj1_size = ((IndxInfo *) obj1)->relpages; - - if (obj2->objType == DO_TABLE_DATA) - obj2_size = ((TableDataInfo *) obj2)->tdtable->relpages; - if (obj2->objType == DO_INDEX) - obj2_size = ((IndxInfo *) obj2)->relpages; - - /* we want to see the biggest item go first */ - if (obj1_size > obj2_size) - return -1; - if (obj2_size > obj1_size) - return 1; + char *buf, int bufsize); - return 0; -} /* * Sort the given objects into a type/name-based ordering @@ -223,7 +126,7 @@ DOTypeNameCompare(const void *p1, const void *p2) DumpableObject *obj2 = *(DumpableObject *const *) p2; int cmpval; - /* Sort by type */ + /* Sort by type's priority */ cmpval = dbObjectTypePriority[obj1->objType] - dbObjectTypePriority[obj2->objType]; @@ -231,17 +134,24 @@ DOTypeNameCompare(const void *p1, const void *p2) return cmpval; /* - * Sort by namespace. Note that all objects of the same type should - * either have or not have a namespace link, so we needn't be fancy about - * cases where one link is null and the other not. + * Sort by namespace. Typically, all objects of the same priority would + * either have or not have a namespace link, but there are exceptions. + * Sort NULL namespace after non-NULL in such cases. */ - if (obj1->namespace && obj2->namespace) + if (obj1->namespace) { - cmpval = strcmp(obj1->namespace->dobj.name, - obj2->namespace->dobj.name); - if (cmpval != 0) - return cmpval; + if (obj2->namespace) + { + cmpval = strcmp(obj1->namespace->dobj.name, + obj2->namespace->dobj.name); + if (cmpval != 0) + return cmpval; + } + else + return -1; } + else if (obj2->namespace) + return 1; /* Sort by name */ cmpval = strcmp(obj1->name, obj2->name); @@ -407,21 +317,20 @@ TopoSort(DumpableObject **objs, * We also make a map showing the input-order index of the item with * dumpId j. */ - beforeConstraints = (int *) pg_malloc((maxDumpId + 1) * sizeof(int)); - memset(beforeConstraints, 0, (maxDumpId + 1) * sizeof(int)); + beforeConstraints = (int *) pg_malloc0((maxDumpId + 1) * sizeof(int)); idMap = (int *) pg_malloc((maxDumpId + 1) * sizeof(int)); for (i = 0; i < numObjs; i++) { obj = objs[i]; j = obj->dumpId; if (j <= 0 || j > maxDumpId) - exit_horribly(modulename, "invalid dumpId %d\n", j); + fatal("invalid dumpId %d", j); idMap[j] = i; for (j = 0; j < obj->nDeps; j++) { k = obj->dependencies[j]; if (k <= 0 || k > maxDumpId) - exit_horribly(modulename, "invalid dependency %d\n", k); + fatal("invalid dependency %d", k); beforeConstraints[k]++; } } @@ -654,7 +563,7 @@ findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs) /* We'd better have fixed at least one loop */ if (!fixedloop) - exit_horribly(modulename, "could not identify dependency loop\n"); + fatal("could not identify dependency loop"); free(workspace); free(searchFailed); @@ -842,19 +751,26 @@ repairViewRuleMultiLoop(DumpableObject *viewobj, * * Note that the "next object" is not necessarily the matview itself; * it could be the matview's rowtype, for example. We may come through here - * several times while removing all the pre-data linkages. + * several times while removing all the pre-data linkages. In particular, + * if there are other matviews that depend on the one with the circularity + * problem, we'll come through here for each such matview and mark them all + * as postponed. (This works because all MVs have pre-data dependencies + * to begin with, so each of them will get visited.) */ static void -repairMatViewBoundaryMultiLoop(DumpableObject *matviewobj, - DumpableObject *boundaryobj, +repairMatViewBoundaryMultiLoop(DumpableObject *boundaryobj, DumpableObject *nextobj) { - TableInfo *matviewinfo = (TableInfo *) matviewobj; - /* remove boundary's dependency on object after it in loop */ removeObjectDependency(boundaryobj, nextobj->dumpId); - /* mark matview as postponed into post-data section */ - matviewinfo->postponed_def = true; + /* if that object is a matview, mark it as postponed into post-data */ + if (nextobj->objType == DO_TABLE) + { + TableInfo *nextinfo = (TableInfo *) nextobj; + + if (nextinfo->relkind == RELKIND_MATVIEW) + nextinfo->postponed_def = true; + } } /* @@ -1043,8 +959,7 @@ repairDependencyLoop(DumpableObject **loop, DumpableObject *nextobj; nextobj = (j < nLoop - 1) ? loop[j + 1] : loop[0]; - repairMatViewBoundaryMultiLoop(loop[i], loop[j], - nextobj); + repairMatViewBoundaryMultiLoop(loop[j], nextobj); return; } } @@ -1189,6 +1104,24 @@ repairDependencyLoop(DumpableObject **loop, } } + /* + * Loop of table with itself --- just ignore it. + * + * (Actually, what this arises from is a dependency of a table column on + * another column, which happens with generated columns; or a dependency + * of a table column on the whole table, which happens with partitioning. + * But we didn't pay attention to sub-object IDs while collecting the + * dependency data, so we can't see that here.) + */ + if (nLoop == 1) + { + if (loop[0]->objType == DO_TABLE) + { + removeObjectDependency(loop[0], loop[0]->dumpId); + return; + } + } + /* * If all the objects are TABLE_DATA items, what we must have is a * circular set of foreign key constraints (or a single self-referential @@ -1201,13 +1134,13 @@ repairDependencyLoop(DumpableObject **loop, } if (i >= nLoop) { - write_msg(NULL, ngettext("NOTICE: there are circular foreign-key constraints on this table:\n", - "NOTICE: there are circular foreign-key constraints among these tables:\n", - nLoop)); + pg_log_warning(ngettext("there are circular foreign-key constraints on this table:", + "there are circular foreign-key constraints among these tables:", + nLoop)); for (i = 0; i < nLoop; i++) - write_msg(NULL, " %s\n", loop[i]->name); - write_msg(NULL, "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.\n"); - write_msg(NULL, "Consider using a full dump instead of a --data-only dump to avoid this problem.\n"); + pg_log_generic(PG_LOG_INFO, " %s", loop[i]->name); + pg_log_generic(PG_LOG_INFO, "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints."); + pg_log_generic(PG_LOG_INFO, "Consider using a full dump instead of a --data-only dump to avoid this problem."); if (nLoop > 1) removeObjectDependency(loop[0], loop[1]->dumpId); else /* must be a self-dependency */ @@ -1219,13 +1152,13 @@ repairDependencyLoop(DumpableObject **loop, * If we can't find a principled way to break the loop, complain and break * it in an arbitrary fashion. */ - write_msg(modulename, "WARNING: could not resolve dependency loop among these items:\n"); + pg_log_warning("could not resolve dependency loop among these items:"); for (i = 0; i < nLoop; i++) { char buf[1024]; describeDumpableObject(loop[i], buf, sizeof(buf)); - write_msg(modulename, " %s\n", buf); + pg_log_generic(PG_LOG_INFO, " %s", buf); } if (nLoop > 1) diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c index 75e4a539bfb..0981efcf5d6 100644 --- a/src/bin/pg_dump/pg_dumpall.c +++ b/src/bin/pg_dump/pg_dumpall.c @@ -2,7 +2,7 @@ * * pg_dumpall.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * pg_dumpall forces all pg_dump output to be text, since it also outputs @@ -23,6 +23,7 @@ #include "dumputils.h" #include "pg_backup.h" #include "common/file_utils.h" +#include "common/logging.h" #include "fe_utils/connect.h" #include "fe_utils/string_utils.h" @@ -44,14 +45,16 @@ static void dumpDatabases(PGconn *conn); static void dumpTimestamp(const char *msg); static int runPgDump(const char *dbname, const char *create_opts); static void buildShSecLabels(PGconn *conn, - const char *catalog_name, Oid objectId, - const char *objtype, const char *objname, - PQExpBuffer buffer); + const char *catalog_name, Oid objectId, + const char *objtype, const char *objname, + PQExpBuffer buffer); static PGconn *connectDatabase(const char *dbname, const char *connstr, const char *pghost, const char *pgport, - const char *pguser, trivalue prompt_password, bool fail_on_error); + const char *pguser, trivalue prompt_password, bool fail_on_error); static char *constructConnStr(const char **keywords, const char **values); static PGresult *executeQuery(PGconn *conn, const char *query); static void executeCommand(PGconn *conn, const char *query); +static void expand_dbname_patterns(PGconn *conn, SimpleStringList *patterns, + SimpleStringList *names); static char pg_dump_bin[MAXPGPATH]; static const char *progname; @@ -78,6 +81,7 @@ static int no_unlogged_table_data = 0; static int no_role_passwords = 0; static int server_version; static int load_via_partition_root = 0; +static int on_conflict_do_nothing = 0; static char role_catalog[10]; #define PG_AUTHID "pg_authid" @@ -86,6 +90,9 @@ static char role_catalog[10]; static FILE *OPF; static char *filename = NULL; +static SimpleStringList database_exclude_patterns = {NULL, NULL}; +static SimpleStringList database_exclude_names = {NULL, NULL}; + #define exit_nicely(code) exit(code) int @@ -100,7 +107,6 @@ main(int argc, char *argv[]) {"host", required_argument, NULL, 'h'}, {"dbname", required_argument, NULL, 'd'}, {"database", required_argument, NULL, 'l'}, - {"oids", no_argument, NULL, 'o'}, {"no-owner", no_argument, NULL, 'O'}, {"port", required_argument, NULL, 'p'}, {"roles-only", no_argument, NULL, 'r'}, @@ -122,6 +128,8 @@ main(int argc, char *argv[]) {"column-inserts", no_argument, &column_inserts, 1}, {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-triggers", no_argument, &disable_triggers, 1}, + {"exclude-database", required_argument, NULL, 6}, + {"extra-float-digits", required_argument, NULL, 5}, {"if-exists", no_argument, &if_exists, 1}, {"inserts", no_argument, &inserts, 1}, {"lock-wait-timeout", required_argument, NULL, 2}, @@ -137,6 +145,8 @@ main(int argc, char *argv[]) {"no-subscriptions", no_argument, &no_subscriptions, 1}, {"no-sync", no_argument, NULL, 4}, {"no-unlogged-table-data", no_argument, &no_unlogged_table_data, 1}, + {"on-conflict-do-nothing", no_argument, &on_conflict_do_nothing, 1}, + {"rows-per-insert", required_argument, NULL, 7}, {NULL, 0, NULL, 0} }; @@ -159,8 +169,9 @@ main(int argc, char *argv[]) ret; int optindex; + pg_logging_init(argv[0]); + pg_logging_set_level(PG_LOG_WARNING); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump")); - progname = get_progname(argv[0]); if (argc > 1) @@ -186,24 +197,21 @@ main(int argc, char *argv[]) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) - fprintf(stderr, - _("The program \"pg_dump\" is needed by %s " - "but was not found in the\n" - "same directory as \"%s\".\n" - "Check your installation.\n"), - progname, full_path); + pg_log_error("The program \"pg_dump\" is needed by %s but was not found in the\n" + "same directory as \"%s\".\n" + "Check your installation.", + progname, full_path); else - fprintf(stderr, - _("The program \"pg_dump\" was found by \"%s\"\n" - "but was not the same version as %s.\n" - "Check your installation.\n"), - full_path, progname); + pg_log_error("The program \"pg_dump\" was found by \"%s\"\n" + "but was not the same version as %s.\n" + "Check your installation.", + full_path, progname); exit_nicely(1); } pgdumpopts = createPQExpBuffer(); - while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:oOp:rsS:tU:vwWx", long_options, &optindex)) != -1) + while ((c = getopt_long(argc, argv, "acd:E:f:gh:l:Op:rsS:tU:vwWx", long_options, &optindex)) != -1) { switch (c) { @@ -244,10 +252,6 @@ main(int argc, char *argv[]) pgdb = pg_strdup(optarg); break; - case 'o': - appendPQExpBufferStr(pgdumpopts, " -o"); - break; - case 'O': appendPQExpBufferStr(pgdumpopts, " -O"); break; @@ -279,6 +283,7 @@ main(int argc, char *argv[]) case 'v': verbose = true; + pg_logging_set_level(PG_LOG_INFO); appendPQExpBufferStr(pgdumpopts, " -v"); break; @@ -316,6 +321,20 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-sync"); break; + case 5: + appendPQExpBufferStr(pgdumpopts, " --extra-float-digits "); + appendShellString(pgdumpopts, optarg); + break; + + case 6: + simple_string_list_append(&database_exclude_patterns, optarg); + break; + + case 7: + appendPQExpBufferStr(pgdumpopts, " --rows-per-insert "); + appendShellString(pgdumpopts, optarg); + break; + default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -325,8 +344,17 @@ main(int argc, char *argv[]) /* Complain if any arguments remain */ if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), + progname); + exit_nicely(1); + } + + if (database_exclude_patterns.head != NULL && + (globals_only || roles_only || tablespaces_only)) + { + pg_log_error("option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only, or -t/--tablespaces-only"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -335,8 +363,7 @@ main(int argc, char *argv[]) /* Make sure the user hasn't specified a mix of globals-only options */ if (globals_only && roles_only) { - fprintf(stderr, _("%s: options -g/--globals-only and -r/--roles-only cannot be used together\n"), - progname); + pg_log_error("options -g/--globals-only and -r/--roles-only cannot be used together"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -344,8 +371,7 @@ main(int argc, char *argv[]) if (globals_only && tablespaces_only) { - fprintf(stderr, _("%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n"), - progname); + pg_log_error("options -g/--globals-only and -t/--tablespaces-only cannot be used together"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -353,15 +379,13 @@ main(int argc, char *argv[]) if (if_exists && !output_clean) { - fprintf(stderr, _("%s: option --if-exists requires option -c/--clean\n"), - progname); + pg_log_error("option --if-exists requires option -c/--clean"); exit_nicely(1); } if (roles_only && tablespaces_only) { - fprintf(stderr, _("%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n"), - progname); + pg_log_error("options -r/--roles-only and -t/--tablespaces-only cannot be used together"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -406,6 +430,8 @@ main(int argc, char *argv[]) appendPQExpBufferStr(pgdumpopts, " --no-subscriptions"); if (no_unlogged_table_data) appendPQExpBufferStr(pgdumpopts, " --no-unlogged-table-data"); + if (on_conflict_do_nothing) + appendPQExpBufferStr(pgdumpopts, " --on-conflict-do-nothing"); /* * If there was a database specified on the command line, use that, @@ -420,8 +446,7 @@ main(int argc, char *argv[]) if (!conn) { - fprintf(stderr, _("%s: could not connect to database \"%s\"\n"), - progname, pgdb); + pg_log_error("could not connect to database \"%s\"", pgdb); exit_nicely(1); } } @@ -435,15 +460,20 @@ main(int argc, char *argv[]) if (!conn) { - fprintf(stderr, _("%s: could not connect to databases \"postgres\" or \"template1\"\n" - "Please specify an alternative database.\n"), - progname); + pg_log_error("could not connect to databases \"postgres\" or \"template1\"\n" + "Please specify an alternative database."); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); } } + /* + * Get a list of database names that match the exclude patterns + */ + expand_dbname_patterns(conn, &database_exclude_patterns, + &database_exclude_names); + /* * Open the output file if required, otherwise use stdout */ @@ -452,8 +482,8 @@ main(int argc, char *argv[]) OPF = fopen(filename, PG_BINARY_W); if (!OPF) { - fprintf(stderr, _("%s: could not open the output file \"%s\": %s\n"), - progname, filename, strerror(errno)); + pg_log_error("could not open output file \"%s\": %m", + filename); exit_nicely(1); } } @@ -467,8 +497,8 @@ main(int argc, char *argv[]) { if (PQsetClientEncoding(conn, dumpencoding) < 0) { - fprintf(stderr, _("%s: invalid client encoding \"%s\" specified\n"), - progname, dumpencoding); + pg_log_error("invalid client encoding \"%s\" specified", + dumpencoding); exit_nicely(1); } } @@ -574,7 +604,7 @@ main(int argc, char *argv[]) /* sync the resulting file, errors are not fatal */ if (dosync) - (void) fsync_fname(filename, false, progname); + (void) fsync_fname(filename, false); } exit_nicely(0); @@ -599,7 +629,6 @@ help(void) printf(_(" -c, --clean clean (drop) databases before recreating\n")); printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n")); printf(_(" -g, --globals-only dump only global objects, no databases\n")); - printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -O, --no-owner skip restoration of object ownership\n")); printf(_(" -r, --roles-only dump only roles, no databases or tablespaces\n")); printf(_(" -s, --schema-only dump only the schema, no data\n")); @@ -610,8 +639,11 @@ help(void) printf(_(" --column-inserts dump data as INSERT commands with column names\n")); printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n")); printf(_(" --disable-triggers disable triggers during data-only restore\n")); + printf(_(" --exclude-database=PATTERN exclude databases whose name matches PATTERN\n")); + printf(_(" --extra-float-digits=NUM override default setting for extra_float_digits\n")); printf(_(" --if-exists use IF EXISTS when dropping objects\n")); printf(_(" --inserts dump data as INSERT commands, rather than COPY\n")); + printf(_(" --load-via-partition-root load partitions via the root table\n")); printf(_(" --no-comments do not dump comments\n")); printf(_(" --no-publications do not dump publications\n")); printf(_(" --no-role-passwords do not dump passwords for roles\n")); @@ -620,8 +652,9 @@ help(void) printf(_(" --no-sync do not wait for changes to be written safely to disk\n")); printf(_(" --no-tablespaces do not dump tablespace assignments\n")); printf(_(" --no-unlogged-table-data do not dump unlogged table data\n")); + printf(_(" --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n")); printf(_(" --quote-all-identifiers quote all identifiers, even if not key words\n")); - printf(_(" --load-via-partition-root load partitions via the root table\n")); + printf(_(" --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n")); printf(_(" --use-set-session-authorization\n" " use SET SESSION AUTHORIZATION commands instead of\n" " ALTER OWNER commands to set ownership\n")); @@ -638,7 +671,7 @@ help(void) printf(_("\nIf -f/--file is not used, then the SQL script will be written to the standard\n" "output.\n\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } @@ -801,7 +834,7 @@ dumpRoles(PGconn *conn) "false as rolcanlogin, " "-1 as rolconnlimit, " "null::text as rolpassword, " - "null::abstime as rolvaliduntil, " + "null::timestamptz as rolvaliduntil, " "false as rolreplication, " "false as rolbypassrls, " "null as rolcomment, " @@ -841,8 +874,8 @@ dumpRoles(PGconn *conn) if (strncmp(rolename, "pg_", 3) == 0) { - fprintf(stderr, _("%s: role name starting with \"pg_\" skipped (%s)\n"), - progname, rolename); + pg_log_warning("role name starting with \"pg_\" skipped (%s)", + rolename); continue; } @@ -1134,19 +1167,38 @@ dumpTablespaces(PGconn *conn) * * See buildACLQueries() and buildACLCommands(). * + * The order in which privileges are in the ACL string (the order they + * have been GRANT'd in, which the backend maintains) must be preserved to + * ensure that GRANTs WITH GRANT OPTION and subsequent GRANTs based on + * those are dumped in the correct order. + * * Note that we do not support initial privileges (pg_init_privs) on - * tablespaces. + * tablespaces, so this logic cannot make use of buildACLQueries(). */ if (server_version >= 90600) res = executeQuery(conn, "SELECT oid, spcname, " "pg_catalog.pg_get_userbyid(spcowner) AS spcowner, " "pg_catalog.pg_tablespace_location(oid), " - "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner))) AS acl " - "EXCEPT SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner))) as foo)" - "AS spcacl," - "(SELECT pg_catalog.array_agg(acl) FROM (SELECT pg_catalog.unnest(pg_catalog.acldefault('t',spcowner)) AS acl " - "EXCEPT SELECT pg_catalog.unnest(coalesce(spcacl,pg_catalog.acldefault('t',spcowner)))) as foo)" - "AS rspcacl," + "(SELECT array_agg(acl ORDER BY row_n) FROM " + " (SELECT acl, row_n FROM " + " unnest(coalesce(spcacl,acldefault('t',spcowner))) " + " WITH ORDINALITY AS perm(acl,row_n) " + " WHERE NOT EXISTS ( " + " SELECT 1 " + " FROM unnest(acldefault('t',spcowner)) " + " AS init(init_acl) " + " WHERE acl = init_acl)) AS spcacls) " + " AS spcacl, " + "(SELECT array_agg(acl ORDER BY row_n) FROM " + " (SELECT acl, row_n FROM " + " unnest(acldefault('t',spcowner)) " + " WITH ORDINALITY AS initp(acl,row_n) " + " WHERE NOT EXISTS ( " + " SELECT 1 " + " FROM unnest(coalesce(spcacl,acldefault('t',spcowner))) " + " AS permp(orig_acl) " + " WHERE acl = orig_acl)) AS rspcacls) " + " AS rspcacl, " "array_to_string(spcoptions, ', ')," "pg_catalog.shobj_description(oid, 'pg_tablespace') " "FROM pg_catalog.pg_tablespace " @@ -1223,8 +1275,8 @@ dumpTablespaces(PGconn *conn) spcacl, rspcacl, spcowner, "", server_version, buf)) { - fprintf(stderr, _("%s: could not parse ACL list (%s) for tablespace \"%s\"\n"), - progname, spcacl, spcname); + pg_log_error("could not parse ACL list (%s) for tablespace \"%s\"", + spcacl, spcname); PQfinish(conn); exit_nicely(1); } @@ -1307,6 +1359,7 @@ dumpUserConfig(PGconn *conn, const char *username) { PQExpBuffer buf = createPQExpBuffer(); int count = 1; + bool first = true; for (;;) { @@ -1328,6 +1381,14 @@ dumpUserConfig(PGconn *conn, const char *username) if (PQntuples(res) == 1 && !PQgetisnull(res, 0, 0)) { + /* comment at section start, only if needed */ + if (first) + { + fprintf(OPF, "--\n-- User Configurations\n--\n\n"); + first = false; + } + + fprintf(OPF, "--\n-- User Config \"%s\"\n--\n\n", username); resetPQExpBuffer(buf); makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0), "ROLE", username, NULL, NULL, @@ -1346,6 +1407,48 @@ dumpUserConfig(PGconn *conn, const char *username) destroyPQExpBuffer(buf); } +/* + * Find a list of database names that match the given patterns. + * See also expand_table_name_patterns() in pg_dump.c + */ +static void +expand_dbname_patterns(PGconn *conn, + SimpleStringList *patterns, + SimpleStringList *names) +{ + PQExpBuffer query; + PGresult *res; + + if (patterns->head == NULL) + return; /* nothing to do */ + + query = createPQExpBuffer(); + + /* + * The loop below runs multiple SELECTs, which might sometimes result in + * duplicate entries in the name list, but we don't care, since all we're + * going to do is test membership of the list. + */ + + for (SimpleStringListCell *cell = patterns->head; cell; cell = cell->next) + { + appendPQExpBufferStr(query, + "SELECT datname FROM pg_catalog.pg_database n\n"); + processSQLNamePattern(conn, query, cell->val, false, + false, NULL, "datname", NULL, NULL); + + res = executeQuery(conn, query->data); + for (int i = 0; i < PQntuples(res); i++) + { + simple_string_list_append(names, PQgetvalue(res, i, 0)); + } + + PQclear(res); + resetPQExpBuffer(query); + } + + destroyPQExpBuffer(query); +} /* * Dump contents of databases. @@ -1373,6 +1476,9 @@ dumpDatabases(PGconn *conn) "WHERE datallowconn " "ORDER BY (datname <> 'template1'), datname"); + if (PQntuples(res) > 0) + fprintf(OPF, "--\n-- Databases\n--\n\n"); + for (i = 0; i < PQntuples(res); i++) { char *dbname = PQgetvalue(res, i, 0); @@ -1383,8 +1489,16 @@ dumpDatabases(PGconn *conn) if (strcmp(dbname, "template0") == 0) continue; - if (verbose) - fprintf(stderr, _("%s: dumping database \"%s\"...\n"), progname, dbname); + /* Skip any explicitly excluded database */ + if (simple_string_list_member(&database_exclude_names, dbname)) + { + pg_log_info("excluding database \"%s\"", dbname); + continue; + } + + pg_log_info("dumping database \"%s\"", dbname); + + fprintf(OPF, "--\n-- Database \"%s\" dump\n--\n\n", dbname); /* * We assume that "template1" and "postgres" already exist in the @@ -1414,7 +1528,7 @@ dumpDatabases(PGconn *conn) ret = runPgDump(dbname, create_opts); if (ret != 0) { - fprintf(stderr, _("%s: pg_dump failed on database \"%s\", exiting\n"), progname, dbname); + pg_log_error("pg_dump failed on database \"%s\", exiting", dbname); exit_nicely(1); } @@ -1423,8 +1537,8 @@ dumpDatabases(PGconn *conn) OPF = fopen(filename, PG_BINARY_A); if (!OPF) { - fprintf(stderr, _("%s: could not re-open the output file \"%s\": %s\n"), - progname, filename, strerror(errno)); + pg_log_error("could not re-open the output file \"%s\": %m", + filename); exit_nicely(1); } } @@ -1467,8 +1581,7 @@ runPgDump(const char *dbname, const char *create_opts) appendShellString(cmd, connstrbuf->data); - if (verbose) - fprintf(stderr, _("%s: running \"%s\"\n"), progname, cmd->data); + pg_log_info("running \"%s\"", cmd->data); fflush(stdout); fflush(stderr); @@ -1568,7 +1681,7 @@ connectDatabase(const char *dbname, const char *connection_string, conn_opts = PQconninfoParse(connection_string, &err_msg); if (conn_opts == NULL) { - fprintf(stderr, "%s: %s", progname, err_msg); + pg_log_error("%s", err_msg); exit_nicely(1); } @@ -1638,8 +1751,7 @@ connectDatabase(const char *dbname, const char *connection_string, if (!conn) { - fprintf(stderr, _("%s: could not connect to database \"%s\"\n"), - progname, dbname); + pg_log_error("could not connect to database \"%s\"", dbname); exit_nicely(1); } @@ -1660,9 +1772,8 @@ connectDatabase(const char *dbname, const char *connection_string, { if (fail_on_error) { - fprintf(stderr, - _("%s: could not connect to database \"%s\": %s\n"), - progname, dbname, PQerrorMessage(conn)); + pg_log_error("could not connect to database \"%s\": %s", + dbname, PQerrorMessage(conn)); exit_nicely(1); } else @@ -1691,14 +1802,14 @@ connectDatabase(const char *dbname, const char *connection_string, remoteversion_str = PQparameterStatus(conn, "server_version"); if (!remoteversion_str) { - fprintf(stderr, _("%s: could not get server version\n"), progname); + pg_log_error("could not get server version"); exit_nicely(1); } server_version = PQserverVersion(conn); if (server_version == 0) { - fprintf(stderr, _("%s: could not parse server version \"%s\"\n"), - progname, remoteversion_str); + pg_log_error("could not parse server version \"%s\"", + remoteversion_str); exit_nicely(1); } @@ -1712,9 +1823,9 @@ connectDatabase(const char *dbname, const char *connection_string, && (server_version < 80000 || (server_version / 100) > (my_version / 100))) { - fprintf(stderr, _("server version: %s; %s version: %s\n"), - remoteversion_str, progname, PG_VERSION); - fprintf(stderr, _("aborting because of server version mismatch\n")); + pg_log_error("server version: %s; %s version: %s", + remoteversion_str, progname, PG_VERSION); + pg_log_error("aborting because of server version mismatch"); exit_nicely(1); } @@ -1769,17 +1880,14 @@ executeQuery(PGconn *conn, const char *query) { PGresult *res; - if (verbose) - fprintf(stderr, _("%s: executing %s\n"), progname, query); + pg_log_info("executing %s", query); res = PQexec(conn, query); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: query failed: %s"), - progname, PQerrorMessage(conn)); - fprintf(stderr, _("%s: query was: %s\n"), - progname, query); + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_error("query was: %s", query); PQfinish(conn); exit_nicely(1); } @@ -1795,17 +1903,14 @@ executeCommand(PGconn *conn, const char *query) { PGresult *res; - if (verbose) - fprintf(stderr, _("%s: executing %s\n"), progname, query); + pg_log_info("executing %s", query); res = PQexec(conn, query); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: query failed: %s"), - progname, PQerrorMessage(conn)); - fprintf(stderr, _("%s: query was: %s\n"), - progname, query); + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_error("query was: %s", query); PQfinish(conn); exit_nicely(1); } diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index edc14f176fa..40a6b3745cb 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -54,8 +54,6 @@ static void usage(const char *progname); -typedef struct option optType; - int main(int argc, char **argv) { @@ -128,6 +126,8 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; + pg_logging_init(argv[0]); + pg_logging_set_level(PG_LOG_WARNING); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump")); init_parallel_dump_utils(); @@ -247,6 +247,7 @@ main(int argc, char **argv) case 'v': /* verbose */ opts->verbose = 1; + pg_logging_set_level(PG_LOG_INFO); break; case 'w': @@ -296,20 +297,26 @@ main(int argc, char **argv) /* Complain if any arguments remain */ if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); } + /* Complain if neither -f nor -d was specified (except if dumping TOC) */ + if (!opts->dbname && !opts->filename && !opts->tocSummary) + { + pg_log_error("one of -d/--dbname and -f/--file must be specified"); + exit_nicely(1); + } + /* Should get at most one of -d and -f, else user is confused */ if (opts->dbname) { if (opts->filename) { - fprintf(stderr, _("%s: options -d/--dbname and -f/--file cannot be used together\n"), - progname); + pg_log_error("options -d/--dbname and -f/--file cannot be used together"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit_nicely(1); @@ -319,21 +326,29 @@ main(int argc, char **argv) if (opts->dataOnly && opts->schemaOnly) { - fprintf(stderr, _("%s: options -s/--schema-only and -a/--data-only cannot be used together\n"), - progname); + pg_log_error("options -s/--schema-only and -a/--data-only cannot be used together"); exit_nicely(1); } if (opts->dataOnly && opts->dropSchema) { - fprintf(stderr, _("%s: options -c/--clean and -a/--data-only cannot be used together\n"), - progname); + pg_log_error("options -c/--clean and -a/--data-only cannot be used together"); + exit_nicely(1); + } + + /* + * -C is not compatible with -1, because we can't create a database inside + * a transaction block. + */ + if (opts->createDB && opts->single_txn) + { + pg_log_error("options -C/--create and -1/--single-transaction cannot be used together"); exit_nicely(1); } if (numWorkers <= 0) { - fprintf(stderr, _("%s: invalid number of parallel jobs\n"), progname); + pg_log_error("invalid number of parallel jobs"); exit(1); } @@ -341,8 +356,8 @@ main(int argc, char **argv) #ifdef WIN32 if (numWorkers > MAXIMUM_WAIT_OBJECTS) { - fprintf(stderr, _("%s: maximum number of parallel jobs is %d\n"), - progname, MAXIMUM_WAIT_OBJECTS); + pg_log_error("maximum number of parallel jobs is %d", + MAXIMUM_WAIT_OBJECTS); exit(1); } #endif @@ -350,8 +365,7 @@ main(int argc, char **argv) /* Can't do single-txn mode with multiple connections */ if (opts->single_txn && numWorkers > 1) { - fprintf(stderr, _("%s: cannot specify both --single-transaction and multiple jobs\n"), - progname); + pg_log_error("cannot specify both --single-transaction and multiple jobs"); exit_nicely(1); } @@ -367,8 +381,7 @@ main(int argc, char **argv) if (if_exists && !opts->dropSchema) { - fprintf(stderr, _("%s: option --if-exists requires option -c/--clean\n"), - progname); + pg_log_error("option --if-exists requires option -c/--clean"); exit_nicely(1); } opts->if_exists = if_exists; @@ -394,8 +407,8 @@ main(int argc, char **argv) break; default: - write_msg(NULL, "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n", - opts->formatName); + pg_log_error("unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"", + opts->formatName); exit_nicely(1); } } @@ -434,8 +447,7 @@ main(int argc, char **argv) /* done, print a summary of ignored errors */ if (AH->n_errors) - fprintf(stderr, _("WARNING: errors ignored on restore: %d\n"), - AH->n_errors); + pg_log_warning("errors ignored on restore: %d", AH->n_errors); /* AH may be freed in CloseArchive? */ exit_code = AH->n_errors ? 1 : 0; @@ -454,7 +466,7 @@ usage(const char *progname) printf(_("\nGeneral options:\n")); printf(_(" -d, --dbname=NAME connect to database name\n")); - printf(_(" -f, --file=FILENAME output file name\n")); + printf(_(" -f, --file=FILENAME output file name (- for stdout)\n")); printf(_(" -F, --format=c|d|t backup file format (should be automatic)\n")); printf(_(" -l, --list print summarized TOC of the archive\n")); printf(_(" -v, --verbose verbose mode\n")); @@ -483,9 +495,9 @@ usage(const char *progname) printf(_(" --disable-triggers disable triggers during data-only restore\n")); printf(_(" --enable-row-security enable row security\n")); printf(_(" --if-exists use IF EXISTS when dropping objects\n")); + printf(_(" --no-comments do not restore comments\n")); printf(_(" --no-data-for-failed-tables do not restore data of tables that could not be\n" " created\n")); - printf(_(" --no-comments do not dump comments\n")); printf(_(" --no-publications do not restore publications\n")); printf(_(" --no-security-labels do not restore security labels\n")); printf(_(" --no-subscriptions do not restore subscriptions\n")); @@ -506,8 +518,8 @@ usage(const char *progname) printf(_(" --role=ROLENAME do SET ROLE before restore\n")); printf(_("\n" - "The options -I, -n, -P, -t, -T, and --section can be combined and specified\n" + "The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" "multiple times to select multiple objects.\n")); printf(_("\nIf no input file name is supplied, then standard input is used.\n\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } diff --git a/src/bin/pg_dump/po/de.po b/src/bin/pg_dump/po/de.po index d3a2ff27baa..6d6afecd7e4 100644 --- a/src/bin/pg_dump/po/de.po +++ b/src/bin/pg_dump/po/de.po @@ -1,56 +1,75 @@ # German message translation file for pg_dump and friends -# Peter Eisentraut , 2001 - 2017. +# Peter Eisentraut , 2001 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-03 03:15+0000\n" -"PO-Revision-Date: 2017-08-03 08:05-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-23 02:17+0000\n" +"PO-Revision-Date: 2019-05-26 23:58+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %s" +msgid "fatal: " +msgstr "Fatal: " -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ungültige Programmdatei »%s«" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "konnte Programmdatei »%s« nicht lesen" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "konnte kein »%s« zum Ausführen finden" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "konnte nicht in Verzeichnis »%s« wechseln: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "konnte symbolische Verknüpfung »%s« nicht lesen" +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose fehlgeschlagen: %s" +msgid "pclose failed: %m" +msgstr "pclose fehlgeschlagen: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "Speicher aufgebraucht" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -78,1352 +97,1228 @@ msgstr "Befehl nicht gefunden" msgid "child process exited with exit code %d" msgstr "Kindprozess hat mit Code %d beendet" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "Kindprozess wurde durch Ausnahme 0x%X beendet" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "Kindprozess wurde von Signal %s beendet" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "Kindprozess wurde von Signal %d beendet" +msgid "child process was terminated by signal %d: %s" +msgstr "Kindprozess wurde von Signal %d beendet: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "Kindprozess hat mit unbekanntem Status %d beendet" -#: common.c:121 +#: common.c:123 #, c-format -msgid "reading extensions\n" -msgstr "lese Erweiterungen\n" +msgid "reading extensions" +msgstr "lese Erweiterungen" -#: common.c:126 +#: common.c:127 #, c-format -msgid "identifying extension members\n" -msgstr "identifiziere Erweiterungselemente\n" +msgid "identifying extension members" +msgstr "identifiziere Erweiterungselemente" #: common.c:130 #, c-format -msgid "reading schemas\n" -msgstr "lese Schemas\n" +msgid "reading schemas" +msgstr "lese Schemas" -#: common.c:141 +#: common.c:140 #, c-format -msgid "reading user-defined tables\n" -msgstr "lese benutzerdefinierte Tabellen\n" +msgid "reading user-defined tables" +msgstr "lese benutzerdefinierte Tabellen" -#: common.c:149 +#: common.c:147 #, c-format -msgid "reading user-defined functions\n" -msgstr "lese benutzerdefinierte Funktionen\n" +msgid "reading user-defined functions" +msgstr "lese benutzerdefinierte Funktionen" -#: common.c:155 +#: common.c:152 #, c-format -msgid "reading user-defined types\n" -msgstr "lese benutzerdefinierte Typen\n" +msgid "reading user-defined types" +msgstr "lese benutzerdefinierte Typen" -#: common.c:161 +#: common.c:157 #, c-format -msgid "reading procedural languages\n" -msgstr "lese prozedurale Sprachen\n" +msgid "reading procedural languages" +msgstr "lese prozedurale Sprachen" -#: common.c:165 +#: common.c:160 #, c-format -msgid "reading user-defined aggregate functions\n" -msgstr "lese benutzerdefinierte Aggregatfunktionen\n" +msgid "reading user-defined aggregate functions" +msgstr "lese benutzerdefinierte Aggregatfunktionen" -#: common.c:169 +#: common.c:163 #, c-format -msgid "reading user-defined operators\n" -msgstr "lese benutzerdefinierte Operatoren\n" +msgid "reading user-defined operators" +msgstr "lese benutzerdefinierte Operatoren" -#: common.c:174 +#: common.c:167 #, c-format -msgid "reading user-defined access methods\n" -msgstr "lese benutzerdefinierte Zugriffsmethoden\n" +msgid "reading user-defined access methods" +msgstr "lese benutzerdefinierte Zugriffsmethoden" -#: common.c:178 +#: common.c:170 #, c-format -msgid "reading user-defined operator classes\n" -msgstr "lese benutzerdefinierte Operatorklassen\n" +msgid "reading user-defined operator classes" +msgstr "lese benutzerdefinierte Operatorklassen" -#: common.c:182 +#: common.c:173 #, c-format -msgid "reading user-defined operator families\n" -msgstr "lese benutzerdefinierte Operatorfamilien\n" +msgid "reading user-defined operator families" +msgstr "lese benutzerdefinierte Operatorfamilien" -#: common.c:186 +#: common.c:176 #, c-format -msgid "reading user-defined text search parsers\n" -msgstr "lese benutzerdefinierte Textsuche-Parser\n" +msgid "reading user-defined text search parsers" +msgstr "lese benutzerdefinierte Textsuche-Parser" -#: common.c:190 +#: common.c:179 #, c-format -msgid "reading user-defined text search templates\n" -msgstr "lese benutzerdefinierte Textsuche-Templates\n" +msgid "reading user-defined text search templates" +msgstr "lese benutzerdefinierte Textsuche-Templates" -#: common.c:194 +#: common.c:182 #, c-format -msgid "reading user-defined text search dictionaries\n" -msgstr "lese benutzerdefinierte Textsuchewörterbücher\n" +msgid "reading user-defined text search dictionaries" +msgstr "lese benutzerdefinierte Textsuchewörterbücher" -#: common.c:198 +#: common.c:185 #, c-format -msgid "reading user-defined text search configurations\n" -msgstr "lese benutzerdefinierte Textsuchekonfigurationen\n" +msgid "reading user-defined text search configurations" +msgstr "lese benutzerdefinierte Textsuchekonfigurationen" -#: common.c:202 +#: common.c:188 #, c-format -msgid "reading user-defined foreign-data wrappers\n" -msgstr "lese benutzerdefinierte Fremddaten-Wrapper\n" +msgid "reading user-defined foreign-data wrappers" +msgstr "lese benutzerdefinierte Fremddaten-Wrapper" -#: common.c:206 +#: common.c:191 #, c-format -msgid "reading user-defined foreign servers\n" -msgstr "lese benutzerdefinierte Fremdserver\n" +msgid "reading user-defined foreign servers" +msgstr "lese benutzerdefinierte Fremdserver" -#: common.c:210 +#: common.c:194 #, c-format -msgid "reading default privileges\n" -msgstr "lese Vorgabeprivilegien\n" +msgid "reading default privileges" +msgstr "lese Vorgabeprivilegien" -#: common.c:214 +#: common.c:197 #, c-format -msgid "reading user-defined collations\n" -msgstr "lese benutzerdefinierte Sortierfolgen\n" +msgid "reading user-defined collations" +msgstr "lese benutzerdefinierte Sortierfolgen" -#: common.c:219 +#: common.c:201 #, c-format -msgid "reading user-defined conversions\n" -msgstr "lese benutzerdefinierte Konversionen\n" +msgid "reading user-defined conversions" +msgstr "lese benutzerdefinierte Konversionen" -#: common.c:223 +#: common.c:204 #, c-format -msgid "reading type casts\n" -msgstr "lese Typumwandlungen\n" +msgid "reading type casts" +msgstr "lese Typumwandlungen" -#: common.c:227 +#: common.c:207 #, c-format -msgid "reading transforms\n" -msgstr "lese Transformationen\n" +msgid "reading transforms" +msgstr "lese Transformationen" -#: common.c:231 +#: common.c:210 #, c-format -msgid "reading table inheritance information\n" -msgstr "lese Tabellenvererbungsinformationen\n" +msgid "reading table inheritance information" +msgstr "lese Tabellenvererbungsinformationen" -#: common.c:235 +#: common.c:213 #, c-format -msgid "reading event triggers\n" -msgstr "lese Ereignistrigger\n" +msgid "reading event triggers" +msgstr "lese Ereignistrigger" -#: common.c:240 +#: common.c:217 #, c-format -msgid "finding extension tables\n" -msgstr "finde Erweiterungstabellen\n" +msgid "finding extension tables" +msgstr "finde Erweiterungstabellen" -#: common.c:245 +#: common.c:221 #, c-format -msgid "finding inheritance relationships\n" -msgstr "lese Vererbungsbeziehungen\n" +msgid "finding inheritance relationships" +msgstr "fine Vererbungsbeziehungen" -#: common.c:249 +#: common.c:224 #, c-format -msgid "reading column info for interesting tables\n" -msgstr "lese Spalteninfo für interessante Tabellen\n" +msgid "reading column info for interesting tables" +msgstr "lese Spalteninfo für interessante Tabellen" -#: common.c:253 +#: common.c:227 #, c-format -msgid "flagging inherited columns in subtables\n" -msgstr "markiere vererbte Spalten in abgeleiteten Tabellen\n" +msgid "flagging inherited columns in subtables" +msgstr "markiere vererbte Spalten in abgeleiteten Tabellen" -#: common.c:257 +#: common.c:230 #, c-format -msgid "reading indexes\n" -msgstr "lese Indexe\n" +msgid "reading indexes" +msgstr "lese Indexe" -#: common.c:261 +#: common.c:233 #, c-format -msgid "reading extended statistics\n" -msgstr "lese erweiterte Statistiken\n" +msgid "flagging indexes in partitioned tables" +msgstr "markiere Indexe in partitionierten Tabellen" -#: common.c:265 +#: common.c:236 #, c-format -msgid "reading constraints\n" -msgstr "lese Constraints\n" +msgid "reading extended statistics" +msgstr "lese erweiterte Statistiken" -#: common.c:269 +#: common.c:239 #, c-format -msgid "reading triggers\n" -msgstr "lese Trigger\n" +msgid "reading constraints" +msgstr "lese Constraints" -#: common.c:273 +#: common.c:242 #, c-format -msgid "reading rewrite rules\n" -msgstr "lese Umschreiberegeln\n" +msgid "reading triggers" +msgstr "lese Trigger" -#: common.c:277 +#: common.c:245 #, c-format -msgid "reading policies\n" -msgstr "lese Policies\n" +msgid "reading rewrite rules" +msgstr "lese Umschreiberegeln" -#: common.c:281 +#: common.c:248 #, c-format -msgid "reading publications\n" -msgstr "lese Publikationen\n" +msgid "reading policies" +msgstr "lese Policies" -#: common.c:285 +#: common.c:251 #, c-format -msgid "reading publication membership\n" -msgstr "lese Publikationsmitgliedschaft\n" +msgid "reading publications" +msgstr "lese Publikationen" -#: common.c:289 +#: common.c:254 #, c-format -msgid "reading subscriptions\n" -msgstr "lese Subskriptionen\n" +msgid "reading publication membership" +msgstr "lese Publikationsmitgliedschaft" -#: common.c:924 +#: common.c:257 #, c-format -msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" -msgstr "Sanity-Check fehlgeschlagen, Eltern-OID %u von Tabelle »%s« (OID %u) nicht gefunden\n" +msgid "reading subscriptions" +msgstr "lese Subskriptionen" -#: common.c:966 +#: common.c:1023 #, c-format -msgid "could not parse numeric array \"%s\": too many numbers\n" -msgstr "konnte numerisches Array »%s« nicht parsen: zu viele Zahlen\n" +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "Sanity-Check fehlgeschlagen, Eltern-OID %u von Tabelle »%s« (OID %u) nicht gefunden" -#: common.c:981 +#: common.c:1065 #, c-format -msgid "could not parse numeric array \"%s\": invalid character in number\n" -msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl\n" +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "konnte numerisches Array »%s« nicht parsen: zu viele Zahlen" -#. translator: this is a module name -#: compress_io.c:78 -msgid "compress_io" -msgstr "compress_io" - -#: compress_io.c:114 +#: common.c:1080 #, c-format -msgid "invalid compression code: %d\n" -msgstr "ungültiger Komprimierungscode: %d\n" +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "konnte numerisches Array »%s« nicht parsen: ungültiges Zeichen in Zahl" -#: compress_io.c:138 compress_io.c:174 compress_io.c:192 compress_io.c:519 -#: compress_io.c:562 +#: compress_io.c:111 #, c-format -msgid "not built with zlib support\n" -msgstr "nicht mit zlib-Unterstützung gebaut\n" +msgid "invalid compression code: %d" +msgstr "ungültiger Komprimierungscode: %d" -#: compress_io.c:242 compress_io.c:344 +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:508 +#: compress_io.c:551 #, c-format -msgid "could not initialize compression library: %s\n" -msgstr "konnte Komprimierungsbibliothek nicht initialisieren: %s\n" +msgid "not built with zlib support" +msgstr "nicht mit zlib-Unterstützung gebaut" -#: compress_io.c:263 +#: compress_io.c:237 compress_io.c:336 #, c-format -msgid "could not close compression stream: %s\n" -msgstr "konnte Komprimierungsstrom nicht schließen: %s\n" +msgid "could not initialize compression library: %s" +msgstr "konnte Komprimierungsbibliothek nicht initialisieren: %s" -#: compress_io.c:281 +#: compress_io.c:257 #, c-format -msgid "could not compress data: %s\n" -msgstr "konnte Daten nicht komprimieren: %s\n" +msgid "could not close compression stream: %s" +msgstr "konnte Komprimierungsstrom nicht schließen: %s" -#: compress_io.c:361 compress_io.c:377 +#: compress_io.c:274 #, c-format -msgid "could not uncompress data: %s\n" -msgstr "konnte Daten nicht dekomprimieren: %s\n" +msgid "could not compress data: %s" +msgstr "konnte Daten nicht komprimieren: %s" -#: compress_io.c:385 +#: compress_io.c:352 compress_io.c:367 #, c-format -msgid "could not close compression library: %s\n" -msgstr "konnte Komprimierungsbibliothek nicht schließen: %s\n" +msgid "could not uncompress data: %s" +msgstr "konnte Daten nicht dekomprimieren: %s" -#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 -#: pg_backup_tar.c:563 +#: compress_io.c:374 #, c-format -msgid "could not read from input file: %s\n" -msgstr "konnte nicht aus Eingabedatei lesen: %s\n" +msgid "could not close compression library: %s" +msgstr "konnte Komprimierungsbibliothek nicht schließen: %s" -#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 -#: pg_backup_tar.c:801 pg_backup_tar.c:825 +#: compress_io.c:588 compress_io.c:625 pg_backup_tar.c:555 pg_backup_tar.c:558 #, c-format -msgid "could not read from input file: end of file\n" -msgstr "konnte nicht aus Eingabedatei lesen: Dateiende\n" +msgid "could not read from input file: %s" +msgstr "konnte nicht aus Eingabedatei lesen: %s" -#: parallel.c:198 -msgid "parallel archiver" -msgstr "paralleler Archivierer" +#: compress_io.c:627 pg_backup_custom.c:578 pg_backup_directory.c:539 +#: pg_backup_tar.c:795 pg_backup_tar.c:818 +#, c-format +msgid "could not read from input file: end of file" +msgstr "konnte nicht aus Eingabedatei lesen: Dateiende" -#: parallel.c:265 +#: parallel.c:263 #, c-format -msgid "%s: WSAStartup failed: %d\n" -msgstr "%s: WSAStartup fehlgeschlagen: %d\n" +msgid "WSAStartup failed: %d" +msgstr "WSAStartup fehlgeschlagen: %d" -#: parallel.c:971 +#: parallel.c:968 #, c-format -msgid "could not create communication channels: %s\n" -msgstr "konnte Kommunikationskanäle nicht erzeugen: %s\n" +msgid "could not create communication channels: %m" +msgstr "konnte Kommunikationskanäle nicht erzeugen: %m" -#: parallel.c:1036 +#: parallel.c:1031 #, c-format -msgid "could not create worker process: %s\n" -msgstr "konnte Arbeitsprozess nicht erzeugen: %s\n" +msgid "could not create worker process: %m" +msgstr "konnte Arbeitsprozess nicht erzeugen: %m" -#: parallel.c:1167 +#: parallel.c:1160 #, c-format -msgid "unrecognized command received from master: \"%s\"\n" -msgstr "unbekannter Befehl vom Master empfangen: »%s«\n" +msgid "unrecognized command received from master: \"%s\"" +msgstr "unbekannter Befehl vom Master empfangen: »%s«" -#: parallel.c:1211 parallel.c:1451 +#: parallel.c:1203 parallel.c:1441 #, c-format -msgid "invalid message received from worker: \"%s\"\n" -msgstr "ungültige Nachricht vom Arbeitsprozess empfangen: »%s«\n" +msgid "invalid message received from worker: \"%s\"" +msgstr "ungültige Nachricht vom Arbeitsprozess empfangen: »%s«" -#: parallel.c:1344 +#: parallel.c:1335 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" -"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table.\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." msgstr "" "konnte Sperre für Relation »%s« nicht setzen\n" -"Das bedeutet meistens, dass jemand eine ACCESS-EXCLUSIVE-Sperre auf die Tabelle gesetzt hat, nachdem der pg-dump-Elternprozess die anfängliche ACCESS-SHARE-Sperre gesetzt hatte.\n" +"Das bedeutet meistens, dass jemand eine ACCESS-EXCLUSIVE-Sperre auf die Tabelle gesetzt hat, nachdem der pg-dump-Elternprozess die anfängliche ACCESS-SHARE-Sperre gesetzt hatte." -#: parallel.c:1433 +#: parallel.c:1424 #, c-format -msgid "a worker process died unexpectedly\n" -msgstr "ein Arbeitsprozess endete unerwartet\n" +msgid "a worker process died unexpectedly" +msgstr "ein Arbeitsprozess endete unerwartet" -#: parallel.c:1557 parallel.c:1675 +#: parallel.c:1546 parallel.c:1662 #, c-format -msgid "could not write to the communication channel: %s\n" -msgstr "konnte nicht in den Kommunikationskanal schreiben: %s\n" +msgid "could not write to the communication channel: %m" +msgstr "konnte nicht in den Kommunikationskanal schreiben: %m" -#: parallel.c:1635 +#: parallel.c:1623 #, c-format -msgid "select() failed: %s\n" -msgstr "select() fehlgeschlagen: %s\n" +msgid "select() failed: %m" +msgstr "select() fehlgeschlagen: %m" -#: parallel.c:1760 +#: parallel.c:1746 #, c-format -msgid "pgpipe: could not create socket: error code %d\n" -msgstr "pgpipe: konnte Socket nicht erzeugen: Fehlercode %d\n" +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: konnte Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1771 -#, c-format -msgid "pgpipe: could not bind: error code %d\n" -msgstr "pgpipe: konnte nicht binden: Fehlercode %d\n" - -#: parallel.c:1778 +#: parallel.c:1757 #, c-format -msgid "pgpipe: could not listen: error code %d\n" -msgstr "pgpipe: konnte nicht auf Socket hören: Fehlercode %d\n" +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: konnte nicht binden: Fehlercode %d" -#: parallel.c:1785 +#: parallel.c:1764 #, c-format -msgid "pgpipe: getsockname() failed: error code %d\n" -msgstr "pgpipe: getsockname() fehlgeschlagen: Fehlercode %d\n" +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: konnte nicht auf Socket hören: Fehlercode %d" -#: parallel.c:1796 +#: parallel.c:1771 #, c-format -msgid "pgpipe: could not create second socket: error code %d\n" -msgstr "pgpipe: konnte zweites Socket nicht erzeugen: Fehlercode %d\n" +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() fehlgeschlagen: Fehlercode %d" -#: parallel.c:1805 +#: parallel.c:1782 #, c-format -msgid "pgpipe: could not connect socket: error code %d\n" -msgstr "pgpipe: konnte Socket nicht verbinden: Fehlercode %d\n" +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: konnte zweites Socket nicht erzeugen: Fehlercode %d" -#: parallel.c:1814 +#: parallel.c:1791 #, c-format -msgid "pgpipe: could not accept connection: error code %d\n" -msgstr "pgpipe: konnte Verbindung nicht annehmen: Fehlercode %d\n" - -#. translator: this is a module name -#: pg_backup_archiver.c:53 -msgid "archiver" -msgstr "Archivierer" +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: konnte Socket nicht verbinden: Fehlercode %d" -#: pg_backup_archiver.c:243 pg_backup_archiver.c:1573 +#: parallel.c:1800 #, c-format -msgid "could not close output file: %s\n" -msgstr "konnte Ausgabedatei nicht schließen: %s\n" +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: konnte Verbindung nicht annehmen: Fehlercode %d" -#: pg_backup_archiver.c:289 pg_backup_archiver.c:294 +#: pg_backup_archiver.c:272 pg_backup_archiver.c:1595 #, c-format -msgid "WARNING: archive items not in correct section order\n" -msgstr "WARNUNG: Archivelemente nicht in richtiger Abschnittsreihenfolge\n" +msgid "could not close output file: %m" +msgstr "konnte Ausgabedatei nicht schließen: %m" -#: pg_backup_archiver.c:300 +#: pg_backup_archiver.c:316 pg_backup_archiver.c:320 #, c-format -msgid "unexpected section code %d\n" -msgstr "unerwarteter Abschnittscode %d\n" +msgid "archive items not in correct section order" +msgstr "Archivelemente nicht in richtiger Abschnittsreihenfolge" -#: pg_backup_archiver.c:336 +#: pg_backup_archiver.c:326 #, c-format -msgid "-C and -1 are incompatible options\n" -msgstr "-C und -1 sind inkompatible Optionen\n" +msgid "unexpected section code %d" +msgstr "unerwarteter Abschnittscode %d" -#: pg_backup_archiver.c:346 +#: pg_backup_archiver.c:363 #, c-format -msgid "parallel restore is not supported with this archive file format\n" -msgstr "parallele Wiederherstellung wird von diesem Archivdateiformat nicht unterstützt\n" +msgid "parallel restore is not supported with this archive file format" +msgstr "parallele Wiederherstellung wird von diesem Archivdateiformat nicht unterstützt" -#: pg_backup_archiver.c:350 +#: pg_backup_archiver.c:367 #, c-format -msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" -msgstr "parallele Wiederherstellung wird mit Archiven, die mit pg_dump vor 8.0 erstellt worden sind, nicht unterstützt\n" - -#: pg_backup_archiver.c:368 -#, c-format -msgid "cannot restore from compressed archive (compression not supported in this installation)\n" -msgstr "kann komprimiertes Archiv nicht wiederherstellen (Komprimierung in dieser Installation nicht unterstützt)\n" +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "parallele Wiederherstellung wird mit Archiven, die mit pg_dump vor 8.0 erstellt worden sind, nicht unterstützt" #: pg_backup_archiver.c:385 #, c-format -msgid "connecting to database for restore\n" -msgstr "verbinde mit der Datenbank zur Wiederherstellung\n" - -#: pg_backup_archiver.c:387 -#, c-format -msgid "direct database connections are not supported in pre-1.3 archives\n" -msgstr "direkte Datenbankverbindungen sind in Archiven vor Version 1.3 nicht unterstützt\n" +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "kann komprimiertes Archiv nicht wiederherstellen (Komprimierung in dieser Installation nicht unterstützt)" -#: pg_backup_archiver.c:432 +#: pg_backup_archiver.c:402 #, c-format -msgid "implied data-only restore\n" -msgstr "implizit werden nur Daten wiederhergestellt\n" +msgid "connecting to database for restore" +msgstr "verbinde mit der Datenbank zur Wiederherstellung" -#: pg_backup_archiver.c:502 +#: pg_backup_archiver.c:404 #, c-format -msgid "dropping %s %s\n" -msgstr "entferne %s %s\n" +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "direkte Datenbankverbindungen sind in Archiven vor Version 1.3 nicht unterstützt" -#: pg_backup_archiver.c:595 +#: pg_backup_archiver.c:449 #, c-format -msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" -msgstr "WARNUNG: konnte nicht bestimmen, wo IF EXISTS in die Anweisung »%s« eingefügt werden soll\n" +msgid "implied data-only restore" +msgstr "implizit werden nur Daten wiederhergestellt" -#: pg_backup_archiver.c:671 +#: pg_backup_archiver.c:515 #, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "setze Eigentümer und Privilegien für %s »%s.%s«\n" +msgid "dropping %s %s" +msgstr "entferne %s %s" -#: pg_backup_archiver.c:674 +#: pg_backup_archiver.c:610 #, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "setze Eigentümer und Privilegien für %s »%s«\n" +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "konnte nicht bestimmen, wo IF EXISTS in die Anweisung »%s« eingefügt werden soll" -#: pg_backup_archiver.c:740 pg_backup_archiver.c:742 +#: pg_backup_archiver.c:766 pg_backup_archiver.c:768 #, c-format -msgid "warning from original dump file: %s\n" -msgstr "Warnung aus der ursprünglichen Ausgabedatei: %s\n" +msgid "warning from original dump file: %s" +msgstr "Warnung aus der ursprünglichen Ausgabedatei: %s" -#: pg_backup_archiver.c:751 +#: pg_backup_archiver.c:783 #, c-format -msgid "creating %s \"%s.%s\"\n" -msgstr "erstelle %s »%s.%s«\n" +msgid "creating %s \"%s.%s\"" +msgstr "erstelle %s »%s.%s«" -#: pg_backup_archiver.c:754 +#: pg_backup_archiver.c:786 #, c-format -msgid "creating %s \"%s\"\n" -msgstr "erstelle %s »%s«\n" +msgid "creating %s \"%s\"" +msgstr "erstelle %s »%s«" -#: pg_backup_archiver.c:806 +#: pg_backup_archiver.c:843 #, c-format -msgid "connecting to new database \"%s\"\n" -msgstr "verbinde mit neuer Datenbank »%s«\n" +msgid "connecting to new database \"%s\"" +msgstr "verbinde mit neuer Datenbank »%s«" -#: pg_backup_archiver.c:834 +#: pg_backup_archiver.c:871 #, c-format -msgid "processing %s\n" -msgstr "verarbeite %s\n" +msgid "processing %s" +msgstr "verarbeite %s" -#: pg_backup_archiver.c:854 +#: pg_backup_archiver.c:891 #, c-format -msgid "processing data for table \"%s.%s\"\n" -msgstr "verarbeite Daten für Tabelle »%s.%s«\n" +msgid "processing data for table \"%s.%s\"" +msgstr "verarbeite Daten für Tabelle »%s.%s«" -#: pg_backup_archiver.c:916 +#: pg_backup_archiver.c:953 #, c-format -msgid "executing %s %s\n" -msgstr "führe %s %s aus\n" +msgid "executing %s %s" +msgstr "führe %s %s aus" -#: pg_backup_archiver.c:955 +#: pg_backup_archiver.c:992 #, c-format -msgid "disabling triggers for %s\n" -msgstr "schalte Trigger für %s aus\n" +msgid "disabling triggers for %s" +msgstr "schalte Trigger für %s aus" -#: pg_backup_archiver.c:983 +#: pg_backup_archiver.c:1018 #, c-format -msgid "enabling triggers for %s\n" -msgstr "schalte Trigger für %s ein\n" +msgid "enabling triggers for %s" +msgstr "schalte Trigger für %s ein" -#: pg_backup_archiver.c:1013 +#: pg_backup_archiver.c:1046 #, c-format -msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n" -msgstr "interner Fehler -- WriteData kann nicht außerhalb des Kontexts einer DataDumper-Routine aufgerufen werden\n" +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "interner Fehler -- WriteData kann nicht außerhalb des Kontexts einer DataDumper-Routine aufgerufen werden" -#: pg_backup_archiver.c:1211 +#: pg_backup_archiver.c:1231 #, c-format -msgid "large-object output not supported in chosen format\n" -msgstr "Large-Object-Ausgabe im gewählten Format nicht unterstützt\n" +msgid "large-object output not supported in chosen format" +msgstr "Large-Object-Ausgabe im gewählten Format nicht unterstützt" -#: pg_backup_archiver.c:1269 +#: pg_backup_archiver.c:1289 #, c-format -msgid "restored %d large object\n" -msgid_plural "restored %d large objects\n" -msgstr[0] "%d Large Object wiederhergestellt\n" -msgstr[1] "%d Large Objects wiederhergestellt\n" +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "%d Large Object wiederhergestellt" +msgstr[1] "%d Large Objects wiederhergestellt" -#: pg_backup_archiver.c:1290 pg_backup_tar.c:743 +#: pg_backup_archiver.c:1310 pg_backup_tar.c:738 #, c-format -msgid "restoring large object with OID %u\n" -msgstr "Wiederherstellung von Large Object mit OID %u\n" +msgid "restoring large object with OID %u" +msgstr "Wiederherstellung von Large Object mit OID %u" -#: pg_backup_archiver.c:1302 +#: pg_backup_archiver.c:1322 #, c-format msgid "could not create large object %u: %s" msgstr "konnte Large Object %u nicht erstellen: %s" -#: pg_backup_archiver.c:1307 pg_dump.c:3084 +#: pg_backup_archiver.c:1327 pg_dump.c:3471 #, c-format msgid "could not open large object %u: %s" msgstr "konnte Large Object %u nicht öffnen: %s" -#: pg_backup_archiver.c:1365 -#, c-format -msgid "could not open TOC file \"%s\": %s\n" -msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht öffnen: %s\n" - -#: pg_backup_archiver.c:1406 +#: pg_backup_archiver.c:1384 #, c-format -msgid "WARNING: line ignored: %s\n" -msgstr "WARNUNG: Zeile ignoriert: %s\n" +msgid "could not open TOC file \"%s\": %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:1413 +#: pg_backup_archiver.c:1424 #, c-format -msgid "could not find entry for ID %d\n" -msgstr "konnte Eintrag für ID %d nicht finden\n" +msgid "line ignored: %s" +msgstr "Zeile ignoriert: %s" -#: pg_backup_archiver.c:1434 pg_backup_directory.c:225 -#: pg_backup_directory.c:596 +#: pg_backup_archiver.c:1431 #, c-format -msgid "could not close TOC file: %s\n" -msgstr "konnte Inhaltsverzeichnisdatei nicht finden: %s\n" +msgid "could not find entry for ID %d" +msgstr "konnte Eintrag für ID %d nicht finden" -#: pg_backup_archiver.c:1543 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:582 pg_backup_directory.c:647 -#: pg_backup_directory.c:667 +#: pg_backup_archiver.c:1452 pg_backup_directory.c:222 +#: pg_backup_directory.c:587 #, c-format -msgid "could not open output file \"%s\": %s\n" -msgstr "konnte Ausgabedatei »%s« nicht öffnen: %s\n" +msgid "could not close TOC file: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht schließen: %m" -#: pg_backup_archiver.c:1546 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1567 pg_backup_custom.c:159 pg_backup_directory.c:332 +#: pg_backup_directory.c:574 pg_backup_directory.c:637 +#: pg_backup_directory.c:656 #, c-format -msgid "could not open output file: %s\n" -msgstr "konnte Ausgabedatei nicht öffnen: %s\n" +msgid "could not open output file \"%s\": %m" +msgstr "konnte Ausgabedatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:1652 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:165 #, c-format -msgid "wrote %lu byte of large object data (result = %lu)\n" -msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" -msgstr[0] "%lu Byte Large-Object-Daten geschrieben (Ergebnis = %lu)\n" -msgstr[1] "%lu Bytes Large-Object-Daten geschrieben (Ergebnis = %lu)\n" +msgid "could not open output file: %m" +msgstr "konnte Ausgabedatei nicht öffnen: %m" -#: pg_backup_archiver.c:1658 +#: pg_backup_archiver.c:1662 #, c-format -msgid "could not write to large object (result: %lu, expected: %lu)\n" -msgstr "konnte Large Object nicht schreiben (Ergebis: %lu, erwartet: %lu)\n" +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "%lu Byte Large-Object-Daten geschrieben (Ergebnis = %lu)" +msgstr[1] "%lu Bytes Large-Object-Daten geschrieben (Ergebnis = %lu)" -#: pg_backup_archiver.c:1751 +#: pg_backup_archiver.c:1667 #, c-format -msgid "Error while INITIALIZING:\n" -msgstr "Fehler in Phase INITIALIZING:\n" +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "konnte Large Object nicht schreiben (Ergebis: %lu, erwartet: %lu)" -#: pg_backup_archiver.c:1756 +#: pg_backup_archiver.c:1759 #, c-format -msgid "Error while PROCESSING TOC:\n" -msgstr "Fehler in Phase PROCESSING TOC:\n" +msgid "while INITIALIZING:" +msgstr "in Phase INITIALIZING:" -#: pg_backup_archiver.c:1761 +#: pg_backup_archiver.c:1764 #, c-format -msgid "Error while FINALIZING:\n" -msgstr "Fehler in Phase FINALIZING:\n" +msgid "while PROCESSING TOC:" +msgstr "in Phase PROCESSING TOC:" -#: pg_backup_archiver.c:1766 +#: pg_backup_archiver.c:1769 #, c-format -msgid "Error from TOC entry %d; %u %u %s %s %s\n" -msgstr "Fehler in Inhaltsverzeichniseintrag %d; %u %u %s %s %s\n" +msgid "while FINALIZING:" +msgstr "in Phase FINALIZING:" -#: pg_backup_archiver.c:1839 +#: pg_backup_archiver.c:1774 #, c-format -msgid "bad dumpId\n" -msgstr "ungültige DumpId\n" +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "in Inhaltsverzeichniseintrag %d; %u %u %s %s %s" -#: pg_backup_archiver.c:1860 +#: pg_backup_archiver.c:1850 #, c-format -msgid "bad table dumpId for TABLE DATA item\n" -msgstr "ungültige Tabellen-DumpId für »TABLE DATA«-Eintrag\n" +msgid "bad dumpId" +msgstr "ungültige DumpId" -#: pg_backup_archiver.c:1952 +#: pg_backup_archiver.c:1871 #, c-format -msgid "unexpected data offset flag %d\n" -msgstr "unerwartete Datenoffsetmarkierung %d\n" +msgid "bad table dumpId for TABLE DATA item" +msgstr "ungültige Tabellen-DumpId für »TABLE DATA«-Eintrag" -#: pg_backup_archiver.c:1965 +#: pg_backup_archiver.c:1963 #, c-format -msgid "file offset in dump file is too large\n" -msgstr "Dateioffset in Dumpdatei ist zu groß\n" +msgid "unexpected data offset flag %d" +msgstr "unerwartete Datenoffsetmarkierung %d" -#: pg_backup_archiver.c:2078 +#: pg_backup_archiver.c:1976 #, c-format -msgid "attempting to ascertain archive format\n" -msgstr "versuche Archivformat zu ermitteln\n" +msgid "file offset in dump file is too large" +msgstr "Dateioffset in Dumpdatei ist zu groß" -#: pg_backup_archiver.c:2104 pg_backup_archiver.c:2114 +#: pg_backup_archiver.c:2113 pg_backup_archiver.c:2123 #, c-format -msgid "directory name too long: \"%s\"\n" -msgstr "Verzeichnisname zu lang: »%s«\n" +msgid "directory name too long: \"%s\"" +msgstr "Verzeichnisname zu lang: »%s«" -#: pg_backup_archiver.c:2122 +#: pg_backup_archiver.c:2131 #, c-format -msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n" -msgstr "Verzeichnis »%s« scheint kein gültiges Archiv zu sein (»toc.dat« existiert nicht)\n" +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "Verzeichnis »%s« scheint kein gültiges Archiv zu sein (»toc.dat« existiert nicht)" -#: pg_backup_archiver.c:2130 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:396 +#: pg_backup_archiver.c:2139 pg_backup_custom.c:176 pg_backup_custom.c:760 +#: pg_backup_directory.c:207 pg_backup_directory.c:391 #, c-format -msgid "could not open input file \"%s\": %s\n" -msgstr "konnte Eingabedatei »%s« nicht öffnen: %s\n" +msgid "could not open input file \"%s\": %m" +msgstr "konnte Eingabedatei »%s« nicht öffnen: %m" -#: pg_backup_archiver.c:2138 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2146 pg_backup_custom.c:182 #, c-format -msgid "could not open input file: %s\n" -msgstr "konnte Eingabedatei nicht öffnen: %s\n" +msgid "could not open input file: %m" +msgstr "konnte Eingabedatei nicht öffnen: %m" -#: pg_backup_archiver.c:2145 +#: pg_backup_archiver.c:2152 #, c-format -msgid "could not read input file: %s\n" -msgstr "konnte Eingabedatei nicht lesen: %s\n" +msgid "could not read input file: %m" +msgstr "konnte Eingabedatei nicht lesen: %m" -#: pg_backup_archiver.c:2147 +#: pg_backup_archiver.c:2154 #, c-format -msgid "input file is too short (read %lu, expected 5)\n" -msgstr "Eingabedatei ist zu kurz (gelesen: %lu, erwartet: 5)\n" +msgid "input file is too short (read %lu, expected 5)" +msgstr "Eingabedatei ist zu kurz (gelesen: %lu, erwartet: 5)" -#: pg_backup_archiver.c:2232 +#: pg_backup_archiver.c:2239 #, c-format -msgid "input file appears to be a text format dump. Please use psql.\n" -msgstr "Eingabedatei ist anscheinend ein Dump im Textformat. Bitte verwenden Sie psql.\n" +msgid "input file appears to be a text format dump. Please use psql." +msgstr "Eingabedatei ist anscheinend ein Dump im Textformat. Bitte verwenden Sie psql." -#: pg_backup_archiver.c:2238 +#: pg_backup_archiver.c:2245 #, c-format -msgid "input file does not appear to be a valid archive (too short?)\n" -msgstr "Eingabedatei scheint kein gültiges Archiv zu sein (zu kurz?)\n" +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "Eingabedatei scheint kein gültiges Archiv zu sein (zu kurz?)" -#: pg_backup_archiver.c:2244 +#: pg_backup_archiver.c:2251 #, c-format -msgid "input file does not appear to be a valid archive\n" -msgstr "Eingabedatei scheint kein gültiges Archiv zu sein\n" +msgid "input file does not appear to be a valid archive" +msgstr "Eingabedatei scheint kein gültiges Archiv zu sein" -#: pg_backup_archiver.c:2264 +#: pg_backup_archiver.c:2271 #, c-format -msgid "could not close input file: %s\n" -msgstr "konnte Eingabedatei nicht schließen: %s\n" +msgid "could not close input file: %m" +msgstr "konnte Eingabedatei nicht schließen: %m" -#: pg_backup_archiver.c:2282 +#: pg_backup_archiver.c:2385 #, c-format -msgid "allocating AH for %s, format %d\n" -msgstr "erstelle AH für %s, Format %d\n" +msgid "unrecognized file format \"%d\"" +msgstr "nicht erkanntes Dateiformat »%d«" -#: pg_backup_archiver.c:2383 +#: pg_backup_archiver.c:2467 pg_backup_archiver.c:4475 #, c-format -msgid "unrecognized file format \"%d\"\n" -msgstr "nicht erkanntes Dateiformat »%d«\n" +msgid "finished item %d %s %s" +msgstr "Element %d %s %s abgeschlossen" -#: pg_backup_archiver.c:2438 pg_backup_archiver.c:4206 +#: pg_backup_archiver.c:2471 pg_backup_archiver.c:4488 #, c-format -msgid "finished item %d %s %s\n" -msgstr "Element %d %s %s abgeschlossen\n" +msgid "worker process failed: exit code %d" +msgstr "Arbeitsprozess fehlgeschlagen: Code %d" -#: pg_backup_archiver.c:2442 pg_backup_archiver.c:4219 +#: pg_backup_archiver.c:2591 #, c-format -msgid "worker process failed: exit code %d\n" -msgstr "Arbeitsprozess fehlgeschlagen: Code %d\n" +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID %d des Eintrags außerhalb des gültigen Bereichs -- vielleicht ein verfälschtes Inhaltsverzeichnis" -#: pg_backup_archiver.c:2562 +#: pg_backup_archiver.c:2658 #, c-format -msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" -msgstr "ID %d des Eintrags außerhalb des gültigen Bereichs -- vielleicht ein verfälschtes Inhaltsverzeichnis\n" +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "Wiederherstellung von Tabellen mit WITH OIDS wird nicht mehr unterstützt" -#: pg_backup_archiver.c:2678 +#: pg_backup_archiver.c:2740 #, c-format -msgid "read TOC entry %d (ID %d) for %s %s\n" -msgstr "Inhaltsverzeichniseintrag %d (ID %d) von %s %s gelesen\n" +msgid "unrecognized encoding \"%s\"" +msgstr "nicht erkannte Kodierung »%s«" -#: pg_backup_archiver.c:2712 +#: pg_backup_archiver.c:2745 #, c-format -msgid "unrecognized encoding \"%s\"\n" -msgstr "nicht erkannte Kodierung »%s«\n" +msgid "invalid ENCODING item: %s" +msgstr "ungültiger ENCODING-Eintrag: %s" -#: pg_backup_archiver.c:2717 +#: pg_backup_archiver.c:2763 #, c-format -msgid "invalid ENCODING item: %s\n" -msgstr "ungültiger ENCODING-Eintrag: %s\n" +msgid "invalid STDSTRINGS item: %s" +msgstr "ungültiger STDSTRINGS-Eintrag: %s" -#: pg_backup_archiver.c:2735 +#: pg_backup_archiver.c:2788 #, c-format -msgid "invalid STDSTRINGS item: %s\n" -msgstr "ungültiger STDSTRINGS-Eintrag: %s\n" +msgid "schema \"%s\" not found" +msgstr "Schema »%s« nicht gefunden" -#: pg_backup_archiver.c:2750 +#: pg_backup_archiver.c:2795 #, c-format -msgid "schema \"%s\" not found\n" -msgstr "Schema »%s« nicht gefunden\n" +msgid "table \"%s\" not found" +msgstr "Tabelle »%s« nicht gefunden" -#: pg_backup_archiver.c:2757 +#: pg_backup_archiver.c:2802 #, c-format -msgid "table \"%s\" not found\n" -msgstr "Tabelle »%s« nicht gefunden\n" +msgid "index \"%s\" not found" +msgstr "Index »%s« nicht gefunden" -#: pg_backup_archiver.c:2764 +#: pg_backup_archiver.c:2809 #, c-format -msgid "index \"%s\" not found\n" -msgstr "Index »%s« nicht gefunden\n" +msgid "function \"%s\" not found" +msgstr "Funktion »%s« nicht gefunden" -#: pg_backup_archiver.c:2771 +#: pg_backup_archiver.c:2816 #, c-format -msgid "function \"%s\" not found\n" -msgstr "Funktion »%s« nicht gefunden\n" +msgid "trigger \"%s\" not found" +msgstr "Trigger »%s« nicht gefunden" -#: pg_backup_archiver.c:2778 -#, c-format -msgid "trigger \"%s\" not found\n" -msgstr "Trigger »%s« nicht gefunden\n" - -#: pg_backup_archiver.c:3034 +#: pg_backup_archiver.c:3195 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "konnte Sitzungsbenutzer nicht auf »%s« setzen: %s" -#: pg_backup_archiver.c:3066 -#, c-format -msgid "could not set default_with_oids: %s" -msgstr "konnte default_with_oids nicht setzen: %s" - -#: pg_backup_archiver.c:3211 -#, c-format -msgid "could not set search_path to \"%s\": %s" -msgstr "konnte search_path nicht auf »%s« setzen: %s" - -#: pg_backup_archiver.c:3273 -#, c-format -msgid "could not set default_tablespace to %s: %s" -msgstr "konnte default_tablespace nicht auf »%s« setzen: %s" - -#: pg_backup_archiver.c:3363 pg_backup_archiver.c:3561 -#, c-format -msgid "WARNING: don't know how to set owner for object type \"%s\"\n" -msgstr "WARNUNG: kann Eigentümer für Objekttyp »%s« nicht setzen\n" - -#: pg_backup_archiver.c:3648 -#, c-format -msgid "did not find magic string in file header\n" -msgstr "magische Zeichenkette im Dateikopf nicht gefunden\n" - -#: pg_backup_archiver.c:3661 -#, c-format -msgid "unsupported version (%d.%d) in file header\n" -msgstr "nicht unterstützte Version (%d.%d) im Dateikopf\n" - -#: pg_backup_archiver.c:3666 -#, c-format -msgid "sanity check on integer size (%lu) failed\n" -msgstr "Prüfung der Integer-Größe (%lu) fehlgeschlagen\n" - -#: pg_backup_archiver.c:3670 -#, c-format -msgid "WARNING: archive was made on a machine with larger integers, some operations might fail\n" -msgstr "WARNUNG: Archiv wurde auf einer Maschine mit größeren Integers erstellt; einige Operationen könnten fehlschlagen\n" - -#: pg_backup_archiver.c:3680 +#: pg_backup_archiver.c:3533 pg_backup_archiver.c:3691 #, c-format -msgid "expected format (%d) differs from format found in file (%d)\n" -msgstr "erwartetes Format (%d) ist nicht das gleiche wie das in der Datei gefundene (%d)\n" +msgid "don't know how to set owner for object type \"%s\"" +msgstr "kann Eigentümer für Objekttyp »%s« nicht setzen" -#: pg_backup_archiver.c:3696 +#: pg_backup_archiver.c:3795 #, c-format -msgid "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n" -msgstr "WARNUNG: Archiv ist komprimiert, aber diese Installation unterstützt keine Komprimierung -- keine Daten verfügbar\n" +msgid "did not find magic string in file header" +msgstr "magische Zeichenkette im Dateikopf nicht gefunden" -#: pg_backup_archiver.c:3714 +#: pg_backup_archiver.c:3808 #, c-format -msgid "WARNING: invalid creation date in header\n" -msgstr "WARNUNG: ungültiges Erstellungsdatum im Kopf\n" +msgid "unsupported version (%d.%d) in file header" +msgstr "nicht unterstützte Version (%d.%d) im Dateikopf" -#: pg_backup_archiver.c:3789 +#: pg_backup_archiver.c:3813 #, c-format -msgid "entering restore_toc_entries_prefork\n" -msgstr "Eintritt in restore_toc_entries_prefork\n" +msgid "sanity check on integer size (%lu) failed" +msgstr "Prüfung der Integer-Größe (%lu) fehlgeschlagen" -#: pg_backup_archiver.c:3833 +#: pg_backup_archiver.c:3817 #, c-format -msgid "processing item %d %s %s\n" -msgstr "verarbeite Element %d %s %s\n" +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "Archiv wurde auf einer Maschine mit größeren Integers erstellt; einige Operationen könnten fehlschlagen" -#: pg_backup_archiver.c:3883 +#: pg_backup_archiver.c:3827 #, c-format -msgid "entering restore_toc_entries_parallel\n" -msgstr "Eintritt in restore_toc_entries_parallel\n" +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "erwartetes Format (%d) ist nicht das gleiche wie das in der Datei gefundene (%d)" -#: pg_backup_archiver.c:3931 +#: pg_backup_archiver.c:3843 #, c-format -msgid "entering main parallel loop\n" -msgstr "Eintritt in Hauptparallelschleife\n" +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "Archiv ist komprimiert, aber diese Installation unterstützt keine Komprimierung -- keine Daten verfügbar" -#: pg_backup_archiver.c:3942 +#: pg_backup_archiver.c:3861 #, c-format -msgid "skipping item %d %s %s\n" -msgstr "Element %d %s %s wird übersprungen\n" +msgid "invalid creation date in header" +msgstr "ungültiges Erstellungsdatum im Kopf" -#: pg_backup_archiver.c:3952 +#: pg_backup_archiver.c:3998 #, c-format -msgid "launching item %d %s %s\n" -msgstr "starte Element %d %s %s\n" +msgid "processing item %d %s %s" +msgstr "verarbeite Element %d %s %s" -#: pg_backup_archiver.c:3983 +#: pg_backup_archiver.c:4077 #, c-format -msgid "finished main parallel loop\n" -msgstr "Hauptparallelschleife beendet\n" +msgid "entering main parallel loop" +msgstr "Eintritt in Hauptparallelschleife" -#: pg_backup_archiver.c:3992 +#: pg_backup_archiver.c:4088 #, c-format -msgid "entering restore_toc_entries_postfork\n" -msgstr "Eintritt in restore_toc_entries_postfork\n" +msgid "skipping item %d %s %s" +msgstr "Element %d %s %s wird übersprungen" -#: pg_backup_archiver.c:4011 +#: pg_backup_archiver.c:4097 #, c-format -msgid "processing missed item %d %s %s\n" -msgstr "verarbeite verpasstes Element %d %s %s\n" +msgid "launching item %d %s %s" +msgstr "starte Element %d %s %s" -#: pg_backup_archiver.c:4162 +#: pg_backup_archiver.c:4151 #, c-format -msgid "no item ready\n" -msgstr "kein Element bereit\n" +msgid "finished main parallel loop" +msgstr "Hauptparallelschleife beendet" -#: pg_backup_archiver.c:4381 +#: pg_backup_archiver.c:4189 #, c-format -msgid "transferring dependency %d -> %d to %d\n" -msgstr "übertrage Abhängigkeit %d -> %d an %d\n" +msgid "processing missed item %d %s %s" +msgstr "verarbeite verpasstes Element %d %s %s" -#: pg_backup_archiver.c:4454 +#: pg_backup_archiver.c:4794 #, c-format -msgid "reducing dependencies for %d\n" -msgstr "reduziere Abhängigkeiten für %d\n" +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "Tabelle »%s« konnte nicht erzeugt werden, ihre Daten werden nicht wiederhergestellt werden" -#: pg_backup_archiver.c:4493 +#: pg_backup_custom.c:377 pg_backup_null.c:150 #, c-format -msgid "table \"%s\" could not be created, will not restore its data\n" -msgstr "Tabelle »%s« konnte nicht erzeugt werden, ihre Daten werden nicht wiederhergestellt werden\n" - -#. translator: this is a module name -#: pg_backup_custom.c:93 -msgid "custom archiver" -msgstr "Custom-Archivierer" +msgid "invalid OID for large object" +msgstr "ungültige OID für Large Object" -#: pg_backup_custom.c:380 pg_backup_null.c:150 +#: pg_backup_custom.c:447 #, c-format -msgid "invalid OID for large object\n" -msgstr "ungültige Oid für Large Object\n" +msgid "unrecognized data block type (%d) while searching archive" +msgstr "unerkannter Datenblocktyp (%d) beim Suchen im Archiv gefunden" -#: pg_backup_custom.c:451 +#: pg_backup_custom.c:458 pg_backup_custom.c:818 #, c-format -msgid "unrecognized data block type (%d) while searching archive\n" -msgstr "unerkannter Datenblocktyp (%d) beim Suchen im Archiv gefunden\n" +msgid "error during file seek: %m" +msgstr "Fehler beim Suchen in Datei: %m" -#: pg_backup_custom.c:462 +#: pg_backup_custom.c:467 #, c-format -msgid "error during file seek: %s\n" -msgstr "Fehler beim Suchen in Datei: %s\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise wegen Wiederherstellung außer der Reihe, was wegen fehlender Datenoffsets im Archiv nicht möglich ist" #: pg_backup_custom.c:472 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive\n" -msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise wegen Wiederherstellung außer der Reihe, was wegen fehlender Datenoffsets im Archiv nicht möglich ist\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise wegen Wiederherstellung außer der Reihe, was nicht möglich ist, weil die Eingabedatei kein Suchen unterstützt" #: pg_backup_custom.c:477 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file\n" -msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise wegen Wiederherstellung außer der Reihe, was nicht möglich ist, weil die Eingabedatei kein Suchen unterstützt\n" +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise beschädigtes Archiv" -#: pg_backup_custom.c:482 +#: pg_backup_custom.c:484 #, c-format -msgid "could not find block ID %d in archive -- possibly corrupt archive\n" -msgstr "konnte Block-ID %d nicht im Archiv finden -- möglicherweise beschädigtes Archiv\n" +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "unerwartete Block-ID (%d) beim Lesen der Daten gefunden -- erwartet wurde %d" -#: pg_backup_custom.c:489 +#: pg_backup_custom.c:498 #, c-format -msgid "found unexpected block ID (%d) when reading data -- expected %d\n" -msgstr "unerwartete Block-ID (%d) beim Lesen der Daten gefunden -- erwartet wurde %d\n" +msgid "unrecognized data block type %d while restoring archive" +msgstr "unerkannter Datenblocktyp %d beim Wiederherstellen des Archivs gefunden" -#: pg_backup_custom.c:503 +#: pg_backup_custom.c:580 #, c-format -msgid "unrecognized data block type %d while restoring archive\n" -msgstr "unerkannter Datenblocktyp %d beim Wiederherstellen des Archivs gefunden\n" +msgid "could not read from input file: %m" +msgstr "konnte nicht aus Eingabedatei lesen: %m" -#: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1096 +#: pg_backup_custom.c:698 pg_backup_custom.c:751 pg_backup_custom.c:891 +#: pg_backup_tar.c:1091 #, c-format -msgid "could not determine seek position in archive file: %s\n" -msgstr "konnte Positionszeiger in Archivdatei nicht ermitteln: %s\n" +msgid "could not determine seek position in archive file: %m" +msgstr "konnte Positionszeiger in Archivdatei nicht ermitteln: %m" -#: pg_backup_custom.c:723 pg_backup_custom.c:764 +#: pg_backup_custom.c:715 pg_backup_custom.c:755 #, c-format -msgid "could not close archive file: %s\n" -msgstr "konnte Archivdatei nicht schließen: %s\n" +msgid "could not close archive file: %m" +msgstr "konnte Archivdatei nicht schließen: %m" -#: pg_backup_custom.c:746 +#: pg_backup_custom.c:738 #, c-format -msgid "can only reopen input archives\n" -msgstr "nur Eingabearchive können neu geöffnet werden\n" +msgid "can only reopen input archives" +msgstr "nur Eingabearchive können neu geöffnet werden" -#: pg_backup_custom.c:753 +#: pg_backup_custom.c:745 #, c-format -msgid "parallel restore from standard input is not supported\n" -msgstr "parallele Wiederherstellung aus der Standardeingabe wird nicht unterstützt\n" +msgid "parallel restore from standard input is not supported" +msgstr "parallele Wiederherstellung aus der Standardeingabe wird nicht unterstützt" -#: pg_backup_custom.c:755 +#: pg_backup_custom.c:747 #, c-format -msgid "parallel restore from non-seekable file is not supported\n" -msgstr "parallele Wiederherstellung aus einer Datei, die kein Suchen ermöglicht, wird nicht unterstützt\n" +msgid "parallel restore from non-seekable file is not supported" +msgstr "parallele Wiederherstellung aus einer Datei, die kein Suchen ermöglicht, wird nicht unterstützt" -#: pg_backup_custom.c:774 +#: pg_backup_custom.c:763 #, c-format -msgid "could not set seek position in archive file: %s\n" -msgstr "konnte Positionszeiger in Archivdatei nicht setzen: %s\n" +msgid "could not set seek position in archive file: %m" +msgstr "konnte Positionszeiger in Archivdatei nicht setzen: %m" -#: pg_backup_custom.c:792 +#: pg_backup_custom.c:839 #, c-format -msgid "compressor active\n" -msgstr "Kompressor ist aktiv\n" +msgid "compressor active" +msgstr "Kompressor ist aktiv" -#: pg_backup_custom.c:848 +#: pg_backup_custom.c:894 #, c-format -msgid "WARNING: ftell mismatch with expected position -- ftell used\n" -msgstr "WARNUNG: erwartete Dateiposition stimmt nicht mit ftell überein -- benutze ftell\n" - -#. translator: this is a module name -#: pg_backup_db.c:29 -msgid "archiver (db)" -msgstr "Archivierer (DB)" +msgid "ftell mismatch with expected position -- ftell used" +msgstr "erwartete Dateiposition stimmt nicht mit ftell überein -- benutze ftell" -#: pg_backup_db.c:45 +#: pg_backup_db.c:44 #, c-format -msgid "could not get server_version from libpq\n" -msgstr "konnte server_version nicht von libpq ermitteln\n" +msgid "could not get server_version from libpq" +msgstr "konnte server_version nicht von libpq ermitteln" -#: pg_backup_db.c:56 pg_dumpall.c:2057 +#: pg_backup_db.c:55 pg_dumpall.c:1819 #, c-format -msgid "server version: %s; %s version: %s\n" -msgstr "Version des Servers: %s; Version von %s: %s\n" +msgid "server version: %s; %s version: %s" +msgstr "Version des Servers: %s; Version von %s: %s" -#: pg_backup_db.c:58 pg_dumpall.c:2059 +#: pg_backup_db.c:57 pg_dumpall.c:1821 #, c-format -msgid "aborting because of server version mismatch\n" -msgstr "Abbruch wegen unpassender Serverversion\n" +msgid "aborting because of server version mismatch" +msgstr "Abbruch wegen unpassender Serverversion" -#: pg_backup_db.c:148 +#: pg_backup_db.c:140 #, c-format -msgid "connecting to database \"%s\" as user \"%s\"\n" -msgstr "verbinde mit Datenbank »%s« als Benutzer »%s«\n" +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "verbinde mit Datenbank »%s« als Benutzer »%s«" -#: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 -#: pg_dumpall.c:1880 pg_dumpall.c:1994 +#: pg_backup_db.c:147 pg_backup_db.c:196 pg_backup_db.c:257 pg_backup_db.c:298 +#: pg_dumpall.c:1644 pg_dumpall.c:1757 msgid "Password: " msgstr "Passwort: " -#: pg_backup_db.c:187 +#: pg_backup_db.c:179 #, c-format -msgid "failed to reconnect to database\n" -msgstr "konnte nicht wieder zur Datenbank verbinden\n" +msgid "failed to reconnect to database" +msgstr "konnte nicht wieder zur Datenbank verbinden" -#: pg_backup_db.c:192 +#: pg_backup_db.c:184 #, c-format msgid "could not reconnect to database: %s" msgstr "konnte nicht wieder zur Datenbank verbinden: %s" -#: pg_backup_db.c:208 +#: pg_backup_db.c:200 #, c-format -msgid "connection needs password\n" -msgstr "Verbindung benötigt Passwort\n" +msgid "connection needs password" +msgstr "Verbindung benötigt Passwort" -#: pg_backup_db.c:259 +#: pg_backup_db.c:251 #, c-format -msgid "already connected to a database\n" -msgstr "bereits mit einer Datenbank verbunden\n" +msgid "already connected to a database" +msgstr "bereits mit einer Datenbank verbunden" -#: pg_backup_db.c:298 +#: pg_backup_db.c:290 #, c-format -msgid "failed to connect to database\n" -msgstr "Verbinden zur Datenbank schlug fehl\n" +msgid "failed to connect to database" +msgstr "Verbinden zur Datenbank schlug fehl" -#: pg_backup_db.c:314 +#: pg_backup_db.c:306 #, c-format msgid "connection to database \"%s\" failed: %s" msgstr "Verbindung zur Datenbank »%s« fehlgeschlagen: %s" -#: pg_backup_db.c:382 +#: pg_backup_db.c:378 pg_dumpall.c:1677 #, c-format msgid "%s" msgstr "%s" -#: pg_backup_db.c:389 +#: pg_backup_db.c:385 pg_dumpall.c:1882 pg_dumpall.c:1905 #, c-format msgid "query failed: %s" msgstr "Anfrage fehlgeschlagen: %s" -#: pg_backup_db.c:391 +#: pg_backup_db.c:387 pg_dumpall.c:1883 pg_dumpall.c:1906 #, c-format -msgid "query was: %s\n" -msgstr "Anfrage war: %s\n" +msgid "query was: %s" +msgstr "Anfrage war: %s" -#: pg_backup_db.c:433 +#: pg_backup_db.c:428 #, c-format -msgid "query returned %d row instead of one: %s\n" -msgid_plural "query returned %d rows instead of one: %s\n" -msgstr[0] "Anfrage ergab %d Zeile anstatt einer: %s\n" -msgstr[1] "Anfrage ergab %d Zeilen anstatt einer: %s\n" +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "Anfrage ergab %d Zeile anstatt einer: %s" +msgstr[1] "Anfrage ergab %d Zeilen anstatt einer: %s" -#: pg_backup_db.c:469 -#, c-format -msgid "%s: %s Command was: %s\n" -msgstr "%s: %s Die Anweisung war: %s\n" - -#: pg_backup_db.c:525 pg_backup_db.c:599 pg_backup_db.c:606 +#: pg_backup_db.c:520 pg_backup_db.c:594 pg_backup_db.c:601 msgid "could not execute query" msgstr "konnte Anfrage nicht ausführen" -#: pg_backup_db.c:578 +#: pg_backup_db.c:573 #, c-format msgid "error returned by PQputCopyData: %s" msgstr "Fehler in PQputCopyData: %s" -#: pg_backup_db.c:627 +#: pg_backup_db.c:622 #, c-format msgid "error returned by PQputCopyEnd: %s" msgstr "Fehler in PQputCopyEnd: %s" -#: pg_backup_db.c:633 +#: pg_backup_db.c:634 pg_dump.c:1924 #, c-format -msgid "COPY failed for table \"%s\": %s" -msgstr "COPY fehlgeschlagen für Tabelle »%s«: %s" +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "unerwartete zusätzliche Ergebnisse während COPY von Tabelle »%s«" -#: pg_backup_db.c:639 pg_dump.c:1841 -#, c-format -msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" -msgstr "WARNUNG: unerwartete zusätzliche Ergebnisse während COPY von Tabelle »%s«\n" - -#: pg_backup_db.c:651 +#: pg_backup_db.c:646 msgid "could not start database transaction" msgstr "konnte Datenbanktransaktion nicht starten" -#: pg_backup_db.c:659 +#: pg_backup_db.c:654 msgid "could not commit database transaction" msgstr "konnte Datenbanktransaktion nicht beenden" -#. translator: this is a module name -#: pg_backup_directory.c:65 -msgid "directory archiver" -msgstr "Verzeichnis-Archivierer" - -#: pg_backup_directory.c:157 +#: pg_backup_directory.c:156 #, c-format -msgid "no output directory specified\n" -msgstr "kein Ausgabeverzeichnis angegeben\n" +msgid "no output directory specified" +msgstr "kein Ausgabeverzeichnis angegeben" -#: pg_backup_directory.c:186 +#: pg_backup_directory.c:185 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: pg_backup_directory.c:190 +#: pg_backup_directory.c:189 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht schließen: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: pg_backup_directory.c:196 +#: pg_backup_directory.c:195 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht erzeugen: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: pg_backup_directory.c:355 pg_backup_directory.c:495 -#: pg_backup_directory.c:525 +#: pg_backup_directory.c:350 pg_backup_directory.c:488 +#: pg_backup_directory.c:518 #, c-format -msgid "could not write to output file: %s\n" -msgstr "konnte nicht in Ausgabedatei schreiben: %s\n" +msgid "could not write to output file: %s" +msgstr "konnte nicht in Ausgabedatei schreiben: %s" -#: pg_backup_directory.c:409 +#: pg_backup_directory.c:403 #, c-format -msgid "could not close data file: %s\n" -msgstr "konnte Datendatei nicht schließen: %s\n" +msgid "could not close data file: %m" +msgstr "konnte Datendatei nicht schließen: %m" -#: pg_backup_directory.c:450 +#: pg_backup_directory.c:443 #, c-format -msgid "could not open large object TOC file \"%s\" for input: %s\n" -msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %s\n" +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %m" -#: pg_backup_directory.c:461 +#: pg_backup_directory.c:454 #, c-format -msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" -msgstr "ungültige Zeile in Large-Object-Inhaltsverzeichnisdatei »%s«: %s\n" +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ungültige Zeile in Large-Object-Inhaltsverzeichnisdatei »%s«: %s" -#: pg_backup_directory.c:470 +#: pg_backup_directory.c:463 #, c-format -msgid "error reading large object TOC file \"%s\"\n" -msgstr "Fehler beim Lesen von Large-Object-Inhaltsverzeichnisdatei »%s«\n" +msgid "error reading large object TOC file \"%s\"" +msgstr "Fehler beim Lesen von Large-Object-Inhaltsverzeichnisdatei »%s«" -#: pg_backup_directory.c:474 +#: pg_backup_directory.c:467 #, c-format -msgid "could not close large object TOC file \"%s\": %s\n" -msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht schließen: %s\n" +msgid "could not close large object TOC file \"%s\": %m" +msgstr "konnte Large-Object-Inhaltsverzeichnisdatei »%s« nicht schließen: %m" -#: pg_backup_directory.c:690 +#: pg_backup_directory.c:678 #, c-format -msgid "could not write to blobs TOC file\n" -msgstr "konnte nicht in Blobs-Inhaltsverzeichnisdatei schreiben\n" +msgid "could not write to blobs TOC file" +msgstr "konnte nicht in Blobs-Inhaltsverzeichnisdatei schreiben" -#: pg_backup_directory.c:722 +#: pg_backup_directory.c:710 #, c-format -msgid "file name too long: \"%s\"\n" -msgstr "Dateiname zu lang: »%s«\n" +msgid "file name too long: \"%s\"" +msgstr "Dateiname zu lang: »%s«" #: pg_backup_null.c:75 #, c-format -msgid "this format cannot be read\n" -msgstr "dieses Format kann nicht gelesen werden\n" - -#. translator: this is a module name -#: pg_backup_tar.c:103 -msgid "tar archiver" -msgstr "Tar-Archivierer" +msgid "this format cannot be read" +msgstr "dieses Format kann nicht gelesen werden" -#: pg_backup_tar.c:181 +#: pg_backup_tar.c:177 #, c-format -msgid "could not open TOC file \"%s\" for output: %s\n" -msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Ausgabe öffnen: %s\n" +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Ausgabe öffnen: %m" -#: pg_backup_tar.c:189 +#: pg_backup_tar.c:184 #, c-format -msgid "could not open TOC file for output: %s\n" -msgstr "konnte Inhaltsverzeichnisdatei nicht zur Ausgabe öffnen: %s\n" +msgid "could not open TOC file for output: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht zur Ausgabe öffnen: %m" -#: pg_backup_tar.c:210 pg_backup_tar.c:366 +#: pg_backup_tar.c:203 pg_backup_tar.c:358 #, c-format -msgid "compression is not supported by tar archive format\n" -msgstr "Komprimierung ist im Tar-Format nicht unterstützt\n" +msgid "compression is not supported by tar archive format" +msgstr "Komprimierung ist im Tar-Format nicht unterstützt" -#: pg_backup_tar.c:218 +#: pg_backup_tar.c:211 #, c-format -msgid "could not open TOC file \"%s\" for input: %s\n" -msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %s\n" +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "konnte Inhaltsverzeichnisdatei »%s« nicht zur Eingabe öffnen: %m" -#: pg_backup_tar.c:225 +#: pg_backup_tar.c:218 #, c-format -msgid "could not open TOC file for input: %s\n" -msgstr "konnte Inhaltsverzeichnisdatei nicht zur Eingabe öffnen: %s\n" +msgid "could not open TOC file for input: %m" +msgstr "konnte Inhaltsverzeichnisdatei nicht zur Eingabe öffnen: %m" -#: pg_backup_tar.c:352 +#: pg_backup_tar.c:344 #, c-format -msgid "could not find file \"%s\" in archive\n" -msgstr "konnte Datei »%s« nicht im Archiv finden\n" +msgid "could not find file \"%s\" in archive" +msgstr "konnte Datei »%s« nicht im Archiv finden" -#: pg_backup_tar.c:418 +#: pg_backup_tar.c:410 #, c-format -msgid "could not generate temporary file name: %s\n" -msgstr "konnte keine temporären Dateinamen erzeugen: %s\n" +msgid "could not generate temporary file name: %m" +msgstr "konnte keine temporären Dateinamen erzeugen: %m" -#: pg_backup_tar.c:429 +#: pg_backup_tar.c:421 #, c-format -msgid "could not open temporary file\n" -msgstr "konnte komprimierte temporäre Datei nicht öffnen\n" +msgid "could not open temporary file" +msgstr "konnte temporäre Datei nicht öffnen" -#: pg_backup_tar.c:456 +#: pg_backup_tar.c:448 #, c-format -msgid "could not close tar member\n" -msgstr "konnte Tar-Mitglied nicht schließen\n" +msgid "could not close tar member" +msgstr "konnte Tar-Mitglied nicht schließen" -#: pg_backup_tar.c:575 +#: pg_backup_tar.c:571 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "interner Fehler -- weder th noch fh in tarReadRaw() angegeben\n" -#: pg_backup_tar.c:698 -#, c-format -msgid "unexpected COPY statement syntax: \"%s\"\n" -msgstr "unerwartete Syntax der COPY-Anweisung: »%s«\n" - -#: pg_backup_tar.c:968 -#, c-format -msgid "invalid OID for large object (%u)\n" -msgstr "Large Object hat ungültige Oid (%u)\n" - -#: pg_backup_tar.c:1112 -#, c-format -msgid "could not close temporary file: %s\n" -msgstr "konnte temporäre Datei nicht schließen: %s\n" - -#: pg_backup_tar.c:1122 +#: pg_backup_tar.c:693 #, c-format -msgid "actual file length (%s) does not match expected (%s)\n" -msgstr "tatsächliche Dateilänge (%s) stimmt nicht mit erwarteter Länge (%s) überein\n" +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "unerwartete Syntax der COPY-Anweisung: »%s«" -#: pg_backup_tar.c:1159 +#: pg_backup_tar.c:961 #, c-format -msgid "moving from position %s to next member at file position %s\n" -msgstr "bewege Position von %s auf nächstes Mitglied bei Position %s\n" +msgid "invalid OID for large object (%u)" +msgstr "Large Object hat ungültige OID (%u)" -#: pg_backup_tar.c:1170 +#: pg_backup_tar.c:1106 #, c-format -msgid "now at file position %s\n" -msgstr "jetzt bei Dateiposition %s\n" +msgid "could not close temporary file: %m" +msgstr "konnte temporäre Datei nicht schließen: %m" -#: pg_backup_tar.c:1179 pg_backup_tar.c:1209 +#: pg_backup_tar.c:1115 #, c-format -msgid "could not find header for file \"%s\" in tar archive\n" -msgstr "konnte Kopf für Datei »%s« im Tar-Archiv nicht finden\n" +msgid "actual file length (%s) does not match expected (%s)" +msgstr "tatsächliche Dateilänge (%s) stimmt nicht mit erwarteter Länge (%s) überein" -#: pg_backup_tar.c:1193 +#: pg_backup_tar.c:1172 pg_backup_tar.c:1202 #, c-format -msgid "skipping tar member %s\n" -msgstr "Tar-Mitglied %s übersprungen\n" +msgid "could not find header for file \"%s\" in tar archive" +msgstr "konnte Kopf für Datei »%s« im Tar-Archiv nicht finden" -#: pg_backup_tar.c:1197 +#: pg_backup_tar.c:1190 #, c-format -msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file.\n" -msgstr "Ausgabe der Daten in anderer Reihenfolge wird in diesem Archivformat nicht unterstützt: »%s« wird benötigt, aber es kommt vor »%s« in der Archivdatei.\n" +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "Ausgabe der Daten in anderer Reihenfolge wird in diesem Archivformat nicht unterstützt: »%s« wird benötigt, aber es kommt vor »%s« in der Archivdatei." -#: pg_backup_tar.c:1243 +#: pg_backup_tar.c:1235 #, c-format -msgid "incomplete tar header found (%lu byte)\n" -msgid_plural "incomplete tar header found (%lu bytes)\n" -msgstr[0] "unvollständiger Tar-Dateikopf gefunden (%lu Byte)\n" -msgstr[1] "unvollständiger Tar-Dateikopf gefunden (%lu Bytes)\n" +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "unvollständiger Tar-Dateikopf gefunden (%lu Byte)" +msgstr[1] "unvollständiger Tar-Dateikopf gefunden (%lu Bytes)" -#: pg_backup_tar.c:1284 +#: pg_backup_tar.c:1286 #, c-format -msgid "TOC Entry %s at %s (length %s, checksum %d)\n" -msgstr "Inhaltsverzeichniseintrag %s bei %s (Länge %s, Prüfsumme %d)\n" - -#: pg_backup_tar.c:1295 -#, c-format -msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" -msgstr "beschädigter Tar-Kopf in %s gefunden (%d erwartet, %d berechnet), Dateiposition %s\n" +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "beschädigter Tar-Kopf in %s gefunden (%d erwartet, %d berechnet), Dateiposition %s" #: pg_backup_utils.c:54 #, c-format -msgid "%s: unrecognized section name: \"%s\"\n" -msgstr "%s: unbekannter Abschnittsname: »%s«\n" +msgid "unrecognized section name: \"%s\"" +msgstr "unbekannter Abschnittsname: »%s«" -#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:313 -#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 -#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 +#: pg_backup_utils.c:55 pg_dump.c:611 pg_dump.c:628 pg_dumpall.c:333 +#: pg_dumpall.c:343 pg_dumpall.c:352 pg_dumpall.c:361 pg_dumpall.c:369 +#: pg_dumpall.c:383 pg_dumpall.c:459 pg_restore.c:288 pg_restore.c:304 +#: pg_restore.c:322 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_backup_utils.c:118 +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "on_exit_nicely-Slots aufgebraucht" + +#: pg_dump.c:542 #, c-format -msgid "out of on_exit_nicely slots\n" -msgstr "on_exit_nicely-Slots aufgebraucht\n" +msgid "compression level must be in range 0..9" +msgstr "Komprimierungsniveau muss im Bereich 0..9 sein" -#: pg_dump.c:511 +#: pg_dump.c:580 #, c-format -msgid "compression level must be in range 0..9\n" -msgstr "Komprimierungsniveau muss im Bereich 0..9 sein\n" +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits muss im Bereich -15..3 sein" -#: pg_dump.c:560 pg_dumpall.c:321 pg_restore.c:297 +#: pg_dump.c:603 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "rows-per-insert must be in range %d..%d" +msgstr "Zeilen-pro-Insert muss im Bereich %d..%d sein" -#: pg_dump.c:581 +#: pg_dump.c:626 pg_dumpall.c:341 pg_restore.c:302 #, c-format -msgid "options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "Optionen -s/--schema-only und -a/--data-only können nicht zusammen verwendet werden\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: pg_dump.c:587 +#: pg_dump.c:647 pg_restore.c:331 #, c-format -msgid "options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "Optionen -c/--clean und -a/--data-only können nicht zusammen verwendet werden\n" +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "Optionen -s/--schema-only und -a/--data-only können nicht zusammen verwendet werden" -#: pg_dump.c:593 +#: pg_dump.c:653 pg_restore.c:337 #, c-format -msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" -msgstr "Optionen --inserts/--column-inserts und -o/--oids können nicht zusammen verwendet werden\n" +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "Optionen -c/--clean und -a/--data-only können nicht zusammen verwendet werden" -#: pg_dump.c:594 +#: pg_dump.c:658 pg_dumpall.c:376 pg_restore.c:386 #, c-format -msgid "(The INSERT command cannot set OIDs.)\n" -msgstr "(Die INSERT-Anweisung kann OIDs nicht setzen.)\n" +msgid "option --if-exists requires option -c/--clean" +msgstr "Option --if-exists benötigt Option -c/--clean" -#: pg_dump.c:599 +#: pg_dump.c:665 #, c-format -msgid "option --if-exists requires option -c/--clean\n" -msgstr "Option --if-exists benötigt Option -c/--clean\n" +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts" +msgstr "Option --on-conflict-do-nothing benötigt Option --inserts, --rows-per-insert oder --column-inserts" -#: pg_dump.c:621 +#: pg_dump.c:687 #, c-format -msgid "WARNING: requested compression not available in this installation -- archive will be uncompressed\n" -msgstr "WARNUNG: Komprimierung ist in dieser Installation nicht verfügbar -- Archiv wird nicht komprimiert\n" +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "Komprimierung ist in dieser Installation nicht verfügbar -- Archiv wird nicht komprimiert" -#: pg_dump.c:636 +#: pg_dump.c:708 pg_restore.c:353 #, c-format -msgid "invalid number of parallel jobs\n" -msgstr "ungültige Anzahl paralleler Jobs\n" +msgid "invalid number of parallel jobs" +msgstr "ungültige Anzahl paralleler Jobs" -#: pg_dump.c:640 +#: pg_dump.c:712 #, c-format -msgid "parallel backup only supported by the directory format\n" -msgstr "parallele Sicherung wird nur vom Ausgabeformat »Verzeichnis« unterstützt\n" +msgid "parallel backup only supported by the directory format" +msgstr "parallele Sicherung wird nur vom Ausgabeformat »Verzeichnis« unterstützt" -#: pg_dump.c:695 +#: pg_dump.c:767 #, c-format msgid "" "Synchronized snapshots are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" "Synchronisierte Snapshots werden von dieser Serverversion nicht unterstützt.\n" "Verwenden Sie --no-synchronized-snapshots, wenn Sie keine synchronisierten\n" -"Snapshots benötigen.\n" +"Snapshots benötigen." -#: pg_dump.c:702 +#: pg_dump.c:773 #, c-format -msgid "Exported snapshots are not supported by this server version.\n" -msgstr "Exportierte Snapshots werden in dieser Serverversion nicht unterstützt.\n" +msgid "Exported snapshots are not supported by this server version." +msgstr "Exportierte Snapshots werden in dieser Serverversion nicht unterstützt." -#: pg_dump.c:716 +#: pg_dump.c:785 #, c-format -msgid "last built-in OID is %u\n" -msgstr "letzte eingebaute OID ist %u\n" +msgid "last built-in OID is %u" +msgstr "letzte eingebaute OID ist %u" -#: pg_dump.c:725 +#: pg_dump.c:794 #, c-format -msgid "no matching schemas were found\n" -msgstr "keine passenden Schemas gefunden\n" +msgid "no matching schemas were found" +msgstr "keine passenden Schemas gefunden" -#: pg_dump.c:739 +#: pg_dump.c:808 #, c-format -msgid "no matching tables were found\n" -msgstr "keine passenden Tabellen gefunden\n" +msgid "no matching tables were found" +msgstr "keine passenden Tabellen gefunden" -#: pg_dump.c:913 +#: pg_dump.c:980 #, c-format msgid "" "%s dumps a database as a text file or to other formats.\n" @@ -1432,17 +1327,17 @@ msgstr "" "%s gibt eine Datenbank als Textdatei oder in anderen Formaten aus.\n" "\n" -#: pg_dump.c:914 pg_dumpall.c:575 pg_restore.c:449 +#: pg_dump.c:981 pg_dumpall.c:612 pg_restore.c:466 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: pg_dump.c:915 +#: pg_dump.c:982 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPTION]... [DBNAME]\n" -#: pg_dump.c:917 pg_dumpall.c:578 pg_restore.c:452 +#: pg_dump.c:984 pg_dumpall.c:615 pg_restore.c:469 #, c-format msgid "" "\n" @@ -1451,12 +1346,12 @@ msgstr "" "\n" "Allgemeine Optionen:\n" -#: pg_dump.c:918 +#: pg_dump.c:985 #, c-format msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=DATEINAME Name der Ausgabedatei oder des -verzeichnisses\n" -#: pg_dump.c:919 +#: pg_dump.c:986 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1465,44 +1360,44 @@ msgstr "" " -F, --format=c|d|t|p Ausgabeformat (custom, d=Verzeichnis, tar,\n" " plain text)\n" -#: pg_dump.c:921 +#: pg_dump.c:988 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM so viele parallele Jobs zur Sicherung verwenden\n" -#: pg_dump.c:922 pg_dumpall.c:580 +#: pg_dump.c:989 pg_dumpall.c:617 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose »Verbose«-Modus\n" -#: pg_dump.c:923 pg_dumpall.c:581 +#: pg_dump.c:990 pg_dumpall.c:618 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_dump.c:924 +#: pg_dump.c:991 #, c-format msgid " -Z, --compress=0-9 compression level for compressed formats\n" msgstr " -Z, --compress=0-9 Komprimierungsniveau für komprimierte Formate\n" -#: pg_dump.c:925 pg_dumpall.c:582 +#: pg_dump.c:992 pg_dumpall.c:619 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=ZEIT Abbruch nach ZEIT Warten auf Tabellensperre\n" -#: pg_dump.c:926 pg_dumpall.c:605 +#: pg_dump.c:993 pg_dumpall.c:646 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr "" " --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" " geschrieben sind\n" -#: pg_dump.c:927 pg_dumpall.c:583 +#: pg_dump.c:994 pg_dumpall.c:620 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_dump.c:929 pg_dumpall.c:584 +#: pg_dump.c:996 pg_dumpall.c:621 #, c-format msgid "" "\n" @@ -1511,54 +1406,49 @@ msgstr "" "\n" "Optionen die den Inhalt der Ausgabe kontrollieren:\n" -#: pg_dump.c:930 pg_dumpall.c:585 +#: pg_dump.c:997 pg_dumpall.c:622 #, c-format msgid " -a, --data-only dump only the data, not the schema\n" msgstr " -a, --data-only nur Daten ausgeben, nicht das Schema\n" -#: pg_dump.c:931 +#: pg_dump.c:998 #, c-format msgid " -b, --blobs include large objects in dump\n" msgstr " -b, --blobs Large Objects mit ausgeben\n" -#: pg_dump.c:932 +#: pg_dump.c:999 #, c-format msgid " -B, --no-blobs exclude large objects in dump\n" msgstr " -B, --no-blobs Large Objects nicht mit ausgeben\n" -#: pg_dump.c:933 pg_restore.c:463 +#: pg_dump.c:1000 pg_restore.c:480 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean Datenbankobjekte vor der Wiedererstellung löschen\n" -#: pg_dump.c:934 +#: pg_dump.c:1001 #, c-format msgid " -C, --create include commands to create database in dump\n" msgstr "" " -C, --create Anweisungen zum Erstellen der Datenbank in\n" " Ausgabe einfügen\n" -#: pg_dump.c:935 +#: pg_dump.c:1002 pg_dumpall.c:624 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=KODIERUNG Daten in Kodierung KODIERUNG ausgeben\n" -#: pg_dump.c:936 +#: pg_dump.c:1003 #, c-format msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" msgstr " -n, --schema=SCHEMA nur das/die angegebene(n) Schema(s) ausgeben\n" -#: pg_dump.c:937 +#: pg_dump.c:1004 #, c-format msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" msgstr " -N, --exclude-schema=SCHEMA das/die angegebene(n) Schema(s) NICHT ausgeben\n" -#: pg_dump.c:938 pg_dumpall.c:588 -#, c-format -msgid " -o, --oids include OIDs in dump\n" -msgstr " -o, --oids OIDs mit ausgeben\n" - -#: pg_dump.c:939 +#: pg_dump.c:1005 #, c-format msgid "" " -O, --no-owner skip restoration of object ownership in\n" @@ -1567,58 +1457,58 @@ msgstr "" " -O, --no-owner Wiederherstellung der Objekteigentümerschaft im\n" " »plain text«-Format auslassen\n" -#: pg_dump.c:941 pg_dumpall.c:591 +#: pg_dump.c:1007 pg_dumpall.c:628 #, c-format msgid " -s, --schema-only dump only the schema, no data\n" msgstr " -s, --schema-only nur das Schema, nicht die Daten, ausgeben\n" -#: pg_dump.c:942 +#: pg_dump.c:1008 #, c-format msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" msgstr " -S, --superuser=NAME Superusername für »plain text«-Format\n" -#: pg_dump.c:943 +#: pg_dump.c:1009 #, c-format msgid " -t, --table=TABLE dump the named table(s) only\n" msgstr " -t, --table=TABELLE nur die angegebene(n) Tabelle(n) ausgeben\n" -#: pg_dump.c:944 +#: pg_dump.c:1010 #, c-format msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" msgstr " -T, --exclude-table=TABELLE die angegebene(n) Tabelle(n) NICHT ausgeben\n" -#: pg_dump.c:945 pg_dumpall.c:594 +#: pg_dump.c:1011 pg_dumpall.c:631 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges Zugriffsprivilegien (grant/revoke) nicht ausgeben\n" -#: pg_dump.c:946 pg_dumpall.c:595 +#: pg_dump.c:1012 pg_dumpall.c:632 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade wird nur von Upgrade-Programmen verwendet\n" -#: pg_dump.c:947 pg_dumpall.c:596 +#: pg_dump.c:1013 pg_dumpall.c:633 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr "" " --column-inserts Daten als INSERT-Anweisungen mit Spaltennamen\n" " ausgeben\n" -#: pg_dump.c:948 pg_dumpall.c:597 +#: pg_dump.c:1014 pg_dumpall.c:634 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr "" " --disable-dollar-quoting Dollar-Quoting abschalten, normales SQL-Quoting\n" " verwenden\n" -#: pg_dump.c:949 pg_dumpall.c:598 pg_restore.c:480 +#: pg_dump.c:1015 pg_dumpall.c:635 pg_restore.c:497 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr "" " --disable-triggers Trigger während der Datenwiederherstellung\n" " abschalten\n" -#: pg_dump.c:950 +#: pg_dump.c:1016 #, c-format msgid "" " --enable-row-security enable row security (dump only content user has\n" @@ -1627,78 +1517,103 @@ msgstr "" " --enable-row-security Sicherheit auf Zeilenebene einschalten (nur Daten\n" " ausgeben, auf die der Benutzer Zugriff hat)\n" -#: pg_dump.c:952 +#: pg_dump.c:1018 #, c-format msgid " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" msgstr " --exclude-table-data=TABELLE Daten der angegebenen Tabelle(n) NICHT ausgeben\n" -#: pg_dump.c:953 pg_dumpall.c:599 pg_restore.c:482 +#: pg_dump.c:1019 pg_dumpall.c:637 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr "" + +#: pg_dump.c:1020 pg_dumpall.c:638 pg_restore.c:499 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists IF EXISTS verwenden, wenn Objekte gelöscht werden\n" -#: pg_dump.c:954 pg_dumpall.c:600 +#: pg_dump.c:1021 pg_dumpall.c:639 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts Daten als INSERT-Anweisungen statt COPY ausgeben\n" -#: pg_dump.c:955 pg_dumpall.c:601 +#: pg_dump.c:1022 pg_dumpall.c:640 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root Partitionen über die Wurzeltabelle laden\n" + +#: pg_dump.c:1023 pg_dumpall.c:641 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments Kommentare nicht ausgeben\n" + +#: pg_dump.c:1024 pg_dumpall.c:642 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications Publikationen nicht ausgeben\n" -#: pg_dump.c:956 pg_dumpall.c:603 +#: pg_dump.c:1025 pg_dumpall.c:644 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels Security-Label-Zuweisungen nicht ausgeben\n" -#: pg_dump.c:957 pg_dumpall.c:604 +#: pg_dump.c:1026 pg_dumpall.c:645 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions Subskriptionen nicht ausgeben\n" -#: pg_dump.c:958 +#: pg_dump.c:1027 #, c-format msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" msgstr "" " --no-synchronized-snapshots keine synchronisierten Snapshots in parallelen\n" " Jobs verwenden\n" -#: pg_dump.c:959 pg_dumpall.c:606 +#: pg_dump.c:1028 pg_dumpall.c:647 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces Tablespace-Zuordnungen nicht ausgeben\n" -#: pg_dump.c:960 pg_dumpall.c:607 +#: pg_dump.c:1029 pg_dumpall.c:648 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data Daten in ungeloggten Tabellen nicht ausgeben\n" -#: pg_dump.c:961 pg_dumpall.c:608 +#: pg_dump.c:1030 pg_dumpall.c:649 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing INSERT-Befehle mit ON CONFLICT DO NOTHING ausgeben\n" + +#: pg_dump.c:1031 pg_dumpall.c:650 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr "" " --quote-all-identifiers alle Bezeichner in Anführungszeichen, selbst wenn\n" " kein Schlüsselwort\n" -#: pg_dump.c:962 +#: pg_dump.c:1032 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr "" + +#: pg_dump.c:1033 #, c-format msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" msgstr "" " --section=ABSCHNITT angegebenen Abschnitt ausgeben (pre-data, data\n" " oder post-data)\n" -#: pg_dump.c:963 +#: pg_dump.c:1034 #, c-format msgid " --serializable-deferrable wait until the dump can run without anomalies\n" msgstr " --serializable-deferrable warten bis der Dump ohne Anomalien laufen kann\n" -#: pg_dump.c:964 +#: pg_dump.c:1035 #, c-format msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT angegebenen Snapshot für den Dump verwenden\n" -#: pg_dump.c:965 pg_restore.c:490 +#: pg_dump.c:1036 pg_restore.c:508 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -1707,7 +1622,7 @@ msgstr "" " --strict-names Tabellen- oder Schemamuster müssen auf mindestens\n" " je ein Objekt passen\n" -#: pg_dump.c:967 pg_dumpall.c:609 pg_restore.c:492 +#: pg_dump.c:1038 pg_dumpall.c:651 pg_restore.c:510 #, c-format msgid "" " --use-set-session-authorization\n" @@ -1719,7 +1634,7 @@ msgstr "" " OWNER Befehle verwenden, um Eigentümerschaft zu\n" " setzen\n" -#: pg_dump.c:971 pg_dumpall.c:613 pg_restore.c:496 +#: pg_dump.c:1042 pg_dumpall.c:655 pg_restore.c:514 #, c-format msgid "" "\n" @@ -1728,42 +1643,42 @@ msgstr "" "\n" "Verbindungsoptionen:\n" -#: pg_dump.c:972 +#: pg_dump.c:1043 #, c-format msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=DBNAME auszugebende Datenbank\n" -#: pg_dump.c:973 pg_dumpall.c:615 pg_restore.c:497 +#: pg_dump.c:1044 pg_dumpall.c:657 pg_restore.c:515 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:498 +#: pg_dump.c:1045 pg_dumpall.c:659 pg_restore.c:516 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT Portnummer des Datenbankservers\n" -#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:499 +#: pg_dump.c:1046 pg_dumpall.c:660 pg_restore.c:517 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:500 +#: pg_dump.c:1047 pg_dumpall.c:661 pg_restore.c:518 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: pg_dump.c:977 pg_dumpall.c:620 pg_restore.c:501 +#: pg_dump.c:1048 pg_dumpall.c:662 pg_restore.c:519 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n" -#: pg_dump.c:978 pg_dumpall.c:621 +#: pg_dump.c:1049 pg_dumpall.c:663 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLLENNAME vor der Ausgabe SET ROLE ausführen\n" -#: pg_dump.c:980 +#: pg_dump.c:1051 #, c-format msgid "" "\n" @@ -1776,540 +1691,582 @@ msgstr "" "PGDATABASE verwendet.\n" "\n" -#: pg_dump.c:982 pg_dumpall.c:625 pg_restore.c:508 +#: pg_dump.c:1053 pg_dumpall.c:667 pg_restore.c:526 #, c-format -msgid "Report bugs to .\n" -msgstr "Berichten Sie Fehler an .\n" +msgid "Report bugs to .\n" +msgstr "Berichten Sie Fehler an .\n" -#: pg_dump.c:999 +#: pg_dump.c:1072 pg_dumpall.c:494 #, c-format -msgid "invalid client encoding \"%s\" specified\n" -msgstr "ungültige Clientkodierung »%s« angegeben\n" +msgid "invalid client encoding \"%s\" specified" +msgstr "ungültige Clientkodierung »%s« angegeben" -#: pg_dump.c:1136 +#: pg_dump.c:1218 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" -"Synchronisierte Snapshots werden auf Standby-Servern nicht unterstützt.\n" +"Synchronisierte Snapshots auf Standby-Servern werden von dieser Serverversion nicht unterstützt.\n" "Verwenden Sie --no-synchronized-snapshots, wenn Sie keine synchronisierten\n" -"Snapshots benötigen.\n" +"Snapshots benötigen." -#: pg_dump.c:1205 +#: pg_dump.c:1287 #, c-format -msgid "invalid output format \"%s\" specified\n" -msgstr "ungültiges Ausgabeformat »%s« angegeben\n" +msgid "invalid output format \"%s\" specified" +msgstr "ungültiges Ausgabeformat »%s« angegeben" -#: pg_dump.c:1243 +#: pg_dump.c:1325 #, c-format -msgid "no matching schemas were found for pattern \"%s\"\n" -msgstr "keine passenden Schemas für Muster »%s« gefunden\n" +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "keine passenden Schemas für Muster »%s« gefunden" -#: pg_dump.c:1297 +#: pg_dump.c:1390 #, c-format -msgid "no matching tables were found for pattern \"%s\"\n" -msgstr "keine passenden Tabellen für Muster »%s« gefunden\n" +msgid "no matching tables were found for pattern \"%s\"" +msgstr "keine passenden Tabellen für Muster »%s« gefunden" -#: pg_dump.c:1701 +#: pg_dump.c:1804 #, c-format -msgid "dumping contents of table \"%s.%s\"\n" -msgstr "gebe Inhalt der Tabelle »%s.%s« aus\n" +msgid "dumping contents of table \"%s.%s\"" +msgstr "gebe Inhalt der Tabelle »%s.%s« aus" -#: pg_dump.c:1822 +#: pg_dump.c:1905 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" -msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetCopyData() fehlgeschlagen.\n" +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetCopyData() fehlgeschlagen." -#: pg_dump.c:1823 pg_dump.c:1833 +#: pg_dump.c:1906 pg_dump.c:1916 #, c-format msgid "Error message from server: %s" msgstr "Fehlermeldung vom Server: %s" -#: pg_dump.c:1824 pg_dump.c:1834 +#: pg_dump.c:1907 pg_dump.c:1917 #, c-format -msgid "The command was: %s\n" -msgstr "Die Anweisung war: %s\n" +msgid "The command was: %s" +msgstr "Die Anweisung war: %s" -#: pg_dump.c:1832 +#: pg_dump.c:1915 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" -msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetResult() fehlgeschlagen.\n" +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Ausgabe des Inhalts der Tabelle »%s« fehlgeschlagen: PQgetResult() fehlgeschlagen." -#: pg_dump.c:2481 +#: pg_dump.c:2666 #, c-format -msgid "saving database definition\n" -msgstr "sichere Datenbankdefinition\n" +msgid "saving database definition" +msgstr "sichere Datenbankdefinition" -#: pg_dump.c:2787 +#: pg_dump.c:3130 #, c-format -msgid "saving encoding = %s\n" -msgstr "sichere Kodierung = %s\n" +msgid "saving encoding = %s" +msgstr "sichere Kodierung = %s" -#: pg_dump.c:2814 +#: pg_dump.c:3155 #, c-format -msgid "saving standard_conforming_strings = %s\n" -msgstr "sichere standard_conforming_strings = %s\n" +msgid "saving standard_conforming_strings = %s" +msgstr "sichere standard_conforming_strings = %s" -#: pg_dump.c:2854 +#: pg_dump.c:3194 #, c-format -msgid "reading large objects\n" -msgstr "lese Large Objects\n" +msgid "could not parse result of current_schemas()" +msgstr "konnte Ergebnis von current_schemas() nicht interpretieren" -#: pg_dump.c:3049 +#: pg_dump.c:3213 #, c-format -msgid "saving large objects\n" -msgstr "sichere Large Objects\n" +msgid "saving search_path = %s" +msgstr "sichere search_path = %s" -#: pg_dump.c:3094 +#: pg_dump.c:3253 +#, c-format +msgid "reading large objects" +msgstr "lese Large Objects" + +#: pg_dump.c:3435 +#, c-format +msgid "saving large objects" +msgstr "sichere Large Objects" + +#: pg_dump.c:3481 #, c-format msgid "error reading large object %u: %s" msgstr "Fehler beim Lesen von Large Object %u: %s" -#: pg_dump.c:3147 +#: pg_dump.c:3533 #, c-format -msgid "reading row security enabled for table \"%s.%s\"\n" -msgstr "lese Einstellung von Sicherheit auf Zeilenebene für Tabelle »%s.%s«\n" +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "lese Einstellung von Sicherheit auf Zeilenebene für Tabelle »%s.%s«" -#: pg_dump.c:3179 +#: pg_dump.c:3564 #, c-format -msgid "reading policies for table \"%s.%s\"\n" -msgstr "lese Policys von Tabelle »%s.%s«\n" +msgid "reading policies for table \"%s.%s\"" +msgstr "lese Policys von Tabelle »%s.%s«" -#: pg_dump.c:3329 +#: pg_dump.c:3714 #, c-format -msgid "unexpected policy command type: %c\n" -msgstr "unerwarteter Policy-Befehlstyp: %c\n" +msgid "unexpected policy command type: %c" +msgstr "unerwarteter Policy-Befehlstyp: %c" -#: pg_dump.c:3445 +#: pg_dump.c:3841 #, c-format -msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Publikation »%s« scheint ungültig zu sein\n" +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "Eigentümer der Publikation »%s« scheint ungültig zu sein" -#: pg_dump.c:3575 +#: pg_dump.c:3978 #, c-format -msgid "reading publication membership for table \"%s.%s\"\n" -msgstr "lese Publikationsmitgliedschaft für Tabelle »%s.%s«\n" +msgid "reading publication membership for table \"%s.%s\"" +msgstr "lese Publikationsmitgliedschaft für Tabelle »%s.%s«" -#: pg_dump.c:3722 +#: pg_dump.c:4121 #, c-format -msgid "WARNING: subscriptions not dumped because current user is not a superuser\n" -msgstr "WARNUNG: Subskriptionen werden nicht ausgegeben, weil der aktuelle Benutzer kein Superuser ist\n" +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "Subskriptionen werden nicht ausgegeben, weil der aktuelle Benutzer kein Superuser ist" -#: pg_dump.c:3776 +#: pg_dump.c:4175 #, c-format -msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Subskription »%s« scheint ungültig zu sein\n" +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "Eigentümer der Subskription »%s« scheint ungültig zu sein" -#: pg_dump.c:3820 +#: pg_dump.c:4219 #, c-format -msgid "WARNING: could not parse subpublications array\n" -msgstr "WARNUNG: konnte subpublications-Array nicht interpretieren\n" +msgid "could not parse subpublications array" +msgstr "konnte subpublications-Array nicht interpretieren" -#: pg_dump.c:4053 +#: pg_dump.c:4491 #, c-format -msgid "could not find parent extension for %s\n" -msgstr "konnte Erweiterung, zu der %s gehört, nicht finden\n" +msgid "could not find parent extension for %s %s" +msgstr "konnte Erweiterung, zu der %s %s gehört, nicht finden" -#: pg_dump.c:4207 +#: pg_dump.c:4623 #, c-format -msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer des Schemas »%s« scheint ungültig zu sein\n" +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "Eigentümer des Schemas »%s« scheint ungültig zu sein" -#: pg_dump.c:4230 +#: pg_dump.c:4646 #, c-format -msgid "schema with OID %u does not exist\n" -msgstr "Schema mit OID %u existiert nicht\n" +msgid "schema with OID %u does not exist" +msgstr "Schema mit OID %u existiert nicht" -#: pg_dump.c:4561 +#: pg_dump.c:4971 #, c-format -msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer des Datentypen »%s« scheint ungültig zu sein\n" +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "Eigentümer des Datentypen »%s« scheint ungültig zu sein" -#: pg_dump.c:4649 +#: pg_dump.c:5056 #, c-format -msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer des Operatoren »%s« scheint ungültig zu sein\n" +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "Eigentümer des Operatoren »%s« scheint ungültig zu sein" -#: pg_dump.c:4963 +#: pg_dump.c:5358 #, c-format -msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Operatorklasse »%s« scheint ungültig zu sein\n" +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "Eigentümer der Operatorklasse »%s« scheint ungültig zu sein" -#: pg_dump.c:5050 +#: pg_dump.c:5442 #, c-format -msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Operatorfamilie »%s« scheint ungültig zu sein\n" +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "Eigentümer der Operatorfamilie »%s« scheint ungültig zu sein" -#: pg_dump.c:5217 +#: pg_dump.c:5611 #, c-format -msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Aggregatfunktion »%s« scheint ungültig zu sein\n" +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "Eigentümer der Aggregatfunktion »%s« scheint ungültig zu sein" -#: pg_dump.c:5476 +#: pg_dump.c:5871 #, c-format -msgid "WARNING: owner of function \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Funktion »%s« scheint ungültig zu sein\n" +msgid "owner of function \"%s\" appears to be invalid" +msgstr "Eigentümer der Funktion »%s« scheint ungültig zu sein" -#: pg_dump.c:6258 +#: pg_dump.c:6667 #, c-format -msgid "WARNING: owner of table \"%s\" appears to be invalid\n" -msgstr "WARNUNG: Eigentümer der Tabelle »%s« scheint ungültig zu sein\n" +msgid "owner of table \"%s\" appears to be invalid" +msgstr "Eigentümer der Tabelle »%s« scheint ungültig zu sein" -#: pg_dump.c:6300 pg_dump.c:16539 +#: pg_dump.c:6709 pg_dump.c:17059 #, c-format -msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found\n" -msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von Sequenz mit OID %u nicht gefunden\n" +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von Sequenz mit OID %u nicht gefunden" -#: pg_dump.c:6431 +#: pg_dump.c:6853 #, c-format -msgid "reading indexes for table \"%s.%s\"\n" -msgstr "lese Indexe von Tabelle »%s.%s«\n" +msgid "reading indexes for table \"%s.%s\"" +msgstr "lese Indexe von Tabelle »%s.%s«" -#: pg_dump.c:6712 +#: pg_dump.c:7254 #, c-format -msgid "reading extended statistics for table \"%s.%s\"\n" -msgstr "lese erweiterte Statistiken für Tabelle »%s.%s«\n" +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "lese Fremdschlüssel-Constraints von Tabelle »%s.%s«" -#: pg_dump.c:6795 +#: pg_dump.c:7473 #, c-format -msgid "reading foreign key constraints for table \"%s.%s\"\n" -msgstr "lese Fremdschlüssel-Constraints von Tabelle »%s.%s«\n" +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von pg_rewrite-Eintrag mit OID %u nicht gefunden" -#: pg_dump.c:7019 +#: pg_dump.c:7556 #, c-format -msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n" -msgstr "Sanity-Check fehlgeschlagen, Elterntabelle mit OID %u von pg_rewrite-Eintrag mit OID %u nicht gefunden\n" +msgid "reading triggers for table \"%s.%s\"" +msgstr "lese Trigger von Tabelle »%s.%s«" -#: pg_dump.c:7103 +#: pg_dump.c:7689 #, c-format -msgid "reading triggers for table \"%s.%s\"\n" -msgstr "lese Trigger von Tabelle »%s.%s«\n" +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "Anfrage ergab NULL als Name der Tabelle auf die sich Fremdschlüssel-Trigger »%s« von Tabelle »%s« bezieht (OID der Tabelle: %u)" -#: pg_dump.c:7241 +#: pg_dump.c:8244 #, c-format -msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n" -msgstr "Anfrage ergab NULL als Name der Tabelle auf die sich Fremdschlüssel-Trigger »%s« von Tabelle »%s« bezieht (OID der Tabelle: %u)\n" +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "finde Spalten und Typen von Tabelle »%s.%s«" -#: pg_dump.c:7813 +#: pg_dump.c:8380 #, c-format -msgid "finding the columns and types of table \"%s.%s\"\n" -msgstr "finde Spalten und Typen von Tabelle »%s.%s«\n" +msgid "invalid column numbering in table \"%s\"" +msgstr "ungültige Spaltennummerierung in Tabelle »%s«" -#: pg_dump.c:7978 +#: pg_dump.c:8417 #, c-format -msgid "invalid column numbering in table \"%s\"\n" -msgstr "ungültige Spaltennummerierung in Tabelle »%s«\n" +msgid "finding default expressions of table \"%s.%s\"" +msgstr "finde DEFAULT-Ausdrücke von Tabelle »%s.%s«" -#: pg_dump.c:8014 +#: pg_dump.c:8439 #, c-format -msgid "finding default expressions of table \"%s.%s\"\n" -msgstr "finde DEFAULT-Ausdrücke von Tabelle »%s.%s«\n" +msgid "invalid adnum value %d for table \"%s\"" +msgstr "ungültiger adnum-Wert %d für Tabelle »%s«" -#: pg_dump.c:8037 +#: pg_dump.c:8504 #, c-format -msgid "invalid adnum value %d for table \"%s\"\n" -msgstr "ungültiger adnum-Wert %d für Tabelle »%s«\n" +msgid "finding check constraints for table \"%s.%s\"" +msgstr "finde Check-Constraints für Tabelle »%s.%s«" -#: pg_dump.c:8103 +#: pg_dump.c:8553 #, c-format -msgid "finding check constraints for table \"%s.%s\"\n" -msgstr "finde Check-Constraints für Tabelle »%s.%s«\n" +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden" +msgstr[1] "%d Check-Constraints für Tabelle %s erwartet, aber %d gefunden" -#: pg_dump.c:8152 +#: pg_dump.c:8557 #, c-format -msgid "expected %d check constraint on table \"%s\" but found %d\n" -msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" -msgstr[0] "%d Check-Constraint für Tabelle %s erwartet, aber %d gefunden\n" -msgstr[1] "%d Check-Constraints für Tabelle %s erwartet, aber %d gefunden\n" +msgid "(The system catalogs might be corrupted.)" +msgstr "(Die Systemkataloge sind wahrscheinlich verfälscht.)" -#: pg_dump.c:8156 +#: pg_dump.c:10133 #, c-format -msgid "(The system catalogs might be corrupted.)\n" -msgstr "(Die Systemkataloge sind wahrscheinlich verfälscht.)\n" +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype des Datentypen »%s« scheint ungültig zu sein" -#: pg_dump.c:9714 +#: pg_dump.c:11487 #, c-format -msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" -msgstr "WARNUNG: typtype des Datentypen »%s« scheint ungültig zu sein\n" +msgid "bogus value in proargmodes array" +msgstr "unsinniger Wert in proargmodes-Array" -#: pg_dump.c:11143 +#: pg_dump.c:11859 #, c-format -msgid "WARNING: bogus value in proargmodes array\n" -msgstr "WARNUNG: unsinniger Wert in proargmodes-Array\n" +msgid "could not parse proallargtypes array" +msgstr "konnte proallargtypes-Array nicht interpretieren" -#: pg_dump.c:11469 +#: pg_dump.c:11875 #, c-format -msgid "WARNING: could not parse proallargtypes array\n" -msgstr "WARNUNG: konnte proallargtypes-Array nicht interpretieren\n" +msgid "could not parse proargmodes array" +msgstr "konnte proargmodes-Array nicht interpretieren" -#: pg_dump.c:11485 +#: pg_dump.c:11889 #, c-format -msgid "WARNING: could not parse proargmodes array\n" -msgstr "WARNUNG: konnte proargmodes-Array nicht interpretieren\n" +msgid "could not parse proargnames array" +msgstr "konnte proargnames-Array nicht interpretieren" -#: pg_dump.c:11499 +#: pg_dump.c:11900 #, c-format -msgid "WARNING: could not parse proargnames array\n" -msgstr "WARNUNG: konnte proargnames-Array nicht interpretieren\n" +msgid "could not parse proconfig array" +msgstr "konnte proconfig-Array nicht interpretieren" -#: pg_dump.c:11510 +#: pg_dump.c:11980 #, c-format -msgid "WARNING: could not parse proconfig array\n" -msgstr "WARNUNG: konnte proconfig-Array nicht interpretieren\n" +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "ungültiger provolatile-Wert für Funktion »%s«" -#: pg_dump.c:11581 +#: pg_dump.c:12030 pg_dump.c:14082 #, c-format -msgid "unrecognized provolatile value for function \"%s\"\n" -msgstr "ungültiger provolatile-Wert für Funktion »%s«\n" +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "ungültiger proparallel-Wert für Funktion »%s«" -#: pg_dump.c:11625 pg_dump.c:13623 +#: pg_dump.c:12163 pg_dump.c:12272 pg_dump.c:12279 #, c-format -msgid "unrecognized proparallel value for function \"%s\"\n" -msgstr "ungültiger proparallel-Wert für Funktion »%s«\n" +msgid "could not find function definition for function with OID %u" +msgstr "konnte Funktionsdefinition für Funktion mit OID %u nicht finden" -#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 +#: pg_dump.c:12202 #, c-format -msgid "could not find function definition for function with OID %u\n" -msgstr "konnte Funktionsdefinition für Funktion mit OID %u nicht finden\n" +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "unsinniger Wert in Feld pg_cast.castfunc oder pg_cast.castmethod" -#: pg_dump.c:11778 +#: pg_dump.c:12205 #, c-format -msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" -msgstr "WARNUNG: unsinniger Wert in Feld pg_cast.castfunc oder pg_cast.castmethod\n" +msgid "bogus value in pg_cast.castmethod field" +msgstr "unsinniger Wert in Feld pg_cast.castmethod" -#: pg_dump.c:11781 +#: pg_dump.c:12298 #, c-format -msgid "WARNING: bogus value in pg_cast.castmethod field\n" -msgstr "WARNUNG: unsinniger Wert in Feld pg_cast.castmethod\n" +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "unsinnige Transformationsdefinition, mindestens eins von trffromsql und trftosql sollte nicht null sein" -#: pg_dump.c:11871 +#: pg_dump.c:12315 #, c-format -msgid "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n" -msgstr "WARNUNG: unsinnige Transformationsdefinition, mindestens eins von trffromsql und trftosql sollte nicht null sein\n" +msgid "bogus value in pg_transform.trffromsql field" +msgstr "unsinniger Wert in Feld pg_transform.trffromsql" -#: pg_dump.c:11888 +#: pg_dump.c:12336 #, c-format -msgid "WARNING: bogus value in pg_transform.trffromsql field\n" -msgstr "WARNUNG: unsinniger Wert in Feld pg_transform.trffromsql\n" +msgid "bogus value in pg_transform.trftosql field" +msgstr "unsinniger Wert in Feld pg_transform.trftosql" -#: pg_dump.c:11909 +#: pg_dump.c:12652 #, c-format -msgid "WARNING: bogus value in pg_transform.trftosql field\n" -msgstr "WARNUNG: unsinniger Wert in Feld pg_transform.trftosql\n" +msgid "could not find operator with OID %s" +msgstr "konnte Operator mit OID %s nicht finden" -#: pg_dump.c:12305 +#: pg_dump.c:12720 #, c-format -msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" -msgstr "WARNUNG: ungültiger Typ »%c« für Zugriffsmethode »%s«\n" +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "ungültiger Typ »%c« für Zugriffsmethode »%s«" -#: pg_dump.c:13086 +#: pg_dump.c:13474 #, c-format msgid "unrecognized collation provider: %s\n" msgstr "unbekannter Sortierfolgen-Provider: %s\n" -#: pg_dump.c:13533 +#: pg_dump.c:13946 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "Aggregatfunktion %s konnte für diese Datenbankversion nicht korrekt ausgegeben werden; ignoriert" + +#: pg_dump.c:14001 #, c-format -msgid "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n" -msgstr "WARNUNG: Aggregatfunktion %s konnte für diese Datenbankversion nicht korrekt ausgegeben werden - ignoriert\n" +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "unbekannter aggfinalmodify-Wert für Aggregat »%s«" -#: pg_dump.c:14389 +#: pg_dump.c:14057 #, c-format -msgid "unrecognized object type in default privileges: %d\n" -msgstr "unbekannter Objekttyp in den Vorgabeprivilegien: %d\n" +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "unbekannter aggmfinalmodify-Wert für Aggregat »%s«" -#: pg_dump.c:14407 +#: pg_dump.c:14779 #, c-format -msgid "could not parse default ACL list (%s)\n" -msgstr "konnte Vorgabe-ACL-Liste (%s) nicht interpretieren\n" +msgid "unrecognized object type in default privileges: %d" +msgstr "unbekannter Objekttyp in den Vorgabeprivilegien: %d" -#: pg_dump.c:14488 +#: pg_dump.c:14797 #, c-format -msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "konnte initiale GRANT-ACL-Liste (%s) oder initiale REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren\n" +msgid "could not parse default ACL list (%s)" +msgstr "konnte Vorgabe-ACL-Liste (%s) nicht interpretieren" -#: pg_dump.c:14496 +#: pg_dump.c:14877 #, c-format -msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "konnte GRANT-ACL-Liste (%s) oder REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren\n" +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "konnte initiale GRANT-ACL-Liste (%s) oder initiale REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren" -#: pg_dump.c:14971 +#: pg_dump.c:14885 #, c-format -msgid "query to obtain definition of view \"%s\" returned no data\n" -msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte keine Daten\n" +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "konnte GRANT-ACL-Liste (%s) oder REVOKE-ACL-Liste (%s) für Objekt »%s« (%s) nicht interpretieren" -#: pg_dump.c:14974 +#: pg_dump.c:15384 #, c-format -msgid "query to obtain definition of view \"%s\" returned more than one definition\n" -msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte mehr als eine Definition\n" +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte keine Daten" -#: pg_dump.c:14981 +#: pg_dump.c:15387 #, c-format -msgid "definition of view \"%s\" appears to be empty (length zero)\n" -msgstr "Definition der Sicht »%s« scheint leer zu sein (Länge null)\n" +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "Anfrage um die Definition der Sicht »%s« zu ermitteln lieferte mehr als eine Definition" -#: pg_dump.c:15210 +#: pg_dump.c:15394 #, c-format -msgid "invalid number of parents %d for table \"%s\"\n" -msgstr "ungültige Anzahl Eltern %d für Tabelle »%s«\n" +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "Definition der Sicht »%s« scheint leer zu sein (Länge null)" -#: pg_dump.c:15857 +#: pg_dump.c:15476 #, c-format -msgid "invalid column number %d for table \"%s\"\n" -msgstr "ungültige Spaltennummer %d in Tabelle »%s«\n" +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS wird nicht mehr unterstützt (Tabelle »%s«)" -#: pg_dump.c:16041 +#: pg_dump.c:15603 #, c-format -msgid "missing index for constraint \"%s\"\n" -msgstr "fehlender Index für Constraint »%s«\n" +msgid "invalid number of parents %d for table \"%s\"" +msgstr "ungültige Anzahl Eltern %d für Tabelle »%s«" -#: pg_dump.c:16244 +#: pg_dump.c:16290 #, c-format -msgid "unrecognized constraint type: %c\n" -msgstr "unbekannter Constraint-Typ: %c\n" +msgid "invalid column number %d for table \"%s\"" +msgstr "ungültige Spaltennummer %d in Tabelle »%s«" -#: pg_dump.c:16381 pg_dump.c:16607 +#: pg_dump.c:16552 #, c-format -msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" -msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)\n" -msgstr[0] "Anfrage nach Daten der Sequenz %s ergab %d Zeile (erwartete 1)\n" -msgstr[1] "Anfrage nach Daten der Sequenz %s ergab %d Zeilen (erwartete 1)\n" +msgid "missing index for constraint \"%s\"" +msgstr "fehlender Index für Constraint »%s«" -#: pg_dump.c:16705 +#: pg_dump.c:16772 #, c-format -msgid "unexpected tgtype value: %d\n" -msgstr "unerwarteter tgtype-Wert: %d\n" +msgid "unrecognized constraint type: %c" +msgstr "unbekannter Constraint-Typ: %c" -#: pg_dump.c:16779 +#: pg_dump.c:16904 pg_dump.c:17124 #, c-format -msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" -msgstr "fehlerhafte Argumentzeichenkette (%s) für Trigger »%s« von Tabelle »%s«\n" +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "Anfrage nach Daten der Sequenz %s ergab %d Zeile (erwartete 1)" +msgstr[1] "Anfrage nach Daten der Sequenz %s ergab %d Zeilen (erwartete 1)" -#: pg_dump.c:17010 +#: pg_dump.c:16938 #, c-format -msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n" -msgstr "Anfrage nach Regel »%s« der Tabelle »%s« fehlgeschlagen: falsche Anzahl Zeilen zurückgegeben\n" +msgid "unrecognized sequence type: %s" +msgstr "unbekannter Sequenztyp: %s" -#: pg_dump.c:17405 +#: pg_dump.c:17220 #, c-format -msgid "reading dependency data\n" -msgstr "lese Abhängigkeitsdaten\n" +msgid "unexpected tgtype value: %d" +msgstr "unerwarteter tgtype-Wert: %d" -#: pg_dump.c:17870 +#: pg_dump.c:17294 #, c-format -msgid "WARNING: could not parse reloptions array\n" -msgstr "WARNUNG: konnte reloptions-Array nicht interpretieren\n" +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "fehlerhafte Argumentzeichenkette (%s) für Trigger »%s« von Tabelle »%s«" -#. translator: this is a module name -#: pg_dump_sort.c:25 -msgid "sorter" -msgstr "Sortierer" +#: pg_dump.c:17523 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "Anfrage nach Regel »%s« der Tabelle »%s« fehlgeschlagen: falsche Anzahl Zeilen zurückgegeben" -#: pg_dump_sort.c:413 +#: pg_dump.c:17685 #, c-format -msgid "invalid dumpId %d\n" -msgstr "ungültige dumpId %d\n" +msgid "could not find referenced extension %u" +msgstr "konnte referenzierte Erweiterung %u nicht finden" -#: pg_dump_sort.c:419 +#: pg_dump.c:17897 #, c-format -msgid "invalid dependency %d\n" -msgstr "ungültige Abhängigkeit %d\n" +msgid "reading dependency data" +msgstr "lese Abhängigkeitsdaten" + +#: pg_dump.c:17952 +#, fuzzy, c-format +#| msgid "could not create large object %u: %s" +msgid "no referencing object %u %u" +msgstr "konnte Large Object %u nicht erstellen: %s" -#: pg_dump_sort.c:652 +#: pg_dump.c:17963 +#, fuzzy, c-format +#| msgid "could not create large object %u: %s" +msgid "no referenced object %u %u" +msgstr "konnte Large Object %u nicht erstellen: %s" + +#: pg_dump.c:18331 #, c-format -msgid "could not identify dependency loop\n" -msgstr "konnte Abhängigkeitsschleife nicht bestimmen\n" +msgid "could not parse reloptions array" +msgstr "konnte reloptions-Array nicht interpretieren" -#: pg_dump_sort.c:1175 +#: pg_dump_sort.c:327 #, c-format -msgid "NOTICE: there are circular foreign-key constraints on this table:\n" -msgid_plural "NOTICE: there are circular foreign-key constraints among these tables:\n" -msgstr[0] "HINWEIS: Es gibt zirkuläre Fremdschlüssel-Constraints für diese Tabelle:\n" -msgstr[1] "HINWEIS: Es gibt zirkuläre Fremdschlüssel-Constraints zwischen diesen Tabellen:\n" +msgid "invalid dumpId %d" +msgstr "ungültige dumpId %d" -#: pg_dump_sort.c:1179 pg_dump_sort.c:1199 +#: pg_dump_sort.c:333 #, c-format -msgid " %s\n" -msgstr " %s\n" +msgid "invalid dependency %d" +msgstr "ungültige Abhängigkeit %d" -#: pg_dump_sort.c:1180 +#: pg_dump_sort.c:566 #, c-format -msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.\n" -msgstr "Möglicherweise kann der Dump nur wiederhergestellt werden, wenn --disable-triggers verwendet wird oder die Constraints vorübergehend entfernt werden.\n" +msgid "could not identify dependency loop" +msgstr "konnte Abhängigkeitsschleife nicht bestimmen" -#: pg_dump_sort.c:1181 +#: pg_dump_sort.c:1129 #, c-format -msgid "Consider using a full dump instead of a --data-only dump to avoid this problem.\n" -msgstr "Führen Sie einen vollen Dump statt eines Dumps mit --data-only durch, um dieses Problem zu vermeiden.\n" +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "Es gibt zirkuläre Fremdschlüssel-Constraints für diese Tabelle:" +msgstr[1] "Es gibt zirkuläre Fremdschlüssel-Constraints zwischen diesen Tabellen:" -#: pg_dump_sort.c:1193 +#: pg_dump_sort.c:1133 pg_dump_sort.c:1153 #, c-format -msgid "WARNING: could not resolve dependency loop among these items:\n" -msgstr "WARNUNG: konnte Abhängigkeitsschleife zwischen diesen Elementen nicht auflösen:\n" +msgid " %s" +msgstr " %s" -#: pg_dumpall.c:189 +#: pg_dump_sort.c:1134 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Möglicherweise kann der Dump nur wiederhergestellt werden, wenn --disable-triggers verwendet wird oder die Constraints vorübergehend entfernt werden." + +#: pg_dump_sort.c:1135 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Führen Sie einen vollen Dump statt eines Dumps mit --data-only durch, um dieses Problem zu vermeiden." + +#: pg_dump_sort.c:1147 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "konnte Abhängigkeitsschleife zwischen diesen Elementen nicht auflösen:" + +#: pg_dumpall.c:199 #, c-format msgid "" "The program \"pg_dump\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Das Programm »pg_dump« wird von %s benötigt, aber wurde nicht im\n" "selben Verzeichnis wie »%s« gefunden.\n" -"Prüfen Sie Ihre Installation.\n" +"Prüfen Sie Ihre Installation." -#: pg_dumpall.c:196 +#: pg_dumpall.c:204 #, c-format msgid "" "The program \"pg_dump\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Das Programm »pg_dump« wurde von »%s« gefunden,\n" "aber war nicht die gleiche Version wie %s.\n" -"Prüfen Sie Ihre Installation.\n" +"Prüfen Sie Ihre Installation." -#: pg_dumpall.c:331 +#: pg_dumpall.c:351 #, c-format -msgid "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" -msgstr "%s: Optionen -g/--globals-only und -r/--roles-only können nicht zusammen verwendet werden\n" +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only" +msgstr "Option --exclude-database kann nicht zusammen mit -g/--globals-only, -r/--roles-only oder -t/--tablesspaces-only verwendet werden" -#: pg_dumpall.c:340 +#: pg_dumpall.c:360 #, c-format -msgid "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: Optionen -g/--globals-only und -t/--tablespaces-only können nicht zusammen verwendet werden\n" +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "Optionen -g/--globals-only und -r/--roles-only können nicht zusammen verwendet werden" -#: pg_dumpall.c:349 pg_restore.c:367 +#: pg_dumpall.c:368 #, c-format -msgid "%s: option --if-exists requires option -c/--clean\n" -msgstr "%s: Option --if-exists benötigt Option -c/--clean\n" +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "Optionen -g/--globals-only und -t/--tablespaces-only können nicht zusammen verwendet werden" -#: pg_dumpall.c:356 +#: pg_dumpall.c:382 #, c-format -msgid "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: Optionen -r/--roles-only und -t/--tablespaces-only können nicht zusammen verwendet werden\n" +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "Optionen -r/--roles-only und -t/--tablespaces-only können nicht zusammen verwendet werden" -#: pg_dumpall.c:412 pg_dumpall.c:1983 +#: pg_dumpall.c:443 pg_dumpall.c:1747 #, c-format -msgid "%s: could not connect to database \"%s\"\n" -msgstr "%s: konnte nicht mit der Datenbank »%s« verbinden\n" +msgid "could not connect to database \"%s\"" +msgstr "konnte nicht mit der Datenbank »%s« verbinden" -#: pg_dumpall.c:427 +#: pg_dumpall.c:457 #, c-format msgid "" -"%s: could not connect to databases \"postgres\" or \"template1\"\n" -"Please specify an alternative database.\n" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." msgstr "" -"%s: konnte nicht mit Datenbank »postgres« oder »template1« verbinden\n" -"Bitte geben Sie eine alternative Datenbank an.\n" +"konnte nicht mit Datenbank »postgres« oder »template1« verbinden\n" +"Bitte geben Sie eine alternative Datenbank an." -#: pg_dumpall.c:444 +#: pg_dumpall.c:479 #, c-format -msgid "%s: could not open the output file \"%s\": %s\n" -msgstr "%s: konnte die Ausgabedatei »%s« nicht öffnen: %s\n" +msgid "could not open the output file \"%s\": %m" +msgstr "konnte die Ausgabedatei »%s« nicht öffnen: %m" -#: pg_dumpall.c:574 +#: pg_dumpall.c:611 #, c-format msgid "" "%s extracts a PostgreSQL database cluster into an SQL script file.\n" @@ -2318,68 +2275,73 @@ msgstr "" "%s gibt einen PostgreSQL-Datenbankcluster in eine SQL-Skriptdatei aus.\n" "\n" -#: pg_dumpall.c:576 +#: pg_dumpall.c:613 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPTION]...\n" -#: pg_dumpall.c:579 +#: pg_dumpall.c:616 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=DATEINAME Name der Ausgabedatei\n" -#: pg_dumpall.c:586 +#: pg_dumpall.c:623 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean Datenbanken vor der Wiedererstellung löschen\n" -#: pg_dumpall.c:587 +#: pg_dumpall.c:625 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr " -g, --globals-only nur globale Objekte ausgeben, keine Datenbanken\n" -#: pg_dumpall.c:589 pg_restore.c:472 +#: pg_dumpall.c:626 pg_restore.c:489 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr "" " -O, --no-owner Wiederherstellung der Objekteigentümerschaft\n" " auslassen\n" -#: pg_dumpall.c:590 +#: pg_dumpall.c:627 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr "" " -r, --roles-only nur Rollen ausgeben, keine Datenbanken oder\n" " Tablespaces\n" -#: pg_dumpall.c:592 +#: pg_dumpall.c:629 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr " -S, --superuser=NAME Superusername für den Dump\n" -#: pg_dumpall.c:593 +#: pg_dumpall.c:630 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr "" " -t, --tablespaces-only nur Tablespaces ausgeben, keine Datenbanken oder\n" " Rollen\n" -#: pg_dumpall.c:602 +#: pg_dumpall.c:636 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr "" + +#: pg_dumpall.c:643 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords Rollenpasswörter nicht mit ausgeben\n" -#: pg_dumpall.c:614 +#: pg_dumpall.c:656 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=VERBDG mit angegebenen Verbindungsparametern verbinden\n" -#: pg_dumpall.c:616 +#: pg_dumpall.c:658 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=DBNAME alternative Standarddatenbank\n" -#: pg_dumpall.c:623 +#: pg_dumpall.c:665 #, c-format msgid "" "\n" @@ -2392,112 +2354,98 @@ msgstr "" "Standardausgabe geschrieben.\n" "\n" -#: pg_dumpall.c:828 -#, c-format -msgid "%s: role name starting with \"pg_\" skipped (%s)\n" -msgstr "%s: mit »pg_« anfangender Rollenname übersprungen (%s)\n" - -#: pg_dumpall.c:1208 +#: pg_dumpall.c:870 #, c-format -msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" -msgstr "%s: konnte ACL-Zeichenkette (%s) für Tablespace »%s« nicht interpretieren\n" +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "mit »pg_« anfangender Rollenname übersprungen (%s)" -#: pg_dumpall.c:1525 +#: pg_dumpall.c:1271 #, c-format -msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" -msgstr "%s: konnte ACL-Zeichenkette (%s) für Datenbank »%s« nicht interpretieren\n" +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "konnte ACL-Zeichenkette (%s) für Tablespace »%s« nicht interpretieren" -#: pg_dumpall.c:1739 -#, c-format -msgid "%s: dumping database \"%s\"...\n" +#: pg_dumpall.c:1488 +#, fuzzy, c-format +#| msgid "%s: dumping database \"%s\"...\n" +msgid "excluding database \"%s\"..." msgstr "%s: Ausgabe der Datenbank »%s«...\n" -#: pg_dumpall.c:1763 -#, c-format -msgid "%s: pg_dump failed on database \"%s\", exiting\n" -msgstr "%s: pg_dump für Datenbank »%s« fehlgeschlagen; beende\n" - -#: pg_dumpall.c:1772 +#: pg_dumpall.c:1492 #, c-format -msgid "%s: could not re-open the output file \"%s\": %s\n" -msgstr "%s: konnte die Ausgabedatei »%s« nicht neu öffnen: %s\n" +msgid "dumping database \"%s\"..." +msgstr "Ausgabe der Datenbank »%s«..." -#: pg_dumpall.c:1817 +#: pg_dumpall.c:1524 #, c-format -msgid "%s: running \"%s\"\n" -msgstr "%s: führe »%s« aus\n" +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump für Datenbank »%s« fehlgeschlagen; beende" -#: pg_dumpall.c:2006 +#: pg_dumpall.c:1533 #, c-format -msgid "%s: could not connect to database \"%s\": %s\n" -msgstr "%s: konnte nicht mit der Datenbank »%s« verbinden: %s\n" +msgid "could not re-open the output file \"%s\": %m" +msgstr "konnte die Ausgabedatei »%s« nicht neu öffnen: %m" -#: pg_dumpall.c:2036 +#: pg_dumpall.c:1577 #, c-format -msgid "%s: could not get server version\n" -msgstr "%s: konnte Version des Servers nicht ermitteln\n" +msgid "running \"%s\"" +msgstr "führe »%s« aus" -#: pg_dumpall.c:2042 +#: pg_dumpall.c:1768 #, c-format -msgid "%s: could not parse server version \"%s\"\n" -msgstr "%s: konnte Versionszeichenkette »%s« nicht entziffern\n" +msgid "could not connect to database \"%s\": %s" +msgstr "konnte nicht mit Datenbank »%s« verbinden: %s" -#: pg_dumpall.c:2118 pg_dumpall.c:2144 +#: pg_dumpall.c:1798 #, c-format -msgid "%s: executing %s\n" -msgstr "%s: führe %s aus\n" +msgid "could not get server version" +msgstr "konnte Version des Servers nicht ermitteln" -#: pg_dumpall.c:2124 pg_dumpall.c:2150 +#: pg_dumpall.c:1804 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: Anfrage fehlgeschlagen: %s" +msgid "could not parse server version \"%s\"" +msgstr "konnte Versionszeichenkette »%s« nicht entziffern" -#: pg_dumpall.c:2126 pg_dumpall.c:2152 +#: pg_dumpall.c:1876 pg_dumpall.c:1899 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: Anfrage war: %s\n" +msgid "executing %s" +msgstr "führe %s aus" -#: pg_restore.c:309 +#: pg_restore.c:312 #, c-format -msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" -msgstr "%s: Optionen -d/--dbname und -f/--file können nicht zusammen verwendet werden\n" +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "entweder -d/--dbname oder -f/--file muss angegeben werden" -#: pg_restore.c:320 +#: pg_restore.c:321 #, c-format -msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "%s: Optionen -s/--schema-only und -a/--data-only können nicht zusammen verwendet werden\n" +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "Optionen -d/--dbname und -f/--file können nicht zusammen verwendet werden" -#: pg_restore.c:327 +#: pg_restore.c:347 #, c-format -msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "%s: Optionen -c/--clean und -a/--data-only können nicht zusammen verwendet werden\n" +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "Optionen -C/--create und -1/--single-transaction können nicht zusammen verwendet werden" -#: pg_restore.c:334 +#: pg_restore.c:361 #, c-format -msgid "%s: invalid number of parallel jobs\n" -msgstr "%s: ungültige Anzahl paralleler Jobs\n" +msgid "maximum number of parallel jobs is %d" +msgstr "maximale Anzahl paralleler Jobs ist %d" -#: pg_restore.c:342 +#: pg_restore.c:370 #, c-format -msgid "%s: maximum number of parallel jobs is %d\n" -msgstr "%s: maximale Anzahl paralleler Jobs ist %d\n" +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "--single-transaction und mehrere Jobs können nicht zusammen verwendet werden" -#: pg_restore.c:351 +#: pg_restore.c:412 #, c-format -msgid "%s: cannot specify both --single-transaction and multiple jobs\n" -msgstr "%s: --single-transaction und mehrere Jobs können nicht zusammen verwendet werden\n" +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "unbekanntes Archivformat »%s«; bitte »c«, »d« oder »t« angeben" -#: pg_restore.c:394 +#: pg_restore.c:452 #, c-format -msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" -msgstr "unbekanntes Archivformat »%s«; bitte »c«, »d« oder »t« angeben\n" +msgid "errors ignored on restore: %d" +msgstr "bei Wiederherstellung ignorierte Fehler: %d" -#: pg_restore.c:434 -#, c-format -msgid "WARNING: errors ignored on restore: %d\n" -msgstr "WARNUNG: bei Wiederherstellung ignorierte Fehler: %d\n" - -#: pg_restore.c:448 +#: pg_restore.c:465 #, c-format msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" @@ -2507,47 +2455,47 @@ msgstr "" "gesichert wurde.\n" "\n" -#: pg_restore.c:450 +#: pg_restore.c:467 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [OPTION]... [DATEI]\n" -#: pg_restore.c:453 +#: pg_restore.c:470 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NAME mit angegebener Datenbank verbinden\n" -#: pg_restore.c:454 +#: pg_restore.c:471 #, c-format -msgid " -f, --file=FILENAME output file name\n" -msgstr " -f, --file=DATEINAME Name der Ausgabedatei\n" +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=DATEINAME Name der Ausgabedatei (- für stdout)\n" -#: pg_restore.c:455 +#: pg_restore.c:472 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t Format der Backup-Datei (sollte automatisch gehen)\n" -#: pg_restore.c:456 +#: pg_restore.c:473 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list Inhaltsverzeichnis für dieses Archiv anzeigen\n" -#: pg_restore.c:457 +#: pg_restore.c:474 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose »Verbose«-Modus\n" -#: pg_restore.c:458 +#: pg_restore.c:475 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_restore.c:459 +#: pg_restore.c:476 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_restore.c:461 +#: pg_restore.c:478 #, c-format msgid "" "\n" @@ -2556,34 +2504,34 @@ msgstr "" "\n" "Optionen die die Wiederherstellung kontrollieren:\n" -#: pg_restore.c:462 +#: pg_restore.c:479 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only nur Daten, nicht das Schema, wiederherstellen\n" -#: pg_restore.c:464 +#: pg_restore.c:481 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create Zieldatenbank erzeugen\n" -#: pg_restore.c:465 +#: pg_restore.c:482 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr " -e, --exit-on-error bei Fehler beenden, Voreinstellung ist fortsetzen\n" -#: pg_restore.c:466 +#: pg_restore.c:483 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAME benannten Index wiederherstellen\n" -#: pg_restore.c:467 +#: pg_restore.c:484 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr "" " -j, --jobs=NUM so viele parallele Jobs zur Wiederherstellung\n" " verwenden\n" -#: pg_restore.c:468 +#: pg_restore.c:485 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -2593,59 +2541,64 @@ msgstr "" " Inhaltsverzeichnis aus dieser Datei zur Auswahl oder\n" " Sortierung der Ausgabe verwenden\n" -#: pg_restore.c:470 +#: pg_restore.c:487 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME nur Objekte in diesem Schema wiederherstellen\n" -#: pg_restore.c:471 +#: pg_restore.c:488 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, ---exclude-schema=NAME Objekte in diesem Schema nicht wiederherstellen\n" -#: pg_restore.c:473 +#: pg_restore.c:490 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NAME(args) benannte Funktion wiederherstellen\n" -#: pg_restore.c:474 +#: pg_restore.c:491 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only nur das Schema, nicht die Daten, wiederherstellen\n" -#: pg_restore.c:475 +#: pg_restore.c:492 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr " -S, --superuser=NAME Name des Superusers, um Trigger auszuschalten\n" -#: pg_restore.c:476 +#: pg_restore.c:493 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr "" " -t, --table=NAME benannte Relation (Tabelle, Sicht, usw.)\n" " wiederherstellen\n" -#: pg_restore.c:477 +#: pg_restore.c:494 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAME benannten Trigger wiederherstellen\n" -#: pg_restore.c:478 +#: pg_restore.c:495 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges Wiederherstellung der Zugriffsprivilegien auslassen\n" -#: pg_restore.c:479 +#: pg_restore.c:496 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction Wiederherstellung als eine einzige Transaktion\n" -#: pg_restore.c:481 +#: pg_restore.c:498 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security Sicherheit auf Zeilenebene einschalten\n" -#: pg_restore.c:483 +#: pg_restore.c:500 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments Kommentare nicht wiederherstellen\n" + +#: pg_restore.c:501 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" @@ -2654,50 +2607,50 @@ msgstr "" " --no-data-for-failed-tables Daten für Tabellen, die nicht erzeugt werden\n" " konnten, nicht wiederherstellen\n" -#: pg_restore.c:485 +#: pg_restore.c:503 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications Publikationen nicht wiederherstellen\n" -#: pg_restore.c:486 +#: pg_restore.c:504 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels Security-Labels nicht wiederherstellen\n" -#: pg_restore.c:487 +#: pg_restore.c:505 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions Subskriptionen nicht wiederherstellen\n" -#: pg_restore.c:488 +#: pg_restore.c:506 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces Tablespace-Zuordnungen nicht wiederherstellen\n" -#: pg_restore.c:489 +#: pg_restore.c:507 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr "" " --section=ABSCHNITT angegebenen Abschnitt wiederherstellen (pre-data,\n" " data oder post-data)\n" -#: pg_restore.c:502 +#: pg_restore.c:520 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLLENNAME vor der Wiederherstellung SET ROLE ausführen\n" -#: pg_restore.c:504 +#: pg_restore.c:522 #, c-format msgid "" "\n" -"The options -I, -n, -P, -t, -T, and --section can be combined and specified\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" "multiple times to select multiple objects.\n" msgstr "" "\n" -"Die Optionen -I, -n, -P, -t, -T und --section können kombiniert und mehrfach\n" +"Die Optionen -I, -n, -N, -P, -t, -T und --section können kombiniert und mehrfach\n" "angegeben werden, um mehrere Objekte auszuwählen.\n" -#: pg_restore.c:507 +#: pg_restore.c:525 #, c-format msgid "" "\n" @@ -2707,3 +2660,72 @@ msgstr "" "\n" "Wenn keine Eingabedatei angegeben ist, wird die Standardeingabe verwendet.\n" "\n" + +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "Inhaltsverzeichniseintrag %s bei %s (Länge %s, Prüfsumme %d)\n" + +#~ msgid "skipping tar member %s\n" +#~ msgstr "Tar-Mitglied %s übersprungen\n" + +#~ msgid "now at file position %s\n" +#~ msgstr "jetzt bei Dateiposition %s\n" + +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "bewege Position von %s auf nächstes Mitglied bei Position %s\n" + +#~ msgid "tar archiver" +#~ msgstr "Tar-Archivierer" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "konnte Verzeichnis »%s« nicht erzeugen: %s\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "konnte Verzeichnis »%s« nicht schließen: %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "konnte Verzeichnis »%s« nicht lesen: %s\n" + +#~ msgid "directory archiver" +#~ msgstr "Verzeichnis-Archivierer" + +#~ msgid "COPY failed for table \"%s\": %s" +#~ msgstr "COPY fehlgeschlagen für Tabelle »%s«: %s" + +#~ msgid "%s: %s Command was: %s\n" +#~ msgstr "%s: %s Die Anweisung war: %s\n" + +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "reduziere Abhängigkeiten für %d\n" + +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "übertrage Abhängigkeit %d -> %d an %d\n" + +#~ msgid "no item ready\n" +#~ msgstr "kein Element bereit\n" + +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "Eintritt in restore_toc_entries_postfork\n" + +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "Eintritt in restore_toc_entries_parallel\n" + +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "Eintritt in restore_toc_entries_prefork\n" + +#~ msgid "could not set default_tablespace to %s: %s" +#~ msgstr "konnte default_tablespace nicht auf »%s« setzen: %s" + +#~ msgid "could not set search_path to \"%s\": %s" +#~ msgstr "konnte search_path nicht auf »%s« setzen: %s" + +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "Inhaltsverzeichniseintrag %d (ID %d) von %s %s gelesen\n" + +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "erstelle AH für %s, Format %d\n" + +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "versuche Archivformat zu ermitteln\n" + +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "-C und -1 sind inkompatible Optionen\n" diff --git a/src/bin/pg_dump/po/es.po b/src/bin/pg_dump/po/es.po index 48a14621f08..2573af30ba9 100644 --- a/src/bin/pg_dump/po/es.po +++ b/src/bin/pg_dump/po/es.po @@ -1,61 +1,80 @@ # Spanish message translation file for pg_dump # -# Copyright (C) 2003-2013 PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Manuel Sugawara , 2003. # Alvaro Herrera , 2004-2007, 2009-2013 -# Carlos Chapi , 2014 +# Carlos Chapi , 2014, 2017 # msgid "" msgstr "" -"Project-Id-Version: pg_dump (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-12 11:12-0500\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL Español \n" +"Project-Id-Version: pg_dump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:15+0000\n" +"PO-Revision-Date: 2019-06-06 17:24-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "fatal: " +msgstr "fatal: " -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar el directorio a «%s»: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "pclose failed: %m" +msgstr "pclose falló: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "memoria agotada" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -83,1369 +102,1227 @@ msgstr "orden no encontrada" msgid "child process exited with exit code %d" msgstr "el proceso hijo terminó con código de salida %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "el proceso hijo fue terminado por una excepción 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "el proceso hijo fue terminado por una señal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "el proceso hijo fue terminado por una señal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "el proceso hijo terminó con código no reconocido %d" -#: common.c:121 +#: common.c:123 #, c-format -msgid "reading extensions\n" -msgstr "leyendo las extensiones\n" +msgid "reading extensions" +msgstr "leyendo las extensiones" -#: common.c:126 +#: common.c:127 #, c-format -msgid "identifying extension members\n" -msgstr "identificando miembros de extensión\n" +msgid "identifying extension members" +msgstr "identificando miembros de extensión" #: common.c:130 #, c-format -msgid "reading schemas\n" -msgstr "leyendo esquemas\n" +msgid "reading schemas" +msgstr "leyendo esquemas" -#: common.c:141 +#: common.c:140 #, c-format -msgid "reading user-defined tables\n" -msgstr "leyendo las tablas definidas por el usuario\n" +msgid "reading user-defined tables" +msgstr "leyendo las tablas definidas por el usuario" -#: common.c:149 +#: common.c:147 #, c-format -msgid "reading user-defined functions\n" -msgstr "leyendo las funciones definidas por el usuario\n" +msgid "reading user-defined functions" +msgstr "leyendo las funciones definidas por el usuario" -#: common.c:155 +#: common.c:152 #, c-format -msgid "reading user-defined types\n" -msgstr "leyendo los tipos definidos por el usuario\n" +msgid "reading user-defined types" +msgstr "leyendo los tipos definidos por el usuario" -#: common.c:161 +#: common.c:157 #, c-format -msgid "reading procedural languages\n" -msgstr "leyendo los lenguajes procedurales\n" +msgid "reading procedural languages" +msgstr "leyendo los lenguajes procedurales" -#: common.c:165 +#: common.c:160 #, c-format -msgid "reading user-defined aggregate functions\n" -msgstr "leyendo las funciones de agregación definidas por el usuario\n" +msgid "reading user-defined aggregate functions" +msgstr "leyendo las funciones de agregación definidas por el usuario" -#: common.c:169 +#: common.c:163 #, c-format -msgid "reading user-defined operators\n" -msgstr "leyendo los operadores definidos por el usuario\n" +msgid "reading user-defined operators" +msgstr "leyendo los operadores definidos por el usuario" -#: common.c:174 +#: common.c:167 #, c-format -msgid "reading user-defined access methods\n" -msgstr "leyendo los métodos de acceso definidos por el usuario\n" +msgid "reading user-defined access methods" +msgstr "leyendo los métodos de acceso definidos por el usuario" -#: common.c:178 +#: common.c:170 #, c-format -msgid "reading user-defined operator classes\n" -msgstr "leyendo las clases de operadores definidos por el usuario\n" +msgid "reading user-defined operator classes" +msgstr "leyendo las clases de operadores definidos por el usuario" -#: common.c:182 +#: common.c:173 #, c-format -msgid "reading user-defined operator families\n" -msgstr "leyendo las familias de operadores definidas por el usuario\n" +msgid "reading user-defined operator families" +msgstr "leyendo las familias de operadores definidas por el usuario" -#: common.c:186 +#: common.c:176 #, c-format -msgid "reading user-defined text search parsers\n" -msgstr "" -"leyendo los procesadores (parsers) de búsqueda en texto definidos\n" -"por el usuario\n" +msgid "reading user-defined text search parsers" +msgstr "leyendo los procesadores (parsers) de búsqueda en texto definidos por el usuario" -#: common.c:190 +#: common.c:179 #, c-format -msgid "reading user-defined text search templates\n" -msgstr "leyendo las plantillas de búsqueda en texto definidas por el usuario\n" +msgid "reading user-defined text search templates" +msgstr "leyendo las plantillas de búsqueda en texto definidas por el usuario" -#: common.c:194 +#: common.c:182 #, c-format -msgid "reading user-defined text search dictionaries\n" -msgstr "leyendo los diccionarios de búsqueda en texto definidos por el usuario\n" +msgid "reading user-defined text search dictionaries" +msgstr "leyendo los diccionarios de búsqueda en texto definidos por el usuario" -#: common.c:198 +#: common.c:185 #, c-format -msgid "reading user-defined text search configurations\n" -msgstr "leyendo las configuraciones de búsqueda en texto definidas por el usuario\n" +msgid "reading user-defined text search configurations" +msgstr "leyendo las configuraciones de búsqueda en texto definidas por el usuario" -#: common.c:202 +#: common.c:188 #, c-format -msgid "reading user-defined foreign-data wrappers\n" -msgstr "leyendo los conectores de datos externos definidos por el usuario\n" +msgid "reading user-defined foreign-data wrappers" +msgstr "leyendo los conectores de datos externos definidos por el usuario" -#: common.c:206 +#: common.c:191 #, c-format -msgid "reading user-defined foreign servers\n" -msgstr "leyendo los servidores foráneos definidas por el usuario\n" +msgid "reading user-defined foreign servers" +msgstr "leyendo los servidores foráneos definidas por el usuario" -#: common.c:210 +#: common.c:194 #, c-format -msgid "reading default privileges\n" -msgstr "leyendo los privilegios por omisión\n" +msgid "reading default privileges" +msgstr "leyendo los privilegios por omisión" -#: common.c:214 +#: common.c:197 #, c-format -msgid "reading user-defined collations\n" -msgstr "leyendo los ordenamientos definidos por el usuario\n" +msgid "reading user-defined collations" +msgstr "leyendo los ordenamientos definidos por el usuario" -#: common.c:219 +#: common.c:201 #, c-format -msgid "reading user-defined conversions\n" -msgstr "leyendo las conversiones definidas por el usuario\n" +msgid "reading user-defined conversions" +msgstr "leyendo las conversiones definidas por el usuario" -#: common.c:223 +#: common.c:204 #, c-format -msgid "reading type casts\n" -msgstr "leyendo conversiones de tipo\n" +msgid "reading type casts" +msgstr "leyendo conversiones de tipo" -#: common.c:227 +#: common.c:207 #, c-format -msgid "reading transforms\n" -msgstr "leyendo las transformaciones\n" +msgid "reading transforms" +msgstr "leyendo las transformaciones" -#: common.c:231 +#: common.c:210 #, c-format -msgid "reading table inheritance information\n" -msgstr "leyendo la información de herencia de las tablas\n" +msgid "reading table inheritance information" +msgstr "leyendo la información de herencia de las tablas" -#: common.c:235 +#: common.c:213 #, c-format -msgid "reading event triggers\n" -msgstr "leyendo los disparadores por eventos\n" +msgid "reading event triggers" +msgstr "leyendo los disparadores por eventos" -#: common.c:240 +#: common.c:217 #, c-format -msgid "finding extension tables\n" -msgstr "buscando tablas de extensión\n" +msgid "finding extension tables" +msgstr "buscando tablas de extensión" -#: common.c:245 +#: common.c:221 #, c-format -msgid "finding inheritance relationships\n" -msgstr "buscando relaciones de herencia\n" +msgid "finding inheritance relationships" +msgstr "buscando relaciones de herencia" -#: common.c:249 +#: common.c:224 #, c-format -msgid "reading column info for interesting tables\n" -msgstr "leyendo la información de columnas para las tablas interesantes\n" +msgid "reading column info for interesting tables" +msgstr "leyendo la información de columnas para las tablas interesantes" -#: common.c:253 +#: common.c:227 #, c-format -msgid "flagging inherited columns in subtables\n" -msgstr "marcando las columnas heredadas en las subtablas\n" +msgid "flagging inherited columns in subtables" +msgstr "marcando las columnas heredadas en las subtablas" -#: common.c:257 +#: common.c:230 #, c-format -msgid "reading indexes\n" -msgstr "leyendo los índices\n" +msgid "reading indexes" +msgstr "leyendo los índices" -#: common.c:261 +#: common.c:233 #, c-format -msgid "reading extended statistics\n" -msgstr "leyendo estadísticas extendidas\n" +msgid "flagging indexes in partitioned tables" +msgstr "marcando índices en las tablas particionadas" -#: common.c:265 +#: common.c:236 #, c-format -msgid "reading constraints\n" -msgstr "leyendo las restricciones\n" +msgid "reading extended statistics" +msgstr "leyendo estadísticas extendidas" -#: common.c:269 +#: common.c:239 #, c-format -msgid "reading triggers\n" -msgstr "leyendo los disparadores (triggers)\n" +msgid "reading constraints" +msgstr "leyendo las restricciones" -#: common.c:273 +#: common.c:242 #, c-format -msgid "reading rewrite rules\n" -msgstr "leyendo las reglas de reescritura\n" +msgid "reading triggers" +msgstr "leyendo los disparadores (triggers)" -#: common.c:277 +#: common.c:245 #, c-format -msgid "reading policies\n" -msgstr "leyendo políticas\n" +msgid "reading rewrite rules" +msgstr "leyendo las reglas de reescritura" -#: common.c:281 +#: common.c:248 #, c-format -msgid "reading publications\n" -msgstr "leyendo publicaciones\n" +msgid "reading policies" +msgstr "leyendo políticas" -#: common.c:285 +#: common.c:251 #, c-format -msgid "reading publication membership\n" -msgstr "leyendo membresía en publicaciones\n" +msgid "reading publications" +msgstr "leyendo publicaciones" -#: common.c:289 +#: common.c:254 #, c-format -msgid "reading subscriptions\n" -msgstr "leyendo las suscripciones\n" +msgid "reading publication membership" +msgstr "leyendo membresía en publicaciones" -#: common.c:924 +#: common.c:257 #, c-format -msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" -msgstr "" -"falló la revisión de integridad, el OID %u del padre de la tabla «%s»\n" -"(OID %u) no se encontró\n" +msgid "reading subscriptions" +msgstr "leyendo las suscripciones" -#: common.c:966 +#: common.c:1023 #, c-format -msgid "could not parse numeric array \"%s\": too many numbers\n" -msgstr "no se pudo interpretar el arreglo numérico «%s»: demasiados números\n" +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "falló la revisión de integridad, el OID %u del padre de la tabla «%s» (OID %u) no se encontró" -#: common.c:981 +#: common.c:1065 #, c-format -msgid "could not parse numeric array \"%s\": invalid character in number\n" -msgstr "no se pudo interpretar el arreglo numérico «%s»: carácter no válido en número\n" +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "no se pudo interpretar el arreglo numérico «%s»: demasiados números" -#. translator: this is a module name -#: compress_io.c:78 -msgid "compress_io" -msgstr "compress_io" - -#: compress_io.c:114 +#: common.c:1080 #, c-format -msgid "invalid compression code: %d\n" -msgstr "código de compresión no válido: %d\n" +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "no se pudo interpretar el arreglo numérico «%s»: carácter no válido en número" -#: compress_io.c:138 compress_io.c:174 compress_io.c:192 compress_io.c:519 -#: compress_io.c:562 +#: compress_io.c:111 #, c-format -msgid "not built with zlib support\n" -msgstr "no contiene soporte zlib\n" +msgid "invalid compression code: %d" +msgstr "código de compresión no válido: %d" -#: compress_io.c:242 compress_io.c:344 +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:508 +#: compress_io.c:551 #, c-format -msgid "could not initialize compression library: %s\n" -msgstr "no se pudo inicializar la biblioteca de compresión: %s\n" +msgid "not built with zlib support" +msgstr "no contiene soporte zlib" -#: compress_io.c:263 +#: compress_io.c:237 compress_io.c:336 #, c-format -msgid "could not close compression stream: %s\n" -msgstr "no se pudo cerrar el flujo comprimido: %s\n" +msgid "could not initialize compression library: %s" +msgstr "no se pudo inicializar la biblioteca de compresión: %s" -#: compress_io.c:281 +#: compress_io.c:257 #, c-format -msgid "could not compress data: %s\n" -msgstr "no se pudo comprimir datos: %s\n" +msgid "could not close compression stream: %s" +msgstr "no se pudo cerrar el flujo comprimido: %s" -#: compress_io.c:361 compress_io.c:377 +#: compress_io.c:274 #, c-format -msgid "could not uncompress data: %s\n" -msgstr "no se pudo descomprimir datos: %s\n" +msgid "could not compress data: %s" +msgstr "no se pudo comprimir datos: %s" -#: compress_io.c:385 +#: compress_io.c:352 compress_io.c:367 #, c-format -msgid "could not close compression library: %s\n" -msgstr "no se pudo cerrar la biblioteca de compresión: %s\n" +msgid "could not uncompress data: %s" +msgstr "no se pudo descomprimir datos: %s" -#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:587 -#: pg_backup_tar.c:559 +#: compress_io.c:374 #, c-format -msgid "could not read from input file: %s\n" -msgstr "no se pudo leer el archivo de entrada: %s\n" +msgid "could not close compression library: %s" +msgstr "no se pudo cerrar la biblioteca de compresión: %s" -#: compress_io.c:635 pg_backup_custom.c:584 pg_backup_directory.c:543 -#: pg_backup_tar.c:795 pg_backup_tar.c:819 +#: compress_io.c:588 compress_io.c:625 pg_backup_tar.c:555 pg_backup_tar.c:558 #, c-format -msgid "could not read from input file: end of file\n" -msgstr "no se pudo leer desde el archivo de entrada: fin de archivo\n" +msgid "could not read from input file: %s" +msgstr "no se pudo leer el archivo de entrada: %s" -#: parallel.c:198 -msgid "parallel archiver" -msgstr "parallel archiver" +#: compress_io.c:627 pg_backup_custom.c:578 pg_backup_directory.c:539 +#: pg_backup_tar.c:795 pg_backup_tar.c:818 +#, c-format +msgid "could not read from input file: end of file" +msgstr "no se pudo leer desde el archivo de entrada: fin de archivo" -#: parallel.c:265 +#: parallel.c:263 #, c-format -msgid "%s: WSAStartup failed: %d\n" -msgstr "%s: WSAStartup falló: %d\n" +msgid "WSAStartup failed: %d" +msgstr "WSAStartup falló: %d" -#: parallel.c:971 +#: parallel.c:968 #, c-format -msgid "could not create communication channels: %s\n" -msgstr "no se pudo crear los canales de comunicación: %s\n" +msgid "could not create communication channels: %m" +msgstr "no se pudo crear los canales de comunicación: %m" -#: parallel.c:1036 +#: parallel.c:1031 #, c-format -msgid "could not create worker process: %s\n" -msgstr "no se pudo crear el proceso hijo: %s\n" +msgid "could not create worker process: %m" +msgstr "no se pudo crear el proceso hijo: %m" -#: parallel.c:1167 +#: parallel.c:1160 #, c-format -msgid "unrecognized command received from master: \"%s\"\n" -msgstr "orden no reconocida recibida del servidor: «%s»\n" +msgid "unrecognized command received from master: \"%s\"" +msgstr "orden no reconocida recibida del servidor: «%s»" -#: parallel.c:1211 parallel.c:1451 +#: parallel.c:1203 parallel.c:1441 #, c-format -msgid "invalid message received from worker: \"%s\"\n" -msgstr "mensaje no válido recibido del proceso hijo: «%s»\n" +msgid "invalid message received from worker: \"%s\"" +msgstr "mensaje no válido recibido del proceso hijo: «%s»" -#: parallel.c:1344 +#: parallel.c:1335 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" -"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table.\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." msgstr "" "no se pudo obtener un lock en la relación «%s»\n" -"Esto normalmente significa que alguien solicitó un lock ACCESS EXCLUSIVE en la tabla después de que el proceso pg_dump padre había obtenido el lock ACCESS SHARE en la tabla.\n" - -#: parallel.c:1433 -#, c-format -msgid "a worker process died unexpectedly\n" -msgstr "un proceso hijo murió inesperadamente\n" +"Esto normalmente significa que alguien solicitó un lock ACCESS EXCLUSIVE en la tabla después de que el proceso pg_dump padre había obtenido el lock ACCESS SHARE en la tabla." -#: parallel.c:1557 parallel.c:1675 +#: parallel.c:1424 #, c-format -msgid "could not write to the communication channel: %s\n" -msgstr "no se pudo escribir al canal de comunicación: %s\n" +msgid "a worker process died unexpectedly" +msgstr "un proceso hijo murió inesperadamente" -#: parallel.c:1635 +#: parallel.c:1546 parallel.c:1662 #, c-format -msgid "select() failed: %s\n" -msgstr "select() fallida: %s\n" +msgid "could not write to the communication channel: %m" +msgstr "no se pudo escribir al canal de comunicación: %m" -#: parallel.c:1760 +#: parallel.c:1623 #, c-format -msgid "pgpipe: could not create socket: error code %d\n" -msgstr "pgpipe: no se pudo crear el socket: código de error %d\n" +msgid "select() failed: %m" +msgstr "select() fallida: %m" -#: parallel.c:1771 +#: parallel.c:1746 #, c-format -msgid "pgpipe: could not bind: error code %d\n" -msgstr "pgpipe: no se pudo enlazar: código de error %d\n" +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: no se pudo crear el socket: código de error %d" -#: parallel.c:1778 +#: parallel.c:1757 #, c-format -msgid "pgpipe: could not listen: error code %d\n" -msgstr "pgpipe: no se pudo escuchar: código de error %d\n" +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: no se pudo enlazar: código de error %d" -#: parallel.c:1785 +#: parallel.c:1764 #, c-format -msgid "pgpipe: getsockname() failed: error code %d\n" -msgstr "pgpipe: getsockname() falló: código de error %d\n" +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: no se pudo escuchar: código de error %d" -#: parallel.c:1796 -#, c-format -msgid "pgpipe: could not create second socket: error code %d\n" -msgstr "pgpipe: no se pudo crear el segundo socket: código de error %d\n" - -#: parallel.c:1805 +#: parallel.c:1771 #, c-format -msgid "pgpipe: could not connect socket: error code %d\n" -msgstr "pgpipe: no se pudo conectar el socket: código de error %d\n" +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() falló: código de error %d" -#: parallel.c:1814 +#: parallel.c:1782 #, c-format -msgid "pgpipe: could not accept connection: error code %d\n" -msgstr "pgpipe: no se pudo aceptar la conexión: código de error %d\n" - -#. translator: this is a module name -#: pg_backup_archiver.c:53 -msgid "archiver" -msgstr "archiver" +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: no se pudo crear el segundo socket: código de error %d" -#: pg_backup_archiver.c:243 pg_backup_archiver.c:1573 +#: parallel.c:1791 #, c-format -msgid "could not close output file: %s\n" -msgstr "no se pudo cerrar el archivo de salida: %s\n" +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: no se pudo conectar el socket: código de error %d" -#: pg_backup_archiver.c:289 pg_backup_archiver.c:294 +#: parallel.c:1800 #, c-format -msgid "WARNING: archive items not in correct section order\n" -msgstr "ATENCIÓN: elementos del archivo no están en el orden correcto de secciones\n" +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: no se pudo aceptar la conexión: código de error %d" -#: pg_backup_archiver.c:300 +#: pg_backup_archiver.c:272 pg_backup_archiver.c:1595 #, c-format -msgid "unexpected section code %d\n" -msgstr "código de sección %d inesperado\n" +msgid "could not close output file: %m" +msgstr "no se pudo cerrar el archivo de salida: %m" -#: pg_backup_archiver.c:336 +#: pg_backup_archiver.c:316 pg_backup_archiver.c:320 #, c-format -msgid "-C and -1 are incompatible options\n" -msgstr "-C y -1 son opciones incompatibles\n" +msgid "archive items not in correct section order" +msgstr "elementos del archivo no están en el orden correcto de secciones" -#: pg_backup_archiver.c:346 +#: pg_backup_archiver.c:326 #, c-format -msgid "parallel restore is not supported with this archive file format\n" -msgstr "la restauración en paralelo no está soportada con este formato de archivo\n" +msgid "unexpected section code %d" +msgstr "código de sección %d inesperado" -#: pg_backup_archiver.c:350 +#: pg_backup_archiver.c:363 #, c-format -msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" -msgstr "la restauración en paralelo no está soportada con archivos construidos con pg_dump anterior a 8.0\n" +msgid "parallel restore is not supported with this archive file format" +msgstr "la restauración en paralelo no está soportada con este formato de archivo" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:367 #, c-format -msgid "cannot restore from compressed archive (compression not supported in this installation)\n" -msgstr "no se puede reestablecer desde un archivo comprimido (la compresión no está soportada en esta instalación)\n" +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "la restauración en paralelo no está soportada con archivos construidos con pg_dump anterior a 8.0" #: pg_backup_archiver.c:385 #, c-format -msgid "connecting to database for restore\n" -msgstr "conectando a la base de datos para reestablecimiento\n" - -#: pg_backup_archiver.c:387 -#, c-format -msgid "direct database connections are not supported in pre-1.3 archives\n" -msgstr "" -"las conexiones directas a la base de datos no están soportadas en\n" -"archivadores pre-1.3\n" +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "no se puede reestablecer desde un archivo comprimido (la compresión no está soportada en esta instalación)" -#: pg_backup_archiver.c:432 +#: pg_backup_archiver.c:402 #, c-format -msgid "implied data-only restore\n" -msgstr "asumiendo reestablecimiento de sólo datos\n" +msgid "connecting to database for restore" +msgstr "conectando a la base de datos para reestablecimiento" -#: pg_backup_archiver.c:502 +#: pg_backup_archiver.c:404 #, c-format -msgid "dropping %s %s\n" -msgstr "eliminando %s %s\n" +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "las conexiones directas a la base de datos no están soportadas en archivadores pre-1.3" -#: pg_backup_archiver.c:595 +#: pg_backup_archiver.c:449 #, c-format -msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" -msgstr "PRECAUCIÓN: no se pudo encontrar dónde insertar IF EXISTS en la sentencia «%s»\n" +msgid "implied data-only restore" +msgstr "asumiendo reestablecimiento de sólo datos" -#: pg_backup_archiver.c:671 +#: pg_backup_archiver.c:515 #, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "estableciendo dueño y privilegios para %s «%s.%s»\n" +msgid "dropping %s %s" +msgstr "eliminando %s %s" -#: pg_backup_archiver.c:674 +#: pg_backup_archiver.c:610 #, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "estableciendo dueño y privilegios para %s «%s»\n" +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "no se pudo encontrar dónde insertar IF EXISTS en la sentencia «%s»" -#: pg_backup_archiver.c:740 pg_backup_archiver.c:742 +#: pg_backup_archiver.c:766 pg_backup_archiver.c:768 #, c-format -msgid "warning from original dump file: %s\n" -msgstr "precaución desde el archivo original: %s\n" +msgid "warning from original dump file: %s" +msgstr "precaución desde el archivo original: %s" -#: pg_backup_archiver.c:751 +#: pg_backup_archiver.c:783 #, c-format -msgid "creating %s \"%s.%s\"\n" -msgstr "creando %s «%s.%s»\n" +msgid "creating %s \"%s.%s\"" +msgstr "creando %s «%s.%s»" -#: pg_backup_archiver.c:754 +#: pg_backup_archiver.c:786 #, c-format -msgid "creating %s \"%s\"\n" -msgstr "creando %s «%s»\n" +msgid "creating %s \"%s\"" +msgstr "creando %s «%s»" -#: pg_backup_archiver.c:806 +#: pg_backup_archiver.c:843 #, c-format -msgid "connecting to new database \"%s\"\n" -msgstr "conectando a nueva base de datos «%s»\n" +msgid "connecting to new database \"%s\"" +msgstr "conectando a nueva base de datos «%s»" -#: pg_backup_archiver.c:834 +#: pg_backup_archiver.c:871 #, c-format -msgid "processing %s\n" -msgstr "procesando %s\n" +msgid "processing %s" +msgstr "procesando %s" -#: pg_backup_archiver.c:854 +#: pg_backup_archiver.c:891 #, c-format -msgid "processing data for table \"%s.%s\"\n" -msgstr "procesando datos de la tabla «%s.%s»\n" +msgid "processing data for table \"%s.%s\"" +msgstr "procesando datos de la tabla «%s.%s»" -#: pg_backup_archiver.c:916 +#: pg_backup_archiver.c:953 #, c-format -msgid "executing %s %s\n" -msgstr "ejecutando %s %s\n" +msgid "executing %s %s" +msgstr "ejecutando %s %s" -#: pg_backup_archiver.c:955 +#: pg_backup_archiver.c:992 #, c-format -msgid "disabling triggers for %s\n" -msgstr "deshabilitando disparadores (triggers) para %s\n" +msgid "disabling triggers for %s" +msgstr "deshabilitando disparadores (triggers) para %s" -#: pg_backup_archiver.c:983 +#: pg_backup_archiver.c:1018 #, c-format -msgid "enabling triggers for %s\n" -msgstr "habilitando disparadores (triggers) para %s\n" +msgid "enabling triggers for %s" +msgstr "habilitando disparadores (triggers) para %s" -#: pg_backup_archiver.c:1013 +#: pg_backup_archiver.c:1046 #, c-format -msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n" -msgstr "" -"error interno -- WriteData no puede ser llamada fuera del contexto\n" -"de una rutina DataDumper\n" +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "error interno -- WriteData no puede ser llamada fuera del contexto de una rutina DataDumper" -#: pg_backup_archiver.c:1211 +#: pg_backup_archiver.c:1231 #, c-format -msgid "large-object output not supported in chosen format\n" -msgstr "" -"la extracción de objetos grandes no está soportada en el formato\n" -"seleccionado\n" +msgid "large-object output not supported in chosen format" +msgstr "la extracción de objetos grandes no está soportada en el formato seleccionado" -#: pg_backup_archiver.c:1269 +#: pg_backup_archiver.c:1289 #, c-format -msgid "restored %d large object\n" -msgid_plural "restored %d large objects\n" -msgstr[0] "se reestableció %d objeto grande\n" -msgstr[1] "se reestablecieron %d objetos grandes\n" +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "se reestableció %d objeto grande" +msgstr[1] "se reestablecieron %d objetos grandes" -#: pg_backup_archiver.c:1290 pg_backup_tar.c:737 +#: pg_backup_archiver.c:1310 pg_backup_tar.c:738 #, c-format -msgid "restoring large object with OID %u\n" -msgstr "reestableciendo objeto grande con OID %u\n" +msgid "restoring large object with OID %u" +msgstr "reestableciendo objeto grande con OID %u" -#: pg_backup_archiver.c:1302 +#: pg_backup_archiver.c:1322 #, c-format msgid "could not create large object %u: %s" msgstr "no se pudo crear el objeto grande %u: %s" -#: pg_backup_archiver.c:1307 pg_dump.c:3084 +#: pg_backup_archiver.c:1327 pg_dump.c:3471 #, c-format msgid "could not open large object %u: %s" msgstr "no se pudo abrir el objeto grande %u: %s" -#: pg_backup_archiver.c:1365 +#: pg_backup_archiver.c:1384 #, c-format -msgid "could not open TOC file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo TOC «%s»: %s\n" +msgid "could not open TOC file \"%s\": %m" +msgstr "no se pudo abrir el archivo TOC «%s»: %m" -#: pg_backup_archiver.c:1406 +#: pg_backup_archiver.c:1424 #, c-format -msgid "WARNING: line ignored: %s\n" -msgstr "PRECAUCIÓN: línea ignorada: %s\n" +msgid "line ignored: %s" +msgstr "línea ignorada: %s" -#: pg_backup_archiver.c:1413 +#: pg_backup_archiver.c:1431 #, c-format -msgid "could not find entry for ID %d\n" -msgstr "no se pudo encontrar una entrada para el ID %d\n" +msgid "could not find entry for ID %d" +msgstr "no se pudo encontrar una entrada para el ID %d" -#: pg_backup_archiver.c:1434 pg_backup_directory.c:225 -#: pg_backup_directory.c:592 +#: pg_backup_archiver.c:1452 pg_backup_directory.c:222 +#: pg_backup_directory.c:587 #, c-format -msgid "could not close TOC file: %s\n" -msgstr "no se pudo cerrar el archivo TOC: %s\n" +msgid "could not close TOC file: %m" +msgstr "no se pudo cerrar el archivo TOC: %m" -#: pg_backup_archiver.c:1543 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:578 pg_backup_directory.c:643 -#: pg_backup_directory.c:663 +#: pg_backup_archiver.c:1567 pg_backup_custom.c:159 pg_backup_directory.c:332 +#: pg_backup_directory.c:574 pg_backup_directory.c:637 +#: pg_backup_directory.c:656 #, c-format -msgid "could not open output file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo de salida «%s»: %s\n" +msgid "could not open output file \"%s\": %m" +msgstr "no se pudo abrir el archivo de salida «%s»: %m" -#: pg_backup_archiver.c:1546 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:165 #, c-format -msgid "could not open output file: %s\n" -msgstr "no se pudo abrir el archivo de salida: %s\n" +msgid "could not open output file: %m" +msgstr "no se pudo abrir el archivo de salida: %m" -#: pg_backup_archiver.c:1652 +#: pg_backup_archiver.c:1662 #, c-format -msgid "wrote %lu byte of large object data (result = %lu)\n" -msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" -msgstr[0] "se escribió %lu byte de los datos del objeto grande (resultado = %lu)\n" -msgstr[1] "se escribieron %lu bytes de los datos del objeto grande (resultado = %lu)\n" +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "se escribió %lu byte de los datos del objeto grande (resultado = %lu)" +msgstr[1] "se escribieron %lu bytes de los datos del objeto grande (resultado = %lu)" -#: pg_backup_archiver.c:1658 +#: pg_backup_archiver.c:1667 #, c-format -msgid "could not write to large object (result: %lu, expected: %lu)\n" -msgstr "no se pudo escribir al objecto grande (resultado: %lu, esperado: %lu)\n" +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "no se pudo escribir al objecto grande (resultado: %lu, esperado: %lu)" -#: pg_backup_archiver.c:1751 +#: pg_backup_archiver.c:1759 #, c-format -msgid "Error while INITIALIZING:\n" -msgstr "Error durante INICIALIZACIÓN:\n" +msgid "while INITIALIZING:" +msgstr "durante INICIALIZACIÓN:" -#: pg_backup_archiver.c:1756 +#: pg_backup_archiver.c:1764 #, c-format -msgid "Error while PROCESSING TOC:\n" -msgstr "Error durante PROCESAMIENTO DE TABLA DE CONTENIDOS:\n" +msgid "while PROCESSING TOC:" +msgstr "durante PROCESAMIENTO DE TABLA DE CONTENIDOS:" -#: pg_backup_archiver.c:1761 +#: pg_backup_archiver.c:1769 #, c-format -msgid "Error while FINALIZING:\n" -msgstr "Error durante FINALIZACIÓN:\n" +msgid "while FINALIZING:" +msgstr "durante FINALIZACIÓN:" -#: pg_backup_archiver.c:1766 +#: pg_backup_archiver.c:1774 #, c-format -msgid "Error from TOC entry %d; %u %u %s %s %s\n" -msgstr "Error en entrada de la tabla de contenidos %d; %u %u %s %s %s\n" +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "en entrada de la tabla de contenidos %d; %u %u %s %s %s" -#: pg_backup_archiver.c:1839 +#: pg_backup_archiver.c:1850 #, c-format -msgid "bad dumpId\n" -msgstr "dumpId incorrecto\n" +msgid "bad dumpId" +msgstr "dumpId incorrecto" -#: pg_backup_archiver.c:1860 +#: pg_backup_archiver.c:1871 #, c-format -msgid "bad table dumpId for TABLE DATA item\n" -msgstr "dumpId de tabla incorrecto para elemento TABLE DATA\n" +msgid "bad table dumpId for TABLE DATA item" +msgstr "dumpId de tabla incorrecto para elemento TABLE DATA" -#: pg_backup_archiver.c:1952 +#: pg_backup_archiver.c:1963 #, c-format -msgid "unexpected data offset flag %d\n" -msgstr "bandera de posición inesperada %d\n" +msgid "unexpected data offset flag %d" +msgstr "bandera de posición inesperada %d" -#: pg_backup_archiver.c:1965 +#: pg_backup_archiver.c:1976 #, c-format -msgid "file offset in dump file is too large\n" -msgstr "el posición en el archivo es demasiado grande\n" +msgid "file offset in dump file is too large" +msgstr "el posición en el archivo es demasiado grande" -#: pg_backup_archiver.c:2078 +#: pg_backup_archiver.c:2113 pg_backup_archiver.c:2123 #, c-format -msgid "attempting to ascertain archive format\n" -msgstr "intentando comprobar el formato del archivador\n" +msgid "directory name too long: \"%s\"" +msgstr "nombre de directorio demasiado largo: «%s»" -#: pg_backup_archiver.c:2104 pg_backup_archiver.c:2114 +#: pg_backup_archiver.c:2131 #, c-format -msgid "directory name too long: \"%s\"\n" -msgstr "nombre de directorio demasiado largo: «%s»\n" +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "el directorio «%s» no parece ser un archivador válido (no existe «toc.dat»)" -#: pg_backup_archiver.c:2122 +#: pg_backup_archiver.c:2139 pg_backup_custom.c:176 pg_backup_custom.c:760 +#: pg_backup_directory.c:207 pg_backup_directory.c:391 #, c-format -msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n" -msgstr "el directorio «%s» no parece ser un archivador válido (no existe «toc.dat»)\n" +msgid "could not open input file \"%s\": %m" +msgstr "no se pudo abrir el archivo de entrada «%s»: %m" -#: pg_backup_archiver.c:2130 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:394 +#: pg_backup_archiver.c:2146 pg_backup_custom.c:182 #, c-format -msgid "could not open input file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo de entrada «%s»: %s\n" +msgid "could not open input file: %m" +msgstr "no se pudo abrir el archivo de entrada: %m" -#: pg_backup_archiver.c:2138 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2152 #, c-format -msgid "could not open input file: %s\n" -msgstr "no se pudo abrir el archivo de entrada: %s\n" +msgid "could not read input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" -#: pg_backup_archiver.c:2145 +#: pg_backup_archiver.c:2154 #, c-format -msgid "could not read input file: %s\n" -msgstr "no se pudo leer el archivo de entrada: %s\n" +msgid "input file is too short (read %lu, expected 5)" +msgstr "el archivo de entrada es demasiado corto (leidos %lu, esperados 5)" -#: pg_backup_archiver.c:2147 +#: pg_backup_archiver.c:2239 #, c-format -msgid "input file is too short (read %lu, expected 5)\n" -msgstr "el archivo de entrada es demasiado corto (leidos %lu, esperados 5)\n" +msgid "input file appears to be a text format dump. Please use psql." +msgstr "el archivo de entrada parece ser un volcado de texto. Por favor use psql." -#: pg_backup_archiver.c:2232 +#: pg_backup_archiver.c:2245 #, c-format -msgid "input file appears to be a text format dump. Please use psql.\n" -msgstr "el archivo de entrada parece ser un volcado de texto. Por favor use psql.\n" +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "el archivo de entrada no parece ser un archivador válido (¿demasiado corto?)" -#: pg_backup_archiver.c:2238 +#: pg_backup_archiver.c:2251 #, c-format -msgid "input file does not appear to be a valid archive (too short?)\n" -msgstr "el archivo de entrada no parece ser un archivador válido (¿demasiado corto?)\n" +msgid "input file does not appear to be a valid archive" +msgstr "el archivo de entrada no parece ser un archivador válido" -#: pg_backup_archiver.c:2244 +#: pg_backup_archiver.c:2271 #, c-format -msgid "input file does not appear to be a valid archive\n" -msgstr "el archivo de entrada no parece ser un archivador válido\n" +msgid "could not close input file: %m" +msgstr "no se pudo cerrar el archivo de entrada: %m" -#: pg_backup_archiver.c:2264 +#: pg_backup_archiver.c:2385 #, c-format -msgid "could not close input file: %s\n" -msgstr "no se pudo cerrar el archivo de entrada: %s\n" +msgid "unrecognized file format \"%d\"" +msgstr "formato de archivo no reconocido «%d»" -#: pg_backup_archiver.c:2282 +#: pg_backup_archiver.c:2467 pg_backup_archiver.c:4475 #, c-format -msgid "allocating AH for %s, format %d\n" -msgstr "reservando AH para %s, formato %d\n" +msgid "finished item %d %s %s" +msgstr "terminó el elemento %d %s %s" -#: pg_backup_archiver.c:2383 +#: pg_backup_archiver.c:2471 pg_backup_archiver.c:4488 #, c-format -msgid "unrecognized file format \"%d\"\n" -msgstr "formato de archivo no reconocido «%d»\n" +msgid "worker process failed: exit code %d" +msgstr "el proceso hijo falló: código de salida %d" -#: pg_backup_archiver.c:2438 pg_backup_archiver.c:4204 +#: pg_backup_archiver.c:2591 #, c-format -msgid "finished item %d %s %s\n" -msgstr "terminó el elemento %d %s %s\n" +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "la entrada con ID %d está fuera de rango -- tal vez la tabla de contenido está corrupta" -#: pg_backup_archiver.c:2442 pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:2658 #, c-format -msgid "worker process failed: exit code %d\n" -msgstr "el proceso hijo falló: código de salida %d\n" - -#: pg_backup_archiver.c:2562 -#, c-format -msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" -msgstr "" -"la entrada con ID %d está fuera de rango -- tal vez\n" -"la tabla de contenido está corrupta\n" +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "restaurar tablas WITH OIDS ya no está soportado" -#: pg_backup_archiver.c:2678 +#: pg_backup_archiver.c:2740 #, c-format -msgid "read TOC entry %d (ID %d) for %s %s\n" -msgstr "leyendo entrada de la tabla de contenidos %d (ID %d) para %s %s\n" +msgid "unrecognized encoding \"%s\"" +msgstr "no se reconoce la codificación: «%s»" -#: pg_backup_archiver.c:2712 +#: pg_backup_archiver.c:2745 #, c-format -msgid "unrecognized encoding \"%s\"\n" -msgstr "no se reconoce la codificación: «%s»\n" +msgid "invalid ENCODING item: %s" +msgstr "elemento ENCODING no válido: %s" -#: pg_backup_archiver.c:2717 +#: pg_backup_archiver.c:2763 #, c-format -msgid "invalid ENCODING item: %s\n" -msgstr "elemento ENCODING no válido: %s\n" +msgid "invalid STDSTRINGS item: %s" +msgstr "elemento STDSTRINGS no válido: %s" -#: pg_backup_archiver.c:2735 +#: pg_backup_archiver.c:2788 #, c-format -msgid "invalid STDSTRINGS item: %s\n" -msgstr "elemento STDSTRINGS no válido: %s\n" +msgid "schema \"%s\" not found" +msgstr "esquema «%s» no encontrado" -#: pg_backup_archiver.c:2750 +#: pg_backup_archiver.c:2795 #, c-format -msgid "schema \"%s\" not found\n" -msgstr "esquema «%s» no encontrado\n" +msgid "table \"%s\" not found" +msgstr "tabla «%s» no encontrada" -#: pg_backup_archiver.c:2757 +#: pg_backup_archiver.c:2802 #, c-format -msgid "table \"%s\" not found\n" -msgstr "tabla «%s» no encontrada\n" +msgid "index \"%s\" not found" +msgstr "índice «%s» no encontrado" -#: pg_backup_archiver.c:2764 +#: pg_backup_archiver.c:2809 #, c-format -msgid "index \"%s\" not found\n" -msgstr "índice «%s» no encontrado\n" +msgid "function \"%s\" not found" +msgstr "función «%s» no encontrada" -#: pg_backup_archiver.c:2771 +#: pg_backup_archiver.c:2816 #, c-format -msgid "function \"%s\" not found\n" -msgstr "función «%s» no encontrada\n" +msgid "trigger \"%s\" not found" +msgstr "disparador «%s» no encontrado" -#: pg_backup_archiver.c:2778 -#, c-format -msgid "trigger \"%s\" not found\n" -msgstr "disparador «%s» no encontrado\n" - -#: pg_backup_archiver.c:3034 +#: pg_backup_archiver.c:3195 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "no se pudo establecer el usuario de sesión a «%s»: %s" -#: pg_backup_archiver.c:3066 -#, c-format -msgid "could not set default_with_oids: %s" -msgstr "no se pudo definir default_with_oids: %s" - -#: pg_backup_archiver.c:3211 -#, c-format -msgid "could not set search_path to \"%s\": %s" -msgstr "no se pudo establecer search_path a «%s»: %s" - -#: pg_backup_archiver.c:3273 -#, c-format -msgid "could not set default_tablespace to %s: %s" -msgstr "no se pudo establecer default_tablespace a %s: %s" - -#: pg_backup_archiver.c:3362 pg_backup_archiver.c:3559 -#, c-format -msgid "WARNING: don't know how to set owner for object type %s\n" -msgstr "PRECAUCIÓN: no se sabe cómo establecer el dueño para el objeto de tipo %s\n" - -#: pg_backup_archiver.c:3646 -#, c-format -msgid "did not find magic string in file header\n" -msgstr "no se encontró la cadena mágica en el encabezado del archivo\n" - -#: pg_backup_archiver.c:3659 -#, c-format -msgid "unsupported version (%d.%d) in file header\n" -msgstr "versión no soportada (%d.%d) en el encabezado del archivo\n" - -#: pg_backup_archiver.c:3664 +#: pg_backup_archiver.c:3533 pg_backup_archiver.c:3691 #, c-format -msgid "sanity check on integer size (%lu) failed\n" -msgstr "revisión de integridad en el tamaño del entero (%lu) falló\n" +msgid "don't know how to set owner for object type \"%s\"" +msgstr "no se sabe cómo establecer el dueño para el objeto de tipo «%s»" -#: pg_backup_archiver.c:3668 +#: pg_backup_archiver.c:3795 #, c-format -msgid "WARNING: archive was made on a machine with larger integers, some operations might fail\n" -msgstr "" -"PRECAUCIÓN: el archivador fue hecho en una máquina con enteros más \n" -"grandes, algunas operaciones podrían fallar\n" +msgid "did not find magic string in file header" +msgstr "no se encontró la cadena mágica en el encabezado del archivo" -#: pg_backup_archiver.c:3678 +#: pg_backup_archiver.c:3808 #, c-format -msgid "expected format (%d) differs from format found in file (%d)\n" -msgstr "el formato esperado (%d) difiere del formato encontrado en el archivo (%d)\n" +msgid "unsupported version (%d.%d) in file header" +msgstr "versión no soportada (%d.%d) en el encabezado del archivo" -#: pg_backup_archiver.c:3694 +#: pg_backup_archiver.c:3813 #, c-format -msgid "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n" -msgstr "" -"PRECAUCIÓN: el archivador está comprimido, pero esta instalación no soporta\n" -"compresión -- no habrá datos disponibles\n" +msgid "sanity check on integer size (%lu) failed" +msgstr "revisión de integridad en el tamaño del entero (%lu) falló" -#: pg_backup_archiver.c:3712 +#: pg_backup_archiver.c:3817 #, c-format -msgid "WARNING: invalid creation date in header\n" -msgstr "PRECAUCIÓN: la fecha de creación en el encabezado no es válida\n" +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "el archivador fue hecho en una máquina con enteros más grandes, algunas operaciones podrían fallar" -#: pg_backup_archiver.c:3787 +#: pg_backup_archiver.c:3827 #, c-format -msgid "entering restore_toc_entries_prefork\n" -msgstr "ingresando restore_toc_entries_prefork\n" +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "el formato esperado (%d) difiere del formato encontrado en el archivo (%d)" -#: pg_backup_archiver.c:3831 +#: pg_backup_archiver.c:3843 #, c-format -msgid "processing item %d %s %s\n" -msgstr "procesando el elemento %d %s %s\n" +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "el archivador está comprimido, pero esta instalación no soporta compresión -- no habrá datos disponibles" -#: pg_backup_archiver.c:3881 +#: pg_backup_archiver.c:3861 #, c-format -msgid "entering restore_toc_entries_parallel\n" -msgstr "ingresando restore_toc_entries_parallel\n" +msgid "invalid creation date in header" +msgstr "la fecha de creación en el encabezado no es válida" -#: pg_backup_archiver.c:3929 +#: pg_backup_archiver.c:3998 #, c-format -msgid "entering main parallel loop\n" -msgstr "ingresando al bucle paralelo principal\n" +msgid "processing item %d %s %s" +msgstr "procesando el elemento %d %s %s" -#: pg_backup_archiver.c:3940 +#: pg_backup_archiver.c:4077 #, c-format -msgid "skipping item %d %s %s\n" -msgstr "saltando el elemento %d %s %s\n" +msgid "entering main parallel loop" +msgstr "ingresando al bucle paralelo principal" -#: pg_backup_archiver.c:3950 +#: pg_backup_archiver.c:4088 #, c-format -msgid "launching item %d %s %s\n" -msgstr "lanzando el elemento %d %s %s\n" +msgid "skipping item %d %s %s" +msgstr "saltando el elemento %d %s %s" -#: pg_backup_archiver.c:3981 +#: pg_backup_archiver.c:4097 #, c-format -msgid "finished main parallel loop\n" -msgstr "terminó el bucle paralelo principal\n" +msgid "launching item %d %s %s" +msgstr "lanzando el elemento %d %s %s" -#: pg_backup_archiver.c:3990 +#: pg_backup_archiver.c:4151 #, c-format -msgid "entering restore_toc_entries_postfork\n" -msgstr "ingresando restore_toc_entries_postfork\n" +msgid "finished main parallel loop" +msgstr "terminó el bucle paralelo principal" -#: pg_backup_archiver.c:4009 +#: pg_backup_archiver.c:4189 #, c-format -msgid "processing missed item %d %s %s\n" -msgstr "procesando el elemento saltado %d %s %s\n" +msgid "processing missed item %d %s %s" +msgstr "procesando el elemento saltado %d %s %s" -#: pg_backup_archiver.c:4160 +#: pg_backup_archiver.c:4794 #, c-format -msgid "no item ready\n" -msgstr "ningún elemento listo\n" +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "la tabla «%s» no pudo ser creada, no se recuperarán sus datos" -#: pg_backup_archiver.c:4379 +#: pg_backup_custom.c:377 pg_backup_null.c:150 #, c-format -msgid "transferring dependency %d -> %d to %d\n" -msgstr "transferiendo la dependencia %d -> %d a %d\n" +msgid "invalid OID for large object" +msgstr "OID no válido para objeto grande" -#: pg_backup_archiver.c:4452 +#: pg_backup_custom.c:447 #, c-format -msgid "reducing dependencies for %d\n" -msgstr "reduciendo las dependencias para %d\n" +msgid "unrecognized data block type (%d) while searching archive" +msgstr "tipo de bloque de datos (%d) no conocido al buscar en el archivador" -#: pg_backup_archiver.c:4491 +#: pg_backup_custom.c:458 pg_backup_custom.c:818 #, c-format -msgid "table \"%s\" could not be created, will not restore its data\n" -msgstr "la tabla «%s» no pudo ser creada, no se recuperarán sus datos\n" - -#. translator: this is a module name -#: pg_backup_custom.c:93 -msgid "custom archiver" -msgstr "custom archiver" +msgid "error during file seek: %m" +msgstr "error durante el posicionamiento (seek) en el archivo: %m" -#: pg_backup_custom.c:380 pg_backup_null.c:150 +#: pg_backup_custom.c:467 #, c-format -msgid "invalid OID for large object\n" -msgstr "OID no válido para objeto grande\n" - -#: pg_backup_custom.c:451 -#, c-format -msgid "unrecognized data block type (%d) while searching archive\n" -msgstr "tipo de bloque de datos (%d) no conocido al buscar en el archivador\n" - -#: pg_backup_custom.c:462 -#, c-format -msgid "error during file seek: %s\n" -msgstr "error durante el posicionamiento (seek) en el archivo: %s\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente debido a una petición de restauración fuera de orden, la que no puede ser satisfecha debido a la falta de información de posicionamiento en el archivo" #: pg_backup_custom.c:472 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive\n" -msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente debido a una petición de restauración fuera de orden, la que no puede ser satisfecha debido a la falta de información de posicionamiento en el archivo\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente debido a una petición de restauración fuera de orden, la que no puede ser completada debido a que en el archivo de entrada no es reposicionable (seekable)" #: pg_backup_custom.c:477 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file\n" -msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente debido a una petición de restauración fuera de orden, la que no puede ser completada debido a que en el archivo de entrada no es reposicionable (seekable)\n" +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente el archivo está corrupto" -#: pg_backup_custom.c:482 +#: pg_backup_custom.c:484 #, c-format -msgid "could not find block ID %d in archive -- possibly corrupt archive\n" -msgstr "no se pudo encontrar el bloque con ID %d en archivo -- posiblemente el archivo está corrupto\n" +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "se encontró un bloque no esperado ID (%d) mientras se leían los datos -- se esperaba %d" -#: pg_backup_custom.c:489 +#: pg_backup_custom.c:498 #, c-format -msgid "found unexpected block ID (%d) when reading data -- expected %d\n" -msgstr "" -"se encontró un bloque no esperado ID (%d) mientras se leían los\n" -"datos -- se esperaba %d\n" +msgid "unrecognized data block type %d while restoring archive" +msgstr "se encontró un bloque tipo %d no reconocido al restablecer el archivador" -#: pg_backup_custom.c:503 +#: pg_backup_custom.c:580 #, c-format -msgid "unrecognized data block type %d while restoring archive\n" -msgstr "se encontró un bloque tipo %d no reconocido al restablecer el archivador\n" +msgid "could not read from input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" -#: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1090 +#: pg_backup_custom.c:698 pg_backup_custom.c:751 pg_backup_custom.c:891 +#: pg_backup_tar.c:1091 #, c-format -msgid "could not determine seek position in archive file: %s\n" -msgstr "no se pudo determinar la posición (seek) en el archivo del archivador: %s\n" +msgid "could not determine seek position in archive file: %m" +msgstr "no se pudo determinar la posición (seek) en el archivo del archivador: %m" -#: pg_backup_custom.c:723 pg_backup_custom.c:764 +#: pg_backup_custom.c:715 pg_backup_custom.c:755 #, c-format -msgid "could not close archive file: %s\n" -msgstr "no se pudo cerrar el archivo del archivador: %s\n" +msgid "could not close archive file: %m" +msgstr "no se pudo cerrar el archivo del archivador: %m" -#: pg_backup_custom.c:746 +#: pg_backup_custom.c:738 #, c-format -msgid "can only reopen input archives\n" -msgstr "sólo se pueden reabrir archivos de entrada\n" +msgid "can only reopen input archives" +msgstr "sólo se pueden reabrir archivos de entrada" -#: pg_backup_custom.c:753 +#: pg_backup_custom.c:745 #, c-format -msgid "parallel restore from standard input is not supported\n" -msgstr "la restauración en paralelo desde entrada estándar (stdin) no está soportada\n" +msgid "parallel restore from standard input is not supported" +msgstr "la restauración en paralelo desde entrada estándar (stdin) no está soportada" -#: pg_backup_custom.c:755 +#: pg_backup_custom.c:747 #, c-format -msgid "parallel restore from non-seekable file is not supported\n" -msgstr "la restauración en paralelo desde un archivo no posicionable no está soportada\n" +msgid "parallel restore from non-seekable file is not supported" +msgstr "la restauración en paralelo desde un archivo no posicionable no está soportada" -#: pg_backup_custom.c:774 +#: pg_backup_custom.c:763 #, c-format -msgid "could not set seek position in archive file: %s\n" -msgstr "no se pudo posicionar (seek) en el archivo del archivador: %s\n" +msgid "could not set seek position in archive file: %m" +msgstr "no se pudo posicionar (seek) en el archivo del archivador: %m" -#: pg_backup_custom.c:792 +#: pg_backup_custom.c:839 #, c-format -msgid "compressor active\n" -msgstr "compresor activo\n" +msgid "compressor active" +msgstr "compresor activo" -#: pg_backup_custom.c:848 +#: pg_backup_custom.c:894 #, c-format -msgid "WARNING: ftell mismatch with expected position -- ftell used\n" -msgstr "ATENCIÓN: ftell no coincide con la posición esperada -- se usó ftell\n" - -#. translator: this is a module name -#: pg_backup_db.c:29 -msgid "archiver (db)" -msgstr "archiver (bd)" +msgid "ftell mismatch with expected position -- ftell used" +msgstr "ftell no coincide con la posición esperada -- se usó ftell" -#: pg_backup_db.c:45 +#: pg_backup_db.c:44 #, c-format -msgid "could not get server_version from libpq\n" -msgstr "no se pudo obtener server_version desde libpq\n" +msgid "could not get server_version from libpq" +msgstr "no se pudo obtener server_version desde libpq" -#: pg_backup_db.c:56 pg_dumpall.c:2057 +#: pg_backup_db.c:55 pg_dumpall.c:1819 #, c-format -msgid "server version: %s; %s version: %s\n" -msgstr "versión del servidor: %s; versión de %s: %s\n" +msgid "server version: %s; %s version: %s" +msgstr "versión del servidor: %s; versión de %s: %s" -#: pg_backup_db.c:58 pg_dumpall.c:2059 +#: pg_backup_db.c:57 pg_dumpall.c:1821 #, c-format -msgid "aborting because of server version mismatch\n" -msgstr "abortando debido a que no coincide la versión del servidor\n" +msgid "aborting because of server version mismatch" +msgstr "abortando debido a que no coincide la versión del servidor" -#: pg_backup_db.c:148 +#: pg_backup_db.c:140 #, c-format -msgid "connecting to database \"%s\" as user \"%s\"\n" -msgstr "conectandose a la base de datos \"%s\" como el usuario «%s»\n" +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "conectandose a la base de datos \"%s\" como el usuario «%s»" -#: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 -#: pg_dumpall.c:1880 pg_dumpall.c:1994 +#: pg_backup_db.c:147 pg_backup_db.c:196 pg_backup_db.c:257 pg_backup_db.c:298 +#: pg_dumpall.c:1644 pg_dumpall.c:1757 msgid "Password: " msgstr "Contraseña: " -#: pg_backup_db.c:187 +#: pg_backup_db.c:179 #, c-format -msgid "failed to reconnect to database\n" -msgstr "falló la reconexión a la base de datos\n" +msgid "failed to reconnect to database" +msgstr "falló la reconexión a la base de datos" -#: pg_backup_db.c:192 +#: pg_backup_db.c:184 #, c-format msgid "could not reconnect to database: %s" msgstr "no se pudo hacer la reconexión a la base de datos: %s" -#: pg_backup_db.c:208 +#: pg_backup_db.c:200 #, c-format -msgid "connection needs password\n" -msgstr "la conexión necesita contraseña\n" +msgid "connection needs password" +msgstr "la conexión necesita contraseña" -#: pg_backup_db.c:259 +#: pg_backup_db.c:251 #, c-format -msgid "already connected to a database\n" -msgstr "ya está conectado a una base de datos\n" +msgid "already connected to a database" +msgstr "ya está conectado a una base de datos" -#: pg_backup_db.c:298 +#: pg_backup_db.c:290 #, c-format -msgid "failed to connect to database\n" -msgstr "falló la conexión a la base de datos\n" +msgid "failed to connect to database" +msgstr "falló la conexión a la base de datos" -#: pg_backup_db.c:314 +#: pg_backup_db.c:306 #, c-format msgid "connection to database \"%s\" failed: %s" msgstr "falló la conexión a la base de datos «%s»: %s" -#: pg_backup_db.c:382 +#: pg_backup_db.c:378 pg_dumpall.c:1677 #, c-format msgid "%s" msgstr "%s" -#: pg_backup_db.c:389 +#: pg_backup_db.c:385 pg_dumpall.c:1882 pg_dumpall.c:1905 #, c-format msgid "query failed: %s" msgstr "la consulta falló: %s" -#: pg_backup_db.c:391 +#: pg_backup_db.c:387 pg_dumpall.c:1883 pg_dumpall.c:1906 #, c-format -msgid "query was: %s\n" -msgstr "la consulta era: %s\n" +msgid "query was: %s" +msgstr "la consulta era: %s" -#: pg_backup_db.c:433 +#: pg_backup_db.c:428 #, c-format -msgid "query returned %d row instead of one: %s\n" -msgid_plural "query returned %d rows instead of one: %s\n" -msgstr[0] "la consulta regresó %d fila en lugar de una: %s\n" -msgstr[1] "la consulta regresó %d filas en lugar de una: %s\n" +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "la consulta regresó %d fila en lugar de una: %s" +msgstr[1] "la consulta regresó %d filas en lugar de una: %s" -#: pg_backup_db.c:469 -#, c-format -msgid "%s: %s Command was: %s\n" -msgstr "%s: %s La orden era: %s\n" - -#: pg_backup_db.c:525 pg_backup_db.c:599 pg_backup_db.c:606 +#: pg_backup_db.c:520 pg_backup_db.c:594 pg_backup_db.c:601 msgid "could not execute query" msgstr "no se pudo ejecutar la consulta" -#: pg_backup_db.c:578 +#: pg_backup_db.c:573 #, c-format msgid "error returned by PQputCopyData: %s" msgstr "PQputCopyData regresó un error: %s" -#: pg_backup_db.c:627 +#: pg_backup_db.c:622 #, c-format msgid "error returned by PQputCopyEnd: %s" msgstr "PQputCopyEnd regresó un error: %s" -#: pg_backup_db.c:633 +#: pg_backup_db.c:634 pg_dump.c:1924 #, c-format -msgid "COPY failed for table \"%s\": %s" -msgstr "COPY falló para la tabla «%s»: %s" +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "resultados extra inesperados durante el COPY de la tabla «%s»" -#: pg_backup_db.c:639 pg_dump.c:1841 -#, c-format -msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" -msgstr "PRECAUCIÓN: resultados extra inesperados durante el COPY de la tabla «%s»\n" - -#: pg_backup_db.c:651 +#: pg_backup_db.c:646 msgid "could not start database transaction" msgstr "no se pudo iniciar la transacción en la base de datos" -#: pg_backup_db.c:659 +#: pg_backup_db.c:654 msgid "could not commit database transaction" msgstr "no se pudo terminar la transacción a la base de datos" -#. translator: this is a module name -#: pg_backup_directory.c:65 -msgid "directory archiver" -msgstr "directory archiver" +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "no se especificó un directorio de salida" -#: pg_backup_directory.c:157 +#: pg_backup_directory.c:185 #, c-format -msgid "no output directory specified\n" -msgstr "no se especificó un directorio de salida\n" +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" -#: pg_backup_directory.c:186 +#: pg_backup_directory.c:189 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "no se pudo leer el directorio «%s»: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: pg_backup_directory.c:190 +#: pg_backup_directory.c:195 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "no se pudo cerrar el directorio «%s»: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" -#: pg_backup_directory.c:196 +#: pg_backup_directory.c:350 pg_backup_directory.c:488 +#: pg_backup_directory.c:518 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "no se pudo crear el directorio «%s»: %s\n" +msgid "could not write to output file: %s" +msgstr "no se pudo escribir al archivo de salida: %s" -#: pg_backup_directory.c:407 +#: pg_backup_directory.c:403 #, c-format -msgid "could not close data file: %s\n" -msgstr "no se pudo cerrar el archivo de datos: %s\n" +msgid "could not close data file: %m" +msgstr "no se pudo cerrar el archivo de datos: %m" -#: pg_backup_directory.c:448 +#: pg_backup_directory.c:443 #, c-format -msgid "could not open large object TOC file \"%s\" for input: %s\n" -msgstr "no se pudo abrir el archivo de la tabla de contenidos de objetos grandes «%s» para su lectura: %s\n" +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "no se pudo abrir el archivo de la tabla de contenidos de objetos grandes «%s» para su lectura: %m" -#: pg_backup_directory.c:459 +#: pg_backup_directory.c:454 #, c-format -msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" -msgstr "línea no válida en el archivo de la tabla de contenido de objetos grandes «%s»: «%s»\n" +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "línea no válida en el archivo de la tabla de contenido de objetos grandes «%s»: «%s»" -#: pg_backup_directory.c:468 +#: pg_backup_directory.c:463 #, c-format -msgid "error reading large object TOC file \"%s\"\n" -msgstr "error al leer el archivo de la tabla de contenidos de objetos grandes «%s»\n" +msgid "error reading large object TOC file \"%s\"" +msgstr "error al leer el archivo de la tabla de contenidos de objetos grandes «%s»" -#: pg_backup_directory.c:472 +#: pg_backup_directory.c:467 #, c-format -msgid "could not close large object TOC file \"%s\": %s\n" -msgstr "no se pudo cerrar el archivo de la tabla de contenido de los objetos grandes «%s»: %s\n" +msgid "could not close large object TOC file \"%s\": %m" +msgstr "no se pudo cerrar el archivo de la tabla de contenido de los objetos grandes «%s»: %m" -#: pg_backup_directory.c:686 +#: pg_backup_directory.c:678 #, c-format -msgid "could not write to blobs TOC file\n" -msgstr "no se pudo escribir al archivo de la tabla de contenidos de objetos grandes\n" +msgid "could not write to blobs TOC file" +msgstr "no se pudo escribir al archivo de la tabla de contenidos de objetos grandes" -#: pg_backup_directory.c:718 +#: pg_backup_directory.c:710 #, c-format -msgid "file name too long: \"%s\"\n" -msgstr "nombre de archivo demasiado largo: «%s»\n" +msgid "file name too long: \"%s\"" +msgstr "nombre de archivo demasiado largo: «%s»" #: pg_backup_null.c:75 #, c-format -msgid "this format cannot be read\n" -msgstr "no se puede leer este formato\n" +msgid "this format cannot be read" +msgstr "no se puede leer este formato" -#. translator: this is a module name -#: pg_backup_tar.c:103 -msgid "tar archiver" -msgstr "tar archiver" - -#: pg_backup_tar.c:181 +#: pg_backup_tar.c:177 #, c-format -msgid "could not open TOC file \"%s\" for output: %s\n" -msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para escribir: %s\n" +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para escribir: %m" -#: pg_backup_tar.c:189 +#: pg_backup_tar.c:184 #, c-format -msgid "could not open TOC file for output: %s\n" -msgstr "no se pudo abrir la tabla de contenido para escribir: %s\n" +msgid "could not open TOC file for output: %m" +msgstr "no se pudo abrir la tabla de contenido para escribir: %m" -#: pg_backup_tar.c:210 pg_backup_tar.c:366 +#: pg_backup_tar.c:203 pg_backup_tar.c:358 #, c-format -msgid "compression is not supported by tar archive format\n" -msgstr "la compresión no está soportada por el formato de salida tar\n" +msgid "compression is not supported by tar archive format" +msgstr "la compresión no está soportada por el formato de salida tar" -#: pg_backup_tar.c:218 +#: pg_backup_tar.c:211 #, c-format -msgid "could not open TOC file \"%s\" for input: %s\n" -msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para leer: %s\n" +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "no se pudo abrir el archivo de tabla de contenido «%s» para leer: %m" -#: pg_backup_tar.c:225 +#: pg_backup_tar.c:218 #, c-format -msgid "could not open TOC file for input: %s\n" -msgstr "no se pudo abrir la tabla de contenido para leer: %s\n" +msgid "could not open TOC file for input: %m" +msgstr "no se pudo abrir la tabla de contenido para leer: %m" -#: pg_backup_tar.c:352 +#: pg_backup_tar.c:344 #, c-format -msgid "could not find file \"%s\" in archive\n" -msgstr "no se pudo encontrar el archivo «%s» en el archivador\n" +msgid "could not find file \"%s\" in archive" +msgstr "no se pudo encontrar el archivo «%s» en el archivador" -#: pg_backup_tar.c:418 +#: pg_backup_tar.c:410 #, c-format -msgid "could not generate temporary file name: %s\n" -msgstr "no se pudo generar el nombre de archivo temporal: %s\n" +msgid "could not generate temporary file name: %m" +msgstr "no se pudo generar el nombre de archivo temporal: %m" -#: pg_backup_tar.c:429 +#: pg_backup_tar.c:421 #, c-format -msgid "could not open temporary file\n" -msgstr "no se pudo abrir archivo temporal\n" +msgid "could not open temporary file" +msgstr "no se pudo abrir archivo temporal" -#: pg_backup_tar.c:456 +#: pg_backup_tar.c:448 #, c-format -msgid "could not close tar member\n" -msgstr "no se pudo cerrar miembro del archivo tar\n" +msgid "could not close tar member" +msgstr "no se pudo cerrar miembro del archivo tar" -#: pg_backup_tar.c:569 +#: pg_backup_tar.c:571 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "error interno --- no se especificó th ni fh en tarReadRaw()\n" -#: pg_backup_tar.c:692 +#: pg_backup_tar.c:693 #, c-format -msgid "unexpected COPY statement syntax: \"%s\"\n" -msgstr "sintaxis de sentencia COPY inesperada: «%s»\n" +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "sintaxis de sentencia COPY inesperada: «%s»" -#: pg_backup_tar.c:962 +#: pg_backup_tar.c:961 #, c-format -msgid "invalid OID for large object (%u)\n" -msgstr "el OID del objeto grande no es válido (%u)\n" +msgid "invalid OID for large object (%u)" +msgstr "el OID del objeto grande no es válido (%u)" #: pg_backup_tar.c:1106 #, c-format -msgid "could not close temporary file: %s\n" -msgstr "no se pudo abrir archivo temporal: %s\n" - -#: pg_backup_tar.c:1116 -#, c-format -msgid "actual file length (%s) does not match expected (%s)\n" -msgstr "el tamaño real del archivo (%s) no coincide con el esperado (%s)\n" - -#: pg_backup_tar.c:1153 -#, c-format -msgid "moving from position %s to next member at file position %s\n" -msgstr "moviendo desde la posición %s a la posición del siguiente miembro %s\n" - -#: pg_backup_tar.c:1164 -#, c-format -msgid "now at file position %s\n" -msgstr "ahora en la posición del archivo %s\n" - -#: pg_backup_tar.c:1173 pg_backup_tar.c:1203 -#, c-format -msgid "could not find header for file \"%s\" in tar archive\n" -msgstr "no se pudo encontrar el encabezado para el archivo «%s» en el archivo tar\n" +msgid "could not close temporary file: %m" +msgstr "no se pudo abrir archivo temporal: %m" -#: pg_backup_tar.c:1187 +#: pg_backup_tar.c:1115 #, c-format -msgid "skipping tar member %s\n" -msgstr "saltando miembro del archivo tar %s\n" +msgid "actual file length (%s) does not match expected (%s)" +msgstr "el tamaño real del archivo (%s) no coincide con el esperado (%s)" -#: pg_backup_tar.c:1191 +#: pg_backup_tar.c:1172 pg_backup_tar.c:1202 #, c-format -msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file.\n" -msgstr "" -"la extracción de datos fuera de orden no está soportada en este formato:\n" -"se requiere «%s», pero viene antes de «%s» en el archivador.\n" +msgid "could not find header for file \"%s\" in tar archive" +msgstr "no se pudo encontrar el encabezado para el archivo «%s» en el archivo tar" -#: pg_backup_tar.c:1237 +#: pg_backup_tar.c:1190 #, c-format -msgid "incomplete tar header found (%lu byte)\n" -msgid_plural "incomplete tar header found (%lu bytes)\n" -msgstr[0] "se encontró un encabezado incompleto (%lu byte)\n" -msgstr[1] "se encontró un encabezado incompleto (%lu bytes)\n" +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "la extracción de datos fuera de orden no está soportada en este formato: se requiere «%s», pero viene antes de «%s» en el archivador." -#: pg_backup_tar.c:1278 +#: pg_backup_tar.c:1235 #, c-format -msgid "TOC Entry %s at %s (length %s, checksum %d)\n" -msgstr "entrada TOC %s en %s (tamaño %s, suma de integridad %d)\n" +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "se encontró un encabezado incompleto (%lu byte)" +msgstr[1] "se encontró un encabezado incompleto (%lu bytes)" -#: pg_backup_tar.c:1289 +#: pg_backup_tar.c:1286 #, c-format -msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" -msgstr "" -"se encontró un encabezado corrupto en %s (esperado %d, calculado %d)\n" -"en la posición %s\n" +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "se encontró un encabezado corrupto en %s (esperado %d, calculado %d) en la posición %s" #: pg_backup_utils.c:54 #, c-format -msgid "%s: unrecognized section name: \"%s\"\n" -msgstr "%s: nombre de sección «%s» no reconocido\n" +msgid "unrecognized section name: \"%s\"" +msgstr "nombre de sección «%s» no reconocido" -#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:313 -#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 -#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 +#: pg_backup_utils.c:55 pg_dump.c:611 pg_dump.c:628 pg_dumpall.c:333 +#: pg_dumpall.c:343 pg_dumpall.c:352 pg_dumpall.c:361 pg_dumpall.c:369 +#: pg_dumpall.c:383 pg_dumpall.c:459 pg_restore.c:288 pg_restore.c:304 +#: pg_restore.c:322 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prueba «%s --help» para más información.\n" -#: pg_backup_utils.c:118 +#: pg_backup_utils.c:68 #, c-format -msgid "out of on_exit_nicely slots\n" -msgstr "elementos on_exit_nicely agotados\n" +msgid "out of on_exit_nicely slots" +msgstr "elementos on_exit_nicely agotados" -#: pg_dump.c:511 +#: pg_dump.c:542 #, c-format -msgid "compression level must be in range 0..9\n" -msgstr "nivel de compresión debe estar en el rango 0..9\n" +msgid "compression level must be in range 0..9" +msgstr "nivel de compresión debe estar en el rango 0..9" -#: pg_dump.c:560 pg_dumpall.c:321 pg_restore.c:297 +#: pg_dump.c:580 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos en la línea de órdenes (el primero es «%s»)\n" +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_floats_digits debe estar en el rango -15..3" -#: pg_dump.c:581 +#: pg_dump.c:603 #, c-format -msgid "options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "las opciones -s/--schema-only y -a/--data-only no pueden usarse juntas\n" +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert debe estar en el rango %d..%d" -#: pg_dump.c:587 +#: pg_dump.c:626 pg_dumpall.c:341 pg_restore.c:302 #, c-format -msgid "options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "las opciones -c/--clean y -a/--data-only no pueden usarse juntas\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_dump.c:593 +#: pg_dump.c:647 pg_restore.c:331 #, c-format -msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" -msgstr "las opciones --inserts/--column-inserts y -o/--oids no pueden usarse juntas\n" +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "las opciones -s/--schema-only y -a/--data-only no pueden usarse juntas" -#: pg_dump.c:594 +#: pg_dump.c:653 pg_restore.c:337 #, c-format -msgid "(The INSERT command cannot set OIDs.)\n" -msgstr "(La orden INSERT no puede establecer los OIDs).\n" +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "las opciones -c/--clean y -a/--data-only no pueden usarse juntas" -#: pg_dump.c:599 +#: pg_dump.c:658 pg_dumpall.c:376 pg_restore.c:386 #, c-format -msgid "option --if-exists requires option -c/--clean\n" -msgstr "la opción --if-exists requiere la opción -c/--clean\n" +msgid "option --if-exists requires option -c/--clean" +msgstr "la opción --if-exists requiere la opción -c/--clean" -#: pg_dump.c:621 +#: pg_dump.c:665 #, c-format -msgid "WARNING: requested compression not available in this installation -- archive will be uncompressed\n" -msgstr "" -"PRECAUCIÓN: la compresión solicitada no está soportada en esta\n" -"instalación -- el archivador no será comprimido\n" +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts" +msgstr "la opción --on-conflict-do-nothing requiere la opción --inserts, --rows-per-insert o --column-inserts" -#: pg_dump.c:636 +#: pg_dump.c:687 #, c-format -msgid "invalid number of parallel jobs\n" -msgstr "número no válido de trabajos paralelos\n" +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "la compresión solicitada no está soportada en esta instalación -- el archivador será sin compresión" -#: pg_dump.c:640 +#: pg_dump.c:708 pg_restore.c:353 #, c-format -msgid "parallel backup only supported by the directory format\n" -msgstr "el volcado en paralelo sólo está soportado por el formato «directory»\n" +msgid "invalid number of parallel jobs" +msgstr "número no válido de trabajos paralelos" -#: pg_dump.c:695 +#: pg_dump.c:712 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "el volcado en paralelo sólo está soportado por el formato «directory»" + +#: pg_dump.c:767 #, c-format msgid "" "Synchronized snapshots are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" "Los snapshots sincronizados no están soportados por esta versión del servidor.\n" -"Ejecute con --no-synchronized-snapshots si no los necesita.\n" +"Ejecute con --no-synchronized-snapshots si no los necesita." -#: pg_dump.c:702 +#: pg_dump.c:773 #, c-format -msgid "Exported snapshots are not supported by this server version.\n" -msgstr "Los snapshot exportados no están soportados por esta versión de servidor.\n" +msgid "Exported snapshots are not supported by this server version." +msgstr "Los snapshot exportados no están soportados por esta versión de servidor." -#: pg_dump.c:716 +#: pg_dump.c:785 #, c-format -msgid "last built-in OID is %u\n" -msgstr "el último OID interno es %u\n" +msgid "last built-in OID is %u" +msgstr "el último OID interno es %u" -#: pg_dump.c:725 +#: pg_dump.c:794 #, c-format -msgid "no matching schemas were found\n" -msgstr "no se encontraron esquemas coincidentes\n" +msgid "no matching schemas were found" +msgstr "no se encontraron esquemas coincidentes" -#: pg_dump.c:739 +#: pg_dump.c:808 #, c-format -msgid "no matching tables were found\n" -msgstr "no se encontraron tablas coincidentes\n" +msgid "no matching tables were found" +msgstr "no se encontraron tablas coincidentes" -#: pg_dump.c:913 +#: pg_dump.c:980 #, c-format msgid "" "%s dumps a database as a text file or to other formats.\n" @@ -1454,17 +1331,17 @@ msgstr "" "%s extrae una base de datos en formato de texto o en otros formatos.\n" "\n" -#: pg_dump.c:914 pg_dumpall.c:575 pg_restore.c:449 +#: pg_dump.c:981 pg_dumpall.c:612 pg_restore.c:466 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_dump.c:915 +#: pg_dump.c:982 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPCIÓN]... [NOMBREDB]\n" -#: pg_dump.c:917 pg_dumpall.c:578 pg_restore.c:452 +#: pg_dump.c:984 pg_dumpall.c:615 pg_restore.c:469 #, c-format msgid "" "\n" @@ -1473,12 +1350,12 @@ msgstr "" "\n" "Opciones generales:\n" -#: pg_dump.c:918 +#: pg_dump.c:985 #, c-format msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=ARCHIVO nombre del archivo o directorio de salida\n" -#: pg_dump.c:919 +#: pg_dump.c:986 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1487,42 +1364,42 @@ msgstr "" " -F, --format=c|d|t|p Formato del archivo de salida (c=personalizado, \n" " d=directorio, t=tar, p=texto (por omisión))\n" -#: pg_dump.c:921 +#: pg_dump.c:988 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM máximo de procesos paralelos para volcar\n" -#: pg_dump.c:922 pg_dumpall.c:580 +#: pg_dump.c:989 pg_dumpall.c:617 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose modo verboso\n" -#: pg_dump.c:923 pg_dumpall.c:581 +#: pg_dump.c:990 pg_dumpall.c:618 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de version y salir\n" -#: pg_dump.c:924 +#: pg_dump.c:991 #, c-format msgid " -Z, --compress=0-9 compression level for compressed formats\n" msgstr " -Z, --compress=0-9 nivel de compresión para formatos comprimidos\n" -#: pg_dump.c:925 pg_dumpall.c:582 +#: pg_dump.c:992 pg_dumpall.c:619 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=SEGS espera a lo más SEGS segundos obtener un lock\n" -#: pg_dump.c:926 pg_dumpall.c:605 +#: pg_dump.c:993 pg_dumpall.c:646 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync no esperar que los cambios se sincronicen a disco\n" -#: pg_dump.c:927 pg_dumpall.c:583 +#: pg_dump.c:994 pg_dumpall.c:620 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: pg_dump.c:929 pg_dumpall.c:584 +#: pg_dump.c:996 pg_dumpall.c:621 #, c-format msgid "" "\n" @@ -1531,54 +1408,49 @@ msgstr "" "\n" "Opciones que controlan el contenido de la salida:\n" -#: pg_dump.c:930 pg_dumpall.c:585 +#: pg_dump.c:997 pg_dumpall.c:622 #, c-format msgid " -a, --data-only dump only the data, not the schema\n" msgstr " -a, --data-only extrae sólo los datos, no el esquema\n" -#: pg_dump.c:931 +#: pg_dump.c:998 #, c-format msgid " -b, --blobs include large objects in dump\n" msgstr " -b, --blobs incluye objetos grandes en la extracción\n" -#: pg_dump.c:932 +#: pg_dump.c:999 #, c-format msgid " -B, --no-blobs exclude large objects in dump\n" msgstr " -B, --no-blobs excluye objetos grandes en la extracción\n" -#: pg_dump.c:933 pg_restore.c:463 +#: pg_dump.c:1000 pg_restore.c:480 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean tira (drop) la base de datos antes de crearla\n" -#: pg_dump.c:934 +#: pg_dump.c:1001 #, c-format msgid " -C, --create include commands to create database in dump\n" msgstr "" " -C, --create incluye órdenes para crear la base de datos\n" " en la extracción\n" -#: pg_dump.c:935 +#: pg_dump.c:1002 pg_dumpall.c:624 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=CODIF extrae los datos con la codificación CODIF\n" -#: pg_dump.c:936 +#: pg_dump.c:1003 #, c-format msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" msgstr " -n, --schema=ESQUEMA extrae sólo el esquema nombrado\n" -#: pg_dump.c:937 +#: pg_dump.c:1004 #, c-format msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" msgstr " -N, --exclude-schema=ESQUEMA NO extrae el o los esquemas nombrados\n" -#: pg_dump.c:938 pg_dumpall.c:588 -#, c-format -msgid " -o, --oids include OIDs in dump\n" -msgstr " -o, --oids incluye OIDs en la extracción\n" - -#: pg_dump.c:939 +#: pg_dump.c:1005 #, c-format msgid "" " -O, --no-owner skip restoration of object ownership in\n" @@ -1587,58 +1459,58 @@ msgstr "" " -O, --no-owner en formato de sólo texto, no reestablece\n" " los dueños de los objetos\n" -#: pg_dump.c:941 pg_dumpall.c:591 +#: pg_dump.c:1007 pg_dumpall.c:628 #, c-format msgid " -s, --schema-only dump only the schema, no data\n" msgstr " -s, --schema-only extrae sólo el esquema, no los datos\n" -#: pg_dump.c:942 +#: pg_dump.c:1008 #, c-format msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" msgstr " -S, --superuser=NAME superusuario a utilizar en el volcado de texto\n" -#: pg_dump.c:943 +#: pg_dump.c:1009 #, c-format msgid " -t, --table=TABLE dump the named table(s) only\n" msgstr " -t, --table=TABLE extrae sólo la o las tablas nombradas\n" -#: pg_dump.c:944 +#: pg_dump.c:1010 #, c-format msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" msgstr " -T, --exclude-table=TABLA NO extrae la(s) tabla(s) nombrada(s)\n" -#: pg_dump.c:945 pg_dumpall.c:594 +#: pg_dump.c:1011 pg_dumpall.c:631 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges no extrae los privilegios (grant/revoke)\n" -#: pg_dump.c:946 pg_dumpall.c:595 +#: pg_dump.c:1012 pg_dumpall.c:632 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade sólo para uso de utilidades de upgrade\n" -#: pg_dump.c:947 pg_dumpall.c:596 +#: pg_dump.c:1013 pg_dumpall.c:633 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr "" " --column-inserts extrae los datos usando INSERT con nombres\n" " de columnas\n" -#: pg_dump.c:948 pg_dumpall.c:597 +#: pg_dump.c:1014 pg_dumpall.c:634 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr "" " --disable-dollar-quoting deshabilita el uso de «delimitadores de dólar»,\n" " usa delimitadores de cadena estándares\n" -#: pg_dump.c:949 pg_dumpall.c:598 pg_restore.c:480 +#: pg_dump.c:1015 pg_dumpall.c:635 pg_restore.c:497 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr "" " --disable-triggers deshabilita los disparadores (triggers) durante el\n" " restablecimiento de la extracción de sólo-datos\n" -#: pg_dump.c:950 +#: pg_dump.c:1016 #, c-format msgid "" " --enable-row-security enable row security (dump only content user has\n" @@ -1647,80 +1519,105 @@ msgstr "" " --enable-row-security activa seguridad de filas (volcar sólo el\n" " contenido al que el usuario tiene acceso)\n" -#: pg_dump.c:952 +#: pg_dump.c:1018 #, c-format msgid " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" msgstr " --exclude-table-data=TABLA NO extrae los datos de la(s) tabla(s) nombrada(s)\n" -#: pg_dump.c:953 pg_dumpall.c:599 pg_restore.c:482 +#: pg_dump.c:1019 pg_dumpall.c:637 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM usa este valor para extra_float_digits\n" + +#: pg_dump.c:1020 pg_dumpall.c:638 pg_restore.c:499 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists usa IF EXISTS al eliminar objetos\n" -#: pg_dump.c:954 pg_dumpall.c:600 +#: pg_dump.c:1021 pg_dumpall.c:639 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts extrae los datos usando INSERT, en vez de COPY\n" -#: pg_dump.c:955 pg_dumpall.c:601 +#: pg_dump.c:1022 pg_dumpall.c:640 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root cargar particiones a través de tabla raíz\n" + +#: pg_dump.c:1023 pg_dumpall.c:641 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments no volcar los comentarios\n" + +#: pg_dump.c:1024 pg_dumpall.c:642 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications no volcar las publicaciones\n" -#: pg_dump.c:956 pg_dumpall.c:603 +#: pg_dump.c:1025 pg_dumpall.c:644 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels no volcar asignaciones de etiquetas de seguridad\n" -#: pg_dump.c:957 pg_dumpall.c:604 +#: pg_dump.c:1026 pg_dumpall.c:645 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions no volcar las suscripciones\n" -#: pg_dump.c:958 +#: pg_dump.c:1027 #, c-format msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" msgstr "" " --no-synchronized-snapshots no usar snapshots sincronizados en trabajos\n" " en paralelo\n" -#: pg_dump.c:959 pg_dumpall.c:606 +#: pg_dump.c:1028 pg_dumpall.c:647 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces no volcar asignaciones de tablespace\n" -#: pg_dump.c:960 pg_dumpall.c:607 +#: pg_dump.c:1029 pg_dumpall.c:648 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data no volcar datos de tablas unlogged\n" -#: pg_dump.c:961 pg_dumpall.c:608 +#: pg_dump.c:1030 pg_dumpall.c:649 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-confict-do-nothing agregar ON CONFLICT DO NOTHING a órdenes INSERT\n" + +#: pg_dump.c:1031 pg_dumpall.c:650 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr "" " --quote-all-identifiers entrecomilla todos los identificadores, incluso\n" " si no son palabras clave\n" -#: pg_dump.c:962 +#: pg_dump.c:1032 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NUMFILAS número de filas por INSERT; implica --inserts\n" + +#: pg_dump.c:1033 #, c-format msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" msgstr "" " --section=SECCIÓN volcar la sección nombrada (pre-data, data,\n" " post-data)\n" -#: pg_dump.c:963 +#: pg_dump.c:1034 #, c-format msgid " --serializable-deferrable wait until the dump can run without anomalies\n" msgstr "" " --serializable-deferrable espera hasta que el respaldo pueda completarse\n" " sin anomalías\n" -#: pg_dump.c:964 +#: pg_dump.c:1035 #, c-format msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT use el snapshot dado para la extracción\n" -#: pg_dump.c:965 pg_restore.c:490 +#: pg_dump.c:1036 pg_restore.c:508 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -1729,7 +1626,7 @@ msgstr "" " --strict-names requerir al menos una coincidencia para cada patrón\n" " de nombre de tablas y esquemas\n" -#: pg_dump.c:967 pg_dumpall.c:609 pg_restore.c:492 +#: pg_dump.c:1038 pg_dumpall.c:651 pg_restore.c:510 #, c-format msgid "" " --use-set-session-authorization\n" @@ -1740,7 +1637,7 @@ msgstr "" " usa órdenes SESSION AUTHORIZATION en lugar de\n" " ALTER OWNER para cambiar los dueño de los objetos\n" -#: pg_dump.c:971 pg_dumpall.c:613 pg_restore.c:496 +#: pg_dump.c:1042 pg_dumpall.c:655 pg_restore.c:514 #, c-format msgid "" "\n" @@ -1749,46 +1646,46 @@ msgstr "" "\n" "Opciones de conexión:\n" -#: pg_dump.c:972 +#: pg_dump.c:1043 #, c-format msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=NOMBRE nombre de la base de datos que volcar\n" -#: pg_dump.c:973 pg_dumpall.c:615 pg_restore.c:497 +#: pg_dump.c:1044 pg_dumpall.c:657 pg_restore.c:515 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=ANFITRIÓN anfitrión de la base de datos o\n" " directorio del enchufe (socket)\n" -#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:498 +#: pg_dump.c:1045 pg_dumpall.c:659 pg_restore.c:516 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PUERTO número del puerto de la base de datos\n" -#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:499 +#: pg_dump.c:1046 pg_dumpall.c:660 pg_restore.c:517 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=USUARIO nombre de usuario con el cual conectarse\n" -#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:500 +#: pg_dump.c:1047 pg_dumpall.c:661 pg_restore.c:518 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password nunca pedir una contraseña\n" -#: pg_dump.c:977 pg_dumpall.c:620 pg_restore.c:501 +#: pg_dump.c:1048 pg_dumpall.c:662 pg_restore.c:519 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr "" " -W, --password fuerza un prompt para la contraseña\n" " (debería ser automático)\n" -#: pg_dump.c:978 pg_dumpall.c:621 +#: pg_dump.c:1049 pg_dumpall.c:663 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROL ejecuta SET ROLE antes del volcado\n" -#: pg_dump.c:980 +#: pg_dump.c:1051 #, c-format msgid "" "\n" @@ -1801,543 +1698,579 @@ msgstr "" "de la variable de ambiente PGDATABASE.\n" "\n" -#: pg_dump.c:982 pg_dumpall.c:625 pg_restore.c:508 +#: pg_dump.c:1053 pg_dumpall.c:667 pg_restore.c:526 #, c-format -msgid "Report bugs to .\n" -msgstr "Reporta errores a .\n" +msgid "Report bugs to .\n" +msgstr "Reporta errores a .\n" -#: pg_dump.c:999 +#: pg_dump.c:1072 pg_dumpall.c:494 #, c-format -msgid "invalid client encoding \"%s\" specified\n" -msgstr "la codificación de cliente especificada «%s» no es válida\n" +msgid "invalid client encoding \"%s\" specified" +msgstr "la codificación de cliente especificada «%s» no es válida" -#: pg_dump.c:1136 +#: pg_dump.c:1218 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" -"Los snapshots sincronizados no están soportados en servidores standby.\n" -"Ejecute con --no-synchronized-snapshots si no los necesita.\n" +"Los snapshots sincronizados en servidores standby no están soportados por esta versión del servidor.\n" +"Ejecute con --no-synchronized-snapshots si no los necesita." -#: pg_dump.c:1205 +#: pg_dump.c:1287 #, c-format -msgid "invalid output format \"%s\" specified\n" -msgstr "el formato de salida especificado «%s» no es válido\n" +msgid "invalid output format \"%s\" specified" +msgstr "el formato de salida especificado «%s» no es válido" -#: pg_dump.c:1243 +#: pg_dump.c:1325 #, c-format -msgid "no matching schemas were found for pattern \"%s\"\n" -msgstr "no se encontraron esquemas coincidentes para el patrón «%s»\n" +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "no se encontraron esquemas coincidentes para el patrón «%s»" -#: pg_dump.c:1297 +#: pg_dump.c:1390 #, c-format -msgid "no matching tables were found for pattern \"%s\"\n" -msgstr "no se encontraron tablas coincidentes para el patrón «%s»\n" +msgid "no matching tables were found for pattern \"%s\"" +msgstr "no se encontraron tablas coincidentes para el patrón «%s»" -#: pg_dump.c:1701 +#: pg_dump.c:1804 #, c-format -msgid "dumping contents of table \"%s.%s\"\n" -msgstr "extrayendo el contenido de la tabla «%s.%s»\n" +msgid "dumping contents of table \"%s.%s\"" +msgstr "extrayendo el contenido de la tabla «%s.%s»" -#: pg_dump.c:1822 +#: pg_dump.c:1905 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" -msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetCopyData() falló.\n" +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetCopyData() falló." -#: pg_dump.c:1823 pg_dump.c:1833 +#: pg_dump.c:1906 pg_dump.c:1916 #, c-format msgid "Error message from server: %s" msgstr "Mensaje de error del servidor: %s" -#: pg_dump.c:1824 pg_dump.c:1834 +#: pg_dump.c:1907 pg_dump.c:1917 +#, c-format +msgid "The command was: %s" +msgstr "La orden era: %s" + +#: pg_dump.c:1915 #, c-format -msgid "The command was: %s\n" -msgstr "La orden era: %s\n" +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetResult() falló." -#: pg_dump.c:1832 +#: pg_dump.c:2666 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" -msgstr "Falló la extracción del contenido de la tabla «%s»: PQgetResult() falló.\n" +msgid "saving database definition" +msgstr "salvando las definiciones de la base de datos" -#: pg_dump.c:2481 +#: pg_dump.c:3130 #, c-format -msgid "saving database definition\n" -msgstr "salvando las definiciones de la base de datos\n" +msgid "saving encoding = %s" +msgstr "salvando codificaciones = %s" -#: pg_dump.c:2787 +#: pg_dump.c:3155 #, c-format -msgid "saving encoding = %s\n" -msgstr "salvando codificaciones = %s\n" +msgid "saving standard_conforming_strings = %s" +msgstr "salvando standard_conforming_strings = %s" -#: pg_dump.c:2814 +#: pg_dump.c:3194 #, c-format -msgid "saving standard_conforming_strings = %s\n" -msgstr "salvando standard_conforming_strings = %s\n" +msgid "could not parse result of current_schemas()" +msgstr "no se pudo interpretar la salida de current_schemas()" -#: pg_dump.c:2854 +#: pg_dump.c:3213 #, c-format -msgid "reading large objects\n" -msgstr "leyendo objetos grandes\n" +msgid "saving search_path = %s" +msgstr "salvando search_path = %s" -#: pg_dump.c:3049 +#: pg_dump.c:3253 #, c-format -msgid "saving large objects\n" -msgstr "salvando objetos grandes\n" +msgid "reading large objects" +msgstr "leyendo objetos grandes" -#: pg_dump.c:3094 +#: pg_dump.c:3435 +#, c-format +msgid "saving large objects" +msgstr "salvando objetos grandes" + +#: pg_dump.c:3481 #, c-format msgid "error reading large object %u: %s" msgstr "error al leer el objeto grande %u: %s" -#: pg_dump.c:3147 +#: pg_dump.c:3533 #, c-format -msgid "reading row security enabled for table \"%s.%s\"\n" -msgstr "leyendo si seguridad de filas está activa para la tabla «%s.%s»\n" +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "leyendo si seguridad de filas está activa para la tabla «%s.%s»" -#: pg_dump.c:3179 +#: pg_dump.c:3564 #, c-format -msgid "reading policies for table \"%s.%s\"\n" -msgstr "extrayendo las políticas para la tabla «%s.%s»\n" +msgid "reading policies for table \"%s.%s\"" +msgstr "extrayendo las políticas para la tabla «%s.%s»" -#: pg_dump.c:3329 +#: pg_dump.c:3714 #, c-format -msgid "unexpected policy command type: %c\n" -msgstr "tipo de orden inesperada en política: %c\n" +msgid "unexpected policy command type: %c" +msgstr "tipo de orden inesperada en política: %c" -#: pg_dump.c:3445 +#: pg_dump.c:3841 #, c-format -msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la publicación «%s» parece no ser válido\n" +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "el dueño de la publicación «%s» parece no ser válido" -#: pg_dump.c:3575 +#: pg_dump.c:3978 #, c-format -msgid "reading publication membership for table \"%s.%s\"\n" -msgstr "extrayendo la membresía en publicaciones para la tabla «%s.%s»\n" +msgid "reading publication membership for table \"%s.%s\"" +msgstr "extrayendo la membresía en publicaciones para la tabla «%s.%s»" -#: pg_dump.c:3722 +#: pg_dump.c:4121 #, c-format -msgid "WARNING: subscriptions not dumped because current user is not a superuser\n" -msgstr "PRECAUCIÓN: no se volcaron las suscripciones porque el usuario actual no es un superusuario\n" +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "no se volcaron las suscripciones porque el usuario actual no es un superusuario" -#: pg_dump.c:3776 +#: pg_dump.c:4175 #, c-format -msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la suscripción «%s» parece no ser válido\n" +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "el dueño de la suscripción «%s» parece no ser válido" -#: pg_dump.c:3820 +#: pg_dump.c:4219 #, c-format -msgid "WARNING: could not parse subpublications array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo subpublications\n" +msgid "could not parse subpublications array" +msgstr "no se pudo interpretar el arreglo subpublications" -#: pg_dump.c:4053 +#: pg_dump.c:4491 #, c-format -msgid "could not find parent extension for %s\n" -msgstr "no se pudo encontrar la extensión padre para %s\n" +msgid "could not find parent extension for %s %s" +msgstr "no se pudo encontrar la extensión padre para %s %s" -#: pg_dump.c:4207 +#: pg_dump.c:4623 #, c-format -msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño del esquema «%s» parece no ser válido\n" +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "el dueño del esquema «%s» parece no ser válido" -#: pg_dump.c:4230 +#: pg_dump.c:4646 #, c-format -msgid "schema with OID %u does not exist\n" -msgstr "el esquema con OID %u no existe\n" +msgid "schema with OID %u does not exist" +msgstr "no existe el esquema con OID %u" -#: pg_dump.c:4561 +#: pg_dump.c:4971 #, c-format -msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño del tipo «%s» parece no ser válido\n" +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "el dueño del tipo «%s» parece no ser válido" -#: pg_dump.c:4649 +#: pg_dump.c:5056 #, c-format -msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño del operador «%s» parece no ser válido\n" +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "el dueño del operador «%s» parece no ser válido" -#: pg_dump.c:4963 +#: pg_dump.c:5358 #, c-format -msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la clase de operadores «%s» parece no ser válido\n" +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "el dueño de la clase de operadores «%s» parece no ser válido" -#: pg_dump.c:5050 +#: pg_dump.c:5442 #, c-format -msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la familia de operadores «%s» parece no ser válido\n" +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "el dueño de la familia de operadores «%s» parece no ser válido" -#: pg_dump.c:5217 +#: pg_dump.c:5611 #, c-format -msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la función de agregación «%s» parece no ser válido\n" +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "el dueño de la función de agregación «%s» parece no ser válido" -#: pg_dump.c:5476 +#: pg_dump.c:5871 #, c-format -msgid "WARNING: owner of function \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la función «%s» parece no ser válido\n" +msgid "owner of function \"%s\" appears to be invalid" +msgstr "el dueño de la función «%s» parece no ser válido" -#: pg_dump.c:6258 +#: pg_dump.c:6675 #, c-format -msgid "WARNING: owner of table \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el dueño de la tabla «%s» parece no ser válido\n" +msgid "owner of table \"%s\" appears to be invalid" +msgstr "el dueño de la tabla «%s» parece no ser válido" -#: pg_dump.c:6300 pg_dump.c:16529 +#: pg_dump.c:6717 pg_dump.c:17067 #, c-format -msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found\n" -msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u de la secuencia con OID %u\n" +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u de la secuencia con OID %u" -#: pg_dump.c:6431 +#: pg_dump.c:6861 #, c-format -msgid "reading indexes for table \"%s.%s\"\n" -msgstr "extrayendo los índices para la tabla «%s.%s»\n" +msgid "reading indexes for table \"%s.%s\"" +msgstr "extrayendo los índices para la tabla «%s.%s»" -#: pg_dump.c:6712 +#: pg_dump.c:7262 #, c-format -msgid "reading extended statistics for table \"%s.%s\"\n" -msgstr "extrayendo las estadísticas extendidas para la tabla «%s.%s»\n" +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "extrayendo restricciones de llave foránea para la tabla «%s.%s»" -#: pg_dump.c:6795 +#: pg_dump.c:7481 #, c-format -msgid "reading foreign key constraints for table \"%s.%s\"\n" -msgstr "extrayendo restricciones de llave foránea para la tabla «%s.%s»\n" +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u del elemento con OID %u de pg_rewrite" -#: pg_dump.c:7019 +#: pg_dump.c:7564 #, c-format -msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n" -msgstr "falló la revisión de integridad, no se encontró la tabla padre con OID %u del elemento con OID %u de pg_rewrite\n" +msgid "reading triggers for table \"%s.%s\"" +msgstr "extrayendo los disparadores (triggers) para la tabla «%s.%s»" -#: pg_dump.c:7103 +#: pg_dump.c:7697 #, c-format -msgid "reading triggers for table \"%s.%s\"\n" -msgstr "extrayendo los disparadores (triggers) para la tabla «%s.%s»\n" +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "la consulta produjo un nombre de tabla nulo para la llave foránea del disparador \"%s\" en la tabla «%s» (OID de la tabla: %u)" -#: pg_dump.c:7241 +#: pg_dump.c:8252 #, c-format -msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n" -msgstr "" -"la consulta produjo un nombre de tabla nulo para la llave foránea del \n" -"disparador \"%s\" en la tabla «%s» (OID de la tabla: %u)\n" +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "buscando las columnas y tipos de la tabla «%s.%s»" -#: pg_dump.c:7813 +#: pg_dump.c:8388 #, c-format -msgid "finding the columns and types of table \"%s.%s\"\n" -msgstr "buscando las columnas y tipos de la tabla «%s.%s»\n" +msgid "invalid column numbering in table \"%s\"" +msgstr "numeración de columnas no válida en la tabla «%s»" -#: pg_dump.c:7978 +#: pg_dump.c:8425 #, c-format -msgid "invalid column numbering in table \"%s\"\n" -msgstr "numeración de columnas no válida en la tabla «%s»\n" +msgid "finding default expressions of table \"%s.%s\"" +msgstr "buscando expresiones por omisión de la tabla «%s.%s»" -#: pg_dump.c:8014 +#: pg_dump.c:8447 #, c-format -msgid "finding default expressions of table \"%s.%s\"\n" -msgstr "buscando expresiones por omisión de la tabla «%s.%s»\n" +msgid "invalid adnum value %d for table \"%s\"" +msgstr "el valor de adnum %d para la tabla «%s» no es válido" -#: pg_dump.c:8037 +#: pg_dump.c:8512 #, c-format -msgid "invalid adnum value %d for table \"%s\"\n" -msgstr "el valor de adnum %d para la tabla «%s» no es válido\n" +msgid "finding check constraints for table \"%s.%s\"" +msgstr "buscando restricciones de revisión (check) para la tabla «%s.%s»" -#: pg_dump.c:8103 +#: pg_dump.c:8561 #, c-format -msgid "finding check constraints for table \"%s.%s\"\n" -msgstr "buscando restricciones de revisión (check) para la tabla «%s.%s»\n" +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d" +msgstr[1] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d" -#: pg_dump.c:8152 +#: pg_dump.c:8565 #, c-format -msgid "expected %d check constraint on table \"%s\" but found %d\n" -msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" -msgstr[0] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d\n" -msgstr[1] "se esperaban %d restricciones CHECK en la tabla «%s» pero se encontraron %d\n" +msgid "(The system catalogs might be corrupted.)" +msgstr "(Los catálogos del sistema podrían estar corruptos)" -#: pg_dump.c:8156 +#: pg_dump.c:10141 #, c-format -msgid "(The system catalogs might be corrupted.)\n" -msgstr "(Los catálogos del sistema podrían estar corruptos)\n" +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "el typtype del tipo «%s» parece no ser válido" -#: pg_dump.c:9714 +#: pg_dump.c:11495 #, c-format -msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" -msgstr "PRECAUCIÓN: el typtype del tipo «%s» parece no ser válido\n" +msgid "bogus value in proargmodes array" +msgstr "valor no válido en el arreglo proargmodes" -#: pg_dump.c:11143 +#: pg_dump.c:11867 #, c-format -msgid "WARNING: bogus value in proargmodes array\n" -msgstr "PRECAUCIÓN: valor no válido en el arreglo proargmodes\n" +msgid "could not parse proallargtypes array" +msgstr "no se pudo interpretar el arreglo proallargtypes" -#: pg_dump.c:11469 +#: pg_dump.c:11883 #, c-format -msgid "WARNING: could not parse proallargtypes array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo proallargtypes\n" +msgid "could not parse proargmodes array" +msgstr "no se pudo interpretar el arreglo proargmodes" -#: pg_dump.c:11485 +#: pg_dump.c:11897 #, c-format -msgid "WARNING: could not parse proargmodes array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo proargmodes\n" +msgid "could not parse proargnames array" +msgstr "no se pudo interpretar el arreglo proargnames" -#: pg_dump.c:11499 +#: pg_dump.c:11908 #, c-format -msgid "WARNING: could not parse proargnames array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo proargnames\n" +msgid "could not parse proconfig array" +msgstr "no se pudo interpretar el arreglo proconfig" -#: pg_dump.c:11510 +#: pg_dump.c:11988 #, c-format -msgid "WARNING: could not parse proconfig array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo proconfig\n" +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "el valor del atributo «provolatile» para la función «%s» es desconocido" -#: pg_dump.c:11581 +#: pg_dump.c:12038 pg_dump.c:14090 #, c-format -msgid "unrecognized provolatile value for function \"%s\"\n" -msgstr "el valor del atributo «provolatile» para la función «%s» es desconocido\n" +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "el valor del atributo «proparallel» para la función «%s» es desconocido" -#: pg_dump.c:11625 pg_dump.c:13623 +#: pg_dump.c:12171 pg_dump.c:12280 pg_dump.c:12287 #, c-format -msgid "unrecognized proparallel value for function \"%s\"\n" -msgstr "el valor del atributo «proparallel» para la función «%s» es desconocido\n" +msgid "could not find function definition for function with OID %u" +msgstr "no se encontró la definición de la función con OID %u" -#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 +#: pg_dump.c:12210 #, c-format -msgid "could not find function definition for function with OID %u\n" -msgstr "no se encontró la definición de la función con OID %u\n" +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "valor no válido en los campos pg_cast.castfunc o pg_cast.castmethod" -#: pg_dump.c:11778 +#: pg_dump.c:12213 #, c-format -msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" -msgstr "PRECAUCIÓN: valor no válido en los campos pg_cast.castfunc o pg_cast.castmethod\n" +msgid "bogus value in pg_cast.castmethod field" +msgstr "valor no válido en el campo pg_cast.castmethod" -#: pg_dump.c:11781 +#: pg_dump.c:12306 #, c-format -msgid "WARNING: bogus value in pg_cast.castmethod field\n" -msgstr "PRECAUCIÓN: valor no válido en el campo pg_cast.castmethod\n" +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "definición errónea de transformación; al menos uno de trffromsql and trftosql debe ser distinto de cero" -#: pg_dump.c:11871 +#: pg_dump.c:12323 #, c-format -msgid "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n" -msgstr "PRECAUCIÓN: definición errónea de transformación; al menos uno de trffromsql and trftosql debe ser distinto de cero\n" +msgid "bogus value in pg_transform.trffromsql field" +msgstr "valor erróneo en el campo pg_transform.trffromsql" -#: pg_dump.c:11888 +#: pg_dump.c:12344 #, c-format -msgid "WARNING: bogus value in pg_transform.trffromsql field\n" -msgstr "PRECAUCIÓN: valor erróneo en el campo pg_transform.trffromsql\n" +msgid "bogus value in pg_transform.trftosql field" +msgstr "valor erróneo en el campo pg_transform.trftosql" -#: pg_dump.c:11909 +#: pg_dump.c:12660 #, c-format -msgid "WARNING: bogus value in pg_transform.trftosql field\n" -msgstr "PRECAUCIÓN: valor erróneo en el campo pg_transform.trftosql\n" +msgid "could not find operator with OID %s" +msgstr "no se pudo encontrar el operador con OID %s" -#: pg_dump.c:12305 +#: pg_dump.c:12728 #, c-format -msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" -msgstr "PRECAUCIÓN: el tipo «%c» para el método de acceso «%s» no es válido\n" +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "el tipo «%c» para el método de acceso «%s» no es válido" -#: pg_dump.c:13086 +#: pg_dump.c:13482 #, c-format msgid "unrecognized collation provider: %s\n" msgstr "proveedor de ordenamiento (collation) no reconocido: %s\n" -#: pg_dump.c:13533 +#: pg_dump.c:13954 #, c-format -msgid "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n" -msgstr "" -"PRECAUCIÓN: la función de agregación «%s» no se pudo extraer correctamente\n" -"para esta versión de la base de datos; ignorada\n" +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "la función de agregación «%s» no se pudo extraer correctamente para esta versión de la base de datos; ignorada" + +#: pg_dump.c:14009 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "valor de aggfinalmodify no reconocido para la agregación «%s»" -#: pg_dump.c:14389 +#: pg_dump.c:14065 #, c-format -msgid "unrecognized object type in default privileges: %d\n" -msgstr "tipo de objeto desconocido en privilegios por omisión: %d\n" +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "valor de aggmfinalmodify no reconocido para la agregación «%s»" -#: pg_dump.c:14407 +#: pg_dump.c:14787 #, c-format -msgid "could not parse default ACL list (%s)\n" -msgstr "no se pudo interpretar la lista de ACL (%s)\n" +msgid "unrecognized object type in default privileges: %d" +msgstr "tipo de objeto desconocido en privilegios por omisión: %d" -#: pg_dump.c:14478 +#: pg_dump.c:14805 #, c-format -msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "no se pudo interpretar la lista inicial de GRANT ACL (%s) o la lista inicial de REVOKE ACL (%s) para el objeto «%s» (%s)\n" +msgid "could not parse default ACL list (%s)" +msgstr "no se pudo interpretar la lista de ACL (%s)" -#: pg_dump.c:14486 +#: pg_dump.c:14885 #, c-format -msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "no se pudo interpretar la lista de GRANT ACL (%s) o la lista de REVOKE ACL (%s) para el objeto «%s» (%s)\n" +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "no se pudo interpretar la lista inicial de GRANT ACL (%s) o la lista inicial de REVOKE ACL (%s) para el objeto «%s» (%s)" -#: pg_dump.c:14961 +#: pg_dump.c:14893 #, c-format -msgid "query to obtain definition of view \"%s\" returned no data\n" -msgstr "la consulta para obtener la definición de la vista «%s» no regresó datos\n" +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "no se pudo interpretar la lista de GRANT ACL (%s) o la lista de REVOKE ACL (%s) para el objeto «%s» (%s)" -#: pg_dump.c:14964 +#: pg_dump.c:15392 #, c-format -msgid "query to obtain definition of view \"%s\" returned more than one definition\n" -msgstr "la consulta para obtener la definición de la vista «%s» regresó más de una definición\n" +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "la consulta para obtener la definición de la vista «%s» no regresó datos" -#: pg_dump.c:14971 +#: pg_dump.c:15395 #, c-format -msgid "definition of view \"%s\" appears to be empty (length zero)\n" -msgstr "la definición de la vista «%s» parece estar vacía (tamaño cero)\n" +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "la consulta para obtener la definición de la vista «%s» regresó más de una definición" -#: pg_dump.c:15200 +#: pg_dump.c:15402 #, c-format -msgid "invalid number of parents %d for table \"%s\"\n" -msgstr "número de padres %d para la tabla «%s» no es válido\n" +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "la definición de la vista «%s» parece estar vacía (tamaño cero)" -#: pg_dump.c:15847 +#: pg_dump.c:15484 #, c-format -msgid "invalid column number %d for table \"%s\"\n" -msgstr "el número de columna %d no es válido para la tabla «%s»\n" +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS ya no está soportado (tabla «%s»)" -#: pg_dump.c:16031 +#: pg_dump.c:15611 #, c-format -msgid "missing index for constraint \"%s\"\n" -msgstr "falta un índice para restricción «%s»\n" +msgid "invalid number of parents %d for table \"%s\"" +msgstr "número de padres %d para la tabla «%s» no es válido" -#: pg_dump.c:16234 +#: pg_dump.c:16298 #, c-format -msgid "unrecognized constraint type: %c\n" -msgstr "tipo de restricción inesperado: %c\n" +msgid "invalid column number %d for table \"%s\"" +msgstr "el número de columna %d no es válido para la tabla «%s»" -#: pg_dump.c:16371 pg_dump.c:16597 +#: pg_dump.c:16560 #, c-format -msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" -msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)\n" -msgstr[0] "la consulta para obtener los datos de la secuencia «%s» regresó %d entrada, pero se esperaba 1\n" -msgstr[1] "la consulta para obtener los datos de la secuencia «%s» regresó %d entradas, pero se esperaba 1\n" +msgid "missing index for constraint \"%s\"" +msgstr "falta un índice para restricción «%s»" -#: pg_dump.c:16695 +#: pg_dump.c:16780 #, c-format -msgid "unexpected tgtype value: %d\n" -msgstr "tgtype no esperado: %d\n" +msgid "unrecognized constraint type: %c" +msgstr "tipo de restricción inesperado: %c" -#: pg_dump.c:16769 +#: pg_dump.c:16912 pg_dump.c:17132 #, c-format -msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" -msgstr "argumento de cadena (%s) no válido para el disparador (trigger) «%s» en la tabla «%s»\n" +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "la consulta para obtener los datos de la secuencia «%s» regresó %d entrada, pero se esperaba 1" +msgstr[1] "la consulta para obtener los datos de la secuencia «%s» regresó %d entradas, pero se esperaba 1" -#: pg_dump.c:16990 +#: pg_dump.c:16946 #, c-format -msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n" -msgstr "la consulta para obtener la regla «%s» asociada con la tabla «%s» falló: retornó un número incorrecto de renglones\n" +msgid "unrecognized sequence type: %s" +msgstr "tipo no reconocido de secuencia: %s" -#: pg_dump.c:17385 +#: pg_dump.c:17228 #, c-format -msgid "reading dependency data\n" -msgstr "obteniendo datos de dependencias\n" +msgid "unexpected tgtype value: %d" +msgstr "tgtype no esperado: %d" -#: pg_dump.c:17850 +#: pg_dump.c:17302 #, c-format -msgid "WARNING: could not parse reloptions array\n" -msgstr "PRECAUCIÓN: no se pudo interpretar el arreglo reloptions\n" +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "argumento de cadena (%s) no válido para el disparador (trigger) «%s» en la tabla «%s»" -#. translator: this is a module name -#: pg_dump_sort.c:25 -msgid "sorter" -msgstr "sorter" +#: pg_dump.c:17531 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "la consulta para obtener la regla «%s» asociada con la tabla «%s» falló: retornó un número incorrecto de renglones" + +#: pg_dump.c:17693 +#, c-format +msgid "could not find referenced extension %u" +msgstr "no se pudo encontrar la extensión referenciada %u" + +#: pg_dump.c:17905 +#, c-format +msgid "reading dependency data" +msgstr "obteniendo datos de dependencias" -#: pg_dump_sort.c:413 +#: pg_dump.c:17960 #, c-format -msgid "invalid dumpId %d\n" -msgstr "dumpId %d no válido\n" +msgid "no referencing object %u %u" +msgstr "no existe el objeto referenciante %u %u" -#: pg_dump_sort.c:419 +#: pg_dump.c:17971 #, c-format -msgid "invalid dependency %d\n" -msgstr "dependencia %d no válida\n" +msgid "no referenced object %u %u" +msgstr "no existe el objeto referenciado %u %u" -#: pg_dump_sort.c:652 +#: pg_dump.c:18339 #, c-format -msgid "could not identify dependency loop\n" -msgstr "no se pudo identificar bucle de dependencia\n" +msgid "could not parse reloptions array" +msgstr "no se pudo interpretar el arreglo reloptions" -#: pg_dump_sort.c:1175 +#: pg_dump_sort.c:327 #, c-format -msgid "NOTICE: there are circular foreign-key constraints on this table:\n" -msgid_plural "NOTICE: there are circular foreign-key constraints among these tables:\n" -msgstr[0] "NOTA: hay restricciones de llave foránea circulares en la siguiente tabla:\n" -msgstr[1] "NOTA: hay restricciones de llave foránea circulares entre las siguientes tablas:\n" +msgid "invalid dumpId %d" +msgstr "dumpId %d no válido" -#: pg_dump_sort.c:1179 pg_dump_sort.c:1199 +#: pg_dump_sort.c:333 #, c-format -msgid " %s\n" -msgstr " %s\n" +msgid "invalid dependency %d" +msgstr "dependencia %d no válida" -#: pg_dump_sort.c:1180 +#: pg_dump_sort.c:566 #, c-format -msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.\n" -msgstr "Puede no ser capaz de restaurar el respaldo sin usar --disable-triggers o temporalmente eliminar las restricciones.\n" +msgid "could not identify dependency loop" +msgstr "no se pudo identificar bucle de dependencia" -#: pg_dump_sort.c:1181 +#: pg_dump_sort.c:1129 #, c-format -msgid "Consider using a full dump instead of a --data-only dump to avoid this problem.\n" -msgstr "Considere usar un volcado completo en lugar de --data-only para evitar este problema.\n" +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "hay restricciones de llave foránea circulares en la siguiente tabla:" +msgstr[1] "hay restricciones de llave foránea circulares entre las siguientes tablas:" -#: pg_dump_sort.c:1193 +#: pg_dump_sort.c:1133 pg_dump_sort.c:1153 #, c-format -msgid "WARNING: could not resolve dependency loop among these items:\n" -msgstr "PRECAUCIÓN: no se pudo resolver el bucle de dependencias entre los siguientes elementos:\n" +msgid " %s" +msgstr " %s" -#: pg_dumpall.c:189 +#: pg_dump_sort.c:1134 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Puede no ser capaz de restaurar el respaldo sin usar --disable-triggers o temporalmente eliminar las restricciones." + +#: pg_dump_sort.c:1135 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Considere usar un volcado completo en lugar de --data-only para evitar este problema." + +#: pg_dump_sort.c:1147 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "no se pudo resolver el bucle de dependencias entre los siguientes elementos:" + +#: pg_dumpall.c:199 #, c-format msgid "" "The program \"pg_dump\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "%s necesita el programa «pg_dump», pero no fue encontrado en el mismo\n" "directorio que «%s».\n" -"Verifique su instalación.\n" +"Verifique su instalación." -#: pg_dumpall.c:196 +#: pg_dumpall.c:204 #, c-format msgid "" "The program \"pg_dump\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "«pg_dump» fue encontrado por «%s»,\n" "pero no es de la misma versión que %s.\n" -"Verifique su instalación.\n" +"Verifique su instalación." -#: pg_dumpall.c:331 +#: pg_dumpall.c:351 #, c-format -msgid "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" -msgstr "%s: las opciones -g/--globals-only y -r/--roles-only no pueden usarse juntas\n" +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only" +msgstr "la opción --exclude-database no puede ser usada junto con -g/--globals-only, -r/--roles-only o -t/--tablespaces-only" -#: pg_dumpall.c:340 +#: pg_dumpall.c:360 #, c-format -msgid "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: las opciones -g/--globals-only y -t/--tablespaces-only no pueden usarse juntas\n" +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "las opciones -g/--globals-only y -r/--roles-only no pueden usarse juntas" -#: pg_dumpall.c:349 pg_restore.c:367 +#: pg_dumpall.c:368 #, c-format -msgid "%s: option --if-exists requires option -c/--clean\n" -msgstr "%s: la opción --if-exists requiere la opción -c/--clean\n" +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "las opciones -g/--globals-only y -t/--tablespaces-only no pueden usarse juntas" -#: pg_dumpall.c:356 +#: pg_dumpall.c:382 #, c-format -msgid "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: las opciones -r/--roles-only y -t/--tablespaces-only no pueden usarse juntas\n" +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "las opciones -r/--roles-only y -t/--tablespaces-only no pueden usarse juntas" -#: pg_dumpall.c:412 pg_dumpall.c:1983 +#: pg_dumpall.c:443 pg_dumpall.c:1747 #, c-format -msgid "%s: could not connect to database \"%s\"\n" -msgstr "%s: no se pudo establecer la conexión a la base de datos «%s»\n" +msgid "could not connect to database \"%s\"" +msgstr "no se pudo establecer la conexión a la base de datos «%s»" -#: pg_dumpall.c:427 +#: pg_dumpall.c:457 #, c-format msgid "" -"%s: could not connect to databases \"postgres\" or \"template1\"\n" -"Please specify an alternative database.\n" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." msgstr "" -"%s: no se pudo establecer la conexión a las bases de datos «postgres» o\n" -"«template1». Por favor especifique una base de datos para conectarse.\n" +"no se pudo establecer la conexión a las bases de datos «postgres» o\n" +"«template1». Por favor especifique una base de datos para conectarse." -#: pg_dumpall.c:444 +#: pg_dumpall.c:479 #, c-format -msgid "%s: could not open the output file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo de salida «%s»: %s\n" +msgid "could not open the output file \"%s\": %m" +msgstr "no se pudo abrir el archivo de salida «%s»: %m" -#: pg_dumpall.c:574 +#: pg_dumpall.c:611 #, c-format msgid "" "%s extracts a PostgreSQL database cluster into an SQL script file.\n" @@ -2347,68 +2280,73 @@ msgstr "" "guión (script) SQL.\n" "\n" -#: pg_dumpall.c:576 +#: pg_dumpall.c:613 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPCIÓN]...\n" -#: pg_dumpall.c:579 +#: pg_dumpall.c:616 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=ARCHIVO nombre del archivo de salida\n" -#: pg_dumpall.c:586 +#: pg_dumpall.c:623 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean tira (drop) la base de datos antes de crearla\n" -#: pg_dumpall.c:587 +#: pg_dumpall.c:625 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr " -g, --globals-only extrae sólo los objetos globales, no bases de datos\n" -#: pg_dumpall.c:589 pg_restore.c:472 +#: pg_dumpall.c:626 pg_restore.c:489 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner no reestablece los dueños de los objetos\n" -#: pg_dumpall.c:590 +#: pg_dumpall.c:627 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr "" " -r, --roles-only extrae sólo los roles, no bases de datos\n" " ni tablespaces\n" -#: pg_dumpall.c:592 +#: pg_dumpall.c:629 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr "" " -S, --superuser=NAME especifica el nombre del superusuario a usar en\n" " el volcado\n" -#: pg_dumpall.c:593 +#: pg_dumpall.c:630 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr "" " -t, --tablespaces-only extrae sólo los tablespaces, no bases de datos\n" " ni roles\n" -#: pg_dumpall.c:602 +#: pg_dumpall.c:636 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=PATRÓN excluir bases de datos cuyos nombres coinciden con el patrón\n" + +#: pg_dumpall.c:643 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords no extraer contraseñas para roles\n" -#: pg_dumpall.c:614 +#: pg_dumpall.c:656 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=CONNSTR conectar usando la cadena de conexión\n" -#: pg_dumpall.c:616 +#: pg_dumpall.c:658 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=NOMBRE especifica la base de datos a la cual conectarse\n" -#: pg_dumpall.c:623 +#: pg_dumpall.c:665 #, c-format msgid "" "\n" @@ -2420,112 +2358,97 @@ msgstr "" "Si no se usa -f/--file, el volcado de SQL será escrito a la salida estándar.\n" "\n" -#: pg_dumpall.c:828 -#, c-format -msgid "%s: role name starting with \"pg_\" skipped (%s)\n" -msgstr "%s: omitido nombre de rol que empieza con «pg_» (%s)\n" - -#: pg_dumpall.c:1208 +#: pg_dumpall.c:870 #, c-format -msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" -msgstr "%s: no se pudo interpretar la lista de control de acceso (%s) del tablespace «%s»\n" +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "omitido nombre de rol que empieza con «pg_» (%s)" -#: pg_dumpall.c:1525 +#: pg_dumpall.c:1271 #, c-format -msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" -msgstr "%s: no se pudo interpretar la lista de control de acceso (%s) de la base de datos «%s»\n" +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "no se pudo interpretar la lista de control de acceso (%s) del tablespace «%s»" -#: pg_dumpall.c:1739 +#: pg_dumpall.c:1488 #, c-format -msgid "%s: dumping database \"%s\"...\n" -msgstr "%s: extrayendo base de datos «%s»...\n" +msgid "excluding database \"%s\"..." +msgstr "excluyendo base de datos «%s»..." -#: pg_dumpall.c:1763 +#: pg_dumpall.c:1492 #, c-format -msgid "%s: pg_dump failed on database \"%s\", exiting\n" -msgstr "%s: pg_dump falló en la base de datos «%s», saliendo\n" +msgid "dumping database \"%s\"..." +msgstr "extrayendo base de datos «%s»..." -#: pg_dumpall.c:1772 +#: pg_dumpall.c:1524 #, c-format -msgid "%s: could not re-open the output file \"%s\": %s\n" -msgstr "%s: no se pudo reabrir el archivo de salida «%s»: %s\n" +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump falló en la base de datos «%s», saliendo" -#: pg_dumpall.c:1817 +#: pg_dumpall.c:1533 #, c-format -msgid "%s: running \"%s\"\n" -msgstr "%s: ejecutando «%s»\n" +msgid "could not re-open the output file \"%s\": %m" +msgstr "no se pudo reabrir el archivo de salida «%s»: %m" -#: pg_dumpall.c:2006 +#: pg_dumpall.c:1577 #, c-format -msgid "%s: could not connect to database \"%s\": %s\n" -msgstr "%s: no se pudo establecer la conexión a la base de datos «%s»: %s\n" +msgid "running \"%s\"" +msgstr "ejecutando «%s»" -#: pg_dumpall.c:2036 +#: pg_dumpall.c:1768 #, c-format -msgid "%s: could not get server version\n" -msgstr "%s: no se pudo obtener la versión del servidor\n" +msgid "could not connect to database \"%s\": %s" +msgstr "no se pudo conectar a la base de datos «%s»: %s" -#: pg_dumpall.c:2042 +#: pg_dumpall.c:1798 #, c-format -msgid "%s: could not parse server version \"%s\"\n" -msgstr "%s: no se pudo interpretar la versión del servidor «%s»\n" +msgid "could not get server version" +msgstr "no se pudo obtener la versión del servidor" -#: pg_dumpall.c:2118 pg_dumpall.c:2144 +#: pg_dumpall.c:1804 #, c-format -msgid "%s: executing %s\n" -msgstr "%s: ejecutando %s\n" +msgid "could not parse server version \"%s\"" +msgstr "no se pudo interpretar la versión del servidor «%s»" -#: pg_dumpall.c:2124 pg_dumpall.c:2150 +#: pg_dumpall.c:1876 pg_dumpall.c:1899 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: falló la consulta: %s" +msgid "executing %s" +msgstr "ejecutando %s" -#: pg_dumpall.c:2126 pg_dumpall.c:2152 +#: pg_restore.c:312 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: la consulta era: %s\n" +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "una de las opciones -d/--dbname y -f/--file debe especificarse" -#: pg_restore.c:309 +#: pg_restore.c:321 #, c-format -msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" -msgstr "%s: las opciones -d/--dbname y -f/--file no pueden usarse juntas\n" +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "las opciones -d/--dbname y -f/--file no pueden usarse juntas" -#: pg_restore.c:320 +#: pg_restore.c:347 #, c-format -msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "%s: las opciones -s/--schema-only y -a/--data-only no pueden usarse juntas\n" +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "las opciones -c/--clean y -1/--single-transaction no pueden usarse juntas" -#: pg_restore.c:327 +#: pg_restore.c:361 #, c-format -msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "%s: las opciones -c/--clean y -a/--data-only no pueden usarse juntas\n" +msgid "maximum number of parallel jobs is %d" +msgstr "el número máximo de trabajos en paralelo es %d" -#: pg_restore.c:334 +#: pg_restore.c:370 #, c-format -msgid "%s: invalid number of parallel jobs\n" -msgstr "%s: número de trabajos paralelos no válido\n" +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "no se puede especificar --single-transaction junto con múltiples tareas" -#: pg_restore.c:342 +#: pg_restore.c:412 #, c-format -msgid "%s: maximum number of parallel jobs is %d\n" -msgstr "%s: el número máximo de trabajos en paralelo es %d\n" +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "formato de archivo «%s» no reconocido; por favor especifique «c», «d» o «t»" -#: pg_restore.c:351 +#: pg_restore.c:452 #, c-format -msgid "%s: cannot specify both --single-transaction and multiple jobs\n" -msgstr "%s: no se puede especificar --single-transaction junto con múltiples tareas\n" +msgid "errors ignored on restore: %d" +msgstr "errores ignorados durante la recuperación: %d" -#: pg_restore.c:394 -#, c-format -msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" -msgstr "formato de archivo «%s» no reconocido; por favor especifique «c», «d» o «t»\n" - -#: pg_restore.c:434 -#, c-format -msgid "WARNING: errors ignored on restore: %d\n" -msgstr "PRECAUCIÓN: errores ignorados durante la recuperación: %d\n" - -#: pg_restore.c:448 +#: pg_restore.c:465 #, c-format msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" @@ -2535,49 +2458,49 @@ msgstr "" "creado por pg_dump.\n" "\n" -#: pg_restore.c:450 +#: pg_restore.c:467 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [OPCIÓN]... [ARCHIVO]\n" -#: pg_restore.c:453 +#: pg_restore.c:470 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NOMBRE nombre de la base de datos a la que conectarse\n" -#: pg_restore.c:454 +#: pg_restore.c:471 #, c-format -msgid " -f, --file=FILENAME output file name\n" -msgstr " -f, --file=ARCHIVO nombre del archivo de salida\n" +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=ARCHIVO nombre del archivo de salida (- para stdout)\n" -#: pg_restore.c:455 +#: pg_restore.c:472 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t formato del volcado (debería ser automático)\n" -#: pg_restore.c:456 +#: pg_restore.c:473 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr "" " -l, --list imprime una tabla resumida de contenidos\n" " del archivador\n" -#: pg_restore.c:457 +#: pg_restore.c:474 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose modo verboso\n" -#: pg_restore.c:458 +#: pg_restore.c:475 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: pg_restore.c:459 +#: pg_restore.c:476 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: pg_restore.c:461 +#: pg_restore.c:478 #, c-format msgid "" "\n" @@ -2586,34 +2509,34 @@ msgstr "" "\n" "Opciones que controlan la recuperación:\n" -#: pg_restore.c:462 +#: pg_restore.c:479 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only reestablece sólo los datos, no el esquema\n" -#: pg_restore.c:464 +#: pg_restore.c:481 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create crea la base de datos de destino\n" -#: pg_restore.c:465 +#: pg_restore.c:482 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr "" " -e, --exit-on-error abandonar al encontrar un error\n" " por omisión, se continúa la restauración\n" -#: pg_restore.c:466 +#: pg_restore.c:483 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NOMBRE reestablece el índice nombrado\n" -#: pg_restore.c:467 +#: pg_restore.c:484 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr " -j, --jobs=NUM máximo de procesos paralelos para restaurar\n" -#: pg_restore.c:468 +#: pg_restore.c:485 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -2622,59 +2545,64 @@ msgstr "" " -L, --use-list=ARCHIVO usa la tabla de contenido especificada para ordenar\n" " la salida de este archivo\n" -#: pg_restore.c:470 +#: pg_restore.c:487 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME reestablece sólo los objetos en este esquema\n" -#: pg_restore.c:471 +#: pg_restore.c:488 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, --exclude-schema=NAME no reestablecer los objetos en este esquema\n" -#: pg_restore.c:473 +#: pg_restore.c:490 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NOMBRE(args) reestablece la función nombrada\n" -#: pg_restore.c:474 +#: pg_restore.c:491 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only reestablece el esquema únicamente, no los datos\n" -#: pg_restore.c:475 +#: pg_restore.c:492 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr "" " -S, --superuser=NOMBRE especifica el nombre del superusuario que se usa\n" " para deshabilitar los disparadores (triggers)\n" -#: pg_restore.c:476 +#: pg_restore.c:493 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr " -t, --table=NOMBRE reestablece la relación (tabla, vista, etc.) nombrada\n" -#: pg_restore.c:477 +#: pg_restore.c:494 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NOMBRE reestablece el disparador (trigger) nombrado\n" -#: pg_restore.c:478 +#: pg_restore.c:495 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges no reestablece los privilegios (grant/revoke)\n" -#: pg_restore.c:479 +#: pg_restore.c:496 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction reestablece en una única transacción\n" -#: pg_restore.c:481 +#: pg_restore.c:498 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security activa seguridad de filas\n" -#: pg_restore.c:483 +#: pg_restore.c:500 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments no restaurar comentarios\n" + +#: pg_restore.c:501 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" @@ -2683,50 +2611,50 @@ msgstr "" " --no-data-for-failed-tables no reestablece datos de tablas que no pudieron\n" " ser creadas\n" -#: pg_restore.c:485 +#: pg_restore.c:503 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications no restaurar publicaciones\n" -#: pg_restore.c:486 +#: pg_restore.c:504 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels no restaura etiquetas de seguridad\n" -#: pg_restore.c:487 +#: pg_restore.c:505 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions no restaurar suscripciones\n" -#: pg_restore.c:488 +#: pg_restore.c:506 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces no vuelca asignaciones de tablespace\n" -#: pg_restore.c:489 +#: pg_restore.c:507 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr "" " --section=SECCIÓN reestablece la sección nombrada (pre-data, data\n" " post-data)\n" -#: pg_restore.c:502 +#: pg_restore.c:520 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLENAME hace SET ROLE antes de restaurar\n" -#: pg_restore.c:504 +#: pg_restore.c:522 #, c-format msgid "" "\n" -"The options -I, -n, -P, -t, -T, and --section can be combined and specified\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" "multiple times to select multiple objects.\n" msgstr "" "\n" -"Las opciones -I, -n, -P, -t, -T, y --section pueden ser combinadas y especificadas\n" +"Las opciones -I, -n, -N, -P, -t, -T, y --section pueden ser combinadas y especificadas\n" "varias veces para seleccionar varios objetos.\n" -#: pg_restore.c:507 +#: pg_restore.c:525 #, c-format msgid "" "\n" @@ -2736,41 +2664,3 @@ msgstr "" "\n" "Si no se especifica un archivo de entrada, se usa la entrada estándar.\n" "\n" - -#~ msgid "worker is terminating\n" -#~ msgstr "el proceso hijo está terminando\n" - -#~ msgid "could not get relation name for OID %u: %s\n" -#~ msgstr "no se pudo obtener un nombre de relación para el OID %u: %s\n" - -#~ msgid "unrecognized command on communication channel: %s\n" -#~ msgstr "orden no reconocida en canal de comunicación: %s\n" - -#~ msgid "error processing a parallel work item\n" -#~ msgstr "error procesando un elemento de trabajo en paralelo\n" - -#~ msgid "terminated by user\n" -#~ msgstr "terminado por el usuario\n" - -#~ msgid "error in ListenToWorkers(): %s\n" -#~ msgstr "error en ListenToWorkers(): %s\n" - -#~ msgid "could not find slot of finished worker\n" -#~ msgstr "no se pudo localizar la entrada del proceso o hilo que terminó\n" - -#~ msgid "error during backup\n" -#~ msgstr "error durante el volcado\n" - -#~ msgid "server version must be at least 7.3 to use schema selection switches\n" -#~ msgstr "" -#~ "la versión del servidor debe ser al menos 7.3 para usar los parámetros de\n" -#~ "selección de esquema\n" - -#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" -#~ msgstr "la consulta para obtener los datos de la secuencia «%s» regresó el nombre «%s»\n" - -#~ msgid "could not open output file \"%s\" for writing\n" -#~ msgstr "no se pudo abrir el archivo de salida «%s» para escritura\n" - -#~ msgid "archive member too large for tar format\n" -#~ msgstr "el miembro de archivador es demasiado grande para el formato tar\n" diff --git a/src/bin/pg_dump/po/fr.po b/src/bin/pg_dump/po/fr.po index 7bc28d0494e..ac91b3101f0 100644 --- a/src/bin/pg_dump/po/fr.po +++ b/src/bin/pg_dump/po/fr.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-24 15:46+0000\n" -"PO-Revision-Date: 2017-07-24 21:28+0200\n" +"POT-Creation-Date: 2018-02-23 04:15+0000\n" +"PO-Revision-Date: 2018-02-23 16:41+0100\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.0.3\n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -353,14 +353,14 @@ msgstr "n'a pas pu décompresser les données : %s\n" msgid "could not close compression library: %s\n" msgstr "n'a pas pu fermer la bibliothèque de compression : %s\n" -#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:587 -#: pg_backup_tar.c:559 +#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 +#: pg_backup_tar.c:564 pg_backup_tar.c:568 #, c-format msgid "could not read from input file: %s\n" msgstr "n'a pas pu lire à partir du fichier en entrée : %s\n" -#: compress_io.c:635 pg_backup_custom.c:584 pg_backup_directory.c:543 -#: pg_backup_tar.c:795 pg_backup_tar.c:819 +#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 +#: pg_backup_tar.c:807 pg_backup_tar.c:831 #, c-format msgid "could not read from input file: end of file\n" msgstr "n'a pas pu lire à partir du fichier en entrée : fin du fichier\n" @@ -462,36 +462,36 @@ msgstr "pgpipe: n'a pas pu accepter de connexion: code d'erreur %d\n" msgid "archiver" msgstr "archiveur" -#: pg_backup_archiver.c:243 pg_backup_archiver.c:1573 +#: pg_backup_archiver.c:249 pg_backup_archiver.c:1599 #, c-format msgid "could not close output file: %s\n" msgstr "n'a pas pu fermer le fichier de sortie : %s\n" -#: pg_backup_archiver.c:289 pg_backup_archiver.c:294 +#: pg_backup_archiver.c:295 pg_backup_archiver.c:300 #, c-format msgid "WARNING: archive items not in correct section order\n" msgstr "" "ATTENTION : les éléments de l'archive ne sont pas dans l'ordre correct de " "la section\n" -#: pg_backup_archiver.c:300 +#: pg_backup_archiver.c:306 #, c-format msgid "unexpected section code %d\n" msgstr "code de section inattendu %d\n" -#: pg_backup_archiver.c:336 +#: pg_backup_archiver.c:342 #, c-format msgid "-C and -1 are incompatible options\n" msgstr "-C et -1 sont des options incompatibles\n" -#: pg_backup_archiver.c:346 +#: pg_backup_archiver.c:352 #, c-format msgid "parallel restore is not supported with this archive file format\n" msgstr "" "la restauration parallèle n'est pas supportée avec ce format de fichier\n" "d'archive\n" -#: pg_backup_archiver.c:350 +#: pg_backup_archiver.c:356 #, c-format msgid "" "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" @@ -499,7 +499,7 @@ msgstr "" "la restauration parallèle n'est pas supportée avec les archives réalisées\n" "par un pg_dump antérieur à la 8.0 d'archive\n" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:374 #, c-format msgid "" "cannot restore from compressed archive (compression not supported in this " @@ -508,29 +508,29 @@ msgstr "" "ne peut pas restaurer à partir de l'archive compressée (compression non\n" "disponible dans cette installation)\n" -#: pg_backup_archiver.c:385 +#: pg_backup_archiver.c:391 #, c-format msgid "connecting to database for restore\n" msgstr "connexion à la base de données pour la restauration\n" -#: pg_backup_archiver.c:387 +#: pg_backup_archiver.c:393 #, c-format msgid "direct database connections are not supported in pre-1.3 archives\n" msgstr "" "les connexions directes à la base de données ne sont pas supportées dans\n" "les archives pre-1.3\n" -#: pg_backup_archiver.c:432 +#: pg_backup_archiver.c:438 #, c-format msgid "implied data-only restore\n" msgstr "a impliqué une restauration des données uniquement\n" -#: pg_backup_archiver.c:502 +#: pg_backup_archiver.c:508 #, c-format msgid "dropping %s %s\n" msgstr "suppression de %s %s\n" -#: pg_backup_archiver.c:595 +#: pg_backup_archiver.c:601 #, c-format msgid "" "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" @@ -538,62 +538,52 @@ msgstr "" "ATTENTION : n'a pas pu trouver où insérer IF EXISTS dans l'instruction « %s " "»\n" -#: pg_backup_archiver.c:671 -#, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "réglage du propriétaire et des droits pour %s « %s.%s»\n" - -#: pg_backup_archiver.c:674 -#, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "réglage du propriétaire et des droits pour %s « %s »\n" - -#: pg_backup_archiver.c:740 pg_backup_archiver.c:742 +#: pg_backup_archiver.c:764 pg_backup_archiver.c:766 #, c-format msgid "warning from original dump file: %s\n" msgstr "message d'avertissement du fichier de sauvegarde original : %s\n" -#: pg_backup_archiver.c:751 +#: pg_backup_archiver.c:778 #, c-format msgid "creating %s \"%s.%s\"\n" msgstr "création de %s « %s.%s »\n" -#: pg_backup_archiver.c:754 +#: pg_backup_archiver.c:781 #, c-format msgid "creating %s \"%s\"\n" msgstr "création de %s « %s »\n" -#: pg_backup_archiver.c:806 +#: pg_backup_archiver.c:832 #, c-format msgid "connecting to new database \"%s\"\n" msgstr "connexion à la nouvelle base de données « %s »\n" -#: pg_backup_archiver.c:834 +#: pg_backup_archiver.c:860 #, c-format msgid "processing %s\n" msgstr "traitement de %s\n" -#: pg_backup_archiver.c:854 +#: pg_backup_archiver.c:880 #, c-format msgid "processing data for table \"%s.%s\"\n" msgstr "traitement des données de la table « %s.%s »\n" -#: pg_backup_archiver.c:916 +#: pg_backup_archiver.c:942 #, c-format msgid "executing %s %s\n" msgstr "exécution de %s %s\n" -#: pg_backup_archiver.c:955 +#: pg_backup_archiver.c:981 #, c-format msgid "disabling triggers for %s\n" msgstr "désactivation des déclencheurs pour %s\n" -#: pg_backup_archiver.c:983 +#: pg_backup_archiver.c:1009 #, c-format msgid "enabling triggers for %s\n" msgstr "activation des triggers pour %s\n" -#: pg_backup_archiver.c:1013 +#: pg_backup_archiver.c:1039 #, c-format msgid "" "internal error -- WriteData cannot be called outside the context of a " @@ -602,69 +592,69 @@ msgstr "" "erreur interne -- WriteData ne peut pas être appelé en dehors du contexte\n" "de la routine DataDumper\n" -#: pg_backup_archiver.c:1211 +#: pg_backup_archiver.c:1237 #, c-format msgid "large-object output not supported in chosen format\n" msgstr "" "la sauvegarde des « Large Objects » n'est pas supportée dans le format " "choisi\n" -#: pg_backup_archiver.c:1269 +#: pg_backup_archiver.c:1295 #, c-format msgid "restored %d large object\n" msgid_plural "restored %d large objects\n" msgstr[0] "restauration de %d « Large Object »\n" msgstr[1] "restauration de %d « Large Objects »\n" -#: pg_backup_archiver.c:1290 pg_backup_tar.c:737 +#: pg_backup_archiver.c:1316 pg_backup_tar.c:749 #, c-format msgid "restoring large object with OID %u\n" msgstr "restauration du « Large Object » d'OID %u\n" -#: pg_backup_archiver.c:1302 +#: pg_backup_archiver.c:1328 #, c-format msgid "could not create large object %u: %s" msgstr "n'a pas pu créer le « Large Object » %u : %s" -#: pg_backup_archiver.c:1307 pg_dump.c:3084 +#: pg_backup_archiver.c:1333 pg_dump.c:3092 #, c-format msgid "could not open large object %u: %s" msgstr "n'a pas pu ouvrir le « Large Object » %u : %s" -#: pg_backup_archiver.c:1365 +#: pg_backup_archiver.c:1391 #, c-format msgid "could not open TOC file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier TOC « %s » : %s\n" -#: pg_backup_archiver.c:1406 +#: pg_backup_archiver.c:1432 #, c-format msgid "WARNING: line ignored: %s\n" msgstr "ATTENTION : ligne ignorée : %s\n" -#: pg_backup_archiver.c:1413 +#: pg_backup_archiver.c:1439 #, c-format msgid "could not find entry for ID %d\n" msgstr "n'a pas pu trouver l'entrée pour l'ID %d\n" -#: pg_backup_archiver.c:1434 pg_backup_directory.c:225 -#: pg_backup_directory.c:592 +#: pg_backup_archiver.c:1460 pg_backup_directory.c:225 +#: pg_backup_directory.c:596 #, c-format msgid "could not close TOC file: %s\n" msgstr "n'a pas pu fermer le fichier TOC : %s\n" -#: pg_backup_archiver.c:1543 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:578 pg_backup_directory.c:643 -#: pg_backup_directory.c:663 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:158 pg_backup_directory.c:336 +#: pg_backup_directory.c:582 pg_backup_directory.c:647 +#: pg_backup_directory.c:667 #, c-format msgid "could not open output file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier de sauvegarde « %s » : %s\n" -#: pg_backup_archiver.c:1546 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1572 pg_backup_custom.c:165 #, c-format msgid "could not open output file: %s\n" msgstr "n'a pas pu ouvrir le fichier de sauvegarde : %s\n" -#: pg_backup_archiver.c:1652 +#: pg_backup_archiver.c:1678 #, c-format msgid "wrote %lu byte of large object data (result = %lu)\n" msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" @@ -673,63 +663,63 @@ msgstr[0] "" msgstr[1] "" "a écrit %lu octets de données d'un « Large Object » (résultat = %lu)\n" -#: pg_backup_archiver.c:1658 +#: pg_backup_archiver.c:1684 #, c-format msgid "could not write to large object (result: %lu, expected: %lu)\n" msgstr "" "n'a pas pu écrire le « Large Object » (résultat : %lu, attendu : %lu)\n" -#: pg_backup_archiver.c:1751 +#: pg_backup_archiver.c:1777 #, c-format msgid "Error while INITIALIZING:\n" msgstr "Erreur pendant l'initialisation (« INITIALIZING ») :\n" -#: pg_backup_archiver.c:1756 +#: pg_backup_archiver.c:1782 #, c-format msgid "Error while PROCESSING TOC:\n" msgstr "Erreur pendant le traitement de la TOC (« PROCESSING TOC ») :\n" -#: pg_backup_archiver.c:1761 +#: pg_backup_archiver.c:1787 #, c-format msgid "Error while FINALIZING:\n" msgstr "Erreur pendant la finalisation (« FINALIZING ») :\n" -#: pg_backup_archiver.c:1766 +#: pg_backup_archiver.c:1792 #, c-format msgid "Error from TOC entry %d; %u %u %s %s %s\n" msgstr "Erreur à partir de l'entrée TOC %d ; %u %u %s %s %s\n" -#: pg_backup_archiver.c:1839 +#: pg_backup_archiver.c:1865 #, c-format msgid "bad dumpId\n" msgstr "mauvais dumpId\n" -#: pg_backup_archiver.c:1860 +#: pg_backup_archiver.c:1886 #, c-format msgid "bad table dumpId for TABLE DATA item\n" msgstr "mauvais dumpId de table pour l'élément TABLE DATA\n" -#: pg_backup_archiver.c:1952 +#: pg_backup_archiver.c:1978 #, c-format msgid "unexpected data offset flag %d\n" msgstr "drapeau de décalage de données inattendu %d\n" -#: pg_backup_archiver.c:1965 +#: pg_backup_archiver.c:1991 #, c-format msgid "file offset in dump file is too large\n" msgstr "le décalage dans le fichier de sauvegarde est trop important\n" -#: pg_backup_archiver.c:2078 +#: pg_backup_archiver.c:2104 #, c-format msgid "attempting to ascertain archive format\n" msgstr "tentative d'identification du format de l'archive\n" -#: pg_backup_archiver.c:2104 pg_backup_archiver.c:2114 +#: pg_backup_archiver.c:2130 pg_backup_archiver.c:2140 #, c-format msgid "directory name too long: \"%s\"\n" msgstr "nom du répertoire trop long : « %s »\n" -#: pg_backup_archiver.c:2122 +#: pg_backup_archiver.c:2148 #, c-format msgid "" "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does " @@ -738,164 +728,164 @@ msgstr "" "le répertoire « %s » ne semble pas être une archive valide (« toc.dat » " "n'existe pas)\n" -#: pg_backup_archiver.c:2130 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:394 +#: pg_backup_archiver.c:2156 pg_backup_custom.c:177 pg_backup_custom.c:770 +#: pg_backup_directory.c:209 pg_backup_directory.c:396 #, c-format msgid "could not open input file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier en entrée « %s » : %s\n" -#: pg_backup_archiver.c:2138 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2164 pg_backup_custom.c:184 #, c-format msgid "could not open input file: %s\n" msgstr "n'a pas pu ouvrir le fichier en entrée : %s\n" -#: pg_backup_archiver.c:2145 +#: pg_backup_archiver.c:2171 #, c-format msgid "could not read input file: %s\n" msgstr "n'a pas pu lire le fichier en entrée : %s\n" -#: pg_backup_archiver.c:2147 +#: pg_backup_archiver.c:2173 #, c-format msgid "input file is too short (read %lu, expected 5)\n" msgstr "le fichier en entrée est trop petit (%lu lus, 5 attendus)\n" -#: pg_backup_archiver.c:2232 +#: pg_backup_archiver.c:2258 #, c-format msgid "input file appears to be a text format dump. Please use psql.\n" msgstr "" "Le fichier en entrée semble être une sauvegarde au format texte. Merci " "d'utiliser psql.\n" -#: pg_backup_archiver.c:2238 +#: pg_backup_archiver.c:2264 #, c-format msgid "input file does not appear to be a valid archive (too short?)\n" msgstr "" "le fichier en entrée ne semble pas être une archive valide (trop petit ?)\n" -#: pg_backup_archiver.c:2244 +#: pg_backup_archiver.c:2270 #, c-format msgid "input file does not appear to be a valid archive\n" msgstr "le fichier en entrée ne semble pas être une archive valide\n" -#: pg_backup_archiver.c:2264 +#: pg_backup_archiver.c:2290 #, c-format msgid "could not close input file: %s\n" msgstr "n'a pas pu fermer le fichier en entrée : %s\n" -#: pg_backup_archiver.c:2282 +#: pg_backup_archiver.c:2308 #, c-format msgid "allocating AH for %s, format %d\n" msgstr "allocation d'AH pour %s, format %d\n" -#: pg_backup_archiver.c:2383 +#: pg_backup_archiver.c:2409 #, c-format msgid "unrecognized file format \"%d\"\n" msgstr "format de fichier « %d » non reconnu\n" -#: pg_backup_archiver.c:2438 pg_backup_archiver.c:4206 +#: pg_backup_archiver.c:2464 pg_backup_archiver.c:4317 #, c-format msgid "finished item %d %s %s\n" msgstr "élément terminé %d %s %s\n" -#: pg_backup_archiver.c:2442 pg_backup_archiver.c:4219 +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4330 #, c-format msgid "worker process failed: exit code %d\n" msgstr "échec du processus de travail : code de sortie %d\n" -#: pg_backup_archiver.c:2562 +#: pg_backup_archiver.c:2588 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" msgstr "" "ID %d de l'entrée en dehors de la plage -- peut-être un TOC corrompu\n" -#: pg_backup_archiver.c:2678 +#: pg_backup_archiver.c:2704 #, c-format msgid "read TOC entry %d (ID %d) for %s %s\n" msgstr "lecture de l'entrée %d de la TOC (ID %d) pour %s %s\n" -#: pg_backup_archiver.c:2712 +#: pg_backup_archiver.c:2738 #, c-format msgid "unrecognized encoding \"%s\"\n" msgstr "encodage « %s » non reconnu\n" -#: pg_backup_archiver.c:2717 +#: pg_backup_archiver.c:2743 #, c-format msgid "invalid ENCODING item: %s\n" msgstr "élément ENCODING invalide : %s\n" -#: pg_backup_archiver.c:2735 +#: pg_backup_archiver.c:2761 #, c-format msgid "invalid STDSTRINGS item: %s\n" msgstr "élément STDSTRINGS invalide : %s\n" -#: pg_backup_archiver.c:2750 +#: pg_backup_archiver.c:2776 #, c-format msgid "schema \"%s\" not found\n" msgstr "schéma « %s » non trouvé\n" -#: pg_backup_archiver.c:2757 +#: pg_backup_archiver.c:2783 #, c-format msgid "table \"%s\" not found\n" msgstr "table « %s » non trouvée\n" -#: pg_backup_archiver.c:2764 +#: pg_backup_archiver.c:2790 #, c-format msgid "index \"%s\" not found\n" msgstr "index « %s » non trouvé\n" -#: pg_backup_archiver.c:2771 +#: pg_backup_archiver.c:2797 #, c-format msgid "function \"%s\" not found\n" msgstr "fonction « %s » non trouvée\n" -#: pg_backup_archiver.c:2778 +#: pg_backup_archiver.c:2804 #, c-format msgid "trigger \"%s\" not found\n" msgstr "trigger « %s » non trouvé\n" -#: pg_backup_archiver.c:3034 +#: pg_backup_archiver.c:3090 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "n'a pas pu initialiser la session utilisateur à « %s »: %s" -#: pg_backup_archiver.c:3066 +#: pg_backup_archiver.c:3122 #, c-format msgid "could not set default_with_oids: %s" msgstr "n'a pas pu configurer default_with_oids : %s" -#: pg_backup_archiver.c:3211 +#: pg_backup_archiver.c:3267 #, c-format msgid "could not set search_path to \"%s\": %s" msgstr "n'a pas pu configurer search_path à « %s » : %s" -#: pg_backup_archiver.c:3273 +#: pg_backup_archiver.c:3329 #, c-format msgid "could not set default_tablespace to %s: %s" msgstr "n'a pas pu configurer default_tablespace à %s : %s" -#: pg_backup_archiver.c:3363 pg_backup_archiver.c:3561 +#: pg_backup_archiver.c:3420 pg_backup_archiver.c:3613 #, c-format msgid "WARNING: don't know how to set owner for object type \"%s\"\n" msgstr "" "ATTENTION : ne sait pas comment initialiser le propriétaire du type d'objet " "« %s »\n" -#: pg_backup_archiver.c:3648 +#: pg_backup_archiver.c:3703 #, c-format msgid "did not find magic string in file header\n" msgstr "n'a pas trouver la chaîne magique dans le fichier d'en-tête\n" -#: pg_backup_archiver.c:3661 +#: pg_backup_archiver.c:3716 #, c-format msgid "unsupported version (%d.%d) in file header\n" msgstr "version non supportée (%d.%d) dans le fichier d'en-tête\n" -#: pg_backup_archiver.c:3666 +#: pg_backup_archiver.c:3721 #, c-format msgid "sanity check on integer size (%lu) failed\n" msgstr "échec de la vérification sur la taille de l'entier (%lu)\n" -#: pg_backup_archiver.c:3670 +#: pg_backup_archiver.c:3725 #, c-format msgid "" "WARNING: archive was made on a machine with larger integers, some " @@ -904,12 +894,12 @@ msgstr "" "ATTENTION : l'archive a été créée sur une machine disposant d'entiers plus\n" "larges, certaines opérations peuvent échouer\n" -#: pg_backup_archiver.c:3680 +#: pg_backup_archiver.c:3735 #, c-format msgid "expected format (%d) differs from format found in file (%d)\n" msgstr "le format attendu (%d) diffère du format du fichier (%d)\n" -#: pg_backup_archiver.c:3696 +#: pg_backup_archiver.c:3751 #, c-format msgid "" "WARNING: archive is compressed, but this installation does not support " @@ -918,72 +908,72 @@ msgstr "" "ATTENTION : l'archive est compressée mais cette installation ne supporte\n" "pas la compression -- aucune donnée ne sera disponible\n" -#: pg_backup_archiver.c:3714 +#: pg_backup_archiver.c:3769 #, c-format msgid "WARNING: invalid creation date in header\n" msgstr "ATTENTION : date de création invalide dans l'en-tête\n" -#: pg_backup_archiver.c:3789 +#: pg_backup_archiver.c:3842 #, c-format msgid "entering restore_toc_entries_prefork\n" msgstr "entrée dans restore_toc_entries_prefork\n" -#: pg_backup_archiver.c:3833 +#: pg_backup_archiver.c:3906 #, c-format msgid "processing item %d %s %s\n" msgstr "traitement de l'élément %d %s %s\n" -#: pg_backup_archiver.c:3883 +#: pg_backup_archiver.c:3960 #, c-format msgid "entering restore_toc_entries_parallel\n" msgstr "entrée dans restore_toc_entries_parallel\n" -#: pg_backup_archiver.c:3931 +#: pg_backup_archiver.c:3981 #, c-format msgid "entering main parallel loop\n" msgstr "entrée dans la boucle parallèle principale\n" -#: pg_backup_archiver.c:3942 +#: pg_backup_archiver.c:3992 #, c-format msgid "skipping item %d %s %s\n" msgstr "omission de l'élément %d %s %s\n" -#: pg_backup_archiver.c:3952 +#: pg_backup_archiver.c:4002 #, c-format msgid "launching item %d %s %s\n" msgstr "élément de lancement %d %s %s\n" -#: pg_backup_archiver.c:3983 +#: pg_backup_archiver.c:4056 #, c-format msgid "finished main parallel loop\n" msgstr "fin de la boucle parallèle principale\n" -#: pg_backup_archiver.c:3992 +#: pg_backup_archiver.c:4074 #, c-format msgid "entering restore_toc_entries_postfork\n" msgstr "entrée dans restore_toc_entries_prefork\n" -#: pg_backup_archiver.c:4011 +#: pg_backup_archiver.c:4094 #, c-format msgid "processing missed item %d %s %s\n" msgstr "traitement de l'élément manquant %d %s %s\n" -#: pg_backup_archiver.c:4162 +#: pg_backup_archiver.c:4273 #, c-format msgid "no item ready\n" msgstr "aucun élément prêt\n" -#: pg_backup_archiver.c:4381 +#: pg_backup_archiver.c:4492 #, c-format msgid "transferring dependency %d -> %d to %d\n" msgstr "transfert de la dépendance %d -> %d vers %d\n" -#: pg_backup_archiver.c:4454 +#: pg_backup_archiver.c:4565 #, c-format msgid "reducing dependencies for %d\n" msgstr "réduction des dépendances pour %d\n" -#: pg_backup_archiver.c:4493 +#: pg_backup_archiver.c:4617 #, c-format msgid "table \"%s\" could not be created, will not restore its data\n" msgstr "" @@ -1059,7 +1049,7 @@ msgstr "" "l'archive\n" #: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1090 +#: pg_backup_tar.c:1102 #, c-format msgid "could not determine seek position in archive file: %s\n" msgstr "" @@ -1253,39 +1243,45 @@ msgstr "n'a pas pu fermer le répertoire « %s » : %s\n" msgid "could not create directory \"%s\": %s\n" msgstr "n'a pas pu créer le répertoire « %s » : %s\n" -#: pg_backup_directory.c:407 +#: pg_backup_directory.c:355 pg_backup_directory.c:495 +#: pg_backup_directory.c:525 +#, c-format +msgid "could not write to output file: %s\n" +msgstr "n'a pas pu écrire dans le fichier de sauvegarde : %s\n" + +#: pg_backup_directory.c:409 #, c-format msgid "could not close data file: %s\n" msgstr "n'a pas pu fermer le fichier de données : %s\n" -#: pg_backup_directory.c:448 +#: pg_backup_directory.c:450 #, c-format msgid "could not open large object TOC file \"%s\" for input: %s\n" msgstr "" "n'a pas pu ouvrir le fichier sommaire « %s » du Large Object en entrée : " "%s\n" -#: pg_backup_directory.c:459 +#: pg_backup_directory.c:461 #, c-format msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" msgstr "ligne invalide dans le fichier TOC du Large Object « %s » : « %s »\n" -#: pg_backup_directory.c:468 +#: pg_backup_directory.c:470 #, c-format msgid "error reading large object TOC file \"%s\"\n" msgstr "erreur lors de la lecture du TOC du fichier Large Object « %s »\n" -#: pg_backup_directory.c:472 +#: pg_backup_directory.c:474 #, c-format msgid "could not close large object TOC file \"%s\": %s\n" msgstr "n'a pas pu fermer le TOC du Large Object « %s » : %s\n" -#: pg_backup_directory.c:686 +#: pg_backup_directory.c:690 #, c-format msgid "could not write to blobs TOC file\n" msgstr "n'a pas pu écrire dans le fichier toc des données binaires\n" -#: pg_backup_directory.c:718 +#: pg_backup_directory.c:722 #, c-format msgid "file name too long: \"%s\"\n" msgstr "nom du fichier trop long : « %s »\n" @@ -1345,27 +1341,27 @@ msgstr "n'a pas pu ouvrir le fichier temporaire\n" msgid "could not close tar member\n" msgstr "n'a pas pu fermer le membre de tar\n" -#: pg_backup_tar.c:569 +#: pg_backup_tar.c:581 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "erreur interne -- ni th ni fh ne sont précisés dans tarReadRaw()\n" -#: pg_backup_tar.c:692 +#: pg_backup_tar.c:704 #, c-format msgid "unexpected COPY statement syntax: \"%s\"\n" msgstr "syntaxe inattendue de l'instruction COPY : « %s »\n" -#: pg_backup_tar.c:962 +#: pg_backup_tar.c:974 #, c-format msgid "invalid OID for large object (%u)\n" msgstr "OID invalide pour le « Large Object » (%u)\n" -#: pg_backup_tar.c:1106 +#: pg_backup_tar.c:1118 #, c-format msgid "could not close temporary file: %s\n" msgstr "n'a pas pu ouvrir le fichier temporaire : %s\n" -#: pg_backup_tar.c:1116 +#: pg_backup_tar.c:1128 #, c-format msgid "actual file length (%s) does not match expected (%s)\n" msgstr "" @@ -1373,29 +1369,29 @@ msgstr "" "attendu\n" "(%s)\n" -#: pg_backup_tar.c:1153 +#: pg_backup_tar.c:1165 #, c-format msgid "moving from position %s to next member at file position %s\n" msgstr "" "déplacement de la position %s vers le prochain membre à la position %s du " "fichier\n" -#: pg_backup_tar.c:1164 +#: pg_backup_tar.c:1176 #, c-format msgid "now at file position %s\n" msgstr "maintenant en position %s du fichier\n" -#: pg_backup_tar.c:1173 pg_backup_tar.c:1203 +#: pg_backup_tar.c:1185 pg_backup_tar.c:1215 #, c-format msgid "could not find header for file \"%s\" in tar archive\n" msgstr "n'a pas pu trouver l'en-tête du fichier « %s » dans l'archive tar\n" -#: pg_backup_tar.c:1187 +#: pg_backup_tar.c:1199 #, c-format msgid "skipping tar member %s\n" msgstr "omission du membre %s du tar\n" -#: pg_backup_tar.c:1191 +#: pg_backup_tar.c:1203 #, c-format msgid "" "restoring data out of order is not supported in this archive format: \"%s\" " @@ -1405,19 +1401,19 @@ msgstr "" "d'archive : « %s » est requis mais vient avant « %s » dans le fichier\n" "d'archive.\n" -#: pg_backup_tar.c:1237 +#: pg_backup_tar.c:1249 #, c-format msgid "incomplete tar header found (%lu byte)\n" msgid_plural "incomplete tar header found (%lu bytes)\n" msgstr[0] "en-tête incomplet du fichier tar (%lu octet)\n" msgstr[1] "en-tête incomplet du fichier tar (%lu octets)\n" -#: pg_backup_tar.c:1278 +#: pg_backup_tar.c:1290 #, c-format msgid "TOC Entry %s at %s (length %s, checksum %d)\n" msgstr "entrée TOC %s à %s (longueur %s, somme de contrôle %d)\n" -#: pg_backup_tar.c:1289 +#: pg_backup_tar.c:1301 #, c-format msgid "" "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" @@ -1997,12 +1993,13 @@ msgstr "encodage client indiqué (« %s ») invalide\n" #: pg_dump.c:1136 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server " +"version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" "synchronized snapshots.\n" msgstr "" -"Les snapshots synchronisés ne sont pas supportés sur les serveurs de " -"stadby.\n" +"Les snapshots synchronisés sur les serveurs standbys ne sont pas supportés " +"par cette version serveur.\n" "Lancez avec --no-synchronized-snapshots à la place si vous n'avez pas " "besoin\n" "de snapshots synchronisés.\n" @@ -2051,65 +2048,65 @@ msgstr "" "La sauvegarde du contenu de la table « %s » a échoué : échec de\n" "PQgetResult().\n" -#: pg_dump.c:2481 +#: pg_dump.c:2482 #, c-format msgid "saving database definition\n" msgstr "sauvegarde de la définition de la base de données\n" -#: pg_dump.c:2787 +#: pg_dump.c:2795 #, c-format msgid "saving encoding = %s\n" msgstr "encodage de la sauvegarde = %s\n" -#: pg_dump.c:2814 +#: pg_dump.c:2822 #, c-format msgid "saving standard_conforming_strings = %s\n" msgstr "standard_conforming_strings de la sauvegarde = %s\n" -#: pg_dump.c:2854 +#: pg_dump.c:2862 #, c-format msgid "reading large objects\n" msgstr "lecture des « Large Objects »\n" -#: pg_dump.c:3049 +#: pg_dump.c:3057 #, c-format msgid "saving large objects\n" msgstr "sauvegarde des « Large Objects »\n" -#: pg_dump.c:3094 +#: pg_dump.c:3102 #, c-format msgid "error reading large object %u: %s" msgstr "erreur lors de la lecture du « Large Object » %u : %s" -#: pg_dump.c:3147 +#: pg_dump.c:3155 #, c-format msgid "reading row security enabled for table \"%s.%s\"\n" msgstr "" "lecture de l'activation de la sécurité niveau ligne pour la table « %s.%s " "»\n" -#: pg_dump.c:3179 +#: pg_dump.c:3187 #, c-format msgid "reading policies for table \"%s.%s\"\n" msgstr "lecture des politiques pour la table « %s.%s »\n" -#: pg_dump.c:3329 +#: pg_dump.c:3337 #, c-format msgid "unexpected policy command type: %c\n" msgstr "type de commande inattendu pour la politique : %c\n" -#: pg_dump.c:3445 +#: pg_dump.c:3456 #, c-format msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la publication « %s » semble être invalide\n" -#: pg_dump.c:3575 +#: pg_dump.c:3589 #, c-format msgid "reading publication membership for table \"%s.%s\"\n" msgstr "lecture des appartenances aux publications pour la table « %s.%s »\n" -#: pg_dump.c:3722 +#: pg_dump.c:3738 #, c-format msgid "" "WARNING: subscriptions not dumped because current user is not a superuser\n" @@ -2117,77 +2114,77 @@ msgstr "" "ATTENTION : les souscriptions ne sont pas sauvegardées parce que " "l'utilisateur courant n'est pas un superutilisateur\n" -#: pg_dump.c:3776 +#: pg_dump.c:3792 #, c-format msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la souscription « %s » semble être invalide\n" -#: pg_dump.c:3820 +#: pg_dump.c:3836 #, c-format msgid "WARNING: could not parse subpublications array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau de sous-publications\n" -#: pg_dump.c:4053 +#: pg_dump.c:4069 #, c-format msgid "could not find parent extension for %s\n" msgstr "n'a pas pu trouver l'extension parent pour %s\n" -#: pg_dump.c:4207 +#: pg_dump.c:4223 #, c-format msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" msgstr "ATTENTION : le propriétaire du schéma « %s » semble être invalide\n" -#: pg_dump.c:4230 +#: pg_dump.c:4246 #, c-format msgid "schema with OID %u does not exist\n" msgstr "le schéma d'OID %u n'existe pas\n" -#: pg_dump.c:4561 +#: pg_dump.c:4577 #, c-format msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire du type de données « %s » semble être invalide\n" -#: pg_dump.c:4649 +#: pg_dump.c:4665 #, c-format msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de l'opérateur « %s » semble être invalide\n" -#: pg_dump.c:4963 +#: pg_dump.c:4979 #, c-format msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la classe d'opérateur « %s » semble être\n" "invalide\n" -#: pg_dump.c:5050 +#: pg_dump.c:5066 #, c-format msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la famille d'opérateur « %s » semble être\n" "invalide\n" -#: pg_dump.c:5217 +#: pg_dump.c:5233 #, c-format msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la fonction d'aggrégat « %s » semble être\n" "invalide\n" -#: pg_dump.c:5476 +#: pg_dump.c:5492 #, c-format msgid "WARNING: owner of function \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : le propriétaire de la fonction « %s » semble être invalide\n" -#: pg_dump.c:6258 +#: pg_dump.c:6275 #, c-format msgid "WARNING: owner of table \"%s\" appears to be invalid\n" msgstr "ATTENTION : le propriétaire de la table « %s » semble être invalide\n" -#: pg_dump.c:6300 pg_dump.c:16529 +#: pg_dump.c:6317 pg_dump.c:16582 #, c-format msgid "" "failed sanity check, parent table with OID %u of sequence with OID %u not " @@ -2196,22 +2193,17 @@ msgstr "" "vérification échouée, OID %u de la table parent de l'OID %u de la séquence " "introuvable\n" -#: pg_dump.c:6431 +#: pg_dump.c:6448 #, c-format msgid "reading indexes for table \"%s.%s\"\n" msgstr "lecture des index de la table « %s.%s »\n" -#: pg_dump.c:6712 -#, c-format -msgid "reading extended statistics for table \"%s.%s\"\n" -msgstr "lecture des statistiques étendues pour la table « %s.%s »\n" - -#: pg_dump.c:6795 +#: pg_dump.c:6784 #, c-format msgid "reading foreign key constraints for table \"%s.%s\"\n" msgstr "lecture des contraintes de clés étrangères pour la table « %s.%s »\n" -#: pg_dump.c:7019 +#: pg_dump.c:7008 #, c-format msgid "" "failed sanity check, parent table with OID %u of pg_rewrite entry with OID " @@ -2220,12 +2212,12 @@ msgstr "" "vérification échouée, OID %u de la table parent de l'OID %u de l'entrée de\n" "pg_rewrite introuvable\n" -#: pg_dump.c:7103 +#: pg_dump.c:7092 #, c-format msgid "reading triggers for table \"%s.%s\"\n" msgstr "lecture des triggers pour la table « %s.%s »\n" -#: pg_dump.c:7241 +#: pg_dump.c:7230 #, c-format msgid "" "query produced null referenced table name for foreign key trigger \"%s\" on " @@ -2234,32 +2226,32 @@ msgstr "" "la requête a produit une réference de nom de table null pour le trigger de\n" "clé étrangère « %s » sur la table « %s » (OID de la table : %u)\n" -#: pg_dump.c:7813 +#: pg_dump.c:7802 #, c-format msgid "finding the columns and types of table \"%s.%s\"\n" msgstr "recherche des colonnes et types de la table « %s.%s »\n" -#: pg_dump.c:7978 +#: pg_dump.c:7967 #, c-format msgid "invalid column numbering in table \"%s\"\n" msgstr "numérotation des colonnes invalide pour la table « %s »\n" -#: pg_dump.c:8014 +#: pg_dump.c:8003 #, c-format msgid "finding default expressions of table \"%s.%s\"\n" msgstr "recherche des expressions par défaut de la table « %s.%s »\n" -#: pg_dump.c:8037 +#: pg_dump.c:8026 #, c-format msgid "invalid adnum value %d for table \"%s\"\n" msgstr "valeur adnum %d invalide pour la table « %s »\n" -#: pg_dump.c:8103 +#: pg_dump.c:8092 #, c-format msgid "finding check constraints for table \"%s.%s\"\n" msgstr "recherche des contraintes de vérification pour la table « %s.%s »\n" -#: pg_dump.c:8152 +#: pg_dump.c:8141 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d\n" msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" @@ -2270,71 +2262,71 @@ msgstr[1] "" "%d contraintes de vérification attendues pour la table « %s » mais %d\n" "trouvées\n" -#: pg_dump.c:8156 +#: pg_dump.c:8145 #, c-format msgid "(The system catalogs might be corrupted.)\n" msgstr "(Les catalogues système sont peut-être corrompus.)\n" -#: pg_dump.c:9714 +#: pg_dump.c:9703 #, c-format msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" msgstr "" "ATTENTION : la colonne typtype du type de données « %s » semble être " "invalide\n" -#: pg_dump.c:11143 +#: pg_dump.c:11132 #, c-format msgid "WARNING: bogus value in proargmodes array\n" msgstr "ATTENTION : valeur erronée dans le tableau proargmodes\n" -#: pg_dump.c:11469 +#: pg_dump.c:11458 #, c-format msgid "WARNING: could not parse proallargtypes array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau proallargtypes\n" -#: pg_dump.c:11485 +#: pg_dump.c:11474 #, c-format msgid "WARNING: could not parse proargmodes array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau proargmodes\n" -#: pg_dump.c:11499 +#: pg_dump.c:11488 #, c-format msgid "WARNING: could not parse proargnames array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau proargnames\n" -#: pg_dump.c:11510 +#: pg_dump.c:11499 #, c-format msgid "WARNING: could not parse proconfig array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau proconfig\n" -#: pg_dump.c:11581 +#: pg_dump.c:11570 #, c-format msgid "unrecognized provolatile value for function \"%s\"\n" msgstr "valeur provolatile non reconnue pour la fonction « %s »\n" -#: pg_dump.c:11625 pg_dump.c:13623 +#: pg_dump.c:11614 pg_dump.c:13612 #, c-format msgid "unrecognized proparallel value for function \"%s\"\n" msgstr "valeur proparallel non reconnue pour la fonction « %s »\n" -#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 +#: pg_dump.c:11722 pg_dump.c:11832 pg_dump.c:11839 #, c-format msgid "could not find function definition for function with OID %u\n" msgstr "n'a pas pu trouver la définition de la fonction d'OID %u\n" -#: pg_dump.c:11778 +#: pg_dump.c:11767 #, c-format msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" msgstr "" "ATTENTION : valeur erronée dans le champ pg_cast.castfunc ou pg_cast." "castmethod\n" -#: pg_dump.c:11781 +#: pg_dump.c:11770 #, c-format msgid "WARNING: bogus value in pg_cast.castmethod field\n" msgstr "ATTENTION : valeur erronée dans pg_cast.castmethod\n" -#: pg_dump.c:11871 +#: pg_dump.c:11860 #, c-format msgid "" "WARNING: bogus transform definition, at least one of trffromsql and " @@ -2343,27 +2335,27 @@ msgstr "" "ATTENTION : définition de transformation invalide, au moins un de " "trffromsql et trftosql ne doit pas valoir 0\n" -#: pg_dump.c:11888 +#: pg_dump.c:11877 #, c-format msgid "WARNING: bogus value in pg_transform.trffromsql field\n" msgstr "ATTENTION : valeur erronée dans pg_transform.trffromsql\n" -#: pg_dump.c:11909 +#: pg_dump.c:11898 #, c-format msgid "WARNING: bogus value in pg_transform.trftosql field\n" msgstr "ATTENTION : valeur erronée dans pg_transform.trftosql\n" -#: pg_dump.c:12305 +#: pg_dump.c:12294 #, c-format msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" msgstr "ATTENTION : type « %c » invalide de la méthode d'accès « %s »\n" -#: pg_dump.c:13086 +#: pg_dump.c:13075 #, c-format msgid "unrecognized collation provider: %s\n" msgstr "fournisseur de collationnement non reconnu : %s\n" -#: pg_dump.c:13533 +#: pg_dump.c:13522 #, c-format msgid "" "WARNING: aggregate function %s could not be dumped correctly for this " @@ -2372,17 +2364,17 @@ msgstr "" "ATTENTION : la fonction d'aggrégat %s n'a pas pu être sauvegardée\n" " correctement avec cette version de la base de données ; ignorée\n" -#: pg_dump.c:14389 +#: pg_dump.c:14376 #, c-format msgid "unrecognized object type in default privileges: %d\n" msgstr "type d'objet inconnu dans les droits par défaut : %d\n" -#: pg_dump.c:14407 +#: pg_dump.c:14394 #, c-format msgid "could not parse default ACL list (%s)\n" msgstr "n'a pas pu analyser la liste ACL par défaut (%s)\n" -#: pg_dump.c:14478 +#: pg_dump.c:14476 #, c-format msgid "" "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) " @@ -2391,7 +2383,7 @@ msgstr "" "n'a pas pu analyser la liste GRANT ACL initiale (%s) ou la liste REVOKE ACL " "initiale (%s) de l'objet « %s » (%s)\n" -#: pg_dump.c:14486 +#: pg_dump.c:14484 #, c-format msgid "" "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s" @@ -2400,14 +2392,14 @@ msgstr "" "n'a pas pu analyser la liste GRANT ACL (%s) ou REVOKE ACL (%s) de l'objet « " "%s » (%s)\n" -#: pg_dump.c:14961 +#: pg_dump.c:14964 #, c-format msgid "query to obtain definition of view \"%s\" returned no data\n" msgstr "" "la requête permettant d'obtenir la définition de la vue « %s » n'a renvoyé\n" "aucune donnée\n" -#: pg_dump.c:14964 +#: pg_dump.c:14967 #, c-format msgid "" "query to obtain definition of view \"%s\" returned more than one " @@ -2416,32 +2408,32 @@ msgstr "" "la requête permettant d'obtenir la définition de la vue « %s » a renvoyé\n" " plusieurs définitions\n" -#: pg_dump.c:14971 +#: pg_dump.c:14974 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)\n" msgstr "la définition de la vue « %s » semble être vide (longueur nulle)\n" -#: pg_dump.c:15200 +#: pg_dump.c:15203 #, c-format msgid "invalid number of parents %d for table \"%s\"\n" msgstr "nombre de parents invalide (%d) pour la table « %s »\n" -#: pg_dump.c:15847 +#: pg_dump.c:15874 #, c-format msgid "invalid column number %d for table \"%s\"\n" msgstr "numéro de colonne %d invalide pour la table « %s »\n" -#: pg_dump.c:16031 +#: pg_dump.c:16076 #, c-format msgid "missing index for constraint \"%s\"\n" msgstr "index manquant pour la contrainte « %s »\n" -#: pg_dump.c:16234 +#: pg_dump.c:16279 #, c-format msgid "unrecognized constraint type: %c\n" msgstr "type de contrainte inconnu : %c\n" -#: pg_dump.c:16371 pg_dump.c:16597 +#: pg_dump.c:16423 pg_dump.c:16650 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" msgid_plural "" @@ -2455,18 +2447,23 @@ msgstr[1] "" "renvoyé\n" "%d lignes (une seule attendue)\n" -#: pg_dump.c:16695 +#: pg_dump.c:16457 +#, c-format +msgid "unrecognized sequence type: %s\n" +msgstr "type de séquence non reconnu : « %s »\n" + +#: pg_dump.c:16748 #, c-format msgid "unexpected tgtype value: %d\n" msgstr "valeur tgtype inattendue : %d\n" -#: pg_dump.c:16769 +#: pg_dump.c:16822 #, c-format msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" msgstr "" "chaîne argument invalide (%s) pour le trigger « %s » sur la table « %s »\n" -#: pg_dump.c:17000 +#: pg_dump.c:17053 #, c-format msgid "" "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows " @@ -2475,12 +2472,12 @@ msgstr "" "la requête permettant d'obtenir la règle « %s » associée à la table « %s »\n" "a échoué : mauvais nombre de lignes renvoyées\n" -#: pg_dump.c:17395 +#: pg_dump.c:17448 #, c-format msgid "reading dependency data\n" msgstr "lecture des données de dépendance\n" -#: pg_dump.c:17860 +#: pg_dump.c:17913 #, c-format msgid "WARNING: could not parse reloptions array\n" msgstr "ATTENTION : n'a pas pu analyser le tableau reloptions\n" @@ -3101,6 +3098,23 @@ msgstr "" "utilisée.\n" "\n" +#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" +#~ msgstr "réglage du propriétaire et des droits pour %s « %s.%s»\n" + +#~ msgid "setting owner and privileges for %s \"%s\"\n" +#~ msgstr "réglage du propriétaire et des droits pour %s « %s »\n" + +#~ msgid "" +#~ "Synchronized snapshots are not supported on standby servers.\n" +#~ "Run with --no-synchronized-snapshots instead if you do not need\n" +#~ "synchronized snapshots.\n" +#~ msgstr "" +#~ "Les snapshots synchronisés ne sont pas supportés sur les serveurs de " +#~ "stadby.\n" +#~ "Lancez avec --no-synchronized-snapshots à la place si vous n'avez pas " +#~ "besoin\n" +#~ "de snapshots synchronisés.\n" + #~ msgid "error processing a parallel work item\n" #~ msgstr "erreur durant le traitement en parallèle d'un item\n" @@ -3362,9 +3376,6 @@ msgstr "" #~ msgid "could not write to custom output routine\n" #~ msgstr "n'a pas pu écrire vers la routine de sauvegarde personnalisée\n" -#~ msgid "could not write to output file: %s\n" -#~ msgstr "n'a pas pu écrire dans le fichier de sauvegarde : %s\n" - #~ msgid "could not open output file \"%s\" for writing\n" #~ msgstr "n'a pas pu ouvrir le fichier de sauvegarde « %s » en écriture\n" @@ -3385,3 +3396,6 @@ msgstr "" #~ msgid "worker is terminating\n" #~ msgstr "le worker est en cours d'arrêt\n" + +#~ msgid "reading extended statistics for table \"%s.%s\"\n" +#~ msgstr "lecture des statistiques étendues pour la table « %s.%s »\n" diff --git a/src/bin/pg_dump/po/he.po b/src/bin/pg_dump/po/he.po new file mode 100644 index 00000000000..e8862ac9c90 --- /dev/null +++ b/src/bin/pg_dump/po/he.po @@ -0,0 +1,2883 @@ +# Hebrew message translation file for pg_dump +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Michael Goldberg , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-05-17 03:16+0000\n" +"PO-Revision-Date: 2017-08-15 10:37-0400\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Last-Translator: Michael Goldberg \n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.2\n" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "×œ× ×™×•×›×œ לזהות ×ת הספריה הנוכחית: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "בינ×רי ×œ× ×—×•×§×™ \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "×œ× × ×™×ª×Ÿ ×œ×§×¨×•× ×‘×™× ×רי \"%s\"" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "×œ× × ×™×ª×Ÿ ×œ×ž×¦×•× \"%s\" לביצוע" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "×œ× ×œ×©× ×•×ª לשנות ספריות ל \"%s\": %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "×œ× × ×™×ª×Ÿ ×œ×§×¨×•× ×ת הקישור הסימבולי \"%s\"" + +#: ../../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "נכשלpclose : %s" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "×ין זיכרון פנוי\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "×œ× × ×™×ª×Ÿ לשכפל מצביע ריק (שגי××” פנימית)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "×œ× × ×™×ª×Ÿ לבצע ×ת הפקודה" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "הפקודה ×œ× × ×ž×¦××”" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "תהליך צ××¦× ×™×¦× ×¢× %d" + +#: ../../common/wait_error.c:61 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "תהליך צ××¦× ×”×•×¤×¡×§ על ידי חריגה 0 0x %X" + +#: ../../common/wait_error.c:71 +#, c-format +msgid "child process was terminated by signal %s" +msgstr "תהליך צ××¦× ×”×•×¤×¡×§ על ידי ×”×ות %s" + +#: ../../common/wait_error.c:75 +#, c-format +msgid "child process was terminated by signal %d" +msgstr "תהליך צ××¦× ×”×•×¤×¡×§ על ידי ×”×ות %d" + +#: ../../common/wait_error.c:80 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "תהליך צ××¦× ×™×¦× ×¢× ×ž×¦×‘ ×œ× ×ž×–×•×”×” %d" + +#: common.c:121 +#, c-format +msgid "reading extensions\n" +msgstr "קרי××” הרחבות\n" + +#: common.c:126 +#, c-format +msgid "identifying extension members\n" +msgstr "זיהוי חברי הרחבה\n" + +#: common.c:130 +#, c-format +msgid "reading schemas\n" +msgstr "קרי××” סכימות\n" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables\n" +msgstr "קרי×ת טבל×ות המשתמש\n" + +#: common.c:149 +#, c-format +msgid "reading user-defined functions\n" +msgstr "קרי××” פונקציות המוגדרות על-ידי המשתמש\n" + +#: common.c:155 +#, c-format +msgid "reading user-defined types\n" +msgstr "קרי××” ×˜×™×¤×•×¡×™× ×”×ž×•×’×“×¨×™× ×¢×œ-ידי המשתמש\n" + +#: common.c:161 +#, c-format +msgid "reading procedural languages\n" +msgstr "קרי××” שפות פרוצדור×ליות\n" + +#: common.c:165 +#, c-format +msgid "reading user-defined aggregate functions\n" +msgstr "קרי××” פונקציות צבירה המוגדרות על-ידי המשתמש\n" + +#: common.c:169 +#, c-format +msgid "reading user-defined operators\n" +msgstr "קרי××” ××•×¤×¨×˜×•×¨×™× ×”×ž×•×’×“×¨×™× ×¢×œ-ידי המשתמש\n" + +#: common.c:174 +#, c-format +msgid "reading user-defined access methods\n" +msgstr "קרי××” שיטות גישה המוגדרות על-ידי המשתמש\n" + +#: common.c:178 +#, c-format +msgid "reading user-defined operator classes\n" +msgstr "קרי×ת מחלקות ×ופרטור המוגדרות על ידי המשתמש\n" + +#: common.c:182 +#, c-format +msgid "reading user-defined operator families\n" +msgstr "קרי×ת משפחות ×ופרטור המוגדרות על ידי המשתמש\n" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search parsers\n" +msgstr "קרי×ת מנתחי מבנה החיפוש טקסט ×”×ž×•×’×“×¨×™× ×¢×œ-ידי המשתמש\n" + +#: common.c:190 +#, c-format +msgid "reading user-defined text search templates\n" +msgstr "קרי×ת תבניות החיפוש טקסט המוגדרות על-ידי המשתמש\n" + +#: common.c:194 +#, c-format +msgid "reading user-defined text search dictionaries\n" +msgstr "קרי×ת מילוני חיפוש טקסט ×”×ž×’×“×¨×™× ×¢×œ-ידי המשתמש חיפוש\n" + +#: common.c:198 +#, c-format +msgid "reading user-defined text search configurations\n" +msgstr "קרי×ת תצורות חיפוש טקסט המוגדרות על-ידי המשתמש\n" + +#: common.c:202 +#, c-format +msgid "reading user-defined foreign-data wrappers\n" +msgstr "קרי××” עטיפות × ×ª×•× ×™× ×–×¨×™× ×”×ž×•×’×“×¨×•×ª על-ידי המשתמש\n" + +#: common.c:206 +#, c-format +msgid "reading user-defined foreign servers\n" +msgstr "הקרי××” ×©×¨×ª×™× ×–×¨×™× ×”×ž×•×’×“×¨×™× ×¢×œ-ידי המשתמש\n" + +#: common.c:210 +#, c-format +msgid "reading default privileges\n" +msgstr "קרי×ת הרש×ות ברירת מחדל\n" + +#: common.c:214 +#, c-format +msgid "reading user-defined collations\n" +msgstr "הקרי××” ×–×¨×™× ×”×ž×•×’×“×¨×™× ×¢×œ-ידי המשתמש\n" + +#: common.c:219 +#, c-format +msgid "reading user-defined conversions\n" +msgstr "הקרי××” המרות המוגדרות על-ידי המשתמש\n" + +#: common.c:223 +#, c-format +msgid "reading type casts\n" +msgstr "קרי×ות סוגי הטלות\n" + +#: common.c:227 +#, c-format +msgid "reading transforms\n" +msgstr "קרי××” שינויי צורה\n" + +#: common.c:231 +#, c-format +msgid "reading table inheritance information\n" +msgstr "קרי×ת המידע על ירושת הטבלה\n" + +#: common.c:235 +#, c-format +msgid "reading event triggers\n" +msgstr "קרי××” ×˜×¨×™×’×¨×™× ×©×œ ×ירוע\n" + +#: common.c:240 +#, c-format +msgid "finding extension tables\n" +msgstr "מצי×ת טבל×ות ההרחבה\n" + +#: common.c:245 +#, c-format +msgid "finding inheritance relationships\n" +msgstr "מצי×ת יחסי ירושה\n" + +#: common.c:249 +#, c-format +msgid "reading column info for interesting tables\n" +msgstr "קרי××” מידע על עמודה של טבל×ות מעניינות\n" + +#: common.c:253 +#, c-format +msgid "flagging inherited columns in subtables\n" +msgstr "סימון עמודות מורשות בתת טבל×ות\n" + +#: common.c:257 +#, c-format +msgid "reading indexes\n" +msgstr "קרי××” ×ינדקסי×\n" + +#: common.c:261 +#, c-format +msgid "reading extended statistics\n" +msgstr "קרי××” סטטיסטיקה מורחבת\n" + +#: common.c:265 +#, c-format +msgid "reading constraints\n" +msgstr "קרי××” ×ילוצי×\n" + +#: common.c:269 +#, c-format +msgid "reading triggers\n" +msgstr "קרי××” טריגירי×\n" + +#: common.c:273 +#, c-format +msgid "reading rewrite rules\n" +msgstr "קרי××” ×—×•×§×™× ×œ×©×›×ª×‘\n" + +#: common.c:277 +#, c-format +msgid "reading policies\n" +msgstr "קרי××” מדיניות\n" + +#: common.c:281 +#, c-format +msgid "reading publications\n" +msgstr "קרי××” פרסומי×\n" + +#: common.c:285 +#, c-format +msgid "reading publication membership\n" +msgstr "קרי××” לחברות פרסו×\n" + +#: common.c:289 +#, c-format +msgid "reading subscriptions\n" +msgstr "קרי××” מנויי×\n" + +#: common.c:924 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" +msgstr "בדיקת שפיות נכשלה, ×ובייקט ×”×בOID %u של טבלה '%s' (OID %u) ×œ× × ×ž×¦×\n" + +#: common.c:966 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לנתח ×ת מערך מספרי \"%s\": ×ž×¡×¤×¨×™× ×¨×‘×™× ×ž×“×™\n" + +#: common.c:981 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לנתח ×ת מערך מספרי \"%s\": תו ×œ× ×—×•×§×™ במספר\n" + +#. translator: this is a module name +#: compress_io.c:78 +msgid "compress_io" +msgstr "compress_io" + +#: compress_io.c:114 +#, c-format +msgid "invalid compression code: %d\n" +msgstr "קוד דחיסה ×œ× ×—×•×§×™: %d\n" + +#: compress_io.c:138 compress_io.c:174 compress_io.c:192 compress_io.c:519 +#: compress_io.c:562 +#, c-format +msgid "not built with zlib support\n" +msgstr "×œ× ×‘× ×•×™ ×¢× ×ª×ž×™×›×” zlib\n" + +#: compress_io.c:242 compress_io.c:344 +#, c-format +msgid "could not initialize compression library: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ל×תחל ×ת ספריית דחיסה: %s\n" + +#: compress_io.c:263 +#, c-format +msgid "could not close compression stream: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור ×–×¨× ×“×—×™×¡×”: %s\n" + +#: compress_io.c:281 +#, c-format +msgid "could not compress data: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לדחוס נתוני×: %s\n" + +#: compress_io.c:361 compress_io.c:377 +#, c-format +msgid "could not uncompress data: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לבטל ×ת דחיסת הנתוני×: %s\n" + +#: compress_io.c:385 +#, c-format +msgid "could not close compression library: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור ×ת הספרייה דחיסה: %s\n" + +#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:587 +#: pg_backup_tar.c:559 +#, c-format +msgid "could not read from input file: %s\n" +msgstr "×œ× × ×™×ª×Ÿ ×œ×§×¨×•× ×ž×ª×•×š קובץ הקלט: %s\n" + +#: compress_io.c:635 pg_backup_custom.c:584 pg_backup_directory.c:543 +#: pg_backup_tar.c:795 pg_backup_tar.c:819 +#, c-format +msgid "could not read from input file: end of file\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×§×¨×•× ×ž×ª×•×š קובץ הקלט: סוף הקובץ\n" + +#: parallel.c:198 +msgid "parallel archiver" +msgstr "×רכיבר מקבילי" + +#: parallel.c:265 +#, c-format +msgid "%s: WSAStartup failed: %d\n" +msgstr "תכנית %s: נכשל WSAStartup : %d\n" + +#: parallel.c:971 +#, c-format +msgid "could not create communication channels: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ליצור ערוצי תקשורת: %s\n" + +#: parallel.c:1036 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ליצור תהליך עובד: %s\n" + +#: parallel.c:1167 +#, c-format +msgid "unrecognized command received from master: \"%s\"\n" +msgstr "פקודה ×œ× ×ž×–×•×”×” נתקבלה מהמ×סטר: \"%s\"\n" + +#: parallel.c:1211 parallel.c:1451 +#, c-format +msgid "invalid message received from worker: \"%s\"\n" +msgstr "הודעה ×œ× ×—×•×§×™×ª נתקבלה מתהליך העובד: \"%s\"\n" + +#: parallel.c:1344 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table.\n" +msgstr "" +"×œ× ×”×™×ª×” ×פשרות להשיג נעילה על היחס \"%s\"\n" +"×–×” בדרך כלל ×ומר ×›×™ מישהו ביקש נעילת גישה בלעדית על הטבלה ל×חר שתהליך ×”×ב pg_dump קיבל נעילת גישה המשותפת הר×שונית על הטבלה.\n" + +#: parallel.c:1433 +#, c-format +msgid "a worker process died unexpectedly\n" +msgstr "תהליך עובד נעצר ב×ופן בלתי צפוי\n" + +#: parallel.c:1557 parallel.c:1675 +#, c-format +msgid "could not write to the communication channel: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לכתוב לערוץ תקשורת: %s\n" + +#: parallel.c:1635 +#, c-format +msgid "select() failed: %s\n" +msgstr "נכשל select(): %s\n" + +#: parallel.c:1760 +#, c-format +msgid "pgpipe: could not create socket: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות ליצור שקע: קוד שגי××” %d\n" + +#: parallel.c:1771 +#, c-format +msgid "pgpipe: could not bind: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות לקשור: קוד שגי××” %d\n" + +#: parallel.c:1778 +#, c-format +msgid "pgpipe: could not listen: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות לה×זין: קוד שגי××” %d\n" + +#: parallel.c:1785 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d\n" +msgstr "תכנית pgpipe: נכשל getsockname() : קוד שגי××” %d\n" + +#: parallel.c:1796 +#, c-format +msgid "pgpipe: could not create second socket: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות ליצור שקע שני: קוד שגי××” %d\n" + +#: parallel.c:1805 +#, c-format +msgid "pgpipe: could not connect socket: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות לחבר שקע: קוד שגי××” %d\n" + +#: parallel.c:1814 +#, c-format +msgid "pgpipe: could not accept connection: error code %d\n" +msgstr "תכנית pgpipe: ×œ× ×”×™×ª×” ×פשרות לקבל חיבור: קוד שגי××” %d\n" + +#. translator: this is a module name +#: pg_backup_archiver.c:53 +msgid "archiver" +msgstr "×רכיבר" + +#: pg_backup_archiver.c:243 pg_backup_archiver.c:1573 +#, c-format +msgid "could not close output file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור קובץ הפלט: %s\n" + +#: pg_backup_archiver.c:289 pg_backup_archiver.c:294 +#, c-format +msgid "WARNING: archive items not in correct section order\n" +msgstr "×זהרה: פריטי ×רכיון ×œ× ×‘×¡×“×¨ נכון במחלקה\n" + +#: pg_backup_archiver.c:300 +#, c-format +msgid "unexpected section code %d\n" +msgstr "קוד סעיף ×œ× ×¦×¤×•×™ %d\n" + +#: pg_backup_archiver.c:336 +#, c-format +msgid "-C and -1 are incompatible options\n" +msgstr "×”×ופציות ×œ× ×ª×•×מות -C ו-1\n" + +#: pg_backup_archiver.c:346 +#, c-format +msgid "parallel restore is not supported with this archive file format\n" +msgstr "שחזור מקבילי ×ינו נתמך ×¢× ×¤×•×¨×ž×˜ קובץ ×רכיון ×–×”\n" + +#: pg_backup_archiver.c:350 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" +msgstr "שחזור מקבילי ××™× ×” נתמך ×¢× ×רכיון שנעשו על ידי pg_dump טרו×-8.0\n" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)\n" +msgstr "×ין ×פשרות לשחזר מ×רכיון דחוס (דחיסה נתמכות בהתקנה זו)\n" + +#: pg_backup_archiver.c:385 +#, c-format +msgid "connecting to database for restore\n" +msgstr "התחברות למסד × ×ª×•× ×™× ×¢×‘×•×¨ שחזור\n" + +#: pg_backup_archiver.c:387 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives\n" +msgstr "×—×™×‘×•×¨×™× ×™×©×™×¨×™× ×œ×ž×¡×“ × ×ª×•× ×™× ××™× × × ×ª×ž×›×™× ×‘××¨×›×™×•× ×™× ×˜×¨×•×-1.3\n" + +#: pg_backup_archiver.c:432 +#, c-format +msgid "implied data-only restore\n" +msgstr "שחזור × ×ª×•× ×™× ×‘×œ×‘×“ משתמע\n" + +#: pg_backup_archiver.c:502 +#, c-format +msgid "dropping %s %s\n" +msgstr "משחרר %s %s\n" + +#: pg_backup_archiver.c:595 +#, c-format +msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×”×™×›×Ÿ להוסיף ×× IF EXISTS במשפט \"%s\"\n" + +#: pg_backup_archiver.c:671 +#, c-format +msgid "setting owner and privileges for %s \"%s.%s\"\n" +msgstr "הגדרת ×”×‘×¢×œ×™× ×•×”×¨×©×ות עבור %s \"%s.%s\"\n" + +#: pg_backup_archiver.c:674 +#, c-format +msgid "setting owner and privileges for %s \"%s\"\n" +msgstr "הגדרת ×”×‘×¢×œ×™× ×•×”×¨×©×ות עבור %s \"%s\"\n" + +#: pg_backup_archiver.c:740 pg_backup_archiver.c:742 +#, c-format +msgid "warning from original dump file: %s\n" +msgstr "×זהרה מקובץ dump המקורי: %s\n" + +#: pg_backup_archiver.c:751 +#, c-format +msgid "creating %s \"%s.%s\"\n" +msgstr "יצירת %s \"%s.%s\"\n" + +#: pg_backup_archiver.c:754 +#, c-format +msgid "creating %s \"%s\"\n" +msgstr "יצירת %s \"%s\"\n" + +#: pg_backup_archiver.c:806 +#, c-format +msgid "connecting to new database \"%s\"\n" +msgstr "התחברות למסד × ×ª×•× ×™× ×—×“×© \"%s\"\n" + +#: pg_backup_archiver.c:834 +#, c-format +msgid "processing %s\n" +msgstr "עיבוד %s\n" + +#: pg_backup_archiver.c:854 +#, c-format +msgid "processing data for table \"%s.%s\"\n" +msgstr "עיבוד × ×ª×•× ×™× ×¢×‘×•×¨ טבלה \"%s.%s\"\n" + +#: pg_backup_archiver.c:916 +#, c-format +msgid "executing %s %s\n" +msgstr "ביצוע %s %s\n" + +#: pg_backup_archiver.c:955 +#, c-format +msgid "disabling triggers for %s\n" +msgstr "נטרול ×˜×¨×™×’×¨×™× ×¢×‘×•×¨ %s\n" + +#: pg_backup_archiver.c:983 +#, c-format +msgid "enabling triggers for %s\n" +msgstr "הפעלת ×˜×¨×™×’×¨×™× ×¢×‘×•×¨ %s\n" + +#: pg_backup_archiver.c:1013 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n" +msgstr "שגי××” פנימית - ×ין ×פשרות ×œ×§×¨×•× ×œWriteData מחוץ להקשר של שיגרה DataDumper\n" + +#: pg_backup_archiver.c:1211 +#, c-format +msgid "large-object output not supported in chosen format\n" +msgstr "×ין תמיכה בתבנית שבחרת בפלט large-object\n" + +#: pg_backup_archiver.c:1269 +#, c-format +msgid "restored %d large object\n" +msgid_plural "restored %d large objects\n" +msgstr[0] "משוחזר %d ×ובייקט גדול\n" +msgstr[1] "×ž×©×•×—×–×¨×™× %d ××•×‘×™×™×§×˜×™× ×’×“×•×œ×™×\n" + +#: pg_backup_archiver.c:1290 pg_backup_tar.c:737 +#, c-format +msgid "restoring large object with OID %u\n" +msgstr "שחזור ×ובייקט גדול ×¢× OID %u\n" + +#: pg_backup_archiver.c:1302 +#, c-format +msgid "could not create large object %u: %s" +msgstr "×œ× ×”×™×ª×” ×פשרות ליצור ×ובייקט גדול % u: %s" + +#: pg_backup_archiver.c:1307 pg_dump.c:3085 +#, c-format +msgid "could not open large object %u: %s" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת ×ובייקט גדול % u: %s" + +#: pg_backup_archiver.c:1365 +#, c-format +msgid "could not open TOC file \"%s\": %s\n" +msgstr "×œ× × ×™×ª×Ÿ לפתוח קובץ TOC \"%s\": %s\n" + +#: pg_backup_archiver.c:1406 +#, c-format +msgid "WARNING: line ignored: %s\n" +msgstr "×זהרה: התעלמות מהשורה: %s\n" + +#: pg_backup_archiver.c:1413 +#, c-format +msgid "could not find entry for ID %d\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×¨×©×•×ž×” עבור מזהה %d\n" + +#: pg_backup_archiver.c:1434 pg_backup_directory.c:225 +#: pg_backup_directory.c:592 +#, c-format +msgid "could not close TOC file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור קובץ TOC: %s\n" + +#: pg_backup_archiver.c:1543 pg_backup_custom.c:158 pg_backup_directory.c:336 +#: pg_backup_directory.c:578 pg_backup_directory.c:643 +#: pg_backup_directory.c:663 +#, c-format +msgid "could not open output file \"%s\": %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח קובץ פלט \"%s\": %s\n" + +#: pg_backup_archiver.c:1546 pg_backup_custom.c:165 +#, c-format +msgid "could not open output file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ הפלט: %s\n" + +#: pg_backup_archiver.c:1652 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)\n" +msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" +msgstr[0] "נכתב % lu בית של נתוני ×”×ובייקט הגדול (תוצ××” = % lu)\n" +msgstr[1] "נכתבו % lu ×‘×ª×™× ×©×œ נתוני ×”×ובייקט הגדול (תוצ××” = % lu)\n" + +#: pg_backup_archiver.c:1658 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)\n" +msgstr "×œ× ×ž×¦×œ×™×— לכתוב על ×ובייקט גדול (תוצ××”: % lu, צפוי: % lu)\n" + +#: pg_backup_archiver.c:1751 +#, c-format +msgid "Error while INITIALIZING:\n" +msgstr "×ירעה שגי××” בעת מ×תחל:\n" + +#: pg_backup_archiver.c:1756 +#, c-format +msgid "Error while PROCESSING TOC:\n" +msgstr "×ירעה שגי××” בעת עיבוד TOC:\n" + +#: pg_backup_archiver.c:1761 +#, c-format +msgid "Error while FINALIZING:\n" +msgstr "×ירעה שגי××” בעת סיו×:\n" + +#: pg_backup_archiver.c:1766 +#, c-format +msgid "Error from TOC entry %d; %u %u %s %s %s\n" +msgstr "שגי×ת מערך TOC %d; %u %u %s %s %s\n" + +#: pg_backup_archiver.c:1839 +#, c-format +msgid "bad dumpId\n" +msgstr "מזהה dump ×œ× ×—×•×§×™\n" + +#: pg_backup_archiver.c:1860 +#, c-format +msgid "bad table dumpId for TABLE DATA item\n" +msgstr "מזהה dump ×œ× ×—×•×§×™ עבור פריט × ×ª×•× ×™× ×‘×˜×‘×œ×”\n" + +#: pg_backup_archiver.c:1952 +#, c-format +msgid "unexpected data offset flag %d\n" +msgstr "דגל היסט בלתי צפוי %d\n" + +#: pg_backup_archiver.c:1965 +#, c-format +msgid "file offset in dump file is too large\n" +msgstr "היסט הקובץ בקובץ ב dump גדול מדי\n" + +#: pg_backup_archiver.c:2078 +#, c-format +msgid "attempting to ascertain archive format\n" +msgstr "ניסיון לברר תבנית ×רכיון\n" + +#: pg_backup_archiver.c:2104 pg_backup_archiver.c:2114 +#, c-format +msgid "directory name too long: \"%s\"\n" +msgstr "×©× ×”×¡×¤×¨×™×” ×רוך מדי: \"%s\"\n" + +#: pg_backup_archiver.c:2122 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n" +msgstr "תיקייה '%s' ××™× ×” מופיעה ×›×™ ×רכיון תקין (\"toc.dat\" ×ינו ×§×™×™×)\n" + +#: pg_backup_archiver.c:2130 pg_backup_custom.c:177 pg_backup_custom.c:770 +#: pg_backup_directory.c:209 pg_backup_directory.c:394 +#, c-format +msgid "could not open input file \"%s\": %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח קובץ קלט \"%s\": %s\n" + +#: pg_backup_archiver.c:2138 pg_backup_custom.c:184 +#, c-format +msgid "could not open input file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ קלט: %s\n" + +#: pg_backup_archiver.c:2145 +#, c-format +msgid "could not read input file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×§×¨×•× ×ž×ª×•×š קובץ הקלט: %s\n" + +#: pg_backup_archiver.c:2147 +#, c-format +msgid "input file is too short (read %lu, expected 5)\n" +msgstr "קובץ הקלט קצר מדי (×œ×§×¨×•× % lu, מצופה 5)\n" + +#: pg_backup_archiver.c:2232 +#, c-format +msgid "input file appears to be a text format dump. Please use psql.\n" +msgstr "קובץ הקלט נר××” כקובץ בתבנית טקסט. ×× × ×”×©×ª×ž×© psql.\n" + +#: pg_backup_archiver.c:2238 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)\n" +msgstr "קובץ הקלט ×ינו נר××” כקובץ ×רכיון חוקי (קצר מדי?)\n" + +#: pg_backup_archiver.c:2244 +#, c-format +msgid "input file does not appear to be a valid archive\n" +msgstr "קובץ הקלט ×ינו נר××” כקובץ ×רכיון חוקי\n" + +#: pg_backup_archiver.c:2264 +#, c-format +msgid "could not close input file: %s\n" +msgstr "×œ× × ×™×ª×Ÿ לסגור קובץ הקלט: %s\n" + +#: pg_backup_archiver.c:2282 +#, c-format +msgid "allocating AH for %s, format %d\n" +msgstr "הקצ×ת AH עבור %s, תבנית %d\n" + +#: pg_backup_archiver.c:2383 +#, c-format +msgid "unrecognized file format \"%d\"\n" +msgstr "תבנית קובץ ×œ× ×ž×–×•×”×” \"%d\"\n" + +#: pg_backup_archiver.c:2438 pg_backup_archiver.c:4204 +#, c-format +msgid "finished item %d %s %s\n" +msgstr "פריט מוגמר %d %s %s\n" + +#: pg_backup_archiver.c:2442 pg_backup_archiver.c:4217 +#, c-format +msgid "worker process failed: exit code %d\n" +msgstr "תהליך עובד נכשל: יצי××” קוד %d\n" + +#: pg_backup_archiver.c:2562 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" +msgstr "מזהה כניסה% d מחוץ לטווח - ×ולי TOC מושחת\n" + +#: pg_backup_archiver.c:2678 +#, c-format +msgid "read TOC entry %d (ID %d) for %s %s\n" +msgstr "×§×¨×•× ×¢×¨×š מתוך TOC %d (מזהה %d) עבור %s %s\n" + +#: pg_backup_archiver.c:2712 +#, c-format +msgid "unrecognized encoding \"%s\"\n" +msgstr "קידוד ×œ× ×ž×–×•×”×” \"%s\"\n" + +#: pg_backup_archiver.c:2717 +#, c-format +msgid "invalid ENCODING item: %s\n" +msgstr "פריט ENCODING ×œ× ×—×•×§×™×ª: %s\n" + +#: pg_backup_archiver.c:2735 +#, c-format +msgid "invalid STDSTRINGS item: %s\n" +msgstr "פריט STDSTRINGS ×œ× ×—×•×§×™×ª: %s\n" + +#: pg_backup_archiver.c:2750 +#, c-format +msgid "schema \"%s\" not found\n" +msgstr "סכימת \"%s\" ×œ× × ×ž×¦××”\n" + +#: pg_backup_archiver.c:2757 +#, c-format +msgid "table \"%s\" not found\n" +msgstr "טבלה '%s' ×œ× × ×ž×¦××”\n" + +#: pg_backup_archiver.c:2764 +#, c-format +msgid "index \"%s\" not found\n" +msgstr "×ינדקס \"%s\" ×œ× × ×ž×¦×\n" + +#: pg_backup_archiver.c:2771 +#, c-format +msgid "function \"%s\" not found\n" +msgstr "פונקציית \"%s\" ×œ× × ×ž×¦××”\n" + +#: pg_backup_archiver.c:2778 +#, c-format +msgid "trigger \"%s\" not found\n" +msgstr "טריגר \"%s\" ×œ× × ×ž×¦×\n" + +#: pg_backup_archiver.c:3034 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "×œ× ×”×™×ª×” ×פשרות להגדיר ×ת הפעלת המשתמש \"%s\": %s" + +#: pg_backup_archiver.c:3066 +#, c-format +msgid "could not set default_with_oids: %s" +msgstr "×œ× ×”×™×ª×” ×פשרות להגדיר ×ת default_with_oids: %s" + +#: pg_backup_archiver.c:3211 +#, c-format +msgid "could not set search_path to \"%s\": %s" +msgstr "×œ× ×”×™×ª×” ×פשרות להגדיר ×ת search_path ל \"%s\": %s" + +#: pg_backup_archiver.c:3273 +#, c-format +msgid "could not set default_tablespace to %s: %s" +msgstr "×œ× ×”×™×ª×” ×פשרות להגדיר default_tablespace ל %s: %s" + +#: pg_backup_archiver.c:3362 pg_backup_archiver.c:3559 +#, c-format +msgid "WARNING: don't know how to set owner for object type %s\n" +msgstr "×זהרה: ×œ× ×™×•×“×¢ ×יך להגדיר ×‘×¢×œ×™× ×¢×‘×•×¨ סוג ×”×ובייקט %s\n" + +#: pg_backup_archiver.c:3646 +#, c-format +msgid "did not find magic string in file header\n" +msgstr "×œ× ×ž×¦× ×ž×—×¨×•×–×ª ×”×§×¡× ×‘×›×•×ª×¨×ª הקובץ\n" + +#: pg_backup_archiver.c:3659 +#, c-format +msgid "unsupported version (%d.%d) in file header\n" +msgstr "גירסה ×œ× × ×ª×ž×›×ª (% d.%d) בכותרת הקובץ\n" + +#: pg_backup_archiver.c:3664 +#, c-format +msgid "sanity check on integer size (%lu) failed\n" +msgstr "בדיקת שפיות על גודל מספר ×©×œ× (% lu) נכשלה\n" + +#: pg_backup_archiver.c:3668 +#, c-format +msgid "WARNING: archive was made on a machine with larger integers, some operations might fail\n" +msgstr "×זהרה: ×”×רכיון בוצע על מכונה ×¢× ×ž×¡×¤×¨×™× ×©×œ×ž×™× ×’×“×•×œ×™× ×™×•×ª×¨, פעולות מסוימות עשוי להיכשל\n" + +#: pg_backup_archiver.c:3678 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)\n" +msgstr "תבנית הצפוי (%d) שונה מתבנית הנמצ××” בקובץ (%d)\n" + +#: pg_backup_archiver.c:3694 +#, c-format +msgid "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n" +msgstr "×זהרה: ×רכיון דחוס, ×בל התקנה זו ××™× ×” תומכת דחיסה - ×œ× ×™×”×™×• × ×ª×•× ×™× ×–×ž×™× ×™×\n" + +#: pg_backup_archiver.c:3712 +#, c-format +msgid "WARNING: invalid creation date in header\n" +msgstr "×זהרה: ת×ריך יצירה ×œ× ×—×•×§×™ בכותרת\n" + +#: pg_backup_archiver.c:3787 +#, c-format +msgid "entering restore_toc_entries_prefork\n" +msgstr "כניסה ל restore_toc_entries_prefork\n" + +#: pg_backup_archiver.c:3831 +#, c-format +msgid "processing item %d %s %s\n" +msgstr "עיבוד פריט %d %s %s\n" + +#: pg_backup_archiver.c:3881 +#, c-format +msgid "entering restore_toc_entries_parallel\n" +msgstr "כניסה ל restore_toc_entries_parallel\n" + +#: pg_backup_archiver.c:3929 +#, c-format +msgid "entering main parallel loop\n" +msgstr "הכניסה ללול××” מקבילה ר×שית \n" + +#: pg_backup_archiver.c:3940 +#, c-format +msgid "skipping item %d %s %s\n" +msgstr "דילוג על פריט %d %s %s\n" + +#: pg_backup_archiver.c:3950 +#, c-format +msgid "launching item %d %s %s\n" +msgstr "השקת פריט %d %s %s\n" + +#: pg_backup_archiver.c:3981 +#, c-format +msgid "finished main parallel loop\n" +msgstr "×¡×™×•× ×œ×•×œ××” מקבילה ר×שית\n" + +#: pg_backup_archiver.c:3990 +#, c-format +msgid "entering restore_toc_entries_postfork\n" +msgstr "כניסה ל restore_toc_entries_postfork\n" + +#: pg_backup_archiver.c:4009 +#, c-format +msgid "processing missed item %d %s %s\n" +msgstr "עיבוד פריט שפוספס %d %s %s\n" + +#: pg_backup_archiver.c:4160 +#, c-format +msgid "no item ready\n" +msgstr "×ין פריט מוכן\n" + +#: pg_backup_archiver.c:4379 +#, c-format +msgid "transferring dependency %d -> %d to %d\n" +msgstr "העברת תלות %d-> %d עד %d\n" + +#: pg_backup_archiver.c:4452 +#, c-format +msgid "reducing dependencies for %d\n" +msgstr "×¦×ž×¦×•× ×™×—×¡×™ התלות עבור %d\n" + +#: pg_backup_archiver.c:4491 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ליצור טבלה '%s', ×”× ×ª×•× ×™× ×©×œ×” ×œ× ×™×©×•×—×–×¨×•\n" + +#. translator: this is a module name +#: pg_backup_custom.c:93 +msgid "custom archiver" +msgstr "×רכיבר מות×× ×ישית" + +#: pg_backup_custom.c:380 pg_backup_null.c:150 +#, c-format +msgid "invalid OID for large object\n" +msgstr "מזהה ×”×ובייקט OID ×œ× ×—×•×§×™ עבור ×ובייקט גדול\n" + +#: pg_backup_custom.c:451 +#, c-format +msgid "unrecognized data block type (%d) while searching archive\n" +msgstr "סוג בלוק × ×ª×•× ×™× ×œ× ×ž×–×•×”×” (% d) בעת חיפוש ב×רכיון\n" + +#: pg_backup_custom.c:462 +#, c-format +msgid "error during file seek: %s\n" +msgstr "שגי××” בעת חיפוש קובץ: %s\n" + +#: pg_backup_custom.c:472 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive\n" +msgstr "×œ× ×™×›×•×œ ×œ×ž×¦×•× ×ת מזהה הבלוק % d ב×רכיון - ×ולי בשל בקשת שחזור ש××™× ×” מסודרת, ×©×œ× × ×™×ª×Ÿ לטפל בה עקב חוסר קיזוז × ×ª×•× ×™× ×‘×רכיון\n" + +#: pg_backup_custom.c:477 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file\n" +msgstr "×œ× ×™×›×•×œ ×œ×ž×¦×•× ×ת מזהה הבלוק% d ב×רכיון - ×ולי בשל בקשת שחזור ש××™× ×” מסודרת, ×©×œ× × ×™×ª×Ÿ לטפל בה עקב קובץ קלט ש×ינו ניתן לחיפוש בו\n" + +#: pg_backup_custom.c:482 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive\n" +msgstr "×œ× ×™×›×•×œ ×œ×ž×¦×•× ×ת מזהה הבלוק% d ב×רכיון - ×ולי בשל בקשת שחזור ש××™× ×” מסודרת, ×©×œ× × ×™×ª×Ÿ לטפל בה עקב קובץ ×רכיון מושחת\n" + +#: pg_backup_custom.c:489 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d\n" +msgstr "× ×ž×¦× ×ž×–×”×” בלוק ×œ× ×¦×¤×•×™ (%d) בעת קרי×ת ×”× ×ª×•× ×™× - %d הצפוי\n" + +#: pg_backup_custom.c:503 +#, c-format +msgid "unrecognized data block type %d while restoring archive\n" +msgstr "סוג בלוק × ×ª×•× ×™× ×œ× ×ž×–×•×”×” %d תוך שחזור ×”×רכיון\n" + +#: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 +#: pg_backup_tar.c:1090 +#, c-format +msgid "could not determine seek position in archive file: %s\n" +msgstr "×œ× ×™×›×•×œ לקבוע ×ת ×”×ž×™×§×•× ×œ×—×¤×© בקובץ ×”×רכיון: %s\n" + +#: pg_backup_custom.c:723 pg_backup_custom.c:764 +#, c-format +msgid "could not close archive file: %s\n" +msgstr "×œ× ×™×›×•×œ לסגור ×ת קובץ ×”×רכיון: %s\n" + +#: pg_backup_custom.c:746 +#, c-format +msgid "can only reopen input archives\n" +msgstr "יכול רק לפתוח מחדש ×ת ×רכיוני הקלט\n" + +#: pg_backup_custom.c:753 +#, c-format +msgid "parallel restore from standard input is not supported\n" +msgstr "שחזור מקבילי מקלט סטנדרטי ×ינו נתמך\n" + +#: pg_backup_custom.c:755 +#, c-format +msgid "parallel restore from non-seekable file is not supported\n" +msgstr "שחזור מקבילי מקובץ ש×ינו ניתן לחיפוש ×ינו נתמך\n" + +#: pg_backup_custom.c:774 +#, c-format +msgid "could not set seek position in archive file: %s\n" +msgstr "×œ× ×™×›×•×œ לקבוע ×ת ×”×ž×™×§×•× ×œ×—×¤×© בקובץ ×”×רכיון: %s\n" + +#: pg_backup_custom.c:792 +#, c-format +msgid "compressor active\n" +msgstr "מדחס פעיל\n" + +#: pg_backup_custom.c:848 +#, c-format +msgid "WARNING: ftell mismatch with expected position -- ftell used\n" +msgstr "×זהרה: ××™ הת×מה ב ftell ×¢× ×”×ž×™×§×•× ×”×¦×¤×•×™ -- ftell בשימוש\n" + +#. translator: this is a module name +#: pg_backup_db.c:29 +msgid "archiver (db)" +msgstr "×רכיבר (db)" + +#: pg_backup_db.c:45 +#, c-format +msgid "could not get server_version from libpq\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לקבל server_version מ- libpq\n" + +#: pg_backup_db.c:56 pg_dumpall.c:2057 +#, c-format +msgid "server version: %s; %s version: %s\n" +msgstr "גירסת שרת: %s; %s גירסה: %s\n" + +#: pg_backup_db.c:58 pg_dumpall.c:2059 +#, c-format +msgid "aborting because of server version mismatch\n" +msgstr "ביטול עקב ××™-הת×מה של גירסת השרת\n" + +#: pg_backup_db.c:148 +#, c-format +msgid "connecting to database \"%s\" as user \"%s\"\n" +msgstr "התחברות למסד ×”× ×ª×•× ×™× \"%s\" כמשתמש \"%s\"\n" + +#: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 +#: pg_dumpall.c:1880 pg_dumpall.c:1994 +msgid "Password: " +msgstr "סיסמה: " + +#: pg_backup_db.c:187 +#, c-format +msgid "failed to reconnect to database\n" +msgstr "×œ× ×”×¦×œ×™×— להתחבר למסד נתוני×\n" + +#: pg_backup_db.c:192 +#, c-format +msgid "could not reconnect to database: %s" +msgstr "יכולתי להתחבר למסד נתוני×: %s" + +#: pg_backup_db.c:208 +#, c-format +msgid "connection needs password\n" +msgstr "החיבור צריך סיסמה\n" + +#: pg_backup_db.c:259 +#, c-format +msgid "already connected to a database\n" +msgstr "כבר מחובר למסד נתוני×\n" + +#: pg_backup_db.c:298 +#, c-format +msgid "failed to connect to database\n" +msgstr "×œ× ×”×¦×œ×™×— להתחבר ×ל מסד נתוני×\n" + +#: pg_backup_db.c:314 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "חיבור מסד ×”× ×ª×•× ×™× '%s' נכשל: %s" + +#: pg_backup_db.c:382 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:389 +#, c-format +msgid "query failed: %s" +msgstr "ש×ילתה נכשלה: %s" + +#: pg_backup_db.c:391 +#, c-format +msgid "query was: %s\n" +msgstr "" +"ש×ילתה הייתה: %s\n" +"\n" + +#: pg_backup_db.c:433 +#, c-format +msgid "query returned %d row instead of one: %s\n" +msgid_plural "query returned %d rows instead of one: %s\n" +msgstr[0] "הש×ילתה החזירה שורה %d ×‘×ž×§×•× ×חד: %s\n" +msgstr[1] "הש×ילתה החזירה %d שורות ×‘×ž×§×•× ×חד: %s\n" + +#: pg_backup_db.c:469 +#, c-format +msgid "%s: %s Command was: %s\n" +msgstr "תכנית %s: %s הפקודה היתה: %s\n" + +#: pg_backup_db.c:525 pg_backup_db.c:599 pg_backup_db.c:606 +msgid "could not execute query" +msgstr "×œ× ×”×™×ª×” ×פשרות לבצע ש×ילתה" + +#: pg_backup_db.c:578 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "השגי××” שהחזיר PQputCopyData: %s" + +#: pg_backup_db.c:627 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "השגי××” שהחזיר PQputCopyEnd: %s" + +#: pg_backup_db.c:633 +#, c-format +msgid "COPY failed for table \"%s\": %s" +msgstr "נכשל COPY עבור טבלה '%s': %s" + +#: pg_backup_db.c:639 pg_dump.c:1842 +#, c-format +msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" +msgstr "×זהרה: תוצ×ות בלתי צפויות נוספות במהלך COPY של הטבלה \"%s\"\n" + +#: pg_backup_db.c:651 +msgid "could not start database transaction" +msgstr "×œ× ×”×™×ª×” ×פשרות ל×תחל טרנז×קציה" + +#: pg_backup_db.c:659 +msgid "could not commit database transaction" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×¡×™×™× ×˜×¨× ×–×קציה" + +#. translator: this is a module name +#: pg_backup_directory.c:65 +msgid "directory archiver" +msgstr "×רכיבר של ספרייה" + +#: pg_backup_directory.c:157 +#, c-format +msgid "no output directory specified\n" +msgstr "×œ× ×¦×•×™×™× ×” ספריית פלט\n" + +#: pg_backup_directory.c:186 +#, c-format +msgid "could not read directory \"%s\": %s\n" +msgstr "×œ× × ×™×ª×Ÿ ×œ×§×¨×•× ×ž×ª×™×§×™×™×” \"%s\": %s\n" + +#: pg_backup_directory.c:190 +#, c-format +msgid "could not close directory \"%s\": %s\n" +msgstr "×œ× × ×™×ª×Ÿ לסגור ×ת מדריך \"%s\": %s\n" + +#: pg_backup_directory.c:196 +#, c-format +msgid "could not create directory \"%s\": %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ליצור תיקייה \"%s\": %s\n" + +#: pg_backup_directory.c:407 +#, c-format +msgid "could not close data file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור קובץ הנתוני×: %s\n" + +#: pg_backup_directory.c:448 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח קובץ TOC של ×ובייקט גדול \"%s\" עבור קלט: %s\n" + +#: pg_backup_directory.c:459 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" +msgstr "שורה ×œ× ×—×•×§×™×ª בקובץ TOC של ×ובייקט גדול \"%s\": \"%s\"\n" + +#: pg_backup_directory.c:468 +#, c-format +msgid "error reading large object TOC file \"%s\"\n" +msgstr "שגי××” בקרי×ת הקובץ TOC של ×ובייקט גדול \"%s\"\n" + +#: pg_backup_directory.c:472 +#, c-format +msgid "could not close large object TOC file \"%s\": %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור קובץ TOC של ×ובייקט גדול \"%s\": %s\n" + +#: pg_backup_directory.c:686 +#, c-format +msgid "could not write to blobs TOC file\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לכתוב לblobs של קובץ TOC\n" + +#: pg_backup_directory.c:718 +#, c-format +msgid "file name too long: \"%s\"\n" +msgstr "×©× ×§×•×‘×¥ ×רוך מדי: \"%s\"\n" + +#: pg_backup_null.c:75 +#, c-format +msgid "this format cannot be read\n" +msgstr "תבנית זו ×œ× × ×™×ª×Ÿ לקרו×\n" + +#. translator: this is a module name +#: pg_backup_tar.c:103 +msgid "tar archiver" +msgstr "×רכיבר tar" + +#: pg_backup_tar.c:181 +#, c-format +msgid "could not open TOC file \"%s\" for output: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ TOC \"%s\" עבור פלט: %s\n" + +#: pg_backup_tar.c:189 +#, c-format +msgid "could not open TOC file for output: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ TOC עבור פלט: %s\n" + +#: pg_backup_tar.c:210 pg_backup_tar.c:366 +#, c-format +msgid "compression is not supported by tar archive format\n" +msgstr "דחיסה ××™× ×” נתמכת על-ידי ×רכיון מפורמט tar\n" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file \"%s\" for input: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח קובץ TOC \"%s\" עבור קלט: %s\n" + +#: pg_backup_tar.c:225 +#, c-format +msgid "could not open TOC file for input: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ TOC עבור קלט: %s\n" + +#: pg_backup_tar.c:352 +#, c-format +msgid "could not find file \"%s\" in archive\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×§×•×‘×¥ \"%s\" ב×רכיון\n" + +#: pg_backup_tar.c:418 +#, c-format +msgid "could not generate temporary file name: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות להפיק ×©× ×”×§×•×‘×¥ הזמני: %s\n" + +#: pg_backup_tar.c:429 +#, c-format +msgid "could not open temporary file\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לפתוח ×ת הקובץ הזמני\n" + +#: pg_backup_tar.c:456 +#, c-format +msgid "could not close tar member\n" +msgstr "×œ× ×™×›×•×œ לסגור חבר בקובץ tar\n" + +#: pg_backup_tar.c:569 +#, c-format +msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" +msgstr "שגי××” פנימית - ×œ× ×¦×•×™×™× ×• ×œ× th ×•×œ× fh ב- tarReadRaw()\n" + +#: pg_backup_tar.c:692 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"\n" +msgstr "תחביר משפט COPY בלתי צפוי: \"%s\"\n" + +#: pg_backup_tar.c:962 +#, c-format +msgid "invalid OID for large object (%u)\n" +msgstr "מזהה ×”×ובייקט OID ×œ× ×—×•×§×™ עבור ×ובייקט גדול (%u)\n" + +#: pg_backup_tar.c:1106 +#, c-format +msgid "could not close temporary file: %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לסגור קובץ זמני: %s\n" + +#: pg_backup_tar.c:1116 +#, c-format +msgid "actual file length (%s) does not match expected (%s)\n" +msgstr "×ורך הקובץ בפועל (%s) ×ינו תו×× ×œ×ורך הצפוי (%s)\n" + +#: pg_backup_tar.c:1153 +#, c-format +msgid "moving from position %s to next member at file position %s\n" +msgstr "הזזת ×ž×ž×§×•× %s לחבר ×”×‘× ×‘×ž×™×§×•× ×‘×§×•×‘×¥ %s\n" + +#: pg_backup_tar.c:1164 +#, c-format +msgid "now at file position %s\n" +msgstr "עכשיו ×‘×ž×™×§×•× ×‘×§×•×‘×¥ %s\n" + +#: pg_backup_tar.c:1173 pg_backup_tar.c:1203 +#, c-format +msgid "could not find header for file \"%s\" in tar archive\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×›×•×ª×¨×ª עבור הקובץ \"%s\" ב×רכיון tar\n" + +#: pg_backup_tar.c:1187 +#, c-format +msgid "skipping tar member %s\n" +msgstr "דילוג על חבר בקובץ tar %s\n" + +#: pg_backup_tar.c:1191 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file.\n" +msgstr "שחזור × ×ª×•× ×™× ×שר ×œ× ×‘×¡×“×¨ ×ינו נתמך בתבנית ×רכיון זו: \"%s\" נדרש, ×ך מגיע לפני \"%s\" בקובץ ×”×רכיון.\n" + +#: pg_backup_tar.c:1237 +#, c-format +msgid "incomplete tar header found (%lu byte)\n" +msgid_plural "incomplete tar header found (%lu bytes)\n" +msgstr[0] "כותרת tar ×œ× ×©×œ×ž×” נמצ××” (% lu בית)\n" +msgstr[1] "כותרת tar ×œ× ×©×œ×ž×” נמצ××” (% lu בתי×)\n" + +#: pg_backup_tar.c:1278 +#, c-format +msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +msgstr "ערך TOC %s ב- %s (×ורך %s, checksum של %d)\n" + +#: pg_backup_tar.c:1289 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" +msgstr "כותרת tar מושחתת נמצ××” ב %s (צפוי%d, מחושב%d) ×ž×™×§×•× ×”×§×•×‘×¥ %s\n" + +#: pg_backup_utils.c:54 +#, c-format +msgid "%s: unrecognized section name: \"%s\"\n" +msgstr "תכנית %s: סעיף ×œ× ×ž×–×•×”×” ש×: \"%s\"\n" + +#: pg_backup_utils.c:56 pg_dump.c:546 pg_dump.c:563 pg_dumpall.c:313 +#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 +#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "נסה '%s --help' לקבלת מידע נוסף.\n" + +#: pg_backup_utils.c:118 +#, c-format +msgid "out of on_exit_nicely slots\n" +msgstr "מחוץ לחריצי on_exit_nicely\n" + +#: pg_dump.c:512 +#, c-format +msgid "compression level must be in range 0..9\n" +msgstr "רמת הדחיסה חייבת להיות בטווח 0..9\n" + +#: pg_dump.c:561 pg_dumpall.c:321 pg_restore.c:297 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "תכנית %s: יותר מדי ××¨×’×•×ž× ×˜×™× ×©×œ שורת הפקודה (הר×שון ×”×•× \"%s\")\n" + +#: pg_dump.c:582 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together\n" +msgstr "×פשרויות -s/--schema-only ו -a/--data-only ×œ× ×™×›×•×œ×™× ×œ×©×ž×© ביחד\n" + +#: pg_dump.c:588 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together\n" +msgstr "×פשרויות -c/--clean ו -a/--data-only ×œ× ×™×›×•×œ לשמש ביחד\n" + +#: pg_dump.c:594 +#, c-format +msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +msgstr "×פשרויות --inserts/--column-inserts ו -o/--oids ×œ× ×™×›×•×œ לשמש יחד\n" + +#: pg_dump.c:595 +#, c-format +msgid "(The INSERT command cannot set OIDs.)\n" +msgstr "(לפקודת ההוספה ×ין ×פשרות להגדיר OID).\n" + +#: pg_dump.c:600 +#, c-format +msgid "option --if-exists requires option -c/--clean\n" +msgstr "×פשרות --if-exists מחייבת ×פשרות -c/--clean\n" + +#: pg_dump.c:622 +#, c-format +msgid "WARNING: requested compression not available in this installation -- archive will be uncompressed\n" +msgstr "×זהרה: דחיסה הנדרשת ××™× ×” זמינה בהתקנה זו - ×רכיון ×œ× ×™×™×“×—×¡\n" + +#: pg_dump.c:637 +#, c-format +msgid "invalid number of parallel jobs\n" +msgstr "מספר ×œ× ×—×•×§×™ של משימות במקבילות\n" + +#: pg_dump.c:641 +#, c-format +msgid "parallel backup only supported by the directory format\n" +msgstr "גיבוי במקביל נתמך רק תבנית התיקייה\n" + +#: pg_dump.c:696 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots.\n" +msgstr "" +"תמונות מצב מסונכרנות ×ינן נתמכות בגירסת שרת זו.\n" +"תריץ ×¢× --no-synchronized-snapshots במקו×,\n" +"×× ×תה ×œ× ×¦×¨×™×š לסנכרן תמונות.\n" + +#: pg_dump.c:703 +#, c-format +msgid "Exported snapshots are not supported by this server version.\n" +msgstr "תמונות מצב המיוצ×ות ×ינן נתמכות בגירסת שרת זו.\n" + +#: pg_dump.c:717 +#, c-format +msgid "last built-in OID is %u\n" +msgstr "מזהה OID מובנה ×”×חרון ×”×•× %u\n" + +#: pg_dump.c:726 +#, c-format +msgid "no matching schemas were found\n" +msgstr "×œ× × ×ž×¦×ו סכימות תו×מות\n" + +#: pg_dump.c:740 +#, c-format +msgid "no matching tables were found\n" +msgstr "×œ× × ×ž×¦×ו טבל×ות תו×מות\n" + +#: pg_dump.c:914 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"תכנית %s מרוקן מ×גר כקובץ טקסט ×ו ×œ×¤×•×¨×ž×˜×™× ×חרי×.\n" +"\n" + +#: pg_dump.c:915 pg_dumpall.c:575 pg_restore.c:449 +#, c-format +msgid "Usage:\n" +msgstr "שימוש:\n" + +#: pg_dump.c:916 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [OPTION]... [DBNAME]\n" + +#: pg_dump.c:918 pg_dumpall.c:578 pg_restore.c:452 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"×פשרויות כלליות:\n" + +#: pg_dump.c:919 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr "" +" -f\n" +" --file=FILENAME\n" +"×©× ×§×•×‘×¥ פלט ×ו ספרייה\n" + +#: pg_dump.c:920 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F\n" +" --format=c|d|t|p\n" +"תבנית של קובץ הפלט (מות×מת ×ישית, ספריה, tar, טקסט רגיל (ברירת מחדל))\n" + +#: pg_dump.c:922 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr "" +" -j\n" +" --jobs=NUM\n" +"תשתמש במשימות מקבילות רבות על מנת לבצע dump\n" + +#: pg_dump.c:923 pg_dumpall.c:580 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr "" +" -v\n" +" --verbose\n" +"מבצ מילולי מפורט\n" + +#: pg_dump.c:924 pg_dumpall.c:581 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version להציג מידע על הגירסה, ול×חר מכן לצ×ת\n" + +#: pg_dump.c:925 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr "" +" -Z\n" +" --compress=0-9\n" +"רמת דחיסה עבור ×¤×•×¨×ž×˜×™× ×“×—×•×¡×™×\n" + +#: pg_dump.c:926 pg_dumpall.c:582 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr "" +" --lock-wait-timeout=TIMEOUT\n" +"להיכשל ל×חר המתנה ל TIMEOUT לנעילה של הטבלה\n" + +#: pg_dump.c:927 pg_dumpall.c:604 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" --no-sync\n" +"×œ× ×œ×—×›×•×ª עד ×שר ×”×©×™× ×•×™×™× ×™×™×›×ª×‘×• בבטחה לדיסק\n" + +#: pg_dump.c:928 pg_dumpall.c:583 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help להציג עזרה זו, ול×חר מכן לצ×ת\n" + +#: pg_dump.c:930 pg_dumpall.c:584 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"×פשרויות שליטה בפלט:\n" + +#: pg_dump.c:931 pg_dumpall.c:585 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr "" +" -a\n" +" --data-only\n" +"לבצע dump עבור ×”× ×ª×•× ×™× ×‘×œ×‘×“, ×œ× ×”×¡×›×™×ž×”\n" + +#: pg_dump.c:932 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr "" +" -b\n" +" --blobs\n" +"לכלול ××•×‘×™×™×§×˜×™× ×’×“×•×œ×™× ×‘dump\n" + +#: pg_dump.c:933 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr "" +" -B\n" +" --no-blobs\n" +"×œ× ×œ×›×œ×•×œ ××•×‘×™×™×§×˜×™× ×’×“×•×œ×™× ×‘dump\n" + +#: pg_dump.c:934 pg_restore.c:463 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr "" +" -c\n" +" --clean\n" +"לנקות (למחוק) ××•×‘×™×™×§×˜×™× ×©×œ מסד × ×ª×•× ×™× ×œ×¤× ×™ יצירה מחדש\n" + +#: pg_dump.c:935 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr "" +" -C\n" +" --create \n" +"לכלול פקודות ליצירת מסד × ×ª×•× ×™× ×‘- dump\n" + +#: pg_dump.c:936 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr "" +" -E\n" +" --encoding=ENCODING\n" +"לבצע dump עבור ×”× ×ª×•× ×™× ×‘×§×™×“×•×“ ENCODING\n" + +#: pg_dump.c:937 +#, c-format +msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" +msgstr "" +" -n\n" +" --schema=SCHEMA\n" +"לבצע dump עבור סכימה (ות) שצוינו בלבד\n" + +#: pg_dump.c:938 +#, c-format +msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" +msgstr "" +" -N\n" +" --exclude-schema=SCHEMA\n" +"×œ× ×œ×›×œ×•×œ ב dump סכימה (ות) שצוינו בלבד\n" + +#: pg_dump.c:939 pg_dumpall.c:588 +#, c-format +msgid " -o, --oids include OIDs in dump\n" +msgstr "" +" -o\n" +" --oids\n" +"לכלול Oid ב dump\n" + +#: pg_dump.c:940 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O\n" +" --no-owner\n" +"לדלג על השחזור בעלות ×ובייקט בפורמט טקסט רגיל\n" + +#: pg_dump.c:942 pg_dumpall.c:591 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr "" +" -s\n" +" --schema-only\n" +"לבצע dump עבור סכימה בלבד, ×œ× × ×ª×•× ×™×\n" + +#: pg_dump.c:943 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr "" +" -S\n" +" --superuser=NAME\n" +"×©× ×ž×©×ª×ž×© על להשתמש בתבנית טקסט רגיל\n" + +#: pg_dump.c:944 +#, c-format +msgid " -t, --table=TABLE dump the named table(s) only\n" +msgstr "" +" -t\n" +" --table=TABLE\n" +"לבצע dump עבור טבלה(ות) לפי ×”×©× ×‘×œ×‘×“\n" + +#: pg_dump.c:945 +#, c-format +msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" +msgstr "" +" -T\n" +" --exclude-table=TABLE\n" +"×œ× ×œ×‘×¦×¢ dump עבור טבלה(ות) לפי ×”×©× ×‘×œ×‘×“\n" + +#: pg_dump.c:946 pg_dumpall.c:594 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr "" +" -x\n" +" --no-privileges\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת הרש×ות (מענק/ביטול)\n" + +#: pg_dump.c:947 pg_dumpall.c:595 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr "" +" --binary-upgrade\n" +"לשימוש על-ידי כלי עזר של שדרוג בלבד\n" + +#: pg_dump.c:948 pg_dumpall.c:596 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr "" +" --column-inserts \n" +"לבצע dump עבור ×”× ×ª×•× ×™× ×›×¤×§×•×“×•×ª INSERT ×¢× ×©×ž×•×ª עמודות\n" + +#: pg_dump.c:949 pg_dumpall.c:597 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr "" +" --disable-dollar-quoting\n" +"ביטול של ציטוט ×¢\"×™ דולר, שימוש במצטט סטנדרטי של SQL \n" + +#: pg_dump.c:950 pg_dumpall.c:598 pg_restore.c:480 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr "" +" --disable-triggers\n" +"לנטרל ×˜×¨×™×’×¨×™× ×‘×ž×”×œ×š שחזור של × ×ª×•× ×™× ×‘×œ×‘×“\n" + +#: pg_dump.c:951 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security\n" +"ל×פשר ×בטחה שורה (לבצע dump עבור רק התוכן שלמשתמש יש גישה)\n" + +#: pg_dump.c:953 +#, c-format +msgid " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" +msgstr "" +" --exclude-table-data=TABLE\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת טבלה (ות) שצוינה (ות)\n" + +#: pg_dump.c:954 pg_dumpall.c:599 pg_restore.c:482 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr "" +" --if-exists\n" +"שימוש ב IF EXISTS בעת הטלת ×”×ובייקטי×\n" + +#: pg_dump.c:955 pg_dumpall.c:600 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr "" +" --inserts\n" +"לבצע dump עבור ×”× ×ª×•× ×™× ×œ×¤×™ פקודות INSERT ×•×œ× COPY\n" + +#: pg_dump.c:956 pg_dumpall.c:601 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr "" +" --no-publications\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת הפרסומי×\n" + +#: pg_dump.c:957 pg_dumpall.c:602 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr "" +" --no-security-labels\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת הקצ×ות תווית ×בטחה\n" + +#: pg_dump.c:958 pg_dumpall.c:603 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr "" +" --no-subscriptions\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת מנויי×\n" + +#: pg_dump.c:959 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr "" +" --no-synchronized-snapshots\n" +"×ל תשתמש בתמונות מצב מסונכרנות במשימות מקבילות\n" + +#: pg_dump.c:960 pg_dumpall.c:605 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr "" +" --no-tablespaces\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת הקצ×ות מרחב טבל×ות\n" + +#: pg_dump.c:961 pg_dumpall.c:606 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr "" +" --no-unlogged-table-data\n" +"×œ× ×œ×›×œ×•×œ בdump ×ת נתוני הטבלה ×שר ×œ× × ×¨×©×ž×• ביומן\n" + +#: pg_dump.c:962 pg_dumpall.c:608 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr "" +" --quote-all-identifiers\n" +"לצטט כל מזהי×, ×פילו ×× ×œ× ×ž×™×œ×•×ª מפתח\n" + +#: pg_dump.c:963 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr "" +" --section=SECTION\n" +"לבצע dump עבור מקטע שצוינה ×‘×©× (pre-data, data ×ו post-data)\n" + +#: pg_dump.c:964 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr "" +" --serializable-deferrable\n" +"לחכות עד dump יכול לרוץ בלי חריגות\n" + +#: pg_dump.c:965 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr "" +" --snapshot=SNAPSHOT\n" +"להשתמש בתמונת מצב נתונה עבור ×”-dump\n" + +#: pg_dump.c:966 pg_restore.c:490 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names\n" +"לדרוש טבלה ו/×ו סכימה לכלול ×“×¤×•×¡×™× ×¢×œ מנת להת××™× ×œ×¢×¨×š ×חד לפחות כל ×חד\n" + +#: pg_dump.c:968 pg_dumpall.c:609 pg_restore.c:492 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +"להשתמש בפקודות SET SESSION AUTHORIZATION במקו×\n" +"הפקודות ALTER OWNER להגדרת הבעלות\n" + +#: pg_dump.c:972 pg_dumpall.c:613 pg_restore.c:496 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"×פשרויות חיבור:\n" + +#: pg_dump.c:973 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr "" +" -d\n" +" --dbname=DBNAME\n" +"מסד × ×ª×•× ×™× ×œ×‘×¦×¢ עליו dump\n" + +#: pg_dump.c:974 pg_dumpall.c:615 pg_restore.c:497 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME שרת מ×רח של מסד ×”× ×ª×•× ×™× ×ו ספריית שקע\n" + +#: pg_dump.c:975 pg_dumpall.c:617 pg_restore.c:498 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr "" +" -p\n" +" --port=PORT\n" +"פורט שרת מסד נתוני×\n" + +#: pg_dump.c:976 pg_dumpall.c:618 pg_restore.c:499 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr "" +" -U\n" +" --username=NAME\n" +"להתחבר כמשתמש מסד ×”× ×ª×•× ×™× ×”×ž×¦×•×™×Ÿ\n" + +#: pg_dump.c:977 pg_dumpall.c:619 pg_restore.c:500 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password ×œ×¢×•×œ× ×œ× ×œ×‘×§×© סיסמה\n" + +#: pg_dump.c:978 pg_dumpall.c:620 pg_restore.c:501 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W, --password נדרשת בקשת סיסמה (צריך לקרות ב×ופן ×וטומטי)\n" + +#: pg_dump.c:979 pg_dumpall.c:621 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr "" +" --role=ROLENAME\n" +"לעשות SET ROLE לפני ×”-dump\n" + +#: pg_dump.c:981 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"×× ×œ× ×¡×•×¤×§ ×©× ×©×œ מסד הנתוני×, ××– הערך משתנה הסביבה PGDATABASE.\n" +"×™×”×™×” בשימוש\n" +"\n" +"\n" + +#: pg_dump.c:983 pg_dumpall.c:625 pg_restore.c:508 +#, c-format +msgid "Report bugs to .\n" +msgstr "לדווח על ב××’×™× ×œ \n" + +#: pg_dump.c:1000 +#, c-format +msgid "invalid client encoding \"%s\" specified\n" +msgstr "צוין קידוד לקוח ×œ× ×—×•×§×™ \"% s\"\n" + +#: pg_dump.c:1137 +#, c-format +msgid "" +"Synchronized snapshots are not supported on standby servers.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots.\n" +msgstr "" +"תמונות מצב מסונכרנות ××™× × × ×ª×ž×›×•×ª ×‘×©×¨×ª×™× ×‘×”×ž×ª× ×”.\n" +"תריץ ×¢× --no-synchronized-snapshots במקו×,\n" +"×× ×תה ×œ× ×¦×¨×™×š לסנכרן תמונות מצב.\n" + +#: pg_dump.c:1206 +#, c-format +msgid "invalid output format \"%s\" specified\n" +msgstr "תבנית הפלט ×œ× ×—×•×§×™ \"%s\" צויינה\n" + +#: pg_dump.c:1244 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"\n" +msgstr "×œ× × ×ž×¦×ו סכימות תו×מות עבור תבנית '%s'\n" + +#: pg_dump.c:1298 +#, c-format +msgid "no matching tables were found for pattern \"%s\"\n" +msgstr "×œ× × ×ž×¦×ו טבל×ות תו×מות עבור תבנית '%s'\n" + +#: pg_dump.c:1702 +#, c-format +msgid "dumping contents of table \"%s.%s\"\n" +msgstr "העברת התוכן של הטבלה \"%s.%s\"\n" + +#: pg_dump.c:1823 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" +msgstr "העברת התוכן של הטבלה \"%s\" נכשלה: PQgetCopyData() נכשל.\n" + +#: pg_dump.c:1824 pg_dump.c:1834 +#, c-format +msgid "Error message from server: %s" +msgstr "הודעת שגי××” משרת: %s" + +#: pg_dump.c:1825 pg_dump.c:1835 +#, c-format +msgid "The command was: %s\n" +msgstr "הפקודה היתה: %s\n" + +#: pg_dump.c:1833 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" +msgstr "העברת התוכן של הטבלה \"%s\" נכשלה: PQgetResult() נכשל.\n" + +#: pg_dump.c:2482 +#, c-format +msgid "saving database definition\n" +msgstr "שמירת הגדרת מסד הנתוני×\n" + +#: pg_dump.c:2788 +#, c-format +msgid "saving encoding = %s\n" +msgstr "שמירת קידוד = %s\n" + +#: pg_dump.c:2815 +#, c-format +msgid "saving standard_conforming_strings = %s\n" +msgstr "שמירת standard_conforming_strings = %s\n" + +#: pg_dump.c:2855 +#, c-format +msgid "reading large objects\n" +msgstr "קרי××” ××•×‘×™×™×§×˜×™× ×’×“×•×œ×™×\n" + +#: pg_dump.c:3050 +#, c-format +msgid "saving large objects\n" +msgstr "שמירת ××•×‘×™×™×§×˜×™× ×’×“×•×œ×™×\n" + +#: pg_dump.c:3095 +#, c-format +msgid "error reading large object %u: %s" +msgstr "שגי××” בעת קרי×ת ×ובייקט גדול % u: %s" + +#: pg_dump.c:3148 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"\n" +msgstr "×בטחת שורה בקרי××” זמינה עבור טבלה \"%s.%s\"\n" + +#: pg_dump.c:3180 +#, c-format +msgid "reading policies for table \"%s.%s\"\n" +msgstr "קרי××” מדיניות עבור טבלה \"%s.%s\"\n" + +#: pg_dump.c:3330 +#, c-format +msgid "unexpected policy command type: %c\n" +msgstr "סוג מדיניות הפקודה בלתי צפוי: %c\n" + +#: pg_dump.c:3446 +#, c-format +msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ ×¤×¨×¡×•× \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:3576 +#, c-format +msgid "reading publication membership for table \"%s.%s\"\n" +msgstr "קרי××” חברות ×”×¤×¨×¡×•× ×¢×‘×•×¨ טבלה \"%s.%s\"\n" + +#: pg_dump.c:3723 +#, c-format +msgid "WARNING: subscriptions not dumped because current user is not a superuser\n" +msgstr "×זהרה: ×ž× ×•×™×™× ×œ× × ×–×¨×§×• ×›×™ משתמש נוכחי ×ינו משתמש על\n" + +#: pg_dump.c:3774 +#, c-format +msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ ×¤×¨×¡×•× \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:3818 +#, c-format +msgid "WARNING: could not parse subpublications array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך subpublications\n" + +#: pg_dump.c:4048 +#, c-format +msgid "could not find parent extension for %s\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×¡×™×•×ž×ª ×”×ב עבור %s\n" + +#: pg_dump.c:4197 +#, c-format +msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ הסכימה \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:4220 +#, c-format +msgid "schema with OID %u does not exist\n" +msgstr "הסכימה ×¢× OID %u ×œ× ×§×™×™×ž×ª\n" + +#: pg_dump.c:4551 +#, c-format +msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ סוג ×”× ×ª×•× ×™× '%s' נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:4639 +#, c-format +msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ ×ופרטור \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:4953 +#, c-format +msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ מחלקת ×”×ופרטור \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:5040 +#, c-format +msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ המשפחה ×ופרטור \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:5207 +#, c-format +msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ פונקציית צבירה \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:5466 +#, c-format +msgid "WARNING: owner of function \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ הפונקציה \"%s\" נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:6248 +#, c-format +msgid "WARNING: owner of table \"%s\" appears to be invalid\n" +msgstr "×זהרה: ×”×‘×¢×œ×™× ×©×œ טבלה '%s' נר××” ×›×œ× ×—×•×§×™\n" + +#: pg_dump.c:6290 pg_dump.c:16504 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found\n" +msgstr "בדיקת שפיות נכשלה, טבלת ×”×ב בעלת OID %u של רצף ×¢× OID %u ×œ× × ×ž×¦××”\n" + +#: pg_dump.c:6421 +#, c-format +msgid "reading indexes for table \"%s.%s\"\n" +msgstr "קרי××” ××™× ×“×§×¡×™× ×¢×‘×•×¨ טבלה \"%s.%s\"\n" + +#: pg_dump.c:6702 +#, c-format +msgid "reading extended statistics for table \"%s.%s\"\n" +msgstr "קרי××” סטטיסטיקה מורחבת עבור טבלה \"%s.%s\"\n" + +#: pg_dump.c:6785 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"\n" +msgstr "קרי××” ×ילוצי מפתח זר עבור טבלה '%s.%s\"\n" + +#: pg_dump.c:7009 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n" +msgstr "בדיקת שפיות נכשלה, טבלת ×”×ב בעלת OID %u ×¢× ×¢×¨×š pg_rewrite בעל OID %u ×œ× × ×ž×¦××”\n" + +#: pg_dump.c:7093 +#, c-format +msgid "reading triggers for table \"%s.%s\"\n" +msgstr "קרי××” ×˜×¨×™×’×¨×™× ×¢×‘×•×¨ טבלה \"%s.%s\"\n" + +#: pg_dump.c:7231 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n" +msgstr "הש×ילתה יצרה ×©× ×”×˜×‘×œ×” ×שר מוצבע ×¢× ×ž×¦×‘×™×¢ ריק עבור טריגר מפתח זר \"%s\" על הטבלה \"%s\" (OID של הטבלה: %u)\n" + +#: pg_dump.c:7803 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"\n" +msgstr "מצי×ת העמודות ×•×”×¡×•×’×™× ×©×œ הטבלה \"%s.%s\"\n" + +#: pg_dump.c:7968 +#, c-format +msgid "invalid column numbering in table \"%s\"\n" +msgstr "מספור העמודות ×œ× ×—×•×§×™ בטבלה '%s'\n" + +#: pg_dump.c:8004 +#, c-format +msgid "finding default expressions of table \"%s.%s\"\n" +msgstr "מצי×ת ביטוי ברירת המחדל של הטבלה \"%s.%s\"\n" + +#: pg_dump.c:8027 +#, c-format +msgid "invalid adnum value %d for table \"%s\"\n" +msgstr "ערך adnum ×œ× ×—×•×§×™ %d עבור טבלה '%s'\n" + +#: pg_dump.c:8093 +#, c-format +msgid "finding check constraints for table \"%s.%s\"\n" +msgstr "מצי×ת ××™×œ×•×¦×™× ×¢×‘×•×¨ טבלה \"%s.%s\"\n" + +#: pg_dump.c:8142 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d\n" +msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" +msgstr[0] "צפי ל%d בדיקת ××™×œ×•×¦×™× ×¢×‘×•×¨ הטבלה \"%s\" ×ך נמצ×ו %d\n" +msgstr[1] "צפי ל%d בדיקות ××™×œ×•×¦×™× ×¢×‘×•×¨ הטבלה \"%s\" ×ך נמצ×ו %d\n" + +#: pg_dump.c:8146 +#, c-format +msgid "(The system catalogs might be corrupted.)\n" +msgstr "(×”×§×˜×œ×•×’×™× ×©×œ המערכת עלול להיות פגו×.)\n" + +#: pg_dump.c:9704 +#, c-format +msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" +msgstr "×זהרה: typtype של סוג ×”× ×ª×•× ×™× '%s' מופיע ×›×™ ×ינו חוקי\n" + +#: pg_dump.c:11133 +#, c-format +msgid "WARNING: bogus value in proargmodes array\n" +msgstr "×זהרה: ערך מזויף במערך proargmodes\n" + +#: pg_dump.c:11459 +#, c-format +msgid "WARNING: could not parse proallargtypes array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך proallargtypes\n" + +#: pg_dump.c:11475 +#, c-format +msgid "WARNING: could not parse proargmodes array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך proargmodes\n" + +#: pg_dump.c:11489 +#, c-format +msgid "WARNING: could not parse proargnames array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך proargnames\n" + +#: pg_dump.c:11500 +#, c-format +msgid "WARNING: could not parse proconfig array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך proconfig\n" + +#: pg_dump.c:11571 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"\n" +msgstr "ערך provolatile ×œ× ×ž×–×•×”×” עבור פונקציה \"%s\"\n" + +#: pg_dump.c:11615 pg_dump.c:13598 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"\n" +msgstr "ערך proparallel ×œ× ×ž×–×•×”×” עבור פונקציה \"%s\"\n" + +#: pg_dump.c:11723 pg_dump.c:11833 pg_dump.c:11840 +#, c-format +msgid "could not find function definition for function with OID %u\n" +msgstr "×œ× ×”×™×ª×” ×פשרות ×œ×ž×¦×•× ×ת הגדרת הפונקציה עבור הפונקציה ×¢× OID %u\n" + +#: pg_dump.c:11768 +#, c-format +msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" +msgstr "×זהרה: הערך מזויף בשדה pg_cast.castfunc ×ו pg_cast.castmethod\n" + +#: pg_dump.c:11771 +#, c-format +msgid "WARNING: bogus value in pg_cast.castmethod field\n" +msgstr "×זהרה: הערך מזויף בשדה pg_cast.castmethod\n" + +#: pg_dump.c:11861 +#, c-format +msgid "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n" +msgstr "×זהרה: הגדרת צורה מזויפת, לפחות ×חת מ trffromsql ו- trftosql צריך להיות שונה מ×פס\n" + +#: pg_dump.c:11878 +#, c-format +msgid "WARNING: bogus value in pg_transform.trffromsql field\n" +msgstr "×זהרה: הערך מזויף בשדה pg_transform.trffromsql\n" + +#: pg_dump.c:11899 +#, c-format +msgid "WARNING: bogus value in pg_transform.trftosql field\n" +msgstr "×זהרה: הערך מזויף בשדה pg_transform.trftosql\n" + +#: pg_dump.c:12295 +#, c-format +msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" +msgstr "×זהרה: סוג ×œ× ×—×•×§×™ '%c' של שיטת גישה \"%s\"\n" + +#: pg_dump.c:13061 +#, c-format +msgid "unrecognized collation provider: %s\n" +msgstr "ספק ×יסוף מוכר: %s\n" + +#: pg_dump.c:13508 +#, c-format +msgid "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n" +msgstr "×זהרה: פונקציית צבירה %s ×œ× × ×™×ª×Ÿ ×”×™×” לעשות dump כר×וי עבור גירסה זו של מסד הנתוני×; התעלמות\n" + +#: pg_dump.c:14364 +#, c-format +msgid "unrecognized object type in default privileges: %d\n" +msgstr "סוג ×ובייקט ×œ× ×ž×–×•×”×” בהרש×ות ברירת מחדל: %d\n" + +#: pg_dump.c:14382 +#, c-format +msgid "could not parse default ACL list (%s)\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לנתח ×ת רשימת ×”-ACL ברירת המחדל (%s)\n" + +#: pg_dump.c:14453 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לנתח ×ת רשימת ×”-ACL ר×שונית (%s) ×ו רשימת REVOKE ACL (%s) ר×שונית עבור ×ובייקט \"%s\" (%s)\n" + +#: pg_dump.c:14461 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n" +msgstr "×œ× ×”×™×ª×” ×פשרות לנתח ×ת רשימת ×”-ACL ברירת המחדל (%s) ×ו רשימת REVOKE ACL (%s) עבור ×ובייקט \"%s\" (%s)\n" + +#: pg_dump.c:14936 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data\n" +msgstr "ש×ילתה כדי לקבל הגדרה של תצוגת \"%s\" ×œ× ×”×—×–×™×¨×” נתוני×\n" + +#: pg_dump.c:14939 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition\n" +msgstr "ש×ילתה כדי לקבל הגדרה של תצוגה \"%s\" החזירה יותר מ×שר הגדרת ×חת\n" + +#: pg_dump.c:14946 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)\n" +msgstr "ההגדרה של תצוגה \"%s\" נר××” ריק (×ורך ×פס)\n" + +#: pg_dump.c:15175 +#, c-format +msgid "invalid number of parents %d for table \"%s\"\n" +msgstr "מספר ×œ× × ×›×•×Ÿ של ×”×•×¨×™× %d עבור טבלה '%s'\n" + +#: pg_dump.c:15822 +#, c-format +msgid "invalid column number %d for table \"%s\"\n" +msgstr "מספר העמודה ×œ× ×—×•×§×™ %d עבור טבלה '%s'\n" + +#: pg_dump.c:16006 +#, c-format +msgid "missing index for constraint \"%s\"\n" +msgstr "×ינדקס חסר עבור ×”×ילוץ \"%s\"\n" + +#: pg_dump.c:16209 +#, c-format +msgid "unrecognized constraint type: %c\n" +msgstr "סוג ×ילוץ ×œ× ×ž×–×•×”×”: %c\n" + +#: pg_dump.c:16346 pg_dump.c:16572 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)\n" +msgstr[0] "ש××™×œ×ª× ×›×“×™ לקבל × ×ª×•× ×™× ×©×œ רצף \"%s\"החזירה שורה %d (הצפוי 1)\n" +msgstr[1] "ש××™×œ×ª× ×›×“×™ לקבל × ×ª×•× ×™× ×©×œ רצף \"%s\"החזירה שורות %d (הצפוי 1)\n" + +#: pg_dump.c:16670 +#, c-format +msgid "unexpected tgtype value: %d\n" +msgstr "ערך tgtype בלתי צפוי: %d\n" + +#: pg_dump.c:16744 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" +msgstr "×רגומנט מסוג מחרוזת ×œ× ×—×•×§×™ (%s) עבור טריגר \"%s\" בטבלה \"%s\"\n" + +#: pg_dump.c:16965 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n" +msgstr "ש×ילתה כדי לקבל כלל \"%s\" עבור טבלה '%s' נכשלה: חזר מספר שגוי של השורות\n" + +#: pg_dump.c:17360 +#, c-format +msgid "reading dependency data\n" +msgstr "קרי×ת נתוני תלות\n" + +#: pg_dump.c:17825 +#, c-format +msgid "WARNING: could not parse reloptions array\n" +msgstr "×זהרה: ×œ× ×”×™×ª×” ×פשרות לנתח מערך reloptions\n" + +#. translator: this is a module name +#: pg_dump_sort.c:25 +msgid "sorter" +msgstr "ממין" + +#: pg_dump_sort.c:413 +#, c-format +msgid "invalid dumpId %d\n" +msgstr "ערך dumpId ×œ× ×—×•×§×™ %d\n" + +#: pg_dump_sort.c:419 +#, c-format +msgid "invalid dependency %d\n" +msgstr "תלות ×œ× ×—×•×§×™ %d\n" + +#: pg_dump_sort.c:652 +#, c-format +msgid "could not identify dependency loop\n" +msgstr "×œ× ×™×•×›×œ לזהות ×ת לול×ת התלות \n" + +#: pg_dump_sort.c:1175 +#, c-format +msgid "NOTICE: there are circular foreign-key constraints on this table:\n" +msgid_plural "NOTICE: there are circular foreign-key constraints among these tables:\n" +msgstr[0] "×©×™× ×œ×‘: יש ×ילוצי מפתח זר ×ž×¢×’×œ×™×™× ×¢×œ הטבלה ×–×”:\n" +msgstr[1] "×©×™× ×œ×‘: יש ×ילוצי מפתח זר ×ž×¢×’×œ×™×™× ×¢×œ הטבל×ות ×לו:\n" + +#: pg_dump_sort.c:1179 pg_dump_sort.c:1199 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: pg_dump_sort.c:1180 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.\n" +msgstr "×תה ×œ× ×™×•×›×œ לשחזר ×ת dump ×œ×œ× ×©×™×ž×•×© ב --disable-triggers ×ו שחרור ××™×œ×•×¦×™× ×–×ž× ×™.\n" + +#: pg_dump_sort.c:1181 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem.\n" +msgstr "שקול שימוש ב dump ×ž×œ× ×‘×ž×§×•× --data-only בכדי להימנע מבעיה זו.\n" + +#: pg_dump_sort.c:1193 +#, c-format +msgid "WARNING: could not resolve dependency loop among these items:\n" +msgstr "×זהרה: ×œ× ×™×›×•×œ×” לפתור ×ת תלות בלול××” בין ×¤×¨×™×˜×™× ×לה:\n" + +#: pg_dumpall.c:189 +#, c-format +msgid "" +"The program \"pg_dump\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation.\n" +msgstr "" +"התוכנית \"pg_dump\" נדרשת על-ידי %s ×בל ×œ× × ×ž×¦××”\n" +"ב×ותה ספריה כמו \"%s\".\n" +"בדוק ×ת ההתקנה.\n" + +#: pg_dumpall.c:196 +#, c-format +msgid "" +"The program \"pg_dump\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation.\n" +msgstr "" +"התוכנית \"pg_dump\" נמצ××” על ידי \"%s\"\n" +"×בל היתה ×œ× ×ž×’×™×¨×¡×” ×–×”×” כמו %s.\n" +"×•×“× ×”×”×ª×§× ×” שלך.\n" + +#: pg_dumpall.c:331 +#, c-format +msgid "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -g/--globals-only ו -r/--roles-only ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_dumpall.c:340 +#, c-format +msgid "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -g/--globals-only ו -t/--tablespaces-only ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_dumpall.c:349 pg_restore.c:367 +#, c-format +msgid "%s: option --if-exists requires option -c/--clean\n" +msgstr "תכנתי %s: ×פשרות --if-exists מחייבת ×פשרות -c/--clean\n" + +#: pg_dumpall.c:356 +#, c-format +msgid "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -r/--roles-only ו -t/--tablespaces-only ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_dumpall.c:412 pg_dumpall.c:1983 +#, c-format +msgid "%s: could not connect to database \"%s\"\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להתחבר ×ל מסד נתוני×: \"%s\"\n" + +#: pg_dumpall.c:427 +#, c-format +msgid "" +"%s: could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database.\n" +msgstr "" +"תכנתי %s: ×œ× ×”×™×ª×” ×פשרות להתחבר למסדי × ×ª×•× ×™× \"postgres\" ×ו \"template1\"\n" +"× × ×¦×™×™×Ÿ מסד × ×ª×•× ×™× ×—×œ×•×¤×™.\n" + +#: pg_dumpall.c:444 +#, c-format +msgid "%s: could not open the output file \"%s\": %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ הפלט \"%s\": %s\n" + +#: pg_dumpall.c:574 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"תכנתי %s מחלץ ×שכול מסד × ×ª×•× ×™× PostgreSQL לקובץ סקריפט של SQL\n" +"\n" + +#: pg_dumpall.c:576 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [OPTION]...\n" + +#: pg_dumpall.c:579 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr "" +"-f\n" +" --file=FILENAM\n" +"×©× ×§×•×‘×¥ פלט\n" + +#: pg_dumpall.c:586 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr "" +"-c\n" +" --clean\n" +"לנקות (למחוק) מסדי ×”× ×ª×•× ×™× ×œ×¤× ×™ יצירה מחדש\n" + +#: pg_dumpall.c:587 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr "" +" -g\n" +" --globals-only\n" +"לבצע dump עבור ××•×‘×™×™×§×˜×™× ×’×œ×•×‘×œ×™×™×, ×œ× ×¢×‘×•×¨ מסדי נתוני×\n" + +#: pg_dumpall.c:589 pg_restore.c:472 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr "" +"-O\n" +" --no-owner\n" +"לדלג על השחזור בעלות על ×”×ובייקט\n" + +#: pg_dumpall.c:590 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr "" +" -r\n" +" --roles-only\n" +"לבצע dump עבור ×ª×¤×§×™×“×™× ×‘×œ×‘×“, ×œ× ×¢×‘×•×¨ מסדי ×”× ×ª×•× ×™× ×ו מרחבי טבל×ות\n" + +#: pg_dumpall.c:592 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr "" +" -S\n" +" --superuser=NAME\n" +"×©× ×ž×©×ª×ž×© על להשתמש ב dump\n" + +#: pg_dumpall.c:593 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr "" +" -t\n" +" --tablespaces-only\n" +"לבצי dump עבור מרחבי טבל×ות, ×œ× ×¢×•×‘×¨ מסדי × ×ª×•× ×™× ×ו תפקידי×\n" + +#: pg_dumpall.c:607 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr "" +" --no-role-passwords\n" +"×œ× ×œ×‘×¦×¢ dump עבור הסיסמ×ות של תפקידי×\n" + +#: pg_dumpall.c:614 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr "" +" -d\n" +" --dbname=CONNSTR\n" +"להתחבר ב×מצעות מחרוזת החיבור\n" + +#: pg_dumpall.c:616 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr "" +" -l\n" +" --database=DBNAME\n" +"מסד × ×ª×•× ×™× ×‘×¨×™×¨×ª המחדל החלופי\n" + +#: pg_dumpall.c:623 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"×× ×œ× × ×¢×©×” שימוש ב -f/--file, ××– סקריפט של SQL ייכתב\n" +"לפלט סטנדרטי.\n" +"\n" +"\n" + +#: pg_dumpall.c:828 +#, c-format +msgid "%s: role name starting with \"pg_\" skipped (%s)\n" +msgstr "תכנית %s: דילוג על ×©× ×ª×¤×§×™×“ ×שר מתחיל ×¢× \"pg_\" (%s)\n" + +#: pg_dumpall.c:1208 +#, c-format +msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לנתח ×ת רשימת ACL (%s) עבור מרחב הטבל×ות \"%s\"\n" + +#: pg_dumpall.c:1525 +#, c-format +msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לנתח ×ת רשימת ACL (%s) עבור מסד ×”× ×ª×•× ×™× \"%s\"\n" + +#: pg_dumpall.c:1739 +#, c-format +msgid "%s: dumping database \"%s\"...\n" +msgstr "תכנית %s: ביצוע dump של מסד ×”× ×ª×•× ×™× '%s'...\n" + +#: pg_dumpall.c:1763 +#, c-format +msgid "%s: pg_dump failed on database \"%s\", exiting\n" +msgstr "תכנית %s: נכשל pg_dump על מסד ×”× ×ª×•× ×™× '%s', יוצ×\n" + +#: pg_dumpall.c:1772 +#, c-format +msgid "%s: could not re-open the output file \"%s\": %s\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לפתוח ×ת קובץ הפלט \"%s\": %s\n" + +#: pg_dumpall.c:1817 +#, c-format +msgid "%s: running \"%s\"\n" +msgstr "תכנית %s: הפעלת \"%s\"\n" + +#: pg_dumpall.c:2006 +#, c-format +msgid "%s: could not connect to database \"%s\": %s\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ להתחבר ×ל מסד נתוני×\"%s\": %s\n" + +#: pg_dumpall.c:2036 +#, c-format +msgid "%s: could not get server version\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לקבל גירסת שרת\n" + +#: pg_dumpall.c:2042 +#, c-format +msgid "%s: could not parse server version \"%s\"\n" +msgstr "תכנית %s: ×œ× ×”×™×ª×” ×פשרות לנתח גירסת שרת \"%s\"\n" + +#: pg_dumpall.c:2118 pg_dumpall.c:2144 +#, c-format +msgid "%s: executing %s\n" +msgstr "תכנית %s: ביצוע %s\n" + +#: pg_dumpall.c:2124 pg_dumpall.c:2150 +#, c-format +msgid "%s: query failed: %s" +msgstr "תכנית %s: ש×ילתה נכשלה: %s" + +#: pg_dumpall.c:2126 pg_dumpall.c:2152 +#, c-format +msgid "%s: query was: %s\n" +msgstr "תכנית %s: ש×ילתה היתה: %s\n" + +#: pg_restore.c:309 +#, c-format +msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -d/--dbname ו -f/--file ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_restore.c:320 +#, c-format +msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -s/--schema-only ו -a/--data-only ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_restore.c:327 +#, c-format +msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +msgstr "תכנית %s: ×פשרויות -c/--clean ו -a/--data-only ×œ× × ×™×ª×Ÿ לשמש ביחד\n" + +#: pg_restore.c:334 +#, c-format +msgid "%s: invalid number of parallel jobs\n" +msgstr "תכנית %s: מספר ×œ× ×—×•×§×™ של משימות מקבילות\n" + +#: pg_restore.c:342 +#, c-format +msgid "%s: maximum number of parallel jobs is %d\n" +msgstr "תכנית %s: מספר מרבי של משרות מקבילות ×”×•× %d\n" + +#: pg_restore.c:351 +#, c-format +msgid "%s: cannot specify both --single-transaction and multiple jobs\n" +msgstr "תכנית %s: ×œ× × ×™×ª×Ÿ לציין ×’× --single-transaction ×•×’× ×ž×©×™×ž×•×ª מרובות\n" + +#: pg_restore.c:394 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" +msgstr "תבנית ×רכיון ×œ× ×ž×–×•×”×” \"%s\"; × × ×¦×™×™×Ÿ \"c\", \"d\" ×ו \"t\"\n" + +#: pg_restore.c:434 +#, c-format +msgid "WARNING: errors ignored on restore: %d\n" +msgstr "×זהרה: התעלמות משגי×ות בשחזור: %d\n" + +#: pg_restore.c:448 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"תכנית %s משחזרת ×ת מסד ×”× ×ª×•× ×™× PostgreSQL מה×רכיון שנוצרו על-ידי pg_dump.\n" +"\n" + +#: pg_restore.c:450 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [OPTION]... [FILE]\n" + +#: pg_restore.c:453 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr "" +" -d\n" +" --dbname=NAME\n" +"×©× ×œ×”×ª×—×‘×¨ ×©× ×ž×¡×“ הנתוני×\n" + +#: pg_restore.c:454 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr "" +" -f\n" +" --file=FILENAM\n" +"×©× ×§×•×‘×¥ פלט\n" + +#: pg_restore.c:455 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr "" +" -F\n" +" --format=c|d|t\n" +"תבנית קובץ גיבוי (צריך להיות ×וטומטי)\n" + +#: pg_restore.c:456 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr "" +" -l\n" +" --list\n" +"הדפס ×¡×™×›×•× TOC של ×”×רכיון\n" + +#: pg_restore.c:457 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr "" +" -v\n" +" --verbose\n" +"מבצ מילולי מפורט\n" + +#: pg_restore.c:458 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version להציג מידע על הגירסה, ול×חר מכן לצ×ת\n" + +#: pg_restore.c:459 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help להציג עזרה זו, ול×חר מכן לצ×ת\n" + +#: pg_restore.c:461 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"×פשרויות שליטה בשחזור:\n" + +#: pg_restore.c:462 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr "" +" -a\n" +" --data-only\n" +"שחזור × ×ª×•× ×™× ×‘×œ×‘×“, ×œ× ×”×¡×›×™×ž×”\n" + +#: pg_restore.c:464 +#, c-format +msgid " -C, --create create the target database\n" +msgstr "" +" -C\n" +" --create \n" +"ליצור ×ת מסד ×”× ×ª×•× ×™× ×”×™×¢×“\n" +"\n" + +#: pg_restore.c:465 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr "" +" -e\n" +" --exit-on-error\n" +"יצי××” cשגי××”, ברירת המחדל ×”×™× ×œ×”×ž×©×™×š\n" + +#: pg_restore.c:466 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr "" +" -I\n" +" --index=NAME\n" +"שחזור ×ינדקס ×שר צוין ב NAME\n" + +#: pg_restore.c:467 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr "" +"-j\n" +" --jobs=NUM\n" +"תשתמש במשימות מקבילות רבות לשיחזור\n" + +#: pg_restore.c:468 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L\n" +" --use-list=FILENAME\n" +"להשתמש בתוכן ×¢× ×™×™× ×™× ×ž×§×•×‘×¦×™× ×–×” על מנת לבחור/לבדר ×ת הפלט\n" + +#: pg_restore.c:470 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr "" +" -n\n" +" --schema=NAME\n" +"לשחזר רק ××•×‘×™×™×§×˜×™× ×ž×¡×›×™×ž×” זו\n" + +#: pg_restore.c:471 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr "" +" -N\n" +" --exclude-schema=NAME\n" +"×œ× ×œ×©×—×–×¨ ×ת ×”××•×‘×™×™×§×˜×™× ×ž×¡×›×™×ž×” זו\n" + +#: pg_restore.c:473 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr "" +" -P\n" +" --function=NAME(args)\n" +"שחזורפונקציה שצוינה\n" + +#: pg_restore.c:474 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr "" +" -s\n" +" --schema-only\n" +"שחזור של הסכימה בלבד, ×œ× × ×ª×•× ×™×\n" + +#: pg_restore.c:475 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr "" +" -S\n" +" --superuser=NAME\n" +"×©× ×ž×©×ª×ž×© על עבור נטרול טריגרי×\n" + +#: pg_restore.c:476 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr "" +" -t\n" +" --table=NAME\n" +"שחזור ×©× ×”×§×©×¨ (טבלה, תצוגה, וכו '.)\n" + +#: pg_restore.c:477 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr "" +" -T\n" +" --trigger=NAME\n" +"שחזור טריגר שצוין\n" + +#: pg_restore.c:478 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr "" +" -x\n" +" --no-privileges\n" +"דלג על שחזור הרש×ות גישה (מענק / שלילה)\n" + +#: pg_restore.c:479 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr "" +" -1, --single-transaction\n" +"שחזור כטרנזקציה יחידה\n" + +#: pg_restore.c:481 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr "" +" --enable-row-security\n" +"ל×פשר ×בטחה שורה\n" + +#: pg_restore.c:483 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables\n" +"×œ× ×œ×©×—×–×¨ × ×ª×•× ×™× ×©×œ טבל×ות ×©×œ× ×”×™×ª×” ×שפרות ×œ×™×¦×•× ×ותן\n" + +#: pg_restore.c:485 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr "" +"--no-publications\n" +"×œ× ×œ×©×—×–×¨ ×ת הפרסומי×\n" + +#: pg_restore.c:486 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr "" +" --no-security-labels\n" +"×œ× ×œ×©×—×–×¨ ×ת תווית ×בטחה\n" + +#: pg_restore.c:487 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr "" +"--no-subscriptions\n" +"×œ× ×œ×©×—×–×¨ ×ת מנויי×\n" + +#: pg_restore.c:488 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr "" +"--no-tablespaces\n" +"×œ× ×œ×©×—×–×¨ ×ת הקצ×ות מרחב טבל×ות\n" + +#: pg_restore.c:489 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr "" +"--section=SECTION\n" +"לבצע שחזור עבור מקטע שצוין ×‘×©× (pre-data, data ×ו post-data)\n" + +#: pg_restore.c:502 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr "" +" --role=ROLENAME \n" +"להגדיר תפקיד לפני השחזור\n" + +#: pg_restore.c:504 +#, c-format +msgid "" +"\n" +"The options -I, -n, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"×פשר לציין ולשלב בין ×”×פשרויות -I, -n, -P, -t, -T ו --section \n" +"כמה ×¤×¢×ž×™× ×¢×œ מנת לבחור ××•×‘×™×™×§×˜×™× ×ž×¨×•×‘×™×.\n" + +#: pg_restore.c:507 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"×× ×œ× ×¦×•×™×™×Ÿ קובץ הקלט, ×™×”×™×” שימוש בקלט סטנדרטי.\n" +"\n" diff --git a/src/bin/pg_dump/po/it.po b/src/bin/pg_dump/po/it.po index 973446e2fb0..d249431a02d 100644 --- a/src/bin/pg_dump/po/it.po +++ b/src/bin/pg_dump/po/it.po @@ -1,33 +1,28 @@ # -# Translation of pg_dump to Italian -# PostgreSQL Project +# pg_dump.po +# Italian message translation file for pg_dump # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Cosimo D'Arcangelo -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017. +# Cosimo D'Arcangelo , 2010. +# Mirko Tebaldi , 2004. +# Fabrizio Mazzoni , 2003. # -# Traduttori precedenti: -# * Fabrizio Mazzoni , 2003. -# * Mirko Tebaldi , 2004. -# -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" "Project-Id-Version: pg_dump (Postgresql) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:46+0000\n" -"PO-Revision-Date: 2017-05-29 17:23+0100\n" +"POT-Creation-Date: 2017-08-30 21:45+0000\n" +"PO-Revision-Date: 2017-10-23 19:11+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -362,14 +357,14 @@ msgstr "decompressione dei dati fallita: %s\n" msgid "could not close compression library: %s\n" msgstr "chiusura della libreria di compressione fallita: %s\n" -#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:587 -#: pg_backup_tar.c:559 +#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 +#: pg_backup_tar.c:564 pg_backup_tar.c:568 #, c-format msgid "could not read from input file: %s\n" msgstr "lettura dal file di input fallita: %s\n" -#: compress_io.c:635 pg_backup_custom.c:584 pg_backup_directory.c:543 -#: pg_backup_tar.c:795 pg_backup_tar.c:819 +#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 +#: pg_backup_tar.c:807 pg_backup_tar.c:831 #, c-format msgid "could not read from input file: end of file\n" msgstr "lettura dal file di input fallita: fine del file\n" @@ -467,485 +462,475 @@ msgstr "pgpipe: accept della connessione fallito: codice di errore %d\n" msgid "archiver" msgstr "archiviatore" -#: pg_backup_archiver.c:243 pg_backup_archiver.c:1573 +#: pg_backup_archiver.c:249 pg_backup_archiver.c:1599 #, c-format msgid "could not close output file: %s\n" msgstr "chiusura del file di output fallita: %s\n" -#: pg_backup_archiver.c:289 pg_backup_archiver.c:294 +#: pg_backup_archiver.c:295 pg_backup_archiver.c:300 #, c-format msgid "WARNING: archive items not in correct section order\n" msgstr "ATTENZIONE: gli elementi dell'archivio non sono nell'ordine di sezione giusto\n" -#: pg_backup_archiver.c:300 +#: pg_backup_archiver.c:306 #, c-format msgid "unexpected section code %d\n" msgstr "codice di sezione non prevista %d\n" -#: pg_backup_archiver.c:336 +#: pg_backup_archiver.c:342 #, c-format msgid "-C and -1 are incompatible options\n" msgstr "-C e -1 sono opzioni incompatibili\n" -#: pg_backup_archiver.c:346 +#: pg_backup_archiver.c:352 #, c-format msgid "parallel restore is not supported with this archive file format\n" msgstr "il ripristino parallelo non è supportato con questo formato di archivio\n" -#: pg_backup_archiver.c:350 +#: pg_backup_archiver.c:356 #, c-format msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" msgstr "il ripristino parallelo non è supportato con archivi eseguiti da pg_dump precedenti la versione 8.0\n" -#: pg_backup_archiver.c:368 +#: pg_backup_archiver.c:374 #, c-format msgid "cannot restore from compressed archive (compression not supported in this installation)\n" msgstr "non è possibile ripristinare da archivio compresso (compressione non supportata in questa installazione)\n" -#: pg_backup_archiver.c:385 +#: pg_backup_archiver.c:391 #, c-format msgid "connecting to database for restore\n" msgstr "connessione al database per il ripristino\n" -#: pg_backup_archiver.c:387 +#: pg_backup_archiver.c:393 #, c-format msgid "direct database connections are not supported in pre-1.3 archives\n" msgstr "le connessioni dirette al database non sono supportate negli archivi pre-1.3\n" -#: pg_backup_archiver.c:432 +#: pg_backup_archiver.c:438 #, c-format msgid "implied data-only restore\n" msgstr "ripristino implicito dei soli dati\n" -#: pg_backup_archiver.c:502 +#: pg_backup_archiver.c:508 #, c-format msgid "dropping %s %s\n" msgstr "cancellazione di %s %s\n" -#: pg_backup_archiver.c:595 +#: pg_backup_archiver.c:601 #, c-format msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" msgstr "ATTENZIONE: posizione dove inserire IF EXISTS nell'istruzione \"%s\" non trovata\n" -#: pg_backup_archiver.c:671 -#, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "impostazione di proprietario e permessi per %s \"%s.%s\"\n" - -#: pg_backup_archiver.c:674 -#, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "impostazione di proprietario e permessi per %s \"%s\"\n" - -#: pg_backup_archiver.c:740 pg_backup_archiver.c:742 +#: pg_backup_archiver.c:764 pg_backup_archiver.c:766 #, c-format msgid "warning from original dump file: %s\n" msgstr "avvertimento dal file originale scaricato: %s\n" -#: pg_backup_archiver.c:751 +#: pg_backup_archiver.c:778 #, c-format msgid "creating %s \"%s.%s\"\n" msgstr "creazione %s \"%s.%s\"\n" -#: pg_backup_archiver.c:754 +#: pg_backup_archiver.c:781 #, c-format msgid "creating %s \"%s\"\n" msgstr "creazione di %s \"%s\"\n" -#: pg_backup_archiver.c:806 +#: pg_backup_archiver.c:832 #, c-format msgid "connecting to new database \"%s\"\n" msgstr "connessione al nuovo database \"%s\"\n" -#: pg_backup_archiver.c:834 +#: pg_backup_archiver.c:860 #, c-format msgid "processing %s\n" msgstr "elaborazione di %s\n" -#: pg_backup_archiver.c:854 +#: pg_backup_archiver.c:880 #, c-format msgid "processing data for table \"%s.%s\"\n" msgstr "elaborazione dati per la tabella \"%s.%s\".\n" -#: pg_backup_archiver.c:916 +#: pg_backup_archiver.c:942 #, c-format msgid "executing %s %s\n" msgstr "esecuzione di %s %s\n" -#: pg_backup_archiver.c:955 +#: pg_backup_archiver.c:981 #, c-format msgid "disabling triggers for %s\n" msgstr "disabilitazione trigger per %s\n" -#: pg_backup_archiver.c:983 +#: pg_backup_archiver.c:1009 #, c-format msgid "enabling triggers for %s\n" msgstr "abilitazione trigger per %s\n" -#: pg_backup_archiver.c:1013 +#: pg_backup_archiver.c:1039 #, c-format msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n" msgstr "errore interno -- WriteData non può essere chiamata al di fuori del contesto di una routine DataDumper\n" -#: pg_backup_archiver.c:1211 +#: pg_backup_archiver.c:1237 #, c-format msgid "large-object output not supported in chosen format\n" msgstr "emissione dei large object non supportata nel formato scelto\n" -#: pg_backup_archiver.c:1269 +#: pg_backup_archiver.c:1295 #, c-format msgid "restored %d large object\n" msgid_plural "restored %d large objects\n" msgstr[0] "ripristinato %d large object\n" msgstr[1] "ripristinati %d large object\n" -#: pg_backup_archiver.c:1290 pg_backup_tar.c:737 +#: pg_backup_archiver.c:1316 pg_backup_tar.c:749 #, c-format msgid "restoring large object with OID %u\n" msgstr "ripristino del large object con OID %u\n" -#: pg_backup_archiver.c:1302 +#: pg_backup_archiver.c:1328 #, c-format msgid "could not create large object %u: %s" msgstr "creazione il large object %u fallita: %s" -#: pg_backup_archiver.c:1307 pg_dump.c:3084 +#: pg_backup_archiver.c:1333 pg_dump.c:3084 #, c-format msgid "could not open large object %u: %s" msgstr "apertura del large object %u fallita: %s" -#: pg_backup_archiver.c:1365 +#: pg_backup_archiver.c:1391 #, c-format msgid "could not open TOC file \"%s\": %s\n" msgstr "apertura del file TOC \"%s\" fallita: %s\n" -#: pg_backup_archiver.c:1406 +#: pg_backup_archiver.c:1432 #, c-format msgid "WARNING: line ignored: %s\n" msgstr "ATTENZIONE: la riga è stata ignorata: %s\n" -#: pg_backup_archiver.c:1413 +#: pg_backup_archiver.c:1439 #, c-format msgid "could not find entry for ID %d\n" msgstr "non sono state trovate voci per l'ID %d\n" -#: pg_backup_archiver.c:1434 pg_backup_directory.c:225 -#: pg_backup_directory.c:592 +#: pg_backup_archiver.c:1460 pg_backup_directory.c:225 +#: pg_backup_directory.c:596 #, c-format msgid "could not close TOC file: %s\n" msgstr "chiusura del file TOC fallita: %s\n" -#: pg_backup_archiver.c:1543 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:578 pg_backup_directory.c:643 -#: pg_backup_directory.c:663 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:158 pg_backup_directory.c:336 +#: pg_backup_directory.c:582 pg_backup_directory.c:647 +#: pg_backup_directory.c:667 #, c-format msgid "could not open output file \"%s\": %s\n" msgstr "apertura del file di output \"%s\" fallita: %s\n" -#: pg_backup_archiver.c:1546 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1572 pg_backup_custom.c:165 #, c-format msgid "could not open output file: %s\n" msgstr "apertura del file di output fallita: %s\n" -#: pg_backup_archiver.c:1652 +#: pg_backup_archiver.c:1678 #, c-format msgid "wrote %lu byte of large object data (result = %lu)\n" msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" msgstr[0] "scritto %lu byte di dati large object (risultato = %lu)\n" msgstr[1] "scritti %lu byte di dati large object (risultato = %lu)\n" -#: pg_backup_archiver.c:1658 +#: pg_backup_archiver.c:1684 #, c-format msgid "could not write to large object (result: %lu, expected: %lu)\n" msgstr "scrittura del large object fallita (risultato: %lu, previsto: %lu)\n" -#: pg_backup_archiver.c:1751 +#: pg_backup_archiver.c:1777 #, c-format msgid "Error while INITIALIZING:\n" msgstr "Errore durante INIZIALIZZAZIONE:\n" -#: pg_backup_archiver.c:1756 +#: pg_backup_archiver.c:1782 #, c-format msgid "Error while PROCESSING TOC:\n" msgstr "Errore durante ELABORAZIONE TOC:\n" -#: pg_backup_archiver.c:1761 +#: pg_backup_archiver.c:1787 #, c-format msgid "Error while FINALIZING:\n" msgstr "Errore durante FINALIZZAZIONE:\n" -#: pg_backup_archiver.c:1766 +#: pg_backup_archiver.c:1792 #, c-format msgid "Error from TOC entry %d; %u %u %s %s %s\n" msgstr "Errore nella voce TOC %d; %u %u %s %s %s\n" -#: pg_backup_archiver.c:1839 +#: pg_backup_archiver.c:1865 #, c-format msgid "bad dumpId\n" msgstr "dumpId errato\n" -#: pg_backup_archiver.c:1860 +#: pg_backup_archiver.c:1886 #, c-format msgid "bad table dumpId for TABLE DATA item\n" msgstr "dumpId di tabella errato per elemento TABLE DATA\n" -#: pg_backup_archiver.c:1952 +#: pg_backup_archiver.c:1978 #, c-format msgid "unexpected data offset flag %d\n" msgstr "flag di offset dati non previsto %d\n" -#: pg_backup_archiver.c:1965 +#: pg_backup_archiver.c:1991 #, c-format msgid "file offset in dump file is too large\n" msgstr "l'offset del file scaricato è troppo grande\n" -#: pg_backup_archiver.c:2078 +#: pg_backup_archiver.c:2104 #, c-format msgid "attempting to ascertain archive format\n" msgstr "tentativo di accertamento del formato dell'archivio\n" -#: pg_backup_archiver.c:2104 pg_backup_archiver.c:2114 +#: pg_backup_archiver.c:2130 pg_backup_archiver.c:2140 #, c-format msgid "directory name too long: \"%s\"\n" msgstr "nome della directory troppo lungo: \"%s\"\n" -#: pg_backup_archiver.c:2122 +#: pg_backup_archiver.c:2148 #, c-format msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n" msgstr "la directory \"%s\" non sembra un archivio valido (\"toc.dat\" non esiste)\n" -#: pg_backup_archiver.c:2130 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:394 +#: pg_backup_archiver.c:2156 pg_backup_custom.c:177 pg_backup_custom.c:770 +#: pg_backup_directory.c:209 pg_backup_directory.c:396 #, c-format msgid "could not open input file \"%s\": %s\n" msgstr "apertura del file di input \"%s\" fallita: %s\n" -#: pg_backup_archiver.c:2138 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2164 pg_backup_custom.c:184 #, c-format msgid "could not open input file: %s\n" msgstr "apertura del file di input fallita: %s\n" -#: pg_backup_archiver.c:2145 +#: pg_backup_archiver.c:2171 #, c-format msgid "could not read input file: %s\n" msgstr "lettura del file di input fallita: %s\n" -#: pg_backup_archiver.c:2147 +#: pg_backup_archiver.c:2173 #, c-format msgid "input file is too short (read %lu, expected 5)\n" msgstr "il file di input è troppo corto (letti %lu, previsti 5)\n" -#: pg_backup_archiver.c:2232 +#: pg_backup_archiver.c:2258 #, c-format msgid "input file appears to be a text format dump. Please use psql.\n" msgstr "il file di input sembra un dump in formato testo. Prego usare psql.\n" -#: pg_backup_archiver.c:2238 +#: pg_backup_archiver.c:2264 #, c-format msgid "input file does not appear to be a valid archive (too short?)\n" msgstr "il file di input non sembra essere un archivio valido (è troppo corto?)\n" -#: pg_backup_archiver.c:2244 +#: pg_backup_archiver.c:2270 #, c-format msgid "input file does not appear to be a valid archive\n" msgstr "il file di input non sembra essere un archivio valido\n" -#: pg_backup_archiver.c:2264 +#: pg_backup_archiver.c:2290 #, c-format msgid "could not close input file: %s\n" msgstr "chiusura del file di input fallita: %s\n" -#: pg_backup_archiver.c:2282 +#: pg_backup_archiver.c:2308 #, c-format msgid "allocating AH for %s, format %d\n" msgstr "allocazione AH per %s, formato %d\n" -#: pg_backup_archiver.c:2383 +#: pg_backup_archiver.c:2409 #, c-format msgid "unrecognized file format \"%d\"\n" msgstr "formato di file \"%d\" sconosciuto\n" -#: pg_backup_archiver.c:2438 pg_backup_archiver.c:4204 +#: pg_backup_archiver.c:2464 pg_backup_archiver.c:4308 #, c-format msgid "finished item %d %s %s\n" msgstr "elemento %d %s %s terminato\n" -#: pg_backup_archiver.c:2442 pg_backup_archiver.c:4217 +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4321 #, c-format msgid "worker process failed: exit code %d\n" msgstr "processo worker fallito: codice di uscita %d\n" -#: pg_backup_archiver.c:2562 +#: pg_backup_archiver.c:2588 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" msgstr "la voce ID %d è fuori dall'intervallo consentito -- possibile corruzione della TOC\n" -#: pg_backup_archiver.c:2678 +#: pg_backup_archiver.c:2704 #, c-format msgid "read TOC entry %d (ID %d) for %s %s\n" msgstr "letta voce TOC %d (ID %d) per %s %s\n" -#: pg_backup_archiver.c:2712 +#: pg_backup_archiver.c:2738 #, c-format msgid "unrecognized encoding \"%s\"\n" msgstr "codifica sconosciuta \"%s\"\n" -#: pg_backup_archiver.c:2717 +#: pg_backup_archiver.c:2743 #, c-format msgid "invalid ENCODING item: %s\n" msgstr "elemento ENCODING non valido: %s\n" -#: pg_backup_archiver.c:2735 +#: pg_backup_archiver.c:2761 #, c-format msgid "invalid STDSTRINGS item: %s\n" msgstr "elemento STDSTRINGS non valido: %s\n" -#: pg_backup_archiver.c:2750 +#: pg_backup_archiver.c:2776 #, c-format msgid "schema \"%s\" not found\n" msgstr "schema \"%s\" non trovato\n" -#: pg_backup_archiver.c:2757 +#: pg_backup_archiver.c:2783 #, c-format msgid "table \"%s\" not found\n" msgstr "tabella \"%s\" non trovata\n" -#: pg_backup_archiver.c:2764 +#: pg_backup_archiver.c:2790 #, c-format msgid "index \"%s\" not found\n" msgstr "indice \"%s\" non trovato\n" -#: pg_backup_archiver.c:2771 +#: pg_backup_archiver.c:2797 #, c-format msgid "function \"%s\" not found\n" msgstr "funzione \"%s\" non trovata\n" -#: pg_backup_archiver.c:2778 +#: pg_backup_archiver.c:2804 #, c-format msgid "trigger \"%s\" not found\n" msgstr "trigger \"%s\" non trovato\n" -#: pg_backup_archiver.c:3034 +#: pg_backup_archiver.c:3082 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "impostazione della sessione utente a \"%s\" fallita: %s" -#: pg_backup_archiver.c:3066 +#: pg_backup_archiver.c:3114 #, c-format msgid "could not set default_with_oids: %s" msgstr "impostazione di default_with_oids fallita: %s" -#: pg_backup_archiver.c:3211 +#: pg_backup_archiver.c:3259 #, c-format msgid "could not set search_path to \"%s\": %s" msgstr "impostazione di search_path a \"%s\" fallita: %s" -#: pg_backup_archiver.c:3273 +#: pg_backup_archiver.c:3321 #, c-format msgid "could not set default_tablespace to %s: %s" msgstr "impostazione di default_tablespace a %s fallita: %s" -#: pg_backup_archiver.c:3362 pg_backup_archiver.c:3559 +#: pg_backup_archiver.c:3411 pg_backup_archiver.c:3604 #, c-format -msgid "WARNING: don't know how to set owner for object type %s\n" -msgstr "ATTENZIONE: non si sa come impostare il proprietario per il tipo di oggetto %s\n" +msgid "WARNING: don't know how to set owner for object type \"%s\"\n" +msgstr "ATTENZIONE: non si sa come impostare il proprietario per il tipo di oggetto \"%s\"\n" -#: pg_backup_archiver.c:3646 +#: pg_backup_archiver.c:3694 #, c-format msgid "did not find magic string in file header\n" msgstr "magic string non trovata nell'intestazione del file\n" -#: pg_backup_archiver.c:3659 +#: pg_backup_archiver.c:3707 #, c-format msgid "unsupported version (%d.%d) in file header\n" msgstr "versione (%d.%d) non supportata nell'intestazione del file\n" -#: pg_backup_archiver.c:3664 +#: pg_backup_archiver.c:3712 #, c-format msgid "sanity check on integer size (%lu) failed\n" msgstr "verifica sulla dimensione degli interi (%lu) fallita\n" -#: pg_backup_archiver.c:3668 +#: pg_backup_archiver.c:3716 #, c-format msgid "WARNING: archive was made on a machine with larger integers, some operations might fail\n" msgstr "ATTENZIONE: L'archivio è stato creato su una macchina con interi lunghi, alcune operazioni potrebbero fallire\n" -#: pg_backup_archiver.c:3678 +#: pg_backup_archiver.c:3726 #, c-format msgid "expected format (%d) differs from format found in file (%d)\n" msgstr "il formato previsto (%d) differisce dal formato trovato nel file (%d)\n" -#: pg_backup_archiver.c:3694 +#: pg_backup_archiver.c:3742 #, c-format msgid "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n" msgstr "ATTENZIONE: l'archivio è compresso, ma questa installazione non supporta la compressione -- nessun dato sarà disponibile\n" -#: pg_backup_archiver.c:3712 +#: pg_backup_archiver.c:3760 #, c-format msgid "WARNING: invalid creation date in header\n" msgstr "ATTENZIONE: la data di creazione nell'intestazione non è valida\n" -#: pg_backup_archiver.c:3787 +#: pg_backup_archiver.c:3833 #, c-format msgid "entering restore_toc_entries_prefork\n" msgstr "inizio di restore_toc_entries_prefork\n" -#: pg_backup_archiver.c:3831 +#: pg_backup_archiver.c:3897 #, c-format msgid "processing item %d %s %s\n" msgstr "elaborazione elemento %d %s %s\n" -#: pg_backup_archiver.c:3881 +#: pg_backup_archiver.c:3951 #, c-format msgid "entering restore_toc_entries_parallel\n" msgstr "immissione restore_toc_entries_parallel\n" -#: pg_backup_archiver.c:3929 +#: pg_backup_archiver.c:3972 #, c-format msgid "entering main parallel loop\n" msgstr "inizio del loop principale parallelo\n" -#: pg_backup_archiver.c:3940 +#: pg_backup_archiver.c:3983 #, c-format msgid "skipping item %d %s %s\n" msgstr "saltato l'elemento %d %s %s\n" -#: pg_backup_archiver.c:3950 +#: pg_backup_archiver.c:3993 #, c-format msgid "launching item %d %s %s\n" msgstr "avvio dell'elemento %d %s %s\n" -#: pg_backup_archiver.c:3981 +#: pg_backup_archiver.c:4047 #, c-format msgid "finished main parallel loop\n" msgstr "loop principale parallelo terminato\n" -#: pg_backup_archiver.c:3990 +#: pg_backup_archiver.c:4065 #, c-format msgid "entering restore_toc_entries_postfork\n" msgstr "inizio di restore_toc_entries_postfork\n" -#: pg_backup_archiver.c:4009 +#: pg_backup_archiver.c:4085 #, c-format msgid "processing missed item %d %s %s\n" msgstr "elaborazione dell'elemento perduto %d %s %s\n" -#: pg_backup_archiver.c:4160 +#: pg_backup_archiver.c:4264 #, c-format msgid "no item ready\n" msgstr "nessun elemento pronto\n" -#: pg_backup_archiver.c:4379 +#: pg_backup_archiver.c:4483 #, c-format msgid "transferring dependency %d -> %d to %d\n" msgstr "trasferimento di dipendenza %d -> %d a %d\n" -#: pg_backup_archiver.c:4452 +#: pg_backup_archiver.c:4556 #, c-format msgid "reducing dependencies for %d\n" msgstr "riduzione dipendenze per %d\n" -#: pg_backup_archiver.c:4491 +#: pg_backup_archiver.c:4608 #, c-format msgid "table \"%s\" could not be created, will not restore its data\n" msgstr "creazione della tabella \"%s\" fallita, i suoi dati non verranno ripristinati\n" @@ -996,7 +981,7 @@ msgid "unrecognized data block type %d while restoring archive\n" msgstr "tipo di blocco dati sconosciuto %d durante il ripristino dell'archivio\n" #: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1090 +#: pg_backup_tar.c:1102 #, c-format msgid "could not determine seek position in archive file: %s\n" msgstr "non è stato possibile determinare la posizione per il seek nel file d'archivio: %s\n" @@ -1180,37 +1165,43 @@ msgstr "chiusura della directory \"%s\" fallita: %s\n" msgid "could not create directory \"%s\": %s\n" msgstr "creazione della directory \"%s\" fallita: %s\n" -#: pg_backup_directory.c:407 +#: pg_backup_directory.c:355 pg_backup_directory.c:495 +#: pg_backup_directory.c:525 +#, c-format +msgid "could not write to output file: %s\n" +msgstr "scrittura nel file di output fallita: %s\n" + +#: pg_backup_directory.c:409 #, c-format msgid "could not close data file: %s\n" msgstr "chiusura del file di dati fallita: %s\n" -#: pg_backup_directory.c:448 +#: pg_backup_directory.c:450 #, c-format msgid "could not open large object TOC file \"%s\" for input: %s\n" msgstr "apertura del file TOC dei large object \"%s\" per l'input fallita: %s\n" -#: pg_backup_directory.c:459 +#: pg_backup_directory.c:461 #, c-format msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" msgstr "riga non valida nel file TOC dei large object \"%s\": \"%s\"\n" -#: pg_backup_directory.c:468 +#: pg_backup_directory.c:470 #, c-format msgid "error reading large object TOC file \"%s\"\n" msgstr "errore in lettura del file TOC dei large object \"%s\"\n" -#: pg_backup_directory.c:472 +#: pg_backup_directory.c:474 #, c-format msgid "could not close large object TOC file \"%s\": %s\n" msgstr "chiusura del file TOC dei large object \"%s\" fallita: %s\n" -#: pg_backup_directory.c:686 +#: pg_backup_directory.c:690 #, c-format msgid "could not write to blobs TOC file\n" msgstr "scrittura nel file TOC dei blob fallita\n" -#: pg_backup_directory.c:718 +#: pg_backup_directory.c:722 #, c-format msgid "file name too long: \"%s\"\n" msgstr "nome del file troppo lungo: \"%s\"\n" @@ -1270,69 +1261,69 @@ msgstr "apertura del file temporaneo fallita\n" msgid "could not close tar member\n" msgstr "chiusura del membro tar fallita\n" -#: pg_backup_tar.c:569 +#: pg_backup_tar.c:581 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "errore interno -- né th né fh specificato in tarReadRaw()\n" -#: pg_backup_tar.c:692 +#: pg_backup_tar.c:704 #, c-format msgid "unexpected COPY statement syntax: \"%s\"\n" msgstr "sintassi dell'istruzione COPY imprevista: \"%s\"\n" -#: pg_backup_tar.c:962 +#: pg_backup_tar.c:974 #, c-format msgid "invalid OID for large object (%u)\n" msgstr "OID non valida per il large object (%u)\n" -#: pg_backup_tar.c:1106 +#: pg_backup_tar.c:1118 #, c-format msgid "could not close temporary file: %s\n" msgstr "chiusura del file temporaneo fallita: %s\n" -#: pg_backup_tar.c:1116 +#: pg_backup_tar.c:1128 #, c-format msgid "actual file length (%s) does not match expected (%s)\n" msgstr "la lunghezza del file (%s) non corrisponde con quella prevista (%s)\n" -#: pg_backup_tar.c:1153 +#: pg_backup_tar.c:1165 #, c-format msgid "moving from position %s to next member at file position %s\n" msgstr "spostamento dalla posizione %s al membro successivo alla posizione nel file %s\n" -#: pg_backup_tar.c:1164 +#: pg_backup_tar.c:1176 #, c-format msgid "now at file position %s\n" msgstr "attuale posizione nel file %s\n" -#: pg_backup_tar.c:1173 pg_backup_tar.c:1203 +#: pg_backup_tar.c:1185 pg_backup_tar.c:1215 #, c-format msgid "could not find header for file \"%s\" in tar archive\n" msgstr "intestazione per il file \"%s\" nell'archivio tar non trovata\n" -#: pg_backup_tar.c:1187 +#: pg_backup_tar.c:1199 #, c-format msgid "skipping tar member %s\n" msgstr "salto del membro tar %s\n" -#: pg_backup_tar.c:1191 +#: pg_backup_tar.c:1203 #, c-format msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file.\n" msgstr "il ripristino dei dati fuori ordine non è supportato in questo formato di archivio: è richiesto \"%s\", ma nel file d'archivio viene prima di \"%s\".\n" -#: pg_backup_tar.c:1237 +#: pg_backup_tar.c:1249 #, c-format msgid "incomplete tar header found (%lu byte)\n" msgid_plural "incomplete tar header found (%lu bytes)\n" msgstr[0] "intestazione del file tar incompleta (%lu byte)\n" msgstr[1] "intestazione del file tar incompleta (%lu byte)\n" -#: pg_backup_tar.c:1278 +#: pg_backup_tar.c:1290 #, c-format msgid "TOC Entry %s at %s (length %s, checksum %d)\n" msgstr "Voce TOC %s a %s (lunghezza %s, checksum %d)\n" -#: pg_backup_tar.c:1289 +#: pg_backup_tar.c:1301 #, c-format msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" msgstr "intestazione tar corrotta in %s (previsti %d, calcolati %d) alla posizione file %s\n" @@ -1504,7 +1495,7 @@ msgstr "" " --lock-wait-timeout=TIMEOUT termina con errore dopo un'attesa di TIMEOUT\n" " per un lock di tabella\n" -#: pg_dump.c:926 pg_dumpall.c:604 +#: pg_dump.c:926 pg_dumpall.c:605 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync non aspettare che i cambiamenti vengano scritti in sicurezza sul disco\n" @@ -1665,12 +1656,12 @@ msgstr " --inserts scarica i dati come comandi INSERT anzich msgid " --no-publications do not dump publications\n" msgstr " --no-publications non scaricare le pubblicazioni\n" -#: pg_dump.c:956 pg_dumpall.c:602 +#: pg_dump.c:956 pg_dumpall.c:603 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels non scaricare le assegnazioni di sicurezza\n" -#: pg_dump.c:957 pg_dumpall.c:603 +#: pg_dump.c:957 pg_dumpall.c:604 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions non scaricare le sottoscrizioni\n" @@ -1680,12 +1671,12 @@ msgstr " --no-subscriptions non scaricare le sottoscrizioni\n" msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" msgstr " --no-synchronized-snapshots non usare snapshot sincronizzati nei job paralleli\n" -#: pg_dump.c:959 pg_dumpall.c:605 +#: pg_dump.c:959 pg_dumpall.c:606 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces non scarica le assegnazioni di tablespace\n" -#: pg_dump.c:960 pg_dumpall.c:606 +#: pg_dump.c:960 pg_dumpall.c:607 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data non scaricare i dati delle tabelle non loggate\n" @@ -1808,11 +1799,11 @@ msgstr "codifica client specificata \"%s\" non valida\n" #: pg_dump.c:1136 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" "synchronized snapshots.\n" msgstr "" -"Gli snapshot sincronizzati non sono supportati sui server di standby.\n" +"Gli snapshot sincronizzati sui server di standby non sono supportati da questa versione.\n" "Usa --no-synchronized-snapshots se non ti servono snapshot\n" "sincronizzati.\n" @@ -1931,291 +1922,291 @@ msgstr "ATTENZIONE: errore nella lettura delle sotto-pubblicazioni\n" msgid "could not find parent extension for %s\n" msgstr "estensione genitore di %s non trovata\n" -#: pg_dump.c:4202 +#: pg_dump.c:4207 #, c-format msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario dello schema \"%s\" sembra non essere valido\n" -#: pg_dump.c:4225 +#: pg_dump.c:4230 #, c-format msgid "schema with OID %u does not exist\n" msgstr "lo schema con OID %u non esiste\n" -#: pg_dump.c:4556 +#: pg_dump.c:4561 #, c-format msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario del tipo dato \"%s\" non sembra essere valido\n" -#: pg_dump.c:4644 +#: pg_dump.c:4649 #, c-format msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario dell'operatore \"%s\" non sembra essere valido\n" -#: pg_dump.c:4958 +#: pg_dump.c:4963 #, c-format msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario della classe operatore \"%s\" non sembra essere valido\n" -#: pg_dump.c:5045 +#: pg_dump.c:5050 #, c-format msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario della famiglia di operatori \"%s\" non sembra essere valido\n" -#: pg_dump.c:5212 +#: pg_dump.c:5217 #, c-format msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario della funzione di aggregazione \"%s\" non sembra essere valido\n" -#: pg_dump.c:5471 +#: pg_dump.c:5476 #, c-format msgid "WARNING: owner of function \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario della funzione \"%s\" non sembra essere valido\n" -#: pg_dump.c:6253 +#: pg_dump.c:6258 #, c-format msgid "WARNING: owner of table \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il proprietario della tabella \"%s\" non sembra essere valido\n" -#: pg_dump.c:6295 pg_dump.c:16509 +#: pg_dump.c:6300 pg_dump.c:16539 #, c-format msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found\n" msgstr "controllo di integrità fallito, tabella padre con OID %u della sequenza con OID %u non trovato\n" -#: pg_dump.c:6426 +#: pg_dump.c:6431 #, c-format msgid "reading indexes for table \"%s.%s\"\n" msgstr "lettura degli indici della tabella \"%s.%s\"\n" -#: pg_dump.c:6707 +#: pg_dump.c:6712 #, c-format msgid "reading extended statistics for table \"%s.%s\"\n" msgstr "lettura delle statistiche estese per la tabella \"%s.%s\"\n" -#: pg_dump.c:6790 +#: pg_dump.c:6795 #, c-format msgid "reading foreign key constraints for table \"%s.%s\"\n" msgstr "lettura dei vincoli di chiave esterna della tabella \"%s.%s\"\n" -#: pg_dump.c:7014 +#: pg_dump.c:7019 #, c-format msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n" msgstr "controllo di sanità fallito, la tabella padre con OID %u della voce di pg_rewrite con OID %u non trovata\n" -#: pg_dump.c:7098 +#: pg_dump.c:7103 #, c-format msgid "reading triggers for table \"%s.%s\"\n" msgstr "lettura dei trigger della tabella \"%s.%s\"\n" -#: pg_dump.c:7236 +#: pg_dump.c:7241 #, c-format msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n" msgstr "la query non ha prodotto nessun nome di tabella referenziata per il trigger di chiave esterna \"%s\" sulla tabella \"%s\" (OID della tabella: %u)\n" -#: pg_dump.c:7808 +#: pg_dump.c:7813 #, c-format msgid "finding the columns and types of table \"%s.%s\"\n" msgstr "lettura delle colonne e dei tipi della tabella \"%s.%s\"\n" -#: pg_dump.c:7973 +#: pg_dump.c:7978 #, c-format msgid "invalid column numbering in table \"%s\"\n" msgstr "numerazione delle colonne non valida nella tabella \"%s\"\n" -#: pg_dump.c:8009 +#: pg_dump.c:8014 #, c-format msgid "finding default expressions of table \"%s.%s\"\n" msgstr "lettura delle espressioni di default della tabella \"%s.%s\"\n" -#: pg_dump.c:8032 +#: pg_dump.c:8037 #, c-format msgid "invalid adnum value %d for table \"%s\"\n" msgstr "valore adnum %d non valido per la tabella \"%s\"\n" -#: pg_dump.c:8098 +#: pg_dump.c:8103 #, c-format msgid "finding check constraints for table \"%s.%s\"\n" msgstr "ricerca dei vincoli di controllo della tabella \"%s.%s\"\n" -#: pg_dump.c:8147 +#: pg_dump.c:8152 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d\n" msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" msgstr[0] "previsto %d vincolo di controllo sulla tabella \"%s\" ma trovato %d\n" msgstr[1] "previsti %d vincoli di controllo sulla tabella \"%s\" ma trovati %d\n" -#: pg_dump.c:8151 +#: pg_dump.c:8156 #, c-format msgid "(The system catalogs might be corrupted.)\n" msgstr "(I cataloghi di sistema potrebbero essere corrotti.)\n" -#: pg_dump.c:9709 +#: pg_dump.c:9714 #, c-format msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" msgstr "ATTENZIONE: il \"typtype\" del tipo dato \"%s\" sembra non essere valido\n" -#: pg_dump.c:11138 +#: pg_dump.c:11143 #, c-format msgid "WARNING: bogus value in proargmodes array\n" msgstr "ATTENZIONE: valore errato nell'array proargmode\n" -#: pg_dump.c:11464 +#: pg_dump.c:11469 #, c-format msgid "WARNING: could not parse proallargtypes array\n" msgstr "ATTENZIONE: non è stato possibile analizzare l'array proallargtype\n" -#: pg_dump.c:11480 +#: pg_dump.c:11485 #, c-format msgid "WARNING: could not parse proargmodes array\n" msgstr "ATTENZIONE: non è stato possibile analizzare l'array proargmode\n" -#: pg_dump.c:11494 +#: pg_dump.c:11499 #, c-format msgid "WARNING: could not parse proargnames array\n" msgstr "ATTENZIONE: non è stato possibile analizzare l'array proargname\n" -#: pg_dump.c:11505 +#: pg_dump.c:11510 #, c-format msgid "WARNING: could not parse proconfig array\n" msgstr "ATTENZIONE: non è stato possibile analizzare l'array preconfig\n" -#: pg_dump.c:11576 +#: pg_dump.c:11581 #, c-format msgid "unrecognized provolatile value for function \"%s\"\n" msgstr "valore provolatile sconosciuto per la funzione \"%s\"\n" -#: pg_dump.c:11620 pg_dump.c:13603 +#: pg_dump.c:11625 pg_dump.c:13623 #, c-format msgid "unrecognized proparallel value for function \"%s\"\n" msgstr "valore proparallel non riconosciuto per la funzione \"%s\"\n" -#: pg_dump.c:11728 pg_dump.c:11838 pg_dump.c:11845 +#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 #, c-format msgid "could not find function definition for function with OID %u\n" msgstr "definizione della funzione con OID %u non trovata\n" -#: pg_dump.c:11773 +#: pg_dump.c:11778 #, c-format msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" msgstr "ATTENZIONE: valore non corretto nei campi pg_cast.castfunc o pg_cast.castmethod\n" -#: pg_dump.c:11776 +#: pg_dump.c:11781 #, c-format msgid "WARNING: bogus value in pg_cast.castmethod field\n" msgstr "ATTENZIONE: valore non corretto nel campo pg_cast.castmethod\n" -#: pg_dump.c:11866 +#: pg_dump.c:11871 #, c-format msgid "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n" msgstr "ATTENZIONE: definizione della trasformazione non corretta, almeno uno tra trffromsql e trftosql dovrebbe essere non-zero\n" -#: pg_dump.c:11883 +#: pg_dump.c:11888 #, c-format msgid "WARNING: bogus value in pg_transform.trffromsql field\n" msgstr "ATTENZIONE: valore non corretto nel campo pg_transform.trffromsql\n" -#: pg_dump.c:11904 +#: pg_dump.c:11909 #, c-format msgid "WARNING: bogus value in pg_transform.trftosql field\n" msgstr "ATTENZIONE: valore non corretto nel campo pg_transform.trftosql\n" -#: pg_dump.c:12300 +#: pg_dump.c:12305 #, c-format msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" msgstr "ATTENZIONE: tipo \"%c\" non valido del metodo di accesso \"%s\"\n" -#: pg_dump.c:13066 +#: pg_dump.c:13086 #, c-format msgid "unrecognized collation provider: %s\n" msgstr "fornitore di ordinamenti non riconosciuto: %s\n" -#: pg_dump.c:13513 +#: pg_dump.c:13533 #, c-format msgid "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n" msgstr "ATTENZIONE: la funzione di aggregazione %s non può essere scaricata correttamente per questa versione database; ignorata\n" -#: pg_dump.c:14369 +#: pg_dump.c:14389 #, c-format msgid "unrecognized object type in default privileges: %d\n" msgstr "tipo di oggetto sconosciuto nei privilegi predefiniti: %d\n" -#: pg_dump.c:14387 +#: pg_dump.c:14407 #, c-format msgid "could not parse default ACL list (%s)\n" msgstr "non è stato possibile interpretare la ACL predefinita (%s)\n" -#: pg_dump.c:14458 +#: pg_dump.c:14488 #, c-format msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n" msgstr "non è stato possibile interpretare il GRANT ACL iniziale (%s) o il REVOKE ACL iniziale (%s) per l'oggetto \"%s\" (%s)\n" -#: pg_dump.c:14466 +#: pg_dump.c:14496 #, c-format msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n" msgstr "non è stato possibile interpretare il GRANT ACL (%s) o il REVOKE ACL (%s) per l'oggetto \"%s\" (%s)\n" -#: pg_dump.c:14941 +#: pg_dump.c:14971 #, c-format msgid "query to obtain definition of view \"%s\" returned no data\n" msgstr "la query per ottenere la definizione della vista \"%s\" non ha restituito dati\n" -#: pg_dump.c:14944 +#: pg_dump.c:14974 #, c-format msgid "query to obtain definition of view \"%s\" returned more than one definition\n" msgstr "la query per ottenere la definizione della vista \"%s\" ha restituito più di una definizione\n" -#: pg_dump.c:14951 +#: pg_dump.c:14981 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)\n" msgstr "la definizione della vista \"%s\" sembra essere vuota (lunghezza zero)\n" -#: pg_dump.c:15180 +#: pg_dump.c:15210 #, c-format msgid "invalid number of parents %d for table \"%s\"\n" msgstr "numero di genitori %d non valido per la tabella \"%s\"\n" -#: pg_dump.c:15827 +#: pg_dump.c:15857 #, c-format msgid "invalid column number %d for table \"%s\"\n" msgstr "il numero di colonne %d non è valido per la tabella \"%s\"\n" -#: pg_dump.c:16011 +#: pg_dump.c:16041 #, c-format msgid "missing index for constraint \"%s\"\n" msgstr "omesso indice per vincolo \"%s\"\n" -#: pg_dump.c:16214 +#: pg_dump.c:16244 #, c-format msgid "unrecognized constraint type: %c\n" msgstr "tipo di vincolo sconosciuto: %c\n" -#: pg_dump.c:16351 pg_dump.c:16577 +#: pg_dump.c:16381 pg_dump.c:16607 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)\n" msgstr[0] "la query per ottenere i dati della sequenza \"%s\" ha restituito %d riga (prevista 1)\n" msgstr[1] "la query per ottenere i dati della sequenza \"%s\" ha restituito %d righe (prevista 1)\n" -#: pg_dump.c:16675 +#: pg_dump.c:16705 #, c-format msgid "unexpected tgtype value: %d\n" msgstr "valore tgtype inatteso: %d\n" -#: pg_dump.c:16749 +#: pg_dump.c:16779 #, c-format msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" msgstr "la stringa argomento (%s) non è valida per il trigger \"%s\" sulla tabella \"%s\"\n" -#: pg_dump.c:16970 +#: pg_dump.c:17010 #, c-format msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n" msgstr "la query per ottenere regole \"%s\" per la tabella \"%s\" ha fallito: ha restituito un numero errato di righe\n" -#: pg_dump.c:17365 +#: pg_dump.c:17405 #, c-format msgid "reading dependency data\n" msgstr "lettura dati di dipendenza\n" -#: pg_dump.c:17830 +#: pg_dump.c:17870 #, c-format msgid "WARNING: could not parse reloptions array\n" msgstr "ATTENZIONE: errore di lettura dell'array reloptions\n" @@ -2377,7 +2368,7 @@ msgstr " -S, --superuser=NOME nome del superutente da usare nel dump\n" msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr " -t, --tablespaces-only scarica solo i tablespace e non i database o i ruoli\n" -#: pg_dumpall.c:607 +#: pg_dumpall.c:602 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords non scaricare le password dei ruoli\n" @@ -2669,7 +2660,7 @@ msgstr " --no-publications non ripristinare le pubblicazioni\n" #: pg_restore.c:486 #, c-format msgid " --no-security-labels do not restore security labels\n" -msgstr " --no-security-labels do ripristinare le etichette di sicurezza\n" +msgstr " --no-security-labels non ripristinare le etichette di sicurezza\n" #: pg_restore.c:487 #, c-format diff --git a/src/bin/pg_dump/po/ko.po b/src/bin/pg_dump/po/ko.po index 45ba3bca78c..d1d8aa53ede 100644 --- a/src/bin/pg_dump/po/ko.po +++ b/src/bin/pg_dump/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: pg_dump (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 18:26+0900\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:25+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" "Language: ko\n" @@ -51,8 +51,7 @@ msgid "pclose failed: %s" msgstr "pclose 실패: %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 pg_backup_db.c:158 pg_backup_db.c:213 -#: pg_backup_db.c:272 pg_backup_db.c:314 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "메모리 부족\n" @@ -62,37 +61,37 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 중복할 수 ì—†ìŒ (ë‚´ë¶€ 오류)\n" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "해당 명령어 ì—†ìŒ" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 종료 코드 %d" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "0x%X 예외처리로 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "%s ì‹œê·¸ë„ ê°ì§€ë¡œ 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, ì‹œê·¸ë„ %d" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "하위 프로세스가 종료ë˜ì—ˆìŒ, 알수 없는 ìƒíƒœ %d" @@ -249,36 +248,56 @@ msgstr "ì¸ë±ìŠ¤ë“¤ì„ ì½ëŠ” 중\n" #: common.c:261 #, c-format +msgid "reading extended statistics\n" +msgstr "확장 í†µê³„ë“¤ì„ ì½ëŠ” 중\n" + +#: common.c:265 +#, c-format msgid "reading constraints\n" msgstr "제약 ì¡°ê±´ë“¤ì„ ì½ëŠ” 중\n" -#: common.c:265 +#: common.c:269 #, c-format msgid "reading triggers\n" msgstr "íŠ¸ë¦¬ê±°ë“¤ì„ ì½ëŠ” 중\n" -#: common.c:269 +#: common.c:273 #, c-format msgid "reading rewrite rules\n" msgstr "룰(rule) ì½ëŠ” 중\n" -#: common.c:273 +#: common.c:277 #, c-format msgid "reading policies\n" msgstr "ì •ì±… ì½ëŠ” 중\n" -#: common.c:908 +#: common.c:281 +#, c-format +msgid "reading publications\n" +msgstr "발행 정보를 ì½ëŠ” 중\n" + +#: common.c:285 +#, c-format +msgid "reading publication membership\n" +msgstr "발행 ë§µë²„ì‰½ì„ ì½ì„ 중\n" + +#: common.c:289 +#, c-format +msgid "reading subscriptions\n" +msgstr "구ë…정보를 ì½ëŠ” 중\n" + +#: common.c:924 #, c-format msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" msgstr "" "안전 검사 실패, OID %uì¸ ë¶€ëª¨ 개체가 ì—†ìŒ. 해당 í…Œì´ë¸” \"%s\" (OID %u)\n" -#: common.c:950 +#: common.c:966 #, c-format msgid "could not parse numeric array \"%s\": too many numbers\n" msgstr "\"%s\" ìˆ«ìž ë°°ì—´ì„ ë¶„ì„í•  수 ì—†ìŒ: 너무 숫ìžê°€ 있습니다\n" -#: common.c:965 +#: common.c:981 #, c-format msgid "could not parse numeric array \"%s\": invalid character in number\n" msgstr "\"%s\" ìˆ«ìž ë°°ì—´ì„ ë¶„ì„í•  수 ì—†ìŒ: 숫ìžì•ˆì— ì´ìƒí•œ 글ìžê°€ 있습니다\n" @@ -324,40 +343,50 @@ msgstr "ìžë£Œ ì••ì¶•ì„ í’€ 수 없습니다: %s\n" msgid "could not close compression library: %s\n" msgstr "ì••ì¶• ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:591 -#: pg_backup_tar.c:561 +#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 +#: pg_backup_tar.c:564 pg_backup_tar.c:568 #, c-format msgid "could not read from input file: %s\n" msgstr "ìž…ë ¥ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: compress_io.c:635 pg_backup_custom.c:588 pg_backup_directory.c:548 -#: pg_backup_tar.c:797 pg_backup_tar.c:821 +#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 +#: pg_backup_tar.c:807 pg_backup_tar.c:831 #, c-format msgid "could not read from input file: end of file\n" msgstr "ìž…ë ¥ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: íŒŒì¼ ë\n" -#: parallel.c:163 +#: parallel.c:198 msgid "parallel archiver" msgstr "병렬 ì•„ì¹´ì´ë²„" # # search5 ë # # advance 부분 -#: parallel.c:227 +#: parallel.c:265 #, c-format msgid "%s: WSAStartup failed: %d\n" msgstr "%s: WSAStartup 작업 실패: %d\n" -#: parallel.c:930 +#: parallel.c:971 #, c-format msgid "could not create communication channels: %s\n" msgstr "통신 ì²´ë„ì„ ë§Œë“¤ 수 ì—†ìŒ: %s\n" -#: parallel.c:993 +#: parallel.c:1036 #, c-format msgid "could not create worker process: %s\n" msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ë¥¼ 만들 수 ì—†ìŒ: %s\n" -#: parallel.c:1188 +#: parallel.c:1167 +#, c-format +msgid "unrecognized command received from master: \"%s\"\n" +msgstr "마스터ì—서 알 수 없는 ëª…ë ¹ì„ ë°›ìŒ: \"%s\"\n" + +#: parallel.c:1211 parallel.c:1451 +#, c-format +msgid "invalid message received from worker: \"%s\"\n" +msgstr "작업 프로세스로부터 ìž˜ëª»ëœ ë©”ì‹œì§€ë¥¼ ë°›ìŒ: \"%s\"\n" + +#: parallel.c:1344 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" @@ -366,111 +395,96 @@ msgid "" "lock on the table.\n" msgstr "" "\"%s\" 릴레ì´ì…˜ì„ ì„ ì í•  수 ì—†ìŒ\n" -"ì´ ìƒí™©ì€ ì¼ë°˜ì ìœ¼ë¡œ 다른 세션ì—서 해당 í…Œì´ë¸”ì„ ì´ë¯¸ ë¤í”„하고 있거나 " -"기타 다른 ì´ìœ ë¡œ 다른 ì„¸ì…˜ì— ì˜í•´ì„œ ì„ ì  ëœ ê²½ìš°ìž…ë‹ˆë‹¤.\n" +"ì´ ìƒí™©ì€ ì¼ë°˜ì ìœ¼ë¡œ 다른 세션ì—서 해당 í…Œì´ë¸”ì„ ì´ë¯¸ ë¤í”„하고 있거나 기타 다" +"른 ì´ìœ ë¡œ 다른 ì„¸ì…˜ì— ì˜í•´ì„œ ì„ ì  ëœ ê²½ìš°ìž…ë‹ˆë‹¤.\n" -#: parallel.c:1258 -#, c-format -msgid "unrecognized command received from master: \"%s\"\n" -msgstr "마스터ì—서 알 수 없는 ëª…ë ¹ì„ ë°›ìŒ: \"%s\"\n" - -#: parallel.c:1296 +#: parallel.c:1433 #, c-format msgid "a worker process died unexpectedly\n" msgstr "작업 프로세스가 예ìƒì¹˜ 않게 종료ë¨\n" -#: parallel.c:1322 parallel.c:1328 -#, c-format -msgid "invalid message received from worker: \"%s\"\n" -msgstr "작업 프로세스로부터 ìž˜ëª»ëœ ë©”ì‹œì§€ë¥¼ ë°›ìŒ: \"%s\"\n" - -#: parallel.c:1385 parallel.c:1436 -#, c-format -msgid "error processing a parallel work item\n" -msgstr "병렬 작업 ì•„ì´í…œ 처리 오류\n" - -#: parallel.c:1465 parallel.c:1583 +#: parallel.c:1557 parallel.c:1675 #, c-format msgid "could not write to the communication channel: %s\n" msgstr "통신 ì²´ë„ì—ì— ì“¸ 수 ì—†ìŒ: %s\n" -#: parallel.c:1543 +#: parallel.c:1635 #, c-format msgid "select() failed: %s\n" msgstr "select() 실패: %s\n" -#: parallel.c:1668 +#: parallel.c:1760 #, c-format msgid "pgpipe: could not create socket: error code %d\n" msgstr "pgpipe: ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ: 오류 코드 %d\n" -#: parallel.c:1679 +#: parallel.c:1771 #, c-format msgid "pgpipe: could not bind: error code %d\n" msgstr "pgpipe: ë°”ì¸ë”© í•  수 ì—†ìŒ: 오류 코드 %d\n" -#: parallel.c:1686 +#: parallel.c:1778 #, c-format msgid "pgpipe: could not listen: error code %d\n" msgstr "pgpipe: 리슨 í•  수 ì—†ìŒ: 오류 코드 %d\n" -#: parallel.c:1693 +#: parallel.c:1785 #, c-format msgid "pgpipe: getsockname() failed: error code %d\n" msgstr "pgpipe: getsockname() 실패: 오류 코드 %d\n" -#: parallel.c:1704 +#: parallel.c:1796 #, c-format msgid "pgpipe: could not create second socket: error code %d\n" msgstr "pgpipe: ë‘번째 ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ: 오류 코드 %d\n" -#: parallel.c:1713 +#: parallel.c:1805 #, c-format msgid "pgpipe: could not connect socket: error code %d\n" msgstr "pgpipe: 소켓 ì ‘ì† ì‹¤íŒ¨: 오류 코드 %d\n" -#: parallel.c:1722 +#: parallel.c:1814 #, c-format msgid "pgpipe: could not accept connection: error code %d\n" msgstr "pgpipe: ì ‘ì†ì„ 승ì¸í•  수 ì—†ìŒ: 오류 코드 %d\n" #. translator: this is a module name -#: pg_backup_archiver.c:55 +#: pg_backup_archiver.c:53 msgid "archiver" msgstr "ì•„ì¹´ì´ë²„" -#: pg_backup_archiver.c:234 pg_backup_archiver.c:1519 +#: pg_backup_archiver.c:249 pg_backup_archiver.c:1599 #, c-format msgid "could not close output file: %s\n" msgstr "출력 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:280 pg_backup_archiver.c:285 +#: pg_backup_archiver.c:295 pg_backup_archiver.c:300 #, c-format msgid "WARNING: archive items not in correct section order\n" msgstr "경고: ì•„ì¹´ì´ë¸Œ ì•„ì´í…œì˜ 순서가 섹션ì—서 비정ìƒì ìž„\n" -#: pg_backup_archiver.c:291 +#: pg_backup_archiver.c:306 #, c-format msgid "unexpected section code %d\n" msgstr "예ìƒì¹˜ 못한 섹션 코드 %d\n" -#: pg_backup_archiver.c:327 +#: pg_backup_archiver.c:342 #, c-format msgid "-C and -1 are incompatible options\n" msgstr "-C와 -1ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_backup_archiver.c:337 +#: pg_backup_archiver.c:352 #, c-format msgid "parallel restore is not supported with this archive file format\n" msgstr "ì´ ì•„ì¹´ì´ë¸Œ íŒŒì¼ í˜•ì‹ì—서는 병렬 ë³µì›ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: pg_backup_archiver.c:341 +#: pg_backup_archiver.c:356 #, c-format msgid "" "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" msgstr "8.0 ì´ì „ pg_dump로 만든 ì•„ì¹´ì´ë¸Œì—서는 병렬 ë³µì›ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: pg_backup_archiver.c:359 +#: pg_backup_archiver.c:374 #, c-format msgid "" "cannot restore from compressed archive (compression not supported in this " @@ -479,82 +493,77 @@ msgstr "" "ì••ì¶•ëœ ìžë£ŒíŒŒì¼ì„ ë³µì›ìš©ìœ¼ë¡œ 사용할 수 없습니다(ì••ì¶•ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않고 컴파" "ì¼ë˜ì—ˆìŒ)\n" -#: pg_backup_archiver.c:376 +#: pg_backup_archiver.c:391 #, c-format msgid "connecting to database for restore\n" msgstr "리스토어 ìž‘ì—…ì„ ìœ„í•´ ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì†í•©ë‹ˆë‹¤\n" -#: pg_backup_archiver.c:378 +#: pg_backup_archiver.c:393 #, c-format msgid "direct database connections are not supported in pre-1.3 archives\n" msgstr "pre-1.3 archiveì—서 ì§í†µ ë°ì´í„°ë² ì´ìФ ì ‘ì†ì€ ì§€ì›ë˜ì§€ 않습니다\n" -#: pg_backup_archiver.c:423 +#: pg_backup_archiver.c:438 #, c-format msgid "implied data-only restore\n" msgstr "ì•”ì‹œëœ ìžë£Œë§Œ ë³µì›í•˜ê¸° - 아주 ë‚˜ìœ ë²ˆì—­\n" -#: pg_backup_archiver.c:493 +#: pg_backup_archiver.c:508 #, c-format msgid "dropping %s %s\n" msgstr "%s %s 삭제하는 중\n" -#: pg_backup_archiver.c:646 -#, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "%s \"%s.%s\" ê°ì²´ì˜ 소유주와 ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•˜ëŠ” 중\n" - -#: pg_backup_archiver.c:649 +#: pg_backup_archiver.c:601 #, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "%s \"%s\" ê°ì²´ì˜ 소유주와 ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•˜ëŠ” 중\n" +msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" +msgstr "경고: \"%s\" 구문ì—서 insert IF EXISTS ë¶€ë¶„ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:715 pg_backup_archiver.c:717 +#: pg_backup_archiver.c:764 pg_backup_archiver.c:766 #, c-format msgid "warning from original dump file: %s\n" msgstr "ì›ë³¸ ë¤í”„ 파ì¼ì—서 ë°œìƒí•œ 경고: %s\n" -#: pg_backup_archiver.c:726 +#: pg_backup_archiver.c:778 #, c-format msgid "creating %s \"%s.%s\"\n" msgstr "%s \"%s.%s\" 만드는 중\n" -#: pg_backup_archiver.c:729 +#: pg_backup_archiver.c:781 #, c-format msgid "creating %s \"%s\"\n" msgstr "%s \"%s\" 만드는 중\n" -#: pg_backup_archiver.c:781 +#: pg_backup_archiver.c:832 #, c-format msgid "connecting to new database \"%s\"\n" msgstr "\"%s\" 새 ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì†í•©ë‹ˆë‹¤\n" -#: pg_backup_archiver.c:809 +#: pg_backup_archiver.c:860 #, c-format msgid "processing %s\n" msgstr "%s 처리 중\n" -#: pg_backup_archiver.c:829 +#: pg_backup_archiver.c:880 #, c-format msgid "processing data for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì˜ ìžë£Œë¥¼ 처리 중\n" -#: pg_backup_archiver.c:891 +#: pg_backup_archiver.c:942 #, c-format msgid "executing %s %s\n" msgstr "실행중: %s %s\n" -#: pg_backup_archiver.c:930 +#: pg_backup_archiver.c:981 #, c-format msgid "disabling triggers for %s\n" msgstr "%s ìžë£Œ ë³µì›ì„ 하면서 트리거 ìž‘ë™ì„ 비활성화 합니다\n" -#: pg_backup_archiver.c:958 +#: pg_backup_archiver.c:1009 #, c-format msgid "enabling triggers for %s\n" msgstr "%s 트리거 ìž‘ë™ì„ 활성화 합니다\n" -#: pg_backup_archiver.c:988 +#: pg_backup_archiver.c:1039 #, c-format msgid "" "internal error -- WriteData cannot be called outside the context of a " @@ -562,275 +571,285 @@ msgid "" msgstr "" "ë‚´ë¶€ 오류 -- WriteDataê°€ DataDumper 루틴 ì˜ì—­ ë°–ì—서 호출 ë  ìˆ˜ 없습니다\n" -#: pg_backup_archiver.c:1157 +#: pg_backup_archiver.c:1237 #, c-format msgid "large-object output not supported in chosen format\n" msgstr "ì„ íƒí•œ íŒŒì¼ í˜•íƒœë¡œëŠ” large-object를 ë¤í”„í•  수 없습니다\n" -#: pg_backup_archiver.c:1215 +#: pg_backup_archiver.c:1295 #, c-format msgid "restored %d large object\n" msgid_plural "restored %d large objects\n" msgstr[0] "%dê°œì˜ í° ê°œì²´ê°€ ë³µì›ë¨\n" -#: pg_backup_archiver.c:1236 pg_backup_tar.c:739 +#: pg_backup_archiver.c:1316 pg_backup_tar.c:749 #, c-format msgid "restoring large object with OID %u\n" msgstr "%u OID large object를 ë³µì›ì¤‘\n" -#: pg_backup_archiver.c:1248 +#: pg_backup_archiver.c:1328 #, c-format msgid "could not create large object %u: %s" msgstr "%u large object를 만들 수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:1253 pg_dump.c:3050 +#: pg_backup_archiver.c:1333 pg_dump.c:3084 #, c-format msgid "could not open large object %u: %s" msgstr "%u large object를 ì—´ 수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:1311 +#: pg_backup_archiver.c:1391 #, c-format msgid "could not open TOC file \"%s\": %s\n" msgstr "TOC íŒŒì¼ \"%s\"ì„(를) ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:1352 +#: pg_backup_archiver.c:1432 #, c-format msgid "WARNING: line ignored: %s\n" msgstr "경고: 줄 무시ë¨: %s\n" -#: pg_backup_archiver.c:1359 +#: pg_backup_archiver.c:1439 #, c-format msgid "could not find entry for ID %d\n" msgstr "%d IDì— ëŒ€í•œ í•­ëª©ì„ ì°¾ì§€ 못했ìŒ\n" -#: pg_backup_archiver.c:1380 pg_backup_directory.c:230 -#: pg_backup_directory.c:597 +#: pg_backup_archiver.c:1460 pg_backup_directory.c:225 +#: pg_backup_directory.c:596 #, c-format msgid "could not close TOC file: %s\n" msgstr "TOC 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:1489 pg_backup_custom.c:162 pg_backup_directory.c:341 -#: pg_backup_directory.c:583 pg_backup_directory.c:641 -#: pg_backup_directory.c:661 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:158 pg_backup_directory.c:336 +#: pg_backup_directory.c:582 pg_backup_directory.c:647 +#: pg_backup_directory.c:667 #, c-format msgid "could not open output file \"%s\": %s\n" msgstr "\"%s\" 출력 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:1492 pg_backup_custom.c:169 +#: pg_backup_archiver.c:1572 pg_backup_custom.c:165 #, c-format msgid "could not open output file: %s\n" msgstr "출력 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:1598 +#: pg_backup_archiver.c:1678 #, c-format msgid "wrote %lu byte of large object data (result = %lu)\n" msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" msgstr[0] "%luë°”ì´íŠ¸ì˜ í° ê°œì²´ ë°ì´í„°ë¥¼ 씀(ê²°ê³¼ = %lu)\n" -#: pg_backup_archiver.c:1604 +#: pg_backup_archiver.c:1684 #, c-format msgid "could not write to large object (result: %lu, expected: %lu)\n" msgstr "large object를 쓸 수 ì—†ìŒ (결과값: %lu, 예ìƒê°’: %lu)\n" -#: pg_backup_archiver.c:1697 +#: pg_backup_archiver.c:1777 #, c-format msgid "Error while INITIALIZING:\n" msgstr "초기화 작업 중 오류:\n" -#: pg_backup_archiver.c:1702 +#: pg_backup_archiver.c:1782 #, c-format msgid "Error while PROCESSING TOC:\n" msgstr "TOC 처리하는 중 오류:\n" -#: pg_backup_archiver.c:1707 +#: pg_backup_archiver.c:1787 #, c-format msgid "Error while FINALIZING:\n" msgstr "ë’· 마무리 작업 중 오류:\n" -#: pg_backup_archiver.c:1712 +#: pg_backup_archiver.c:1792 #, c-format msgid "Error from TOC entry %d; %u %u %s %s %s\n" msgstr "%d TOC 항목ì—서 오류발견; %u %u %s %s %s\n" -#: pg_backup_archiver.c:1785 +#: pg_backup_archiver.c:1865 #, c-format msgid "bad dumpId\n" msgstr "ìž˜ëª»ëœ dumpID\n" -#: pg_backup_archiver.c:1806 +#: pg_backup_archiver.c:1886 #, c-format msgid "bad table dumpId for TABLE DATA item\n" msgstr "TABLE DATA ì•„ì´í…œì— 대한 ìž˜ëª»ëœ í…Œì´ë¸” dumpId\n" -#: pg_backup_archiver.c:1898 +#: pg_backup_archiver.c:1978 #, c-format msgid "unexpected data offset flag %d\n" msgstr "예ìƒì¹˜ 못한 ìžë£Œ 옵셋 플래그 %d\n" -#: pg_backup_archiver.c:1911 +#: pg_backup_archiver.c:1991 #, c-format msgid "file offset in dump file is too large\n" msgstr "ë¤í”„ 파ì¼ì—서 íŒŒì¼ ì˜µì…‹ ê°’ì´ ë„ˆë¬´ í½ë‹ˆë‹¤\n" -#: pg_backup_archiver.c:2024 +#: pg_backup_archiver.c:2104 #, c-format msgid "attempting to ascertain archive format\n" msgstr "ì•„ì¹´ì´ë¸Œ í¬ë©§ì„ 결정합니다\n" -#: pg_backup_archiver.c:2050 pg_backup_archiver.c:2060 +#: pg_backup_archiver.c:2130 pg_backup_archiver.c:2140 #, c-format msgid "directory name too long: \"%s\"\n" msgstr "디렉터리 ì´ë¦„ì´ ë„ˆë¬´ 긺: \"%s\"\n" -#: pg_backup_archiver.c:2068 +#: pg_backup_archiver.c:2148 #, c-format msgid "" "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not " "exist)\n" msgstr "\"%s\" 디렉터리가 ì•Œë§žì€ ì•„ì¹´ì´ë¸Œìš©ì´ 아님 (\"toc.dat\" 파ì¼ì´ ì—†ìŒ)\n" -#: pg_backup_archiver.c:2076 pg_backup_custom.c:181 pg_backup_custom.c:770 -#: pg_backup_directory.c:214 pg_backup_directory.c:399 +#: pg_backup_archiver.c:2156 pg_backup_custom.c:177 pg_backup_custom.c:770 +#: pg_backup_directory.c:209 pg_backup_directory.c:396 #, c-format msgid "could not open input file \"%s\": %s\n" msgstr "\"%s\" ìž…ë ¥ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:2084 pg_backup_custom.c:188 +#: pg_backup_archiver.c:2164 pg_backup_custom.c:184 #, c-format msgid "could not open input file: %s\n" msgstr "ìž…ë ¥ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:2091 +#: pg_backup_archiver.c:2171 #, c-format msgid "could not read input file: %s\n" msgstr "ìž…ë ¥ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:2093 +#: pg_backup_archiver.c:2173 #, c-format msgid "input file is too short (read %lu, expected 5)\n" msgstr "ìž…ë ¥ 파ì¼ì´ 너무 짧습니다 (%lu ì½ì—ˆìŒ, 예ìƒì¹˜ 5)\n" -#: pg_backup_archiver.c:2176 +#: pg_backup_archiver.c:2258 #, c-format msgid "input file appears to be a text format dump. Please use psql.\n" msgstr "ìž…ë ¥ 파ì¼ì€ ì¼ë°˜ í…스트 ë¤í”„ 파ì¼ìž…니다. psql ëª…ë ¹ì„ ì‚¬ìš©í•˜ì„¸ìš”.\n" -#: pg_backup_archiver.c:2182 +#: pg_backup_archiver.c:2264 #, c-format msgid "input file does not appear to be a valid archive (too short?)\n" msgstr "ìž…ë ¥ 파ì¼ì—서 타당한 ì•„ì¹´ì´ë¸Œë¥¼ ì°¾ì„ ìˆ˜ 없습니다(너무 ì§§ì€ì§€?)\n" -#: pg_backup_archiver.c:2188 +#: pg_backup_archiver.c:2270 #, c-format msgid "input file does not appear to be a valid archive\n" msgstr "ìž…ë ¥ 파ì¼ì—서 타당한 ì•„ì¹´ì´ë¸Œë¥¼ ì°¾ì„ ìˆ˜ 없습니다\n" -#: pg_backup_archiver.c:2208 +#: pg_backup_archiver.c:2290 #, c-format msgid "could not close input file: %s\n" msgstr "ìž…ë ¥ 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_archiver.c:2225 +#: pg_backup_archiver.c:2308 #, c-format msgid "allocating AH for %s, format %d\n" msgstr "%s 위한 AH를 할당하는 중, í¬ë©§ %d\n" -#: pg_backup_archiver.c:2330 +#: pg_backup_archiver.c:2409 #, c-format msgid "unrecognized file format \"%d\"\n" msgstr "알 수 없는 íŒŒì¼ í¬ë©§: \"%d\"\n" -#: pg_backup_archiver.c:2486 +#: pg_backup_archiver.c:2464 pg_backup_archiver.c:4308 +#, c-format +msgid "finished item %d %s %s\n" +msgstr "%d %s %s 항목 마침\n" + +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4321 +#, c-format +msgid "worker process failed: exit code %d\n" +msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ 실패: 종료 코드 %d\n" + +#: pg_backup_archiver.c:2588 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" msgstr "%d ID í•­ëª©ì€ ë²”ìœ„ë¥¼ ë²—ì–´ë‚¬ìŒ -- TOC ì •ë³´ê°€ ì†ìƒëœ 듯 합니다\n" -#: pg_backup_archiver.c:2602 +#: pg_backup_archiver.c:2704 #, c-format msgid "read TOC entry %d (ID %d) for %s %s\n" msgstr "%d TOC 항목 (%d ID) ì½ê¸°, 해당개체: %s %s\n" -#: pg_backup_archiver.c:2636 +#: pg_backup_archiver.c:2738 #, c-format msgid "unrecognized encoding \"%s\"\n" msgstr "알 수 없는 ì¸ì½”딩: \"%s\"\n" -#: pg_backup_archiver.c:2641 +#: pg_backup_archiver.c:2743 #, c-format msgid "invalid ENCODING item: %s\n" msgstr "ìž˜ëª»ëœ ENCODING 항목: %s\n" -#: pg_backup_archiver.c:2659 +#: pg_backup_archiver.c:2761 #, c-format msgid "invalid STDSTRINGS item: %s\n" msgstr "ìž˜ëª»ëœ STDSTRINGS 항목: %s\n" -#: pg_backup_archiver.c:2674 +#: pg_backup_archiver.c:2776 #, c-format msgid "schema \"%s\" not found\n" msgstr "\"%s\" 스키마를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:2681 +#: pg_backup_archiver.c:2783 #, c-format msgid "table \"%s\" not found\n" msgstr "\"%s\" í…Œì´ë¸”ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:2688 +#: pg_backup_archiver.c:2790 #, c-format msgid "index \"%s\" not found\n" msgstr "\"%s\" ì¸ë±ìŠ¤ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:2695 +#: pg_backup_archiver.c:2797 #, c-format msgid "function \"%s\" not found\n" msgstr "\"%s\" 함수를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:2702 +#: pg_backup_archiver.c:2804 #, c-format msgid "trigger \"%s\" not found\n" msgstr "\"%s\" 트리거를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_archiver.c:2934 +#: pg_backup_archiver.c:3082 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "\"%s\" 사용ìžë¡œ 세션 사용ìžë¥¼ 지정할 수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:2966 +#: pg_backup_archiver.c:3114 #, c-format msgid "could not set default_with_oids: %s" msgstr "default_with_oids 설정 í•  수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:3111 +#: pg_backup_archiver.c:3259 #, c-format msgid "could not set search_path to \"%s\": %s" msgstr "search_path를 \"%s\"(으)로 지정할 수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:3173 +#: pg_backup_archiver.c:3321 #, c-format msgid "could not set default_tablespace to %s: %s" msgstr "default_tablespace로 %s(으)로 지정할 수 ì—†ìŒ: %s" -#: pg_backup_archiver.c:3260 pg_backup_archiver.c:3454 +#: pg_backup_archiver.c:3411 pg_backup_archiver.c:3604 #, c-format -msgid "WARNING: don't know how to set owner for object type %s\n" +msgid "WARNING: don't know how to set owner for object type \"%s\"\n" msgstr "경고: %s ê°œì²´ì˜ ì†Œìœ ì£¼ë¥¼ 지정할 수 없습니다\n" -#: pg_backup_archiver.c:3536 +#: pg_backup_archiver.c:3694 #, c-format msgid "did not find magic string in file header\n" msgstr "íŒŒì¼ í—¤ë”ì—서 ë§¤ì§ ë¬¸ìžì—´ì„ 찾지 못했습니다\n" -#: pg_backup_archiver.c:3549 +#: pg_backup_archiver.c:3707 #, c-format msgid "unsupported version (%d.%d) in file header\n" msgstr "íŒŒì¼ í—¤ë”ì— ìžˆëŠ” %d.%d ë²„ì „ì€ ì§€ì›ë˜ì§€ 않습니다\n" -#: pg_backup_archiver.c:3554 +#: pg_backup_archiver.c:3712 #, c-format msgid "sanity check on integer size (%lu) failed\n" msgstr "정수 í¬ê¸° (%lu) 안전성 검사 실패\n" -#: pg_backup_archiver.c:3558 +#: pg_backup_archiver.c:3716 #, c-format msgid "" "WARNING: archive was made on a machine with larger integers, some operations " @@ -839,12 +858,12 @@ msgstr "" "경고: ì´ ì•„ì¹´ì´ë¸ŒëŠ” í° ì •ìˆ˜ë¥¼ ì§€ì›í•˜ëŠ” 시스템ì—서 만들어졌습니다. 그래서 몇 " "ë™ìž‘ì´ ì‹¤íŒ¨í•  ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤\n" -#: pg_backup_archiver.c:3568 +#: pg_backup_archiver.c:3726 #, c-format msgid "expected format (%d) differs from format found in file (%d)\n" msgstr "예ìƒë˜ëŠ” í¬ë©§ (%d)와 ë°œê²¬ëœ íŒŒì¼ í¬ë©§ (%d)ì´ ì„œë¡œ 틀립니다\n" -#: pg_backup_archiver.c:3584 +#: pg_backup_archiver.c:3742 #, c-format msgid "" "WARNING: archive is compressed, but this installation does not support " @@ -853,112 +872,97 @@ msgstr "" "경고: ì•„ì¹´ì´ë¸ŒëŠ” ì••ì¶•ë˜ì–´ìžˆì§€ë§Œ, ì´ í”„ë¡œê·¸ëž¨ì—서는 ì••ì¶•ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 못합니" "다 -- ì´ ì•ˆì— ìžˆëŠ” ìžë£Œë¥¼ ëª¨ë‘ ì‚¬ìš©í•  수 없습니다.\n" -#: pg_backup_archiver.c:3602 +#: pg_backup_archiver.c:3760 #, c-format msgid "WARNING: invalid creation date in header\n" msgstr "경고: í—¤ë”ì— ìž˜ëª»ëœ ìƒì„± 날짜가 있ìŒ\n" -#: pg_backup_archiver.c:3677 +#: pg_backup_archiver.c:3833 #, c-format msgid "entering restore_toc_entries_prefork\n" msgstr "restore_toc_entries_prefork 시작 함\n" -#: pg_backup_archiver.c:3721 +#: pg_backup_archiver.c:3897 #, c-format msgid "processing item %d %s %s\n" msgstr "%d %s %s í•­ëª©ì„ ì²˜ë¦¬í•˜ëŠ” 중\n" -#: pg_backup_archiver.c:3773 +#: pg_backup_archiver.c:3951 #, c-format msgid "entering restore_toc_entries_parallel\n" msgstr "restore_toc_entries_parallelì„ ì‹œìž‘í•˜ëŠ” 중\n" -#: pg_backup_archiver.c:3821 +#: pg_backup_archiver.c:3972 #, c-format msgid "entering main parallel loop\n" msgstr "기본 병렬 루프를 시작하는 중\n" -#: pg_backup_archiver.c:3832 +#: pg_backup_archiver.c:3983 #, c-format msgid "skipping item %d %s %s\n" msgstr "%d %s %s í•­ëª©ì„ ê±´ë„ˆë›°ëŠ” 중\n" -#: pg_backup_archiver.c:3842 +#: pg_backup_archiver.c:3993 #, c-format msgid "launching item %d %s %s\n" msgstr "%d %s %s í•­ëª©ì„ ì‹œìž‘í•˜ëŠ” 중\n" -#: pg_backup_archiver.c:3898 +#: pg_backup_archiver.c:4047 #, c-format msgid "finished main parallel loop\n" msgstr "기본 병렬 루프 마침\n" -#: pg_backup_archiver.c:3907 +#: pg_backup_archiver.c:4065 #, c-format msgid "entering restore_toc_entries_postfork\n" msgstr "restore_toc_entries_postfork 시작하는 중\n" -#: pg_backup_archiver.c:3926 +#: pg_backup_archiver.c:4085 #, c-format msgid "processing missed item %d %s %s\n" msgstr "누ë½ëœ 항목 %d %s %sì„(를) 처리하는 중\n" -#: pg_backup_archiver.c:4075 +#: pg_backup_archiver.c:4264 #, c-format msgid "no item ready\n" msgstr "ì¤€ë¹„ëœ í•­ëª©ì´ ì—†ìŒ\n" -#: pg_backup_archiver.c:4123 -#, c-format -msgid "could not find slot of finished worker\n" -msgstr "ì™„ë£Œëœ ìž‘ì—…ìžì˜ ìŠ¬ë¡¯ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" - -#: pg_backup_archiver.c:4125 -#, c-format -msgid "finished item %d %s %s\n" -msgstr "%d %s %s 항목 마침\n" - -#: pg_backup_archiver.c:4138 -#, c-format -msgid "worker process failed: exit code %d\n" -msgstr "ìž‘ì—…ìž í”„ë¡œì„¸ìŠ¤ 실패: 종료 코드 %d\n" - -#: pg_backup_archiver.c:4300 +#: pg_backup_archiver.c:4483 #, c-format msgid "transferring dependency %d -> %d to %d\n" msgstr "%d -> %d - %d(으)로 종ì†ì„± 변경 중\n" -#: pg_backup_archiver.c:4373 +#: pg_backup_archiver.c:4556 #, c-format msgid "reducing dependencies for %d\n" msgstr "%dì— ëŒ€í•œ 종ì†ì„±ì„ 줄ì´ëŠ” 중\n" -#: pg_backup_archiver.c:4412 +#: pg_backup_archiver.c:4608 #, c-format msgid "table \"%s\" could not be created, will not restore its data\n" msgstr "\"%s\" í…Œì´ë¸”ì„ ë§Œë“¤ 수 없어, 해당 ìžë£ŒëŠ” ë³µì›ë˜ì§€ ì•Šì„ ê²ƒìž…ë‹ˆë‹¤\n" #. translator: this is a module name -#: pg_backup_custom.c:94 +#: pg_backup_custom.c:93 msgid "custom archiver" msgstr "custom ì•„ì¹´ì´ë²„" -#: pg_backup_custom.c:384 pg_backup_null.c:150 +#: pg_backup_custom.c:380 pg_backup_null.c:150 #, c-format msgid "invalid OID for large object\n" msgstr "ìž˜ëª»ëœ large objectìš© OID\n" -#: pg_backup_custom.c:455 +#: pg_backup_custom.c:451 #, c-format msgid "unrecognized data block type (%d) while searching archive\n" msgstr "ì•„ì¹´ì´ë¸Œ 검색하는 ë™ì•ˆ 알 수 없는 ìžë£Œ 블럭 형태(%d)를 발견함\n" -#: pg_backup_custom.c:466 +#: pg_backup_custom.c:462 #, c-format msgid "error during file seek: %s\n" msgstr "íŒŒì¼ seek 작업하는 ë„중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤: %s\n" -#: pg_backup_custom.c:476 +#: pg_backup_custom.c:472 #, c-format msgid "" "could not find block ID %d in archive -- possibly due to out-of-order " @@ -968,7 +972,7 @@ msgstr "" "ì•„ì¹´ì´ë¸Œì—서 ë¸”ë¡ ID %dì„(를) 찾지 못했습니다. ë³µì› ìš”ì²­ì´ ìž˜ëª»ëœ ê²ƒ 같습니" "다. ì•„ì¹´ì´ë¸Œì˜ ë°ì´í„° ì˜¤í”„ì…‹ì´ ë¶€ì¡±í•˜ì—¬ ìš”ì²­ì„ ì²˜ë¦¬í•  수 없습니다.\n" -#: pg_backup_custom.c:481 +#: pg_backup_custom.c:477 #, c-format msgid "" "could not find block ID %d in archive -- possibly due to out-of-order " @@ -977,30 +981,30 @@ msgstr "" "ì•„ì¹´ì´ë¸Œì—서 ë¸”ë¡ ID %dì„(를) 찾지 못했습니다. ë³µì› ìš”ì²­ì´ ìž˜ëª»ëœ ê²ƒ 같습니" "다. ìž…ë ¥ 파ì¼ì„ 검색할 수 없으므로 ìš”ì²­ì„ ì²˜ë¦¬í•  수 없습니다.\n" -#: pg_backup_custom.c:486 +#: pg_backup_custom.c:482 #, c-format msgid "could not find block ID %d in archive -- possibly corrupt archive\n" msgstr "" "ì•„ì¹´ì´ë¸Œì—서 ë¸”ë¡ ID %dì„(를) ì°¾ì„ ìˆ˜ 없습니다. ì•„ì¹´ì´ë¸Œê°€ ì†ìƒëœ 것 같습니" "다.\n" -#: pg_backup_custom.c:493 +#: pg_backup_custom.c:489 #, c-format msgid "found unexpected block ID (%d) when reading data -- expected %d\n" msgstr "ìžë£Œë¥¼ ì½ëŠ” ë™ì•ˆ 예ìƒì¹˜ 못한 ID (%d) ë°œê²¬ë¨ -- 예ìƒê°’ %d\n" -#: pg_backup_custom.c:507 +#: pg_backup_custom.c:503 #, c-format msgid "unrecognized data block type %d while restoring archive\n" msgstr "ì•„ì¹´ì´ë¸Œ ë³µì›í•˜ëŠ” 중ì—, 알 수 없는 ìžë£Œ 블럭 형태 %d 를 발견함\n" -#: pg_backup_custom.c:709 pg_backup_custom.c:759 pg_backup_custom.c:908 -#: pg_backup_tar.c:1088 +#: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 +#: pg_backup_tar.c:1102 #, c-format msgid "could not determine seek position in archive file: %s\n" msgstr "ì•„ì¹´ì´ë¸Œ 파ì¼ì—서 검색 위치를 확ì¸í•  수 ì—†ìŒ: %s\n" -#: pg_backup_custom.c:727 pg_backup_custom.c:764 +#: pg_backup_custom.c:723 pg_backup_custom.c:764 #, c-format msgid "could not close archive file: %s\n" msgstr "ìžë£Œ 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" @@ -1018,7 +1022,8 @@ msgstr "표준 ìž…ë ¥ì„ ì´ìš©í•œ 병렬 ë³µì› ìž‘ì—…ì€ ì§€ì›í•˜ì§€ 않습 #: pg_backup_custom.c:755 #, c-format msgid "parallel restore from non-seekable file is not supported\n" -msgstr "시작 위치를 ìž„ì˜ë¡œ 지정할 수 없는 파ì¼ë¡œëŠ” 병렬 ë³µì› ìž‘ì—…ì„ í•  수 없습니다.\n" +msgstr "" +"시작 위치를 ìž„ì˜ë¡œ 지정할 수 없는 파ì¼ë¡œëŠ” 병렬 ë³µì› ìž‘ì—…ì„ í•  수 없습니다.\n" #: pg_backup_custom.c:774 #, c-format @@ -1030,295 +1035,296 @@ msgstr "ì•„ì¹´ì´ë¸Œ 파ì¼ì—서 검색 위치를 설정할 수 ì—†ìŒ: %s\n" msgid "compressor active\n" msgstr "압축기 사용\n" -#: pg_backup_custom.c:912 +#: pg_backup_custom.c:848 #, c-format msgid "WARNING: ftell mismatch with expected position -- ftell used\n" msgstr "경고: ftell ê°’ê³¼, 예ìƒë˜ëŠ” ìœ„ì¹˜ê°’ì´ í‹€ë¦¼ -- ftell ê°’ì´ ì‚¬ìš©ë¨\n" #. translator: this is a module name -#: pg_backup_db.c:31 +#: pg_backup_db.c:29 msgid "archiver (db)" msgstr "ë¤í”„ë°›ì„ DB" -#: pg_backup_db.c:47 +#: pg_backup_db.c:45 #, c-format msgid "could not get server_version from libpq\n" msgstr "libpqì—서 server_verion ê°’ì„ êµ¬í•  수 ì—†ìŒ\n" -#: pg_backup_db.c:58 pg_dumpall.c:2067 +#: pg_backup_db.c:56 pg_dumpall.c:2057 #, c-format msgid "server version: %s; %s version: %s\n" msgstr "서버 버전: %s; %s 버전: %s\n" -#: pg_backup_db.c:60 pg_dumpall.c:2069 +#: pg_backup_db.c:58 pg_dumpall.c:2059 #, c-format msgid "aborting because of server version mismatch\n" msgstr "서버 ë²„ì „ì´ ì¼ì¹˜í•˜ì§€ 않아 중단하는 중\n" -#: pg_backup_db.c:149 +#: pg_backup_db.c:148 #, c-format msgid "connecting to database \"%s\" as user \"%s\"\n" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ë¥¼ \"%s\" 사용ìžë¡œ ì ‘ì†í•©ë‹ˆë‹¤\n" -#: pg_backup_db.c:156 pg_backup_db.c:208 pg_backup_db.c:270 pg_backup_db.c:312 -#: pg_dumpall.c:1893 pg_dumpall.c:2005 +#: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 +#: pg_dumpall.c:1880 pg_dumpall.c:1994 msgid "Password: " msgstr "암호: " -#: pg_backup_db.c:189 +#: pg_backup_db.c:187 #, c-format msgid "failed to reconnect to database\n" msgstr "ë°ì´í„°ë² ì´ìФ ìž¬ì ‘ì† ì‹¤íŒ¨\n" -#: pg_backup_db.c:194 +#: pg_backup_db.c:192 #, c-format msgid "could not reconnect to database: %s" msgstr "ë°ì´í„°ë² ì´ìФ 재접ì†ì„ í•  수 ì—†ìŒ: %s" -#: pg_backup_db.c:210 +#: pg_backup_db.c:208 #, c-format msgid "connection needs password\n" msgstr "연결하려면 암호 í•„ìš”\n" -#: pg_backup_db.c:264 +#: pg_backup_db.c:259 #, c-format msgid "already connected to a database\n" msgstr "ë°ì´í„°ë² ì´ìŠ¤ì— ì´ë¯¸ ì ‘ì†í•´ 있ìŒ\n" -#: pg_backup_db.c:304 +#: pg_backup_db.c:298 #, c-format msgid "failed to connect to database\n" msgstr "ë°ì´í„°ë² ì´ìФ ì ‘ì† ì‹¤íŒ¨\n" -#: pg_backup_db.c:321 +#: pg_backup_db.c:314 #, c-format msgid "connection to database \"%s\" failed: %s" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì† í•  수 ì—†ìŒ: %s" -#: pg_backup_db.c:391 +#: pg_backup_db.c:382 #, c-format msgid "%s" msgstr "%s" -#: pg_backup_db.c:398 +#: pg_backup_db.c:389 #, c-format msgid "query failed: %s" msgstr "쿼리 실패: %s" -#: pg_backup_db.c:400 +#: pg_backup_db.c:391 #, c-format msgid "query was: %s\n" msgstr "사용한 쿼리: %s\n" -#: pg_backup_db.c:442 +#: pg_backup_db.c:433 #, c-format msgid "query returned %d row instead of one: %s\n" msgid_plural "query returned %d rows instead of one: %s\n" msgstr[0] "쿼리ì—서 한 개가 아닌 %dê°œì˜ í–‰ì„ ë°˜í™˜: %s\n" -#: pg_backup_db.c:487 +#: pg_backup_db.c:469 #, c-format msgid "%s: %s Command was: %s\n" msgstr "%s: %s ì‚¬ìš©ëœ ëª…ë ¹: %s\n" -#: pg_backup_db.c:543 pg_backup_db.c:617 pg_backup_db.c:624 +#: pg_backup_db.c:525 pg_backup_db.c:599 pg_backup_db.c:606 msgid "could not execute query" msgstr "쿼리를 실행 í•  수 ì—†ìŒ" -#: pg_backup_db.c:596 +#: pg_backup_db.c:578 #, c-format msgid "error returned by PQputCopyData: %s" msgstr "PQputCopyDataì— ì˜í•´ì„œ 오류가 반환ë˜ì—ˆìŒ: %s" -#: pg_backup_db.c:645 +#: pg_backup_db.c:627 #, c-format msgid "error returned by PQputCopyEnd: %s" msgstr "PQputCopyEndì— ì˜í•´ì„œ 오류가 반환ë˜ì—ˆìŒ: %s" -#: pg_backup_db.c:651 +#: pg_backup_db.c:633 #, c-format msgid "COPY failed for table \"%s\": %s" msgstr "\"%s\" í…Œì´ë¸”ì„ ìœ„í•œ COPY 실패: %s" -#: pg_backup_db.c:657 pg_dump.c:1787 +#: pg_backup_db.c:639 pg_dump.c:1841 #, c-format msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" msgstr "경고: \"%s\" í…Œì´ë¸” COPY 작업 중 ìž˜ëª»ëœ ë¶€ê°€ 결과가 있ìŒ\n" -#: pg_backup_db.c:669 +#: pg_backup_db.c:651 msgid "could not start database transaction" msgstr "ë°ì´í„°ë² ì´ìФ íŠ¸ëžœìž­ì…˜ì„ ì‹œìž‘í•  수 ì—†ìŒ" -#: pg_backup_db.c:677 +#: pg_backup_db.c:659 msgid "could not commit database transaction" msgstr "ë°ì´í„°ë² ì´ìФ íŠ¸ëžœìž­ì…˜ì„ commit í•  수 ì—†ìŒ" #. translator: this is a module name -#: pg_backup_directory.c:64 +#: pg_backup_directory.c:65 msgid "directory archiver" msgstr "디렉터리 ì•„ì¹´ì´ë²„" -#: pg_backup_directory.c:162 +#: pg_backup_directory.c:157 #, c-format msgid "no output directory specified\n" msgstr "ìžë£Œê°€ ì €ìž¥ë  ë””ë ‰í„°ë¦¬ë¥¼ 지정하지 않았ìŒ\n" -#: pg_backup_directory.c:191 +#: pg_backup_directory.c:186 #, c-format msgid "could not read directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" -#: pg_backup_directory.c:195 +#: pg_backup_directory.c:190 #, c-format msgid "could not close directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_directory.c:201 +#: pg_backup_directory.c:196 #, c-format msgid "could not create directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 만들 수 ì—†ìŒ: %s\n" -#: pg_backup_directory.c:412 +#: pg_backup_directory.c:355 pg_backup_directory.c:495 +#: pg_backup_directory.c:525 +#, c-format +msgid "could not write to output file: %s\n" +msgstr "출력 파ì¼ì„ 쓸 수 ì—†ìŒ: %s\n" + +#: pg_backup_directory.c:409 #, c-format msgid "could not close data file: %s\n" msgstr "ìžë£Œ 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_directory.c:453 +#: pg_backup_directory.c:450 #, c-format msgid "could not open large object TOC file \"%s\" for input: %s\n" msgstr "입력용 large object TOC 파ì¼(\"%s\")ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_directory.c:464 +#: pg_backup_directory.c:461 #, c-format msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" msgstr "large object TOC 파ì¼(\"%s\")ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: \"%s\"\n" -#: pg_backup_directory.c:473 +#: pg_backup_directory.c:470 #, c-format msgid "error reading large object TOC file \"%s\"\n" msgstr "large object TOC 파ì¼(\"%s\")ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_directory.c:477 +#: pg_backup_directory.c:474 #, c-format msgid "could not close large object TOC file \"%s\": %s\n" msgstr "large object TOC 파ì¼(\"%s\")ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_backup_directory.c:684 +#: pg_backup_directory.c:690 #, c-format msgid "could not write to blobs TOC file\n" msgstr "blob TOC 파ì¼ì— 쓸 수 ì—†ìŒ\n" -#: pg_backup_directory.c:716 +#: pg_backup_directory.c:722 #, c-format msgid "file name too long: \"%s\"\n" msgstr "íŒŒì¼ ì´ë¦„ì´ ë„ˆë¬´ 긺: \"%s\"\n" -#: pg_backup_directory.c:802 -#, c-format -msgid "error during backup\n" -msgstr "백업 중 오류\n" - #: pg_backup_null.c:75 #, c-format msgid "this format cannot be read\n" msgstr "ì´ íŒŒì¼ í˜•íƒœëŠ” ì½ì„ 수 ì—†ìŒ\n" #. translator: this is a module name -#: pg_backup_tar.c:102 +#: pg_backup_tar.c:103 msgid "tar archiver" msgstr "tar ì•„ì¹´ì´ë²„" -#: pg_backup_tar.c:183 +#: pg_backup_tar.c:181 #, c-format msgid "could not open TOC file \"%s\" for output: %s\n" msgstr "출력용 TOC íŒŒì¼ \"%s\"ì„(를) ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_tar.c:191 +#: pg_backup_tar.c:189 #, c-format msgid "could not open TOC file for output: %s\n" msgstr "출력용 TOC 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_tar.c:212 pg_backup_tar.c:368 +#: pg_backup_tar.c:210 pg_backup_tar.c:366 #, c-format msgid "compression is not supported by tar archive format\n" msgstr "tar 출력 í¬ë©§ì—서 ì••ì¶• ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ\n" -#: pg_backup_tar.c:220 +#: pg_backup_tar.c:218 #, c-format msgid "could not open TOC file \"%s\" for input: %s\n" msgstr "입력용 TOC 파ì¼(\"%s\")ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_tar.c:227 +#: pg_backup_tar.c:225 #, c-format msgid "could not open TOC file for input: %s\n" msgstr "입력용 TOC 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_tar.c:354 +#: pg_backup_tar.c:352 #, c-format msgid "could not find file \"%s\" in archive\n" msgstr "ì•„ì¹´ì´ë¸Œì—서 \"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_tar.c:420 +#: pg_backup_tar.c:418 #, c-format msgid "could not generate temporary file name: %s\n" msgstr "임시 íŒŒì¼ ì´ë¦„ì„ ì§“ì§€ 못했습니다: %s\n" -#: pg_backup_tar.c:431 +#: pg_backup_tar.c:429 #, c-format msgid "could not open temporary file\n" msgstr "임시 파ì¼ì„ ì—´ 수 ì—†ìŒ\n" -#: pg_backup_tar.c:458 +#: pg_backup_tar.c:456 #, c-format msgid "could not close tar member\n" msgstr "tar 맴버를 ë‹«ì§€ 못했습니다\n" -#: pg_backup_tar.c:571 +#: pg_backup_tar.c:581 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "ë‚´ë¶€ 오류 - tarReadRaw()ì—서 th, fh 둘다 지정하지 않았ìŒ\n" -#: pg_backup_tar.c:694 +#: pg_backup_tar.c:704 #, c-format msgid "unexpected COPY statement syntax: \"%s\"\n" msgstr "COPY 구문 오류: \"%s\"\n" -#: pg_backup_tar.c:960 +#: pg_backup_tar.c:974 #, c-format msgid "invalid OID for large object (%u)\n" msgstr "ìž˜ëª»ëœ large object OID: %u\n" -#: pg_backup_tar.c:1104 +#: pg_backup_tar.c:1118 #, c-format msgid "could not close temporary file: %s\n" msgstr "임시 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_backup_tar.c:1114 +#: pg_backup_tar.c:1128 #, c-format msgid "actual file length (%s) does not match expected (%s)\n" msgstr "실재 íŒŒì¼ ê¸¸ì´(%s)와 예ìƒë˜ëŠ” ê°’(%s)ì´ í‹€ë¦½ë‹ˆë‹¤\n" -#: pg_backup_tar.c:1151 +#: pg_backup_tar.c:1165 #, c-format msgid "moving from position %s to next member at file position %s\n" msgstr "%s 위치ì—서 ë‹¤ìŒ ë§´ë²„ë¡œ ì´ë™í•©ë‹ˆë‹¤, 해당 íŒŒì¼ ìœ„ì¹˜ %s\n" -#: pg_backup_tar.c:1162 +#: pg_backup_tar.c:1176 #, c-format msgid "now at file position %s\n" msgstr "새로 ì´ë™ëœ íŒŒì¼ ìœ„ì¹˜: %s\n" -#: pg_backup_tar.c:1171 pg_backup_tar.c:1201 +#: pg_backup_tar.c:1185 pg_backup_tar.c:1215 #, c-format msgid "could not find header for file \"%s\" in tar archive\n" msgstr "tar ì•„ì¹´ì´ë¸Œì—서 \"%s\" 파ì¼ì„ 위한 í—¤ë”를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_backup_tar.c:1185 +#: pg_backup_tar.c:1199 #, c-format msgid "skipping tar member %s\n" msgstr "%s tar 맴버는 건너ëœë‹ˆë‹¤\n" -#: pg_backup_tar.c:1189 +#: pg_backup_tar.c:1203 #, c-format msgid "" "restoring data out of order is not supported in this archive format: \"%s\" " @@ -1327,18 +1333,18 @@ msgstr "" "순서를 넘어서는 ìžë£Œ ë¤í”„ ìž‘ì—…ì€ ì´ ì•„ì¹´ì´ë¸Œ í¬ë©§ì—서는 ì§€ì›í•˜ì§€ 않습니다: " "\"%s\" 요구ë˜ì—ˆì§€ë§Œ, ì´ ì•„ì¹´ì´ë¸Œ 파ì¼ì—서는 \"%s\" ì „ì— ì˜µë‹ˆë‹¤.\n" -#: pg_backup_tar.c:1235 +#: pg_backup_tar.c:1249 #, c-format msgid "incomplete tar header found (%lu byte)\n" msgid_plural "incomplete tar header found (%lu bytes)\n" msgstr[0] "불완전한 tar í—¤ë”ê°€ 있ìŒ(%luë°”ì´íЏ)\n" -#: pg_backup_tar.c:1276 +#: pg_backup_tar.c:1290 #, c-format msgid "TOC Entry %s at %s (length %s, checksum %d)\n" msgstr "TOC Entry %s at %s (length %s, checksum %d)\n" -#: pg_backup_tar.c:1287 +#: pg_backup_tar.c:1301 #, c-format msgid "" "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" @@ -1349,9 +1355,9 @@ msgstr "%s ì•ˆì— ì†ìƒëœ tar í—¤ë” ë°œê²¬ (예ìƒì¹˜ %d, ê³„ì‚°ëœ ê°’ %d), msgid "%s: unrecognized section name: \"%s\"\n" msgstr "%s: ìž˜ëª»ëœ ì„¹ì…˜ ì´ë¦„: \"%s\"\n" -#: pg_backup_utils.c:56 pg_dump.c:533 pg_dump.c:550 pg_dumpall.c:299 -#: pg_dumpall.c:309 pg_dumpall.c:319 pg_dumpall.c:328 pg_dumpall.c:344 -#: pg_dumpall.c:402 pg_restore.c:279 pg_restore.c:295 pg_restore.c:307 +#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:313 +#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 +#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "보다 ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\"\n" @@ -1361,43 +1367,43 @@ msgstr "보다 ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\"\n" msgid "out of on_exit_nicely slots\n" msgstr "on_exit_nicely 슬롯 범위 벗어남\n" -#: pg_dump.c:503 +#: pg_dump.c:511 #, c-format msgid "compression level must be in range 0..9\n" msgstr "ì••ì¶• 수위는 0부터 9까지 지정할 수 있습니다.\n" -#: pg_dump.c:548 pg_dumpall.c:307 pg_restore.c:293 +#: pg_dump.c:560 pg_dumpall.c:321 pg_restore.c:297 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë“¤ (시작 \"%s\")\n" -#: pg_dump.c:561 +#: pg_dump.c:581 #, c-format msgid "options -s/--schema-only and -a/--data-only cannot be used together\n" msgstr "-s/--schema-only ë° -a/--data-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dump.c:567 +#: pg_dump.c:587 #, c-format msgid "options -c/--clean and -a/--data-only cannot be used together\n" msgstr "-c/--clean ë° -a/--data-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dump.c:573 +#: pg_dump.c:593 #, c-format msgid "" "options --inserts/--column-inserts and -o/--oids cannot be used together\n" msgstr "--inserts/--column-inserts ë° -o/--oids ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dump.c:574 +#: pg_dump.c:594 #, c-format msgid "(The INSERT command cannot set OIDs.)\n" msgstr "(INSERT 명령으로는 OID ê°’ì„ ìž…ë ¥í•  수 ì—†ìŒ.)\n" -#: pg_dump.c:579 +#: pg_dump.c:599 #, c-format msgid "option --if-exists requires option -c/--clean\n" msgstr "--if-exists ì˜µì…˜ì€ -c/--clean 옵션과 함께 사용해야 함\n" -#: pg_dump.c:601 +#: pg_dump.c:621 #, c-format msgid "" "WARNING: requested compression not available in this installation -- archive " @@ -1406,17 +1412,17 @@ msgstr "" "경고: 요청한 ì••ì¶• ê¸°ëŠ¥ì€ ì´ ì„¤ì¹˜íŒì—서는 사용할 수 없습니다 -- ìžë£Œ 파ì¼ì€ ì••" "ì¶• ì—†ì´ ë§Œë“¤ì–´ì§ˆ 것입니다\n" -#: pg_dump.c:616 +#: pg_dump.c:636 #, c-format -msgid "%s: invalid number of parallel jobs\n" -msgstr "%s: ìž˜ëª»ëœ ë³‘ë ¬ 작업 수\n" +msgid "invalid number of parallel jobs\n" +msgstr "ìž˜ëª»ëœ ë³‘ë ¬ 작업 수\n" -#: pg_dump.c:620 +#: pg_dump.c:640 #, c-format msgid "parallel backup only supported by the directory format\n" msgstr "병렬 ë°±ì—…ì€ ë””ë ‰í„°ë¦¬ 기반 ì¶œë ¥ì¼ ë•Œë§Œ 사용할 수 없습니다.\n" -#: pg_dump.c:677 +#: pg_dump.c:695 #, c-format msgid "" "Synchronized snapshots are not supported by this server version.\n" @@ -1427,27 +1433,27 @@ msgstr "" "ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì´ í•„ìš” 없다면, --no-synchronized-snapshots\n" "ì˜µì…˜ì„ ì§€ì •í•´ì„œ ë¤í”„í•  수 있습니다.\n" -#: pg_dump.c:684 +#: pg_dump.c:702 #, c-format msgid "Exported snapshots are not supported by this server version.\n" msgstr "ì´ ì„œë²„ëŠ” exported snapshot를 ì§€ì›í•˜ì§€ 않ìŒ.\n" -#: pg_dump.c:695 +#: pg_dump.c:716 #, c-format msgid "last built-in OID is %u\n" msgstr "마지막 내장 OID는 %u\n" -#: pg_dump.c:705 +#: pg_dump.c:725 #, c-format msgid "no matching schemas were found\n" msgstr "ì¡°ê±´ì— ë§žëŠ” 스키마가 없습니다\n" -#: pg_dump.c:719 +#: pg_dump.c:739 #, c-format msgid "no matching tables were found\n" msgstr "ì¡°ê±´ì— ë§žëŠ” í…Œì´ë¸”ì´ ì—†ìŠµë‹ˆë‹¤\n" -#: pg_dump.c:878 +#: pg_dump.c:913 #, c-format msgid "" "%s dumps a database as a text file or to other formats.\n" @@ -1457,17 +1463,17 @@ msgstr "" "다른 í˜•íƒœì˜ íŒŒì¼ë¡œ ë¤í”„합니다.\n" "\n" -#: pg_dump.c:879 pg_dumpall.c:547 pg_restore.c:437 +#: pg_dump.c:914 pg_dumpall.c:575 pg_restore.c:449 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: pg_dump.c:880 +#: pg_dump.c:915 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [옵션]... [DBì´ë¦„]\n" -#: pg_dump.c:882 pg_dumpall.c:550 pg_restore.c:440 +#: pg_dump.c:917 pg_dumpall.c:578 pg_restore.c:452 #, c-format msgid "" "\n" @@ -1476,12 +1482,12 @@ msgstr "" "\n" "ì¼ë°˜ 옵션들:\n" -#: pg_dump.c:883 +#: pg_dump.c:918 #, c-format msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=파ì¼ì´ë¦„ 출력 íŒŒì¼ ë˜ëŠ” 디렉터리 ì´ë¦„\n" -#: pg_dump.c:884 +#: pg_dump.c:919 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1490,40 +1496,47 @@ msgstr "" " -F, --format=c|d|t|p 출력 íŒŒì¼ í˜•ì‹(ì‚¬ìš©ìž ì§€ì •, 디렉터리, tar,\n" " ì¼ë°˜ í…스트(초기값))\n" -#: pg_dump.c:886 +#: pg_dump.c:921 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=개수 ë¤í”„ ìž‘ì—…ì„ ë³‘ë ¬ 처리 함\n" -#: pg_dump.c:887 +#: pg_dump.c:922 pg_dumpall.c:580 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose 작업 ë‚´ì—­ì„ ìžì„¸ížˆ ë´„\n" -#: pg_dump.c:888 pg_dumpall.c:552 +#: pg_dump.c:923 pg_dumpall.c:581 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: pg_dump.c:889 +#: pg_dump.c:924 #, c-format msgid "" " -Z, --compress=0-9 compression level for compressed formats\n" msgstr " -Z, --compress=0-9 출력 ìžë£Œ ì••ì¶• 수위\n" -#: pg_dump.c:890 pg_dumpall.c:553 +#: pg_dump.c:925 pg_dumpall.c:582 #, c-format msgid "" " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr "" " --lock-wait-timeout=ì´ˆ í…Œì´ë¸” 잠금 시 지정한 ì´ˆë§Œí¼ ê¸°ë‹¤ë¦° 후 실패\n" -#: pg_dump.c:891 pg_dumpall.c:554 +#: pg_dump.c:926 pg_dumpall.c:605 +#, c-format +msgid "" +" --no-sync do not wait for changes to be written safely " +"to disk\n" +msgstr " --no-sync fsync 작업 ìƒëžµ\n" + +#: pg_dump.c:927 pg_dumpall.c:583 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: pg_dump.c:893 pg_dumpall.c:555 +#: pg_dump.c:929 pg_dumpall.c:584 #, c-format msgid "" "\n" @@ -1532,17 +1545,22 @@ msgstr "" "\n" "출력 ë‚´ìš©ì„ ë‹¤ë£¨ëŠ” 옵션들:\n" -#: pg_dump.c:894 pg_dumpall.c:556 +#: pg_dump.c:930 pg_dumpall.c:585 #, c-format msgid " -a, --data-only dump only the data, not the schema\n" msgstr " -a, --data-only 스키마 빼고 ìžë£Œë§Œ ë¤í”„\n" -#: pg_dump.c:895 +#: pg_dump.c:931 #, c-format msgid " -b, --blobs include large objects in dump\n" msgstr " -b, --blobs Large Objectë“¤ë„ í•¨ê»˜ ë¤í”„함\n" -#: pg_dump.c:896 pg_restore.c:451 +#: pg_dump.c:932 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs Large Objectë“¤ì„ ì œì™¸í•˜ê³  ë¤í”„함\n" + +#: pg_dump.c:933 pg_restore.c:463 #, c-format msgid "" " -c, --clean clean (drop) database objects before " @@ -1551,34 +1569,34 @@ msgstr "" " -c, --clean 다시 만들기 ì „ì— ë°ì´í„°ë² ì´ìФ 개체 지우기(ì‚­" "ì œ)\n" -#: pg_dump.c:897 +#: pg_dump.c:934 #, c-format msgid "" " -C, --create include commands to create database in dump\n" msgstr "" " -C, --create ë°ì´í„°ë² ì´ìФ 만드는 ëª…ë ¹êµ¬ë¬¸ë„ í¬í•¨ì‹œí‚´\n" -#: pg_dump.c:898 +#: pg_dump.c:935 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=ì¸ì½”딩 지정한 ì¸ì½”딩으로 ìžë£Œë¥¼ ë¤í”„ 함\n" -#: pg_dump.c:899 +#: pg_dump.c:936 #, c-format msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" msgstr " -n, --schema=SCHEMA 지정한 SCHEMA들 ìžë£Œë§Œ ë¤í”„\n" -#: pg_dump.c:900 +#: pg_dump.c:937 #, c-format msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" msgstr " -N, --exclude-schema=SCHEMA 지정한 SCHEMA들만 빼고 ëª¨ë‘ ë¤í”„\n" -#: pg_dump.c:901 pg_dumpall.c:559 +#: pg_dump.c:938 pg_dumpall.c:588 #, c-format msgid " -o, --oids include OIDs in dump\n" msgstr " -o, --oids OID í¬í•¨í•´ì„œ ë¤í”„\n" -#: pg_dump.c:902 +#: pg_dump.c:939 #, c-format msgid "" " -O, --no-owner skip restoration of object ownership in\n" @@ -1587,12 +1605,12 @@ msgstr "" " -O, --no-owner ì¼ë°˜ í…스트 형ì‹ì—서\n" " 개체 소유권 ë³µì› ê±´ë„ˆë›°ê¸°\n" -#: pg_dump.c:904 pg_dumpall.c:562 +#: pg_dump.c:941 pg_dumpall.c:591 #, c-format msgid " -s, --schema-only dump only the schema, no data\n" msgstr " -s, --schema-only ìžë£Œêµ¬ì¡°(스키마)ë§Œ ë¤í”„\n" -#: pg_dump.c:905 +#: pg_dump.c:942 #, c-format msgid "" " -S, --superuser=NAME superuser user name to use in plain-text " @@ -1601,28 +1619,28 @@ msgstr "" " -S, --superuser=NAME ì¼ë°˜ í…스트 형ì‹ì—서 사용할 슈í¼ìœ ì € ì‚¬ìš©ìž ì´" "름\n" -#: pg_dump.c:906 +#: pg_dump.c:943 #, c-format msgid " -t, --table=TABLE dump the named table(s) only\n" msgstr " -t, --table=TABLE 지정한 ì´ë¦„ì˜ í…Œì´ë¸”들만 ë¤í”„\n" -#: pg_dump.c:907 +#: pg_dump.c:944 #, c-format msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" msgstr " -T, --exclude-table=TABLE 지정한 í…Œì´ë¸”들만 빼고 ë¤í”„\n" -#: pg_dump.c:908 pg_dumpall.c:565 +#: pg_dump.c:945 pg_dumpall.c:594 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr "" " -x, --no-privileges ì ‘ê·¼ 권한 (grant/revoke) 정보는 ë¤í”„ 안 함\n" -#: pg_dump.c:909 pg_dumpall.c:566 +#: pg_dump.c:946 pg_dumpall.c:595 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade 업그레ì´ë“œ 유틸리티 ì „ìš©\n" -#: pg_dump.c:910 pg_dumpall.c:567 +#: pg_dump.c:947 pg_dumpall.c:596 #, c-format msgid "" " --column-inserts dump data as INSERT commands with column " @@ -1630,7 +1648,7 @@ msgid "" msgstr "" " --column-inserts 칼럼 ì´ë¦„ê³¼ 함께 INSERT 명령으로 ìžë£Œ ë¤í”„\n" -#: pg_dump.c:911 pg_dumpall.c:568 +#: pg_dump.c:948 pg_dumpall.c:597 #, c-format msgid "" " --disable-dollar-quoting disable dollar quoting, use SQL standard " @@ -1638,13 +1656,13 @@ msgid "" msgstr "" " --disable-dollar-quoting $ ì¸ìš© 구문 사용안함, SQL 표준 따옴표 사용\n" -#: pg_dump.c:912 pg_dumpall.c:569 pg_restore.c:467 +#: pg_dump.c:949 pg_dumpall.c:598 pg_restore.c:480 #, c-format msgid "" " --disable-triggers disable triggers during data-only restore\n" msgstr " --disable-triggers ìžë£Œë§Œ ë³µì›í•  때 트리거 ì‚¬ìš©ì„ ì•ˆí•¨\n" -#: pg_dump.c:913 +#: pg_dump.c:950 #, c-format msgid "" " --enable-row-security enable row security (dump only content user " @@ -1654,30 +1672,40 @@ msgstr "" " --enable-row-security 로우 보안 활성화 (현재 작업ìžê°€ 접근할 수\n" " 있는 ìžë£Œë§Œ ë¤í”„ 함)\n" -#: pg_dump.c:915 +#: pg_dump.c:952 #, c-format msgid "" " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" msgstr " --exclude-table-data=í…Œì´ë¸” 해당 í…Œì´ë¸” ìžë£ŒëŠ” ë¤í”„ 안함\n" -#: pg_dump.c:916 pg_dumpall.c:570 pg_restore.c:469 +#: pg_dump.c:953 pg_dumpall.c:599 pg_restore.c:482 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists ê°ì²´ ì‚­ì œ 시 IF EXISTS 구문 사용\n" -#: pg_dump.c:917 pg_dumpall.c:571 +#: pg_dump.c:954 pg_dumpall.c:600 #, c-format msgid "" " --inserts dump data as INSERT commands, rather than " "COPY\n" msgstr " --inserts COPY 대신 INSERT 명령으로 ìžë£Œ ë¤í”„\n" -#: pg_dump.c:918 pg_dumpall.c:572 +#: pg_dump.c:955 pg_dumpall.c:601 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications 발행 정보는 ë¤í”„하지 않ìŒ\n" + +#: pg_dump.c:956 pg_dumpall.c:603 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels 보안 ë¼ë²¨ í• ë‹¹ì„ ë¤í”„ 하지 않ìŒ\n" -#: pg_dump.c:919 +#: pg_dump.c:957 pg_dumpall.c:604 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions êµ¬ë… ì •ë³´ëŠ” ë¤í”„하지 않ìŒ\n" + +#: pg_dump.c:958 #, c-format msgid "" " --no-synchronized-snapshots do not use synchronized snapshots in parallel " @@ -1685,24 +1713,24 @@ msgid "" msgstr "" " --no-synchronized-snapshots 병렬 작업ì—서 스냅샷 ì¼ê´€ì„±ì„ 맞추지 않ìŒ\n" -#: pg_dump.c:920 pg_dumpall.c:573 +#: pg_dump.c:959 pg_dumpall.c:606 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces í…Œì´ë¸”스페ì´ìФ í• ë‹¹ì„ ë¤í”„하지 않ìŒ\n" -#: pg_dump.c:921 pg_dumpall.c:574 +#: pg_dump.c:960 pg_dumpall.c:607 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data 언로그드 í…Œì´ë¸” ìžë£ŒëŠ” ë¤í”„하지 않ìŒ\n" -#: pg_dump.c:922 pg_dumpall.c:575 +#: pg_dump.c:961 pg_dumpall.c:608 #, c-format msgid "" " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr "" " --quote-all-identifiers 예약어가 ì•„ë‹ˆì—¬ë„ ëª¨ë“  ì‹ë³„ìžëŠ” 따옴표를 씀\n" -#: pg_dump.c:923 +#: pg_dump.c:962 #, c-format msgid "" " --section=SECTION dump named section (pre-data, data, or post-" @@ -1710,7 +1738,7 @@ msgid "" msgstr "" " --section=SECTION 해당 섹션(pre-data, data, post-data)ë§Œ ë¤í”„\n" -#: pg_dump.c:924 +#: pg_dump.c:963 #, c-format msgid "" " --serializable-deferrable wait until the dump can run without " @@ -1719,22 +1747,23 @@ msgstr "" " --serializable-deferrable ìžë£Œ ì •í•©ì„±ì„ ë³´ìž¥í•˜ê¸° 위해 ë¤í”„ 작업ì„\n" " ì§ë ¬í™” 가능한 트랜잭션으로 처리 함\n" -#: pg_dump.c:925 +#: pg_dump.c:964 #, c-format msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT 지정한 ìŠ¤ëƒ…ìƒ·ì„ ë¤í”„ 함\n" -#: pg_dump.c:926 pg_restore.c:475 +#: pg_dump.c:965 pg_restore.c:490 #, c-format msgid "" " --strict-names require table and/or schema include patterns " "to\n" " match at least one entity each\n" msgstr "" -" --strict-names í…Œì´ë¸”ì´ë‚˜ 스키마를 ì§€ì •í–ˆì„ ë•Œ ê·¸ íŒ¨í„´ì— ë§žëŠ”\n" +" --strict-names í…Œì´ë¸”ì´ë‚˜ 스키마를 ì§€ì •í–ˆì„ ë•Œ ê·¸ íŒ¨í„´ì— ë§ž" +"는\n" " ê°ì²´ê°€ ì ì–´ë„ 하나 ì´ìƒ 있어야 함\n" -#: pg_dump.c:928 pg_dumpall.c:576 pg_restore.c:477 +#: pg_dump.c:967 pg_dumpall.c:609 pg_restore.c:492 #, c-format msgid "" " --use-set-session-authorization\n" @@ -1747,7 +1776,7 @@ msgstr "" "명령\n" " 대신 사용하여 소유권 설정\n" -#: pg_dump.c:932 pg_dumpall.c:580 pg_restore.c:481 +#: pg_dump.c:971 pg_dumpall.c:613 pg_restore.c:496 #, c-format msgid "" "\n" @@ -1756,45 +1785,45 @@ msgstr "" "\n" "ì—°ê²° 옵션들:\n" -#: pg_dump.c:933 +#: pg_dump.c:972 #, c-format msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=DBNAME ë¤í”„í•  ë°ì´í„°ë² ì´ìФ\n" -#: pg_dump.c:934 pg_dumpall.c:582 pg_restore.c:482 +#: pg_dump.c:973 pg_dumpall.c:615 pg_restore.c:497 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=HOSTNAME ì ‘ì†í•  ë°ì´í„°ë² ì´ìФ 서버 ë˜ëŠ” 소켓 디렉터리\n" -#: pg_dump.c:935 pg_dumpall.c:584 pg_restore.c:483 +#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:498 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT ë°ì´í„°ë² ì´ìФ ì„œë²„ì˜ í¬íЏ 번호\n" -#: pg_dump.c:936 pg_dumpall.c:585 pg_restore.c:484 +#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:499 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAME ì—°ê²°í•  ë°ì´í„°ë² ì´ìФ 사용ìž\n" -#: pg_dump.c:937 pg_dumpall.c:586 pg_restore.c:485 +#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:500 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password 암호 프롬프트 표시 안 함\n" -#: pg_dump.c:938 pg_dumpall.c:587 pg_restore.c:486 +#: pg_dump.c:977 pg_dumpall.c:620 pg_restore.c:501 #, c-format msgid "" " -W, --password force password prompt (should happen " "automatically)\n" msgstr " -W, --password 암호 ìž…ë ¥ 프롬프트 ë³´ìž„(ìžë™ìœ¼ë¡œ 처리함)\n" -#: pg_dump.c:939 pg_dumpall.c:588 +#: pg_dump.c:978 pg_dumpall.c:621 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLENAME ë¤í”„ ì „ì— SET ROLE 수행\n" -#: pg_dump.c:941 +#: pg_dump.c:980 #, c-format msgid "" "\n" @@ -1807,186 +1836,227 @@ msgstr "" "사용합니다.\n" "\n" -#: pg_dump.c:943 pg_dumpall.c:592 pg_restore.c:493 +#: pg_dump.c:982 pg_dumpall.c:625 pg_restore.c:508 #, c-format msgid "Report bugs to .\n" msgstr "오류보고: .\n" -#: pg_dump.c:960 +#: pg_dump.c:999 #, c-format msgid "invalid client encoding \"%s\" specified\n" msgstr "í´ë¼ì´ì–¸íЏ ì¸ì½”딩 ê°’ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤: \"%s\"\n" -#: pg_dump.c:1102 +#: pg_dump.c:1136 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server " +"version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" "synchronized snapshots.\n" msgstr "" -"대기 서버ì—서는 ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 ì—†ìŒ.\n" +"ì´ ì„œë²„ 버전ì—서는 대기 서버ì—서 ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 ì—†ìŒ.\n" "ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì´ í•„ìš” 없다면, --no-synchronized-snapshots\n" "ì˜µì…˜ì„ ì§€ì •í•´ì„œ ë¤í”„í•  수 있습니다.\n" -#: pg_dump.c:1171 +#: pg_dump.c:1205 #, c-format msgid "invalid output format \"%s\" specified\n" msgstr "\"%s\" ê°’ì€ ìž˜ëª»ëœ ì¶œë ¥ íŒŒì¼ í˜•íƒœìž…ë‹ˆë‹¤.\n" -#: pg_dump.c:1194 +#: pg_dump.c:1243 #, c-format -msgid "server version must be at least 7.3 to use schema selection switches\n" -msgstr "스키마 ì„ íƒ ì˜µì…˜ì„ ì‚¬ìš©í•˜ë ¤ë©´ 서버 ë²„ì „ì´ 7.3 ì´ìƒì´ì–´ì•¼í•©ë‹ˆë‹¤\n" +msgid "no matching schemas were found for pattern \"%s\"\n" +msgstr "\"%s\" 검색 ì¡°ê±´ì— ë§Œì¡±í•˜ëŠ” 스키마가 없습니다\n" -#: pg_dump.c:1212 pg_dump.c:1265 +#: pg_dump.c:1297 #, c-format msgid "no matching tables were found for pattern \"%s\"\n" msgstr "\"%s\" 검색 ì¡°ê±´ì— ë§Œì¡±í•˜ëŠ” í…Œì´ë¸”ì´ ì—†ìŠµë‹ˆë‹¤\n" -#: pg_dump.c:1644 +#: pg_dump.c:1701 #, c-format msgid "dumping contents of table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì˜ ë‚´ìš© ë¤í”„ 중\n" -#: pg_dump.c:1768 +#: pg_dump.c:1822 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" msgstr "\"%s\" í…Œì´ë¸” ë‚´ìš©ì„ ë¤í”„하면서 오류 ë°œìƒ: PQgetCopyData() 실패.\n" -#: pg_dump.c:1769 pg_dump.c:1779 +#: pg_dump.c:1823 pg_dump.c:1833 #, c-format msgid "Error message from server: %s" msgstr "서버ì—서 보낸 오류 메시지: %s" -#: pg_dump.c:1770 pg_dump.c:1780 +#: pg_dump.c:1824 pg_dump.c:1834 #, c-format msgid "The command was: %s\n" msgstr "ì‚¬ìš©ëœ ëª…ë ¹: %s\n" -#: pg_dump.c:1778 +#: pg_dump.c:1832 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" msgstr "\"%s\" í…Œì´ë¸” ë‚´ìš©ì„ ë¤í”„하면서 오류 ë°œìƒ: PQgetResult() 실패.\n" -#: pg_dump.c:2427 +#: pg_dump.c:2481 #, c-format msgid "saving database definition\n" msgstr "ë°ì´í„°ë² ì´ìФ 구성정보를 저장중입니다\n" -#: pg_dump.c:2760 +#: pg_dump.c:2787 #, c-format msgid "saving encoding = %s\n" msgstr "ì¸ì½”딩 = %s 저장중\n" -#: pg_dump.c:2787 +#: pg_dump.c:2814 #, c-format msgid "saving standard_conforming_strings = %s\n" msgstr "standard_conforming_strings = %s 저장함\n" -#: pg_dump.c:2827 +#: pg_dump.c:2854 #, c-format msgid "reading large objects\n" msgstr "large object ì½ëŠ” 중\n" -#: pg_dump.c:3013 +#: pg_dump.c:3049 #, c-format msgid "saving large objects\n" msgstr "large objectë“¤ì„ ì €ìž¥ 중입니다\n" -#: pg_dump.c:3060 +#: pg_dump.c:3094 #, c-format msgid "error reading large object %u: %s" msgstr "%u large object ì½ëŠ” 중 오류: %s" -#: pg_dump.c:3112 +#: pg_dump.c:3147 #, c-format msgid "reading row security enabled for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì„ ìœ„í•œ 로우 보안 활성화를 ì½ëŠ” 중\n" -#: pg_dump.c:3143 +#: pg_dump.c:3179 #, c-format msgid "reading policies for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì„ ìœ„í•œ ì •ì±… ì½ëŠ” 중\n" -#: pg_dump.c:3276 +#: pg_dump.c:3329 +#, c-format +msgid "unexpected policy command type: %c\n" +msgstr "예ìƒì¹˜ 못한 ì •ì±… 명령 형태: %c\n" + +#: pg_dump.c:3445 #, c-format -msgid "unexpected policy command type: \"%s\"\n" -msgstr "예ìƒì¹˜ 못한 ì •ì±… 명령 형태: \"%s\"\n" +msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" +msgstr "WARNING: \"%s\" 구ë…ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:3495 +#: pg_dump.c:3575 +#, c-format +msgid "reading publication membership for table \"%s.%s\"\n" +msgstr "\"%s.%s\" í…Œì´ë¸”ì„ ìœ„í•œ 발행 ë§µë²„ì‰½ì„ ì½ëŠ” 중\n" + +#: pg_dump.c:3722 +#, c-format +msgid "" +"WARNING: subscriptions not dumped because current user is not a superuser\n" +msgstr "" +"경고: 현재 사용ìžê°€ 슈í¼ìœ ì €ê°€ 아니기 ë•Œë¬¸ì— ì„œë¸ŒìŠ¤í¬ë¦½ì…˜ë“¤ì€ ë¤í”„하지 못했" +"ìŒ\n" + +#: pg_dump.c:3776 +#, c-format +msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" +msgstr "WARNING: \"%s\" 구ë…ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" + +#: pg_dump.c:3820 +#, c-format +msgid "WARNING: could not parse subpublications array\n" +msgstr "경고: êµ¬ë… ë°°ì—´ì„ ë¶„ì„í•  수 ì—†ìŒ\n" + +#: pg_dump.c:4053 #, c-format msgid "could not find parent extension for %s\n" msgstr "%s ê°ì²´ì™€ ê´€ë ¨ëœ ìƒìœ„ 확장 ê¸°ëŠ¥ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_dump.c:3663 +#: pg_dump.c:4207 #, c-format msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" msgstr "경고: \"%s\" ìŠ¤í‚¤ë§ˆì˜ ì†Œìœ ì£¼ê°€ 바르지 않습니다\n" -#: pg_dump.c:3706 +#: pg_dump.c:4230 #, c-format msgid "schema with OID %u does not exist\n" msgstr "OIDê°€ %u ì¸ ìŠ¤í‚¤ë§ˆê°€ 없습니다.\n" -#: pg_dump.c:4121 +#: pg_dump.c:4561 #, c-format msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" msgstr "경고: \"%s\" ìžë£Œí˜•ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:4235 +#: pg_dump.c:4649 #, c-format msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" msgstr "경고: \"%s\" ì—°ì‚°ìžì˜ 소유주가 ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:4580 +#: pg_dump.c:4963 #, c-format msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" msgstr "WARNING: \"%s\" ì—°ì‚°ìž í´ëž˜ìŠ¤ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:4671 +#: pg_dump.c:5050 #, c-format msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" msgstr "경고: \"%s\" ì—°ì‚°ìž ë¶€ë¥˜ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:4872 +#: pg_dump.c:5217 #, c-format msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" msgstr "WARNING: \"%s\" 집계 í•¨ìˆ˜ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:5137 +#: pg_dump.c:5476 #, c-format msgid "WARNING: owner of function \"%s\" appears to be invalid\n" msgstr "WARNING: \"%s\" í•¨ìˆ˜ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:5999 +#: pg_dump.c:6258 #, c-format msgid "WARNING: owner of table \"%s\" appears to be invalid\n" msgstr "WARNING: \"%s\" í…Œì´ë¸”ì˜ ì†Œìœ ì£¼ê°€ ì ë‹¹í•˜ì§€ 않습니다.\n" -#: pg_dump.c:6165 +#: pg_dump.c:6300 pg_dump.c:16539 +#, c-format +msgid "" +"failed sanity check, parent table with OID %u of sequence with OID %u not " +"found\n" +msgstr "ì˜ì¡´ì„± 검사 실패, 부모 í…Œì´ë¸” OID %u ì—†ìŒ. 해당 시퀀스 개체 OID %u\n" + +#: pg_dump.c:6431 #, c-format msgid "reading indexes for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì—서 사용하는 ì¸ë±ìŠ¤ë“¤ì„ ì½ëŠ” 중\n" -#: pg_dump.c:6533 +#: pg_dump.c:6712 +#, c-format +msgid "reading extended statistics for table \"%s.%s\"\n" +msgstr "\"%s.%s\" í…Œì´ë¸”ìš© í™•ìž¥ëœ í†µê³„ì •ë³´ë¥¼ ì½ëŠ” 중\n" + +#: pg_dump.c:6795 #, c-format msgid "reading foreign key constraints for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì—서 사용하는 참조키 ì œì•½ì¡°ê±´ì„ ì½ëŠ” 중\n" -#: pg_dump.c:6779 +#: pg_dump.c:7019 #, c-format msgid "" -"failed sanity check, parent table OID %u of pg_rewrite entry OID %u not " -"found\n" +"failed sanity check, parent table with OID %u of pg_rewrite entry with OID " +"%u not found\n" msgstr "" "ì˜ì¡´ì„± 검사 실패, 부모 í…Œì´ë¸” OID %u ì—†ìŒ. 해당 pg_rewrite 개체 OID %u\n" -#: pg_dump.c:6873 +#: pg_dump.c:7103 #, c-format msgid "reading triggers for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì—서 사용하는 íŠ¸ë¦¬ê±°ë“¤ì„ ì½ëŠ” 중\n" -#: pg_dump.c:7038 +#: pg_dump.c:7241 #, c-format msgid "" "query produced null referenced table name for foreign key trigger \"%s\" on " @@ -1995,94 +2065,99 @@ msgstr "" "쿼리가 참조테ì´ë¸” ì •ë³´ê°€ 없는 \"%s\" 참조키 트리거를 \"%s\" (해당 OID: %u) í…Œ" "ì´ë¸”ì—서 만들었습니다.\n" -#: pg_dump.c:7693 +#: pg_dump.c:7813 #, c-format msgid "finding the columns and types of table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì˜ ì¹¼ëŸ¼ê³¼ ìžë£Œí˜•ì„ ì°¾ëŠ” 중\n" -#: pg_dump.c:7872 +#: pg_dump.c:7978 #, c-format msgid "invalid column numbering in table \"%s\"\n" msgstr "\"%s\" í…Œì´ë¸”ì— ë§¤ê²¨ì ¸ 있는 ì—´ 번호가 잘못ë˜ì—ˆìŠµë‹ˆë‹¤\n" -#: pg_dump.c:7906 +#: pg_dump.c:8014 #, c-format msgid "finding default expressions of table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì—서 default 표현들 찾는 중\n" -#: pg_dump.c:7959 +#: pg_dump.c:8037 #, c-format msgid "invalid adnum value %d for table \"%s\"\n" msgstr "ì ë‹¹í•˜ì§€ 않는 adnum ê°’: %d, 해당 í…Œì´ë¸” \"%s\"\n" -#: pg_dump.c:8031 +#: pg_dump.c:8103 #, c-format msgid "finding check constraints for table \"%s.%s\"\n" msgstr "\"%s.%s\" í…Œì´ë¸”ì—서 사용하는 ì²´í¬ ì œì•½ ì¡°ê±´ì„ ì°¾ëŠ” 중\n" -#: pg_dump.c:8127 +#: pg_dump.c:8152 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d\n" msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" msgstr[0] "%d 제약 ì¡°ê±´ 확ì¸ì´ \"%s\" í…Œì´ë¸”ì— í•„ìš”í•œë° %dì´(ê°€) 있ìŒ\n" -#: pg_dump.c:8131 +#: pg_dump.c:8156 #, c-format msgid "(The system catalogs might be corrupted.)\n" msgstr "(시스템 카탈로그가 ì†ìƒë˜ì—ˆëŠ” 것 같습니다)\n" -#: pg_dump.c:9663 +#: pg_dump.c:9714 #, c-format msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" msgstr "경고: \"%s\" ìžë£Œí˜•ì˜ typtypeê°€ 잘못 ë˜ì–´ 있ìŒ\n" -#: pg_dump.c:11205 +#: pg_dump.c:11143 #, c-format msgid "WARNING: bogus value in proargmodes array\n" msgstr "경고: proargmodes ë°°ì—´ì— ìž˜ëª»ëœ ê°’ì´ ìžˆìŒ\n" -#: pg_dump.c:11583 +#: pg_dump.c:11469 #, c-format msgid "WARNING: could not parse proallargtypes array\n" msgstr "경고: proallargtypes ë°°ì—´ì„ ë¶„ì„í•  수 없습니다\n" -#: pg_dump.c:11599 +#: pg_dump.c:11485 #, c-format msgid "WARNING: could not parse proargmodes array\n" msgstr "경고: proargmodes ë°°ì—´ì„ ë¶„ì„í•  수 없습니다\n" -#: pg_dump.c:11613 +#: pg_dump.c:11499 #, c-format msgid "WARNING: could not parse proargnames array\n" msgstr "경고: proargnames ë°°ì—´ì„ ë¶„ì„í•  수 없습니다\n" -#: pg_dump.c:11624 +#: pg_dump.c:11510 #, c-format msgid "WARNING: could not parse proconfig array\n" msgstr "경고: proconfig ë°°ì—´ì„ êµ¬ë¬¸ ë¶„ì„í•  수 ì—†ìŒ\n" -#: pg_dump.c:11695 +#: pg_dump.c:11581 #, c-format msgid "unrecognized provolatile value for function \"%s\"\n" msgstr "\"%s\" í•¨ìˆ˜ì˜ provolatile ê°’ì´ ìž˜ëª» ë˜ì—ˆìŠµë‹ˆë‹¤\n" -#: pg_dump.c:11739 pg_dump.c:13782 +#: pg_dump.c:11625 pg_dump.c:13623 #, c-format msgid "unrecognized proparallel value for function \"%s\"\n" msgstr "\"%s\" í•¨ìˆ˜ì˜ proparallel ê°’ì´ ìž˜ëª» ë˜ì—ˆìŠµë‹ˆë‹¤\n" -#: pg_dump.c:11891 +#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 +#, c-format +msgid "could not find function definition for function with OID %u\n" +msgstr "%u OID í•¨ìˆ˜ì— ëŒ€í•œ 함수 ì •ì˜ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" + +#: pg_dump.c:11778 #, c-format msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" msgstr "" "경고: pg_cast.castfunc ë˜ëŠ” pg_cast.castmethod í•„ë“œì— ìž˜ëª»ëœ ê°’ì´ ìžˆìŒ\n" -#: pg_dump.c:11894 +#: pg_dump.c:11781 #, c-format msgid "WARNING: bogus value in pg_cast.castmethod field\n" msgstr "경고: pg_cast.castmethod í•„ë“œì— ìž˜ëª»ëœ ê°’ì´ ìžˆìŒ\n" -#: pg_dump.c:11982 +#: pg_dump.c:11871 #, c-format msgid "" "WARNING: bogus transform definition, at least one of trffromsql and trftosql " @@ -2090,27 +2165,27 @@ msgid "" msgstr "" "경고: ìž˜ëª»ëœ ì „ì†¡ ì •ì˜, trffromsql ë˜ëŠ” trftosql 중 하나는 비어 있으면 안ë¨\n" -#: pg_dump.c:11999 +#: pg_dump.c:11888 #, c-format msgid "WARNING: bogus value in pg_transform.trffromsql field\n" msgstr "경고: pg_transform.trffromsql í•„ë“œì— ìž˜ëª»ëœ ê°’ì´ ìžˆìŒ\n" -#: pg_dump.c:12020 +#: pg_dump.c:11909 #, c-format msgid "WARNING: bogus value in pg_transform.trftosql field\n" msgstr "경고: pg_transform.trftosql í•„ë“œì— ìž˜ëª»ëœ ê°’ì´ ìžˆìŒ\n" -#: pg_dump.c:12411 -#, c-format -msgid "WARNING: could not find operator with OID %s\n" -msgstr "경고: %s OIDì˜ ì—°ì‚°ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" - -#: pg_dump.c:12475 +#: pg_dump.c:12305 #, c-format msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" msgstr "경고: \"%c\" ìž˜ëª»ëœ ìžë£Œí˜•, 해당 ì ‘ê·¼ 방법: \"%s\"\n" -#: pg_dump.c:13673 +#: pg_dump.c:13086 +#, c-format +msgid "unrecognized collation provider: %s\n" +msgstr "알 수 없는 문ìžì •ë ¬ 제공ìž: %s\n" + +#: pg_dump.c:13533 #, c-format msgid "" "WARNING: aggregate function %s could not be dumped correctly for this " @@ -2119,66 +2194,71 @@ msgstr "" "경고: %s 집계 함수는 ì´ ë°ì´í„°ë² ì´ìФ 버전ì—서는 바르게 ë¤í”„ë˜ì§ˆ 못했습니다; " "무시함\n" -#: pg_dump.c:14545 +#: pg_dump.c:14389 #, c-format msgid "unrecognized object type in default privileges: %d\n" msgstr "기본 ì ‘ê·¼ 권한ì—서 알 수 없는 ê°ì²´í˜•ì´ ìžˆìŒ: %d\n" -#: pg_dump.c:14560 +#: pg_dump.c:14407 #, c-format msgid "could not parse default ACL list (%s)\n" msgstr "기본 ACL ëª©ë¡ (%s)ì„ ë¶„ì„í•  수 ì—†ìŒ\n" -#: pg_dump.c:14631 +#: pg_dump.c:14488 #, c-format msgid "" "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) " "for object \"%s\" (%s)\n" msgstr "" -"GRANT ACL ëª©ë¡ ì´ˆê¸°ê°’ (%s) ë˜ëŠ” REVOKE ACL ëª©ë¡ ì´ˆê¸°ê°’ (%s) " -"ë¶„ì„í•  수 ì—†ìŒ, 해당 ê°ì²´: \"%s\" (%s)\n" +"GRANT ACL ëª©ë¡ ì´ˆê¸°ê°’ (%s) ë˜ëŠ” REVOKE ACL ëª©ë¡ ì´ˆê¸°ê°’ (%s) ë¶„ì„í•  수 ì—†ìŒ, " +"해당 ê°ì²´: \"%s\" (%s)\n" -#: pg_dump.c:14639 +#: pg_dump.c:14496 #, c-format msgid "" "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s" "\" (%s)\n" msgstr "" -"GRANT ACL ëª©ë¡ (%s) ë˜ëŠ” REVOKE ACL ëª©ë¡ (%s) " -"ë¶„ì„í•  수 ì—†ìŒ, 해당 ê°ì²´: \"%s\" (%s)\n" +"GRANT ACL ëª©ë¡ (%s) ë˜ëŠ” REVOKE ACL ëª©ë¡ (%s) ë¶„ì„í•  수 ì—†ìŒ, 해당 ê°ì²´: \"%s" +"\" (%s)\n" -#: pg_dump.c:15123 +#: pg_dump.c:14971 #, c-format msgid "query to obtain definition of view \"%s\" returned no data\n" msgstr "\"%s\" ë·° ì •ì˜ ì •ë³´ê°€ 없습니다\n" -#: pg_dump.c:15126 +#: pg_dump.c:14974 #, c-format msgid "" "query to obtain definition of view \"%s\" returned more than one definition\n" msgstr "\"%s\" ë·° ì •ì˜ ì •ë³´ê°€ 하나 ì´ìƒ 있습니다.\n" -#: pg_dump.c:15133 +#: pg_dump.c:14981 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)\n" msgstr "\"%s\" ë·°ì˜ ì •ì˜ ë‚´ìš©ì´ ë¹„ì–´ìžˆìŠµë‹ˆë‹¤\n" -#: pg_dump.c:15892 +#: pg_dump.c:15210 +#, c-format +msgid "invalid number of parents %d for table \"%s\"\n" +msgstr "ìž˜ëª»ëœ ë¶€ëª¨ 수: %d, 해당 í…Œì´ë¸” \"%s\"\n" + +#: pg_dump.c:15857 #, c-format msgid "invalid column number %d for table \"%s\"\n" msgstr "ìž˜ëª»ëœ ì—´ 번호 %d, 해당 í…Œì´ë¸” \"%s\"\n" -#: pg_dump.c:16021 +#: pg_dump.c:16041 #, c-format msgid "missing index for constraint \"%s\"\n" msgstr "\"%s\" 제약 ì¡°ê±´ì„ ìœ„í•œ ì¸ë±ìŠ¤ê°€ 빠졌습니다\n" -#: pg_dump.c:16224 +#: pg_dump.c:16244 #, c-format msgid "unrecognized constraint type: %c\n" msgstr "알 수 없는 제약 ì¡°ê±´ 종류: %c\n" -#: pg_dump.c:16378 pg_dump.c:16547 +#: pg_dump.c:16381 pg_dump.c:16607 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" msgid_plural "" @@ -2186,22 +2266,17 @@ msgid_plural "" msgstr[0] "" "\"%s\" ì‹œí€€ìŠ¤ì˜ ë°ì´í„°ë¥¼ 가져오기 위한 쿼리ì—서 %dê°œì˜ í–‰ 반환(1ê°œ í•„ìš”)\n" -#: pg_dump.c:16389 -#, c-format -msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" -msgstr "\"%s\" ì‹œí€€ìŠ¤ì˜ ìžë£Œë¥¼ 구하는 쿼리가 \"%s\" ì´ë¦„ì„ ë¦¬í„´í–ˆìŒ\n" - -#: pg_dump.c:16645 +#: pg_dump.c:16705 #, c-format msgid "unexpected tgtype value: %d\n" msgstr "기대ë˜ì§€ ì•Šì€ tgtype ê°’: %d\n" -#: pg_dump.c:16727 +#: pg_dump.c:16779 #, c-format msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" msgstr "ìž˜ëª»ëœ ì¸ìˆ˜ 문ìžì—´ (%s), 해당 트리거 \"%s\", 사용ë˜ëŠ” í…Œì´ë¸” \"%s\"\n" -#: pg_dump.c:16924 +#: pg_dump.c:17010 #, c-format msgid "" "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows " @@ -2209,7 +2284,7 @@ msgid "" msgstr "" "\"%s\" 규칙(\"%s\" í…Œì´ë¸”)ì„(를) 가져오기 위한 쿼리 실패: ìž˜ëª»ëœ í–‰ 수 반환\n" -#: pg_dump.c:17313 +#: pg_dump.c:17405 #, c-format msgid "reading dependency data\n" msgstr "ì˜ì¡´ 관계 ìžë£Œ ì½ëŠ” 중\n" @@ -2220,47 +2295,47 @@ msgid "WARNING: could not parse reloptions array\n" msgstr "경고: reloptions ë°°ì—´ì„ ë¶„ì„í•  수 ì—†ìŒ\n" #. translator: this is a module name -#: pg_dump_sort.c:23 +#: pg_dump_sort.c:25 msgid "sorter" msgstr "sorter" -#: pg_dump_sort.c:491 +#: pg_dump_sort.c:413 #, c-format msgid "invalid dumpId %d\n" msgstr "ìž˜ëª»ëœ dumpId %d\n" -#: pg_dump_sort.c:497 +#: pg_dump_sort.c:419 #, c-format msgid "invalid dependency %d\n" msgstr "ìž˜ëª»ëœ ì˜ì¡´ì„± %d\n" -#: pg_dump_sort.c:730 +#: pg_dump_sort.c:652 #, c-format msgid "could not identify dependency loop\n" msgstr "ì˜ì¡´ 관계를 ì‹ë³„ í•  수 ì—†ìŒ\n" -#: pg_dump_sort.c:1262 +#: pg_dump_sort.c:1175 #, c-format msgid "NOTICE: there are circular foreign-key constraints on this table:\n" msgid_plural "" "NOTICE: there are circular foreign-key constraints among these tables:\n" msgstr[0] "주ì˜: ë‹¤ìŒ ë°ì´ë¸” ê°„ 참조키가 서로 êµì°¨í•˜ê³  있ìŒ:\n" -#: pg_dump_sort.c:1266 pg_dump_sort.c:1286 +#: pg_dump_sort.c:1179 pg_dump_sort.c:1199 #, c-format msgid " %s\n" msgstr " %s\n" -#: pg_dump_sort.c:1267 +#: pg_dump_sort.c:1180 #, c-format msgid "" "You might not be able to restore the dump without using --disable-triggers " "or temporarily dropping the constraints.\n" msgstr "" -"--disable-triggers 옵션으로 ë³µì›í•  수 있습니다. ë˜ëŠ” 임시로 " -"제약 ì¡°ê±´ì„ ì‚­ì œí•˜ê³  ë³µì›í•˜ì„¸ìš”.\n" +"--disable-triggers 옵션으로 ë³µì›í•  수 있습니다. ë˜ëŠ” 임시로 제약 ì¡°ê±´ì„ ì‚­ì œ" +"하고 ë³µì›í•˜ì„¸ìš”.\n" -#: pg_dump_sort.c:1268 +#: pg_dump_sort.c:1181 #, c-format msgid "" "Consider using a full dump instead of a --data-only dump to avoid this " @@ -2268,12 +2343,12 @@ msgid "" msgstr "" "ì´ ë¬¸ì œë¥¼ 피하려면, --data-only ë¤í”„ ëŒ€ì‹ ì— ëª¨ë“  ë¤í”„를 사용하길 권합니다.\n" -#: pg_dump_sort.c:1280 +#: pg_dump_sort.c:1193 #, c-format msgid "WARNING: could not resolve dependency loop among these items:\n" msgstr "경고: ë‹¤ìŒ í•­ëª© ê°„ ì˜ì¡´ 관계를 ë¶„ì„í•  수 ì—†ìŒ:\n" -#: pg_dumpall.c:180 +#: pg_dumpall.c:189 #, c-format msgid "" "The program \"pg_dump\" is needed by %s but was not found in the\n" @@ -2284,7 +2359,7 @@ msgstr "" "있는 ê°™ì€ ë””ë ‰í„°ë¦¬ì—서 ì°¾ì„ ìˆ˜ 없습니다.\n" "설치 ìƒíƒœë¥¼ 살펴 보십시오.\n" -#: pg_dumpall.c:187 +#: pg_dumpall.c:196 #, c-format msgid "" "The program \"pg_dump\" was found by \"%s\"\n" @@ -2295,13 +2370,13 @@ msgstr "" "%s 버전과 서로 틀립니다.\n" "설치 ìƒíƒœë¥¼ 살펴 보십시오.\n" -#: pg_dumpall.c:317 +#: pg_dumpall.c:331 #, c-format msgid "" "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" msgstr "%s: -g/--globals-only ë° -r/--roles-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dumpall.c:326 +#: pg_dumpall.c:340 #, c-format msgid "" "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used " @@ -2309,12 +2384,12 @@ msgid "" msgstr "" "%s: -g/--globals-only ë° -t/--tablespaces-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dumpall.c:335 pg_restore.c:345 +#: pg_dumpall.c:349 pg_restore.c:367 #, c-format msgid "%s: option --if-exists requires option -c/--clean\n" msgstr "%s: --if-exists ì˜µì…˜ì€ -c/--clean 옵션과 함께 사용해야 함\n" -#: pg_dumpall.c:342 +#: pg_dumpall.c:356 #, c-format msgid "" "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used " @@ -2322,12 +2397,12 @@ msgid "" msgstr "" "%s: -r/--roles-only ë° -t/--tablespaces-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_dumpall.c:384 pg_dumpall.c:1994 +#: pg_dumpall.c:412 pg_dumpall.c:1983 #, c-format msgid "%s: could not connect to database \"%s\"\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì†í•  수 ì—†ìŒ\n" -#: pg_dumpall.c:399 +#: pg_dumpall.c:427 #, c-format msgid "" "%s: could not connect to databases \"postgres\" or \"template1\"\n" @@ -2336,12 +2411,12 @@ msgstr "" "%s: \"postgres\" ë˜ëŠ” \"template1\" ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²°í•  수 없습니다.\n" "다른 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 지정하십시오.\n" -#: pg_dumpall.c:416 +#: pg_dumpall.c:444 #, c-format msgid "%s: could not open the output file \"%s\": %s\n" msgstr "%s: 출력 íŒŒì¼ \"%s\"ì„(를) ì—´ 수 ì—†ìŒ: %s\n" -#: pg_dumpall.c:546 +#: pg_dumpall.c:574 #, c-format msgid "" "%s extracts a PostgreSQL database cluster into an SQL script file.\n" @@ -2351,35 +2426,35 @@ msgstr "" "추출하는 프로그램입니다.\n" "\n" -#: pg_dumpall.c:548 +#: pg_dumpall.c:576 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [옵션]...\n" -#: pg_dumpall.c:551 +#: pg_dumpall.c:579 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=파ì¼ì´ë¦„ 출력 íŒŒì¼ ì´ë¦„\n" -#: pg_dumpall.c:557 +#: pg_dumpall.c:586 #, c-format msgid "" " -c, --clean clean (drop) databases before recreating\n" msgstr "" " -c, --clean 다시 만들기 ì „ì— ë°ì´í„°ë² ì´ìФ 지우기(ì‚­ì œ)\n" -#: pg_dumpall.c:558 +#: pg_dumpall.c:587 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr "" " -g, --globals-only ë°ì´í„°ë² ì´ìŠ¤ëŠ” 제외하고 글로벌 개체만 ë¤í”„\n" -#: pg_dumpall.c:560 pg_restore.c:459 +#: pg_dumpall.c:589 pg_restore.c:472 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner 개체 소유권 ë³µì› ê±´ë„ˆë›°ê¸°\n" -#: pg_dumpall.c:561 +#: pg_dumpall.c:590 #, c-format msgid "" " -r, --roles-only dump only roles, no databases or tablespaces\n" @@ -2387,12 +2462,12 @@ msgstr "" " -r, --roles-only ë°ì´í„°ë² ì´ìŠ¤ë‚˜ í…Œì´ë¸”스페ì´ìŠ¤ëŠ” 제외하고 ì—­í• " "ë§Œ ë¤í”„\n" -#: pg_dumpall.c:563 +#: pg_dumpall.c:592 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr " -S, --superuser=NAME ë¤í”„ì— ì‚¬ìš©í•  슈í¼ìœ ì € ì‚¬ìš©ìž ì´ë¦„\n" -#: pg_dumpall.c:564 +#: pg_dumpall.c:593 #, c-format msgid "" " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" @@ -2400,17 +2475,22 @@ msgstr "" " -t, --tablespaces-only ë°ì´í„°ë² ì´ìŠ¤ë‚˜ ì—­í• ì€ ì œì™¸í•˜ê³  í…Œì´ë¸”스페ì´ìФ" "ë§Œ ë¤í”„\n" -#: pg_dumpall.c:581 +#: pg_dumpall.c:602 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " --no-role-passwords 롤용 비밀번호를 ë¤í”„하지 않ìŒ\n" + +#: pg_dumpall.c:614 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=ì ‘ì†ë¬¸ìžì—´ 서버 ì ‘ì† ë¬¸ìžì—´\n" -#: pg_dumpall.c:583 +#: pg_dumpall.c:616 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=DBNAME 대체용 기본 ë°ì´í„°ë² ì´ìФ\n" -#: pg_dumpall.c:590 +#: pg_dumpall.c:623 #, c-format msgid "" "\n" @@ -2424,112 +2504,117 @@ msgstr "" "ì¶œë ¥ì— ì“°ì—¬ì§‘ë‹ˆë‹¤.\n" "\n" -#: pg_dumpall.c:791 +#: pg_dumpall.c:828 #, c-format msgid "%s: role name starting with \"pg_\" skipped (%s)\n" msgstr "%s: 롤 ì´ë¦„ì´ \"pg_\"로 시작함, 무시함: (%s)\n" -#: pg_dumpall.c:1168 +#: pg_dumpall.c:1208 #, c-format msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" msgstr "" "%s: í…Œì´ë¸”스페ì´ìФ ìš© ACL ëª©ë¡ (%s)ì„ ë¶„ì„í•  수 ì—†ìŒ, 해당개체 \"%s\"\n" -#: pg_dumpall.c:1536 +#: pg_dumpall.c:1525 #, c-format msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" msgstr "%s: ë°ì´í„°ë² ì´ìФ ìš© ACL ëª©ë¡ (%s)ì„ ë¶„ì„í•  수 ì—†ìŒ, 해당개체: \"%s\"\n" -#: pg_dumpall.c:1754 +#: pg_dumpall.c:1739 #, c-format msgid "%s: dumping database \"%s\"...\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìФ ë¤í”„ 중...\n" -#: pg_dumpall.c:1778 +#: pg_dumpall.c:1763 #, c-format msgid "%s: pg_dump failed on database \"%s\", exiting\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìФì—서 pg_dump 작업 ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒ, ë냅니다.\n" -#: pg_dumpall.c:1787 +#: pg_dumpall.c:1772 #, c-format msgid "%s: could not re-open the output file \"%s\": %s\n" msgstr "%s: 출력 íŒŒì¼ \"%s\"ì„(를) 다시 ì—´ 수 ì—†ìŒ: %s\n" -#: pg_dumpall.c:1832 +#: pg_dumpall.c:1817 #, c-format msgid "%s: running \"%s\"\n" msgstr "%s: \"%s\" ê°€ë™ì¤‘\n" -#: pg_dumpall.c:2016 +#: pg_dumpall.c:2006 #, c-format msgid "%s: could not connect to database \"%s\": %s\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì†í•  수 ì—†ìŒ: %s\n" -#: pg_dumpall.c:2046 +#: pg_dumpall.c:2036 #, c-format msgid "%s: could not get server version\n" msgstr "%s: 서버 ë²„ì „ì„ ì•Œ 수 ì—†ìŒ\n" -#: pg_dumpall.c:2052 +#: pg_dumpall.c:2042 #, c-format msgid "%s: could not parse server version \"%s\"\n" msgstr "%s: \"%s\" 서버 ë²„ì „ì„ ë¶„ì„í•  수 ì—†ìŒ\n" -#: pg_dumpall.c:2130 pg_dumpall.c:2156 +#: pg_dumpall.c:2118 pg_dumpall.c:2144 #, c-format msgid "%s: executing %s\n" msgstr "%s: %s 실행중\n" -#: pg_dumpall.c:2136 pg_dumpall.c:2162 +#: pg_dumpall.c:2124 pg_dumpall.c:2150 #, c-format msgid "%s: query failed: %s" msgstr "%s: 쿼리 실패: %s" -#: pg_dumpall.c:2138 pg_dumpall.c:2164 +#: pg_dumpall.c:2126 pg_dumpall.c:2152 #, c-format msgid "%s: query was: %s\n" msgstr "%s: 사용한 쿼리: %s\n" -#: pg_restore.c:305 +#: pg_restore.c:309 #, c-format msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" msgstr "%s: -d/--dbname ë° -f/--file ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_restore.c:316 +#: pg_restore.c:320 #, c-format msgid "" "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" msgstr "" "%s: -s/--schema-only 옵션과 -a/--data-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_restore.c:323 +#: pg_restore.c:327 #, c-format msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" msgstr "%s: -c/--clean 옵션과 -a/--data-only ì˜µì…˜ì€ í•¨ê»˜ 사용할 수 ì—†ìŒ\n" -#: pg_restore.c:331 +#: pg_restore.c:334 +#, c-format +msgid "%s: invalid number of parallel jobs\n" +msgstr "%s: ìž˜ëª»ëœ ë³‘ë ¬ 작업 수\n" + +#: pg_restore.c:342 +#, c-format +msgid "%s: maximum number of parallel jobs is %d\n" +msgstr "%s: 병렬 작업 최대수는 %d 입니다.\n" + +#: pg_restore.c:351 #, c-format msgid "%s: cannot specify both --single-transaction and multiple jobs\n" msgstr "%s: --single-transaction ë° ì—¬ëŸ¬ ìž‘ì—…ì„ ëª¨ë‘ ì§€ì •í•  수는 ì—†ìŒ\n" -#: pg_restore.c:372 +#: pg_restore.c:394 #, c-format msgid "" "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" msgstr "" "알 수 없는 ì•„ì¹´ì´ë¸Œ 형ì‹: \"%s\"; 사용할 수 있는 ê°’: \"c\", \"d\", \"t\"\n" -#: pg_restore.c:404 -#, c-format -msgid "%s: maximum number of parallel jobs is %d\n" -msgstr "%s: 병렬 작업 최대수는 %d 입니다.\n" - -#: pg_restore.c:422 +#: pg_restore.c:434 #, c-format msgid "WARNING: errors ignored on restore: %d\n" msgstr "경고: ë³µì›ìž‘ì—…ì—ì„œì˜ ì˜¤ë¥˜ë“¤ì´ ë¬´ì‹œë˜ì—ˆìŒ: %d\n" -#: pg_restore.c:436 +#: pg_restore.c:448 #, c-format msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" @@ -2539,47 +2624,47 @@ msgstr "" "ê·¸ ìžë£Œë¥¼ ì¼ê´„ 입력합니다.\n" "\n" -#: pg_restore.c:438 +#: pg_restore.c:450 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [옵션]... [파ì¼]\n" -#: pg_restore.c:441 +#: pg_restore.c:453 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NAME ì ‘ì†í•  ë°ì´í„°ë² ì´ìФ ì´ë¦„\n" -#: pg_restore.c:442 +#: pg_restore.c:454 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=FILENAME 출력 íŒŒì¼ ì´ë¦„\n" -#: pg_restore.c:443 +#: pg_restore.c:455 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t 백업 íŒŒì¼ í˜•ì‹ (지정하지 않으면 ìžë™ë¶„ì„)\n" -#: pg_restore.c:444 +#: pg_restore.c:456 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list ìžë£Œì˜ ìš”ì•½ëœ ëª©ì°¨ë¥¼ 보여줌\n" -#: pg_restore.c:445 +#: pg_restore.c:457 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose ìžì„¸í•œ ì •ë³´ 보여줌\n" -#: pg_restore.c:446 +#: pg_restore.c:458 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: pg_restore.c:447 +#: pg_restore.c:459 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: pg_restore.c:449 +#: pg_restore.c:461 #, c-format msgid "" "\n" @@ -2588,33 +2673,33 @@ msgstr "" "\n" "리스토어 처리를 위한 옵션들:\n" -#: pg_restore.c:450 +#: pg_restore.c:462 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only 스키마는 빼고 ìžë£Œë§Œ 입력함\n" -#: pg_restore.c:452 +#: pg_restore.c:464 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create 작업 ëŒ€ìƒ ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 만듦\n" -#: pg_restore.c:453 +#: pg_restore.c:465 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr "" " -e, --exit-on-error 오류가 ìƒê¸°ë©´ ë냄, ê¸°ë³¸ì€ ê³„ì† ì§„í–‰í•¨\n" -#: pg_restore.c:454 +#: pg_restore.c:466 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAME 지정한 ì¸ë±ìФ 만듦\n" -#: pg_restore.c:455 +#: pg_restore.c:467 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr " -j, --jobs=NUM 여러 병렬 ìž‘ì—…ì„ ì‚¬ìš©í•˜ì—¬ ë³µì›\n" -#: pg_restore.c:456 +#: pg_restore.c:468 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -2623,22 +2708,27 @@ msgstr "" " -L, --use-list=FILENAME ì¶œë ¥ì„ ì„ íƒí•˜ê³  해당 순서를 지정하기 위해\n" " ì´ íŒŒì¼ì˜ 목차 사용\n" -#: pg_restore.c:458 +#: pg_restore.c:470 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAME 해당 ìŠ¤í‚¤ë§ˆì˜ ê°œì²´ë“¤ë§Œ ë³µì›í•¨\n" -#: pg_restore.c:460 +#: pg_restore.c:471 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=NAME 해당 ìŠ¤í‚¤ë§ˆì˜ ê°œì²´ë“¤ì€ ë³µì› ì•ˆí•¨\n" + +#: pg_restore.c:473 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NAME(args) 지정한 함수 만듦\n" -#: pg_restore.c:461 +#: pg_restore.c:474 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only ìžë£Œêµ¬ì¡°(스키마)ë§Œ 만듦\n" -#: pg_restore.c:462 +#: pg_restore.c:475 #, c-format msgid "" " -S, --superuser=NAME superuser user name to use for disabling " @@ -2647,36 +2737,35 @@ msgstr "" " -S, --superuser=NAME 트리거를 사용하지 않기 위해 사용할 슈í¼ìœ ì €\n" " ì‚¬ìš©ìž ì´ë¦„\n" -#: pg_restore.c:463 +#: pg_restore.c:476 #, c-format msgid "" " -t, --table=NAME restore named relation (table, view, etc.)\n" -msgstr "" -" -t, --table=NAME ë³µì›í•  ê°ì²´ ì´ë¦„ (í…Œì´ë¸”, ë·°, 기타)\n" +msgstr " -t, --table=NAME ë³µì›í•  ê°ì²´ ì´ë¦„ (í…Œì´ë¸”, ë·°, 기타)\n" -#: pg_restore.c:464 +#: pg_restore.c:477 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAME 지정한 트리거 만듦\n" -#: pg_restore.c:465 +#: pg_restore.c:478 #, c-format msgid "" " -x, --no-privileges skip restoration of access privileges (grant/" "revoke)\n" msgstr " -x, --no-privileges ì ‘ê·¼ 권한(grant/revoke) 지정 안함\n" -#: pg_restore.c:466 +#: pg_restore.c:479 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ 작업으로 ë³µì›í•¨\n" -#: pg_restore.c:468 +#: pg_restore.c:481 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security 로우 보안 활성화\n" -#: pg_restore.c:470 +#: pg_restore.c:483 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not " @@ -2686,17 +2775,27 @@ msgstr "" " --no-data-for-failed-tables 만들 수 없는 í…Œì´ë¸”ì— ëŒ€í•´ì„œëŠ” ìžë£Œë¥¼ ë¤í”„하" "ì§€ 않ìŒ\n" -#: pg_restore.c:472 +#: pg_restore.c:485 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications 발행 정보는 ë³µì› ì•ˆí•¨\n" + +#: pg_restore.c:486 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels 보안 ë¼ë²¨ì„ ë³µì›í•˜ì§€ 않ìŒ\n" -#: pg_restore.c:473 +#: pg_restore.c:487 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions êµ¬ë… ì •ë³´ëŠ” ë³µì› ì•ˆí•¨\n" + +#: pg_restore.c:488 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces í…Œì´ë¸”스페ì´ìФ í• ë‹¹ì„ ë³µì›í•˜ì§€ 않ìŒ\n" -#: pg_restore.c:474 +#: pg_restore.c:489 #, c-format msgid "" " --section=SECTION restore named section (pre-data, data, or " @@ -2705,12 +2804,12 @@ msgstr "" " --section=SECTION 지정한 섹션만 ë³µì›í•¨\n" " 섹션 종류: pre-data, data, post-data\n" -#: pg_restore.c:487 +#: pg_restore.c:502 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLENAME ë³µì› ì „ì— SET ROLE 수행\n" -#: pg_restore.c:489 +#: pg_restore.c:504 #, c-format msgid "" "\n" @@ -2721,7 +2820,7 @@ msgstr "" "-I, -n, -P, -t, -T, --section ì˜µì…˜ì€ ê·¸ 대ìƒì´ ë˜ëŠ” ê°ì²´ë¥¼ 복수로 지정하기\n" "위해서 여러번 사용할 수 있습니다.\n" -#: pg_restore.c:492 +#: pg_restore.c:507 #, c-format msgid "" "\n" @@ -2732,20 +2831,17 @@ msgstr "" "사용할 ìž…ë ¥ 파ì¼ì„ 지정하지 않았다면, 표준 ìž…ë ¥(stdin)ì„ ì‚¬ìš©í•©ë‹ˆë‹¤.\n" "\n" -#~ msgid "could not open output file \"%s\" for writing\n" -#~ msgstr "\"%s\" 파ì¼ì„ 쓰기 모드로 ì—´ 수 ì—†ìŒ\n" - -#~ msgid "error in ListenToWorkers(): %s\n" -#~ msgstr "ListenToWorkers()ì—서 오류 ë°œìƒ: %s\n" - -#~ msgid "terminated by user\n" -#~ msgstr "사용ìžì— ì˜í•´ 종료ë¨\n" - -#~ msgid "unrecognized command on communication channel: %s\n" -#~ msgstr "통신 ì²´ë„ì—서 알 수 없는 명령: %s\n" +#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" +#~ msgstr "%s \"%s.%s\" ê°ì²´ì˜ 소유주와 ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•˜ëŠ” 중\n" -#~ msgid "could not get relation name for OID %u: %s\n" -#~ msgstr "%u OIDì— ëŒ€ì‘하는 릴레ì´ì…˜ ì´ë¦„ì„ ì•Œ 수 ì—†ìŒ: %s\n" +#~ msgid "setting owner and privileges for %s \"%s\"\n" +#~ msgstr "%s \"%s\" ê°ì²´ì˜ 소유주와 ì ‘ê·¼ ê¶Œí•œì„ ì§€ì •í•˜ëŠ” 중\n" -#~ msgid "worker is terminating\n" -#~ msgstr "작업 프로세스 종료 중\n" +#~ msgid "" +#~ "Synchronized snapshots are not supported on standby servers.\n" +#~ "Run with --no-synchronized-snapshots instead if you do not need\n" +#~ "synchronized snapshots.\n" +#~ msgstr "" +#~ "대기 서버ì—서는 ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì„ ì‚¬ìš©í•  수 ì—†ìŒ.\n" +#~ "ë™ê¸°í™”ëœ ìŠ¤ëƒ…ìƒ· ê¸°ëŠ¥ì´ í•„ìš” 없다면, --no-synchronized-snapshots\n" +#~ "ì˜µì…˜ì„ ì§€ì •í•´ì„œ ë¤í”„í•  수 있습니다.\n" diff --git a/src/bin/pg_dump/po/ru.po b/src/bin/pg_dump/po/ru.po index 446e0b6c5bf..f384bbf27f3 100644 --- a/src/bin/pg_dump/po/ru.po +++ b/src/bin/pg_dump/po/ru.po @@ -6,13 +6,13 @@ # Sergey Burladyan , 2012. # Dmitriy Olshevskiy , 2014. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: pg_dump (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-02 23:46+0000\n" -"PO-Revision-Date: 2017-04-03 16:01+0300\n" +"POT-Creation-Date: 2018-02-12 12:29+0300\n" +"PO-Revision-Date: 2017-08-21 06:16+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -20,7 +20,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -103,224 +102,209 @@ msgstr "дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½ по Ñигналу %d" msgid "child process exited with unrecognized status %d" msgstr "дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ñ Ð½ÐµÑ€Ð°Ñпознанным ÑоÑтоÑнием %d" -#: common.c:127 +#: common.c:121 #, c-format msgid "reading extensions\n" msgstr "чтение раÑширений\n" -#: common.c:132 +#: common.c:126 #, c-format msgid "identifying extension members\n" msgstr "выÑвление членов раÑширений\n" -#: common.c:136 +#: common.c:130 #, c-format msgid "reading schemas\n" msgstr "чтение Ñхем\n" -#: common.c:147 +#: common.c:141 #, c-format msgid "reading user-defined tables\n" msgstr "чтение пользовательÑких таблиц\n" -#: common.c:155 +#: common.c:149 #, c-format msgid "reading user-defined functions\n" msgstr "чтение пользовательÑких функций\n" -#: common.c:161 +#: common.c:155 #, c-format msgid "reading user-defined types\n" msgstr "чтение пользовательÑких типов\n" -#: common.c:167 +#: common.c:161 #, c-format msgid "reading procedural languages\n" msgstr "чтение процедурных Ñзыков\n" -#: common.c:171 +#: common.c:165 #, c-format msgid "reading user-defined aggregate functions\n" msgstr "чтение пользовательÑких агрегатных функций\n" -#: common.c:175 +#: common.c:169 #, c-format msgid "reading user-defined operators\n" msgstr "чтение пользовательÑких операторов\n" -#: common.c:180 +#: common.c:174 #, c-format msgid "reading user-defined access methods\n" msgstr "чтение пользовательÑких методов доÑтупа\n" -#: common.c:184 +#: common.c:178 #, c-format msgid "reading user-defined operator classes\n" msgstr "чтение пользовательÑких клаÑÑов операторов\n" -#: common.c:188 +#: common.c:182 #, c-format msgid "reading user-defined operator families\n" msgstr "чтение пользовательÑких ÑемейÑтв операторов\n" -#: common.c:192 +#: common.c:186 #, c-format msgid "reading user-defined text search parsers\n" msgstr "чтение пользовательÑких анализаторов текÑтового поиÑка\n" -#: common.c:196 +#: common.c:190 #, c-format msgid "reading user-defined text search templates\n" msgstr "чтение пользовательÑких шаблонов текÑтового поиÑка\n" -#: common.c:200 +#: common.c:194 #, c-format msgid "reading user-defined text search dictionaries\n" msgstr "чтение пользовательÑких Ñловарей текÑтового поиÑка\n" -#: common.c:204 +#: common.c:198 #, c-format msgid "reading user-defined text search configurations\n" msgstr "чтение пользовательÑких конфигураций текÑтового поиÑка\n" -#: common.c:208 +#: common.c:202 #, c-format msgid "reading user-defined foreign-data wrappers\n" msgstr "чтение пользовательÑких оболочек Ñторонних данных\n" -#: common.c:212 +#: common.c:206 #, c-format msgid "reading user-defined foreign servers\n" msgstr "чтение пользовательÑких Ñторонних Ñерверов\n" -#: common.c:216 +#: common.c:210 #, c-format msgid "reading default privileges\n" msgstr "чтение прав по умолчанию\n" -#: common.c:220 +#: common.c:214 #, c-format msgid "reading user-defined collations\n" msgstr "чтение пользовательÑких правил Ñортировки\n" -#: common.c:225 +#: common.c:219 #, c-format msgid "reading user-defined conversions\n" msgstr "чтение пользовательÑких преобразований\n" -#: common.c:229 +#: common.c:223 #, c-format msgid "reading type casts\n" msgstr "чтение приведений типов\n" -#: common.c:233 +#: common.c:227 #, c-format msgid "reading transforms\n" msgstr "чтение преобразований\n" -#: common.c:237 +#: common.c:231 #, c-format msgid "reading table inheritance information\n" msgstr "чтение информации о наÑледовании таблиц\n" -#: common.c:241 -#, c-format -msgid "reading partition information\n" -msgstr "чтение информации о ÑекциÑÑ…\n" - -#: common.c:245 +#: common.c:235 #, c-format msgid "reading event triggers\n" msgstr "чтение Ñобытийных триггеров\n" -#: common.c:250 +#: common.c:240 #, c-format msgid "finding extension tables\n" msgstr "поиÑк таблиц раÑширений\n" -#: common.c:255 +#: common.c:245 #, c-format msgid "finding inheritance relationships\n" msgstr "поиÑк ÑвÑзей наÑледованиÑ\n" -#: common.c:260 -#, c-format -msgid "finding partition relationships\n" -msgstr "обнаружение взаимоÑвÑзей Ñекций\n" - -#: common.c:264 +#: common.c:249 #, c-format msgid "reading column info for interesting tables\n" msgstr "чтение информации о Ñтолбцах интереÑующих таблиц\n" -#: common.c:268 +#: common.c:253 #, c-format msgid "flagging inherited columns in subtables\n" msgstr "пометка наÑледованных Ñтолбцов в подтаблицах\n" -#: common.c:272 +#: common.c:257 #, c-format msgid "reading indexes\n" msgstr "чтение индекÑов\n" -#: common.c:276 +#: common.c:261 #, c-format msgid "reading extended statistics\n" msgstr "чтение раÑширенной ÑтатиÑтики\n" -#: common.c:280 +#: common.c:265 #, c-format msgid "reading constraints\n" msgstr "чтение ограничений\n" -#: common.c:284 +#: common.c:269 #, c-format msgid "reading triggers\n" msgstr "чтение триггеров\n" -#: common.c:288 +#: common.c:273 #, c-format msgid "reading rewrite rules\n" msgstr "чтение правил перезапиÑи\n" -#: common.c:292 +#: common.c:277 #, c-format msgid "reading policies\n" msgstr "чтение политик\n" -#: common.c:296 -#, c-format -msgid "reading partition key information for interesting tables\n" -msgstr "чтение информации о ключах Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€ÐµÑующих таблиц\n" - -#: common.c:300 +#: common.c:281 #, c-format msgid "reading publications\n" msgstr "чтение публикаций\n" -#: common.c:304 +#: common.c:285 #, c-format msgid "reading publication membership\n" msgstr "чтение учаÑтников публикаций\n" -#: common.c:308 +#: common.c:289 #, c-format msgid "reading subscriptions\n" msgstr "чтение подпиÑок\n" -#: common.c:980 common.c:1014 +#: common.c:924 #, c-format msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" msgstr "" "нарушение целоÑтноÑти: родительÑÐºÐ°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ñ OID %u Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" (OID " "%u) не найдена\n" -#: common.c:1056 +#: common.c:966 #, c-format msgid "could not parse numeric array \"%s\": too many numbers\n" msgstr "не удалоÑÑŒ разобрать чиÑловой маÑÑив \"%s\": Ñлишком много чиÑел\n" -#: common.c:1071 +#: common.c:981 #, c-format msgid "could not parse numeric array \"%s\": invalid character in number\n" msgstr "не удалоÑÑŒ разобрать чиÑловой маÑÑив \"%s\": неверный Ñимвол в чиÑле\n" @@ -366,14 +350,14 @@ msgstr "не удалоÑÑŒ раÑпаковать данные: %s\n" msgid "could not close compression library: %s\n" msgstr "не удалоÑÑŒ закрыть библиотеку ÑжатиÑ: %s\n" -#: compress_io.c:596 compress_io.c:632 pg_backup_custom.c:587 -#: pg_backup_tar.c:559 +#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 +#: pg_backup_tar.c:564 pg_backup_tar.c:568 #, c-format msgid "could not read from input file: %s\n" msgstr "не удалоÑÑŒ прочитать входной файл: %s\n" -#: compress_io.c:635 pg_backup_custom.c:584 pg_backup_directory.c:543 -#: pg_backup_tar.c:795 pg_backup_tar.c:819 +#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 +#: pg_backup_tar.c:807 pg_backup_tar.c:831 #, c-format msgid "could not read from input file: end of file\n" msgstr "не удалоÑÑŒ прочитать входной файл: конец файла\n" @@ -475,36 +459,36 @@ msgstr "pgpipe: не удалоÑÑŒ принÑть Ñоединение (код msgid "archiver" msgstr "архиватор" -#: pg_backup_archiver.c:242 pg_backup_archiver.c:1572 +#: pg_backup_archiver.c:249 pg_backup_archiver.c:1599 #, c-format msgid "could not close output file: %s\n" msgstr "не удалоÑÑŒ закрыть выходной файл: %s\n" -#: pg_backup_archiver.c:288 pg_backup_archiver.c:293 +#: pg_backup_archiver.c:295 pg_backup_archiver.c:300 #, c-format msgid "WARNING: archive items not in correct section order\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: в поÑледовательноÑти Ñлементов архива нарушен порÑдок " "разделов\n" -#: pg_backup_archiver.c:299 +#: pg_backup_archiver.c:306 #, c-format msgid "unexpected section code %d\n" msgstr "неожиданный код раздела %d\n" -#: pg_backup_archiver.c:335 +#: pg_backup_archiver.c:342 #, c-format msgid "-C and -1 are incompatible options\n" msgstr "Параметры -C и -1 неÑовмеÑтимы\n" -#: pg_backup_archiver.c:345 +#: pg_backup_archiver.c:352 #, c-format msgid "parallel restore is not supported with this archive file format\n" msgstr "" "параллельное воÑÑтановление не поддерживаетÑÑ Ñ Ð²Ñ‹Ð±Ñ€Ð°Ð½Ð½Ñ‹Ð¼ форматом архивного " "файла\n" -#: pg_backup_archiver.c:349 +#: pg_backup_archiver.c:356 #, c-format msgid "" "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" @@ -512,7 +496,7 @@ msgstr "" "параллельное воÑÑтановление возможно только Ð´Ð»Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð¾Ð², Ñозданных pg_dump " "верÑии 8.0 и новее\n" -#: pg_backup_archiver.c:367 +#: pg_backup_archiver.c:374 #, c-format msgid "" "cannot restore from compressed archive (compression not supported in this " @@ -521,90 +505,80 @@ msgstr "" "воÑÑтановить данные из Ñжатого архива Ð½ÐµÐ»ÑŒÐ·Ñ (уÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð½Ðµ " "поддерживает Ñжатие)\n" -#: pg_backup_archiver.c:384 +#: pg_backup_archiver.c:391 #, c-format msgid "connecting to database for restore\n" msgstr "подключение к базе данных Ð´Ð»Ñ Ð²Ð¾ÑÑтановлениÑ\n" -#: pg_backup_archiver.c:386 +#: pg_backup_archiver.c:393 #, c-format msgid "direct database connections are not supported in pre-1.3 archives\n" msgstr "" "прÑмые Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº базе данных не поддерживаютÑÑ Ð² архивах до верÑии 1.3\n" -#: pg_backup_archiver.c:431 +#: pg_backup_archiver.c:438 #, c-format msgid "implied data-only restore\n" msgstr "подразумеваетÑÑ Ð²Ð¾ÑÑтановление только данных\n" -#: pg_backup_archiver.c:501 +#: pg_backup_archiver.c:508 #, c-format msgid "dropping %s %s\n" msgstr "удалÑетÑÑ %s %s\n" -#: pg_backup_archiver.c:594 +#: pg_backup_archiver.c:601 #, c-format msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ определить, куда добавить IF EXISTS в оператор " "\"%s\"\n" -#: pg_backup_archiver.c:670 -#, c-format -msgid "setting owner and privileges for %s \"%s.%s\"\n" -msgstr "уÑтановка владельца и прав: %s \"%s.%s\"\n" - -#: pg_backup_archiver.c:673 -#, c-format -msgid "setting owner and privileges for %s \"%s\"\n" -msgstr "уÑтановка владельца и прав: %s \"%s\"\n" - -#: pg_backup_archiver.c:739 pg_backup_archiver.c:741 +#: pg_backup_archiver.c:764 pg_backup_archiver.c:766 #, c-format msgid "warning from original dump file: %s\n" msgstr "предупреждение из иÑходного файла: %s\n" -#: pg_backup_archiver.c:750 +#: pg_backup_archiver.c:778 #, c-format msgid "creating %s \"%s.%s\"\n" msgstr "ÑоздаётÑÑ %s \"%s.%s\"\n" -#: pg_backup_archiver.c:753 +#: pg_backup_archiver.c:781 #, c-format msgid "creating %s \"%s\"\n" msgstr "ÑоздаётÑÑ %s \"%s\"\n" -#: pg_backup_archiver.c:805 +#: pg_backup_archiver.c:832 #, c-format msgid "connecting to new database \"%s\"\n" msgstr "подключение к новой базе данных \"%s\"\n" -#: pg_backup_archiver.c:833 +#: pg_backup_archiver.c:860 #, c-format msgid "processing %s\n" msgstr "обрабатываетÑÑ %s\n" -#: pg_backup_archiver.c:853 +#: pg_backup_archiver.c:880 #, c-format msgid "processing data for table \"%s.%s\"\n" msgstr "обрабатываютÑÑ Ð´Ð°Ð½Ð½Ñ‹Ðµ таблицы \"%s.%s\"\n" -#: pg_backup_archiver.c:915 +#: pg_backup_archiver.c:942 #, c-format msgid "executing %s %s\n" msgstr "выполнÑетÑÑ %s %s\n" -#: pg_backup_archiver.c:954 +#: pg_backup_archiver.c:981 #, c-format msgid "disabling triggers for %s\n" msgstr "отключаютÑÑ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ñ‹ таблицы %s\n" -#: pg_backup_archiver.c:982 +#: pg_backup_archiver.c:1009 #, c-format msgid "enabling triggers for %s\n" msgstr "включаютÑÑ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ñ‹ таблицы %s\n" -#: pg_backup_archiver.c:1012 +#: pg_backup_archiver.c:1039 #, c-format msgid "" "internal error -- WriteData cannot be called outside the context of a " @@ -613,12 +587,12 @@ msgstr "" "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° -- WriteData Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð·Ñ‹Ð²Ð°Ñ‚ÑŒ вне контекÑта процедуры " "DataDumper\n" -#: pg_backup_archiver.c:1210 +#: pg_backup_archiver.c:1237 #, c-format msgid "large-object output not supported in chosen format\n" msgstr "выбранный формат не поддерживает выгрузку больших объектов\n" -#: pg_backup_archiver.c:1268 +#: pg_backup_archiver.c:1295 #, c-format msgid "restored %d large object\n" msgid_plural "restored %d large objects\n" @@ -626,55 +600,55 @@ msgstr[0] "воÑÑтановлен %d большой объект\n" msgstr[1] "воÑÑтановлено %d больших объекта\n" msgstr[2] "воÑÑтановлено %d больших объектов\n" -#: pg_backup_archiver.c:1289 pg_backup_tar.c:737 +#: pg_backup_archiver.c:1316 pg_backup_tar.c:749 #, c-format msgid "restoring large object with OID %u\n" msgstr "воÑÑтановление большого объекта Ñ OID %u\n" -#: pg_backup_archiver.c:1301 +#: pg_backup_archiver.c:1328 #, c-format msgid "could not create large object %u: %s" msgstr "не удалоÑÑŒ Ñоздать большой объект %u: %s" -#: pg_backup_archiver.c:1306 pg_dump.c:3080 +#: pg_backup_archiver.c:1333 pg_dump.c:3092 #, c-format msgid "could not open large object %u: %s" msgstr "не удалоÑÑŒ открыть большой объект %u: %s" -#: pg_backup_archiver.c:1364 +#: pg_backup_archiver.c:1391 #, c-format msgid "could not open TOC file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть файл Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\": %s\n" -#: pg_backup_archiver.c:1405 +#: pg_backup_archiver.c:1432 #, c-format msgid "WARNING: line ignored: %s\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: Ñтрока проигнорирована: %s\n" -#: pg_backup_archiver.c:1412 +#: pg_backup_archiver.c:1439 #, c-format msgid "could not find entry for ID %d\n" msgstr "не найдена запиÑÑŒ Ð´Ð»Ñ ID %d\n" -#: pg_backup_archiver.c:1433 pg_backup_directory.c:225 -#: pg_backup_directory.c:592 +#: pg_backup_archiver.c:1460 pg_backup_directory.c:225 +#: pg_backup_directory.c:596 #, c-format msgid "could not close TOC file: %s\n" msgstr "не удалоÑÑŒ закрыть файл оглавлениÑ: %s\n" -#: pg_backup_archiver.c:1542 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:578 pg_backup_directory.c:643 -#: pg_backup_directory.c:663 +#: pg_backup_archiver.c:1569 pg_backup_custom.c:158 pg_backup_directory.c:336 +#: pg_backup_directory.c:582 pg_backup_directory.c:647 +#: pg_backup_directory.c:667 #, c-format msgid "could not open output file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть выходной файл \"%s\": %s\n" -#: pg_backup_archiver.c:1545 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1572 pg_backup_custom.c:165 #, c-format msgid "could not open output file: %s\n" msgstr "не удалоÑÑŒ открыть выходной файл: %s\n" -#: pg_backup_archiver.c:1651 +#: pg_backup_archiver.c:1678 #, c-format msgid "wrote %lu byte of large object data (result = %lu)\n" msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" @@ -682,222 +656,222 @@ msgstr[0] "запиÑан %lu байт данных большого объек msgstr[1] "запиÑано %lu байта данных большого объекта (результат = %lu)\n" msgstr[2] "запиÑано %lu байт данных большого объекта (результат = %lu)\n" -#: pg_backup_archiver.c:1657 +#: pg_backup_archiver.c:1684 #, c-format msgid "could not write to large object (result: %lu, expected: %lu)\n" msgstr "не удалоÑÑŒ запиÑать большой объект (результат: %lu, ожидалоÑÑŒ: %lu)\n" -#: pg_backup_archiver.c:1750 +#: pg_backup_archiver.c:1777 #, c-format msgid "Error while INITIALIZING:\n" msgstr "Ошибка при инициализации:\n" -#: pg_backup_archiver.c:1755 +#: pg_backup_archiver.c:1782 #, c-format msgid "Error while PROCESSING TOC:\n" msgstr "Ошибка при обработке оглавлениÑ:\n" -#: pg_backup_archiver.c:1760 +#: pg_backup_archiver.c:1787 #, c-format msgid "Error while FINALIZING:\n" msgstr "Ошибка при завершении:\n" -#: pg_backup_archiver.c:1765 +#: pg_backup_archiver.c:1792 #, c-format msgid "Error from TOC entry %d; %u %u %s %s %s\n" msgstr "Ошибка из запиÑи Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ %d; %u %u %s %s %s\n" -#: pg_backup_archiver.c:1838 +#: pg_backup_archiver.c:1865 #, c-format msgid "bad dumpId\n" msgstr "неверный dumpId\n" -#: pg_backup_archiver.c:1859 +#: pg_backup_archiver.c:1886 #, c-format msgid "bad table dumpId for TABLE DATA item\n" msgstr "неверный dumpId таблицы в Ñлементе TABLE DATA\n" -#: pg_backup_archiver.c:1951 +#: pg_backup_archiver.c:1978 #, c-format msgid "unexpected data offset flag %d\n" msgstr "неожиданный флаг ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %d\n" -#: pg_backup_archiver.c:1964 +#: pg_backup_archiver.c:1991 #, c-format msgid "file offset in dump file is too large\n" msgstr "Ñлишком большое Ñмещение в файле вывода\n" -#: pg_backup_archiver.c:2077 +#: pg_backup_archiver.c:2104 #, c-format msgid "attempting to ascertain archive format\n" msgstr "попытка выÑÑнить формат архива\n" -#: pg_backup_archiver.c:2103 pg_backup_archiver.c:2113 +#: pg_backup_archiver.c:2130 pg_backup_archiver.c:2140 #, c-format msgid "directory name too long: \"%s\"\n" msgstr "Ñлишком длинное Ð¸Ð¼Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð°: \"%s\"\n" -#: pg_backup_archiver.c:2121 +#: pg_backup_archiver.c:2148 #, c-format msgid "" "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not " "exist)\n" msgstr "каталог \"%s\" не похож на архивный (в нём отÑутÑтвует \"toc.dat\")\n" -#: pg_backup_archiver.c:2129 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:394 +#: pg_backup_archiver.c:2156 pg_backup_custom.c:177 pg_backup_custom.c:770 +#: pg_backup_directory.c:209 pg_backup_directory.c:396 #, c-format msgid "could not open input file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть входной файл \"%s\": %s\n" -#: pg_backup_archiver.c:2137 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2164 pg_backup_custom.c:184 #, c-format msgid "could not open input file: %s\n" msgstr "не удалоÑÑŒ открыть входной файл: %s\n" -#: pg_backup_archiver.c:2144 +#: pg_backup_archiver.c:2171 #, c-format msgid "could not read input file: %s\n" msgstr "не удалоÑÑŒ прочитать входной файл: %s\n" -#: pg_backup_archiver.c:2146 +#: pg_backup_archiver.c:2173 #, c-format msgid "input file is too short (read %lu, expected 5)\n" msgstr "входной файл Ñлишком короткий (прочитано байт: %lu, ожидалоÑÑŒ: 5)\n" -#: pg_backup_archiver.c:2231 +#: pg_backup_archiver.c:2258 #, c-format msgid "input file appears to be a text format dump. Please use psql.\n" msgstr "" "входной файл похоже имеет текÑтовый формат. Загрузите его Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ psql.\n" -#: pg_backup_archiver.c:2237 +#: pg_backup_archiver.c:2264 #, c-format msgid "input file does not appear to be a valid archive (too short?)\n" msgstr "входной файл не похож на архив (возможно, Ñлишком мал?)\n" -#: pg_backup_archiver.c:2243 +#: pg_backup_archiver.c:2270 #, c-format msgid "input file does not appear to be a valid archive\n" msgstr "входной файл не похож на архив\n" -#: pg_backup_archiver.c:2263 +#: pg_backup_archiver.c:2290 #, c-format msgid "could not close input file: %s\n" msgstr "не удалоÑÑŒ закрыть входной файл: %s\n" -#: pg_backup_archiver.c:2281 +#: pg_backup_archiver.c:2308 #, c-format msgid "allocating AH for %s, format %d\n" msgstr "выделение Ñтруктуры AH Ð´Ð»Ñ %s, формат %d\n" -#: pg_backup_archiver.c:2382 +#: pg_backup_archiver.c:2409 #, c-format msgid "unrecognized file format \"%d\"\n" msgstr "неопознанный формат файла: \"%d\"\n" -#: pg_backup_archiver.c:2437 pg_backup_archiver.c:4195 +#: pg_backup_archiver.c:2464 pg_backup_archiver.c:4317 #, c-format msgid "finished item %d %s %s\n" msgstr "закончен объект %d %s %s\n" -#: pg_backup_archiver.c:2441 pg_backup_archiver.c:4208 +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4330 #, c-format msgid "worker process failed: exit code %d\n" msgstr "рабочий процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ñ ÐºÐ¾Ð´Ð¾Ð¼ возврата %d\n" -#: pg_backup_archiver.c:2561 +#: pg_backup_archiver.c:2588 #, c-format msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" msgstr "ID запиÑи %d вне диапазона - возможно повреждено оглавление\n" -#: pg_backup_archiver.c:2677 +#: pg_backup_archiver.c:2704 #, c-format msgid "read TOC entry %d (ID %d) for %s %s\n" msgstr "прочитана запиÑÑŒ Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ %d (ID %d): %s %s\n" -#: pg_backup_archiver.c:2711 +#: pg_backup_archiver.c:2738 #, c-format msgid "unrecognized encoding \"%s\"\n" msgstr "нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° \"%s\"\n" -#: pg_backup_archiver.c:2716 +#: pg_backup_archiver.c:2743 #, c-format msgid "invalid ENCODING item: %s\n" msgstr "неверный Ñлемент ENCODING: %s\n" -#: pg_backup_archiver.c:2734 +#: pg_backup_archiver.c:2761 #, c-format msgid "invalid STDSTRINGS item: %s\n" msgstr "неверный Ñлемент STDSTRINGS: %s\n" -#: pg_backup_archiver.c:2749 +#: pg_backup_archiver.c:2776 #, c-format msgid "schema \"%s\" not found\n" msgstr "Ñхема \"%s\" не найдена\n" -#: pg_backup_archiver.c:2756 +#: pg_backup_archiver.c:2783 #, c-format msgid "table \"%s\" not found\n" msgstr "таблица \"%s\" не найдена\n" -#: pg_backup_archiver.c:2763 +#: pg_backup_archiver.c:2790 #, c-format msgid "index \"%s\" not found\n" msgstr "Ð¸Ð½Ð´ÐµÐºÑ \"%s\" не найден\n" -#: pg_backup_archiver.c:2770 +#: pg_backup_archiver.c:2797 #, c-format msgid "function \"%s\" not found\n" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" не найдена\n" -#: pg_backup_archiver.c:2777 +#: pg_backup_archiver.c:2804 #, c-format msgid "trigger \"%s\" not found\n" msgstr "триггер \"%s\" не найден\n" -#: pg_backup_archiver.c:3025 +#: pg_backup_archiver.c:3090 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "не удалоÑÑŒ переключить Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑеÑÑии на \"%s\": %s" -#: pg_backup_archiver.c:3057 +#: pg_backup_archiver.c:3122 #, c-format msgid "could not set default_with_oids: %s" msgstr "не удалоÑÑŒ уÑтановить параметр default_with_oids: %s" -#: pg_backup_archiver.c:3202 +#: pg_backup_archiver.c:3267 #, c-format msgid "could not set search_path to \"%s\": %s" msgstr "не удалоÑÑŒ приÑвоить search_path значение \"%s\": %s" -#: pg_backup_archiver.c:3264 +#: pg_backup_archiver.c:3329 #, c-format msgid "could not set default_tablespace to %s: %s" msgstr "не удалоÑÑŒ задать Ð´Ð»Ñ default_tablespace значение %s: %s" -#: pg_backup_archiver.c:3353 pg_backup_archiver.c:3550 +#: pg_backup_archiver.c:3420 pg_backup_archiver.c:3613 #, c-format -msgid "WARNING: don't know how to set owner for object type %s\n" +msgid "WARNING: don't know how to set owner for object type \"%s\"\n" msgstr "" -"ПРЕДУПРЕЖДЕÐИЕ: неизвеÑтно, как назначить владельца Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° типа %s\n" +"ПРЕДУПРЕЖДЕÐИЕ: неизвеÑтно, как назначить владельца Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° типа \"%s\"\n" -#: pg_backup_archiver.c:3637 +#: pg_backup_archiver.c:3703 #, c-format msgid "did not find magic string in file header\n" msgstr "в файле заголовка не найдена магичеÑÐºÐ°Ñ Ñтрока\n" -#: pg_backup_archiver.c:3650 +#: pg_backup_archiver.c:3716 #, c-format msgid "unsupported version (%d.%d) in file header\n" msgstr "Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ (%d.%d) в заголовке файла\n" -#: pg_backup_archiver.c:3655 +#: pg_backup_archiver.c:3721 #, c-format msgid "sanity check on integer size (%lu) failed\n" msgstr "неÑоответÑтвие размера integer (%lu)\n" -#: pg_backup_archiver.c:3659 +#: pg_backup_archiver.c:3725 #, c-format msgid "" "WARNING: archive was made on a machine with larger integers, some operations " @@ -906,12 +880,12 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: архив был Ñделан на компьютере большей разрÑдноÑти -- " "возможен Ñбой некоторых операций\n" -#: pg_backup_archiver.c:3669 +#: pg_backup_archiver.c:3735 #, c-format msgid "expected format (%d) differs from format found in file (%d)\n" msgstr "ожидаемый формат (%d) отличаетÑÑ Ð¾Ñ‚ формата, указанного в файле (%d)\n" -#: pg_backup_archiver.c:3685 +#: pg_backup_archiver.c:3751 #, c-format msgid "" "WARNING: archive is compressed, but this installation does not support " @@ -920,72 +894,72 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: архив Ñжат, но уÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Ð½Ðµ поддерживает Ñжатие " "-- данные недоÑтупны\n" -#: pg_backup_archiver.c:3703 +#: pg_backup_archiver.c:3769 #, c-format msgid "WARNING: invalid creation date in header\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð² заголовке\n" -#: pg_backup_archiver.c:3778 +#: pg_backup_archiver.c:3842 #, c-format msgid "entering restore_toc_entries_prefork\n" msgstr "вход в restore_toc_entries_prefork\n" -#: pg_backup_archiver.c:3822 +#: pg_backup_archiver.c:3906 #, c-format msgid "processing item %d %s %s\n" msgstr "обработка объекта %d %s %s\n" -#: pg_backup_archiver.c:3872 +#: pg_backup_archiver.c:3960 #, c-format msgid "entering restore_toc_entries_parallel\n" msgstr "вход в restore_toc_entries_parallel\n" -#: pg_backup_archiver.c:3920 +#: pg_backup_archiver.c:3981 #, c-format msgid "entering main parallel loop\n" msgstr "вход в оÑновной параллельный цикл\n" -#: pg_backup_archiver.c:3931 +#: pg_backup_archiver.c:3992 #, c-format msgid "skipping item %d %s %s\n" msgstr "объект %d %s %s пропуÑкаетÑÑ\n" -#: pg_backup_archiver.c:3941 +#: pg_backup_archiver.c:4002 #, c-format msgid "launching item %d %s %s\n" msgstr "объект %d %s %s запуÑкаетÑÑ\n" -#: pg_backup_archiver.c:3972 +#: pg_backup_archiver.c:4056 #, c-format msgid "finished main parallel loop\n" msgstr "оÑновной параллельный цикл закончен\n" -#: pg_backup_archiver.c:3981 +#: pg_backup_archiver.c:4074 #, c-format msgid "entering restore_toc_entries_postfork\n" msgstr "вход в restore_toc_entries_postfork\n" -#: pg_backup_archiver.c:4000 +#: pg_backup_archiver.c:4094 #, c-format msgid "processing missed item %d %s %s\n" msgstr "обработка пропущенного объекта %d %s %s\n" -#: pg_backup_archiver.c:4151 +#: pg_backup_archiver.c:4273 #, c-format msgid "no item ready\n" msgstr "Ñлемент не готов\n" -#: pg_backup_archiver.c:4370 +#: pg_backup_archiver.c:4492 #, c-format msgid "transferring dependency %d -> %d to %d\n" msgstr "переключение завиÑимоÑти %d -> %d на %d\n" -#: pg_backup_archiver.c:4443 +#: pg_backup_archiver.c:4565 #, c-format msgid "reducing dependencies for %d\n" msgstr "уменьшение завиÑимоÑтей Ð´Ð»Ñ %d\n" -#: pg_backup_archiver.c:4482 +#: pg_backup_archiver.c:4617 #, c-format msgid "table \"%s\" could not be created, will not restore its data\n" msgstr "Ñоздать таблицу \"%s\" не удалоÑÑŒ, её данные не будут воÑÑтановлены\n" @@ -1047,7 +1021,7 @@ msgid "unrecognized data block type %d while restoring archive\n" msgstr "нераÑпознанный тип блока данных %d при воÑÑтановлении архива\n" #: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1090 +#: pg_backup_tar.c:1102 #, c-format msgid "could not determine seek position in archive file: %s\n" msgstr "не удалоÑÑŒ определить позицию в файле архива: %s\n" @@ -1100,12 +1074,12 @@ msgstr "архиватор (БД)" msgid "could not get server_version from libpq\n" msgstr "не удалоÑÑŒ получить верÑию Ñервера из libpq\n" -#: pg_backup_db.c:56 pg_dumpall.c:2056 +#: pg_backup_db.c:56 pg_dumpall.c:2057 #, c-format msgid "server version: %s; %s version: %s\n" msgstr "верÑÐ¸Ñ Ñервера: %s; верÑÐ¸Ñ %s: %s\n" -#: pg_backup_db.c:58 pg_dumpall.c:2058 +#: pg_backup_db.c:58 pg_dumpall.c:2059 #, c-format msgid "aborting because of server version mismatch\n" msgstr "продолжение работы Ñ Ð´Ñ€ÑƒÐ³Ð¾Ð¹ верÑией Ñервера невозможно\n" @@ -1116,7 +1090,7 @@ msgid "connecting to database \"%s\" as user \"%s\"\n" msgstr "подключение к базе \"%s\" Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ \"%s\"\n" #: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 -#: pg_dumpall.c:1879 pg_dumpall.c:1993 +#: pg_dumpall.c:1880 pg_dumpall.c:1994 msgid "Password: " msgstr "Пароль: " @@ -1197,7 +1171,7 @@ msgstr "ошибка в PQputCopyEnd: %s" msgid "COPY failed for table \"%s\": %s" msgstr "Ñбой команды COPY Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\": %s" -#: pg_backup_db.c:639 pg_dump.c:1840 +#: pg_backup_db.c:639 pg_dump.c:1841 #, c-format msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" msgstr "" @@ -1237,38 +1211,44 @@ msgstr "не удалоÑÑŒ закрыть каталог \"%s\": %s\n" msgid "could not create directory \"%s\": %s\n" msgstr "Ñоздать каталог \"%s\" не удалоÑÑŒ: %s\n" -#: pg_backup_directory.c:407 +#: pg_backup_directory.c:355 pg_backup_directory.c:495 +#: pg_backup_directory.c:525 +#, c-format +msgid "could not write to output file: %s\n" +msgstr "не удалоÑÑŒ запиÑать в выходной файл: %s\n" + +#: pg_backup_directory.c:409 #, c-format msgid "could not close data file: %s\n" msgstr "не удалоÑÑŒ закрыть файл данных: %s\n" -#: pg_backup_directory.c:448 +#: pg_backup_directory.c:450 #, c-format msgid "could not open large object TOC file \"%s\" for input: %s\n" msgstr "" "не удалоÑÑŒ открыть Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð» Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов \"%s\": %s\n" -#: pg_backup_directory.c:459 +#: pg_backup_directory.c:461 #, c-format msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñтрока в файле Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов \"%s\": \"%s\"\n" -#: pg_backup_directory.c:468 +#: pg_backup_directory.c:470 #, c-format msgid "error reading large object TOC file \"%s\"\n" msgstr "ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов \"%s\"\n" -#: pg_backup_directory.c:472 +#: pg_backup_directory.c:474 #, c-format msgid "could not close large object TOC file \"%s\": %s\n" msgstr "не удалоÑÑŒ закрыть файл Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов \"%s\": %s\n" -#: pg_backup_directory.c:686 +#: pg_backup_directory.c:690 #, c-format msgid "could not write to blobs TOC file\n" msgstr "не удалоÑÑŒ запиÑать в файл Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов\n" -#: pg_backup_directory.c:718 +#: pg_backup_directory.c:722 #, c-format msgid "file name too long: \"%s\"\n" msgstr "Ñлишком длинное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°: \"%s\"\n" @@ -1328,52 +1308,52 @@ msgstr "не удалоÑÑŒ открыть временный файл\n" msgid "could not close tar member\n" msgstr "не удалоÑÑŒ закрыть компонент tar-архива\n" -#: pg_backup_tar.c:569 +#: pg_backup_tar.c:581 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° -- в tarReadRaw() не указан ни th, ни fh\n" -#: pg_backup_tar.c:692 +#: pg_backup_tar.c:704 #, c-format msgid "unexpected COPY statement syntax: \"%s\"\n" msgstr "недопуÑтимый ÑинтакÑÐ¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° COPY: \"%s\"\n" -#: pg_backup_tar.c:962 +#: pg_backup_tar.c:974 #, c-format msgid "invalid OID for large object (%u)\n" msgstr "неверный OID Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð³Ð¾ объекта (%u)\n" -#: pg_backup_tar.c:1106 +#: pg_backup_tar.c:1118 #, c-format msgid "could not close temporary file: %s\n" msgstr "не удалоÑÑŒ закрыть временный файл: %s\n" -#: pg_backup_tar.c:1116 +#: pg_backup_tar.c:1128 #, c-format msgid "actual file length (%s) does not match expected (%s)\n" msgstr "дейÑÑ‚Ð²Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° файла (%s) не равна ожидаемой (%s)\n" -#: pg_backup_tar.c:1153 +#: pg_backup_tar.c:1165 #, c-format msgid "moving from position %s to next member at file position %s\n" msgstr "переход от позиции %s к Ñледующему компоненту в позиции %s\n" -#: pg_backup_tar.c:1164 +#: pg_backup_tar.c:1176 #, c-format msgid "now at file position %s\n" msgstr "Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² файле %s\n" -#: pg_backup_tar.c:1173 pg_backup_tar.c:1203 +#: pg_backup_tar.c:1185 pg_backup_tar.c:1215 #, c-format msgid "could not find header for file \"%s\" in tar archive\n" msgstr "в архиве tar не найден заголовок Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\"\n" -#: pg_backup_tar.c:1187 +#: pg_backup_tar.c:1199 #, c-format msgid "skipping tar member %s\n" msgstr "пропуÑкаетÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚ tar %s\n" -#: pg_backup_tar.c:1191 +#: pg_backup_tar.c:1203 #, c-format msgid "" "restoring data out of order is not supported in this archive format: \"%s\" " @@ -1383,7 +1363,7 @@ msgstr "" "поддерживаетÑÑ: требуетÑÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚ \"%s\", но в файле архива прежде идёт " "\"%s\".\n" -#: pg_backup_tar.c:1237 +#: pg_backup_tar.c:1249 #, c-format msgid "incomplete tar header found (%lu byte)\n" msgid_plural "incomplete tar header found (%lu bytes)\n" @@ -1392,12 +1372,12 @@ msgstr[1] "найден неполный tar-заголовок (размер %l msgstr[2] "найден неполный tar-заголовок (размер %lu байтов)\n" # skip-rule: capital-letter-first -#: pg_backup_tar.c:1278 +#: pg_backup_tar.c:1290 #, c-format msgid "TOC Entry %s at %s (length %s, checksum %d)\n" msgstr "ЗапиÑÑŒ Ð¾Ð³Ð»Ð°Ð²Ð»ÐµÐ½Ð¸Ñ %s в %s (длина: %s, контр. Ñумма: %d)\n" -#: pg_backup_tar.c:1289 +#: pg_backup_tar.c:1301 #, c-format msgid "" "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" @@ -1410,10 +1390,9 @@ msgstr "" msgid "%s: unrecognized section name: \"%s\"\n" msgstr "%s: нераÑпознанное Ð¸Ð¼Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð°: \"%s\"\n" -#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:309 -#: pg_dumpall.c:319 pg_dumpall.c:329 pg_dumpall.c:338 pg_dumpall.c:354 -#: pg_dumpall.c:363 pg_dumpall.c:431 pg_restore.c:281 pg_restore.c:297 -#: pg_restore.c:309 +#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:313 +#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 +#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" @@ -1428,7 +1407,7 @@ msgstr "превышен предел обработчиков штатного msgid "compression level must be in range 0..9\n" msgstr "уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ быть в диапазоне 0..9\n" -#: pg_dump.c:560 pg_dumpall.c:317 pg_restore.c:295 +#: pg_dump.c:560 pg_dumpall.c:321 pg_restore.c:297 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" @@ -1512,7 +1491,7 @@ msgstr "ÑоответÑтвующие Ñхемы не найдены\n" msgid "no matching tables were found\n" msgstr "ÑоответÑтвующие таблицы не найдены\n" -#: pg_dump.c:912 +#: pg_dump.c:913 #, c-format msgid "" "%s dumps a database as a text file or to other formats.\n" @@ -1521,17 +1500,17 @@ msgstr "" "%s ÑохранÑет резервную копию БД в текÑтовом файле или другом виде.\n" "\n" -#: pg_dump.c:913 pg_dumpall.c:576 pg_restore.c:446 +#: pg_dump.c:914 pg_dumpall.c:575 pg_restore.c:449 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" -#: pg_dump.c:914 +#: pg_dump.c:915 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [ПÐРÐМЕТР]... [ИМЯ_БД]\n" -#: pg_dump.c:916 pg_dumpall.c:579 pg_restore.c:449 +#: pg_dump.c:917 pg_dumpall.c:578 pg_restore.c:452 #, c-format msgid "" "\n" @@ -1540,12 +1519,12 @@ msgstr "" "\n" "Общие параметры:\n" -#: pg_dump.c:917 +#: pg_dump.c:918 #, c-format msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=ИМЯ Ð¸Ð¼Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла или каталога\n" -#: pg_dump.c:918 +#: pg_dump.c:919 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1555,7 +1534,7 @@ msgstr "" " (пользовательÑкий | каталог | tar |\n" " текÑтовый (по умолчанию))\n" -#: pg_dump.c:920 +#: pg_dump.c:921 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr "" @@ -1563,23 +1542,23 @@ msgstr "" "чиÑло\n" " заданий\n" -#: pg_dump.c:921 pg_dumpall.c:581 +#: pg_dump.c:922 pg_dumpall.c:580 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose режим подробных Ñообщений\n" -#: pg_dump.c:922 pg_dumpall.c:582 +#: pg_dump.c:923 pg_dumpall.c:581 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: pg_dump.c:923 +#: pg_dump.c:924 #, c-format msgid "" " -Z, --compress=0-9 compression level for compressed formats\n" msgstr " -Z, --compress=0-9 уровень ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð¿Ñ€Ð¸ архивации\n" -#: pg_dump.c:924 pg_dumpall.c:583 +#: pg_dump.c:925 pg_dumpall.c:582 #, c-format msgid "" " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" @@ -1587,7 +1566,7 @@ msgstr "" " --lock-wait-timeout=ТÐЙМÐУТ прервать операцию при таймауте блокировки " "таблицы\n" -#: pg_dump.c:925 pg_dumpall.c:603 +#: pg_dump.c:926 pg_dumpall.c:605 #, c-format msgid "" " --no-sync do not wait for changes to be written safely " @@ -1596,12 +1575,12 @@ msgstr "" " --no-sync не ждать надёжного ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ на " "диÑке\n" -#: pg_dump.c:926 pg_dumpall.c:584 +#: pg_dump.c:927 pg_dumpall.c:583 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_dump.c:928 pg_dumpall.c:585 +#: pg_dump.c:929 pg_dumpall.c:584 #, c-format msgid "" "\n" @@ -1610,22 +1589,22 @@ msgstr "" "\n" "Параметры, управлÑющие выводом:\n" -#: pg_dump.c:929 pg_dumpall.c:586 +#: pg_dump.c:930 pg_dumpall.c:585 #, c-format msgid " -a, --data-only dump only the data, not the schema\n" msgstr " -a, --data-only выгрузить только данные, без Ñхемы\n" -#: pg_dump.c:930 +#: pg_dump.c:931 #, c-format msgid " -b, --blobs include large objects in dump\n" msgstr " -b, --blobs выгрузить также большие объекты\n" -#: pg_dump.c:931 +#: pg_dump.c:932 #, c-format msgid " -B, --no-blobs exclude large objects in dump\n" msgstr " -B, --no-blobs иÑключить из выгрузки большие объекты\n" -#: pg_dump.c:932 pg_restore.c:460 +#: pg_dump.c:933 pg_restore.c:463 #, c-format msgid "" " -c, --clean clean (drop) database objects before " @@ -1634,7 +1613,7 @@ msgstr "" " -c, --clean очиÑтить (удалить) объекты БД при " "воÑÑтановлении\n" -#: pg_dump.c:933 +#: pg_dump.c:934 #, c-format msgid "" " -C, --create include commands to create database in dump\n" @@ -1642,27 +1621,27 @@ msgstr "" " -C, --create добавить в копию команды ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð°Ð·Ñ‹ " "данных\n" -#: pg_dump.c:934 +#: pg_dump.c:935 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=КОДИРОВКРвыгружать данные в заданной кодировке\n" -#: pg_dump.c:935 +#: pg_dump.c:936 #, c-format msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" msgstr " -n, --schema=СХЕМРвыгрузить только указанную Ñхему(Ñ‹)\n" -#: pg_dump.c:936 +#: pg_dump.c:937 #, c-format msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" msgstr " -N, --exclude-schema=СХЕМРÐЕ выгружать указанную Ñхему(Ñ‹)\n" -#: pg_dump.c:937 pg_dumpall.c:589 +#: pg_dump.c:938 pg_dumpall.c:588 #, c-format msgid " -o, --oids include OIDs in dump\n" msgstr " -o, --oids выгружать данные Ñ OID\n" -#: pg_dump.c:938 +#: pg_dump.c:939 #, c-format msgid "" " -O, --no-owner skip restoration of object ownership in\n" @@ -1671,12 +1650,12 @@ msgstr "" " -O, --no-owner не воÑÑтанавливать владение объектами\n" " при иÑпользовании текÑтового формата\n" -#: pg_dump.c:940 pg_dumpall.c:592 +#: pg_dump.c:941 pg_dumpall.c:591 #, c-format msgid " -s, --schema-only dump only the schema, no data\n" msgstr " -s, --schema-only выгрузить только Ñхему, без данных\n" -#: pg_dump.c:941 +#: pg_dump.c:942 #, c-format msgid "" " -S, --superuser=NAME superuser user name to use in plain-text " @@ -1685,27 +1664,27 @@ msgstr "" " -S, --superuser=ИМЯ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ, который будет задейÑтвован\n" " при воÑÑтановлении из текÑтового формата\n" -#: pg_dump.c:942 +#: pg_dump.c:943 #, c-format msgid " -t, --table=TABLE dump the named table(s) only\n" msgstr " -t, --table=ТÐБЛИЦРвыгрузить только указанную таблицу(Ñ‹)\n" -#: pg_dump.c:943 +#: pg_dump.c:944 #, c-format msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" msgstr " -T, --exclude-table=ТÐБЛИЦРÐЕ выгружать указанную таблицу(Ñ‹)\n" -#: pg_dump.c:944 pg_dumpall.c:595 +#: pg_dump.c:945 pg_dumpall.c:594 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges не выгружать права (назначение/отзыв)\n" -#: pg_dump.c:945 pg_dumpall.c:596 +#: pg_dump.c:946 pg_dumpall.c:595 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade только Ð´Ð»Ñ ÑƒÑ‚Ð¸Ð»Ð¸Ñ‚ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð‘Ð”\n" -#: pg_dump.c:946 pg_dumpall.c:597 +#: pg_dump.c:947 pg_dumpall.c:596 #, c-format msgid "" " --column-inserts dump data as INSERT commands with column " @@ -1714,7 +1693,7 @@ msgstr "" " --column-inserts выгружать данные в виде INSERT Ñ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸ " "Ñтолбцов\n" -#: pg_dump.c:947 pg_dumpall.c:598 +#: pg_dump.c:948 pg_dumpall.c:597 #, c-format msgid "" " --disable-dollar-quoting disable dollar quoting, use SQL standard " @@ -1723,7 +1702,7 @@ msgstr "" " --disable-dollar-quoting отключить ÑпецÑтроки Ñ $, выводить Ñтроки\n" " по Ñтандарту SQL\n" -#: pg_dump.c:948 pg_dumpall.c:599 pg_restore.c:477 +#: pg_dump.c:949 pg_dumpall.c:598 pg_restore.c:480 #, c-format msgid "" " --disable-triggers disable triggers during data-only restore\n" @@ -1731,7 +1710,7 @@ msgstr "" " --disable-triggers отключить триггеры при воÑÑтановлении\n" " только данных, без Ñхемы\n" -#: pg_dump.c:949 +#: pg_dump.c:950 #, c-format msgid "" " --enable-row-security enable row security (dump only content user " @@ -1742,25 +1721,19 @@ msgstr "" "только\n" " те данные, которые доÑтупны пользователю)\n" -#: pg_dump.c:951 +#: pg_dump.c:952 #, c-format msgid "" " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" msgstr " --exclude-table-data=ТÐБЛИЦРÐЕ выгружать указанную таблицу(Ñ‹)\n" -#: pg_dump.c:952 pg_dumpall.c:600 pg_restore.c:479 +#: pg_dump.c:953 pg_dumpall.c:599 pg_restore.c:482 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr "" " --if-exists применÑть IF EXISTS при удалении объектов\n" -#: pg_dump.c:953 -#, c-format -msgid " --include-subscriptions dump logical replication subscriptions\n" -msgstr "" -" --include-subscriptions выгрузить подпиÑки логичеÑкой репликации\n" - -#: pg_dump.c:954 pg_dumpall.c:601 +#: pg_dump.c:954 pg_dumpall.c:600 #, c-format msgid "" " --inserts dump data as INSERT commands, rather than " @@ -1769,23 +1742,23 @@ msgstr "" " --inserts выгрузить данные в виде команд INSERT, не " "COPY\n" -#: pg_dump.c:955 pg_dumpall.c:602 +#: pg_dump.c:955 pg_dumpall.c:601 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications не выгружать публикации\n" + +#: pg_dump.c:956 pg_dumpall.c:603 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr "" " --no-security-labels не выгружать Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¼ÐµÑ‚Ð¾Ðº безопаÑноÑти\n" -#: pg_dump.c:956 +#: pg_dump.c:957 pg_dumpall.c:604 #, c-format -msgid "" -" --no-subscription-connect dump subscriptions so they don't connect on " -"restore\n" -msgstr "" -" --no-subscription-connect выгружать подпиÑки так, чтобы они не " -"подключалиÑÑŒ\n" -" при воÑÑтановлении\n" +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions не выгружать подпиÑки\n" -#: pg_dump.c:957 +#: pg_dump.c:958 #, c-format msgid "" " --no-synchronized-snapshots do not use synchronized snapshots in parallel " @@ -1794,20 +1767,20 @@ msgstr "" " --no-synchronized-snapshots не иÑпользовать Ñинхронизированные Ñнимки\n" " в параллельных заданиÑÑ…\n" -#: pg_dump.c:958 pg_dumpall.c:604 +#: pg_dump.c:959 pg_dumpall.c:606 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr "" " --no-tablespaces не выгружать Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ‡Ð½Ñ‹Ñ… " "проÑтранÑтв\n" -#: pg_dump.c:959 pg_dumpall.c:605 +#: pg_dump.c:960 pg_dumpall.c:607 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr "" " --no-unlogged-table-data не выгружать данные нежурналируемых таблиц\n" -#: pg_dump.c:960 pg_dumpall.c:607 +#: pg_dump.c:961 pg_dumpall.c:608 #, c-format msgid "" " --quote-all-identifiers quote all identifiers, even if not key words\n" @@ -1815,7 +1788,7 @@ msgstr "" " --quote-all-identifiers заключать в кавычки вÑе идентификаторы,\n" " а не только ключевые Ñлова\n" -#: pg_dump.c:961 +#: pg_dump.c:962 #, c-format msgid "" " --section=SECTION dump named section (pre-data, data, or post-" @@ -1824,7 +1797,7 @@ msgstr "" " --section=РÐЗДЕЛ выгрузить заданный раздел\n" " (pre-data, data или post-data)\n" -#: pg_dump.c:962 +#: pg_dump.c:963 #, c-format msgid "" " --serializable-deferrable wait until the dump can run without " @@ -1833,13 +1806,13 @@ msgstr "" " --serializable-deferrable дождатьÑÑ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° Ð´Ð»Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ¸ данных без " "аномалий\n" -#: pg_dump.c:963 +#: pg_dump.c:964 #, c-format msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr "" " --snapshot=СÐИМОК иÑпользовать при выгрузке заданный Ñнимок\n" -#: pg_dump.c:964 pg_restore.c:485 +#: pg_dump.c:965 pg_restore.c:490 #, c-format msgid "" " --strict-names require table and/or schema include patterns " @@ -1852,7 +1825,7 @@ msgstr "" "минимум\n" " один объект\n" -#: pg_dump.c:966 pg_dumpall.c:608 pg_restore.c:487 +#: pg_dump.c:967 pg_dumpall.c:609 pg_restore.c:492 #, c-format msgid "" " --use-set-session-authorization\n" @@ -1864,7 +1837,7 @@ msgstr "" " уÑтанавливать владельца, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ‹\n" " SET SESSION AUTHORIZATION вмеÑто ALTER OWNER\n" -#: pg_dump.c:970 pg_dumpall.c:612 pg_restore.c:491 +#: pg_dump.c:971 pg_dumpall.c:613 pg_restore.c:496 #, c-format msgid "" "\n" @@ -1873,33 +1846,33 @@ msgstr "" "\n" "Параметры подключениÑ:\n" -#: pg_dump.c:971 +#: pg_dump.c:972 #, c-format msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=БД Ð¸Ð¼Ñ Ð±Ð°Ð·Ñ‹ данных Ð´Ð»Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ¸\n" -#: pg_dump.c:972 pg_dumpall.c:614 pg_restore.c:492 +#: pg_dump.c:973 pg_dumpall.c:615 pg_restore.c:497 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=ИМЯ Ð¸Ð¼Ñ Ñервера баз данных или каталог Ñокетов\n" -#: pg_dump.c:973 pg_dumpall.c:616 pg_restore.c:493 +#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:498 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=ПОРТ номер порта Ñервера БД\n" -#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:494 +#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:499 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=ИМЯ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð±Ð°Ð· данных\n" -#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:495 +#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:500 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password не запрашивать пароль\n" -#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:496 +#: pg_dump.c:977 pg_dumpall.c:620 pg_restore.c:501 #, c-format msgid "" " -W, --password force password prompt (should happen " @@ -1907,12 +1880,12 @@ msgid "" msgstr "" " -W, --password запрашивать пароль вÑегда (обычно не требуетÑÑ)\n" -#: pg_dump.c:977 pg_dumpall.c:620 +#: pg_dump.c:978 pg_dumpall.c:621 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ИМЯ_РОЛИ выполнить SET ROLE перед выгрузкой\n" -#: pg_dump.c:979 +#: pg_dump.c:980 #, c-format msgid "" "\n" @@ -1925,192 +1898,202 @@ msgstr "" "PGDATABASE.\n" "\n" -#: pg_dump.c:981 pg_dumpall.c:624 pg_restore.c:503 +#: pg_dump.c:982 pg_dumpall.c:625 pg_restore.c:508 #, c-format msgid "Report bugs to .\n" msgstr "Об ошибках Ñообщайте по адреÑу .\n" -#: pg_dump.c:998 +#: pg_dump.c:999 #, c-format msgid "invalid client encoding \"%s\" specified\n" msgstr "указана Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚ÑÐºÐ°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° \"%s\"\n" -#: pg_dump.c:1135 +#: pg_dump.c:1136 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server " +"version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" "synchronized snapshots.\n" msgstr "" -"Ðа резервных Ñерверах Ñинхронизированные Ñнимки не поддерживаютÑÑ.\n" +"Ð’ Ñтой верÑии Ñервера Ñинхронизированные Ñнимки на ведомых Ñерверах не " +"поддерживаютÑÑ.\n" "ЕÑли они вам не нужны, укажите при запуÑке ключ\n" "--no-synchronized-snapshots.\n" -#: pg_dump.c:1204 +#: pg_dump.c:1205 #, c-format msgid "invalid output format \"%s\" specified\n" msgstr "указан неверный формат вывода: \"%s\"\n" -#: pg_dump.c:1242 +#: pg_dump.c:1243 #, c-format msgid "no matching schemas were found for pattern \"%s\"\n" msgstr "Ñхемы, ÑоответÑтвующие шаблону \"%s\", не найдены\n" -#: pg_dump.c:1296 +#: pg_dump.c:1297 #, c-format msgid "no matching tables were found for pattern \"%s\"\n" msgstr "таблицы, ÑоответÑтвующие шаблону \"%s\", не найдены\n" -#: pg_dump.c:1700 +#: pg_dump.c:1701 #, c-format msgid "dumping contents of table \"%s.%s\"\n" msgstr "выгрузка Ñодержимого таблицы \"%s.%s\"\n" -#: pg_dump.c:1821 +#: pg_dump.c:1822 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" msgstr "Ошибка выгрузки таблицы \"%s\": Ñбой в PQendcopy().\n" -#: pg_dump.c:1822 pg_dump.c:1832 +#: pg_dump.c:1823 pg_dump.c:1833 #, c-format msgid "Error message from server: %s" msgstr "Сообщение об ошибке Ñ Ñервера: %s" -#: pg_dump.c:1823 pg_dump.c:1833 +#: pg_dump.c:1824 pg_dump.c:1834 #, c-format msgid "The command was: %s\n" msgstr "ВыполнÑлаÑÑŒ команда: %s\n" -#: pg_dump.c:1831 +#: pg_dump.c:1832 #, c-format msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" msgstr "Ошибка выгрузки таблицы \"%s\": Ñбой в PQgetResult().\n" -#: pg_dump.c:2477 +#: pg_dump.c:2482 #, c-format msgid "saving database definition\n" msgstr "Ñохранение Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ñ‹ данных\n" -#: pg_dump.c:2783 +#: pg_dump.c:2795 #, c-format msgid "saving encoding = %s\n" msgstr "Ñохранение кодировки (%s)\n" -#: pg_dump.c:2810 +#: pg_dump.c:2822 #, c-format msgid "saving standard_conforming_strings = %s\n" msgstr "Ñохранение standard_conforming_strings (%s)\n" -#: pg_dump.c:2850 +#: pg_dump.c:2862 #, c-format msgid "reading large objects\n" msgstr "чтение больших объектов\n" -#: pg_dump.c:3045 +#: pg_dump.c:3057 #, c-format msgid "saving large objects\n" msgstr "Ñохранение больших объектов\n" -#: pg_dump.c:3090 +#: pg_dump.c:3102 #, c-format msgid "error reading large object %u: %s" msgstr "ошибка Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¾Ð³Ð¾ объекта %u: %s" -#: pg_dump.c:3143 +#: pg_dump.c:3155 #, c-format msgid "reading row security enabled for table \"%s.%s\"\n" msgstr "чтение информации о защите Ñтрок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"\n" -#: pg_dump.c:3175 +#: pg_dump.c:3187 #, c-format msgid "reading policies for table \"%s.%s\"\n" msgstr "чтение политик таблицы \"%s.%s\"\n" -#: pg_dump.c:3325 +#: pg_dump.c:3337 #, c-format msgid "unexpected policy command type: %c\n" msgstr "нераÑпознанный тип команды в политике: %c\n" -#: pg_dump.c:3440 +#: pg_dump.c:3456 #, c-format msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у публикации \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:3546 +#: pg_dump.c:3589 #, c-format msgid "reading publication membership for table \"%s.%s\"\n" msgstr "чтение информации об учаÑтии в репликации таблицы \"%s.%s\"\n" -#: pg_dump.c:3711 +#: pg_dump.c:3738 +#, c-format +msgid "" +"WARNING: subscriptions not dumped because current user is not a superuser\n" +msgstr "" +"ПРЕДУПРЕЖДЕÐИЕ: подпиÑки не выгружены, так как текущий пользователь не " +"Ñуперпользователь\n" + +#: pg_dump.c:3792 #, c-format msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: у подпиÑки \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:3751 +#: pg_dump.c:3836 #, c-format msgid "WARNING: could not parse subpublications array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив subpublications\n" -#: pg_dump.c:3976 +#: pg_dump.c:4069 #, c-format msgid "could not find parent extension for %s\n" msgstr "не удалоÑÑŒ найти родительÑкое раÑширение Ð´Ð»Ñ %s\n" # TO REVIEW -#: pg_dump.c:4125 +#: pg_dump.c:4223 #, c-format msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: у Ñхемы \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:4148 +#: pg_dump.c:4246 #, c-format msgid "schema with OID %u does not exist\n" msgstr "Ñхема Ñ OID %u не ÑущеÑтвует\n" -#: pg_dump.c:4479 +#: pg_dump.c:4577 #, c-format msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у типа данных \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:4567 +#: pg_dump.c:4665 #, c-format msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: у оператора \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:4881 +#: pg_dump.c:4979 #, c-format msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у клаÑÑа операторов \"%s\" по-видимому неправильный " "владелец\n" -#: pg_dump.c:4968 +#: pg_dump.c:5066 #, c-format msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у ÑемейÑтва операторов \"%s\" по-видимому неправильный " "владелец\n" -#: pg_dump.c:5135 +#: pg_dump.c:5233 #, c-format msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у агрегатной функции \"%s\" по-видимому неправильный " "владелец\n" -#: pg_dump.c:5394 +#: pg_dump.c:5492 #, c-format msgid "WARNING: owner of function \"%s\" appears to be invalid\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: у функции \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:6112 +#: pg_dump.c:6274 #, c-format msgid "WARNING: owner of table \"%s\" appears to be invalid\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: у таблицы \"%s\" по-видимому неправильный владелец\n" -#: pg_dump.c:6154 pg_dump.c:16389 +#: pg_dump.c:6316 pg_dump.c:16552 #, c-format msgid "" "failed sanity check, parent table with OID %u of sequence with OID %u not " @@ -2119,22 +2102,17 @@ msgstr "" "нарушение целоÑтноÑти: по OID %u не удалоÑÑŒ найти родительÑкую таблицу " "поÑледовательноÑти Ñ OID %u\n" -#: pg_dump.c:6355 +#: pg_dump.c:6447 #, c-format msgid "reading indexes for table \"%s.%s\"\n" msgstr "чтение индекÑов таблицы \"%s.%s\"\n" -#: pg_dump.c:6631 -#, c-format -msgid "reading extended statistics for table \"%s.%s\"\n" -msgstr "чтение раÑширенной ÑтатиÑтики Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"\n" - -#: pg_dump.c:6714 +#: pg_dump.c:6783 #, c-format msgid "reading foreign key constraints for table \"%s.%s\"\n" msgstr "чтение ограничений внешних ключей таблицы \"%s.%s\"\n" -#: pg_dump.c:6938 +#: pg_dump.c:7007 #, c-format msgid "" "failed sanity check, parent table with OID %u of pg_rewrite entry with OID " @@ -2143,12 +2121,12 @@ msgstr "" "нарушение целоÑтноÑти: по OID %u не удалоÑÑŒ найти родительÑкую таблицу Ð´Ð»Ñ " "запиÑи pg_rewrite Ñ OID %u\n" -#: pg_dump.c:7022 +#: pg_dump.c:7091 #, c-format msgid "reading triggers for table \"%s.%s\"\n" msgstr "чтение триггеров таблицы \"%s.%s\"\n" -#: pg_dump.c:7160 +#: pg_dump.c:7229 #, c-format msgid "" "query produced null referenced table name for foreign key trigger \"%s\" on " @@ -2157,32 +2135,32 @@ msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ вернул Ð¸Ð¼Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð¹ таблицы Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° внешнего ключа \"%s\" в " "таблице \"%s\" (OID целевой таблицы: %u)\n" -#: pg_dump.c:7774 +#: pg_dump.c:7801 #, c-format msgid "finding the columns and types of table \"%s.%s\"\n" msgstr "поиÑк Ñтолбцов и типов таблицы \"%s.%s\"\n" -#: pg_dump.c:7910 +#: pg_dump.c:7966 #, c-format msgid "invalid column numbering in table \"%s\"\n" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð½ÑƒÐ¼ÐµÑ€Ð°Ñ†Ð¸Ñ Ñтолбцов в таблице \"%s\"\n" -#: pg_dump.c:7944 +#: pg_dump.c:8002 #, c-format msgid "finding default expressions of table \"%s.%s\"\n" msgstr "поиÑк выражений по умолчанию Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"\n" -#: pg_dump.c:7967 +#: pg_dump.c:8025 #, c-format msgid "invalid adnum value %d for table \"%s\"\n" msgstr "неверное значение adnum (%d) в таблице \"%s\"\n" -#: pg_dump.c:8033 +#: pg_dump.c:8091 #, c-format msgid "finding check constraints for table \"%s.%s\"\n" msgstr "поиÑк ограничений-проверок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"\n" -#: pg_dump.c:8082 +#: pg_dump.c:8140 #, c-format msgid "expected %d check constraint on table \"%s\" but found %d\n" msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" @@ -2193,72 +2171,72 @@ msgstr[1] "" msgstr[2] "" "ожидалоÑÑŒ %d ограничений-проверок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\", но найдено: %d\n" -#: pg_dump.c:8086 +#: pg_dump.c:8144 #, c-format msgid "(The system catalogs might be corrupted.)\n" msgstr "(Возможно повреждены ÑиÑтемные каталоги.)\n" -#: pg_dump.c:9644 +#: pg_dump.c:9702 #, c-format msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: у типа данных \"%s\" по-видимому неправильный тип типа\n" -#: pg_dump.c:11073 +#: pg_dump.c:11131 #, c-format msgid "WARNING: bogus value in proargmodes array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое значение в маÑÑиве proargmodes\n" -#: pg_dump.c:11399 +#: pg_dump.c:11457 #, c-format msgid "WARNING: could not parse proallargtypes array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив proallargtypes\n" -#: pg_dump.c:11415 +#: pg_dump.c:11473 #, c-format msgid "WARNING: could not parse proargmodes array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив proargmodes\n" -#: pg_dump.c:11429 +#: pg_dump.c:11487 #, c-format msgid "WARNING: could not parse proargnames array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив proargnames\n" -#: pg_dump.c:11440 +#: pg_dump.c:11498 #, c-format msgid "WARNING: could not parse proconfig array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив proconfig\n" # TO REVEIW -#: pg_dump.c:11511 +#: pg_dump.c:11569 #, c-format msgid "unrecognized provolatile value for function \"%s\"\n" msgstr "недопуÑтимое значение provolatile Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ \"%s\"\n" # TO REVEIW -#: pg_dump.c:11555 pg_dump.c:13538 +#: pg_dump.c:11613 pg_dump.c:13611 #, c-format msgid "unrecognized proparallel value for function \"%s\"\n" msgstr "недопуÑтимое значение proparallel Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ \"%s\"\n" -#: pg_dump.c:11663 pg_dump.c:11773 pg_dump.c:11780 +#: pg_dump.c:11721 pg_dump.c:11831 pg_dump.c:11838 #, c-format msgid "could not find function definition for function with OID %u\n" msgstr "не удалоÑÑŒ найти определение функции Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ Ñ OID %u\n" -#: pg_dump.c:11708 +#: pg_dump.c:11766 #, c-format msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое значение в поле pg_cast.castfunc или pg_cast." "castmethod\n" -#: pg_dump.c:11711 +#: pg_dump.c:11769 #, c-format msgid "WARNING: bogus value in pg_cast.castmethod field\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое значение в поле pg_cast.castmethod\n" -#: pg_dump.c:11801 +#: pg_dump.c:11859 #, c-format msgid "" "WARNING: bogus transform definition, at least one of trffromsql and trftosql " @@ -2267,27 +2245,27 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое определение Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ (trffromsql или " "trftosql должно быть ненулевым)\n" -#: pg_dump.c:11818 +#: pg_dump.c:11876 #, c-format msgid "WARNING: bogus value in pg_transform.trffromsql field\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое значение в поле pg_transform.trffromsql\n" -#: pg_dump.c:11839 +#: pg_dump.c:11897 #, c-format msgid "WARNING: bogus value in pg_transform.trftosql field\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: неприемлемое значение в поле pg_transform.trftosql\n" -#: pg_dump.c:12235 +#: pg_dump.c:12293 #, c-format msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: неверный тип \"%c\" метода доÑтупа \"%s\"\n" -#: pg_dump.c:13001 +#: pg_dump.c:13074 #, c-format msgid "unrecognized collation provider: %s\n" msgstr "нераÑпознанный поÑтавщик правил Ñортировки: %s\n" -#: pg_dump.c:13448 +#: pg_dump.c:13521 #, c-format msgid "" "WARNING: aggregate function %s could not be dumped correctly for this " @@ -2296,17 +2274,17 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: Ð°Ð³Ñ€ÐµÐ³Ð°Ñ‚Ð½Ð°Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ %s не может быть правильно выгружена Ð´Ð»Ñ " "Ñтой верÑии базы данных; Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¾Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð°\n" -#: pg_dump.c:14304 +#: pg_dump.c:14375 #, c-format msgid "unrecognized object type in default privileges: %d\n" msgstr "нераÑпознанный тип объекта в определении прав по умолчанию: %d)\n" -#: pg_dump.c:14322 +#: pg_dump.c:14393 #, c-format msgid "could not parse default ACL list (%s)\n" msgstr "не удалоÑÑŒ разобрать ÑпиÑок прав по умолчанию (%s)\n" -#: pg_dump.c:14393 +#: pg_dump.c:14475 #, c-format msgid "" "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) " @@ -2315,7 +2293,7 @@ msgstr "" "не удалоÑÑŒ разобрать изначальный ÑпиÑок GRANT ACL (%s) или изначальный " "ÑпиÑок REVOKE ACL (%s) Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° \"%s\" (%s)\n" -#: pg_dump.c:14401 +#: pg_dump.c:14483 #, c-format msgid "" "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s" @@ -2324,13 +2302,13 @@ msgstr "" "не удалоÑÑŒ разобрать ÑпиÑок GRANT ACL (%s) или ÑпиÑок REVOKE ACL (%s) Ð´Ð»Ñ " "объекта \"%s\" (%s)\n" -#: pg_dump.c:14876 +#: pg_dump.c:14963 #, c-format msgid "query to obtain definition of view \"%s\" returned no data\n" msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° получение Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" не возвратил данные\n" -#: pg_dump.c:14879 +#: pg_dump.c:14966 #, c-format msgid "" "query to obtain definition of view \"%s\" returned more than one definition\n" @@ -2338,27 +2316,32 @@ msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´ÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" возвратил неÑколько " "определений\n" -#: pg_dump.c:14886 +#: pg_dump.c:14973 #, c-format msgid "definition of view \"%s\" appears to be empty (length zero)\n" msgstr "определение предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ \"%s\" пуÑтое (длина равна нулю)\n" -#: pg_dump.c:15733 +#: pg_dump.c:15202 +#, c-format +msgid "invalid number of parents %d for table \"%s\"\n" +msgstr "неверное чиÑло родителей (%d) Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"\n" + +#: pg_dump.c:15849 #, c-format msgid "invalid column number %d for table \"%s\"\n" msgstr "неверный номер Ñтолбца %d Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\"\n" -#: pg_dump.c:15917 +#: pg_dump.c:16051 #, c-format msgid "missing index for constraint \"%s\"\n" msgstr "отÑутÑтвует Ð¸Ð½Ð´ÐµÐºÑ Ð´Ð»Ñ Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ \"%s\"\n" -#: pg_dump.c:16120 +#: pg_dump.c:16254 #, c-format msgid "unrecognized constraint type: %c\n" msgstr "нераÑпознанный тип ограничениÑ: %c\n" -#: pg_dump.c:16257 pg_dump.c:16457 +#: pg_dump.c:16394 pg_dump.c:16620 #, c-format msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" msgid_plural "" @@ -2373,17 +2356,17 @@ msgstr[2] "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° получение данных поÑледовательноÑти \"%s\" вернул %d Ñтрок " "(ожидалаÑÑŒ 1)\n" -#: pg_dump.c:16555 +#: pg_dump.c:16718 #, c-format msgid "unexpected tgtype value: %d\n" msgstr "неожиданное значение tgtype: %d\n" -#: pg_dump.c:16629 +#: pg_dump.c:16792 #, c-format msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñтрока аргументов (%s) Ð´Ð»Ñ Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð° \"%s\" таблицы \"%s\"\n" -#: pg_dump.c:16850 +#: pg_dump.c:17023 #, c-format msgid "" "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows " @@ -2392,12 +2375,12 @@ msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° получение правила \"%s\" Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s\" возвратил неверное " "чиÑло Ñтрок\n" -#: pg_dump.c:17245 +#: pg_dump.c:17418 #, c-format msgid "reading dependency data\n" msgstr "чтение данных о завиÑимоÑÑ‚ÑÑ…\n" -#: pg_dump.c:17710 +#: pg_dump.c:17883 #, c-format msgid "WARNING: could not parse reloptions array\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разобрать маÑÑив reloptions\n" @@ -2464,7 +2447,7 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: не удалоÑÑŒ разрешить цикл завиÑимоÑтей Ð´Ð»Ñ Ñледующих " "объектов:\n" -#: pg_dumpall.c:185 +#: pg_dumpall.c:189 #, c-format msgid "" "The program \"pg_dump\" is needed by %s but was not found in the\n" @@ -2475,7 +2458,7 @@ msgstr "" "в каталоге \"%s\".\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_dumpall.c:192 +#: pg_dumpall.c:196 #, c-format msgid "" "The program \"pg_dump\" was found by \"%s\"\n" @@ -2486,14 +2469,14 @@ msgstr "" "но её верÑÐ¸Ñ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð°ÐµÑ‚ÑÑ Ð¾Ñ‚ верÑии %s.\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_dumpall.c:327 +#: pg_dumpall.c:331 #, c-format msgid "" "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" msgstr "" "%s: параметры -g/--globals-only и -r/--roles-only иÑключают друг друга\n" -#: pg_dumpall.c:336 +#: pg_dumpall.c:340 #, c-format msgid "" "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used " @@ -2502,12 +2485,12 @@ msgstr "" "%s: параметры -g/--globals-only и -t/--tablespaces-only иÑключают друг " "друга\n" -#: pg_dumpall.c:345 pg_restore.c:364 +#: pg_dumpall.c:349 pg_restore.c:367 #, c-format msgid "%s: option --if-exists requires option -c/--clean\n" msgstr "%s: параметру --if-exists требуетÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€ -c/--clean\n" -#: pg_dumpall.c:352 +#: pg_dumpall.c:356 #, c-format msgid "" "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used " @@ -2515,20 +2498,12 @@ msgid "" msgstr "" "%s: параметры -r/--roles-only и -t/--tablespaces-only иÑключают друг друга\n" -#: pg_dumpall.c:361 -#, c-format -msgid "" -"%s: options --no-role-passwords and --binary-upgrade cannot be used " -"together\n" -msgstr "" -"%s: параметры --no-role-passwords и --binary-upgrade иÑключают друг друга\n" - -#: pg_dumpall.c:413 pg_dumpall.c:1982 +#: pg_dumpall.c:412 pg_dumpall.c:1983 #, c-format msgid "%s: could not connect to database \"%s\"\n" msgstr "%s: не удалоÑÑŒ подключитьÑÑ Ðº базе данных: \"%s\"\n" -#: pg_dumpall.c:428 +#: pg_dumpall.c:427 #, c-format msgid "" "%s: could not connect to databases \"postgres\" or \"template1\"\n" @@ -2537,12 +2512,12 @@ msgstr "" "%s: не удалоÑÑŒ подключитьÑÑ Ðº базе данных \"postgres\" или \"template1\"\n" "Укажите другую базу данных.\n" -#: pg_dumpall.c:445 +#: pg_dumpall.c:444 #, c-format msgid "%s: could not open the output file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть выходной файл \"%s\": %s\n" -#: pg_dumpall.c:575 +#: pg_dumpall.c:574 #, c-format msgid "" "%s extracts a PostgreSQL database cluster into an SQL script file.\n" @@ -2551,17 +2526,17 @@ msgstr "" "%s ÑкÑпортирует вÑÑ‘ Ñодержимое клаÑтера баз данных PostgreSQL в SQL-Ñкрипт.\n" "\n" -#: pg_dumpall.c:577 +#: pg_dumpall.c:576 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [ПÐРÐМЕТР]...\n" -#: pg_dumpall.c:580 +#: pg_dumpall.c:579 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=ИМЯ_ФÐÐ™Ð›Ð Ð¸Ð¼Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла\n" -#: pg_dumpall.c:587 +#: pg_dumpall.c:586 #, c-format msgid "" " -c, --clean clean (drop) databases before recreating\n" @@ -2569,18 +2544,18 @@ msgstr "" " -c, --clean очиÑтить (удалить) базы данных перед\n" " воÑÑтановлением\n" -#: pg_dumpall.c:588 +#: pg_dumpall.c:587 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr "" " -g, --globals-only выгрузить только глобальные объекты, без баз\n" -#: pg_dumpall.c:590 pg_restore.c:469 +#: pg_dumpall.c:589 pg_restore.c:472 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner не воÑÑтанавливать владение объектами\n" -#: pg_dumpall.c:591 +#: pg_dumpall.c:590 #, c-format msgid "" " -r, --roles-only dump only roles, no databases or tablespaces\n" @@ -2588,13 +2563,13 @@ msgstr "" " -r, --roles-only выгрузить только роли, без баз данных\n" " и табличных проÑтранÑтв\n" -#: pg_dumpall.c:593 +#: pg_dumpall.c:592 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr "" " -S, --superuser=ИМЯ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñ‹Ð³Ñ€ÑƒÐ·ÐºÐ¸\n" -#: pg_dumpall.c:594 +#: pg_dumpall.c:593 #, c-format msgid "" " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" @@ -2602,22 +2577,22 @@ msgstr "" " -t, --tablespaces-only выгружать только табличные проÑтранÑтва,\n" " без баз данных и ролей\n" -#: pg_dumpall.c:606 +#: pg_dumpall.c:602 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords не выгружать пароли ролей\n" -#: pg_dumpall.c:613 +#: pg_dumpall.c:614 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=СТРОКРподключитьÑÑ Ñ Ð´Ð°Ð½Ð½Ð¾Ð¹ Ñтрокой подключениÑ\n" -#: pg_dumpall.c:615 +#: pg_dumpall.c:616 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=ИМЯ_БД выбор другой базы данных по умолчанию\n" -#: pg_dumpall.c:622 +#: pg_dumpall.c:623 #, c-format msgid "" "\n" @@ -2631,120 +2606,120 @@ msgstr "" "вывод.\n" "\n" -#: pg_dumpall.c:827 +#: pg_dumpall.c:828 #, c-format msgid "%s: role name starting with \"pg_\" skipped (%s)\n" msgstr "%s: Ð¸Ð¼Ñ Ñ€Ð¾Ð»Ð¸, начинающееÑÑ Ñ \"pg_\", пропущено (%s)\n" -#: pg_dumpall.c:1207 +#: pg_dumpall.c:1208 #, c-format msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" msgstr "" "%s: не удалоÑÑŒ разобрать ÑпиÑок ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупом (%s) Ð´Ð»Ñ Ñ‚Ð°Ð±Ð». " "проÑтранÑтва \"%s\"\n" -#: pg_dumpall.c:1524 +#: pg_dumpall.c:1525 #, c-format msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" msgstr "" "%s: не удалоÑÑŒ разобрать ÑпиÑок ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупом (%s) Ð´Ð»Ñ Ð±Ð°Ð·Ñ‹ данных \"%s" "\"\n" -#: pg_dumpall.c:1738 +#: pg_dumpall.c:1739 #, c-format msgid "%s: dumping database \"%s\"...\n" msgstr "%s: выгрузка базы данных \"%s\"...\n" -#: pg_dumpall.c:1762 +#: pg_dumpall.c:1763 #, c-format msgid "%s: pg_dump failed on database \"%s\", exiting\n" msgstr "%s: ошибка pg_dump Ð´Ð»Ñ Ð±Ð°Ð·Ñ‹ данных \"%s\", выход...\n" -#: pg_dumpall.c:1771 +#: pg_dumpall.c:1772 #, c-format msgid "%s: could not re-open the output file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ повторно открыть выходной файл \"%s\": %s\n" -#: pg_dumpall.c:1816 +#: pg_dumpall.c:1817 #, c-format msgid "%s: running \"%s\"\n" msgstr "%s: выполнÑетÑÑ \"%s\"\n" -#: pg_dumpall.c:2005 +#: pg_dumpall.c:2006 #, c-format msgid "%s: could not connect to database \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ подключитьÑÑ Ðº базе \"%s\": %s\n" -#: pg_dumpall.c:2035 +#: pg_dumpall.c:2036 #, c-format msgid "%s: could not get server version\n" msgstr "%s: не удалоÑÑŒ узнать верÑию Ñервера\n" -#: pg_dumpall.c:2041 +#: pg_dumpall.c:2042 #, c-format msgid "%s: could not parse server version \"%s\"\n" msgstr "%s: не удалоÑÑŒ разобрать Ñтроку верÑии Ñервера \"%s\"\n" -#: pg_dumpall.c:2117 pg_dumpall.c:2143 +#: pg_dumpall.c:2118 pg_dumpall.c:2144 #, c-format msgid "%s: executing %s\n" msgstr "%s: выполнÑетÑÑ %s\n" -#: pg_dumpall.c:2123 pg_dumpall.c:2149 +#: pg_dumpall.c:2124 pg_dumpall.c:2150 #, c-format msgid "%s: query failed: %s" msgstr "%s: ошибка при выполнении запроÑа: %s" -#: pg_dumpall.c:2125 pg_dumpall.c:2151 +#: pg_dumpall.c:2126 pg_dumpall.c:2152 #, c-format msgid "%s: query was: %s\n" msgstr "%s: запроÑ: %s\n" # TO REVEIW -#: pg_restore.c:307 +#: pg_restore.c:309 #, c-format msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" msgstr "%s: параметры -d/--dbname и -f/--file иÑключают друг друга\n" -#: pg_restore.c:318 +#: pg_restore.c:320 #, c-format msgid "" "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" msgstr "%s: параметры -s/--schema-only и -a/--data-only иÑключают друг друга\n" -#: pg_restore.c:325 +#: pg_restore.c:327 #, c-format msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" msgstr "%s: параметры -c/--clean and -a/--data-only иÑключают друг друга\n" -#: pg_restore.c:332 +#: pg_restore.c:334 #, c-format msgid "%s: invalid number of parallel jobs\n" msgstr "%s: неверное чиÑло параллельных заданий\n" -#: pg_restore.c:340 +#: pg_restore.c:342 #, c-format msgid "%s: maximum number of parallel jobs is %d\n" msgstr "%s: макÑимальное чиÑло параллельных заданий равно %d\n" -#: pg_restore.c:349 +#: pg_restore.c:351 #, c-format msgid "%s: cannot specify both --single-transaction and multiple jobs\n" msgstr "" "%s: параметр --single-transaction допуÑкаетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ Ñ Ð¾Ð´Ð½Ð¸Ð¼ заданием\n" -#: pg_restore.c:391 +#: pg_restore.c:394 #, c-format msgid "" "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" msgstr "нераÑпознанный формат архива \"%s\"; укажите \"c\", \"d\" или \"t\"\n" -#: pg_restore.c:431 +#: pg_restore.c:434 #, c-format msgid "WARNING: errors ignored on restore: %d\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: при воÑÑтановлении проигнорировано ошибок: %d\n" -#: pg_restore.c:445 +#: pg_restore.c:448 #, c-format msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" @@ -2754,48 +2729,48 @@ msgstr "" "pg_dump.\n" "\n" -#: pg_restore.c:447 +#: pg_restore.c:450 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [ПÐРÐМЕТР]... [ФÐЙЛ]\n" -#: pg_restore.c:450 +#: pg_restore.c:453 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=БД подключитьÑÑ Ðº указанной базе данных\n" -#: pg_restore.c:451 +#: pg_restore.c:454 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=ИМЯ_ФÐÐ™Ð›Ð Ð¸Ð¼Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð¾Ð³Ð¾ файла\n" -#: pg_restore.c:452 +#: pg_restore.c:455 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr "" " -F, --format=c|d|t формат файла (должен определÑтьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки)\n" -#: pg_restore.c:453 +#: pg_restore.c:456 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list вывеÑти краткое оглавление архива\n" -#: pg_restore.c:454 +#: pg_restore.c:457 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose выводить подробные ÑообщениÑ\n" -#: pg_restore.c:455 +#: pg_restore.c:458 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: pg_restore.c:456 +#: pg_restore.c:459 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_restore.c:458 +#: pg_restore.c:461 #, c-format msgid "" "\n" @@ -2804,35 +2779,35 @@ msgstr "" "\n" "Параметры, управлÑющие воÑÑтановлением:\n" -#: pg_restore.c:459 +#: pg_restore.c:462 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only воÑÑтановить только данные, без Ñхемы\n" -#: pg_restore.c:461 +#: pg_restore.c:464 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create Ñоздать целевую базу данных\n" -#: pg_restore.c:462 +#: pg_restore.c:465 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr "" " -e, --exit-on-error выйти при ошибке (по умолчанию - продолжать)\n" -#: pg_restore.c:463 +#: pg_restore.c:466 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=ИМЯ воÑÑтановить указанный индекÑ\n" -#: pg_restore.c:464 +#: pg_restore.c:467 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr "" " -j, --jobs=ЧИСЛО раÑпараллелить воÑÑтановление на указанное " "чиÑло заданий\n" -#: pg_restore.c:465 +#: pg_restore.c:468 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -2841,13 +2816,13 @@ msgstr "" " -L, --use-list=ИМЯ_ФÐЙЛРиÑпользовать оглавление из Ñтого файла длÑ\n" " чтениÑ/упорÑÐ´Ð¾Ñ‡Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…\n" -#: pg_restore.c:467 +#: pg_restore.c:470 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr "" " -n, --schema=ИМЯ воÑÑтановить объекты только в Ñтой Ñхеме\n" -#: pg_restore.c:468 +#: pg_restore.c:471 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr "" @@ -2855,17 +2830,17 @@ msgstr "" # skip-rule: no-space-before-parentheses # well-spelled: арг -#: pg_restore.c:470 +#: pg_restore.c:473 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=ИМЯ(арг-ты) воÑÑтановить заданную функцию\n" -#: pg_restore.c:471 +#: pg_restore.c:474 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only воÑÑтановить только Ñхему, без данных\n" -#: pg_restore.c:472 +#: pg_restore.c:475 #, c-format msgid "" " -S, --superuser=NAME superuser user name to use for disabling " @@ -2874,7 +2849,7 @@ msgstr "" " -S, --superuser=ИМЯ Ð¸Ð¼Ñ ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¾Ñ‚ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ " "триггеров\n" -#: pg_restore.c:473 +#: pg_restore.c:476 #, c-format msgid "" " -t, --table=NAME restore named relation (table, view, etc.)\n" @@ -2882,12 +2857,12 @@ msgstr "" " -t, --table=ИМЯ воÑÑтановить заданное отношение (таблицу, " "предÑтавление и Ñ‚. п.)\n" -#: pg_restore.c:474 +#: pg_restore.c:477 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=ИМЯ воÑÑтановить заданный триггер\n" -#: pg_restore.c:475 +#: pg_restore.c:478 #, c-format msgid "" " -x, --no-privileges skip restoration of access privileges (grant/" @@ -2896,18 +2871,18 @@ msgstr "" " -x, --no-privileges не воÑÑтанавливать права доÑтупа\n" " (назначение/отзыв)\n" -#: pg_restore.c:476 +#: pg_restore.c:479 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr "" " -1, --single-transaction выполнить воÑÑтановление в одной транзакции\n" -#: pg_restore.c:478 +#: pg_restore.c:481 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security включить защиту на уровне Ñтрок\n" -#: pg_restore.c:480 +#: pg_restore.c:483 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not " @@ -2917,19 +2892,29 @@ msgstr "" " --no-data-for-failed-tables не воÑÑтанавливать данные таблиц, которые\n" " не удалоÑÑŒ Ñоздать\n" -#: pg_restore.c:482 +#: pg_restore.c:485 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications не воÑÑтанавливать публикации\n" + +#: pg_restore.c:486 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels не воÑÑтанавливать метки безопаÑноÑти\n" -#: pg_restore.c:483 +#: pg_restore.c:487 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions не воÑÑтанавливать подпиÑки\n" + +#: pg_restore.c:488 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr "" " --no-tablespaces не воÑÑтанавливать Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð». " "проÑтранÑтв\n" -#: pg_restore.c:484 +#: pg_restore.c:489 #, c-format msgid "" " --section=SECTION restore named section (pre-data, data, or " @@ -2938,12 +2923,12 @@ msgstr "" " --section=РÐЗДЕЛ воÑÑтановить заданный раздел\n" " (pre-data, data или post-data)\n" -#: pg_restore.c:497 +#: pg_restore.c:502 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ИМЯ_РОЛИ выполнить SET ROLE перед воÑÑтановлением\n" -#: pg_restore.c:499 +#: pg_restore.c:504 #, c-format msgid "" "\n" @@ -2954,7 +2939,7 @@ msgstr "" "Параметры -I, -n, -P, -t, -T и --section можно комбинировать и указывать\n" "неÑколько раз Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° неÑкольких объектов.\n" -#: pg_restore.c:502 +#: pg_restore.c:507 #, c-format msgid "" "\n" @@ -2966,6 +2951,48 @@ msgstr "" "ввода.\n" "\n" +#~ msgid "reading extended statistics for table \"%s.%s\"\n" +#~ msgstr "чтение раÑширенной ÑтатиÑтики Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"\n" + +#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" +#~ msgstr "уÑтановка владельца и прав: %s \"%s.%s\"\n" + +#~ msgid "setting owner and privileges for %s \"%s\"\n" +#~ msgstr "уÑтановка владельца и прав: %s \"%s\"\n" + +#~ msgid "" +#~ "Synchronized snapshots are not supported on standby servers.\n" +#~ "Run with --no-synchronized-snapshots instead if you do not need\n" +#~ "synchronized snapshots.\n" +#~ msgstr "" +#~ "Ðа резервных Ñерверах Ñинхронизированные Ñнимки не поддерживаютÑÑ.\n" +#~ "ЕÑли они вам не нужны, укажите при запуÑке ключ\n" +#~ "--no-synchronized-snapshots.\n" + +#~ msgid "reading partition information\n" +#~ msgstr "чтение информации о ÑекциÑÑ…\n" + +#~ msgid "finding partition relationships\n" +#~ msgstr "обнаружение взаимоÑвÑзей Ñекций\n" + +#~ msgid "reading partition key information for interesting tables\n" +#~ msgstr "чтение информации о ключах Ñ€Ð°Ð·Ð±Ð¸ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€ÐµÑующих таблиц\n" + +#~ msgid "" +#~ " --no-subscription-connect dump subscriptions so they don't connect " +#~ "on restore\n" +#~ msgstr "" +#~ " --no-subscription-connect выгружать подпиÑки так, чтобы они не " +#~ "подключалиÑÑŒ\n" +#~ " при воÑÑтановлении\n" + +#~ msgid "" +#~ "%s: options --no-role-passwords and --binary-upgrade cannot be used " +#~ "together\n" +#~ msgstr "" +#~ "%s: параметры --no-role-passwords и --binary-upgrade иÑключают друг " +#~ "друга\n" + #~ msgid "error processing a parallel work item\n" #~ msgstr "ошибка Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ‡Ð°Ñти параллельной работы\n" @@ -3009,9 +3036,6 @@ msgstr "" #~ msgid "archive member too large for tar format\n" #~ msgstr "компонент архива Ñлишком велик Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° tar\n" -#~ msgid "could not write to output file: %s\n" -#~ msgstr "не удалоÑÑŒ запиÑать в выходной файл: %s\n" - #~ msgid "could not write to custom output routine\n" #~ msgstr "не удалоÑÑŒ вывеÑти данную в пользовательÑкую процедуру\n" diff --git a/src/bin/pg_dump/po/sv.po b/src/bin/pg_dump/po/sv.po index 64cc9c1dcc4..b1b549647a3 100644 --- a/src/bin/pg_dump/po/sv.po +++ b/src/bin/pg_dump/po/sv.po @@ -1,13 +1,13 @@ # Swedish message translation file for pg_dump # Peter Eisentraut , 2001, 2009, 2010. -# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-05 02:15+0000\n" -"PO-Revision-Date: 2017-08-05 07:56+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 16:47+0000\n" +"PO-Revision-Date: 2019-04-29 20:24+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -16,40 +16,59 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "could not identify current directory: %s" -msgstr "kunde inte identifiera aktuell katalog: %s" +msgid "fatal: " +msgstr "fatalt: " -#: ../../common/exec.c:146 +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ogiltig binär \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "kunde inte läsa binär \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "kunde inte byta katalog till \"%s\": %s" +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "kunde inte läsa symbolisk länk \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:541 #, c-format -msgid "pclose failed: %s" -msgstr "pclose misslyckades: %s" +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "slut pÃ¥ minne" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 @@ -77,1343 +96,1229 @@ msgstr "kommandot kan ej hittas" msgid "child process exited with exit code %d" msgstr "barnprocess avslutade med kod %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "barnprocess terminerades med avbrott 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "barnprocess terminerades av signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "barnprocess terminerades av signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "barnprocess avslutade med okänd statuskod %d" -#: common.c:121 +#: common.c:124 #, c-format -msgid "reading extensions\n" -msgstr "läser utökningar\n" +msgid "reading extensions" +msgstr "läser utökningar" -#: common.c:126 +#: common.c:128 #, c-format -msgid "identifying extension members\n" -msgstr "identifierar utökningsmedlemmar\n" +msgid "identifying extension members" +msgstr "identifierar utökningsmedlemmar" -#: common.c:130 +#: common.c:131 #, c-format -msgid "reading schemas\n" -msgstr "läser scheman\n" +msgid "reading schemas" +msgstr "läser scheman" #: common.c:141 #, c-format -msgid "reading user-defined tables\n" -msgstr "läser användardefinierade tabeller\n" +msgid "reading user-defined tables" +msgstr "läser användardefinierade tabeller" -#: common.c:149 +#: common.c:148 #, c-format -msgid "reading user-defined functions\n" -msgstr "läser användardefinierade funktioner\n" +msgid "reading user-defined functions" +msgstr "läser användardefinierade funktioner" -#: common.c:155 +#: common.c:153 #, c-format -msgid "reading user-defined types\n" -msgstr "läser användardefinierade typer\n" +msgid "reading user-defined types" +msgstr "läser användardefinierade typer" -#: common.c:161 +#: common.c:158 #, c-format -msgid "reading procedural languages\n" -msgstr "läser procedursprÃ¥k\n" +msgid "reading procedural languages" +msgstr "läser procedursprÃ¥k" -#: common.c:165 +#: common.c:161 #, c-format -msgid "reading user-defined aggregate functions\n" -msgstr "läser användardefinierade aggregatfunktioner\n" +msgid "reading user-defined aggregate functions" +msgstr "läser användardefinierade aggregatfunktioner" -#: common.c:169 +#: common.c:164 #, c-format -msgid "reading user-defined operators\n" -msgstr "läser användardefinierade operatorer\n" +msgid "reading user-defined operators" +msgstr "läser användardefinierade operatorer" -#: common.c:174 +#: common.c:168 #, c-format -msgid "reading user-defined access methods\n" -msgstr "läser användardefinierade accessmetoder\n" +msgid "reading user-defined access methods" +msgstr "läser användardefinierade accessmetoder" -#: common.c:178 +#: common.c:171 #, c-format -msgid "reading user-defined operator classes\n" -msgstr "läser användardefinierade operatorklasser\n" +msgid "reading user-defined operator classes" +msgstr "läser användardefinierade operatorklasser" -#: common.c:182 +#: common.c:174 #, c-format -msgid "reading user-defined operator families\n" -msgstr "läser användardefinierade operator-familjer\n" +msgid "reading user-defined operator families" +msgstr "läser användardefinierade operator-familjer" -#: common.c:186 +#: common.c:177 #, c-format -msgid "reading user-defined text search parsers\n" -msgstr "läser användardefinierade textsöktolkare\n" +msgid "reading user-defined text search parsers" +msgstr "läser användardefinierade textsöktolkare" -#: common.c:190 +#: common.c:180 #, c-format -msgid "reading user-defined text search templates\n" -msgstr "läser användardefinierade textsökmallar\n" +msgid "reading user-defined text search templates" +msgstr "läser användardefinierade textsökmallar" -#: common.c:194 +#: common.c:183 #, c-format -msgid "reading user-defined text search dictionaries\n" -msgstr "läser användardefinierade textsökordlistor\n" +msgid "reading user-defined text search dictionaries" +msgstr "läser användardefinierade textsökordlistor" -#: common.c:198 +#: common.c:186 #, c-format -msgid "reading user-defined text search configurations\n" -msgstr "läser användardefinierade textsökkonfigurationer\n" +msgid "reading user-defined text search configurations" +msgstr "läser användardefinierade textsökkonfigurationer" -#: common.c:202 +#: common.c:189 #, c-format -msgid "reading user-defined foreign-data wrappers\n" -msgstr "läser användardefinierade främmande data-omvandlare\n" +msgid "reading user-defined foreign-data wrappers" +msgstr "läser användardefinierade främmande data-omvandlare" -#: common.c:206 +#: common.c:192 #, c-format -msgid "reading user-defined foreign servers\n" -msgstr "läser användardefinierade främmande servrar\n" +msgid "reading user-defined foreign servers" +msgstr "läser användardefinierade främmande servrar" -#: common.c:210 +#: common.c:195 #, c-format -msgid "reading default privileges\n" -msgstr "läser standardrättigheter\n" +msgid "reading default privileges" +msgstr "läser standardrättigheter" -#: common.c:214 +#: common.c:198 #, c-format -msgid "reading user-defined collations\n" -msgstr "läser användardefinierade sorteringar\n" +msgid "reading user-defined collations" +msgstr "läser användardefinierade jämförelser" -#: common.c:219 +#: common.c:202 #, c-format -msgid "reading user-defined conversions\n" -msgstr "läser användardefinierade konverteringar\n" +msgid "reading user-defined conversions" +msgstr "läser användardefinierade konverteringar" -#: common.c:223 +#: common.c:205 #, c-format -msgid "reading type casts\n" -msgstr "läser typomvandlingar\n" +msgid "reading type casts" +msgstr "läser typomvandlingar" -#: common.c:227 +#: common.c:208 #, c-format -msgid "reading transforms\n" -msgstr "läser transformer\n" +msgid "reading transforms" +msgstr "läser transformer" -#: common.c:231 +#: common.c:211 #, c-format -msgid "reading table inheritance information\n" -msgstr "läser information om arv av tabeller\n" +msgid "reading table inheritance information" +msgstr "läser information om arv av tabeller" -#: common.c:235 +#: common.c:214 #, c-format -msgid "reading event triggers\n" -msgstr "läser händelseutlösare\n" +msgid "reading event triggers" +msgstr "läser händelseutlösare" -#: common.c:240 +#: common.c:218 #, c-format -msgid "finding extension tables\n" -msgstr "hittar utökningstabeller\n" +msgid "finding extension tables" +msgstr "hittar utökningstabeller" -#: common.c:245 +#: common.c:222 #, c-format -msgid "finding inheritance relationships\n" -msgstr "hittar arvrelationer\n" +msgid "finding inheritance relationships" +msgstr "hittar arvrelationer" -#: common.c:249 +#: common.c:225 #, c-format -msgid "reading column info for interesting tables\n" -msgstr "läser kolumninfo flr intressanta tabeller\n" +msgid "reading column info for interesting tables" +msgstr "läser kolumninfo flr intressanta tabeller" -#: common.c:253 +#: common.c:228 #, c-format -msgid "flagging inherited columns in subtables\n" -msgstr "markerar ärvda kolumner i undertabeller\n" +msgid "flagging inherited columns in subtables" +msgstr "markerar ärvda kolumner i undertabeller" -#: common.c:257 +#: common.c:231 #, c-format -msgid "reading indexes\n" -msgstr "läser index\n" +msgid "reading indexes" +msgstr "läser index" -#: common.c:261 +#: common.c:234 #, c-format -msgid "reading extended statistics\n" -msgstr "läser utökad statistik\n" +msgid "flagging indexes in partitioned tables" +msgstr "flaggar index i partitionerade tabeller" -#: common.c:265 +#: common.c:237 #, c-format -msgid "reading constraints\n" -msgstr "läser integritetsvillkor\n" +msgid "reading extended statistics" +msgstr "läser utökad statistik" -#: common.c:269 +#: common.c:240 #, c-format -msgid "reading triggers\n" -msgstr "läser utlösare\n" +msgid "reading constraints" +msgstr "läser integritetsvillkor" -#: common.c:273 +#: common.c:243 #, c-format -msgid "reading rewrite rules\n" -msgstr "läser omskrivningsregler\n" +msgid "reading triggers" +msgstr "läser utlösare" -#: common.c:277 +#: common.c:246 #, c-format -msgid "reading policies\n" -msgstr "läser policys\n" +msgid "reading rewrite rules" +msgstr "läser omskrivningsregler" -#: common.c:281 +#: common.c:249 #, c-format -msgid "reading publications\n" -msgstr "läser publiceringar\n" +msgid "reading policies" +msgstr "läser policys" -#: common.c:285 +#: common.c:252 #, c-format -msgid "reading publication membership\n" -msgstr "läser publiceringsmedlemskap\n" +msgid "reading publications" +msgstr "läser publiceringar" -#: common.c:289 +#: common.c:255 #, c-format -msgid "reading subscriptions\n" -msgstr "läser prenumerationer\n" +msgid "reading publication membership" +msgstr "läser publiceringsmedlemskap" -#: common.c:924 +#: common.c:258 #, c-format -msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found\n" -msgstr "misslyckades med riktighetskontroll, hittade inte förälder-OID %u för tabell \"%s\" (OID %u)\n" +msgid "reading subscriptions" +msgstr "läser prenumerationer" -#: common.c:966 +#: common.c:1024 #, c-format -msgid "could not parse numeric array \"%s\": too many numbers\n" -msgstr "kunde inte tolka numerisk array \"%s\": för mÃ¥nga nummer\n" +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "misslyckades med riktighetskontroll, hittade inte förälder-OID %u för tabell \"%s\" (OID %u)" -#: common.c:981 +#: common.c:1066 #, c-format -msgid "could not parse numeric array \"%s\": invalid character in number\n" -msgstr "kunde inte tolka numerisk array \"%s\": ogiltigt tecken i nummer\n" - -#. translator: this is a module name -#: compress_io.c:78 -msgid "compress_io" -msgstr "compress_io" +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "kunde inte tolka numerisk array \"%s\": för mÃ¥nga nummer" -#: compress_io.c:114 +#: common.c:1081 #, c-format -msgid "invalid compression code: %d\n" -msgstr "ogiltig komprimeringskod: %d\n" +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "kunde inte tolka numerisk array \"%s\": ogiltigt tecken i nummer" -#: compress_io.c:138 compress_io.c:174 compress_io.c:192 compress_io.c:519 -#: compress_io.c:562 +#: compress_io.c:111 #, c-format -msgid "not built with zlib support\n" -msgstr "ej byggt med zlib-stöd\n" +msgid "invalid compression code: %d" +msgstr "ogiltig komprimeringskod: %d" -#: compress_io.c:242 compress_io.c:344 +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:508 +#: compress_io.c:551 #, c-format -msgid "could not initialize compression library: %s\n" -msgstr "kunde inte initiera komprimeringsbibliotek: %s\n" +msgid "not built with zlib support" +msgstr "ej byggt med zlib-stöd" -#: compress_io.c:263 +#: compress_io.c:237 compress_io.c:336 #, c-format -msgid "could not close compression stream: %s\n" -msgstr "kunde inte stänga komprimeringsströmmen: %s\n" +msgid "could not initialize compression library: %s" +msgstr "kunde inte initiera komprimeringsbibliotek: %s" -#: compress_io.c:281 +#: compress_io.c:257 #, c-format -msgid "could not compress data: %s\n" -msgstr "kunde inte komprimera data: %s\n" +msgid "could not close compression stream: %s" +msgstr "kunde inte stänga komprimeringsströmmen: %s" -#: compress_io.c:361 compress_io.c:377 +#: compress_io.c:274 #, c-format -msgid "could not uncompress data: %s\n" -msgstr "kunde inte packa upp data: %s\n" +msgid "could not compress data: %s" +msgstr "kunde inte komprimera data: %s" -#: compress_io.c:385 +#: compress_io.c:352 compress_io.c:367 #, c-format -msgid "could not close compression library: %s\n" -msgstr "kunde inte stänga komprimeringsbiblioteket: %s\n" +msgid "could not uncompress data: %s" +msgstr "kunde inte packa upp data: %s" -#: compress_io.c:600 compress_io.c:638 pg_backup_custom.c:587 -#: pg_backup_tar.c:564 pg_backup_tar.c:568 +#: compress_io.c:374 #, c-format -msgid "could not read from input file: %s\n" -msgstr "kunde inte läsa frÃ¥n infilen: %s\n" +msgid "could not close compression library: %s" +msgstr "kunde inte stänga komprimeringsbiblioteket: %s" -#: compress_io.c:641 pg_backup_custom.c:584 pg_backup_directory.c:547 -#: pg_backup_tar.c:807 pg_backup_tar.c:831 +#: compress_io.c:588 compress_io.c:625 pg_backup_tar.c:555 pg_backup_tar.c:558 #, c-format -msgid "could not read from input file: end of file\n" -msgstr "kunde inte läsa frÃ¥n infilen: slut pÃ¥ filen\n" +msgid "could not read from input file: %s" +msgstr "kunde inte läsa frÃ¥n infilen: %s" -#: parallel.c:198 -msgid "parallel archiver" -msgstr "parallell arkiverare" +#: compress_io.c:627 pg_backup_custom.c:578 pg_backup_directory.c:539 +#: pg_backup_tar.c:795 pg_backup_tar.c:818 +#, c-format +msgid "could not read from input file: end of file" +msgstr "kunde inte läsa frÃ¥n infilen: slut pÃ¥ filen" -#: parallel.c:265 +#: parallel.c:263 #, c-format -msgid "%s: WSAStartup failed: %d\n" -msgstr "%s: WSAStartup misslyckades: %d\n" +msgid "WSAStartup failed: %d" +msgstr "WSAStartup misslyckades: %d" -#: parallel.c:971 +#: parallel.c:968 #, c-format -msgid "could not create communication channels: %s\n" -msgstr "kunde inte skapa kommunikationskanaler: %s\n" +msgid "could not create communication channels: %m" +msgstr "kunde inte skapa kommunikationskanaler: %m" -#: parallel.c:1036 +#: parallel.c:1031 #, c-format -msgid "could not create worker process: %s\n" -msgstr "kunde inte skapa arbetsprocess: %s\n" +msgid "could not create worker process: %m" +msgstr "kunde inte skapa arbetsprocess: %m" -#: parallel.c:1167 +#: parallel.c:1160 #, c-format -msgid "unrecognized command received from master: \"%s\"\n" -msgstr "okänt kommando mottaget frÃ¥n master: \"%s\"\n" +msgid "unrecognized command received from master: \"%s\"" +msgstr "okänt kommando mottaget frÃ¥n master: \"%s\"" -#: parallel.c:1211 parallel.c:1451 +#: parallel.c:1203 parallel.c:1441 #, c-format -msgid "invalid message received from worker: \"%s\"\n" -msgstr "ogiltigt meddelande mottaget frÃ¥n arbetare: \"%s\"\n" +msgid "invalid message received from worker: \"%s\"" +msgstr "ogiltigt meddelande mottaget frÃ¥n arbetare: \"%s\"" -#: parallel.c:1344 +#: parallel.c:1335 #, c-format msgid "" "could not obtain lock on relation \"%s\"\n" -"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table.\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." msgstr "" "kunde inte lÃ¥sa relationen \"%s\"\n" "Dette beror oftast pÃ¥ att nÃ¥gon tagit ett ACCESS EXCLUSIVE-lÃ¥s pÃ¥ tabellen\n" -"efter att pg_dumps föräldraprocess tagit ett ACCESS SHARE-lÃ¥s pÃ¥ tabellen.\n" +"efter att pg_dumps föräldraprocess tagit ett ACCESS SHARE-lÃ¥s pÃ¥ tabellen." -#: parallel.c:1433 +#: parallel.c:1424 #, c-format -msgid "a worker process died unexpectedly\n" -msgstr "en arbetsprocess dog oväntat\n" +msgid "a worker process died unexpectedly" +msgstr "en arbetsprocess dog oväntat" -#: parallel.c:1557 parallel.c:1675 +#: parallel.c:1546 parallel.c:1662 #, c-format -msgid "could not write to the communication channel: %s\n" -msgstr "kunde inte skriva till kommunikationskanal: %s\n" +msgid "could not write to the communication channel: %m" +msgstr "kunde inte skriva till kommunikationskanal: %m" -#: parallel.c:1635 +#: parallel.c:1623 #, c-format -msgid "select() failed: %s\n" -msgstr "select() misslyckades: %s\n" +msgid "select() failed: %m" +msgstr "select() misslyckades: %m" -#: parallel.c:1760 +#: parallel.c:1746 #, c-format -msgid "pgpipe: could not create socket: error code %d\n" -msgstr "pgpipe: kunde inte skapa uttag (socket): felkod %d\n" +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: kunde inte skapa uttag (socket): felkod %d" -#: parallel.c:1771 -#, c-format -msgid "pgpipe: could not bind: error code %d\n" -msgstr "pgpipe: kunde inte göra \"bind\": felkod %d\n" - -#: parallel.c:1778 +#: parallel.c:1757 #, c-format -msgid "pgpipe: could not listen: error code %d\n" -msgstr "pgpipe: kunde inte göra \"listen\": felkod %d\n" +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: kunde inte göra \"bind\": felkod %d" -#: parallel.c:1785 +#: parallel.c:1764 #, c-format -msgid "pgpipe: getsockname() failed: error code %d\n" -msgstr "pgpipe: getsockname() misslyckades: felkod %d\n" +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: kunde inte göra \"listen\": felkod %d" -#: parallel.c:1796 +#: parallel.c:1771 #, c-format -msgid "pgpipe: could not create second socket: error code %d\n" -msgstr "pgpipe: kunde inte skapa ett andra uttag (socket): felkod %d\n" +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() misslyckades: felkod %d" -#: parallel.c:1805 +#: parallel.c:1782 #, c-format -msgid "pgpipe: could not connect socket: error code %d\n" -msgstr "pgpipe: kunde itne ansluta till uttag (socket): felkod %d\n" +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: kunde inte skapa ett andra uttag (socket): felkod %d" -#: parallel.c:1814 +#: parallel.c:1791 #, c-format -msgid "pgpipe: could not accept connection: error code %d\n" -msgstr "pgpipe: kunde inte acceptera anslutning: felkod %d\n" - -#. translator: this is a module name -#: pg_backup_archiver.c:53 -msgid "archiver" -msgstr "arkiverare" +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: kunde itne ansluta till uttag (socket): felkod %d" -#: pg_backup_archiver.c:249 pg_backup_archiver.c:1599 +#: parallel.c:1800 #, c-format -msgid "could not close output file: %s\n" -msgstr "kunde inte stänga utdatafilen: %s\n" +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: kunde inte acceptera anslutning: felkod %d" -#: pg_backup_archiver.c:295 pg_backup_archiver.c:300 +#: pg_backup_archiver.c:273 pg_backup_archiver.c:1596 #, c-format -msgid "WARNING: archive items not in correct section order\n" -msgstr "VARNING: arkivobjekten är inte i korrekt sektionsordning\n" +msgid "could not close output file: %m" +msgstr "kunde inte stänga utdatafilen: %m" -#: pg_backup_archiver.c:306 +#: pg_backup_archiver.c:317 pg_backup_archiver.c:321 #, c-format -msgid "unexpected section code %d\n" -msgstr "oväntad sektionskod %d\n" +msgid "archive items not in correct section order" +msgstr "arkivobjekten är inte i korrekt sektionsordning" -#: pg_backup_archiver.c:342 +#: pg_backup_archiver.c:327 #, c-format -msgid "-C and -1 are incompatible options\n" -msgstr "-C och -1 är inkompatibla flaggor\n" +msgid "unexpected section code %d" +msgstr "oväntad sektionskod %d" -#: pg_backup_archiver.c:352 +#: pg_backup_archiver.c:364 #, c-format -msgid "parallel restore is not supported with this archive file format\n" -msgstr "parallell Ã¥terställning stöds inte med detta arkivformat\n" +msgid "parallel restore is not supported with this archive file format" +msgstr "parallell Ã¥terställning stöds inte med detta arkivformat" -#: pg_backup_archiver.c:356 +#: pg_backup_archiver.c:368 #, c-format -msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump\n" -msgstr "parallell Ã¥terställning stöds inte med arkiv som skapats av en pre-8.0 pg_dump\n" +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "parallell Ã¥terställning stöds inte med arkiv som skapats av en pre-8.0 pg_dump" -#: pg_backup_archiver.c:374 +#: pg_backup_archiver.c:386 #, c-format -msgid "cannot restore from compressed archive (compression not supported in this installation)\n" -msgstr "kan inte Ã¥terställa frÃ¥n komprimerat arkiv (inte konfigurerad med stöd för komprimering)\n" +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "kan inte Ã¥terställa frÃ¥n komprimerat arkiv (inte konfigurerad med stöd för komprimering)" -#: pg_backup_archiver.c:391 +#: pg_backup_archiver.c:403 #, c-format -msgid "connecting to database for restore\n" -msgstr "kopplar upp mot databas för Ã¥terställning\n" +msgid "connecting to database for restore" +msgstr "kopplar upp mot databas för Ã¥terställning" -#: pg_backup_archiver.c:393 +#: pg_backup_archiver.c:405 #, c-format -msgid "direct database connections are not supported in pre-1.3 archives\n" -msgstr "direkta databasuppkopplingar stöds inte i arkiv frÃ¥n före version 1.3\n" +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "direkta databasuppkopplingar stöds inte i arkiv frÃ¥n före version 1.3" -#: pg_backup_archiver.c:438 +#: pg_backup_archiver.c:450 #, c-format -msgid "implied data-only restore\n" -msgstr "implicerad Ã¥terställning av enbart data\n" +msgid "implied data-only restore" +msgstr "implicerad Ã¥terställning av enbart data" -#: pg_backup_archiver.c:508 +#: pg_backup_archiver.c:516 #, c-format -msgid "dropping %s %s\n" -msgstr "tar bort %s %s\n" +msgid "dropping %s %s" +msgstr "tar bort %s %s" -#: pg_backup_archiver.c:601 +#: pg_backup_archiver.c:611 #, c-format -msgid "WARNING: could not find where to insert IF EXISTS in statement \"%s\"\n" -msgstr "VARNING: kunde inte hitta var IF EXISTS skulle stoppas in i sats \"%s\"\n" +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "kunde inte hitta var IF EXISTS skulle stoppas in i sats \"%s\"" -#: pg_backup_archiver.c:764 pg_backup_archiver.c:766 +#: pg_backup_archiver.c:767 pg_backup_archiver.c:769 #, c-format -msgid "warning from original dump file: %s\n" -msgstr "varning frÃ¥n orginaldumpfilen: %s\n" +msgid "warning from original dump file: %s" +msgstr "varning frÃ¥n orginaldumpfilen: %s" -#: pg_backup_archiver.c:778 +#: pg_backup_archiver.c:784 #, c-format -msgid "creating %s \"%s.%s\"\n" -msgstr "skapar %s \"%s.%s\"\n" +msgid "creating %s \"%s.%s\"" +msgstr "skapar %s \"%s.%s\"" -#: pg_backup_archiver.c:781 +#: pg_backup_archiver.c:787 #, c-format -msgid "creating %s \"%s\"\n" -msgstr "skapar %s \"%s\"\n" +msgid "creating %s \"%s\"" +msgstr "skapar %s \"%s\"" -#: pg_backup_archiver.c:832 +#: pg_backup_archiver.c:844 #, c-format -msgid "connecting to new database \"%s\"\n" -msgstr "kopplar upp mot ny databas \"%s\"\n" +msgid "connecting to new database \"%s\"" +msgstr "kopplar upp mot ny databas \"%s\"" -#: pg_backup_archiver.c:860 +#: pg_backup_archiver.c:872 #, c-format -msgid "processing %s\n" -msgstr "processar %s\n" +msgid "processing %s" +msgstr "processar %s" -#: pg_backup_archiver.c:880 +#: pg_backup_archiver.c:892 #, c-format -msgid "processing data for table \"%s.%s\"\n" -msgstr "processar data för tabell \"%s.%s\"\n" +msgid "processing data for table \"%s.%s\"" +msgstr "processar data för tabell \"%s.%s\"" -#: pg_backup_archiver.c:942 +#: pg_backup_archiver.c:954 #, c-format -msgid "executing %s %s\n" -msgstr "kör %s %s\n" +msgid "executing %s %s" +msgstr "kör %s %s" -#: pg_backup_archiver.c:981 +#: pg_backup_archiver.c:993 #, c-format -msgid "disabling triggers for %s\n" -msgstr "stänger av utlösare för %s\n" +msgid "disabling triggers for %s" +msgstr "stänger av utlösare för %s" -#: pg_backup_archiver.c:1009 +#: pg_backup_archiver.c:1019 #, c-format -msgid "enabling triggers for %s\n" -msgstr "slÃ¥r pÃ¥ utlösare för %s\n" +msgid "enabling triggers for %s" +msgstr "slÃ¥r pÃ¥ utlösare för %s" -#: pg_backup_archiver.c:1039 +#: pg_backup_archiver.c:1047 #, c-format -msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine\n" -msgstr "internt fel -- WriteData kan inte anropas utanför kontexten av en DataDumper-rutin\n" +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "internt fel -- WriteData kan inte anropas utanför kontexten av en DataDumper-rutin" -#: pg_backup_archiver.c:1237 +#: pg_backup_archiver.c:1232 #, c-format -msgid "large-object output not supported in chosen format\n" -msgstr "utmatning av stora objekt stöds inte i det valda formatet\n" +msgid "large-object output not supported in chosen format" +msgstr "utmatning av stora objekt stöds inte i det valda formatet" -#: pg_backup_archiver.c:1295 +#: pg_backup_archiver.c:1290 #, c-format -msgid "restored %d large object\n" -msgid_plural "restored %d large objects\n" -msgstr[0] "Ã¥terställde %d stor objekt\n" -msgstr[1] "Ã¥terställde %d stora objekt\n" +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "Ã¥terställde %d stor objekt" +msgstr[1] "Ã¥terställde %d stora objekt" -#: pg_backup_archiver.c:1316 pg_backup_tar.c:749 +#: pg_backup_archiver.c:1311 pg_backup_tar.c:738 #, c-format -msgid "restoring large object with OID %u\n" -msgstr "Ã¥terställer stort objekt med OID %u\n" +msgid "restoring large object with OID %u" +msgstr "Ã¥terställer stort objekt med OID %u" -#: pg_backup_archiver.c:1328 +#: pg_backup_archiver.c:1323 #, c-format msgid "could not create large object %u: %s" msgstr "kunde inte skapa stort objekt %u: %s" -#: pg_backup_archiver.c:1333 pg_dump.c:3084 +#: pg_backup_archiver.c:1328 pg_dump.c:3450 #, c-format msgid "could not open large object %u: %s" msgstr "kunde inte öppna stort objekt %u: %s" -#: pg_backup_archiver.c:1391 +#: pg_backup_archiver.c:1385 #, c-format -msgid "could not open TOC file \"%s\": %s\n" -msgstr "kunde inte öppna TOC-filen \"%s\": %s\n" +msgid "could not open TOC file \"%s\": %m" +msgstr "kunde inte öppna TOC-filen \"%s\": %m" -#: pg_backup_archiver.c:1432 +#: pg_backup_archiver.c:1425 #, c-format -msgid "WARNING: line ignored: %s\n" -msgstr "VARNING: rad ignorerad: %s\n" +msgid "line ignored: %s" +msgstr "rad ignorerad: %s" -#: pg_backup_archiver.c:1439 -#, c-format -msgid "could not find entry for ID %d\n" -msgstr "kunde inte hitta en post för ID %d\n" - -#: pg_backup_archiver.c:1460 pg_backup_directory.c:225 -#: pg_backup_directory.c:596 -#, c-format -msgid "could not close TOC file: %s\n" -msgstr "kunde inte stänga TOC-filen: %s\n" - -#: pg_backup_archiver.c:1569 pg_backup_custom.c:158 pg_backup_directory.c:336 -#: pg_backup_directory.c:582 pg_backup_directory.c:647 -#: pg_backup_directory.c:667 +#: pg_backup_archiver.c:1432 #, c-format -msgid "could not open output file \"%s\": %s\n" -msgstr "kunde inte öppna utdatafilen \"%s\": %s\n" +msgid "could not find entry for ID %d" +msgstr "kunde inte hitta en post för ID %d" -#: pg_backup_archiver.c:1572 pg_backup_custom.c:165 +#: pg_backup_archiver.c:1453 pg_backup_directory.c:222 +#: pg_backup_directory.c:587 #, c-format -msgid "could not open output file: %s\n" -msgstr "kunde inte öppna utdatafilen: %s\n" +msgid "could not close TOC file: %m" +msgstr "kunde inte stänga TOC-filen: %m" -#: pg_backup_archiver.c:1678 +#: pg_backup_archiver.c:1568 pg_backup_custom.c:159 pg_backup_directory.c:332 +#: pg_backup_directory.c:574 pg_backup_directory.c:637 +#: pg_backup_directory.c:656 #, c-format -msgid "wrote %lu byte of large object data (result = %lu)\n" -msgid_plural "wrote %lu bytes of large object data (result = %lu)\n" -msgstr[0] "skrev %lu byte av stort objekt-data (resultat = %lu)\n" -msgstr[1] "skrev %lu bytes av stort objekt-data (resultat = %lu)\n" +msgid "could not open output file \"%s\": %m" +msgstr "kunde inte öppna utdatafilen \"%s\": %m" -#: pg_backup_archiver.c:1684 +#: pg_backup_archiver.c:1570 pg_backup_custom.c:165 #, c-format -msgid "could not write to large object (result: %lu, expected: %lu)\n" -msgstr "kunde inte skriva till stort objekt (resultat: %lu, förväntat: %lu)\n" +msgid "could not open output file: %m" +msgstr "kunde inte öppna utdatafilen: %m" -#: pg_backup_archiver.c:1777 +#: pg_backup_archiver.c:1663 #, c-format -msgid "Error while INITIALIZING:\n" -msgstr "Fel vid INITIERING:\n" +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "skrev %lu byte av stort objekt-data (resultat = %lu)" +msgstr[1] "skrev %lu bytes av stort objekt-data (resultat = %lu)" -#: pg_backup_archiver.c:1782 +#: pg_backup_archiver.c:1668 #, c-format -msgid "Error while PROCESSING TOC:\n" -msgstr "Fel vid HANTERING AV TOC:\n" +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "kunde inte skriva till stort objekt (resultat: %lu, förväntat: %lu)" -#: pg_backup_archiver.c:1787 +#: pg_backup_archiver.c:1760 #, c-format -msgid "Error while FINALIZING:\n" -msgstr "Fel vid SLUTFÖRANDE:\n" +msgid "while INITIALIZING:" +msgstr "vid INITIERING:" -#: pg_backup_archiver.c:1792 +#: pg_backup_archiver.c:1765 #, c-format -msgid "Error from TOC entry %d; %u %u %s %s %s\n" -msgstr "Fel pÃ¥ TOC-post %d; %u %u %s %s %s\n" +msgid "while PROCESSING TOC:" +msgstr "vid HANTERING AV TOC:" -#: pg_backup_archiver.c:1865 +#: pg_backup_archiver.c:1770 #, c-format -msgid "bad dumpId\n" -msgstr "felaktigt dumpId\n" +msgid "while FINALIZING:" +msgstr "vid SLUTFÖRANDE:" -#: pg_backup_archiver.c:1886 +#: pg_backup_archiver.c:1775 #, c-format -msgid "bad table dumpId for TABLE DATA item\n" -msgstr "felaktig tabell-dumpId för TABLE DATA-objekt\n" +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "frÃ¥n TOC-post %d; %u %u %s %s %s" -#: pg_backup_archiver.c:1978 +#: pg_backup_archiver.c:1851 #, c-format -msgid "unexpected data offset flag %d\n" -msgstr "oväntad data-offset-flagga %d\n" +msgid "bad dumpId" +msgstr "felaktigt dumpId" -#: pg_backup_archiver.c:1991 +#: pg_backup_archiver.c:1872 #, c-format -msgid "file offset in dump file is too large\n" -msgstr "fil-offset i dumpfilen är för stort\n" +msgid "bad table dumpId for TABLE DATA item" +msgstr "felaktig tabell-dumpId för TABLE DATA-objekt" -#: pg_backup_archiver.c:2104 +#: pg_backup_archiver.c:1964 #, c-format -msgid "attempting to ascertain archive format\n" -msgstr "försöker lista ut arkivformat\n" +msgid "unexpected data offset flag %d" +msgstr "oväntad data-offset-flagga %d" -#: pg_backup_archiver.c:2130 pg_backup_archiver.c:2140 +#: pg_backup_archiver.c:1977 #, c-format -msgid "directory name too long: \"%s\"\n" -msgstr "katalognamn för lÃ¥ngt: \"%s\"\n" +msgid "file offset in dump file is too large" +msgstr "fil-offset i dumpfilen är för stort" -#: pg_backup_archiver.c:2148 +#: pg_backup_archiver.c:2114 pg_backup_archiver.c:2124 #, c-format -msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n" -msgstr "katalogen \"%s\" verkar inte vara ett giltigt arkiv (\"toc.dat\" finns inte)\n" +msgid "directory name too long: \"%s\"" +msgstr "katalognamn för lÃ¥ngt: \"%s\"" -#: pg_backup_archiver.c:2156 pg_backup_custom.c:177 pg_backup_custom.c:770 -#: pg_backup_directory.c:209 pg_backup_directory.c:396 +#: pg_backup_archiver.c:2132 #, c-format -msgid "could not open input file \"%s\": %s\n" -msgstr "kunde inte öppna indatafilen \"%s\": %s\n" +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "katalogen \"%s\" verkar inte vara ett giltigt arkiv (\"toc.dat\" finns inte)" -#: pg_backup_archiver.c:2164 pg_backup_custom.c:184 +#: pg_backup_archiver.c:2140 pg_backup_custom.c:176 pg_backup_custom.c:760 +#: pg_backup_directory.c:207 pg_backup_directory.c:391 #, c-format -msgid "could not open input file: %s\n" -msgstr "kan inte öppna infil: %s\n" +msgid "could not open input file \"%s\": %m" +msgstr "kunde inte öppna indatafilen \"%s\": %m" -#: pg_backup_archiver.c:2171 +#: pg_backup_archiver.c:2147 pg_backup_custom.c:182 #, c-format -msgid "could not read input file: %s\n" -msgstr "kan inte läsa infilen: %s\n" +msgid "could not open input file: %m" +msgstr "kan inte öppna infil: %m" -#: pg_backup_archiver.c:2173 +#: pg_backup_archiver.c:2153 #, c-format -msgid "input file is too short (read %lu, expected 5)\n" -msgstr "indatafilen är för kort (läste %lu, förväntade 5)\n" +msgid "could not read input file: %m" +msgstr "kan inte läsa infilen: %m" -#: pg_backup_archiver.c:2258 +#: pg_backup_archiver.c:2155 #, c-format -msgid "input file appears to be a text format dump. Please use psql.\n" -msgstr "indatafilen verkar vara en dump i textformat. Använd psql.\n" +msgid "input file is too short (read %lu, expected 5)" +msgstr "indatafilen är för kort (läste %lu, förväntade 5)" -#: pg_backup_archiver.c:2264 +#: pg_backup_archiver.c:2240 #, c-format -msgid "input file does not appear to be a valid archive (too short?)\n" -msgstr "indatafilen verkar inte vara ett korrekt arkiv (för kort?)\n" +msgid "input file appears to be a text format dump. Please use psql." +msgstr "indatafilen verkar vara en dump i textformat. Använd psql." -#: pg_backup_archiver.c:2270 +#: pg_backup_archiver.c:2246 #, c-format -msgid "input file does not appear to be a valid archive\n" -msgstr "indatafilen verkar inte vara ett korrekt arkiv\n" +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "indatafilen verkar inte vara ett korrekt arkiv (för kort?)" -#: pg_backup_archiver.c:2290 +#: pg_backup_archiver.c:2252 #, c-format -msgid "could not close input file: %s\n" -msgstr "kunde inte stänga indatafilen: %s\n" +msgid "input file does not appear to be a valid archive" +msgstr "indatafilen verkar inte vara ett korrekt arkiv" -#: pg_backup_archiver.c:2308 +#: pg_backup_archiver.c:2272 #, c-format -msgid "allocating AH for %s, format %d\n" -msgstr "allokerar AH för %s, format %d\n" +msgid "could not close input file: %m" +msgstr "kunde inte stänga indatafilen: %m" -#: pg_backup_archiver.c:2409 +#: pg_backup_archiver.c:2386 #, c-format -msgid "unrecognized file format \"%d\"\n" -msgstr "känner inte igen filformat \"%d\"\n" +msgid "unrecognized file format \"%d\"" +msgstr "känner inte igen filformat \"%d\"" -#: pg_backup_archiver.c:2464 pg_backup_archiver.c:4307 +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4475 #, c-format -msgid "finished item %d %s %s\n" -msgstr "klar med onjekt %d %s %s\n" +msgid "finished item %d %s %s" +msgstr "klar med objekt %d %s %s" -#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4320 +#: pg_backup_archiver.c:2472 pg_backup_archiver.c:4488 #, c-format -msgid "worker process failed: exit code %d\n" -msgstr "arbetsprocess misslyckades: felkod %d\n" +msgid "worker process failed: exit code %d" +msgstr "arbetsprocess misslyckades: felkod %d" -#: pg_backup_archiver.c:2588 +#: pg_backup_archiver.c:2592 #, c-format -msgid "entry ID %d out of range -- perhaps a corrupt TOC\n" -msgstr "post-ID %d utanför sitt intervall -- kanske en trasig TOC\n" +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "post-ID %d utanför sitt intervall -- kanske en trasig TOC" -#: pg_backup_archiver.c:2704 +#: pg_backup_archiver.c:2659 #, c-format -msgid "read TOC entry %d (ID %d) for %s %s\n" -msgstr "läste TOC-post %d (ID %d) för %s %s\n" +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "Ã¥tereställa tabeller med WITH OIDS stöds inte längre" -#: pg_backup_archiver.c:2738 +#: pg_backup_archiver.c:2741 #, c-format -msgid "unrecognized encoding \"%s\"\n" -msgstr "okänd teckenkodning \"%s\"\n" +msgid "unrecognized encoding \"%s\"" +msgstr "okänd teckenkodning \"%s\"" -#: pg_backup_archiver.c:2743 +#: pg_backup_archiver.c:2746 #, c-format -msgid "invalid ENCODING item: %s\n" -msgstr "ogiltigt ENCODING-val: %s\n" +msgid "invalid ENCODING item: %s" +msgstr "ogiltigt ENCODING-val: %s" -#: pg_backup_archiver.c:2761 +#: pg_backup_archiver.c:2764 #, c-format -msgid "invalid STDSTRINGS item: %s\n" -msgstr "ogiltigt STDSTRINGS-val: %s\n" +msgid "invalid STDSTRINGS item: %s" +msgstr "ogiltigt STDSTRINGS-val: %s" -#: pg_backup_archiver.c:2776 +#: pg_backup_archiver.c:2789 #, c-format -msgid "schema \"%s\" not found\n" -msgstr "schema \"%s\" hittades inte\n" +msgid "schema \"%s\" not found" +msgstr "schema \"%s\" hittades inte" -#: pg_backup_archiver.c:2783 +#: pg_backup_archiver.c:2796 #, c-format -msgid "table \"%s\" not found\n" -msgstr "tabell \"%s\" hittades inte\n" +msgid "table \"%s\" not found" +msgstr "tabell \"%s\" hittades inte" -#: pg_backup_archiver.c:2790 +#: pg_backup_archiver.c:2803 #, c-format -msgid "index \"%s\" not found\n" -msgstr "index \"%s\" hittades inte\n" +msgid "index \"%s\" not found" +msgstr "index \"%s\" hittades inte" -#: pg_backup_archiver.c:2797 +#: pg_backup_archiver.c:2810 #, c-format -msgid "function \"%s\" not found\n" -msgstr "funktion \"%s\" hittades inte\n" +msgid "function \"%s\" not found" +msgstr "funktion \"%s\" hittades inte" -#: pg_backup_archiver.c:2804 +#: pg_backup_archiver.c:2817 #, c-format -msgid "trigger \"%s\" not found\n" -msgstr "utlösare \"%s\" hittades inte\n" +msgid "trigger \"%s\" not found" +msgstr "utlösare \"%s\" hittades inte" -#: pg_backup_archiver.c:3082 +#: pg_backup_archiver.c:3196 #, c-format msgid "could not set session user to \"%s\": %s" msgstr "kunde inte sätta sessionsanvändare till \"%s\": %s" -#: pg_backup_archiver.c:3114 -#, c-format -msgid "could not set default_with_oids: %s" -msgstr "kunde inte sätta default_with_oids: %s" - -#: pg_backup_archiver.c:3259 -#, c-format -msgid "could not set search_path to \"%s\": %s" -msgstr "kunde inte sätta search_path till \"%s\": %s" - -#: pg_backup_archiver.c:3321 -#, c-format -msgid "could not set default_tablespace to %s: %s" -msgstr "kunde inte sätta default_tablespace till %s: %s" - -#: pg_backup_archiver.c:3411 pg_backup_archiver.c:3604 +#: pg_backup_archiver.c:3533 pg_backup_archiver.c:3691 #, c-format -msgid "WARNING: don't know how to set owner for object type \"%s\"\n" -msgstr "VARNING: vet inte hur man sätter ägare för objekttyp \"%s\"\n" +msgid "don't know how to set owner for object type \"%s\"" +msgstr "vet inte hur man sätter ägare för objekttyp \"%s\"" -#: pg_backup_archiver.c:3694 +#: pg_backup_archiver.c:3795 #, c-format -msgid "did not find magic string in file header\n" -msgstr "kunde inte hitta den magiska strängen i filhuvudet\n" +msgid "did not find magic string in file header" +msgstr "kunde inte hitta den magiska strängen i filhuvudet" -#: pg_backup_archiver.c:3707 +#: pg_backup_archiver.c:3808 #, c-format -msgid "unsupported version (%d.%d) in file header\n" -msgstr "ej supportad version (%d.%d) i filhuvudet\n" +msgid "unsupported version (%d.%d) in file header" +msgstr "ej supportad version (%d.%d) i filhuvudet" -#: pg_backup_archiver.c:3712 +#: pg_backup_archiver.c:3813 #, c-format -msgid "sanity check on integer size (%lu) failed\n" -msgstr "riktighetskontroll pÃ¥ heltalsstorlek (%lu) misslyckades\n" +msgid "sanity check on integer size (%lu) failed" +msgstr "riktighetskontroll pÃ¥ heltalsstorlek (%lu) misslyckades" -#: pg_backup_archiver.c:3716 +#: pg_backup_archiver.c:3817 #, c-format -msgid "WARNING: archive was made on a machine with larger integers, some operations might fail\n" -msgstr "VARNING: arkivet skapades pÃ¥ en maskin med större heltal, en del operationer kan misslyckas\n" +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "arkivet skapades pÃ¥ en maskin med större heltal, en del operationer kan misslyckas" -#: pg_backup_archiver.c:3726 +#: pg_backup_archiver.c:3827 #, c-format -msgid "expected format (%d) differs from format found in file (%d)\n" -msgstr "förväntat format (%d) skiljer sig frÃ¥n formatet som fanns i filen (%d)\n" +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "förväntat format (%d) skiljer sig frÃ¥n formatet som fanns i filen (%d)" -#: pg_backup_archiver.c:3742 +#: pg_backup_archiver.c:3843 #, c-format -msgid "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n" -msgstr "VARNING: arkivet är komprimerat, men denna installation stödjer inte komprimering -- ingen data kommer kunna läsas\n" +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "arkivet är komprimerat, men denna installation stödjer inte komprimering -- ingen data kommer kunna läsas" -#: pg_backup_archiver.c:3760 +#: pg_backup_archiver.c:3861 #, c-format -msgid "WARNING: invalid creation date in header\n" -msgstr "VARNING: ogiltig skapandedatum i huvud\n" +msgid "invalid creation date in header" +msgstr "ogiltig skapandedatum i huvud" -#: pg_backup_archiver.c:3833 +#: pg_backup_archiver.c:3998 #, c-format -msgid "entering restore_toc_entries_prefork\n" -msgstr "gÃ¥r in i restore_toc_entries_prefork\n" +msgid "processing item %d %s %s" +msgstr "processar objekt %d %s %s" -#: pg_backup_archiver.c:3896 +#: pg_backup_archiver.c:4077 #, c-format -msgid "processing item %d %s %s\n" -msgstr "processar objekt %d %s %s\n" +msgid "entering main parallel loop" +msgstr "gÃ¥r in i parallella huvudloopen" -#: pg_backup_archiver.c:3950 +#: pg_backup_archiver.c:4088 #, c-format -msgid "entering restore_toc_entries_parallel\n" -msgstr "gÃ¥r in i restore_toc_entries_parallel\n" +msgid "skipping item %d %s %s" +msgstr "hoppar över objekt %d %s %s" -#: pg_backup_archiver.c:3971 +#: pg_backup_archiver.c:4097 #, c-format -msgid "entering main parallel loop\n" -msgstr "gÃ¥r in i parallella huvudloopen\n" +msgid "launching item %d %s %s" +msgstr "startar objekt %d %s %s" -#: pg_backup_archiver.c:3982 +#: pg_backup_archiver.c:4151 #, c-format -msgid "skipping item %d %s %s\n" -msgstr "hoppar över objekt %d %s %s\n" +msgid "finished main parallel loop" +msgstr "klar med parallella huvudloopen" -#: pg_backup_archiver.c:3992 +#: pg_backup_archiver.c:4189 #, c-format -msgid "launching item %d %s %s\n" -msgstr "startar objekt %d %s %s\n" +msgid "processing missed item %d %s %s" +msgstr "processar saknat objekt %d %s %s" -#: pg_backup_archiver.c:4046 +#: pg_backup_archiver.c:4794 #, c-format -msgid "finished main parallel loop\n" -msgstr "klar med parallella huvudloopen\n" +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "tabell \"%s\" kunde inte skapas, dess data kommer ej Ã¥terställas" -#: pg_backup_archiver.c:4064 +#: pg_backup_custom.c:377 pg_backup_null.c:150 #, c-format -msgid "entering restore_toc_entries_postfork\n" -msgstr "gÃ¥r in i restore_toc_entries_postfork\n" +msgid "invalid OID for large object" +msgstr "ogiltig OID för stort objekt" -#: pg_backup_archiver.c:4084 +#: pg_backup_custom.c:447 #, c-format -msgid "processing missed item %d %s %s\n" -msgstr "processar saknat objekt %d %s %s\n" +msgid "unrecognized data block type (%d) while searching archive" +msgstr "känner inte igen datablocktyp (%d) vid genomsökning av arkiv" -#: pg_backup_archiver.c:4263 +#: pg_backup_custom.c:458 pg_backup_custom.c:818 #, c-format -msgid "no item ready\n" -msgstr "inget objekt är redo\n" +msgid "error during file seek: %m" +msgstr "fel vid sökning: %m" -#: pg_backup_archiver.c:4482 +#: pg_backup_custom.c:467 #, c-format -msgid "transferring dependency %d -> %d to %d\n" -msgstr "överför beroende %d -> %d till %d\n" - -#: pg_backup_archiver.c:4555 -#, c-format -msgid "reducing dependencies for %d\n" -msgstr "reducerar beroenden för %d\n" - -#: pg_backup_archiver.c:4603 -#, c-format -msgid "table \"%s\" could not be created, will not restore its data\n" -msgstr "tabell \"%s\" kunde inte skapas, dess data kommer ej Ã¥terställas\n" - -#. translator: this is a module name -#: pg_backup_custom.c:93 -msgid "custom archiver" -msgstr "egen arkiverare" - -#: pg_backup_custom.c:380 pg_backup_null.c:150 -#, c-format -msgid "invalid OID for large object\n" -msgstr "ogiltig OID för stort objekt\n" - -#: pg_backup_custom.c:451 -#, c-format -msgid "unrecognized data block type (%d) while searching archive\n" -msgstr "känner inte igen datablocktyp (%d) vid genomsökning av arkiv\n" - -#: pg_backup_custom.c:462 -#, c-format -msgid "error during file seek: %s\n" -msgstr "fel vid sökning: %s\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +msgstr "kunde inte hitta block ID %d i arkiv -- kanske pÃ¥ grund av en Ã¥terställningbegäran i oordning vilket inte kan hanteras dÃ¥ det saknas dataoffsets i arkivet" #: pg_backup_custom.c:472 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive\n" -msgstr "kunde inte hitta block ID %d i arkiv -- kanske pÃ¥ grund av en Ã¥terställningbegäran i oordning vilket inte kan hanteras dÃ¥ det saknas dataoffsets i arkivet\n" +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "kunde inte hitta block ID %d i arkiv -- kanske pÃ¥ grund av en Ã¥terställningbegäran i oordning vilket inte kan hanteras dÃ¥ inputfilen inte är sökbar" #: pg_backup_custom.c:477 #, c-format -msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file\n" -msgstr "kunde inte hitta block ID %d i arkiv -- kanske pÃ¥ grund av en Ã¥terställningbegäran i oordning vilket inte kan hanteras dÃ¥ inputfilen inte är sökbar\n" +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "kunde inte hitta block ID %d i arkiv -- möjligen ett trasigt arkiv" -#: pg_backup_custom.c:482 +#: pg_backup_custom.c:484 #, c-format -msgid "could not find block ID %d in archive -- possibly corrupt archive\n" -msgstr "kunde inte hitta block ID %d i arkiv -- möjligen ett trasigt arkiv\n" +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "hittade oväntat block-ID (%d) vid läsning av data -- förväntade %d" -#: pg_backup_custom.c:489 +#: pg_backup_custom.c:498 #, c-format -msgid "found unexpected block ID (%d) when reading data -- expected %d\n" -msgstr "hittade oväntat block-ID (%d) vid läsning av data -- förväntade %d\n" +msgid "unrecognized data block type %d while restoring archive" +msgstr "ej igenkänd datablockstyp %d vid Ã¥terställande av arkiv" -#: pg_backup_custom.c:503 +#: pg_backup_custom.c:580 #, c-format -msgid "unrecognized data block type %d while restoring archive\n" -msgstr "ej igenkänd datablockstyp %d vid Ã¥terställande av arkiv\n" +msgid "could not read from input file: %m" +msgstr "kunde inte läsa frÃ¥n infilen: %m" -#: pg_backup_custom.c:705 pg_backup_custom.c:759 pg_backup_custom.c:844 -#: pg_backup_tar.c:1102 +#: pg_backup_custom.c:698 pg_backup_custom.c:751 pg_backup_custom.c:891 +#: pg_backup_tar.c:1091 #, c-format -msgid "could not determine seek position in archive file: %s\n" -msgstr "kunde inte bestämma sökposition i arkivfil: %s\n" +msgid "could not determine seek position in archive file: %m" +msgstr "kunde inte bestämma sökposition i arkivfil: %m" -#: pg_backup_custom.c:723 pg_backup_custom.c:764 +#: pg_backup_custom.c:715 pg_backup_custom.c:755 #, c-format -msgid "could not close archive file: %s\n" -msgstr "kan inte stänga arkivfilen: %s\n" +msgid "could not close archive file: %m" +msgstr "kan inte stänga arkivfilen: %m" -#: pg_backup_custom.c:746 +#: pg_backup_custom.c:738 #, c-format -msgid "can only reopen input archives\n" -msgstr "kan inte Ã¥teröppna indataarkiven\n" +msgid "can only reopen input archives" +msgstr "kan inte Ã¥teröppna indataarkiven" -#: pg_backup_custom.c:753 +#: pg_backup_custom.c:745 #, c-format -msgid "parallel restore from standard input is not supported\n" -msgstr "parallell Ã¥terställning frÃ¥n standard in stöds inte\n" +msgid "parallel restore from standard input is not supported" +msgstr "parallell Ã¥terställning frÃ¥n standard in stöds inte" -#: pg_backup_custom.c:755 +#: pg_backup_custom.c:747 #, c-format -msgid "parallel restore from non-seekable file is not supported\n" -msgstr "parallell Ã¥terställning för en icke sökbar fil stöds inte\n" +msgid "parallel restore from non-seekable file is not supported" +msgstr "parallell Ã¥terställning för en icke sökbar fil stöds inte" -#: pg_backup_custom.c:774 +#: pg_backup_custom.c:763 #, c-format -msgid "could not set seek position in archive file: %s\n" -msgstr "kunde inte söka till rätt position i arkivfilen: %s\n" +msgid "could not set seek position in archive file: %m" +msgstr "kunde inte söka till rätt position i arkivfilen: %m" -#: pg_backup_custom.c:792 +#: pg_backup_custom.c:839 #, c-format -msgid "compressor active\n" -msgstr "komprimerare aktiv\n" +msgid "compressor active" +msgstr "komprimerare aktiv" -#: pg_backup_custom.c:848 +#: pg_backup_custom.c:894 #, c-format -msgid "WARNING: ftell mismatch with expected position -- ftell used\n" -msgstr "VARNING: ftell stämmer inte med förväntad position -- ftell använd\n" - -#. translator: this is a module name -#: pg_backup_db.c:29 -msgid "archiver (db)" -msgstr "arkiverare (db)" +msgid "ftell mismatch with expected position -- ftell used" +msgstr "ftell stämmer inte med förväntad position -- ftell använd" -#: pg_backup_db.c:45 +#: pg_backup_db.c:44 #, c-format -msgid "could not get server_version from libpq\n" -msgstr "kunde inte hämta serverversionen frÃ¥n libpq\n" +msgid "could not get server_version from libpq" +msgstr "kunde inte hämta serverversionen frÃ¥n libpq" -#: pg_backup_db.c:56 pg_dumpall.c:2057 +#: pg_backup_db.c:55 pg_dumpall.c:1806 #, c-format -msgid "server version: %s; %s version: %s\n" -msgstr "server version: %s; %s version: %s\n" +msgid "server version: %s; %s version: %s" +msgstr "server version: %s; %s version: %s" -#: pg_backup_db.c:58 pg_dumpall.c:2059 +#: pg_backup_db.c:57 pg_dumpall.c:1808 #, c-format -msgid "aborting because of server version mismatch\n" -msgstr "avbryter dÃ¥ serverversionerna i matchar\n" +msgid "aborting because of server version mismatch" +msgstr "avbryter dÃ¥ serverversionerna i matchar" -#: pg_backup_db.c:148 +#: pg_backup_db.c:140 #, c-format -msgid "connecting to database \"%s\" as user \"%s\"\n" -msgstr "kopplar upp mot databas \"%s\" som användare \"%s\"\n" +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "kopplar upp mot databas \"%s\" som användare \"%s\"" -#: pg_backup_db.c:155 pg_backup_db.c:204 pg_backup_db.c:265 pg_backup_db.c:306 -#: pg_dumpall.c:1880 pg_dumpall.c:1994 +#: pg_backup_db.c:147 pg_backup_db.c:196 pg_backup_db.c:257 pg_backup_db.c:298 +#: pg_dumpall.c:1631 pg_dumpall.c:1744 msgid "Password: " msgstr "Lösenord: " -#: pg_backup_db.c:187 +#: pg_backup_db.c:179 #, c-format -msgid "failed to reconnect to database\n" -msgstr "misslyckades att Ã¥teruppkoppla mot databasen\n" +msgid "failed to reconnect to database" +msgstr "misslyckades att Ã¥teruppkoppla mot databasen" -#: pg_backup_db.c:192 +#: pg_backup_db.c:184 #, c-format msgid "could not reconnect to database: %s" msgstr "kunde inte Ã¥teruppkoppla mot databasen: %s" -#: pg_backup_db.c:208 +#: pg_backup_db.c:200 #, c-format -msgid "connection needs password\n" -msgstr "anslutningen kräver lösenord\n" +msgid "connection needs password" +msgstr "anslutningen kräver lösenord" -#: pg_backup_db.c:259 +#: pg_backup_db.c:251 #, c-format -msgid "already connected to a database\n" -msgstr "är redan uppkopplad mot en databas\n" +msgid "already connected to a database" +msgstr "är redan uppkopplad mot en databas" -#: pg_backup_db.c:298 +#: pg_backup_db.c:290 #, c-format -msgid "failed to connect to database\n" -msgstr "misslyckades med att koppla upp mot databas\n" +msgid "failed to connect to database" +msgstr "misslyckades med att koppla upp mot databas" -#: pg_backup_db.c:314 +#: pg_backup_db.c:306 #, c-format msgid "connection to database \"%s\" failed: %s" msgstr "uppkoppling mot databas \"%s\" misslyckades: %s" -#: pg_backup_db.c:382 +#: pg_backup_db.c:378 pg_dumpall.c:1664 #, c-format msgid "%s" msgstr "%s" -#: pg_backup_db.c:389 +#: pg_backup_db.c:385 pg_dumpall.c:1869 pg_dumpall.c:1892 #, c-format msgid "query failed: %s" msgstr "frÃ¥ga misslyckades: %s" -#: pg_backup_db.c:391 +#: pg_backup_db.c:387 pg_dumpall.c:1870 pg_dumpall.c:1893 #, c-format -msgid "query was: %s\n" -msgstr "frÃ¥gan var: %s\n" +msgid "query was: %s" +msgstr "frÃ¥gan var: %s" -#: pg_backup_db.c:433 +#: pg_backup_db.c:428 #, c-format -msgid "query returned %d row instead of one: %s\n" -msgid_plural "query returned %d rows instead of one: %s\n" -msgstr[0] "frÃ¥ga gav %d rad istället för en: %s\n" -msgstr[1] "frÃ¥ga gav %d rader istället för en: %s\n" +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "frÃ¥ga gav %d rad istället för en: %s" +msgstr[1] "frÃ¥ga gav %d rader istället för en: %s" -#: pg_backup_db.c:469 -#, c-format -msgid "%s: %s Command was: %s\n" -msgstr "%s: %s Kommandot var: %s\n" - -#: pg_backup_db.c:525 pg_backup_db.c:599 pg_backup_db.c:606 +#: pg_backup_db.c:520 pg_backup_db.c:594 pg_backup_db.c:601 msgid "could not execute query" msgstr "kunde inte utföra frÃ¥ga" -#: pg_backup_db.c:578 +#: pg_backup_db.c:573 #, c-format msgid "error returned by PQputCopyData: %s" msgstr "fel returnerat av PQputCopyData: %s" -#: pg_backup_db.c:627 +#: pg_backup_db.c:622 #, c-format msgid "error returned by PQputCopyEnd: %s" msgstr "fel returnerat av PQputCopyEnd: %s" -#: pg_backup_db.c:633 -#, c-format -msgid "COPY failed for table \"%s\": %s" -msgstr "COPY misslyckades för tabell \"%s\": %s" - -#: pg_backup_db.c:639 pg_dump.c:1841 +#: pg_backup_db.c:634 pg_dump.c:1924 #, c-format -msgid "WARNING: unexpected extra results during COPY of table \"%s\"\n" -msgstr "VARNING: oväntade extraresultat under kopiering (COPY) av tabell \"%s\"\n" +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "oväntade extraresultat under kopiering (COPY) av tabell \"%s\"" -#: pg_backup_db.c:651 +#: pg_backup_db.c:646 msgid "could not start database transaction" msgstr "kunde inte starta databastransaktionen" -#: pg_backup_db.c:659 +#: pg_backup_db.c:654 msgid "could not commit database transaction" msgstr "kunde inte genomföra databastransaktionen" -#. translator: this is a module name -#: pg_backup_directory.c:65 -msgid "directory archiver" -msgstr "katalogarkiverare" - -#: pg_backup_directory.c:157 +#: pg_backup_directory.c:156 #, c-format -msgid "no output directory specified\n" -msgstr "ingen utdatakatalog angiven\n" +msgid "no output directory specified" +msgstr "ingen utdatakatalog angiven" -#: pg_backup_directory.c:186 +#: pg_backup_directory.c:185 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "kunde inte läsa katalog \"%s\": %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" -#: pg_backup_directory.c:190 +#: pg_backup_directory.c:189 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "kunde inte stänga katalog \"%s\": %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" -#: pg_backup_directory.c:196 +#: pg_backup_directory.c:195 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "kunde inte skapa katalog \"%s\": %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" -#: pg_backup_directory.c:355 pg_backup_directory.c:495 -#: pg_backup_directory.c:525 +#: pg_backup_directory.c:350 pg_backup_directory.c:488 +#: pg_backup_directory.c:518 #, c-format -msgid "could not write to output file: %s\n" -msgstr "kunde inte skriva till utdatafil: %s\n" +msgid "could not write to output file: %s" +msgstr "kunde inte skriva till utdatafil: %s" -#: pg_backup_directory.c:409 +#: pg_backup_directory.c:403 #, c-format -msgid "could not close data file: %s\n" -msgstr "kan inte stänga datafil: %s\n" +msgid "could not close data file: %m" +msgstr "kan inte stänga datafil: %m" -#: pg_backup_directory.c:450 +#: pg_backup_directory.c:443 #, c-format -msgid "could not open large object TOC file \"%s\" for input: %s\n" -msgstr "kunde inte öppna stora objekts TOC-fil \"%s\" för läsning: %s\n" +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "kunde inte öppna stora objekts TOC-fil \"%s\" för läsning: %m" -#: pg_backup_directory.c:461 +#: pg_backup_directory.c:454 #, c-format -msgid "invalid line in large object TOC file \"%s\": \"%s\"\n" -msgstr "ogiltig rad i stora objekts TOC-fil \"%s\": \"%s\"\n" +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "ogiltig rad i stora objekts TOC-fil \"%s\": \"%s\"" -#: pg_backup_directory.c:470 +#: pg_backup_directory.c:463 #, c-format -msgid "error reading large object TOC file \"%s\"\n" -msgstr "fel vid lösning av stora objekts TOC-fil \"%s\"\n" +msgid "error reading large object TOC file \"%s\"" +msgstr "fel vid lösning av stora objekts TOC-fil \"%s\"" -#: pg_backup_directory.c:474 +#: pg_backup_directory.c:467 #, c-format -msgid "could not close large object TOC file \"%s\": %s\n" -msgstr "kunde inte stänga stora objekts TOC-fil \"%s\": %s\n" +msgid "could not close large object TOC file \"%s\": %m" +msgstr "kunde inte stänga stora objekts TOC-fil \"%s\": %m" -#: pg_backup_directory.c:690 +#: pg_backup_directory.c:678 #, c-format -msgid "could not write to blobs TOC file\n" -msgstr "kunde inte skriva till blobbars TOC-fil\n" +msgid "could not write to blobs TOC file" +msgstr "kunde inte skriva till blobbars TOC-fil" -#: pg_backup_directory.c:722 +#: pg_backup_directory.c:710 #, c-format -msgid "file name too long: \"%s\"\n" -msgstr "filnamnet är för lÃ¥ngt: \"%s\"\n" +msgid "file name too long: \"%s\"" +msgstr "filnamnet är för lÃ¥ngt: \"%s\"" #: pg_backup_null.c:75 #, c-format -msgid "this format cannot be read\n" -msgstr "detta format kan inte läsas\n" - -#. translator: this is a module name -#: pg_backup_tar.c:103 -msgid "tar archiver" -msgstr "tar-arkiverare" +msgid "this format cannot be read" +msgstr "detta format kan inte läsas" -#: pg_backup_tar.c:181 +#: pg_backup_tar.c:177 #, c-format -msgid "could not open TOC file \"%s\" for output: %s\n" -msgstr "kunde inte öppna TOC-filen \"%s\" för utmatning: %s\n" +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "kunde inte öppna TOC-filen \"%s\" för utmatning: %m" -#: pg_backup_tar.c:189 +#: pg_backup_tar.c:184 #, c-format -msgid "could not open TOC file for output: %s\n" -msgstr "kunde inte öppna TOC-filen för utmatning: %s\n" +msgid "could not open TOC file for output: %m" +msgstr "kunde inte öppna TOC-filen för utmatning: %m" -#: pg_backup_tar.c:210 pg_backup_tar.c:366 +#: pg_backup_tar.c:203 pg_backup_tar.c:358 #, c-format -msgid "compression is not supported by tar archive format\n" -msgstr "komprimering är stödjs inte av arkivformatet tar\n" +msgid "compression is not supported by tar archive format" +msgstr "komprimering är stödjs inte av arkivformatet tar" -#: pg_backup_tar.c:218 +#: pg_backup_tar.c:211 #, c-format -msgid "could not open TOC file \"%s\" for input: %s\n" -msgstr "kunde inte öppna TOC-fil \"%s\" för läsning: %s\n" +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "kunde inte öppna TOC-fil \"%s\" för läsning: %m" -#: pg_backup_tar.c:225 +#: pg_backup_tar.c:218 #, c-format -msgid "could not open TOC file for input: %s\n" -msgstr "kunde inte öppna TOC-fil för läsning: %s\n" +msgid "could not open TOC file for input: %m" +msgstr "kunde inte öppna TOC-fil för läsning: %m" -#: pg_backup_tar.c:352 +#: pg_backup_tar.c:344 #, c-format -msgid "could not find file \"%s\" in archive\n" -msgstr "kunde inte hitta fil \"%s\" i arkiv\n" +msgid "could not find file \"%s\" in archive" +msgstr "kunde inte hitta fil \"%s\" i arkiv" -#: pg_backup_tar.c:418 +#: pg_backup_tar.c:410 #, c-format -msgid "could not generate temporary file name: %s\n" -msgstr "kunde inte generera temporärt filnamn: %s\n" +msgid "could not generate temporary file name: %m" +msgstr "kunde inte generera temporärt filnamn: %m" -#: pg_backup_tar.c:429 +#: pg_backup_tar.c:421 #, c-format -msgid "could not open temporary file\n" -msgstr "kunde inte öppna temporär fil\n" +msgid "could not open temporary file" +msgstr "kunde inte öppna temporär fil" -#: pg_backup_tar.c:456 +#: pg_backup_tar.c:448 #, c-format -msgid "could not close tar member\n" -msgstr "kunde inte stänga tar-medlem\n" +msgid "could not close tar member" +msgstr "kunde inte stänga tar-medlem" -#: pg_backup_tar.c:581 +#: pg_backup_tar.c:571 #, c-format msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" msgstr "internt fel -- varken th eller fh angiven i tarReadRaw()\n" -#: pg_backup_tar.c:704 -#, c-format -msgid "unexpected COPY statement syntax: \"%s\"\n" -msgstr "oväntad COPY-satssyntax: \"%s\"\n" - -#: pg_backup_tar.c:974 -#, c-format -msgid "invalid OID for large object (%u)\n" -msgstr "ogiltig OID för stort objekt (%u)\n" - -#: pg_backup_tar.c:1118 -#, c-format -msgid "could not close temporary file: %s\n" -msgstr "kunde inte stänga temporär fil: %s\n" - -#: pg_backup_tar.c:1128 +#: pg_backup_tar.c:693 #, c-format -msgid "actual file length (%s) does not match expected (%s)\n" -msgstr "verklig fillängd (%s) matchar inte det förväntade (%s)\n" +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "oväntad COPY-satssyntax: \"%s\"" -#: pg_backup_tar.c:1165 +#: pg_backup_tar.c:961 #, c-format -msgid "moving from position %s to next member at file position %s\n" -msgstr "flyttar frÃ¥n position %s till nästa del vid filposition %s\n" +msgid "invalid OID for large object (%u)" +msgstr "ogiltig OID för stort objekt (%u)" -#: pg_backup_tar.c:1176 +#: pg_backup_tar.c:1106 #, c-format -msgid "now at file position %s\n" -msgstr "nu pÃ¥ filposition %s\n" +msgid "could not close temporary file: %m" +msgstr "kunde inte stänga temporär fil: %m" -#: pg_backup_tar.c:1185 pg_backup_tar.c:1215 +#: pg_backup_tar.c:1115 #, c-format -msgid "could not find header for file \"%s\" in tar archive\n" -msgstr "kunde inte hitta filhuvud för fil \"%s\" i tar-arkiv\n" +msgid "actual file length (%s) does not match expected (%s)" +msgstr "verklig fillängd (%s) matchar inte det förväntade (%s)" -#: pg_backup_tar.c:1199 +#: pg_backup_tar.c:1172 pg_backup_tar.c:1202 #, c-format -msgid "skipping tar member %s\n" -msgstr "hoppar över tar-medlem %s\n" +msgid "could not find header for file \"%s\" in tar archive" +msgstr "kunde inte hitta filhuvud för fil \"%s\" i tar-arkiv" -#: pg_backup_tar.c:1203 +#: pg_backup_tar.c:1190 #, c-format -msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file.\n" -msgstr "dumpa data i oordning stöds inte av detta arkivformat: \"%s\" krävs, men kommer före \"%s\" i denna arkivfil.\n" +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "dumpa data i oordning stöds inte av detta arkivformat: \"%s\" krävs, men kommer före \"%s\" i denna arkivfil." -#: pg_backup_tar.c:1249 +#: pg_backup_tar.c:1235 #, c-format -msgid "incomplete tar header found (%lu byte)\n" -msgid_plural "incomplete tar header found (%lu bytes)\n" -msgstr[0] "inkomplett tar-huvud hittat (%lu byte)\n" -msgstr[1] "inkomplett tar-huvud hittat (%lu bytes)\n" +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "inkomplett tar-huvud hittat (%lu byte)" +msgstr[1] "inkomplett tar-huvud hittat (%lu bytes)" -#: pg_backup_tar.c:1290 +#: pg_backup_tar.c:1286 #, c-format -msgid "TOC Entry %s at %s (length %s, checksum %d)\n" -msgstr "TOC-objekt %s vid %s (längd %s, kontrollsumma %d)\n" - -#: pg_backup_tar.c:1301 -#, c-format -msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s\n" -msgstr "trasigt tar-huvud hittat i %s (förväntade %d, beräknad %d) filposition %s\n" +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "trasigt tar-huvud hittat i %s (förväntade %d, beräknad %d) filposition %s" #: pg_backup_utils.c:54 #, c-format -msgid "%s: unrecognized section name: \"%s\"\n" -msgstr "%s: okänt sektionsnamn: \"%s\"\n" +msgid "unrecognized section name: \"%s\"" +msgstr "okänt sektionsnamn: \"%s\"" -#: pg_backup_utils.c:56 pg_dump.c:545 pg_dump.c:562 pg_dumpall.c:313 -#: pg_dumpall.c:323 pg_dumpall.c:333 pg_dumpall.c:342 pg_dumpall.c:358 -#: pg_dumpall.c:430 pg_restore.c:283 pg_restore.c:299 pg_restore.c:311 +#: pg_backup_utils.c:55 pg_dump.c:612 pg_dump.c:629 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:290 pg_restore.c:306 +#: pg_restore.c:324 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_backup_utils.c:118 +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "slut pÃ¥ on_exit_nicely-slottar" + +#: pg_dump.c:543 #, c-format -msgid "out of on_exit_nicely slots\n" -msgstr "slut pÃ¥ on_exit_nicely-slottar\n" +msgid "compression level must be in range 0..9" +msgstr "komprimeringsnivÃ¥ mÃ¥ste vara i intervallet 0..9" -#: pg_dump.c:511 +#: pg_dump.c:581 #, c-format -msgid "compression level must be in range 0..9\n" -msgstr "komprimeringsnivÃ¥ mÃ¥ste vara i intervallet 0..9\n" +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits mÃ¥ste vara i intervallet -15..3" -#: pg_dump.c:560 pg_dumpall.c:321 pg_restore.c:297 +#: pg_dump.c:604 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert mÃ¥ste vara i intervallet %d..%d" -#: pg_dump.c:581 +#: pg_dump.c:627 pg_dumpall.c:346 pg_restore.c:304 #, c-format -msgid "options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "flaggorna \"bara schema\" (-s) och \"bara data\" (-a) kan inte användas tillsammans\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: pg_dump.c:587 +#: pg_dump.c:648 pg_restore.c:333 #, c-format -msgid "options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "flaggorna \"nollställ\" (-c) och \"bara data\" (-a) kan inte användas tillsammans\n" +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "flaggorna \"bara schema\" (-s) och \"bara data\" (-a) kan inte användas tillsammans" -#: pg_dump.c:593 +#: pg_dump.c:654 pg_restore.c:339 #, c-format -msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" -msgstr "flaggorna --inserts/--column-inserts och -o/--oids kan inte användas tillsammans\n" +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "flaggorna \"nollställ\" (-c) och \"bara data\" (-a) kan inte användas tillsammans" -#: pg_dump.c:594 +#: pg_dump.c:659 pg_dumpall.c:381 pg_restore.c:388 #, c-format -msgid "(The INSERT command cannot set OIDs.)\n" -msgstr "(Kommandot INSERT kan inte sätta OID:s.)\n" +msgid "option --if-exists requires option -c/--clean" +msgstr "flaggan --if-exists kräver flaggan -c/--clean" -#: pg_dump.c:599 +#: pg_dump.c:666 #, c-format -msgid "option --if-exists requires option -c/--clean\n" -msgstr "flaggan --if-exists kräver flaggan -c/--clean\n" +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts" +msgstr "flagga --on-conflict-do-nothing kräver --inserts, --rows-per-insert eller --column-inserts" -#: pg_dump.c:621 +#: pg_dump.c:688 #, c-format -msgid "WARNING: requested compression not available in this installation -- archive will be uncompressed\n" -msgstr "VARNING: efterfrÃ¥gad komprimering finns inte i denna installation -- arkivet kommer sparas okomprimerat\n" +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "efterfrÃ¥gad komprimering finns inte i denna installation -- arkivet kommer sparas okomprimerat" -#: pg_dump.c:636 +#: pg_dump.c:709 pg_restore.c:355 #, c-format -msgid "invalid number of parallel jobs\n" -msgstr "felaktigt antal parallella job\n" +msgid "invalid number of parallel jobs" +msgstr "felaktigt antal parallella job" -#: pg_dump.c:640 +#: pg_dump.c:713 #, c-format -msgid "parallel backup only supported by the directory format\n" -msgstr "parallell backup stöds bara med katalogformat\n" +msgid "parallel backup only supported by the directory format" +msgstr "parallell backup stöds bara med katalogformat" -#: pg_dump.c:695 +#: pg_dump.c:768 #, c-format msgid "" "Synchronized snapshots are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" "Synkroniseringssnapshots stöds inte av denna serverversion.\n" "Kör med --no-synchronized-snapshots istället om du inte kräver\n" -"synkroniserade snapshots.\n" +"synkroniserade snapshots." -#: pg_dump.c:702 +#: pg_dump.c:774 #, c-format -msgid "Exported snapshots are not supported by this server version.\n" -msgstr "Exporterade snapshots stöds inte i denna serverversion.\n" +msgid "Exported snapshots are not supported by this server version." +msgstr "Exporterade snapshots stöds inte i denna serverversion." -#: pg_dump.c:716 +#: pg_dump.c:786 #, c-format -msgid "last built-in OID is %u\n" -msgstr "sista inbyggda OID är %u\n" +msgid "last built-in OID is %u" +msgstr "sista inbyggda OID är %u" -#: pg_dump.c:725 +#: pg_dump.c:795 #, c-format -msgid "no matching schemas were found\n" -msgstr "hittade inga matchande scheman\n" +msgid "no matching schemas were found" +msgstr "hittade inga matchande scheman" -#: pg_dump.c:739 +#: pg_dump.c:809 #, c-format -msgid "no matching tables were found\n" -msgstr "hittade inga matchande tabeller\n" +msgid "no matching tables were found" +msgstr "hittade inga matchande tabeller" -#: pg_dump.c:913 +#: pg_dump.c:981 #, c-format msgid "" "%s dumps a database as a text file or to other formats.\n" @@ -1422,17 +1327,17 @@ msgstr "" "%s dumpar en databas som en textfil eller i andra format.\n" "\n" -#: pg_dump.c:914 pg_dumpall.c:575 pg_restore.c:449 +#: pg_dump.c:982 pg_dumpall.c:617 pg_restore.c:468 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_dump.c:915 +#: pg_dump.c:983 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [FLAGGA]... [DBNAMN]\n" -#: pg_dump.c:917 pg_dumpall.c:578 pg_restore.c:452 +#: pg_dump.c:985 pg_dumpall.c:620 pg_restore.c:471 #, c-format msgid "" "\n" @@ -1441,12 +1346,12 @@ msgstr "" "\n" "Allmänna flaggor:\n" -#: pg_dump.c:918 +#: pg_dump.c:986 #, c-format msgid " -f, --file=FILENAME output file or directory name\n" msgstr " -f, --file=FILENAME fil eller katalognamn för utdata\n" -#: pg_dump.c:919 +#: pg_dump.c:987 #, c-format msgid "" " -F, --format=c|d|t|p output file format (custom, directory, tar,\n" @@ -1455,42 +1360,42 @@ msgstr "" " -F, --format=c|d|t|p utdatans filformat (egen (c), katalog (d), tar (t),\n" " ren text (p) (standard))\n" -#: pg_dump.c:921 +#: pg_dump.c:989 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" msgstr " -j, --jobs=NUM använd sÃ¥ här mÃ¥nga parellella job för att dumpa\n" -#: pg_dump.c:922 pg_dumpall.c:580 +#: pg_dump.c:990 pg_dumpall.c:622 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose visa mer information\n" -#: pg_dump.c:923 pg_dumpall.c:581 +#: pg_dump.c:991 pg_dumpall.c:623 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_dump.c:924 +#: pg_dump.c:992 #, c-format msgid " -Z, --compress=0-9 compression level for compressed formats\n" msgstr " -Z, --compress=0-9 komprimeringsnivÃ¥ för komprimerade format\n" -#: pg_dump.c:925 pg_dumpall.c:582 +#: pg_dump.c:993 pg_dumpall.c:624 #, c-format msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" msgstr " --lock-wait-timeout=TIMEOUT misslyckas efter att ha väntat i TIMEOUT pÃ¥ tabellÃ¥s\n" -#: pg_dump.c:926 pg_dumpall.c:605 +#: pg_dump.c:994 pg_dumpall.c:652 #, c-format msgid " --no-sync do not wait for changes to be written safely to disk\n" msgstr " --no-sync vänta inte pÃ¥ att ändingar säkert skrivits till disk\n" -#: pg_dump.c:927 pg_dumpall.c:583 +#: pg_dump.c:995 pg_dumpall.c:625 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: pg_dump.c:929 pg_dumpall.c:584 +#: pg_dump.c:997 pg_dumpall.c:626 #, c-format msgid "" "\n" @@ -1499,52 +1404,47 @@ msgstr "" "\n" "Flaggor som styr utmatning:\n" -#: pg_dump.c:930 pg_dumpall.c:585 +#: pg_dump.c:998 pg_dumpall.c:627 #, c-format msgid " -a, --data-only dump only the data, not the schema\n" msgstr " -a, --data-only dumpa bara data, inte schema\n" -#: pg_dump.c:931 +#: pg_dump.c:999 #, c-format msgid " -b, --blobs include large objects in dump\n" msgstr " -b, --blobs inkludera stora objekt i dumpen\n" -#: pg_dump.c:932 +#: pg_dump.c:1000 #, c-format msgid " -B, --no-blobs exclude large objects in dump\n" msgstr " -B, --no-blobs exkludera stora objekt i dumpen\n" -#: pg_dump.c:933 pg_restore.c:463 +#: pg_dump.c:1001 pg_restore.c:482 #, c-format msgid " -c, --clean clean (drop) database objects before recreating\n" msgstr " -c, --clean nollställ (drop) databaser innan Ã¥terskapande\n" -#: pg_dump.c:934 +#: pg_dump.c:1002 #, c-format msgid " -C, --create include commands to create database in dump\n" msgstr " -C, --create inkludera kommandon för att skapa databasen i dumpen\n" -#: pg_dump.c:935 +#: pg_dump.c:1003 pg_dumpall.c:629 #, c-format msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" msgstr " -E, --encoding=KODNING dumpa data i teckenkodning KODNING\n" -#: pg_dump.c:936 +#: pg_dump.c:1004 #, c-format msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" msgstr " -n, --schema=SCHEMA dumpa bara namngivna scheman\n" -#: pg_dump.c:937 +#: pg_dump.c:1005 #, c-format msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" msgstr " -N, --exclude-schema=SCHEMA dumpa INTE de namngivna scheman\n" -#: pg_dump.c:938 pg_dumpall.c:588 -#, c-format -msgid " -o, --oids include OIDs in dump\n" -msgstr " -o, --oids inkludera OID:er i dumpning\n" - -#: pg_dump.c:939 +#: pg_dump.c:1006 #, c-format msgid "" " -O, --no-owner skip restoration of object ownership in\n" @@ -1553,52 +1453,52 @@ msgstr "" " -O, --no-owner hoppa över Ã¥terställande av objektägare i\n" " textformatdumpar\n" -#: pg_dump.c:941 pg_dumpall.c:591 +#: pg_dump.c:1008 pg_dumpall.c:634 #, c-format msgid " -s, --schema-only dump only the schema, no data\n" msgstr " -s, --schema-only dumpa bara scheman, inte data\n" -#: pg_dump.c:942 +#: pg_dump.c:1009 #, c-format msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" msgstr " -S, --superuser=NAME superanvändarens namn för textformatdumpar\n" -#: pg_dump.c:943 +#: pg_dump.c:1010 #, c-format msgid " -t, --table=TABLE dump the named table(s) only\n" msgstr " -t, --table=TABELL dumpa bara de namngivna tabellerna\n" -#: pg_dump.c:944 +#: pg_dump.c:1011 #, c-format msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" msgstr " -T, --exclude-table=TABELL dumpa INTE de namngivna tabellerna\n" -#: pg_dump.c:945 pg_dumpall.c:594 +#: pg_dump.c:1012 pg_dumpall.c:637 #, c-format msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" msgstr " -x, --no-privileges dumpa inte rättigheter (grant/revoke)\n" -#: pg_dump.c:946 pg_dumpall.c:595 +#: pg_dump.c:1013 pg_dumpall.c:638 #, c-format msgid " --binary-upgrade for use by upgrade utilities only\n" msgstr " --binary-upgrade används bara av uppgraderingsverktyg\n" -#: pg_dump.c:947 pg_dumpall.c:596 +#: pg_dump.c:1014 pg_dumpall.c:639 #, c-format msgid " --column-inserts dump data as INSERT commands with column names\n" msgstr " --column-inserts dumpa data som INSERT med kolumnnamn\n" -#: pg_dump.c:948 pg_dumpall.c:597 +#: pg_dump.c:1015 pg_dumpall.c:640 #, c-format msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" msgstr " --disable-dollar-quoting slÃ¥ av dollar-citering, använd standard SQL-citering\n" -#: pg_dump.c:949 pg_dumpall.c:598 pg_restore.c:480 +#: pg_dump.c:1016 pg_dumpall.c:641 pg_restore.c:499 #, c-format msgid " --disable-triggers disable triggers during data-only restore\n" msgstr " --disable-triggers slÃ¥ av utlösare vid Ã¥terställning av enbart data\n" -#: pg_dump.c:950 +#: pg_dump.c:1017 #, c-format msgid "" " --enable-row-security enable row security (dump only content user has\n" @@ -1607,72 +1507,97 @@ msgstr "" " --enable-row-security slÃ¥ pÃ¥ radsäkerhet (dumpa bara data användaren\n" " har rätt till)\n" -#: pg_dump.c:952 +#: pg_dump.c:1019 #, c-format msgid " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" msgstr " --exclude-table-data=TABELL dumpa INTE data för de namngivna tabellerna\n" -#: pg_dump.c:953 pg_dumpall.c:599 pg_restore.c:482 +#: pg_dump.c:1020 pg_dumpall.c:643 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM övertrumfa standardinställningen för extra_float_digits\n" + +#: pg_dump.c:1021 pg_dumpall.c:644 pg_restore.c:501 #, c-format msgid " --if-exists use IF EXISTS when dropping objects\n" msgstr " --if-exists använd IF EXISTS när objekt droppas\n" -#: pg_dump.c:954 pg_dumpall.c:600 +#: pg_dump.c:1022 pg_dumpall.c:645 #, c-format msgid " --inserts dump data as INSERT commands, rather than COPY\n" msgstr " --inserts dumpa data som INSERT, istället för COPY\n" -#: pg_dump.c:955 pg_dumpall.c:601 +#: pg_dump.c:1023 pg_dumpall.c:646 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root ladda partitioner via root-tabellen\n" + +#: pg_dump.c:1024 pg_dumpall.c:647 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr " --no-comments dumpa inte kommentarer\n" + +#: pg_dump.c:1025 pg_dumpall.c:648 #, c-format msgid " --no-publications do not dump publications\n" msgstr " --no-publications dumpa inte publiceringar\n" -#: pg_dump.c:956 pg_dumpall.c:603 +#: pg_dump.c:1026 pg_dumpall.c:650 #, c-format msgid " --no-security-labels do not dump security label assignments\n" msgstr " --no-security-labels dumpa inte tilldelning av säkerhetsetiketter\n" -#: pg_dump.c:957 pg_dumpall.c:604 +#: pg_dump.c:1027 pg_dumpall.c:651 #, c-format msgid " --no-subscriptions do not dump subscriptions\n" msgstr " --no-subscriptions dumpa inte prenumereringar\n" -#: pg_dump.c:958 +#: pg_dump.c:1028 #, c-format msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" msgstr " --no-synchronized-snapshots använd inte synkroniserade snapshots i parallella job\n" -#: pg_dump.c:959 pg_dumpall.c:606 +#: pg_dump.c:1029 pg_dumpall.c:653 #, c-format msgid " --no-tablespaces do not dump tablespace assignments\n" msgstr " --no-tablespaces dumpa inte användning av tabellutymmen\n" -#: pg_dump.c:960 pg_dumpall.c:607 +#: pg_dump.c:1030 pg_dumpall.c:654 #, c-format msgid " --no-unlogged-table-data do not dump unlogged table data\n" msgstr " --no-unlogged-table-data dumpa inte ologgad tabelldata\n" -#: pg_dump.c:961 pg_dumpall.c:608 +#: pg_dump.c:1031 pg_dumpall.c:655 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing addera ON CONFLICT DO NOTHING till INSERT-kommandon\n" + +#: pg_dump.c:1032 pg_dumpall.c:656 #, c-format msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" msgstr " --quote-all-identifiers citera alla identifierar, även om de inte är nyckelord\n" -#: pg_dump.c:962 +#: pg_dump.c:1033 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NRADER antal rader per INSERT; implicerar --inserts\n" + +#: pg_dump.c:1034 #, c-format msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" msgstr " --section=SEKTION dumpa namngiven sektion (pre-data, data eller post-data)\n" -#: pg_dump.c:963 +#: pg_dump.c:1035 #, c-format msgid " --serializable-deferrable wait until the dump can run without anomalies\n" msgstr " --serializable-deferrable wait until the dump can run without anomalies\n" -#: pg_dump.c:964 +#: pg_dump.c:1036 #, c-format msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" msgstr " --snapshot=SNAPSHOT använda namngivet snapshot för att dumpa\n" -#: pg_dump.c:965 pg_restore.c:490 +#: pg_dump.c:1037 pg_restore.c:510 #, c-format msgid "" " --strict-names require table and/or schema include patterns to\n" @@ -1681,7 +1606,7 @@ msgstr "" " --strict-names kräv att mallar för tabeller och/eller scheman matchar\n" " minst en sak var\n" -#: pg_dump.c:967 pg_dumpall.c:609 pg_restore.c:492 +#: pg_dump.c:1039 pg_dumpall.c:657 pg_restore.c:512 #, c-format msgid "" " --use-set-session-authorization\n" @@ -1692,7 +1617,7 @@ msgstr "" " använd kommandot SET SESSION AUTHORIZATION istället för\n" " kommandot ALTER OWNER för att sätta ägare\n" -#: pg_dump.c:971 pg_dumpall.c:613 pg_restore.c:496 +#: pg_dump.c:1043 pg_dumpall.c:661 pg_restore.c:516 #, c-format msgid "" "\n" @@ -1701,42 +1626,42 @@ msgstr "" "\n" "Flaggor för anslutning:\n" -#: pg_dump.c:972 +#: pg_dump.c:1044 #, c-format msgid " -d, --dbname=DBNAME database to dump\n" msgstr " -d, --dbname=DBNAMN databasens som skall dumpas\n" -#: pg_dump.c:973 pg_dumpall.c:615 pg_restore.c:497 +#: pg_dump.c:1045 pg_dumpall.c:663 pg_restore.c:517 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=VÄRDNAMN databasens värdnamn eller socketkatalog\n" -#: pg_dump.c:974 pg_dumpall.c:617 pg_restore.c:498 +#: pg_dump.c:1046 pg_dumpall.c:665 pg_restore.c:518 #, c-format msgid " -p, --port=PORT database server port number\n" msgstr " -p, --port=PORT databasens värdport\n" -#: pg_dump.c:975 pg_dumpall.c:618 pg_restore.c:499 +#: pg_dump.c:1047 pg_dumpall.c:666 pg_restore.c:519 #, c-format msgid " -U, --username=NAME connect as specified database user\n" msgstr " -U, --username=NAMN anslut med datta användarnamn mot databasen\n" -#: pg_dump.c:976 pg_dumpall.c:619 pg_restore.c:500 +#: pg_dump.c:1048 pg_dumpall.c:667 pg_restore.c:520 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password frÃ¥ga aldrig efter lösenord\n" -#: pg_dump.c:977 pg_dumpall.c:620 pg_restore.c:501 +#: pg_dump.c:1049 pg_dumpall.c:668 pg_restore.c:521 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password frÃ¥ga om lösenord (borde ske automatiskt)\n" -#: pg_dump.c:978 pg_dumpall.c:621 +#: pg_dump.c:1050 pg_dumpall.c:669 #, c-format msgid " --role=ROLENAME do SET ROLE before dump\n" msgstr " --role=ROLLNAMN gör SET ROLE innan dumpen\n" -#: pg_dump.c:980 +#: pg_dump.c:1052 #, c-format msgid "" "\n" @@ -1749,540 +1674,580 @@ msgstr "" "PGDATABASE att användas.\n" "\n" -#: pg_dump.c:982 pg_dumpall.c:625 pg_restore.c:508 +#: pg_dump.c:1054 pg_dumpall.c:673 pg_restore.c:528 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapportera fel till .\n" +msgid "Report bugs to .\n" +msgstr "Rapportera buggar till .\n" -#: pg_dump.c:999 +#: pg_dump.c:1073 pg_dumpall.c:499 #, c-format -msgid "invalid client encoding \"%s\" specified\n" -msgstr "ogiltig klientteckenkodning \"%s\" angiven\n" +msgid "invalid client encoding \"%s\" specified" +msgstr "ogiltig klientteckenkodning \"%s\" angiven" -#: pg_dump.c:1136 +#: pg_dump.c:1218 #, c-format msgid "" -"Synchronized snapshots are not supported on standby servers.\n" +"Synchronized snapshots on standby servers are not supported by this server version.\n" "Run with --no-synchronized-snapshots instead if you do not need\n" -"synchronized snapshots.\n" +"synchronized snapshots." msgstr "" -"Synkroniserade snapshots stöds inte av standby-servrar.\n" -"Kör med --no-synchronized-snapshots istället om du inte\n" -"behöver synkroniserade snapshots.\n" +"Synkroniserade snapshots pÃ¥ standby-servrar stöds inte av denna serverversion.\n" +"Kör med --no-synchronized-snapshots istället om du inte behöver\n" +"synkroniserade snapshots." -#: pg_dump.c:1205 +#: pg_dump.c:1287 #, c-format -msgid "invalid output format \"%s\" specified\n" -msgstr "ogiltigt utdataformat \"%s\" angivet\n" +msgid "invalid output format \"%s\" specified" +msgstr "ogiltigt utdataformat \"%s\" angivet" -#: pg_dump.c:1243 +#: pg_dump.c:1325 #, c-format -msgid "no matching schemas were found for pattern \"%s\"\n" -msgstr "hittade inga matchande scheman för mallen \"%s\"\n" +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "hittade inga matchande scheman för mallen \"%s\"" -#: pg_dump.c:1297 +#: pg_dump.c:1390 #, c-format -msgid "no matching tables were found for pattern \"%s\"\n" -msgstr "hittade inga matchande tabeller för mallen \"%s\"\n" +msgid "no matching tables were found for pattern \"%s\"" +msgstr "hittade inga matchande tabeller för mallen \"%s\"" -#: pg_dump.c:1701 +#: pg_dump.c:1804 #, c-format -msgid "dumping contents of table \"%s.%s\"\n" -msgstr "dumpar innehÃ¥llet i tabell \"%s.%s\"\n" +msgid "dumping contents of table \"%s.%s\"" +msgstr "dumpar innehÃ¥llet i tabell \"%s.%s\"" -#: pg_dump.c:1822 +#: pg_dump.c:1905 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed.\n" -msgstr "Dumpning av innehÃ¥llet i tabellen \"%s\" misslyckades: PQendcopy() misslyckades.\n" +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "Dumpning av innehÃ¥llet i tabellen \"%s\" misslyckades: PQendcopy() misslyckades." -#: pg_dump.c:1823 pg_dump.c:1833 +#: pg_dump.c:1906 pg_dump.c:1916 #, c-format msgid "Error message from server: %s" msgstr "Felmeddelandet frÃ¥n servern: %s" -#: pg_dump.c:1824 pg_dump.c:1834 +#: pg_dump.c:1907 pg_dump.c:1917 +#, c-format +msgid "The command was: %s" +msgstr "Kommandot var: %s" + +#: pg_dump.c:1915 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "Dumpning av innehÃ¥llet i tabellen \"%s\" misslyckades: PQgetResult() misslyckades." + +#: pg_dump.c:2666 #, c-format -msgid "The command was: %s\n" -msgstr "Kommandot var: %s\n" +msgid "saving database definition" +msgstr "sparar databasdefinition" -#: pg_dump.c:1832 +#: pg_dump.c:3109 #, c-format -msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed.\n" -msgstr "Dumpning av innehÃ¥llet i tabellen \"%s\" misslyckades: PQgetResult() misslyckades.\n" +msgid "saving encoding = %s" +msgstr "sparar kodning = %s" -#: pg_dump.c:2481 +#: pg_dump.c:3134 #, c-format -msgid "saving database definition\n" -msgstr "sparar databasdefinition\n" +msgid "saving standard_conforming_strings = %s" +msgstr "sparar standard_conforming_strings = %s" -#: pg_dump.c:2787 +#: pg_dump.c:3173 #, c-format -msgid "saving encoding = %s\n" -msgstr "sparar kodning = %s\n" +msgid "could not parse result of current_schemas()" +msgstr "kunde inte parsa resultat frÃ¥n current_schemas()" -#: pg_dump.c:2814 +#: pg_dump.c:3192 #, c-format -msgid "saving standard_conforming_strings = %s\n" -msgstr "sparar standard_conforming_strings = %s\n" +msgid "saving search_path = %s" +msgstr "sparar search_path = %s" -#: pg_dump.c:2854 +#: pg_dump.c:3232 #, c-format -msgid "reading large objects\n" -msgstr "läser stora objekt\n" +msgid "reading large objects" +msgstr "läser stora objekt" -#: pg_dump.c:3049 +#: pg_dump.c:3414 #, c-format -msgid "saving large objects\n" -msgstr "sparar stora objekt\n" +msgid "saving large objects" +msgstr "sparar stora objekt" -#: pg_dump.c:3094 +#: pg_dump.c:3460 #, c-format msgid "error reading large object %u: %s" msgstr "fel vid läsning av stort objekt %u: %s" -#: pg_dump.c:3147 +#: pg_dump.c:3512 #, c-format -msgid "reading row security enabled for table \"%s.%s\"\n" -msgstr "läser aktiverad radsäkerhet för tabell \"%s.%s\"\n" +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "läser aktiverad radsäkerhet för tabell \"%s.%s\"" -#: pg_dump.c:3179 +#: pg_dump.c:3543 #, c-format -msgid "reading policies for table \"%s.%s\"\n" -msgstr "läser policys för tabell \"%s.%s\"\n" +msgid "reading policies for table \"%s.%s\"" +msgstr "läser policys för tabell \"%s.%s\"" -#: pg_dump.c:3329 +#: pg_dump.c:3693 #, c-format -msgid "unexpected policy command type: %c\n" -msgstr "oväntad kommandotyp för policy: %c\n" +msgid "unexpected policy command type: %c" +msgstr "oväntad kommandotyp för policy: %c" -#: pg_dump.c:3445 +#: pg_dump.c:3820 #, c-format -msgid "WARNING: owner of publication \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av publicering \"%s\" verkar vara ogiltig\n" +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "ägare av publicering \"%s\" verkar vara ogiltig" -#: pg_dump.c:3575 +#: pg_dump.c:3957 #, c-format -msgid "reading publication membership for table \"%s.%s\"\n" -msgstr "läser publiceringsmedlemskap för tabell \"%s.%s\"\n" +msgid "reading publication membership for table \"%s.%s\"" +msgstr "läser publiceringsmedlemskap för tabell \"%s.%s\"" -#: pg_dump.c:3722 +#: pg_dump.c:4100 #, c-format -msgid "WARNING: subscriptions not dumped because current user is not a superuser\n" -msgstr "VARNING: prenumerationer har inte dumpats fÃ¥ aktuell användare inte är en superanvändare\n" +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "prenumerationer har inte dumpats fÃ¥ aktuell användare inte är en superanvändare" -#: pg_dump.c:3776 +#: pg_dump.c:4154 #, c-format -msgid "WARNING: owner of subscription \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av prenumeration \"%s\" verkar vara ogiltig\n" +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "ägare av prenumeration \"%s\" verkar vara ogiltig" -#: pg_dump.c:3820 +#: pg_dump.c:4198 #, c-format -msgid "WARNING: could not parse subpublications array\n" -msgstr "VARNING: kunde inte parsa arrayen för subpubliceringar\n" +msgid "could not parse subpublications array" +msgstr "kunde inte parsa arrayen för subpubliceringar" -#: pg_dump.c:4053 +#: pg_dump.c:4470 #, c-format -msgid "could not find parent extension for %s\n" -msgstr "kunde inte hitta föräldrautökning för %s\n" +msgid "could not find parent extension for %s %s" +msgstr "kunde inte hitta föräldrautökning för %s %s" -#: pg_dump.c:4207 +#: pg_dump.c:4602 #, c-format -msgid "WARNING: owner of schema \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av schema \"%s\" verkar vara ogiltig\n" +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "ägare av schema \"%s\" verkar vara ogiltig" -#: pg_dump.c:4230 +#: pg_dump.c:4625 #, c-format -msgid "schema with OID %u does not exist\n" -msgstr "schema med OID %u existerar inte\n" +msgid "schema with OID %u does not exist" +msgstr "schema med OID %u existerar inte" -#: pg_dump.c:4561 +#: pg_dump.c:4950 #, c-format -msgid "WARNING: owner of data type \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av datatyp \"%s\" verkar vara ogiltig\n" +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "ägare av datatyp \"%s\" verkar vara ogiltig" -#: pg_dump.c:4649 +#: pg_dump.c:5035 #, c-format -msgid "WARNING: owner of operator \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av operator \"%s\" verkar vara ogiltig\n" +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "ägare av operator \"%s\" verkar vara ogiltig" -#: pg_dump.c:4963 +#: pg_dump.c:5337 #, c-format -msgid "WARNING: owner of operator class \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av operatorklass \"%s\" verkar vara ogiltig\n" +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "ägare av operatorklass \"%s\" verkar vara ogiltig" -#: pg_dump.c:5050 +#: pg_dump.c:5421 #, c-format -msgid "WARNING: owner of operator family \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av operator-familj \"%s\" verkar vara ogiltig\n" +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "ägare av operator-familj \"%s\" verkar vara ogiltig" -#: pg_dump.c:5217 +#: pg_dump.c:5590 #, c-format -msgid "WARNING: owner of aggregate function \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av aggregatfunktion \"%s\" verkar vara ogiltig\n" +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "ägare av aggregatfunktion \"%s\" verkar vara ogiltig" -#: pg_dump.c:5476 +#: pg_dump.c:5850 #, c-format -msgid "WARNING: owner of function \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av funktion \"%s\" verkar vara ogiltig\n" +msgid "owner of function \"%s\" appears to be invalid" +msgstr "ägare av funktion \"%s\" verkar vara ogiltig" -#: pg_dump.c:6258 +#: pg_dump.c:6646 #, c-format -msgid "WARNING: owner of table \"%s\" appears to be invalid\n" -msgstr "VARNING: ägare av tabell \"%s\" verkar vara ogiltig\n" +msgid "owner of table \"%s\" appears to be invalid" +msgstr "ägare av tabell \"%s\" verkar vara ogiltig" -#: pg_dump.c:6300 pg_dump.c:16539 +#: pg_dump.c:6688 pg_dump.c:17017 #, c-format -msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found\n" -msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för sekvens med OID %u hittas inte\n" +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för sekvens med OID %u hittas inte" -#: pg_dump.c:6431 +#: pg_dump.c:6832 #, c-format -msgid "reading indexes for table \"%s.%s\"\n" -msgstr "läser index för tabell \"%s.%s\"\n" +msgid "reading indexes for table \"%s.%s\"" +msgstr "läser index för tabell \"%s.%s\"" -#: pg_dump.c:6712 +#: pg_dump.c:7233 #, c-format -msgid "reading extended statistics for table \"%s.%s\"\n" -msgstr "läser utökad statistik för tabell \"%s.%s\"\n" +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "läser främmande nyckel-villkor för tabell \"%s.%s\"" -#: pg_dump.c:6795 +#: pg_dump.c:7452 #, c-format -msgid "reading foreign key constraints for table \"%s.%s\"\n" -msgstr "läser främmande nyckel-villkor för tabell \"%s.%s\"\n" +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för pg_rewrite-rad med OID %u hittades inte" -#: pg_dump.c:7019 +#: pg_dump.c:7535 #, c-format -msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found\n" -msgstr "misslyckades med riktighetskontroll, föräldratabell med OID %u för pg_rewrite-rad med OID %u hittades inte\n" +msgid "reading triggers for table \"%s.%s\"" +msgstr "läser utlösare för tabell \"%s.%s\"" -#: pg_dump.c:7103 +#: pg_dump.c:7668 #, c-format -msgid "reading triggers for table \"%s.%s\"\n" -msgstr "läser utlösare för tabell \"%s.%s\"\n" +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "frÃ¥ga producerade null som refererad tabell för främmande nyckel-utlösare \"%s\" i tabell \"%s\" (OID för tabell : %u)" -#: pg_dump.c:7241 +#: pg_dump.c:8223 #, c-format -msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)\n" -msgstr "frÃ¥ga producerade null som refererad tabell för främmande nyckel-utlösare \"%s\" i tabell \"%s\" (OID för tabell : %u)\n" +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "hittar kolumner och typer för tabell \"%s.%s\"" -#: pg_dump.c:7813 +#: pg_dump.c:8359 #, c-format -msgid "finding the columns and types of table \"%s.%s\"\n" -msgstr "hittar kolumner och typer för tabell \"%s.%s\"\n" +msgid "invalid column numbering in table \"%s\"" +msgstr "ogiltigt kolumnnumrering i tabell \"%s\"" -#: pg_dump.c:7978 +#: pg_dump.c:8396 #, c-format -msgid "invalid column numbering in table \"%s\"\n" -msgstr "ogiltigt kolumnnumrering i tabell \"%s\"\n" +msgid "finding default expressions of table \"%s.%s\"" +msgstr "hittar default-uttryck för tabell \"%s.%s\"" -#: pg_dump.c:8014 +#: pg_dump.c:8418 #, c-format -msgid "finding default expressions of table \"%s.%s\"\n" -msgstr "hittar default-uttryck för tabell \"%s.%s\"\n" +msgid "invalid adnum value %d for table \"%s\"" +msgstr "felaktigt adnum-värde %d för tabell \"%s\"" -#: pg_dump.c:8037 +#: pg_dump.c:8483 #, c-format -msgid "invalid adnum value %d for table \"%s\"\n" -msgstr "felaktigt adnum-värde %d för tabell \"%s\"\n" +msgid "finding check constraints for table \"%s.%s\"" +msgstr "hittar check-villkor för tabell \"%s.%s\"" -#: pg_dump.c:8103 +#: pg_dump.c:8532 #, c-format -msgid "finding check constraints for table \"%s.%s\"\n" -msgstr "hittar check-villkor för tabell \"%s.%s\"\n" +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "förväntade %d check-villkor för tabell \"%s\" men hittade %d" +msgstr[1] "förväntade %d check-villkor för tabell \"%s\" men hittade %d" -#: pg_dump.c:8152 +#: pg_dump.c:8536 #, c-format -msgid "expected %d check constraint on table \"%s\" but found %d\n" -msgid_plural "expected %d check constraints on table \"%s\" but found %d\n" -msgstr[0] "förväntade %d check-villkor för tabell \"%s\" men hittade %d\n" -msgstr[1] "förväntade %d check-villkor för tabell \"%s\" men hittade %d\n" +msgid "(The system catalogs might be corrupted.)" +msgstr "(systemkatalogerna kan vara trasiga.)" -#: pg_dump.c:8156 +#: pg_dump.c:10117 #, c-format -msgid "(The system catalogs might be corrupted.)\n" -msgstr "(systemkatalogerna kan vara trasiga.)\n" +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "typtype för datatyp \"%s\" verkar vara ogiltig" -#: pg_dump.c:9714 +#: pg_dump.c:11471 #, c-format -msgid "WARNING: typtype of data type \"%s\" appears to be invalid\n" -msgstr "VARNING: typtype för datatyp \"%s\" verkar vara ogiltig\n" +msgid "bogus value in proargmodes array" +msgstr "felaktigt värde i arrayen proargmodes" -#: pg_dump.c:11143 +#: pg_dump.c:11843 #, c-format -msgid "WARNING: bogus value in proargmodes array\n" -msgstr "VARNING: felaktigt värde i arrayen proargmodes\n" +msgid "could not parse proallargtypes array" +msgstr "kunde inte tolka arrayen proallargtypes" -#: pg_dump.c:11469 +#: pg_dump.c:11859 #, c-format -msgid "WARNING: could not parse proallargtypes array\n" -msgstr "VARNING: kunde inte tolka arrayen proallargtypes\n" +msgid "could not parse proargmodes array" +msgstr "kunde inte tolka arrayen proargmodes" -#: pg_dump.c:11485 +#: pg_dump.c:11873 #, c-format -msgid "WARNING: could not parse proargmodes array\n" -msgstr "VARNING: kunde inte tolka arrayen proargmodes\n" +msgid "could not parse proargnames array" +msgstr "kunde inte tolka arrayen proargnames" -#: pg_dump.c:11499 +#: pg_dump.c:11884 #, c-format -msgid "WARNING: could not parse proargnames array\n" -msgstr "VARNING: kunde inte tolka arrayen proargnames\n" +msgid "could not parse proconfig array" +msgstr "kunde inte tolka arrayen proconfig" -#: pg_dump.c:11510 +#: pg_dump.c:11964 #, c-format -msgid "WARNING: could not parse proconfig array\n" -msgstr "VARNING: kunde inte tolka arrayen proconfig\n" +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "okänt provolatile-värde för funktion \"%s\"" -#: pg_dump.c:11581 +#: pg_dump.c:12014 pg_dump.c:14066 #, c-format -msgid "unrecognized provolatile value for function \"%s\"\n" -msgstr "okänt provolatile-värde för funktion \"%s\"\n" +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "okänt proparallel-värde för funktion \"%s\"" -#: pg_dump.c:11625 pg_dump.c:13623 +#: pg_dump.c:12147 pg_dump.c:12256 pg_dump.c:12263 #, c-format -msgid "unrecognized proparallel value for function \"%s\"\n" -msgstr "okänt proparallel-värde för funktion \"%s\"\n" +msgid "could not find function definition for function with OID %u" +msgstr "kunde inte hitta funktionsdefinitionen för funktion med OID %u" -#: pg_dump.c:11733 pg_dump.c:11843 pg_dump.c:11850 +#: pg_dump.c:12186 #, c-format -msgid "could not find function definition for function with OID %u\n" -msgstr "kunde inte hitta funktionsdefinitionen för funktion med OID %u\n" +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "felaktigt värde i fältet pg_cast.castfunc eller pg_cast.castmethod" -#: pg_dump.c:11778 +#: pg_dump.c:12189 #, c-format -msgid "WARNING: bogus value in pg_cast.castfunc or pg_cast.castmethod field\n" -msgstr "VARNING: felaktigt värde i fältet pg_cast.castfunc eller pg_cast.castmethod\n" +msgid "bogus value in pg_cast.castmethod field" +msgstr "felaktigt värde i fältet pg_cast.castmethod" -#: pg_dump.c:11781 +#: pg_dump.c:12282 #, c-format -msgid "WARNING: bogus value in pg_cast.castmethod field\n" -msgstr "VARNING: felaktigt värde i fältet pg_cast.castmethod\n" +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "felaktig transform-definition, minst en av trffromsql och trftosql mÃ¥ste vara ickenoll" -#: pg_dump.c:11871 +#: pg_dump.c:12299 #, c-format -msgid "WARNING: bogus transform definition, at least one of trffromsql and trftosql should be nonzero\n" -msgstr "VARNING: felaktig transform-definition, minst en av trffromsql och trftosql mÃ¥ste vara ickenoll\n" +msgid "bogus value in pg_transform.trffromsql field" +msgstr "felaktigt värde i fältet pg_transform.trffromsql" -#: pg_dump.c:11888 +#: pg_dump.c:12320 #, c-format -msgid "WARNING: bogus value in pg_transform.trffromsql field\n" -msgstr "VARNING: felaktigt värde i fältet pg_transform.trffromsql\n" +msgid "bogus value in pg_transform.trftosql field" +msgstr "felaktigt värde i fältet pg_transform.trftosql" -#: pg_dump.c:11909 +#: pg_dump.c:12636 #, c-format -msgid "WARNING: bogus value in pg_transform.trftosql field\n" -msgstr "VARNING: felaktigt värde i fältet pg_transform.trftosql\n" +msgid "could not find operator with OID %s" +msgstr "kunde inte hitta en operator med OID %s." -#: pg_dump.c:12305 +#: pg_dump.c:12704 #, c-format -msgid "WARNING: invalid type \"%c\" of access method \"%s\"\n" -msgstr "VARNING: ogiltig typ \"%c\" för accessmetod \"%s\"\n" +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "ogiltig typ \"%c\" för accessmetod \"%s\"" -#: pg_dump.c:13086 +#: pg_dump.c:13458 #, c-format msgid "unrecognized collation provider: %s\n" -msgstr "okänd soreteringsleverantör: %s\n" +msgstr "okänd jämförelseleverantör: %s\n" + +#: pg_dump.c:13930 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "aggregatfunktion %s kunde inte dumpas korrekt för denna databasversion; ignorerad" -#: pg_dump.c:13533 +#: pg_dump.c:13985 #, c-format -msgid "WARNING: aggregate function %s could not be dumped correctly for this database version; ignored\n" -msgstr "VARNING: aggregatfunktion %s kunde inte dumpas korrekt för denna databasversion; ignorerad\n" +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "okänt aggfinalmodify-värde för aggregat \"%s\"" -#: pg_dump.c:14389 +#: pg_dump.c:14041 #, c-format -msgid "unrecognized object type in default privileges: %d\n" -msgstr "okänd objekttyp i standardrättigheter: %d\n" +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "okänt aggmfinalmodify-värde för aggregat \"%s\"" -#: pg_dump.c:14407 +#: pg_dump.c:14763 #, c-format -msgid "could not parse default ACL list (%s)\n" -msgstr "kunde inte parsa standard-ACL-lista (%s)\n" +msgid "unrecognized object type in default privileges: %d" +msgstr "okänd objekttyp i standardrättigheter: %d" -#: pg_dump.c:14488 +#: pg_dump.c:14781 #, c-format -msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "kunde inte parsa initial GRANT ACL-lista (%s) eller initial REVOKE ACL-lista (%s) för objekt \"%s\" (%s)\n" +msgid "could not parse default ACL list (%s)" +msgstr "kunde inte parsa standard-ACL-lista (%s)" -#: pg_dump.c:14496 +#: pg_dump.c:14861 #, c-format -msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)\n" -msgstr "kunde inte parsa GRANT ACL-lista (%s) eller REVOKE ACL-lista (%s) för objekt \"%s\" (%s)\n" +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "kunde inte parsa initial GRANT ACL-lista (%s) eller initial REVOKE ACL-lista (%s) för objekt \"%s\" (%s)" -#: pg_dump.c:14971 +#: pg_dump.c:14869 #, c-format -msgid "query to obtain definition of view \"%s\" returned no data\n" -msgstr "frÃ¥ga för att hämta definition av vy \"%s\" returnerade ingen data\n" +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "kunde inte parsa GRANT ACL-lista (%s) eller REVOKE ACL-lista (%s) för objekt \"%s\" (%s)" -#: pg_dump.c:14974 +#: pg_dump.c:15368 #, c-format -msgid "query to obtain definition of view \"%s\" returned more than one definition\n" -msgstr "frÃ¥ga för att hämta definition av vy \"%s\" returnerade mer än en definiton\n" +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "frÃ¥ga för att hämta definition av vy \"%s\" returnerade ingen data" -#: pg_dump.c:14981 +#: pg_dump.c:15371 #, c-format -msgid "definition of view \"%s\" appears to be empty (length zero)\n" -msgstr "definition av vy \"%s\" verkar vara tom (längd noll)\n" +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "frÃ¥ga för att hämta definition av vy \"%s\" returnerade mer än en definition" -#: pg_dump.c:15210 +#: pg_dump.c:15378 #, c-format -msgid "invalid number of parents %d for table \"%s\"\n" -msgstr "ogiltigt antal (%d) föräldrar för tabell \"%s\"\n" +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "definition av vy \"%s\" verkar vara tom (längd noll)" -#: pg_dump.c:15857 +#: pg_dump.c:15460 #, c-format -msgid "invalid column number %d for table \"%s\"\n" -msgstr "ogiltigt kolumnnummer %d för tabell \"%s\"\n" +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS stöds inte längre (tabell \"%s\")" -#: pg_dump.c:16041 +#: pg_dump.c:15911 #, c-format -msgid "missing index for constraint \"%s\"\n" -msgstr "saknar index för integritetsvillkor \"%s\"\n" +msgid "invalid number of parents %d for table \"%s\"" +msgstr "ogiltigt antal (%d) föräldrar för tabell \"%s\"" -#: pg_dump.c:16244 +#: pg_dump.c:16248 #, c-format -msgid "unrecognized constraint type: %c\n" -msgstr "oväntad integritetsvillkorstyp: %c\n" +msgid "invalid column number %d for table \"%s\"" +msgstr "ogiltigt kolumnnummer %d för tabell \"%s\"" -#: pg_dump.c:16381 pg_dump.c:16607 +#: pg_dump.c:16510 #, c-format -msgid "query to get data of sequence \"%s\" returned %d row (expected 1)\n" -msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)\n" -msgstr[0] "frÃ¥ga för att hämta data för sekvens \"%s\" returnerade %d rad (förväntade 1)\n" -msgstr[1] "frÃ¥ga för att hämta data för sekvens \"%s\" returnerade %d rader (förväntade 1)\n" +msgid "missing index for constraint \"%s\"" +msgstr "saknar index för integritetsvillkor \"%s\"" -#: pg_dump.c:16705 +#: pg_dump.c:16730 #, c-format -msgid "unexpected tgtype value: %d\n" -msgstr "oväntat tgtype-värde: %d\n" +msgid "unrecognized constraint type: %c" +msgstr "oväntad integritetsvillkorstyp: %c" -#: pg_dump.c:16779 +#: pg_dump.c:16862 pg_dump.c:17082 #, c-format -msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"\n" -msgstr "felaktig argumentsträng (%s) för utlösare \"%s\" i tabell \"%s\"\n" +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "frÃ¥ga för att hämta data för sekvens \"%s\" returnerade %d rad (förväntade 1)" +msgstr[1] "frÃ¥ga för att hämta data för sekvens \"%s\" returnerade %d rader (förväntade 1)" -#: pg_dump.c:17010 +#: pg_dump.c:16896 #, c-format -msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned\n" -msgstr "frÃ¥ga för att hämta regel \"%s\" för tabell \"%s\" misslyckades: fel antal rader returnerades\n" +msgid "unrecognized sequence type: %s" +msgstr "okänd sekvenstyp: %s" -#: pg_dump.c:17405 +#: pg_dump.c:17178 #, c-format -msgid "reading dependency data\n" -msgstr "läser beroendedata\n" +msgid "unexpected tgtype value: %d" +msgstr "oväntat tgtype-värde: %d" -#: pg_dump.c:17870 +#: pg_dump.c:17252 #, c-format -msgid "WARNING: could not parse reloptions array\n" -msgstr "VARNING: kunde inte parsa arrayen reloptions\n" +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "felaktig argumentsträng (%s) för utlösare \"%s\" i tabell \"%s\"" -#. translator: this is a module name -#: pg_dump_sort.c:25 -msgid "sorter" -msgstr "sorterare" +#: pg_dump.c:17481 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "frÃ¥ga för att hämta regel \"%s\" för tabell \"%s\" misslyckades: fel antal rader returnerades" -#: pg_dump_sort.c:413 +#: pg_dump.c:17643 #, c-format -msgid "invalid dumpId %d\n" -msgstr "ogiltigt dumpId %d\n" +msgid "could not find referenced extension %u" +msgstr "kunde inte hitta refererad utökning %u" -#: pg_dump_sort.c:419 +#: pg_dump.c:17855 #, c-format -msgid "invalid dependency %d\n" -msgstr "ogiltigt beroende %d\n" +msgid "reading dependency data" +msgstr "läser beroendedata" -#: pg_dump_sort.c:652 +#: pg_dump.c:17910 #, c-format -msgid "could not identify dependency loop\n" -msgstr "kunde inte fastställa beroendeloop\n" +msgid "no referencing object %u %u" +msgstr "inget refererande objekt %u %u" -#: pg_dump_sort.c:1175 +#: pg_dump.c:17921 #, c-format -msgid "NOTICE: there are circular foreign-key constraints on this table:\n" -msgid_plural "NOTICE: there are circular foreign-key constraints among these tables:\n" -msgstr[0] "NOTIS: det finns cirkulära främmande nyckelberoenden för denna tabell:\n" -msgstr[1] "NOTIS: det finns cirkulära främmande nyckelberoenden för dessa tabeller:\n" +msgid "no referenced object %u %u" +msgstr "inget refererat objekt %u %u" -#: pg_dump_sort.c:1179 pg_dump_sort.c:1199 +#: pg_dump.c:18289 #, c-format -msgid " %s\n" -msgstr " %s\n" +msgid "could not parse reloptions array" +msgstr "kunde inte parsa arrayen reloptions" -#: pg_dump_sort.c:1180 +#: pg_dump_sort.c:328 #, c-format -msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.\n" -msgstr "Du kan eventiellt inte Ã¥terställa dumpen utan att använda --disable-triggers eller temporärt droppa vilkoren.\n" +msgid "invalid dumpId %d" +msgstr "ogiltigt dumpId %d" -#: pg_dump_sort.c:1181 +#: pg_dump_sort.c:334 #, c-format -msgid "Consider using a full dump instead of a --data-only dump to avoid this problem.\n" -msgstr "Överväg att göra en full dump istället för --data-only för att undvika detta problem.\n" +msgid "invalid dependency %d" +msgstr "ogiltigt beroende %d" -#: pg_dump_sort.c:1193 +#: pg_dump_sort.c:567 #, c-format -msgid "WARNING: could not resolve dependency loop among these items:\n" -msgstr "VARNING: kunde inte räta ut beroendeloopen för dessa saker:\n" +msgid "could not identify dependency loop" +msgstr "kunde inte fastställa beroendeloop" -#: pg_dumpall.c:189 +#: pg_dump_sort.c:1130 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "det finns cirkulära främmande nyckelberoenden för denna tabell:" +msgstr[1] "det finns cirkulära främmande nyckelberoenden för dessa tabeller:" + +#: pg_dump_sort.c:1134 pg_dump_sort.c:1154 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1135 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "Du kan eventiellt inte Ã¥terställa dumpen utan att använda --disable-triggers eller temporärt droppa vilkoren." + +#: pg_dump_sort.c:1136 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Överväg att göra en full dump istället för --data-only för att undvika detta problem." + +#: pg_dump_sort.c:1148 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "kunde inte räta ut beroendeloopen för dessa saker:" + +#: pg_dumpall.c:200 #, c-format msgid "" "The program \"pg_dump\" is needed by %s but was not found in the\n" "same directory as \"%s\".\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Programmet \"pg_dump\" behövs av %s men kunde inte hittas i samma katalog\n" "som \"%s\".\n" -"Kontrollera din installation.\n" +"Kontrollera din installation." -#: pg_dumpall.c:196 +#: pg_dumpall.c:205 #, c-format msgid "" "The program \"pg_dump\" was found by \"%s\"\n" "but was not the same version as %s.\n" -"Check your installation.\n" +"Check your installation." msgstr "" "Programmet \"pg_dump\" hittades av \"%s\"\n" "men hade inte samma version som \"%s\".\n" -"Kontrollera din installation.\n" +"Kontrollera din installation." -#: pg_dumpall.c:331 +#: pg_dumpall.c:356 #, c-format -msgid "%s: options -g/--globals-only and -r/--roles-only cannot be used together\n" -msgstr "%s: flaggorna \"bara gobala\" (-g) och \"bara roller\" (-r) kan inte användas tillsammans\n" +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only" +msgstr "flaggan --exclude-database kan inte användas tillsammans med -g/--globals-only, -r/--roles-only eller -t/--tablespaces-only" -#: pg_dumpall.c:340 +#: pg_dumpall.c:365 #, c-format -msgid "%s: options -g/--globals-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: flaggorna \"bara globala\" (-g) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans\n" +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "flaggorna \"bara gobala\" (-g) och \"bara roller\" (-r) kan inte användas tillsammans" -#: pg_dumpall.c:349 pg_restore.c:367 +#: pg_dumpall.c:373 #, c-format -msgid "%s: option --if-exists requires option -c/--clean\n" -msgstr "%s: flaggan --if-exists kräver flaggan -c/--clean\n" +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "flaggorna \"bara globala\" (-g) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans" -#: pg_dumpall.c:356 +#: pg_dumpall.c:387 #, c-format -msgid "%s: options -r/--roles-only and -t/--tablespaces-only cannot be used together\n" -msgstr "%s: flaggorna \"bara roller\" (-r) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans\n" +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "flaggorna \"bara roller\" (-r) och \"bara tabellutrymmen\" (-t) kan inte användas tillsammans" -#: pg_dumpall.c:412 pg_dumpall.c:1983 +#: pg_dumpall.c:448 pg_dumpall.c:1734 #, c-format -msgid "%s: could not connect to database \"%s\"\n" -msgstr "%s: kunde inte ansluta till databasen \"%s\"\n" +msgid "could not connect to database \"%s\"" +msgstr "kunde inte ansluta till databasen \"%s\"" -#: pg_dumpall.c:427 +#: pg_dumpall.c:462 #, c-format msgid "" -"%s: could not connect to databases \"postgres\" or \"template1\"\n" -"Please specify an alternative database.\n" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." msgstr "" -"%s: kunde inte ansluta till databasen \"postgres\" eller \"template1\"\n" -"Ange en annan databas.\n" +"kunde inte ansluta till databasen \"postgres\" eller \"template1\"\n" +"Ange en annan databas." -#: pg_dumpall.c:444 +#: pg_dumpall.c:484 #, c-format -msgid "%s: could not open the output file \"%s\": %s\n" -msgstr "%s: kunde inte öppna utdatafilen \"%s\": %s\n" +msgid "could not open the output file \"%s\": %m" +msgstr "kunde inte öppna utdatafilen \"%s\": %m" -#: pg_dumpall.c:574 +#: pg_dumpall.c:616 #, c-format msgid "" "%s extracts a PostgreSQL database cluster into an SQL script file.\n" @@ -2291,62 +2256,72 @@ msgstr "" "%s extraherar ett PostgreSQL databaskluster till en SQL-scriptfil.\n" "\n" -#: pg_dumpall.c:576 +#: pg_dumpall.c:618 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [FLAGGA]...\n" -#: pg_dumpall.c:579 +#: pg_dumpall.c:621 #, c-format msgid " -f, --file=FILENAME output file name\n" msgstr " -f, --file=FILENAME utdatafilnamn\n" -#: pg_dumpall.c:586 +#: pg_dumpall.c:628 #, c-format msgid " -c, --clean clean (drop) databases before recreating\n" msgstr " -c, --clean nollställa (droppa) databaser innan Ã¥terskapning\n" -#: pg_dumpall.c:587 +#: pg_dumpall.c:630 #, c-format msgid " -g, --globals-only dump only global objects, no databases\n" msgstr " -g, --globals-only dumpa bara globala objekt, inte databaser\n" -#: pg_dumpall.c:589 pg_restore.c:472 +#: pg_dumpall.c:631 +#, c-format +msgid " -o, --oids include OIDs in dump\n" +msgstr " -o, --oids inkludera OID:er i dumpning\n" + +#: pg_dumpall.c:632 pg_restore.c:491 #, c-format msgid " -O, --no-owner skip restoration of object ownership\n" msgstr " -O, --no-owner Ã¥terställ inte objektägare\n" -#: pg_dumpall.c:590 +#: pg_dumpall.c:633 #, c-format msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" msgstr " -r, --roles-only dumpa endast roller, inte databaser eller tabellutrymmen\n" -#: pg_dumpall.c:592 +#: pg_dumpall.c:635 #, c-format msgid " -S, --superuser=NAME superuser user name to use in the dump\n" msgstr " -S, --superuser=NAMN superanvändarens namn för användning i dumpen\n" -#: pg_dumpall.c:593 +#: pg_dumpall.c:636 #, c-format msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" msgstr " -t, --tablespaces-only dumpa endasdt tabellutrymmen, inte databaser eller roller\n" -#: pg_dumpall.c:602 +#: pg_dumpall.c:642 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=MALL uteslut databaser vars namn matchar MALL\n" + +#: pg_dumpall.c:649 #, c-format msgid " --no-role-passwords do not dump passwords for roles\n" msgstr " --no-role-passwords dumpa inte lösenord för roller\n" -#: pg_dumpall.c:614 +#: pg_dumpall.c:662 #, c-format msgid " -d, --dbname=CONNSTR connect using connection string\n" msgstr " -d, --dbname=ANSLSTR anslut med anslutningssträng\n" -#: pg_dumpall.c:616 +#: pg_dumpall.c:664 #, c-format msgid " -l, --database=DBNAME alternative default database\n" msgstr " -l, --database=DBNAMN alternativ standarddatabas\n" -#: pg_dumpall.c:623 +#: pg_dumpall.c:671 #, c-format msgid "" "\n" @@ -2358,112 +2333,97 @@ msgstr "" "Om -f/--file inte används sÃ¥ kommer SQL-skriptet skriva till standard ut.\n" "\n" -#: pg_dumpall.c:828 -#, c-format -msgid "%s: role name starting with \"pg_\" skipped (%s)\n" -msgstr "%s: rollnamn som startar med \"pg_\" hoppas över (%s)\n" - -#: pg_dumpall.c:1208 -#, c-format -msgid "%s: could not parse ACL list (%s) for tablespace \"%s\"\n" -msgstr "%s: kunde inte tolka ACL-listan (%s) för tabellutrymme \"%s\"\n" - -#: pg_dumpall.c:1525 +#: pg_dumpall.c:876 #, c-format -msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" -msgstr "%s: kunde inte tolka ACL-listan (%s) för databas \"%s\"\n" +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "rollnamn som startar med \"pg_\" hoppas över (%s)" -#: pg_dumpall.c:1739 +#: pg_dumpall.c:1258 #, c-format -msgid "%s: dumping database \"%s\"...\n" -msgstr "%s: dumpar databas \"%s\"...\n" +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "kunde inte tolka ACL-listan (%s) för tabellutrymme \"%s\"" -#: pg_dumpall.c:1763 +#: pg_dumpall.c:1475 #, c-format -msgid "%s: pg_dump failed on database \"%s\", exiting\n" -msgstr "%s: pg_dump misslyckades med databas \"%s\", avslutar\n" +msgid "excluding database \"%s\"..." +msgstr "utesluter databas \"%s\"..." -#: pg_dumpall.c:1772 +#: pg_dumpall.c:1479 #, c-format -msgid "%s: could not re-open the output file \"%s\": %s\n" -msgstr "%s: kunde inte öppna om utdatafilen \"%s\": %s\n" +msgid "dumping database \"%s\"..." +msgstr "dumpar databas \"%s\"..." -#: pg_dumpall.c:1817 +#: pg_dumpall.c:1511 #, c-format -msgid "%s: running \"%s\"\n" -msgstr "%s: kör \"%s\"\n" +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump misslyckades med databas \"%s\", avslutar" -#: pg_dumpall.c:2006 +#: pg_dumpall.c:1520 #, c-format -msgid "%s: could not connect to database \"%s\": %s\n" -msgstr "%s: kunde inte ansluta till databasen \"%s\": %s\n" +msgid "could not re-open the output file \"%s\": %m" +msgstr "kunde inte öppna om utdatafilen \"%s\": %m" -#: pg_dumpall.c:2036 +#: pg_dumpall.c:1564 #, c-format -msgid "%s: could not get server version\n" -msgstr "%s: kunde inte hämta serverversionen\n" +msgid "running \"%s\"" +msgstr "kör \"%s\"" -#: pg_dumpall.c:2042 +#: pg_dumpall.c:1755 #, c-format -msgid "%s: could not parse server version \"%s\"\n" -msgstr "%s: kunde inte tolka versionsträngen \"%s\"\n" +msgid "could not connect to database \"%s\": %s" +msgstr "kunde inte ansluta till databasen \"%s\": %s" -#: pg_dumpall.c:2118 pg_dumpall.c:2144 +#: pg_dumpall.c:1785 #, c-format -msgid "%s: executing %s\n" -msgstr "%s: kör %s\n" +msgid "could not get server version" +msgstr "kunde inte hämta serverversionen" -#: pg_dumpall.c:2124 pg_dumpall.c:2150 +#: pg_dumpall.c:1791 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: frÃ¥ga misslyckades: %s" +msgid "could not parse server version \"%s\"" +msgstr "kunde inte tolka versionsträngen \"%s\"" -#: pg_dumpall.c:2126 pg_dumpall.c:2152 +#: pg_dumpall.c:1863 pg_dumpall.c:1886 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: frÃ¥gan var: %s\n" +msgid "executing %s" +msgstr "kör: %s" -#: pg_restore.c:309 +#: pg_restore.c:314 #, c-format -msgid "%s: options -d/--dbname and -f/--file cannot be used together\n" -msgstr "%s: flaggorna -d/--dbname och -f/--file kan inte användas ihop\n" +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "en av flaggorna -d/--dbname och -f/--file mÃ¥ste anges" -#: pg_restore.c:320 +#: pg_restore.c:323 #, c-format -msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" -msgstr "%s: flaggorna -s/--schema-only och -a/--data-only kan inte användas ihop\n" +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "flaggorna -d/--dbname och -f/--file kan inte användas ihop" -#: pg_restore.c:327 +#: pg_restore.c:349 #, c-format -msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" -msgstr "%s: flaggorna -c/--clean och -a/--data-only kan inte användas ihop\n" +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "flaggorna -C/--create och -1/--single-transaction kan inte användas tillsammans" -#: pg_restore.c:334 +#: pg_restore.c:363 #, c-format -msgid "%s: invalid number of parallel jobs\n" -msgstr "%s: ogiltigt antal parallella job\n" +msgid "maximum number of parallel jobs is %d" +msgstr "maximalt antal parallella job är %d" -#: pg_restore.c:342 +#: pg_restore.c:372 #, c-format -msgid "%s: maximum number of parallel jobs is %d\n" -msgstr "%s: maximalt antal parallella job är %d\n" +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "kan inte ange bÃ¥de --single-transaction och multipla job" -#: pg_restore.c:351 +#: pg_restore.c:414 #, c-format -msgid "%s: cannot specify both --single-transaction and multiple jobs\n" -msgstr "%s: kan inte ange bÃ¥de --single-transaction och multipla job\n" +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "okänt arkivformat \"%s\"; vänligen ange \"c\", \"d\" eller \"t\"" -#: pg_restore.c:394 -#, c-format -msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"\n" -msgstr "okänt arkivformat \"%s\"; vänligen ange \"c\", \"d\" eller \"t\"\n" - -#: pg_restore.c:434 +#: pg_restore.c:454 #, c-format -msgid "WARNING: errors ignored on restore: %d\n" -msgstr "VARNING: fel ignorerade vid Ã¥terställande: %d\n" +msgid "errors ignored on restore: %d" +msgstr "fel ignorerade vid Ã¥terställande: %d" -#: pg_restore.c:448 +#: pg_restore.c:467 #, c-format msgid "" "%s restores a PostgreSQL database from an archive created by pg_dump.\n" @@ -2472,47 +2432,47 @@ msgstr "" "%s Ã¥terställer en PostgreSQL-databas frÃ¥n ett arkiv skapat av pg_dump.\n" "\n" -#: pg_restore.c:450 +#: pg_restore.c:469 #, c-format msgid " %s [OPTION]... [FILE]\n" msgstr " %s [FLAGGA]... [FIL]\n" -#: pg_restore.c:453 +#: pg_restore.c:472 #, c-format msgid " -d, --dbname=NAME connect to database name\n" msgstr " -d, --dbname=NAMN koppla upp med databasnamn\n" -#: pg_restore.c:454 +#: pg_restore.c:473 #, c-format -msgid " -f, --file=FILENAME output file name\n" -msgstr " -f, --file=FILNAMN utdatafilnamn\n" +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=FILNAMN utdatafilnamn (- för stdout)\n" -#: pg_restore.c:455 +#: pg_restore.c:474 #, c-format msgid " -F, --format=c|d|t backup file format (should be automatic)\n" msgstr " -F, --format=c|d|t backupens filformat (bör ske automatiskt)\n" -#: pg_restore.c:456 +#: pg_restore.c:475 #, c-format msgid " -l, --list print summarized TOC of the archive\n" msgstr " -l, --list skriv ut summerad TOC för arkivet\n" -#: pg_restore.c:457 +#: pg_restore.c:476 #, c-format msgid " -v, --verbose verbose mode\n" msgstr " -v, --verbose visa mer information\n" -#: pg_restore.c:458 +#: pg_restore.c:477 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_restore.c:459 +#: pg_restore.c:478 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: pg_restore.c:461 +#: pg_restore.c:480 #, c-format msgid "" "\n" @@ -2521,32 +2481,32 @@ msgstr "" "\n" "Flaggor som styr Ã¥terställning:\n" -#: pg_restore.c:462 +#: pg_restore.c:481 #, c-format msgid " -a, --data-only restore only the data, no schema\n" msgstr " -a, --data-only Ã¥terställ bara data, inte scheman\n" -#: pg_restore.c:464 +#: pg_restore.c:483 #, c-format msgid " -C, --create create the target database\n" msgstr " -C, --create skapa mÃ¥ldatabasen\n" -#: pg_restore.c:465 +#: pg_restore.c:484 #, c-format msgid " -e, --exit-on-error exit on error, default is to continue\n" msgstr " -e, --exit-on-error avsluta vid fel, standard är att fortsätta\n" -#: pg_restore.c:466 +#: pg_restore.c:485 #, c-format msgid " -I, --index=NAME restore named index\n" msgstr " -I, --index=NAMN Ã¥terställ namngivet index\n" -#: pg_restore.c:467 +#: pg_restore.c:486 #, c-format msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" msgstr " -j, --jobs=NUM använda sÃ¥ här mÃ¥nga parallella job för Ã¥terställning\n" -#: pg_restore.c:468 +#: pg_restore.c:487 #, c-format msgid "" " -L, --use-list=FILENAME use table of contents from this file for\n" @@ -2555,57 +2515,62 @@ msgstr "" " -L, --use-list=FILNAMN använd innehÃ¥llsförteckning frÃ¥n denna fil för\n" " att välja/sortera utdata\n" -#: pg_restore.c:470 +#: pg_restore.c:489 #, c-format msgid " -n, --schema=NAME restore only objects in this schema\n" msgstr " -n, --schema=NAMN Ã¥terställ enbart objekt i detta schema\n" -#: pg_restore.c:471 +#: pg_restore.c:490 #, c-format msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" msgstr " -N, --exclude-schema=NAMN Ã¥terställ inte objekt i detta schema\n" -#: pg_restore.c:473 +#: pg_restore.c:492 #, c-format msgid " -P, --function=NAME(args) restore named function\n" msgstr " -P, --function=NAMN(arg) Ã¥terställ namngiven funktion\n" -#: pg_restore.c:474 +#: pg_restore.c:493 #, c-format msgid " -s, --schema-only restore only the schema, no data\n" msgstr " -s, --schema-only Ã¥terställ bara scheman, inte data\n" -#: pg_restore.c:475 +#: pg_restore.c:494 #, c-format msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" msgstr " -S, --superuser=NAMN superanvändarens namn för att slÃ¥ av utlösare\n" -#: pg_restore.c:476 +#: pg_restore.c:495 #, c-format msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" msgstr " -t, --table=NAMN Ã¥terställ namngiven relation (tabell, vy, osv.)\n" -#: pg_restore.c:477 +#: pg_restore.c:496 #, c-format msgid " -T, --trigger=NAME restore named trigger\n" msgstr " -T, --trigger=NAMN Ã¥terställ namngiven utlösare\n" -#: pg_restore.c:478 +#: pg_restore.c:497 #, c-format msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" msgstr " -x, --no-privileges Ã¥terställ inte Ã¥tkomsträttigheter (grant/revoke)\n" -#: pg_restore.c:479 +#: pg_restore.c:498 #, c-format msgid " -1, --single-transaction restore as a single transaction\n" msgstr " -1, --single-transaction Ã¥terställ i en enda transaktion\n" -#: pg_restore.c:481 +#: pg_restore.c:500 #, c-format msgid " --enable-row-security enable row security\n" msgstr " --enable-row-security aktivera radsäkerhet\n" -#: pg_restore.c:483 +#: pg_restore.c:502 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments Ã¥terställ inte kommentarer\n" + +#: pg_restore.c:503 #, c-format msgid "" " --no-data-for-failed-tables do not restore data of tables that could not be\n" @@ -2614,48 +2579,48 @@ msgstr "" " --no-data-for-failed-tables Ã¥terställ inte data för tabeller som\n" " inte kunde skapas\n" -#: pg_restore.c:485 +#: pg_restore.c:505 #, c-format msgid " --no-publications do not restore publications\n" msgstr " --no-publications Ã¥terställ inte publiceringar\n" -#: pg_restore.c:486 +#: pg_restore.c:506 #, c-format msgid " --no-security-labels do not restore security labels\n" msgstr " --no-security-labels Ã¥terställ inte säkerhetsetiketter\n" -#: pg_restore.c:487 +#: pg_restore.c:507 #, c-format msgid " --no-subscriptions do not restore subscriptions\n" msgstr " --no-subscriptions Ã¥terställ inte prenumerationer\n" -#: pg_restore.c:488 +#: pg_restore.c:508 #, c-format msgid " --no-tablespaces do not restore tablespace assignments\n" msgstr " --no-tablespaces Ã¥terställ inte användning av tabellutymmen\n" -#: pg_restore.c:489 +#: pg_restore.c:509 #, c-format msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" msgstr " --section=SEKTION Ã¥terställ namngiven sektion (pre-data, data eller post-data)\n" -#: pg_restore.c:502 +#: pg_restore.c:522 #, c-format msgid " --role=ROLENAME do SET ROLE before restore\n" msgstr " --role=ROLENAME gör SET ROLE innan Ã¥terställning\n" -#: pg_restore.c:504 +#: pg_restore.c:524 #, c-format msgid "" "\n" -"The options -I, -n, -P, -t, -T, and --section can be combined and specified\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" "multiple times to select multiple objects.\n" msgstr "" "\n" -"Flaggorna -I, -n, -P, -t, -T och --section kan kombineras och anges\n" +"Flaggorna -I, -n, -N, -P, -t, -T och --section kan kombineras och anges\n" "mÃ¥nga gÃ¥nger för att välja flera objekt.\n" -#: pg_restore.c:507 +#: pg_restore.c:527 #, c-format msgid "" "\n" @@ -2666,255 +2631,155 @@ msgstr "" "Om inget indatafilnamn är angivet, sÃ¥ kommer standard in att användas.\n" "\n" -#~ msgid "" -#~ " --disable-dollar-quoting\n" -#~ " disable dollar quoting, use SQL standard quoting\n" -#~ msgstr " -x, --no-privileges dumpa inte rättigheter (grant/revoke)\n" - -#~ msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" -#~ msgstr " -x, --no-privileges dumpa inte rättigheter (grant/revoke)\n" - -#~ msgid " -s, --schema-only dump only the schema, no data\n" -#~ msgstr " -s, --schema-only dumpa bara scheman, inte data\n" - -#~ msgid " -o, --oids include OIDs in dump\n" -#~ msgstr " -o, --oids inkludera OID:er i dumpning\n" - -#~ msgid " -D, --column-inserts dump data as INSERT commands with column names\n" -#~ msgstr " -D, --column-inserts dumpa data som INSERT med kolumnnamn\n" - -#~ msgid " -d, --inserts dump data as INSERT, rather than COPY, commands\n" -#~ msgstr " -d, --inserts dumpa data som INSERT, istället för COPY\n" - -#~ msgid " -a, --data-only dump only the data, not the schema\n" -#~ msgstr " -a, --data-only dumpa bara data, inte schema\n" - -#~ msgid "" -#~ " -i, --ignore-version proceed even when server version mismatches\n" -#~ " pg_dumpall version\n" -#~ msgstr "" -#~ " -i, --ignore-version fortsätt även när serverns version inte är\n" -#~ " samma som pg_dumpall-versionen\n" - -#~ msgid "" -#~ " --use-set-session-authorization\n" -#~ " use SESSION AUTHORIZATION commands instead of\n" -#~ " OWNER TO commands\n" -#~ msgstr "" -#~ " --use-set-session-authorization\n" -#~ " använd kommandot SESSION AUTHORIZATION istället för\n" -#~ " OWNER TO\n" - -#~ msgid " -c, --clean clean (drop) schema prior to create\n" -#~ msgstr " -c, --clean nollställ (drop) schema innan skapande\n" - -#~ msgid " -i, --ignore-version proceed even when server version mismatches\n" -#~ msgstr " -i, --ignore-version fortsätt även när versionerna inte stämmer\n" - -#~ msgid "requested %d bytes, got %d from lookahead and %d from file\n" -#~ msgstr "efterfrÃ¥gade %d tecken, fick %d frÃ¥n lookahead och %d frÃ¥n filen\n" - -#~ msgid "%s: no result from server\n" -#~ msgstr "%s: inget resultat frÃ¥n servern\n" - -#~ msgid "aborting because of version mismatch (Use the -i option to proceed anyway.)\n" -#~ msgstr "avbryter pÃ¥ grund av att versionerna inte matchar (använd flaggan -i för att fortsätta ändÃ¥.)\n" - -#~ msgid "archive format is %d\n" -#~ msgstr "arkivformat är %d\n" - -#~ msgid "read %lu bytes into lookahead buffer\n" -#~ msgstr "läste %lu tecken in i lookahead-bufferten\n" - -#~ msgid "expected %d triggers on table \"%s\" but found %d\n" -#~ msgstr "förväntade %d utlösare pÃ¥ tabell \"%s\" men hittade %d\n" - -#~ msgid "" -#~ " -S, --superuser=NAME specify the superuser user name to use in\n" -#~ " plain text format\n" -#~ msgstr "" -#~ " -S, --superuser=NAMN ange superanvändarens användarnamn för\n" -#~ " användning i textformat\n" - -#~ msgid " -c, --clean clean (drop) schema prior to create\n" -#~ msgstr " -c, --clean nollställ (drop) schema innan skapande\n" - -#~ msgid "" -#~ " -i, --ignore-version proceed even when server version mismatches\n" -#~ " pg_dump version\n" -#~ msgstr "" -#~ " -i, --ignore-version fortsätt även när serverns version inte är\n" -#~ " samma som pg_dump-versionen\n" - -#~ msgid "User name: " -#~ msgstr "Användarnamn: " - -#~ msgid "compression support is disabled in this format\n" -#~ msgstr "stöd för komprimering är avstängt för detta format\n" +#~ msgid "could not identify current directory: %s" +#~ msgstr "kunde inte identifiera aktuell katalog: %s" -#~ msgid "dumping a specific TOC data block out of order is not supported without ID on this input stream (fseek required)\n" -#~ msgstr "" -#~ "dumpning av ett specifikt TOC-datablock utanför normal skrivordning stöds inte\n" -#~ "utan ett ID för denna indataström (fseek krävs)\n" +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" -#~ msgid "no label definitions found for enum ID %u\n" -#~ msgstr "inga etikettsdefinitioner hittades för enum med ID %u\n" +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" -#~ msgid "saving large object comments\n" -#~ msgstr "sparar kommentar för stora objekt\n" +#~ msgid "pclose failed: %s" +#~ msgstr "pclose misslyckades: %s" -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "kunde inte byta katalog till \"%s\"" +#~ msgid "child process was terminated by signal %s" +#~ msgstr "barnprocess terminerades av signal %s" -#~ msgid "%s: could not parse version \"%s\"\n" -#~ msgstr "%s: kunde inte tolka versionen \"%s\"\n" +#~ msgid "child process was terminated by signal %d" +#~ msgstr "barnprocess terminerades av signal %d" -#~ msgid "%s: out of memory\n" -#~ msgstr "%s: slut pÃ¥ minne\n" +#~ msgid "compress_io" +#~ msgstr "compress_io" -#, fuzzy -#~ msgid "" -#~ " --use-set-session-authorization\n" -#~ " use SET SESSION AUTHORIZATION commands instead of\n" -#~ " ALTER OWNER commands to set ownership\n" -#~ msgstr "" -#~ " --use-set-session-authorization\n" -#~ " använd kommandot SESSION AUTHORIZATION istället\n" -#~ " för ALTER OWNER för att sätta ägare\n" +#~ msgid "parallel archiver" +#~ msgstr "parallell arkiverare" -#~ msgid " --disable-triggers disable triggers during data-only restore\n" -#~ msgstr " --disable-triggers slÃ¥ av utlösare vid Ã¥terställning av enbart data\n" +#~ msgid "select() failed: %s\n" +#~ msgstr "select() misslyckades: %s\n" -#~ msgid " -O, --no-owner skip restoration of object ownership\n" -#~ msgstr " -O, --no-owner Ã¥terställ inte objektägare\n" +#~ msgid "archiver" +#~ msgstr "arkiverare" -#, fuzzy -#~ msgid " -c, --clean clean (drop) database objects before recreating\n" -#~ msgstr " -c, --clean nollställ (drop) databaser innan skapande\n" +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "-C och -1 är inkompatibla flaggor\n" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version visa versionsinformation och avsluta sedan\n" +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "försöker lista ut arkivformat\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help visa denna hjälp och avsluta sedan\n" +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "allokerar AH för %s, format %d\n" -#~ msgid "mismatch in actual vs. predicted file position (%s vs. %s)\n" -#~ msgstr "verklig jämfört med förväntad filposition matchar inte (%s mot %s)\n" +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "läste TOC-post %d (ID %d) för %s %s\n" -#~ msgid "could not output padding at end of tar member\n" -#~ msgstr "kunde inte skriva utfyllnad i slutet av tar-medlem\n" +#~ msgid "could not set default_with_oids: %s" +#~ msgstr "kunde inte sätta default_with_oids: %s" -#~ msgid "archive member too large for tar format\n" -#~ msgstr "arkivdel för stor för formatet tar\n" +#~ msgid "could not set search_path to \"%s\": %s" +#~ msgstr "kunde inte sätta search_path till \"%s\": %s" -#~ msgid "could not write null block at end of tar archive\n" -#~ msgstr "kunde inte skriva null-block i slutet pÃ¥ tar-arkivet\n" +#~ msgid "could not set default_tablespace to %s: %s" +#~ msgstr "kunde inte sätta default_tablespace till %s: %s" -#~ msgid "restoring large object OID %u\n" -#~ msgstr "Ã¥terställer stort objekt OID %u\n" +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "gÃ¥r in i restore_toc_entries_prefork\n" -#~ msgid "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n" -#~ msgstr "felaktig COPY-sats -- kunde inte hitta \"from stdin\" i strängen \"%s\" med början i position %lu\n" +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "gÃ¥r in i restore_toc_entries_parallel\n" -#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" -#~ msgstr "felaktig COPY-sats -- kunde inte hitta \"copy\" i strängen \"%s\"\n" +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "gÃ¥r in i restore_toc_entries_postfork\n" -#~ msgid "could not close large object file\n" -#~ msgstr "kunde inte stänga filen för stort objekt\n" +#~ msgid "no item ready\n" +#~ msgstr "inget objekt är redo\n" -#~ msgid "could not open large object TOC for output: %s\n" -#~ msgstr "kunde inte öppna TOC-filen för stora objekt för utmatning: %s\n" +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "överför beroende %d -> %d till %d\n" -#~ msgid "could not write byte\n" -#~ msgstr "kunde inte skriva tecken\n" +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "reducerar beroenden för %d\n" -#~ msgid "could not open large object TOC for input: %s\n" -#~ msgstr "kunde inte öppna TOC-filen för stora objekt: %s\n" +#~ msgid "custom archiver" +#~ msgstr "egen arkiverare" -#~ msgid "could not close data file after reading\n" -#~ msgstr "kan inte stänga datafil efter läsning\n" +#~ msgid "archiver (db)" +#~ msgstr "arkiverare (db)" -#~ msgid "" -#~ "WARNING:\n" -#~ " This format is for demonstration purposes; it is not intended for\n" -#~ " normal use. Files will be written in the current working directory.\n" -#~ msgstr "" -#~ "VARNING:\n" -#~ " Detta format är för demonstationsanvändning; det är inte tänkt\n" -#~ " för normal användning. Filer skrivs i aktuell katalog.\n" +#~ msgid "%s: %s Command was: %s\n" +#~ msgstr "%s: %s Kommandot var: %s\n" -#~ msgid "file archiver" -#~ msgstr "filarkiverare" +#~ msgid "COPY failed for table \"%s\": %s" +#~ msgstr "COPY misslyckades för tabell \"%s\": %s" -#~ msgid "could not write byte: %s\n" -#~ msgstr "kunde inte skriva tecken: %s\n" +#~ msgid "directory archiver" +#~ msgstr "katalogarkiverare" -#~ msgid "unexpected end of file\n" -#~ msgstr "oväntat slut pÃ¥ filen\n" +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "kunde inte läsa katalog \"%s\": %s\n" -#~ msgid "could not write to custom output routine\n" -#~ msgstr "kunde inte skriva till egen utdatarutin\n" +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "kunde inte stänga katalog \"%s\": %s\n" -#~ msgid "-C and -c are incompatible options\n" -#~ msgstr "-C och -c är inkompatibla flaggor\n" +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "kunde inte skapa katalog \"%s\": %s\n" -#~ msgid "cannot duplicate null pointer\n" -#~ msgstr "kan inte duplicera null-pekaren\n" +#~ msgid "tar archiver" +#~ msgstr "tar-arkiverare" -#~ msgid "SQL command failed\n" -#~ msgstr "SQL-kommando misslyckades\n" +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "flyttar frÃ¥n position %s till nästa del vid filposition %s\n" -#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" -#~ msgstr "frÃ¥ga för att hämta data för sekvens \"%s\" returnerade namn \"%s\"\n" +#~ msgid "now at file position %s\n" +#~ msgstr "nu pÃ¥ filposition %s\n" -#~ msgid "found more than one entry for pg_indexes in pg_class\n" -#~ msgstr "hittade mer än en post för pg_indexes i pg_class\n" +#~ msgid "skipping tar member %s\n" +#~ msgstr "hoppar över tar-medlem %s\n" -#~ msgid "could not find entry for pg_indexes in pg_class\n" -#~ msgstr "kunde inte hitta post för pg_indexes i pg_class\n" +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "TOC-objekt %s vid %s (längd %s, kontrollsumma %d)\n" -#~ msgid "found more than one pg_database entry for this database\n" -#~ msgstr "det finns mer än en pg_database-post för denna databas\n" +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" -#~ msgid "missing pg_database entry for this database\n" -#~ msgstr "pg_database-posten för denna databas saknas\n" +#~ msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +#~ msgstr "flaggorna --inserts/--column-inserts och -o/--oids kan inte användas tillsammans\n" -#~ msgid "query returned no rows: %s\n" -#~ msgstr "frÃ¥gan gav inga rader: %s\n" +#~ msgid "(The INSERT command cannot set OIDs.)\n" +#~ msgstr "(Kommandot INSERT kan inte sätta OID:s.)\n" -#, fuzzy -#~ msgid "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n" -#~ msgstr "dumpBlobs(): kunde inte öppna det stora objektet: %s" +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapportera fel till .\n" -#~ msgid "query returned more than one (%d) pg_database entry for database \"%s\"\n" -#~ msgstr "frÃ¥ga har givit mer än en (%d) pg_database-post som resultat för databas \"%s\"\n" +#~ msgid "schema with OID %u does not exist\n" +#~ msgstr "schema med OID %u existerar inte\n" -#~ msgid "missing pg_database entry for database \"%s\"\n" -#~ msgstr "pg_database-post för databas \"%s\" saknas\n" +#~ msgid "WARNING: could not parse reloptions array\n" +#~ msgstr "VARNING: kunde inte parsa arrayen reloptions\n" -#~ msgid "server version must be at least 7.3 to use schema selection switches\n" -#~ msgstr "serverversionen mÃ¥ste vara minst 7.3 för att man skall kunna använda schemavalflaggorna\n" +#~ msgid "sorter" +#~ msgstr "sorterare" -#~ msgid "*** aborted because of error\n" -#~ msgstr "*** avbruten pÃ¥ grund av fel\n" +#~ msgid "%s: option --if-exists requires option -c/--clean\n" +#~ msgstr "%s: flaggan --if-exists kräver flaggan -c/--clean\n" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version visa versionsinformation, avsluta sedan\n" +#~ msgid "%s: invalid client encoding \"%s\" specified\n" +#~ msgstr "%s: ogiltig klientteckenkodning \"%s\" angiven\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help visa denna hjälp, avsluta sedan\n" +#~ msgid "%s: executing %s\n" +#~ msgstr "%s: kör %s\n" -#~ msgid "could not parse version string \"%s\"\n" -#~ msgstr "kunde inte tolka versionsträngen \"%s\"\n" +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: frÃ¥ga misslyckades: %s" -#~ msgid "could not open output file \"%s\" for writing\n" -#~ msgstr "kunde inte öppna utfil \"%s\" för skrivning\n" +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: frÃ¥gan var: %s\n" -#~ msgid "%s: invalid -X option -- %s\n" -#~ msgstr "%s: ogiltig \"-X\"-flagga -- %s\n" +#~ msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +#~ msgstr "%s: flaggorna -s/--schema-only och -a/--data-only kan inte användas ihop\n" -#~ msgid "setting owner and privileges for %s \"%s\"\n" -#~ msgstr "sätter ägare och rättigheter för %s \"%s\"\n" +#~ msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +#~ msgstr "%s: flaggorna -c/--clean och -a/--data-only kan inte användas ihop\n" -#~ msgid "setting owner and privileges for %s \"%s.%s\"\n" -#~ msgstr "sätter ägare och rättigheter för %s \"%s.%s\"\n" +#~ msgid "%s: invalid number of parallel jobs\n" +#~ msgstr "%s: ogiltigt antal parallella job\n" diff --git a/src/bin/pg_dump/po/tr.po b/src/bin/pg_dump/po/tr.po new file mode 100644 index 00000000000..7ec7f5de791 --- /dev/null +++ b/src/bin/pg_dump/po/tr.po @@ -0,0 +1,3070 @@ +# translation of pg_dump-tr.po to Turkish +# Devrim GUNDUZ , 2004, 2006, 2007. +# Nicolai TUFAR 2004, 2005, 2006, 2007. +# Abdullah Gülner , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_dump-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:47+0000\n" +"PO-Revision-Date: 2019-05-31 15:16+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: /home/ntufar/pg/pgsql/src/bin/pg_dump\n" +"X-Poedit-SearchPath-0: C:/pgsql/src/bin/pg_dump\n" +"X-Poedit-SearchPath-1: /home/ntufar/pg/pgsql/src/backend\n" +"X-Poedit-SearchPath-2: c:/pgsql/src/backend\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "geçerli dizin tespit edilemedi: %m" + +#: ../../common/exec.c:157 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "geçersiz ikili (binary) \"%s\"" + +#: ../../common/exec.c:207 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili (binary) dosyası okunamadı" + +#: ../../common/exec.c:215 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "\"%s\" çalıştırmak için bulunamadı" + +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %m" + +#: ../../common/exec.c:288 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" okuma hatası: %m" + +#: ../../common/exec.c:541 +#, c-format +msgid "pclose failed: %m" +msgstr "pclose baÅŸarısız oldu: %m" + +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +msgid "out of memory" +msgstr "yetersiz bellek" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "yetersiz bellek\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer çoÄŸaltılamıyor (duplicate) (iç hata)\n" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "komut çalıştırılabilir deÄŸil" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "komut bulunamadı" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "alt süreç %d çıkış koduyla sonuçlandırılmıştır" + +#: ../../common/wait_error.c:62 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "alt süreç 0x%X exception tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:66 +#, c-format +msgid "child process was terminated by signal %d: %s" +msgstr "alt süreç %d sinyali tarafından sonlandırılmıştır :%s" + +#: ../../common/wait_error.c:72 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "alt süreç %d bilinmeyen durumu ile sonlandırılmıştır" + +#: common.c:124 +#, c-format +msgid "reading extensions" +msgstr "uzantılar okunuyor" + +#: common.c:128 +#, c-format +msgid "identifying extension members" +msgstr "uzantı üyeleri belirleniyor" + +#: common.c:131 +#, c-format +msgid "reading schemas" +msgstr "ÅŸemalar okunuyor" + +#: common.c:141 +#, c-format +msgid "reading user-defined tables" +msgstr "kullanıcı tanımlı tablolar okunuyor" + +#: common.c:148 +#, c-format +msgid "reading user-defined functions" +msgstr "kullanıcı tanımlı fonksiyonlar okunuyor" + +#: common.c:153 +#, c-format +msgid "reading user-defined types" +msgstr "kullanıcı tanımlı tipler okunuyor" + +#: common.c:158 +#, c-format +msgid "reading procedural languages" +msgstr "yordamsal diller okunuyor" + +#: common.c:161 +#, c-format +msgid "reading user-defined aggregate functions" +msgstr "kullanıcı-tanımlı aggregate fonksiyonlar okunuyor" + +#: common.c:164 +#, c-format +msgid "reading user-defined operators" +msgstr "kullanıcı tanımlı operatörler okunuyor" + +#: common.c:168 +#, c-format +msgid "reading user-defined access methods" +msgstr "kullanıcı tanımlı eriÅŸim yöntemleri okunuyor" + +#: common.c:171 +#, c-format +msgid "reading user-defined operator classes" +msgstr "kullanıcı-tanımlı operatör sınıfları okunuyor" + +#: common.c:174 +#, c-format +msgid "reading user-defined operator families" +msgstr "kullanıcı tanımlı operatör aileleri okunuyor" + +#: common.c:177 +#, c-format +msgid "reading user-defined text search parsers" +msgstr "kullanıcı tanımlı metin arama ayrıştırıcıları okunuyor" + +#: common.c:180 +#, c-format +msgid "reading user-defined text search templates" +msgstr "kullanıcı tanımlı metin arama ÅŸablonları okunuyor" + +#: common.c:183 +#, c-format +msgid "reading user-defined text search dictionaries" +msgstr "kullanıcı-tanımlı metin arama sözlükleri okunuyor" + +#: common.c:186 +#, c-format +msgid "reading user-defined text search configurations" +msgstr "kullanıcı-tanımlı metin arama yapılandırmaları okunuyor" + +#: common.c:189 +#, c-format +msgid "reading user-defined foreign-data wrappers" +msgstr "kullanıcı tanımlı foreign-data wrapperlar okunuyor" + +#: common.c:192 +#, c-format +msgid "reading user-defined foreign servers" +msgstr "kullanıcı tanımlı foreign sunucular okunuyor" + +#: common.c:195 +#, c-format +msgid "reading default privileges" +msgstr "öntanımlı yetkiler okunuyor" + +#: common.c:198 +#, c-format +msgid "reading user-defined collations" +msgstr "kullanıcı tanımlı collation'lar okunuyor" + +#: common.c:202 +#, c-format +msgid "reading user-defined conversions" +msgstr "kullanıcı tanımlı dönüşümler (conversion) okunuyor" + +#: common.c:205 +#, c-format +msgid "reading type casts" +msgstr "type cast'lar okunuyor" + +#: common.c:208 +#, c-format +msgid "reading transforms" +msgstr "dönüşümler (transform) okunuyor" + +#: common.c:211 +#, c-format +msgid "reading table inheritance information" +msgstr "tablo kalıtım (inheritance) bilgisi okunuyor" + +#: common.c:214 +#, c-format +msgid "reading event triggers" +msgstr "olay tetikleyicileri okunuyor" + +#: common.c:218 +#, c-format +msgid "finding extension tables" +msgstr "uzantı tabloları bulunuyor" + +#: common.c:222 +#, c-format +msgid "finding inheritance relationships" +msgstr "kalıtım (inheritance) iliÅŸkileri bulunuyor" + +#: common.c:225 +#, c-format +msgid "reading column info for interesting tables" +msgstr "ilgili tabloların sütun bilgisi okunuyor" + +#: common.c:228 +#, c-format +msgid "flagging inherited columns in subtables" +msgstr "alt tablolarda inherited sütunlar iÅŸaretleniyor" + +#: common.c:231 +#, c-format +msgid "reading indexes" +msgstr "indeksler okunuyor" + +#: common.c:234 +#, c-format +msgid "flagging indexes in partitioned tables" +msgstr "bölümlenmiÅŸ tablolardaki indeksler iÅŸaretleniyor" + +#: common.c:237 +#, c-format +msgid "reading extended statistics" +msgstr "geniÅŸletilmiÅŸ istatistikler okunuyor" + +#: common.c:240 +#, c-format +msgid "reading constraints" +msgstr "bütünlük kısıtlamaları okunuyor" + +#: common.c:243 +#, c-format +msgid "reading triggers" +msgstr "tetikleyiciler okunuyor" + +#: common.c:246 +#, c-format +msgid "reading rewrite rules" +msgstr "rewrite kuralları okunuyor" + +#: common.c:249 +#, c-format +msgid "reading policies" +msgstr "ilkeler (policy) okunuyor" + +#: common.c:252 +#, c-format +msgid "reading publications" +msgstr "yayınlar (publication) okunuyor" + +#: common.c:255 +#, c-format +msgid "reading publication membership" +msgstr "yayın üyeliÄŸi okunuyor" + +#: common.c:258 +#, c-format +msgid "reading subscriptions" +msgstr "abonelikler okunuyor" + +#: common.c:1024 +#, c-format +msgid "failed sanity check, parent OID %u of table \"%s\" (OID %u) not found" +msgstr "tutarlılık kontrolü baÅŸarısız, \"%2$s\" tablosunun (OID %3$u) üst OIDsi %1$u bulunamadı" + +#: common.c:1066 +#, c-format +msgid "could not parse numeric array \"%s\": too many numbers" +msgstr "\"%s\" numerik dizisi ayrıştırılamadı: çok fazla sayı" + +#: common.c:1081 +#, c-format +msgid "could not parse numeric array \"%s\": invalid character in number" +msgstr "\"%s\" numerik dizisi ayrıştırılamadı: sayıda geçersiz karakter" + +#: compress_io.c:111 +#, c-format +msgid "invalid compression code: %d" +msgstr "geçersiz sıkıştırma kodu: %d" + +#: compress_io.c:134 compress_io.c:170 compress_io.c:188 compress_io.c:508 +#: compress_io.c:551 +#, c-format +msgid "not built with zlib support" +msgstr "zlib desteÄŸiyle oluÅŸturulmamış" + +#: compress_io.c:237 compress_io.c:336 +#, c-format +msgid "could not initialize compression library: %s" +msgstr "sıkıştırma kütüphanesi ilklendirilemedi: %s" + +#: compress_io.c:257 +#, c-format +msgid "could not close compression stream: %s" +msgstr "sıkıştırma akımı kapatılamadı: %s" + +#: compress_io.c:274 +#, c-format +msgid "could not compress data: %s" +msgstr "veri sıkıştırılamadı: %s" + +#: compress_io.c:352 compress_io.c:367 +#, c-format +msgid "could not uncompress data: %s" +msgstr "sıkıştırılmış veri açılamadı: %s" + +#: compress_io.c:374 +#, c-format +msgid "could not close compression library: %s" +msgstr "sıkıştırma kütüphanesi kapatılamadı: %s" + +#: compress_io.c:588 compress_io.c:625 pg_backup_tar.c:555 pg_backup_tar.c:558 +#, c-format +msgid "could not read from input file: %s" +msgstr "girdi dosyası okuma hatası: %s" + +#: compress_io.c:627 pg_backup_custom.c:578 pg_backup_directory.c:539 +#: pg_backup_tar.c:795 pg_backup_tar.c:818 +#, c-format +msgid "could not read from input file: end of file" +msgstr "girdi dosyası okuma hatası: dosya sonu" + +#: parallel.c:263 +#, c-format +msgid "WSAStartup failed: %d" +msgstr "WSAStartup baÅŸarısız: %d" + +#: parallel.c:968 +#, c-format +msgid "could not create communication channels: %m" +msgstr "iletiÅŸim kanalları oluÅŸturulamadı: %m" + +#: parallel.c:1031 +#, c-format +msgid "could not create worker process: %m" +msgstr "işçi süreci yaratılamadı: %m" + +#: parallel.c:1160 +#, c-format +msgid "unrecognized command received from master: \"%s\"" +msgstr "ana sunucudan (master) bilinmeyen komut alındı: \"%s\"" + +#: parallel.c:1203 parallel.c:1441 +#, c-format +msgid "invalid message received from worker: \"%s\"" +msgstr "alt süreçten (worker) geçersiz mesaj alındı: \"%s\"" + +#: parallel.c:1335 +#, c-format +msgid "" +"could not obtain lock on relation \"%s\"\n" +"This usually means that someone requested an ACCESS EXCLUSIVE lock on the table after the pg_dump parent process had gotten the initial ACCESS SHARE lock on the table." +msgstr "" +"\"%s\" nesnesi üzerinde kilit alınamadı\n" +"Bu genellikle pg_dump ana süreci tablo üzerinde baÅŸta ACCESS SHARE kilidi aldıktan sonra baÅŸka birinin tablo üzerinde ACCESS EXCLUSIVE kilidi talep ettiÄŸi anlamına gelir." + +#: parallel.c:1424 +#, c-format +msgid "a worker process died unexpectedly" +msgstr "alt süreç beklenmeyen biçimde sonlandı" + +#: parallel.c:1546 parallel.c:1662 +#, c-format +msgid "could not write to the communication channel: %m" +msgstr "iletiÅŸim kanalına yazma baÅŸarısız: %m" + +#: parallel.c:1623 +#, c-format +msgid "select() failed: %m" +msgstr "select() baÅŸarısız oldu: %m" + +#: parallel.c:1746 +#, c-format +msgid "pgpipe: could not create socket: error code %d" +msgstr "pgpipe: soket oluÅŸturulamadı: hata kodu %d" + +#: parallel.c:1757 +#, c-format +msgid "pgpipe: could not bind: error code %d" +msgstr "pgpipe: baÄŸlanamadı (bind): hata kodu %d" + +#: parallel.c:1764 +#, c-format +msgid "pgpipe: could not listen: error code %d" +msgstr "pgpipe: dinleyemedi: hata kodu %d" + +#: parallel.c:1771 +#, c-format +msgid "pgpipe: getsockname() failed: error code %d" +msgstr "pgpipe: getsockname() baÅŸarısız oldu: hata kodu %d" + +#: parallel.c:1782 +#, c-format +msgid "pgpipe: could not create second socket: error code %d" +msgstr "pgpipe: ikinci soket oluÅŸturulamadı: hata kodu %d" + +#: parallel.c:1791 +#, c-format +msgid "pgpipe: could not connect socket: error code %d" +msgstr "pgpipe: soket baÄŸlanamadı: hata kodu %d" + +#: parallel.c:1800 +#, c-format +msgid "pgpipe: could not accept connection: error code %d" +msgstr "pgpipe: baÄŸlantı kabul edemedi: hata kodu %d" + +#: pg_backup_archiver.c:273 pg_backup_archiver.c:1596 +#, c-format +msgid "could not close output file: %m" +msgstr "çıktı dosyası kapatılamadı: %m" + +#: pg_backup_archiver.c:317 pg_backup_archiver.c:321 +#, c-format +msgid "archive items not in correct section order" +msgstr "arÅŸiv kalemleri doÄŸru bölüm sırasında deÄŸil" + +#: pg_backup_archiver.c:327 +#, c-format +msgid "unexpected section code %d" +msgstr "beklenmeyen bölüm kodu %d" + +#: pg_backup_archiver.c:364 +#, c-format +msgid "parallel restore is not supported with this archive file format" +msgstr "paralel geri yükleme bu arÅŸiv dosya biçimiyle desteklenmiyor" + +#: pg_backup_archiver.c:368 +#, c-format +msgid "parallel restore is not supported with archives made by pre-8.0 pg_dump" +msgstr "paralel geri yükleme özelliÄŸi 8.0 öncesi pg_dump ile yapılan arÅŸivlerle desteklenmemektedir" + +#: pg_backup_archiver.c:386 +#, c-format +msgid "cannot restore from compressed archive (compression not supported in this installation)" +msgstr "sıkıştırılmış arÅŸivden yükleme baÅŸarısız (bu kurulumda sıkıştırma desteklenmiyor)" + +#: pg_backup_archiver.c:403 +#, c-format +msgid "connecting to database for restore" +msgstr "geri yükleme için veritabanına baÄŸlanılıyor" + +#: pg_backup_archiver.c:405 +#, c-format +msgid "direct database connections are not supported in pre-1.3 archives" +msgstr "1.3 sürüm öncesi arÅŸivlerinde doÄŸrudan veritabanı baÄŸlantıları desteklenmemektedir" + +#: pg_backup_archiver.c:450 +#, c-format +msgid "implied data-only restore" +msgstr "örtük salt veri geri yükleme" + +#: pg_backup_archiver.c:516 +#, c-format +msgid "dropping %s %s" +msgstr "%s %s kaldırılıyor" + +#: pg_backup_archiver.c:611 +#, c-format +msgid "could not find where to insert IF EXISTS in statement \"%s\"" +msgstr "\"%s\" ifadesinde nereye IF EXISTS ekleneceÄŸi bulunamadı" + +#: pg_backup_archiver.c:767 pg_backup_archiver.c:769 +#, c-format +msgid "warning from original dump file: %s" +msgstr "asıl dump dosyasından uyarı: %s" + +#: pg_backup_archiver.c:784 +#, c-format +msgid "creating %s \"%s.%s\"" +msgstr "%s oluÅŸturuluyor \"%s.%s\"" + +#: pg_backup_archiver.c:787 +#, c-format +msgid "creating %s \"%s\"" +msgstr "%s oluÅŸturuluyor \"%s\"" + +#: pg_backup_archiver.c:844 +#, c-format +msgid "connecting to new database \"%s\"" +msgstr "yeni \"%s\" veritabanına baÄŸlanılıyor" + +#: pg_backup_archiver.c:872 +#, c-format +msgid "processing %s" +msgstr "%s iÅŸleniyor" + +#: pg_backup_archiver.c:892 +#, c-format +msgid "processing data for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için veri iÅŸleniyor" + +#: pg_backup_archiver.c:954 +#, c-format +msgid "executing %s %s" +msgstr "%s %s yürütülüyor" + +#: pg_backup_archiver.c:993 +#, c-format +msgid "disabling triggers for %s" +msgstr "%s için tetikleyiciler etkisiz hale getiriliyor" + +#: pg_backup_archiver.c:1019 +#, c-format +msgid "enabling triggers for %s" +msgstr "%s için tetikleyiciler etkinleÅŸtiriliyor" + +#: pg_backup_archiver.c:1047 +#, c-format +msgid "internal error -- WriteData cannot be called outside the context of a DataDumper routine" +msgstr "iç hata -- WriteData, DataDumper yordamının baÄŸlamı dışında çaÄŸrılamaz" + +#: pg_backup_archiver.c:1232 +#, c-format +msgid "large-object output not supported in chosen format" +msgstr "seçilen biçimde large-object çıktısı desteklenmemektedir" + +#: pg_backup_archiver.c:1290 +#, c-format +msgid "restored %d large object" +msgid_plural "restored %d large objects" +msgstr[0] "%d large object geri yüklendi" +msgstr[1] "%d large object geri yüklendi" + +#: pg_backup_archiver.c:1311 pg_backup_tar.c:738 +#, c-format +msgid "restoring large object with OID %u" +msgstr "%u OID'li large-object geri yükleniyor" + +#: pg_backup_archiver.c:1323 +#, c-format +msgid "could not create large object %u: %s" +msgstr "%u large object oluÅŸturulamadı: %s" + +#: pg_backup_archiver.c:1328 pg_dump.c:3463 +#, c-format +msgid "could not open large object %u: %s" +msgstr "%u large object açılamadı: %s" + +#: pg_backup_archiver.c:1385 +#, c-format +msgid "could not open TOC file \"%s\": %m" +msgstr "\"%s\" TOC dosyası açılamadı: %m" + +#: pg_backup_archiver.c:1425 +#, c-format +msgid "line ignored: %s" +msgstr "satır yoksayıldı: %s" + +#: pg_backup_archiver.c:1432 +#, c-format +msgid "could not find entry for ID %d" +msgstr "ID %d için bir girdi bulunamıyor" + +#: pg_backup_archiver.c:1453 pg_backup_directory.c:222 +#: pg_backup_directory.c:587 +#, c-format +msgid "could not close TOC file: %m" +msgstr "TOC dosyası kapatılamıyor: %m" + +#: pg_backup_archiver.c:1568 pg_backup_custom.c:159 pg_backup_directory.c:332 +#: pg_backup_directory.c:574 pg_backup_directory.c:637 +#: pg_backup_directory.c:656 +#, c-format +msgid "could not open output file \"%s\": %m" +msgstr "\"%s\" çıktı dosyası açılamadı: %m" + +#: pg_backup_archiver.c:1570 pg_backup_custom.c:165 +#, c-format +msgid "could not open output file: %m" +msgstr "çıktı dosyası açılamadı: %m" + +#: pg_backup_archiver.c:1663 +#, c-format +msgid "wrote %lu byte of large object data (result = %lu)" +msgid_plural "wrote %lu bytes of large object data (result = %lu)" +msgstr[0] "large object verisinin %lu baytı yazıldı (sonuç = %lu)" +msgstr[1] "large object verisinin %lu baytı yazıldı (sonuç = %lu)" + +#: pg_backup_archiver.c:1668 +#, c-format +msgid "could not write to large object (result: %lu, expected: %lu)" +msgstr "large-object yazılamıyor (sonuç: %lu, beklenen: %lu)" + +#: pg_backup_archiver.c:1760 +#, c-format +msgid "while INITIALIZING:" +msgstr "INITIALIZING sırasında:" + +#: pg_backup_archiver.c:1765 +#, c-format +msgid "while PROCESSING TOC:" +msgstr "PROCESSING TOC sırasında:" + +#: pg_backup_archiver.c:1770 +#, c-format +msgid "while FINALIZING:" +msgstr "FINALIZING sırasında:" + +#: pg_backup_archiver.c:1775 +#, c-format +msgid "from TOC entry %d; %u %u %s %s %s" +msgstr "TOC giriÅŸte hata %d; %u %u %s %s %s" + +#: pg_backup_archiver.c:1851 +#, c-format +msgid "bad dumpId" +msgstr "kötü dumpId" + +#: pg_backup_archiver.c:1872 +#, c-format +msgid "bad table dumpId for TABLE DATA item" +msgstr "TABLE DATA öğesi için kötü tablo dumpId deÄŸeri" + +#: pg_backup_archiver.c:1964 +#, c-format +msgid "unexpected data offset flag %d" +msgstr "beklenmeyen veri konum bayrağı %d" + +#: pg_backup_archiver.c:1977 +#, c-format +msgid "file offset in dump file is too large" +msgstr "dump dosyasında dosya göstergesi çok büyük" + +#: pg_backup_archiver.c:2114 pg_backup_archiver.c:2124 +#, c-format +msgid "directory name too long: \"%s\"" +msgstr "dizin adı çok uzun: \"%s\"" + +#: pg_backup_archiver.c:2132 +#, c-format +msgid "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)" +msgstr "\"%s\" dizini geçerli bir arÅŸiv olarak görünmüyor (\"toc.dat\" bulunamadı)" + +#: pg_backup_archiver.c:2140 pg_backup_custom.c:176 pg_backup_custom.c:760 +#: pg_backup_directory.c:207 pg_backup_directory.c:391 +#, c-format +msgid "could not open input file \"%s\": %m" +msgstr "\"%s\" girdi dosyası açılamadı: %m" + +#: pg_backup_archiver.c:2147 pg_backup_custom.c:182 +#, c-format +msgid "could not open input file: %m" +msgstr "girdi dosyası açılamadı: %m" + +#: pg_backup_archiver.c:2153 +#, c-format +msgid "could not read input file: %m" +msgstr "girdi dosyası okuma hatası: %m" + +#: pg_backup_archiver.c:2155 +#, c-format +msgid "input file is too short (read %lu, expected 5)" +msgstr "girdi dosyası fazla kısa (okunan: %lu, beklenen: 5)" + +#: pg_backup_archiver.c:2240 +#, c-format +msgid "input file appears to be a text format dump. Please use psql." +msgstr "girdi dosyası metin biçiminde bir döküm (dump) gibi görünüyor. Lütfen psql kullanın." + +#: pg_backup_archiver.c:2246 +#, c-format +msgid "input file does not appear to be a valid archive (too short?)" +msgstr "girdi dosyası geçerli bir arÅŸiv gibi görünmüyor (çok kısa?)" + +#: pg_backup_archiver.c:2252 +#, c-format +msgid "input file does not appear to be a valid archive" +msgstr "girdi dosyası geçerli bir arÅŸiv gibi görünmüyor" + +#: pg_backup_archiver.c:2272 +#, c-format +msgid "could not close input file: %m" +msgstr "çıktı dosyası kapatılamadı: %m" + +#: pg_backup_archiver.c:2386 +#, c-format +msgid "unrecognized file format \"%d\"" +msgstr "tanınmayan dosya biçimi: \"%d\"" + +#: pg_backup_archiver.c:2468 pg_backup_archiver.c:4474 +#, c-format +msgid "finished item %d %s %s" +msgstr "%d %s %s öğesi bitirildi" + +#: pg_backup_archiver.c:2472 pg_backup_archiver.c:4487 +#, c-format +msgid "worker process failed: exit code %d" +msgstr "alt süreç baÅŸarısız oldu: çıkış kodu %d" + +#: pg_backup_archiver.c:2592 +#, c-format +msgid "entry ID %d out of range -- perhaps a corrupt TOC" +msgstr "ID %d olan giriÅŸ kapsam dışıdır -- bozuk bir TOC olabilir" + +#: pg_backup_archiver.c:2659 +#, c-format +msgid "restoring tables WITH OIDS is not supported anymore" +msgstr "WITH OIDS ile tanımlanmış tabloların geri yüklenmesi (restore) artık desteklenmemektedir" + +#: pg_backup_archiver.c:2741 +#, c-format +msgid "unrecognized encoding \"%s\"" +msgstr "tanınmayan dil kodlaması \"%s\"" + +#: pg_backup_archiver.c:2746 +#, c-format +msgid "invalid ENCODING item: %s" +msgstr "geçersiz ENCODING öğesi: %s" + +#: pg_backup_archiver.c:2764 +#, c-format +msgid "invalid STDSTRINGS item: %s" +msgstr "geçersiz STDSTRINGS öğesi: %s" + +#: pg_backup_archiver.c:2789 +#, c-format +msgid "schema \"%s\" not found" +msgstr "\"%s\" ÅŸeması bulunamadı" + +#: pg_backup_archiver.c:2796 +#, c-format +msgid "table \"%s\" not found" +msgstr "\"%s\" tablosu bulunamadı" + +#: pg_backup_archiver.c:2803 +#, c-format +msgid "index \"%s\" not found" +msgstr "\"%s\" indeksi bulunamadı" + +#: pg_backup_archiver.c:2810 +#, c-format +msgid "function \"%s\" not found" +msgstr "\"%s\" fonksiyonu bulunamadı" + +#: pg_backup_archiver.c:2817 +#, c-format +msgid "trigger \"%s\" not found" +msgstr "\"%s\" tetikleyicisi bulunamadı" + +#: pg_backup_archiver.c:3196 +#, c-format +msgid "could not set session user to \"%s\": %s" +msgstr "oturum kullanıcısı \"%s\" olarak deÄŸiÅŸtirilemedi: %s" + +#: pg_backup_archiver.c:3533 pg_backup_archiver.c:3690 +#, c-format +msgid "don't know how to set owner for object type \"%s\"" +msgstr "\"%s\" nesne tipi için sahip bilgisinin nasıl ayarlanacağı bilinmiyor" + +#: pg_backup_archiver.c:3794 +#, c-format +msgid "did not find magic string in file header" +msgstr "dosya baÅŸlığında magic string bulunamadı" + +#: pg_backup_archiver.c:3807 +#, c-format +msgid "unsupported version (%d.%d) in file header" +msgstr "dosya baÅŸlığında desteklenmeyen sürüm (%d.%d)" + +#: pg_backup_archiver.c:3812 +#, c-format +msgid "sanity check on integer size (%lu) failed" +msgstr "tamsayı (integer) boyutunda (%lu) tutarlılık kontrolü baÅŸarısız" + +#: pg_backup_archiver.c:3816 +#, c-format +msgid "archive was made on a machine with larger integers, some operations might fail" +msgstr "arÅŸiv daha büyük tam sayılara (integer) sahip platformda oluÅŸturulmuÅŸ, bazı iÅŸlemler baÅŸarısız olabilir" + +#: pg_backup_archiver.c:3826 +#, c-format +msgid "expected format (%d) differs from format found in file (%d)" +msgstr "dosyada bulunan biçim (%2$d) beklenen biçimden (%1$d) farklıdır" + +#: pg_backup_archiver.c:3842 +#, c-format +msgid "archive is compressed, but this installation does not support compression -- no data will be available" +msgstr "arÅŸiv sıkıştırılmış, ancak bu kurulum sıkıştırmayı desteklemiyor -- uygun veri olmayacak" + +#: pg_backup_archiver.c:3860 +#, c-format +msgid "invalid creation date in header" +msgstr "veri baÅŸlığında geçersiz tarih" + +#: pg_backup_archiver.c:3997 +#, c-format +msgid "processing item %d %s %s" +msgstr "%d %s %s öğesi iÅŸleniyor" + +#: pg_backup_archiver.c:4076 +#, c-format +msgid "entering main parallel loop" +msgstr "ana paralel döngüye giriliyor" + +#: pg_backup_archiver.c:4087 +#, c-format +msgid "skipping item %d %s %s" +msgstr "%d %s %s öğesi atlanıyor" + +#: pg_backup_archiver.c:4096 +#, c-format +msgid "launching item %d %s %s" +msgstr "%d %s %s öğesi baÅŸlatılıyor" + +#: pg_backup_archiver.c:4150 +#, c-format +msgid "finished main parallel loop" +msgstr "ana paralel döngü bitti" + +#: pg_backup_archiver.c:4188 +#, c-format +msgid "processing missed item %d %s %s" +msgstr "atlanan %d %s %s öğesi iÅŸleniyor" + +#: pg_backup_archiver.c:4793 +#, c-format +msgid "table \"%s\" could not be created, will not restore its data" +msgstr "\"%s\" tablosu oluÅŸturulamadı, onun verileri yüklenmeyecektir" + +#: pg_backup_custom.c:377 pg_backup_null.c:150 +#, c-format +msgid "invalid OID for large object" +msgstr "large object için geçersiz OID" + +#: pg_backup_custom.c:447 +#, c-format +msgid "unrecognized data block type (%d) while searching archive" +msgstr "arÅŸivde ararken tanınmayan veri blok tipine (%d) rastlandı" + +#: pg_backup_custom.c:458 pg_backup_custom.c:818 +#, c-format +msgid "error during file seek: %m" +msgstr "dosya içerisinde gösterge ilerleme hatası: %m" + +#: pg_backup_custom.c:467 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to lack of data offsets in archive" +msgstr "arÅŸivde %d block ID'si bulunamadı -- arÅŸivdeki eksik veri konumu nedeniyle iÅŸlenemeyen geçersiz yükleme isteÄŸi nedeniyle olabilir" + +#: pg_backup_custom.c:472 +#, c-format +msgid "could not find block ID %d in archive -- possibly due to out-of-order restore request, which cannot be handled due to non-seekable input file" +msgstr "arÅŸivde %d block ID'si bulunamadı -- aranamayan girdi dosyası nedeniyle iÅŸlenemeyen geçersiz yükleme isteÄŸi nedeniyle olabilir" + +#: pg_backup_custom.c:477 +#, c-format +msgid "could not find block ID %d in archive -- possibly corrupt archive" +msgstr "%d blok ID'si arÅŸivde bulunamadı -- arÅŸiv bozulmuÅŸ olabilir" + +#: pg_backup_custom.c:484 +#, c-format +msgid "found unexpected block ID (%d) when reading data -- expected %d" +msgstr "veriyi okurken beklenmeyen blok ID (%d) bulundu -- beklenen: %d" + +#: pg_backup_custom.c:498 +#, c-format +msgid "unrecognized data block type %d while restoring archive" +msgstr "arÅŸivi yüklerken bilinmeyen veri blok tipi %d bulundu" + +#: pg_backup_custom.c:580 +#, c-format +msgid "could not read from input file: %m" +msgstr "girdi dosyası okuma hatası: %m" + +#: pg_backup_custom.c:698 pg_backup_custom.c:751 pg_backup_custom.c:891 +#: pg_backup_tar.c:1091 +#, c-format +msgid "could not determine seek position in archive file: %m" +msgstr "arÅŸiv dosyasında arama pozisyonu belirlenemedi: %m" + +#: pg_backup_custom.c:715 pg_backup_custom.c:755 +#, c-format +msgid "could not close archive file: %m" +msgstr "arÅŸiv dosyası kapatma hatası: %m" + +#: pg_backup_custom.c:738 +#, c-format +msgid "can only reopen input archives" +msgstr "sadece girdi arÅŸivleri tekrar açılabilir" + +#: pg_backup_custom.c:745 +#, c-format +msgid "parallel restore from standard input is not supported" +msgstr "standart girdiden paralel geri yükleme desteklenmiyor" + +#: pg_backup_custom.c:747 +#, c-format +msgid "parallel restore from non-seekable file is not supported" +msgstr "taranamayan dosyadan paralel geri yükleme desteklenmiyor" + +#: pg_backup_custom.c:763 +#, c-format +msgid "could not set seek position in archive file: %m" +msgstr "arÅŸiv dosyasında arama pozisyonu ayarlanamadı: %m" + +#: pg_backup_custom.c:839 +#, c-format +msgid "compressor active" +msgstr "sıkıştırma etkin" + +#: pg_backup_custom.c:894 +#, c-format +msgid "ftell mismatch with expected position -- ftell used" +msgstr "ftell fonksiyonun bidirdiÄŸi pozisyonu ile beklenen pozisyon uyumsuz -- ftell kullanıldı" + +#: pg_backup_db.c:44 +#, c-format +msgid "could not get server_version from libpq" +msgstr "libpq kütüphanesinden server_version alınamadı" + +#: pg_backup_db.c:55 pg_dumpall.c:1806 +#, c-format +msgid "server version: %s; %s version: %s" +msgstr "sunucu sürümü: %s; %s sürümü: %s" + +#: pg_backup_db.c:57 pg_dumpall.c:1808 +#, c-format +msgid "aborting because of server version mismatch" +msgstr "sunucu sürümü uyuÅŸmazlığı nedeniyle iptal ediliyor (abort)" + +#: pg_backup_db.c:140 +#, c-format +msgid "connecting to database \"%s\" as user \"%s\"" +msgstr "\"%2$s\" kullanıcısı olarak \"%1$s\" veritabanına baÄŸlanılıyor" + +#: pg_backup_db.c:147 pg_backup_db.c:196 pg_backup_db.c:257 pg_backup_db.c:298 +#: pg_dumpall.c:1631 pg_dumpall.c:1744 +msgid "Password: " +msgstr "Parola: " + +#: pg_backup_db.c:179 +#, c-format +msgid "failed to reconnect to database" +msgstr "veritabanına yeniden baÄŸlanma hatası" + +#: pg_backup_db.c:184 +#, c-format +msgid "could not reconnect to database: %s" +msgstr "%s veritabanına yeniden baÄŸlanılamadı" + +#: pg_backup_db.c:200 +#, c-format +msgid "connection needs password" +msgstr "baÄŸlantı parola gerektiriyor" + +#: pg_backup_db.c:251 +#, c-format +msgid "already connected to a database" +msgstr "bir veritabanına zaten baÄŸlı" + +#: pg_backup_db.c:290 +#, c-format +msgid "failed to connect to database" +msgstr "veritabanına baÄŸlantı baÅŸarısız oldu" + +#: pg_backup_db.c:306 +#, c-format +msgid "connection to database \"%s\" failed: %s" +msgstr "\"%s\" veritabanına baÄŸlantı baÅŸarısız oldu: %s" + +#: pg_backup_db.c:378 pg_dumpall.c:1664 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_backup_db.c:385 pg_dumpall.c:1869 pg_dumpall.c:1892 +#, c-format +msgid "query failed: %s" +msgstr "sorgu baÅŸarısız oldu: %s" + +#: pg_backup_db.c:387 pg_dumpall.c:1870 pg_dumpall.c:1893 +#, c-format +msgid "query was: %s" +msgstr "sorgu ÅŸu idi: %s" + +#: pg_backup_db.c:428 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "sorgu 1 yerine %d satır döndürdü: %s" +msgstr[1] "sorgu 1 yerine %d satır döndürdü: %s" + +#: pg_backup_db.c:520 pg_backup_db.c:594 pg_backup_db.c:601 +msgid "could not execute query" +msgstr "sorgu çalıştırılamadı" + +#: pg_backup_db.c:573 +#, c-format +msgid "error returned by PQputCopyData: %s" +msgstr "PQputCopyData'nın döndürdüğü hata: %s" + +#: pg_backup_db.c:622 +#, c-format +msgid "error returned by PQputCopyEnd: %s" +msgstr "PQputCopyEnd'in döndürdüğü hata: %s" + +#: pg_backup_db.c:634 pg_dump.c:1924 +#, c-format +msgid "unexpected extra results during COPY of table \"%s\"" +msgstr "\"%s\" tablosunun COPY iÅŸlemi sırasında beklenmeyen ilave sonuçlar" + +#: pg_backup_db.c:646 +msgid "could not start database transaction" +msgstr "veritabanı transaction'u baÅŸlatılamadı" + +#: pg_backup_db.c:654 +msgid "could not commit database transaction" +msgstr "veritabanı iÅŸlemi (transaction) commit edilemedi" + +#: pg_backup_directory.c:156 +#, c-format +msgid "no output directory specified" +msgstr "herhangi bir çıktı dizini belirtilmedi" + +#: pg_backup_directory.c:185 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: pg_backup_directory.c:189 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" dizini kapatılamadı: %m" + +#: pg_backup_directory.c:195 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" dizini oluÅŸturulamadı: %m" + +#: pg_backup_directory.c:350 pg_backup_directory.c:488 +#: pg_backup_directory.c:518 +#, c-format +msgid "could not write to output file: %s" +msgstr "çıktı dosyasına yazma baÅŸarısız: %s" + +#: pg_backup_directory.c:403 +#, c-format +msgid "could not close data file: %m" +msgstr "veri dosyası kapatılamadı: %m" + +#: pg_backup_directory.c:443 +#, c-format +msgid "could not open large object TOC file \"%s\" for input: %m" +msgstr "girdi için \"%s\" large object TOC dosyası açılamadı: %m" + +#: pg_backup_directory.c:454 +#, c-format +msgid "invalid line in large object TOC file \"%s\": \"%s\"" +msgstr "\"%s\" large object TOC dosyasında geçersiz satır: \"%s\"" + +#: pg_backup_directory.c:463 +#, c-format +msgid "error reading large object TOC file \"%s\"" +msgstr "\"%s\" large object TOC dosyası okuma hatası" + +#: pg_backup_directory.c:467 +#, c-format +msgid "could not close large object TOC file \"%s\": %m" +msgstr "\"%s\" large object TOC dosyası kapatılamadı: %m" + +#: pg_backup_directory.c:678 +#, c-format +msgid "could not write to blobs TOC file" +msgstr "blobs TOC dosyası yazma hatası" + +#: pg_backup_directory.c:710 +#, c-format +msgid "file name too long: \"%s\"" +msgstr "dosya adı çok uzun: \"%s\"" + +#: pg_backup_null.c:75 +#, c-format +msgid "this format cannot be read" +msgstr "bu biçim okunamıyor" + +#: pg_backup_tar.c:177 +#, c-format +msgid "could not open TOC file \"%s\" for output: %m" +msgstr "çıktı için \"%s\" TOC dosyası açılamadı: %m" + +#: pg_backup_tar.c:184 +#, c-format +msgid "could not open TOC file for output: %m" +msgstr "çıktı için TOC dosyası açılamadı: %m" + +#: pg_backup_tar.c:203 pg_backup_tar.c:358 +#, c-format +msgid "compression is not supported by tar archive format" +msgstr "sıkıştırma, tar çıktı formatı tarafından desteklenmiyor" + +#: pg_backup_tar.c:211 +#, c-format +msgid "could not open TOC file \"%s\" for input: %m" +msgstr "\"%s\" TOC dosyası girdi için açılamadı: %m" + +#: pg_backup_tar.c:218 +#, c-format +msgid "could not open TOC file for input: %m" +msgstr "girdi için TOC dosyası açılamadı: %m" + +#: pg_backup_tar.c:344 +#, c-format +msgid "could not find file \"%s\" in archive" +msgstr "\"%s\" dosyası arÅŸivde bulunamadı" + +#: pg_backup_tar.c:410 +#, c-format +msgid "could not generate temporary file name: %m" +msgstr "geçici dosya adı oluÅŸturulamadı: %m" + +#: pg_backup_tar.c:421 +#, c-format +msgid "could not open temporary file" +msgstr "geçici dosya açılamadı" + +#: pg_backup_tar.c:448 +#, c-format +msgid "could not close tar member" +msgstr "tar öğesi kapatılamadı" + +#: pg_backup_tar.c:571 +#, c-format +msgid "internal error -- neither th nor fh specified in tarReadRaw()\n" +msgstr "iç hata - th ya da fh, tarReadRaw() içinde belirtilmedi\n" + +#: pg_backup_tar.c:693 +#, c-format +msgid "unexpected COPY statement syntax: \"%s\"" +msgstr "beklenmeyen COPY ifadesi söz dizimi: \"%s\"" + +#: pg_backup_tar.c:961 +#, c-format +msgid "invalid OID for large object (%u)" +msgstr "(%u) large object'i için geçersiz OID" + +#: pg_backup_tar.c:1106 +#, c-format +msgid "could not close temporary file: %m" +msgstr "geçici dosya kapatma hatası: %m" + +#: pg_backup_tar.c:1115 +#, c-format +msgid "actual file length (%s) does not match expected (%s)" +msgstr "gerçek dosya uzunluÄŸu (%s) beklenen uzunluÄŸu (%s) ile uyuÅŸmamaktadır" + +#: pg_backup_tar.c:1172 pg_backup_tar.c:1202 +#, c-format +msgid "could not find header for file \"%s\" in tar archive" +msgstr "tar arÅŸivinde \"%s\" dosyası için baÅŸlık bulunamadı" + +#: pg_backup_tar.c:1190 +#, c-format +msgid "restoring data out of order is not supported in this archive format: \"%s\" is required, but comes before \"%s\" in the archive file." +msgstr "bu arÅŸiv biçiminde veriyi sıra dışı geri yükleme desteklenmemektedir: \"%s\" bekleniyor ancak arÅŸiv dosyasında %s ondan önce gelmektedir." + +#: pg_backup_tar.c:1235 +#, c-format +msgid "incomplete tar header found (%lu byte)" +msgid_plural "incomplete tar header found (%lu bytes)" +msgstr[0] "eksik tar baÅŸlığı bulundu (%lu bayt)" +msgstr[1] "eksik tar baÅŸlığı bulundu (%lu bayt)" + +#: pg_backup_tar.c:1286 +#, c-format +msgid "corrupt tar header found in %s (expected %d, computed %d) file position %s" +msgstr "%s dosyasında bozuk tar baÅŸlığı (beklenen: %d, hesaplanan: %d) dosya pozisyonu %s" + +#: pg_backup_utils.c:54 +#, c-format +msgid "unrecognized section name: \"%s\"" +msgstr "bilinmeyen bölüm adı: \"%s\"" + +#: pg_backup_utils.c:55 pg_dump.c:612 pg_dump.c:629 pg_dumpall.c:338 +#: pg_dumpall.c:348 pg_dumpall.c:357 pg_dumpall.c:366 pg_dumpall.c:374 +#: pg_dumpall.c:388 pg_dumpall.c:464 pg_restore.c:290 pg_restore.c:306 +#: pg_restore.c:324 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazabilirsiniz.\n" + +#: pg_backup_utils.c:68 +#, c-format +msgid "out of on_exit_nicely slots" +msgstr "on_exit_nicely slotları yetersiz" + +#: pg_dump.c:543 +#, c-format +msgid "compression level must be in range 0..9" +msgstr "sıkıştırma seviyesi 0..9 aralığında olmalı" + +#: pg_dump.c:581 +#, c-format +msgid "extra_float_digits must be in range -15..3" +msgstr "extra_float_digits -15..3 aralığında olmalı" + +#: pg_dump.c:604 +#, c-format +msgid "rows-per-insert must be in range %d..%d" +msgstr "rows-per-insert %d..%d aralığında olmalı" + +#: pg_dump.c:627 pg_dumpall.c:346 pg_restore.c:304 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı argümanı (ilki \"%s\")" + +#: pg_dump.c:648 pg_restore.c:333 +#, c-format +msgid "options -s/--schema-only and -a/--data-only cannot be used together" +msgstr "-s/--schema-only ve -a/--data-only seçenekleri aynı anda kullanılamazlar" + +#: pg_dump.c:654 pg_restore.c:339 +#, c-format +msgid "options -c/--clean and -a/--data-only cannot be used together" +msgstr "-c/--clean ve -a/--data-only seçenekleri aynı anda kullanılamazlar" + +#: pg_dump.c:659 pg_dumpall.c:381 pg_restore.c:388 +#, c-format +msgid "option --if-exists requires option -c/--clean" +msgstr "--if-exists seçeneÄŸi -c/--clean seçeneÄŸini gerektirir" + +#: pg_dump.c:666 +#, c-format +msgid "option --on-conflict-do-nothing requires option --inserts, --rows-per-insert or --column-inserts" +msgstr "--on-conflict-do-nothing seçeneÄŸi --inserts, --rows-per-insert veya --column-inserts seçeneÄŸini gerektirir" + +#: pg_dump.c:688 +#, c-format +msgid "requested compression not available in this installation -- archive will be uncompressed" +msgstr "istenen sıkıştırma bu kurulumda desteklenmemektedir -- arÅŸiv sıkıştırılmayacak" + +#: pg_dump.c:709 pg_restore.c:355 +#, c-format +msgid "invalid number of parallel jobs" +msgstr "geçersiz sayıda parallel iÅŸ" + +#: pg_dump.c:713 +#, c-format +msgid "parallel backup only supported by the directory format" +msgstr "paralel yedek sadece dizin biçimi tarafından destekleniyor" + +#: pg_dump.c:768 +#, c-format +msgid "" +"Synchronized snapshots are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Senkronize anlık görüntüler (snapshot) bu sunucu sürümü tarafından desteklenmiyor.\n" +"Senkronize anlık görüntülere ihtiyaç yoksa bunun yerine --no-synchronized-snapshots \n" +"ile çalıştırın." + +#: pg_dump.c:774 +#, c-format +msgid "Exported snapshots are not supported by this server version." +msgstr "Bu sunucu sürümünde dışa aktarılmış anlık görüntü (exported snapshot) desteklenmemektedir." + +#: pg_dump.c:786 +#, c-format +msgid "last built-in OID is %u" +msgstr "son gömülü OID : %u" + +#: pg_dump.c:795 +#, c-format +msgid "no matching schemas were found" +msgstr "uygun ÅŸema bulunamadı" + +#: pg_dump.c:809 +#, c-format +msgid "no matching tables were found" +msgstr "uygun tablo bulunamadı" + +#: pg_dump.c:981 +#, c-format +msgid "" +"%s dumps a database as a text file or to other formats.\n" +"\n" +msgstr "" +"%s veritabanını metin dosyası ya da diÄŸer biçimlerde dump eder.\n" +"\n" + +#: pg_dump.c:982 pg_dumpall.c:617 pg_restore.c:468 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_dump.c:983 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [SEÇENEK]... [VERİTABANI_ADI]\n" + +#: pg_dump.c:985 pg_dumpall.c:620 pg_restore.c:471 +#, c-format +msgid "" +"\n" +"General options:\n" +msgstr "" +"\n" +"Genel seçenekler:\n" + +#: pg_dump.c:986 +#, c-format +msgid " -f, --file=FILENAME output file or directory name\n" +msgstr " -f, --file=DOSYAADI çıktı dosya adı ya da dizin adı\n" + +#: pg_dump.c:987 +#, c-format +msgid "" +" -F, --format=c|d|t|p output file format (custom, directory, tar,\n" +" plain text (default))\n" +msgstr "" +" -F, --format=c|d|t|p çıktı dosya biçimi (c:özel, d:dizin, t:tar,\n" +" p: düz metin (varsayılan))\n" +"\n" + +#: pg_dump.c:989 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to dump\n" +msgstr " -j, --jobs=SAYI döküm (dump) için belirtilen sayı kadar paralel süreç kullan\n" + +#: pg_dump.c:990 pg_dumpall.c:622 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose detaylı açıklamalı mod\n" + +#: pg_dump.c:991 pg_dumpall.c:623 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_dump.c:992 +#, c-format +msgid " -Z, --compress=0-9 compression level for compressed formats\n" +msgstr " -Z, --compress=0-9 sıkıştırılmış biçimler için sıkıştırma seviyesi\n" + +#: pg_dump.c:993 pg_dumpall.c:624 +#, c-format +msgid " --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n" +msgstr " --lock-wait-timeout=ZAMANAÅžIMI tablo kilitlemesi için ZAMANAÅžIMI kadar bekledikten sonra hata ver\n" + +#: pg_dump.c:994 pg_dumpall.c:652 +#, c-format +msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgstr "" +" --no-sync deÄŸiÅŸikliklerin diske yazılması için bekleme\n" +"\n" + +#: pg_dump.c:995 pg_dumpall.c:625 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı gösterir ve sonra çıkar\n" + +#: pg_dump.c:997 pg_dumpall.c:626 +#, c-format +msgid "" +"\n" +"Options controlling the output content:\n" +msgstr "" +"\n" +"Çıktı içeriÄŸini kontrol eden seçenekler:\n" + +#: pg_dump.c:998 pg_dumpall.c:627 +#, c-format +msgid " -a, --data-only dump only the data, not the schema\n" +msgstr " -a, --data-only sadece veriyi yedekle (dump); ÅŸemayı yedekleme\n" + +#: pg_dump.c:999 +#, c-format +msgid " -b, --blobs include large objects in dump\n" +msgstr " -b, --blobs yedeÄŸin (dump) içine büyük nesneleri dahil et\n" + +#: pg_dump.c:1000 +#, c-format +msgid " -B, --no-blobs exclude large objects in dump\n" +msgstr " -B, --no-blobs büyük nesneleri yedeÄŸin içine dahil etme\n" + +#: pg_dump.c:1001 pg_restore.c:482 +#, c-format +msgid " -c, --clean clean (drop) database objects before recreating\n" +msgstr " -c, --clean veritabanı nesnelerini yeniden oluÅŸturmadan önce temizle (kaldır)\n" + +#: pg_dump.c:1002 +#, c-format +msgid " -C, --create include commands to create database in dump\n" +msgstr " -C, --create yedeÄŸin (dump) içine veritabanını oluÅŸturacak komutları da ekle\n" + +#: pg_dump.c:1003 pg_dumpall.c:629 +#, c-format +msgid " -E, --encoding=ENCODING dump the data in encoding ENCODING\n" +msgstr " -E, --encoding=DİLKODLAMASI veriyi DİLKODLAMASI dil kodlamasıyla yedekle\n" + +#: pg_dump.c:1004 +#, c-format +msgid " -n, --schema=SCHEMA dump the named schema(s) only\n" +msgstr " -n, --schema=ÅžEMA sadece belirtilen ÅŸema veya ÅŸemaları yedekle\n" + +#: pg_dump.c:1005 +#, c-format +msgid " -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n" +msgstr " -N, --exclude-schema=ÅžEMA bu ÅŸema veya ÅŸemaları yedekleme\n" + +#: pg_dump.c:1006 +#, c-format +msgid "" +" -O, --no-owner skip restoration of object ownership in\n" +" plain-text format\n" +msgstr "" +" -O, --no-owner düz metin biçiminde nesne \n" +" sahipliÄŸinin yüklenmesini atla\n" + +#: pg_dump.c:1008 pg_dumpall.c:634 +#, c-format +msgid " -s, --schema-only dump only the schema, no data\n" +msgstr " -s, --schema-only sadece ÅŸemayı yedekle (dump), veriyi deÄŸil\n" + +#: pg_dump.c:1009 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in plain-text format\n" +msgstr " -S, --superuser=İSİM düz metin formatında kullanılacak superuser kullanıcı adı\n" + +#: pg_dump.c:1010 +#, c-format +msgid " -t, --table=TABLE dump the named table(s) only\n" +msgstr " -t, --table=TABLO sadece ismi geçen tablo veya tabloları yedekle\n" + +#: pg_dump.c:1011 +#, c-format +msgid " -T, --exclude-table=TABLE do NOT dump the named table(s)\n" +msgstr " -T, --exclude-table=TABLO ismi geçen tablo veya tabloları yedekleme\n" + +#: pg_dump.c:1012 pg_dumpall.c:637 +#, c-format +msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +msgstr " -x, --no-privileges yetkileri yedekleme (grant/revoke)\n" + +#: pg_dump.c:1013 pg_dumpall.c:638 +#, c-format +msgid " --binary-upgrade for use by upgrade utilities only\n" +msgstr " --binary-upgrade sadece yükseltme araçlarının kullanımı için\n" + +#: pg_dump.c:1014 pg_dumpall.c:639 +#, c-format +msgid " --column-inserts dump data as INSERT commands with column names\n" +msgstr " --column-inserts veriyi kolon adları ile INSERT komutları olarak yedekle\n" + +#: pg_dump.c:1015 pg_dumpall.c:640 +#, c-format +msgid " --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n" +msgstr " --disable-dollar-quoting dollar quoting kullanmayı engelle, standart SQL quoting kullan\n" + +#: pg_dump.c:1016 pg_dumpall.c:641 pg_restore.c:499 +#, c-format +msgid " --disable-triggers disable triggers during data-only restore\n" +msgstr " --disable-triggers salt-veri geri yüklemesi sırasında tetikleyicileri devre dışı bırak\n" + +#: pg_dump.c:1017 +#, c-format +msgid "" +" --enable-row-security enable row security (dump only content user has\n" +" access to)\n" +msgstr "" +" --enable-row-security satır güvenliÄŸini etkinleÅŸtir (sadece kullanıcının eriÅŸimi\n" +" olan içeriÄŸi yedekle)\n" + +#: pg_dump.c:1019 +#, c-format +msgid " --exclude-table-data=TABLE do NOT dump data for the named table(s)\n" +msgstr " --exclude-table-data=TABLO bu tablo veya tabloları yedekleme\n" + +#: pg_dump.c:1020 pg_dumpall.c:643 +#, c-format +msgid " --extra-float-digits=NUM override default setting for extra_float_digits\n" +msgstr " --extra-float-digits=NUM extra_float_digits için varayılan ayarı geçersiz kıl\n" + +#: pg_dump.c:1021 pg_dumpall.c:644 pg_restore.c:501 +#, c-format +msgid " --if-exists use IF EXISTS when dropping objects\n" +msgstr " --if-exists nesneleri silerken IF EXISTS kullan\n" + +#: pg_dump.c:1022 pg_dumpall.c:645 +#, c-format +msgid " --inserts dump data as INSERT commands, rather than COPY\n" +msgstr "" +" --inserts veriyi COPY'den ziyade INSERT komutları olarak yedekle\n" +"\n" + +#: pg_dump.c:1023 pg_dumpall.c:646 +#, c-format +msgid " --load-via-partition-root load partitions via the root table\n" +msgstr " --load-via-partition-root bölümleri (partition) kök tablo üzerinden yükle\n" + +#: pg_dump.c:1024 pg_dumpall.c:647 +#, c-format +msgid " --no-comments do not dump comments\n" +msgstr "" +" --no-comments açıklamaları (comments) yedekleme\n" +"\n" + +#: pg_dump.c:1025 pg_dumpall.c:648 +#, c-format +msgid " --no-publications do not dump publications\n" +msgstr " --no-publications yayınları yedekleme\n" + +#: pg_dump.c:1026 pg_dumpall.c:650 +#, c-format +msgid " --no-security-labels do not dump security label assignments\n" +msgstr " --no-security-labels güvenlik etiketi atamalarını yedekleme\n" + +#: pg_dump.c:1027 pg_dumpall.c:651 +#, c-format +msgid " --no-subscriptions do not dump subscriptions\n" +msgstr " --no-subscriptions abonelikleri yedekleme\n" + +#: pg_dump.c:1028 +#, c-format +msgid " --no-synchronized-snapshots do not use synchronized snapshots in parallel jobs\n" +msgstr " --no-synchronized-snapshots paralel iÅŸlerde senkronize anlık görüntüleri yedekleme\n" + +#: pg_dump.c:1029 pg_dumpall.c:653 +#, c-format +msgid " --no-tablespaces do not dump tablespace assignments\n" +msgstr " --no-tablespaces tablespace atamalarını yedekleme\n" + +#: pg_dump.c:1030 pg_dumpall.c:654 +#, c-format +msgid " --no-unlogged-table-data do not dump unlogged table data\n" +msgstr " --no-unlogged-table-data loglanmayan tablo verisini yedekleme\n" + +#: pg_dump.c:1031 pg_dumpall.c:655 +#, c-format +msgid " --on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands\n" +msgstr " --on-conflict-do-nothing INSERT komutlarına ON CONFLICT DO NOTHING ekle\n" + +#: pg_dump.c:1032 pg_dumpall.c:656 +#, c-format +msgid " --quote-all-identifiers quote all identifiers, even if not key words\n" +msgstr " --quote-all-identifiers anahtar sözcükler olmasa bile tüm belirteçleri çift tırnak içine al\n" + +#: pg_dump.c:1033 +#, c-format +msgid " --rows-per-insert=NROWS number of rows per INSERT; implies --inserts\n" +msgstr " --rows-per-insert=NROWS INSERT başına satır sayısı; --inserts seçeneÄŸiyle kullanılır\n" + +#: pg_dump.c:1034 +#, c-format +msgid " --section=SECTION dump named section (pre-data, data, or post-data)\n" +msgstr " --section=BÖLÜM belirtilen bölümü yedekle (pre-data, data, veya post-data)\n" + +#: pg_dump.c:1035 +#, c-format +msgid " --serializable-deferrable wait until the dump can run without anomalies\n" +msgstr " --serializable-deferrable yedeÄŸin bir anormallik olmadan biteceÄŸi ana kadar bekle\n" + +#: pg_dump.c:1036 +#, c-format +msgid " --snapshot=SNAPSHOT use given snapshot for the dump\n" +msgstr " --snapshot=SNAPSHOT yedek için verilen anlık görüntüyü (snapshot) kullan\n" + +#: pg_dump.c:1037 pg_restore.c:510 +#, c-format +msgid "" +" --strict-names require table and/or schema include patterns to\n" +" match at least one entity each\n" +msgstr "" +" --strict-names tablo ve/veya ÅŸema her biri en az bir varlıkla (entity)\n" +" eÅŸleÅŸecek desenler (pattern) bulundurmalıdır\n" + +#: pg_dump.c:1039 pg_dumpall.c:657 pg_restore.c:512 +#, c-format +msgid "" +" --use-set-session-authorization\n" +" use SET SESSION AUTHORIZATION commands instead of\n" +" ALTER OWNER commands to set ownership\n" +msgstr "" +" --use-set-session-authorization\n" +" SahipliÄŸi ayarlamak için ALTER OWNER komutları yerine\n" +" SET SESSION AUTHORIZATION komutlarını kullan\n" + +#: pg_dump.c:1043 pg_dumpall.c:661 pg_restore.c:516 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"BaÄŸlantı Seçenekleri:\n" + +#: pg_dump.c:1044 +#, c-format +msgid " -d, --dbname=DBNAME database to dump\n" +msgstr " -d, --dbname=VERİTABANI_ADI yedeklenecek veritabanı adı\n" + +#: pg_dump.c:1045 pg_dumpall.c:663 pg_restore.c:517 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME veritabanı sunucusu adresi ya da soket dizini\n" + +#: pg_dump.c:1046 pg_dumpall.c:665 pg_restore.c:518 +#, c-format +msgid " -p, --port=PORT database server port number\n" +msgstr " -p PORT veritabanı sunucusunun port numarası\n" + +#: pg_dump.c:1047 pg_dumpall.c:666 pg_restore.c:519 +#, c-format +msgid " -U, --username=NAME connect as specified database user\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı\n" + +#: pg_dump.c:1048 pg_dumpall.c:667 pg_restore.c:520 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password baÄŸlanmak için kesinlikle parola sorma\n" + +#: pg_dump.c:1049 pg_dumpall.c:668 pg_restore.c:521 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W ÅŸifre sor (otomatik olarak her zaman açık)\n" + +#: pg_dump.c:1050 pg_dumpall.c:669 +#, c-format +msgid " --role=ROLENAME do SET ROLE before dump\n" +msgstr " --role=ROL ADI yedek iÅŸleminden önce SET ROLE çalıştır\n" + +#: pg_dump.c:1052 +#, c-format +msgid "" +"\n" +"If no database name is supplied, then the PGDATABASE environment\n" +"variable value is used.\n" +"\n" +msgstr "" +"\n" +"Veritabanı adı verilmemiÅŸse PGDATABASE çevre deÄŸiÅŸkeni\n" +"kullanılacaktır.\n" +"\n" + +#: pg_dump.c:1054 pg_dumpall.c:673 pg_restore.c:528 +#, c-format +msgid "Report bugs to .\n" +msgstr "Hataları adresine bildirin.\n" + +#: pg_dump.c:1073 pg_dumpall.c:499 +#, c-format +msgid "invalid client encoding \"%s\" specified" +msgstr "belirtilen \"%s\" istemci dil kodlaması geçersiz" + +#: pg_dump.c:1218 +#, c-format +msgid "" +"Synchronized snapshots on standby servers are not supported by this server version.\n" +"Run with --no-synchronized-snapshots instead if you do not need\n" +"synchronized snapshots." +msgstr "" +"Yedek (standby) sunucularda anlık görüntüler (snapshot) bu sunucu sürümünde desteklenmiyor.\n" +"Senkronize anlık görüntülere ihtiyaç yoksa bunun yerine --no-synchronized-snapshots\n" +"ile çalıştırın." + +#: pg_dump.c:1287 +#, c-format +msgid "invalid output format \"%s\" specified" +msgstr "geçersiz çıktı biçimi \"%s\" belirtildi" + +#: pg_dump.c:1325 +#, c-format +msgid "no matching schemas were found for pattern \"%s\"" +msgstr "\"%s\" ÅŸablonu (pattern) için eÅŸleÅŸen ÅŸema bulunamadı" + +#: pg_dump.c:1390 +#, c-format +msgid "no matching tables were found for pattern \"%s\"" +msgstr "\"%s\" ÅŸablonu (pattern) için eÅŸleÅŸen tablo bulunamadı" + +#: pg_dump.c:1804 +#, c-format +msgid "dumping contents of table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun içeriÄŸi yedekleniyor" + +#: pg_dump.c:1905 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetCopyData() failed." +msgstr "\"%s\" tablosunu içeriÄŸinin yedeklenmesi baÅŸarısız: PQgetCopyData() baÅŸarısız." + +#: pg_dump.c:1906 pg_dump.c:1916 +#, c-format +msgid "Error message from server: %s" +msgstr "Sunucudan hata mesajı alındı: %s" + +#: pg_dump.c:1907 pg_dump.c:1917 +#, c-format +msgid "The command was: %s" +msgstr "O sırada yürütülen komut: %s" + +#: pg_dump.c:1915 +#, c-format +msgid "Dumping the contents of table \"%s\" failed: PQgetResult() failed." +msgstr "\"%s\" tablosunun içeriÄŸinin yedeklenmesi baÅŸarısız: PQgetResult() baÅŸarısız." + +#: pg_dump.c:2669 +#, c-format +msgid "saving database definition" +msgstr "veritabanın tanımı kaydediliyor" + +#: pg_dump.c:3116 +#, c-format +msgid "saving encoding = %s" +msgstr "dil kodlaması kaydediliyor = %s" + +#: pg_dump.c:3143 +#, c-format +msgid "saving standard_conforming_strings = %s" +msgstr "standard_conforming_strings kaydediliyor = %s " + +#: pg_dump.c:3184 +#, c-format +msgid "could not parse result of current_schemas()" +msgstr "current_schemas() sonucu ayrıştırılamadı" + +#: pg_dump.c:3203 +#, c-format +msgid "saving search_path = %s" +msgstr "search_path = %s olarak kaydediliyor" + +#: pg_dump.c:3245 +#, c-format +msgid "reading large objects" +msgstr "large object'ler okunuyor" + +#: pg_dump.c:3427 +#, c-format +msgid "saving large objects" +msgstr "large object'ler kaydediliyor" + +#: pg_dump.c:3473 +#, c-format +msgid "error reading large object %u: %s" +msgstr "%u large object okurken hata oldu: %s" + +#: pg_dump.c:3525 +#, c-format +msgid "reading row security enabled for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için etkinleÅŸtirilen satır güvenliÄŸi (row security) okunuyor" + +#: pg_dump.c:3556 +#, c-format +msgid "reading policies for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için ilkeler (policy) okunuyor" + +#: pg_dump.c:3707 +#, c-format +msgid "unexpected policy command type: %c" +msgstr "beklenmeyen ilke (policy) komut türü: %c" + +#: pg_dump.c:3834 +#, c-format +msgid "owner of publication \"%s\" appears to be invalid" +msgstr "\"%s\" fonksiyonunun sahibi geçersiz görünüyor" + +#: pg_dump.c:3971 +#, c-format +msgid "reading publication membership for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun yayın (publication) üyeliÄŸi okunuyor" + +#: pg_dump.c:4116 +#, c-format +msgid "subscriptions not dumped because current user is not a superuser" +msgstr "abonelikler yedeklenmedi çünkü geçerli kullanıcı superuser deÄŸil" + +#: pg_dump.c:4170 +#, c-format +msgid "owner of subscription \"%s\" appears to be invalid" +msgstr "\"%s\" aboneliÄŸinin sahibi geçersiz görünüyor" + +#: pg_dump.c:4214 +#, c-format +msgid "could not parse subpublications array" +msgstr "alt-yayınlar dizisi ayrıştırılamadı" + +#: pg_dump.c:4486 +#, c-format +msgid "could not find parent extension for %s %s" +msgstr "%s için üst uzantı bulunamadı %s" + +#: pg_dump.c:4618 +#, c-format +msgid "owner of schema \"%s\" appears to be invalid" +msgstr "\"%s\" ÅŸemasının sahibi geçersiz görünüyor" + +#: pg_dump.c:4641 +#, c-format +msgid "schema with OID %u does not exist" +msgstr "%u OID'li ÅŸema mevcut deÄŸil" + +#: pg_dump.c:4966 +#, c-format +msgid "owner of data type \"%s\" appears to be invalid" +msgstr "\"%s\" veri tipinin sahibi geçersiz görünüyor" + +#: pg_dump.c:5051 +#, c-format +msgid "owner of operator \"%s\" appears to be invalid" +msgstr "\"%s\" operatörünün sahibi geçersiz görünüyor" + +#: pg_dump.c:5353 +#, c-format +msgid "owner of operator class \"%s\" appears to be invalid" +msgstr "\"%s\" operatör sınıfının sahibi geçersiz görünüyor" + +#: pg_dump.c:5437 +#, c-format +msgid "owner of operator family \"%s\" appears to be invalid" +msgstr "\"%s\" operatör ailesinin sahibi geçersiz görünüyor" + +#: pg_dump.c:5606 +#, c-format +msgid "owner of aggregate function \"%s\" appears to be invalid" +msgstr "\"%s\" aggregate fonksiyonun sahibi geçersiz görünüyor" + +#: pg_dump.c:5866 +#, c-format +msgid "owner of function \"%s\" appears to be invalid" +msgstr "\"%s\" fonksiyonunun sahibi geçersiz görünüyor" + +#: pg_dump.c:6662 +#, c-format +msgid "owner of table \"%s\" appears to be invalid" +msgstr "\"%s\" tablosunun sahibi geçersiz görünüyor" + +#: pg_dump.c:6704 pg_dump.c:17053 +#, c-format +msgid "failed sanity check, parent table with OID %u of sequence with OID %u not found" +msgstr "tutarlılık kontrolü baÅŸarısız, %2$u OID'li dizinin (sequence) %1$u OID'li üst tablosu bulunamadı" + +#: pg_dump.c:6848 +#, c-format +msgid "reading indexes for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun indeksleri okunuyor" + +#: pg_dump.c:7249 +#, c-format +msgid "reading foreign key constraints for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun foreign key bütünlük kısıtlamaları okunuyor" + +#: pg_dump.c:7468 +#, c-format +msgid "failed sanity check, parent table with OID %u of pg_rewrite entry with OID %u not found" +msgstr "tutarlılık kontrolü baÅŸarısız, %2$u OID'li pg_rewrite girdisinin %1$u OID'li üst tablosu bulunamadı" + +#: pg_dump.c:7551 +#, c-format +msgid "reading triggers for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun tetikleyicileri okunuyor" + +#: pg_dump.c:7684 +#, c-format +msgid "query produced null referenced table name for foreign key trigger \"%s\" on table \"%s\" (OID of table: %u)" +msgstr "sorgu, \"%2$s\" tablosu (tablo OID: %3$u) üzerindeki \"%1$s\" foreign key tetikleyici için null referans edilen tablo adı getirdi" + +#: pg_dump.c:8239 +#, c-format +msgid "finding the columns and types of table \"%s.%s\"" +msgstr "\"%s.%s\" tablosunun sütunları ve tipleri bulunuyor" + +#: pg_dump.c:8375 +#, c-format +msgid "invalid column numbering in table \"%s\"" +msgstr "\"%s\" tablosunda geçersiz sütun numaralandırması" + +#: pg_dump.c:8412 +#, c-format +msgid "finding default expressions of table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için varsayılan ifadeler bulunuyor" + +#: pg_dump.c:8434 +#, c-format +msgid "invalid adnum value %d for table \"%s\"" +msgstr "\"%2$s\" tablosu için geçersiz adnum deÄŸeri %1$d" + +#: pg_dump.c:8499 +#, c-format +msgid "finding check constraints for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için kontrol kısıtlamaları bulunuyor" + +#: pg_dump.c:8548 +#, c-format +msgid "expected %d check constraint on table \"%s\" but found %d" +msgid_plural "expected %d check constraints on table \"%s\" but found %d" +msgstr[0] "%d check kısıtlamasının \"%s\" tablosunda bulunması beklendi; ancak %d bulundu" +msgstr[1] "%d check kısıtlamasının \"%s\" tablosunda bulunması beklendi; ancak %d bulundu" + +#: pg_dump.c:8552 +#, c-format +msgid "(The system catalogs might be corrupted.)" +msgstr "(Sistem kataloÄŸu bozulmuÅŸ olabilir.)" + +#: pg_dump.c:10140 +#, c-format +msgid "typtype of data type \"%s\" appears to be invalid" +msgstr "\"%s\" veri tipinin typtype'i geçersiz görünüyor" + +#: pg_dump.c:11496 +#, c-format +msgid "bogus value in proargmodes array" +msgstr "proargnames dizisi içinde belirsiz deÄŸer" + +#: pg_dump.c:11868 +#, c-format +msgid "could not parse proallargtypes array" +msgstr "proallargtypes dizisi ayrıştırılamadı" + +#: pg_dump.c:11884 +#, c-format +msgid "could not parse proargmodes array" +msgstr "proargmodes dizisi ayrıştırılamadı" + +#: pg_dump.c:11898 +#, c-format +msgid "could not parse proargnames array" +msgstr "proargnames dizisi ayrıştırılamadı" + +#: pg_dump.c:11909 +#, c-format +msgid "could not parse proconfig array" +msgstr "proconfig dizisi ayrıştırılamadı" + +#: pg_dump.c:11989 +#, c-format +msgid "unrecognized provolatile value for function \"%s\"" +msgstr "\"%s\" fonksiyonu için bilinmeyen provolatile deÄŸeri" + +#: pg_dump.c:12039 pg_dump.c:14094 +#, c-format +msgid "unrecognized proparallel value for function \"%s\"" +msgstr "unrecognized proparallel value for function \"%s\"" + +#: pg_dump.c:12172 pg_dump.c:12282 pg_dump.c:12289 +#, c-format +msgid "could not find function definition for function with OID %u" +msgstr "%u OID'li fonksiyon için fonksiyon tanımı bulunamadı" + +#: pg_dump.c:12211 +#, c-format +msgid "bogus value in pg_cast.castfunc or pg_cast.castmethod field" +msgstr "pg_cast.castfunc veya pg_cast.castmethod field alanı içinde belirsiz deÄŸer" + +#: pg_dump.c:12214 +#, c-format +msgid "bogus value in pg_cast.castmethod field" +msgstr "pg_cast.castmethod field alanı içinde belirsiz deÄŸer" + +#: pg_dump.c:12308 +#, c-format +msgid "bogus transform definition, at least one of trffromsql and trftosql should be nonzero" +msgstr "belirsiz dönüşüm tanımı, trffromsql ve trftosql'in en azından biri sıfırdan farklı olmalı" + +#: pg_dump.c:12325 +#, c-format +msgid "bogus value in pg_transform.trffromsql field" +msgstr "pg_transform.trffromsql alanı içinde belirsiz deÄŸer" + +#: pg_dump.c:12346 +#, c-format +msgid "bogus value in pg_transform.trftosql field" +msgstr "pg_transform.trftosql alanı içinde belirsiz deÄŸer" + +#: pg_dump.c:12663 +#, c-format +msgid "could not find operator with OID %s" +msgstr "%s OID'li olan operatör bulunamadı" + +#: pg_dump.c:12731 +#, c-format +msgid "invalid type \"%c\" of access method \"%s\"" +msgstr "\"%2$s\" eriÅŸim yöntemi için geçersiz tip \"%1$c\"" + +#: pg_dump.c:13486 +#, c-format +msgid "unrecognized collation provider: %s\n" +msgstr "bilinmeyen karşılaÅŸtırma (collation) saÄŸlayıcısı: %s\n" + +#: pg_dump.c:13958 +#, c-format +msgid "aggregate function %s could not be dumped correctly for this database version; ignored" +msgstr "%s aggregate fonksiyonu veritabanının bu sürümünde düzgün dump edilemiyor; atlanıyor" + +#: pg_dump.c:14013 +#, c-format +msgid "unrecognized aggfinalmodify value for aggregate \"%s\"" +msgstr "\"%s\" toplamı (aggregate) için tanınmayan aggfinalmodify deÄŸeri" + +#: pg_dump.c:14069 +#, c-format +msgid "unrecognized aggmfinalmodify value for aggregate \"%s\"" +msgstr "\"%s\" toplamı (aggregate) için tanınmayan aggmfinalmodify deÄŸeri" + +#: pg_dump.c:14793 +#, c-format +msgid "unrecognized object type in default privileges: %d" +msgstr "öntanımlı yetkilerde bilinmeyen nesne tipi: %d" + +#: pg_dump.c:14811 +#, c-format +msgid "could not parse default ACL list (%s)" +msgstr "öntanımlı ACL listesi ayrıştırılamıyor (%s)" + +#: pg_dump.c:14892 +#, c-format +msgid "could not parse initial GRANT ACL list (%s) or initial REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "\"%3$s\" nesnesinin ilk GRANT ACL listesi (%1$s) veya ilk REVOKE ACL listesi (%2$s) ayrıştırılamıyor (%4$s)" + +#: pg_dump.c:14900 +#, c-format +msgid "could not parse GRANT ACL list (%s) or REVOKE ACL list (%s) for object \"%s\" (%s)" +msgstr "\"%3$s\" nesnesinin GRANT ACL listesi (%1$s) veya REVOKE ACL listesi (%2$s) ayrıştırılamıyor (%4$s)" + +#: pg_dump.c:15402 +#, c-format +msgid "query to obtain definition of view \"%s\" returned no data" +msgstr "\"%s\" view tanımını getirecek sorgu hiçbir veri getirmedi" + +#: pg_dump.c:15405 +#, c-format +msgid "query to obtain definition of view \"%s\" returned more than one definition" +msgstr "\"%s\" view tanımını getirecek sorgu birden çok tanım getirdi" + +#: pg_dump.c:15412 +#, c-format +msgid "definition of view \"%s\" appears to be empty (length zero)" +msgstr "\"%s\" view tanımı boÅŸ görünüyor (uzunluÄŸu sıfır)" + +#: pg_dump.c:15494 +#, c-format +msgid "WITH OIDS is not supported anymore (table \"%s\")" +msgstr "WITH OIDS artık desteklenmiyor (\"%s\" tablosu)" + +#: pg_dump.c:15945 +#, c-format +msgid "invalid number of parents %d for table \"%s\"" +msgstr "\"%2$s\" tablosu için geçersiz üst nesne sayısı %1$d" + +#: pg_dump.c:16282 +#, c-format +msgid "invalid column number %d for table \"%s\"" +msgstr "\"%2$s\" tablosu için geçersiz sütun sayısı %1$d" + +#: pg_dump.c:16546 +#, c-format +msgid "missing index for constraint \"%s\"" +msgstr "\"%s\" bütünlük kısıtlamasının indeksi eksik" + +#: pg_dump.c:16766 +#, c-format +msgid "unrecognized constraint type: %c" +msgstr "bilinmeyen bütünlük kısıtlama türü: %c" + +#: pg_dump.c:16898 pg_dump.c:17119 +#, c-format +msgid "query to get data of sequence \"%s\" returned %d row (expected 1)" +msgid_plural "query to get data of sequence \"%s\" returned %d rows (expected 1)" +msgstr[0] "\"%s\" sequence verisini getirecek sorgu %d satır döndürdü (bir satır bekleniyordu)" +msgstr[1] "\"%s\" sequence verisini getirecek sorgu %d satır döndürdü (bir satır bekleniyordu)" + +#: pg_dump.c:16932 +#, c-format +msgid "unrecognized sequence type: %s" +msgstr "tanınmayan sequence tipi \"%s\"" + +#: pg_dump.c:17216 +#, c-format +msgid "unexpected tgtype value: %d" +msgstr "beklenmeyen tgtype deÄŸeri: %d" + +#: pg_dump.c:17290 +#, c-format +msgid "invalid argument string (%s) for trigger \"%s\" on table \"%s\"" +msgstr "\"%3$s\" tablosunun \"%2$s\" tetikleyicisi için geçersiz argüman dizesi (%1$s)" + +#: pg_dump.c:17519 +#, c-format +msgid "query to get rule \"%s\" for table \"%s\" failed: wrong number of rows returned" +msgstr "\"%s\" tablosundan \"%s\" rule'unu getiren sorgu baÅŸarısız: dönen satır sayısı yanlış" + +#: pg_dump.c:17681 +#, c-format +msgid "could not find referenced extension %u" +msgstr "referans verilen uzantı bulunamadı %u" + +#: pg_dump.c:17893 +#, c-format +msgid "reading dependency data" +msgstr "bağımlılık verileri okunuyor" + +#: pg_dump.c:17948 +#, c-format +msgid "no referencing object %u %u" +msgstr "referans veren nesne yok %u %u" + +#: pg_dump.c:17959 +#, c-format +msgid "no referenced object %u %u" +msgstr "referans verilen nesne yok %u %u" + +#: pg_dump.c:18327 +#, c-format +msgid "could not parse reloptions array" +msgstr "reloptions dizisi (array) ayrıştırılamadı" + +#: pg_dump_sort.c:328 +#, c-format +msgid "invalid dumpId %d" +msgstr "geçersiz dumpId %d" + +#: pg_dump_sort.c:334 +#, c-format +msgid "invalid dependency %d" +msgstr "geçersiz bağımlılık %d" + +#: pg_dump_sort.c:567 +#, c-format +msgid "could not identify dependency loop" +msgstr "bağımlılık döngüsü tespit edilemedi" + +#: pg_dump_sort.c:1130 +#, c-format +msgid "there are circular foreign-key constraints on this table:" +msgid_plural "there are circular foreign-key constraints among these tables:" +msgstr[0] "DİKKAT: Bu tablo üzerinde dairesel (circular) foreign-key kısıtlamaları bulunmaktadır:" +msgstr[1] "DİKKAT: Bu tablolar arasında dairesel (circular) foreign-key kısıtlamaları bulunmaktadır:" + +#: pg_dump_sort.c:1134 pg_dump_sort.c:1154 +#, c-format +msgid " %s" +msgstr " %s" + +#: pg_dump_sort.c:1135 +#, c-format +msgid "You might not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints." +msgstr "--disable-triggers kullanmadan veya kısıtlamaları (constraint) geçici olarak kaldırmadan yedeÄŸi (dump) geri yükleyemebilirsiniz." + +#: pg_dump_sort.c:1136 +#, c-format +msgid "Consider using a full dump instead of a --data-only dump to avoid this problem." +msgstr "Bu sorunla karşılaÅŸmamak için --data-only yedek yerine tam yedek (full dump) almayı düşünün." + +#: pg_dump_sort.c:1148 +#, c-format +msgid "could not resolve dependency loop among these items:" +msgstr "bu öğeler arasındaki bağımlılık döngüsü çözülemedi" + +#: pg_dumpall.c:200 +#, c-format +msgid "" +"The program \"pg_dump\" is needed by %s but was not found in the\n" +"same directory as \"%s\".\n" +"Check your installation." +msgstr "" +"\"pg_dump\" uygulaması %s için gerekmektedir ancak\n" +"\"%s\" ile aynı dizinde bulunamadı.\n" +"Kurulumunuzu kontrol edin." + +#: pg_dumpall.c:205 +#, c-format +msgid "" +"The program \"pg_dump\" was found by \"%s\"\n" +"but was not the same version as %s.\n" +"Check your installation." +msgstr "" +"\"pg_dump\" uygulaması \"%s\" tarafından bulundu\n" +"ancak %s ile aynı sürüm deÄŸildir.\n" +"Kurulumunuzu kontrol edin." + +#: pg_dumpall.c:356 +#, c-format +msgid "option --exclude-database cannot be used together with -g/--globals-only, -r/--roles-only or -t/--tablespaces-only" +msgstr "--exclude-database seçeneÄŸi -g/--globals-only, -r/--roles-only veya -t/--tablespaces-only ile birlikte kullanılamaz" + +#: pg_dumpall.c:365 +#, c-format +msgid "options -g/--globals-only and -r/--roles-only cannot be used together" +msgstr "-g/--globals-only ve -r/--roles-only seçenekleri beraber kullanılamaz" + +#: pg_dumpall.c:373 +#, c-format +msgid "options -g/--globals-only and -t/--tablespaces-only cannot be used together" +msgstr "-g/--globals-only ve -t/--tablespaces-only seçenekleri beraber kullanılamaz" + +#: pg_dumpall.c:387 +#, c-format +msgid "options -r/--roles-only and -t/--tablespaces-only cannot be used together" +msgstr "-r/--roles-only ve -t/--tablespaces-only seçenekleri birlikte kullanılamaz" + +#: pg_dumpall.c:448 pg_dumpall.c:1734 +#, c-format +msgid "could not connect to database \"%s\"" +msgstr "\"%s\" veritabanına baÄŸlanılamadı" + +#: pg_dumpall.c:462 +#, c-format +msgid "" +"could not connect to databases \"postgres\" or \"template1\"\n" +"Please specify an alternative database." +msgstr "" +"\"postgres\" veya \"template1\" veritabanına baÄŸlanılamadı\n" +"Lütfen alternatif bir veritabanı belirtin" + +#: pg_dumpall.c:484 +#, c-format +msgid "could not open the output file \"%s\": %m" +msgstr "\"%s\" çıktı dosyası açılamadı: %m" + +#: pg_dumpall.c:616 +#, c-format +msgid "" +"%s extracts a PostgreSQL database cluster into an SQL script file.\n" +"\n" +msgstr "" +"%s, PostgreSQL veritabanı clusteri SQL betik dosyasına aktarıyor.\n" +"\n" + +#: pg_dumpall.c:618 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [SEÇENEK]...\n" + +#: pg_dumpall.c:621 +#, c-format +msgid " -f, --file=FILENAME output file name\n" +msgstr " -f, --file=DOSYA_ADI çıktı dosya adı\n" + +#: pg_dumpall.c:628 +#, c-format +msgid " -c, --clean clean (drop) databases before recreating\n" +msgstr " -c, --clean yeniden oluÅŸturmadan önce veritabanlarını temizle (drop)\n" + +#: pg_dumpall.c:630 +#, c-format +msgid " -g, --globals-only dump only global objects, no databases\n" +msgstr " -g, --globals-only Sadece global nesneleri yedekle, veritabanlarını yedekleme\n" + +#: pg_dumpall.c:631 +#, c-format +msgid " -o, --oids include OIDs in dump\n" +msgstr " -o, --oids yedeÄŸin içine OID'leri de ekle\n" + +#: pg_dumpall.c:632 pg_restore.c:491 +#, c-format +msgid " -O, --no-owner skip restoration of object ownership\n" +msgstr " -O, --no-owner veri sahipliÄŸi ile ilgili bilgileri geri yükleme\n" + +#: pg_dumpall.c:633 +#, c-format +msgid " -r, --roles-only dump only roles, no databases or tablespaces\n" +msgstr " -r, --roles-only sadece rolleri yedekle, veritabanlarını ya da tablespace'leri deÄŸil\n" + +#: pg_dumpall.c:635 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use in the dump\n" +msgstr " -S, --superuser=AD yedeklerde kullanılacak superuser kullanıcı adı\n" + +#: pg_dumpall.c:636 +#, c-format +msgid " -t, --tablespaces-only dump only tablespaces, no databases or roles\n" +msgstr " -t, --tablespaces-only sadece tablespaceleri yedekle, veritabanlarını ya da rolleri deÄŸil\n" + +#: pg_dumpall.c:642 +#, c-format +msgid " --exclude-database=PATTERN exclude databases whose name matches PATTERN\n" +msgstr " --exclude-database=DESEN isimleri DESEN ile eÅŸleÅŸen veritabanlarını hariç tut\n" + +#: pg_dumpall.c:649 +#, c-format +msgid " --no-role-passwords do not dump passwords for roles\n" +msgstr " -W, --password rollerin parolalarını yedekleme\n" + +#: pg_dumpall.c:662 +#, c-format +msgid " -d, --dbname=CONNSTR connect using connection string\n" +msgstr " -d, --dbname=CONNSTR baÄŸlantı cümleciÄŸini kullanarak baÄŸlan\n" + +#: pg_dumpall.c:664 +#, c-format +msgid " -l, --database=DBNAME alternative default database\n" +msgstr " -l, --database=VERİTABANI ADI varsayılan alternatif veritabanı\n" + +#: pg_dumpall.c:671 +#, c-format +msgid "" +"\n" +"If -f/--file is not used, then the SQL script will be written to the standard\n" +"output.\n" +"\n" +msgstr "" +"\n" +"EÄŸer -f/--file kullanılmazsa, SQL betiÄŸi standart çıktıya\n" +"yazılacaktır.\n" +"\n" + +#: pg_dumpall.c:876 +#, c-format +msgid "role name starting with \"pg_\" skipped (%s)" +msgstr "\"pg_\" ile baÅŸlayan rol adı atlandı (%s)" + +#: pg_dumpall.c:1258 +#, c-format +msgid "could not parse ACL list (%s) for tablespace \"%s\"" +msgstr "\"%2$s\" tablespace için ACL (%1$s) listesi ayrıştırılamadı" + +#: pg_dumpall.c:1475 +#, c-format +msgid "excluding database \"%s\"..." +msgstr "\"%s\" veritabanı hariç tutuluyor..." + +#: pg_dumpall.c:1479 +#, c-format +msgid "dumping database \"%s\"..." +msgstr "\"%s\" veritabanı dökümü alınıyor(dump)..." + +#: pg_dumpall.c:1511 +#, c-format +msgid "pg_dump failed on database \"%s\", exiting" +msgstr "pg_dump \"%s\" veritabanında baÅŸarısız oldu, çıkılıyor" + +#: pg_dumpall.c:1520 +#, c-format +msgid "could not re-open the output file \"%s\": %m" +msgstr "\"%s\" çıktı dosyası yeniden açılamadı: %m" + +#: pg_dumpall.c:1564 +#, c-format +msgid "running \"%s\"" +msgstr "\"%s\" yürütülüyor" + +#: pg_dumpall.c:1755 +#, c-format +msgid "could not connect to database \"%s\": %s" +msgstr "\"%s\" veritabanına baÄŸlanılamadı: %s" + +#: pg_dumpall.c:1785 +#, c-format +msgid "could not get server version" +msgstr "sunucu sürüm bilgisi alınamadı" + +#: pg_dumpall.c:1791 +#, c-format +msgid "could not parse server version \"%s\"" +msgstr "\"%s\" sürüm bilgisi ayrıştırılamadı" + +#: pg_dumpall.c:1863 pg_dumpall.c:1886 +#, c-format +msgid "executing %s" +msgstr "çalıştırılıyor: %s" + +#: pg_restore.c:314 +#, c-format +msgid "one of -d/--dbname and -f/--file must be specified" +msgstr "-d/--dbname ve -f/--file seçeneklerinden biri belirtilmeli" + +#: pg_restore.c:323 +#, c-format +msgid "options -d/--dbname and -f/--file cannot be used together" +msgstr "-d/--dbname ve -f/--file seçenekleri birlikte kullanılamaz" + +#: pg_restore.c:349 +#, c-format +msgid "options -C/--create and -1/--single-transaction cannot be used together" +msgstr "-C/--create ve -1/--single-transaction seçenekleri birlikte kullanılamaz" + +#: pg_restore.c:363 +#, c-format +msgid "maximum number of parallel jobs is %d" +msgstr "azami paralel iÅŸ sayısı %d" + +#: pg_restore.c:372 +#, c-format +msgid "cannot specify both --single-transaction and multiple jobs" +msgstr "hem --single-transaction hem de çoklu iÅŸ (multiple jobs) aynı anda belirtilemez" + +#: pg_restore.c:414 +#, c-format +msgid "unrecognized archive format \"%s\"; please specify \"c\", \"d\", or \"t\"" +msgstr "tanımlanamayan arÅŸiv formatı \"%s\"; lütfen \"c\", \"d\", ya da \"t\" seçeneÄŸini belirtin" + +#: pg_restore.c:454 +#, c-format +msgid "errors ignored on restore: %d" +msgstr "geri yükleme sırasında es geçilen hatalar: %d" + +#: pg_restore.c:467 +#, c-format +msgid "" +"%s restores a PostgreSQL database from an archive created by pg_dump.\n" +"\n" +msgstr "" +"%s, pg_dump tarafından oluÅŸturulan PostgreSQL arÅŸivinden veritabanı geri yükleniyor.\n" +"\n" + +#: pg_restore.c:469 +#, c-format +msgid " %s [OPTION]... [FILE]\n" +msgstr " %s [SEÇENEK]... [DOSYA]\n" + +#: pg_restore.c:472 +#, c-format +msgid " -d, --dbname=NAME connect to database name\n" +msgstr " -d, --dbname=NAME baÄŸlanacak veritabanının adı\n" + +#: pg_restore.c:473 +#, c-format +msgid " -f, --file=FILENAME output file name (- for stdout)\n" +msgstr " -f, --file=DOSYA_ADI çıktı dosya adı (stdout için -)\n" + +#: pg_restore.c:474 +#, c-format +msgid " -F, --format=c|d|t backup file format (should be automatic)\n" +msgstr " -F, --format=c|d|t yedek dosya biçimi (otomatik olmalı)\n" + +#: pg_restore.c:475 +#, c-format +msgid " -l, --list print summarized TOC of the archive\n" +msgstr " -l, --list arÅŸivin kısa içeriÄŸini yaz\n" + +#: pg_restore.c:476 +#, c-format +msgid " -v, --verbose verbose mode\n" +msgstr " -v, --verbose verbose modu\n" + +#: pg_restore.c:477 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini gösterir ve sonra çıkar\n" + +#: pg_restore.c:478 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı gösterir ve sonra çıkar\n" + +#: pg_restore.c:480 +#, c-format +msgid "" +"\n" +"Options controlling the restore:\n" +msgstr "" +"\n" +"Geri güklemeyi kontrol eden seçenekler:\n" + +#: pg_restore.c:481 +#, c-format +msgid " -a, --data-only restore only the data, no schema\n" +msgstr " -a, --data-only sadece veriyi geri yükle, ÅŸemaları deÄŸil\n" + +#: pg_restore.c:483 +#, c-format +msgid " -C, --create create the target database\n" +msgstr " -C, --create hedef veritabanını oluÅŸtur\n" + +#: pg_restore.c:484 +#, c-format +msgid " -e, --exit-on-error exit on error, default is to continue\n" +msgstr " -e, --exit-on-error hata durumunda çık, varsayılan seçenek ise devam et\n" + +#: pg_restore.c:485 +#, c-format +msgid " -I, --index=NAME restore named index\n" +msgstr " -I, --index=AD adı geçen indeksi geri yükle\n" + +#: pg_restore.c:486 +#, c-format +msgid " -j, --jobs=NUM use this many parallel jobs to restore\n" +msgstr " -j, --jobs=SAYI geri yükleme için belirtilen sayı kadar paralel süreç kullan\n" + +#: pg_restore.c:487 +#, c-format +msgid "" +" -L, --use-list=FILENAME use table of contents from this file for\n" +" selecting/ordering output\n" +msgstr "" +" -L, --use-list=DOSYAADI çıktıyı seçmek/sıralamak için\n" +" bu dosyadaki içindekiler tablosunu kullan\n" + +#: pg_restore.c:489 +#, c-format +msgid " -n, --schema=NAME restore only objects in this schema\n" +msgstr " -n, --schema=AD sadece bu ÅŸemaya ait nesneleri geri yükle\n" + +#: pg_restore.c:490 +#, c-format +msgid " -N, --exclude-schema=NAME do not restore objects in this schema\n" +msgstr " -N, --exclude-schema=AD bu ÅŸemadaki nesneleri geri yükleme\n" + +#: pg_restore.c:492 +#, c-format +msgid " -P, --function=NAME(args) restore named function\n" +msgstr " -P, --function=NAME(args) adı geçen fonksiyonu geri yükle\n" + +#: pg_restore.c:493 +#, c-format +msgid " -s, --schema-only restore only the schema, no data\n" +msgstr " -s, --schema-only sadece ÅŸemayı geri yükle, veriyi deÄŸil\n" + +#: pg_restore.c:494 +#, c-format +msgid " -S, --superuser=NAME superuser user name to use for disabling triggers\n" +msgstr " -S, --superuser=AD tetikleyicileri (trigger) devre dışı bırakmak için kullanılacak superuser kullanıcı adı\n" + +#: pg_restore.c:495 +#, c-format +msgid " -t, --table=NAME restore named relation (table, view, etc.)\n" +msgstr " -t, --table=AD adı geçen nesneyi (tablo, görünüm, vb.) geri yükle\n" + +#: pg_restore.c:496 +#, c-format +msgid " -T, --trigger=NAME restore named trigger\n" +msgstr " -T, --trigger=AD adı geçen tetikleyiciyi geri yükle\n" + +#: pg_restore.c:497 +#, c-format +msgid " -x, --no-privileges skip restoration of access privileges (grant/revoke)\n" +msgstr " -x, --no-privileges eriÅŸim haklarının geri yüklemesini atla (grant/revoke)\n" + +#: pg_restore.c:498 +#, c-format +msgid " -1, --single-transaction restore as a single transaction\n" +msgstr " -1, --single-transaction tek bir transaction olarak geri yükle\n" + +#: pg_restore.c:500 +#, c-format +msgid " --enable-row-security enable row security\n" +msgstr " --enable-row-security satır güvenliÄŸini etkinleÅŸtir\n" + +#: pg_restore.c:502 +#, c-format +msgid " --no-comments do not restore comments\n" +msgstr " --no-comments açıklamaları (comments) yedekleme\n" + +#: pg_restore.c:503 +#, c-format +msgid "" +" --no-data-for-failed-tables do not restore data of tables that could not be\n" +" created\n" +msgstr "" +" --no-data-for-failed-tables oluÅŸturulamayan tabloların verilerini geri\n" +" yükleme\n" + +#: pg_restore.c:505 +#, c-format +msgid " --no-publications do not restore publications\n" +msgstr " --no-publications yayınları geri yükleme\n" + +#: pg_restore.c:506 +#, c-format +msgid " --no-security-labels do not restore security labels\n" +msgstr " --no-security-labels güvenlik etiketlerini geri yükleme\n" + +#: pg_restore.c:507 +#, c-format +msgid " --no-subscriptions do not restore subscriptions\n" +msgstr " --no-subscriptions abonelikleri geri yükleme\n" + +#: pg_restore.c:508 +#, c-format +msgid " --no-tablespaces do not restore tablespace assignments\n" +msgstr " --no-tablespaces tablespace atamalarını geri yükleme\n" + +#: pg_restore.c:509 +#, c-format +msgid " --section=SECTION restore named section (pre-data, data, or post-data)\n" +msgstr " --section=BÖLÜM belirtilen bölümü yedekle (pre-data, data, veya post-data)\n" + +#: pg_restore.c:522 +#, c-format +msgid " --role=ROLENAME do SET ROLE before restore\n" +msgstr " --role=ROL ADI geri yüklemeden önce SET ROLE iÅŸlemini gerçekleÅŸtir\n" + +#: pg_restore.c:524 +#, c-format +msgid "" +"\n" +"The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified\n" +"multiple times to select multiple objects.\n" +msgstr "" +"\n" +"-I, -n, -N, -P, -t, -T, ve --section seçenekleri, çoklu nesnelerin seçilmesi için\n" +"birden fazla kez kullanılabilir ve belirtilebilir\n" +"\n" + +#: pg_restore.c:527 +#, c-format +msgid "" +"\n" +"If no input file name is supplied, then standard input is used.\n" +"\n" +msgstr "" +"\n" +"EÄŸer giriÅŸ dosya adı verilmemiÅŸse, standart giriÅŸ akımı (stdin) kulanılacaktır.\n" +"\n" + +#~ msgid "reading extended statistics for table \"%s.%s\"\n" +#~ msgstr "\"%s.%s\" tablosunun geniÅŸletilmiÅŸ istatistikleri okunuyor\n" + +#~ msgid "%s: could not parse ACL list (%s) for database \"%s\"\n" +#~ msgstr "%1$s: \"%3$s\" veritabanı için ACL (%2$s) listesi ayrıştırılamadı\n" + +#~ msgid "Got %d rows instead of one from: %s" +#~ msgstr "%2$s sorgusundan bir yerine %1$d satır alındı" + +#~ msgid "No rows found for enum" +#~ msgstr "Enum için veri bulunamadı" + +#~ msgid "INSERT (-d, -D) and OID (-o) options cannot be used together\n" +#~ msgstr "INSERT (-d, -D) ve OID (-o)seçenekleri beraber kullanılamaz\n" + +#~ msgid "" +#~ " --disable-dollar-quoting\n" +#~ " disable dollar quoting, use SQL standard quoting\n" +#~ msgstr "" +#~ " --disable-dollar-quoting\n" +#~ " dollar quoting kullanmayı engelle, standart SQL quoting kullan\n" + +#~ msgid " -x, --no-privileges do not dump privileges (grant/revoke)\n" +#~ msgstr " -x, --no-privileges yetkileri aktarmayı engelle (grant/revoke)\n" + +#~ msgid " -s, --schema-only dump only the schema, no data\n" +#~ msgstr " -s, --schema-only sadece ÅŸemayı dump et, veriyi etme\n" + +#~ msgid " -o, --oids include OIDs in dump\n" +#~ msgstr " -o, --oids dump içinde OIDleri de içer\n" + +#~ msgid " -D, --column-inserts dump data as INSERT commands with column names\n" +#~ msgstr " -D, --column-inserts veriyi kolon adları ile insert komutu olarak dump et.\n" + +#~ msgid " -d, --inserts dump data as INSERT, rather than COPY, commands\n" +#~ msgstr " -d, --inserts verileri COPYkomutları yerine INSERT olarak dump et\n" + +#~ msgid " -a, --data-only dump only the data, not the schema\n" +#~ msgstr " -a, --data-only sadece veriyi dump eder, ÅŸemayı etmez\n" + +#~ msgid "" +#~ " -i, --ignore-version proceed even when server version mismatches\n" +#~ " pg_dumpall version\n" +#~ msgstr "" +#~ " -i, --ignore-version sunucunun sürümü uyuÅŸmadığı durumda\n" +#~ " bile devam et\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SESSION AUTHORIZATION commands instead of\n" +#~ " OWNER TO commands\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " OWNER TO komutun yerine\n" +#~ " SESSION AUTHORIZATION komutunu kullan\n" + +#~ msgid " -c, --clean clean (drop) schema prior to create\n" +#~ msgstr " -c, --clean ÅŸemayı yaratmadan önce onu temizle (kaldır)\n" + +#~ msgid " -i, --ignore-version proceed even when server version mismatches\n" +#~ msgstr " -i, --ignore-version sunucunun sürümü uyuÅŸmadığında bile devam et\n" + +#~ msgid "%s: no result from server\n" +#~ msgstr "%s: sunucudan sonuç gelmedi\n" + +#~ msgid "aborting because of version mismatch (Use the -i option to proceed anyway.)\n" +#~ msgstr "sürüm uyuÅŸmazlığı yüzünden iÅŸlem duruduruldu (Buna raÄŸmen devam etmek için -i seçeneÄŸi kullanın).\n" + +#~ msgid "archive format is %d\n" +#~ msgstr "%d arÅŸiv biçimi\n" + +#~ msgid "expected %d triggers on table \"%s\" but found %d\n" +#~ msgstr "\"%2$s\" tablosu zerinde %1$d tetikleyici beklenirken %3$d bulundu\n" + +#~ msgid "" +#~ " -S, --superuser=NAME specify the superuser user name to use in\n" +#~ " plain text format\n" +#~ msgstr "" +#~ " -S, --superuser=NAME düz metin biçiminde kullanılacak superuser\n" +#~ " kullanıcısının adı\n" + +#~ msgid " -c, --clean clean (drop) schema prior to create\n" +#~ msgstr " -c, --clean ÅŸemayı oluÅŸturmadan önce onu temizle (kaldır)\n" + +#~ msgid "" +#~ " -i, --ignore-version proceed even when server version mismatches\n" +#~ " pg_dump version\n" +#~ msgstr "" +#~ " -i, --ignore-version sunucunun sürümü ile pg_dump'ın sürümü eÅŸleÅŸmezse\n" +#~ " bile devam et\n" + +#~ msgid "User name: " +#~ msgstr "Kullanıcı adı: " + +#~ msgid "requested %d byte, got %d from lookahead and %d from file\n" +#~ msgid_plural "requested %d bytes, got %d from lookahead and %d from file\n" +#~ msgstr[0] "%d bayt istenildi, lookahead'denn %d, dosyadan ise %d alındı\n" +#~ msgstr[1] "%d bayt istenildi, lookahead'denn %d, dosyadan ise %d alındı\n" + +#~ msgid "read %lu byte into lookahead buffer\n" +#~ msgid_plural "read %lu bytes into lookahead buffer\n" +#~ msgstr[0] "lookahead artalanına %lu bayt okundu\n" +#~ msgstr[1] "lookahead artalanına %lu bayt okundu\n" + +#~ msgid "query returned %d rows instead of one: %s\n" +#~ msgstr "sorgu bir yerine %d satır döndirdi: %s\n" + +#~ msgid "compression support is disabled in this format\n" +#~ msgstr "bu formatta sıkıştırma desteÄŸi devre dışı bırakılmıştır\n" + +#~ msgid "dumping a specific TOC data block out of order is not supported without ID on this input stream (fseek required)\n" +#~ msgstr "sıra dışı TOC veri blokun aktarılması, giriÅŸ akımında ID olmadan desteklenmemektedir (fseek() gerekir)\n" + +#~ msgid "no label definitions found for enum ID %u\n" +#~ msgstr "%u enum ID'si için etiket tanımları bulunamadı \n" + +#~ msgid "saving large object comments\n" +#~ msgstr "large object açıklamaları kaydediliyor\n" + +#~ msgid "dumpBlobs(): could not open large object: %s" +#~ msgstr "dumpBlobs(): large object açılamadı: %s" + +#~ msgid "cannot reopen non-seekable file\n" +#~ msgstr "aranamayan dosya yeniden açılamadı\n" + +#~ msgid "cannot reopen stdin\n" +#~ msgstr "stdin açılamıyor\n" + +#~ msgid "query returned no rows: %s\n" +#~ msgstr "sorgu hiçbir satır döndürmedi: %s\n" + +#~ msgid "%s: invalid -X option -- %s\n" +#~ msgstr "%s: geçersiz -X seçeneÄŸi -- %s\n" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" + +#~ msgid "%s: could not parse version \"%s\"\n" +#~ msgstr "%s: \"%s\" sürüm bilgisi ayrıştırılamadı\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: yetersiz bellek\n" + +#~ msgid "" +#~ " --use-set-session-authorization\n" +#~ " use SET SESSION AUTHORIZATION commands instead of\n" +#~ " ALTER OWNER commands to set ownership\n" +#~ msgstr "" +#~ " --use-set-session-authorization\n" +#~ " SahipliÄŸi ayarlamak için ALTER OWNER komutunun yerine\n" +#~ " SET SESSION AUTHORIZATION komutunu kullan\n" + +#~ msgid " --disable-triggers disable triggers during data-only restore\n" +#~ msgstr " --disable-triggers sadece veri geri yüklemede tetikleyicileri devre dışı bırak\n" + +#~ msgid " -O, --no-owner skip restoration of object ownership\n" +#~ msgstr " -O, --no-owner nesne sahipliÄŸini ayarlayan komutlarının oluÅŸturmasını engelle\n" + +#~ msgid " -c, --clean clean (drop) database objects before recreating\n" +#~ msgstr " -c, --clean veritabanı nesnelerini yeniden yaratmadan önce onları kaldır (sil)\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini gösterir ve çıkar\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı gösterir ve çıkar\n" + +#~ msgid "mismatch in actual vs. predicted file position (%s vs. %s)\n" +#~ msgstr "gerçek ile beklenilen dosya pozisyonunda uyumsuzluk (%s ile %s)\n" + +#~ msgid "could not output padding at end of tar member\n" +#~ msgstr "tar öğesinin arkasına doldurma alanı eklenemedi\n" + +#~ msgid "archive member too large for tar format\n" +#~ msgstr "tar biçimi için arÅŸiv öğesi çok büyük\n" + +#~ msgid "could not write null block at end of tar archive\n" +#~ msgstr "arÅŸivin sonunda null blok yazılamadı\n" + +#~ msgid "restoring large object OID %u\n" +#~ msgstr "large-object %u geri yükleniyor\n" + +#~ msgid "invalid COPY statement -- could not find \"from stdin\" in string \"%s\" starting at position %lu\n" +#~ msgstr "geçersiz COPY komutu -- \"%s\" satırında %lu pozisyonunda \"from stdin\" bulunamadı\n" + +#~ msgid "invalid COPY statement -- could not find \"copy\" in string \"%s\"\n" +#~ msgstr "geçersiz COPY komutu -- \"%s\" satırında \"copy\" bulunamadı\n" + +#~ msgid "could not close large object file\n" +#~ msgstr "large object dosyası kapatılamadı\n" + +#~ msgid "could not open large object TOC for output: %s\n" +#~ msgstr "çıktı için large object TOC açılamadı: %s\n" + +#~ msgid "could not write byte\n" +#~ msgstr "byte yazılamadı\n" + +#~ msgid "could not open large object TOC for input: %s\n" +#~ msgstr "girdi için large object TOC açılamadı: %s\n" + +#~ msgid "could not close data file after reading\n" +#~ msgstr "veri dosyası okunduktan sonra kapatılamadı\n" + +#~ msgid "" +#~ "WARNING:\n" +#~ " This format is for demonstration purposes; it is not intended for\n" +#~ " normal use. Files will be written in the current working directory.\n" +#~ msgstr "" +#~ "UYARI:\n" +#~ " Bu biçim sadece demo amaçlıdır. Normal kullanım için\n" +#~ " denenmemelidir. Dosyalar mecvut çalışma dizinine yazılacaktır.\n" + +#~ msgid "file archiver" +#~ msgstr "dosya arÅŸivleyicisi" + +#~ msgid "could not write byte: %s\n" +#~ msgstr "bayt yazılamadı: %s\n" + +#~ msgid "could not find slot of finished worker\n" +#~ msgstr "bitmiÅŸ sürecin yuvasu bulunamadı\n" + +#~ msgid "could not create worker thread: %s\n" +#~ msgstr "işçi threadi yaratılamadı: %s\n" + +#~ msgid "parallel_restore should not return\n" +#~ msgstr "parallel_restore dönmemeli\n" + +#~ msgid "worker process crashed: status %d\n" +#~ msgstr "worker sürecii çöktü: Durum %d\n" + +#~ msgid "could not write to custom output routine\n" +#~ msgstr "kullanıcı tanımlı çıktı yordamına yazma hatası\n" + +#~ msgid "setting owner and privileges for %s %s\n" +#~ msgstr "%s %s için sahiplik ve izinler ayarlanıyor\n" + +#~ msgid "-C and -c are incompatible options\n" +#~ msgstr "-C ve -c seçenekler bir arada kullanılamaz\n" + +#~ msgid "cannot duplicate null pointer\n" +#~ msgstr "null pointer dump edilemez\n" + +#~ msgid "SQL command failed\n" +#~ msgstr "SQL komutu baÅŸarısız\n" + +#~ msgid "query to get data of sequence \"%s\" returned name \"%s\"\n" +#~ msgstr "\"%s\" sequence verisini getirecek sorgu \"%s\" adını getirdi\n" + +#~ msgid "found more than one entry for pg_indexes in pg_class\n" +#~ msgstr "pg_class içinde pg_indexes için birden çok kayıt bulundu\n" + +#~ msgid "could not find entry for pg_indexes in pg_class\n" +#~ msgstr "pg_class içinde pg_indexes için kayıt bulunamadı\n" + +#~ msgid "found more than one pg_database entry for this database\n" +#~ msgstr "bu veritabanı için birden fazla pg_database kaydı bulundu\n" + +#~ msgid "missing pg_database entry for this database\n" +#~ msgstr "bu veritabanı için pg_database kaydı bulunamadı\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject_metadata.relfrozenxid\n" +#~ msgstr "dumpDatabase(): pg_largeobject_metadata.relfrozenxid bulunamadı\n" + +#~ msgid "dumpDatabase(): could not find pg_largeobject.relfrozenxid\n" +#~ msgstr "dumpDatabase(): pg_largeobject.relfrozenxid bulunamadı\n" + +#~ msgid "query returned more than one (%d) pg_database entry for database \"%s\"\n" +#~ msgstr "Sorgu, birden fazla (%d) sonucu \"%s\" veritabanının pg_database kaydı için döndürdü\n" + +#~ msgid "missing pg_database entry for database \"%s\"\n" +#~ msgstr "\"%s\" veritabanı için pg_database kaydı bulunamadı\n" + +#~ msgid "server version must be at least 7.3 to use schema selection switches\n" +#~ msgstr "ÅŸema seçim anahtarlarını kullanmak için sunucu sürümü 7.3 ya da daha yüksek olmalıdır\n" + +#~ msgid "*** aborted because of error\n" +#~ msgstr "*** hata nedeniyle durduruldu\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini ver ve çık\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve sonra çık\n" + +#~ msgid "could not parse version string \"%s\"\n" +#~ msgstr "\"%s\" sürüm bilgisi ayrıştırılamadı\n" + +#~ msgid "could not open output file \"%s\" for writing\n" +#~ msgstr "\"%s\" çıktı dosyası yazmak için açılamadı\n" + +#~ msgid "%s: invalid number of parallel jobs\n" +#~ msgstr "%s: parallel iÅŸ sayısı geçersiz\n" + +#~ msgid "%s: options -c/--clean and -a/--data-only cannot be used together\n" +#~ msgstr "%s: -c/--clean ve -a/--data-only seçenekleri aynı anda kullanılamaz\n" + +#~ msgid "%s: options -s/--schema-only and -a/--data-only cannot be used together\n" +#~ msgstr "%s: -s/--schema-only ve -a/--data-only seçenekleri aynı anda kullanılamaz\n" + +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: sorgu ÅŸu idi: %s\n" + +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: sorgu baÅŸarısız oldu: %s" + +#~ msgid "%s: executing %s\n" +#~ msgstr "%s: %s yürütülüyor\n" + +#~ msgid "%s: invalid client encoding \"%s\" specified\n" +#~ msgstr "%s: belirtilen \"%s\" istemci dil kodlaması geçersiz\n" + +#~ msgid "%s: option --if-exists requires option -c/--clean\n" +#~ msgstr "%s: --if-exists seçeneÄŸi -c/--clean seçeneÄŸini gerektirir\n" + +#~ msgid "sorter" +#~ msgstr "sorter" + +#~ msgid "WARNING: could not parse reloptions array\n" +#~ msgstr "UYARI: reloptions dizisi ayrıştırılamadı\n" + +#~ msgid "schema with OID %u does not exist\n" +#~ msgstr "OID %u olan ÅŸema mevcut deÄŸil\n" + +#~ msgid "(The INSERT command cannot set OIDs.)\n" +#~ msgstr "(INSERT komutu OIDleri ayarlayamaz.)\n" + +#~ msgid "options --inserts/--column-inserts and -o/--oids cannot be used together\n" +#~ msgstr "--inserts/--column-inserts ve -o/--oids beraber kullanılamazlar\n" + +#~ msgid "TOC Entry %s at %s (length %s, checksum %d)\n" +#~ msgstr "%2$s adresinde %1$s TOC GiriÅŸi (uzunluk %3$s, checksum %4$d)\n" + +#~ msgid "skipping tar member %s\n" +#~ msgstr "%s tar öğesi atlandı\n" + +#~ msgid "now at file position %s\n" +#~ msgstr "ÅŸu an dosyanın %s yerinde\n" + +#~ msgid "moving from position %s to next member at file position %s\n" +#~ msgstr "dosya içerisinde %s yerinden bir sonraki %s yerine geçiÅŸ yapılamıyor\n" + +#~ msgid "tar archiver" +#~ msgstr "tar archiver" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini oluÅŸturulamadı: %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini okunamıyor: %s\n" + +#~ msgid "directory archiver" +#~ msgstr "directory archiver" + +#~ msgid "COPY failed for table \"%s\": %s" +#~ msgstr "COPY \"%s\" tablosu için baÅŸarısız oldu: %s" + +#~ msgid "%s: %s Command was: %s\n" +#~ msgstr "" +#~ "%s: %s Komut ÅŸuydu: %s\n" +#~ "\n" + +#~ msgid "archiver (db)" +#~ msgstr "archiver (db)" + +#~ msgid "custom archiver" +#~ msgstr "custom archiver" + +#~ msgid "reducing dependencies for %d\n" +#~ msgstr "%d için bağımlılıklar azaltılıyor\n" + +#~ msgid "transferring dependency %d -> %d to %d\n" +#~ msgstr "%d -> %d bağımlılığı %d olarak aktarılıyor\n" + +#~ msgid "no item ready\n" +#~ msgstr "hiç bir öğe hazır deÄŸil\n" + +#~ msgid "entering restore_toc_entries_postfork\n" +#~ msgstr "restore_toc_entries_postfork'a giriliyor\n" + +#~ msgid "entering restore_toc_entries_parallel\n" +#~ msgstr "restore_toc_entries_parallel'e giriliyor\n" + +#~ msgid "entering restore_toc_entries_prefork\n" +#~ msgstr "restore_toc_entries_prefork'a giriliyor\n" + +#~ msgid "could not set default_tablespace to %s: %s" +#~ msgstr "default_tablespace %s olarak deÄŸiÅŸtirilemedi: %s" + +#~ msgid "could not set search_path to \"%s\": %s" +#~ msgstr "search_path \"%s\" olarak deÄŸiÅŸtirilemedi: %s" + +#~ msgid "could not set default_with_oids: %s" +#~ msgstr "default_with_oids ayarlanamıyor: %s" + +#~ msgid "read TOC entry %d (ID %d) for %s %s\n" +#~ msgstr "%3$s %4$s için TOC öğe %1$d (ID %2$d) okunuyor\n" + +#~ msgid "allocating AH for %s, format %d\n" +#~ msgstr "%s için AH ayırılıyor, biçim %d\n" + +#~ msgid "attempting to ascertain archive format\n" +#~ msgstr "arÅŸiv formatı doÄŸrulanmaya çalışılıyor\n" + +#~ msgid "-C and -1 are incompatible options\n" +#~ msgstr "-C ve -1 uyumsuz seçeneklerdir\n" + +#~ msgid "archiver" +#~ msgstr "archiver" + +#~ msgid "parallel archiver" +#~ msgstr "paralel arÅŸivleyici" + +#~ msgid "compress_io" +#~ msgstr "compress_io" + +#~ msgid "child process was terminated by signal %s" +#~ msgstr "alt süreç %s sinyali tarafından sonlandırılmıştır" + +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "symbolic link \"%s\" okuma hatası" + +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %s" diff --git a/src/bin/pg_dump/t/001_basic.pl b/src/bin/pg_dump/t/001_basic.pl index 257fb08ccb7..9ca8a8e6088 100644 --- a/src/bin/pg_dump/t/001_basic.pl +++ b/src/bin/pg_dump/t/001_basic.pl @@ -4,7 +4,7 @@ use Config; use PostgresNode; use TestLib; -use Test::More tests => 68; +use Test::More tests => 74; my $tempdir = TestLib::tempdir; my $tempdir_short = TestLib::tempdir_short; @@ -30,117 +30,136 @@ command_fails_like( [ 'pg_dump', 'qqq', 'abc' ], - qr/\Qpg_dump: too many command-line arguments (first is "abc")\E/, - 'pg_dump: too many command-line arguments (first is "asd")'); + qr/\Qpg_dump: error: too many command-line arguments (first is "abc")\E/, + 'pg_dump: too many command-line arguments'); command_fails_like( [ 'pg_restore', 'qqq', 'abc' ], - qr/\Qpg_restore: too many command-line arguments (first is "abc")\E/, - 'pg_restore too many command-line arguments (first is "abc")'); + qr/\Qpg_restore: error: too many command-line arguments (first is "abc")\E/, + 'pg_restore: too many command-line arguments'); command_fails_like( [ 'pg_dumpall', 'qqq', 'abc' ], - qr/\Qpg_dumpall: too many command-line arguments (first is "qqq")\E/, - 'pg_dumpall: too many command-line arguments (first is "qqq")'); + qr/\Qpg_dumpall: error: too many command-line arguments (first is "qqq")\E/, + 'pg_dumpall: too many command-line arguments'); command_fails_like( [ 'pg_dump', '-s', '-a' ], -qr/\Qpg_dump: options -s\/--schema-only and -a\/--data-only cannot be used together\E/, -'pg_dump: options -s/--schema-only and -a/--data-only cannot be used together' + qr/\Qpg_dump: error: options -s\/--schema-only and -a\/--data-only cannot be used together\E/, + 'pg_dump: options -s/--schema-only and -a/--data-only cannot be used together' ); command_fails_like( - [ 'pg_restore', '-s', '-a' ], -qr/\Qpg_restore: options -s\/--schema-only and -a\/--data-only cannot be used together\E/, -'pg_restore: options -s/--schema-only and -a/--data-only cannot be used together' + ['pg_restore'], + qr{\Qpg_restore: error: one of -d/--dbname and -f/--file must be specified\E}, + 'pg_restore: error: one of -d/--dbname and -f/--file must be specified'); + +command_fails_like( + [ 'pg_restore', '-s', '-a', '-f -' ], + qr/\Qpg_restore: error: options -s\/--schema-only and -a\/--data-only cannot be used together\E/, + 'pg_restore: options -s/--schema-only and -a/--data-only cannot be used together' ); command_fails_like( [ 'pg_restore', '-d', 'xxx', '-f', 'xxx' ], -qr/\Qpg_restore: options -d\/--dbname and -f\/--file cannot be used together\E/, + qr/\Qpg_restore: error: options -d\/--dbname and -f\/--file cannot be used together\E/, 'pg_restore: options -d/--dbname and -f/--file cannot be used together'); command_fails_like( [ 'pg_dump', '-c', '-a' ], -qr/\Qpg_dump: options -c\/--clean and -a\/--data-only cannot be used together\E/, + qr/\Qpg_dump: error: options -c\/--clean and -a\/--data-only cannot be used together\E/, 'pg_dump: options -c/--clean and -a/--data-only cannot be used together'); command_fails_like( - [ 'pg_restore', '-c', '-a' ], -qr/\Qpg_restore: options -c\/--clean and -a\/--data-only cannot be used together\E/, -'pg_restore: options -c/--clean and -a/--data-only cannot be used together'); - -command_fails_like( - [ 'pg_dump', '--inserts', '-o' ], -qr/\Qpg_dump: options --inserts\/--column-inserts and -o\/--oids cannot be used together\E/, -'pg_dump: options --inserts/--column-inserts and -o/--oids cannot be used together' + [ 'pg_restore', '-c', '-a', '-f -' ], + qr/\Qpg_restore: error: options -c\/--clean and -a\/--data-only cannot be used together\E/, + 'pg_restore: options -c/--clean and -a/--data-only cannot be used together' ); command_fails_like( [ 'pg_dump', '--if-exists' ], - qr/\Qpg_dump: option --if-exists requires option -c\/--clean\E/, + qr/\Qpg_dump: error: option --if-exists requires option -c\/--clean\E/, 'pg_dump: option --if-exists requires option -c/--clean'); command_fails_like( [ 'pg_dump', '-j3' ], - qr/\Qpg_dump: parallel backup only supported by the directory format\E/, + qr/\Qpg_dump: error: parallel backup only supported by the directory format\E/, 'pg_dump: parallel backup only supported by the directory format'); command_fails_like( [ 'pg_dump', '-j', '-1' ], - qr/\Qpg_dump: invalid number of parallel jobs\E/, + qr/\Qpg_dump: error: invalid number of parallel jobs\E/, 'pg_dump: invalid number of parallel jobs'); command_fails_like( [ 'pg_dump', '-F', 'garbage' ], - qr/\Qpg_dump: invalid output format\E/, + qr/\Qpg_dump: error: invalid output format\E/, 'pg_dump: invalid output format'); command_fails_like( - [ 'pg_restore', '-j', '-1' ], - qr/\Qpg_restore: invalid number of parallel jobs\E/, + [ 'pg_restore', '-j', '-1', '-f -' ], + qr/\Qpg_restore: error: invalid number of parallel jobs\E/, 'pg_restore: invalid number of parallel jobs'); command_fails_like( - [ 'pg_restore', '--single-transaction', '-j3' ], -qr/\Qpg_restore: cannot specify both --single-transaction and multiple jobs\E/, + [ 'pg_restore', '--single-transaction', '-j3', '-f -' ], + qr/\Qpg_restore: error: cannot specify both --single-transaction and multiple jobs\E/, 'pg_restore: cannot specify both --single-transaction and multiple jobs'); command_fails_like( [ 'pg_dump', '-Z', '-1' ], - qr/\Qpg_dump: compression level must be in range 0..9\E/, + qr/\Qpg_dump: error: compression level must be in range 0..9\E/, 'pg_dump: compression level must be in range 0..9'); command_fails_like( - [ 'pg_restore', '--if-exists' ], - qr/\Qpg_restore: option --if-exists requires option -c\/--clean\E/, + [ 'pg_restore', '--if-exists', '-f -' ], + qr/\Qpg_restore: error: option --if-exists requires option -c\/--clean\E/, 'pg_restore: option --if-exists requires option -c/--clean'); command_fails_like( - [ 'pg_restore', '-F', 'garbage' ], - qr/\Qpg_restore: unrecognized archive format "garbage";\E/, + [ 'pg_restore', '-f -', '-F', 'garbage' ], + qr/\Qpg_restore: error: unrecognized archive format "garbage";\E/, 'pg_dump: unrecognized archive format'); +command_fails_like( + [ 'pg_dump', '--on-conflict-do-nothing' ], + qr/pg_dump: error: option --on-conflict-do-nothing requires option --inserts, --rows-per-insert, or --column-inserts/, + 'pg_dump: --on-conflict-do-nothing requires --inserts, --rows-per-insert, --column-inserts' +); + # pg_dumpall command-line argument checks command_fails_like( [ 'pg_dumpall', '-g', '-r' ], -qr/\Qpg_dumpall: options -g\/--globals-only and -r\/--roles-only cannot be used together\E/, -'pg_dumpall: options -g/--globals-only and -r/--roles-only cannot be used together' + qr/\Qpg_dumpall: error: options -g\/--globals-only and -r\/--roles-only cannot be used together\E/, + 'pg_dumpall: options -g/--globals-only and -r/--roles-only cannot be used together' ); command_fails_like( [ 'pg_dumpall', '-g', '-t' ], -qr/\Qpg_dumpall: options -g\/--globals-only and -t\/--tablespaces-only cannot be used together\E/, -'pg_dumpall: options -g/--globals-only and -t/--tablespaces-only cannot be used together' + qr/\Qpg_dumpall: error: options -g\/--globals-only and -t\/--tablespaces-only cannot be used together\E/, + 'pg_dumpall: options -g/--globals-only and -t/--tablespaces-only cannot be used together' ); command_fails_like( [ 'pg_dumpall', '-r', '-t' ], -qr/\Qpg_dumpall: options -r\/--roles-only and -t\/--tablespaces-only cannot be used together\E/, -'pg_dumpall: options -r/--roles-only and -t/--tablespaces-only cannot be used together' + qr/\Qpg_dumpall: error: options -r\/--roles-only and -t\/--tablespaces-only cannot be used together\E/, + 'pg_dumpall: options -r/--roles-only and -t/--tablespaces-only cannot be used together' ); command_fails_like( [ 'pg_dumpall', '--if-exists' ], - qr/\Qpg_dumpall: option --if-exists requires option -c\/--clean\E/, + qr/\Qpg_dumpall: error: option --if-exists requires option -c\/--clean\E/, 'pg_dumpall: option --if-exists requires option -c/--clean'); + +command_fails_like( + [ 'pg_restore', '-C', '-1', '-f -' ], + qr/\Qpg_restore: error: options -C\/--create and -1\/--single-transaction cannot be used together\E/, + 'pg_restore: options -C\/--create and -1\/--single-transaction cannot be used together' +); + +# also fails for -r and -t, but it seems pointless to add more tests for those. +command_fails_like( + [ 'pg_dumpall', '--exclude-database=foo', '--globals-only' ], + qr/\Qpg_dumpall: error: option --exclude-database cannot be used together with -g\/--globals-only\E/, + 'pg_dumpall: option --exclude-database cannot be used together with -g/--globals-only' +); diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl index 25852b903c0..4712e3a9581 100644 --- a/src/bin/pg_dump/t/002_pg_dump.pl +++ b/src/bin/pg_dump/t/002_pg_dump.pl @@ -50,7 +50,9 @@ restore_cmd => [ 'pg_restore', '-Fc', '--verbose', "--file=$tempdir/binary_upgrade.sql", - "$tempdir/binary_upgrade.dump", ], }, + "$tempdir/binary_upgrade.dump", + ], + }, clean => { dump_cmd => [ 'pg_dump', @@ -58,7 +60,8 @@ "--file=$tempdir/clean.sql", '-c', '-d', 'postgres', # alternative way to specify database - ], }, + ], + }, clean_if_exists => { dump_cmd => [ 'pg_dump', @@ -67,12 +70,16 @@ '-c', '--if-exists', '--encoding=UTF8', # no-op, just tests that option is accepted - 'postgres', ], }, + 'postgres', + ], + }, column_inserts => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/column_inserts.sql", '-a', - '--column-inserts', 'postgres', ], }, + '--column-inserts', 'postgres', + ], + }, createdb => { dump_cmd => [ 'pg_dump', @@ -81,7 +88,9 @@ '-C', '-R', # no-op, just for testing '-v', - 'postgres', ], }, + 'postgres', + ], + }, data_only => { dump_cmd => [ 'pg_dump', @@ -91,78 +100,102 @@ '--superuser=test_superuser', '--disable-triggers', '-v', # no-op, just make sure it works - 'postgres', ], }, + 'postgres', + ], + }, defaults => { dump_cmd => [ 'pg_dump', '--no-sync', '-f', "$tempdir/defaults.sql", - 'postgres', ], }, + 'postgres', + ], + }, defaults_no_public => { database => 'regress_pg_dump_test', dump_cmd => [ 'pg_dump', '--no-sync', '-f', "$tempdir/defaults_no_public.sql", - 'regress_pg_dump_test', ], }, + 'regress_pg_dump_test', + ], + }, defaults_no_public_clean => { database => 'regress_pg_dump_test', dump_cmd => [ 'pg_dump', '--no-sync', '-c', '-f', "$tempdir/defaults_no_public_clean.sql", - 'regress_pg_dump_test', ], }, + 'regress_pg_dump_test', + ], + }, # Do not use --no-sync to give test coverage for data sync. defaults_custom_format => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '-Fc', '-Z6', - "--file=$tempdir/defaults_custom_format.dump", 'postgres', ], + "--file=$tempdir/defaults_custom_format.dump", 'postgres', + ], restore_cmd => [ 'pg_restore', '-Fc', "--file=$tempdir/defaults_custom_format.sql", - "$tempdir/defaults_custom_format.dump", ], }, + "$tempdir/defaults_custom_format.dump", + ], + }, # Do not use --no-sync to give test coverage for data sync. defaults_dir_format => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '-Fd', - "--file=$tempdir/defaults_dir_format", 'postgres', ], + "--file=$tempdir/defaults_dir_format", 'postgres', + ], restore_cmd => [ 'pg_restore', '-Fd', "--file=$tempdir/defaults_dir_format.sql", - "$tempdir/defaults_dir_format", ], }, + "$tempdir/defaults_dir_format", + ], + }, # Do not use --no-sync to give test coverage for data sync. defaults_parallel => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '-Fd', '-j2', "--file=$tempdir/defaults_parallel", - 'postgres', ], + 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/defaults_parallel.sql", - "$tempdir/defaults_parallel", ], }, + "$tempdir/defaults_parallel", + ], + }, # Do not use --no-sync to give test coverage for data sync. defaults_tar_format => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '-Ft', - "--file=$tempdir/defaults_tar_format.tar", 'postgres', ], + "--file=$tempdir/defaults_tar_format.tar", 'postgres', + ], restore_cmd => [ 'pg_restore', '--format=tar', "--file=$tempdir/defaults_tar_format.sql", - "$tempdir/defaults_tar_format.tar", ], }, + "$tempdir/defaults_tar_format.tar", + ], + }, exclude_dump_test_schema => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/exclude_dump_test_schema.sql", - '--exclude-schema=dump_test', 'postgres', ], }, + '--exclude-schema=dump_test', 'postgres', + ], + }, exclude_test_table => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/exclude_test_table.sql", - '--exclude-table=dump_test.test_table', 'postgres', ], }, + '--exclude-table=dump_test.test_table', 'postgres', + ], + }, exclude_test_table_data => { dump_cmd => [ 'pg_dump', @@ -170,39 +203,61 @@ "--file=$tempdir/exclude_test_table_data.sql", '--exclude-table-data=dump_test.test_table', '--no-unlogged-table-data', - 'postgres', ], }, + 'postgres', + ], + }, pg_dumpall_globals => { dump_cmd => [ 'pg_dumpall', '-v', "--file=$tempdir/pg_dumpall_globals.sql", - '-g', '--no-sync', ], }, + '-g', '--no-sync', + ], + }, pg_dumpall_globals_clean => { dump_cmd => [ 'pg_dumpall', "--file=$tempdir/pg_dumpall_globals_clean.sql", - '-g', '-c', '--no-sync', ], }, + '-g', '-c', '--no-sync', + ], + }, pg_dumpall_dbprivs => { dump_cmd => [ 'pg_dumpall', '--no-sync', - "--file=$tempdir/pg_dumpall_dbprivs.sql", ], }, + "--file=$tempdir/pg_dumpall_dbprivs.sql", + ], + }, + pg_dumpall_exclude => { + dump_cmd => [ + 'pg_dumpall', '-v', "--file=$tempdir/pg_dumpall_exclude.sql", + '--exclude-database', '*dump_test*', '--no-sync', + ], + }, no_blobs => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/no_blobs.sql", '-B', - 'postgres', ], }, + 'postgres', + ], + }, no_privs => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/no_privs.sql", '-x', - 'postgres', ], }, + 'postgres', + ], + }, no_owner => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/no_owner.sql", '-O', - 'postgres', ], }, + 'postgres', + ], + }, only_dump_test_schema => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/only_dump_test_schema.sql", - '--schema=dump_test', 'postgres', ], }, + '--schema=dump_test', 'postgres', + ], + }, only_dump_test_table => { dump_cmd => [ 'pg_dump', @@ -210,7 +265,9 @@ "--file=$tempdir/only_dump_test_table.sql", '--table=dump_test.test_table', '--lock-wait-timeout=1000000', - 'postgres', ], }, + 'postgres', + ], + }, role => { dump_cmd => [ 'pg_dump', @@ -218,7 +275,9 @@ "--file=$tempdir/role.sql", '--role=regress_dump_test_role', '--schema=dump_test_second_schema', - 'postgres', ], }, + 'postgres', + ], + }, role_parallel => { test_key => 'role', dump_cmd => [ @@ -229,39 +288,59 @@ "--file=$tempdir/role_parallel", '--role=regress_dump_test_role', '--schema=dump_test_second_schema', - 'postgres', ], + 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/role_parallel.sql", - "$tempdir/role_parallel", ], }, + "$tempdir/role_parallel", + ], + }, + rows_per_insert => { + dump_cmd => [ + 'pg_dump', + '--no-sync', + "--file=$tempdir/rows_per_insert.sql", + '-a', + '--rows-per-insert=4', + '--table=dump_test.test_table', + '--table=dump_test.test_fourth_table', + 'postgres', + ], + }, schema_only => { dump_cmd => [ 'pg_dump', '--format=plain', "--file=$tempdir/schema_only.sql", '--no-sync', - '-s', 'postgres', ], }, + '-s', 'postgres', + ], + }, section_pre_data => { dump_cmd => [ 'pg_dump', "--file=$tempdir/section_pre_data.sql", '--section=pre-data', '--no-sync', - 'postgres', ], }, + 'postgres', + ], + }, section_data => { dump_cmd => [ 'pg_dump', "--file=$tempdir/section_data.sql", '--section=data', '--no-sync', - 'postgres', ], }, + 'postgres', + ], + }, section_post_data => { dump_cmd => [ 'pg_dump', "--file=$tempdir/section_post_data.sql", - '--section=post-data', '--no-sync', 'postgres', ], }, + '--section=post-data', '--no-sync', 'postgres', + ], + }, test_schema_plus_blobs => { dump_cmd => [ 'pg_dump', "--file=$tempdir/test_schema_plus_blobs.sql", - '--schema=dump_test', '-b', '-B', '--no-sync', 'postgres', ], }, - with_oids => { - dump_cmd => [ - 'pg_dump', '--oids', - '--no-sync', "--file=$tempdir/with_oids.sql", - 'postgres', ], },); + '--schema=dump_test', '-b', '-B', '--no-sync', 'postgres', + ], + },); ############################################################### # Definition of the tests to run. @@ -301,28 +380,26 @@ # Tests which target the 'dump_test' schema, specifically. my %dump_test_schema_runs = ( - only_dump_test_schema => 1, - test_schema_plus_blobs => 1, -); + only_dump_test_schema => 1, + test_schema_plus_blobs => 1,); # Tests which are considered 'full' dumps by pg_dump, but there # are flags used to exclude specific items (ACLs, blobs, etc). my %full_runs = ( - binary_upgrade => 1, - clean => 1, - clean_if_exists => 1, - createdb => 1, - defaults => 1, + binary_upgrade => 1, + clean => 1, + clean_if_exists => 1, + createdb => 1, + defaults => 1, exclude_dump_test_schema => 1, - exclude_test_table => 1, - exclude_test_table_data => 1, - no_blobs => 1, - no_owner => 1, - no_privs => 1, - pg_dumpall_dbprivs => 1, - schema_only => 1, - with_oids => 1, -); + exclude_test_table => 1, + exclude_test_table_data => 1, + no_blobs => 1, + no_owner => 1, + no_privs => 1, + pg_dumpall_dbprivs => 1, + pg_dumpall_exclude => 1, + schema_only => 1,); # This is where the actual tests are defined. my %tests = ( @@ -336,13 +413,13 @@ \QFOR ROLE regress_dump_test_role IN SCHEMA dump_test \E \QGRANT SELECT ON TABLES TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'ALTER DEFAULT PRIVILEGES FOR ROLE regress_dump_test_role REVOKE' => { create_order => 55, @@ -354,11 +431,9 @@ \QFOR ROLE regress_dump_test_role \E \QREVOKE ALL ON FUNCTIONS FROM PUBLIC;\E /xm, - like => { - %full_runs, - section_post_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + unlike => { no_privs => 1, }, + }, 'ALTER DEFAULT PRIVILEGES FOR ROLE regress_dump_test_role REVOKE SELECT' => { @@ -374,14 +449,12 @@ \QFOR ROLE regress_dump_test_role \E \QGRANT INSERT,REFERENCES,DELETE,TRIGGER,TRUNCATE,UPDATE ON TABLES TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - section_post_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + unlike => { no_privs => 1, }, + }, 'ALTER ROLE regress_dump_test_role' => { - regexp => qr/^ + regexp => qr/^ \QALTER ROLE regress_dump_test_role WITH \E \QNOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB NOLOGIN \E \QNOREPLICATION NOBYPASSRLS;\E @@ -389,59 +462,55 @@ like => { pg_dumpall_dbprivs => 1, pg_dumpall_globals => 1, - pg_dumpall_globals_clean => 1, }, }, + pg_dumpall_globals_clean => 1, + pg_dumpall_exclude => 1, + }, + }, 'ALTER COLLATION test0 OWNER TO' => { - regexp => qr/^ALTER COLLATION public.test0 OWNER TO .*;/m, + regexp => qr/^\QALTER COLLATION public.test0 OWNER TO \E.+;/m, collation => 1, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - %dump_test_schema_runs, - no_owner => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { %dump_test_schema_runs, no_owner => 1, }, + }, 'ALTER FOREIGN DATA WRAPPER dummy OWNER TO' => { - regexp => qr/^ALTER FOREIGN DATA WRAPPER dummy OWNER TO .*;/m, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + regexp => qr/^ALTER FOREIGN DATA WRAPPER dummy OWNER TO .+;/m, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_owner => 1, }, + }, 'ALTER SERVER s1 OWNER TO' => { - regexp => qr/^ALTER SERVER s1 OWNER TO .*;/m, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + regexp => qr/^ALTER SERVER s1 OWNER TO .+;/m, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_owner => 1, }, + }, 'ALTER FUNCTION dump_test.pltestlang_call_handler() OWNER TO' => { - regexp => qr/^ + regexp => qr/^ \QALTER FUNCTION dump_test.pltestlang_call_handler() \E \QOWNER TO \E - .*;/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + .+;/xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER OPERATOR FAMILY dump_test.op_family OWNER TO' => { - regexp => qr/^ + regexp => qr/^ \QALTER OPERATOR FAMILY dump_test.op_family USING btree \E \QOWNER TO \E - .*;/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + .+;/xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER OPERATOR FAMILY dump_test.op_family USING btree' => { create_order => 75, @@ -464,181 +533,213 @@ \QFUNCTION 1 (integer, integer) btint4cmp(integer,integer) ,\E\n\s+ \QFUNCTION 2 (integer, integer) btint4sortsupport(internal);\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'ALTER OPERATOR CLASS dump_test.op_class OWNER TO' => { - regexp => qr/^ + regexp => qr/^ \QALTER OPERATOR CLASS dump_test.op_class USING btree \E \QOWNER TO \E - .*;/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + .+;/xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER PUBLICATION pub1 OWNER TO' => { - regexp => qr/^ALTER PUBLICATION pub1 OWNER TO .*;/m, - like => { - %full_runs, - section_post_data => 1, }, - unlike => { - no_owner => 1, }, }, + regexp => qr/^ALTER PUBLICATION pub1 OWNER TO .+;/m, + like => { %full_runs, section_post_data => 1, }, + unlike => { no_owner => 1, }, + }, 'ALTER LARGE OBJECT ... OWNER TO' => { - regexp => qr/^ALTER LARGE OBJECT \d+ OWNER TO .*;/m, - like => { + regexp => qr/^ALTER LARGE OBJECT \d+ OWNER TO .+;/m, + like => { %full_runs, - column_inserts => 1, - data_only => 1, - section_pre_data => 1, - test_schema_plus_blobs => 1, }, + column_inserts => 1, + data_only => 1, + section_pre_data => 1, + test_schema_plus_blobs => 1, + }, unlike => { - no_blobs => 1, - no_owner => 1, - schema_only => 1, }, }, + no_blobs => 1, + no_owner => 1, + schema_only => 1, + }, + }, 'ALTER PROCEDURAL LANGUAGE pltestlang OWNER TO' => { - regexp => qr/^ALTER PROCEDURAL LANGUAGE pltestlang OWNER TO .*;/m, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + regexp => qr/^ALTER PROCEDURAL LANGUAGE pltestlang OWNER TO .+;/m, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_owner => 1, }, + }, 'ALTER SCHEMA dump_test OWNER TO' => { - regexp => qr/^ALTER SCHEMA dump_test OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + regexp => qr/^ALTER SCHEMA dump_test OWNER TO .+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER SCHEMA dump_test_second_schema OWNER TO' => { - regexp => qr/^ALTER SCHEMA dump_test_second_schema OWNER TO .*;/m, - like => { + regexp => qr/^ALTER SCHEMA dump_test_second_schema OWNER TO .+;/m, + like => { %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + role => 1, + section_pre_data => 1, + }, + unlike => { no_owner => 1, }, + }, 'ALTER SEQUENCE test_table_col1_seq' => { - regexp => qr/^ + regexp => qr/^ \QALTER SEQUENCE dump_test.test_table_col1_seq OWNED BY dump_test.test_table.col1;\E /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, - - 'ALTER SEQUENCE test_third_table_col1_seq' => { - regexp => qr/^ - \QALTER SEQUENCE dump_test_second_schema.test_third_table_col1_seq OWNED BY dump_test_second_schema.test_third_table.col1;\E - /xm, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE ONLY test_table ADD CONSTRAINT ... PRIMARY KEY' => { - regexp => qr/^ + regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table\E \n^\s+ \QADD CONSTRAINT test_table_pkey PRIMARY KEY (col1);\E /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, + unlike => { + exclude_dump_test_schema => 1, + exclude_test_table => 1, + }, + }, + + 'ALTER TABLE (partitioned) ADD CONSTRAINT ... FOREIGN KEY' => { + create_order => 4, + create_sql => 'CREATE TABLE dump_test.test_table_fk ( + col1 int references dump_test.test_table) + PARTITION BY RANGE (col1); + CREATE TABLE dump_test.test_table_fk_1 + PARTITION OF dump_test.test_table_fk + FOR VALUES FROM (0) TO (10);', + regexp => qr/ + \QADD CONSTRAINT test_table_fk_col1_fkey FOREIGN KEY (col1) REFERENCES dump_test.test_table\E + /xm, + like => { + %full_runs, %dump_test_schema_runs, section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + }, + }, 'ALTER TABLE ONLY test_table ALTER COLUMN col1 SET STATISTICS 90' => { create_order => 93, create_sql => -'ALTER TABLE dump_test.test_table ALTER COLUMN col1 SET STATISTICS 90;', + 'ALTER TABLE dump_test.test_table ALTER COLUMN col1 SET STATISTICS 90;', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table ALTER COLUMN col1 SET STATISTICS 90;\E\n /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE ONLY test_table ALTER COLUMN col2 SET STORAGE' => { create_order => 94, create_sql => -'ALTER TABLE dump_test.test_table ALTER COLUMN col2 SET STORAGE EXTERNAL;', + 'ALTER TABLE dump_test.test_table ALTER COLUMN col2 SET STORAGE EXTERNAL;', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table ALTER COLUMN col2 SET STORAGE EXTERNAL;\E\n /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE ONLY test_table ALTER COLUMN col3 SET STORAGE' => { create_order => 95, create_sql => -'ALTER TABLE dump_test.test_table ALTER COLUMN col3 SET STORAGE MAIN;', + 'ALTER TABLE dump_test.test_table ALTER COLUMN col3 SET STORAGE MAIN;', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table ALTER COLUMN col3 SET STORAGE MAIN;\E\n /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE ONLY test_table ALTER COLUMN col4 SET n_distinct' => { create_order => 95, create_sql => -'ALTER TABLE dump_test.test_table ALTER COLUMN col4 SET (n_distinct = 10);', + 'ALTER TABLE dump_test.test_table ALTER COLUMN col4 SET (n_distinct = 10);', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_table ALTER COLUMN col4 SET (n_distinct=10);\E\n /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, -'ALTER TABLE ONLY dump_test.measurement ATTACH PARTITION measurement_y2006m2' + 'ALTER TABLE ONLY dump_test.measurement ATTACH PARTITION measurement_y2006m2' => { - regexp => qr/^ + regexp => qr/^ \QALTER TABLE ONLY dump_test.measurement ATTACH PARTITION dump_test_second_schema.measurement_y2006m2 \E \QFOR VALUES FROM ('2006-02-01') TO ('2006-03-01');\E\n /xm, - like => { binary_upgrade => 1, }, }, + like => { + %full_runs, + role => 1, + section_pre_data => 1, + binary_upgrade => 1, + }, + }, 'ALTER TABLE test_table CLUSTER ON test_table_pkey' => { create_order => 96, @@ -650,149 +751,156 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE test_table DISABLE TRIGGER ALL' => { - regexp => qr/^ + regexp => qr/^ \QSET SESSION AUTHORIZATION 'test_superuser';\E\n\n \QALTER TABLE dump_test.test_table DISABLE TRIGGER ALL;\E\n\n \QCOPY dump_test.test_table (col1, col2, col3, col4) FROM stdin;\E \n(?:\d\t\\N\t\\N\t\\N\n){9}\\\.\n\n\n \QALTER TABLE dump_test.test_table ENABLE TRIGGER ALL;\E/xm, - like => { data_only => 1, }, }, + like => { data_only => 1, }, + }, 'ALTER FOREIGN TABLE foreign_table ALTER COLUMN c1 OPTIONS' => { - regexp => qr/^ + regexp => qr/^ \QALTER FOREIGN TABLE dump_test.foreign_table ALTER COLUMN c1 OPTIONS (\E\n \s+\Qcolumn_name 'col1'\E\n \Q);\E\n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'ALTER TABLE test_table OWNER TO' => { - regexp => qr/^ALTER TABLE dump_test.test_table OWNER TO .*;/m, - like => { + regexp => qr/^\QALTER TABLE dump_test.test_table OWNER TO \E.+;/m, + like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, - no_owner => 1, }, }, + exclude_test_table => 1, + no_owner => 1, + }, + }, 'ALTER TABLE test_table ENABLE ROW LEVEL SECURITY' => { create_order => 23, create_sql => 'ALTER TABLE dump_test.test_table ENABLE ROW LEVEL SECURITY;', - regexp => qr/^ALTER TABLE dump_test.test_table ENABLE ROW LEVEL SECURITY;/m, - like => { + regexp => + qr/^\QALTER TABLE dump_test.test_table ENABLE ROW LEVEL SECURITY;\E/m, + like => { %full_runs, %dump_test_schema_runs, only_dump_test_table => 1, - section_post_data => 1, }, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER TABLE test_second_table OWNER TO' => { - regexp => qr/^ALTER TABLE dump_test.test_second_table OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + regexp => + qr/^\QALTER TABLE dump_test.test_second_table OWNER TO \E.+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, - - 'ALTER TABLE test_third_table OWNER TO' => { - regexp => qr/^ALTER TABLE dump_test_second_schema.test_third_table OWNER TO .*;/m, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER TABLE measurement OWNER TO' => { - regexp => qr/^ALTER TABLE dump_test.measurement OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + regexp => qr/^\QALTER TABLE dump_test.measurement OWNER TO \E.+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER TABLE measurement_y2006m2 OWNER TO' => { - regexp => qr/^ALTER TABLE dump_test_second_schema.measurement_y2006m2 OWNER TO .*;/m, - like => { + regexp => + qr/^\QALTER TABLE dump_test_second_schema.measurement_y2006m2 OWNER TO \E.+;/m, + like => { %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_owner => 1, }, }, + role => 1, + section_pre_data => 1, + }, + unlike => { no_owner => 1, }, + }, 'ALTER FOREIGN TABLE foreign_table OWNER TO' => { - regexp => qr/^ALTER FOREIGN TABLE dump_test.foreign_table OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + regexp => + qr/^\QALTER FOREIGN TABLE dump_test.foreign_table OWNER TO \E.+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER TEXT SEARCH CONFIGURATION alt_ts_conf1 OWNER TO' => { regexp => - qr/^ALTER TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + qr/^\QALTER TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 OWNER TO \E.+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_owner => 1, }, }, + no_owner => 1, + }, + }, 'ALTER TEXT SEARCH DICTIONARY alt_ts_dict1 OWNER TO' => { regexp => - qr/^ALTER TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 OWNER TO .*;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + qr/^\QALTER TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 OWNER TO \E.+;/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, only_dump_test_table => 1, no_owner => 1, - role => 1, }, }, + role => 1, + }, + }, 'BLOB create (using lo_from_bytea)' => { create_order => 50, create_sql => -'SELECT pg_catalog.lo_from_bytea(0, \'\\x310a320a330a340a350a360a370a380a390a\');', + 'SELECT pg_catalog.lo_from_bytea(0, \'\\x310a320a330a340a350a360a370a380a390a\');', regexp => qr/^SELECT pg_catalog\.lo_create\('\d+'\);/m, like => { %full_runs, - column_inserts => 1, - data_only => 1, - section_pre_data => 1, - test_schema_plus_blobs => 1, }, + column_inserts => 1, + data_only => 1, + section_pre_data => 1, + test_schema_plus_blobs => 1, + }, unlike => { schema_only => 1, - no_blobs => 1, }, }, + no_blobs => 1, + }, + }, 'BLOB load (using lo_from_bytea)' => { - regexp => qr/^ + regexp => qr/^ \QSELECT pg_catalog.lo_open\E \('\d+',\ \d+\);\n \QSELECT pg_catalog.lowrite(0, \E \Q'\x310a320a330a340a350a360a370a380a390a');\E\n @@ -800,38 +908,49 @@ /xm, like => { %full_runs, - column_inserts => 1, - data_only => 1, - section_data => 1, - test_schema_plus_blobs => 1, }, + column_inserts => 1, + data_only => 1, + section_data => 1, + test_schema_plus_blobs => 1, + }, unlike => { binary_upgrade => 1, - no_blobs => 1, - schema_only => 1, }, }, + no_blobs => 1, + schema_only => 1, + }, + }, 'COMMENT ON DATABASE postgres' => { - regexp => qr/^COMMENT ON DATABASE postgres IS .*;/m, + regexp => qr/^COMMENT ON DATABASE postgres IS .+;/m, + # Should appear in the same tests as "CREATE DATABASE postgres" - like => { createdb => 1, }, }, + like => { createdb => 1, }, + }, 'COMMENT ON EXTENSION plpgsql' => { - regexp => qr/^COMMENT ON EXTENSION plpgsql IS .*;/m, + regexp => qr/^COMMENT ON EXTENSION plpgsql IS .+;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'COMMENT ON TABLE dump_test.test_table' => { create_order => 36, create_sql => 'COMMENT ON TABLE dump_test.test_table IS \'comment on table\';', - regexp => qr/^COMMENT ON TABLE dump_test.test_table IS 'comment on table';/m, - like => { + regexp => + qr/^\QCOMMENT ON TABLE dump_test.test_table IS 'comment on table';\E/m, + like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'COMMENT ON COLUMN dump_test.test_table.col1' => { create_order => 36, @@ -843,11 +962,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'COMMENT ON COLUMN dump_test.composite.f1' => { create_order => 44, @@ -856,12 +978,10 @@ regexp => qr/^ \QCOMMENT ON COLUMN dump_test.composite.f1 IS 'comment on column of type';\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON COLUMN dump_test.test_second_table.col1' => { create_order => 63, @@ -870,12 +990,10 @@ regexp => qr/^ \QCOMMENT ON COLUMN dump_test.test_second_table.col1 IS 'comment on column col1';\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON COLUMN dump_test.test_second_table.col2' => { create_order => 64, @@ -884,36 +1002,31 @@ regexp => qr/^ \QCOMMENT ON COLUMN dump_test.test_second_table.col2 IS 'comment on column col2';\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON CONVERSION dump_test.test_conversion' => { create_order => 79, create_sql => 'COMMENT ON CONVERSION dump_test.test_conversion IS \'comment on test conversion\';', regexp => -qr/^COMMENT ON CONVERSION dump_test.test_conversion IS 'comment on test conversion';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON CONVERSION dump_test.test_conversion IS 'comment on test conversion';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON COLLATION test0' => { create_order => 77, create_sql => 'COMMENT ON COLLATION test0 IS \'comment on test0 collation\';', regexp => - qr/^COMMENT ON COLLATION public.test0 IS 'comment on test0 collation';/m, + qr/^\QCOMMENT ON COLLATION public.test0 IS 'comment on test0 collation';\E/m, collation => 1, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'COMMENT ON LARGE OBJECT ...' => { create_order => 65, @@ -929,13 +1042,16 @@ /xm, like => { %full_runs, - column_inserts => 1, - data_only => 1, - section_pre_data => 1, - test_schema_plus_blobs => 1, }, + column_inserts => 1, + data_only => 1, + section_pre_data => 1, + test_schema_plus_blobs => 1, + }, unlike => { - no_blobs => 1, - schema_only => 1, }, }, + no_blobs => 1, + schema_only => 1, + }, + }, 'COMMENT ON PUBLICATION pub1' => { create_order => 55, @@ -943,9 +1059,8 @@ IS \'comment on publication\';', regexp => qr/^COMMENT ON PUBLICATION pub1 IS 'comment on publication';/m, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'COMMENT ON SUBSCRIPTION sub1' => { create_order => 55, @@ -953,9 +1068,8 @@ IS \'comment on subscription\';', regexp => qr/^COMMENT ON SUBSCRIPTION sub1 IS 'comment on subscription';/m, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'COMMENT ON TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1' => { create_order => 84, @@ -963,13 +1077,11 @@ 'COMMENT ON TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 IS \'comment on text search configuration\';', regexp => -qr/^COMMENT ON TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 IS 'comment on text search configuration';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 IS 'comment on text search configuration';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1' => { create_order => 84, @@ -977,88 +1089,77 @@ 'COMMENT ON TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 IS \'comment on text search dictionary\';', regexp => -qr/^COMMENT ON TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 IS 'comment on text search dictionary';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 IS 'comment on text search dictionary';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TEXT SEARCH PARSER dump_test.alt_ts_prs1' => { create_order => 84, create_sql => 'COMMENT ON TEXT SEARCH PARSER dump_test.alt_ts_prs1 IS \'comment on text search parser\';', regexp => -qr/^COMMENT ON TEXT SEARCH PARSER dump_test.alt_ts_prs1 IS 'comment on text search parser';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON TEXT SEARCH PARSER dump_test.alt_ts_prs1 IS 'comment on text search parser';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1' => { create_order => 84, create_sql => 'COMMENT ON TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 IS \'comment on text search template\';', regexp => -qr/^COMMENT ON TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 IS 'comment on text search template';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 IS 'comment on text search template';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TYPE dump_test.planets - ENUM' => { create_order => 68, create_sql => 'COMMENT ON TYPE dump_test.planets IS \'comment on enum type\';', - regexp => qr/^COMMENT ON TYPE dump_test.planets IS 'comment on enum type';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + regexp => + qr/^\QCOMMENT ON TYPE dump_test.planets IS 'comment on enum type';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TYPE dump_test.textrange - RANGE' => { create_order => 69, create_sql => 'COMMENT ON TYPE dump_test.textrange IS \'comment on range type\';', - regexp => qr/^COMMENT ON TYPE dump_test.textrange IS 'comment on range type';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + regexp => + qr/^\QCOMMENT ON TYPE dump_test.textrange IS 'comment on range type';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TYPE dump_test.int42 - Regular' => { create_order => 70, create_sql => 'COMMENT ON TYPE dump_test.int42 IS \'comment on regular type\';', - regexp => qr/^COMMENT ON TYPE dump_test.int42 IS 'comment on regular type';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + regexp => + qr/^\QCOMMENT ON TYPE dump_test.int42 IS 'comment on regular type';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COMMENT ON TYPE dump_test.undefined - Undefined' => { create_order => 71, create_sql => 'COMMENT ON TYPE dump_test.undefined IS \'comment on undefined type\';', regexp => - qr/^COMMENT ON TYPE dump_test.undefined IS 'comment on undefined type';/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCOMMENT ON TYPE dump_test.undefined IS 'comment on undefined type';\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'COPY test_table' => { create_order => 4, @@ -1071,15 +1172,18 @@ like => { %full_runs, %dump_test_schema_runs, - data_only => 1, - only_dump_test_table => 1, - section_data => 1, }, + data_only => 1, + only_dump_test_table => 1, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - exclude_test_table => 1, - exclude_test_table_data => 1, - schema_only => 1, }, }, + exclude_test_table => 1, + exclude_test_table_data => 1, + schema_only => 1, + }, + }, 'COPY fk_reference_test_table' => { create_order => 22, @@ -1095,23 +1199,27 @@ data_only => 1, exclude_test_table => 1, exclude_test_table_data => 1, - section_data => 1, }, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, # In a data-only dump, we try to actually order according to FKs, # so this check is just making sure that the referring table comes after # the referred-to table. 'COPY fk_reference_test_table second' => { - regexp => qr/^ + regexp => qr/^ \QCOPY dump_test.test_table (col1, col2, col3, col4) FROM stdin;\E \n(?:\d\t\\N\t\\N\t\\N\n){9}\\\.\n.* \QCOPY dump_test.fk_reference_test_table (col1) FROM stdin;\E \n(?:\d\n){5}\\\.\n /xms, - like => { data_only => 1, }, }, + like => { data_only => 1, }, + }, 'COPY test_second_table' => { create_order => 7, @@ -1125,62 +1233,42 @@ like => { %full_runs, %dump_test_schema_runs, - data_only => 1, - section_data => 1, }, + data_only => 1, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, - - 'COPY test_third_table' => { - create_order => 12, - create_sql => - 'INSERT INTO dump_test_second_schema.test_third_table (col1) ' - . 'SELECT generate_series FROM generate_series(1,9);', - regexp => qr/^ - \QCOPY dump_test_second_schema.test_third_table (col1) FROM stdin;\E - \n(?:\d\n){9}\\\.\n - /xm, - like => { - %full_runs, - data_only => 1, - role => 1, - section_data => 1, }, - unlike => { - binary_upgrade => 1, - exclude_test_table_data => 1, - schema_only => 1, - with_oids => 1, }, }, - - 'COPY test_third_table WITH OIDS' => { - regexp => qr/^ - \QCOPY dump_test_second_schema.test_third_table (col1) WITH OIDS FROM stdin;\E - \n(?:\d+\t\d\n){9}\\\.\n - /xm, - like => { with_oids => 1, }, }, + schema_only => 1, + }, + }, 'COPY test_fourth_table' => { create_order => 7, create_sql => - 'INSERT INTO dump_test.test_fourth_table DEFAULT VALUES;', + 'INSERT INTO dump_test.test_fourth_table DEFAULT VALUES;' + . 'INSERT INTO dump_test.test_fourth_table DEFAULT VALUES;', regexp => qr/^ \QCOPY dump_test.test_fourth_table FROM stdin;\E - \n\n\\\.\n + \n\n\n\\\.\n /xm, like => { %full_runs, %dump_test_schema_runs, - data_only => 1, - section_data => 1, }, + data_only => 1, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, 'COPY test_fifth_table' => { create_order => 54, create_sql => -'INSERT INTO dump_test.test_fifth_table VALUES (NULL, true, false, \'11001\'::bit(5), \'NaN\');', + 'INSERT INTO dump_test.test_fifth_table VALUES (NULL, true, false, \'11001\'::bit(5), \'NaN\');', regexp => qr/^ \QCOPY dump_test.test_fifth_table (col1, col2, col3, col4, col5) FROM stdin;\E \n\\N\tt\tf\t11001\tNaN\n\\\.\n @@ -1188,17 +1276,20 @@ like => { %full_runs, %dump_test_schema_runs, - data_only => 1, - section_data => 1, }, + data_only => 1, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, 'COPY test_table_identity' => { create_order => 54, create_sql => -'INSERT INTO dump_test.test_table_identity (col2) VALUES (\'test\');', + 'INSERT INTO dump_test.test_table_identity (col2) VALUES (\'test\');', regexp => qr/^ \QCOPY dump_test.test_table_identity (col1, col2) FROM stdin;\E \n1\ttest\n\\\.\n @@ -1206,44 +1297,60 @@ like => { %full_runs, %dump_test_schema_runs, - data_only => 1, - section_data => 1, }, + data_only => 1, + section_data => 1, + }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, 'INSERT INTO test_table' => { - regexp => qr/^ - (?:INSERT\ INTO\ dump_test.test_table\ \(col1,\ col2,\ col3,\ col4\)\ VALUES\ \(\d,\ NULL,\ NULL,\ NULL\);\n){9} + regexp => qr/^ + (?:INSERT\ INTO\ dump_test\.test_table\ \(col1,\ col2,\ col3,\ col4\)\ VALUES\ \(\d,\ NULL,\ NULL,\ NULL\);\n){9} /xm, - like => { column_inserts => 1, }, }, + like => { column_inserts => 1, }, + }, + + 'test_table with 4-row INSERTs' => { + regexp => qr/^ + (?: + INSERT\ INTO\ dump_test\.test_table\ VALUES\n + (?:\t\(\d,\ NULL,\ NULL,\ NULL\),\n){3} + \t\(\d,\ NULL,\ NULL,\ NULL\);\n + ){2} + INSERT\ INTO\ dump_test\.test_table\ VALUES\n + \t\(\d,\ NULL,\ NULL,\ NULL\); + /xm, + like => { rows_per_insert => 1, }, + }, 'INSERT INTO test_second_table' => { - regexp => qr/^ - (?:INSERT\ INTO\ dump_test.test_second_table\ \(col1,\ col2\) + regexp => qr/^ + (?:INSERT\ INTO\ dump_test\.test_second_table\ \(col1,\ col2\) \ VALUES\ \(\d,\ '\d'\);\n){9}/xm, - like => { column_inserts => 1, }, }, - - 'INSERT INTO test_third_table' => { - regexp => qr/^ - (?:INSERT\ INTO\ dump_test_second_schema.test_third_table\ \(col1\) - \ VALUES\ \(\d\);\n){9}/xm, - like => { column_inserts => 1, }, }, + like => { column_inserts => 1, }, + }, 'INSERT INTO test_fourth_table' => { - regexp => qr/^\QINSERT INTO dump_test.test_fourth_table DEFAULT VALUES;\E/m, - like => { column_inserts => 1, }, }, + regexp => + qr/^(?:INSERT INTO dump_test\.test_fourth_table DEFAULT VALUES;\n){2}/m, + like => { column_inserts => 1, rows_per_insert => 1, }, + }, 'INSERT INTO test_fifth_table' => { regexp => -qr/^\QINSERT INTO dump_test.test_fifth_table (col1, col2, col3, col4, col5) VALUES (NULL, true, false, B'11001', 'NaN');\E/m, - like => { column_inserts => 1, }, }, + qr/^\QINSERT INTO dump_test.test_fifth_table (col1, col2, col3, col4, col5) VALUES (NULL, true, false, B'11001', 'NaN');\E/m, + like => { column_inserts => 1, }, + }, 'INSERT INTO test_table_identity' => { regexp => -qr/^\QINSERT INTO dump_test.test_table_identity (col1, col2) OVERRIDING SYSTEM VALUE VALUES (1, 'test');\E/m, - like => { column_inserts => 1, }, }, + qr/^\QINSERT INTO dump_test.test_table_identity (col1, col2) OVERRIDING SYSTEM VALUE VALUES (1, 'test');\E/m, + like => { column_inserts => 1, }, + }, 'CREATE ROLE regress_dump_test_role' => { create_order => 1, @@ -1251,8 +1358,11 @@ regexp => qr/^CREATE ROLE regress_dump_test_role;/m, like => { pg_dumpall_dbprivs => 1, + pg_dumpall_exclude => 1, pg_dumpall_globals => 1, - pg_dumpall_globals_clean => 1, }, }, + pg_dumpall_globals_clean => 1, + }, + }, 'CREATE ACCESS METHOD gist2' => { create_order => 52, @@ -1260,9 +1370,8 @@ 'CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;', regexp => qr/CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler;/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE COLLATION test0 FROM "C"' => { create_order => 76, @@ -1270,40 +1379,51 @@ regexp => qr/^ \QCREATE COLLATION public.test0 (provider = libc, locale = 'C');\E/xm, collation => 1, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE CAST FOR timestamptz' => { create_order => 51, create_sql => -'CREATE CAST (timestamptz AS interval) WITH FUNCTION age(timestamptz) AS ASSIGNMENT;', + 'CREATE CAST (timestamptz AS interval) WITH FUNCTION age(timestamptz) AS ASSIGNMENT;', regexp => -qr/CREATE CAST \(timestamp with time zone AS interval\) WITH FUNCTION pg_catalog\.age\(timestamp with time zone\) AS ASSIGNMENT;/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + qr/CREATE CAST \(timestamp with time zone AS interval\) WITH FUNCTION pg_catalog\.age\(timestamp with time zone\) AS ASSIGNMENT;/m, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE DATABASE postgres' => { - regexp => qr/^ + regexp => qr/^ \QCREATE DATABASE postgres WITH TEMPLATE = template0 \E - .*;/xm, - like => { createdb => 1, }, }, + .+;/xm, + like => { createdb => 1, }, + }, 'CREATE DATABASE dump_test' => { create_order => 47, create_sql => 'CREATE DATABASE dump_test;', regexp => qr/^ \QCREATE DATABASE dump_test WITH TEMPLATE = template0 \E - .*;/xm, - like => { pg_dumpall_dbprivs => 1, }, }, + .+;/xm, + like => { pg_dumpall_dbprivs => 1, }, + }, + + "CREATE DATABASE dump_test2 LOCALE = 'C'" => { + create_order => 47, + create_sql => "CREATE DATABASE dump_test2 LOCALE = 'C' TEMPLATE = template0;", + regexp => qr/^ + \QCREATE DATABASE dump_test2 \E.*\QLOCALE = 'C';\E + /xm, + like => { pg_dumpall_dbprivs => 1, }, + }, 'CREATE EXTENSION ... plpgsql' => { - regexp => qr/^ + regexp => qr/^ \QCREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;\E /xm, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'CREATE AGGREGATE dump_test.newavg' => { create_order => 25, @@ -1312,7 +1432,7 @@ basetype = int4, stype = _int8, finalfunc = int8_avg, - finalfunc_modify = sharable, + finalfunc_modify = shareable, initcond1 = \'{0,0}\' );', regexp => qr/^ @@ -1321,28 +1441,27 @@ \n\s+\QSTYPE = bigint[],\E \n\s+\QINITCOND = '{0,0}',\E \n\s+\QFINALFUNC = int8_avg,\E - \n\s+\QFINALFUNC_MODIFY = SHARABLE\E + \n\s+\QFINALFUNC_MODIFY = SHAREABLE\E \n\);/xm, like => { %full_runs, %dump_test_schema_runs, - exclude_test_table => 1, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + exclude_test_table => 1, + section_pre_data => 1, + }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE CONVERSION dump_test.test_conversion' => { create_order => 78, create_sql => -'CREATE DEFAULT CONVERSION dump_test.test_conversion FOR \'LATIN1\' TO \'UTF8\' FROM iso8859_1_to_utf8;', + 'CREATE DEFAULT CONVERSION dump_test.test_conversion FOR \'LATIN1\' TO \'UTF8\' FROM iso8859_1_to_utf8;', regexp => -qr/^\QCREATE DEFAULT CONVERSION dump_test.test_conversion FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;\E/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + qr/^\QCREATE DEFAULT CONVERSION dump_test.test_conversion FOR 'LATIN1' TO 'UTF8' FROM iso8859_1_to_utf8;\E/xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE DOMAIN dump_test.us_postal_code' => { create_order => 29, @@ -1358,12 +1477,10 @@ \$\Q'::text) OR (VALUE ~ '^\d{5}-\d{4}\E\$ \Q'::text)));\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FUNCTION dump_test.pltestlang_call_handler' => { create_order => 17, @@ -1377,12 +1494,10 @@ \n\s+AS\ \'\$ \Qlibdir\/plpgsql', 'plpgsql_call_handler';\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FUNCTION dump_test.trigger_func' => { create_order => 30, @@ -1395,12 +1510,10 @@ \n\s+AS\ \$\$ \Q BEGIN RETURN NULL; END;\E \$\$;/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FUNCTION dump_test.event_trigger_func' => { create_order => 32, @@ -1413,12 +1526,10 @@ \n\s+AS\ \$\$ \Q BEGIN RETURN; END;\E \$\$;/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE OPERATOR FAMILY dump_test.op_family' => { create_order => 73, @@ -1427,12 +1538,10 @@ regexp => qr/^ \QCREATE OPERATOR FAMILY dump_test.op_family USING btree;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE OPERATOR CLASS dump_test.op_class' => { create_order => 74, @@ -1457,46 +1566,90 @@ \QFUNCTION 1 (bigint, bigint) btint8cmp(bigint,bigint) ,\E\n\s+ \QFUNCTION 2 (bigint, bigint) btint8sortsupport(internal);\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + # verify that a custom operator/opclass/range type is dumped in right order + 'CREATE OPERATOR CLASS dump_test.op_class_custom' => { + create_order => 74, + create_sql => 'CREATE OPERATOR dump_test.~~ ( + PROCEDURE = int4eq, + LEFTARG = int, + RIGHTARG = int); + CREATE OPERATOR CLASS dump_test.op_class_custom + FOR TYPE int USING btree AS + OPERATOR 3 dump_test.~~; + CREATE TYPE dump_test.range_type_custom AS RANGE ( + subtype = int, + subtype_opclass = dump_test.op_class_custom);', + regexp => qr/^ + \QCREATE OPERATOR dump_test.~~ (\E\n.+ + \QCREATE OPERATOR FAMILY dump_test.op_class_custom USING btree;\E\n.+ + \QCREATE OPERATOR CLASS dump_test.op_class_custom\E\n\s+ + \QFOR TYPE integer USING btree FAMILY dump_test.op_class_custom AS\E\n\s+ + \QOPERATOR 3 dump_test.~~(integer,integer);\E\n.+ + \QCREATE TYPE dump_test.range_type_custom AS RANGE (\E\n\s+ + \Qsubtype = integer,\E\n\s+ + \Qsubtype_opclass = dump_test.op_class_custom\E\n + \Q);\E + /xms, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE OPERATOR CLASS dump_test.op_class_empty' => { + create_order => 89, + create_sql => 'CREATE OPERATOR CLASS dump_test.op_class_empty + FOR TYPE bigint USING btree FAMILY dump_test.op_family + AS STORAGE bigint;', + regexp => qr/^ + \QCREATE OPERATOR CLASS dump_test.op_class_empty\E\n\s+ + \QFOR TYPE bigint USING btree FAMILY dump_test.op_family AS\E\n\s+ + \QSTORAGE bigint;\E + /xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE EVENT TRIGGER test_event_trigger' => { create_order => 33, create_sql => 'CREATE EVENT TRIGGER test_event_trigger ON ddl_command_start - EXECUTE PROCEDURE dump_test.event_trigger_func();', + EXECUTE FUNCTION dump_test.event_trigger_func();', regexp => qr/^ \QCREATE EVENT TRIGGER test_event_trigger \E \QON ddl_command_start\E - \n\s+\QEXECUTE PROCEDURE dump_test.event_trigger_func();\E + \n\s+\QEXECUTE FUNCTION dump_test.event_trigger_func();\E /xm, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'CREATE TRIGGER test_trigger' => { create_order => 31, create_sql => 'CREATE TRIGGER test_trigger BEFORE INSERT ON dump_test.test_table FOR EACH ROW WHEN (NEW.col1 > 10) - EXECUTE PROCEDURE dump_test.trigger_func();', + EXECUTE FUNCTION dump_test.trigger_func();', regexp => qr/^ \QCREATE TRIGGER test_trigger BEFORE INSERT ON dump_test.test_table \E \QFOR EACH ROW WHEN ((new.col1 > 10)) \E - \QEXECUTE PROCEDURE dump_test.trigger_func();\E + \QEXECUTE FUNCTION dump_test.trigger_func();\E /xm, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { - exclude_test_table => 1, - exclude_dump_test_schema => 1, }, }, + exclude_test_table => 1, + exclude_dump_test_schema => 1, + }, + }, 'CREATE TYPE dump_test.planets AS ENUM' => { create_order => 37, @@ -1508,16 +1661,16 @@ \n\s+'earth', \n\s+'mars' \n\);/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { - binary_upgrade => 1, - exclude_dump_test_schema => 1, }, }, + binary_upgrade => 1, + exclude_dump_test_schema => 1, + }, + }, 'CREATE TYPE dump_test.planets AS ENUM pg_upgrade' => { - regexp => qr/^ + regexp => qr/^ \QCREATE TYPE dump_test.planets AS ENUM (\E \n\);.*^ \QALTER TYPE dump_test.planets ADD VALUE 'venus';\E @@ -1526,7 +1679,8 @@ \n.*^ \QALTER TYPE dump_test.planets ADD VALUE 'mars';\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE TYPE dump_test.textrange AS RANGE' => { create_order => 38, @@ -1537,40 +1691,34 @@ \n\s+\Qsubtype = text,\E \n\s+\Qcollation = pg_catalog."C"\E \n\);/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TYPE dump_test.int42' => { create_order => 39, create_sql => 'CREATE TYPE dump_test.int42;', - regexp => qr/^CREATE TYPE dump_test.int42;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + regexp => qr/^\QCREATE TYPE dump_test.int42;\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1' => { create_order => 80, create_sql => -'CREATE TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 (copy=english);', + 'CREATE TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 (copy=english);', regexp => qr/^ \QCREATE TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 (\E\n \s+\QPARSER = pg_catalog."default" );\E/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'ALTER TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1 ...' => { - regexp => qr/^ + regexp => qr/^ \QALTER TEXT SEARCH CONFIGURATION dump_test.alt_ts_conf1\E\n \s+\QADD MAPPING FOR asciiword WITH english_stem;\E\n \n @@ -1629,26 +1777,22 @@ \s+\QADD MAPPING FOR uint WITH simple;\E\n \n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1' => { create_order => 81, create_sql => -'CREATE TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 (lexize=dsimple_lexize);', + 'CREATE TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 (lexize=dsimple_lexize);', regexp => qr/^ \QCREATE TEXT SEARCH TEMPLATE dump_test.alt_ts_temp1 (\E\n \s+\QLEXIZE = dsimple_lexize );\E/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TEXT SEARCH PARSER dump_test.alt_ts_prs1' => { create_order => 82, @@ -1661,27 +1805,23 @@ \s+\QEND = prsd_end,\E\n \s+\QLEXTYPES = prsd_lextype );\E\n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1' => { create_order => 83, create_sql => -'CREATE TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 (template=simple);', + 'CREATE TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 (template=simple);', regexp => qr/^ \QCREATE TEXT SEARCH DICTIONARY dump_test.alt_ts_dict1 (\E\n \s+\QTEMPLATE = pg_catalog.simple );\E\n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FUNCTION dump_test.int42_in' => { create_order => 40, @@ -1693,12 +1833,10 @@ \n\s+\QLANGUAGE internal IMMUTABLE STRICT\E \n\s+AS\ \$\$int4in\$\$; /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FUNCTION dump_test.int42_out' => { create_order => 41, @@ -1710,12 +1848,24 @@ \n\s+\QLANGUAGE internal IMMUTABLE STRICT\E \n\s+AS\ \$\$int4out\$\$; /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE FUNCTION ... SUPPORT' => { + create_order => 41, + create_sql => + 'CREATE FUNCTION dump_test.func_with_support() RETURNS int LANGUAGE sql AS $$ SELECT 1 $$ SUPPORT varchar_support;', + regexp => qr/^ + \QCREATE FUNCTION dump_test.func_with_support() RETURNS integer\E + \n\s+\QLANGUAGE sql SUPPORT varchar_support\E + \n\s+AS\ \$\$\Q SELECT 1 \E\$\$; + /xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE PROCEDURE dump_test.ptest1' => { create_order => 41, @@ -1726,12 +1876,10 @@ \n\s+\QLANGUAGE sql\E \n\s+AS\ \$\$\Q INSERT INTO dump_test.test_table (col1) VALUES (a) \E\$\$; /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TYPE dump_test.int42 populated' => { create_order => 42, @@ -1752,12 +1900,10 @@ \n\s+\QSTORAGE = plain,\E \n\s+PASSEDBYVALUE\n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TYPE dump_test.composite' => { create_order => 43, @@ -1771,44 +1917,38 @@ \n\s+\Qf2 dump_test.int42\E \n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TYPE dump_test.undefined' => { create_order => 39, create_sql => 'CREATE TYPE dump_test.undefined;', - regexp => qr/^CREATE TYPE dump_test.undefined;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + regexp => qr/^\QCREATE TYPE dump_test.undefined;\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE FOREIGN DATA WRAPPER dummy' => { create_order => 35, create_sql => 'CREATE FOREIGN DATA WRAPPER dummy;', regexp => qr/CREATE FOREIGN DATA WRAPPER dummy;/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE SERVER s1 FOREIGN DATA WRAPPER dummy' => { create_order => 36, create_sql => 'CREATE SERVER s1 FOREIGN DATA WRAPPER dummy;', regexp => qr/CREATE SERVER s1 FOREIGN DATA WRAPPER dummy;/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE FOREIGN TABLE dump_test.foreign_table SERVER s1' => { create_order => 88, create_sql => -'CREATE FOREIGN TABLE dump_test.foreign_table (c1 int options (column_name \'col1\')) + 'CREATE FOREIGN TABLE dump_test.foreign_table (c1 int options (column_name \'col1\')) SERVER s1 OPTIONS (schema_name \'x1\');', regexp => qr/ \QCREATE FOREIGN TABLE dump_test.foreign_table (\E\n @@ -1819,12 +1959,10 @@ \s+\Qschema_name 'x1'\E\n \Q);\E\n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE USER MAPPING FOR regress_dump_test_role SERVER s1' => { create_order => 86, @@ -1832,19 +1970,17 @@ 'CREATE USER MAPPING FOR regress_dump_test_role SERVER s1;', regexp => qr/CREATE USER MAPPING FOR regress_dump_test_role SERVER s1;/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE TRANSFORM FOR int' => { create_order => 34, create_sql => -'CREATE TRANSFORM FOR int LANGUAGE SQL (FROM SQL WITH FUNCTION varchar_transform(internal), TO SQL WITH FUNCTION int4recv(internal));', + 'CREATE TRANSFORM FOR int LANGUAGE SQL (FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal));', regexp => -qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog\.varchar_transform\(internal\), TO SQL WITH FUNCTION pg_catalog\.int4recv\(internal\)\);/m, - like => { - %full_runs, - section_pre_data => 1, }, }, + qr/CREATE TRANSFORM FOR integer LANGUAGE sql \(FROM SQL WITH FUNCTION pg_catalog\.prsd_lextype\(internal\), TO SQL WITH FUNCTION pg_catalog\.int4recv\(internal\)\);/m, + like => { %full_runs, section_pre_data => 1, }, + }, 'CREATE LANGUAGE pltestlang' => { create_order => 18, @@ -1854,11 +1990,9 @@ \QCREATE PROCEDURAL LANGUAGE pltestlang \E \QHANDLER dump_test.pltestlang_call_handler;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE MATERIALIZED VIEW matview' => { create_order => 20, @@ -1870,12 +2004,10 @@ \n\s+\QFROM dump_test.test_table\E \n\s+\QWITH NO DATA;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE MATERIALIZED VIEW matview_second' => { create_order => 21, @@ -1888,12 +2020,10 @@ \n\s+\QFROM dump_test.matview\E \n\s+\QWITH NO DATA;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE MATERIALIZED VIEW matview_third' => { create_order => 58, @@ -1906,12 +2036,10 @@ \n\s+\QFROM dump_test.matview_second\E \n\s+\QWITH NO DATA;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE MATERIALIZED VIEW matview_fourth' => { create_order => 59, @@ -1924,12 +2052,10 @@ \n\s+\QFROM dump_test.matview_third\E \n\s+\QWITH NO DATA;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE POLICY p1 ON test_table' => { create_order => 22, @@ -1943,11 +2069,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE POLICY p2 ON test_table FOR SELECT' => { create_order => 24, @@ -1960,11 +2089,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE POLICY p3 ON test_table FOR INSERT' => { create_order => 25, @@ -1977,11 +2109,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE POLICY p4 ON test_table FOR UPDATE' => { create_order => 26, @@ -1994,11 +2129,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE POLICY p5 ON test_table FOR DELETE' => { create_order => 27, @@ -2011,11 +2149,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE POLICY p6 ON test_table AS RESTRICTIVE' => { create_order => 27, @@ -2028,11 +2169,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_post_data => 1, }, + only_dump_test_table => 1, + section_post_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE PUBLICATION pub1' => { create_order => 50, @@ -2040,9 +2184,8 @@ regexp => qr/^ \QCREATE PUBLICATION pub1 WITH (publish = 'insert, update, delete, truncate');\E /xm, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'CREATE PUBLICATION pub2' => { create_order => 50, @@ -2052,9 +2195,8 @@ regexp => qr/^ \QCREATE PUBLICATION pub2 FOR ALL TABLES WITH (publish = '');\E /xm, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'CREATE SUBSCRIPTION sub1' => { create_order => 50, @@ -2064,9 +2206,8 @@ regexp => qr/^ \QCREATE SUBSCRIPTION sub1 CONNECTION 'dbname=doesnotexist' PUBLICATION pub1 WITH (connect = false, slot_name = 'sub1');\E /xm, - like => { - %full_runs, - section_post_data => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + }, 'ALTER PUBLICATION pub1 ADD TABLE test_table' => { create_order => 51, @@ -2075,12 +2216,12 @@ regexp => qr/^ \QALTER PUBLICATION pub1 ADD TABLE ONLY dump_test.test_table;\E /xm, - like => { - %full_runs, - section_post_data => 1, }, + like => { %full_runs, section_post_data => 1, }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'ALTER PUBLICATION pub1 ADD TABLE test_second_table' => { create_order => 52, @@ -2089,27 +2230,25 @@ regexp => qr/^ \QALTER PUBLICATION pub1 ADD TABLE ONLY dump_test.test_second_table;\E /xm, - like => { - %full_runs, - section_post_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => { %full_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE SCHEMA public' => { - regexp => qr/^CREATE SCHEMA public;/m, + regexp => qr/^CREATE SCHEMA public;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'CREATE SCHEMA dump_test' => { create_order => 2, create_sql => 'CREATE SCHEMA dump_test;', regexp => qr/^CREATE SCHEMA dump_test;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE SCHEMA dump_test_second_schema' => { create_order => 9, @@ -2117,8 +2256,10 @@ regexp => qr/^CREATE SCHEMA dump_test_second_schema;/m, like => { %full_runs, - role => 1, - section_pre_data => 1, }, }, + role => 1, + section_pre_data => 1, + }, + }, 'CREATE TABLE test_table' => { create_order => 3, @@ -2141,11 +2282,14 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, }, }, + exclude_test_table => 1, + }, + }, 'CREATE TABLE fk_reference_test_table' => { create_order => 21, @@ -2157,12 +2301,10 @@ \n\s+\Qcol1 integer NOT NULL\E \n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TABLE test_second_table' => { create_order => 6, @@ -2176,43 +2318,17 @@ \n\s+\Qcol2 text\E \n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, - - 'CREATE UNLOGGED TABLE test_third_table WITH OIDS' => { - create_order => 11, - create_sql => - 'CREATE UNLOGGED TABLE dump_test_second_schema.test_third_table ( - col1 serial - ) WITH OIDS;', - regexp => qr/^ - \QSET default_with_oids = true;\E\n\n - \Q--\E\n - (\Q-- TOC entry \E[0-9]+\ \(class\ 1259\ OID\ [0-9]+\)\n)? - \Q-- Name: test_third_table;\E.*\n - \Q--\E\n\n - \QCREATE UNLOGGED TABLE dump_test_second_schema.test_third_table (\E - \n\s+\Qcol1 integer NOT NULL\E - \n\);\n - /xm, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - # FIXME figure out why/how binary upgrade drops OIDs. - binary_upgrade => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TABLE measurement PARTITIONED BY' => { create_order => 90, create_sql => 'CREATE TABLE dump_test.measurement ( - city_id int not null, + city_id serial not null, logdate date not null, - peaktemp int, + peaktemp int CHECK (peaktemp >= -460), unitsales int ) PARTITION BY RANGE (logdate);', regexp => qr/^ @@ -2222,36 +2338,44 @@ \s+\Qcity_id integer NOT NULL,\E\n \s+\Qlogdate date NOT NULL,\E\n \s+\Qpeaktemp integer,\E\n - \s+\Qunitsales integer\E\n + \s+\Qunitsales integer,\E\n + \s+\QCONSTRAINT measurement_peaktemp_check CHECK ((peaktemp >= '-460'::integer))\E\n \)\n \QPARTITION BY RANGE (logdate);\E\n /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { - binary_upgrade => 1, - exclude_dump_test_schema => 1, }, }, + binary_upgrade => 1, + exclude_dump_test_schema => 1, + }, + }, - 'CREATE TABLE measurement_y2006m2 PARTITION OF' => { + 'Partition measurement_y2006m2 creation' => { create_order => 91, create_sql => 'CREATE TABLE dump_test_second_schema.measurement_y2006m2 - PARTITION OF dump_test.measurement FOR VALUES - FROM (\'2006-02-01\') TO (\'2006-03-01\');', + PARTITION OF dump_test.measurement ( + unitsales DEFAULT 0 CHECK (unitsales >= 0) + ) + FOR VALUES FROM (\'2006-02-01\') TO (\'2006-03-01\');', regexp => qr/^ - \Q-- Name: measurement_y2006m2;\E.*\n - \Q--\E\n\n - \QCREATE TABLE dump_test_second_schema.measurement_y2006m2 PARTITION OF dump_test.measurement\E\n - \QFOR VALUES FROM ('2006-02-01') TO ('2006-03-01');\E\n + \QCREATE TABLE dump_test_second_schema.measurement_y2006m2 (\E\n + \s+\Qcity_id integer DEFAULT nextval('dump_test.measurement_city_id_seq'::regclass) NOT NULL,\E\n + \s+\Qlogdate date NOT NULL,\E\n + \s+\Qpeaktemp integer,\E\n + \s+\Qunitsales integer DEFAULT 0,\E\n + \s+\QCONSTRAINT measurement_peaktemp_check CHECK ((peaktemp >= '-460'::integer)),\E\n + \s+\QCONSTRAINT measurement_y2006m2_unitsales_check CHECK ((unitsales >= 0))\E\n + \);\n /xm, like => { %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - binary_upgrade => 1, }, }, + section_pre_data => 1, + role => 1, + binary_upgrade => 1, + }, + }, 'CREATE TABLE test_fourth_table_zero_col' => { create_order => 6, @@ -2261,12 +2385,10 @@ \QCREATE TABLE dump_test.test_fourth_table (\E \n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TABLE test_fifth_table' => { create_order => 53, @@ -2286,12 +2408,10 @@ \n\s+\Qcol5 double precision\E \n\); /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE TABLE test_table_identity' => { create_order => 3, @@ -2314,12 +2434,89 @@ \s+\QCACHE 1\E\n \); /xms, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE TABLE test_table_generated' => { + create_order => 3, + create_sql => 'CREATE TABLE dump_test.test_table_generated ( + col1 int primary key, + col2 int generated always as (col1 * 2) stored + );', + regexp => qr/^ + \QCREATE TABLE dump_test.test_table_generated (\E\n + \s+\Qcol1 integer NOT NULL,\E\n + \s+\Qcol2 integer GENERATED ALWAYS AS ((col1 * 2)) STORED\E\n + \); + /xms, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE TABLE table_with_stats' => { + create_order => 98, + create_sql => 'CREATE TABLE dump_test.table_index_stats ( + col1 int, + col2 int, + col3 int); + CREATE INDEX index_with_stats + ON dump_test.table_index_stats + ((col1 + 1), col1, (col2 + 1), (col3 + 1)); + ALTER INDEX dump_test.index_with_stats + ALTER COLUMN 1 SET STATISTICS 400; + ALTER INDEX dump_test.index_with_stats + ALTER COLUMN 3 SET STATISTICS 500;', + regexp => qr/^ + \QALTER INDEX dump_test.index_with_stats ALTER COLUMN 1 SET STATISTICS 400;\E\n + \QALTER INDEX dump_test.index_with_stats ALTER COLUMN 3 SET STATISTICS 500;\E\n + /xms, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE TABLE test_inheritance_parent' => { + create_order => 90, + create_sql => 'CREATE TABLE dump_test.test_inheritance_parent ( + col1 int NOT NULL, + col2 int CHECK (col2 >= 42) + );', + regexp => qr/^ + \QCREATE TABLE dump_test.test_inheritance_parent (\E\n + \s+\Qcol1 integer NOT NULL,\E\n + \s+\Qcol2 integer,\E\n + \s+\QCONSTRAINT test_inheritance_parent_col2_check CHECK ((col2 >= 42))\E\n + \Q);\E\n + /xm, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'CREATE TABLE test_inheritance_child' => { + create_order => 91, + create_sql => 'CREATE TABLE dump_test.test_inheritance_child ( + col1 int NOT NULL, + CONSTRAINT test_inheritance_child CHECK (col2 >= 142857) + ) INHERITS (dump_test.test_inheritance_parent);', + regexp => qr/^ + \QCREATE TABLE dump_test.test_inheritance_child (\E\n + \s+\Qcol1 integer,\E\n + \s+\QCONSTRAINT test_inheritance_child CHECK ((col2 >= 142857))\E\n + \)\n + \QINHERITS (dump_test.test_inheritance_parent);\E\n + /xm, like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + %full_runs, %dump_test_schema_runs, section_pre_data => 1, + }, unlike => { - exclude_dump_test_schema => 1, }, }, + binary_upgrade => 1, + exclude_dump_test_schema => 1, + }, + }, 'CREATE STATISTICS extended_stats_no_options' => { create_order => 97, @@ -2328,12 +2525,10 @@ regexp => qr/^ \QCREATE STATISTICS dump_test.test_ext_stats_no_options ON col1, col2 FROM dump_test.test_fifth_table;\E /xms, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE STATISTICS extended_stats_options' => { create_order => 97, @@ -2342,15 +2537,24 @@ regexp => qr/^ \QCREATE STATISTICS dump_test.test_ext_stats_opts (ndistinct) ON col1, col2 FROM dump_test.test_fifth_table;\E /xms, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, + + 'ALTER STATISTICS extended_stats_options' => { + create_order => 98, + create_sql => 'ALTER STATISTICS dump_test.test_ext_stats_opts SET STATISTICS 1000', + regexp => qr/^ + \QALTER STATISTICS dump_test.test_ext_stats_opts SET STATISTICS 1000;\E + /xms, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE SEQUENCE test_table_col1_seq' => { - regexp => qr/^ + regexp => qr/^ \QCREATE SEQUENCE dump_test.test_table_col1_seq\E \n\s+\QAS integer\E \n\s+\QSTART WITH 1\E @@ -2362,108 +2566,88 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, - - 'CREATE SEQUENCE test_third_table_col1_seq' => { - regexp => qr/^ - \QCREATE SEQUENCE dump_test_second_schema.test_third_table_col1_seq\E - \n\s+\QAS integer\E - \n\s+\QSTART WITH 1\E - \n\s+\QINCREMENT BY 1\E - \n\s+\QNO MINVALUE\E - \n\s+\QNO MAXVALUE\E - \n\s+\QCACHE 1;\E - /xm, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, }, - - 'CREATE UNIQUE INDEX test_third_table_idx ON test_third_table' => { - create_order => 13, - create_sql => 'CREATE UNIQUE INDEX test_third_table_idx - ON dump_test_second_schema.test_third_table (col1);', - regexp => qr/^ - \QCREATE UNIQUE INDEX test_third_table_idx \E - \QON dump_test_second_schema.test_third_table USING btree (col1);\E - /xm, - like => { - %full_runs, - role => 1, - section_post_data => 1, }, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE INDEX ON ONLY measurement' => { create_order => 92, - create_sql => 'CREATE INDEX ON dump_test.measurement (city_id, logdate);', + create_sql => + 'CREATE INDEX ON dump_test.measurement (city_id, logdate);', regexp => qr/^ \QCREATE INDEX measurement_city_id_logdate_idx ON ONLY dump_test.measurement USING\E /xm, like => { - binary_upgrade => 1, - clean => 1, - clean_if_exists => 1, - createdb => 1, - defaults => 1, - exclude_test_table => 1, - exclude_test_table_data => 1, - no_blobs => 1, - no_privs => 1, - no_owner => 1, - only_dump_test_schema => 1, - pg_dumpall_dbprivs => 1, - schema_only => 1, - section_post_data => 1, - test_schema_plus_blobs => 1, - with_oids => 1, }, + binary_upgrade => 1, + clean => 1, + clean_if_exists => 1, + createdb => 1, + defaults => 1, + exclude_test_table => 1, + exclude_test_table_data => 1, + no_blobs => 1, + no_privs => 1, + no_owner => 1, + only_dump_test_schema => 1, + pg_dumpall_dbprivs => 1, + pg_dumpall_exclude => 1, + schema_only => 1, + section_post_data => 1, + test_schema_plus_blobs => 1, + }, unlike => { exclude_dump_test_schema => 1, only_dump_test_table => 1, pg_dumpall_globals => 1, pg_dumpall_globals_clean => 1, role => 1, - section_pre_data => 1, }, }, + section_pre_data => 1, + }, + }, 'ALTER TABLE measurement PRIMARY KEY' => { all_runs => 1, catch_all => 'CREATE ... commands', create_order => 93, - create_sql => 'ALTER TABLE dump_test.measurement ADD PRIMARY KEY (city_id, logdate);', + create_sql => + 'ALTER TABLE dump_test.measurement ADD PRIMARY KEY (city_id, logdate);', regexp => qr/^ \QALTER TABLE ONLY dump_test.measurement\E \n^\s+ \QADD CONSTRAINT measurement_pkey PRIMARY KEY (city_id, logdate);\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'CREATE INDEX ... ON measurement_y2006_m2' => { - regexp => qr/^ + regexp => qr/^ \QCREATE INDEX measurement_y2006m2_city_id_logdate_idx ON dump_test_second_schema.measurement_y2006m2 \E /xm, like => { %full_runs, - role => 1, - section_post_data => 1, }, }, + role => 1, + section_post_data => 1, + }, + }, 'ALTER INDEX ... ATTACH PARTITION' => { - regexp => qr/^ + regexp => qr/^ \QALTER INDEX dump_test.measurement_city_id_logdate_idx ATTACH PARTITION dump_test_second_schema.measurement_y2006m2_city_id_logdate_idx\E /xm, like => { %full_runs, - role => 1, - section_post_data => 1, }, }, + role => 1, + section_post_data => 1, + }, + }, 'ALTER INDEX ... ATTACH PARTITION (primary key)' => { - all_runs => 1, - catch_all => 'CREATE ... commands', - regexp => qr/^ + all_runs => 1, + catch_all => 'CREATE ... commands', + regexp => qr/^ \QALTER INDEX dump_test.measurement_pkey ATTACH PARTITION dump_test_second_schema.measurement_y2006m2_pkey\E /xm, like => { @@ -2479,17 +2663,20 @@ no_privs => 1, no_owner => 1, pg_dumpall_dbprivs => 1, + pg_dumpall_exclude => 1, role => 1, schema_only => 1, section_post_data => 1, - with_oids => 1, }, + }, unlike => { only_dump_test_schema => 1, only_dump_test_table => 1, pg_dumpall_globals => 1, pg_dumpall_globals_clean => 1, section_pre_data => 1, - test_schema_plus_blobs => 1, }, }, + test_schema_plus_blobs => 1, + }, + }, 'CREATE VIEW test_view' => { create_order => 61, @@ -2501,12 +2688,10 @@ \n\s+\QSELECT test_table.col1\E \n\s+\QFROM dump_test.test_table\E \n\s+\QWITH LOCAL CHECK OPTION;\E/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, 'ALTER VIEW test_view SET DEFAULT' => { create_order => 62, @@ -2514,12 +2699,10 @@ 'ALTER VIEW dump_test.test_view ALTER COLUMN col1 SET DEFAULT 1;', regexp => qr/^ \QALTER TABLE ONLY dump_test.test_view ALTER COLUMN col1 SET DEFAULT 1;\E/xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, - unlike => { - exclude_dump_test_schema => 1, }, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, + unlike => { exclude_dump_test_schema => 1, }, + }, # FIXME 'DROP SCHEMA public (for testing without public schema)' => { @@ -2527,104 +2710,119 @@ create_order => 100, create_sql => 'DROP SCHEMA public;', regexp => qr/^DROP SCHEMA public;/m, - like => {}, }, + like => {}, + }, 'DROP SCHEMA public' => { - regexp => qr/^DROP SCHEMA public;/m, + regexp => qr/^DROP SCHEMA public;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'DROP SCHEMA IF EXISTS public' => { - regexp => qr/^DROP SCHEMA IF EXISTS public;/m, + regexp => qr/^DROP SCHEMA IF EXISTS public;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'DROP EXTENSION plpgsql' => { - regexp => qr/^DROP EXTENSION plpgsql;/m, + regexp => qr/^DROP EXTENSION plpgsql;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'DROP FUNCTION dump_test.pltestlang_call_handler()' => { regexp => qr/^DROP FUNCTION dump_test\.pltestlang_call_handler\(\);/m, - like => { clean => 1, }, }, + like => { clean => 1, }, + }, 'DROP LANGUAGE pltestlang' => { - regexp => qr/^DROP PROCEDURAL LANGUAGE pltestlang;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP PROCEDURAL LANGUAGE pltestlang;/m, + like => { clean => 1, }, + }, 'DROP SCHEMA dump_test' => { - regexp => qr/^DROP SCHEMA dump_test;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP SCHEMA dump_test;/m, + like => { clean => 1, }, + }, 'DROP SCHEMA dump_test_second_schema' => { - regexp => qr/^DROP SCHEMA dump_test_second_schema;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP SCHEMA dump_test_second_schema;/m, + like => { clean => 1, }, + }, 'DROP TABLE test_table' => { - regexp => qr/^DROP TABLE dump_test\.test_table;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP TABLE dump_test\.test_table;/m, + like => { clean => 1, }, + }, 'DROP TABLE fk_reference_test_table' => { - regexp => qr/^DROP TABLE dump_test\.fk_reference_test_table;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP TABLE dump_test\.fk_reference_test_table;/m, + like => { clean => 1, }, + }, 'DROP TABLE test_second_table' => { - regexp => qr/^DROP TABLE dump_test\.test_second_table;/m, - like => { clean => 1, }, }, - - 'DROP TABLE test_third_table' => { - regexp => qr/^DROP TABLE dump_test_second_schema\.test_third_table;/m, - like => { clean => 1, }, }, + regexp => qr/^DROP TABLE dump_test\.test_second_table;/m, + like => { clean => 1, }, + }, 'DROP EXTENSION IF EXISTS plpgsql' => { - regexp => qr/^DROP EXTENSION IF EXISTS plpgsql;/m, + regexp => qr/^DROP EXTENSION IF EXISTS plpgsql;/m, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'DROP FUNCTION IF EXISTS dump_test.pltestlang_call_handler()' => { - regexp => qr/^ + regexp => qr/^ \QDROP FUNCTION IF EXISTS dump_test.pltestlang_call_handler();\E /xm, - like => { clean_if_exists => 1, }, }, + like => { clean_if_exists => 1, }, + }, 'DROP LANGUAGE IF EXISTS pltestlang' => { - regexp => qr/^DROP PROCEDURAL LANGUAGE IF EXISTS pltestlang;/m, - like => { clean_if_exists => 1, }, }, + regexp => qr/^DROP PROCEDURAL LANGUAGE IF EXISTS pltestlang;/m, + like => { clean_if_exists => 1, }, + }, 'DROP SCHEMA IF EXISTS dump_test' => { - regexp => qr/^DROP SCHEMA IF EXISTS dump_test;/m, - like => { clean_if_exists => 1, }, }, + regexp => qr/^DROP SCHEMA IF EXISTS dump_test;/m, + like => { clean_if_exists => 1, }, + }, 'DROP SCHEMA IF EXISTS dump_test_second_schema' => { - regexp => qr/^DROP SCHEMA IF EXISTS dump_test_second_schema;/m, - like => { clean_if_exists => 1, }, }, + regexp => qr/^DROP SCHEMA IF EXISTS dump_test_second_schema;/m, + like => { clean_if_exists => 1, }, + }, 'DROP TABLE IF EXISTS test_table' => { - regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_table;/m, - like => { clean_if_exists => 1, }, }, + regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_table;/m, + like => { clean_if_exists => 1, }, + }, 'DROP TABLE IF EXISTS test_second_table' => { - regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_second_table;/m, - like => { clean_if_exists => 1, }, }, - - 'DROP TABLE IF EXISTS test_third_table' => { - regexp => qr/^ - \QDROP TABLE IF EXISTS dump_test_second_schema.test_third_table;\E - /xm, - like => { clean_if_exists => 1, }, }, + regexp => qr/^DROP TABLE IF EXISTS dump_test\.test_second_table;/m, + like => { clean_if_exists => 1, }, + }, 'DROP ROLE regress_dump_test_role' => { - regexp => qr/^ + regexp => qr/^ \QDROP ROLE regress_dump_test_role;\E /xm, - like => { pg_dumpall_globals_clean => 1, }, }, + like => { pg_dumpall_globals_clean => 1, }, + }, 'DROP ROLE pg_' => { - regexp => qr/^ - \QDROP ROLE pg_\E.*; + regexp => qr/^ + \QDROP ROLE pg_\E.+; /xm, + # this shouldn't ever get emitted anywhere - like => {}, }, + like => {}, + }, 'GRANT USAGE ON SCHEMA dump_test_second_schema' => { create_order => 10, @@ -2635,10 +2833,11 @@ /xm, like => { %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + role => 1, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON FOREIGN DATA WRAPPER dummy' => { create_order => 85, @@ -2647,11 +2846,9 @@ regexp => qr/^ \QGRANT ALL ON FOREIGN DATA WRAPPER dummy TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON FOREIGN SERVER s1' => { create_order => 85, @@ -2660,26 +2857,24 @@ regexp => qr/^ \QGRANT ALL ON FOREIGN SERVER s1 TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON DOMAIN dump_test.us_postal_code' => { create_order => 72, create_sql => -'GRANT USAGE ON DOMAIN dump_test.us_postal_code TO regress_dump_test_role;', + 'GRANT USAGE ON DOMAIN dump_test.us_postal_code TO regress_dump_test_role;', regexp => qr/^ \QGRANT ALL ON TYPE dump_test.us_postal_code TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT USAGE ON TYPE dump_test.int42' => { create_order => 87, @@ -2688,13 +2883,13 @@ regexp => qr/^ \QGRANT ALL ON TYPE dump_test.int42 TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT USAGE ON TYPE dump_test.planets - ENUM' => { create_order => 66, @@ -2703,27 +2898,28 @@ regexp => qr/^ \QGRANT ALL ON TYPE dump_test.planets TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT USAGE ON TYPE dump_test.textrange - RANGE' => { create_order => 67, - create_sql => 'GRANT USAGE ON TYPE dump_test.textrange TO regress_dump_test_role;', + create_sql => + 'GRANT USAGE ON TYPE dump_test.textrange TO regress_dump_test_role;', regexp => qr/^ \QGRANT ALL ON TYPE dump_test.textrange TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT CREATE ON DATABASE dump_test' => { create_order => 48, @@ -2732,52 +2928,27 @@ regexp => qr/^ \QGRANT CREATE ON DATABASE dump_test TO regress_dump_test_role;\E /xm, - like => { pg_dumpall_dbprivs => 1, }, }, + like => { pg_dumpall_dbprivs => 1, }, + }, 'GRANT SELECT ON TABLE test_table' => { create_order => 5, create_sql => 'GRANT SELECT ON TABLE dump_test.test_table TO regress_dump_test_role;', regexp => - qr/^GRANT SELECT ON TABLE dump_test.test_table TO regress_dump_test_role;/m, + qr/^\QGRANT SELECT ON TABLE dump_test.test_table TO regress_dump_test_role;\E/m, like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - section_pre_data => 1, }, + only_dump_test_table => 1, + section_pre_data => 1, + }, unlike => { exclude_dump_test_schema => 1, - exclude_test_table => 1, - no_privs => 1, }, }, - - 'GRANT SELECT ON TABLE test_third_table' => { - create_order => 19, - create_sql => 'GRANT SELECT ON - TABLE dump_test_second_schema.test_third_table - TO regress_dump_test_role;', - regexp => -qr/^GRANT SELECT ON TABLE dump_test_second_schema.test_third_table TO regress_dump_test_role;/m, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, - - 'GRANT ALL ON SEQUENCE test_third_table_col1_seq' => { - create_order => 28, - create_sql => 'GRANT ALL ON SEQUENCE - dump_test_second_schema.test_third_table_col1_seq - TO regress_dump_test_role;', - regexp => qr/^ - \QGRANT ALL ON SEQUENCE dump_test_second_schema.test_third_table_col1_seq TO regress_dump_test_role;\E - /xm, - like => { - %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + exclude_test_table => 1, + no_privs => 1, + }, + }, 'GRANT SELECT ON TABLE measurement' => { create_order => 91, @@ -2785,27 +2956,29 @@ TABLE dump_test.measurement TO regress_dump_test_role;', regexp => - qr/^GRANT SELECT ON TABLE dump_test.measurement TO regress_dump_test_role;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + qr/^\QGRANT SELECT ON TABLE dump_test.measurement TO regress_dump_test_role;\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT SELECT ON TABLE measurement_y2006m2' => { create_order => 92, create_sql => 'GRANT SELECT ON TABLE dump_test_second_schema.measurement_y2006m2 TO regress_dump_test_role;', - regexp => qr/^GRANT SELECT ON TABLE dump_test_second_schema.measurement_y2006m2 TO regress_dump_test_role;/m, + regexp => + qr/^\QGRANT SELECT ON TABLE dump_test_second_schema.measurement_y2006m2 TO regress_dump_test_role;\E/m, like => { %full_runs, - role => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + role => 1, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, 'GRANT ALL ON LARGE OBJECT ...' => { create_order => 60, @@ -2821,15 +2994,18 @@ /xm, like => { %full_runs, - column_inserts => 1, - data_only => 1, - section_pre_data => 1, - test_schema_plus_blobs => 1, }, + column_inserts => 1, + data_only => 1, + section_pre_data => 1, + test_schema_plus_blobs => 1, + binary_upgrade => 1, + }, unlike => { - binary_upgrade => 1, - no_blobs => 1, - no_privs => 1, - schema_only => 1, }, }, + no_blobs => 1, + no_privs => 1, + schema_only => 1, + }, + }, 'GRANT INSERT(col1) ON TABLE test_second_table' => { create_order => 8, @@ -2839,13 +3015,13 @@ regexp => qr/^ \QGRANT INSERT(col1) ON TABLE dump_test.test_second_table TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - %dump_test_schema_runs, - section_pre_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_pre_data => 1, }, unlike => { exclude_dump_test_schema => 1, - no_privs => 1, }, }, + no_privs => 1, + }, + }, 'GRANT EXECUTE ON FUNCTION pg_sleep() TO regress_dump_test_role' => { create_order => 16, @@ -2854,11 +3030,9 @@ regexp => qr/^ \QGRANT ALL ON FUNCTION pg_catalog.pg_sleep(double precision) TO regress_dump_test_role;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'GRANT SELECT (proname ...) ON TABLE pg_proc TO public' => { create_order => 46, @@ -2872,7 +3046,7 @@ procost, prorows, provariadic, - protransform, + prosupport, prokind, prosecdef, proleakproof, @@ -2904,7 +3078,7 @@ \QGRANT SELECT(procost) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(prorows) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(provariadic) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* - \QGRANT SELECT(protransform) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* + \QGRANT SELECT(prosupport) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(prokind) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(prosecdef) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(proleakproof) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* @@ -2925,59 +3099,61 @@ \QGRANT SELECT(probin) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(proconfig) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E\n.* \QGRANT SELECT(proacl) ON TABLE pg_catalog.pg_proc TO PUBLIC;\E/xms, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON SCHEMA public TO public' => { regexp => qr/^ \Q--\E\n\n \QGRANT USAGE ON SCHEMA public TO PUBLIC;\E /xm, + # this shouldn't ever get emitted anymore - like => {}, }, + like => {}, + }, 'REFRESH MATERIALIZED VIEW matview' => { - regexp => qr/^REFRESH MATERIALIZED VIEW dump_test.matview;/m, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, + regexp => qr/^\QREFRESH MATERIALIZED VIEW dump_test.matview;\E/m, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, 'REFRESH MATERIALIZED VIEW matview_second' => { - regexp => qr/^ + regexp => qr/^ \QREFRESH MATERIALIZED VIEW dump_test.matview;\E \n.* \QREFRESH MATERIALIZED VIEW dump_test.matview_second;\E /xms, - like => { - %full_runs, - %dump_test_schema_runs, - section_post_data => 1, }, + like => + { %full_runs, %dump_test_schema_runs, section_post_data => 1, }, unlike => { - binary_upgrade => 1, + binary_upgrade => 1, exclude_dump_test_schema => 1, - schema_only => 1, }, }, + schema_only => 1, + }, + }, # FIXME 'REFRESH MATERIALIZED VIEW matview_third' => { - regexp => qr/^ + regexp => qr/^ \QREFRESH MATERIALIZED VIEW dump_test.matview_third;\E /xms, - like => {}, }, + like => {}, + }, # FIXME 'REFRESH MATERIALIZED VIEW matview_fourth' => { - regexp => qr/^ + regexp => qr/^ \QREFRESH MATERIALIZED VIEW dump_test.matview_fourth;\E /xms, - like => {}, }, + like => {}, + }, 'REVOKE CONNECT ON DATABASE dump_test FROM public' => { create_order => 49, @@ -2987,7 +3163,8 @@ \QGRANT TEMPORARY ON DATABASE dump_test TO PUBLIC;\E\n \QGRANT CREATE ON DATABASE dump_test TO regress_dump_test_role;\E /xm, - like => { pg_dumpall_dbprivs => 1, }, }, + like => { pg_dumpall_dbprivs => 1, }, + }, 'REVOKE EXECUTE ON FUNCTION pg_sleep() FROM public' => { create_order => 15, @@ -2996,21 +3173,18 @@ regexp => qr/^ \QREVOKE ALL ON FUNCTION pg_catalog.pg_sleep(double precision) FROM PUBLIC;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'REVOKE SELECT ON TABLE pg_proc FROM public' => { create_order => 45, create_sql => 'REVOKE SELECT ON TABLE pg_proc FROM public;', - regexp => qr/^REVOKE SELECT ON TABLE pg_catalog.pg_proc FROM PUBLIC;/m, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + regexp => + qr/^\QREVOKE SELECT ON TABLE pg_catalog.pg_proc FROM PUBLIC;\E/m, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'REVOKE CREATE ON SCHEMA public FROM public' => { create_order => 16, @@ -3019,11 +3193,9 @@ \QREVOKE ALL ON SCHEMA public FROM PUBLIC;\E \n\QGRANT USAGE ON SCHEMA public TO PUBLIC;\E /xm, - like => { - %full_runs, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + like => { %full_runs, section_pre_data => 1, }, + unlike => { no_privs => 1, }, + }, 'REVOKE USAGE ON LANGUAGE plpgsql FROM public' => { create_order => 16, @@ -3032,13 +3204,69 @@ like => { %full_runs, %dump_test_schema_runs, - only_dump_test_table => 1, - role => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + only_dump_test_table => 1, + role => 1, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, + -); + 'CREATE ACCESS METHOD regress_test_table_am' => { + create_order => 11, + create_sql => + 'CREATE ACCESS METHOD regress_table_am TYPE TABLE HANDLER heap_tableam_handler;', + regexp => qr/^ + \QCREATE ACCESS METHOD regress_table_am TYPE TABLE HANDLER heap_tableam_handler;\E + \n/xm, + like => { + %full_runs, section_pre_data => 1, + }, + }, + + # It's a bit tricky to ensure that the proper SET of default table + # AM occurs. To achieve that we create a table with the standard + # AM, test AM, standard AM. That guarantees that there needs to be + # a SET interspersed. Then use a regex that prevents interspersed + # SET ...; statements, followed by the expected CREATE TABLE. Not + # pretty, but seems hard to do better in this framework. + 'CREATE TABLE regress_pg_dump_table_am' => { + create_order => 12, + create_sql => ' + CREATE TABLE dump_test.regress_pg_dump_table_am_0() USING heap; + CREATE TABLE dump_test.regress_pg_dump_table_am_1 (col1 int) USING regress_table_am; + CREATE TABLE dump_test.regress_pg_dump_table_am_2() USING heap;', + regexp => qr/^ + \QSET default_table_access_method = regress_table_am;\E + (\n(?!SET[^;]+;)[^\n]*)* + \n\QCREATE TABLE dump_test.regress_pg_dump_table_am_1 (\E + \n\s+\Qcol1 integer\E + \n\);/xm, + like => { + %full_runs, %dump_test_schema_runs, section_pre_data => 1, + }, + unlike => { exclude_dump_test_schema => 1 }, + }, + + 'CREATE MATERIALIZED VIEW regress_pg_dump_matview_am' => { + create_order => 13, + create_sql => ' + CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_0 USING heap AS SELECT 1; + CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_1 + USING regress_table_am AS SELECT count(*) FROM pg_class; + CREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_2 USING heap AS SELECT 1;', + regexp => qr/^ + \QSET default_table_access_method = regress_table_am;\E + (\n(?!SET[^;]+;)[^\n]*)* + \QCREATE MATERIALIZED VIEW dump_test.regress_pg_dump_matview_am_1 AS\E + \n\s+\QSELECT count(*) AS count\E + \n\s+\QFROM pg_class\E + \n\s+\QWITH NO DATA;\E\n/xm, + like => { + %full_runs, %dump_test_schema_runs, section_pre_data => 1, + }, + unlike => { exclude_dump_test_schema => 1 }, + }); ######################################### # Create a PG instance to test actually dumping from @@ -3122,7 +3350,8 @@ } # If there is a like entry, but no unlike entry, then we will test the like case - if ($tests{$test}->{like}->{$test_key} && !defined($tests{$test}->{unlike}->{$test_key})) + if ($tests{$test}->{like}->{$test_key} + && !defined($tests{$test}->{unlike}->{$test_key})) { $num_tests++; } @@ -3193,40 +3422,39 @@ command_fails_like( [ 'pg_dump', '-p', "$port", 'qqq' ], -qr/\Qpg_dump: [archiver (db)] connection to database "qqq" failed: FATAL: database "qqq" does not exist\E/, -'pg_dump: [archiver (db)] connection to database "qqq" failed: FATAL: database "qqq" does not exist' -); + qr/\Qpg_dump: error: connection to database "qqq" failed: FATAL: database "qqq" does not exist\E/, + 'connecting to a non-existent database'); ######################################### # Test connecting with an unprivileged user command_fails_like( [ 'pg_dump', '-p', "$port", '--role=regress_dump_test_role' ], -qr/\Qpg_dump: [archiver (db)] query failed: ERROR: permission denied for\E/, - 'pg_dump: [archiver (db)] query failed: ERROR: permission denied for'); + qr/\Qpg_dump: error: query failed: ERROR: permission denied for\E/, + 'connecting with an unprivileged user'); ######################################### # Test dumping a non-existent schema, table, and patterns with --strict-names command_fails_like( - [ 'pg_dump', '-p', "$port", '-n', 'nonexistant' ], - qr/\Qpg_dump: no matching schemas were found\E/, - 'pg_dump: no matching schemas were found'); + [ 'pg_dump', '-p', "$port", '-n', 'nonexistent' ], + qr/\Qpg_dump: error: no matching schemas were found\E/, + 'dumping a non-existent schema'); command_fails_like( - [ 'pg_dump', '-p', "$port", '-t', 'nonexistant' ], - qr/\Qpg_dump: no matching tables were found\E/, - 'pg_dump: no matching tables were found'); + [ 'pg_dump', '-p', "$port", '-t', 'nonexistent' ], + qr/\Qpg_dump: error: no matching tables were found\E/, + 'dumping a non-existent table'); command_fails_like( - [ 'pg_dump', '-p', "$port", '--strict-names', '-n', 'nonexistant*' ], - qr/\Qpg_dump: no matching schemas were found for pattern\E/, - 'pg_dump: no matching schemas were found for pattern'); + [ 'pg_dump', '-p', "$port", '--strict-names', '-n', 'nonexistent*' ], + qr/\Qpg_dump: error: no matching schemas were found for pattern\E/, + 'no matching schemas'); command_fails_like( - [ 'pg_dump', '-p', "$port", '--strict-names', '-t', 'nonexistant*' ], - qr/\Qpg_dump: no matching tables were found for pattern\E/, - 'pg_dump: no matching tables were found for pattern'); + [ 'pg_dump', '-p', "$port", '--strict-names', '-t', 'nonexistent*' ], + qr/\Qpg_dump: error: no matching tables were found for pattern\E/, + 'no matching tables'); ######################################### # Run all runs @@ -3283,19 +3511,19 @@ # Run the test listed as a like, unless it is specifically noted # as an unlike (generally due to an explicit exclusion or similar). - if ($tests{$test}->{like}->{$test_key} && !defined($tests{$test}->{unlike}->{$test_key})) + if ($tests{$test}->{like}->{$test_key} + && !defined($tests{$test}->{unlike}->{$test_key})) { - if (!ok($output_file =~ $tests{$test}->{regexp}, "$run: should dump $test")) + if (!ok($output_file =~ $tests{$test}->{regexp}, + "$run: should dump $test")) { diag("Review $run results in $tempdir"); } } else { - if (!ok( - $output_file !~ - $tests{$test}->{regexp}, - "$run: should not dump $test")) + if (!ok($output_file !~ $tests{$test}->{regexp}, + "$run: should not dump $test")) { diag("Review $run results in $tempdir"); } diff --git a/src/bin/pg_dump/t/010_dump_connstr.pl b/src/bin/pg_dump/t/010_dump_connstr.pl index bf9bd525dfc..abdb07c5588 100644 --- a/src/bin/pg_dump/t/010_dump_connstr.pl +++ b/src/bin/pg_dump/t/010_dump_connstr.pl @@ -3,40 +3,63 @@ use PostgresNode; use TestLib; -use Test::More tests => 14; +use Test::More; -# In a SQL_ASCII database, pgwin32_message_to_UTF16() needs to -# interpret everything as UTF8. We're going to use byte sequences -# that aren't valid UTF-8 strings, so that would fail. Use LATIN1, -# which accepts any byte and has a conversion from each byte to UTF-8. +if ($^O eq 'msys' && `uname -or` =~ /^[2-9].*Msys/) +{ + plan skip_all => 'High bit name tests fail on Msys2'; +} +else +{ + plan tests => 14; +} + +# We're going to use byte sequences that aren't valid UTF-8 strings. Use +# LATIN1, which accepts any byte and has a conversion from each byte to UTF-8. $ENV{LC_ALL} = 'C'; $ENV{PGCLIENTENCODING} = 'LATIN1'; # Create database and user names covering the range of LATIN1 # characters, for use in a connection string by pg_dumpall. Skip ',' # because of pg_regress --create-role, skip [\n\r] because pg_dumpall -# does not allow them. +# does not allow them. We also skip many ASCII letters, to keep the +# total number of tested characters to what will fit in four names. +# The odds of finding something interesting by testing all ASCII letters +# seem too small to justify the cycles of testing a fifth name. my $dbname1 = - generate_ascii_string(1, 9) + 'regression' + . generate_ascii_string(1, 9) . generate_ascii_string(11, 12) . generate_ascii_string(14, 33) - . ($TestLib::windows_os ? '' : '"x"') - . # IPC::Run mishandles '"' on Windows - generate_ascii_string(35, 43) - . generate_ascii_string(45, 63); # contains '=' -my $dbname2 = - generate_ascii_string(67, 129); # skip 64-66 to keep length to 62 -my $dbname3 = generate_ascii_string(130, 192); -my $dbname4 = generate_ascii_string(193, 255); + . ($TestLib::windows_os ? '' : '"x"') # IPC::Run mishandles '"' on Windows + . generate_ascii_string(35, 43) # skip ',' + . generate_ascii_string(45, 54); +my $dbname2 = 'regression' . generate_ascii_string(55, 65) # skip 'B'-'W' + . generate_ascii_string(88, 99) # skip 'd'-'w' + . generate_ascii_string(120, 149); +my $dbname3 = 'regression' . generate_ascii_string(150, 202); +my $dbname4 = 'regression' . generate_ascii_string(203, 255); + +(my $username1 = $dbname1) =~ s/^regression/regress_/; +(my $username2 = $dbname2) =~ s/^regression/regress_/; +(my $username3 = $dbname3) =~ s/^regression/regress_/; +(my $username4 = $dbname4) =~ s/^regression/regress_/; + +my $src_bootstrap_super = 'regress_postgres'; +my $dst_bootstrap_super = 'boot'; my $node = get_new_node('main'); -$node->init(extra => [ '--locale=C', '--encoding=LATIN1' ]); +$node->init(extra => + [ '-U', $src_bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); # prep pg_hba.conf and pg_ident.conf $node->run_log( - [ $ENV{PG_REGRESS}, '--config-auth', - $node->data_dir, '--create-role', - "$dbname1,$dbname2,$dbname3,$dbname4" ]); + [ + $ENV{PG_REGRESS}, '--config-auth', + $node->data_dir, '--user', + $src_bootstrap_super, '--create-role', + "$username1,$username2,$username3,$username4" + ]); $node->start; my $backupdir = $node->backup_dir; @@ -44,80 +67,112 @@ my $plain = "$backupdir/plain.sql"; my $dirfmt = "$backupdir/dirfmt"; -foreach my $dbname ($dbname1, $dbname2, $dbname3, $dbname4, 'CamelCase') -{ - $node->run_log([ 'createdb', $dbname ]); - $node->run_log([ 'createuser', '-s', $dbname ]); -} +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname1 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username1 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname2 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username2 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname3 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username3 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname4 ]); +$node->run_log( + [ 'createuser', '-U', $src_bootstrap_super, '-s', $username4 ]); # For these tests, pg_dumpall -r is used because it produces a short # dump. $node->command_ok( - [ 'pg_dumpall', '-r', '-f', $discard, '--dbname', + [ + 'pg_dumpall', '-r', '-f', $discard, '--dbname', $node->connstr($dbname1), - '-U', $dbname4 ], + '-U', $username4 + ], 'pg_dumpall with long ASCII name 1'); $node->command_ok( - [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', + [ + 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname2), - '-U', $dbname3 ], + '-U', $username3 + ], 'pg_dumpall with long ASCII name 2'); $node->command_ok( - [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', + [ + 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname3), - '-U', $dbname2 ], + '-U', $username2 + ], 'pg_dumpall with long ASCII name 3'); $node->command_ok( - [ 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', + [ + 'pg_dumpall', '--no-sync', '-r', '-f', $discard, '--dbname', $node->connstr($dbname4), - '-U', $dbname1 ], + '-U', $username1 + ], 'pg_dumpall with long ASCII name 4'); $node->command_ok( - [ 'pg_dumpall', '--no-sync', '-r', '-l', 'dbname=template1' ], + [ + 'pg_dumpall', '-U', + $src_bootstrap_super, '--no-sync', + '-r', '-l', + 'dbname=template1' + ], 'pg_dumpall -l accepts connection string'); -$node->run_log([ 'createdb', "foo\n\rbar" ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, "foo\n\rbar" ]); # not sufficient to use -r here $node->command_fails( - [ 'pg_dumpall', '--no-sync', '-f', $discard ], + [ 'pg_dumpall', '-U', $src_bootstrap_super, '--no-sync', '-f', $discard ], 'pg_dumpall with \n\r in database name'); -$node->run_log([ 'dropdb', "foo\n\rbar" ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, "foo\n\rbar" ]); # make a table, so the parallel worker has something to dump -$node->safe_psql($dbname1, 'CREATE TABLE t0()'); +$node->safe_psql( + $dbname1, + 'CREATE TABLE t0()', + extra_params => [ '-U', $src_bootstrap_super ]); # XXX no printed message when this fails, just SIGPIPE termination $node->command_ok( - [ 'pg_dump', '-Fd', '--no-sync', '-j2', '-f', $dirfmt, '-U', $dbname1, - $node->connstr($dbname1) ], + [ + 'pg_dump', '-Fd', '--no-sync', '-j2', '-f', $dirfmt, '-U', $username1, + $node->connstr($dbname1) + ], 'parallel dump'); # recreate $dbname1 for restore test -$node->run_log([ 'dropdb', $dbname1 ]); -$node->run_log([ 'createdb', $dbname1 ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, $dbname1 ]); +$node->run_log([ 'createdb', '-U', $src_bootstrap_super, $dbname1 ]); $node->command_ok( - [ 'pg_restore', '-v', '-d', 'template1', '-j2', '-U', $dbname1, $dirfmt ], + [ + 'pg_restore', '-v', '-d', 'template1', + '-j2', '-U', $username1, $dirfmt + ], 'parallel restore'); -$node->run_log([ 'dropdb', $dbname1 ]); +$node->run_log([ 'dropdb', '-U', $src_bootstrap_super, $dbname1 ]); $node->command_ok( - [ 'pg_restore', '-C', '-v', '-d', - 'template1', '-j2', '-U', $dbname1, - $dirfmt ], + [ + 'pg_restore', '-C', '-v', '-d', + 'template1', '-j2', '-U', $username1, + $dirfmt + ], 'parallel restore with create'); -$node->command_ok([ 'pg_dumpall', '--no-sync', '-f', $plain, '-U', $dbname1 ], +$node->command_ok( + [ 'pg_dumpall', '--no-sync', '-f', $plain, '-U', $username1 ], 'take full dump'); system_log('cat', $plain); my ($stderr, $result); -my $bootstrap_super = 'boot'; -my $restore_super = qq{a'b\\c=d\\ne"f}; +my $restore_super = qq{regress_a'b\\c=d\\ne"f}; +$restore_super =~ s/"//g + if $TestLib::windows_os; # IPC::Run mishandles '"' on Windows # Restore full dump through psql using environment variables for @@ -125,16 +180,15 @@ my $envar_node = get_new_node('destination_envar'); $envar_node->init( - extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); -$envar_node->run_log( - [ $ENV{PG_REGRESS}, '--config-auth', - $envar_node->data_dir, '--create-role', - "$bootstrap_super,$restore_super" ]); + extra => + [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ], + auth_extra => + [ '--user', $dst_bootstrap_super, '--create-role', $restore_super ]); $envar_node->start; # make superuser for restore $envar_node->run_log( - [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); + [ 'createuser', '-U', $dst_bootstrap_super, '-s', $restore_super ]); { local $ENV{PGPORT} = $envar_node->port; @@ -151,22 +205,21 @@ # dbname/user connection parameters. "\connect dbname=" forgets # user/port from command line. -$restore_super =~ s/"//g - if $TestLib::windows_os; # IPC::Run mishandles '"' on Windows my $cmdline_node = get_new_node('destination_cmdline'); $cmdline_node->init( - extra => [ '-U', $bootstrap_super, '--locale=C', '--encoding=LATIN1' ]); -$cmdline_node->run_log( - [ $ENV{PG_REGRESS}, '--config-auth', - $cmdline_node->data_dir, '--create-role', - "$bootstrap_super,$restore_super" ]); + extra => + [ '-U', $dst_bootstrap_super, '--locale=C', '--encoding=LATIN1' ], + auth_extra => + [ '--user', $dst_bootstrap_super, '--create-role', $restore_super ]); $cmdline_node->start; $cmdline_node->run_log( - [ 'createuser', '-U', $bootstrap_super, '-s', $restore_super ]); + [ 'createuser', '-U', $dst_bootstrap_super, '-s', $restore_super ]); { $result = run_log( - [ 'psql', '-p', $cmdline_node->port, '-U', - $restore_super, '-X', '-f', $plain ], + [ + 'psql', '-p', $cmdline_node->port, '-U', + $restore_super, '-X', '-f', $plain + ], '2>', \$stderr); } diff --git a/src/bin/pg_resetwal/Makefile b/src/bin/pg_resetwal/Makefile index e49d52b9288..2a3835691fd 100644 --- a/src/bin/pg_resetwal/Makefile +++ b/src/bin/pg_resetwal/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_resetwal # -# Copyright (c) 1998-2018, PostgreSQL Global Development Group +# Copyright (c) 1998-2019, PostgreSQL Global Development Group # # src/bin/pg_resetwal/Makefile # diff --git a/src/bin/pg_resetwal/nls.mk b/src/bin/pg_resetwal/nls.mk index d04d58ee340..cc40875b482 100644 --- a/src/bin/pg_resetwal/nls.mk +++ b/src/bin/pg_resetwal/nls.mk @@ -1,4 +1,6 @@ # src/bin/pg_resetwal/nls.mk CATALOG_NAME = pg_resetwal -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv zh_CN -GETTEXT_FILES = pg_resetwal.c ../../common/restricted_token.c +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_resetwal.c ../../common/restricted_token.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 8a0a805f1ed..f85ea2db52f 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -20,7 +20,7 @@ * step 2 ... * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pg_resetwal/pg_resetwal.c @@ -45,15 +45,16 @@ #include #include "access/transam.h" -#include "access/tuptoaster.h" +#include "access/heaptoast.h" #include "access/multixact.h" #include "access/xlog.h" #include "access/xlog_internal.h" -#include "catalog/catversion.h" -#include "catalog/pg_control.h" +#include "common/controldata_utils.h" #include "common/fe_memutils.h" #include "common/file_perm.h" +#include "common/logging.h" #include "common/restricted_token.h" +#include "common/string.h" #include "storage/large_object.h" #include "pg_getopt.h" #include "getopt_long.h" @@ -116,8 +117,8 @@ main(int argc, char *argv[]) char *log_fname = NULL; int fd; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal")); - progname = get_progname(argv[0]); if (argc > 1) @@ -157,13 +158,13 @@ main(int argc, char *argv[]) { /*------ translator: the second %s is a command line argument (-e, etc) */ - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-e"); + pg_log_error("invalid argument for option %s", "-e"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (set_xid_epoch == -1) { - fprintf(stderr, _("%s: transaction ID epoch (-e) must not be -1\n"), progname); + pg_log_error("transaction ID epoch (-e) must not be -1"); exit(1); } break; @@ -172,13 +173,13 @@ main(int argc, char *argv[]) set_xid = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != '\0') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-x"); + pg_log_error("invalid argument for option %s", "-x"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (set_xid == 0) { - fprintf(stderr, _("%s: transaction ID (-x) must not be 0\n"), progname); + pg_log_error("transaction ID (-x) must not be 0"); exit(1); } break; @@ -187,14 +188,14 @@ main(int argc, char *argv[]) set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != ',') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c"); + pg_log_error("invalid argument for option %s", "-c"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0); if (endptr2 == endptr + 1 || *endptr2 != '\0') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c"); + pg_log_error("invalid argument for option %s", "-c"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -202,14 +203,14 @@ main(int argc, char *argv[]) if (set_oldest_commit_ts_xid < 2 && set_oldest_commit_ts_xid != 0) { - fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname); + pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2"); exit(1); } if (set_newest_commit_ts_xid < 2 && set_newest_commit_ts_xid != 0) { - fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname); + pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2"); exit(1); } break; @@ -218,13 +219,13 @@ main(int argc, char *argv[]) set_oid = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != '\0') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-o"); + pg_log_error("invalid argument for option %s", "-o"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (set_oid == 0) { - fprintf(stderr, _("%s: OID (-o) must not be 0\n"), progname); + pg_log_error("OID (-o) must not be 0"); exit(1); } break; @@ -233,7 +234,7 @@ main(int argc, char *argv[]) set_mxid = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != ',') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m"); + pg_log_error("invalid argument for option %s", "-m"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -241,13 +242,13 @@ main(int argc, char *argv[]) set_oldestmxid = strtoul(endptr + 1, &endptr2, 0); if (endptr2 == endptr + 1 || *endptr2 != '\0') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m"); + pg_log_error("invalid argument for option %s", "-m"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (set_mxid == 0) { - fprintf(stderr, _("%s: multitransaction ID (-m) must not be 0\n"), progname); + pg_log_error("multitransaction ID (-m) must not be 0"); exit(1); } @@ -257,8 +258,7 @@ main(int argc, char *argv[]) */ if (set_oldestmxid == 0) { - fprintf(stderr, _("%s: oldest multitransaction ID (-m) must not be 0\n"), - progname); + pg_log_error("oldest multitransaction ID (-m) must not be 0"); exit(1); } break; @@ -267,13 +267,13 @@ main(int argc, char *argv[]) set_mxoff = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != '\0') { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-O"); + pg_log_error("invalid argument for option %s", "-O"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (set_mxoff == -1) { - fprintf(stderr, _("%s: multitransaction offset (-O) must not be -1\n"), progname); + pg_log_error("multitransaction offset (-O) must not be -1"); exit(1); } break; @@ -281,7 +281,7 @@ main(int argc, char *argv[]) case 'l': if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN) { - fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-l"); + pg_log_error("invalid argument for option %s", "-l"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -297,16 +297,12 @@ main(int argc, char *argv[]) set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024; if (endptr == optarg || *endptr != '\0') { - fprintf(stderr, - _("%s: argument of --wal-segsize must be a number\n"), - progname); + pg_log_error("argument of --wal-segsize must be a number"); exit(1); } if (!IsValidWalSegSize(set_wal_segsize)) { - fprintf(stderr, - _("%s: argument of --wal-segsize must be a power of 2 between 1 and 1024\n"), - progname); + pg_log_error("argument of --wal-segsize must be a power of 2 between 1 and 1024"); exit(1); } break; @@ -323,8 +319,8 @@ main(int argc, char *argv[]) /* Complain if any arguments remain */ if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -332,7 +328,7 @@ main(int argc, char *argv[]) if (DataDir == NULL) { - fprintf(stderr, _("%s: no data directory specified\n"), progname); + pg_log_error("no data directory specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -346,33 +342,32 @@ main(int argc, char *argv[]) #ifndef WIN32 if (geteuid() == 0) { - fprintf(stderr, _("%s: cannot be executed by \"root\"\n"), - progname); - fprintf(stderr, _("You must run %s as the PostgreSQL superuser.\n"), - progname); + pg_log_error("cannot be executed by \"root\""); + pg_log_info("You must run %s as the PostgreSQL superuser.", + progname); exit(1); } #endif - get_restricted_token(progname); - - if (chdir(DataDir) < 0) - { - fprintf(stderr, _("%s: could not change directory to \"%s\": %s\n"), - progname, DataDir, strerror(errno)); - exit(1); - } + get_restricted_token(); /* Set mask based on PGDATA permissions */ if (!GetDataDirectoryCreatePerm(DataDir)) { - fprintf(stderr, _("%s: unable to read permissions from \"%s\"\n"), - progname, DataDir); + pg_log_error("could not read permissions of directory \"%s\": %m", + DataDir); exit(1); } umask(pg_mode_mask); + if (chdir(DataDir) < 0) + { + pg_log_error("could not change directory to \"%s\": %m", + DataDir); + exit(1); + } + /* Check that data directory matches our server version */ CheckDataVersion(); @@ -384,16 +379,15 @@ main(int argc, char *argv[]) { if (errno != ENOENT) { - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, "postmaster.pid", strerror(errno)); + pg_log_error("could not open file \"%s\" for reading: %m", + "postmaster.pid"); exit(1); } } else { - fprintf(stderr, _("%s: lock file \"%s\" exists\n" - "Is a server running? If not, delete the lock file and try again.\n"), - progname, "postmaster.pid"); + pg_log_error("lock file \"%s\" exists", "postmaster.pid"); + pg_log_info("Is a server running? If not, delete the lock file and try again."); exit(1); } @@ -431,11 +425,15 @@ main(int argc, char *argv[]) * if any, includes these values.) */ if (set_xid_epoch != -1) - ControlFile.checkPointCopy.nextXidEpoch = set_xid_epoch; + ControlFile.checkPointCopy.nextFullXid = + FullTransactionIdFromEpochAndXid(set_xid_epoch, + XidFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid)); if (set_xid != 0) { - ControlFile.checkPointCopy.nextXid = set_xid; + ControlFile.checkPointCopy.nextFullXid = + FullTransactionIdFromEpochAndXid(EpochFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid), + set_xid); /* * For the moment, just set oldestXid to a value that will force @@ -541,12 +539,11 @@ CheckDataVersion(void) const char *ver_file = "PG_VERSION"; FILE *ver_fd; char rawline[64]; - int len; if ((ver_fd = fopen(ver_file, "r")) == NULL) { - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, ver_file, strerror(errno)); + pg_log_error("could not open file \"%s\" for reading: %m", + ver_file); exit(1); } @@ -554,32 +551,20 @@ CheckDataVersion(void) if (!fgets(rawline, sizeof(rawline), ver_fd)) { if (!ferror(ver_fd)) - { - fprintf(stderr, _("%s: unexpected empty file \"%s\"\n"), - progname, ver_file); - } + pg_log_error("unexpected empty file \"%s\"", ver_file); else - { - fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), - progname, ver_file, strerror(errno)); - } + pg_log_error("could not read file \"%s\": %m", ver_file); exit(1); } - /* remove trailing newline, handling Windows newlines as well */ - len = strlen(rawline); - if (len > 0 && rawline[len - 1] == '\n') - { - rawline[--len] = '\0'; - if (len > 0 && rawline[len - 1] == '\r') - rawline[--len] = '\0'; - } + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(rawline); if (strcmp(rawline, PG_MAJORVERSION) != 0) { - fprintf(stderr, _("%s: data directory is of wrong version\n" - "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n"), - progname, ver_file, rawline, PG_MAJORVERSION); + pg_log_error("data directory is of wrong version"); + pg_log_info("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".", + ver_file, rawline, PG_MAJORVERSION); exit(1); } @@ -608,13 +593,13 @@ ReadControlFile(void) * are we've been handed a bad DataDir path, so give up. User can do * "touch pg_control" to force us to proceed. */ - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, XLOG_CONTROL_FILE, strerror(errno)); + pg_log_error("could not open file \"%s\" for reading: %m", + XLOG_CONTROL_FILE); if (errno == ENOENT) - fprintf(stderr, _("If you are sure the data directory path is correct, execute\n" - " touch %s\n" - "and try again.\n"), - XLOG_CONTROL_FILE); + pg_log_info("If you are sure the data directory path is correct, execute\n" + " touch %s\n" + "and try again.", + XLOG_CONTROL_FILE); exit(1); } @@ -624,8 +609,7 @@ ReadControlFile(void) len = read(fd, buffer, PG_CONTROL_FILE_SIZE); if (len < 0) { - fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), - progname, XLOG_CONTROL_FILE, strerror(errno)); + pg_log_error("could not read file \"%s\": %m", XLOG_CONTROL_FILE); exit(1); } close(fd); @@ -643,9 +627,7 @@ ReadControlFile(void) if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc)) { /* We will use the data but treat it as guessed. */ - fprintf(stderr, - _("%s: pg_control exists but has invalid CRC; proceed with caution\n"), - progname); + pg_log_warning("pg_control exists but has invalid CRC; proceed with caution"); guessed = true; } @@ -654,9 +636,10 @@ ReadControlFile(void) /* return false if WAL segment size is not valid */ if (!IsValidWalSegSize(ControlFile.xlog_seg_size)) { - fprintf(stderr, - _("%s: pg_control specifies invalid WAL segment size (%d bytes); proceed with caution \n"), - progname, ControlFile.xlog_seg_size); + pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution", + "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution", + ControlFile.xlog_seg_size), + ControlFile.xlog_seg_size); return false; } @@ -664,8 +647,7 @@ ReadControlFile(void) } /* Looks like it's a mess. */ - fprintf(stderr, _("%s: pg_control exists but is broken or wrong version; ignoring it\n"), - progname); + pg_log_warning("pg_control exists but is broken or wrong version; ignoring it"); return false; } @@ -703,8 +685,8 @@ GuessControlValues(void) ControlFile.checkPointCopy.ThisTimeLineID = 1; ControlFile.checkPointCopy.PrevTimeLineID = 1; ControlFile.checkPointCopy.fullPageWrites = false; - ControlFile.checkPointCopy.nextXidEpoch = 0; - ControlFile.checkPointCopy.nextXid = FirstNormalTransactionId; + ControlFile.checkPointCopy.nextFullXid = + FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId); ControlFile.checkPointCopy.nextOid = FirstBootstrapObjectId; ControlFile.checkPointCopy.nextMulti = FirstMultiXactId; ControlFile.checkPointCopy.nextMultiOffset = 0; @@ -726,6 +708,7 @@ GuessControlValues(void) ControlFile.wal_log_hints = false; ControlFile.track_commit_timestamp = false; ControlFile.MaxConnections = 100; + ControlFile.max_wal_senders = 10; ControlFile.max_worker_processes = 8; ControlFile.max_prepared_xacts = 0; ControlFile.max_locks_per_xact = 64; @@ -759,33 +742,24 @@ GuessControlValues(void) static void PrintControlValues(bool guessed) { - char sysident_str[32]; - if (guessed) printf(_("Guessed pg_control values:\n\n")); else printf(_("Current pg_control values:\n\n")); - /* - * Format system_identifier separately to keep platform-dependent format - * code out of the translatable message string. - */ - snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT, - ControlFile.system_identifier); - printf(_("pg_control version number: %u\n"), ControlFile.pg_control_version); printf(_("Catalog version number: %u\n"), ControlFile.catalog_version_no); - printf(_("Database system identifier: %s\n"), - sysident_str); + printf(_("Database system identifier: %llu\n"), + (unsigned long long) ControlFile.system_identifier); printf(_("Latest checkpoint's TimeLineID: %u\n"), ControlFile.checkPointCopy.ThisTimeLineID); printf(_("Latest checkpoint's full_page_writes: %s\n"), ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off")); printf(_("Latest checkpoint's NextXID: %u:%u\n"), - ControlFile.checkPointCopy.nextXidEpoch, - ControlFile.checkPointCopy.nextXid); + EpochFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid), + XidFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid)); printf(_("Latest checkpoint's NextOID: %u\n"), ControlFile.checkPointCopy.nextOid); printf(_("Latest checkpoint's NextMultiXactId: %u\n"), @@ -877,7 +851,7 @@ PrintNewControlValues(void) if (set_xid != 0) { printf(_("NextXID: %u\n"), - ControlFile.checkPointCopy.nextXid); + XidFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid)); printf(_("OldestXID: %u\n"), ControlFile.checkPointCopy.oldestXid); printf(_("OldestXID's DB: %u\n"), @@ -887,7 +861,7 @@ PrintNewControlValues(void) if (set_xid_epoch != -1) { printf(_("NextXID epoch: %u\n"), - ControlFile.checkPointCopy.nextXidEpoch); + EpochFromFullTransactionId(ControlFile.checkPointCopy.nextFullXid)); } if (set_oldest_commit_ts_xid != 0) @@ -915,24 +889,12 @@ PrintNewControlValues(void) static void RewriteControlFile(void) { - int fd; - char buffer[PG_CONTROL_FILE_SIZE]; /* need not be aligned */ - - /* - * For good luck, apply the same static assertions as in backend's - * WriteControlFile(). - */ - StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE, - "pg_control is too large for atomic disk writes"); - StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE, - "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE"); - /* * Adjust fields as needed to force an empty XLOG starting at * newXlogSegNo. */ - XLogSegNoOffsetToRecPtr(newXlogSegNo, SizeOfXLogLongPHD, - ControlFile.checkPointCopy.redo, WalSegSz); + XLogSegNoOffsetToRecPtr(newXlogSegNo, SizeOfXLogLongPHD, WalSegSz, + ControlFile.checkPointCopy.redo); ControlFile.checkPointCopy.time = (pg_time_t) time(NULL); ControlFile.state = DB_SHUTDOWNED; @@ -953,57 +915,13 @@ RewriteControlFile(void) ControlFile.wal_log_hints = false; ControlFile.track_commit_timestamp = false; ControlFile.MaxConnections = 100; + ControlFile.max_wal_senders = 10; ControlFile.max_worker_processes = 8; ControlFile.max_prepared_xacts = 0; ControlFile.max_locks_per_xact = 64; - /* Contents are protected with a CRC */ - INIT_CRC32C(ControlFile.crc); - COMP_CRC32C(ControlFile.crc, - (char *) &ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(ControlFile.crc); - - /* - * We write out PG_CONTROL_FILE_SIZE bytes into pg_control, zero-padding - * the excess over sizeof(ControlFileData). This reduces the odds of - * premature-EOF errors when reading pg_control. We'll still fail when we - * check the contents of the file, but hopefully with a more specific - * error than "couldn't read pg_control". - */ - memset(buffer, 0, PG_CONTROL_FILE_SIZE); - memcpy(buffer, &ControlFile, sizeof(ControlFileData)); - - unlink(XLOG_CONTROL_FILE); - - fd = open(XLOG_CONTROL_FILE, - O_RDWR | O_CREAT | O_EXCL | PG_BINARY, - pg_file_create_mode); - if (fd < 0) - { - fprintf(stderr, _("%s: could not create pg_control file: %s\n"), - progname, strerror(errno)); - exit(1); - } - - errno = 0; - if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - fprintf(stderr, _("%s: could not write pg_control file: %s\n"), - progname, strerror(errno)); - exit(1); - } - - if (fsync(fd) != 0) - { - fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno)); - exit(1); - } - - close(fd); + /* The control file gets flushed here. */ + update_controlfile(".", &ControlFile, true); } @@ -1012,8 +930,8 @@ RewriteControlFile(void) * * On entry, ControlFile.checkPointCopy.redo and ControlFile.xlog_seg_size * are assumed valid (note that we allow the old xlog seg size to differ - * from what we're using). On exit, newXlogId and newXlogSeg are set to - * suitable values for the beginning of replacement WAL (in our seg size). + * from what we're using). On exit, newXlogSegNo is set to suitable + * value for the beginning of replacement WAL (in our seg size). */ static void FindEndOfXLOG(void) @@ -1039,8 +957,7 @@ FindEndOfXLOG(void) xldir = opendir(XLOGDIR); if (xldir == NULL) { - fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not open directory \"%s\": %m", XLOGDIR); exit(1); } @@ -1075,15 +992,13 @@ FindEndOfXLOG(void) if (errno) { - fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not read directory \"%s\": %m", XLOGDIR); exit(1); } if (closedir(xldir)) { - fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not close directory \"%s\": %m", XLOGDIR); exit(1); } @@ -1110,8 +1025,7 @@ KillExistingXLOG(void) xldir = opendir(XLOGDIR); if (xldir == NULL) { - fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not open directory \"%s\": %m", XLOGDIR); exit(1); } @@ -1123,8 +1037,7 @@ KillExistingXLOG(void) snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name); if (unlink(path) < 0) { - fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not delete file \"%s\": %m", path); exit(1); } } @@ -1132,15 +1045,13 @@ KillExistingXLOG(void) if (errno) { - fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not read directory \"%s\": %m", XLOGDIR); exit(1); } if (closedir(xldir)) { - fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"), - progname, XLOGDIR, strerror(errno)); + pg_log_error("could not close directory \"%s\": %m", XLOGDIR); exit(1); } } @@ -1161,8 +1072,7 @@ KillExistingArchiveStatus(void) xldir = opendir(ARCHSTATDIR); if (xldir == NULL) { - fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), - progname, ARCHSTATDIR, strerror(errno)); + pg_log_error("could not open directory \"%s\": %m", ARCHSTATDIR); exit(1); } @@ -1177,8 +1087,7 @@ KillExistingArchiveStatus(void) snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name); if (unlink(path) < 0) { - fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not delete file \"%s\": %m", path); exit(1); } } @@ -1186,15 +1095,13 @@ KillExistingArchiveStatus(void) if (errno) { - fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), - progname, ARCHSTATDIR, strerror(errno)); + pg_log_error("could not read directory \"%s\": %m", ARCHSTATDIR); exit(1); } if (closedir(xldir)) { - fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"), - progname, ARCHSTATDIR, strerror(errno)); + pg_log_error("could not close directory \"%s\": %m", ARCHSTATDIR); exit(1); } } @@ -1207,7 +1114,7 @@ KillExistingArchiveStatus(void) static void WriteEmptyXLOG(void) { - char *buffer; + PGAlignedXLogBlock buffer; XLogPageHeader page; XLogLongPageHeader longpage; XLogRecord *record; @@ -1217,12 +1124,10 @@ WriteEmptyXLOG(void) int nbytes; char *recptr; - /* Use malloc() to ensure buffer is MAXALIGNED */ - buffer = (char *) pg_malloc(XLOG_BLCKSZ); - page = (XLogPageHeader) buffer; - memset(buffer, 0, XLOG_BLCKSZ); + memset(buffer.data, 0, XLOG_BLCKSZ); /* Set up the XLOG page header */ + page = (XLogPageHeader) buffer.data; page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_info = XLP_LONG_HEADER; page->xlp_tli = ControlFile.checkPointCopy.ThisTimeLineID; @@ -1263,40 +1168,37 @@ WriteEmptyXLOG(void) pg_file_create_mode); if (fd < 0) { - fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not open file \"%s\": %m", path); exit(1); } errno = 0; - if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not write file \"%s\": %m", path); exit(1); } /* Fill the rest of the file with zeroes */ - memset(buffer, 0, XLOG_BLCKSZ); + memset(buffer.data, 0, XLOG_BLCKSZ); for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ) { errno = 0; - if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ) + if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ) { if (errno == 0) errno = ENOSPC; - fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not write file \"%s\": %m", path); exit(1); } } if (fsync(fd) != 0) { - fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno)); + pg_log_error("fsync error: %m"); exit(1); } @@ -1325,5 +1227,5 @@ usage(void) printf(_(" -x, --next-transaction-id=XID set next transaction ID\n")); printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n")); printf(_(" -?, --help show this help, then exit\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/pg_resetwal/po/de.po b/src/bin/pg_resetwal/po/de.po index 68b1e9846b5..d7cbfde7d75 100644 --- a/src/bin/pg_resetwal/po/de.po +++ b/src/bin/pg_resetwal/po/de.po @@ -1,146 +1,178 @@ # German message translation file for pg_resetwal -# Peter Eisentraut , 2002 - 2017. +# Peter Eisentraut , 2002 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-01 19:15+0000\n" -"PO-Revision-Date: 2017-08-01 17:03-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-04 09:16+0000\n" +"PO-Revision-Date: 2019-05-04 19:59+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/restricted_token.c:68 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: WARNUNG: auf dieser Plattform können keine beschränkten Token erzeugt werden\n" +msgid "fatal: " +msgstr "Fatal: " -#: ../../common/restricted_token.c:77 +#: ../../../src/fe_utils/logging.c:189 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" +msgid "error: " +msgstr "Fehler: " -#: ../../common/restricted_token.c:90 +#: ../../../src/fe_utils/logging.c:196 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: konnte SIDs nicht erzeugen: Fehlercode %lu\n" +msgid "warning: " +msgstr "Warnung: " + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: konnte beschränktes Token nicht erzeugen: Fehlercode %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" #. translator: the second %s is a command line argument (-e, etc) -#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 -#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 -#: pg_resetwal.c:264 +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 #, c-format -msgid "%s: invalid argument for option %s\n" -msgstr "%s: ungültiges Argument für Option %s\n" +msgid "invalid argument for option %s" +msgstr "ungültiges Argument für Option %s" -#: pg_resetwal.c:141 pg_resetwal.c:156 pg_resetwal.c:171 pg_resetwal.c:178 -#: pg_resetwal.c:202 pg_resetwal.c:217 pg_resetwal.c:225 pg_resetwal.c:251 -#: pg_resetwal.c:265 pg_resetwal.c:272 pg_resetwal.c:285 pg_resetwal.c:293 +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_resetwal.c:146 +#: pg_resetwal.c:166 #, c-format -msgid "%s: transaction ID epoch (-e) must not be -1\n" -msgstr "%s: Transaktions-ID-Epoche (-e) darf nicht -1 sein\n" +msgid "transaction ID epoch (-e) must not be -1" +msgstr "Transaktions-ID-Epoche (-e) darf nicht -1 sein" -#: pg_resetwal.c:161 +#: pg_resetwal.c:181 #, c-format -msgid "%s: transaction ID (-x) must not be 0\n" -msgstr "%s: Transaktions-ID (-x) darf nicht 0 sein\n" +msgid "transaction ID (-x) must not be 0" +msgstr "Transaktions-ID (-x) darf nicht 0 sein" -#: pg_resetwal.c:185 pg_resetwal.c:192 +#: pg_resetwal.c:205 pg_resetwal.c:212 #, c-format -msgid "%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n" -msgstr "%s: Transaktions-ID (-c) muss entweder 0 oder größer oder gleich 2 sein\n" +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "Transaktions-ID (-c) muss entweder 0 oder größer oder gleich 2 sein" -#: pg_resetwal.c:207 +#: pg_resetwal.c:227 #, c-format -msgid "%s: OID (-o) must not be 0\n" -msgstr "%s: OID (-o) darf nicht 0 sein\n" +msgid "OID (-o) must not be 0" +msgstr "OID (-o) darf nicht 0 sein" -#: pg_resetwal.c:230 +#: pg_resetwal.c:250 #, c-format -msgid "%s: multitransaction ID (-m) must not be 0\n" -msgstr "%s: Multitransaktions-ID (-m) darf nicht 0 sein\n" +msgid "multitransaction ID (-m) must not be 0" +msgstr "Multitransaktions-ID (-m) darf nicht 0 sein" -#: pg_resetwal.c:240 +#: pg_resetwal.c:260 #, c-format -msgid "%s: oldest multitransaction ID (-m) must not be 0\n" -msgstr "%s: älteste Multitransaktions-ID (-m) darf nicht 0 sein\n" +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "älteste Multitransaktions-ID (-m) darf nicht 0 sein" -#: pg_resetwal.c:256 +#: pg_resetwal.c:275 #, c-format -msgid "%s: multitransaction offset (-O) must not be -1\n" -msgstr "%s: Multitransaktions-Offset (-O) darf nicht -1 sein\n" +msgid "multitransaction offset (-O) must not be -1" +msgstr "Multitransaktions-Offset (-O) darf nicht -1 sein" -#: pg_resetwal.c:283 +#: pg_resetwal.c:299 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "argument of --wal-segsize must be a number" +msgstr "Argument von --wal-segsize muss eine Zahl sein" -#: pg_resetwal.c:292 +#: pg_resetwal.c:304 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: kein Datenverzeichnis angegeben\n" +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "Argument von --wal-segsize muss eine Zweierpotenz zwischen 1 und 1024 sein" -#: pg_resetwal.c:306 +#: pg_resetwal.c:321 #, c-format -msgid "%s: cannot be executed by \"root\"\n" -msgstr "%s: kann nicht von »root« ausgeführt werden\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: pg_resetwal.c:308 +#: pg_resetwal.c:330 #, c-format -msgid "You must run %s as the PostgreSQL superuser.\n" -msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen.\n" +msgid "no data directory specified" +msgstr "kein Datenverzeichnis angegeben" -#: pg_resetwal.c:318 +#: pg_resetwal.c:344 #, c-format -msgid "%s: could not change directory to \"%s\": %s\n" -msgstr "%s: konnte nicht in Verzeichnis »%s« wechseln: %s\n" +msgid "cannot be executed by \"root\"" +msgstr "kann nicht von »root« ausgeführt werden" -#: pg_resetwal.c:334 pg_resetwal.c:481 pg_resetwal.c:544 +#: pg_resetwal.c:345 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: konnte Datei »%s« nicht zum Lesen öffnen: %s\n" +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen." -#: pg_resetwal.c:341 +#: pg_resetwal.c:356 #, c-format -msgid "" -"%s: lock file \"%s\" exists\n" -"Is a server running? If not, delete the lock file and try again.\n" -msgstr "" -"%s: Sperrdatei »%s« existiert bereits\n" -"Läuft der Server? Wenn nicht, dann Sperrdatei löschen und nochmal versuchen.\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "konnte nicht in Verzeichnis »%s« wechseln: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:545 pg_resetwal.c:602 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "Sperrdatei »%s« existiert" -#: pg_resetwal.c:428 +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "Läuft der Server? Wenn nicht, dann Sperrdatei löschen und nochmal versuchen." + +#: pg_resetwal.c:492 #, c-format msgid "" "\n" @@ -150,7 +182,7 @@ msgstr "" "Wenn diese Werte akzeptabel scheinen, dann benutzen Sie -f um das\n" "Zurücksetzen zu erzwingen.\n" -#: pg_resetwal.c:440 +#: pg_resetwal.c:504 #, c-format msgid "" "The database server was not shut down cleanly.\n" @@ -162,52 +194,60 @@ msgstr "" "Wenn Sie trotzdem weiter machen wollen, benutzen Sie -f, um das\n" "Zurücksetzen zu erzwingen.\n" -#: pg_resetwal.c:454 +#: pg_resetwal.c:518 #, c-format msgid "Write-ahead log reset\n" msgstr "Write-Ahead-Log wurde zurückgesetzt\n" -#: pg_resetwal.c:491 +#: pg_resetwal.c:554 #, c-format -msgid "%s: unexpected empty file \"%s\"\n" -msgstr "%s: unerwartete leere Datei »%s«\n" +msgid "unexpected empty file \"%s\"" +msgstr "unerwartete leere Datei »%s«" -#: pg_resetwal.c:496 pg_resetwal.c:560 +#: pg_resetwal.c:556 pg_resetwal.c:618 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht lesen: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" -#: pg_resetwal.c:513 +#: pg_resetwal.c:571 #, c-format -msgid "" -"%s: data directory is of wrong version\n" -"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n" -msgstr "" -"%s: Datenverzeichnis hat falsche Version\n" -"Datei »%s« enthält »%s«, was nicht mit der Version dieses Programms »%s« kompatibel ist.\n" +msgid "data directory is of wrong version" +msgstr "Datenverzeichnis hat falsche Version" -#: pg_resetwal.c:547 +#: pg_resetwal.c:572 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "Datei »%s« enthält »%s«, was nicht mit der Version dieses Programms »%s« kompatibel ist." + +#: pg_resetwal.c:605 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" " touch %s\n" -"and try again.\n" +"and try again." msgstr "" "Wenn Sie sicher sind, dass das Datenverzeichnis korrekt ist, führen Sie\n" " touch %s\n" -"aus und versuchen Sie es erneut.\n" +"aus und versuchen Sie es erneut." -#: pg_resetwal.c:583 +#: pg_resetwal.c:636 #, c-format -msgid "%s: pg_control exists but has invalid CRC; proceed with caution\n" -msgstr "%s: pg_control existiert, aber mit ungültiger CRC; mit Vorsicht fortfahren\n" +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control existiert, aber mit ungültiger CRC; mit Vorsicht fortfahren" -#: pg_resetwal.c:592 +#: pg_resetwal.c:645 #, c-format -msgid "%s: pg_control exists but is broken or wrong version; ignoring it\n" -msgstr "%s: pg_control existiert, aber ist kaputt oder hat falsche Version; wird ignoriert\n" +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control gibt ungültige WAL-Segmentgröße an (%d Byte); mit Vorsicht fortfahren" +msgstr[1] "pg_control gibt ungültige WAL-Segmentgröße an (%d Bytes); mit Vorsicht fortfahren" -#: pg_resetwal.c:690 +#: pg_resetwal.c:656 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control existiert, aber ist kaputt oder hat falsche Version; wird ignoriert" + +#: pg_resetwal.c:754 #, c-format msgid "" "Guessed pg_control values:\n" @@ -216,7 +256,7 @@ msgstr "" "Geschätzte pg_control-Werte:\n" "\n" -#: pg_resetwal.c:692 +#: pg_resetwal.c:756 #, c-format msgid "" "Current pg_control values:\n" @@ -225,172 +265,172 @@ msgstr "" "Aktuelle pg_control-Werte:\n" "\n" -#: pg_resetwal.c:701 +#: pg_resetwal.c:765 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control-Versionsnummer: %u\n" -#: pg_resetwal.c:703 +#: pg_resetwal.c:767 #, c-format msgid "Catalog version number: %u\n" msgstr "Katalogversionsnummer: %u\n" -#: pg_resetwal.c:705 +#: pg_resetwal.c:769 #, c-format msgid "Database system identifier: %s\n" msgstr "Datenbanksystemidentifikation: %s\n" -#: pg_resetwal.c:707 +#: pg_resetwal.c:771 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:709 +#: pg_resetwal.c:773 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes des letzten Checkpoints: %s\n" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "off" msgstr "aus" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "on" msgstr "an" -#: pg_resetwal.c:711 +#: pg_resetwal.c:775 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID des letzten Checkpoints: %u:%u\n" -#: pg_resetwal.c:714 +#: pg_resetwal.c:778 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:716 +#: pg_resetwal.c:780 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId des letzten Checkpoints: %u\n" -#: pg_resetwal.c:718 +#: pg_resetwal.c:782 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset des letzten Checkpoints: %u\n" -#: pg_resetwal.c:720 +#: pg_resetwal.c:784 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:722 +#: pg_resetwal.c:786 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB der oldestXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:724 +#: pg_resetwal.c:788 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID des letzten Checkpoints: %u\n" -#: pg_resetwal.c:726 +#: pg_resetwal.c:790 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:728 +#: pg_resetwal.c:792 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB des oldestMulti des letzten Checkpoints: %u\n" -#: pg_resetwal.c:730 +#: pg_resetwal.c:794 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:732 +#: pg_resetwal.c:796 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid des letzten Checkpoints: %u\n" -#: pg_resetwal.c:734 +#: pg_resetwal.c:798 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximale Datenausrichtung (Alignment): %u\n" -#: pg_resetwal.c:737 +#: pg_resetwal.c:801 #, c-format msgid "Database block size: %u\n" msgstr "Datenbankblockgröße: %u\n" -#: pg_resetwal.c:739 +#: pg_resetwal.c:803 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Blöcke pro Segment: %u\n" -#: pg_resetwal.c:741 +#: pg_resetwal.c:805 #, c-format msgid "WAL block size: %u\n" msgstr "WAL-Blockgröße: %u\n" -#: pg_resetwal.c:743 +#: pg_resetwal.c:807 pg_resetwal.c:895 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes pro WAL-Segment: %u\n" -#: pg_resetwal.c:745 +#: pg_resetwal.c:809 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximale Bezeichnerlänge: %u\n" -#: pg_resetwal.c:747 +#: pg_resetwal.c:811 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximale Spalten in einem Index: %u\n" -#: pg_resetwal.c:749 +#: pg_resetwal.c:813 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximale Größe eines Stücks TOAST: %u\n" -#: pg_resetwal.c:751 +#: pg_resetwal.c:815 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Größe eines Large-Object-Chunks: %u\n" -#: pg_resetwal.c:754 +#: pg_resetwal.c:818 #, c-format msgid "Date/time type storage: %s\n" msgstr "Speicherung von Datum/Zeit-Typen: %s\n" -#: pg_resetwal.c:755 +#: pg_resetwal.c:819 msgid "64-bit integers" msgstr "64-Bit-Ganzzahlen" -#: pg_resetwal.c:756 +#: pg_resetwal.c:820 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Übergabe von Float4-Argumenten: %s\n" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by reference" msgstr "Referenz" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by value" msgstr "Wert" -#: pg_resetwal.c:758 +#: pg_resetwal.c:822 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Übergabe von Float8-Argumenten: %s\n" -#: pg_resetwal.c:760 +#: pg_resetwal.c:824 #, c-format msgid "Data page checksum version: %u\n" msgstr "Datenseitenprüfsummenversion: %u\n" -#: pg_resetwal.c:774 +#: pg_resetwal.c:838 #, c-format msgid "" "\n" @@ -403,119 +443,111 @@ msgstr "" "Zu ändernde Werte:\n" "\n" -#: pg_resetwal.c:777 +#: pg_resetwal.c:842 #, c-format msgid "First log segment after reset: %s\n" msgstr "Erstes Logdateisegment nach Zurücksetzen: %s\n" -#: pg_resetwal.c:781 +#: pg_resetwal.c:846 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetwal.c:783 +#: pg_resetwal.c:848 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetwal.c:785 +#: pg_resetwal.c:850 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "OldestMulti's DB: %u\n" -#: pg_resetwal.c:791 +#: pg_resetwal.c:856 #, c-format msgid "NextMultiOffset: %u\n" msgstr "NextMultiOffset: %u\n" -#: pg_resetwal.c:797 +#: pg_resetwal.c:862 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetwal.c:803 +#: pg_resetwal.c:868 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetwal.c:805 +#: pg_resetwal.c:870 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetwal.c:807 +#: pg_resetwal.c:872 #, c-format msgid "OldestXID's DB: %u\n" msgstr "OldestXID's DB: %u\n" -#: pg_resetwal.c:813 +#: pg_resetwal.c:878 #, c-format msgid "NextXID epoch: %u\n" msgstr "NextXID-Epoche: %u\n" -#: pg_resetwal.c:819 +#: pg_resetwal.c:884 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "oldestCommitTsXid: %u\n" -#: pg_resetwal.c:824 +#: pg_resetwal.c:889 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "newestCommitTsXid: %u\n" -#: pg_resetwal.c:906 -#, c-format -msgid "%s: could not create pg_control file: %s\n" -msgstr "%s: konnte pg_control-Datei nicht erstellen: %s\n" - -#: pg_resetwal.c:917 +#: pg_resetwal.c:975 pg_resetwal.c:1043 pg_resetwal.c:1090 #, c-format -msgid "%s: could not write pg_control file: %s\n" -msgstr "%sL konnte pg_control-Datei nicht schreiben: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" -#: pg_resetwal.c:924 pg_resetwal.c:1220 +#: pg_resetwal.c:1010 pg_resetwal.c:1063 pg_resetwal.c:1113 #, c-format -msgid "%s: fsync error: %s\n" -msgstr "%s: fsync-Fehler: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: pg_resetwal.c:964 pg_resetwal.c:1035 pg_resetwal.c:1086 +#: pg_resetwal.c:1016 pg_resetwal.c:1069 pg_resetwal.c:1119 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht öffnen: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: pg_resetwal.c:1000 pg_resetwal.c:1057 pg_resetwal.c:1111 +#: pg_resetwal.c:1055 pg_resetwal.c:1105 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "could not delete file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" -#: pg_resetwal.c:1007 pg_resetwal.c:1064 pg_resetwal.c:1118 +#: pg_resetwal.c:1186 #, c-format -msgid "%s: could not close directory \"%s\": %s\n" -msgstr "%s: konnte Verzeichnis »%s« nicht schließen: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" -#: pg_resetwal.c:1048 pg_resetwal.c:1102 +#: pg_resetwal.c:1196 pg_resetwal.c:1209 #, c-format -msgid "%s: could not delete file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht löschen: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" -#: pg_resetwal.c:1187 +#: pg_resetwal.c:1216 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht öffnen: %s\n" +msgid "fsync error: %m" +msgstr "fsync-Fehler: %m" -#: pg_resetwal.c:1198 pg_resetwal.c:1212 -#, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: konnte Datei »%s« nicht schreiben: %s\n" - -#: pg_resetwal.c:1231 +#: pg_resetwal.c:1227 #, c-format msgid "" "%s resets the PostgreSQL write-ahead log.\n" "\n" -msgstr "%s setzt den PostgreSQL-Write-Ahead-Log zurück.\n\n" +msgstr "" +"%s setzt den PostgreSQL-Write-Ahead-Log zurück.\n" +"\n" -#: pg_resetwal.c:1232 +#: pg_resetwal.c:1228 #, c-format msgid "" "Usage:\n" @@ -526,83 +558,89 @@ msgstr "" " %s [OPTION]... DATENVERZEICHNIS\n" "\n" -#: pg_resetwal.c:1233 +#: pg_resetwal.c:1229 #, c-format msgid "Options:\n" msgstr "Optionen:\n" +#: pg_resetwal.c:1230 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" älteste und neuste Transaktion mit Commit-\n" +" Timestamp setzen (Null bedeutet keine Änderung)\n" + +#: pg_resetwal.c:1233 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]VERZ Datenbankverzeichnis\n" + #: pg_resetwal.c:1234 #, c-format -msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" -msgstr " -c XID,XID älteste und neuste Transaktion mit Commit-Timestamp setzen\n" +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCHE nächste Transaktions-ID-Epoche setzen\n" #: pg_resetwal.c:1235 #, c-format -msgid " (zero in either value means no change)\n" -msgstr " (Null in einem Wert bedeutet keine Änderung)\n" +msgid " -f, --force force update to be done\n" +msgstr " -f, --force Änderung erzwingen\n" #: pg_resetwal.c:1236 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATENVERZ Datenbankverzeichnis\n" +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALDATEI minimale Startposition für neuen WAL setzen\n" #: pg_resetwal.c:1237 #, c-format -msgid " -e XIDEPOCH set next transaction ID epoch\n" -msgstr " -e XIDEPOCHE nächste Transaktions-ID-Epoche setzen\n" +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID nächste und älteste Multitransaktions-ID setzen\n" #: pg_resetwal.c:1238 #, c-format -msgid " -f force update to be done\n" -msgstr " -f Änderung erzwingen\n" +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr "" +" -n, --dry-run keine Änderungen; nur zeigen, was gemacht\n" +" werden würde\n" #: pg_resetwal.c:1239 #, c-format -msgid " -l WALFILE force minimum WAL starting location for new write-ahead log\n" -msgstr " -l WALDATEI minimale WAL-Startposition für neuen Write-Ahead-Log erzwingen\n" +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID nächste OID setzen\n" #: pg_resetwal.c:1240 #, c-format -msgid " -m MXID,MXID set next and oldest multitransaction ID\n" -msgstr " -m MXID,MXID nächste und älteste Multitransaktions-ID setzen\n" +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET nächsten Multitransaktions-Offset setzen\n" #: pg_resetwal.c:1241 #, c-format -msgid " -n no update, just show what would be done (for testing)\n" -msgstr "" -" -n keine Änderungen; nur zeigen, was gemacht werden würde (zum\n" -" Testen)\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" #: pg_resetwal.c:1242 #, c-format -msgid " -o OID set next OID\n" -msgstr " -o OID nächste OID setzen\n" +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID nächste Transaktions-ID setzen\n" #: pg_resetwal.c:1243 #, c-format -msgid " -O OFFSET set next multitransaction offset\n" -msgstr " -O OFFSET nächsten Multitransaktions-Offset setzen\n" +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=ZAHL Größe eines WAL-Segments, in Megabytes\n" #: pg_resetwal.c:1244 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" #: pg_resetwal.c:1245 #, c-format -msgid " -x XID set next transaction ID\n" -msgstr " -x XID nächste Transaktions-ID setzen\n" - -#: pg_resetwal.c:1246 -#, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" - -#: pg_resetwal.c:1247 -#, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Berichten Sie Fehler an .\n" +"Berichten Sie Fehler an .\n" diff --git a/src/bin/pg_resetwal/po/es.po b/src/bin/pg_resetwal/po/es.po index 8b0ea7385e7..36acfc87842 100644 --- a/src/bin/pg_resetwal/po/es.po +++ b/src/bin/pg_resetwal/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for pg_resetwal # -# Copyright (C) 2003-2012 PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Ivan Hernandez , 2003. @@ -10,143 +10,175 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_resetwal (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-10 12:13-0400\n" +"Project-Id-Version: pg_resetwal (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:14+0000\n" +"PO-Revision-Date: 2019-06-06 17:24-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: Español \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../common/restricted_token.c:68 +#: ../../../src/common/logging.c:188 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" +msgid "fatal: " +msgstr "fatal: " -#: ../../common/restricted_token.c:77 +#: ../../../src/common/logging.c:195 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" +msgid "error: " +msgstr "error: " -#: ../../common/restricted_token.c:90 +#: ../../../src/common/logging.c:202 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" +msgid "warning: " +msgstr "precaución: " + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "no se pueden crear tokens restrigidos en esta plataforma" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: no se pudo iniciar el proceso para la orden «%s»: código de error %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: no se pudo re-ejecutar con el token restringido: código de error %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: no se pudo obtener el código de salida del subproceso»: código de error %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" #. translator: the second %s is a command line argument (-e, etc) -#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 -#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 -#: pg_resetwal.c:264 +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 #, c-format -msgid "%s: invalid argument for option %s\n" -msgstr "%s: argumento no válido para la opción %s\n" +msgid "invalid argument for option %s" +msgstr "argumento no válido para la opción %s" -#: pg_resetwal.c:141 pg_resetwal.c:156 pg_resetwal.c:171 pg_resetwal.c:178 -#: pg_resetwal.c:202 pg_resetwal.c:217 pg_resetwal.c:225 pg_resetwal.c:251 -#: pg_resetwal.c:265 pg_resetwal.c:272 pg_resetwal.c:285 pg_resetwal.c:293 +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prueba con «%s --help» para más información\n" -#: pg_resetwal.c:146 +#: pg_resetwal.c:166 #, c-format -msgid "%s: transaction ID epoch (-e) must not be -1\n" -msgstr "%s: el «epoch» de ID de transacción (-e) no debe ser -1\n" +msgid "transaction ID epoch (-e) must not be -1" +msgstr "el «epoch» de ID de transacción (-e) no debe ser -1" -#: pg_resetwal.c:161 +#: pg_resetwal.c:181 #, c-format -msgid "%s: transaction ID (-x) must not be 0\n" -msgstr "%s: el ID de transacción (-x) no debe ser 0\n" +msgid "transaction ID (-x) must not be 0" +msgstr "el ID de transacción (-x) no debe ser 0" -#: pg_resetwal.c:185 pg_resetwal.c:192 +#: pg_resetwal.c:205 pg_resetwal.c:212 #, c-format -msgid "%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n" -msgstr "%s: el ID de transacción (-c) debe ser 0 o bien mayor o igual a 2\n" +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "el ID de transacción (-c) debe ser 0 o bien mayor o igual a 2" -#: pg_resetwal.c:207 +#: pg_resetwal.c:227 #, c-format -msgid "%s: OID (-o) must not be 0\n" -msgstr "%s: OID (-o) no debe ser cero\n" +msgid "OID (-o) must not be 0" +msgstr "OID (-o) no debe ser cero" -#: pg_resetwal.c:230 +#: pg_resetwal.c:250 #, c-format -msgid "%s: multitransaction ID (-m) must not be 0\n" -msgstr "%s: el ID de multitransacción (-m) no debe ser 0\n" +msgid "multitransaction ID (-m) must not be 0" +msgstr "el ID de multitransacción (-m) no debe ser 0" -#: pg_resetwal.c:240 +#: pg_resetwal.c:260 #, c-format -msgid "%s: oldest multitransaction ID (-m) must not be 0\n" -msgstr "%s: el ID de multitransacción más antiguo (-m) no debe ser 0\n" +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "el ID de multitransacción más antiguo (-m) no debe ser 0" -#: pg_resetwal.c:256 +#: pg_resetwal.c:275 #, c-format -msgid "%s: multitransaction offset (-O) must not be -1\n" -msgstr "%s: la posición de multitransacción (-O) no debe ser -1\n" +msgid "multitransaction offset (-O) must not be -1" +msgstr "la posición de multitransacción (-O) no debe ser -1" -#: pg_resetwal.c:283 +#: pg_resetwal.c:299 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "argument of --wal-segsize must be a number" +msgstr "el argumento de --wal-segsize debe ser un número" -#: pg_resetwal.c:292 +#: pg_resetwal.c:304 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: directorio de datos no especificado\n" +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "el argumento de --wal-segsize debe ser una potencia de 2 entre 1 y 1024" -#: pg_resetwal.c:306 +#: pg_resetwal.c:321 #, c-format -msgid "%s: cannot be executed by \"root\"\n" -msgstr "%s: no puede ser ejecutado con el usuario «root»\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_resetwal.c:308 +#: pg_resetwal.c:330 #, c-format -msgid "You must run %s as the PostgreSQL superuser.\n" -msgstr "Debe ejecutar %s con el superusuario de PostgreSQL.\n" +msgid "no data directory specified" +msgstr "directorio de datos no especificado" -#: pg_resetwal.c:318 +#: pg_resetwal.c:344 #, c-format -msgid "%s: could not change directory to \"%s\": %s\n" -msgstr "%s: no se pudo cambiar al directorio «%s»: %s\n" +msgid "cannot be executed by \"root\"" +msgstr "no puede ser ejecutado con el usuario «root»" -#: pg_resetwal.c:334 pg_resetwal.c:481 pg_resetwal.c:544 +#: pg_resetwal.c:345 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: no se pudo abrir el archivo «%s» para lectura: %s\n" +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Debe ejecutar %s con el superusuario de PostgreSQL." -#: pg_resetwal.c:341 +#: pg_resetwal.c:356 #, c-format -msgid "" -"%s: lock file \"%s\" exists\n" -"Is a server running? If not, delete the lock file and try again.\n" -msgstr "" -"%s: el archivo candado «%s» existe\n" -"¿Hay un servidor corriendo? Si no, borre el archivo candado e inténtelo de nuevo\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:545 pg_resetwal.c:602 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "el archivo candado «%s» existe" -#: pg_resetwal.c:428 +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "¿Hay un servidor corriendo? Si no, borre el archivo candado e inténtelo de nuevo." + +#: pg_resetwal.c:492 #, c-format msgid "" "\n" @@ -155,7 +187,7 @@ msgstr "" "\n" "Si estos valores parecen aceptables, use -f para forzar reinicio.\n" -#: pg_resetwal.c:440 +#: pg_resetwal.c:504 #, c-format msgid "" "The database server was not shut down cleanly.\n" @@ -166,52 +198,60 @@ msgstr "" "Restablecer el WAL puede causar pérdida de datos.\n" "Si quiere continuar de todas formas, use -f para forzar el restablecimiento.\n" -#: pg_resetwal.c:454 +#: pg_resetwal.c:518 #, c-format msgid "Write-ahead log reset\n" msgstr "«Write-ahead log» restablecido\n" -#: pg_resetwal.c:491 +#: pg_resetwal.c:554 #, c-format -msgid "%s: unexpected empty file \"%s\"\n" -msgstr "%s: archivo vacío inesperado «%s»\n" +msgid "unexpected empty file \"%s\"" +msgstr "archivo vacío inesperado «%s»" -#: pg_resetwal.c:496 pg_resetwal.c:560 +#: pg_resetwal.c:556 pg_resetwal.c:618 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: no se pudo leer el archivo «%s»: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" -#: pg_resetwal.c:513 +#: pg_resetwal.c:571 #, c-format -msgid "" -"%s: data directory is of wrong version\n" -"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n" -msgstr "" -"%s: el directorio de datos tiene la versión equivocada\n" -"El archivo «%s» contiene «%s», que no es compatible con la versión «%s» de este programa.\n" +msgid "data directory is of wrong version" +msgstr "el directorio de datos tiene la versión equivocada" -#: pg_resetwal.c:547 +#: pg_resetwal.c:572 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "El archivo «%s» contiene «%s», que no es compatible con la versión «%s» de este programa." + +#: pg_resetwal.c:605 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" " touch %s\n" -"and try again.\n" +"and try again." msgstr "" "Si está seguro que la ruta al directorio de datos es correcta, ejecute\n" " touch %s\n" -"y pruebe de nuevo.\n" +"y pruebe de nuevo." -#: pg_resetwal.c:583 +#: pg_resetwal.c:636 #, c-format -msgid "%s: pg_control exists but has invalid CRC; proceed with caution\n" -msgstr "%s: existe pg_control pero tiene un CRC no válido, proceda con precaución\n" +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "existe pg_control pero tiene un CRC no válido, proceda con precaución" -#: pg_resetwal.c:592 +#: pg_resetwal.c:645 #, c-format -msgid "%s: pg_control exists but is broken or wrong version; ignoring it\n" -msgstr "%s: existe pg_control pero está roto o tiene la versión equivocada; ignorándolo\n" +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control especifica un tamaño de segmento de WAL no válido (%d byte), proceda con precaución" +msgstr[1] "pg_control especifica un tamaño de segmento de WAL no válido (%d bytes), proceda con precaución" -#: pg_resetwal.c:690 +#: pg_resetwal.c:656 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "existe pg_control pero está roto o tiene la versión equivocada; ignorándolo" + +#: pg_resetwal.c:754 #, c-format msgid "" "Guessed pg_control values:\n" @@ -220,7 +260,7 @@ msgstr "" "Valores de pg_control asumidos:\n" "\n" -#: pg_resetwal.c:692 +#: pg_resetwal.c:756 #, c-format msgid "" "Current pg_control values:\n" @@ -229,172 +269,172 @@ msgstr "" "Valores actuales de pg_control:\n" "\n" -#: pg_resetwal.c:701 +#: pg_resetwal.c:765 #, c-format msgid "pg_control version number: %u\n" msgstr "Número de versión de pg_control: %u\n" -#: pg_resetwal.c:703 +#: pg_resetwal.c:767 #, c-format msgid "Catalog version number: %u\n" msgstr "Número de versión de catálogo: %u\n" -#: pg_resetwal.c:705 +#: pg_resetwal.c:769 #, c-format msgid "Database system identifier: %s\n" msgstr "Identificador de sistema: %s\n" -#: pg_resetwal.c:707 +#: pg_resetwal.c:771 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID del checkpoint más reciente: %u\n" -#: pg_resetwal.c:709 +#: pg_resetwal.c:773 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "full_page_writes del checkpoint más reciente: %s\n" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "off" msgstr "desactivado" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "on" msgstr "activado" -#: pg_resetwal.c:711 +#: pg_resetwal.c:775 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID del checkpoint más reciente: %u:%u\n" -#: pg_resetwal.c:714 +#: pg_resetwal.c:778 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID del checkpoint más reciente: %u\n" -#: pg_resetwal.c:716 +#: pg_resetwal.c:780 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId del checkpoint más reciente: %u\n" -#: pg_resetwal.c:718 +#: pg_resetwal.c:782 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset del checkpoint más reciente: %u\n" -#: pg_resetwal.c:720 +#: pg_resetwal.c:784 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID del checkpoint más reciente: %u\n" -#: pg_resetwal.c:722 +#: pg_resetwal.c:786 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "BD del oldestXID del checkpoint más reciente: %u\n" -#: pg_resetwal.c:724 +#: pg_resetwal.c:788 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID del checkpoint más reciente: %u\n" -#: pg_resetwal.c:726 +#: pg_resetwal.c:790 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid del checkpoint más reciente: %u\n" -#: pg_resetwal.c:728 +#: pg_resetwal.c:792 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "BD del oldestMultiXid del checkpt. más reciente: %u\n" -#: pg_resetwal.c:730 +#: pg_resetwal.c:794 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid del último checkpoint: %u\n" -#: pg_resetwal.c:732 +#: pg_resetwal.c:796 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid del último checkpoint: %u\n" -#: pg_resetwal.c:734 +#: pg_resetwal.c:798 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Máximo alineamiento de datos: %u\n" -#: pg_resetwal.c:737 +#: pg_resetwal.c:801 #, c-format msgid "Database block size: %u\n" msgstr "Tamaño del bloque de la base de datos: %u\n" -#: pg_resetwal.c:739 +#: pg_resetwal.c:803 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Bloques por segmento de relación grande: %u\n" -#: pg_resetwal.c:741 +#: pg_resetwal.c:805 #, c-format msgid "WAL block size: %u\n" msgstr "Tamaño del bloque de WAL: %u\n" -#: pg_resetwal.c:743 +#: pg_resetwal.c:807 pg_resetwal.c:895 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Bytes por segmento WAL: %u\n" -#: pg_resetwal.c:745 +#: pg_resetwal.c:809 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Longitud máxima de identificadores: %u\n" -#: pg_resetwal.c:747 +#: pg_resetwal.c:811 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Máximo número de columnas en un índice: %u\n" -#: pg_resetwal.c:749 +#: pg_resetwal.c:813 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Longitud máxima de un trozo TOAST: %u\n" -#: pg_resetwal.c:751 +#: pg_resetwal.c:815 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Longitud máxima de un trozo de objeto grande: %u\n" -#: pg_resetwal.c:754 +#: pg_resetwal.c:818 #, c-format msgid "Date/time type storage: %s\n" msgstr "Tipo de almacenamiento hora/fecha: %s\n" -#: pg_resetwal.c:755 +#: pg_resetwal.c:819 msgid "64-bit integers" msgstr "enteros de 64 bits" -#: pg_resetwal.c:756 +#: pg_resetwal.c:820 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Paso de parámetros float4: %s\n" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by reference" msgstr "por referencia" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by value" msgstr "por valor" -#: pg_resetwal.c:758 +#: pg_resetwal.c:822 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Paso de parámetros float8: %s\n" -#: pg_resetwal.c:760 +#: pg_resetwal.c:824 #, c-format msgid "Data page checksum version: %u\n" msgstr "Versión de suma de verificación de datos: %u\n" -#: pg_resetwal.c:774 +#: pg_resetwal.c:838 #, c-format msgid "" "\n" @@ -407,117 +447,102 @@ msgstr "" "Valores a cambiar:\n" "\n" -#: pg_resetwal.c:777 +#: pg_resetwal.c:842 #, c-format msgid "First log segment after reset: %s\n" msgstr "Primer segmento de log después de reiniciar: %s\n" -#: pg_resetwal.c:781 +#: pg_resetwal.c:846 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetwal.c:783 +#: pg_resetwal.c:848 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetwal.c:785 +#: pg_resetwal.c:850 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "Base de datos del OldestMulti: %u\n" -#: pg_resetwal.c:791 +#: pg_resetwal.c:856 #, c-format msgid "NextMultiOffset: %u\n" msgstr "NextMultiOffset: %u\n" -#: pg_resetwal.c:797 +#: pg_resetwal.c:862 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetwal.c:803 +#: pg_resetwal.c:868 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetwal.c:805 +#: pg_resetwal.c:870 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetwal.c:807 +#: pg_resetwal.c:872 #, c-format msgid "OldestXID's DB: %u\n" msgstr "Base de datos del OldestXID: %u\n" -#: pg_resetwal.c:813 +#: pg_resetwal.c:878 #, c-format msgid "NextXID epoch: %u\n" msgstr "Epoch del NextXID: %u\n" -#: pg_resetwal.c:819 +#: pg_resetwal.c:884 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "oldestCommitTsXid: %u\n" -#: pg_resetwal.c:824 +#: pg_resetwal.c:889 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "newestCommitTsXid: %u\n" -#: pg_resetwal.c:890 -#, c-format -msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" -msgstr "%s: error interno -- sizeof(ControlFileData) es demasiado grande ... corrija PG_CONTROL_SIZE\n" - -#: pg_resetwal.c:905 -#, c-format -msgid "%s: could not create pg_control file: %s\n" -msgstr "%s: no se pudo crear el archivo pg_control: %s\n" - -#: pg_resetwal.c:916 -#, c-format -msgid "%s: could not write pg_control file: %s\n" -msgstr "%s: no se pudo escribir el archivo pg_control: %s\n" - -#: pg_resetwal.c:923 pg_resetwal.c:1219 +#: pg_resetwal.c:975 pg_resetwal.c:1043 pg_resetwal.c:1090 #, c-format -msgid "%s: fsync error: %s\n" -msgstr "%s: error de fsync: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: pg_resetwal.c:963 pg_resetwal.c:1034 pg_resetwal.c:1085 +#: pg_resetwal.c:1010 pg_resetwal.c:1063 pg_resetwal.c:1113 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: no se pudo abrir el directorio «%s»: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" -#: pg_resetwal.c:999 pg_resetwal.c:1056 pg_resetwal.c:1110 +#: pg_resetwal.c:1016 pg_resetwal.c:1069 pg_resetwal.c:1119 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: no se pudo leer el directorio «%s»: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: pg_resetwal.c:1006 pg_resetwal.c:1063 pg_resetwal.c:1117 +#: pg_resetwal.c:1055 pg_resetwal.c:1105 #, c-format -msgid "%s: could not close directory \"%s\": %s\n" -msgstr "%s: no se pudo cerrar el directorio «%s»: %s\n" +msgid "could not delete file \"%s\": %m" +msgstr "no se pudo borrar el archivo «%s»: %m" -#: pg_resetwal.c:1047 pg_resetwal.c:1101 +#: pg_resetwal.c:1186 #, c-format -msgid "%s: could not delete file \"%s\": %s\n" -msgstr "%s: no se pudo borrar el archivo «%s»: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" -#: pg_resetwal.c:1186 +#: pg_resetwal.c:1196 pg_resetwal.c:1209 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: no se pudo abrir el archivo «%s»: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" -#: pg_resetwal.c:1197 pg_resetwal.c:1211 +#: pg_resetwal.c:1216 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: no se pudo escribir en el archivo «%s»: %s\n" +msgid "fsync error: %m" +msgstr "error de fsync: %m" -#: pg_resetwal.c:1230 +#: pg_resetwal.c:1227 #, c-format msgid "" "%s resets the PostgreSQL write-ahead log.\n" @@ -526,7 +551,7 @@ msgstr "" "%s restablece el WAL («write-ahead log») de PostgreSQL.\n" "\n" -#: pg_resetwal.c:1231 +#: pg_resetwal.c:1228 #, c-format msgid "" "Usage:\n" @@ -537,83 +562,97 @@ msgstr "" " %s [OPCIÓN]... DATADIR\n" "\n" -#: pg_resetwal.c:1232 +#: pg_resetwal.c:1229 #, c-format msgid "Options:\n" msgstr "Opciones:\n" -#: pg_resetwal.c:1233 +#: pg_resetwal.c:1230 #, c-format -msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" msgstr "" -" -c XID,XID asigna los ID de transacciones más antiguo y más nuevo que llevan\n" -" timestamp de commit\n" +" -c, --commit-timestamp-ids=XID,XID\n" +" definir la más antigua y la más nueva transacciones\n" +" que llevan timestamp de commit (cero significa no\n" +" cambiar)\n" + +#: pg_resetwal.c:1233 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR directorio de datos\n" #: pg_resetwal.c:1234 #, c-format -msgid " (zero in either value means no change)\n" -msgstr " (cero en cualquiera de ellos significa no cambiar)\n" +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH asigna el siguiente «epoch» de ID de transacción\n" #: pg_resetwal.c:1235 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR directorio de datos\n" +msgid " -f, --force force update to be done\n" +msgstr " -f, --force fuerza que la actualización sea hecha\n" #: pg_resetwal.c:1236 #, c-format -msgid " -e XIDEPOCH set next transaction ID epoch\n" -msgstr " -e XIDEPOCH asigna el siguiente «epoch» de ID de transacción\n" +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr "" +" -l, --next-wal-file=ARCHIVOWAL\n" +" fuerza una ubicación inicial mínima para nuevo WAL\n" #: pg_resetwal.c:1237 #, c-format -msgid " -f force update to be done\n" -msgstr " -f fuerza que la actualización sea hecha\n" +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr "" +" -m, --multixact-ids=MXID,MXID\n" +" asigna el siguiente ID de multitransacción y\n" +" el más antiguo\n" #: pg_resetwal.c:1238 #, c-format -msgid " -l WALFILE force minimum WAL starting location for new write-ahead log\n" -msgstr " -l ARCHIVOWAL fuerza una ubicación inicial mínima para el nuevo WAL\n" +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run no actualiza, sólo muestra lo que se haría\n" #: pg_resetwal.c:1239 #, c-format -msgid " -m MXID,MXID set next and oldest multitransaction ID\n" -msgstr " -m MXID,MXID asigna el siguiente ID de multitransacción y el más antiguo\n" +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID asigna el siguiente OID\n" #: pg_resetwal.c:1240 #, c-format -msgid " -n no update, just show what would be done (for testing)\n" -msgstr " -n no actualiza, sólo muestra lo que va a hacer (para pruebas)\n" +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr "" +" -O, --multixact-offset=OFFSET\n" +" asigna la siguiente posición de multitransacción\n" #: pg_resetwal.c:1241 #, c-format -msgid " -o OID set next OID\n" -msgstr " -o OID asigna el siguiente OID\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" #: pg_resetwal.c:1242 #, c-format -msgid " -O OFFSET set next multitransaction offset\n" -msgstr " -O OFFSET asigna la siguiente posición de multitransacción\n" +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr "" +" -x, --next-transaction-id=XID\n" +" asigna el siguiente ID de transacción\n" #: pg_resetwal.c:1243 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version muestra información de la versión, luego sale\n" +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=TAMAÑO tamaño de segmentos de WAL, en megabytes\n" #: pg_resetwal.c:1244 #, c-format -msgid " -x XID set next transaction ID\n" -msgstr " -x XID asigna el siguiente ID de transacción\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" #: pg_resetwal.c:1245 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help muestra esta ayuda, luego sale\n" - -#: pg_resetwal.c:1246 -#, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" diff --git a/src/bin/pg_resetwal/po/fr.po b/src/bin/pg_resetwal/po/fr.po index 82aec617ba3..6e19f49c359 100644 --- a/src/bin/pg_resetwal/po/fr.po +++ b/src/bin/pg_resetwal/po/fr.po @@ -22,7 +22,7 @@ msgstr "" #: ../../common/restricted_token.c:68 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s : ATTENTION : ne peut pas crér les jetons restreints sur cette plateforme\n" +msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" #: ../../common/restricted_token.c:77 #, c-format diff --git a/src/bin/pg_resetwal/po/ko.po b/src/bin/pg_resetwal/po/ko.po index 763a51d4573..a948e317483 100644 --- a/src/bin/pg_resetwal/po/ko.po +++ b/src/bin/pg_resetwal/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: pg_resetwal (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 18:37+0900\n" +"POT-Creation-Date: 2017-08-02 13:57+0900\n" +"PO-Revision-Date: 2017-08-17 15:51+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" "Language: ko\n" @@ -51,87 +51,87 @@ msgid "%s: could not get exit code from subprocess: error code %lu\n" msgstr "%s: 하위 í”„ë¡œì„¸ìŠ¤ì˜ ì¢…ë£Œ 코드를 구할 수 ì—†ìŒ: 오류 코드 %lu\n" #. translator: the second %s is a command line argument (-e, etc) -#: pg_resetxlog.c:140 pg_resetxlog.c:155 pg_resetxlog.c:170 pg_resetxlog.c:177 -#: pg_resetxlog.c:201 pg_resetxlog.c:216 pg_resetxlog.c:224 pg_resetxlog.c:250 -#: pg_resetxlog.c:264 +#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 +#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 +#: pg_resetwal.c:264 #, c-format msgid "%s: invalid argument for option %s\n" msgstr "%s: %s ì˜µì…˜ì˜ ìž˜ëª»ëœ ì¸ìž\n" -#: pg_resetxlog.c:141 pg_resetxlog.c:156 pg_resetxlog.c:171 pg_resetxlog.c:178 -#: pg_resetxlog.c:202 pg_resetxlog.c:217 pg_resetxlog.c:225 pg_resetxlog.c:251 -#: pg_resetxlog.c:265 pg_resetxlog.c:272 pg_resetxlog.c:285 pg_resetxlog.c:293 +#: pg_resetwal.c:141 pg_resetwal.c:156 pg_resetwal.c:171 pg_resetwal.c:178 +#: pg_resetwal.c:202 pg_resetwal.c:217 pg_resetwal.c:225 pg_resetwal.c:251 +#: pg_resetwal.c:265 pg_resetwal.c:272 pg_resetwal.c:285 pg_resetwal.c:293 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\"\n" -#: pg_resetxlog.c:146 +#: pg_resetwal.c:146 #, c-format msgid "%s: transaction ID epoch (-e) must not be -1\n" msgstr "%s: 트랜잭션 ID epoch (-e) ê°’ì€ -1ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:161 +#: pg_resetwal.c:161 #, c-format msgid "%s: transaction ID (-x) must not be 0\n" msgstr "%s: 트랜잭션 ID (-x) ê°’ì€ 0ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:185 pg_resetxlog.c:192 +#: pg_resetwal.c:185 pg_resetwal.c:192 #, c-format msgid "" "%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n" msgstr "%s: -c 옵션으로 지정한 트랜잭션 ID는 0ì´ê±°ë‚˜ 2ì´ìƒì´ì–´ì•¼ 함\n" -#: pg_resetxlog.c:207 +#: pg_resetwal.c:207 #, c-format msgid "%s: OID (-o) must not be 0\n" msgstr "%s: OID (-o) ê°’ì€ 0ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:230 +#: pg_resetwal.c:230 #, c-format msgid "%s: multitransaction ID (-m) must not be 0\n" msgstr "%s: 멀티트랜잭션 ID (-m) ê°’ì€ 0ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:240 +#: pg_resetwal.c:240 #, c-format msgid "%s: oldest multitransaction ID (-m) must not be 0\n" msgstr "%s: ì œì¼ ì˜¤ëž˜ëœ ë©€í‹°íŠ¸ëžœìž­ì…˜ ID (-m) ê°’ì€ 0ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:256 +#: pg_resetwal.c:256 #, c-format msgid "%s: multitransaction offset (-O) must not be -1\n" msgstr "%s: 멀티트랜잭션 옵셋 (-O) ê°’ì€ -1ì´ ì•„ë‹ˆì—¬ì•¼í•¨\n" -#: pg_resetxlog.c:283 +#: pg_resetwal.c:283 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" -#: pg_resetxlog.c:292 +#: pg_resetwal.c:292 #, c-format msgid "%s: no data directory specified\n" msgstr "%s: ë°ì´í„° 디렉터리를 지정하지 않았ìŒ\n" -#: pg_resetxlog.c:306 +#: pg_resetwal.c:306 #, c-format msgid "%s: cannot be executed by \"root\"\n" msgstr "%s: ì´ í”„ë¡œê·¸ëž¨ì€ \"root\"로 ì‹¤í–‰ë  ìˆ˜ ì—†ìŒ\n" -#: pg_resetxlog.c:308 +#: pg_resetwal.c:308 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "PostgreSQL superuser로 %s í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•˜ì‹­ì‹œì˜¤.\n" -#: pg_resetxlog.c:318 +#: pg_resetwal.c:318 #, c-format msgid "%s: could not change directory to \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리로 바꿀 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:331 pg_resetxlog.c:477 +#: pg_resetwal.c:334 pg_resetwal.c:481 pg_resetwal.c:544 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: \"%s\" 파ì¼ì„ ì½ê¸° 모드로 ì—´ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:338 +#: pg_resetwal.c:341 #, c-format msgid "" "%s: lock file \"%s\" exists\n" @@ -140,7 +140,7 @@ msgstr "" "%s: \"%s\" 잠금 파ì¼ì´ 있습니다.\n" "서버가 ê°€ë™ì¤‘ì¸ê°€ìš”? 그렇지 않다면, ì´ íŒŒì¼ì„ 지우고 다시 시ë„하십시오.\n" -#: pg_resetxlog.c:425 +#: pg_resetwal.c:428 #, c-format msgid "" "\n" @@ -149,23 +149,43 @@ msgstr "" "\n" "ì´ ì„¤ì •ê°’ë“¤ì´ íƒ€ë‹¹í•˜ë‹¤ê³  íŒë‹¨ë˜ë©´, 강제로 갱신하려면, -f ì˜µì…˜ì„ ì“°ì„¸ìš”.\n" -#: pg_resetxlog.c:437 +#: pg_resetwal.c:440 #, c-format msgid "" "The database server was not shut down cleanly.\n" -"Resetting the transaction log might cause data to be lost.\n" +"Resetting the write-ahead log might cause data to be lost.\n" "If you want to proceed anyway, use -f to force reset.\n" msgstr "" "ì´ ë°ì´í„°ë² ì´ìФ 서버는 ì •ìƒì ìœ¼ë¡œ 중지ë˜ì§€ 못했습니다.\n" "트랜잭션 로그를 다시 설정하는 ê²ƒì€ ìžë£Œ ì†ì‹¤ì„ 야기할 수 있습니다.\n" "그럼ì—ë„ ë¶ˆêµ¬í•˜ê³  진행하려면, -f ì˜µì…˜ì„ ì‚¬ìš©í•´ì„œ ê°•ì œ ì„¤ì •ì„ í•˜ì‹­ì‹œì˜¤.\n" -#: pg_resetxlog.c:451 +#: pg_resetwal.c:454 #, c-format -msgid "Transaction log reset\n" +msgid "Write-ahead log reset\n" msgstr "트랜잭션 로그 재설정\n" -#: pg_resetxlog.c:480 +#: pg_resetwal.c:491 +#, c-format +msgid "%s: unexpected empty file \"%s\"\n" +msgstr "%s: \"%s\" 파ì¼ì€ 예ìƒì¹˜ 않게 비었ìŒ\n" + +#: pg_resetwal.c:496 pg_resetwal.c:560 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" + +#: pg_resetwal.c:513 +#, c-format +msgid "" +"%s: data directory is of wrong version\n" +"File \"%s\" contains \"%s\", which is not compatible with this program's " +"version \"%s\".\n" +msgstr "" +"%s: ë°ì´í„° 디렉터리 ë²„ì „ì´ ìž˜ëª»ë¨\n" +"\"%s\" íŒŒì¼ ë²„ì „ì€ \"%s\", ì´ í”„ë¡œê·¸ëž¨ ë²„ì „ì€ \"%s\".\n" + +#: pg_resetwal.c:547 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" @@ -177,23 +197,18 @@ msgstr "" " touch %s\n" "(win32ì—서 어떻게 하나?)\n" -#: pg_resetxlog.c:493 -#, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" - -#: pg_resetxlog.c:516 +#: pg_resetwal.c:583 #, c-format msgid "%s: pg_control exists but has invalid CRC; proceed with caution\n" msgstr "" "%s: pg_control파ì¼ì´ 있지만, CRCê°’ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤; 경고과 함께 진행함\n" -#: pg_resetxlog.c:525 +#: pg_resetwal.c:592 #, c-format -msgid "%s: pg_control exists but is broken or unknown version; ignoring it\n" -msgstr "%s: pg_control파ì¼ì´ 있지만, ì†ìƒë˜ì—ˆê±°ë‚˜ ë²„ì „ì„ ì•Œ 수 ì—†ìŒ; 무시함\n" +msgid "%s: pg_control exists but is broken or wrong version; ignoring it\n" +msgstr "%s: pg_control 파ì¼ì´ 있지만, ì†ìƒë˜ì—ˆê±°ë‚˜ ë²„ì „ì„ ì•Œ 수 ì—†ìŒ; 무시함\n" -#: pg_resetxlog.c:628 +#: pg_resetwal.c:690 #, c-format msgid "" "Guessed pg_control values:\n" @@ -202,7 +217,7 @@ msgstr "" "ì¶”ì¸¡ëœ pg_control 설정값들:\n" "\n" -#: pg_resetxlog.c:630 +#: pg_resetwal.c:692 #, c-format msgid "" "Current pg_control values:\n" @@ -211,176 +226,172 @@ msgstr "" "현재 pg_control 설정값들:\n" "\n" -#: pg_resetxlog.c:639 +#: pg_resetwal.c:701 #, c-format msgid "pg_control version number: %u\n" msgstr "pg_control 버전 번호: %u\n" -#: pg_resetxlog.c:641 +#: pg_resetwal.c:703 #, c-format msgid "Catalog version number: %u\n" msgstr "카탈로그 버전 번호: %u\n" -#: pg_resetxlog.c:643 +#: pg_resetwal.c:705 #, c-format msgid "Database system identifier: %s\n" msgstr "ë°ì´í„°ë² ì´ìФ 시스템 ì‹ë³„ìž: %s\n" -#: pg_resetxlog.c:645 +#: pg_resetwal.c:707 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ TimeLineID: %u\n" -#: pg_resetxlog.c:647 +#: pg_resetwal.c:709 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ full_page_writes: %s\n" -#: pg_resetxlog.c:648 +#: pg_resetwal.c:710 msgid "off" msgstr "off" -#: pg_resetxlog.c:648 +#: pg_resetwal.c:710 msgid "on" msgstr "on" -#: pg_resetxlog.c:649 +#: pg_resetwal.c:711 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextXID: %u:%u\n" -#: pg_resetxlog.c:652 +#: pg_resetwal.c:714 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextOID: %u\n" -#: pg_resetxlog.c:654 +#: pg_resetwal.c:716 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextMultiXactId: %u\n" -#: pg_resetxlog.c:656 +#: pg_resetwal.c:718 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ NextMultiOffset: %u\n" -#: pg_resetxlog.c:658 +#: pg_resetwal.c:720 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ XID: %u\n" -#: pg_resetxlog.c:660 +#: pg_resetwal.c:722 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ XIDì˜ DB:%u\n" -#: pg_resetxlog.c:662 +#: pg_resetwal.c:724 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ ActiveXID:%u\n" -#: pg_resetxlog.c:664 +#: pg_resetwal.c:726 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ MultiXid:%u\n" -#: pg_resetxlog.c:666 +#: pg_resetwal.c:728 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ MultiXidì˜ DB:%u\n" -#: pg_resetxlog.c:668 +#: pg_resetwal.c:730 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ CommitTsXid:%u\n" -#: pg_resetxlog.c:670 +#: pg_resetwal.c:732 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "마지막 ì²´í¬í¬ì¸íЏ 최신 CommitTsXid: %u\n" -#: pg_resetxlog.c:672 +#: pg_resetwal.c:734 #, c-format msgid "Maximum data alignment: %u\n" msgstr "최대 ìžë£Œ ì •ë ¬: %u\n" -#: pg_resetxlog.c:675 +#: pg_resetwal.c:737 #, c-format msgid "Database block size: %u\n" msgstr "ë°ì´í„°ë² ì´ìФ ë¸”ë¡ í¬ê¸°: %u\n" -#: pg_resetxlog.c:677 +#: pg_resetwal.c:739 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "대형 릴레ì´ì…˜ì˜ 세그먼트당 블럭 갯수: %u\n" -#: pg_resetxlog.c:679 +#: pg_resetwal.c:741 #, c-format msgid "WAL block size: %u\n" msgstr "WAL ë¸”ë¡ í¬ê¸°: %u\n" -#: pg_resetxlog.c:681 +#: pg_resetwal.c:743 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "WAL ì„¸ê·¸ë¨¼íŠ¸ì˜ í¬ê¸°(byte): %u\n" -#: pg_resetxlog.c:683 +#: pg_resetwal.c:745 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "ì‹ë³„ìž ìµœëŒ€ 길ì´: %u\n" -#: pg_resetxlog.c:685 +#: pg_resetwal.c:747 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "ì¸ë±ìФì—서 사용하는 최대 ì—´ 수: %u\n" -#: pg_resetxlog.c:687 +#: pg_resetwal.c:749 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "TOAST ì²­í¬ì˜ 최대 í¬ê¸°: %u\n" -#: pg_resetxlog.c:689 +#: pg_resetwal.c:751 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "대형ê°ì²´ ì²­í¬ì˜ 최대 í¬ê¸°: %u\n" -#: pg_resetxlog.c:691 +#: pg_resetwal.c:754 #, c-format msgid "Date/time type storage: %s\n" msgstr "ë‚ ì§œ/시간형 ìžë£Œì˜ 저장방ì‹: %s\n" -#: pg_resetxlog.c:692 +#: pg_resetwal.c:755 msgid "64-bit integers" msgstr "64-비트 정수" -#: pg_resetxlog.c:692 -msgid "floating-point numbers" -msgstr "ë¶€ë™ì†Œìˆ˜" - -#: pg_resetxlog.c:693 +#: pg_resetwal.c:756 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Float4 ì¸ìˆ˜ 전달: %s\n" -#: pg_resetxlog.c:694 pg_resetxlog.c:696 +#: pg_resetwal.c:757 pg_resetwal.c:759 msgid "by reference" msgstr "참조별" -#: pg_resetxlog.c:694 pg_resetxlog.c:696 +#: pg_resetwal.c:757 pg_resetwal.c:759 msgid "by value" msgstr "값별" -#: pg_resetxlog.c:695 +#: pg_resetwal.c:758 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Float8 ì¸ìˆ˜ 전달: %s\n" -#: pg_resetxlog.c:697 +#: pg_resetwal.c:760 #, c-format msgid "Data page checksum version: %u\n" msgstr "ë°ì´í„° 페ì´ì§€ ì²´í¬ì„¬ 버전: %u\n" -#: pg_resetxlog.c:711 +#: pg_resetwal.c:774 #, c-format msgid "" "\n" @@ -393,130 +404,121 @@ msgstr "" "ë³€ê²½ë  ê°’:\n" "\n" -#: pg_resetxlog.c:714 +#: pg_resetwal.c:777 #, c-format msgid "First log segment after reset: %s\n" msgstr "리셋 ë’¤ 첫 로그 세그먼트: %s\n" -#: pg_resetxlog.c:718 +#: pg_resetwal.c:781 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetxlog.c:720 +#: pg_resetwal.c:783 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetxlog.c:722 +#: pg_resetwal.c:785 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "OldestMultiXidì˜ DB: %u\n" -#: pg_resetxlog.c:728 +#: pg_resetwal.c:791 #, c-format msgid "NextMultiOffset: %u\n" msgstr "NextMultiOffset: %u\n" -#: pg_resetxlog.c:734 +#: pg_resetwal.c:797 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetxlog.c:740 +#: pg_resetwal.c:803 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetxlog.c:742 +#: pg_resetwal.c:805 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetxlog.c:744 +#: pg_resetwal.c:807 #, c-format msgid "OldestXID's DB: %u\n" msgstr "OldestXIDì˜ DB: %u\n" -#: pg_resetxlog.c:750 +#: pg_resetwal.c:813 #, c-format msgid "NextXID epoch: %u\n" msgstr "NextXID epoch: %u\n" -#: pg_resetxlog.c:756 +#: pg_resetwal.c:819 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "ì œì¼ ì˜¤ëž˜ëœ CommitTsXid: %u\n" -#: pg_resetxlog.c:761 +#: pg_resetwal.c:824 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "최근 CommitTsXid: %u\n" -#: pg_resetxlog.c:827 -#, c-format -msgid "" -"%s: internal error -- sizeof(ControlFileData) is too large ... fix " -"PG_CONTROL_SIZE\n" -msgstr "" -"%s: ë‚´ë¶€ 오류 -- sizeof(ControlFileData) ê°’ì´ ë„ˆë¬´ í¼ ... PG_CONTROL_SIZE ê³ " -"ì³ì•¼í•¨\n" - -#: pg_resetxlog.c:842 +#: pg_resetwal.c:906 #, c-format msgid "%s: could not create pg_control file: %s\n" msgstr "%s: pg_control íŒŒì¼ ë§Œë“¤ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:853 +#: pg_resetwal.c:917 #, c-format msgid "%s: could not write pg_control file: %s\n" msgstr "%s: pg_control íŒŒì¼ ì“¸ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:860 pg_resetxlog.c:1156 +#: pg_resetwal.c:924 pg_resetwal.c:1220 #, c-format msgid "%s: fsync error: %s\n" msgstr "%s: fsync 오류: %s\n" -#: pg_resetxlog.c:900 pg_resetxlog.c:971 pg_resetxlog.c:1022 +#: pg_resetwal.c:964 pg_resetwal.c:1035 pg_resetwal.c:1086 #, c-format msgid "%s: could not open directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:936 pg_resetxlog.c:993 pg_resetxlog.c:1047 +#: pg_resetwal.c:1000 pg_resetwal.c:1057 pg_resetwal.c:1111 #, c-format msgid "%s: could not read directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:943 pg_resetxlog.c:1000 pg_resetxlog.c:1054 +#: pg_resetwal.c:1007 pg_resetwal.c:1064 pg_resetwal.c:1118 #, c-format msgid "%s: could not close directory \"%s\": %s\n" msgstr "%s: \"%s\" 디렉터리를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: pg_resetxlog.c:984 pg_resetxlog.c:1038 +#: pg_resetwal.c:1048 pg_resetwal.c:1102 #, c-format msgid "%s: could not delete file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì‚­ì œ í•  수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:1123 +#: pg_resetwal.c:1187 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì—´ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:1134 pg_resetxlog.c:1148 +#: pg_resetwal.c:1198 pg_resetwal.c:1212 #, c-format msgid "%s: could not write file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì“¸ 수 ì—†ìŒ: %s\n" -#: pg_resetxlog.c:1167 +#: pg_resetwal.c:1231 #, c-format msgid "" -"%s resets the PostgreSQL transaction log.\n" +"%s resets the PostgreSQL write-ahead log.\n" "\n" msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL 트랜잭션 로그를 다시 설정합니다.\n" "\n" -#: pg_resetxlog.c:1168 +#: pg_resetwal.c:1232 #, c-format msgid "" "Usage:\n" @@ -527,12 +529,12 @@ msgstr "" " %s [옵션]... DATADIR\n" "\n" -#: pg_resetxlog.c:1169 +#: pg_resetwal.c:1233 #, c-format msgid "Options:\n" msgstr "옵션들:\n" -#: pg_resetxlog.c:1170 +#: pg_resetwal.c:1234 #, c-format msgid "" " -c XID,XID set oldest and newest transactions bearing commit " @@ -540,72 +542,72 @@ msgid "" msgstr "" " -c XID,XID 커밋 ì‹œê°„ì„ ë„출하는 ì œì¼ ì˜¤ëž˜ëœ, ìµœì‹ ì˜ íŠ¸ëžœìž­ì…˜ 지정\n" -#: pg_resetxlog.c:1171 +#: pg_resetwal.c:1235 #, c-format msgid " (zero in either value means no change)\n" msgstr " (0으로 지정하면 바꾸지 않ìŒ)\n" -#: pg_resetxlog.c:1172 +#: pg_resetwal.c:1236 #, c-format msgid " [-D] DATADIR data directory\n" msgstr " [-D] DATADIR ë°ì´í„° 디렉터리\n" -#: pg_resetxlog.c:1173 +#: pg_resetwal.c:1237 #, c-format msgid " -e XIDEPOCH set next transaction ID epoch\n" msgstr " -e XIDEPOCH ë‹¤ìŒ íŠ¸ëž™ìž­ì…˜ ID epoch 지정\n" -#: pg_resetxlog.c:1174 +#: pg_resetwal.c:1238 #, c-format msgid " -f force update to be done\n" msgstr " -f 강제로 갱신함\n" -#: pg_resetxlog.c:1175 +#: pg_resetwal.c:1239 #, c-format msgid "" -" -l XLOGFILE force minimum WAL starting location for new transaction " +" -l WALFILE force minimum WAL starting location for new write-ahead " "log\n" msgstr "" -" -l XLOGFILE 새 트랜잭션 로그를 위한 WAL 최소 시작 위치를 강제로 지정\n" +" -l WALFILE 새 트랜잭션 로그를 위한 WAL 최소 시작 위치를 강제로 지정\n" -#: pg_resetxlog.c:1176 +#: pg_resetwal.c:1240 #, c-format msgid " -m MXID,MXID set next and oldest multitransaction ID\n" msgstr " -m MXID,MXID ë‹¤ìŒ ì œì¼ ì˜¤ëž˜ëœ ë©€í‹°íŠ¸ëžœìž­ì…˜ ID 지정\n" -#: pg_resetxlog.c:1177 +#: pg_resetwal.c:1241 #, c-format msgid "" " -n no update, just show what would be done (for testing)\n" msgstr "" " -n 갱신하지 않ìŒ, 컨트롤 ê°’ë“¤ì„ ë³´ì—¬ì£¼ê¸°ë§Œ 함(테스트용)\n" -#: pg_resetxlog.c:1178 +#: pg_resetwal.c:1242 #, c-format msgid " -o OID set next OID\n" msgstr " -o OID ë‹¤ìŒ OID 지정\n" -#: pg_resetxlog.c:1179 +#: pg_resetwal.c:1243 #, c-format msgid " -O OFFSET set next multitransaction offset\n" msgstr " -O OFFSET ë‹¤ìŒ ë©€í‹°íŠ¸ëžœìž­ì…˜ 옵셋 지정\n" -#: pg_resetxlog.c:1180 +#: pg_resetwal.c:1244 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" -#: pg_resetxlog.c:1181 +#: pg_resetwal.c:1245 #, c-format msgid " -x XID set next transaction ID\n" msgstr " -x XID ë‹¤ìŒ XID(트랜잭션 ID) 지정\n" -#: pg_resetxlog.c:1182 +#: pg_resetwal.c:1246 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: pg_resetxlog.c:1183 +#: pg_resetwal.c:1247 #, c-format msgid "" "\n" diff --git a/src/bin/pg_resetwal/po/ru.po b/src/bin/pg_resetwal/po/ru.po index 8e9555b934a..83097f948f6 100644 --- a/src/bin/pg_resetwal/po/ru.po +++ b/src/bin/pg_resetwal/po/ru.po @@ -6,13 +6,12 @@ # Sergey Burladyan , 2009. # Dmitriy Olshevskiy , 2014. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: pg_resetxlog (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:45+0000\n" -"PO-Revision-Date: 2016-12-20 18:26+0300\n" +"POT-Creation-Date: 2017-08-23 14:45+0000\n" +"PO-Revision-Date: 2017-08-23 12:34+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -60,87 +59,87 @@ msgid "%s: could not get exit code from subprocess: error code %lu\n" msgstr "%s: не удалоÑÑŒ получить код выхода от подпроцеÑÑа (код ошибки: %lu)\n" #. translator: the second %s is a command line argument (-e, etc) -#: pg_resetwal.c:139 pg_resetwal.c:154 pg_resetwal.c:169 pg_resetwal.c:176 -#: pg_resetwal.c:200 pg_resetwal.c:215 pg_resetwal.c:223 pg_resetwal.c:249 -#: pg_resetwal.c:263 +#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 +#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 +#: pg_resetwal.c:264 #, c-format msgid "%s: invalid argument for option %s\n" msgstr "%s: недопуÑтимый аргумент параметра %s\n" -#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 -#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 -#: pg_resetwal.c:264 pg_resetwal.c:271 pg_resetwal.c:284 pg_resetwal.c:292 +#: pg_resetwal.c:141 pg_resetwal.c:156 pg_resetwal.c:171 pg_resetwal.c:178 +#: pg_resetwal.c:202 pg_resetwal.c:217 pg_resetwal.c:225 pg_resetwal.c:251 +#: pg_resetwal.c:265 pg_resetwal.c:272 pg_resetwal.c:285 pg_resetwal.c:293 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_resetwal.c:145 +#: pg_resetwal.c:146 #, c-format msgid "%s: transaction ID epoch (-e) must not be -1\n" msgstr "%s: Ñпоха ID транзакции (-e) не должна быть равна -1\n" -#: pg_resetwal.c:160 +#: pg_resetwal.c:161 #, c-format msgid "%s: transaction ID (-x) must not be 0\n" msgstr "%s: ID транзакции (-x) не должен быть равен 0\n" -#: pg_resetwal.c:184 pg_resetwal.c:191 +#: pg_resetwal.c:185 pg_resetwal.c:192 #, c-format msgid "" "%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n" msgstr "%s: ID транзакции (-c) должен быть равен 0, либо больше или равен 2\n" -#: pg_resetwal.c:206 +#: pg_resetwal.c:207 #, c-format msgid "%s: OID (-o) must not be 0\n" msgstr "%s: OID (-o) не должен быть равен 0\n" -#: pg_resetwal.c:229 +#: pg_resetwal.c:230 #, c-format msgid "%s: multitransaction ID (-m) must not be 0\n" msgstr "%s: ID мультитранзакции (-m) не должен быть равен 0\n" -#: pg_resetwal.c:239 +#: pg_resetwal.c:240 #, c-format msgid "%s: oldest multitransaction ID (-m) must not be 0\n" msgstr "%s: ID Ñтарейшей мультитранзакции (-m) не должен быть равен 0\n" -#: pg_resetwal.c:255 +#: pg_resetwal.c:256 #, c-format msgid "%s: multitransaction offset (-O) must not be -1\n" msgstr "%s: Ñмещение мультитранзакции (-O) не должно быть равно -1\n" -#: pg_resetwal.c:282 +#: pg_resetwal.c:283 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: pg_resetwal.c:291 +#: pg_resetwal.c:292 #, c-format msgid "%s: no data directory specified\n" msgstr "%s: каталог данных не указан\n" -#: pg_resetwal.c:305 +#: pg_resetwal.c:306 #, c-format msgid "%s: cannot be executed by \"root\"\n" msgstr "%s: программу не должен запуÑкать root\n" -#: pg_resetwal.c:307 +#: pg_resetwal.c:308 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "ЗапуÑкать %s нужно от имени ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ PostgreSQL.\n" -#: pg_resetwal.c:317 +#: pg_resetwal.c:318 #, c-format msgid "%s: could not change directory to \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ перейти в каталог \"%s\": %s\n" -#: pg_resetwal.c:330 pg_resetwal.c:476 +#: pg_resetwal.c:334 pg_resetwal.c:481 pg_resetwal.c:544 #, c-format msgid "%s: could not open file \"%s\" for reading: %s\n" msgstr "%s: не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %s\n" -#: pg_resetwal.c:337 +#: pg_resetwal.c:341 #, c-format msgid "" "%s: lock file \"%s\" exists\n" @@ -149,7 +148,7 @@ msgstr "" "%s: обнаружен файл блокировки \"%s\"\n" "Возможно, Ñервер запущен? ЕÑли нет, удалите Ñтот файл и попробуйте Ñнова.\n" -#: pg_resetwal.c:424 +#: pg_resetwal.c:428 #, c-format msgid "" "\n" @@ -159,23 +158,43 @@ msgstr "" "ЕÑли Ñти Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ÐµÐ¼Ð»ÐµÐ¼Ñ‹, выполните ÑÐ±Ñ€Ð¾Ñ Ð¿Ñ€Ð¸Ð½ÑƒÐ´Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾, добавив ключ -" "f.\n" -#: pg_resetwal.c:436 +#: pg_resetwal.c:440 #, c-format msgid "" "The database server was not shut down cleanly.\n" -"Resetting the transaction log might cause data to be lost.\n" +"Resetting the write-ahead log might cause data to be lost.\n" "If you want to proceed anyway, use -f to force reset.\n" msgstr "" "Сервер баз данных был оÑтановлен некорректно.\n" -"Ð¡Ð±Ñ€Ð¾Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° транзакций может привеÑти к потере данных.\n" +"Ð¡Ð±Ñ€Ð¾Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° предзапиÑи может привеÑти к потере данных.\n" "ЕÑли вы хотите ÑброÑить его, неÑÐ¼Ð¾Ñ‚Ñ€Ñ Ð½Ð° Ñто, добавьте ключ -f.\n" -#: pg_resetwal.c:450 +#: pg_resetwal.c:454 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "Журнал предзапиÑи Ñброшен\n" + +#: pg_resetwal.c:491 +#, c-format +msgid "%s: unexpected empty file \"%s\"\n" +msgstr "%s: файл \"%s\" оказалÑÑ Ð¿ÑƒÑтым\n" + +#: pg_resetwal.c:496 pg_resetwal.c:560 +#, c-format +msgid "%s: could not read file \"%s\": %s\n" +msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\": %s\n" + +#: pg_resetwal.c:513 #, c-format -msgid "Transaction log reset\n" -msgstr "Журнал транзакций Ñброшен\n" +msgid "" +"%s: data directory is of wrong version\n" +"File \"%s\" contains \"%s\", which is not compatible with this program's " +"version \"%s\".\n" +msgstr "" +"%s: каталог данных неверной верÑии\n" +"Файл \"%s\" Ñодержит Ñтроку \"%s\", а ожидаетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ \"%s\".\n" -#: pg_resetwal.c:479 +#: pg_resetwal.c:547 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" @@ -186,25 +205,21 @@ msgstr "" " touch %s\n" "и повторите попытку.\n" -#: pg_resetwal.c:492 -#, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: не удалоÑÑŒ прочитать файл \"%s\": %s\n" - -#: pg_resetwal.c:515 +#: pg_resetwal.c:583 #, c-format msgid "%s: pg_control exists but has invalid CRC; proceed with caution\n" msgstr "" "%s: pg_control ÑущеÑтвует, но его ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма неверна; продолжайте Ñ " "оÑторожноÑтью\n" -#: pg_resetwal.c:524 +#: pg_resetwal.c:592 #, c-format -msgid "%s: pg_control exists but is broken or unknown version; ignoring it\n" +msgid "%s: pg_control exists but is broken or wrong version; ignoring it\n" msgstr "" -"%s: pg_control иÑпорчен или имеет неизвеÑтную верÑию; игнорируетÑÑ...\n" +"%s: pg_control иÑпорчен или имеет неизвеÑтную либо недопуÑтимую верÑию; " +"игнорируетÑÑ...\n" -#: pg_resetwal.c:622 +#: pg_resetwal.c:690 #, c-format msgid "" "Guessed pg_control values:\n" @@ -213,7 +228,7 @@ msgstr "" "Предполагаемые Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ pg_control:\n" "\n" -#: pg_resetwal.c:624 +#: pg_resetwal.c:692 #, c-format msgid "" "Current pg_control values:\n" @@ -222,186 +237,186 @@ msgstr "" "Текущие Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ pg_control:\n" "\n" -#: pg_resetwal.c:633 +#: pg_resetwal.c:701 #, c-format msgid "pg_control version number: %u\n" msgstr "Ðомер верÑии pg_control: %u\n" -#: pg_resetwal.c:635 +#: pg_resetwal.c:703 #, c-format msgid "Catalog version number: %u\n" msgstr "Ðомер верÑии каталога: %u\n" -#: pg_resetwal.c:637 +#: pg_resetwal.c:705 #, c-format msgid "Database system identifier: %s\n" msgstr "Идентификатор ÑиÑтемы баз данных: %s\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:639 +#: pg_resetwal.c:707 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "Ð›Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ поÑледней конт. точки: %u\n" # skip-rule: no-space-after-period -#: pg_resetwal.c:641 +#: pg_resetwal.c:709 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "Режим full_page_writes поÑледней к.Ñ‚: %s\n" -#: pg_resetwal.c:642 +#: pg_resetwal.c:710 msgid "off" msgstr "выкл." -#: pg_resetwal.c:642 +#: pg_resetwal.c:710 msgid "on" msgstr "вкл." # skip-rule: capital-letter-first -#: pg_resetwal.c:643 +#: pg_resetwal.c:711 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID поÑледней конт. точки: %u:%u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:646 +#: pg_resetwal.c:714 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:648 +#: pg_resetwal.c:716 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId поÑлед. конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:650 +#: pg_resetwal.c:718 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset поÑлед. конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:652 +#: pg_resetwal.c:720 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:654 +#: pg_resetwal.c:722 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "БД Ñ oldestXID поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:656 +#: pg_resetwal.c:724 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID поÑледней к. Ñ‚.: %u\n" # skip-rule: capital-letter-first -#: pg_resetwal.c:658 +#: pg_resetwal.c:726 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid поÑледней конт. точки: %u\n" # skip-rule: capital-letter-first, double-space -#: pg_resetwal.c:660 +#: pg_resetwal.c:728 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "БД Ñ oldestMulti поÑледней к. Ñ‚.: %u\n" # skip-rule: capital-letter-first, double-space -#: pg_resetwal.c:662 +#: pg_resetwal.c:730 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid поÑледней к. Ñ‚.: %u\n" # skip-rule: capital-letter-first, double-space -#: pg_resetwal.c:664 +#: pg_resetwal.c:732 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid поÑледней к. Ñ‚.: %u\n" -#: pg_resetwal.c:666 +#: pg_resetwal.c:734 #, c-format msgid "Maximum data alignment: %u\n" msgstr "МакÑ. предел Ð²Ñ‹Ñ€Ð°Ð²Ð½Ð¸Ð²Ð°Ð½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…: %u\n" -#: pg_resetwal.c:669 +#: pg_resetwal.c:737 #, c-format msgid "Database block size: %u\n" msgstr "Размер блока БД: %u\n" # skip-rule: double-space -#: pg_resetwal.c:671 +#: pg_resetwal.c:739 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Блоков в макÑ. Ñегменте отношений: %u\n" -#: pg_resetwal.c:673 +#: pg_resetwal.c:741 #, c-format msgid "WAL block size: %u\n" msgstr "Размер блока WAL: %u\n" -#: pg_resetwal.c:675 +#: pg_resetwal.c:743 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Байт в Ñегменте WAL: %u\n" -#: pg_resetwal.c:677 +#: pg_resetwal.c:745 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° идентификаторов: %u\n" -#: pg_resetwal.c:679 +#: pg_resetwal.c:747 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "МакÑимальное чиÑло Ñтолбцов в индекÑе: %u\n" -#: pg_resetwal.c:681 +#: pg_resetwal.c:749 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "МакÑимальный размер порции TOAST: %u\n" -#: pg_resetwal.c:683 +#: pg_resetwal.c:751 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Размер порции большого объекта: %u\n" -#: pg_resetwal.c:686 +#: pg_resetwal.c:754 #, c-format msgid "Date/time type storage: %s\n" msgstr "Формат Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‹/времени: %s\n" -#: pg_resetwal.c:687 +#: pg_resetwal.c:755 msgid "64-bit integers" msgstr "64-битные целые" -#: pg_resetwal.c:688 +#: pg_resetwal.c:756 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Передача аргумента Float4: %s\n" -#: pg_resetwal.c:689 pg_resetwal.c:691 +#: pg_resetwal.c:757 pg_resetwal.c:759 msgid "by reference" msgstr "по ÑÑылке" -#: pg_resetwal.c:689 pg_resetwal.c:691 +#: pg_resetwal.c:757 pg_resetwal.c:759 msgid "by value" msgstr "по значению" -#: pg_resetwal.c:690 +#: pg_resetwal.c:758 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Передача аргумента Float8: %s\n" -#: pg_resetwal.c:692 +#: pg_resetwal.c:760 #, c-format msgid "Data page checksum version: %u\n" msgstr "ВерÑÐ¸Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… Ñумм Ñтраниц: %u\n" -#: pg_resetwal.c:706 +#: pg_resetwal.c:774 #, c-format msgid "" "\n" @@ -414,130 +429,121 @@ msgstr "" "ЗначениÑ, которые будут изменены:\n" "\n" -#: pg_resetwal.c:709 +#: pg_resetwal.c:777 #, c-format msgid "First log segment after reset: %s\n" msgstr "Первый Ñегмент журнала поÑле ÑброÑа: %s\n" -#: pg_resetwal.c:713 +#: pg_resetwal.c:781 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetwal.c:715 +#: pg_resetwal.c:783 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetwal.c:717 +#: pg_resetwal.c:785 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "БД Ñ oldestMultiXid: %u\n" -#: pg_resetwal.c:723 +#: pg_resetwal.c:791 #, c-format msgid "NextMultiOffset: %u\n" msgstr "NextMultiOffset: %u\n" -#: pg_resetwal.c:729 +#: pg_resetwal.c:797 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetwal.c:735 +#: pg_resetwal.c:803 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetwal.c:737 +#: pg_resetwal.c:805 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetwal.c:739 +#: pg_resetwal.c:807 #, c-format msgid "OldestXID's DB: %u\n" msgstr "БД Ñ oldestXID: %u\n" -#: pg_resetwal.c:745 +#: pg_resetwal.c:813 #, c-format msgid "NextXID epoch: %u\n" msgstr "Эпоха NextXID: %u\n" -#: pg_resetwal.c:751 +#: pg_resetwal.c:819 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "oldestCommitTsXid: %u\n" -#: pg_resetwal.c:756 +#: pg_resetwal.c:824 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "newestCommitTsXid: %u\n" -#: pg_resetwal.c:822 -#, c-format -msgid "" -"%s: internal error -- sizeof(ControlFileData) is too large ... fix " -"PG_CONTROL_SIZE\n" -msgstr "" -"%s: внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° -- размер ControlFileData Ñлишком велик -- иÑправьте " -"PG_CONTROL_SIZE\n" - -#: pg_resetwal.c:837 +#: pg_resetwal.c:906 #, c-format msgid "%s: could not create pg_control file: %s\n" msgstr "%s: не удалоÑÑŒ Ñоздать файл pg_control: %s\n" -#: pg_resetwal.c:848 +#: pg_resetwal.c:917 #, c-format msgid "%s: could not write pg_control file: %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл pg_control: %s\n" -#: pg_resetwal.c:855 pg_resetwal.c:1151 +#: pg_resetwal.c:924 pg_resetwal.c:1220 #, c-format msgid "%s: fsync error: %s\n" msgstr "%s: ошибка Ñинхронизации Ñ Ð¤Ð¡: %s\n" -#: pg_resetwal.c:895 pg_resetwal.c:966 pg_resetwal.c:1017 +#: pg_resetwal.c:964 pg_resetwal.c:1035 pg_resetwal.c:1086 #, c-format msgid "%s: could not open directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть каталог \"%s\": %s\n" -#: pg_resetwal.c:931 pg_resetwal.c:988 pg_resetwal.c:1042 +#: pg_resetwal.c:1000 pg_resetwal.c:1057 pg_resetwal.c:1111 #, c-format msgid "%s: could not read directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ прочитать каталог \"%s\": %s\n" -#: pg_resetwal.c:938 pg_resetwal.c:995 pg_resetwal.c:1049 +#: pg_resetwal.c:1007 pg_resetwal.c:1064 pg_resetwal.c:1118 #, c-format msgid "%s: could not close directory \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ закрыть каталог \"%s\": %s\n" -#: pg_resetwal.c:979 pg_resetwal.c:1033 +#: pg_resetwal.c:1048 pg_resetwal.c:1102 #, c-format msgid "%s: could not delete file \"%s\": %s\n" msgstr "%s: ошибка при удалении файла \"%s\": %s\n" -#: pg_resetwal.c:1118 +#: pg_resetwal.c:1187 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть файл \"%s\": %s\n" -#: pg_resetwal.c:1129 pg_resetwal.c:1143 +#: pg_resetwal.c:1198 pg_resetwal.c:1212 #, c-format msgid "%s: could not write file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ запиÑать файл \"%s\": %s\n" -#: pg_resetwal.c:1162 +#: pg_resetwal.c:1231 #, c-format msgid "" -"%s resets the PostgreSQL transaction log.\n" +"%s resets the PostgreSQL write-ahead log.\n" "\n" msgstr "" -"%s ÑбраÑывает журнал транзакций PostgreSQL.\n" +"%s ÑбраÑывает журнал предзапиÑи PostgreSQL.\n" "\n" -#: pg_resetwal.c:1163 +#: pg_resetwal.c:1232 #, c-format msgid "" "Usage:\n" @@ -548,12 +554,12 @@ msgstr "" " %s [ПÐРÐМЕТР]... КÐТ_ДÐÐÐЫХ\n" "\n" -#: pg_resetwal.c:1164 +#: pg_resetwal.c:1233 #, c-format msgid "Options:\n" msgstr "Параметры:\n" -#: pg_resetwal.c:1165 +#: pg_resetwal.c:1234 #, c-format msgid "" " -c XID,XID set oldest and newest transactions bearing commit " @@ -562,41 +568,41 @@ msgstr "" " -c XID,XID задать Ñтарейшую и новейшую транзакции, неÑущие метку " "времени фикÑации\n" -#: pg_resetwal.c:1166 +#: pg_resetwal.c:1235 #, c-format msgid " (zero in either value means no change)\n" msgstr " (0 в любом из аргументов игнорируетÑÑ)\n" -#: pg_resetwal.c:1167 +#: pg_resetwal.c:1236 #, c-format msgid " [-D] DATADIR data directory\n" msgstr " [-D] КÐТ_ДÐÐÐЫХ каталог данных\n" -#: pg_resetwal.c:1168 +#: pg_resetwal.c:1237 #, c-format msgid " -e XIDEPOCH set next transaction ID epoch\n" msgstr " -e XIDEPOCH задать Ñпоху в ID Ñледующей транзакции\n" -#: pg_resetwal.c:1169 +#: pg_resetwal.c:1238 #, c-format msgid " -f force update to be done\n" msgstr " -f принудительное выполнение операции\n" -#: pg_resetwal.c:1170 +#: pg_resetwal.c:1239 #, c-format msgid "" -" -l XLOGFILE force minimum WAL starting location for new transaction " +" -l WALFILE force minimum WAL starting location for new write-ahead " "log\n" msgstr "" -" -l XLOGFILE задать минимальное начальное положение WAL Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾\n" -" журнала транзакций\n" +" -l WALFILE задать минимальное начальное положение WAL Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾\n" +" журнала предзапиÑи\n" -#: pg_resetwal.c:1171 +#: pg_resetwal.c:1240 #, c-format msgid " -m MXID,MXID set next and oldest multitransaction ID\n" msgstr " -m MXID,MXID задать ID Ñледующей и Ñтарейшей мультитранзакции\n" -#: pg_resetwal.c:1172 +#: pg_resetwal.c:1241 #, c-format msgid "" " -n no update, just show what would be done (for testing)\n" @@ -605,32 +611,32 @@ msgstr "" "их\n" " (Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸)\n" -#: pg_resetwal.c:1173 +#: pg_resetwal.c:1242 #, c-format msgid " -o OID set next OID\n" msgstr " -o OID задать Ñледующий OID\n" -#: pg_resetwal.c:1174 +#: pg_resetwal.c:1243 #, c-format msgid " -O OFFSET set next multitransaction offset\n" msgstr " -O СМЕЩЕÐИЕ задать Ñмещение Ñледующей мультитранзакции\n" -#: pg_resetwal.c:1175 +#: pg_resetwal.c:1244 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: pg_resetwal.c:1176 +#: pg_resetwal.c:1245 #, c-format msgid " -x XID set next transaction ID\n" msgstr " -x XID задать ID Ñледующей транзакции\n" -#: pg_resetwal.c:1177 +#: pg_resetwal.c:1246 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: pg_resetwal.c:1178 +#: pg_resetwal.c:1247 #, c-format msgid "" "\n" @@ -639,6 +645,13 @@ msgstr "" "\n" "Об ошибках Ñообщайте по адреÑу .\n" +#~ msgid "" +#~ "%s: internal error -- sizeof(ControlFileData) is too large ... fix " +#~ "PG_CONTROL_SIZE\n" +#~ msgstr "" +#~ "%s: внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ° -- размер ControlFileData Ñлишком велик -- " +#~ "иÑправьте PG_CONTROL_SIZE\n" + #~ msgid "floating-point numbers" #~ msgstr "чиÑла Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой" diff --git a/src/bin/pg_resetwal/po/sv.po b/src/bin/pg_resetwal/po/sv.po index 04b653f3632..34b9f646a7c 100644 --- a/src/bin/pg_resetwal/po/sv.po +++ b/src/bin/pg_resetwal/po/sv.po @@ -1,146 +1,178 @@ # Swedish message translation file for resetxlog. -# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. # Peter Eisentraut , 2010. # Mats Erik Andersson , 2014. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-19 06:46+0000\n" -"PO-Revision-Date: 2017-07-20 21:32+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 07:17+0000\n" +"PO-Revision-Date: 2019-04-29 14:11+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/restricted_token.c:68 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: VARNING: \"Restricted Token\" stöds inte av plattformen.\n" +msgid "fatal: " +msgstr "fatalt: " -#: ../../common/restricted_token.c:77 +#: ../../../src/fe_utils/logging.c:189 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: kunde inte skapa processmärke (token): felkod %lu\n" +msgid "error: " +msgstr "fel: " -#: ../../common/restricted_token.c:90 +#: ../../../src/fe_utils/logging.c:196 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: kunde inte tilldela SID: felkod %lu\n" +msgid "warning: " +msgstr "varning: " + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "kan inte skapa token för begränsad Ã¥tkomst pÃ¥ denna plattorm" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "kunde inte öppna process-token: felkod %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "kunde inte allokera SID: felkod %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "kunde inte skapa token för begränsad Ã¥tkomst: felkod %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "kunde inte starta process för kommando \"%s\": felkod %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: kunde inte upprepa med restriktivt styrmärke (token): felkod %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kunde inte köra igen med token för begränsad Ã¥tkomst: felkod %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: kunde inte utvinna statuskod för underprocess: felkod %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "kunde inte hämta statuskod för underprocess: felkod %lu" #. translator: the second %s is a command line argument (-e, etc) -#: pg_resetwal.c:140 pg_resetwal.c:155 pg_resetwal.c:170 pg_resetwal.c:177 -#: pg_resetwal.c:201 pg_resetwal.c:216 pg_resetwal.c:224 pg_resetwal.c:250 -#: pg_resetwal.c:264 +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 #, c-format -msgid "%s: invalid argument for option %s\n" -msgstr "%s: ogiltigt argument för flaggan %s\n" +msgid "invalid argument for option %s" +msgstr "ogiltigt argument för flaggan %s" -#: pg_resetwal.c:141 pg_resetwal.c:156 pg_resetwal.c:171 pg_resetwal.c:178 -#: pg_resetwal.c:202 pg_resetwal.c:217 pg_resetwal.c:225 pg_resetwal.c:251 -#: pg_resetwal.c:265 pg_resetwal.c:272 pg_resetwal.c:285 pg_resetwal.c:293 +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_resetwal.c:146 +#: pg_resetwal.c:166 #, c-format -msgid "%s: transaction ID epoch (-e) must not be -1\n" -msgstr "%s: Epoch (-e) för transaktions-ID fÃ¥r inte vara -1.\n" +msgid "transaction ID epoch (-e) must not be -1" +msgstr "Epoch (-e) för transaktions-ID fÃ¥r inte vara -1." -#: pg_resetwal.c:161 +#: pg_resetwal.c:181 #, c-format -msgid "%s: transaction ID (-x) must not be 0\n" -msgstr "%s: Transaktions-ID (-x) fÃ¥r inte vara 0.\n" +msgid "transaction ID (-x) must not be 0" +msgstr "Transaktions-ID (-x) fÃ¥r inte vara 0." -#: pg_resetwal.c:185 pg_resetwal.c:192 +#: pg_resetwal.c:205 pg_resetwal.c:212 #, c-format -msgid "%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n" -msgstr "%s: transaktions-ID (-c) mÃ¥ste antingen vara 0 eller större än eller lika med 2\n" +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "transaktions-ID (-c) mÃ¥ste antingen vara 0 eller större än eller lika med 2" -#: pg_resetwal.c:207 +#: pg_resetwal.c:227 #, c-format -msgid "%s: OID (-o) must not be 0\n" -msgstr "%s: OID (-o) fÃ¥r inte vara 0.\n" +msgid "OID (-o) must not be 0" +msgstr "OID (-o) fÃ¥r inte vara 0." -#: pg_resetwal.c:230 +#: pg_resetwal.c:250 #, c-format -msgid "%s: multitransaction ID (-m) must not be 0\n" -msgstr "%s: Multitransaktions-ID (-m) fÃ¥r inte vara 0.\n" +msgid "multitransaction ID (-m) must not be 0" +msgstr "Multitransaktions-ID (-m) fÃ¥r inte vara 0." -#: pg_resetwal.c:240 +#: pg_resetwal.c:260 #, c-format -msgid "%s: oldest multitransaction ID (-m) must not be 0\n" -msgstr "%s: Äldsta multitransaktions-ID (-m) fÃ¥r inte vara 0.\n" +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "Äldsta multitransaktions-ID (-m) fÃ¥r inte vara 0." -#: pg_resetwal.c:256 +#: pg_resetwal.c:275 #, c-format -msgid "%s: multitransaction offset (-O) must not be -1\n" -msgstr "%s: Multitransaktionsoffset (-O) fÃ¥r inte vara -1.\n" +msgid "multitransaction offset (-O) must not be -1" +msgstr "Multitransaktionsoffset (-O) fÃ¥r inte vara -1." -#: pg_resetwal.c:283 +#: pg_resetwal.c:299 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "argument of --wal-segsize must be a number" +msgstr "argumentet till --wal-segsize mÃ¥ste vara ett tal" -#: pg_resetwal.c:292 +#: pg_resetwal.c:304 #, c-format -msgid "%s: no data directory specified\n" -msgstr "%s: ingen datakatalog angiven.\n" +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "argumentet till --wal-segsize mÃ¥ste vara en tvÃ¥potens mellan 1 och 1024" -#: pg_resetwal.c:306 +#: pg_resetwal.c:321 #, c-format -msgid "%s: cannot be executed by \"root\"\n" -msgstr "%s: fÃ¥r inte utföras av \"root\".\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: pg_resetwal.c:308 +#: pg_resetwal.c:330 #, c-format -msgid "You must run %s as the PostgreSQL superuser.\n" -msgstr "Du mÃ¥ste köra %s som PostgreSQL:s superanvändare.\n" +msgid "no data directory specified" +msgstr "ingen datakatalog angiven" -#: pg_resetwal.c:318 +#: pg_resetwal.c:344 #, c-format -msgid "%s: could not change directory to \"%s\": %s\n" -msgstr "%s: kunde inte gÃ¥ till katalog \"%s\": %s\n" +msgid "cannot be executed by \"root\"" +msgstr "kan inte köras av \"root\"" -#: pg_resetwal.c:334 pg_resetwal.c:481 pg_resetwal.c:544 +#: pg_resetwal.c:345 #, c-format -msgid "%s: could not open file \"%s\" for reading: %s\n" -msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" +msgid "You must run %s as the PostgreSQL superuser." +msgstr "Du mÃ¥ste köra %s som PostgreSQL:s superanvändare." -#: pg_resetwal.c:341 +#: pg_resetwal.c:356 #, c-format -msgid "" -"%s: lock file \"%s\" exists\n" -"Is a server running? If not, delete the lock file and try again.\n" -msgstr "" -"%s: En lÃ¥sfil \"%s\" finns pÃ¥ plats.\n" -"Kör servern redan? Om inte, radera lÃ¥sfilen och försök igen.\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: pg_resetwal.c:381 pg_resetwal.c:545 pg_resetwal.c:602 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "lÃ¥sfil med namn \"%s\" finns redan" -#: pg_resetwal.c:428 +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "Kör servern redan? Om inte, radera lÃ¥sfilen och försök igen." + +#: pg_resetwal.c:492 #, c-format msgid "" "\n" @@ -150,7 +182,7 @@ msgstr "" "Om dessa värden verkar godtagbara, använd dÃ¥ -f för att\n" "framtvinga Ã¥terställning.\n" -#: pg_resetwal.c:440 +#: pg_resetwal.c:504 #, c-format msgid "" "The database server was not shut down cleanly.\n" @@ -161,51 +193,59 @@ msgstr "" "write-ahead-loggen kan medföra att data förloras. Om du ändÃ¥\n" "vill fortsätta, använd -f för att framtvinga Ã¥terställning.\n" -#: pg_resetwal.c:454 +#: pg_resetwal.c:518 #, c-format msgid "Write-ahead log reset\n" msgstr "Ã…terställning av write-ahead-log\n" -#: pg_resetwal.c:491 +#: pg_resetwal.c:554 #, c-format -msgid "%s: unexpected empty file \"%s\"\n" -msgstr "%s: oväntad tom fil \"%s\"\n" +msgid "unexpected empty file \"%s\"" +msgstr "oväntad tom fil \"%s\"" -#: pg_resetwal.c:496 pg_resetwal.c:560 +#: pg_resetwal.c:556 pg_resetwal.c:618 #, c-format -msgid "%s: could not read file \"%s\": %s\n" -msgstr "%s: kunde inte läsa fil \"%s\": %s\n" +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" -#: pg_resetwal.c:513 +#: pg_resetwal.c:571 #, c-format -msgid "" -"%s: data directory is of wrong version\n" -"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n" -msgstr "" -"%s: datakatalogen har fel version\n" -"Filen \"%s\" innehÃ¥ller \"%s\", vilket inte är kompatibelt med detta programmets version \"%s\".\n" +msgid "data directory is of wrong version" +msgstr "datakatalogen har fel version" -#: pg_resetwal.c:547 +#: pg_resetwal.c:572 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "Filen \"%s\" innehÃ¥ller \"%s\", vilket inte är kompatibelt med detta programmets version \"%s\"." + +#: pg_resetwal.c:605 #, c-format msgid "" "If you are sure the data directory path is correct, execute\n" " touch %s\n" -"and try again.\n" +"and try again." msgstr "" "Om du är säker pÃ¥ att sökvägen till datakatalogen är riktig,\n" -"utför dÃ¥ \"touch %s\" och försök sedan igen.\n" +"utför dÃ¥ \"touch %s\" och försök sedan igen." + +#: pg_resetwal.c:636 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control existerar men har ogiltig CRC. Fortsätt med varsamhet." -#: pg_resetwal.c:583 +#: pg_resetwal.c:645 #, c-format -msgid "%s: pg_control exists but has invalid CRC; proceed with caution\n" -msgstr "%s: pg_control existerar men har ogiltig CRC. Fortsätt med varsamhet.\n" +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control anger ogiltig WAL-segmentstorlek (%d byte); fortsätt med varsamhet." +msgstr[1] "pg_control anger ogiltig WAL-segmentstorlek (%d byte); fortsätt med varsamhet." -#: pg_resetwal.c:592 +#: pg_resetwal.c:656 #, c-format -msgid "%s: pg_control exists but is broken or wrong version; ignoring it\n" -msgstr "%s: pg_control existerar men är trasig eller har fel version. Den ignoreras.\n" +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control existerar men är trasig eller har fel version. Den ignoreras." -#: pg_resetwal.c:690 +#: pg_resetwal.c:754 #, c-format msgid "" "Guessed pg_control values:\n" @@ -214,7 +254,7 @@ msgstr "" "Gissade värden för pg_control:\n" "\n" -#: pg_resetwal.c:692 +#: pg_resetwal.c:756 #, c-format msgid "" "Current pg_control values:\n" @@ -226,173 +266,173 @@ msgstr "" # November 26th, 2014: Insert six additional space characters # for best alignment with Swedish translation. # Translations should be checked against those of pg_controldata. -#: pg_resetwal.c:701 +#: pg_resetwal.c:765 #, c-format msgid "pg_control version number: %u\n" msgstr "Versionsnummer för pg_control: %u\n" -#: pg_resetwal.c:703 +#: pg_resetwal.c:767 #, c-format msgid "Catalog version number: %u\n" msgstr "Katalogversion: %u\n" -#: pg_resetwal.c:705 +#: pg_resetwal.c:769 #, c-format msgid "Database system identifier: %s\n" msgstr "Databasens systemidentifierare: %s\n" -#: pg_resetwal.c:707 +#: pg_resetwal.c:771 #, c-format msgid "Latest checkpoint's TimeLineID: %u\n" msgstr "TimeLineID vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:709 +#: pg_resetwal.c:773 #, c-format msgid "Latest checkpoint's full_page_writes: %s\n" msgstr "Senaste kontrollpunktens full_page_writes: %s\n" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "off" msgstr "av" -#: pg_resetwal.c:710 +#: pg_resetwal.c:774 msgid "on" msgstr "pÃ¥" -#: pg_resetwal.c:711 +#: pg_resetwal.c:775 #, c-format msgid "Latest checkpoint's NextXID: %u:%u\n" msgstr "NextXID vid senaste kontrollpunkt: %u:%u\n" -#: pg_resetwal.c:714 +#: pg_resetwal.c:778 #, c-format msgid "Latest checkpoint's NextOID: %u\n" msgstr "NextOID vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:716 +#: pg_resetwal.c:780 #, c-format msgid "Latest checkpoint's NextMultiXactId: %u\n" msgstr "NextMultiXactId vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:718 +#: pg_resetwal.c:782 #, c-format msgid "Latest checkpoint's NextMultiOffset: %u\n" msgstr "NextMultiOffset vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:720 +#: pg_resetwal.c:784 #, c-format msgid "Latest checkpoint's oldestXID: %u\n" msgstr "oldestXID vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:722 +#: pg_resetwal.c:786 #, c-format msgid "Latest checkpoint's oldestXID's DB: %u\n" msgstr "DB för oldestXID vid senaste kontrollpunkt: %u\n" # FIXME: too wide -#: pg_resetwal.c:724 +#: pg_resetwal.c:788 #, c-format msgid "Latest checkpoint's oldestActiveXID: %u\n" msgstr "oldestActiveXID vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:726 +#: pg_resetwal.c:790 #, c-format msgid "Latest checkpoint's oldestMultiXid: %u\n" msgstr "oldestMultiXid vid senaste kontrollpunkt: %u\n" -#: pg_resetwal.c:728 +#: pg_resetwal.c:792 #, c-format msgid "Latest checkpoint's oldestMulti's DB: %u\n" msgstr "DB för oldestMulti vid senaste kontrollpkt: %u\n" -#: pg_resetwal.c:730 +#: pg_resetwal.c:794 #, c-format msgid "Latest checkpoint's oldestCommitTsXid:%u\n" msgstr "oldestCommitTsXid vid senaste kontrollpunkt:%u\n" -#: pg_resetwal.c:732 +#: pg_resetwal.c:796 #, c-format msgid "Latest checkpoint's newestCommitTsXid:%u\n" msgstr "newestCommitTsXid vid senaste kontrollpunkt:%u\n" -#: pg_resetwal.c:734 +#: pg_resetwal.c:798 #, c-format msgid "Maximum data alignment: %u\n" msgstr "Maximal jämkning av data (alignment): %u\n" -#: pg_resetwal.c:737 +#: pg_resetwal.c:801 #, c-format msgid "Database block size: %u\n" msgstr "Databasens blockstorlek: %u\n" -#: pg_resetwal.c:739 +#: pg_resetwal.c:803 #, c-format msgid "Blocks per segment of large relation: %u\n" msgstr "Block per segment i en stor relation: %u\n" -#: pg_resetwal.c:741 +#: pg_resetwal.c:805 #, c-format msgid "WAL block size: %u\n" msgstr "Blockstorlek i transaktionsloggen: %u\n" -#: pg_resetwal.c:743 +#: pg_resetwal.c:807 pg_resetwal.c:895 #, c-format msgid "Bytes per WAL segment: %u\n" msgstr "Segmentstorlek i transaktionsloggen: %u\n" -#: pg_resetwal.c:745 +#: pg_resetwal.c:809 #, c-format msgid "Maximum length of identifiers: %u\n" msgstr "Maximal längd för identifierare: %u\n" -#: pg_resetwal.c:747 +#: pg_resetwal.c:811 #, c-format msgid "Maximum columns in an index: %u\n" msgstr "Maximalt antal kolonner i ett index: %u\n" -#: pg_resetwal.c:749 +#: pg_resetwal.c:813 #, c-format msgid "Maximum size of a TOAST chunk: %u\n" msgstr "Maximal storlek för en TOAST-enhet: %u\n" -#: pg_resetwal.c:751 +#: pg_resetwal.c:815 #, c-format msgid "Size of a large-object chunk: %u\n" msgstr "Storlek för large-object-enheter: %u\n" -#: pg_resetwal.c:754 +#: pg_resetwal.c:818 #, c-format msgid "Date/time type storage: %s\n" msgstr "Representation av dag och tid: %s\n" -#: pg_resetwal.c:755 +#: pg_resetwal.c:819 msgid "64-bit integers" msgstr "64-bitars heltal" -#: pg_resetwal.c:756 +#: pg_resetwal.c:820 #, c-format msgid "Float4 argument passing: %s\n" msgstr "Ã…tkomst till float4-argument: %s\n" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by reference" msgstr "referens" -#: pg_resetwal.c:757 pg_resetwal.c:759 +#: pg_resetwal.c:821 pg_resetwal.c:823 msgid "by value" msgstr "värdeÃ¥tkomst" -#: pg_resetwal.c:758 +#: pg_resetwal.c:822 #, c-format msgid "Float8 argument passing: %s\n" msgstr "Ã…tkomst till float8-argument: %s\n" -#: pg_resetwal.c:760 +#: pg_resetwal.c:824 #, c-format msgid "Data page checksum version: %u\n" msgstr "Checksummaversion för datasidor: %u\n" -#: pg_resetwal.c:774 +#: pg_resetwal.c:838 #, c-format msgid "" "\n" @@ -407,124 +447,111 @@ msgstr "" # November 26th, 2014: Insert additional spacing to fit # with the first translated text, which uses most characters. -#: pg_resetwal.c:777 +#: pg_resetwal.c:842 #, c-format msgid "First log segment after reset: %s\n" msgstr "Första loggsegment efter Ã¥terställning: %s\n" -#: pg_resetwal.c:781 +#: pg_resetwal.c:846 #, c-format msgid "NextMultiXactId: %u\n" msgstr "NextMultiXactId: %u\n" -#: pg_resetwal.c:783 +#: pg_resetwal.c:848 #, c-format msgid "OldestMultiXid: %u\n" msgstr "OldestMultiXid: %u\n" -#: pg_resetwal.c:785 +#: pg_resetwal.c:850 #, c-format msgid "OldestMulti's DB: %u\n" msgstr "DB för OldestMulti: %u\n" -#: pg_resetwal.c:791 +#: pg_resetwal.c:856 #, c-format msgid "NextMultiOffset: %u\n" msgstr "NextMultiOffset: %u\n" -#: pg_resetwal.c:797 +#: pg_resetwal.c:862 #, c-format msgid "NextOID: %u\n" msgstr "NextOID: %u\n" -#: pg_resetwal.c:803 +#: pg_resetwal.c:868 #, c-format msgid "NextXID: %u\n" msgstr "NextXID: %u\n" -#: pg_resetwal.c:805 +#: pg_resetwal.c:870 #, c-format msgid "OldestXID: %u\n" msgstr "OldestXID: %u\n" -#: pg_resetwal.c:807 +#: pg_resetwal.c:872 #, c-format msgid "OldestXID's DB: %u\n" msgstr "DB för OldestXID: %u\n" -#: pg_resetwal.c:813 +#: pg_resetwal.c:878 #, c-format msgid "NextXID epoch: %u\n" msgstr "Epoch för NextXID: %u\n" -#: pg_resetwal.c:819 +#: pg_resetwal.c:884 #, c-format msgid "oldestCommitTsXid: %u\n" msgstr "oldestCommitTsXid: %u\n" -#: pg_resetwal.c:824 +#: pg_resetwal.c:889 #, c-format msgid "newestCommitTsXid: %u\n" msgstr "newestCommitTsXid: %u\n" -#: pg_resetwal.c:890 -#, c-format -msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" -msgstr "%s: Internt fel: sizeof(ControlFileData) är alltför stor. Rätta till PG_CONTROL_SIZE.\n" - -#: pg_resetwal.c:905 -#, c-format -msgid "%s: could not create pg_control file: %s\n" -msgstr "%s: kunde inte skapa fil för pg_control: %s\n" - -#: pg_resetwal.c:916 +#: pg_resetwal.c:975 pg_resetwal.c:1043 pg_resetwal.c:1090 #, c-format -msgid "%s: could not write pg_control file: %s\n" -msgstr "%s: kunde inte skriva fil för pg_control: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" -#: pg_resetwal.c:923 pg_resetwal.c:1219 +#: pg_resetwal.c:1010 pg_resetwal.c:1063 pg_resetwal.c:1113 #, c-format -msgid "%s: fsync error: %s\n" -msgstr "%s: misslyckad fsync: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" -#: pg_resetwal.c:963 pg_resetwal.c:1034 pg_resetwal.c:1085 +#: pg_resetwal.c:1016 pg_resetwal.c:1069 pg_resetwal.c:1119 #, c-format -msgid "%s: could not open directory \"%s\": %s\n" -msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" -#: pg_resetwal.c:999 pg_resetwal.c:1056 pg_resetwal.c:1110 +#: pg_resetwal.c:1055 pg_resetwal.c:1105 #, c-format -msgid "%s: could not read directory \"%s\": %s\n" -msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" +msgid "could not delete file \"%s\": %m" +msgstr "kunde inte radera fil \"%s\": %m" -#: pg_resetwal.c:1006 pg_resetwal.c:1063 pg_resetwal.c:1117 -#, c-format -msgid "%s: could not close directory \"%s\": %s\n" -msgstr "%s: kunde inte stänga katalog \"%s\": %s\n" - -#: pg_resetwal.c:1047 pg_resetwal.c:1101 +#: pg_resetwal.c:1186 #, c-format -msgid "%s: could not delete file \"%s\": %s\n" -msgstr "%s: kunde inte radera fil \"%s\": %s\n" +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" -#: pg_resetwal.c:1186 +#: pg_resetwal.c:1196 pg_resetwal.c:1209 #, c-format -msgid "%s: could not open file \"%s\": %s\n" -msgstr "%s: kunde inte öppna fil \"%s\": %s\n" +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" -#: pg_resetwal.c:1197 pg_resetwal.c:1211 +#: pg_resetwal.c:1216 #, c-format -msgid "%s: could not write file \"%s\": %s\n" -msgstr "%s: kunde inte skriva fil \"%s\": %s\n" +msgid "fsync error: %m" +msgstr "misslyckad fsync: %m" -#: pg_resetwal.c:1230 +#: pg_resetwal.c:1227 #, c-format msgid "" "%s resets the PostgreSQL write-ahead log.\n" "\n" -msgstr "%s Ã¥terställer write-ahead-log för PostgreSQL.\n\n" +msgstr "" +"%s Ã¥terställer write-ahead-log för PostgreSQL.\n" +"\n" -#: pg_resetwal.c:1231 +#: pg_resetwal.c:1228 #, c-format msgid "" "Usage:\n" @@ -535,88 +562,200 @@ msgstr "" " %s [FLAGGA]... DATAKATALOG\n" "\n" -#: pg_resetwal.c:1232 +#: pg_resetwal.c:1229 #, c-format msgid "Options:\n" msgstr "Flaggor:\n" +#: pg_resetwal.c:1230 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" sätt äldsta och nyaste transaktionerna som\n" +" kan ha commit-tidstämpel (noll betyder\n" +" ingen ändring)\n" + #: pg_resetwal.c:1233 #, c-format -msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" -msgstr " -c XID,XID sätt äldsta och nyaste transaktioner med commit-tidstämpel\n" +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR datakatalog\n" #: pg_resetwal.c:1234 #, c-format -msgid " (zero in either value means no change)\n" -msgstr " (noll i nÃ¥got värde innebär ingen ändring)\n" +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH sätter epoch för nästa transaktions-ID\n" #: pg_resetwal.c:1235 #, c-format -msgid " [-D] DATADIR data directory\n" -msgstr " [-D] DATADIR datakatalog\n" +msgid " -f, --force force update to be done\n" +msgstr " -f, --force framtvinga uppdatering\n" #: pg_resetwal.c:1236 #, c-format -msgid " -e XIDEPOCH set next transaction ID epoch\n" -msgstr " -e XIDEPOCH sätter epoch för nästa transaktions-ID\n" +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALFIL sätt minsta startposition för ny WAL\n" #: pg_resetwal.c:1237 #, c-format -msgid " -f force update to be done\n" -msgstr " -f framtvinga Ã¥terställning\n" +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID sätt nästa och äldsta multitransaktions-ID\n" #: pg_resetwal.c:1238 #, c-format -msgid " -l WALFILE force minimum WAL starting location for new write-ahead log\n" -msgstr " -l WALFIL tvinga minsta WAL-startposition för ny write-ahead-log\n" +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run ingen updatering; visa bara planerade Ã¥tgärder\n" #: pg_resetwal.c:1239 #, c-format -msgid " -m MXID,MXID set next and oldest multitransaction ID\n" -msgstr " -m MXID,MXID sätt nästa och äldsta multitransaktions-ID\n" +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID sätt nästa OID\n" #: pg_resetwal.c:1240 #, c-format -msgid " -n no update, just show what would be done (for testing)\n" -msgstr " -n ingen updatering; visa planerade Ã¥tgärder (för testning)\n" +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET sätt nästa multitransaktionsoffset\n" #: pg_resetwal.c:1241 #, c-format -msgid " -o OID set next OID\n" -msgstr " -o OID sätt nästa OID\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version skriv ut versioninformation och avsluta sedan\n" #: pg_resetwal.c:1242 #, c-format -msgid " -O OFFSET set next multitransaction offset\n" -msgstr " -O OFFSET sätt nästa multitransaktionsoffset\n" +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID sätt nästa transaktions-ID\n" #: pg_resetwal.c:1243 #, c-format -msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version visa versionsinformation, avsluta sedan\n" +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=STORLEK storlek pÃ¥ WAL-segment i megabyte\n" #: pg_resetwal.c:1244 #, c-format -msgid " -x XID set next transaction ID\n" -msgstr " -x XID sätt nästa transaktions-ID\n" +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denna hjälp och avsluta sedan\n" #: pg_resetwal.c:1245 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help visa denna hjälp, avsluta sedan\n" - -#: pg_resetwal.c:1246 -#, c-format msgid "" "\n" -"Report bugs to .\n" -msgstr "\nRapportera fel till .\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Rapportera fel till .\n" -#~ msgid "floating-point numbers" -#~ msgstr "flyttal" +#~ msgid "%s: unable to read permissions from \"%s\"\n" +#~ msgstr "%s: kunde inte läsa rättigheter frÃ¥n \"%s\"\n" + +#~ msgid "Transaction log reset\n" +#~ msgstr "Ã…terställning av transaktionslogg.\n" #~ msgid "Latest checkpoint's NextXID: %u/%u\n" #~ msgstr "NextXID vid senaste kontrollpunkt: %u/%u\n" -#~ msgid "Transaction log reset\n" -#~ msgstr "Ã…terställning av transaktionslogg.\n" +#~ msgid "floating-point numbers" +#~ msgstr "flyttal" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help visa denna hjälp, avsluta sedan\n" + +#~ msgid " -x XID set next transaction ID\n" +#~ msgstr " -x XID sätt nästa transaktions-ID\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#~ msgid " [-D] DATADIR data directory\n" +#~ msgstr " [-D] DATADIR datakatalog\n" + +#~ msgid " (zero in either value means no change)\n" +#~ msgstr " (noll i nÃ¥got värde innebär ingen ändring)\n" + +#~ msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" +#~ msgstr " -c XID,XID sätt äldsta och nyaste transaktioner med commit-tidstämpel\n" + +#~ msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" +#~ msgstr "%s: Internt fel: sizeof(ControlFileData) är alltför stor. Rätta till PG_CONTROL_SIZE.\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapportera fel till .\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: kunde inte skriva fil \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\": %s\n" + +#~ msgid "%s: could not delete file \"%s\": %s\n" +#~ msgstr "%s: kunde inte radera fil \"%s\": %s\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte stänga katalog \"%s\": %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "%s: could not write pg_control file: %s\n" +#~ msgstr "%s: kunde inte skriva fil för pg_control: %s\n" + +#~ msgid "%s: could not create pg_control file: %s\n" +#~ msgstr "%s: kunde inte skapa fil för pg_control: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa fil \"%s\": %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: kunde inte öppna fil \"%s\" för läsning: %s\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %s\n" + +#~ msgid "%s: could not change directory to \"%s\": %s\n" +#~ msgstr "%s: kunde inte gÃ¥ till katalog \"%s\": %s\n" + +#~ msgid "%s: cannot be executed by \"root\"\n" +#~ msgstr "%s: fÃ¥r inte utföras av \"root\".\n" + +#~ msgid "%s: no data directory specified\n" +#~ msgstr "%s: ingen datakatalog angiven.\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" + +#~ msgid "%s: argument of --wal-segsize must be a power of 2 between 1 and 1024\n" +#~ msgstr "%s: argumentet till --wal-segsize mÃ¥ste vara en tvÃ¥potens mellan 1 och 1024\n" + +#~ msgid "%s: argument of --wal-segsize must be a number\n" +#~ msgstr "%s: argumentet till --wal-segsize mÃ¥ste vara ett tal\n" + +#~ msgid "%s: could not get exit code from subprocess: error code %lu\n" +#~ msgstr "%s: kunde inte utvinna statuskod för underprocess: felkod %lu\n" + +#~ msgid "%s: could not re-execute with restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte upprepa med restriktivt styrmärke (token): felkod %lu\n" + +#~ msgid "%s: could not start process for command \"%s\": error code %lu\n" +#~ msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" + +#~ msgid "%s: could not create restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" + +#~ msgid "%s: could not allocate SIDs: error code %lu\n" +#~ msgstr "%s: kunde inte tilldela SID: felkod %lu\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: kunde inte öppna process-token: felkod %lu\n" + +#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +#~ msgstr "%s: VARNING: \"Restricted Token\" stöds inte av plattformen.\n" diff --git a/src/bin/pg_resetwal/po/tr.po b/src/bin/pg_resetwal/po/tr.po new file mode 100644 index 00000000000..48b1497c553 --- /dev/null +++ b/src/bin/pg_resetwal/po/tr.po @@ -0,0 +1,751 @@ +# translation of pg_resetxlog-tr.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2006, 2007. +# Nicolai TUFAR , 2004, 2005, 2006, 2007. +# Abdullah GÜLNER , 2017, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_resetxlog-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:47+0000\n" +"PO-Revision-Date: 2019-06-12 16:23+0300\n" +"Last-Translator: Abdullah GÜLNER\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: /home/ntufar/pg/pgsql/src/bin/pg_resetxlog\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "bu platformda restricted token oluÅŸturulamıyor" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "process token açma baÅŸarısız: hata kodu %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDler ayrılamıyor (allocate): Hata kodu %lu" + +#: ../../common/restricted_token.c:110 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "restricted token oluÅŸturulamıyor: hata kodu %lu" + +#: ../../common/restricted_token.c:131 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" komutu için iÅŸlem (process) baÅŸlatılamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:169 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "restricted token ile tekrar çalıştırılamadı (re-execute): hata kodu %lu" + +#: ../../common/restricted_token.c:185 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "alt-iÅŸlemden çıkış kodu alınamadı: hata kodu %lu" + +#. translator: the second %s is a command line argument (-e, etc) +#: pg_resetwal.c:160 pg_resetwal.c:175 pg_resetwal.c:190 pg_resetwal.c:197 +#: pg_resetwal.c:221 pg_resetwal.c:236 pg_resetwal.c:244 pg_resetwal.c:269 +#: pg_resetwal.c:283 +#, c-format +msgid "invalid argument for option %s" +msgstr "%s seçeneÄŸi için geçersiz argüman" + +#: pg_resetwal.c:161 pg_resetwal.c:176 pg_resetwal.c:191 pg_resetwal.c:198 +#: pg_resetwal.c:222 pg_resetwal.c:237 pg_resetwal.c:245 pg_resetwal.c:270 +#: pg_resetwal.c:284 pg_resetwal.c:310 pg_resetwal.c:323 pg_resetwal.c:331 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazabilirsiniz.\n" + +#: pg_resetwal.c:166 +#, c-format +msgid "transaction ID epoch (-e) must not be -1" +msgstr "transaction ID epoch (-e) -1 olamaz" + +#: pg_resetwal.c:181 +#, c-format +msgid "transaction ID (-x) must not be 0" +msgstr "transaction ID (-x) 0 olamaz" + +#: pg_resetwal.c:205 pg_resetwal.c:212 +#, c-format +msgid "transaction ID (-c) must be either 0 or greater than or equal to 2" +msgstr "iÅŸlem (transaction) ID (-c) ya 0 ya da 2 den büyük veya eÅŸit olmalı" + +#: pg_resetwal.c:227 +#, c-format +msgid "OID (-o) must not be 0" +msgstr "OID (-o) 0 olamaz" + +#: pg_resetwal.c:250 +#, c-format +msgid "multitransaction ID (-m) must not be 0" +msgstr "multitransaction ID (-m) 0 olamaz" + +#: pg_resetwal.c:260 +#, c-format +msgid "oldest multitransaction ID (-m) must not be 0" +msgstr "en eski multitransaction ID (-m) 0 olamaz" + +#: pg_resetwal.c:275 +#, c-format +msgid "multitransaction offset (-O) must not be -1" +msgstr "multitransaction offset (-O) deÄŸeri -1 olamaz" + +#: pg_resetwal.c:299 +#, c-format +msgid "argument of --wal-segsize must be a number" +msgstr "--wal-segsize argümanı bir sayı olmalıdır" + +#: pg_resetwal.c:304 +#, c-format +msgid "argument of --wal-segsize must be a power of 2 between 1 and 1024" +msgstr "--wal-segsize argümanı 2'nin 1 ve 1024 arasındaki bir üssü olmalıdır" + +#: pg_resetwal.c:321 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı argümanı var (ilki \"%s\")" + +#: pg_resetwal.c:330 +#, c-format +msgid "no data directory specified" +msgstr "veri dizini belirtilmedi" + +#: pg_resetwal.c:344 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\" tarafından çalıştırılamaz" + +#: pg_resetwal.c:345 +#, c-format +msgid "You must run %s as the PostgreSQL superuser." +msgstr "%s komutunu PostgreSQL superuser olarak çalıştırmalısınız." + +#: pg_resetwal.c:356 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" dizininin eriÅŸim haklarını okunamıyor: %m" + +#: pg_resetwal.c:365 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi: %m" + +#: pg_resetwal.c:381 pg_resetwal.c:545 pg_resetwal.c:602 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" dosyası, okunmak için açılamadı: %m" + +#: pg_resetwal.c:388 +#, c-format +msgid "lock file \"%s\" exists" +msgstr "\"%s\" lock dosyası mevcuttur" + +#: pg_resetwal.c:389 +#, c-format +msgid "Is a server running? If not, delete the lock file and try again." +msgstr "Bir sunucu çalışıyor mu? EÄŸer çalışmıyorsa, lock dosyasını silin ve yeniden deneyin." + +#: pg_resetwal.c:492 +#, c-format +msgid "" +"\n" +"If these values seem acceptable, use -f to force reset.\n" +msgstr "" +"\n" +"Bu deÄŸerler uygun görünüyorsa, reset zorlamak için -f kullanın.\n" + +#: pg_resetwal.c:504 +#, c-format +msgid "" +"The database server was not shut down cleanly.\n" +"Resetting the write-ahead log might cause data to be lost.\n" +"If you want to proceed anyway, use -f to force reset.\n" +msgstr "" +"Veritabanı sunucusu düzgün kapatılmadı.\n" +"İşlem kayıt (write-ahead log) dosyasını sıfırlamak veri kaybına neden olabilir.\n" +"Yine de devam etmek istiyorsanız, sıfırlama iÅŸlemini zorlamak için -f parametresini kullanınız.\n" + +#: pg_resetwal.c:518 +#, c-format +msgid "Write-ahead log reset\n" +msgstr "Write-ahead log sıfırlama\n" + +#: pg_resetwal.c:554 +#, c-format +msgid "unexpected empty file \"%s\"" +msgstr "beklenmeyen boÅŸ dosya \"%s\"" + +#: pg_resetwal.c:556 pg_resetwal.c:618 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" dosyası okuma hatası: %m" + +#: pg_resetwal.c:571 +#, c-format +msgid "data directory is of wrong version" +msgstr "veri dizininin sürümü yanlış" + +#: pg_resetwal.c:572 +#, c-format +msgid "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\"." +msgstr "\"%s\" dosyası \"%s\" içermekte ki bu programın \"%s\" sürümüyle uyumlu deÄŸil." + +#: pg_resetwal.c:605 +#, c-format +msgid "" +"If you are sure the data directory path is correct, execute\n" +" touch %s\n" +"and try again." +msgstr "" +"EÄŸer veri dizininin doÄŸru olduÄŸuna eminseniz\n" +" touch %s\n" +"komutunu çalıştırın ve tekrar deneyin." + +#: pg_resetwal.c:636 +#, c-format +msgid "pg_control exists but has invalid CRC; proceed with caution" +msgstr "pg_control mevcut ancak geçersiz CRC'ye sahip, dikkatle ilerleyin" + +#: pg_resetwal.c:645 +#, c-format +msgid "pg_control specifies invalid WAL segment size (%d byte); proceed with caution" +msgid_plural "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution" +msgstr[0] "pg_control geçersiz WAL segment boyutu belirtmekte (%d bayt); dikkatle ilerleyin" +msgstr[1] "pg_control geçersiz WAL segment boyutu belirtmekte (%d bayt); dikkatle ilerleyin" + +#: pg_resetwal.c:656 +#, c-format +msgid "pg_control exists but is broken or wrong version; ignoring it" +msgstr "pg_control mevcut ama ya bozuk ya da yanlış sürümde; gözardı ediliyor" + +#: pg_resetwal.c:754 +#, c-format +msgid "" +"Guessed pg_control values:\n" +"\n" +msgstr "" +"Tahmin edilen pg_control deÄŸerleri:\n" +"\n" + +#: pg_resetwal.c:756 +#, c-format +msgid "" +"Current pg_control values:\n" +"\n" +msgstr "" +"Geçerli pg_control deÄŸerleri:\n" +"\n" + +#: pg_resetwal.c:765 +#, c-format +msgid "pg_control version number: %u\n" +msgstr "pg_control sürüm numarası: %u\n" + +#: pg_resetwal.c:767 +#, c-format +msgid "Catalog version number: %u\n" +msgstr "Katalog sürüm numarası: %u\n" + +#: pg_resetwal.c:769 +#, c-format +msgid "Database system identifier: %s\n" +msgstr "Veritabanı sistem tanımlayıcısı: %s\n" + +#: pg_resetwal.c:771 +#, c-format +msgid "Latest checkpoint's TimeLineID: %u\n" +msgstr "Son checkpoint''in TimeLineID deÄŸeri: %u\n" + +#: pg_resetwal.c:773 +#, c-format +msgid "Latest checkpoint's full_page_writes: %s\n" +msgstr "Son checkpoint'in full_page_writes deÄŸeri: %s\n" + +#: pg_resetwal.c:774 +msgid "off" +msgstr "kapalı" + +#: pg_resetwal.c:774 +msgid "on" +msgstr "açık" + +#: pg_resetwal.c:775 +#, c-format +msgid "Latest checkpoint's NextXID: %u:%u\n" +msgstr "Son checkpoint'in NextXID deÄŸeri: %u:%u\n" + +#: pg_resetwal.c:778 +#, c-format +msgid "Latest checkpoint's NextOID: %u\n" +msgstr "Son checkpoint''in NextOID deÄŸeri: %u\n" + +#: pg_resetwal.c:780 +#, c-format +msgid "Latest checkpoint's NextMultiXactId: %u\n" +msgstr "Son checkpoint''in NextMultiXactId deÄŸeri: %u\n" + +#: pg_resetwal.c:782 +#, c-format +msgid "Latest checkpoint's NextMultiOffset: %u\n" +msgstr "Son checkpoint''in NextMultiOffset deÄŸeri: %u\n" + +#: pg_resetwal.c:784 +#, c-format +msgid "Latest checkpoint's oldestXID: %u\n" +msgstr "Son checkpoint'in oldestXID deÄŸeri: %u\n" + +#: pg_resetwal.c:786 +#, c-format +msgid "Latest checkpoint's oldestXID's DB: %u\n" +msgstr "Son checkpoint'in oldestXID deÄŸeri'nin DB'si: %u\n" + +#: pg_resetwal.c:788 +#, c-format +msgid "Latest checkpoint's oldestActiveXID: %u\n" +msgstr "Son checkpoint'in oldestActiveXID deÄŸeri: %u\n" + +#: pg_resetwal.c:790 +#, c-format +msgid "Latest checkpoint's oldestMultiXid: %u\n" +msgstr "Son checkpoint'in oldestMultiXid deÄŸeri: %u\n" + +#: pg_resetwal.c:792 +#, c-format +msgid "Latest checkpoint's oldestMulti's DB: %u\n" +msgstr "Son checkpoint'in oldestMulti'sinin VT'si: %u\n" + +#: pg_resetwal.c:794 +#, c-format +msgid "Latest checkpoint's oldestCommitTsXid:%u\n" +msgstr "Son checkpoint'in oldestCommitTsXid deÄŸeri: %u\n" + +#: pg_resetwal.c:796 +#, c-format +msgid "Latest checkpoint's newestCommitTsXid:%u\n" +msgstr "Son checkpoint''in newestCommitTsXid deÄŸeri: %u\n" + +#: pg_resetwal.c:798 +#, c-format +msgid "Maximum data alignment: %u\n" +msgstr "Azami veri hizalama: %u\n" + +#: pg_resetwal.c:801 +#, c-format +msgid "Database block size: %u\n" +msgstr "Veritabanı blok büyüklüğü: %u\n" + +#: pg_resetwal.c:803 +#, c-format +msgid "Blocks per segment of large relation: %u\n" +msgstr "büyük nesnenin bölümü başına blok sayısı: %u\n" + +#: pg_resetwal.c:805 +#, c-format +msgid "WAL block size: %u\n" +msgstr "WAL blok büyüklüğü: %u\n" + +#: pg_resetwal.c:807 pg_resetwal.c:895 +#, c-format +msgid "Bytes per WAL segment: %u\n" +msgstr "WAL segment başına WAL bayt sayısı: %u\n" + +#: pg_resetwal.c:809 +#, c-format +msgid "Maximum length of identifiers: %u\n" +msgstr "Tanımlayıcıların en yüksek sayısı: %u\n" + +#: pg_resetwal.c:811 +#, c-format +msgid "Maximum columns in an index: %u\n" +msgstr "Bir indexteki en fazla kolon sayısı: %u\n" + +#: pg_resetwal.c:813 +#, c-format +msgid "Maximum size of a TOAST chunk: %u\n" +msgstr "TOAST parçasının en büyük uzunluÄŸu: %u\n" + +#: pg_resetwal.c:815 +#, c-format +msgid "Size of a large-object chunk: %u\n" +msgstr "Büyük-nesne parçasının boyutu: %u\n" + +#: pg_resetwal.c:818 +#, c-format +msgid "Date/time type storage: %s\n" +msgstr "Tarih/zaman tipi saklanması: %s\n" + +#: pg_resetwal.c:819 +msgid "64-bit integers" +msgstr "64-bit tamsayılar" + +#: pg_resetwal.c:820 +#, c-format +msgid "Float4 argument passing: %s\n" +msgstr "Float4 argument passing: %s\n" + +#: pg_resetwal.c:821 pg_resetwal.c:823 +msgid "by reference" +msgstr "referans ile" + +#: pg_resetwal.c:821 pg_resetwal.c:823 +msgid "by value" +msgstr "deÄŸer ils" + +#: pg_resetwal.c:822 +#, c-format +msgid "Float8 argument passing: %s\n" +msgstr "Float8 argument passing: %s\n" + +#: pg_resetwal.c:824 +#, c-format +msgid "Data page checksum version: %u\n" +msgstr "Veri sayfası saÄŸlama (checksum) sürümü: %u\n" + +#: pg_resetwal.c:838 +#, c-format +msgid "" +"\n" +"\n" +"Values to be changed:\n" +"\n" +msgstr "" +"\n" +"\n" +"DeÄŸiÅŸtirilecek deÄŸerler:\n" +"\n" + +#: pg_resetwal.c:842 +#, c-format +msgid "First log segment after reset: %s\n" +msgstr "Sıfırlamadan sonraki ilk kayıt segmenti: %s\n" + +#: pg_resetwal.c:846 +#, c-format +msgid "NextMultiXactId: %u\n" +msgstr "NextMultiXactId deÄŸeri: %u\n" + +#: pg_resetwal.c:848 +#, c-format +msgid "OldestMultiXid: %u\n" +msgstr "OldestMultiXid deÄŸeri: %u\n" + +#: pg_resetwal.c:850 +#, c-format +msgid "OldestMulti's DB: %u\n" +msgstr "OldestMulti'nin VT'si: %u\n" + +#: pg_resetwal.c:856 +#, c-format +msgid "NextMultiOffset: %u\n" +msgstr "NextMultiOffset deÄŸeri: %u\n" + +#: pg_resetwal.c:862 +#, c-format +msgid "NextOID: %u\n" +msgstr "NextOID deÄŸeri: %u\n" + +#: pg_resetwal.c:868 +#, c-format +msgid "NextXID: %u\n" +msgstr "NextXID deÄŸeri: %u\n" + +#: pg_resetwal.c:870 +#, c-format +msgid "OldestXID: %u\n" +msgstr "OldestXID deÄŸeri: %u\n" + +#: pg_resetwal.c:872 +#, c-format +msgid "OldestXID's DB: %u\n" +msgstr "OldestXID'nin VT'si: %u\n" + +#: pg_resetwal.c:878 +#, c-format +msgid "NextXID epoch: %u\n" +msgstr "NextXID devri: %u\n" + +#: pg_resetwal.c:884 +#, c-format +msgid "oldestCommitTsXid: %u\n" +msgstr "oldestCommitTsXid deÄŸeri: %u\n" + +#: pg_resetwal.c:889 +#, c-format +msgid "newestCommitTsXid: %u\n" +msgstr "newestCommitTsXid deÄŸeri: %u\n" + +#: pg_resetwal.c:975 pg_resetwal.c:1043 pg_resetwal.c:1090 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" dizini açılamıyor: %m" + +#: pg_resetwal.c:1010 pg_resetwal.c:1063 pg_resetwal.c:1113 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: pg_resetwal.c:1016 pg_resetwal.c:1069 pg_resetwal.c:1119 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" dizini kapatılamadı: %m" + +#: pg_resetwal.c:1055 pg_resetwal.c:1105 +#, c-format +msgid "could not delete file \"%s\": %m" +msgstr "\"%s\" dosyası silinemedi: %m" + +#: pg_resetwal.c:1186 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: pg_resetwal.c:1196 pg_resetwal.c:1209 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" dosyasına yazma hatası: %m" + +#: pg_resetwal.c:1216 +#, c-format +msgid "fsync error: %m" +msgstr "fsync hatası: %m" + +#: pg_resetwal.c:1227 +#, c-format +msgid "" +"%s resets the PostgreSQL write-ahead log.\n" +"\n" +msgstr "" +"%s PostgreSQL iÅŸlem kayıt (write-ahead log) dosyasını sıfırlar.\n" +"\n" + +#: pg_resetwal.c:1228 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]... DATADIR\n" +"\n" +msgstr "" +"Kullanımı:\n" +" %s [SEÇENEK]... VERİ_DİZİNİ\n" +"\n" + +#: pg_resetwal.c:1229 +#, c-format +msgid "Options:\n" +msgstr "Seçenekler:\n" + +#: pg_resetwal.c:1230 +#, c-format +msgid "" +" -c, --commit-timestamp-ids=XID,XID\n" +" set oldest and newest transactions bearing\n" +" commit timestamp (zero means no change)\n" +msgstr "" +" -c, --commit-timestamp-ids=XID,XID\n" +" commit timestamp taşıyan en eski ve en yeni\n" +" iÅŸlemleri (transaction) ayarla (sıfır, deÄŸiÅŸiklik yok demek)\n" + +#: pg_resetwal.c:1233 +#, c-format +msgid " [-D, --pgdata=]DATADIR data directory\n" +msgstr " [-D, --pgdata=]DATADIR veri dizini\n" + +#: pg_resetwal.c:1234 +#, c-format +msgid " -e, --epoch=XIDEPOCH set next transaction ID epoch\n" +msgstr " -e, --epoch=XIDEPOCH sonraki transaction ID epoch ayarla\n" + +#: pg_resetwal.c:1235 +#, c-format +msgid " -f, --force force update to be done\n" +msgstr " -f, --force güncellemenin yapılmasını zorla\n" + +#: pg_resetwal.c:1236 +#, c-format +msgid " -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n" +msgstr " -l, --next-wal-file=WALFILE yeni WAL için en düşük baÅŸlama yerini ayarla\n" + +#: pg_resetwal.c:1237 +#, c-format +msgid " -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n" +msgstr " -m, --multixact-ids=MXID,MXID sonraki ve en eski multitransaction ID'sini ayarla\n" + +#: pg_resetwal.c:1238 +#, c-format +msgid " -n, --dry-run no update, just show what would be done\n" +msgstr " -n, --dry-run güncelleme yok, sadece ne yapılacağını göster\n" + +#: pg_resetwal.c:1239 +#, c-format +msgid " -o, --next-oid=OID set next OID\n" +msgstr " -o, --next-oid=OID sonraki OID'i ayarla\n" + +#: pg_resetwal.c:1240 +#, c-format +msgid " -O, --multixact-offset=OFFSET set next multitransaction offset\n" +msgstr " -O, --multixact-offset=OFFSET sonraki multitransaction offseti ayarla\n" + +#: pg_resetwal.c:1241 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_resetwal.c:1242 +#, c-format +msgid " -x, --next-transaction-id=XID set next transaction ID\n" +msgstr " -x, --next-transaction-id=XID sonraki iÅŸlem (transaction) ID ayarla\n" + +#: pg_resetwal.c:1243 +#, c-format +msgid " --wal-segsize=SIZE size of WAL segments, in megabytes\n" +msgstr " --wal-segsize=SIZE WAL segmentlerinin boyutu, megabayt olarak\n" + +#: pg_resetwal.c:1244 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_resetwal.c:1245 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildiriniz.\n" + +#~ msgid " -c XID,XID set oldest and newest transactions bearing commit timestamp\n" +#~ msgstr " -c XID,XID commit timestamp taşıyan en eski ve enyeni iÅŸlemleri (transaction) ayarla\n" + +#~ msgid " (zero in either value means no change)\n" +#~ msgstr "" +#~ " (her iki deÄŸerde sıfır deÄŸiÅŸiklik olmadığı anlamına gelir)\n" +#~ "\n" + +#~ msgid " [-D] DATADIR data directory\n" +#~ msgstr " [-D] DATADIR veri dizini\n" + +#~ msgid " -V, --version output version information, then exit\n" +#~ msgstr " -V,--version sürüm numarasını yaz ve çık\n" + +#~ msgid " -x XID set next transaction ID\n" +#~ msgstr " -x XID sıradaki transaction ID'sini ayarla\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help bu yardımı göster ve çık\n" + +#~ msgid "Maximum length of locale name: %u\n" +#~ msgstr "Yerel adının en büyük uzunluÄŸu: %u\n" + +#~ msgid "%s: invalid LC_CTYPE setting\n" +#~ msgstr "%s: geçersiz LC_CTYPE ayarı\n" + +#~ msgid "%s: invalid LC_COLLATE setting\n" +#~ msgstr "%s: Geçersiz LC_COLLATE ayarı\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini göster ve çık\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve çık\n" + +#~ msgid "%s: could not read from directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini okunamadı: %s\n" + +#~ msgid "%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n" +#~ msgstr "%s: iç hata -- sizeof(ControlFileData) çok büyük ... PG_CONTROL_SIZE deÄŸerini düzeltiniz\n" + +#~ msgid "floating-point numbers" +#~ msgstr "kayan nokta sayılar" + +#~ msgid "First log file ID after reset: %u\n" +#~ msgstr "Sıfırlamadan sonraki ilk kayıt dosyası ID'si: %u\n" + +#~ msgid "Transaction log reset\n" +#~ msgstr "Transaction kayıt dosyası sıfırlandı\n" + +#~ msgid "%s: invalid argument for option -l\n" +#~ msgstr "%s: -l seçeneÄŸi için geçersiz argüman\n" + +#~ msgid "%s: invalid argument for option -O\n" +#~ msgstr "%s: -O seçeneÄŸi için geçersiz argüman\n" + +#~ msgid "%s: invalid argument for option -m\n" +#~ msgstr "%s: -m seçeneÄŸi için geçersiz argüman\n" + +#~ msgid "%s: invalid argument for option -o\n" +#~ msgstr "%s: -o seçeneÄŸi için geçersiz argüman\n" + +#~ msgid "%s: invalid argument for option -x\n" +#~ msgstr "%s: -x seçeneÄŸi için geçersiz argüman\n" + +#~ msgid "%s: could not write file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyasına yazılamadı: %s\n" + +#~ msgid "%s: could not open file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası açılamadı: %s\n" + +#~ msgid "%s: could not delete file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası silinemedi: %s\n" + +#~ msgid "%s: could not close directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini kapatılamadı: %s\n" + +#~ msgid "%s: could not read directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini okunamadı: %s\n" + +#~ msgid "%s: could not open directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizini açılamadı: %s\n" + +#~ msgid "%s: could not write pg_control file: %s\n" +#~ msgstr "%s: pg_control dosyasına yazılamadı: %s\n" + +#~ msgid "%s: could not create pg_control file: %s\n" +#~ msgstr "%s: pg_control dosyası yaratılamadı: %s\n" + +#~ msgid "%s: could not read file \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dosyası okunamadı: %s\n" + +#~ msgid "%s: could not open file \"%s\" for reading: %s\n" +#~ msgstr "%s: \"%s\" dosyası okunmak için açılamadı: %s\n" + +#~ msgid "%s: could not change directory to \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizine geçilemedi: %s\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizininin eriÅŸim hakları okunamadı : %s\n" + +#~ msgid "%s: cannot be executed by \"root\"\n" +#~ msgstr "%s: \"root\" tarafından çalıştırılamaz\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: process token açma baÅŸarısız: hata kodu %lu\n" diff --git a/src/bin/pg_resetwal/t/001_basic.pl b/src/bin/pg_resetwal/t/001_basic.pl index 0d6ab20073a..ca93ddbda05 100644 --- a/src/bin/pg_resetwal/t/001_basic.pl +++ b/src/bin/pg_resetwal/t/001_basic.pl @@ -13,14 +13,14 @@ $node->init; command_like([ 'pg_resetwal', '-n', $node->data_dir ], - qr/checkpoint/, - 'pg_resetwal -n produces output'); + qr/checkpoint/, 'pg_resetwal -n produces output'); # Permissions on PGDATA should be default SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive($node->data_dir, 0700, 0600), 'check PGDATA permissions'); diff --git a/src/bin/pg_resetwal/t/002_corrupted.pl b/src/bin/pg_resetwal/t/002_corrupted.pl index 9df5574c8bd..f9940d7fc5d 100644 --- a/src/bin/pg_resetwal/t/002_corrupted.pl +++ b/src/bin/pg_resetwal/t/002_corrupted.pl @@ -11,7 +11,7 @@ $node->init; my $pg_control = $node->data_dir . '/global/pg_control'; -my $size = (stat($pg_control))[7]; +my $size = (stat($pg_control))[7]; # Read out the head of the file to get PG_CONTROL_VERSION in # particular. @@ -27,11 +27,14 @@ print $fh pack("x[$size]"); close $fh; -command_checks_all([ 'pg_resetwal', '-n', $node->data_dir ], - 0, - [ qr/pg_control version number/ ], - [ qr/pg_resetwal: pg_control exists but is broken or wrong version; ignoring it/ ], - 'processes corrupted pg_control all zeroes'); +command_checks_all( + [ 'pg_resetwal', '-n', $node->data_dir ], + 0, + [qr/pg_control version number/], + [ + qr/pg_resetwal: warning: pg_control exists but is broken or wrong version; ignoring it/ + ], + 'processes corrupted pg_control all zeroes'); # Put in the previously saved header data. This uses a different code # path internally, allowing us to process a zero WAL segment size. @@ -40,8 +43,11 @@ print $fh $data, pack("x[" . ($size - 16) . "]"); close $fh; -command_checks_all([ 'pg_resetwal', '-n', $node->data_dir ], - 0, - [ qr/pg_control version number/ ], - [ qr/\Qpg_resetwal: pg_control specifies invalid WAL segment size (0 bytes); proceed with caution\E/ ], - 'processes zero WAL segment size'); +command_checks_all( + [ 'pg_resetwal', '-n', $node->data_dir ], + 0, + [qr/pg_control version number/], + [ + qr/\Qpg_resetwal: warning: pg_control specifies invalid WAL segment size (0 bytes); proceed with caution\E/ + ], + 'processes zero WAL segment size'); diff --git a/src/bin/pg_rewind/Makefile b/src/bin/pg_rewind/Makefile index 2bcfcc61af2..7a97df660b5 100644 --- a/src/bin/pg_rewind/Makefile +++ b/src/bin/pg_rewind/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pg_rewind # -# Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group # # src/bin/pg_rewind/Makefile # @@ -16,10 +16,10 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I$(libpq_srcdir) -DFRONTEND $(CPPFLAGS) -LDFLAGS_INTERNAL += $(libpq_pgport) +LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) OBJS = pg_rewind.o parsexlog.o xlogreader.o datapagemap.o timeline.o \ - fetch.o file_ops.o copy_fetch.o libpq_fetch.o filemap.o logging.o \ + fetch.o file_ops.o copy_fetch.o libpq_fetch.o filemap.o \ $(WIN32RES) EXTRA_CLEAN = xlogreader.c diff --git a/src/bin/pg_rewind/copy_fetch.c b/src/bin/pg_rewind/copy_fetch.c index 160a9128477..d74001eb05b 100644 --- a/src/bin/pg_rewind/copy_fetch.c +++ b/src/bin/pg_rewind/copy_fetch.c @@ -3,7 +3,7 @@ * copy_fetch.c * Functions for using a data directory as the source. * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -18,11 +18,10 @@ #include "fetch.h" #include "file_ops.h" #include "filemap.h" -#include "logging.h" #include "pg_rewind.h" static void recurse_dir(const char *datadir, const char *path, - process_file_callback_t callback); + process_file_callback_t callback); static void execute_pagemap(datapagemap_t *pagemap, const char *path); @@ -57,8 +56,8 @@ recurse_dir(const char *datadir, const char *parentpath, xldir = opendir(fullparentpath); if (xldir == NULL) - pg_fatal("could not open directory \"%s\": %s\n", - fullparentpath, strerror(errno)); + pg_fatal("could not open directory \"%s\": %m", + fullparentpath); while (errno = 0, (xlde = readdir(xldir)) != NULL) { @@ -86,8 +85,8 @@ recurse_dir(const char *datadir, const char *parentpath, */ } else - pg_fatal("could not stat file \"%s\": %s\n", - fullpath, strerror(errno)); + pg_fatal("could not stat file \"%s\": %m", + fullpath); } if (parentpath) @@ -115,10 +114,10 @@ recurse_dir(const char *datadir, const char *parentpath, len = readlink(fullpath, link_target, sizeof(link_target)); if (len < 0) - pg_fatal("could not read symbolic link \"%s\": %s\n", - fullpath, strerror(errno)); + pg_fatal("could not read symbolic link \"%s\": %m", + fullpath); if (len >= sizeof(link_target)) - pg_fatal("symbolic link \"%s\" target is too long\n", + pg_fatal("symbolic link \"%s\" target is too long", fullpath); link_target[len] = '\0'; @@ -133,19 +132,19 @@ recurse_dir(const char *datadir, const char *parentpath, strcmp(path, "pg_wal") == 0) recurse_dir(datadir, path, callback); #else - pg_fatal("\"%s\" is a symbolic link, but symbolic links are not supported on this platform\n", + pg_fatal("\"%s\" is a symbolic link, but symbolic links are not supported on this platform", fullpath); #endif /* HAVE_READLINK */ } } if (errno) - pg_fatal("could not read directory \"%s\": %s\n", - fullparentpath, strerror(errno)); + pg_fatal("could not read directory \"%s\": %m", + fullparentpath); if (closedir(xldir)) - pg_fatal("could not close directory \"%s\": %s\n", - fullparentpath, strerror(errno)); + pg_fatal("could not close directory \"%s\": %m", + fullparentpath); } /* @@ -156,7 +155,7 @@ recurse_dir(const char *datadir, const char *parentpath, static void rewind_copy_file_range(const char *path, off_t begin, off_t end, bool trunc) { - char buf[BLCKSZ]; + PGAlignedBlock buf; char srcpath[MAXPGPATH]; int srcfd; @@ -164,11 +163,11 @@ rewind_copy_file_range(const char *path, off_t begin, off_t end, bool trunc) srcfd = open(srcpath, O_RDONLY | PG_BINARY, 0); if (srcfd < 0) - pg_fatal("could not open source file \"%s\": %s\n", - srcpath, strerror(errno)); + pg_fatal("could not open source file \"%s\": %m", + srcpath); if (lseek(srcfd, begin, SEEK_SET) == -1) - pg_fatal("could not seek in source file: %s\n", strerror(errno)); + pg_fatal("could not seek in source file: %m"); open_target_file(path, trunc); @@ -182,20 +181,20 @@ rewind_copy_file_range(const char *path, off_t begin, off_t end, bool trunc) else len = end - begin; - readlen = read(srcfd, buf, len); + readlen = read(srcfd, buf.data, len); if (readlen < 0) - pg_fatal("could not read file \"%s\": %s\n", - srcpath, strerror(errno)); + pg_fatal("could not read file \"%s\": %m", + srcpath); else if (readlen == 0) - pg_fatal("unexpected EOF while reading file \"%s\"\n", srcpath); + pg_fatal("unexpected EOF while reading file \"%s\"", srcpath); - write_target_range(buf, begin, readlen); + write_target_range(buf.data, begin, readlen); begin += readlen; } if (close(srcfd) != 0) - pg_fatal("could not close file \"%s\": %s\n", srcpath, strerror(errno)); + pg_fatal("could not close file \"%s\": %m", srcpath); } /* diff --git a/src/bin/pg_rewind/datapagemap.c b/src/bin/pg_rewind/datapagemap.c index 01bb1a4694f..93165f697cd 100644 --- a/src/bin/pg_rewind/datapagemap.c +++ b/src/bin/pg_rewind/datapagemap.c @@ -5,7 +5,7 @@ * * This is a fairly simple bitmap. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -13,7 +13,8 @@ #include "postgres_fe.h" #include "datapagemap.h" -#include "logging.h" + +#include "common/logging.h" struct datapagemap_iterator { @@ -121,7 +122,7 @@ datapagemap_print(datapagemap_t *map) iter = datapagemap_iterate(map); while (datapagemap_next(iter, &blocknum)) - pg_log(PG_DEBUG, " block %u\n", blocknum); + pg_log_debug("block %u", blocknum); pg_free(iter); } diff --git a/src/bin/pg_rewind/datapagemap.h b/src/bin/pg_rewind/datapagemap.h index 50c0ef779c5..c2baaae644a 100644 --- a/src/bin/pg_rewind/datapagemap.h +++ b/src/bin/pg_rewind/datapagemap.h @@ -2,7 +2,7 @@ * * datapagemap.h * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/fetch.c b/src/bin/pg_rewind/fetch.c index 5a35a8f2e39..03a5fd675f1 100644 --- a/src/bin/pg_rewind/fetch.c +++ b/src/bin/pg_rewind/fetch.c @@ -10,7 +10,7 @@ * connection (libpq_fetch.c) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/fetch.h b/src/bin/pg_rewind/fetch.h index 5ee06817b64..a694e8b157d 100644 --- a/src/bin/pg_rewind/fetch.h +++ b/src/bin/pg_rewind/fetch.h @@ -8,7 +8,7 @@ * directory (copy method), or a remote PostgreSQL server (libpq fetch * method). * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/file_ops.c b/src/bin/pg_rewind/file_ops.c index 94bcc13ae86..f9e41b1fc40 100644 --- a/src/bin/pg_rewind/file_ops.c +++ b/src/bin/pg_rewind/file_ops.c @@ -8,7 +8,7 @@ * do nothing if it's enabled. You should avoid accessing the target files * directly but if you do, make sure you honor the --dry-run mode! * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -21,7 +21,6 @@ #include "common/file_perm.h" #include "file_ops.h" #include "filemap.h" -#include "logging.h" #include "pg_rewind.h" /* @@ -60,8 +59,8 @@ open_target_file(const char *path, bool trunc) mode |= O_TRUNC; dstfd = open(dstpath, mode, pg_file_create_mode); if (dstfd < 0) - pg_fatal("could not open target file \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not open target file \"%s\": %m", + dstpath); } /* @@ -74,8 +73,8 @@ close_target_file(void) return; if (close(dstfd) != 0) - pg_fatal("could not close target file \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not close target file \"%s\": %m", + dstpath); dstfd = -1; } @@ -94,8 +93,8 @@ write_target_range(char *buf, off_t begin, size_t size) return; if (lseek(dstfd, begin, SEEK_SET) == -1) - pg_fatal("could not seek in target file \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not seek in target file \"%s\": %m", + dstpath); writeleft = size; p = buf; @@ -110,8 +109,8 @@ write_target_range(char *buf, off_t begin, size_t size) /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) errno = ENOSPC; - pg_fatal("could not write file \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not write file \"%s\": %m", + dstpath); } p += writelen; @@ -160,7 +159,7 @@ create_target(file_entry_t *entry) case FILE_TYPE_REGULAR: /* can't happen. Regular files are created with open_target_file. */ - pg_fatal("invalid action (CREATE) for regular file\n"); + pg_fatal("invalid action (CREATE) for regular file"); break; } } @@ -183,8 +182,8 @@ remove_target_file(const char *path, bool missing_ok) if (errno == ENOENT && missing_ok) return; - pg_fatal("could not remove file \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not remove file \"%s\": %m", + dstpath); } } @@ -201,12 +200,12 @@ truncate_target_file(const char *path, off_t newsize) fd = open(dstpath, O_WRONLY, pg_file_create_mode); if (fd < 0) - pg_fatal("could not open file \"%s\" for truncation: %s\n", - dstpath, strerror(errno)); + pg_fatal("could not open file \"%s\" for truncation: %m", + dstpath); if (ftruncate(fd, newsize) != 0) - pg_fatal("could not truncate file \"%s\" to %u: %s\n", - dstpath, (unsigned int) newsize, strerror(errno)); + pg_fatal("could not truncate file \"%s\" to %u: %m", + dstpath, (unsigned int) newsize); close(fd); } @@ -221,8 +220,8 @@ create_target_dir(const char *path) snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path); if (mkdir(dstpath, pg_dir_create_mode) != 0) - pg_fatal("could not create directory \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not create directory \"%s\": %m", + dstpath); } static void @@ -235,8 +234,8 @@ remove_target_dir(const char *path) snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path); if (rmdir(dstpath) != 0) - pg_fatal("could not remove directory \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not remove directory \"%s\": %m", + dstpath); } static void @@ -249,8 +248,8 @@ create_target_symlink(const char *path, const char *link) snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path); if (symlink(link, dstpath) != 0) - pg_fatal("could not create symbolic link at \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not create symbolic link at \"%s\": %m", + dstpath); } static void @@ -263,8 +262,8 @@ remove_target_symlink(const char *path) snprintf(dstpath, sizeof(dstpath), "%s/%s", datadir_target, path); if (unlink(dstpath) != 0) - pg_fatal("could not remove symbolic link \"%s\": %s\n", - dstpath, strerror(errno)); + pg_fatal("could not remove symbolic link \"%s\": %m", + dstpath); } @@ -289,24 +288,32 @@ slurpFile(const char *datadir, const char *path, size_t *filesize) struct stat statbuf; char fullpath[MAXPGPATH]; int len; + int r; snprintf(fullpath, sizeof(fullpath), "%s/%s", datadir, path); if ((fd = open(fullpath, O_RDONLY | PG_BINARY, 0)) == -1) - pg_fatal("could not open file \"%s\" for reading: %s\n", - fullpath, strerror(errno)); + pg_fatal("could not open file \"%s\" for reading: %m", + fullpath); if (fstat(fd, &statbuf) < 0) - pg_fatal("could not open file \"%s\" for reading: %s\n", - fullpath, strerror(errno)); + pg_fatal("could not open file \"%s\" for reading: %m", + fullpath); len = statbuf.st_size; buffer = pg_malloc(len + 1); - if (read(fd, buffer, len) != len) - pg_fatal("could not read file \"%s\": %s\n", - fullpath, strerror(errno)); + r = read(fd, buffer, len); + if (r != len) + { + if (r < 0) + pg_fatal("could not read file \"%s\": %m", + fullpath); + else + pg_fatal("could not read file \"%s\": read %d of %zu", + fullpath, r, (Size) len); + } close(fd); /* Zero-terminate the buffer. */ diff --git a/src/bin/pg_rewind/file_ops.h b/src/bin/pg_rewind/file_ops.h index 9d26cf4f774..b3d1fe6b0ac 100644 --- a/src/bin/pg_rewind/file_ops.h +++ b/src/bin/pg_rewind/file_ops.h @@ -3,7 +3,7 @@ * file_ops.h * Helper functions for operating on files * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c index e45e6d44ec7..601f7e9690e 100644 --- a/src/bin/pg_rewind/filemap.c +++ b/src/bin/pg_rewind/filemap.c @@ -3,7 +3,7 @@ * filemap.c * A data structure for keeping track of files that have changed. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -15,7 +15,6 @@ #include "datapagemap.h" #include "filemap.h" -#include "logging.h" #include "pg_rewind.h" #include "common/string.h" @@ -26,11 +25,11 @@ filemap_t *filemap = NULL; static bool isRelDataFile(const char *path); static char *datasegpath(RelFileNode rnode, ForkNumber forknum, - BlockNumber segno); + BlockNumber segno); static int path_cmp(const void *a, const void *b); static int final_filemap_cmp(const void *a, const void *b); static void filemap_list_to_array(filemap_t *map); -static bool check_file_excluded(const char *path, const char *type); +static bool check_file_excluded(const char *path, bool is_source); /* * The contents of these directories are removed or recreated during server @@ -48,7 +47,7 @@ static const char *excludeDirContents[] = * when stats_temp_directory is set because PGSS_TEXT_FILE is always * created there. */ - "pg_stat_tmp", /* defined as PG_STAT_TMP_DIR */ + "pg_stat_tmp", /* defined as PG_STAT_TMP_DIR */ /* * It is generally not useful to backup the contents of this directory @@ -58,7 +57,7 @@ static const char *excludeDirContents[] = "pg_replslot", /* Contents removed on startup, see dsm_cleanup_for_mmap(). */ - "pg_dynshmem", /* defined as PG_DYNSHMEM_DIR */ + "pg_dynshmem", /* defined as PG_DYNSHMEM_DIR */ /* Contents removed on startup, see AsyncShmemInit(). */ "pg_notify", @@ -147,8 +146,11 @@ process_source_file(const char *path, file_type_t type, size_t newsize, Assert(map->array == NULL); - /* ignore any path matching the exclusion filters */ - if (check_file_excluded(path, "source")) + /* + * Skip any files matching the exclusion filters. This has the effect to + * remove all those files on the target. + */ + if (check_file_excluded(path, true)) return; /* @@ -174,7 +176,7 @@ process_source_file(const char *path, file_type_t type, size_t newsize, * regular file */ if (type != FILE_TYPE_REGULAR && isRelDataFile(path)) - pg_fatal("data file \"%s\" in source is not a regular file\n", path); + pg_fatal("data file \"%s\" in source is not a regular file", path); snprintf(localpath, sizeof(localpath), "%s/%s", datadir_target, path); @@ -182,8 +184,8 @@ process_source_file(const char *path, file_type_t type, size_t newsize, if (lstat(localpath, &statbuf) < 0) { if (errno != ENOENT) - pg_fatal("could not stat file \"%s\": %s\n", - localpath, strerror(errno)); + pg_fatal("could not stat file \"%s\": %m", + localpath); exists = false; } @@ -196,7 +198,7 @@ process_source_file(const char *path, file_type_t type, size_t newsize, if (exists && !S_ISDIR(statbuf.st_mode) && strcmp(path, "pg_wal") != 0) { /* it's a directory in source, but not in target. Strange.. */ - pg_fatal("\"%s\" is not a directory\n", localpath); + pg_fatal("\"%s\" is not a directory", localpath); } if (!exists) @@ -219,7 +221,7 @@ process_source_file(const char *path, file_type_t type, size_t newsize, * It's a symbolic link in source, but not in target. * Strange.. */ - pg_fatal("\"%s\" is not a symbolic link\n", localpath); + pg_fatal("\"%s\" is not a symbolic link", localpath); } if (!exists) @@ -231,7 +233,7 @@ process_source_file(const char *path, file_type_t type, size_t newsize, case FILE_TYPE_REGULAR: if (exists && !S_ISREG(statbuf.st_mode)) - pg_fatal("\"%s\" is not a regular file\n", localpath); + pg_fatal("\"%s\" is not a regular file", localpath); if (!exists || !isRelDataFile(path)) { @@ -334,19 +336,17 @@ process_target_file(const char *path, file_type_t type, size_t oldsize, file_entry_t *entry; /* - * Ignore any path matching the exclusion filters. This is not actually - * mandatory for target files, but this does not hurt and let's be - * consistent with the source processing. + * Do not apply any exclusion filters here. This has advantage to remove + * from the target data folder all paths which have been filtered out from + * the source data folder when processing the source files. */ - if (check_file_excluded(path, "target")) - return; snprintf(localpath, sizeof(localpath), "%s/%s", datadir_target, path); if (lstat(localpath, &statbuf) < 0) { if (errno != ENOENT) - pg_fatal("could not stat file \"%s\": %s\n", - localpath, strerror(errno)); + pg_fatal("could not stat file \"%s\": %m", + localpath); exists = false; } @@ -357,7 +357,7 @@ process_target_file(const char *path, file_type_t type, size_t oldsize, if (map->nlist == 0) { /* should not happen */ - pg_fatal("source file list is empty\n"); + pg_fatal("source file list is empty"); } filemap_list_to_array(map); @@ -472,7 +472,7 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno) break; case FILE_ACTION_CREATE: - pg_fatal("unexpected page modification for directory or symbolic link \"%s\"\n", entry->path); + pg_fatal("unexpected page modification for directory or symbolic link \"%s\"", entry->path); } } else @@ -490,11 +490,11 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno) * Is this the path of file that pg_rewind can skip copying? */ static bool -check_file_excluded(const char *path, const char *type) +check_file_excluded(const char *path, bool is_source) { - char localpath[MAXPGPATH]; - int excludeIdx; - const char *filename; + char localpath[MAXPGPATH]; + int excludeIdx; + const char *filename; /* check individual files... */ for (excludeIdx = 0; excludeFiles[excludeIdx] != NULL; excludeIdx++) @@ -506,8 +506,12 @@ check_file_excluded(const char *path, const char *type) filename++; if (strcmp(filename, excludeFiles[excludeIdx]) == 0) { - pg_log(PG_DEBUG, "entry \"%s\" excluded from %s file list\n", - path, type); + if (is_source) + pg_log_debug("entry \"%s\" excluded from source file list", + path); + else + pg_log_debug("entry \"%s\" excluded from target file list", + path); return true; } } @@ -522,8 +526,12 @@ check_file_excluded(const char *path, const char *type) excludeDirContents[excludeIdx]); if (strstr(path, localpath) == path) { - pg_log(PG_DEBUG, "entry \"%s\" excluded from %s file list\n", - path, type); + if (is_source) + pg_log_debug("entry \"%s\" excluded from source file list", + path); + else + pg_log_debug("entry \"%s\" excluded from target file list", + path); return true; } } @@ -650,11 +658,8 @@ print_filemap(void) if (entry->action != FILE_ACTION_NONE || entry->pagemap.bitmapsize > 0) { - pg_log(PG_DEBUG, - /*------ - translator: first %s is a file path, second is a keyword such as COPY */ - "%s (%s)\n", entry->path, - action_to_str(entry->action)); + pg_log_debug("%s (%s)", entry->path, + action_to_str(entry->action)); if (entry->pagemap.bitmapsize > 0) datapagemap_print(&entry->pagemap); @@ -733,8 +738,8 @@ isRelDataFile(const char *path) /* * The sscanf tests above can match files that have extra characters at * the end. To eliminate such cases, cross-check that GetRelationPath - * creates the exact same filename, when passed the RelFileNode information - * we extracted from the filename. + * creates the exact same filename, when passed the RelFileNode + * information we extracted from the filename. */ if (matched) { @@ -802,7 +807,7 @@ final_filemap_cmp(const void *a, const void *b) return -1; if (fa->action == FILE_ACTION_REMOVE) - return -strcmp(fa->path, fb->path); + return strcmp(fb->path, fa->path); else return strcmp(fa->path, fb->path); } diff --git a/src/bin/pg_rewind/filemap.h b/src/bin/pg_rewind/filemap.h index 63ba32a6cda..588228404cd 100644 --- a/src/bin/pg_rewind/filemap.h +++ b/src/bin/pg_rewind/filemap.h @@ -2,7 +2,7 @@ * * filemap.h * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group *------------------------------------------------------------------------- */ #ifndef FILEMAP_H @@ -95,11 +95,11 @@ extern void print_filemap(void); /* Functions for populating the filemap */ extern void process_source_file(const char *path, file_type_t type, - size_t newsize, const char *link_target); + size_t newsize, const char *link_target); extern void process_target_file(const char *path, file_type_t type, - size_t newsize, const char *link_target); + size_t newsize, const char *link_target); extern void process_block_change(ForkNumber forknum, RelFileNode rnode, - BlockNumber blkno); + BlockNumber blkno); extern void filemap_finalize(void); #endif /* FILEMAP_H */ diff --git a/src/bin/pg_rewind/libpq_fetch.c b/src/bin/pg_rewind/libpq_fetch.c index 9a085ea258f..f4ebf7d8420 100644 --- a/src/bin/pg_rewind/libpq_fetch.c +++ b/src/bin/pg_rewind/libpq_fetch.c @@ -3,7 +3,7 @@ * libpq_fetch.c * Functions for fetching files from a remote server. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -19,14 +19,12 @@ #include "fetch.h" #include "file_ops.h" #include "filemap.h" -#include "logging.h" -#include "libpq-fe.h" #include "catalog/pg_type_d.h" #include "fe_utils/connect.h" #include "port/pg_bswap.h" -static PGconn *conn = NULL; +PGconn *conn = NULL; /* * Files are fetched max CHUNKSIZE bytes at a time. @@ -40,6 +38,7 @@ static PGconn *conn = NULL; static void receiveFileChunks(const char *sql); static void execute_pagemap(datapagemap_t *pagemap, const char *path); static char *run_simple_query(const char *sql); +static void run_simple_command(const char *sql); void libpqConnect(const char *connstr) @@ -52,7 +51,13 @@ libpqConnect(const char *connstr) pg_fatal("could not connect to server: %s", PQerrorMessage(conn)); - pg_log(PG_PROGRESS, "connected to server\n"); + if (showprogress) + pg_log_info("connected to server"); + + /* disable all types of timeouts */ + run_simple_command("SET statement_timeout = 0"); + run_simple_command("SET lock_timeout = 0"); + run_simple_command("SET idle_in_transaction_session_timeout = 0"); res = PQexec(conn, ALWAYS_SECURE_SEARCH_PATH_SQL); if (PQresultStatus(res) != PGRES_TUPLES_OK) @@ -68,7 +73,7 @@ libpqConnect(const char *connstr) */ str = run_simple_query("SELECT pg_is_in_recovery()"); if (strcmp(str, "f") != 0) - pg_fatal("source server must not be in recovery mode\n"); + pg_fatal("source server must not be in recovery mode"); pg_free(str); /* @@ -78,7 +83,7 @@ libpqConnect(const char *connstr) */ str = run_simple_query("SHOW full_page_writes"); if (strcmp(str, "on") != 0) - pg_fatal("full_page_writes must be enabled in the source server\n"); + pg_fatal("full_page_writes must be enabled in the source server"); pg_free(str); /* @@ -88,11 +93,7 @@ libpqConnect(const char *connstr) * replication, and replication isn't working for some reason, we don't * want to get stuck, waiting for it to start working again. */ - res = PQexec(conn, "SET synchronous_commit = off"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - pg_fatal("could not set up connection context: %s", - PQresultErrorMessage(res)); - PQclear(res); + run_simple_command("SET synchronous_commit = off"); } /* @@ -113,7 +114,7 @@ run_simple_query(const char *sql) /* sanity check the result set */ if (PQnfields(res) != 1 || PQntuples(res) != 1 || PQgetisnull(res, 0, 0)) - pg_fatal("unexpected result set from query\n"); + pg_fatal("unexpected result set from query"); result = pg_strdup(PQgetvalue(res, 0, 0)); @@ -122,6 +123,24 @@ run_simple_query(const char *sql) return result; } +/* + * Runs a command. + * In the event of a failure, exit immediately. + */ +static void +run_simple_command(const char *sql) +{ + PGresult *res; + + res = PQexec(conn, sql); + + if (PQresultStatus(res) != PGRES_COMMAND_OK) + pg_fatal("error running query (%s) in source server: %s", + sql, PQresultErrorMessage(res)); + + PQclear(res); +} + /* * Calls pg_current_wal_insert_lsn() function */ @@ -136,7 +155,7 @@ libpqGetCurrentXlogInsertLocation(void) val = run_simple_query("SELECT pg_current_wal_insert_lsn()"); if (sscanf(val, "%X/%X", &hi, &lo) != 2) - pg_fatal("unrecognized result \"%s\" for current WAL insert location\n", val); + pg_fatal("unrecognized result \"%s\" for current WAL insert location", val); result = ((uint64) hi) << 32 | lo; @@ -191,7 +210,7 @@ libpqProcessFileList(void) /* sanity check the result set */ if (PQnfields(res) != 4) - pg_fatal("unexpected result set while fetching file list\n"); + pg_fatal("unexpected result set while fetching file list"); /* Read result to local variables */ for (i = 0; i < PQntuples(res); i++) @@ -241,17 +260,16 @@ receiveFileChunks(const char *sql) if (PQsendQueryParams(conn, sql, 0, NULL, NULL, NULL, NULL, 1) != 1) pg_fatal("could not send query: %s", PQerrorMessage(conn)); - pg_log(PG_DEBUG, "getting file chunks\n"); + pg_log_debug("getting file chunks"); if (PQsetSingleRowMode(conn) != 1) - pg_fatal("could not set libpq connection to single row mode\n"); + pg_fatal("could not set libpq connection to single row mode"); while ((res = PQgetResult(conn)) != NULL) { char *filename; int filenamelen; int64 chunkoff; - char chunkoff_str[32]; int chunksize; char *chunk; @@ -271,13 +289,13 @@ receiveFileChunks(const char *sql) /* sanity check the result set */ if (PQnfields(res) != 3 || PQntuples(res) != 1) - pg_fatal("unexpected result set size while fetching remote files\n"); + pg_fatal("unexpected result set size while fetching remote files"); if (PQftype(res, 0) != TEXTOID || PQftype(res, 1) != INT8OID || PQftype(res, 2) != BYTEAOID) { - pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u\n", + pg_fatal("unexpected data types in result set while fetching remote files: %u %u %u", PQftype(res, 0), PQftype(res, 1), PQftype(res, 2)); } @@ -285,17 +303,17 @@ receiveFileChunks(const char *sql) PQfformat(res, 1) != 1 && PQfformat(res, 2) != 1) { - pg_fatal("unexpected result format while fetching remote files\n"); + pg_fatal("unexpected result format while fetching remote files"); } if (PQgetisnull(res, 0, 0) || PQgetisnull(res, 0, 1)) { - pg_fatal("unexpected null values in result while fetching remote files\n"); + pg_fatal("unexpected null values in result while fetching remote files"); } if (PQgetlength(res, 0, 1) != sizeof(int64)) - pg_fatal("unexpected result length while fetching remote files\n"); + pg_fatal("unexpected result length while fetching remote files"); /* Read result set to local variables */ memcpy(&chunkoff, PQgetvalue(res, 0, 1), sizeof(int64)); @@ -319,22 +337,16 @@ receiveFileChunks(const char *sql) */ if (PQgetisnull(res, 0, 2)) { - pg_log(PG_DEBUG, - "received null value for chunk for file \"%s\", file has been deleted\n", - filename); + pg_log_debug("received null value for chunk for file \"%s\", file has been deleted", + filename); remove_target_file(filename, true); pg_free(filename); PQclear(res); continue; } - /* - * Separate step to keep platform-dependent format code out of - * translatable strings. - */ - snprintf(chunkoff_str, sizeof(chunkoff_str), INT64_FORMAT, chunkoff); - pg_log(PG_DEBUG, "received chunk for file \"%s\", offset %s, size %d\n", - filename, chunkoff_str, chunksize); + pg_log_debug("received chunk for file \"%s\", offset %lld, size %d", + filename, (long long int) chunkoff, chunksize); open_target_file(filename, false); @@ -367,7 +379,7 @@ libpqGetFile(const char *filename, size_t *filesize) /* sanity check the result set */ if (PQntuples(res) != 1 || PQgetisnull(res, 0, 0)) - pg_fatal("unexpected result set while fetching remote file \"%s\"\n", + pg_fatal("unexpected result set while fetching remote file \"%s\"", filename); /* Read result to local variables */ @@ -378,7 +390,7 @@ libpqGetFile(const char *filename, size_t *filesize) PQclear(res); - pg_log(PG_DEBUG, "fetched file \"%s\", length %d\n", filename, len); + pg_log_debug("fetched file \"%s\", length %d", filename, len); if (filesize) *filesize = len; @@ -434,12 +446,7 @@ libpq_executeFileMap(filemap_t *map) * need to fetch. */ sql = "CREATE TEMPORARY TABLE fetchchunks(path text, begin int8, len int4);"; - res = PQexec(conn, sql); - - if (PQresultStatus(res) != PGRES_COMMAND_OK) - pg_fatal("could not create temporary table: %s", - PQresultErrorMessage(res)); - PQclear(res); + run_simple_command(sql); sql = "COPY fetchchunks FROM STDIN"; res = PQexec(conn, sql); diff --git a/src/bin/pg_rewind/logging.c b/src/bin/pg_rewind/logging.c deleted file mode 100644 index f48f7e9070e..00000000000 --- a/src/bin/pg_rewind/logging.c +++ /dev/null @@ -1,144 +0,0 @@ -/*------------------------------------------------------------------------- - * - * logging.c - * logging functions - * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include -#include - -#include "pg_rewind.h" -#include "logging.h" - -#include "pgtime.h" - -/* Progress counters */ -uint64 fetch_size; -uint64 fetch_done; - -static pg_time_t last_progress_report = 0; - -#define QUERY_ALLOC 8192 - -#define MESSAGE_WIDTH 60 - -static -pg_attribute_printf(2, 0) -void -pg_log_v(eLogType type, const char *fmt, va_list ap) -{ - char message[QUERY_ALLOC]; - - vsnprintf(message, sizeof(message), _(fmt), ap); - - switch (type) - { - case PG_DEBUG: - if (debug) - printf("%s", message); - break; - - case PG_PROGRESS: - if (showprogress) - printf("%s", message); - break; - - case PG_WARNING: - printf("%s", message); - break; - - case PG_FATAL: - printf("\n%s", message); - printf("%s", _("Failure, exiting\n")); - exit(1); - break; - - default: - break; - } - fflush(stdout); -} - - -void -pg_log(eLogType type, const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - pg_log_v(type, fmt, args); - va_end(args); -} - - -/* - * Print an error message, and exit. - */ -void -pg_fatal(const char *fmt,...) -{ - va_list args; - - va_start(args, fmt); - pg_log_v(PG_FATAL, fmt, args); - va_end(args); - /* should not get here, pg_log_v() exited already */ - exit(1); -} - - -/* - * Print a progress report based on the global variables. - * - * Progress report is written at maximum once per second, unless the - * force parameter is set to true. - */ -void -progress_report(bool force) -{ - int percent; - char fetch_done_str[32]; - char fetch_size_str[32]; - pg_time_t now; - - if (!showprogress) - return; - - now = time(NULL); - if (now == last_progress_report && !force) - return; /* Max once per second */ - - last_progress_report = now; - percent = fetch_size ? (int) ((fetch_done) * 100 / fetch_size) : 0; - - /* - * Avoid overflowing past 100% or the full size. This may make the total - * size number change as we approach the end of the backup (the estimate - * will always be wrong if WAL is included), but that's better than having - * the done column be bigger than the total. - */ - if (percent > 100) - percent = 100; - if (fetch_done > fetch_size) - fetch_size = fetch_done; - - /* - * Separate step to keep platform-dependent format code out of - * translatable strings. And we only test for INT64_FORMAT availability - * in snprintf, not fprintf. - */ - snprintf(fetch_done_str, sizeof(fetch_done_str), INT64_FORMAT, - fetch_done / 1024); - snprintf(fetch_size_str, sizeof(fetch_size_str), INT64_FORMAT, - fetch_size / 1024); - - pg_log(PG_PROGRESS, "%*s/%s kB (%d%%) copied", - (int) strlen(fetch_size_str), fetch_done_str, fetch_size_str, - percent); - printf("\r"); -} diff --git a/src/bin/pg_rewind/logging.h b/src/bin/pg_rewind/logging.h deleted file mode 100644 index 66455039dbd..00000000000 --- a/src/bin/pg_rewind/logging.h +++ /dev/null @@ -1,35 +0,0 @@ -/*------------------------------------------------------------------------- - * - * logging.h - * prototypes for logging functions - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - *------------------------------------------------------------------------- - */ -#ifndef PG_REWIND_LOGGING_H -#define PG_REWIND_LOGGING_H - -/* progress counters */ -extern uint64 fetch_size; -extern uint64 fetch_done; - -/* - * Enumeration to denote pg_log modes - */ -typedef enum -{ - PG_DEBUG, - PG_PROGRESS, - PG_WARNING, - PG_FATAL -} eLogType; - -extern void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3); -extern void pg_fatal(const char *fmt,...) pg_attribute_printf(1, 2) pg_attribute_noreturn(); - -extern void progress_report(bool force); - -#endif /* PG_REWIND_LOGGING_H */ diff --git a/src/bin/pg_rewind/nls.mk b/src/bin/pg_rewind/nls.mk index f0e8d69c82d..ba29d62545c 100644 --- a/src/bin/pg_rewind/nls.mk +++ b/src/bin/pg_rewind/nls.mk @@ -1,9 +1,8 @@ # src/bin/pg_rewind/nls.mk CATALOG_NAME = pg_rewind -AVAIL_LANGUAGES =de es fr it ja ko pl pt_BR ru sv zh_CN -GETTEXT_FILES = copy_fetch.c datapagemap.c fetch.c file_ops.c filemap.c libpq_fetch.c logging.c parsexlog.c pg_rewind.c timeline.c ../../common/fe_memutils.c ../../common/restricted_token.c xlogreader.c - -GETTEXT_TRIGGERS = pg_log:2 pg_fatal report_invalid_record:2 -GETTEXT_FLAGS = pg_log:2:c-format \ +AVAIL_LANGUAGES =de es fr it ja ko pl pt_BR ru sv tr zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) copy_fetch.c datapagemap.c fetch.c file_ops.c filemap.c libpq_fetch.c parsexlog.c pg_rewind.c timeline.c ../../common/fe_memutils.c ../../common/restricted_token.c xlogreader.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) pg_fatal report_invalid_record:2 +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) \ pg_fatal:1:c-format \ report_invalid_record:2:c-format diff --git a/src/bin/pg_rewind/parsexlog.c b/src/bin/pg_rewind/parsexlog.c index b4c1f827a62..264a8f4db5f 100644 --- a/src/bin/pg_rewind/parsexlog.c +++ b/src/bin/pg_rewind/parsexlog.c @@ -3,7 +3,7 @@ * parsexlog.c * Functions for reading Write-Ahead-Log * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -15,7 +15,6 @@ #include "pg_rewind.h" #include "filemap.h" -#include "logging.h" #include "access/rmgr.h" #include "access/xlog_internal.h" @@ -44,14 +43,12 @@ static char xlogfpath[MAXPGPATH]; typedef struct XLogPageReadPrivate { - const char *datadir; int tliIndex; } XLogPageReadPrivate; -static int SimpleXLogPageRead(XLogReaderState *xlogreader, - XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, char *readBuf, - TimeLineID *pageTLI); +static int SimpleXLogPageRead(XLogReaderState *xlogreader, + XLogRecPtr targetPagePtr, + int reqLen, XLogRecPtr targetRecPtr, char *readBuf); /* * Read WAL from the datadir/pg_wal, starting from 'startpoint' on timeline @@ -67,12 +64,11 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, int tliIndex, char *errormsg; XLogPageReadPrivate private; - private.datadir = datadir; private.tliIndex = tliIndex; - xlogreader = XLogReaderAllocate(WalSegSz, &SimpleXLogPageRead, + xlogreader = XLogReaderAllocate(WalSegSz, datadir, &SimpleXLogPageRead, &private); if (xlogreader == NULL) - pg_fatal("out of memory\n"); + pg_fatal("out of memory"); do { @@ -85,13 +81,12 @@ extractPageMap(const char *datadir, XLogRecPtr startpoint, int tliIndex, errptr = startpoint ? startpoint : xlogreader->EndRecPtr; if (errormsg) - pg_fatal("could not read WAL record at %X/%X: %s\n", + pg_fatal("could not read WAL record at %X/%X: %s", (uint32) (errptr >> 32), (uint32) (errptr), errormsg); else - pg_fatal("could not read WAL record at %X/%X\n", - (uint32) (startpoint >> 32), - (uint32) (startpoint)); + pg_fatal("could not read WAL record at %X/%X", + (uint32) (errptr >> 32), (uint32) (errptr)); } extractPageInfo(xlogreader); @@ -121,21 +116,20 @@ readOneRecord(const char *datadir, XLogRecPtr ptr, int tliIndex) XLogPageReadPrivate private; XLogRecPtr endptr; - private.datadir = datadir; private.tliIndex = tliIndex; - xlogreader = XLogReaderAllocate(WalSegSz, &SimpleXLogPageRead, + xlogreader = XLogReaderAllocate(WalSegSz, datadir, &SimpleXLogPageRead, &private); if (xlogreader == NULL) - pg_fatal("out of memory\n"); + pg_fatal("out of memory"); record = XLogReadRecord(xlogreader, ptr, &errormsg); if (record == NULL) { if (errormsg) - pg_fatal("could not read WAL record at %X/%X: %s\n", + pg_fatal("could not read WAL record at %X/%X: %s", (uint32) (ptr >> 32), (uint32) (ptr), errormsg); else - pg_fatal("could not read WAL record at %X/%X\n", + pg_fatal("could not read WAL record at %X/%X", (uint32) (ptr >> 32), (uint32) (ptr)); } endptr = xlogreader->EndRecPtr; @@ -179,12 +173,11 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, forkptr += SizeOfXLogShortPHD; } - private.datadir = datadir; private.tliIndex = tliIndex; - xlogreader = XLogReaderAllocate(WalSegSz, &SimpleXLogPageRead, + xlogreader = XLogReaderAllocate(WalSegSz, datadir, &SimpleXLogPageRead, &private); if (xlogreader == NULL) - pg_fatal("out of memory\n"); + pg_fatal("out of memory"); searchptr = forkptr; for (;;) @@ -196,11 +189,11 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, if (record == NULL) { if (errormsg) - pg_fatal("could not find previous WAL record at %X/%X: %s\n", + pg_fatal("could not find previous WAL record at %X/%X: %s", (uint32) (searchptr >> 32), (uint32) (searchptr), errormsg); else - pg_fatal("could not find previous WAL record at %X/%X\n", + pg_fatal("could not find previous WAL record at %X/%X", (uint32) (searchptr >> 32), (uint32) (searchptr)); } @@ -236,19 +229,19 @@ findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, } } -/* XLogreader callback function, to read a WAL page */ +/* XLogReader callback function, to read a WAL page */ static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, char *readBuf, - TimeLineID *pageTLI) + int reqLen, XLogRecPtr targetRecPtr, char *readBuf) { XLogPageReadPrivate *private = (XLogPageReadPrivate *) xlogreader->private_data; uint32 targetPageOff; XLogRecPtr targetSegEnd; XLogSegNo targetSegNo; + int r; XLByteToSeg(targetPagePtr, targetSegNo, WalSegSz); - XLogSegNoOffsetToRecPtr(targetSegNo + 1, 0, targetSegEnd, WalSegSz); + XLogSegNoOffsetToRecPtr(targetSegNo + 1, 0, WalSegSz, targetSegEnd); targetPageOff = XLogSegmentOffset(targetPagePtr, WalSegSz); /* @@ -284,14 +277,14 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, XLogFileName(xlogfname, targetHistory[private->tliIndex].tli, xlogreadsegno, WalSegSz); - snprintf(xlogfpath, MAXPGPATH, "%s/" XLOGDIR "/%s", private->datadir, xlogfname); + snprintf(xlogfpath, MAXPGPATH, "%s/" XLOGDIR "/%s", + xlogreader->segcxt.ws_dir, xlogfname); xlogreadfd = open(xlogfpath, O_RDONLY | PG_BINARY, 0); if (xlogreadfd < 0) { - printf(_("could not open file \"%s\": %s\n"), xlogfpath, - strerror(errno)); + pg_log_error("could not open file \"%s\": %m", xlogfpath); return -1; } } @@ -304,21 +297,26 @@ SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, /* Read the requested page */ if (lseek(xlogreadfd, (off_t) targetPageOff, SEEK_SET) < 0) { - printf(_("could not seek in file \"%s\": %s\n"), xlogfpath, - strerror(errno)); + pg_log_error("could not seek in file \"%s\": %m", xlogfpath); return -1; } - if (read(xlogreadfd, readBuf, XLOG_BLCKSZ) != XLOG_BLCKSZ) + + r = read(xlogreadfd, readBuf, XLOG_BLCKSZ); + if (r != XLOG_BLCKSZ) { - printf(_("could not read from file \"%s\": %s\n"), xlogfpath, - strerror(errno)); + if (r < 0) + pg_log_error("could not read file \"%s\": %m", xlogfpath); + else + pg_log_error("could not read file \"%s\": read %d of %zu", + xlogfpath, r, (Size) XLOG_BLCKSZ); + return -1; } Assert(targetSegNo == xlogreadsegno); - *pageTLI = targetHistory[private->tliIndex].tli; + xlogreader->seg.ws_tli = targetHistory[private->tliIndex].tli; return XLOG_BLCKSZ; } @@ -379,8 +377,8 @@ extractPageInfo(XLogReaderState *record) * we don't recognize the type. That's bad - we don't know how to * track that change. */ - pg_fatal("WAL record modifies a relation, but record type is not recognized\n" - "lsn: %X/%X, rmgr: %s, info: %02X\n", + pg_fatal("WAL record modifies a relation, but record type is not recognized: " + "lsn: %X/%X, rmgr: %s, info: %02X", (uint32) (record->ReadRecPtr >> 32), (uint32) (record->ReadRecPtr), RmgrNames[rmid], info); } diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index a1ab13963a7..a7fd9e0cabe 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -3,7 +3,7 @@ * pg_rewind.c * Synchronizes a PostgreSQL data directory to a new timeline * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -18,28 +18,31 @@ #include "fetch.h" #include "file_ops.h" #include "filemap.h" -#include "logging.h" #include "access/timeline.h" #include "access/xlog_internal.h" #include "catalog/catversion.h" #include "catalog/pg_control.h" +#include "common/controldata_utils.h" #include "common/file_perm.h" +#include "common/file_utils.h" #include "common/restricted_token.h" +#include "fe_utils/recovery_gen.h" #include "getopt_long.h" #include "storage/bufpage.h" static void usage(const char *progname); static void createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli, - XLogRecPtr checkpointloc); + XLogRecPtr checkpointloc); static void digestControlFile(ControlFileData *ControlFile, char *source, - size_t size); -static void updateControlFile(ControlFileData *ControlFile); -static void syncTargetDirectory(const char *argv0); + size_t size); +static void syncTargetDirectory(void); static void sanityChecks(void); static void findCommonAncestorTimeline(XLogRecPtr *recptr, int *tliIndex); +static void ensureCleanShutdown(const char *argv0); +static void disconnect_atexit(void); static ControlFileData ControlFile_target; static ControlFileData ControlFile_source; @@ -52,14 +55,20 @@ char *datadir_target = NULL; char *datadir_source = NULL; char *connstr_source = NULL; -bool debug = false; +static bool debug = false; bool showprogress = false; bool dry_run = false; +bool do_sync = true; /* Target history */ TimeLineHistoryEntry *targetHistory; int targetNentries; +/* Progress counters */ +uint64 fetch_size; +uint64 fetch_done; + + static void usage(const char *progname) { @@ -69,12 +78,17 @@ usage(const char *progname) printf(_(" -D, --target-pgdata=DIRECTORY existing data directory to modify\n")); printf(_(" --source-pgdata=DIRECTORY source data directory to synchronize with\n")); printf(_(" --source-server=CONNSTR source server to synchronize with\n")); + printf(_(" -R, --write-recovery-conf write configuration for replication\n" + " (requires --source-server)\n")); printf(_(" -n, --dry-run stop before modifying anything\n")); + printf(_(" -N, --no-sync do not wait for changes to be written\n" + " safely to disk\n")); printf(_(" -P, --progress write progress messages\n")); + printf(_(" --no-ensure-shutdown do not automatically fix unclean shutdown\n")); printf(_(" --debug write a lot of debug messages\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_(" -?, --help show this help, then exit\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } @@ -84,10 +98,13 @@ main(int argc, char **argv) static struct option long_options[] = { {"help", no_argument, NULL, '?'}, {"target-pgdata", required_argument, NULL, 'D'}, + {"write-recovery-conf", no_argument, NULL, 'R'}, {"source-pgdata", required_argument, NULL, 1}, {"source-server", required_argument, NULL, 2}, + {"no-ensure-shutdown", no_argument, NULL, 44}, {"version", no_argument, NULL, 'V'}, {"dry-run", no_argument, NULL, 'n'}, + {"no-sync", no_argument, NULL, 'N'}, {"progress", no_argument, NULL, 'P'}, {"debug", no_argument, NULL, 3}, {NULL, 0, NULL, 0} @@ -101,11 +118,14 @@ main(int argc, char **argv) XLogRecPtr chkptredo; size_t size; char *buffer; + bool no_ensure_shutdown = false; bool rewind_needed; XLogRecPtr endrec; TimeLineID endtli; ControlFileData ControlFile_new; + bool writerecoveryconf = false; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_rewind")); progname = get_progname(argv[0]); @@ -124,7 +144,7 @@ main(int argc, char **argv) } } - while ((c = getopt_long(argc, argv, "D:nP", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "D:nNPR", long_options, &option_index)) != -1) { switch (c) { @@ -140,8 +160,17 @@ main(int argc, char **argv) dry_run = true; break; + case 'N': + do_sync = false; + break; + + case 'R': + writerecoveryconf = true; + break; + case 3: debug = true; + pg_logging_set_level(PG_LOG_DEBUG); break; case 'D': /* -D or --target-pgdata */ @@ -154,48 +183,48 @@ main(int argc, char **argv) case 2: /* --source-server */ connstr_source = pg_strdup(optarg); break; + case 4: + no_ensure_shutdown = true; + break; } } if (datadir_source == NULL && connstr_source == NULL) { - fprintf(stderr, _("%s: no source specified (--source-pgdata or --source-server)\n"), progname); + pg_log_error("no source specified (--source-pgdata or --source-server)"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (datadir_source != NULL && connstr_source != NULL) { - fprintf(stderr, _("%s: only one of --source-pgdata or --source-server can be specified\n"), progname); + pg_log_error("only one of --source-pgdata or --source-server can be specified"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } if (datadir_target == NULL) { - fprintf(stderr, _("%s: no target data directory specified (--target-pgdata)\n"), progname); + pg_log_error("no target data directory specified (--target-pgdata)"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } - if (optind < argc) + if (writerecoveryconf && connstr_source == NULL) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("no source server information (--source--server) specified for --write-recovery-conf"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } - /* Set mask based on PGDATA permissions */ - if (!GetDataDirectoryCreatePerm(datadir_target)) + if (optind < argc) { - fprintf(stderr, _("%s: unable to read permissions from \"%s\"\n"), - progname, datadir_target); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } - umask(pg_mode_mask); - /* * Don't allow pg_rewind to be run as root, to avoid overwriting the * ownership of files in the data directory. We need only check for root @@ -205,14 +234,26 @@ main(int argc, char **argv) #ifndef WIN32 if (geteuid() == 0) { - fprintf(stderr, _("cannot be executed by \"root\"\n")); + pg_log_error("cannot be executed by \"root\""); fprintf(stderr, _("You must run %s as the PostgreSQL superuser.\n"), progname); exit(1); } #endif - get_restricted_token(progname); + get_restricted_token(); + + /* Set mask based on PGDATA permissions */ + if (!GetDataDirectoryCreatePerm(datadir_target)) + { + pg_log_error("could not read permissions of directory \"%s\": %m", + datadir_target); + exit(1); + } + + umask(pg_mode_mask); + + atexit(disconnect_atexit); /* Connect to remote server */ if (connstr_source) @@ -226,6 +267,24 @@ main(int argc, char **argv) digestControlFile(&ControlFile_target, buffer, size); pg_free(buffer); + /* + * If the target instance was not cleanly shut down, run a single-user + * postgres session really quickly and reload the control file to get the + * new state. Note if no_ensure_shutdown is specified, pg_rewind won't do + * that automatically. That means users need to do themselves in advance, + * else pg_rewind will soon quit, see sanityChecks(). + */ + if (!no_ensure_shutdown && + ControlFile_target.state != DB_SHUTDOWNED && + ControlFile_target.state != DB_SHUTDOWNED_IN_RECOVERY) + { + ensureCleanShutdown(argv[0]); + + buffer = slurpFile(datadir_target, "global/pg_control", &size); + digestControlFile(&ControlFile_target, buffer, size); + pg_free(buffer); + } + buffer = fetchFile("global/pg_control", &size); digestControlFile(&ControlFile_source, buffer, size); pg_free(buffer); @@ -238,15 +297,15 @@ main(int argc, char **argv) */ if (ControlFile_target.checkPointCopy.ThisTimeLineID == ControlFile_source.checkPointCopy.ThisTimeLineID) { - printf(_("source and target cluster are on the same timeline\n")); + pg_log_info("source and target cluster are on the same timeline"); rewind_needed = false; } else { findCommonAncestorTimeline(&divergerec, &lastcommontliIndex); - printf(_("servers diverged at WAL location %X/%X on timeline %u\n"), - (uint32) (divergerec >> 32), (uint32) divergerec, - targetHistory[lastcommontliIndex].tli); + pg_log_info("servers diverged at WAL location %X/%X on timeline %u", + (uint32) (divergerec >> 32), (uint32) divergerec, + targetHistory[lastcommontliIndex].tli); /* * Check for the possibility that the target is in fact a direct @@ -281,24 +340,29 @@ main(int argc, char **argv) if (!rewind_needed) { - printf(_("no rewind required\n")); + pg_log_info("no rewind required"); + if (writerecoveryconf) + WriteRecoveryConfig(conn, datadir_target, + GenerateRecoveryConfig(conn, NULL)); exit(0); } findLastCheckpoint(datadir_target, divergerec, lastcommontliIndex, &chkptrec, &chkpttli, &chkptredo); - printf(_("rewinding from last common checkpoint at %X/%X on timeline %u\n"), - (uint32) (chkptrec >> 32), (uint32) chkptrec, - chkpttli); + pg_log_info("rewinding from last common checkpoint at %X/%X on timeline %u", + (uint32) (chkptrec >> 32), (uint32) chkptrec, + chkpttli); /* * Build the filemap, by comparing the source and target data directories. */ filemap_create(); - pg_log(PG_PROGRESS, "reading source file list\n"); + if (showprogress) + pg_log_info("reading source file list"); fetchSourceFileList(); - pg_log(PG_PROGRESS, "reading target file list\n"); + if (showprogress) + pg_log_info("reading target file list"); traverse_datadir(datadir_target, &process_target_file); /* @@ -308,7 +372,8 @@ main(int argc, char **argv) * XXX: If we supported rewinding a server that was not shut down cleanly, * we would need to replay until the end of WAL here. */ - pg_log(PG_PROGRESS, "reading WAL in target\n"); + if (showprogress) + pg_log_info("reading WAL in target"); extractPageMap(datadir_target, chkptrec, lastcommontliIndex, ControlFile_target.checkPoint); filemap_finalize(); @@ -325,9 +390,9 @@ main(int argc, char **argv) */ if (showprogress) { - pg_log(PG_PROGRESS, "need to copy %lu MB (total source directory size is %lu MB)\n", - (unsigned long) (filemap->fetch_size / (1024 * 1024)), - (unsigned long) (filemap->total_size / (1024 * 1024))); + pg_log_info("need to copy %lu MB (total source directory size is %lu MB)", + (unsigned long) (filemap->fetch_size / (1024 * 1024)), + (unsigned long) (filemap->total_size / (1024 * 1024))); fetch_size = filemap->fetch_size; fetch_done = 0; @@ -341,8 +406,10 @@ main(int argc, char **argv) executeFileMap(); progress_report(true); + printf("\n"); - pg_log(PG_PROGRESS, "\ncreating backup label and updating control file\n"); + if (showprogress) + pg_log_info("creating backup label and updating control file"); createBackupLabel(chkptredo, chkpttli, chkptrec); /* @@ -368,12 +435,17 @@ main(int argc, char **argv) ControlFile_new.minRecoveryPoint = endrec; ControlFile_new.minRecoveryPointTLI = endtli; ControlFile_new.state = DB_IN_ARCHIVE_RECOVERY; - updateControlFile(&ControlFile_new); + update_controlfile(datadir_target, &ControlFile_new, do_sync); + + if (showprogress) + pg_log_info("syncing target data directory"); + syncTargetDirectory(); - pg_log(PG_PROGRESS, "syncing target data directory\n"); - syncTargetDirectory(argv[0]); + if (writerecoveryconf) + WriteRecoveryConfig(conn, datadir_target, + GenerateRecoveryConfig(conn, NULL)); - printf(_("Done!\n")); + pg_log_info("Done!"); return 0; } @@ -383,9 +455,9 @@ sanityChecks(void) { /* TODO Check that there's no backup_label in either cluster */ - /* Check system_id match */ + /* Check system_identifier match */ if (ControlFile_target.system_identifier != ControlFile_source.system_identifier) - pg_fatal("source and target clusters are from different systems\n"); + pg_fatal("source and target clusters are from different systems"); /* check version */ if (ControlFile_target.pg_control_version != PG_CONTROL_VERSION || @@ -393,7 +465,7 @@ sanityChecks(void) ControlFile_target.catalog_version_no != CATALOG_VERSION_NO || ControlFile_source.catalog_version_no != CATALOG_VERSION_NO) { - pg_fatal("clusters are not compatible with this version of pg_rewind\n"); + pg_fatal("clusters are not compatible with this version of pg_rewind"); } /* @@ -403,7 +475,7 @@ sanityChecks(void) if (ControlFile_target.data_checksum_version != PG_DATA_CHECKSUM_VERSION && !ControlFile_target.wal_log_hints) { - pg_fatal("target server needs to use either data checksums or \"wal_log_hints = on\"\n"); + pg_fatal("target server needs to use either data checksums or \"wal_log_hints = on\""); } /* @@ -414,7 +486,7 @@ sanityChecks(void) */ if (ControlFile_target.state != DB_SHUTDOWNED && ControlFile_target.state != DB_SHUTDOWNED_IN_RECOVERY) - pg_fatal("target server must be shut down cleanly\n"); + pg_fatal("target server must be shut down cleanly"); /* * When the source is a data directory, also require that the source @@ -424,7 +496,62 @@ sanityChecks(void) if (datadir_source && ControlFile_source.state != DB_SHUTDOWNED && ControlFile_source.state != DB_SHUTDOWNED_IN_RECOVERY) - pg_fatal("source data directory must be shut down cleanly\n"); + pg_fatal("source data directory must be shut down cleanly"); +} + +/* + * Print a progress report based on the fetch_size and fetch_done variables. + * + * Progress report is written at maximum once per second, unless the + * force parameter is set to true. + */ +void +progress_report(bool force) +{ + static pg_time_t last_progress_report = 0; + int percent; + char fetch_done_str[32]; + char fetch_size_str[32]; + pg_time_t now; + + if (!showprogress) + return; + + now = time(NULL); + if (now == last_progress_report && !force) + return; /* Max once per second */ + + last_progress_report = now; + percent = fetch_size ? (int) ((fetch_done) * 100 / fetch_size) : 0; + + /* + * Avoid overflowing past 100% or the full size. This may make the total + * size number change as we approach the end of the backup (the estimate + * will always be wrong if WAL is included), but that's better than having + * the done column be bigger than the total. + */ + if (percent > 100) + percent = 100; + if (fetch_done > fetch_size) + fetch_size = fetch_done; + + /* + * Separate step to keep platform-dependent format code out of + * translatable strings. And we only test for INT64_FORMAT availability + * in snprintf, not fprintf. + */ + snprintf(fetch_done_str, sizeof(fetch_done_str), INT64_FORMAT, + fetch_done / 1024); + snprintf(fetch_size_str, sizeof(fetch_size_str), INT64_FORMAT, + fetch_size / 1024); + + fprintf(stderr, _("%*s/%s kB (%d%%) copied"), + (int) strlen(fetch_size_str), fetch_done_str, fetch_size_str, + percent); + if (isatty(fileno(stderr))) + fprintf(stderr, "\r"); + else + fprintf(stderr, "\n"); } /* @@ -490,9 +617,9 @@ getTimelineHistory(ControlFileData *controlFile, int *nentries) int i; if (controlFile == &ControlFile_source) - pg_log(PG_DEBUG, "Source timeline history:\n"); + pg_log_debug("Source timeline history:"); else if (controlFile == &ControlFile_target) - pg_log(PG_DEBUG, "Target timeline history:\n"); + pg_log_debug("Target timeline history:"); else Assert(false); @@ -504,11 +631,9 @@ getTimelineHistory(ControlFileData *controlFile, int *nentries) TimeLineHistoryEntry *entry; entry = &history[i]; - pg_log(PG_DEBUG, - /* translator: %d is a timeline number, others are LSN positions */ - "%d: %X/%X - %X/%X\n", entry->tli, - (uint32) (entry->begin >> 32), (uint32) (entry->begin), - (uint32) (entry->end >> 32), (uint32) (entry->end)); + pg_log_debug("%d: %X/%X - %X/%X", entry->tli, + (uint32) (entry->begin >> 32), (uint32) (entry->begin), + (uint32) (entry->end >> 32), (uint32) (entry->end)); } } @@ -565,7 +690,7 @@ findCommonAncestorTimeline(XLogRecPtr *recptr, int *tliIndex) } else { - pg_fatal("could not find common ancestor of the source and target cluster's timelines\n"); + pg_fatal("could not find common ancestor of the source and target cluster's timelines"); } } @@ -606,7 +731,7 @@ createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli, XLogRecPtr checkpo (uint32) (checkpointloc >> 32), (uint32) checkpointloc, strfbuf); if (len >= sizeof(buf)) - pg_fatal("backup label buffer too small\n"); /* shouldn't happen */ + pg_fatal("backup label buffer too small"); /* shouldn't happen */ /* TODO: move old file out of the way, if any. */ open_target_file("backup_label", true); /* BACKUP_LABEL_FILE */ @@ -629,7 +754,7 @@ checkControlFile(ControlFileData *ControlFile) /* And simply compare it */ if (!EQ_CRC32C(crc, ControlFile->crc)) - pg_fatal("unexpected control file CRC\n"); + pg_fatal("unexpected control file CRC"); } /* @@ -639,7 +764,7 @@ static void digestControlFile(ControlFileData *ControlFile, char *src, size_t size) { if (size != PG_CONTROL_FILE_SIZE) - pg_fatal("unexpected control file size %d, expected %d\n", + pg_fatal("unexpected control file size %d, expected %d", (int) size, PG_CONTROL_FILE_SIZE); memcpy(ControlFile, src, sizeof(ControlFileData)); @@ -648,7 +773,9 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size) WalSegSz = ControlFile->xlog_seg_size; if (!IsValidWalSegSize(WalSegSz)) - pg_fatal("WAL segment size must be a power of two between 1MB and 1GB, but the control file specifies %d bytes\n", + pg_fatal(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte", + "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes", + WalSegSz), WalSegSz); /* Additional checks on control file */ @@ -656,64 +783,38 @@ digestControlFile(ControlFileData *ControlFile, char *src, size_t size) } /* - * Update the target's control file. + * Sync target data directory to ensure that modifications are safely on disk. + * + * We do this once, for the whole data directory, for performance reasons. At + * the end of pg_rewind's run, the kernel is likely to already have flushed + * most dirty buffers to disk. Additionally fsync_pgdata uses a two-pass + * approach (only initiating writeback in the first pass), which often reduces + * the overall amount of IO noticeably. */ static void -updateControlFile(ControlFileData *ControlFile) +syncTargetDirectory(void) { - char buffer[PG_CONTROL_FILE_SIZE]; - - /* - * For good luck, apply the same static assertions as in backend's - * WriteControlFile(). - */ - StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE, - "pg_control is too large for atomic disk writes"); - StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE, - "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE"); - - /* Recalculate CRC of control file */ - INIT_CRC32C(ControlFile->crc); - COMP_CRC32C(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(ControlFile->crc); - - /* - * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding - * the excess over sizeof(ControlFileData), to avoid premature EOF related - * errors when reading it. - */ - memset(buffer, 0, PG_CONTROL_FILE_SIZE); - memcpy(buffer, ControlFile, sizeof(ControlFileData)); - - open_target_file("global/pg_control", false); - - write_target_range(buffer, 0, PG_CONTROL_FILE_SIZE); + if (!do_sync || dry_run) + return; - close_target_file(); + fsync_pgdata(datadir_target, PG_VERSION_NUM); } /* - * Sync target data directory to ensure that modifications are safely on disk. - * - * We do this once, for the whole data directory, for performance reasons. At - * the end of pg_rewind's run, the kernel is likely to already have flushed - * most dirty buffers to disk. Additionally initdb -S uses a two-pass approach - * (only initiating writeback in the first pass), which often reduces the - * overall amount of IO noticeably. + * Ensure clean shutdown of target instance by launching single-user mode + * postgres to do crash recovery. */ static void -syncTargetDirectory(const char *argv0) +ensureCleanShutdown(const char *argv0) { int ret; #define MAXCMDLEN (2 * MAXPGPATH) char exec_path[MAXPGPATH]; char cmd[MAXCMDLEN]; - /* locate initdb binary */ - if ((ret = find_other_exec(argv0, "initdb", - "initdb (PostgreSQL) " PG_VERSION "\n", + /* locate postgres binary */ + if ((ret = find_other_exec(argv0, "postgres", + PG_BACKEND_VERSIONSTR, exec_path)) < 0) { char full_path[MAXPGPATH]; @@ -722,27 +823,41 @@ syncTargetDirectory(const char *argv0) strlcpy(full_path, progname, sizeof(full_path)); if (ret == -1) - pg_fatal("The program \"initdb\" is needed by %s but was\n" + pg_fatal("The program \"%s\" is needed by %s but was\n" "not found in the same directory as \"%s\".\n" - "Check your installation.\n", progname, full_path); + "Check your installation.", + "postgres", progname, full_path); else - pg_fatal("The program \"initdb\" was found by \"%s\"\n" - "but was not the same version as %s.\n" - "Check your installation.\n", full_path, progname); + pg_fatal("The program \"%s\" was found by \"%s\" but was\n" + "not the same version as %s.\n" + "Check your installation.", + "postgres", full_path, progname); } - /* only skip processing after ensuring presence of initdb */ + pg_log_info("executing \"%s\" for target server to complete crash recovery", + exec_path); + + /* + * Skip processing if requested, but only after ensuring presence of + * postgres. + */ if (dry_run) return; - /* finally run initdb -S */ - if (debug) - snprintf(cmd, MAXCMDLEN, "\"%s\" -D \"%s\" -S", - exec_path, datadir_target); - else - snprintf(cmd, MAXCMDLEN, "\"%s\" -D \"%s\" -S > \"%s\"", - exec_path, datadir_target, DEVNULL); + /* finally run postgres in single-user mode */ + snprintf(cmd, MAXCMDLEN, "\"%s\" --single -D \"%s\" template1 < \"%s\"", + exec_path, datadir_target, DEVNULL); if (system(cmd) != 0) - pg_fatal("sync of target directory failed\n"); + { + pg_log_error("postgres single-user mode of target instance failed"); + pg_fatal("Command was: %s", cmd); + } +} + +static void +disconnect_atexit(void) +{ + if (conn != NULL) + PQfinish(conn); } diff --git a/src/bin/pg_rewind/pg_rewind.h b/src/bin/pg_rewind/pg_rewind.h index 3f4ba7a2676..aa3a0ce8fc5 100644 --- a/src/bin/pg_rewind/pg_rewind.h +++ b/src/bin/pg_rewind/pg_rewind.h @@ -3,7 +3,7 @@ * pg_rewind.h * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -14,14 +14,16 @@ #include "datapagemap.h" #include "access/timeline.h" +#include "common/logging.h" +#include "libpq-fe.h" #include "storage/block.h" #include "storage/relfilenode.h" + /* Configuration options */ extern char *datadir_target; extern char *datadir_source; extern char *connstr_source; -extern bool debug; extern bool showprogress; extern bool dry_run; extern int WalSegSz; @@ -30,18 +32,32 @@ extern int WalSegSz; extern TimeLineHistoryEntry *targetHistory; extern int targetNentries; +/* general state */ +extern PGconn *conn; + +/* Progress counters */ +extern uint64 fetch_size; +extern uint64 fetch_done; + +/* logging support */ +#define pg_fatal(...) do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0) + /* in parsexlog.c */ extern void extractPageMap(const char *datadir, XLogRecPtr startpoint, - int tliIndex, XLogRecPtr endpoint); + int tliIndex, XLogRecPtr endpoint); extern void findLastCheckpoint(const char *datadir, XLogRecPtr searchptr, - int tliIndex, - XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, - XLogRecPtr *lastchkptredo); + int tliIndex, + XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, + XLogRecPtr *lastchkptredo); extern XLogRecPtr readOneRecord(const char *datadir, XLogRecPtr ptr, - int tliIndex); + int tliIndex); + +/* in pg_rewind.c */ +extern void progress_report(bool force); /* in timeline.c */ extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer, - TimeLineID targetTLI, int *nentries); + TimeLineID targetTLI, + int *nentries); #endif /* PG_REWIND_H */ diff --git a/src/bin/pg_rewind/po/de.po b/src/bin/pg_rewind/po/de.po index e8d5b17e634..2e94a090a18 100644 --- a/src/bin/pg_rewind/po/de.po +++ b/src/bin/pg_rewind/po/de.po @@ -1,24 +1,39 @@ # German message translation file for pg_rewind -# Copyright (C) 2015-2017 PostgreSQL Global Development Group +# Copyright (C) 2015-2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2015-2017. +# Peter Eisentraut , 2015-2019. # msgid "" msgstr "" -"Project-Id-Version: pg_rewind (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-12 23:46+0000\n" -"PO-Revision-Date: 2017-05-12 22:57-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: pg_rewind (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-26 22:15+0000\n" +"PO-Revision-Date: 2019-05-27 13:02-0400\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 -#: parsexlog.c:179 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" @@ -28,406 +43,372 @@ msgstr "Speicher aufgebraucht\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:69 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: WARNUNG: auf dieser Plattform können keine beschränkten Token erzeugt werden\n" +msgid "cannot create restricted tokens on this platform" +msgstr "auf dieser Plattform können keine beschränkten Token erzeugt werden" -#: ../../common/restricted_token.c:77 +#: ../../common/restricted_token.c:78 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: konnte Prozess-Token nicht öffnen: Fehlercode %lu\n" +msgid "could not open process token: error code %lu" +msgstr "konnte Prozess-Token nicht öffnen: Fehlercode %lu" -#: ../../common/restricted_token.c:90 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: konnte SIDs nicht erzeugen: Fehlercode %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "konnte SIDs nicht erzeugen: Fehlercode %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: konnte beschränktes Token nicht erzeugen: Fehlercode %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "konnte beschränktes Token nicht erzeugen: Fehlercode %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "konnte Prozess für Befehl »%s« nicht starten: Fehlercode %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "konnte Prozess nicht mit beschränktem Token neu starten: Fehlercode %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "konnte Statuscode des Subprozesses nicht ermitteln: Fehlercode %lu" -#: copy_fetch.c:62 +#: copy_fetch.c:59 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht öffnen: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %m" -#: copy_fetch.c:91 filemap.c:111 filemap.c:266 +#: copy_fetch.c:88 filemap.c:187 filemap.c:348 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "konnte »stat« für Datei »%s« nicht ausführen: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m" -#: copy_fetch.c:120 +#: copy_fetch.c:117 #, c-format -msgid "could not read symbolic link \"%s\": %s\n" -msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %s\n" +msgid "could not read symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht lesen: %m" -#: copy_fetch.c:123 +#: copy_fetch.c:120 #, c-format -msgid "symbolic link \"%s\" target is too long\n" -msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang\n" +msgid "symbolic link \"%s\" target is too long" +msgstr "Ziel für symbolische Verknüpfung »%s« ist zu lang" -#: copy_fetch.c:138 +#: copy_fetch.c:135 #, c-format -msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform\n" -msgstr "»%s« ist eine symbolische Verknüpfung, aber symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt\n" +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "»%s« ist eine symbolische Verknüpfung, aber symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt" -#: copy_fetch.c:145 +#: copy_fetch.c:142 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht lesen: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht lesen: %m" -#: copy_fetch.c:149 +#: copy_fetch.c:146 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht schließen: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht schließen: %m" -#: copy_fetch.c:169 +#: copy_fetch.c:166 #, c-format -msgid "could not open source file \"%s\": %s\n" -msgstr "konnte Quelldatei »%s« nicht öffnen: %s\n" +msgid "could not open source file \"%s\": %m" +msgstr "konnte Quelldatei »%s« nicht öffnen: %m" -#: copy_fetch.c:173 +#: copy_fetch.c:170 #, c-format -msgid "could not seek in source file: %s\n" -msgstr "konnte Positionszeiger in Quelldatei nicht setzen: %s\n" +msgid "could not seek in source file: %m" +msgstr "konnte Positionszeiger in Quelldatei nicht setzen: %m" -#: copy_fetch.c:190 file_ops.c:299 +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:315 #, c-format -msgid "could not read file \"%s\": %s\n" -msgstr "konnte Datei »%s« nicht lesen: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "konnte Datei »%s« nicht lesen: %m" -#: copy_fetch.c:193 +#: copy_fetch.c:190 #, c-format -msgid "unexpected EOF while reading file \"%s\"\n" -msgstr "unerwartetes EOF beim Lesen der Datei »%s«\n" +msgid "unexpected EOF while reading file \"%s\"" +msgstr "unerwartetes EOF beim Lesen der Datei »%s«" -#: copy_fetch.c:200 +#: copy_fetch.c:197 #, c-format -msgid "could not close file \"%s\": %s\n" -msgstr "konnte Datei »%s« nicht schließen: %s\n" +msgid "could not close file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schließen: %m" -#: datapagemap.c:124 +#: file_ops.c:62 #, c-format -msgid " block %u\n" -msgstr " Block %u\n" +msgid "could not open target file \"%s\": %m" +msgstr "konnte Zieldatei »%s« nicht öffnen: %m" -#: file_ops.c:63 +#: file_ops.c:76 #, c-format -msgid "could not open target file \"%s\": %s\n" -msgstr "konnte Zieldatei »%s« nicht öffnen: %s\n" +msgid "could not close target file \"%s\": %m" +msgstr "konnte Zieldatei »%s« nicht schließen: %m" -#: file_ops.c:77 +#: file_ops.c:96 #, c-format -msgid "could not close target file \"%s\": %s\n" -msgstr "konnte Zieldatei »%s« nicht schließen: %s\n" +msgid "could not seek in target file \"%s\": %m" +msgstr "konnte Positionszeiger in Zieldatei »%s« nicht setzen: %m" -#: file_ops.c:97 +#: file_ops.c:112 #, c-format -msgid "could not seek in target file \"%s\": %s\n" -msgstr "konnte Positionszeiger in Zieldatei »%s« nicht setzen: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "konnte Datei »%s« nicht schreiben: %m" -#: file_ops.c:113 +#: file_ops.c:162 #, c-format -msgid "could not write file \"%s\": %s\n" -msgstr "konnte Datei »%s« nicht schreiben: %s\n" +msgid "invalid action (CREATE) for regular file" +msgstr "ungültige Aktion (CREATE) für normale Datei" -#: file_ops.c:163 +#: file_ops.c:185 #, c-format -msgid "invalid action (CREATE) for regular file\n" -msgstr "ungültige Aktion (CREATE) für normale Datei\n" +msgid "could not remove file \"%s\": %m" +msgstr "konnte Datei »%s« nicht löschen: %m" -#: file_ops.c:178 +#: file_ops.c:203 #, c-format -msgid "could not remove file \"%s\": %s\n" -msgstr "konnte Datei »%s« nicht löschen: %s\n" +msgid "could not open file \"%s\" for truncation: %m" +msgstr "konnte Datei »%s« nicht zum Kürzen öffnen: %m" -#: file_ops.c:195 +#: file_ops.c:207 #, c-format -msgid "could not open file \"%s\" for truncation: %s\n" -msgstr "konnte Datei »%s« nicht zum Kürzen öffnen: %s\n" +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "konnte Datei »%s« nicht auf %u kürzen: %m" -#: file_ops.c:199 +#: file_ops.c:223 #, c-format -msgid "could not truncate file \"%s\" to %u: %s\n" -msgstr "konnte Datei »%s« nicht auf %u kürzen: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m" -#: file_ops.c:215 +#: file_ops.c:237 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht erzeugen: %s\n" +msgid "could not remove directory \"%s\": %m" +msgstr "konnte Verzeichnis »%s« nicht löschen: %m" -#: file_ops.c:229 +#: file_ops.c:251 #, c-format -msgid "could not remove directory \"%s\": %s\n" -msgstr "konnte Verzeichnis »%s« nicht löschen: %s\n" +msgid "could not create symbolic link at \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m" -#: file_ops.c:243 +#: file_ops.c:265 #, c-format -msgid "could not create symbolic link at \"%s\": %s\n" -msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %s\n" +msgid "could not remove symbolic link \"%s\": %m" +msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %m" -#: file_ops.c:257 +#: file_ops.c:296 file_ops.c:300 #, c-format -msgid "could not remove symbolic link \"%s\": %s\n" -msgstr "konnte symbolische Verknüpfung »%s« nicht löschen: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %m" -#: file_ops.c:287 file_ops.c:291 +#: file_ops.c:314 parsexlog.c:317 #, c-format -msgid "could not open file \"%s\" for reading: %s\n" -msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %s\n" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" -#: filemap.c:103 +#: filemap.c:179 #, c-format -msgid "data file \"%s\" in source is not a regular file\n" -msgstr "Datendatei »%s« in der Quelle ist keine normale Datei\n" +msgid "data file \"%s\" in source is not a regular file" +msgstr "Datendatei »%s« in der Quelle ist keine normale Datei" -#: filemap.c:125 +#: filemap.c:201 #, c-format -msgid "\"%s\" is not a directory\n" -msgstr "»%s« ist kein Verzeichnis\n" +msgid "\"%s\" is not a directory" +msgstr "»%s« ist kein Verzeichnis" -#: filemap.c:148 +#: filemap.c:224 #, c-format -msgid "\"%s\" is not a symbolic link\n" -msgstr "»%s« ist keine symbolische Verknüpfung\n" +msgid "\"%s\" is not a symbolic link" +msgstr "»%s« ist keine symbolische Verknüpfung" -#: filemap.c:160 +#: filemap.c:236 #, c-format -msgid "\"%s\" is not a regular file\n" -msgstr "»%s« ist keine normale Datei\n" +msgid "\"%s\" is not a regular file" +msgstr "»%s« ist keine normale Datei" -#: filemap.c:278 +#: filemap.c:360 #, c-format -msgid "source file list is empty\n" -msgstr "Quelldateiliste ist leer\n" +msgid "source file list is empty" +msgstr "Quelldateiliste ist leer" -#: filemap.c:400 +#: filemap.c:475 #, c-format -msgid "unexpected page modification for directory or symbolic link \"%s\"\n" -msgstr "unerwartete Seitenänderung für Verzeichnis oder symbolische Verknüpfung »%s«\n" +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "unerwartete Seitenänderung für Verzeichnis oder symbolische Verknüpfung »%s«" -#. translator: first %s is a file path, second is a keyword such as COPY -#: filemap.c:536 +#: libpq_fetch.c:51 #, c-format -msgid "%s (%s)\n" -msgstr "%s (%s)\n" +msgid "could not connect to server: %s" +msgstr "konnte nicht mit Server verbinden: %s" #: libpq_fetch.c:55 #, c-format -msgid "could not connect to server: %s" -msgstr "konnte nicht mit Server verbinden: %s" +msgid "connected to server" +msgstr "mit Server verbunden" -#: libpq_fetch.c:58 +#: libpq_fetch.c:59 #, c-format -msgid "connected to server\n" -msgstr "mit Server verbunden\n" +msgid "could not clear search_path: %s" +msgstr "konnte search_path nicht auf leer setzen: %s" -#: libpq_fetch.c:68 +#: libpq_fetch.c:71 #, c-format -msgid "source server must not be in recovery mode\n" -msgstr "Quell-Server darf nicht im Wiederherstellungsmodus sein\n" +msgid "source server must not be in recovery mode" +msgstr "Quell-Server darf nicht im Wiederherstellungsmodus sein" -#: libpq_fetch.c:78 +#: libpq_fetch.c:81 #, c-format -msgid "full_page_writes must be enabled in the source server\n" -msgstr "full_page_writes muss im Quell-Server eingeschaltet sein\n" +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes muss im Quell-Server eingeschaltet sein" -#: libpq_fetch.c:90 +#: libpq_fetch.c:93 #, c-format msgid "could not set up connection context: %s" msgstr "konnte Verbindungskontext nicht einrichten: %s" -#: libpq_fetch.c:108 +#: libpq_fetch.c:111 #, c-format msgid "error running query (%s) in source server: %s" msgstr "Fehler beim Ausführen einer Anfrage (%s) im Quellserver: %s" -#: libpq_fetch.c:113 +#: libpq_fetch.c:116 #, c-format -msgid "unexpected result set from query\n" -msgstr "Anfrage ergab unerwartete Ergebnismenge\n" +msgid "unexpected result set from query" +msgstr "Anfrage ergab unerwartete Ergebnismenge" -#: libpq_fetch.c:136 +#: libpq_fetch.c:139 #, c-format -msgid "unrecognized result \"%s\" for current WAL insert location\n" -msgstr "unbekanntes Ergebnis »%s« für aktuelle WAL-Einfügeposition\n" +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "unbekanntes Ergebnis »%s« für aktuelle WAL-Einfügeposition" -#: libpq_fetch.c:186 +#: libpq_fetch.c:189 #, c-format msgid "could not fetch file list: %s" msgstr "konnte Dateiliste nicht holen: %s" -#: libpq_fetch.c:191 +#: libpq_fetch.c:194 #, c-format -msgid "unexpected result set while fetching file list\n" -msgstr "unerwartete Ergebnismenge beim Holen der Dateiliste\n" +msgid "unexpected result set while fetching file list" +msgstr "unerwartete Ergebnismenge beim Holen der Dateiliste" -#: libpq_fetch.c:239 +#: libpq_fetch.c:242 #, c-format msgid "could not send query: %s" msgstr "konnte Anfrage nicht senden: %s" -#: libpq_fetch.c:241 -#, c-format -msgid "getting file chunks\n" -msgstr "hole Dateistücke\n" - -#: libpq_fetch.c:244 +#: libpq_fetch.c:247 #, c-format -msgid "could not set libpq connection to single row mode\n" -msgstr "konnte libpq-Verbindung nicht in den Einzelzeilenmodus setzen\n" +msgid "could not set libpq connection to single row mode" +msgstr "konnte libpq-Verbindung nicht in den Einzelzeilenmodus setzen" -#: libpq_fetch.c:264 +#: libpq_fetch.c:268 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "unerwartetes Ergebnis beim Holen von fernen Dateien: %s" -#: libpq_fetch.c:270 +#: libpq_fetch.c:274 #, c-format -msgid "unexpected result set size while fetching remote files\n" -msgstr "unerwartete Ergebnismengengröße beim Holen von fernen Dateien\n" +msgid "unexpected result set size while fetching remote files" +msgstr "unerwartete Ergebnismengengröße beim Holen von fernen Dateien" -#: libpq_fetch.c:276 +#: libpq_fetch.c:280 #, c-format -msgid "unexpected data types in result set while fetching remote files: %u %u %u\n" -msgstr "unerwartete Datentypen in Ergebnismenge beim Holen von fernen Dateien: %u %u %u\n" +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "unerwartete Datentypen in Ergebnismenge beim Holen von fernen Dateien: %u %u %u" -#: libpq_fetch.c:284 +#: libpq_fetch.c:288 #, c-format -msgid "unexpected result format while fetching remote files\n" -msgstr "unerwartetes Ergebnisformat beim Holen von fernen Dateien\n" - -#: libpq_fetch.c:290 -#, c-format -msgid "unexpected null values in result while fetching remote files\n" -msgstr "unerwartete NULL-Werte im Ergebnis beim Holen von fernen Dateien\n" +msgid "unexpected result format while fetching remote files" +msgstr "unerwartetes Ergebnisformat beim Holen von fernen Dateien" #: libpq_fetch.c:294 #, c-format -msgid "unexpected result length while fetching remote files\n" -msgstr "unerwartete Ergebnislänge beim Holen von fernen Dateien\n" - -#: libpq_fetch.c:316 -#, c-format -msgid "received null value for chunk for file \"%s\", file has been deleted\n" -msgstr "NULL-Wert für Stück von Datei »%s« empfangen, Datei wurde gelöscht\n" +msgid "unexpected null values in result while fetching remote files" +msgstr "unerwartete NULL-Werte im Ergebnis beim Holen von fernen Dateien" -#: libpq_fetch.c:323 +#: libpq_fetch.c:298 #, c-format -msgid "received chunk for file \"%s\", offset %d, size %d\n" -msgstr "Stück von Datei »%s« empfangen, Offset %d, Größe %d\n" +msgid "unexpected result length while fetching remote files" +msgstr "unerwartete Ergebnislänge beim Holen von fernen Dateien" -#: libpq_fetch.c:352 +#: libpq_fetch.c:364 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "konnte ferne Datei »%s« nicht holen: %s" -#: libpq_fetch.c:357 +#: libpq_fetch.c:369 #, c-format -msgid "unexpected result set while fetching remote file \"%s\"\n" -msgstr "unerwartete Ergebnismenge beim Holen der fernen Datei »%s«\n" +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "unerwartete Ergebnismenge beim Holen der fernen Datei »%s«" -#: libpq_fetch.c:368 -#, c-format -msgid "fetched file \"%s\", length %d\n" -msgstr "Datei »%s« geholt, Länge %d\n" - -#: libpq_fetch.c:400 +#: libpq_fetch.c:413 #, c-format msgid "could not send COPY data: %s" msgstr "konnte COPY-Daten nicht senden: %s" -#: libpq_fetch.c:426 +#: libpq_fetch.c:439 #, c-format msgid "could not create temporary table: %s" msgstr "konnte temporäre Tabelle nicht erzeugen: %s" -#: libpq_fetch.c:434 +#: libpq_fetch.c:447 #, c-format msgid "could not send file list: %s" msgstr "konnte Dateiliste nicht senden: %s" -#: libpq_fetch.c:476 +#: libpq_fetch.c:489 #, c-format msgid "could not send end-of-COPY: %s" msgstr "konnte COPY-Ende nicht senden: %s" -#: libpq_fetch.c:482 +#: libpq_fetch.c:495 #, c-format msgid "unexpected result while sending file list: %s" msgstr "unerwartetes Ergebnis beim Senden der Dateiliste: %s" -#: logging.c:57 -msgid "Failure, exiting\n" -msgstr "Fehlgeschlagen, Programm wird beendet\n" - -#: logging.c:140 +#: parsexlog.c:74 parsexlog.c:128 parsexlog.c:186 #, c-format -msgid "%*s/%s kB (%d%%) copied" -msgstr "%*s/%s kB (%d%%) kopiert" +msgid "out of memory" +msgstr "Speicher aufgebraucht" -#: parsexlog.c:87 parsexlog.c:133 +#: parsexlog.c:87 parsexlog.c:134 #, c-format -msgid "could not read WAL record at %X/%X: %s\n" -msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen: %s\n" +msgid "could not read WAL record at %X/%X: %s" +msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen: %s" -#: parsexlog.c:91 parsexlog.c:136 +#: parsexlog.c:91 parsexlog.c:137 #, c-format -msgid "could not read WAL record at %X/%X\n" -msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen\n" +msgid "could not read WAL record at %X/%X" +msgstr "konnte WAL-Eintrag bei %X/%X nicht lesen" -#: parsexlog.c:191 +#: parsexlog.c:198 #, c-format -msgid "could not find previous WAL record at %X/%X: %s\n" -msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden: %s\n" +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden: %s" -#: parsexlog.c:195 +#: parsexlog.c:202 #, c-format -msgid "could not find previous WAL record at %X/%X\n" -msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden\n" +msgid "could not find previous WAL record at %X/%X" +msgstr "konnte vorangegangenen WAL-Eintrag bei %X/%X nicht finden" -#: parsexlog.c:283 +#: parsexlog.c:293 #, c-format -msgid "could not open file \"%s\": %s\n" -msgstr "konnte Datei »%s« nicht öffnen: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "konnte Datei »%s« nicht öffnen: %m" -#: parsexlog.c:297 +#: parsexlog.c:306 #, c-format -msgid "could not seek in file \"%s\": %s\n" -msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %s\n" +msgid "could not seek in file \"%s\": %m" +msgstr "konnte Positionszeiger in Datei »%s« nicht setzen: %m" -#: parsexlog.c:304 +#: parsexlog.c:386 #, c-format -msgid "could not read from file \"%s\": %s\n" -msgstr "konnte nicht aus Datei »%s« nicht lesen: %s\n" +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL-Eintrag modifiziert eine Relation, aber Typ des Eintrags wurde nicht erkannt: lsn: %X/%X, rmgr: %s, info: %02X" -#: parsexlog.c:372 -#, c-format -msgid "" -"WAL record modifies a relation, but record type is not recognized\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" -msgstr "" -"WAL-Eintrag modifiziert eine Relation, aber Typ des Eintrags wurde nicht erkannt\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" - -#: pg_rewind.c:64 +#: pg_rewind.c:72 #, c-format msgid "" "%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" @@ -436,7 +417,7 @@ msgstr "" "%s resynchronisiert einen PostgreSQL-Cluster mit einer Kopie des Clusters.\n" "\n" -#: pg_rewind.c:65 +#: pg_rewind.c:73 #, c-format msgid "" "Usage:\n" @@ -447,416 +428,395 @@ msgstr "" " %s [OPTION]...\n" "\n" -#: pg_rewind.c:66 +#: pg_rewind.c:74 #, c-format msgid "Options:\n" msgstr "Optionen:\n" -#: pg_rewind.c:67 +#: pg_rewind.c:75 #, c-format msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" msgstr " -D, --target-pgdata=VERZ bestehendes zu modifizierendes Datenverzeichnis\n" -#: pg_rewind.c:68 +#: pg_rewind.c:76 #, c-format msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" msgstr "" " --source-pgdata=VERZ Quelldatenverzeichnis, mit dem synchronisiert\n" " werden soll\n" -#: pg_rewind.c:69 +#: pg_rewind.c:77 #, c-format msgid " --source-server=CONNSTR source server to synchronize with\n" msgstr " --source-server=VERB Quellserver, mit dem synchronisiert werden soll\n" -#: pg_rewind.c:70 +#: pg_rewind.c:78 #, c-format msgid " -n, --dry-run stop before modifying anything\n" msgstr " -n, --dry-run anhalten, bevor etwas geändert wird\n" -#: pg_rewind.c:71 +#: pg_rewind.c:79 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n" +" geschrieben sind\n" + +#: pg_rewind.c:81 #, c-format msgid " -P, --progress write progress messages\n" msgstr " -P, --progress Fortschrittsmeldungen ausgeben\n" -#: pg_rewind.c:72 +#: pg_rewind.c:82 #, c-format msgid " --debug write a lot of debug messages\n" msgstr " --debug viele Debug-Meldungen ausgeben\n" -#: pg_rewind.c:73 +#: pg_rewind.c:83 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_rewind.c:74 +#: pg_rewind.c:84 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_rewind.c:75 +#: pg_rewind.c:85 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Berichten Sie Fehler an .\n" +"Berichten Sie Fehler an .\n" -#: pg_rewind.c:130 pg_rewind.c:161 pg_rewind.c:168 pg_rewind.c:175 -#: pg_rewind.c:183 +#: pg_rewind.c:142 pg_rewind.c:178 pg_rewind.c:185 pg_rewind.c:192 +#: pg_rewind.c:200 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: pg_rewind.c:160 +#: pg_rewind.c:177 #, c-format -msgid "%s: no source specified (--source-pgdata or --source-server)\n" -msgstr "%s: keine Quelle angegeben (--source-pgdata oder --source-server)\n" +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "keine Quelle angegeben (--source-pgdata oder --source-server)" -#: pg_rewind.c:167 +#: pg_rewind.c:184 #, c-format -msgid "%s: only one of --source-pgdata or --source-server can be specified\n" -msgstr "%s: --source-pgdata und --source-server können nicht zusammen angegeben werden\n" +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "--source-pgdata und --source-server können nicht zusammen angegeben werden" -#: pg_rewind.c:174 +#: pg_rewind.c:191 #, c-format -msgid "%s: no target data directory specified (--target-pgdata)\n" -msgstr "%s: kein Zielverzeichnis angegeben (--target-pgdata)\n" +msgid "no target data directory specified (--target-pgdata)" +msgstr "kein Zielverzeichnis angegeben (--target-pgdata)" -#: pg_rewind.c:181 +#: pg_rewind.c:198 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: pg_rewind.c:196 +#: pg_rewind.c:213 #, c-format -msgid "cannot be executed by \"root\"\n" -msgstr "kann nicht von »root« ausgeführt werden\n" +msgid "cannot be executed by \"root\"" +msgstr "kann nicht von »root« ausgeführt werden" -#: pg_rewind.c:197 +#: pg_rewind.c:214 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "Sie müssen %s als PostgreSQL-Superuser ausführen.\n" -#: pg_rewind.c:228 +#: pg_rewind.c:225 #, c-format -msgid "source and target cluster are on the same timeline\n" -msgstr "Quell- und Ziel-Cluster sind auf der gleichen Zeitleiste\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %m" -#: pg_rewind.c:234 +#: pg_rewind.c:256 #, c-format -msgid "servers diverged at WAL location %X/%X on timeline %u\n" -msgstr "Server divergierten bei WAL-Position %X/%X auf Zeitleiste %u\n" +msgid "source and target cluster are on the same timeline" +msgstr "Quell- und Ziel-Cluster sind auf der gleichen Zeitleiste" -#: pg_rewind.c:271 +#: pg_rewind.c:262 #, c-format -msgid "no rewind required\n" -msgstr "kein Rückspulen nötig\n" +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "Server divergierten bei WAL-Position %X/%X auf Zeitleiste %u" -#: pg_rewind.c:278 +#: pg_rewind.c:299 #, c-format -msgid "rewinding from last common checkpoint at %X/%X on timeline %u\n" -msgstr "Rückspulen ab letztem gemeinsamen Checkpoint bei %X/%X auf Zeitleiste %u\n" +msgid "no rewind required" +msgstr "kein Rückspulen nötig" -#: pg_rewind.c:286 +#: pg_rewind.c:306 #, c-format -msgid "reading source file list\n" -msgstr "lese Quelldateiliste\n" - -#: pg_rewind.c:288 -#, c-format -msgid "reading target file list\n" -msgstr "lese Zieldateiliste\n" - -#: pg_rewind.c:298 -#, c-format -msgid "reading WAL in target\n" -msgstr "lese WAL im Ziel-Cluster\n" +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "Rückspulen ab letztem gemeinsamen Checkpoint bei %X/%X auf Zeitleiste %u" #: pg_rewind.c:315 #, c-format -msgid "need to copy %lu MB (total source directory size is %lu MB)\n" -msgstr "%lu MB müssen kopiert werden (Gesamtgröße des Quellverzeichnisses ist %lu MB)\n" - -#: pg_rewind.c:332 -#, c-format -msgid "" -"\n" -"creating backup label and updating control file\n" -msgstr "" -"\n" -"erzeuge Backup-Label und aktualisiere Kontrolldatei\n" +msgid "reading source file list" +msgstr "lese Quelldateiliste" -#: pg_rewind.c:360 +#: pg_rewind.c:318 #, c-format -msgid "syncing target data directory\n" -msgstr "synchronisiere Zieldatenverzeichnis\n" +msgid "reading target file list" +msgstr "lese Zieldateiliste" -#: pg_rewind.c:363 +#: pg_rewind.c:329 #, c-format -msgid "Done!\n" -msgstr "Fertig!\n" +msgid "reading WAL in target" +msgstr "lese WAL im Ziel-Cluster" -#: pg_rewind.c:375 +#: pg_rewind.c:346 #, c-format -msgid "source and target clusters are from different systems\n" -msgstr "Quell- und Ziel-Cluster sind von verschiedenen Systemen\n" +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "%lu MB müssen kopiert werden (Gesamtgröße des Quellverzeichnisses ist %lu MB)" -#: pg_rewind.c:383 +#: pg_rewind.c:365 #, c-format -msgid "clusters are not compatible with this version of pg_rewind\n" -msgstr "die Cluster sind nicht mit dieser Version von pg_rewind kompatibel\n" +msgid "creating backup label and updating control file" +msgstr "erzeuge Backup-Label und aktualisiere Kontrolldatei" -#: pg_rewind.c:393 +#: pg_rewind.c:394 #, c-format -msgid "target server needs to use either data checksums or \"wal_log_hints = on\"\n" -msgstr "Zielserver muss entweder Datenprüfsummen oder »wal_log_hints = on« verwenden\n" +msgid "syncing target data directory" +msgstr "synchronisiere Zieldatenverzeichnis" -#: pg_rewind.c:404 +#: pg_rewind.c:397 #, c-format -msgid "target server must be shut down cleanly\n" -msgstr "Zielserver muss sauber heruntergefahren worden sein\n" +msgid "Done!" +msgstr "Fertig!" -#: pg_rewind.c:414 +#: pg_rewind.c:409 #, c-format -msgid "source data directory must be shut down cleanly\n" -msgstr "Quelldatenverzeichnis muss sauber heruntergefahren worden sein\n" +msgid "source and target clusters are from different systems" +msgstr "Quell- und Ziel-Cluster sind von verschiedenen Systemen" -#: pg_rewind.c:469 +#: pg_rewind.c:417 #, c-format -msgid "invalid control file" -msgstr "ungültige Kontrolldatei" +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "die Cluster sind nicht mit dieser Version von pg_rewind kompatibel" -#: pg_rewind.c:480 +#: pg_rewind.c:427 #, c-format -msgid "Source timeline history:\n" -msgstr "Verlauf der Quellzeitleiste:\n" +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "Zielserver muss entweder Datenprüfsummen oder »wal_log_hints = on« verwenden" -#: pg_rewind.c:482 +#: pg_rewind.c:438 #, c-format -msgid "Target timeline history:\n" -msgstr "Verlauf der Zielzeitleiste:\n" +msgid "target server must be shut down cleanly" +msgstr "Zielserver muss sauber heruntergefahren worden sein" -#. translator: %d is a timeline number, others are LSN positions -#: pg_rewind.c:496 +#: pg_rewind.c:448 #, c-format -msgid "%d: %X/%X - %X/%X\n" -msgstr "%d: %X/%X - %X/%X\n" +msgid "source data directory must be shut down cleanly" +msgstr "Quelldatenverzeichnis muss sauber heruntergefahren worden sein" -#: pg_rewind.c:555 +#: pg_rewind.c:497 #, c-format -msgid "could not find common ancestor of the source and target cluster's timelines\n" -msgstr "konnte keinen gemeinsamen Anfangspunkt in den Zeitleisten von Quell- und Ziel-Cluster finden\n" +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) kopiert" -#: pg_rewind.c:596 +#: pg_rewind.c:558 #, c-format -msgid "backup label buffer too small\n" -msgstr "Puffer für Backup-Label ist zu klein\n" +msgid "invalid control file\n" +msgstr "ungültige Kontrolldatei\n" -#: pg_rewind.c:619 +#: pg_rewind.c:642 #, c-format -msgid "unexpected control file CRC\n" -msgstr "unerwartete CRC in Kontrolldatei\n" +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "konnte keinen gemeinsamen Anfangspunkt in den Zeitleisten von Quell- und Ziel-Cluster finden" -#: pg_rewind.c:629 +#: pg_rewind.c:683 #, c-format -msgid "unexpected control file size %d, expected %d\n" -msgstr "unerwartete Kontrolldateigröße %d, erwartet wurde %d\n" +msgid "backup label buffer too small" +msgstr "Puffer für Backup-Label ist zu klein" -#: pg_rewind.c:696 +#: pg_rewind.c:706 #, c-format -msgid "" -"The program \"initdb\" is needed by %s but was\n" -"not found in the same directory as \"%s\".\n" -"Check your installation.\n" -msgstr "" -"Das Programm »initdb« wird von %s benötigt, aber wurde nicht im\n" -"selben Verzeichnis wie »%s« gefunden.\n" -"Prüfen Sie Ihre Installation.\n" +msgid "unexpected control file CRC" +msgstr "unerwartete CRC in Kontrolldatei" -#: pg_rewind.c:700 +#: pg_rewind.c:716 #, c-format -msgid "" -"The program \"initdb\" was found by \"%s\"\n" -"but was not the same version as %s.\n" -"Check your installation.\n" -msgstr "" -"Das Programm »initdb« wurde von %s gefunden,\n" -"aber es hatte nicht die gleiche Version wie %s.\n" -"Prüfen Sie Ihre Installation.\n" +msgid "unexpected control file size %d, expected %d" +msgstr "unerwartete Kontrolldateigröße %d, erwartet wurde %d" -#: pg_rewind.c:718 +#: pg_rewind.c:725 #, c-format -msgid "sync of target directory failed\n" -msgstr "Synchronisieren des Zielverzeichnisses fehlgeschlagen\n" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber die Kontrolldatei gibt %d Bytes an" #: timeline.c:76 timeline.c:82 #, c-format -msgid "syntax error in history file: %s\n" -msgstr "Syntaxfehler in History-Datei: %s\n" +msgid "syntax error in history file: %s" +msgstr "Syntaxfehler in History-Datei: %s" #: timeline.c:77 #, c-format -msgid "Expected a numeric timeline ID.\n" -msgstr "Eine numerische Zeitleisten-ID wurde erwartet.\n" +msgid "Expected a numeric timeline ID." +msgstr "Eine numerische Zeitleisten-ID wurde erwartet." #: timeline.c:83 #, c-format -msgid "Expected a write-ahead log switchpoint location.\n" -msgstr "Eine Write-Ahead-Log-Switchpoint-Position wurde erwartet.\n" +msgid "Expected a write-ahead log switchpoint location." +msgstr "Eine Write-Ahead-Log-Switchpoint-Position wurde erwartet." #: timeline.c:88 #, c-format -msgid "invalid data in history file: %s\n" -msgstr "ungültige Daten in History-Datei: %s\n" +msgid "invalid data in history file: %s" +msgstr "ungültige Daten in History-Datei: %s" #: timeline.c:89 #, c-format -msgid "Timeline IDs must be in increasing sequence.\n" -msgstr "Zeitleisten-IDs müssen in aufsteigender Folge sein.\n" +msgid "Timeline IDs must be in increasing sequence." +msgstr "Zeitleisten-IDs müssen in aufsteigender Folge sein." #: timeline.c:109 #, c-format -msgid "invalid data in history file\n" -msgstr "ungültige Daten in History-Datei\n" +msgid "invalid data in history file" +msgstr "ungültige Daten in History-Datei" #: timeline.c:110 #, c-format -msgid "Timeline IDs must be less than child timeline's ID.\n" -msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein.\n" +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Zeitleisten-IDs müssen kleiner als die Zeitleisten-ID des Kindes sein." -#: xlogreader.c:276 +#: xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "ungültiger Datensatz-Offset bei %X/%X" -#: xlogreader.c:284 +#: xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "Contrecord angefordert von %X/%X" -#: xlogreader.c:325 xlogreader.c:625 +#: xlogreader.c:348 xlogreader.c:645 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "ungültige Datensatzlänge bei %X/%X: %u erwartet, %u erhalten" -#: xlogreader.c:340 +#: xlogreader.c:372 #, c-format msgid "record length %u at %X/%X too long" msgstr "Datensatzlänge %u bei %X/%X ist zu lang" -#: xlogreader.c:381 +#: xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "keine Contrecord-Flag bei %X/%X" -#: xlogreader.c:394 +#: xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "ungültige Contrecord-Länge %u bei %X/%X" -#: xlogreader.c:633 +#: xlogreader.c:653 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ungültige Resource-Manager-ID %u bei %X/%X" -#: xlogreader.c:647 xlogreader.c:664 +#: xlogreader.c:667 xlogreader.c:684 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "Datensatz mit falschem Prev-Link %X/%X bei %X/%X" -#: xlogreader.c:701 +#: xlogreader.c:721 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "ungültige Resource-Manager-Datenprüfsumme in Datensatz bei %X/%X" -#: xlogreader.c:734 +#: xlogreader.c:758 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "ungültige magische Zahl %04X in Logsegment %s, Offset %u" -#: xlogreader.c:748 xlogreader.c:799 +#: xlogreader.c:772 xlogreader.c:823 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "ungültige Info-Bits %04X in Logsegment %s, Offset %u" -#: xlogreader.c:774 +#: xlogreader.c:798 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Datenbanksystemidentifikator in WAL-Datei ist %s, Datenbanksystemidentifikator in pg_control ist %s" -#: xlogreader.c:781 +#: xlogreader.c:805 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Falsche XLOG_SEG_SIZE im Seitenkopf" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche Segmentgröße im Seitenkopf" -#: xlogreader.c:787 +#: xlogreader.c:811 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" -msgstr "WAL-Datei ist von einem anderen Datenbanksystem: Falsche XLOG_BLCKSZ im Seitenkopf" +msgstr "WAL-Datei ist von einem anderen Datenbanksystem: falsche XLOG_BLCKSZ im Seitenkopf" -#: xlogreader.c:813 +#: xlogreader.c:842 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "unerwartete Pageaddr %X/%X in Logsegment %s, Offset %u" -#: xlogreader.c:838 +#: xlogreader.c:867 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "Zeitleisten-ID %u außer der Reihe (nach %u) in Logsegment %s, Offset %u" -#: xlogreader.c:1083 +#: xlogreader.c:1112 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u außer der Reihe bei %X/%X" -#: xlogreader.c:1106 +#: xlogreader.c:1135 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA gesetzt, aber keine Daten enthalten bei %X/%X" -#: xlogreader.c:1113 +#: xlogreader.c:1142 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA nicht gesetzt, aber Datenlänge ist %u bei %X/%X" -#: xlogreader.c:1149 +#: xlogreader.c:1178 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE gesetzt, aber Loch Offset %u Länge %u Block-Abbild-Länge %u bei %X/%X" -#: xlogreader.c:1165 +#: xlogreader.c:1194 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE nicht gesetzt, aber Loch Offset %u Länge %u bei %X/%X" -#: xlogreader.c:1180 +#: xlogreader.c:1209 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge %u bei %X/%X" -#: xlogreader.c:1195 +#: xlogreader.c:1224 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "weder BKPIMAGE_HAS_HOLE noch BKPIMAGE_IS_COMPRESSED gesetzt, aber Block-Abbild-Länge ist %u bei %X/%X" -#: xlogreader.c:1211 +#: xlogreader.c:1240 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL gesetzt, aber keine vorangehende Relation bei %X/%X" -#: xlogreader.c:1223 +#: xlogreader.c:1252 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "ungültige block_id %u bei %X/%X" -#: xlogreader.c:1291 +#: xlogreader.c:1341 #, c-format msgid "record with invalid length at %X/%X" msgstr "Datensatz mit ungültiger Länge bei %X/%X" -#: xlogreader.c:1380 +#: xlogreader.c:1430 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "ungültiges komprimiertes Abbild bei %X/%X, Block %d" diff --git a/src/bin/pg_rewind/po/es.po b/src/bin/pg_rewind/po/es.po index b33bd65fe8d..3b6cd92ef57 100644 --- a/src/bin/pg_rewind/po/es.po +++ b/src/bin/pg_rewind/po/es.po @@ -1,24 +1,43 @@ # Spanish message translation file for pg_rewind -# Copyright (C) 2015 PostgreSQL Global Development Group +# +# Copyright (c) 2015-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. +# # Ãlvaro Herrera , 2015. +# Carlos Chapi , 2017. # msgid "" msgstr "" -"Project-Id-Version: pg_rewind (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-11 11:25-0500\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL Español \n" +"Project-Id-Version: pg_rewind (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:15+0000\n" +"PO-Revision-Date: 2019-06-06 17:24-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 parsexlog.c:179 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "memoria agotada\n" @@ -28,406 +47,372 @@ msgstr "memoria agotada\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "no se puede duplicar un puntero nulo (error interno)\n" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:69 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: ATENCIÓN: no se pueden crear tokens restrigidos en esta plataforma\n" +msgid "cannot create restricted tokens on this platform" +msgstr "no se pueden crear tokens restrigidos en esta plataforma" -#: ../../common/restricted_token.c:77 +#: ../../common/restricted_token.c:78 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: no se pudo abrir el token de proceso: código de error %lu\n" +msgid "could not open process token: error code %lu" +msgstr "no se pudo abrir el token de proceso: código de error %lu" -#: ../../common/restricted_token.c:90 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: no se pudo emplazar los SIDs: código de error %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "no se pudo emplazar los SIDs: código de error %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: no se pudo crear el token restringido: código de error %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "no se pudo crear el token restringido: código de error %lu" -#: ../../common/restricted_token.c:132 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: no se pudo iniciar el proceso para la orden «%s»: código de error %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "no se pudo iniciar el proceso para la orden «%s»: código de error %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: no se pudo re-ejecutar con el token restringido: código de error %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "no se pudo re-ejecutar con el token restringido: código de error %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:185 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: no se pudo obtener el código de salida del subproceso»: código de error %lu\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "no se pudo obtener el código de salida del subproceso»: código de error %lu" -#: copy_fetch.c:62 +#: copy_fetch.c:59 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "no se pudo abrir el directorio «%s»: %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: copy_fetch.c:91 filemap.c:111 filemap.c:266 +#: copy_fetch.c:88 filemap.c:187 filemap.c:348 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "no se pudo hacer stat del archivo «%s»: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" -#: copy_fetch.c:120 +#: copy_fetch.c:117 #, c-format -msgid "could not read symbolic link \"%s\": %s\n" -msgstr "no se pudo leer link simbólico «%s»: %s\n" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: copy_fetch.c:123 +#: copy_fetch.c:120 #, c-format -msgid "symbolic link \"%s\" target is too long\n" -msgstr "el destino del link simbólico «%s» es demasiado largo\n" +msgid "symbolic link \"%s\" target is too long" +msgstr "la ruta «%s» del enlace simbólico es demasiado larga" -#: copy_fetch.c:138 +#: copy_fetch.c:135 #, c-format -msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform\n" -msgstr "«%s» es un link simbólico, pero los links simbólicos no están soportados en esta plataforma\n" +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "«%s» es un link simbólico, pero los links simbólicos no están soportados en esta plataforma" -#: copy_fetch.c:145 +#: copy_fetch.c:142 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "no se pudo leer el directorio «%s»: %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "no se pudo leer el directorio «%s»: %m" -#: copy_fetch.c:149 +#: copy_fetch.c:146 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "no se pudo cerrar el directorio «%s»: %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "no se pudo abrir el directorio «%s»: %m" -#: copy_fetch.c:169 +#: copy_fetch.c:166 #, c-format -msgid "could not open source file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo de origen «%s»: %s\n" +msgid "could not open source file \"%s\": %m" +msgstr "no se pudo abrir el archivo de origen «%s»: %m" -#: copy_fetch.c:173 +#: copy_fetch.c:170 #, c-format -msgid "could not seek in source file: %s\n" -msgstr "no se pudo posicionar en archivo de origen: %s\n" +msgid "could not seek in source file: %m" +msgstr "no se pudo posicionar en archivo de origen: %m" -#: copy_fetch.c:190 file_ops.c:299 +#: copy_fetch.c:187 file_ops.c:311 parsexlog.c:315 #, c-format -msgid "could not read file \"%s\": %s\n" -msgstr "no se pudo leer el archivo «%s»: %s\n" +msgid "could not read file \"%s\": %m" +msgstr "no se pudo leer el archivo «%s»: %m" -#: copy_fetch.c:193 +#: copy_fetch.c:190 #, c-format -msgid "unexpected EOF while reading file \"%s\"\n" -msgstr "EOF inesperado mientras se leía el archivo «%s»\n" +msgid "unexpected EOF while reading file \"%s\"" +msgstr "EOF inesperado mientras se leía el archivo «%s»" -#: copy_fetch.c:200 +#: copy_fetch.c:197 #, c-format -msgid "could not close file \"%s\": %s\n" -msgstr "no se pudo cerrar el archivo «%s»: %s\n" +msgid "could not close file \"%s\": %m" +msgstr "no se pudo cerrar el archivo «%s»: %m" -#: datapagemap.c:124 +#: file_ops.c:62 #, c-format -msgid " block %u\n" -msgstr " bloque %u\n" +msgid "could not open target file \"%s\": %m" +msgstr "no se pudo abrir el archivo de destino «%s»: %m" -#: file_ops.c:63 +#: file_ops.c:76 #, c-format -msgid "could not open target file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo de destino «%s»: %s\n" +msgid "could not close target file \"%s\": %m" +msgstr "no se pudo cerrar el archivo de destino «%s»: %m" -#: file_ops.c:77 +#: file_ops.c:96 #, c-format -msgid "could not close target file \"%s\": %s\n" -msgstr "no se pudo cerrar el archivo de destino «%s»: %s\n" +msgid "could not seek in target file \"%s\": %m" +msgstr "no se pudo posicionar en archivo de destino «%s»: %m" -#: file_ops.c:97 +#: file_ops.c:112 #, c-format -msgid "could not seek in target file \"%s\": %s\n" -msgstr "no se pudo posicionar en archivo de destino «%s»: %s\n" +msgid "could not write file \"%s\": %m" +msgstr "no se pudo escribir el archivo «%s»: %m" -#: file_ops.c:113 +#: file_ops.c:162 #, c-format -msgid "could not write file \"%s\": %s\n" -msgstr "no se pudo escribir el archivo «%s»: %s\n" +msgid "invalid action (CREATE) for regular file" +msgstr "acción no válida (CREATE) para archivo regular" -#: file_ops.c:163 +#: file_ops.c:185 #, c-format -msgid "invalid action (CREATE) for regular file\n" -msgstr "acción no válida (CREATE) para archivo regular\n" +msgid "could not remove file \"%s\": %m" +msgstr "no se pudo eliminar el archivo «%s»: %m" -#: file_ops.c:178 +#: file_ops.c:203 #, c-format -msgid "could not remove file \"%s\": %s\n" -msgstr "no se pudo eliminar el archivo «%s»: %s\n" +msgid "could not open file \"%s\" for truncation: %m" +msgstr "no se pudo abrir el archivo «%s» para truncarlo: %m" -#: file_ops.c:195 +#: file_ops.c:207 #, c-format -msgid "could not open file \"%s\" for truncation: %s\n" -msgstr "no se pudo abrir el archivo «%s» para truncarlo: %s\n" +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "no se pudo truncar el archivo «%s» a %u: %m" -#: file_ops.c:199 +#: file_ops.c:223 #, c-format -msgid "could not truncate file \"%s\" to %u: %s\n" -msgstr "no se pudo truncar el archivo «%s» a %u: %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "no se pudo crear el directorio «%s»: %m" -#: file_ops.c:215 +#: file_ops.c:237 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "no se pudo crear el directorio «%s»: %s\n" +msgid "could not remove directory \"%s\": %m" +msgstr "no se pudo eliminar el directorio «%s»: %m" -#: file_ops.c:229 +#: file_ops.c:251 #, c-format -msgid "could not remove directory \"%s\": %s\n" -msgstr "no se pudo eliminar el directorio «%s»: %s\n" +msgid "could not create symbolic link at \"%s\": %m" +msgstr "no se pudo crear el link simbólico en «%s»: %m" -#: file_ops.c:243 +#: file_ops.c:265 #, c-format -msgid "could not create symbolic link at \"%s\": %s\n" -msgstr "no se pudo crear el link simbólico en «%s»: %s\n" +msgid "could not remove symbolic link \"%s\": %m" +msgstr "no se pudo eliminar el enlace simbólico «%s»: %m" -#: file_ops.c:257 +#: file_ops.c:296 file_ops.c:300 #, c-format -msgid "could not remove symbolic link \"%s\": %s\n" -msgstr "no se pudo eliminar el link simbólico «%s»: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "no se pudo abrir archivo «%s» para lectura: %m" -#: file_ops.c:287 file_ops.c:291 +#: file_ops.c:314 parsexlog.c:317 #, c-format -msgid "could not open file \"%s\" for reading: %s\n" -msgstr "no se pudo abrir el archivo «%s» para lectura: %s\n" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" -#: filemap.c:103 +#: filemap.c:179 #, c-format -msgid "data file \"%s\" in source is not a regular file\n" -msgstr "el archivo de datos «%s» en el origen no es un archivo regular\n" +msgid "data file \"%s\" in source is not a regular file" +msgstr "el archivo de datos «%s» en el origen no es un archivo regular" -#: filemap.c:125 +#: filemap.c:201 #, c-format -msgid "\"%s\" is not a directory\n" -msgstr "«%s» no es un directorio\n" +msgid "\"%s\" is not a directory" +msgstr "«%s» no es un directorio" -#: filemap.c:148 +#: filemap.c:224 #, c-format -msgid "\"%s\" is not a symbolic link\n" -msgstr "«%s» no es un link simbólico\n" +msgid "\"%s\" is not a symbolic link" +msgstr "«%s» no es un link simbólico" -#: filemap.c:160 +#: filemap.c:236 #, c-format -msgid "\"%s\" is not a regular file\n" -msgstr "«%s» no es un archivo regular\n" +msgid "\"%s\" is not a regular file" +msgstr "«%s» no es un archivo regular" -#: filemap.c:278 +#: filemap.c:360 #, c-format -msgid "source file list is empty\n" -msgstr "el listado de archivos de origen está vacío\n" +msgid "source file list is empty" +msgstr "el listado de archivos de origen está vacío" -#: filemap.c:400 +#: filemap.c:475 #, c-format -msgid "unexpected page modification for directory or symbolic link \"%s\"\n" -msgstr "modificación de página inesperada para el directorio o link simbólico «%s»\n" +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "modificación de página inesperada para el directorio o link simbólico «%s»" -#. translator: first %s is a file path, second is a keyword such as COPY -#: filemap.c:536 +#: libpq_fetch.c:51 #, c-format -msgid "%s (%s)\n" -msgstr "%s (%s)\n" +msgid "could not connect to server: %s" +msgstr "no se pudo conectar al servidor: %s" #: libpq_fetch.c:55 #, c-format -msgid "could not connect to server: %s" -msgstr "no se pudo conectar al servidor: %s" +msgid "connected to server" +msgstr "conectado al servidor" -#: libpq_fetch.c:58 +#: libpq_fetch.c:59 #, c-format -msgid "connected to server\n" -msgstr "conectado al servidor\n" +msgid "could not clear search_path: %s" +msgstr "no se pudo limpiar search_path: %s" -#: libpq_fetch.c:68 +#: libpq_fetch.c:71 #, c-format -msgid "source server must not be in recovery mode\n" -msgstr "el servidor de origen no debe estar en modo de recuperación\n" +msgid "source server must not be in recovery mode" +msgstr "el servidor de origen no debe estar en modo de recuperación" -#: libpq_fetch.c:78 +#: libpq_fetch.c:81 #, c-format -msgid "full_page_writes must be enabled in the source server\n" -msgstr "full_page_writes debe estar activado en el servidor de origen\n" +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes debe estar activado en el servidor de origen" -#: libpq_fetch.c:90 +#: libpq_fetch.c:93 #, c-format msgid "could not set up connection context: %s" msgstr "no se pudo establecer el contexto de conexión: %s" -#: libpq_fetch.c:108 +#: libpq_fetch.c:111 #, c-format msgid "error running query (%s) in source server: %s" msgstr "error ejecutando consulta (%s) en el servidor de origen: %s" -#: libpq_fetch.c:113 +#: libpq_fetch.c:116 #, c-format -msgid "unexpected result set from query\n" -msgstr "conjunto de resultados inesperados de la consulta\n" +msgid "unexpected result set from query" +msgstr "conjunto de resultados inesperados de la consulta" -#: libpq_fetch.c:136 +#: libpq_fetch.c:139 #, c-format -msgid "unrecognized result \"%s\" for current WAL insert location\n" -msgstr "resultado «%s» no reconocido para la ubicación de inserción WAL actual\n" +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "resultado «%s» no reconocido para la ubicación de inserción WAL actual" -#: libpq_fetch.c:186 +#: libpq_fetch.c:189 #, c-format msgid "could not fetch file list: %s" msgstr "no se pudo obtener el listado de archivos: %s" -#: libpq_fetch.c:191 +#: libpq_fetch.c:194 #, c-format -msgid "unexpected result set while fetching file list\n" -msgstr "conjunto de resultados inesperado mientras se obtenía el listado de archivos\n" +msgid "unexpected result set while fetching file list" +msgstr "conjunto de resultados inesperado mientras se obtenía el listado de archivos" -#: libpq_fetch.c:239 +#: libpq_fetch.c:242 #, c-format msgid "could not send query: %s" msgstr "no se pudo enviar la consulta: %s" -#: libpq_fetch.c:241 +#: libpq_fetch.c:247 #, c-format -msgid "getting file chunks\n" -msgstr "obteniendo trozos de archivos\n" +msgid "could not set libpq connection to single row mode" +msgstr "no se pudo establecer la coneción libpq a modo «single row»" -#: libpq_fetch.c:244 -#, c-format -msgid "could not set libpq connection to single row mode\n" -msgstr "no se pudo establecer la coneción libpq a modo «single row»\n" - -#: libpq_fetch.c:264 +#: libpq_fetch.c:268 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "resultados inesperados mientras se obtenían archivos remotos: %s" -#: libpq_fetch.c:270 -#, c-format -msgid "unexpected result set size while fetching remote files\n" -msgstr "tamaño del conjunto de resultados inesperado mientras se obtenían archivos remotos\n" - -#: libpq_fetch.c:276 +#: libpq_fetch.c:274 #, c-format -msgid "unexpected data types in result set while fetching remote files: %u %u %u\n" -msgstr "tipos de dato inesperados en el conjunto de resultados mientras se obtenían archivos remotos: %u %u %u\n" +msgid "unexpected result set size while fetching remote files" +msgstr "tamaño del conjunto de resultados inesperado mientras se obtenían archivos remotos" -#: libpq_fetch.c:284 +#: libpq_fetch.c:280 #, c-format -msgid "unexpected result format while fetching remote files\n" -msgstr "formato de resultados inesperado mientras se obtenían archivos remotos\n" +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "tipos de dato inesperados en el conjunto de resultados mientras se obtenían archivos remotos: %u %u %u" -#: libpq_fetch.c:290 +#: libpq_fetch.c:288 #, c-format -msgid "unexpected null values in result while fetching remote files\n" -msgstr "valores nulos inesperados en el resultado mientras se obtenían archivos remotos\n" +msgid "unexpected result format while fetching remote files" +msgstr "formato de resultados inesperado mientras se obtenían archivos remotos" #: libpq_fetch.c:294 #, c-format -msgid "unexpected result length while fetching remote files\n" -msgstr "largo del resultado inesperado mientras se obtenían los archivos remotos\n" +msgid "unexpected null values in result while fetching remote files" +msgstr "valores nulos inesperados en el resultado mientras se obtenían archivos remotos" -#: libpq_fetch.c:316 +#: libpq_fetch.c:298 #, c-format -msgid "received null value for chunk for file \"%s\", file has been deleted\n" -msgstr "recibido un valor NULL para un trozo del archivo «%s», el archivo ha sido borrado\n" +msgid "unexpected result length while fetching remote files" +msgstr "largo del resultado inesperado mientras se obtenían los archivos remotos" -#: libpq_fetch.c:323 -#, c-format -msgid "received chunk for file \"%s\", offset %d, size %d\n" -msgstr "recibido un trozo para el archivo «%s», posición %d, tamaño %d\n" - -#: libpq_fetch.c:352 +#: libpq_fetch.c:364 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "no se pudo obtener el archivo remoto «%s»: %s" -#: libpq_fetch.c:357 -#, c-format -msgid "unexpected result set while fetching remote file \"%s\"\n" -msgstr "conjunto de resultados inesperado mientras se obtenía el archivo remoto «%s»\n" - -#: libpq_fetch.c:368 +#: libpq_fetch.c:369 #, c-format -msgid "fetched file \"%s\", length %d\n" -msgstr "obtenido archivo «%s», largo %d\n" +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "conjunto de resultados inesperado mientras se obtenía el archivo remoto «%s»" -#: libpq_fetch.c:400 +#: libpq_fetch.c:413 #, c-format msgid "could not send COPY data: %s" msgstr "no se pudo enviar datos COPY: %s" -#: libpq_fetch.c:426 +#: libpq_fetch.c:439 #, c-format msgid "could not create temporary table: %s" msgstr "no se pudo crear tabla temporal: %s" -#: libpq_fetch.c:434 +#: libpq_fetch.c:447 #, c-format msgid "could not send file list: %s" msgstr "no se pudo enviar el listado de archivos: %s" -#: libpq_fetch.c:476 +#: libpq_fetch.c:489 #, c-format msgid "could not send end-of-COPY: %s" msgstr "no se pudo enviar fin-de-COPY: %s" -#: libpq_fetch.c:482 +#: libpq_fetch.c:495 #, c-format msgid "unexpected result while sending file list: %s" msgstr "resultados inesperados mientras se enviaba el listado de archivos: %s" -#: logging.c:57 -msgid "Failure, exiting\n" -msgstr "Falló, saliendo\n" - -#: logging.c:140 +#: parsexlog.c:74 parsexlog.c:128 parsexlog.c:186 #, c-format -msgid "%*s/%s kB (%d%%) copied" -msgstr "%*s/%s kB (%d%%) copiados" +msgid "out of memory" +msgstr "memoria agotada" -#: parsexlog.c:87 parsexlog.c:133 +#: parsexlog.c:87 parsexlog.c:134 #, c-format -msgid "could not read WAL record at %X/%X: %s\n" -msgstr "no se pudo leer el registro WAL en %X/%X: %s\n" +msgid "could not read WAL record at %X/%X: %s" +msgstr "no se pudo leer el registro WAL en %X/%X: %s" -#: parsexlog.c:91 parsexlog.c:136 +#: parsexlog.c:91 parsexlog.c:137 #, c-format -msgid "could not read WAL record at %X/%X\n" -msgstr "no se pudo leer el registro WAL en %X/%X\n" +msgid "could not read WAL record at %X/%X" +msgstr "no se pudo leer el registro WAL en %X/%X" -#: parsexlog.c:191 +#: parsexlog.c:198 #, c-format -msgid "could not find previous WAL record at %X/%X: %s\n" -msgstr "no se pudo encontrar el registro WAL anterior en %X/%X: %s\n" +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "no se pudo encontrar el registro WAL anterior en %X/%X: %s" -#: parsexlog.c:195 +#: parsexlog.c:202 #, c-format -msgid "could not find previous WAL record at %X/%X\n" -msgstr "no se pudo encontrar el registro WAL anterior en %X/%X\n" +msgid "could not find previous WAL record at %X/%X" +msgstr "no se pudo encontrar el registro WAL anterior en %X/%X" -#: parsexlog.c:283 +#: parsexlog.c:293 #, c-format -msgid "could not open file \"%s\": %s\n" -msgstr "no se pudo abrir el archivo «%s»: %s\n" +msgid "could not open file \"%s\": %m" +msgstr "no se pudo abrir el archivo «%s»: %m" -#: parsexlog.c:297 +#: parsexlog.c:306 #, c-format -msgid "could not seek in file \"%s\": %s\n" -msgstr "no se pudo posicionar en archivo «%s»: %s\n" +msgid "could not seek in file \"%s\": %m" +msgstr "no se pudo posicionar (seek) el archivo «%s»: %m" -#: parsexlog.c:304 +#: parsexlog.c:386 #, c-format -msgid "could not read from file \"%s\": %s\n" -msgstr "no se pudo leer el archivo «%s»: %s\n" - -#: parsexlog.c:372 -#, c-format -msgid "" -"WAL record modifies a relation, but record type is not recognized\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" -msgstr "" -"el registro WAL modifica una relación, pero el tipo de registro no es reconocido\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "el registro WAL modifica una relación, pero el tipo de registro no es reconocido lsn: %X/%X, rmgr: %s, info: %02X" -#: pg_rewind.c:64 +#: pg_rewind.c:72 #, c-format msgid "" "%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" @@ -436,7 +421,7 @@ msgstr "" "%s resincroniza un cluster PostgreSQL con otra copia del cluster.\n" "\n" -#: pg_rewind.c:65 +#: pg_rewind.c:73 #, c-format msgid "" "Usage:\n" @@ -447,414 +432,391 @@ msgstr "" " %s [OPCION]...\n" "\n" -#: pg_rewind.c:66 +#: pg_rewind.c:74 #, c-format msgid "Options:\n" msgstr "Opciones:\n" -#: pg_rewind.c:67 +#: pg_rewind.c:75 #, c-format msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" msgstr " -D, --target-pgdata=DIRECTORIO directorio de datos existente a modificar\n" -#: pg_rewind.c:68 +#: pg_rewind.c:76 #, c-format msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" msgstr " --source-pgdata=DIRECTORIO directorio de datos de origen a sincronizar\n" -#: pg_rewind.c:69 +#: pg_rewind.c:77 #, c-format msgid " --source-server=CONNSTR source server to synchronize with\n" msgstr " --source-server=CONN servidor de origen a sincronizar\n" -#: pg_rewind.c:70 +#: pg_rewind.c:78 #, c-format msgid " -n, --dry-run stop before modifying anything\n" msgstr " -n, --dry-run detener antes de modificar nada\n" -#: pg_rewind.c:71 +#: pg_rewind.c:79 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n" + +#: pg_rewind.c:81 #, c-format msgid " -P, --progress write progress messages\n" msgstr " -P, --progress escribir mensajes de progreso\n" -#: pg_rewind.c:72 +#: pg_rewind.c:82 #, c-format msgid " --debug write a lot of debug messages\n" msgstr " --debug escribir muchos mensajes de depuración\n" -#: pg_rewind.c:73 +#: pg_rewind.c:83 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: pg_rewind.c:74 +#: pg_rewind.c:84 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: pg_rewind.c:75 +#: pg_rewind.c:85 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" -#: pg_rewind.c:130 pg_rewind.c:161 pg_rewind.c:168 pg_rewind.c:175 -#: pg_rewind.c:183 +#: pg_rewind.c:142 pg_rewind.c:178 pg_rewind.c:185 pg_rewind.c:192 +#: pg_rewind.c:200 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Pruebe «%s --help» para mayor información.\n" -#: pg_rewind.c:160 +#: pg_rewind.c:177 #, c-format -msgid "%s: no source specified (--source-pgdata or --source-server)\n" -msgstr "%s: no se especificó origen (--source-pgdata o --source-server)\n" +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "no se especificó origen (--source-pgdata o --source-server)" -#: pg_rewind.c:167 +#: pg_rewind.c:184 #, c-format -msgid "%s: only one of --source-pgdata or --source-server can be specified\n" -msgstr "%s: sólo uno de --source-pgdata o --source-server puede ser especificado\n" +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "sólo uno de --source-pgdata o --source-server puede ser especificado" -#: pg_rewind.c:174 +#: pg_rewind.c:191 #, c-format -msgid "%s: no target data directory specified (--target-pgdata)\n" -msgstr "%s: no se especificó directorio de datos de destino (--target-pgdata)\n" +msgid "no target data directory specified (--target-pgdata)" +msgstr "no se especificó directorio de datos de destino (--target-pgdata)" -#: pg_rewind.c:181 +#: pg_rewind.c:198 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_rewind.c:196 +#: pg_rewind.c:213 #, c-format -msgid "cannot be executed by \"root\"\n" -msgstr "no puede ser ejecutado por «root»\n" +msgid "cannot be executed by \"root\"" +msgstr "no puede ser ejecutado por «root»" -#: pg_rewind.c:197 +#: pg_rewind.c:214 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "Debe ejecutar %s con el superusuario de PostgreSQL.\n" -#: pg_rewind.c:228 -#, c-format -msgid "source and target cluster are on the same timeline\n" -msgstr "el cluster de origen y destino están en el mismo timeline\n" - -#: pg_rewind.c:234 +#: pg_rewind.c:225 #, c-format -msgid "servers diverged at WAL location %X/%X on timeline %u\n" -msgstr "servidores divergieron en la posición de WAL %X/%X en el timeline %u\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "no se pudo obtener los permisos del directorio «%s»: %m" -#: pg_rewind.c:271 +#: pg_rewind.c:256 #, c-format -msgid "no rewind required\n" -msgstr "no se requiere rebobinar\n" +msgid "source and target cluster are on the same timeline" +msgstr "el cluster de origen y destino están en el mismo timeline" -#: pg_rewind.c:278 +#: pg_rewind.c:262 #, c-format -msgid "rewinding from last common checkpoint at %X/%X on timeline %u\n" -msgstr "rebobinando desde el último checkpoint común en %X/%X en el timeline %u\n" +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "servidores divergieron en la posición de WAL %X/%X en el timeline %u" -#: pg_rewind.c:286 +#: pg_rewind.c:299 #, c-format -msgid "reading source file list\n" -msgstr "leyendo la lista de archivos de origen\n" +msgid "no rewind required" +msgstr "no se requiere rebobinar" -#: pg_rewind.c:288 +#: pg_rewind.c:306 #, c-format -msgid "reading target file list\n" -msgstr "leyendo la lista de archivos de destino\n" - -#: pg_rewind.c:298 -#, c-format -msgid "reading WAL in target\n" -msgstr "leyendo WAL en destino\n" +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "rebobinando desde el último checkpoint común en %X/%X en el timeline %u" #: pg_rewind.c:315 #, c-format -msgid "need to copy %lu MB (total source directory size is %lu MB)\n" -msgstr "se necesitan copiar %lu MB (tamaño total de directorio de origen es %lu MB)\n" - -#: pg_rewind.c:332 -#, c-format -msgid "" -"\n" -"creating backup label and updating control file\n" -msgstr "" -"\n" -"creando etiqueta de respaldo y actualizando archivo de control\n" +msgid "reading source file list" +msgstr "leyendo la lista de archivos de origen" -#: pg_rewind.c:360 +#: pg_rewind.c:318 #, c-format -msgid "syncing target data directory\n" -msgstr "sincronizando directorio de datos de destino\n" +msgid "reading target file list" +msgstr "leyendo la lista de archivos de destino" -#: pg_rewind.c:363 +#: pg_rewind.c:329 #, c-format -msgid "Done!\n" -msgstr "¡Listo!\n" +msgid "reading WAL in target" +msgstr "leyendo WAL en destino" -#: pg_rewind.c:375 +#: pg_rewind.c:346 #, c-format -msgid "source and target clusters are from different systems\n" -msgstr "clusters de origen y destino son de sistemas diferentes\n" +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "se necesitan copiar %lu MB (tamaño total de directorio de origen es %lu MB)" -#: pg_rewind.c:383 +#: pg_rewind.c:365 #, c-format -msgid "clusters are not compatible with this version of pg_rewind\n" -msgstr "los clusters no son compatibles con esta versión de pg_rewind\n" +msgid "creating backup label and updating control file" +msgstr "creando etiqueta de respaldo y actualizando archivo de control" -#: pg_rewind.c:393 +#: pg_rewind.c:394 #, c-format -msgid "target server needs to use either data checksums or \"wal_log_hints = on\"\n" -msgstr "el servidor de destino necesita tener sumas de verificación de datos o «wal_log_hints» activados\n" +msgid "syncing target data directory" +msgstr "sincronizando directorio de datos de destino" -#: pg_rewind.c:404 +#: pg_rewind.c:397 #, c-format -msgid "target server must be shut down cleanly\n" -msgstr "el directorio de destino debe estar apagado limpiamente\n" +msgid "Done!" +msgstr "¡Listo!" -#: pg_rewind.c:414 +#: pg_rewind.c:409 #, c-format -msgid "source data directory must be shut down cleanly\n" -msgstr "el directorio de origen debe estar apagado limpiamente\n" +msgid "source and target clusters are from different systems" +msgstr "clusters de origen y destino son de sistemas diferentes" -#: pg_rewind.c:469 +#: pg_rewind.c:417 #, c-format -msgid "invalid control file" -msgstr "archivo de control no válido" +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "los clusters no son compatibles con esta versión de pg_rewind" -#: pg_rewind.c:480 +#: pg_rewind.c:427 #, c-format -msgid "Source timeline history:\n" -msgstr "Historia de timeline origen:\n" +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "el servidor de destino necesita tener sumas de verificación de datos o «wal_log_hints» activados" -#: pg_rewind.c:482 +#: pg_rewind.c:438 #, c-format -msgid "Target timeline history:\n" -msgstr "Historia de timeline destino:\n" +msgid "target server must be shut down cleanly" +msgstr "el directorio de destino debe estar apagado limpiamente" -#. translator: %d is a timeline number, others are LSN positions -#: pg_rewind.c:496 +#: pg_rewind.c:448 #, c-format -msgid "%d: %X/%X - %X/%X\n" -msgstr "%d: %X/%X - %X/%X\n" +msgid "source data directory must be shut down cleanly" +msgstr "el directorio de origen debe estar apagado limpiamente" -#: pg_rewind.c:555 +#: pg_rewind.c:497 #, c-format -msgid "could not find common ancestor of the source and target cluster's timelines\n" -msgstr "no se pudo encontrar un ancestro común en el timeline de los clusters de origen y destino\n" +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) copiados" -#: pg_rewind.c:596 +#: pg_rewind.c:558 #, c-format -msgid "backup label buffer too small\n" -msgstr "el búfer del backup label es demasiado pequeño\n" +msgid "invalid control file\n" +msgstr "archivo de control no válido\n" -#: pg_rewind.c:619 +#: pg_rewind.c:642 #, c-format -msgid "unexpected control file CRC\n" -msgstr "CRC de archivo de control inesperado\n" +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "no se pudo encontrar un ancestro común en el timeline de los clusters de origen y destino" -#: pg_rewind.c:629 +#: pg_rewind.c:683 #, c-format -msgid "unexpected control file size %d, expected %d\n" -msgstr "tamaño del archivo de control %d inesperado, se esperaba %d\n" +msgid "backup label buffer too small" +msgstr "el búfer del backup label es demasiado pequeño" -#: pg_rewind.c:696 +#: pg_rewind.c:706 #, c-format -msgid "" -"The program \"initdb\" is needed by %s but was\n" -"not found in the same directory as \"%s\".\n" -"Check your installation.\n" -msgstr "" -"%s necesita el programa «initdb», pero no pudo ser encontrado en el mismo\n" -"directorio que «%s».\n" -"Verifique su instalación.\n" +msgid "unexpected control file CRC" +msgstr "CRC de archivo de control inesperado" -#: pg_rewind.c:700 +#: pg_rewind.c:716 #, c-format -msgid "" -"The program \"initdb\" was found by \"%s\"\n" -"but was not the same version as %s.\n" -"Check your installation.\n" -msgstr "" -"El programa «initdb» fue encontrado por «%s», pero no es\n" -"de la misma versión que %s.\n" -"Verifique su instalación.\n" +msgid "unexpected control file size %d, expected %d" +msgstr "tamaño del archivo de control %d inesperado, se esperaba %d" -#: pg_rewind.c:718 +#: pg_rewind.c:725 #, c-format -msgid "sync of target directory failed\n" -msgstr "falló sincronización de directorio destino\n" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d byte" +msgstr[1] "El tamaño del segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el archivo de control especifica %d bytes" #: timeline.c:76 timeline.c:82 #, c-format -msgid "syntax error in history file: %s\n" -msgstr "error de sintaxis en archivo de historia: %s\n" +msgid "syntax error in history file: %s" +msgstr "error de sintaxis en archivo de historia: %s" #: timeline.c:77 #, c-format -msgid "Expected a numeric timeline ID.\n" -msgstr "Se esperaba un ID de timeline numérico.\n" +msgid "Expected a numeric timeline ID." +msgstr "Se esperaba un ID numérico de timeline." #: timeline.c:83 #, c-format -msgid "Expected a write-ahead log switchpoint location.\n" -msgstr "Se esperaba una ubicación de punto de cambio del «write-ahead log».\n" +msgid "Expected a write-ahead log switchpoint location." +msgstr "Se esperaba una ubicación de punto de cambio del «write-ahead log»." #: timeline.c:88 #, c-format -msgid "invalid data in history file: %s\n" -msgstr "datos no válidos en archivo de historia: %s\n" +msgid "invalid data in history file: %s" +msgstr "datos no válidos en archivo de historia: %s" #: timeline.c:89 #, c-format -msgid "Timeline IDs must be in increasing sequence.\n" -msgstr "IDs de timeline debe estar en secuencia creciente.\n" +msgid "Timeline IDs must be in increasing sequence." +msgstr "IDs de timeline deben ser una secuencia creciente." #: timeline.c:109 #, c-format -msgid "invalid data in history file\n" -msgstr "datos no válidos en archivo de historia\n" +msgid "invalid data in history file" +msgstr "datos no válidos en archivo de historia" #: timeline.c:110 #, c-format -msgid "Timeline IDs must be less than child timeline's ID.\n" -msgstr "IDs de timeline deben ser menores que los ID de timelines «hijos».\n" +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "IDs de timeline deben ser menores que el ID de timeline del hijo." -#: xlogreader.c:276 +#: xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "posición de registro no válida en %X/%X" -#: xlogreader.c:284 +#: xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "contrecord solicitado por %X/%X" -#: xlogreader.c:325 xlogreader.c:625 +#: xlogreader.c:348 xlogreader.c:645 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "largo de registro no válido en %X/%X: se esperaba %u, se obtuvo %u" -#: xlogreader.c:340 +#: xlogreader.c:372 #, c-format msgid "record length %u at %X/%X too long" msgstr "largo de registro %u en %X/%X demasiado largo" -#: xlogreader.c:381 +#: xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "no hay bandera de contrecord en %X/%X" -#: xlogreader.c:394 +#: xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "largo de contrecord %u no válido en %X/%X" -#: xlogreader.c:633 +#: xlogreader.c:653 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ID de gestor de recursos %u no válido en %X/%X" -#: xlogreader.c:647 xlogreader.c:664 +#: xlogreader.c:667 xlogreader.c:684 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "registro con prev-link %X/%X incorrecto en %X/%X" -#: xlogreader.c:701 +#: xlogreader.c:721 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "suma de verificación de los datos del gestor de recursos incorrecta en el registro en %X/%X" -#: xlogreader.c:734 +#: xlogreader.c:758 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "número mágico %04X no válido en archivo %s, posición %u" -#: xlogreader.c:748 xlogreader.c:799 +#: xlogreader.c:772 xlogreader.c:823 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "info bits %04X no válidos en archivo %s, posición %u" -#: xlogreader.c:774 +#: xlogreader.c:798 #, c-format msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" msgstr "archivo WAL es de un sistema de bases de datos distinto: identificador de sistema en archivo WAL es %s, identificador en pg_control es %s" -#: xlogreader.c:781 +#: xlogreader.c:805 #, c-format -msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" -msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_SEG_SIZE incorrecto en cabecera de página" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "archivo WAL es de un sistema de bases de datos distinto: tamaño de segmento incorrecto en cabecera de paǵina" -#: xlogreader.c:787 +#: xlogreader.c:811 #, c-format msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" msgstr "archivo WAL es de un sistema de bases de datos distinto: XLOG_BLCKSZ incorrecto en cabecera de paǵina" -#: xlogreader.c:813 +#: xlogreader.c:842 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "pageaddr %X/%X inesperado en archivo %s, posición %u" -#: xlogreader.c:838 +#: xlogreader.c:867 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "ID de timeline %u fuera de secuencia (después de %u) en archivo %s, posición %u" -#: xlogreader.c:1083 +#: xlogreader.c:1112 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "block_id %u fuera de orden en %X/%X" -#: xlogreader.c:1106 +#: xlogreader.c:1135 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA está definido, pero no hay datos en %X/%X" -#: xlogreader.c:1113 +#: xlogreader.c:1142 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA no está definido, pero el largo de los datos es %u en %X/%X" -#: xlogreader.c:1149 +#: xlogreader.c:1178 #, c-format msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE está definido, pero posición del agujero es %u largo %u largo de imagen %u en %X/%X" -#: xlogreader.c:1165 +#: xlogreader.c:1194 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE no está definido, pero posición del agujero es %u largo %u en %X/%X" -#: xlogreader.c:1180 +#: xlogreader.c:1209 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED definido, pero largo de imagen de bloque es %u en %X/%X" -#: xlogreader.c:1195 +#: xlogreader.c:1224 #, c-format msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" msgstr "ni BKPIMAGE_HAS_HOLE ni BKPIMAGE_IS_COMPRESSED está definido, pero largo de imagen de bloque es %u en %X/%X" -#: xlogreader.c:1211 +#: xlogreader.c:1240 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL está definido, pero no hay «rel» anterior en %X/%X " -#: xlogreader.c:1223 +#: xlogreader.c:1252 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "block_id %u no válido en %X/%X" -#: xlogreader.c:1291 +#: xlogreader.c:1341 #, c-format msgid "record with invalid length at %X/%X" msgstr "registro con largo no válido en %X/%X" -#: xlogreader.c:1380 +#: xlogreader.c:1430 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "imagen comprimida no válida en %X/%X, bloque %d" diff --git a/src/bin/pg_rewind/po/fr.po b/src/bin/pg_rewind/po/fr.po index 4ef41e1a683..37242440a2f 100644 --- a/src/bin/pg_rewind/po/fr.po +++ b/src/bin/pg_rewind/po/fr.po @@ -7,15 +7,15 @@ msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-24 15:46+0000\n" -"PO-Revision-Date: 2017-07-24 22:05+0200\n" +"POT-Creation-Date: 2017-09-16 19:45+0000\n" +"PO-Revision-Date: 2017-09-17 18:22+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.0.3\n" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 parsexlog.c:179 @@ -31,7 +31,7 @@ msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" #: ../../common/restricted_token.c:68 #, c-format msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s : ATTENTION : ne peut pas crér les jetons restreints sur cette plateforme\n" +msgstr "%s : ATTENTION : ne peut pas créer les jetons restreints sur cette plateforme\n" #: ../../common/restricted_token.c:77 #, c-format @@ -294,82 +294,82 @@ msgstr "récupération des parties de fichier\n" msgid "could not set libpq connection to single row mode\n" msgstr "n'a pas pu configurer la connexion libpq en mode ligne seule\n" -#: libpq_fetch.c:286 +#: libpq_fetch.c:287 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "résultat inattendu lors de la récupération des fichiers cibles : %s" -#: libpq_fetch.c:292 +#: libpq_fetch.c:293 #, c-format msgid "unexpected result set size while fetching remote files\n" msgstr "taille inattendue de l'ensemble de résultats lors de la récupération des fichiers distants\n" -#: libpq_fetch.c:298 +#: libpq_fetch.c:299 #, c-format msgid "unexpected data types in result set while fetching remote files: %u %u %u\n" msgstr "types de données inattendus dans l'ensemble de résultats lors de la récupération des fichiers distants : %u %u %u\n" -#: libpq_fetch.c:306 +#: libpq_fetch.c:307 #, c-format msgid "unexpected result format while fetching remote files\n" msgstr "format de résultat inattendu lors de la récupération des fichiers distants\n" -#: libpq_fetch.c:312 +#: libpq_fetch.c:313 #, c-format msgid "unexpected null values in result while fetching remote files\n" msgstr "valeurs NULL inattendues dans le résultat lors de la récupération des fichiers distants\n" -#: libpq_fetch.c:316 +#: libpq_fetch.c:317 #, c-format msgid "unexpected result length while fetching remote files\n" msgstr "longueur de résultats inattendu lors de la récupération des fichiers distants\n" -#: libpq_fetch.c:338 +#: libpq_fetch.c:339 #, c-format msgid "received null value for chunk for file \"%s\", file has been deleted\n" msgstr "a reçu une valeur NULL pour une partie du fichier « %s », le fichier a été supprimé\n" -#: libpq_fetch.c:345 +#: libpq_fetch.c:351 #, c-format -msgid "received chunk for file \"%s\", offset " -msgstr "a reçu une partie du fichier « %s », décalage " +msgid "received chunk for file \"%s\", offset %s, size %d\n" +msgstr "a reçu une partie du fichier « %s », décalage %s, taille %d\n" -#: libpq_fetch.c:374 +#: libpq_fetch.c:380 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "n'a pas pu récupérer le fichier distant « %s » : %s" -#: libpq_fetch.c:379 +#: libpq_fetch.c:385 #, c-format msgid "unexpected result set while fetching remote file \"%s\"\n" msgstr "ensemble de résultats inattendu lors de la récupération du fichier distant « %s »\n" -#: libpq_fetch.c:390 +#: libpq_fetch.c:396 #, c-format msgid "fetched file \"%s\", length %d\n" msgstr "fichier récupéré « %s », longueur %d\n" -#: libpq_fetch.c:423 +#: libpq_fetch.c:429 #, c-format msgid "could not send COPY data: %s" msgstr "n'a pas pu envoyer les données COPY : %s" -#: libpq_fetch.c:449 +#: libpq_fetch.c:455 #, c-format msgid "could not create temporary table: %s" msgstr "n'a pas pu créer la table temporaire : %s" -#: libpq_fetch.c:457 +#: libpq_fetch.c:463 #, c-format msgid "could not send file list: %s" msgstr "n'a pas pu envoyer la liste de fichiers : %s" -#: libpq_fetch.c:499 +#: libpq_fetch.c:505 #, c-format msgid "could not send end-of-COPY: %s" msgstr "n'a pas pu envoyer end-of-COPY : %s" -#: libpq_fetch.c:505 +#: libpq_fetch.c:511 #, c-format msgid "unexpected result while sending file list: %s" msgstr "résultat inattendu lors de l'envoi de la liste de fichiers : %s" diff --git a/src/bin/pg_rewind/po/it.po b/src/bin/pg_rewind/po/it.po index 0da2db70ea0..30b1d7b7ef2 100644 --- a/src/bin/pg_rewind/po/it.po +++ b/src/bin/pg_rewind/po/it.po @@ -1,34 +1,36 @@ # -# Translation of pg_rewind to Italian -# PostgreSQL Project +# pg_rewind.po +# Italian message translation file for pg_rewind # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# Daniele Varrazzo , 2012-2017. +# +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:46+0000\n" -"PO-Revision-Date: 2017-05-29 17:25+0100\n" +"POT-Creation-Date: 2017-09-10 14:15+0000\n" +"PO-Revision-Date: 2017-09-10 18:02+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 1.5.4\n" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 parsexlog.c:179 +#: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 +#: parsexlog.c:179 #, c-format msgid "out of memory\n" msgstr "memoria esaurita\n" @@ -289,97 +291,97 @@ msgstr "ricezione della lista dei file fallita: %s" msgid "unexpected result set while fetching file list\n" msgstr "risultato imprevisto ricevendo la lista dei file\n" -#: libpq_fetch.c:239 +#: libpq_fetch.c:261 #, c-format msgid "could not send query: %s" msgstr "invio della query non riuscito: %s" -#: libpq_fetch.c:241 +#: libpq_fetch.c:263 #, c-format msgid "getting file chunks\n" msgstr "ricezione blocchi del file\n" -#: libpq_fetch.c:244 +#: libpq_fetch.c:266 #, c-format msgid "could not set libpq connection to single row mode\n" msgstr "impostazione della connessione libpq in modalità riga singola fallita\n" -#: libpq_fetch.c:264 +#: libpq_fetch.c:287 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "risultato imprevisto ricevendo i file remoti: %s" -#: libpq_fetch.c:270 +#: libpq_fetch.c:293 #, c-format msgid "unexpected result set size while fetching remote files\n" msgstr "dimensione del risultato imprevisto ricevendo i file remoti\n" -#: libpq_fetch.c:276 +#: libpq_fetch.c:299 #, c-format msgid "unexpected data types in result set while fetching remote files: %u %u %u\n" msgstr "tipo di dati imprevisto nel risultato ricevendo i file remoti: %u %u %u\n" -#: libpq_fetch.c:284 +#: libpq_fetch.c:307 #, c-format msgid "unexpected result format while fetching remote files\n" msgstr "formato del risultato imprevisto ricevendo i file remoti\n" -#: libpq_fetch.c:290 +#: libpq_fetch.c:313 #, c-format msgid "unexpected null values in result while fetching remote files\n" msgstr "valori null non previsti nel risultato ricevendo i file remoti\n" -#: libpq_fetch.c:294 +#: libpq_fetch.c:317 #, c-format msgid "unexpected result length while fetching remote files\n" msgstr "lunghezza del risultato non prevista ricevendo i file remoti\n" -#: libpq_fetch.c:316 +#: libpq_fetch.c:339 #, c-format msgid "received null value for chunk for file \"%s\", file has been deleted\n" msgstr "ricevuto valore null per il blocco del file \"%s\", il file è stato cancellato\n" -#: libpq_fetch.c:323 +#: libpq_fetch.c:351 #, c-format -msgid "received chunk for file \"%s\", offset %d, size %d\n" -msgstr "ricevuto blocco per il file \"%s\", offset %d, dimensione %d\n" +msgid "received chunk for file \"%s\", offset %s, size %d\n" +msgstr "ricevuto blocco per il file \"%s\", offset %s, dimensione %d\n" -#: libpq_fetch.c:352 +#: libpq_fetch.c:380 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "ricezione del file remoto \"%s\" fallita: %s" -#: libpq_fetch.c:357 +#: libpq_fetch.c:385 #, c-format msgid "unexpected result set while fetching remote file \"%s\"\n" msgstr "risultato inatteso leggendo il file remoto \"%s\"\n" -#: libpq_fetch.c:368 +#: libpq_fetch.c:396 #, c-format msgid "fetched file \"%s\", length %d\n" msgstr "ricevuto il file \"%s\", lunghezza %d\n" -#: libpq_fetch.c:400 +#: libpq_fetch.c:429 #, c-format msgid "could not send COPY data: %s" msgstr "invio dei dati di COPY fallito: %s" -#: libpq_fetch.c:426 +#: libpq_fetch.c:455 #, c-format msgid "could not create temporary table: %s" msgstr "creazione della tabella temporanea fallita: %s" -#: libpq_fetch.c:434 +#: libpq_fetch.c:463 #, c-format msgid "could not send file list: %s" msgstr "invio della lista dei file fallito: %s" -#: libpq_fetch.c:476 +#: libpq_fetch.c:505 #, c-format msgid "could not send end-of-COPY: %s" msgstr "invio del fine-COPY fallito: %s" -#: libpq_fetch.c:482 +#: libpq_fetch.c:511 #, c-format msgid "unexpected result while sending file list: %s" msgstr "risultato imprevisto inviando la lista dei file: %s" @@ -672,7 +674,7 @@ msgstr "CRC del file di controllo imprevisto\n" msgid "unexpected control file size %d, expected %d\n" msgstr "dimensione del file di controllo %d imprevista, atteso %d\n" -#: pg_rewind.c:696 +#: pg_rewind.c:705 #, c-format msgid "" "The program \"initdb\" is needed by %s but was\n" @@ -683,7 +685,7 @@ msgstr "" "stato tro vato nella stessa directory di \"%s\".\n" "Controlla la tua installazione.\n" -#: pg_rewind.c:700 +#: pg_rewind.c:709 #, c-format msgid "" "The program \"initdb\" was found by \"%s\"\n" @@ -694,7 +696,7 @@ msgstr "" "ma non è la stessa versione di %s.\n" "Controlla la tua installazione.\n" -#: pg_rewind.c:718 +#: pg_rewind.c:727 #, c-format msgid "sync of target directory failed\n" msgstr "sincronizzazione della directory di destinazione fallita\n" diff --git a/src/bin/pg_rewind/po/ko.po b/src/bin/pg_rewind/po/ko.po index 36f7c1ca877..4f7c553305b 100644 --- a/src/bin/pg_rewind/po/ko.po +++ b/src/bin/pg_rewind/po/ko.po @@ -5,16 +5,17 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_rewind (PostgreSQL) 9.6\n" +"Project-Id-Version: pg_rewind (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 18:50+0900\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:29+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 @@ -63,27 +64,27 @@ msgstr "%s: restricted tokenì„ ìž¬ì‹¤í–‰ í•  수 ì—†ìŒ: 오류 코드 %lu\n" msgid "%s: could not get exit code from subprocess: error code %lu\n" msgstr "%s: 하위 í”„ë¡œì„¸ìŠ¤ì˜ ì¢…ë£Œ 코드를 구할 수 ì—†ìŒ: 오류 코드 %lu\n" -#: copy_fetch.c:64 +#: copy_fetch.c:62 #, c-format msgid "could not open directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리 ì—´ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:93 filemap.c:112 filemap.c:267 +#: copy_fetch.c:91 filemap.c:111 filemap.c:266 #, c-format msgid "could not stat file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì˜ ìƒíƒœê°’ì„ ì•Œ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:122 +#: copy_fetch.c:120 #, c-format msgid "could not read symbolic link \"%s\": %s\n" msgstr "\"%s\" 심볼릭 ë§í¬ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:125 +#: copy_fetch.c:123 #, c-format msgid "symbolic link \"%s\" target is too long\n" msgstr "\"%s\" 심볼릭 ë§í¬ì˜ 대ìƒì´ 너무 길ìŒ\n" -#: copy_fetch.c:140 +#: copy_fetch.c:138 #, c-format msgid "" "\"%s\" is a symbolic link, but symbolic links are not supported on this " @@ -92,37 +93,37 @@ msgstr "" "\"%s\" 파ì¼ì€ 심볼릭 ë§í¬ 파ì¼ì´ì§€ë§Œ ì´ ìš´ì˜ì²´ì œëŠ” 심볼릭 ë§í¬ 파ì¼ì„ ì§€ì›í•˜" "ì§€ 않ìŒ\n" -#: copy_fetch.c:147 +#: copy_fetch.c:145 #, c-format msgid "could not read directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ì½ì„ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:151 +#: copy_fetch.c:149 #, c-format msgid "could not close directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: copy_fetch.c:171 +#: copy_fetch.c:169 #, c-format msgid "could not open source file \"%s\": %s\n" msgstr "\"%s\" ì›ë³¸ 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:175 +#: copy_fetch.c:173 #, c-format msgid "could not seek in source file: %s\n" msgstr "ì›ë³¸ 파ì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %s\n" -#: copy_fetch.c:192 file_ops.c:300 +#: copy_fetch.c:190 file_ops.c:299 #, c-format msgid "could not read file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: copy_fetch.c:195 +#: copy_fetch.c:193 #, c-format msgid "unexpected EOF while reading file \"%s\"\n" msgstr "\"%s\" 파ì¼ì„ ì½ëŠ” 중 예ìƒì¹˜ 못한 EOF\n" -#: copy_fetch.c:202 +#: copy_fetch.c:200 #, c-format msgid "could not close file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" @@ -132,103 +133,103 @@ msgstr "\"%s\" 파ì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" msgid " block %u\n" msgstr " ë¸”ë¡ %u\n" -#: file_ops.c:64 +#: file_ops.c:63 #, c-format msgid "could not open target file \"%s\": %s\n" msgstr "\"%s\" ëŒ€ìƒ íŒŒì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: file_ops.c:78 +#: file_ops.c:77 #, c-format msgid "could not close target file \"%s\": %s\n" msgstr "\"%s\" ëŒ€ìƒ íŒŒì¼ì„ ë‹«ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: file_ops.c:98 +#: file_ops.c:97 #, c-format msgid "could not seek in target file \"%s\": %s\n" msgstr "\"%s\" ëŒ€ìƒ íŒŒì¼ì—서 seek ìž‘ì—…ì„ í•  수 ì—†ìŒ: %s\n" -#: file_ops.c:114 +#: file_ops.c:113 #, c-format msgid "could not write file \"%s\": %s\n" msgstr "\"%s\" íŒŒì¼ ì“°ê¸° 실패: %s\n" -#: file_ops.c:164 +#: file_ops.c:163 #, c-format msgid "invalid action (CREATE) for regular file\n" msgstr "ì¼ë°˜ 파ì¼ì— 대한 잘못 ëœ ìž‘ì—… (CREATE)\n" -#: file_ops.c:179 +#: file_ops.c:178 #, c-format msgid "could not remove file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ 삭제할 수 ì—†ìŒ: %s\n" -#: file_ops.c:196 +#: file_ops.c:195 #, c-format msgid "could not open file \"%s\" for truncation: %s\n" msgstr "íŠ¸ëž™ìž­ì…˜ì„ ìœ„í•œ \"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: file_ops.c:200 +#: file_ops.c:199 #, c-format msgid "could not truncate file \"%s\" to %u: %s\n" msgstr "\"%s\" 파ì¼ì„ %u í¬ê¸°ë¡œ 정리할 수 ì—†ìŒ: %s\n" -#: file_ops.c:216 +#: file_ops.c:215 #, c-format msgid "could not create directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 만들 수 ì—†ìŒ: %s\n" -#: file_ops.c:230 +#: file_ops.c:229 #, c-format msgid "could not remove directory \"%s\": %s\n" msgstr "\"%s\" 디렉터리를 ì‚­ì œ í•  수 ì—†ìŒ: %s\n" -#: file_ops.c:244 +#: file_ops.c:243 #, c-format msgid "could not create symbolic link at \"%s\": %s\n" msgstr "\"%s\"ì— ëŒ€í•œ 심볼릭 ë§í¬ë¥¼ 만들 수 ì—†ìŒ: %s\n" -#: file_ops.c:258 +#: file_ops.c:257 #, c-format msgid "could not remove symbolic link \"%s\": %s\n" msgstr "\"%s\" 심볼릭 ë§í¬ë¥¼ ì‚­ì œ í•  수 ì—†ìŒ: %s\n" -#: file_ops.c:288 file_ops.c:292 +#: file_ops.c:287 file_ops.c:291 #, c-format msgid "could not open file \"%s\" for reading: %s\n" msgstr "ì½ê¸°ë¥¼ 위한 \"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: filemap.c:104 +#: filemap.c:103 #, c-format msgid "data file \"%s\" in source is not a regular file\n" msgstr "\"%s\" ì›ë³¸ 파ì¼ì€ ì¼ë°˜ 파ì¼ì´ 아님\n" -#: filemap.c:126 +#: filemap.c:125 #, c-format msgid "\"%s\" is not a directory\n" msgstr "\"%s\" 디렉터리가 아님\n" -#: filemap.c:149 +#: filemap.c:148 #, c-format msgid "\"%s\" is not a symbolic link\n" msgstr "\"%s\" 심볼릭 ë§í¬ê°€ 아님\n" -#: filemap.c:161 +#: filemap.c:160 #, c-format msgid "\"%s\" is not a regular file\n" msgstr "\"%s\" ì¼ë°˜ 파ì¼ì´ 아님\n" -#: filemap.c:279 +#: filemap.c:278 #, c-format msgid "source file list is empty\n" msgstr "ì›ë³¸ íŒŒì¼ ëª©ë¡ì´ 비었ìŒ\n" -#: filemap.c:401 +#: filemap.c:400 #, c-format msgid "unexpected page modification for directory or symbolic link \"%s\"\n" msgstr "ë””í…터리나 심볼릭 ë§í¬ \"%s\" ì˜ íŽ˜ì´ì§€ 변경 ì •ë³´ê°€ 잘못 ë¨\n" #. translator: first %s is a file path, second is a keyword such as COPY -#: filemap.c:537 +#: filemap.c:536 #, c-format msgid "%s (%s)\n" msgstr "%s (%s)\n" @@ -253,123 +254,128 @@ msgstr "ì›ë³¸ 서버는 복구 모드가 아니여야 함\n" msgid "full_page_writes must be enabled in the source server\n" msgstr "ì›ë³¸ 서버는 full_page_writes 옵션으로 ìš´ì˜ë˜ì–´ì•¼ 함\n" -#: libpq_fetch.c:95 +#: libpq_fetch.c:90 +#, c-format +msgid "could not set up connection context: %s" +msgstr "ì ‘ì† ìƒíƒœë¥¼ 설정할 수 ì—†ìŒ: %s" + +#: libpq_fetch.c:108 #, c-format msgid "error running query (%s) in source server: %s" msgstr "ì›ë³¸ì—서ì—서 쿼리(%s) 실행 오류: %s" -#: libpq_fetch.c:100 +#: libpq_fetch.c:113 #, c-format msgid "unexpected result set from query\n" msgstr "쿼리 결과가 바르지 않ìŒ\n" -#: libpq_fetch.c:123 +#: libpq_fetch.c:136 #, c-format msgid "unrecognized result \"%s\" for current WAL insert location\n" msgstr "현재 WAL 삽입 위치를 위한 결과가 ìž˜ëª»ë¨ : \"%s\"\n" -#: libpq_fetch.c:173 +#: libpq_fetch.c:186 #, c-format msgid "could not fetch file list: %s" msgstr "íŒŒì¼ ëª©ë¡ì„ 가져올 수 ì—†ìŒ: %s" -#: libpq_fetch.c:178 +#: libpq_fetch.c:191 #, c-format msgid "unexpected result set while fetching file list\n" msgstr "íŒŒì¼ ëª©ë¡ì„ 가져온 결과가 잘못 ë¨\n" -#: libpq_fetch.c:226 +#: libpq_fetch.c:261 #, c-format msgid "could not send query: %s" msgstr "쿼리를 보낼 수 ì—†ìŒ: %s" -#: libpq_fetch.c:228 +#: libpq_fetch.c:263 #, c-format msgid "getting file chunks\n" msgstr "íŒŒì¼ ì²­í¬ ê°€ì ¸ì˜¤ëŠ” 중\n" -#: libpq_fetch.c:231 +#: libpq_fetch.c:266 #, c-format msgid "could not set libpq connection to single row mode\n" msgstr "libpq ì—°ê²°ì„ ë‹¨ì¼ ë¡œìš° 모드로 지정할 수 ì—†ìŒ\n" -#: libpq_fetch.c:251 +#: libpq_fetch.c:287 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "ì›ê²© 파ì¼ì„ 가져오는 ë„중 결과가 잘못ë¨: %s" -#: libpq_fetch.c:257 +#: libpq_fetch.c:293 #, c-format msgid "unexpected result set size while fetching remote files\n" msgstr "ì›ê²© 파ì¼ì„ 가져오는 ë„중 ê²°ê³¼ ì§‘í•©ì˜ í¬ê¸°ê°€ 잘못 ë¨\n" -#: libpq_fetch.c:263 +#: libpq_fetch.c:299 #, c-format msgid "" "unexpected data types in result set while fetching remote files: %u %u %u\n" msgstr "ì›ê²© 파ì¼ì„ 가져오는 ë„중 ê²°ê³¼ ì§‘í•©ì˜ ìžë£Œí˜•ì´ ìž˜ëª» ë¨: %u %u %u\n" -#: libpq_fetch.c:271 +#: libpq_fetch.c:307 #, c-format msgid "unexpected result format while fetching remote files\n" msgstr "ì›ê²© 파ì¼ì„ 가져오는 중 예ìƒì¹˜ 못한 ê²°ê³¼ í˜•ì‹ ë°œê²¬\n" -#: libpq_fetch.c:277 +#: libpq_fetch.c:313 #, c-format msgid "unexpected null values in result while fetching remote files\n" msgstr "ì›ê²© 파ì¼ì„ 가져오는 ë„중 ê²°ê³¼ì•ˆì— null ê°’ì´ ìž˜ëª»ë¨\n" -#: libpq_fetch.c:281 +#: libpq_fetch.c:317 #, c-format msgid "unexpected result length while fetching remote files\n" msgstr "ì›ê²© 파ì¼ì„ 가져오는 ë„중 ê²°ê³¼ 길ì´ê°€ 잘못ë¨\n" -#: libpq_fetch.c:303 +#: libpq_fetch.c:339 #, c-format msgid "received null value for chunk for file \"%s\", file has been deleted\n" msgstr "\"%s\" 파ì¼ì„ 위한 ì²­í¬ì— null ê°’ì„ ë°›ìŒ, íŒŒì¼ ì§€ì›Œì§\n" -#: libpq_fetch.c:310 +#: libpq_fetch.c:351 #, c-format -msgid "received chunk for file \"%s\", offset %d, size %d\n" -msgstr "\"%s\" 파ì¼ì˜ ì²­í¬ë¥¼ ë°›ìŒ, 옵셋 %d, í¬ê¸° %d\n" +msgid "received chunk for file \"%s\", offset %s, size %d\n" +msgstr "\"%s\" 파ì¼ì˜ ì²­í¬ë¥¼ ë°›ìŒ, 옵셋 %s, í¬ê¸° %d\n" -#: libpq_fetch.c:339 +#: libpq_fetch.c:380 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "\"%s\" ì›ê²© 파ì¼ì„ 가져올 수 ì—†ìŒ: %s" -#: libpq_fetch.c:344 +#: libpq_fetch.c:385 #, c-format msgid "unexpected result set while fetching remote file \"%s\"\n" msgstr "\"%s\" ì›ê²©íŒŒì¼ì„ 가져오는 ë„중 ê²°ê³¼ ì§‘í•©ì´ ìž˜ëª» ë¨\n" -#: libpq_fetch.c:355 +#: libpq_fetch.c:396 #, c-format msgid "fetched file \"%s\", length %d\n" msgstr "\"%s\" 파ì¼ì„ 가져옴, ê¸¸ì´ %d\n" -#: libpq_fetch.c:387 +#: libpq_fetch.c:429 #, c-format msgid "could not send COPY data: %s" msgstr "COPY ìžë£Œë¥¼ 보낼 수 ì—†ìŒ: %s" -#: libpq_fetch.c:413 +#: libpq_fetch.c:455 #, c-format msgid "could not create temporary table: %s" msgstr "임시 í…Œì´ë¸”ì„ ë§Œë“¤ 수 ì—†ìŒ: %s" -#: libpq_fetch.c:421 +#: libpq_fetch.c:463 #, c-format msgid "could not send file list: %s" msgstr "íŒŒì¼ ëª©ë¡ì„ 보낼 수 ì—†ìŒ: %s" -#: libpq_fetch.c:463 +#: libpq_fetch.c:505 #, c-format msgid "could not send end-of-COPY: %s" msgstr "COPYëì„ ë³´ë‚¼ 수 ì—†ìŒ: %s" -#: libpq_fetch.c:469 +#: libpq_fetch.c:511 #, c-format msgid "unexpected result while sending file list: %s" msgstr "íŒŒì¼ ëª©ë¡ì„ 보내는 ë„중 결과가 잘못 ë¨: %s" @@ -504,7 +510,8 @@ msgstr "" "\n" "오류보고: .\n" -#: pg_rewind.c:130 pg_rewind.c:161 pg_rewind.c:168 pg_rewind.c:176 +#: pg_rewind.c:130 pg_rewind.c:161 pg_rewind.c:168 pg_rewind.c:175 +#: pg_rewind.c:183 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "ìžì œí•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보십시오.\n" @@ -518,66 +525,71 @@ msgstr "" #: pg_rewind.c:167 #, c-format +msgid "%s: only one of --source-pgdata or --source-server can be specified\n" +msgstr "%s: --source-pgdata ë˜ëŠ” --source-server 옵션 중 하나만 지정해야 함\n" + +#: pg_rewind.c:174 +#, c-format msgid "%s: no target data directory specified (--target-pgdata)\n" msgstr "" "%s: ëŒ€ìƒ ë°ì´í„° 디렉토리가 지정ë˜ì§€ ì•Šì•˜ìŒ (--target-pgdata 옵션 사용)\n" -#: pg_rewind.c:174 +#: pg_rewind.c:181 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" -#: pg_rewind.c:189 +#: pg_rewind.c:196 #, c-format msgid "cannot be executed by \"root\"\n" msgstr "\"root\" 계정으로는 실행 í•  수 ì—†ìŒ\n" -#: pg_rewind.c:190 +#: pg_rewind.c:197 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "PostgreSQL superuser로 %s í”„ë¡œê·¸ëž¨ì„ ì‹¤í–‰í•˜ì‹­ì‹œì˜¤.\n" -#: pg_rewind.c:221 +#: pg_rewind.c:228 #, c-format msgid "source and target cluster are on the same timeline\n" msgstr "ì›ë³¸ê³¼ ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ì˜ íƒ€ìž„ë¼ì¸ì´ ê°™ìŒ\n" -#: pg_rewind.c:227 +#: pg_rewind.c:234 #, c-format -msgid "servers diverged at WAL position %X/%X on timeline %u\n" -msgstr "서버 분기 위치: %X/%X, 타임ë¼ì¸ %u\n" +msgid "servers diverged at WAL location %X/%X on timeline %u\n" +msgstr "서버 분기 WAL 위치: %X/%X, 타임ë¼ì¸ %u\n" -#: pg_rewind.c:264 +#: pg_rewind.c:271 #, c-format msgid "no rewind required\n" msgstr "ë˜ê°ì„ í•„ìš” ì—†ìŒ\n" -#: pg_rewind.c:271 +#: pg_rewind.c:278 #, c-format msgid "rewinding from last common checkpoint at %X/%X on timeline %u\n" msgstr "재ë™ê¸°í™” 시작함, 마지막 ì²´í¬í¬ì¸íЏ 위치 %X/%X, 타임ë¼ì¸ %u\n" -#: pg_rewind.c:279 +#: pg_rewind.c:286 #, c-format msgid "reading source file list\n" msgstr "ì›ë³¸ íŒŒì¼ ëª©ë¡ ì½ëŠ” 중\n" -#: pg_rewind.c:281 +#: pg_rewind.c:288 #, c-format msgid "reading target file list\n" msgstr "ëŒ€ìƒ íŒŒì¼ ëª©ë¡ ì½ëŠ” 중\n" -#: pg_rewind.c:291 +#: pg_rewind.c:298 #, c-format msgid "reading WAL in target\n" msgstr "ëŒ€ìƒ ì„œë²„ì—서 WAL ì½ëŠ” 중\n" -#: pg_rewind.c:308 +#: pg_rewind.c:315 #, c-format msgid "need to copy %lu MB (total source directory size is %lu MB)\n" msgstr "복사를 위해서 %lu MB 필요함 (ì›ë³¸ 디렉토리 ì „ì²´ í¬ê¸°ëŠ” %lu MB)\n" -#: pg_rewind.c:325 +#: pg_rewind.c:332 #, c-format msgid "" "\n" @@ -586,27 +598,27 @@ msgstr "" "\n" "백업 ë¼ë²¨ì„ 만들고, 컨트롤 파ì¼ì„ 갱신 중\n" -#: pg_rewind.c:353 +#: pg_rewind.c:360 #, c-format msgid "syncing target data directory\n" msgstr "ëŒ€ìƒ ë°ì´í„° 디렉터리 ë™ê¸°í™” 중\n" -#: pg_rewind.c:356 +#: pg_rewind.c:363 #, c-format msgid "Done!\n" msgstr "완료!\n" -#: pg_rewind.c:368 +#: pg_rewind.c:375 #, c-format msgid "source and target clusters are from different systems\n" msgstr "ì›ë³¸ê³¼ ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ì˜ ë°ì´í„° í´ëŸ¬ìŠ¤í„°ì˜ ì‹ë³„ 번호가 다름\n" -#: pg_rewind.c:376 +#: pg_rewind.c:383 #, c-format msgid "clusters are not compatible with this version of pg_rewind\n" msgstr "해당 í´ëŸ¬ìŠ¤í„°ëŠ” ì´ pg_rewind 버전으로 작업할 수 ì—†ìŒ\n" -#: pg_rewind.c:386 +#: pg_rewind.c:393 #, c-format msgid "" "target server needs to use either data checksums or \"wal_log_hints = on\"\n" @@ -614,59 +626,59 @@ msgstr "" "ëŒ€ìƒ ì„œë²„ì˜ ë°ì´í„° í´ëŸ¬ìŠ¤í„°ê°€ ë°ì´í„° ì²´í¬ì„¬ ê¸°ëŠ¥ì„ ì¼°ê±°ë‚˜, \"wal_log_hints " "= on\" ì„¤ì •ì´ ë˜ì–´ì•¼ 함\n" -#: pg_rewind.c:397 +#: pg_rewind.c:404 #, c-format msgid "target server must be shut down cleanly\n" msgstr "ëŒ€ìƒ ì„œë²„ëŠ” ì •ìƒ ì¢…ë£Œë˜ì–´ì•¼ 함\n" -#: pg_rewind.c:407 +#: pg_rewind.c:414 #, c-format msgid "source data directory must be shut down cleanly\n" msgstr "ì›ë³¸ ë°ì´í„° 디렉토리는 ì •ìƒì ìœ¼ë¡œ 종료ë˜ì–´ì•¼ 함\n" -#: pg_rewind.c:462 +#: pg_rewind.c:469 #, c-format msgid "invalid control file" msgstr "ìž˜ëª»ëœ ì»¨íŠ¸ë¡¤ 파ì¼" -#: pg_rewind.c:473 +#: pg_rewind.c:480 #, c-format msgid "Source timeline history:\n" msgstr "ì›ë³¸ 타임ë¼ì¸ ë‚´ì—­:\n" -#: pg_rewind.c:475 +#: pg_rewind.c:482 #, c-format msgid "Target timeline history:\n" msgstr "ëŒ€ìƒ íƒ€ìž„ë¼ì¸ ë‚´ì—­:\n" #. translator: %d is a timeline number, others are LSN positions -#: pg_rewind.c:489 +#: pg_rewind.c:496 #, c-format msgid "%d: %X/%X - %X/%X\n" msgstr "%d: %X/%X - %X/%X\n" -#: pg_rewind.c:548 +#: pg_rewind.c:555 #, c-format msgid "" "could not find common ancestor of the source and target cluster's timelines\n" msgstr "ì›ë³¸ê³¼ ëŒ€ìƒ ì„œë²„ì˜ ê³µí†µëœ ìƒìœ„ 타임ë¼ì¸ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: pg_rewind.c:589 +#: pg_rewind.c:596 #, c-format msgid "backup label buffer too small\n" msgstr "백업 ë¼ë²¨ 버í¼ê°€ 너무 ìž‘ìŒ\n" -#: pg_rewind.c:612 +#: pg_rewind.c:619 #, c-format msgid "unexpected control file CRC\n" msgstr "컨트롤 íŒŒì¼ CRC 오류\n" -#: pg_rewind.c:622 +#: pg_rewind.c:629 #, c-format msgid "unexpected control file size %d, expected %d\n" msgstr "컨트롤 파ì¼ì˜ í¬ê¸°ê°€ %d 로 비정ìƒ, ì •ìƒê°’ %d\n" -#: pg_rewind.c:689 +#: pg_rewind.c:705 #, c-format msgid "" "The program \"initdb\" is needed by %s but was\n" @@ -677,7 +689,7 @@ msgstr "" "\"%s\" 디렉터리 ì•ˆì— ì—†ìŠµë‹ˆë‹¤.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: pg_rewind.c:693 +#: pg_rewind.c:709 #, c-format msgid "" "The program \"initdb\" was found by \"%s\"\n" @@ -688,7 +700,7 @@ msgstr "" "%s 버전과 같지 않습니다.\n" "설치 ìƒíƒœë¥¼ 확ì¸í•´ 주십시오.\n" -#: pg_rewind.c:711 +#: pg_rewind.c:727 #, c-format msgid "sync of target directory failed\n" msgstr "ëŒ€ìƒ ë””ë ‰í„°ë¦¬ ë™ê¸°í™” 실패\n" @@ -705,7 +717,7 @@ msgstr "타임ë¼ì¸ ID ê°’ì€ ìˆ«ìžì—¬ì•¼ 함\n" #: timeline.c:83 #, c-format -msgid "Expected a transaction log switchpoint location.\n" +msgid "Expected a write-ahead log switchpoint location.\n" msgstr "트랜잭션 로그 전환 위치 ê°’ì´ ìžˆì–´ì•¼ 함\n" #: timeline.c:88 @@ -738,7 +750,7 @@ msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 위치: %X/%X" msgid "contrecord is requested by %X/%X" msgstr "%X/%Xì—서 contrecord를 필요로 함" -#: xlogreader.c:325 xlogreader.c:624 +#: xlogreader.c:325 xlogreader.c:625 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 길ì´: %X/%X, 기대값 %u, 실재값 %u" @@ -758,32 +770,32 @@ msgstr "%X/%X ìœ„ì¹˜ì— contrecord 플래그가 ì—†ìŒ" msgid "invalid contrecord length %u at %X/%X" msgstr "ìž˜ëª»ëœ contrecord ê¸¸ì´ %u, 위치 %X/%X" -#: xlogreader.c:632 +#: xlogreader.c:633 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ìž˜ëª»ëœ ìžì› 관리 ID %u, 위치: %X/%X" -#: xlogreader.c:646 xlogreader.c:663 +#: xlogreader.c:647 xlogreader.c:664 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "ë ˆì½”ë“œì˜ ìž˜ëª»ëœ í”„ë¦¬ë§í¬ %X/%X, 해당 레코드 %X/%X" -#: xlogreader.c:700 +#: xlogreader.c:701 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "ìž˜ëª»ëœ ìžì›ê´€ë¦¬ìž ë°ì´í„° ì²´í¬ì„¬, 위치: %X/%X 레코드" -#: xlogreader.c:733 +#: xlogreader.c:734 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "%04X ë§¤ì§ ë²ˆí˜¸ê°€ 잘못ë¨, 로그 íŒŒì¼ %s, 위치 %u" -#: xlogreader.c:747 xlogreader.c:798 +#: xlogreader.c:748 xlogreader.c:799 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "ìž˜ëª»ëœ ì •ë³´ 비트 %04X, 로그 íŒŒì¼ %s, 위치 %u" -#: xlogreader.c:773 +#: xlogreader.c:774 #, c-format msgid "" "WAL file is from different database system: WAL file database system " @@ -792,7 +804,7 @@ msgstr "" "WAL 파ì¼ì´ 다른 ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤. WAL 파ì¼ì˜ 시스템 ì‹ë³„ìžëŠ” %s, pg_control " "ì˜ ì‹ë³„ìžëŠ” %s" -#: xlogreader.c:780 +#: xlogreader.c:781 #, c-format msgid "" "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page " @@ -801,7 +813,7 @@ msgstr "" "WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì˜ XLOG_SEG_SIZE " "ê°’ì´ ë°”ë¥´ì§€ 않ìŒ" -#: xlogreader.c:786 +#: xlogreader.c:787 #, c-format msgid "" "WAL file is from different database system: incorrect XLOG_BLCKSZ in page " @@ -810,73 +822,77 @@ msgstr "" "WAL 파ì¼ì´ 다른 ë°ì´í„°ë² ì´ìФ ì‹œìŠ¤í…œì˜ ê²ƒìž…ë‹ˆë‹¤: 페ì´ì§€ í—¤ë”ì˜ XLOG_BLCKSZ ê°’" "ì´ ë°”ë¥´ì§€ 않ìŒ" -#: xlogreader.c:812 +#: xlogreader.c:813 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "ìž˜ëª»ëœ íŽ˜ì´ì§€ 주소 %X/%X, 로그 íŒŒì¼ %s, 위치 %u" -#: xlogreader.c:837 +#: xlogreader.c:838 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "타임ë¼ì¸ 범위 벗어남 %u (ì´ì „ 번호 %u), 로그 íŒŒì¼ %s, 위치 %u" -#: xlogreader.c:1081 +#: xlogreader.c:1083 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "%u block_id는 범위를 벗어남, 위치 %X/%X" -#: xlogreader.c:1103 +#: xlogreader.c:1106 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA 지정했지만, %X/%X ì— ìžë£Œê°€ ì—†ìŒ" -#: xlogreader.c:1110 +#: xlogreader.c:1113 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA 지정 않았지만, %u 길ì´ì˜ ìžë£Œê°€ 있ìŒ, 위치 %X/%X" -#: xlogreader.c:1143 +#: xlogreader.c:1149 #, c-format msgid "" "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " "%X/%X" -msgstr "BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, " -"ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: " +"%u, 대ìƒ: %X/%X" -#: xlogreader.c:1159 +#: xlogreader.c:1165 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ì•ˆë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, 대ìƒ: %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE ì„¤ì •ì´ ì•ˆë˜ì–´ 있지만, 옵셋: %u, 길ì´: %u, 대ìƒ: %X/%X" -#: xlogreader.c:1174 +#: xlogreader.c:1180 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" -msgstr "BKPIMAGE_IS_COMPRESSED ì„¤ì •ì´ ë˜ì–´ 있지만, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" +msgstr "" +"BKPIMAGE_IS_COMPRESSED ì„¤ì •ì´ ë˜ì–´ 있지만, ë¸”ë¡ ì´ë¯¸ì§€ 길ì´: %u, 대ìƒ: %X/%X" -#: xlogreader.c:1189 +#: xlogreader.c:1195 #, c-format msgid "" "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " "length is %u at %X/%X" -msgstr "BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED 지정 안ë˜ì–´ 있으나, ë¸”ë¡ " -"ì´ë¯¸ì§€ 길ì´ëŠ” %u, 대ìƒ: %X/%X" +msgstr "" +"BKPIMAGE_HAS_HOLE, BKPIMAGE_IS_COMPRESSED 지정 안ë˜ì–´ 있으나, ë¸”ë¡ ì´ë¯¸ì§€ 길" +"ì´ëŠ” %u, 대ìƒ: %X/%X" -#: xlogreader.c:1205 +#: xlogreader.c:1211 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL ì„¤ì •ì´ ë˜ì–´ 있지만, %X/%X ì— ì´ì „ 릴레ì´ì…˜ ì—†ìŒ" -#: xlogreader.c:1217 +#: xlogreader.c:1223 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "ìž˜ëª»ëœ block_id %u, 위치 %X/%X" -#: xlogreader.c:1282 +#: xlogreader.c:1291 #, c-format msgid "record with invalid length at %X/%X" msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 길ì´, 위치 %X/%X" -#: xlogreader.c:1371 +#: xlogreader.c:1380 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "ìž˜ëª»ëœ ì••ì¶• ì´ë¯¸ì§€, 위치 %X/%X, ë¸”ë¡ %d" diff --git a/src/bin/pg_rewind/po/ru.po b/src/bin/pg_rewind/po/ru.po index 198a7f64781..9517ecc492f 100644 --- a/src/bin/pg_rewind/po/ru.po +++ b/src/bin/pg_rewind/po/ru.po @@ -2,13 +2,12 @@ # Copyright (C) 2015-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Alexander Lakhin , 2015-2017. -# msgid "" msgstr "" "Project-Id-Version: pg_rewind (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:46+0000\n" -"PO-Revision-Date: 2016-11-24 14:26+0300\n" +"POT-Creation-Date: 2018-01-31 07:53+0300\n" +"PO-Revision-Date: 2017-09-21 12:01+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -289,32 +288,32 @@ msgstr "не удалоÑÑŒ получить ÑпиÑок файлов: %s" msgid "unexpected result set while fetching file list\n" msgstr "неожиданный результат при получении ÑпиÑка файлов\n" -#: libpq_fetch.c:239 +#: libpq_fetch.c:261 #, c-format msgid "could not send query: %s" msgstr "не удалоÑÑŒ отправить запроÑ: %s" -#: libpq_fetch.c:241 +#: libpq_fetch.c:263 #, c-format msgid "getting file chunks\n" msgstr "получение Ñегментов файлов\n" -#: libpq_fetch.c:244 +#: libpq_fetch.c:266 #, c-format msgid "could not set libpq connection to single row mode\n" msgstr "не удалоÑÑŒ перевеÑти подключение libpq в одноÑтрочный режим\n" -#: libpq_fetch.c:264 +#: libpq_fetch.c:287 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "неожиданный результат при получении удалённых файлов: %s" -#: libpq_fetch.c:270 +#: libpq_fetch.c:293 #, c-format msgid "unexpected result set size while fetching remote files\n" msgstr "неожиданный размер набора результатов при получении удалённых файлов\n" -#: libpq_fetch.c:276 +#: libpq_fetch.c:299 #, c-format msgid "" "unexpected data types in result set while fetching remote files: %u %u %u\n" @@ -322,68 +321,68 @@ msgstr "" "неожиданные типы данных в наборе результатов при получении удалённых файлов: " "%u %u %u\n" -#: libpq_fetch.c:284 +#: libpq_fetch.c:307 #, c-format msgid "unexpected result format while fetching remote files\n" msgstr "неожиданный формат результата при получении удалённых файлов\n" -#: libpq_fetch.c:290 +#: libpq_fetch.c:313 #, c-format msgid "unexpected null values in result while fetching remote files\n" msgstr "" "неожиданные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NULL в результате при получении удалённых файлов\n" -#: libpq_fetch.c:294 +#: libpq_fetch.c:317 #, c-format msgid "unexpected result length while fetching remote files\n" msgstr "Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° результата при получении удалённых файлов\n" -#: libpq_fetch.c:316 +#: libpq_fetch.c:339 #, c-format msgid "received null value for chunk for file \"%s\", file has been deleted\n" msgstr "Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\" вмеÑто Ñегмента получено NULL-значение, файл удалён\n" -#: libpq_fetch.c:323 +#: libpq_fetch.c:351 #, c-format -msgid "received chunk for file \"%s\", offset %d, size %d\n" -msgstr "получен Ñегмент файла \"%s\": Ñмещение %d, размер %d\n" +msgid "received chunk for file \"%s\", offset %s, size %d\n" +msgstr "получен Ñегмент файла \"%s\": Ñмещение %s, размер %d\n" -#: libpq_fetch.c:352 +#: libpq_fetch.c:380 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "не удалоÑÑŒ получить удалённый файл \"%s\": %s" -#: libpq_fetch.c:357 +#: libpq_fetch.c:385 #, c-format msgid "unexpected result set while fetching remote file \"%s\"\n" msgstr "неожиданный набор результатов при получении удалённого файла \"%s\"\n" -#: libpq_fetch.c:368 +#: libpq_fetch.c:396 #, c-format msgid "fetched file \"%s\", length %d\n" msgstr "получен файл \"%s\", длина %d\n" -#: libpq_fetch.c:400 +#: libpq_fetch.c:429 #, c-format msgid "could not send COPY data: %s" msgstr "не удалоÑÑŒ отправить данные COPY: %s" -#: libpq_fetch.c:426 +#: libpq_fetch.c:455 #, c-format msgid "could not create temporary table: %s" msgstr "не удалоÑÑŒ Ñоздать временную таблицу: %s" -#: libpq_fetch.c:434 +#: libpq_fetch.c:463 #, c-format msgid "could not send file list: %s" msgstr "не удалоÑÑŒ отправить ÑпиÑок файлов: %s" -#: libpq_fetch.c:476 +#: libpq_fetch.c:505 #, c-format msgid "could not send end-of-COPY: %s" msgstr "не удалоÑÑŒ отправить Ñообщение о завершении копированиÑ: %s" -#: libpq_fetch.c:482 +#: libpq_fetch.c:511 #, c-format msgid "unexpected result while sending file list: %s" msgstr "неожиданный результат при передаче ÑпиÑка: %s" @@ -571,8 +570,8 @@ msgstr "иÑходный и целевой клаÑтер уже на одной #: pg_rewind.c:234 #, c-format -msgid "servers diverged at WAL position %X/%X on timeline %u\n" -msgstr "Серверы разошлиÑÑŒ в позиции WAL %X/%X на линии времени %u.\n" +msgid "servers diverged at WAL location %X/%X on timeline %u\n" +msgstr "Ñерверы разошлиÑÑŒ в позиции WAL %X/%X на линии времени %u\n" #: pg_rewind.c:271 #, c-format @@ -697,7 +696,7 @@ msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ð°Ñ Ñумма управлÑюще msgid "unexpected control file size %d, expected %d\n" msgstr "неверный размер управлÑющего файла (%d), ожидалоÑÑŒ: %d\n" -#: pg_rewind.c:696 +#: pg_rewind.c:705 #, c-format msgid "" "The program \"initdb\" is needed by %s but was\n" @@ -708,7 +707,7 @@ msgstr "" "в каталоге \"%s\".\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_rewind.c:700 +#: pg_rewind.c:709 #, c-format msgid "" "The program \"initdb\" was found by \"%s\"\n" @@ -719,7 +718,7 @@ msgstr "" "но её верÑÐ¸Ñ Ð¾Ñ‚Ð»Ð¸Ñ‡Ð°ÐµÑ‚ÑÑ Ð¾Ñ‚ верÑии %s.\n" "Проверьте правильноÑть уÑтановки СУБД.\n" -#: pg_rewind.c:718 +#: pg_rewind.c:727 #, c-format msgid "sync of target directory failed\n" msgstr "Ñбой Ñинхронизации целевого каталога\n" @@ -736,8 +735,8 @@ msgstr "ОжидаетÑÑ Ñ‡Ð¸Ñловой идентификатор лини #: timeline.c:83 #, c-format -msgid "Expected a transaction log switchpoint location.\n" -msgstr "ОжидаетÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ точки Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° транзакций.\n" +msgid "Expected a write-ahead log switchpoint location.\n" +msgstr "ОжидаетÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ðµ точки Ð¿ÐµÑ€ÐµÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ð° предзапиÑи.\n" #: timeline.c:88 #, c-format @@ -917,12 +916,12 @@ msgstr "" msgid "invalid block_id %u at %X/%X" msgstr "неверный идентификатор блока %u в позиции %X/%X" -#: xlogreader.c:1291 +#: xlogreader.c:1306 #, c-format msgid "record with invalid length at %X/%X" msgstr "запиÑÑŒ Ñ Ð½ÐµÐ²ÐµÑ€Ð½Ð¾Ð¹ длиной в позиции %X/%X" -#: xlogreader.c:1380 +#: xlogreader.c:1395 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "неверный Ñжатый образ в позиции %X/%X, блок %d" diff --git a/src/bin/pg_rewind/po/sv.po b/src/bin/pg_rewind/po/sv.po index ba363a644be..d4b17d0aeea 100644 --- a/src/bin/pg_rewind/po/sv.po +++ b/src/bin/pg_rewind/po/sv.po @@ -1,23 +1,39 @@ # Swedish message translation file for pg_rewind # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: pg_rewind (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-05 14:15+0000\n" -"PO-Revision-Date: 2017-08-05 23:21+0200\n" +"Project-Id-Version: pg_rewind (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 20:47+0000\n" +"PO-Revision-Date: 2019-05-20 15:55+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 parsexlog.c:74 parsexlog.c:127 parsexlog.c:179 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "slut pÃ¥ minne\n" @@ -27,416 +43,386 @@ msgstr "slut pÃ¥ minne\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "kan inte duplicera null-pekare (internt fel)\n" -#: ../../common/restricted_token.c:68 +#: ../../common/restricted_token.c:69 #, c-format -msgid "%s: WARNING: cannot create restricted tokens on this platform\n" -msgstr "%s: VARNING: \"restricted Token\" stöds inte av plattformen.\n" +msgid "cannot create restricted tokens on this platform" +msgstr "kan inte skapa token för begränsad Ã¥tkomst pÃ¥ denna plattorm" -#: ../../common/restricted_token.c:77 +#: ../../common/restricted_token.c:78 #, c-format -msgid "%s: could not open process token: error code %lu\n" -msgstr "%s: kunde inte skapa processtoken: felkod %lu\n" +msgid "could not open process token: error code %lu" +msgstr "kunde inte öppna process-token: felkod %lu" -#: ../../common/restricted_token.c:90 +#: ../../common/restricted_token.c:91 #, c-format -msgid "%s: could not allocate SIDs: error code %lu\n" -msgstr "%s: kunde inte tilldela SID: felkod %lu\n" +msgid "could not allocate SIDs: error code %lu" +msgstr "kunde inte allokera SID: felkod %lu" #: ../../common/restricted_token.c:110 #, c-format -msgid "%s: could not create restricted token: error code %lu\n" -msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" - -#: ../../common/restricted_token.c:132 -#, c-format -msgid "%s: could not start process for command \"%s\": error code %lu\n" -msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" +msgid "could not create restricted token: error code %lu" +msgstr "kunde inte skapa token för begränsad Ã¥tkomst: felkod %lu" -#: ../../common/restricted_token.c:170 +#: ../../common/restricted_token.c:131 #, c-format -msgid "%s: could not re-execute with restricted token: error code %lu\n" -msgstr "%s: kunde inte upprepa med restriktivt styrmärke (token): felkod %lu\n" +msgid "could not start process for command \"%s\": error code %lu" +msgstr "kunde inte starta process för kommando \"%s\": felkod %lu" -#: ../../common/restricted_token.c:186 +#: ../../common/restricted_token.c:169 #, c-format -msgid "%s: could not get exit code from subprocess: error code %lu\n" -msgstr "%s: kunde inte utvinna statuskod för underprocess: felkod %lu\n" +msgid "could not re-execute with restricted token: error code %lu" +msgstr "kunde inte köra igen med token för begränsad Ã¥tkomst: felkod %lu" -#: copy_fetch.c:62 +#: ../../common/restricted_token.c:185 #, c-format -msgid "could not open directory \"%s\": %s\n" -msgstr "kunde inte öppna katalog \"%s\": %s\n" +msgid "could not get exit code from subprocess: error code %lu" +msgstr "kunde inte hämta statuskod för underprocess: felkod %lu" -#: copy_fetch.c:91 filemap.c:111 filemap.c:266 +#: copy_fetch.c:60 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %s\n" +msgid "could not open directory \"%s\": %m" +msgstr "kunde inte öppna katalog \"%s\": %m" -#: copy_fetch.c:120 +#: copy_fetch.c:89 filemap.c:189 filemap.c:350 #, c-format -msgid "could not read symbolic link \"%s\": %s\n" -msgstr "kunde inte läsa symbolisk länk \"%s\": %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" -#: copy_fetch.c:123 +#: copy_fetch.c:118 #, c-format -msgid "symbolic link \"%s\" target is too long\n" -msgstr "mÃ¥l för symbolisk länk \"%s\" är för lÃ¥ng\n" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: copy_fetch.c:138 +#: copy_fetch.c:121 #, c-format -msgid "" -"\"%s\" is a symbolic link, but symbolic links are not supported on this " -"platform\n" -msgstr "\"%s\" är en symbolisk länk men symboliska länkar stöds inte pÃ¥ denna plattform\n" +msgid "symbolic link \"%s\" target is too long" +msgstr "mÃ¥l för symbolisk länk \"%s\" är för lÃ¥ng" -#: copy_fetch.c:145 +#: copy_fetch.c:136 #, c-format -msgid "could not read directory \"%s\": %s\n" -msgstr "kunde inte läsa katalog \"%s\": %s\n" +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\" är en symbolisk länk men symboliska länkar stöds inte pÃ¥ denna plattform" -#: copy_fetch.c:149 +#: copy_fetch.c:143 #, c-format -msgid "could not close directory \"%s\": %s\n" -msgstr "kunde inte stänga katalog \"%s\": %s\n" +msgid "could not read directory \"%s\": %m" +msgstr "kunde inte läsa katalog \"%s\": %m" -#: copy_fetch.c:169 +#: copy_fetch.c:147 #, c-format -msgid "could not open source file \"%s\": %s\n" -msgstr "kunde inte öppna källfil \"%s\": %s\n" +msgid "could not close directory \"%s\": %m" +msgstr "kunde inte stänga katalog \"%s\": %m" -#: copy_fetch.c:173 +#: copy_fetch.c:167 #, c-format -msgid "could not seek in source file: %s\n" -msgstr "kunde inte söka i källfil: %s\n" +msgid "could not open source file \"%s\": %m" +msgstr "kunde inte öppna källfil \"%s\": %m" -#: copy_fetch.c:190 file_ops.c:299 +#: copy_fetch.c:171 #, c-format -msgid "could not read file \"%s\": %s\n" -msgstr "kunde inte läsa fil \"%s\": %s\n" +msgid "could not seek in source file: %m" +msgstr "kunde inte söka i källfil: %m" -#: copy_fetch.c:193 +#: copy_fetch.c:188 file_ops.c:312 parsexlog.c:316 #, c-format -msgid "unexpected EOF while reading file \"%s\"\n" -msgstr "oväntad EOF under läsning av fil \"%s\"\n" +msgid "could not read file \"%s\": %m" +msgstr "kunde inte läsa fil \"%s\": %m" -#: copy_fetch.c:200 +#: copy_fetch.c:191 #, c-format -msgid "could not close file \"%s\": %s\n" -msgstr "kunde inte stänga fil \"%s\": %s\n" +msgid "unexpected EOF while reading file \"%s\"" +msgstr "oväntad EOF under läsning av fil \"%s\"" -#: datapagemap.c:124 +#: copy_fetch.c:198 #, c-format -msgid " block %u\n" -msgstr " block %u\n" +msgid "could not close file \"%s\": %m" +msgstr "kunde inte stänga fil \"%s\": %m" #: file_ops.c:63 #, c-format -msgid "could not open target file \"%s\": %s\n" -msgstr "kunde inte öppna mÃ¥lfil \"%s\": %s\n" +msgid "could not open target file \"%s\": %m" +msgstr "kunde inte öppna mÃ¥lfil \"%s\": %m" #: file_ops.c:77 #, c-format -msgid "could not close target file \"%s\": %s\n" -msgstr "kunde inte stänga mÃ¥lfil \"%s\": %s\n" +msgid "could not close target file \"%s\": %m" +msgstr "kunde inte stänga mÃ¥lfil \"%s\": %m" #: file_ops.c:97 #, c-format -msgid "could not seek in target file \"%s\": %s\n" -msgstr "kunde inte söka i mÃ¥lfil \"%s\": %s\n" +msgid "could not seek in target file \"%s\": %m" +msgstr "kunde inte söka i mÃ¥lfil \"%s\": %m" #: file_ops.c:113 #, c-format -msgid "could not write file \"%s\": %s\n" -msgstr "kunde inte skriva fil \"%s\": %s\n" +msgid "could not write file \"%s\": %m" +msgstr "kunde inte skriva fil \"%s\": %m" #: file_ops.c:163 #, c-format -msgid "invalid action (CREATE) for regular file\n" -msgstr "ogiltig aktion (CREATE) för vanlig fil\n" +msgid "invalid action (CREATE) for regular file" +msgstr "ogiltig aktion (CREATE) för vanlig fil" -#: file_ops.c:178 +#: file_ops.c:186 #, c-format -msgid "could not remove file \"%s\": %s\n" -msgstr "kunde inte ta bort fil \"%s\": %s\n" +msgid "could not remove file \"%s\": %m" +msgstr "kunde inte ta bort fil \"%s\": %m" -#: file_ops.c:195 +#: file_ops.c:204 #, c-format -msgid "could not open file \"%s\" for truncation: %s\n" -msgstr "kunde inte öppna fil \"%s\" för trunkering: %s\n" +msgid "could not open file \"%s\" for truncation: %m" +msgstr "kunde inte öppna fil \"%s\" för trunkering: %m" -#: file_ops.c:199 +#: file_ops.c:208 #, c-format -msgid "could not truncate file \"%s\" to %u: %s\n" -msgstr "kunde inte trunkera fil \"%s\" till %u: %s\n" +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "kunde inte trunkera fil \"%s\" till %u: %m" -#: file_ops.c:215 +#: file_ops.c:224 #, c-format -msgid "could not create directory \"%s\": %s\n" -msgstr "kunde inte skapa katalog \"%s\": %s\n" +msgid "could not create directory \"%s\": %m" +msgstr "kunde inte skapa katalog \"%s\": %m" -#: file_ops.c:229 +#: file_ops.c:238 #, c-format -msgid "could not remove directory \"%s\": %s\n" -msgstr "kunde inte radera katalog \"%s\": %s\n" +msgid "could not remove directory \"%s\": %m" +msgstr "kunde inte ta bort katalog \"%s\": %m" -#: file_ops.c:243 +#: file_ops.c:252 #, c-format -msgid "could not create symbolic link at \"%s\": %s\n" -msgstr "kunde inte skapa en symnbolisk länk vid \"%s\": %s\n" +msgid "could not create symbolic link at \"%s\": %m" +msgstr "kunde inte skapa en symnbolisk länk vid \"%s\": %m" -#: file_ops.c:257 +#: file_ops.c:266 #, c-format -msgid "could not remove symbolic link \"%s\": %s\n" -msgstr "kunde inte radera symbolisk länk \"%s\": %s\n" +msgid "could not remove symbolic link \"%s\": %m" +msgstr "kan inte ta bort symbolisk länk \"%s\": %m" -#: file_ops.c:287 file_ops.c:291 +#: file_ops.c:297 file_ops.c:301 #, c-format -msgid "could not open file \"%s\" for reading: %s\n" -msgstr "kunde inte öppna fil \"%s\" för läsning: %s\n" +msgid "could not open file \"%s\" for reading: %m" +msgstr "kunde inte öppna filen \"%s\" för läsning: %m" -#: filemap.c:103 +#: file_ops.c:315 parsexlog.c:318 #, c-format -msgid "data file \"%s\" in source is not a regular file\n" -msgstr "datafil \"%s\" i källan är inte en vanlig fil\n" +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" -#: filemap.c:125 +#: filemap.c:181 #, c-format -msgid "\"%s\" is not a directory\n" -msgstr "\"%s\" är inte en katalog\n" +msgid "data file \"%s\" in source is not a regular file" +msgstr "datafil \"%s\" i källan är inte en vanlig fil" -#: filemap.c:148 +#: filemap.c:203 #, c-format -msgid "\"%s\" is not a symbolic link\n" -msgstr "\"%s\" är inte en symbolisk länk\n" +msgid "\"%s\" is not a directory" +msgstr "\"%s\" är inte en katalog" -#: filemap.c:160 +#: filemap.c:226 #, c-format -msgid "\"%s\" is not a regular file\n" -msgstr "\"%s\" är inte en vanlig fil\n" +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\" är inte en symbolisk länk" -#: filemap.c:278 +#: filemap.c:238 #, c-format -msgid "source file list is empty\n" -msgstr "källfillistan är tom\n" +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" är inte en vanlig fil" -#: filemap.c:400 +#: filemap.c:362 #, c-format -msgid "unexpected page modification for directory or symbolic link \"%s\"\n" -msgstr "oväntad sidmodifiering för katalog eller symbolisk länk \"%s\"\n" +msgid "source file list is empty" +msgstr "källfillistan är tom" -#. translator: first %s is a file path, second is a keyword such as COPY -#: filemap.c:536 +#: filemap.c:477 #, c-format -msgid "%s (%s)\n" -msgstr "%s (%s)\n" +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "oväntad sidmodifiering för katalog eller symbolisk länk \"%s\"" -#: libpq_fetch.c:55 +#: libpq_fetch.c:53 #, c-format msgid "could not connect to server: %s" msgstr "kunde inte ansluta till server: %s" -#: libpq_fetch.c:58 +#: libpq_fetch.c:57 #, c-format -msgid "connected to server\n" -msgstr "ansluten till server\n" +msgid "connected to server" +msgstr "ansluten till server" -#: libpq_fetch.c:68 +#: libpq_fetch.c:61 #, c-format -msgid "source server must not be in recovery mode\n" -msgstr "källserver fÃ¥r inte vara i Ã¥terställningsläge\n" +msgid "could not clear search_path: %s" +msgstr "kunde inte nollställa search_path: %s" -#: libpq_fetch.c:78 +#: libpq_fetch.c:73 #, c-format -msgid "full_page_writes must be enabled in the source server\n" -msgstr "full_page_writes mÃ¥ste vara pÃ¥slagen i källservern\n" +msgid "source server must not be in recovery mode" +msgstr "källserver fÃ¥r inte vara i Ã¥terställningsläge" -#: libpq_fetch.c:90 +#: libpq_fetch.c:83 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "full_page_writes mÃ¥ste vara pÃ¥slagen i källservern" + +#: libpq_fetch.c:95 #, c-format msgid "could not set up connection context: %s" msgstr "kunde inte sätta upp anslutningskontext: %s" -#: libpq_fetch.c:108 +#: libpq_fetch.c:113 #, c-format msgid "error running query (%s) in source server: %s" msgstr "fel vid körande av frÃ¥ga (%s) i källserver: %s" -#: libpq_fetch.c:113 +#: libpq_fetch.c:118 #, c-format -msgid "unexpected result set from query\n" -msgstr "oväntad resultatmängd frÃ¥n frÃ¥ga\n" +msgid "unexpected result set from query" +msgstr "oväntad resultatmängd frÃ¥n frÃ¥ga" -#: libpq_fetch.c:136 +#: libpq_fetch.c:141 #, c-format -msgid "unrecognized result \"%s\" for current WAL insert location\n" -msgstr "oväntat resultat \"%s\" för nuvarande WAL-insättningsposition\n" +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "oväntat resultat \"%s\" för nuvarande WAL-insättningsposition" -#: libpq_fetch.c:186 +#: libpq_fetch.c:191 #, c-format msgid "could not fetch file list: %s" msgstr "kunde inte hämta fillista: %s" -#: libpq_fetch.c:191 +#: libpq_fetch.c:196 #, c-format -msgid "unexpected result set while fetching file list\n" -msgstr "oväntad resultatmängd vid hämtning av fillista\n" +msgid "unexpected result set while fetching file list" +msgstr "oväntad resultatmängd vid hämtning av fillista" -#: libpq_fetch.c:261 +#: libpq_fetch.c:244 #, c-format msgid "could not send query: %s" msgstr "kunde inte skicka frÃ¥ga: %s" -#: libpq_fetch.c:263 -#, c-format -msgid "getting file chunks\n" -msgstr "hämtar fildelar\n" - -#: libpq_fetch.c:266 +#: libpq_fetch.c:249 #, c-format -msgid "could not set libpq connection to single row mode\n" -msgstr "kunde inte sätta libpq-anslutning till enradsläge\n" +msgid "could not set libpq connection to single row mode" +msgstr "kunde inte sätta libpq-anslutning till enradsläge" -#: libpq_fetch.c:286 +#: libpq_fetch.c:270 #, c-format msgid "unexpected result while fetching remote files: %s" msgstr "oväntat resultat vid hämtning av extern fil: %s" -#: libpq_fetch.c:292 +#: libpq_fetch.c:276 #, c-format -msgid "unexpected result set size while fetching remote files\n" -msgstr "oväntad resultatmängdstorlek vid hämtning av externa filer\n" +msgid "unexpected result set size while fetching remote files" +msgstr "oväntad resultatmängdstorlek vid hämtning av externa filer" -#: libpq_fetch.c:298 +#: libpq_fetch.c:282 #, c-format -msgid "" -"unexpected data types in result set while fetching remote files: %u %u %u\n" -msgstr "oväntade datayper i resultatmängd vid hämtning av externa filer: %u %u %u\n" +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "oväntade datayper i resultatmängd vid hämtning av externa filer: %u %u %u" -#: libpq_fetch.c:306 +#: libpq_fetch.c:290 #, c-format -msgid "unexpected result format while fetching remote files\n" -msgstr "oväntat resultatformat vid hämtning av externa filer\n" +msgid "unexpected result format while fetching remote files" +msgstr "oväntat resultatformat vid hämtning av externa filer" -#: libpq_fetch.c:312 +#: libpq_fetch.c:296 #, c-format -msgid "unexpected null values in result while fetching remote files\n" -msgstr "oväntade null-värden i resultat vid hämtning av externa filer\n" +msgid "unexpected null values in result while fetching remote files" +msgstr "oväntade null-värden i resultat vid hämtning av externa filer" -#: libpq_fetch.c:316 +#: libpq_fetch.c:300 #, c-format -msgid "unexpected result length while fetching remote files\n" -msgstr "oväntad resultatlängd vid hämtning av externa filer\n" +msgid "unexpected result length while fetching remote files" +msgstr "oväntad resultatlängd vid hämtning av externa filer" -#: libpq_fetch.c:338 -#, c-format -msgid "received null value for chunk for file \"%s\", file has been deleted\n" -msgstr "mottog null-värde som del av fil \"%s\", filen har blivit raderad\n" - -#: libpq_fetch.c:345 -#, c-format -msgid "received chunk for file \"%s\", offset " -msgstr "mottog del för fil \"%s\", offset " - -#: libpq_fetch.c:374 +#: libpq_fetch.c:366 #, c-format msgid "could not fetch remote file \"%s\": %s" msgstr "kunde inte hämta extern fil \"%s\": %s" -#: libpq_fetch.c:379 +#: libpq_fetch.c:371 #, c-format -msgid "unexpected result set while fetching remote file \"%s\"\n" -msgstr "oväntat resultatmängd vid hämtning av extern fil \"%s\"\n" +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "oväntat resultatmängd vid hämtning av extern fil \"%s\"" -#: libpq_fetch.c:390 -#, c-format -msgid "fetched file \"%s\", length %d\n" -msgstr "hämtade fil \"%s\", längd %d\n" - -#: libpq_fetch.c:423 +#: libpq_fetch.c:415 #, c-format msgid "could not send COPY data: %s" msgstr "kunde inte skicka COPY-data: %s" -#: libpq_fetch.c:449 +#: libpq_fetch.c:441 #, c-format msgid "could not create temporary table: %s" msgstr "kunde inte skapa temporär tabell: %s" -#: libpq_fetch.c:457 +#: libpq_fetch.c:449 #, c-format msgid "could not send file list: %s" msgstr "kunde inte skicka fillista: %s" -#: libpq_fetch.c:499 +#: libpq_fetch.c:491 #, c-format msgid "could not send end-of-COPY: %s" msgstr "kunde inte skicka slut-pÃ¥-COPY: %s" -#: libpq_fetch.c:505 +#: libpq_fetch.c:497 #, c-format msgid "unexpected result while sending file list: %s" msgstr "oväntat resultat vid skickande av fillista: %s" -#: logging.c:57 -msgid "Failure, exiting\n" -msgstr "Misslyckades, avslutar\n" - -#: logging.c:140 +#: logging.c:72 #, c-format msgid "%*s/%s kB (%d%%) copied" msgstr "%*s/%s kB (%d%%) kopierad" -#: parsexlog.c:87 parsexlog.c:133 +#: parsexlog.c:75 parsexlog.c:129 parsexlog.c:187 #, c-format -msgid "could not read WAL record at %X/%X: %s\n" -msgstr "kunde inte läsa WAL-post vid %X/%X: %s\n" +msgid "out of memory" +msgstr "slut pÃ¥ minne" -#: parsexlog.c:91 parsexlog.c:136 +#: parsexlog.c:88 parsexlog.c:135 #, c-format -msgid "could not read WAL record at %X/%X\n" -msgstr "kunde inte läsa WAL-post vid %X/%X\n" +msgid "could not read WAL record at %X/%X: %s" +msgstr "kunde inte läsa WAL-post vid %X/%X: %s" -#: parsexlog.c:191 +#: parsexlog.c:92 parsexlog.c:138 #, c-format -msgid "could not find previous WAL record at %X/%X: %s\n" -msgstr "kunde inte hitta föregÃ¥ende WAL-post vid %X/%X: %s\n" +msgid "could not read WAL record at %X/%X" +msgstr "kunde inte läsa WAL-post vid %X/%X" -#: parsexlog.c:195 +#: parsexlog.c:199 #, c-format -msgid "could not find previous WAL record at %X/%X\n" -msgstr "kunde inte hitta förgÃ¥ende WAL-post vid %X/%X\n" +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "kunde inte hitta föregÃ¥ende WAL-post vid %X/%X: %s" -#: parsexlog.c:283 +#: parsexlog.c:203 #, c-format -msgid "could not open file \"%s\": %s\n" -msgstr "kan inte öppna fil \"%s\": %s\n" +msgid "could not find previous WAL record at %X/%X" +msgstr "kunde inte hitta förgÃ¥ende WAL-post vid %X/%X" -#: parsexlog.c:297 +#: parsexlog.c:294 #, c-format -msgid "could not seek in file \"%s\": %s\n" -msgstr "kunde inte söka i fil \"%s\": %s\n" +msgid "could not open file \"%s\": %m" +msgstr "kunde inte öppna fil \"%s\": %m" -#: parsexlog.c:304 +#: parsexlog.c:307 #, c-format -msgid "could not read from file \"%s\": %s\n" -msgstr "kunde inte läsa frÃ¥n fil \"%s\": %s\n" +msgid "could not seek in file \"%s\": %m" +msgstr "kunde inte söka (seek) i fil \"%s\": %m" -#: parsexlog.c:372 +#: parsexlog.c:387 #, c-format -msgid "" -"WAL record modifies a relation, but record type is not recognized\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" -msgstr "" -"WAL-post modifierar en relation, men posttypen känns inte igen\n" -"lsn: %X/%X, rmgr: %s, info: %02X\n" +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL-post modifierar en relation, men posttypen känns inte igen: lsn: %X/%X, rmgr: %s, info: %02X" -#: pg_rewind.c:64 +#: pg_rewind.c:69 #, c-format msgid "" "%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" "\n" -msgstr "%s resynkroniserar ett PostgreSQL-kluster med en annan kopia av klustret.\n\n" +msgstr "" +"%s resynkroniserar ett PostgreSQL-kluster med en annan kopia av klustret.\n" +"\n" -#: pg_rewind.c:65 +#: pg_rewind.c:70 #, c-format msgid "" "Usage:\n" @@ -447,434 +433,562 @@ msgstr "" " %s [FLAGGA]...\n" "\n" -#: pg_rewind.c:66 +#: pg_rewind.c:71 #, c-format msgid "Options:\n" msgstr "Flaggor:\n" -#: pg_rewind.c:67 +#: pg_rewind.c:72 #, c-format msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" msgstr " -D, --target-pgdata=KATALOG existerande datakatalog att modifiera\n" -#: pg_rewind.c:68 +#: pg_rewind.c:73 #, c-format -msgid "" -" --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" msgstr " --source-pgdata=KATALOG källdatakatalog att synkronisera med\n" -#: pg_rewind.c:69 +#: pg_rewind.c:74 #, c-format msgid " --source-server=CONNSTR source server to synchronize with\n" msgstr " --source-server=ANSLSTR källserver att synkronisera med\n" -#: pg_rewind.c:70 +#: pg_rewind.c:75 #, c-format msgid " -n, --dry-run stop before modifying anything\n" msgstr " -n, --dry-run stoppa innan nÃ¥got modifieras\n" -#: pg_rewind.c:71 +#: pg_rewind.c:76 +#, c-format +msgid "" +" -N, --no-sync do not wait for changes to be written\n" +" safely to disk\n" +msgstr "" +" -N, --no-sync vänta inte pÃ¥ att ändingar säkert\n" +" skrivits till disk\n" + +#: pg_rewind.c:78 #, c-format msgid " -P, --progress write progress messages\n" msgstr " -P, --progress skriv ut förloppmeddelanden\n" -#: pg_rewind.c:72 +#: pg_rewind.c:79 #, c-format msgid " --debug write a lot of debug messages\n" msgstr " --debug skriv ut en massa debugmeddelanden\n" -#: pg_rewind.c:73 +#: pg_rewind.c:80 #, c-format -msgid "" -" -V, --version output version information, then exit\n" +msgid " -V, --version output version information, then exit\n" msgstr " -V, --version skriv ut versioninformation och avsluta sedan\n" -#: pg_rewind.c:74 +#: pg_rewind.c:81 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp och avsluta sedan\n" -#: pg_rewind.c:75 +#: pg_rewind.c:82 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapportera fel till .\n" +"Rapportera fel till .\n" -#: pg_rewind.c:130 pg_rewind.c:161 pg_rewind.c:168 pg_rewind.c:175 -#: pg_rewind.c:183 +#: pg_rewind.c:139 pg_rewind.c:175 pg_rewind.c:182 pg_rewind.c:189 +#: pg_rewind.c:197 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_rewind.c:160 +#: pg_rewind.c:174 #, c-format -msgid "%s: no source specified (--source-pgdata or --source-server)\n" -msgstr "%s: ingen källa angavs (--source-pgdata eller --source-server)\n" +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "ingen källa angavs (--source-pgdata eller --source-server)" -#: pg_rewind.c:167 +#: pg_rewind.c:181 #, c-format -msgid "%s: only one of --source-pgdata or --source-server can be specified\n" -msgstr "%s: bara en av --source-pgdata och --source-server fÃ¥r anges\n" +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "bara en av --source-pgdata och --source-server fÃ¥r anges" -#: pg_rewind.c:174 +#: pg_rewind.c:188 #, c-format -msgid "%s: no target data directory specified (--target-pgdata)\n" -msgstr "%s: ingen mÃ¥ldatakatalog angiven (--target-pgdata)\n" +msgid "no target data directory specified (--target-pgdata)" +msgstr "ingen mÃ¥ldatakatalog angiven (--target-pgdata)" -#: pg_rewind.c:181 +#: pg_rewind.c:195 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: pg_rewind.c:196 +#: pg_rewind.c:210 #, c-format -msgid "cannot be executed by \"root\"\n" -msgstr "kan inte köras av \"root\"\n" +msgid "cannot be executed by \"root\"" +msgstr "kan inte köras av \"root\"" -#: pg_rewind.c:197 +#: pg_rewind.c:211 #, c-format msgid "You must run %s as the PostgreSQL superuser.\n" msgstr "Du mÃ¥ste köra %s som PostgreSQL:s superanvändare.\n" -#: pg_rewind.c:228 +#: pg_rewind.c:222 #, c-format -msgid "source and target cluster are on the same timeline\n" -msgstr "källa och mÃ¥lkluster är pÃ¥ samma tidslinje\n" +msgid "could not read permissions of directory \"%s\": %m" +msgstr "kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %m" -#: pg_rewind.c:234 +#: pg_rewind.c:253 #, c-format -msgid "servers diverged at WAL location %X/%X on timeline %u\n" -msgstr "servrarna divergerade vid WAL-position %X/%X pÃ¥ tidslinje %u\n" +msgid "source and target cluster are on the same timeline" +msgstr "källa och mÃ¥lkluster är pÃ¥ samma tidslinje" -#: pg_rewind.c:271 +#: pg_rewind.c:259 #, c-format -msgid "no rewind required\n" -msgstr "ingen rewind krävs\n" +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "servrarna divergerade vid WAL-position %X/%X pÃ¥ tidslinje %u" -#: pg_rewind.c:278 +#: pg_rewind.c:296 #, c-format -msgid "rewinding from last common checkpoint at %X/%X on timeline %u\n" -msgstr "rewind frÃ¥n senaste gemensamma checkpoint vid %X/%X pÃ¥ tidslinje %u\n" +msgid "no rewind required" +msgstr "ingen rewind krävs" -#: pg_rewind.c:286 +#: pg_rewind.c:303 #, c-format -msgid "reading source file list\n" -msgstr "läser källfillista\n" +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "rewind frÃ¥n senaste gemensamma checkpoint vid %X/%X pÃ¥ tidslinje %u" -#: pg_rewind.c:288 +#: pg_rewind.c:312 #, c-format -msgid "reading target file list\n" -msgstr "läser mÃ¥lfillista\n" - -#: pg_rewind.c:298 -#, c-format -msgid "reading WAL in target\n" -msgstr "läser WAL i mÃ¥let\n" +msgid "reading source file list" +msgstr "läser källfillista" #: pg_rewind.c:315 #, c-format -msgid "need to copy %lu MB (total source directory size is %lu MB)\n" -msgstr "behöver kopiera %lu MB (total källkatalogstorlek är %lu MB)\n" +msgid "reading target file list" +msgstr "läser mÃ¥lfillista" -#: pg_rewind.c:332 +#: pg_rewind.c:326 #, c-format -msgid "" -"\n" -"creating backup label and updating control file\n" -msgstr "\nskapar backupetikett och uppdaterar kontrollfil\n" +msgid "reading WAL in target" +msgstr "läser WAL i mÃ¥let" -#: pg_rewind.c:360 +#: pg_rewind.c:343 #, c-format -msgid "syncing target data directory\n" -msgstr "synkar mÃ¥ldatakatalog\n" +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "behöver kopiera %lu MB (total källkatalogstorlek är %lu MB)" -#: pg_rewind.c:363 +#: pg_rewind.c:362 #, c-format -msgid "Done!\n" -msgstr "Klar!\n" +msgid "creating backup label and updating control file" +msgstr "skapar backupetikett och uppdaterar kontrollfil" -#: pg_rewind.c:375 +#: pg_rewind.c:391 #, c-format -msgid "source and target clusters are from different systems\n" -msgstr "källa och mÃ¥lkluster är frÃ¥n olika system\n" +msgid "syncing target data directory" +msgstr "synkar mÃ¥ldatakatalog" -#: pg_rewind.c:383 +#: pg_rewind.c:394 #, c-format -msgid "clusters are not compatible with this version of pg_rewind\n" -msgstr "klustren är inte kompatibla med denna version av pg_rewind\n" +msgid "Done!" +msgstr "Klar!" -#: pg_rewind.c:393 +#: pg_rewind.c:406 #, c-format -msgid "" -"target server needs to use either data checksums or \"wal_log_hints = on\"\n" -msgstr "mÃ¥lservern behöver använda antingen datachecksums eller \"wal_log_hints = on\"\n" - -#: pg_rewind.c:404 -#, c-format -msgid "target server must be shut down cleanly\n" -msgstr "mÃ¥lserver mÃ¥ste stängas ner utan fel\n" +msgid "source and target clusters are from different systems" +msgstr "källa och mÃ¥lkluster är frÃ¥n olika system" #: pg_rewind.c:414 #, c-format -msgid "source data directory must be shut down cleanly\n" -msgstr "mÃ¥ldatakatalog mÃ¥ste stängas ner utan fel\n" +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "klustren är inte kompatibla med denna version av pg_rewind" -#: pg_rewind.c:469 +#: pg_rewind.c:424 #, c-format -msgid "invalid control file" -msgstr "ogiltig kontrollfil" +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "mÃ¥lservern behöver använda antingen datachecksums eller \"wal_log_hints = on\"" -#: pg_rewind.c:480 +#: pg_rewind.c:435 #, c-format -msgid "Source timeline history:\n" -msgstr "Källans tidslinjehistorik:\n" +msgid "target server must be shut down cleanly" +msgstr "mÃ¥lserver mÃ¥ste stängas ner utan fel" -#: pg_rewind.c:482 +#: pg_rewind.c:445 #, c-format -msgid "Target timeline history:\n" -msgstr "MÃ¥lets tidslinjehistorik:\n" +msgid "source data directory must be shut down cleanly" +msgstr "mÃ¥ldatakatalog mÃ¥ste stängas ner utan fel" -#. translator: %d is a timeline number, others are LSN positions -#: pg_rewind.c:496 +#: pg_rewind.c:500 #, c-format -msgid "%d: %X/%X - %X/%X\n" -msgstr "%d: %X/%X - %X/%X\n" +msgid "invalid control file\n" +msgstr "ogiltig kontrollfil\n" -#: pg_rewind.c:555 +#: pg_rewind.c:584 #, c-format -msgid "" -"could not find common ancestor of the source and target cluster's timelines\n" -msgstr "kunde inte finna en gemensam anfader av källa och mÃ¥lklusterets tidslinjer\n" +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "kunde inte finna en gemensam anfader av källa och mÃ¥lklusterets tidslinjer" -#: pg_rewind.c:596 +#: pg_rewind.c:625 #, c-format -msgid "backup label buffer too small\n" -msgstr "backupetikett-buffer för liten\n" +msgid "backup label buffer too small" +msgstr "backupetikett-buffer för liten" -#: pg_rewind.c:619 +#: pg_rewind.c:648 #, c-format -msgid "unexpected control file CRC\n" -msgstr "oväntad kontrollfil-CRC\n" +msgid "unexpected control file CRC" +msgstr "oväntad kontrollfil-CRC" -#: pg_rewind.c:629 +#: pg_rewind.c:658 #, c-format -msgid "unexpected control file size %d, expected %d\n" -msgstr "oväntad kontrollfilstorlek %d, förväntade %d\n" +msgid "unexpected control file size %d, expected %d" +msgstr "oväntad kontrollfilstorlek %d, förväntade %d" -#: pg_rewind.c:705 +#: pg_rewind.c:667 #, c-format -msgid "" -"The program \"initdb\" is needed by %s but was\n" -"not found in the same directory as \"%s\".\n" -"Check your installation.\n" -msgstr "" -"Programmet \"initdb\" krävs av %s men\n" -"hittades inte i samma katalog som \"%s\".\n" -"Kontrollera din installation.\n" +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte" +msgstr[1] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte" -#: pg_rewind.c:709 +#: timeline.c:77 timeline.c:83 #, c-format -msgid "" -"The program \"initdb\" was found by \"%s\"\n" -"but was not the same version as %s.\n" -"Check your installation.\n" -msgstr "" -"Programmet \"initdb\" hittades av \"%s\"\n" -"men var inte av samma version som %s.\n" -"Kontrollera din installation.\n" +msgid "syntax error in history file: %s" +msgstr "syntaxfel i history-fil: %s" -#: pg_rewind.c:727 +#: timeline.c:78 #, c-format -msgid "sync of target directory failed\n" -msgstr "synk av mÃ¥lkatalog misslyckades\n" +msgid "Expected a numeric timeline ID." +msgstr "Förväntade ett numeriskt tidslinje-ID." -#: timeline.c:76 timeline.c:82 +#: timeline.c:84 #, c-format -msgid "syntax error in history file: %s\n" -msgstr "syntaxfel i historikfil: %s\n" - -#: timeline.c:77 -#, c-format -msgid "Expected a numeric timeline ID.\n" -msgstr "Förväntade ett numeriskt tidslinje-ID.\n" - -#: timeline.c:83 -#, c-format -msgid "Expected a write-ahead log switchpoint location.\n" -msgstr "Förväntade en write-ahead-log brytpunktposition.\n" - -#: timeline.c:88 -#, c-format -msgid "invalid data in history file: %s\n" -msgstr "ogiltig data i historikfil: %s\n" +msgid "Expected a write-ahead log switchpoint location." +msgstr "Förväntade en write-ahead-logg:s switchpoint-position." #: timeline.c:89 #, c-format -msgid "Timeline IDs must be in increasing sequence.\n" -msgstr "Tidslinje-ID:er mÃ¥ste komma i en ökande sekvens.\n" +msgid "invalid data in history file: %s" +msgstr "felaktig data i history-fil: %s" -#: timeline.c:109 +#: timeline.c:90 #, c-format -msgid "invalid data in history file\n" -msgstr "ogiltig data i historikfil\n" +msgid "Timeline IDs must be in increasing sequence." +msgstr "Tidslinje-ID mÃ¥ste komma i en stigande sekvens." #: timeline.c:110 #, c-format -msgid "Timeline IDs must be less than child timeline's ID.\n" -msgstr "Tidslinje-ID:er mÃ¥ste vara mindre än barnets tidslinjes ID.\n" +msgid "invalid data in history file" +msgstr "ogiltig data i historikfil" -#: xlogreader.c:276 +#: timeline.c:111 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "Tidslinje-ID:er mÃ¥ste vara mindre än barnens tidslinje-ID:er." + +#: xlogreader.c:299 #, c-format msgid "invalid record offset at %X/%X" msgstr "ogiltig postoffset vid %X/%X" -#: xlogreader.c:284 +#: xlogreader.c:307 #, c-format msgid "contrecord is requested by %X/%X" msgstr "contrecord är begärd vid %X/%X" -#: xlogreader.c:325 xlogreader.c:625 +#: xlogreader.c:348 xlogreader.c:645 #, c-format msgid "invalid record length at %X/%X: wanted %u, got %u" msgstr "ogiltig postlängd vid %X/%X: förväntade %u, fick %u" -#: xlogreader.c:340 +#: xlogreader.c:372 #, c-format msgid "record length %u at %X/%X too long" msgstr "postlängd %u vid %X/%X är för lÃ¥ng" -#: xlogreader.c:381 +#: xlogreader.c:404 #, c-format msgid "there is no contrecord flag at %X/%X" msgstr "det finns ingen contrecord-flagga vid %X/%X" -#: xlogreader.c:394 +#: xlogreader.c:417 #, c-format msgid "invalid contrecord length %u at %X/%X" msgstr "ogiltig contrecord-längd %u vid %X/%X" -#: xlogreader.c:633 +#: xlogreader.c:653 #, c-format msgid "invalid resource manager ID %u at %X/%X" msgstr "ogiltigt resurshanterar-ID %u vid %X/%X" -#: xlogreader.c:647 xlogreader.c:664 +#: xlogreader.c:667 xlogreader.c:684 #, c-format msgid "record with incorrect prev-link %X/%X at %X/%X" msgstr "post med inkorrekt prev-link %X/%X vid %X/%X" -#: xlogreader.c:701 +#: xlogreader.c:721 #, c-format msgid "incorrect resource manager data checksum in record at %X/%X" msgstr "felaktig resurshanterardatakontrollsumma i post vid %X/%X" -#: xlogreader.c:734 +#: xlogreader.c:758 #, c-format msgid "invalid magic number %04X in log segment %s, offset %u" msgstr "felaktigt magiskt nummer %04X i loggsegment %s, offset %u" -#: xlogreader.c:748 xlogreader.c:799 +#: xlogreader.c:772 xlogreader.c:823 #, c-format msgid "invalid info bits %04X in log segment %s, offset %u" msgstr "ogiltiga infobitar %04X i loggsegment %s, offset %u" -#: xlogreader.c:774 +#: xlogreader.c:798 #, c-format -msgid "" -"WAL file is from different database system: WAL file database system " -"identifier is %s, pg_control database system identifier is %s" -msgstr "" -"WAL-fil är frÃ¥n ett annat databassystem: WAL-filens " -"databassystemidentifierare är %s, pg_control databassystemidentifierare är %s" +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: WAL-filens databassystemidentifierare är %s, pg_control databassystemidentifierare är %s" -#: xlogreader.c:781 +#: xlogreader.c:805 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_SEG_SIZE in page " -"header" -msgstr "" -"WAL-fil är frÃ¥n ett annat databassystem: felaktig XLOG_SEG_SIZE i sidhuvud" +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: inkorrekt segmentstorlek i sidhuvud" -#: xlogreader.c:787 +#: xlogreader.c:811 #, c-format -msgid "" -"WAL file is from different database system: incorrect XLOG_BLCKSZ in page " -"header" -msgstr "" -"WAL-fil är frÃ¥n ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvuid" +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL-fil är frÃ¥n ett annat databassystem: inkorrekt XLOG_BLCKSZ i sidhuvud" -#: xlogreader.c:813 +#: xlogreader.c:842 #, c-format msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" msgstr "oväntad sidadress %X/%X i loggsegment %s, offset %u" -#: xlogreader.c:838 +#: xlogreader.c:867 #, c-format msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" msgstr "ej-i-sekvens för tidslinje-ID %u (efter %u) i loggsegment %s, offset %u" -#: xlogreader.c:1083 +#: xlogreader.c:1112 #, c-format msgid "out-of-order block_id %u at %X/%X" msgstr "ej-i-sekvens block_id %u vid %X/%X" -#: xlogreader.c:1106 +#: xlogreader.c:1135 #, c-format msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" msgstr "BKPBLOCK_HAS_DATA satt, men ingen data inkluderad vid %X/%X" -#: xlogreader.c:1113 +#: xlogreader.c:1142 #, c-format msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" msgstr "BKPBLOCK_HAS_DATA ej satt, men datalängd är %u vid %X/%X" -#: xlogreader.c:1149 +#: xlogreader.c:1178 #, c-format -msgid "" -"BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at " -"%X/%X" -msgstr "" -"BKPIMAGE_HAS_HOLE satt, men hÃ¥loffset %u längd %u block-image-längd %u vid " -"%X/%X" +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE satt, men hÃ¥loffset %u längd %u block-image-längd %u vid %X/%X" -#: xlogreader.c:1165 +#: xlogreader.c:1194 #, c-format msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" msgstr "BKPIMAGE_HAS_HOLE ej satt, men hÃ¥loffset %u längd %u vid %X/%X" -#: xlogreader.c:1180 +#: xlogreader.c:1209 #, c-format msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" msgstr "BKPIMAGE_IS_COMPRESSED satt, men block-image-längd %u vid %X/%X" -#: xlogreader.c:1195 +#: xlogreader.c:1224 #, c-format -msgid "" -"neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image " -"length is %u at %X/%X" -msgstr "" -"varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_IS_COMPRESSED satt, men block-image-" -"längd är %u vid %X/%X" +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "varken BKPIMAGE_HAS_HOLE eller BKPIMAGE_IS_COMPRESSED satt, men block-image-längd är %u vid %X/%X" -#: xlogreader.c:1211 +#: xlogreader.c:1240 #, c-format msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" msgstr "BKPBLOCK_SAME_REL satt men ingen tidigare rel vid %X/%X" -#: xlogreader.c:1223 +#: xlogreader.c:1252 #, c-format msgid "invalid block_id %u at %X/%X" msgstr "ogiltig block_id %u vid %X/%X" -#: xlogreader.c:1291 +#: xlogreader.c:1341 #, c-format msgid "record with invalid length at %X/%X" msgstr "post med ogiltig längd vid %X/%X" -#: xlogreader.c:1380 +#: xlogreader.c:1430 #, c-format msgid "invalid compressed image at %X/%X, block %d" msgstr "ogiltig komprimerad image vid %X/%X, block %d" + +#~ msgid "%s: WARNING: cannot create restricted tokens on this platform\n" +#~ msgstr "%s: VARNING: \"restricted Token\" stöds inte av plattformen.\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: kunde inte öppna process-token: felkod %lu\n" + +#~ msgid "%s: could not allocate SIDs: error code %lu\n" +#~ msgstr "%s: kunde inte tilldela SID: felkod %lu\n" + +#~ msgid "%s: could not create restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte skapa restriktivt styrmärke (token): felkod %lu\n" + +#~ msgid "%s: could not start process for command \"%s\": error code %lu\n" +#~ msgstr "%s: kunde inte starta process för kommando \"%s\": felkod %lu\n" + +#~ msgid "%s: could not re-execute with restricted token: error code %lu\n" +#~ msgstr "%s: kunde inte upprepa med restriktivt styrmärke (token): felkod %lu\n" + +#~ msgid "%s: could not get exit code from subprocess: error code %lu\n" +#~ msgstr "%s: kunde inte utvinna statuskod för underprocess: felkod %lu\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "kunde inte öppna katalog \"%s\": %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %s\n" + +#~ msgid "could not read symbolic link \"%s\": %s\n" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\": %s\n" + +#~ msgid "symbolic link \"%s\" target is too long\n" +#~ msgstr "mÃ¥l för symbolisk länk \"%s\" är för lÃ¥ng\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "kunde inte läsa katalog \"%s\": %s\n" + +#~ msgid "could not close directory \"%s\": %s\n" +#~ msgstr "kunde inte stänga katalog \"%s\": %s\n" + +#~ msgid "could not read file \"%s\": %s\n" +#~ msgstr "kunde inte läsa fil \"%s\": %s\n" + +#~ msgid "could not close file \"%s\": %s\n" +#~ msgstr "kunde inte stänga fil \"%s\": %s\n" + +#~ msgid " block %u\n" +#~ msgstr " block %u\n" + +#~ msgid "could not write file \"%s\": %s\n" +#~ msgstr "kunde inte skriva fil \"%s\": %s\n" + +#~ msgid "could not remove file \"%s\": %s\n" +#~ msgstr "kunde inte ta bort fil \"%s\": %s\n" + +#~ msgid "could not truncate file \"%s\" to %u: %s\n" +#~ msgstr "kunde inte trunkera fil \"%s\" till %u: %s\n" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "kunde inte skapa katalog \"%s\": %s\n" + +#~ msgid "could not remove directory \"%s\": %s\n" +#~ msgstr "kunde inte radera katalog \"%s\": %s\n" + +#~ msgid "could not remove symbolic link \"%s\": %s\n" +#~ msgstr "kunde inte radera symbolisk länk \"%s\": %s\n" + +#~ msgid "could not open file \"%s\" for reading: %s\n" +#~ msgstr "kunde inte öppna fil \"%s\" för läsning: %s\n" + +#~ msgid "entry \"%s\" excluded from source file list\n" +#~ msgstr "post \"%s\" utesluten frÃ¥n källfillista\n" + +#~ msgid "entry \"%s\" excluded from target file list\n" +#~ msgstr "post \"%s\" utesluten frÃ¥n mÃ¥lfillista\n" + +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" + +#~ msgid "getting file chunks\n" +#~ msgstr "hämtar fildelar\n" + +#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "mottog null-värde som del av fil \"%s\", filen har blivit raderad\n" + +#~ msgid "received chunk for file \"%s\", offset %s, size %d\n" +#~ msgstr "mottog del för fil \"%s\", offset %s, storlek %d\n" + +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "hämtade fil \"%s\", längd %d\n" + +#~ msgid "Failure, exiting\n" +#~ msgstr "Misslyckades, avslutar\n" + +#~ msgid "could not open file \"%s\": %s\n" +#~ msgstr "kan inte öppna fil \"%s\": %s\n" + +#~ msgid "could not seek in file \"%s\": %s\n" +#~ msgstr "kunde inte söka i fil \"%s\": %s\n" + +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "kunde inte läsa frÃ¥n fil \"%s\": %s\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapportera fel till .\n" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %s\n" + +#~ msgid "Source timeline history:\n" +#~ msgstr "Källans tidslinjehistorik:\n" + +#~ msgid "Target timeline history:\n" +#~ msgstr "MÃ¥lets tidslinjehistorik:\n" + +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d: %X/%X - %X/%X\n" + +#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte\n" +#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes\n" +#~ msgstr[0] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte\n" +#~ msgstr[1] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men kontrollfilen anger %d byte\n" + +#~ msgid "" +#~ "The program \"initdb\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Programmet \"initdb\" krävs av %s men\n" +#~ "hittades inte i samma katalog som \"%s\".\n" +#~ "Kontrollera din installation.\n" + +#~ msgid "" +#~ "The program \"initdb\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "Programmet \"initdb\" hittades av \"%s\"\n" +#~ "men var inte av samma version som %s.\n" +#~ "Kontrollera din installation.\n" + +#~ msgid "sync of target directory failed\n" +#~ msgstr "synk av mÃ¥lkatalog misslyckades\n" + +#~ msgid "syntax error in history file: %s\n" +#~ msgstr "syntaxfel i historikfil: %s\n" + +#~ msgid "Expected a numeric timeline ID.\n" +#~ msgstr "Förväntade ett numeriskt tidslinje-ID.\n" + +#~ msgid "Expected a write-ahead log switchpoint location.\n" +#~ msgstr "Förväntade en write-ahead-log brytpunktposition.\n" + +#~ msgid "invalid data in history file: %s\n" +#~ msgstr "ogiltig data i historikfil: %s\n" + +#~ msgid "Timeline IDs must be in increasing sequence.\n" +#~ msgstr "Tidslinje-ID:er mÃ¥ste komma i en ökande sekvens.\n" + +#~ msgid "Timeline IDs must be less than child timeline's ID.\n" +#~ msgstr "Tidslinje-ID:er mÃ¥ste vara mindre än barnets tidslinjes ID.\n" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "WAL-fil är frÃ¥n ett annat databassystem: felaktig XLOG_SEG_SIZE i sidhuvud" + +#~ msgid "%s: unable to read permissions from \"%s\"\n" +#~ msgstr "%s: kunde inte läsa rättigheter frÃ¥n \"%s\"\n" diff --git a/src/bin/pg_rewind/po/tr.po b/src/bin/pg_rewind/po/tr.po new file mode 100644 index 00000000000..d31493101c6 --- /dev/null +++ b/src/bin/pg_rewind/po/tr.po @@ -0,0 +1,966 @@ +# LANGUAGE message translation file for pg_rewind +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_rewind (PostgreSQL) package. +# Abdullah GÜLNER , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_rewind (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:48+0000\n" +"PO-Revision-Date: 2019-06-12 16:57+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/restricted_token.c:69 +#, c-format +msgid "cannot create restricted tokens on this platform" +msgstr "bu platformda restricted token oluÅŸturulamıyor" + +#: ../../common/restricted_token.c:78 +#, c-format +msgid "could not open process token: error code %lu" +msgstr "process token açma baÅŸarısız: hata kodu %lu" + +#: ../../common/restricted_token.c:91 +#, c-format +msgid "could not allocate SIDs: error code %lu" +msgstr "SIDler ayrılamıyor (allocate): hata kodu %lu" + +#: ../../common/restricted_token.c:110 +#, c-format +msgid "could not create restricted token: error code %lu" +msgstr "restricted token oluÅŸturulamıyor: hata kodu %lu" + +#: ../../common/restricted_token.c:131 +#, c-format +msgid "could not start process for command \"%s\": error code %lu" +msgstr "\"%s\" komutu için iÅŸlem (process) baÅŸlatılamadı: hata kodu %lu" + +#: ../../common/restricted_token.c:169 +#, c-format +msgid "could not re-execute with restricted token: error code %lu" +msgstr "restricted token ile tekrar çalıştırılamadı (re-execute): hata kodu %lu" + +#: ../../common/restricted_token.c:185 +#, c-format +msgid "could not get exit code from subprocess: error code %lu" +msgstr "alt-iÅŸlemden çıkış kodu alınamadı: hata kodu %lu" + +#: copy_fetch.c:60 +#, c-format +msgid "could not open directory \"%s\": %m" +msgstr "\"%s\" dizini açılamıyor: %m" + +#: copy_fetch.c:89 filemap.c:189 filemap.c:350 +#, c-format +msgid "could not stat file \"%s\": %m" +msgstr "\"%s\" dosyası durumlanamadı: %m" + +#: copy_fetch.c:118 +#, c-format +msgid "could not read symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" okuma hatası: %m" + +#: copy_fetch.c:121 +#, c-format +msgid "symbolic link \"%s\" target is too long" +msgstr "symbolic link \"%s\" hedefi çok uzun" + +#: copy_fetch.c:136 +#, c-format +msgid "\"%s\" is a symbolic link, but symbolic links are not supported on this platform" +msgstr "\"%s\" bir sembolik link, fakat bu platformda sembolik linkler desteklenmiyor" + +#: copy_fetch.c:143 +#, c-format +msgid "could not read directory \"%s\": %m" +msgstr "\"%s\" dizini okunamıyor: %m" + +#: copy_fetch.c:147 +#, c-format +msgid "could not close directory \"%s\": %m" +msgstr "\"%s\" dizini kapatılamadı: %m" + +#: copy_fetch.c:167 +#, c-format +msgid "could not open source file \"%s\": %m" +msgstr "\"%s\" kaynak dosyası açılamadı: %m" + +#: copy_fetch.c:171 +#, c-format +msgid "could not seek in source file: %m" +msgstr "kaynak dosyada arama yapılamadı: %m" + +#: copy_fetch.c:188 file_ops.c:312 parsexlog.c:316 +#, c-format +msgid "could not read file \"%s\": %m" +msgstr "\"%s\" dosyası okuma hatası: %m" + +#: copy_fetch.c:191 +#, c-format +msgid "unexpected EOF while reading file \"%s\"" +msgstr "\"%s\" dosyası okunurken beklenmedik dosya sonu (EOF)" + +#: copy_fetch.c:198 +#, c-format +msgid "could not close file \"%s\": %m" +msgstr "\"%s\" dosyası kapatılamıyor: %m" + +#: file_ops.c:63 +#, c-format +msgid "could not open target file \"%s\": %m" +msgstr "\"%s\" hedef dosyası açılamadı: %m" + +#: file_ops.c:77 +#, c-format +msgid "could not close target file \"%s\": %m" +msgstr "\"%s\" hedef dosyası kapatılamadı: %m" + +#: file_ops.c:97 +#, c-format +msgid "could not seek in target file \"%s\": %m" +msgstr "\"%s\" hedef dosyasında arama yapılamadı: %m" + +#: file_ops.c:113 +#, c-format +msgid "could not write file \"%s\": %m" +msgstr "\"%s\" dosyasına yazma hatası: %m" + +#: file_ops.c:163 +#, c-format +msgid "invalid action (CREATE) for regular file" +msgstr "normal (regular) dosya için geçersiz iÅŸlem (CREATE)" + +#: file_ops.c:186 +#, c-format +msgid "could not remove file \"%s\": %m" +msgstr "\"%s\" dosyası silinemedi: %m" + +#: file_ops.c:204 +#, c-format +msgid "could not open file \"%s\" for truncation: %m" +msgstr "\"%s\" dosyası küçültme (truncation) için açılamadı: %m" + +#: file_ops.c:208 +#, c-format +msgid "could not truncate file \"%s\" to %u: %m" +msgstr "%s dosyası %u'ya küçültülemedi: %m" + +#: file_ops.c:224 +#, c-format +msgid "could not create directory \"%s\": %m" +msgstr "\"%s\" dizini oluÅŸturulamadı: %m" + +#: file_ops.c:238 +#, c-format +msgid "could not remove directory \"%s\": %m" +msgstr "\"%s\" dizini silme hatası: %m" + +#: file_ops.c:252 +#, c-format +msgid "could not create symbolic link at \"%s\": %m" +msgstr "\"%s\" de sembolik link oluÅŸturulamadı: %m" + +#: file_ops.c:266 +#, c-format +msgid "could not remove symbolic link \"%s\": %m" +msgstr "symbolic link \"%s\" kaldırma hatası: %m" + +#: file_ops.c:297 file_ops.c:301 +#, c-format +msgid "could not open file \"%s\" for reading: %m" +msgstr "\"%s\" dosyası, okunmak için açılamadı: %m" + +#: file_ops.c:315 parsexlog.c:318 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%1$s\" dosyası okuma hatası: %3$zu nun %2$d si okundu" + +#: filemap.c:181 +#, c-format +msgid "data file \"%s\" in source is not a regular file" +msgstr "kaynaktaki \"%s\" veri dosyası normal (regular) bir dosya deÄŸil" + +#: filemap.c:203 +#, c-format +msgid "\"%s\" is not a directory" +msgstr "\"%s\" bir dizin deÄŸil" + +#: filemap.c:226 +#, c-format +msgid "\"%s\" is not a symbolic link" +msgstr "\"%s\" bir sembolik link deÄŸil" + +#: filemap.c:238 +#, c-format +msgid "\"%s\" is not a regular file" +msgstr "\"%s\" normal (regular) bir dosya deÄŸil" + +#: filemap.c:362 +#, c-format +msgid "source file list is empty" +msgstr "kaynak dosya listesi boÅŸ" + +#: filemap.c:477 +#, c-format +msgid "unexpected page modification for directory or symbolic link \"%s\"" +msgstr "\"%s\" dizini veya sembolik linki için beklenmedik sayfa deÄŸiÅŸikliÄŸi (page modification)" + +#: libpq_fetch.c:53 +#, c-format +msgid "could not connect to server: %s" +msgstr "sunucuya baÄŸlanamadı: %s" + +#: libpq_fetch.c:57 +#, c-format +msgid "connected to server" +msgstr "sunucuya baÄŸlandı" + +#: libpq_fetch.c:61 +#, c-format +msgid "could not clear search_path: %s" +msgstr "search_path temizlenemedi: %s" + +#: libpq_fetch.c:73 +#, c-format +msgid "source server must not be in recovery mode" +msgstr "kaynak sunucu kurtarma (recovery) modunda olmamalı" + +#: libpq_fetch.c:83 +#, c-format +msgid "full_page_writes must be enabled in the source server" +msgstr "kaynak sunucuda full_page_writes etkinleÅŸtirilmiÅŸ olmalı" + +#: libpq_fetch.c:95 +#, c-format +msgid "could not set up connection context: %s" +msgstr "baÄŸlantı baÄŸlamı (context) kurulamadı: %s" + +#: libpq_fetch.c:113 +#, c-format +msgid "error running query (%s) in source server: %s" +msgstr "kaynak sunucuda (%s) sorgusu hata üretti: %s" + +#: libpq_fetch.c:118 +#, c-format +msgid "unexpected result set from query" +msgstr "sorgudan beklenmedik sonuç kümesi" + +#: libpq_fetch.c:141 +#, c-format +msgid "unrecognized result \"%s\" for current WAL insert location" +msgstr "geçerli WAL ekleme (insert) yeri için bilinmeyen sonuç \"%s\"" + +#: libpq_fetch.c:191 +#, c-format +msgid "could not fetch file list: %s" +msgstr "dosya listesi getirilemedi: %s" + +#: libpq_fetch.c:196 +#, c-format +msgid "unexpected result set while fetching file list" +msgstr "dosya listesi getirilirken beklenmedik sonuç kümesi" + +#: libpq_fetch.c:244 +#, c-format +msgid "could not send query: %s" +msgstr "sorgu gönderilemedi: %s" + +#: libpq_fetch.c:249 +#, c-format +msgid "could not set libpq connection to single row mode" +msgstr "libpq baÄŸlantısı tek satır moduna ayarlanamadı" + +#: libpq_fetch.c:270 +#, c-format +msgid "unexpected result while fetching remote files: %s" +msgstr "uzak dosyalar getirilirken beklenmedik sonuç: %s" + +#: libpq_fetch.c:276 +#, c-format +msgid "unexpected result set size while fetching remote files" +msgstr "uzak dosyalar getirilirken beklenmedik sonuç kümesi" + +#: libpq_fetch.c:282 +#, c-format +msgid "unexpected data types in result set while fetching remote files: %u %u %u" +msgstr "uzak dosyalar getirilirken sonuç kümesinde beklenmedik veri tipleri: %u %u %u" + +#: libpq_fetch.c:290 +#, c-format +msgid "unexpected result format while fetching remote files" +msgstr "uzak dosyalar getirilirken beklenmedik sonuç formatı" + +#: libpq_fetch.c:296 +#, c-format +msgid "unexpected null values in result while fetching remote files" +msgstr "uzak dosyalar getirilirken sonuçta beklenmeyen boÅŸ (null) deÄŸerler" + +#: libpq_fetch.c:300 +#, c-format +msgid "unexpected result length while fetching remote files" +msgstr "uzak dosyalar getirilirken beklenmedik sonuç uzunluÄŸu" + +#: libpq_fetch.c:366 +#, c-format +msgid "could not fetch remote file \"%s\": %s" +msgstr "\"%s\" uzak dosyası getirilemedi: %s" + +#: libpq_fetch.c:371 +#, c-format +msgid "unexpected result set while fetching remote file \"%s\"" +msgstr "\"%s\" uzak dosyası getirilirken beklenmedik sonuç kümesi" + +#: libpq_fetch.c:415 +#, c-format +msgid "could not send COPY data: %s" +msgstr "COPY veri gönderilemedi: %s" + +#: libpq_fetch.c:441 +#, c-format +msgid "could not create temporary table: %s" +msgstr "geçici dosya oluÅŸturulamadı: %s" + +#: libpq_fetch.c:449 +#, c-format +msgid "could not send file list: %s" +msgstr "dosya listesi gönderilemedi: %s" + +#: libpq_fetch.c:491 +#, c-format +msgid "could not send end-of-COPY: %s" +msgstr "kopya sonu (end-of-COPY) gönderilemedi: %s" + +#: libpq_fetch.c:497 +#, c-format +msgid "unexpected result while sending file list: %s" +msgstr "dosya listesi gönderilirken beklenmeye sonuç: %s" + +#: logging.c:72 +#, c-format +msgid "%*s/%s kB (%d%%) copied" +msgstr "%*s/%s kB (%d%%) kopyalandı" + +#: parsexlog.c:75 parsexlog.c:129 parsexlog.c:187 +#, c-format +msgid "out of memory" +msgstr "yetersiz bellek" + +#: parsexlog.c:88 parsexlog.c:135 +#, c-format +msgid "could not read WAL record at %X/%X: %s" +msgstr "%X/%X deki WAL kaydı okunamadı: %s" + +#: parsexlog.c:92 parsexlog.c:138 +#, c-format +msgid "could not read WAL record at %X/%X" +msgstr "%X/%X deki WAL kaydı okunamadı" + +#: parsexlog.c:199 +#, c-format +msgid "could not find previous WAL record at %X/%X: %s" +msgstr "önceki WAL kaydı %X/%X de bulunamadı: %s" + +#: parsexlog.c:203 +#, c-format +msgid "could not find previous WAL record at %X/%X" +msgstr "önceki WAL kaydı %X/%X de bulunamadı" + +#: parsexlog.c:294 +#, c-format +msgid "could not open file \"%s\": %m" +msgstr "\"%s\" dosyası açılamıyor: %m" + +#: parsexlog.c:307 +#, c-format +msgid "could not seek in file \"%s\": %m" +msgstr "\"%s\" dosyası ilerleme hatası: %m" + +#: parsexlog.c:387 +#, c-format +msgid "WAL record modifies a relation, but record type is not recognized: lsn: %X/%X, rmgr: %s, info: %02X" +msgstr "WAL kaydı bir nesneyi deÄŸiÅŸtiriyor, fakat kayıt türü tanınmıyor: lsn: %X/%X, rmgr: %s, info: %02X" + +#: pg_rewind.c:69 +#, c-format +msgid "" +"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n" +"\n" +msgstr "" +"%s bir PostgreSQL kümesini kümenin diÄŸer bir kopyasıyla yeniden senkronize eder.\n" +"\n" + +#: pg_rewind.c:70 +#, c-format +msgid "" +"Usage:\n" +" %s [OPTION]...\n" +"\n" +msgstr "" +"kullanım:\n" +" %s [OPTION]...\n" +"\n" + +#: pg_rewind.c:71 +#, c-format +msgid "Options:\n" +msgstr "Seçenekler:\n" + +#: pg_rewind.c:72 +#, c-format +msgid " -D, --target-pgdata=DIRECTORY existing data directory to modify\n" +msgstr " -D, --target-pgdata=DİZİN deÄŸiÅŸtirilecek mevcut veri dizini\n" + +#: pg_rewind.c:73 +#, c-format +msgid " --source-pgdata=DIRECTORY source data directory to synchronize with\n" +msgstr " --source-pgdata=DİZİN senkronize edilecek kaynak veri dizini\n" + +#: pg_rewind.c:74 +#, c-format +msgid " --source-server=CONNSTR source server to synchronize with\n" +msgstr " --source-server=CONNSTR senkronize edilecek kaynak sunucu\n" + +#: pg_rewind.c:75 +#, c-format +msgid " -n, --dry-run stop before modifying anything\n" +msgstr " -n, --dry-run herhangi bir ÅŸeyi deÄŸiÅŸtirmeden dur\n" + +#: pg_rewind.c:76 +#, fuzzy, c-format +#| msgid " -N, --no-sync do not wait for changes to be written safely to disk\n" +msgid " -N, --no-sync do not wait for changes to be written\n" +msgstr " -N, --no-sync deÄŸiÅŸikliklerin diske yazılmasını bekleme\n" + +#: pg_rewind.c:77 +#, fuzzy, c-format +#| msgid " --no-sync do not wait for changes to be written safely to disk\n" +msgid " safely to disk\n" +msgstr "" +" --no-sync deÄŸiÅŸikliklerin diske yazılması için bekleme\n" +"\n" + +#: pg_rewind.c:78 +#, c-format +msgid " -P, --progress write progress messages\n" +msgstr " -P, --progress ilerleme mesajları yaz\n" + +#: pg_rewind.c:79 +#, c-format +msgid " --debug write a lot of debug messages\n" +msgstr " --debug bir çok hata ayıklama mesajı yaz\n" + +#: pg_rewind.c:80 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: pg_rewind.c:81 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_rewind.c:82 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: pg_rewind.c:139 pg_rewind.c:175 pg_rewind.c:182 pg_rewind.c:189 +#: pg_rewind.c:197 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: pg_rewind.c:174 +#, c-format +msgid "no source specified (--source-pgdata or --source-server)" +msgstr "kaynak belirtilmemiÅŸ (--source-pgdata veya --source-server)" + +#: pg_rewind.c:181 +#, c-format +msgid "only one of --source-pgdata or --source-server can be specified" +msgstr "--source-pgdata veya --source-server'dan sadece biri belirtilebilir" + +#: pg_rewind.c:188 +#, c-format +msgid "no target data directory specified (--target-pgdata)" +msgstr "hedef veri dizini belirtilmemiÅŸ (--target-pgdata)" + +#: pg_rewind.c:195 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı girdisi var (ilki \"%s\")" + +#: pg_rewind.c:210 +#, c-format +msgid "cannot be executed by \"root\"" +msgstr "\"root\" tarafından çalıştırılamaz" + +#: pg_rewind.c:211 +#, c-format +msgid "You must run %s as the PostgreSQL superuser.\n" +msgstr "%s komutunu PostgreSQL superuser olarak çalıştırmalısınız.\n" + +#: pg_rewind.c:222 +#, c-format +msgid "could not read permissions of directory \"%s\": %m" +msgstr "\"%s\" dizininin eriÅŸim haklarını okunamıyor: %m" + +#: pg_rewind.c:253 +#, c-format +msgid "source and target cluster are on the same timeline" +msgstr "kaynak ve hedef kümesi aynı zaman çizelgesinde" + +#: pg_rewind.c:259 +#, c-format +msgid "servers diverged at WAL location %X/%X on timeline %u" +msgstr "sunucular %3$u zaman çizelgesinde %1$X/%2$X WAL konumunda birbirlerinden farklılaşıyor" + +#: pg_rewind.c:296 +#, c-format +msgid "no rewind required" +msgstr "geri sarma (rewind) gerekmiyor" + +#: pg_rewind.c:303 +#, c-format +msgid "rewinding from last common checkpoint at %X/%X on timeline %u" +msgstr "%3$u zaman çizelgesinde %1$X/%2$X deki son ortak kontrol noktasından geri sarıyor (rewind)" + +#: pg_rewind.c:312 +#, c-format +msgid "reading source file list" +msgstr "kaynak dosya listesi okunuyor" + +#: pg_rewind.c:315 +#, c-format +msgid "reading target file list" +msgstr "hedef dosya listesi okunuyor" + +#: pg_rewind.c:326 +#, c-format +msgid "reading WAL in target" +msgstr "hedefteki WAL okunuyor" + +#: pg_rewind.c:343 +#, c-format +msgid "need to copy %lu MB (total source directory size is %lu MB)" +msgstr "%lu MB kopyalanmalı (toplam kaynak dizin boyutu %lu MB)" + +#: pg_rewind.c:362 +#, c-format +msgid "creating backup label and updating control file" +msgstr "yedek etiketi oluÅŸturuluyor ve kontrol dosyası güncelleniyor" + +#: pg_rewind.c:391 +#, c-format +msgid "syncing target data directory" +msgstr "hedef veri dizini senkronize ediliyor" + +#: pg_rewind.c:394 +#, c-format +msgid "Done!" +msgstr "Tamamlandı!" + +#: pg_rewind.c:406 +#, c-format +msgid "source and target clusters are from different systems" +msgstr "kaynak ve hedef kümeleri farklı sistemlerden" + +#: pg_rewind.c:414 +#, c-format +msgid "clusters are not compatible with this version of pg_rewind" +msgstr "kümeler pg_rewind'in bu sürümüyle uyumlu deÄŸil" + +#: pg_rewind.c:424 +#, c-format +msgid "target server needs to use either data checksums or \"wal_log_hints = on\"" +msgstr "hedef sunucu ya veri saÄŸlama toplamları (checksum) ya da \"wal_log_hints = on\" kullanmalı" + +#: pg_rewind.c:435 +#, c-format +msgid "target server must be shut down cleanly" +msgstr "hedef sunucu düzgün bir ÅŸekilde kapatılmalı" + +#: pg_rewind.c:445 +#, c-format +msgid "source data directory must be shut down cleanly" +msgstr "kaynak veri dizini düzgün bir ÅŸekilde kapatılmalı" + +#: pg_rewind.c:500 +#, c-format +msgid "invalid control file\n" +msgstr "geçersiz kontrol dosyası\n" + +#: pg_rewind.c:584 +#, c-format +msgid "could not find common ancestor of the source and target cluster's timelines" +msgstr "kaynak ve hedef kümelerin zaman çizelgelerinin ortak atası bulunamadı" + +#: pg_rewind.c:625 +#, c-format +msgid "backup label buffer too small" +msgstr "yedek etiketi tamponu (buffer) çok küçük" + +#: pg_rewind.c:648 +#, c-format +msgid "unexpected control file CRC" +msgstr "beklenmedik kontrol dosyası CRC'si" + +#: pg_rewind.c:658 +#, c-format +msgid "unexpected control file size %d, expected %d" +msgstr "beklenmedik kontrol dosyası boyutu %d, beklenen %d" + +#: pg_rewind.c:667 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes" +msgstr[0] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir" +msgstr[1] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir" + +#: timeline.c:77 timeline.c:83 +#, c-format +msgid "syntax error in history file: %s" +msgstr "%s geçmiÅŸ dosyasında sözdizimi hatası" + +#: timeline.c:78 +#, c-format +msgid "Expected a numeric timeline ID." +msgstr "Sayısal timeline ID bekleniyordu." + +#: timeline.c:84 +#, c-format +msgid "Expected a write-ahead log switchpoint location." +msgstr "Bir write-ahead log geçiÅŸ noktası (switchpoint) lokasyonu bekleniyordu " + +#: timeline.c:89 +#, c-format +msgid "invalid data in history file: %s" +msgstr "geçmiÅŸ dosyasında geçersiz veri: %s" + +#: timeline.c:90 +#, c-format +msgid "Timeline IDs must be in increasing sequence." +msgstr "Timeline ID daima artan sırayla olmalıdır." + +#: timeline.c:110 +#, c-format +msgid "invalid data in history file" +msgstr "geçmiÅŸ dosyasında geçersiz veri" + +#: timeline.c:111 +#, c-format +msgid "Timeline IDs must be less than child timeline's ID." +msgstr "timeline ID, child timeline ID'sinden daha düşük olmalıdır." + +#: xlogreader.c:299 +#, c-format +msgid "invalid record offset at %X/%X" +msgstr "%X/%X adresinde geçersiz kayıt offseti" + +#: xlogreader.c:307 +#, c-format +msgid "contrecord is requested by %X/%X" +msgstr "contrecord %X/%X tarafından talep edilmiÅŸtir" + +#: xlogreader.c:348 xlogreader.c:645 +#, c-format +msgid "invalid record length at %X/%X: wanted %u, got %u" +msgstr "%X/%X adresinde geçersiz kayıt uzunluÄŸu: istenen %u, alınan %u" + +#: xlogreader.c:372 +#, c-format +msgid "record length %u at %X/%X too long" +msgstr "%2$X/%3$X adresinde çok büyük kayıt uzunluÄŸu: %1$u " + +#: xlogreader.c:404 +#, c-format +msgid "there is no contrecord flag at %X/%X" +msgstr "%X/%X de contrecord bayrağı (flag) bulunmuyor" + +#: xlogreader.c:417 +#, c-format +msgid "invalid contrecord length %u at %X/%X" +msgstr "%X/%X adresinde geçersiz %u contrecord uzunluÄŸu" + +#: xlogreader.c:653 +#, c-format +msgid "invalid resource manager ID %u at %X/%X" +msgstr "%2$X/%3$X adresinde geçersiz resource manager ID %1$u" + +#: xlogreader.c:667 xlogreader.c:684 +#, c-format +msgid "record with incorrect prev-link %X/%X at %X/%X" +msgstr "geçersiz incorrect prev-link olan kayıt: %X/%X at %X/%X" + +#: xlogreader.c:721 +#, c-format +msgid "incorrect resource manager data checksum in record at %X/%X" +msgstr "resoource manager data checksum %X/%X kaydında geçersiz" + +#: xlogreader.c:758 +#, c-format +msgid "invalid magic number %04X in log segment %s, offset %u" +msgstr "%04X geçersiz tanııtım kodu; %s kayıt segmentinde, offset %u" + +#: xlogreader.c:772 xlogreader.c:823 +#, c-format +msgid "invalid info bits %04X in log segment %s, offset %u" +msgstr "%04X geçersiz info bits; %s kayıt segmentinde, offset %u" + +#: xlogreader.c:798 +#, c-format +msgid "WAL file is from different database system: WAL file database system identifier is %s, pg_control database system identifier is %s" +msgstr "WAL dosyası farklı veritabanı sisteminden: WAL dosya veritabanı sistem tanımlayıcı %s, pg_control veritabanı sistem tanımlayıcı %s" + +#: xlogreader.c:805 +#, c-format +msgid "WAL file is from different database system: incorrect segment size in page header" +msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış segment boyutu deÄŸeri" + +#: xlogreader.c:811 +#, c-format +msgid "WAL file is from different database system: incorrect XLOG_BLCKSZ in page header" +msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış XLOG_BLCKSZ deÄŸeri" + +#: xlogreader.c:842 +#, c-format +msgid "unexpected pageaddr %X/%X in log segment %s, offset %u" +msgstr "beklenmeyen pageaddr %X/%X: log segmenti %s, offset %u" + +#: xlogreader.c:867 +#, c-format +msgid "out-of-sequence timeline ID %u (after %u) in log segment %s, offset %u" +msgstr "sıra dışı timeline ID %u (%u'dan sonra), bulunduÄŸu log segmenti %s, offset %u" + +#: xlogreader.c:1112 +#, c-format +msgid "out-of-order block_id %u at %X/%X" +msgstr "%X/%X deki %u block_id deÄŸeri bozuk" + +#: xlogreader.c:1135 +#, c-format +msgid "BKPBLOCK_HAS_DATA set, but no data included at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ayarlandı, fakat %X/%X de veri yok" + +#: xlogreader.c:1142 +#, c-format +msgid "BKPBLOCK_HAS_DATA not set, but data length is %u at %X/%X" +msgstr "BKPBLOCK_HAS_DATA ayarlanmadı, fakat veri uzunluÄŸu %u (%X/%x de)" + +#: xlogreader.c:1178 +#, c-format +msgid "BKPIMAGE_HAS_HOLE set, but hole offset %u length %u block image length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ayarlandı, fakat hole offset %u uzunluk %u blok image uzunluÄŸu %u (%X/%X de)" + +#: xlogreader.c:1194 +#, c-format +msgid "BKPIMAGE_HAS_HOLE not set, but hole offset %u length %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ayarlanmadı, fakat hole offset %u uzunluk %u (%X/%X de)" + +#: xlogreader.c:1209 +#, c-format +msgid "BKPIMAGE_IS_COMPRESSED set, but block image length %u at %X/%X" +msgstr "BKPIMAGE_IS_COMPRESSED ayarlandı, fakat block image uzunluÄŸu %u (%X/%X de)" + +#: xlogreader.c:1224 +#, c-format +msgid "neither BKPIMAGE_HAS_HOLE nor BKPIMAGE_IS_COMPRESSED set, but block image length is %u at %X/%X" +msgstr "BKPIMAGE_HAS_HOLE ve BKPIMAGE_IS_COMPRESSED ayarlanmadı, fakat block image uzunluÄŸu %u (%X/%X de)" + +#: xlogreader.c:1240 +#, c-format +msgid "BKPBLOCK_SAME_REL set but no previous rel at %X/%X" +msgstr "BKPBLOCK_SAME_REL ayarlandı fakat %X/%X de önceki rel yok" + +#: xlogreader.c:1252 +#, c-format +msgid "invalid block_id %u at %X/%X" +msgstr "%X/%X adresinde %u block_id geçersiz" + +#: xlogreader.c:1341 +#, c-format +msgid "record with invalid length at %X/%X" +msgstr "%X/%X adresinde geçersiz uzunlukta kayıt" + +#: xlogreader.c:1430 +#, c-format +msgid "invalid compressed image at %X/%X, block %d" +msgstr "%X/%X adresinde (blok %d), geçersiz compressed image" + +#~ msgid "WAL file is from different database system: incorrect XLOG_SEG_SIZE in page header" +#~ msgstr "WAL dosyası farklı veritabanı sisteminden: page header'da yanlış XLOG_SEG_SIZE deÄŸeri" + +#~ msgid "Timeline IDs must be less than child timeline's ID.\n" +#~ msgstr "Zamançizelgesi ID'leri alt zaman çizelgesinin ID'lerinden küçük olmalı.\n" + +#~ msgid "Timeline IDs must be in increasing sequence.\n" +#~ msgstr "Zaman çizelgesi ID'leri artan sırada olmalı.\n" + +#~ msgid "invalid data in history file: %s\n" +#~ msgstr "geçmiÅŸ dosyasında geçersiz veri: %s\n" + +#~ msgid "Expected a write-ahead log switchpoint location.\n" +#~ msgstr "İşlem kaydı (WAL) geçiÅŸ noktası konumu bekleniyor.\n" + +#~ msgid "Expected a numeric timeline ID.\n" +#~ msgstr "Sayısal bir zaman çizelgesi ID'si bekleniyor.\n" + +#~ msgid "syntax error in history file: %s\n" +#~ msgstr "geçmiÅŸ dosyasında sözdizimi hatası: %s\n" + +#~ msgid "sync of target directory failed\n" +#~ msgstr "hedef dizinin senkronizasyonu baÅŸarısız oldu\n" + +#~ msgid "" +#~ "The program \"initdb\" was found by \"%s\"\n" +#~ "but was not the same version as %s.\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "\"initdb\" programı \"%s\" tarafından bulundu\n" +#~ "fakat %s ile aynı sürümde deÄŸil.\n" +#~ "Kurulumunuzu kontrol ediniz\n" + +#~ msgid "" +#~ "The program \"initdb\" is needed by %s but was\n" +#~ "not found in the same directory as \"%s\".\n" +#~ "Check your installation.\n" +#~ msgstr "" +#~ "\"initdb\" programına %s tarafından ihtiyaç duyuluyor fakat\n" +#~ "\"%s\" ile aynı dizinde bulunmuyor.\n" +#~ "Kurulumunuzu kontrol ediniz.\n" + +#~ msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte\n" +#~ msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes\n" +#~ msgstr[0] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir\n" +#~ msgstr[1] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat kontrol dosyası %d bayt belirtmektedir\n" + +#~ msgid "%d: %X/%X - %X/%X\n" +#~ msgstr "%d: %X/%X - %X/%X\n" + +#~ msgid "Target timeline history:\n" +#~ msgstr "Hedef zaman çizelgesi geçmiÅŸi:\n" + +#~ msgid "Source timeline history:\n" +#~ msgstr "Kaynak zaman çizelgesi geçmiÅŸi:\n" + +#~ msgid "%s: could not read permissions of directory \"%s\": %s\n" +#~ msgstr "%s: \"%s\" dizininin eriÅŸim hakları okunamadı : %s\n" + +#~ msgid "could not read from file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyasından okuma hatası: %s\n" + +#~ msgid "could not seek in file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyasında arama yapılamadı: %s\n" + +#~ msgid "could not open file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyası açılamadı: %s\n" + +#~ msgid "Failure, exiting\n" +#~ msgstr "BaÅŸarısız, çıkılıyor\n" + +#~ msgid "fetched file \"%s\", length %d\n" +#~ msgstr "\"%s\" dosyası getirildi, uzunluk %d\n" + +#~ msgid "received chunk for file \"%s\", offset %s, size %d\n" +#~ msgstr "\"%s\" dosyası için parça (chunk) alındı, ofset %s, boyut %d\n" + +#~ msgid "received null value for chunk for file \"%s\", file has been deleted\n" +#~ msgstr "\"%s\" dosyası parçası (chunk) için boÅŸ (null) deÄŸer alındı, dosya silindi\n" + +#~ msgid "getting file chunks\n" +#~ msgstr "dosya parçaları alınıyor\n" + +#~ msgid "%s (%s)\n" +#~ msgstr "%s (%s)\n" + +#~ msgid "entry \"%s\" excluded from target file list\n" +#~ msgstr "\"%s\" kaydı hedef dosya listesinden hariç tutuldu\n" + +#~ msgid "entry \"%s\" excluded from source file list\n" +#~ msgstr "\"%s\" kaydı kaynak dosya listesinden hariç tutuldu\n" + +#~ msgid "could not open file \"%s\" for reading: %s\n" +#~ msgstr "\"%s\" dosyası okuma için açılamadı: %s\n" + +#~ msgid "could not remove symbolic link \"%s\": %s\n" +#~ msgstr "\"%s\" sembolik linki kaldırılamadı: %s\n" + +#~ msgid "could not remove directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini silinemedi: %s\n" + +#~ msgid "could not create directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini oluÅŸturulamadı: %s\n" + +#~ msgid "could not truncate file \"%s\" to %u: %s\n" +#~ msgstr "\"%s\" dosyası %u'ya küçültülemedi (truncate): %s\n" + +#~ msgid "could not remove file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyası silinemedi: %s\n" + +#~ msgid "could not write file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyasına yazılamadı: %s\n" + +#~ msgid " block %u\n" +#~ msgstr " blok %u\n" + +#~ msgid "could not close file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyası kapatılamadı: %s\n" + +#~ msgid "could not read file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyası okunamadı: %s\n" + +#~ msgid "could not read directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini okunamıyor: %s\n" + +#~ msgid "symbolic link \"%s\" target is too long\n" +#~ msgstr "\"%s\" sembolik link hedefi çok uzun\n" + +#~ msgid "could not read symbolic link \"%s\": %s\n" +#~ msgstr "\"%s\" sembolik linki okunamadı: %s\n" + +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "\"%s\" dosyasının durumu görüntülenemedi (stat): %s\n" + +#~ msgid "could not open directory \"%s\": %s\n" +#~ msgstr "\"%s\" dizini açılamıyor: %s\n" + +#~ msgid "%s: could not open process token: error code %lu\n" +#~ msgstr "%s: process token açma baÅŸarısız: hata kodu %lu\n" diff --git a/src/bin/pg_rewind/t/001_basic.pl b/src/bin/pg_rewind/t/001_basic.pl index 1b0f823b0cc..c3293e93df7 100644 --- a/src/bin/pg_rewind/t/001_basic.pl +++ b/src/bin/pg_rewind/t/001_basic.pl @@ -1,7 +1,10 @@ use strict; use warnings; use TestLib; -use Test::More tests => 10; +use Test::More tests => 11; + +use FindBin; +use lib $FindBin::RealBin; use RewindTest; @@ -35,7 +38,7 @@ sub run_test master_psql( "INSERT INTO trunc_tbl values ('in master, before promotion')"); master_psql( -"INSERT INTO tail_tbl SELECT g, 'in master, before promotion: ' || g FROM generate_series(1, 10000) g" + "INSERT INTO tail_tbl SELECT g, 'in master, before promotion: ' || g FROM generate_series(1, 10000) g" ); master_psql('CHECKPOINT'); @@ -54,7 +57,7 @@ sub run_test # Insert enough rows to trunc_tbl to extend the file. pg_rewind should # truncate it back to the old size. master_psql( -"INSERT INTO trunc_tbl SELECT 'in master, after promotion: ' || g FROM generate_series(1, 10000) g" + "INSERT INTO trunc_tbl SELECT 'in master, after promotion: ' || g FROM generate_series(1, 10000) g" ); # Truncate tail_tbl. pg_rewind should copy back the truncated part @@ -87,15 +90,17 @@ sub run_test 'tail-copy'); # Permissions on PGDATA should be default - SKIP: + SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive($node_master->data_dir(), 0700, 0600), 'check PGDATA permissions'); } RewindTest::clean_rewind_test(); + return; } # Run the test in both modes diff --git a/src/bin/pg_rewind/t/002_databases.pl b/src/bin/pg_rewind/t/002_databases.pl index c364965d3ae..1db534c0dc0 100644 --- a/src/bin/pg_rewind/t/002_databases.pl +++ b/src/bin/pg_rewind/t/002_databases.pl @@ -1,7 +1,10 @@ use strict; use warnings; use TestLib; -use Test::More tests => 6; +use Test::More tests => 7; + +use FindBin; +use lib $FindBin::RealBin; use RewindTest; @@ -12,19 +15,27 @@ sub run_test RewindTest::setup_cluster($test_mode, ['-g']); RewindTest::start_master(); - # Create a database in master. + # Create a database in master with a table. master_psql('CREATE DATABASE inmaster'); + master_psql('CREATE TABLE inmaster_tab (a int)', 'inmaster'); RewindTest::create_standby($test_mode); - # Create another database, the creation is replicated to the standby + # Create another database with another table, the creation is + # replicated to the standby. master_psql('CREATE DATABASE beforepromotion'); + master_psql('CREATE TABLE beforepromotion_tab (a int)', + 'beforepromotion'); RewindTest::promote_standby(); # Create databases in the old master and the new promoted standby. master_psql('CREATE DATABASE master_afterpromotion'); + master_psql('CREATE TABLE master_promotion_tab (a int)', + 'master_afterpromotion'); standby_psql('CREATE DATABASE standby_afterpromotion'); + standby_psql('CREATE TABLE standby_promotion_tab (a int)', + 'standby_afterpromotion'); # The clusters are now diverged. @@ -43,15 +54,17 @@ sub run_test 'database names'); # Permissions on PGDATA should have group permissions - SKIP: + SKIP: { - skip "unix-style permissions not supported on Windows", 1 if ($windows_os); + skip "unix-style permissions not supported on Windows", 1 + if ($windows_os); ok(check_mode_recursive($node_master->data_dir(), 0750, 0640), 'check PGDATA permissions'); } RewindTest::clean_rewind_test(); + return; } # Run the test in both modes. diff --git a/src/bin/pg_rewind/t/003_extrafiles.pl b/src/bin/pg_rewind/t/003_extrafiles.pl index 2433a4aab6f..f4710440fc3 100644 --- a/src/bin/pg_rewind/t/003_extrafiles.pl +++ b/src/bin/pg_rewind/t/003_extrafiles.pl @@ -3,10 +3,13 @@ use strict; use warnings; use TestLib; -use Test::More tests => 4; +use Test::More tests => 5; use File::Find; +use FindBin; +use lib $FindBin::RealBin; + use RewindTest; @@ -66,7 +69,8 @@ sub run_test @paths = sort @paths; is_deeply( \@paths, - [ "$test_master_datadir/tst_both_dir", + [ + "$test_master_datadir/tst_both_dir", "$test_master_datadir/tst_both_dir/both_file1", "$test_master_datadir/tst_both_dir/both_file2", "$test_master_datadir/tst_both_dir/both_subdir", @@ -75,10 +79,12 @@ sub run_test "$test_master_datadir/tst_standby_dir/standby_file1", "$test_master_datadir/tst_standby_dir/standby_file2", "$test_master_datadir/tst_standby_dir/standby_subdir", -"$test_master_datadir/tst_standby_dir/standby_subdir/standby_file3" ], + "$test_master_datadir/tst_standby_dir/standby_subdir/standby_file3" + ], "file lists match"); RewindTest::clean_rewind_test(); + return; } # Run the test in both modes. diff --git a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl index feadaa6a0ff..639eeb9c910 100644 --- a/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl +++ b/src/bin/pg_rewind/t/004_pg_xlog_symlink.pl @@ -14,9 +14,12 @@ } else { - plan tests => 4; + plan tests => 5; } +use FindBin; +use lib $FindBin::RealBin; + use RewindTest; sub run_test @@ -72,6 +75,7 @@ sub run_test 'table content'); RewindTest::clean_rewind_test(); + return; } # Run the test in both modes diff --git a/src/bin/pg_rewind/t/005_same_timeline.pl b/src/bin/pg_rewind/t/005_same_timeline.pl index 0e334ee191a..40dbc44caa3 100644 --- a/src/bin/pg_rewind/t/005_same_timeline.pl +++ b/src/bin/pg_rewind/t/005_same_timeline.pl @@ -3,6 +3,9 @@ use TestLib; use Test::More tests => 1; +use FindBin; +use lib $FindBin::RealBin; + use RewindTest; # Test that running pg_rewind if the two clusters are on the same diff --git a/src/bin/pg_rewind/RewindTest.pm b/src/bin/pg_rewind/t/RewindTest.pm similarity index 68% rename from src/bin/pg_rewind/RewindTest.pm rename to src/bin/pg_rewind/t/RewindTest.pm index 63d9bd517df..c540722420e 100644 --- a/src/bin/pg_rewind/RewindTest.pm +++ b/src/bin/pg_rewind/t/RewindTest.pm @@ -26,11 +26,7 @@ package RewindTest; # still running. # # The test script can use the helper functions master_psql and standby_psql -# to run psql against the master and standby servers, respectively. The -# test script can also use the $connstr_master and $connstr_standby global -# variables, which contain libpq connection strings for connecting to the -# master and standby servers. The data directories are also available -# in paths $test_master_datadir and $test_standby_datadir +# to run psql against the master and standby servers, respectively. use strict; use warnings; @@ -68,23 +64,29 @@ our $node_standby; sub master_psql { my $cmd = shift; + my $dbname = shift || 'postgres'; system_or_bail 'psql', '-q', '--no-psqlrc', '-d', - $node_master->connstr('postgres'), '-c', "$cmd"; + $node_master->connstr($dbname), '-c', "$cmd"; + return; } sub standby_psql { my $cmd = shift; + my $dbname = shift || 'postgres'; system_or_bail 'psql', '-q', '--no-psqlrc', '-d', - $node_standby->connstr('postgres'), '-c', "$cmd"; + $node_standby->connstr($dbname), '-c', "$cmd"; + return; } # Run a query against the master, and check that the output matches what's # expected sub check_query { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($query, $expected_stdout, $test_name) = @_; my ($stdout, $stderr); @@ -92,7 +94,8 @@ sub check_query my $result = run [ 'psql', '-q', '-A', '-t', '--no-psqlrc', '-d', $node_master->connstr('postgres'), - '-c', $query ], + '-c', $query + ], '>', \$stdout, '2>', \$stderr; # We don't use ok() for the exit code and stderr, because we want this @@ -111,53 +114,83 @@ sub check_query $stdout =~ s/\r//g if $Config{osname} eq 'msys'; is($stdout, $expected_stdout, "$test_name: query result matches"); } + return; } sub setup_cluster { - my $extra_name = shift; # Used to differentiate clusters - my $extra = shift; # Extra params for initdb + my $extra_name = shift; # Used to differentiate clusters + my $extra = shift; # Extra params for initdb # Initialize master, data checksums are mandatory - $node_master = get_new_node('master' . ($extra_name ? "_${extra_name}" : '')); + $node_master = + get_new_node('master' . ($extra_name ? "_${extra_name}" : '')); + + # Set up pg_hba.conf and pg_ident.conf for the role running + # pg_rewind. This role is used for all the tests, and has + # minimal permissions enough to rewind from an online source. $node_master->init( - allows_streaming => 1, extra => $extra); + allows_streaming => 1, + extra => $extra, + auth_extra => [ '--create-role', 'rewind_user' ]); + # Set wal_keep_segments to prevent WAL segment recycling after enforced # checkpoints in the tests. - $node_master->append_conf('postgresql.conf', qq( + $node_master->append_conf( + 'postgresql.conf', qq( wal_keep_segments = 20 )); + return; } sub start_master { $node_master->start; + # Create custom role which is used to run pg_rewind, and adjust its + # permissions to the minimum necessary. + $node_master->safe_psql( + 'postgres', " + CREATE ROLE rewind_user LOGIN; + GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) + TO rewind_user; + GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) + TO rewind_user; + GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) + TO rewind_user; + GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) + TO rewind_user;"); + #### Now run the test-specific parts to initialize the master before setting # up standby + + return; } sub create_standby { my $extra_name = shift; - $node_standby = get_new_node('standby' . ($extra_name ? "_${extra_name}" : '')); + $node_standby = + get_new_node('standby' . ($extra_name ? "_${extra_name}" : '')); $node_master->backup('my_backup'); $node_standby->init_from_backup($node_master, 'my_backup'); my $connstr_master = $node_master->connstr(); $node_standby->append_conf( - "recovery.conf", qq( -primary_conninfo='$connstr_master application_name=rewind_standby' -standby_mode=on -recovery_target_timeline='latest' + "postgresql.conf", qq( +primary_conninfo='$connstr_master' )); + $node_standby->set_standby_mode(); + # Start standby $node_standby->start; # The standby may have WAL to apply before it matches the primary. That # is fine, because no test examines the standby before promotion. + + return; } sub promote_standby @@ -166,7 +199,7 @@ sub promote_standby # up standby # Wait for the standby to receive and write all WAL. - $node_master->wait_for_catchup('rewind_standby', 'write'); + $node_master->wait_for_catchup($node_standby, 'write'); # Now promote standby and insert some new data on master, this will put # the master out-of-sync with the standby. @@ -179,6 +212,8 @@ sub promote_standby # after promotion so quickly that when pg_rewind runs, the standby has not # performed a checkpoint after promotion yet. standby_psql("checkpoint"); + + return; } sub run_pg_rewind @@ -189,6 +224,9 @@ sub run_pg_rewind my $standby_connstr = $node_standby->connstr('postgres'); my $tmp_folder = TestLib::tempdir; + # Append the rewind-specific role to the connection string. + $standby_connstr = "$standby_connstr user=rewind_user"; + # Stop the master and be ready to perform the rewind $node_master->stop; @@ -211,10 +249,13 @@ sub run_pg_rewind # Stop the master and be ready to perform the rewind $node_standby->stop; command_ok( - [ 'pg_rewind', + [ + 'pg_rewind', "--debug", "--source-pgdata=$standby_pgdata", - "--target-pgdata=$master_pgdata" ], + "--target-pgdata=$master_pgdata", + "--no-sync" + ], 'pg_rewind local'); } elsif ($test_mode eq "remote") @@ -222,10 +263,22 @@ sub run_pg_rewind # Do rewind using a remote connection as source command_ok( - [ 'pg_rewind', "--debug", - "--source-server", $standby_connstr, - "--target-pgdata=$master_pgdata" ], + [ + 'pg_rewind', "--debug", + "--source-server", $standby_connstr, + "--target-pgdata=$master_pgdata", "-R", + "--no-sync" + ], 'pg_rewind remote'); + + # Check that standby.signal has been created. + ok(-e "$master_pgdata/standby.signal"); + + # Now, when pg_rewind apparently succeeded with minimal permissions, + # add REPLICATION privilege. So we could test that new standby + # is able to connect to the new master with generated config. + $node_standby->safe_psql('postgres', + "ALTER ROLE rewind_user WITH REPLICATION;"); } else { @@ -239,24 +292,29 @@ sub run_pg_rewind "$tmp_folder/master-postgresql.conf.tmp", "$master_pgdata/postgresql.conf"); - chmod($node_master->group_access() ? 0640 : 0600, - "$master_pgdata/postgresql.conf") - or BAIL_OUT( - "unable to set permissions for $master_pgdata/postgresql.conf"); + chmod( + $node_master->group_access() ? 0640 : 0600, + "$master_pgdata/postgresql.conf") + or BAIL_OUT( + "unable to set permissions for $master_pgdata/postgresql.conf"); # Plug-in rewound node to the now-promoted standby node - my $port_standby = $node_standby->port; - $node_master->append_conf( - 'recovery.conf', qq( -primary_conninfo='port=$port_standby' -standby_mode=on -recovery_target_timeline='latest' -)); + if ($test_mode ne "remote") + { + my $port_standby = $node_standby->port; + $node_master->append_conf( + 'postgresql.conf', qq( +primary_conninfo='port=$port_standby')); + + $node_master->set_standby_mode(); + } # Restart the master to check that rewind went correctly $node_master->start; #### Now run the test-specific parts to check the result + + return; } # Clean up after the test. Stop both servers, if they're still running. @@ -264,6 +322,7 @@ sub clean_rewind_test { $node_master->teardown_node if defined $node_master; $node_standby->teardown_node if defined $node_standby; + return; } 1; diff --git a/src/bin/pg_rewind/timeline.c b/src/bin/pg_rewind/timeline.c index 8a8c587440c..987452c4f41 100644 --- a/src/bin/pg_rewind/timeline.c +++ b/src/bin/pg_rewind/timeline.c @@ -3,7 +3,7 @@ * timeline.c * timeline-related functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -73,20 +73,20 @@ rewind_parseTimeLineHistory(char *buffer, TimeLineID targetTLI, int *nentries) if (nfields < 1) { /* expect a numeric timeline ID as first field of line */ - fprintf(stderr, _("syntax error in history file: %s\n"), fline); - fprintf(stderr, _("Expected a numeric timeline ID.\n")); + pg_log_error("syntax error in history file: %s", fline); + pg_log_error("Expected a numeric timeline ID."); exit(1); } if (nfields != 3) { - fprintf(stderr, _("syntax error in history file: %s\n"), fline); - fprintf(stderr, _("Expected a write-ahead log switchpoint location.\n")); + pg_log_error("syntax error in history file: %s", fline); + pg_log_error("Expected a write-ahead log switchpoint location."); exit(1); } if (entries && tli <= lasttli) { - fprintf(stderr, _("invalid data in history file: %s\n"), fline); - fprintf(stderr, _("Timeline IDs must be in increasing sequence.\n")); + pg_log_error("invalid data in history file: %s", fline); + pg_log_error("Timeline IDs must be in increasing sequence."); exit(1); } @@ -106,8 +106,8 @@ rewind_parseTimeLineHistory(char *buffer, TimeLineID targetTLI, int *nentries) if (entries && targetTLI <= lasttli) { - fprintf(stderr, _("invalid data in history file\n")); - fprintf(stderr, _("Timeline IDs must be less than child timeline's ID.\n")); + pg_log_error("invalid data in history file"); + pg_log_error("Timeline IDs must be less than child timeline's ID."); exit(1); } diff --git a/src/bin/pg_test_fsync/nls.mk b/src/bin/pg_test_fsync/nls.mk index adf8f767f17..1a21369b5a5 100644 --- a/src/bin/pg_test_fsync/nls.mk +++ b/src/bin/pg_test_fsync/nls.mk @@ -1,5 +1,5 @@ # src/bin/pg_test_fsync/nls.mk CATALOG_NAME = pg_test_fsync -AVAIL_LANGUAGES =es fr pl ru sv +AVAIL_LANGUAGES =cs de es fr ja ko pl ru sv tr vi GETTEXT_FILES = pg_test_fsync.c GETTEXT_TRIGGERS = die diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c index e6f7ef85579..225557e6c57 100644 --- a/src/bin/pg_test_fsync/pg_test_fsync.c +++ b/src/bin/pg_test_fsync/pg_test_fsync.c @@ -14,6 +14,7 @@ #include "getopt_long.h" #include "access/xlogdefs.h" +#include "common/logging.h" /* @@ -46,7 +47,7 @@ do { \ if (CreateThread(NULL, 0, process_alarm, NULL, 0, NULL) == \ INVALID_HANDLE_VALUE) \ { \ - fprintf(stderr, _("Could not create thread for alarm\n")); \ + pg_log_error("could not create thread for alarm"); \ exit(1); \ } \ gettimeofday(&start_t, NULL); \ @@ -92,12 +93,14 @@ static void signal_cleanup(int sig); static int pg_fsync_writethrough(int fd); #endif static void print_elapse(struct timeval start_t, struct timeval stop_t, int ops); -static void die(const char *str); + +#define die(msg) do { pg_log_error("%s: %m", _(msg)); exit(1); } while(0) int main(int argc, char *argv[]) { + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_test_fsync")); progname = get_progname(argv[0]); @@ -167,7 +170,7 @@ handle_args(int argc, char *argv[]) switch (option) { case 'f': - filename = strdup(optarg); + filename = pg_strdup(optarg); break; case 's': @@ -184,9 +187,8 @@ handle_args(int argc, char *argv[]) if (argc > optind) { - fprintf(stderr, - _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -601,10 +603,3 @@ process_alarm(LPVOID param) ExitThread(0); } #endif - -static void -die(const char *str) -{ - fprintf(stderr, _("%s: %s\n"), _(str), strerror(errno)); - exit(1); -} diff --git a/src/bin/pg_test_fsync/po/cs.po b/src/bin/pg_test_fsync/po/cs.po new file mode 100644 index 00000000000..a654745c89e --- /dev/null +++ b/src/bin/pg_test_fsync/po/cs.po @@ -0,0 +1,210 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_fsync (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-07-13 19:47+0000\n" +"PO-Revision-Date: 2018-07-13 23:50+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : " +"2;\n" +"X-Generator: Poedit 2.0.7\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "Nelze vytvoÅ™it thread pro alarm\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Použití: %s [-f SOUBOR] [-s SECS-PER-TEST]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "" +"%s: příliÅ¡ mnoho argumentů v příkazové řádce (první je \"%s\")\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d sekund per test\n" +msgstr[1] "%d seconds per test\n" +msgstr[2] "%d seconds per test\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "" +"O_DIRECT supported on this platform for open_datasync and " +"open_sync.\n" +msgstr "" +"O_DIRECT podporováno na této platformÄ› pro open_datasync a " +"open_sync.\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Direct I/O není na této platformÄ› podporováno.\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:292 pg_test_fsync.c:316 +#: pg_test_fsync.c:339 pg_test_fsync.c:480 pg_test_fsync.c:492 +#: pg_test_fsync.c:508 pg_test_fsync.c:514 pg_test_fsync.c:539 +msgid "could not open output file" +msgstr "nelze otevřít výstupní soubor" + +#: pg_test_fsync.c:231 pg_test_fsync.c:273 pg_test_fsync.c:298 +#: pg_test_fsync.c:322 pg_test_fsync.c:345 pg_test_fsync.c:383 +#: pg_test_fsync.c:441 pg_test_fsync.c:482 pg_test_fsync.c:510 +#: pg_test_fsync.c:541 +msgid "write failed" +msgstr "zápis selhal" + +#: pg_test_fsync.c:235 pg_test_fsync.c:324 pg_test_fsync.c:347 +#: pg_test_fsync.c:484 pg_test_fsync.c:516 +msgid "fsync failed" +msgstr "fsync selhal" + +#: pg_test_fsync.c:249 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Srovnání sync metod souboru pomocí jednoho %dkB zápisu:\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Srovnání sync metod souboru pomocí dvou %dkB zápisů:\n" + +#: pg_test_fsync.c:252 +#, c-format +msgid "" +"(in wal_sync_method preference order, except fdatasync is Linux's " +"default)\n" +msgstr "" +"(v poÅ™adí dle wal_sync_method, s výjimkou že fdatasync je výchozí na " +"Linuxu)\n" + +#: pg_test_fsync.c:263 pg_test_fsync.c:366 pg_test_fsync.c:432 +msgid "n/a*" +msgstr "n/a*" + +#: pg_test_fsync.c:275 pg_test_fsync.c:301 pg_test_fsync.c:326 +#: pg_test_fsync.c:349 pg_test_fsync.c:385 pg_test_fsync.c:443 +msgid "seek failed" +msgstr "nastavení pozice (seek) selhalo" + +#: pg_test_fsync.c:281 pg_test_fsync.c:306 pg_test_fsync.c:354 +#: pg_test_fsync.c:391 pg_test_fsync.c:449 +msgid "n/a" +msgstr "n/a" + +#: pg_test_fsync.c:396 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Tento souborový systém a jeho mount volby nepodporují direct\n" +" I/O, e.g. ext4 v journaled módu.\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Srovnání open_sync s různými velikostmi zápisů:\n" + +#: pg_test_fsync.c:405 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different " +"write\n" +"open_sync sizes.)\n" +msgstr "" +"(Toto je navrženo pro srovnání ceny zápisu 16kB s různými " +"velikostmi\n" +"zápisů open_sync.)\n" + +#: pg_test_fsync.c:408 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync write" + +#: pg_test_fsync.c:409 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync writes" + +#: pg_test_fsync.c:410 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync writes" + +#: pg_test_fsync.c:411 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync writes" + +#: pg_test_fsync.c:412 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync writes" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Testuje zda fsync funguje na non-write file descriptoru:\n" + +#: pg_test_fsync.c:466 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a " +"different\n" +"descriptor.)\n" +msgstr "" +"(Pokud jsou výsledky podobné, fsync() může synchronizovat data\n" +"zapsaná na různých descriptorech.)\n" + +#: pg_test_fsync.c:531 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Non-sync'ed %dkB writes:\n" + +#: pg_test_fsync.c:608 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/de.po b/src/bin/pg_test_fsync/po/de.po new file mode 100644 index 00000000000..92b4146bdc8 --- /dev/null +++ b/src/bin/pg_test_fsync/po/de.po @@ -0,0 +1,195 @@ +# German message translation file for pg_test_fsync +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Peter Eisentraut , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-08-26 15:46+0000\n" +"PO-Revision-Date: 2017-08-26 12:30-0400\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr " %13.3f Op./s %6.0f µs/Op.\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "Konnte Thread für Alarm nicht erzeugen\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Aufruf: %s [-f DATEINAME] [-s SEK-PRO-TEST]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d Sekunde pro Test\n" +msgstr[1] "%d Sekunden pro Test\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT wird auf dieser Plattform für open_datasync und open_sync unterstützt.\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "Direct-I/O wird auf dieser Plattform nicht unterstützt.\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:291 pg_test_fsync.c:315 +#: pg_test_fsync.c:338 pg_test_fsync.c:479 pg_test_fsync.c:491 +#: pg_test_fsync.c:507 pg_test_fsync.c:513 pg_test_fsync.c:538 +msgid "could not open output file" +msgstr "konnte Ausgabedatei nicht öffnen" + +#: pg_test_fsync.c:230 pg_test_fsync.c:272 pg_test_fsync.c:297 +#: pg_test_fsync.c:321 pg_test_fsync.c:344 pg_test_fsync.c:382 +#: pg_test_fsync.c:440 pg_test_fsync.c:481 pg_test_fsync.c:509 +#: pg_test_fsync.c:540 +msgid "write failed" +msgstr "Schreiben fehlgeschlagen" + +#: pg_test_fsync.c:234 pg_test_fsync.c:323 pg_test_fsync.c:346 +#: pg_test_fsync.c:483 pg_test_fsync.c:515 +msgid "fsync failed" +msgstr "fsync fehlgeschlagen" + +#: pg_test_fsync.c:248 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Vergleich von Datei-Sync-Methoden bei einem Schreibvorgang aus %dkB:\n" + +#: pg_test_fsync.c:250 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Vergleich von Datei-Sync-Methoden bei zwei Schreibvorgängen aus je %dkB:\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(in Rangordnung von wal_sync_method, außer dass fdatasync auf Linux Standard ist)\n" + +#: pg_test_fsync.c:262 pg_test_fsync.c:365 pg_test_fsync.c:431 +msgid "n/a*" +msgstr "entf.*" + +#: pg_test_fsync.c:274 pg_test_fsync.c:300 pg_test_fsync.c:325 +#: pg_test_fsync.c:348 pg_test_fsync.c:384 pg_test_fsync.c:442 +msgid "seek failed" +msgstr "seek fehlgeschlagen" + +#: pg_test_fsync.c:280 pg_test_fsync.c:305 pg_test_fsync.c:353 +#: pg_test_fsync.c:390 pg_test_fsync.c:448 +msgid "n/a" +msgstr "entf." + +#: pg_test_fsync.c:395 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Dieses Dateisystem und die Mount-Optionen unterstützen kein Direct-I/O,\n" +" z.B. ext4 im Journaled-Modus.\n" + +#: pg_test_fsync.c:403 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"Vergleich von open_sync mit verschiedenen Schreibgrößen:\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Damit werden die Kosten für das Schreiben von 16kB in verschieden Größen mit\n" +"open_sync verglichen.)\n" + +#: pg_test_fsync.c:407 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync schreiben" + +#: pg_test_fsync.c:408 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync schreiben" + +#: pg_test_fsync.c:409 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync schreiben" + +#: pg_test_fsync.c:410 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync schreiben" + +#: pg_test_fsync.c:411 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync schreiben" + +#: pg_test_fsync.c:464 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Probe ob fsync auf einem anderen Dateideskriptor funktioniert:\n" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Wenn die Zeiten ähnlich sind, dann kann fsync() auf einem anderen Deskriptor\n" +"geschriebene Daten syncen.)\n" + +#: pg_test_fsync.c:530 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Nicht gesynctes Schreiben von %dkB:\n" + +#: pg_test_fsync.c:607 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/es.po b/src/bin/pg_test_fsync/po/es.po index e247332c6f8..0c94560c76e 100644 --- a/src/bin/pg_test_fsync/po/es.po +++ b/src/bin/pg_test_fsync/po/es.po @@ -1,78 +1,77 @@ # Spanish message translation file for pg_test_fsync # -# Copyright (C) 2017 PostgreSQL Global Development Group +# Copyright (c) 2017-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # -# Carlos Chapi , 2017. +# Carlos Chapi , 2017. # msgid "" msgstr "" "Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:17+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" -"Language-Team: PgSQL-es-Ayuda \n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:16+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Carlos Chapi \n" -"X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: BlackCAT 1.0\n" -#: pg_test_fsync.c:48 +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:31 #, c-format -msgid "Cannot create thread for alarm\n" -msgstr "No se puede crear hilo para alarma\n" +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/seg %6.0f usegs/op\n" -#: pg_test_fsync.c:153 +#: pg_test_fsync.c:157 #, c-format msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" msgstr "Empleo: %s [-f ARCHIVO] [-s SEG-POR-PRUEBA]\n" -#: pg_test_fsync.c:177 pg_test_fsync.c:189 +#: pg_test_fsync.c:181 pg_test_fsync.c:192 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Pruebe «%s --help» para mayor información.\n" -#: pg_test_fsync.c:187 +#: pg_test_fsync.c:197 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d segundo por prueba\n" +msgstr[1] "%d segundos por prueba\n" -#: pg_test_fsync.c:194 -#, c-format -msgid "%d seconds per test\n" -msgstr "%d segundos por prueba\n" - -#: pg_test_fsync.c:196 +#: pg_test_fsync.c:202 #, c-format msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" msgstr "O_DIRECT tiene soporte en esta plataforma para open_datasync y open_sync.\n" -#: pg_test_fsync.c:198 +#: pg_test_fsync.c:204 #, c-format msgid "Direct I/O is not supported on this platform.\n" msgstr "Direct I/O no está soportado en esta plataforma.\n" -#: pg_test_fsync.c:223 pg_test_fsync.c:287 pg_test_fsync.c:311 -#: pg_test_fsync.c:334 pg_test_fsync.c:475 pg_test_fsync.c:487 -#: pg_test_fsync.c:503 pg_test_fsync.c:509 pg_test_fsync.c:534 +#: pg_test_fsync.c:229 pg_test_fsync.c:294 pg_test_fsync.c:318 +#: pg_test_fsync.c:341 pg_test_fsync.c:482 pg_test_fsync.c:494 +#: pg_test_fsync.c:510 pg_test_fsync.c:516 pg_test_fsync.c:541 msgid "could not open output file" msgstr "no se pudo abrir el archivo de salida" -#: pg_test_fsync.c:226 pg_test_fsync.c:268 pg_test_fsync.c:293 -#: pg_test_fsync.c:317 pg_test_fsync.c:340 pg_test_fsync.c:378 -#: pg_test_fsync.c:436 pg_test_fsync.c:477 pg_test_fsync.c:505 -#: pg_test_fsync.c:536 +#: pg_test_fsync.c:233 pg_test_fsync.c:275 pg_test_fsync.c:300 +#: pg_test_fsync.c:324 pg_test_fsync.c:347 pg_test_fsync.c:385 +#: pg_test_fsync.c:443 pg_test_fsync.c:484 pg_test_fsync.c:512 +#: pg_test_fsync.c:543 msgid "write failed" msgstr "escritura falló" -#: pg_test_fsync.c:230 pg_test_fsync.c:319 pg_test_fsync.c:342 -#: pg_test_fsync.c:479 pg_test_fsync.c:511 +#: pg_test_fsync.c:237 pg_test_fsync.c:326 pg_test_fsync.c:349 +#: pg_test_fsync.c:486 pg_test_fsync.c:518 msgid "fsync failed" msgstr "fsync falló" -#: pg_test_fsync.c:244 +#: pg_test_fsync.c:251 #, c-format msgid "" "\n" @@ -81,7 +80,7 @@ msgstr "" "\n" "Comparar métodos de sincronización de archivos usando una escritura de %dkB:\n" -#: pg_test_fsync.c:246 +#: pg_test_fsync.c:253 #, c-format msgid "" "\n" @@ -90,26 +89,26 @@ msgstr "" "\n" "Comparar métodos de sincronización de archivos usando dos escrituras de %dkB:\n" -#: pg_test_fsync.c:247 +#: pg_test_fsync.c:254 #, c-format msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" msgstr "(en orden de preferencia de wal_sync_method, excepto en Linux donde fdatasync es el predeterminado)\n" -#: pg_test_fsync.c:258 pg_test_fsync.c:361 pg_test_fsync.c:427 -msgid "n/a*\n" -msgstr "n/a*\n" +#: pg_test_fsync.c:265 pg_test_fsync.c:368 pg_test_fsync.c:434 +msgid "n/a*" +msgstr "n/a*" -#: pg_test_fsync.c:270 pg_test_fsync.c:296 pg_test_fsync.c:321 -#: pg_test_fsync.c:344 pg_test_fsync.c:380 pg_test_fsync.c:438 +#: pg_test_fsync.c:277 pg_test_fsync.c:303 pg_test_fsync.c:328 +#: pg_test_fsync.c:351 pg_test_fsync.c:387 pg_test_fsync.c:445 msgid "seek failed" msgstr "búsqueda falló" -#: pg_test_fsync.c:276 pg_test_fsync.c:301 pg_test_fsync.c:349 -#: pg_test_fsync.c:386 pg_test_fsync.c:444 -msgid "n/a\n" -msgstr "n/a\n" +#: pg_test_fsync.c:283 pg_test_fsync.c:308 pg_test_fsync.c:356 +#: pg_test_fsync.c:393 pg_test_fsync.c:451 +msgid "n/a" +msgstr "n/a" -#: pg_test_fsync.c:391 +#: pg_test_fsync.c:398 #, c-format msgid "" "* This file system and its mount options do not support direct\n" @@ -118,7 +117,7 @@ msgstr "" "* Este sistema de archivos con sus opciones de montaje no soportan\n" " Direct I/O, e.g. ext4 en modo journal.\n" -#: pg_test_fsync.c:399 +#: pg_test_fsync.c:406 #, c-format msgid "" "\n" @@ -127,7 +126,7 @@ msgstr "" "\n" "Comparar open_sync con diferentes tamaños de escritura:\n" -#: pg_test_fsync.c:400 +#: pg_test_fsync.c:407 #, c-format msgid "" "(This is designed to compare the cost of writing 16kB in different write\n" @@ -136,27 +135,27 @@ msgstr "" "(Esto está diseñado para comparar el costo de escribir 16kB en diferentes\n" "tamaños de escrituras open_sync.)\n" -#: pg_test_fsync.c:403 +#: pg_test_fsync.c:410 msgid " 1 * 16kB open_sync write" msgstr " 1 * 16kB escritura open_sync" -#: pg_test_fsync.c:404 +#: pg_test_fsync.c:411 msgid " 2 * 8kB open_sync writes" msgstr " 2 * 8kB escrituras open_sync" -#: pg_test_fsync.c:405 +#: pg_test_fsync.c:412 msgid " 4 * 4kB open_sync writes" msgstr " 4 * 4kB escrituras open_sync" -#: pg_test_fsync.c:406 +#: pg_test_fsync.c:413 msgid " 8 * 2kB open_sync writes" msgstr " 8 * 2kB escrituras open_sync" -#: pg_test_fsync.c:407 +#: pg_test_fsync.c:414 msgid "16 * 1kB open_sync writes" msgstr "16 * 1kB escrituras open_sync" -#: pg_test_fsync.c:460 +#: pg_test_fsync.c:467 #, c-format msgid "" "\n" @@ -165,7 +164,7 @@ msgstr "" "\n" "Probar si se respeta fsync en un descriptor de archivo que no es de escritura:\n" -#: pg_test_fsync.c:461 +#: pg_test_fsync.c:468 #, c-format msgid "" "(If the times are similar, fsync() can sync data written on a different\n" @@ -174,7 +173,7 @@ msgstr "" "(Si los tiempos son similares, fsync() puede sincronizar datos escritos\n" "en un descriptor diferente.)\n" -#: pg_test_fsync.c:526 +#: pg_test_fsync.c:533 #, c-format msgid "" "\n" @@ -182,8 +181,3 @@ msgid "" msgstr "" "\n" "Escrituras de %dkB no sincronizadas:\n" - -#: pg_test_fsync.c:603 -#, c-format -msgid "%s: %s\n" -msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/fr.po b/src/bin/pg_test_fsync/po/fr.po index 9628d21a508..1a1201d2f8b 100644 --- a/src/bin/pg_test_fsync/po/fr.po +++ b/src/bin/pg_test_fsync/po/fr.po @@ -7,70 +7,79 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-02 04:46+0000\n" -"PO-Revision-Date: 2017-07-05 18:52+0200\n" +"POT-Creation-Date: 2017-08-26 21:16+0000\n" +"PO-Revision-Date: 2017-08-27 09:02+0200\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: \n" -"Language-Team: \n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.0.3\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" -#: pg_test_fsync.c:48 +#: pg_test_fsync.c:49 #, c-format -msgid "Cannot create thread for alarm\n" -msgstr "Ne peut pas créer un thread pour l'alarme\n" +msgid "Could not create thread for alarm\n" +msgstr "N'a pas pu créer un thread pour l'alarme\n" -#: pg_test_fsync.c:153 +#: pg_test_fsync.c:154 #, c-format msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" msgstr "Usage: %s [-f NOMFICHIER] [-s SECS-PAR-TEST]\n" -#: pg_test_fsync.c:177 pg_test_fsync.c:189 +#: pg_test_fsync.c:178 pg_test_fsync.c:190 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: pg_test_fsync.c:187 +#: pg_test_fsync.c:188 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" -#: pg_test_fsync.c:194 +#: pg_test_fsync.c:195 #, c-format -msgid "%d seconds per test\n" -msgstr "%d secondes par test\n" +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d seconde par test\n" +msgstr[1] "%d secondes par test\n" -#: pg_test_fsync.c:196 +#: pg_test_fsync.c:200 #, c-format msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" msgstr "O_DIRECT supporté sur cette plateforme pour open_datasync et open_sync.\n" -#: pg_test_fsync.c:198 +#: pg_test_fsync.c:202 #, c-format msgid "Direct I/O is not supported on this platform.\n" msgstr "Direct I/O n'est pas supporté sur cette plateforme.\n" -#: pg_test_fsync.c:223 pg_test_fsync.c:287 pg_test_fsync.c:311 -#: pg_test_fsync.c:334 pg_test_fsync.c:475 pg_test_fsync.c:487 -#: pg_test_fsync.c:503 pg_test_fsync.c:509 pg_test_fsync.c:534 +#: pg_test_fsync.c:227 pg_test_fsync.c:291 pg_test_fsync.c:315 +#: pg_test_fsync.c:338 pg_test_fsync.c:479 pg_test_fsync.c:491 +#: pg_test_fsync.c:507 pg_test_fsync.c:513 pg_test_fsync.c:538 msgid "could not open output file" msgstr "n'a pas pu ouvrir le fichier en sortie" -#: pg_test_fsync.c:226 pg_test_fsync.c:268 pg_test_fsync.c:293 -#: pg_test_fsync.c:317 pg_test_fsync.c:340 pg_test_fsync.c:378 -#: pg_test_fsync.c:436 pg_test_fsync.c:477 pg_test_fsync.c:505 -#: pg_test_fsync.c:536 +#: pg_test_fsync.c:230 pg_test_fsync.c:272 pg_test_fsync.c:297 +#: pg_test_fsync.c:321 pg_test_fsync.c:344 pg_test_fsync.c:382 +#: pg_test_fsync.c:440 pg_test_fsync.c:481 pg_test_fsync.c:509 +#: pg_test_fsync.c:540 msgid "write failed" msgstr "échec en écriture" -#: pg_test_fsync.c:230 pg_test_fsync.c:319 pg_test_fsync.c:342 -#: pg_test_fsync.c:479 pg_test_fsync.c:511 +#: pg_test_fsync.c:234 pg_test_fsync.c:323 pg_test_fsync.c:346 +#: pg_test_fsync.c:483 pg_test_fsync.c:515 msgid "fsync failed" msgstr "échec de la synchronisation (fsync)" -#: pg_test_fsync.c:244 +#: pg_test_fsync.c:248 #, c-format msgid "" "\n" @@ -79,7 +88,7 @@ msgstr "" "\n" "Comparer les méthodes de synchronisation de fichier en utilisant une écriture de %d Ko :\n" -#: pg_test_fsync.c:246 +#: pg_test_fsync.c:250 #, c-format msgid "" "\n" @@ -88,26 +97,26 @@ msgstr "" "\n" "Comparer les méthodes de synchronisation de fichier sur disque en utilisant deux écritures de %d Ko :\n" -#: pg_test_fsync.c:247 +#: pg_test_fsync.c:251 #, c-format msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" msgstr "(dans l'ordre de préférence de wal_sync_method, sauf fdatasync qui est la valeur par défaut sous Linux)\n" -#: pg_test_fsync.c:258 pg_test_fsync.c:361 pg_test_fsync.c:427 -msgid "n/a*\n" -msgstr "n/a*\n" +#: pg_test_fsync.c:262 pg_test_fsync.c:365 pg_test_fsync.c:431 +msgid "n/a*" +msgstr "n/a*" -#: pg_test_fsync.c:270 pg_test_fsync.c:296 pg_test_fsync.c:321 -#: pg_test_fsync.c:344 pg_test_fsync.c:380 pg_test_fsync.c:438 +#: pg_test_fsync.c:274 pg_test_fsync.c:300 pg_test_fsync.c:325 +#: pg_test_fsync.c:348 pg_test_fsync.c:384 pg_test_fsync.c:442 msgid "seek failed" msgstr "seek échoué" -#: pg_test_fsync.c:276 pg_test_fsync.c:301 pg_test_fsync.c:349 -#: pg_test_fsync.c:386 pg_test_fsync.c:444 -msgid "n/a\n" -msgstr "n/a\n" +#: pg_test_fsync.c:280 pg_test_fsync.c:305 pg_test_fsync.c:353 +#: pg_test_fsync.c:390 pg_test_fsync.c:448 +msgid "n/a" +msgstr "n/a" -#: pg_test_fsync.c:391 +#: pg_test_fsync.c:395 #, c-format msgid "" "* This file system and its mount options do not support direct\n" @@ -116,7 +125,7 @@ msgstr "" "* Ce système de fichiers et ses options de montage ne supportent pas les\n" " I/O directes, par exemple ext4 en journalisé.\n" -#: pg_test_fsync.c:399 +#: pg_test_fsync.c:403 #, c-format msgid "" "\n" @@ -125,7 +134,7 @@ msgstr "" "\n" "Comparer open_sync avec différentes tailles d'écriture :\n" -#: pg_test_fsync.c:400 +#: pg_test_fsync.c:404 #, c-format msgid "" "(This is designed to compare the cost of writing 16kB in different write\n" @@ -134,27 +143,27 @@ msgstr "" "(Ceci est conçu pour comparer le coût d'écriture de 16 Ko dans différentes tailles\n" "d'écritures open_sync.)\n" -#: pg_test_fsync.c:403 +#: pg_test_fsync.c:407 msgid " 1 * 16kB open_sync write" msgstr " 1 * 16 Ko, écriture avec open_sync" -#: pg_test_fsync.c:404 +#: pg_test_fsync.c:408 msgid " 2 * 8kB open_sync writes" msgstr " 2 * 8 Ko, écriture avec open_sync" -#: pg_test_fsync.c:405 +#: pg_test_fsync.c:409 msgid " 4 * 4kB open_sync writes" msgstr " 4 * 4 Ko, écriture avec open_sync" -#: pg_test_fsync.c:406 +#: pg_test_fsync.c:410 msgid " 8 * 2kB open_sync writes" msgstr " 8 * 2 Ko, écriture avec open_sync" -#: pg_test_fsync.c:407 +#: pg_test_fsync.c:411 msgid "16 * 1kB open_sync writes" msgstr " 16 * 1 Ko, écriture avec open_sync" -#: pg_test_fsync.c:460 +#: pg_test_fsync.c:464 #, c-format msgid "" "\n" @@ -163,7 +172,7 @@ msgstr "" "\n" "Teste si fsync est honoré sur un descripteur de fichiers sans écriture :\n" -#: pg_test_fsync.c:461 +#: pg_test_fsync.c:465 #, c-format msgid "" "(If the times are similar, fsync() can sync data written on a different\n" @@ -172,7 +181,7 @@ msgstr "" "(Si les temps sont similaires, fsync() peut synchroniser sur disque les données écrites sur\n" "un descripteur différent.)\n" -#: pg_test_fsync.c:526 +#: pg_test_fsync.c:530 #, c-format msgid "" "\n" @@ -181,7 +190,7 @@ msgstr "" "\n" "%d Ko d'écritures non synchronisées :\n" -#: pg_test_fsync.c:603 +#: pg_test_fsync.c:607 #, c-format msgid "%s: %s\n" msgstr "%s : %s\n" diff --git a/src/bin/pg_test_fsync/po/ja.po b/src/bin/pg_test_fsync/po/ja.po new file mode 100644 index 00000000000..4547a2cbf12 --- /dev/null +++ b/src/bin/pg_test_fsync/po/ja.po @@ -0,0 +1,195 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_fsync (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-01-30 16:17+0900\n" +"PO-Revision-Date: 2018-01-30 17:07+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Last-Translator: Michihide Hotta \n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.6\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f æ“作/ç§’ %6.0f マイクロ秒/æ“作\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "アラーム用ã®ã‚¹ãƒ¬ãƒƒãƒ‰ã‚’生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "使用法: %s [-f ファイルå] [-s テストã‚ãŸã‚Šã®ç§’æ•°]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\" ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™ï¼ˆå…ˆé ­ã¯ \"%s\")\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "テスト1件ã‚ãŸã‚Š %d ç§’\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ open_datasync 㨠open_sync ã«ã¤ã„㦠O_DIRECT ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆ I/O ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:291 pg_test_fsync.c:315 +#: pg_test_fsync.c:338 pg_test_fsync.c:479 pg_test_fsync.c:491 +#: pg_test_fsync.c:507 pg_test_fsync.c:513 pg_test_fsync.c:538 +msgid "could not open output file" +msgstr "出力ファイルをオープンã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: pg_test_fsync.c:230 pg_test_fsync.c:272 pg_test_fsync.c:297 +#: pg_test_fsync.c:321 pg_test_fsync.c:344 pg_test_fsync.c:382 +#: pg_test_fsync.c:440 pg_test_fsync.c:481 pg_test_fsync.c:509 +#: pg_test_fsync.c:540 +msgid "write failed" +msgstr "書ãè¾¼ã¿ã«å¤±æ•—" + +#: pg_test_fsync.c:234 pg_test_fsync.c:323 pg_test_fsync.c:346 +#: pg_test_fsync.c:483 pg_test_fsync.c:515 +msgid "fsync failed" +msgstr "fsync ã«å¤±æ•—" + +#: pg_test_fsync.c:248 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"1個㮠%dkB write を使ã£ã¦ãƒ•ã‚¡ã‚¤ãƒ«åŒæœŸãƒ¡ã‚½ãƒƒãƒ‰ã‚’比較ã—ã¾ã™:\n" + +#: pg_test_fsync.c:250 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"2個㮠%dkB write を使ã£ã¦ãƒ•ã‚¡ã‚¤ãƒ«åŒæœŸãƒ¡ã‚½ãƒƒãƒ‰ã‚’比較ã—ã¾ã™:\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(wal_sync_method ã®æŒ‡å®šé †ã®ä¸­ã§ã€Linux ã®ãƒ‡ãƒ•ォルトã§ã‚ã‚‹ fdatasync ã¯é™¤ãã¾ã™ï¼‰\n" + +#: pg_test_fsync.c:262 pg_test_fsync.c:365 pg_test_fsync.c:431 +msgid "n/a*" +msgstr "利用ä¸å¯*" + +#: pg_test_fsync.c:274 pg_test_fsync.c:300 pg_test_fsync.c:325 +#: pg_test_fsync.c:348 pg_test_fsync.c:384 pg_test_fsync.c:442 +msgid "seek failed" +msgstr "seek 失敗" + +#: pg_test_fsync.c:280 pg_test_fsync.c:305 pg_test_fsync.c:353 +#: pg_test_fsync.c:390 pg_test_fsync.c:448 +msgid "n/a" +msgstr "利用ä¸å¯" + +#: pg_test_fsync.c:395 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* ã“ã®ãƒ•ァイルシステムã¨ãã®ãƒžã‚¦ãƒ³ãƒˆã‚ªãƒ—ションã§ã¯ãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆ I/O をサãƒãƒ¼ãƒˆ\n" +" ã—ã¦ã„ã¾ã›ã‚“。例)ジャーナルモード㮠ext4。\n" + +#: pg_test_fsync.c:403 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"open_sync ã‚’ç•°ãªã£ãŸ write ã‚µã‚¤ã‚ºã§æ¯”較ã—ã¾ã™:\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(ã“れ㯠open_sync ã® write サイズを変ãˆãªãŒã‚‰ã€16kB write ã®ã‚³ã‚¹ãƒˆã‚’\n" +"比較ã™ã‚‹ã‚ˆã†æŒ‡å®šã•れã¦ã„ã¾ã™ã€‚)\n" + +#: pg_test_fsync.c:407 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync write" + +#: pg_test_fsync.c:408 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync writes" + +#: pg_test_fsync.c:409 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync writes" + +#: pg_test_fsync.c:410 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync writes" + +#: pg_test_fsync.c:411 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync writes" + +#: pg_test_fsync.c:464 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"書ãè¾¼ã¿ãªã—ã®ãƒ•ァイルディスクリプタ上㮠fsync ã®æ–¹ãŒå„ªã‚Œã¦ã„ã‚‹ã‹ã‚’テストã—ã¾ã™:\n" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(もã—実行時間ãŒåŒç­‰ã§ã‚れã°ã€fsync() ã¯ç•°ãªã£ãŸãƒ•ァイルディスクリプタ上ã§\n" +"データを sync ã§ãã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚)\n" + +#: pg_test_fsync.c:530 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"%dkB ã® sync ãªã— write:\n" + +#: pg_test_fsync.c:607 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/ko.po b/src/bin/pg_test_fsync/po/ko.po new file mode 100644 index 00000000000..bc8f32c2b3d --- /dev/null +++ b/src/bin/pg_test_fsync/po/ko.po @@ -0,0 +1,197 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:25+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "알람용 쓰레드를 만들 수 ì—†ìŒ\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "사용법: %s [-f 파ì¼ì´ë¦„] [-s 검사초]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\" ëª…ë ¹ì„ ì´ìš©í•˜ì„¸ìš”.\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìžë¥¼ ì§€ì •í–ˆìŒ (ì‹œìž‘ì€ \"%s\")\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "검사 간격: %d ì´ˆ\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "" +"ì´ í”Œëž«í¼ì—서는 open_datasync, open_sync ì—서 O_DIRECT ì˜µì…˜ì„ ì§€ì›í•¨.\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "ì´ í”Œëž«í¼ì€ direct I/O ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ.\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:291 pg_test_fsync.c:315 +#: pg_test_fsync.c:338 pg_test_fsync.c:479 pg_test_fsync.c:491 +#: pg_test_fsync.c:507 pg_test_fsync.c:513 pg_test_fsync.c:538 +msgid "could not open output file" +msgstr "출력 파ì¼ì„ ì—´ 수 ì—†ìŒ" + +#: pg_test_fsync.c:230 pg_test_fsync.c:272 pg_test_fsync.c:297 +#: pg_test_fsync.c:321 pg_test_fsync.c:344 pg_test_fsync.c:382 +#: pg_test_fsync.c:440 pg_test_fsync.c:481 pg_test_fsync.c:509 +#: pg_test_fsync.c:540 +msgid "write failed" +msgstr "쓰기 실패" + +#: pg_test_fsync.c:234 pg_test_fsync.c:323 pg_test_fsync.c:346 +#: pg_test_fsync.c:483 pg_test_fsync.c:515 +msgid "fsync failed" +msgstr "fsync 실패" + +#: pg_test_fsync.c:248 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"í•˜ë‚˜ì˜ %dkB ì“°ê¸°ì— ëŒ€í•œ íŒŒì¼ ì‹±í¬ ë°©ë²• 비êµ:\n" + +#: pg_test_fsync.c:250 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"ë‘ê°œì˜ %dkB ì“°ê¸°ì— ëŒ€í•œ íŒŒì¼ ì‹±í¬ ë°©ë²• 비êµ:\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "" +"(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "" +"(fdatasyncê°€ 리눅스 기본값ì´ê¸°ì— 제외하고, wal_sync_method 우선으로 처리 " +"함)\n" + +#: pg_test_fsync.c:262 pg_test_fsync.c:365 pg_test_fsync.c:431 +msgid "n/a*" +msgstr "n/a*" + +#: pg_test_fsync.c:274 pg_test_fsync.c:300 pg_test_fsync.c:325 +#: pg_test_fsync.c:348 pg_test_fsync.c:384 pg_test_fsync.c:442 +msgid "seek failed" +msgstr "찾기 실패" + +#: pg_test_fsync.c:280 pg_test_fsync.c:305 pg_test_fsync.c:353 +#: pg_test_fsync.c:390 pg_test_fsync.c:448 +msgid "n/a" +msgstr "n/a" + +#: pg_test_fsync.c:395 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* ì´ íŒŒì¼ ì‹œìŠ¤í…œê³¼ 마운트 ì˜µì…˜ì´ direct I/O ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않ìŒ\n" +" 예: journaled modeì—서 ext4\n" + +#: pg_test_fsync.c:403 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"서로 다른 쓰기량으로 open_sync 비êµ:\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(서로 다른 í¬ê¸°ë¡œ 16kB를 쓰는ë°, open_sync ì˜µì…˜ì„ ì‚¬ìš©í•  ë•Œì˜ ë¹„ìš© 비êµ)\n" + +#: pg_test_fsync.c:407 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync 쓰기" + +#: pg_test_fsync.c:408 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync 쓰기" + +#: pg_test_fsync.c:409 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync 쓰기" + +#: pg_test_fsync.c:410 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync 쓰기" + +#: pg_test_fsync.c:411 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync 쓰기" + +#: pg_test_fsync.c:464 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"쓰기 ë°©ì§€ 파ì¼ì—서 fsync ìž‘ë™ ì—¬ë¶€ 검사:\n" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(ì´ ê°’ì´ ë¹„ìŠ·í•˜ë‹¤ë©´, fsync() 호출로 여러 íŒŒì¼ ìƒíƒœì— 대해서 sync를 사용\n" +"í•  수 있ìŒ.)\n" + +#: pg_test_fsync.c:530 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Non-sync %dkB 쓰기:\n" + +#: pg_test_fsync.c:607 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/ru.po b/src/bin/pg_test_fsync/po/ru.po index 658915148c7..8ab9f2dfa75 100644 --- a/src/bin/pg_test_fsync/po/ru.po +++ b/src/bin/pg_test_fsync/po/ru.po @@ -1,78 +1,86 @@ # Russian message translation file for pg_test_fsync # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander LAW , 2017. -# +# Alexander Lakhin , 2017. msgid "" msgstr "" "Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-04 04:16+0000\n" -"PO-Revision-Date: 2017-04-10 11:38+0300\n" +"POT-Creation-Date: 2018-10-05 21:51+0300\n" +"PO-Revision-Date: 2017-09-21 14:03+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Alexander Lakhin \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: pg_test_fsync.c:47 +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 #, c-format -msgid "Cannot create thread for alarm\n" +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f оп/Ñ %6.0f мкÑ/оп\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" msgstr "Ðе удалоÑÑŒ Ñоздать поток Ð´Ð»Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸ Ñигналов\n" -#: pg_test_fsync.c:152 +#: pg_test_fsync.c:154 #, c-format msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" msgstr "ИÑпользование: %s [-f ИМЯ_ФÐЙЛР] [-s ТЕСТ_СЕК]\n" -#: pg_test_fsync.c:176 pg_test_fsync.c:188 +#: pg_test_fsync.c:178 pg_test_fsync.c:190 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: pg_test_fsync.c:186 +#: pg_test_fsync.c:188 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" -#: pg_test_fsync.c:193 +#: pg_test_fsync.c:195 #, c-format -msgid "%d seconds per test\n" -msgstr "на теÑÑ‚ отводитÑÑ %d Ñек.\n" +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "на теÑÑ‚ отводитÑÑ %d Ñек.\n" +msgstr[1] "на теÑÑ‚ отводитÑÑ %d Ñек.\n" +msgstr[2] "на теÑÑ‚ отводитÑÑ %d Ñек.\n" -#: pg_test_fsync.c:195 +#: pg_test_fsync.c:200 #, c-format msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" msgstr "" "O_DIRECT на Ñтой платформе не поддерживаетÑÑ Ð´Ð»Ñ open_datasync и open_sync.\n" -#: pg_test_fsync.c:197 +#: pg_test_fsync.c:202 #, c-format msgid "Direct I/O is not supported on this platform.\n" msgstr "ПрÑмой ввод/вывод не поддерживаетÑÑ Ð½Ð° Ñтой платформе.\n" -#: pg_test_fsync.c:222 pg_test_fsync.c:286 pg_test_fsync.c:310 -#: pg_test_fsync.c:333 pg_test_fsync.c:474 pg_test_fsync.c:486 -#: pg_test_fsync.c:502 pg_test_fsync.c:508 pg_test_fsync.c:533 +#: pg_test_fsync.c:227 pg_test_fsync.c:292 pg_test_fsync.c:316 +#: pg_test_fsync.c:339 pg_test_fsync.c:480 pg_test_fsync.c:492 +#: pg_test_fsync.c:508 pg_test_fsync.c:514 pg_test_fsync.c:539 msgid "could not open output file" msgstr "не удалоÑÑŒ открыть выходной файл" -#: pg_test_fsync.c:225 pg_test_fsync.c:267 pg_test_fsync.c:292 -#: pg_test_fsync.c:316 pg_test_fsync.c:339 pg_test_fsync.c:377 -#: pg_test_fsync.c:435 pg_test_fsync.c:476 pg_test_fsync.c:504 -#: pg_test_fsync.c:535 +#: pg_test_fsync.c:231 pg_test_fsync.c:273 pg_test_fsync.c:298 +#: pg_test_fsync.c:322 pg_test_fsync.c:345 pg_test_fsync.c:383 +#: pg_test_fsync.c:441 pg_test_fsync.c:482 pg_test_fsync.c:510 +#: pg_test_fsync.c:541 msgid "write failed" msgstr "ошибка запиÑи" -#: pg_test_fsync.c:229 pg_test_fsync.c:318 pg_test_fsync.c:341 -#: pg_test_fsync.c:478 pg_test_fsync.c:510 +#: pg_test_fsync.c:235 pg_test_fsync.c:324 pg_test_fsync.c:347 +#: pg_test_fsync.c:484 pg_test_fsync.c:516 msgid "fsync failed" msgstr "ошибка Ñинхронизации Ñ Ð¤Ð¡" -#: pg_test_fsync.c:243 +#: pg_test_fsync.c:249 #, c-format msgid "" "\n" @@ -81,7 +89,7 @@ msgstr "" "\n" "Сравнение методов Ñинхронизации файлов при однократной запиÑи %d КБ:\n" -#: pg_test_fsync.c:245 +#: pg_test_fsync.c:251 #, c-format msgid "" "\n" @@ -90,7 +98,7 @@ msgstr "" "\n" "Сравнение методов Ñинхронизации файлов при двухкратной запиÑи %d КБ:\n" -#: pg_test_fsync.c:246 +#: pg_test_fsync.c:252 #, c-format msgid "" "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" @@ -98,21 +106,21 @@ msgstr "" "(в порÑдке Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð´Ð»Ñ wal_sync_method, без учёта наибольшего " "Ð¿Ñ€ÐµÐ´Ð¿Ð¾Ñ‡Ñ‚ÐµÐ½Ð¸Ñ fdatasync в Linux)\n" -#: pg_test_fsync.c:257 pg_test_fsync.c:360 pg_test_fsync.c:426 -msgid "n/a*\n" -msgstr "н/д*\n" +#: pg_test_fsync.c:263 pg_test_fsync.c:366 pg_test_fsync.c:432 +msgid "n/a*" +msgstr "н/д*" -#: pg_test_fsync.c:269 pg_test_fsync.c:295 pg_test_fsync.c:320 -#: pg_test_fsync.c:343 pg_test_fsync.c:379 pg_test_fsync.c:437 +#: pg_test_fsync.c:275 pg_test_fsync.c:301 pg_test_fsync.c:326 +#: pg_test_fsync.c:349 pg_test_fsync.c:385 pg_test_fsync.c:443 msgid "seek failed" msgstr "ошибка позиционированиÑ" -#: pg_test_fsync.c:275 pg_test_fsync.c:300 pg_test_fsync.c:348 -#: pg_test_fsync.c:385 pg_test_fsync.c:443 -msgid "n/a\n" -msgstr "н/д\n" +#: pg_test_fsync.c:281 pg_test_fsync.c:306 pg_test_fsync.c:354 +#: pg_test_fsync.c:391 pg_test_fsync.c:449 +msgid "n/a" +msgstr "н/д" -#: pg_test_fsync.c:390 +#: pg_test_fsync.c:396 #, c-format msgid "" "* This file system and its mount options do not support direct\n" @@ -121,7 +129,7 @@ msgstr "" "* Эта Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема Ñ Ñ‚ÐµÐºÑƒÑ‰Ð¸Ð¼Ð¸ параметрами Ð¼Ð¾Ð½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ðµ поддерживает\n" " прÑмой ввод/вывод, как например, ext4 в режиме журналированиÑ.\n" -#: pg_test_fsync.c:398 +#: pg_test_fsync.c:404 #, c-format msgid "" "\n" @@ -130,7 +138,7 @@ msgstr "" "\n" "Сравнение open_sync при различных объёмах запиÑываемых данных:\n" -#: pg_test_fsync.c:399 +#: pg_test_fsync.c:405 #, c-format msgid "" "(This is designed to compare the cost of writing 16kB in different write\n" @@ -141,27 +149,27 @@ msgstr "" "запиÑи Ñ open_sync.)\n" # skip-rule: double-space -#: pg_test_fsync.c:402 +#: pg_test_fsync.c:408 msgid " 1 * 16kB open_sync write" msgstr "запиÑÑŒ Ñ open_sync 1 * 16 КБ" -#: pg_test_fsync.c:403 +#: pg_test_fsync.c:409 msgid " 2 * 8kB open_sync writes" msgstr "запиÑÑŒ Ñ open_sync 2 * 8 КБ" -#: pg_test_fsync.c:404 +#: pg_test_fsync.c:410 msgid " 4 * 4kB open_sync writes" msgstr "запиÑÑŒ Ñ open_sync 4 * 4 КБ" -#: pg_test_fsync.c:405 +#: pg_test_fsync.c:411 msgid " 8 * 2kB open_sync writes" msgstr "запиÑÑŒ Ñ open_sync 8 * 2 КБ" -#: pg_test_fsync.c:406 +#: pg_test_fsync.c:412 msgid "16 * 1kB open_sync writes" msgstr "запиÑÑŒ Ñ open_sync 16 * 1 КБ" -#: pg_test_fsync.c:459 +#: pg_test_fsync.c:465 #, c-format msgid "" "\n" @@ -171,7 +179,7 @@ msgstr "" "Проверка, производитÑÑ Ð»Ð¸ fsync Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»ÐµÐ¼ файла, открытого не Ð´Ð»Ñ " "запиÑи:\n" -#: pg_test_fsync.c:460 +#: pg_test_fsync.c:466 #, c-format msgid "" "(If the times are similar, fsync() can sync data written on a different\n" @@ -181,7 +189,7 @@ msgstr "" "данные,\n" "запиÑанные через другой деÑкриптор.)\n" -#: pg_test_fsync.c:525 +#: pg_test_fsync.c:531 #, c-format msgid "" "\n" @@ -190,7 +198,7 @@ msgstr "" "\n" "ÐеÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ %d КБ:\n" -#: pg_test_fsync.c:602 +#: pg_test_fsync.c:608 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/sv.po b/src/bin/pg_test_fsync/po/sv.po index e459fe4e74f..0960dc39f7a 100644 --- a/src/bin/pg_test_fsync/po/sv.po +++ b/src/bin/pg_test_fsync/po/sv.po @@ -7,102 +7,115 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-20 20:16+0000\n" -"PO-Revision-Date: 2017-07-20 22:33+0200\n" +"POT-Creation-Date: 2017-09-07 15:46+0000\n" +"PO-Revision-Date: 2017-09-07 22:15+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: pg_test_fsync.c:48 +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 #, c-format -msgid "Cannot create thread for alarm\n" -msgstr "Kan intr skapa trÃ¥d för larm\n" +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sek %6.0f useks/op\n" -#: pg_test_fsync.c:153 +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "Kunde inte skapa trÃ¥d för larm\n" + +#: pg_test_fsync.c:154 #, c-format msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" msgstr "Användning: %s [-f FILENAMN] [-s SEK-PER-TEST]\n" -#: pg_test_fsync.c:177 pg_test_fsync.c:189 +#: pg_test_fsync.c:178 pg_test_fsync.c:190 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: pg_test_fsync.c:187 +#: pg_test_fsync.c:188 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" -#: pg_test_fsync.c:194 +#: pg_test_fsync.c:195 #, c-format -msgid "%d seconds per test\n" -msgstr "%d sekunder per test\n" +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d sekund per test\n" +msgstr[1] "%d sekunder per test\n" -#: pg_test_fsync.c:196 +#: pg_test_fsync.c:200 #, c-format msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" msgstr "O_DIRECT stöds pÃ¥ denna plattform för open_datasync och open_sync.\n" -#: pg_test_fsync.c:198 +#: pg_test_fsync.c:202 #, c-format msgid "Direct I/O is not supported on this platform.\n" msgstr "Direkt I/O stöds inte pÃ¥ denna plattform.\n" -#: pg_test_fsync.c:223 pg_test_fsync.c:287 pg_test_fsync.c:311 -#: pg_test_fsync.c:334 pg_test_fsync.c:475 pg_test_fsync.c:487 -#: pg_test_fsync.c:503 pg_test_fsync.c:509 pg_test_fsync.c:534 +#: pg_test_fsync.c:227 pg_test_fsync.c:291 pg_test_fsync.c:315 +#: pg_test_fsync.c:338 pg_test_fsync.c:479 pg_test_fsync.c:491 +#: pg_test_fsync.c:507 pg_test_fsync.c:513 pg_test_fsync.c:538 msgid "could not open output file" msgstr "kunde inte öppna utdatafil" -#: pg_test_fsync.c:226 pg_test_fsync.c:268 pg_test_fsync.c:293 -#: pg_test_fsync.c:317 pg_test_fsync.c:340 pg_test_fsync.c:378 -#: pg_test_fsync.c:436 pg_test_fsync.c:477 pg_test_fsync.c:505 -#: pg_test_fsync.c:536 +#: pg_test_fsync.c:230 pg_test_fsync.c:272 pg_test_fsync.c:297 +#: pg_test_fsync.c:321 pg_test_fsync.c:344 pg_test_fsync.c:382 +#: pg_test_fsync.c:440 pg_test_fsync.c:481 pg_test_fsync.c:509 +#: pg_test_fsync.c:540 msgid "write failed" msgstr "skrivning misslyckades" -#: pg_test_fsync.c:230 pg_test_fsync.c:319 pg_test_fsync.c:342 -#: pg_test_fsync.c:479 pg_test_fsync.c:511 +#: pg_test_fsync.c:234 pg_test_fsync.c:323 pg_test_fsync.c:346 +#: pg_test_fsync.c:483 pg_test_fsync.c:515 msgid "fsync failed" msgstr "fsync misslyckades" -#: pg_test_fsync.c:244 +#: pg_test_fsync.c:248 #, c-format msgid "" "\n" "Compare file sync methods using one %dkB write:\n" -msgstr "\nJämför filsynkningsmetoder genom att använda en %dkB-skrivning:\n" +msgstr "" +"\n" +"Jämför filsynkningsmetoder genom att använda en %dkB-skrivning:\n" -#: pg_test_fsync.c:246 +#: pg_test_fsync.c:250 #, c-format msgid "" "\n" "Compare file sync methods using two %dkB writes:\n" -msgstr "\nJämför filsynkningsmetoder genom att använda tvÃ¥ %dkB-skrivningar:\n" +msgstr "" +"\n" +"Jämför filsynkningsmetoder genom att använda tvÃ¥ %dkB-skrivningar:\n" -#: pg_test_fsync.c:247 +#: pg_test_fsync.c:251 #, c-format msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" msgstr "(i wal_sync_method inställningsordning, förutom att fdatasync är standard i Linux)\n" -#: pg_test_fsync.c:258 pg_test_fsync.c:361 pg_test_fsync.c:427 -msgid "n/a*\n" -msgstr "ej tillämpbar*\n" +#: pg_test_fsync.c:262 pg_test_fsync.c:365 pg_test_fsync.c:431 +msgid "n/a*" +msgstr "ej tillämpbar*" -#: pg_test_fsync.c:270 pg_test_fsync.c:296 pg_test_fsync.c:321 -#: pg_test_fsync.c:344 pg_test_fsync.c:380 pg_test_fsync.c:438 +#: pg_test_fsync.c:274 pg_test_fsync.c:300 pg_test_fsync.c:325 +#: pg_test_fsync.c:348 pg_test_fsync.c:384 pg_test_fsync.c:442 msgid "seek failed" msgstr "seek misslyckades" -#: pg_test_fsync.c:276 pg_test_fsync.c:301 pg_test_fsync.c:349 -#: pg_test_fsync.c:386 pg_test_fsync.c:444 -msgid "n/a\n" -msgstr "ej tillämpbar\n" +#: pg_test_fsync.c:280 pg_test_fsync.c:305 pg_test_fsync.c:353 +#: pg_test_fsync.c:390 pg_test_fsync.c:448 +msgid "n/a" +msgstr "ej tillämpbar" -#: pg_test_fsync.c:391 +#: pg_test_fsync.c:395 #, c-format msgid "" "* This file system and its mount options do not support direct\n" @@ -111,14 +124,16 @@ msgstr "" "* Detta filsystem och dess monteringsflaffor stöder inte\n" " direkt I/O, t.ex. ext4 i journalläge.\n" -#: pg_test_fsync.c:399 +#: pg_test_fsync.c:403 #, c-format msgid "" "\n" "Compare open_sync with different write sizes:\n" -msgstr "\nJämför open_sync med olika skrivstorlekar:\n" +msgstr "" +"\n" +"Jämför open_sync med olika skrivstorlekar:\n" -#: pg_test_fsync.c:400 +#: pg_test_fsync.c:404 #, c-format msgid "" "(This is designed to compare the cost of writing 16kB in different write\n" @@ -127,34 +142,36 @@ msgstr "" "(Detta är gjort för att jämföra kostnaden att skriva 16kB med olika\n" "open_sync skrivstorlekar.)\n" -#: pg_test_fsync.c:403 +#: pg_test_fsync.c:407 msgid " 1 * 16kB open_sync write" msgstr " 1 * 16kB open_sync skrivning" -#: pg_test_fsync.c:404 +#: pg_test_fsync.c:408 msgid " 2 * 8kB open_sync writes" msgstr " 2 * 8kB open_sync skrivningar" -#: pg_test_fsync.c:405 +#: pg_test_fsync.c:409 msgid " 4 * 4kB open_sync writes" msgstr " 4 * 4kB open_sync skrivningar" -#: pg_test_fsync.c:406 +#: pg_test_fsync.c:410 msgid " 8 * 2kB open_sync writes" msgstr " 8 * 2kB open_sync skrivningar" -#: pg_test_fsync.c:407 +#: pg_test_fsync.c:411 msgid "16 * 1kB open_sync writes" msgstr "16 * 1kB open_sync skrivningar" -#: pg_test_fsync.c:460 +#: pg_test_fsync.c:464 #, c-format msgid "" "\n" "Test if fsync on non-write file descriptor is honored:\n" -msgstr "\nTesta om fsync pÃ¥ en icke skrivbar fildeskriptor respekteras:\n" +msgstr "" +"\n" +"Testa om fsync pÃ¥ en icke skrivbar fildeskriptor respekteras:\n" -#: pg_test_fsync.c:461 +#: pg_test_fsync.c:465 #, c-format msgid "" "(If the times are similar, fsync() can sync data written on a different\n" @@ -163,14 +180,16 @@ msgstr "" "(Om tiderna är liknande, sÃ¥ kan fsync() synka data skriven pÃ¥\n" "olika deskriptorer.)\n" -#: pg_test_fsync.c:526 +#: pg_test_fsync.c:530 #, c-format msgid "" "\n" "Non-sync'ed %dkB writes:\n" -msgstr "\nIcke-synkade %dkB-skrivningar:\n" +msgstr "" +"\n" +"Icke-synkade %dkB-skrivningar:\n" -#: pg_test_fsync.c:603 +#: pg_test_fsync.c:607 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/tr.po b/src/bin/pg_test_fsync/po/tr.po new file mode 100644 index 00000000000..12f0e2887b1 --- /dev/null +++ b/src/bin/pg_test_fsync/po/tr.po @@ -0,0 +1,194 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_fsync (PostgreSQL) package. +# FIRST AUTHOR , 2017. +# Abdullah GÜLNER , 2017, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-11-28 12:46+0000\n" +"PO-Revision-Date: 2018-11-28 17:01+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7.1\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f ops/sec %6.0f usecs/op\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "Alarm için thread oluÅŸturulamadı\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Kullanımı: %s [-f DOSYAADI] [-s TEST-BASINA-SANIYE]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: Çok fazla komut satırı girdisi var (ilki \"%s\")\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "test başına %d saniye\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "Bu platformda open_datasync ve open_sync için O_DIRECT destekleniyor.\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "DoÄŸrudan I/O bu platformda desteklenmiyor.\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:292 pg_test_fsync.c:316 +#: pg_test_fsync.c:339 pg_test_fsync.c:480 pg_test_fsync.c:492 +#: pg_test_fsync.c:508 pg_test_fsync.c:514 pg_test_fsync.c:539 +msgid "could not open output file" +msgstr "çıktı dosyası açılamadı" + +#: pg_test_fsync.c:231 pg_test_fsync.c:273 pg_test_fsync.c:298 +#: pg_test_fsync.c:322 pg_test_fsync.c:345 pg_test_fsync.c:383 +#: pg_test_fsync.c:441 pg_test_fsync.c:482 pg_test_fsync.c:510 +#: pg_test_fsync.c:541 +msgid "write failed" +msgstr "yazma baÅŸarısız oldu" + +#: pg_test_fsync.c:235 pg_test_fsync.c:324 pg_test_fsync.c:347 +#: pg_test_fsync.c:484 pg_test_fsync.c:516 +msgid "fsync failed" +msgstr "fsync baÅŸarısız oldu" + +#: pg_test_fsync.c:249 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"Dosya sync yöntemlerini bir %dkB yazma kullanarak karşılaÅŸtır\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"Dosya sync yöntemlerini iki %dkB yazma kullanarak karşılaÅŸtır\n" + +#: pg_test_fsync.c:252 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(wal_sync_method tercih sırasında, fdatadync'in Linux'un varsayılanı olması dışında)\n" + +#: pg_test_fsync.c:263 pg_test_fsync.c:366 pg_test_fsync.c:432 +msgid "n/a*" +msgstr "n/a* (uygulanamaz)" + +#: pg_test_fsync.c:275 pg_test_fsync.c:301 pg_test_fsync.c:326 +#: pg_test_fsync.c:349 pg_test_fsync.c:385 pg_test_fsync.c:443 +msgid "seek failed" +msgstr "arama baÅŸarıız oldu" + +#: pg_test_fsync.c:281 pg_test_fsync.c:306 pg_test_fsync.c:354 +#: pg_test_fsync.c:391 pg_test_fsync.c:449 +msgid "n/a" +msgstr "n/a (uygulanamaz)" + +#: pg_test_fsync.c:396 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Bu dosya sistemi ve baÄŸlama (mount) seçenekleri doÄŸrudan I/O\n" +" desteklemiyor, örn: günlüklü modda ext4.\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"open_sync ile farklı yazma boyutlarını kıyaslayın\n" + +#: pg_test_fsync.c:405 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Bu, farklı write open-sync boyutlarında 16kB yazma maliyetini karşılaÅŸtırmak\n" +"için tasarlanmıştır.)\n" + +#: pg_test_fsync.c:408 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync yazma" + +#: pg_test_fsync.c:409 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync yazma" + +#: pg_test_fsync.c:410 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync yazma" + +#: pg_test_fsync.c:411 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync yazma" + +#: pg_test_fsync.c:412 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync yazma" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" + +#: pg_test_fsync.c:466 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Zamanlar benzerse, fsync() farklı bir tanımlayıcıda (descriptor) yazılmış veriyi\n" +"senkronize edebilir.)\n" + +#: pg_test_fsync.c:531 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"sync edilmemiÅŸ %dkB yazma:\n" + +#: pg_test_fsync.c:608 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_fsync/po/vi.po b/src/bin/pg_test_fsync/po/vi.po new file mode 100644 index 00000000000..32a5b549874 --- /dev/null +++ b/src/bin/pg_test_fsync/po/vi.po @@ -0,0 +1,195 @@ +# LANGUAGE message translation file for pg_test_fsync +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_fsync (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_fsync (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:17+0000\n" +"PO-Revision-Date: 2018-04-30 00:47+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Language: vi_VN\n" + +#. translator: maintain alignment with NA_FORMAT +#: pg_test_fsync.c:30 +#, c-format +msgid "%13.3f ops/sec %6.0f usecs/op\n" +msgstr "%13.3f thao tác/giây %6.0f micro giây/thao tác\n" + +#: pg_test_fsync.c:49 +#, c-format +msgid "Could not create thread for alarm\n" +msgstr "Không thể tạo luồng sá»­ dụng cho alarm\n" + +#: pg_test_fsync.c:154 +#, c-format +msgid "Usage: %s [-f FILENAME] [-s SECS-PER-TEST]\n" +msgstr "Cách sá»­ dụng: %s [-f TÊN FILE] [-s Sá» GIÂY CHO MỘT KIỂM TRA]\n" + +#: pg_test_fsync.c:178 pg_test_fsync.c:190 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_test_fsync.c:188 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: quá nhiá»u đối số cho câu lệnh (đầu tiên là \"%s\")\n" + +#: pg_test_fsync.c:195 +#, c-format +msgid "%d second per test\n" +msgid_plural "%d seconds per test\n" +msgstr[0] "%d giây cho má»—i kiểm tra\n" + +#: pg_test_fsync.c:200 +#, c-format +msgid "O_DIRECT supported on this platform for open_datasync and open_sync.\n" +msgstr "O_DIRECT được há»— trợ trên hệ Ä‘iá»u hành này cho open_datasync và open_sync.\n" + +#: pg_test_fsync.c:202 +#, c-format +msgid "Direct I/O is not supported on this platform.\n" +msgstr "I/O trá»±c tiếp không được há»— trợ trên hệ Ä‘iá»u hành này.\n" + +#: pg_test_fsync.c:227 pg_test_fsync.c:292 pg_test_fsync.c:316 +#: pg_test_fsync.c:339 pg_test_fsync.c:480 pg_test_fsync.c:492 +#: pg_test_fsync.c:508 pg_test_fsync.c:514 pg_test_fsync.c:539 +msgid "could not open output file" +msgstr "không thể mở tập tin đầu ra" + +#: pg_test_fsync.c:231 pg_test_fsync.c:273 pg_test_fsync.c:298 +#: pg_test_fsync.c:322 pg_test_fsync.c:345 pg_test_fsync.c:383 +#: pg_test_fsync.c:441 pg_test_fsync.c:482 pg_test_fsync.c:510 +#: pg_test_fsync.c:541 +msgid "write failed" +msgstr "viết không thành công" + +#: pg_test_fsync.c:235 pg_test_fsync.c:324 pg_test_fsync.c:347 +#: pg_test_fsync.c:484 pg_test_fsync.c:516 +msgid "fsync failed" +msgstr "đồng bá»™ không thành công" + +#: pg_test_fsync.c:249 +#, c-format +msgid "" +"\n" +"Compare file sync methods using one %dkB write:\n" +msgstr "" +"\n" +"So sánh các phương pháp đồng bá»™ hóa tệp sá»­ dụng viết má»™t %dkB:\n" + +#: pg_test_fsync.c:251 +#, c-format +msgid "" +"\n" +"Compare file sync methods using two %dkB writes:\n" +msgstr "" +"\n" +"So sánh các phương pháp đồng bá»™ hóa tệp sá»­ dụng viết hai %dkB:\n" + +#: pg_test_fsync.c:252 +#, c-format +msgid "(in wal_sync_method preference order, except fdatasync is Linux's default)\n" +msgstr "(theo thứ tá»± ưu tiên tham số wal_sync_method, ngoại trừ fdatasync là mặc định cá»§a Linux)\n" + +#: pg_test_fsync.c:263 pg_test_fsync.c:366 pg_test_fsync.c:432 +msgid "n/a*" +msgstr "không khả dụng*" + +#: pg_test_fsync.c:275 pg_test_fsync.c:301 pg_test_fsync.c:326 +#: pg_test_fsync.c:349 pg_test_fsync.c:385 pg_test_fsync.c:443 +msgid "seek failed" +msgstr "seek lá»—i" + +#: pg_test_fsync.c:281 pg_test_fsync.c:306 pg_test_fsync.c:354 +#: pg_test_fsync.c:391 pg_test_fsync.c:449 +msgid "n/a" +msgstr "không khả dụng" + +#: pg_test_fsync.c:396 +#, c-format +msgid "" +"* This file system and its mount options do not support direct\n" +" I/O, e.g. ext4 in journaled mode.\n" +msgstr "" +"* Hệ thống tệp này và tùy chá»n mount không há»— trợ I/O trá»±c tiếp\n" +" ví dụ: ext4 trong chế độ journaled.\n" + +#: pg_test_fsync.c:404 +#, c-format +msgid "" +"\n" +"Compare open_sync with different write sizes:\n" +msgstr "" +"\n" +"So sánh open_sync vá»›i các kích thước ghi khác nhau:\n" + +#: pg_test_fsync.c:405 +#, c-format +msgid "" +"(This is designed to compare the cost of writing 16kB in different write\n" +"open_sync sizes.)\n" +msgstr "" +"(Äiá»u này được thiết kế để so sánh cost cá»§a việc viết 16kB trong các \n" +"kích thước open_sync khác nhau.)\n" + +#: pg_test_fsync.c:408 +msgid " 1 * 16kB open_sync write" +msgstr " 1 * 16kB open_sync write" + +#: pg_test_fsync.c:409 +msgid " 2 * 8kB open_sync writes" +msgstr " 2 * 8kB open_sync writes" + +#: pg_test_fsync.c:410 +msgid " 4 * 4kB open_sync writes" +msgstr " 4 * 4kB open_sync writes" + +#: pg_test_fsync.c:411 +msgid " 8 * 2kB open_sync writes" +msgstr " 8 * 2kB open_sync writes" + +#: pg_test_fsync.c:412 +msgid "16 * 1kB open_sync writes" +msgstr "16 * 1kB open_sync writes" + +#: pg_test_fsync.c:465 +#, c-format +msgid "" +"\n" +"Test if fsync on non-write file descriptor is honored:\n" +msgstr "" +"\n" +"Kiểm tra xem fsync trên tệp descrtiptor không ghi có tốt không:\n" + +#: pg_test_fsync.c:466 +#, c-format +msgid "" +"(If the times are similar, fsync() can sync data written on a different\n" +"descriptor.)\n" +msgstr "" +"(Nếu số lần là tương đương, fsync() có thể đồng bá»™ dữ liệu được ghi ở \n" +"descriptor khác.)\n" + +#: pg_test_fsync.c:531 +#, c-format +msgid "" +"\n" +"Non-sync'ed %dkB writes:\n" +msgstr "" +"\n" +"Viết %dkB không sync:\n" + +#: pg_test_fsync.c:608 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" diff --git a/src/bin/pg_test_timing/nls.mk b/src/bin/pg_test_timing/nls.mk index dd70a12b774..c4000b4aa6a 100644 --- a/src/bin/pg_test_timing/nls.mk +++ b/src/bin/pg_test_timing/nls.mk @@ -1,4 +1,4 @@ # src/bin/pg_test_timing/nls.mk CATALOG_NAME = pg_test_timing -AVAIL_LANGUAGES =de es fr pl ru sv +AVAIL_LANGUAGES =cs de es fr ja ko pl ru sv tr vi GETTEXT_FILES = pg_test_timing.c diff --git a/src/bin/pg_test_timing/pg_test_timing.c b/src/bin/pg_test_timing/pg_test_timing.c index 6e2fd1ab8c7..e14802372bd 100644 --- a/src/bin/pg_test_timing/pg_test_timing.c +++ b/src/bin/pg_test_timing/pg_test_timing.c @@ -18,7 +18,7 @@ static uint64 test_timing(int32); static void output(uint64 loop_count); /* record duration in powers of 2 microseconds */ -int64 histogram[32]; +long long int histogram[32]; int main(int argc, char *argv[]) @@ -190,14 +190,8 @@ output(uint64 loop_count) Max(10, len3), header3); for (i = 0; i <= max_bit; i++) - { - char buf[100]; - - /* lame hack to work around INT64_FORMAT deficiencies */ - snprintf(buf, sizeof(buf), INT64_FORMAT, histogram[i]); - printf("%*ld %*.5f %*s\n", + printf("%*ld %*.5f %*lld\n", Max(6, len1), 1l << i, Max(10, len2) - 1, (double) histogram[i] * 100 / loop_count, - Max(10, len3), buf); - } + Max(10, len3), histogram[i]); } diff --git a/src/bin/pg_test_timing/po/cs.po b/src/bin/pg_test_timing/po/cs.po new file mode 100644 index 00000000000..1d53e94453f --- /dev/null +++ b/src/bin/pg_test_timing/po/cs.po @@ -0,0 +1,80 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-07-13 19:46+0000\n" +"PO-Revision-Date: 2018-07-13 23:50+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Poedit 2.0.7\n" + +#: pg_test_timing.c:55 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Použití: %s [-d DURATION]\n" + +#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: pg_test_timing.c:85 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: příliÅ¡ mnoho argumentů v příkazové řádce (první je \"%s\")\n" + +#: pg_test_timing.c:94 +#, c-format +msgid "Testing timing overhead for %d second.\n" +msgid_plural "Testing timing overhead for %d seconds.\n" +msgstr[0] "Testuji režii Äasování po %d sekund.\n" +msgstr[1] "Testuji režii Äasování po %d sekundy.\n" +msgstr[2] "Testuji režii Äasování po %d sekund.\n" + +#: pg_test_timing.c:102 +#, c-format +msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgstr "%s: trvání testu musí být kladné celé Äíslo (trvání je \"%d\")\n" + +#: pg_test_timing.c:140 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Detekovány posun hodin zpÄ›t v Äase.\n" + +#: pg_test_timing.c:141 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Time warp: %d ms\n" + +#: pg_test_timing.c:164 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "ÄŒas pro smyÄku vÄetnÄ› režie: %0.2f ns\n" + +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% celku" + +#: pg_test_timing.c:177 +msgid "count" +msgstr "poÄet" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histogram trvání:\n" diff --git a/src/bin/pg_test_timing/po/de.po b/src/bin/pg_test_timing/po/de.po index a7817c5ba84..57984f8dd9d 100644 --- a/src/bin/pg_test_timing/po/de.po +++ b/src/bin/pg_test_timing/po/de.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-02-10 21:45+0000\n" -"PO-Revision-Date: 2017-02-10 21:46-0500\n" +"POT-Creation-Date: 2017-08-26 15:45+0000\n" +"PO-Revision-Date: 2017-08-26 12:30-0400\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -61,19 +61,20 @@ msgstr "Zeitdifferenz: %d ms\n" msgid "Per loop time including overhead: %0.2f ns\n" msgstr "Zeit pro Durchlauf einschließlich Overhead: %0.2f ns\n" -#: pg_test_timing.c:180 -#, c-format -msgid "Histogram of timing durations:\n" -msgstr "Histogramm der Dauern der Zeitmessungen:\n" +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< µs" -#: pg_test_timing.c:181 +#: pg_test_timing.c:176 +#, no-c-format msgid "% of total" msgstr "% von gesamt" -#: pg_test_timing.c:181 -msgid "< us" -msgstr "< us" - -#: pg_test_timing.c:181 +#: pg_test_timing.c:177 msgid "count" msgstr "Anzahl" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histogramm der Dauern der Zeitmessungen:\n" diff --git a/src/bin/pg_test_timing/po/es.po b/src/bin/pg_test_timing/po/es.po index c4a5109cff8..27447289736 100644 --- a/src/bin/pg_test_timing/po/es.po +++ b/src/bin/pg_test_timing/po/es.po @@ -1,24 +1,24 @@ # Spanish message translation file for pg_test_timing # -# Copyright (C) 2017 PostgreSQL Global Development Group +# Copyright (c) 2017-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # -# Carlos Chapi , 2017. +# Carlos Chapi , 2017. # msgid "" msgstr "" -"Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: pg_test_timing (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:14+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" #: pg_test_timing.c:55 #, c-format @@ -62,20 +62,20 @@ msgstr "Desfase de tiempo: %d ms\n" msgid "Per loop time including overhead: %0.2f ns\n" msgstr "Tiempo por lectura incluyendo sobrecosto: %0.2f ns\n" -#: pg_test_timing.c:180 -#, c-format -msgid "Histogram of timing durations:\n" -msgstr "Histograma de duraciones de lectura de reloj:\n" - -#: pg_test_timing.c:181 -#, c-format -msgid "% of total" -msgstr "" - -#: pg_test_timing.c:181 +#: pg_test_timing.c:175 msgid "< us" msgstr "< us" -#: pg_test_timing.c:181 +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% del total" + +#: pg_test_timing.c:177 msgid "count" msgstr "cantidad" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histograma de duraciones de lectura de reloj:\n" diff --git a/src/bin/pg_test_timing/po/fr.po b/src/bin/pg_test_timing/po/fr.po index 1882b3bc34e..4613c8bf91a 100644 --- a/src/bin/pg_test_timing/po/fr.po +++ b/src/bin/pg_test_timing/po/fr.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 02:45+0000\n" -"PO-Revision-Date: 2017-07-29 21:37+0200\n" +"POT-Creation-Date: 2017-11-06 09:45+0000\n" +"PO-Revision-Date: 2017-11-11 14:21+0100\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.0.3\n" #: pg_test_timing.c:55 #, c-format @@ -60,20 +60,20 @@ msgstr "Décalage de temps : %d ms\n" msgid "Per loop time including overhead: %0.2f ns\n" msgstr "Durée par boucle incluant le coût : %0.2f ns\n" -#: pg_test_timing.c:180 -#, c-format -msgid "Histogram of timing durations:\n" -msgstr "Histogramme des durées de chronométrage\n" - -#: pg_test_timing.c:181 -#, c-format -msgid "% of total" -msgstr "" - -#: pg_test_timing.c:181 +#: pg_test_timing.c:175 msgid "< us" msgstr "< us" -#: pg_test_timing.c:181 +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% du total" + +#: pg_test_timing.c:177 msgid "count" msgstr "nombre" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Histogramme des durées de chronométrage\n" diff --git a/src/bin/pg_test_timing/po/ja.po b/src/bin/pg_test_timing/po/ja.po new file mode 100644 index 00000000000..33efc7664e5 --- /dev/null +++ b/src/bin/pg_test_timing/po/ja.po @@ -0,0 +1,78 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-01-31 13:31+0900\n" +"PO-Revision-Date: 2018-01-31 14:03+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Last-Translator: Michihide Hotta \n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.6\n" + +#: pg_test_timing.c:55 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "使用方法: %s [-d 期間]\n" + +#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\" ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。\n" + +#: pg_test_timing.c:85 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™ï¼ˆå…ˆé ­ã¯ \"%s\")\n" + +#: pg_test_timing.c:94 +#, c-format +msgid "Testing timing overhead for %d second.\n" +msgid_plural "Testing timing overhead for %d seconds.\n" +msgstr[0] "%d ç§’ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ˜ãƒƒãƒ‰ã‚’テストã—ã¦ã„ã¾ã™ã€‚\n" + +#: pg_test_timing.c:102 +#, c-format +msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgstr "%s: æŒç¶šæ™‚é–“ã¯æ­£ã®æ•´æ•°ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ (æŒç¶šæ™‚é–“ã¯\"%d\")\n" + +#: pg_test_timing.c:140 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "ã‚¯ãƒ­ãƒƒã‚¯ã®æ™‚刻ãŒé€†è¡Œã—ã¦ã„ã‚‹ã“ã¨ã‚’検出ã—ã¾ã—ãŸã€‚\n" + +#: pg_test_timing.c:141 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "逆行ã—ãŸæ™‚é–“: %d ms\n" + +#: pg_test_timing.c:164 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "オーãƒãƒ¼ãƒ˜ãƒƒãƒ‰è¾¼ã¿ã®ãƒ«ãƒ¼ãƒ—時間毎: %0.2f ns\n" + +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "全体ã®ï¼…" + +#: pg_test_timing.c:177 +msgid "count" +msgstr "個数" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "タイミングæŒç¶šæ™‚é–“ã®ãƒ’ストグラム:\n" diff --git a/src/bin/pg_test_timing/po/ko.po b/src/bin/pg_test_timing/po/ko.po new file mode 100644 index 00000000000..dd80881bd73 --- /dev/null +++ b/src/bin/pg_test_timing/po/ko.po @@ -0,0 +1,77 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:25+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: pg_test_timing.c:55 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "사용법: %s [-d 간격]\n" + +#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "ë” ìžì„¸í•œ 정보는 \"%s --help\" ëª…ë ¹ì„ ì´ìš©í•˜ì„¸ìš”.\n" + +#: pg_test_timing.c:85 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìžë¥¼ 사용했습니다 (ì‹œìž‘ì€ \"%s\")\n" + +#: pg_test_timing.c:94 +#, c-format +msgid "Testing timing overhead for %d second.\n" +msgid_plural "Testing timing overhead for %d seconds.\n" +msgstr[0] "%dì´ˆ ë™ì•ˆ 타ì´ë° ì˜¤ë²„í•´ë” ê²€ì‚¬.\n" + +#: pg_test_timing.c:102 +#, c-format +msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgstr "%s: ê°„ê²©ì€ ì–‘ìˆ˜ì—¬ì•¼ 합니다. (간격: \"%d\")\n" + +#: pg_test_timing.c:140 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "거꾸로 í른 ê°ì§€ëœ í´ëŸ­.\n" + +#: pg_test_timing.c:141 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "간격: %d ms\n" + +#: pg_test_timing.c:164 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "오버헤ë”를 í¬í•¨í•œ 루프 시간: %0.2f ns\n" + +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% of total" + +#: pg_test_timing.c:177 +msgid "count" +msgstr "회" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "타ì´ë° 간견 히스토그램:\n" diff --git a/src/bin/pg_test_timing/po/ru.po b/src/bin/pg_test_timing/po/ru.po index e9b85aa033c..db072b3232d 100644 --- a/src/bin/pg_test_timing/po/ru.po +++ b/src/bin/pg_test_timing/po/ru.po @@ -1,20 +1,19 @@ # Russian message translation file for pg_test_timing # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander LAW , 2017. -# +# Alexander Lakhin , 2017. msgid "" msgstr "" "Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-04 04:15+0000\n" -"PO-Revision-Date: 2017-04-04 12:55+0300\n" +"POT-Creation-Date: 2017-09-20 18:14+0000\n" +"PO-Revision-Date: 2017-08-23 19:20+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Alexander Lakhin \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" @@ -62,20 +61,20 @@ msgstr "Сдвиг времени: %d мÑ\n" msgid "Per loop time including overhead: %0.2f ns\n" msgstr "Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾ цикла, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¸Ð·Ð´ÐµÑ€Ð¶ÐºÐ¸: %0.2f нÑ\n" -#: pg_test_timing.c:180 -#, c-format -msgid "Histogram of timing durations:\n" -msgstr "ГиÑтограмма длительноÑти замеров времени:\n" - -#: pg_test_timing.c:181 -#, c-format -msgid "%% of total" -msgstr "%% от общего" - -#: pg_test_timing.c:181 +#: pg_test_timing.c:175 msgid "< us" msgstr "< мкÑ" -#: pg_test_timing.c:181 +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% от общего" + +#: pg_test_timing.c:177 msgid "count" msgstr "чиÑло" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "ГиÑтограмма длительноÑти замеров времени:\n" diff --git a/src/bin/pg_test_timing/po/tr.po b/src/bin/pg_test_timing/po/tr.po new file mode 100644 index 00000000000..8ae31a81875 --- /dev/null +++ b/src/bin/pg_test_timing/po/tr.po @@ -0,0 +1,78 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-02-11 18:45+0000\n" +"PO-Revision-Date: 2018-02-12 15:29+0300\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Last-Translator: \n" +"Language-Team: \n" +"X-Generator: Poedit 1.8.7.1\n" + +#: pg_test_timing.c:55 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Kullanım: %s [-d SÜRE]\n" + +#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: pg_test_timing.c:85 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: Çok fazla komut satırı girdisi var (ilki \"%s\")\n" + +#: pg_test_timing.c:94 +#, c-format +msgid "Testing timing overhead for %d second.\n" +msgid_plural "Testing timing overhead for %d seconds.\n" +msgstr[0] "Zamanlama yükü %d saniye boyunca test ediliyor\n" + +#: pg_test_timing.c:102 +#, c-format +msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgstr "%s: süre pozitif bir tamsayı olmalı (süre \"%d\" dir)\n" + +#: pg_test_timing.c:140 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Geriye doÄŸru çalışan saat tespit edildi.\n" + +#: pg_test_timing.c:141 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Zaman farkı: %d ms\n" + +#: pg_test_timing.c:164 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Ek yük (overhead) dahil döngü başına geçen süre: %0.2f ns\n" + +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "toplamın % si" + +#: pg_test_timing.c:177 +msgid "count" +msgstr "toplam sayı" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Zamanlama sürelerinin histogramı:\n" diff --git a/src/bin/pg_test_timing/po/vi.po b/src/bin/pg_test_timing/po/vi.po new file mode 100644 index 00000000000..92144003c21 --- /dev/null +++ b/src/bin/pg_test_timing/po/vi.po @@ -0,0 +1,78 @@ +# LANGUAGE message translation file for pg_test_timing +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_test_timing (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_test_timing (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:16+0000\n" +"PO-Revision-Date: 2018-05-04 22:06+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Language: vi_VN\n" + +#: pg_test_timing.c:55 +#, c-format +msgid "Usage: %s [-d DURATION]\n" +msgstr "Cách dùng: %s [-d THỜI LƯỢNG]\n" + +#: pg_test_timing.c:75 pg_test_timing.c:87 pg_test_timing.c:104 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" + +#: pg_test_timing.c:85 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: quá nhiá»u đối số cho câu lệnh (đầu tiên là \"%s\")\n" + +#: pg_test_timing.c:94 +#, c-format +msgid "Testing timing overhead for %d second.\n" +msgid_plural "Testing timing overhead for %d seconds.\n" +msgstr[0] "Kiểm tra thá»i gian vượt quá cho %d giây.\n" + +#: pg_test_timing.c:102 +#, c-format +msgid "%s: duration must be a positive integer (duration is \"%d\")\n" +msgstr "%s: thá»i lượng phải là má»™t số nguyên dương (khoảng thá»i gian: \"%d\")\n" + +#: pg_test_timing.c:140 +#, c-format +msgid "Detected clock going backwards in time.\n" +msgstr "Clock được phát hiện Ä‘ang Ä‘i ngược thá»i gian.\n" + +#: pg_test_timing.c:141 +#, c-format +msgid "Time warp: %d ms\n" +msgstr "Thá»i gian đảo ngược: %d ms\n" + +#: pg_test_timing.c:164 +#, c-format +msgid "Per loop time including overhead: %0.2f ns\n" +msgstr "Thá»i gian má»—i vòng lặp bao gồm cả thá»i gian vượt quá: %0.2f ns\n" + +#: pg_test_timing.c:175 +msgid "< us" +msgstr "< us" + +#: pg_test_timing.c:176 +#, no-c-format +msgid "% of total" +msgstr "% cá»§a tổng" + +#: pg_test_timing.c:177 +msgid "count" +msgstr "số lượng" + +#: pg_test_timing.c:186 +#, c-format +msgid "Histogram of timing durations:\n" +msgstr "Biểu đồ vá» thá»i lượng thá»i gian:\n" diff --git a/src/bin/pg_upgrade/.gitignore b/src/bin/pg_upgrade/.gitignore index 6fb644de7a9..9edea5c98f0 100644 --- a/src/bin/pg_upgrade/.gitignore +++ b/src/bin/pg_upgrade/.gitignore @@ -1,5 +1,6 @@ /pg_upgrade # Generated by test suite +/pg_upgrade_internal.log /analyze_new_cluster.sh /delete_old_cluster.sh /analyze_new_cluster.bat diff --git a/src/bin/pg_upgrade/Makefile b/src/bin/pg_upgrade/Makefile index adb0d5d707a..2cb829acd59 100644 --- a/src/bin/pg_upgrade/Makefile +++ b/src/bin/pg_upgrade/Makefile @@ -14,7 +14,6 @@ OBJS = check.o controldata.o dump.o exec.o file.o function.o info.o \ override CPPFLAGS := -DDLSUFFIX=\"$(DLSUFFIX)\" -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS) LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) - all: pg_upgrade pg_upgrade: $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils @@ -36,8 +35,17 @@ clean distclean maintainer-clean: pg_upgrade_dump_globals.sql \ pg_upgrade_dump_*.custom pg_upgrade_*.log -check: test.sh all - MAKE=$(MAKE) bindir=$(bindir) libdir=$(libdir) EXTRA_REGRESS_OPTS="$(EXTRA_REGRESS_OPTS)" $(SHELL) $< --install +# When $(MAKE) is present, make automatically infers that this is a +# recursive make. which is not actually what we want here, as that +# e.g. prevents output synchronization from working (as make thinks +# that the subsidiary make knows how to deal with that itself, but +# we're invoking a shell script that doesn't know). Referencing +# $(MAKE) indirectly avoids that behaviour. +# See https://www.gnu.org/software/make/manual/html_node/MAKE-Variable.html#MAKE-Variable +NOTSUBMAKEMAKE=$(MAKE) + +check: test.sh all temp-install + MAKE=$(NOTSUBMAKEMAKE) $(with_temp_install) bindir=$(abs_top_builddir)/tmp_install/$(bindir) EXTRA_REGRESS_OPTS="$(EXTRA_REGRESS_OPTS)" $(SHELL) $< # installcheck is not supported because there's no meaningful way to test # pg_upgrade against a single already-running server diff --git a/src/bin/pg_upgrade/TESTING b/src/bin/pg_upgrade/TESTING index 6831f679f66..e69874b42d0 100644 --- a/src/bin/pg_upgrade/TESTING +++ b/src/bin/pg_upgrade/TESTING @@ -36,7 +36,7 @@ Here are the steps needed to create a regression database dump file: 1) Create and populate the regression database in the old cluster. This database can be created by running 'make installcheck' from - src/test/regression. + src/test/regress. 2) Use pg_dump to dump out the regression database. Use the new cluster's pg_dump on the old database to minimize whitespace diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c index 577db73f100..617270f101d 100644 --- a/src/bin/pg_upgrade/check.c +++ b/src/bin/pg_upgrade/check.c @@ -3,7 +3,7 @@ * * server checks and output routines * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/check.c */ @@ -23,6 +23,7 @@ static void check_is_install_user(ClusterInfo *cluster); static void check_proper_datallowconn(ClusterInfo *cluster); static void check_for_prepared_transactions(ClusterInfo *cluster); static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); +static void check_for_tables_with_oids(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster); static void check_for_jsonb_9_4_usage(ClusterInfo *cluster); static void check_for_pg_role_prefix(ClusterInfo *cluster); @@ -100,6 +101,13 @@ check_and_dump_old_cluster(bool live_check) check_for_reg_data_type_usage(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); + /* + * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not + * supported anymore. Verify there are none, iff applicable. + */ + if (GET_MAJOR_VERSION(old_cluster.major_version) <= 1100) + check_for_tables_with_oids(&old_cluster); + /* * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged * hash indexes @@ -149,8 +157,17 @@ check_new_cluster(void) check_loadable_libraries(); - if (user_opts.transfer_mode == TRANSFER_MODE_LINK) - check_hard_link(); + switch (user_opts.transfer_mode) + { + case TRANSFER_MODE_CLONE: + check_file_clone(); + break; + case TRANSFER_MODE_COPY: + break; + case TRANSFER_MODE_LINK: + check_hard_link(); + break; + } check_is_install_user(&new_cluster); @@ -382,8 +399,10 @@ check_new_cluster_is_empty(void) { /* pg_largeobject and its index should be skipped */ if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0) - pg_fatal("New cluster database \"%s\" is not empty\n", - new_cluster.dbarr.dbs[dbnum].db_name); + pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n", + new_cluster.dbarr.dbs[dbnum].db_name, + rel_arr->rels[relnum].nspname, + rel_arr->rels[relnum].relname); } } } @@ -871,6 +890,83 @@ check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster) } +/* + * Verify that no tables are declared WITH OIDS. + */ +static void +check_for_tables_with_oids(ClusterInfo *cluster) +{ + int dbnum; + FILE *script = NULL; + bool found = false; + char output_path[MAXPGPATH]; + + prep_status("Checking for tables WITH OIDS"); + + snprintf(output_path, sizeof(output_path), + "tables_with_oids.txt"); + + /* Find any tables declared WITH OIDS */ + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) + { + PGresult *res; + bool db_used = false; + int ntups; + int rowno; + int i_nspname, + i_relname; + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); + + res = executeQueryOrDie(conn, + "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_namespace n " + "WHERE c.relnamespace = n.oid AND " + " c.relhasoids AND" + " n.nspname NOT IN ('pg_catalog')"); + + ntups = PQntuples(res); + i_nspname = PQfnumber(res, "nspname"); + i_relname = PQfnumber(res, "relname"); + for (rowno = 0; rowno < ntups; rowno++) + { + found = true; + if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %s\n", + output_path, strerror(errno)); + if (!db_used) + { + fprintf(script, "Database: %s\n", active_db->db_name); + db_used = true; + } + fprintf(script, " %s.%s\n", + PQgetvalue(res, rowno, i_nspname), + PQgetvalue(res, rowno, i_relname)); + } + + PQclear(res); + + PQfinish(conn); + } + + if (script) + fclose(script); + + if (found) + { + pg_log(PG_REPORT, "fatal\n"); + pg_fatal("Your installation contains tables declared WITH OIDS, which is not supported\n" + "anymore. Consider removing the oid column using\n" + " ALTER TABLE ... SET WITHOUT OIDS;\n" + "A list of tables with the problem is in the file:\n" + " %s\n\n", output_path); + } + else + check_ok(); +} + + /* * check_for_reg_data_type_usage() * pg_upgrade only preserves these system values: @@ -915,18 +1011,26 @@ check_for_reg_data_type_usage(ClusterInfo *cluster) "SELECT n.nspname, c.relname, a.attname " "FROM pg_catalog.pg_class c, " " pg_catalog.pg_namespace n, " - " pg_catalog.pg_attribute a " + " pg_catalog.pg_attribute a, " + " pg_catalog.pg_type t " "WHERE c.oid = a.attrelid AND " " NOT a.attisdropped AND " - " a.atttypid IN ( " - " 'pg_catalog.regproc'::pg_catalog.regtype, " - " 'pg_catalog.regprocedure'::pg_catalog.regtype, " - " 'pg_catalog.regoper'::pg_catalog.regtype, " - " 'pg_catalog.regoperator'::pg_catalog.regtype, " + " a.atttypid = t.oid AND " + " t.typnamespace = " + " (SELECT oid FROM pg_namespace " + " WHERE nspname = 'pg_catalog') AND" + " t.typname IN ( " /* regclass.oid is preserved, so 'regclass' is OK */ + " 'regconfig', " + " 'regdictionary', " + " 'regnamespace', " + " 'regoper', " + " 'regoperator', " + " 'regproc', " + " 'regprocedure' " + /* regrole.oid is preserved, so 'regrole' is OK */ /* regtype.oid is preserved, so 'regtype' is OK */ - " 'pg_catalog.regconfig'::pg_catalog.regtype, " - " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND " + " ) AND " " c.relnamespace = n.oid AND " " n.nspname NOT IN ('pg_catalog', 'information_schema')"); diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c index 0fe98a550e1..38236415bef 100644 --- a/src/bin/pg_upgrade/controldata.c +++ b/src/bin/pg_upgrade/controldata.c @@ -3,7 +3,7 @@ * * controldata functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/controldata.c */ @@ -58,6 +58,7 @@ get_control_data(ClusterInfo *cluster, bool live_check) bool got_large_object = false; bool got_date_is_int = false; bool got_data_checksum_version = false; + bool got_cluster_state = false; char *lc_collate = NULL; char *lc_ctype = NULL; char *lc_monetary = NULL; @@ -101,17 +102,83 @@ get_control_data(ClusterInfo *cluster, bool live_check) pg_putenv("LC_MONETARY", NULL); pg_putenv("LC_NUMERIC", NULL); pg_putenv("LC_TIME", NULL); - pg_putenv("LANG", #ifndef WIN32 - NULL); + pg_putenv("LANG", NULL); #else - /* On Windows the default locale cannot be English, so force it */ - "en"); + /* On Windows the default locale may not be English, so force it */ + pg_putenv("LANG", "en"); #endif pg_putenv("LANGUAGE", NULL); pg_putenv("LC_ALL", NULL); pg_putenv("LC_MESSAGES", "C"); + /* + * Check for clean shutdown + */ + if (!live_check || cluster == &new_cluster) + { + /* only pg_controldata outputs the cluster state */ + snprintf(cmd, sizeof(cmd), "\"%s/pg_controldata\" \"%s\"", + cluster->bindir, cluster->pgdata); + fflush(stdout); + fflush(stderr); + + if ((output = popen(cmd, "r")) == NULL) + pg_fatal("could not get control data using %s: %s\n", + cmd, strerror(errno)); + + /* we have the result of cmd in "output". so parse it line by line now */ + while (fgets(bufin, sizeof(bufin), output)) + { + if ((p = strstr(bufin, "Database cluster state:")) != NULL) + { + p = strchr(p, ':'); + + if (p == NULL || strlen(p) <= 1) + pg_fatal("%d: database cluster state problem\n", __LINE__); + + p++; /* remove ':' char */ + + /* + * We checked earlier for a postmaster lock file, and if we + * found one, we tried to start/stop the server to replay the + * WAL. However, pg_ctl -m immediate doesn't leave a lock + * file, but does require WAL replay, so we check here that + * the server was shut down cleanly, from the controldata + * perspective. + */ + /* remove leading spaces */ + while (*p == ' ') + p++; + if (strcmp(p, "shut down in recovery\n") == 0) + { + if (cluster == &old_cluster) + pg_fatal("The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n"); + else + pg_fatal("The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n"); + } + else if (strcmp(p, "shut down\n") != 0) + { + if (cluster == &old_cluster) + pg_fatal("The source cluster was not shut down cleanly.\n"); + else + pg_fatal("The target cluster was not shut down cleanly.\n"); + } + got_cluster_state = true; + } + } + + pclose(output); + + if (!got_cluster_state) + { + if (cluster == &old_cluster) + pg_fatal("The source cluster lacks cluster state information:\n"); + else + pg_fatal("The target cluster lacks cluster state information:\n"); + } + } + /* pg_resetxlog has been renamed to pg_resetwal in version 10 */ if (GET_MAJOR_VERSION(cluster->bin_version) < 1000) resetwal_bin = "pg_resetxlog\" -n"; diff --git a/src/bin/pg_upgrade/dump.c b/src/bin/pg_upgrade/dump.c index def22c65211..c1429fe4bfb 100644 --- a/src/bin/pg_upgrade/dump.c +++ b/src/bin/pg_upgrade/dump.c @@ -3,7 +3,7 @@ * * dump functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/dump.c */ @@ -42,7 +42,7 @@ generate_old_dump(void) escaped_connstr; initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, old_db->db_name); initPQExpBuffer(&escaped_connstr); appendShellString(&escaped_connstr, connstr.data); diff --git a/src/bin/pg_upgrade/exec.c b/src/bin/pg_upgrade/exec.c index 9122e2769e1..dba02c495dd 100644 --- a/src/bin/pg_upgrade/exec.c +++ b/src/bin/pg_upgrade/exec.c @@ -3,7 +3,7 @@ * * execution functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/exec.c */ @@ -110,6 +110,7 @@ exec_prog(const char *log_file, const char *opt_log_file, pg_log(PG_VERBOSE, "%s\n", cmd); #ifdef WIN32 + /* * For some reason, Windows issues a file-in-use error if we write data to * the log file from a non-primary thread just before we create a @@ -145,7 +146,7 @@ exec_prog(const char *log_file, const char *opt_log_file, #endif if (log == NULL) - pg_fatal("could not write to log file \"%s\"\n", log_file); + pg_fatal("could not open log file \"%s\": %m\n", log_file); #ifdef WIN32 /* Are we printing "command:" before its output? */ @@ -191,6 +192,7 @@ exec_prog(const char *log_file, const char *opt_log_file, } #ifndef WIN32 + /* * We can't do this on Windows because it will keep the "pg_ctl start" * output filename open until the server stops, so we do the \n\n above on @@ -199,7 +201,7 @@ exec_prog(const char *log_file, const char *opt_log_file, * log these commands to a third file, but that just adds complexity. */ if ((log = fopen(log_file, "a")) == NULL) - pg_fatal("could not write to log file \"%s\"\n", log_file); + pg_fatal("could not write to log file \"%s\": %m\n", log_file); fprintf(log, "\n\n"); fclose(log); #endif @@ -374,6 +376,7 @@ check_bin_dir(ClusterInfo *cluster) cluster->bindir); validate_exec(cluster->bindir, "postgres"); + validate_exec(cluster->bindir, "pg_controldata"); validate_exec(cluster->bindir, "pg_ctl"); /* @@ -388,12 +391,20 @@ check_bin_dir(ClusterInfo *cluster) validate_exec(cluster->bindir, "pg_resetxlog"); else validate_exec(cluster->bindir, "pg_resetwal"); + if (cluster == &new_cluster) { - /* these are only needed in the new cluster */ - validate_exec(cluster->bindir, "psql"); + /* + * These binaries are only needed for the target version. pg_dump and + * pg_dumpall are used to dump the old cluster, but must be of the + * target version. + */ + validate_exec(cluster->bindir, "initdb"); validate_exec(cluster->bindir, "pg_dump"); validate_exec(cluster->bindir, "pg_dumpall"); + validate_exec(cluster->bindir, "pg_restore"); + validate_exec(cluster->bindir, "psql"); + validate_exec(cluster->bindir, "vacuumdb"); } } diff --git a/src/bin/pg_upgrade/file.c b/src/bin/pg_upgrade/file.c index f68211aa20a..c7fed24df93 100644 --- a/src/bin/pg_upgrade/file.c +++ b/src/bin/pg_upgrade/file.c @@ -3,7 +3,7 @@ * * file system operations * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/file.c */ @@ -18,6 +18,13 @@ #include #include +#ifdef HAVE_COPYFILE_H +#include +#endif +#ifdef __linux__ +#include +#include +#endif #ifdef WIN32 @@ -25,6 +32,47 @@ static int win32_pghardlink(const char *src, const char *dst); #endif +/* + * cloneFile() + * + * Clones/reflinks a relation file from src to dst. + * + * schemaName/relName are relation's SQL name (used for error messages only). + */ +void +cloneFile(const char *src, const char *dst, + const char *schemaName, const char *relName) +{ +#if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE) + if (copyfile(src, dst, NULL, COPYFILE_CLONE_FORCE) < 0) + pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n", + schemaName, relName, src, dst, strerror(errno)); +#elif defined(__linux__) && defined(FICLONE) + int src_fd; + int dest_fd; + + if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0) + pg_fatal("error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n", + schemaName, relName, src, strerror(errno)); + + if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, + pg_file_create_mode)) < 0) + pg_fatal("error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n", + schemaName, relName, dst, strerror(errno)); + + if (ioctl(dest_fd, FICLONE, src_fd) < 0) + { + unlink(dst); + pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n", + schemaName, relName, src, dst, strerror(errno)); + } + + close(src_fd); + close(dest_fd); +#endif +} + + /* * copyFile() * @@ -132,8 +180,8 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, { int src_fd; int dst_fd; - char *buffer; - char *new_vmbuf; + PGAlignedBlock buffer; + PGAlignedBlock new_vmbuf; ssize_t totalBytesRead = 0; ssize_t src_filesize; int rewriteVmBytesPerPage; @@ -159,13 +207,6 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, /* Save old file size */ src_filesize = statbuf.st_size; - /* - * Malloc the work buffers, rather than making them local arrays, to - * ensure adequate alignment. - */ - buffer = (char *) pg_malloc(BLCKSZ); - new_vmbuf = (char *) pg_malloc(BLCKSZ); - /* * Turn each visibility map page into 2 pages one by one. Each new page * has the same page header as the old one. If the last section of the @@ -181,7 +222,7 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, PageHeaderData pageheader; bool old_lastblk; - if ((bytesRead = read(src_fd, buffer, BLCKSZ)) != BLCKSZ) + if ((bytesRead = read(src_fd, buffer.data, BLCKSZ)) != BLCKSZ) { if (bytesRead < 0) pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n", @@ -195,7 +236,7 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, old_lastblk = (totalBytesRead == src_filesize); /* Save the page header data */ - memcpy(&pageheader, buffer, SizeOfPageHeaderData); + memcpy(&pageheader, buffer.data, SizeOfPageHeaderData); /* * These old_* variables point to old visibility map page. old_cur @@ -203,8 +244,8 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, * old block. old_break is the end+1 position on the old page for the * data that will be transferred to the current new page. */ - old_cur = buffer + SizeOfPageHeaderData; - old_blkend = buffer + bytesRead; + old_cur = buffer.data + SizeOfPageHeaderData; + old_blkend = buffer.data + bytesRead; old_break = old_cur + rewriteVmBytesPerPage; while (old_break <= old_blkend) @@ -214,12 +255,12 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, bool old_lastpart; /* First, copy old page header to new page */ - memcpy(new_vmbuf, &pageheader, SizeOfPageHeaderData); + memcpy(new_vmbuf.data, &pageheader, SizeOfPageHeaderData); /* Rewriting the last part of the last old page? */ old_lastpart = old_lastblk && (old_break == old_blkend); - new_cur = new_vmbuf + SizeOfPageHeaderData; + new_cur = new_vmbuf.data + SizeOfPageHeaderData; /* Process old page bytes one by one, and turn it into new page. */ while (old_cur < old_break) @@ -253,11 +294,11 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, /* Set new checksum for visibility map page, if enabled */ if (new_cluster.controldata.data_checksum_version != 0) - ((PageHeader) new_vmbuf)->pd_checksum = - pg_checksum_page(new_vmbuf, new_blkno); + ((PageHeader) new_vmbuf.data)->pd_checksum = + pg_checksum_page(new_vmbuf.data, new_blkno); errno = 0; - if (write(dst_fd, new_vmbuf, BLCKSZ) != BLCKSZ) + if (write(dst_fd, new_vmbuf.data, BLCKSZ) != BLCKSZ) { /* if write didn't set errno, assume problem is no disk space */ if (errno == 0) @@ -273,12 +314,52 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile, } /* Clean up */ - pg_free(buffer); - pg_free(new_vmbuf); close(dst_fd); close(src_fd); } +void +check_file_clone(void) +{ + char existing_file[MAXPGPATH]; + char new_link_file[MAXPGPATH]; + + snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata); + snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.clonetest", new_cluster.pgdata); + unlink(new_link_file); /* might fail */ + +#if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE) + if (copyfile(existing_file, new_link_file, NULL, COPYFILE_CLONE_FORCE) < 0) + pg_fatal("could not clone file between old and new data directories: %s\n", + strerror(errno)); +#elif defined(__linux__) && defined(FICLONE) + { + int src_fd; + int dest_fd; + + if ((src_fd = open(existing_file, O_RDONLY | PG_BINARY, 0)) < 0) + pg_fatal("could not open file \"%s\": %s\n", + existing_file, strerror(errno)); + + if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, + pg_file_create_mode)) < 0) + pg_fatal("could not create file \"%s\": %s\n", + new_link_file, strerror(errno)); + + if (ioctl(dest_fd, FICLONE, src_fd) < 0) + pg_fatal("could not clone file between old and new data directories: %s\n", + strerror(errno)); + + close(src_fd); + close(dest_fd); + } +#else + pg_fatal("file cloning not supported on this platform\n"); +#endif + + unlink(new_link_file); +} + void check_hard_link(void) { diff --git a/src/bin/pg_upgrade/function.c b/src/bin/pg_upgrade/function.c index 03fd155dcda..0c66d1c0566 100644 --- a/src/bin/pg_upgrade/function.c +++ b/src/bin/pg_upgrade/function.c @@ -3,7 +3,7 @@ * * server-side function support * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/function.c */ @@ -18,24 +18,30 @@ /* * qsort comparator for pointers to library names * - * We sort first by name length, then alphabetically for names of the same - * length. This is to ensure that, eg, "hstore_plpython" sorts after both - * "hstore" and "plpython"; otherwise transform modules will probably fail - * their LOAD tests. (The backend ought to cope with that consideration, - * but it doesn't yet, and even when it does it'll still be a good idea - * to have a predictable order of probing here.) + * We sort first by name length, then alphabetically for names of the + * same length, then database array index. This is to ensure that, eg, + * "hstore_plpython" sorts after both "hstore" and "plpython"; otherwise + * transform modules will probably fail their LOAD tests. (The backend + * ought to cope with that consideration, but it doesn't yet, and even + * when it does it'll still be a good idea to have a predictable order of + * probing here.) */ static int library_name_compare(const void *p1, const void *p2) { - const char *str1 = *(const char *const *) p1; - const char *str2 = *(const char *const *) p2; + const char *str1 = ((const LibraryInfo *) p1)->name; + const char *str2 = ((const LibraryInfo *) p2)->name; int slen1 = strlen(str1); int slen2 = strlen(str2); + int cmp = strcmp(str1, str2); if (slen1 != slen2) return slen1 - slen2; - return strcmp(str1, str2); + if (cmp != 0) + return cmp; + else + return ((const LibraryInfo *) p1)->dbnum - + ((const LibraryInfo *) p2)->dbnum; } @@ -137,18 +143,7 @@ get_loadable_libraries(void) if (found_public_plpython_handler) pg_fatal("Remove the problem functions from the old cluster to continue.\n"); - /* - * Now we want to remove duplicates across DBs and sort the library names - * into order. This avoids multiple probes of the same library, and - * ensures that libraries are probed in a consistent order, which is - * important for reproducible behavior if one library depends on another. - * - * First transfer all the names into one array, then sort, then remove - * duplicates. Note: we strdup each name in the first loop so that we can - * safely clear the PGresults in the same loop. This is a bit wasteful - * but it's unlikely there are enough names to matter. - */ - os_info.libraries = (char **) pg_malloc(totaltups * sizeof(char *)); + os_info.libraries = (LibraryInfo *) pg_malloc(totaltups * sizeof(LibraryInfo)); totaltups = 0; for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++) @@ -162,32 +157,16 @@ get_loadable_libraries(void) { char *lib = PQgetvalue(res, rowno, 0); - os_info.libraries[totaltups++] = pg_strdup(lib); + os_info.libraries[totaltups].name = pg_strdup(lib); + os_info.libraries[totaltups].dbnum = dbnum; + + totaltups++; } PQclear(res); } pg_free(ress); - if (totaltups > 1) - { - int i, - lastnondup; - - qsort((void *) os_info.libraries, totaltups, sizeof(char *), - library_name_compare); - - for (i = 1, lastnondup = 0; i < totaltups; i++) - { - if (strcmp(os_info.libraries[i], - os_info.libraries[lastnondup]) != 0) - os_info.libraries[++lastnondup] = os_info.libraries[i]; - else - pg_free(os_info.libraries[i]); - } - totaltups = lastnondup + 1; - } - os_info.num_libraries = totaltups; } @@ -204,6 +183,7 @@ check_loadable_libraries(void) { PGconn *conn = connectToServer(&new_cluster, "template1"); int libnum; + int was_load_failure = false; FILE *script = NULL; bool found = false; char output_path[MAXPGPATH]; @@ -212,52 +192,72 @@ check_loadable_libraries(void) snprintf(output_path, sizeof(output_path), "loadable_libraries.txt"); + /* + * Now we want to sort the library names into order. This avoids multiple + * probes of the same library, and ensures that libraries are probed in a + * consistent order, which is important for reproducible behavior if one + * library depends on another. + */ + qsort((void *) os_info.libraries, os_info.num_libraries, + sizeof(LibraryInfo), library_name_compare); + for (libnum = 0; libnum < os_info.num_libraries; libnum++) { - char *lib = os_info.libraries[libnum]; + char *lib = os_info.libraries[libnum].name; int llen = strlen(lib); char cmd[7 + 2 * MAXPGPATH + 1]; PGresult *res; - /* - * In Postgres 9.0, Python 3 support was added, and to do that, a - * plpython2u language was created with library name plpython2.so as a - * symbolic link to plpython.so. In Postgres 9.1, only the - * plpython2.so library was created, and both plpythonu and plpython2u - * pointing to it. For this reason, any reference to library name - * "plpython" in an old PG <= 9.1 cluster must look for "plpython2" in - * the new cluster. - * - * For this case, we could check pg_pltemplate, but that only works - * for languages, and does not help with function shared objects, so - * we just do a general fix. - */ - if (GET_MAJOR_VERSION(old_cluster.major_version) < 901 && - strcmp(lib, "$libdir/plpython") == 0) + /* Did the library name change? Probe it. */ + if (libnum == 0 || strcmp(lib, os_info.libraries[libnum - 1].name) != 0) { - lib = "$libdir/plpython2"; - llen = strlen(lib); - } + /* + * In Postgres 9.0, Python 3 support was added, and to do that, a + * plpython2u language was created with library name plpython2.so + * as a symbolic link to plpython.so. In Postgres 9.1, only the + * plpython2.so library was created, and both plpythonu and + * plpython2u pointing to it. For this reason, any reference to + * library name "plpython" in an old PG <= 9.1 cluster must look + * for "plpython2" in the new cluster. + * + * For this case, we could check pg_pltemplate, but that only + * works for languages, and does not help with function shared + * objects, so we just do a general fix. + */ + if (GET_MAJOR_VERSION(old_cluster.major_version) < 901 && + strcmp(lib, "$libdir/plpython") == 0) + { + lib = "$libdir/plpython2"; + llen = strlen(lib); + } - strcpy(cmd, "LOAD '"); - PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL); - strcat(cmd, "'"); + strcpy(cmd, "LOAD '"); + PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL); + strcat(cmd, "'"); - res = PQexec(conn, cmd); + res = PQexec(conn, cmd); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - found = true; - - if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) - pg_fatal("could not open file \"%s\": %s\n", - output_path, strerror(errno)); - fprintf(script, _("could not load library \"%s\": %s"), - lib, - PQerrorMessage(conn)); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + found = true; + was_load_failure = true; + + if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %s\n", + output_path, strerror(errno)); + fprintf(script, _("could not load library \"%s\": %s"), + lib, + PQerrorMessage(conn)); + } + else + was_load_failure = false; + + PQclear(res); } - PQclear(res); + if (was_load_failure) + fprintf(script, _("Database: %s\n"), + old_cluster.dbarr.dbs[os_info.libraries[libnum].dbnum].db_name); } PQfinish(conn); diff --git a/src/bin/pg_upgrade/info.c b/src/bin/pg_upgrade/info.c index fd0b44c3ce9..5c7b4337ba4 100644 --- a/src/bin/pg_upgrade/info.c +++ b/src/bin/pg_upgrade/info.c @@ -3,7 +3,7 @@ * * information support functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/info.c */ @@ -16,11 +16,11 @@ static void create_rel_filename_map(const char *old_data, const char *new_data, - const DbInfo *old_db, const DbInfo *new_db, - const RelInfo *old_rel, const RelInfo *new_rel, - FileNameMap *map); + const DbInfo *old_db, const DbInfo *new_db, + const RelInfo *old_rel, const RelInfo *new_rel, + FileNameMap *map); static void report_unmatched_relation(const RelInfo *rel, const DbInfo *db, - bool is_new_db); + bool is_new_db); static void free_db_and_rel_infos(DbInfoArr *db_arr); static void get_db_infos(ClusterInfo *cluster); static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo); @@ -441,8 +441,7 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) * * pg_largeobject contains user data that does not appear in pg_dump * output, so we have to copy that system table. It's easiest to do that - * by treating it as a user table. Likewise for pg_largeobject_metadata, - * if it exists. + * by treating it as a user table. */ snprintf(query + strlen(query), sizeof(query) - strlen(query), "WITH regular_heap (reloid, indtable, toastheap) AS ( " @@ -458,10 +457,8 @@ get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo) " 'binary_upgrade', 'pg_toast') AND " " c.oid >= %u::pg_catalog.oid) OR " " (n.nspname = 'pg_catalog' AND " - " relname IN ('pg_largeobject'%s) ))), ", - FirstNormalObjectId, - (GET_MAJOR_VERSION(old_cluster.major_version) >= 900) ? - ", 'pg_largeobject_metadata'" : ""); + " relname IN ('pg_largeobject') ))), ", + FirstNormalObjectId); /* * Add a CTE that collects OIDs of toast tables belonging to the tables diff --git a/src/bin/pg_upgrade/nls.mk b/src/bin/pg_upgrade/nls.mk index 33b0208a61d..ad6d2e25230 100644 --- a/src/bin/pg_upgrade/nls.mk +++ b/src/bin/pg_upgrade/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_upgrade/nls.mk CATALOG_NAME = pg_upgrade -AVAIL_LANGUAGES =fr ru +AVAIL_LANGUAGES =cs de es fr ja ko ru sv tr GETTEXT_FILES = check.c controldata.c dump.c exec.c file.c function.c \ info.c option.c parallel.c pg_upgrade.c relfilenode.c \ server.c tablespace.c util.c version.c diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 9dbc9225a64..28ff4c48ed3 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -1,9 +1,9 @@ /* - * opt.c + * option.c * * options functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/option.c */ @@ -15,14 +15,17 @@ #endif #include "getopt_long.h" +#include "common/string.h" #include "utils/pidfile.h" #include "pg_upgrade.h" static void usage(void); -static void check_required_directory(char **dirpath, char **configpath, - const char *envVarName, const char *cmdLineOption, const char *description); +static void check_required_directory(char **dirpath, + const char *envVarName, bool useCwd, + const char *cmdLineOption, const char *description, + bool missingOk); #define FIX_DEFAULT_READ_ONLY "-c default_transaction_read_only=false" @@ -52,7 +55,10 @@ parseCommandLine(int argc, char *argv[]) {"link", no_argument, NULL, 'k'}, {"retain", no_argument, NULL, 'r'}, {"jobs", required_argument, NULL, 'j'}, + {"socketdir", required_argument, NULL, 's'}, {"verbose", no_argument, NULL, 'v'}, + {"clone", no_argument, NULL, 1}, + {NULL, 0, NULL, 0} }; int option; /* Command line option */ @@ -97,10 +103,7 @@ parseCommandLine(int argc, char *argv[]) if (os_user_effective_id == 0) pg_fatal("%s: cannot be run as root\n", os_info.progname); - if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL) - pg_fatal("could not write to log file \"%s\"\n", INTERNAL_LOG_FILE); - - while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v", + while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rs:U:v", long_options, &optindex)) != -1) { switch (option) @@ -119,12 +122,10 @@ parseCommandLine(int argc, char *argv[]) case 'd': old_cluster.pgdata = pg_strdup(optarg); - old_cluster.pgconfig = pg_strdup(optarg); break; case 'D': new_cluster.pgdata = pg_strdup(optarg); - new_cluster.pgconfig = pg_strdup(optarg); break; case 'j': @@ -186,6 +187,10 @@ parseCommandLine(int argc, char *argv[]) log_opts.retain = true; break; + case 's': + user_opts.socketdir = pg_strdup(optarg); + break; + case 'U': pg_free(os_info.user); os_info.user = pg_strdup(optarg); @@ -199,22 +204,34 @@ parseCommandLine(int argc, char *argv[]) break; case 'v': - pg_log(PG_REPORT, "Running in verbose mode\n"); log_opts.verbose = true; break; - default: - pg_fatal("Try \"%s --help\" for more information.\n", - os_info.progname); + case 1: + user_opts.transfer_mode = TRANSFER_MODE_CLONE; break; + + default: + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), + os_info.progname); + exit(1); } } + if (optind < argc) + pg_fatal("too many command-line arguments (first is \"%s\")\n", argv[optind]); + + if ((log_opts.internal = fopen_priv(INTERNAL_LOG_FILE, "a")) == NULL) + pg_fatal("could not open log file \"%s\": %m\n", INTERNAL_LOG_FILE); + + if (log_opts.verbose) + pg_log(PG_REPORT, "Running in verbose mode\n"); + /* label start of upgrade in logfiles */ for (filename = output_files; *filename != NULL; filename++) { if ((fp = fopen_priv(*filename, "a")) == NULL) - pg_fatal("could not write to log file \"%s\"\n", *filename); + pg_fatal("could not write to log file \"%s\": %m\n", *filename); /* Start with newline because we might be appending to a file. */ fprintf(fp, "\n" @@ -238,14 +255,16 @@ parseCommandLine(int argc, char *argv[]) pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY); /* Get values from env if not already set */ - check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b", - _("old cluster binaries reside")); - check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B", - _("new cluster binaries reside")); - check_required_directory(&old_cluster.pgdata, &old_cluster.pgconfig, - "PGDATAOLD", "-d", _("old cluster data resides")); - check_required_directory(&new_cluster.pgdata, &new_cluster.pgconfig, - "PGDATANEW", "-D", _("new cluster data resides")); + check_required_directory(&old_cluster.bindir, "PGBINOLD", false, + "-b", _("old cluster binaries reside"), false); + check_required_directory(&new_cluster.bindir, "PGBINNEW", false, + "-B", _("new cluster binaries reside"), true); + check_required_directory(&old_cluster.pgdata, "PGDATAOLD", false, + "-d", _("old cluster data resides"), false); + check_required_directory(&new_cluster.pgdata, "PGDATANEW", false, + "-D", _("new cluster data resides"), false); + check_required_directory(&user_opts.socketdir, "PGSOCKETDIR", true, + "-s", _("sockets will be created"), false); #ifdef WIN32 @@ -279,7 +298,8 @@ usage(void) printf(_(" pg_upgrade [OPTION]...\n\n")); printf(_("Options:\n")); printf(_(" -b, --old-bindir=BINDIR old cluster executable directory\n")); - printf(_(" -B, --new-bindir=BINDIR new cluster executable directory\n")); + printf(_(" -B, --new-bindir=BINDIR new cluster executable directory (default\n" + " same directory as pg_upgrade)\n")); printf(_(" -c, --check check clusters only, don't change any data\n")); printf(_(" -d, --old-datadir=DATADIR old cluster data directory\n")); printf(_(" -D, --new-datadir=DATADIR new cluster data directory\n")); @@ -290,9 +310,11 @@ usage(void) printf(_(" -p, --old-port=PORT old cluster port number (default %d)\n"), old_cluster.port); printf(_(" -P, --new-port=PORT new cluster port number (default %d)\n"), new_cluster.port); printf(_(" -r, --retain retain SQL and log files after success\n")); + printf(_(" -s, --socketdir=DIR socket directory to use (default current dir.)\n")); printf(_(" -U, --username=NAME cluster superuser (default \"%s\")\n"), os_info.user); printf(_(" -v, --verbose enable verbose internal logging\n")); printf(_(" -V, --version display version information, then exit\n")); + printf(_(" --clone clone instead of copying files to new cluster\n")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\n" "Before running pg_upgrade you must:\n" @@ -322,7 +344,7 @@ usage(void) " C:\\> set PGBINNEW=newCluster/bin\n" " C:\\> pg_upgrade\n")); #endif - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } @@ -330,30 +352,37 @@ usage(void) * check_required_directory() * * Checks a directory option. - * dirpath - the directory name supplied on the command line - * configpath - optional configuration directory + * dirpath - the directory name supplied on the command line, or NULL * envVarName - the name of an environment variable to get if dirpath is NULL - * cmdLineOption - the command line option corresponds to this directory (-o, -O, -n, -N) + * useCwd - true if OK to default to CWD + * cmdLineOption - the command line option for this directory * description - a description of this directory option + * missingOk - true if OK that both dirpath and envVarName are not existing * * We use the last two arguments to construct a meaningful error message if the * user hasn't provided the required directory name. */ static void -check_required_directory(char **dirpath, char **configpath, - const char *envVarName, const char *cmdLineOption, - const char *description) +check_required_directory(char **dirpath, const char *envVarName, bool useCwd, + const char *cmdLineOption, const char *description, + bool missingOk) { if (*dirpath == NULL || strlen(*dirpath) == 0) { const char *envVar; if ((envVar = getenv(envVarName)) && strlen(envVar)) - { *dirpath = pg_strdup(envVar); - if (configpath) - *configpath = pg_strdup(envVar); + else if (useCwd) + { + char cwd[MAXPGPATH]; + + if (!getcwd(cwd, MAXPGPATH)) + pg_fatal("could not determine current directory\n"); + *dirpath = pg_strdup(cwd); } + else if (missingOk) + return; else pg_fatal("You must identify the directory where the %s.\n" "Please use the %s command-line option or the %s environment variable.\n", @@ -361,16 +390,10 @@ check_required_directory(char **dirpath, char **configpath, } /* - * Trim off any trailing path separators because we construct paths by - * appending to this path. + * Clean up the path, in particular trimming any trailing path separators, + * because we construct paths by appending to this path. */ -#ifndef WIN32 - if ((*dirpath)[strlen(*dirpath) - 1] == '/') -#else - if ((*dirpath)[strlen(*dirpath) - 1] == '/' || - (*dirpath)[strlen(*dirpath) - 1] == '\\') -#endif - (*dirpath)[strlen(*dirpath) - 1] = 0; + canonicalize_path(*dirpath); } /* @@ -379,6 +402,10 @@ check_required_directory(char **dirpath, char **configpath, * If a configuration-only directory was specified, find the real data dir * by querying the running server. This has limited checking because we * can't check for a running server because we can't find postmaster.pid. + * + * On entry, cluster->pgdata has been set from command line or env variable, + * but cluster->pgconfig isn't set. We fill both variables with corrected + * values. */ void adjust_data_dir(ClusterInfo *cluster) @@ -389,6 +416,9 @@ adjust_data_dir(ClusterInfo *cluster) FILE *fp, *output; + /* Initially assume config dir and data dir are the same */ + cluster->pgconfig = pg_strdup(cluster->pgdata); + /* If there is no postgresql.conf, it can't be a config-only dir */ snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig); if ((fp = fopen(filename, "r")) == NULL) @@ -425,9 +455,8 @@ adjust_data_dir(ClusterInfo *cluster) pclose(output); - /* Remove trailing newline */ - if (strchr(cmd_output, '\n') != NULL) - *strchr(cmd_output, '\n') = '\0'; + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(cmd_output); cluster->pgdata = pg_strdup(cmd_output); @@ -455,12 +484,7 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) if (GET_MAJOR_VERSION(cluster->major_version) >= 901) { if (!live_check) - { - /* Use the current directory for the socket */ - cluster->sockdir = pg_malloc(MAXPGPATH); - if (!getcwd(cluster->sockdir, MAXPGPATH)) - pg_fatal("could not determine current directory\n"); - } + cluster->sockdir = user_opts.socketdir; else { /* @@ -493,10 +517,9 @@ get_sock_dir(ClusterInfo *cluster, bool live_check) sscanf(line, "%hu", &old_cluster.port); if (lineno == LOCK_FILE_LINE_SOCKET_DIR) { + /* strip trailing newline and carriage return */ cluster->sockdir = pg_strdup(line); - /* strip off newline */ - if (strchr(cluster->sockdir, '\n') != NULL) - *strchr(cluster->sockdir, '\n') = '\0'; + (void) pg_strip_crlf(cluster->sockdir); } } fclose(fp); diff --git a/src/bin/pg_upgrade/parallel.c b/src/bin/pg_upgrade/parallel.c index 23f869f6c7b..80ab1b86093 100644 --- a/src/bin/pg_upgrade/parallel.c +++ b/src/bin/pg_upgrade/parallel.c @@ -3,7 +3,7 @@ * * multi-process support * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/parallel.c */ @@ -290,7 +290,7 @@ reap_child(bool wait_for_child) { #ifndef WIN32 int work_status; - int ret; + pid_t child; #else int thread_num; DWORD res; @@ -300,14 +300,13 @@ reap_child(bool wait_for_child) return false; #ifndef WIN32 - ret = waitpid(-1, &work_status, wait_for_child ? 0 : WNOHANG); - - /* no children or, for WNOHANG, no dead children */ - if (ret <= 0 || !WIFEXITED(work_status)) - return false; - - if (WEXITSTATUS(work_status) != 0) - pg_fatal("child worker exited abnormally: %s\n", strerror(errno)); + child = waitpid(-1, &work_status, wait_for_child ? 0 : WNOHANG); + if (child == (pid_t) -1) + pg_fatal("waitpid() failed: %s\n", strerror(errno)); + if (child == 0) + return false; /* no children, or no dead children */ + if (work_status != 0) + pg_fatal("child process exited abnormally: status %d\n", work_status); #else /* wait for one to finish */ thread_num = WaitForMultipleObjects(parallel_jobs, thread_handles, diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 9b2d37f9171..5e617e97c0f 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -3,7 +3,7 @@ * * main source file * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/pg_upgrade.c */ @@ -28,8 +28,9 @@ * We control all assignments of pg_enum.oid because these oids are stored * in user tables as enum values. * - * We control all assignments of pg_authid.oid because these oids are stored - * in pg_largeobject_metadata. + * We control all assignments of pg_authid.oid for historical reasons (the + * oids used to be stored in pg_largeobject_metadata, which is now copied via + * SQL commands), that might change at some point in the future. */ @@ -39,6 +40,7 @@ #include "pg_upgrade.h" #include "catalog/pg_class_d.h" #include "common/file_perm.h" +#include "common/logging.h" #include "common/restricted_token.h" #include "fe_utils/string_utils.h" @@ -77,6 +79,7 @@ main(int argc, char **argv) char *deletion_script_file_name = NULL; bool live_check = false; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_upgrade")); /* Set default restrictive mask until new cluster permissions are read */ @@ -84,7 +87,7 @@ main(int argc, char **argv) parseCommandLine(argc, argv); - get_restricted_token(os_info.progname); + get_restricted_token(); adjust_data_dir(&old_cluster); adjust_data_dir(&new_cluster); @@ -103,8 +106,8 @@ main(int argc, char **argv) /* Set mask based on PGDATA permissions */ if (!GetDataDirectoryCreatePerm(new_cluster.pgdata)) { - pg_log(PG_FATAL, "unable to read permissions from \"%s\"\n", - new_cluster.pgdata); + pg_log(PG_FATAL, "could not read permissions of directory \"%s\": %s\n", + new_cluster.pgdata, strerror(errno)); exit(1); } @@ -201,14 +204,29 @@ main(int argc, char **argv) static void setup(char *argv0, bool *live_check) { - char exec_path[MAXPGPATH]; /* full path to my executable */ - /* * make sure the user has a clean environment, otherwise, we may confuse * libpq when we connect to one (or both) of the servers. */ check_pghost_envvar(); + /* + * In case the user hasn't specified the directory for the new binaries + * with -B, default to using the path of the currently executed pg_upgrade + * binary. + */ + if (!new_cluster.bindir) + { + char exec_path[MAXPGPATH]; + + if (find_my_exec(argv0, exec_path) < 0) + pg_fatal("%s: could not find own program executable\n", argv0); + /* Trim off program name and keep just path */ + *last_dir_separator(exec_path) = '\0'; + canonicalize_path(exec_path); + new_cluster.bindir = pg_strdup(exec_path); + } + verify_directories(); /* no postmasters should be running, except for a live check */ @@ -220,7 +238,8 @@ setup(char *argv0, bool *live_check) * start, assume the server is running. If the pid file is left over * from a server crash, this also allows any committed transactions * stored in the WAL to be replayed so they are not lost, because WAL - * files are not transferred from old to new servers. + * files are not transferred from old to new servers. We later check + * for a clean shutdown. */ if (start_postmaster(&old_cluster, false)) stop_postmaster(false); @@ -243,15 +262,6 @@ setup(char *argv0, bool *live_check) pg_fatal("There seems to be a postmaster servicing the new cluster.\n" "Please shutdown that postmaster and try again.\n"); } - - /* get path to pg_upgrade executable */ - if (find_my_exec(argv0, exec_path) < 0) - pg_fatal("%s: could not find own program executable\n", argv0); - - /* Trim off program name and keep just path */ - *last_dir_separator(exec_path) = '\0'; - canonicalize_path(exec_path); - os_info.exec_path = pg_strdup(exec_path); } @@ -260,7 +270,7 @@ prepare_new_cluster(void) { /* * It would make more sense to freeze after loading the schema, but that - * would cause us to lose the frozenids restored by the load. We use + * would cause us to lose the frozenxids restored by the load. We use * --analyze so autovacuum doesn't update statistics later */ prep_status("Analyzing all rows in the new cluster"); diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index 7e5e9712947..f724ecf9cad 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -1,7 +1,7 @@ /* * pg_upgrade.h * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/pg_upgrade.h */ @@ -15,15 +15,9 @@ /* Use port in the private/dynamic port number range */ #define DEF_PGUPORT 50432 -/* Allocate for null byte */ -#define USER_NAME_SIZE 128 - #define MAX_STRING 1024 -#define LINE_ALLOC 4096 #define QUERY_ALLOC 8192 -#define MIGRATOR_API_VERSION 1 - #define MESSAGE_WIDTH 60 #define GET_MAJOR_VERSION(v) ((v) / 100) @@ -141,7 +135,7 @@ typedef struct char *nspname; /* namespace name */ char *relname; /* relation name */ Oid reloid; /* relation OID */ - Oid relfilenode; /* relation relfile node */ + Oid relfilenode; /* relation file node */ Oid indtable; /* if index, OID of its table, else 0 */ Oid toastheap; /* if toast table, OID of base table, else 0 */ char *tablespace; /* tablespace path; "" for cluster default */ @@ -230,10 +224,11 @@ typedef struct } ControlData; /* - * Enumeration to denote link modes + * Enumeration to denote transfer modes */ typedef enum { + TRANSFER_MODE_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK } transferMode; @@ -297,9 +292,15 @@ typedef struct bool check; /* true -> ask user for permission to make * changes */ transferMode transfer_mode; /* copy files or link them? */ - int jobs; + int jobs; /* number of processes/threads to use */ + char *socketdir; /* directory to use for Unix sockets */ } UserOpts; +typedef struct +{ + char *name; + int dbnum; +} LibraryInfo; /* * OSInfo @@ -307,12 +308,11 @@ typedef struct typedef struct { const char *progname; /* complete pathname for this program */ - char *exec_path; /* full path to my executable */ char *user; /* username for clusters */ bool user_specified; /* user specified on command-line */ char **old_tablespaces; /* tablespaces */ int num_old_tablespaces; - char **libraries; /* loadable libraries */ + LibraryInfo *libraries; /* loadable libraries */ int num_libraries; ClusterInfo *running_cluster; } OSInfo; @@ -335,8 +335,8 @@ void check_and_dump_old_cluster(bool live_check); void check_new_cluster(void); void report_clusters_compatible(void); void issue_warnings_and_set_wal_level(void); -void output_completion_banner(char *analyze_script_file_name, - char *deletion_script_file_name); +void output_completion_banner(char *analyze_script_file_name, + char *deletion_script_file_name); void check_cluster_versions(void); void check_cluster_compatibility(bool live_check); void create_script_for_old_cluster_deletion(char **deletion_script_file_name); @@ -359,20 +359,23 @@ void generate_old_dump(void); #define EXEC_PSQL_ARGS "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1" -bool exec_prog(const char *log_file, const char *opt_log_file, - bool report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5, 6); +bool exec_prog(const char *log_file, const char *opt_log_file, + bool report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5, 6); void verify_directories(void); bool pid_lock_file_exists(const char *datadir); /* file.c */ -void copyFile(const char *src, const char *dst, - const char *schemaName, const char *relName); -void linkFile(const char *src, const char *dst, - const char *schemaName, const char *relName); -void rewriteVisibilityMap(const char *fromfile, const char *tofile, +void cloneFile(const char *src, const char *dst, + const char *schemaName, const char *relName); +void copyFile(const char *src, const char *dst, + const char *schemaName, const char *relName); +void linkFile(const char *src, const char *dst, const char *schemaName, const char *relName); +void rewriteVisibilityMap(const char *fromfile, const char *tofile, + const char *schemaName, const char *relName); +void check_file_clone(void); void check_hard_link(void); /* fopen_priv() is no longer different from fopen() */ @@ -386,11 +389,11 @@ void check_loadable_libraries(void); /* info.c */ FileNameMap *gen_db_file_maps(DbInfo *old_db, - DbInfo *new_db, int *nmaps, const char *old_pgdata, - const char *new_pgdata); + DbInfo *new_db, int *nmaps, const char *old_pgdata, + const char *new_pgdata); void get_db_and_rel_infos(ClusterInfo *cluster); -void print_maps(FileNameMap *maps, int n, - const char *db_name); +void print_maps(FileNameMap *maps, int n, + const char *db_name); /* option.c */ @@ -400,11 +403,11 @@ void get_sock_dir(ClusterInfo *cluster, bool live_check); /* relfilenode.c */ -void transfer_all_new_tablespaces(DbInfoArr *old_db_arr, - DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata); -void transfer_all_new_dbs(DbInfoArr *old_db_arr, - DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, - char *old_tablespace); +void transfer_all_new_tablespaces(DbInfoArr *old_db_arr, + DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata); +void transfer_all_new_dbs(DbInfoArr *old_db_arr, + DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, + char *old_tablespace); /* tablespace.c */ @@ -441,17 +444,17 @@ void pg_putenv(const char *var, const char *val); /* version.c */ -void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, - bool check_mode); +void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, + bool check_mode); void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster); void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster); -void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, - bool check_mode); +void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, + bool check_mode); /* parallel.c */ -void parallel_exec_prog(const char *log_file, const char *opt_log_file, - const char *fmt,...) pg_attribute_printf(3, 4); -void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, - char *old_pgdata, char *new_pgdata, - char *old_tablespace); +void parallel_exec_prog(const char *log_file, const char *opt_log_file, + const char *fmt,...) pg_attribute_printf(3, 4); +void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, + char *old_pgdata, char *new_pgdata, + char *old_tablespace); bool reap_child(bool wait_for_child); diff --git a/src/bin/pg_upgrade/po/cs.po b/src/bin/pg_upgrade/po/cs.po new file mode 100644 index 00000000000..9beb79ebc9d --- /dev/null +++ b/src/bin/pg_upgrade/po/cs.po @@ -0,0 +1,1758 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_upgrade (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-07-13 19:46+0000\n" +"PO-Revision-Date: 2018-07-13 23:50+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.7\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Provádím Kontrolu Konzistence na Starém Live Serveru\n" +"----------------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Provádím Kontrolu Konzistence\n" +"-----------------------------\n" + +#: check.c:166 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Clustery jsou kompatibilní*\n" + +#: check.c:172 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Pokud pg_upgrade selže po tomto místÄ›, musíte reinicializovat\n" +"(initdb) nový cluster než budete pokraÄovat.\n" + +#: check.c:208 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Statistiky optimalizéru nejsou zachovány pÅ™i pg_upgrade,\n" +"takže po nastartování nového serveru zvažte spuÅ¡tÄ›ní:\n" +" %s\n" +"\n" + +#: check.c:213 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Statistiky optimalizéru a informace o volném místÄ› nejsou zachovány\n" +"pÅ™i pg_upgrade, takže po nastartování nového serveru zvažte spuÅ¡tÄ›ní:\n" +" %s\n" +"\n" + +#: check.c:220 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"SpuÅ¡tÄ›ní tohoto skriptu smaže datové soubory starého clusteru:\n" +" %s\n" + +#: check.c:225 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Nelze vytvoÅ™it skript pro smazání datových souborů starého cluster\n" +"protože uživatelem definované tablespaces nebo datový adresář nového\n" +"clusteru jsou v adresáři starého clusteru. Obsah starého clusteru musí\n" +"být smazán manuálnÄ›.\n" + +#: check.c:235 +#, c-format +msgid "Checking cluster versions" +msgstr "Kontroluji verze clusterů" + +#: check.c:247 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "" +"Tato utilita může upgradovat pouze z PostgreSQL verze 8.4 a novÄ›jších.\n" + +#: check.c:251 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Tato utilita může upgradovat pouze na PostgreSQL verze %s.\n" + +#: check.c:260 +#, c-format +msgid "" +"This utility cannot be used to downgrade to older major PostgreSQL " +"versions.\n" +msgstr "" +"Tato utilita nemůže být použita pro downgrade na starší major PostgreSQL " +"verze.\n" + +#: check.c:265 +#, c-format +msgid "" +"Old cluster data and binary directories are from different major versions.\n" +msgstr "Data a binární adresáře starého clusteru jsou z jiných major verzí.\n" + +#: check.c:268 +#, c-format +msgid "" +"New cluster data and binary directories are from different major versions.\n" +msgstr "" +"Data a binární adresáře nového clusteru jsou z různých minárních verzí.\n" + +#: check.c:285 +#, c-format +msgid "" +"When checking a pre-PG 9.1 live old server, you must specify the old " +"server's port number.\n" +msgstr "" +"PÅ™i kontrole pre-PG 9.1 živého starého serveru, musíte zadat Äíslo portu " +"starého serveru.\n" + +#: check.c:289 +#, c-format +msgid "" +"When checking a live server, the old and new port numbers must be " +"different.\n" +msgstr "" +"PÅ™i kontrole živého serveru, staré a nové Äíslo portu musí být různá.\n" + +#: check.c:304 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "kódování databáze \"%s\" neodpovídají: stará \"%s\", nová \"%s\"\n" + +#: check.c:309 +#, c-format +msgid "" +"lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"lc_collate hodnoty pro databázi \"%s\" neodpovídají: stará \"%s\", nová \"%s" +"\"\n" + +#: check.c:312 +#, c-format +msgid "" +"lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"lc_ctype hodnoty pro databázi \"%s\" neodpovídají: stará \"%s\", nová \"%s" +"\"\n" + +#: check.c:385 +#, c-format +msgid "New cluster database \"%s\" is not empty\n" +msgstr "Databáze \"%s\" na novém clusteru není prázdná\n" + +#: check.c:432 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Vytvářím skript pro analyze nového clusteru" + +#: check.c:446 check.c:574 check.c:838 check.c:941 check.c:1032 function.c:253 +#: option.c:480 version.c:57 version.c:156 version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "nelze otevřít soubor \"%s\": %s\n" + +#: check.c:501 check.c:630 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "nelze pÅ™idat právo na spuÅ¡tÄ›ní pro soubor \"%s\": %s\n" + +#: check.c:537 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e." +"g. %s\n" +msgstr "" +"\n" +"VAROVÃNÃ: nový datový adresář by nemÄ›l být ve starém datovém adresáři, e.g. " +"%s\n" + +#: check.c:561 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data " +"directory, e.g. %s\n" +msgstr "" +"\n" +"VAROVÃNÃ: umístÄ›ní uživatelem definovaných tablespaces by nemÄ›ly být v " +"datovém adresáři, e.g. %s\n" + +#: check.c:571 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Vytvářím skript pro smazání starého clusteru" + +#: check.c:650 +#, c-format +msgid "Checking database user is the install user" +msgstr "Kontroluji že databázový uživatel je použit pro instalaci" + +#: check.c:666 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "databázový uživatel \"%s\" nebyl použit pro instalaci\n" + +#: check.c:677 +#, c-format +msgid "could not determine the number of users\n" +msgstr "nelže urÄit poÄet uživatelů\n" + +#: check.c:685 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Pouze instalaÄní uživatel může být definován pro nový cluster.\n" + +#: check.c:705 +#, c-format +msgid "Checking database connection settings" +msgstr "Kontroluji nastavení databázového spojení" + +#: check.c:727 +#, c-format +msgid "" +"template0 must not allow connections, i.e. its pg_database.datallowconn must " +"be false\n" +msgstr "" +"template0 nesmí povolovat spojení, i.e. přísluÅ¡ná hodnota pg_database." +"datallowconn musí být false\n" + +#: check.c:737 +#, c-format +msgid "" +"All non-template0 databases must allow connections, i.e. their pg_database." +"datallowconn must be true\n" +msgstr "" +"VÅ¡echny non-template0 databáze musí povolovat spojení, i.e. jejich " +"pg_database.datallowconn musí být true\n" + +#: check.c:762 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Kontroluji prepared transakce" + +#: check.c:771 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Zdrojový cluster obsahuje prepared transakce\n" + +#: check.c:773 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Cílový cluster obsahuje prepared transakce\n" + +#: check.c:799 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Kontroluji contrib/isn s bigint-passing rozdílem" + +#: check.c:860 check.c:964 check.c:1055 function.c:268 version.c:179 +#: version.c:280 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:861 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace obsahuje \"contrib/isn\" funkce které spoléhají na\n" +"bigint datový typ. Váš starý a nový cluster pÅ™edávají bigint hodnoty\n" +"rozdílnÄ› takže tento cluster aktuálnÄ› nelze upgradovat. Můžete manuálnÄ›\n" +"upgradovat databáze které používají \"contrib/isn\" prostÅ™edky a odstranit\n" +"\"contrib/isn\" ze starého clusteru a znovu spustit upgrade. Seznam\n" +"problematických funkcí je v souboru:\n" +" %s\n" +"\n" + +#: check.c:893 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Kontroluji reg* datové typy v uživatelských tabulkách" + +#: check.c:965 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace obsahuje nÄ›který z reg* datových typů v uživatelských\n" +"tabulkách. Tyto datové typy odkazují na systémové OID hodnoty které\n" +"nejsou zachovány pÅ™i pg_upgrade, takže tento cluster aktuálnÄ› nelze\n" +"upgradovat. Můžete odstranit problematické tabulky a znovu spustit\n" +"upgrade. Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: check.c:990 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Kontroluji nekompatibilní \"jsonb\" datový typ" + +#: check.c:1056 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster " +"cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A " +"list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace obsahuje \"jsonb\" datový typ v uživatelských tabulkách.\n" +"Interní formát \"jsonb\" se zmÄ›nil v 9.4 beta takže tento cluster aktuálnÄ› " +"nelze\n" +"upgradovat. Můžete odstranit problematické tabulky a znovu spustit " +"upgrade.\n" +"Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: check.c:1077 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Kontroluji existenci rolí zaÄínajících na \"pg_\"" + +#: check.c:1087 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Zdrojový cluster obsahuje role zaÄínající na \"pg_\"\n" + +#: check.c:1089 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Cílový cluster obsahuje role zaÄínající na \"pg_\"\n" + +#: check.c:1115 +#, c-format +msgid "failed to get the current locale\n" +msgstr "selhalo získání aktuální hodnoty locale\n" + +#: check.c:1124 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "selhalo získání jména systémové locale pro \"%s\"\n" + +#: check.c:1130 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "selhala obnova staré locale \"%s\"\n" + +#: controldata.c:128 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "nelze získat control data pomocí %s: %s\n" + +#: controldata.c:141 dump.c:51 pg_upgrade.c:332 pg_upgrade.c:369 +#: relfilenode.c:244 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:148 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal problem\n" + +#: controldata.c:158 controldata.c:168 controldata.c:179 controldata.c:190 +#: controldata.c:201 controldata.c:220 controldata.c:231 controldata.c:242 +#: controldata.c:253 controldata.c:264 controldata.c:275 controldata.c:278 +#: controldata.c:282 controldata.c:292 controldata.c:304 controldata.c:315 +#: controldata.c:326 controldata.c:337 controldata.c:348 controldata.c:359 +#: controldata.c:370 controldata.c:381 controldata.c:392 controldata.c:403 +#: controldata.c:414 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: controldata retrieval problem\n" + +#: controldata.c:479 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Zdrojový cluster postrádá nÄ›které nutné control informace:\n" + +#: controldata.c:482 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Cílový cluster postrádá nÄ›které nutné control informace:\n" + +#: controldata.c:485 +#, c-format +msgid " checkpoint next XID\n" +msgstr " další XID checkpointu\n" + +#: controldata.c:488 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " další OID posledního checkpointu\n" + +#: controldata.c:491 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " další MultiXactId posledního checkpointu\n" + +#: controldata.c:495 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " nejstarší MultiXactId posledního checkpointu\n" + +#: controldata.c:498 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " MultiXactOffset posledního checkpointu\n" + +#: controldata.c:501 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " první WAL segment po resets\n" + +#: controldata.c:504 +#, c-format +msgid " float8 argument passing method\n" +msgstr " metoda pÅ™edávání float8 argumentů\n" + +#: controldata.c:507 +#, c-format +msgid " maximum alignment\n" +msgstr " maximální alignment\n" + +#: controldata.c:510 +#, c-format +msgid " block size\n" +msgstr " velikost bloku\n" + +#: controldata.c:513 +#, c-format +msgid " large relation segment size\n" +msgstr " velikost segmentu velkých relací\n" + +#: controldata.c:516 +#, c-format +msgid " WAL block size\n" +msgstr " velikost WAL bloku\n" + +#: controldata.c:519 +#, c-format +msgid " WAL segment size\n" +msgstr " velikost WAL segmentu\n" + +#: controldata.c:522 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximální délka identifikátoru\n" + +#: controldata.c:525 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximální poÄet indexovaných sloupců\n" + +#: controldata.c:528 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximální velikost TOAST chunku\n" + +#: controldata.c:532 +#, c-format +msgid " large-object chunk size\n" +msgstr " velikost large-object chunku\n" + +#: controldata.c:535 +#, c-format +msgid " dates/times are integers?\n" +msgstr " datum/Äas jsou integery?\n" + +#: controldata.c:539 +#, c-format +msgid " data checksum version\n" +msgstr " verze datových kontrolních souÄtů\n" + +#: controldata.c:541 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Nelze pokraÄovat bez kontrolních informací, konÄím\n" + +#: controldata.c:556 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"stará a nová hodnota pg_controldata alignmentu jsou neplatné nebo se " +"neshodují\n" +"PravdÄ›podobnÄ› jeden z clusterů je 32-bitový a druhý je 64-bitový\n" + +#: controldata.c:560 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "" +"stará a nová hodnota pg_controldata velikosti bloku jsou neplatné nebo se " +"neshodují\n" + +#: controldata.c:563 +#, c-format +msgid "" +"old and new pg_controldata maximum relation segment sizes are invalid or do " +"not match\n" +msgstr "" +"stará a nová hodnota pg_controldata maximální velikosti segmentu relace jsou " +"neplatné nebo se neshodují\n" + +#: controldata.c:566 +#, c-format +msgid "" +"old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "" +"stará a nová hodnota pg_controldata velikost WAL bloku jsou neplatné nebo se " +"neshodují\n" + +#: controldata.c:569 +#, c-format +msgid "" +"old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "" +"stará a nová hodnota pg_controldata velikost WAL segmentu jsou neplatné nebo " +"se neshodují\n" + +#: controldata.c:572 +#, c-format +msgid "" +"old and new pg_controldata maximum identifier lengths are invalid or do not " +"match\n" +msgstr "" +"stará a nová hodnota pg_controldata maximální délky identifikátoru jsou " +"neplatné nebo se neshodují\n" + +#: controldata.c:575 +#, c-format +msgid "" +"old and new pg_controldata maximum indexed columns are invalid or do not " +"match\n" +msgstr "" +"stará a nová hodnota pg_controldata maximálního poÄtu indexovaných sloupců " +"jsou neplatné nebo se neshodují\n" + +#: controldata.c:578 +#, c-format +msgid "" +"old and new pg_controldata maximum TOAST chunk sizes are invalid or do not " +"match\n" +msgstr "" +"stará a nová hodnota pg_controldata maximální velikosti TOAST chunku jsou " +"neplatné nebo se neshodují\n" + +#: controldata.c:583 +#, c-format +msgid "" +"old and new pg_controldata large-object chunk sizes are invalid or do not " +"match\n" +msgstr "" +"stará a nová hodnota pg_controldata velikosti large-object chunku jsou " +"neplatné nebo se neshodují\n" + +#: controldata.c:586 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "" +"stará a nová hodnota pg_controldata typu pro datum/Äas jsou neplatné nebo se " +"neshodují\n" + +#: controldata.c:599 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "starý cluster nepoužívá data chechsums ale nový ano\n" + +#: controldata.c:602 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "starý cluster používá data chechsums ale nový nikoliv\n" + +#: controldata.c:604 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "verze kontrolních souÄtů na starém a novém clusteru se neshodují\n" + +#: controldata.c:615 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "PÅ™idávám \".old\" příponu ke starému global/pg_control souboru" + +#: controldata.c:620 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Nelze pÅ™ejmenovat %s na %s.\n" + +#: controldata.c:623 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Pokud budete chtít nastartovat starý cluster, budete muset odstranit\n" +"příponu \".old\" z %s/global/pg_control.old.\n" +"Protože byl použit \"link\" mód, starý cluster nemůže být bezpeÄnÄ›\n" +"spuÅ¡tÄ›n jakmile bude nastartován nový cluster.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "Vytvářím dump globálních objektů" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Vytvářím dump databázových schémat\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "nelze získat verzi pg_ctl pomocí %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "nelze získat výstup s pg_ctl verzí z %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "příkaz je příliÅ¡ dlouhý\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:101 option.c:217 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "nelze zapsat do log souboru \"%s\"\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*failure*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "DoÅ¡lo k problémům pÅ™i spuÅ¡tÄ›ní \"%s\"\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Pro pravdÄ›podobnou příÄinu selhání prozkoumejte posledních pár\n" +"řádek z \"%s\" nebo \"%s\".\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Pro pravdÄ›podobnou příÄinu selhání prozkoumejte posledních pár\n" +"řádek z \"%s\".\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "nelze otevřít soubor \"%s\" pro Ätení: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Musíte mít práva na Ätení a zápis v aktuálním adresáři.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "kontrola pro \"%s\" selhala: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" není adresář\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "check for \"%s\" failed: not a regular file\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "kontrola \"%s\" selhala: nelze Äíst soubor (přístup odepÅ™en)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "kontrola \"%s\" selhala: nelze spustit soubor (přístup odepÅ™en)\n" + +#: file.c:44 file.c:147 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": nelze otevřít soubor \"%s\": %s\n" + +#: file.c:49 file.c:156 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": nelze vytvoÅ™it soubor \"%s\": %s\n" + +#: file.c:63 file.c:187 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": nelze Äíst ze souboru \"%s\": %s\n" + +#: file.c:75 file.c:265 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": nelze zapsat do souboru \"%s\": %s\n" + +#: file.c:89 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "chyba pÅ™i kopírování relace \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: file.c:108 +#, c-format +msgid "" +"error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"chyba pÅ™i vytváření odkazů pro relaci \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: file.c:151 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": nelze získat informace o souboru \"%s" +"\": %s\n" + +#: file.c:190 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "" +"chyba pÅ™i kopírování relace \"%s.%s\": ÄásteÄnÄ› zapsaná stránka nalezena v " +"souboru \"%s\"\n" + +#: file.c:293 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file " +"system.\n" +msgstr "" +"nelze vytvoÅ™it hard link mezi starým a novým datovým adresářem: %s\n" +"V link módu musí být starý a nový datový adresář na stejném souborovém " +"systému.\n" + +#: function.c:110 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Starý cluster má \"plpython_call_handler\" funkci definovanou\n" +"v \"public\" schématu což je duplicitní s tou definovanou v \"pg_catalog\"\n" +"schématu. Ověřit to můžete spuÅ¡tÄ›ním tohoto v psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Veze z \"public\" schématu byla vytvoÅ™ena instalací plpython pÅ™ed 8.1,\n" +"a musí být odstranÄ›na aby pg_upgrade mohlo fungovat protože\n" +"odkazuje na nyní zastaralý \"plpython\" sdílený objekt. Verzi z \"public\"\n" +"schématu můžete odstranit spuÅ¡tÄ›ním následujícího příkazu:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"v každé postižené databázi:\n" +"\n" + +#: function.c:128 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:138 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Pro pokraÄování ze starého clusteru odstraňte problematické funkce.\n" + +#: function.c:211 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Kontroluji dostupnost potÅ™ebných knihoven" + +#: function.c:255 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "nelze naÄíst knihovnu \"%s\": %s" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace odkazuje na knihovny které chybí v nové instalaci. Můtete\n" +"je buÄ pÅ™idat do nové instalace, nebo odstranit funkce které je vyžadují ze\n" +"staré instalace. Seznam problematických knihoven je v souboru:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "" +"Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s" +"\", new name \"%s.%s\"\n" +msgstr "" +"Názvy relace pro OID %u v databázi \"%s\" neodpovídají: staré jméno \"%s.%s" +"\", nové jméno \"%s.%s\"\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Chyba pÅ™i párování starých a nových tabulek v databázi \"%s\"\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " což je index na \"%s.%s\"" + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr " což je index na OID %u" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " což je TOAST tabulka pro \"%s.%s\"" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " což je TOAST tabulka pro OID %u" + +#: info.c:276 +#, c-format +msgid "" +"No match found in old cluster for new relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"Ve starém clusteru nebyl nalezen odpovídající záznam pro novou relaci s OID " +"%u v databázi \"%s\": %s\n" + +#: info.c:279 +#, c-format +msgid "" +"No match found in new cluster for old relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"V novém clusteru nebyl nalezen odpovídající záznam pro relaci s OID %u v " +"databázi \"%s\": %s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "mapování pro databázi \"%s\":\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u na %u\n" + +#: info.c:299 info.c:638 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"zdrojové databáze:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"cílové databáze:\n" + +#: info.c:636 +#, c-format +msgid "Database: %s\n" +msgstr "Databáze: %s\n" + +#: info.c:649 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:98 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: nelze spouÅ¡tÄ›t jako root\n" + +#: option.c:172 +#, c-format +msgid "invalid old port number\n" +msgstr "neplatné staré Äíslo portu\n" + +#: option.c:180 +#, c-format +msgid "invalid new port number\n" +msgstr "neplatné nové Äíslo portu\n" + +#: option.c:202 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Běží v módu s detailním (verbose) logováním.\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Zkuste \"%s --help\" pro více informací.\n" + +#: option.c:242 +msgid "old cluster binaries reside" +msgstr "binárky starého clusteru jsou umístÄ›ny" + +#: option.c:244 +msgid "new cluster binaries reside" +msgstr "binárky nového clusteru jsou umístÄ›ny" + +#: option.c:246 +msgid "old cluster data resides" +msgstr "data starého clusteru jsou umístÄ›na" + +#: option.c:248 +msgid "new cluster data resides" +msgstr "data nového clusteru jsou umístÄ›na" + +#: option.c:265 option.c:462 +#, c-format +msgid "could not determine current directory\n" +msgstr "nelze urÄit aktuální adresář\n" + +#: option.c:268 +#, c-format +msgid "" +"cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"na Windows nelze spouÅ¡tÄ›t pg_upgrade z datového adresáře nového clusteru\n" + +#: option.c:277 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade upgraduje PostgreSQL cluster na jinou major verzi.\n" +"\n" + +#: option.c:278 +#, c-format +msgid "Usage:\n" +msgstr "Použití:\n" + +#: option.c:279 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [VOLBA]...\n" +"\n" + +#: option.c:280 +#, c-format +msgid "Options:\n" +msgstr "PÅ™epínaÄe:\n" + +#: option.c:281 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr "" +" -b, --old-bindir=BINDIR adresář se spustitelnými soubory starého " +"clusteru\n" + +#: option.c:282 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr "" +" -B, --new-bindir=BINDIR adresář se spustitelnými soubory nového " +"clusteru\n" + +#: option.c:283 +#, c-format +msgid "" +" -c, --check check clusters only, don't change any data\n" +msgstr "" +" -c, --check pouze kontroluje clustery, nemÄ›ní žádná " +"data\n" + +#: option.c:284 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR datový adresář starého clusteru\n" + +#: option.c:285 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR datový adresář nového clusteru\n" + +#: option.c:286 +#, c-format +msgid "" +" -j, --jobs number of simultaneous processes or threads " +"to use\n" +msgstr "" +" -j, --jobs poÄet paralelních procesů nebo threadů\n" + +#: option.c:287 +#, c-format +msgid "" +" -k, --link link instead of copying files to new " +"cluster\n" +msgstr "" +" -k, --link vytváří odkazy namísto copírování souborů do " +"nového clusteru\n" + +#: option.c:288 +#, c-format +msgid "" +" -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr "" +" -o, --old-options=VOLBY volby pro starý cluster které se mají pÅ™edat " +"serveru\n" + +#: option.c:289 +#, c-format +msgid "" +" -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr "" +" -O, --new-options=VOLBY volby pro nový cluster které se mají pÅ™edat " +"serveru\n" + +#: option.c:290 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr "" +" -p, --old-port=PORT Äíslo portu pro starý cluster (implicitnÄ› " +"%d)\n" + +#: option.c:291 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr "" +" -P, --new-port=PORT Äíslo portu pro nový cluster (implicitnÄ› " +"%d)\n" + +#: option.c:292 +#, c-format +msgid "" +" -r, --retain retain SQL and log files after success\n" +msgstr "" +" -r, --retain v případÄ› úspÄ›chu zachovat SQL a log " +"soubory\n" + +#: option.c:293 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr "" +" -U, --username=JMÉNO superuživatel pro cluster (implicitnÄ› \"%s" +"\")\n" + +#: option.c:294 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose zapné podrobné interní logování\n" + +#: option.c:295 +#, c-format +msgid "" +" -V, --version display version information, then exit\n" +msgstr "" +" -V, --version zobrazí informaci o verzi, poté skonÄí\n" + +#: option.c:296 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help zobrazí tuto nápovÄ›du, poté skonÄí\n" + +#: option.c:297 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"PÅ™ed spuÅ¡tÄ›ním pg_upgrade musíte:\n" +" vytvoÅ™it nový databázový cluster (pomocí nové verze initdb)\n" +" zastavit postmaster proces běžící nad starým clusterem\n" +" zastavit postmaster proces běžízí nad novým clusterem\n" + +#: option.c:302 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"PÅ™i spuÅ¡tÄ›ní pg_upgrade musíte zadat následující informace:\n" +" datový adresář pro starý cluster (-d DATADIR)\n" +" datový adresář pro nový cluster (-D DATADIR)\n" +" \"bin\" adresář pro starou verzi (-b BINDIR)\n" +" \"bin\" adresář pro novou verzi (-B BINDIR)\n" + +#: option.c:308 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Například:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" +"nebo\n" + +#: option.c:313 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:319 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:325 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Chyby hlaste na adresu .\n" + +#: option.c:358 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Musíte zadat adresář kde %s.\n" +"Použijte prosím volbu %s na příkazové řádce nebo promÄ›nnou prostÅ™edí %s.\n" + +#: option.c:409 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Vyhledávám skuteÄný datový adresář pro zdrojový cluster" + +#: option.c:411 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Vyhledávám skuteÄný datový adresář pro cílový cluster" + +#: option.c:423 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "nelze získat datový adresář pomocí %s: %s\n" + +#: option.c:488 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "nelze naÄíst řádek %d ze souboru \"%s\": %s\n" + +#: option.c:506 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "uživatelem-zadané Äíslo starého portu %hu opraveno na %hu\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "nelze vytvoÅ™it worker proces: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "nelze vytvoÅ™it worker thread: %s\n" + +#: parallel.c:310 parallel.c:325 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "podřízený proces neoÄekávanÄ› skonÄil: %s\n" + +#: pg_upgrade.c:106 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "nelze zjistit přístupová práva adresáře \"%s\": %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Provádím Upgrade\n" +"----------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Nastavuji další OID pro nový cluster" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synchronizuji datový adresář na disk" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Upgrade DokonÄen\n" +"----------------\n" + +#: pg_upgrade.c:230 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Zdá se že postmaster nad starým clusterem stále běží.\n" +"Prosím zastavte přísluÅ¡ný postmaster proces a zkuste to znovu.\n" + +#: pg_upgrade.c:243 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Zdá se že postmaster nad novým clusterem stále běží.\n" +"Prosím zastavte přísluÅ¡ný postmaster proces a zkuste to znovu.\n" + +#: pg_upgrade.c:249 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: nelze najít vlastní spustitelný soubor\n" + +#: pg_upgrade.c:266 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analyzuji vÅ¡echny řádky v novém clusteru" + +#: pg_upgrade.c:279 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Provádím freeze na vÅ¡ech řádcích v novém clusteru" + +#: pg_upgrade.c:299 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Obnovuji globální objekty v novém clusteru" + +#: pg_upgrade.c:314 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Obnovuji databázová schémata v novém clusteru\n" + +#: pg_upgrade.c:420 +#, c-format +msgid "Deleting files from new %s" +msgstr "Mažu soubory z nového %s" + +#: pg_upgrade.c:424 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "nelze smazat adresář \"%s\"\n" + +#: pg_upgrade.c:443 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopíruji starý %s do nového serveru" + +#: pg_upgrade.c:470 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Nastavuij následující transaction ID a epochu pro nový cluster" + +#: pg_upgrade.c:500 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Nastavuji následující multixact ID a offset pro nový cluster" + +#: pg_upgrade.c:524 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Nastavuji nejstarší multixact ID v novém clusteru" + +#: pg_upgrade.c:544 +#, c-format +msgid "Resetting WAL archives" +msgstr "Resetuji WAL archivy" + +#: pg_upgrade.c:587 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Nastavuji frozenxid a minmxid v novém clusteru" + +#: pg_upgrade.c:589 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Nastavuji minmxid v novém clustreru" + +#: relfilenode.c:34 +#, c-format +msgid "Linking user relation files\n" +msgstr "Linkuji soubory pro uživatelské relace\n" + +#: relfilenode.c:36 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopíruji soubory pro uživatelské relace\n" + +#: relfilenode.c:110 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "stará databáze \"%s\" nenalezena v novém clusteru\n" + +#: relfilenode.c:231 +#, c-format +msgid "" +"error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"chyba pÅ™i kontrole existence souboru \"%s.%s\" (\"%s\" na \"%s\"): %s\n" + +#: relfilenode.c:249 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "pÅ™episuji \"%s\" na \"%s\"\n" + +#: relfilenode.c:255 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "copíruji \"%s\" do \"%s\"\n" + +#: relfilenode.c:261 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "linkuji \"%s\" na \"%s\"\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "spojení do databáze selhalo: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "Chyba, konÄím\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "spouÅ¡tím: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL příkaz selhal\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "nelze otevřít soubor s verzí: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "nelze naparsovat PG_VERSION soubor z %s\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"spojení na databázi selhalo: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"nelze se pÅ™ipojit ke zdrojovému postmaster procesu příkazem:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"nelze se pÅ™ipojit k cílovému postmaster procesu příkazem:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "" +"pg_ctl selhal pÅ™i pokusu nastartovat zdrojový server, nebo selhal pokus o " +"spojení\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "" +"pg_ctl selhal pÅ™i pokusu nastartovat cílový server, nebo selhal pokus o " +"spojení\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek pamÄ›ti\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "" +"libpq promÄ›nná prostÅ™edí %s má hodnotu odkazující na nelokální server: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"PÅ™i použití tablespaces nelze provádÄ›t upgrade na/ze stejné verze\n" +"systémových katalogů.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "adresář pro tablespace \"%s\" neexistuje\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "nelze pÅ™istoupit k tablespace adresáři \"%s\": %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "cesta k tabespace \"%s\" není adresář\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "Kontrola velkých objektů" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "varování" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"VaÅ¡e instalace obsahuje velké objekty. Nová databáze má další tabulku\n" +"s právy k velkým objektům. Po upgrade vám bude poskytnut příkaz pro\n" +"naplnÄ›ní tabulky pg_largeobject_metadata s výchozími právy.\n" +"\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"VaÅ¡e instalace obsahuje velké objekty. Nová databáze má další tabulku\n" +"s právy k velkým objektům, takže pro vÅ¡echny velké objekty musí být\n" +"definována výchozí práva. Soubor\n" +" %s\n" +"po spuÅ¡tÄ›ní z psql pod superuživatelským úÄtem tato výchozí práva nastaví.\n" +"\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Kontrola nekompatibilního \"line\" datového typu" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace obsahuje datový typ \"line\" v uživatelských tabulkách. " +"Tento\n" +"datový typ zmÄ›nil interní a vstupní/výstupní formát mezi vaším starým a " +"novým\n" +"clusterem takže tento cluster nemůže být aktuálnÄ› upgradován. Můžete " +"odstranit\n" +"problematické tabulky a znovu spustit upgrade. Seznam problematických " +"sloupců\n" +"je v souboru:\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Kontrola pro neplatné \"unknown\" uživatelské sloupce" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"VaÅ¡e instalace obsahuje \"unknown\" datový typ v uživatelských tabulkách. " +"Tento\n" +"datový typ není v uživatelských tabulkách nadále povolen, takže tento " +"cluster nelze\n" +"aktuálnÄ› upgradovat. Můžete problematické tabulky odstranit a znovu spustit " +"upgrade.\n" +"Seznam problematických sloupců je v souboru:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Kontrola hash indexů" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"VaÅ¡e instalace obsahuje hash indexy. Tyto indexy mají rozdílný interní\n" +"formát mezi vaším starým a novým clusterem, takže musí být reindexovány\n" +"příkazem REINDEX. Po skonÄení upgrade vám budou poskytnuty instrukce\n" +"jak REINDEX provést.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"VaÅ¡e instalace obsahuje hash indexy. Tyto indexy mají rozdílný interní\n" +"formát mezi vaším starým a novým clusterem, takže musí být reindexovány\n" +"příkazem REINDEX. Soubor\n" +" %s\n" +"po spuÅ¡tÄ›ní z psql pod superuživatelským úÄtem znovu vytvoří vÅ¡echny\n" +"neplatné indexy; dokud k tomu nedojde tyto indexy nebudou používány.\n" +"\n" diff --git a/src/bin/pg_upgrade/po/de.po b/src/bin/pg_upgrade/po/de.po new file mode 100644 index 00000000000..56c828b3a47 --- /dev/null +++ b/src/bin/pg_upgrade/po/de.po @@ -0,0 +1,1745 @@ +# German message translation file for pg_upgrade +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Peter Eisentraut , 2018 - 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-20 07:16+0000\n" +"PO-Revision-Date: 2019-05-20 13:21+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Führe Konsistenzprüfungen am alten laufenden Server durch\n" +"---------------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Führe Konsistenzprüfungen durch\n" +"-------------------------------\n" + +#: check.c:183 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Cluster sind kompatibel*\n" + +#: check.c:189 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Wenn pg_upgrade ab diesem Punkt fehlschlägt, dann müssen Sie den\n" +"neuen Cluster neu mit initdb initialisieren, bevor fortgesetzt\n" +"werden kann.\n" + +#: check.c:225 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Optimizer-Statistiken werden von pg_upgrade nicht übertragen. Wenn Sie\n" +"den neuen Server starten, sollte Sie diesen Befehl ausführen:\n" +" %s\n" +"\n" + +#: check.c:230 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Optimizer-Statistiken und Informationen über freien Platz werden von\n" +"pg_upgrade nicht übertragen. Wenn Sie den neuen Server starten, sollten\n" +"Sie diesen Befehl ausführen:\n" +" %s\n" +"\n" + +#: check.c:237 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Mit diesem Skript können die Dateien des alten Clusters gelöscht werden:\n" +" %s\n" + +#: check.c:242 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Ein Skript zum Löschen der Dateien des alten Clusters konnte nicht\n" +"erzeugt werden, weil benutzerdefinierte Tablespaces oder das\n" +"Datenverzeichnis des neuen Clusters im alten Cluster-Verzeichnis\n" +"liegen. Der Inhalt des alten Clusters muss von Hand gelöscht werden.\n" + +#: check.c:252 +#, c-format +msgid "Checking cluster versions" +msgstr "Prüfe Cluster-Versionen" + +#: check.c:264 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Dieses Programm kann nur Upgrades von PostgreSQL Version 8.4 oder später durchführen.\n" + +#: check.c:268 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Dieses Programm kann nur Upgrades auf PostgreSQL Version %s durchführen.\n" + +#: check.c:277 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Dieses Programm kann keine Downgrades auf ältere Hauptversionen von PostgreSQL durchführen.\n" + +#: check.c:282 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Die Daten- und Programmverzeichnisse des alten Clusters stammen von verschiedenen Hauptversionen.\n" + +#: check.c:285 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Die Daten- und Programmverzeichnisse des neuen Clusters stammen von verschiedenen Hauptversionen.\n" + +#: check.c:302 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Wenn ein laufender alter Server vor Version 9.1 geprüft wird, muss die Portnummer des alten Servers angegeben werden.\n" + +#: check.c:306 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Wenn ein laufender Server geprüft wird, müssen die alte und die neue Portnummer verschieden sein.\n" + +#: check.c:321 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "Kodierungen für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:326 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_collate-Werte für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:329 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_ctype-Werte für Datenbank »%s« stimmen nicht überein: alt »%s«, neu »%s«\n" + +#: check.c:402 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Datenbank »%s« im neuen Cluster ist nicht leer: Relation »%s.%s« gefunden\n" + +#: check.c:451 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Erzeuge Skript zum Analysieren des neuen Clusters" + +#: check.c:465 check.c:593 check.c:857 check.c:936 check.c:1045 check.c:1136 +#: file.c:341 function.c:246 option.c:493 version.c:57 version.c:156 +#: version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht öffnen: %s\n" + +#: check.c:520 check.c:649 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht ausführbar machen: %s\n" + +#: check.c:556 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"WARNUNG: das neue Datenverzeichnis sollte nicht im alten Datenverzeichnis liegen, z.B. %s\n" + +#: check.c:580 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"WARNUNG: benutzerdefinierte Tablespace-Pfade sollten nicht im Datenverzeichnis liegen, z.B. %s\n" + +#: check.c:590 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Erzeuge Skript zum Löschen des alten Clusters" + +#: check.c:669 +#, c-format +msgid "Checking database user is the install user" +msgstr "Prüfe ob der Datenbankbenutzer der Installationsbenutzer ist" + +#: check.c:685 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "Datenbankbenutzer »%s« ist nicht der Installationsbenutzer\n" + +#: check.c:696 +#, c-format +msgid "could not determine the number of users\n" +msgstr "konnte die Anzahl der Benutzer nicht ermitteln\n" + +#: check.c:704 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Nur der Installationsbenutzer darf im neuen Cluster definiert sein.\n" + +#: check.c:724 +#, c-format +msgid "Checking database connection settings" +msgstr "Prüfe Verbindungseinstellungen der Datenbank" + +#: check.c:746 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 darf keine Verbindungen erlauben, d.h. ihr pg_database.datallowconn muss falsch sein\n" + +#: check.c:756 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Alle Datenbanken außer template0 müssen Verbindungen erlauben, d.h. ihr pg_database.datallowconn muss wahr sein\n" + +#: check.c:781 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Prüfe auf vorbereitete Transaktionen" + +#: check.c:790 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Der alte Cluster enthält vorbereitete Transaktionen\n" + +#: check.c:792 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Der neue Cluster enthält vorbereitete Transaktionen\n" + +#: check.c:818 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Prüfe auf contrib/isn mit unpassender bigint-Übergabe" + +#: check.c:879 check.c:958 check.c:1068 check.c:1159 function.c:268 +#: version.c:179 version.c:280 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:880 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält Funktionen aus »contrib/isn«, welche den\n" +"Datentyp bigint verwenden. Der alte und der neue Cluster übergeben\n" +"bigint auf andere Weise und daher kann dieser Cluster gegenwärtig\n" +"nicht aktualisiert werden. Sie können die Datenbanken, die\n" +"»contrib/isn« verwenden, manuell übertragen und »contrib/isn« aus dem\n" +"alten Cluster entfernen und dann das Upgrade neu starten. Eine Liste\n" +"der problematischen Funktionen ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:904 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Prüfe auf Tabellen mit WITH OIDS" + +#: check.c:959 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not supported\n" +"anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält Tabellen, die mit WITH OIDS deklariert sind, was\n" +"nicht mehr unterstützt wird. Entfernen Sie die oid-Spalte mit\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Eine Liste der Tabellen mit dem Problem ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:989 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Prüfe auf reg*-Datentypen in Benutzertabellen" + +#: check.c:1069 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält einen der reg*-Datentypen in\n" +"Benutzertabellen. Diese Datentypen verweisen auf System-OIDs, die von\n" +"pg_upgrade nicht erhalten werden. Daher kann dieser Cluster\n" +"gegenwärtig nicht aktualiert werden. Sie können die Problemtabellen\n" +"entfernen und das Upgrade neu starten. Eine Liste der Problemspalten\n" +"ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1094 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Prüfe auf inkompatiblen Datentyp »jsonb«" + +#: check.c:1160 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »jsonb« in\n" +"Benutzertabellen. Das interne Format von »jsonb« wurde während 9.4\n" +"Beta geändert. Daher kann dieser Cluster gegenwärtig nicht\n" +"aktualisiert werden. Sie können die Problemtabellen entfernen und das\n" +"Upgrade neu starten. Eine Liste der Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: check.c:1181 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Prüfe auf Rollen, die mit »pg_« anfangen" + +#: check.c:1191 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Der alte Cluster enthält Rollen, die mit »pg_« anfangen\n" + +#: check.c:1193 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Der neue Cluster enthält Rollen, die mit »pg_« anfangen\n" + +#: check.c:1219 +#, c-format +msgid "failed to get the current locale\n" +msgstr "konnte aktuelle Locale nicht ermitteln\n" + +#: check.c:1228 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "konnte System-Locale-Namen für »%s« nicht ermitteln\n" + +#: check.c:1234 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "konnte alte Locale »%s« nicht wiederherstellen\n" + +#: controldata.c:127 controldata.c:194 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "konnte Kontrolldaten mit %s nicht ermitteln: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: Problem mit dem Zustand des Clusters\n" + +#: controldata.c:155 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Der alte Cluster wurde im Wiederherstellungsmodus heruntergefahren. Um ihn zu aktualisieren, verwenden Sie »rsync« wie in der Dokumentation beschrieben oder fahren Sie ihn im Primärmodus herunter.\n" + +#: controldata.c:157 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Der neue Cluster wurde im Wiederherstellungsmodus heruntergefahren. Um ihn zu aktualisieren, verwenden Sie »rsync« wie in der Dokumentation beschrieben oder fahren Sie ihn im Primärmodus herunter.\n" + +#: controldata.c:162 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Der alte Cluster wurde nicht sauber heruntergefahren.\n" + +#: controldata.c:164 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Der neue Cluster wurde nicht sauber heruntergefahren.\n" + +#: controldata.c:175 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Im alten Cluster fehlen Cluster-Zustandsinformationen:\n" + +#: controldata.c:177 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Im neuen Cluster fehlen Cluster-Zustandsinformationen:\n" + +#: controldata.c:207 dump.c:51 pg_upgrade.c:336 pg_upgrade.c:373 +#: relfilenode.c:252 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:214 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: Problem mit pg_resetwal\n" + +#: controldata.c:224 controldata.c:234 controldata.c:245 controldata.c:256 +#: controldata.c:267 controldata.c:286 controldata.c:297 controldata.c:308 +#: controldata.c:319 controldata.c:330 controldata.c:341 controldata.c:344 +#: controldata.c:348 controldata.c:358 controldata.c:370 controldata.c:381 +#: controldata.c:392 controldata.c:403 controldata.c:414 controldata.c:425 +#: controldata.c:436 controldata.c:447 controldata.c:458 controldata.c:469 +#: controldata.c:480 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: Problem beim Ermitteln der Kontrolldaten\n" + +#: controldata.c:545 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Im alten Cluster fehlen einige notwendige Kontrollinformationen:\n" + +#: controldata.c:548 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Im neuen Cluster fehlen einige notwendige Kontrollinformationen:\n" + +#: controldata.c:551 +#, c-format +msgid " checkpoint next XID\n" +msgstr " Checkpoint nächste XID\n" + +#: controldata.c:554 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " NextOID des letzten Checkpoints\n" + +#: controldata.c:557 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " NextMultiXactId des letzten Checkpoints\n" + +#: controldata.c:561 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " oldestMultiXid des letzten Checkpoints\n" + +#: controldata.c:564 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " NextMultiOffset des letzten Checkpoints\n" + +#: controldata.c:567 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " erstes WAL-Segment nach dem Reset\n" + +#: controldata.c:570 +#, c-format +msgid " float8 argument passing method\n" +msgstr " Übergabe von Float8-Argumenten\n" + +#: controldata.c:573 +#, c-format +msgid " maximum alignment\n" +msgstr " maximale Ausrichtung (Alignment)\n" + +#: controldata.c:576 +#, c-format +msgid " block size\n" +msgstr " Blockgröße\n" + +#: controldata.c:579 +#, c-format +msgid " large relation segment size\n" +msgstr " Segmentgröße für große Relationen\n" + +#: controldata.c:582 +#, c-format +msgid " WAL block size\n" +msgstr " WAL-Blockgröße\n" + +#: controldata.c:585 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL-Segmentgröße\n" + +#: controldata.c:588 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximale Bezeichnerlänge\n" + +#: controldata.c:591 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximale Anzahl indizierter Spalten\n" + +#: controldata.c:594 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximale TOAST-Chunk-Größe\n" + +#: controldata.c:598 +#, c-format +msgid " large-object chunk size\n" +msgstr " Large-Object-Chunk-Größe\n" + +#: controldata.c:601 +#, c-format +msgid " dates/times are integers?\n" +msgstr " Datum/Zeit sind Ganzzahlen?\n" + +#: controldata.c:605 +#, c-format +msgid " data checksum version\n" +msgstr " Datenprüfsummenversion\n" + +#: controldata.c:607 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Kann ohne die benötigten Kontrollinformationen nicht fortsetzen, Programm wird beendet\n" + +#: controldata.c:622 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"altes und neues Alignment in pg_controldata ist ungültig oder stimmt nicht überein\n" +"Wahrscheinlich ist ein Cluster eine 32-Bit-Installation und der andere 64-Bit\n" + +#: controldata.c:626 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "alte und neue Blockgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:629 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "alte und neue maximale Relationssegmentgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:632 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "alte und neue WAL-Blockgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:635 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "alte und neue WAL-Segmentgrößen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:638 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "alte und neue maximale Bezeichnerlängen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:641 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "alte und neue Maximalzahlen indizierter Spalten von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:644 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "alte und neue maximale TOAST-Chunk-Größen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:649 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "alte und neue Large-Object-Chunk-Größen von pg_controldata sind ungültig oder stimmen nicht überein\n" + +#: controldata.c:652 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "alte und neue Speicherung von Datums- und Zeittypen von pg_controldata ist ungültig oder stimmt nicht überein\n" + +#: controldata.c:665 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "der alte Cluster verwendet keine Datenprüfsummen, aber der neue verwendet sie\n" + +#: controldata.c:668 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "die alte Cluster verwendet Datenprüfsummen, aber der neue nicht\n" + +#: controldata.c:670 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "Prüfsummenversionen im alten und neuen Cluster stimmen nicht überein\n" + +#: controldata.c:681 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Füge Endung ».old« an altes global/pg_control an" + +#: controldata.c:686 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Konnte %s nicht in %s umbenennen.\n" + +#: controldata.c:689 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Wenn Sie den alten Cluster starten wollen, müssen Sie die Endung\n" +"».old« von %s/global/pg_control.old entfernen. Da der »link«-Modus\n" +"verwendet wurde, kann der alte Cluster nicht gefahrlos gestartet\n" +"werden, nachdem der neue Cluster gestartet worden ist.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "Erzeuge Dump der globalen Objekte" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Erzeuge Dump der Datenbankschemas\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "konnte pg_ctl-Versionsdaten mit %s nicht ermitteln: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "konnte pg_ctl-Version nicht ermitteln von %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "Befehl zu lang\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:105 option.c:227 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "konnte nicht in Logdatei »%s «schreiben\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*fehlgeschlagen*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Probleme beim Ausführen von »%s«\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Prüfen Sie die letzten Zeilen von »%s« oder »%s« für den\n" +"wahrscheinlichen Grund für das Scheitern.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Prüfen Sie die letzten Zeilen von »%s« für den\n" +"wahrscheinlichen Grund für das Scheitern.\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "konnte Datei »%s« nicht zum Lesen öffnen: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Sie müssen Lese- und Schreibzugriff im aktuellen Verzeichnis haben.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "Prüfen von »%s« fehlgeschlagen: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "»%s« ist kein Verzeichnis\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "Prüfen von »%s« fehlgeschlagen: keine reguläre Datei\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "Prüfen von »%s« fehlgeschlagen: kann nicht gelesen werden (keine Berechtigung)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "Prüfen von »%s« fehlgeschlagen: kann nicht ausgeführt werden (keine Berechtigung)\n" + +#: file.c:48 file.c:66 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s«: konnte Datei »%s« nicht öffnen: %s\n" + +#: file.c:60 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "Fehler beim Klonen von Relation »%s.%s«: konnte Datei »%s« nicht erzeugen: %s\n" + +#: file.c:92 file.c:195 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht öffnen: %s\n" + +#: file.c:97 file.c:204 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht erzeugen: %s\n" + +#: file.c:111 file.c:228 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht lesen: %s\n" + +#: file.c:123 file.c:306 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte Datei »%s« nicht schreiben: %s\n" + +#: file.c:137 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:156 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Erzeugen einer Verknüpfung für Relation »%s.%s« (»%s« nach »%s«): %s\n" + +#: file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: konnte »stat« für Datei »%s« nicht ausführen: %s\n" + +#: file.c:231 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "Fehler beim Kopieren von Relation »%s.%s«: unvollständige Seite gefunden in Datei »%s«\n" + +#: file.c:333 file.c:350 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "konnte Datei nicht vom alten in das neue Datenverzeichnis klonen: %s\n" + +#: file.c:346 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "konnte Datei »%s« nicht erstellen: %s\n" + +#: file.c:357 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "Klonen von Dateien wird auf dieser Plattform nicht unterstützt\n" + +#: file.c:374 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"konnte Hard-Link-Verknüpfung zwischen altem und neuen Datenverzeichnis nicht erzeugen: %s\n" +"Im Link-Modus müssen das alte und das neue Datenverzeichnis im selben Dateisystem liegen.\n" + +#: function.c:116 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Der alte Cluster hat eine Funktion »plpython_call_handler« definiert\n" +"im Schema »public«, die eine Duplikat der im Schema »pg_catalog«\n" +"definierten ist. Sie können das bestätigen, indem Sie dies in psql\n" +"ausführen:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Die Version im Schema »public« wurde von einer Installation von\n" +"plpython vor Version 8.1 erzeugt und muss entfernt werden, damit\n" +"pg_upgrade fortsetzen kann, weil sie auf die mittlerweile obsolete\n" +"Shared-Object-Datei »plpython« verweist. Sie können die Version dieser\n" +"Funktion im Schema »public« entfernen, indem Sie diesen Befehl in\n" +"jeder betroffenen Datenbank ausführen:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" + +#: function.c:134 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:144 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Entfernen Sie die problematischen Funktionen aus dem alten Cluster um fortzufahren.\n" + +#: function.c:191 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Prüfe das Vorhandensein benötigter Bibliotheken" + +#: function.c:248 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "konnte Bibliothek »%s« nicht laden: %s" + +#: function.c:259 info.c:633 +#, c-format +msgid "Database: %s\n" +msgstr "Datenbank: %s\n" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation verweist auf ladbare Bibliotheken, die in der neuen\n" +"Installation fehlen. Sie können diese Bibliotheken zur neuen\n" +"Installation hinzufügen oder die Funktionen in der alten Installation\n" +"entfernen. Eine Liste der problematischen Bibliotheken ist in der\n" +"Datei:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Relationsnamen für OID %u in Datenbank »%s« stimmen nicht überein: alten Name »%s.%s«, neuer Name »%s.%s«\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Alte und neue Tabellen in Datenbank »%s« konnten nicht gepaart werden\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr ", ein Index für »%s.%s«" + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr ", ein Index für OID %u" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr ", eine TOAST-Tabelle für »%s.%s«" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr ", eine TOAST-Tabelle für OID %u" + +#: info.c:276 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Keine Übereinstimmung gefunden im alten Cluster für neue Relation mit OID %u in Datenbank »%s«: %s\n" + +#: info.c:279 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "Keine Übereinstimmung gefunden im neuen Cluster für alte Relation mit OID %u in Datenbank »%s«: %s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "Paarungen für Datenbank »%s«:\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u nach %u\n" + +#: info.c:299 info.c:635 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"Quelldatenbanken:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"Zieldatenbanken:\n" + +#: info.c:646 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: kann nicht als root ausgeführt werden\n" + +#: option.c:174 +#, c-format +msgid "invalid old port number\n" +msgstr "ungültige alte Portnummer\n" + +#: option.c:182 +#, c-format +msgid "invalid new port number\n" +msgstr "ungültige neue Portnummer\n" + +#: option.c:208 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Ausführung im Verbose-Modus\n" + +#: option.c:217 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" + +#: option.c:252 +msgid "old cluster binaries reside" +msgstr "die Programmdateien des alten Clusters liegen" + +#: option.c:254 +msgid "new cluster binaries reside" +msgstr "die Programmdateien des neuen Clusters liegen" + +#: option.c:256 +msgid "old cluster data resides" +msgstr "die Daten das alten Clusters liegen" + +#: option.c:258 +msgid "new cluster data resides" +msgstr "die Daten des neuen Clusters liegen" + +#: option.c:260 +msgid "sockets will be created" +msgstr "die Sockets erzeugt werden sollen" + +#: option.c:277 option.c:371 +#, c-format +msgid "could not determine current directory\n" +msgstr "konnte aktuelles Verzeichnis nicht ermitteln\n" + +#: option.c:280 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "auf Windows kann pg_upgrade nicht von innerhalb des Cluster-Datenverzeichnisses ausgeführt werden\n" + +#: option.c:289 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade aktualisiert einen PostgreSQL-Cluster auf eine neue Hauptversion.\n" +"\n" + +#: option.c:290 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: option.c:291 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [OPTION]...\n" +"\n" + +#: option.c:292 +#, c-format +msgid "Options:\n" +msgstr "Optionen:\n" + +#: option.c:293 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINVERZ Programmverzeichnis des alten Clusters\n" + +#: option.c:294 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINVERZ Programmverzeichnis des neuen Clusters\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check nur Cluster prüfen, keine Daten ändern\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATENVERZ Datenverzeichnis des alten Clusters\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATENVERZ Datenverzeichnis des neuen Clusters\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs Anzahl paralleler Prozesse oder Threads\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link Dateien in den neuen Cluster verknüpfen statt kopieren\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONEN Serveroptionen für den alten Cluster\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONEN Serveroptionen für den neuen Cluster\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT Portnummer für den alten Cluster (Standard: %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT Portnummer für den neuen Cluster (Standard: %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain SQL- und Logdateien bei Erfolg aufheben\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default CWD)\n" +msgstr " -s, --socketdir=VERZ Verzeichnis für Socket (Standard: aktuelles Verz.)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAME Cluster-Superuser (Standard: »%s«)\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose »Verbose«-Modus einschalten\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone Dateien in den neuen Cluster klonen statt kopieren\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Vor dem Aufruf von pg_upgrade müssen Sie:\n" +" den neuen Datenbankcluster anlegen (mit der neuen Version von initdb)\n" +" den Postmaster für den alten Cluster anhalten\n" +" den Postmaster für den neuen Cluster anhalten\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Beim Aufruf von pg_upgrade müssen die folgenden Informationen angegeben werden:\n" +" das Datenverzeichnis des alten Clusters (-d DATENVERZ)\n" +" das Datenverzeichnis des neuen Clusters (-D DATENVERZ)\n" +" das »bin«-Verzeichnis der alten Version (-b BINVERZ)\n" +" das »bin«-Verzeichnis der neuen Version (-B BINVERZ)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Zum Beispiel:\n" +" pg_upgrade -d alterCluster/data -D neuerCluster/data -b alterCluster/bin -B neuerCluster/bin\n" +"oder\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=alterCluster/data\n" +" $ export PGDATANEW=neuerCluster/data\n" +" $ export PGBINOLD=alterCluster/bin\n" +" $ export PGBINNEW=neuerCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=alterCluster/data\n" +" C:\\> set PGDATANEW=neuerCluster/data\n" +" C:\\> set PGBINOLD=alterCluster/bin\n" +" C:\\> set PGBINNEW=neuerCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Berichten Sie Fehler an .\n" + +#: option.c:375 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Sie müssen das Verzeichnis angeben, wo %s.\n" +"Bitte verwenden Sie die Kommandzeilenoption %s oder die Umgebungsvariable %s.\n" + +#: option.c:427 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Suche das tatsächliche Datenverzeichnis des alten Clusters" + +#: option.c:429 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Suche das tatsächliche Datenverzeichnis des neuen Clusters" + +#: option.c:441 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "konnte Datenverzeichnis mit %s nicht ermitteln: %s\n" + +#: option.c:501 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "konnte Zeile %d aus Datei »%s« nicht lesen: %s\n" + +#: option.c:519 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "vom Benutzer angegebene Portnummer %hu wurde auf %hu korrigiert\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "konnte Arbeitsprozess nicht erzeugen: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "konnte Arbeits-Thread nicht erzeugen: %s\n" + +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() fehlgeschlagen: %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "Kindprozess wurde abnormal beendet: Status %d\n" + +#: parallel.c:324 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "Kindprozess wurde abnormal beendet: %s\n" + +#: pg_upgrade.c:109 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "konnte Zugriffsrechte von Verzeichnis »%s« nicht lesen: %s\n" + +#: pg_upgrade.c:126 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Führe Upgrade durch\n" +"-------------------\n" + +#: pg_upgrade.c:169 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Setze nächste OID im neuen Cluster" + +#: pg_upgrade.c:176 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synchronisiere Datenverzeichnis auf Festplatte" + +#: pg_upgrade.c:188 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Upgrade abgeschlossen\n" +"---------------------\n" + +#: pg_upgrade.c:234 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Es läuft scheinbar ein Postmaster für den alten Cluster.\n" +"Bitte beenden Sie diesen Postmaster und versuchen Sie es erneut.\n" + +#: pg_upgrade.c:247 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Es läuft scheinbar ein Postmaster für den neuen Cluster.\n" +"Bitte beenden Sie diesen Postmaster und versuchen Sie es erneut.\n" + +#: pg_upgrade.c:253 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: konnte eigene Programmdatei nicht finden\n" + +#: pg_upgrade.c:270 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analysiere alle Zeilen im neuen Cluster" + +#: pg_upgrade.c:283 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Friere alle Zeilen im neuen Cluster ein" + +#: pg_upgrade.c:303 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Stelle globale Objekte im neuen Cluster wieder her" + +#: pg_upgrade.c:318 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Stelle Datenbankschemas im neuen Cluster wieder her\n" + +#: pg_upgrade.c:424 +#, c-format +msgid "Deleting files from new %s" +msgstr "Lösche Dateien aus neuem %s" + +#: pg_upgrade.c:428 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "konnte Verzeichnis »%s« nicht löschen\n" + +#: pg_upgrade.c:447 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopiere altes %s zum neuen Server" + +#: pg_upgrade.c:474 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Setze nächste Transaktions-ID und -epoche im neuen Cluster" + +#: pg_upgrade.c:504 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Setze nächste Multixact-ID und nächstes Offset im neuen Cluster" + +#: pg_upgrade.c:528 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Setze älteste Multixact-ID im neuen Cluster" + +#: pg_upgrade.c:548 +#, c-format +msgid "Resetting WAL archives" +msgstr "Setze WAL-Archive zurück" + +#: pg_upgrade.c:591 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Setze frozenxid und minmxid im neuen Cluster" + +#: pg_upgrade.c:593 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Setze minmxid im neuen Cluster" + +#: relfilenode.c:36 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Klonen Benutzertabellendateien\n" + +#: relfilenode.c:39 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopiere Benutzertabellendateien\n" + +#: relfilenode.c:42 +#, c-format +msgid "Linking user relation files\n" +msgstr "Verknüpfe Benutzertabellendateien\n" + +#: relfilenode.c:118 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "alte Datenbank »%s« nicht im neuen Cluster gefunden\n" + +#: relfilenode.c:239 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "Fehler beim Prüfen auf Existenz der Datei für »%s.%s« (»%s« nach »%s«): %s\n" + +#: relfilenode.c:257 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "konvertiere »%s« nach »%s«\n" + +#: relfilenode.c:265 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "klone »%s« nach »%s«\n" + +#: relfilenode.c:270 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "kopiere »%s« nach »%s«\n" + +#: relfilenode.c:275 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "verknüpfe »%s« nach »%s«\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "Verbindung zur Datenbank fehlgeschlagen: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "Fehlgeschlagen, Programm wird beendet\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "führe aus: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL-Befehl fehlgeschlagen\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "konnte Versionsdatei nicht öffnen: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "konnte PG_VERSION-Datei von %s nicht parsen\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"Verbindung zur Datenbank fehlgeschlagen: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"konnte nicht mit dem Postmaster für den alten Cluster verbinden, gestartet mit dem Befehl:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"konnte nicht mit dem Postmaster für den neuen Cluster verbinden, gestartet mit dem Befehl:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl konnte den Quellserver nicht starten, oder Verbindung fehlgeschlagen\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl konnte den Zielserver nicht starten, oder Verbindung fehlgeschlagen\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "Speicher aufgebraucht\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq-Umgebungsvariable %s hat einen nicht lokalen Serverwert: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Kann nicht auf gleiche Systemkatalogversion aktualisieren, wenn\n" +"Tablespaces verwendet werden.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "Tablespace-Verzeichnis »%s« existiert nicht\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "konnte »stat« für Tablespace-Verzeichnis »%s« nicht ausführen: %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "Tablespace-Pfad »%s« ist kein Verzeichnis\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "Prüfe auf Large Objects" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "Warnung" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Large Objects. Die neue Datenbank hat eine\n" +"zusätzliche Tabelle mit den Zugriffsrechten für Large Objects. Nach\n" +"dem Upgrade wird Ihnen ein Befehl gegeben werden, mit dem die Tabelle\n" +"pg_largeobject_metadata mit den Standardrechten gefüllt wird.\n" +"\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Large Objects. Die neue Datenbank hat eine\n" +"zusätzliche Tabelle mit den Zugriffsrechten für Large Objects, sodass\n" +"Standardrechte für alle Large Objects gesetzt werden müssen. Die Datei\n" +" %s\n" +"kann mit psql als Datenbank-Superuser ausgeführt werden, um die\n" +"Standardrechte zu setzen.\n" +"\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Prüfe auf inkompatiblen Datentyp »line«" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »line« in Benutzertabellen. Das\n" +"interne Format und das Eingabe-/Ausgabeformat dieses Datentyps wurden\n" +"zwischen Ihrem alten und neuen Cluster geändert und daher kann dieser\n" +"Cluster gegenwärtig nicht aktualisiert werden. Sie können die\n" +"Problemtabellen entfernen und das Upgrade neu starten. Eine Liste der\n" +"Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Prüfe auf ungültige Benutzerspalten mit Typ »unknown«" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Ihre Installation enthält den Datentyp »unknown« in\n" +"Benutzertabellen. Dieser Datentyp ist nicht mehr in Tabellen erlaubt\n" +"und daher kann dieser Cluster gegenwärtig nicht aktualisiert\n" +"werden. Sie können die Problemtabellen entfernen und das Upgrade neu\n" +"starten. Eine Liste der Problemspalten ist in der Datei:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Prüfe auf Hash-Indexe" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Hash-Indexe. Diese Indexe haben\n" +"unterschiedliche interne Formate im alten und neuen Cluster und müssen\n" +"daher mit dem Befehl REINDEX reindiziert werden. Nach dem Upgrade\n" +"werden Sie Anweisungen zum REINDEX erhalten.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Ihre Installation enthält Hash-Indexe. Diese Indexe haben\n" +"unterschiedliche interne Formate im alten und neuen Cluster und müssen\n" +"daher mit dem Befehl REINDEX reindiziert werden. Die Datei\n" +" %s\n" +"kann mit psql als Datenbank-Superuser ausgeführt werden, um alle\n" +"ungültigen Indexe neu zu erzeugen. Bis dahin werden diese Indexe nicht\n" +"verwendet werden.\n" +"\n" diff --git a/src/bin/pg_upgrade/po/es.po b/src/bin/pg_upgrade/po/es.po new file mode 100644 index 00000000000..f5df8ce0dc9 --- /dev/null +++ b/src/bin/pg_upgrade/po/es.po @@ -0,0 +1,1750 @@ +# spanish message translation file for pg_upgrade +# +# Copyright (c) 2017-2019, PostgreSQL Global Development Group +# +# This file is distributed under the same license as the PostgreSQL package. +# Ãlvaro Herrera , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:14+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" +"Last-Translator: Ãlvaro Herrera \n" +"Language-Team: PgSQL-es-Ayuda \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Verificando Consistencia en Vivo en el Servidor Antiguo\n" +"-------------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Verificando Consistencia\n" +"------------------------\n" + +#: check.c:183 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Los clústers son compatibles*\n" + +#: check.c:189 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Si pg_upgrade falla a partir de este punto, deberá re-ejecutar initdb\n" +"en el clúster nuevo antes de continuar.\n" + +#: check.c:225 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Las estadísticas para el optimizador no son transferidas por pg_upgrade,\n" +"de manera que una vez que inicie el servidor nuevo considere ejecutar:\n" +" %s\n" +"\n" + +#: check.c:230 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Las estadísticas para el optimizador y la información de espacio libre\n" +"no son transferidas por pg_upgrade, de manera que una vez que inicie\n" +"el servidor nuevo considere ejecutar:\n" +" %s\n" +"\n" + +#: check.c:237 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Ejecutando este script se borrarán los archivos de datos del servidor antiguo:\n" +" %s\n" + +#: check.c:242 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"No se pudo crear un script para borrar los archivos de datos del servidor\n" +"antiguo, porque el directorio del clúster antiguo contiene tablespaces\n" +"o el directorio de datos del servidor nuevo. El contenido del servidor\n" +"antiguo debe ser borrado manualmente.\n" + +#: check.c:252 +#, c-format +msgid "Checking cluster versions" +msgstr "Verificando las versiones de los clústers" + +#: check.c:264 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Este programa sólo puede actualizar desde PostgreSQL versión 8.4 y posterior.\n" + +#: check.c:268 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Este programa sólo puede actualizar a PostgreSQL versión %s.\n" + +#: check.c:277 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Este programa no puede usarse para volver a versiones anteriores de PostgreSQL.\n" + +#: check.c:282 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "" +"El directorio de datos antiguo y el directorio de binarios antiguo son de\n" +"versiones diferentes.\n" + +#: check.c:285 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "" +"El directorio de datos nuevo y el directorio de binarios nuevo son de\n" +"versiones diferentes.\n" + +#: check.c:302 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Al verificar un servidor antiguo anterior a 9.1, debe especificar el port de éste.\n" + +#: check.c:306 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Al verificar servidores en caliente, los números de port antiguo y nuevo deben ser diferentes.\n" + +#: check.c:321 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "las codificaciones de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:326 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "valores lc_collate de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:329 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "valores lc_ctype de la base de datos «%s» no coinciden: antigua «%s», nueva «%s»\n" + +#: check.c:402 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "La base de datos «%s» del clúster nuevo no está vacía: se encontró la relación «%s.%s»\n" + +#: check.c:451 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Creando un script para analizar el clúster nuevo" + +#: check.c:465 check.c:593 check.c:857 check.c:936 check.c:1045 check.c:1136 +#: file.c:341 function.c:246 option.c:493 version.c:57 version.c:156 +#: version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "no se pudo abrir el archivo «%s»: %s\n" + +#: check.c:520 check.c:649 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "no se pudo agregar permisos de ejecución al archivo «%s»: %s\n" + +#: check.c:556 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"ADVERTENCIA: el directorio de datos nuevo no debería estar dentro del directorio antiguo,\n" +"por ej. %s\n" + +#: check.c:580 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"ADVERTENCIA: las ubicaciones de tablespaces definidos por el usuario\n" +"no deberían estar dentro del directorio de datos,\n" +"por ej. %s\n" + +#: check.c:590 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Creando un script para borrar el clúster antiguo" + +#: check.c:669 +#, c-format +msgid "Checking database user is the install user" +msgstr "Verificando que el usuario de base de datos es el usuario de instalación" + +#: check.c:685 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "el usuario de base de datos «%s» no es el usuario de instalación\n" + +#: check.c:696 +#, c-format +msgid "could not determine the number of users\n" +msgstr "no se pudo determinar el número de usuarios\n" + +#: check.c:704 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Sólo el usuario de instalación puede estar definido en el nuevo clúster.\n" + +#: check.c:724 +#, c-format +msgid "Checking database connection settings" +msgstr "Verificando los parámetros de conexión de bases de datos" + +#: check.c:746 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 no debe permitir conexiones, es decir su pg_database.datallowconn debe ser «false»\n" + +#: check.c:756 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Todas las bases de datos no-template0 deben permitir conexiones, es decir su pg_database.datallowconn debe ser «true»\n" + +#: check.c:781 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Verificando transacciones preparadas" + +#: check.c:790 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "El clúster de origen contiene transacciones preparadas\n" + +#: check.c:792 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "El clúster de destino contiene transacciones preparadas\n" + +#: check.c:818 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Verificando contrib/isn con discordancia en mecanismo de paso de bigint" + +#: check.c:879 check.c:958 check.c:1068 check.c:1159 function.c:268 +#: version.c:179 version.c:280 +#, c-format +msgid "fatal\n" +msgstr "fatal\n" + +#: check.c:880 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene funciones «contrib/isn» que usan el tipo de dato\n" +"bigint. Los clústers origen y destino pasan valores bigint de distintas\n" +"maneras, por lo que este clúster no puede ser actualizado en este momento.\n" +"Puede actualizar manualmente las bases de datos que contengan funcionalidad\n" +"«contrib/isn» y eliminar el módulo de la base de datos de origen.\n" +"A continuación se provee una lista de funciones problemáticas:\n" +" %s\n" +"\n" + +#: check.c:904 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Verificando tablas WITH OIDS" + +#: check.c:959 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not supported\n" +"anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene tablas declaradas WITH OIDS, que ya no es soportado.\n" +"Considere eliminar las columns oid usando\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Una lista de tablas con el problema está en el archivo:\n" +" %s\n" + +#: check.c:989 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Verificando tipos de datos reg* en datos de usuario" + +#: check.c:1069 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene uno de los tipos de dato reg* en tablas de usuario.\n" +"Estos tipos de dato hacen referencia a OIDs de sistema que no son preservados\n" +"por pg_upgrade, por lo que este clúster no puede actualmente actualizarse.\n" +"Puede eliminar las tablas problemáticas y reiniciar la actualización.\n" +"Puede encontrar una lista de columnas problemáticas en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1094 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Verificando datos de usuario en tipo «jsonb» incompatible" + +#: check.c:1160 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene alguno de los tipos de dato «jsonb» en tablas de usuario.\n" +"El formato interno de «jsonb» cambió durante 9.4 beta, de manera que este clúster\n" +"no puede ser actualizado en este momento. Puede eliminar las tablas\n" +"problemáticas y reiniciar la actualización. Una lista de columnas puede\n" +"encontrarse en el archivo:\n" +" %s\n" +"\n" + +#: check.c:1181 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Verificando roles que empiecen con «pg_»" + +#: check.c:1191 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "El clúster de origen contiene roles que empiezan con «pg_»\n" + +#: check.c:1193 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "El clúster de destino contiene roles que empiezan con «pg_»\n" + +#: check.c:1219 +#, c-format +msgid "failed to get the current locale\n" +msgstr "no se pudo obtener el «locale» actual\n" + +#: check.c:1228 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "no se pudo obtener el nombre del «locale» para «%s»\n" + +#: check.c:1234 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "no se pudo restaurar el locale antiguo «%s»\n" + +#: controldata.c:127 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "no se pudo obtener datos de control usando %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: problema de estado del clúster\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "El clúster de origen fue apagado mientras estaba en modo de recuperación. Para actualizarlo, use «rsync» como está documentado, o apáguelo siendo primario.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "El clúster de destino fue apagado mientras estaba en modo de recuperación. Para actualizarlo, use «rsync» como está documentado, o apáguelo siendo primario.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "El clúster de origen no fue apagado limpiamente.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "El clúster de destino no fue apagado limpiamente.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Al clúster de origen le falta información de estado:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Al cluster de destino le falta información de estado:\n" + +#: controldata.c:208 dump.c:51 pg_upgrade.c:336 pg_upgrade.c:373 +#: relfilenode.c:252 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: problema en pg_resetwal\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: problema de extracción de controldata\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Al clúster de origen le falta información de control requerida:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Al clúster de destino le falta información de control requerida:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " siguiente XID del último checkpoint\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " siguiente OID del último checkpoint\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " siguiente MultiXactId del último checkpoint\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " MultiXactId más antiguo del último checkpoint\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " siguiente MultiXactOffset del siguiente checkpoint\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " primer segmento de WAL después del reinicio\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " método de paso de argumentos float8\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " alineamiento máximo\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " tamaño de bloques\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " tamaño de segmento de relación grande\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " tamaño de bloque de WAL\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " tamaño de segmento de WAL\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " máximo largo de identificadores\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " máximo número de columnas indexadas\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " tamaño máximo de trozos TOAST\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " tamaño de trozos de objetos grandes\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " fechas/horas son enteros?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " versión del checksum de datos\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "No se puede continuar sin la información de control requerida. Terminando\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"Alineamientos de pg_controldata antiguo y nuevo no son válidos o no coinciden\n" +"Seguramente un clúster es 32-bit y el otro es 64-bit\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "Los tamaños de bloque antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "El tamaño máximo de segmento de relación antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "El tamaño de bloques de WAL antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "El tamaño de segmentos de WAL antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "Los máximos largos de identificador antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "La cantidad máxima de columnas indexadas antigua y nueva no son válidos o no coinciden\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "Los máximos de trozos TOAST antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "Los tamaños de trozos de objetos grandes antiguo y nuevo no son válidos o no coinciden\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "Los tipos de almacenamiento de fecha/hora antiguo y nuevo no coinciden\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "El clúster antiguo no usa checksums de datos pero el nuevo sí\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "El clúster antiguo usa checksums de datos pero el nuevo no\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "Las versiones de checksum de datos antigua y nueva no coinciden\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Agregando el sufijo «.old» a global/pg_control" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "No se pudo renombrar %s a %s.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Si desea iniciar el clúster antiguo, necesitará eliminar el sufijo\n" +"«.old» de %s/global/pg_control.old.\n" +"Puesto que se usó el modo «link», el clúster antiguo no puede usarse\n" +"en forma segura después de que el clúster nuevo haya sido iniciado.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "Creando el volcado de objetos globales" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Creando el volcado de esquemas de bases de datos\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "no se pudo obtener datos de versión de pg_ctl usando %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "no se pudo obtener la salida de versión de pg_ctl de %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "orden demasiado larga\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:105 option.c:227 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "no se pudo escribir al archivo de log «%s»\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*falló*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Hubo problemas ejecutando «%s»\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Consulte las últimas línea de «%s» o «%s» para\n" +"saber la causa probable de la falla.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Consulte las últimas líneas de «%s» para saber\n" +"la causa probable de la falla.\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "no se pudo abrir el archivo «%s» para lectura: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Debe tener privilegios de lectura y escritura en el directorio actual.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "la comprobación de «%s» falló: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "«%s» no es un directorio\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "La comprobación de «%s» falló: no es un archivo regular\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "La comprobación de «%s» falló: no se puede leer el archivo (permiso denegado)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "La comprobación de «%s» falló: no se puede ejecutar (permiso denegado)\n" + +#: file.c:48 file.c:66 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se clonaba la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "error mientras se clonaba la relación «%s.%s»: no se pudo abrir el archivo «%s»: %s\n" + +#: file.c:60 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "error mientras se clonaba la relación «%s.%s»: no se pudo crear el archivo «%s»: %s\n" + +#: file.c:92 file.c:195 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo leer el archivo «%s»: %s\n" + +#: file.c:97 file.c:204 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo crear el archivo «%s»: %s\n" + +#: file.c:111 file.c:228 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo leer el archivo «%s»: %s\n" + +#: file.c:123 file.c:306 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo escribir el archivo «%s»: %s\n" + +#: file.c:137 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se copiaba la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:156 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se creaba el link para la relación «%s.%s» («%s» a «%s»): %s\n" + +#: file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "error mientras se copiaba la relación «%s.%s»: no se pudo hacer stat a «%s»: %s\n" + +#: file.c:231 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "error mientras se copiaba la relación «%s.%s»: se encontró una página parcial en el archivo «%s»\n" + +#: file.c:333 file.c:350 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "no se pudo clonar el archivo entre los directorios viejo y nuevo: %s\n" + +#: file.c:346 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "no se pudo crear el archivo «%s»: %s\n" + +#: file.c:357 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "el clonado de archivos no está soportado en esta plataforma\n" + +#: file.c:374 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"No se pudo crear un link duro entre los directorios de datos nuevo y antiguo: %s\n" +"En modo link los directorios de dato nuevo y antiguo deben estar en el mismo sistema de archivos.\n" + +#: function.c:116 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"El clúster antiguo tiene la función «plpython_call_handler» definida\n" +"en el esquema «public» que es un duplicado de la que está definida en\n" +"el esquema «pg_catalog». Puede confirmar esto ejecutando lo siguiente\n" +"en psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"La versión del esquema «public» de esta función fue creada por una\n" +"instalación pre-8.1 de plpython, y debe eliminarse para que pg_upgrade\n" +"pueda completar puesto que hace referencia a un archivo objeto compartido\n" +"«plpython» ahora obsoleto. Puede eliminar la versión del esquema «public»\n" +"de esta función ejecutando la siguiente orden:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"en cada base de datos afectada:\n" +"\n" + +#: function.c:134 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:144 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Elimine las funciones problemáticas del clúster antiguo para continuar.\n" + +#: function.c:191 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Verificando la presencia de las bibliotecas requeridas" + +#: function.c:248 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "no se pudo cargar la biblioteca «%s»: %s" + +#: function.c:259 info.c:633 +#, c-format +msgid "Database: %s\n" +msgstr "Base de datos: %s\n" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación hace referencia a bibliotecas que no están en la nueva\n" +"instalación. Puede agregar estar bibliotecas la instalación nueva, o\n" +"eliminar las funciones que las utilizan de la versión antigua. Un listado\n" +"de las bibliotecas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Los nombres de relación para OID %u en la base de datos «%s» no coinciden: nombre antiguo «%s.%s», nombre nuevo «%s.%s»\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "No hubo coincidencia en las tablas nueva y antigua en la base de datos «%s»\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " que es un índice en «%s.%s»" + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr " que es un índice en el OID %u" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " que es la tabla TOAST para «%s.%s»" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " que es la tabla TOAST para el OID %u" + +#: info.c:276 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "" +"No se encontró equivalente en el clúster antiguo para la relación con OID %u\n" +"en la base de datos «%s» en el clúster nuevo: %s\n" + +#: info.c:279 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "" +"No se encontró equivalente en el clúster nuevo para la relación con OID %u\n" +"en la base de datos «%s» en el clúster antiguo: %s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "mapeos para la base de datos «%s»:\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u a %u\n" + +#: info.c:299 info.c:635 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"bases de datos de origen:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"bases de datos de destino:\n" + +#: info.c:646 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: no puede ejecutarse como root\n" + +#: option.c:174 +#, c-format +msgid "invalid old port number\n" +msgstr "número de puerto antiguo no válido\n" + +#: option.c:182 +#, c-format +msgid "invalid new port number\n" +msgstr "número de puerto nuevo no válido\n" + +#: option.c:208 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Ejecutando en modo verboso\n" + +#: option.c:217 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Pruebe «%s --help» para mayor información.\n" + +#: option.c:252 +msgid "old cluster binaries reside" +msgstr "residen los binarios del clúster antiguo" + +#: option.c:254 +msgid "new cluster binaries reside" +msgstr "residen los binarios del clúster nuevo" + +#: option.c:256 +msgid "old cluster data resides" +msgstr "residen los datos del clúster antiguo" + +#: option.c:258 +msgid "new cluster data resides" +msgstr "residen los datos del clúster nuevo" + +#: option.c:260 +msgid "sockets will be created" +msgstr "se crearán los sockets" + +#: option.c:277 option.c:371 +#, c-format +msgid "could not determine current directory\n" +msgstr "no se pudo identificar el directorio actual\n" + +#: option.c:280 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"no se puede ejecutar pg_upgrade desde dentro del directorio de datos\n" +"del clúster nuevo en Windows\n" + +#: option.c:289 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "pg_upgrado actualiza un clúster PostgreSQL a una versión «mayor» diferente.\n" + +#: option.c:290 +#, c-format +msgid "Usage:\n" +msgstr "Empleo:\n" + +#: option.c:291 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [OPCIÓN]...\n" +"\n" + +#: option.c:292 +#, c-format +msgid "Options:\n" +msgstr "Opciones:\n" + +#: option.c:293 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR directorio de ejecutables del clúster antiguo\n" + +#: option.c:294 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINDIR directorio de ejecutables del clúster nuevo\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check sólo verificar clústers, no cambiar datos\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR directorio de datos del clúster antiguo\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR directorio de datos del clúster nuevo\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs número de procesos o hilos simultáneos a usar\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link enlazar (link) archivos en vez de copiarlos\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPCIONES opciones a pasar al servidor antiguo\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPCIONES opciones a pasar al servidor nuevo\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PUERTO número de puerto del clúster antiguo (def. %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PUERTO número de puerto del clúster nuevo (def. %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain preservar archivos SQL y logs en caso de éxito\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default CWD)\n" +msgstr " -s, --socketdir=DIR directorio de sockets a usar (default CWD)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NOMBRE superusuario del clúster (def. «%s»)\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose activar registro interno verboso\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version mostrar información de versión y salir\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " --clone clonar los archivos en vez de copiarlos\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help mostrar esta ayuda y salir\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Antes de ejecutar pg_upgrade, debe:\n" +" crear el nuevo clúster de la base de datos (usando la nueva versión de initdb)\n" +" apagar el postmaster que atiende al clúster antiguo\n" +" apagar el postmaster que atiende al clúster nuevo\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"Cuando ejecute pg_ugpade, debe proveer la siguiente información:\n" +" el directorio de datos del clúster antiguo (-d DATADIR)\n" +" el directorio de datos del clúster nuevo (-D DATADIR)\n" +" el directorio «bin» para la versión antigua (-b BINDIR)\n" +" el directorio «bin» para la versión nueva (-B BINDIR)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Por ejemplo:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"o\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=clusterAntiguo/data\n" +" $ export PGDATANEW=clusterNuevo/data\n" +" $ export PGBINOLD=clusterAntiguo/bin\n" +" $ export PGBINNEW=clusterNuevo/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=clusterAntiguo/data\n" +" C:\\> set PGDATANEW=clusterNuevo/data\n" +" C:\\> set PGBINOLD=clusterAntiguo/bin\n" +" C:\\> set PGBINNEW=clusterNuevo/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Reporte errores a .\n" + +#: option.c:375 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Debe identificar el directorio donde %s.\n" +"Por favor use la opción %s o la variable de ambiente %s.\n" + +#: option.c:427 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Buscando el directorio de datos real para el clúster de origen" + +#: option.c:429 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Buscando el directorio de datos real para el clúster de destino" + +#: option.c:441 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "no se pudo obtener el directorio de datos usando %s: %s\n" + +#: option.c:501 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "no se pudo leer la línea %d del archivo «%s»: %s\n" + +#: option.c:519 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "número de port entregado por el usuario %hu corregido a %hu\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "no se pudo crear el proceso hijo: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "no se pudo crear el thread: %s\n" + +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() fallida: %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "el proceso hijo terminó anormalmente: estado %d\n" + +#: parallel.c:324 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "el thread terminó anormalmente: %s\n" + +#: pg_upgrade.c:109 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "no se pudo obtener los permisos del directorio «%s»: %s\n" + +#: pg_upgrade.c:126 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Llevando a cabo el Upgrade\n" +"--------------------------\n" + +#: pg_upgrade.c:169 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Seteando siguiente OID para el nuevo clúster" + +#: pg_upgrade.c:176 +#, c-format +msgid "Sync data directory to disk" +msgstr "Sincronizando directorio de datos a disco" + +#: pg_upgrade.c:188 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Actualización Completa\n" +"----------------------\n" + +#: pg_upgrade.c:234 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Parece haber un postmaster sirviendo el clúster antiguo.\n" +"Por favor detenga ese postmaster e inténtelo nuevamente.\n" + +#: pg_upgrade.c:247 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Parece haber un postmaster sirviendo el clúster nuevo.\n" +"Por favor detenga ese postmaster e inténtelo nuevamente.\n" + +#: pg_upgrade.c:253 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: no se pudo encontrar el ejecutable propio\n" + +#: pg_upgrade.c:270 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analizando todas las filas en el clúster nuevo" + +#: pg_upgrade.c:283 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Congelando todas las filas en el nuevo clúster" + +#: pg_upgrade.c:303 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Restaurando objetos globales en el nuevo clúster" + +#: pg_upgrade.c:318 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Restaurando esquemas de bases de datos en el clúster nuevo\n" + +#: pg_upgrade.c:424 +#, c-format +msgid "Deleting files from new %s" +msgstr "Eliminando archivos del nuevo %s" + +#: pg_upgrade.c:428 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "no se pudo eliminar directorio «%s»\n" + +#: pg_upgrade.c:447 +#, c-format +msgid "Copying old %s to new server" +msgstr "Copiando el %s antiguo al nuevo servidor" + +#: pg_upgrade.c:474 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Seteando el ID de transacción y «época» siguientes en el nuevo clúster" + +#: pg_upgrade.c:504 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Seteando el multixact ID y offset siguientes en el nuevo clúster" + +#: pg_upgrade.c:528 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Seteando el multixact ID más antiguo en el nuevo clúster" + +#: pg_upgrade.c:548 +#, c-format +msgid "Resetting WAL archives" +msgstr "Reseteando los archivos de WAL" + +#: pg_upgrade.c:591 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Seteando contadores frozenxid y minmxid en el clúster nuevo" + +#: pg_upgrade.c:593 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Seteando contador minmxid en el clúster nuevo" + +#: relfilenode.c:36 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Clonando archivos de relaciones de usuario\n" + +#: relfilenode.c:39 +#, c-format +msgid "Copying user relation files\n" +msgstr "Copiando archivos de relaciones de usuario\n" + +#: relfilenode.c:42 +#, c-format +msgid "Linking user relation files\n" +msgstr "Enlazando archivos de relaciones de usuario\n" + +#: relfilenode.c:118 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "la base de datos «%s» no se encontró en el clúster nuevo\n" + +#: relfilenode.c:239 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "error mientras se comprobaba la existencia del archivo «%s.%s» («%s» a «%s»); %s\n" + +#: relfilenode.c:257 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "reescribiendo «%s» a «%s»\n" + +#: relfilenode.c:265 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "clonando «%s» a «%s»\n" + +#: relfilenode.c:270 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "copiando «%s» a «%s»\n" + +#: relfilenode.c:275 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "enlazando «%s» a «%s»\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "falló la conexión a la base de datos: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "Falló, saliendo\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "ejecutando: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"Orden SQL falló\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "no se pudo abrir el archivo de versión: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "no se pudo interpretar el archivo PG_VERSION de %s\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"falló la conexión a la base de datos: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"no se pudo conectar al postmaster de origen iniciado con la orden:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"no se pudo conectar al postmaster de destino iniciado con la orden:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl no pudo iniciar el servidor de origen, o la conexión falló\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl no pudo iniciar el servidor de destino, o la conexión falló\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "la variable de ambiente libpq %s tiene un valor de servidor no-local: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"No se puede actualizar desde el mismo número de versión del catálogo\n" +"cuando se están usando tablespaces.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "el directorio de tablespace «%s» no existe\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "no se pudo hace stat al directorio de tablespace «%s»: %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "la ruta de tablespace «%s» no es un directorio\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "éxito" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "Buscando objetos grandes" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "atención" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene objetos grandes. La base de datos nueva\n" +"tiene una tabla adicional de permisos de objetos grandes. Después de\n" +"actualizar, se le dará una instrucción para poblar la tabla\n" +"pg_largeobject_metadata con privilegios por omisión.\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene objetos grandes. La base de datos nueva tiene\n" +"una tabla adicional de permisos de objetos grandes, por lo que deben ser\n" +"definidos permisos por omisión para todos los objetos grandes. El archivo\n" +" %s\n" +"cuando se ejecute en psql con el superusuario de la base de datos\n" +"establecerá los privilegios por omisión.\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Verificando datos de usuario de tipo «line» incompatible" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo de dato «line» en tablas de usuario. Este\n" +"tipo de dato cambió su formato interno y de entrada/salida entre las\n" +"versiones de sus clústers antiguo y nuevo, por lo que este clúster no puede\n" +"actualmente ser actualizado. Puede eliminar las tablas problemáticas y\n" +"reiniciar la actualización. Un listado de las columnas problemáticas está\n" +"en el archivo:\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Verificando columnas de usuario del tipo no válido «unknown»" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Su instalación contiene el tipo «unknown» en tablas de usuario. Este tipo\n" +"ya no es permitido en tablas, por lo que este clúster no puede ser actualizado.\n" +"Puede elimiar las tablas y reiniciar la actualización.\n" +"Un listado de columnas problemáticas está en el archivo:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Verificando índices hash" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene índices hash. Estos índices tienen formato interno\n" +"distinto entre su versión nueva y antigua, por lo que deben ser reindexados\n" +"con la orden REINDEX. Después de la actualización, se le entregarán\n" +"instrucciones de REINDEX.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Su instalación contiene índices hash. Estos índices tienen formato interno\n" +"distinto entre su versión nueva y antigua, por lo que deben ser reindexados\n" +"con la orden REINDEX. El archivo\n" +" %s\n" +"cuando se ejecute en psql con el superusuario de la base de datos recreará\n" +"los índices no válidos; hasta entonces, ninguno de esos índices será usado.\n" +"\n" diff --git a/src/bin/pg_upgrade/po/fr.po b/src/bin/pg_upgrade/po/fr.po index 0e0198212cb..7537afd6a8e 100644 --- a/src/bin/pg_upgrade/po/fr.po +++ b/src/bin/pg_upgrade/po/fr.po @@ -5,39 +5,37 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-28 18:45+0000\n" -"PO-Revision-Date: 2017-07-29 09:33+0200\n" +"Project-Id-Version: pg_upgrade (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:16+0000\n" +"PO-Revision-Date: 2019-05-17 15:18+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.2.1\n" -#: check.c:65 +#: check.c:67 #, c-format -msgid "Performing Consistency Checks on Old Live Server\n" -msgstr "Exécution de tests de cohérence sur l'ancien serveur\n" - -#: check.c:66 -#, c-format -msgid "------------------------------------------------\n" -msgstr "------------------------------------------------\n" - -#: check.c:70 -#, c-format -msgid "Performing Consistency Checks\n" -msgstr "Exécution de tests de cohérence\n" +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Exécution de tests de cohérence sur l'ancien serveur\n" +"----------------------------------------------------\n" -#: check.c:71 +#: check.c:73 #, c-format -msgid "-----------------------------\n" -msgstr "-----------------------------\n" +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Exécution de tests de cohérence\n" +"-------------------------------\n" -#: check.c:164 +#: check.c:183 #, c-format msgid "" "\n" @@ -46,7 +44,7 @@ msgstr "" "\n" "*Les instances sont compatibles*\n" -#: check.c:170 +#: check.c:189 #, c-format msgid "" "\n" @@ -57,7 +55,7 @@ msgstr "" "Si pg_upgrade échoue après cela, vous devez ré-exécuter initdb\n" "sur la nouvelle instance avant de continuer.\n" -#: check.c:206 +#: check.c:225 #, c-format msgid "" "Optimizer statistics are not transferred by pg_upgrade so,\n" @@ -70,7 +68,7 @@ msgstr "" " %s\n" "\n" -#: check.c:211 +#: check.c:230 #, c-format msgid "" "Optimizer statistics and free space information are not transferred\n" @@ -84,7 +82,7 @@ msgstr "" " %s\n" "\n" -#: check.c:218 +#: check.c:237 #, c-format msgid "" "Running this script will delete the old cluster's data files:\n" @@ -94,7 +92,7 @@ msgstr "" "instance :\n" " %s\n" -#: check.c:223 +#: check.c:242 #, c-format msgid "" "Could not create a script to delete the old cluster's data files\n" @@ -104,180 +102,224 @@ msgid "" msgstr "" "N'a pas pu créer un script pour supprimer les fichiers de données\n" "de l'ancienne instance parce que les tablespaces définis par l'utilisateur\n" -"ou le répertoire de données de la nouvelle instance existent dans le répertoire\n" -"de l'ancienne instance. Le contenu de l'ancienne instance doit être supprimé\n" +"ou le répertoire de données de la nouvelle instance existent dans le " +"répertoire\n" +"de l'ancienne instance. Le contenu de l'ancienne instance doit être " +"supprimé\n" "manuellement.\n" -#: check.c:233 +#: check.c:252 #, c-format msgid "Checking cluster versions" msgstr "Vérification des versions des instances" -#: check.c:245 +#: check.c:264 #, c-format msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" -msgstr "Cet outil peut seulement mettre à jour les versions 8.4 et ultérieures de PostgreSQL.\n" +msgstr "" +"Cet outil peut seulement mettre à jour les versions 8.4 et ultérieures de " +"PostgreSQL.\n" -#: check.c:249 +#: check.c:268 #, c-format msgid "This utility can only upgrade to PostgreSQL version %s.\n" -msgstr "Cet outil peut seulement mettre à jour vers la version %s de PostgreSQL.\n" - -#: check.c:258 -#, c-format -msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" -msgstr "Cet outil ne peut pas être utilisé pour mettre à jour vers des versions majeures plus anciennes de PostgreSQL.\n" +msgstr "" +"Cet outil peut seulement mettre à jour vers la version %s de PostgreSQL.\n" -#: check.c:263 +#: check.c:277 #, c-format -msgid "Old cluster data and binary directories are from different major versions.\n" -msgstr "Les répertoires des données de l'ancienne instance et des binaires sont de versions majeures différentes.\n" +msgid "" +"This utility cannot be used to downgrade to older major PostgreSQL " +"versions.\n" +msgstr "" +"Cet outil ne peut pas être utilisé pour mettre à jour vers des versions " +"majeures plus anciennes de PostgreSQL.\n" -#: check.c:266 +#: check.c:282 #, c-format -msgid "New cluster data and binary directories are from different major versions.\n" -msgstr "Les répertoires des données de la nouvelle instance et des binaires sont de versions majeures différentes.\n" +msgid "" +"Old cluster data and binary directories are from different major versions.\n" +msgstr "" +"Les répertoires des données de l'ancienne instance et des binaires sont de " +"versions majeures différentes.\n" -#: check.c:283 +#: check.c:285 #, c-format msgid "" -"This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" -"because of backend API changes made during development.\n" +"New cluster data and binary directories are from different major versions.\n" msgstr "" -"Cet outil peut seulement mettre à jour à partir de la version 9.0 de PostgreSQL (après le 11 janvier 2010)\n" -"à cause de changements dans l'API du moteur fait lors du développement.\n" +"Les répertoires des données de la nouvelle instance et des binaires sont de " +"versions majeures différentes.\n" -#: check.c:289 +#: check.c:302 #, c-format -msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" -msgstr "Lors de la vérification d'un serveur antérieur à la 9.1, vous devez spécifier le numéro de port de l'ancien serveur.\n" +msgid "" +"When checking a pre-PG 9.1 live old server, you must specify the old " +"server's port number.\n" +msgstr "" +"Lors de la vérification d'un serveur antérieur à la 9.1, vous devez " +"spécifier le numéro de port de l'ancien serveur.\n" -#: check.c:293 +#: check.c:306 #, c-format -msgid "When checking a live server, the old and new port numbers must be different.\n" -msgstr "Lors de la vérification d'un serveur en production, l'ancien numéro de port doit être différent du nouveau.\n" +msgid "" +"When checking a live server, the old and new port numbers must be " +"different.\n" +msgstr "" +"Lors de la vérification d'un serveur en production, l'ancien numéro de port " +"doit être différent du nouveau.\n" -#: check.c:308 +#: check.c:321 #, c-format msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -msgstr "les encodages de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" +msgstr "" +"les encodages de la base de données « %s » ne correspondent pas : ancien « " +"%s », nouveau « %s »\n" -#: check.c:313 +#: check.c:326 #, c-format -msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -msgstr "les valeurs de lc_collate de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" +msgid "" +"lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"les valeurs de lc_collate de la base de données « %s » ne correspondent " +"pas : ancien « %s », nouveau « %s »\n" -#: check.c:316 +#: check.c:329 #, c-format -msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" -msgstr "les valeurs de lc_ctype de la base de données « %s » ne correspondent pas : ancien « %s », nouveau « %s »\n" +msgid "" +"lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "" +"les valeurs de lc_ctype de la base de données « %s » ne correspondent pas : " +"ancien « %s », nouveau « %s »\n" -#: check.c:389 +#: check.c:402 #, c-format -msgid "New cluster database \"%s\" is not empty\n" -msgstr "La nouvelle instance « %s » n'est pas vide\n" +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "" +"La nouvelle instance « %s » n'est pas vide : relation « %s.%s » trouvée\n" -#: check.c:436 +#: check.c:451 #, c-format msgid "Creating script to analyze new cluster" msgstr "Création d'un script pour analyser la nouvelle instance" -#: check.c:450 check.c:578 check.c:842 check.c:945 check.c:1036 function.c:253 -#: version.c:57 version.c:156 version.c:257 version.c:339 +#: check.c:465 check.c:593 check.c:857 check.c:936 check.c:1045 check.c:1136 +#: file.c:341 function.c:246 option.c:493 version.c:57 version.c:156 +#: version.c:257 version.c:339 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier « %s » : %s\n" -#: check.c:505 check.c:634 +#: check.c:520 check.c:649 #, c-format msgid "could not add execute permission to file \"%s\": %s\n" -msgstr "n'a pas pu ajouter les droits d'exécution pour le fichier « %s » : %s\n" +msgstr "" +"n'a pas pu ajouter les droits d'exécution pour le fichier « %s » : %s\n" -#: check.c:541 +#: check.c:556 #, c-format msgid "" "\n" -"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +"WARNING: new data directory should not be inside the old data directory, e." +"g. %s\n" msgstr "" "\n" -"AVERTISSEMENT : le nouveau répertoire de données ne doit pas être à l'intérieur de l'ancien répertoire de données, %s\n" +"AVERTISSEMENT : le nouveau répertoire de données ne doit pas être à " +"l'intérieur de l'ancien répertoire de données, %s\n" -#: check.c:565 +#: check.c:580 #, c-format msgid "" "\n" -"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +"WARNING: user-defined tablespace locations should not be inside the data " +"directory, e.g. %s\n" msgstr "" "\n" -"AVERTISSEMENT : les emplacements de tablespaces utilisateurs ne doivent pas être à l'intérieur du répertoire de données, %s\n" +"AVERTISSEMENT : les emplacements de tablespaces utilisateurs ne doivent pas " +"être à l'intérieur du répertoire de données, %s\n" -#: check.c:575 +#: check.c:590 #, c-format msgid "Creating script to delete old cluster" msgstr "Création du script pour supprimer l'ancienne instance" -#: check.c:654 +#: check.c:669 #, c-format msgid "Checking database user is the install user" -msgstr "Vérification que l'utilisateur de la base de données est l'utilisateur d'installation" +msgstr "" +"Vérification que l'utilisateur de la base de données est l'utilisateur " +"d'installation" -#: check.c:670 +#: check.c:685 #, c-format msgid "database user \"%s\" is not the install user\n" -msgstr "l'utilisateur de la base de données « %s » n'est pas l'utilisateur d'installation\n" +msgstr "" +"l'utilisateur de la base de données « %s » n'est pas l'utilisateur " +"d'installation\n" -#: check.c:681 +#: check.c:696 #, c-format msgid "could not determine the number of users\n" msgstr "n'a pas pu déterminer le nombre d'utilisateurs\n" -#: check.c:689 +#: check.c:704 #, c-format msgid "Only the install user can be defined in the new cluster.\n" -msgstr "Seul l'utilisateur d'installation peut être défini dans la nouvelle instance.\n" +msgstr "" +"Seul l'utilisateur d'installation peut être défini dans la nouvelle " +"instance.\n" -#: check.c:709 +#: check.c:724 #, c-format msgid "Checking database connection settings" msgstr "Vérification des paramètres de connexion de la base de données" -#: check.c:731 +#: check.c:746 #, c-format -msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" -msgstr "template0 ne doit pas autoriser les connexions, ie pg_database.datallowconn doit valoir false\n" +msgid "" +"template0 must not allow connections, i.e. its pg_database.datallowconn must " +"be false\n" +msgstr "" +"template0 ne doit pas autoriser les connexions, ie pg_database.datallowconn " +"doit valoir false\n" -#: check.c:741 +#: check.c:756 #, c-format -msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" -msgstr "Toutes les bases de données, autre que template0, doivent autoriser les connexions, ie pg_database.datallowconn doit valoir true\n" +msgid "" +"All non-template0 databases must allow connections, i.e. their pg_database." +"datallowconn must be true\n" +msgstr "" +"Toutes les bases de données, autre que template0, doivent autoriser les " +"connexions, ie pg_database.datallowconn doit valoir true\n" -#: check.c:766 +#: check.c:781 #, c-format msgid "Checking for prepared transactions" msgstr "Vérification des transactions préparées" -#: check.c:775 +#: check.c:790 #, c-format msgid "The source cluster contains prepared transactions\n" msgstr "L'instance source contient des transactions préparées\n" -#: check.c:777 +#: check.c:792 #, c-format msgid "The target cluster contains prepared transactions\n" msgstr "L'instance cible contient des transactions préparées\n" -#: check.c:803 +#: check.c:818 #, c-format msgid "Checking for contrib/isn with bigint-passing mismatch" -msgstr "Vérification de contrib/isn avec une différence sur le passage des bigint" +msgstr "" +"Vérification de contrib/isn avec une différence sur le passage des bigint" -#: check.c:864 check.c:968 check.c:1059 function.c:268 version.c:179 -#: version.c:280 +#: check.c:879 check.c:958 check.c:1068 check.c:1159 function.c:268 +#: version.c:179 version.c:280 #, c-format msgid "fatal\n" msgstr "fatal\n" -#: check.c:865 +#: check.c:880 #, c-format msgid "" "Your installation contains \"contrib/isn\" functions which rely on the\n" @@ -289,22 +331,50 @@ msgid "" " %s\n" "\n" msgstr "" -"Votre installation contient les fonctions « contrib/isn » qui se basent sur le\n" -"type de données bigint. Vos ancienne et nouvelle instances passent les valeurs\n" +"Votre installation contient les fonctions « contrib/isn » qui se basent sur " +"le\n" +"type de données bigint. Vos ancienne et nouvelle instances passent les " +"valeurs\n" "bigint différemment, donc cette instance ne peut pas être mise à jour\n" "actuellement. Vous pouvez mettre à jour manuellement vos bases de données\n" -"qui utilisent « contrib/isn » et supprimer « contrib/isn » de l'ancienne instance\n" -"pour relancer la mise à jour. Une liste des fonctions problématiques est disponible\n" +"qui utilisent « contrib/isn » et supprimer « contrib/isn » de l'ancienne " +"instance\n" +"pour relancer la mise à jour. Une liste des fonctions problématiques est " +"disponible\n" "dans le fichier :\n" " %s\n" "\n" -#: check.c:897 +#: check.c:904 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Vérification des tables WITH OIDS" + +#: check.c:959 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not " +"supported\n" +"anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Votre installation contient des tables déclarées avec WITH OIDS, ce qui " +"n'est plus supporté.\n" +"Pensez à supprimer la colonne oid en utilisant\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"Une liste des tables ayant ce problème se trouve dans le fichier :\n" +" %s\n" +"\n" + +#: check.c:989 #, c-format -msgid "Checking for reg* system OID user data types" -msgstr "Vérification des types de données utilisateur avec un OID système reg*" +msgid "Checking for reg* data types in user tables" +msgstr "Vérification des types de données reg* dans les tables utilisateurs" -#: check.c:969 +#: check.c:1069 #, c-format msgid "" "Your installation contains one of the reg* data types in user tables.\n" @@ -318,278 +388,376 @@ msgstr "" "Votre installation contient un des types de données reg* dans les tables\n" "utilisateurs. Ces types de données référencent des OID système qui ne sont\n" "pas préservés par pg_upgrade, donc cette instance ne peut pas être mise à\n" -"jour actuellement. Vous pouvez supprimer les tables problématiques et relancer\n" -"la mise à jour. Une liste des colonnes problématiques est disponible dans le\n" +"jour actuellement. Vous pouvez supprimer les tables problématiques et " +"relancer\n" +"la mise à jour. Une liste des colonnes problématiques est disponible dans " +"le\n" "fichier :\n" " %s\n" "\n" -#: check.c:994 +#: check.c:1094 #, c-format -msgid "Checking for JSONB user data types" -msgstr "Vérification des types de données utilisateur JSONB" +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Vérification des types de données « jsonb » incompatibles" -#: check.c:1060 +#: check.c:1160 #, c-format msgid "" -"Your installation contains one of the JSONB data types in user tables.\n" -"The internal format of JSONB changed during 9.4 beta so this cluster cannot currently\n" -"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster " +"cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A " +"list\n" "of the problem columns is in the file:\n" " %s\n" "\n" msgstr "" -"Votre installation contient un des types de données JSONB dans les tables utilisateurs.\n" -"Le format interne de JSONB a changé lors du développement de la version 9.4 beta, donc\n" -"cette instance ne peut pas être mise à jour actuellement. Vous pouvez supprimer les\n" -"tables problématiques et relancer la mise à jour. Une liste des colonnes problématiques\n" +"Votre installation contient un des types de données JSONB dans les tables " +"utilisateurs.\n" +"Le format interne de JSONB a changé lors du développement de la version 9.4 " +"beta, donc\n" +"cette instance ne peut pas être mise à jour actuellement. Vous pouvez " +"supprimer les\n" +"tables problématiques et relancer la mise à jour. Une liste des colonnes " +"problématiques\n" "est disponible dans le fichier :\n" " %s\n" "\n" -#: check.c:1081 +#: check.c:1181 #, c-format -msgid "Checking for roles starting with 'pg_'" +msgid "Checking for roles starting with \"pg_\"" msgstr "Vérification des rôles commençant avec « pg_ »" -#: check.c:1091 +#: check.c:1191 #, c-format -msgid "The source cluster contains roles starting with 'pg_'\n" +msgid "The source cluster contains roles starting with \"pg_\"\n" msgstr "L'instance source contient des rôles commençant avec « pg_ »\n" -#: check.c:1093 +#: check.c:1193 #, c-format -msgid "The target cluster contains roles starting with 'pg_'\n" +msgid "The target cluster contains roles starting with \"pg_\"\n" msgstr "L'instance cible contient des rôles commençant avec « pg_ »\n" -#: check.c:1119 +#: check.c:1219 #, c-format msgid "failed to get the current locale\n" msgstr "a échoué pour obtenir la locale courante\n" -#: check.c:1128 +#: check.c:1228 #, c-format msgid "failed to get system locale name for \"%s\"\n" msgstr "a échoué pour obtenir le nom de la locale système « %s »\n" -#: check.c:1134 +#: check.c:1234 #, c-format msgid "failed to restore old locale \"%s\"\n" msgstr "a échoué pour restaurer l'ancienne locale « %s »\n" -#: controldata.c:128 +#: controldata.c:127 controldata.c:194 #, c-format msgid "could not get control data using %s: %s\n" msgstr "" "n'a pas pu obtenir les données de contrôle en utilisant %s : %s\n" "\n" -#: controldata.c:141 dump.c:59 pg_upgrade.c:321 relfilenode.c:244 util.c:80 +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d : problème sur l'état de l'instance de la base de données\n" + +#: controldata.c:155 +#, c-format +msgid "" +"The source cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"L'instance source a été arrêté alors qu'elle était en mode restauration. " +"Pour mettre à jour, utilisez « rsync » comme documenté ou arrêtez-la en tant " +"que serveur primaire.\n" + +#: controldata.c:157 +#, c-format +msgid "" +"The target cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"L'instance cible a été arrêté alors qu'elle était en mode restauration. Pour " +"mettre à jour, utilisez « rsync » comme documenté ou arrêtez-la en tant que " +"serveur primaire.\n" + +#: controldata.c:162 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "L'instance source n'a pas été arrêtée proprement.\n" + +#: controldata.c:164 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "L'instance cible n'a pas été arrêtée proprement.\n" + +#: controldata.c:175 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "" +"Il manque certaines informations d'état requises sur l'instance source :\n" + +#: controldata.c:177 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "" +"Il manque certaines informations d'état requises sur l'instance cible :\n" + +#: controldata.c:207 dump.c:51 pg_upgrade.c:336 pg_upgrade.c:373 +#: relfilenode.c:252 util.c:80 #, c-format msgid "%s" msgstr "%s" -#: controldata.c:148 +#: controldata.c:214 #, c-format msgid "%d: pg_resetwal problem\n" msgstr "%d : problème avec pg_resetwal\n" -#: controldata.c:158 controldata.c:168 controldata.c:179 controldata.c:190 -#: controldata.c:201 controldata.c:220 controldata.c:231 controldata.c:242 -#: controldata.c:253 controldata.c:264 controldata.c:275 controldata.c:278 -#: controldata.c:282 controldata.c:292 controldata.c:304 controldata.c:315 -#: controldata.c:326 controldata.c:337 controldata.c:348 controldata.c:359 -#: controldata.c:370 controldata.c:381 controldata.c:392 controldata.c:403 -#: controldata.c:414 +#: controldata.c:224 controldata.c:234 controldata.c:245 controldata.c:256 +#: controldata.c:267 controldata.c:286 controldata.c:297 controldata.c:308 +#: controldata.c:319 controldata.c:330 controldata.c:341 controldata.c:344 +#: controldata.c:348 controldata.c:358 controldata.c:370 controldata.c:381 +#: controldata.c:392 controldata.c:403 controldata.c:414 controldata.c:425 +#: controldata.c:436 controldata.c:447 controldata.c:458 controldata.c:469 +#: controldata.c:480 #, c-format msgid "%d: controldata retrieval problem\n" msgstr "%d : problème de récupération des controldata\n" -#: controldata.c:479 +#: controldata.c:545 #, c-format msgid "The source cluster lacks some required control information:\n" -msgstr "Il manque certaines informations de contrôle requises sur l'instance source :\n" +msgstr "" +"Il manque certaines informations de contrôle requises sur l'instance " +"source :\n" -#: controldata.c:482 +#: controldata.c:548 #, c-format msgid "The target cluster lacks some required control information:\n" -msgstr "Il manque certaines informations de contrôle requises sur l'instance cible :\n" +msgstr "" +"Il manque certaines informations de contrôle requises sur l'instance " +"cible :\n" -#: controldata.c:485 +#: controldata.c:551 #, c-format msgid " checkpoint next XID\n" msgstr " XID du prochain checkpoint\n" -#: controldata.c:488 +#: controldata.c:554 #, c-format msgid " latest checkpoint next OID\n" msgstr " prochain OID du dernier checkpoint\n" -#: controldata.c:491 +#: controldata.c:557 #, c-format msgid " latest checkpoint next MultiXactId\n" msgstr " prochain MultiXactId du dernier checkpoint\n" -#: controldata.c:495 +#: controldata.c:561 #, c-format msgid " latest checkpoint oldest MultiXactId\n" msgstr " plus ancien MultiXactId du dernier checkpoint\n" -#: controldata.c:498 +#: controldata.c:564 #, c-format msgid " latest checkpoint next MultiXactOffset\n" msgstr " prochain MultiXactOffset du dernier checkpoint\n" -#: controldata.c:501 +#: controldata.c:567 #, c-format msgid " first WAL segment after reset\n" msgstr " premier segment WAL après réinitialisation\n" -#: controldata.c:504 +#: controldata.c:570 #, c-format msgid " float8 argument passing method\n" msgstr " méthode de passage de arguments float8\n" -#: controldata.c:507 +#: controldata.c:573 #, c-format msgid " maximum alignment\n" msgstr " alignement maximale\n" -#: controldata.c:510 +#: controldata.c:576 #, c-format msgid " block size\n" msgstr " taille de bloc\n" -#: controldata.c:513 +#: controldata.c:579 #, c-format msgid " large relation segment size\n" msgstr " taille de segment des relations\n" -#: controldata.c:516 +#: controldata.c:582 #, c-format msgid " WAL block size\n" msgstr " taille de bloc d'un WAL\n" -#: controldata.c:519 +#: controldata.c:585 #, c-format msgid " WAL segment size\n" msgstr " taille d'un segment WAL\n" -#: controldata.c:522 +#: controldata.c:588 #, c-format msgid " maximum identifier length\n" msgstr " longueur maximum d'un identifiant\n" -#: controldata.c:525 +#: controldata.c:591 #, c-format msgid " maximum number of indexed columns\n" msgstr " nombre maximum de colonnes indexées\n" -#: controldata.c:528 +#: controldata.c:594 #, c-format msgid " maximum TOAST chunk size\n" msgstr " taille maximale d'un morceau de TOAST\n" -#: controldata.c:532 +#: controldata.c:598 #, c-format msgid " large-object chunk size\n" msgstr " taille d'un morceau Large-Object\n" -#: controldata.c:535 +#: controldata.c:601 #, c-format msgid " dates/times are integers?\n" msgstr " les dates/heures sont-ils des integers?\n" -#: controldata.c:539 +#: controldata.c:605 #, c-format msgid " data checksum version\n" msgstr " version des sommes de contrôle des données\n" -#: controldata.c:541 +#: controldata.c:607 #, c-format msgid "Cannot continue without required control information, terminating\n" -msgstr "Ne peut pas continuer sans les informations de contrôle requises, en arrêt\n" +msgstr "" +"Ne peut pas continuer sans les informations de contrôle requises, en arrêt\n" -#: controldata.c:556 +#: controldata.c:622 #, c-format msgid "" "old and new pg_controldata alignments are invalid or do not match\n" "Likely one cluster is a 32-bit install, the other 64-bit\n" msgstr "" -"les alignements sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +"les alignements sont invalides ou ne correspondent pas entre l'ancien et le " +"nouveau pg_controldata.\n" "Il est probable qu'une installation soit en 32 bits et l'autre en 64 bits.\n" -#: controldata.c:560 +#: controldata.c:626 #, c-format msgid "old and new pg_controldata block sizes are invalid or do not match\n" -msgstr "les tailles de bloc sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgstr "" +"les tailles de bloc sont invalides ou ne correspondent pas entre l'ancien et " +"le nouveau pg_controldata.\n" -#: controldata.c:563 +#: controldata.c:629 #, c-format -msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" -msgstr "les tailles maximales de segment de relation sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata maximum relation segment sizes are invalid or do " +"not match\n" +msgstr "" +"les tailles maximales de segment de relation sont invalides ou ne " +"correspondent pas entre l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:566 +#: controldata.c:632 #, c-format -msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" -msgstr "les tailles de bloc des WAL sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "" +"les tailles de bloc des WAL sont invalides ou ne correspondent pas entre " +"l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:569 +#: controldata.c:635 #, c-format -msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" -msgstr "les tailles de segment de WAL sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "" +"les tailles de segment de WAL sont invalides ou ne correspondent pas entre " +"l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:572 +#: controldata.c:638 #, c-format -msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" -msgstr "les longueurs maximales des identifiants sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata maximum identifier lengths are invalid or do not " +"match\n" +msgstr "" +"les longueurs maximales des identifiants sont invalides ou ne correspondent " +"pas entre l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:575 +#: controldata.c:641 #, c-format -msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" -msgstr "les nombres maximums de colonnes indexées sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata maximum indexed columns are invalid or do not " +"match\n" +msgstr "" +"les nombres maximums de colonnes indexées sont invalides ou ne correspondent " +"pas entre l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:578 +#: controldata.c:644 #, c-format -msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" -msgstr "les tailles maximales de morceaux des TOAST sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata maximum TOAST chunk sizes are invalid or do not " +"match\n" +msgstr "" +"les tailles maximales de morceaux des TOAST sont invalides ou ne " +"correspondent pas entre l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:583 +#: controldata.c:649 #, c-format -msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" -msgstr "les tailles des morceaux de Large Objects sont invalides ou ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgid "" +"old and new pg_controldata large-object chunk sizes are invalid or do not " +"match\n" +msgstr "" +"les tailles des morceaux de Large Objects sont invalides ou ne correspondent " +"pas entre l'ancien et le nouveau pg_controldata.\n" -#: controldata.c:586 +#: controldata.c:652 #, c-format msgid "old and new pg_controldata date/time storage types do not match\n" -msgstr "les types de stockage date/heure ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgstr "" +"les types de stockage date/heure ne correspondent pas entre l'ancien et le " +"nouveau pg_controldata.\n" -#: controldata.c:599 +#: controldata.c:665 #, c-format msgid "old cluster does not use data checksums but the new one does\n" -msgstr "l'ancienne instance n'utilise pas les sommes de contrôle alors que la nouvelle les utilise\n" +msgstr "" +"l'ancienne instance n'utilise pas les sommes de contrôle alors que la " +"nouvelle les utilise\n" -#: controldata.c:602 +#: controldata.c:668 #, c-format msgid "old cluster uses data checksums but the new one does not\n" -msgstr "l'ancienne instance utilise les sommes de contrôle alors que la nouvelle ne les utilise pas\n" +msgstr "" +"l'ancienne instance utilise les sommes de contrôle alors que la nouvelle ne " +"les utilise pas\n" -#: controldata.c:604 +#: controldata.c:670 #, c-format msgid "old and new cluster pg_controldata checksum versions do not match\n" -msgstr "les versions des sommes de contrôle ne correspondent pas entre l'ancien et le nouveau pg_controldata.\n" +msgstr "" +"les versions des sommes de contrôle ne correspondent pas entre l'ancien et " +"le nouveau pg_controldata.\n" -#: controldata.c:615 +#: controldata.c:681 #, c-format msgid "Adding \".old\" suffix to old global/pg_control" msgstr "Ajout du suffixe « .old » à l'ancien global/pg_control" -#: controldata.c:620 +#: controldata.c:686 #, c-format msgid "Unable to rename %s to %s.\n" msgstr "Incapable de renommer %s à %s.\n" -#: controldata.c:623 +#: controldata.c:689 #, c-format msgid "" "\n" @@ -600,17 +768,19 @@ msgid "" "\n" msgstr "" "\n" -"Si vous voulez démarrer l'ancienne instance, vous devez supprimer le suffixe « .old » du fichier %s/global/pg_control.old.\n" +"Si vous voulez démarrer l'ancienne instance, vous devez supprimer le suffixe " +"« .old » du fichier %s/global/pg_control.old.\n" "\n" -"Comme le mode lien était utilisé, l'ancienne instance ne peut pas être démarré proprement une fois que la nouvelle instance a été démarrée.\n" +"Comme le mode lien était utilisé, l'ancienne instance ne peut pas être " +"démarré proprement une fois que la nouvelle instance a été démarrée.\n" "\n" -#: dump.c:23 +#: dump.c:22 #, c-format msgid "Creating dump of global objects" msgstr "Création de la sauvegarde des objets globaux" -#: dump.c:34 +#: dump.c:33 #, c-format msgid "Creating dump of database schemas\n" msgstr "Création de la sauvegarde des schémas des bases\n" @@ -620,27 +790,27 @@ msgstr "Création de la sauvegarde des schémas des bases\n" msgid "could not get pg_ctl version data using %s: %s\n" msgstr "n'a pas pu obtenir la version de pg_ctl en utilisant %s : %s\n" -#: exec.c:54 server.c:170 +#: exec.c:50 #, c-format -msgid "could not get version from %s\n" -msgstr "n'a pas pu obtenir la version à partir de %s\n" +msgid "could not get pg_ctl version output from %s\n" +msgstr "n'a pas pu obtenir la version de pg_ctl à partir de %s\n" -#: exec.c:101 exec.c:105 +#: exec.c:104 exec.c:108 #, c-format msgid "command too long\n" msgstr "commande trop longue\n" -#: exec.c:107 util.c:38 util.c:226 +#: exec.c:110 util.c:38 util.c:226 #, c-format msgid "%s\n" msgstr "%s\n" -#: exec.c:146 exec.c:201 option.c:101 option.c:217 +#: exec.c:149 exec.c:204 option.c:105 option.c:227 #, c-format -msgid "cannot write to log file %s\n" -msgstr "ne peut pas écrire dans le fichier de traces %s\n" +msgid "could not write to log file \"%s\"\n" +msgstr "n'a pas pu écrire dans le journal applicatif « %s »\n" -#: exec.c:175 +#: exec.c:178 #, c-format msgid "" "\n" @@ -649,110 +819,182 @@ msgstr "" "\n" "*échec*" -#: exec.c:178 +#: exec.c:181 #, c-format msgid "There were problems executing \"%s\"\n" msgstr "Il y a eu des problèmes lors de l'exécution de « %s »\n" -#: exec.c:181 +#: exec.c:184 #, c-format msgid "" "Consult the last few lines of \"%s\" or \"%s\" for\n" "the probable cause of the failure.\n" -msgstr "Consultez les dernières lignes de « %s » ou « %s » pour trouver la cause probable de l'échec.\n" +msgstr "" +"Consultez les dernières lignes de « %s » ou « %s » pour trouver la cause " +"probable de l'échec.\n" -#: exec.c:186 +#: exec.c:189 #, c-format msgid "" "Consult the last few lines of \"%s\" for\n" "the probable cause of the failure.\n" -msgstr "Consultez les dernières lignes de « %s » pour trouver la cause probable de l'échec.\n" +msgstr "" +"Consultez les dernières lignes de « %s » pour trouver la cause probable de " +"l'échec.\n" -#: exec.c:227 +#: exec.c:230 #, c-format msgid "could not open file \"%s\" for reading: %s\n" msgstr "n'a pas pu ouvrir le fichier « %s » pour une lecture : %s\n" -#: exec.c:254 +#: exec.c:257 #, c-format msgid "You must have read and write access in the current directory.\n" -msgstr "Vous devez avoir les droits de lecture et d'écriture dans le répertoire actuel.\n" +msgstr "" +"Vous devez avoir les droits de lecture et d'écriture dans le répertoire " +"actuel.\n" -#: exec.c:307 exec.c:370 exec.c:426 +#: exec.c:310 exec.c:372 exec.c:427 #, c-format msgid "check for \"%s\" failed: %s\n" msgstr "échec de la vérification de « %s » : %s\n" -#: exec.c:310 exec.c:373 +#: exec.c:313 exec.c:375 #, c-format -msgid "%s is not a directory\n" -msgstr "%s n'est pas un répertoire\n" +msgid "\"%s\" is not a directory\n" +msgstr "« %s » n'est pas un répertoire\n" -#: exec.c:429 +#: exec.c:430 #, c-format -msgid "check for \"%s\" failed: not an executable file\n" -msgstr "échec de la vérification de « %s » : pas un fichier exécutable\n" +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "échec de la vérification de « %s » : pas un fichier régulier\n" -#: exec.c:441 +#: exec.c:442 #, c-format msgid "check for \"%s\" failed: cannot read file (permission denied)\n" -msgstr "échec de la vérification de « %s » : ne peut pas lire le fichier (droit refusé)\n" +msgstr "" +"échec de la vérification de « %s » : ne peut pas lire le fichier (droit " +"refusé)\n" -#: exec.c:449 +#: exec.c:450 #, c-format msgid "check for \"%s\" failed: cannot execute (permission denied)\n" -msgstr "échec de la vérification de « %s » : ne peut pas exécuter (droit refusé)\n" +msgstr "" +"échec de la vérification de « %s » : ne peut pas exécuter (droit refusé)\n" -#: file.c:43 file.c:146 +#: file.c:48 file.c:66 #, c-format -msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu ouvrir le fichier « %s » : %s\n" +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"erreur lors du clonage de la relation « %s.%s » (« %s » à « %s ») : %s\n" + +#: file.c:55 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "" +"erreur lors du clonage de la relation « %s.%s » : n'a pas pu ouvrir le " +"fichier « %s » : %s\n" + +#: file.c:60 +#, c-format +msgid "" +"error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "" +"erreur lors du clonage de la relation « %s.%s » : n'a pas pu créer le " +"fichier « %s » : %s\n" -#: file.c:48 file.c:155 +#: file.c:92 file.c:195 #, c-format -msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu créer le fichier « %s » : %s\n" +msgid "" +"error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : n'a pas pu ouvrir le " +"fichier « %s » : %s\n" -#: file.c:62 file.c:186 +#: file.c:97 file.c:204 #, c-format -msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu lire le fichier « %s » : %s\n" +msgid "" +"error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : n'a pas pu créer le " +"fichier « %s » : %s\n" -#: file.c:74 file.c:264 +#: file.c:111 file.c:228 #, c-format -msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu écrire le fichier « %s » : %s\n" +msgid "" +"error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : n'a pas pu lire le " +"fichier « %s » : %s\n" -#: file.c:88 +#: file.c:123 file.c:306 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : n'a pas pu écrire le " +"fichier « %s » : %s\n" + +#: file.c:137 #, c-format msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » (« %s » à « %s ») : %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » (« %s » à « %s ») : %s\n" + +#: file.c:156 +#, c-format +msgid "" +"error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"erreur lors de la création du lien pour la relation « %s.%s » (« %s » à « %s " +"») : %s\n" + +#: file.c:199 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : n'a pas pu tester le " +"fichier « %s » : %s\n" + +#: file.c:231 +#, c-format +msgid "" +"error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "" +"erreur lors de la copie de la relation « %s.%s » : page partielle trouvée " +"dans le fichier « %s »\n" -#: file.c:107 +#: file.c:333 file.c:350 #, c-format -msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" -msgstr "erreur lors de la création du lien pour la relation « %s.%s » (« %s » à « %s ») : %s\n" +msgid "could not clone file between old and new data directories: %s\n" +msgstr "" +"n'a pas pu cloner le fichier entre l'ancien et le nouveau répertoires : %s\n" -#: file.c:150 +#: file.c:346 #, c-format -msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : n'a pas pu tester le fichier « %s » : %s\n" +msgid "could not create file \"%s\": %s\n" +msgstr "n'a pas pu créer le fichier « %s » : %s\n" -#: file.c:189 +#: file.c:357 #, c-format -msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" -msgstr "erreur lors de la copie de la relation « %s.%s » : page partielle trouvée dans le fichier « %s »\n" +msgid "file cloning not supported on this platform\n" +msgstr "clonage de fichiers non supporté sur cette plateforme\n" -#: file.c:292 +#: file.c:374 #, c-format msgid "" "could not create hard link between old and new data directories: %s\n" -"In link mode the old and new data directories must be on the same file system volume.\n" +"In link mode the old and new data directories must be on the same file " +"system.\n" msgstr "" -"n'a pas pu créer le lien physique entre l'ancien et le nouveau répertoires de données : %s\n" -"Dans le mode lien, les ancien et nouveau répertoires doivent être sur le même système de fichiers.\n" +"n'a pas pu créer le lien physique entre l'ancien et le nouveau répertoires " +"de données : %s\n" +"Dans le mode lien, les ancien et nouveau répertoires de données doivent être " +"sur le même système de fichiers.\n" -#: function.c:110 +#: function.c:116 #, c-format msgid "" "\n" @@ -794,29 +1036,32 @@ msgstr "" "dans chaque base de données affectée :\n" "\n" -#: function.c:128 +#: function.c:134 #, c-format msgid " %s\n" msgstr " %s\n" -#: function.c:138 +#: function.c:144 #, c-format msgid "Remove the problem functions from the old cluster to continue.\n" -msgstr "Supprimez les fonctions problématiques de l'ancienne instance pour continuer.\n" +msgstr "" +"Supprimez les fonctions problématiques de l'ancienne instance pour " +"continuer.\n" -#: function.c:211 +#: function.c:191 #, c-format msgid "Checking for presence of required libraries" msgstr "Vérification de la présence des bibliothèques requises" -#: function.c:255 +#: function.c:248 #, c-format -msgid "" -"could not load library \"%s\":\n" -"%s\n" -msgstr "" -"n'a pas pu charger la biblothèque « %s »:\n" -"%s\n" +msgid "could not load library \"%s\": %s" +msgstr "n'a pas pu charger la bibliothèque « %s » : %s" + +#: function.c:259 info.c:633 +#, c-format +msgid "Database: %s\n" +msgstr "Base de données : %s\n" #: function.c:269 #, c-format @@ -828,22 +1073,31 @@ msgid "" " %s\n" "\n" msgstr "" -"Votre installation référence des bibliothèques chargeables, mais manquantes sur\n" -"la nouvelle installation. Vous pouvez ajouter ces bibliothèques à la nouvelle\n" -"installation ou supprimer les fonctions les utilisant dans l'ancienne installation.\n" +"Votre installation référence des bibliothèques chargeables, mais manquantes " +"sur\n" +"la nouvelle installation. Vous pouvez ajouter ces bibliothèques à la " +"nouvelle\n" +"installation ou supprimer les fonctions les utilisant dans l'ancienne " +"installation.\n" "Une liste des biblioth_ques problématiques est disponible dans le fichier :\n" " %s\n" "\n" #: info.c:133 #, c-format -msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" -msgstr "Les noms de relation pour l'OID %u dans la base de données « %s » ne correspondent pas : ancien nom « %s.%s », nouveau nom « %s.%s »\n" +msgid "" +"Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s" +"\", new name \"%s.%s\"\n" +msgstr "" +"Les noms de relation pour l'OID %u dans la base de données « %s » ne " +"correspondent pas : ancien nom « %s.%s », nouveau nom « %s.%s »\n" #: info.c:153 #, c-format msgid "Failed to match up old and new tables in database \"%s\"\n" -msgstr "Échec de correspondance des anciennes et nouvelles tables dans la base de données « %s »\n" +msgstr "" +"Échec de correspondance des anciennes et nouvelles tables dans la base de " +"données « %s »\n" #: info.c:242 #, c-format @@ -867,13 +1121,21 @@ msgstr " qui est la table TOAST pour l'OID %u" #: info.c:276 #, c-format -msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" -msgstr "Aucune correspondance trouvée dans l'ancienne instance pour la nouvelle relation d'OID %u dans la base de données « %s » : %s\n" +msgid "" +"No match found in old cluster for new relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"Aucune correspondance trouvée dans l'ancienne instance pour la nouvelle " +"relation d'OID %u dans la base de données « %s » : %s\n" #: info.c:279 #, c-format -msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" -msgstr "Aucune correspondance trouvée dans la nouvelle instance pour la nouvelle relation d'OID %u dans la base de données « %s » : %s\n" +msgid "" +"No match found in new cluster for old relation with OID %u in database \"%s" +"\": %s\n" +msgstr "" +"Aucune correspondance trouvée dans la nouvelle instance pour la nouvelle " +"relation d'OID %u dans la base de données « %s » : %s\n" #: info.c:291 #, c-format @@ -885,7 +1147,7 @@ msgstr "correspondances pour la base de données « %s » :\n" msgid "%s.%s: %u to %u\n" msgstr "%s.%s : %u vers %u\n" -#: info.c:299 info.c:638 +#: info.c:299 info.c:635 #, c-format msgid "" "\n" @@ -912,80 +1174,84 @@ msgstr "" "\n" "bases de données cibles :\n" -#: info.c:636 -#, c-format -msgid "Database: %s\n" -msgstr "Base de données : %s\n" - -#: info.c:649 +#: info.c:646 #, c-format msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" msgstr "relname : %s.%s : reloid : %u reltblspace : %s\n" -#: option.c:98 +#: option.c:102 #, c-format msgid "%s: cannot be run as root\n" msgstr "%s : ne peut pas être exécuté en tant que root\n" -#: option.c:172 +#: option.c:174 #, c-format msgid "invalid old port number\n" msgstr "ancien numéro de port invalide\n" -#: option.c:180 +#: option.c:182 #, c-format msgid "invalid new port number\n" msgstr "nouveau numéro de port invalide\n" -#: option.c:202 +#: option.c:208 #, c-format msgid "Running in verbose mode\n" msgstr "Exécution en mode verbeux\n" -#: option.c:207 +#: option.c:217 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: option.c:242 +#: option.c:252 msgid "old cluster binaries reside" msgstr "les binaires de l'ancienne instance résident" -#: option.c:244 +#: option.c:254 msgid "new cluster binaries reside" msgstr "les binaires de la nouvelle instance résident" -#: option.c:246 +#: option.c:256 msgid "old cluster data resides" msgstr "les données de l'ancienne instance résident" -#: option.c:248 +#: option.c:258 msgid "new cluster data resides" msgstr "les données de la nouvelle instance résident" -#: option.c:265 option.c:462 +#: option.c:260 +msgid "sockets will be created" +msgstr "les sockets seront créés" + +#: option.c:277 option.c:371 #, c-format -msgid "cannot find current directory\n" -msgstr "ne peut pas trouver le répertoire courant\n" +msgid "could not determine current directory\n" +msgstr "n'a pas pu déterminer le répertoire courant\n" -#: option.c:268 +#: option.c:280 #, c-format -msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" -msgstr "ne peut pas exécuter pg_upgrade depuis le répertoire de données de la nouvelle instance sur Windows\n" +msgid "" +"cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "" +"ne peut pas exécuter pg_upgrade depuis le répertoire de données de la " +"nouvelle instance sur Windows\n" -#: option.c:277 +#: option.c:289 #, c-format msgid "" "pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" "\n" -msgstr "pg_upgrade met à jour une instance PostgreSQL vers une version majeure différente.\n" +msgstr "" +"pg_upgrade met à jour une instance PostgreSQL vers une version majeure " +"différente.\n" -#: option.c:278 +#: option.c:290 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: option.c:279 +#: option.c:291 #, c-format msgid "" " pg_upgrade [OPTION]...\n" @@ -994,92 +1260,143 @@ msgstr "" " pg_upgrade [OPTION]...\n" "\n" -#: option.c:280 +#: option.c:292 #, c-format msgid "Options:\n" msgstr "Options :\n" -#: option.c:281 +#: option.c:293 #, c-format msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" -msgstr " -b, --old-bindir=DIRBIN répertoire des exécutables de l'ancienne instance\n" +msgstr "" +" -b, --old-bindir=DIRBIN répertoire des exécutables de l'ancienne " +"instance\n" -#: option.c:282 +#: option.c:294 #, c-format msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" -msgstr " -B, --new-bindir=DIRBIN répertoire des exécutables de la nouvelle instance\n" +msgstr "" +" -B, --new-bindir=DIRBIN répertoire des exécutables de la nouvelle " +"instance\n" -#: option.c:283 +#: option.c:295 #, c-format -msgid " -c, --check check clusters only, don't change any data\n" -msgstr " -c, --check vérifie seulement les instances, pas de modifications\n" +msgid "" +" -c, --check check clusters only, don't change any data\n" +msgstr "" +" -c, --check vérifie seulement les instances, pas de " +"modifications\n" -#: option.c:284 +#: option.c:296 #, c-format msgid " -d, --old-datadir=DATADIR old cluster data directory\n" -msgstr " -d, --old-datadir=DIRDONNEES répertoire des données de l'ancienne instance\n" +msgstr "" +" -d, --old-datadir=DIRDONNEES répertoire des données de l'ancienne " +"instance\n" -#: option.c:285 +#: option.c:297 #, c-format msgid " -D, --new-datadir=DATADIR new cluster data directory\n" -msgstr " -D, --new-datadir=DIRDONNEES répertoire des données de la nouvelle instance\n" +msgstr "" +" -D, --new-datadir=DIRDONNEES répertoire des données de la nouvelle " +"instance\n" -#: option.c:286 +#: option.c:298 #, c-format -msgid " -j, --jobs number of simultaneous processes or threads to use\n" -msgstr " -j, --jobs nombre de processus ou threads simultanés à utiliser\n" +msgid "" +" -j, --jobs number of simultaneous processes or threads " +"to use\n" +msgstr "" +" -j, --jobs nombre de processus ou threads simultanés à " +"utiliser\n" -#: option.c:287 +#: option.c:299 #, c-format -msgid " -k, --link link instead of copying files to new cluster\n" -msgstr " -k, --link lie les fichiers au lieu de les copier vers la nouvelle instance\n" +msgid "" +" -k, --link link instead of copying files to new " +"cluster\n" +msgstr "" +" -k, --link lie les fichiers au lieu de les copier vers " +"la nouvelle instance\n" -#: option.c:288 +#: option.c:300 #, c-format -msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" -msgstr " -o, --old-options=OPTIONS options à passer au serveur de l'ancienne instance\n" +msgid "" +" -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr "" +" -o, --old-options=OPTIONS options à passer au serveur de l'ancienne " +"instance\n" -#: option.c:289 +#: option.c:301 #, c-format -msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" -msgstr " -O, --new-options=OPTIONS options à passer au serveur de la nouvelle instance\n" +msgid "" +" -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr "" +" -O, --new-options=OPTIONS options à passer au serveur de la nouvelle " +"instance\n" -#: option.c:290 +#: option.c:302 #, c-format msgid " -p, --old-port=PORT old cluster port number (default %d)\n" -msgstr " -p, --old-port=PORT numéro de port de l'ancienne instance (par défaut %d)\n" +msgstr "" +" -p, --old-port=PORT numéro de port de l'ancienne instance (par " +"défaut %d)\n" -#: option.c:291 +#: option.c:303 #, c-format msgid " -P, --new-port=PORT new cluster port number (default %d)\n" -msgstr " -P, --new-port=PORT numéro de port de la nouvelle instance (par défaut %d)\n" +msgstr "" +" -P, --new-port=PORT numéro de port de la nouvelle instance (par " +"défaut %d)\n" -#: option.c:292 +#: option.c:304 +#, c-format +msgid "" +" -r, --retain retain SQL and log files after success\n" +msgstr "" +" -r, --retain conserve les fichiers SQL et de traces en " +"cas de succès\n" + +#: option.c:305 #, c-format -msgid " -r, --retain retain SQL and log files after success\n" -msgstr " -r, --retain conserve les fichiers SQL et de traces en cas de succès\n" +msgid " -s, --socketdir=DIR socket directory to use (default CWD)\n" +msgstr "" +" -s, --socketdir=DIR répertoire de la socket à utiliser (par " +"défaut CWD)\n" -#: option.c:293 +#: option.c:306 #, c-format msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" -msgstr " -U, --username=NOM superutilisateur de l'instance (par défaut « %s »)\n" +msgstr "" +" -U, --username=NOM superutilisateur de l'instance (par défaut « " +"%s »)\n" -#: option.c:294 +#: option.c:307 #, c-format msgid " -v, --verbose enable verbose internal logging\n" msgstr " -v, --verbose active des traces internes verbeuses\n" -#: option.c:295 +#: option.c:308 #, c-format -msgid " -V, --version display version information, then exit\n" +msgid "" +" -V, --version display version information, then exit\n" msgstr " -V, --version affiche la version, puis quitte\n" -#: option.c:296 +#: option.c:309 +#, c-format +msgid "" +" --clone clone instead of copying files to new " +"cluster\n" +msgstr "" +" --clone clone au lieu de copier les fichiers vers la " +"nouvelle instance\n" + +#: option.c:310 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide, puis quitte\n" -#: option.c:297 +#: option.c:311 #, c-format msgid "" "\n" @@ -1095,7 +1412,7 @@ msgstr "" " arrêter le postmaster de la nouvelle instance\n" "\n" -#: option.c:302 +#: option.c:316 #, c-format msgid "" "\n" @@ -1106,26 +1423,29 @@ msgid "" " the \"bin\" directory for the new version (-B BINDIR)\n" msgstr "" "\n" -"Quand vous exécutez pg_upgrade, vous devez fournir les informations suivantes :\n" +"Quand vous exécutez pg_upgrade, vous devez fournir les informations " +"suivantes :\n" " le répertoire de données pour l'ancienne instance (-d DIRDONNÉES)\n" " le répertoire de données pour la nouvelle instance (-D DIRDONNÉES)\n" " le répertoire « bin » pour l'ancienne version (-b DIRBIN)\n" " le répertoire « bin » pour la nouvelle version (-B DIRBIN)\n" -#: option.c:308 +#: option.c:322 #, c-format msgid "" "\n" "For example:\n" -" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" "or\n" msgstr "" "\n" "Par exemple :\n" -" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B " +"newCluster/bin\n" "ou\n" -#: option.c:313 +#: option.c:327 #, c-format msgid "" " $ export PGDATAOLD=oldCluster/data\n" @@ -1140,7 +1460,7 @@ msgstr "" " $ export PGBINNEW=newCluster/bin\n" " $ pg_upgrade\n" -#: option.c:319 +#: option.c:333 #, c-format msgid "" " C:\\> set PGDATAOLD=oldCluster/data\n" @@ -1155,108 +1475,113 @@ msgstr "" " C:\\> set PGBINNEW=newCluster/bin\n" " C:\\> pg_upgrade\n" -#: option.c:325 +#: option.c:339 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapporter les bogues à .\n" +"Rapporter les bogues à .\n" -#: option.c:358 +#: option.c:375 #, c-format msgid "" "You must identify the directory where the %s.\n" "Please use the %s command-line option or the %s environment variable.\n" msgstr "" "Vous devez identifier le répertoire où le %s.\n" -"Merci d'utiliser l'option en ligne de commande %s ou la variable d'environnement %s.\n" +"Merci d'utiliser l'option en ligne de commande %s ou la variable " +"d'environnement %s.\n" -#: option.c:409 +#: option.c:427 #, c-format msgid "Finding the real data directory for the source cluster" msgstr "Recherche du vrai répertoire des données pour l'instance source" -#: option.c:411 +#: option.c:429 #, c-format msgid "Finding the real data directory for the target cluster" msgstr "Recherche du vrai répertoire des données pour l'instance cible" -#: option.c:423 +#: option.c:441 #, c-format msgid "could not get data directory using %s: %s\n" msgstr "n'a pas pu obtenir le répertoire des données en utilisant %s : %s\n" -#: option.c:480 -#, c-format -msgid "Cannot open file %s: %m\n" -msgstr "Ne peut pas ouvrir le fichier %s : %m\n" - -#: option.c:487 +#: option.c:501 #, c-format -msgid "Cannot read line %d from %s: %m\n" -msgstr "Ne peut pas lire la ligne %d à partir de %s : %m\n" +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "n'a pas pu lire la ligne %d du fichier « %s » : %s\n" -#: option.c:504 +#: option.c:519 #, c-format -msgid "User-supplied old port number %hu corrected to %hu\n" -msgstr "Ancien numéro de port %hu fourni par l'utilisateur corrigé en %hu\n" +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "ancien numéro de port %hu fourni par l'utilisateur corrigé en %hu\n" -#: parallel.c:128 parallel.c:242 +#: parallel.c:128 parallel.c:241 #, c-format msgid "could not create worker process: %s\n" msgstr "n'a pas pu créer le processus de travail : %s\n" -#: parallel.c:147 parallel.c:263 +#: parallel.c:147 parallel.c:262 #, c-format msgid "could not create worker thread: %s\n" msgstr "n'a pas pu créer le fil de travail: %s\n" -#: parallel.c:311 parallel.c:326 +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "échec de waitpid() : %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "le processus fils a quitté anormalement : statut %d\n" + +#: parallel.c:324 #, c-format msgid "child worker exited abnormally: %s\n" msgstr "le processus fils a quitté anormalement : %s\n" -#: pg_upgrade.c:107 +#: pg_upgrade.c:109 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "n'a pas pu lire les droits du répertoire « %s » : %s\n" + +#: pg_upgrade.c:126 #, c-format msgid "" "\n" "Performing Upgrade\n" +"------------------\n" msgstr "" "\n" "Réalisation de la mise à jour\n" +"-----------------------------\n" -#: pg_upgrade.c:108 -#, c-format -msgid "------------------\n" -msgstr "------------------\n" - -#: pg_upgrade.c:149 +#: pg_upgrade.c:169 #, c-format msgid "Setting next OID for new cluster" msgstr "Configuration du prochain OID sur la nouvelle instance" -#: pg_upgrade.c:156 +#: pg_upgrade.c:176 #, c-format msgid "Sync data directory to disk" msgstr "Synchronisation du répertoire des données sur disque" -#: pg_upgrade.c:167 +#: pg_upgrade.c:188 #, c-format msgid "" "\n" "Upgrade Complete\n" +"----------------\n" msgstr "" "\n" "Mise à jour terminée\n" +"--------------------\n" -#: pg_upgrade.c:168 -#, c-format -msgid "----------------\n" -msgstr "----------------\n" - -#: pg_upgrade.c:211 +#: pg_upgrade.c:234 #, c-format msgid "" "There seems to be a postmaster servicing the old cluster.\n" @@ -1265,7 +1590,7 @@ msgstr "" "Il semble qu'un postmaster est démarré sur l'ancienne instance.\n" "Merci d'arrêter ce postmaster et d'essayer de nouveau.\n" -#: pg_upgrade.c:224 +#: pg_upgrade.c:247 #, c-format msgid "" "There seems to be a postmaster servicing the new cluster.\n" @@ -1274,152 +1599,177 @@ msgstr "" "Il semble qu'un postmaster est démarré sur la nouvelle instance.\n" "Merci d'arrêter ce postmaster et d'essayer de nouveau.\n" -#: pg_upgrade.c:230 +#: pg_upgrade.c:253 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s : n'a pas pu trouver son propre exécutable\n" -#: pg_upgrade.c:247 +#: pg_upgrade.c:270 #, c-format msgid "Analyzing all rows in the new cluster" msgstr "Analyse de toutes les lignes dans la nouvelle instance" -#: pg_upgrade.c:260 +#: pg_upgrade.c:283 #, c-format -msgid "Freezing all rows on the new cluster" +msgid "Freezing all rows in the new cluster" msgstr "Gel de toutes les lignes dans la nouvelle instance" -#: pg_upgrade.c:280 +#: pg_upgrade.c:303 #, c-format msgid "Restoring global objects in the new cluster" msgstr "Restauration des objets globaux dans la nouvelle instance" -#: pg_upgrade.c:304 +#: pg_upgrade.c:318 #, c-format msgid "Restoring database schemas in the new cluster\n" -msgstr "Restauration des schémas des bases de données dans la nouvelle instance\n" +msgstr "" +"Restauration des schémas des bases de données dans la nouvelle instance\n" -#: pg_upgrade.c:366 +#: pg_upgrade.c:424 #, c-format msgid "Deleting files from new %s" msgstr "Suppression des fichiers à partir du nouveau %s" -#: pg_upgrade.c:370 +#: pg_upgrade.c:428 #, c-format msgid "could not delete directory \"%s\"\n" msgstr "n'a pas pu supprimer le répertoire « %s »\n" -#: pg_upgrade.c:389 +#: pg_upgrade.c:447 #, c-format msgid "Copying old %s to new server" msgstr "Copie de l'ancien %s vers le nouveau serveur" -#: pg_upgrade.c:416 +#: pg_upgrade.c:474 #, c-format msgid "Setting next transaction ID and epoch for new cluster" -msgstr "Configuration du prochain identifiant de transaction et de l'epoch pour la nouvelle instance" +msgstr "" +"Configuration du prochain identifiant de transaction et de l'epoch pour la " +"nouvelle instance" -#: pg_upgrade.c:446 +#: pg_upgrade.c:504 #, c-format msgid "Setting next multixact ID and offset for new cluster" -msgstr "Configuration du prochain MultiXactId et décalage pour la nouvelle instance" +msgstr "" +"Configuration du prochain MultiXactId et décalage pour la nouvelle instance" -#: pg_upgrade.c:470 +#: pg_upgrade.c:528 #, c-format -msgid "Setting oldest multixact ID on new cluster" -msgstr "Configuration du plus ancien MultiXactId sur la nouvelle instance" +msgid "Setting oldest multixact ID in new cluster" +msgstr "" +"Configuration du plus ancien identifiant multixact sur la nouvelle instance" -#: pg_upgrade.c:490 +#: pg_upgrade.c:548 #, c-format msgid "Resetting WAL archives" msgstr "Réinitialisation des archives WAL" -#: pg_upgrade.c:522 +#: pg_upgrade.c:591 #, c-format msgid "Setting frozenxid and minmxid counters in new cluster" -msgstr "Configuration des compteurs frozenxid et minmxid dans la nouvelle instance" +msgstr "" +"Configuration des compteurs frozenxid et minmxid dans la nouvelle instance" -#: pg_upgrade.c:524 +#: pg_upgrade.c:593 #, c-format msgid "Setting minmxid counter in new cluster" msgstr "Configuration du compteur minmxid dans la nouvelle instance" -#: relfilenode.c:34 +#: relfilenode.c:36 #, c-format -msgid "Linking user relation files\n" -msgstr "Création des liens pour les fichiers des relations utilisateurs\n" +msgid "Cloning user relation files\n" +msgstr "Clonage des fichiers des relations utilisateurs\n" -#: relfilenode.c:36 +#: relfilenode.c:39 #, c-format msgid "Copying user relation files\n" msgstr "Copie des fichiers des relations utilisateurs\n" -#: relfilenode.c:110 +#: relfilenode.c:42 +#, c-format +msgid "Linking user relation files\n" +msgstr "Création des liens pour les fichiers des relations utilisateurs\n" + +#: relfilenode.c:118 #, c-format msgid "old database \"%s\" not found in the new cluster\n" -msgstr "ancienne base de données « %s » introuvable dans la nouvelle instance\n" +msgstr "" +"ancienne base de données « %s » introuvable dans la nouvelle instance\n" -#: relfilenode.c:231 +#: relfilenode.c:239 #, c-format -msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" -msgstr "erreur lors de la vérification de l'existence du fichier « %s.%s » (« %s » vers « %s ») : %s\n" +msgid "" +"error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "" +"erreur lors de la vérification de l'existence du fichier « %s.%s » (« %s » " +"vers « %s ») : %s\n" -#: relfilenode.c:249 +#: relfilenode.c:257 #, c-format msgid "rewriting \"%s\" to \"%s\"\n" msgstr "réécriture de « %s » en « %s »\n" -#: relfilenode.c:255 +#: relfilenode.c:265 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "clonage de « %s » en « %s »\n" + +#: relfilenode.c:270 #, c-format msgid "copying \"%s\" to \"%s\"\n" msgstr "copie de « %s » en « %s »\n" -#: relfilenode.c:261 +#: relfilenode.c:275 #, c-format msgid "linking \"%s\" to \"%s\"\n" msgstr "lien de « %s » vers « %s »\n" -#: server.c:33 +#: server.c:34 #, c-format -msgid "connection to database failed: %s\n" -msgstr "échec de la connexion à la base de données : %s\n" +msgid "connection to database failed: %s" +msgstr "échec de la connexion à la base de données : %s" -#: server.c:39 server.c:139 util.c:136 util.c:166 +#: server.c:40 server.c:142 util.c:136 util.c:166 #, c-format msgid "Failure, exiting\n" msgstr "Échec, sortie\n" -#: server.c:129 +#: server.c:132 #, c-format msgid "executing: %s\n" msgstr "exécution : %s\n" -#: server.c:135 +#: server.c:138 #, c-format msgid "" "SQL command failed\n" "%s\n" -"%s\n" +"%s" msgstr "" "La commande SQL a échoué\n" "%s\n" -"%s\n" +"%s" -#: server.c:165 +#: server.c:168 #, c-format msgid "could not open version file: %s\n" msgstr "n'a pas pu ouvrir le fichier de version : %s\n" -#: server.c:284 +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "n'a pas pu analyser le fichier PG_VERSION à partir de %s\n" + +#: server.c:295 #, c-format msgid "" "\n" -"connection to database failed: %s\n" +"connection to database failed: %s" msgstr "" "\n" -"échec de la connexion à la base de données : %s\n" +"échec de la connexion à la base de données : %s" -#: server.c:289 +#: server.c:300 #, c-format msgid "" "could not connect to source postmaster started with the command:\n" @@ -1428,7 +1778,7 @@ msgstr "" "n'a pas pu se connecter au postmaster source lancé avec la commande :\n" "%s\n" -#: server.c:293 +#: server.c:304 #, c-format msgid "" "could not connect to target postmaster started with the command:\n" @@ -1437,32 +1787,35 @@ msgstr "" "n'a pas pu se connecter au postmaster cible lancé avec la commande :\n" "%s\n" -#: server.c:307 +#: server.c:318 #, c-format msgid "pg_ctl failed to start the source server, or connection failed\n" msgstr "pg_ctl a échoué à démarrer le serveur source ou connexion échouée\n" -#: server.c:309 +#: server.c:320 #, c-format msgid "pg_ctl failed to start the target server, or connection failed\n" msgstr "pg_ctl a échoué à démarrer le serveur cible ou connexion échouée\n" -#: server.c:354 +#: server.c:365 #, c-format msgid "out of memory\n" msgstr "mémoire épuisée\n" -#: server.c:367 +#: server.c:378 #, c-format msgid "libpq environment variable %s has a non-local server value: %s\n" -msgstr "la variable d'environnement libpq %s a une valeur serveur non locale : %s\n" +msgstr "" +"la variable d'environnement libpq %s a une valeur serveur non locale : %s\n" #: tablespace.c:28 #, c-format msgid "" "Cannot upgrade to/from the same system catalog version when\n" "using tablespaces.\n" -msgstr "Ne peut pas mettre à jour vers ou à partir de la même version de catalogue système quand des tablespaces sont utilisés.\n" +msgstr "" +"Ne peut pas mettre à jour vers ou à partir de la même version de catalogue " +"système quand des tablespaces sont utilisés.\n" #: tablespace.c:87 #, c-format @@ -1510,13 +1863,15 @@ msgid "" "\n" "Your installation contains large objects. The new database has an\n" "additional large object permission table. After upgrading, you will be\n" -"given a command to populate the pg_largeobject permission table with\n" +"given a command to populate the pg_largeobject_metadata table with\n" "default permissions.\n" "\n" msgstr "" "\n" -"Votre installation contient des Large Objects. La nouvelle base de données a un table de droit supplémentaire sur les Large Objects.\n" -"Après la mise à jour, vous disposerez d'une commande pour peupler la table de droits des Large Objects avec les droits par défaut.\n" +"Votre installation contient des Large Objects. La nouvelle base de données a " +"une table de droit supplémentaire sur les Large Objects.\n" +"Après la mise à jour, vous disposerez d'une commande pour peupler la table " +"pg_largeobject_metadata avec les droits par défaut.\n" "\n" #: version.c:88 @@ -1542,8 +1897,8 @@ msgstr "" #: version.c:118 #, c-format -msgid "Checking for invalid \"line\" user columns" -msgstr "Vérification des colonnes utilisateurs « line » invalides" +msgid "Checking for incompatible \"line\" data type" +msgstr "Vérification des types de données line incompatibles" #: version.c:180 #, c-format @@ -1556,10 +1911,14 @@ msgid "" " %s\n" "\n" msgstr "" -"Votre installation contient le type de données « line » dans vos tables utilisateurs.\n" -"Ce type de données a changé de format interne et en entrée/sortie entre votre ancienne\n" -"instance et votre nouvelle instance, donc cette instance ne peut pas être mise à jour\n" -"actuellement. Vous pouvez supprimer les tables problématiques et relancer la mise à jour.\n" +"Votre installation contient le type de données « line » dans vos tables " +"utilisateurs.\n" +"Ce type de données a changé de format interne et en entrée/sortie entre " +"votre ancienne\n" +"instance et votre nouvelle instance, donc cette instance ne peut pas être " +"mise à jour\n" +"actuellement. Vous pouvez supprimer les tables problématiques et relancer la " +"mise à jour.\n" "Vous trouverez une liste des colonnes problématiques dans le fichier :\n" " %s\n" "\n" @@ -1582,7 +1941,8 @@ msgstr "" "Votre installation contient le type de données « unknown » dans les tables\n" "utilisateurs. Ce type de données n'est plus autorisé dans les tables, donc\n" "cette instance ne peut pas être mise à jour pour l'instant. Vous pouvez\n" -"supprimer les tables problématiques et relancer la mise à jour. Vous trouverez\n" +"supprimer les tables problématiques et relancer la mise à jour. Vous " +"trouverez\n" "une liste des colonnes problématiques dans le fichier :\n" " %s\n" "\n" @@ -1604,8 +1964,10 @@ msgid "" msgstr "" "\n" "Votre installation contient des index hashs. Ces index ont des formats\n" -"internes différents entre l'ancienne et la nouvelle instance, dont ils doivent\n" -"être recréés avec la commande REINDEX. Après la mise à jour, les instructions\n" +"internes différents entre l'ancienne et la nouvelle instance, dont ils " +"doivent\n" +"être recréés avec la commande REINDEX. Après la mise à jour, les " +"instructions\n" "REINDEX vous seront données.\n" "\n" @@ -1615,7 +1977,7 @@ msgid "" "\n" "Your installation contains hash indexes. These indexes have different\n" "internal formats between your old and new clusters, so they must be\n" -"reindexed with the REINDEX command. The file:\n" +"reindexed with the REINDEX command. The file\n" " %s\n" "when executed by psql by the database superuser will recreate all invalid\n" "indexes; until then, none of these indexes will be used.\n" @@ -1623,9 +1985,55 @@ msgid "" msgstr "" "\n" "Votre installation contient des index hashs. Ces index ont des formats\n" -"internes différents entre l'ancienne et la nouvelle instance, dont ils doivent\n" +"internes différents entre l'ancienne et la nouvelle instance, donc ils " +"doivent\n" "être recréés avec la commande REINDEX. Le fichier :\n" " %s\n" "une fois exécuté par psql en tant que superutilisateur va recréer tous les\n" "index invalides. Avant cela, aucun de ces index ne sera utilisé.\n" "\n" + +#~ msgid "cannot write to log file %s\n" +#~ msgstr "ne peut pas écrire dans le fichier de traces %s\n" + +#~ msgid "cannot find current directory\n" +#~ msgstr "ne peut pas trouver le répertoire courant\n" + +#~ msgid "Cannot open file %s: %m\n" +#~ msgstr "Ne peut pas ouvrir le fichier %s : %m\n" + +#~ msgid "Cannot read line %d from %s: %m\n" +#~ msgstr "Ne peut pas lire la ligne %d à partir de %s : %m\n" + +#~ msgid "Checking for invalid \"line\" user columns" +#~ msgstr "Vérification des colonnes utilisateurs « line » invalides" + +#~ msgid "----------------\n" +#~ msgstr "----------------\n" + +#~ msgid "------------------\n" +#~ msgstr "------------------\n" + +#~ msgid "" +#~ "could not load library \"%s\":\n" +#~ "%s\n" +#~ msgstr "" +#~ "n'a pas pu charger la biblothèque « %s »:\n" +#~ "%s\n" + +#~ msgid "%s is not a directory\n" +#~ msgstr "%s n'est pas un répertoire\n" + +#~ msgid "" +#~ "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" +#~ "because of backend API changes made during development.\n" +#~ msgstr "" +#~ "Cet outil peut seulement mettre à jour à partir de la version 9.0 de " +#~ "PostgreSQL (après le 11 janvier 2010)\n" +#~ "à cause de changements dans l'API du moteur fait lors du développement.\n" + +#~ msgid "-----------------------------\n" +#~ msgstr "-----------------------------\n" + +#~ msgid "------------------------------------------------\n" +#~ msgstr "------------------------------------------------\n" diff --git a/src/bin/pg_upgrade/po/ja.po b/src/bin/pg_upgrade/po/ja.po new file mode 100644 index 00000000000..cac7a9aeb1c --- /dev/null +++ b/src/bin/pg_upgrade/po/ja.po @@ -0,0 +1,1651 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_upgrade (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-08-31 16:22+0900\n" +"PO-Revision-Date: 2018-08-27 16:16+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" +"Plural-Forms: nplural=1; plural=0;\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"å…ƒã®å®Ÿè¡Œä¸­ã‚µãƒ¼ãƒãƒ¼ã®ä¸€è²«æ€§ãƒã‚§ãƒƒã‚¯ã‚’実行ã—ã¦ã„ã¾ã™ã€‚\n" +"--------------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"æ•´åˆæ€§ãƒã‚§ãƒƒã‚¯ã‚’実行ã—ã¦ã„ã¾ã™ã€‚\n" +"-----------------------------\n" + +#: check.c:166 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"* クラスターã¯äº’æ›æ€§ãŒã‚りã¾ã™ *\n" + +#: check.c:172 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"ã“ã®ãƒã‚¤ãƒ³ãƒˆã®å¾Œã« pg_upgrade ãŒå¤±æ•—ã—ãŸå ´åˆã€ç¶šè¡Œã®å‰ã«å†åº¦ initdb を行ã£ã¦ã€\n" +"æ–°ã—ã„クラスターã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: check.c:208 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"オプティマイザーã®çµ±è¨ˆã¯ã€pg_upgrade ã§ã¯è»¢é€ã•れã¾ã›ã‚“。ãã®ãŸã‚\n" +"新サーãƒãƒ¼ã‚’èµ·å‹•ã—ãŸå¾Œã€%s ã‚’å‹•ã‹ã™ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。\n" +"\n" +"\n" + +#: check.c:213 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"オプティマイザーã®çµ±è¨ˆæƒ…å ±ã¨ç©ºã容é‡ã®æƒ…報㯠pg_upgrade ã§ã¯è»¢é€ã•れã¾ã›ã‚“。\n" +"ãã®ãŸã‚新サーãƒãƒ¼ã‚’èµ·å‹•ã—ãŸå¾Œã€%s ã®å®Ÿè¡Œã‚’検討ã—ã¦ãã ã•ã„。\n" +"\n" +"\n" + +#: check.c:220 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"ã“ã®ã‚¹ã‚¯ãƒªãƒ—トを実行ã™ã‚‹ã¨ã€æ—§ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ãƒ‡ãƒ¼ã‚¿ãƒ•ァイル %sãŒå‰Šé™¤ã•れã¾ã™:\n" +"\n" + +#: check.c:225 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"ユーザー定義ã®ãƒ†ãƒ¼ãƒ–ル区間もã—ãã¯æ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒ\n" +"æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªå†…ã«å­˜åœ¨ã™ã‚‹ãŸã‚ã€æ—§ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ãƒ‡ãƒ¼ã‚¿\n" +"ファイルを削除ã™ã‚‹ãŸã‚ã®ã‚¹ã‚¯ãƒªãƒ—トを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ å¤ã„\n" +"クラスターã®ä¸­èº«ã‚’手動ã§å‰Šé™¤ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: check.c:235 +#, c-format +msgid "Checking cluster versions" +msgstr "クラスターã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’確èªã—ã¦ã„ã¾ã™" + +#: check.c:247 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "ã“ã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ã§ã¯ PostgreSQL 8.4 以é™ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‹ã‚‰ã®ã¿ã‚¢ãƒƒãƒ—グレードã§ãã¾ã™ã€‚\n" + +#: check.c:251 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "ã“ã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ã¯ã€PostgreSQL ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s ã«ã®ã¿ã‚¢ãƒƒãƒ—グレードã§ãã¾ã™ã€‚\n" + +#: check.c:260 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "ã“ã®ãƒ¦ãƒ¼ãƒ†ã‚£ãƒªãƒ†ã‚£ã¯ PostgreSQL ã®éŽåŽ»ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ãƒ€ã‚¦ãƒ³ã‚°ãƒ¬ãƒ¼ãƒ‰ã™ã‚‹ç”¨é€”ã§ã¯ä½¿ç”¨ã§ãã¾ã›ã‚“。\n" + +#: check.c:265 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãƒ‡ãƒ¼ã‚¿ã¨ãƒã‚¤ãƒŠãƒªãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç•°ãªã‚Šã¾ã™ã€‚\n" + +#: check.c:268 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "æ–°ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãƒ‡ãƒ¼ã‚¿ã¨ãƒã‚¤ãƒŠãƒªãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç•°ãªã‚Šã¾ã™ã€‚\n" + +#: check.c:285 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "ç¾åœ¨å‹•作中㮠PG 9.1 以å‰ã®æ—§ã‚µãƒ¼ãƒã‚’ãƒã‚§ãƒƒã‚¯ã™ã‚‹å ´åˆã€æ—§ã‚µãƒ¼ãƒã®ãƒãƒ¼ãƒˆç•ªå·ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: check.c:289 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "稼åƒä¸­ã®ã‚µãƒ¼ãƒã‚’ãƒã‚§ãƒƒã‚¯ã™ã‚‹å ´åˆã€æ–°æ—§ã®ãƒãƒ¼ãƒˆç•ªå·ãŒç•°ãªã£ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: check.c:304 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"ã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ãŒä¸€è‡´ã—ã¾ã›ã‚“: æ—§ \"%s\"ã€æ–° \"%s\"\n" + +#: check.c:309 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"ã® lc_collate 値ãŒä¸€è‡´ã—ã¾ã›ã‚“:æ—§ \"%s\"ã€æ–° \"%s\"\n" + +#: check.c:312 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "データベース\"%s\"ã® lc_ctype 値ãŒä¸€è‡´ã—ã¾ã›ã‚“:æ—§ \"%s\"ã€æ–° \"%s\"\n" + +#: check.c:385 +#, c-format +msgid "New cluster database \"%s\" is not empty\n" +msgstr "æ–°ã—ã„クラスターデータベース\"%s\"ãŒç©ºã§ã¯ã‚りã¾ã›ã‚“。\n" + +#: check.c:432 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "æ–°ã—ã„クラスターを分æžã™ã‚‹ãŸã‚ã®ã‚¹ã‚¯ãƒªãƒ—トを作æˆã—ã¦ã„ã¾ã™" + +#: check.c:446 check.c:574 check.c:838 check.c:941 check.c:1032 function.c:253 +#: option.c:480 version.c:57 version.c:156 version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "ファイル \"%s\" をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: check.c:501 check.c:630 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "ファイル\"%s\"ã«å®Ÿè¡Œæ¨©é™ã‚’追加ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: check.c:537 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"警告: æ–°ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒæ—§ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ä¾‹ãˆã° %s ã®ä¸­ã«ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“。\n" + +#: check.c:561 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"警告: ユーザー定義テーブル空間ã®å ´æ‰€ãŒãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€ä¾‹ãˆã° %s ã®ä¸­ã«ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“。\n" + +#: check.c:571 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "å¤ã„クラスターを削除ã™ã‚‹ã‚¹ã‚¯ãƒªãƒ—トを作æˆã—ã¦ã„ã¾ã™" + +#: check.c:650 +#, c-format +msgid "Checking database user is the install user" +msgstr "データベースユーザーãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‹ã©ã†ã‹ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:666 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "データベースユーザー\"%s\"ãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã§ã¯ã‚りã¾ã›ã‚“\n" + +#: check.c:677 +#, c-format +msgid "could not determine the number of users\n" +msgstr "ユーザー数を特定ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: check.c:685 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "æ–°ã—ã„クラスター内ã«å®šç¾©ã§ãã‚‹ã®ã¯ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ã¿ã§ã™ã€‚\n" + +#: check.c:705 +#, c-format +msgid "Checking database connection settings" +msgstr "データベース接続ã®è¨­å®šã‚’確èªã—ã¦ã„ã¾ã™" + +#: check.c:727 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 ã«ã¯æŽ¥ç¶šã‚’許å¯ã—ã¦ã¯ãªã‚Šã¾ã›ã‚“。ã™ãªã‚ã¡ã€pg_database.datallowconn 㯠false ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: check.c:737 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "template0 以外ã®ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã¯æŽ¥ç¶šã‚’許å¯ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã™ãªã‚ã¡ pg_database.datallowconn ㌠true ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。\n" + +#: check.c:762 +#, c-format +msgid "Checking for prepared transactions" +msgstr "準備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:771 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚\n" + +#: check.c:773 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "変æ›å…ˆã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«æº–備済ã¿ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ãŒå«ã¾ã‚Œã¦ã„ã¾ã™\n" + +#: check.c:799 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "bigint を渡ã™éš›ã«ãƒŸã‚¹ãƒžãƒƒãƒãŒç™ºç”Ÿã™ã‚‹ contrib/isn ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:860 check.c:964 check.c:1055 function.c:268 version.c:179 +#: version.c:280 +#, c-format +msgid "fatal\n" +msgstr "致命的\n" + +#: check.c:861 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"変æ›å…ƒã‚·ã‚¹ãƒ†ãƒ ã«ã€bigint データ型ã«ä¾å­˜ã™ã‚‹ã€Œcontrib/isnã€æ©Ÿèƒ½ãŒ\n" +"å«ã¾ã‚Œã¦ã„ã¾ã™ã€‚æ–°æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼é–“ã§æ¸¡ã—ã¦ã„ã‚‹ bigint ã®å€¤ãŒç•°ãªã‚‹ãŸã‚ã€\n" +"ç¾æ™‚点ã§ã¯ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚’アップグレードã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" +"「Contrib/isnã€æ©Ÿèƒ½ã‚’使ã†ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’手動ã§ã‚¢ãƒƒãƒ—グレードã—ã€\n" +"旧クラスターã‹ã‚‰ã€Œcontrib/isnã€ã‚’削除後ã€å†åº¦ã‚¢ãƒƒãƒ—グレードを行ã£ã¦ãã ã•ã„。 \n" +"å•題ã®ã‚る関数ã®ä¸€è¦§ã¯ãƒ•ァイル %s ã«ã‚りã¾ã™ã€‚\n" +"\n" + +#: check.c:893 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "ユーザーテーブル内㮠reg * データ型をãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:965 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"変æ›å…ƒã‚·ã‚¹ãƒ†ãƒ ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ†ãƒ¼ãƒ–ル㫠reg * データ型㮠1 ã¤ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚\n" +"ã“れらã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯ã‚·ã‚¹ãƒ†ãƒ ã® OID ã‚’å‚ç…§ã—ã¾ã™ãŒã€ã“れ㯠pg_upgrade ã§ã¯\n" +"ä¿è­·ã•れãªã„ãŸã‚ã€ç¾æ™‚点ã§ã¯ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚’アップグレードã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" +"å•題ã«ãªã£ã¦ã„るテーブルを削除ã—ã¦ã‹ã‚‰ã€å†åº¦ã‚¢ãƒƒãƒ—グレードを実行ã§ãã¾ã™ã€‚\n" +"å•題ã«ãªã‚‹åˆ—ã®ä¸€è¦§ã¯ãƒ•ァイル %s ã«æ›¸ã‹ã‚Œã¦ã„ã¾ã™ã€‚\n" +"\n" +"\n" + +#: check.c:990 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "äº’æ›æ€§ã®ãªã„\"jsonb\"データ型をãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:1056 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"変æ›å…ƒã‚·ã‚¹ãƒ†ãƒ ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ†ãƒ¼ãƒ–ル㫠\"jsonb\" ã®ãƒ‡ãƒ¼ã‚¿åž‹ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚\n" +"\"jsonb\" ã®å†…部フォーマット㯠9.4 ベータã®é–“ã«å¤‰æ›´ã•れã¦ãŠã‚Šã€ç¾æ™‚点ã§ã¯ã“ã®\n" +"クラスターをアップグレードã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" +"å•題ã«ãªã£ã¦ã„るテーブルを削除ã—ã¦ã‹ã‚‰ã€å†åº¦ã‚¢ãƒƒãƒ—グレードを実行ã§ãã¾ã™ã€‚\n" +"å•題ã«ãªã‚‹åˆ—ã®ä¸€è¦§ã¯ãƒ•ァイル %s ã«æ›¸ã‹ã‚Œã¦ã„ã¾ã™ã€‚\n" +"\n" + +#: check.c:1077 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "'pg_' ã§å§‹ã¾ã‚‹ãƒ­ãƒ¼ãƒ«ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: check.c:1087 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã« 'pg_' ã§å§‹ã¾ã‚‹ãƒ­ãƒ¼ãƒ«ãŒå«ã¾ã‚Œã¦ã„ã¾ã™\n" + +#: check.c:1089 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "ターゲット クラスター㫠\"pg_\" ã§å§‹ã¾ã‚‹ãƒ­ãƒ¼ãƒ«ãŒå«ã¾ã‚Œã¦ã„ã¾ã™\n" + +#: check.c:1115 +#, c-format +msgid "failed to get the current locale\n" +msgstr "ç¾åœ¨ã®ãƒ­ã‚±ãƒ¼ãƒ«ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: check.c:1124 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "\"%s\"ã®ã‚·ã‚¹ãƒ†ãƒ ãƒ­ã‚±ãƒ¼ãƒ«åã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: check.c:1130 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "å¤ã„ロケール\"%s\"を復元ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: controldata.c:128 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "%s を使ã£ãŸåˆ¶å¾¡æƒ…å ±ãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" + +#: controldata.c:139 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: データベースクラスタã®çŠ¶æ…‹ç•°å¸¸\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "ソースクラスタã¯ãƒªã‚«ãƒãƒªãƒ¢ãƒ¼ãƒ‰ä¸­ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã•れã¦ã„ã¾ã™ã€‚アップグレードをã™ã‚‹ã«ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã®é€šã‚Šã« \"rsync\" を実行ã™ã‚‹ã‹ã€ãƒ—ライマリã¨ã—ã¦ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¦ãã ã•ã„。\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "ターゲットクラスタã¯ãƒªã‚«ãƒãƒªãƒ¢ãƒ¼ãƒ‰ä¸­ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã•れã¦ã„ã¾ã™ã€‚アップグレードをã™ã‚‹ã«ã¯ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆã®é€šã‚Šã« \"rsync\" を実行ã™ã‚‹ã‹ã€ãƒ—ライマリã¨ã—ã¦ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã—ã¦ãã ã•ã„。\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚¯ãƒªãƒ¼ãƒ³ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã•れã¦ã„ã¾ã›ã‚“。\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "変æ›å…ˆã‚¯ãƒ©ã‚¹ã‚¿ã¯ã‚¯ãƒªãƒ¼ãƒ³ã«ã‚·ãƒ£ãƒƒãƒˆãƒ€ã‚¦ãƒ³ã•れã¦ã„ã¾ã›ã‚“。\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ã«ã‚¯ãƒ©ã‚¹ã‚¿çŠ¶æ…‹æƒ…å ±ãŒã‚りã¾ã›ã‚“:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "変æ›å…ˆã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«ã‚¯ãƒ©ã‚¹ã‚¿çŠ¶æ…‹æƒ…å ±ãŒã‚りã¾ã›ã‚“:\n" + +#: controldata.c:208 dump.c:51 pg_upgrade.c:333 pg_upgrade.c:370 +#: relfilenode.c:244 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal ã§å•題発生\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: 制御情報ã®å–å¾—ã§å•題発生\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«å¿…è¦ãªåˆ¶å¾¡æƒ…å ±ã®ä¸€éƒ¨ãŒã‚りã¾ã›ã‚“:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "変æ›å…ˆã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã«å¿…è¦ãªåˆ¶å¾¡æƒ…å ±ã®ä¸€éƒ¨ãŒã‚りã¾ã›ã‚“:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘る次㮠XID\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " 最新ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘る次㮠OID\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " 最新ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘る次㮠MultiXactId\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " 最新ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘る最å¤ã® MultiXactId\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " 最新ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã«ãŠã‘る次㮠MultiXactOffset\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " ãƒªã‚»ãƒƒãƒˆå¾Œã®æœ€åˆã® WAL セグメント\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 引数ãŒãƒ¡ã‚½ãƒƒãƒ‰ã‚’渡ã—ã¦ã„ã¾ã™\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " 最大アラインメント\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " ブロックサイズ\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " リレーションセグメントã®ã‚µã‚¤ã‚º\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL ã®ãƒ–ロックサイズ\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL ã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆ サイズ\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " 識別å­ã®æœ€å¤§é•·\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹å¯¾è±¡ã‚«ãƒ©ãƒ ã®æœ€å¤§æ•°\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " 最大㮠TOAST ãƒãƒ£ãƒ³ã‚¯ã‚µã‚¤ã‚º\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " ラージオブジェクトã®ãƒãƒ£ãƒ³ã‚¯ã‚µã‚¤ã‚º\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " 日付/æ™‚é–“ãŒæ•´æ•°ï¼Ÿ\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " データãƒã‚§ãƒƒã‚¯ã‚µãƒ ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "å¿…è¦ãªåˆ¶å¾¡æƒ…å ±ãŒãªã„ã®ã§ç¶šè¡Œã§ãã¾ã›ã‚“。終了ã—ã¦ã„ã¾ã™\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ã‚¢ãƒ©ã‚¤ãƒ³ãƒ¡ãƒ³ãƒˆãŒæœ‰åйã§ãªã„ã‹ã¾ãŸã¯ä¸€è‡´ã—ã¾ã›ã‚“\n" +"一方ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãŒ32ビットã§ã€ã‚‚ã†ä¸€æ–¹ãŒ64ビットã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ãƒ–ãƒ­ãƒƒã‚¯ã‚µã‚¤ã‚ºãŒæœ‰åйã§ãªã„ã‹ã¾ãŸã¯ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã®æœ€å¤§ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚µã‚¤ã‚ºãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ WAL ãƒ–ãƒ­ãƒƒã‚¯ã‚µã‚¤ã‚ºãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ WAL ã‚»ã‚°ãƒ¡ãƒ³ãƒˆã‚µã‚¤ã‚ºãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘る識別å­ã®æœ€å¤§é•·ãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘るインデックス付ãåˆ—ã®æœ€å¤§æ•°ãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘ã‚‹ TOAST ãƒãƒ£ãƒ³ã‚¯ã‚µã‚¤ã‚ºã®æœ€å¤§å€¤ãŒæœ‰åйã§ãªã„ã‹ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘るラージオブジェクトã®ãƒãƒ£ãƒ³ã‚¯ã‚µã‚¤ã‚ºãŒæœ‰åйã§ãªã„ã‹ã¾ãŸã¯ä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "æ–°æ—§ã® pg_controldata ã«ãŠã‘る日付/時刻型データã®ä¿å­˜ãƒã‚¤ãƒˆæ•°ãŒä¸€è‡´ã—ã¾ã›ã‚“\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "旧クラスターã§ã¯ãƒ‡ãƒ¼ã‚¿ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚’使ã£ã¦ã„ã¾ã›ã‚“ãŒã€æ–°ã§ã¯ä½¿ã£ã¦ã„ã¾ã™ã€‚\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "旧クラスターã§ã¯ãƒ‡ãƒ¼ã‚¿ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã‚’使ã£ã¦ã„ã¾ã™ãŒã€æ–°ã§ã¯ä½¿ã£ã¦ã„ã¾ã›ã‚“。\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "æ–°æ—§ã® pg_controldata é–“ã§ãƒã‚§ãƒƒã‚¯ã‚µãƒ ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒä¸€è‡´ã—ã¾ã›ã‚“。\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "æ—§ã® global/pg_control ã« \".old\" サフィックスを追加ã—ã¦ã„ã¾ã™" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "%s ã®åå‰ã‚’ %s ã«å¤‰æ›´ã§ãã¾ã›ã‚“。\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚’èµ·å‹•ã™ã‚‹å ´åˆã€%s/global/pg_control.old ã‹ã‚‰\n" +"\".old\"サフィックスを削除ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ã“れã¯\n" +"「リンクã€ãƒ¢ãƒ¼ãƒ‰ã ã£ãŸãŸã‚ã€ã„ã£ãŸã‚“æ–°ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ãŒèµ·å‹•ã—ã¦\n" +"ã—ã¾ã†ã¨ã€æ—§ã‚’安全ã«é–‹å§‹ã§ããªããªã‚‹ã‹ã‚‰ã§ã™ã€‚\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "グローãƒãƒ«ã‚ªãƒ–ジェクトã®ãƒ€ãƒ³ãƒ—を作æˆã—ã¦ã„ã¾ã™" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "データベーススキーマã®ãƒ€ãƒ³ãƒ—を作æˆã—ã¦ã„ã¾ã™ã€‚\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "%s を使ã£ã¦ pg_ctl ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒ‡ãƒ¼ã‚¿ã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "pg_ctl ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³å‡ºåŠ›ã‚’ %s ã‹ã‚‰å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "コマンドãŒé•·ã™ãŽã¾ã™\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:101 option.c:217 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "ログ ファイル\"%s\"ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*失敗*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "\"%s\"を実行ã—ã¦ã„ã¦å•題ãŒç™ºç”Ÿã—ã¾ã—ãŸ\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"失敗ã®åŽŸå› ã«ã¤ã„ã¦ã¯\"%s\"ã¾ãŸã¯\"%s\"ã®æœ€å¾Œã®æ•°è¡Œã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" +"\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"失敗ã®åŽŸå› ã«ã¤ã„ã¦ã¯ã€\"%s\"ã®æœ€å¾Œã®æ•°è¡Œã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" +"\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "ファイル\"%s\"を読ã¿å–り用ã¨ã—ã¦ã‚ªãƒ¼ãƒ—ンã§ãã¾ã›ã‚“ã§ã—ãŸ:%s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "カレントディレクトリã«å¯¾ã—ã¦èª­ã¿æ›¸ãå¯èƒ½ãªã‚¢ã‚¯ã‚»ã‚¹æ¨©ãŒå¿…è¦ã§ã™ã€‚\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\"ã¯ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸï¼šé€šå¸¸ãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸï¼šãƒ•ァイルãŒèª­ã‚ã¾ã›ã‚“(権é™ãŒæ‹’å¦ã•れã¾ã—ãŸï¼‰\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "\"%s\"ã®ãƒã‚§ãƒƒã‚¯ã«å¤±æ•—ã—ã¾ã—ãŸï¼šå®Ÿè¡Œã§ãã¾ã›ã‚“(権é™ãŒæ‹’å¦ã•れã¾ã—ãŸï¼‰\n" + +#: file.c:44 file.c:147 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: file.c:49 file.c:156 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: file.c:63 file.c:187 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"を読ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: file.c:75 file.c:265 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"ã«æ›¸ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: file.c:89 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー(\"%s\" -> \"%s\")中ã«ã‚¨ãƒ©ãƒ¼ï¼š%s\n" + +#: file.c:108 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "リレーション\"%s.%s\"ã¸ã®ãƒªãƒ³ã‚¯ï¼ˆ\"%s\" -> \"%s\")作æˆä¸­ã«ã‚¨ãƒ©ãƒ¼ï¼š%s\n" + +#: file.c:151 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"ã‚’ stat ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: file.c:190 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "リレーション\"%s.%s\"ã®ã‚³ãƒ”ー中ã«ã‚¨ãƒ©ãƒ¼: ファイル\"%s\"中ã«ä¸å®Œå…¨ãªãƒšãƒ¼ã‚¸ãŒã‚りã¾ã—ãŸ\n" + +#: file.c:293 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"æ–°æ—§ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªé–“ã§ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ã‚’作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +"リンクモードã§ã¯ã€æ–°æ—§ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒåŒã˜ãƒ•ァイルシステム上ã«å­˜åœ¨ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“。\n" + +#: function.c:110 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã§ \"public\" スキーマ内㫠\"plpython_call_handler\" \n" +"関数ãŒå®šç¾©ã•れã¦ã„ã¾ã™ãŒã€ã“れ㌠\"pg_catalog\" スキーマã§å®šç¾©\n" +"ã•れã¦ã„ã‚‹ã‚‚ã®ã¨é‡è¤‡ã—ã¦ã„ã¾ã™ã€‚ã“れ㯠psql ã§ä»¥ä¸‹ã‚’実行ã™ã‚‹ã“ã¨ã§\n" +"確èªã§ãã¾ã™:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"\"public\" スキーマ仕様ã«åŸºã¥ãã“ã®é–¢æ•°ã¯ plpython ã® 8.1 以å‰ã®ç’°å¢ƒã§\n" +"作æˆã•れãŸã‚‚ã®ã§ã€ã™ã§ã«å»ƒæ­¢æ¸ˆã¿ã® \"plpython\" 共有オブジェクト\n" +"å‚ç…§ã—ã¦ã„ã‚‹ãŸã‚ã€äºˆã‚削除ã—ã¦ãŠã‹ãªã„㨠pg_upgrade を完了\n" +"ã§ãã¾ã›ã‚“。以下ã®ã‚³ãƒžãƒ³ãƒ‰ã«ã‚ˆã‚Š \"public\" スキーマ仕様ã®ã“ã®\n" +"関数を削除ã§ãã¾ã™: \n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"ã‚’ã€ã“ã®é–¢æ•°ã‚’å‚ç…§ã—ã¦ã„ã‚‹ãれãžã‚Œã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã§å®Ÿè¡Œã—ã¦ãã ã•ã„。\n" +"\n" + +#: function.c:128 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:138 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "継続ã™ã‚‹ã«ã¯ã€æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‹ã‚‰å•題ã¨ãªã£ã¦ã„る関数を削除ã—ã¦ãã ã•ã„。\n" + +#: function.c:211 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "å¿…è¦ãªãƒ©ã‚¤ãƒ–ãƒ©ãƒªã®æœ‰ç„¡ã‚’確èªã—ã¦ã„ã¾ã™" + +#: function.c:255 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "ライブラリ\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"æ—§ã®ç’°å¢ƒã§ã€æ–°ã®ç’°å¢ƒã«ã¯ãªã„ローダブルライブラリをå‚ç…§ã—ã¦ã„ã¾ã™ã€‚\n" +"ã“れらã®ãƒ©ã‚¤ãƒ–ラリを新ã®ç’°å¢ƒã«è¿½åŠ ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯æ—§ã®ç’°å¢ƒã‹ã‚‰\n" +"ãれらを使ã£ã¦ã„る関数を削除ã—ã¦ãã ã•ã„。 å•題ã®ãƒ©ã‚¤ãƒ–ラリã®ä¸€è¦§ã¯ã€\n" +"以下ã®ãƒ•ァイルã«å…¥ã£ã¦ã„ã¾ã™:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "データベース\"%2$s\"ã§ OID %1$u ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³åãŒä¸€è‡´ã—ã¾ã›ã‚“: å…ƒã®åå‰ \"%3$s.%4$s\"ã€æ–°ã—ã„åå‰ \"%5$s.%6$s\"\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "データベース\"%s\"ã§æ–°æ—§ã®ãƒ†ãƒ¼ãƒ–ルã®ç…§åˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " ã“れ㯠\"%s.%s\" 上ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr " ã“れ㯠OID %u 上ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã§ã™" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " ã“れ㯠\"%s.%s\" ã® TOAST テーブルã§ã™" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " ã“れ㯠OID %u ã® TOAST テーブルã§ã™" + +#: info.c:276 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "データベース\"%2$s\"ã§ OID %1$u ã‚’æŒã¤æ–°ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæ—§ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼å†…ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %3$s\n" + +#: info.c:279 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "データベース\"%2$s\"ã§ OID %1$u ã‚’æŒã¤æ—§ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒæ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼å†…ã«è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %3$s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "データベース\"%s\"ã®ãƒžãƒƒãƒ”ング:\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u -> %u\n" + +#: info.c:299 info.c:638 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"変æ›å…ƒãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"変æ›å…ˆãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹:\n" + +#: info.c:636 +#, c-format +msgid "Database: %s\n" +msgstr "データベース: %s\n" + +#: info.c:649 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:98 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: root ã§ã¯å®Ÿè¡Œã§ãã¾ã›ã‚“\n" + +#: option.c:172 +#, c-format +msgid "invalid old port number\n" +msgstr "æ—§ãƒãƒ¼ãƒˆç•ªå·ãŒç„¡åйã§ã™\n" + +#: option.c:180 +#, c-format +msgid "invalid new port number\n" +msgstr "æ–°ãƒãƒ¼ãƒˆç•ªå·ãŒç„¡åйã§ã™\n" + +#: option.c:202 +#, c-format +msgid "Running in verbose mode\n" +msgstr "冗長モードã§å®Ÿè¡Œã—ã¦ã„ã¾ã™\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "詳細ã¯\"%s --help\"ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" + +#: option.c:242 +msgid "old cluster binaries reside" +msgstr "旧クラスターã®ãƒã‚¤ãƒŠãƒªãŒå­˜åœ¨ã—ã¾ã™" + +#: option.c:244 +msgid "new cluster binaries reside" +msgstr "新クラスターã®ãƒã‚¤ãƒŠãƒªãŒå­˜åœ¨ã—ã¾ã™" + +#: option.c:246 +msgid "old cluster data resides" +msgstr "旧クラスターã®ãƒ‡ãƒ¼ã‚¿ãŒå­˜åœ¨ã—ã¾ã™" + +#: option.c:248 +msgid "new cluster data resides" +msgstr "新クラスターã®ãƒ‡ãƒ¼ã‚¿ãŒå­˜åœ¨ã—ã¾ã™" + +#: option.c:265 option.c:462 +#, c-format +msgid "could not determine current directory\n" +msgstr "カレントディレクトリを特定ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: option.c:268 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "Windows ã®å ´åˆã€æ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã®ä¸­ã‹ã‚‰ pg_upgrade を実行ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。\n" + +#: option.c:277 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade ã¯ã€PostgreSQL ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã‚’別ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã«ã‚¢ãƒƒãƒ—グレードã—ã¾ã™ã€‚\n" +"\n" + +#: option.c:278 +#, c-format +msgid "Usage:\n" +msgstr "ä½¿ã„æ–¹:\n" + +#: option.c:279 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [オプション]...\n" +"\n" + +#: option.c:280 +#, c-format +msgid "Options:\n" +msgstr "オプション:\n" + +#: option.c:281 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR 旧クラスターã®å®Ÿè¡Œãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: option.c:282 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINDIR 新クラスターã®å®Ÿè¡Œãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: option.c:283 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check クラスターã®ãƒã‚§ãƒƒã‚¯ã®ã¿ã§ã€ãƒ‡ãƒ¼ã‚¿ã‚’一切変更ã—ã¾ã›ã‚“\n" + +#: option.c:284 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR 旧クラスターã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: option.c:285 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR 新クラスターã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\n" + +#: option.c:286 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs åŒæ™‚並行プロセス数ã¾ãŸã¯ä½¿ç”¨ã‚¹ãƒ¬ãƒƒãƒ‰æ•°\n" + +#: option.c:287 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link æ–°ã—ã„クラスターã«ãƒ•ァイルをコピーã™ã‚‹ä»£ã‚りã«ãƒªãƒ³ã‚¯ã‚’作æˆã—ã¾ã™\n" + +#: option.c:288 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONS サーãƒãƒ¼ã«æ¸¡ã™æ—§ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ã‚ªãƒ—ション\n" + +#: option.c:289 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=OPTIONS サーãƒãƒ¼ã«æ¸¡ã™æ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®ã‚ªãƒ—ション\n" + +#: option.c:290 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT 旧クラスターã®ãƒãƒ¼ãƒˆç•ªå·(デフォルト %d)\n" + +#: option.c:291 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT 新クラスターã®ãƒãƒ¼ãƒˆç•ªå·(デフォルト %d)\n" + +#: option.c:292 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain SQL ã¨ãƒ­ã‚°ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ã€æˆåŠŸå¾Œã‚‚æ¶ˆã•ãšã«æ®‹ã—ã¾ã™\n" + +#: option.c:293 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAME クラスターã®ã‚¹ãƒ¼ãƒ‘ーユーザー (デフォルト\"%s\")\n" + +#: option.c:294 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose 詳細ãªå†…部ログをå–å¾—ã—ã¾ã™\n" + +#: option.c:295 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" + +#: option.c:296 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" + +#: option.c:297 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"pg_upgrade を実行ã™ã‚‹å‰ã«ã€ä»¥ä¸‹ã®ã“ã¨ã‚’行ã£ã¦ãã ã•ã„:\n" +" (新ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® initdb を使ã£ã¦ï¼‰æ–°ã—ã„データベースクラスターを作æˆã™ã‚‹\n" +" æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® postmaster をシャットダウンã™ã‚‹\n" +" æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã® postmaster をシャットダウンã™ã‚‹\n" + +#: option.c:302 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"pg_upgrade ã‚’å‹•ã‹ã™å ´åˆã€æ¬¡ã®æƒ…報を指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™: \n" +" 旧クラスターã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª (-d DATADIR)\n" +" 新クラスターã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª (-D DATADIR) \n" +" æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®\"bin\"ディレクトリ (-b BINDIR)\n" +" æ–°ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®\"bin\"ディレクトリ(-B BINDIR)\n" + +#: option.c:308 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"実行例:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"ã¾ãŸã¯\n" + +#: option.c:313 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:319 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:325 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ä¸å…·åˆã¯ ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" + +#: option.c:358 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"%s ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"コマンドラインオプション %s ã¾ãŸã¯ç’°å¢ƒå¤‰æ•° %s を使用ã—ã¦ãã ã•ã„。\n" + +#: option.c:409 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "変æ›å…ƒã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®å®Ÿéš›ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’検索ã—ã¦ã„ã¾ã™" + +#: option.c:411 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "変æ›å…ˆã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã®å®Ÿéš›ã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’検索ã—ã¦ã„ã¾ã™" + +#: option.c:423 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "%s を使ã£ã¦ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s\n" + +#: option.c:488 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "ファイル\"%2$s\"ã®%1$d行目を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %3$s\n" + +#: option.c:506 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "ãƒ¦ãƒ¼ã‚¶ãƒ¼æŒ‡å®šã®æ—§ãƒãƒ¼ãƒˆç•ªå· %hu 㯠%hu ã«è¨‚æ­£ã•れã¾ã—ãŸ\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "ワーカープロセスを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "ワーカースレッドを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: parallel.c:310 parallel.c:325 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "å­ãƒ¯ãƒ¼ã‚«ãƒ¼ãŒç•°å¸¸çµ‚了ã—ã¾ã—ãŸ: %s\n" + +#: pg_upgrade.c:106 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "ディレクトリ\"%s\"ã®æ¨©é™ã‚’読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"アップグレードを実行ã—ã¦ã„ã¾ã™ã€‚\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "新クラスター用ã®ã€æ¬¡ã® OID を設定ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "データディレクトリをディスクã«åŒæœŸã—ã¾ã™" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"アップグレードãŒå®Œäº†ã—ã¾ã—ãŸ\n" +"----------------\n" + +#: pg_upgrade.c:231 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"旧クラスター用㮠postmaster サービスãŒå‹•ã„ã¦ã„るよã†ã§ã™ã€‚\n" +"ãã® postmaster をシャットダウンã—ã¦ã‹ã‚‰ã€ã‚‚ã†ä¸€åº¦ã‚„り直ã—ã¦ãã ã•ã„。\n" + +#: pg_upgrade.c:244 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"新クラスター用㮠postmaster サービスãŒå‹•ã„ã¦ã„るよã†ã§ã™ã€‚\n" +"ãã® postmaster をシャットダウンã—ã¦ã‹ã‚‰ã€ã‚‚ã†ä¸€åº¦ã‚„り直ã—ã¦ãã ã•ã„。\n" + +#: pg_upgrade.c:250 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 自身ã®ãŸã‚ã®å®Ÿè¡Œãƒ•ァイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_upgrade.c:267 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "新クラスター内ã®ã™ã¹ã¦ã®è¡Œã‚’分æžã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:280 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "新クラスター内ã®ã™ã¹ã¦ã®è¡Œã‚’å‡çµã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:300 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "新クラスター内ã®ã‚°ãƒ­ãƒ¼ãƒãƒ«ã‚ªãƒ–ジェクトを復元ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:315 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "新クラスター内ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚¹ã‚­ãƒ¼ãƒžã‚’復元ã—ã¦ã„ã¾ã™ã€‚\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "æ–°ã—ã„ %s ã‹ã‚‰ãƒ•ァイルを削除ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "ディレクトリ\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "æ—§ã® %s を新サーãƒãƒ¼ã«ã‚³ãƒ”ーã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "新クラスター用ã®ã€æ¬¡ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ ID 㨠epoch 値を設定ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "新クラスター用ã®ã€æ¬¡ã® multixact ID ã¨ã‚ªãƒ•セット値を設定ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "æ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼å†…ã§æœ€ã‚‚éŽåŽ»ã® multixact ID を設定ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "WAL アーカイブをリセットã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "新クラスター内㧠frozenxid 㨠minmxid カウンターを設定ã—ã¦ã„ã¾ã™" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "新クラスター内㧠minmxid カウンターを設定ã—ã¦ã„ã¾ã™" + +#: relfilenode.c:34 +#, c-format +msgid "Linking user relation files\n" +msgstr "ユーザーリレーションã®ãƒ•ァイルをリンクã—ã¦ã„ã¾ã™\n" + +#: relfilenode.c:36 +#, c-format +msgid "Copying user relation files\n" +msgstr "ユーザーリレーションã®ãƒ•ァイルをコピーã—ã¦ã„ã¾ã™\n" + +#: relfilenode.c:110 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "æ–°ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼å†…ã«æ—§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%s\"ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n" + +#: relfilenode.c:231 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\"ファイル (\"%s\" -> \"%s\")ã®å­˜åœ¨ã‚’確èªä¸­ã«ã‚¨ãƒ©ãƒ¼: %s\n" + +#: relfilenode.c:249 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "\"%s\"ã‚’\"%s\"ã«æ›¸ãæ›ãˆã¦ã„ã¾ã™\n" + +#: relfilenode.c:255 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "\"%s\"ã‚’\"%s\"ã«ã‚³ãƒ”ーã—ã¦ã„ã¾ã™\n" + +#: relfilenode.c:261 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "\"%s\"ã‹ã‚‰\"%s\"ã¸ãƒªãƒ³ã‚¯ã‚’作æˆã—ã¦ã„ã¾ã™\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "データベースã¸ã®æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "失敗ã—ã¾ã—ãŸã€çµ‚了ã—ã¦ã„ã¾ã™\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "実行中: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãƒ•ァイルを開ã‘ã¾ã›ã‚“: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "%s ã‹ã‚‰ PG_VERSION ファイルを読ã¿å–れã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"データベースã¸ã®æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"%s\n" +"ã¨ã„ã†ã‚³ãƒžãƒ³ãƒ‰ã§é–‹å§‹ã—ãŸå¤‰æ›å…ƒ postmaster ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"%s\n" +"ã¨ã„ã†ã‚³ãƒžãƒ³ãƒ‰ã§é–‹å§‹ã—ãŸå¤‰æ›å…ˆ postmaster ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl ãŒå¤‰æ›å…ƒã‚µãƒ¼ãƒã®é–‹å§‹ã¾ãŸã¯æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl ãŒå¤‰æ›å…ˆã‚µãƒ¼ãƒã®é–‹å§‹ã¾ãŸã¯æŽ¥ç¶šã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "メモリä¸è¶³ã§ã™\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq ã®ç’°å¢ƒå¤‰æ•° %s ã§ã€ãƒ­ãƒ¼ã‚«ãƒ«ã§ãªã„サーãƒå€¤ãŒè¨­å®šã•れã¦ã„ã¾ã™: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"テーブル空間を使用ã™ã‚‹å ´åˆã€\n" +"åŒä¸€ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚·ã‚¹ãƒ†ãƒ ã‚«ã‚¿ãƒ­ã‚°åŒå£«ã§ã‚¢ãƒƒãƒ—グレードã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "テーブル空間ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "テーブル空間ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª\"%s\"ã‚’ stat ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "テーブル空間ã®ãƒ‘ス\"%s\"ãŒãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã§ã¯ã‚りã¾ã›ã‚“。\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "ラージオブジェクトをãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "警告" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"変æ›å…ƒã®ç’°å¢ƒã«ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクトãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚æ–°ã—ã„データベースã§ã¯\n" +"ラージオブジェクトã®ãƒ‘ーミッションテーブルãŒè¿½åŠ ã•れã¦ã„ã¾ã™ã€‚\n" +"アップグレードãŒçµ‚ã‚ã£ãŸã‚‰ã€ pg_largeobject_metadata テーブルã«\n" +"デフォルトã®ãƒ‘ーミッションを投入ã™ã‚‹ãŸã‚ã®ã‚³ãƒžãƒ³ãƒ‰ãŒæ¡ˆå†…ã•れã¾ã™ã€‚\n" +"\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"変æ›å…ƒã®ç’°å¢ƒã«ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ジェクトãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚æ–°ã—ã„データベースã§ã¯\n" +"ラージオブジェクトã®ãƒ‘ーミッションテーブルãŒè¿½åŠ ã•れã¦ãŠã‚Šã€ã™ã¹ã¦ã®ãƒ©ãƒ¼ã‚¸\n" +"オブジェクトã«ã¤ã„ã¦ã€ãƒ‡ãƒ•ォルトã®ãƒ‘ーミッションを定義ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"データベースã®ã‚¹ãƒ¼ãƒ‘ーユーザã«ãªã£ã¦ã€psql を使ã£ã¦ãƒ•ァイル\n" +" %s\n" +"を実行ã™ã‚‹ã¨ã€ãƒ‡ãƒ•ォルトã®ãƒ‘ーミッションを設定ã§ãã¾ã™ã€‚\n" +"\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "éžäº’æ›ã® \"line\" データ型を確èªã—ã¦ã„ã¾ã™" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"変æ›å…ƒã®ç’°å¢ƒã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ†ãƒ¼ãƒ–ル㫠\"line\" データ型ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚\n" +"ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯æ–°æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼é–“ã§å†…部形å¼ã‚„入出力フォーマットãŒ\n" +"変更ã•れã¦ã„ã‚‹ãŸã‚ã€ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã¯ç¾æ™‚点ã§ã¯ã‚¢ãƒƒãƒ—グレードã§ãã¾ã›ã‚“。\n" +"å•題ã®ãƒ†ãƒ¼ãƒ–ルを削除ã—ã¦ã‹ã‚‰ã€å†åº¦ã‚¢ãƒƒãƒ—グレードを実行ã—ã¦ãã ã•ã„。\n" +"å•題ã®ã‚る列ã¯ã€ä»¥ä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã‹ã‚Œã¦ã„ã¾ã™ï¼š\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "無効㪠\"unknown\" ユーザ列をãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"変æ›å…ƒã®ç’°å¢ƒã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ãƒ†ãƒ¼ãƒ–ル㫠\"unknown\" データ型ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã¯ã‚‚ã¯ã‚„\n" +"テーブル内ã§ã¯åˆ©ç”¨ã§ãã¾ã›ã‚“ã®ã§ã€ã“ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼ã¯ç¾æ™‚点ã§ã¯ã‚¢ãƒƒãƒ—グレードã§ãã¾ã›ã‚“。\n" +"å•題ã®ãƒ†ãƒ¼ãƒ–ルを削除ã—ã¦ã‹ã‚‰ã€å†åº¦ã‚¢ãƒƒãƒ—グレードを実行ã—ã¦ãã ã•ã„。\n" +"å•題ã®ã‚る列ã¯ã€ä»¥ä¸‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã‹ã‚Œã¦ã„ã¾ã™ï¼š\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’ãƒã‚§ãƒƒã‚¯ã—ã¦ã„ã¾ã™" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"変æ›å…ƒã®ç’°å¢ƒã«ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“れらã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯\n" +"æ–°æ—§ã®ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼é–“ã§ãƒ•ォーマットãŒç•°ãªã‚‹ãŸã‚ã€REINDEX コマンドを使ã£ã¦\n" +"冿§‹ç¯‰ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"アップグレードãŒçµ‚ã‚ã£ãŸã‚‰ã€REINDEX を使ã£ãŸæ“作方法ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"変æ›å…ƒã®ç’°å¢ƒã«ãƒãƒƒã‚·ãƒ¥ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚ã“れらã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯æ–°æ—§ã®\n" +"クラスター間ã§ãƒ•ォーマットãŒç•°ãªã‚‹ãŸã‚ã€REINDEX コマンドを使ã£ã¦å†æ§‹ç¯‰ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"データベースã®ã‚¹ãƒ¼ãƒ‘ーユーザã«ãªã£ã¦ã€psql を使ã£ã¦ãƒ•ァイル\n" +" %s\n" +"を実行ã™ã‚‹ã“ã¨ã§ã€ç„¡åйã«ãªã£ãŸã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’å†ç”Ÿæˆã§ãã¾ã™ã€‚\n" +"ãれã¾ã§ã¯ã€ã“れらã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã¯ä¸€åˆ‡ä½¿ã‚れã¾ã›ã‚“。\n" +"\n" diff --git a/src/bin/pg_upgrade/po/ko.po b/src/bin/pg_upgrade/po/ko.po new file mode 100644 index 00000000000..8a1577cf363 --- /dev/null +++ b/src/bin/pg_upgrade/po/ko.po @@ -0,0 +1,1645 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 16:16+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"옛 ìš´ì˜ ì„œë²„ì—서 ì¼ê´€ì„± 검사를 진행합니다.\n" +"------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"ì¼ê´€ì„± 검사 수행중\n" +"------------------\n" + +#: check.c:166 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*í´ëŸ¬ìŠ¤í„° 호환성*\n" + +#: check.c:172 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"여기서 pg_upgrade ìž‘ì—…ì„ ì‹¤íŒ¨í•œë‹¤ë©´, ìž¬ì‹œë„ í•˜ê¸° ì „ì— ë¨¼ì €\n" +"새 í´ëŸ¬ìŠ¤í„°ë¥¼ 처ìŒë¶€í„° 다시 만들어 진행해야 합니다.\n" + +#: check.c:208 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"pg_upgrade 작업ì—서는 최ì í™”기를 위한 통계 정보까지 업그레ì´ë“œ\n" +"하지는 않습니다. 새 서버가 실행 ë  ë•Œ, ë‹¤ìŒ ëª…ë ¹ì„ ìˆ˜í–‰í•˜ê¸¸ 권합니다:\n" +" %s\n" +"\n" + +#: check.c:213 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"pg_upgrade 작업으로는 통계 정보와 빈 공간 정보는 업그레ì´ë“œ ë˜ì§€\n" +"않습니다. 새 서버가 실행 ë  ë•Œ, ë‹¤ìŒ ëª…ë ¹ì„ ìˆ˜í–‰í•˜ê¸¸ 권합니다:\n" +" %s\n" +"\n" + +#: check.c:220 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"아래 스í¬ë¦½íŠ¸ë¥¼ 실행하면, 옛 í´ëŸ¬ìŠ¤í„° ìžë£Œë¥¼ 지울 것입니다:\n" +" %s\n" + +#: check.c:225 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"옛 í´ëŸ¬ìŠ¤í„° ìžë£Œ 파ì¼ì„ 지우는 스í¬ë¦½íŠ¸ë¥¼ 만들지 못했습니다.\n" +"ì‚¬ìš©ìž ì •ì˜ í…Œì´ë¸”스페ì´ìŠ¤ë‚˜, 새 í´ëŸ¬ìŠ¤í„°ê°€ 옛 í´ëŸ¬ìŠ¤í„° 안ì—\n" +"있기 때문입니다. 옛 í´ëŸ¬ìŠ¤í„° ìžë£ŒëŠ” ì§ì ‘ 찾아서 지우세요.\n" + +#: check.c:235 +#, c-format +msgid "Checking cluster versions" +msgstr "í´ëŸ¬ìŠ¤í„° 버전 검사 중" + +#: check.c:247 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "ì´ ë„구는 PostgreSQL 8.4 ì´ìƒ 버전ì—서 사용할 수 있습니다.\n" + +#: check.c:251 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "ì´ ë„구는 PostgreSQL %s 버전으로만 업그레ì´ë“œ í•  수 있습니다.\n" + +#: check.c:260 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "ì´ ë„구는 ë” ë‚®ì€ ë©”ì´ì ¸ PostgreSQL 버전으로 다운그레ì´ë“œí•˜ëŠ”ë° ì‚¬ìš©í•  수 없습니다.\n" + +#: check.c:265 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„° ìžë£Œì™€ ì‹¤í–‰íŒŒì¼ ë””ë ‰í„°ë¦¬ê°€ 서로 ë©”ì´ì ¸ ë²„ì „ì´ ë‹¤ë¦…ë‹ˆë‹¤.\n" + +#: check.c:268 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "새 í´ëŸ¬ìŠ¤í„° ìžë£Œì™€ ì‹¤í–‰íŒŒì¼ ë””ë ‰í„°ë¦¬ê°€ 서로 ë©”ì´ì ¸ ë²„ì „ì´ ë‹¤ë¦…ë‹ˆë‹¤.\n" + +#: check.c:285 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "옛 서버가 9.1 버전 ì´ì „ ì´ë¼ë©´ 옛 ì„œë²„ì˜ í¬íŠ¸ë¥¼ 반드시 지정해야 합니다.\n" + +#: check.c:289 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "ìš´ì˜ ì„œë²„ 검사를 í•  때는, 옛 서버, 새 ì„œë²„ì˜ í¬íŠ¸ë¥¼ 다르게 지정해야 합니다.\n" + +#: check.c:304 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì˜ ì¸ì½”ë”©ì´ ì„œë¡œ 다릅니다: 옛 서버 \"%s\", 새 서버 \"%s\"\n" + +#: check.c:309 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì˜ lc_collate ê°’ì´ ì„œë¡œ 다릅니다: 옛 서버 \"%s\", 새 서버 \"%s\"\n" + +#: check.c:312 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ì˜ lc_ctype ê°’ì´ ì„œë¡œ 다릅니다: 옛 서버 \"%s\", 새 서버 \"%s\"\n" + +#: check.c:385 +#, c-format +msgid "New cluster database \"%s\" is not empty\n" +msgstr "\"%s\" 새 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ê°€ 비어있지 않습니다.\n" + +#: check.c:432 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„° 통계정보 수집 스í¬ë¦½íŠ¸ë¥¼ 만듭니다" + +#: check.c:446 check.c:574 check.c:838 check.c:941 check.c:1032 function.c:253 +#: option.c:480 version.c:57 version.c:156 version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" + +#: check.c:501 check.c:630 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "\"%s\" 파ì¼ì— 실행 ê¶Œí•œì„ ì¶”ê°€ í•  수 ì—†ìŒ: %s\n" + +#: check.c:537 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"경고: 새 ë°ì´í„° 디렉터리는 옛 ë°ì´í„° 디렉터리 ì•ˆì— ë‘˜ 수 없습니다, 예: %s\n" + +#: check.c:561 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"경고: ì‚¬ìš©ìž ì •ì˜ í…Œì´ë¸”스페ì´ìФ 위치를 ë°ì´í„° 디렉터리 ì•ˆì— ë‘˜ 수 없습니다, 예: %s\n" + +#: check.c:571 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ë¥¼ 지우는 스í¬ë¦½íŠ¸ë¥¼ 만듭니다" + +#: check.c:650 +#, c-format +msgid "Checking database user is the install user" +msgstr "ë°ì´í„°ë² ì´ìФ 사용ìžê°€ 설치 ìž‘ì—…ì„ í•œ 사용ìžì¸ì§€ 확ì¸í•©ë‹ˆë‹¤" + +#: check.c:666 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 사용ìžëŠ” 설치 ìž‘ì—…ì„ í•œ 사용ìžê°€ 아닙니다\n" + +#: check.c:677 +#, c-format +msgid "could not determine the number of users\n" +msgstr "ì‚¬ìš©ìž ìˆ˜ë¥¼ 확ì¸í•  수 ì—†ìŒ\n" + +#: check.c:685 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì—서만 설치 사용 사용ìžê°€ ì •ì˜ë  수 있ìŒ\n" + +#: check.c:705 +#, c-format +msgid "Checking database connection settings" +msgstr "ë°ì´í„°ë² ì´ìФ ì—°ê²° ì„¤ì •ì„ í™•ì¸ ì¤‘" + +#: check.c:727 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 ë°ì´í„°ë² ì´ìФ ì ‘ì†ì„ 금지해야 합니다. 예: 해당 ë°ì´í„°ë² ì´ìŠ¤ì˜ pg_database.datallowconn ê°’ì´ false여야 합니다.\n" + +#: check.c:737 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "template0 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 제외한 다른 모든 ë°ì´í„°ë² ì´ìŠ¤ëŠ” ì ‘ì†ì´ 가능해야합니다. 예: ê·¸ë“¤ì˜ pg_database.datallowconn ê°’ì€ true여야 합니다.\n" + +#: check.c:762 +#, c-format +msgid "Checking for prepared transactions" +msgstr "미리 ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì„ í™•ì¸ ì¤‘" + +#: check.c:771 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ì— ë¯¸ë¦¬ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆìŒ\n" + +#: check.c:773 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì— ë¯¸ë¦¬ ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì´ ìžˆìŒ\n" + +#: check.c:799 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "contrib/isn ëª¨ë“ˆì˜ bigint 처리가 서로 ê°™ì€ì§€ í™•ì¸ ì¤‘" + +#: check.c:860 check.c:964 check.c:1055 function.c:268 version.c:179 +#: version.c:280 +#, c-format +msgid "fatal\n" +msgstr "ì¹˜ëª…ì  ì˜¤ë¥˜\n" + +#: check.c:861 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"설치ë˜ì–´ 있는 \"contrib/isn\" ëª¨ë“ˆì€ bigint ìžë£Œí˜•ì„ ì‚¬ìš©í•©ë‹ˆë‹¤.\n" +"ì´ bigint ìžë£Œí˜•ì˜ ì²˜ë¦¬ ë°©ì‹ì´ 새 버전과 옛 버전 ì‚¬ì´ í˜¸í™˜ì„±ì´ ì—†ìŠµë‹ˆë‹¤.\n" +"ì´ ëª¨ë“ˆì„ ê³„ì† ì‚¬ìš©í•˜ë ¤ë©´, 사용ìžê°€ ì§ì ‘ 업그레ì´ë“œ 해야 합니다.\n" +"먼저 옛 버전ì—서 \"contrib/isn\" ëª¨ë“ˆì„ ì‚­ì œí•˜ê³  서버를 재실행하고, 업그레ì´ë“œ 한 ë’¤\n" +"ì§ì ‘ 나머지 ìž‘ì—…ì„ ì§„í–‰í•˜ì‹­ì‹œì˜¤. 문제가 있는 함수는 아래 íŒŒì¼ ì•ˆì— ìžˆìŠµë‹ˆë‹¤:\n" +" %s\n" +"\n" + +#: check.c:893 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "사용ìžê°€ 만든 í…Œì´ë¸”ì— reg* ìžë£Œí˜•ì„ ì“°ëŠ”ì§€ í™•ì¸ ì¤‘" + +#: check.c:965 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"옛 ì„œë²„ì˜ ì‚¬ìš©ìžê°€ 만든 í…Œì´ë¸”ì—서 reg* ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ê³  있습니다.\n" +"ì´ ìžë£Œí˜•ë“¤ì€ pg_upgrade 명령으로 ë‚´ì •ëœ ì‹œìŠ¤í…œ OID를 사용하지 못할 수\n" +"있습니다. 그래서 업그레ì´ë“œ ìž‘ì—…ì„ ì§„í–‰í•  수 없습니다.\n" +"사용하고 있는 í…Œì´ë¸”ë“¤ì„ ì§€ìš°ê³  업그레ì´ë“œ ìž‘ì—…ì„ ë‹¤ì‹œ 시ë„하세요.\n" +"ì´ëŸ° ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ëŠ” 파ì¼ì€ ë‹¤ìŒ íŒŒì¼ë“¤ 입니다:\n" +" %s\n" +"\n" + +#: check.c:990 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "\"jsonb\" ìžë£Œí˜• 호환성 í™•ì¸ ì¤‘" + +#: check.c:1056 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"ì‚¬ìš©ìž í…Œì´ë¸”ì—서 \"jsonb\" ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ê³  있습니다.\n" +"9.4 베타 비전 ì´í›„ JSONB ë‚´ë¶€ ìžë£Œ 구조가 바뀌었습니다.\n" +"그래서, 업그레ì´ë“œ ìž‘ì—…ì´ ë¶ˆê°€ëŠ¥í•©ë‹ˆë‹¤.\n" +"해당 í…Œì´ë¸”ë“¤ì„ ì§€ìš°ê³  업그레ì´ë“œ ìž‘ì—…ì„ ì§„í–‰í•˜ì„¸ìš”\n" +"해당 ìžë£Œí˜•ì„ ì“°ëŠ” 파ì¼ì€ 다ìŒê³¼ 같습니다:\n" +" %s\n" +"\n" + +#: check.c:1077 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "\"pg_\"로 시작하는 롤 í™•ì¸ ì¤‘" + +#: check.c:1087 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ì— \"pg_\" 시작하는 ë¡¤ì´ ìžˆìŠµë‹ˆë‹¤.\n" + +#: check.c:1089 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì— \"pg_\"로 시작하는 ë¡¤ì´ ìžˆìŠµë‹ˆë‹¤.\n" + +#: check.c:1115 +#, c-format +msgid "failed to get the current locale\n" +msgstr "현재 로케ì¼ì„ í™•ì¸ í•  수 ì—†ìŒ\n" + +#: check.c:1124 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "\"%s\"ìš© 시스템 ë¡œì¼€ì¼ ì´ë¦„ì„ ì•Œ 수 ì—†ìŒ\n" + +#: check.c:1130 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "\"%s\" 옛 로케ì¼ì„ ë³µì›í•  수 ì—†ìŒ\n" + +#: controldata.c:128 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "%s 사용하는 컨트롤 ìžë£Œë¥¼ 구할 수 ì—†ìŒ: %s\n" + +#: controldata.c:139 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„° ìƒíƒœ 문제\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"ì›ë³¸ í´ëŸ¬ìŠ¤í„°ëŠ” 복구 모드(대기 서버 모드나, 복구 중) ìƒíƒœì—서 중지 ë˜ì—ˆìŠµë‹ˆë‹¤. 업그레ì´ë“œ 하려면, ë¬¸ì„œì— ì–¸ê¸‰í•œ 것 처럼 \"rsync\"를 사용하든가, ê·¸ 서버를 ìš´ì˜ ì„œë²„ 모드로 바꾼 ë’¤ 중지하고 작업하십시오.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ëŠ” 복구 모드(대기 서버 모드나, 복구 중) ìƒíƒœì—서 중지 ë˜ì—ˆìŠµë‹ˆë‹¤. 업그레ì´ë“œ 하려면, ë¬¸ì„œì— ì–¸ê¸‰í•œ 것 처럼 \"rsync\"를 사용하든가, ê·¸ 서버를 ìš´ì˜ ì„œë²„ 모드로 바꾼 ë’¤ 중지하고 작업하십시오.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "ì›ë³¸ í´ëŸ¬ìŠ¤í„°ëŠ” ì •ìƒì ìœ¼ë¡œ 종료ë˜ì–´ì•¼ 함\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ëŠ” ì •ìƒ ì¢…ë£Œë˜ì–´ì•¼ 함\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "ì›ë³¸ í´ëŸ¬ìŠ¤í„°ì— í´ëŸ¬ìŠ¤í„° ìƒíƒœ ì •ë³´ê°€ ì—†ìŒ:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ì— í´ëŸ¬ìŠ¤í„° ìƒíƒœ ì •ë³´ê°€ ì—†ìŒ:\n" + +#: controldata.c:208 dump.c:51 pg_upgrade.c:333 pg_upgrade.c:370 +#: relfilenode.c:244 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal 문제\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: controldata ë³µì› ë¬¸ì œ\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ì— í•„ìš”í•œ 컨트롤 ì •ë³´ê°€ 몇몇 빠져있ìŒ:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì— í•„ìš”í•œ 컨트롤 ì •ë³´ê°€ 몇몇 빠져있ìŒ:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " ì²´í¬í¬ì¸íЏ ë‹¤ìŒ XID\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " 마지막 ì²´í¬í¬ì¸íЏ ë‹¤ìŒ OID\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " 마지막 ì²´í¬í¬ì¸íЏ ë‹¤ìŒ MultiXactId\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " 마지막 ì²´í¬í¬ì¸íЏ ì œì¼ ì˜¤ëž˜ëœ MultiXactId\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " 마지막 ì²´í¬í¬ì¸íЏ ë‹¤ìŒ MultiXactOffset\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " 리셋 ë’¤ 첫 WAL ì¡°ê°\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 ì¸ìž 처리 ë°©ì‹\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " 최대 ì •ë ¬\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " ë¸”ë¡ í¬ê¸°\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " 대형 릴레ì´ì…˜ ì¡°ê° í¬ê¸°\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL ë¸”ë¡ í¬ê¸°\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL ì¡°ê° í¬ê¸°\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " 최대 ì‹ë³„ìž ê¸¸ì´\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " 최대 ì¸ë±ìФ 칼럼 수\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " 최대 토스트 ì¡°ê° í¬ê¸°\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " 대형 ê°ì²´ ì¡°ê° í¬ê¸°\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " date/time ìžë£Œí˜•ì„ ì •ìˆ˜ë¡œ?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " ìžë£Œ ì²´í¬ì„¬ 버전\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "필요한 컨트롤 ì •ë³´ ì—†ì´ëŠ” 진행할 수 ì—†ìŒ, 중지 함\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata ì •ë ¬ì´ ì„œë¡œ 다릅니다.\n" +"하나는 32비트고, 하나는 64ë¹„íŠ¸ì¸ ê²½ìš° 같습니다\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata ë¸”ë¡ í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata 최대 릴레ì´ì…˜ ì¡°ê° í¬ê°€ê°€ 서로 다릅니다.\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata WAL ë¸”ë¡ í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata WAL ì¡°ê° í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata 최대 ì‹ë³„ìž ê¸¸ì´ê°€ 서로 다릅니다.\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata 최대 ì¸ë±ìФ 칼럼수가 서로 다릅니다.\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata 최대 토스트 ì¡°ê° í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata 대형 ê°ì²´ ì¡°ê° í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata date/time 저장 í¬ê¸°ê°€ 서로 다릅니다.\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ëŠ” ë°ì´í„° ì²´í¬ì„¬ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ì§€ 않고, 새 í´ëŸ¬ìŠ¤í„°ëŠ” 사용하고 있습니다.\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ëŠ” ë°ì´í„° ì²´í¬ì„¬ ê¸°ëŠ¥ì„ ì‚¬ìš©í•˜ê³ , 새 í´ëŸ¬ìŠ¤í„°ëŠ” 사용하고 있지 않습니다.\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "í´ëŸ¬ìŠ¤í„°ê°„ pg_controldata ì²´í¬ì„¬ ë²„ì „ì´ ì„œë¡œ 다릅니다.\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "옛 global/pg_control 파ì¼ì— \".old\" ì´ë¦„ì„ ë§ë¶™ìž…니다." + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "%s ì´ë¦„ì„ %s ì´ë¦„으로 바꿀 수 ì—†ìŒ.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"옛 버전으로 옛 í´ëŸ¬ìŠ¤í„°ë¥¼ 사용해서 서버를 실행하려면,\n" +"%s/global/pg_control.old 파ì¼ì˜ ì´ë¦„ì„ \".old\" 빼고 바꾸어\n" +"사용해야합니다. 업그레ì´ë“œë¥¼ \"link\" 모드로 했기 때문ì—,\n" +"한번ì´ë¼ë„ 새 ë²„ì „ì˜ ì„œë²„ê°€ ì´ í´ëŸ¬ìŠ¤í„°ë¥¼ ì´ìš©í•´ì„œ 실행ë˜ì—ˆë‹¤ë©´,\n" +"ì´ íŒŒì¼ì´ ë” ì´ìƒ 안전하지 않기 때문입니다.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "ì „ì—­ ê°ì²´ ë¤í”„를 만듭니다" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "ë°ì´í„°ë² ì´ìФ 스키마 ë¤í”„를 만듭니다\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "%s ëª…ë ¹ì„ ì‚¬ìš©í•´ì„œ pg_ctl 버전 ìžë£Œë¥¼ 구할 수 ì—†ìŒ: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "%sì—서 pg_ctl ë²„ì „ì„ ì•Œ 수 ì—†ìŒ\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "ëª…ë ¹ì´ ë„ˆë¬´ 긺\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:101 option.c:217 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "\"%s\" 로그 파ì¼ì„ 쓸 수 ì—†ìŒ\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*실패*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "\"%s\" 실행ì—서 문제 ë°œìƒ\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"\"%s\" ë˜ëŠ” \"%s\" 파ì¼ì˜ 마지막 ë¶€ë¶„ì„ ì‚´íŽ´ë³´ë©´\n" +"ì´ ë¬¸ì œë¥¼ í’€ 실마리가 ë³´ì¼ ê²ƒìž…ë‹ˆë‹¤.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"\"%s\" 파ì¼ì˜ 마지막 ë¶€ë¶„ì„ ì‚´íŽ´ë³´ë©´\n" +"ì´ ë¬¸ì œë¥¼ í’€ 실마리가 ë³´ì¼ ê²ƒìž…ë‹ˆë‹¤.\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "\"%s\" 파ì¼ì„ ì½ê¸° 위해 ì—´ 수 없습니다: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "현재 ë””ë ‰í„°ë¦¬ì˜ ì½ê¸° 쓰기 ê¶Œí•œì„ ë¶€ì—¬í•˜ì„¸ìš”.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "\"%s\" 검사 실패: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" 파ì¼ì€ 디렉터리가 아닙니다.\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "\"%s\" 검사 실패: ì¼ë°˜ 파ì¼ì´ 아닙니다\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "\"%s\" 검사 실패: 해당 파ì¼ì„ ì½ì„ 수 ì—†ìŒ (ì ‘ê·¼ 권한 ì—†ìŒ)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "\"%s\" 검사 실패: 실행할 수 ì—†ìŒ (ì ‘ê·¼ 권한 ì—†ìŒ)\n" + +#: file.c:44 file.c:147 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" + +#: file.c:49 file.c:156 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" 파ì¼ì„ 만들 수 ì—†ìŒ: %s\n" + +#: file.c:63 file.c:180 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" + +#: file.c:75 file.c:258 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" 파ì¼ì„ 쓸 수 ì—†ìŒ: %s\n" + +#: file.c:89 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 릴레ì´ì…˜ 복사 중 오류: %s\n" + +#: file.c:108 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 릴레ì´ì…˜ ë§í¬ 만드는 중 오류: %s\n" + +#: file.c:151 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" íŒŒì¼ ìƒíƒœ 정보를 알 수 ì—†ìŒ: %s\n" + +#: file.c:183 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "\"%s.%s\" 릴레ì´ì…˜ 복사 중 오류: \"%s\" 파ì¼ì— 페ì´ì§€ê°€ ì†ìƒë˜ì—ˆìŒ\n" + +#: file.c:284 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"ë°ì´í„° 디렉터리간 하드 ë§í¬ë¥¼ 만들 수 ì—†ìŒ: %s\n" +"하드 ë§í¬ë¥¼ 사용하려면, ë‘ ë””ë ‰í„°ë¦¬ê°€ ê°™ì€ ì‹œìŠ¤í…œ 볼륨 ì•ˆì— ìžˆì–´ì•¼ 합니다.\n" + +#: function.c:110 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"옛 í´ëŸ¬ìŠ¤í„°ëŠ” \"plpython_call_handler\" 함수가 \"public\" 스키마 안ì—\n" +"ì •ì˜ ë˜ì–´ìžˆìŠµë‹ˆë‹¤. ì´ í•¨ìˆ˜ëŠ” \"pg_catalog\" 스키마 ì•ˆì— ìžˆì–´ì•¼í•©ë‹ˆë‹¤.\n" +"psqlì—서 ë‹¤ìŒ ëª…ë ¹ìœ¼ë¡œ ì´ í•¨ìˆ˜ì˜ ìœ„ì¹˜ë¥¼ 살펴 ë³¼ 수 있습니다:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"\"public\" 스키마 ì•ˆì— ì´ í•¨ìˆ˜ê°€ 있는 경우는 8.1 버전 ì´ì „ 버전ì´ì—ˆìŠµë‹ˆë‹¤.\n" +"업그레ì´ë“œ ìž‘ì—…ì„ ì •ìƒì ìœ¼ë¡œ 마치려면, 먼저 \"plpython\" 관련 ê°ì²´ë“¤ì„ 먼저\n" +"ëª¨ë‘ ì§€ìš°ê³ , 새 버전용 ëª¨ë“ˆì„ ì„¤ì¹˜í•´ì„œ 사용해야 합니다.\n" +"ì´ ì‚­ì œ ìž‘ì—…ì€ ë‹¤ìŒê³¼ ê°™ì´ ì§„í–‰í•©ë‹ˆë‹¤:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"ì´ ìž‘ì—…ì€ ê´€ë ¨ 모든 ë°ì´í„°ë² ì´ìФ 단위로 ì§„í–‰ë˜ì–´ì•¼ 합니다.\n" +"\n" + +#: function.c:128 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:138 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ì—서 문제가 있는 í•¨ìˆ˜ë“¤ì„ ì‚­ì œí•˜ê³  진행하세요.\n" + +#: function.c:211 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "필요한 ë¼ì´ë¸ŒëŸ¬ë¦¬ í™•ì¸ ì¤‘" + +#: function.c:255 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" ë¼ì´ë¸ŒëŸ¬ë¦¬ 로드 실패: %s" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"옛 버전ì—는 있고, 새 버전ì—는 없는 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì´ 있습니다. 새 버전ì—\n" +"해당 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì„ 설치하거나, 옛 버전ì—서 해당 ë¼ì´ë¸ŒëŸ¬ë¦¬ë¥¼ 삭제하고,\n" +"업그레ì´ë“œ ìž‘ì—…ì„ í•´ì•¼í•©ë‹ˆë‹¤. 문제가 있는 ë¼ì´ë¸ŒëŸ¬ë¦¬ë“¤ì€ 다ìŒê³¼ 같습니다:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "%u OIDì— ëŒ€í•œ \"%s\" ë°ì´í„°ë² ì´ìФ ì´ë¦„ì´ ì„œë¡œ 다릅니다: 옛 ì´ë¦„: \"%s.%s\", 새 ì´ë¦„: \"%s.%s\"\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ ë‚´ í…Œì´ë¸” ì´ë¦„ì´ ì„œë¡œ 다릅니다:\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " 해당 ì¸ë±ìФ: \"%s.%s\"" + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr " 해당 ì¸ë±ìŠ¤ì˜ OID: %u" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " \"%s.%s\" ê°ì²´ì˜ 토스트 í…Œì´ë¸”" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " 해당 토스트 ë² ì´ë¸”ì˜ OID: %u" + +#: info.c:276 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì˜ %u OID (해당 ë°ì´í„°ë² ì´ìФ: \"%s\")ê°€ 옛 í´ëŸ¬ìŠ¤í„°ì— ì—†ìŒ: %s\n" + +#: info.c:279 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "옛 í´ëŸ¬ìŠ¤í„°ì˜ %u OID (해당 ë°ì´í„°ë² ì´ìФ: \"%s\")ê°€ 새 í´ëŸ¬ìŠ¤í„°ì— ì—†ìŒ: %s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "\"%s\" ë°ì´í„°ë² ì´ìФ 맵핑 중:\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u / %u\n" + +#: info.c:299 info.c:638 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"ì›ë³¸ ë°ì´í„°ë² ì´ìФ:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"ëŒ€ìƒ ë°ì´í„°ë² ì´ìФ:\n" + +#: info.c:636 +#, c-format +msgid "Database: %s\n" +msgstr "ë°ì´í„°ë² ì´ìФ: %s\n" + +#: info.c:649 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:98 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: root 권한으로 실행할 수 ì—†ìŒ\n" + +#: option.c:172 +#, c-format +msgid "invalid old port number\n" +msgstr "ìž˜ëª»ëœ ì˜› í¬íЏ 번호\n" + +#: option.c:180 +#, c-format +msgid "invalid new port number\n" +msgstr "ìž˜ëª»ëœ ìƒˆ í¬íЏ 번호\n" + +#: option.c:202 +#, c-format +msgid "Running in verbose mode\n" +msgstr "작업 ë‚´ì—­ì„ ìžì„¸ížˆ ë´„\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "보다 ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\" ëª…ë ¹ì„ ì´ìš©í•˜ì„¸ìš”.\n" + +#: option.c:242 +msgid "old cluster binaries reside" +msgstr "옛 í´ëŸ¬ìŠ¤í„° ì‹¤í–‰íŒŒì¼ ìœ„ì¹˜" + +#: option.c:244 +msgid "new cluster binaries reside" +msgstr "새 í´ëŸ¬ìŠ¤í„° ì‹¤íŒ½íŒŒì¼ ìœ„ì¹˜" + +#: option.c:246 +msgid "old cluster data resides" +msgstr "옛 í´ëŸ¬ìŠ¤í„° ìžë£Œ 위치" + +#: option.c:248 +msgid "new cluster data resides" +msgstr "새 í´ëŸ¬ìŠ¤í„° ìžë£Œ 위치" + +#: option.c:265 option.c:462 +#, c-format +msgid "could not determine current directory\n" +msgstr "현재 디렉터리 위치를 알 수 ì—†ìŒ\n" + +#: option.c:268 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "윈ë„우즈 환경ì—서는 pg_upgrade ëª…ë ¹ì€ ìƒˆ í´ëŸ¬ìŠ¤í„° ë°ì´í„° 디렉터리 안ì—서는 실행할 수 ì—†ìŒ\n" + +#: option.c:277 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"새 ë°ì´í„° í´ëŸ¬ìŠ¤í„° 버전과 pg_upgrade ë²„ì „ì˜ ë©”ì´ì € ë²„ì „ì´ ì„œë¡œ 다릅니다.\n" +"\n" + +#: option.c:278 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: option.c:279 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [옵션]...\n" +"\n" + +#: option.c:280 +#, c-format +msgid "Options:\n" +msgstr "옵션:\n" + +#: option.c:281 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR 옛 í´ëŸ¬ìŠ¤í„° 실행 파ì¼ì˜ 디렉터리\n" + +#: option.c:282 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINDIR 새 í´ëŸ¬ìŠ¤í„° 실행 파ì¼ì˜ 디렉터리\n" + +#: option.c:283 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check 실 작업 ì—†ì´, 그냥 검사만\n" + +#: option.c:284 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR 옛 í´ëŸ¬ìŠ¤í„° ë°ì´í„° 디렉터리\n" + +#: option.c:285 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR 새 í´ëŸ¬ìŠ¤í„° ë°ì´í„° 디렉터리\n" + +#: option.c:286 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs ë™ì‹œì— 작업할 프로세스 ë˜ëŠ” 쓰레드 수\n" + +#: option.c:287 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link 새 í´ëŸ¬ìŠ¤í„° êµ¬ì¶•ì„ ë³µì‚¬ 대신 ë§í¬ 사용\n" + +#: option.c:288 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=옵션 옛 서버ì—서 사용할 서버 옵션들\n" + +#: option.c:289 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=옵션 새 서버ì—서 사용할 서버 옵션들\n" + +#: option.c:290 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT 옛 í´ëŸ¬ìŠ¤í„° í¬íЏ 번호 (기본값 %d)\n" + +#: option.c:291 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT 새 í´ëŸ¬ìŠ¤í„° í¬íЏ 번호 (기본값 %d)\n" + +#: option.c:292 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain 작업 완료 후 ì‚¬ìš©í–ˆë˜ SQLê³¼ 로그 íŒŒì¼ ë‚¨ê¹€\n" + +#: option.c:293 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=ì´ë¦„ í´ëŸ¬ìŠ¤í„° 슈í¼ìœ ì € (기본값 \"%s\")\n" + +#: option.c:294 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose 작업 ë‚´ì—­ì„ ìžì„¸ížˆ 남김\n" + +#: option.c:295 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version 버전 정보를 보여주고 마침\n" + +#: option.c:296 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" + +#: option.c:297 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"pg_upgrade 작업 ì „ì— ë¨¼ì € 해야 í•  것들:\n" +" 새 ë²„ì „ì˜ initdb 명령으로 새 ë°ì´í„°ë² ì´ìФ í´ëŸ¬ìŠ¤í„°ë¥¼ 만들고\n" +" 옛 서버를 중지하고\n" +" 새 ì„œë²„ë„ ì¤‘ì§€í•˜ì„¸ìš”.\n" + +#: option.c:302 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"pg_upgrade ìž‘ì—…ì€ ë‹¤ìŒ ë„¤ê°œì˜ ì˜µì…˜ ê°’ì€ ë°˜ë“œì‹œ 지정해야 함:\n" +" 옛 ë°ì´í„° í´ëŸ¬ìŠ¤í„° 디렉터리 (-d DATADIR)\n" +" 새 ë°ì´í„° í´ëŸ¬ìŠ¤í„° 디렉터리 (-D DATADIR)\n" +" 옛 ë²„ì „ì˜ \"bin\" 디렉터리 (-b BINDIR)\n" +" 새 ë²„ì „ì˜ \"bin\" 디렉터리 (-B BINDIR)\n" + +#: option.c:308 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"사용예:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" + +#: option.c:313 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:319 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:325 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"ë¬¸ì œì  ë³´ê³ : .\n" + +#: option.c:358 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"%s ìœ„ì¹˜ì˜ ë””ë ‰í„°ë¦¬ë¥¼ 알고 있어야 함.\n" +"%s 명령행 옵션ì´ë‚˜, %s 환경 변수를 사용하세요.\n" + +#: option.c:409 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "ì›ë³¸ í´ëŸ¬ìŠ¤í„°ìš© 실 ë°ì´í„° 디렉터리를 찾는 중" + +#: option.c:411 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "ëŒ€ìƒ í´ëŸ¬ìŠ¤í„°ìš© 실 ë°ì´í„° 디렉터리를 찾는 중" + +#: option.c:423 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "%s 지정한 ë°ì´í„° 디렉터리를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s\n" + +#: option.c:488 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "%d 번째 ì¤„ì„ \"%s\" 파ì¼ì—서 ì½ì„ 수 ì—†ìŒ: %s\n" + +#: option.c:506 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "지정한 %hu 옛 í¬íЏ 번호를 %hu 번호로 바꿈\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "작업용 프로세스를 만들 수 ì—†ìŒ: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "작업용 쓰레드를 만들 수 ì—†ìŒ: %s\n" + +#: parallel.c:310 parallel.c:325 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "하위 작업ìžê°€ ë¹„ì •ìƒ ì¢…ë£Œë¨: %s\n" + +#: pg_upgrade.c:106 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "\"%s\" 디렉터리 ì½ê¸° 권한 ì—†ìŒ: %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"업그레ì´ë“œ ì§„í–‰ 중\n" +"------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ìš© ë‹¤ìŒ OID 설정 중" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "ë°ì´í„° 디렉터리 fsync 작업 중" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"업그레ì´ë“œ 완료\n" +"---------------\n" + +#: pg_upgrade.c:231 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"옛 서버가 현재 ìš´ì˜ ë˜ê³  있습니다.\n" +"먼저 서버를 중지하고 진행하세요.\n" + +#: pg_upgrade.c:244 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"새 서버가 현재 ìš´ì˜ ë˜ê³  있습니다.\n" +"먼저 서버를 중지하고 진행하세요.\n" + +#: pg_upgrade.c:250 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: 실행할 í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ 없습니다.\n" + +#: pg_upgrade.c:267 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì˜ ëª¨ë“  ë¡œìš°ì— ëŒ€í•´ì„œ 통계 ì •ë³´ 수집 중" + +#: pg_upgrade.c:280 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì˜ ëª¨ë“  ë¡œìš°ì— ëŒ€í•´ì„œ ì˜êµ¬ 격리(freeze) 중" + +#: pg_upgrade.c:300 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì— ì „ì—­ ê°ì²´ë¥¼ ë³µì› ì¤‘" + +#: pg_upgrade.c:315 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì— ë°ì´í„°ë² ì´ìФ 스키마 ë³µì› ì¤‘\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "새 %sì—서 íŒŒì¼ ì§€ìš°ëŠ” 중" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "\"%s\" 디렉터리를 ì‚­ì œ í•  수 ì—†ìŒ\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "옛 %s ê°ì²´ë¥¼ 새 서버로 복사 중" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ìš© ë‹¤ìŒ íŠ¸ëžœìž­ì…˜ ID와 epoch ê°’ 설정 중" + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ìš© ë‹¤ìŒ ë©€í‹° 트랜잭션 ID와 위치 ê°’ 설정 중" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ìš© ì œì¼ ì˜¤ëž˜ëœ ë©€í‹° 트랜잭션 ID 설정 중" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "WAL ì•„ì¹´ì´ë¸Œ 재설정 중" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì—서 frozenxid, minmxid ê°’ 설정 중" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "새 í´ëŸ¬ìŠ¤í„°ì—서 minmxid ê°’ 설정 중" + +#: relfilenode.c:34 +#, c-format +msgid "Linking user relation files\n" +msgstr "ì‚¬ìš©ìž ë¦´ë ˆì´ì…˜ íŒŒì¼ ë§í¬ 중\n" + +#: relfilenode.c:36 +#, c-format +msgid "Copying user relation files\n" +msgstr "ì‚¬ìš©ìž ë¦´ë ˆì´ì…˜ íŒŒì¼ ë³µì‚¬ 중\n" + +#: relfilenode.c:110 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "\"%s\" ì´ë¦„ì˜ ì˜› ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 새 í´ëŸ¬ìŠ¤í„°ì—서 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" + +#: relfilenode.c:231 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" (\"%s\" / \"%s\") 파ì¼ì´ 있는지 í™•ì¸ ë„중 오류 ë°œìƒ: %s\n" + +#: relfilenode.c:249 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "\"%s\" ê°ì²´ë¥¼ \"%s\" ê°ì²´ë¡œ 다시 쓰는 중\n" + +#: relfilenode.c:255 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "\"%s\" ê°ì²´ë¥¼ \"%s\" ê°ì²´ë¡œ 복사 중\n" + +#: relfilenode.c:261 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "\"%s\" ê°ì²´ë¥¼ \"%s\" ê°ì²´ë¡œ ë§í¬ 중\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "ë°ì´í„°ë² ì´ìФ ì—°ê²° 실패: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "실패, 종료함\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "실행중: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL 명령 실패\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "버전 íŒŒì¼ ì—´ê¸° 실패: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "\"%s\" 파ì¼ì—서 PG_VERSIONì„ í•´ì„í•  수 ì—†ìŒ\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"ë°ì´í„°ë² ì´ìФ ì—°ê²° 실패: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"ë‹¤ìŒ ëª…ë ¹ìœ¼ë¡œ ì‹¤í–‰ëœ ì›ë³¸ 서버로 ì ‘ì†í•  수 ì—†ìŒ:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"ë‹¤ìŒ ëª…ë ¹ìœ¼ë¡œ ì‹¤í–‰ëœ ëŒ€ìƒ ì„œë²„ë¡œ ì ‘ì†í•  수 ì—†ìŒ:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "ì›ë³¸ 서버를 실행하는 pg_ctl 작업 실패, ë˜ëŠ” ì—°ê²° 실패\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "ëŒ€ìƒ ì„œë²„ë¥¼ 실행하는 pg_ctl 작업 실패, ë˜ëŠ” ì—°ê²° 실패\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "%s libpq 환경 변수가 로컬 서버 ê°’ì´ ì•„ë‹˜: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"ì‚¬ìš©ìž ì •ì˜ í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ 사용하는 경우 ê°™ì€ ì‹œìŠ¤í…œ 카탈로그 버전으로\n" +"업그레ì´ë“œ ìž‘ì—…ì„ ì§„í–‰í•  수 없습니다.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "\"%s\" ì´ë¦„ì˜ í…Œì´ë¸”스페ì´ìФ 디렉터리가 ì—†ìŒ\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "\"%s\" í…Œì´ë¸”스페ì´ìФ ë””ë ‰í„°ë¦¬ì˜ ìƒíƒœ 정보를 구할 수 ì—†ìŒ: %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "\"%s\" í…Œì´ë¸”스페ì´ìФ 경로는 디렉터리가 아님\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "대형 ê°ì²´ í™•ì¸ ì¤‘" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "경고" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"ì´ ë°ì´í„°ë² ì´ìŠ¤ëŠ” 대형 ê°ì²´ë¥¼ 사용하고 있습니다. 새 ë°ì´í„°ë² ì´ìФì—서는\n" +"ì´ë“¤ì˜ ì ‘ê·¼ 권한 제어를 위해 추가ì ì¸ í…Œì´ë¸”ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 업그레ì´ë“œ 후\n" +"ì´ ê°ì²´ë“¤ì˜ ì ‘ê·¼ ê¶Œí•œì€ pg_largeobject_metadata í…Œì´ë¸”ì— ê¸°ë³¸ê°’ìœ¼ë¡œ 지정ë©ë‹ˆë‹¤.\n" +"\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"ì´ ë°ì´í„°ë² ì´ìŠ¤ëŠ” 대형 ê°ì²´ë¥¼ 사용하고 있습니다. 새 ë°ì´í„°ë² ì´ìФì—서는\n" +"ì´ë“¤ì˜ ì ‘ê·¼ 권한 제어를 위해 추가ì ì¸ í…Œì´ë¸”ì„ ì‚¬ìš©í•©ë‹ˆë‹¤. 그래서\n" +"ì´ë“¤ì˜ ì ‘ê·¼ ê¶Œí•œì„ ê¸°ë³¸ê°’ìœ¼ë¡œ 설정하려면,\n" +" %s\n" +"파ì¼ì„ 새 서버가 실행 ë˜ì—ˆì„ 때 슈í¼ìœ ì € 권한으로 psql 명령으로\n" +"실행 하세요.\n" +"\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "\"line\" ìžë£Œí˜• 호환성 í™•ì¸ ì¤‘" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"해당 ë°ì´í„°ë² ì´ìФì—서 \"line\" ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ëŠ” ì¹¼ëŸ¼ì´ ìžˆìŠµë‹ˆë‹¤.\n" +"ì´ ìžë£Œí˜•ì˜ ìž…ì¶œë ¥ ë°©ì‹ì´ 옛 버전과 새 버전ì—서 서로 호환하지 않습니다.\n" +"먼저 ì´ ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ëŠ” í…Œì´ë¸”ì„ ì‚­ì œ 후 업그레ì´ë“œ ìž‘ì—…ì„ í•˜ê³ ,\n" +"수ë™ìœ¼ë¡œ ë³µì› ìž‘ì—…ì„ í•´ì•¼ 합니다. 해당 파ì¼ë“¤ì€ 다ìŒê³¼ 같습니다:\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "ìž˜ëª»ëœ \"unknown\" ì‚¬ìš©ìž ì¹¼ëŸ¼ì„ í™•ì¸ ì¤‘" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"해당 ë°ì´í„°ë² ì´ìФì—서 ì‚¬ìš©ìž í…Œì´ë¸”ì—서 \"unknown\" ìžë£Œí˜•ì„ ì‚¬ìš©í•˜ê³  있습니다.\n" +"ì´ ìžë£Œí˜•ì€ ë” ì´ìƒ 사용할 수 없습니다. ì´ ë¬¸ì œë¥¼ 옛 버전ì—서 먼저 정리하고\n" +"업그레ì´ë“œ ìž‘ì—…ì„ ì§„í–‰í•˜ì„¸ìš”. 해당 파ì¼ì€ 다ìŒê³¼ 같습니다:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "해쉬 ì¸ë±ìФ í™•ì¸ ì¤‘" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"해당 ë°ì´í„°ë² ì´ìФì—서 해쉬 ì¸ë±ìŠ¤ë¥¼ 사용하고 있습니다. 해쉬 ì¸ë±ìФ ìžë£Œêµ¬ì¡°ê°€\n" +"새 버전ì—서 호환ë˜ì§€ 않습니다. 업그레ì´ë“œ í›„ì— í•´ë‹¹ ì¸ë±ìŠ¤ë“¤ì„\n" +"REINDEX 명령으로 다시 만들어야 합니다.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"해당 ë°ì´í„°ë² ì´ìФì—서 해쉬 ì¸ë±ìŠ¤ë¥¼ 사용하고 있습니다. 해쉬 ì¸ë±ìФ ìžë£Œêµ¬ì¡°ê°€\n" +"새 버전ì—서 호환ë˜ì§€ 않습니다. 업그레ì´ë“œ 후 ë‹¤ìŒ íŒŒì¼ì„\n" +"슈í¼ìœ ì € 권한으로 실행한 psqlì—서 실행해서, REINDEX ìž‘ì—…ì„ ì§„í–‰í•˜ì„¸ìš”:\n" +" %s\n" +"ì´ ìž‘ì—…ì´ ìžˆê¸° 전까지는 해당 ì¸ë±ìŠ¤ëŠ” invalid ìƒíƒœë¡œ 사용할 수 없게 ë©ë‹ˆë‹¤.\n" +"\n" diff --git a/src/bin/pg_upgrade/po/ru.po b/src/bin/pg_upgrade/po/ru.po index 5d1b84c2c0e..a4e5364ecc7 100644 --- a/src/bin/pg_upgrade/po/ru.po +++ b/src/bin/pg_upgrade/po/ru.po @@ -1,44 +1,41 @@ # Russian message translation file for pg_upgrade # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander LAW , 2017. -# +# Alexander Lakhin , 2017, 2018, 2019. msgid "" msgstr "" "Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-04 04:15+0000\n" -"PO-Revision-Date: 2017-04-10 15:12+0300\n" +"POT-Creation-Date: 2019-02-08 11:42+0300\n" +"PO-Revision-Date: 2019-02-08 13:03+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Alexander Lakhin \n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: check.c:65 -#, c-format -msgid "Performing Consistency Checks on Old Live Server\n" -msgstr "Проверка целоÑтноÑти на Ñтаром работающем Ñервере\n" - #: check.c:66 #, c-format -msgid "------------------------------------------------\n" -msgstr "------------------------------------------------\n" - -#: check.c:70 -#, c-format -msgid "Performing Consistency Checks\n" -msgstr "Проведение проверок целоÑтноÑти\n" +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Проверка целоÑтноÑти на Ñтаром работающем Ñервере\n" +"-------------------------------------------------\n" -#: check.c:71 +#: check.c:72 #, c-format -msgid "-----------------------------\n" -msgstr "-----------------------------\n" +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Проведение проверок целоÑтноÑти\n" +"-------------------------------\n" -#: check.c:157 +#: check.c:166 #, c-format msgid "" "\n" @@ -47,7 +44,7 @@ msgstr "" "\n" "*КлаÑтеры ÑовмеÑтимы*\n" -#: check.c:163 +#: check.c:172 #, c-format msgid "" "\n" @@ -59,7 +56,7 @@ msgstr "" "initdb\n" "Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ клаÑтера, чтобы продолжить.\n" -#: check.c:189 +#: check.c:208 #, c-format msgid "" "Optimizer statistics are not transferred by pg_upgrade so,\n" @@ -72,7 +69,7 @@ msgstr "" " %s\n" "\n" -#: check.c:194 +#: check.c:213 #, c-format msgid "" "Optimizer statistics and free space information are not transferred\n" @@ -85,7 +82,7 @@ msgstr "" " %s\n" "\n" -#: check.c:201 +#: check.c:220 #, c-format msgid "" "Running this script will delete the old cluster's data files:\n" @@ -94,7 +91,7 @@ msgstr "" "При запуÑке Ñтого Ñкрипта будут удалены файлы данных Ñтарого клаÑтера:\n" " %s\n" -#: check.c:206 +#: check.c:225 #, c-format msgid "" "Could not create a script to delete the old cluster's data files\n" @@ -107,33 +104,33 @@ msgstr "" "проÑтранÑтва или каталог данных нового клаÑтера.\n" "Содержимое Ñтарого клаÑтера нужно будет удалить вручную.\n" -#: check.c:216 +#: check.c:235 #, c-format msgid "Checking cluster versions" msgstr "Проверка верÑий клаÑтеров" -#: check.c:228 +#: check.c:247 #, c-format msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" msgstr "" "Эта утилита может производить обновление только Ñ Ð²ÐµÑ€Ñии PostgreSQL 8.4 и " "новее.\n" -#: check.c:232 +#: check.c:251 #, c-format msgid "This utility can only upgrade to PostgreSQL version %s.\n" msgstr "Эта утилита может только повышать верÑию PostgreSQL до %s.\n" -#: check.c:241 +#: check.c:260 #, c-format msgid "" -"This utility cannot be used to downgrade to older major PostgreSQL " -"versions.\n" +"This utility cannot be used to downgrade to older major PostgreSQL versions." +"\n" msgstr "" "Эта утилита не может понижать верÑию до более Ñтарой оÑновной верÑии " "PostgreSQL.\n" -#: check.c:246 +#: check.c:265 #, c-format msgid "" "Old cluster data and binary directories are from different major versions.\n" @@ -141,7 +138,7 @@ msgstr "" "Каталоги данных и иÑполнÑемых файлов Ñтарого клаÑтера отноÑÑÑ‚ÑÑ Ðº разным " "оÑновным верÑиÑм.\n" -#: check.c:249 +#: check.c:268 #, c-format msgid "" "New cluster data and binary directories are from different major versions.\n" @@ -149,16 +146,7 @@ msgstr "" "Каталоги данных и иÑполнÑемых файлов нового клаÑтера отноÑÑÑ‚ÑÑ Ðº разным " "оÑновным верÑиÑм.\n" -#: check.c:266 -#, c-format -msgid "" -"This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" -"because of backend API changes made during development.\n" -msgstr "" -"Эта утилита поддерживает обновление только до верÑии 9.0 поÑле 2010-01-11,\n" -"так как в API Ñерверной чаÑти были внеÑены изменениÑ.\n" - -#: check.c:272 +#: check.c:285 #, c-format msgid "" "When checking a pre-PG 9.1 live old server, you must specify the old " @@ -167,23 +155,23 @@ msgstr "" "Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ Ñтарого работающего Ñервера верÑии до 9.1 необходимо указать " "номер порта Ñтого Ñервера.\n" -#: check.c:276 +#: check.c:289 #, c-format msgid "" -"When checking a live server, the old and new port numbers must be " -"different.\n" +"When checking a live server, the old and new port numbers must be different." +"\n" msgstr "" "Ð”Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ работающего Ñервера новый номер порта должен отличатьÑÑ Ð¾Ñ‚ " "Ñтарого.\n" -#: check.c:291 +#: check.c:304 #, c-format msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" msgstr "" -"кодировки в базе данных \"%s\" различаютÑÑ: ÑÑ‚Ð°Ñ€Ð°Ñ - \"%s\", Ð½Ð¾Ð²Ð°Ñ - \"%s" -"\"\n" +"кодировки в базе данных \"%s\" различаютÑÑ: ÑÑ‚Ð°Ñ€Ð°Ñ - \"%s\", Ð½Ð¾Ð²Ð°Ñ - \"" +"%s\"\n" -#: check.c:296 +#: check.c:309 #, c-format msgid "" "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" @@ -191,7 +179,7 @@ msgstr "" "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ lc_collate в базе данных \"%s\" различаютÑÑ: Ñтарое - \"%s\", " "новое - \"%s\"\n" -#: check.c:299 +#: check.c:312 #, c-format msgid "" "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" @@ -199,28 +187,28 @@ msgstr "" "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ lc_ctype в базе данных \"%s\" различаютÑÑ: Ñтарое - \"%s\", новое " "- \"%s\"\n" -#: check.c:372 +#: check.c:385 #, c-format msgid "New cluster database \"%s\" is not empty\n" msgstr "ÐÐ¾Ð²Ð°Ñ Ð±Ð°Ð·Ð° данных клаÑтера \"%s\" не пуÑтаÑ\n" -#: check.c:419 +#: check.c:432 #, c-format msgid "Creating script to analyze new cluster" msgstr "Создание Ñкрипта Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð° нового клаÑтера" -#: check.c:433 check.c:561 check.c:821 check.c:924 check.c:1015 function.c:253 -#: version.c:57 version.c:156 version.c:257 +#: check.c:446 check.c:574 check.c:838 check.c:949 check.c:1040 function.c:253 +#: option.c:480 version.c:57 version.c:156 version.c:257 version.c:339 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть файл \"%s\": %s\n" -#: check.c:488 check.c:617 +#: check.c:501 check.c:630 #, c-format msgid "could not add execute permission to file \"%s\": %s\n" msgstr "не удалоÑÑŒ добавить право Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\": %s\n" -#: check.c:524 +#: check.c:537 #, c-format msgid "" "\n" @@ -231,7 +219,7 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: новый каталог данных не должен раÑполагатьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ Ñтарого " "каталога данных, то еÑть, в %s\n" -#: check.c:548 +#: check.c:561 #, c-format msgid "" "\n" @@ -242,37 +230,37 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: пользовательÑкие табличные проÑтранÑтва не должны " "раÑполагатьÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ каталога данных, то еÑть, в %s\n" -#: check.c:558 +#: check.c:571 #, c-format msgid "Creating script to delete old cluster" msgstr "Создание Ñкрипта Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ñтарого клаÑтера" -#: check.c:637 +#: check.c:650 #, c-format msgid "Checking database user is the install user" msgstr "Проверка, ÑвлÑетÑÑ Ð»Ð¸ пользователь БД Ñтартовым пользователем" -#: check.c:653 +#: check.c:666 #, c-format msgid "database user \"%s\" is not the install user\n" msgstr "пользователь БД \"%s\" не ÑвлÑетÑÑ Ñтартовым пользователем\n" -#: check.c:664 +#: check.c:677 #, c-format msgid "could not determine the number of users\n" msgstr "не удалоÑÑŒ определить количеÑтво пользователей\n" -#: check.c:672 +#: check.c:685 #, c-format msgid "Only the install user can be defined in the new cluster.\n" msgstr "Ð’ новом клаÑтере может быть определён только Ñтартовый пользователь.\n" -#: check.c:692 +#: check.c:705 #, c-format msgid "Checking database connection settings" msgstr "Проверка параметров Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº базе данных" -#: check.c:714 +#: check.c:727 #, c-format msgid "" "template0 must not allow connections, i.e. its pg_database.datallowconn must " @@ -281,7 +269,7 @@ msgstr "" "База template0 не должна допуÑкать подключениÑ, то еÑть её ÑвойÑтво " "pg_database.datallowconn должно быть false\n" -#: check.c:724 +#: check.c:737 #, c-format msgid "" "All non-template0 databases must allow connections, i.e. their pg_database." @@ -290,28 +278,33 @@ msgstr "" "Ð’Ñе базы, кроме template0, должны допуÑкать подключениÑ, то еÑть их ÑвойÑтво " "pg_database.datallowconn должно быть true\n" -#: check.c:749 +#: check.c:762 #, c-format msgid "Checking for prepared transactions" msgstr "Проверка Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ð¿Ð¾Ð´Ð³Ð¾Ñ‚Ð¾Ð²Ð»ÐµÐ½Ð½Ñ‹Ñ… транзакций" -#: check.c:756 +#: check.c:771 #, c-format -msgid "The %s cluster contains prepared transactions\n" -msgstr "КлаÑтер %s Ñодержит подготовленные транзакции\n" +msgid "The source cluster contains prepared transactions\n" +msgstr "ИÑходный клаÑтер Ñодержит подготовленные транзакции\n" -#: check.c:782 +#: check.c:773 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Целевой клаÑтер Ñодержит подготовленные транзакции\n" + +#: check.c:799 #, c-format msgid "Checking for contrib/isn with bigint-passing mismatch" msgstr "Проверка неÑоответÑÑ‚Ð²Ð¸Ñ Ð¿Ñ€Ð¸ передаче bigint в contrib/isn" -#: check.c:843 check.c:947 check.c:1038 function.c:268 version.c:179 +#: check.c:860 check.c:972 check.c:1063 function.c:268 version.c:179 #: version.c:280 #, c-format msgid "fatal\n" msgstr "Ñбой\n" -#: check.c:844 +#: check.c:861 #, c-format msgid "" "Your installation contains \"contrib/isn\" functions which rely on the\n" @@ -327,20 +320,20 @@ msgstr "" "biging.\n" "Однако в новом клаÑтере Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ bigint передаётÑÑ Ð½Ðµ так, как в Ñтаром,\n" "так что обновление клаÑтера в текущем ÑоÑтоÑнии невозможно. Ð’Ñ‹ можете\n" -"вручную обновить базы данных, где иÑпользуетÑÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð¾Ñть \"contrib/isn" -"\" или\n" +"вручную обновить базы данных, где иÑпользуетÑÑ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð¾Ñть \"contrib/" +"isn\" или\n" "удалить \"contrib/isn\" из Ñтарого клаÑтера и перезапуÑтить обновление. " "СпиÑок\n" "проблемных функций приведён в файле:\n" " %s\n" "\n" -#: check.c:876 +#: check.c:893 #, c-format -msgid "Checking for reg* system OID user data types" -msgstr "Проверка пользовательÑких типов данных reg* Ñ ÑиÑтемными OID" +msgid "Checking for reg* data types in user tables" +msgstr "Проверка типов данных reg* в пользовательÑких таблицах" -#: check.c:948 +#: check.c:973 #, c-format msgid "" "Your installation contains one of the reg* data types in user tables.\n" @@ -360,190 +353,245 @@ msgstr "" " %s\n" "\n" -#: check.c:973 +#: check.c:998 #, c-format -msgid "Checking for JSONB user data types" -msgstr "Проверка пользовательÑких типов данных JSONB" +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Проверка неÑовмеÑтимого типа данных \"jsonb\"" -#: check.c:1039 +#: check.c:1064 #, c-format msgid "" -"Your installation contains one of the JSONB data types in user tables.\n" -"The internal format of JSONB changed during 9.4 beta so this cluster cannot " -"currently\n" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster " +"cannot currently\n" "be upgraded. You can remove the problem tables and restart the upgrade. A " "list\n" "of the problem columns is in the file:\n" " %s\n" "\n" msgstr "" -"Ð’ вашей инÑталлÑции таблицы иÑпользуют один или неÑколько типов JSONB.\n" -"Внутренний формат JSONB изменилÑÑ Ð² верÑии 9.4 beta, поÑтому обновить " +"Ð’ вашей инÑталлÑции таблицы иÑпользуют тип данных jsonb.\n" +"Внутренний формат \"jsonb\" изменилÑÑ Ð² верÑии 9.4 beta, поÑтому обновить " "клаÑтер\n" "в текущем ÑоÑтоÑнии невозможно. Ð’Ñ‹ можете удалить проблемные таблицы и\n" "перезапуÑтить обновление. СпиÑок проблемных Ñтолбцов приведён в файле:\n" " %s\n" "\n" -#: check.c:1060 +#: check.c:1085 #, c-format -msgid "Checking for roles starting with 'pg_'" -msgstr "Проверка ролей Ñ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸, начинающимиÑÑ Ñ 'pg_'" +msgid "Checking for roles starting with \"pg_\"" +msgstr "Проверка ролей Ñ Ð¸Ð¼ÐµÐ½Ð°Ð¼Ð¸, начинающимиÑÑ Ñ \"pg_\"" -#: check.c:1068 +#: check.c:1095 #, c-format -msgid "The %s cluster contains roles starting with 'pg_'\n" -msgstr "Ð’ клаÑтере %s еÑть роли, имена которых начинаютÑÑ Ñ 'pg_'\n" +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Ð’ иÑходном клаÑтере еÑть роли, имена которых начинаютÑÑ Ñ \"pg_\"\n" -#: check.c:1094 +#: check.c:1097 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Ð’ целевом клаÑтере еÑть роли, имена которых начинаютÑÑ Ñ \"pg_\"\n" + +#: check.c:1123 #, c-format msgid "failed to get the current locale\n" msgstr "не удалоÑÑŒ получить текущую локаль\n" -#: check.c:1103 +#: check.c:1132 #, c-format msgid "failed to get system locale name for \"%s\"\n" msgstr "не удалоÑÑŒ получить ÑиÑтемное Ð¸Ð¼Ñ Ð»Ð¾ÐºÐ°Ð»Ð¸ Ð´Ð»Ñ \"%s\"\n" -#: check.c:1109 +#: check.c:1138 #, c-format msgid "failed to restore old locale \"%s\"\n" msgstr "не удалоÑÑŒ воÑÑтановить Ñтарую локаль \"%s\"\n" -#: controldata.c:128 +#: controldata.c:128 controldata.c:195 #, c-format msgid "could not get control data using %s: %s\n" msgstr "не удалоÑÑŒ получить управлÑющие данные, выполнив %s: %s\n" -#: controldata.c:141 dump.c:59 pg_upgrade.c:321 relfilenode.c:244 util.c:80 +#: controldata.c:139 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: недопуÑтимое ÑоÑтоÑние клаÑтера баз данных\n" + +#: controldata.c:156 +#, c-format +msgid "" +"The source cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"ИÑходный клаÑтер был отключён в режиме воÑÑтановлениÑ. Чтобы произвеÑти " +"обновление, иÑпользуйте документированный ÑпоÑоб Ñ rsync или отключите его в " +"режиме главного Ñервера.\n" + +#: controldata.c:158 +#, c-format +msgid "" +"The target cluster was shut down while in recovery mode. To upgrade, use " +"\"rsync\" as documented or shut it down as a primary.\n" +msgstr "" +"Целевой клаÑтер был отключён в режиме воÑÑтановлениÑ. Чтобы произвеÑти " +"обновление, иÑпользуйте документированный ÑпоÑоб Ñ rsync или отключите его в " +"режиме главного Ñервера.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "ИÑходный клаÑтер не был отключён штатным образом.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Целевой клаÑтер не был отключён штатным образом.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Ð’ иÑходном клаÑтере не хватает информации о ÑоÑтоÑнии клаÑтера:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Ð’ целевом клаÑтере не хватает информации о ÑоÑтоÑнии клаÑтера:\n" + +#: controldata.c:208 dump.c:51 pg_upgrade.c:333 pg_upgrade.c:370 +#: relfilenode.c:244 util.c:80 #, c-format msgid "%s" msgstr "%s" -#: controldata.c:148 +#: controldata.c:215 #, c-format msgid "%d: pg_resetwal problem\n" msgstr "%d: проблема Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð¾Ð¼ pg_resetwal\n" -#: controldata.c:158 controldata.c:168 controldata.c:179 controldata.c:190 -#: controldata.c:201 controldata.c:220 controldata.c:231 controldata.c:242 -#: controldata.c:253 controldata.c:264 controldata.c:275 controldata.c:278 -#: controldata.c:282 controldata.c:292 controldata.c:304 controldata.c:315 -#: controldata.c:326 controldata.c:337 controldata.c:348 controldata.c:359 -#: controldata.c:370 controldata.c:381 controldata.c:392 controldata.c:403 -#: controldata.c:414 +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 #, c-format msgid "%d: controldata retrieval problem\n" msgstr "%d: проблема Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸ÐµÐ¼ управлÑющих данных\n" -#: controldata.c:478 +#: controldata.c:546 #, c-format -msgid "The %s cluster lacks some required control information:\n" -msgstr "" -"Ð’ клаÑтере %s не хватает некоторой необходимой управлÑющей информации:\n" +msgid "The source cluster lacks some required control information:\n" +msgstr "Ð’ иÑходном клаÑтере не хватает необходимой управлÑющей информации:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Ð’ целевом клаÑтере не хватает необходимой управлÑющей информации:\n" # skip-rule: capital-letter-first -#: controldata.c:482 +#: controldata.c:552 #, c-format msgid " checkpoint next XID\n" msgstr " Ñледующий XID поÑледней конт. точки\n" # skip-rule: capital-letter-first -#: controldata.c:485 +#: controldata.c:555 #, c-format msgid " latest checkpoint next OID\n" msgstr " Ñледующий OID поÑледней конт. точки\n" # skip-rule: capital-letter-first -#: controldata.c:488 +#: controldata.c:558 #, c-format msgid " latest checkpoint next MultiXactId\n" msgstr " Ñледующий MultiXactId поÑледней конт. точки\n" # skip-rule: capital-letter-first -#: controldata.c:492 +#: controldata.c:562 #, c-format msgid " latest checkpoint oldest MultiXactId\n" msgstr " Ñтарейший MultiXactId поÑледней конт. точки\n" # skip-rule: capital-letter-first -#: controldata.c:495 +#: controldata.c:565 #, c-format msgid " latest checkpoint next MultiXactOffset\n" msgstr " Ñледующий MultiXactOffset поÑледней конт. точки\n" -#: controldata.c:498 +#: controldata.c:568 #, c-format msgid " first WAL segment after reset\n" msgstr " первый Ñегмент WAL поÑле ÑброÑа\n" -#: controldata.c:501 +#: controldata.c:571 #, c-format msgid " float8 argument passing method\n" msgstr " метод передачи аргумента float8\n" -#: controldata.c:504 +#: controldata.c:574 #, c-format msgid " maximum alignment\n" msgstr " макÑимальное выравнивание\n" -#: controldata.c:507 +#: controldata.c:577 #, c-format msgid " block size\n" msgstr " размер блока\n" -#: controldata.c:510 +#: controldata.c:580 #, c-format msgid " large relation segment size\n" msgstr " размер Ñегмента большого отношениÑ\n" -#: controldata.c:513 +#: controldata.c:583 #, c-format msgid " WAL block size\n" msgstr " размер блока WAL\n" -#: controldata.c:516 +#: controldata.c:586 #, c-format msgid " WAL segment size\n" msgstr " размер Ñегмента WAL\n" -#: controldata.c:519 +#: controldata.c:589 #, c-format msgid " maximum identifier length\n" msgstr " макÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° идентификатора\n" -#: controldata.c:522 +#: controldata.c:592 #, c-format msgid " maximum number of indexed columns\n" msgstr " макÑимальное чиÑло Ñтолбцов в индекÑе\n" -#: controldata.c:525 +#: controldata.c:595 #, c-format msgid " maximum TOAST chunk size\n" msgstr " макÑимальный размер порции TOAST\n" -#: controldata.c:529 +#: controldata.c:599 #, c-format msgid " large-object chunk size\n" msgstr " размер порции большого объекта\n" -#: controldata.c:532 +#: controldata.c:602 #, c-format msgid " dates/times are integers?\n" msgstr " дата/Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€ÐµÐ´Ñтавлены целыми чиÑлами?\n" -#: controldata.c:536 +#: controldata.c:606 #, c-format msgid " data checksum version\n" msgstr " верÑÐ¸Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… Ñумм данных\n" -#: controldata.c:538 +#: controldata.c:608 #, c-format msgid "Cannot continue without required control information, terminating\n" msgstr "" "Ðет необходимой управлÑющей информации Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ, работа прерываетÑÑ\n" -#: controldata.c:553 +#: controldata.c:623 #, c-format msgid "" "old and new pg_controldata alignments are invalid or do not match\n" @@ -553,13 +601,13 @@ msgstr "" "ВероÑтно, один клаÑтер уÑтановлен в 32-битной ÑиÑтеме, а другой ~ в 64-" "битной\n" -#: controldata.c:557 +#: controldata.c:627 #, c-format msgid "old and new pg_controldata block sizes are invalid or do not match\n" msgstr "" "Ñтарый и новый размер блоков в pg_controldata различаютÑÑ Ð¸Ð»Ð¸ некорректны\n" -#: controldata.c:560 +#: controldata.c:630 #, c-format msgid "" "old and new pg_controldata maximum relation segment sizes are invalid or do " @@ -568,7 +616,7 @@ msgstr "" "Ñтарый и новый макÑимальный размер Ñегментов отношений в pg_controldata " "различаютÑÑ Ð¸Ð»Ð¸ некорректны\n" -#: controldata.c:563 +#: controldata.c:633 #, c-format msgid "" "old and new pg_controldata WAL block sizes are invalid or do not match\n" @@ -576,7 +624,7 @@ msgstr "" "Ñтарый и новый размер блоков WAL в pg_controldata различаютÑÑ Ð¸Ð»Ð¸ " "некорректны\n" -#: controldata.c:566 +#: controldata.c:636 #, c-format msgid "" "old and new pg_controldata WAL segment sizes are invalid or do not match\n" @@ -584,7 +632,7 @@ msgstr "" "Ñтарый и новый размер Ñегментов WAL в pg_controldata различаютÑÑ Ð¸Ð»Ð¸ " "некорректны\n" -#: controldata.c:569 +#: controldata.c:639 #, c-format msgid "" "old and new pg_controldata maximum identifier lengths are invalid or do not " @@ -593,7 +641,7 @@ msgstr "" "ÑÑ‚Ð°Ñ€Ð°Ñ Ð¸ Ð½Ð¾Ð²Ð°Ñ Ð¼Ð°ÐºÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° идентификаторов в pg_controldata " "различаютÑÑ Ð¸Ð»Ð¸ некорректны\n" -#: controldata.c:572 +#: controldata.c:642 #, c-format msgid "" "old and new pg_controldata maximum indexed columns are invalid or do not " @@ -602,7 +650,7 @@ msgstr "" "Ñтарый и новый макÑимум чиÑла Ñтолбцов, ÑоÑтавлÑющих индекÑÑ‹, в " "pg_controldata различаютÑÑ Ð¸Ð»Ð¸ некорректны\n" -#: controldata.c:575 +#: controldata.c:645 #, c-format msgid "" "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not " @@ -611,7 +659,7 @@ msgstr "" "Ñтарый и новый макÑимальный размер порции TOAST в pg_controldata различаютÑÑ " "или некорректны\n" -#: controldata.c:580 +#: controldata.c:650 #, c-format msgid "" "old and new pg_controldata large-object chunk sizes are invalid or do not " @@ -619,44 +667,44 @@ msgid "" msgstr "" "Ñтарый и новый размер порции большого объекта различаютÑÑ Ð¸Ð»Ð¸ некорректны\n" -#: controldata.c:583 +#: controldata.c:653 #, c-format msgid "old and new pg_controldata date/time storage types do not match\n" msgstr "" "Ñтарый и новый тип Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‹/времени в pg_controldata различаютÑÑ Ð¸Ð»Ð¸ " "некорректны\n" -#: controldata.c:596 +#: controldata.c:666 #, c-format msgid "old cluster does not use data checksums but the new one does\n" msgstr "" "в Ñтаром клаÑтере не применÑлиÑÑŒ контрольные Ñуммы данных, но в новом они " "еÑть\n" -#: controldata.c:599 +#: controldata.c:669 #, c-format msgid "old cluster uses data checksums but the new one does not\n" msgstr "" "в Ñтаром клаÑтере применÑлиÑÑŒ контрольные Ñуммы данных, но в новом их нет\n" -#: controldata.c:601 +#: controldata.c:671 #, c-format msgid "old and new cluster pg_controldata checksum versions do not match\n" msgstr "" "ÑÑ‚Ð°Ñ€Ð°Ñ Ð¸ Ð½Ð¾Ð²Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ ÐºÐ¾Ð½Ñ‚Ñ€Ð¾Ð»ÑŒÐ½Ñ‹Ñ… Ñумм клаÑтера в pg_controldata " "различаютÑÑ\n" -#: controldata.c:612 +#: controldata.c:682 #, c-format msgid "Adding \".old\" suffix to old global/pg_control" msgstr "Добавление раÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ \".old\" к Ñтарому файлу global/pg_control" -#: controldata.c:617 +#: controldata.c:687 #, c-format msgid "Unable to rename %s to %s.\n" msgstr "Ðе удалоÑÑŒ переименовать %s в %s.\n" -#: controldata.c:620 +#: controldata.c:690 #, c-format msgid "" "\n" @@ -673,12 +721,12 @@ msgstr "" "поÑле того, как будет запущен новый, не гарантируетÑÑ.\n" "\n" -#: dump.c:23 +#: dump.c:22 #, c-format msgid "Creating dump of global objects" msgstr "Формирование выгрузки глобальных объектов" -#: dump.c:34 +#: dump.c:33 #, c-format msgid "Creating dump of database schemas\n" msgstr "Формирование выгрузки Ñхем базы данных\n" @@ -688,27 +736,27 @@ msgstr "Формирование выгрузки Ñхем базы данных msgid "could not get pg_ctl version data using %s: %s\n" msgstr "не удалоÑÑŒ получить данные верÑии pg_ctl, выполнив %s: %s\n" -#: exec.c:54 server.c:170 +#: exec.c:50 #, c-format -msgid "could not get version from %s\n" -msgstr "не удалоÑÑŒ получить верÑию от %s\n" +msgid "could not get pg_ctl version output from %s\n" +msgstr "не удалоÑÑŒ получить верÑию pg_ctl из результата %s\n" -#: exec.c:101 exec.c:105 +#: exec.c:104 exec.c:108 #, c-format msgid "command too long\n" msgstr "команда Ñлишком длиннаÑ\n" -#: exec.c:107 util.c:38 util.c:226 +#: exec.c:110 util.c:38 util.c:226 #, c-format msgid "%s\n" msgstr "%s\n" -#: exec.c:146 exec.c:201 option.c:101 option.c:217 +#: exec.c:149 exec.c:204 option.c:101 option.c:217 #, c-format -msgid "cannot write to log file %s\n" -msgstr "не удаётÑÑ Ð·Ð°Ð¿Ð¸Ñать в файл журнала %s\n" +msgid "could not write to log file \"%s\"\n" +msgstr "не удалоÑÑŒ запиÑать в файл протокола \"%s\"\n" -#: exec.c:175 +#: exec.c:178 #, c-format msgid "" "\n" @@ -717,12 +765,12 @@ msgstr "" "\n" "*ошибка*" -#: exec.c:178 +#: exec.c:181 #, c-format msgid "There were problems executing \"%s\"\n" msgstr "При выполнении \"%s\" возникли проблемы\n" -#: exec.c:181 +#: exec.c:184 #, c-format msgid "" "Consult the last few lines of \"%s\" or \"%s\" for\n" @@ -731,7 +779,7 @@ msgstr "" "Чтобы понÑть причину ошибки, проÑмотрите поÑледние неÑколько Ñтрок\n" "файла \"%s\" или \"%s\".\n" -#: exec.c:186 +#: exec.c:189 #, c-format msgid "" "Consult the last few lines of \"%s\" for\n" @@ -740,44 +788,44 @@ msgstr "" "Чтобы понÑть причину ошибки, проÑмотрите поÑледние неÑколько Ñтрок\n" "файла \"%s\".\n" -#: exec.c:227 +#: exec.c:230 #, c-format msgid "could not open file \"%s\" for reading: %s\n" msgstr "не удалоÑÑŒ открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ: %s\n" -#: exec.c:254 +#: exec.c:257 #, c-format msgid "You must have read and write access in the current directory.\n" msgstr "У Ð²Ð°Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ‹ быть права на чтение и запиÑÑŒ в текущем каталоге.\n" -#: exec.c:307 exec.c:370 exec.c:426 +#: exec.c:310 exec.c:372 exec.c:427 #, c-format msgid "check for \"%s\" failed: %s\n" msgstr "проверка ÑущеÑÑ‚Ð²Ð¾Ð²Ð°Ð½Ð¸Ñ \"%s\" не пройдена: %s\n" -#: exec.c:310 exec.c:373 +#: exec.c:313 exec.c:375 #, c-format -msgid "%s is not a directory\n" -msgstr "%s\" не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼\n" +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" не ÑвлÑетÑÑ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼\n" -#: exec.c:429 +#: exec.c:430 #, c-format -msgid "check for \"%s\" failed: not an executable file\n" -msgstr "проверка файла \"%s\" не пройдена: Ñто не иÑполнÑемый файл\n" +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "проверка файла \"%s\" не пройдена: Ñто не обычный файл\n" -#: exec.c:441 +#: exec.c:442 #, c-format msgid "check for \"%s\" failed: cannot read file (permission denied)\n" msgstr "" "проверка файла \"%s\" не пройдена: не удаётÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚ÑŒ файл (нет доÑтупа)\n" -#: exec.c:449 +#: exec.c:450 #, c-format msgid "check for \"%s\" failed: cannot execute (permission denied)\n" msgstr "" "проверка файла \"%s\" не пройдена: выполнение невозможно (нет доÑтупа)\n" -#: file.c:43 file.c:146 +#: file.c:44 file.c:147 #, c-format msgid "" "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" @@ -785,7 +833,7 @@ msgstr "" "ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ открыть файл \"%s\": " "%s\n" -#: file.c:48 file.c:155 +#: file.c:49 file.c:156 #, c-format msgid "" "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" @@ -793,35 +841,35 @@ msgstr "" "ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ Ñоздать файл \"%s\": " "%s\n" -#: file.c:62 file.c:186 +#: file.c:63 file.c:180 #, c-format msgid "" "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" msgstr "" -"ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ прочитать файл \"%s" -"\": %s\n" +"ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ прочитать файл \"" +"%s\": %s\n" -#: file.c:74 file.c:264 +#: file.c:75 file.c:258 #, c-format msgid "" "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" msgstr "" -"ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ запиÑать в файл \"%s" -"\": %s\n" +"ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ запиÑать в файл \"" +"%s\": %s\n" -#: file.c:88 +#: file.c:89 #, c-format msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" msgstr "ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\" (из \"%s\" в \"%s\"): %s\n" -#: file.c:107 +#: file.c:108 #, c-format msgid "" "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" msgstr "" "ошибка при Ñоздании ÑÑылки Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\" (из \"%s\" в \"%s\"): %s\n" -#: file.c:150 +#: file.c:151 #, c-format msgid "" "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" @@ -829,7 +877,7 @@ msgstr "" "ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": не удалоÑÑŒ получить информацию о " "файле \"%s\": %s\n" -#: file.c:189 +#: file.c:183 #, c-format msgid "" "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" @@ -837,17 +885,17 @@ msgstr "" "ошибка при копировании Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ \"%s.%s\": в файле \"%s\" обнаружена " "Ð½ÐµÐ¿Ð¾Ð»Ð½Ð°Ñ Ñтраница\n" -#: file.c:292 +#: file.c:284 #, c-format msgid "" "could not create hard link between old and new data directories: %s\n" "In link mode the old and new data directories must be on the same file " -"system volume.\n" +"system.\n" msgstr "" "не удалоÑÑŒ Ñоздать жёÑткую ÑÑылку между Ñтарым и новым каталогами данных: " "%s\n" -"Ð’ режиме \"ÑÑылок\" Ñтарый и новый каталоги данных должны находитьÑÑ Ð² одном " -"томе файловой ÑиÑтемы.\n" +"Ð’ режиме \"ÑÑылок\" Ñтарый и новый каталоги данных должны находитьÑÑ Ð² одной " +"файловой ÑиÑтеме.\n" #: function.c:110 #, c-format @@ -908,12 +956,8 @@ msgstr "Проверка Ð½Ð°Ð»Ð¸Ñ‡Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÐ¼Ñ‹Ñ… библиотек" #: function.c:255 #, c-format -msgid "" -"could not load library \"%s\":\n" -"%s\n" -msgstr "" -"не удалоÑÑŒ загрузить библиотеку \"%s\":\n" -"%s\n" +msgid "could not load library \"%s\": %s" +msgstr "загрузить библиотеку \"%s\" не удалоÑÑŒ: %s" #: function.c:269 #, c-format @@ -935,8 +979,8 @@ msgstr "" #: info.c:133 #, c-format msgid "" -"Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s" -"\", new name \"%s.%s\"\n" +"Relation names for OID %u in database \"%s\" do not match: old name \"%s." +"%s\", new name \"%s.%s\"\n" msgstr "" "Имена Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ OID %u в базе данных \"%s\" различаютÑÑ: Ñтарое Ð¸Ð¼Ñ - \"%s." "%s\", новое - \"%s.%s\"\n" @@ -969,8 +1013,8 @@ msgstr " Ñто TOAST-таблица Ð´Ð»Ñ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ OID %u" #: info.c:276 #, c-format msgid "" -"No match found in old cluster for new relation with OID %u in database \"%s" -"\": %s\n" +"No match found in old cluster for new relation with OID %u in database \"" +"%s\": %s\n" msgstr "" "Ð’ Ñтаром клаÑтере не нашлоÑÑŒ ÑоответÑÑ‚Ð²Ð¸Ñ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ OID %u в " "базе данных \"%s\": %s\n" @@ -978,8 +1022,8 @@ msgstr "" #: info.c:279 #, c-format msgid "" -"No match found in new cluster for old relation with OID %u in database \"%s" -"\": %s\n" +"No match found in new cluster for old relation with OID %u in database \"" +"%s\": %s\n" msgstr "" "Ð’ новом клаÑтере не нашлоÑÑŒ ÑоответÑÑ‚Ð²Ð¸Ñ Ð´Ð»Ñ Ñтарого Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ñ OID %u в " "базе данных \"%s\": %s\n" @@ -994,7 +1038,7 @@ msgstr "Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð±Ð°Ð·Ñ‹ данных \"%s\":\n" msgid "%s.%s: %u to %u\n" msgstr "%s.%s: %u в %u\n" -#: info.c:299 info.c:634 +#: info.c:299 info.c:638 #, c-format msgid "" "\n" @@ -1003,21 +1047,30 @@ msgstr "" "\n" "\n" -#: info.c:323 +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"иÑходные базы данных:\n" + +#: info.c:326 #, c-format msgid "" "\n" -"%s databases:\n" +"target databases:\n" msgstr "" "\n" -"базы данных %s:\n" +"целевые базы данных:\n" -#: info.c:632 +#: info.c:636 #, c-format msgid "Database: %s\n" msgstr "База данных: %s\n" -#: info.c:645 +#: info.c:649 #, c-format msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" msgstr "имÑ_отношениÑ: %s.%s: oid_отношениÑ: %u табл_проÑтранÑтво: %s\n" @@ -1063,10 +1116,10 @@ msgstr "раÑположение данных Ñтарого клаÑтера" msgid "new cluster data resides" msgstr "раÑположение данных нового клаÑтера" -#: option.c:265 option.c:460 +#: option.c:265 option.c:462 #, c-format -msgid "cannot find current directory\n" -msgstr "не удаётÑÑ Ð½Ð°Ð¹Ñ‚Ð¸ текущий каталог\n" +msgid "could not determine current directory\n" +msgstr "не удалоÑÑŒ определить текущий каталог\n" #: option.c:268 #, c-format @@ -1152,7 +1205,6 @@ msgid "" msgstr "" " -k, --link уÑтанавливать ÑÑылки вмеÑто ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ " "файлов\n" -"\n" " в новый клаÑтер\n" #: option.c:288 @@ -1182,8 +1234,8 @@ msgstr "" #, c-format msgid " -P, --new-port=PORT new cluster port number (default %d)\n" msgstr "" -" -P, --new-port=ПОРТ номер порта нового клаÑтера (по умолчанию " -"%d)\n" +" -P, --new-port=ПОРТ номер порта нового клаÑтера (по умолчанию %d)" +"\n" #: option.c:292 #, c-format @@ -1197,8 +1249,8 @@ msgstr "" #, c-format msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" msgstr "" -" -U, --username=ИМЯ Ñуперпользователь клаÑтера (по умолчанию \"%s" -"\")\n" +" -U, --username=ИМЯ Ñуперпользователь клаÑтера (по умолчанию \"" +"%s\")\n" #: option.c:294 #, c-format @@ -1314,85 +1366,94 @@ msgstr "" "ВоÑпользуйтеÑÑŒ Ð´Ð»Ñ Ñтого ключом командной Ñтроки %s или переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ " "%s.\n" -#: option.c:408 +#: option.c:409 #, c-format -msgid "Finding the real data directory for the %s cluster" -msgstr "ПоиÑк фактичеÑкого каталога данных Ð´Ð»Ñ ÐºÐ»Ð°Ñтера %s" +msgid "Finding the real data directory for the source cluster" +msgstr "ПоиÑк фактичеÑкого каталога данных Ð´Ð»Ñ Ð¸Ñходного клаÑтера" -#: option.c:421 +#: option.c:411 #, c-format -msgid "could not get data directory using %s: %s\n" -msgstr "не удалоÑÑŒ получить каталог данных, выполнив %s: %s\n" +msgid "Finding the real data directory for the target cluster" +msgstr "ПоиÑк фактичеÑкого каталога данных Ð´Ð»Ñ Ñ†ÐµÐ»ÐµÐ²Ð¾Ð³Ð¾ клаÑтера" -#: option.c:478 +#: option.c:423 #, c-format -msgid "Cannot open file %s: %m\n" -msgstr "Ðе удаётÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ файл %s: %m\n" +msgid "could not get data directory using %s: %s\n" +msgstr "не удалоÑÑŒ получить каталог данных, выполнив %s: %s\n" -#: option.c:485 +#: option.c:488 #, c-format -msgid "Cannot read line %d from %s: %m\n" -msgstr "Ðе удалоÑÑŒ прочитать Ñтроку %d из %s: %m\n" +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "не удалоÑÑŒ прочитать Ñтроку %d из файла \"%s\": %s\n" -#: option.c:502 +#: option.c:506 #, c-format -msgid "User-supplied old port number %hu corrected to %hu\n" -msgstr "Заданный пользователем Ñтарый номер порта %hu изменён на %hu\n" +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "заданный пользователем Ñтарый номер порта %hu изменён на %hu\n" -#: parallel.c:128 parallel.c:242 +#: parallel.c:128 parallel.c:241 #, c-format msgid "could not create worker process: %s\n" msgstr "не удалоÑÑŒ Ñоздать рабочий процеÑÑ: %s\n" -#: parallel.c:147 parallel.c:263 +#: parallel.c:147 parallel.c:262 #, c-format msgid "could not create worker thread: %s\n" msgstr "не удалоÑÑŒ Ñоздать рабочий поток: %s\n" -#: parallel.c:311 parallel.c:326 +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "Ñбой waitpid(): %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ð½ÐµÑˆÑ‚Ð°Ñ‚Ð½Ð¾ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹ %d\n" + +#: parallel.c:324 #, c-format msgid "child worker exited abnormally: %s\n" msgstr "дочерний процеÑÑ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»ÑÑ Ð°Ð²Ð°Ñ€Ð¸Ð¹Ð½Ð¾: %s\n" -#: pg_upgrade.c:107 +#: pg_upgrade.c:106 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "не удалоÑÑŒ Ñчитать права на каталог \"%s\": %s\n" + +#: pg_upgrade.c:123 #, c-format msgid "" "\n" "Performing Upgrade\n" +"------------------\n" msgstr "" "\n" "Выполнение обновлениÑ\n" +"---------------------\n" -#: pg_upgrade.c:108 -#, c-format -msgid "------------------\n" -msgstr "------------------\n" - -#: pg_upgrade.c:149 +#: pg_upgrade.c:166 #, c-format msgid "Setting next OID for new cluster" msgstr "УÑтановка Ñледующего OID Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ клаÑтера" -#: pg_upgrade.c:156 +#: pg_upgrade.c:173 #, c-format msgid "Sync data directory to disk" msgstr "Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð° данных Ñ Ð¤Ð¡" -#: pg_upgrade.c:167 +#: pg_upgrade.c:185 #, c-format msgid "" "\n" "Upgrade Complete\n" +"----------------\n" msgstr "" "\n" "Обновление завершено\n" +"--------------------\n" -#: pg_upgrade.c:168 -#, c-format -msgid "----------------\n" -msgstr "----------------\n" - -#: pg_upgrade.c:211 +#: pg_upgrade.c:231 #, c-format msgid "" "There seems to be a postmaster servicing the old cluster.\n" @@ -1401,7 +1462,7 @@ msgstr "" "Видимо, запущен процеÑÑ postmaster, обÑлуживающий Ñтарый клаÑтер.\n" "ОÑтановите его и попробуйте ещё раз.\n" -#: pg_upgrade.c:224 +#: pg_upgrade.c:244 #, c-format msgid "" "There seems to be a postmaster servicing the new cluster.\n" @@ -1410,75 +1471,75 @@ msgstr "" "Видимо, запущен процеÑÑ postmaster, обÑлуживающий новый клаÑтер.\n" "ОÑтановите его и попробуйте ещё раз.\n" -#: pg_upgrade.c:230 +#: pg_upgrade.c:250 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: не удалоÑÑŒ найти Ñвой иÑполнÑемый файл\n" -#: pg_upgrade.c:247 +#: pg_upgrade.c:267 #, c-format msgid "Analyzing all rows in the new cluster" msgstr "Ðнализ вÑех Ñтрок в новом клаÑтере" -#: pg_upgrade.c:260 +#: pg_upgrade.c:280 #, c-format -msgid "Freezing all rows on the new cluster" +msgid "Freezing all rows in the new cluster" msgstr "Замораживание вÑех Ñтрок в новом клаÑтере" -#: pg_upgrade.c:280 +#: pg_upgrade.c:300 #, c-format msgid "Restoring global objects in the new cluster" msgstr "ВоÑÑтановление глобальных объектов в новом клаÑтере" -#: pg_upgrade.c:304 +#: pg_upgrade.c:315 #, c-format msgid "Restoring database schemas in the new cluster\n" msgstr "ВоÑÑтановление Ñхем баз данных в новом клаÑтере\n" -#: pg_upgrade.c:366 +#: pg_upgrade.c:421 #, c-format msgid "Deleting files from new %s" msgstr "Удаление файлов из нового каталога %s" -#: pg_upgrade.c:370 +#: pg_upgrade.c:425 #, c-format msgid "could not delete directory \"%s\"\n" msgstr "ошибка при удалении каталога \"%s\"\n" -#: pg_upgrade.c:389 +#: pg_upgrade.c:444 #, c-format msgid "Copying old %s to new server" msgstr "Копирование Ñтарого каталога %s на новый Ñервер" -#: pg_upgrade.c:416 +#: pg_upgrade.c:471 #, c-format msgid "Setting next transaction ID and epoch for new cluster" msgstr "" "УÑтановка Ñледующего идентификатора транзакции и Ñпохи Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ клаÑтера" -#: pg_upgrade.c:446 +#: pg_upgrade.c:501 #, c-format msgid "Setting next multixact ID and offset for new cluster" msgstr "" "УÑтановка Ñледующего идентификатора и ÑÐ¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¼ÑƒÐ»ÑŒÑ‚Ð¸Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¸ Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ " "клаÑтера" -#: pg_upgrade.c:470 +#: pg_upgrade.c:525 #, c-format -msgid "Setting oldest multixact ID on new cluster" +msgid "Setting oldest multixact ID in new cluster" msgstr "УÑтановка Ñтарейшего идентификатора мультитранзакции в новом клаÑтере" -#: pg_upgrade.c:490 +#: pg_upgrade.c:545 #, c-format msgid "Resetting WAL archives" msgstr "Ð¡Ð±Ñ€Ð¾Ñ Ð°Ñ€Ñ…Ð¸Ð²Ð¾Ð² WAL" -#: pg_upgrade.c:522 +#: pg_upgrade.c:588 #, c-format msgid "Setting frozenxid and minmxid counters in new cluster" msgstr "УÑтановка Ñчётчиков frozenxid и minmxid в новом клаÑтере" -#: pg_upgrade.c:524 +#: pg_upgrade.c:590 #, c-format msgid "Setting minmxid counter in new cluster" msgstr "УÑтановка Ñчётчика minmxid в новом клаÑтере" @@ -1521,69 +1582,91 @@ msgstr "копирование \"%s\" в \"%s\"\n" msgid "linking \"%s\" to \"%s\"\n" msgstr "Ñоздание ÑÑылки на \"%s\" в \"%s\"\n" -#: server.c:33 +#: server.c:34 #, c-format -msgid "connection to database failed: %s\n" -msgstr "не удалоÑÑŒ подключитьÑÑ Ðº базе: %s\n" +msgid "connection to database failed: %s" +msgstr "не удалоÑÑŒ подключитьÑÑ Ðº базе: %s" -#: server.c:39 server.c:139 util.c:136 util.c:166 +#: server.c:40 server.c:142 util.c:136 util.c:166 #, c-format msgid "Failure, exiting\n" msgstr "Ошибка, выполнÑетÑÑ Ð²Ñ‹Ñ…Ð¾Ð´\n" -#: server.c:129 +#: server.c:132 #, c-format msgid "executing: %s\n" msgstr "выполнÑетÑÑ: %s\n" -#: server.c:135 +#: server.c:138 #, c-format msgid "" "SQL command failed\n" "%s\n" -"%s\n" +"%s" msgstr "" "Ошибка SQL-команды\n" "%s\n" -"%s\n" +"%s" -#: server.c:165 +#: server.c:168 #, c-format msgid "could not open version file: %s\n" msgstr "не удалоÑÑŒ открыть файл Ñ Ð²ÐµÑ€Ñией: %s\n" -#: server.c:284 +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "не удалоÑÑŒ разобрать файл PG_VERSION из %s\n" + +#: server.c:295 #, c-format msgid "" "\n" -"connection to database failed: %s\n" +"connection to database failed: %s" msgstr "" "\n" -"не удалоÑÑŒ подключитьÑÑ Ðº базе: %s\n" +"не удалоÑÑŒ подключитьÑÑ Ðº базе: %s" -#: server.c:288 +#: server.c:300 #, c-format msgid "" -"could not connect to %s postmaster started with the command:\n" +"could not connect to source postmaster started with the command:\n" "%s\n" msgstr "" -"не удалоÑÑŒ подключитьÑÑ Ðº главному процеÑÑу клаÑтера %s, запущенному " +"не удалоÑÑŒ подключитьÑÑ Ðº главному процеÑÑу иÑходного Ñервера, запущенному " "командой:\n" "%s\n" -#: server.c:300 +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"не удалоÑÑŒ подключитьÑÑ Ðº главному процеÑÑу целевого Ñервера, запущенному " +"командой:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "" +"программа pg_ctl не Ñмогла запуÑтить иÑходный Ñервер, либо к нему не удалоÑÑŒ " +"подключитьÑÑ\n" + +#: server.c:320 #, c-format -msgid "pg_ctl failed to start the %s server, or connection failed\n" +msgid "pg_ctl failed to start the target server, or connection failed\n" msgstr "" -"программа pg_ctl не Ñмогла запуÑтить Ñервер %s, либо к нему не удалоÑÑŒ " +"программа pg_ctl не Ñмогла запуÑтить целевой Ñервер, либо к нему не удалоÑÑŒ " "подключитьÑÑ\n" -#: server.c:345 +#: server.c:365 #, c-format msgid "out of memory\n" msgstr "нехватка памÑти\n" -#: server.c:358 +#: server.c:378 #, c-format msgid "libpq environment variable %s has a non-local server value: %s\n" msgstr "в переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð´Ð»Ñ libpq %s задано не локальное значение: %s\n" @@ -1634,7 +1717,7 @@ msgstr "ok" msgid "Checking for large objects" msgstr "Проверка больших объектов" -#: version.c:80 +#: version.c:80 version.c:382 #, c-format msgid "warning" msgstr "предупреждение" @@ -1645,7 +1728,7 @@ msgid "" "\n" "Your installation contains large objects. The new database has an\n" "additional large object permission table. After upgrading, you will be\n" -"given a command to populate the pg_largeobject permission table with\n" +"given a command to populate the pg_largeobject_metadata table with\n" "default permissions.\n" "\n" msgstr "" @@ -1653,8 +1736,8 @@ msgstr "" "Ð’ вашей инÑталлÑции иÑпользуютÑÑ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ðµ объекты. Ð’ новой базе данных\n" "имеетÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° Ñ Ð¿Ñ€Ð°Ð²Ð°Ð¼Ð¸ Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов. ПоÑле " "обновлениÑ\n" -"вам будет предÑтавлена команда Ð´Ð»Ñ Ð½Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ прав pg_largeobject\n" -"правами по умолчанию.\n" +"вам будет предÑтавлена команда Ð´Ð»Ñ Ð½Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ прав\n" +"pg_largeobject_metadata правами по умолчанию.\n" "\n" #: version.c:88 @@ -1680,8 +1763,8 @@ msgstr "" #: version.c:118 #, c-format -msgid "Checking for invalid \"line\" user columns" -msgstr "Проверка неправильных пользовательÑких Ñтолбцов типа \"line\"" +msgid "Checking for incompatible \"line\" data type" +msgstr "Проверка неÑовмеÑтимого типа данных \"line\"" #: version.c:180 #, c-format @@ -1694,8 +1777,8 @@ msgid "" " %s\n" "\n" msgstr "" -"Ð’ вашей инÑталлÑции пользовательÑкие таблицы иÑпользуют тип данных \"line" -"\".\n" +"Ð’ вашей инÑталлÑции пользовательÑкие таблицы иÑпользуют тип данных \"line\"." +"\n" "Ð’ Ñтаром клаÑтере внутренний формат и формат ввода/вывода Ñтого типа " "отличаетÑÑ\n" "от нового, поÑтому в наÑтоÑщем ÑоÑтоÑнии обновить клаÑтер невозможно. Ð’Ñ‹ " @@ -1720,10 +1803,82 @@ msgid "" " %s\n" "\n" msgstr "" -"Ð’ вашей инÑталлÑции пользовательÑкие таблицы иÑпользуют тип данных \"unknown" -"\".\n" +"Ð’ вашей инÑталлÑции пользовательÑкие таблицы иÑпользуют тип данных " +"\"unknown\".\n" "Теперь иÑпользование Ñтого типа данных не допуÑкаетÑÑ, поÑтому в наÑтоÑщем\n" "ÑоÑтоÑнии обновить клаÑтер невозможно. Ð’Ñ‹ можете удалить проблемные таблицы\n" "и перезапуÑтить обновлениÑ. СпиÑок проблемных Ñтолбцов приведён в файле:\n" " %s\n" "\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Проверка хеш-индекÑов" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Ð’ вашей инÑталлÑции иÑпользуютÑÑ Ñ…ÐµÑˆ-индекÑÑ‹. Эти индекÑÑ‹ имеют разные\n" +"внутренние форматы в Ñтаром и новом клаÑтерах, поÑтому их необходимо\n" +"переÑтроить Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команды REINDEX. По завершении Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ñ‹ получите\n" +"инÑтрукции по выполнению REINDEX.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Ð’ вашей инÑталлÑции иÑпользуютÑÑ Ñ…ÐµÑˆ-индекÑÑ‹. Эти индекÑÑ‹ имеют разные\n" +"внутренние форматы в Ñтаром и новом клаÑтерах, поÑтому их необходимо\n" +"переÑтроить Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ команды REINDEX. Скрипт\n" +" %s\n" +"будучи выполненным админиÑтратором БД в psql, переÑоздаÑÑ‚ вÑе неправильные\n" +"индекÑÑ‹; до Ñтого никакие хеш-индекÑÑ‹ не будут иÑпользоватьÑÑ.\n" +"\n" + +#~ msgid "" +#~ "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" +#~ "because of backend API changes made during development.\n" +#~ msgstr "" +#~ "Эта утилита поддерживает обновление только до верÑии 9.0 поÑле 2010-01-11," +#~ "\n" +#~ "так как в API Ñерверной чаÑти были внеÑены изменениÑ.\n" + +#~ msgid "Cannot open file %s: %m\n" +#~ msgstr "Ðе удаётÑÑ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ файл %s: %m\n" + +#~ msgid "Cannot read line %d from %s: %m\n" +#~ msgstr "Ðе удалоÑÑŒ прочитать Ñтроку %d из %s: %m\n" + +#~ msgid "------------------------------------------------\n" +#~ msgstr "------------------------------------------------\n" + +#~ msgid "-----------------------------\n" +#~ msgstr "-----------------------------\n" + +#~ msgid "------------------\n" +#~ msgstr "------------------\n" + +#~ msgid "----------------\n" +#~ msgstr "----------------\n" + +#~ msgid "Checking for invalid \"line\" user columns" +#~ msgstr "Проверка неправильных пользовательÑких Ñтолбцов типа \"line\"" diff --git a/src/bin/pg_upgrade/po/sv.po b/src/bin/pg_upgrade/po/sv.po new file mode 100644 index 00000000000..6f2f836e78e --- /dev/null +++ b/src/bin/pg_upgrade/po/sv.po @@ -0,0 +1,1799 @@ +# Swedish message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Dennis Björklund , 2017, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 16:46+0000\n" +"PO-Revision-Date: 2019-04-29 20:31+0200\n" +"Last-Translator: Dennis Björklund \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: check.c:67 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Utför konsistenskontroller pÃ¥ gamla live-servern\n" +"------------------------------------------------\n" + +#: check.c:73 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Utför konsistenskontroller\n" +"--------------------------\n" + +#: check.c:183 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Klustren är kompatibla*\n" + +#: check.c:189 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"Om pg_upgrade misslyckas efter denna punkt sÃ¥ mÃ¥ste du\n" +"köra om initdb pÃ¥ nya klustret innan du fortsätter.\n" + +#: check.c:225 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Optimeringsstatistik överförs inte av pg_upgrade sÃ¥\n" +"när du startar nya servern sÃ¥ vill du nog köra:\n" +" %s\n" +"\n" + +#: check.c:230 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Optimeringsstatistik och information om ledigt utrymme överförs\n" +"inte av pg_upgrade sÃ¥ när du startar nya servern sÃ¥ vill du nog köra:\n" +" %s\n" + +#: check.c:237 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"När detta skript körs sÃ¥ raderas gamla klustrets datafiler:\n" +" %s\n" + +#: check.c:242 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Kunde inte skapa ett script som raderar gamla klustrets datafiler\n" +"dÃ¥ användardefinierade tabellutrymmen eller nya klustrets datakatalog\n" +"ligger i gamla klusterkatalogen. Det gamla klustrets innehÃ¥ll\n" +"mÃ¥ste raderas för hand.\n" + +#: check.c:252 +#, c-format +msgid "Checking cluster versions" +msgstr "Kontrollerar klustrets versioner" + +#: check.c:264 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Detta verktyg kan bara uppgradera frÃ¥n PostgreSQL version 8.4 eller nyare.\n" + +#: check.c:268 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Detta verktyg kan bara uppgradera till PostgreSQL version %s.\n" + +#: check.c:277 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "Detta verktyg kan inte användas för att nergradera till äldre major-versioner av PostgreSQL.\n" + +#: check.c:282 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Gammal klusterdata och binära kataloger är frÃ¥n olika major-versioner.\n" + +#: check.c:285 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Nya klusterdata och binära kataloger är frÃ¥n olika major-versioner.\n" + +#: check.c:302 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "Vid kontroll av en gammal live-server före PG 9.1 sÃ¥ mÃ¥ste den gamla serverns portnummer anges.\n" + +#: check.c:306 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Vid kontroll av en live-server sÃ¥ mÃ¥ste gamla och nya portnumren vara olika.\n" + +#: check.c:321 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "kodning för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:326 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_collate-värden för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:329 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "lc_ctype-värden för databasen \"%s\" matchar inte: gammal \"%s\", ny \"%s\"\n" + +#: check.c:402 +#, c-format +msgid "New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n" +msgstr "Nya databasklustret \"%s\" är inte tomt: hittade relation \"%s.%s\"\n" + +#: check.c:451 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Skapar skript för att analysera nya klustret" + +#: check.c:465 check.c:593 check.c:857 check.c:936 check.c:1045 check.c:1136 +#: file.c:341 function.c:246 option.c:493 version.c:57 version.c:156 +#: version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "kan inte öppna fil \"%s\": %s\n" + +#: check.c:520 check.c:649 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "kan inte sätta rättigheten \"körbar\" pÃ¥ filen \"%s\": %s\n" + +#: check.c:556 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"VARNING: nya datakatalogen skall inte ligga inuti den gamla datakatalogen, dvs. %s\n" + +#: check.c:580 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"VARNING: användardefinierade tabellutrymmens position skall inte vara i datakatalogen, dvs. %s\n" + +#: check.c:590 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Skapar skript för att radera gamla klustret" + +#: check.c:669 +#, c-format +msgid "Checking database user is the install user" +msgstr "Kontrollerar att databasanvändaren är installationsanvändaren" + +#: check.c:685 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "databasanvändare \"%s\" är inte installationsanvändaren\n" + +#: check.c:696 +#, c-format +msgid "could not determine the number of users\n" +msgstr "kunde inte bestämma antalet användare\n" + +#: check.c:704 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Bara installationsanvändaren fÃ¥r finnas i nya klustret.\n" + +#: check.c:724 +#, c-format +msgid "Checking database connection settings" +msgstr "Kontrollerar databasens anslutningsinställningar" + +#: check.c:746 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 fÃ¥r inte tillÃ¥ta anslutningar, dvs dess pg_database.datallowconn mÃ¥ste vara false\n" + +#: check.c:756 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "Alla icke-template0-databaser mÃ¥ste tillÃ¥ta anslutningar, dvs. deras pg_database.datallowconn mÃ¥ste vara true\n" + +#: check.c:781 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Letar efter förberedda transaktioner" + +#: check.c:790 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Källklustret innehÃ¥ller förberedda transaktioner\n" + +#: check.c:792 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "MÃ¥lklustret innehÃ¥ller förberedda transaktioner\n" + +#: check.c:818 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "Letar efter contrib/isn med bigint-anropsfel" + +#: check.c:879 check.c:958 check.c:1068 check.c:1159 function.c:268 +#: version.c:179 version.c:280 +#, c-format +msgid "fatal\n" +msgstr "fatalt\n" + +#: check.c:880 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehÃ¥ller \"contrib/isn\"-funktioner sin beror pÃ¥\n" +"datatypen bigint. Ditt gamla och nya kluster skickar bigint-värden\n" +"pÃ¥ olika sätt sÃ¥ detta kluster kan för närvarande inte uppgraderas. Du\n" +"kan manuellt uppgradera databaser som använder \"contrib/isn\"-finesser\n" +"genom att radera \"contrib/isn\" frÃ¥n gamla klustret och Ã¥terstarta\n" +"uppgraderingen. En lista med problemfunktionerna finns i filen:\n" +" %s\n" +"\n" + +#: check.c:904 +#, c-format +msgid "Checking for tables WITH OIDS" +msgstr "Letar efter tabeller med WITH OIDS" + +#: check.c:959 +#, c-format +msgid "" +"Your installation contains tables declared WITH OIDS, which is not supported\n" +"anymore. Consider removing the oid column using\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"A list of tables with the problem is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehÃ¥ller tabeller deklarerade med WITH OIDS som inte stöds\n" +"längre. Överväg att ta bort oid-kolumnen med\n" +" ALTER TABLE ... SET WITHOUT OIDS;\n" +"En lista över tabeller med detta problem finns i filen:\n" +" %s\n" +"\n" + +# FIXME: is this msgid correct? +#: check.c:989 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Letar efter reg*-datatyper i användartabeller" + +#: check.c:1069 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation använder en av reg*-datatyperna i en användartabell.\n" +"Dessa datatyper refererar system-OID:er som inte bevaras av pg_upgrade\n" +"sÃ¥ detta kluster kan för närvarande inte uppgraderas. Du kan ta bort\n" +"problemtabellerna och starta om uppgraderingen. En lista med\n" +"problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +# FIXME: is this msgid correct? +#: check.c:1094 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Letar efter inkompatibel \"jsonb\"-datatyp" + +#: check.c:1160 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehÃ¥ller \"jsonb\"-datatypen i användartabeller.\n" +"Interna formatet för \"jsonb\" ändrades under 9.4-betan sÃ¥ detta kluster kan\n" +"för närvarande inte uppgraderas. Du kan ta bort problemtabellerna och\n" +"starta om uppgraderingen. En lista med problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +#: check.c:1181 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "Letar efter roller som startar med \"pg_\"" + +#: check.c:1191 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Källklustret innehÃ¥ller roller som startar med \"pg_\"\n" + +#: check.c:1193 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "MÃ¥lklustret innehÃ¥ller roller som startar med \"pg_\"\n" + +#: check.c:1219 +#, c-format +msgid "failed to get the current locale\n" +msgstr "misslyckades med att hämta aktuell lokal\n" + +#: check.c:1228 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "misslyckades med att hämta systemlokalnamn för \"%s\"\n" + +#: check.c:1234 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "misslyckades med att Ã¥terställa gamla lokalen \"%s\"\n" + +#: controldata.c:127 controldata.c:194 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "kunde inte hämta kontrolldata med %s: %s\n" + +#: controldata.c:138 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: state-problem för databaskluster\n" + +#: controldata.c:155 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Källklustret stängdes ner när det var i Ã¥terställningsläge. För att uppgradera sÃ¥ använd \"rsync\" enligt dokumentation eller stäng ner den som en primär.\n" + +#: controldata.c:157 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "MÃ¥lklustret stängdes ner när det var i Ã¥terställningsläge. För att uppgradera sÃ¥ använd \"rsync\" enligt dokumentation eller stäng ner den som en primär.\n" + +#: controldata.c:162 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Källklustret har inte stängts ner pÃ¥ ett korrekt sätt.\n" + +#: controldata.c:164 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "MÃ¥lklustret har inte stängts ner pÃ¥ ett korrekt sätt\n" + +#: controldata.c:175 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Källklustret saknar information om kluster-state:\n" + +#: controldata.c:177 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "MÃ¥lklustret saknar information om kluster-state:\n" + +#: controldata.c:207 dump.c:51 pg_upgrade.c:336 pg_upgrade.c:373 +#: relfilenode.c:255 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:214 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal-problem\n" + +#: controldata.c:224 controldata.c:234 controldata.c:245 controldata.c:256 +#: controldata.c:267 controldata.c:286 controldata.c:297 controldata.c:308 +#: controldata.c:319 controldata.c:330 controldata.c:341 controldata.c:344 +#: controldata.c:348 controldata.c:358 controldata.c:370 controldata.c:381 +#: controldata.c:392 controldata.c:403 controldata.c:414 controldata.c:425 +#: controldata.c:436 controldata.c:447 controldata.c:458 controldata.c:469 +#: controldata.c:480 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: problem vid hämtning av kontrolldata\n" + +#: controldata.c:545 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Källklustret saknar lite kontrolldata som krävs:\n" + +#: controldata.c:548 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "MÃ¥lklustret saknar lite kontrolldata som krävs:\n" + +#: controldata.c:551 +#, c-format +msgid " checkpoint next XID\n" +msgstr " checkpoint nästa-XID\n" + +#: controldata.c:554 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " senaste checkpoint nästa-OID\n" + +#: controldata.c:557 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " senaster checkpoint nästa-MultiXactId\n" + +#: controldata.c:561 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " senaste checkpoint äldsta-MultiXactId\n" + +#: controldata.c:564 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " senaste checkpoint nästa-MultiXactOffset\n" + +#: controldata.c:567 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " första WAL-segmentet efter reset\n" + +#: controldata.c:570 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 argumentöverföringsmetod\n" + +#: controldata.c:573 +#, c-format +msgid " maximum alignment\n" +msgstr " maximal alignment\n" + +#: controldata.c:576 +#, c-format +msgid " block size\n" +msgstr " blockstorlek\n" + +#: controldata.c:579 +#, c-format +msgid " large relation segment size\n" +msgstr " stora relationers segmentstorlek\n" + +#: controldata.c:582 +#, c-format +msgid " WAL block size\n" +msgstr " WAL-blockstorlek\n" + +#: controldata.c:585 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL-segmentstorlek\n" + +#: controldata.c:588 +#, c-format +msgid " maximum identifier length\n" +msgstr " maximal identifierarlängd\n" + +#: controldata.c:591 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " maximalt antal indexerade kolumner\n" + +#: controldata.c:594 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " maximal TOAST-chunkstorlek\n" + +#: controldata.c:598 +#, c-format +msgid " large-object chunk size\n" +msgstr " stora-objekt chunkstorlek\n" + +#: controldata.c:601 +#, c-format +msgid " dates/times are integers?\n" +msgstr " datum/tid är heltal?\n" + +#: controldata.c:605 +#, c-format +msgid " data checksum version\n" +msgstr " datachecksumversion\n" + +#: controldata.c:607 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Kan inte fortsätta utan kontrollinformation som krävs, avslutar\n" + +#: controldata.c:622 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"gamla och nya pg_controldata-alignments är ogiltiga eller matchar inte.\n" +"Troligen är ett kluster en 32-bitars-installation och den andra 64-bitars\n" + +#: controldata.c:626 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata-blockstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:629 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximala relationssegmentstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:632 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata WAL-blockstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:635 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata WAL-segmentstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:638 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximal identifierarlängder är ogiltiga eller matchar inte\n" + +#: controldata.c:641 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maxilmalt indexerade kolumner ogiltiga eller matchar inte\n" + +#: controldata.c:644 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata maximal TOAST-chunkstorlek ogiltiga eller matchar inte\n" + +#: controldata.c:649 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "gamla och nya pg_controldata stora-objekt-chunkstorlekar är ogiltiga eller matchar inte\n" + +#: controldata.c:652 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "gamla och nya pg_controldata datum/tid-lagringstyper matchar inte\n" + +#: controldata.c:665 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "gamla klustret använder inte datachecksummor men nya gör det\n" + +#: controldata.c:668 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "gamla klustret använder datachecksummor men nya gör inte det\n" + +#: controldata.c:670 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "gamla och nya klustrets pg_controldata checksumversioner matchar inte\n" + +#: controldata.c:681 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "Lägger till \".old\"-suffix till gamla global/pg_control" + +#: controldata.c:686 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "Kan inte byta namn pÃ¥ %s till %s.\n" + +#: controldata.c:689 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Om du vill starta gamla klustret sÃ¥ mÃ¥ste du ta bort\n" +"\".old\"-suffixet frÃ¥n %s/global/pg_control.old.\n" +"Detta dÃ¥ \"link\"-läge användes och gamla klustret kan inte\n" +"startas pÃ¥ ett säkert sätt efter att nya klustret startats.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "Skapar dump med globala objekt" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Skapar dump med databasscheman\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "kunde inte hämta pg_ctl versionsdata med %s: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "kunde inte läsa versionutdata för pg_ctl frÃ¥n %s\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "kommandot för lÃ¥ngt\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:105 option.c:227 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "kunde inte skriva till loggfil: \"%s\"\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*misslyckande*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "Det var problem med att köra \"%s\"\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Se de sista raderna i \"%s\" eller \"%s\" för\n" +"en trolig orsak till misslyckandet.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Se de sista raderna i \"%s\" för\n" +"en trolig orsak till misslyckandet.\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "kunde inte öppna fil \"%s\" för läsning: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Du mÃ¥ste ha läs och skrivrättigheter till den aktuella katalogen.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "kontroll av \"%s\" misslyckades: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" är inte en katalog\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "kontroll av \"%s\" misslyckades: inte en vanlig fil\n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "kontroll av \"%s\" misslyckades: kan inte läsa filen (rättighet saknas)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "kontroll av \"%s\" misslyckades: kan inte exekvera (rättighet saknas)\n" + +#: file.c:48 file.c:66 +#, c-format +msgid "error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kloning av relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:55 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "fel vid kloning av relation \"%s.%s\": kunde inte öppna filen \"%s\": %s\n" + +#: file.c:60 +#, c-format +msgid "error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "fel vid kloning av relation \"%s.%s\": kunde inte skapa filen \"%s\": %s\n" + +#: file.c:92 file.c:195 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte öppna filen \"%s\": %s\n" + +#: file.c:97 file.c:204 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte skapa filen \"%s\": %s\n" + +#: file.c:111 file.c:228 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte läsa filen \"%s\": %s\n" + +#: file.c:123 file.c:306 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte skriva filen \"%s\": %s\n" + +#: file.c:137 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:156 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid skapande av länk för relation \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: file.c:199 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "fel vid kopiering av relation \"%s.%s\": kunde inte göra stat pÃ¥ file \"%s\": %s\n" + +#: file.c:231 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "fel vid kopiering av relation \"%s.%s\": partiell sida hittad i fil \"%s\"\n" + +#: file.c:333 file.c:350 +#, c-format +msgid "could not clone file between old and new data directories: %s\n" +msgstr "kunde inte klona fil mellan gamla och nya datakatalogen: %s\n" + +#: file.c:346 +#, c-format +msgid "could not create file \"%s\": %s\n" +msgstr "kan inte skapa fil \"%s\": %s\n" + +#: file.c:357 +#, c-format +msgid "file cloning not supported on this platform\n" +msgstr "filkloning stöds inte pÃ¥ denna plattform\n" + +#: file.c:374 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"kunde inte skapa hÃ¥rd länk mellan gamla och nya datakatalogerna: %s\n" +"I länk-läge mÃ¥ste gamla och nya datakatalogerna vara i samma filsystem.\n" + +#: function.c:116 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Det gamla klustret har en \"plpython_call_handler\"-funktion definierad\n" +"i \"public\"-schemat vilket är en kopia pÃ¥ den som definierats\n" +"i \"pg_catalog\"-schemat. Du kan verifiera detta genom att i\n" +"psql köra:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"\"public\"-schema-versionen av denna funktion har skapats av en\n" +"pre-8.1-installation av plpython och mÃ¥ste raderas för att pg_upgrade\n" +"skall kunna gÃ¥ klart dÃ¥ den referar till en nu förÃ¥ldrad\n" +"\"plpython\" delad objektfil. Du kan ta bort \"public\"-schemaversionen\n" +"av denna funktion genom att köra följande kommando:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"i varje inblandad databas:\n" +"\n" + +#: function.c:134 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:144 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Ta bort problemfunktionerna frÃ¥n gamla klustret för att fortsätta.\n" + +#: function.c:191 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Kontrollerar att krävda länkbibliotek finns" + +#: function.c:248 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "kunde inte ladda länkbibliotek \"%s\": %s" + +#: function.c:259 info.c:645 +#, c-format +msgid "Database: %s\n" +msgstr "Databas: %s\n" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation refererar till laddbara bibliotek som saknas i nya\n" +"installationen. Du kan lägga till dessa itll nya installationen eller\n" +"ta bort funktionerna som använder dem i gamla installationen. En lista\n" +"med problembiblioteken finns i filen:\n" +" %s\n" +"\n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "Relationsname för OID %u i databas \"%s\" matchar inte: gammalt namn \"%s.%s\", nytt namn \"%s.%s\"\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "Misslyckades med att matcha ihop gamla och nya tabeller i databas \"%s\"\n" + +#: info.c:244 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " vilket är ett index för \"%s.%s\"" + +#: info.c:254 +#, c-format +msgid " which is an index on OID %u" +msgstr " vilket är ett index för OID %u" + +#: info.c:266 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " vilket är TOAST-tabellen för \"%s.%s\"" + +#: info.c:274 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " vilket är TOAST-tabellen för OID %u" + +#: info.c:278 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "Ingen träff hittad i gamla klustret för ny relation med OID %u i databas \"%s\": %s\n" + +#: info.c:281 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "Ingen träff hittad i nya klustret för gammal relation med OID %u i databas \"%s\": %s\n" + +#: info.c:293 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "avbildningar för databasen \"%s\":\n" + +#: info.c:296 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u till %u\n" + +#: info.c:301 info.c:647 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"källdatabaser:\n" + +#: info.c:328 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"mÃ¥ldatabaser:\n" + +#: info.c:658 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relnamn: %s.%s: reloid: %u reltblutrymme: %s\n" + +#: option.c:102 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: kan inte köras som root\n" + +#: option.c:174 +#, c-format +msgid "invalid old port number\n" +msgstr "ogiltigt gammalt portnummer\n" + +#: option.c:182 +#, c-format +msgid "invalid new port number\n" +msgstr "ogiltigt nytt portnummer\n" + +#: option.c:208 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Kör i utförligt läge\n" + +#: option.c:217 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Försök med \"%s --help\" för mer information.\n" + +# FIXME: the source code need to be fixed here. it paste words together +#: option.c:252 +msgid "old cluster binaries reside" +msgstr "gamla klusterbinärer är i" + +#: option.c:254 +msgid "new cluster binaries reside" +msgstr "nya klusterbinärer är i" + +#: option.c:256 +msgid "old cluster data resides" +msgstr "gamla klusterdatan är i" + +#: option.c:258 +msgid "new cluster data resides" +msgstr "nya klusterdatan är i" + +#: option.c:260 +msgid "sockets will be created" +msgstr "uttag kommer skapas" + +#: option.c:277 option.c:371 +#, c-format +msgid "could not determine current directory\n" +msgstr "kunde inte bestämma aktuell katalog\n" + +#: option.c:280 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "kan inte köra pg_upgrade inifrÃ¥n nya klusterdatakatalogen i Windows\n" + +#: option.c:289 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade uppgraderar ett PostgreSQL-kluster till en annan major-version.\n" +"\n" + +#: option.c:290 +#, c-format +msgid "Usage:\n" +msgstr "Användning:\n" + +#: option.c:291 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [FLAGGA]...\n" +"\n" + +#: option.c:292 +#, c-format +msgid "Options:\n" +msgstr "Flaggor:\n" + +#: option.c:293 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINKAT gamla klustrets katalog för körbara filer\n" + +#: option.c:294 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINKAT nya klustrets katalog för körbara filer\n" + +#: option.c:295 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check testa klustren bara, ändra ingen data\n" + +#: option.c:296 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATAKAT gamla klustrets datakatalog\n" + +#: option.c:297 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATAKAT nya klustrets datakatalog\n" + +#: option.c:298 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs antal samtidiga processer eller trÃ¥dar att använda\n" + +#: option.c:299 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link länka istället för att kopiera filer till nya klustret\n" + +#: option.c:300 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=FLAGGOR serverflaggor för gamla klustret\n" + +#: option.c:301 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --new-options=FLAGGOR serverflaggor för nya klustret\n" + +#: option.c:302 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT gamla klustrets portnummer (standard %d)\n" + +#: option.c:303 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT nya klustrets portnummer (standard %d)\n" + +#: option.c:304 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain behÃ¥ll SQL och loggfiler efter lyckad uppgradering\n" + +#: option.c:305 +#, c-format +msgid " -s, --socketdir=DIR socket directory to use (default CWD)\n" +msgstr " -s, --socketdir=KAT uttagskatalog (standard CWD)\n" + +#: option.c:306 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr " -U, --username=NAMN klustrets superanvändare (standard \"%s\")\n" + +#: option.c:307 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose slÃ¥ pÃ¥ utförligt intern loggning\n" + +#: option.c:308 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version visa versionsinformation, avsluta sedan\n" + +#: option.c:309 +#, c-format +msgid " --clone clone instead of copying files to new cluster\n" +msgstr " -clone klona istället för att kopiera filer till nya klustret\n" + +#: option.c:310 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help visa denns hjälp, avsluta sedan\n" + +#: option.c:311 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"Innan du kör pg_upgrade mÃ¥ste du:\n" +" skapa ett nytt databaskluster (med nya versionens initdb)\n" +" stänga ner den postmaster som hanterar gamla klustret\n" +" stänga ner den postmaster som hanterar nya klustret\n" + +#: option.c:316 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"När du kör pg_upgrade mÃ¥ste du ange följande information:\n" +" datakatalogen för gamla klustret (-d DATAKAT)\n" +" datakatalogen för nya klustret (-D DATAKAT)\n" +" \"bin\"-katalogen för gamla versionen (-b BINKAT)\n" +" \"bin\"-katalogen för nya versionen (-B BINKAT)\n" + +#: option.c:322 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Till exempel:\n" +" pg_upgrade -d gammaltKluster/data -D nyttKluster/data -b gammaltKluster/bin -B nyttKluster/bin\n" +"eller\n" + +#: option.c:327 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=gammaltKluster/data\n" +" $ export PGDATANEW=nyttKluster/data\n" +" $ export PGBINOLD=gammaltKluster/bin\n" +" $ export PGBINNEW=nyttKluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:333 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=gammaltKluster/data\n" +" C:\\> set PGDATANEW=nyttKluster/data\n" +" C:\\> set PGBINOLD=gammaltKluster/bin\n" +" C:\\> set PGBINNEW=nyttKluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:339 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Rapportera fel till .\n" + +#: option.c:375 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"Du mÃ¥ste identifiera katalogen där %s.\n" +"Använd kommandoradsflaggan %s eller omgivningsvariabeln %s.\n" + +#: option.c:427 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Letar efter den riktiga datakatalogen i källklustret" + +#: option.c:429 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Letar efter den riktiga datakatalogen för mÃ¥lklustret" + +#: option.c:441 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "kunde inte hämta datakatalogen med %s: %s\n" + +#: option.c:501 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "kunde inte läsa rad %d frÃ¥n fil \"%s\": %s\n" + +#: option.c:519 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "användarangivet gammalt portnummer %hu korrigerat till %hu\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "kunde inte skapa arbetsprocess: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "kunde inte skapa arbetstrÃ¥d: %s\n" + +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() misslyckades: %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "barnprocess avslutade felaktigt: status %d\n" + +#: parallel.c:324 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "barnprocess avslutade felaktigt: %s\n" + +#: pg_upgrade.c:109 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "kunde inte läsa rättigheter pÃ¥ katalog \"%s\": %s\n" + +#: pg_upgrade.c:126 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Utför uppgradering\n" +"------------------\n" + +#: pg_upgrade.c:169 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Sätter nästa OID för nya klustret" + +#: pg_upgrade.c:176 +#, c-format +msgid "Sync data directory to disk" +msgstr "Synkar datakatalog till disk" + +#: pg_upgrade.c:188 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Uppgradering klar\n" +"-----------------\n" + +#: pg_upgrade.c:234 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Det verkar vara en postmaster igÃ¥ng som hanterar gamla klustret.\n" +"Stänga ner den postmastern och försök igen.\n" + +#: pg_upgrade.c:247 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Det verkar vara en postmaster igÃ¥ng som hanterar nya klustret.\n" +"Stänga ner den postmastern och försök igen.\n" + +#: pg_upgrade.c:253 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: kunde inte hitta det egna programmets körbara fil\n" + +#: pg_upgrade.c:270 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Analyserar alla rader i nya klustret" + +#: pg_upgrade.c:283 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Fryser alla rader i nya klustret" + +#: pg_upgrade.c:303 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Ã…terställer globala objekt i nya klustret" + +#: pg_upgrade.c:318 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Ã…terställer databasscheman i nya klustret\n" + +#: pg_upgrade.c:424 +#, c-format +msgid "Deleting files from new %s" +msgstr "Raderar filer frÃ¥n ny %s" + +#: pg_upgrade.c:428 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "kunde inte ta bort katalog \"%s\"\n" + +#: pg_upgrade.c:447 +#, c-format +msgid "Copying old %s to new server" +msgstr "Kopierar gammal %s till ny server" + +#: pg_upgrade.c:474 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Sätter nästa transaktions-ID och epoch för nytt kluster" + +#: pg_upgrade.c:504 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Sätter nästa multixact-ID och offset för nytt kluster" + +#: pg_upgrade.c:528 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Sätter äldsta multixact-ID i nytt kluster" + +#: pg_upgrade.c:548 +#, c-format +msgid "Resetting WAL archives" +msgstr "Resettar WAL-arkiv" + +#: pg_upgrade.c:591 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Sätter räknarna frozenxid och minmxid för nytt kluster" + +#: pg_upgrade.c:593 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Sätter räknarenm minmxid för nytt kluster" + +#: relfilenode.c:38 +#, c-format +msgid "Cloning user relation files\n" +msgstr "Klonar användares relationsfiler\n" + +#: relfilenode.c:41 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kopierar användares relationsfiler\n" + +#: relfilenode.c:44 +#, c-format +msgid "Linking user relation files\n" +msgstr "Länkar användares relationsfiler\n" + +#: relfilenode.c:120 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "gamla databasen \"%s\" kan inte hittas i nya klustret\n" + +#: relfilenode.c:242 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "fel vid kontroll av filexistens \"%s.%s\" (\"%s\" till \"%s\"): %s\n" + +#: relfilenode.c:260 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "skriver om \"%s\" till \"%s\"\n" + +#: relfilenode.c:268 +#, c-format +msgid "cloning \"%s\" to \"%s\"\n" +msgstr "klonar \"%s\" till \"%s\"\n" + +#: relfilenode.c:273 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "kopierar \"%s\" till \"%s\"\n" + +#: relfilenode.c:278 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "länkar \"%s\" till \"%s\"\n" + +#: relfilenode.c:331 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\"): %s\n" +msgstr "fel vid kontroll av filexistens \"%s.%s\" (\"%s\"): %s\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "anslutning till databas misslyckades: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "Misslyckades, avslutar\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "kör: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL-kommando misslyckades\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "kunde inte öppna versionsfil: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "kunde inte parsa PG_VERSION-fil frÃ¥n %s\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"anslutning till databas misslyckades: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"kunde inte ansluta till käll-postmaster som startats med kommandot:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"kunde inte ansluta till mÃ¥l-postmaster som startats med kommandot:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl misslyckades att start källservern eller sÃ¥ misslyckades anslutningen\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl misslyckades att start mÃ¥lservern eller sÃ¥ misslyckades anslutningen\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "slut pÃ¥ minne\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "libpq:s omgivningsvariabel %s har ett icke-lokalt servervärde: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Kan inte uppgradera till/frÃ¥n samma systemkatalogversion när\n" +"man använder tablespace.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "tablespace-katalogen \"%s\" finns inte\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "kunde inte göra stat pÃ¥ tablespace-katalog \"%s\": %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "tablespace-sökväg \"%s\" är inte en katalog\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "ok" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "Letar efter stora objekt" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "varning" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehÃ¥ller stora objekt. Den nya databasen\n" +"har en extra rättighetstabell för stora objekt. Efter uppgradering\n" +"kommer du ges ett kommando för att populera rättighetstabellen\n" +"pg_largeobject_metadata med standardrättigheter.\n" +"\n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehÃ¥ller stora objekt. Den nya databasen har en extra\n" +"rättighetstabell för stora onbjekt sÃ¥ standardrättigheter mÃ¥ste ges för\n" +"alla stora objekt. Filen\n" +" %s\n" +"kan köras med psql av databasens superanvändare för att sätta\n" +"standardrättigheter.\n" +"\n" + +# FIXME: is this msgid correct? +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Letar efter inkompatibel \"line\"-datatyp" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehÃ¥ller datatypen \"line\" i användartabeller. Denna\n" +"datatype har ändrat sitt interna format samt sitt in/ut-format mellan ditt\n" +"gamla och nya kluster sÃ¥ detta kluster kan för närvarande inte uppgraderas.\n" +"Du kan radera problemtabellerna och Ã¥terstarta uppgraderingen. En lista\n" +"med problemkolumner finns i filen:\n" +" %s\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Letar efter ogiltiga användarkolumner av typen \"unknown\"" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Din installation innehÃ¥ller användartabeller med datatypen \"unknown\".\n" +"Denna typ tillÃ¥ts inte längre i tabeller sÃ¥ detta kluster kan\n" +"för närvarande inte uppgraderas. Du kan radera problemtabellerna och\n" +"Ã¥terstarta uppgraderingen. En lista med problemkolumnerna finns i filen:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Letar efter hash-index" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Din installation innehÃ¥ller hash-index. Dessa index har olika internt\n" +"format i ditt gamla och nya kluster sÃ¥ de mÃ¥ste omindexeras med\n" +"kommandot REINDEX. Efter uppgraderingen sÃ¥ kommer du fÃ¥\n" +"REINDEX-instruktioner.\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Din installation innehÃ¥ller hash-index. Dessa index har olika internt\n" +"format i ditt gamla och nya kluster sÃ¥ de mÃ¥ste omindexeras med\n" +"kommandot REINDEX. Filen\n" +" %s\n" +"kan köras med psql av databasens superanvändare och kommer Ã¥terskapa\n" +"alla ogiltiga index; innan dess sÃ¥ kommer inget av dess index användas.\n" +"\n" + +#~ msgid "------------------------------------------------\n" +#~ msgstr "------------------------------------------------\n" + +#~ msgid "-----------------------------\n" +#~ msgstr "-----------------------------\n" + +#~ msgid "" +#~ "This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n" +#~ "because of backend API changes made during development.\n" +#~ msgstr "" +#~ "Detta verktyg kan bara uppgradera till PostgreSQL version 9.0 efter 2010-01-11\n" +#~ "dÃ¥ backend-API-ändringar gjorts under utvecklingen.\n" + +#~ msgid "%s is not a directory\n" +#~ msgstr "%s är inte en katalog\n" + +#~ msgid "" +#~ "could not load library \"%s\":\n" +#~ "%s\n" +#~ msgstr "" +#~ "kunde inte ladda bibliotek \"%s\":\n" +#~ "%s\n" + +#~ msgid "------------------\n" +#~ msgstr "------------------\n" + +#~ msgid "----------------\n" +#~ msgstr "----------------\n" + +#~ msgid "Checking for invalid \"line\" user columns" +#~ msgstr "Letar efter ogiltiga användarkolumner av typen \"line\"" + +#~ msgid "Cannot read line %d from %s: %m\n" +#~ msgstr "Kan inte läsa rad %d frÃ¥n %s: %m\n" + +#~ msgid "Cannot open file %s: %m\n" +#~ msgstr "Kan inte öppna fil %s: %m\n" + +#~ msgid "cannot find current directory\n" +#~ msgstr "kan inte hitta aktuell katalog\n" + +#~ msgid "cannot write to log file %s\n" +#~ msgstr "kan inte skriva till loggfil %s\n" + +#~ msgid "unable to read permissions from \"%s\"\n" +#~ msgstr "kunde inte läsa rättigheter frÃ¥n \"%s\"\n" + +#~ msgid "" +#~ "\n" +#~ "Report bugs to .\n" +#~ msgstr "" +#~ "\n" +#~ "Rapportera fel till .\n" diff --git a/src/bin/pg_upgrade/po/tr.po b/src/bin/pg_upgrade/po/tr.po new file mode 100644 index 00000000000..f6b27984409 --- /dev/null +++ b/src/bin/pg_upgrade/po/tr.po @@ -0,0 +1,1668 @@ +# LANGUAGE message translation file for pg_upgrade +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Abdullah GÜLNER , 2017, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_upgrade (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2019-04-02 07:45+0000\n" +"PO-Revision-Date: 2019-04-03 14:47+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: check.c:66 +#, c-format +msgid "" +"Performing Consistency Checks on Old Live Server\n" +"------------------------------------------------\n" +msgstr "" +"Eski Canlı Sunucuda Tutarlılık Testleri GerçekleÅŸtirliyor\n" +"------------------------------------------------\n" + +#: check.c:72 +#, c-format +msgid "" +"Performing Consistency Checks\n" +"-----------------------------\n" +msgstr "" +"Tutarlılık Testleri GerçekleÅŸtiriliyor\n" +"-----------------------------\n" + +#: check.c:166 +#, c-format +msgid "" +"\n" +"*Clusters are compatible*\n" +msgstr "" +"\n" +"*Cluster'lar uyumlu*\n" + +#: check.c:172 +#, c-format +msgid "" +"\n" +"If pg_upgrade fails after this point, you must re-initdb the\n" +"new cluster before continuing.\n" +msgstr "" +"\n" +"EÄŸer pg_upgrade bu noktadan sonra baÅŸarısız olursa,\n" +"devam etmeden önce yeni cluster'da tekrar initdb yapılmalıdır.\n" + +#: check.c:208 +#, c-format +msgid "" +"Optimizer statistics are not transferred by pg_upgrade so,\n" +"once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Eniyileyici (optimizer) istatistikleri pg_upgrade tarafından aktarılmadığından\n" +"yeni sunucuyu baÅŸlattığınızda, %s\n" +"çalıştırmanız önerilir.\n" +"\n" + +#: check.c:213 +#, c-format +msgid "" +"Optimizer statistics and free space information are not transferred\n" +"by pg_upgrade so, once you start the new server, consider running:\n" +" %s\n" +"\n" +msgstr "" +"Eniyileyici (optimizer) istatistikleri ve boÅŸ alan bilgisi pg_upgrade\n" +"tarafından aktarılmadığından, yeni sunucuyu baÅŸlattığınızda \n" +"%s çalıştırmanız önerilir\n" +"\n" + +#: check.c:220 +#, c-format +msgid "" +"Running this script will delete the old cluster's data files:\n" +" %s\n" +msgstr "" +"Bu betiÄŸin (script) çalıştırılması eski cluster'ın veri dosyalarını silecektir:\n" +" %s\n" + +#: check.c:225 +#, c-format +msgid "" +"Could not create a script to delete the old cluster's data files\n" +"because user-defined tablespaces or the new cluster's data directory\n" +"exist in the old cluster directory. The old cluster's contents must\n" +"be deleted manually.\n" +msgstr "" +"Eski kümenin (cluster) veri dosyalarını silecek betik (script) oluÅŸturulamadı;\n" +"çünkü eski kümenin dizininde kullanıcı-tanımlı tablespace'ler veya \n" +"yeni kümenin veri dizini bulunuyor. Eski kümeye ait içerikler\n" +"elle silinmeli.\n" + +#: check.c:235 +#, c-format +msgid "Checking cluster versions" +msgstr "Cluster sürümleri kontrol ediliyor" + +#: check.c:247 +#, c-format +msgid "This utility can only upgrade from PostgreSQL version 8.4 and later.\n" +msgstr "Bu uygulama sadece PostgreSQL 8.4 ve sonraki sürümlerden yükseltme yapabilir.\n" + +#: check.c:251 +#, c-format +msgid "This utility can only upgrade to PostgreSQL version %s.\n" +msgstr "Bu uygulama sadece PostgreSQL'in %s sürümüne yükseltme yapabilir.\n" + +#: check.c:260 +#, c-format +msgid "This utility cannot be used to downgrade to older major PostgreSQL versions.\n" +msgstr "pg-upgrade uygulaması daha eski ana PostgreSQL sürümlerine geçiÅŸ için kullanılamaz.\n" + +#: check.c:265 +#, c-format +msgid "Old cluster data and binary directories are from different major versions.\n" +msgstr "Eski kümenin (cluster) veri ve ikili (binary) dizinleri farklı ana sürümlerden.\n" + +#: check.c:268 +#, c-format +msgid "New cluster data and binary directories are from different major versions.\n" +msgstr "Yeni küme (cluster) veri ve ikili (binary) dizinleri farklı ana (major) sürümlerden.\n" + +#: check.c:285 +#, c-format +msgid "When checking a pre-PG 9.1 live old server, you must specify the old server's port number.\n" +msgstr "PG 9.1 öncesi eski bir canlı sunucu kontrol edildiÄŸinde, eski sunucunun port numarasını belirtmelisiniz.\n" + +#: check.c:289 +#, c-format +msgid "When checking a live server, the old and new port numbers must be different.\n" +msgstr "Canlı bir sunucu kontrol edilirken, eski ve yeni port numaraları farklı olmalı.\n" + +#: check.c:304 +#, c-format +msgid "encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" veritabanı için dil kodlaması eÅŸleÅŸmiyor: eskisi \"%s\", yenisi \"%s\"\n" + +#: check.c:309 +#, c-format +msgid "lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" veritabanı için lc_collate deÄŸerleri eÅŸleÅŸmiyor: eskisi \"%s\", yenisi \"%s\"\n" + +#: check.c:312 +#, c-format +msgid "lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n" +msgstr "\"%s\" veritabanı için lc_ctype deÄŸerleri eÅŸleÅŸmiyor: eskisi \"%s\", yenisi \"%s\"\n" + +#: check.c:385 +#, c-format +msgid "New cluster database \"%s\" is not empty\n" +msgstr "Yeni cluster veritabanı \"%s\" boÅŸ deÄŸil\n" + +#: check.c:432 +#, c-format +msgid "Creating script to analyze new cluster" +msgstr "Yeni kümeyi (cluster) analiz etmek için betik (script) oluÅŸturuluyor " + +#: check.c:446 check.c:574 check.c:838 check.c:949 check.c:1040 function.c:253 +#: option.c:480 version.c:57 version.c:156 version.c:257 version.c:339 +#, c-format +msgid "could not open file \"%s\": %s\n" +msgstr "\"%s\" dosyası açılamadı: %s\n" + +#: check.c:501 check.c:630 +#, c-format +msgid "could not add execute permission to file \"%s\": %s\n" +msgstr "\"%s\" dosyasına çalıştırma (execute) izni eklenemedi: %s\n" + +#: check.c:537 +#, c-format +msgid "" +"\n" +"WARNING: new data directory should not be inside the old data directory, e.g. %s\n" +msgstr "" +"\n" +"UYARI: yeni veri dizini eski veri dizini içinde olmamalı, örn. %s\n" + +#: check.c:561 +#, c-format +msgid "" +"\n" +"WARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n" +msgstr "" +"\n" +"UYARI: kullanıcı-tanımlı tablespace lokasyonları veri dizini içinde olmamalıdır, örn. %s\n" + +#: check.c:571 +#, c-format +msgid "Creating script to delete old cluster" +msgstr "Eski kümeyi (cluster) silmek için betik (script) oluÅŸturuluyor." + +#: check.c:650 +#, c-format +msgid "Checking database user is the install user" +msgstr "Veritabanı kullanıcısının kurulum kullanıcısı olup olmadığı kontrol ediliyor" + +#: check.c:666 +#, c-format +msgid "database user \"%s\" is not the install user\n" +msgstr "Veritabanı kullanıcısı \"%s\" kurulum kullanıcısı deÄŸil\n" + +#: check.c:677 +#, c-format +msgid "could not determine the number of users\n" +msgstr "kullanıcı sayısı belirlenemedi\n" + +#: check.c:685 +#, c-format +msgid "Only the install user can be defined in the new cluster.\n" +msgstr "Yeni kümede (cluster) sadece kurulum kullanıcısı tanımlanabilir\n" + +#: check.c:705 +#, c-format +msgid "Checking database connection settings" +msgstr "Veritabanı baÄŸlantı ayarları kontrol ediliyor" + +#: check.c:727 +#, c-format +msgid "template0 must not allow connections, i.e. its pg_database.datallowconn must be false\n" +msgstr "template0 baÄŸlantıya izin vermemeli, yani pg_database.datallowconn deÄŸeri \"false\" olmalı\n" + +#: check.c:737 +#, c-format +msgid "All non-template0 databases must allow connections, i.e. their pg_database.datallowconn must be true\n" +msgstr "template0 dışındaki tüm veritabanları baÄŸlantıya izin vermeli, yani pg_database.datallowconn deÄŸerleri \"true\" olmalı\n" + +#: check.c:762 +#, c-format +msgid "Checking for prepared transactions" +msgstr "Hazırlanmış iÅŸlemler (prepared transaction) için kontrol gerçekleÅŸtiriliyor" + +#: check.c:771 +#, c-format +msgid "The source cluster contains prepared transactions\n" +msgstr "Kaynak küme (cluster) hazırlanmış iÅŸlemler (prepared transaction) içeriyor\n" + +#: check.c:773 +#, c-format +msgid "The target cluster contains prepared transactions\n" +msgstr "Hedef küme(cluster) hazırlanmış iÅŸlemler içeriyor\n" + +#: check.c:799 +#, c-format +msgid "Checking for contrib/isn with bigint-passing mismatch" +msgstr "bigint-geçirme uyuÅŸmazlığı olan contrib/isn için denetim gerçekleÅŸtiriliyor" + +#: check.c:860 check.c:972 check.c:1063 function.c:268 version.c:179 +#: version.c:280 +#, c-format +msgid "fatal\n" +msgstr "ölümcül (fatal)\n" + +#: check.c:861 +#, c-format +msgid "" +"Your installation contains \"contrib/isn\" functions which rely on the\n" +"bigint data type. Your old and new clusters pass bigint values\n" +"differently so this cluster cannot currently be upgraded. You can\n" +"manually upgrade databases that use \"contrib/isn\" facilities and remove\n" +"\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n" +"the problem functions is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Kurulumunuz bigint veri tipine dayalı \"contrib/isn\" fonksiyonları\n" +"içeriyor. Eski ve yeni kümeleriniz (cluster) bigint deÄŸerlerini farklı\n" +"geçirdiÄŸinden bu küme ÅŸu anda yükseltilemiyor. \"contrib/isn\" imkanlarını\n" +"kullanan veritabanlarını \"contrib/isn\" yi eski kümeden çıkartarak\n" +" elle yükseltebilir ve yükseltmeyi tekrar baÅŸlatabilirsiniz.\n" +"Problemli fonksiyonların bir listesi aÅŸağıdaki dosyadadır:\n" +" %s\n" +"\n" + +#: check.c:893 +#, c-format +msgid "Checking for reg* data types in user tables" +msgstr "Kullanıcı tablolarındaki reg* veri tipleri için kontrol yapılıyor" + +#: check.c:973 +#, c-format +msgid "" +"Your installation contains one of the reg* data types in user tables.\n" +"These data types reference system OIDs that are not preserved by\n" +"pg_upgrade, so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Kurulumunuz kullanıcı tablolarında reg* veri tiplerinden birini kullanıyor.\n" +"Bu veri tipleri pg_upgrade tarafından korunmayan sistem OID'lerine referans\n" +"veriyor, dolayısıyla bu küme ÅŸu anda yükseltilemiyor. Sorunlu tabloları\n" +"çıkartıp yükseltmeyi yeniden baÅŸlatabilirsiniz. Sorunlu sütunların listesi\n" +"aÅŸağıdaki dosyadadır:\n" +" %s\n" +"\n" + +#: check.c:998 +#, c-format +msgid "Checking for incompatible \"jsonb\" data type" +msgstr "Uyumlu olmayan (incompatible) \"jsonb\" veri tipi için kontrol gerçekleÅŸtiriliyor" + +#: check.c:1064 +#, c-format +msgid "" +"Your installation contains the \"jsonb\" data type in user tables.\n" +"The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade. A list\n" +"of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Kullanıcı tablolarınızda \"jsonb\" veri tipi içeren alanlar bulunmaktadır.\n" +"9.4 beta ile birlikte \"jsonb\" iç formatı deÄŸiÅŸtiÄŸinden bu küme (cluster) ÅŸu anda\n" +"yükseltilemiyor. Sorunlu tabloları çıkartarak (remove) yükseltmeyi tekrar \n" +"baÅŸlatabilirsiniz. Problemli sütunların bir listesini ÅŸu dosyada bulabilirsiniz:\n" +"%s\n" + +#: check.c:1085 +#, c-format +msgid "Checking for roles starting with \"pg_\"" +msgstr "\"pg_\" ie baÅŸlayan roller için kontrol gerçekleÅŸtiriliyor" + +#: check.c:1095 +#, c-format +msgid "The source cluster contains roles starting with \"pg_\"\n" +msgstr "Kaynak küme (cluster) \"pg_\" ile baÅŸlayan roller içeriyor\n" + +#: check.c:1097 +#, c-format +msgid "The target cluster contains roles starting with \"pg_\"\n" +msgstr "Hedef küme (cluster) \"pg_\" ile baÅŸlayan roller içeriyor\n" + +#: check.c:1123 +#, c-format +msgid "failed to get the current locale\n" +msgstr "geçerli yerel ayarları (locale) almakta baÅŸarısız olundu\n" + +#: check.c:1132 +#, c-format +msgid "failed to get system locale name for \"%s\"\n" +msgstr "\"%s\" için sistem yerel ayarlarını (locale) almakta baÅŸarısız olundu\n" + +#: check.c:1138 +#, c-format +msgid "failed to restore old locale \"%s\"\n" +msgstr "Eski \"%s\" yerel ayarlarını (locale) geri yüklemekte baÅŸarısız olundu\n" + +#: controldata.c:128 controldata.c:195 +#, c-format +msgid "could not get control data using %s: %s\n" +msgstr "%s kullanılarak kontrol verisi alınamadı: %s\n" + +#: controldata.c:139 +#, c-format +msgid "%d: database cluster state problem\n" +msgstr "%d: veritabanı kümesini durumu ile ilgili sorun\n" + +#: controldata.c:156 +#, c-format +msgid "The source cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Kaynak küme kurtarma (recovery) modunda iken kapatıldı. Yükseltmek için, belgelerde açıklandığı gibi \"rsync\" kullanın ya da birincil (primary) sunucu olarak kapatın.\n" + +#: controldata.c:158 +#, c-format +msgid "The target cluster was shut down while in recovery mode. To upgrade, use \"rsync\" as documented or shut it down as a primary.\n" +msgstr "Hedef küme kurtarma (recovery) modunda iken kapatıldı. Yükseltmek için, belgelerde açıklandığı gibi \"rsync\" kullanın ya da birincil (primary) sunucu olarak kapatın.\n" + +#: controldata.c:163 +#, c-format +msgid "The source cluster was not shut down cleanly.\n" +msgstr "Kaynak küme düzgün bir ÅŸekilde kapatılmamış.\n" + +#: controldata.c:165 +#, c-format +msgid "The target cluster was not shut down cleanly.\n" +msgstr "Hedef küme düzgün bir ÅŸekilde kapatılmamış.\n" + +#: controldata.c:176 +#, c-format +msgid "The source cluster lacks cluster state information:\n" +msgstr "Kaynak kümede (cluster) küme durumu bilgisi eksik:\n" + +#: controldata.c:178 +#, c-format +msgid "The target cluster lacks cluster state information:\n" +msgstr "Hedef kümede (cluster) küme durumu bilgisi eksik:\n" + +#: controldata.c:208 dump.c:51 pg_upgrade.c:333 pg_upgrade.c:370 +#: relfilenode.c:244 util.c:80 +#, c-format +msgid "%s" +msgstr "%s" + +#: controldata.c:215 +#, c-format +msgid "%d: pg_resetwal problem\n" +msgstr "%d: pg_resetwal sorunu\n" + +#: controldata.c:225 controldata.c:235 controldata.c:246 controldata.c:257 +#: controldata.c:268 controldata.c:287 controldata.c:298 controldata.c:309 +#: controldata.c:320 controldata.c:331 controldata.c:342 controldata.c:345 +#: controldata.c:349 controldata.c:359 controldata.c:371 controldata.c:382 +#: controldata.c:393 controldata.c:404 controldata.c:415 controldata.c:426 +#: controldata.c:437 controldata.c:448 controldata.c:459 controldata.c:470 +#: controldata.c:481 +#, c-format +msgid "%d: controldata retrieval problem\n" +msgstr "%d: controldata alma (retrieval) sorunu\n" + +#: controldata.c:546 +#, c-format +msgid "The source cluster lacks some required control information:\n" +msgstr "Kaynak kümede (cluster) bazı gerekli kontrol bilgileri eksik:\n" + +#: controldata.c:549 +#, c-format +msgid "The target cluster lacks some required control information:\n" +msgstr "Hedef kümede (cluster) bazı gerekli kontrol bilgileri eksik:\n" + +#: controldata.c:552 +#, c-format +msgid " checkpoint next XID\n" +msgstr " sonraki XID kontrol noktası (checkpoint)\n" + +#: controldata.c:555 +#, c-format +msgid " latest checkpoint next OID\n" +msgstr " sonraki OID en son kontrol noktası (checkpoint)\n" + +#: controldata.c:558 +#, c-format +msgid " latest checkpoint next MultiXactId\n" +msgstr " sonraki MultiXactId en son kontrol noktası (checkpoint)\n" + +#: controldata.c:562 +#, c-format +msgid " latest checkpoint oldest MultiXactId\n" +msgstr " En eski MultiXactId en son kontrol noktası (checkpoint)\n" + +#: controldata.c:565 +#, c-format +msgid " latest checkpoint next MultiXactOffset\n" +msgstr " sonraki MultiXactOffset en son kontrol noktası\n" + +#: controldata.c:568 +#, c-format +msgid " first WAL segment after reset\n" +msgstr " sıfırlama (reset) sonrası ilk WAL kesimi (segment)\n" + +#: controldata.c:571 +#, c-format +msgid " float8 argument passing method\n" +msgstr " float8 argumanı geçirme yöntemi\n" + +#: controldata.c:574 +#, c-format +msgid " maximum alignment\n" +msgstr " azami hizalanma (max alignment)\n" + +#: controldata.c:577 +#, c-format +msgid " block size\n" +msgstr " blok boyutu (block size)\n" + +#: controldata.c:580 +#, c-format +msgid " large relation segment size\n" +msgstr " büyük iliÅŸki (relation) kesimi (segment) boyutu\n" + +#: controldata.c:583 +#, c-format +msgid " WAL block size\n" +msgstr " WAL blok boyutu (block size)\n" + +#: controldata.c:586 +#, c-format +msgid " WAL segment size\n" +msgstr " WAL kesim boyutu (segment size)\n" + +#: controldata.c:589 +#, c-format +msgid " maximum identifier length\n" +msgstr " azami tanımlayıcı (identifier) uzunluÄŸu\n" + +#: controldata.c:592 +#, c-format +msgid " maximum number of indexed columns\n" +msgstr " azami indeksli sütun sayısı\n" + +#: controldata.c:595 +#, c-format +msgid " maximum TOAST chunk size\n" +msgstr " azami TOAST yığın (chunk) boyutu\n" + +#: controldata.c:599 +#, c-format +msgid " large-object chunk size\n" +msgstr " büyük-nesne yığın (chunk) boyutu\n" + +#: controldata.c:602 +#, c-format +msgid " dates/times are integers?\n" +msgstr " tarih/saat deÄŸerleri tamsayı mı?\n" + +#: controldata.c:606 +#, c-format +msgid " data checksum version\n" +msgstr " veri saÄŸlama (checksum) sürümü\n" + +#: controldata.c:608 +#, c-format +msgid "Cannot continue without required control information, terminating\n" +msgstr "Gerekli kontrol bilgisi olmadan devam edilemez, sonlandırılıyor\n" + +#: controldata.c:623 +#, c-format +msgid "" +"old and new pg_controldata alignments are invalid or do not match\n" +"Likely one cluster is a 32-bit install, the other 64-bit\n" +msgstr "" +"eski ve yeni pg_controldata hizalamaları (alignment) ya geçersiz ya da eÅŸleÅŸmiyor\n" +"Muhtemelen bir küme 32-bit diÄŸeri 64-bit kurulumları\n" + +#: controldata.c:627 +#, c-format +msgid "old and new pg_controldata block sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata hizalamaları (alignment) ya geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:630 +#, c-format +msgid "old and new pg_controldata maximum relation segment sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata azami iliÅŸki (relation) kesim (segment) boyutları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:633 +#, c-format +msgid "old and new pg_controldata WAL block sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata WAL blok boyutları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:636 +#, c-format +msgid "old and new pg_controldata WAL segment sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata WAL kesim (segment) boyutları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:639 +#, c-format +msgid "old and new pg_controldata maximum identifier lengths are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata azami tanımlayıcı uzunlukları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:642 +#, c-format +msgid "old and new pg_controldata maximum indexed columns are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata azami indeksli sütunları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:645 +#, c-format +msgid "old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata azami TOAST yığın (chunk) boyutları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:650 +#, c-format +msgid "old and new pg_controldata large-object chunk sizes are invalid or do not match\n" +msgstr "eski ve yeni pg_controldata büyük-nesne (large-obj.) yığın (chunk) boyutları geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:653 +#, c-format +msgid "old and new pg_controldata date/time storage types do not match\n" +msgstr "eski ve yeni pg_controldata tarih/saat saklama tipleri geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:666 +#, c-format +msgid "old cluster does not use data checksums but the new one does\n" +msgstr "eski küme veri saÄŸlamaları (checksum) kullanmıyorken yenisi kullanıyor\n" + +#: controldata.c:669 +#, c-format +msgid "old cluster uses data checksums but the new one does not\n" +msgstr "eski küme veri saÄŸlamaları (checksum) kullanıyorken yenisi kullanmıyor\n" + +#: controldata.c:671 +#, c-format +msgid "old and new cluster pg_controldata checksum versions do not match\n" +msgstr "eski ve yeni küme (cluster) pg_controldata saÄŸlama sürümleri geçersiz ya da eÅŸleÅŸmiyor\n" + +#: controldata.c:682 +#, c-format +msgid "Adding \".old\" suffix to old global/pg_control" +msgstr "eski global/pg_control'e \".old\" soneki ekleniyor" + +#: controldata.c:687 +#, c-format +msgid "Unable to rename %s to %s.\n" +msgstr "%s ismi %s'ye deÄŸiÅŸtirilemiyor.\n" + +#: controldata.c:690 +#, c-format +msgid "" +"\n" +"If you want to start the old cluster, you will need to remove\n" +"the \".old\" suffix from %s/global/pg_control.old.\n" +"Because \"link\" mode was used, the old cluster cannot be safely\n" +"started once the new cluster has been started.\n" +"\n" +msgstr "" +"\n" +"Eski kümeyi (cluster) baÅŸlatmak istiyorsanız, \".old\" sonekini\n" +"%s/global/pg_control.old 'dan çıkartmanız gerekecektir.\n" +"\"link\" kipi (mode) kullanıldığından, bir kere yeni küme baÅŸlatıldığında\n" +"eski küme güvenle baÅŸlatılamaz.\n" +"\n" + +#: dump.c:22 +#, c-format +msgid "Creating dump of global objects" +msgstr "Global nesnelerin dökümü (dump) oluÅŸturuluyor" + +#: dump.c:33 +#, c-format +msgid "Creating dump of database schemas\n" +msgstr "Veritabanı ÅŸemalarının dökümü (dump) oluÅŸturuluyor\n" + +#: exec.c:44 +#, c-format +msgid "could not get pg_ctl version data using %s: %s\n" +msgstr "%s kullanılarak pg_ctl sürüm verisi alınamadı: %s\n" + +#: exec.c:50 +#, c-format +msgid "could not get pg_ctl version output from %s\n" +msgstr "%s den pg_ctl sürüm çıktısı alınamadı\n" + +#: exec.c:104 exec.c:108 +#, c-format +msgid "command too long\n" +msgstr "çok uzun komut\n" + +#: exec.c:110 util.c:38 util.c:226 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: exec.c:149 exec.c:204 option.c:101 option.c:217 +#, c-format +msgid "could not write to log file \"%s\"\n" +msgstr "\"%s\" günlük (log) dosyasına yazılamadı\n" + +#: exec.c:178 +#, c-format +msgid "" +"\n" +"*failure*" +msgstr "" +"\n" +"*hata*" + +#: exec.c:181 +#, c-format +msgid "There were problems executing \"%s\"\n" +msgstr "\"%s\"nin çalıştırılmasında sorunlar oluÅŸtu\n" + +#: exec.c:184 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" or \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Hatanın muhtemel sebebi için \"%s\" veya \n" +"\"%s\"nin son bir kaç satırına bakınız.\n" + +#: exec.c:189 +#, c-format +msgid "" +"Consult the last few lines of \"%s\" for\n" +"the probable cause of the failure.\n" +msgstr "" +"Hatanın muhtemel sebebi için \"%s\" nin\n" +"son bir kaç satırına bakınız.\n" + +#: exec.c:230 +#, c-format +msgid "could not open file \"%s\" for reading: %s\n" +msgstr "\"%s\" dosyası okuma için açılamadı: %s\n" + +#: exec.c:257 +#, c-format +msgid "You must have read and write access in the current directory.\n" +msgstr "Geçerli dizinde okuma ve yazma eriÅŸiminiz olmalı.\n" + +#: exec.c:310 exec.c:372 exec.c:427 +#, c-format +msgid "check for \"%s\" failed: %s\n" +msgstr "\"%s\" kontrolü aksadı: %s\n" + +#: exec.c:313 exec.c:375 +#, c-format +msgid "\"%s\" is not a directory\n" +msgstr "\"%s\" bir dizin deÄŸil\n" + +#: exec.c:430 +#, c-format +msgid "check for \"%s\" failed: not a regular file\n" +msgstr "" +"\"%s\" kontrolü hata verdi: normal bir dosya deÄŸil\n" +" \n" + +#: exec.c:442 +#, c-format +msgid "check for \"%s\" failed: cannot read file (permission denied)\n" +msgstr "\"%s\" kontrolü hata verdi: dosya okunamıyor (izin yok)\n" + +#: exec.c:450 +#, c-format +msgid "check for \"%s\" failed: cannot execute (permission denied)\n" +msgstr "\"%s\" kontrolü hata verdi: çalıştırılamıyor (izin yok)\n" + +#: file.c:44 file.c:147 +#, c-format +msgid "error while copying relation \"%s.%s\": could not open file \"%s\": %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyası açılamadı: %s\n" + +#: file.c:49 file.c:156 +#, c-format +msgid "error while copying relation \"%s.%s\": could not create file \"%s\": %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyası oluÅŸturulamadı: %s\n" + +#: file.c:63 file.c:180 +#, c-format +msgid "error while copying relation \"%s.%s\": could not read file \"%s\": %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyası okunamadı: %s\n" + +#: file.c:75 file.c:258 +#, c-format +msgid "error while copying relation \"%s.%s\": could not write file \"%s\": %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyasına yazılamadı: %s\n" + +#: file.c:89 +#, c-format +msgid "error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu (\"%s\" \"%s\"ye): %s\n" + +#: file.c:108 +#, c-format +msgid "error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "\"%s.%s\" iliÅŸkisi için baÄŸlantı oluÅŸturulurken hata oluÅŸtu (\"%s\" \"%s\"ye): %s\n" + +#: file.c:151 +#, c-format +msgid "error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyasının durumu görüntülenemiyor (stat) : %s\n" + +#: file.c:183 +#, c-format +msgid "error while copying relation \"%s.%s\": partial page found in file \"%s\"\n" +msgstr "\"%s.%s\" iliÅŸkisi (relation) kopyalanırken hata oluÅŸtu: \"%s\" dosyasında kısmi (partial) sayfa (page) bulundu\n" + +#: file.c:284 +#, c-format +msgid "" +"could not create hard link between old and new data directories: %s\n" +"In link mode the old and new data directories must be on the same file system.\n" +msgstr "" +"eski ve yeni veri dizinleri arasında sabit baÄŸlantı (hard link) oluÅŸturulamadı: %s\n" +"BaÄŸlantı kipinde eski ve yeni veri dizinleri aynı dosya sisteminde olmalı.\n" + +#: function.c:110 +#, c-format +msgid "" +"\n" +"The old cluster has a \"plpython_call_handler\" function defined\n" +"in the \"public\" schema which is a duplicate of the one defined\n" +"in the \"pg_catalog\" schema. You can confirm this by executing\n" +"in psql:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"The \"public\" schema version of this function was created by a\n" +"pre-8.1 install of plpython, and must be removed for pg_upgrade\n" +"to complete because it references a now-obsolete \"plpython\"\n" +"shared object file. You can remove the \"public\" schema version\n" +"of this function by running the following command:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" +"in each affected database:\n" +"\n" +msgstr "" +"\n" +"Eski kümenin \"public\" ÅŸemasında tanımlı bir \"plpython_call_handler\"\n" +"fonksiyonu var ki bunun bir kopyası da \"pg_catalog\" ÅŸemasında da tanımlı.\n" +"Bunu teyit etmek için psql'de ÅŸunu çalıştırabilirsiniz:\n" +"\n" +" \\df *.plpython_call_handler\n" +"\n" +"Bu fonksiyonun \"public\" ÅŸemasındaki sürümü plpython'un 8.1 öncesi bir\n" +"kurulumu tarafından oluÅŸturulmuÅŸ, ve eski \"plpython\" paylaşımlı nesne \n" +"dosyasına referans verdiÄŸi için pg_upgrade'in tamamlanması için \n" +"kaldırılmalıdır. Bu fonksiyonun \"public\" ÅŸemasınaki sürümünü etkilenen\n" +"bütün veritabanlarında aÅŸağıdaki komutu çalıştırarak kaldırabilirsiniz:\n" +"\n" +" DROP FUNCTION public.plpython_call_handler()\n" +"\n" + +#: function.c:128 +#, c-format +msgid " %s\n" +msgstr " %s\n" + +#: function.c:138 +#, c-format +msgid "Remove the problem functions from the old cluster to continue.\n" +msgstr "Devam etmek için problemli fonksiyonları çıkartınız (remove).\n" + +#: function.c:211 +#, c-format +msgid "Checking for presence of required libraries" +msgstr "Gereken kütüphanelerin varlığı kontrol ediliyor" + +#: function.c:255 +#, c-format +msgid "could not load library \"%s\": %s" +msgstr "\"%s\" kütüphanesi yüklenemedi: %s" + +#: function.c:269 +#, c-format +msgid "" +"Your installation references loadable libraries that are missing from the\n" +"new installation. You can add these libraries to the new installation,\n" +"or remove the functions using them from the old installation. A list of\n" +"problem libraries is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Eski kurulumunuz yenisinde eksik olan yüklenebilir kütüphanelere referans\n" +"veriyor. Bu kütüphaneleri yeni kuruluma ekleyebilir, ya da bunları kullanan\n" +"fonksiyonları eski kurulumdan çıkarabilirsiniz. Sorunlu kütüphanelerin bir\n" +"listesi aÅŸağıdaki dosyadadır:\n" +" %s\n" +"\n" +" \n" + +#: info.c:133 +#, c-format +msgid "Relation names for OID %u in database \"%s\" do not match: old name \"%s.%s\", new name \"%s.%s\"\n" +msgstr "%u OID'si için \"%s\" veritabanındaki iliÅŸki isimleri eÅŸleÅŸmiyor: eski isim \"%s.%s\", yeni isim \"%s.%s\"\n" + +#: info.c:153 +#, c-format +msgid "Failed to match up old and new tables in database \"%s\"\n" +msgstr "\"%s\" veritabanında eski ve yeni tabloların eÅŸleÅŸtirilmesi baÅŸarısız oldu\n" + +#: info.c:242 +#, c-format +msgid " which is an index on \"%s.%s\"" +msgstr " \"%s.%s\" üzerinde bir indeks " + +#: info.c:252 +#, c-format +msgid " which is an index on OID %u" +msgstr " %u OID'li nesne üzerinde bir indeks" + +#: info.c:264 +#, c-format +msgid " which is the TOAST table for \"%s.%s\"" +msgstr " \"%s.%s\" için TOAST tablosu" + +#: info.c:272 +#, c-format +msgid " which is the TOAST table for OID %u" +msgstr " %u OID'li nesne için TOAST tablosu" + +#: info.c:276 +#, c-format +msgid "No match found in old cluster for new relation with OID %u in database \"%s\": %s\n" +msgstr "%u OID li yeni iliÅŸki (relation) için eski kümede (cluster) karşılık bulunamadı (veritabanı: \"%s): %s\n" + +#: info.c:279 +#, c-format +msgid "No match found in new cluster for old relation with OID %u in database \"%s\": %s\n" +msgstr "%u OID li eski iliÅŸki (relation) için yeni kümede (cluster) karşılık bulunamadı (veritabanı: \"%s): %s\n" + +#: info.c:291 +#, c-format +msgid "mappings for database \"%s\":\n" +msgstr "\"%s\" veritabanı için eÅŸleÅŸtrimeler:\n" + +#: info.c:294 +#, c-format +msgid "%s.%s: %u to %u\n" +msgstr "%s.%s: %u yu %uya\n" + +#: info.c:299 info.c:638 +#, c-format +msgid "" +"\n" +"\n" +msgstr "" +"\n" +"\n" + +#: info.c:324 +#, c-format +msgid "" +"\n" +"source databases:\n" +msgstr "" +"\n" +"kaynak veritabanları:\n" + +#: info.c:326 +#, c-format +msgid "" +"\n" +"target databases:\n" +msgstr "" +"\n" +"hedef veritabanları:\n" + +#: info.c:636 +#, c-format +msgid "Database: %s\n" +msgstr "Veritabanı: %s\n" + +#: info.c:649 +#, c-format +msgid "relname: %s.%s: reloid: %u reltblspace: %s\n" +msgstr "relname: %s.%s: reloid: %u reltblspace: %s\n" + +#: option.c:98 +#, c-format +msgid "%s: cannot be run as root\n" +msgstr "%s: root kullanıcısyla çalıştırılamaz\n" + +#: option.c:172 +#, c-format +msgid "invalid old port number\n" +msgstr "geçersiz eski port numarası\n" + +#: option.c:180 +#, c-format +msgid "invalid new port number\n" +msgstr "geçersiz yeni port numarası\n" + +#: option.c:202 +#, c-format +msgid "Running in verbose mode\n" +msgstr "Verbose kipte çalışıyor\n" + +#: option.c:207 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#: option.c:242 +msgid "old cluster binaries reside" +msgstr "eski küme ikili dosyaları bulunmakta" + +#: option.c:244 +msgid "new cluster binaries reside" +msgstr "yeni küme ikili dosyaları bulunmakta" + +#: option.c:246 +msgid "old cluster data resides" +msgstr "eski küme verisi bulunmakta" + +#: option.c:248 +msgid "new cluster data resides" +msgstr "yeni küme verisi bulunmakta" + +#: option.c:265 option.c:462 +#, c-format +msgid "could not determine current directory\n" +msgstr "geçerli dizin belirlenemedi\n" + +#: option.c:268 +#, c-format +msgid "cannot run pg_upgrade from inside the new cluster data directory on Windows\n" +msgstr "pg_upgrade, Windows üzerindeki yeni küme (cluster) veri dizini içerisinden çalıştırılamıyor\n" + +#: option.c:277 +#, c-format +msgid "" +"pg_upgrade upgrades a PostgreSQL cluster to a different major version.\n" +"\n" +msgstr "" +"pg_upgrade bir PostgreSQL kümesini (cluster) farklı bir ana sürüme yükseltir.\n" +"\n" + +#: option.c:278 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: option.c:279 +#, c-format +msgid "" +" pg_upgrade [OPTION]...\n" +"\n" +msgstr "" +" pg_upgrade [SEÇENEK]...\n" +"\n" + +#: option.c:280 +#, c-format +msgid "Options:\n" +msgstr "Seçenekler:\n" + +#: option.c:281 +#, c-format +msgid " -b, --old-bindir=BINDIR old cluster executable directory\n" +msgstr " -b, --old-bindir=BINDIR eski küme (cluster) için çalıştırılabilir (executable) dizini\n" + +#: option.c:282 +#, c-format +msgid " -B, --new-bindir=BINDIR new cluster executable directory\n" +msgstr " -B, --new-bindir=BINDIR yeni küme (cluster) çalıştırılabilir (executable) dizini\n" + +#: option.c:283 +#, c-format +msgid " -c, --check check clusters only, don't change any data\n" +msgstr " -c, --check sadece kümeleri (cluster) kontrol et, veri deÄŸiÅŸikliÄŸi yapma\n" + +#: option.c:284 +#, c-format +msgid " -d, --old-datadir=DATADIR old cluster data directory\n" +msgstr " -d, --old-datadir=DATADIR eski küme (cluster) veri dizini\n" + +#: option.c:285 +#, c-format +msgid " -D, --new-datadir=DATADIR new cluster data directory\n" +msgstr " -D, --new-datadir=DATADIR yeni küme (cluster) veri dizini\n" + +#: option.c:286 +#, c-format +msgid " -j, --jobs number of simultaneous processes or threads to use\n" +msgstr " -j, --jobs kullanılacak eÅŸzamanlı süreç veya iÅŸ parçacığı (thread) sayısı\n" + +#: option.c:287 +#, c-format +msgid " -k, --link link instead of copying files to new cluster\n" +msgstr " -k, --link dosyaları yeni kümeye (cluster) kopyalama yerine baÄŸlantılandır\n" + +#: option.c:288 +#, c-format +msgid " -o, --old-options=OPTIONS old cluster options to pass to the server\n" +msgstr " -o, --old-options=OPTIONS sunucuya geçirilecek eski küme (cluster) seçenekleri\n" + +#: option.c:289 +#, c-format +msgid " -O, --new-options=OPTIONS new cluster options to pass to the server\n" +msgstr " -O, --ne-options=OPTIONS sunucuya geçirilecek yeni küme (cluster) seçenekleri\n" + +#: option.c:290 +#, c-format +msgid " -p, --old-port=PORT old cluster port number (default %d)\n" +msgstr " -p, --old-port=PORT eski küme port numarası (varsayılan %d)\n" + +#: option.c:291 +#, c-format +msgid " -P, --new-port=PORT new cluster port number (default %d)\n" +msgstr " -P, --new-port=PORT yeni küme port numarası (varsayılan %d)\n" + +#: option.c:292 +#, c-format +msgid " -r, --retain retain SQL and log files after success\n" +msgstr " -r, --retain baÅŸarılı iÅŸlem sonrası SQL ve log dosyalarını tut\n" + +#: option.c:293 +#, c-format +msgid " -U, --username=NAME cluster superuser (default \"%s\")\n" +msgstr "" +" -U, --username=NAME küme (cluster) superuser'ı (varsayılan \"%s\")\n" +" \n" + +#: option.c:294 +#, c-format +msgid " -v, --verbose enable verbose internal logging\n" +msgstr " -v, --verbose açıklamalı (verbose) dahili loglamayı etkinleÅŸtir\n" + +#: option.c:295 +#, c-format +msgid " -V, --version display version information, then exit\n" +msgstr " -V, --version sürüm bilgisini görüntüle, sonrasında çık\n" + +#: option.c:296 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonrasında çık\n" + +#: option.c:297 +#, c-format +msgid "" +"\n" +"Before running pg_upgrade you must:\n" +" create a new database cluster (using the new version of initdb)\n" +" shutdown the postmaster servicing the old cluster\n" +" shutdown the postmaster servicing the new cluster\n" +msgstr "" +"\n" +"pg_upgrade 'i çalıştırmadan önce yapılması gerekenler:\n" +" (initdb'nin yeni sürümünü kullanarak) yeni bir veritabanı kümesi (cluster) oluÅŸturmak\n" +" eski kümeye hizmet veren postmaster'ı kapatmak\n" +" yeni kümeye hizmet veren postmaster'ı kapatmak\n" + +#: option.c:302 +#, c-format +msgid "" +"\n" +"When you run pg_upgrade, you must provide the following information:\n" +" the data directory for the old cluster (-d DATADIR)\n" +" the data directory for the new cluster (-D DATADIR)\n" +" the \"bin\" directory for the old version (-b BINDIR)\n" +" the \"bin\" directory for the new version (-B BINDIR)\n" +msgstr "" +"\n" +"pg_upgrade çalıştırdığınızda, aÅŸağıdaki bilgileri saÄŸlamalısınız:\n" +" eski küme için veri dizini (-d DATADIR)\n" +" yeni küme için veri dizini (-D DATADIR)\n" +" eski sürüm için \"bin\" dizini (-b BINDIR)\n" +" yeni sürüm için \"bin\" dizini (-B BINDIR)\n" + +#: option.c:308 +#, c-format +msgid "" +"\n" +"For example:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"or\n" +msgstr "" +"\n" +"Örnek:\n" +" pg_upgrade -d oldCluster/data -D newCluster/data -b oldCluster/bin -B newCluster/bin\n" +"veya\n" +"\n" +"\n" + +#: option.c:313 +#, c-format +msgid "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" +msgstr "" +" $ export PGDATAOLD=oldCluster/data\n" +" $ export PGDATANEW=newCluster/data\n" +" $ export PGBINOLD=oldCluster/bin\n" +" $ export PGBINNEW=newCluster/bin\n" +" $ pg_upgrade\n" + +#: option.c:319 +#, c-format +msgid "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" +msgstr "" +" C:\\> set PGDATAOLD=oldCluster/data\n" +" C:\\> set PGDATANEW=newCluster/data\n" +" C:\\> set PGBINOLD=oldCluster/bin\n" +" C:\\> set PGBINNEW=newCluster/bin\n" +" C:\\> pg_upgrade\n" + +#: option.c:325 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: option.c:358 +#, c-format +msgid "" +"You must identify the directory where the %s.\n" +"Please use the %s command-line option or the %s environment variable.\n" +msgstr "" +"%s'nin olduÄŸu dizini belirtmelisiniz.\n" +"Lütfen %s komut-satırı seçeneÄŸini ya da %s ortam deÄŸiÅŸkenini kullanınız.\n" + +#: option.c:409 +#, c-format +msgid "Finding the real data directory for the source cluster" +msgstr "Kaynak küme (cluster) için gerçek veri dizini bulunuyor" + +#: option.c:411 +#, c-format +msgid "Finding the real data directory for the target cluster" +msgstr "Hedef küme (cluster) için gerçek veri dizini bulunuyor" + +#: option.c:423 +#, c-format +msgid "could not get data directory using %s: %s\n" +msgstr "%s kullanılarak veri dizini alınamadı: %s\n" + +#: option.c:488 +#, c-format +msgid "could not read line %d from file \"%s\": %s\n" +msgstr "%d satırı, \"%s\" dosyasından okunamadı: %s\n" + +#: option.c:506 +#, c-format +msgid "user-supplied old port number %hu corrected to %hu\n" +msgstr "kullanıcı tarafından saÄŸlanan eski port numarası%hu %hu olarak düzeltildi\n" + +#: parallel.c:128 parallel.c:241 +#, c-format +msgid "could not create worker process: %s\n" +msgstr "işçi süreci yaratılamadı: %s\n" + +#: parallel.c:147 parallel.c:262 +#, c-format +msgid "could not create worker thread: %s\n" +msgstr "işçi threadi yaratılamadı: %s\n" + +#: parallel.c:305 +#, c-format +msgid "waitpid() failed: %s\n" +msgstr "waitpid() baÅŸarısız oldu: %s\n" + +#: parallel.c:309 +#, c-format +msgid "child process exited abnormally: status %d\n" +msgstr "alt süreç (child process) olaÄŸan dışı olarak sonlandı: durum %d\n" + +#: parallel.c:324 +#, c-format +msgid "child worker exited abnormally: %s\n" +msgstr "Alt işçi (child worker) olaÄŸan dışı olarak sonlandı: %s\n" + +#: pg_upgrade.c:106 +#, c-format +msgid "could not read permissions of directory \"%s\": %s\n" +msgstr "\"%s\" dizininin eriÅŸim hakları okunamıyor: %s\n" + +#: pg_upgrade.c:123 +#, c-format +msgid "" +"\n" +"Performing Upgrade\n" +"------------------\n" +msgstr "" +"\n" +"Yükseltme (upgrade) gerçekleÅŸtiriliyor\n" +"----------------------------------\n" + +#: pg_upgrade.c:166 +#, c-format +msgid "Setting next OID for new cluster" +msgstr "Yeni küme (cluster) için sonraki OID belirleniyor" + +#: pg_upgrade.c:173 +#, c-format +msgid "Sync data directory to disk" +msgstr "Veri dizinini diske eÅŸzamanla (sync)" + +#: pg_upgrade.c:185 +#, c-format +msgid "" +"\n" +"Upgrade Complete\n" +"----------------\n" +msgstr "" +"\n" +"Yükseltme (upgrade) tamamlandı\n" +"----------------------------\n" + +#: pg_upgrade.c:231 +#, c-format +msgid "" +"There seems to be a postmaster servicing the old cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Eski kümeye (cluster) hizmet veren bir postmaster var görünüyor.\n" +"Lütfen o postmaster'ı kapatıp tekrar deneyin.\n" + +#: pg_upgrade.c:244 +#, c-format +msgid "" +"There seems to be a postmaster servicing the new cluster.\n" +"Please shutdown that postmaster and try again.\n" +msgstr "" +"Yeni kümeye (cluster) hizmet veren bir postmaster var görünüyor.\n" +"Lütfen o postmaster'ı kapatıp tekrar deneyin.\n" + +#: pg_upgrade.c:250 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: çalıştırılabilir dosya bulunamadı\n" + +#: pg_upgrade.c:267 +#, c-format +msgid "Analyzing all rows in the new cluster" +msgstr "Yeni cluster daki tüm satırlar (row) analiz ediliyor." + +#: pg_upgrade.c:280 +#, c-format +msgid "Freezing all rows in the new cluster" +msgstr "Yeni cluster daki tüm satırlar donduruluyor." + +#: pg_upgrade.c:300 +#, c-format +msgid "Restoring global objects in the new cluster" +msgstr "Yeni kümede (cluster) global objeler geri yükleniyor (restore)" + +#: pg_upgrade.c:315 +#, c-format +msgid "Restoring database schemas in the new cluster\n" +msgstr "Yeni kümede (cluster) veritabanı ÅŸemaları geri yükleniyor\n" + +#: pg_upgrade.c:421 +#, c-format +msgid "Deleting files from new %s" +msgstr "yeni %s deki dosyalar siliniyor" + +#: pg_upgrade.c:425 +#, c-format +msgid "could not delete directory \"%s\"\n" +msgstr "%s dizini silinemedi\n" + +#: pg_upgrade.c:444 +#, c-format +msgid "Copying old %s to new server" +msgstr "Eski %s yeni sunucuya kopyalanıyor" + +#: pg_upgrade.c:471 +#, c-format +msgid "Setting next transaction ID and epoch for new cluster" +msgstr "Yeni küme (cluster) için sonraki iÅŸlem (transaction) ID ve dönem deÄŸeri belirleniyor." + +#: pg_upgrade.c:501 +#, c-format +msgid "Setting next multixact ID and offset for new cluster" +msgstr "Yeni kümede (cluster) sonraki multixact ID deÄŸeri ve göreli konum deÄŸeri (offset) belirleniyor" + +#: pg_upgrade.c:525 +#, c-format +msgid "Setting oldest multixact ID in new cluster" +msgstr "Yeni kümede (cluster) en eski multixact ID deÄŸeri belirleniyor" + +#: pg_upgrade.c:545 +#, c-format +msgid "Resetting WAL archives" +msgstr "WAL arÅŸivleri sıfırlanıyor (reset)" + +#: pg_upgrade.c:588 +#, c-format +msgid "Setting frozenxid and minmxid counters in new cluster" +msgstr "Yeni kümede (cluster) frozenxid ve minmxid sayaçları belirleniyor" + +#: pg_upgrade.c:590 +#, c-format +msgid "Setting minmxid counter in new cluster" +msgstr "Yeni kümede (cluster) minmxid sayacı belirleniyor" + +#: relfilenode.c:34 +#, c-format +msgid "Linking user relation files\n" +msgstr "Kullanıcı iliÅŸki dosyaları baÄŸlantılanıyor\n" + +#: relfilenode.c:36 +#, c-format +msgid "Copying user relation files\n" +msgstr "Kullanıcı iliÅŸki dosyaları kopyalanıyor\n" + +#: relfilenode.c:110 +#, c-format +msgid "old database \"%s\" not found in the new cluster\n" +msgstr "eski veritabanı \"%s\" yeni kümede (cluster) bulunmuyor\n" + +#: relfilenode.c:231 +#, c-format +msgid "error while checking for file existence \"%s.%s\" (\"%s\" to \"%s\"): %s\n" +msgstr "dosya varlığını kontrol sırasında hata oluÅŸtu \"%s.%s\" (\"%s\"yi \"%s\"ye): %s\n" + +#: relfilenode.c:249 +#, c-format +msgid "rewriting \"%s\" to \"%s\"\n" +msgstr "\"%s\", \"%s\"ye yeniden yazılıyor\n" + +#: relfilenode.c:255 +#, c-format +msgid "copying \"%s\" to \"%s\"\n" +msgstr "\"%s\", \"%s\"ye kopyalanıyor\n" + +#: relfilenode.c:261 +#, c-format +msgid "linking \"%s\" to \"%s\"\n" +msgstr "\"%s\", \"%s\" ye baÄŸlantılanıyor\n" + +#: server.c:34 +#, c-format +msgid "connection to database failed: %s" +msgstr "veritabanına baÄŸlantı baÅŸarısız oldu: %s" + +#: server.c:40 server.c:142 util.c:136 util.c:166 +#, c-format +msgid "Failure, exiting\n" +msgstr "BaÅŸarısız, çıkılıyor\n" + +#: server.c:132 +#, c-format +msgid "executing: %s\n" +msgstr "çalıştırılıyor: %s\n" + +#: server.c:138 +#, c-format +msgid "" +"SQL command failed\n" +"%s\n" +"%s" +msgstr "" +"SQL komutu çalıştırılamadı\n" +"%s\n" +"%s" + +#: server.c:168 +#, c-format +msgid "could not open version file: %s\n" +msgstr "sürüm dosyası açılamadı: %s\n" + +#: server.c:172 +#, c-format +msgid "could not parse PG_VERSION file from %s\n" +msgstr "PG_VERSION dosyası %s den ayrıştırılamadı (parse)\n" + +#: server.c:295 +#, c-format +msgid "" +"\n" +"connection to database failed: %s" +msgstr "" +"\n" +"veritabanına baÄŸlantı baÅŸarısız oldu: %s" + +#: server.c:300 +#, c-format +msgid "" +"could not connect to source postmaster started with the command:\n" +"%s\n" +msgstr "" +"aÅŸağıdaki komutla baÅŸlatılan kaynak postmaster'a baÄŸlanılamadı:\n" +"%s\n" + +#: server.c:304 +#, c-format +msgid "" +"could not connect to target postmaster started with the command:\n" +"%s\n" +msgstr "" +"aÅŸağıdaki komutla baÅŸlatılan hedef postmaster'a baÄŸlanılamadı:\n" +"%s\n" + +#: server.c:318 +#, c-format +msgid "pg_ctl failed to start the source server, or connection failed\n" +msgstr "pg_ctl kaynak sunucuyu baÅŸlatmakta baÅŸarısız oldu, ya da baÄŸlantı baÅŸarısız\n" + +#: server.c:320 +#, c-format +msgid "pg_ctl failed to start the target server, or connection failed\n" +msgstr "pg_ctl hedef sunucuyu baÅŸlatmakta baÅŸarısız oldu, ya da baÄŸlantı baÅŸarısız\n" + +#: server.c:365 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: server.c:378 +#, c-format +msgid "libpq environment variable %s has a non-local server value: %s\n" +msgstr "%s libpq ortam deÄŸiÅŸkeni yerel olmayan (non-local) bir sunucu deÄŸerine sahip: %s\n" + +#: tablespace.c:28 +#, c-format +msgid "" +"Cannot upgrade to/from the same system catalog version when\n" +"using tablespaces.\n" +msgstr "" +"Tablespace'ler kullanıldığında aynı sistem katalog sürümüne/sürümünden\n" +"yükseltme yapılamaz.\n" + +#: tablespace.c:87 +#, c-format +msgid "tablespace directory \"%s\" does not exist\n" +msgstr "tablespace için \"%s\" dizini mevcut deÄŸil\n" + +#: tablespace.c:91 +#, c-format +msgid "could not stat tablespace directory \"%s\": %s\n" +msgstr "\"%s\" tablesapace dizininin durumu görüntülenemedi (stat): %s\n" + +#: tablespace.c:96 +#, c-format +msgid "tablespace path \"%s\" is not a directory\n" +msgstr "tablespace için verilen \"%s\" yolu bir dizin deÄŸil\n" + +#: util.c:50 +#, c-format +msgid " " +msgstr " " + +#: util.c:83 +#, c-format +msgid "%-*s" +msgstr "%-*s" + +#: util.c:175 +#, c-format +msgid "ok" +msgstr "tamam" + +#: version.c:32 +#, c-format +msgid "Checking for large objects" +msgstr "Büyük nesneler (large objects) için kontrol yapılıyor" + +#: version.c:80 version.c:382 +#, c-format +msgid "warning" +msgstr "uyarı" + +#: version.c:82 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table. After upgrading, you will be\n" +"given a command to populate the pg_largeobject_metadata table with\n" +"default permissions.\n" +"\n" +msgstr "" +"\n" +"Kurulumunuzda büyük nesneler mevcut. Yeni veritabanının\n" +"ilave bir büyük nesne yetkilendirme tablosu var. Yükseltme sonrası,\n" +"size pg_largeobjet_metadata tablosunu varsayılan yetkilerle\n" +" doldurmak için bir komut verilecek.\n" +"\n" +" \n" + +#: version.c:88 +#, c-format +msgid "" +"\n" +"Your installation contains large objects. The new database has an\n" +"additional large object permission table, so default permissions must be\n" +"defined for all large objects. The file\n" +" %s\n" +"when executed by psql by the database superuser will set the default\n" +"permissions.\n" +"\n" +msgstr "" +"\n" +"Kurulumunuzda büyük nesneler mevcut. Yeni veritabanının\n" +"ilave bir büyük nesne yetkilendirme tablosu var, yani bütün büyük\n" +"nesneler için varsayılan yetkiler tanımlanmalı. AÅŸağıdaki dosya:\n" +" %s\n" +"psql'de veritabanı superuser'ı tarafından çalıştırıldığında varsayılan yetkileri ayarlayacak.\n" +"\n" +"\n" +"\n" + +#: version.c:118 +#, c-format +msgid "Checking for incompatible \"line\" data type" +msgstr "Uyumlu olmayan \"line\" veri tipi için kontrol yapılıyor" + +#: version.c:180 +#, c-format +msgid "" +"Your installation contains the \"line\" data type in user tables. This\n" +"data type changed its internal and input/output format between your old\n" +"and new clusters so this cluster cannot currently be upgraded. You can\n" +"remove the problem tables and restart the upgrade. A list of the problem\n" +"columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Kurulumunuzda kullanıcı tablolarında \"line\" veri tipi mevcut. Bu \n" +"veri tipi, girdi/çıktı formatı eski ve yeni sürümler arasında deÄŸiÅŸiklik\n" +"gösterdiÄŸi için bu küme ÅŸu anda yükseltilemiyor. Sorunlu tabloları\n" +"çıkartıp yükseltmeyi tekrar baÅŸlatabilirsiniz. Problemli sütunları \n" +"aÅŸağıdaki dosyada bulabilirsiniz:\n" +" %s\n" +"\n" +"\n" + +#: version.c:215 +#, c-format +msgid "Checking for invalid \"unknown\" user columns" +msgstr "Geçersiz \"bilinmeyen\" kullanıcı sütunları için kontrol yapılıyor" + +#: version.c:281 +#, c-format +msgid "" +"Your installation contains the \"unknown\" data type in user tables. This\n" +"data type is no longer allowed in tables, so this cluster cannot currently\n" +"be upgraded. You can remove the problem tables and restart the upgrade.\n" +"A list of the problem columns is in the file:\n" +" %s\n" +"\n" +msgstr "" +"Kurulumunuz kullanıcı tablolarında \"unknown\" veri tipini içeriyor. Bu veri tipi\n" +"tablolarda artık kullanılamadığından, bu küme (cluster) ÅŸu anda yüksletilemez\n" +"Problemli tabloları çıkartarak (remove) yükseltmeyi tekrar baÅŸlatabilirsiniz.\n" +"Problemli alanların bir listesini ÅŸu dosya içinde bulabilirsiniz:\n" +" %s\n" +"\n" + +#: version.c:304 +#, c-format +msgid "Checking for hash indexes" +msgstr "Hash indeksler kontrol ediliyor" + +#: version.c:384 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. After upgrading, you will be given\n" +"REINDEX instructions.\n" +"\n" +msgstr "" +"\n" +"Kurulumunuzda hash indeksler mevcut. Bu indeksler eski ve yeni \n" +"kümelerinizde farklı dahili formatlara sahip, bu yüzden REINDEX \n" +"komutuyla tekrar indekslemelisiniz. Yükseltme sonrası size \n" +"REINDEX talimatları verilecek.\n" +"\n" +"\n" + +#: version.c:390 +#, c-format +msgid "" +"\n" +"Your installation contains hash indexes. These indexes have different\n" +"internal formats between your old and new clusters, so they must be\n" +"reindexed with the REINDEX command. The file\n" +" %s\n" +"when executed by psql by the database superuser will recreate all invalid\n" +"indexes; until then, none of these indexes will be used.\n" +"\n" +msgstr "" +"\n" +"Kurulumunuzda hash indeksler mevcut. Bu indeksler eski ve yeni \n" +"kümelerinizde farklı dahili formatlara sahip, bu yüzden REINDEX \n" +"komutuyla tekrar indekslemelisiniz. AÅŸağıdaki dosya:\n" +" %s\n" +"psql'de veritabanı superuser'ı tarafından çalıştırıldığında bütün geçersiz\n" +"indeksleri yeniden oluÅŸturacak; o zamana kadar bu indeksler kullanılmayacak.\n" +"\n" diff --git a/src/bin/pg_upgrade/relfilenode.c b/src/bin/pg_upgrade/relfilenode.c index ed604f26ca7..0c78073f0eb 100644 --- a/src/bin/pg_upgrade/relfilenode.c +++ b/src/bin/pg_upgrade/relfilenode.c @@ -3,7 +3,7 @@ * * relfilenode functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/relfilenode.c */ @@ -30,10 +30,18 @@ void transfer_all_new_tablespaces(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata) { - if (user_opts.transfer_mode == TRANSFER_MODE_LINK) - pg_log(PG_REPORT, "Linking user relation files\n"); - else - pg_log(PG_REPORT, "Copying user relation files\n"); + switch (user_opts.transfer_mode) + { + case TRANSFER_MODE_CLONE: + pg_log(PG_REPORT, "Cloning user relation files\n"); + break; + case TRANSFER_MODE_COPY: + pg_log(PG_REPORT, "Copying user relation files\n"); + break; + case TRANSFER_MODE_LINK: + pg_log(PG_REPORT, "Linking user relation files\n"); + break; + } /* * Transferring files by tablespace is tricky because a single database @@ -250,17 +258,23 @@ transfer_relfile(FileNameMap *map, const char *type_suffix, bool vm_must_add_fro old_file, new_file); rewriteVisibilityMap(old_file, new_file, map->nspname, map->relname); } - else if (user_opts.transfer_mode == TRANSFER_MODE_COPY) - { - pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", - old_file, new_file); - copyFile(old_file, new_file, map->nspname, map->relname); - } else - { - pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", - old_file, new_file); - linkFile(old_file, new_file, map->nspname, map->relname); - } + switch (user_opts.transfer_mode) + { + case TRANSFER_MODE_CLONE: + pg_log(PG_VERBOSE, "cloning \"%s\" to \"%s\"\n", + old_file, new_file); + cloneFile(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_COPY: + pg_log(PG_VERBOSE, "copying \"%s\" to \"%s\"\n", + old_file, new_file); + copyFile(old_file, new_file, map->nspname, map->relname); + break; + case TRANSFER_MODE_LINK: + pg_log(PG_VERBOSE, "linking \"%s\" to \"%s\"\n", + old_file, new_file); + linkFile(old_file, new_file, map->nspname, map->relname); + } } } diff --git a/src/bin/pg_upgrade/server.c b/src/bin/pg_upgrade/server.c index 5273ef6681f..6ad4b14e16a 100644 --- a/src/bin/pg_upgrade/server.c +++ b/src/bin/pg_upgrade/server.c @@ -3,7 +3,7 @@ * * database server functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/server.c */ @@ -309,8 +309,8 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error) /* * If pg_ctl failed, and the connection didn't fail, and - * report_and_exit_on_error is enabled, fail now. This - * could happen if the server was already running. + * report_and_exit_on_error is enabled, fail now. This could happen if + * the server was already running. */ if (!pg_ctl_return) { diff --git a/src/bin/pg_upgrade/tablespace.c b/src/bin/pg_upgrade/tablespace.c index b0cbf81f7da..dfe5bfdcfd5 100644 --- a/src/bin/pg_upgrade/tablespace.c +++ b/src/bin/pg_upgrade/tablespace.c @@ -3,7 +3,7 @@ * * tablespace functions * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * src/bin/pg_upgrade/tablespace.c */ @@ -34,7 +34,7 @@ init_tablespaces(void) * get_tablespace_paths() * * Scans pg_tablespace and returns a malloc'ed array of all tablespace - * paths. Its the caller's responsibility to free the array. + * paths. It's the caller's responsibility to free the array. */ static void get_tablespace_paths(void) diff --git a/src/bin/pg_upgrade/test.sh b/src/bin/pg_upgrade/test.sh index a80501895b1..03c2e46b9c4 100644 --- a/src/bin/pg_upgrade/test.sh +++ b/src/bin/pg_upgrade/test.sh @@ -6,7 +6,7 @@ # runs the regression tests (to put in some data), runs pg_dumpall, # runs pg_upgrade, runs pg_dumpall again, compares the dumps. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California set -e @@ -22,7 +22,8 @@ unset MAKELEVEL standard_initdb() { # To increase coverage of non-standard segment size and group access # without increasing test runtime, run these tests with a custom setting. - "$1" -N --wal-segsize 1 -g + # Also, specify "-A trust" explicitly to suppress initdb's warning. + "$1" -N --wal-segsize 1 -g -A trust if [ -n "$TEMP_CONFIG" -a -r "$TEMP_CONFIG" ] then cat "$TEMP_CONFIG" >> "$PGDATA/postgresql.conf" @@ -30,9 +31,11 @@ standard_initdb() { ../../test/regress/pg_regress --config-auth "$PGDATA" } -# Establish how the server will listen for connections -testhost=`uname -s` +# What flavor of host are we on? +# Treat MINGW* (msys1) and MSYS* (msys2) the same. +testhost=`uname -s | sed 's/^MSYS/MINGW/'` +# Establish how the server will listen for connections case $testhost in MINGW*) LISTEN_ADDRESSES="localhost" @@ -44,20 +47,18 @@ case $testhost in # script; the outcome mimics pg_regress.c:make_temp_sockdir(). PGHOST=$PG_REGRESS_SOCK_DIR if [ "x$PGHOST" = x ]; then - { - dir=`(umask 077 && - mktemp -d /tmp/pg_upgrade_check-XXXXXX) 2>/dev/null` && - [ -d "$dir" ] - } || - { + set +e + dir=`(umask 077 && + mktemp -d /tmp/pg_upgrade_check-XXXXXX) 2>/dev/null` + if [ ! -d "$dir" ]; then dir=/tmp/pg_upgrade_check-$$-$RANDOM (umask 077 && mkdir "$dir") - } || - { - echo "could not create socket temporary directory in \"/tmp\"" - exit 1 - } - + if [ ! -d "$dir" ]; then + echo "could not create socket temporary directory in \"/tmp\"" + exit 1 + fi + fi + set -e PGHOST=$dir trap 'rm -rf "$PGHOST"' 0 trap 'exit 3' 1 2 13 15 @@ -65,38 +66,13 @@ case $testhost in ;; esac -POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES -k \"$PGHOST\"" +POSTMASTER_OPTS="-F -c listen_addresses=\"$LISTEN_ADDRESSES\" -k \"$PGHOST\"" export PGHOST # don't rely on $PWD here, as old shells don't set it temp_root=`pwd`/tmp_check - -if [ "$1" = '--install' ]; then - temp_install=$temp_root/install - bindir=$temp_install/$bindir - libdir=$temp_install/$libdir - - "$MAKE" -s -C ../.. install DESTDIR="$temp_install" - - # platform-specific magic to find the shared libraries; see pg_regress.c - LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH - DYLD_LIBRARY_PATH=$libdir:$DYLD_LIBRARY_PATH - export DYLD_LIBRARY_PATH - LIBPATH=$libdir:$LIBPATH - export LIBPATH - SHLIB_PATH=$libdir:$SHLIB_PATH - export SHLIB_PATH - PATH=$libdir:$PATH - - # We need to make it use psql from our temporary installation, - # because otherwise the installcheck run below would try to - # use psql from the proper installation directory, which might - # be outdated or missing. But don't override anything else that's - # already in EXTRA_REGRESS_OPTS. - EXTRA_REGRESS_OPTS="$EXTRA_REGRESS_OPTS --bindir='$bindir'" - export EXTRA_REGRESS_OPTS -fi +rm -rf "$temp_root" +mkdir "$temp_root" : ${oldbindir=$bindir} @@ -104,13 +80,34 @@ fi oldsrc=`cd "$oldsrc" && pwd` newsrc=`cd ../../.. && pwd` +# We need to make pg_regress use psql from the desired installation +# (likely a temporary one), because otherwise the installcheck run +# below would try to use psql from the proper installation directory +# of the target version, which might be outdated or not exist. But +# don't override anything else that's already in EXTRA_REGRESS_OPTS. +EXTRA_REGRESS_OPTS="$EXTRA_REGRESS_OPTS --bindir='$oldbindir'" +export EXTRA_REGRESS_OPTS + +# While in normal cases this will already be set up, adding bindir to +# path allows test.sh to be invoked with different versions as +# described in ./TESTING PATH=$bindir:$PATH export PATH -BASE_PGDATA=$temp_root/data -PGDATA="$BASE_PGDATA.old" +BASE_PGDATA="$temp_root/data" +PGDATA="${BASE_PGDATA}.old" export PGDATA -rm -rf "$BASE_PGDATA" "$PGDATA" + +# Send installcheck outputs to a private directory. This avoids conflict when +# check-world runs pg_upgrade check concurrently with src/test/regress check. +# To retrieve interesting files after a run, use pattern tmp_check/*/*.diffs. +outputdir="$temp_root/regress" +EXTRA_REGRESS_OPTS="$EXTRA_REGRESS_OPTS --outputdir=$outputdir" +export EXTRA_REGRESS_OPTS +mkdir "$outputdir" +mkdir "$outputdir"/sql +mkdir "$outputdir"/expected +mkdir "$outputdir"/testtablespace logdir=`pwd`/log rm -rf "$logdir" @@ -152,9 +149,6 @@ done EXTRA_REGRESS_OPTS="$EXTRA_REGRESS_OPTS --port=$PGPORT" export EXTRA_REGRESS_OPTS -# enable echo so the user can see what is being executed -set -x - standard_initdb "$oldbindir"/initdb "$oldbindir"/pg_ctl start -l "$logdir/postmaster1.log" -o "$POSTMASTER_OPTS" -w @@ -167,11 +161,11 @@ dbname1=`awk 'BEGIN { for (i= 1; i < 46; i++) dbname1='\"\'$dbname1'\\"\\\' dbname2=`awk 'BEGIN { for (i = 46; i < 91; i++) printf "%c", i }' -#include -#include - -#include "pg_getopt.h" - - -static int64 files = 0; -static int64 blocks = 0; -static int64 badblocks = 0; -static ControlFileData *ControlFile; - -static char *only_relfilenode = NULL; -static bool debug = false; - -static const char *progname; - -static void -usage() -{ - printf(_("%s verifies page level checksums in offline PostgreSQL database cluster.\n\n"), progname); - printf(_("Usage:\n")); - printf(_(" %s [OPTION] [DATADIR]\n"), progname); - printf(_("\nOptions:\n")); - printf(_(" [-D] DATADIR data directory\n")); - printf(_(" -f, force check even if checksums are disabled\n")); - printf(_(" -r relfilenode check only relation with specified relfilenode\n")); - printf(_(" -d debug output, listing all checked blocks\n")); - printf(_(" -V, --version output version information, then exit\n")); - printf(_(" -?, --help show this help, then exit\n")); - printf(_("\nIf no data directory (DATADIR) is specified, " - "the environment variable PGDATA\nis used.\n\n")); - printf(_("Report bugs to .\n")); -} - -static const char *skip[] = { - "pg_control", - "pg_filenode.map", - "pg_internal.init", - "PG_VERSION", - NULL, -}; - -static bool -skipfile(char *fn) -{ - const char **f; - - if (strcmp(fn, ".") == 0 || - strcmp(fn, "..") == 0) - return true; - - for (f = skip; *f; f++) - if (strcmp(*f, fn) == 0) - return true; - return false; -} - -static void -scan_file(char *fn, int segmentno) -{ - char buf[BLCKSZ]; - PageHeader header = (PageHeader) buf; - int f; - int blockno; - - f = open(fn, 0); - if (f < 0) - { - fprintf(stderr, _("%s: could not open file \"%s\": %m\n"), progname, fn); - exit(1); - } - - files++; - - for (blockno = 0;; blockno++) - { - uint16 csum; - int r = read(f, buf, BLCKSZ); - - if (r == 0) - break; - if (r != BLCKSZ) - { - fprintf(stderr, _("%s: short read of block %d in file \"%s\", got only %d bytes\n"), - progname, blockno, fn, r); - exit(1); - } - blocks++; - - csum = pg_checksum_page(buf, blockno + segmentno * RELSEG_SIZE); - if (csum != header->pd_checksum) - { - if (ControlFile->data_checksum_version == PG_DATA_CHECKSUM_VERSION) - fprintf(stderr, _("%s: checksum verification failed in file \"%s\", block %d: calculated checksum %X but expected %X\n"), - progname, fn, blockno, csum, header->pd_checksum); - badblocks++; - } - else if (debug) - fprintf(stderr, _("%s: checksum verified in file \"%s\", block %d: %X\n"), - progname, fn, blockno, csum); - } - - close(f); -} - -static void -scan_directory(char *basedir, char *subdir) -{ - char path[MAXPGPATH]; - DIR *dir; - struct dirent *de; - - snprintf(path, sizeof(path), "%s/%s", basedir, subdir); - dir = opendir(path); - if (!dir) - { - fprintf(stderr, _("%s: could not open directory \"%s\": %m\n"), - progname, path); - exit(1); - } - while ((de = readdir(dir)) != NULL) - { - char fn[MAXPGPATH + 1]; - struct stat st; - - if (skipfile(de->d_name)) - continue; - - snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name); - if (lstat(fn, &st) < 0) - { - fprintf(stderr, _("%s: could not stat file \"%s\": %m\n"), - progname, fn); - exit(1); - } - if (S_ISREG(st.st_mode)) - { - char *forkpath, - *segmentpath; - int segmentno = 0; - - /* - * Cut off at the segment boundary (".") to get the segment number - * in order to mix it into the checksum. Then also cut off at the - * fork boundary, to get the relfilenode the file belongs to for - * filtering. - */ - segmentpath = strchr(de->d_name, '.'); - if (segmentpath != NULL) - { - *segmentpath++ = '\0'; - segmentno = atoi(segmentpath); - if (segmentno == 0) - { - fprintf(stderr, _("%s: invalid segment number %d in filename \"%s\"\n"), - progname, segmentno, fn); - exit(1); - } - } - - forkpath = strchr(de->d_name, '_'); - if (forkpath != NULL) - *forkpath++ = '\0'; - - if (only_relfilenode && strcmp(only_relfilenode, de->d_name) != 0) - /* Relfilenode not to be included */ - continue; - - scan_file(fn, segmentno); - } -#ifndef WIN32 - else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) -#else - else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn)) -#endif - scan_directory(path, de->d_name); - } - closedir(dir); -} - -int -main(int argc, char *argv[]) -{ - char *DataDir = NULL; - bool force = false; - int c; - bool crc_ok; - - set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_verify_checksums")); - - progname = get_progname(argv[0]); - - if (argc > 1) - { - if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) - { - usage(); - exit(0); - } - if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) - { - puts("pg_verify_checksums (PostgreSQL) " PG_VERSION); - exit(0); - } - } - - while ((c = getopt(argc, argv, "D:fr:d")) != -1) - { - switch (c) - { - case 'd': - debug = true; - break; - case 'D': - DataDir = optarg; - break; - case 'f': - force = true; - break; - case 'r': - if (atoi(optarg) <= 0) - { - fprintf(stderr, _("%s: invalid relfilenode: %s\n"), progname, optarg); - exit(1); - } - only_relfilenode = pstrdup(optarg); - break; - default: - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); - } - } - - if (DataDir == NULL) - { - if (optind < argc) - DataDir = argv[optind++]; - else - DataDir = getenv("PGDATA"); - - /* If no DataDir was specified, and none could be found, error out */ - if (DataDir == NULL) - { - fprintf(stderr, _("%s: no data directory specified\n"), progname); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); - exit(1); - } - } - - /* Complain if any arguments remain */ - if (optind < argc) - { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); - fprintf(stderr, _("Try \"%s --help\" for more information.\n"), - progname); - exit(1); - } - - /* Check if cluster is running */ - ControlFile = get_controlfile(DataDir, progname, &crc_ok); - if (!crc_ok) - { - fprintf(stderr, _("%s: pg_control CRC value is incorrect.\n"), progname); - exit(1); - } - - if (ControlFile->state != DB_SHUTDOWNED && - ControlFile->state != DB_SHUTDOWNED_IN_RECOVERY) - { - fprintf(stderr, _("%s: cluster must be shut down to verify checksums.\n"), progname); - exit(1); - } - - if (ControlFile->data_checksum_version == 0 && !force) - { - fprintf(stderr, _("%s: data checksums are not enabled in cluster.\n"), progname); - exit(1); - } - - /* Scan all files */ - scan_directory(DataDir, "global"); - scan_directory(DataDir, "base"); - scan_directory(DataDir, "pg_tblspc"); - - printf(_("Checksum scan completed\n")); - printf(_("Data checksum version: %d\n"), ControlFile->data_checksum_version); - printf(_("Files scanned: %" INT64_MODIFIER "d\n"), files); - printf(_("Blocks scanned: %" INT64_MODIFIER "d\n"), blocks); - printf(_("Bad checksums: %" INT64_MODIFIER "d\n"), badblocks); - - if (badblocks > 0) - return 1; - - return 0; -} diff --git a/src/bin/pg_waldump/.gitignore b/src/bin/pg_waldump/.gitignore index 0013a93189c..350d4927a68 100644 --- a/src/bin/pg_waldump/.gitignore +++ b/src/bin/pg_waldump/.gitignore @@ -2,3 +2,6 @@ # Source files copied from src/backend/access/rmgrdesc/ /*desc.c /xlogreader.c + +# Generated by test suite +/tmp_check/ diff --git a/src/bin/pg_waldump/Makefile b/src/bin/pg_waldump/Makefile index f5957bd75a6..135979cef38 100644 --- a/src/bin/pg_waldump/Makefile +++ b/src/bin/pg_waldump/Makefile @@ -38,3 +38,10 @@ uninstall: clean distclean maintainer-clean: rm -f pg_waldump$(X) $(OBJS) $(RMGRDESCSOURCES) xlogreader.c + rm -rf tmp_check + +check: + $(prove_check) + +installcheck: + $(prove_installcheck) diff --git a/src/bin/pg_waldump/compat.c b/src/bin/pg_waldump/compat.c index 6ff9eb7e77b..0e0dca7d1ad 100644 --- a/src/bin/pg_waldump/compat.c +++ b/src/bin/pg_waldump/compat.c @@ -3,7 +3,7 @@ * compat.c * Reimplementations of various backend functions. * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_waldump/compat.c @@ -58,7 +58,8 @@ timestamptz_to_str(TimestampTz dt) strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", ltime); strftime(zone, sizeof(zone), "%Z", ltime); - sprintf(buf, "%s.%06d %s", ts, (int) (dt % USECS_PER_SEC), zone); + snprintf(buf, sizeof(buf), "%s.%06d %s", + ts, (int) (dt % USECS_PER_SEC), zone); return buf; } diff --git a/src/bin/pg_waldump/nls.mk b/src/bin/pg_waldump/nls.mk index 2d9e78f5c6e..2ee2da79015 100644 --- a/src/bin/pg_waldump/nls.mk +++ b/src/bin/pg_waldump/nls.mk @@ -1,6 +1,6 @@ # src/bin/pg_waldump/nls.mk CATALOG_NAME = pg_waldump -AVAIL_LANGUAGES = es fr sv -GETTEXT_FILES = pg_waldump.c -GETTEXT_TRIGGERS = fatal_error -GETTEXT_FLAGS = fatal_error:1:c-format +AVAIL_LANGUAGES = de es fr ja ko ru sv tr vi +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_waldump.c +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) fatal_error +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) fatal_error:1:c-format diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index 242aff2d681..b79208cd736 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -2,7 +2,7 @@ * * pg_waldump.c - decode and display WAL * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/bin/pg_waldump/pg_waldump.c @@ -21,6 +21,7 @@ #include "access/xlog_internal.h" #include "access/transam.h" #include "common/fe_memutils.h" +#include "common/logging.h" #include "getopt_long.h" #include "rmgrdesc.h" @@ -32,7 +33,6 @@ static int WalSegSz; typedef struct XLogDumpPrivate { TimeLineID timeline; - char *inpath; XLogRecPtr startptr; XLogRecPtr endptr; bool endptr_reached; @@ -70,26 +70,7 @@ typedef struct XLogDumpStats Stats record_stats[RM_NEXT_ID][MAX_XLINFO_TYPES]; } XLogDumpStats; -static void fatal_error(const char *fmt,...) pg_attribute_printf(1, 2); - -/* - * Big red button to push when things go horribly wrong. - */ -static void -fatal_error(const char *fmt,...) -{ - va_list args; - - fflush(stdout); - - fprintf(stderr, _("%s: FATAL: "), progname); - va_start(args, fmt); - vfprintf(stderr, _(fmt), args); - va_end(args); - fputc('\n', stderr); - - exit(EXIT_FAILURE); -} +#define fatal_error(...) do { pg_log_fatal(__VA_ARGS__); exit(EXIT_FAILURE); } while(0) static void print_rmgr_list(void) @@ -209,16 +190,20 @@ search_directory(const char *directory, const char *fname) /* set WalSegSz if file is successfully opened */ if (fd >= 0) { - char buf[XLOG_BLCKSZ]; + PGAlignedXLogBlock buf; + int r; - if (read(fd, buf, XLOG_BLCKSZ) == XLOG_BLCKSZ) + r = read(fd, buf.data, XLOG_BLCKSZ); + if (r == XLOG_BLCKSZ) { - XLogLongPageHeader longhdr = (XLogLongPageHeader) buf; + XLogLongPageHeader longhdr = (XLogLongPageHeader) buf.data; WalSegSz = longhdr->xlp_seg_size; if (!IsValidWalSegSize(WalSegSz)) - fatal_error("WAL segment size must be a power of two between 1MB and 1GB, but the WAL file \"%s\" header specifies %d bytes", + fatal_error(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte", + "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes", + WalSegSz), fname, WalSegSz); } else @@ -227,7 +212,8 @@ search_directory(const char *directory, const char *fname) fatal_error("could not read file \"%s\": %s", fname, strerror(errno)); else - fatal_error("not enough data in file \"%s\"", fname); + fatal_error("could not read file \"%s\": read %d of %zu", + fname, r, (Size) XLOG_BLCKSZ); } close(fd); return true; @@ -237,7 +223,7 @@ search_directory(const char *directory, const char *fname) } /* - * Identify the target directory and set WalSegSz. + * Identify the target directory. * * Try to find the file in several places: * if directory != NULL: @@ -248,29 +234,22 @@ search_directory(const char *directory, const char *fname) * XLOGDIR / * $PGDATA / XLOGDIR / * - * Set the valid target directory in private->inpath. + * The valid target directory is returned. */ -static void -identify_target_directory(XLogDumpPrivate *private, char *directory, - char *fname) +static char * +identify_target_directory(char *directory, char *fname) { char fpath[MAXPGPATH]; if (directory != NULL) { if (search_directory(directory, fname)) - { - private->inpath = strdup(directory); - return; - } + return pg_strdup(directory); /* directory / XLOGDIR */ snprintf(fpath, MAXPGPATH, "%s/%s", directory, XLOGDIR); if (search_directory(fpath, fname)) - { - private->inpath = strdup(fpath); - return; - } + return pg_strdup(fpath); } else { @@ -278,16 +257,10 @@ identify_target_directory(XLogDumpPrivate *private, char *directory, /* current directory */ if (search_directory(".", fname)) - { - private->inpath = strdup("."); - return; - } + return pg_strdup("."); /* XLOGDIR */ if (search_directory(XLOGDIR, fname)) - { - private->inpath = strdup(XLOGDIR); - return; - } + return pg_strdup(XLOGDIR); datadir = getenv("PGDATA"); /* $PGDATA / XLOGDIR */ @@ -295,10 +268,7 @@ identify_target_directory(XLogDumpPrivate *private, char *directory, { snprintf(fpath, MAXPGPATH, "%s/%s", datadir, XLOGDIR); if (search_directory(fpath, fname)) - { - private->inpath = strdup(fpath); - return; - } + return pg_strdup(fpath); } } @@ -307,6 +277,8 @@ identify_target_directory(XLogDumpPrivate *private, char *directory, fatal_error("could not locate WAL file \"%s\"", fname); else fatal_error("could not find any WAL file"); + + return NULL; /* not reached */ } /* @@ -409,11 +381,17 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id, { int err = errno; char fname[MAXPGPATH]; + int save_errno = errno; XLogFileName(fname, timeline_id, sendSegNo, WalSegSz); - - fatal_error("could not read from log file %s, offset %u, length %d: %s", - fname, sendOff, segbytes, strerror(err)); + errno = save_errno; + + if (readbytes < 0) + fatal_error("could not read from log file %s, offset %u, length %d: %s", + fname, sendOff, segbytes, strerror(err)); + else if (readbytes == 0) + fatal_error("could not read from log file %s, offset %u: read %d of %zu", + fname, sendOff, readbytes, (Size) segbytes); } /* Update state for read */ @@ -430,7 +408,7 @@ XLogDumpXLogRead(const char *directory, TimeLineID timeline_id, */ static int XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, - XLogRecPtr targetPtr, char *readBuff, TimeLineID *curFileTLI) + XLogRecPtr targetPtr, char *readBuff) { XLogDumpPrivate *private = state->private_data; int count = XLOG_BLCKSZ; @@ -448,7 +426,7 @@ XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen, } } - XLogDumpXLogRead(private->inpath, private->timeline, targetPagePtr, + XLogDumpXLogRead(state->segcxt.ws_dir, private->timeline, targetPagePtr, readBuff, count); return count; @@ -813,6 +791,7 @@ usage(void) printf(_(" -z, --stats[=record] show statistics instead of records\n" " (optionally, show per-record statistics)\n")); printf(_(" -?, --help show this help, then exit\n")); + printf(_("\nReport bugs to .\n")); } int @@ -826,6 +805,7 @@ main(int argc, char **argv) XLogDumpStats stats; XLogRecord *record; XLogRecPtr first_record; + char *waldir = NULL; char *errormsg; static struct option long_options[] = { @@ -847,9 +827,24 @@ main(int argc, char **argv) int option; int optindex = 0; + pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_waldump")); progname = get_progname(argv[0]); + if (argc > 1) + { + if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) + { + usage(); + exit(0); + } + if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) + { + puts("pg_waldump (PostgreSQL) " PG_VERSION); + exit(0); + } + } + memset(&private, 0, sizeof(XLogDumpPrivate)); memset(&config, 0, sizeof(XLogDumpConfig)); memset(&stats, 0, sizeof(XLogDumpStats)); @@ -871,11 +866,11 @@ main(int argc, char **argv) if (argc <= 1) { - fprintf(stderr, _("%s: no arguments specified\n"), progname); + pg_log_error("no arguments specified"); goto bad_argument; } - while ((option = getopt_long(argc, argv, "be:?fn:p:r:s:t:Vx:z", + while ((option = getopt_long(argc, argv, "be:fn:p:r:s:t:x:z", long_options, &optindex)) != -1) { switch (option) @@ -886,8 +881,8 @@ main(int argc, char **argv) case 'e': if (sscanf(optarg, "%X/%X", &xlogid, &xrecoff) != 2) { - fprintf(stderr, _("%s: could not parse end WAL location \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse end WAL location \"%s\"", + optarg); goto bad_argument; } private.endptr = (uint64) xlogid << 32 | xrecoff; @@ -895,20 +890,15 @@ main(int argc, char **argv) case 'f': config.follow = true; break; - case '?': - usage(); - exit(EXIT_SUCCESS); - break; case 'n': if (sscanf(optarg, "%d", &config.stop_after_records) != 1) { - fprintf(stderr, _("%s: could not parse limit \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse limit \"%s\"", optarg); goto bad_argument; } break; case 'p': - private.inpath = pg_strdup(optarg); + waldir = pg_strdup(optarg); break; case 'r': { @@ -931,8 +921,8 @@ main(int argc, char **argv) if (config.filter_by_rmgr == -1) { - fprintf(stderr, _("%s: resource manager \"%s\" does not exist\n"), - progname, optarg); + pg_log_error("resource manager \"%s\" does not exist", + optarg); goto bad_argument; } } @@ -940,8 +930,8 @@ main(int argc, char **argv) case 's': if (sscanf(optarg, "%X/%X", &xlogid, &xrecoff) != 2) { - fprintf(stderr, _("%s: could not parse start WAL location \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse start WAL location \"%s\"", + optarg); goto bad_argument; } else @@ -950,20 +940,15 @@ main(int argc, char **argv) case 't': if (sscanf(optarg, "%d", &private.timeline) != 1) { - fprintf(stderr, _("%s: could not parse timeline \"%s\"\n"), - progname, optarg); + pg_log_error("could not parse timeline \"%s\"", optarg); goto bad_argument; } break; - case 'V': - puts("pg_waldump (PostgreSQL) " PG_VERSION); - exit(EXIT_SUCCESS); - break; case 'x': if (sscanf(optarg, "%u", &config.filter_by_xid) != 1) { - fprintf(stderr, _("%s: could not parse \"%s\" as a transaction ID\n"), - progname, optarg); + pg_log_error("could not parse \"%s\" as a transaction ID", + optarg); goto bad_argument; } config.filter_by_xid_enabled = true; @@ -977,8 +962,8 @@ main(int argc, char **argv) config.stats_per_record = true; else if (strcmp(optarg, "rmgr") != 0) { - fprintf(stderr, _("%s: unrecognized argument to --stats: %s\n"), - progname, optarg); + pg_log_error("unrecognized argument to --stats: %s", + optarg); goto bad_argument; } } @@ -990,20 +975,18 @@ main(int argc, char **argv) if ((optind + 2) < argc) { - fprintf(stderr, - _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 2]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind + 2]); goto bad_argument; } - if (private.inpath != NULL) + if (waldir != NULL) { /* validate path points to directory */ - if (!verify_directory(private.inpath)) + if (!verify_directory(waldir)) { - fprintf(stderr, - _("%s: path \"%s\" could not be opened: %s\n"), - progname, private.inpath, strerror(errno)); + pg_log_error("path \"%s\" could not be opened: %s", + waldir, strerror(errno)); goto bad_argument; } } @@ -1018,17 +1001,17 @@ main(int argc, char **argv) split_path(argv[optind], &directory, &fname); - if (private.inpath == NULL && directory != NULL) + if (waldir == NULL && directory != NULL) { - private.inpath = directory; + waldir = directory; - if (!verify_directory(private.inpath)) + if (!verify_directory(waldir)) fatal_error("could not open directory \"%s\": %s", - private.inpath, strerror(errno)); + waldir, strerror(errno)); } - identify_target_directory(&private, private.inpath, fname); - fd = open_file_in_directory(private.inpath, fname); + waldir = identify_target_directory(waldir, fname); + fd = open_file_in_directory(waldir, fname); if (fd < 0) fatal_error("could not open file \"%s\"", fname); close(fd); @@ -1037,21 +1020,19 @@ main(int argc, char **argv) XLogFromFileName(fname, &private.timeline, &segno, WalSegSz); if (XLogRecPtrIsInvalid(private.startptr)) - XLogSegNoOffsetToRecPtr(segno, 0, private.startptr, WalSegSz); + XLogSegNoOffsetToRecPtr(segno, 0, WalSegSz, private.startptr); else if (!XLByteInSeg(private.startptr, segno, WalSegSz)) { - fprintf(stderr, - _("%s: start WAL location %X/%X is not inside file \"%s\"\n"), - progname, - (uint32) (private.startptr >> 32), - (uint32) private.startptr, - fname); + pg_log_error("start WAL location %X/%X is not inside file \"%s\"", + (uint32) (private.startptr >> 32), + (uint32) private.startptr, + fname); goto bad_argument; } /* no second file specified, set end position */ if (!(optind + 1 < argc) && XLogRecPtrIsInvalid(private.endptr)) - XLogSegNoOffsetToRecPtr(segno + 1, 0, private.endptr, WalSegSz); + XLogSegNoOffsetToRecPtr(segno + 1, 0, WalSegSz, private.endptr); /* parse ENDSEG if passed */ if (optind + 1 < argc) @@ -1061,7 +1042,7 @@ main(int argc, char **argv) /* ignore directory, already have that */ split_path(argv[optind + 1], &directory, &fname); - fd = open_file_in_directory(private.inpath, fname); + fd = open_file_in_directory(waldir, fname); if (fd < 0) fatal_error("could not open file \"%s\"", fname); close(fd); @@ -1074,8 +1055,8 @@ main(int argc, char **argv) argv[optind + 1], argv[optind]); if (XLogRecPtrIsInvalid(private.endptr)) - XLogSegNoOffsetToRecPtr(endsegno + 1, 0, private.endptr, - WalSegSz); + XLogSegNoOffsetToRecPtr(endsegno + 1, 0, WalSegSz, + private.endptr); /* set segno to endsegno for check of --end */ segno = endsegno; @@ -1085,29 +1066,27 @@ main(int argc, char **argv) if (!XLByteInSeg(private.endptr, segno, WalSegSz) && private.endptr != (segno + 1) * WalSegSz) { - fprintf(stderr, - _("%s: end WAL location %X/%X is not inside file \"%s\"\n"), - progname, - (uint32) (private.endptr >> 32), - (uint32) private.endptr, - argv[argc - 1]); + pg_log_error("end WAL location %X/%X is not inside file \"%s\"", + (uint32) (private.endptr >> 32), + (uint32) private.endptr, + argv[argc - 1]); goto bad_argument; } } else - identify_target_directory(&private, private.inpath, NULL); + waldir = identify_target_directory(waldir, NULL); /* we don't know what to print */ if (XLogRecPtrIsInvalid(private.startptr)) { - fprintf(stderr, _("%s: no start WAL location given\n"), progname); + pg_log_error("no start WAL location given"); goto bad_argument; } /* done with argument parsing, do the actual work */ /* we have everything we need, start reading */ - xlogreader_state = XLogReaderAllocate(WalSegSz, XLogDumpReadPage, + xlogreader_state = XLogReaderAllocate(WalSegSz, waldir, XLogDumpReadPage, &private); if (!xlogreader_state) fatal_error("out of memory"); diff --git a/src/bin/pg_waldump/po/de.po b/src/bin/pg_waldump/po/de.po new file mode 100644 index 00000000000..30fac183b9e --- /dev/null +++ b/src/bin/pg_waldump/po/de.po @@ -0,0 +1,307 @@ +# German message translation file for pg_waldump +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Peter Eisentraut , 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-16 18:13+0000\n" +"PO-Revision-Date: 2019-05-15 16:52+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "Warnung: " + +#: pg_waldump.c:148 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "konnte Datei »%s« nicht öffnen: %s" + +#: pg_waldump.c:205 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Kopf der WAL-Datei »%s« gibt %d Byte an" +msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Kopf der WAL-Datei »%s« gibt %d Bytes an" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "konnte Datei »%s« nicht lesen: %s" + +#: pg_waldump.c:216 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen" + +#: pg_waldump.c:294 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "konnte WAL-Datei »%s« nicht finden" + +#: pg_waldump.c:296 +#, c-format +msgid "could not find any WAL file" +msgstr "konnte keine WAL-Datei finden" + +#: pg_waldump.c:367 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "konnte Datei »%s« nicht finden: %s" + +#: pg_waldump.c:382 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "konnte Positionszeiger in Logdatei %s nicht auf %u setzen: %s" + +#: pg_waldump.c:405 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "konnte nicht aus Logdatei %s bei Position %u, Länge %d lesen: %s" + +#: pg_waldump.c:408 +#, c-format +msgid "could not read from log file %s, offset %u: read %d of %zu" +msgstr "konnte nicht aus Logdatei %s bei Position %u lesen: %d von %zu gelesen" + +#: pg_waldump.c:787 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s dekodiert und zeigt PostgreSQL-Write-Ahead-Logs zum Debuggen.\n" +"\n" + +#: pg_waldump.c:789 +#, c-format +msgid "Usage:\n" +msgstr "Aufruf:\n" + +#: pg_waldump.c:790 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [OPTION]... [STARTSEG [ENDSEG]]\n" + +#: pg_waldump.c:791 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Optionen:\n" + +#: pg_waldump.c:792 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details detaillierte Informationen über Backup-Blöcke ausgeben\n" + +#: pg_waldump.c:793 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR bei WAL-Position RECPTR zu lesen aufhören\n" + +#: pg_waldump.c:794 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow am Ende des WAL weiter versuchen\n" + +#: pg_waldump.c:795 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N Anzahl der anzuzeigenden Datensätze\n" + +#: pg_waldump.c:796 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr "" +" -p, --path=PATH Verzeichnis mit den Logsegmentdateien oder Verzeichnis\n" +" mit ./pg_wal mit solchen Dateien (Vorgabe: aktuelles\n" +" Verzeichnis, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:799 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr "" +" -r, --rmgr=RMGR nur Datensätze erzeugt von Resource-Manager RMGR zeigen;\n" +" --rmgr=list zeigt gültige Resource-Manager-Namen\n" + +#: pg_waldump.c:801 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR bei WAL-Position RECPTR zu lesen anfangen\n" + +#: pg_waldump.c:802 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=ZAHL Zeitleiste aus der Datensätze gelesen werden sollen\n" +" (Vorgabe: 1 oder der in STARTSEG verwendete Wert)\n" + +#: pg_waldump.c:804 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" + +#: pg_waldump.c:805 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID nur Datensätze mit Transaktions-ID XID zeigen\n" + +#: pg_waldump.c:806 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] Statistiken statt Datensätzen anzeigen\n" +" (optional Statistiken pro Datensatz zeigen)\n" + +#: pg_waldump.c:808 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" + +#: pg_waldump.c:809 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Berichten Sie Fehler an .\n" + +#: pg_waldump.c:883 +#, c-format +msgid "no arguments specified" +msgstr "keine Argumente angegeben" + +#: pg_waldump.c:898 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "konnte WAL-Endposition »%s« nicht parsen" + +#: pg_waldump.c:910 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "konnte Limit »%s« nicht parsen" + +#: pg_waldump.c:938 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "Resouce-Manager »%s« existiert nicht" + +#: pg_waldump.c:947 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "konnte WAL-Startposition »%s« nicht parsen" + +#: pg_waldump.c:957 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "konnte Zeitleiste »%s« nicht parsen" + +#: pg_waldump.c:964 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "konnte »%s« nicht als gültige Transaktions-ID parsen" + +#: pg_waldump.c:979 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "unbekanntes Argument für --stats: %s" + +#: pg_waldump.c:992 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" + +#: pg_waldump.c:1002 +#, c-format +msgid "path \"%s\" could not be opened: %s" +msgstr "Pfad »%s« konnte nicht geöffnet werden: %s" + +#: pg_waldump.c:1023 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "konnte Verzeichnis »%s« nicht öffnen: %s" + +#: pg_waldump.c:1030 pg_waldump.c:1061 +#, c-format +msgid "could not open file \"%s\"" +msgstr "konnte Datei »%s« nicht öffnen" + +#: pg_waldump.c:1040 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "WAL-Startposition %X/%X ist nicht innerhalb der Datei »%s«" + +#: pg_waldump.c:1068 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG %s kommt vor STARTSEG %s" + +#: pg_waldump.c:1083 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "WAL-Endposition %X/%X ist nicht innerhalb der Datei »%s«" + +#: pg_waldump.c:1096 +#, c-format +msgid "no start WAL location given" +msgstr "keine WAL-Startposition angegeben" + +#: pg_waldump.c:1106 +#, c-format +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: pg_waldump.c:1112 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "konnte keinen gültigen Datensatz nach %X/%X finden" + +#: pg_waldump.c:1123 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "erster Datensatz kommt nach %X/%X, bei %X/%X, %u Byte wurde übersprungen\n" +msgstr[1] "erster Datensatz kommt nach %X/%X, bei %X/%X, %u Bytes wurden übersprungen\n" + +#: pg_waldump.c:1174 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "Fehler in WAL-Eintrag bei %X/%X: %s" + +#: pg_waldump.c:1184 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" diff --git a/src/bin/pg_waldump/po/es.po b/src/bin/pg_waldump/po/es.po index c3f91c3f247..1168f998009 100644 --- a/src/bin/pg_waldump/po/es.po +++ b/src/bin/pg_waldump/po/es.po @@ -1,45 +1,93 @@ # Spanish message translation file for pg_waldump # -# Copyright (C) 2017 PostgreSQL Global Development Group +# Copyright (c) 2017-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Carlos Chapi , 2017. # msgid "" msgstr "" -"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:15+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: pg_waldump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:13+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" "X-Generator: Poedit 2.0.2\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: pg_waldump.c:148 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "no se pudo abrir el archivo «%s»: %s" + +#: pg_waldump.c:205 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "el tamaño de segmento WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero la cabecera del archivo WAL «%s» especifica %d byte" +msgstr[1] "el tamaño de segmento WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero la cabecera del archivo WAL «%s» especifica %d bytes" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "no se pudo leer el archivo «%s»: %s" + +#: pg_waldump.c:216 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "no se pudo leer el archivo «%s»: leídos %d de %zu" -#: pg_waldump.c:82 +#: pg_waldump.c:294 #, c-format -msgid "%s: FATAL: " -msgstr "%s: FATAL: " +msgid "could not locate WAL file \"%s\"" +msgstr "no se pudo ubicar el archivo WAL «%s»" -#: pg_waldump.c:288 +#: pg_waldump.c:296 +#, c-format +msgid "could not find any WAL file" +msgstr "no se pudo encontrar ningún archivo WAL" + +#: pg_waldump.c:367 #, c-format msgid "could not find file \"%s\": %s" msgstr "no se pudo encontrar el archivo «%s»: %s" -#: pg_waldump.c:303 +#: pg_waldump.c:382 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "no se pudo posicionar (seek) en el archivo de log %s a la posición %u: %s" + +#: pg_waldump.c:405 #, c-format -msgid "could not seek in log segment %s to offset %u: %s" -msgstr "no se pudo posicionar (seek) en el segmento de WAL %s a la posición %u: %s" +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "no se pudo leer del archivo de log %s, posición %u, longitud %d: %s" -#: pg_waldump.c:323 +#: pg_waldump.c:408 #, c-format -msgid "could not read from log segment %s, offset %d, length %d: %s" -msgstr "no se pudo leer del segmento de WAL %s, posición %d, longitud %d: %s" +msgid "could not read from log file %s, offset %u: read %d of %zu" +msgstr "no se pudo leer del archivo de log %s, posición %u: leído %d de %zu" -#: pg_waldump.c:702 +#: pg_waldump.c:787 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" @@ -48,17 +96,17 @@ msgstr "" "%s decodifica y muestra segmentos de WAL de PostgreSQL para depuración.\n" "\n" -#: pg_waldump.c:704 +#: pg_waldump.c:789 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: pg_waldump.c:705 +#: pg_waldump.c:790 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [OPCIÓN]... [SEGINICIAL [SEGFINAL]]\n" -#: pg_waldump.c:706 +#: pg_waldump.c:791 #, c-format msgid "" "\n" @@ -67,52 +115,52 @@ msgstr "" "\n" "Opciones:\n" -#: pg_waldump.c:707 +#: pg_waldump.c:792 #, c-format msgid " -b, --bkp-details output detailed information about backup blocks\n" msgstr " -b, --bkp-details mostrar información detallada sobre bloques de respaldo\n" -#: pg_waldump.c:708 +#: pg_waldump.c:793 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" msgstr " -e, --end=RECPTR detener la lectura del WAL en la posición RECPTR\n" -#: pg_waldump.c:709 +#: pg_waldump.c:794 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" msgstr " -f, --follow seguir reintentando después de alcanzar el final del WAL\n" -#: pg_waldump.c:710 +#: pg_waldump.c:795 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N número de registros a mostrar\n" -#: pg_waldump.c:711 +#: pg_waldump.c:796 #, c-format msgid "" " -p, --path=PATH directory in which to find log segment files or a\n" " directory with a ./pg_wal that contains such files\n" -" (default: current directory, ./pg_wal, PGDATA/pg_wal)\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" msgstr "" " -p, --path=RUTA directorio donde buscar los archivos de segmento de WAL\n" " o un directorio con un ./pg_wal que contenga tales archivos\n" -" (por omisión: directorio actual, ./pg_wal, PGDATA/pg_wal)\n" +" (por omisión: directorio actual, ./pg_wal, $PGDATA/pg_wal)\n" -#: pg_waldump.c:714 +#: pg_waldump.c:799 #, c-format msgid "" -" -r, --rmgr=RMGR only show records generated by resource manager RMGR\n" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" " use --rmgr=list to list valid resource manager names\n" msgstr "" -" -r, --rmgr=GESREC solo mostrar registros generados por el gestor de recursos GESREC\n" -" use --rmgr=list para listar nombres válidos para gestor de recursos\n" +" -r, --rmgr=GREC sólo mostrar registros generados por el gestor de\n" +" recursos GREC; use --rmgr=list para listar nombres válidos\n" -#: pg_waldump.c:716 +#: pg_waldump.c:801 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" msgstr " -s, --start=RECPTR empezar a leer el WAL en la posición RECPTR\n" -#: pg_waldump.c:717 +#: pg_waldump.c:802 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read log records\n" @@ -121,17 +169,17 @@ msgstr "" " -t, --timeline=TLI timeline del cual leer los registros de WAL\n" " (por omisión: 1 o el valor usado en SEGINICIAL)\n" -#: pg_waldump.c:719 +#: pg_waldump.c:804 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión, luego salir\n" -#: pg_waldump.c:720 +#: pg_waldump.c:805 #, c-format -msgid " -x, --xid=XID only show records with TransactionId XID\n" -msgstr " -x, --xid=XID solo mostrar registros con el id de transacción XID\n" +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID sólo mostrar registros con el id de transacción XID\n" -#: pg_waldump.c:721 +#: pg_waldump.c:806 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" @@ -140,112 +188,123 @@ msgstr "" " -z, --stats[=registro] mostrar estadísticas en lugar de registros\n" " (opcionalmente, mostrar estadísticas por registro)\n" -#: pg_waldump.c:723 +#: pg_waldump.c:808 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda, luego salir\n" -#: pg_waldump.c:782 +#: pg_waldump.c:809 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Reporte errores a .\n" + +#: pg_waldump.c:883 #, c-format -msgid "%s: no arguments specified\n" -msgstr "%s: no se especificó ningún argumento\n" +msgid "no arguments specified" +msgstr "no se especificó ningún argumento" -#: pg_waldump.c:797 +#: pg_waldump.c:898 #, c-format -msgid "%s: could not parse end WAL location \"%s\"\n" -msgstr "%s: no se pudo interpretar la posición final de WAL «%s»\n" +msgid "could not parse end WAL location \"%s\"" +msgstr "no se pudo interpretar la posición final de WAL «%s»" -#: pg_waldump.c:813 +#: pg_waldump.c:910 #, c-format -msgid "%s: could not parse limit \"%s\"\n" -msgstr "%s: no se pudo interpretar el límite «%s»\n" +msgid "could not parse limit \"%s\"" +msgstr "no se pudo interpretar el límite «%s»" -#: pg_waldump.c:842 +#: pg_waldump.c:938 #, c-format -msgid "%s: resource manager \"%s\" does not exist\n" -msgstr "%s: el gestor de recursos «%s» no existe\n" +msgid "resource manager \"%s\" does not exist" +msgstr "el gestor de recursos «%s» no existe" -#: pg_waldump.c:851 +#: pg_waldump.c:947 #, c-format -msgid "%s: could not parse start WAL location \"%s\"\n" -msgstr "%s: no se pudo interpretar la posición inicial de WAL «%s»\n" +msgid "could not parse start WAL location \"%s\"" +msgstr "no se pudo interpretar la posición inicial de WAL «%s»" -#: pg_waldump.c:861 +#: pg_waldump.c:957 #, c-format -msgid "%s: could not parse timeline \"%s\"\n" -msgstr "%s: no se pudo interpretar el timeline «%s»\n" +msgid "could not parse timeline \"%s\"" +msgstr "no se pudo interpretar el timeline «%s»" -#: pg_waldump.c:873 +#: pg_waldump.c:964 #, c-format -msgid "%s: could not parse \"%s\" as a valid xid\n" -msgstr "%s: no se pudo interpretar «%s» como un id de transacción válido\n" +msgid "could not parse \"%s\" as a transaction ID" +msgstr "no se pudo interpretar «%s» como un id de transacción" -#: pg_waldump.c:888 +#: pg_waldump.c:979 #, c-format -msgid "%s: unrecognized argument to --stats: %s\n" -msgstr "%s: parámetro no reconocido para --stats: %s\n" +msgid "unrecognized argument to --stats: %s" +msgstr "parámetro no reconocido para --stats: %s" -#: pg_waldump.c:902 +#: pg_waldump.c:992 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos de línea de órdenes (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: pg_waldump.c:913 +#: pg_waldump.c:1002 #, c-format -msgid "%s: path \"%s\" cannot be opened: %s\n" -msgstr "%s: la ruta «%s» no se puede abrir: %s\n" +msgid "path \"%s\" could not be opened: %s" +msgstr "la ruta «%s» no se pudo abrir: %s" -#: pg_waldump.c:934 +#: pg_waldump.c:1023 #, c-format -msgid "cannot open directory \"%s\": %s" -msgstr "no se puede abrir el directorio «%s»: %s" +msgid "could not open directory \"%s\": %s" +msgstr "no se pudo abrir el directorio «%s»: %s" -#: pg_waldump.c:940 pg_waldump.c:973 +#: pg_waldump.c:1030 pg_waldump.c:1061 #, c-format msgid "could not open file \"%s\"" msgstr "no se pudo abrir el archivo «%s»" -#: pg_waldump.c:951 +#: pg_waldump.c:1040 #, c-format -msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s: la posición inicial de WAL %X/%X no está en el archivo «%s»\n" +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "la posición inicial de WAL %X/%X no está en el archivo «%s»" -#: pg_waldump.c:980 +#: pg_waldump.c:1068 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "SEGFINAL %s está antes del SEGINICIAL %s" -#: pg_waldump.c:995 +#: pg_waldump.c:1083 #, c-format -msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s: la posición final de WAL %X/%X no está en el archivo «%s»\n" +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "la posición final de WAL %X/%X no está en el archivo «%s»" -#: pg_waldump.c:1007 +#: pg_waldump.c:1096 #, c-format -msgid "%s: no start WAL location given\n" -msgstr "%s: no se especificó posición inicial de WAL\n" +msgid "no start WAL location given" +msgstr "no se especificó posición inicial de WAL" -#: pg_waldump.c:1016 +#: pg_waldump.c:1106 #, c-format msgid "out of memory" msgstr "memoria agotada" -#: pg_waldump.c:1022 +#: pg_waldump.c:1112 #, c-format msgid "could not find a valid record after %X/%X" msgstr "no se pudo encontrar un registro válido después de %X/%X" -#: pg_waldump.c:1032 +#: pg_waldump.c:1123 #, c-format -msgid "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" -msgstr "el primer registro está ubicado después de %X/%X, en %X/%X, saltándose %u bytes\n" +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "el primer registro está ubicado después de %X/%X, en %X/%X, saltándose %u byte\n" +msgstr[1] "el primer registro está ubicado después de %X/%X, en %X/%X, saltándose %u bytes\n" -#: pg_waldump.c:1081 +#: pg_waldump.c:1174 #, c-format msgid "error in WAL record at %X/%X: %s" msgstr "error en registro de WAL en %X/%X: %s" -#: pg_waldump.c:1091 +#: pg_waldump.c:1184 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Pruebe «%s --help» para mayor información.\n" diff --git a/src/bin/pg_waldump/po/fr.po b/src/bin/pg_waldump/po/fr.po index 5922974c658..bce5836ad9d 100644 --- a/src/bin/pg_waldump/po/fr.po +++ b/src/bin/pg_waldump/po/fr.po @@ -5,58 +5,120 @@ # msgid "" msgstr "" -"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-02 04:45+0000\n" -"PO-Revision-Date: 2017-07-05 22:51+0200\n" +"Project-Id-Version: pg_waldump (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:16+0000\n" +"PO-Revision-Date: 2019-05-17 15:06+0200\n" +"Last-Translator: \n" +"Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Last-Translator: \n" -"Language-Team: \n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal : " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "erreur : " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "attention : " + +#: pg_waldump.c:148 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "n'a pas pu ouvrir le fichier « %s » : %s" + +#: pg_waldump.c:205 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL " +"file \"%s\" header specifies %d byte" +msgid_plural "" +"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL " +"file \"%s\" header specifies %d bytes" +msgstr[0] "" +"La taille du segment WAL doit être une puissance de deux entre 1 Mo et 1 Go, " +"mais l'en-tête du fichier WAL « %s » indique %d octet" +msgstr[1] "" +"La taille du segment WAL doit être une puissance de deux entre 1 Mo et 1 Go, " +"mais l'en-tête du fichier WAL « %s » indique %d octets" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "n'a pas pu lire le fichier « %s » : %s" -#: pg_waldump.c:82 +#: pg_waldump.c:216 #, c-format -msgid "%s: FATAL: " -msgstr "%s : FATAL : " +msgid "could not read file \"%s\": read %d of %zu" +msgstr "n'a pas pu lire le fichier « %s » : a lu %d sur %zu" -#: pg_waldump.c:288 +#: pg_waldump.c:294 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "n'a pas pu trouver le fichier WAL « %s »" + +#: pg_waldump.c:296 +#, c-format +msgid "could not find any WAL file" +msgstr "n'a pas pu trouver un seul fichier WAL" + +#: pg_waldump.c:367 #, c-format msgid "could not find file \"%s\": %s" msgstr "n'a pas pu trouver le fichier « %s » : %s" -#: pg_waldump.c:303 +#: pg_waldump.c:382 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "" +"n'a pas pu se déplacer dans le fichier de transactions %s au décalage %u : %s" + +#: pg_waldump.c:405 #, c-format -msgid "could not seek in log segment %s to offset %u: %s" -msgstr "n'a pas pu rechercher dans le segment %s du journal de transactions au décalage %u : %s" +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "" +"n'a pas pu lire à partir du segment %s du journal de transactions, décalage " +"%u, longueur %d : %s" -#: pg_waldump.c:323 +#: pg_waldump.c:408 #, c-format -msgid "could not read from log segment %s, offset %d, length %d: %s" -msgstr "n'a pas pu lire à partir du segment %s du journal de transactions, décalage %d, longueur %d : %s" +msgid "could not read from log file %s, offset %u: read %d of %zu" +msgstr "" +"n'a pas pu lire à partir du segment %s du journal de transactions, décalage " +"%u: %d lu sur %zu" -#: pg_waldump.c:702 +#: pg_waldump.c:787 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" "\n" msgstr "" -"%s décode et affiche les journaux de transactions PostgreSQL pour du débogage.\n" +"%s décode et affiche les journaux de transactions PostgreSQL pour du " +"débogage.\n" "\n" -#: pg_waldump.c:704 +#: pg_waldump.c:789 #, c-format msgid "Usage:\n" msgstr "Usage :\n" -#: pg_waldump.c:705 +#: pg_waldump.c:790 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [OPTION]... [SEG_DEBUT [SEG_FIN]]\n" -#: pg_waldump.c:706 +#: pg_waldump.c:791 #, c-format msgid "" "\n" @@ -65,187 +127,234 @@ msgstr "" "\n" "Options :\n" -#: pg_waldump.c:707 +#: pg_waldump.c:792 #, c-format -msgid " -b, --bkp-details output detailed information about backup blocks\n" -msgstr " -b, --bkp-details affiche des informations détaillées sur les blocs de sauvegarde\n" +msgid "" +" -b, --bkp-details output detailed information about backup blocks\n" +msgstr "" +" -b, --bkp-details affiche des informations détaillées sur les blocs " +"de sauvegarde\n" -#: pg_waldump.c:708 +#: pg_waldump.c:793 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" -msgstr " -e, --end=RECPTR arrête la lecture des journaux de transactions à l'emplacement RECPTR\n" +msgstr "" +" -e, --end=RECPTR arrête la lecture des journaux de transactions à " +"l'emplacement RECPTR\n" -#: pg_waldump.c:709 +#: pg_waldump.c:794 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" -msgstr " -f, --follow continue après avoir atteint la fin des journaux de transactions\n" +msgstr "" +" -f, --follow continue après avoir atteint la fin des journaux de " +"transactions\n" -#: pg_waldump.c:710 +#: pg_waldump.c:795 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N nombre d'enregistrements à afficher\n" -#: pg_waldump.c:711 +#: pg_waldump.c:796 #, c-format msgid "" " -p, --path=PATH directory in which to find log segment files or a\n" " directory with a ./pg_wal that contains such files\n" -" (default: current directory, ./pg_wal, PGDATA/pg_wal)\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" msgstr "" -" -p, --path=CHEMIN répertoire où trouver les fichiers des segments de journaux de transactions\n" -" ou un répertoire avec ./pg_wal qui contient ces fichiers\n" -" (par défaut: répertoire courant, ./pg_wal, PGDATA/pg_wal)\n" +" -p, --path=CHEMIN répertoire où trouver les fichiers des segments de " +"journaux de transactions\n" +" ou un répertoire avec ./pg_wal qui contient ces " +"fichiers\n" +" (par défaut: répertoire courant, ./pg_wal, $PGDATA/" +"pg_wal)\n" -#: pg_waldump.c:714 +#: pg_waldump.c:799 #, c-format msgid "" -" -r, --rmgr=RMGR only show records generated by resource manager RMGR\n" -" use --rmgr=list to list valid resource manager names\n" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" msgstr "" -" -r, --rmgr=RMGR affiche seulement les enregistrements générés par le gestionnaire\n" -" de ressources RMGR, utilisez --rmgr=list pour avoir une liste valide des noms\n" +" -r, --rmgr=RMGR affiche seulement les enregistrements générés par " +"le gestionnaire\n" +" de ressources RMGR, utilisez --rmgr=list pour avoir " +"une liste des noms valides\n" " de gestionnaires de ressources\n" "\n" -#: pg_waldump.c:716 +#: pg_waldump.c:801 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" -msgstr " -s, --start=RECPTR commence à lire à l'emplacement RECPTR des journaux de transactions\n" +msgstr "" +" -s, --start=RECPTR commence à lire à l'emplacement RECPTR des journaux " +"de transactions\n" -#: pg_waldump.c:717 +#: pg_waldump.c:802 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read log records\n" " (default: 1 or the value used in STARTSEG)\n" msgstr "" -" -t, --timeline=TLI timeline à partir de laquelle lire les enregistrements\n" -" des journaux (par défaut: 1 ou la valeur utilisée dans SEG_DÉBUT)\n" +" -t, --timeline=TLI timeline à partir de laquelle lire les " +"enregistrements\n" +" des journaux (par défaut: 1 ou la valeur utilisée " +"dans SEG_DÉBUT)\n" -#: pg_waldump.c:719 +#: pg_waldump.c:804 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version puis quitte\n" -#: pg_waldump.c:720 +#: pg_waldump.c:805 #, c-format -msgid " -x, --xid=XID only show records with TransactionId XID\n" -msgstr " -x, --xid=XID affiche seulement des enregistrements avec le TransactionId XID\n" +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr "" +" -x, --xid=XID affiche seulement des enregistrements avec " +"l'identifiant de transaction XID\n" -#: pg_waldump.c:721 +#: pg_waldump.c:806 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" " (optionally, show per-record statistics)\n" msgstr "" -" -z, --stats[=enregistrement] affiche des statistiques à la place d'enregistrements\n" -" (en option, affiche des statistiques par enregistrement)\n" +" -z, --stats[=enregistrement] affiche des statistiques à la place " +"d'enregistrements\n" +" (en option, affiche des statistiques par " +"enregistrement)\n" -#: pg_waldump.c:723 +#: pg_waldump.c:808 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide puis quitte\n" -#: pg_waldump.c:782 +#: pg_waldump.c:868 #, c-format -msgid "%s: no arguments specified\n" -msgstr "%s : aucun argument spécifié\n" +msgid "no arguments specified" +msgstr "aucun argument spécifié" -#: pg_waldump.c:797 +#: pg_waldump.c:883 #, c-format -msgid "%s: could not parse end WAL location \"%s\"\n" -msgstr "%s : n'a pas pu analyser l'emplacement de fin du journal de transactions « %s »\n" +msgid "could not parse end WAL location \"%s\"" +msgstr "" +"n'a pas pu analyser l'emplacement de fin du journal de transactions « %s »" -#: pg_waldump.c:813 +#: pg_waldump.c:899 #, c-format -msgid "%s: could not parse limit \"%s\"\n" -msgstr "%s : n'a pas pu analyser la limite « %s »\n" +msgid "could not parse limit \"%s\"" +msgstr "n'a pas pu analyser la limite « %s »" -#: pg_waldump.c:842 +#: pg_waldump.c:927 #, c-format -msgid "%s: resource manager \"%s\" does not exist\n" -msgstr "%s : le gestionnaire de ressources « %s » n'existe pas\n" +msgid "resource manager \"%s\" does not exist" +msgstr "le gestionnaire de ressources « %s » n'existe pas" -#: pg_waldump.c:851 +#: pg_waldump.c:936 #, c-format -msgid "%s: could not parse start WAL location \"%s\"\n" -msgstr "%s : n'a pas pu analyser l'emplacement de début du journal de transactions « %s »\n" +msgid "could not parse start WAL location \"%s\"" +msgstr "" +"n'a pas pu analyser l'emplacement de début du journal de transactions « %s »" -#: pg_waldump.c:861 +#: pg_waldump.c:946 #, c-format -msgid "%s: could not parse timeline \"%s\"\n" -msgstr "%s : n'a pas pu analyser la timeline « %s »\n" +msgid "could not parse timeline \"%s\"" +msgstr "n'a pas pu analyser la timeline « %s »" -#: pg_waldump.c:873 +#: pg_waldump.c:957 #, c-format -msgid "%s: could not parse \"%s\" as a valid xid\n" -msgstr "%s : n'a pas pu analyser « %s » comme un xid valide\n" +msgid "could not parse \"%s\" as a transaction ID" +msgstr "n'a pas pu analyser « %s » comme un identifiant de transaction" -#: pg_waldump.c:888 +#: pg_waldump.c:972 #, c-format -msgid "%s: unrecognized argument to --stats: %s\n" -msgstr "%s : argument non reconnu pour --stats : %s\n" +msgid "unrecognized argument to --stats: %s" +msgstr "argument non reconnu pour --stats : %s" -#: pg_waldump.c:902 +#: pg_waldump.c:985 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)" -#: pg_waldump.c:913 +#: pg_waldump.c:995 #, c-format -msgid "%s: path \"%s\" cannot be opened: %s\n" -msgstr "%s : le chemin « %s » ne peut pas être ouvert : %s\n" +msgid "path \"%s\" could not be opened: %s" +msgstr "le chemin « %s » n'a pas pu être ouvert : %s" -#: pg_waldump.c:934 +#: pg_waldump.c:1016 #, c-format -msgid "cannot open directory \"%s\": %s" -msgstr "ne peut pas ouvrir le répertoire « %s » : %s" +msgid "could not open directory \"%s\": %s" +msgstr "n'a pas pu ouvrir le répertoire « %s » : %s" -#: pg_waldump.c:940 pg_waldump.c:973 +#: pg_waldump.c:1023 pg_waldump.c:1054 #, c-format msgid "could not open file \"%s\"" msgstr "n'a pas pu ouvrir le fichier « %s »" -#: pg_waldump.c:951 +#: pg_waldump.c:1033 #, c-format -msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s : l'emplacement de début des journaux de transactions %X/%X n'est pas à l'intérieur du fichier « %s »\n" +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "" +"l'emplacement de début des journaux de transactions %X/%X n'est pas à " +"l'intérieur du fichier « %s »" -#: pg_waldump.c:980 +#: pg_waldump.c:1061 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "SEG_FIN %s est avant SEG_DÉBUT %s" -#: pg_waldump.c:995 +#: pg_waldump.c:1076 #, c-format -msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s : l'emplacement de fin des journaux de transactions %X/%X n'est pas à l'intérieur du fichier « %s »\n" +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "" +"l'emplacement de fin des journaux de transactions %X/%X n'est pas à " +"l'intérieur du fichier « %s »" -#: pg_waldump.c:1007 +#: pg_waldump.c:1089 #, c-format -msgid "%s: no start WAL location given\n" -msgstr "%s : pas d'emplacement donné de début du journaux de transactions\n" +msgid "no start WAL location given" +msgstr "pas d'emplacement donné de début du journal de transactions" -#: pg_waldump.c:1016 +#: pg_waldump.c:1099 #, c-format msgid "out of memory" msgstr "mémoire épuisée" -#: pg_waldump.c:1022 +#: pg_waldump.c:1105 #, c-format msgid "could not find a valid record after %X/%X" msgstr "n'a pas pu trouver un enregistrement valide après %X/%X" -#: pg_waldump.c:1032 +#: pg_waldump.c:1116 #, c-format -msgid "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" -msgstr "le premier enregistrement se trouve après %X/%X, à %X/%X, ignore %u octets\n" +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "" +"le premier enregistrement se trouve après %X/%X, à %X/%X, ignore %u octet\n" +msgstr[1] "" +"le premier enregistrement se trouve après %X/%X, à %X/%X, ignore %u octets\n" -#: pg_waldump.c:1081 +#: pg_waldump.c:1167 #, c-format msgid "error in WAL record at %X/%X: %s" msgstr "erreur dans l'enregistrement des journaux de transactions à %X/%X : %s" -#: pg_waldump.c:1091 +#: pg_waldump.c:1177 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" + +#~ msgid "cannot open directory \"%s\": %s" +#~ msgstr "ne peut pas ouvrir le répertoire « %s » : %s" + +#~ msgid "could not seek in log segment %s to offset %u: %s" +#~ msgstr "" +#~ "n'a pas pu rechercher dans le segment %s du journal de transactions au " +#~ "décalage %u : %s" + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "données insuffisantes dans le fichier « %s »" + +#~ msgid "%s: FATAL: " +#~ msgstr "%s : FATAL : " diff --git a/src/bin/pg_waldump/po/ja.po b/src/bin/pg_waldump/po/ja.po new file mode 100644 index 00000000000..723f35ce84f --- /dev/null +++ b/src/bin/pg_waldump/po/ja.po @@ -0,0 +1,276 @@ +# LANGUAGE message translation file for pg_waldump +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_waldump (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-01-31 14:39+0900\n" +"PO-Revision-Date: 2018-01-31 15:34+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Last-Translator: Michihide Hotta \n" +"Language-Team: \n" +"X-Generator: Poedit 2.0.6\n" + +#: pg_waldump.c:82 +#, c-format +msgid "%s: FATAL: " +msgstr "%s: 致命的ãªã‚¨ãƒ©ãƒ¼: " + +#: pg_waldump.c:288 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "ファイル \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_waldump.c:303 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "ログファイル %s ã§ã‚ªãƒ•セット %u ã« seek ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_waldump.c:323 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "" +"ログ ファイル %s ã®ã‚ªãƒ•セット %u ã‹ã‚‰é•·ã• %d 分を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸã€‚: " +"%s" + +#: pg_waldump.c:702 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s ã¯ãƒ‡ãƒãƒƒã‚°ã®ãŸã‚ã« PostgreSQL ã®å…ˆè¡Œæ›¸ãè¾¼ã¿ãƒ­ã‚°ã‚’デコードã—ã¦è¡¨ç¤ºã—ã¾" +"ã™ã€‚\n" +"\n" + +#: pg_waldump.c:704 +#, c-format +msgid "Usage:\n" +msgstr "使用方法:\n" + +#: pg_waldump.c:705 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [オプション] ... [開始セグメント [終了セグメント]]\n" + +#: pg_waldump.c:706 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"オプション:\n" + +#: pg_waldump.c:707 +#, c-format +msgid "" +" -b, --bkp-details output detailed information about backup " +"blocks\n" +msgstr "" +" -b, --bkp-details ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ブロックã«é–¢ã™ã‚‹è©³ç´°æƒ…報を出力ã™ã‚‹\n" + +#: pg_waldump.c:708 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr "" +" -e, --end=RECPTR WAL 中ã®ä½ç½® RECPTR ã§èª­ã¿è¾¼ã¿ã‚’åœæ­¢ã™ã‚‹\n" + +#: pg_waldump.c:709 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr "" +" -f, --follow WAL ã®çµ‚端ã«é”ã—ã¦ã‹ã‚‰ã‚‚リトライを続ã‘ã‚‹\n" + +#: pg_waldump.c:710 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N 表示ã™ã‚‹ãƒ¬ã‚³ãƒ¼ãƒ‰æ•°\n" + +#: pg_waldump.c:711 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or " +"a\n" +" directory with a ./pg_wal that contains such " +"files\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" +msgstr "" +" -p, --path=PATH ログã®ã‚»ã‚°ãƒ¡ãƒ³ãƒˆãƒ•ァイルを検索ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã€" +"ã¾ãŸã¯\n" +" ãã®ã‚ˆã†ãªãƒ•ァイルãŒå…¥ã£ã¦ã„ã‚‹ ./pg_wal ã®ã‚ã‚‹" +"ディレクトリ\n" +" (デフォルト: カレントディレクトリ, ./pg_wal, " +"$PGDATA/pg_wal)\n" + +#: pg_waldump.c:714 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" +msgstr "" +" -r, --rmgr=RMGR リソースマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ RMGR ã§ç”Ÿæˆã•れãŸãƒ¬ã‚³ãƒ¼ãƒ‰ã®" +"ã¿ã‚’表示ã™ã‚‹;\n" +" --rmgr=list ã§æœ‰åйãªãƒªã‚½ãƒ¼ã‚¹ãƒžãƒãƒ¼ã‚¸ãƒ£ãƒ¼ã®ä¸€è¦§ã‚’" +"表示ã™ã‚‹\n" + +#: pg_waldump.c:716 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr "" +" -s, --start=RECPTR WAL ã®ä½ç½® RECPTR ã‹ã‚‰èª­ã¿è¾¼ã¿ã‚’é–‹å§‹ã™ã‚‹\n" + +#: pg_waldump.c:717 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI ログレコードを読むã¹ãタイムライン\n" +" (デフォルト: 1 ã¾ãŸã¯ STARTSEG ã§ä½¿ã‚れãŸå€¤)\n" + +#: pg_waldump.c:719 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了ã™ã‚‹\n" + +#: pg_waldump.c:720 +#, c-format +msgid "" +" -x, --xid=XID only show records with transaction ID XID\n" +msgstr "" +" -x, --xid=XID トランザクション ID ㌠XID ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ã®ã¿ã‚’表示" +"ã™ã‚‹\n" + +#: pg_waldump.c:721 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=レコード] レコードã®ä»£ã‚りã«çµ±è¨ˆæƒ…報を表示ã™ã‚‹\n" +" (オプションã§ã€ãƒ¬ã‚³ãƒ¼ãƒ‰ã”ã¨ã®çµ±è¨ˆã‚’表示ã™ã‚‹)\n" + +#: pg_waldump.c:723 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦çµ‚了ã™ã‚‹\n" + +#: pg_waldump.c:782 +#, c-format +msgid "%s: no arguments specified\n" +msgstr "%s: å¼•æ•°ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_waldump.c:797 +#, c-format +msgid "%s: could not parse end WAL location \"%s\"\n" +msgstr "%s: WAL ã®çµ‚了ä½ç½® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: pg_waldump.c:813 +#, c-format +msgid "%s: could not parse limit \"%s\"\n" +msgstr "%s: 表示レコード数ã®åˆ¶é™å€¤ \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_waldump.c:842 +#, c-format +msgid "%s: resource manager \"%s\" does not exist\n" +msgstr "%s: リソースマãƒãƒ¼ã‚¸ãƒ£ãƒ¼ \"%s\" ãŒå­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: pg_waldump.c:851 +#, c-format +msgid "%s: could not parse start WAL location \"%s\"\n" +msgstr "%s: WAL ã®é–‹å§‹ä½ç½® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_waldump.c:861 +#, c-format +msgid "%s: could not parse timeline \"%s\"\n" +msgstr "%s: タイムライン \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_waldump.c:873 +#, c-format +msgid "%s: could not parse \"%s\" as a transaction ID\n" +msgstr "%s: トランザクション ID ã¨ã—ã¦ã® \"%s\" ã‚’è§£æžã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: pg_waldump.c:888 +#, c-format +msgid "%s: unrecognized argument to --stats: %s\n" +msgstr "%s: --stats ã¸ã®å¼•æ•°ãŒèªè­˜ã§ãã¾ã›ã‚“: %s\n" + +#: pg_waldump.c:902 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: コマンドライン引数ãŒå¤šã™ãŽã¾ã™(先頭ã¯\"%s\")\n" + +#: pg_waldump.c:913 +#, c-format +msgid "%s: path \"%s\" could not be opened: %s\n" +msgstr "%s: パス \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: pg_waldump.c:934 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "ディレクトリ \"%s\" ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pg_waldump.c:940 pg_waldump.c:973 +#, c-format +msgid "could not open file \"%s\"" +msgstr "ファイル \"%s\" ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" + +#: pg_waldump.c:951 +#, c-format +msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: WAL ã®é–‹å§‹ä½ç½® %X/%X ãŒãƒ•ァイル \"%s\" ã®ä¸­ã«ã¯ã‚りã¾ã›ã‚“\n" + +#: pg_waldump.c:980 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG %s ㌠STARTSEG %s よりå‰ã«ç¾ã‚Œã¾ã—ãŸ" + +#: pg_waldump.c:995 +#, c-format +msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: WAL ã®çµ‚了ä½ç½® %X/%X ãŒãƒ•ァイル \"%s\" ã®ä¸­ã«ã¯ã‚りã¾ã›ã‚“\n" + +#: pg_waldump.c:1007 +#, c-format +msgid "%s: no start WAL location given\n" +msgstr "%s: WAL ã®é–‹å§‹ä½ç½®ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" + +#: pg_waldump.c:1016 +#, c-format +msgid "out of memory" +msgstr "メモリä¸è¶³ã§ã™" + +#: pg_waldump.c:1022 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "%X/%X ã®å¾Œã«æœ‰åйãªãƒ¬ã‚³ãƒ¼ãƒ‰ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" + +#: pg_waldump.c:1032 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "" +"first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "" +"先頭レコード㌠%X/%X ã®å¾Œã® %X/%X ã®ä½ç½®ã«ã‚りã¾ã—ãŸã€‚%u ãƒã‚¤ãƒˆåˆ†ã‚’スキッ" +"プã—ã¦ã„ã¾ã™\n" + +#: pg_waldump.c:1083 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "WAL レコード㮠%X/%X ã§ã‚¨ãƒ©ãƒ¼: %s" + +#: pg_waldump.c:1093 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "\"%s --help\" ã§è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。\n" diff --git a/src/bin/pg_waldump/po/ko.po b/src/bin/pg_waldump/po/ko.po new file mode 100644 index 00000000000..8fc77bef6d9 --- /dev/null +++ b/src/bin/pg_waldump/po/ko.po @@ -0,0 +1,252 @@ +# LANGUAGE message translation file for pg_waldump +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:25+0900\n" +"Last-Translator: Ioseph Kim \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: pg_waldump.c:82 +#, c-format +msgid "%s: FATAL: " +msgstr "%s: 치명ì ì˜¤ë¥˜: " + +#: pg_waldump.c:288 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "\"%s\" 파ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" + +#: pg_waldump.c:303 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "%s 로그 ì¡°ê° íŒŒì¼ì—서 %u 위치를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" + +#: pg_waldump.c:323 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "%s 로그 ì¡°ê° íŒŒì¼ì—서 %u 위치ì—서 %d 길ì´ë¥¼ ì½ì„ 수 ì—†ìŒ: %s" + +#: pg_waldump.c:702 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "%s ëª…ë ¹ì€ ë””ë²„ê¹…ì„ ìœ„í•´ PostgreSQL 미리 쓰기 로그(WAL)를 ë¶„ì„합니다.\n" + +#: pg_waldump.c:704 +#, c-format +msgid "Usage:\n" +msgstr "사용법:\n" + +#: pg_waldump.c:705 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [옵션]... [ì‹œìž‘íŒŒì¼ [마침파ì¼]]\n" + +#: pg_waldump.c:706 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"옵션들:\n" + +#: pg_waldump.c:707 +#, c-format +msgid "" +" -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details 백업 블ë¡ì— 대한 ìžì„¸í•œ ì •ë³´ë„ ì¶œë ¥í•¨\n" + +#: pg_waldump.c:708 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR RECPTR WAL 위치ì—서 ì½ê¸° 멈춤\n" + +#: pg_waldump.c:709 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow WAL ë까지 ì½ì€ ë’¤ì—ë„ ê³„ì† ì§„í–‰í•¨\n" + +#: pg_waldump.c:710 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N 출력할 레코드 수\n" + +#: pg_waldump.c:711 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" +msgstr "" +" -p, --path=PATH 로그 ì¡°ê° íŒŒì¼ì´ 있는 디렉터리 지정, ë˜ëŠ”\n" +" ./pg_wal 디렉터리가 있는 디렉터리 지정\n" +" (기본값: 현재 디렉터리, ./pg_wal, PGDATA/pg_wal)\n" + +#: pg_waldump.c:714 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" +msgstr "" +" -r, --rmgr=RMGR 리소스 ê´€ë¦¬ìž RMGRì—서 만든 레코드만 출력함\n" +" 리소스 ê´€ë¦¬ìž ì´ë“¤ì„ --rmgr=list 로 ë´„\n" + +#: pg_waldump.c:716 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR WAL RECPTR 위치ì—서 ì½ê¸° 시작\n" + +#: pg_waldump.c:717 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI ì½ê¸° 시작할 타임ë¼ì¸ 번호\n" +" (기본값: 1 ë˜ëŠ” STARTSEGì— ì‚¬ìš©ëœ ê°’)\n" + +#: pg_waldump.c:719 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" + +#: pg_waldump.c:720 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID 트랜잭션 XID 레코드만 출력\n" + +#: pg_waldump.c:721 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] ë ˆí¬ë“œ 통계 정보를 보여줌\n" +" (추가로, 레코드당 통계정보를 출력)\n" + +#: pg_waldump.c:723 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" + +#: pg_waldump.c:782 +#, c-format +msgid "%s: no arguments specified\n" +msgstr "%s: ì¸ìžë¥¼ 지정하세요\n" + +#: pg_waldump.c:797 +#, c-format +msgid "%s: could not parse end WAL location \"%s\"\n" +msgstr "%s: \"%s\" ì´ë¦„ì˜ WAL 위치를 í•´ì„í•  수 ì—†ìŒ\n" + +#: pg_waldump.c:813 +#, c-format +msgid "%s: could not parse limit \"%s\"\n" +msgstr "%s: \"%s\" ì œí•œì„ í•´ì„í•  수 ì—†ìŒ\n" + +#: pg_waldump.c:842 +#, c-format +msgid "%s: resource manager \"%s\" does not exist\n" +msgstr "%s: \"%s\" ì´ë¦„ì˜ ë¦¬ì†ŒìŠ¤ 관리ìžê°€ ì—†ìŒ\n" + +#: pg_waldump.c:851 +#, c-format +msgid "%s: could not parse start WAL location \"%s\"\n" +msgstr "%s: \"%s\" WAL 위치를 í•´ì„í•  수 ì—†ìŒ\n" + +#: pg_waldump.c:861 +#, c-format +msgid "%s: could not parse timeline \"%s\"\n" +msgstr "%s: \"%s\" 타임ë¼ì¸ 번호를 í•´ì„í•  수 ì—†ìŒ\n" + +#: pg_waldump.c:873 +#, c-format +msgid "%s: could not parse \"%s\" as a transaction ID\n" +msgstr "%s: \"%s\" 문ìžì—´ì„ 트랜잭션 ID로 í•´ì„í•  수 ì—†ìŒ\n" + +#: pg_waldump.c:888 +#, c-format +msgid "%s: unrecognized argument to --stats: %s\n" +msgstr "%s: --stats ì˜µì…˜ê°’ì´ ë°”ë¥´ì§€ 않ìŒ: %s\n" + +#: pg_waldump.c:902 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë¥¼ 지정했습니다. (ì²˜ìŒ \"%s\")\n" + +#: pg_waldump.c:913 +#, c-format +msgid "%s: path \"%s\" could not be opened: %s\n" +msgstr "%s: \"%s\" 경로를 ì—´ 수 ì—†ìŒ: %s\n" + +#: pg_waldump.c:934 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "\"%s\" 디렉터리를 ì—´ 수 ì—†ìŒ: %s" + +#: pg_waldump.c:940 pg_waldump.c:973 +#, c-format +msgid "could not open file \"%s\"" +msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ" + +#: pg_waldump.c:951 +#, c-format +msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: %X/%X WAL 시작 위치가 \"%s\" 파ì¼ì— ì—†ìŒ\n" + +#: pg_waldump.c:980 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "%s ENDSEGê°€ %s STARTSEG ì•žì— ìžˆìŒ" + +#: pg_waldump.c:995 +#, c-format +msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: %X/%X WAL ë 위치가 \"%s\" 파ì¼ì— ì—†ìŒ\n" + +#: pg_waldump.c:1007 +#, c-format +msgid "%s: no start WAL location given\n" +msgstr "%s: 입력한 WAL 위치ì—서 시작할 수 ì—†ìŒ\n" + +#: pg_waldump.c:1016 +#, c-format +msgid "out of memory" +msgstr "메모리 부족" + +#: pg_waldump.c:1022 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "%X/%X 위치 ë’¤ì— ì˜¬ë°”ë¥¸ 레코드가 ì—†ìŒ" + +#: pg_waldump.c:1032 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "첫 레코드가 %X/%X ë’¤ì— ìžˆê³ , (%X/%X), %u ë°”ì´íЏ 건너 뜀\n" + +#: pg_waldump.c:1083 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "%X/%X 위치ì—서 WAL 레코드 오류: %s" + +#: pg_waldump.c:1093 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "ìžì œí•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보십시오.\n" diff --git a/src/bin/pg_waldump/po/ru.po b/src/bin/pg_waldump/po/ru.po new file mode 100644 index 00000000000..4c684afd0ee --- /dev/null +++ b/src/bin/pg_waldump/po/ru.po @@ -0,0 +1,276 @@ +# Russian message translation file for pg_waldump +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Alexander Lakhin , 2017. +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2017-09-27 06:14+0000\n" +"PO-Revision-Date: 2017-09-21 12:20+0300\n" +"Last-Translator: Alexander Lakhin \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: pg_waldump.c:82 +#, c-format +msgid "%s: FATAL: " +msgstr "%s: СБОЙ: " + +#: pg_waldump.c:288 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "не удалоÑÑŒ найти файл \"%s\": %s" + +#: pg_waldump.c:303 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "не удалоÑÑŒ перемеÑтитьÑÑ Ð² файле журнала %s к Ñмещению %u: %s" + +#: pg_waldump.c:323 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "не удалоÑÑŒ прочитать из файла журнала %s по Ñмещению %u, длина %d: %s" + +#: pg_waldump.c:702 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s декодирует и показывает журналы предзапиÑи PostgreSQL Ð´Ð»Ñ Ñ†ÐµÐ»ÐµÐ¹ отладки.\n" +"\n" + +#: pg_waldump.c:704 +#, c-format +msgid "Usage:\n" +msgstr "ИÑпользование:\n" + +#: pg_waldump.c:705 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [ПÐРÐМЕТР]... [ÐÐЧÐЛЬÐЫЙ_СЕГМЕÐТ [КОÐЕЧÐЫЙ_СЕГМЕÐТ]]\n" + +#: pg_waldump.c:706 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Параметры:\n" + +#: pg_waldump.c:707 +#, c-format +msgid "" +" -b, --bkp-details output detailed information about backup blocks\n" +msgstr "" +" -b, --bkp-details вывеÑти подробную информацию о копиÑÑ… Ñтраниц\n" + +# well-spelled: ПОЗЗÐП +#: pg_waldump.c:708 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr "" +" -e, --end=ПОЗЗÐП прекратить чтение в заданной позиции запиÑи в WAL\n" + +#: pg_waldump.c:709 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr "" +" -f, --follow повторÑть попытки Ñ‡Ñ‚ÐµÐ½Ð¸Ñ Ð¿Ð¾ доÑтижении конца WAL\n" + +#: pg_waldump.c:710 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N чиÑло выводимых запиÑей\n" + +# skip-rule: space-before-period +#: pg_waldump.c:711 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" +msgstr "" +" -p, --path=ПУТЬ каталог, где нужно иÑкать файлы Ñегментов журнала, " +"или\n" +" каталог Ñ Ð¿Ð¾Ð´ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ ./pg_wal, Ñодержащим такие " +"файлы\n" +" (по умолчанию: текущий каталог,\n" +" ./pg_wal, $PGDATA/pg_wal)\n" + +# well-spelled: МÐГР +#: pg_waldump.c:714 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" +msgstr "" +" -r, --rmgr=МÐГР выводить запиÑи только менеджера реÑурÑов МÐГР;\n" +" Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра ÑпиÑка доÑтупных менеджеров реÑурÑов\n" +" укажите --rmgr=list\n" + +# well-spelled: ПОЗЗÐП +#: pg_waldump.c:716 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr "" +" -s, --start=ПОЗЗÐП начать чтение Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð¹ позиции запиÑи в WAL\n" + +# well-spelled: ЛВР +#: pg_waldump.c:717 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=ЛВР Ð»Ð¸Ð½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸, запиÑи которой будут прочитаны\n" +" (по умолчанию: 1 или линиÑ, определÑÐµÐ¼Ð°Ñ " +"аргументом\n" +" ÐÐЧÐЛЬÐЫЙ_СЕГМЕÐТ)\n" + +#: pg_waldump.c:719 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version показать верÑию и выйти\n" + +#: pg_waldump.c:720 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr "" +" -x, --xid=XID выводить только запиÑи Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ñ‹Ð¼\n" +" идентификатором транзакции\n" + +#: pg_waldump.c:721 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] показывать ÑтатиÑтику вмеÑто запиÑей\n" +" (также возможно получить ÑтатиÑтику по запиÑÑм)\n" + +#: pg_waldump.c:723 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help показать Ñту Ñправку и выйти\n" + +#: pg_waldump.c:782 +#, c-format +msgid "%s: no arguments specified\n" +msgstr "%s: аргументы не указаны\n" + +#: pg_waldump.c:797 +#, c-format +msgid "%s: could not parse end WAL location \"%s\"\n" +msgstr "%s: не удалоÑÑŒ разобрать конечную позицию в WAL \"%s\"\n" + +#: pg_waldump.c:813 +#, c-format +msgid "%s: could not parse limit \"%s\"\n" +msgstr "%s: не удалоÑÑŒ разобрать предел в \"%s\"\n" + +#: pg_waldump.c:842 +#, c-format +msgid "%s: resource manager \"%s\" does not exist\n" +msgstr "%s: менеджер реÑурÑов \"%s\" не ÑущеÑтвует\n" + +#: pg_waldump.c:851 +#, c-format +msgid "%s: could not parse start WAL location \"%s\"\n" +msgstr "%s: не удалоÑÑŒ разобрать начальную позицию в WAL \"%s\"\n" + +#: pg_waldump.c:861 +#, c-format +msgid "%s: could not parse timeline \"%s\"\n" +msgstr "%s: не удалоÑÑŒ разобрать линию времени в \"%s\"\n" + +#: pg_waldump.c:873 +#, c-format +msgid "%s: could not parse \"%s\" as a transaction ID\n" +msgstr "%s: не удалоÑÑŒ разобрать в \"%s\" идентификатор транзакции\n" + +#: pg_waldump.c:888 +#, c-format +msgid "%s: unrecognized argument to --stats: %s\n" +msgstr "%s: нераÑпознанный аргумент ключа --stats: %s\n" + +#: pg_waldump.c:902 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: Ñлишком много аргументов командной Ñтроки (первый: \"%s\")\n" + +#: pg_waldump.c:913 +#, c-format +msgid "%s: path \"%s\" could not be opened: %s\n" +msgstr "%s: не удалоÑÑŒ открыть путь \"%s\": %s\n" + +#: pg_waldump.c:934 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "не удалоÑÑŒ открыть каталог \"%s\": %s" + +#: pg_waldump.c:940 pg_waldump.c:973 +#, c-format +msgid "could not open file \"%s\"" +msgstr "не удалоÑÑŒ открыть файл \"%s\"" + +#: pg_waldump.c:951 +#, c-format +msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² WAL %X/%X находитÑÑ Ð½Ðµ в файле \"%s\"\n" + +#: pg_waldump.c:980 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "КОÐЕЧÐЫЙ_СЕГМЕÐТ %s меньше, чем ÐÐЧÐЛЬÐЫЙ_СЕГМЕÐТ %s" + +#: pg_waldump.c:995 +#, c-format +msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: ÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² WAL %X/%X находитÑÑ Ð½Ðµ в файле \"%s\"\n" + +#: pg_waldump.c:1007 +#, c-format +msgid "%s: no start WAL location given\n" +msgstr "%s: Ð½Ð°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð² WAL не задана.\n" + +#: pg_waldump.c:1016 +#, c-format +msgid "out of memory" +msgstr "нехватка памÑти" + +#: pg_waldump.c:1022 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "не удалоÑÑŒ найти дейÑтвительную запиÑÑŒ поÑле позиции %X/%X" + +#: pg_waldump.c:1032 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "" +"Ð¿ÐµÑ€Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ обнаружена поÑле %X/%X, в позиции %X/%X, пропуÑкаетÑÑ %u Б\n" +msgstr[1] "" +"Ð¿ÐµÑ€Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ обнаружена поÑле %X/%X, в позиции %X/%X, пропуÑкаетÑÑ %u Б\n" +msgstr[2] "" +"Ð¿ÐµÑ€Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ обнаружена поÑле %X/%X, в позиции %X/%X, пропуÑкаетÑÑ %u Б\n" + +#: pg_waldump.c:1083 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "ошибка в запиÑи WAL в позиции %X/%X: %s" + +#: pg_waldump.c:1093 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" diff --git a/src/bin/pg_waldump/po/sv.po b/src/bin/pg_waldump/po/sv.po index 4a6e69d98f6..67bbac6f406 100644 --- a/src/bin/pg_waldump/po/sv.po +++ b/src/bin/pg_waldump/po/sv.po @@ -1,59 +1,107 @@ # Swedish message translation file for pg_waldump # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-20 20:15+0000\n" -"PO-Revision-Date: 2017-07-20 22:49+0200\n" +"Project-Id-Version: pg_waldump (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-07 12:13+0000\n" +"PO-Revision-Date: 2019-04-29 14:19+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: pg_waldump.c:82 +#: ../../../src/common/logging.c:188 #, c-format -msgid "%s: FATAL: " -msgstr "%s: FATALT: " +msgid "fatal: " +msgstr "fatalt: " -#: pg_waldump.c:288 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: pg_waldump.c:148 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "kunde inte öppna fil \"%s\": %s" + +#: pg_waldump.c:205 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men headern i WAL-filen \"%s\" anger %d byte" +msgstr[1] "WAL-segmentstorlek mÃ¥ste vara en tvÃ¥potens mellan 1MB och 1GB men headern i WAL-filen \"%s\" anger %d byte" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "kunde inte läsa fil \"%s\": %s" + +#: pg_waldump.c:216 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "kunde inte läsa fil \"%s\": läste %d av %zu" + +#: pg_waldump.c:294 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "kunde inte lokalisera WAL-fil \"%s\"" + +#: pg_waldump.c:296 +#, c-format +msgid "could not find any WAL file" +msgstr "kunde inte hitta nÃ¥gra WAL-filer" + +#: pg_waldump.c:367 #, c-format msgid "could not find file \"%s\": %s" msgstr "kunde inte hitta filen \"%s\": %s" -#: pg_waldump.c:303 +#: pg_waldump.c:382 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "kunde inte söka i loggfil %s till offset %u: %s" + +#: pg_waldump.c:405 #, c-format -msgid "could not seek in log segment %s to offset %u: %s" -msgstr "kunde inte söka i loggsegment %s till offset %u: %s" +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "kunde inte läsa frÃ¥n loggfil %s, offset %u, längd %d: %s" -#: pg_waldump.c:323 +#: pg_waldump.c:408 #, c-format -msgid "could not read from log segment %s, offset %d, length %d: %s" -msgstr "kunde inte läsa frÃ¥n loggsegment %s, offset %d, längd %d: %s" +msgid "could not read from log file %s, offset %u: read %d of %zu" +msgstr "kunde inte läsa frÃ¥n loggfil %s, offset %u, läste %d av %zu" -#: pg_waldump.c:702 +#: pg_waldump.c:787 #, c-format msgid "" "%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" "\n" msgstr "%s avkodar och visar PostgreSQLs write-ahead-logg för debuggning.\n" -#: pg_waldump.c:704 +#: pg_waldump.c:789 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: pg_waldump.c:705 +#: pg_waldump.c:790 #, c-format msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" msgstr " %s [FLAGGA]... [STARTSEG [SLUTSEG]]\n" -#: pg_waldump.c:706 +#: pg_waldump.c:791 #, c-format msgid "" "\n" @@ -62,52 +110,52 @@ msgstr "" "\n" "Flaggor:\n" -#: pg_waldump.c:707 +#: pg_waldump.c:792 #, c-format msgid " -b, --bkp-details output detailed information about backup blocks\n" msgstr " -b, --bkp-details skriv detaljerad information om backupblock\n" -#: pg_waldump.c:708 +#: pg_waldump.c:793 #, c-format msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" msgstr " -e, --end=RECPTR stoppa läsning vid WAL-position RECPTR\n" -#: pg_waldump.c:709 +#: pg_waldump.c:794 #, c-format msgid " -f, --follow keep retrying after reaching end of WAL\n" msgstr " -f, --follow fortsätt försök efter att ha nÃ¥tt slutet av WAL\n" -#: pg_waldump.c:710 +#: pg_waldump.c:795 #, c-format msgid " -n, --limit=N number of records to display\n" msgstr " -n, --limit=N antal poster att visa\n" -#: pg_waldump.c:711 +#: pg_waldump.c:796 #, c-format msgid "" " -p, --path=PATH directory in which to find log segment files or a\n" " directory with a ./pg_wal that contains such files\n" -" (default: current directory, ./pg_wal, PGDATA/pg_wal)\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" msgstr "" " -p, --path=SÖKVÄG katalog där man hittar loggsegmentfiler eller en\n" " katalog med en ./pg_wal som innehÃ¥ller sÃ¥dana filer\n" -" (standard: aktuell katalog, ./pg_wal, PGDATA/pg_wal)\n" +" (standard: aktuell katalog, ./pg_wal, $PGDATA/pg_wal)\n" -#: pg_waldump.c:714 +#: pg_waldump.c:799 #, c-format msgid "" -" -r, --rmgr=RMGR only show records generated by resource manager RMGR\n" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" " use --rmgr=list to list valid resource manager names\n" msgstr "" -" -r, --rmgr=RMGR visa bara poster skapade av resurshanteraren RMGR\n" +" -r, --rmgr=RMGR visa bara poster skapade av resurshanteraren RMGR;\n" " använd --rmgr=list för att lista giltiga resurshanterarnamn\n" -#: pg_waldump.c:716 +#: pg_waldump.c:801 #, c-format msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" msgstr " -s, --start=RECPTR börja läsning vid WAL-position RECPTR\n" -#: pg_waldump.c:717 +#: pg_waldump.c:802 #, c-format msgid "" " -t, --timeline=TLI timeline from which to read log records\n" @@ -116,17 +164,17 @@ msgstr "" " -t, --timeline=TLI tidslinje frÃ¥n vilken vi läser loggposter\n" " (standard: 1 eller värdet som används i STARTSEG)\n" -#: pg_waldump.c:719 +#: pg_waldump.c:804 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_waldump.c:720 +#: pg_waldump.c:805 #, c-format -msgid " -x, --xid=XID only show records with TransactionId XID\n" -msgstr " -x, --xid=XID visa baras poster med TransactionId XID\n" +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID visa baras poster med transaktions-ID XID\n" -#: pg_waldump.c:721 +#: pg_waldump.c:806 #, c-format msgid "" " -z, --stats[=record] show statistics instead of records\n" @@ -135,112 +183,138 @@ msgstr "" " -z, --stats[=post] visa statistik istället för poster\n" " (alternativt, visa statistik per post)\n" -#: pg_waldump.c:723 +#: pg_waldump.c:808 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa den här hjälpen, avsluta sedan\n" -#: pg_waldump.c:782 +#: pg_waldump.c:809 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Rapportera fel till .\n" + +#: pg_waldump.c:883 #, c-format -msgid "%s: no arguments specified\n" -msgstr "%s: inga argument angivna\n" +msgid "no arguments specified" +msgstr "inga argument angivna" -#: pg_waldump.c:797 +#: pg_waldump.c:898 #, c-format -msgid "%s: could not parse end WAL location \"%s\"\n" -msgstr "%s: kunde inte parsa slut-WAL-position \"%s\"\n" +msgid "could not parse end WAL location \"%s\"" +msgstr "kunde inte parsa slut-WAL-position \"%s\"" -#: pg_waldump.c:813 +#: pg_waldump.c:910 #, c-format -msgid "%s: could not parse limit \"%s\"\n" -msgstr "%s: kunde inte parsa gränsen \"%s\"\n" +msgid "could not parse limit \"%s\"" +msgstr "kunde inte parsa gränsen \"%s\"" -#: pg_waldump.c:842 +#: pg_waldump.c:938 #, c-format -msgid "%s: resource manager \"%s\" does not exist\n" -msgstr "%s: resurshanterare \"%s\" finns inte\n" +msgid "resource manager \"%s\" does not exist" +msgstr "resurshanterare \"%s\" finns inte" -#: pg_waldump.c:851 +#: pg_waldump.c:947 #, c-format -msgid "%s: could not parse start WAL location \"%s\"\n" -msgstr "%s: kunde inte parsa start-WAL-position \"%s\"\n" +msgid "could not parse start WAL location \"%s\"" +msgstr "kunde inte parsa start-WAL-position \"%s\"" -#: pg_waldump.c:861 +#: pg_waldump.c:957 #, c-format -msgid "%s: could not parse timeline \"%s\"\n" -msgstr "%s: kunde inte parsa tidlinjen \"%s\"\n" +msgid "could not parse timeline \"%s\"" +msgstr "kunde inte parsa tidlinjen \"%s\"" -#: pg_waldump.c:873 +#: pg_waldump.c:964 #, c-format -msgid "%s: could not parse \"%s\" as a valid xid\n" -msgstr "%s: kunde inte parsa \"%s\" som en giltig xid\n" +msgid "could not parse \"%s\" as a transaction ID" +msgstr "kunde inte parsa \"%s\" som ett transaktions-ID" -#: pg_waldump.c:888 +#: pg_waldump.c:979 #, c-format -msgid "%s: unrecognized argument to --stats: %s\n" -msgstr "%s: okänt argument till --stats: %s\n" +msgid "unrecognized argument to --stats: %s" +msgstr "okänt argument till --stats: %s" -#: pg_waldump.c:902 +#: pg_waldump.c:992 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: pg_waldump.c:913 +#: pg_waldump.c:1002 #, c-format -msgid "%s: path \"%s\" cannot be opened: %s\n" -msgstr "%s: sökvägen \"%s\" kan inte öppnas: %s\n" +msgid "path \"%s\" could not be opened: %s" +msgstr "sökvägen \"%s\" kunde inte öppnas: %s" -#: pg_waldump.c:934 +#: pg_waldump.c:1023 #, c-format -msgid "cannot open directory \"%s\": %s" -msgstr "kan inte öppna katalogen \"%s\": %s" +msgid "could not open directory \"%s\": %s" +msgstr "kunde inte öppna katalog \"%s\": %s" -#: pg_waldump.c:940 pg_waldump.c:973 +#: pg_waldump.c:1030 pg_waldump.c:1061 #, c-format msgid "could not open file \"%s\"" msgstr "kunde inte öppna filen \"%s\"" -#: pg_waldump.c:951 +#: pg_waldump.c:1040 #, c-format -msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s: start-WAL-position %X/%X är inte i filen \"%s\"\n" +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "start-WAL-position %X/%X är inte i filen \"%s\"" -#: pg_waldump.c:980 +#: pg_waldump.c:1068 #, c-format msgid "ENDSEG %s is before STARTSEG %s" msgstr "SLUTSEG %s är före STARTSEG %s" -#: pg_waldump.c:995 +#: pg_waldump.c:1083 #, c-format -msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" -msgstr "%s: slut-WAL-position %X/%X är inte i filen \"%s\"\n" +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "slut-WAL-position %X/%X är inte i filen \"%s\"" -#: pg_waldump.c:1007 +#: pg_waldump.c:1096 #, c-format -msgid "%s: no start WAL location given\n" -msgstr "%s: ingen start-WAL-position angiven\n" +msgid "no start WAL location given" +msgstr "ingen start-WAL-position angiven" -#: pg_waldump.c:1016 +#: pg_waldump.c:1106 #, c-format msgid "out of memory" msgstr "slut pÃ¥ minne" -#: pg_waldump.c:1022 +#: pg_waldump.c:1112 #, c-format msgid "could not find a valid record after %X/%X" msgstr "kunde inte hitta en giltig post efter %X/%X" -#: pg_waldump.c:1032 +#: pg_waldump.c:1123 #, c-format -msgid "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" -msgstr "första posten efter %X/%X, vid %X/%X, hoppar över %u byte\n" +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "första posten efter %X/%X, vid %X/%X, hoppar över %u byte\n" +msgstr[1] "första posten efter %X/%X, vid %X/%X, hoppar över %u byte\n" -#: pg_waldump.c:1081 +#: pg_waldump.c:1174 #, c-format msgid "error in WAL record at %X/%X: %s" msgstr "fel i WAL-post vid %X/%X: %s" -#: pg_waldump.c:1091 +#: pg_waldump.c:1184 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" + +#~ msgid "%s: FATAL: " +#~ msgstr "%s: FATALT: " + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "otillräckligt med data i fil \"%s\"" + +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" + +#~ msgid "cannot open directory \"%s\": %s" +#~ msgstr "kan inte öppna katalogen \"%s\": %s" + +#~ msgid "could not seek in log segment %s to offset %u: %s" +#~ msgstr "kunde inte söka i loggsegment %s till offset %u: %s" diff --git a/src/bin/pg_waldump/po/tr.po b/src/bin/pg_waldump/po/tr.po new file mode 100644 index 00000000000..e572031f870 --- /dev/null +++ b/src/bin/pg_waldump/po/tr.po @@ -0,0 +1,306 @@ +# LANGUAGE message translation file for pg_waldump +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_waldump (PostgreSQL) package. +# FIRST AUTHOR , 2017. +# Abdullah Gülner , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:46+0000\n" +"PO-Revision-Date: 2019-06-12 17:17+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: pg_waldump.c:148 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "\"%s\" dosyası açılamıyor: %s" + +#: pg_waldump.c:205 +#, c-format +msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte" +msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes" +msgstr[0] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat \"%s\" WAL dosyasının baÅŸlığında (header) %d bayt belirtilmektedir" +msgstr[1] "WAL segment boyutu 1 MB ve 1GB arasında 2 nin üssü bir deÄŸer olmalıdır, fakat \"%s\" WAL dosyasının baÅŸlığında (header) %d bayt belirtilmektedir" + +#: pg_waldump.c:213 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "\"%s\" dosyası okunamadı: %s" + +#: pg_waldump.c:216 +#, c-format +msgid "could not read file \"%s\": read %d of %zu" +msgstr "\"%1$s\" dosyası okuma hatası: %3$zu nun %2$d si okundu" + +#: pg_waldump.c:294 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "\"%s\" WAL dosyasının yeri tespit edilemedi" + +#: pg_waldump.c:296 +#, c-format +msgid "could not find any WAL file" +msgstr "hiç WAL dosyası bulunamadı" + +#: pg_waldump.c:367 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "\"%s\" dosyası bulunamadı: %s" + +#: pg_waldump.c:382 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "%s log dosyasında aranamadı %u göreli konumuna (pfset) kadar: %s" + +#: pg_waldump.c:405 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "log dosyasından okunamadı %s, göreli konum (offset) %u, uzunluk %d: %s" + +#: pg_waldump.c:408 +#, c-format +msgid "could not read from log file %s, offset %u: read %d of %zu" +msgstr "%1$s log dosyasından okunamadı , göreli konum (offset) %2$u: %4$zu'nin %3$d'si okundu" + +#: pg_waldump.c:787 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s PostgreSQL write-ahead loglarını hata ayıklama için çözer (decode) ve görüntüler.\n" +"\n" + +#: pg_waldump.c:789 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: pg_waldump.c:790 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [SEÇENEK]... [BAÅžLAMASEG [BİTİŞSEG]]\n" + +#: pg_waldump.c:791 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: pg_waldump.c:792 +#, c-format +msgid " -b, --bkp-details output detailed information about backup blocks\n" +msgstr " -b, --bkp-details yedek blokları hakkında ayrıntılı bilgi görüntüler\n" + +#: pg_waldump.c:793 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR RECPTR WAL konumunda okumayı durdur\n" + +#: pg_waldump.c:794 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr " -f, --follow WAL sonuna ulaÅŸtıktan sonra denemeye devam et\n" + +#: pg_waldump.c:795 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N görüntülenecek kayıt sayısı\n" + +#: pg_waldump.c:796 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or a\n" +" directory with a ./pg_wal that contains such files\n" +" (default: current directory, ./pg_wal, $PGDATA/pg_wal)\n" +msgstr "" +" -p, --path=PATH log segment dosyalarının bulunacağı dizin veya\n" +" öyle dosyaları içeren ./pg_wal'li bir dizin \n" +" (varsayılan: geçerli dizin, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:799 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager RMGR;\n" +" use --rmgr=list to list valid resource manager names\n" +msgstr "" +" -r, --rmgr=RMGR sadece RMGR kaynak yöneticisi tarafından oluÅŸturulan kayıtları göster;\n" +" geçerli kaynak yöneticisi adlarını listelemek için --rmgr=list kullanın\n" + +#: pg_waldump.c:801 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR RECPTR WAL konumunda okumayı baÅŸlat\n" + +#: pg_waldump.c:802 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI log kayıtlarının okunacağı zaman çizelgesi\n" +" (varsayılan: 1 veya BAÅžLAMASEG'de belirtilen deÄŸer)\n" + +#: pg_waldump.c:804 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini görüntüle, sonra çık\n" + +#: pg_waldump.c:805 +#, c-format +msgid " -x, --xid=XID only show records with transaction ID XID\n" +msgstr " -x, --xid=XID sadece XID iÅŸlem ID'li kayıtları göster\n" + +#: pg_waldump.c:806 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] kayıtlar yerine istatistikleri göster\n" +" (opsiyonel olarak, kayıt bazında istatistikleri göster)\n" + +#: pg_waldump.c:808 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: pg_waldump.c:868 +#, c-format +msgid "no arguments specified" +msgstr "hiç argüman belirtilmemiÅŸ" + +#: pg_waldump.c:883 +#, c-format +msgid "could not parse end WAL location \"%s\"" +msgstr "bitiÅŸ WAL konumu \"%s\" ayrıştırılamadı" + +#: pg_waldump.c:899 +#, c-format +msgid "could not parse limit \"%s\"" +msgstr "\"%s\" limiti ayrıştırılamadı" + +#: pg_waldump.c:927 +#, c-format +msgid "resource manager \"%s\" does not exist" +msgstr "\"%s\" kaynak yöneticisi mevcut deÄŸil" + +#: pg_waldump.c:936 +#, c-format +msgid "could not parse start WAL location \"%s\"" +msgstr "baÅŸlama WAL konumu \"%s\" ayrıştırılamadı" + +#: pg_waldump.c:946 +#, c-format +msgid "could not parse timeline \"%s\"" +msgstr "\"%s\" zaman çizelgesi ayrıştırılamadı" + +#: pg_waldump.c:957 +#, c-format +msgid "could not parse \"%s\" as a transaction ID" +msgstr "\"%s\" bir iÅŸlem (transaction) ID'si olarak ayrıştırılamadı" + +#: pg_waldump.c:972 +#, c-format +msgid "unrecognized argument to --stats: %s" +msgstr "--stats için bilinmeyen argüman: %s" + +#: pg_waldump.c:985 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok fazla komut satırı argümanı var (ilki \"%s\")" + +#: pg_waldump.c:995 +#, c-format +msgid "path \"%s\" could not be opened: %s" +msgstr "\"%s\" yolu açılamadı: %s" + +#: pg_waldump.c:1016 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "\"%s\" dizini açılamadı: %s" + +#: pg_waldump.c:1023 pg_waldump.c:1054 +#, c-format +msgid "could not open file \"%s\"" +msgstr "\"%s\" dosyası açılamadı" + +#: pg_waldump.c:1033 +#, c-format +msgid "start WAL location %X/%X is not inside file \"%s\"" +msgstr "baÅŸlama WAL konumu %X/%X \"%s\" dosyası içinde yok" + +#: pg_waldump.c:1061 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "BİTİŞSEG %s BAÅžLAMASEG %s den önce" + +#: pg_waldump.c:1076 +#, c-format +msgid "end WAL location %X/%X is not inside file \"%s\"" +msgstr "bitiÅŸ WAL konumu %X/%X \"%s\" dosyası içinde yok" + +#: pg_waldump.c:1089 +#, c-format +msgid "no start WAL location given" +msgstr "baÅŸlama WAL konumu belirtilmemiÅŸ" + +#: pg_waldump.c:1099 +#, c-format +msgid "out of memory" +msgstr "yetersiz bellek" + +#: pg_waldump.c:1105 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "%X/%X den sonra geçerli bir kayıt bulunamadı" + +#: pg_waldump.c:1116 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "ilk kayıt %X/%X 'den sonra, %X/%X 'dedir, %u bayt atlanıyor\n" +msgstr[1] "ilk kayıt %X/%X 'den sonra, %X/%X 'dedir, %u bayt atlanıyor\n" + +#: pg_waldump.c:1167 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "%X/%X de WAL kaydında hata: %s" + +#: pg_waldump.c:1177 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın\n" + +#~ msgid "not enough data in file \"%s\"" +#~ msgstr "\"%s\" dosyasında yetersiz veri" + +#~ msgid "%s: FATAL: " +#~ msgstr "%s: KRİTİK (FATAL): " diff --git a/src/bin/pg_waldump/po/vi.po b/src/bin/pg_waldump/po/vi.po new file mode 100644 index 00000000000..037d9955842 --- /dev/null +++ b/src/bin/pg_waldump/po/vi.po @@ -0,0 +1,309 @@ +# LANGUAGE message translation file for pg_waldump +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pg_waldump (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pg_waldump (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:16+0000\n" +"PO-Revision-Date: 2018-05-04 22:19+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Language: vi_VN\n" + +#: pg_waldump.c:85 +#, c-format +msgid "%s: FATAL: " +msgstr "%s: FATAL: " + +#: pg_waldump.c:166 +#, c-format +msgid "could not open file \"%s\": %s" +msgstr "không thể mở tệp \"%s\": %s" + +#: pg_waldump.c:221 +#, c-format +msgid "" +"WAL segment size must be a power of two between 1MB and 1GB, but the WAL " +"file \"%s\" header specifies %d bytes" +msgstr "" +"Kích thước phân Ä‘oạn WAL phải là lÅ©y thừa cá»§a hai giá trị từ 1MB đến " +"1GB, nhưng header cá»§a tệp WAL \"%s\" chỉ định %d bytes" + +#: pg_waldump.c:227 +#, c-format +msgid "could not read file \"%s\": %s" +msgstr "không thể Ä‘á»c tệp \"%s\": %s" + +#: pg_waldump.c:230 +#, c-format +msgid "not enough data in file \"%s\"" +msgstr "không đủ dữ liệu trong tệp \"%s\"" + +#: pg_waldump.c:307 +#, c-format +msgid "could not locate WAL file \"%s\"" +msgstr "không thể định vị tệp WAL \"%s\"" + +#: pg_waldump.c:309 +#, c-format +msgid "could not find any WAL file" +msgstr "không thể tìm thấy tệp WAL nào cả" + +#: pg_waldump.c:380 +#, c-format +msgid "could not find file \"%s\": %s" +msgstr "không thể tìm được tệp \"%s\": %s" + +#: pg_waldump.c:395 +#, c-format +msgid "could not seek in log file %s to offset %u: %s" +msgstr "không thể tìm kiếm trong tệp log %s tá»›i offset %u: %s" + +#: pg_waldump.c:415 +#, c-format +msgid "could not read from log file %s, offset %u, length %d: %s" +msgstr "không thể Ä‘á»c từ tệp log %s, offset %u, độ dài %d: %s" + +#: pg_waldump.c:794 +#, c-format +msgid "" +"%s decodes and displays PostgreSQL write-ahead logs for debugging.\n" +"\n" +msgstr "" +"%s giải mã và hiển thị các bản ghi WAL cá»§a PostgreSQL cho debug.\n" +"\n" + +#: pg_waldump.c:796 +#, c-format +msgid "Usage:\n" +msgstr "Cách sá»­ dụng:\n" + +#: pg_waldump.c:797 +#, c-format +msgid " %s [OPTION]... [STARTSEG [ENDSEG]]\n" +msgstr " %s [OPTION]... [STARTSEG [ENDSEG]]\n" + +#: pg_waldump.c:798 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Tùy chá»n:\n" + +#: pg_waldump.c:799 +#, c-format +msgid "" +" -b, --bkp-details output detailed information about backup " +"blocks\n" +msgstr "" +" -b, --bkp-details xuất thông tin chi tiết vá» các khối sao lưu\n" + +#: pg_waldump.c:800 +#, c-format +msgid " -e, --end=RECPTR stop reading at WAL location RECPTR\n" +msgstr " -e, --end=RECPTR dừng Ä‘á»c WAL tại vị trí RECPTR\n" + +#: pg_waldump.c:801 +#, c-format +msgid " -f, --follow keep retrying after reaching end of WAL\n" +msgstr "" +" -f, --follow tiếp tục thá»­ lại sau khi đến tá»›i vị trí cuối " +"cá»§a WAL\n" + +#: pg_waldump.c:802 +#, c-format +msgid " -n, --limit=N number of records to display\n" +msgstr " -n, --limit=N số bản ghi để hiển thị\n" + +#: pg_waldump.c:803 +#, c-format +msgid "" +" -p, --path=PATH directory in which to find log segment files or " +"a\n" +" directory with a ./pg_wal that contains such " +"files\n" +" (default: current directory, ./pg_wal, $PGDATA/" +"pg_wal)\n" +msgstr "" +" -p, --path=PATH thư mục để tìm tệp phân Ä‘oạn log hay thư mục \n" +" chứa những tệp đó như là ./pg_wal (mặc định: " +"thư mục \n" +" hiện tại, ./pg_wal, $PGDATA/pg_wal)\n" + +#: pg_waldump.c:806 +#, c-format +msgid "" +" -r, --rmgr=RMGR only show records generated by resource manager " +"RMGR;\n" +" use --rmgr=list to list valid resource manager " +"names\n" +msgstr "" +" -r, --rmgr=RMGR chỉ hiển thị các bản ghi được tạo bởi trình " +"quản lý \n" +" tài nguyên RMGR; sá»­ dụng --rmgr=list để hiểu " +"thị\n" +" tên các trình quản lý tài nguyên hợp lệ\n" + +#: pg_waldump.c:808 +#, c-format +msgid " -s, --start=RECPTR start reading at WAL location RECPTR\n" +msgstr " -s, --start=RECPTR bắt đầu Ä‘á»c tại vị trí RECPTR cá»§a WAL\n" + +#: pg_waldump.c:809 +#, c-format +msgid "" +" -t, --timeline=TLI timeline from which to read log records\n" +" (default: 1 or the value used in STARTSEG)\n" +msgstr "" +" -t, --timeline=TLI Ä‘á»c bản ghi vá»›i giá trị timeline chỉ định\n" +" (mặc định: 1 hoặc giá trị sá»­ dụng trong " +"STARTSEG)\n" + +#: pg_waldump.c:811 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr "" +" -V, --version hiển thị thông tin phiên bản, sau đó thoát\n" + +#: pg_waldump.c:812 +#, c-format +msgid "" +" -x, --xid=XID only show records with transaction ID XID\n" +msgstr "" +" -x, --xid=XID chỉ xuất bản ghi vá»›i transaction ID là XID\n" + +#: pg_waldump.c:813 +#, c-format +msgid "" +" -z, --stats[=record] show statistics instead of records\n" +" (optionally, show per-record statistics)\n" +msgstr "" +" -z, --stats[=record] hiển thị số liệu thống kê thay vì bản ghi\n" +" (tùy chá»n, hiển thị số liệu thống kê cho má»—i " +"bản ghi)\n" + +#: pg_waldump.c:815 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help hiện thị trợ giúp này, sau đó kết thúc\n" + +#: pg_waldump.c:874 +#, c-format +msgid "%s: no arguments specified\n" +msgstr "%s: không có đối số nào được chỉ định\n" + +#: pg_waldump.c:889 +#, c-format +msgid "%s: could not parse end WAL location \"%s\"\n" +msgstr "%s: không thể phân tích cú pháp vị trí kết thúc WAL \"%s\"\n" + +#: pg_waldump.c:905 +#, c-format +msgid "%s: could not parse limit \"%s\"\n" +msgstr "%s: không thể phân tích giá»›i hạn\"%s\"\n" + +#: pg_waldump.c:934 +#, c-format +msgid "%s: resource manager \"%s\" does not exist\n" +msgstr "%s: trình quản lý tài nguyên \"%s\" không tồn tại\n" + +#: pg_waldump.c:943 +#, c-format +msgid "%s: could not parse start WAL location \"%s\"\n" +msgstr "" +"%s: không thể phân tích cú pháp vị trí bắt đầu WAL \"%s\"\n" +"\n" + +#: pg_waldump.c:953 +#, c-format +msgid "%s: could not parse timeline \"%s\"\n" +msgstr "%s: không thể phân tích timeline \"%s\"\n" + +#: pg_waldump.c:965 +#, c-format +msgid "%s: could not parse \"%s\" as a transaction ID\n" +msgstr "%s: không thể phân tích \"%s\" như là má»™t transaction ID\n" + +#: pg_waldump.c:980 +#, c-format +msgid "%s: unrecognized argument to --stats: %s\n" +msgstr "%s: đối số không được công nhận cho tùy chá»n --stats: %s\n" + +#: pg_waldump.c:994 +#, c-format +msgid "%s: too many command-line arguments (first is \"%s\")\n" +msgstr "%s: có quá nhiá»u đối số dòng lệnh (đầu tiên là \"%s\")\n" + +#: pg_waldump.c:1005 +#, c-format +msgid "%s: path \"%s\" could not be opened: %s\n" +msgstr "%s: đưá»ng dẫn \"%s\" không thể mở được %s\n" + +#: pg_waldump.c:1026 +#, c-format +msgid "could not open directory \"%s\": %s" +msgstr "không thể mở thư mục \"%s\": %s" + +#: pg_waldump.c:1033 pg_waldump.c:1066 +#, c-format +msgid "could not open file \"%s\"" +msgstr "không thể mở tệp \"%s\"" + +#: pg_waldump.c:1044 +#, c-format +msgid "%s: start WAL location %X/%X is not inside file \"%s\"\n" +msgstr "%s: vị trí bắt đầu WAL %X/%X không nằm trong tệp \"%s\"\n" + +#: pg_waldump.c:1073 +#, c-format +msgid "ENDSEG %s is before STARTSEG %s" +msgstr "ENDSEG %s ở trước STARTSEG %s" + +#: pg_waldump.c:1089 +#, c-format +msgid "%s: end WAL location %X/%X is not inside file \"%s\"\n" +msgstr "" +"%s: vị trí kết thúc WAL %X/%X không nằm trong tệp \"%s\"\n" +"\n" + +#: pg_waldump.c:1103 +#, c-format +msgid "%s: no start WAL location given\n" +msgstr "%s: không có vị trí bắt đầu WAL được chỉ định\n" + +#: pg_waldump.c:1113 +#, c-format +msgid "out of memory" +msgstr "hết bá»™ nhá»›" + +#: pg_waldump.c:1119 +#, c-format +msgid "could not find a valid record after %X/%X" +msgstr "không thể tìm thấy bản ghi hợp lệ sau %X/%X" + +#: pg_waldump.c:1130 +#, c-format +msgid "first record is after %X/%X, at %X/%X, skipping over %u byte\n" +msgid_plural "" +"first record is after %X/%X, at %X/%X, skipping over %u bytes\n" +msgstr[0] "bản ghi đầu tiên sau %X/%X, at %X/%X, bá» qua %u bytes\n" + +#: pg_waldump.c:1181 +#, c-format +msgid "error in WAL record at %X/%X: %s" +msgstr "lá»—i trong bản ghi WAL ở %X/%X: %s" + +#: pg_waldump.c:1191 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Hãy thá»­ \"%s --help\" để biết thêm thông tin.\n" diff --git a/src/bin/pg_waldump/rmgrdesc.h b/src/bin/pg_waldump/rmgrdesc.h index d5f6923e5ce..42f8483b482 100644 --- a/src/bin/pg_waldump/rmgrdesc.h +++ b/src/bin/pg_waldump/rmgrdesc.h @@ -8,6 +8,7 @@ #ifndef RMGRDESC_H #define RMGRDESC_H +#include "access/xlogreader.h" #include "lib/stringinfo.h" typedef struct RmgrDescData diff --git a/src/bin/pg_waldump/t/001_basic.pl b/src/bin/pg_waldump/t/001_basic.pl new file mode 100644 index 00000000000..5af0ce94fb8 --- /dev/null +++ b/src/bin/pg_waldump/t/001_basic.pl @@ -0,0 +1,8 @@ +use strict; +use warnings; +use TestLib; +use Test::More tests => 8; + +program_help_ok('pg_waldump'); +program_version_ok('pg_waldump'); +program_options_handling_ok('pg_waldump'); diff --git a/src/bin/pgbench/exprparse.y b/src/bin/pgbench/exprparse.y index 8447e14d141..17c9ec32c50 100644 --- a/src/bin/pgbench/exprparse.y +++ b/src/bin/pgbench/exprparse.y @@ -4,7 +4,7 @@ * exprparse.y * bison grammar for a simple expression syntax * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pgbench/exprparse.y @@ -61,7 +61,8 @@ static PgBenchExpr *make_case(yyscan_t yyscanner, PgBenchExprList *when_then_lis %type BOOLEAN_CONST %type VARIABLE FUNCTION -%token NULL_CONST INTEGER_CONST DOUBLE_CONST BOOLEAN_CONST VARIABLE FUNCTION +%token NULL_CONST INTEGER_CONST MAXINT_PLUS_ONE_CONST DOUBLE_CONST +%token BOOLEAN_CONST VARIABLE FUNCTION %token AND_OP OR_OP NOT_OP NE_OP LE_OP GE_OP LS_OP RS_OP IS_OP %token CASE_KW WHEN_KW THEN_KW ELSE_KW END_KW @@ -90,6 +91,9 @@ expr: '(' expr ')' { $$ = $2; } /* unary minus "-x" implemented as "0 - x" */ | '-' expr %prec UNARY { $$ = make_op(yyscanner, "-", make_integer_constant(0), $2); } + /* special PG_INT64_MIN handling, only after a unary minus */ + | '-' MAXINT_PLUS_ONE_CONST %prec UNARY + { $$ = make_integer_constant(PG_INT64_MIN); } /* binary ones complement "~x" implemented as 0xffff... xor x" */ | '~' expr { $$ = make_op(yyscanner, "#", make_integer_constant(~INT64CONST(0)), $2); } @@ -366,15 +370,6 @@ static const struct { "hash_fnv1a", PGBENCH_NARGS_HASH, PGBENCH_HASH_FNV1A }, - { - "hash", PGBENCH_NARGS_HASH, PGBENCH_HASH_MURMUR2 - }, - { - "hash_murmur2", PGBENCH_NARGS_HASH, PGBENCH_HASH_MURMUR2 - }, - { - "hash_fnv1a", PGBENCH_NARGS_HASH, PGBENCH_HASH_FNV1A - }, /* keep as last array element */ { NULL, 0, 0 @@ -476,7 +471,7 @@ make_func(yyscan_t yyscanner, int fnumber, PgBenchExprList *args) /* hash functions with optional seed argument */ case PGBENCH_NARGS_HASH: - if (len > 2) + if (len < 1 || len > 2) expr_yyerror_more(yyscanner, "unexpected number of arguments", PGBENCH_FUNCTIONS[fnumber].fname); diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l index 5c1bd881283..e9020ad231a 100644 --- a/src/bin/pgbench/exprscan.l +++ b/src/bin/pgbench/exprscan.l @@ -15,7 +15,7 @@ * * Note that this lexer operates within the framework created by psqlscan.l, * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/pgbench/exprscan.l @@ -69,7 +69,7 @@ nonspace [^ \t\r\f\v\n] newline [\n] /* Line continuation marker */ -continuation \\{newline} +continuation \\\r?{newline} /* case insensitive keywords */ and [Aa][Nn][Dd] @@ -122,8 +122,12 @@ notnull [Nn][Oo][Tt][Nn][Uu][Ll][Ll] * a continuation marker just after a word: */ {nonspace}+{continuation} { - /* Found "word\\\n", emit and return just "word" */ - psqlscan_emit(cur_state, yytext, yyleng - 2); + /* Found "word\\\r?\n", emit and return just "word" */ + int wordlen = yyleng - 2; + if (yytext[wordlen] == '\r') + wordlen--; + Assert(yytext[wordlen] == '\\'); + psqlscan_emit(cur_state, yytext, wordlen); return 1; } @@ -191,16 +195,31 @@ notnull [Nn][Oo][Tt][Nn][Uu][Ll][Ll] yylval->bval = false; return BOOLEAN_CONST; } +"9223372036854775808" { + /* + * Special handling for PG_INT64_MIN, which can't + * accurately be represented here, as the minus sign is + * lexed separately and INT64_MIN can't be represented as + * a positive integer. + */ + return MAXINT_PLUS_ONE_CONST; + } {digit}+ { - yylval->ival = strtoint64(yytext); + if (!strtoint64(yytext, true, &yylval->ival)) + expr_yyerror_more(yyscanner, "bigint constant overflow", + strdup(yytext)); return INTEGER_CONST; } {digit}+(\.{digit}*)?([eE][-+]?{digit}+)? { - yylval->dval = atof(yytext); + if (!strtodouble(yytext, true, &yylval->dval)) + expr_yyerror_more(yyscanner, "double constant overflow", + strdup(yytext)); return DOUBLE_CONST; } \.{digit}+([eE][-+]?{digit}+)? { - yylval->dval = atof(yytext); + if (!strtodouble(yytext, true, &yylval->dval)) + expr_yyerror_more(yyscanner, "double constant overflow", + strdup(yytext)); return DOUBLE_CONST; } {alpha}{alnum}* { diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index fd1856837a2..e72ad0036e1 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -5,7 +5,7 @@ * Originally written by Tatsuo Ishii and enhanced by many contributors. * * src/bin/pgbench/pgbench.c - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * ALL RIGHTS RESERVED; * * Permission to use, copy, modify, and distribute this software and its @@ -28,12 +28,13 @@ */ #ifdef WIN32 -#define FD_SETSIZE 1024 /* set before winsock2.h is included */ -#endif /* ! WIN32 */ +#define FD_SETSIZE 1024 /* must set before winsock2.h is included */ +#endif #include "postgres_fe.h" +#include "common/int.h" +#include "common/logging.h" #include "fe_utils/conditional.h" - #include "getopt_long.h" #include "libpq-fe.h" #include "portability/instr_time.h" @@ -45,12 +46,21 @@ #include #include #include +#ifdef HAVE_SYS_RESOURCE_H +#include /* for getrlimit */ +#endif + +/* For testing, PGBENCH_USE_SELECT can be defined to force use of that code */ +#if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT) +#define POLL_USING_PPOLL +#ifdef HAVE_POLL_H +#include +#endif +#else /* no ppoll(), so use select() */ +#define POLL_USING_SELECT #ifdef HAVE_SYS_SELECT_H #include #endif - -#ifdef HAVE_SYS_RESOURCE_H -#include /* for getrlimit */ #endif #ifndef M_PI @@ -67,8 +77,36 @@ #define FNV_PRIME UINT64CONST(0x100000001b3) #define FNV_OFFSET_BASIS UINT64CONST(0xcbf29ce484222325) #define MM2_MUL UINT64CONST(0xc6a4a7935bd1e995) +#define MM2_MUL_TIMES_8 UINT64CONST(0x35253c9ade8f4ca8) #define MM2_ROT 47 +/* + * Multi-platform socket set implementations + */ + +#ifdef POLL_USING_PPOLL +#define SOCKET_WAIT_METHOD "ppoll" + +typedef struct socket_set +{ + int maxfds; /* allocated length of pollfds[] array */ + int curfds; /* number currently in use */ + struct pollfd pollfds[FLEXIBLE_ARRAY_MEMBER]; +} socket_set; + +#endif /* POLL_USING_PPOLL */ + +#ifdef POLL_USING_SELECT +#define SOCKET_WAIT_METHOD "select" + +typedef struct socket_set +{ + int maxfd; /* largest FD currently set in fds */ + fd_set fds; +} socket_set; + +#endif /* POLL_USING_SELECT */ + /* * Multi-platform pthread implementations */ @@ -92,22 +130,15 @@ static int pthread_join(pthread_t th, void **thread_return); /******************************************************************** * some configurable parameters */ -/* max number of clients allowed */ -#ifdef FD_SETSIZE -#define MAXCLIENTS (FD_SETSIZE - 10) -#else -#define MAXCLIENTS 1024 -#endif - #define DEFAULT_INIT_STEPS "dtgvp" /* default -I setting */ #define LOG_STEP_SECONDS 5 /* seconds between log messages */ #define DEFAULT_NXACTS 10 /* default nxacts */ -#define ZIPF_CACHE_SIZE 15 /* cache cells number */ - #define MIN_GAUSSIAN_PARAM 2.0 /* minimum parameter for gauss */ -#define MAX_ZIPFIAN_PARAM 1000 /* maximum parameter for zipfian */ + +#define MIN_ZIPFIAN_PARAM 1.001 /* minimum parameter for zipfian */ +#define MAX_ZIPFIAN_PARAM 1000.0 /* maximum parameter for zipfian */ int nxacts = 0; /* number of transactions per client */ int duration = 0; /* duration in seconds */ @@ -139,7 +170,7 @@ double sample_rate = 0.0; * When threads are throttled to a given rate limit, this is the target delay * to reach that rate in usec. 0 is the default and means no throttling. */ -int64 throttle_delay = 0; +double throttle_delay = 0; /* * Transactions which take longer than this limit (in usec) are counted as @@ -155,8 +186,25 @@ int64 latency_limit = 0; char *tablespace = NULL; char *index_tablespace = NULL; -/* random seed used when calling srandom() */ -int64 random_seed = -1; +/* + * Number of "pgbench_accounts" partitions. 0 is the default and means no + * partitioning. + */ +static int partitions = 0; + +/* partitioning strategy for "pgbench_accounts" */ +typedef enum +{ + PART_NONE, /* no partitioning */ + PART_RANGE, /* range partitioning */ + PART_HASH /* hash partitioning */ +} partition_method_t; + +static partition_method_t partition_method = PART_NONE; +static const char *PARTITION_METHOD[] = {"none", "range", "hash"}; + +/* random seed used to initialize base_random_sequence */ +int64 random_seed = -1; /* * end of configurable parameters @@ -186,7 +234,7 @@ bool progress_timestamp = false; /* progress report with Unix time */ int nclients = 1; /* number of clients */ int nthreads = 1; /* number of threads */ bool is_connect; /* establish connection for each transaction */ -bool is_latencies; /* report per-command latencies */ +bool report_per_command; /* report per-command latencies */ int main_pid; /* main process id used in log filename */ char *pghost = ""; @@ -249,6 +297,17 @@ typedef struct StatsData SimpleStats lag; } StatsData; +/* + * Struct to keep random state. + */ +typedef struct RandomState +{ + unsigned short xseed[3]; +} RandomState; + +/* Various random sequences are initialized from this one. */ +static RandomState base_random_sequence; + /* * Connection state machine states. */ @@ -256,26 +315,33 @@ typedef enum { /* * The client must first choose a script to execute. Once chosen, it can - * either be throttled (state CSTATE_START_THROTTLE under --rate) or start - * right away (state CSTATE_START_TX). + * either be throttled (state CSTATE_PREPARE_THROTTLE under --rate), start + * right away (state CSTATE_START_TX) or not start at all if the timer was + * exceeded (state CSTATE_FINISHED). */ CSTATE_CHOOSE_SCRIPT, /* - * In CSTATE_START_THROTTLE state, we calculate when to begin the next - * transaction, and advance to CSTATE_THROTTLE. CSTATE_THROTTLE state - * sleeps until that moment. (If throttling is not enabled, doCustom() - * falls directly through from CSTATE_START_THROTTLE to CSTATE_START_TX.) + * CSTATE_START_TX performs start-of-transaction processing. Establishes + * a new connection for the transaction in --connect mode, records the + * transaction start time, and proceed to the first command. + * + * Note: once a script is started, it will either error or run till its + * end, where it may be interrupted. It is not interrupted while running, + * so pgbench --time is to be understood as tx are allowed to start in + * that time, and will finish when their work is completed. */ - CSTATE_START_THROTTLE, - CSTATE_THROTTLE, + CSTATE_START_TX, /* - * CSTATE_START_TX performs start-of-transaction processing. Establishes - * a new connection for the transaction, in --connect mode, and records - * the transaction start time. + * In CSTATE_PREPARE_THROTTLE state, we calculate when to begin the next + * transaction, and advance to CSTATE_THROTTLE. CSTATE_THROTTLE state + * sleeps until that moment, then advances to CSTATE_START_TX, or + * CSTATE_FINISHED if the next transaction would start beyond the end of + * the run. */ - CSTATE_START_TX, + CSTATE_PREPARE_THROTTLE, + CSTATE_THROTTLE, /* * We loop through these states, to process each command in the script: @@ -284,10 +350,8 @@ typedef enum * command, the command is sent to the server, and we move to * CSTATE_WAIT_RESULT state. On a \sleep meta-command, the timer is set, * and we enter the CSTATE_SLEEP state to wait for it to expire. Other - * meta-commands are executed immediately. - * - * CSTATE_SKIP_COMMAND for conditional branches which are not executed, - * quickly skip commands that do not need any evaluation. + * meta-commands are executed immediately. If the command about to start + * is actually beyond the end of the script, advance to CSTATE_END_TX. * * CSTATE_WAIT_RESULT waits until we get a result set back from the server * for the current command. @@ -296,19 +360,25 @@ typedef enum * * CSTATE_END_COMMAND records the end-of-command timestamp, increments the * command counter, and loops back to CSTATE_START_COMMAND state. + * + * CSTATE_SKIP_COMMAND is used by conditional branches which are not + * executed. It quickly skip commands that do not need any evaluation. + * This state can move forward several commands, till there is something + * to do or the end of the script. */ CSTATE_START_COMMAND, - CSTATE_SKIP_COMMAND, CSTATE_WAIT_RESULT, CSTATE_SLEEP, CSTATE_END_COMMAND, + CSTATE_SKIP_COMMAND, /* - * CSTATE_END_TX performs end-of-transaction processing. Calculates - * latency, and logs the transaction. In --connect mode, closes the - * current connection. Chooses the next script to execute and starts over - * in CSTATE_START_THROTTLE state, or enters CSTATE_FINISHED if we have no - * more work to do. + * CSTATE_END_TX performs end-of-transaction processing. It calculates + * latency, and logs the transaction. In --connect mode, it closes the + * current connection. + * + * Then either starts over in CSTATE_CHOOSE_SCRIPT, or enters + * CSTATE_FINISHED if we have no more work to do. */ CSTATE_END_TX, @@ -330,6 +400,12 @@ typedef struct ConnectionStateEnum state; /* state machine's current state. */ ConditionalStack cstack; /* enclosing conditionals state */ + /* + * Separate randomness for each client. This is used for random functions + * PGBENCH_RANDOM_* during the execution of the script. + */ + RandomState cs_func_rs; + int use_file; /* index in sql_script for this client */ int command; /* command number in script */ @@ -351,35 +427,6 @@ typedef struct int ecnt; /* error count */ } CState; -/* - * Cache cell for zipfian_random call - */ -typedef struct -{ - /* cell keys */ - double s; /* s - parameter of zipfan_random function */ - int64 n; /* number of elements in range (max - min + 1) */ - - double harmonicn; /* generalizedHarmonicNumber(n, s) */ - double alpha; - double beta; - double eta; - - uint64 last_used; /* last used logical time */ -} ZipfCell; - -/* - * Zipf cache for zeta values - */ -typedef struct -{ - uint64 current; /* counter for LRU cache replacement algorithm */ - - int nb_cells; /* number of filled cells */ - int overflowCount; /* number of cache overflows */ - ZipfCell cells[ZIPF_CACHE_SIZE]; -} ZipfCache; - /* * Thread state */ @@ -389,11 +436,18 @@ typedef struct pthread_t thread; /* thread handle */ CState *state; /* array of CState */ int nstate; /* length of state[] */ - unsigned short random_state[3]; /* separate randomness for each thread */ + + /* + * Separate randomness for each thread. Each thread option uses its own + * random state to make all of them independent of each other and + * therefore deterministic at the thread level. + */ + RandomState ts_choose_rs; /* random state for selecting a script */ + RandomState ts_throttle_rs; /* random state for transaction throttling */ + RandomState ts_sample_rs; /* random state for log sampling */ + int64 throttle_trigger; /* previous/next throttling (us) */ FILE *logfile; /* where to log, or NULL */ - ZipfCache zipf_cache; /* for thread-safe zipfian random number - * generation */ /* per thread collected stats */ instr_time start_time; /* thread start time */ @@ -409,7 +463,12 @@ typedef struct */ #define SQL_COMMAND 1 #define META_COMMAND 2 -#define MAX_ARGS 10 + +/* + * max number of backslash command arguments or SQL variables, + * including the command or SQL statement itself + */ +#define MAX_ARGS 256 typedef enum MetaCommand { @@ -418,6 +477,7 @@ typedef enum MetaCommand META_SETSHELL, /* \setshell */ META_SHELL, /* \shell */ META_SLEEP, /* \sleep */ + META_GSET, /* \gset */ META_IF, /* \if */ META_ELIF, /* \elif */ META_ELSE, /* \else */ @@ -435,16 +495,35 @@ typedef enum QueryMode static QueryMode querymode = QUERY_SIMPLE; static const char *QUERYMODE[] = {"simple", "extended", "prepared"}; -typedef struct +/* + * struct Command represents one command in a script. + * + * lines The raw, possibly multi-line command text. Variable substitution + * not applied. + * first_line A short, single-line extract of 'lines', for error reporting. + * type SQL_COMMAND or META_COMMAND + * meta The type of meta-command, or META_NONE if command is SQL + * argc Number of arguments of the command, 0 if not yet processed. + * argv Command arguments, the first of which is the command or SQL + * string itself. For SQL commands, after post-processing + * argv[0] is the same as 'lines' with variables substituted. + * varprefix SQL commands terminated with \gset have this set + * to a non NULL value. If nonempty, it's used to prefix the + * variable name that receives the value. + * expr Parsed expression, if needed. + * stats Time spent in this command. + */ +typedef struct Command { - char *line; /* text of command line */ - int command_num; /* unique index of this Command struct */ - int type; /* command type (SQL_COMMAND or META_COMMAND) */ - MetaCommand meta; /* meta command identifier, or META_NONE */ - int argc; /* number of command words */ - char *argv[MAX_ARGS]; /* command word list */ - PgBenchExpr *expr; /* parsed expression, if needed */ - SimpleStats stats; /* time spent in this command */ + PQExpBufferData lines; + char *first_line; + int type; + MetaCommand meta; + int argc; + char *argv[MAX_ARGS]; + char *varprefix; + PgBenchExpr *expr; + SimpleStats stats; } Command; typedef struct ParsedScript @@ -457,7 +536,6 @@ typedef struct ParsedScript static ParsedScript sql_script[MAX_SCRIPTS]; /* SQL script files */ static int num_scripts; /* number of scripts in sql_script[] */ -static int num_commands = 0; /* total number of Command structs */ static int64 total_weight = 0; static int debug = 0; /* debug flag */ @@ -514,22 +592,29 @@ static void setNullValue(PgBenchValue *pv); static void setBoolValue(PgBenchValue *pv, bool bval); static void setIntValue(PgBenchValue *pv, int64 ival); static void setDoubleValue(PgBenchValue *pv, double dval); -static bool evaluateExpr(TState *, CState *, PgBenchExpr *, PgBenchValue *); +static bool evaluateExpr(CState *st, PgBenchExpr *expr, + PgBenchValue *retval); +static ConnectionStateEnum executeMetaCommand(CState *st, instr_time *now); static void doLog(TState *thread, CState *st, - StatsData *agg, bool skipped, double latency, double lag); + StatsData *agg, bool skipped, double latency, double lag); static void processXactStats(TState *thread, CState *st, instr_time *now, - bool skipped, StatsData *agg); -static void pgbench_error(const char *fmt,...) pg_attribute_printf(1, 2); + bool skipped, StatsData *agg); +static void append_fillfactor(char *opts, int len); static void addScript(ParsedScript script); static void *threadRun(void *arg); -static void setalarm(int seconds); static void finishCon(CState *st); +static void setalarm(int seconds); +static socket_set *alloc_socket_set(int count); +static void free_socket_set(socket_set *sa); +static void clear_socket_set(socket_set *sa); +static void add_socket_to_set(socket_set *sa, int fd, int idx); +static int wait_on_socket_set(socket_set *sa, int64 usecs); +static bool socket_has_input(socket_set *sa, int fd, int idx); /* callback functions for our flex lexer */ static const PsqlScanCallbacks pgbench_callbacks = { NULL, /* don't need get_variable functionality */ - pgbench_error }; @@ -550,6 +635,9 @@ usage(void) " --foreign-keys create foreign key constraints between tables\n" " --index-tablespace=TABLESPACE\n" " create indexes in the specified tablespace\n" + " --partitions=NUM partition pgbench_accounts in NUM parts (default: 0)\n" + " --partition-method=(range|hash)\n" + " partition pgbench_accounts with this method (default: range)\n" " --tablespace=TABLESPACE create tables in the specified tablespace\n" " --unlogged-tables create tables as unlogged tables\n" "\nOptions to select what to run:\n" @@ -584,6 +672,7 @@ usage(void) " --progress-timestamp use Unix epoch timestamps for progress\n" " --random-seed=SEED set random seed (\"time\", \"rand\", integer)\n" " --sampling-rate=NUM fraction of transactions to log (e.g., 0.01 for 1%%)\n" + " --show-script=NAME show builtin script code, then exit\n" "\nCommon options:\n" " -d, --debug print debugging output\n" " -h, --host=HOSTNAME database server host or socket directory\n" @@ -592,7 +681,7 @@ usage(void) " -V, --version output version information, then exit\n" " -?, --help show this help, then exit\n" "\n" - "Report bugs to .\n", + "Report bugs to .\n", progname, progname); } @@ -626,19 +715,27 @@ is_an_int(const char *str) /* * strtoint64 -- convert a string to 64-bit integer * - * This function is a modified version of scanint8() from + * This function is a slightly modified version of scanint8() from * src/backend/utils/adt/int8.c. + * + * The function returns whether the conversion worked, and if so + * "*result" is set to the result. + * + * If not errorOK, an error message is also printed out on errors. */ -int64 -strtoint64(const char *str) +bool +strtoint64(const char *str, bool errorOK, int64 *result) { const char *ptr = str; - int64 result = 0; - int sign = 1; + int64 tmp = 0; + bool neg = false; /* * Do our own scan, rather than relying on sscanf which might be broken * for long long. + * + * As INT64_MIN can't be stored as a positive 64 bit integer, accumulate + * value as a negative number. */ /* skip leading spaces */ @@ -649,51 +746,108 @@ strtoint64(const char *str) if (*ptr == '-') { ptr++; - - /* - * Do an explicit check for INT64_MIN. Ugly though this is, it's - * cleaner than trying to get the loop below to handle it portably. - */ - if (strncmp(ptr, "9223372036854775808", 19) == 0) - { - result = PG_INT64_MIN; - ptr += 19; - goto gotdigits; - } - sign = -1; + neg = true; } else if (*ptr == '+') ptr++; /* require at least one digit */ - if (!isdigit((unsigned char) *ptr)) - fprintf(stderr, "invalid input syntax for integer: \"%s\"\n", str); + if (unlikely(!isdigit((unsigned char) *ptr))) + goto invalid_syntax; /* process digits */ while (*ptr && isdigit((unsigned char) *ptr)) { - int64 tmp = result * 10 + (*ptr++ - '0'); + int8 digit = (*ptr++ - '0'); - if ((tmp / 10) != result) /* overflow? */ - fprintf(stderr, "value \"%s\" is out of range for type bigint\n", str); - result = tmp; + if (unlikely(pg_mul_s64_overflow(tmp, 10, &tmp)) || + unlikely(pg_sub_s64_overflow(tmp, digit, &tmp))) + goto out_of_range; } -gotdigits: - /* allow trailing whitespace, but not other trailing chars */ while (*ptr != '\0' && isspace((unsigned char) *ptr)) ptr++; - if (*ptr != '\0') - fprintf(stderr, "invalid input syntax for integer: \"%s\"\n", str); + if (unlikely(*ptr != '\0')) + goto invalid_syntax; + + if (!neg) + { + if (unlikely(tmp == PG_INT64_MIN)) + goto out_of_range; + tmp = -tmp; + } + + *result = tmp; + return true; + +out_of_range: + if (!errorOK) + fprintf(stderr, + "value \"%s\" is out of range for type bigint\n", str); + return false; + +invalid_syntax: + if (!errorOK) + fprintf(stderr, + "invalid input syntax for type bigint: \"%s\"\n", str); + return false; +} + +/* convert string to double, detecting overflows/underflows */ +bool +strtodouble(const char *str, bool errorOK, double *dv) +{ + char *end; + + errno = 0; + *dv = strtod(str, &end); + + if (unlikely(errno != 0)) + { + if (!errorOK) + fprintf(stderr, + "value \"%s\" is out of range for type double\n", str); + return false; + } + + if (unlikely(end == str || *end != '\0')) + { + if (!errorOK) + fprintf(stderr, + "invalid input syntax for type double: \"%s\"\n", str); + return false; + } + return true; +} - return ((sign < 0) ? -result : result); +/* + * Initialize a random state struct. + * + * We derive the seed from base_random_sequence, which must be set up already. + */ +static void +initRandomState(RandomState *random_state) +{ + random_state->xseed[0] = (unsigned short) + (pg_jrand48(base_random_sequence.xseed) & 0xFFFF); + random_state->xseed[1] = (unsigned short) + (pg_jrand48(base_random_sequence.xseed) & 0xFFFF); + random_state->xseed[2] = (unsigned short) + (pg_jrand48(base_random_sequence.xseed) & 0xFFFF); } -/* random number generator: uniform distribution from min to max inclusive */ +/* + * Random number generator: uniform distribution from min to max inclusive. + * + * Although the limits are expressed as int64, you can't generate the full + * int64 range in one call, because the difference of the limits mustn't + * overflow int64. In practice it's unwise to ask for more than an int32 + * range, because of the limited precision of pg_erand48(). + */ static int64 -getrand(TState *thread, int64 min, int64 max) +getrand(RandomState *random_state, int64 min, int64 max) { /* * Odd coding is so that min and max have approximately the same chance of @@ -704,7 +858,7 @@ getrand(TState *thread, int64 min, int64 max) * protected by a mutex, and therefore a bottleneck on machines with many * CPUs. */ - return min + (int64) ((max - min + 1) * pg_erand48(thread->random_state)); + return min + (int64) ((max - min + 1) * pg_erand48(random_state->xseed)); } /* @@ -713,7 +867,8 @@ getrand(TState *thread, int64 min, int64 max) * value is exp(-parameter). */ static int64 -getExponentialRand(TState *thread, int64 min, int64 max, double parameter) +getExponentialRand(RandomState *random_state, int64 min, int64 max, + double parameter) { double cut, uniform, @@ -723,7 +878,7 @@ getExponentialRand(TState *thread, int64 min, int64 max, double parameter) Assert(parameter > 0.0); cut = exp(-parameter); /* erand in [0, 1), uniform in (0, 1] */ - uniform = 1.0 - pg_erand48(thread->random_state); + uniform = 1.0 - pg_erand48(random_state->xseed); /* * inner expression in (cut, 1] (if parameter > 0), rand in [0, 1) @@ -736,7 +891,8 @@ getExponentialRand(TState *thread, int64 min, int64 max, double parameter) /* random number generator: gaussian distribution from min to max inclusive */ static int64 -getGaussianRand(TState *thread, int64 min, int64 max, double parameter) +getGaussianRand(RandomState *random_state, int64 min, int64 max, + double parameter) { double stdev; double rand; @@ -762,10 +918,10 @@ getGaussianRand(TState *thread, int64 min, int64 max, double parameter) * pg_erand48 generates [0,1), but for the basic version of the * Box-Muller transform the two uniformly distributed random numbers * are expected in (0, 1] (see - * http://en.wikipedia.org/wiki/Box_muller) + * https://en.wikipedia.org/wiki/Box-Muller_transform) */ - double rand1 = 1.0 - pg_erand48(thread->random_state); - double rand2 = 1.0 - pg_erand48(thread->random_state); + double rand1 = 1.0 - pg_erand48(random_state->xseed); + double rand2 = 1.0 - pg_erand48(random_state->xseed); /* Box-Muller basic form transform */ double var_sqrt = sqrt(-2.0 * log(rand1)); @@ -790,9 +946,12 @@ getGaussianRand(TState *thread, int64 min, int64 max, double parameter) /* * random number generator: generate a value, such that the series of values * will approximate a Poisson distribution centered on the given value. + * + * Individual results are rounded to integers, though the center value need + * not be one. */ static int64 -getPoissonRand(TState *thread, int64 center) +getPoissonRand(RandomState *random_state, double center) { /* * Use inverse transform sampling to generate a value > 0, such that the @@ -801,85 +960,20 @@ getPoissonRand(TState *thread, int64 center) double uniform; /* erand in [0, 1), uniform in (0, 1] */ - uniform = 1.0 - pg_erand48(thread->random_state); - - return (int64) (-log(uniform) * ((double) center) + 0.5); -} + uniform = 1.0 - pg_erand48(random_state->xseed); -/* helper function for getZipfianRand */ -static double -generalizedHarmonicNumber(int64 n, double s) -{ - int i; - double ans = 0.0; - - for (i = n; i > 1; i--) - ans += pow(i, -s); - return ans + 1.0; -} - -/* set harmonicn and other parameters to cache cell */ -static void -zipfSetCacheCell(ZipfCell * cell, int64 n, double s) -{ - double harmonic2; - - cell->n = n; - cell->s = s; - - harmonic2 = generalizedHarmonicNumber(2, s); - cell->harmonicn = generalizedHarmonicNumber(n, s); - - cell->alpha = 1.0 / (1.0 - s); - cell->beta = pow(0.5, s); - cell->eta = (1.0 - pow(2.0 / n, 1.0 - s)) / (1.0 - harmonic2 / cell->harmonicn); -} - -/* - * search for cache cell with keys (n, s) - * and create new cell if it does not exist - */ -static ZipfCell * -zipfFindOrCreateCacheCell(ZipfCache * cache, int64 n, double s) -{ - int i, - least_recently_used = 0; - ZipfCell *cell; - - /* search cached cell for given parameters */ - for (i = 0; i < cache->nb_cells; i++) - { - cell = &cache->cells[i]; - if (cell->n == n && cell->s == s) - return &cache->cells[i]; - - if (cell->last_used < cache->cells[least_recently_used].last_used) - least_recently_used = i; - } - - /* create new one if it does not exist */ - if (cache->nb_cells < ZIPF_CACHE_SIZE) - i = cache->nb_cells++; - else - { - /* replace LRU cell if cache is full */ - i = least_recently_used; - cache->overflowCount++; - } - - zipfSetCacheCell(&cache->cells[i], n, s); - - cache->cells[i].last_used = cache->current++; - return &cache->cells[i]; + return (int64) (-log(uniform) * center + 0.5); } /* * Computing zipfian using rejection method, based on * "Non-Uniform Random Variate Generation", * Luc Devroye, p. 550-551, Springer 1986. + * + * This works for s > 1.0, but may perform badly for s very close to 1.0. */ static int64 -computeIterativeZipfian(TState *thread, int64 n, double s) +computeIterativeZipfian(RandomState *random_state, int64 n, double s) { double b = pow(2.0, s - 1.0); double x, @@ -887,11 +981,15 @@ computeIterativeZipfian(TState *thread, int64 n, double s) u, v; + /* Ensure n is sane */ + if (n <= 1) + return 1; + while (true) { /* random variates */ - u = pg_erand48(thread->random_state); - v = pg_erand48(thread->random_state); + u = pg_erand48(random_state->xseed); + v = pg_erand48(random_state->xseed); x = floor(pow(u, -1.0 / (s - 1.0))); @@ -903,38 +1001,16 @@ computeIterativeZipfian(TState *thread, int64 n, double s) return (int64) x; } -/* - * Computing zipfian using harmonic numbers, based on algorithm described in - * "Quickly Generating Billion-Record Synthetic Databases", - * Jim Gray et al, SIGMOD 1994 - */ -static int64 -computeHarmonicZipfian(TState *thread, int64 n, double s) -{ - ZipfCell *cell = zipfFindOrCreateCacheCell(&thread->zipf_cache, n, s); - double uniform = pg_erand48(thread->random_state); - double uz = uniform * cell->harmonicn; - - if (uz < 1.0) - return 1; - if (uz < 1.0 + cell->beta) - return 2; - return 1 + (int64) (cell->n * pow(cell->eta * uniform - cell->eta + 1.0, cell->alpha)); -} - /* random number generator: zipfian distribution from min to max inclusive */ static int64 -getZipfianRand(TState *thread, int64 min, int64 max, double s) +getZipfianRand(RandomState *random_state, int64 min, int64 max, double s) { int64 n = max - min + 1; /* abort if parameter is invalid */ - Assert(s > 0.0 && s != 1.0 && s <= MAX_ZIPFIAN_PARAM); - + Assert(MIN_ZIPFIAN_PARAM <= s && s <= MAX_ZIPFIAN_PARAM); - return min - 1 + ((s > 1) - ? computeIterativeZipfian(thread, n, s) - : computeHarmonicZipfian(thread, n, s)); + return min - 1 + computeIterativeZipfian(random_state, n, s); } /* @@ -943,13 +1019,13 @@ getZipfianRand(TState *thread, int64 min, int64 max, double s) static int64 getHashFnv1a(int64 val, uint64 seed) { - int64 result; - int i; + int64 result; + int i; result = FNV_OFFSET_BASIS ^ seed; for (i = 0; i < 8; ++i) { - int32 octet = val & 0xff; + int32 octet = val & 0xff; val = val >> 8; result = result ^ octet; @@ -968,8 +1044,8 @@ getHashFnv1a(int64 val, uint64 seed) static int64 getHashMurmur2(int64 val, uint64 seed) { - uint64 result = seed ^ (sizeof(int64) * MM2_MUL); - uint64 k = (uint64) val; + uint64 result = seed ^ MM2_MUL_TIMES_8; /* sizeof(int64) */ + uint64 k = (uint64) val; k *= MM2_MUL; k ^= k >> MM2_ROT; @@ -1160,20 +1236,6 @@ doConnect(void) return conn; } -/* throw away response from backend */ -static void -discard_response(CState *state) -{ - PGresult *res; - - do - { - res = PQgetResult(state->con); - if (res) - PQclear(res); - } while (res); -} - /* qsort comparator for Variable array */ static int compareVariableNames(const void *v1, const void *v2) @@ -1236,7 +1298,7 @@ getVariable(CState *st, char *name) else if (var->value.type == PGBT_DOUBLE) snprintf(stringform, sizeof(stringform), "%.*g", DBL_DIG, var->value.u.dval); - else /* internal error, unexpected type */ + else /* internal error, unexpected type */ Assert(0); var->svalue = pg_strdup(stringform); return var->svalue; @@ -1246,7 +1308,7 @@ getVariable(CState *st, char *name) static bool makeVariableValue(Variable *var) { - size_t slen; + size_t slen; if (var->value.type != PGBT_NO_VALUE) return true; /* no work */ @@ -1261,10 +1323,10 @@ makeVariableValue(Variable *var) { setNullValue(&var->value); } + /* - * accept prefixes such as y, ye, n, no... but not for "o". - * 0/1 are recognized later as an int, which is converted - * to bool if needed. + * accept prefixes such as y, ye, n, no... but not for "o". 0/1 are + * recognized later as an int, which is converted to bool if needed. */ else if (pg_strncasecmp(var->svalue, "true", slen) == 0 || pg_strncasecmp(var->svalue, "yes", slen) == 0 || @@ -1281,14 +1343,19 @@ makeVariableValue(Variable *var) } else if (is_an_int(var->svalue)) { - setIntValue(&var->value, strtoint64(var->svalue)); + /* if it looks like an int, it must be an int without overflow */ + int64 iv; + + if (!strtoint64(var->svalue, false, &iv)) + return false; + + setIntValue(&var->value, iv); } else /* type should be double */ { double dv; - char xs; - if (sscanf(var->svalue, "%lf%c", &dv, &xs) != 1) + if (!strtodouble(var->svalue, true, &dv)) { fprintf(stderr, "malformed variable \"%s\" value: \"%s\"\n", @@ -1410,7 +1477,7 @@ putVariable(CState *st, const char *context, char *name, const char *value) /* Returns false on failure (bad name) */ static bool putVariableValue(CState *st, const char *context, char *name, - const PgBenchValue *value) + const PgBenchValue *value) { Variable *var; @@ -1563,7 +1630,7 @@ coerceToBool(PgBenchValue *pval, bool *bval) *bval = pval->u.bval; return true; } - else /* NULL, INT or DOUBLE */ + else /* NULL, INT or DOUBLE */ { fprintf(stderr, "cannot coerce %s to boolean\n", valueTypeName(pval)); *bval = false; /* suppress uninitialized-variable warnings */ @@ -1616,7 +1683,7 @@ coerceToInt(PgBenchValue *pval, int64 *ival) *ival = (int64) dval; return true; } - else /* BOOLEAN or NULL */ + else /* BOOLEAN or NULL */ { fprintf(stderr, "cannot coerce %s to int\n", valueTypeName(pval)); return false; @@ -1637,7 +1704,7 @@ coerceToDouble(PgBenchValue *pval, double *dval) *dval = (double) pval->u.ival; return true; } - else /* BOOLEAN or NULL */ + else /* BOOLEAN or NULL */ { fprintf(stderr, "cannot coerce %s to double\n", valueTypeName(pval)); return false; @@ -1676,23 +1743,26 @@ setDoubleValue(PgBenchValue *pv, double dval) pv->u.dval = dval; } -static bool isLazyFunc(PgBenchFunction func) +static bool +isLazyFunc(PgBenchFunction func) { return func == PGBENCH_AND || func == PGBENCH_OR || func == PGBENCH_CASE; } /* lazy evaluation of some functions */ static bool -evalLazyFunc(TState *thread, CState *st, +evalLazyFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval) { - PgBenchValue a1, a2; - bool ba1, ba2; + PgBenchValue a1, + a2; + bool ba1, + ba2; Assert(isLazyFunc(func) && args != NULL && args->next != NULL); /* args points to first condition */ - if (!evaluateExpr(thread, st, args->expr, &a1)) + if (!evaluateExpr(st, args->expr, &a1)) return false; /* second condition for AND/OR and corresponding branch for CASE */ @@ -1700,92 +1770,92 @@ evalLazyFunc(TState *thread, CState *st, switch (func) { - case PGBENCH_AND: - if (a1.type == PGBT_NULL) - { - setNullValue(retval); - return true; - } + case PGBENCH_AND: + if (a1.type == PGBT_NULL) + { + setNullValue(retval); + return true; + } - if (!coerceToBool(&a1, &ba1)) - return false; + if (!coerceToBool(&a1, &ba1)) + return false; - if (!ba1) - { - setBoolValue(retval, false); - return true; - } + if (!ba1) + { + setBoolValue(retval, false); + return true; + } - if (!evaluateExpr(thread, st, args->expr, &a2)) - return false; + if (!evaluateExpr(st, args->expr, &a2)) + return false; - if (a2.type == PGBT_NULL) - { - setNullValue(retval); - return true; - } - else if (!coerceToBool(&a2, &ba2)) - return false; - else - { - setBoolValue(retval, ba2); - return true; - } + if (a2.type == PGBT_NULL) + { + setNullValue(retval); + return true; + } + else if (!coerceToBool(&a2, &ba2)) + return false; + else + { + setBoolValue(retval, ba2); + return true; + } - return true; + return true; - case PGBENCH_OR: + case PGBENCH_OR: - if (a1.type == PGBT_NULL) - { - setNullValue(retval); - return true; - } + if (a1.type == PGBT_NULL) + { + setNullValue(retval); + return true; + } - if (!coerceToBool(&a1, &ba1)) - return false; + if (!coerceToBool(&a1, &ba1)) + return false; - if (ba1) - { - setBoolValue(retval, true); - return true; - } + if (ba1) + { + setBoolValue(retval, true); + return true; + } - if (!evaluateExpr(thread, st, args->expr, &a2)) - return false; + if (!evaluateExpr(st, args->expr, &a2)) + return false; - if (a2.type == PGBT_NULL) - { - setNullValue(retval); - return true; - } - else if (!coerceToBool(&a2, &ba2)) - return false; - else - { - setBoolValue(retval, ba2); - return true; - } + if (a2.type == PGBT_NULL) + { + setNullValue(retval); + return true; + } + else if (!coerceToBool(&a2, &ba2)) + return false; + else + { + setBoolValue(retval, ba2); + return true; + } - case PGBENCH_CASE: - /* when true, execute branch */ - if (valueTruth(&a1)) - return evaluateExpr(thread, st, args->expr, retval); + case PGBENCH_CASE: + /* when true, execute branch */ + if (valueTruth(&a1)) + return evaluateExpr(st, args->expr, retval); - /* now args contains next condition or final else expression */ - args = args->next; + /* now args contains next condition or final else expression */ + args = args->next; - /* final else case? */ - if (args->next == NULL) - return evaluateExpr(thread, st, args->expr, retval); + /* final else case? */ + if (args->next == NULL) + return evaluateExpr(st, args->expr, retval); - /* no, another when, proceed */ - return evalLazyFunc(thread, st, PGBENCH_CASE, args, retval); + /* no, another when, proceed */ + return evalLazyFunc(st, PGBENCH_CASE, args, retval); - default: - /* internal error, cannot get here */ - Assert(0); - break; + default: + /* internal error, cannot get here */ + Assert(0); + break; } return false; } @@ -1798,19 +1868,19 @@ evalLazyFunc(TState *thread, CState *st, * which do not require lazy evaluation. */ static bool -evalStandardFunc(TState *thread, CState *st, +evalStandardFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval) { /* evaluate all function arguments */ - int nargs = 0; - PgBenchValue vargs[MAX_FARGS]; + int nargs = 0; + PgBenchValue vargs[MAX_FARGS]; PgBenchExprLink *l = args; - bool has_null = false; + bool has_null = false; for (nargs = 0; nargs < MAX_FARGS && l != NULL; nargs++, l = l->next) { - if (!evaluateExpr(thread, st, l->expr, &vargs[nargs])) + if (!evaluateExpr(st, l->expr, &vargs[nargs])) return false; has_null |= vargs[nargs].type == PGBT_NULL; } @@ -1901,7 +1971,8 @@ evalStandardFunc(TState *thread, CState *st, else /* we have integer operands, or % */ { int64 li, - ri; + ri, + res; if (!coerceToInt(lval, &li) || !coerceToInt(rval, &ri)) @@ -1910,15 +1981,30 @@ evalStandardFunc(TState *thread, CState *st, switch (func) { case PGBENCH_ADD: - setIntValue(retval, li + ri); + if (pg_add_s64_overflow(li, ri, &res)) + { + fprintf(stderr, "bigint add out of range\n"); + return false; + } + setIntValue(retval, res); return true; case PGBENCH_SUB: - setIntValue(retval, li - ri); + if (pg_sub_s64_overflow(li, ri, &res)) + { + fprintf(stderr, "bigint sub out of range\n"); + return false; + } + setIntValue(retval, res); return true; case PGBENCH_MUL: - setIntValue(retval, li * ri); + if (pg_mul_s64_overflow(li, ri, &res)) + { + fprintf(stderr, "bigint mul out of range\n"); + return false; + } + setIntValue(retval, res); return true; case PGBENCH_EQ: @@ -1952,7 +2038,7 @@ evalStandardFunc(TState *thread, CState *st, /* overflow check (needed for INT64_MIN) */ if (li == PG_INT64_MIN) { - fprintf(stderr, "bigint out of range\n"); + fprintf(stderr, "bigint div out of range\n"); return false; } else @@ -1975,6 +2061,9 @@ evalStandardFunc(TState *thread, CState *st, Assert(0); } } + + Assert(0); + return false; /* NOTREACHED */ } /* integer bitwise operators */ @@ -1984,7 +2073,8 @@ evalStandardFunc(TState *thread, CState *st, case PGBENCH_LSHIFT: case PGBENCH_RSHIFT: { - int64 li, ri; + int64 li, + ri; if (!coerceToInt(&vargs[0], &li) || !coerceToInt(&vargs[1], &ri)) return false; @@ -1999,7 +2089,7 @@ evalStandardFunc(TState *thread, CState *st, setIntValue(retval, li << ri); else if (func == PGBENCH_RSHIFT) setIntValue(retval, li >> ri); - else /* cannot get here */ + else /* cannot get here */ Assert(0); return true; @@ -2008,7 +2098,8 @@ evalStandardFunc(TState *thread, CState *st, /* logical operators */ case PGBENCH_NOT: { - bool b; + bool b; + if (!coerceToBool(&vargs[0], &b)) return false; @@ -2062,7 +2153,7 @@ evalStandardFunc(TState *thread, CState *st, fprintf(stderr, "int " INT64_FORMAT "\n", varg->u.ival); else if (varg->type == PGBT_DOUBLE) fprintf(stderr, "double %.*g\n", DBL_DIG, varg->u.dval); - else /* internal error, unexpected type */ + else /* internal error, unexpected type */ Assert(0); *retval = *varg; @@ -2200,7 +2291,7 @@ evalStandardFunc(TState *thread, CState *st, if (func == PGBENCH_RANDOM) { Assert(nargs == 2); - setIntValue(retval, getrand(thread, imin, imax)); + setIntValue(retval, getrand(&st->cs_func_rs, imin, imax)); } else /* gaussian & exponential */ { @@ -2222,19 +2313,22 @@ evalStandardFunc(TState *thread, CState *st, } setIntValue(retval, - getGaussianRand(thread, imin, imax, param)); + getGaussianRand(&st->cs_func_rs, + imin, imax, param)); } else if (func == PGBENCH_RANDOM_ZIPFIAN) { - if (param <= 0.0 || param == 1.0 || param > MAX_ZIPFIAN_PARAM) + if (param < MIN_ZIPFIAN_PARAM || param > MAX_ZIPFIAN_PARAM) { fprintf(stderr, - "zipfian parameter must be in range (0, 1) U (1, %d]" - " (got %f)\n", MAX_ZIPFIAN_PARAM, param); + "zipfian parameter must be in range [%.3f, %.0f]" + " (not %f)\n", + MIN_ZIPFIAN_PARAM, MAX_ZIPFIAN_PARAM, param); return false; } + setIntValue(retval, - getZipfianRand(thread, imin, imax, param)); + getZipfianRand(&st->cs_func_rs, imin, imax, param)); } else /* exponential */ { @@ -2242,12 +2336,13 @@ evalStandardFunc(TState *thread, CState *st, { fprintf(stderr, "exponential parameter must be greater than zero" - " (got %f)\n", param); + " (not %f)\n", param); return false; } setIntValue(retval, - getExponentialRand(thread, imin, imax, param)); + getExponentialRand(&st->cs_func_rs, + imin, imax, param)); } } @@ -2275,8 +2370,12 @@ evalStandardFunc(TState *thread, CState *st, case PGBENCH_IS: { Assert(nargs == 2); - /* note: this simple implementation is more permissive than SQL */ - setBoolValue(retval, + + /* + * note: this simple implementation is more permissive than + * SQL + */ + setBoolValue(retval, vargs[0].type == vargs[1].type && vargs[0].u.bval == vargs[1].u.bval); return true; @@ -2286,8 +2385,8 @@ evalStandardFunc(TState *thread, CState *st, case PGBENCH_HASH_FNV1A: case PGBENCH_HASH_MURMUR2: { - int64 val, - seed; + int64 val, + seed; Assert(nargs == 2); @@ -2316,13 +2415,13 @@ evalStandardFunc(TState *thread, CState *st, /* evaluate some function */ static bool -evalFunc(TState *thread, CState *st, +evalFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval) { if (isLazyFunc(func)) - return evalLazyFunc(thread, st, func, args, retval); + return evalLazyFunc(st, func, args, retval); else - return evalStandardFunc(thread, st, func, args, retval); + return evalStandardFunc(st, func, args, retval); } /* @@ -2332,7 +2431,7 @@ evalFunc(TState *thread, CState *st, * the value itself is returned through the retval pointer. */ static bool -evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr, PgBenchValue *retval) +evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval) { switch (expr->etype) { @@ -2361,7 +2460,7 @@ evaluateExpr(TState *thread, CState *st, PgBenchExpr *expr, PgBenchValue *retval } case ENODE_FUNCTION: - return evalFunc(thread, st, + return evalFunc(st, expr->u.function.function, expr->u.function.args, retval); @@ -2400,6 +2499,8 @@ getMetaCommand(const char *cmd) mc = META_ELSE; else if (pg_strcasecmp(cmd, "endif") == 0) mc = META_ENDIF; + else if (pg_strcasecmp(cmd, "gset") == 0) + mc = META_GSET; else mc = META_NONE; return mc; @@ -2538,7 +2639,7 @@ chooseScript(TState *thread) if (num_scripts == 1) return 0; - w = getrand(thread, 0, total_weight - 1); + w = getrand(&thread->ts_choose_rs, 0, total_weight - 1); do { w -= sql_script[i++].weight; @@ -2627,6 +2728,119 @@ sendCommand(CState *st, Command *command) return true; } +/* + * Process query response from the backend. + * + * If varprefix is not NULL, it's the variable name prefix where to store + * the results of the *last* command. + * + * Returns true if everything is A-OK, false if any error occurs. + */ +static bool +readCommandResponse(CState *st, char *varprefix) +{ + PGresult *res; + PGresult *next_res; + int qrynum = 0; + + res = PQgetResult(st->con); + + while (res != NULL) + { + bool is_last; + + /* peek at the next result to know whether the current is last */ + next_res = PQgetResult(st->con); + is_last = (next_res == NULL); + + switch (PQresultStatus(res)) + { + case PGRES_COMMAND_OK: /* non-SELECT commands */ + case PGRES_EMPTY_QUERY: /* may be used for testing no-op overhead */ + if (is_last && varprefix != NULL) + { + fprintf(stderr, + "client %d script %d command %d query %d: expected one row, got %d\n", + st->id, st->use_file, st->command, qrynum, 0); + goto error; + } + break; + + case PGRES_TUPLES_OK: + if (is_last && varprefix != NULL) + { + if (PQntuples(res) != 1) + { + fprintf(stderr, + "client %d script %d command %d query %d: expected one row, got %d\n", + st->id, st->use_file, st->command, qrynum, PQntuples(res)); + goto error; + } + + /* store results into variables */ + for (int fld = 0; fld < PQnfields(res); fld++) + { + char *varname = PQfname(res, fld); + + /* allocate varname only if necessary, freed below */ + if (*varprefix != '\0') + varname = psprintf("%s%s", varprefix, varname); + + /* store result as a string */ + if (!putVariable(st, "gset", varname, + PQgetvalue(res, 0, fld))) + { + /* internal error */ + fprintf(stderr, + "client %d script %d command %d query %d: error storing into variable %s\n", + st->id, st->use_file, st->command, qrynum, + varname); + goto error; + } + + if (*varprefix != '\0') + pg_free(varname); + } + } + /* otherwise the result is simply thrown away by PQclear below */ + break; + + default: + /* anything else is unexpected */ + fprintf(stderr, + "client %d script %d aborted in command %d query %d: %s", + st->id, st->use_file, st->command, qrynum, + PQerrorMessage(st->con)); + goto error; + } + + PQclear(res); + qrynum++; + res = next_res; + } + + if (qrynum == 0) + { + fprintf(stderr, "client %d command %d: no results\n", st->id, st->command); + st->ecnt++; + return false; + } + + return true; + +error: + st->ecnt++; + PQclear(res); + PQclear(next_res); + do + { + res = PQgetResult(st->con); + PQclear(res); + } while (res); + + return false; +} + /* * Parse the argument to a \sleep command, and return the requested amount * of delay, in microseconds. Returns true on success, false on error. @@ -2665,16 +2879,12 @@ evaluateSleep(CState *st, int argc, char **argv, int *usecs) } /* - * Advance the state machine of a connection, if possible. + * Advance the state machine of a connection. */ static void -doCustom(TState *thread, CState *st, StatsData *agg) +advanceConnectionState(TState *thread, CState *st, StatsData *agg) { - PGresult *res; - Command *command; instr_time now; - bool end_tx_processed = false; - int64 wait; /* * gettimeofday() isn't free, so we get the current timestamp lazily the @@ -2688,39 +2898,80 @@ doCustom(TState *thread, CState *st, StatsData *agg) /* * Loop in the state machine, until we have to wait for a result from the - * server (or have to sleep, for throttling or for \sleep). + * server or have to sleep for throttling or \sleep. * * Note: In the switch-statement below, 'break' will loop back here, * meaning "continue in the state machine". Return is used to return to - * the caller. + * the caller, giving the thread the opportunity to advance another + * client. */ for (;;) { + Command *command; + switch (st->state) { - /* - * Select transaction to run. - */ + /* Select transaction (script) to run. */ case CSTATE_CHOOSE_SCRIPT: - st->use_file = chooseScript(thread); + Assert(conditional_stack_empty(st->cstack)); if (debug) fprintf(stderr, "client %d executing script \"%s\"\n", st->id, sql_script[st->use_file].desc); - if (throttle_delay > 0) - st->state = CSTATE_START_THROTTLE; - else - st->state = CSTATE_START_TX; - /* check consistency */ - Assert(conditional_stack_empty(st->cstack)); + /* + * If time is over, we're done; otherwise, get ready to start + * a new transaction, or to get throttled if that's requested. + */ + st->state = timer_exceeded ? CSTATE_FINISHED : + throttle_delay > 0 ? CSTATE_PREPARE_THROTTLE : CSTATE_START_TX; + break; + + /* Start new transaction (script) */ + case CSTATE_START_TX: + + /* establish connection if needed, i.e. under --connect */ + if (st->con == NULL) + { + instr_time start; + + INSTR_TIME_SET_CURRENT_LAZY(now); + start = now; + if ((st->con = doConnect()) == NULL) + { + fprintf(stderr, "client %d aborted while establishing connection\n", + st->id); + st->state = CSTATE_ABORTED; + break; + } + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_ACCUM_DIFF(thread->conn_time, now, start); + + /* Reset session-local state */ + memset(st->prepared, 0, sizeof(st->prepared)); + } + + /* record transaction start time */ + INSTR_TIME_SET_CURRENT_LAZY(now); + st->txn_begin = now; + + /* + * When not throttling, this is also the transaction's + * scheduled start time. + */ + if (!throttle_delay) + st->txn_scheduled = INSTR_TIME_GET_MICROSEC(now); + + /* Begin with the first command */ + st->state = CSTATE_START_COMMAND; + st->command = 0; break; /* * Handle throttling once per transaction by sleeping. */ - case CSTATE_START_THROTTLE: + case CSTATE_PREPARE_THROTTLE: /* * Generate a delay such that the series of delays will @@ -2732,45 +2983,39 @@ doCustom(TState *thread, CState *st, StatsData *agg) * away. */ Assert(throttle_delay > 0); - wait = getPoissonRand(thread, throttle_delay); - thread->throttle_trigger += wait; + thread->throttle_trigger += + getPoissonRand(&thread->ts_throttle_rs, throttle_delay); st->txn_scheduled = thread->throttle_trigger; - /* - * stop client if next transaction is beyond pgbench end of - * execution - */ - if (duration > 0 && st->txn_scheduled > end_time) - { - st->state = CSTATE_FINISHED; - break; - } - /* * If --latency-limit is used, and this slot is already late * so that the transaction will miss the latency limit even if - * it completed immediately, we skip this time slot and - * iterate till the next slot that isn't late yet. But don't - * iterate beyond the -t limit, if one is given. + * it completed immediately, skip this time slot and schedule + * to continue running on the next slot that isn't late yet. + * But don't iterate beyond the -t limit, if one is given. */ if (latency_limit) { int64 now_us; - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SET_CURRENT_LAZY(now); now_us = INSTR_TIME_GET_MICROSEC(now); + while (thread->throttle_trigger < now_us - latency_limit && (nxacts <= 0 || st->cnt < nxacts)) { processXactStats(thread, st, &now, true, agg); /* next rendez-vous */ - wait = getPoissonRand(thread, throttle_delay); - thread->throttle_trigger += wait; + thread->throttle_trigger += + getPoissonRand(&thread->ts_throttle_rs, throttle_delay); st->txn_scheduled = thread->throttle_trigger; } - /* stop client if -t exceeded */ + + /* + * stop client if -t was exceeded in the previous skip + * loop + */ if (nxacts > 0 && st->cnt >= nxacts) { st->state = CSTATE_FINISHED; @@ -2778,75 +3023,25 @@ doCustom(TState *thread, CState *st, StatsData *agg) } } - st->state = CSTATE_THROTTLE; - if (debug) - fprintf(stderr, "client %d throttling " INT64_FORMAT " us\n", - st->id, wait); - break; - /* - * Wait until it's time to start next transaction. + * stop client if next transaction is beyond pgbench end of + * execution; otherwise, throttle it. */ - case CSTATE_THROTTLE: - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); - if (INSTR_TIME_GET_MICROSEC(now) < st->txn_scheduled) - return; /* Still sleeping, nothing to do here */ - - /* Else done sleeping, start the transaction */ - st->state = CSTATE_START_TX; + st->state = end_time > 0 && st->txn_scheduled > end_time ? + CSTATE_FINISHED : CSTATE_THROTTLE; break; - /* Start new transaction */ - case CSTATE_START_TX: - - /* - * Establish connection on first call, or if is_connect is - * true. - */ - if (st->con == NULL) - { - instr_time start; - - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); - start = now; - if ((st->con = doConnect()) == NULL) - { - fprintf(stderr, "client %d aborted while establishing connection\n", - st->id); - st->state = CSTATE_ABORTED; - break; - } - INSTR_TIME_SET_CURRENT(now); - INSTR_TIME_ACCUM_DIFF(thread->conn_time, now, start); - - /* Reset session-local state */ - memset(st->prepared, 0, sizeof(st->prepared)); - } - /* - * Record transaction start time under logging, progress or - * throttling. + * Wait until it's time to start next transaction. */ - if (use_log || progress || throttle_delay || latency_limit || - per_script_stats) - { - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); - st->txn_begin = now; + case CSTATE_THROTTLE: + INSTR_TIME_SET_CURRENT_LAZY(now); - /* - * When not throttling, this is also the transaction's - * scheduled start time. - */ - if (!throttle_delay) - st->txn_scheduled = INSTR_TIME_GET_MICROSEC(now); - } + if (INSTR_TIME_GET_MICROSEC(now) < st->txn_scheduled) + return; /* still sleeping, nothing to do here */ - /* Begin with the first command */ - st->command = 0; - st->state = CSTATE_START_COMMAND; + /* done sleeping, but don't start transaction if we're done */ + st->state = timer_exceeded ? CSTATE_FINISHED : CSTATE_START_TX; break; /* @@ -2855,27 +3050,21 @@ doCustom(TState *thread, CState *st, StatsData *agg) case CSTATE_START_COMMAND: command = sql_script[st->use_file].commands[st->command]; - /* - * If we reached the end of the script, move to end-of-xact - * processing. - */ + /* Transition to script end processing if done */ if (command == NULL) { st->state = CSTATE_END_TX; break; } - /* - * Record statement start time if per-command latencies are - * requested - */ - if (is_latencies) + /* record begin time of next command, and initiate it */ + if (report_per_command) { - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SET_CURRENT_LAZY(now); st->stmt_begin = now; } + /* Execute the command */ if (command->type == SQL_COMMAND) { if (!sendCommand(st, command)) @@ -2888,166 +3077,24 @@ doCustom(TState *thread, CState *st, StatsData *agg) } else if (command->type == META_COMMAND) { - int argc = command->argc, - i; - char **argv = command->argv; - - if (debug) - { - fprintf(stderr, "client %d executing \\%s", st->id, argv[0]); - for (i = 1; i < argc; i++) - fprintf(stderr, " %s", argv[i]); - fprintf(stderr, "\n"); - } - - if (command->meta == META_SLEEP) - { - /* - * A \sleep doesn't execute anything, we just get the - * delay from the argument, and enter the CSTATE_SLEEP - * state. (The per-command latency will be recorded - * in CSTATE_SLEEP state, not here, after the delay - * has elapsed.) - */ - int usec; - - if (!evaluateSleep(st, argc, argv, &usec)) - { - commandFailed(st, "sleep", "execution of meta-command failed"); - st->state = CSTATE_ABORTED; - break; - } - - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); - st->sleep_until = INSTR_TIME_GET_MICROSEC(now) + usec; - st->state = CSTATE_SLEEP; - break; - } - else if (command->meta == META_SET || - command->meta == META_IF || - command->meta == META_ELIF) - { - /* backslash commands with an expression to evaluate */ - PgBenchExpr *expr = command->expr; - PgBenchValue result; - - if (command->meta == META_ELIF && - conditional_stack_peek(st->cstack) == IFSTATE_TRUE) - { - /* elif after executed block, skip eval and wait for endif */ - conditional_stack_poke(st->cstack, IFSTATE_IGNORED); - goto move_to_end_command; - } - - if (!evaluateExpr(thread, st, expr, &result)) - { - commandFailed(st, argv[0], "evaluation of meta-command failed"); - st->state = CSTATE_ABORTED; - break; - } - - if (command->meta == META_SET) - { - if (!putVariableValue(st, argv[0], argv[1], &result)) - { - commandFailed(st, "set", "assignment of meta-command failed"); - st->state = CSTATE_ABORTED; - break; - } - } - else /* if and elif evaluated cases */ - { - bool cond = valueTruth(&result); - - /* execute or not depending on evaluated condition */ - if (command->meta == META_IF) - { - conditional_stack_push(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE); - } - else /* elif */ - { - /* we should get here only if the "elif" needed evaluation */ - Assert(conditional_stack_peek(st->cstack) == IFSTATE_FALSE); - conditional_stack_poke(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE); - } - } - } - else if (command->meta == META_ELSE) - { - switch (conditional_stack_peek(st->cstack)) - { - case IFSTATE_TRUE: - conditional_stack_poke(st->cstack, IFSTATE_ELSE_FALSE); - break; - case IFSTATE_FALSE: /* inconsistent if active */ - case IFSTATE_IGNORED: /* inconsistent if active */ - case IFSTATE_NONE: /* else without if */ - case IFSTATE_ELSE_TRUE: /* else after else */ - case IFSTATE_ELSE_FALSE: /* else after else */ - default: - /* dead code if conditional check is ok */ - Assert(false); - } - goto move_to_end_command; - } - else if (command->meta == META_ENDIF) - { - Assert(!conditional_stack_empty(st->cstack)); - conditional_stack_pop(st->cstack); - goto move_to_end_command; - } - else if (command->meta == META_SETSHELL) - { - bool ret = runShellCommand(st, argv[1], argv + 2, argc - 2); - - if (timer_exceeded) /* timeout */ - { - st->state = CSTATE_FINISHED; - break; - } - else if (!ret) /* on error */ - { - commandFailed(st, "setshell", "execution of meta-command failed"); - st->state = CSTATE_ABORTED; - break; - } - else - { - /* succeeded */ - } - } - else if (command->meta == META_SHELL) - { - bool ret = runShellCommand(st, NULL, argv + 1, argc - 1); - - if (timer_exceeded) /* timeout */ - { - st->state = CSTATE_FINISHED; - break; - } - else if (!ret) /* on error */ - { - commandFailed(st, "shell", "execution of meta-command failed"); - st->state = CSTATE_ABORTED; - break; - } - else - { - /* succeeded */ - } - } - - move_to_end_command: - /* - * executing the expression or shell command might - * take a non-negligible amount of time, so reset - * 'now' + /*----- + * Possible state changes when executing meta commands: + * - on errors CSTATE_ABORTED + * - on sleep CSTATE_SLEEP + * - else CSTATE_END_COMMAND */ - INSTR_TIME_SET_ZERO(now); - - st->state = CSTATE_END_COMMAND; + st->state = executeMetaCommand(st, &now); } + + /* + * We're now waiting for an SQL command to complete, or + * finished processing a metacommand, or need to sleep, or + * something bad happened. + */ + Assert(st->state == CSTATE_WAIT_RESULT || + st->state == CSTATE_END_COMMAND || + st->state == CSTATE_SLEEP || + st->state == CSTATE_ABORTED); break; /* @@ -3058,12 +3105,17 @@ doCustom(TState *thread, CState *st, StatsData *agg) /* quickly skip commands until something to do... */ while (true) { + Command *command; + command = sql_script[st->use_file].commands[st->command]; /* cannot reach end of script in that state */ Assert(command != NULL); - /* if this is conditional related, update conditional state */ + /* + * if this is conditional related, update conditional + * state + */ if (command->type == META_COMMAND && (command->meta == META_IF || command->meta == META_ELIF || @@ -3072,51 +3124,62 @@ doCustom(TState *thread, CState *st, StatsData *agg) { switch (conditional_stack_peek(st->cstack)) { - case IFSTATE_FALSE: - if (command->meta == META_IF || command->meta == META_ELIF) - { - /* we must evaluate the condition */ - st->state = CSTATE_START_COMMAND; - } - else if (command->meta == META_ELSE) - { - /* we must execute next command */ - conditional_stack_poke(st->cstack, IFSTATE_ELSE_TRUE); - st->state = CSTATE_START_COMMAND; - st->command++; - } - else if (command->meta == META_ENDIF) - { - Assert(!conditional_stack_empty(st->cstack)); - conditional_stack_pop(st->cstack); - if (conditional_active(st->cstack)) + case IFSTATE_FALSE: + if (command->meta == META_IF || + command->meta == META_ELIF) + { + /* we must evaluate the condition */ st->state = CSTATE_START_COMMAND; - /* else state remains in CSTATE_SKIP_COMMAND */ + } + else if (command->meta == META_ELSE) + { + /* we must execute next command */ + conditional_stack_poke(st->cstack, + IFSTATE_ELSE_TRUE); + st->state = CSTATE_START_COMMAND; + st->command++; + } + else if (command->meta == META_ENDIF) + { + Assert(!conditional_stack_empty(st->cstack)); + conditional_stack_pop(st->cstack); + if (conditional_active(st->cstack)) + st->state = CSTATE_START_COMMAND; + + /* + * else state remains in + * CSTATE_SKIP_COMMAND + */ + st->command++; + } + break; + + case IFSTATE_IGNORED: + case IFSTATE_ELSE_FALSE: + if (command->meta == META_IF) + conditional_stack_push(st->cstack, + IFSTATE_IGNORED); + else if (command->meta == META_ENDIF) + { + Assert(!conditional_stack_empty(st->cstack)); + conditional_stack_pop(st->cstack); + if (conditional_active(st->cstack)) + st->state = CSTATE_START_COMMAND; + } + /* could detect "else" & "elif" after "else" */ st->command++; - } - break; + break; - case IFSTATE_IGNORED: - case IFSTATE_ELSE_FALSE: - if (command->meta == META_IF) - conditional_stack_push(st->cstack, IFSTATE_IGNORED); - else if (command->meta == META_ENDIF) - { - Assert(!conditional_stack_empty(st->cstack)); - conditional_stack_pop(st->cstack); - if (conditional_active(st->cstack)) - st->state = CSTATE_START_COMMAND; - } - /* could detect "else" & "elif" after "else" */ - st->command++; - break; + case IFSTATE_NONE: + case IFSTATE_TRUE: + case IFSTATE_ELSE_TRUE: + default: - case IFSTATE_NONE: - case IFSTATE_TRUE: - case IFSTATE_ELSE_TRUE: - default: - /* inconsistent if inactive, unreachable dead code */ - Assert(false); + /* + * inconsistent if inactive, unreachable dead + * code + */ + Assert(false); } } else @@ -3126,6 +3189,7 @@ doCustom(TState *thread, CState *st, StatsData *agg) } if (st->state != CSTATE_SKIP_COMMAND) + /* out of quick skip command loop */ break; } break; @@ -3134,11 +3198,11 @@ doCustom(TState *thread, CState *st, StatsData *agg) * Wait for the current SQL command to complete */ case CSTATE_WAIT_RESULT: - command = sql_script[st->use_file].commands[st->command]; if (debug) fprintf(stderr, "client %d receiving\n", st->id); if (!PQconsumeInput(st->con)) - { /* there's something wrong */ + { + /* there's something wrong */ commandFailed(st, "SQL", "perhaps the backend died while processing"); st->state = CSTATE_ABORTED; break; @@ -3146,26 +3210,11 @@ doCustom(TState *thread, CState *st, StatsData *agg) if (PQisBusy(st->con)) return; /* don't have the whole result yet */ - /* - * Read and discard the query result; - */ - res = PQgetResult(st->con); - switch (PQresultStatus(res)) - { - case PGRES_COMMAND_OK: - case PGRES_TUPLES_OK: - case PGRES_EMPTY_QUERY: - /* OK */ - PQclear(res); - discard_response(st); - st->state = CSTATE_END_COMMAND; - break; - default: - commandFailed(st, "SQL", PQerrorMessage(st->con)); - PQclear(res); - st->state = CSTATE_ABORTED; - break; - } + /* store or discard the query results */ + if (readCommandResponse(st, sql_script[st->use_file].commands[st->command]->varprefix)) + st->state = CSTATE_END_COMMAND; + else + st->state = CSTATE_ABORTED; break; /* @@ -3175,10 +3224,9 @@ doCustom(TState *thread, CState *st, StatsData *agg) * instead of CSTATE_START_TX. */ case CSTATE_SLEEP: - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SET_CURRENT_LAZY(now); if (INSTR_TIME_GET_MICROSEC(now) < st->sleep_until) - return; /* Still sleeping, nothing to do here */ + return; /* still sleeping, nothing to do here */ /* Else done sleeping. */ st->state = CSTATE_END_COMMAND; break; @@ -3193,13 +3241,14 @@ doCustom(TState *thread, CState *st, StatsData *agg) * in thread-local data structure, if per-command latencies * are requested. */ - if (is_latencies) + if (report_per_command) { - if (INSTR_TIME_IS_ZERO(now)) - INSTR_TIME_SET_CURRENT(now); + Command *command; + + INSTR_TIME_SET_CURRENT_LAZY(now); - /* XXX could use a mutex here, but we choose not to */ command = sql_script[st->use_file].commands[st->command]; + /* XXX could use a mutex here, but we choose not to */ addToSimpleStats(&command->stats, INSTR_TIME_GET_DOUBLE(now) - INSTR_TIME_GET_DOUBLE(st->stmt_begin)); @@ -3212,63 +3261,202 @@ doCustom(TState *thread, CState *st, StatsData *agg) break; /* - * End of transaction. + * End of transaction (end of script, really). */ case CSTATE_END_TX: /* transaction finished: calculate latency and do log */ processXactStats(thread, st, &now, false, agg); - /* conditional stack must be empty */ - if (!conditional_stack_empty(st->cstack)) - { - fprintf(stderr, "end of script reached within a conditional, missing \\endif\n"); - exit(1); - } + /* + * missing \endif... cannot happen if CheckConditional was + * okay + */ + Assert(conditional_stack_empty(st->cstack)); + + if (is_connect) + { + finishCon(st); + INSTR_TIME_SET_ZERO(now); + } + + if ((st->cnt >= nxacts && duration <= 0) || timer_exceeded) + { + /* script completed */ + st->state = CSTATE_FINISHED; + break; + } + + /* next transaction (script) */ + st->state = CSTATE_CHOOSE_SCRIPT; + + /* + * Ensure that we always return on this point, so as to avoid + * an infinite loop if the script only contains meta commands. + */ + return; + + /* + * Final states. Close the connection if it's still open. + */ + case CSTATE_ABORTED: + case CSTATE_FINISHED: + finishCon(st); + return; + } + } +} + +/* + * Subroutine for advanceConnectionState -- initiate or execute the current + * meta command, and return the next state to set. + * + * *now is updated to the current time, unless the command is expected to + * take no time to execute. + */ +static ConnectionStateEnum +executeMetaCommand(CState *st, instr_time *now) +{ + Command *command = sql_script[st->use_file].commands[st->command]; + int argc; + char **argv; + + Assert(command != NULL && command->type == META_COMMAND); + + argc = command->argc; + argv = command->argv; + + if (debug) + { + fprintf(stderr, "client %d executing \\%s", st->id, argv[0]); + for (int i = 1; i < argc; i++) + fprintf(stderr, " %s", argv[i]); + fprintf(stderr, "\n"); + } + + if (command->meta == META_SLEEP) + { + int usec; + + /* + * A \sleep doesn't execute anything, we just get the delay from the + * argument, and enter the CSTATE_SLEEP state. (The per-command + * latency will be recorded in CSTATE_SLEEP state, not here, after the + * delay has elapsed.) + */ + if (!evaluateSleep(st, argc, argv, &usec)) + { + commandFailed(st, "sleep", "execution of meta-command failed"); + return CSTATE_ABORTED; + } + + INSTR_TIME_SET_CURRENT_LAZY(*now); + st->sleep_until = INSTR_TIME_GET_MICROSEC(*now) + usec; + return CSTATE_SLEEP; + } + else if (command->meta == META_SET) + { + PgBenchExpr *expr = command->expr; + PgBenchValue result; + + if (!evaluateExpr(st, expr, &result)) + { + commandFailed(st, argv[0], "evaluation of meta-command failed"); + return CSTATE_ABORTED; + } + + if (!putVariableValue(st, argv[0], argv[1], &result)) + { + commandFailed(st, "set", "assignment of meta-command failed"); + return CSTATE_ABORTED; + } + } + else if (command->meta == META_IF) + { + /* backslash commands with an expression to evaluate */ + PgBenchExpr *expr = command->expr; + PgBenchValue result; + bool cond; - if (is_connect) - { - finishCon(st); - INSTR_TIME_SET_ZERO(now); - } + if (!evaluateExpr(st, expr, &result)) + { + commandFailed(st, argv[0], "evaluation of meta-command failed"); + return CSTATE_ABORTED; + } - if ((st->cnt >= nxacts && duration <= 0) || timer_exceeded) - { - /* exit success */ - st->state = CSTATE_FINISHED; - break; - } + cond = valueTruth(&result); + conditional_stack_push(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE); + } + else if (command->meta == META_ELIF) + { + /* backslash commands with an expression to evaluate */ + PgBenchExpr *expr = command->expr; + PgBenchValue result; + bool cond; - /* - * No transaction is underway anymore. - */ - st->state = CSTATE_CHOOSE_SCRIPT; + if (conditional_stack_peek(st->cstack) == IFSTATE_TRUE) + { + /* elif after executed block, skip eval and wait for endif. */ + conditional_stack_poke(st->cstack, IFSTATE_IGNORED); + return CSTATE_END_COMMAND; + } - /* - * If we paced through all commands in the script in this - * loop, without returning to the caller even once, do it now. - * This gives the thread a chance to process other - * connections, and to do progress reporting. This can - * currently only happen if the script consists entirely of - * meta-commands. - */ - if (end_tx_processed) - return; - else - { - end_tx_processed = true; - break; - } + if (!evaluateExpr(st, expr, &result)) + { + commandFailed(st, argv[0], "evaluation of meta-command failed"); + return CSTATE_ABORTED; + } - /* - * Final states. Close the connection if it's still open. - */ - case CSTATE_ABORTED: - case CSTATE_FINISHED: - finishCon(st); - return; + cond = valueTruth(&result); + Assert(conditional_stack_peek(st->cstack) == IFSTATE_FALSE); + conditional_stack_poke(st->cstack, cond ? IFSTATE_TRUE : IFSTATE_FALSE); + } + else if (command->meta == META_ELSE) + { + switch (conditional_stack_peek(st->cstack)) + { + case IFSTATE_TRUE: + conditional_stack_poke(st->cstack, IFSTATE_ELSE_FALSE); + break; + case IFSTATE_FALSE: /* inconsistent if active */ + case IFSTATE_IGNORED: /* inconsistent if active */ + case IFSTATE_NONE: /* else without if */ + case IFSTATE_ELSE_TRUE: /* else after else */ + case IFSTATE_ELSE_FALSE: /* else after else */ + default: + /* dead code if conditional check is ok */ + Assert(false); + } + } + else if (command->meta == META_ENDIF) + { + Assert(!conditional_stack_empty(st->cstack)); + conditional_stack_pop(st->cstack); + } + else if (command->meta == META_SETSHELL) + { + if (!runShellCommand(st, argv[1], argv + 2, argc - 2)) + { + commandFailed(st, "setshell", "execution of meta-command failed"); + return CSTATE_ABORTED; + } + } + else if (command->meta == META_SHELL) + { + if (!runShellCommand(st, NULL, argv + 1, argc - 1)) + { + commandFailed(st, "shell", "execution of meta-command failed"); + return CSTATE_ABORTED; } } + + /* + * executing the expression or shell command might have taken a + * non-negligible amount of time, so reset 'now' + */ + INSTR_TIME_SET_ZERO(*now); + + return CSTATE_END_COMMAND; } /* @@ -3292,7 +3480,7 @@ doLog(TState *thread, CState *st, * to the random sample. */ if (sample_rate != 0.0 && - pg_erand48(thread->random_state) > sample_rate) + pg_erand48(thread->ts_sample_rs.xseed) > sample_rate) return; /* should we aggregate the results or not? */ @@ -3371,8 +3559,7 @@ processXactStats(TState *thread, CState *st, instr_time *now, if (detailed && !skipped) { - if (INSTR_TIME_IS_ZERO(*now)) - INSTR_TIME_SET_CURRENT(*now); + INSTR_TIME_SET_CURRENT_LAZY(*now); /* compute latency & lag */ latency = INSTR_TIME_GET_MICROSEC(*now) - st->txn_scheduled; @@ -3436,21 +3623,82 @@ initDropTables(PGconn *con) } /* - * Create pgbench's standard tables + * Create "pgbench_accounts" partitions if needed. + * + * This is the larger table of pgbench default tpc-b like schema + * with a known size, so we choose to partition it. */ static void -initCreateTables(PGconn *con) +createPartitions(PGconn *con) { + char ff[64]; + + ff[0] = '\0'; + /* - * The scale factor at/beyond which 32-bit integers are insufficient for - * storing TPC-B account IDs. - * - * Although the actual threshold is 21474, we use 20000 because it is - * easier to document and remember, and isn't that far away from the real - * threshold. + * Per ddlinfo in initCreateTables, fillfactor is needed on table + * pgbench_accounts. */ -#define SCALE_32BIT_THRESHOLD 20000 + append_fillfactor(ff, sizeof(ff)); + + /* we must have to create some partitions */ + Assert(partitions > 0); + + fprintf(stderr, "creating %d partitions...\n", partitions); + + for (int p = 1; p <= partitions; p++) + { + char query[256]; + if (partition_method == PART_RANGE) + { + int64 part_size = (naccounts * (int64) scale + partitions - 1) / partitions; + char minvalue[32], + maxvalue[32]; + + /* + * For RANGE, we use open-ended partitions at the beginning and + * end to allow any valid value for the primary key. Although the + * actual minimum and maximum values can be derived from the + * scale, it is more generic and the performance is better. + */ + if (p == 1) + sprintf(minvalue, "minvalue"); + else + sprintf(minvalue, INT64_FORMAT, (p - 1) * part_size + 1); + + if (p < partitions) + sprintf(maxvalue, INT64_FORMAT, p * part_size + 1); + else + sprintf(maxvalue, "maxvalue"); + + snprintf(query, sizeof(query), + "create%s table pgbench_accounts_%d\n" + " partition of pgbench_accounts\n" + " for values from (%s) to (%s)%s\n", + unlogged_tables ? " unlogged" : "", p, + minvalue, maxvalue, ff); + } + else if (partition_method == PART_HASH) + snprintf(query, sizeof(query), + "create%s table pgbench_accounts_%d\n" + " partition of pgbench_accounts\n" + " for values with (modulus %d, remainder %d)%s\n", + unlogged_tables ? " unlogged" : "", p, + partitions, p - 1, ff); + else /* cannot get there */ + Assert(0); + + executeStatement(con, query); + } +} + +/* + * Create pgbench's standard tables + */ +static void +initCreateTables(PGconn *con) +{ /* * Note: TPC-B requires at least 100 bytes per row, and the "filler" * fields in these table declarations were intended to comply with that. @@ -3508,9 +3756,15 @@ initCreateTables(PGconn *con) /* Construct new create table statement. */ opts[0] = '\0'; - if (ddl->declare_fillfactor) + + /* Partition pgbench_accounts table */ + if (partition_method != PART_NONE && strcmp(ddl->table, "pgbench_accounts") == 0) snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts), - " with (fillfactor=%d)", fillfactor); + " partition by %s (aid)", PARTITION_METHOD[partition_method]); + else if (ddl->declare_fillfactor) + /* fillfactor is only expected on actual tables */ + append_fillfactor(opts, sizeof(opts)); + if (tablespace != NULL) { char *escape_tablespace; @@ -3530,6 +3784,21 @@ initCreateTables(PGconn *con) executeStatement(con, buffer); } + + if (partition_method != PART_NONE) + createPartitions(con); +} + +/* + * add fillfactor percent option. + * + * XXX - As default is 100, it could be removed in this case. + */ +static void +append_fillfactor(char *opts, int len) +{ + snprintf(opts + strlen(opts), len - strlen(opts), + " with (fillfactor=%d)", fillfactor); } /* @@ -3776,32 +4045,48 @@ checkInitSteps(const char *initialize_steps) static void runInitSteps(const char *initialize_steps) { + PQExpBufferData stats; PGconn *con; const char *step; + double run_time = 0.0; + bool first = true; + + initPQExpBuffer(&stats); if ((con = doConnect()) == NULL) exit(1); for (step = initialize_steps; *step != '\0'; step++) { + instr_time start; + char *op = NULL; + + INSTR_TIME_SET_CURRENT(start); + switch (*step) { case 'd': + op = "drop tables"; initDropTables(con); break; case 't': + op = "create tables"; initCreateTables(con); break; case 'g': + op = "generate"; initGenerateData(con); break; case 'v': + op = "vacuum"; initVacuum(con); break; case 'p': + op = "primary keys"; initCreatePKeys(con); break; case 'f': + op = "foreign keys"; initCreateFKeys(con); break; case ' ': @@ -3812,15 +4097,150 @@ runInitSteps(const char *initialize_steps) PQfinish(con); exit(1); } + + if (op != NULL) + { + instr_time diff; + double elapsed_sec; + + INSTR_TIME_SET_CURRENT(diff); + INSTR_TIME_SUBTRACT(diff, start); + elapsed_sec = INSTR_TIME_GET_DOUBLE(diff); + + if (!first) + appendPQExpBufferStr(&stats, ", "); + else + first = false; + + appendPQExpBuffer(&stats, "%s %.2f s", op, elapsed_sec); + + run_time += elapsed_sec; + } } - fprintf(stderr, "done.\n"); + fprintf(stderr, "done in %.2f s (%s).\n", run_time, stats.data); PQfinish(con); + termPQExpBuffer(&stats); +} + +/* + * Extract pgbench table informations into global variables scale, + * partition_method and partitions. + */ +static void +GetTableInfo(PGconn *con, bool scale_given) +{ + PGresult *res; + + /* + * get the scaling factor that should be same as count(*) from + * pgbench_branches if this is not a custom query + */ + res = PQexec(con, "select count(*) from pgbench_branches"); + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + char *sqlState = PQresultErrorField(res, PG_DIAG_SQLSTATE); + + fprintf(stderr, "%s", PQerrorMessage(con)); + if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) == 0) + { + fprintf(stderr, "Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\"\n", PQdb(con)); + } + + exit(1); + } + scale = atoi(PQgetvalue(res, 0, 0)); + if (scale < 0) + { + fprintf(stderr, "invalid count(*) from pgbench_branches: \"%s\"\n", + PQgetvalue(res, 0, 0)); + exit(1); + } + PQclear(res); + + /* warn if we override user-given -s switch */ + if (scale_given) + fprintf(stderr, + "scale option ignored, using count from pgbench_branches table (%d)\n", + scale); + + /* + * Get the partition information for the first "pgbench_accounts" table + * found in search_path. + * + * The result is empty if no "pgbench_accounts" is found. + * + * Otherwise, it always returns one row even if the table is not + * partitioned (in which case the partition strategy is NULL). + * + * The number of partitions can be 0 even for partitioned tables, if no + * partition is attached. + * + * We assume no partitioning on any failure, so as to avoid failing on an + * old version without "pg_partitioned_table". + */ + res = PQexec(con, + "select o.n, p.partstrat, pg_catalog.count(i.inhparent) " + "from pg_catalog.pg_class as c " + "join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) " + "cross join lateral (select pg_catalog.array_position(pg_catalog.current_schemas(true), n.nspname)) as o(n) " + "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) " + "left join pg_catalog.pg_inherits as i on (c.oid = i.inhparent) " + "where c.relname = 'pgbench_accounts' and o.n is not null " + "group by 1, 2 " + "order by 1 asc " + "limit 1"); + + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + /* probably an older version, coldly assume no partitioning */ + partition_method = PART_NONE; + partitions = 0; + } + else if (PQntuples(res) == 0) + { + /* + * This case is unlikely as pgbench already found "pgbench_branches" + * above to compute the scale. + */ + fprintf(stderr, + "no pgbench_accounts table found in search_path\n" + "Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".\n", PQdb(con)); + exit(1); + } + else /* PQntupes(res) == 1 */ + { + /* normal case, extract partition information */ + if (PQgetisnull(res, 0, 1)) + partition_method = PART_NONE; + else + { + char *ps = PQgetvalue(res, 0, 1); + + /* column must be there */ + Assert(ps != NULL); + + if (strcmp(ps, "r") == 0) + partition_method = PART_RANGE; + else if (strcmp(ps, "h") == 0) + partition_method = PART_HASH; + else + { + /* possibly a newer version with new partition method */ + fprintf(stderr, "unexpected partition method: \"%s\"\n", ps); + exit(1); + } + } + + partitions = atoi(PQgetvalue(res, 0, 2)); + } + + PQclear(res); } /* * Replace :param with $n throughout the command's SQL text, which - * is a modifiable string in cmd->argv[0]. + * is a modifiable string in cmd->lines. */ static bool parseQuery(Command *cmd) @@ -3828,12 +4248,9 @@ parseQuery(Command *cmd) char *sql, *p; - /* We don't want to scribble on cmd->argv[0] until done */ - sql = pg_strdup(cmd->argv[0]); - cmd->argc = 1; - p = sql; + p = sql = pg_strdup(cmd->lines.data); while ((p = strchr(p, ':')) != NULL) { char var[13]; @@ -3850,10 +4267,14 @@ parseQuery(Command *cmd) continue; } + /* + * cmd->argv[0] is the SQL statement itself, so the max number of + * arguments is one less than MAX_ARGS + */ if (cmd->argc >= MAX_ARGS) { fprintf(stderr, "statement has too many arguments (maximum is %d): %s\n", - MAX_ARGS - 1, cmd->argv[0]); + MAX_ARGS - 1, cmd->lines.data); pg_free(name); return false; } @@ -3865,25 +4286,11 @@ parseQuery(Command *cmd) cmd->argc++; } - pg_free(cmd->argv[0]); + Assert(cmd->argv[0] == NULL); cmd->argv[0] = sql; return true; } -/* - * Simple error-printing function, might be needed by lexer - */ -static void -pgbench_error(const char *fmt,...) -{ - va_list ap; - - fflush(stdout); - va_start(ap, fmt); - vfprintf(stderr, _(fmt), ap); - va_end(ap); -} - /* * syntax error while parsing a script (in practice, while parsing a * backslash command, because we don't detect syntax errors in SQL) @@ -3925,21 +4332,16 @@ syntax_error(const char *source, int lineno, } /* - * Parse a SQL command; return a Command struct, or NULL if it's a comment - * - * On entry, psqlscan.l has collected the command into "buf", so we don't - * really need to do much here except check for comment and set up a - * Command struct. + * Return a pointer to the start of the SQL command, after skipping over + * whitespace and "--" comments. + * If the end of the string is reached, return NULL. */ -static Command * -process_sql_command(PQExpBuffer buf, const char *source) +static char * +skip_sql_comments(char *sql_command) { - Command *my_command; - char *p; - char *nlpos; + char *p = sql_command; /* Skip any leading whitespace, as well as "--" style comments */ - p = buf->data; for (;;) { if (isspace((unsigned char) *p)) @@ -3955,39 +4357,95 @@ process_sql_command(PQExpBuffer buf, const char *source) break; } - /* If there's nothing but whitespace and comments, we're done */ + /* NULL if there's nothing but whitespace and comments */ if (*p == '\0') return NULL; + return p; +} + +/* + * Parse a SQL command; return a Command struct, or NULL if it's a comment + * + * On entry, psqlscan.l has collected the command into "buf", so we don't + * really need to do much here except check for comments and set up a Command + * struct. + */ +static Command * +create_sql_command(PQExpBuffer buf, const char *source) +{ + Command *my_command; + char *p = skip_sql_comments(buf->data); + + if (p == NULL) + return NULL; + /* Allocate and initialize Command structure */ - my_command = (Command *) pg_malloc0(sizeof(Command)); - my_command->command_num = num_commands++; + my_command = (Command *) pg_malloc(sizeof(Command)); + initPQExpBuffer(&my_command->lines); + appendPQExpBufferStr(&my_command->lines, p); + my_command->first_line = NULL; /* this is set later */ my_command->type = SQL_COMMAND; my_command->meta = META_NONE; + my_command->argc = 0; + memset(my_command->argv, 0, sizeof(my_command->argv)); + my_command->varprefix = NULL; /* allocated later, if needed */ + my_command->expr = NULL; initSimpleStats(&my_command->stats); - /* - * Install query text as the sole argv string. If we are using a - * non-simple query mode, we'll extract parameters from it later. - */ - my_command->argv[0] = pg_strdup(p); - my_command->argc = 1; + return my_command; +} + +/* Free a Command structure and associated data */ +static void +free_command(Command *command) +{ + termPQExpBuffer(&command->lines); + if (command->first_line) + pg_free(command->first_line); + for (int i = 0; i < command->argc; i++) + pg_free(command->argv[i]); + if (command->varprefix) + pg_free(command->varprefix); /* - * If SQL command is multi-line, we only want to save the first line as - * the "line" label. + * It should also free expr recursively, but this is currently not needed + * as only gset commands (which do not have an expression) are freed. */ - nlpos = strchr(p, '\n'); - if (nlpos) + pg_free(command); +} + +/* + * Once an SQL command is fully parsed, possibly by accumulating several + * parts, complete other fields of the Command structure. + */ +static void +postprocess_sql_command(Command *my_command) +{ + char buffer[128]; + + Assert(my_command->type == SQL_COMMAND); + + /* Save the first line for error display. */ + strlcpy(buffer, my_command->lines.data, sizeof(buffer)); + buffer[strcspn(buffer, "\n\r")] = '\0'; + my_command->first_line = pg_strdup(buffer); + + /* parse query if necessary */ + switch (querymode) { - my_command->line = pg_malloc(nlpos - p + 1); - memcpy(my_command->line, p, nlpos - p); - my_command->line[nlpos - p] = '\0'; + case QUERY_SIMPLE: + my_command->argv[0] = my_command->lines.data; + my_command->argc++; + break; + case QUERY_EXTENDED: + case QUERY_PREPARED: + if (!parseQuery(my_command)) + exit(1); + break; + default: + exit(1); } - else - my_command->line = pg_strdup(p); - - return my_command; } /* @@ -4021,7 +4479,6 @@ process_backslash_command(PsqlScanState sstate, const char *source) /* Allocate and initialize Command structure */ my_command = (Command *) pg_malloc0(sizeof(Command)); - my_command->command_num = num_commands++; my_command->type = META_COMMAND; my_command->argc = 0; initSimpleStats(&my_command->stats); @@ -4045,7 +4502,7 @@ process_backslash_command(PsqlScanState sstate, const char *source) if (my_command->meta == META_SET) { if (!expr_lex_one_word(sstate, &word_buf, &word_offset)) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "missing argument", NULL, -1); offsets[j] = word_offset; @@ -4066,10 +4523,11 @@ process_backslash_command(PsqlScanState sstate, const char *source) my_command->expr = expr_parse_result; /* Save line, trimming any trailing newline */ - my_command->line = expr_scanner_get_substring(sstate, - start_offset, - expr_scanner_offset(sstate), - true); + my_command->first_line = + expr_scanner_get_substring(sstate, + start_offset, + expr_scanner_offset(sstate), + true); expr_scanner_finish(yyscanner); @@ -4081,8 +4539,12 @@ process_backslash_command(PsqlScanState sstate, const char *source) /* For all other commands, collect remaining words. */ while (expr_lex_one_word(sstate, &word_buf, &word_offset)) { + /* + * my_command->argv[0] is the command itself, so the max number of + * arguments is one less than MAX_ARGS + */ if (j >= MAX_ARGS) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "too many arguments", NULL, -1); offsets[j] = word_offset; @@ -4091,19 +4553,20 @@ process_backslash_command(PsqlScanState sstate, const char *source) } /* Save line, trimming any trailing newline */ - my_command->line = expr_scanner_get_substring(sstate, - start_offset, - expr_scanner_offset(sstate), - true); + my_command->first_line = + expr_scanner_get_substring(sstate, + start_offset, + expr_scanner_offset(sstate), + true); if (my_command->meta == META_SLEEP) { if (my_command->argc < 2) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "missing argument", NULL, -1); if (my_command->argc > 3) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "too many arguments", NULL, offsets[3] - start_offset); @@ -4132,7 +4595,7 @@ process_backslash_command(PsqlScanState sstate, const char *source) if (pg_strcasecmp(my_command->argv[2], "us") != 0 && pg_strcasecmp(my_command->argv[2], "ms") != 0 && pg_strcasecmp(my_command->argv[2], "s") != 0) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "unrecognized time unit, must be us, ms or s", my_command->argv[2], offsets[2] - start_offset); } @@ -4140,25 +4603,31 @@ process_backslash_command(PsqlScanState sstate, const char *source) else if (my_command->meta == META_SETSHELL) { if (my_command->argc < 3) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "missing argument", NULL, -1); } else if (my_command->meta == META_SHELL) { if (my_command->argc < 2) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "missing command", NULL, -1); } else if (my_command->meta == META_ELSE || my_command->meta == META_ENDIF) { if (my_command->argc != 1) - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "unexpected argument", NULL, -1); } + else if (my_command->meta == META_GSET) + { + if (my_command->argc > 2) + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], + "too many arguments", NULL, -1); + } else { /* my_command->meta == META_NONE */ - syntax_error(source, lineno, my_command->line, my_command->argv[0], + syntax_error(source, lineno, my_command->first_line, my_command->argv[0], "invalid command", NULL, -1); } @@ -4184,42 +4653,44 @@ CheckConditional(ParsedScript ps) { /* statically check conditional structure */ ConditionalStack cs = conditional_stack_create(); - int i; - for (i = 0 ; ps.commands[i] != NULL ; i++) + int i; + + for (i = 0; ps.commands[i] != NULL; i++) { - Command *cmd = ps.commands[i]; + Command *cmd = ps.commands[i]; + if (cmd->type == META_COMMAND) { switch (cmd->meta) { - case META_IF: - conditional_stack_push(cs, IFSTATE_FALSE); - break; - case META_ELIF: - if (conditional_stack_empty(cs)) - ConditionError(ps.desc, i+1, "\\elif without matching \\if"); - if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) - ConditionError(ps.desc, i+1, "\\elif after \\else"); - break; - case META_ELSE: - if (conditional_stack_empty(cs)) - ConditionError(ps.desc, i+1, "\\else without matching \\if"); - if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) - ConditionError(ps.desc, i+1, "\\else after \\else"); - conditional_stack_poke(cs, IFSTATE_ELSE_FALSE); - break; - case META_ENDIF: - if (!conditional_stack_pop(cs)) - ConditionError(ps.desc, i+1, "\\endif without matching \\if"); - break; - default: - /* ignore anything else... */ - break; + case META_IF: + conditional_stack_push(cs, IFSTATE_FALSE); + break; + case META_ELIF: + if (conditional_stack_empty(cs)) + ConditionError(ps.desc, i + 1, "\\elif without matching \\if"); + if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) + ConditionError(ps.desc, i + 1, "\\elif after \\else"); + break; + case META_ELSE: + if (conditional_stack_empty(cs)) + ConditionError(ps.desc, i + 1, "\\else without matching \\if"); + if (conditional_stack_peek(cs) == IFSTATE_ELSE_FALSE) + ConditionError(ps.desc, i + 1, "\\else after \\else"); + conditional_stack_poke(cs, IFSTATE_ELSE_FALSE); + break; + case META_ENDIF: + if (!conditional_stack_pop(cs)) + ConditionError(ps.desc, i + 1, "\\endif without matching \\if"); + break; + default: + /* ignore anything else... */ + break; } } } if (!conditional_stack_empty(cs)) - ConditionError(ps.desc, i+1, "\\if without matching \\endif"); + ConditionError(ps.desc, i + 1, "\\if without matching \\endif"); conditional_stack_destroy(cs); } @@ -4235,6 +4706,8 @@ ParseScript(const char *script, const char *desc, int weight) PQExpBufferData line_buf; int alloc_num; int index; + int lineno; + int start_offset; #define COMMANDS_ALLOC_NUM 128 alloc_num = COMMANDS_ALLOC_NUM; @@ -4258,6 +4731,7 @@ ParseScript(const char *script, const char *desc, int weight) * stdstrings should be true, which is a bit riskier. */ psql_scan_setup(sstate, script, strlen(script), 0, true); + start_offset = expr_scanner_offset(sstate) - 1; initPQExpBuffer(&line_buf); @@ -4267,43 +4741,75 @@ ParseScript(const char *script, const char *desc, int weight) { PsqlScanResult sr; promptStatus_t prompt; - Command *command; + Command *command = NULL; resetPQExpBuffer(&line_buf); + lineno = expr_scanner_get_lineno(sstate, start_offset); sr = psql_scan(sstate, &line_buf, &prompt); - /* If we collected a SQL command, process that */ - command = process_sql_command(&line_buf, desc); + /* If we collected a new SQL command, process that */ + command = create_sql_command(&line_buf, desc); + + /* store new command */ if (command) + ps.commands[index++] = command; + + /* If we reached a backslash, process that */ + if (sr == PSCAN_BACKSLASH) { - ps.commands[index] = command; - index++; + command = process_backslash_command(sstate, desc); + + if (command) + { + /* + * If this is gset, merge into the preceding command. (We + * don't use a command slot in this case). + */ + if (command->meta == META_GSET) + { + Command *cmd; + + if (index == 0) + syntax_error(desc, lineno, NULL, NULL, + "\\gset must follow a SQL command", + NULL, -1); + + cmd = ps.commands[index - 1]; + + if (cmd->type != SQL_COMMAND || + cmd->varprefix != NULL) + syntax_error(desc, lineno, NULL, NULL, + "\\gset must follow a SQL command", + cmd->first_line, -1); + + /* get variable prefix */ + if (command->argc <= 1 || command->argv[1][0] == '\0') + cmd->varprefix = pg_strdup(""); + else + cmd->varprefix = pg_strdup(command->argv[1]); + + /* cleanup unused command */ + free_command(command); + + continue; + } - if (index >= alloc_num) - { - alloc_num += COMMANDS_ALLOC_NUM; - ps.commands = (Command **) - pg_realloc(ps.commands, sizeof(Command *) * alloc_num); + /* Attach any other backslash command as a new command */ + ps.commands[index++] = command; } } - /* If we reached a backslash, process that */ - if (sr == PSCAN_BACKSLASH) + /* + * Since we used a command slot, allocate more if needed. Note we + * always allocate one more in order to accommodate the NULL + * terminator below. + */ + if (index >= alloc_num) { - command = process_backslash_command(sstate, desc); - if (command) - { - ps.commands[index] = command; - index++; - - if (index >= alloc_num) - { - alloc_num += COMMANDS_ALLOC_NUM; - ps.commands = (Command **) - pg_realloc(ps.commands, sizeof(Command *) * alloc_num); - } - } + alloc_num += COMMANDS_ALLOC_NUM; + ps.commands = (Command **) + pg_realloc(ps.commands, sizeof(Command *) * alloc_num); } /* Done if we reached EOF */ @@ -4407,7 +4913,7 @@ listAvailableScripts(void) fprintf(stderr, "Available builtin scripts:\n"); for (i = 0; i < lengthof(builtin_script); i++) - fprintf(stderr, "\t%s\n", builtin_script[i].name); + fprintf(stderr, " %13s: %s\n", builtin_script[i].name, builtin_script[i].desc); fprintf(stderr, "\n"); } @@ -4514,6 +5020,99 @@ addScript(ParsedScript script) num_scripts++; } +/* + * Print progress report. + * + * On entry, *last and *last_report contain the statistics and time of last + * progress report. On exit, they are updated with the new stats. + */ +static void +printProgressReport(TState *threads, int64 test_start, int64 now, + StatsData *last, int64 *last_report) +{ + /* generate and show report */ + int64 run = now - *last_report, + ntx; + double tps, + total_run, + latency, + sqlat, + lag, + stdev; + char tbuf[315]; + StatsData cur; + + /* + * Add up the statistics of all threads. + * + * XXX: No locking. There is no guarantee that we get an atomic snapshot + * of the transaction count and latencies, so these figures can well be + * off by a small amount. The progress report's purpose is to give a + * quick overview of how the test is going, so that shouldn't matter too + * much. (If a read from a 64-bit integer is not atomic, you might get a + * "torn" read and completely bogus latencies though!) + */ + initStats(&cur, 0); + for (int i = 0; i < nthreads; i++) + { + mergeSimpleStats(&cur.latency, &threads[i].stats.latency); + mergeSimpleStats(&cur.lag, &threads[i].stats.lag); + cur.cnt += threads[i].stats.cnt; + cur.skipped += threads[i].stats.skipped; + } + + /* we count only actually executed transactions */ + ntx = (cur.cnt - cur.skipped) - (last->cnt - last->skipped); + total_run = (now - test_start) / 1000000.0; + tps = 1000000.0 * ntx / run; + if (ntx > 0) + { + latency = 0.001 * (cur.latency.sum - last->latency.sum) / ntx; + sqlat = 1.0 * (cur.latency.sum2 - last->latency.sum2) / ntx; + stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency); + lag = 0.001 * (cur.lag.sum - last->lag.sum) / ntx; + } + else + { + latency = sqlat = stdev = lag = 0; + } + + if (progress_timestamp) + { + /* + * On some platforms the current system timestamp is available in + * now_time, but rather than get entangled with that, we just eat the + * cost of an extra syscall in all cases. + */ + struct timeval tv; + + gettimeofday(&tv, NULL); + snprintf(tbuf, sizeof(tbuf), "%ld.%03ld s", + (long) tv.tv_sec, (long) (tv.tv_usec / 1000)); + } + else + { + /* round seconds are expected, but the thread may be late */ + snprintf(tbuf, sizeof(tbuf), "%.1f s", total_run); + } + + fprintf(stderr, + "progress: %s, %.1f tps, lat %.3f ms stddev %.3f", + tbuf, tps, latency, stdev); + + if (throttle_delay) + { + fprintf(stderr, ", lag %.3f ms", lag); + if (latency_limit) + fprintf(stderr, ", " INT64_FORMAT " skipped", + cur.skipped - last->skipped); + } + fprintf(stderr, "\n"); + + *last = cur; + *last_report = now; +} + static void printSimpleStats(const char *prefix, SimpleStats *ss) { @@ -4529,15 +5128,13 @@ printSimpleStats(const char *prefix, SimpleStats *ss) /* print out results */ static void -printResults(TState *threads, StatsData *total, instr_time total_time, +printResults(StatsData *total, instr_time total_time, instr_time conn_total_time, int64 latency_late) { double time_include, tps_include, tps_exclude; int64 ntx = total->cnt - total->skipped; - int i, - totalCacheOverflows = 0; time_include = INSTR_TIME_GET_DOUBLE(total_time); @@ -4550,6 +5147,10 @@ printResults(TState *threads, StatsData *total, instr_time total_time, printf("transaction type: %s\n", num_scripts == 1 ? sql_script[0].desc : "multiple scripts"); printf("scaling factor: %d\n", scale); + /* only print partitioning information if some partitioning was detected */ + if (partition_method != PART_NONE) + printf("partition method: %s\npartitions: %d\n", + PARTITION_METHOD[partition_method], partitions); printf("query mode: %s\n", QUERYMODE[querymode]); printf("number of clients: %d\n", nclients); printf("number of threads: %d\n", nthreads); @@ -4565,15 +5166,6 @@ printResults(TState *threads, StatsData *total, instr_time total_time, printf("number of transactions actually processed: " INT64_FORMAT "\n", ntx); } - /* Report zipfian cache overflow */ - for (i = 0; i < nthreads; i++) - { - totalCacheOverflows += threads[i].zipf_cache.overflowCount; - } - if (totalCacheOverflows > 0) - { - printf("zipfian cache array overflowed %d time(s)\n", totalCacheOverflows); - } /* Remaining stats are nonsensical if we failed to execute any xacts */ if (total->cnt <= 0) @@ -4614,7 +5206,7 @@ printResults(TState *threads, StatsData *total, instr_time total_time, printf("tps = %f (excluding connections establishing)\n", tps_exclude); /* Report per-script/command statistics */ - if (per_script_stats || is_latencies) + if (per_script_stats || report_per_command) { int i; @@ -4643,7 +5235,7 @@ printResults(TState *threads, StatsData *total, instr_time total_time, } /* Report per-command latencies */ - if (is_latencies) + if (report_per_command) { Command **commands; @@ -4661,62 +5253,68 @@ printResults(TState *threads, StatsData *total, instr_time total_time, printf(" %11.3f %s\n", (cstats->count > 0) ? 1000.0 * cstats->sum / cstats->count : 0.0, - (*commands)->line); + (*commands)->first_line); } } } } } -/* call srandom based on some seed. NULL triggers the default behavior. */ +/* + * Set up a random seed according to seed parameter (NULL means default), + * and initialize base_random_sequence for use in initializing other sequences. + */ static bool set_random_seed(const char *seed) { - /* srandom expects an unsigned int */ - unsigned int iseed; + uint64 iseed; if (seed == NULL || strcmp(seed, "time") == 0) { /* rely on current time */ instr_time now; + INSTR_TIME_SET_CURRENT(now); - iseed = (unsigned int) INSTR_TIME_GET_MICROSEC(now); + iseed = (uint64) INSTR_TIME_GET_MICROSEC(now); } else if (strcmp(seed, "rand") == 0) { /* use some "strong" random source */ -#ifdef HAVE_STRONG_RANDOM if (!pg_strong_random(&iseed, sizeof(iseed))) -#endif { - fprintf(stderr, - "cannot seed random from a strong source, none available: " - "use \"time\" or an unsigned integer value.\n"); + fprintf(stderr, "could not generate random seed.\n"); return false; } } else { - /* parse seed unsigned int value */ - char garbage; - if (sscanf(seed, "%u%c", &iseed, &garbage) != 1) + /* parse unsigned-int seed value */ + unsigned long ulseed; + char garbage; + + /* Don't try to use UINT64_FORMAT here; it might not work for sscanf */ + if (sscanf(seed, "%lu%c", &ulseed, &garbage) != 1) { fprintf(stderr, "unrecognized random seed option \"%s\": expecting an unsigned integer, \"time\" or \"rand\"\n", seed); return false; } + iseed = (uint64) ulseed; } if (seed != NULL) - fprintf(stderr, "setting random seed to %u\n", iseed); - srandom(iseed); - /* no precision loss: 32 bit unsigned int cast to 64 bit int */ + fprintf(stderr, "setting random seed to " UINT64_FORMAT "\n", iseed); random_seed = iseed; + + /* Fill base_random_sequence with low-order bits of seed */ + base_random_sequence.xseed[0] = iseed & 0xFFFF; + base_random_sequence.xseed[1] = (iseed >> 16) & 0xFFFF; + base_random_sequence.xseed[2] = (iseed >> 32) & 0xFFFF; + return true; } - int main(int argc, char **argv) { @@ -4759,6 +5357,9 @@ main(int argc, char **argv) {"log-prefix", required_argument, NULL, 7}, {"foreign-keys", no_argument, NULL, 8}, {"random-seed", required_argument, NULL, 9}, + {"show-script", required_argument, NULL, 10}, + {"partitions", required_argument, NULL, 11}, + {"partition-method", required_argument, NULL, 12}, {NULL, 0, NULL, 0} }; @@ -4793,9 +5394,11 @@ main(int argc, char **argv) #endif PGconn *con; - PGresult *res; char *env; + int exit_code = 0; + + pg_logging_init(argv[0]); progname = get_progname(argv[0]); if (argc > 1) @@ -4812,11 +5415,6 @@ main(int argc, char **argv) } } -#ifdef WIN32 - /* stderr is buffered on Win32. */ - setvbuf(stderr, NULL, _IONBF, 0); -#endif - if ((env = getenv("PGHOST")) != NULL && *env != '\0') pghost = env; if ((env = getenv("PGPORT")) != NULL && *env != '\0') @@ -4824,8 +5422,7 @@ main(int argc, char **argv) else if ((env = getenv("PGUSER")) != NULL && *env != '\0') login = env; - state = (CState *) pg_malloc(sizeof(CState)); - memset(state, 0, sizeof(CState)); + state = (CState *) pg_malloc0(sizeof(CState)); /* set random seed early, because it may be used while parsing scripts. */ if (!set_random_seed(getenv("PGBENCH_RANDOM_SEED"))) @@ -4869,7 +5466,7 @@ main(int argc, char **argv) case 'c': benchmarking_option_set = true; nclients = atoi(optarg); - if (nclients <= 0 || nclients > MAXCLIENTS) + if (nclients <= 0) { fprintf(stderr, "invalid number of clients: \"%s\"\n", optarg); @@ -4917,7 +5514,7 @@ main(int argc, char **argv) break; case 'r': benchmarking_option_set = true; - is_latencies = true; + report_per_command = true; break; case 's': scale_given = true; @@ -5045,8 +5642,8 @@ main(int argc, char **argv) fprintf(stderr, "invalid rate limit: \"%s\"\n", optarg); exit(1); } - /* Invert rate limit into a time offset */ - throttle_delay = (int64) (1000000.0 / throttle_value); + /* Invert rate limit into per-transaction delay in usec */ + throttle_delay = 1000000.0 / throttle_value; } break; case 'L': @@ -5114,6 +5711,37 @@ main(int argc, char **argv) exit(1); } break; + case 10: /* list */ + { + const BuiltinScript *s = findBuiltin(optarg); + + fprintf(stderr, "-- %s: %s\n%s\n", s->name, s->desc, s->script); + exit(0); + } + break; + case 11: /* partitions */ + initialization_option_set = true; + partitions = atoi(optarg); + if (partitions < 0) + { + fprintf(stderr, "invalid number of partitions: \"%s\"\n", + optarg); + exit(1); + } + break; + case 12: /* partition-method */ + initialization_option_set = true; + if (pg_strcasecmp(optarg, "range") == 0) + partition_method = PART_RANGE; + else if (pg_strcasecmp(optarg, "hash") == 0) + partition_method = PART_HASH; + else + { + fprintf(stderr, "invalid partition method, expecting \"range\" or \"hash\"," + " got: \"%s\"\n", optarg); + exit(1); + } + break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -5129,28 +5757,18 @@ main(int argc, char **argv) internal_script_used = true; } - /* if not simple query mode, parse the script(s) to find parameters */ - if (querymode != QUERY_SIMPLE) + /* complete SQL command initialization and compute total weight */ + for (i = 0; i < num_scripts; i++) { - for (i = 0; i < num_scripts; i++) - { - Command **commands = sql_script[i].commands; - int j; + Command **commands = sql_script[i].commands; - for (j = 0; commands[j] != NULL; j++) - { - if (commands[j]->type != SQL_COMMAND) - continue; - if (!parseQuery(commands[j])) - exit(1); - } - } - } + for (int j = 0; commands[j] != NULL; j++) + if (commands[j]->type == SQL_COMMAND) + postprocess_sql_command(commands[j]); - /* compute total_weight */ - for (i = 0; i < num_scripts; i++) /* cannot overflow: weight is 32b, total_weight 64b */ total_weight += sql_script[i].weight; + } if (total_weight == 0 && !is_init_mode) { @@ -5170,11 +5788,15 @@ main(int argc, char **argv) if (nthreads > nclients) nthreads = nclients; - /* compute a per thread delay */ + /* + * Convert throttle_delay to a per-thread delay time. Note that this + * might be a fractional number of usec, but that's OK, since it's just + * the center of a Poisson distribution of delays. + */ throttle_delay *= nthreads; if (argc > optind) - dbName = argv[optind]; + dbName = argv[optind++]; else { if ((env = getenv("PGDATABASE")) != NULL && *env != '\0') @@ -5185,6 +5807,14 @@ main(int argc, char **argv) dbName = ""; } + if (optind < argc) + { + fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), + progname, argv[optind]); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + if (is_init_mode) { if (benchmarking_option_set) @@ -5193,6 +5823,16 @@ main(int argc, char **argv) exit(1); } + if (partitions == 0 && partition_method != PART_NONE) + { + fprintf(stderr, "--partition-method requires greater than zero --partitions\n"); + exit(1); + } + + /* set default method */ + if (partitions > 0 && partition_method == PART_NONE) + partition_method = PART_RANGE; + if (initialize_steps == NULL) initialize_steps = pg_strdup(DEFAULT_INIT_STEPS); @@ -5307,7 +5947,7 @@ main(int argc, char **argv) if (var->value.type != PGBT_NO_VALUE) { if (!putVariableValue(&state[i], "startup", - var->name, &var->value)) + var->name, &var->value)) exit(1); } else @@ -5324,6 +5964,7 @@ main(int argc, char **argv) for (i = 0; i < nclients; i++) { state[i].cstack = conditional_stack_create(); + initRandomState(&state[i].cs_func_rs); } if (debug) @@ -5349,39 +5990,7 @@ main(int argc, char **argv) } if (internal_script_used) - { - /* - * get the scaling factor that should be same as count(*) from - * pgbench_branches if this is not a custom query - */ - res = PQexec(con, "select count(*) from pgbench_branches"); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - char *sqlState = PQresultErrorField(res, PG_DIAG_SQLSTATE); - - fprintf(stderr, "%s", PQerrorMessage(con)); - if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) == 0) - { - fprintf(stderr, "Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\"\n", PQdb(con)); - } - - exit(1); - } - scale = atoi(PQgetvalue(res, 0, 0)); - if (scale < 0) - { - fprintf(stderr, "invalid count(*) from pgbench_branches: \"%s\"\n", - PQgetvalue(res, 0, 0)); - exit(1); - } - PQclear(res); - - /* warn if we override user-given -s switch */ - if (scale_given) - fprintf(stderr, - "scale option ignored, using count from pgbench_branches table (%d)\n", - scale); - } + GetTableInfo(con, scale_given); /* * :scale variables normally get -s or database scale, but don't override @@ -5410,10 +6019,9 @@ main(int argc, char **argv) /* set default seed for hash functions */ if (lookupVariable(&state[0], "default_seed") == NULL) { - uint64 seed = ((uint64) (random() & 0xFFFF) << 48) | - ((uint64) (random() & 0xFFFF) << 32) | - ((uint64) (random() & 0xFFFF) << 16) | - (uint64) (random() & 0xFFFF); + uint64 seed = + ((uint64) pg_jrand48(base_random_sequence.xseed) & 0xFFFFFFFF) | + (((uint64) pg_jrand48(base_random_sequence.xseed) & 0xFFFFFFFF) << 32); for (i = 0; i < nclients; i++) if (!putVariableInt(&state[i], "startup", "default_seed", (int64) seed)) @@ -5457,14 +6065,11 @@ main(int argc, char **argv) thread->state = &state[nclients_dealt]; thread->nstate = (nclients - nclients_dealt + nthreads - i - 1) / (nthreads - i); - thread->random_state[0] = random(); - thread->random_state[1] = random(); - thread->random_state[2] = random(); + initRandomState(&thread->ts_choose_rs); + initRandomState(&thread->ts_throttle_rs); + initRandomState(&thread->ts_sample_rs); thread->logfile = NULL; /* filled in later */ thread->latency_late = 0; - thread->zipf_cache.nb_cells = 0; - thread->zipf_cache.current = 0; - thread->zipf_cache.overflowCount = 0; initStats(&thread->stats, 0); nclients_dealt += thread->nstate; @@ -5536,6 +6141,10 @@ main(int argc, char **argv) (void) threadRun(thread); #endif /* ENABLE_THREAD_SAFETY */ + for (int j = 0; j < thread->nstate; j++) + if (thread->state[j].state == CSTATE_ABORTED) + exit_code = 2; + /* aggregate thread level stats */ mergeSimpleStats(&stats.latency, &thread->stats.latency); mergeSimpleStats(&stats.lag, &thread->stats.lag); @@ -5558,9 +6167,12 @@ main(int argc, char **argv) */ INSTR_TIME_SET_CURRENT(total_time); INSTR_TIME_SUBTRACT(total_time, start_time); - printResults(threads, &stats, total_time, conn_total_time, latency_late); + printResults(&stats, total_time, conn_total_time, latency_late); - return 0; + if (exit_code != 0) + fprintf(stderr, "Run was aborted; the above results are incomplete.\n"); + + return exit_code; } static void * @@ -5572,6 +6184,7 @@ threadRun(void *arg) end; int nstate = thread->nstate; int remains = nstate; /* number of remaining clients */ + socket_set *sockets = alloc_socket_set(nstate); int i; /* for reporting progress: */ @@ -5618,7 +6231,7 @@ threadRun(void *arg) if (!is_connect) { - /* make connections to the database */ + /* make connections to the database before starting */ for (i = 0; i < nstate; i++) { if ((state[i].con = doConnect()) == NULL) @@ -5639,27 +6252,22 @@ threadRun(void *arg) /* loop till all clients have terminated */ while (remains > 0) { - fd_set input_mask; - int maxsock; /* max socket number to be waited for */ + int nsocks; /* number of sockets to be waited for */ int64 min_usec; int64 now_usec = 0; /* set this only if needed */ - /* identify which client sockets should be checked for input */ - FD_ZERO(&input_mask); - maxsock = -1; + /* + * identify which client sockets should be checked for input, and + * compute the nearest time (if any) at which we need to wake up. + */ + clear_socket_set(sockets); + nsocks = 0; min_usec = PG_INT64_MAX; for (i = 0; i < nstate; i++) { CState *st = &state[i]; - if (st->state == CSTATE_THROTTLE && timer_exceeded) - { - /* interrupt client that has not started a transaction */ - st->state = CSTATE_FINISHED; - finishCon(st); - remains--; - } - else if (st->state == CSTATE_SLEEP || st->state == CSTATE_THROTTLE) + if (st->state == CSTATE_SLEEP || st->state == CSTATE_THROTTLE) { /* a nap from the script, or under throttling */ int64 this_usec; @@ -5694,9 +6302,7 @@ threadRun(void *arg) goto done; } - FD_SET(sock, &input_mask); - if (maxsock < sock) - maxsock = sock; + add_socket_to_set(sockets, sock, nsocks++); } else if (st->state != CSTATE_ABORTED && st->state != CSTATE_FINISHED) @@ -5730,35 +6336,29 @@ threadRun(void *arg) /* * If no clients are ready to execute actions, sleep until we receive - * data from the server, or a nap-time specified in the script ends, - * or it's time to print a progress report. Update input_mask to show - * which client(s) received data. + * data on some client socket or the timeout (if any) elapses. */ if (min_usec > 0) { - int nsocks = 0; /* return from select(2) if called */ + int rc = 0; if (min_usec != PG_INT64_MAX) { - if (maxsock != -1) + if (nsocks > 0) { - struct timeval timeout; - - timeout.tv_sec = min_usec / 1000000; - timeout.tv_usec = min_usec % 1000000; - nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout); + rc = wait_on_socket_set(sockets, min_usec); } else /* nothing active, simple sleep */ { pg_usleep(min_usec); } } - else /* no explicit delay, select without timeout */ + else /* no explicit delay, wait without timeout */ { - nsocks = select(maxsock + 1, &input_mask, NULL, NULL, NULL); + rc = wait_on_socket_set(sockets, 0); } - if (nsocks < 0) + if (rc < 0) { if (errno == EINTR) { @@ -5766,26 +6366,27 @@ threadRun(void *arg) continue; } /* must be something wrong */ - fprintf(stderr, "select() failed: %s\n", strerror(errno)); + fprintf(stderr, "%s() failed: %s\n", SOCKET_WAIT_METHOD, strerror(errno)); goto done; } } else { - /* min_usec == 0, i.e. something needs to be executed */ + /* min_usec <= 0, i.e. something needs to be executed now */ - /* If we didn't call select(), don't try to read any data */ - FD_ZERO(&input_mask); + /* If we didn't wait, don't try to read any data */ + clear_socket_set(sockets); } /* ok, advance the state machine of each connection */ + nsocks = 0; for (i = 0; i < nstate; i++) { CState *st = &state[i]; if (st->state == CSTATE_WAIT_RESULT) { - /* don't call doCustom unless data is available */ + /* don't call advanceConnectionState unless data is available */ int sock = PQsocket(st->con); if (sock < 0) @@ -5795,7 +6396,7 @@ threadRun(void *arg) goto done; } - if (!FD_ISSET(sock, &input_mask)) + if (!socket_has_input(sockets, sock, nsocks++)) continue; } else if (st->state == CSTATE_FINISHED || @@ -5805,9 +6406,12 @@ threadRun(void *arg) continue; } - doCustom(thread, st, &aggs); + advanceConnectionState(thread, st, &aggs); - /* If doCustom changed client to finished state, reduce remains */ + /* + * If advanceConnectionState changed client to finished state, + * that's one less client that remains. + */ if (st->state == CSTATE_FINISHED || st->state == CSTATE_ABORTED) remains--; } @@ -5822,89 +6426,14 @@ threadRun(void *arg) now = INSTR_TIME_GET_MICROSEC(now_time); if (now >= next_report) { - /* generate and show report */ - StatsData cur; - int64 run = now - last_report, - ntx; - double tps, - total_run, - latency, - sqlat, - lag, - stdev; - char tbuf[315]; - /* - * Add up the statistics of all threads. - * - * XXX: No locking. There is no guarantee that we get an - * atomic snapshot of the transaction count and latencies, so - * these figures can well be off by a small amount. The - * progress report's purpose is to give a quick overview of - * how the test is going, so that shouldn't matter too much. - * (If a read from a 64-bit integer is not atomic, you might - * get a "torn" read and completely bogus latencies though!) + * Horrible hack: this relies on the thread pointer we are + * passed to be equivalent to threads[0], that is the first + * entry of the threads array. That is why this MUST be done + * by thread 0 and not any other. */ - initStats(&cur, 0); - for (i = 0; i < nthreads; i++) - { - mergeSimpleStats(&cur.latency, &thread[i].stats.latency); - mergeSimpleStats(&cur.lag, &thread[i].stats.lag); - cur.cnt += thread[i].stats.cnt; - cur.skipped += thread[i].stats.skipped; - } - - /* we count only actually executed transactions */ - ntx = (cur.cnt - cur.skipped) - (last.cnt - last.skipped); - total_run = (now - thread_start) / 1000000.0; - tps = 1000000.0 * ntx / run; - if (ntx > 0) - { - latency = 0.001 * (cur.latency.sum - last.latency.sum) / ntx; - sqlat = 1.0 * (cur.latency.sum2 - last.latency.sum2) / ntx; - stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency); - lag = 0.001 * (cur.lag.sum - last.lag.sum) / ntx; - } - else - { - latency = sqlat = stdev = lag = 0; - } - - if (progress_timestamp) - { - /* - * On some platforms the current system timestamp is - * available in now_time, but rather than get entangled - * with that, we just eat the cost of an extra syscall in - * all cases. - */ - struct timeval tv; - - gettimeofday(&tv, NULL); - snprintf(tbuf, sizeof(tbuf), "%ld.%03ld s", - (long) tv.tv_sec, (long) (tv.tv_usec / 1000)); - } - else - { - /* round seconds are expected, but the thread may be late */ - snprintf(tbuf, sizeof(tbuf), "%.1f s", total_run); - } - - fprintf(stderr, - "progress: %s, %.1f tps, lat %.3f ms stddev %.3f", - tbuf, tps, latency, stdev); - - if (throttle_delay) - { - fprintf(stderr, ", lag %.3f ms", lag); - if (latency_limit) - fprintf(stderr, ", " INT64_FORMAT " skipped", - cur.skipped - last.skipped); - } - fprintf(stderr, "\n"); - - last = cur; - last_report = now; + printProgressReport(thread, thread_start, now, + &last, &last_report); /* * Ensure that the next report is in the future, in case @@ -5933,6 +6462,7 @@ threadRun(void *arg) fclose(thread->logfile); thread->logfile = NULL; } + free_socket_set(sockets); return NULL; } @@ -5991,8 +6521,185 @@ setalarm(int seconds) } } +#endif /* WIN32 */ + + +/* + * These functions provide an abstraction layer that hides the syscall + * we use to wait for input on a set of sockets. + * + * Currently there are two implementations, based on ppoll(2) and select(2). + * ppoll() is preferred where available due to its typically higher ceiling + * on the number of usable sockets. We do not use the more-widely-available + * poll(2) because it only offers millisecond timeout resolution, which could + * be problematic with high --rate settings. + * + * Function APIs: + * + * alloc_socket_set: allocate an empty socket set with room for up to + * "count" sockets. + * + * free_socket_set: deallocate a socket set. + * + * clear_socket_set: reset a socket set to empty. + * + * add_socket_to_set: add socket with indicated FD to slot "idx" in the + * socket set. Slots must be filled in order, starting with 0. + * + * wait_on_socket_set: wait for input on any socket in set, or for timeout + * to expire. timeout is measured in microseconds; 0 means wait forever. + * Returns result code of underlying syscall (>=0 if OK, else see errno). + * + * socket_has_input: after waiting, call this to see if given socket has + * input. fd and idx parameters should match some previous call to + * add_socket_to_set. + * + * Note that wait_on_socket_set destructively modifies the state of the + * socket set. After checking for input, caller must apply clear_socket_set + * and add_socket_to_set again before waiting again. + */ + +#ifdef POLL_USING_PPOLL + +static socket_set * +alloc_socket_set(int count) +{ + socket_set *sa; + + sa = (socket_set *) pg_malloc0(offsetof(socket_set, pollfds) + + sizeof(struct pollfd) * count); + sa->maxfds = count; + sa->curfds = 0; + return sa; +} + +static void +free_socket_set(socket_set *sa) +{ + pg_free(sa); +} + +static void +clear_socket_set(socket_set *sa) +{ + sa->curfds = 0; +} + +static void +add_socket_to_set(socket_set *sa, int fd, int idx) +{ + Assert(idx < sa->maxfds && idx == sa->curfds); + sa->pollfds[idx].fd = fd; + sa->pollfds[idx].events = POLLIN; + sa->pollfds[idx].revents = 0; + sa->curfds++; +} + +static int +wait_on_socket_set(socket_set *sa, int64 usecs) +{ + if (usecs > 0) + { + struct timespec timeout; + + timeout.tv_sec = usecs / 1000000; + timeout.tv_nsec = (usecs % 1000000) * 1000; + return ppoll(sa->pollfds, sa->curfds, &timeout, NULL); + } + else + { + return ppoll(sa->pollfds, sa->curfds, NULL, NULL); + } +} + +static bool +socket_has_input(socket_set *sa, int fd, int idx) +{ + /* + * In some cases, threadRun will apply clear_socket_set and then try to + * apply socket_has_input anyway with arguments that it used before that, + * or might've used before that except that it exited its setup loop + * early. Hence, if the socket set is empty, silently return false + * regardless of the parameters. If it's not empty, we can Assert that + * the parameters match a previous call. + */ + if (sa->curfds == 0) + return false; + + Assert(idx < sa->curfds && sa->pollfds[idx].fd == fd); + return (sa->pollfds[idx].revents & POLLIN) != 0; +} + +#endif /* POLL_USING_PPOLL */ + +#ifdef POLL_USING_SELECT + +static socket_set * +alloc_socket_set(int count) +{ + return (socket_set *) pg_malloc0(sizeof(socket_set)); +} + +static void +free_socket_set(socket_set *sa) +{ + pg_free(sa); +} + +static void +clear_socket_set(socket_set *sa) +{ + FD_ZERO(&sa->fds); + sa->maxfd = -1; +} + +static void +add_socket_to_set(socket_set *sa, int fd, int idx) +{ + if (fd < 0 || fd >= FD_SETSIZE) + { + /* + * Doing a hard exit here is a bit grotty, but it doesn't seem worth + * complicating the API to make it less grotty. + */ + fprintf(stderr, "too many client connections for select()\n"); + exit(1); + } + FD_SET(fd, &sa->fds); + if (fd > sa->maxfd) + sa->maxfd = fd; +} + +static int +wait_on_socket_set(socket_set *sa, int64 usecs) +{ + if (usecs > 0) + { + struct timeval timeout; + + timeout.tv_sec = usecs / 1000000; + timeout.tv_usec = usecs % 1000000; + return select(sa->maxfd + 1, &sa->fds, NULL, NULL, &timeout); + } + else + { + return select(sa->maxfd + 1, &sa->fds, NULL, NULL, NULL); + } +} + +static bool +socket_has_input(socket_set *sa, int fd, int idx) +{ + return (FD_ISSET(fd, &sa->fds) != 0); +} + +#endif /* POLL_USING_SELECT */ + + /* partial pthread implementation for Windows */ +#ifdef WIN32 + typedef struct win32_pthread { HANDLE handle; diff --git a/src/bin/pgbench/pgbench.h b/src/bin/pgbench/pgbench.h index 6983865b925..c4a1e298e06 100644 --- a/src/bin/pgbench/pgbench.h +++ b/src/bin/pgbench/pgbench.h @@ -2,7 +2,7 @@ * * pgbench.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -143,23 +143,24 @@ extern int expr_yyparse(yyscan_t yyscanner); extern int expr_yylex(union YYSTYPE *lvalp, yyscan_t yyscanner); extern void expr_yyerror(yyscan_t yyscanner, const char *str) pg_attribute_noreturn(); extern void expr_yyerror_more(yyscan_t yyscanner, const char *str, - const char *more) pg_attribute_noreturn(); + const char *more) pg_attribute_noreturn(); extern bool expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf, - int *offset); + int *offset); extern yyscan_t expr_scanner_init(PsqlScanState state, - const char *source, int lineno, int start_offset, - const char *command); + const char *source, int lineno, int start_offset, + const char *command); extern void expr_scanner_finish(yyscan_t yyscanner); extern int expr_scanner_offset(PsqlScanState state); extern char *expr_scanner_get_substring(PsqlScanState state, - int start_offset, int end_offset, - bool chomp); + int start_offset, int end_offset, + bool chomp); extern int expr_scanner_get_lineno(PsqlScanState state, int offset); extern void syntax_error(const char *source, int lineno, const char *line, - const char *cmd, const char *msg, - const char *more, int col) pg_attribute_noreturn(); + const char *cmd, const char *msg, + const char *more, int col) pg_attribute_noreturn(); -extern int64 strtoint64(const char *str); +extern bool strtoint64(const char *str, bool errorOK, int64 *pi); +extern bool strtodouble(const char *str, bool errorOK, double *pd); #endif /* PGBENCH_H */ diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl index be08b206113..c441626d7cd 100644 --- a/src/bin/pgbench/t/001_pgbench_with_server.pl +++ b/src/bin/pgbench/t/001_pgbench_with_server.pl @@ -10,10 +10,19 @@ $node->init; $node->start; -# invoke pgbench +# invoke pgbench, with parameters: +# $opts: options as a string to be split on spaces +# $stat: expected exit status +# $out: reference to a regexp list that must match stdout +# $err: reference to a regexp list that must match stderr +# $name: name of test for error messages +# $files: reference to filename/contents dictionary +# @args: further raw options or arguments sub pgbench { - my ($opts, $stat, $out, $err, $name, $files) = @_; + local $Test::Builder::Level = $Test::Builder::Level + 1; + + my ($opts, $stat, $out, $err, $name, $files, @args) = @_; my @cmd = ('pgbench', split /\s+/, $opts); my @filenames = (); if (defined $files) @@ -38,40 +47,53 @@ sub pgbench append_to_file($filename, $$files{$fn}); } } + + push @cmd, @args; + $node->command_checks_all(\@cmd, $stat, $out, $err, $name); # cleanup? #unlink @filenames or die "cannot unlink files (@filenames): $!"; + + return; } -# Test concurrent insertion into table with UNIQUE oid column. DDL expects -# GetNewOidWithIndex() to successfully avoid violating uniqueness for indexes -# like pg_class_oid_index and pg_proc_oid_index. This indirectly exercises -# LWLock and spinlock concurrency. This test makes a 5-MiB table. +# tablespace for testing, because partitioned tables cannot use pg_default +# explicitly and we want to test that table creation with tablespace works +# for partitioned tables. +my $ts = $node->basedir . '/regress_pgbench_tap_1_ts_dir'; +mkdir $ts or die "cannot create directory $ts"; +# this takes care of WIN-specific path issues +my $ets = TestLib::perl2host($ts); +# the next commands will issue a syntax error if the path contains a "'" $node->safe_psql('postgres', - 'CREATE UNLOGGED TABLE oid_tbl () WITH OIDS; ' - . 'ALTER TABLE oid_tbl ADD UNIQUE (oid);'); + "CREATE TABLESPACE regress_pgbench_tap_1_ts LOCATION '$ets';" +); +# Test concurrent OID generation via pg_enum_oid_index. This indirectly +# exercises LWLock and spinlock concurrency. +my $labels = join ',', map { "'l$_'" } 1 .. 1000; pgbench( '--no-vacuum --client=5 --protocol=prepared --transactions=25', 0, [qr{processed: 125/125}], [qr{^$}], - 'concurrency OID generation', - { '001_pgbench_concurrent_oid_generation' => - 'INSERT INTO oid_tbl SELECT FROM generate_series(1,1000);' }); - -# cleanup -$node->safe_psql('postgres', 'DROP TABLE oid_tbl;'); + 'concurrent OID generation', + { + '001_pgbench_concurrent_insert' => + "CREATE TYPE pg_temp.e AS ENUM ($labels); DROP TYPE pg_temp.e;" + }); # Trigger various connection errors pgbench( 'no-such-database', 1, [qr{^$}], - [ qr{connection to database "no-such-database" failed}, - qr{FATAL: database "no-such-database" does not exist} ], + [ + qr{connection to database "no-such-database" failed}, + qr{FATAL: database "no-such-database" does not exist} + ], 'no such database'); pgbench( @@ -81,33 +103,46 @@ sub pgbench # Initialize pgbench tables scale 1 pgbench( - '-i', 0, [qr{^$}], - [ qr{creating tables}, qr{vacuuming}, qr{creating primary keys}, qr{done\.} ], + '-i', 0, + [qr{^$}], + [ + qr{creating tables}, qr{vacuuming}, + qr{creating primary keys}, qr{done in \d+\.\d\d s } + ], 'pgbench scale 1 initialization',); # Again, with all possible options pgbench( -'--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=pg_default --index-tablespace=pg_default', + '--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=regress_pgbench_tap_1_ts --index-tablespace=regress_pgbench_tap_1_ts --partitions=2 --partition-method=hash', 0, [qr{^$}i], - [ qr{dropping old tables}, + [ + qr{dropping old tables}, qr{creating tables}, + qr{creating 2 partitions}, qr{vacuuming}, qr{creating primary keys}, qr{creating foreign keys}, - qr{done\.} ], + qr{(?!vacuuming)}, # no vacuum + qr{done in \d+\.\d\d s } + ], 'pgbench scale 1 initialization'); # Test interaction of --init-steps with legacy step-selection options pgbench( - '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables', - 0, [qr{^$}], - [ qr{dropping old tables}, + '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables --partitions=3', + 0, + [qr{^$}], + [ + qr{dropping old tables}, qr{creating tables}, + qr{creating 3 partitions}, qr{creating primary keys}, qr{.* of .* tuples \(.*\) done}, qr{creating foreign keys}, - qr{done\.} ], + qr{(?!vacuuming)}, # no vacuum + qr{done in \d+\.\d\d s } + ], 'pgbench --init-steps'); # Run all builtin scripts, for a few transactions each @@ -115,34 +150,42 @@ sub pgbench '--transactions=5 -Dfoo=bla --client=2 --protocol=simple --builtin=t' . ' --connect -n -v -n', 0, - [ qr{builtin: TPC-B}, + [ + qr{builtin: TPC-B}, qr{clients: 2\b}, qr{processed: 10/10}, - qr{mode: simple} ], + qr{mode: simple} + ], [qr{^$}], 'pgbench tpcb-like'); pgbench( -'--transactions=20 --client=5 -M extended --builtin=si -C --no-vacuum -s 1', + '--transactions=20 --client=5 -M extended --builtin=si -C --no-vacuum -s 1', 0, - [ qr{builtin: simple update}, + [ + qr{builtin: simple update}, qr{clients: 5\b}, qr{threads: 1\b}, qr{processed: 100/100}, - qr{mode: extended} ], + qr{mode: extended} + ], [qr{scale option ignored}], 'pgbench simple update'); pgbench( '-t 100 -c 7 -M prepared -b se --debug', 0, - [ qr{builtin: select only}, + [ + qr{builtin: select only}, qr{clients: 7\b}, qr{threads: 1\b}, qr{processed: 700/700}, - qr{mode: prepared} ], - [ qr{vacuum}, qr{client 0}, qr{client 1}, qr{sending}, - qr{receiving}, qr{executing} ], + qr{mode: prepared} + ], + [ + qr{vacuum}, qr{client 0}, qr{client 1}, qr{sending}, + qr{receiving}, qr{executing} + ], 'pgbench select only'); # check if threads are supported @@ -158,16 +201,19 @@ sub pgbench pgbench( "-t 100 -c 1 -j $nthreads -M prepared -n", 0, - [ qr{type: multiple scripts}, + [ + qr{type: multiple scripts}, qr{mode: prepared}, qr{script 1: .*/001_pgbench_custom_script_1}, qr{weight: 2}, qr{script 2: .*/001_pgbench_custom_script_2}, qr{weight: 1}, - qr{processed: 100/100} ], + qr{processed: 100/100} + ], [qr{^$}], 'pgbench custom scripts', - { '001_pgbench_custom_script_1@1' => q{-- select only + { + '001_pgbench_custom_script_1@1' => q{-- select only \set aid random(1, :scale * 100000) SELECT abalance::INTEGER AS balance FROM pgbench_accounts @@ -179,54 +225,65 @@ sub pgbench -- cast are needed for typing under -M prepared SELECT :foo::INT + :scale::INT * :client_id::INT AS bla; COMMIT; -} }); +} + }); pgbench( '-n -t 10 -c 1 -M simple', 0, - [ qr{type: .*/001_pgbench_custom_script_3}, + [ + qr{type: .*/001_pgbench_custom_script_3}, qr{processed: 10/10}, - qr{mode: simple} ], + qr{mode: simple} + ], [qr{^$}], 'pgbench custom script', - { '001_pgbench_custom_script_3' => q{-- select only variant + { + '001_pgbench_custom_script_3' => q{-- select only variant \set aid random(1, :scale * 100000) BEGIN; SELECT abalance::INTEGER AS balance FROM pgbench_accounts WHERE aid=:aid; COMMIT; -} }); +} + }); pgbench( '-n -t 10 -c 2 -M extended', 0, - [ qr{type: .*/001_pgbench_custom_script_4}, + [ + qr{type: .*/001_pgbench_custom_script_4}, qr{processed: 20/20}, - qr{mode: extended} ], + qr{mode: extended} + ], [qr{^$}], 'pgbench custom script', - { '001_pgbench_custom_script_4' => q{-- select only variant + { + '001_pgbench_custom_script_4' => q{-- select only variant \set aid random(1, :scale * 100000) BEGIN; SELECT abalance::INTEGER AS balance FROM pgbench_accounts WHERE aid=:aid; COMMIT; -} }); +} + }); # test expressions # command 1..3 and 23 depend on random seed which is used to call srandom. pgbench( - '--random-seed=5432 -t 1 -Dfoo=-10.1 -Dbla=false -Di=+3 -Dminint=-9223372036854775808 -Dn=null -Dt=t -Df=of -Dd=1.0', + '--random-seed=5432 -t 1 -Dfoo=-10.1 -Dbla=false -Di=+3 -Dn=null -Dt=t -Df=of -Dd=1.0', 0, [ qr{type: .*/001_pgbench_expressions}, qr{processed: 1/1} ], - [ qr{setting random seed to 5432\b}, - # After explicit seeding, the four * random checks (1-3,20) should be - # deterministic, but not necessarily portable. - qr{command=1.: int 1\d\b}, # uniform random: 12 on linux - qr{command=2.: int 1\d\d\b}, # exponential random: 106 on linux - qr{command=3.: int 1\d\d\d\b}, # gaussian random: 1462 on linux + [ + qr{setting random seed to 5432\b}, + + # After explicit seeding, the four random checks (1-3,20) are + # deterministic + qr{command=1.: int 13\b}, # uniform random + qr{command=2.: int 116\b}, # exponential random + qr{command=3.: int 1498\b}, # gaussian random qr{command=4.: int 4\b}, qr{command=5.: int 5\b}, qr{command=6.: int 6\b}, @@ -239,8 +296,7 @@ sub pgbench qr{command=15.: double 15\b}, qr{command=16.: double 16\b}, qr{command=17.: double 17\b}, - qr{command=18.: int 9223372036854775807\b}, - qr{command=20.: int \d\b}, # zipfian random: 1 on linux + qr{command=20.: int 1\b}, # zipfian random qr{command=21.: double -27\b}, qr{command=22.: double 1024\b}, qr{command=23.: double 1\b}, @@ -280,12 +336,15 @@ sub pgbench qr{command=86.: int 86\b}, qr{command=93.: int 93\b}, qr{command=95.: int 0\b}, - qr{command=96.: int 1\b}, # :scale - qr{command=97.: int 0\b}, # :client_id - qr{command=98.: int 5432\b}, # :random_seed + qr{command=96.: int 1\b}, # :scale + qr{command=97.: int 0\b}, # :client_id + qr{command=98.: int 5432\b}, # :random_seed + qr{command=99.: int -9223372036854775808\b}, # min int + qr{command=100.: int 9223372036854775807\b}, # max int ], 'pgbench expressions', - { '001_pgbench_expressions' => q{-- integer functions + { + '001_pgbench_expressions' => q{-- integer functions \set i1 debug(random(10, 19)) \set i2 debug(random_exponential(100, 199, 10.0)) \set i3 debug(random_gaussian(1000, 1999, 10.0)) @@ -305,10 +364,9 @@ sub pgbench \set pi debug(pi() * 4.9) \set d4 debug(greatest(4, 2, -1.17) * 4.0 * Ln(Exp(1.0))) \set d5 debug(least(-5.18, .0E0, 1.0/0) * -3.3) --- forced overflow -\set maxint debug(:minint - 1) --- reset a variable +-- reset variables \set i1 0 +\set d1 false -- yet another integer function \set id debug(random_zipfian(1, 9, 1.3)) --- pow and power @@ -407,57 +465,72 @@ sub pgbench \set sc debug(:scale) \set ci debug(:client_id) \set rs debug(:random_seed) -} }); +-- minint constant parsing +\set min debug(-9223372036854775808) +\set max debug(-(:min + 1)) +} + }); # random determinism when seeded $node->safe_psql('postgres', - 'CREATE UNLOGGED TABLE seeded_random(seed INT8 NOT NULL, rand TEXT NOT NULL, val INTEGER NOT NULL);'); + 'CREATE UNLOGGED TABLE seeded_random(seed INT8 NOT NULL, rand TEXT NOT NULL, val INTEGER NOT NULL);' +); # same value to check for determinism my $seed = int(rand(1000000000)); for my $i (1, 2) { - pgbench("--random-seed=$seed -t 1", - 0, - [qr{processed: 1/1}], - [qr{setting random seed to $seed\b}], - "random seeded with $seed", - { "001_pgbench_random_seed_$i" => q{-- test random functions + pgbench( + "--random-seed=$seed -t 1", + 0, + [qr{processed: 1/1}], + [qr{setting random seed to $seed\b}], + "random seeded with $seed", + { + "001_pgbench_random_seed_$i" => q{-- test random functions \set ur random(1000, 1999) \set er random_exponential(2000, 2999, 2.0) \set gr random_gaussian(3000, 3999, 3.0) -\set zr random_zipfian(4000, 4999, 2.5) +\set zr random_zipfian(4000, 4999, 1.5) INSERT INTO seeded_random(seed, rand, val) VALUES (:random_seed, 'uniform', :ur), (:random_seed, 'exponential', :er), (:random_seed, 'gaussian', :gr), (:random_seed, 'zipfian', :zr); -} }); +} + }); } # check that all runs generated the same 4 values -my ($ret, $out, $err) = - $node->psql('postgres', - 'SELECT seed, rand, val, COUNT(*) FROM seeded_random GROUP BY seed, rand, val'); +my ($ret, $out, $err) = $node->psql('postgres', + 'SELECT seed, rand, val, COUNT(*) FROM seeded_random GROUP BY seed, rand, val' +); -ok($ret == 0, "psql seeded_random count ok"); +ok($ret == 0, "psql seeded_random count ok"); ok($err eq '', "psql seeded_random count stderr is empty"); -ok($out =~ /\b$seed\|uniform\|1\d\d\d\|2/, "psql seeded_random count uniform"); -ok($out =~ /\b$seed\|exponential\|2\d\d\d\|2/, "psql seeded_random count exponential"); -ok($out =~ /\b$seed\|gaussian\|3\d\d\d\|2/, "psql seeded_random count gaussian"); -ok($out =~ /\b$seed\|zipfian\|4\d\d\d\|2/, "psql seeded_random count zipfian"); +ok($out =~ /\b$seed\|uniform\|1\d\d\d\|2/, + "psql seeded_random count uniform"); +ok( $out =~ /\b$seed\|exponential\|2\d\d\d\|2/, + "psql seeded_random count exponential"); +ok( $out =~ /\b$seed\|gaussian\|3\d\d\d\|2/, + "psql seeded_random count gaussian"); +ok($out =~ /\b$seed\|zipfian\|4\d\d\d\|2/, + "psql seeded_random count zipfian"); $node->safe_psql('postgres', 'DROP TABLE seeded_random;'); # backslash commands pgbench( '-t 1', 0, - [ qr{type: .*/001_pgbench_backslash_commands}, + [ + qr{type: .*/001_pgbench_backslash_commands}, qr{processed: 1/1}, - qr{shell-echo-output} ], - [qr{command=8.: int 2\b}], + qr{shell-echo-output} + ], + [qr{command=8.: int 1\b}], 'pgbench backslash commands', - { '001_pgbench_backslash_commands' => q{-- run set + { + '001_pgbench_backslash_commands' => q{-- run set \set zero 0 \set one 1.0 -- sleep @@ -466,208 +539,306 @@ sub pgbench \sleep 0 s \sleep :zero -- setshell and continuation -\setshell two\ - expr \ - 1 + :one -\set n debug(:two) +\setshell another_one\ + echo \ + :one +\set n debug(:another_one) -- shell \shell echo shell-echo-output -} }); +} + }); + +# working \gset +pgbench( + '-t 1', 0, + [ qr{type: .*/001_pgbench_gset}, qr{processed: 1/1} ], + [ + qr{command=3.: int 0\b}, + qr{command=5.: int 1\b}, + qr{command=6.: int 2\b}, + qr{command=8.: int 3\b}, + qr{command=10.: int 4\b}, + qr{command=12.: int 5\b} + ], + 'pgbench gset command', + { + '001_pgbench_gset' => q{-- test gset +-- no columns +SELECT \gset +-- one value +SELECT 0 AS i0 \gset +\set i debug(:i0) +-- two values +SELECT 1 AS i1, 2 AS i2 \gset +\set i debug(:i1) +\set i debug(:i2) +-- with prefix +SELECT 3 AS i3 \gset x_ +\set i debug(:x_i3) +-- overwrite existing variable +SELECT 0 AS i4, 4 AS i4 \gset +\set i debug(:i4) +-- work on the last SQL command under \; +\; \; SELECT 0 AS i5 \; SELECT 5 AS i5 \; \; \gset +\set i debug(:i5) +} + }); # trigger many expression errors my @errors = ( - # [ test name, script number, status, stderr match ] + # [ test name, expected status, expected stderr, script ] # SQL - [ 'sql syntax error', - 0, - [ qr{ERROR: syntax error}, qr{prepared statement .* does not exist} + [ + 'sql syntax error', + 2, + [ + qr{ERROR: syntax error}, + qr{prepared statement .* does not exist} ], q{-- SQL syntax error SELECT 1 + ; -} ], - [ 'sql too many args', 1, [qr{statement has too many arguments.*\b9\b}], - q{-- MAX_ARGS=10 for prepared +} + ], + [ + 'sql too many args', 1, + [qr{statement has too many arguments.*\b255\b}], + q{-- MAX_ARGS=256 for prepared \set i 0 -SELECT LEAST(:i, :i, :i, :i, :i, :i, :i, :i, :i, :i, :i); -} ], +SELECT LEAST(} . join(', ', (':i') x 256) . q{)} + ], # SHELL - [ 'shell bad command', 0, - [qr{\(shell\) .* meta-command failed}], q{\shell no-such-command} ], - [ 'shell undefined variable', 0, + [ + 'shell bad command', 2, + [qr{\(shell\) .* meta-command failed}], q{\shell no-such-command} + ], + [ + 'shell undefined variable', 2, [qr{undefined variable ":nosuchvariable"}], q{-- undefined variable in shell \shell echo ::foo :nosuchvariable -} ], +} + ], [ 'shell missing command', 1, [qr{missing command }], q{\shell} ], - [ 'shell too many args', 1, [qr{too many arguments in command "shell"}], - q{-- 257 arguments to \shell -\shell echo \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F \ - 0 1 2 3 4 5 6 7 8 9 A B C D E F -} ], + [ + 'shell too many args', 1, [qr{too many arguments in command "shell"}], + q{-- 256 arguments to \shell +\shell echo } . join(' ', ('arg') x 255) + ], # SET - [ 'set syntax error', 1, - [qr{syntax error in command "set"}], q{\set i 1 +} ], - [ 'set no such function', 1, - [qr{unexpected function name}], q{\set i noSuchFunction()} ], - [ 'set invalid variable name', 0, - [qr{invalid variable name}], q{\set . 1} ], - [ 'set int overflow', 0, - [qr{double to int overflow for 100}], q{\set i int(1E32)} ], - [ 'set division by zero', 0, [qr{division by zero}], q{\set i 1/0} ], - [ 'set bigint out of range', 0, - [qr{bigint out of range}], q{\set i 9223372036854775808 / -1} ], - [ 'set undefined variable', - 0, + [ + 'set syntax error', 1, + [qr{syntax error in command "set"}], q{\set i 1 +} + ], + [ + 'set no such function', 1, + [qr{unexpected function name}], q{\set i noSuchFunction()} + ], + [ + 'set invalid variable name', 2, + [qr{invalid variable name}], q{\set . 1} + ], + [ 'set division by zero', 2, [qr{division by zero}], q{\set i 1/0} ], + [ + 'set undefined variable', + 2, [qr{undefined variable "nosuchvariable"}], - q{\set i :nosuchvariable} ], + q{\set i :nosuchvariable} + ], [ 'set unexpected char', 1, [qr{unexpected character .;.}], q{\set i ;} ], - [ 'set too many args', - 0, + [ + 'set too many args', + 2, [qr{too many function arguments}], - q{\set i least(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)} ], - [ 'set empty random range', 0, - [qr{empty range given to random}], q{\set i random(5,3)} ], - [ 'set random range too large', - 0, - [qr{random range is too large}], - q{\set i random(-9223372036854775808, 9223372036854775807)} ], - [ 'set gaussian param too small', - 0, + q{\set i least(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)} + ], + [ + 'set empty random range', 2, + [qr{empty range given to random}], q{\set i random(5,3)} + ], + [ + 'set random range too large', 2, + [qr{random range is too large}], q{\set i random(:minint, :maxint)} + ], + [ + 'set gaussian param too small', + 2, [qr{gaussian param.* at least 2}], - q{\set i random_gaussian(0, 10, 1.0)} ], - [ 'set exponential param greater 0', - 0, + q{\set i random_gaussian(0, 10, 1.0)} + ], + [ + 'set exponential param greater 0', + 2, [qr{exponential parameter must be greater }], - q{\set i random_exponential(0, 10, 0.0)} ], - [ 'set zipfian param to 1', - 0, - [qr{zipfian parameter must be in range \(0, 1\) U \(1, \d+\]}], - q{\set i random_zipfian(0, 10, 1)} ], - [ 'set zipfian param too large', - 0, - [qr{zipfian parameter must be in range \(0, 1\) U \(1, \d+\]}], - q{\set i random_zipfian(0, 10, 1000000)} ], - [ 'set non numeric value', 0, - [qr{malformed variable "foo" value: "bla"}], q{\set i :foo + 1} ], - [ 'set no expression', - 1, - [qr{syntax error}], - q{\set i} ], - [ 'set missing argument', - 1, - [qr{missing argument}i], - q{\set} ], - [ 'set not a bool', - 0, - [ qr{cannot coerce double to boolean} ], - q{\set b NOT 0.0} ], - [ 'set not an int', - 0, - [ qr{cannot coerce boolean to int} ], - q{\set i TRUE + 2} ], - [ 'set not a double', - 0, - [ qr{cannot coerce boolean to double} ], - q{\set d ln(TRUE)} ], - [ 'set case error', - 1, - [ qr{syntax error in command "set"} ], - q{\set i CASE TRUE THEN 1 ELSE 0 END} ], - [ 'set random error', - 0, - [ qr{cannot coerce boolean to int} ], - q{\set b random(FALSE, TRUE)} ], - [ 'set number of args mismatch', - 1, - [ qr{unexpected number of arguments} ], - q{\set d ln(1.0, 2.0))} ], - [ 'set at least one arg', + q{\set i random_exponential(0, 10, 0.0)} + ], + [ + 'set zipfian param to 1', + 2, + [qr{zipfian parameter must be in range \[1\.001, 1000\]}], + q{\set i random_zipfian(0, 10, 1)} + ], + [ + 'set zipfian param too large', + 2, + [qr{zipfian parameter must be in range \[1\.001, 1000\]}], + q{\set i random_zipfian(0, 10, 1000000)} + ], + [ + 'set non numeric value', 2, + [qr{malformed variable "foo" value: "bla"}], q{\set i :foo + 1} + ], + [ 'set no expression', 1, [qr{syntax error}], q{\set i} ], + [ 'set missing argument', 1, [qr{missing argument}i], q{\set} ], + [ + 'set not a bool', 2, + [qr{cannot coerce double to boolean}], q{\set b NOT 0.0} + ], + [ + 'set not an int', 2, + [qr{cannot coerce boolean to int}], q{\set i TRUE + 2} + ], + [ + 'set not a double', 2, + [qr{cannot coerce boolean to double}], q{\set d ln(TRUE)} + ], + [ + 'set case error', 1, - [ qr{at least one argument expected} ], - q{\set i greatest())} ], + [qr{syntax error in command "set"}], + q{\set i CASE TRUE THEN 1 ELSE 0 END} + ], + [ + 'set random error', 2, + [qr{cannot coerce boolean to int}], q{\set b random(FALSE, TRUE)} + ], + [ + 'set number of args mismatch', 1, + [qr{unexpected number of arguments}], q{\set d ln(1.0, 2.0))} + ], + [ + 'set at least one arg', 1, + [qr{at least one argument expected}], q{\set i greatest())} + ], + + # SET: ARITHMETIC OVERFLOW DETECTION + [ + 'set double to int overflow', 2, + [qr{double to int overflow for 100}], q{\set i int(1E32)} + ], + [ + 'set bigint add overflow', 2, + [qr{int add out}], q{\set i (1<<62) + (1<<62)} + ], + [ + 'set bigint sub overflow', + 2, [qr{int sub out}], q{\set i 0 - (1<<62) - (1<<62) - (1<<62)} + ], + [ + 'set bigint mul overflow', 2, + [qr{int mul out}], q{\set i 2 * (1<<62)} + ], + [ + 'set bigint div out of range', 2, + [qr{bigint div out of range}], q{\set i :minint / -1} + ], # SETSHELL - [ 'setshell not an int', 0, - [qr{command must return an integer}], q{\setshell i echo -n one} ], + [ + 'setshell not an int', 2, + [qr{command must return an integer}], q{\setshell i echo -n one} + ], [ 'setshell missing arg', 1, [qr{missing argument }], q{\setshell var} ], - [ 'setshell no such command', 0, - [qr{could not read result }], q{\setshell var no-such-command} ], + [ + 'setshell no such command', 2, + [qr{could not read result }], q{\setshell var no-such-command} + ], # SLEEP - [ 'sleep undefined variable', 0, - [qr{sleep: undefined variable}], q{\sleep :nosuchvariable} ], - [ 'sleep too many args', 1, - [qr{too many arguments}], q{\sleep too many args} ], - [ 'sleep missing arg', 1, - [ qr{missing argument}, qr{\\sleep} ], q{\sleep} ], - [ 'sleep unknown unit', 1, - [qr{unrecognized time unit}], q{\sleep 1 week} ], + [ + 'sleep undefined variable', 2, + [qr{sleep: undefined variable}], q{\sleep :nosuchvariable} + ], + [ + 'sleep too many args', 1, + [qr{too many arguments}], q{\sleep too many args} + ], + [ + 'sleep missing arg', 1, + [ qr{missing argument}, qr{\\sleep} ], q{\sleep} + ], + [ + 'sleep unknown unit', 1, + [qr{unrecognized time unit}], q{\sleep 1 week} + ], # MISC - [ 'misc invalid backslash command', 1, - [qr{invalid command .* "nosuchcommand"}], q{\nosuchcommand} ], + [ + 'misc invalid backslash command', 1, + [qr{invalid command .* "nosuchcommand"}], q{\nosuchcommand} + ], [ 'misc empty script', 1, [qr{empty command list for script}], q{} ], - [ 'bad boolean', 0, [qr{malformed variable.*trueXXX}], q{\set b :badtrue or true} ], - ); + [ + 'bad boolean', 2, + [qr{malformed variable.*trueXXX}], q{\set b :badtrue or true} + ], + # GSET + [ + 'gset no row', 2, + [qr{expected one row, got 0\b}], q{SELECT WHERE FALSE \gset} + ], + [ 'gset alone', 1, [qr{gset must follow a SQL command}], q{\gset} ], + [ + 'gset no SQL', 1, + [qr{gset must follow a SQL command}], q{\set i +1 +\gset} + ], + [ + 'gset too many arguments', 1, + [qr{too many arguments}], q{SELECT 1 \gset a b} + ], + [ + 'gset after gset', 1, + [qr{gset must follow a SQL command}], q{SELECT 1 AS i \gset +\gset} + ], + [ + 'gset non SELECT', + 2, + [qr{expected one row, got 0}], + q{DROP TABLE IF EXISTS no_such_table \gset} + ], + [ + 'gset bad default name', 2, + [qr{error storing into variable \?column\?}], q{SELECT 1 \gset} + ], + [ + 'gset bad name', + 2, + [qr{error storing into variable bad name!}], + q{SELECT 1 AS "bad name!" \gset} + ],); for my $e (@errors) { - my ($name, $status, $re, $script) = @$e; + my ($name, $status, $re, $script, $no_prepare) = @$e; + $status != 0 or die "invalid expected status for test \"$name\""; my $n = '001_pgbench_error_' . $name; $n =~ s/ /_/g; pgbench( - '-n -t 1 -Dfoo=bla -Dnull=null -Dtrue=true -Done=1 -Dzero=0.0 -Dbadtrue=trueXXX -M prepared', + '-n -t 1 -Dfoo=bla -Dnull=null -Dtrue=true -Done=1 -Dzero=0.0 -Dbadtrue=trueXXX' + . ' -Dmaxint=9223372036854775807 -Dminint=-9223372036854775808' + . ($no_prepare ? '' : ' -M prepared'), $status, - [ $status ? qr{^$} : qr{processed: 0/1} ], + [ $status == 1 ? qr{^$} : qr{processed: 0/1} ], $re, 'pgbench script error: ' . $name, { $n => $script }); } -# zipfian cache array overflow -pgbench( - '-t 1', 0, - [ qr{processed: 1/1}, qr{zipfian cache array overflowed 1 time\(s\)} ], - [ qr{^} ], - 'pgbench zipfian array overflow on random_zipfian', - { '001_pgbench_random_zipfian' => q{ -\set i random_zipfian(1, 100, 0.5) -\set i random_zipfian(2, 100, 0.5) -\set i random_zipfian(3, 100, 0.5) -\set i random_zipfian(4, 100, 0.5) -\set i random_zipfian(5, 100, 0.5) -\set i random_zipfian(6, 100, 0.5) -\set i random_zipfian(7, 100, 0.5) -\set i random_zipfian(8, 100, 0.5) -\set i random_zipfian(9, 100, 0.5) -\set i random_zipfian(10, 100, 0.5) -\set i random_zipfian(11, 100, 0.5) -\set i random_zipfian(12, 100, 0.5) -\set i random_zipfian(13, 100, 0.5) -\set i random_zipfian(14, 100, 0.5) -\set i random_zipfian(15, 100, 0.5) -\set i random_zipfian(16, 100, 0.5) -} }); - # throttling pgbench( '-t 100 -S --rate=100000 --latency-limit=1000000 -c 2 -n -r', @@ -678,24 +849,40 @@ sub pgbench pgbench( - # given the expected rate and the 2 ms tx duration, at most one is executed + # given the expected rate and the 2 ms tx duration, at most one is executed '-t 10 --rate=100000 --latency-limit=1 -n -r', 0, - [ qr{processed: [01]/10}, + [ + qr{processed: [01]/10}, qr{type: .*/001_pgbench_sleep}, - qr{above the 1.0 ms latency limit: [01]/} ], - [qr{^$}i], + qr{above the 1.0 ms latency limit: [01]/} + ], + [qr{^$}], 'pgbench late throttling', { '001_pgbench_sleep' => q{\sleep 2ms} }); +# return a list of files from directory $dir matching regexpr $re +# this works around glob portability and escaping issues +sub list_files +{ + my ($dir, $re) = @_; + opendir my $dh, $dir or die "cannot opendir $dir: $!"; + my @files = grep /$re/, readdir $dh; + closedir $dh or die "cannot closedir $dir: $!"; + return map { $dir . '/' . $_ } @files; +} + # check log contents and cleanup sub check_pgbench_logs { - my ($prefix, $nb, $min, $max, $re) = @_; + local $Test::Builder::Level = $Test::Builder::Level + 1; - my @logs = glob "$prefix.*"; + my ($dir, $prefix, $nb, $min, $max, $re) = @_; + + # $prefix is simple enough, thus does not need escaping + my @logs = list_files($dir, qr{^$prefix\..*$}); ok(@logs == $nb, "number of log files"); - ok(grep(/^$prefix\.\d+(\.\d+)?$/, @logs) == $nb, "file name format"); + ok(grep(/\/$prefix\.\d+(\.\d+)?$/, @logs) == $nb, "file name format"); my $log_number = 0; for my $log (sort @logs) @@ -712,30 +899,32 @@ sub check_pgbench_logs }; } ok(unlink(@logs), "remove log files"); + return; } my $bdir = $node->basedir; # with sampling rate pgbench( -"-n -S -t 50 -c 2 --log --log-prefix=$bdir/001_pgbench_log_2 --sampling-rate=0.5", - 0, - [ qr{select only}, qr{processed: 100/100} ], - [qr{^$}], - 'pgbench logs'); + "-n -S -t 50 -c 2 --log --sampling-rate=0.5", 0, + [ qr{select only}, qr{processed: 100/100} ], [qr{^$}], + 'pgbench logs', undef, + "--log-prefix=$bdir/001_pgbench_log_2"); -check_pgbench_logs("$bdir/001_pgbench_log_2", 1, 8, 92, +check_pgbench_logs($bdir, '001_pgbench_log_2', 1, 8, 92, qr{^0 \d{1,2} \d+ \d \d+ \d+$}); # check log file in some detail pgbench( - "-n -b se -t 10 -l --log-prefix=$bdir/001_pgbench_log_3", - 0, [ qr{select only}, qr{processed: 10/10} ], - [qr{^$}], 'pgbench logs contents'); + "-n -b se -t 10 -l", 0, + [ qr{select only}, qr{processed: 10/10} ], [qr{^$}], + 'pgbench logs contents', undef, + "--log-prefix=$bdir/001_pgbench_log_3"); -check_pgbench_logs("$bdir/001_pgbench_log_3", 1, 10, 10, +check_pgbench_logs($bdir, '001_pgbench_log_3', 1, 10, 10, qr{^\d \d{1,2} \d+ \d \d+ \d+$}); # done +$node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts'); $node->stop; done_testing(); diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl index af21f046496..1e9542af3f2 100644 --- a/src/bin/pgbench/t/002_pgbench_no_server.pl +++ b/src/bin/pgbench/t/002_pgbench_no_server.pl @@ -15,21 +15,25 @@ my $testdir = "$TestLib::tmp_check/t_${testname}_stuff"; mkdir $testdir - or - BAIL_OUT("could not create test directory \"${testdir}\": $!"); + or BAIL_OUT("could not create test directory \"${testdir}\": $!"); # invoke pgbench sub pgbench { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($opts, $stat, $out, $err, $name) = @_; print STDERR "opts=$opts, stat=$stat, out=$out, err=$err, name=$name"; command_checks_all([ 'pgbench', split(/\s+/, $opts) ], $stat, $out, $err, $name); + return; } # invoke pgbench with scripts sub pgbench_scripts { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($opts, $stat, $out, $err, $name, $files) = @_; my @cmd = ('pgbench', split /\s+/, $opts); my @filenames = (); @@ -38,8 +42,10 @@ sub pgbench_scripts for my $fn (sort keys %$files) { my $filename = $testdir . '/' . $fn; + # cleanup file weight if any $filename =~ s/\@\d+$//; + # cleanup from prior runs unlink $filename; append_to_file($filename, $$files{$fn}); @@ -47,6 +53,7 @@ sub pgbench_scripts } } command_checks_all(\@cmd, $stat, $out, $err, $name); + return; } # @@ -56,79 +63,133 @@ sub pgbench_scripts my @options = ( # name, options, stderr checks - [ 'bad option', + [ + 'bad option', '-h home -p 5432 -U calvin -d --bad-option', - [ qr{(unrecognized|illegal) option}, qr{--help.*more information} ] ], - [ 'no file', + [qr{--help.*more information}] + ], + [ + 'no file', '-f no-such-file', - [qr{could not open file "no-such-file":}] ], - [ 'no builtin', + [qr{could not open file "no-such-file":}] + ], + [ + 'no builtin', '-b no-such-builtin', - [qr{no builtin script .* "no-such-builtin"}] ], - [ 'invalid weight', + [qr{no builtin script .* "no-such-builtin"}] + ], + [ + 'invalid weight', '--builtin=select-only@one', - [qr{invalid weight specification: \@one}] ], - [ 'invalid weight', + [qr{invalid weight specification: \@one}] + ], + [ + 'invalid weight', '-b select-only@-1', - [qr{weight spec.* out of range .*: -1}] ], + [qr{weight spec.* out of range .*: -1}] + ], [ 'too many scripts', '-S ' x 129, [qr{at most 128 SQL scripts}] ], [ 'bad #clients', '-c three', [qr{invalid number of clients: "three"}] ], - [ 'bad #threads', '-j eleven', [qr{invalid number of threads: "eleven"}] + [ + 'bad #threads', '-j eleven', [qr{invalid number of threads: "eleven"}] ], [ 'bad scale', '-i -s two', [qr{invalid scaling factor: "two"}] ], - [ 'invalid #transactions', + [ + 'invalid #transactions', '-t zil', - [qr{invalid number of transactions: "zil"}] ], + [qr{invalid number of transactions: "zil"}] + ], [ 'invalid duration', '-T ten', [qr{invalid duration: "ten"}] ], - [ '-t XOR -T', + [ + '-t XOR -T', '-N -l --aggregate-interval=5 --log-prefix=notused -t 1000 -T 1', - [qr{specify either }] ], - [ '-T XOR -t', + [qr{specify either }] + ], + [ + '-T XOR -t', '-P 1 --progress-timestamp -l --sampling-rate=0.001 -T 10 -t 1000', - [qr{specify either }] ], + [qr{specify either }] + ], [ 'bad variable', '--define foobla', [qr{invalid variable definition}] ], [ 'invalid fillfactor', '-F 1', [qr{invalid fillfactor}] ], [ 'invalid query mode', '-M no-such-mode', [qr{invalid query mode}] ], - [ 'invalid progress', '--progress=0', - [qr{invalid thread progress delay}] ], + [ + 'invalid progress', '--progress=0', + [qr{invalid thread progress delay}] + ], [ 'invalid rate', '--rate=0.0', [qr{invalid rate limit}] ], [ 'invalid latency', '--latency-limit=0.0', [qr{invalid latency limit}] ], - [ 'invalid sampling rate', '--sampling-rate=0', - [qr{invalid sampling rate}] ], - [ 'invalid aggregate interval', '--aggregate-interval=-3', - [qr{invalid .* seconds for}] ], - [ 'weight zero', + [ + 'invalid sampling rate', '--sampling-rate=0', + [qr{invalid sampling rate}] + ], + [ + 'invalid aggregate interval', '--aggregate-interval=-3', + [qr{invalid .* seconds for}] + ], + [ + 'weight zero', '-b se@0 -b si@0 -b tpcb@0', - [qr{weight must not be zero}] ], + [qr{weight must not be zero}] + ], [ 'init vs run', '-i -S', [qr{cannot be used in initialization}] ], [ 'run vs init', '-S -F 90', [qr{cannot be used in benchmarking}] ], [ 'ambiguous builtin', '-b s', [qr{ambiguous}] ], - [ '--progress-timestamp => --progress', '--progress-timestamp', - [qr{allowed only under}] ], - [ '-I without init option', '-I dtg', - [qr{cannot be used in benchmarking mode}] ], - [ 'invalid init step', '-i -I dta', - [qr{unrecognized initialization step}, - qr{allowed steps are} ] ], - [ 'bad random seed', '--random-seed=one', - [qr{unrecognized random seed option "one": expecting an unsigned integer, "time" or "rand"}, - qr{error while setting random seed from --random-seed option} ] ], - - # loging sub-options - [ 'sampling => log', '--sampling-rate=0.01', - [qr{log sampling .* only when}] ], - [ 'sampling XOR aggregate', + [ + '--progress-timestamp => --progress', '--progress-timestamp', + [qr{allowed only under}] + ], + [ + '-I without init option', + '-I dtg', + [qr{cannot be used in benchmarking mode}] + ], + [ + 'invalid init step', + '-i -I dta', + [ qr{unrecognized initialization step}, qr{allowed steps are} ] + ], + [ + 'bad random seed', + '--random-seed=one', + [ + qr{unrecognized random seed option "one": expecting an unsigned integer, "time" or "rand"}, + qr{error while setting random seed from --random-seed option} + ] + ], + [ 'bad partition type', '-i --partition-method=BAD', [qr{"range"}, qr{"hash"}, qr{"BAD"}] ], + [ 'bad partition number', '-i --partitions -1', [ qr{invalid number of partitions: "-1"} ] ], + [ + 'partition method without partitioning', + '-i --partition-method=hash', + [ qr{partition-method requires greater than zero --partitions} ] + ], + + # logging sub-options + [ + 'sampling => log', '--sampling-rate=0.01', + [qr{log sampling .* only when}] + ], + [ + 'sampling XOR aggregate', '-l --sampling-rate=0.1 --aggregate-interval=3', - [qr{sampling .* aggregation .* cannot be used at the same time}] ], - [ 'aggregate => log', '--aggregate-interval=3', - [qr{aggregation .* only when}] ], + [qr{sampling .* aggregation .* cannot be used at the same time}] + ], + [ + 'aggregate => log', '--aggregate-interval=3', + [qr{aggregation .* only when}] + ], [ 'log-prefix => log', '--log-prefix=x', [qr{prefix .* only when}] ], - [ 'duration & aggregation', + [ + 'duration & aggregation', '-l -T 1 --aggregate-interval=3', - [qr{aggr.* not be higher}] ], - [ 'duration % aggregation', + [qr{aggr.* not be higher}] + ], + [ + 'duration % aggregation', '-l -T 5 --aggregate-interval=3', - [qr{multiple}] ],); + [qr{multiple}] + ],); for my $o (@options) { @@ -140,11 +201,13 @@ sub pgbench_scripts # Help pgbench( '--help', 0, - [ qr{benchmarking tool for PostgreSQL}, + [ + qr{benchmarking tool for PostgreSQL}, qr{Usage}, qr{Initialization options:}, qr{Common options:}, - qr{Report bugs to} ], + qr{Report bugs to} + ], [qr{^$}], 'pgbench help'); @@ -156,28 +219,116 @@ sub pgbench_scripts '-b list', 0, [qr{^$}], - [ qr{Available builtin scripts:}, qr{tpcb-like}, - qr{simple-update}, qr{select-only} ], + [ + qr{Available builtin scripts:}, qr{tpcb-like}, + qr{simple-update}, qr{select-only} + ], 'pgbench builtin list'); +# builtin listing +pgbench( + '--show-script se', + 0, + [qr{^$}], + [ qr{select-only: }, qr{SELECT abalance FROM pgbench_accounts WHERE}, + qr{(?!UPDATE)}, qr{(?!INSERT)} ], + 'pgbench builtin listing'); + my @script_tests = ( + # name, err, { file => contents } - [ 'missing endif', [qr{\\if without matching \\endif}], {'if-noendif.sql' => '\if 1'} ], - [ 'missing if on elif', [qr{\\elif without matching \\if}], {'elif-noif.sql' => '\elif 1'} ], - [ 'missing if on else', [qr{\\else without matching \\if}], {'else-noif.sql' => '\else'} ], - [ 'missing if on endif', [qr{\\endif without matching \\if}], {'endif-noif.sql' => '\endif'} ], - [ 'elif after else', [qr{\\elif after \\else}], {'else-elif.sql' => "\\if 1\n\\else\n\\elif 0\n\\endif"} ], - [ 'else after else', [qr{\\else after \\else}], {'else-else.sql' => "\\if 1\n\\else\n\\else\n\\endif"} ], - [ 'if syntax error', [qr{syntax error in command "if"}], {'if-bad.sql' => "\\if\n\\endif\n"} ], - [ 'elif syntax error', [qr{syntax error in command "elif"}], {'elif-bad.sql' => "\\if 0\n\\elif +\n\\endif\n"} ], - [ 'else syntax error', [qr{unexpected argument in command "else"}], {'else-bad.sql' => "\\if 0\n\\else BAD\n\\endif\n"} ], - [ 'endif syntax error', [qr{unexpected argument in command "endif"}], {'endif-bad.sql' => "\\if 0\n\\endif BAD\n"} ], -); + [ + 'missing endif', + [qr{\\if without matching \\endif}], + { 'if-noendif.sql' => '\if 1' } + ], + [ + 'missing if on elif', + [qr{\\elif without matching \\if}], + { 'elif-noif.sql' => '\elif 1' } + ], + [ + 'missing if on else', + [qr{\\else without matching \\if}], + { 'else-noif.sql' => '\else' } + ], + [ + 'missing if on endif', + [qr{\\endif without matching \\if}], + { 'endif-noif.sql' => '\endif' } + ], + [ + 'elif after else', + [qr{\\elif after \\else}], + { 'else-elif.sql' => "\\if 1\n\\else\n\\elif 0\n\\endif" } + ], + [ + 'else after else', + [qr{\\else after \\else}], + { 'else-else.sql' => "\\if 1\n\\else\n\\else\n\\endif" } + ], + [ + 'if syntax error', + [qr{syntax error in command "if"}], + { 'if-bad.sql' => "\\if\n\\endif\n" } + ], + [ + 'elif syntax error', + [qr{syntax error in command "elif"}], + { 'elif-bad.sql' => "\\if 0\n\\elif +\n\\endif\n" } + ], + [ + 'else syntax error', + [qr{unexpected argument in command "else"}], + { 'else-bad.sql' => "\\if 0\n\\else BAD\n\\endif\n" } + ], + [ + 'endif syntax error', + [qr{unexpected argument in command "endif"}], + { 'endif-bad.sql' => "\\if 0\n\\endif BAD\n" } + ], + [ + 'not enough arguments for least', + [qr{at least one argument expected \(least\)}], + { 'bad-least.sql' => "\\set i least()\n" } + ], + [ + 'not enough arguments for greatest', + [qr{at least one argument expected \(greatest\)}], + { 'bad-greatest.sql' => "\\set i greatest()\n" } + ], + [ + 'not enough arguments for hash', + [qr{unexpected number of arguments \(hash\)}], + { 'bad-hash-1.sql' => "\\set i hash()\n" } + ], + [ + 'too many arguments for hash', + [qr{unexpected number of arguments \(hash\)}], + { 'bad-hash-2.sql' => "\\set i hash(1,2,3)\n" } + ], + # overflow + [ + 'bigint overflow 1', + [qr{bigint constant overflow}], + { 'overflow-1.sql' => "\\set i 100000000000000000000\n" } + ], + [ + 'double overflow 2', + [qr{double constant overflow}], + { 'overflow-2.sql' => "\\set d 1.0E309\n" } + ], + [ + 'double overflow 3', + [qr{double constant overflow}], + { 'overflow-3.sql' => "\\set d .1E310\n" } + ],); for my $t (@script_tests) { my ($name, $err, $files) = @$t; - pgbench_scripts('', 1, [qr{^$}], $err, 'pgbench option error: ' . $name, $files); + pgbench_scripts('', 1, [qr{^$}], $err, 'pgbench option error: ' . $name, + $files); } done_testing(); diff --git a/src/bin/pgevent/Makefile b/src/bin/pgevent/Makefile index 5c79eb8e44d..171d0d81a0e 100644 --- a/src/bin/pgevent/Makefile +++ b/src/bin/pgevent/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/pgevent # -# Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Copyright (c) 1996-2019, PostgreSQL Global Development Group # #------------------------------------------------------------------------- diff --git a/src/bin/pgevent/README b/src/bin/pgevent/README index 3d0329ec330..10ec8d2d62b 100644 --- a/src/bin/pgevent/README +++ b/src/bin/pgevent/README @@ -3,7 +3,7 @@ src/bin/pgevent/README pgevent ======= -MSG000001.bin is a binary file, result of Microsoft MC compiler. MC compiler +MSG00001.bin is a binary file, result of Microsoft MC compiler. MC compiler can be downloaded for free with MS Core SDK but it is not included with MSYS tools and I didn't find an alternative way to compile MC file. diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile index cd1b1b6ee99..69bb297fe7c 100644 --- a/src/bin/psql/Makefile +++ b/src/bin/psql/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/psql # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/psql/Makefile diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 4c85f43f09e..b981ae81ffa 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/command.c */ @@ -28,6 +28,8 @@ #include "libpq-fe.h" #include "pqexpbuffer.h" +#include "common/logging.h" +#include "fe_utils/print.h" #include "fe_utils/string_utils.h" #include "common.h" @@ -38,7 +40,6 @@ #include "input.h" #include "large_obj.h" #include "mainloop.h" -#include "fe_utils/print.h" #include "psqlscanslash.h" #include "settings.h" #include "variables.h" @@ -54,77 +55,77 @@ typedef enum EditableObjectType /* local function declarations */ static backslashResult exec_command(const char *cmd, - PsqlScanState scan_state, - ConditionalStack cstack, - PQExpBuffer query_buf, - PQExpBuffer previous_buf); + PsqlScanState scan_state, + ConditionalStack cstack, + PQExpBuffer query_buf, + PQExpBuffer previous_buf); static backslashResult exec_command_a(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_C(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_connect(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_cd(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_conninfo(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_copy(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_copyright(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf, PQExpBuffer previous_buf); + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf, bool is_func); + PQExpBuffer query_buf, bool is_func); static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static backslashResult exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static backslashResult exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static backslashResult exec_command_encoding(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_errverbose(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_f(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_g(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_gdesc(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_gexec(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_gset(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_help(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_html(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_include(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_if(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static backslashResult exec_command_list(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf, PQExpBuffer previous_buf); + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, - const char *cmd, bool is_func); + const char *cmd, bool is_func); static backslashResult exec_command_t(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_T(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_timing(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_unset(PsqlScanState scan_state, bool active_branch, - const char *cmd); + const char *cmd); static backslashResult exec_command_write(PsqlScanState scan_state, bool active_branch, - const char *cmd, - PQExpBuffer query_buf, PQExpBuffer previous_buf); + const char *cmd, + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_watch(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf, PQExpBuffer previous_buf); + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_x(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_z(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_shell_escape(PsqlScanState scan_state, bool active_branch); @@ -138,27 +139,28 @@ static void ignore_slash_filepipe(PsqlScanState scan_state); static void ignore_slash_whole_line(PsqlScanState scan_state); static bool is_branching_command(const char *cmd); static void save_query_text_state(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static void discard_query_text(PsqlScanState scan_state, ConditionalStack cstack, - PQExpBuffer query_buf); + PQExpBuffer query_buf); static void copy_previous_query(PQExpBuffer query_buf, PQExpBuffer previous_buf); static bool do_connect(enum trivalue reuse_previous_specification, - char *dbname, char *user, char *host, char *port); + char *dbname, char *user, char *host, char *port); static bool do_edit(const char *filename_arg, PQExpBuffer query_buf, - int lineno, bool *edited); + int lineno, bool *edited); static bool do_shell(const char *command); static bool do_watch(PQExpBuffer query_buf, double sleep); static bool lookup_object_oid(EditableObjectType obj_type, const char *desc, - Oid *obj_oid); + Oid *obj_oid); static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid, - PQExpBuffer buf); + PQExpBuffer buf); static int strip_lineno_from_objdesc(char *obj); static int count_lines_in_buf(PQExpBuffer buf); static void print_with_linenumbers(FILE *output, char *lines, - const char *header_keyword); + const char *header_keyword); static void minimal_error_message(PGresult *res); static void printSSLInfo(void); +static void printGSSInfo(void); static bool printPsetInfo(const char *param, struct printQueryOpt *popt); static char *pset_value_string(const char *param, struct printQueryOpt *popt); @@ -216,10 +218,9 @@ HandleSlashCmds(PsqlScanState scan_state, if (status == PSQL_CMD_UNKNOWN) { + pg_log_error("invalid command \\%s", cmd); if (pset.cur_cmd_interactive) - psql_error("Invalid command \\%s. Try \\? for help.\n", cmd); - else - psql_error("invalid command \\%s\n", cmd); + pg_log_info("Try \\? for help."); status = PSQL_CMD_ERROR; } @@ -237,7 +238,7 @@ HandleSlashCmds(PsqlScanState scan_state, OT_NORMAL, NULL, false))) { if (active_branch) - psql_error("\\%s: extra argument \"%s\" ignored\n", cmd, arg); + pg_log_warning("\\%s: extra argument \"%s\" ignored", cmd, arg); free(arg); } conditional_stack_pop(cstack); @@ -289,8 +290,8 @@ exec_command(const char *cmd, if (pset.cur_cmd_interactive && !active_branch && !is_branching_command(cmd)) { - psql_error("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n", - cmd); + pg_log_warning("\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block", + cmd); } if (strcmp(cmd, "a") == 0) @@ -318,7 +319,8 @@ exec_command(const char *cmd, status = exec_command_ef_ev(scan_state, active_branch, query_buf, true); else if (strcmp(cmd, "ev") == 0) status = exec_command_ef_ev(scan_state, active_branch, query_buf, false); - else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0) + else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 || + strcmp(cmd, "warn") == 0) status = exec_command_echo(scan_state, active_branch, cmd); else if (strcmp(cmd, "elif") == 0) status = exec_command_elif(scan_state, cstack, query_buf); @@ -549,9 +551,9 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd) pw = getpwuid(user_id); if (!pw) { - psql_error("could not get home directory for user ID %ld: %s\n", - (long) user_id, - errno ? strerror(errno) : _("user does not exist")); + pg_log_error("could not get home directory for user ID %ld: %s", + (long) user_id, + errno ? strerror(errno) : _("user does not exist")); exit(EXIT_FAILURE); } dir = pw->pw_dir; @@ -567,8 +569,8 @@ exec_command_cd(PsqlScanState scan_state, bool active_branch, const char *cmd) if (chdir(dir) == -1) { - psql_error("\\%s: could not change directory to \"%s\": %s\n", - cmd, dir, strerror(errno)); + pg_log_error("\\%s: could not change directory to \"%s\": %m", + cmd, dir); success = false; } @@ -595,36 +597,33 @@ exec_command_conninfo(PsqlScanState scan_state, bool active_branch) printf(_("You are currently not connected to a database.\n")); else { - char *host; - PQconninfoOption *connOptions; - PQconninfoOption *option; - - host = PQhost(pset.db); - /* A usable "hostaddr" overrides the basic sense of host. */ - connOptions = PQconninfo(pset.db); - if (connOptions == NULL) - { - psql_error("out of memory\n"); - exit(EXIT_FAILURE); - } - for (option = connOptions; option && option->keyword; option++) - if (strcmp(option->keyword, "hostaddr") == 0) - { - if (option->val != NULL && option->val[0] != '\0') - host = option->val; - break; - } + char *host = PQhost(pset.db); + char *hostaddr = PQhostaddr(pset.db); - /* If the host is an absolute path, the connection is via socket */ + /* + * If the host is an absolute path, the connection is via socket + * unless overridden by hostaddr + */ if (is_absolute_path(host)) - printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), - db, PQuser(pset.db), host, PQport(pset.db)); + { + if (hostaddr && *hostaddr) + printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), hostaddr, PQport(pset.db)); + else + printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), host, PQport(pset.db)); + } else - printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), - db, PQuser(pset.db), host, PQport(pset.db)); + { + if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0) + printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"), + db, PQuser(pset.db), host, hostaddr, PQport(pset.db)); + else + printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), + db, PQuser(pset.db), host, PQport(pset.db)); + } printSSLInfo(); - - PQconninfoFree(connOptions); + printGSSInfo(); } } @@ -754,6 +753,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'S': case 'a': case 'n': + case 'p': case 't': case 'w': success = describeFunctions(&cmd[2], pattern, show_verbose, show_system); @@ -785,6 +785,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd) case 'p': success = permissionsList(pattern); break; + case 'P': + { + switch (cmd[2]) + { + case '\0': + case '+': + case 't': + case 'i': + case 'n': + success = listPartitionedTables(&cmd[2], pattern, show_verbose); + break; + default: + status = PSQL_CMD_UNKNOWN; + break; + } + } + break; case 'T': success = describeTypes(pattern, show_verbose, show_system); break; @@ -911,7 +928,7 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch, { if (!query_buf) { - psql_error("no query buffer\n"); + pg_log_error("no query buffer"); status = PSQL_CMD_ERROR; } else @@ -944,7 +961,7 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch, lineno = atoi(ln); if (lineno < 1) { - psql_error("invalid line number: %s\n", ln); + pg_log_error("invalid line number: %s", ln); status = PSQL_CMD_ERROR; } } @@ -998,16 +1015,16 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, formatPGVersionNumber(pset.sversion, false, sverbuf, sizeof(sverbuf)); if (is_func) - psql_error("The server (version %s) does not support editing function source.\n", - sverbuf); + pg_log_error("The server (version %s) does not support editing function source.", + sverbuf); else - psql_error("The server (version %s) does not support editing view definitions.\n", - sverbuf); + pg_log_error("The server (version %s) does not support editing view definitions.", + sverbuf); status = PSQL_CMD_ERROR; } else if (!query_buf) { - psql_error("no query buffer\n"); + pg_log_error("no query buffer"); status = PSQL_CMD_ERROR; } else @@ -1098,7 +1115,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, } /* - * \echo and \qecho -- echo arguments to stdout or query output + * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr */ static backslashResult exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd) @@ -1113,13 +1130,15 @@ exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd) if (strcmp(cmd, "qecho") == 0) fout = pset.queryFout; + else if (strcmp(cmd, "warn") == 0) + fout = stderr; else fout = stdout; while ((value = psql_scan_slash_option(scan_state, OT_NORMAL, "ed, false))) { - if (!quoted && strcmp(value, "-n") == 0) + if (first && !no_newline && !quoted && strcmp(value, "-n") == 0) no_newline = true; else { @@ -1160,7 +1179,7 @@ exec_command_encoding(PsqlScanState scan_state, bool active_branch) { /* set encoding */ if (PQsetClientEncoding(pset.db, encoding) == -1) - psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding); + pg_log_error("%s: invalid encoding name or conversion procedure not found", encoding); else { /* save encoding info into psql internal data */ @@ -1195,7 +1214,7 @@ exec_command_errverbose(PsqlScanState scan_state, bool active_branch) PQSHOW_CONTEXT_ALWAYS); if (msg) { - psql_error("%s", msg); + pg_log_error("%s", msg); PQfreemem(msg); } else @@ -1390,7 +1409,7 @@ exec_command_include(PsqlScanState scan_state, bool active_branch, const char *c if (!fname) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else @@ -1521,12 +1540,12 @@ exec_command_elif(PsqlScanState scan_state, ConditionalStack cstack, break; case IFSTATE_ELSE_TRUE: case IFSTATE_ELSE_FALSE: - psql_error("\\elif: cannot occur after \\else\n"); + pg_log_error("\\elif: cannot occur after \\else"); success = false; break; case IFSTATE_NONE: /* no \if to elif from */ - psql_error("\\elif: no matching \\if\n"); + pg_log_error("\\elif: no matching \\if"); success = false; break; } @@ -1590,12 +1609,12 @@ exec_command_else(PsqlScanState scan_state, ConditionalStack cstack, break; case IFSTATE_ELSE_TRUE: case IFSTATE_ELSE_FALSE: - psql_error("\\else: cannot occur after \\else\n"); + pg_log_error("\\else: cannot occur after \\else"); success = false; break; case IFSTATE_NONE: /* no \if to else from */ - psql_error("\\else: no matching \\if\n"); + pg_log_error("\\else: no matching \\if"); success = false; break; } @@ -1635,7 +1654,7 @@ exec_command_endif(PsqlScanState scan_state, ConditionalStack cstack, break; case IFSTATE_NONE: /* no \if to end */ - psql_error("\\endif: no matching \\if\n"); + pg_log_error("\\endif: no matching \\if"); success = false; break; } @@ -1695,7 +1714,7 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd) { if (!opt2) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else @@ -1709,7 +1728,7 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd) { if (!opt1) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else @@ -1726,7 +1745,7 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd) { if (!opt1) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else @@ -1817,7 +1836,7 @@ exec_command_password(PsqlScanState scan_state, bool active_branch) if (strcmp(pw1, pw2) != 0) { - psql_error("Passwords didn't match.\n"); + pg_log_error("Passwords didn't match."); success = false; } else @@ -1834,7 +1853,7 @@ exec_command_password(PsqlScanState scan_state, bool active_branch) if (!encrypted_password) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); success = false; } else @@ -1886,7 +1905,7 @@ exec_command_prompt(PsqlScanState scan_state, bool active_branch, if (!arg1) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else @@ -1916,8 +1935,8 @@ exec_command_prompt(PsqlScanState scan_state, bool active_branch, result = gets_fromFile(stdin); if (!result) { - psql_error("\\%s: could not read value for variable\n", - cmd); + pg_log_error("\\%s: could not read value for variable", + cmd); success = false; } } @@ -1960,8 +1979,8 @@ exec_command_pset(PsqlScanState scan_state, bool active_branch) int i; static const char *const my_list[] = { - "border", "columns", "expanded", "fieldsep", "fieldsep_zero", - "footer", "format", "linestyle", "null", + "border", "columns", "csv_fieldsep", "expanded", "fieldsep", + "fieldsep_zero", "footer", "format", "linestyle", "null", "numericlocale", "pager", "pager_min_lines", "recordsep", "recordsep_zero", "tableattr", "title", "tuples_only", @@ -2123,13 +2142,13 @@ exec_command_setenv(PsqlScanState scan_state, bool active_branch, if (!envvar) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else if (strchr(envvar, '=') != NULL) { - psql_error("\\%s: environment variable name must not contain \"=\"\n", - cmd); + pg_log_error("\\%s: environment variable name must not contain \"=\"", + cmd); success = false; } else if (!envval) @@ -2189,19 +2208,19 @@ exec_command_sf_sv(PsqlScanState scan_state, bool active_branch, formatPGVersionNumber(pset.sversion, false, sverbuf, sizeof(sverbuf)); if (is_func) - psql_error("The server (version %s) does not support showing function source.\n", - sverbuf); + pg_log_error("The server (version %s) does not support showing function source.", + sverbuf); else - psql_error("The server (version %s) does not support showing view definitions.\n", - sverbuf); + pg_log_error("The server (version %s) does not support showing view definitions.", + sverbuf); status = PSQL_CMD_ERROR; } else if (!obj_desc) { if (is_func) - psql_error("function name is required\n"); + pg_log_error("function name is required"); else - psql_error("view name is required\n"); + pg_log_error("view name is required"); status = PSQL_CMD_ERROR; } else if (!lookup_object_oid(eot, obj_desc, &obj_oid)) @@ -2359,7 +2378,7 @@ exec_command_unset(PsqlScanState scan_state, bool active_branch, if (!opt) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); success = false; } else if (!SetVariable(pset.vars, opt, NULL)) @@ -2392,14 +2411,14 @@ exec_command_write(PsqlScanState scan_state, bool active_branch, if (!query_buf) { - psql_error("no query buffer\n"); + pg_log_error("no query buffer"); status = PSQL_CMD_ERROR; } else { if (!fname) { - psql_error("\\%s: missing required argument\n", cmd); + pg_log_error("\\%s: missing required argument", cmd); status = PSQL_CMD_ERROR; } else @@ -2418,7 +2437,7 @@ exec_command_write(PsqlScanState scan_state, bool active_branch, } if (!fd) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); status = PSQL_CMD_ERROR; } } @@ -2446,7 +2465,7 @@ exec_command_write(PsqlScanState scan_state, bool active_branch, if (result == EOF) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); status = PSQL_CMD_ERROR; } } @@ -2854,6 +2873,26 @@ param_is_newly_set(const char *old_val, const char *new_val) return false; } +/* return whether the connection has 'hostaddr' in its conninfo */ +static bool +has_hostaddr(PGconn *conn) +{ + bool used = false; + PQconninfoOption *ciopt = PQconninfo(conn); + + for (PQconninfoOption *p = ciopt; p->keyword != NULL; p++) + { + if (strcmp(p->keyword, "hostaddr") == 0 && p->val != NULL) + { + used = true; + break; + } + } + + PQconninfoFree(ciopt); + return used; +} + /* * do_connect -- handler for \connect * @@ -2873,6 +2912,7 @@ do_connect(enum trivalue reuse_previous_specification, PGconn *o_conn = pset.db, *n_conn; char *password = NULL; + char *hostaddr = NULL; bool keep_password; bool has_connection_string; bool reuse_previous; @@ -2885,8 +2925,8 @@ do_connect(enum trivalue reuse_previous_specification, * connect to the wrong database by using defaults, so require all * parameters to be specified. */ - psql_error("All connection parameters must be supplied because no " - "database connection exists\n"); + pg_log_error("All connection parameters must be supplied because no " + "database connection exists"); return false; } @@ -2912,13 +2952,28 @@ do_connect(enum trivalue reuse_previous_specification, port = NULL; } - /* grab missing values from the old connection */ - if (!user && reuse_previous) - user = PQuser(o_conn); - if (!host && reuse_previous) - host = PQhost(o_conn); - if (!port && reuse_previous) - port = PQport(o_conn); + /* + * Grab missing values from the old connection. If we grab host (or host + * is the same as before) and hostaddr was set, grab that too. + */ + if (reuse_previous) + { + if (!user) + user = PQuser(o_conn); + if (host && strcmp(host, PQhost(o_conn)) == 0 && + has_hostaddr(o_conn)) + { + hostaddr = PQhostaddr(o_conn); + } + if (!host) + { + host = PQhost(o_conn); + if (has_hostaddr(o_conn)) + hostaddr = PQhostaddr(o_conn); + } + if (!port) + port = PQport(o_conn); + } /* * Any change in the parameters read above makes us discard the password. @@ -2940,7 +2995,7 @@ do_connect(enum trivalue reuse_previous_specification, if (!dbname && reuse_previous) { initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, PQdb(o_conn)); dbname = connstr.data; /* has_connection_string=true would be a dead store */ @@ -2980,13 +3035,18 @@ do_connect(enum trivalue reuse_previous_specification, while (true) { -#define PARAMS_ARRAY_SIZE 8 +#define PARAMS_ARRAY_SIZE 9 const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords)); const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values)); int paramnum = -1; keywords[++paramnum] = "host"; values[paramnum] = host; + if (hostaddr && *hostaddr) + { + keywords[++paramnum] = "hostaddr"; + values[paramnum] = hostaddr; + } keywords[++paramnum] = "port"; values[paramnum] = port; keywords[++paramnum] = "user"; @@ -3049,19 +3109,25 @@ do_connect(enum trivalue reuse_previous_specification, */ if (pset.cur_cmd_interactive) { - psql_error("%s", PQerrorMessage(n_conn)); + pg_log_info("%s", PQerrorMessage(n_conn)); /* pset.db is left unmodified */ if (o_conn) - psql_error("Previous connection kept\n"); + pg_log_info("Previous connection kept"); } else { - psql_error("\\connect: %s", PQerrorMessage(n_conn)); + pg_log_error("\\connect: %s", PQerrorMessage(n_conn)); if (o_conn) { + /* + * Transition to having no connection. Keep this bit in sync + * with CheckConnection(). + */ PQfinish(o_conn); pset.db = NULL; + ResetCancelConn(); + UnsyncVariables(); } } @@ -3075,7 +3141,8 @@ do_connect(enum trivalue reuse_previous_specification, /* * Replace the old connection with the new one, and update - * connection-dependent variables. + * connection-dependent variables. Keep the resynchronization logic in + * sync with CheckConnection(). */ PQsetNoticeProcessor(n_conn, NoticeProcessor, NULL); pset.db = n_conn; @@ -3090,14 +3157,30 @@ do_connect(enum trivalue reuse_previous_specification, param_is_newly_set(PQport(o_conn), PQport(pset.db))) { char *host = PQhost(pset.db); + char *hostaddr = PQhostaddr(pset.db); - /* If the host is an absolute path, the connection is via socket */ + /* + * If the host is an absolute path, the connection is via socket + * unless overridden by hostaddr + */ if (is_absolute_path(host)) - printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), - PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); + { + if (hostaddr && *hostaddr) + printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"), + PQdb(pset.db), PQuser(pset.db), hostaddr, PQport(pset.db)); + else + printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"), + PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); + } else - printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), - PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); + { + if (hostaddr && *hostaddr && strcmp(host, hostaddr) != 0) + printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"), + PQdb(pset.db), PQuser(pset.db), host, hostaddr, PQport(pset.db)); + else + printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"), + PQdb(pset.db), PQuser(pset.db), host, PQport(pset.db)); + } } else printf(_("You are now connected to database \"%s\" as user \"%s\".\n"), @@ -3150,9 +3233,11 @@ connection_warnings(bool in_startup) sverbuf, sizeof(sverbuf))); #ifdef WIN32 - checkWin32Codepage(); + if (in_startup) + checkWin32Codepage(); #endif printSSLInfo(); + printGSSInfo(); } } @@ -3185,6 +3270,20 @@ printSSLInfo(void) (compression && strcmp(compression, "off") != 0) ? _("on") : _("off")); } +/* + * printGSSInfo + * + * Prints information about the current GSSAPI connection, if GSSAPI encryption is in use + */ +static void +printGSSInfo(void) +{ + if (!PQgssEncInUse(pset.db)) + return; /* no GSSAPI encryption in use */ + + printf(_("GSSAPI-encrypted connection\n")); +} + /* * checkWin32Codepage @@ -3306,7 +3405,7 @@ editFile(const char *fname, int lineno) #endif if (!editor_lineno_arg) { - psql_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n"); + pg_log_error("environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number"); return false; } } @@ -3335,9 +3434,9 @@ editFile(const char *fname, int lineno) #endif result = system(sys); if (result == -1) - psql_error("could not start editor \"%s\"\n", editorName); + pg_log_error("could not start editor \"%s\"", editorName); else if (result == 127) - psql_error("could not start /bin/sh\n"); + pg_log_error("could not start /bin/sh"); free(sys); return result == 0; @@ -3375,8 +3474,8 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, ret = GetTempPath(MAXPGPATH, tmpdir); if (ret == 0 || ret > MAXPGPATH) { - psql_error("could not locate temporary directory: %s\n", - !ret ? strerror(errno) : ""); + pg_log_error("could not locate temporary directory: %s", + !ret ? strerror(errno) : ""); return false; } @@ -3402,7 +3501,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, if (fd == -1 || !stream) { - psql_error("could not open temporary file \"%s\": %s\n", fname, strerror(errno)); + pg_log_error("could not open temporary file \"%s\": %m", fname); error = true; } else @@ -3417,21 +3516,21 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, if (fwrite(query_buf->data, 1, ql, stream) != ql) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); if (fclose(stream) != 0) - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); if (remove(fname) != 0) - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } else if (fclose(stream) != 0) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); if (remove(fname) != 0) - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } } @@ -3439,7 +3538,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, if (!error && stat(fname, &before) != 0) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } @@ -3449,7 +3548,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, if (!error && stat(fname, &after) != 0) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } @@ -3458,7 +3557,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, stream = fopen(fname, PG_BINARY_R); if (!stream) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } else @@ -3472,7 +3571,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, if (ferror(stream)) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } else if (edited) @@ -3489,7 +3588,7 @@ do_edit(const char *filename_arg, PQExpBuffer query_buf, { if (remove(fname) == -1) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); error = true; } } @@ -3547,7 +3646,7 @@ process_file(char *filename, bool use_relative_path) if (!fd) { - psql_error("%s: %s\n", filename, strerror(errno)); + pg_log_error("%s: %m", filename); return EXIT_FAILURE; } } @@ -3560,12 +3659,17 @@ process_file(char *filename, bool use_relative_path) oldfilename = pset.inputfile; pset.inputfile = filename; + pg_logging_config(pset.inputfile ? 0 : PG_LOG_FLAG_TERSE); + result = MainLoop(fd); if (fd != stdin) fclose(fd); pset.inputfile = oldfilename; + + pg_logging_config(pset.inputfile ? 0 : PG_LOG_FLAG_TERSE); + return result; } @@ -3579,21 +3683,18 @@ _align2string(enum printFormat in) case PRINT_NOTHING: return "nothing"; break; - case PRINT_UNALIGNED: - return "unaligned"; - break; case PRINT_ALIGNED: return "aligned"; break; - case PRINT_WRAPPED: - return "wrapped"; + case PRINT_ASCIIDOC: + return "asciidoc"; + break; + case PRINT_CSV: + return "csv"; break; case PRINT_HTML: return "html"; break; - case PRINT_ASCIIDOC: - return "asciidoc"; - break; case PRINT_LATEX: return "latex"; break; @@ -3603,6 +3704,12 @@ _align2string(enum printFormat in) case PRINT_TROFF_MS: return "troff-ms"; break; + case PRINT_UNALIGNED: + return "unaligned"; + break; + case PRINT_WRAPPED: + return "wrapped"; + break; } return "unknown"; } @@ -3656,28 +3763,60 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) /* set format */ if (strcmp(param, "format") == 0) { + static const struct fmt + { + const char *name; + enum printFormat number; + } formats[] = + { + /* remember to update error message below when adding more */ + {"aligned", PRINT_ALIGNED}, + {"asciidoc", PRINT_ASCIIDOC}, + {"csv", PRINT_CSV}, + {"html", PRINT_HTML}, + {"latex", PRINT_LATEX}, + {"troff-ms", PRINT_TROFF_MS}, + {"unaligned", PRINT_UNALIGNED}, + {"wrapped", PRINT_WRAPPED} + }; + if (!value) ; - else if (pg_strncasecmp("unaligned", value, vallen) == 0) - popt->topt.format = PRINT_UNALIGNED; - else if (pg_strncasecmp("aligned", value, vallen) == 0) - popt->topt.format = PRINT_ALIGNED; - else if (pg_strncasecmp("wrapped", value, vallen) == 0) - popt->topt.format = PRINT_WRAPPED; - else if (pg_strncasecmp("html", value, vallen) == 0) - popt->topt.format = PRINT_HTML; - else if (pg_strncasecmp("asciidoc", value, vallen) == 0) - popt->topt.format = PRINT_ASCIIDOC; - else if (pg_strncasecmp("latex", value, vallen) == 0) - popt->topt.format = PRINT_LATEX; - else if (pg_strncasecmp("latex-longtable", value, vallen) == 0) - popt->topt.format = PRINT_LATEX_LONGTABLE; - else if (pg_strncasecmp("troff-ms", value, vallen) == 0) - popt->topt.format = PRINT_TROFF_MS; else { - psql_error("\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n"); - return false; + int match_pos = -1; + + for (int i = 0; i < lengthof(formats); i++) + { + if (pg_strncasecmp(formats[i].name, value, vallen) == 0) + { + if (match_pos < 0) + match_pos = i; + else + { + pg_log_error("\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"", + value, + formats[match_pos].name, formats[i].name); + return false; + } + } + } + if (match_pos >= 0) + popt->topt.format = formats[match_pos].number; + else if (pg_strncasecmp("latex-longtable", value, vallen) == 0) + { + /* + * We must treat latex-longtable specially because latex is a + * prefix of it; if both were in the table above, we'd think + * "latex" is ambiguous. + */ + popt->topt.format = PRINT_LATEX_LONGTABLE; + } + else + { + pg_log_error("\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped"); + return false; + } } } @@ -3694,7 +3833,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.line_style = &pg_utf8format; else { - psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n"); + pg_log_error("\\pset: allowed line styles are ascii, old-ascii, unicode"); return false; } } @@ -3709,7 +3848,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) refresh_utf8format(&(popt->topt)); else { - psql_error("\\pset: allowed Unicode border line styles are single, double\n"); + pg_log_error("\\pset: allowed Unicode border line styles are single, double"); return false; } } @@ -3724,7 +3863,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) refresh_utf8format(&(popt->topt)); else { - psql_error("\\pset: allowed Unicode column line styles are single, double\n"); + pg_log_error("\\pset: allowed Unicode column line styles are single, double"); return false; } } @@ -3739,7 +3878,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) refresh_utf8format(&(popt->topt)); else { - psql_error("\\pset: allowed Unicode header line styles are single, double\n"); + pg_log_error("\\pset: allowed Unicode header line styles are single, double"); return false; } } @@ -3774,6 +3913,26 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.expanded = !popt->topt.expanded; } + /* field separator for CSV format */ + else if (strcmp(param, "csv_fieldsep") == 0) + { + if (value) + { + /* CSV separator has to be a one-byte character */ + if (strlen(value) != 1) + { + pg_log_error("\\pset: csv_fieldsep must be a single one-byte character"); + return false; + } + if (value[0] == '"' || value[0] == '\n' || value[0] == '\r') + { + pg_log_error("\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return"); + return false; + } + popt->topt.csvFieldSep[0] = value[0]; + } + } + /* locale-aware numeric output */ else if (strcmp(param, "numericlocale") == 0) { @@ -3904,7 +4063,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) } else { - psql_error("\\pset: unknown option: %s\n", param); + pg_log_error("\\pset: unknown option: %s", param); return false; } @@ -3944,6 +4103,13 @@ printPsetInfo(const char *param, struct printQueryOpt *popt) printf(_("Expanded display is off.\n")); } + /* show field separator for CSV format */ + else if (strcmp(param, "csv_fieldsep") == 0) + { + printf(_("Field separator for CSV is \"%s\".\n"), + popt->topt.csvFieldSep); + } + /* show field separator for unaligned text */ else if (strcmp(param, "fieldsep") == 0) { @@ -4083,7 +4249,7 @@ printPsetInfo(const char *param, struct printQueryOpt *popt) else { - psql_error("\\pset: unknown option: %s\n", param); + pg_log_error("\\pset: unknown option: %s", param); return false; } @@ -4145,6 +4311,8 @@ pset_value_string(const char *param, struct printQueryOpt *popt) return psprintf("%d", popt->topt.border); else if (strcmp(param, "columns") == 0) return psprintf("%d", popt->topt.columns); + else if (strcmp(param, "csv_fieldsep") == 0) + return pset_quoted_string(popt->topt.csvFieldSep); else if (strcmp(param, "expanded") == 0) return pstrdup(popt->topt.expanded == 2 ? "auto" @@ -4237,7 +4405,7 @@ do_shell(const char *command) if (result == 127 || result == -1) { - psql_error("\\!: failed\n"); + pg_log_error("\\!: failed"); return false; } return true; @@ -4262,7 +4430,7 @@ do_watch(PQExpBuffer query_buf, double sleep) if (!query_buf || query_buf->len <= 0) { - psql_error(_("\\watch cannot be used with an empty query\n")); + pg_log_error("\\watch cannot be used with an empty query"); return false; } @@ -4419,7 +4587,7 @@ lookup_object_oid(EditableObjectType obj_type, const char *desc, */ appendPQExpBufferStr(query, "SELECT "); appendStringLiteralConn(query, desc, pset.db); - appendPQExpBuffer(query, "::pg_catalog.regclass::pg_catalog.oid"); + appendPQExpBufferStr(query, "::pg_catalog.regclass::pg_catalog.oid"); break; } @@ -4483,7 +4651,7 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid, printfPQExpBuffer(query, "SELECT nspname, relname, relkind, " "pg_catalog.pg_get_viewdef(c.oid, true), " - "array_remove(array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " + "pg_catalog.array_remove(pg_catalog.array_remove(c.reloptions,'check_option=local'),'check_option=cascaded') AS reloptions, " "CASE WHEN 'check_option=local' = ANY (c.reloptions) THEN 'LOCAL'::text " "WHEN 'check_option=cascaded' = ANY (c.reloptions) THEN 'CASCADED'::text ELSE NULL END AS checkoption " "FROM pg_catalog.pg_class c " @@ -4559,8 +4727,8 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid, appendPQExpBufferStr(buf, "CREATE OR REPLACE VIEW "); break; default: - psql_error("\"%s.%s\" is not a view\n", - nspname, relname); + pg_log_error("\"%s.%s\" is not a view", + nspname, relname); result = false; break; } @@ -4575,7 +4743,7 @@ get_create_object_cmd(EditableObjectType obj_type, Oid oid, pset.encoding, standard_strings())) { - psql_error("could not parse reloptions array\n"); + pg_log_error("could not parse reloptions array"); result = false; } appendPQExpBufferChar(buf, ')'); @@ -4664,7 +4832,7 @@ strip_lineno_from_objdesc(char *obj) lineno = atoi(c); if (lineno < 1) { - psql_error("invalid line number: %s\n", c); + pg_log_error("invalid line number: %s", c); return 0; } @@ -4766,7 +4934,7 @@ minimal_error_message(PGresult *res) appendPQExpBufferStr(msg, "(not available)"); appendPQExpBufferChar(msg, '\n'); - psql_error("%s", msg->data); + pg_log_error("%s", msg->data); destroyPQExpBuffer(msg); } diff --git a/src/bin/psql/command.h b/src/bin/psql/command.h index 29a8edd5a5d..33791b6ff8b 100644 --- a/src/bin/psql/command.h +++ b/src/bin/psql/command.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/command.h */ @@ -26,16 +26,16 @@ typedef enum _backslashResult extern backslashResult HandleSlashCmds(PsqlScanState scan_state, - ConditionalStack cstack, - PQExpBuffer query_buf, - PQExpBuffer previous_buf); + ConditionalStack cstack, + PQExpBuffer query_buf, + PQExpBuffer previous_buf); extern int process_file(char *filename, bool use_relative_path); extern bool do_pset(const char *param, - const char *value, - printQueryOpt *popt, - bool quiet); + const char *value, + printQueryOpt *popt, + bool quiet); extern void connection_warnings(bool in_startup); diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 2b1c4daceda..4b2679360fc 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1,12 +1,11 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/common.c */ #include "postgres_fe.h" -#include "common.h" #include #include @@ -19,14 +18,16 @@ #include #endif +#include "common/logging.h" +#include "fe_utils/mbprint.h" #include "fe_utils/string_utils.h" #include "portability/instr_time.h" -#include "settings.h" #include "command.h" +#include "common.h" #include "copy.h" #include "crosstabview.h" -#include "fe_utils/mbprint.h" +#include "settings.h" static bool DescribeQuery(const char *query, double *elapsed_msec); @@ -67,7 +68,7 @@ openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe) if (*fout == NULL) { - psql_error("%s: %s\n", fname, strerror(errno)); + pg_log_error("%s: %m", fname); return false; } @@ -156,7 +157,7 @@ psql_get_variable(const char *varname, PsqlScanQuoteType quote, if (!pset.db) { - psql_error("cannot escape without active connection\n"); + pg_log_error("cannot escape without active connection"); return NULL; } @@ -171,7 +172,7 @@ psql_get_variable(const char *varname, PsqlScanQuoteType quote, { const char *error = PQerrorMessage(pset.db); - psql_error("%s", error); + pg_log_info("%s", error); return NULL; } @@ -197,8 +198,8 @@ psql_get_variable(const char *varname, PsqlScanQuoteType quote, initPQExpBuffer(&buf); if (!appendShellStringNoError(&buf, value)) { - psql_error("shell command argument contains a newline or carriage return: \"%s\"\n", - value); + pg_log_error("shell command argument contains a newline or carriage return: \"%s\"", + value); free(buf.data); return NULL; } @@ -213,28 +214,6 @@ psql_get_variable(const char *varname, PsqlScanQuoteType quote, } -/* - * Error reporting for scripts. Errors should look like - * psql:filename:lineno: message - */ -void -psql_error(const char *fmt,...) -{ - va_list ap; - - fflush(stdout); - if (pset.queryFout && pset.queryFout != stdout) - fflush(pset.queryFout); - - if (pset.inputfile) - fprintf(stderr, "%s:%s:" UINT64_FORMAT ": ", pset.progname, pset.inputfile, pset.lineno); - va_start(ap, fmt); - vfprintf(stderr, _(fmt), ap); - va_end(ap); -} - - - /* * for backend Notice messages (INFO, WARNING, etc) */ @@ -242,7 +221,7 @@ void NoticeProcessor(void *arg, const char *message) { (void) arg; /* not used */ - psql_error("%s", message); + pg_log_info("%s", message); } @@ -413,23 +392,37 @@ CheckConnection(void) { if (!pset.cur_cmd_interactive) { - psql_error("connection to server was lost\n"); + pg_log_fatal("connection to server was lost"); exit(EXIT_BADCONN); } - psql_error("The connection to the server was lost. Attempting reset: "); + fprintf(stderr, _("The connection to the server was lost. Attempting reset: ")); PQreset(pset.db); OK = ConnectionUp(); if (!OK) { - psql_error("Failed.\n"); + fprintf(stderr, _("Failed.\n")); + + /* + * Transition to having no connection. Keep this bit in sync with + * do_connect(). + */ PQfinish(pset.db); pset.db = NULL; ResetCancelConn(); UnsyncVariables(); } else - psql_error("Succeeded.\n"); + { + fprintf(stderr, _("Succeeded.\n")); + + /* + * Re-sync, just in case anything changed. Keep this in sync with + * do_connect(). + */ + SyncVariables(); + connection_warnings(false); /* Must be after SyncVariables */ + } } return OK; @@ -529,8 +522,8 @@ AcceptResult(const PGresult *result) default: OK = false; - psql_error("unexpected PQresultStatus: %d\n", - PQresultStatus(result)); + pg_log_error("unexpected PQresultStatus: %d", + PQresultStatus(result)); break; } @@ -539,7 +532,7 @@ AcceptResult(const PGresult *result) const char *error = PQerrorMessage(pset.db); if (strlen(error)) - psql_error("%s", error); + pg_log_info("%s", error); CheckConnection(); } @@ -693,7 +686,7 @@ PSQLexec(const char *query) if (!pset.db) { - psql_error("You are currently not connected to a database.\n"); + pg_log_error("You are currently not connected to a database."); return NULL; } @@ -751,7 +744,7 @@ PSQLexecWatch(const char *query, const printQueryOpt *opt) if (!pset.db) { - psql_error("You are currently not connected to a database.\n"); + pg_log_error("You are currently not connected to a database."); return 0; } @@ -799,19 +792,19 @@ PSQLexecWatch(const char *query, const printQueryOpt *opt) break; case PGRES_EMPTY_QUERY: - psql_error(_("\\watch cannot be used with an empty query\n")); + pg_log_error("\\watch cannot be used with an empty query"); PQclear(res); return -1; case PGRES_COPY_OUT: case PGRES_COPY_IN: case PGRES_COPY_BOTH: - psql_error(_("\\watch cannot be used with COPY\n")); + pg_log_error("\\watch cannot be used with COPY"); PQclear(res); return -1; default: - psql_error(_("unexpected result status for \\watch\n")); + pg_log_error("unexpected result status for \\watch"); PQclear(res); return -1; } @@ -836,7 +829,8 @@ PrintNotifications(void) { PGnotify *notify; - while ((notify = PQnotifies(pset.db))) + PQconsumeInput(pset.db); + while ((notify = PQnotifies(pset.db)) != NULL) { /* for backward compatibility, only show payload if nonempty */ if (notify->extra[0]) @@ -847,6 +841,7 @@ PrintNotifications(void) notify->relname, notify->be_pid); fflush(pset.queryFout); PQfreemem(notify); + PQconsumeInput(pset.db); } } @@ -905,12 +900,12 @@ StoreQueryTuple(const PGresult *result) if (PQntuples(result) < 1) { - psql_error("no rows returned for \\gset\n"); + pg_log_error("no rows returned for \\gset"); success = false; } else if (PQntuples(result) > 1) { - psql_error("more than one row returned for \\gset\n"); + pg_log_error("more than one row returned for \\gset"); success = false; } else @@ -1079,7 +1074,7 @@ ProcessResult(PGresult **results) default: /* AcceptResult() should have caught anything else. */ is_copy = false; - psql_error("unexpected PQresultStatus: %d\n", result_status); + pg_log_error("unexpected PQresultStatus: %d", result_status); break; } @@ -1090,20 +1085,49 @@ ProcessResult(PGresult **results) * connection out of its COPY state, then call PQresultStatus() * once and report any error. * - * If pset.copyStream is set, use that as data source/sink, - * otherwise use queryFout or cur_cmd_source as appropriate. + * For COPY OUT, direct the output to pset.copyStream if it's set, + * otherwise to pset.gfname if it's set, otherwise to queryFout. + * For COPY IN, use pset.copyStream as data source if it's set, + * otherwise cur_cmd_source. */ - FILE *copystream = pset.copyStream; + FILE *copystream; PGresult *copy_result; SetCancelConn(); if (result_status == PGRES_COPY_OUT) { - if (!copystream) + bool need_close = false; + bool is_pipe = false; + + if (pset.copyStream) + { + /* invoked by \copy */ + copystream = pset.copyStream; + } + else if (pset.gfname) + { + /* invoked by \g */ + if (openQueryOutputFile(pset.gfname, + ©stream, &is_pipe)) + { + need_close = true; + if (is_pipe) + disable_sigpipe_trap(); + } + else + copystream = NULL; /* discard COPY data entirely */ + } + else + { + /* fall back to the generic query output stream */ copystream = pset.queryFout; + } + success = handleCopyOut(pset.db, copystream, - ©_result) && success; + ©_result) + && success + && (copystream != NULL); /* * Suppress status printing if the report would go to the same @@ -1115,11 +1139,25 @@ ProcessResult(PGresult **results) PQclear(copy_result); copy_result = NULL; } + + if (need_close) + { + /* close \g argument file/pipe */ + if (is_pipe) + { + pclose(copystream); + restore_sigpipe_trap(); + } + else + { + fclose(copystream); + } + } } else { - if (!copystream) - copystream = pset.cur_cmd_source; + /* COPY IN */ + copystream = pset.copyStream ? pset.copyStream : pset.cur_cmd_source; success = handleCopyIn(pset.db, copystream, PQbinaryTuples(*results), @@ -1253,8 +1291,8 @@ PrintQueryResults(PGresult *results) default: success = false; - psql_error("unexpected PQresultStatus: %d\n", - PQresultStatus(results)); + pg_log_error("unexpected PQresultStatus: %d", + PQresultStatus(results)); break; } @@ -1289,7 +1327,7 @@ SendQuery(const char *query) if (!pset.db) { - psql_error("You are currently not connected to a database.\n"); + pg_log_error("You are currently not connected to a database."); goto sendquery_cleanup; } @@ -1335,7 +1373,7 @@ SendQuery(const char *query) results = PQexec(pset.db, "BEGIN"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(results); ResetCancelConn(); goto sendquery_cleanup; @@ -1353,9 +1391,9 @@ SendQuery(const char *query) { char sverbuf[32]; - psql_error("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_warning("The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); on_error_rollback_warning = true; } else @@ -1363,7 +1401,7 @@ SendQuery(const char *query) results = PQexec(pset.db, "SAVEPOINT pg_psql_temporary_savepoint"); if (PQresultStatus(results) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(results); ResetCancelConn(); goto sendquery_cleanup; @@ -1416,7 +1454,7 @@ SendQuery(const char *query) } if (!OK && pset.echo == PSQL_ECHO_ERRORS) - psql_error("STATEMENT: %s\n", query); + pg_log_info("STATEMENT: %s", query); /* If we made a temporary savepoint, possibly release/rollback */ if (on_error_rollback_savepoint) @@ -1459,8 +1497,8 @@ SendQuery(const char *query) OK = false; /* PQTRANS_UNKNOWN is expected given a broken connection. */ if (transaction_status != PQTRANS_UNKNOWN || ConnectionUp()) - psql_error("unexpected transaction status (%d)\n", - transaction_status); + pg_log_error("unexpected transaction status (%d)", + transaction_status); break; } @@ -1471,7 +1509,7 @@ SendQuery(const char *query) svptres = PQexec(pset.db, svptcmd); if (PQresultStatus(svptres) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); ClearOrSaveResult(svptres); OK = false; @@ -1574,7 +1612,7 @@ DescribeQuery(const char *query, double *elapsed_msec) results = PQprepare(pset.db, "", query, 0, NULL); if (PQresultStatus(results) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); SetResultVariables(results, false); ClearOrSaveResult(results); return false; @@ -1612,7 +1650,7 @@ DescribeQuery(const char *query, double *elapsed_msec) if (escname == NULL) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); PQclear(results); termPQExpBuffer(&buf); return false; @@ -2047,8 +2085,8 @@ command_no_begin(const char *query) /* * Commands not allowed within transactions. The statements checked for - * here should be exactly those that call PreventInTransactionBlock() in the - * backend. + * here should be exactly those that call PreventInTransactionBlock() in + * the backend. */ if (wordlen == 6 && pg_strncasecmp(query, "vacuum", 6) == 0) return true; @@ -2147,6 +2185,22 @@ command_no_begin(const char *query) return true; if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0) return true; + if (wordlen == 5 && (pg_strncasecmp(query, "index", 5) == 0 || + pg_strncasecmp(query, "table", 5) == 0)) + { + query += wordlen; + query = skip_white_space(query); + wordlen = 0; + while (isalpha((unsigned char) query[wordlen])) + wordlen += PQmblen(&query[wordlen], pset.encoding); + + /* + * REINDEX [ TABLE | INDEX ] CONCURRENTLY are not allowed in + * xacts. + */ + if (wordlen == 12 && pg_strncasecmp(query, "concurrently", 12) == 0) + return true; + } /* DROP INDEX CONCURRENTLY isn't allowed in xacts */ if (wordlen == 5 && pg_strncasecmp(query, "index", 5) == 0) diff --git a/src/bin/psql/common.h b/src/bin/psql/common.h index 43142a7aa60..282a520116a 100644 --- a/src/bin/psql/common.h +++ b/src/bin/psql/common.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/common.h */ @@ -18,9 +18,7 @@ extern bool openQueryOutputFile(const char *fname, FILE **fout, bool *is_pipe); extern bool setQFout(const char *fname); extern char *psql_get_variable(const char *varname, PsqlScanQuoteType quote, - void *passthrough); - -extern void psql_error(const char *fmt,...) pg_attribute_printf(1, 2); + void *passthrough); extern void NoticeProcessor(void *arg, const char *message); diff --git a/src/bin/psql/copy.c b/src/bin/psql/copy.c index 555c6331a36..f9e53d62954 100644 --- a/src/bin/psql/copy.c +++ b/src/bin/psql/copy.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/copy.c */ @@ -24,6 +24,7 @@ #include "prompt.h" #include "stringutils.h" +#include "common/logging.h" /* * parse_slash_copy @@ -96,7 +97,7 @@ parse_slash_copy(const char *args) if (!args) { - psql_error("\\copy: arguments required\n"); + pg_log_error("\\copy: arguments required"); return NULL; } @@ -251,9 +252,9 @@ parse_slash_copy(const char *args) error: if (token) - psql_error("\\copy: parse error at \"%s\"\n", token); + pg_log_error("\\copy: parse error at \"%s\"", token); else - psql_error("\\copy: parse error at end of line\n"); + pg_log_error("\\copy: parse error at end of line"); free_copy_options(result); return NULL; @@ -326,11 +327,11 @@ do_copy(const char *args) if (!copystream) { if (options->program) - psql_error("could not execute command \"%s\": %s\n", - options->file, strerror(errno)); + pg_log_error("could not execute command \"%s\": %m", + options->file); else - psql_error("%s: %s\n", - options->file, strerror(errno)); + pg_log_error("%s: %m", + options->file); free_copy_options(options); return false; } @@ -342,12 +343,12 @@ do_copy(const char *args) /* make sure the specified file is not a directory */ if ((result = fstat(fileno(copystream), &st)) < 0) - psql_error("could not stat file \"%s\": %s\n", - options->file, strerror(errno)); + pg_log_error("could not stat file \"%s\": %m", + options->file); if (result == 0 && S_ISDIR(st.st_mode)) - psql_error("%s: cannot copy from/to a directory\n", - options->file); + pg_log_error("%s: cannot copy from/to a directory", + options->file); if (result < 0 || S_ISDIR(st.st_mode)) { @@ -383,14 +384,13 @@ do_copy(const char *args) if (pclose_rc != 0) { if (pclose_rc < 0) - psql_error("could not close pipe to external command: %s\n", - strerror(errno)); + pg_log_error("could not close pipe to external command: %m"); else { char *reason = wait_result_to_str(pclose_rc); - psql_error("%s: %s\n", options->file, - reason ? reason : ""); + pg_log_error("%s: %s", options->file, + reason ? reason : ""); if (reason) free(reason); } @@ -402,7 +402,7 @@ do_copy(const char *args) { if (fclose(copystream) != 0) { - psql_error("%s: %s\n", options->file, strerror(errno)); + pg_log_error("%s: %m", options->file); success = false; } } @@ -425,7 +425,10 @@ do_copy(const char *args) * * conn should be a database connection that you just issued COPY TO on * and got back a PGRES_COPY_OUT result. + * * copystream is the file stream for the data to go to. + * copystream can be NULL to eat the data without writing it anywhere. + * * The final status for the COPY is returned into *res (but note * we already reported the error, if it's not a success result). * @@ -447,10 +450,9 @@ handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res) if (buf) { - if (OK && fwrite(buf, 1, ret, copystream) != ret) + if (OK && copystream && fwrite(buf, 1, ret, copystream) != ret) { - psql_error("could not write COPY data: %s\n", - strerror(errno)); + pg_log_error("could not write COPY data: %m"); /* complain only once, keep reading data from server */ OK = false; } @@ -458,16 +460,15 @@ handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res) } } - if (OK && fflush(copystream)) + if (OK && copystream && fflush(copystream)) { - psql_error("could not write COPY data: %s\n", - strerror(errno)); + pg_log_error("could not write COPY data: %m"); OK = false; } if (ret == -2) { - psql_error("COPY data transfer failed: %s", PQerrorMessage(conn)); + pg_log_error("COPY data transfer failed: %s", PQerrorMessage(conn)); OK = false; } @@ -486,7 +487,7 @@ handleCopyOut(PGconn *conn, FILE *copystream, PGresult **res) *res = PQgetResult(conn); if (PQresultStatus(*res) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(conn)); + pg_log_info("%s", PQerrorMessage(conn)); OK = false; } @@ -705,7 +706,7 @@ handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, PGresult **res) } if (PQresultStatus(*res) != PGRES_COMMAND_OK) { - psql_error("%s", PQerrorMessage(conn)); + pg_log_info("%s", PQerrorMessage(conn)); OK = false; } diff --git a/src/bin/psql/copy.h b/src/bin/psql/copy.h index f4107d70b07..cee731beeb4 100644 --- a/src/bin/psql/copy.h +++ b/src/bin/psql/copy.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/copy.h */ @@ -17,8 +17,8 @@ extern bool do_copy(const char *args); /* lower level processors for copy in/out streams */ extern bool handleCopyOut(PGconn *conn, FILE *copystream, - PGresult **res); + PGresult **res); extern bool handleCopyIn(PGconn *conn, FILE *copystream, bool isbinary, - PGresult **res); + PGresult **res); #endif diff --git a/src/bin/psql/create_help.pl b/src/bin/psql/create_help.pl index cb0e6e806ef..d8e6671e689 100644 --- a/src/bin/psql/create_help.pl +++ b/src/bin/psql/create_help.pl @@ -3,7 +3,7 @@ ################################################################# # create_help.pl -- converts SGML docs to internal psql help # -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group # # src/bin/psql/create_help.pl ################################################################# @@ -64,6 +64,7 @@ { const char *cmd; /* the command name */ const char *help; /* the help associated with it */ + const char *docbook_id; /* DocBook XML id (for generating URL) */ void (*syntaxfunc)(PQExpBuffer); /* function that prints the syntax associated with it */ int nl_count; /* number of newlines in syntax (for pager) */ }; @@ -92,7 +93,7 @@ foreach my $file (sort readdir DIR) { - my (@cmdnames, $cmddesc, $cmdsynopsis); + my ($cmdid, @cmdnames, $cmddesc, $cmdsynopsis); $file =~ /\.sgml$/ or next; open(my $fh, '<', "$docdir/$file") or next; @@ -104,6 +105,9 @@ m!\s*SQL - Language Statements\s*!i or next; + $filecontent =~ m!! + and $cmdid = $1; + # Collect multiple refnames LOOP: { @@ -116,7 +120,7 @@ $filecontent =~ m!\s*(.+?)\s*!is and $cmdsynopsis = $1; - if (@cmdnames && $cmddesc && $cmdsynopsis) + if (@cmdnames && $cmddesc && $cmdid && $cmdsynopsis) { s/\"/\\"/g foreach @cmdnames; @@ -128,8 +132,6 @@ my $nl_count = () = $cmdsynopsis =~ /\n/g; - $cmdsynopsis =~ m!! - and die "$0: $file: null end tag not supported in synopsis\n"; $cmdsynopsis =~ s/%/%%/g; while ($cmdsynopsis =~ m!<(\w+)[^>]*>(.+?)]*>!) @@ -146,10 +148,12 @@ foreach my $cmdname (@cmdnames) { $entries{$cmdname} = { + cmdid => $cmdid, cmddesc => $cmddesc, cmdsynopsis => $cmdsynopsis, params => \@params, - nl_count => $nl_count }; + nl_count => $nl_count + }; $maxlen = ($maxlen >= length $cmdname) ? $maxlen : length $cmdname; } @@ -187,6 +191,7 @@ $id =~ s/ /_/g; print $cfile_handle " { \"$_\", N_(\"$entries{$_}{cmddesc}\"), + \"$entries{$_}{cmdid}\", sql_help_$id, $entries{$_}{nl_count} }, diff --git a/src/bin/psql/crosstabview.c b/src/bin/psql/crosstabview.c index 05042b3e133..83789cb911a 100644 --- a/src/bin/psql/crosstabview.c +++ b/src/bin/psql/crosstabview.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/crosstabview.c */ @@ -13,6 +13,7 @@ #include "psqlscanslash.h" #include "settings.h" +#include "common/logging.h" /* * Value/position from the resultset that goes into the horizontal or vertical @@ -78,13 +79,13 @@ typedef struct _avl_tree static bool printCrosstab(const PGresult *results, - int num_columns, pivot_field *piv_columns, int field_for_columns, - int num_rows, pivot_field *piv_rows, int field_for_rows, - int field_for_data); + int num_columns, pivot_field *piv_columns, int field_for_columns, + int num_rows, pivot_field *piv_rows, int field_for_rows, + int field_for_data); static void avlInit(avl_tree *tree); static void avlMergeValue(avl_tree *tree, char *name, char *sort_value); -static int avlCollectFields(avl_tree *tree, avl_node *node, - pivot_field *fields, int idx); +static int avlCollectFields(avl_tree *tree, avl_node *node, + pivot_field *fields, int idx); static void avlFree(avl_tree *tree, avl_node *node); static void rankSort(int num_columns, pivot_field *piv_columns); static int indexOfColumn(char *arg, const PGresult *res); @@ -120,13 +121,13 @@ PrintResultsInCrosstab(const PGresult *res) if (PQresultStatus(res) != PGRES_TUPLES_OK) { - psql_error("\\crosstabview: statement did not return a result set\n"); + pg_log_error("\\crosstabview: statement did not return a result set"); goto error_return; } if (PQnfields(res) < 3) { - psql_error("\\crosstabview: query must return at least three columns\n"); + pg_log_error("\\crosstabview: query must return at least three columns"); goto error_return; } @@ -153,7 +154,7 @@ PrintResultsInCrosstab(const PGresult *res) /* Insist that header columns be distinct */ if (field_for_columns == field_for_rows) { - psql_error("\\crosstabview: vertical and horizontal headers must be different columns\n"); + pg_log_error("\\crosstabview: vertical and horizontal headers must be different columns"); goto error_return; } @@ -169,7 +170,7 @@ PrintResultsInCrosstab(const PGresult *res) */ if (PQnfields(res) != 3) { - psql_error("\\crosstabview: data column must be specified when query returns more than three columns\n"); + pg_log_error("\\crosstabview: data column must be specified when query returns more than three columns"); goto error_return; } @@ -225,8 +226,8 @@ PrintResultsInCrosstab(const PGresult *res) if (piv_columns.count > CROSSTABVIEW_MAX_COLUMNS) { - psql_error("\\crosstabview: maximum number of columns (%d) exceeded\n", - CROSSTABVIEW_MAX_COLUMNS); + pg_log_error("\\crosstabview: maximum number of columns (%d) exceeded", + CROSSTABVIEW_MAX_COLUMNS); goto error_return; } @@ -394,11 +395,11 @@ printCrosstab(const PGresult *results, */ if (cont.cells[idx] != NULL) { - psql_error("\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n", - rp->name ? rp->name : - (popt.nullPrint ? popt.nullPrint : "(null)"), - cp->name ? cp->name : - (popt.nullPrint ? popt.nullPrint : "(null)")); + pg_log_error("\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"", + rp->name ? rp->name : + (popt.nullPrint ? popt.nullPrint : "(null)"), + cp->name ? cp->name : + (popt.nullPrint ? popt.nullPrint : "(null)")); goto error; } @@ -642,8 +643,8 @@ indexOfColumn(char *arg, const PGresult *res) idx = atoi(arg) - 1; if (idx < 0 || idx >= PQnfields(res)) { - psql_error("\\crosstabview: column number %d is out of range 1..%d\n", - idx + 1, PQnfields(res)); + pg_log_error("\\crosstabview: column number %d is out of range 1..%d", + idx + 1, PQnfields(res)); return -1; } } @@ -667,7 +668,7 @@ indexOfColumn(char *arg, const PGresult *res) if (idx >= 0) { /* another idx was already found for the same name */ - psql_error("\\crosstabview: ambiguous column name: \"%s\"\n", arg); + pg_log_error("\\crosstabview: ambiguous column name: \"%s\"", arg); return -1; } idx = i; @@ -675,7 +676,7 @@ indexOfColumn(char *arg, const PGresult *res) } if (idx == -1) { - psql_error("\\crosstabview: column name not found: \"%s\"\n", arg); + pg_log_error("\\crosstabview: column name not found: \"%s\"", arg); return -1; } } diff --git a/src/bin/psql/crosstabview.h b/src/bin/psql/crosstabview.h index 54ddcc308b4..bb02032bbd5 100644 --- a/src/bin/psql/crosstabview.h +++ b/src/bin/psql/crosstabview.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/crosstabview.h */ @@ -9,6 +9,8 @@ #ifndef CROSSTABVIEW_H #define CROSSTABVIEW_H +#include "libpq-fe.h" + /* * Limit the number of output columns generated in memory by the crosstabview * algorithm. A new output column is added for each distinct value found in the diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 410131e5c72..d7c0fc0c1e7 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -6,7 +6,7 @@ * with servers of versions 7.4 and up. It's okay to omit irrelevant * information for an old server, but not to fail outright. * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/describe.c */ @@ -15,32 +15,35 @@ #include #include "catalog/pg_attribute_d.h" +#include "catalog/pg_cast_d.h" #include "catalog/pg_class_d.h" #include "catalog/pg_default_acl_d.h" + +#include "common/logging.h" +#include "fe_utils/mbprint.h" +#include "fe_utils/print.h" #include "fe_utils/string_utils.h" #include "common.h" #include "describe.h" -#include "fe_utils/mbprint.h" -#include "fe_utils/print.h" #include "settings.h" #include "variables.h" static bool describeOneTableDetails(const char *schemaname, - const char *relationname, - const char *oid, - bool verbose); + const char *relationname, + const char *oid, + bool verbose); static void add_tablespace_footer(printTableContent *const cont, char relkind, - Oid tablespace, const bool newline); + Oid tablespace, const bool newline); static void add_role_attribute(PQExpBuffer buf, const char *const str); static bool listTSParsersVerbose(const char *pattern); static bool describeOneTSParser(const char *oid, const char *nspname, - const char *prsname); + const char *prsname); static bool listTSConfigsVerbose(const char *pattern); static bool describeOneTSConfig(const char *oid, const char *nspname, - const char *cfgname, - const char *pnspname, const char *prsname); + const char *cfgname, + const char *pnspname, const char *prsname); static void printACLColumn(PQExpBuffer buf, const char *colname); static bool listOneExtensionContents(const char *extname, const char *oid); @@ -156,9 +159,9 @@ describeAccessMethods(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support access methods.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support access methods.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -168,9 +171,11 @@ describeAccessMethods(const char *pattern, bool verbose) "SELECT amname AS \"%s\",\n" " CASE amtype" " WHEN 'i' THEN '%s'" + " WHEN 't' THEN '%s'" " END AS \"%s\"", gettext_noop("Name"), gettext_noop("Index"), + gettext_noop("Table"), gettext_noop("Type")); if (verbose) @@ -223,9 +228,9 @@ describeTablespaces(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support tablespaces.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_info("The server (version %s) does not support tablespaces.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -302,6 +307,7 @@ describeTablespaces(const char *pattern, bool verbose) * * a for aggregates * n for normal + * p for procedure * t for trigger * w for window * @@ -312,6 +318,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool { bool showAggregate = strchr(functypes, 'a') != NULL; bool showNormal = strchr(functypes, 'n') != NULL; + bool showProcedure = strchr(functypes, 'p') != NULL; bool showTrigger = strchr(functypes, 't') != NULL; bool showWindow = strchr(functypes, 'w') != NULL; bool have_where; @@ -323,9 +330,20 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool /* No "Parallel" column before 9.6 */ static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, false, false, false, false}; - if (strlen(functypes) != strspn(functypes, "antwS+")) + if (strlen(functypes) != strspn(functypes, "anptwS+")) { - psql_error("\\df only takes [antwS+] as options\n"); + pg_log_error("\\df only takes [anptwS+] as options"); + return true; + } + + if (showProcedure && pset.sversion < 110000) + { + char sverbuf[32]; + + pg_log_error("\\df does not take a \"%c\" option with server version %s", + 'p', + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -333,15 +351,18 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool { char sverbuf[32]; - psql_error("\\df does not take a \"w\" option with server version %s\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("\\df does not take a \"%c\" option with server version %s", + 'w', + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } - if (!showAggregate && !showNormal && !showTrigger && !showWindow) + if (!showAggregate && !showNormal && !showProcedure && !showTrigger && !showWindow) { showAggregate = showNormal = showTrigger = true; + if (pset.sversion >= 110000) + showProcedure = true; if (pset.sversion >= 80400) showWindow = true; } @@ -505,7 +526,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool have_where = false; /* filter by function type, if requested */ - if (showNormal && showAggregate && showTrigger && showWindow) + if (showNormal && showAggregate && showProcedure && showTrigger && showWindow) /* Do nothing */ ; else if (showNormal) { @@ -523,6 +544,17 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool else appendPQExpBufferStr(&buf, "NOT p.proisagg\n"); } + if (!showProcedure && pset.sversion >= 110000) + { + if (have_where) + appendPQExpBufferStr(&buf, " AND "); + else + { + appendPQExpBufferStr(&buf, "WHERE "); + have_where = true; + } + appendPQExpBufferStr(&buf, "p.prokind <> 'p'\n"); + } if (!showTrigger) { if (have_where) @@ -572,6 +604,13 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n"); needs_or = true; } + if (showProcedure) + { + if (needs_or) + appendPQExpBufferStr(&buf, " OR "); + appendPQExpBufferStr(&buf, "p.prokind = 'p'\n"); + needs_or = true; + } if (showWindow) { if (needs_or) @@ -921,7 +960,7 @@ permissionsList(const char *pattern) gettext_noop("materialized view"), gettext_noop("sequence"), gettext_noop("foreign table"), - gettext_noop("table"), /* partitioned table */ + gettext_noop("partitioned table"), gettext_noop("Type")); printACLColumn(&buf, "c.relacl"); @@ -1061,9 +1100,9 @@ listDefaultACLs(const char *pattern) { char sverbuf[32]; - psql_error("The server (version %s) does not support altering default privileges.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support altering default privileges.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -1362,10 +1401,10 @@ describeTableDetails(const char *pattern, bool verbose, bool showSystem) if (!pset.quiet) { if (pattern) - psql_error("Did not find any relation named \"%s\".\n", - pattern); + pg_log_error("Did not find any relation named \"%s\".", + pattern); else - psql_error("Did not find any relations.\n"); + pg_log_error("Did not find any relations."); } PQclear(res); return false; @@ -1410,6 +1449,7 @@ describeOneTableDetails(const char *schemaname, const char *oid, bool verbose) { + bool retval = false; PQExpBufferData buf; PGresult *res = NULL; printTableOpt myopt = pset.popt.topt; @@ -1421,7 +1461,20 @@ describeOneTableDetails(const char *schemaname, PQExpBufferData title; PQExpBufferData tmpbuf; int cols; - int numrows = 0; + int attname_col = -1, /* column indexes in "res" */ + atttype_col = -1, + attrdef_col = -1, + attnotnull_col = -1, + attcoll_col = -1, + attidentity_col = -1, + attgenerated_col = -1, + isindexkey_col = -1, + indexdef_col = -1, + fdwopts_col = -1, + attstorage_col = -1, + attstattarget_col = -1, + attdescr_col = -1; + int numrows; struct { int16 checks; @@ -1432,16 +1485,15 @@ describeOneTableDetails(const char *schemaname, bool rowsecurity; bool forcerowsecurity; bool hasoids; + bool ispartition; Oid tablespace; char *reloptions; char *reloftype; char relpersistence; char relreplident; + char *relam; } tableinfo; bool show_column_details = false; - bool retval; - - retval = false; myopt.default_footer = false; /* This output looks confusing in expanded mode. */ @@ -1452,12 +1504,47 @@ describeOneTableDetails(const char *schemaname, initPQExpBuffer(&tmpbuf); /* Get general table info */ - if (pset.sversion >= 90500) + if (pset.sversion >= 120000) + { + printfPQExpBuffer(&buf, + "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " + "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, " + "false AS relhasoids, c.relispartition, %s, c.reltablespace, " + "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " + "c.relpersistence, c.relreplident, am.amname\n" + "FROM pg_catalog.pg_class c\n " + "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" + "LEFT JOIN pg_catalog.pg_am am ON (c.relam = am.oid)\n" + "WHERE c.oid = '%s';", + (verbose ? + "pg_catalog.array_to_string(c.reloptions || " + "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n" + : "''"), + oid); + } + else if (pset.sversion >= 100000) + { + printfPQExpBuffer(&buf, + "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " + "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, " + "c.relhasoids, c.relispartition, %s, c.reltablespace, " + "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " + "c.relpersistence, c.relreplident\n" + "FROM pg_catalog.pg_class c\n " + "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" + "WHERE c.oid = '%s';", + (verbose ? + "pg_catalog.array_to_string(c.reloptions || " + "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n" + : "''"), + oid); + } + else if (pset.sversion >= 90500) { printfPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, " - "c.relhasoids, %s, c.reltablespace, " + "c.relhasoids, false as relispartition, %s, c.reltablespace, " "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " "c.relpersistence, c.relreplident\n" "FROM pg_catalog.pg_class c\n " @@ -1474,7 +1561,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " "c.relhastriggers, false, false, c.relhasoids, " - "%s, c.reltablespace, " + "false as relispartition, %s, c.reltablespace, " "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " "c.relpersistence, c.relreplident\n" "FROM pg_catalog.pg_class c\n " @@ -1491,7 +1578,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " "c.relhastriggers, false, false, c.relhasoids, " - "%s, c.reltablespace, " + "false as relispartition, %s, c.reltablespace, " "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, " "c.relpersistence\n" "FROM pg_catalog.pg_class c\n " @@ -1508,7 +1595,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " "c.relhastriggers, false, false, c.relhasoids, " - "%s, c.reltablespace, " + "false as relispartition, %s, c.reltablespace, " "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n" "FROM pg_catalog.pg_class c\n " "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" @@ -1524,7 +1611,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, " "c.relhastriggers, false, false, c.relhasoids, " - "%s, c.reltablespace\n" + "false as relispartition, %s, c.reltablespace\n" "FROM pg_catalog.pg_class c\n " "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n" "WHERE c.oid = '%s';", @@ -1539,7 +1626,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT relchecks, relkind, relhasindex, relhasrules, " "reltriggers <> 0, false, false, relhasoids, " - "%s, reltablespace\n" + "false as relispartition, %s, reltablespace\n" "FROM pg_catalog.pg_class WHERE oid = '%s';", (verbose ? "pg_catalog.array_to_string(reloptions, E', ')" : "''"), @@ -1550,7 +1637,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT relchecks, relkind, relhasindex, relhasrules, " "reltriggers <> 0, false, false, relhasoids, " - "'', reltablespace\n" + "false as relispartition, '', reltablespace\n" "FROM pg_catalog.pg_class WHERE oid = '%s';", oid); } @@ -1559,7 +1646,7 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&buf, "SELECT relchecks, relkind, relhasindex, relhasrules, " "reltriggers <> 0, false, false, relhasoids, " - "'', ''\n" + "false as relispartition, '', ''\n" "FROM pg_catalog.pg_class WHERE oid = '%s';", oid); } @@ -1572,7 +1659,7 @@ describeOneTableDetails(const char *schemaname, if (PQntuples(res) == 0) { if (!pset.quiet) - psql_error("Did not find any relation with OID %s.\n", oid); + pg_log_error("Did not find any relation with OID %s.", oid); goto error_return; } @@ -1584,17 +1671,23 @@ describeOneTableDetails(const char *schemaname, tableinfo.rowsecurity = strcmp(PQgetvalue(res, 0, 5), "t") == 0; tableinfo.forcerowsecurity = strcmp(PQgetvalue(res, 0, 6), "t") == 0; tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 7), "t") == 0; + tableinfo.ispartition = strcmp(PQgetvalue(res, 0, 8), "t") == 0; tableinfo.reloptions = (pset.sversion >= 80200) ? - pg_strdup(PQgetvalue(res, 0, 8)) : NULL; + pg_strdup(PQgetvalue(res, 0, 9)) : NULL; tableinfo.tablespace = (pset.sversion >= 80000) ? - atooid(PQgetvalue(res, 0, 9)) : 0; + atooid(PQgetvalue(res, 0, 10)) : 0; tableinfo.reloftype = (pset.sversion >= 90000 && - strcmp(PQgetvalue(res, 0, 10), "") != 0) ? - pg_strdup(PQgetvalue(res, 0, 10)) : NULL; + strcmp(PQgetvalue(res, 0, 11), "") != 0) ? + pg_strdup(PQgetvalue(res, 0, 11)) : NULL; tableinfo.relpersistence = (pset.sversion >= 90100) ? - *(PQgetvalue(res, 0, 11)) : 0; + *(PQgetvalue(res, 0, 12)) : 0; tableinfo.relreplident = (pset.sversion >= 90400) ? - *(PQgetvalue(res, 0, 12)) : 'd'; + *(PQgetvalue(res, 0, 13)) : 'd'; + if (pset.sversion >= 120000) + tableinfo.relam = PQgetisnull(res, 0, 14) ? + (char *) NULL : pg_strdup(PQgetvalue(res, 0, 14)); + else + tableinfo.relam = NULL; PQclear(res); res = NULL; @@ -1720,42 +1813,94 @@ describeOneTableDetails(const char *schemaname, goto error_return; /* not an error, just return early */ } + /* Identify whether we should print collation, nullable, default vals */ + if (tableinfo.relkind == RELKIND_RELATION || + tableinfo.relkind == RELKIND_VIEW || + tableinfo.relkind == RELKIND_MATVIEW || + tableinfo.relkind == RELKIND_FOREIGN_TABLE || + tableinfo.relkind == RELKIND_COMPOSITE_TYPE || + tableinfo.relkind == RELKIND_PARTITIONED_TABLE) + show_column_details = true; + /* - * Get column info + * Get per-column info * - * You need to modify value of "firstvcol" which will be defined below if - * you are adding column(s) preceding to verbose-only columns. + * Since the set of query columns we need varies depending on relkind and + * server version, we compute all the column numbers on-the-fly. Column + * number variables for columns not fetched are left as -1; this avoids + * duplicative test logic below. */ - printfPQExpBuffer(&buf, "SELECT a.attname,"); - appendPQExpBufferStr(&buf, "\n pg_catalog.format_type(a.atttypid, a.atttypmod)," - "\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)" - "\n FROM pg_catalog.pg_attrdef d" - "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)," - "\n a.attnotnull, a.attnum,"); - if (pset.sversion >= 90100) - appendPQExpBufferStr(&buf, "\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n" - " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation"); - else - appendPQExpBufferStr(&buf, "\n NULL AS attcollation"); - if (pset.sversion >= 100000) - appendPQExpBufferStr(&buf, ",\n a.attidentity"); - else - appendPQExpBufferStr(&buf, ",\n ''::pg_catalog.char AS attidentity"); + cols = 0; + printfPQExpBuffer(&buf, "SELECT a.attname"); + attname_col = cols++; + appendPQExpBufferStr(&buf, ",\n pg_catalog.format_type(a.atttypid, a.atttypmod)"); + atttype_col = cols++; + + if (show_column_details) + { + /* use "pretty" mode for expression to avoid excessive parentheses */ + appendPQExpBufferStr(&buf, + ",\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128)" + "\n FROM pg_catalog.pg_attrdef d" + "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef)" + ",\n a.attnotnull"); + attrdef_col = cols++; + attnotnull_col = cols++; + if (pset.sversion >= 90100) + appendPQExpBufferStr(&buf, ",\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n" + " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation"); + else + appendPQExpBufferStr(&buf, ",\n NULL AS attcollation"); + attcoll_col = cols++; + if (pset.sversion >= 100000) + appendPQExpBufferStr(&buf, ",\n a.attidentity"); + else + appendPQExpBufferStr(&buf, ",\n ''::pg_catalog.char AS attidentity"); + attidentity_col = cols++; + if (pset.sversion >= 120000) + appendPQExpBufferStr(&buf, ",\n a.attgenerated"); + else + appendPQExpBufferStr(&buf, ",\n ''::pg_catalog.char AS attgenerated"); + attgenerated_col = cols++; + } if (tableinfo.relkind == RELKIND_INDEX || tableinfo.relkind == RELKIND_PARTITIONED_INDEX) + { + if (pset.sversion >= 110000) + { + appendPQExpBuffer(&buf, ",\n CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key", + oid, + gettext_noop("yes"), + gettext_noop("no")); + isindexkey_col = cols++; + } appendPQExpBufferStr(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef"); - else - appendPQExpBufferStr(&buf, ",\n NULL AS indexdef"); + indexdef_col = cols++; + } + /* FDW options for foreign table column, only for 9.2 or later */ if (tableinfo.relkind == RELKIND_FOREIGN_TABLE && pset.sversion >= 90200) + { appendPQExpBufferStr(&buf, ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE " " '(' || pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM " " pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions"); - else - appendPQExpBufferStr(&buf, ",\n NULL AS attfdwoptions"); + fdwopts_col = cols++; + } if (verbose) { appendPQExpBufferStr(&buf, ",\n a.attstorage"); - appendPQExpBufferStr(&buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget"); + attstorage_col = cols++; + + /* stats target, if relevant to relkind */ + if (tableinfo.relkind == RELKIND_RELATION || + tableinfo.relkind == RELKIND_INDEX || + tableinfo.relkind == RELKIND_PARTITIONED_INDEX || + tableinfo.relkind == RELKIND_MATVIEW || + tableinfo.relkind == RELKIND_FOREIGN_TABLE || + tableinfo.relkind == RELKIND_PARTITIONED_TABLE) + { + appendPQExpBufferStr(&buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget"); + attstattarget_col = cols++; + } /* * In 9.0+, we have column comments for: relations, views, composite @@ -1767,7 +1912,10 @@ describeOneTableDetails(const char *schemaname, tableinfo.relkind == RELKIND_FOREIGN_TABLE || tableinfo.relkind == RELKIND_COMPOSITE_TYPE || tableinfo.relkind == RELKIND_PARTITIONED_TABLE) - appendPQExpBufferStr(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum)"); + { + appendPQExpBufferStr(&buf, ",\n pg_catalog.col_description(a.attrelid, a.attnum)"); + attdescr_col = cols++; + } } appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_attribute a"); @@ -1803,7 +1951,6 @@ describeOneTableDetails(const char *schemaname, schemaname, relationname); break; case RELKIND_INDEX: - case RELKIND_PARTITIONED_INDEX: if (tableinfo.relpersistence == 'u') printfPQExpBuffer(&title, _("Unlogged index \"%s.%s\""), schemaname, relationname); @@ -1811,6 +1958,14 @@ describeOneTableDetails(const char *schemaname, printfPQExpBuffer(&title, _("Index \"%s.%s\""), schemaname, relationname); break; + case RELKIND_PARTITIONED_INDEX: + if (tableinfo.relpersistence == 'u') + printfPQExpBuffer(&title, _("Unlogged partitioned index \"%s.%s\""), + schemaname, relationname); + else + printfPQExpBuffer(&title, _("Partitioned index \"%s.%s\""), + schemaname, relationname); + break; case 's': /* not used as of 8.2, but keep it for backwards compatibility */ printfPQExpBuffer(&title, _("Special relation \"%s.%s\""), @@ -1830,10 +1985,10 @@ describeOneTableDetails(const char *schemaname, break; case RELKIND_PARTITIONED_TABLE: if (tableinfo.relpersistence == 'u') - printfPQExpBuffer(&title, _("Unlogged table \"%s.%s\""), + printfPQExpBuffer(&title, _("Unlogged partitioned table \"%s.%s\""), schemaname, relationname); else - printfPQExpBuffer(&title, _("Table \"%s.%s\""), + printfPQExpBuffer(&title, _("Partitioned table \"%s.%s\""), schemaname, relationname); break; default: @@ -1843,50 +1998,30 @@ describeOneTableDetails(const char *schemaname, break; } - /* Set the number of columns, and their names */ - headers[0] = gettext_noop("Column"); - headers[1] = gettext_noop("Type"); - cols = 2; - - if (tableinfo.relkind == RELKIND_RELATION || - tableinfo.relkind == RELKIND_VIEW || - tableinfo.relkind == RELKIND_MATVIEW || - tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_COMPOSITE_TYPE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) + /* Fill headers[] with the names of the columns we will output */ + cols = 0; + headers[cols++] = gettext_noop("Column"); + headers[cols++] = gettext_noop("Type"); + if (show_column_details) { headers[cols++] = gettext_noop("Collation"); headers[cols++] = gettext_noop("Nullable"); headers[cols++] = gettext_noop("Default"); - show_column_details = true; } - - if (tableinfo.relkind == RELKIND_INDEX || - tableinfo.relkind == RELKIND_PARTITIONED_INDEX) + if (isindexkey_col >= 0) + headers[cols++] = gettext_noop("Key?"); + if (indexdef_col >= 0) headers[cols++] = gettext_noop("Definition"); - - if (tableinfo.relkind == RELKIND_FOREIGN_TABLE && pset.sversion >= 90200) + if (fdwopts_col >= 0) headers[cols++] = gettext_noop("FDW options"); - - if (verbose) - { + if (attstorage_col >= 0) headers[cols++] = gettext_noop("Storage"); - if (tableinfo.relkind == RELKIND_RELATION || - tableinfo.relkind == RELKIND_INDEX || - tableinfo.relkind == RELKIND_PARTITIONED_INDEX || - tableinfo.relkind == RELKIND_MATVIEW || - tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) - headers[cols++] = gettext_noop("Stats target"); - /* Column comments, if the relkind supports this feature. */ - if (tableinfo.relkind == RELKIND_RELATION || - tableinfo.relkind == RELKIND_VIEW || - tableinfo.relkind == RELKIND_MATVIEW || - tableinfo.relkind == RELKIND_COMPOSITE_TYPE || - tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) - headers[cols++] = gettext_noop("Description"); - } + if (attstattarget_col >= 0) + headers[cols++] = gettext_noop("Stats target"); + if (attdescr_col >= 0) + headers[cols++] = gettext_noop("Description"); + + Assert(cols <= lengthof(headers)); printTableInit(&cont, &myopt, title.data, cols, numrows); printTableInitialized = true; @@ -1894,71 +2029,58 @@ describeOneTableDetails(const char *schemaname, for (i = 0; i < cols; i++) printTableAddHeader(&cont, headers[i], true, 'l'); - /* Get view_def if table is a view or materialized view */ - if ((tableinfo.relkind == RELKIND_VIEW || - tableinfo.relkind == RELKIND_MATVIEW) && verbose) - { - PGresult *result; - - printfPQExpBuffer(&buf, - "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);", - oid); - result = PSQLexec(buf.data); - if (!result) - goto error_return; - - if (PQntuples(result) > 0) - view_def = pg_strdup(PQgetvalue(result, 0, 0)); - - PQclear(result); - } - /* Generate table cells to be printed */ for (i = 0; i < numrows; i++) { /* Column */ - printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, attname_col), false, false); /* Type */ - printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, atttype_col), false, false); /* Collation, Nullable, Default */ if (show_column_details) { char *identity; + char *generated; char *default_str = ""; - printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false); + printTableAddCell(&cont, PQgetvalue(res, i, attcoll_col), false, false); - printTableAddCell(&cont, strcmp(PQgetvalue(res, i, 3), "t") == 0 ? "not null" : "", false, false); + printTableAddCell(&cont, + strcmp(PQgetvalue(res, i, attnotnull_col), "t") == 0 ? "not null" : "", + false, false); - identity = PQgetvalue(res, i, 6); + identity = PQgetvalue(res, i, attidentity_col); + generated = PQgetvalue(res, i, attgenerated_col); - if (!identity[0]) - /* (note: above we cut off the 'default' string at 128) */ - default_str = PQgetvalue(res, i, 2); - else if (identity[0] == ATTRIBUTE_IDENTITY_ALWAYS) + if (identity[0] == ATTRIBUTE_IDENTITY_ALWAYS) default_str = "generated always as identity"; else if (identity[0] == ATTRIBUTE_IDENTITY_BY_DEFAULT) default_str = "generated by default as identity"; + else if (generated[0] == ATTRIBUTE_GENERATED_STORED) + default_str = psprintf("generated always as (%s) stored", PQgetvalue(res, i, attrdef_col)); + else + /* (note: above we cut off the 'default' string at 128) */ + default_str = PQgetvalue(res, i, attrdef_col); - printTableAddCell(&cont, default_str, false, false); + printTableAddCell(&cont, default_str, false, generated[0] ? true : false); } - /* Expression for index column */ - if (tableinfo.relkind == RELKIND_INDEX || - tableinfo.relkind == RELKIND_PARTITIONED_INDEX) - printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false); + /* Info for index columns */ + if (isindexkey_col >= 0) + printTableAddCell(&cont, PQgetvalue(res, i, isindexkey_col), true, false); + if (indexdef_col >= 0) + printTableAddCell(&cont, PQgetvalue(res, i, indexdef_col), false, false); - /* FDW options for foreign table column, only for 9.2 or later */ - if (tableinfo.relkind == RELKIND_FOREIGN_TABLE && pset.sversion >= 90200) - printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false); + /* FDW options for foreign table columns */ + if (fdwopts_col >= 0) + printTableAddCell(&cont, PQgetvalue(res, i, fdwopts_col), false, false); /* Storage and Description */ - if (verbose) + if (attstorage_col >= 0) { - int firstvcol = 9; - char *storage = PQgetvalue(res, i, firstvcol); + char *storage = PQgetvalue(res, i, attstorage_col); /* these strings are literal in our syntax, so not translated. */ printTableAddCell(&cont, (storage[0] == 'p' ? "plain" : @@ -1967,63 +2089,46 @@ describeOneTableDetails(const char *schemaname, (storage[0] == 'e' ? "external" : "???")))), false, false); + } - /* Statistics target, if the relkind supports this feature */ - if (tableinfo.relkind == RELKIND_RELATION || - tableinfo.relkind == RELKIND_INDEX || - tableinfo.relkind == RELKIND_PARTITIONED_INDEX || - tableinfo.relkind == RELKIND_MATVIEW || - tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) - { - printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1), - false, false); - } + /* Statistics target, if the relkind supports this feature */ + if (attstattarget_col >= 0) + printTableAddCell(&cont, PQgetvalue(res, i, attstattarget_col), + false, false); - /* Column comments, if the relkind supports this feature. */ - if (tableinfo.relkind == RELKIND_RELATION || - tableinfo.relkind == RELKIND_VIEW || - tableinfo.relkind == RELKIND_MATVIEW || - tableinfo.relkind == RELKIND_COMPOSITE_TYPE || - tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) - printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 2), - false, false); - } + /* Column comments, if the relkind supports this feature */ + if (attdescr_col >= 0) + printTableAddCell(&cont, PQgetvalue(res, i, attdescr_col), + false, false); } /* Make footers */ - if (pset.sversion >= 100000) + + if (tableinfo.ispartition) { - /* Get the partition information */ + /* Footer information for a partition child table */ PGresult *result; - char *parent_name; - char *partdef; - char *partconstraintdef = NULL; printfPQExpBuffer(&buf, "SELECT inhparent::pg_catalog.regclass,\n" - " pg_catalog.pg_get_expr(c.relpartbound, inhrelid)"); + " pg_catalog.pg_get_expr(c.relpartbound, c.oid)"); /* If verbose, also request the partition constraint definition */ if (verbose) - appendPQExpBuffer(&buf, - ",\n pg_catalog.pg_get_partition_constraintdef(inhrelid)"); + appendPQExpBufferStr(&buf, + ",\n pg_catalog.pg_get_partition_constraintdef(c.oid)"); appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_class c" " JOIN pg_catalog.pg_inherits i" " ON c.oid = inhrelid" - "\nWHERE c.oid = '%s' AND c.relispartition;", oid); + "\nWHERE c.oid = '%s';", oid); result = PSQLexec(buf.data); if (!result) goto error_return; if (PQntuples(result) > 0) { - parent_name = PQgetvalue(result, 0, 0); - partdef = PQgetvalue(result, 0, 1); - - if (PQnfields(result) == 3 && !PQgetisnull(result, 0, 2)) - partconstraintdef = PQgetvalue(result, 0, 2); + char *parent_name = PQgetvalue(result, 0, 0); + char *partdef = PQgetvalue(result, 0, 1); printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name, partdef); @@ -2031,6 +2136,10 @@ describeOneTableDetails(const char *schemaname, if (verbose) { + char *partconstraintdef = NULL; + + if (!PQgetisnull(result, 0, 2)) + partconstraintdef = PQgetvalue(result, 0, 2); /* If there isn't any constraint, show that explicitly */ if (partconstraintdef == NULL || partconstraintdef[0] == '\0') printfPQExpBuffer(&tmpbuf, _("No partition constraint")); @@ -2039,27 +2148,56 @@ describeOneTableDetails(const char *schemaname, partconstraintdef); printTableAddFooter(&cont, tmpbuf.data); } - - PQclear(result); } + PQclear(result); } if (tableinfo.relkind == RELKIND_PARTITIONED_TABLE) { - /* Get the partition key information */ + /* Footer information for a partitioned table (partitioning parent) */ PGresult *result; - char *partkeydef; printfPQExpBuffer(&buf, "SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);", oid); result = PSQLexec(buf.data); - if (!result || PQntuples(result) != 1) + if (!result) + goto error_return; + + if (PQntuples(result) == 1) + { + char *partkeydef = PQgetvalue(result, 0, 0); + + printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef); + printTableAddFooter(&cont, tmpbuf.data); + } + PQclear(result); + } + + if (tableinfo.relkind == RELKIND_TOASTVALUE) + { + /* For a TOAST table, print name of owning table */ + PGresult *result; + + printfPQExpBuffer(&buf, + "SELECT n.nspname, c.relname\n" + "FROM pg_catalog.pg_class c" + " JOIN pg_catalog.pg_namespace n" + " ON n.oid = c.relnamespace\n" + "WHERE reltoastrelid = '%s';", oid); + result = PSQLexec(buf.data); + if (!result) goto error_return; - partkeydef = PQgetvalue(result, 0, 0); - printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef); - printTableAddFooter(&cont, tmpbuf.data); + if (PQntuples(result) == 1) + { + char *schemaname = PQgetvalue(result, 0, 0); + char *relname = PQgetvalue(result, 0, 1); + + printfPQExpBuffer(&tmpbuf, _("Owning table: \"%s.%s\""), + schemaname, relname); + printTableAddFooter(&cont, tmpbuf.data); + } PQclear(result); } @@ -2094,9 +2232,9 @@ describeOneTableDetails(const char *schemaname, " false AS condeferrable, false AS condeferred,\n"); if (pset.sversion >= 90400) - appendPQExpBuffer(&buf, "i.indisreplident,\n"); + appendPQExpBufferStr(&buf, "i.indisreplident,\n"); else - appendPQExpBuffer(&buf, "false AS indisreplident,\n"); + appendPQExpBufferStr(&buf, "false AS indisreplident,\n"); appendPQExpBuffer(&buf, " a.amname, c2.relname, " "pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n" @@ -2154,19 +2292,27 @@ describeOneTableDetails(const char *schemaname, appendPQExpBufferStr(&tmpbuf, _(", initially deferred")); if (strcmp(indisreplident, "t") == 0) - appendPQExpBuffer(&tmpbuf, _(", replica identity")); + appendPQExpBufferStr(&tmpbuf, _(", replica identity")); printTableAddFooter(&cont, tmpbuf.data); - add_tablespace_footer(&cont, tableinfo.relkind, - tableinfo.tablespace, true); + + /* + * If it's a partitioned index, we'll print the tablespace below + */ + if (tableinfo.relkind == RELKIND_INDEX) + add_tablespace_footer(&cont, tableinfo.relkind, + tableinfo.tablespace, true); } PQclear(result); } + /* If you add relkinds here, see also "Finish printing..." stanza below */ else if (tableinfo.relkind == RELKIND_RELATION || tableinfo.relkind == RELKIND_MATVIEW || tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) + tableinfo.relkind == RELKIND_PARTITIONED_TABLE || + tableinfo.relkind == RELKIND_PARTITIONED_INDEX || + tableinfo.relkind == RELKIND_TOASTVALUE) { /* Footer information about a table */ PGresult *result = NULL; @@ -2203,7 +2349,7 @@ describeOneTableDetails(const char *schemaname, " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n"); appendPQExpBuffer(&buf, "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" - "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;", + "ORDER BY i.indisprimary DESC, c2.relname;", oid); result = PSQLexec(buf.data); if (!result) @@ -2265,7 +2411,7 @@ describeOneTableDetails(const char *schemaname, appendPQExpBufferStr(&buf, " INVALID"); if (strcmp(PQgetvalue(result, i, 10), "t") == 0) - appendPQExpBuffer(&buf, " REPLICA IDENTITY"); + appendPQExpBufferStr(&buf, " REPLICA IDENTITY"); printTableAddFooter(&cont, buf.data); @@ -2311,15 +2457,47 @@ describeOneTableDetails(const char *schemaname, PQclear(result); } - /* print foreign-key constraints (there are none if no triggers) */ - if (tableinfo.hastriggers) + /* + * Print foreign-key constraints (there are none if no triggers, + * except if the table is partitioned, in which case the triggers + * appear in the partitions) + */ + if (tableinfo.hastriggers || + tableinfo.relkind == RELKIND_PARTITIONED_TABLE) { - printfPQExpBuffer(&buf, - "SELECT conname,\n" - " pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n" - "FROM pg_catalog.pg_constraint r\n" - "WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1;", - oid); + if (pset.sversion >= 120000 && + (tableinfo.ispartition || tableinfo.relkind == RELKIND_PARTITIONED_TABLE)) + { + /* + * Put the constraints defined in this table first, followed + * by the constraints defined in ancestor partitioned tables. + */ + printfPQExpBuffer(&buf, + "SELECT conrelid = '%s'::pg_catalog.regclass AS sametable,\n" + " conname,\n" + " pg_catalog.pg_get_constraintdef(oid, true) AS condef,\n" + " conrelid::pg_catalog.regclass AS ontable\n" + " FROM pg_catalog.pg_constraint,\n" + " pg_catalog.pg_partition_ancestors('%s')\n" + " WHERE conrelid = relid AND contype = 'f' AND conparentid = 0\n" + "ORDER BY sametable DESC, conname;", + oid, oid); + } + else + { + printfPQExpBuffer(&buf, + "SELECT true as sametable, conname,\n" + " pg_catalog.pg_get_constraintdef(r.oid, true) as condef,\n" + " conrelid::pg_catalog.regclass AS ontable\n" + "FROM pg_catalog.pg_constraint r\n" + "WHERE r.conrelid = '%s' AND r.contype = 'f'\n", + oid); + + if (pset.sversion >= 120000) + appendPQExpBufferStr(&buf, " AND conparentid = 0\n"); + appendPQExpBufferStr(&buf, "ORDER BY conname"); + } + result = PSQLexec(buf.data); if (!result) goto error_return; @@ -2328,13 +2506,28 @@ describeOneTableDetails(const char *schemaname, if (tuples > 0) { + int i_sametable = PQfnumber(result, "sametable"), + i_conname = PQfnumber(result, "conname"), + i_condef = PQfnumber(result, "condef"), + i_ontable = PQfnumber(result, "ontable"); + printTableAddFooter(&cont, _("Foreign-key constraints:")); for (i = 0; i < tuples; i++) { - /* untranslated constraint name and def */ - printfPQExpBuffer(&buf, " \"%s\" %s", - PQgetvalue(result, i, 0), - PQgetvalue(result, i, 1)); + /* + * Print untranslated constraint name and definition. Use + * a "TABLE tab" prefix when the constraint is defined in + * a parent partitioned table. + */ + if (strcmp(PQgetvalue(result, i, i_sametable), "f") == 0) + printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s", + PQgetvalue(result, i, i_ontable), + PQgetvalue(result, i, i_conname), + PQgetvalue(result, i, i_condef)); + else + printfPQExpBuffer(&buf, " \"%s\" %s", + PQgetvalue(result, i, i_conname), + PQgetvalue(result, i, i_condef)); printTableAddFooter(&cont, buf.data); } @@ -2342,15 +2535,33 @@ describeOneTableDetails(const char *schemaname, PQclear(result); } - /* print incoming foreign-key references (none if no triggers) */ - if (tableinfo.hastriggers) + /* print incoming foreign-key references */ + if (tableinfo.hastriggers || + tableinfo.relkind == RELKIND_PARTITIONED_TABLE) { - printfPQExpBuffer(&buf, - "SELECT conname, conrelid::pg_catalog.regclass,\n" - " pg_catalog.pg_get_constraintdef(c.oid, true) as condef\n" - "FROM pg_catalog.pg_constraint c\n" - "WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1;", - oid); + if (pset.sversion >= 120000) + { + printfPQExpBuffer(&buf, + "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n" + " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n" + " FROM pg_catalog.pg_constraint c\n" + " WHERE confrelid IN (SELECT pg_catalog.pg_partition_ancestors('%s')\n" + " UNION ALL VALUES ('%s'::pg_catalog.regclass))\n" + " AND contype = 'f' AND conparentid = 0\n" + "ORDER BY conname;", + oid, oid); + } + else + { + printfPQExpBuffer(&buf, + "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n" + " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n" + " FROM pg_catalog.pg_constraint\n" + " WHERE confrelid = %s AND contype = 'f'\n" + "ORDER BY conname;", + oid); + } + result = PSQLexec(buf.data); if (!result) goto error_return; @@ -2359,13 +2570,17 @@ describeOneTableDetails(const char *schemaname, if (tuples > 0) { + int i_conname = PQfnumber(result, "conname"), + i_ontable = PQfnumber(result, "ontable"), + i_condef = PQfnumber(result, "condef"); + printTableAddFooter(&cont, _("Referenced by:")); for (i = 0; i < tuples; i++) { printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s", - PQgetvalue(result, i, 1), - PQgetvalue(result, i, 0), - PQgetvalue(result, i, 2)); + PQgetvalue(result, i, i_ontable), + PQgetvalue(result, i, i_conname), + PQgetvalue(result, i, i_condef)); printTableAddFooter(&cont, buf.data); } @@ -2378,11 +2593,11 @@ describeOneTableDetails(const char *schemaname, { printfPQExpBuffer(&buf, "SELECT pol.polname,"); if (pset.sversion >= 100000) - appendPQExpBuffer(&buf, - " pol.polpermissive,\n"); + appendPQExpBufferStr(&buf, + " pol.polpermissive,\n"); else - appendPQExpBuffer(&buf, - " 't' as polpermissive,\n"); + appendPQExpBufferStr(&buf, + " 't' as polpermissive,\n"); appendPQExpBuffer(&buf, " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n" " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n" @@ -2430,7 +2645,7 @@ describeOneTableDetails(const char *schemaname, PQgetvalue(result, i, 0)); if (*(PQgetvalue(result, i, 1)) == 'f') - appendPQExpBuffer(&buf, " AS RESTRICTIVE"); + appendPQExpBufferStr(&buf, " AS RESTRICTIVE"); if (!PQgetisnull(result, i, 5)) appendPQExpBuffer(&buf, " FOR %s", @@ -2469,7 +2684,8 @@ describeOneTableDetails(const char *schemaname, " JOIN pg_catalog.pg_attribute a ON (stxrelid = a.attrelid AND\n" " a.attnum = s.attnum AND NOT attisdropped)) AS columns,\n" " 'd' = any(stxkind) AS ndist_enabled,\n" - " 'f' = any(stxkind) AS deps_enabled\n" + " 'f' = any(stxkind) AS deps_enabled,\n" + " 'm' = any(stxkind) AS mcv_enabled\n" "FROM pg_catalog.pg_statistic_ext stat " "WHERE stxrelid = '%s'\n" "ORDER BY 1;", @@ -2506,6 +2722,12 @@ describeOneTableDetails(const char *schemaname, if (strcmp(PQgetvalue(result, i, 6), "t") == 0) { appendPQExpBuffer(&buf, "%sdependencies", gotone ? ", " : ""); + gotone = true; + } + + if (strcmp(PQgetvalue(result, i, 7), "t") == 0) + { + appendPQExpBuffer(&buf, "%smcv", gotone ? ", " : ""); } appendPQExpBuffer(&buf, ") ON %s FROM %s", @@ -2649,6 +2871,25 @@ describeOneTableDetails(const char *schemaname, } } + /* Get view_def if table is a view or materialized view */ + if ((tableinfo.relkind == RELKIND_VIEW || + tableinfo.relkind == RELKIND_MATVIEW) && verbose) + { + PGresult *result; + + printfPQExpBuffer(&buf, + "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);", + oid); + result = PSQLexec(buf.data); + if (!result) + goto error_return; + + if (PQntuples(result) > 0) + view_def = pg_strdup(PQgetvalue(result, 0, 0)); + + PQclear(result); + } + if (view_def) { PGresult *result = NULL; @@ -2708,9 +2949,13 @@ describeOneTableDetails(const char *schemaname, pset.sversion >= 80300 ? "t.tgconstraint <> 0 AS tgisinternal" : "false AS tgisinternal"), oid); - if (pset.sversion >= 90000) + if (pset.sversion >= 110000) + appendPQExpBufferStr(&buf, "(NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D') \n" + " OR EXISTS (SELECT 1 FROM pg_catalog.pg_depend WHERE objid = t.oid \n" + " AND refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass))"); + else if (pset.sversion >= 90000) /* display/warn about disabled internal triggers */ - appendPQExpBuffer(&buf, "(NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D'))"); + appendPQExpBufferStr(&buf, "(NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D'))"); else if (pset.sversion >= 80300) appendPQExpBufferStr(&buf, "(t.tgconstraint = 0 OR (t.tgconstraint <> 0 AND t.tgenabled = 'D'))"); else @@ -2832,11 +3077,18 @@ describeOneTableDetails(const char *schemaname, if (tableinfo.relkind == RELKIND_RELATION || tableinfo.relkind == RELKIND_MATVIEW || tableinfo.relkind == RELKIND_FOREIGN_TABLE || - tableinfo.relkind == RELKIND_PARTITIONED_TABLE) + tableinfo.relkind == RELKIND_PARTITIONED_TABLE || + tableinfo.relkind == RELKIND_PARTITIONED_INDEX || + tableinfo.relkind == RELKIND_TOASTVALUE) { + bool is_partitioned; PGresult *result; int tuples; + /* simplify some repeated tests below */ + is_partitioned = (tableinfo.relkind == RELKIND_PARTITIONED_TABLE || + tableinfo.relkind == RELKIND_PARTITIONED_INDEX); + /* print foreign server name */ if (tableinfo.relkind == RELKIND_FOREIGN_TABLE) { @@ -2877,13 +3129,15 @@ describeOneTableDetails(const char *schemaname, PQclear(result); } - /* print inherited tables (exclude, if parent is a partitioned table) */ + /* print tables inherited from (exclude partitioned parents) */ printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass" - " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i" - " WHERE c.oid=i.inhparent AND i.inhrelid = '%s'" - " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_TABLE) - " ORDER BY inhseqno;", oid); + "SELECT c.oid::pg_catalog.regclass\n" + "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" + "WHERE c.oid = i.inhparent AND i.inhrelid = '%s'\n" + " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_TABLE) + " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_INDEX) + "\nORDER BY inhseqno;", + oid); result = PSQLexec(buf.data); if (!result) @@ -2915,31 +3169,32 @@ describeOneTableDetails(const char *schemaname, /* print child tables (with additional info if partitions) */ if (pset.sversion >= 100000) printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass," - " pg_catalog.pg_get_expr(c.relpartbound, c.oid)," - " c.relkind" - " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i" - " WHERE c.oid=i.inhrelid AND i.inhparent = '%s'" - " ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," - " c.oid::pg_catalog.regclass::pg_catalog.text;", oid); + "SELECT c.oid::pg_catalog.regclass, c.relkind," + " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n" + "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" + "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" + "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," + " c.oid::pg_catalog.regclass::pg_catalog.text;", + oid); else if (pset.sversion >= 80300) printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass" - " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i" - " WHERE c.oid=i.inhrelid AND i.inhparent = '%s'" - " ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid); + "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n" + "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" + "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" + "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", + oid); else printfPQExpBuffer(&buf, - "SELECT c.oid::pg_catalog.regclass" - " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i" - " WHERE c.oid=i.inhrelid AND i.inhparent = '%s'" - " ORDER BY c.relname;", oid); + "SELECT c.oid::pg_catalog.regclass, c.relkind, NULL\n" + "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" + "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" + "ORDER BY c.relname;", + oid); result = PSQLexec(buf.data); if (!result) goto error_return; - else - tuples = PQntuples(result); + tuples = PQntuples(result); /* * For a partitioned table with no partitions, always print the number @@ -2947,7 +3202,7 @@ describeOneTableDetails(const char *schemaname, * Otherwise, we will not print "Partitions" section for a partitioned * table without any partitions. */ - if (tableinfo.relkind == RELKIND_PARTITIONED_TABLE && tuples == 0) + if (is_partitioned && tuples == 0) { printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples); printTableAddFooter(&cont, buf.data); @@ -2957,49 +3212,34 @@ describeOneTableDetails(const char *schemaname, /* print the number of child tables, if any */ if (tuples > 0) { - if (tableinfo.relkind != RELKIND_PARTITIONED_TABLE) - printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples); - else + if (is_partitioned) printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples); + else + printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples); printTableAddFooter(&cont, buf.data); } } else { /* display the list of child tables */ - const char *ct = (tableinfo.relkind != RELKIND_PARTITIONED_TABLE) ? - _("Child tables") : _("Partitions"); + const char *ct = is_partitioned ? _("Partitions") : _("Child tables"); int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding); for (i = 0; i < tuples; i++) { - if (tableinfo.relkind != RELKIND_PARTITIONED_TABLE) - { - if (i == 0) - printfPQExpBuffer(&buf, "%s: %s", - ct, PQgetvalue(result, i, 0)); - else - printfPQExpBuffer(&buf, "%*s %s", - ctw, "", PQgetvalue(result, i, 0)); - } - else - { - char *partitioned_note; - - if (*PQgetvalue(result, i, 2) == RELKIND_PARTITIONED_TABLE) - partitioned_note = ", PARTITIONED"; - else - partitioned_note = ""; + char child_relkind = *PQgetvalue(result, i, 1); - if (i == 0) - printfPQExpBuffer(&buf, "%s: %s %s%s", - ct, PQgetvalue(result, i, 0), PQgetvalue(result, i, 1), - partitioned_note); - else - printfPQExpBuffer(&buf, "%*s %s %s%s", - ctw, "", PQgetvalue(result, i, 0), PQgetvalue(result, i, 1), - partitioned_note); - } + if (i == 0) + printfPQExpBuffer(&buf, "%s: %s", + ct, PQgetvalue(result, i, 0)); + else + printfPQExpBuffer(&buf, "%*s %s", + ctw, "", PQgetvalue(result, i, 0)); + if (!PQgetisnull(result, i, 2)) + appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 2)); + if (child_relkind == RELKIND_PARTITIONED_TABLE || + child_relkind == RELKIND_PARTITIONED_INDEX) + appendPQExpBufferStr(&buf, ", PARTITIONED"); if (i < tuples - 1) appendPQExpBufferChar(&buf, ','); @@ -3045,6 +3285,13 @@ describeOneTableDetails(const char *schemaname, /* Tablespace info */ add_tablespace_footer(&cont, tableinfo.relkind, tableinfo.tablespace, true); + + /* Access method info */ + if (verbose && tableinfo.relam != NULL && !pset.hide_tableam) + { + printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam); + printTableAddFooter(&cont, buf.data); + } } /* reloptions, if verbose */ @@ -3092,7 +3339,9 @@ add_tablespace_footer(printTableContent *const cont, char relkind, if (relkind == RELKIND_RELATION || relkind == RELKIND_MATVIEW || relkind == RELKIND_INDEX || - relkind == RELKIND_PARTITIONED_TABLE) + relkind == RELKIND_PARTITIONED_TABLE || + relkind == RELKIND_PARTITIONED_INDEX || + relkind == RELKIND_TOASTVALUE) { /* * We ignore the database default tablespace so that users not using @@ -3331,9 +3580,9 @@ listDbRoleSettings(const char *pattern, const char *pattern2) { char sverbuf[32]; - psql_error("The server (version %s) does not support per-database role settings.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support per-database role settings.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -3367,13 +3616,13 @@ listDbRoleSettings(const char *pattern, const char *pattern2) if (PQntuples(res) == 0 && !pset.quiet) { if (pattern && pattern2) - psql_error("Did not find any settings for role \"%s\" and database \"%s\".\n", - pattern, pattern2); + pg_log_error("Did not find any settings for role \"%s\" and database \"%s\".", + pattern, pattern2); else if (pattern) - psql_error("Did not find any settings for role \"%s\".\n", - pattern); + pg_log_error("Did not find any settings for role \"%s\".", + pattern); else - psql_error("Did not find any settings.\n"); + pg_log_error("Did not find any settings."); } else { @@ -3416,7 +3665,8 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys PQExpBufferData buf; PGresult *res; printQueryOpt myopt = pset.popt; - static const bool translate_columns[] = {false, false, true, false, false, false, false}; + int cols_so_far; + bool translate_columns[] = {false, false, true, false, false, false, false, false}; /* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */ if (!(showTables || showIndexes || showViews || showMatViews || showSeq || showForeign)) @@ -3452,18 +3702,43 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys gettext_noop("sequence"), gettext_noop("special"), gettext_noop("foreign table"), - gettext_noop("table"), /* partitioned table */ - gettext_noop("index"), /* partitioned index */ + gettext_noop("partitioned table"), + gettext_noop("partitioned index"), gettext_noop("Type"), gettext_noop("Owner")); + cols_so_far = 4; if (showIndexes) + { appendPQExpBuffer(&buf, - ",\n c2.relname as \"%s\"", + ",\n c2.relname as \"%s\"", gettext_noop("Table")); + cols_so_far++; + } if (verbose) { + /* + * Show whether a relation is permanent, temporary, or unlogged. Like + * describeOneTableDetails(), we consider that persistence emerged in + * v9.1, even though related concepts existed before. + */ + if (pset.sversion >= 90100) + { + appendPQExpBuffer(&buf, + ",\n CASE c.relpersistence WHEN 'p' THEN '%s' WHEN 't' THEN '%s' WHEN 'u' THEN '%s' END as \"%s\"", + gettext_noop("permanent"), + gettext_noop("temporary"), + gettext_noop("unlogged"), + gettext_noop("Persistence")); + translate_columns[cols_so_far] = true; + } + + /* + * We don't bother to count cols_so_far below here, as there's no need + * to; this might change with future additions to the output columns. + */ + /* * As of PostgreSQL 9.0, use pg_table_size() to show a more accurate * size of a table, including FSM, VM and TOAST tables. @@ -3543,10 +3818,10 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys if (PQntuples(res) == 0 && !pset.quiet) { if (pattern) - psql_error("Did not find any relation named \"%s\".\n", - pattern); + pg_log_error("Did not find any relation named \"%s\".", + pattern); else - psql_error("Did not find any relations.\n"); + pg_log_error("Did not find any relations."); } else { @@ -3563,6 +3838,219 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys return true; } +/* + * \dP + * Takes an optional regexp to select particular relations + * + * As with \d, you can specify the kinds of relations you want: + * + * t for tables + * i for indexes + * + * And there's additional flags: + * + * n to list non-leaf partitioned tables + * + * and you can mix and match these in any order. + */ +bool +listPartitionedTables(const char *reltypes, const char *pattern, bool verbose) +{ + bool showTables = strchr(reltypes, 't') != NULL; + bool showIndexes = strchr(reltypes, 'i') != NULL; + bool showNested = strchr(reltypes, 'n') != NULL; + PQExpBufferData buf; + PQExpBufferData title; + PGresult *res; + printQueryOpt myopt = pset.popt; + bool translate_columns[] = {false, false, false, false, false, false, false, false, false}; + const char *tabletitle; + bool mixed_output = false; + + /* + * Note: Declarative table partitioning is only supported as of Pg 10.0. + */ + if (pset.sversion < 100000) + { + char sverbuf[32]; + + pg_log_error("The server (version %s) does not support declarative table partitioning.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); + return true; + } + + /* If no relation kind was selected, show them all */ + if (!showTables && !showIndexes) + showTables = showIndexes = true; + + if (showIndexes && !showTables) + tabletitle = _("List of partitioned indexes"); /* \dPi */ + else if (showTables && !showIndexes) + tabletitle = _("List of partitioned tables"); /* \dPt */ + else + { + /* show all kinds */ + tabletitle = _("List of partitioned relations"); + mixed_output = true; + } + + initPQExpBuffer(&buf); + + printfPQExpBuffer(&buf, + "SELECT n.nspname as \"%s\",\n" + " c.relname as \"%s\",\n" + " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"", + gettext_noop("Schema"), + gettext_noop("Name"), + gettext_noop("Owner")); + + if (mixed_output) + { + appendPQExpBuffer(&buf, + ",\n CASE c.relkind" + " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" + " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" + " END as \"%s\"", + gettext_noop("partitioned table"), + gettext_noop("partitioned index"), + gettext_noop("Type")); + + translate_columns[3] = true; + } + + if (showNested || pattern) + appendPQExpBuffer(&buf, + ",\n inh.inhparent::regclass as \"%s\"", + gettext_noop("Parent name")); + + if (showIndexes) + appendPQExpBuffer(&buf, + ",\n c2.oid::regclass as \"%s\"", + gettext_noop("Table")); + + if (verbose) + { + if (showNested) + { + appendPQExpBuffer(&buf, + ",\n s.dps as \"%s\"", + gettext_noop("Leaf partition size")); + appendPQExpBuffer(&buf, + ",\n s.tps as \"%s\"", + gettext_noop("Total size")); + } + else + /* Sizes of all partitions are considered in this case. */ + appendPQExpBuffer(&buf, + ",\n s.tps as \"%s\"", + gettext_noop("Total size")); + + appendPQExpBuffer(&buf, + ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"", + gettext_noop("Description")); + } + + appendPQExpBufferStr(&buf, + "\nFROM pg_catalog.pg_class c" + "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace"); + + if (showIndexes) + appendPQExpBufferStr(&buf, + "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid" + "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid"); + + if (showNested || pattern) + appendPQExpBufferStr(&buf, + "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid"); + + if (verbose) + { + if (pset.sversion < 120000) + { + appendPQExpBufferStr(&buf, + ",\n LATERAL (WITH RECURSIVE d\n" + " AS (SELECT inhrelid AS oid, 1 AS level\n" + " FROM pg_catalog.pg_inherits\n" + " WHERE inhparent = c.oid\n" + " UNION ALL\n" + " SELECT inhrelid, level + 1\n" + " FROM pg_catalog.pg_inherits i\n" + " JOIN d ON i.inhparent = d.oid)\n" + " SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.pg_table_size(" + "d.oid))) AS tps,\n" + " pg_catalog.pg_size_pretty(sum(" + "\n CASE WHEN d.level = 1" + " THEN pg_catalog.pg_table_size(d.oid) ELSE 0 END)) AS dps\n" + " FROM d) s"); + } + else + { + /* PostgreSQL 12 has pg_partition_tree function */ + appendPQExpBufferStr(&buf, + ",\n LATERAL (SELECT pg_catalog.pg_size_pretty(sum(" + "\n CASE WHEN ppt.isleaf AND ppt.level = 1" + "\n THEN pg_catalog.pg_table_size(ppt.relid)" + " ELSE 0 END)) AS dps" + ",\n pg_catalog.pg_size_pretty(sum(" + "pg_catalog.pg_table_size(ppt.relid))) AS tps" + "\n FROM pg_catalog.pg_partition_tree(c.oid) ppt) s"); + } + } + + appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); + if (showTables) + appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ","); + if (showIndexes) + appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ","); + appendPQExpBufferStr(&buf, "''"); /* dummy */ + appendPQExpBufferStr(&buf, ")\n"); + + appendPQExpBufferStr(&buf, !showNested && !pattern ? + " AND NOT c.relispartition\n" : ""); + + if (!pattern) + appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" + " AND n.nspname <> 'information_schema'\n"); + + /* + * TOAST objects are suppressed unconditionally. Since we don't provide + * any way to select RELKIND_TOASTVALUE above, we would never show toast + * tables in any case; it seems a bit confusing to allow their indexes to + * be shown. Use plain \d if you really need to look at a TOAST + * table/index. + */ + appendPQExpBufferStr(&buf, " AND n.nspname !~ '^pg_toast'\n"); + + processSQLNamePattern(pset.db, &buf, pattern, true, false, + "n.nspname", "c.relname", NULL, + "pg_catalog.pg_table_is_visible(c.oid)"); + + appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";", + mixed_output ? "\"Type\" DESC, " : "", + showNested || pattern ? "\"Parent name\" NULLS FIRST, " : ""); + + res = PSQLexec(buf.data); + termPQExpBuffer(&buf); + if (!res) + return false; + + initPQExpBuffer(&title); + appendPQExpBufferStr(&title, tabletitle); + + myopt.nullPrint = NULL; + myopt.title = title.data; + myopt.translate_header = true; + myopt.translate_columns = translate_columns; + myopt.n_translate_columns = lengthof(translate_columns); + + printQuery(res, &myopt, pset.queryFout, false, pset.logfile); + + termPQExpBuffer(&title); + + PQclear(res); + return true; +} /* * \dL @@ -3836,7 +4324,7 @@ listEventTriggers(const char *pattern, bool verbose) gettext_noop("always"), gettext_noop("disabled"), gettext_noop("Enabled"), - gettext_noop("Procedure"), + gettext_noop("Function"), gettext_noop("Tags")); if (verbose) appendPQExpBuffer(&buf, @@ -3882,37 +4370,56 @@ listCasts(const char *pattern, bool verbose) initPQExpBuffer(&buf); - /* - * We need a left join to pg_proc for binary casts; the others are just - * paranoia. Also note that we don't attempt to localize '(binary - * coercible)', because there's too much risk of gettext translating a - * function name that happens to match some string in the PO database. - */ printfPQExpBuffer(&buf, "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n" - " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n" - " CASE WHEN castfunc = 0 THEN '(binary coercible)'\n" - " ELSE p.proname\n" - " END as \"%s\",\n" - " CASE WHEN c.castcontext = 'e' THEN '%s'\n" - " WHEN c.castcontext = 'a' THEN '%s'\n" - " ELSE '%s'\n" - " END as \"%s\"", + " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n", gettext_noop("Source type"), - gettext_noop("Target type"), - gettext_noop("Function"), + gettext_noop("Target type")); + + /* + * We don't attempt to localize '(binary coercible)' or '(with inout)', + * because there's too much risk of gettext translating a function name + * that happens to match some string in the PO database. + */ + if (pset.sversion >= 80400) + appendPQExpBuffer(&buf, + " CASE WHEN c.castmethod = '%c' THEN '(binary coercible)'\n" + " WHEN c.castmethod = '%c' THEN '(with inout)'\n" + " ELSE p.proname\n" + " END AS \"%s\",\n", + COERCION_METHOD_BINARY, + COERCION_METHOD_INOUT, + gettext_noop("Function")); + else + appendPQExpBuffer(&buf, + " CASE WHEN c.castfunc = 0 THEN '(binary coercible)'\n" + " ELSE p.proname\n" + " END AS \"%s\",\n", + gettext_noop("Function")); + + appendPQExpBuffer(&buf, + " CASE WHEN c.castcontext = '%c' THEN '%s'\n" + " WHEN c.castcontext = '%c' THEN '%s'\n" + " ELSE '%s'\n" + " END AS \"%s\"", + COERCION_CODE_EXPLICIT, gettext_noop("no"), + COERCION_CODE_ASSIGNMENT, gettext_noop("in assignment"), gettext_noop("yes"), gettext_noop("Implicit?")); if (verbose) appendPQExpBuffer(&buf, - ",\n d.description AS \"%s\"\n", + ",\n d.description AS \"%s\"", gettext_noop("Description")); + /* + * We need a left join to pg_proc for binary casts; the others are just + * paranoia. + */ appendPQExpBufferStr(&buf, - "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n" + "\nFROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n" " ON c.castfunc = p.oid\n" " LEFT JOIN pg_catalog.pg_type ts\n" " ON c.castsource = ts.oid\n" @@ -3977,15 +4484,15 @@ listCollations(const char *pattern, bool verbose, bool showSystem) PQExpBufferData buf; PGresult *res; printQueryOpt myopt = pset.popt; - static const bool translate_columns[] = {false, false, false, false, false, false}; + static const bool translate_columns[] = {false, false, false, false, false, true, false}; if (pset.sversion < 90100) { char sverbuf[32]; - psql_error("The server (version %s) does not support collations.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support collations.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4005,6 +4512,21 @@ listCollations(const char *pattern, bool verbose, bool showSystem) appendPQExpBuffer(&buf, ",\n CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\"", gettext_noop("Provider")); + else + appendPQExpBuffer(&buf, + ",\n 'libc' AS \"%s\"", + gettext_noop("Provider")); + + if (pset.sversion >= 120000) + appendPQExpBuffer(&buf, + ",\n CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \"%s\"", + gettext_noop("yes"), gettext_noop("no"), + gettext_noop("Deterministic?")); + else + appendPQExpBuffer(&buf, + ",\n '%s' AS \"%s\"", + gettext_noop("yes"), + gettext_noop("Deterministic?")); if (verbose) appendPQExpBuffer(&buf, @@ -4078,8 +4600,8 @@ listSchemas(const char *pattern, bool verbose, bool showSystem) gettext_noop("Description")); } - appendPQExpBuffer(&buf, - "\nFROM pg_catalog.pg_namespace n\n"); + appendPQExpBufferStr(&buf, + "\nFROM pg_catalog.pg_namespace n\n"); if (!showSystem && !pattern) appendPQExpBufferStr(&buf, @@ -4123,9 +4645,9 @@ listTSParsers(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support full text search.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support full text search.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4203,10 +4725,10 @@ listTSParsersVerbose(const char *pattern) if (!pset.quiet) { if (pattern) - psql_error("Did not find any text search parser named \"%s\".\n", - pattern); + pg_log_error("Did not find any text search parser named \"%s\".", + pattern); else - psql_error("Did not find any text search parsers.\n"); + pg_log_error("Did not find any text search parsers."); } PQclear(res); return false; @@ -4370,9 +4892,9 @@ listTSDictionaries(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support full text search.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support full text search.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4441,9 +4963,9 @@ listTSTemplates(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support full text search.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support full text search.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4512,9 +5034,9 @@ listTSConfigs(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support full text search.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support full text search.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4593,10 +5115,10 @@ listTSConfigsVerbose(const char *pattern) if (!pset.quiet) { if (pattern) - psql_error("Did not find any text search configuration named \"%s\".\n", - pattern); + pg_log_error("Did not find any text search configuration named \"%s\".", + pattern); else - psql_error("Did not find any text search configurations.\n"); + pg_log_error("Did not find any text search configurations."); } PQclear(res); return false; @@ -4718,9 +5240,9 @@ listForeignDataWrappers(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support foreign-data wrappers.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support foreign-data wrappers.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4801,9 +5323,9 @@ listForeignServers(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support foreign servers.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support foreign servers.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4883,9 +5405,9 @@ listUserMappings(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support user mappings.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support user mappings.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -4944,9 +5466,9 @@ listForeignTables(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support foreign tables.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support foreign tables.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -5022,9 +5544,9 @@ listExtensions(const char *pattern) { char sverbuf[32]; - psql_error("The server (version %s) does not support extensions.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support extensions.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -5079,9 +5601,9 @@ listExtensionContents(const char *pattern) { char sverbuf[32]; - psql_error("The server (version %s) does not support extensions.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support extensions.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -5107,10 +5629,10 @@ listExtensionContents(const char *pattern) if (!pset.quiet) { if (pattern) - psql_error("Did not find any extension named \"%s\".\n", - pattern); + pg_log_error("Did not find any extension named \"%s\".", + pattern); else - psql_error("Did not find any extensions.\n"); + pg_log_error("Did not find any extensions."); } PQclear(res); return false; @@ -5193,9 +5715,9 @@ listPublications(const char *pattern) { char sverbuf[32]; - psql_error("The server (version %s) does not support publications.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support publications.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -5264,9 +5786,9 @@ describePublications(const char *pattern) { char sverbuf[32]; - psql_error("The server (version %s) does not support publications.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support publications.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } @@ -5279,10 +5801,10 @@ describePublications(const char *pattern) " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n" " puballtables, pubinsert, pubupdate, pubdelete"); if (has_pubtruncate) - appendPQExpBuffer(&buf, - ", pubtruncate"); - appendPQExpBuffer(&buf, - "\nFROM pg_catalog.pg_publication\n"); + appendPQExpBufferStr(&buf, + ", pubtruncate"); + appendPQExpBufferStr(&buf, + "\nFROM pg_catalog.pg_publication\n"); processSQLNamePattern(pset.db, &buf, pattern, false, false, NULL, "pubname", NULL, @@ -5302,10 +5824,10 @@ describePublications(const char *pattern) if (!pset.quiet) { if (pattern) - psql_error("Did not find any publication named \"%s\".\n", - pattern); + pg_log_error("Did not find any publication named \"%s\".", + pattern); else - psql_error("Did not find any publications.\n"); + pg_log_error("Did not find any publications."); } termPQExpBuffer(&buf); @@ -5420,9 +5942,9 @@ describeSubscriptions(const char *pattern, bool verbose) { char sverbuf[32]; - psql_error("The server (version %s) does not support subscriptions.\n", - formatPGVersionNumber(pset.sversion, false, - sverbuf, sizeof(sverbuf))); + pg_log_error("The server (version %s) does not support subscriptions.", + formatPGVersionNumber(pset.sversion, false, + sverbuf, sizeof(sverbuf))); return true; } diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h index a4cc5efae0c..b50c7d209ca 100644 --- a/src/bin/psql/describe.h +++ b/src/bin/psql/describe.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/describe.h */ @@ -31,7 +31,7 @@ extern bool describeOperators(const char *pattern, bool verbose, bool showSystem extern bool describeRoles(const char *pattern, bool verbose, bool showSystem); /* \drds */ -extern bool listDbRoleSettings(const char *pattern1, const char *pattern2); +extern bool listDbRoleSettings(const char *pattern, const char *pattern2); /* \z (or \dp) */ extern bool permissionsList(const char *pattern); @@ -63,6 +63,9 @@ extern bool listAllDbs(const char *pattern, bool verbose); /* \dt, \di, \ds, \dS, etc. */ extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem); +/* \dP */ +extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose); + /* \dD */ extern bool listDomains(const char *pattern, bool verbose, bool showSystem); diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 702e742af4f..59ea8cc16e3 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/help.c */ @@ -21,14 +21,15 @@ #include #endif -#include "common.h" +#include "common/logging.h" #include "common/username.h" + +#include "common.h" #include "help.h" #include "input.h" #include "settings.h" #include "sql_help.h" - /* * PLEASE: * If you change something in this file, also make the same changes @@ -59,7 +60,7 @@ usage(unsigned short int pager) user = get_user_name(&errstr); if (!user) { - psql_error("%s\n", errstr); + pg_log_fatal("%s", errstr); exit(EXIT_FAILURE); } } @@ -68,7 +69,7 @@ usage(unsigned short int pager) * Keep this line count in sync with the number of lines printed below! * Use "psql --help=options | wc" to count correctly. */ - output = PageOutput(61, pager ? &(pset.popt.topt) : NULL); + output = PageOutput(62, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n")); fprintf(output, _("Usage:\n")); @@ -108,6 +109,7 @@ usage(unsigned short int pager) fprintf(output, _("\nOutput format options:\n")); fprintf(output, _(" -A, --no-align unaligned table output mode\n")); + fprintf(output, _(" --csv CSV (Comma-Separated Values) table output mode\n")); fprintf(output, _(" -F, --field-separator=STRING\n" " field separator for unaligned output (default: \"%s\")\n"), DEFAULT_FIELD_SEP); @@ -143,7 +145,7 @@ usage(unsigned short int pager) fprintf(output, _("\nFor more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" "commands) from within psql, or consult the psql section in the PostgreSQL\n" "documentation.\n\n")); - fprintf(output, _("Report bugs to .\n")); + fprintf(output, _("Report bugs to .\n")); ClosePager(output); } @@ -167,7 +169,7 @@ slashUsage(unsigned short int pager) * Use "psql --help=commands | wc" to count correctly. It's okay to count * the USE_READLINE line even in builds without that. */ - output = PageOutput(125, pager ? &(pset.popt.topt) : NULL); + output = PageOutput(128, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("General\n")); fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n")); @@ -204,11 +206,12 @@ slashUsage(unsigned short int pager) fprintf(output, _("Input/Output\n")); fprintf(output, _(" \\copy ... perform SQL COPY with data stream to the client host\n")); - fprintf(output, _(" \\echo [STRING] write string to standard output\n")); + fprintf(output, _(" \\echo [-n] [STRING] write string to standard output (-n for no newline)\n")); fprintf(output, _(" \\i FILE execute commands from file\n")); fprintf(output, _(" \\ir FILE as \\i, but relative to location of current script\n")); fprintf(output, _(" \\o [FILE] send all query results to file or |pipe\n")); - fprintf(output, _(" \\qecho [STRING] write string to query output stream (see \\o)\n")); + fprintf(output, _(" \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n")); + fprintf(output, _(" \\warn [-n] [STRING] write string to standard error (-n for no newline)\n")); fprintf(output, "\n"); fprintf(output, _("Conditional\n")); @@ -235,7 +238,7 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\des[+] [PATTERN] list foreign servers\n")); fprintf(output, _(" \\deu[+] [PATTERN] list user mappings\n")); fprintf(output, _(" \\dew[+] [PATTERN] list foreign-data wrappers\n")); - fprintf(output, _(" \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n")); + fprintf(output, _(" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n")); fprintf(output, _(" \\dF[+] [PATTERN] list text search configurations\n")); fprintf(output, _(" \\dFd[+] [PATTERN] list text search dictionaries\n")); fprintf(output, _(" \\dFp[+] [PATTERN] list text search parsers\n")); @@ -249,6 +252,7 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\do[S] [PATTERN] list operators\n")); fprintf(output, _(" \\dO[S+] [PATTERN] list collations\n")); fprintf(output, _(" \\dp [PATTERN] list table, view, and sequence access privileges\n")); + fprintf(output, _(" \\dP[itn+] [PATTERN] list [only index/table] partitioned relations [n=nested]\n")); fprintf(output, _(" \\drds [PATRN1 [PATRN2]] list per-database role settings\n")); fprintf(output, _(" \\dRp[+] [PATTERN] list replication publications\n")); fprintf(output, _(" \\dRs[+] [PATTERN] list replication subscriptions\n")); @@ -272,11 +276,12 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\H toggle HTML output mode (currently %s)\n"), ON(pset.popt.topt.format == PRINT_HTML)); fprintf(output, _(" \\pset [NAME [VALUE]] set table output option\n" - " (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" - " footer|format|linestyle|null|numericlocale|pager|\n" - " pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" - " tuples_only|unicode_border_linestyle|\n" - " unicode_column_linestyle|unicode_header_linestyle})\n")); + " (border|columns|csv_fieldsep|expanded|fieldsep|\n" + " fieldsep_zero|footer|format|linestyle|null|\n" + " numericlocale|pager|pager_min_lines|recordsep|\n" + " recordsep_zero|tableattr|title|tuples_only|\n" + " unicode_border_linestyle|unicode_column_linestyle|\n" + " unicode_header_linestyle)\n")); fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"), ON(pset.popt.topt.tuples_only)); fprintf(output, _(" \\T [STRING] set HTML
tag attributes, or unset if none\n")); @@ -337,7 +342,7 @@ helpVariables(unsigned short int pager) * Windows builds currently print one more line than non-Windows builds. * Using the larger number is fine. */ - output = PageOutput(156, pager ? &(pset.popt.topt) : NULL); + output = PageOutput(158, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("List of specially treated variables\n\n")); @@ -364,12 +369,14 @@ helpVariables(unsigned short int pager) " true if last query failed, else false\n")); fprintf(output, _(" FETCH_COUNT\n" " the number of result rows to fetch and display at a time (0 = unlimited)\n")); + fprintf(output, _(" HIDE_TABLEAM\n" + " if set, table access methods are not displayed\n")); fprintf(output, _(" HISTCONTROL\n" " controls command history [ignorespace, ignoredups, ignoreboth]\n")); fprintf(output, _(" HISTFILE\n" " file name used to store the command history\n")); fprintf(output, _(" HISTSIZE\n" - " max number of commands to store in the command history\n")); + " maximum number of commands to store in the command history\n")); fprintf(output, _(" HOST\n" " the currently connected database server host\n")); fprintf(output, _(" IGNOREEOF\n" @@ -409,7 +416,7 @@ helpVariables(unsigned short int pager) fprintf(output, _(" USER\n" " the currently connected database user\n")); fprintf(output, _(" VERBOSITY\n" - " controls verbosity of error reports [default, verbose, terse]\n")); + " controls verbosity of error reports [default, verbose, terse, sqlstate]\n")); fprintf(output, _(" VERSION\n" " VERSION_NAME\n" " VERSION_NUM\n" @@ -619,16 +626,23 @@ helpSQL(const char *topic, unsigned short int pager) strcmp(topic, "*") == 0) { PQExpBufferData buffer; + char *url; initPQExpBuffer(&buffer); QL_HELP[i].syntaxfunc(&buffer); help_found = true; + url = psprintf("https://www.postgresql.org/docs/%s/%s.html", + strstr(PG_VERSION, "devel") ? "devel" : PG_MAJORVERSION, + QL_HELP[i].docbook_id); fprintf(output, _("Command: %s\n" "Description: %s\n" - "Syntax:\n%s\n\n"), + "Syntax:\n%s\n\n" + "URL: %s\n\n"), QL_HELP[i].cmd, _(QL_HELP[i].help), - buffer.data); + buffer.data, + url); + free(url); /* If we have an exact match, exit. Fixes \h SELECT */ if (pg_strcasecmp(topic, QL_HELP[i].cmd) == 0) break; @@ -653,7 +667,7 @@ print_copyright(void) puts( "PostgreSQL Database Management System\n" "(formerly known as Postgres, then as Postgres95)\n\n" - "Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group\n\n" + "Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group\n\n" "Portions Copyright (c) 1994, The Regents of the University of California\n\n" "Permission to use, copy, modify, and distribute this software and its\n" "documentation for any purpose, without fee, and without a written agreement\n" diff --git a/src/bin/psql/help.h b/src/bin/psql/help.h index 7a292497e75..e588989176e 100644 --- a/src/bin/psql/help.h +++ b/src/bin/psql/help.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/help.h */ diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index 8e32cd0b330..5a18ac9bbc4 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/input.c */ @@ -18,6 +18,8 @@ #include "tab-complete.h" #include "common.h" +#include "common/logging.h" + #ifndef WIN32 #define PSQLHISTORY ".psql_history" #else @@ -213,8 +215,7 @@ gets_fromFile(FILE *source) { if (ferror(source)) { - psql_error("could not read from input file: %s\n", - strerror(errno)); + pg_log_error("could not read from input file: %m"); return NULL; } break; @@ -224,7 +225,7 @@ gets_fromFile(FILE *source) if (PQExpBufferBroken(buffer)) { - psql_error("out of memory\n"); + pg_log_error("out of memory"); return NULL; } @@ -468,8 +469,7 @@ saveHistory(char *fname, int max_lines) } #endif - psql_error("could not save history to file \"%s\": %s\n", - fname, strerror(errnum)); + pg_log_error("could not save history to file \"%s\": %m", fname); } return false; } @@ -507,8 +507,7 @@ printHistory(const char *fname, unsigned short int pager) output = fopen(fname, "w"); if (output == NULL) { - psql_error("could not save history to file \"%s\": %s\n", - fname, strerror(errno)); + pg_log_error("could not save history to file \"%s\": %m", fname); return false; } is_pager = false; @@ -527,7 +526,7 @@ printHistory(const char *fname, unsigned short int pager) return true; #else - psql_error("history is not supported by this installation\n"); + pg_log_error("history is not supported by this installation"); return false; #endif } diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h index 6c2ff615403..375b23bda74 100644 --- a/src/bin/psql/input.h +++ b/src/bin/psql/input.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/input.h */ diff --git a/src/bin/psql/large_obj.c b/src/bin/psql/large_obj.c index 7faf5591b3e..2713f15d4f3 100644 --- a/src/bin/psql/large_obj.c +++ b/src/bin/psql/large_obj.c @@ -1,17 +1,18 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/large_obj.c */ #include "postgres_fe.h" #include "large_obj.h" - #include "settings.h" #include "common.h" +#include "common/logging.h" + static void print_lo_result(const char *fmt,...) pg_attribute_printf(1, 2); static void @@ -61,7 +62,7 @@ start_lo_xact(const char *operation, bool *own_transaction) if (!pset.db) { - psql_error("%s: not connected to a database\n", operation); + pg_log_error("%s: not connected to a database", operation); return false; } @@ -80,10 +81,10 @@ start_lo_xact(const char *operation, bool *own_transaction) /* use the existing xact */ break; case PQTRANS_INERROR: - psql_error("%s: current transaction is aborted\n", operation); + pg_log_error("%s: current transaction is aborted", operation); return false; default: - psql_error("%s: unknown transaction status\n", operation); + pg_log_error("%s: unknown transaction status", operation); return false; } @@ -153,7 +154,7 @@ do_lo_export(const char *loid_arg, const char *filename_arg) /* of course this status is documented nowhere :( */ if (status != 1) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); return fail_lo_xact("\\lo_export", own_transaction); } @@ -188,7 +189,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg) if (loid == InvalidOid) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); return fail_lo_xact("\\lo_import", own_transaction); } @@ -199,7 +200,7 @@ do_lo_import(const char *filename_arg, const char *comment_arg) char *bufptr; size_t slen = strlen(comment_arg); - cmdbuf = malloc(slen * 2 + 256); + cmdbuf = pg_malloc_extended(slen * 2 + 256, MCXT_ALLOC_NO_OOM); if (!cmdbuf) return fail_lo_xact("\\lo_import", own_transaction); sprintf(cmdbuf, "COMMENT ON LARGE OBJECT %u IS '", loid); @@ -250,7 +251,7 @@ do_lo_unlink(const char *loid_arg) if (status == -1) { - psql_error("%s", PQerrorMessage(pset.db)); + pg_log_info("%s", PQerrorMessage(pset.db)); return fail_lo_xact("\\lo_unlink", own_transaction); } diff --git a/src/bin/psql/large_obj.h b/src/bin/psql/large_obj.h index e749a824c55..c7f46eb1e22 100644 --- a/src/bin/psql/large_obj.h +++ b/src/bin/psql/large_obj.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/large_obj.h */ diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c index c06ce3ca09c..e386d9888d7 100644 --- a/src/bin/psql/mainloop.c +++ b/src/bin/psql/mainloop.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/mainloop.c */ @@ -14,13 +14,13 @@ #include "prompt.h" #include "settings.h" +#include "common/logging.h" #include "mb/pg_wchar.h" /* callback functions for our flex lexer */ const PsqlScanCallbacks psqlscan_callbacks = { psql_get_variable, - psql_error }; @@ -79,7 +79,7 @@ MainLoop(FILE *source) PQExpBufferBroken(previous_buf) || PQExpBufferBroken(history_buf)) { - psql_error("out of memory\n"); + pg_log_error("out of memory"); exit(EXIT_FAILURE); } @@ -133,7 +133,7 @@ MainLoop(FILE *source) */ if (!conditional_stack_empty(cond_stack)) { - psql_error("\\if: escaped\n"); + pg_log_error("\\if: escaped"); conditional_stack_pop(cond_stack); } } @@ -247,9 +247,8 @@ MainLoop(FILE *source) /* * If we found a command word, check whether the rest of the line * contains only whitespace plus maybe one semicolon. If not, - * ignore the command word after all. These commands are only - * for compatibility with other SQL clients and are not - * documented. + * ignore the command word after all. These commands are only for + * compatibility with other SQL clients and are not documented. */ if (rest_of_line != NULL) { @@ -330,18 +329,17 @@ MainLoop(FILE *source) } /* - * If they typed "\q" in a place where "\q" is not active, - * supply a hint. The text is still added to the query - * buffer. + * If they typed "\q" in a place where "\q" is not active, supply + * a hint. The text is still added to the query buffer. */ if (found_q && query_buf->len != 0 && prompt_status != PROMPT_READY && prompt_status != PROMPT_CONTINUE && prompt_status != PROMPT_PAREN) #ifndef WIN32 - puts(_("Use control-D to quit.")); + puts(_("Use control-D to quit.")); #else - puts(_("Use control-C to quit.")); + puts(_("Use control-C to quit.")); #endif } @@ -385,7 +383,7 @@ MainLoop(FILE *source) if (PQExpBufferBroken(query_buf)) { - psql_error("out of memory\n"); + pg_log_error("out of memory"); exit(EXIT_FAILURE); } @@ -448,7 +446,7 @@ MainLoop(FILE *source) { /* if interactive, warn about non-executed query */ if (pset.cur_cmd_interactive) - psql_error("query ignored; use \\endif or Ctrl-C to exit current \\if block\n"); + pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block"); /* fake an OK result for purposes of loop checks */ success = true; slashCmdStatus = PSQL_CMD_SEND; @@ -590,7 +588,7 @@ MainLoop(FILE *source) else { if (pset.cur_cmd_interactive) - psql_error("query ignored; use \\endif or Ctrl-C to exit current \\if block\n"); + pg_log_error("query ignored; use \\endif or Ctrl-C to exit current \\if block"); success = true; } @@ -608,7 +606,7 @@ MainLoop(FILE *source) successResult != EXIT_USER && !conditional_stack_empty(cond_stack)) { - psql_error("reached EOF without finding closing \\endif(s)\n"); + pg_log_error("reached EOF without finding closing \\endif(s)"); if (die_on_error && !pset.cur_cmd_interactive) successResult = EXIT_USER; } diff --git a/src/bin/psql/mainloop.h b/src/bin/psql/mainloop.h index 6cd90f03b81..9e88c86286e 100644 --- a/src/bin/psql/mainloop.h +++ b/src/bin/psql/mainloop.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/mainloop.h */ diff --git a/src/bin/psql/nls.mk b/src/bin/psql/nls.mk index e355f219b98..d5eecc45aab 100644 --- a/src/bin/psql/nls.mk +++ b/src/bin/psql/nls.mk @@ -1,12 +1,14 @@ # src/bin/psql/nls.mk CATALOG_NAME = psql -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv zh_CN zh_TW -GETTEXT_FILES = command.c common.c copy.c crosstabview.c help.c input.c large_obj.c \ +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN zh_TW +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ + command.c common.c copy.c crosstabview.c help.c input.c large_obj.c \ mainloop.c psqlscanslash.c startup.c \ describe.c sql_help.h sql_help.c \ tab-complete.c variables.c \ ../../fe_utils/print.c ../../fe_utils/psqlscan.c \ ../../common/exec.c ../../common/fe_memutils.c ../../common/username.c \ ../../common/wait_error.c -GETTEXT_TRIGGERS = N_ psql_error simple_prompt write_error -GETTEXT_FLAGS = psql_error:1:c-format write_error:1:c-format +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \ + N_ simple_prompt +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/psql/po/cs.po b/src/bin/psql/po/cs.po index a378251c1df..6700e96e4bc 100644 --- a/src/bin/psql/po/cs.po +++ b/src/bin/psql/po/cs.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: psql-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-09-23 20:17+0000\n" -"PO-Revision-Date: 2013-09-24 21:01+0200\n" +"POT-Creation-Date: 2018-07-13 19:45+0000\n" +"PO-Revision-Date: 2018-07-13 23:54+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -17,121 +17,177 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" -#: ../../common/fe_memutils.c:33 ../../common/fe_memutils.c:60 -#: ../../common/fe_memutils.c:83 command.c:1130 input.c:204 mainloop.c:72 -#: mainloop.c:234 tab-complete.c:3827 -#, c-format -msgid "out of memory\n" -msgstr "nedostatek pamÄ›ti\n" - -#: ../../common/fe_memutils.c:77 -#, c-format -msgid "cannot duplicate null pointer (internal error)\n" -msgstr "nelze duplikovat null pointer (interní chyba)\n" - -#: ../../port/exec.c:127 ../../port/exec.c:241 ../../port/exec.c:284 +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" msgstr "nelze získat aktuální adresář: %s" -#: ../../port/exec.c:146 +#: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" msgstr "neplatný binární soubor\"%s\"" -#: ../../port/exec.c:195 +#: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" msgstr "nelze Äíst binární soubor \"%s\"" -#: ../../port/exec.c:202 +#: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" -msgstr "nelze najít spustitelný soubor \"%s\"" +msgstr "nelze najít příkaz \"%s\" ke spuÅ¡tÄ›ní" -#: ../../port/exec.c:257 ../../port/exec.c:293 +#: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" msgstr "nelze zmÄ›nit adresář na \"%s\" : %s" -#: ../../port/exec.c:272 +#: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" msgstr "nelze Äíst symbolický link \"%s\"" -#: ../../port/exec.c:523 +#: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "volání pclose selhalo: %s" -#: ../../port/wait_error.c:47 +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 command.c:607 input.c:227 mainloop.c:82 +#: mainloop.c:386 +#, c-format +msgid "out of memory\n" +msgstr "nedostatek pamÄ›ti\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "nelze duplikovat null pointer (interní chyba)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "nelze naÄíst efektivní user ID \"%ld\": %s" + +#: ../../common/username.c:45 command.c:554 +msgid "user does not exist" +msgstr "uživatel neexistuje" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "vyhledávání uživatele selhalo: chybový kód %lu" + +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "příkaz není spustitelný" -#: ../../port/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "příkaz nenalezen" -#: ../../port/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "potomek skonÄil s návratovým kódem %d" -#: ../../port/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "potomek byl ukonÄen výjimkou 0x%X" -#: ../../port/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "potomek byl ukonÄen signálem %s" -#: ../../port/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "potomek byl ukonÄen signálem %d" -#: ../../port/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "potomek skonÄil s nerozponaným stavem %d" -#: command.c:115 +#: ../../fe_utils/print.c:353 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu řádka)" +msgstr[1] "(%lu řádky)" +msgstr[2] "(%lu řádek)" + +#: ../../fe_utils/print.c:2915 +#, c-format +msgid "Interrupted\n" +msgstr "PÅ™eruÅ¡eno\n" + +#: ../../fe_utils/print.c:2979 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Nelze pÅ™idat hlaviÄku k obsahu tabulky: pÅ™ekroÄen poÄet sloupců %d.\n" + +#: ../../fe_utils/print.c:3019 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "" +"Nelze pÅ™idat buňku do obsahu tabulky: pÅ™ekroÄen celkový poÄet bunÄ›k %d.\n" + +#: ../../fe_utils/print.c:3268 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "specifikován neplatný formát výstupu (interní chyba): %d" + +#: ../../fe_utils/psqlscan.l:715 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"\n" +msgstr "pÅ™eskakuji rekursivní expanzi promÄ›nné \"%s\"\n" + +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "Neplatný příkaz \\%s. Použijte \\? pro nápovÄ›du.\n" -#: command.c:117 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" msgstr "neplatný příkaz \\%s\n" -#: command.c:128 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s: nadbyteÄný argument \"%s\" ignorován\n" -#: command.c:270 +#: command.c:292 +#, c-format +msgid "" +"\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "" +"\\%s příkaz ignorová; použijte \\endif nebo Ctrl-C pro ukonÄení aktuálního " +"\\if bloku\n" + +#: command.c:552 #, c-format -msgid "could not get home directory: %s\n" -msgstr "nelze získat domácí adresář: %s\n" +msgid "could not get home directory for user ID %ld: %s\n" +msgstr "nelze získat domácí adresář pro uživatele ID %ld: %s\n" -#: command.c:286 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s: nelze zmÄ›nit adresář na \"%s\": %s\n" -#: command.c:307 common.c:446 common.c:851 +#: command.c:595 common.c:696 common.c:754 common.c:1292 #, c-format msgid "You are currently not connected to a database.\n" msgstr "AktuálnÄ› nejste pÅ™ipojeni k databázi.\n" -#: command.c:314 +#: command.c:620 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " @@ -140,7 +196,7 @@ msgstr "" "Jste pÅ™ipojeni k databázi \"%s\" jako uživatel \"%s\" pÅ™es socket v \"%s\" " "naportu \"%s\".\n" -#: command.c:317 +#: command.c:623 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " @@ -149,118 +205,165 @@ msgstr "" "Nyní jste pÅ™ipojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" " "na portu\"%s\".\n" -#: command.c:516 command.c:586 command.c:1382 +#: command.c:914 command.c:1010 command.c:2395 #, c-format msgid "no query buffer\n" msgstr "v historii není žádný dotaz\n" -#: command.c:549 command.c:2826 +#: command.c:947 command.c:4667 #, c-format msgid "invalid line number: %s\n" msgstr "neplatné Äíslo řádky: %s\n" -#: command.c:580 +#: command.c:1001 +#, c-format +msgid "The server (version %s) does not support editing function source.\n" +msgstr "Server (verze %s) nepodporuje editaci zdrojového kódu funkce.\n" + +#: command.c:1004 #, c-format -msgid "The server (version %d.%d) does not support editing function source.\n" -msgstr "Server (verze %d.%d) nepodporuje editaci zdrojového kódu funkce.\n" +msgid "The server (version %s) does not support editing view definitions.\n" +msgstr "Server (verze %s) nepodporuje editaci definice pohledu.\n" -#: command.c:660 +#: command.c:1086 msgid "No changes" msgstr "Žádné zmÄ›ny" -#: command.c:714 +#: command.c:1163 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "%s: neplatné jméno kódování nebo nenalezena konverzní funkce\n" -#: command.c:810 command.c:860 command.c:874 command.c:891 command.c:998 -#: command.c:1048 command.c:1158 command.c:1362 command.c:1393 +#: command.c:1198 command.c:1837 command.c:3052 command.c:4769 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1202 +msgid "out of memory" +msgstr "nedostatek pamÄ›ti" + +#: command.c:1205 +msgid "There is no previous error." +msgstr "Žádná pÅ™edchozí chyba." + +#: command.c:1393 command.c:1698 command.c:1712 command.c:1729 command.c:1889 +#: command.c:2126 command.c:2362 command.c:2402 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s: chybí požadovaný argument\n" -#: command.c:923 +#: command.c:1524 +#, c-format +msgid "\\elif: cannot occur after \\else\n" +msgstr "\\elif: nemůže být zadáno po \\else\n" + +#: command.c:1529 +#, c-format +msgid "\\elif: no matching \\if\n" +msgstr "\\elif: žádné odpovídající \\if\n" + +#: command.c:1593 +#, c-format +msgid "\\else: cannot occur after \\else\n" +msgstr "\\else: nemůže být zadáno po \\else\n" + +#: command.c:1598 +#, c-format +msgid "\\else: no matching \\if\n" +msgstr "\\else: žádné odpovídající \\if\n" + +#: command.c:1638 +#, c-format +msgid "\\endif: no matching \\if\n" +msgstr "\\endif: žádné odpovídající \\if\n" + +#: command.c:1793 msgid "Query buffer is empty." msgstr "Buffer dotazů je prázdný." -#: command.c:933 +#: command.c:1815 msgid "Enter new password: " msgstr "Zadejte nové heslo: " -#: command.c:934 +#: command.c:1816 msgid "Enter it again: " msgstr "Zadejte znova: " -#: command.c:938 +#: command.c:1820 #, c-format msgid "Passwords didn't match.\n" msgstr "Hesla se neshodují.\n" -#: command.c:956 -#, c-format -msgid "Password encryption failed.\n" -msgstr "ZaÅ¡ifrování hesla selhalo.\n" - -#: command.c:1027 command.c:1139 command.c:1367 +#: command.c:1919 #, c-format -msgid "\\%s: error while setting variable\n" -msgstr "\\%s: chyba pÅ™i nastavování promÄ›nné\n" +msgid "\\%s: could not read value for variable\n" +msgstr "\\%s: nelze naÄíst hodnotu promÄ›nné\n" -#: command.c:1068 +#: command.c:2022 msgid "Query buffer reset (cleared)." msgstr "Buffer dotazů vyprázdnÄ›n." -#: command.c:1092 +#: command.c:2044 #, c-format -msgid "Wrote history to file \"%s/%s\".\n" -msgstr "Historie zapsána do souboru: \"%s/%s\".\n" +msgid "Wrote history to file \"%s\".\n" +msgstr "Historie zapsána do souboru: \"%s\".\n" -#: command.c:1163 +#: command.c:2131 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s: název promÄ›nné prostÅ™edí nesmí obsahovat '='\n" -#: command.c:1206 +#: command.c:2192 #, c-format -msgid "The server (version %d.%d) does not support showing function source.\n" -msgstr "Server (verze %d.%d) nepodporuje zobrazování zdrojového kódu funkce.\n" +msgid "The server (version %s) does not support showing function source.\n" +msgstr "Server (verze %s) nepodporuje zobrazování zdrojového kódu funkce.\n" -#: command.c:1212 +#: command.c:2195 +#, c-format +msgid "The server (version %s) does not support showing view definitions.\n" +msgstr "Server (verze %s) nepodporuje zobrazování definice pohledu.\n" + +#: command.c:2202 #, c-format msgid "function name is required\n" msgstr "je vyžadováno jméno funkce\n" -#: command.c:1347 +#: command.c:2204 +#, c-format +msgid "view name is required\n" +msgstr "je vyžadováno jméno pohledu\n" + +#: command.c:2334 msgid "Timing is on." msgstr "Sledování Äasu je zapnuto." -#: command.c:1349 +#: command.c:2336 msgid "Timing is off." msgstr "Sledování Äasu je vypnuto." -#: command.c:1410 command.c:1430 command.c:2027 command.c:2034 command.c:2043 -#: command.c:2053 command.c:2062 command.c:2076 command.c:2093 command.c:2152 -#: common.c:74 copy.c:342 copy.c:395 copy.c:410 psqlscan.l:1674 -#: psqlscan.l:1685 psqlscan.l:1695 +#: command.c:2421 command.c:2449 command.c:3420 command.c:3423 command.c:3426 +#: command.c:3432 command.c:3434 command.c:3442 command.c:3452 command.c:3461 +#: command.c:3475 command.c:3492 command.c:3550 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:1509 -#, c-format -msgid "+ opt(%d) = |%s|\n" -msgstr "+ opt(%d) = |%s|\n" - -#: command.c:1535 startup.c:185 +#: command.c:2833 startup.c:214 startup.c:265 msgid "Password: " msgstr "Heslo: " -#: command.c:1542 startup.c:188 startup.c:190 +#: command.c:2838 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "Heslo pro uživatele %s: " -#: command.c:1587 +#: command.c:2888 #, c-format msgid "" "All connection parameters must be supplied because no database connection " @@ -269,24 +372,17 @@ msgstr "" "VÅ¡echny parametry musí být zadány protože žádné pÅ™ipojení k databázi " "neexistuje\n" -#: command.c:1673 command.c:2860 common.c:120 common.c:413 common.c:478 -#: common.c:894 common.c:919 common.c:1016 copy.c:504 copy.c:691 -#: large_obj.c:158 large_obj.c:193 large_obj.c:255 psqlscan.l:1946 -#, c-format -msgid "%s" -msgstr "%s" - -#: command.c:1677 +#: command.c:3056 #, c-format msgid "Previous connection kept\n" msgstr "PÅ™edchozí spojení zachováno\n" -#: command.c:1681 +#: command.c:3060 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:1714 +#: command.c:3096 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " @@ -295,7 +391,7 @@ msgstr "" "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " "at port \"%s\".\n" -#: command.c:1717 +#: command.c:3099 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " @@ -304,36 +400,43 @@ msgstr "" "Nyní jste pÅ™ipojeni k databázi \"%s\" jako uživatel \"%s\" na serveru \"%s\" " "na portu\"%s\".\n" -#: command.c:1721 +#: command.c:3103 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Nyní jste pÅ™ipojeni k databázi \"%s\" jako uživatel \"%s\".\n" -#: command.c:1755 +#: command.c:3136 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, server %s)\n" -#: command.c:1763 +#: command.c:3144 #, c-format msgid "" -"WARNING: %s major version %d.%d, server major version %d.%d.\n" +"WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n" msgstr "" -"VAROVÃNÃ: %s major verze %d.%d, major verze serveru %d.%d.\n" +"VAROVÃNÃ: %s major verze %s, major verze serveru %s.\n" " NÄ›které vlastnosti psql nemusí fungovat.\n" -#: command.c:1793 +#: command.c:3181 #, c-format -msgid "SSL connection (cipher: %s, bits: %d)\n" -msgstr "SSL spojení (Å¡ifra: %s, bitů: %d)\n" +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL spojení (protokol: %s, Å¡ifra: %s, bitů: %s, komprese: %s)\n" -#: command.c:1803 -#, c-format -msgid "SSL connection (unknown cipher)\n" -msgstr "SSL spojení (neznámá Å¡ifra)\n" +#: command.c:3182 command.c:3183 command.c:3184 +msgid "unknown" +msgstr "neznámé" -#: command.c:1824 +#: command.c:3185 help.c:45 +msgid "off" +msgstr "vypnuto" + +#: command.c:3185 help.c:45 +msgid "on" +msgstr "zapnuto" + +#: command.c:3205 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -345,7 +448,7 @@ msgstr "" " informace najdete v manuálu k psql na stránce \"Poznámky pro\n" " uživatele Windows.\"\n" -#: command.c:1908 +#: command.c:3309 #, c-format msgid "" "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " @@ -354,230 +457,329 @@ msgstr "" "promÄ›nná prostÅ™edí PSQL_EDITOR_LINENUMBER_ARG musí být nastavena pro " "zadáníÄísla řádky\n" -#: command.c:1945 +#: command.c:3338 #, c-format msgid "could not start editor \"%s\"\n" msgstr "nelze spustit editor \"%s\"\n" -#: command.c:1947 +#: command.c:3340 #, c-format msgid "could not start /bin/sh\n" msgstr "nelze spustit /bin/sh\n" -#: command.c:1985 +#: command.c:3378 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "nelze najít doÄasný adresář: %s\n" -#: command.c:2012 +#: command.c:3405 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "nelze otevřít doÄasný soubor \"%s\": %s\n" -#: command.c:2274 +#: command.c:3679 #, c-format msgid "" -"\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-" -"ms\n" +"\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, " +"latex, latex-longtable, troff-ms\n" msgstr "" -"\\pset: dovolené formáty jsou: unaligned, aligned, wrapped, html, latex, " -"troff-ms\n" - -#: command.c:2279 -#, c-format -msgid "Output format is %s.\n" -msgstr "Výstupní formát je %s.\n" +"\\pset: dovolené formáty jsou: unaligned, aligned, wrapped, html, asciidoc, " +"latex, latex-longtable, troff-ms\n" -#: command.c:2295 +#: command.c:3697 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "\\pset: povolené styly řádek jsou ascii, old-ascii, unicode\n" -#: command.c:2300 +#: command.c:3712 #, c-format -msgid "Line style is %s.\n" -msgstr "Styl Äar je %s.\n" +msgid "\\pset: allowed Unicode border line styles are single, double\n" +msgstr "\\pset: povolené styly Unicode rámeÄků jsou single, double\n" + +#: command.c:3727 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double\n" +msgstr "\\pset: povolené styly Unicode sloupců jsou single, double\n" + +#: command.c:3742 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double\n" +msgstr "\\pset: povolené styly Unicode rámeÄků záhlaví single, double\n" -#: command.c:2311 +#: command.c:3907 command.c:4086 +#, c-format +msgid "\\pset: unknown option: %s\n" +msgstr "\\pset: neznámá volba: %s\n" + +#: command.c:3925 #, c-format msgid "Border style is %d.\n" msgstr "Styl rámeÄků je %d.\n" -#: command.c:2326 +#: command.c:3931 +#, c-format +msgid "Target width is unset.\n" +msgstr "Cílová šířka není nastavena.\n" + +#: command.c:3933 +#, c-format +msgid "Target width is %d.\n" +msgstr "Cílová šířka je %d.\n" + +#: command.c:3940 #, c-format msgid "Expanded display is on.\n" msgstr "Rozšířené zobrazení zapnuto.\n" -#: command.c:2328 +#: command.c:3942 #, c-format msgid "Expanded display is used automatically.\n" msgstr "Rozšířené zobrazení je zapnuto automaticky.\n" -#: command.c:2330 +#: command.c:3944 #, c-format msgid "Expanded display is off.\n" msgstr "Rozšířené zobrazení vypnuto.\n" -#: command.c:2344 -msgid "Showing locale-adjusted numeric output." -msgstr "Zobrazí Äíselný výstup dle národního nastavení." +#: command.c:3951 command.c:3959 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "OddÄ›lovaÄ polí je nulový byte.\n" + +#: command.c:3953 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "OddÄ›lovaÄ polí je '\"%s\"'.\n" + +#: command.c:3966 +#, c-format +msgid "Default footer is on.\n" +msgstr "Implicitní zápatí je zapnuto.\n" + +#: command.c:3968 +#, c-format +msgid "Default footer is off.\n" +msgstr "Implicitní zápatí je vypnuto.\n" + +#: command.c:3974 +#, c-format +msgid "Output format is %s.\n" +msgstr "Výstupní formát je %s.\n" -#: command.c:2346 -msgid "Locale-adjusted numeric output is off." -msgstr "Zobrazení Äíselného výstupu dle národního nastavení je vypnuto." +#: command.c:3980 +#, c-format +msgid "Line style is %s.\n" +msgstr "Styl Äar je %s.\n" -#: command.c:2359 +#: command.c:3987 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null je zobrazován jako '\"%s\"'.\n" -#: command.c:2374 command.c:2386 +#: command.c:3995 #, c-format -msgid "Field separator is zero byte.\n" -msgstr "OddÄ›lovaÄ polí je nulový byte.\n" +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Zobrazení Äíselného výstupu dle národního nastavení je vypnuto.\n" -#: command.c:2376 +#: command.c:3997 #, c-format -msgid "Field separator is \"%s\".\n" -msgstr "OddÄ›lovaÄ polí je '\"%s\"'.\n" +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Zobrazení Äíselného výstupu dle národního nastavení je vypnuto.\n" + +#: command.c:4004 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Stránkování je zapnuto pro dlouhé výstupy.\n" + +#: command.c:4006 +#, c-format +msgid "Pager is always used.\n" +msgstr "Stránkování je vždy použito.\n" + +#: command.c:4008 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Stránkování je vypnuto.\n" + +#: command.c:4014 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "Pager nebude použit pro ménÄ› než %d řáden.\n" +msgstr[1] "Pager won't be used for less than %d lines.\n" +msgstr[2] "Pager won't be used for less than %d lines.\n" -#: command.c:2401 command.c:2415 +#: command.c:4024 command.c:4034 #, c-format msgid "Record separator is zero byte.\n" msgstr "OddÄ›lovaÄ záznamů je nulový byte.\n" -#: command.c:2403 +#: command.c:4026 #, c-format -msgid "Record separator is ." -msgstr "OddÄ›lovaÄ záznamů je ." +msgid "Record separator is .\n" +msgstr "OddÄ›lovaÄ záznamů je .\n" -#: command.c:2405 +#: command.c:4028 #, c-format msgid "Record separator is \"%s\".\n" msgstr "OddÄ›lovaÄ záznamů je '\"%s\"'.\n" -#: command.c:2428 -msgid "Showing only tuples." -msgstr "Zobrazovány jsou pouze záznamy." +#: command.c:4041 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Atributy tabulky jsou \"%s\".\n" -#: command.c:2430 -msgid "Tuples only is off." -msgstr "Zobrazování pouze záznamů je vypnuto." +#: command.c:4044 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Atributy tabulky nejsou nastaveny.\n" -#: command.c:2446 +#: command.c:4051 #, c-format msgid "Title is \"%s\".\n" msgstr "Nadpis je \"%s\".\n" -#: command.c:2448 +#: command.c:4053 #, c-format msgid "Title is unset.\n" msgstr "Nadpis není nastaven.\n" -#: command.c:2464 +#: command.c:4060 #, c-format -msgid "Table attribute is \"%s\".\n" -msgstr "Atribut tabulky je \"%s\".\n" +msgid "Tuples only is on.\n" +msgstr "Zobrazování pouze záznamů je vypnuto.\n" -#: command.c:2466 +#: command.c:4062 #, c-format -msgid "Table attributes unset.\n" -msgstr "Atributy tabulky nejsou nastaveny.\n" - -#: command.c:2487 -msgid "Pager is used for long output." -msgstr "Stránkování je zapnuto pro dlouhé výstupy." - -#: command.c:2489 -msgid "Pager is always used." -msgstr "Stránkování je vždy použito." +msgid "Tuples only is off.\n" +msgstr "Zobrazování pouze záznamů je vypnuto.\n" -#: command.c:2491 -msgid "Pager usage is off." -msgstr "Stránkování je vypnuto." - -#: command.c:2505 -msgid "Default footer is on." -msgstr "Implicitní zápatí je zapnuto." - -#: command.c:2507 -msgid "Default footer is off." -msgstr "Implicitní zápatí je vypnuto." +#: command.c:4068 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Styl Unicode rámeÄků je \"%s\".\n" -#: command.c:2518 +#: command.c:4074 #, c-format -msgid "Target width is %d.\n" -msgstr "Cílová šířka je %d.\n" +msgid "Unicode column line style is \"%s\".\n" +msgstr "Styl Unicode sloupců je \"%s\".\n" -#: command.c:2523 +#: command.c:4080 #, c-format -msgid "\\pset: unknown option: %s\n" -msgstr "\\pset: neznámá volba: %s\n" +msgid "Unicode header line style is \"%s\".\n" +msgstr "Styl Unicode rámeÄků záhlaví je \"%s\".\n" -#: command.c:2577 +#: command.c:4240 #, c-format msgid "\\!: failed\n" msgstr "\\!: selhal\n" -#: command.c:2597 command.c:2656 +#: command.c:4265 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch neze použít s prázdným dotazem\n" -#: command.c:2619 +#: command.c:4306 #, c-format -msgid "Watch every %lds\t%s" -msgstr "Zkontroluj každých %lds\t%s" +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (každé %gs)\n" -#: command.c:2663 +#: command.c:4309 #, c-format -msgid "\\watch cannot be used with COPY\n" -msgstr "\\watch nelze použít s COPY\n" +msgid "%s (every %gs)\n" +msgstr "%s (každé %gs)\n" -#: command.c:2669 +#: command.c:4363 command.c:4370 common.c:702 common.c:709 common.c:1321 #, c-format -msgid "unexpected result status for \\watch\n" -msgstr "neoÄekávaný stav výsledku pro \\watch\n" +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* DOTAZ **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4562 +#, c-format +msgid "\"%s.%s\" is not a view\n" +msgstr "\"%s.%s\" není pohled\n" + +#: command.c:4578 +#, c-format +msgid "could not parse reloptions array\n" +msgstr "nelze naparsovat pole reloptions\n" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection\n" +msgstr "nelze escapovat bez aktivního spojení\n" -#: common.c:287 +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgstr "" +"argument shell příkazu obsahuje pÅ™echod na nový řádek nebo návrat na zaÄátek " +"(carriage return): \"%s\"\n" + +#: common.c:416 #, c-format msgid "connection to server was lost\n" msgstr "spojení na server bylo ztraceno\n" -#: common.c:291 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Spojení na server bylo ztraceno. ZkouÅ¡en restart: " -#: common.c:296 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "NepodaÅ™ilo se.\n" -#: common.c:303 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "PodaÅ™ilo se.\n" -#: common.c:403 common.c:683 common.c:816 +#: common.c:532 common.c:1082 common.c:1256 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "neoÄekávaný PQresultStatus: %d\n" -#: common.c:452 common.c:459 common.c:877 +#: common.c:641 #, c-format -msgid "" -"********* QUERY **********\n" -"%s\n" -"**************************\n" -"\n" -msgstr "" -"********* DOTAZ **********\n" -"%s\n" -"**************************\n" -"\n" +msgid "Time: %.3f ms\n" +msgstr "ÄŒas: %.3f ms\n" + +#: common.c:656 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "ÄŒas: %.3f ms (%02d:%06.3f)\n" + +#: common.c:665 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "ÄŒas: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:672 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "ÄŒas: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:809 +#, c-format +msgid "\\watch cannot be used with COPY\n" +msgstr "\\watch nelze použít s COPY\n" + +#: common.c:814 +#, c-format +msgid "unexpected result status for \\watch\n" +msgstr "neoÄekávaný stav výsledku pro \\watch\n" -#: common.c:513 +#: common.c:843 #, c-format msgid "" "Asynchronous notification \"%s\" with payload \"%s\" received from server " @@ -586,668 +788,901 @@ msgstr "" "Asynchronní upozornÄ›ní \"%s\" s obsahem \"%s\" obdrženo ze serverového " "procesu s PID %d.\n" -#: common.c:516 +#: common.c:846 #, c-format msgid "" "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Asynchronní upozornÄ›ní \"%s\" obdrženo z procesu serveru s PID %d.\n" -#: common.c:578 +#: common.c:908 #, c-format msgid "no rows returned for \\gset\n" msgstr "žádné řádky nevráceny pro \\gset\n" -#: common.c:583 +#: common.c:913 #, c-format msgid "more than one row returned for \\gset\n" msgstr "více než jedna řádka vrácena pro \\gset\n" -#: common.c:611 -#, c-format -msgid "could not set variable \"%s\"\n" -msgstr "nelze nastavit promÄ›nnou \"%s\"\n" - -#: common.c:859 +#: common.c:1301 #, c-format msgid "" -"***(Single step mode: verify command)" -"*******************************************\n" +"***(Single step mode: verify " +"command)*******************************************\n" "%s\n" -"***(press return to proceed or enter x and return to cancel)" -"********************\n" +"***(press return to proceed or enter x and return to " +"cancel)********************\n" msgstr "" -"***(Krokovací mód: potvrÄte příkaz)" -"*******************************************\n" +"***(Krokovací mód: potvrÄte " +"příkaz)*******************************************\n" "%s\n" -"***(stisknÄ›te return pro zpracování nebo x a return pro zruÅ¡ení)" -"********************\n" +"***(stisknÄ›te return pro zpracování nebo x a return pro " +"zruÅ¡ení)********************\n" -#: common.c:910 +#: common.c:1356 #, c-format msgid "" -"The server (version %d.%d) does not support savepoints for " -"ON_ERROR_ROLLBACK.\n" -msgstr "Server (verze %d.%d) nepodporuje savepoints pro ON_ERROR_ROLLBACK.\n" +"The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" +msgstr "Server (verze %s) nepodporuje savepoints pro ON_ERROR_ROLLBACK.\n" + +#: common.c:1419 +#, c-format +msgid "STATEMENT: %s\n" +msgstr "PŘÃKAZ: %s\n" -#: common.c:1004 +#: common.c:1462 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "neoÄekávaný stav transakce: (%d)\n" -#: common.c:1032 +#: common.c:1599 describe.c:1847 +msgid "Column" +msgstr "Sloupec" + +#: common.c:1600 describe.c:174 describe.c:374 describe.c:392 describe.c:437 +#: describe.c:454 describe.c:925 describe.c:1089 describe.c:1620 +#: describe.c:1644 describe.c:1848 describe.c:3466 describe.c:3671 +#: describe.c:4843 +msgid "Type" +msgstr "Typ" + +#: common.c:1649 #, c-format -msgid "Time: %.3f ms\n" -msgstr "ÄŒas: %.3f ms\n" +msgid "The command has no result, or the result has no columns.\n" +msgstr "Příkaz nevrátil žádný výsledek, nebo výsledek nemá žádné sloupce.\n" -#: copy.c:100 +#: copy.c:99 #, c-format msgid "\\copy: arguments required\n" msgstr "\\copy: argumenty jsou povinné\n" -#: copy.c:255 +#: copy.c:254 #, c-format msgid "\\copy: parse error at \"%s\"\n" msgstr "\\copy: chyba na \"%s\"\n" -#: copy.c:257 +#: copy.c:256 #, c-format msgid "\\copy: parse error at end of line\n" msgstr "\\copy: chyba na konci řádku\n" -#: copy.c:339 +#: copy.c:329 #, c-format msgid "could not execute command \"%s\": %s\n" msgstr "nelze spustit příkaz \"%s\": %s\n" -#: copy.c:355 +#: copy.c:345 +#, c-format +msgid "could not stat file \"%s\": %s\n" +msgstr "nelze provést stat souboru \"%s\": %s\n" + +#: copy.c:349 #, c-format msgid "%s: cannot copy from/to a directory\n" msgstr "%s: nelze kopírovat z/do adresáře\n" -#: copy.c:389 +#: copy.c:386 #, c-format msgid "could not close pipe to external command: %s\n" msgstr "nelze zavřít rouru (pipe) pro externí příkaz: %s\n" -#: copy.c:457 copy.c:467 +#: copy.c:452 copy.c:463 #, c-format msgid "could not write COPY data: %s\n" msgstr "nelze zapsat data příkazu COPY: %s\n" -#: copy.c:474 +#: copy.c:470 #, c-format msgid "COPY data transfer failed: %s" -msgstr "pÅ™enos dat příkazem COPY selhal: %s" +msgstr "pÅ™enos dat příkazu COPY selhal: %s" -#: copy.c:544 +#: copy.c:531 msgid "canceled by user" msgstr "zruÅ¡eno na žádost uživatele" # common.c:485 -#: copy.c:554 +#: copy.c:542 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" "Zadejte data pro kopírování následovaná novým řádkem.\n" "UkonÄete zpÄ›tným lomítkem a teÄkou na samostatném řádku." -#: copy.c:667 +#: copy.c:670 msgid "aborted because of read failure" msgstr "pÅ™eruÅ¡eno z důvodu chyby Ätení" -#: copy.c:687 +#: copy.c:704 msgid "trying to exit copy mode" msgstr "pokouším se opustit copy mód" -#: describe.c:71 describe.c:247 describe.c:478 describe.c:605 describe.c:737 -#: describe.c:822 describe.c:891 describe.c:2666 describe.c:2870 -#: describe.c:2959 describe.c:3197 describe.c:3333 describe.c:3560 -#: describe.c:3632 describe.c:3643 describe.c:3702 describe.c:4110 -#: describe.c:4189 +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set\n" +msgstr "\\crosstabview: příkaz nevrátil žádný výsledek\n" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns\n" +msgstr "\\crosstabview: dotaz musí vracet alespoň tÅ™i sloupce\n" + +#: crosstabview.c:156 +#, c-format +msgid "" +"\\crosstabview: vertical and horizontal headers must be different columns\n" +msgstr "" +"\\crosstabview: vertikální a horozintální záklaví musí být různé sloupce\n" + +#: crosstabview.c:172 +#, c-format +msgid "" +"\\crosstabview: data column must be specified when query returns more than " +"three columns\n" +msgstr "" +"\\crosstabview: datový sloupec musí být specifikován pokud má dotaz více než " +"tÅ™i sloupce\n" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" +msgstr "\\crosstabview: maximální poÄet sloupců (%d) pÅ™ekroÄen\n" + +#: crosstabview.c:397 +#, c-format +msgid "" +"\\crosstabview: query result contains multiple data values for row \"%s\", " +"column \"%s\"\n" +msgstr "" +"\\crosstabview: výsledek dotazu obsahuje nÄ›kolik hodnot pro řádek \"%s\", " +"sloupec \"%s\"\n" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d\n" +msgstr "\\crosstabview: Äíslo sloupce %d je mimo rozsah 0..%d\n" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"\n" +msgstr "\\crosstabview: nejednoznaÄný název sloupce: \"%s\"\n" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"\n" +msgstr "\\crosstabview: sloupec nenaleze: \"%s\"\n" + +#: describe.c:74 describe.c:354 describe.c:641 describe.c:773 describe.c:917 +#: describe.c:1078 describe.c:1150 describe.c:3455 describe.c:3669 +#: describe.c:3760 describe.c:4008 describe.c:4153 describe.c:4394 +#: describe.c:4469 describe.c:4480 describe.c:4542 describe.c:4967 +#: describe.c:5050 msgid "Schema" msgstr "Schéma" -#: describe.c:72 describe.c:149 describe.c:157 describe.c:248 describe.c:479 -#: describe.c:606 describe.c:656 describe.c:738 describe.c:892 describe.c:2667 -#: describe.c:2792 describe.c:2871 describe.c:2960 describe.c:3038 -#: describe.c:3198 describe.c:3261 describe.c:3334 describe.c:3561 -#: describe.c:3633 describe.c:3644 describe.c:3703 describe.c:3892 -#: describe.c:3973 describe.c:4187 +#: describe.c:75 describe.c:172 describe.c:239 describe.c:247 describe.c:355 +#: describe.c:642 describe.c:774 describe.c:835 describe.c:918 describe.c:1151 +#: describe.c:3456 describe.c:3592 describe.c:3670 describe.c:3761 +#: describe.c:3840 describe.c:4009 describe.c:4078 describe.c:4154 +#: describe.c:4395 describe.c:4470 describe.c:4481 describe.c:4543 +#: describe.c:4740 describe.c:4824 describe.c:5048 describe.c:5220 +#: describe.c:5445 msgid "Name" msgstr "Jméno" -#: describe.c:73 describe.c:260 describe.c:306 describe.c:323 +#: describe.c:76 describe.c:367 describe.c:385 describe.c:431 describe.c:448 msgid "Result data type" msgstr "Datový typ výsledku" -#: describe.c:87 describe.c:91 describe.c:261 describe.c:307 describe.c:324 +#: describe.c:84 describe.c:97 describe.c:101 describe.c:368 describe.c:386 +#: describe.c:432 describe.c:449 msgid "Argument data types" msgstr "Datový typ parametru" -#: describe.c:98 describe.c:170 describe.c:353 describe.c:521 describe.c:610 -#: describe.c:681 describe.c:894 describe.c:1442 describe.c:2471 -#: describe.c:2700 describe.c:2823 describe.c:2897 describe.c:2969 -#: describe.c:3047 describe.c:3114 describe.c:3205 describe.c:3270 -#: describe.c:3335 describe.c:3471 describe.c:3510 describe.c:3577 -#: describe.c:3636 describe.c:3645 describe.c:3704 describe.c:3918 -#: describe.c:3995 describe.c:4124 describe.c:4190 large_obj.c:291 -#: large_obj.c:301 +#: describe.c:109 describe.c:116 describe.c:182 describe.c:270 describe.c:494 +#: describe.c:690 describe.c:789 describe.c:860 describe.c:1153 describe.c:1888 +#: describe.c:3244 describe.c:3491 describe.c:3623 describe.c:3697 +#: describe.c:3770 describe.c:3853 describe.c:3921 describe.c:4021 +#: describe.c:4087 describe.c:4155 describe.c:4296 describe.c:4338 +#: describe.c:4411 describe.c:4473 describe.c:4482 describe.c:4544 +#: describe.c:4766 describe.c:4846 describe.c:4981 describe.c:5051 +#: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "Popis" -#: describe.c:116 +#: describe.c:134 msgid "List of aggregate functions" msgstr "Seznam agregaÄních funkcí" -#: describe.c:137 +#: describe.c:159 +#, c-format +msgid "The server (version %s) does not support access methods.\n" +msgstr "Server (verze %s) nepodporuje tablespaces.\n" + +#: describe.c:173 +msgid "Index" +msgstr "Index" + +#: describe.c:181 describe.c:4745 +msgid "Handler" +msgstr "Handler" + +#: describe.c:200 +msgid "List of access methods" +msgstr "Seznam přístupových metod" + +#: describe.c:226 #, c-format -msgid "The server (version %d.%d) does not support tablespaces.\n" -msgstr "Server (verze %d.%d) nepodporuje tablespaces.\n" +msgid "The server (version %s) does not support tablespaces.\n" +msgstr "Server (verze %s) nepodporuje tablespaces.\n" -#: describe.c:150 describe.c:158 describe.c:350 describe.c:657 describe.c:821 -#: describe.c:2676 describe.c:2796 describe.c:3040 describe.c:3262 -#: describe.c:3893 describe.c:3974 large_obj.c:290 +#: describe.c:240 describe.c:248 describe.c:482 describe.c:680 describe.c:836 +#: describe.c:1077 describe.c:3467 describe.c:3596 describe.c:3842 +#: describe.c:4079 describe.c:4741 describe.c:4825 describe.c:5221 +#: describe.c:5347 describe.c:5446 large_obj.c:288 msgid "Owner" msgstr "Vlastník" -#: describe.c:151 describe.c:159 +#: describe.c:241 describe.c:249 msgid "Location" msgstr "UmístÄ›ní" -#: describe.c:187 -msgid "List of tablespaces" -msgstr "Seznam tablespaces" +#: describe.c:260 describe.c:3063 +msgid "Options" +msgstr "Volby" + +#: describe.c:265 describe.c:653 describe.c:852 describe.c:3483 describe.c:3487 +msgid "Size" +msgstr "Velikost" + +#: describe.c:287 +msgid "List of tablespaces" +msgstr "Seznam tablespaces" -#: describe.c:224 +#: describe.c:328 #, c-format msgid "\\df only takes [antwS+] as options\n" msgstr "pro \\df můžete použít pouze pÅ™epínaÄe [antwS+]\n" -#: describe.c:230 +#: describe.c:336 #, c-format -msgid "\\df does not take a \"w\" option with server version %d.%d\n" -msgstr "pro \\df nelze použít volbu \"w\" ve verzi serveru %d.%d.\n" +msgid "\\df does not take a \"w\" option with server version %s\n" +msgstr "pro \\df nelze použít volbu \"w\" ve verzi serveru %s.\n" #. translator: "agg" is short for "aggregate" -#: describe.c:263 describe.c:309 describe.c:326 +#: describe.c:370 describe.c:388 describe.c:434 describe.c:451 msgid "agg" msgstr "agg" -#: describe.c:264 +#: describe.c:371 describe.c:389 msgid "window" msgstr "window" -#: describe.c:265 describe.c:310 describe.c:327 describe.c:1005 -msgid "trigger" -msgstr "trigger" - -#: describe.c:266 describe.c:311 describe.c:328 -msgid "normal" -msgstr "normal" - -#: describe.c:267 describe.c:312 describe.c:329 describe.c:744 describe.c:831 -#: describe.c:1411 describe.c:2675 describe.c:2872 describe.c:3992 -msgid "Type" -msgstr "Typ" - -#: describe.c:343 -msgid "definer" -msgstr "definer" +#: describe.c:372 +msgid "proc" +msgstr "proc" -#: describe.c:344 -msgid "invoker" -msgstr "invoker" +#: describe.c:373 describe.c:391 describe.c:436 describe.c:453 +msgid "func" +msgstr "func" -#: describe.c:345 -msgid "Security" -msgstr "BezpeÄnost" +#: describe.c:390 describe.c:435 describe.c:452 describe.c:1287 +msgid "trigger" +msgstr "trigger" -#: describe.c:346 +#: describe.c:464 msgid "immutable" msgstr "immutable" -#: describe.c:347 +#: describe.c:465 msgid "stable" msgstr "stable" -#: describe.c:348 +#: describe.c:466 msgid "volatile" msgstr "volatile" -#: describe.c:349 +#: describe.c:467 msgid "Volatility" msgstr "Volatilita" -#: describe.c:351 +#: describe.c:475 +msgid "restricted" +msgstr "restricted" + +#: describe.c:476 +msgid "safe" +msgstr "safe" + +#: describe.c:477 +msgid "unsafe" +msgstr "unsafe" + +#: describe.c:478 +msgid "Parallel" +msgstr "Parallel" + +#: describe.c:483 +msgid "definer" +msgstr "definer" + +#: describe.c:484 +msgid "invoker" +msgstr "invoker" + +#: describe.c:485 +msgid "Security" +msgstr "BezpeÄnost" + +#: describe.c:492 msgid "Language" msgstr "Jazyk" -#: describe.c:352 +#: describe.c:493 msgid "Source code" msgstr "Zdrojový kód" -#: describe.c:450 +#: describe.c:604 msgid "List of functions" msgstr "Seznam funkcí" -#: describe.c:489 +#: describe.c:652 msgid "Internal name" msgstr "Interní jméno" -#: describe.c:490 describe.c:673 describe.c:2692 describe.c:2696 -msgid "Size" -msgstr "Velikost" - -#: describe.c:511 +#: describe.c:674 msgid "Elements" msgstr "Složky" -#: describe.c:561 +#: describe.c:731 msgid "List of data types" msgstr "Seznam datových typů" -#: describe.c:607 +#: describe.c:775 msgid "Left arg type" -msgstr "Typ levého arg." +msgstr "Typ levého argumentu" -#: describe.c:608 +#: describe.c:776 msgid "Right arg type" -msgstr "Typ pravého arg." +msgstr "Typ pravého argumentu" -#: describe.c:609 +#: describe.c:777 msgid "Result type" msgstr "Typ výsledku" -#: describe.c:628 +#: describe.c:782 describe.c:3912 describe.c:4295 +msgid "Function" +msgstr "Funkce" + +#: describe.c:807 msgid "List of operators" msgstr "Seznam operátorů" -#: describe.c:658 +#: describe.c:837 msgid "Encoding" msgstr "Kódování" -#: describe.c:663 describe.c:3199 +#: describe.c:842 describe.c:4010 msgid "Collate" msgstr "Collation" -#: describe.c:664 describe.c:3200 +#: describe.c:843 describe.c:4011 msgid "Ctype" msgstr "CType" -#: describe.c:677 +#: describe.c:856 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:699 +#: describe.c:878 msgid "List of databases" msgstr "Seznam databází" -#: describe.c:739 describe.c:824 describe.c:2668 +#: describe.c:919 describe.c:924 describe.c:1080 describe.c:3457 +#: describe.c:3464 msgid "table" msgstr "tabulka" -#: describe.c:740 describe.c:2669 +#: describe.c:920 describe.c:3458 msgid "view" msgstr "pohled" -#: describe.c:741 describe.c:2670 +#: describe.c:921 describe.c:3459 msgid "materialized view" msgstr "materializovaný pohled" -#: describe.c:742 describe.c:826 describe.c:2672 +#: describe.c:922 describe.c:1082 describe.c:3461 msgid "sequence" msgstr "sekvence" -#: describe.c:743 describe.c:2674 +#: describe.c:923 describe.c:3463 msgid "foreign table" msgstr "foreign_tabulka" # -#: describe.c:755 -msgid "Column access privileges" +#: describe.c:936 +msgid "Column privileges" msgstr "Přístupová práva k atributům" -#: describe.c:781 describe.c:4334 describe.c:4338 +#: describe.c:967 describe.c:1001 +msgid "Policies" +msgstr "Politiky" + +#: describe.c:1033 describe.c:5502 describe.c:5506 msgid "Access privileges" msgstr "Přístupová práva" -#: describe.c:809 +#: describe.c:1064 #, c-format -msgid "" -"The server (version %d.%d) does not support altering default privileges.\n" -msgstr "Server (verze %d.%d) nepodporuje foreign servery.\n" +msgid "The server (version %s) does not support altering default privileges.\n" +msgstr "Server (verze %s) nepodporuje zmÄ›ny výchozích privilegií.\n" -#: describe.c:828 +#: describe.c:1084 msgid "function" msgstr "funkce" -#: describe.c:830 +#: describe.c:1086 msgid "type" msgstr "typ" -#: describe.c:854 +#: describe.c:1088 +msgid "schema" +msgstr "schéma" + +#: describe.c:1112 msgid "Default access privileges" msgstr "Implicitní přístupová práva" -#: describe.c:893 +#: describe.c:1152 msgid "Object" msgstr "Objekt" -#: describe.c:907 sql_help.c:1447 -msgid "constraint" -msgstr "omezení" +#: describe.c:1166 +msgid "table constraint" +msgstr "omezení tabulky" + +#: describe.c:1188 +msgid "domain constraint" +msgstr "omezení domény" -#: describe.c:934 +#: describe.c:1216 msgid "operator class" msgstr "třída operátorů" -#: describe.c:963 +#: describe.c:1245 msgid "operator family" msgstr "rodina operátorů" -#: describe.c:985 +#: describe.c:1267 msgid "rule" msgstr "rule" -#: describe.c:1027 +#: describe.c:1309 msgid "Object descriptions" msgstr "Popis objektu" -#: describe.c:1080 +#: describe.c:1365 describe.c:3555 #, c-format msgid "Did not find any relation named \"%s\".\n" msgstr "Nelze nalézt relaci se jménem \"%s\".\n" -#: describe.c:1253 +#: describe.c:1368 describe.c:3558 +#, c-format +msgid "Did not find any relations.\n" +msgstr "Nelze nalézt žádnou relaci.\n" + +#: describe.c:1575 #, c-format msgid "Did not find any relation with OID %s.\n" msgstr "Nelze nalézt relaci se OID \"%s\".\n" -#: describe.c:1355 +#: describe.c:1621 describe.c:1645 +msgid "Start" +msgstr "Start" + +#: describe.c:1622 describe.c:1646 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1623 describe.c:1647 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1624 describe.c:1648 +msgid "Increment" +msgstr "Inkrement" + +#: describe.c:1625 describe.c:1649 describe.c:3764 describe.c:3915 +msgid "yes" +msgstr "ano" + +#: describe.c:1626 describe.c:1650 describe.c:3764 describe.c:3913 +msgid "no" +msgstr "ne" + +#: describe.c:1627 describe.c:1651 +msgid "Cycles?" +msgstr "Cycles?" + +#: describe.c:1628 describe.c:1652 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1695 +#, c-format +msgid "Owned by: %s" +msgstr "Vlastník: %s" + +#: describe.c:1699 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sekvence pro identity sloupec: %s" + +#: describe.c:1706 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sekvence \"%s.%s\"" + +#: describe.c:1787 describe.c:1833 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Unlogged tabulka \"%s.%s\"" -#: describe.c:1358 +#: describe.c:1790 describe.c:1836 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabulka \"%s.%s\"" -#: describe.c:1362 +#: describe.c:1794 #, c-format msgid "View \"%s.%s\"" msgstr "Pohled \"%s.%s\"" -#: describe.c:1367 +#: describe.c:1799 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Unlogged materializovaný pohled \"%s.%s\"" -#: describe.c:1370 +#: describe.c:1802 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Materializovaný pohled \"%s.%s\"" -#: describe.c:1374 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Sekvence \"%s.%s\"" - -#: describe.c:1379 +#: describe.c:1808 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Unlogged index \"%s.%s\"" -#: describe.c:1382 +#: describe.c:1811 #, c-format msgid "Index \"%s.%s\"" msgstr "Index \"%s.%s\"" -#: describe.c:1387 +#: describe.c:1816 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Speciální relace \"%s.%s\"" -#: describe.c:1391 +#: describe.c:1820 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST tabulka \"%s.%s\"" -#: describe.c:1395 +#: describe.c:1824 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Složený typ \"%s.%s\"" -#: describe.c:1399 +#: describe.c:1828 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Foreign tabulka \"%s.%s\"" -#: describe.c:1410 -msgid "Column" -msgstr "Sloupec" +#: describe.c:1858 describe.c:3677 +msgid "Collation" +msgstr "Collation" -#: describe.c:1419 -msgid "Modifiers" -msgstr "Modifikátory" +#: describe.c:1859 describe.c:3684 +msgid "Nullable" +msgstr "Nullable" -#: describe.c:1424 -msgid "Value" -msgstr "Hodnota" +#: describe.c:1860 describe.c:3685 +msgid "Default" +msgstr "ImplicitnÄ›" -#: describe.c:1427 +#: describe.c:1866 msgid "Definition" msgstr "Definice" -#: describe.c:1430 describe.c:3913 describe.c:3994 describe.c:4062 -#: describe.c:4123 -msgid "FDW Options" -msgstr "FDW Volby" +#: describe.c:1869 describe.c:4761 describe.c:4845 describe.c:4916 +#: describe.c:4980 +msgid "FDW options" +msgstr "FDW volby" -#: describe.c:1434 +#: describe.c:1873 msgid "Storage" msgstr "Uložení" -#: describe.c:1437 +#: describe.c:1880 msgid "Stats target" msgstr "Stats target" -#: describe.c:1487 +#: describe.c:2028 #, c-format -msgid "collate %s" -msgstr "collate %s" +msgid "Partition of: %s %s" +msgstr "Partition pro: %s %s" + +#: describe.c:2036 +msgid "No partition constraint" +msgstr "Žádné omezení partition" -#: describe.c:1495 -msgid "not null" -msgstr "not null" +#: describe.c:2038 +#, c-format +msgid "Partition constraint: %s" +msgstr "Omezení partition: %s" -#. translator: default values of column definitions -#: describe.c:1505 +#: describe.c:2061 #, c-format -msgid "default %s" -msgstr "implicitnÄ› %s" +msgid "Partition key: %s" +msgstr "Partition klíÄ: %s" -#: describe.c:1613 +#: describe.c:2130 msgid "primary key, " msgstr "primární klíÄ, " -#: describe.c:1615 +#: describe.c:2132 msgid "unique, " msgstr "unikátní, " -#: describe.c:1621 +#: describe.c:2138 #, c-format msgid "for table \"%s.%s\"" msgstr "pro tabulku \"%s.%s\"" -#: describe.c:1625 +#: describe.c:2142 #, c-format msgid ", predicate (%s)" msgstr ", predikát (%s)" -#: describe.c:1628 +#: describe.c:2145 msgid ", clustered" msgstr ", clusterován" -#: describe.c:1631 +#: describe.c:2148 msgid ", invalid" msgstr ", neplatný" -#: describe.c:1634 +#: describe.c:2151 msgid ", deferrable" msgstr ", odložitelný" -#: describe.c:1637 +#: describe.c:2154 msgid ", initially deferred" msgstr ", iniciálnÄ› odložený" -#: describe.c:1672 -#, c-format -msgid "Owned by: %s" -msgstr "Vlastník: %s" +#: describe.c:2157 +msgid ", replica identity" +msgstr ", replica identity" -#: describe.c:1728 +#: describe.c:2216 msgid "Indexes:" msgstr "Indexy:" -#: describe.c:1809 +#: describe.c:2300 msgid "Check constraints:" msgstr "Kontrolní pravidla:" -#: describe.c:1840 +#: describe.c:2336 msgid "Foreign-key constraints:" msgstr "Podmínky cizího klíÄe:" -#: describe.c:1871 +#: describe.c:2367 msgid "Referenced by:" msgstr "Odkazovaný:" -#: describe.c:1953 describe.c:2003 +#: describe.c:2417 +msgid "Policies:" +msgstr "Politiky:" + +#: describe.c:2420 +msgid "Policies (forced row security enabled):" +msgstr "Poitiky (forced row security zapnuta):" + +#: describe.c:2423 +msgid "Policies (row security enabled): (none)" +msgstr "Politiky (row security zapnuta): (žádné)" + +#: describe.c:2426 +msgid "Policies (forced row security enabled): (none)" +msgstr "Politiky (forced row security zapnuta): (žádné)" + +#: describe.c:2429 +msgid "Policies (row security disabled):" +msgstr "Politiky (row security vypnuta):" + +#: describe.c:2491 +msgid "Statistics objects:" +msgstr "Statistické objekty:" + +#: describe.c:2594 describe.c:2679 msgid "Rules:" msgstr "Rules:" -#: describe.c:1956 +#: describe.c:2597 msgid "Disabled rules:" msgstr "Vypnutá pravidla (rules):" -#: describe.c:1959 +#: describe.c:2600 msgid "Rules firing always:" msgstr "Vždy spouÅ¡tÄ›ná pravidla:" -#: describe.c:1962 +#: describe.c:2603 msgid "Rules firing on replica only:" msgstr "Pravidla spouÅ¡tÄ›ná jen na replice:" -#: describe.c:1986 +#: describe.c:2643 +msgid "Publications:" +msgstr "Publikace:" + +#: describe.c:2662 msgid "View definition:" msgstr "Definice pohledu:" -#: describe.c:2109 +#: describe.c:2801 msgid "Triggers:" msgstr "Triggery:" -#: describe.c:2112 +#: describe.c:2805 +msgid "Disabled user triggers:" +msgstr "Vypnuté uživatelské triggery:" + +#: describe.c:2807 msgid "Disabled triggers:" msgstr "Vypnuté triggery:" -#: describe.c:2115 +#: describe.c:2810 +msgid "Disabled internal triggers:" +msgstr "Vypnuté interní triggery:" + +#: describe.c:2813 msgid "Triggers firing always:" msgstr "Vždy spouÅ¡tÄ›né triggery:" -#: describe.c:2118 +#: describe.c:2816 msgid "Triggers firing on replica only:" msgstr "Triggery spouÅ¡tÄ›né jen na replice:" -#: describe.c:2197 +#: describe.c:2875 +#, c-format +msgid "Server: %s" +msgstr "Server: %s" + +#: describe.c:2883 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW volby: (%s)" + +#: describe.c:2902 msgid "Inherits" msgstr "DÄ›dí" -#: describe.c:2236 +#: describe.c:2961 +#, c-format +msgid "Number of partitions: %d" +msgstr "PoÄet partition: %d" + +#: describe.c:2970 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "PoÄet podřízených tabulek: %d (Použijte \\d+ pro jejich seznam.)" -#: describe.c:2243 +#: describe.c:2972 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "PoÄet partitions: %d (Použijte \\d+ pro jejich seznam.)" + +#: describe.c:2980 msgid "Child tables" msgstr "Podřízené tabulky" -#: describe.c:2265 +#: describe.c:2980 +msgid "Partitions" +msgstr "Partitions" + +#: describe.c:3023 #, c-format msgid "Typed table of type: %s" msgstr "Typovaná tabulka typu: %s" -#: describe.c:2272 -msgid "Has OIDs" -msgstr "Má OID" - -#: describe.c:2275 describe.c:2963 describe.c:3106 -msgid "no" -msgstr "ne" - -#: describe.c:2275 describe.c:2963 describe.c:3108 -msgid "yes" -msgstr "ano" +#: describe.c:3039 +msgid "Replica Identity" +msgstr "Replica Identity" -#: describe.c:2288 -msgid "Options" -msgstr "Volby" +#: describe.c:3052 +msgid "Has OIDs: yes" +msgstr "Má OID: ano" -#: describe.c:2366 +#: describe.c:3132 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace: \"%s\"" -#: describe.c:2379 +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3144 #, c-format msgid ", tablespace \"%s\"" msgstr ", tablespace: \"%s\"" -#: describe.c:2464 +#: describe.c:3237 msgid "List of roles" msgstr "Seznam rolí" -#: describe.c:2466 +#: describe.c:3239 msgid "Role name" msgstr "Jméno role" -#: describe.c:2467 +#: describe.c:3240 msgid "Attributes" msgstr "Atributy" -#: describe.c:2468 +#: describe.c:3241 msgid "Member of" msgstr "Je Älenem" -#: describe.c:2479 +#: describe.c:3252 msgid "Superuser" msgstr "Super-uživatel" -#: describe.c:2482 +#: describe.c:3255 msgid "No inheritance" msgstr "Bez dÄ›diÄnosti" -#: describe.c:2485 +#: describe.c:3258 msgid "Create role" msgstr "VytvoÅ™ roli" -#: describe.c:2488 +#: describe.c:3261 msgid "Create DB" msgstr "VytvoÅ™ DB" -#: describe.c:2491 +#: describe.c:3264 msgid "Cannot login" msgstr "Nemohu se pÅ™ihlásit" -#: describe.c:2495 +#: describe.c:3268 msgid "Replication" msgstr "Replikace" -#: describe.c:2504 +#: describe.c:3272 +msgid "Bypass RLS" +msgstr "Obejít RLS" + +#: describe.c:3281 msgid "No connections" msgstr "Není spojení" -#: describe.c:2506 +#: describe.c:3283 #, c-format msgid "%d connection" msgid_plural "%d connections" @@ -1255,290 +1690,308 @@ msgstr[0] "%d spojení" msgstr[1] "%d spojení" msgstr[2] "%d spojení" -#: describe.c:2516 +#: describe.c:3293 msgid "Password valid until " msgstr "Heslo platné do " -#: describe.c:2572 +#: describe.c:3343 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "" +"Server (verze %s) nepodporuje nastavení rolí pro jednotlivé databáze.\n" + +#: describe.c:3356 msgid "Role" msgstr "Role" -#: describe.c:2573 +#: describe.c:3357 msgid "Database" msgstr "Databáze" -#: describe.c:2574 +#: describe.c:3358 msgid "Settings" msgstr "Nastavení" -#: describe.c:2584 +#: describe.c:3379 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "Tato verze serveru nepodporuje nastavení rolí dle databáze.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "Nelze nalézt žádné nastavení pro roli \"%s\" a databázi \"%s\".\n" -#: describe.c:2595 +#: describe.c:3382 #, c-format -msgid "No matching settings found.\n" -msgstr "Odpovídající relace nebyla nalezena.\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "Nelze nalézt žádné nastavení pro roli \"%s\".\n" -#: describe.c:2597 +#: describe.c:3385 #, c-format -msgid "No settings found.\n" -msgstr "Žádné nastavení nenalezeno.\n" +msgid "Did not find any settings.\n" +msgstr "Žádná nastavení nenalezena.\n" -#: describe.c:2602 +#: describe.c:3390 msgid "List of settings" msgstr "Seznam nastavení" -#: describe.c:2671 +#: describe.c:3460 describe.c:3465 msgid "index" msgstr "index" -#: describe.c:2673 +#: describe.c:3462 msgid "special" msgstr "speciální" -#: describe.c:2681 describe.c:4111 +#: describe.c:3472 describe.c:4968 msgid "Table" msgstr "Tabulka" -#: describe.c:2757 -#, c-format -msgid "No matching relations found.\n" -msgstr "Odpovídající relace nebyla nalezena.\n" - -#: describe.c:2759 -#, c-format -msgid "No relations found.\n" -msgstr "Žádné relace nenalezeny.\n" - -#: describe.c:2764 +#: describe.c:3563 msgid "List of relations" msgstr "Seznam relací" -#: describe.c:2800 +#: describe.c:3600 msgid "Trusted" msgstr "DůvÄ›ryhodný" -#: describe.c:2808 -msgid "Internal Language" -msgstr "Interní Jazyk" +#: describe.c:3608 +msgid "Internal language" +msgstr "Interní jazyk" -#: describe.c:2809 -msgid "Call Handler" -msgstr "Call Handler" +#: describe.c:3609 +msgid "Call handler" +msgstr "Call handler" -#: describe.c:2810 describe.c:3900 +#: describe.c:3610 describe.c:4748 msgid "Validator" msgstr "Validátor" -#: describe.c:2813 -msgid "Inline Handler" -msgstr "Inline Handler" +#: describe.c:3613 +msgid "Inline handler" +msgstr "Inline handler" -#: describe.c:2841 +#: describe.c:3641 msgid "List of languages" msgstr "Seznam jazyků" -#: describe.c:2885 -msgid "Modifier" -msgstr "Modifikátor" - -#: describe.c:2886 +#: describe.c:3686 msgid "Check" msgstr "Kontrola" -#: describe.c:2928 +#: describe.c:3728 msgid "List of domains" msgstr "Seznam domén" -#: describe.c:2961 +#: describe.c:3762 msgid "Source" msgstr "Zdroj" -#: describe.c:2962 +#: describe.c:3763 msgid "Destination" msgstr "Cíl" -#: describe.c:2964 +#: describe.c:3765 msgid "Default?" msgstr "ImplicitnÄ›?" -#: describe.c:3001 +#: describe.c:3802 msgid "List of conversions" msgstr "Seznam konverzí" -#: describe.c:3039 +#: describe.c:3841 msgid "Event" msgstr "Událost" -#: describe.c:3041 +#: describe.c:3843 +msgid "enabled" +msgstr "povoleno" + +#: describe.c:3844 +msgid "replica" +msgstr "replica" + +#: describe.c:3845 +msgid "always" +msgstr "vždy" + +#: describe.c:3846 +msgid "disabled" +msgstr "disabled" + +#: describe.c:3847 describe.c:5447 msgid "Enabled" msgstr "Povoleno" -#: describe.c:3042 +#: describe.c:3848 msgid "Procedure" msgstr "Procedura" -#: describe.c:3043 +#: describe.c:3849 msgid "Tags" msgstr "Tagy" -#: describe.c:3062 +#: describe.c:3868 msgid "List of event triggers" msgstr "Seznam event triggerů" -#: describe.c:3103 +#: describe.c:3910 msgid "Source type" msgstr "Zdrojový typ" -#: describe.c:3104 +#: describe.c:3911 msgid "Target type" msgstr "Cílový typ" -#: describe.c:3105 describe.c:3470 -msgid "Function" -msgstr "Funkce" - -#: describe.c:3107 +#: describe.c:3914 msgid "in assignment" msgstr "v pÅ™iÅ™azení" -#: describe.c:3109 +#: describe.c:3916 msgid "Implicit?" msgstr "ImplicitnÄ›?" -#: describe.c:3160 +#: describe.c:3967 msgid "List of casts" msgstr "Seznam pÅ™etypování" -#: describe.c:3185 +#: describe.c:3995 #, c-format -msgid "The server (version %d.%d) does not support collations.\n" -msgstr "Server (verze %d.%d) nepodporuje collations.\n" +msgid "The server (version %s) does not support collations.\n" +msgstr "Server (verze %s) nepodporuje collations.\n" + +#: describe.c:4016 +msgid "Provider" +msgstr "Provider" -#: describe.c:3235 +#: describe.c:4051 msgid "List of collations" msgstr "Seznam collations" -#: describe.c:3293 +#: describe.c:4110 msgid "List of schemas" msgstr "Seznam schémat" -#: describe.c:3316 describe.c:3549 describe.c:3617 describe.c:3685 +#: describe.c:4135 describe.c:4382 describe.c:4453 describe.c:4524 #, c-format -msgid "The server (version %d.%d) does not support full text search.\n" -msgstr "Server (verze %d.%d) nepodporuje fulltextové vyhledávání.\n" +msgid "The server (version %s) does not support full text search.\n" +msgstr "Server (verze %s) nepodporuje fulltextové vyhledávání.\n" -#: describe.c:3350 +#: describe.c:4170 msgid "List of text search parsers" msgstr "Seznam fulltextových parserů" -#: describe.c:3393 +#: describe.c:4215 #, c-format msgid "Did not find any text search parser named \"%s\".\n" msgstr "Nelze nalézt fulltextový parser se jménem \"%s\".\n" -#: describe.c:3468 +#: describe.c:4218 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "Nelze nalézt žádný fulltextový parser.\n" + +#: describe.c:4293 msgid "Start parse" msgstr "ZaÄátek parsování" -#: describe.c:3469 +#: describe.c:4294 msgid "Method" msgstr "Metoda" -#: describe.c:3473 +#: describe.c:4298 msgid "Get next token" msgstr "Získej další token" -#: describe.c:3475 +#: describe.c:4300 msgid "End parse" msgstr "Konec parsování" -#: describe.c:3477 +#: describe.c:4302 msgid "Get headline" msgstr "Získej záhlaví" -#: describe.c:3479 +#: describe.c:4304 msgid "Get token types" msgstr "Získej typy tokenu" -#: describe.c:3489 +#: describe.c:4315 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Fulltextový parser \"%s.%s\"" -#: describe.c:3491 +#: describe.c:4318 #, c-format msgid "Text search parser \"%s\"" msgstr "Fulltextový parser \"%s\"" -#: describe.c:3509 +#: describe.c:4337 msgid "Token name" msgstr "Jméno tokenu" -#: describe.c:3520 +#: describe.c:4348 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Jméno tokenu pro parser \"%s.%s\"" -#: describe.c:3522 +#: describe.c:4351 #, c-format msgid "Token types for parser \"%s\"" msgstr "Typ tokenu pro parser \"%s\"" -#: describe.c:3571 +#: describe.c:4405 msgid "Template" msgstr "Å ablona" -#: describe.c:3572 +#: describe.c:4406 msgid "Init options" msgstr "Init options" -#: describe.c:3594 +#: describe.c:4428 msgid "List of text search dictionaries" msgstr "Seznam fulltextových slovníků" -#: describe.c:3634 +#: describe.c:4471 msgid "Init" msgstr "Init" -#: describe.c:3635 +#: describe.c:4472 msgid "Lexize" msgstr "Lexize" -#: describe.c:3662 +#: describe.c:4499 msgid "List of text search templates" msgstr "Seznam fulltextových Å¡ablon" -#: describe.c:3719 +#: describe.c:4559 msgid "List of text search configurations" msgstr "Seznam fulltextových konfigurací" -#: describe.c:3763 +#: describe.c:4605 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" msgstr "Nelze nalézt fulltextovou konfiguraci se jménem \"%s\".\n" -#: describe.c:3829 +#: describe.c:4608 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "Nelze nalézt žádnou fulltextovou konfiguraci.\n" + +#: describe.c:4674 msgid "Token" msgstr "Token" -#: describe.c:3830 +#: describe.c:4675 msgid "Dictionaries" msgstr "Slovníky" -#: describe.c:3841 +#: describe.c:4686 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Fulltextová konfigurace \"%s.%s\"" -#: describe.c:3844 +#: describe.c:4689 #, c-format msgid "Text search configuration \"%s\"" msgstr "Fulltextová konfigurace \"%s\"" -#: describe.c:3848 +#: describe.c:4693 #, c-format msgid "" "\n" @@ -1547,7 +2000,7 @@ msgstr "" "\n" "Parser: \"%s.%s\"" -#: describe.c:3851 +#: describe.c:4696 #, c-format msgid "" "\n" @@ -1556,104 +2009,161 @@ msgstr "" "\n" "Parser: \"%s\"" -#: describe.c:3883 +#: describe.c:4730 #, c-format -msgid "The server (version %d.%d) does not support foreign-data wrappers.\n" -msgstr "Server (verze %d.%d) nepodporuje foreign-data wrappery.\n" +msgid "The server (version %s) does not support foreign-data wrappers.\n" +msgstr "Server (verze %s) nepodporuje foreign-data wrappery.\n" -#: describe.c:3897 -msgid "Handler" -msgstr "Handler" - -#: describe.c:3940 +#: describe.c:4788 msgid "List of foreign-data wrappers" msgstr "Seznam foreign-data wrapperů" -#: describe.c:3963 +#: describe.c:4813 #, c-format -msgid "The server (version %d.%d) does not support foreign servers.\n" -msgstr "Server (verze %d.%d) nepodporuje foreign servery.\n" +msgid "The server (version %s) does not support foreign servers.\n" +msgstr "Server (verze %s) nepodporuje foreign servery.\n" -#: describe.c:3975 +#: describe.c:4826 msgid "Foreign-data wrapper" msgstr "Foreign-data wrapper" -#: describe.c:3993 describe.c:4188 +#: describe.c:4844 describe.c:5049 msgid "Version" msgstr "Verze" -#: describe.c:4019 +#: describe.c:4870 msgid "List of foreign servers" msgstr "Seznam foreign serverů" -#: describe.c:4042 +#: describe.c:4895 #, c-format -msgid "The server (version %d.%d) does not support user mappings.\n" -msgstr "Server (verze %d.%d) nepodporuje mapování uživatelů.\n" +msgid "The server (version %s) does not support user mappings.\n" +msgstr "Server (verze %s) nepodporuje mapování uživatelů.\n" -#: describe.c:4051 describe.c:4112 +#: describe.c:4905 describe.c:4969 msgid "Server" msgstr "Server" -#: describe.c:4052 +#: describe.c:4906 msgid "User name" msgstr "Uživatelské jméno" -#: describe.c:4077 +#: describe.c:4931 msgid "List of user mappings" msgstr "Seznam mapování uživatelů" -#: describe.c:4100 +#: describe.c:4956 #, c-format -msgid "The server (version %d.%d) does not support foreign tables.\n" -msgstr "Server (verze %d.%d) nepodporuje foreign tabulky.\n" +msgid "The server (version %s) does not support foreign tables.\n" +msgstr "Server (verze %s) nepodporuje foreign tabulky.\n" -#: describe.c:4151 +#: describe.c:5009 msgid "List of foreign tables" msgstr "Seznam foreign tabulek" -#: describe.c:4174 describe.c:4228 +#: describe.c:5034 describe.c:5091 #, c-format -msgid "The server (version %d.%d) does not support extensions.\n" -msgstr "Server (verze %d.%d) nepodporuje extensions.\n" +msgid "The server (version %s) does not support extensions.\n" +msgstr "Server (verze %s) nepodporuje extensions.\n" -#: describe.c:4205 +#: describe.c:5066 msgid "List of installed extensions" msgstr "Seznam instalovaných extensions" -#: describe.c:4255 +#: describe.c:5119 #, c-format msgid "Did not find any extension named \"%s\".\n" msgstr "Nelze nalézt extension se jménem \"%s\".\n" -#: describe.c:4258 +#: describe.c:5122 #, c-format msgid "Did not find any extensions.\n" msgstr "Nelze nalézt žádnou extension.\n" -#: describe.c:4302 -msgid "Object Description" +#: describe.c:5166 +msgid "Object description" msgstr "Popis objektu" -#: describe.c:4311 +#: describe.c:5176 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objekty v rozšíření \"%s\"" -#: help.c:48 -msgid "off" -msgstr "vypnuto" +#: describe.c:5205 describe.c:5276 +#, c-format +msgid "The server (version %s) does not support publications.\n" +msgstr "Server (verze %s) nepodporuje collations.\n" -#: help.c:48 -msgid "on" -msgstr "zapnuto" +#: describe.c:5222 describe.c:5348 +msgid "All tables" +msgstr "VÅ¡echny tabulky" + +#: describe.c:5223 describe.c:5349 +msgid "Inserts" +msgstr "Insert" + +#: describe.c:5224 describe.c:5350 +msgid "Updates" +msgstr "Update" + +#: describe.c:5225 describe.c:5351 +msgid "Deletes" +msgstr "Delete" -#: help.c:70 +#: describe.c:5229 describe.c:5353 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:5246 +msgid "List of publications" +msgstr "Seznam publikací" + +#: describe.c:5314 #, c-format -msgid "could not get current user name: %s\n" -msgstr "nelze získat aktuální uživatelské jméno: %s\n" +msgid "Did not find any publication named \"%s\".\n" +msgstr "Nelze nalézt publikaci se jménem \"%s\".\n" -#: help.c:82 +#: describe.c:5317 +#, c-format +msgid "Did not find any publications.\n" +msgstr "Nelze nalézt žádnou publikaci.\n" + +#: describe.c:5344 +#, c-format +msgid "Publication %s" +msgstr "Publikace %s" + +#: describe.c:5388 +msgid "Tables:" +msgstr "Tabulky:" + +#: describe.c:5432 +#, c-format +msgid "The server (version %s) does not support subscriptions.\n" +msgstr "Server (verze %s) nepodporuje subskripce.\n" + +#: describe.c:5448 +msgid "Publication" +msgstr "Publikace" + +#: describe.c:5455 +msgid "Synchronous commit" +msgstr "Synchronní commit" + +#: describe.c:5456 +msgid "Conninfo" +msgstr "Spojení" + +#: describe.c:5478 +msgid "List of subscriptions" +msgstr "Seznam subskripcí" + +#: help.c:62 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: help.c:73 #, c-format msgid "" "psql is the PostgreSQL interactive terminal.\n" @@ -1662,12 +2172,12 @@ msgstr "" "psql je PostgreSQL interaktivní terminál.\n" "\n" -#: help.c:83 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" msgstr "Použití:\n" -#: help.c:84 +#: help.c:75 #, c-format msgid "" " psql [OPTION]... [DBNAME [USERNAME]]\n" @@ -1676,12 +2186,12 @@ msgstr "" " psql [PŘEPÃNAÄŒE]... [DATABÃZE [UŽIVATEL]]\n" "\n" -#: help.c:86 +#: help.c:77 #, c-format msgid "General options:\n" msgstr "Základní volby:\n" -#: help.c:91 +#: help.c:82 #, c-format msgid "" " -c, --command=COMMAND run only single command (SQL or internal) and " @@ -1690,44 +2200,47 @@ msgstr "" " -c, --command=PŘÃKAZ provede pouze jeden příkaz (SQL nebo interní) a " "skonÄí\n" -#: help.c:92 +#: help.c:83 #, c-format msgid "" " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" msgstr "" " -d, --dbname=DATABÃZE jméno databáze pro spojení (implicitnÄ›: \"%s\")\n" -#: help.c:93 +#: help.c:84 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" msgstr " -f, --file=SOUBOR provede příkazy ze souboru a skonÄí\n" -#: help.c:94 +#: help.c:85 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr "" " -l, --list vypíše seznam dostupných databází a skonÄí\n" -#: help.c:95 +#: help.c:86 #, c-format msgid "" " -v, --set=, --variable=NAME=VALUE\n" " set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" msgstr "" " -v, --set=, --variable=JMÉNO=HODNOTA\n" -" nastaví psql promÄ›nnou 'JMÉNO' na 'HODNOTA'\n" +" nastaví psql promÄ›nnou JMÉNO na HODNOTA\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +"\n" -#: help.c:97 +#: help.c:89 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version ukáže informace o verzi a skonÄí\n" -#: help.c:98 +#: help.c:90 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" msgstr " -X, --no-psqlrc neÄíst inicializaÄní soubor (~/.psqlrc)\n" -#: help.c:99 +#: help.c:91 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" @@ -1737,12 +2250,22 @@ msgstr "" " -1 (\"jedna\"), --single-transaction\n" " proveÄ operaci v rámci jedné transakce\n" -#: help.c:101 +#: help.c:93 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ukáže tuto nápovÄ›du a skonÄí\n" +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] ukáže tuto nápovÄ›du, a skonÄí\n" -#: help.c:103 +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands vypíše interní příkazy, poté skonÄí\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables vypíše speciální promÄ›nné, poté skonÄí\n" + +#: help.c:97 #, c-format msgid "" "\n" @@ -1751,28 +2274,33 @@ msgstr "" "\n" "Vstupní a výstupní pÅ™epínaÄe:\n" -#: help.c:104 +#: help.c:98 #, c-format msgid " -a, --echo-all echo all input from script\n" msgstr " -a, --echo-all ukáže vÅ¡echny vstupy ze skriptu\n" -#: help.c:105 +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors vypíše příkazy které selhaly\n" + +#: help.c:100 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" msgstr " -e --echo-queries ukáže vÅ¡echny příkazy poslané na server\n" -#: help.c:106 +#: help.c:101 #, c-format msgid "" " -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden ukáže dotazy generované interními příkazy\n" -#: help.c:107 +#: help.c:102 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" msgstr " -L, --log-file=FILENAME uloží záznam sezení do souboru\n" -#: help.c:108 +#: help.c:103 #, c-format msgid "" " -n, --no-readline disable enhanced command line editing (readline)\n" @@ -1780,26 +2308,26 @@ msgstr "" " -n, --no-readline vypne pokroÄilé editaÄní možnosti příkazové řádky " "(podpora readline)\n" -#: help.c:109 +#: help.c:104 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" msgstr "" " -o, --output=SOUBOR zapíše výsledek dotazu do souboru (nebo |roury)\n" -#: help.c:110 +#: help.c:105 #, c-format msgid "" " -q, --quiet run quietly (no messages, only query output)\n" msgstr "" " -q, --quiet tichý chod (bez hlášek, pouze výstupy dotazů)\n" -#: help.c:111 +#: help.c:106 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" msgstr "" " -s, --single-step krokovací mód (nutné potvrzení každého dotazu)\n" -#: help.c:112 +#: help.c:107 #, c-format msgid "" " -S, --single-line single-line mode (end of line terminates SQL " @@ -1808,7 +2336,7 @@ msgstr "" " -S, --single-line jednořádkový mód (konec řádky ukonÄuje SQL " "příkaz)\n" -#: help.c:114 +#: help.c:109 #, c-format msgid "" "\n" @@ -1817,81 +2345,89 @@ msgstr "" "\n" "Výstupní formát je:\n" -#: help.c:115 +#: help.c:110 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align mód nezarovnaného formátu tabulky\n" -#: help.c:116 +#: help.c:111 #, c-format msgid "" " -F, --field-separator=STRING\n" -" set field separator (default: \"%s\")\n" +" field separator for unaligned output (default: " +"\"%s\")\n" msgstr "" " -F, --field-separator=ŘETÄšZEC\n" -" oddÄ›lovaÄ polí (implicitnÄ›: \"%s\")\n" +" oddÄ›lovaÄ polí pro nezarovnaný výstup " +"(implicitnÄ›: \"%s\")\n" -#: help.c:119 +#: help.c:114 #, c-format msgid " -H, --html HTML table output mode\n" -msgstr " -H, --html Mód HTML formátu tabulky\n" +msgstr " -H, --html mód HTML formátu tabulky\n" -#: help.c:120 +#: help.c:115 #, c-format msgid "" " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " "command)\n" msgstr "" -" -P, --pset=VAR[=ARG] nastaví zobrazovací parametr 'VAR' na hodnotu " -"'ARG' (viz. příkaz \\pset)\n" +" -P, --pset=VAR[=ARG] nastaví zobrazovací parametr VAR na hodnotu ARG " +"(viz. příkaz \\pset)\n" -#: help.c:121 +#: help.c:116 #, c-format msgid "" " -R, --record-separator=STRING\n" -" set record separator (default: newline)\n" +" record separator for unaligned output (default: " +"newline)\n" msgstr "" " -R, --record-separator=ŘETÄšZEC\n" -" oddÄ›lovaÄ záznamů (implicitnÄ›: newline)\n" +" oddÄ›lovaÄ záznamů pro nezarovnaný výstup " +"(implicitnÄ›: newline)\n" -#: help.c:123 +#: help.c:118 #, c-format msgid " -t, --tuples-only print rows only\n" -msgstr " -t, --tuples-only tiskne pouze řádky\n" +msgstr " -t, --tuples-only tiskni pouze řádky\n" -#: help.c:124 +#: help.c:119 #, c-format msgid "" " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " "border)\n" msgstr "" -" -T, --table-attr=TEXT nastavení atributů HTML tabulky (napÅ™. width, " +" -T, --table-attr=TEXT nastaví atributy HTML tabulky (napÅ™. width, " "border)\n" -#: help.c:125 +#: help.c:120 #, c-format msgid " -x, --expanded turn on expanded table output\n" -msgstr " -x, --expanded výstupu v rozšířené tabulce\n" +msgstr " -x, --expanded zapne rozšířený tabulkový výstup\n" -#: help.c:126 +#: help.c:121 #, c-format msgid "" " -z, --field-separator-zero\n" -" set field separator to zero byte\n" +" set field separator for unaligned output to zero " +"byte\n" msgstr "" " -z, --field-separator-zero\n" -" nastaví oddÄ›lovaÄ polí na nulový byte\n" +" nastaví oddÄ›lovaÄ polí pro nezarovnaný výstup na " +"nulový byte\n" -#: help.c:128 +#: help.c:123 #, c-format msgid "" " -0, --record-separator-zero\n" -" set record separator to zero byte\n" +" set record separator for unaligned output to zero " +"byte\n" msgstr "" " -0, --record-separator-zero\n" -" nastaví oddÄ›lovaÄ záznamů na nulový byte\n" +" nastaví oddÄ›lovaÄ záznamů pro nezarovnaný výstup " +"na nulový byte\n" -#: help.c:131 +#: help.c:126 #, c-format msgid "" "\n" @@ -1900,7 +2436,7 @@ msgstr "" "\n" "Parametry spojení:\n" -#: help.c:134 +#: help.c:129 #, c-format msgid "" " -h, --host=HOSTNAME database server host or socket directory " @@ -1909,30 +2445,29 @@ msgstr "" " -h, --host=HOSTNAME jméno databázového serveru nebo adresář se " "soketem (implicitnÄ›: \"%s\")\n" -#: help.c:135 +#: help.c:130 msgid "local socket" msgstr "lokální soket" -#: help.c:138 +#: help.c:133 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" msgstr "" -" -p, --port=PORT specifikuje port databázového serveru " -"(implicitnÄ›: \"%s\")\n" +" -p, --port=PORT port databázového serveru (implicitnÄ›: \"%s\")\n" -#: help.c:144 +#: help.c:139 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr "" -" -U, --username=JMÉNO specifikuje jméno databázového uživatele " -"(implicitnÄ›: \"%s\")\n" +" -U, --username=JMÉNO jméno databázového uživatele (implicitnÄ›: \"%s" +"\")\n" -#: help.c:145 +#: help.c:140 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password neptá se na heslo\n" -#: help.c:146 +#: help.c:141 #, c-format msgid "" " -W, --password force password prompt (should happen " @@ -1941,7 +2476,7 @@ msgstr "" " -W, --password vynucený dotaz na heslo (mÄ›l by být proveden " "automaticky)\n" -#: help.c:148 +#: help.c:143 #, c-format msgid "" "\n" @@ -1957,7 +2492,7 @@ msgstr "" "Äásti vÄ›nované psql.\n" "\n" -#: help.c:151 +#: help.c:146 #, c-format msgid "Report bugs to .\n" msgstr "Chyby posílejte na adresu .\n" @@ -1977,43 +2512,102 @@ msgstr "" #: help.c:174 #, c-format msgid "" -" \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" msgstr "" -" \\g [SOUBOR] nebo ; poÅ¡le SQL dotaz na server (a zapíše výsledek do " -"souboru nebo |roury)\n" +" \\crosstabview [SLOUPCE] spustí dotaz a zobrazí výsledek pÅ™es crosstab\n" #: help.c:175 #, c-format msgid "" -" \\gset [PREFIX] execute query and store results in psql variables\n" +" \\errverbose show most recent error message at maximum " +"verbosity\n" msgstr "" -" \\gset [PREFIX] spustí dotaz a uloží výsledky v psql promÄ›nných\n" +" \\errverbose zobrazí polední chybovou hlášku s maximem " +"podrobností\n" #: help.c:176 #, c-format msgid "" -" \\h [NAME] help on syntax of SQL commands, * for all " -"commands\n" +" \\g [FILE] or ; execute query (and send results to file or |pipe)\n" msgstr "" -" \\h [JMÉNO] nápovÄ›da syntaxe SQL příkazů, * pro vÅ¡echny " -"příkazy\n" +" \\g [SOUBOR] nebo ; poÅ¡le SQL dotaz na server (a zapíše výsledek do " +"souboru nebo |roury)\n" #: help.c:177 #, c-format +msgid "" +" \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc popíše výsledek dotazu, bez spuÅ¡tÄ›ní\n" + +#: help.c:178 +#, c-format +msgid "" +" \\gexec execute query, then execute each value in its " +"result\n" +msgstr "" +" \\gexec spustí dotaz, poté spustí každou hodnotu z jeho " +"výsledku\n" + +#: help.c:179 +#, c-format +msgid "" +" \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr "" +" \\gset [PREFIX] spustí dotaz a uloží výsledky v psql promÄ›nných\n" + +#: help.c:180 +#, c-format +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr "" +" \\gx [FILE] jako \\g, ale vynucuje rozšířený mód výstupu\n" + +#: help.c:181 +#, c-format msgid " \\q quit psql\n" msgstr " \\q ukonÄení psql\n" -#: help.c:178 +#: help.c:182 #, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEC] každých SEC vteÅ™in spusÅ¥ dotaz\n" -#: help.c:181 +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "NápovÄ›da\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [commands] zobrazí nápovÄ›du k interním příkazům\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr "" +" \\? options zobrazí nápovÄ›du k psql parametrům psql pro " +"příkazovou řádku\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables zobrazí nápovÄ›du ke speciálním promÄ›nným\n" + +#: help.c:190 +#, c-format +msgid "" +" \\h [NAME] help on syntax of SQL commands, * for all " +"commands\n" +msgstr "" +" \\h [JMÉNO] nápovÄ›da syntaxe SQL příkazů, * pro vÅ¡echny " +"příkazy\n" + +#: help.c:193 #, c-format msgid "Query Buffer\n" msgstr "Paměť dotazu\n" -#: help.c:182 +#: help.c:194 #, c-format msgid "" " \\e [FILE] [LINE] edit the query buffer (or file) with external " @@ -2022,7 +2616,7 @@ msgstr "" " \\e [SOUBOR] [ŘÃDEK] editace aktuálního dotazu (nebo souboru) v " "externím editoru\n" -#: help.c:183 +#: help.c:195 #, c-format msgid "" " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" @@ -2030,49 +2624,56 @@ msgstr "" " \\ef [JMENOFUNKCE [ŘÃDEK]] editace definice funkce v externím " "editoru\n" -#: help.c:184 +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr "" +" \\ev [VIEWNAME [LINE]] editace definice pohledu v externím editoru\n" +"\n" + +#: help.c:197 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p ukázat souÄasný obsah pamÄ›ti s dotazem\n" -#: help.c:185 +#: help.c:198 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r vyprázdnÄ›ní pamÄ›ti s dotazy\n" -#: help.c:187 +#: help.c:200 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [SOUBOR] vytiskne historii nebo ji uloží do souboru\n" -#: help.c:189 +#: help.c:202 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w SOUBOR zapsání pamÄ›ti s dotazem do souboru\n" -#: help.c:192 +#: help.c:205 #, c-format msgid "Input/Output\n" msgstr "Vstup/Výstup\n" -#: help.c:193 +#: help.c:206 #, c-format msgid "" " \\copy ... perform SQL COPY with data stream to the client " "host\n" msgstr " \\copy ... provede SQL COPY s tokem dat na klienta\n" -#: help.c:194 +#: help.c:207 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [TEXT] vypsání textu na standardní výstup\n" -#: help.c:195 +#: help.c:208 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i SOUBOR provedení příkazů ze souboru\n" -#: help.c:196 +#: help.c:209 #, c-format msgid "" " \\ir FILE as \\i, but relative to location of current " @@ -2081,166 +2682,205 @@ msgstr "" " \\ir FILE jako \\i, ale relativnÄ› k pozici v aktuálním " "skriptu\n" -#: help.c:197 +#: help.c:210 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr "" " \\o [SOUBOR] pÅ™esmÄ›rování výsledků dotazu do souboru nebo |" "roury\n" -#: help.c:198 +#: help.c:211 #, c-format msgid "" " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr " \\qecho [ŘETÄšZEC] vypsání textu na výstup dotazů (viz. \\o)\n" -#: help.c:201 +#: help.c:214 +#, c-format +msgid "Conditional\n" +msgstr "Podmínka\n" + +#: help.c:215 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR zaÄne podmínÄ›ný blok\n" + +#: help.c:216 +#, c-format +msgid "" +" \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR alternativa v souÄasném podmínÄ›ném bloku\n" + +#: help.c:217 +#, c-format +msgid "" +" \\else final alternative within current conditional " +"block\n" +msgstr "" +" \\else poslední alternativa v souÄasném podmínÄ›ném bloku\n" + +#: help.c:218 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif ukonÄí podmínÄ›ný blok\n" + +#: help.c:221 #, c-format msgid "Informational\n" msgstr "InformaÄní\n" -#: help.c:202 +#: help.c:222 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (volby: S = zobraz systémové objekty, + = další detaily)\n" -#: help.c:203 +#: help.c:223 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] seznam tabulek, pohledů a sekvencí\n" -#: help.c:204 +#: help.c:224 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr "" " \\d[S+] JMÉNO popis tabulky, pohledů, sekvence nebo indexu\n" -#: help.c:205 +#: help.c:225 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [VZOR] seznam agregaÄních funkcí\n" -#: help.c:206 +#: help.c:226 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATTERN] seznam přístupových metod\n" + +#: help.c:227 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [VZOR] seznam tablespaces\n" -#: help.c:207 +#: help.c:228 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [PATTERN] seznam konverzí\n" -#: help.c:208 +#: help.c:229 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [PATTERN] seznam pÅ™etypování\n" -#: help.c:209 +#: help.c:230 #, c-format msgid "" " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr " \\dd[S] [PATTERN] zobrazí popis objektů nezobrazených jinde\n" -#: help.c:210 +#: help.c:231 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] seznam domén\n" + +#: help.c:232 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [VZOR] seznam implicitních privilegií\n" -#: help.c:211 +#: help.c:233 #, c-format -msgid " \\dD[S+] [PATTERN] list domains\n" -msgstr " \\dD[S+] [PATTERN] seznam domén\n" +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [VZOR] seznam foreign tabulek\n" -#: help.c:212 +#: help.c:234 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [VZOR] seznam foreign tabulek\n" -#: help.c:213 +#: help.c:235 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [VZOR] seznam foreign serverů\n" -#: help.c:214 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [VZOR] seznam mapování uživatelů\n" -#: help.c:215 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [VZOR] seznam foreign-data wrapperů\n" -#: help.c:216 +#: help.c:238 #, c-format msgid "" " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" msgstr "" " \\df[antw][S+] [VZOR] seznam [pouze agg/normal/trigger/window] funkcí\n" -#: help.c:217 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr "" " \\dF[+] [VZOR] seznam konfigurací fulltextového vyhledávání\n" -#: help.c:218 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [VZOR] seznam slovníků fulltextového vyhledávání\n" -#: help.c:219 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [VZOR] seznam parserů fulltextového vyhledávání\n" -#: help.c:220 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [VZOR] seznam Å¡ablon fulltextového vyhledávání\n" -#: help.c:221 +#: help.c:243 #, c-format -msgid " \\dg[+] [PATTERN] list roles\n" -msgstr " \\dg[+] [VZOR] seznam rolí\n" +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATTERN] seznam rolí\n" -#: help.c:222 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [VZOR] seznam indexů\n" -#: help.c:223 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr "" " \\dl seznam \"large object\" stejné jako \\lo_list\n" -#: help.c:224 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [VZOR] seznam procedurálních jazyků\n" -#: help.c:225 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [PATTERN] seznam materializovaných pohledů\n" -#: help.c:226 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [VZOR] seznam schémat\n" -#: help.c:227 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [VZOR] seznam operátorů\n" -#: help.c:228 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [VZOR] seznam collations\n" -#: help.c:229 +#: help.c:251 #, c-format msgid "" " \\dp [PATTERN] list table, view, and sequence access privileges\n" @@ -2248,73 +2888,83 @@ msgstr "" " \\dp [VZOR] seznam přístupových práv tabulek, pohledů a " "sekvencí\n" -#: help.c:230 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr "" " \\drds [VZOR1 [VZOR2]] seznam nastavení rolí pro jednotlivé databáze\n" -#: help.c:231 +#: help.c:253 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] seznam replikaÄních publikací\n" + +#: help.c:254 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] seznam replikaÄních subskripcí\n" + +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [VZOR] seznam sekvencí\n" -#: help.c:232 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [VZOR] seznam tabulek\n" -#: help.c:233 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [VZOR] seznam datových typů\n" -#: help.c:234 +#: help.c:258 #, c-format -msgid " \\du[+] [PATTERN] list roles\n" -msgstr " \\du[+] [VZOR] seznam rolí (uživatelů)\n" +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATTERN] seznam rolí\n" -#: help.c:235 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [VZOR] seznam pohledů\n" -#: help.c:236 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [VZOR] seznam foreign tabulek\n" - -#: help.c:237 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [VZOR] seznam rozšíření\n" -#: help.c:238 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [PATTERN] seznam event triggerů\n" -#: help.c:239 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [PATTERN] seznam databází\n" -#: help.c:240 +#: help.c:263 #, c-format -msgid " \\sf[+] FUNCNAME show a function's definition\n" -msgstr " \\sf[+] [JMENOFUNKCE] zobrazí definici funkce\n" +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNCNAME zobrazí definici funkce\n" -#: help.c:241 +#: help.c:264 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VIEWNAME zobrazí definici pohledu\n" + +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [VZOR] stejné jako \\dp\n" -#: help.c:244 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "Formátování\n" -#: help.c:245 +#: help.c:269 #, c-format msgid "" " \\a toggle between unaligned and aligned output mode\n" @@ -2322,14 +2972,14 @@ msgstr "" " \\a pÅ™epíná mezi 'unaligned' a 'aligned' modem " "výstupu\n" -#: help.c:246 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr "" " \\C [ŘETÄšZEC] nastaví titulek tabulky nebo odnastaví pokud není " "definován Å™etÄ›zec\n" -#: help.c:247 +#: help.c:271 #, c-format msgid "" " \\f [STRING] show or set field separator for unaligned query " @@ -2338,103 +2988,111 @@ msgstr "" " \\f [ŘETÄšZEC] nastaví nebo zobrazí oddÄ›lovaÄe polí pro " "nezarovnaný výstup dotazů\n" -#: help.c:248 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H zapne HTML mód výstupu (nyní %s)\n" -#: help.c:250 +#: help.c:274 #, c-format msgid "" -" \\pset NAME [VALUE] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager})\n" +" \\pset [NAME [VALUE]] set table output option\n" +" (NAME := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" +"unicode_header_linestyle})\n" msgstr "" -" \\pset NAME [VALUE] nastaví typ výpisu tabulek\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager})\n" - -#: help.c:253 +" \\pset [NAME [VALUE]] nastaví typ výpisu tabulek\n" +" (NAME := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" +"unicode_header_linestyle})\n" + +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] ukazovat pouze řádky (nyní %s)\n" -#: help.c:255 +#: help.c:282 #, c-format msgid "" " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr " \\T [ŘETĚZEC] nastavení atributů HTML tagu
\n" -#: help.c:256 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] zapne rozšířený mód výstupu (nyní %s)\n" -#: help.c:260 +#: help.c:287 #, c-format msgid "Connection\n" msgstr "Spojení\n" -#: help.c:262 +#: help.c:289 #, c-format msgid "" -" \\c[onnect] [DBNAME|- USER|- HOST|- PORT|-]\n" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently \"%s\")\n" msgstr "" -" \\c[onnect] [DATABÃZE|- UŽIVATEL|- HOST|- PORT|-]]\n" -" vytvoří spojení do nové databáze (souÄasná \"%s\")\n" +" \\c[onnect] [DATABÃZE|- UŽIVATEL|- HOST|- PORT|-] | conninfo]\n" +" pÅ™ipojí se do nové databáze (souÄasná \"%s\")\n" -#: help.c:266 +#: help.c:293 #, c-format msgid "" -" \\c[onnect] [DBNAME|- USER|- HOST|- PORT|-]\n" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently no connection)\n" msgstr "" -" \\c[onnect] [DATABÃZE|- UŽIVATEL|- HOST|- PORT|-]]\n" -" vytvoří spojení do nové databáze (souÄasnÄ› žádné " +" \\c[onnect] [DATABÃZE|- UŽIVATEL|- HOST|- PORT|-] | conninfo]\n" +" pÅ™ipojí se do nové databáze (souÄasnÄ› žádné " "spojení)\n" -#: help.c:268 +#: help.c:295 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo zobrazí informace o aktuálním spojení\n" + +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [KÓDOVÃNÃ] zobrazení nebo nastavení kódování klienta\n" -#: help.c:269 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [UŽIVATEL] bezpeÄná zmÄ›na hesla uživatele\n" -#: help.c:270 -#, c-format -msgid "" -" \\conninfo display information about current connection\n" -msgstr " \\conninfo zobrazí informace o aktuálním spojení\n" - -#: help.c:273 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "OperaÄní systém\n" -#: help.c:274 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [ADRESÃŘ] zmÄ›na aktuálního pracovního adresář\n" -#: help.c:275 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAME [VALUE] nastaví nebo zruší promÄ›nnou prostÅ™edí\n" -#: help.c:276 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] použít sledování Äasu u příkazů (nyní %s)\n" -#: help.c:278 +#: help.c:305 #, c-format msgid "" " \\! [COMMAND] execute command in shell or start interactive " @@ -2443,18 +3101,18 @@ msgstr "" " \\! [PŘÃKAZ] provedení příkazu v shellu nebo nastartuje " "interaktivní shell\n" -#: help.c:281 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "PromÄ›nné\n" -#: help.c:282 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr "" " \\prompt [TEXT] PROMÄšNà vyzve uživatele, aby zadal hodnotu promÄ›nné\n" -#: help.c:283 +#: help.c:310 #, c-format msgid "" " \\set [NAME [VALUE]] set internal variable, or list all if no " @@ -2465,17 +3123,17 @@ msgstr "" "zobrazí\n" " seznam vÅ¡ech promÄ›nných\n" -#: help.c:284 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset JMÉNO zruÅ¡ení interní promÄ›nné\n" -#: help.c:287 +#: help.c:314 #, c-format msgid "Large Objects\n" msgstr "Velké objekty (LO)\n" -#: help.c:288 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2488,82 +3146,783 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID operace s \"large\" objekty\n" -#: help.c:335 -msgid "Available help:\n" -msgstr "Dostupná nápovÄ›da:\n" - -#: help.c:419 +#: help.c:342 #, c-format msgid "" -"Command: %s\n" -"Description: %s\n" -"Syntax:\n" -"%s\n" +"List of specially treated variables\n" "\n" msgstr "" -"Příkaz: %s\n" -"Popis: %s\n" -"Syntaxe:\n" -"%s\n" +"Seznam promÄ›nných se zvláštním významem\n" "\n" -#: help.c:435 +#: help.c:344 +#, c-format +msgid "psql variables:\n" +msgstr "psql promÄ›nné:\n" + +#: help.c:346 #, c-format msgid "" -"No help available for \"%s\".\n" -"Try \\h with no arguments to see available help.\n" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" msgstr "" -"NápovÄ›da pro \"%s\" je nedostupná.\n" -"Pomocí \\h bez parametrů lze získat seznam dostupných nápovÄ›d.\n" +" psql --set=NAME=VALUE\n" +" nebo \\set NAME VALUE v psql\n" +"\n" -#: input.c:193 +#: help.c:348 #, c-format -msgid "could not read from input file: %s\n" -msgstr "nelze Äíst vstupní soubor: %s\n" +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" pokud nastaveno, úspěšnÄ› dokonÄené SQL příkazy jsou automaticky " +"commitovány\n" -#: input.c:407 +#: help.c:350 #, c-format -msgid "could not save history to file \"%s\": %s\n" -msgstr "nelze uložit historii do souboru \"%s\": %s\n" +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" urÄuje velikost písmen pro dokonÄování SQL klíÄových slov\n" +" [lower, upper, preserve-lower, preserve-upper]\n" -#: input.c:412 +#: help.c:353 #, c-format -msgid "history is not supported by this installation\n" -msgstr "historie není podporována pro tuto instalaci\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" název aktuálnÄ› pÅ™ipojené databáze\n" -#: large_obj.c:66 +#: help.c:355 #, c-format -msgid "%s: not connected to a database\n" -msgstr "%s: není spojení s databází\n" +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" urÄuje jaký vstup je zapisován na standardní výstup\n" +" [all, errors, none, queries]\n" -#: large_obj.c:85 +#: help.c:358 #, c-format -msgid "%s: current transaction is aborted\n" -msgstr "%s: souÄasná transakce je nestandardnÄ› ukonÄena (abort)\n" +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" pokud je nastaveno, zobrazuje dotazy spouÅ¡tÄ›né interními (backslash) " +"příkazy;\n" +" pÅ™i nastavení na \"noexec\", pouze zobrazí bez spuÅ¡tÄ›ní\n" -#: large_obj.c:88 +#: help.c:361 #, c-format -msgid "%s: unknown transaction status\n" -msgstr "%s: neznámý status transakce\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuální kódování znakové sady klienta\n" -#: large_obj.c:289 large_obj.c:300 +#: help.c:363 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" nastaveno na true pokud poslední dotaz selhal, jinak false\n" + +#: help.c:365 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = " +"unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" poÄet řádek výsledku pro naÄtení a zobrazení nanjednou (0 = unlimited)\n" + +#: help.c:367 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" nastavuje chování historie příkazů [ignorespace, ignoredups, " +"ignoreboth]\n" + +#: help.c:369 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" název souboru pro uložení historie příkazů\n" + +#: help.c:371 +#, c-format +msgid "" +" HISTSIZE\n" +" max number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximální poÄet položek uložených v historii pÅ™kazů\n" + +#: help.c:373 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" databázový server ke kterému jste aktuálnÄ› pÅ™ipojeni\n" + +#: help.c:375 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" poÄet EOF znaků potÅ™ebných pro ukonÄení interaktivníhi sezení\n" + +#: help.c:377 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" hodnota posledního zmÄ›nÄ›ného OID\n" + +#: help.c:379 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if " +"none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" zpráva a SQLSTATE poslední chyby, nebo prázdný Å™etÄ›zec a \"00000\" pokud " +"se chyba nevyskytla\n" + +#: help.c:382 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" pokud nastaveno, chyba nepÅ™eruší transakci (používá implicitní " +"savepointy)\n" + +#: help.c:384 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" zastaví dávkové spouÅ¡tÄ›ní v případÄ› výskytu chyby\n" + +#: help.c:386 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" port na serveru používaný aktuálním spojením\n" + +#: help.c:388 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" specifikuje standardní psql prompt\n" + +#: help.c:390 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous " +"line\n" +msgstr "" +" PROMPT2\n" +" specifikuje prompt používaný pokud příkaz pokraÄuje z pÅ™edchozí řádky\n" + +#: help.c:392 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" specifikuje prompt používaný bÄ›hem COPY ... FROM STDIN\n" + +#: help.c:394 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" tichý bÄ›h (stejné jako volba -q)\n" + +#: help.c:396 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" poÄet řádek vrácených nebo ovlivnÄ›ných pÅ™edchozím dotazem, nebo 0\n" + +#: help.c:398 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" verze serveru (v krátkém textovém nebo numerickém formátu)\n" + +#: help.c:401 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" urÄuje zobrazení informací o kontextu zpráv [never, errors, always]\n" + +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" pokud nastaveno, konec řádky ukonÄuje SQL příkazy (stejné jako volba -" +"S)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" single-step mód (stejné jako volba -s)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE posledního dotazu, nebo \"00000\" pokud skonÄil bez chyby\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" uživatelský úÄet ke kterému jste aktuálnÄ› pÅ™ipojeni\n" + +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" urÄuje podrobnost chybových hlášení [default, verbose, terse]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" verze psql (v podropbném Å™etÄ›zci, krátkém Å™etÄ›zci, nebo numerickém " +"formátu)\n" + +#: help.c:418 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Nastavení zobrazení:\n" + +#: help.c:420 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAME[=VALUE]\n" +" nebo \\pset NAME [VALUE] v psql\n" +"\n" + +#: help.c:422 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" styl rámeÄků (Äíslo)\n" + +#: help.c:424 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" cílová šířka pro zalomený formát\n" + +#: help.c:426 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (nebo x)\n" +" rozšířený výstup [on, off, auto]\n" + +#: help.c:428 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" oddÄ›lovaÄ položek pro nezarovnaný výstup (výchozí \"%s\")\n" + +#: help.c:431 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" nastaví oddÄ›lovaÄ polí pro nezarovnaný výstup na nulový byte\n" + +#: help.c:433 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" zapne nebo vypne zobrazení zápatí tabulky [on, off]\n" + +#: help.c:435 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" nastaví formát výstupu [unaligned, aligned, wrapped, html, " +"asciidoc, ...]\n" + +#: help.c:437 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestype\n" +" nastaví styl vykreslování rámeÄků [ascii, old-ascii, unicode]\n" + +#: help.c:439 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" nastaví Å™etÄ›zec vypisovaný místo null hodnoty\n" + +#: help.c:441 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of " +"digits\n" +msgstr "" +" numericlocale\n" +" zapne zobrazení lokalizovaného znaku pro oddÄ›lení skupin Äíslic\n" + +#: help.c:443 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" urÄuje kdy se použije externí pager [yes, no, always]\n" + +#: help.c:445 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" oddÄ›lovaÄ záznamů (řádek) pro nezarovnaný výstup\n" + +#: help.c:447 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" nastaví oddÄ›lovaÄ záznamů pro nezarovnaný výstup na nulový byte\n" + +#: help.c:449 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (or T)\n" +" specifikuje attributy pro table tag v html formátu, nebo proporcionální\n" +" šířky sloupců pro datové typy zarovnávané doleva v latex-longtable " +"formátu\n" + +#: help.c:452 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" nastavuje titulek tabulky pro následnÄ› vypisované tabulky\n" + +#: help.c:454 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" pokud nastaveno, jsou vypsána pouze data z tabulky\n" + +#: help.c:456 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" nastaví styl Unicode rámeÄků [single, double]\n" + +#: help.c:461 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"PromÄ›nné prostÅ™edí:\n" + +#: help.c:465 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" nebo \\setenv NAME [VALUE] v rámci psql\n" +"\n" + +#: help.c:467 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAME=VALUE\n" +" psql ...\n" +" nebo \\setenv NAME [VALUE] v rámci psql\n" +"\n" + +#: help.c:470 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" poÄet sloupců pro zalamovaný formát\n" + +#: help.c:472 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" stejné jako application_name v parametrech spojení\n" + +#: help.c:474 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" stejné jako dbname v parametrech spojení\n" + +#: help.c:476 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" stejné jako host v parametrech spojení\n" + +#: help.c:478 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" heslo pro spojení (nedoporuÄuje se)\n" + +#: help.c:480 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" jméno souboru s hesly\n" + +#: help.c:482 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" stejné jako port v parametrech spojení\n" + +#: help.c:484 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" stejné jako user v parametrech spojení\n" + +#: help.c:486 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor používaný příkazy \\e, \\ef, a \\ev\n" + +#: help.c:488 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" jak specifikovat Äíslo řádky pÅ™i spouÅ¡tÄ›ní editoru\n" + +#: help.c:490 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativní umístÄ›ní pro soubor s historií příkazů\n" + +#: help.c:492 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" jméno externího stránkovacího programu (pageru)\n" + +#: help.c:494 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativní umístÄ›ní uživatelova .psqlrc souboru\n" + +#: help.c:496 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell používaný \\! příkazem\n" + +#: help.c:498 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" adresář pro doÄasné soubory\n" + +#: help.c:542 +msgid "Available help:\n" +msgstr "Dostupná nápovÄ›da:\n" + +#: help.c:626 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +msgstr "" +"Příkaz: %s\n" +"Popis: %s\n" +"Syntaxe:\n" +"%s\n" +"\n" + +#: help.c:642 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"NápovÄ›da pro \"%s\" je nedostupná.\n" +"Pomocí \\h bez parametrů lze získat seznam dostupných nápovÄ›d.\n" + +#: input.c:216 +#, c-format +msgid "could not read from input file: %s\n" +msgstr "nelze Äíst vstupní soubor: %s\n" + +#: input.c:471 input.c:510 +#, c-format +msgid "could not save history to file \"%s\": %s\n" +msgstr "nelze uložit historii do souboru \"%s\": %s\n" + +#: input.c:530 +#, c-format +msgid "history is not supported by this installation\n" +msgstr "historie není podporována pro tuto instalaci\n" + +#: large_obj.c:64 +#, c-format +msgid "%s: not connected to a database\n" +msgstr "%s: není spojení s databází\n" + +#: large_obj.c:83 +#, c-format +msgid "%s: current transaction is aborted\n" +msgstr "%s: souÄasná transakce je nestandardnÄ› ukonÄena (abort)\n" + +#: large_obj.c:86 +#, c-format +msgid "%s: unknown transaction status\n" +msgstr "%s: neznámý status transakce\n" + +#: large_obj.c:287 large_obj.c:298 msgid "ID" msgstr "ID" -#: large_obj.c:310 +#: large_obj.c:308 msgid "Large objects" msgstr "Velké objekty (LO)" -#: mainloop.c:159 +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped\n" +msgstr "\\if: escapované\n" + +#: mainloop.c:183 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "Použijte \"\\q\" pro odchod z %s.\n" -#: mainloop.c:189 +#: mainloop.c:205 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Na vstupu je dump v PostgreSQL \"custom\" formátu.\n" +"Pro obnovení této zálohy použijte klienta pg_restore pro příkazovou řádku.\n" + +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "" +"Použijte \\? pro nápovÄ›du nebo stisknÄ›te control-C pro vymazání vstupního " +"bufferu." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Pro zobrazení nápovÄ›dy použijte \"\\?\"." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Používáte psql, řádkový nástroj pro pÅ™ipojení k PostgreSQL." -#: mainloop.c:190 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -2578,1812 +3937,2235 @@ msgstr "" " \\g nebo stÅ™edník pro ukonÄení SQL příkazů\n" " \\q pro ukonÄení programu\n" -#: print.c:272 -#, c-format -msgid "(%lu row)" -msgid_plural "(%lu rows)" -msgstr[0] "(%lu řádka)" -msgstr[1] "(%lu řádky)" -msgstr[2] "(%lu řádek)" - -#: print.c:1175 -#, c-format -msgid "(No rows)\n" -msgstr "(Žádné řádky)\n" +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Použijte \\q pro ukonÄení." -#: print.c:2239 -#, c-format -msgid "Interrupted\n" -msgstr "PÅ™eruÅ¡eno\n" +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Použijte control-D pro ukonÄení." -#: print.c:2305 -#, c-format -msgid "Cannot add header to table content: column count of %d exceeded.\n" -msgstr "Nelze pÅ™idat hlaviÄku k obsahu tabulky: pÅ™ekroÄen poÄet sloupců %d.\n" +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Použijte control-C pro ukonÄení." -#: print.c:2345 +#: mainloop.c:449 mainloop.c:591 #, c-format -msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "" -"Nelze pÅ™idat buňku do obsahu tabulky: pÅ™ekroÄen celkový poÄet bunÄ›k %d.\n" +"dotaz ignorován; použijte \\endif nebo Ctrl-C pro ukonÄení aktuálního \\if " +"bloku\n" -#: print.c:2571 +#: mainloop.c:609 #, c-format -msgid "invalid output format (internal error): %d" -msgstr "specifikován neplatný formát výstupu (interní chyba): %d" +msgid "reached EOF without finding closing \\endif(s)\n" +msgstr "dosažen EOF bez nalezení ukonÄujícího \\endif(s)\n" -#: psqlscan.l:726 -#, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" -msgstr "pÅ™eskakuji rekursivní expanzi promÄ›nné \"%s\"\n" - -#: psqlscan.l:1601 +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" msgstr "neukonÄený Å™etÄ›zec v uvozovkách\n" -#: psqlscan.l:1701 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" msgstr "%s: nedostatek pamÄ›ti\n" -#: psqlscan.l:1930 -#, c-format -msgid "can't escape without active connection\n" -msgstr "nelze escapovat bez aktivního spojení\n" - -#: sql_help.c:26 sql_help.c:29 sql_help.c:32 sql_help.c:44 sql_help.c:46 -#: sql_help.c:48 sql_help.c:59 sql_help.c:61 sql_help.c:63 sql_help.c:87 -#: sql_help.c:91 sql_help.c:93 sql_help.c:95 sql_help.c:97 sql_help.c:100 -#: sql_help.c:102 sql_help.c:104 sql_help.c:197 sql_help.c:199 sql_help.c:200 -#: sql_help.c:202 sql_help.c:204 sql_help.c:207 sql_help.c:209 sql_help.c:211 -#: sql_help.c:213 sql_help.c:225 sql_help.c:226 sql_help.c:227 sql_help.c:229 -#: sql_help.c:268 sql_help.c:270 sql_help.c:272 sql_help.c:274 sql_help.c:322 -#: sql_help.c:327 sql_help.c:329 sql_help.c:360 sql_help.c:362 sql_help.c:365 -#: sql_help.c:367 sql_help.c:420 sql_help.c:425 sql_help.c:430 sql_help.c:435 -#: sql_help.c:473 sql_help.c:475 sql_help.c:477 sql_help.c:480 sql_help.c:490 -#: sql_help.c:492 sql_help.c:530 sql_help.c:532 sql_help.c:535 sql_help.c:537 -#: sql_help.c:562 sql_help.c:566 sql_help.c:579 sql_help.c:582 sql_help.c:585 -#: sql_help.c:605 sql_help.c:617 sql_help.c:625 sql_help.c:628 sql_help.c:631 -#: sql_help.c:661 sql_help.c:667 sql_help.c:669 sql_help.c:673 sql_help.c:676 -#: sql_help.c:679 sql_help.c:688 sql_help.c:699 sql_help.c:701 sql_help.c:718 -#: sql_help.c:727 sql_help.c:729 sql_help.c:731 sql_help.c:743 sql_help.c:747 -#: sql_help.c:749 sql_help.c:810 sql_help.c:812 sql_help.c:815 sql_help.c:818 -#: sql_help.c:820 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:885 -#: sql_help.c:906 sql_help.c:909 sql_help.c:912 sql_help.c:915 sql_help.c:919 -#: sql_help.c:921 sql_help.c:923 sql_help.c:925 sql_help.c:939 sql_help.c:942 -#: sql_help.c:944 sql_help.c:946 sql_help.c:956 sql_help.c:958 sql_help.c:968 -#: sql_help.c:970 sql_help.c:979 sql_help.c:1000 sql_help.c:1002 -#: sql_help.c:1004 sql_help.c:1007 sql_help.c:1009 sql_help.c:1011 -#: sql_help.c:1049 sql_help.c:1055 sql_help.c:1057 sql_help.c:1060 -#: sql_help.c:1062 sql_help.c:1064 sql_help.c:1091 sql_help.c:1094 -#: sql_help.c:1096 sql_help.c:1098 sql_help.c:1100 sql_help.c:1102 -#: sql_help.c:1105 sql_help.c:1145 sql_help.c:1336 sql_help.c:1344 -#: sql_help.c:1388 sql_help.c:1392 sql_help.c:1402 sql_help.c:1420 -#: sql_help.c:1443 sql_help.c:1461 sql_help.c:1489 sql_help.c:1548 -#: sql_help.c:1590 sql_help.c:1612 sql_help.c:1632 sql_help.c:1633 -#: sql_help.c:1668 sql_help.c:1688 sql_help.c:1710 sql_help.c:1738 -#: sql_help.c:1759 sql_help.c:1794 sql_help.c:1975 sql_help.c:1988 -#: sql_help.c:2005 sql_help.c:2021 sql_help.c:2044 sql_help.c:2095 -#: sql_help.c:2099 sql_help.c:2101 sql_help.c:2107 sql_help.c:2125 -#: sql_help.c:2152 sql_help.c:2186 sql_help.c:2198 sql_help.c:2207 -#: sql_help.c:2251 sql_help.c:2269 sql_help.c:2277 sql_help.c:2285 -#: sql_help.c:2293 sql_help.c:2301 sql_help.c:2309 sql_help.c:2317 -#: sql_help.c:2325 sql_help.c:2334 sql_help.c:2345 sql_help.c:2353 -#: sql_help.c:2361 sql_help.c:2369 sql_help.c:2377 sql_help.c:2387 -#: sql_help.c:2396 sql_help.c:2405 sql_help.c:2413 sql_help.c:2421 -#: sql_help.c:2430 sql_help.c:2438 sql_help.c:2446 sql_help.c:2454 -#: sql_help.c:2462 sql_help.c:2470 sql_help.c:2478 sql_help.c:2486 -#: sql_help.c:2494 sql_help.c:2502 sql_help.c:2511 sql_help.c:2519 -#: sql_help.c:2536 sql_help.c:2551 sql_help.c:2757 sql_help.c:2808 -#: sql_help.c:2836 sql_help.c:2844 sql_help.c:3214 sql_help.c:3262 -#: sql_help.c:3370 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 msgid "name" msgstr "jméno" -#: sql_help.c:27 sql_help.c:30 sql_help.c:33 sql_help.c:290 sql_help.c:423 -#: sql_help.c:428 sql_help.c:433 sql_help.c:438 sql_help.c:1218 -#: sql_help.c:1551 sql_help.c:2252 sql_help.c:2337 sql_help.c:3061 -msgid "argtype" -msgstr "typ_argumentu" - -#: sql_help.c:28 sql_help.c:45 sql_help.c:60 sql_help.c:92 sql_help.c:212 -#: sql_help.c:230 sql_help.c:330 sql_help.c:366 sql_help.c:429 sql_help.c:462 -#: sql_help.c:474 sql_help.c:491 sql_help.c:536 sql_help.c:581 sql_help.c:627 -#: sql_help.c:668 sql_help.c:690 sql_help.c:700 sql_help.c:730 sql_help.c:750 -#: sql_help.c:819 sql_help.c:879 sql_help.c:922 sql_help.c:943 sql_help.c:957 -#: sql_help.c:969 sql_help.c:981 sql_help.c:1008 sql_help.c:1056 -#: sql_help.c:1099 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 +msgid "aggregate_signature" +msgstr "aggregate_signature" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "nové_jméno" -#: sql_help.c:31 sql_help.c:47 sql_help.c:62 sql_help.c:94 sql_help.c:210 -#: sql_help.c:228 sql_help.c:328 sql_help.c:391 sql_help.c:434 sql_help.c:493 -#: sql_help.c:502 sql_help.c:552 sql_help.c:565 sql_help.c:584 sql_help.c:630 -#: sql_help.c:702 sql_help.c:728 sql_help.c:748 sql_help.c:863 sql_help.c:881 -#: sql_help.c:924 sql_help.c:945 sql_help.c:1003 sql_help.c:1097 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "nový_vlastník" -#: sql_help.c:34 sql_help.c:49 sql_help.c:64 sql_help.c:214 sql_help.c:271 -#: sql_help.c:368 sql_help.c:439 sql_help.c:538 sql_help.c:569 sql_help.c:587 -#: sql_help.c:633 sql_help.c:732 sql_help.c:821 sql_help.c:926 sql_help.c:947 -#: sql_help.c:959 sql_help.c:971 sql_help.c:1010 sql_help.c:1101 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "nové_schéma" -#: sql_help.c:88 sql_help.c:325 sql_help.c:389 sql_help.c:392 sql_help.c:662 -#: sql_help.c:745 sql_help.c:940 sql_help.c:1050 sql_help.c:1076 -#: sql_help.c:1293 sql_help.c:1299 sql_help.c:1492 sql_help.c:1516 -#: sql_help.c:1521 sql_help.c:1591 sql_help.c:1739 sql_help.c:1815 -#: sql_help.c:1990 sql_help.c:2153 sql_help.c:2175 sql_help.c:2570 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 +msgid "where aggregate_signature is:" +msgstr "kde aggregate_signature je:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 +msgid "argmode" +msgstr "mód_argumentu" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 +msgid "argname" +msgstr "jméno_argumentu" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 +msgid "argtype" +msgstr "typ_argumentu" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "volba" -#: sql_help.c:89 sql_help.c:663 sql_help.c:1051 sql_help.c:1592 -#: sql_help.c:1740 sql_help.c:2154 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" msgstr "kde volba může být:" -#: sql_help.c:90 sql_help.c:664 sql_help.c:1052 sql_help.c:1427 -#: sql_help.c:1741 sql_help.c:2155 +#: sql_help.c:114 sql_help.c:2118 +msgid "allowconn" +msgstr "allowconn" + +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" msgstr "connlimit" -#: sql_help.c:96 sql_help.c:553 sql_help.c:864 +#: sql_help.c:116 sql_help.c:2120 +msgid "istemplate" +msgstr "istemplate" + +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "nový_tablespace" -#: sql_help.c:98 sql_help.c:101 sql_help.c:103 sql_help.c:443 sql_help.c:445 -#: sql_help.c:446 sql_help.c:671 sql_help.c:675 sql_help.c:678 sql_help.c:1058 -#: sql_help.c:1061 sql_help.c:1063 sql_help.c:1559 sql_help.c:2861 -#: sql_help.c:3203 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" msgstr "konfiguraÄní_parametr" -#: sql_help.c:99 sql_help.c:326 sql_help.c:385 sql_help.c:390 sql_help.c:393 -#: sql_help.c:444 sql_help.c:479 sql_help.c:544 sql_help.c:550 sql_help.c:672 -#: sql_help.c:746 sql_help.c:840 sql_help.c:858 sql_help.c:884 sql_help.c:941 -#: sql_help.c:1059 sql_help.c:1077 sql_help.c:1493 sql_help.c:1517 -#: sql_help.c:1522 sql_help.c:1560 sql_help.c:1561 sql_help.c:1620 -#: sql_help.c:1652 sql_help.c:1816 sql_help.c:1890 sql_help.c:1898 -#: sql_help.c:1930 sql_help.c:1952 sql_help.c:1991 sql_help.c:2176 -#: sql_help.c:3204 sql_help.c:3205 +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "hodnota" -#: sql_help.c:161 +#: sql_help.c:197 msgid "target_role" msgstr "cílová_role" -#: sql_help.c:162 sql_help.c:1476 sql_help.c:1776 sql_help.c:1781 -#: sql_help.c:2677 sql_help.c:2684 sql_help.c:2698 sql_help.c:2704 -#: sql_help.c:2956 sql_help.c:2963 sql_help.c:2977 sql_help.c:2983 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "jméno_schématu" -#: sql_help.c:163 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "zkrácený_grant_nebo_revoke" -#: sql_help.c:164 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "kde zkrácený_grant_nebo_revoke je jedno z:" -#: sql_help.c:165 sql_help.c:166 sql_help.c:167 sql_help.c:168 sql_help.c:169 -#: sql_help.c:170 sql_help.c:171 sql_help.c:172 sql_help.c:1595 -#: sql_help.c:1596 sql_help.c:1597 sql_help.c:1598 sql_help.c:1599 -#: sql_help.c:1744 sql_help.c:1745 sql_help.c:1746 sql_help.c:1747 -#: sql_help.c:1748 sql_help.c:2158 sql_help.c:2159 sql_help.c:2160 -#: sql_help.c:2161 sql_help.c:2162 sql_help.c:2678 sql_help.c:2682 -#: sql_help.c:2685 sql_help.c:2687 sql_help.c:2689 sql_help.c:2691 -#: sql_help.c:2693 sql_help.c:2699 sql_help.c:2701 sql_help.c:2703 -#: sql_help.c:2705 sql_help.c:2707 sql_help.c:2709 sql_help.c:2710 -#: sql_help.c:2711 sql_help.c:2957 sql_help.c:2961 sql_help.c:2964 -#: sql_help.c:2966 sql_help.c:2968 sql_help.c:2970 sql_help.c:2972 -#: sql_help.c:2978 sql_help.c:2980 sql_help.c:2982 sql_help.c:2984 -#: sql_help.c:2986 sql_help.c:2988 sql_help.c:2989 sql_help.c:2990 -#: sql_help.c:3224 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "jméno_role" -#: sql_help.c:198 sql_help.c:378 sql_help.c:831 sql_help.c:833 sql_help.c:1093 -#: sql_help.c:1446 sql_help.c:1450 sql_help.c:1616 sql_help.c:1902 -#: sql_help.c:1912 sql_help.c:1934 sql_help.c:2725 sql_help.c:3108 -#: sql_help.c:3109 sql_help.c:3113 sql_help.c:3118 sql_help.c:3178 -#: sql_help.c:3179 sql_help.c:3184 sql_help.c:3189 sql_help.c:3314 -#: sql_help.c:3315 sql_help.c:3319 sql_help.c:3324 sql_help.c:3396 -#: sql_help.c:3398 sql_help.c:3429 sql_help.c:3471 sql_help.c:3472 -#: sql_help.c:3476 sql_help.c:3481 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "výraz" -#: sql_help.c:201 +#: sql_help.c:239 msgid "domain_constraint" msgstr "omezení_domény" -#: sql_help.c:203 sql_help.c:205 sql_help.c:208 sql_help.c:816 sql_help.c:846 -#: sql_help.c:847 sql_help.c:866 sql_help.c:1206 sql_help.c:1449 -#: sql_help.c:1524 sql_help.c:1901 sql_help.c:1911 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "jméno_omezení" -#: sql_help.c:206 sql_help.c:817 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "jméno_nového_omezení" -#: sql_help.c:269 sql_help.c:744 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "nová_verze" -#: sql_help.c:273 sql_help.c:275 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "Älenský_objekt" -#: sql_help.c:276 +#: sql_help.c:324 msgid "where member_object is:" msgstr "kde Älenský_objekt je:" -#: sql_help.c:277 sql_help.c:1199 sql_help.c:3052 -msgid "agg_name" -msgstr "jméno_agregace" +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 +msgid "object_name" +msgstr "jméno_objektu" -#: sql_help.c:278 sql_help.c:1200 sql_help.c:3053 -msgid "agg_type" -msgstr "typ_agregace" +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 +msgid "aggregate_name" +msgstr "aggregate_name" -#: sql_help.c:279 sql_help.c:1201 sql_help.c:1368 sql_help.c:1372 -#: sql_help.c:1374 sql_help.c:2260 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" msgstr "zdrojový_typ" -#: sql_help.c:280 sql_help.c:1202 sql_help.c:1369 sql_help.c:1373 -#: sql_help.c:1375 sql_help.c:2261 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" msgstr "cílový_typ" -#: sql_help.c:281 sql_help.c:282 sql_help.c:283 sql_help.c:284 sql_help.c:285 -#: sql_help.c:286 sql_help.c:291 sql_help.c:295 sql_help.c:297 sql_help.c:299 -#: sql_help.c:300 sql_help.c:301 sql_help.c:302 sql_help.c:303 sql_help.c:304 -#: sql_help.c:305 sql_help.c:306 sql_help.c:307 sql_help.c:308 sql_help.c:309 -#: sql_help.c:1203 sql_help.c:1208 sql_help.c:1209 sql_help.c:1210 -#: sql_help.c:1211 sql_help.c:1212 sql_help.c:1213 sql_help.c:1214 -#: sql_help.c:1219 sql_help.c:1221 sql_help.c:1225 sql_help.c:1227 -#: sql_help.c:1229 sql_help.c:1230 sql_help.c:1233 sql_help.c:1234 -#: sql_help.c:1235 sql_help.c:1236 sql_help.c:1237 sql_help.c:1238 -#: sql_help.c:1239 sql_help.c:1240 sql_help.c:1241 sql_help.c:1244 -#: sql_help.c:1245 sql_help.c:3049 sql_help.c:3054 sql_help.c:3055 -#: sql_help.c:3056 sql_help.c:3057 sql_help.c:3063 sql_help.c:3064 -#: sql_help.c:3065 sql_help.c:3066 sql_help.c:3067 sql_help.c:3068 -#: sql_help.c:3069 sql_help.c:3070 -msgid "object_name" -msgstr "jméno_objektu" - -#: sql_help.c:287 sql_help.c:615 sql_help.c:1215 sql_help.c:1370 -#: sql_help.c:1405 sql_help.c:1464 sql_help.c:1669 sql_help.c:1700 -#: sql_help.c:2049 sql_help.c:2694 sql_help.c:2973 sql_help.c:3058 -#: sql_help.c:3134 sql_help.c:3139 sql_help.c:3340 sql_help.c:3345 -#: sql_help.c:3497 sql_help.c:3502 +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "jméno_funkce" -#: sql_help.c:288 sql_help.c:421 sql_help.c:426 sql_help.c:431 sql_help.c:436 -#: sql_help.c:1216 sql_help.c:1549 sql_help.c:2335 sql_help.c:2695 -#: sql_help.c:2974 sql_help.c:3059 -msgid "argmode" -msgstr "mód_argumentu" - -#: sql_help.c:289 sql_help.c:422 sql_help.c:427 sql_help.c:432 sql_help.c:437 -#: sql_help.c:1217 sql_help.c:1550 sql_help.c:2336 sql_help.c:3060 -msgid "argname" -msgstr "jméno_argumentu" - -#: sql_help.c:292 sql_help.c:608 sql_help.c:1222 sql_help.c:1693 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "jméno_operátoru" -#: sql_help.c:293 sql_help.c:563 sql_help.c:567 sql_help.c:1223 -#: sql_help.c:1670 sql_help.c:2378 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "levý_typ" -#: sql_help.c:294 sql_help.c:564 sql_help.c:568 sql_help.c:1224 -#: sql_help.c:1671 sql_help.c:2379 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "pravý_typ" -#: sql_help.c:296 sql_help.c:298 sql_help.c:580 sql_help.c:583 sql_help.c:586 -#: sql_help.c:606 sql_help.c:618 sql_help.c:626 sql_help.c:629 sql_help.c:632 -#: sql_help.c:1226 sql_help.c:1228 sql_help.c:1690 sql_help.c:1711 -#: sql_help.c:1917 sql_help.c:2388 sql_help.c:2397 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "metoda_indexování" -#: sql_help.c:323 sql_help.c:1490 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "procedure_name" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "routine_name" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 +msgid "type_name" +msgstr "jméno_typu" + +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 +msgid "lang_name" +msgstr "jméno_jazyka" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "a aggregate_signature je:" + +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" msgstr "handler_function" -#: sql_help.c:324 sql_help.c:1491 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "validator_function" -#: sql_help.c:361 sql_help.c:424 sql_help.c:531 sql_help.c:811 sql_help.c:1001 -#: sql_help.c:1908 sql_help.c:1909 sql_help.c:1925 sql_help.c:1926 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "akce" -#: sql_help.c:363 sql_help.c:370 sql_help.c:374 sql_help.c:375 sql_help.c:377 -#: sql_help.c:379 sql_help.c:380 sql_help.c:381 sql_help.c:383 sql_help.c:386 -#: sql_help.c:388 sql_help.c:533 sql_help.c:540 sql_help.c:542 sql_help.c:545 -#: sql_help.c:547 sql_help.c:726 sql_help.c:813 sql_help.c:823 sql_help.c:827 -#: sql_help.c:828 sql_help.c:832 sql_help.c:834 sql_help.c:835 sql_help.c:836 -#: sql_help.c:838 sql_help.c:841 sql_help.c:843 sql_help.c:1092 -#: sql_help.c:1095 sql_help.c:1115 sql_help.c:1205 sql_help.c:1290 -#: sql_help.c:1295 sql_help.c:1309 sql_help.c:1310 sql_help.c:1514 -#: sql_help.c:1554 sql_help.c:1615 sql_help.c:1650 sql_help.c:1801 -#: sql_help.c:1881 sql_help.c:1894 sql_help.c:1913 sql_help.c:1915 -#: sql_help.c:1922 sql_help.c:1933 sql_help.c:1950 sql_help.c:2052 -#: sql_help.c:2187 sql_help.c:2679 sql_help.c:2680 sql_help.c:2724 -#: sql_help.c:2958 sql_help.c:2959 sql_help.c:3051 sql_help.c:3149 -#: sql_help.c:3355 sql_help.c:3395 sql_help.c:3397 sql_help.c:3414 -#: sql_help.c:3417 sql_help.c:3512 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "jméno_sloupce" -#: sql_help.c:364 sql_help.c:534 sql_help.c:814 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "nové_jméno_sloupce" -#: sql_help.c:369 sql_help.c:440 sql_help.c:539 sql_help.c:822 sql_help.c:1014 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" msgstr "kde akce je jedno z:" -#: sql_help.c:371 sql_help.c:376 sql_help.c:824 sql_help.c:829 sql_help.c:1016 -#: sql_help.c:1020 sql_help.c:1444 sql_help.c:1515 sql_help.c:1689 -#: sql_help.c:1882 sql_help.c:2097 sql_help.c:2809 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "datový_typ" -#: sql_help.c:372 sql_help.c:825 sql_help.c:830 sql_help.c:1017 -#: sql_help.c:1021 sql_help.c:1445 sql_help.c:1518 sql_help.c:1617 -#: sql_help.c:1883 sql_help.c:2098 sql_help.c:2104 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "collation" -#: sql_help.c:373 sql_help.c:826 sql_help.c:1519 sql_help.c:1884 -#: sql_help.c:1895 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" msgstr "omezení_sloupce" -#: sql_help.c:382 sql_help.c:541 sql_help.c:837 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "integer" -#: sql_help.c:384 sql_help.c:387 sql_help.c:543 sql_help.c:546 sql_help.c:839 -#: sql_help.c:842 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "volba_atributu" -#: sql_help.c:441 sql_help.c:1557 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 +msgid "table_constraint" +msgstr "omezení_tabulky" + +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 +msgid "trigger_name" +msgstr "jméno_triggeru" + +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 +msgid "parent_table" +msgstr "nadřízená_tabulka" + +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 +msgid "extension_name" +msgstr "název_extension" + +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "execution_cost" -#: sql_help.c:442 sql_help.c:1558 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "výsledné_řádky" -#: sql_help.c:457 sql_help.c:459 sql_help.c:461 -msgid "group_name" -msgstr "group_name" - -#: sql_help.c:458 sql_help.c:460 sql_help.c:1074 sql_help.c:1421 -#: sql_help.c:1777 sql_help.c:1779 sql_help.c:1782 sql_help.c:1783 -#: sql_help.c:1963 sql_help.c:2173 sql_help.c:2527 sql_help.c:3234 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 +msgid "role_specification" +msgstr "role_specification" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "uživatel" -#: sql_help.c:476 sql_help.c:1426 sql_help.c:1621 sql_help.c:1653 -#: sql_help.c:1891 sql_help.c:1899 sql_help.c:1931 sql_help.c:1953 -#: sql_help.c:1962 sql_help.c:2706 sql_help.c:2985 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 +msgid "where role_specification can be:" +msgstr "kde role_specification může být:" + +#: sql_help.c:569 +msgid "group_name" +msgstr "group_name" + +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" msgstr "jméno_tablespace" -#: sql_help.c:478 sql_help.c:481 sql_help.c:549 sql_help.c:551 sql_help.c:857 -#: sql_help.c:859 sql_help.c:1619 sql_help.c:1651 sql_help.c:1889 -#: sql_help.c:1897 sql_help.c:1929 sql_help.c:1951 +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "jméno_indexu" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "parametr_uložení" -#: sql_help.c:501 sql_help.c:1220 sql_help.c:3062 +#: sql_help.c:601 +msgid "column_number" +msgstr "column_number" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" msgstr "oid_large_objektu" -#: sql_help.c:548 sql_help.c:856 sql_help.c:867 sql_help.c:1155 -msgid "index_name" -msgstr "jméno_indexu" +#: sql_help.c:712 sql_help.c:2402 +msgid "res_proc" +msgstr "res_proc" -#: sql_help.c:607 sql_help.c:619 sql_help.c:1692 +#: sql_help.c:713 sql_help.c:2403 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" msgstr "Äíslo_strategie" -#: sql_help.c:609 sql_help.c:610 sql_help.c:613 sql_help.c:614 sql_help.c:620 -#: sql_help.c:621 sql_help.c:623 sql_help.c:624 sql_help.c:1694 -#: sql_help.c:1695 sql_help.c:1698 sql_help.c:1699 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "typ_operátoru" -#: sql_help.c:611 sql_help.c:1696 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "sort_family_name" -#: sql_help.c:612 sql_help.c:622 sql_help.c:1697 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "support_number" -#: sql_help.c:616 sql_help.c:1371 sql_help.c:1701 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "typ_argumentu" -#: sql_help.c:665 sql_help.c:1053 sql_help.c:1593 sql_help.c:1742 -#: sql_help.c:2156 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 +msgid "table_name" +msgstr "jméno_tabulky" + +#: sql_help.c:810 sql_help.c:2455 +msgid "using_expression" +msgstr "using_expression" + +#: sql_help.c:811 sql_help.c:2456 +msgid "check_expression" +msgstr "check_expression" + +#: sql_help.c:885 sql_help.c:2497 +msgid "publication_parameter" +msgstr "publication_parameter" + +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "heslo" -#: sql_help.c:666 sql_help.c:1054 sql_help.c:1594 sql_help.c:1743 -#: sql_help.c:2157 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "timestamp" -#: sql_help.c:670 sql_help.c:674 sql_help.c:677 sql_help.c:680 sql_help.c:2686 -#: sql_help.c:2965 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "jméno_databáze" -#: sql_help.c:689 sql_help.c:725 sql_help.c:980 sql_help.c:1114 -#: sql_help.c:1154 sql_help.c:1207 sql_help.c:1232 sql_help.c:1243 -#: sql_help.c:1289 sql_help.c:1294 sql_help.c:1513 sql_help.c:1613 -#: sql_help.c:1649 sql_help.c:1761 sql_help.c:1800 sql_help.c:1880 -#: sql_help.c:1892 sql_help.c:1949 sql_help.c:2046 sql_help.c:2221 -#: sql_help.c:2422 sql_help.c:2503 sql_help.c:2676 sql_help.c:2681 -#: sql_help.c:2723 sql_help.c:2955 sql_help.c:2960 sql_help.c:3050 -#: sql_help.c:3123 sql_help.c:3125 sql_help.c:3155 sql_help.c:3194 -#: sql_help.c:3329 sql_help.c:3331 sql_help.c:3361 sql_help.c:3393 -#: sql_help.c:3413 sql_help.c:3415 sql_help.c:3416 sql_help.c:3486 -#: sql_help.c:3488 sql_help.c:3518 -msgid "table_name" -msgstr "jméno_tabulky" - -#: sql_help.c:719 sql_help.c:1795 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" msgstr "inkrement" -#: sql_help.c:720 sql_help.c:1796 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "min_hodnota" -#: sql_help.c:721 sql_help.c:1797 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "max_hodnota" -#: sql_help.c:722 sql_help.c:1798 sql_help.c:3121 sql_help.c:3192 -#: sql_help.c:3327 sql_help.c:3433 sql_help.c:3484 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" msgstr "start" -#: sql_help.c:723 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" msgstr "restart" -#: sql_help.c:724 sql_help.c:1799 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" msgstr "cache" -#: sql_help.c:844 sql_help.c:1885 sql_help.c:1896 -msgid "table_constraint" -msgstr "omezení_tabulky" +#: sql_help.c:1109 sql_help.c:2646 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1111 sql_help.c:2647 +msgid "publication_name" +msgstr "publication_name" + +#: sql_help.c:1112 +msgid "set_publication_option" +msgstr "set_publication_option" + +#: sql_help.c:1115 +msgid "refresh_option" +msgstr "refresh_option" + +#: sql_help.c:1120 sql_help.c:2648 +msgid "subscription_parameter" +msgstr "subscription_parameter" + +#: sql_help.c:1273 sql_help.c:1276 +msgid "partition_name" +msgstr "partition_name" + +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 +msgid "partition_bound_spec" +msgstr "partition_bound_spec" + +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 +msgid "sequence_options" +msgstr "sequence_options" -#: sql_help.c:845 +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "sequence_option" + +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "omezení_tabulky_s_využitím_indexu" -#: sql_help.c:848 sql_help.c:849 sql_help.c:850 sql_help.c:851 sql_help.c:1242 -msgid "trigger_name" -msgstr "jméno_triggeru" - -#: sql_help.c:852 sql_help.c:853 sql_help.c:854 sql_help.c:855 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "pÅ™episovací_pravidlo" -#: sql_help.c:860 sql_help.c:861 sql_help.c:1888 -msgid "parent_table" -msgstr "nadřízená_tabulka" +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "a partition_bound_spec je:" -#: sql_help.c:862 sql_help.c:1893 sql_help.c:2708 sql_help.c:2987 -msgid "type_name" -msgstr "jméno_typu" +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "numeric_literal" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "string_literal" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "a column_constraint je:" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "implicitní_výraz" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "parametry_indexu" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "odkazovaná_tabulka" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "odkazovaný_sloupec" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "a omezení_tabulky je:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "exclude_element" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "operátor" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "predikát" + +#: sql_help.c:1365 +msgid "and table_constraint_using_index is:" +msgstr "a omezení_tabulky_s_využitím_indexu je:" + +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "parametry_indexu v UNIQUE, PRIMARY KEY, a EXCLUDE omezeních jsou:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "exclude_element v EXCLUDE omezení je:" -#: sql_help.c:865 -msgid "and table_constraint_using_index is:" -msgstr "a omezení_tabulky_s_využitím_indexu je:" +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "třída_operátoru" -#: sql_help.c:883 sql_help.c:886 +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" msgstr "volba_tablespace" -#: sql_help.c:907 sql_help.c:910 sql_help.c:916 sql_help.c:920 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "typ_tokenu" -#: sql_help.c:908 sql_help.c:911 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "jméno_slovníku" -#: sql_help.c:913 sql_help.c:917 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "starý_slovník" -#: sql_help.c:914 sql_help.c:918 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "nový_slovník" -#: sql_help.c:1005 sql_help.c:1015 sql_help.c:1018 sql_help.c:1019 -#: sql_help.c:2096 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "jméno_atributu" -#: sql_help.c:1006 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "nové_jméno_atributu" -#: sql_help.c:1012 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "nová_enum_hodnota" -#: sql_help.c:1013 +#: sql_help.c:1527 +msgid "neighbor_enum_value" +msgstr "neighbor_enum_value" + +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "existing_enum_value" -#: sql_help.c:1075 sql_help.c:1520 sql_help.c:1811 sql_help.c:2174 -#: sql_help.c:2528 sql_help.c:2692 sql_help.c:2971 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" msgstr "jméno_serveru" -#: sql_help.c:1103 sql_help.c:1106 sql_help.c:2188 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "název_volby_pohledu" -#: sql_help.c:1104 sql_help.c:2189 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" msgstr "hodnota_volby_pohledu" -#: sql_help.c:1129 sql_help.c:3250 sql_help.c:3252 sql_help.c:3276 +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "table_and_columns" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "kde volba je jedno z:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "a table_and_columns je:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "transakÄní_mód" -#: sql_help.c:1130 sql_help.c:3253 sql_help.c:3277 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" msgstr "kde transakÄní_mód je jedno z:" -#: sql_help.c:1204 +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1772 msgid "relation_name" msgstr "název_relace" -#: sql_help.c:1231 +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 +msgid "domain_name" +msgstr "jméno_domény" + +#: sql_help.c:1799 +msgid "policy_name" +msgstr "policy_name" + +#: sql_help.c:1812 msgid "rule_name" msgstr "jméno_pravidla" -#: sql_help.c:1246 +#: sql_help.c:1831 msgid "text" msgstr "text" -#: sql_help.c:1261 sql_help.c:2818 sql_help.c:3005 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" msgstr "id_transakce" -#: sql_help.c:1291 sql_help.c:1297 sql_help.c:2744 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "jméno_souboru" -#: sql_help.c:1292 sql_help.c:1298 sql_help.c:1763 sql_help.c:1764 -#: sql_help.c:1765 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "příkaz" -#: sql_help.c:1296 sql_help.c:1654 sql_help.c:1954 sql_help.c:2190 -#: sql_help.c:2208 sql_help.c:2726 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "dotaz" -#: sql_help.c:1300 sql_help.c:2573 -msgid "where option can be one of:" -msgstr "kde volba je jedno z:" - -#: sql_help.c:1301 +#: sql_help.c:1897 msgid "format_name" msgstr "jméno_formátu" -#: sql_help.c:1302 sql_help.c:1303 sql_help.c:1306 sql_help.c:2574 -#: sql_help.c:2575 sql_help.c:2576 sql_help.c:2577 sql_help.c:2578 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" msgstr "boolean" -#: sql_help.c:1304 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "oddÄ›lovací_znak" -#: sql_help.c:1305 +#: sql_help.c:1901 msgid "null_string" msgstr "null_string" -#: sql_help.c:1307 +#: sql_help.c:1903 msgid "quote_character" msgstr "quote_character" -#: sql_help.c:1308 +#: sql_help.c:1904 msgid "escape_character" msgstr "escape_character" -#: sql_help.c:1311 +#: sql_help.c:1908 msgid "encoding_name" msgstr "název_kódování" -#: sql_help.c:1337 -msgid "input_data_type" -msgstr "vstupní_datový_typ" +#: sql_help.c:1919 +msgid "access_method_type" +msgstr "access_method_type" + +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 +msgid "arg_data_type" +msgstr "arg_data_type" -#: sql_help.c:1338 sql_help.c:1346 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "sfunc" -#: sql_help.c:1339 sql_help.c:1347 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "datový_typ_stavu" -#: sql_help.c:1340 sql_help.c:1348 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 +msgid "state_data_size" +msgstr "state_data_size" + +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "ffunc" -#: sql_help.c:1341 sql_help.c:1349 +#: sql_help.c:1995 sql_help.c:2025 +msgid "combinefunc" +msgstr "combinefunc" + +#: sql_help.c:1996 sql_help.c:2026 +msgid "serialfunc" +msgstr "serialfunc" + +#: sql_help.c:1997 sql_help.c:2027 +msgid "deserialfunc" +msgstr "deserialfunc" + +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "výchozí_podmínka" -#: sql_help.c:1342 sql_help.c:1350 +#: sql_help.c:1999 sql_help.c:2029 +msgid "msfunc" +msgstr "msfunc" + +#: sql_help.c:2000 sql_help.c:2030 +msgid "minvfunc" +msgstr "minvfunc" + +#: sql_help.c:2001 sql_help.c:2031 +msgid "mstate_data_type" +msgstr "mstate_data_type" + +#: sql_help.c:2002 sql_help.c:2032 +msgid "mstate_data_size" +msgstr "mstate_data_size" + +#: sql_help.c:2003 sql_help.c:2033 +msgid "mffunc" +msgstr "mffunc" + +#: sql_help.c:2004 sql_help.c:2034 +msgid "minitial_condition" +msgstr "minitial_condition" + +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "operátor_třídÄ›ní" -#: sql_help.c:1343 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "nebo stará syntaxe" -#: sql_help.c:1345 +#: sql_help.c:2020 msgid "base_type" msgstr "základní_typ" -#: sql_help.c:1389 +#: sql_help.c:2076 msgid "locale" msgstr "locale" -#: sql_help.c:1390 sql_help.c:1424 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1391 sql_help.c:1425 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1393 +#: sql_help.c:2079 sql_help.c:4122 +msgid "provider" +msgstr "provider" + +#: sql_help.c:2080 sql_help.c:2171 +msgid "version" +msgstr "verze" + +#: sql_help.c:2082 msgid "existing_collation" msgstr "existující_collation" -#: sql_help.c:1403 +#: sql_help.c:2092 msgid "source_encoding" msgstr "kódování_zdroje" -#: sql_help.c:1404 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "kódování_cíle" -#: sql_help.c:1422 sql_help.c:1989 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "Å¡ablona" -#: sql_help.c:1423 +#: sql_help.c:2114 msgid "encoding" msgstr "kódování" -#: sql_help.c:1448 +#: sql_help.c:2140 +msgid "constraint" +msgstr "omezení" + +#: sql_help.c:2141 msgid "where constraint is:" msgstr "kde omezení je:" -#: sql_help.c:1462 sql_help.c:1760 sql_help.c:2045 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "událost" -#: sql_help.c:1463 +#: sql_help.c:2156 msgid "filter_variable" msgstr "filter_variable" -#: sql_help.c:1475 -msgid "extension_name" -msgstr "název_extension" - -#: sql_help.c:1477 -msgid "version" -msgstr "verze" - -#: sql_help.c:1478 +#: sql_help.c:2172 msgid "old_version" msgstr "stará_verze" -#: sql_help.c:1523 sql_help.c:1900 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" msgstr "kde omezení_sloupce je:" -#: sql_help.c:1525 sql_help.c:1552 sql_help.c:1903 -msgid "default_expr" -msgstr "implicitní_výraz" - -#: sql_help.c:1553 +#: sql_help.c:2280 msgid "rettype" msgstr "návratový_typ" -#: sql_help.c:1555 +#: sql_help.c:2282 msgid "column_type" msgstr "typ_sloupce" -#: sql_help.c:1556 sql_help.c:2242 sql_help.c:2700 sql_help.c:2979 -msgid "lang_name" -msgstr "jméno_jazyka" - -#: sql_help.c:1562 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "definice" -#: sql_help.c:1563 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "obj_file" -#: sql_help.c:1564 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "link_symbol" -#: sql_help.c:1565 -msgid "attribute" -msgstr "atribut" - -#: sql_help.c:1600 sql_help.c:1749 sql_help.c:2163 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" msgstr "uid" -#: sql_help.c:1614 +#: sql_help.c:2341 msgid "method" msgstr "metoda" -#: sql_help.c:1618 sql_help.c:1935 -msgid "opclass" -msgstr "třída_operátoru" - -#: sql_help.c:1622 sql_help.c:1921 -msgid "predicate" -msgstr "predikát" - -#: sql_help.c:1634 +#: sql_help.c:2362 msgid "call_handler" msgstr "call_handler" -#: sql_help.c:1635 +#: sql_help.c:2363 msgid "inline_handler" msgstr "inline_handler" -#: sql_help.c:1636 +#: sql_help.c:2364 msgid "valfunction" msgstr "valfunction" -#: sql_help.c:1672 +#: sql_help.c:2400 msgid "com_op" msgstr "com_op" -#: sql_help.c:1673 +#: sql_help.c:2401 msgid "neg_op" msgstr "neg_op" -#: sql_help.c:1674 -msgid "res_proc" -msgstr "res_proc" - -#: sql_help.c:1675 -msgid "join_proc" -msgstr "join_proc" - -#: sql_help.c:1691 +#: sql_help.c:2419 msgid "family_name" msgstr "family_name" -#: sql_help.c:1702 +#: sql_help.c:2430 msgid "storage_type" msgstr "typ_uložení" -#: sql_help.c:1762 sql_help.c:2048 sql_help.c:2224 sql_help.c:3112 -#: sql_help.c:3114 sql_help.c:3183 sql_help.c:3185 sql_help.c:3318 -#: sql_help.c:3320 sql_help.c:3400 sql_help.c:3475 sql_help.c:3477 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "podmínka" -#: sql_help.c:1778 sql_help.c:1780 +#: sql_help.c:2557 sql_help.c:2961 +msgid "where event can be one of:" +msgstr "kde událost může být jedno z:" + +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "prvek_schématu" -#: sql_help.c:1812 +#: sql_help.c:2615 msgid "server_type" msgstr "typ_serveru" -#: sql_help.c:1813 +#: sql_help.c:2616 msgid "server_version" msgstr "verze_serveru" -#: sql_help.c:1814 sql_help.c:2690 sql_help.c:2969 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" msgstr "fdw_jméno" -#: sql_help.c:1886 +#: sql_help.c:2630 +msgid "statistics_name" +msgstr "statistics_name" + +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "statistics_kind" + +#: sql_help.c:2645 +msgid "subscription_name" +msgstr "subscription_name" + +#: sql_help.c:2741 msgid "source_table" msgstr "zdrojová_tabulka" -#: sql_help.c:1887 +#: sql_help.c:2742 msgid "like_option" msgstr "like_volba" -#: sql_help.c:1904 sql_help.c:1905 sql_help.c:1914 sql_help.c:1916 -#: sql_help.c:1920 -msgid "index_parameters" -msgstr "parametry_indexu" - -#: sql_help.c:1906 sql_help.c:1923 -msgid "reftable" -msgstr "odkazovaná_tabulka" - -#: sql_help.c:1907 sql_help.c:1924 -msgid "refcolumn" -msgstr "odkazovaný_sloupec" - -#: sql_help.c:1910 -msgid "and table_constraint is:" -msgstr "a omezení_tabulky je:" - -#: sql_help.c:1918 -msgid "exclude_element" -msgstr "exclude_element" - -#: sql_help.c:1919 sql_help.c:3119 sql_help.c:3190 sql_help.c:3325 -#: sql_help.c:3431 sql_help.c:3482 -msgid "operator" -msgstr "operátor" - -#: sql_help.c:1927 +#: sql_help.c:2804 msgid "and like_option is:" msgstr "a like_volba je:" -#: sql_help.c:1928 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "parametry_indexu v UNIQUE, PRIMARY KEY, a EXCLUDE omezeních jsou:" - -#: sql_help.c:1932 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "exclude_element v EXCLUDE omezení je:" - -#: sql_help.c:1964 +#: sql_help.c:2854 msgid "directory" msgstr "adresář" -#: sql_help.c:1976 +#: sql_help.c:2868 msgid "parser_name" msgstr "jméno_parseru" -#: sql_help.c:1977 +#: sql_help.c:2869 msgid "source_config" msgstr "source_config" -#: sql_help.c:2006 +#: sql_help.c:2898 msgid "start_function" msgstr "start_funkce" -#: sql_help.c:2007 +#: sql_help.c:2899 msgid "gettoken_function" msgstr "gettoken_funkce" -#: sql_help.c:2008 +#: sql_help.c:2900 msgid "end_function" msgstr "end_function" -#: sql_help.c:2009 +#: sql_help.c:2901 msgid "lextypes_function" msgstr "lextypes_funkce" -#: sql_help.c:2010 +#: sql_help.c:2902 msgid "headline_function" msgstr "headline_funkce" -#: sql_help.c:2022 +#: sql_help.c:2914 msgid "init_function" msgstr "init_funkce" -#: sql_help.c:2023 +#: sql_help.c:2915 msgid "lexize_function" msgstr "lexize_funkce" -#: sql_help.c:2047 +#: sql_help.c:2928 +msgid "from_sql_function_name" +msgstr "from_sql_function_name" + +#: sql_help.c:2930 +msgid "to_sql_function_name" +msgstr "to_sql_function_name" + +#: sql_help.c:2956 msgid "referenced_table_name" msgstr "jméno_odkazované_tabulky" -#: sql_help.c:2050 +#: sql_help.c:2957 +msgid "transition_relation_name" +msgstr "transition_relation_name" + +#: sql_help.c:2960 msgid "arguments" msgstr "argumenty" -#: sql_help.c:2051 -msgid "where event can be one of:" -msgstr "kde událost může být jedno z:" - -#: sql_help.c:2100 sql_help.c:3071 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "popisek" -#: sql_help.c:2102 +#: sql_help.c:3012 msgid "subtype" msgstr "subtyp" -#: sql_help.c:2103 +#: sql_help.c:3013 msgid "subtype_operator_class" msgstr "třída_operátorů_subtypu" -#: sql_help.c:2105 +#: sql_help.c:3015 msgid "canonical_function" msgstr "kanonická_funkce" -#: sql_help.c:2106 +#: sql_help.c:3016 msgid "subtype_diff_function" msgstr "diff_funkce_subtypu" -#: sql_help.c:2108 +#: sql_help.c:3018 msgid "input_function" msgstr "vstupní_funkce" -#: sql_help.c:2109 +#: sql_help.c:3019 msgid "output_function" msgstr "výstupní_funkce" -#: sql_help.c:2110 +#: sql_help.c:3020 msgid "receive_function" msgstr "receive_funkce" -#: sql_help.c:2111 +#: sql_help.c:3021 msgid "send_function" msgstr "send_funkce" -#: sql_help.c:2112 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "type_modifier_input_function" -#: sql_help.c:2113 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "type_modifier_output_function" -#: sql_help.c:2114 +#: sql_help.c:3024 msgid "analyze_function" msgstr "analyze_funkce" -#: sql_help.c:2115 +#: sql_help.c:3025 msgid "internallength" msgstr "interní_délka" -#: sql_help.c:2116 +#: sql_help.c:3026 msgid "alignment" msgstr "zarovnání" -#: sql_help.c:2117 +#: sql_help.c:3027 msgid "storage" msgstr "uložení" -#: sql_help.c:2118 +#: sql_help.c:3028 msgid "like_type" msgstr "like_typ" -#: sql_help.c:2119 +#: sql_help.c:3029 msgid "category" msgstr "kategorie" -#: sql_help.c:2120 +#: sql_help.c:3030 msgid "preferred" msgstr "preferovaný" -#: sql_help.c:2121 +#: sql_help.c:3031 msgid "default" msgstr "implicitní" -#: sql_help.c:2122 +#: sql_help.c:3032 msgid "element" msgstr "prvek" -#: sql_help.c:2123 +#: sql_help.c:3033 msgid "delimiter" msgstr "oddÄ›lovaÄ" -#: sql_help.c:2124 +#: sql_help.c:3034 msgid "collatable" msgstr "collatable" -#: sql_help.c:2220 sql_help.c:2722 sql_help.c:3107 sql_help.c:3177 -#: sql_help.c:3313 sql_help.c:3392 sql_help.c:3470 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "with_dotaz" -#: sql_help.c:2222 sql_help.c:3126 sql_help.c:3129 sql_help.c:3132 -#: sql_help.c:3136 sql_help.c:3332 sql_help.c:3335 sql_help.c:3338 -#: sql_help.c:3342 sql_help.c:3394 sql_help.c:3489 sql_help.c:3492 -#: sql_help.c:3495 sql_help.c:3499 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" msgstr "alias" -#: sql_help.c:2223 +#: sql_help.c:3134 msgid "using_list" msgstr "using_seznam" -#: sql_help.c:2225 sql_help.c:2604 sql_help.c:2785 sql_help.c:3401 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "jméno_kurzoru" -#: sql_help.c:2226 sql_help.c:2727 sql_help.c:3402 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "výstupní_výraz" -#: sql_help.c:2227 sql_help.c:2728 sql_help.c:3110 sql_help.c:3180 -#: sql_help.c:3316 sql_help.c:3403 sql_help.c:3473 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "výstupní_jméno" -#: sql_help.c:2243 +#: sql_help.c:3154 msgid "code" msgstr "kód" -#: sql_help.c:2552 +#: sql_help.c:3553 msgid "parameter" msgstr "parametr" -#: sql_help.c:2571 sql_help.c:2572 sql_help.c:2810 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "příkaz" -#: sql_help.c:2603 sql_help.c:2784 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" msgstr "smÄ›r" -#: sql_help.c:2605 sql_help.c:2786 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" msgstr "kde smÄ›r může být prázdný nebo jedno z:" -#: sql_help.c:2606 sql_help.c:2607 sql_help.c:2608 sql_help.c:2609 -#: sql_help.c:2610 sql_help.c:2787 sql_help.c:2788 sql_help.c:2789 -#: sql_help.c:2790 sql_help.c:2791 sql_help.c:3120 sql_help.c:3122 -#: sql_help.c:3191 sql_help.c:3193 sql_help.c:3326 sql_help.c:3328 -#: sql_help.c:3432 sql_help.c:3434 sql_help.c:3483 sql_help.c:3485 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" msgstr "poÄet" -#: sql_help.c:2683 sql_help.c:2962 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "sekvence" -#: sql_help.c:2688 sql_help.c:2967 -msgid "domain_name" -msgstr "jméno_domény" - -#: sql_help.c:2696 sql_help.c:2975 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "jméno_argumentu" -#: sql_help.c:2697 sql_help.c:2976 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "typ_argumentu" -#: sql_help.c:2702 sql_help.c:2981 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "loid" -#: sql_help.c:2736 sql_help.c:2799 sql_help.c:3378 +#: sql_help.c:3735 +msgid "remote_schema" +msgstr "remote_schema" + +#: sql_help.c:3738 +msgid "local_schema" +msgstr "local_schema" + +#: sql_help.c:3773 +msgid "conflict_target" +msgstr "conflict_target" + +#: sql_help.c:3774 +msgid "conflict_action" +msgstr "conflict_action" + +#: sql_help.c:3777 +msgid "where conflict_target can be one of:" +msgstr "where conflict_target can be one of:" + +#: sql_help.c:3778 +msgid "index_column_name" +msgstr "index_column_name" + +#: sql_help.c:3779 +msgid "index_expression" +msgstr "index_expression" + +#: sql_help.c:3782 +msgid "index_predicate" +msgstr "index_predicate" + +#: sql_help.c:3784 +msgid "and conflict_action is one of:" +msgstr "a conflict_action je jedno z:" + +#: sql_help.c:3790 sql_help.c:4562 +msgid "sub-SELECT" +msgstr "sub-SELECT" + +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "kanál" -#: sql_help.c:2758 +#: sql_help.c:3821 msgid "lockmode" msgstr "mód_zámku" -#: sql_help.c:2759 +#: sql_help.c:3822 msgid "where lockmode is one of:" msgstr "kde mód_zámku je jedno z:" -#: sql_help.c:2800 +#: sql_help.c:3863 msgid "payload" msgstr "náklad" -#: sql_help.c:2826 +#: sql_help.c:3890 msgid "old_role" msgstr "stará_role" -#: sql_help.c:2827 +#: sql_help.c:3891 msgid "new_role" msgstr "nová_role" -#: sql_help.c:2852 sql_help.c:3013 sql_help.c:3021 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "jméno_savepointu" -#: sql_help.c:3048 -msgid "provider" -msgstr "provider" - -#: sql_help.c:3111 sql_help.c:3142 sql_help.c:3144 sql_help.c:3182 -#: sql_help.c:3317 sql_help.c:3348 sql_help.c:3350 sql_help.c:3474 -#: sql_help.c:3505 sql_help.c:3507 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" msgstr "z_položky" -#: sql_help.c:3115 sql_help.c:3186 sql_help.c:3321 sql_help.c:3478 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 +msgid "grouping_element" +msgstr "grouping_element" + +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "jméno_okna" -#: sql_help.c:3116 sql_help.c:3187 sql_help.c:3322 sql_help.c:3479 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "definice_okna" -#: sql_help.c:3117 sql_help.c:3128 sql_help.c:3150 sql_help.c:3188 -#: sql_help.c:3323 sql_help.c:3334 sql_help.c:3356 sql_help.c:3480 -#: sql_help.c:3491 sql_help.c:3513 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "select" -#: sql_help.c:3124 sql_help.c:3330 sql_help.c:3487 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" msgstr "kde z_položky může být jedno z:" -#: sql_help.c:3127 sql_help.c:3130 sql_help.c:3133 sql_help.c:3137 -#: sql_help.c:3333 sql_help.c:3336 sql_help.c:3339 sql_help.c:3343 -#: sql_help.c:3490 sql_help.c:3493 sql_help.c:3496 sql_help.c:3500 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" msgstr "alias_sloupce" -#: sql_help.c:3131 sql_help.c:3148 sql_help.c:3337 sql_help.c:3354 -#: sql_help.c:3494 sql_help.c:3511 +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 +msgid "sampling_method" +msgstr "sampling_method" + +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 +msgid "seed" +msgstr "seed" + +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "jméno_with_dotazu" -#: sql_help.c:3135 sql_help.c:3140 sql_help.c:3341 sql_help.c:3346 -#: sql_help.c:3498 sql_help.c:3503 -msgid "argument" -msgstr "argument" - -#: sql_help.c:3138 sql_help.c:3141 sql_help.c:3344 sql_help.c:3347 -#: sql_help.c:3501 sql_help.c:3504 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" msgstr "definice_sloupce" -#: sql_help.c:3143 sql_help.c:3349 sql_help.c:3506 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" msgstr "typ_joinu" -#: sql_help.c:3145 sql_help.c:3351 sql_help.c:3508 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" msgstr "joinovací_podmínka" -#: sql_help.c:3146 sql_help.c:3352 sql_help.c:3509 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" msgstr "joinovací_sloupec" -#: sql_help.c:3147 sql_help.c:3353 sql_help.c:3510 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 +msgid "and grouping_element can be one of:" +msgstr "a grouping_element může být jedno z:" + +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" msgstr "a with_dotaz je:" -#: sql_help.c:3151 sql_help.c:3357 sql_help.c:3514 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "hodnoty" -#: sql_help.c:3152 sql_help.c:3358 sql_help.c:3515 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" -msgstr "insert " +msgstr "insert" -#: sql_help.c:3153 sql_help.c:3359 sql_help.c:3516 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "update" -#: sql_help.c:3154 sql_help.c:3360 sql_help.c:3517 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "delete" -#: sql_help.c:3181 +#: sql_help.c:4308 msgid "new_table" msgstr "nová_tabulka" -#: sql_help.c:3206 +#: sql_help.c:4333 msgid "timezone" msgstr "Äasová_zóna" -#: sql_help.c:3251 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "snapshot_id" -#: sql_help.c:3399 +#: sql_help.c:4563 msgid "from_list" msgstr "from_seznam" -#: sql_help.c:3430 +#: sql_help.c:4607 msgid "sort_expression" msgstr "sort_expression" -#: sql_help.h:190 sql_help.h:885 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" msgstr "nestandardní ukonÄení (abort) souÄasné transakce" -#: sql_help.h:195 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" msgstr "zmÄ›na definice agregátní funkce" -#: sql_help.h:200 +#: sql_help.c:4744 msgid "change the definition of a collation" msgstr "zmÄ›ní definici collation" -#: sql_help.h:205 +#: sql_help.c:4749 msgid "change the definition of a conversion" msgstr "zmÄ›na definice konverze" -#: sql_help.h:210 +#: sql_help.c:4754 msgid "change a database" msgstr "zmÄ›ní databázi" -#: sql_help.h:215 +#: sql_help.c:4759 msgid "define default access privileges" msgstr "definuje výchozí přístupová práva" -#: sql_help.h:220 +#: sql_help.c:4764 msgid "change the definition of a domain" msgstr "zmÄ›ní definici domény" -#: sql_help.h:225 +#: sql_help.c:4769 msgid "change the definition of an event trigger" msgstr "zmÄ›ní definici event triggeru" -#: sql_help.h:230 +#: sql_help.c:4774 msgid "change the definition of an extension" msgstr "zmÄ›na definice extension" -#: sql_help.h:235 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" msgstr "zmÄ›ní definici foreign-data wrapperu" -#: sql_help.h:240 +#: sql_help.c:4784 msgid "change the definition of a foreign table" msgstr "zmÄ›ní definici foreign tabulky" -#: sql_help.h:245 +#: sql_help.c:4789 msgid "change the definition of a function" msgstr "zmÄ›ní definici funkce" -#: sql_help.h:250 +#: sql_help.c:4794 msgid "change role name or membership" msgstr "zmÄ›ní jméno role nebo Älenství" -#: sql_help.h:255 +#: sql_help.c:4799 msgid "change the definition of an index" msgstr "zmÄ›ní definici indexu" -#: sql_help.h:260 +#: sql_help.c:4804 msgid "change the definition of a procedural language" msgstr "zmÄ›ní definici procedurálního jazyka" -#: sql_help.h:265 +#: sql_help.c:4809 msgid "change the definition of a large object" msgstr "zmÄ›ní definici large objektu" -#: sql_help.h:270 +#: sql_help.c:4814 msgid "change the definition of a materialized view" msgstr "zmÄ›ní definici materializovaného pohledu" -#: sql_help.h:275 +#: sql_help.c:4819 msgid "change the definition of an operator" msgstr "zmÄ›ní definici operátoru" -#: sql_help.h:280 +#: sql_help.c:4824 msgid "change the definition of an operator class" msgstr "zmÄ›ní definici třídy operátorů" -#: sql_help.h:285 +#: sql_help.c:4829 msgid "change the definition of an operator family" msgstr "zmÄ›ní definici rodiny operátorů" -#: sql_help.h:290 sql_help.h:355 +#: sql_help.c:4834 +msgid "change the definition of a row level security policy" +msgstr "zmÄ›ní definici row level security politiky" + +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "zmÄ›ní definici procedury" + +#: sql_help.c:4844 +msgid "change the definition of a publication" +msgstr "zmÄ›ní definici publikace" + +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" msgstr "zmÄ›ní databázovou roli" -#: sql_help.h:295 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "zmÄ›ní definici rutiny" + +#: sql_help.c:4859 msgid "change the definition of a rule" msgstr "zmÄ›ní definici pravidla" -#: sql_help.h:300 +#: sql_help.c:4864 msgid "change the definition of a schema" msgstr "zmÄ›ní definici schématu" -#: sql_help.h:305 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" msgstr "zmÄ›ní definici generátoru sekvencí" -#: sql_help.h:310 +#: sql_help.c:4874 msgid "change the definition of a foreign server" msgstr "zmÄ›ní definici foreign serveru" -#: sql_help.h:315 +#: sql_help.c:4879 +msgid "change the definition of an extended statistics object" +msgstr "zmÄ›na definice rozšířené statistiky" + +#: sql_help.c:4884 +msgid "change the definition of a subscription" +msgstr "zmÄ›ní definici subskripce" + +#: sql_help.c:4889 +msgid "change a server configuration parameter" +msgstr "zmÄ›ní serverový konfiguraÄní parametr" + +#: sql_help.c:4894 msgid "change the definition of a table" msgstr "zmÄ›ní definici tabulky" -#: sql_help.h:320 +#: sql_help.c:4899 msgid "change the definition of a tablespace" msgstr "zmÄ›ní definici tablespace" -#: sql_help.h:325 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" msgstr "zmÄ›ní definici konfigurace fulltextového vyhledávání" -#: sql_help.h:330 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" msgstr "zmÄ›ní definici slovníku pro fulltextové vyhledávání" -#: sql_help.h:335 +#: sql_help.c:4914 msgid "change the definition of a text search parser" msgstr "zmÄ›ní definici parseru pro fulltextové vyhledávání" -#: sql_help.h:340 +#: sql_help.c:4919 msgid "change the definition of a text search template" msgstr "zmÄ›ní definici Å¡ablony pro fulltextové vyhledávání" -#: sql_help.h:345 +#: sql_help.c:4924 msgid "change the definition of a trigger" msgstr "zmÄ›ní definici triggeru" -#: sql_help.h:350 +#: sql_help.c:4929 msgid "change the definition of a type" msgstr "zmÄ›ní definici datového typu" -#: sql_help.h:360 +#: sql_help.c:4939 msgid "change the definition of a user mapping" msgstr "zmÄ›ní definici mapování uživatelů" -#: sql_help.h:365 +#: sql_help.c:4944 msgid "change the definition of a view" msgstr "zmÄ›ní definici pohledu" -#: sql_help.h:370 +#: sql_help.c:4949 msgid "collect statistics about a database" msgstr "shromáždí statistické informace o databázi" -#: sql_help.h:375 sql_help.h:950 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" msgstr "nastartuje nový transakÄní blok" -#: sql_help.h:380 -msgid "force a transaction log checkpoint" +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "spustí proceduru" + +#: sql_help.c:4964 +msgid "force a write-ahead log checkpoint" msgstr "vynutí checkpoint transakÄního logu" -#: sql_help.h:385 +#: sql_help.c:4969 msgid "close a cursor" msgstr "uzavÅ™e kursor" -#: sql_help.h:390 +#: sql_help.c:4974 msgid "cluster a table according to an index" msgstr "pÅ™erovná obsah tabulky dle indexu" -#: sql_help.h:395 +#: sql_help.c:4979 msgid "define or change the comment of an object" msgstr "definuje nebo zmÄ›ní komentář objektu" -#: sql_help.h:400 sql_help.h:790 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" msgstr "potvrzení aktuální transakce" -#: sql_help.h:405 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "" "potvrzení aktuální transakce, která byla již dříve pÅ™ipravena pro dvoufázový " "commit" -#: sql_help.h:410 +#: sql_help.c:4994 msgid "copy data between a file and a table" msgstr "kopíruje data mezi souborem a tabulkou" -#: sql_help.h:415 +#: sql_help.c:4999 +msgid "define a new access method" +msgstr "definuje novou přístupovou metodu" + +#: sql_help.c:5004 msgid "define a new aggregate function" msgstr "definuje novou agrefunkci" -#: sql_help.h:420 +#: sql_help.c:5009 msgid "define a new cast" msgstr "definuje nové pÅ™etypování" -#: sql_help.h:425 +#: sql_help.c:5014 msgid "define a new collation" msgstr "definuje novou collation" -#: sql_help.h:430 +#: sql_help.c:5019 msgid "define a new encoding conversion" msgstr "definuje novou konverzi kódování" -#: sql_help.h:435 +#: sql_help.c:5024 msgid "create a new database" msgstr "vytvoří novou databázi" -#: sql_help.h:440 +#: sql_help.c:5029 msgid "define a new domain" msgstr "definuje novou atributovou doménu" -#: sql_help.h:445 +#: sql_help.c:5034 msgid "define a new event trigger" msgstr "definuje nový event trigger" -#: sql_help.h:450 +#: sql_help.c:5039 msgid "install an extension" msgstr "instaluje rozšíření" -#: sql_help.h:455 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" msgstr "definuje nový foreign-data wrapper" -#: sql_help.h:460 +#: sql_help.c:5049 msgid "define a new foreign table" msgstr "definuje nový foreign tabulku" -#: sql_help.h:465 +#: sql_help.c:5054 msgid "define a new function" msgstr "definuje novou funkci" -#: sql_help.h:470 sql_help.h:505 sql_help.h:575 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" msgstr "definuje novou databázovou roli" -#: sql_help.h:475 +#: sql_help.c:5064 msgid "define a new index" msgstr "definuje nový index" -#: sql_help.h:480 +#: sql_help.c:5069 msgid "define a new procedural language" msgstr "definuje nový procedurální jazyk" -#: sql_help.h:485 +#: sql_help.c:5074 msgid "define a new materialized view" msgstr "definuje nový materializovaný pohled" -#: sql_help.h:490 +#: sql_help.c:5079 msgid "define a new operator" msgstr "definuje nový operátor" -#: sql_help.h:495 +#: sql_help.c:5084 msgid "define a new operator class" msgstr "definuje novou třídu operátorů" -#: sql_help.h:500 +#: sql_help.c:5089 msgid "define a new operator family" msgstr "definuje novou rodinu operátorů" -#: sql_help.h:510 +#: sql_help.c:5094 +msgid "define a new row level security policy for a table" +msgstr "definute novou row level security politiku pro tabulku" + +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "definuje novou proceduru" + +#: sql_help.c:5104 +msgid "define a new publication" +msgstr "definuje novou publikaci" + +#: sql_help.c:5114 msgid "define a new rewrite rule" msgstr "definuje nové pÅ™episovací pravidlo (rule)" -#: sql_help.h:515 +#: sql_help.c:5119 msgid "define a new schema" msgstr "definuje nové schéma" -#: sql_help.h:520 +#: sql_help.c:5124 msgid "define a new sequence generator" msgstr "definuje nový generátor sekvencí" -#: sql_help.h:525 +#: sql_help.c:5129 msgid "define a new foreign server" msgstr "definuje nový foreign server" -#: sql_help.h:530 +#: sql_help.c:5134 +msgid "define extended statistics" +msgstr "definuje nové rozšířené statistiky" + +#: sql_help.c:5139 +msgid "define a new subscription" +msgstr "definuje novou subskripci" + +#: sql_help.c:5144 msgid "define a new table" msgstr "definuje novou tabulku" -#: sql_help.h:535 sql_help.h:915 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" msgstr "definuje novou tabulku dle výsledku dotazu" -#: sql_help.h:540 +#: sql_help.c:5154 msgid "define a new tablespace" msgstr "definuje nový tablespace" -#: sql_help.h:545 +#: sql_help.c:5159 msgid "define a new text search configuration" msgstr "definuje novou konfiguraci fulltextového vyhledávání" -#: sql_help.h:550 +#: sql_help.c:5164 msgid "define a new text search dictionary" msgstr "definuje nový slovník pro fulltextové vyhledávání" -#: sql_help.h:555 +#: sql_help.c:5169 msgid "define a new text search parser" msgstr "definuje nový parser pro fulltextové vyhledávání" -#: sql_help.h:560 +#: sql_help.c:5174 msgid "define a new text search template" msgstr "definuje novou Å¡ablonu pro fulltextové vyhledávání" -#: sql_help.h:565 +#: sql_help.c:5179 +msgid "define a new transform" +msgstr "definuje novou transformaci" + +#: sql_help.c:5184 msgid "define a new trigger" msgstr "definuje nový trigger" -#: sql_help.h:570 +#: sql_help.c:5189 msgid "define a new data type" msgstr "definuje nový datový typ" -#: sql_help.h:580 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" msgstr "definuje nové mapování uživatele na vzdálený server" -#: sql_help.h:585 +#: sql_help.c:5204 msgid "define a new view" msgstr "definuje nový pohled" -#: sql_help.h:590 +#: sql_help.c:5209 msgid "deallocate a prepared statement" msgstr "dealokuje pÅ™ipravený dotaz (prepared statement)" -#: sql_help.h:595 +#: sql_help.c:5214 msgid "define a cursor" msgstr "definuje kursor" -#: sql_help.h:600 +#: sql_help.c:5219 msgid "delete rows of a table" msgstr "smaže řádky z takulky" -#: sql_help.h:605 +#: sql_help.c:5224 msgid "discard session state" msgstr "zahodí stav session" -#: sql_help.h:610 +#: sql_help.c:5229 msgid "execute an anonymous code block" msgstr "spustí anonymní blok kódu" -#: sql_help.h:615 +#: sql_help.c:5234 +msgid "remove an access method" +msgstr "odstraní definici přístupové metody" + +#: sql_help.c:5239 msgid "remove an aggregate function" msgstr "odstraní agregaÄní funkci" -#: sql_help.h:620 +#: sql_help.c:5244 msgid "remove a cast" msgstr "odstraní definici pÅ™etypování" -#: sql_help.h:625 +#: sql_help.c:5249 msgid "remove a collation" msgstr "odstraní collation" -#: sql_help.h:630 +#: sql_help.c:5254 msgid "remove a conversion" msgstr "odstraní konverzi" -#: sql_help.h:635 +#: sql_help.c:5259 msgid "remove a database" msgstr "odstraní databázi" -#: sql_help.h:640 +#: sql_help.c:5264 msgid "remove a domain" msgstr "odstraní doménu" -#: sql_help.h:645 +#: sql_help.c:5269 msgid "remove an event trigger" msgstr "odstraní event trigger" -#: sql_help.h:650 +#: sql_help.c:5274 msgid "remove an extension" msgstr "odstraní extension" -#: sql_help.h:655 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" msgstr "odstraní foreign-data wrapper" -#: sql_help.h:660 +#: sql_help.c:5284 msgid "remove a foreign table" msgstr "odstraní foreign tabulku" -#: sql_help.h:665 +#: sql_help.c:5289 msgid "remove a function" msgstr "odstraní funkci" -#: sql_help.h:670 sql_help.h:710 sql_help.h:775 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" msgstr "odstraní databázovou roli" -#: sql_help.h:675 +#: sql_help.c:5299 msgid "remove an index" msgstr "odstraní index" -#: sql_help.h:680 +#: sql_help.c:5304 msgid "remove a procedural language" msgstr "odstraní procedurální jazyk" -#: sql_help.h:685 +#: sql_help.c:5309 msgid "remove a materialized view" msgstr "odstraní materializovaný pohled" -#: sql_help.h:690 +#: sql_help.c:5314 msgid "remove an operator" msgstr "odstraní operátor" -#: sql_help.h:695 +#: sql_help.c:5319 msgid "remove an operator class" msgstr "odstraní třídu operátorů" -#: sql_help.h:700 +#: sql_help.c:5324 msgid "remove an operator family" msgstr "odstraní rodinu operátorů" -#: sql_help.h:705 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" msgstr "odstraní objekty vlastnÄ›né databázovou rolí" -#: sql_help.h:715 +#: sql_help.c:5334 +msgid "remove a row level security policy from a table" +msgstr "odstraní row level security politiku z tabulky" + +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "odstraní proceduru" + +#: sql_help.c:5344 +msgid "remove a publication" +msgstr "odstraní publikaci" + +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "odstraní rutinu" + +#: sql_help.c:5359 msgid "remove a rewrite rule" msgstr "odstraní pÅ™episovací pravidlo (rule)" -#: sql_help.h:720 +#: sql_help.c:5364 msgid "remove a schema" msgstr "odstraní schéma" -#: sql_help.h:725 +#: sql_help.c:5369 msgid "remove a sequence" msgstr "odstraní sekvenci" -#: sql_help.h:730 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" msgstr "odstraní deskriptor foreign serveru" -#: sql_help.h:735 +#: sql_help.c:5379 +msgid "remove extended statistics" +msgstr "odstraní rozšířené statistiky" + +#: sql_help.c:5384 +msgid "remove a subscription" +msgstr "odstraní subskripci" + +#: sql_help.c:5389 msgid "remove a table" msgstr "odstraní tabulku" -#: sql_help.h:740 +#: sql_help.c:5394 msgid "remove a tablespace" msgstr "odstraní tablespace" -#: sql_help.h:745 +#: sql_help.c:5399 msgid "remove a text search configuration" msgstr "odstraní konfiguraci fulltextového vyhledávání" -#: sql_help.h:750 +#: sql_help.c:5404 msgid "remove a text search dictionary" msgstr "odstraní slovn?ik pro fulltextové vyhledávání" -#: sql_help.h:755 +#: sql_help.c:5409 msgid "remove a text search parser" msgstr "odstraní parser pro fulltextové vyhledávání" -#: sql_help.h:760 +#: sql_help.c:5414 msgid "remove a text search template" msgstr "odstraní Å ablonu fulltextového vyhledávání" -#: sql_help.h:765 +#: sql_help.c:5419 +msgid "remove a transform" +msgstr "odstraní transformaci" + +#: sql_help.c:5424 msgid "remove a trigger" msgstr "odstraní trigger" -#: sql_help.h:770 +#: sql_help.c:5429 msgid "remove a data type" msgstr "odstraní datový typ" -#: sql_help.h:780 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" msgstr "odstraní mapování uživatele z foreign serveru" -#: sql_help.h:785 +#: sql_help.c:5444 msgid "remove a view" msgstr "odstraní náhled" -#: sql_help.h:795 +#: sql_help.c:5454 msgid "execute a prepared statement" msgstr "provede pÅ™ipravený dotaz (prepared statement)" -#: sql_help.h:800 +#: sql_help.c:5459 msgid "show the execution plan of a statement" msgstr "ukáže provádÄ›cí plán dotazu" -#: sql_help.h:805 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" msgstr "naÄte řádky z výsledku dotazu pomocí kursoru" -#: sql_help.h:810 +#: sql_help.c:5469 msgid "define access privileges" msgstr "definuje přístupová práva" -#: sql_help.h:815 +#: sql_help.c:5474 +msgid "import table definitions from a foreign server" +msgstr "importuje definice tabulek z foreign serveru" + +#: sql_help.c:5479 msgid "create new rows in a table" msgstr "pÅ™idá nové řádky do tabulky" -#: sql_help.h:820 +#: sql_help.c:5484 msgid "listen for a notification" msgstr "naslouchá upozornÄ›ním" -#: sql_help.h:825 +#: sql_help.c:5489 msgid "load a shared library file" msgstr "naÄte sdílenou knihovnu" -#: sql_help.h:830 +#: sql_help.c:5494 msgid "lock a table" msgstr "uzamkne tabulku" -#: sql_help.h:835 +#: sql_help.c:5499 msgid "position a cursor" msgstr "pÅ™emístí kursor" -#: sql_help.h:840 +#: sql_help.c:5504 msgid "generate a notification" msgstr "generuje upozornÄ›ní" -#: sql_help.h:845 +#: sql_help.c:5509 msgid "prepare a statement for execution" msgstr "pÅ™ipraví a uloží dotaz pro provedení" -#: sql_help.h:850 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" msgstr "přípraví aktuální transakci pro dvoufázoví commit" -#: sql_help.h:855 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" msgstr "zmÄ›ní vlastníka databázových objektů vlastnÄ›ných databázovou rolí" -#: sql_help.h:860 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" msgstr "nahraÄ obsah materializovaného pohledu" -#: sql_help.h:865 +#: sql_help.c:5529 msgid "rebuild indexes" msgstr "znovuvytvoří indexy" -#: sql_help.h:870 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" msgstr "odstraní dříve vytvoÅ™ený savepoint" -#: sql_help.h:875 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" msgstr "pÅ™enastaví parametr bÄ›hu na implicitní hodnotu" -#: sql_help.h:880 +#: sql_help.c:5544 msgid "remove access privileges" msgstr "odstraní přístupová práva" -#: sql_help.h:890 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "zruší transakci, která byla pÅ™ipravena pro dvoufázový commit" -#: sql_help.h:895 +#: sql_help.c:5559 msgid "roll back to a savepoint" msgstr "vrátí se na savepoint" -#: sql_help.h:900 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" msgstr "definuje nový savepoint uvnitÅ™ aktuální transakce" -#: sql_help.h:905 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" msgstr "definuje nebo zmÄ›ní bezpeÄnostní Å¡títek aplikovaný na objekt" -#: sql_help.h:910 sql_help.h:955 sql_help.h:985 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" msgstr "vybere řádky z tabulky nebo náhledu" -#: sql_help.h:920 +#: sql_help.c:5584 msgid "change a run-time parameter" msgstr "zmÄ›ní parametry bÄ›hu" -#: sql_help.h:925 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" msgstr "nastaví mód kontroly omezení (constraints) pro aktuální transakci" -#: sql_help.h:930 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" msgstr "nastaví uživatelský identifikátor aktuální session" -#: sql_help.h:935 +#: sql_help.c:5599 msgid "" "set the session user identifier and the current user identifier of the " "current session" @@ -4391,45 +6173,45 @@ msgstr "" "nastaví uživatelský identifikátor session a identifikátor " "aktuálníhouživatele pro aktuální session" -#: sql_help.h:940 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" msgstr "nastaví charakteristiku pro aktualní trasakci" -#: sql_help.h:945 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" msgstr "zobrazí hodnoty run-time parametrů" -#: sql_help.h:960 +#: sql_help.c:5624 msgid "empty a table or set of tables" msgstr "zruší obsah tabulky nebo skupiny tabulek" -#: sql_help.h:965 +#: sql_help.c:5629 msgid "stop listening for a notification" msgstr "ukonÄí naslouchání pÅ™ipomínkám" -#: sql_help.h:970 +#: sql_help.c:5634 msgid "update rows of a table" msgstr "aktualizuje řádky tabulky" -#: sql_help.h:975 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" msgstr "provede úklid a případnÄ› analýzu databáze" -#: sql_help.h:980 +#: sql_help.c:5644 msgid "compute a set of rows" msgstr "spoÄítá množinu řádek" -#: startup.c:167 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s: -1 může být použito pouze pro neinteraktivní módy\n" -#: startup.c:269 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: nelze otevřít logovací soubor \"%s\": %s\n" -#: startup.c:331 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" @@ -4438,32 +6220,27 @@ msgstr "" "Pro získání nápovÄ›dy napiÅ¡te \"help\".\n" "\n" -#: startup.c:476 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s: nelze nastavit parametr zobrazení \"%s\"\n" -#: startup.c:516 -#, c-format -msgid "%s: could not delete variable \"%s\"\n" -msgstr "%s: nelze smazat promÄ›nnou \"%s\"\n" - -#: startup.c:526 -#, c-format -msgid "%s: could not set variable \"%s\"\n" -msgstr "%s: nelze nastavit promÄ›nnou \"%s\"\n" - -#: startup.c:569 startup.c:575 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: startup.c:592 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" msgstr "%s: varování: nadbyteÄný parametr příkazové řádky \"%s\" ignorován\n" -#: tab-complete.c:3962 +#: startup.c:729 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: nelze najít vlastní spustitelný soubor\n" + +#: tab-complete.c:4480 #, c-format msgid "" "tab completion query failed: %s\n" @@ -4474,64 +6251,164 @@ msgstr "" "Dotaz byl:\n" "%s\n" -#: variables.c:115 +#: variables.c:139 #, c-format -msgid "unrecognized Boolean value; assuming \"on\"\n" -msgstr "nerozpoznaná boolean hodnota; pÅ™edpokládám \"on\".\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "nerozpoznaná hodnota \"%s\" pro \"%s\": oÄekáván Boolean výraz\n" -#~ msgid "%s: -1 is incompatible with -c and -l\n" -#~ msgstr "%s: -1 je nekompatibilní s -c a -l\n" +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected\n" +msgstr "neplatná hodnota \"%s\" pro \"%s\" oÄekáváno celé Äíslo\n" -#~ msgid " \\l[+] list all databases\n" -#~ msgstr " \\l[+] seznam databází\n" +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"\n" +msgstr "neplatný název promÄ›nné: \"%s\"\n" -#~ msgid "column" -#~ msgstr "sloupec" +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s.\n" +msgstr "" +"nerozpoznaná hodnota \"%s\" pro \"%s\"\n" +"Možné hodnoty jsou: %s.\n" -#~ msgid "new_column" -#~ msgstr "nový_sloupec" +#~ msgid "\\%s: error\n" +#~ msgstr "\\%s: chyba\n" -#~ msgid "tablespace" -#~ msgstr "tablespace" +#~ msgid "\\copy: %s" +#~ msgstr "\\copy: %s" -#~ msgid "schema" -#~ msgstr "schéma" +#~ msgid "\\copy: unexpected response (%d)\n" +#~ msgstr "\\copy: neoÄekávaná odezva (%d)\n" -#~ msgid "contains support for command-line editing" -#~ msgstr "obsahuje podporu pro editaci příkazové řádky " +#~ msgid "data type" +#~ msgstr "datový typ" -#~ msgid "ABORT [ WORK | TRANSACTION ]" -#~ msgstr "ABORT [ WORK | TRANSACTION ]" +#~ msgid " on host \"%s\"" +#~ msgstr " na poÄítaÄ \"%s\"" -#~ msgid " \"%s\" IN %s %s" -#~ msgstr " \"%s\" IN %s %s" +#~ msgid " at port \"%s\"" +#~ msgstr " na port \"%s\"" + +#~ msgid " as user \"%s\"" +#~ msgstr " jako uživatel \"%s\"" #~ msgid "define a new constraint trigger" #~ msgstr "defunuje nový constraint trigger" -#~ msgid "out of memory" -#~ msgstr "nedostatek pamÄ›ti" +#~ msgid " \"%s\" IN %s %s" +#~ msgstr " \"%s\" IN %s %s" -#~ msgid " as user \"%s\"" -#~ msgstr " jako uživatel \"%s\"" +#~ msgid "ABORT [ WORK | TRANSACTION ]" +#~ msgstr "ABORT [ WORK | TRANSACTION ]" -#~ msgid " at port \"%s\"" -#~ msgstr " na port \"%s\"" +#~ msgid "contains support for command-line editing" +#~ msgstr "obsahuje podporu pro editaci příkazové řádky " -#~ msgid " on host \"%s\"" -#~ msgstr " na poÄítaÄ \"%s\"" +#~ msgid "tablespace" +#~ msgstr "tablespace" -#~ msgid "data type" -#~ msgstr "datový typ" +#~ msgid "new_column" +#~ msgstr "nový_sloupec" -#~ msgid "aggregate" -#~ msgstr "agregace" +#~ msgid "column" +#~ msgstr "sloupec" -#~ msgid "\\copy: unexpected response (%d)\n" -#~ msgstr "\\copy: neoÄekávaná odezva (%d)\n" +#~ msgid " \\l[+] list all databases\n" +#~ msgstr " \\l[+] seznam databází\n" -#~ msgid "\\copy: %s" -#~ msgstr "\\copy: %s" +#~ msgid "%s: -1 is incompatible with -c and -l\n" +#~ msgstr "%s: -1 je nekompatibilní s -c a -l\n" -#~ msgid "\\%s: error\n" -#~ msgstr "\\%s: chyba\n" +#~ msgid "unrecognized Boolean value; assuming \"on\"\n" +#~ msgstr "nerozpoznaná boolean hodnota; pÅ™edpokládám \"on\".\n" + +#~ msgid "%s: could not set variable \"%s\"\n" +#~ msgstr "%s: nelze nastavit promÄ›nnou \"%s\"\n" + +#~ msgid "attribute" +#~ msgstr "atribut" + +#~ msgid "input_data_type" +#~ msgstr "vstupní_datový_typ" + +#~ msgid "agg_type" +#~ msgstr "typ_agregace" + +#~ msgid "agg_name" +#~ msgstr "jméno_agregace" + +#~ msgid "(No rows)\n" +#~ msgstr "(Žádné řádky)\n" + +#~ msgid " -?, --help show this help, then exit\n" +#~ msgstr " -?, --help ukáže tuto nápovÄ›du a skonÄí\n" + +#~ msgid "could not get current user name: %s\n" +#~ msgstr "nelze získat aktuální uživatelské jméno: %s\n" + +#~ msgid "Object Description" +#~ msgstr "Popis objektu" + +#~ msgid "Modifier" +#~ msgstr "Modifikátor" + +#~ msgid "No relations found.\n" +#~ msgstr "Žádné relace nenalezeny.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "Odpovídající relace nebyla nalezena.\n" + +#~ msgid "No settings found.\n" +#~ msgstr "Žádné nastavení nenalezeno.\n" + +#~ msgid "No matching settings found.\n" +#~ msgstr "Odpovídající relace nebyla nalezena.\n" + +#~ msgid "No per-database role settings support in this server version.\n" +#~ msgstr "Tato verze serveru nepodporuje nastavení rolí dle databáze.\n" + +#~ msgid "default %s" +#~ msgstr "implicitnÄ› %s" + +#~ msgid "not null" +#~ msgstr "not null" + +#~ msgid "collate %s" +#~ msgstr "collate %s" + +#~ msgid "Value" +#~ msgstr "Hodnota" + +#~ msgid "Modifiers" +#~ msgstr "Modifikátory" + +#~ msgid "normal" +#~ msgstr "normal" + +#~ msgid "could not set variable \"%s\"\n" +#~ msgstr "nelze nastavit promÄ›nnou \"%s\"\n" + +#~ msgid "Watch every %lds\t%s" +#~ msgstr "Zkontroluj každých %lds\t%s" + +#~ msgid "Showing only tuples." +#~ msgstr "Zobrazovány jsou pouze záznamy." + +#~ msgid "Showing locale-adjusted numeric output." +#~ msgstr "Zobrazí Äíselný výstup dle národního nastavení." + +#~ msgid "SSL connection (unknown cipher)\n" +#~ msgstr "SSL spojení (neznámá Å¡ifra)\n" + +#~ msgid "+ opt(%d) = |%s|\n" +#~ msgstr "+ opt(%d) = |%s|\n" + +#~ msgid "\\%s: error while setting variable\n" +#~ msgstr "\\%s: chyba pÅ™i nastavování promÄ›nné\n" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "ZaÅ¡ifrování hesla selhalo.\n" diff --git a/src/bin/psql/po/de.po b/src/bin/psql/po/de.po index 09c41666752..8ef13254f63 100644 --- a/src/bin/psql/po/de.po +++ b/src/bin/psql/po/de.po @@ -1,14 +1,14 @@ # German message translation file for psql -# Peter Eisentraut , 2001 - 2017. +# Peter Eisentraut , 2001 - 2018. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" +"Project-Id-Version: PostgreSQL 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-13 22:14+0000\n" -"PO-Revision-Date: 2017-03-13 22:33-0400\n" +"POT-Creation-Date: 2018-09-14 05:15+0000\n" +"PO-Revision-Date: 2018-09-14 08:22+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -53,8 +53,7 @@ msgid "pclose failed: %s" msgstr "pclose fehlgeschlagen: %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:345 input.c:227 mainloop.c:80 -#: mainloop.c:261 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 #, c-format msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" @@ -69,7 +68,7 @@ msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n" msgid "could not look up effective user ID %ld: %s" msgstr "konnte effektive Benutzer-ID %ld nicht nachschlagen: %s" -#: ../../common/username.c:45 command.c:302 +#: ../../common/username.c:45 command.c:554 msgid "user does not exist" msgstr "Benutzer existiert nicht" @@ -120,250 +119,270 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu Zeile)" msgstr[1] "(%lu Zeilen)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:2915 #, c-format msgid "Interrupted\n" msgstr "Unterbrochen\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:2979 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kann keinen weiteren Spaltenkopf zur Tabelle hinzufügen: Spaltenzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3019 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Cann keine weitere Zelle zur Tabelle hinzufügen: Zellengesamtzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3268 #, c-format msgid "invalid output format (internal error): %d" msgstr "ungültiges Ausgabeformat (interner Fehler): %d" -#: ../../fe_utils/psqlscan.l:714 +#: ../../fe_utils/psqlscan.l:724 #, c-format msgid "skipping recursive expansion of variable \"%s\"\n" msgstr "rekursive Auswertung der Variable »%s« wird ausgelassen\n" -#: command.c:126 +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "Ungültige Anweisung \\%s. Versuchen Sie \\? für Hilfe.\n" -#: command.c:128 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" msgstr "ungültige Anweisung \\%s\n" -#: command.c:139 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s: überflüssiges Argument »%s« ignoriert\n" -#: command.c:300 +#: command.c:292 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "Befehl \\%s ignoriert; verwenden Sie \\endif oder Strg-C um den aktuellen \\if-Block zu beenden\n" + +#: command.c:552 #, c-format msgid "could not get home directory for user ID %ld: %s\n" msgstr "konnte Home-Verzeichnis für Benutzer-ID %ld nicht ermitteln: %s\n" -#: command.c:318 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s: konnte nicht in das Verzeichnis »%s« wechseln: %s\n" -#: command.c:333 common.c:609 common.c:667 common.c:1203 +#: command.c:595 common.c:696 common.c:754 common.c:1292 #, c-format msgid "You are currently not connected to a database.\n" msgstr "Sie sind gegenwärtig nicht mit einer Datenbank verbunden.\n" -#: command.c:358 +#: command.c:602 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« via Socket in »%s« auf Port »%s«.\n" -#: command.c:361 +#: command.c:605 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Sie sind verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« auf Port »%s«.\n" -#: command.c:593 command.c:666 command.c:765 command.c:1609 +#: command.c:895 command.c:991 command.c:2376 #, c-format msgid "no query buffer\n" msgstr "kein Anfragepuffer\n" -#: command.c:626 command.c:3582 +#: command.c:928 command.c:4648 #, c-format msgid "invalid line number: %s\n" msgstr "ungültige Zeilennummer: %s\n" -#: command.c:659 +#: command.c:982 #, c-format msgid "The server (version %s) does not support editing function source.\n" msgstr "Der Server (Version %s) unterstützt das Bearbeiten des Funktionsquelltextes nicht.\n" -#: command.c:740 command.c:811 -msgid "No changes" -msgstr "keine Änderungen" - -#: command.c:758 +#: command.c:985 #, c-format msgid "The server (version %s) does not support editing view definitions.\n" msgstr "Der Server (Version %s) unterstützt das Bearbeiten von Sichtdefinitionen nicht.\n" -#: command.c:865 +#: command.c:1067 +msgid "No changes" +msgstr "keine Änderungen" + +#: command.c:1144 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "%s: ungültiger Kodierungsname oder Umwandlungsprozedur nicht gefunden\n" -#: command.c:890 command.c:1986 command.c:3684 common.c:158 common.c:205 -#: common.c:502 common.c:1249 common.c:1277 common.c:1378 copy.c:489 -#: copy.c:699 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 #, c-format msgid "%s" msgstr "%s" -#: command.c:894 +#: command.c:1183 msgid "out of memory" msgstr "Speicher aufgebraucht" -#: command.c:897 +#: command.c:1186 msgid "There is no previous error." msgstr "Es gibt keinen vorangegangenen Fehler." -#: command.c:996 command.c:1046 command.c:1060 command.c:1077 command.c:1181 -#: command.c:1351 command.c:1591 command.c:1620 +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s: notwendiges Argument fehlt\n" -#: command.c:1109 +#: command.c:1505 +#, c-format +msgid "\\elif: cannot occur after \\else\n" +msgstr "\\elif: kann nicht nach \\else kommen\n" + +#: command.c:1510 +#, c-format +msgid "\\elif: no matching \\if\n" +msgstr "\\elif: kein passendes \\if\n" + +#: command.c:1574 +#, c-format +msgid "\\else: cannot occur after \\else\n" +msgstr "\\else: kann nicht nach \\else kommen\n" + +#: command.c:1579 +#, c-format +msgid "\\else: no matching \\if\n" +msgstr "\\else: kein passendes \\if\n" + +#: command.c:1619 +#, c-format +msgid "\\endif: no matching \\if\n" +msgstr "\\endif: kein passendes \\if\n" + +#: command.c:1774 msgid "Query buffer is empty." msgstr "Anfragepuffer ist leer." -#: command.c:1119 +#: command.c:1796 msgid "Enter new password: " msgstr "Neues Passwort eingeben: " -#: command.c:1120 +#: command.c:1797 msgid "Enter it again: " msgstr "Geben Sie es noch einmal ein: " -#: command.c:1124 +#: command.c:1801 #, c-format msgid "Passwords didn't match.\n" msgstr "Passwörter stimmten nicht überein.\n" -#: command.c:1142 +#: command.c:1900 #, c-format -msgid "Password encryption failed.\n" -msgstr "Passwortverschlüsselung ist fehlgeschlagen.\n" - -#: command.c:1211 -#, fuzzy, c-format -#| msgid "%s: could not delete variable \"%s\"\n" msgid "\\%s: could not read value for variable\n" -msgstr "%s: konnte Variable »%s« nicht löschen\n" +msgstr "\\%s: konnte Wert für Variable nicht lesen\n" -#: command.c:1281 +#: command.c:2003 msgid "Query buffer reset (cleared)." msgstr "Anfragepuffer wurde gelöscht." -#: command.c:1293 +#: command.c:2025 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Befehlsgeschichte in Datei »%s« geschrieben.\n" -#: command.c:1356 +#: command.c:2112 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s: Name der Umgebungsvariable darf kein »=« enthalten\n" -#: command.c:1400 +#: command.c:2173 #, c-format msgid "The server (version %s) does not support showing function source.\n" msgstr "Der Server (Version %s) unterstützt das Anzeigen des Funktionsquelltextes nicht.\n" -#: command.c:1407 -#, c-format -msgid "function name is required\n" -msgstr "Funktionsname wird benötigt\n" - -#: command.c:1482 +#: command.c:2176 #, c-format msgid "The server (version %s) does not support showing view definitions.\n" msgstr "Der Server (Version %s) unterstützt das Anzeigen von Sichtdefinitionen nicht.\n" -#: command.c:1489 +#: command.c:2183 +#, c-format +msgid "function name is required\n" +msgstr "Funktionsname wird benötigt\n" + +#: command.c:2185 #, c-format msgid "view name is required\n" msgstr "Sichtname wird benötigt\n" -#: command.c:1576 +#: command.c:2315 msgid "Timing is on." msgstr "Zeitmessung ist an." -#: command.c:1578 +#: command.c:2317 msgid "Timing is off." msgstr "Zeitmessung ist aus." -#: command.c:1638 command.c:1658 command.c:2335 command.c:2338 command.c:2341 -#: command.c:2347 command.c:2349 command.c:2357 command.c:2367 command.c:2376 -#: command.c:2390 command.c:2407 command.c:2465 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:712 psqlscanslash.l:723 -#: psqlscanslash.l:733 +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:1752 -#, c-format -msgid "+ opt(%d) = |%s|\n" -msgstr "+ opt(%d) = |%s|\n" - -#: command.c:1778 startup.c:202 +#: command.c:2814 startup.c:214 startup.c:265 msgid "Password: " msgstr "Passwort: " -#: command.c:1783 startup.c:204 +#: command.c:2819 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "Passwort für Benutzer %s: " -#: command.c:1833 +#: command.c:2869 #, c-format msgid "All connection parameters must be supplied because no database connection exists\n" msgstr "Alle Verbindungsparameter müssen angegeben werden, weil keine Datenbankverbindung besteht\n" -#: command.c:1990 +#: command.c:3037 #, c-format msgid "Previous connection kept\n" msgstr "Vorherige Verbindung wurde behalten\n" -#: command.c:1994 +#: command.c:3041 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:2030 +#: command.c:3077 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« via Socket in »%s« auf Port »%s«.\n" -#: command.c:2033 +#: command.c:3080 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s« auf Host »%s« auf Port »%s«.\n" -#: command.c:2037 +#: command.c:3084 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Sie sind jetzt verbunden mit der Datenbank »%s« als Benutzer »%s«.\n" -#: command.c:2070 +#: command.c:3117 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, Server %s)\n" -#: command.c:2078 +#: command.c:3125 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -372,24 +391,24 @@ msgstr "" "WARNUNG: %s-Hauptversion %s, Server-Hauptversion %s.\n" " Einige Features von psql werden eventuell nicht funktionieren.\n" -#: command.c:2115 +#: command.c:3162 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "SSL-Verbindung (Protokoll: %s, Verschlüsselungsmethode: %s, Bits: %s, Komprimierung: %s)\n" -#: command.c:2116 command.c:2117 command.c:2118 +#: command.c:3163 command.c:3164 command.c:3165 msgid "unknown" msgstr "unbekannt" -#: command.c:2119 help.c:45 +#: command.c:3166 help.c:45 msgid "off" msgstr "aus" -#: command.c:2119 help.c:45 +#: command.c:3166 help.c:45 msgid "on" msgstr "an" -#: command.c:2139 +#: command.c:3186 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -401,239 +420,239 @@ msgstr "" " richtig. Einzelheiten finden Sie auf der psql-Handbuchseite unter\n" " »Notes for Windows users«.\n" -#: command.c:2224 +#: command.c:3290 #, c-format msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" msgstr "Umgebungsvariable PSQL_EDITOR_LINENUMBER_ARG muss gesetzt werden, um eine Zeilennummer angeben zu können\n" -#: command.c:2253 +#: command.c:3319 #, c-format msgid "could not start editor \"%s\"\n" msgstr "konnte Editor »%s« nicht starten\n" -#: command.c:2255 +#: command.c:3321 #, c-format msgid "could not start /bin/sh\n" msgstr "konnte /bin/sh nicht starten\n" -#: command.c:2293 +#: command.c:3359 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "konnte temporäres Verzeichnis nicht finden: %s\n" -#: command.c:2320 +#: command.c:3386 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "konnte temporäre Datei »%s« nicht öffnen: %s\n" -#: command.c:2594 +#: command.c:3660 #, c-format msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" msgstr "\\pset: zulässige Formate sind unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" -#: command.c:2612 +#: command.c:3678 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "\\pset: zulässige Linienstile sind ascii, old-ascii, unicode\n" -#: command.c:2627 +#: command.c:3693 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double\n" msgstr "\\pset: zulässige Unicode-Rahmnenlinienstile sind single, double\n" -#: command.c:2642 +#: command.c:3708 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double\n" msgstr "\\pset: zulässige Unicode-Spaltenlinienstile sind single, double\n" -#: command.c:2657 +#: command.c:3723 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double\n" msgstr "\\pset: zulässige Unicode-Kopflinienstile sind single, double\n" -#: command.c:2822 command.c:3001 +#: command.c:3888 command.c:4067 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "\\pset: unbekannte Option: %s\n" -#: command.c:2840 +#: command.c:3906 #, c-format msgid "Border style is %d.\n" msgstr "Rahmenstil ist %d.\n" -#: command.c:2846 +#: command.c:3912 #, c-format msgid "Target width is unset.\n" msgstr "Zielbreite ist nicht gesetzt.\n" -#: command.c:2848 +#: command.c:3914 #, c-format msgid "Target width is %d.\n" msgstr "Zielbreite ist %d.\n" -#: command.c:2855 +#: command.c:3921 #, c-format msgid "Expanded display is on.\n" msgstr "Erweiterte Anzeige ist an.\n" -#: command.c:2857 +#: command.c:3923 #, c-format msgid "Expanded display is used automatically.\n" msgstr "Erweiterte Anzeige wird automatisch verwendet.\n" -#: command.c:2859 +#: command.c:3925 #, c-format msgid "Expanded display is off.\n" msgstr "Erweiterte Anzeige ist aus.\n" -#: command.c:2866 command.c:2874 +#: command.c:3932 command.c:3940 #, c-format msgid "Field separator is zero byte.\n" msgstr "Feldtrennzeichen ist ein Null-Byte.\n" -#: command.c:2868 +#: command.c:3934 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Feldtrennzeichen ist »%s«.\n" -#: command.c:2881 +#: command.c:3947 #, c-format msgid "Default footer is on.\n" msgstr "Standardfußzeile ist an.\n" -#: command.c:2883 +#: command.c:3949 #, c-format msgid "Default footer is off.\n" msgstr "Standardfußzeile ist aus.\n" -#: command.c:2889 +#: command.c:3955 #, c-format msgid "Output format is %s.\n" msgstr "Ausgabeformat ist »%s«.\n" -#: command.c:2895 +#: command.c:3961 #, c-format msgid "Line style is %s.\n" msgstr "Linienstil ist %s.\n" -#: command.c:2902 +#: command.c:3968 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null-Anzeige ist »%s«.\n" -#: command.c:2910 +#: command.c:3976 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "Lokalisiertes Format für numerische Daten ist an.\n" -#: command.c:2912 +#: command.c:3978 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "Lokalisiertes Format für numerische Daten ist aus.\n" -#: command.c:2919 +#: command.c:3985 #, c-format msgid "Pager is used for long output.\n" msgstr "Pager wird für lange Ausgaben verwendet.\n" -#: command.c:2921 +#: command.c:3987 #, c-format msgid "Pager is always used.\n" msgstr "Pager wird immer verwendet.\n" -#: command.c:2923 +#: command.c:3989 #, c-format msgid "Pager usage is off.\n" msgstr "Pager-Verwendung ist aus.\n" -#: command.c:2929 +#: command.c:3995 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "Pager wird nicht für weniger als %d Zeile verwendet werden.\n" msgstr[1] "Pager wird nicht für weniger als %d Zeilen verwendet werden.\n" -#: command.c:2939 command.c:2949 +#: command.c:4005 command.c:4015 #, c-format msgid "Record separator is zero byte.\n" msgstr "Satztrennzeichen ist ein Null-Byte.\n" -#: command.c:2941 +#: command.c:4007 #, c-format msgid "Record separator is .\n" msgstr "Satztrennzeichen ist .\n" -#: command.c:2943 +#: command.c:4009 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Satztrennzeichen ist »%s«.\n" -#: command.c:2956 +#: command.c:4022 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Tabellenattribute sind »%s«.\n" -#: command.c:2959 +#: command.c:4025 #, c-format msgid "Table attributes unset.\n" msgstr "Tabellenattribute sind nicht gesetzt.\n" -#: command.c:2966 +#: command.c:4032 #, c-format msgid "Title is \"%s\".\n" msgstr "Titel ist »%s«.\n" -#: command.c:2968 +#: command.c:4034 #, c-format msgid "Title is unset.\n" msgstr "Titel ist nicht gesetzt.\n" -#: command.c:2975 +#: command.c:4041 #, c-format msgid "Tuples only is on.\n" msgstr "Nur Datenzeilen ist an.\n" -#: command.c:2977 +#: command.c:4043 #, c-format msgid "Tuples only is off.\n" msgstr "Nur Datenzeilen ist aus.\n" -#: command.c:2983 +#: command.c:4049 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Unicode-Rahmenlinienstil ist »%s«.\n" -#: command.c:2989 +#: command.c:4055 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Unicode-Spaltenlinienstil ist »%s«.\n" -#: command.c:2995 +#: command.c:4061 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Unicode-Kopflinienstil ist »%s«.\n" -#: command.c:3155 +#: command.c:4221 #, c-format msgid "\\!: failed\n" msgstr "\\!: fehlgeschlagen\n" -#: command.c:3180 common.c:715 +#: command.c:4246 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch kann nicht mit einer leeren Anfrage verwendet werden\n" -#: command.c:3221 +#: command.c:4287 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (alle %gs)\n" -#: command.c:3224 +#: command.c:4290 #, c-format msgid "%s (every %gs)\n" msgstr "%s (alle %gs)\n" -#: command.c:3278 command.c:3285 common.c:615 common.c:622 common.c:1232 +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1321 #, c-format msgid "" "********* QUERY **********\n" @@ -646,97 +665,102 @@ msgstr "" "**************************\n" "\n" -#: command.c:3477 +#: command.c:4543 #, c-format msgid "\"%s.%s\" is not a view\n" msgstr "»%s.%s« ist keine Sicht\n" -#: command.c:3493 +#: command.c:4559 #, c-format msgid "could not parse reloptions array\n" msgstr "konnte reloptions-Array nicht interpretieren\n" -#: common.c:143 +#: common.c:159 #, c-format msgid "cannot escape without active connection\n" msgstr "Escape kann nicht ohne aktive Verbindung ausgeführt werden\n" -#: common.c:376 +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgstr "Argument des Shell-Befehls enthält Newline oder Carriage Return: »%s«\n" + +#: common.c:416 #, c-format msgid "connection to server was lost\n" msgstr "Verbindung zum Server wurde verloren\n" -#: common.c:380 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Die Verbindung zum Server wurde verloren. Versuche Reset: " -#: common.c:385 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "Fehlgeschlagen.\n" -#: common.c:392 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "Erfolgreich.\n" -#: common.c:492 common.c:995 common.c:1167 +#: common.c:532 common.c:1082 common.c:1256 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "unerwarteter PQresultStatus: %d\n" -#: common.c:554 +#: common.c:641 #, c-format msgid "Time: %.3f ms\n" msgstr "Zeit: %.3f ms\n" -#: common.c:569 +#: common.c:656 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%02d:%06.3f)\n" -#: common.c:578 +#: common.c:665 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:585 +#: common.c:672 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Zeit: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:722 +#: common.c:809 #, c-format msgid "\\watch cannot be used with COPY\n" msgstr "\\watch kann nicht mit COPY verwendet werden\n" -#: common.c:727 +#: common.c:814 #, c-format msgid "unexpected result status for \\watch\n" msgstr "unerwarteter Ergebnisstatus für \\watch\n" -#: common.c:756 +#: common.c:843 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Asynchrone Benachrichtigung »%s« mit Daten »%s« vom Serverprozess mit PID %d empfangen.\n" -#: common.c:759 +#: common.c:846 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Asynchrone Benachrichtigung »%s« vom Serverprozess mit PID %d empfangen.\n" -#: common.c:821 +#: common.c:908 #, c-format msgid "no rows returned for \\gset\n" msgstr "keine Zeilen für \\gset zurückgegeben\n" -#: common.c:826 +#: common.c:913 #, c-format msgid "more than one row returned for \\gset\n" msgstr "mehr als eine Zeile für \\gset zurückgegeben\n" -#: common.c:1212 +#: common.c:1301 #, c-format msgid "" "***(Single step mode: verify command)*******************************************\n" @@ -747,21 +771,37 @@ msgstr "" "%s\n" "***(Drücken Sie die Eingabetaste um fortzufahren oder »x« um abzubrechen)*******\n" -#: common.c:1267 +#: common.c:1356 #, c-format msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" msgstr "Der Server (Version %s) unterstützt keine Sicherungspunkte für ON_ERROR_ROLLBACK.\n" -#: common.c:1323 +#: common.c:1419 #, c-format msgid "STATEMENT: %s\n" msgstr "ANWEISUNG: %s\n" -#: common.c:1366 +#: common.c:1462 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "unerwarteter Transaktionsstatus (%d)\n" +#: common.c:1599 describe.c:1941 +msgid "Column" +msgstr "Spalte" + +#: common.c:1600 describe.c:175 describe.c:390 describe.c:408 describe.c:453 +#: describe.c:470 describe.c:959 describe.c:1123 describe.c:1664 +#: describe.c:1688 describe.c:1942 describe.c:3529 describe.c:3734 +#: describe.c:4925 +msgid "Type" +msgstr "Typ" + +#: common.c:1649 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Der Befehl hat kein Ergebnis oder das Ergebnis hat keine Spalten.\n" + #: copy.c:99 #, c-format msgid "\\copy: arguments required\n" @@ -814,16 +854,16 @@ msgstr "vom Benutzer abgebrochen" #: copy.c:542 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" "Geben Sie die zu kopierenden Daten ein, gefolgt von einem Zeilenende.\n" -"Beenden Sie mit einem Backslash und einem Punkt alleine auf einer Zeile." +"Beenden Sie mit einem Backslash und einem Punkt alleine auf einer Zeile, oder einem EOF-Signal." -#: copy.c:671 +#: copy.c:670 msgid "aborted because of read failure" msgstr "abgebrochen wegen Lesenfehlers" -#: copy.c:695 +#: copy.c:704 msgid "trying to exit copy mode" msgstr "versuche, den COPY-Modus zu verlassen" @@ -872,959 +912,1026 @@ msgstr "\\crosstabview: zweideutiger Spaltenname: »%s«\n" msgid "\\crosstabview: column name not found: \"%s\"\n" msgstr "\\crosstabview: Spaltenname nicht gefunden: »%s«\n" -#: describe.c:72 describe.c:341 describe.c:598 describe.c:729 describe.c:873 -#: describe.c:1034 describe.c:1104 describe.c:3215 describe.c:3421 -#: describe.c:3512 describe.c:3760 describe.c:3900 describe.c:4132 -#: describe.c:4207 describe.c:4218 describe.c:4280 describe.c:4700 -#: describe.c:4783 +#: describe.c:75 describe.c:370 describe.c:675 describe.c:807 describe.c:951 +#: describe.c:1112 describe.c:1184 describe.c:3518 describe.c:3732 +#: describe.c:3823 describe.c:4090 describe.c:4235 describe.c:4476 +#: describe.c:4551 describe.c:4562 describe.c:4624 describe.c:5049 +#: describe.c:5132 msgid "Schema" msgstr "Schema" -#: describe.c:73 describe.c:161 describe.c:227 describe.c:235 describe.c:342 -#: describe.c:599 describe.c:730 describe.c:791 describe.c:874 describe.c:1105 -#: describe.c:3216 describe.c:3344 describe.c:3422 describe.c:3513 -#: describe.c:3592 describe.c:3761 describe.c:3825 describe.c:3901 -#: describe.c:4133 describe.c:4208 describe.c:4219 describe.c:4281 -#: describe.c:4473 describe.c:4557 describe.c:4781 describe.c:4948 -#: describe.c:5136 +#: describe.c:76 describe.c:173 describe.c:240 describe.c:248 describe.c:371 +#: describe.c:676 describe.c:808 describe.c:869 describe.c:952 describe.c:1185 +#: describe.c:3519 describe.c:3655 describe.c:3733 describe.c:3824 +#: describe.c:3903 describe.c:4091 describe.c:4160 describe.c:4236 +#: describe.c:4477 describe.c:4552 describe.c:4563 describe.c:4625 +#: describe.c:4822 describe.c:4906 describe.c:5130 describe.c:5302 +#: describe.c:5527 msgid "Name" msgstr "Name" -#: describe.c:74 describe.c:354 describe.c:400 describe.c:417 +#: describe.c:77 describe.c:383 describe.c:401 describe.c:447 describe.c:464 msgid "Result data type" msgstr "Ergebnisdatentyp" -#: describe.c:82 describe.c:95 describe.c:99 describe.c:355 describe.c:401 -#: describe.c:418 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:384 describe.c:402 +#: describe.c:448 describe.c:465 msgid "Argument data types" msgstr "Argumentdatentypen" -#: describe.c:106 describe.c:171 describe.c:258 describe.c:463 describe.c:647 -#: describe.c:745 describe.c:816 describe.c:1107 describe.c:1739 -#: describe.c:3015 describe.c:3250 describe.c:3375 describe.c:3449 -#: describe.c:3522 describe.c:3605 describe.c:3673 describe.c:3768 -#: describe.c:3834 describe.c:3902 describe.c:4038 describe.c:4078 -#: describe.c:4149 describe.c:4211 describe.c:4220 describe.c:4282 -#: describe.c:4499 describe.c:4579 describe.c:4714 describe.c:4784 +#: describe.c:110 describe.c:117 describe.c:183 describe.c:271 describe.c:510 +#: describe.c:724 describe.c:823 describe.c:894 describe.c:1187 describe.c:1960 +#: describe.c:3307 describe.c:3554 describe.c:3686 describe.c:3760 +#: describe.c:3833 describe.c:3916 describe.c:3999 describe.c:4103 +#: describe.c:4169 describe.c:4237 describe.c:4378 describe.c:4420 +#: describe.c:4493 describe.c:4555 describe.c:4564 describe.c:4626 +#: describe.c:4848 describe.c:4928 describe.c:5063 describe.c:5133 #: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "Beschreibung" -#: describe.c:124 +#: describe.c:135 msgid "List of aggregate functions" msgstr "Liste der Aggregatfunktionen" -#: describe.c:148 +#: describe.c:160 #, c-format msgid "The server (version %s) does not support access methods.\n" msgstr "Der Server (Version %s) unterstützt keine Zugriffsmethoden.\n" -#: describe.c:162 +#: describe.c:174 msgid "Index" msgstr "Index" -#: describe.c:163 describe.c:361 describe.c:406 describe.c:423 describe.c:881 -#: describe.c:1043 describe.c:1699 describe.c:3225 describe.c:3423 -#: describe.c:4576 -msgid "Type" -msgstr "Typ" - -#: describe.c:170 describe.c:4478 +#: describe.c:182 describe.c:4827 msgid "Handler" msgstr "Handler" -#: describe.c:189 +#: describe.c:201 msgid "List of access methods" msgstr "Liste der Zugriffsmethoden" -#: describe.c:214 +#: describe.c:227 #, c-format msgid "The server (version %s) does not support tablespaces.\n" msgstr "Der Server (Version %s) unterstützt keine Tablespaces.\n" -#: describe.c:228 describe.c:236 describe.c:451 describe.c:637 describe.c:792 -#: describe.c:1033 describe.c:3226 describe.c:3348 describe.c:3594 -#: describe.c:3826 describe.c:4474 describe.c:4558 describe.c:4949 -#: describe.c:5137 large_obj.c:288 +#: describe.c:241 describe.c:249 describe.c:498 describe.c:714 describe.c:870 +#: describe.c:1111 describe.c:3530 describe.c:3659 describe.c:3905 +#: describe.c:4161 describe.c:4823 describe.c:4907 describe.c:5303 +#: describe.c:5429 describe.c:5528 large_obj.c:288 msgid "Owner" msgstr "Eigentümer" -#: describe.c:229 describe.c:237 +#: describe.c:242 describe.c:250 msgid "Location" msgstr "Pfad" -#: describe.c:248 describe.c:2830 +#: describe.c:261 describe.c:3126 msgid "Options" msgstr "Optionen" -#: describe.c:253 describe.c:610 describe.c:808 describe.c:3242 -#: describe.c:3246 +#: describe.c:266 describe.c:687 describe.c:886 describe.c:3546 describe.c:3550 msgid "Size" msgstr "Größe" -#: describe.c:275 +#: describe.c:288 msgid "List of tablespaces" msgstr "Liste der Tablespaces" -#: describe.c:315 +#: describe.c:330 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df akzeptiert nur [antwS+] als Optionen\n" +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df akzeptiert nur [anptwS+] als Optionen\n" -#: describe.c:323 +#: describe.c:338 describe.c:349 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df akzeptiert die Option »w« nicht mit Serverversion %s\n" +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "\\df akzeptiert die Option »%c« nicht mit Serverversion %s\n" #. translator: "agg" is short for "aggregate" -#: describe.c:357 describe.c:403 describe.c:420 +#: describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "agg" msgstr "Agg" -#: describe.c:358 +#: describe.c:387 describe.c:405 msgid "window" msgstr "Fenster" -#: describe.c:359 describe.c:404 describe.c:421 describe.c:1241 +#: describe.c:388 +msgid "proc" +msgstr "Proz" + +#: describe.c:389 describe.c:407 describe.c:452 describe.c:469 +msgid "func" +msgstr "Funk" + +#: describe.c:406 describe.c:451 describe.c:468 describe.c:1321 msgid "trigger" msgstr "Trigger" -#: describe.c:360 describe.c:405 describe.c:422 -msgid "normal" -msgstr "normal" - -#: describe.c:433 +#: describe.c:480 msgid "immutable" msgstr "unveränderlich" -#: describe.c:434 +#: describe.c:481 msgid "stable" msgstr "stabil" -#: describe.c:435 +#: describe.c:482 msgid "volatile" msgstr "volatil" -#: describe.c:436 +#: describe.c:483 msgid "Volatility" msgstr "Volatilität" -#: describe.c:444 +#: describe.c:491 msgid "restricted" msgstr "beschränkt" -#: describe.c:445 +#: describe.c:492 msgid "safe" msgstr "sicher" -#: describe.c:446 +#: describe.c:493 msgid "unsafe" msgstr "unsicher" -#: describe.c:447 +#: describe.c:494 msgid "Parallel" msgstr "Parallel" -#: describe.c:452 +#: describe.c:499 msgid "definer" msgstr "definer" -#: describe.c:453 +#: describe.c:500 msgid "invoker" msgstr "invoker" -#: describe.c:454 +#: describe.c:501 msgid "Security" msgstr "Sicherheit" -#: describe.c:461 +#: describe.c:508 msgid "Language" msgstr "Sprache" -#: describe.c:462 +#: describe.c:509 msgid "Source code" msgstr "Quelltext" -#: describe.c:561 +#: describe.c:638 msgid "List of functions" msgstr "Liste der Funktionen" -#: describe.c:609 +#: describe.c:686 msgid "Internal name" msgstr "Interner Name" -#: describe.c:631 +#: describe.c:708 msgid "Elements" msgstr "Elemente" -#: describe.c:688 +#: describe.c:765 msgid "List of data types" msgstr "Liste der Datentypen" -#: describe.c:731 +#: describe.c:809 msgid "Left arg type" msgstr "Linker Typ" -#: describe.c:732 +#: describe.c:810 msgid "Right arg type" msgstr "Rechter Typ" -#: describe.c:733 +#: describe.c:811 msgid "Result type" msgstr "Ergebnistyp" -#: describe.c:738 describe.c:3664 describe.c:4037 +#: describe.c:816 describe.c:3911 describe.c:3976 describe.c:3982 +#: describe.c:4377 msgid "Function" msgstr "Funktion" -#: describe.c:763 +#: describe.c:841 msgid "List of operators" msgstr "Liste der Operatoren" -#: describe.c:793 +#: describe.c:871 msgid "Encoding" msgstr "Kodierung" -#: describe.c:798 describe.c:3762 +#: describe.c:876 describe.c:4092 msgid "Collate" msgstr "Sortierfolge" -#: describe.c:799 describe.c:3763 +#: describe.c:877 describe.c:4093 msgid "Ctype" msgstr "Zeichentyp" -#: describe.c:812 +#: describe.c:890 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:834 +#: describe.c:912 msgid "List of databases" msgstr "Liste der Datenbanken" -#: describe.c:875 describe.c:880 describe.c:1036 describe.c:3217 -#: describe.c:3224 +#: describe.c:953 describe.c:958 describe.c:1114 describe.c:3520 +#: describe.c:3527 msgid "table" msgstr "Tabelle" -#: describe.c:876 describe.c:3218 +#: describe.c:954 describe.c:3521 msgid "view" msgstr "Sicht" -#: describe.c:877 describe.c:3219 +#: describe.c:955 describe.c:3522 msgid "materialized view" msgstr "materialisierte Sicht" -#: describe.c:878 describe.c:1038 describe.c:3221 +#: describe.c:956 describe.c:1116 describe.c:3524 msgid "sequence" msgstr "Sequenz" -#: describe.c:879 describe.c:3223 +#: describe.c:957 describe.c:3526 msgid "foreign table" msgstr "Fremdtabelle" -#: describe.c:892 +#: describe.c:970 msgid "Column privileges" msgstr "Spaltenprivilegien" -#: describe.c:923 describe.c:957 +#: describe.c:1001 describe.c:1035 msgid "Policies" msgstr "Policys" -#: describe.c:989 describe.c:5191 describe.c:5195 +#: describe.c:1067 describe.c:5584 describe.c:5588 msgid "Access privileges" msgstr "Zugriffsprivilegien" -#: describe.c:1020 +#: describe.c:1098 #, c-format msgid "The server (version %s) does not support altering default privileges.\n" msgstr "Der Server (Version %s) unterstützt kein Ändern der Vorgabeprivilegien.\n" -#: describe.c:1040 +#: describe.c:1118 msgid "function" msgstr "Funktion" -#: describe.c:1042 +#: describe.c:1120 msgid "type" msgstr "Typ" -#: describe.c:1066 +#: describe.c:1122 +msgid "schema" +msgstr "Schema" + +#: describe.c:1146 msgid "Default access privileges" msgstr "Vorgegebene Zugriffsprivilegien" -#: describe.c:1106 +#: describe.c:1186 msgid "Object" msgstr "Objekt" -#: describe.c:1120 +#: describe.c:1200 msgid "table constraint" msgstr "Tabellen-Constraint" -#: describe.c:1142 +#: describe.c:1222 msgid "domain constraint" msgstr "Domänen-Constraint" -#: describe.c:1170 +#: describe.c:1250 msgid "operator class" msgstr "Operatorklasse" -#: describe.c:1199 +#: describe.c:1279 msgid "operator family" msgstr "Operatorfamilie" -#: describe.c:1221 +#: describe.c:1301 msgid "rule" msgstr "Rule" -#: describe.c:1263 +#: describe.c:1343 msgid "Object descriptions" msgstr "Objektbeschreibungen" -#: describe.c:1317 +#: describe.c:1399 describe.c:3618 #, c-format msgid "Did not find any relation named \"%s\".\n" -msgstr "Keine Relationen namens »%s« gefunden\n" +msgstr "Keine Relation namens »%s« gefunden\n" + +#: describe.c:1402 describe.c:3621 +#, c-format +msgid "Did not find any relations.\n" +msgstr "Keine Relationen gefunden\n" -#: describe.c:1526 +#: describe.c:1619 #, c-format msgid "Did not find any relation with OID %s.\n" -msgstr "Keine Relation mit OID %s gefunden.\n" +msgstr "Keine Relation mit OID %s gefunden\n" + +#: describe.c:1665 describe.c:1689 +msgid "Start" +msgstr "Start" + +#: describe.c:1666 describe.c:1690 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1667 describe.c:1691 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1668 describe.c:1692 +msgid "Increment" +msgstr "Inkrement" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3827 +#: describe.c:3993 +msgid "yes" +msgstr "ja" + +#: describe.c:1670 describe.c:1694 describe.c:1819 describe.c:3827 +#: describe.c:3990 +msgid "no" +msgstr "nein" + +#: describe.c:1671 describe.c:1695 +msgid "Cycles?" +msgstr "Zyklisch?" -#: describe.c:1635 describe.c:1684 +#: describe.c:1672 describe.c:1696 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1739 +#, c-format +msgid "Owned by: %s" +msgstr "Eigentümer: %s" + +#: describe.c:1743 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sequenz für Identitätsspalte: %s" + +#: describe.c:1750 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sequenz »%s.%s«" + +#: describe.c:1880 describe.c:1926 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Ungeloggte Tabelle »%s.%s«" -#: describe.c:1638 describe.c:1687 +#: describe.c:1883 describe.c:1929 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabelle »%s.%s«" -#: describe.c:1642 +#: describe.c:1887 #, c-format msgid "View \"%s.%s\"" msgstr "Sicht »%s.%s«" -#: describe.c:1647 +#: describe.c:1892 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Ungeloggte materialisierte Sicht »%s.%s«" -#: describe.c:1650 +#: describe.c:1895 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Materialisierte Sicht »%s.%s«" -#: describe.c:1654 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Sequenz »%s.%s«" - -#: describe.c:1659 +#: describe.c:1901 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Ungeloggter Index »%s.%s«" -#: describe.c:1662 +#: describe.c:1904 #, c-format msgid "Index \"%s.%s\"" msgstr "Index »%s.%s«" -#: describe.c:1667 +#: describe.c:1909 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Spezielle Relation »%s.%s«" -#: describe.c:1671 +#: describe.c:1913 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST-Tabelle »%s.%s«" -#: describe.c:1675 +#: describe.c:1917 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Zusammengesetzter Typ »%s.%s«" -#: describe.c:1679 +#: describe.c:1921 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Fremdtabelle »%s.%s«" -#: describe.c:1698 -msgid "Column" -msgstr "Spalte" - -#: describe.c:1709 describe.c:3429 +#: describe.c:1945 describe.c:3740 msgid "Collation" msgstr "Sortierfolge" -#: describe.c:1710 describe.c:3436 +#: describe.c:1946 describe.c:3747 msgid "Nullable" msgstr "NULL erlaubt?" -#: describe.c:1711 describe.c:3437 +#: describe.c:1947 describe.c:3748 msgid "Default" msgstr "Vorgabewert" -#: describe.c:1716 -msgid "Value" -msgstr "Wert" +#: describe.c:1950 +msgid "Key?" +msgstr "Schlüssel?" -#: describe.c:1719 +#: describe.c:1952 msgid "Definition" msgstr "Definition" -#: describe.c:1722 describe.c:4494 describe.c:4578 describe.c:4649 -#: describe.c:4713 -msgid "FDW Options" +#: describe.c:1954 describe.c:4843 describe.c:4927 describe.c:4998 +#: describe.c:5062 +msgid "FDW options" msgstr "FDW-Optionen" -#: describe.c:1726 +#: describe.c:1956 msgid "Storage" msgstr "Speicherung" -#: describe.c:1731 +#: describe.c:1958 msgid "Stats target" msgstr "Statistikziel" -#: describe.c:1857 +#: describe.c:2072 #, c-format msgid "Partition of: %s %s" msgstr "Partition von: %s %s" -#: describe.c:1878 +#: describe.c:2080 +msgid "No partition constraint" +msgstr "Kein Partitions-Constraint" + +#: describe.c:2082 +#, c-format +msgid "Partition constraint: %s" +msgstr "Partitions-Constraint: %s" + +#: describe.c:2105 #, c-format msgid "Partition key: %s" msgstr "Partitionsschlüssel: %s" -#: describe.c:1946 +#: describe.c:2174 msgid "primary key, " msgstr "Primärschlüssel, " -#: describe.c:1948 +#: describe.c:2176 msgid "unique, " msgstr "eindeutig, " -#: describe.c:1954 +#: describe.c:2182 #, c-format msgid "for table \"%s.%s\"" msgstr "für Tabelle »%s.%s«" -#: describe.c:1958 +#: describe.c:2186 #, c-format msgid ", predicate (%s)" msgstr ", Prädikat (%s)" -#: describe.c:1961 +#: describe.c:2189 msgid ", clustered" msgstr ", geclustert" -#: describe.c:1964 +#: describe.c:2192 msgid ", invalid" msgstr ", ungültig" -#: describe.c:1967 +#: describe.c:2195 msgid ", deferrable" msgstr ", DEFERRABLE" -#: describe.c:1970 +#: describe.c:2198 msgid ", initially deferred" msgstr ", INITIALLY DEFERRED" -#: describe.c:1973 +#: describe.c:2201 msgid ", replica identity" msgstr ", Replika-Identität" -#: describe.c:2008 -#, c-format -msgid "Owned by: %s" -msgstr "Eigentümer: %s" - -#: describe.c:2070 +#: describe.c:2260 msgid "Indexes:" msgstr "Indexe:" -#: describe.c:2154 +#: describe.c:2344 msgid "Check constraints:" msgstr "Check-Constraints:" -#: describe.c:2185 +#: describe.c:2380 msgid "Foreign-key constraints:" msgstr "Fremdschlüssel-Constraints:" -#: describe.c:2216 +#: describe.c:2411 msgid "Referenced by:" msgstr "Fremdschlüsselverweise von:" -#: describe.c:2276 +#: describe.c:2461 msgid "Policies:" msgstr "Policys:" -#: describe.c:2279 +#: describe.c:2464 msgid "Policies (forced row security enabled):" msgstr "Policys (Sicherheit auf Zeilenebene erzwungen):" -#: describe.c:2282 +#: describe.c:2467 msgid "Policies (row security enabled): (none)" msgstr "Policys (Sicherheit auf Zeilenebene eingeschaltet): (keine)" -#: describe.c:2285 +#: describe.c:2470 msgid "Policies (forced row security enabled): (none)" msgstr "Policys (Sicherheit auf Zeilenebene erzwungen): (keine)" -#: describe.c:2288 +#: describe.c:2473 msgid "Policies (row security disabled):" msgstr "Policys (Sicherheit auf Zeilenebene ausgeschaltet):" -#: describe.c:2391 describe.c:2473 +#: describe.c:2535 +msgid "Statistics objects:" +msgstr "Statistikobjekte:" + +#: describe.c:2638 describe.c:2742 msgid "Rules:" msgstr "Regeln:" -#: describe.c:2394 +#: describe.c:2641 msgid "Disabled rules:" msgstr "Abgeschaltete Regeln:" -#: describe.c:2397 +#: describe.c:2644 msgid "Rules firing always:" msgstr "Regeln, die immer aktiv werden:" -#: describe.c:2400 +#: describe.c:2647 msgid "Rules firing on replica only:" msgstr "Regeln, die nur im Replikat aktiv werden:" -#: describe.c:2437 +#: describe.c:2687 msgid "Publications:" msgstr "Publikationen:" -#: describe.c:2456 +#: describe.c:2725 msgid "View definition:" msgstr "Sichtdefinition:" -#: describe.c:2591 +#: describe.c:2864 msgid "Triggers:" msgstr "Trigger:" -#: describe.c:2595 +#: describe.c:2868 msgid "Disabled user triggers:" msgstr "Abgeschaltete Benutzer-Trigger:" -#: describe.c:2597 +#: describe.c:2870 msgid "Disabled triggers:" msgstr "Abgeschaltete Trigger:" -#: describe.c:2600 +#: describe.c:2873 msgid "Disabled internal triggers:" msgstr "Abgeschaltete interne Trigger:" -#: describe.c:2603 +#: describe.c:2876 msgid "Triggers firing always:" msgstr "Trigger, die immer aktiv werden:" -#: describe.c:2606 +#: describe.c:2879 msgid "Triggers firing on replica only:" msgstr "Trigger, die nur im Replikat aktiv werden:" -#: describe.c:2692 +#: describe.c:2938 +#, c-format +msgid "Server: %s" +msgstr "Server: %s" + +#: describe.c:2946 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW-Optionen: (%s)" + +#: describe.c:2965 msgid "Inherits" msgstr "Erbt von" -#: describe.c:2746 +#: describe.c:3024 +#, c-format +msgid "Number of partitions: %d" +msgstr "Anzahl Partitionen: %d" + +#: describe.c:3033 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Anzahl Kindtabellen: %d (Mit \\d+ alle anzeigen.)" -#: describe.c:2748 +#: describe.c:3035 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Anzahl Partitionen: %d (Mit \\d+ alle anzeigen.)" -#: describe.c:2756 +#: describe.c:3043 msgid "Child tables" msgstr "Kindtabellen" -#: describe.c:2756 +#: describe.c:3043 msgid "Partitions" msgstr "Partitionen" -#: describe.c:2790 +#: describe.c:3086 #, c-format msgid "Typed table of type: %s" msgstr "Getypte Tabelle vom Typ: %s" -#: describe.c:2806 +#: describe.c:3102 msgid "Replica Identity" msgstr "Replika-Identität" -#: describe.c:2819 +#: describe.c:3115 msgid "Has OIDs: yes" msgstr "Hat OIDs: ja" -#: describe.c:2903 +#: describe.c:3195 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace: »%s«" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:2915 +#: describe.c:3207 #, c-format msgid ", tablespace \"%s\"" msgstr ", Tablespace »%s«" -#: describe.c:3008 +#: describe.c:3300 msgid "List of roles" msgstr "Liste der Rollen" -#: describe.c:3010 +#: describe.c:3302 msgid "Role name" msgstr "Rollenname" -#: describe.c:3011 +#: describe.c:3303 msgid "Attributes" msgstr "Attribute" -#: describe.c:3012 +#: describe.c:3304 msgid "Member of" msgstr "Mitglied von" -#: describe.c:3023 +#: describe.c:3315 msgid "Superuser" msgstr "Superuser" -#: describe.c:3026 +#: describe.c:3318 msgid "No inheritance" msgstr "keine Vererbung" -#: describe.c:3029 +#: describe.c:3321 msgid "Create role" msgstr "Rolle erzeugen" -#: describe.c:3032 +#: describe.c:3324 msgid "Create DB" msgstr "DB erzeugen" -#: describe.c:3035 +#: describe.c:3327 msgid "Cannot login" msgstr "kann nicht einloggen" -#: describe.c:3039 +#: describe.c:3331 msgid "Replication" msgstr "Replikation" -#: describe.c:3043 +#: describe.c:3335 msgid "Bypass RLS" msgstr "Bypass RLS" -#: describe.c:3052 +#: describe.c:3344 msgid "No connections" msgstr "keine Verbindungen" -#: describe.c:3054 +#: describe.c:3346 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d Verbindung" msgstr[1] "%d Verbindungen" -#: describe.c:3064 +#: describe.c:3356 msgid "Password valid until " msgstr "Passwort gültig bis " -#: describe.c:3120 +#: describe.c:3406 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "Der Server (Version %s) unterstützt keine Rolleneinstellungen pro Datenbank.\n" + +#: describe.c:3419 msgid "Role" msgstr "Rolle" -#: describe.c:3121 +#: describe.c:3420 msgid "Database" msgstr "Datenbank" -#: describe.c:3122 +#: describe.c:3421 msgid "Settings" msgstr "Einstellung" -#: describe.c:3132 +#: describe.c:3442 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "Keine Unterstützung für Rolleneinstellungen pro Datenbank in dieser Serverversion.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "Keine Einstellungen für Rolle »%s« und Datenbank »%s« gefunden\n" -#: describe.c:3143 +#: describe.c:3445 #, c-format -msgid "No matching settings found.\n" -msgstr "Keine passenden Einstellungen gefunden.\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "Keine Einstellungen für Rolle »%s« gefunden\n" -#: describe.c:3145 +#: describe.c:3448 #, c-format -msgid "No settings found.\n" -msgstr "Keine Einstellungen gefunden.\n" +msgid "Did not find any settings.\n" +msgstr "Keine Einstellungen gefunden\n" -#: describe.c:3150 +#: describe.c:3453 msgid "List of settings" msgstr "Liste der Einstellungen" -#: describe.c:3220 +#: describe.c:3523 describe.c:3528 msgid "index" msgstr "Index" -#: describe.c:3222 +#: describe.c:3525 msgid "special" msgstr "speziell" -#: describe.c:3231 describe.c:4701 +#: describe.c:3535 describe.c:5050 msgid "Table" msgstr "Tabelle" -#: describe.c:3308 -#, c-format -msgid "No matching relations found.\n" -msgstr "Keine passenden Relationen gefunden.\n" - -#: describe.c:3310 -#, c-format -msgid "No relations found.\n" -msgstr "Keine Relationen gefunden.\n" - -#: describe.c:3315 +#: describe.c:3626 msgid "List of relations" msgstr "Liste der Relationen" -#: describe.c:3352 +#: describe.c:3663 msgid "Trusted" msgstr "Vertraut" -#: describe.c:3360 -msgid "Internal Language" +#: describe.c:3671 +msgid "Internal language" msgstr "Interne Sprache" -#: describe.c:3361 -msgid "Call Handler" +#: describe.c:3672 +msgid "Call handler" msgstr "Call-Handler" -#: describe.c:3362 describe.c:4481 +#: describe.c:3673 describe.c:4830 msgid "Validator" msgstr "Validator" -#: describe.c:3365 -msgid "Inline Handler" +#: describe.c:3676 +msgid "Inline handler" msgstr "Inline-Handler" -#: describe.c:3393 +#: describe.c:3704 msgid "List of languages" msgstr "Liste der Sprachen" -#: describe.c:3438 +#: describe.c:3749 msgid "Check" msgstr "Check" -#: describe.c:3480 +#: describe.c:3791 msgid "List of domains" msgstr "Liste der Domänen" -#: describe.c:3514 +#: describe.c:3825 msgid "Source" msgstr "Quelle" -#: describe.c:3515 +#: describe.c:3826 msgid "Destination" msgstr "Ziel" -#: describe.c:3516 describe.c:3665 -msgid "no" -msgstr "nein" - -#: describe.c:3516 describe.c:3667 -msgid "yes" -msgstr "ja" - -#: describe.c:3517 +#: describe.c:3828 msgid "Default?" msgstr "Standard?" -#: describe.c:3554 +#: describe.c:3865 msgid "List of conversions" msgstr "Liste der Konversionen" -#: describe.c:3593 +#: describe.c:3904 msgid "Event" msgstr "Ereignis" -#: describe.c:3595 +#: describe.c:3906 msgid "enabled" msgstr "eingeschaltet" -#: describe.c:3596 +#: describe.c:3907 msgid "replica" msgstr "Replika" -#: describe.c:3597 +#: describe.c:3908 msgid "always" msgstr "immer" -#: describe.c:3598 +#: describe.c:3909 msgid "disabled" msgstr "ausgeschaltet" -#: describe.c:3599 describe.c:5138 +#: describe.c:3910 describe.c:5529 msgid "Enabled" msgstr "Eingeschaltet" -#: describe.c:3600 -msgid "Procedure" -msgstr "Prozedur" - -#: describe.c:3601 +#: describe.c:3912 msgid "Tags" msgstr "Tags" -#: describe.c:3620 +#: describe.c:3931 msgid "List of event triggers" msgstr "Liste der Ereignistrigger" -#: describe.c:3662 +#: describe.c:3960 msgid "Source type" msgstr "Quelltyp" -#: describe.c:3663 +#: describe.c:3961 msgid "Target type" msgstr "Zieltyp" -#: describe.c:3666 +#: describe.c:3992 msgid "in assignment" msgstr "in Zuweisung" -#: describe.c:3668 +#: describe.c:3994 msgid "Implicit?" msgstr "Implizit?" -#: describe.c:3719 +#: describe.c:4049 msgid "List of casts" msgstr "Liste der Typumwandlungen" -#: describe.c:3747 +#: describe.c:4077 #, c-format msgid "The server (version %s) does not support collations.\n" msgstr "Der Server (Version %s) unterstützt keine Sortierfolgen.\n" -#: describe.c:3798 +#: describe.c:4098 +msgid "Provider" +msgstr "Provider" + +#: describe.c:4133 msgid "List of collations" msgstr "Liste der Sortierfolgen" -#: describe.c:3857 +#: describe.c:4192 msgid "List of schemas" msgstr "Liste der Schemas" -#: describe.c:3882 describe.c:4120 describe.c:4191 describe.c:4262 +#: describe.c:4217 describe.c:4464 describe.c:4535 describe.c:4606 #, c-format msgid "The server (version %s) does not support full text search.\n" msgstr "Der Server (Version %s) unterstützt keine Volltextsuche.\n" -#: describe.c:3917 +#: describe.c:4252 msgid "List of text search parsers" msgstr "Liste der Textsucheparser" -#: describe.c:3960 +#: describe.c:4297 #, c-format msgid "Did not find any text search parser named \"%s\".\n" msgstr "Kein Textsucheparser namens »%s« gefunden\n" -#: describe.c:4035 +#: describe.c:4300 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "Keine Textsucheparser gefunden\n" + +#: describe.c:4375 msgid "Start parse" msgstr "Parsen starten" -#: describe.c:4036 +#: describe.c:4376 msgid "Method" msgstr "Methode" -#: describe.c:4040 +#: describe.c:4380 msgid "Get next token" msgstr "Nächstes Token lesen" -#: describe.c:4042 +#: describe.c:4382 msgid "End parse" msgstr "Parsen beenden" -#: describe.c:4044 +#: describe.c:4384 msgid "Get headline" msgstr "Überschrift ermitteln" -#: describe.c:4046 +#: describe.c:4386 msgid "Get token types" msgstr "Tokentypen ermitteln" -#: describe.c:4056 +#: describe.c:4397 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Textsucheparser »%s.%s«" -#: describe.c:4058 +#: describe.c:4400 #, c-format msgid "Text search parser \"%s\"" msgstr "Textsucheparser »%s«" -#: describe.c:4077 +#: describe.c:4419 msgid "Token name" msgstr "Tokenname" -#: describe.c:4088 +#: describe.c:4430 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Tokentypen für Parser »%s.%s«" -#: describe.c:4090 +#: describe.c:4433 #, c-format msgid "Token types for parser \"%s\"" msgstr "Tokentypen für Parser »%s«" -#: describe.c:4143 +#: describe.c:4487 msgid "Template" msgstr "Vorlage" -#: describe.c:4144 +#: describe.c:4488 msgid "Init options" msgstr "Initialisierungsoptionen" -#: describe.c:4166 +#: describe.c:4510 msgid "List of text search dictionaries" msgstr "Liste der Textsuchewörterbücher" -#: describe.c:4209 +#: describe.c:4553 msgid "Init" msgstr "Init" -#: describe.c:4210 +#: describe.c:4554 msgid "Lexize" msgstr "Lexize" -#: describe.c:4237 +#: describe.c:4581 msgid "List of text search templates" msgstr "Liste der Textsuchevorlagen" -#: describe.c:4297 +#: describe.c:4641 msgid "List of text search configurations" msgstr "Liste der Textsuchekonfigurationen" -#: describe.c:4341 +#: describe.c:4687 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" msgstr "Keine Textsuchekonfiguration namens »%s« gefunden\n" -#: describe.c:4407 +#: describe.c:4690 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "Keine Textsuchekonfigurationen gefunden\n" + +#: describe.c:4756 msgid "Token" msgstr "Token" -#: describe.c:4408 +#: describe.c:4757 msgid "Dictionaries" msgstr "Wörterbücher" -#: describe.c:4419 +#: describe.c:4768 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Textsuchekonfiguration »%s.%s«" -#: describe.c:4422 +#: describe.c:4771 #, c-format msgid "Text search configuration \"%s\"" msgstr "Textsuchekonfiguration »%s«" -#: describe.c:4426 +#: describe.c:4775 #, c-format msgid "" "\n" @@ -1833,7 +1940,7 @@ msgstr "" "\n" "Parser: »%s.%s«" -#: describe.c:4429 +#: describe.c:4778 #, c-format msgid "" "\n" @@ -1842,130 +1949,152 @@ msgstr "" "\n" "Parser: »%s«" -#: describe.c:4463 +#: describe.c:4812 #, c-format msgid "The server (version %s) does not support foreign-data wrappers.\n" msgstr "Der Server (Version %s) unterstützt keine Fremddaten-Wrapper.\n" -#: describe.c:4521 +#: describe.c:4870 msgid "List of foreign-data wrappers" msgstr "Liste der Fremddaten-Wrapper" -#: describe.c:4546 +#: describe.c:4895 #, c-format msgid "The server (version %s) does not support foreign servers.\n" msgstr "Der Server (Version %s) unterstützt keine Fremdserver.\n" -#: describe.c:4559 +#: describe.c:4908 msgid "Foreign-data wrapper" msgstr "Fremddaten-Wrapper" -#: describe.c:4577 describe.c:4782 +#: describe.c:4926 describe.c:5131 msgid "Version" msgstr "Version" -#: describe.c:4603 +#: describe.c:4952 msgid "List of foreign servers" msgstr "Liste der Fremdserver" -#: describe.c:4628 +#: describe.c:4977 #, c-format msgid "The server (version %s) does not support user mappings.\n" msgstr "Der Server (Version %s) unterstützt keine Benutzerabbildungen.\n" -#: describe.c:4638 describe.c:4702 +#: describe.c:4987 describe.c:5051 msgid "Server" msgstr "Server" -#: describe.c:4639 +#: describe.c:4988 msgid "User name" msgstr "Benutzername" -#: describe.c:4664 +#: describe.c:5013 msgid "List of user mappings" msgstr "Liste der Benutzerabbildungen" -#: describe.c:4689 +#: describe.c:5038 #, c-format msgid "The server (version %s) does not support foreign tables.\n" msgstr "Der Server (Version %s) unterstützt keine Fremdtabellen.\n" -#: describe.c:4742 +#: describe.c:5091 msgid "List of foreign tables" msgstr "Liste der Fremdtabellen" -#: describe.c:4767 describe.c:4824 +#: describe.c:5116 describe.c:5173 #, c-format msgid "The server (version %s) does not support extensions.\n" msgstr "Der Server (Version %s) unterstützt keine Erweiterungen.\n" -#: describe.c:4799 +#: describe.c:5148 msgid "List of installed extensions" msgstr "Liste der installierten Erweiterungen" -#: describe.c:4852 +#: describe.c:5201 #, c-format msgid "Did not find any extension named \"%s\".\n" -msgstr "Keine Erweiterungen namens »%s« gefunden\n" +msgstr "Keine Erweiterung namens »%s« gefunden\n" -#: describe.c:4855 +#: describe.c:5204 #, c-format msgid "Did not find any extensions.\n" msgstr "Keine Erweiterungen gefunden\n" -#: describe.c:4899 -msgid "Object Description" +#: describe.c:5248 +msgid "Object description" msgstr "Objektbeschreibung" -#: describe.c:4908 +#: describe.c:5258 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objekte in Erweiterung »%s«" -#: describe.c:4934 describe.c:4996 +#: describe.c:5287 describe.c:5358 #, c-format msgid "The server (version %s) does not support publications.\n" msgstr "Der Server (Version %s) unterstützt keine Publikationen.\n" -#: describe.c:4950 describe.c:5041 +#: describe.c:5304 describe.c:5430 +msgid "All tables" +msgstr "Alle Tabellen" + +#: describe.c:5305 describe.c:5431 msgid "Inserts" msgstr "Inserts" -#: describe.c:4951 describe.c:5042 +#: describe.c:5306 describe.c:5432 msgid "Updates" msgstr "Updates" -#: describe.c:4952 describe.c:5043 +#: describe.c:5307 describe.c:5433 msgid "Deletes" msgstr "Deletes" -#: describe.c:4969 +#: describe.c:5311 describe.c:5435 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:5328 msgid "List of publications" msgstr "Liste der Publikationen" -#: describe.c:5038 +#: describe.c:5396 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "Keine Publikation namens »%s« gefunden\n" + +#: describe.c:5399 +#, c-format +msgid "Did not find any publications.\n" +msgstr "Keine Publikationen gefunden\n" + +#: describe.c:5426 #, c-format msgid "Publication %s" msgstr "Publikation %s" -#: describe.c:5083 +#: describe.c:5470 msgid "Tables:" msgstr "Tabellen:" -#: describe.c:5123 +#: describe.c:5514 #, c-format msgid "The server (version %s) does not support subscriptions.\n" msgstr "Der Server (Version %s) unterstützt keine Subskriptionen.\n" -#: describe.c:5139 +#: describe.c:5530 msgid "Publication" msgstr "Publikation" -#: describe.c:5145 +#: describe.c:5537 +msgid "Synchronous commit" +msgstr "Synchroner Commit" + +#: describe.c:5538 msgid "Conninfo" msgstr "Verbindungsinfo" -#: describe.c:5167 +#: describe.c:5560 msgid "List of subscriptions" msgstr "Liste der Subskriptionen" @@ -1983,7 +2112,7 @@ msgstr "" "psql ist das interaktive PostgreSQL-Terminal.\n" "\n" -#: help.c:74 help.c:335 help.c:369 help.c:396 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" @@ -2286,444 +2415,478 @@ msgstr " \\copyright PostgreSQL-Urheberrechtsinformationen zeigen\n #: help.c:174 #, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [SPALTEN] Anfrage ausführen und Ergebnisse als Kreuztabelle\n" +" anzeigen\n" + +#: help.c:175 +#, c-format msgid " \\errverbose show most recent error message at maximum verbosity\n" msgstr " \\errverbose letzte Fehlermeldung mit vollen Details anzeigen\n" -#: help.c:175 +#: help.c:176 #, c-format msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" msgstr "" " \\g [DATEI] oder ; SQL-Anweisung ausführen (und Ergebnis in Datei oder\n" " |Pipe schreiben)\n" -#: help.c:176 +#: help.c:177 #, c-format -msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" -msgstr " \\gx [DATEI] wie \\g, aber mit erweitertem Ausgabemodus\n" +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc Ergebnis der Anfrage beschreiben ohne sie auszuführen\n" -#: help.c:177 +#: help.c:178 #, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr "" " \\gexec Anfrage ausführen, dann jeden Ergebniswert als\n" " Anweisung ausführen\n" -#: help.c:178 +#: help.c:179 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr "" " \\gset [PREFIX] SQL-Anweisung ausführen und Ergebnis in psql-Variablen\n" " ablegen\n" -#: help.c:179 -#, c-format -msgid " \\q quit psql\n" -msgstr " \\q psql beenden\n" - #: help.c:180 #, c-format -msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" -msgstr "" -" \\crosstabview [SPALTEN] Anfrage ausführen und Ergebnisse als Kreuztabelle\n" -" anzeigen\n" +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [DATEI] wie \\g, aber mit erweitertem Ausgabemodus\n" #: help.c:181 #, c-format +msgid " \\q quit psql\n" +msgstr " \\q psql beenden\n" + +#: help.c:182 +#, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEK] Anfrage alle SEK Sekunden ausführen\n" -#: help.c:184 +#: help.c:185 #, c-format msgid "Help\n" msgstr "Hilfe\n" -#: help.c:186 +#: help.c:187 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] Hilfe über Backslash-Befehle anzeigen\n" -#: help.c:187 +#: help.c:188 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options Hilfe über psql-Kommandozeilenoptionen anzeigen\n" -#: help.c:188 +#: help.c:189 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables Hilfe über besondere Variablen anzeigen\n" -#: help.c:189 +#: help.c:190 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr " \\h [NAME] Syntaxhilfe über SQL-Anweisung, * für alle Anweisungen\n" -#: help.c:192 +#: help.c:193 #, c-format msgid "Query Buffer\n" msgstr "Anfragepuffer\n" -#: help.c:193 +#: help.c:194 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr " \\e [DATEI] [ZEILE] Anfragepuffer (oder Datei) mit externem Editor bearbeiten\n" -#: help.c:194 +#: help.c:195 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr " \\ef [FUNKNAME [ZEILE]] Funktionsdefinition mit externem Editor bearbeiten\n" -#: help.c:195 +#: help.c:196 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr " \\ev [SICHTNAME [ZEILE]] Sichtdefinition mit externem Editor bearbeiten\n" -#: help.c:196 +#: help.c:197 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p aktuellen Inhalt der Anfragepuffers zeigen\n" -#: help.c:197 +#: help.c:198 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r Anfragepuffer löschen\n" -#: help.c:199 +#: help.c:200 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [DATEI] Befehlsgeschichte ausgeben oder in Datei schreiben\n" -#: help.c:201 +#: help.c:202 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w DATEI Anfragepuffer in Datei schreiben\n" -#: help.c:204 +#: help.c:205 #, c-format msgid "Input/Output\n" msgstr "Eingabe/Ausgabe\n" -#: help.c:205 +#: help.c:206 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr " \\copy ... SQL COPY mit Datenstrom auf Client-Host ausführen\n" -#: help.c:206 +#: help.c:207 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [TEXT] Text auf Standardausgabe schreiben\n" -#: help.c:207 +#: help.c:208 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i DATEI Befehle aus Datei ausführen\n" -#: help.c:208 +#: help.c:209 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr " \\ir DATEI wie \\i, aber relativ zum Ort des aktuellen Skripts\n" -#: help.c:209 +#: help.c:210 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr " \\o [DATEI] alle Anfrageergebnisse in Datei oder |Pipe schreiben\n" -#: help.c:210 +#: help.c:211 #, c-format msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr "" " \\qecho [TEXT] Text auf Ausgabestrom für Anfrageergebnisse schreiben\n" " (siehe \\o)\n" -#: help.c:213 +#: help.c:214 +#, c-format +msgid "Conditional\n" +msgstr "Bedingte Anweisungen\n" + +#: help.c:215 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if AUSDRUCK Beginn einer bedingten Anweisung\n" + +#: help.c:216 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif AUSDRUCK Alternative in aktueller bedingter Anweisung\n" + +#: help.c:217 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else letzte Alternative in aktueller bedingter Anweisung\n" + +#: help.c:218 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif Ende einer bedingten Anweisung\n" + +#: help.c:221 #, c-format msgid "Informational\n" msgstr "Informationen\n" -#: help.c:214 +#: help.c:222 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (Optionen: S = Systemobjekte zeigen, + = zusätzliche Details zeigen)\n" -#: help.c:215 +#: help.c:223 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] Tabellen, Sichten und Sequenzen auflisten\n" -#: help.c:216 +#: help.c:224 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NAME Tabelle, Sicht, Sequenz oder Index beschreiben\n" -#: help.c:217 +#: help.c:225 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [MUSTER] Aggregatfunktionen auflisten\n" -#: help.c:218 +#: help.c:226 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [MUSTER] Zugriffsmethoden auflisten\n" -#: help.c:219 +#: help.c:227 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [MUSTER] Tablespaces auflisten\n" -#: help.c:220 +#: help.c:228 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [MUSTER] Konversionen auflisten\n" -#: help.c:221 +#: help.c:229 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [MUSTER] Typumwandlungen (Casts) auflisten\n" -#: help.c:222 +#: help.c:230 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr "" " \\dd[S] [MUSTER] Objektbeschreibungen zeigen, die nirgendwo anders\n" " erscheinen\n" -#: help.c:223 +#: help.c:231 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [MUSTER] Domänen auflisten\n" + +#: help.c:232 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [MUSTER] Vorgabeprivilegien auflisten\n" -#: help.c:224 +#: help.c:233 #, c-format -msgid " \\dD[S+] [PATTERN] list domains\n" -msgstr " \\dD[S+] [MUSTER] Domänen auflisten\n" +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [MUSTER] Fremdtabellen auflisten\n" -#: help.c:225 +#: help.c:234 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [MUSTER] Fremdtabellen auflisten\n" -#: help.c:226 +#: help.c:235 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [MUSTER] Fremdserver auflisten\n" -#: help.c:227 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [MUSTER] Benutzerabbildungen auflisten\n" -#: help.c:228 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [MUSTER] Fremddaten-Wrapper auflisten\n" -#: help.c:229 +#: help.c:238 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [MUSTR] Funktionen [nur Agg/normale/Trigger/Fenster] auflisten\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [MUSTR] Funktionen [nur Agg/normale/Proz/Trigger/Fenster] auflisten\n" -#: help.c:230 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [MUSTER] Textsuchekonfigurationen auflisten\n" -#: help.c:231 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [MUSTER] Textsuchewörterbücher auflisten\n" -#: help.c:232 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [MUSTER] Textsucheparser auflisten\n" -#: help.c:233 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [MUSTER] Textsuchevorlagen auflisten\n" -#: help.c:234 +#: help.c:243 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [MUSTER] Rollen auflisten\n" -#: help.c:235 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [MUSTER] Indexe auflisten\n" -#: help.c:236 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl Large Objects auflisten, wie \\lo_list\n" -#: help.c:237 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [MUSTER] prozedurale Sprachen auflisten\n" -#: help.c:238 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [MUSTER] materialisierte Sichten auflisten\n" -#: help.c:239 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [MUSTER] Schemas auflisten\n" -#: help.c:240 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [MUSTER] Operatoren auflisten\n" -#: help.c:241 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [MUSTER] Sortierfolgen auflisten\n" -#: help.c:242 +#: help.c:251 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr "" " \\dp [MUSTER] Zugriffsprivilegien für Tabellen, Sichten und\n" " Sequenzen auflisten\n" -#: help.c:243 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [MUSTER1 [MUSTER2]] datenbankspezifische Rolleneinstellungen auflisten\n" -#: help.c:244 +#: help.c:253 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[+] [MUSTER] Replikationspublikationen auflisten\n" -#: help.c:245 +#: help.c:254 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [MUSTER] Replikationssubskriptionen auflisten\n" -#: help.c:246 +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [MUSTER] Sequenzen auflisten\n" -#: help.c:247 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [MUSTER] Tabellen auflisten\n" -#: help.c:248 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [MUSTER] Datentypen auflisten\n" -#: help.c:249 +#: help.c:258 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [MUSTER] Rollen auflisten\n" -#: help.c:250 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [MUSTER] Sichten auflisten\n" -#: help.c:251 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [MUSTER] Fremdtabellen auflisten\n" - -#: help.c:252 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [MUSTER] Erweiterungen auflisten\n" -#: help.c:253 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [MUSTER] Ereignistrigger auflisten\n" -#: help.c:254 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [MUSTER] Datenbanken auflisten\n" -#: help.c:255 +#: help.c:263 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNKNAME Funktionsdefinition zeigen\n" -#: help.c:256 +#: help.c:264 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] SICHTNAME Sichtdefinition zeigen\n" -#: help.c:257 +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [MUSTER] äquivalent zu \\dp\n" -#: help.c:260 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "Formatierung\n" -#: help.c:261 +#: help.c:269 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr "" " \\a zwischen unausgerichtetem und ausgerichtetem Ausgabemodus\n" " umschalten\n" -#: help.c:262 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr " \\C [TEXT] Tabellentitel setzen oder löschen\n" -#: help.c:263 +#: help.c:271 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr " \\f [ZEICHEN] Feldtrennzeichen zeigen oder setzen\n" -#: help.c:264 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H HTML-Ausgabemodus umschalten (gegenwärtig %s)\n" -#: help.c:266 +#: help.c:274 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" msgstr "" " \\pset [NAME [WERT]] Tabellenausgabeoption setzen\n" -" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" -#: help.c:270 +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] nur Datenzeilen zeigen (gegenwärtig %s)\n" -#: help.c:272 +#: help.c:282 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr " \\T [TEXT] HTML
-Tag-Attribute setzen oder löschen\n" -#: help.c:273 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] erweiterte Ausgabe umschalten (gegenwärtig %s)\n" -#: help.c:277 +#: help.c:287 #, c-format msgid "Connection\n" msgstr "Verbindung\n" -#: help.c:279 +#: help.c:289 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2732,7 +2895,7 @@ msgstr "" " \\c[onnect] {[DBNAME|- BENUTZER|- HOST|- PORT|-] | conninfo}\n" " mit neuer Datenbank verbinden (aktuell »%s«)\n" -#: help.c:283 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2741,74 +2904,74 @@ msgstr "" " \\c[onnect] {[DBNAME|- BENUTZER|- HOST|- PORT|-] | conninfo}\n" " mit neuer Datenbank verbinden (aktuell keine Verbindung)\n" -#: help.c:285 +#: help.c:295 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo Informationen über aktuelle Verbindung anzeigen\n" + +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [KODIERUNG] Client-Kodierung zeigen oder setzen\n" -#: help.c:286 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr "" " \\password [BENUTZERNAME]\n" " sicheres Ändern eines Benutzerpasswortes\n" -#: help.c:287 -#, c-format -msgid " \\conninfo display information about current connection\n" -msgstr " \\conninfo Informationen über aktuelle Verbindung anzeigen\n" - -#: help.c:290 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "Betriebssystem\n" -#: help.c:291 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [VERZ] Arbeitsverzeichnis wechseln\n" -#: help.c:292 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAME [WERT] Umgebungsvariable setzen oder löschen\n" -#: help.c:293 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] Zeitmessung umschalten (gegenwärtig %s)\n" -#: help.c:295 +#: help.c:305 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr " \\! [BEFEHL] Befehl in Shell ausführen oder interaktive Shell starten\n" -#: help.c:298 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "Variablen\n" -#: help.c:299 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr " \\prompt [TEXT] NAME interne Variable vom Benutzer abfragen\n" -#: help.c:300 +#: help.c:310 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr " \\set [NAME [WERT]] interne Variable setzen, oder alle anzeigen\n" -#: help.c:301 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NAME interne Variable löschen\n" -#: help.c:304 +#: help.c:314 #, c-format msgid "Large Objects\n" msgstr "Large Objects\n" -#: help.c:305 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2821,7 +2984,7 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID Large-Object-Operationen\n" -#: help.c:332 +#: help.c:342 #, c-format msgid "" "List of specially treated variables\n" @@ -2830,12 +2993,12 @@ msgstr "" "Liste besonderer Variablen\n" "\n" -#: help.c:334 +#: help.c:344 #, c-format msgid "psql variables:\n" msgstr "psql-Variablen:\n" -#: help.c:336 +#: help.c:346 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -2846,165 +3009,304 @@ msgstr "" " oder \\set NAME WERT innerhalb von psql\n" "\n" -#: help.c:338 +#: help.c:348 #, c-format -msgid " AUTOCOMMIT if set, successful SQL commands are automatically committed\n" +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" msgstr "" -" AUTOCOMMIT wenn gesetzt werden alle erfolgreichen SQL-Befehle\n" -" automatisch committet\n" +" AUTOCOMMIT\n" +" wenn gesetzt werden alle erfolgreichen SQL-Befehle automatisch committet\n" -#: help.c:339 +#: help.c:350 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" COMP_KEYWORD_CASE bestimmt, ob SQL-Schlüsselwörter in Groß- oder Klein-\n" -" schreibung vervollständigt werden\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" bestimmt, ob SQL-Schlüsselwörter in Groß- oder Kleinschreibung\n" +" vervollständigt werden [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:341 +#: help.c:353 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME Name der aktuellen Datenbank\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" Name der aktuellen Datenbank\n" -#: help.c:342 +#: help.c:355 #, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" -" ECHO kontrolliert, welche Eingaben auf die Standardausgabe\n" -" geschrieben werden [all, errors, none, queries]\n" +" ECHO\n" +" kontrolliert, welche Eingaben auf die Standardausgabe geschrieben werden\n" +" [all, errors, none, queries]\n" -#: help.c:344 +#: help.c:358 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash commands;\n" -" if set to \"noexec\", just show without execution\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" -" ECHO_HIDDEN wenn gesetzt, interne Anfragen, die von Backslash-Befehlen\n" -" ausgeführt werden, anzeigen; wenn auf »noexec« gesetzt, nur\n" -" anzeigen, nicht ausführen\n" +" ECHO_HIDDEN\n" +" wenn gesetzt, interne Anfragen, die von Backslash-Befehlen ausgeführt werden,\n" +" anzeigen; wenn auf »noexec« gesetzt, nur anzeigen, nicht ausführen\n" -#: help.c:346 +#: help.c:361 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING aktuelle Zeichensatzkodierung des Clients\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuelle Zeichensatzkodierung des Clients\n" -#: help.c:347 +#: help.c:363 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a time\n" -" (default: 0=unlimited)\n" +" ERROR\n" +" true if last query failed, else false\n" msgstr "" -" FETCH_COUNT Anzahl auf einmal zu holender und anzuzeigender Zeilen\n" -" (Standard: 0=unbegrenzt)\n" +" ERROR\n" +" »true« wenn die letzte Anfrage fehlgeschlagen ist, sonst »false«\n" -#: help.c:349 +#: help.c:365 #, c-format -msgid " HISTCONTROL controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" msgstr "" -" HISTCONTROL kontrolliert Befehlsgeschichte\n" -" [ignorespace, ignoredups, ignoreboth]\n" +" FETCH_COUNT\n" +" Anzahl auf einmal zu holender und anzuzeigender Zeilen (0 = unbegrenzt)\n" -#: help.c:350 +#: help.c:367 #, c-format -msgid " HISTFILE file name used to store the command history\n" -msgstr " HISTFILE Dateiname für die Befehlsgeschichte\n" +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" kontrolliert Befehlsgeschichte [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:351 +#: help.c:369 #, c-format -msgid " HISTSIZE max number of commands to store in the command history\n" -msgstr " HISTSIZE max. Anzahl der in der Befehlsgeschichte zu speichernden Befehle\n" +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" Dateiname für die Befehlsgeschichte\n" -#: help.c:352 +#: help.c:371 #, c-format -msgid " HOST the currently connected database server host\n" -msgstr " HOST der aktuell verbundene Datenbankserverhost\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximale Anzahl der in der Befehlsgeschichte zu speichernden Befehle\n" -#: help.c:353 -#, fuzzy, c-format -#| msgid " IGNOREEOF if unset, sending an EOF to interactive session terminates application\n" -msgid " IGNOREEOF number of EOFs needed to terminate an interactive session\n" +#: help.c:373 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" msgstr "" -" IGNOREEOF wenn nicht gesetzt beendet ein EOF in einer interaktiven\n" -" Sitzung das Programm\n" +" HOST\n" +" der aktuell verbundene Datenbankserverhost\n" -#: help.c:354 +#: help.c:375 #, c-format -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID Wert der zuletzt beinträchtigten OID\n" +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" Anzahl benötigter EOFs um eine interaktive Sitzung zu beenden\n" -#: help.c:355 +#: help.c:377 #, c-format -msgid " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" msgstr "" -" ON_ERROR_ROLLBACK wenn gesetzt beendet ein Fehler die Transaktion nicht\n" -" (verwendet implizite Sicherungspunkte)\n" +" LASTOID\n" +" Wert der zuletzt beinträchtigten OID\n" -#: help.c:356 +#: help.c:379 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr " ON_ERROR_STOP Skriptausführung bei Fehler beenden\n" +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" Fehlermeldung und SQLSTATE des letzten Fehlers, oder leer und »000000« wenn\n" +" kein Fehler\n" -#: help.c:357 +#: help.c:382 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT Serverport der aktuellen Verbindung\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" wenn gesetzt beendet ein Fehler die Transaktion nicht (verwendet implizite\n" +" Sicherungspunkte)\n" -#: help.c:358 +#: help.c:384 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 der normale psql-Prompt\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" Skriptausführung bei Fehler beenden\n" -#: help.c:359 +#: help.c:386 #, c-format -msgid " PROMPT2 specifies the prompt used when a statement continues from a previous line\n" +msgid "" +" PORT\n" +" server port of the current connection\n" msgstr "" -" PROMPT2 der Prompt, wenn eine Anweisung von der vorherigen Zeile\n" -" fortgesetzt wird\n" +" PORT\n" +" Serverport der aktuellen Verbindung\n" -#: help.c:360 +#: help.c:388 #, c-format -msgid " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr " PROMPT3 der Prompt während COPY ... FROM STDIN\n" +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" der normale psql-Prompt\n" -#: help.c:361 +#: help.c:390 #, c-format -msgid " QUIET run quietly (same as -q option)\n" -msgstr " QUIET stille Ausführung (wie Option -q)\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" der Prompt, wenn eine Anweisung von der vorherigen Zeile fortgesetzt wird\n" -#: help.c:362 +#: help.c:392 #, c-format -msgid " SHOW_CONTEXT controls display of message context fields [never, errors, always]\n" +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" msgstr "" -" SHOW_CONTEXT kontrolliert die Anzeige von Kontextinformationen in\n" -" Meldungen [never, errors, always]\n" +" PROMPT3\n" +" der Prompt während COPY ... FROM STDIN\n" -#: help.c:363 +#: help.c:394 #, c-format -msgid " SINGLELINE end of line terminates SQL command mode (same as -S option)\n" -msgstr " SINGLELINE Zeilenende beendet SQL-Anweisung (wie Option -S)\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" stille Ausführung (wie Option -q)\n" -#: help.c:364 +#: help.c:396 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP Einzelschrittmodus (wie Option -s)\n" +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" Anzahl der von der letzten Anfrage beeinträchtigten Zeilen, oder 0\n" -#: help.c:365 +#: help.c:398 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" Serverversion (kurze Zeichenkette oder numerisches Format)\n" + +#: help.c:401 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" kontrolliert die Anzeige von Kontextinformationen in Meldungen\n" +" [never, errors, always]\n" + +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" wenn gesetzt beendet Zeilenende die SQL-Anweisung (wie Option -S)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" Einzelschrittmodus (wie Option -s)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE der letzten Anfrage, oder »00000« wenn kein Fehler\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" der aktuell verbundene Datenbankbenutzer\n" + +#: help.c:411 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER der aktuell verbundene Datenbankbenutzer\n" +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" kontrolliert wieviele Details in Fehlermeldungen enthalten sind\n" +" [default, verbose, terse]\n" -#: help.c:366 +#: help.c:413 #, c-format -msgid " VERBOSITY controls verbosity of error reports [default, verbose, terse]\n" +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" msgstr "" -" VERBOSITY kontrolliert wieviele Details in Fehlermeldungen enthalten\n" -" sind [default, verbose, terse]\n" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" Version von psql (lange Zeichenkette, kurze Zeichenkette oder numerisch)\n" -#: help.c:368 +#: help.c:418 #, c-format msgid "" "\n" @@ -3013,7 +3315,7 @@ msgstr "" "\n" "Anzeigeeinstellungen:\n" -#: help.c:370 +#: help.c:420 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3024,121 +3326,167 @@ msgstr "" " oder \\pset NAME [WERT] innerhalb von psql\n" "\n" -#: help.c:372 +#: help.c:422 #, c-format -msgid " border border style (number)\n" -msgstr " border Rahmenstil (Zahl)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" Rahmenstil (Zahl)\n" -#: help.c:373 +#: help.c:424 #, c-format -msgid " columns target width for the wrapped format\n" -msgstr " columns Zielbreite für das Format »wrapped«\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" Zielbreite für das Format »wrapped«\n" -#: help.c:374 +#: help.c:426 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" -msgstr " expanded (oder x) erweiterte Ausgabe [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (oder x)\n" +" erweiterte Ausgabe [on, off, auto]\n" -#: help.c:375 +#: help.c:428 #, c-format -msgid " fieldsep field separator for unaligned output (default \"%s\")\n" +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" msgstr "" -" fieldsep Feldtrennzeichen für unausgerichteten Ausgabemodus\n" -" (Standard »%s«)\n" +" fieldsep\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus (Standard »%s«)\n" -#: help.c:376 +#: help.c:431 #, c-format -msgid " fieldsep_zero set field separator for unaligned output to zero byte\n" +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" msgstr "" -" fieldsep_zero Feldtrennzeichen für unausgerichteten Ausgabemodus auf\n" -" Null-Byte setzen\n" +" fieldsep_zero\n" +" Feldtrennzeichen für unausgerichteten Ausgabemodus auf Null-Byte setzen\n" -#: help.c:377 +#: help.c:433 #, c-format -msgid " footer enable or disable display of the table footer [on, off]\n" -msgstr " footer Tabellenfußzeile ein- oder auschalten [on, off]\n" +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" Tabellenfußzeile ein- oder auschalten [on, off]\n" -#: help.c:378 +#: help.c:435 #, c-format -msgid " format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -msgstr " format Ausgabeformat setzen [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" Ausgabeformat setzen [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:379 +#: help.c:437 #, c-format -msgid " linestyle set the border line drawing style [ascii, old-ascii, unicode]\n" -msgstr " linestyle Rahmenlinienstil setzen [ascii, old-ascii, unicode]\n" +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" Rahmenlinienstil setzen [ascii, old-ascii, unicode]\n" -#: help.c:380 +#: help.c:439 #, c-format -msgid " null set the string to be printed in place of a null value\n" +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" msgstr "" -" null setzt die Zeichenkette, die anstelle eines NULL-Wertes\n" -" ausgegeben wird\n" +" null\n" +" setzt die Zeichenkette, die anstelle eines NULL-Wertes ausgegeben wird\n" -#: help.c:381 +#: help.c:441 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale Verwendung eines Locale-spezifischen Zeichens zur Trennung\n" -" von Zifferngruppen ein- oder auschalten [on, off]\n" +" numericlocale\n" +" Verwendung eines Locale-spezifischen Zeichens zur Trennung von Zifferngruppen\n" +" einschalten [on, off]\n" -#: help.c:383 +#: help.c:443 #, c-format -msgid " pager control when an external pager is used [yes, no, always]\n" +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" msgstr "" -" pager kontrolliert Verwendung eines externen Pager-Programms\n" -" [yes, no, always]\n" +" pager\n" +" kontrolliert Verwendung eines externen Pager-Programms [yes, no, always]\n" -#: help.c:384 +#: help.c:445 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" -msgstr " recordsep Satztrennzeichen für unausgerichteten Ausgabemodus\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus\n" -#: help.c:385 +#: help.c:447 #, c-format -msgid " recordsep_zero set record separator for unaligned output to zero byte\n" +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" msgstr "" -" recordsep_zero Satztrennzeichen für unausgerichteten Ausgabemodus auf\n" -" Null-Byte setzen\n" +" recordsep_zero\n" +" Satztrennzeichen für unausgerichteten Ausgabemodus auf Null-Byte setzen\n" -#: help.c:386 +#: help.c:449 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or proportional\n" -" column widths for left-aligned data types in latex-longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (or T) Attribute für das »table«-Tag im Format »html« oder\n" -" proportionale Spaltenbreite für links ausgerichtete Datentypen\n" -" im Format »latex-longtable«\n" +" tableattr (or T)\n" +" Attribute für das »table«-Tag im Format »html« oder proportionale\n" +" Spaltenbreite für links ausgerichtete Datentypen im Format »latex-longtable«\n" -#: help.c:388 +#: help.c:452 #, c-format -msgid " title set the table title for any subsequently printed tables\n" -msgstr " title setzt den Titel darauffolgend ausgegebener Tabellen\n" +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" setzt den Titel darauffolgend ausgegebener Tabellen\n" -#: help.c:389 +#: help.c:454 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" msgstr "" -" tuples_only wenn gesetzt werden nur die eigentlichen Tabellendaten\n" -" gezeigt\n" +" tuples_only\n" +" wenn gesetzt werden nur die eigentlichen Tabellendaten gezeigt\n" -#: help.c:390 +#: help.c:456 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" setzt den Stil für Unicode-Linien [single, double]\n" +" setzt den Stil für Unicode-Linien [single, double]\n" -#: help.c:395 +#: help.c:461 #, c-format msgid "" "\n" @@ -3147,7 +3495,7 @@ msgstr "" "\n" "Umgebungsvariablen:\n" -#: help.c:399 +#: help.c:465 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3158,7 +3506,7 @@ msgstr "" " oder \\setenv NAME [WERT] innerhalb von psql\n" "\n" -#: help.c:401 +#: help.c:467 #, c-format msgid "" " set NAME=VALUE\n" @@ -3171,94 +3519,146 @@ msgstr "" " oder \\setenv NAME [WERT] innerhalb von psql\n" "\n" -#: help.c:404 -#, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS Anzahl Spalten im Format »wrapped«\n" - -#: help.c:405 +#: help.c:470 #, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER Name des externen Pager-Programms\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" Anzahl Spalten im Format »wrapped«\n" -#: help.c:406 +#: help.c:472 #, c-format -msgid " PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME wie Verbindungsparameter »application_name«\n" +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" wie Verbindungsparameter »application_name«\n" -#: help.c:407 +#: help.c:474 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE wie Verbindungsparameter »dbname«\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" wie Verbindungsparameter »dbname«\n" -#: help.c:408 +#: help.c:476 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST wie Verbindungsparameter »host«\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" wie Verbindungsparameter »host«\n" -#: help.c:409 +#: help.c:478 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT wie Verbindungsparameter »port«\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" Verbindungspasswort (nicht empfohlen)\n" -#: help.c:410 +#: help.c:480 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER wie Verbindungsparameter »user«\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" Name der Passwortdatei\n" -#: help.c:411 +#: help.c:482 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" -msgstr " PGPASSWORD Verbindungspasswort (nicht empfohlen)\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" wie Verbindungsparameter »port«\n" -#: help.c:412 +#: help.c:484 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE Name der Passwortdatei\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" wie Verbindungsparameter »user«\n" -#: help.c:413 +#: help.c:486 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" Editor für Befehle \\e, \\ef und \\ev\n" +" Editor für Befehle \\e, \\ef und \\ev\n" -#: help.c:415 +#: help.c:488 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" wie die Zeilennummer beim Aufruf des Editors angegeben wird\n" +" wie die Zeilennummer beim Aufruf des Editors angegeben wird\n" -#: help.c:417 +#: help.c:490 #, c-format -msgid " PSQL_HISTORY alternative location for the command history file\n" -msgstr " PSQL_HISTORY alternativer Pfad für History-Datei\n" +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativer Pfad für History-Datei\n" -#: help.c:418 +#: help.c:492 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" Name des externen Pager-Programms\n" + +#: help.c:494 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" -msgstr " PSQLRC alternativer Pfad für .psqlrc-Datei des Benutzers\n" +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativer Pfad für .psqlrc-Datei des Benutzers\n" -#: help.c:419 +#: help.c:496 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL Shell für den Befehl \\!\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" Shell für den Befehl \\!\n" -#: help.c:420 +#: help.c:498 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR Verzeichnis für temporäre Dateien\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" Verzeichnis für temporäre Dateien\n" -#: help.c:463 +#: help.c:542 msgid "Available help:\n" msgstr "Verfügbare Hilfe:\n" -#: help.c:547 +#: help.c:626 #, c-format msgid "" "Command: %s\n" @@ -3273,7 +3673,7 @@ msgstr "" "%s\n" "\n" -#: help.c:563 +#: help.c:642 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3320,12 +3720,17 @@ msgstr "ID" msgid "Large objects" msgstr "Large Objects" -#: mainloop.c:168 +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped\n" +msgstr "\\if: abgebrochen\n" + +#: mainloop.c:183 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "Verwenden Sie »\\q«, um %s zu verlassen.\n" -#: mainloop.c:190 +#: mainloop.c:205 msgid "" "The input is a PostgreSQL custom-format dump.\n" "Use the pg_restore command-line client to restore this dump to a database.\n" @@ -3334,11 +3739,19 @@ msgstr "" "Verwenden Sie den Kommandozeilen-Client pg_restore, um diesen Dump in die\n" "Datenbank zurückzuspielen.\n" -#: mainloop.c:210 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Verwenden Sie \\? für Hilfe oder drücken Sie Strg-C um den Eingabepuffer zu löschen." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Verwenden Sie \\? für Hilfe." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Dies ist psql, die Kommandozeilenschnittstelle für PostgreSQL." -#: mainloop.c:211 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3353,2118 +3766,2273 @@ msgstr "" " \\g oder Semikolon, um eine Anfrage auszuführen\n" " \\q um zu beenden\n" -#: psqlscanslash.l:585 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Verwenden Sie \\q zum beenden." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Verwenden Sie Strg-D zum beenden." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Verwenden Sie Strg-C zum beenden." + +#: mainloop.c:449 mainloop.c:591 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "Anfrage ignoriert; verwenden Sie \\endif oder Strg-C um den aktuellen \\if-Block zu beenden\n" + +#: mainloop.c:609 +#, c-format +msgid "reached EOF without finding closing \\endif(s)\n" +msgstr "Dateiende erreicht, aber schließendes \\endif fehlt\n" + +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen\n" -#: psqlscanslash.l:739 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" msgstr "%s: Speicher aufgebraucht\n" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:64 sql_help.c:66 -#: sql_help.c:68 sql_help.c:79 sql_help.c:81 sql_help.c:83 sql_help.c:109 -#: sql_help.c:115 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:124 -#: sql_help.c:126 sql_help.c:128 sql_help.c:221 sql_help.c:223 sql_help.c:224 -#: sql_help.c:226 sql_help.c:228 sql_help.c:231 sql_help.c:233 sql_help.c:235 -#: sql_help.c:237 sql_help.c:249 sql_help.c:250 sql_help.c:251 sql_help.c:253 -#: sql_help.c:300 sql_help.c:302 sql_help.c:304 sql_help.c:306 sql_help.c:367 -#: sql_help.c:372 sql_help.c:374 sql_help.c:417 sql_help.c:419 sql_help.c:422 -#: sql_help.c:424 sql_help.c:491 sql_help.c:496 sql_help.c:501 sql_help.c:506 -#: sql_help.c:511 sql_help.c:560 sql_help.c:562 sql_help.c:564 sql_help.c:566 -#: sql_help.c:569 sql_help.c:571 sql_help.c:582 sql_help.c:584 sql_help.c:625 -#: sql_help.c:627 sql_help.c:629 sql_help.c:632 sql_help.c:634 sql_help.c:636 -#: sql_help.c:669 sql_help.c:673 sql_help.c:677 sql_help.c:696 sql_help.c:699 -#: sql_help.c:702 sql_help.c:731 sql_help.c:743 sql_help.c:751 sql_help.c:754 -#: sql_help.c:757 sql_help.c:772 sql_help.c:775 sql_help.c:798 sql_help.c:801 -#: sql_help.c:803 sql_help.c:805 sql_help.c:807 sql_help.c:848 sql_help.c:871 -#: sql_help.c:882 sql_help.c:884 sql_help.c:903 sql_help.c:913 sql_help.c:915 -#: sql_help.c:917 sql_help.c:929 sql_help.c:933 sql_help.c:935 sql_help.c:954 -#: sql_help.c:957 sql_help.c:959 sql_help.c:960 sql_help.c:961 sql_help.c:962 -#: sql_help.c:1049 sql_help.c:1051 sql_help.c:1054 sql_help.c:1057 -#: sql_help.c:1059 sql_help.c:1061 sql_help.c:1064 sql_help.c:1067 -#: sql_help.c:1127 sql_help.c:1129 sql_help.c:1131 sql_help.c:1134 -#: sql_help.c:1155 sql_help.c:1158 sql_help.c:1161 sql_help.c:1164 -#: sql_help.c:1168 sql_help.c:1170 sql_help.c:1172 sql_help.c:1174 -#: sql_help.c:1188 sql_help.c:1191 sql_help.c:1193 sql_help.c:1195 -#: sql_help.c:1205 sql_help.c:1207 sql_help.c:1217 sql_help.c:1219 -#: sql_help.c:1229 sql_help.c:1232 sql_help.c:1254 sql_help.c:1256 -#: sql_help.c:1258 sql_help.c:1261 sql_help.c:1263 sql_help.c:1265 -#: sql_help.c:1268 sql_help.c:1318 sql_help.c:1356 sql_help.c:1359 -#: sql_help.c:1361 sql_help.c:1363 sql_help.c:1365 sql_help.c:1367 -#: sql_help.c:1370 sql_help.c:1410 sql_help.c:1615 sql_help.c:1679 -#: sql_help.c:1698 sql_help.c:1711 sql_help.c:1765 sql_help.c:1769 -#: sql_help.c:1779 sql_help.c:1799 sql_help.c:1824 sql_help.c:1842 -#: sql_help.c:1871 sql_help.c:1964 sql_help.c:2006 sql_help.c:2028 -#: sql_help.c:2048 sql_help.c:2049 sql_help.c:2084 sql_help.c:2104 -#: sql_help.c:2126 sql_help.c:2140 sql_help.c:2161 sql_help.c:2191 -#: sql_help.c:2216 sql_help.c:2262 sql_help.c:2508 sql_help.c:2521 -#: sql_help.c:2538 sql_help.c:2554 sql_help.c:2594 sql_help.c:2646 -#: sql_help.c:2650 sql_help.c:2652 sql_help.c:2658 sql_help.c:2676 -#: sql_help.c:2703 sql_help.c:2738 sql_help.c:2750 sql_help.c:2759 -#: sql_help.c:2803 sql_help.c:2817 sql_help.c:2845 sql_help.c:2853 -#: sql_help.c:2861 sql_help.c:2869 sql_help.c:2877 sql_help.c:2885 -#: sql_help.c:2893 sql_help.c:2901 sql_help.c:2910 sql_help.c:2921 -#: sql_help.c:2929 sql_help.c:2937 sql_help.c:2945 sql_help.c:2953 -#: sql_help.c:2963 sql_help.c:2972 sql_help.c:2981 sql_help.c:2989 -#: sql_help.c:2998 sql_help.c:3006 sql_help.c:3014 sql_help.c:3023 -#: sql_help.c:3031 sql_help.c:3039 sql_help.c:3047 sql_help.c:3057 -#: sql_help.c:3065 sql_help.c:3073 sql_help.c:3081 sql_help.c:3089 -#: sql_help.c:3097 sql_help.c:3114 sql_help.c:3123 sql_help.c:3131 -#: sql_help.c:3148 sql_help.c:3163 sql_help.c:3430 sql_help.c:3481 -#: sql_help.c:3510 sql_help.c:3518 sql_help.c:3937 sql_help.c:3985 -#: sql_help.c:4126 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 msgid "name" msgstr "Name" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:311 sql_help.c:1476 -#: sql_help.c:2818 sql_help.c:3733 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 msgid "aggregate_signature" msgstr "Aggregatsignatur" -#: sql_help.c:38 sql_help.c:65 sql_help.c:80 sql_help.c:116 sql_help.c:236 -#: sql_help.c:254 sql_help.c:375 sql_help.c:423 sql_help.c:500 sql_help.c:546 -#: sql_help.c:561 sql_help.c:583 sql_help.c:633 sql_help.c:698 sql_help.c:753 -#: sql_help.c:774 sql_help.c:849 sql_help.c:873 sql_help.c:883 sql_help.c:916 -#: sql_help.c:936 sql_help.c:1058 sql_help.c:1128 sql_help.c:1171 -#: sql_help.c:1192 sql_help.c:1206 sql_help.c:1218 sql_help.c:1231 -#: sql_help.c:1262 sql_help.c:1319 sql_help.c:1364 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "neuer_Name" -#: sql_help.c:41 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:234 -#: sql_help.c:252 sql_help.c:373 sql_help.c:459 sql_help.c:505 sql_help.c:585 -#: sql_help.c:594 sql_help.c:652 sql_help.c:672 sql_help.c:701 sql_help.c:756 -#: sql_help.c:802 sql_help.c:885 sql_help.c:914 sql_help.c:934 sql_help.c:958 -#: sql_help.c:1112 sql_help.c:1130 sql_help.c:1173 sql_help.c:1194 -#: sql_help.c:1257 sql_help.c:1362 sql_help.c:2494 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "neuer_Eigentümer" -#: sql_help.c:44 sql_help.c:69 sql_help.c:84 sql_help.c:238 sql_help.c:303 -#: sql_help.c:425 sql_help.c:510 sql_help.c:635 sql_help.c:676 sql_help.c:704 -#: sql_help.c:759 sql_help.c:918 sql_help.c:1060 sql_help.c:1175 -#: sql_help.c:1196 sql_help.c:1208 sql_help.c:1220 sql_help.c:1264 -#: sql_help.c:1366 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "neues_Schema" -#: sql_help.c:45 sql_help.c:1529 sql_help.c:2819 sql_help.c:3752 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 msgid "where aggregate_signature is:" msgstr "wobei Aggregatsignatur Folgendes ist:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:321 sql_help.c:346 -#: sql_help.c:349 sql_help.c:352 sql_help.c:492 sql_help.c:497 sql_help.c:502 -#: sql_help.c:507 sql_help.c:512 sql_help.c:1494 sql_help.c:1530 -#: sql_help.c:1533 sql_help.c:1536 sql_help.c:1680 sql_help.c:1699 -#: sql_help.c:1702 sql_help.c:1965 sql_help.c:2820 sql_help.c:2823 -#: sql_help.c:2826 sql_help.c:2911 sql_help.c:3316 sql_help.c:3648 -#: sql_help.c:3739 sql_help.c:3753 sql_help.c:3756 sql_help.c:3759 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 msgid "argmode" msgstr "Argmodus" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:322 sql_help.c:347 -#: sql_help.c:350 sql_help.c:353 sql_help.c:493 sql_help.c:498 sql_help.c:503 -#: sql_help.c:508 sql_help.c:513 sql_help.c:1495 sql_help.c:1531 -#: sql_help.c:1534 sql_help.c:1537 sql_help.c:1681 sql_help.c:1700 -#: sql_help.c:1703 sql_help.c:1966 sql_help.c:2821 sql_help.c:2824 -#: sql_help.c:2827 sql_help.c:2912 sql_help.c:3740 sql_help.c:3754 -#: sql_help.c:3757 sql_help.c:3760 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 msgid "argname" msgstr "Argname" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:323 sql_help.c:348 -#: sql_help.c:351 sql_help.c:354 sql_help.c:494 sql_help.c:499 sql_help.c:504 -#: sql_help.c:509 sql_help.c:514 sql_help.c:1496 sql_help.c:1532 -#: sql_help.c:1535 sql_help.c:1538 sql_help.c:1967 sql_help.c:2822 -#: sql_help.c:2825 sql_help.c:2828 sql_help.c:2913 sql_help.c:3741 -#: sql_help.c:3755 sql_help.c:3758 sql_help.c:3761 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 msgid "argtype" msgstr "Argtyp" -#: sql_help.c:110 sql_help.c:370 sql_help.c:448 sql_help.c:460 sql_help.c:799 -#: sql_help.c:843 sql_help.c:931 sql_help.c:955 sql_help.c:1189 -#: sql_help.c:1313 sql_help.c:1341 sql_help.c:1586 sql_help.c:1592 -#: sql_help.c:1874 sql_help.c:1915 sql_help.c:1922 sql_help.c:1931 -#: sql_help.c:2007 sql_help.c:2163 sql_help.c:2192 sql_help.c:2284 -#: sql_help.c:2300 sql_help.c:2523 sql_help.c:2704 sql_help.c:2726 -#: sql_help.c:3183 sql_help.c:3350 +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "Option" -#: sql_help.c:111 sql_help.c:800 sql_help.c:844 sql_help.c:956 sql_help.c:1314 -#: sql_help.c:2008 sql_help.c:2164 sql_help.c:2193 sql_help.c:2301 -#: sql_help.c:2705 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" msgstr "wobei Option Folgendes sein kann:" -#: sql_help.c:112 sql_help.c:1806 +#: sql_help.c:114 sql_help.c:2118 msgid "allowconn" msgstr "allowconn" -#: sql_help.c:113 sql_help.c:845 sql_help.c:1315 sql_help.c:1807 -#: sql_help.c:2194 sql_help.c:2706 +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" msgstr "Verbindungslimit" -#: sql_help.c:114 sql_help.c:1808 +#: sql_help.c:116 sql_help.c:2120 msgid "istemplate" msgstr "istemplate" -#: sql_help.c:120 sql_help.c:573 sql_help.c:638 sql_help.c:1063 -#: sql_help.c:1105 +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "neuer_Tablespace" -#: sql_help.c:122 sql_help.c:125 sql_help.c:127 sql_help.c:519 sql_help.c:521 -#: sql_help.c:522 sql_help.c:852 sql_help.c:856 sql_help.c:859 sql_help.c:973 -#: sql_help.c:976 sql_help.c:1321 sql_help.c:1324 sql_help.c:1326 -#: sql_help.c:1976 sql_help.c:3535 sql_help.c:3926 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" msgstr "Konfigurationsparameter" -#: sql_help.c:123 sql_help.c:371 sql_help.c:443 sql_help.c:449 sql_help.c:461 -#: sql_help.c:520 sql_help.c:568 sql_help.c:644 sql_help.c:650 sql_help.c:853 -#: sql_help.c:932 sql_help.c:974 sql_help.c:975 sql_help.c:1087 -#: sql_help.c:1107 sql_help.c:1133 sql_help.c:1190 sql_help.c:1322 -#: sql_help.c:1342 sql_help.c:1875 sql_help.c:1916 sql_help.c:1923 -#: sql_help.c:1932 sql_help.c:1977 sql_help.c:1978 sql_help.c:2036 -#: sql_help.c:2068 sql_help.c:2285 sql_help.c:2397 sql_help.c:2409 -#: sql_help.c:2422 sql_help.c:2458 sql_help.c:2480 sql_help.c:2497 -#: sql_help.c:2524 sql_help.c:2727 sql_help.c:3351 sql_help.c:3927 -#: sql_help.c:3928 +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "Wert" -#: sql_help.c:185 +#: sql_help.c:197 msgid "target_role" msgstr "Zielrolle" -#: sql_help.c:186 sql_help.c:1858 sql_help.c:2240 sql_help.c:2245 -#: sql_help.c:3298 sql_help.c:3305 sql_help.c:3319 sql_help.c:3325 -#: sql_help.c:3630 sql_help.c:3637 sql_help.c:3651 sql_help.c:3657 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "Schemaname" -#: sql_help.c:187 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "abgekürztes_Grant_oder_Revoke" -#: sql_help.c:188 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "wobei abgekürztes_Grant_oder_Revoke Folgendes sein kann:" -#: sql_help.c:189 sql_help.c:190 sql_help.c:191 sql_help.c:192 sql_help.c:193 -#: sql_help.c:194 sql_help.c:195 sql_help.c:196 sql_help.c:544 sql_help.c:572 -#: sql_help.c:637 sql_help.c:777 sql_help.c:863 sql_help.c:1062 -#: sql_help.c:1329 sql_help.c:2011 sql_help.c:2012 sql_help.c:2013 -#: sql_help.c:2014 sql_help.c:2015 sql_help.c:2142 sql_help.c:2197 -#: sql_help.c:2198 sql_help.c:2199 sql_help.c:2200 sql_help.c:2201 -#: sql_help.c:2709 sql_help.c:2710 sql_help.c:2711 sql_help.c:2712 -#: sql_help.c:2713 sql_help.c:3332 sql_help.c:3333 sql_help.c:3334 -#: sql_help.c:3631 sql_help.c:3635 sql_help.c:3638 sql_help.c:3640 -#: sql_help.c:3642 sql_help.c:3644 sql_help.c:3646 sql_help.c:3652 -#: sql_help.c:3654 sql_help.c:3656 sql_help.c:3658 sql_help.c:3660 -#: sql_help.c:3662 sql_help.c:3663 sql_help.c:3664 sql_help.c:3947 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "Rollenname" -#: sql_help.c:222 sql_help.c:436 sql_help.c:1078 sql_help.c:1080 -#: sql_help.c:1358 sql_help.c:1827 sql_help.c:1831 sql_help.c:1935 -#: sql_help.c:1939 sql_help.c:2032 sql_help.c:2393 sql_help.c:2405 -#: sql_help.c:2418 sql_help.c:2426 sql_help.c:2436 sql_help.c:2462 -#: sql_help.c:3381 sql_help.c:3396 sql_help.c:3398 sql_help.c:3812 -#: sql_help.c:3813 sql_help.c:3822 sql_help.c:3863 sql_help.c:3864 -#: sql_help.c:3865 sql_help.c:3866 sql_help.c:3867 sql_help.c:3868 -#: sql_help.c:3901 sql_help.c:3902 sql_help.c:3907 sql_help.c:3912 -#: sql_help.c:4051 sql_help.c:4052 sql_help.c:4061 sql_help.c:4102 -#: sql_help.c:4103 sql_help.c:4104 sql_help.c:4105 sql_help.c:4106 -#: sql_help.c:4107 sql_help.c:4154 sql_help.c:4156 sql_help.c:4189 -#: sql_help.c:4245 sql_help.c:4246 sql_help.c:4255 sql_help.c:4296 -#: sql_help.c:4297 sql_help.c:4298 sql_help.c:4299 sql_help.c:4300 -#: sql_help.c:4301 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "Ausdruck" -#: sql_help.c:225 +#: sql_help.c:239 msgid "domain_constraint" msgstr "Domänen-Constraint" -#: sql_help.c:227 sql_help.c:229 sql_help.c:232 sql_help.c:451 sql_help.c:452 -#: sql_help.c:1055 sql_help.c:1093 sql_help.c:1094 sql_help.c:1095 -#: sql_help.c:1115 sql_help.c:1482 sql_help.c:1484 sql_help.c:1830 -#: sql_help.c:1934 sql_help.c:1938 sql_help.c:2425 sql_help.c:2435 -#: sql_help.c:3393 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "Constraint-Name" -#: sql_help.c:230 sql_help.c:1056 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "neuer_Constraint-Name" -#: sql_help.c:301 sql_help.c:930 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "neue_Version" -#: sql_help.c:305 sql_help.c:307 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "Elementobjekt" -#: sql_help.c:308 +#: sql_help.c:324 msgid "where member_object is:" msgstr "wobei Elementobjekt Folgendes ist:" -#: sql_help.c:309 sql_help.c:314 sql_help.c:315 sql_help.c:316 sql_help.c:317 -#: sql_help.c:318 sql_help.c:319 sql_help.c:324 sql_help.c:328 sql_help.c:330 -#: sql_help.c:332 sql_help.c:333 sql_help.c:334 sql_help.c:335 sql_help.c:336 -#: sql_help.c:337 sql_help.c:338 sql_help.c:339 sql_help.c:340 sql_help.c:343 -#: sql_help.c:344 sql_help.c:1474 sql_help.c:1479 sql_help.c:1486 -#: sql_help.c:1487 sql_help.c:1488 sql_help.c:1489 sql_help.c:1490 -#: sql_help.c:1491 sql_help.c:1492 sql_help.c:1497 sql_help.c:1499 -#: sql_help.c:1503 sql_help.c:1505 sql_help.c:1509 sql_help.c:1510 -#: sql_help.c:1513 sql_help.c:1514 sql_help.c:1515 sql_help.c:1516 -#: sql_help.c:1517 sql_help.c:1518 sql_help.c:1519 sql_help.c:1520 -#: sql_help.c:1521 sql_help.c:1526 sql_help.c:1527 sql_help.c:3729 -#: sql_help.c:3734 sql_help.c:3735 sql_help.c:3736 sql_help.c:3737 -#: sql_help.c:3743 sql_help.c:3744 sql_help.c:3745 sql_help.c:3746 -#: sql_help.c:3747 sql_help.c:3748 sql_help.c:3749 sql_help.c:3750 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 msgid "object_name" msgstr "Objektname" -#: sql_help.c:310 sql_help.c:1475 sql_help.c:3732 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 msgid "aggregate_name" msgstr "Aggregatname" -#: sql_help.c:312 sql_help.c:1477 sql_help.c:1745 sql_help.c:1749 -#: sql_help.c:1751 sql_help.c:2836 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" msgstr "Quelltyp" -#: sql_help.c:313 sql_help.c:1478 sql_help.c:1746 sql_help.c:1750 -#: sql_help.c:1752 sql_help.c:2837 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" msgstr "Zieltyp" -#: sql_help.c:320 sql_help.c:741 sql_help.c:1493 sql_help.c:1747 -#: sql_help.c:1782 sql_help.c:1845 sql_help.c:2085 sql_help.c:2116 -#: sql_help.c:2600 sql_help.c:3315 sql_help.c:3647 sql_help.c:3738 -#: sql_help.c:3841 sql_help.c:3845 sql_help.c:3849 sql_help.c:3852 -#: sql_help.c:4080 sql_help.c:4084 sql_help.c:4088 sql_help.c:4091 -#: sql_help.c:4274 sql_help.c:4278 sql_help.c:4282 sql_help.c:4285 +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "Funktionsname" -#: sql_help.c:325 sql_help.c:734 sql_help.c:1500 sql_help.c:2109 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "Operatorname" -#: sql_help.c:326 sql_help.c:670 sql_help.c:674 sql_help.c:678 sql_help.c:1501 -#: sql_help.c:2086 sql_help.c:2954 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "linker_Typ" -#: sql_help.c:327 sql_help.c:671 sql_help.c:675 sql_help.c:679 sql_help.c:1502 -#: sql_help.c:2087 sql_help.c:2955 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "rechter_Typ" -#: sql_help.c:329 sql_help.c:331 sql_help.c:697 sql_help.c:700 sql_help.c:703 -#: sql_help.c:732 sql_help.c:744 sql_help.c:752 sql_help.c:755 sql_help.c:758 -#: sql_help.c:1504 sql_help.c:1506 sql_help.c:2106 sql_help.c:2127 -#: sql_help.c:2441 sql_help.c:2964 sql_help.c:2973 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "Indexmethode" -#: sql_help.c:341 sql_help.c:1111 sql_help.c:1522 sql_help.c:1973 -#: sql_help.c:2400 sql_help.c:2567 sql_help.c:3105 sql_help.c:3329 -#: sql_help.c:3661 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "Prozedurname" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "Routinenname" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 msgid "type_name" msgstr "Typname" -#: sql_help.c:342 sql_help.c:1523 sql_help.c:1972 sql_help.c:2568 -#: sql_help.c:2794 sql_help.c:3106 sql_help.c:3321 sql_help.c:3653 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 msgid "lang_name" msgstr "Sprachname" -#: sql_help.c:345 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "und Aggregatsignatur Folgendes ist:" -#: sql_help.c:368 sql_help.c:1617 sql_help.c:1872 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" msgstr "Handler-Funktion" -#: sql_help.c:369 sql_help.c:1873 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "Validator-Funktion" -#: sql_help.c:418 sql_help.c:495 sql_help.c:626 sql_help.c:1050 -#: sql_help.c:1255 sql_help.c:2432 sql_help.c:2433 sql_help.c:2449 -#: sql_help.c:2450 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "Aktion" -#: sql_help.c:420 sql_help.c:427 sql_help.c:431 sql_help.c:432 sql_help.c:435 -#: sql_help.c:437 sql_help.c:438 sql_help.c:439 sql_help.c:441 sql_help.c:444 -#: sql_help.c:446 sql_help.c:447 sql_help.c:630 sql_help.c:640 sql_help.c:642 -#: sql_help.c:645 sql_help.c:647 sql_help.c:912 sql_help.c:1052 -#: sql_help.c:1070 sql_help.c:1074 sql_help.c:1075 sql_help.c:1079 -#: sql_help.c:1081 sql_help.c:1082 sql_help.c:1083 sql_help.c:1085 -#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1357 sql_help.c:1360 -#: sql_help.c:1380 sql_help.c:1481 sql_help.c:1583 sql_help.c:1588 -#: sql_help.c:1602 sql_help.c:1603 sql_help.c:1604 sql_help.c:1913 -#: sql_help.c:1926 sql_help.c:1970 sql_help.c:2031 sql_help.c:2066 -#: sql_help.c:2270 sql_help.c:2384 sql_help.c:2392 sql_help.c:2401 -#: sql_help.c:2404 sql_help.c:2413 sql_help.c:2417 sql_help.c:2437 -#: sql_help.c:2439 sql_help.c:2446 sql_help.c:2461 sql_help.c:2478 -#: sql_help.c:2603 sql_help.c:2739 sql_help.c:3300 sql_help.c:3301 -#: sql_help.c:3380 sql_help.c:3395 sql_help.c:3397 sql_help.c:3399 -#: sql_help.c:3632 sql_help.c:3633 sql_help.c:3731 sql_help.c:3872 -#: sql_help.c:4111 sql_help.c:4153 sql_help.c:4155 sql_help.c:4157 -#: sql_help.c:4174 sql_help.c:4177 sql_help.c:4305 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "Spaltenname" -#: sql_help.c:421 sql_help.c:631 sql_help.c:1053 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "neuer_Spaltenname" -#: sql_help.c:426 sql_help.c:516 sql_help.c:639 sql_help.c:1069 -#: sql_help.c:1271 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" msgstr "wobei Aktion Folgendes sein kann:" -#: sql_help.c:428 sql_help.c:433 sql_help.c:904 sql_help.c:1071 -#: sql_help.c:1076 sql_help.c:1273 sql_help.c:1277 sql_help.c:1825 -#: sql_help.c:1914 sql_help.c:2105 sql_help.c:2263 sql_help.c:2385 -#: sql_help.c:2648 sql_help.c:3482 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "Datentyp" -#: sql_help.c:429 sql_help.c:434 sql_help.c:1072 sql_help.c:1077 -#: sql_help.c:1274 sql_help.c:1278 sql_help.c:1826 sql_help.c:1917 -#: sql_help.c:2033 sql_help.c:2386 sql_help.c:2394 sql_help.c:2406 -#: sql_help.c:2419 sql_help.c:2649 sql_help.c:2655 sql_help.c:3390 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "Sortierfolge" -#: sql_help.c:430 sql_help.c:1073 sql_help.c:1918 sql_help.c:1927 -#: sql_help.c:2387 sql_help.c:2402 sql_help.c:2414 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" msgstr "Spalten-Constraint" -#: sql_help.c:440 sql_help.c:641 sql_help.c:1084 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "ganze_Zahl" -#: sql_help.c:442 sql_help.c:445 sql_help.c:643 sql_help.c:646 sql_help.c:1086 -#: sql_help.c:1089 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "Attributoption" -#: sql_help.c:450 sql_help.c:1091 sql_help.c:1919 sql_help.c:1928 -#: sql_help.c:2388 sql_help.c:2403 sql_help.c:2415 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 msgid "table_constraint" msgstr "Tabellen-Constraint" -#: sql_help.c:453 sql_help.c:454 sql_help.c:455 sql_help.c:456 sql_help.c:1096 -#: sql_help.c:1097 sql_help.c:1098 sql_help.c:1099 sql_help.c:1524 +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "Triggername" -#: sql_help.c:457 sql_help.c:458 sql_help.c:1109 sql_help.c:1110 -#: sql_help.c:1920 sql_help.c:1925 sql_help.c:2391 sql_help.c:2412 +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 msgid "parent_table" msgstr "Elterntabelle" -#: sql_help.c:515 sql_help.c:565 sql_help.c:628 sql_help.c:1234 -#: sql_help.c:1857 +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 msgid "extension_name" msgstr "Erweiterungsname" -#: sql_help.c:517 sql_help.c:1974 +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "Ausführungskosten" -#: sql_help.c:518 sql_help.c:1975 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "Ergebniszeilen" -#: sql_help.c:539 sql_help.c:541 sql_help.c:842 sql_help.c:850 sql_help.c:854 -#: sql_help.c:857 sql_help.c:860 sql_help.c:1312 sql_help.c:1320 -#: sql_help.c:1323 sql_help.c:1325 sql_help.c:1327 sql_help.c:2241 -#: sql_help.c:2243 sql_help.c:2246 sql_help.c:2247 sql_help.c:3299 -#: sql_help.c:3303 sql_help.c:3306 sql_help.c:3308 sql_help.c:3310 -#: sql_help.c:3312 sql_help.c:3314 sql_help.c:3320 sql_help.c:3322 -#: sql_help.c:3324 sql_help.c:3326 sql_help.c:3328 sql_help.c:3330 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 msgid "role_specification" msgstr "Rollenangabe" -#: sql_help.c:540 sql_help.c:542 sql_help.c:1339 sql_help.c:1800 -#: sql_help.c:2249 sql_help.c:2724 sql_help.c:3139 sql_help.c:3957 +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "Benutzername" -#: sql_help.c:543 sql_help.c:862 sql_help.c:1328 sql_help.c:2248 -#: sql_help.c:3331 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 msgid "where role_specification can be:" msgstr "wobei Rollenangabe Folgendes sein kann:" -#: sql_help.c:545 +#: sql_help.c:569 msgid "group_name" msgstr "Gruppenname" -#: sql_help.c:563 sql_help.c:1805 sql_help.c:2037 sql_help.c:2069 -#: sql_help.c:2398 sql_help.c:2410 sql_help.c:2423 sql_help.c:2459 -#: sql_help.c:2481 sql_help.c:2493 sql_help.c:3327 sql_help.c:3659 +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" msgstr "Tablespace-Name" -#: sql_help.c:567 sql_help.c:570 sql_help.c:649 sql_help.c:651 sql_help.c:1106 -#: sql_help.c:1108 sql_help.c:2035 sql_help.c:2067 sql_help.c:2396 -#: sql_help.c:2408 sql_help.c:2421 sql_help.c:2457 sql_help.c:2479 +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "Indexname" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "Storage-Parameter" -#: sql_help.c:593 sql_help.c:1498 sql_help.c:3742 +#: sql_help.c:601 +msgid "column_number" +msgstr "Spaltennummer" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" msgstr "Large-Object-OID" -#: sql_help.c:648 sql_help.c:1104 sql_help.c:1113 sql_help.c:1116 -#: sql_help.c:1420 -msgid "index_name" -msgstr "Indexname" - -#: sql_help.c:680 sql_help.c:2090 +#: sql_help.c:712 sql_help.c:2402 msgid "res_proc" msgstr "Res-Funktion" -#: sql_help.c:681 sql_help.c:2091 +#: sql_help.c:713 sql_help.c:2403 msgid "join_proc" msgstr "Join-Funktion" -#: sql_help.c:733 sql_help.c:745 sql_help.c:2108 +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" msgstr "Strategienummer" -#: sql_help.c:735 sql_help.c:736 sql_help.c:739 sql_help.c:740 sql_help.c:746 -#: sql_help.c:747 sql_help.c:749 sql_help.c:750 sql_help.c:2110 -#: sql_help.c:2111 sql_help.c:2114 sql_help.c:2115 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "Optyp" -#: sql_help.c:737 sql_help.c:2112 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "Sortierfamilienname" -#: sql_help.c:738 sql_help.c:748 sql_help.c:2113 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "Unterst-Nummer" -#: sql_help.c:742 sql_help.c:1748 sql_help.c:2117 sql_help.c:2570 -#: sql_help.c:2572 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "Argumenttyp" -#: sql_help.c:773 sql_help.c:776 sql_help.c:804 sql_help.c:806 sql_help.c:808 -#: sql_help.c:872 sql_help.c:911 sql_help.c:1230 sql_help.c:1233 -#: sql_help.c:1379 sql_help.c:1419 sql_help.c:1483 sql_help.c:1508 -#: sql_help.c:1512 sql_help.c:1525 sql_help.c:1582 sql_help.c:1587 -#: sql_help.c:1912 sql_help.c:1924 sql_help.c:2029 sql_help.c:2065 -#: sql_help.c:2141 sql_help.c:2162 sql_help.c:2218 sql_help.c:2269 -#: sql_help.c:2383 sql_help.c:2399 sql_help.c:2411 sql_help.c:2477 -#: sql_help.c:2596 sql_help.c:2773 sql_help.c:2990 sql_help.c:3015 -#: sql_help.c:3115 sql_help.c:3297 sql_help.c:3302 sql_help.c:3347 -#: sql_help.c:3378 sql_help.c:3629 sql_help.c:3634 sql_help.c:3730 -#: sql_help.c:3827 sql_help.c:3829 sql_help.c:3878 sql_help.c:3917 -#: sql_help.c:4066 sql_help.c:4068 sql_help.c:4117 sql_help.c:4151 -#: sql_help.c:4173 sql_help.c:4175 sql_help.c:4176 sql_help.c:4260 -#: sql_help.c:4262 sql_help.c:4311 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 msgid "table_name" msgstr "Tabellenname" -#: sql_help.c:778 sql_help.c:2143 +#: sql_help.c:810 sql_help.c:2455 msgid "using_expression" msgstr "Using-Ausdruck" -#: sql_help.c:779 sql_help.c:2144 +#: sql_help.c:811 sql_help.c:2456 msgid "check_expression" msgstr "Check-Ausdruck" -#: sql_help.c:846 sql_help.c:1316 sql_help.c:2009 sql_help.c:2195 -#: sql_help.c:2707 +#: sql_help.c:885 sql_help.c:2497 +msgid "publication_parameter" +msgstr "Publikationsparameter" + +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "Passwort" -#: sql_help.c:847 sql_help.c:1317 sql_help.c:2010 sql_help.c:2196 -#: sql_help.c:2708 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "Zeit" -#: sql_help.c:851 sql_help.c:855 sql_help.c:858 sql_help.c:861 sql_help.c:3307 -#: sql_help.c:3639 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "Datenbankname" -#: sql_help.c:905 sql_help.c:2264 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" msgstr "Inkrement" -#: sql_help.c:906 sql_help.c:2265 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "Minwert" -#: sql_help.c:907 sql_help.c:2266 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "Maxwert" -#: sql_help.c:908 sql_help.c:2267 sql_help.c:3825 sql_help.c:3915 -#: sql_help.c:4064 sql_help.c:4193 sql_help.c:4258 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" msgstr "Start" -#: sql_help.c:909 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" msgstr "Restart" -#: sql_help.c:910 sql_help.c:2268 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" msgstr "Cache" -#: sql_help.c:1065 sql_help.c:1068 +#: sql_help.c:1109 sql_help.c:2646 +msgid "conninfo" +msgstr "Verbindungsinfo" + +#: sql_help.c:1111 sql_help.c:2647 +msgid "publication_name" +msgstr "Publikationsname" + +#: sql_help.c:1112 +msgid "set_publication_option" +msgstr "SET-Publikationsoption" + +#: sql_help.c:1115 +msgid "refresh_option" +msgstr "Refresh-Option" + +#: sql_help.c:1120 sql_help.c:2648 +msgid "subscription_parameter" +msgstr "Subskriptionsparameter" + +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" msgstr "Partitionsname" -#: sql_help.c:1066 sql_help.c:1929 sql_help.c:2416 +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 msgid "partition_bound_spec" -msgstr "" +msgstr "Partitionsbegrenzungsangabe" + +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 +msgid "sequence_options" +msgstr "Sequenzoptionen" + +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "Sequenzoption" -#: sql_help.c:1092 +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "Tabellen-Constraint-für-Index" -#: sql_help.c:1100 sql_help.c:1101 sql_help.c:1102 sql_help.c:1103 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "Regelname" -#: sql_help.c:1114 +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "und Partitionsbegrenzungsangabe Folgendes ist:" + +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "numerische_Konstante" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "Zeichenkettenkonstante" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "und Spalten-Constraint Folgendes ist:" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "Vorgabeausdruck" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "Indexparameter" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "Reftabelle" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "Refspalte" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "und Tabellen-Constraint Folgendes ist:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "Exclude-Element" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "Operator" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "Prädikat" + +#: sql_help.c:1365 msgid "and table_constraint_using_index is:" msgstr "und Tabellen-Constraint-für-Index Folgendes ist:" -#: sql_help.c:1132 sql_help.c:1135 sql_help.c:2496 +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "Indexparameter bei UNIQUE-, PRIMARY KEY- und EXCLUDE-Constraints sind:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "Exclude-Element in einem EXCLUDE-Constraint ist:" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "Opklasse" + +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" msgstr "Tablespace-Option" -#: sql_help.c:1156 sql_help.c:1159 sql_help.c:1165 sql_help.c:1169 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "Tokentyp" -#: sql_help.c:1157 sql_help.c:1160 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "Wörterbuchname" -#: sql_help.c:1162 sql_help.c:1166 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "altes_Wörterbuch" -#: sql_help.c:1163 sql_help.c:1167 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "neues_Wörterbuch" -#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1275 sql_help.c:1276 -#: sql_help.c:2647 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "Attributname" -#: sql_help.c:1260 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "neuer_Attributname" -#: sql_help.c:1266 sql_help.c:1270 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "neuer_Enum-Wert" -#: sql_help.c:1267 -#, fuzzy -#| msgid "new_enum_value" +#: sql_help.c:1527 msgid "neighbor_enum_value" -msgstr "neuer_Enum-Wert" +msgstr "Nachbar-Enum-Wert" -#: sql_help.c:1269 +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "existierender_Enum-Wert" -#: sql_help.c:1340 sql_help.c:1921 sql_help.c:1930 sql_help.c:2280 -#: sql_help.c:2725 sql_help.c:3140 sql_help.c:3313 sql_help.c:3348 -#: sql_help.c:3645 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" msgstr "Servername" -#: sql_help.c:1368 sql_help.c:1371 sql_help.c:2740 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "Sichtoptionsname" -#: sql_help.c:1369 sql_help.c:2741 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" msgstr "Sichtoptionswert" -#: sql_help.c:1394 sql_help.c:3973 sql_help.c:3975 sql_help.c:3999 +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "Tabelle-und-Spalten" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "wobei Option eine der folgenden sein kann:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "und Tabelle-und-Spalten Folgendes ist:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "Transaktionsmodus" -#: sql_help.c:1395 sql_help.c:3976 sql_help.c:4000 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" msgstr "wobei Transaktionsmodus Folgendes sein kann:" -#: sql_help.c:1480 +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "Argument" + +#: sql_help.c:1772 msgid "relation_name" msgstr "Relationsname" -#: sql_help.c:1485 sql_help.c:3309 sql_help.c:3641 +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 msgid "domain_name" msgstr "Domänenname" -#: sql_help.c:1507 +#: sql_help.c:1799 msgid "policy_name" msgstr "Policy-Name" -#: sql_help.c:1511 +#: sql_help.c:1812 msgid "rule_name" msgstr "Regelname" -#: sql_help.c:1528 +#: sql_help.c:1831 msgid "text" msgstr "Text" -#: sql_help.c:1553 sql_help.c:3491 sql_help.c:3679 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" msgstr "Transaktions-ID" -#: sql_help.c:1584 sql_help.c:1590 sql_help.c:3417 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "Dateiname" -#: sql_help.c:1585 sql_help.c:1591 sql_help.c:2220 sql_help.c:2221 -#: sql_help.c:2222 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "Befehl" -#: sql_help.c:1589 sql_help.c:2070 sql_help.c:2482 sql_help.c:2742 -#: sql_help.c:2760 sql_help.c:3382 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "Anfrage" -#: sql_help.c:1593 sql_help.c:3186 -msgid "where option can be one of:" -msgstr "wobei Option eine der folgenden sein kann:" - -#: sql_help.c:1594 +#: sql_help.c:1897 msgid "format_name" msgstr "Formatname" -#: sql_help.c:1595 sql_help.c:1596 sql_help.c:1599 sql_help.c:3187 -#: sql_help.c:3188 sql_help.c:3189 sql_help.c:3190 sql_help.c:3191 -#: sql_help.c:3192 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" msgstr "boolean" -#: sql_help.c:1597 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "Trennzeichen" -#: sql_help.c:1598 +#: sql_help.c:1901 msgid "null_string" msgstr "Null-Zeichenkette" -#: sql_help.c:1600 +#: sql_help.c:1903 msgid "quote_character" msgstr "Quote-Zeichen" -#: sql_help.c:1601 +#: sql_help.c:1904 msgid "escape_character" msgstr "Escape-Zeichen" -#: sql_help.c:1605 +#: sql_help.c:1908 msgid "encoding_name" msgstr "Kodierungsname" -#: sql_help.c:1616 +#: sql_help.c:1919 msgid "access_method_type" msgstr "Zugriffsmethodentyp" -#: sql_help.c:1682 sql_help.c:1701 sql_help.c:1704 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "Arg-Datentyp" -#: sql_help.c:1683 sql_help.c:1705 sql_help.c:1713 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "Übergangsfunktion" -#: sql_help.c:1684 sql_help.c:1706 sql_help.c:1714 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "Zustandsdatentyp" -#: sql_help.c:1685 sql_help.c:1707 sql_help.c:1715 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "Zustandsdatengröße" -#: sql_help.c:1686 sql_help.c:1708 sql_help.c:1716 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "Abschlussfunktion" -#: sql_help.c:1687 sql_help.c:1717 +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "Combine-Funktion" -#: sql_help.c:1688 sql_help.c:1718 +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "Serialisierungsfunktion" -#: sql_help.c:1689 sql_help.c:1719 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "Deserialisierungsfunktion" -#: sql_help.c:1690 sql_help.c:1709 sql_help.c:1720 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "Anfangswert" -#: sql_help.c:1691 sql_help.c:1721 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "Moving-Übergangsfunktion" -#: sql_help.c:1692 sql_help.c:1722 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "Moving-Inversfunktion" -#: sql_help.c:1693 sql_help.c:1723 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "Moving-Zustandsdatentyp" -#: sql_help.c:1694 sql_help.c:1724 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "Moving-Zustandsdatengröße" -#: sql_help.c:1695 sql_help.c:1725 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "Moving-Abschlussfunktion" -#: sql_help.c:1696 sql_help.c:1726 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "Moving-Anfangswert" -#: sql_help.c:1697 sql_help.c:1727 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "Sortieroperator" -#: sql_help.c:1710 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "oder die alte Syntax" -#: sql_help.c:1712 +#: sql_help.c:2020 msgid "base_type" msgstr "Basistyp" -#: sql_help.c:1766 +#: sql_help.c:2076 msgid "locale" msgstr "Locale" -#: sql_help.c:1767 sql_help.c:1803 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1768 sql_help.c:1804 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1770 +#: sql_help.c:2079 sql_help.c:4122 +msgid "provider" +msgstr "Provider" + +#: sql_help.c:2080 sql_help.c:2171 +msgid "version" +msgstr "Version" + +#: sql_help.c:2082 msgid "existing_collation" msgstr "existierende_Sortierfolge" -#: sql_help.c:1780 +#: sql_help.c:2092 msgid "source_encoding" msgstr "Quellkodierung" -#: sql_help.c:1781 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "Zielkodierung" -#: sql_help.c:1801 sql_help.c:2522 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "Vorlage" -#: sql_help.c:1802 +#: sql_help.c:2114 msgid "encoding" msgstr "Kodierung" -#: sql_help.c:1828 +#: sql_help.c:2140 msgid "constraint" msgstr "Constraint" -#: sql_help.c:1829 +#: sql_help.c:2141 msgid "where constraint is:" msgstr "wobei Constraint Folgendes ist:" -#: sql_help.c:1843 sql_help.c:2217 sql_help.c:2595 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "Ereignis" -#: sql_help.c:1844 +#: sql_help.c:2156 msgid "filter_variable" msgstr "Filtervariable" -#: sql_help.c:1859 -msgid "version" -msgstr "Version" - -#: sql_help.c:1860 +#: sql_help.c:2172 msgid "old_version" msgstr "alte_Version" -#: sql_help.c:1933 sql_help.c:2424 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" msgstr "wobei Spalten-Constraint Folgendes ist:" -#: sql_help.c:1936 sql_help.c:1968 sql_help.c:2427 -msgid "default_expr" -msgstr "Vorgabeausdruck" - -#: sql_help.c:1937 sql_help.c:2434 -msgid "and table_constraint is:" -msgstr "und Tabellen-Constraint Folgendes ist:" - -#: sql_help.c:1969 +#: sql_help.c:2280 msgid "rettype" msgstr "Rückgabetyp" -#: sql_help.c:1971 +#: sql_help.c:2282 msgid "column_type" msgstr "Spaltentyp" -#: sql_help.c:1979 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "Definition" -#: sql_help.c:1980 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "Objektdatei" -#: sql_help.c:1981 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "Linksymbol" -#: sql_help.c:1982 -msgid "attribute" -msgstr "Attribut" - -#: sql_help.c:2016 sql_help.c:2202 sql_help.c:2714 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" msgstr "Uid" -#: sql_help.c:2030 +#: sql_help.c:2341 msgid "method" msgstr "Methode" -#: sql_help.c:2034 sql_help.c:2395 sql_help.c:2407 sql_help.c:2420 -#: sql_help.c:2463 sql_help.c:3391 -msgid "opclass" -msgstr "Opklasse" - -#: sql_help.c:2038 sql_help.c:2445 -msgid "predicate" -msgstr "Prädikat" - -#: sql_help.c:2050 +#: sql_help.c:2362 msgid "call_handler" msgstr "Handler" -#: sql_help.c:2051 +#: sql_help.c:2363 msgid "inline_handler" msgstr "Inline-Handler" -#: sql_help.c:2052 +#: sql_help.c:2364 msgid "valfunction" msgstr "Valfunktion" -#: sql_help.c:2088 +#: sql_help.c:2400 msgid "com_op" msgstr "Kommutator-Op" -#: sql_help.c:2089 +#: sql_help.c:2401 msgid "neg_op" msgstr "Umkehrungs-Op" -#: sql_help.c:2107 +#: sql_help.c:2419 msgid "family_name" msgstr "Familienname" -#: sql_help.c:2118 +#: sql_help.c:2430 msgid "storage_type" msgstr "Storage-Typ" -#: sql_help.c:2219 sql_help.c:2599 sql_help.c:2776 sql_help.c:3401 -#: sql_help.c:3816 sql_help.c:3818 sql_help.c:3906 sql_help.c:3908 -#: sql_help.c:4055 sql_help.c:4057 sql_help.c:4160 sql_help.c:4249 -#: sql_help.c:4251 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "Bedingung" -#: sql_help.c:2223 sql_help.c:2602 +#: sql_help.c:2557 sql_help.c:2961 msgid "where event can be one of:" msgstr "wobei Ereignis eins der folgenden sein kann:" -#: sql_help.c:2242 sql_help.c:2244 +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "Schemaelement" -#: sql_help.c:2281 +#: sql_help.c:2615 msgid "server_type" msgstr "Servertyp" -#: sql_help.c:2282 +#: sql_help.c:2616 msgid "server_version" msgstr "Serverversion" -#: sql_help.c:2283 sql_help.c:3311 sql_help.c:3643 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" msgstr "FDW-Name" -#: sql_help.c:2299 +#: sql_help.c:2630 +msgid "statistics_name" +msgstr "Statistikname" + +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "Statistikart" + +#: sql_help.c:2645 msgid "subscription_name" msgstr "Subskriptionsname" -#: sql_help.c:2389 +#: sql_help.c:2741 msgid "source_table" msgstr "Quelltabelle" -#: sql_help.c:2390 +#: sql_help.c:2742 msgid "like_option" msgstr "Like-Option" -#: sql_help.c:2428 sql_help.c:2429 sql_help.c:2438 sql_help.c:2440 -#: sql_help.c:2444 -msgid "index_parameters" -msgstr "Indexparameter" - -#: sql_help.c:2430 sql_help.c:2447 -msgid "reftable" -msgstr "Reftabelle" - -#: sql_help.c:2431 sql_help.c:2448 -msgid "refcolumn" -msgstr "Refspalte" - -#: sql_help.c:2442 -msgid "exclude_element" -msgstr "Exclude-Element" - -#: sql_help.c:2443 sql_help.c:3823 sql_help.c:3913 sql_help.c:4062 -#: sql_help.c:4191 sql_help.c:4256 -msgid "operator" -msgstr "Operator" - -#: sql_help.c:2451 +#: sql_help.c:2804 msgid "and like_option is:" msgstr "und Like-Option Folgendes ist:" -#: sql_help.c:2452 -msgid "and partition_bound_spec is:" -msgstr "" - -#: sql_help.c:2453 sql_help.c:2454 sql_help.c:2455 -msgid "bound_literal" -msgstr "" - -#: sql_help.c:2456 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "Indexparameter bei UNIQUE-, PRIMARY KEY- und EXCLUDE-Constraints sind:" - -#: sql_help.c:2460 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "Exclude-Element in einem EXCLUDE-Constraint ist:" - -#: sql_help.c:2495 +#: sql_help.c:2854 msgid "directory" msgstr "Verzeichnis" -#: sql_help.c:2509 +#: sql_help.c:2868 msgid "parser_name" msgstr "Parser-Name" -#: sql_help.c:2510 +#: sql_help.c:2869 msgid "source_config" msgstr "Quellkonfig" -#: sql_help.c:2539 +#: sql_help.c:2898 msgid "start_function" msgstr "Startfunktion" -#: sql_help.c:2540 +#: sql_help.c:2899 msgid "gettoken_function" msgstr "Gettext-Funktion" -#: sql_help.c:2541 +#: sql_help.c:2900 msgid "end_function" msgstr "Endfunktion" -#: sql_help.c:2542 +#: sql_help.c:2901 msgid "lextypes_function" msgstr "Lextypenfunktion" -#: sql_help.c:2543 +#: sql_help.c:2902 msgid "headline_function" msgstr "Headline-Funktion" -#: sql_help.c:2555 +#: sql_help.c:2914 msgid "init_function" msgstr "Init-Funktion" -#: sql_help.c:2556 +#: sql_help.c:2915 msgid "lexize_function" msgstr "Lexize-Funktion" -#: sql_help.c:2569 +#: sql_help.c:2928 msgid "from_sql_function_name" msgstr "From-SQL-Funktionsname" -#: sql_help.c:2571 +#: sql_help.c:2930 msgid "to_sql_function_name" msgstr "To-SQL-Funktionsname" -#: sql_help.c:2597 +#: sql_help.c:2956 msgid "referenced_table_name" msgstr "verwiesener_Tabellenname" -#: sql_help.c:2598 -#, fuzzy -#| msgid "relation_name" +#: sql_help.c:2957 msgid "transition_relation_name" -msgstr "Relationsname" +msgstr "Übergangsrelationsname" -#: sql_help.c:2601 +#: sql_help.c:2960 msgid "arguments" msgstr "Argumente" -#: sql_help.c:2651 sql_help.c:3751 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "Label" -#: sql_help.c:2653 +#: sql_help.c:3012 msgid "subtype" msgstr "Untertyp" -#: sql_help.c:2654 +#: sql_help.c:3013 msgid "subtype_operator_class" msgstr "Untertyp-Operatorklasse" -#: sql_help.c:2656 +#: sql_help.c:3015 msgid "canonical_function" msgstr "Canonical-Funktion" -#: sql_help.c:2657 +#: sql_help.c:3016 msgid "subtype_diff_function" msgstr "Untertyp-Diff-Funktion" -#: sql_help.c:2659 +#: sql_help.c:3018 msgid "input_function" msgstr "Eingabefunktion" -#: sql_help.c:2660 +#: sql_help.c:3019 msgid "output_function" msgstr "Ausgabefunktion" -#: sql_help.c:2661 +#: sql_help.c:3020 msgid "receive_function" msgstr "Empfangsfunktion" -#: sql_help.c:2662 +#: sql_help.c:3021 msgid "send_function" msgstr "Sendefunktion" -#: sql_help.c:2663 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "Typmod-Eingabefunktion" -#: sql_help.c:2664 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "Typmod-Ausgabefunktion" -#: sql_help.c:2665 +#: sql_help.c:3024 msgid "analyze_function" msgstr "Analyze-Funktion" -#: sql_help.c:2666 +#: sql_help.c:3025 msgid "internallength" msgstr "interne_Länge" -#: sql_help.c:2667 +#: sql_help.c:3026 msgid "alignment" msgstr "Ausrichtung" -#: sql_help.c:2668 +#: sql_help.c:3027 msgid "storage" msgstr "Speicherung" -#: sql_help.c:2669 +#: sql_help.c:3028 msgid "like_type" msgstr "wie_Typ" -#: sql_help.c:2670 +#: sql_help.c:3029 msgid "category" msgstr "Kategorie" -#: sql_help.c:2671 +#: sql_help.c:3030 msgid "preferred" msgstr "bevorzugt" -#: sql_help.c:2672 +#: sql_help.c:3031 msgid "default" msgstr "Vorgabewert" -#: sql_help.c:2673 +#: sql_help.c:3032 msgid "element" msgstr "Element" -#: sql_help.c:2674 +#: sql_help.c:3033 msgid "delimiter" msgstr "Trennzeichen" -#: sql_help.c:2675 +#: sql_help.c:3034 msgid "collatable" msgstr "sortierbar" -#: sql_help.c:2772 sql_help.c:3377 sql_help.c:3811 sql_help.c:3900 -#: sql_help.c:4050 sql_help.c:4150 sql_help.c:4244 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "With-Anfrage" -#: sql_help.c:2774 sql_help.c:3379 sql_help.c:3830 sql_help.c:3836 -#: sql_help.c:3839 sql_help.c:3843 sql_help.c:3847 sql_help.c:3855 -#: sql_help.c:4069 sql_help.c:4075 sql_help.c:4078 sql_help.c:4082 -#: sql_help.c:4086 sql_help.c:4094 sql_help.c:4152 sql_help.c:4263 -#: sql_help.c:4269 sql_help.c:4272 sql_help.c:4276 sql_help.c:4280 -#: sql_help.c:4288 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" msgstr "Alias" -#: sql_help.c:2775 +#: sql_help.c:3134 msgid "using_list" msgstr "Using-Liste" -#: sql_help.c:2777 sql_help.c:3218 sql_help.c:3458 sql_help.c:4161 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "Cursor-Name" -#: sql_help.c:2778 sql_help.c:3385 sql_help.c:4162 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "Ausgabeausdruck" -#: sql_help.c:2779 sql_help.c:3386 sql_help.c:3814 sql_help.c:3903 -#: sql_help.c:4053 sql_help.c:4163 sql_help.c:4247 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "Ausgabename" -#: sql_help.c:2795 +#: sql_help.c:3154 msgid "code" msgstr "Code" -#: sql_help.c:3164 +#: sql_help.c:3553 msgid "parameter" msgstr "Parameter" -#: sql_help.c:3184 sql_help.c:3185 sql_help.c:3483 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "Anweisung" -#: sql_help.c:3217 sql_help.c:3457 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" msgstr "Richtung" -#: sql_help.c:3219 sql_help.c:3459 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" msgstr "wobei Richtung leer sein kann oder Folgendes:" -#: sql_help.c:3220 sql_help.c:3221 sql_help.c:3222 sql_help.c:3223 -#: sql_help.c:3224 sql_help.c:3460 sql_help.c:3461 sql_help.c:3462 -#: sql_help.c:3463 sql_help.c:3464 sql_help.c:3824 sql_help.c:3826 -#: sql_help.c:3914 sql_help.c:3916 sql_help.c:4063 sql_help.c:4065 -#: sql_help.c:4192 sql_help.c:4194 sql_help.c:4257 sql_help.c:4259 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" msgstr "Anzahl" -#: sql_help.c:3304 sql_help.c:3636 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "Sequenzname" -#: sql_help.c:3317 sql_help.c:3649 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "Argname" -#: sql_help.c:3318 sql_help.c:3650 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "Argtyp" -#: sql_help.c:3323 sql_help.c:3655 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "Large-Object-OID" -#: sql_help.c:3346 +#: sql_help.c:3735 msgid "remote_schema" msgstr "fernes_Schema" -#: sql_help.c:3349 +#: sql_help.c:3738 msgid "local_schema" msgstr "lokales_Schema" -#: sql_help.c:3383 +#: sql_help.c:3773 msgid "conflict_target" msgstr "Konfliktziel" -#: sql_help.c:3384 +#: sql_help.c:3774 msgid "conflict_action" msgstr "Konfliktaktion" -#: sql_help.c:3387 +#: sql_help.c:3777 msgid "where conflict_target can be one of:" msgstr "wobei Konfliktziel Folgendes sein kann:" -#: sql_help.c:3388 +#: sql_help.c:3778 msgid "index_column_name" msgstr "Indexspaltenname" -#: sql_help.c:3389 +#: sql_help.c:3779 msgid "index_expression" msgstr "Indexausdruck" -#: sql_help.c:3392 +#: sql_help.c:3782 msgid "index_predicate" msgstr "Indexprädikat" -#: sql_help.c:3394 +#: sql_help.c:3784 msgid "and conflict_action is one of:" msgstr "und Konfliktaktion Folgendes sein kann:" -#: sql_help.c:3400 sql_help.c:4158 +#: sql_help.c:3790 sql_help.c:4562 msgid "sub-SELECT" msgstr "Sub-SELECT" -#: sql_help.c:3409 sql_help.c:3472 sql_help.c:4134 +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "Kanal" -#: sql_help.c:3431 +#: sql_help.c:3821 msgid "lockmode" msgstr "Sperrmodus" -#: sql_help.c:3432 +#: sql_help.c:3822 msgid "where lockmode is one of:" msgstr "wobei Sperrmodus Folgendes sein kann:" -#: sql_help.c:3473 +#: sql_help.c:3863 msgid "payload" msgstr "Payload" -#: sql_help.c:3500 +#: sql_help.c:3890 msgid "old_role" msgstr "alte_Rolle" -#: sql_help.c:3501 +#: sql_help.c:3891 msgid "new_role" msgstr "neue_Rolle" -#: sql_help.c:3526 sql_help.c:3687 sql_help.c:3695 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "Sicherungspunktsname" -#: sql_help.c:3728 -msgid "provider" -msgstr "Provider" - -#: sql_help.c:3815 sql_help.c:3857 sql_help.c:3859 sql_help.c:3905 -#: sql_help.c:4054 sql_help.c:4096 sql_help.c:4098 sql_help.c:4248 -#: sql_help.c:4290 sql_help.c:4292 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" msgstr "From-Element" -#: sql_help.c:3817 sql_help.c:3869 sql_help.c:4056 sql_help.c:4108 -#: sql_help.c:4250 sql_help.c:4302 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 msgid "grouping_element" msgstr "Gruppierelement" -#: sql_help.c:3819 sql_help.c:3909 sql_help.c:4058 sql_help.c:4252 +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "Fenstername" -#: sql_help.c:3820 sql_help.c:3910 sql_help.c:4059 sql_help.c:4253 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "Fensterdefinition" -#: sql_help.c:3821 sql_help.c:3835 sql_help.c:3873 sql_help.c:3911 -#: sql_help.c:4060 sql_help.c:4074 sql_help.c:4112 sql_help.c:4254 -#: sql_help.c:4268 sql_help.c:4306 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "Select" -#: sql_help.c:3828 sql_help.c:4067 sql_help.c:4261 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" msgstr "wobei From-Element Folgendes sein kann:" -#: sql_help.c:3831 sql_help.c:3837 sql_help.c:3840 sql_help.c:3844 -#: sql_help.c:3856 sql_help.c:4070 sql_help.c:4076 sql_help.c:4079 -#: sql_help.c:4083 sql_help.c:4095 sql_help.c:4264 sql_help.c:4270 -#: sql_help.c:4273 sql_help.c:4277 sql_help.c:4289 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" msgstr "Spaltenalias" -#: sql_help.c:3832 sql_help.c:4071 sql_help.c:4265 +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 msgid "sampling_method" msgstr "Stichprobenmethode" -#: sql_help.c:3833 sql_help.c:3842 sql_help.c:3846 sql_help.c:3850 -#: sql_help.c:3853 sql_help.c:4072 sql_help.c:4081 sql_help.c:4085 -#: sql_help.c:4089 sql_help.c:4092 sql_help.c:4266 sql_help.c:4275 -#: sql_help.c:4279 sql_help.c:4283 sql_help.c:4286 -msgid "argument" -msgstr "Argument" - -#: sql_help.c:3834 sql_help.c:4073 sql_help.c:4267 +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 msgid "seed" msgstr "Startwert" -#: sql_help.c:3838 sql_help.c:3871 sql_help.c:4077 sql_help.c:4110 -#: sql_help.c:4271 sql_help.c:4304 +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "With-Anfragename" -#: sql_help.c:3848 sql_help.c:3851 sql_help.c:3854 sql_help.c:4087 -#: sql_help.c:4090 sql_help.c:4093 sql_help.c:4281 sql_help.c:4284 -#: sql_help.c:4287 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" msgstr "Spaltendefinition" -#: sql_help.c:3858 sql_help.c:4097 sql_help.c:4291 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" msgstr "Verbundtyp" -#: sql_help.c:3860 sql_help.c:4099 sql_help.c:4293 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" msgstr "Verbundbedingung" -#: sql_help.c:3861 sql_help.c:4100 sql_help.c:4294 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" msgstr "Verbundspalte" -#: sql_help.c:3862 sql_help.c:4101 sql_help.c:4295 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 msgid "and grouping_element can be one of:" msgstr "und Gruppierelement eins der folgenden sein kann:" -#: sql_help.c:3870 sql_help.c:4109 sql_help.c:4303 +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" msgstr "und With-Anfrage ist:" -#: sql_help.c:3874 sql_help.c:4113 sql_help.c:4307 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "values" -#: sql_help.c:3875 sql_help.c:4114 sql_help.c:4308 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" msgstr "insert" -#: sql_help.c:3876 sql_help.c:4115 sql_help.c:4309 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "update" -#: sql_help.c:3877 sql_help.c:4116 sql_help.c:4310 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "delete" -#: sql_help.c:3904 +#: sql_help.c:4308 msgid "new_table" msgstr "neue_Tabelle" -#: sql_help.c:3929 +#: sql_help.c:4333 msgid "timezone" msgstr "Zeitzone" -#: sql_help.c:3974 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "Snapshot-ID" -#: sql_help.c:4159 +#: sql_help.c:4563 msgid "from_list" msgstr "From-Liste" -#: sql_help.c:4190 +#: sql_help.c:4607 msgid "sort_expression" msgstr "Sortierausdruck" -#: sql_help.c:4317 sql_help.c:5087 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" msgstr "bricht die aktuelle Transaktion ab" -#: sql_help.c:4322 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" msgstr "ändert die Definition einer Aggregatfunktion" -#: sql_help.c:4327 +#: sql_help.c:4744 msgid "change the definition of a collation" msgstr "ändert die Definition einer Sortierfolge" -#: sql_help.c:4332 +#: sql_help.c:4749 msgid "change the definition of a conversion" msgstr "ändert die Definition einer Zeichensatzkonversion" -#: sql_help.c:4337 +#: sql_help.c:4754 msgid "change a database" msgstr "ändert eine Datenbank" -#: sql_help.c:4342 +#: sql_help.c:4759 msgid "define default access privileges" msgstr "definiert vorgegebene Zugriffsprivilegien" -#: sql_help.c:4347 +#: sql_help.c:4764 msgid "change the definition of a domain" msgstr "ändert die Definition einer Domäne" -#: sql_help.c:4352 +#: sql_help.c:4769 msgid "change the definition of an event trigger" msgstr "ändert die Definition eines Ereignistriggers" -#: sql_help.c:4357 +#: sql_help.c:4774 msgid "change the definition of an extension" msgstr "ändert die Definition einer Erweiterung" -#: sql_help.c:4362 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" msgstr "ändert die Definition eines Fremddaten-Wrappers" -#: sql_help.c:4367 +#: sql_help.c:4784 msgid "change the definition of a foreign table" msgstr "ändert die Definition einer Fremdtabelle" -#: sql_help.c:4372 +#: sql_help.c:4789 msgid "change the definition of a function" msgstr "ändert die Definition einer Funktion" -#: sql_help.c:4377 +#: sql_help.c:4794 msgid "change role name or membership" msgstr "ändert Rollenname oder -mitglieder" -#: sql_help.c:4382 +#: sql_help.c:4799 msgid "change the definition of an index" msgstr "ändert die Definition eines Index" -#: sql_help.c:4387 +#: sql_help.c:4804 msgid "change the definition of a procedural language" msgstr "ändert die Definition einer prozeduralen Sprache" -#: sql_help.c:4392 +#: sql_help.c:4809 msgid "change the definition of a large object" msgstr "ändert die Definition eines Large Object" -#: sql_help.c:4397 +#: sql_help.c:4814 msgid "change the definition of a materialized view" msgstr "ändert die Definition einer materialisierten Sicht" -#: sql_help.c:4402 +#: sql_help.c:4819 msgid "change the definition of an operator" msgstr "ändert die Definition eines Operators" -#: sql_help.c:4407 +#: sql_help.c:4824 msgid "change the definition of an operator class" msgstr "ändert die Definition einer Operatorklasse" -#: sql_help.c:4412 +#: sql_help.c:4829 msgid "change the definition of an operator family" msgstr "ändert die Definition einer Operatorfamilie" -#: sql_help.c:4417 +#: sql_help.c:4834 msgid "change the definition of a row level security policy" msgstr "ändert die Definition einer Policy für Sicherheit auf Zeilenebene" -#: sql_help.c:4422 +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "ändert die Definition einer Prozedur" + +#: sql_help.c:4844 msgid "change the definition of a publication" msgstr "ändert die Definition einer Publikation" -#: sql_help.c:4427 sql_help.c:4502 +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" msgstr "ändert eine Datenbankrolle" -#: sql_help.c:4432 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "ändert die Definition einer Routine" + +#: sql_help.c:4859 msgid "change the definition of a rule" msgstr "ändert die Definition einer Regel" -#: sql_help.c:4437 +#: sql_help.c:4864 msgid "change the definition of a schema" msgstr "ändert die Definition eines Schemas" -#: sql_help.c:4442 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" msgstr "ändert die Definition eines Sequenzgenerators" -#: sql_help.c:4447 +#: sql_help.c:4874 msgid "change the definition of a foreign server" msgstr "ändert die Definition eines Fremdservers" -#: sql_help.c:4452 +#: sql_help.c:4879 +msgid "change the definition of an extended statistics object" +msgstr "ändert die Definition eines erweiterten Statistikobjekts" + +#: sql_help.c:4884 msgid "change the definition of a subscription" msgstr "ändert die Definition einer Subskription" -#: sql_help.c:4457 +#: sql_help.c:4889 msgid "change a server configuration parameter" msgstr "ändert einen Server-Konfigurationsparameter" -#: sql_help.c:4462 +#: sql_help.c:4894 msgid "change the definition of a table" msgstr "ändert die Definition einer Tabelle" -#: sql_help.c:4467 +#: sql_help.c:4899 msgid "change the definition of a tablespace" msgstr "ändert die Definition eines Tablespace" -#: sql_help.c:4472 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" msgstr "ändert die Definition einer Textsuchekonfiguration" -#: sql_help.c:4477 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" msgstr "ändert die Definition eines Textsuchewörterbuchs" -#: sql_help.c:4482 +#: sql_help.c:4914 msgid "change the definition of a text search parser" msgstr "ändert die Definition eines Textsucheparsers" -#: sql_help.c:4487 +#: sql_help.c:4919 msgid "change the definition of a text search template" msgstr "ändert die Definition einer Textsuchevorlage" -#: sql_help.c:4492 +#: sql_help.c:4924 msgid "change the definition of a trigger" msgstr "ändert die Definition eines Triggers" -#: sql_help.c:4497 +#: sql_help.c:4929 msgid "change the definition of a type" msgstr "ändert die Definition eines Typs" -#: sql_help.c:4507 +#: sql_help.c:4939 msgid "change the definition of a user mapping" msgstr "ändert die Definition einer Benutzerabbildung" -#: sql_help.c:4512 +#: sql_help.c:4944 msgid "change the definition of a view" msgstr "ändert die Definition einer Sicht" -#: sql_help.c:4517 +#: sql_help.c:4949 msgid "collect statistics about a database" msgstr "sammelt Statistiken über eine Datenbank" -#: sql_help.c:4522 sql_help.c:5152 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" msgstr "startet einen Transaktionsblock" -#: sql_help.c:4527 -msgid "force a transaction log checkpoint" -msgstr "erzwingt einen Checkpoint im Transaktionslog" +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "ruft eine Prozedur auf" + +#: sql_help.c:4964 +msgid "force a write-ahead log checkpoint" +msgstr "erzwingt einen Checkpoint im Write-Ahead-Log" -#: sql_help.c:4532 +#: sql_help.c:4969 msgid "close a cursor" msgstr "schließt einen Cursor" -#: sql_help.c:4537 +#: sql_help.c:4974 msgid "cluster a table according to an index" msgstr "clustert eine Tabelle nach einem Index" -#: sql_help.c:4542 +#: sql_help.c:4979 msgid "define or change the comment of an object" msgstr "definiert oder ändert den Kommentar eines Objektes" -#: sql_help.c:4547 sql_help.c:4987 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" msgstr "schließt die aktuelle Transaktion ab" -#: sql_help.c:4552 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "schließt eine Transaktion ab, die vorher für Two-Phase-Commit vorbereitet worden war" -#: sql_help.c:4557 +#: sql_help.c:4994 msgid "copy data between a file and a table" msgstr "kopiert Daten zwischen einer Datei und einer Tabelle" -#: sql_help.c:4562 +#: sql_help.c:4999 msgid "define a new access method" msgstr "definiert eine neue Zugriffsmethode" -#: sql_help.c:4567 +#: sql_help.c:5004 msgid "define a new aggregate function" msgstr "definiert eine neue Aggregatfunktion" -#: sql_help.c:4572 +#: sql_help.c:5009 msgid "define a new cast" msgstr "definiert eine neue Typumwandlung" -#: sql_help.c:4577 +#: sql_help.c:5014 msgid "define a new collation" msgstr "definiert eine neue Sortierfolge" -#: sql_help.c:4582 +#: sql_help.c:5019 msgid "define a new encoding conversion" msgstr "definiert eine neue Kodierungskonversion" -#: sql_help.c:4587 +#: sql_help.c:5024 msgid "create a new database" msgstr "erzeugt eine neue Datenbank" -#: sql_help.c:4592 +#: sql_help.c:5029 msgid "define a new domain" msgstr "definiert eine neue Domäne" -#: sql_help.c:4597 +#: sql_help.c:5034 msgid "define a new event trigger" msgstr "definiert einen neuen Ereignistrigger" -#: sql_help.c:4602 +#: sql_help.c:5039 msgid "install an extension" msgstr "installiert eine Erweiterung" -#: sql_help.c:4607 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" msgstr "definiert einen neuen Fremddaten-Wrapper" -#: sql_help.c:4612 +#: sql_help.c:5049 msgid "define a new foreign table" msgstr "definiert eine neue Fremdtabelle" -#: sql_help.c:4617 +#: sql_help.c:5054 msgid "define a new function" msgstr "definiert eine neue Funktion" -#: sql_help.c:4622 sql_help.c:4667 sql_help.c:4747 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" msgstr "definiert eine neue Datenbankrolle" -#: sql_help.c:4627 +#: sql_help.c:5064 msgid "define a new index" msgstr "definiert einen neuen Index" -#: sql_help.c:4632 +#: sql_help.c:5069 msgid "define a new procedural language" msgstr "definiert eine neue prozedurale Sprache" -#: sql_help.c:4637 +#: sql_help.c:5074 msgid "define a new materialized view" msgstr "definiert eine neue materialisierte Sicht" -#: sql_help.c:4642 +#: sql_help.c:5079 msgid "define a new operator" msgstr "definiert einen neuen Operator" -#: sql_help.c:4647 +#: sql_help.c:5084 msgid "define a new operator class" msgstr "definiert eine neue Operatorklasse" -#: sql_help.c:4652 +#: sql_help.c:5089 msgid "define a new operator family" msgstr "definiert eine neue Operatorfamilie" -#: sql_help.c:4657 +#: sql_help.c:5094 msgid "define a new row level security policy for a table" msgstr "definiert eine neue Policy für Sicherheit auf Zeilenebene für eine Tabelle" -#: sql_help.c:4662 +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "definiert eine neue Prozedur" + +#: sql_help.c:5104 msgid "define a new publication" msgstr "definiert eine neue Publikation" -#: sql_help.c:4672 +#: sql_help.c:5114 msgid "define a new rewrite rule" msgstr "definiert eine neue Umschreiberegel" -#: sql_help.c:4677 +#: sql_help.c:5119 msgid "define a new schema" msgstr "definiert ein neues Schema" -#: sql_help.c:4682 +#: sql_help.c:5124 msgid "define a new sequence generator" msgstr "definiert einen neuen Sequenzgenerator" -#: sql_help.c:4687 +#: sql_help.c:5129 msgid "define a new foreign server" msgstr "definiert einen neuen Fremdserver" -#: sql_help.c:4692 +#: sql_help.c:5134 +msgid "define extended statistics" +msgstr "definiert erweiterte Statistiken" + +#: sql_help.c:5139 msgid "define a new subscription" msgstr "definiert eine neue Subskription" -#: sql_help.c:4697 +#: sql_help.c:5144 msgid "define a new table" msgstr "definiert eine neue Tabelle" -#: sql_help.c:4702 sql_help.c:5117 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" msgstr "definiert eine neue Tabelle aus den Ergebnissen einer Anfrage" -#: sql_help.c:4707 +#: sql_help.c:5154 msgid "define a new tablespace" msgstr "definiert einen neuen Tablespace" -#: sql_help.c:4712 +#: sql_help.c:5159 msgid "define a new text search configuration" msgstr "definiert eine neue Textsuchekonfiguration" -#: sql_help.c:4717 +#: sql_help.c:5164 msgid "define a new text search dictionary" msgstr "definiert ein neues Textsuchewörterbuch" -#: sql_help.c:4722 +#: sql_help.c:5169 msgid "define a new text search parser" msgstr "definiert einen neuen Textsucheparser" -#: sql_help.c:4727 +#: sql_help.c:5174 msgid "define a new text search template" msgstr "definiert eine neue Textsuchevorlage" -#: sql_help.c:4732 +#: sql_help.c:5179 msgid "define a new transform" msgstr "definiert eine neue Transformation" -#: sql_help.c:4737 +#: sql_help.c:5184 msgid "define a new trigger" msgstr "definiert einen neuen Trigger" -#: sql_help.c:4742 +#: sql_help.c:5189 msgid "define a new data type" msgstr "definiert einen neuen Datentyp" -#: sql_help.c:4752 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" msgstr "definiert eine neue Abbildung eines Benutzers auf einen Fremdserver" -#: sql_help.c:4757 +#: sql_help.c:5204 msgid "define a new view" msgstr "definiert eine neue Sicht" -#: sql_help.c:4762 +#: sql_help.c:5209 msgid "deallocate a prepared statement" msgstr "gibt einen vorbereiteten Befehl frei" -#: sql_help.c:4767 +#: sql_help.c:5214 msgid "define a cursor" msgstr "definiert einen Cursor" -#: sql_help.c:4772 +#: sql_help.c:5219 msgid "delete rows of a table" msgstr "löscht Zeilen einer Tabelle" -#: sql_help.c:4777 +#: sql_help.c:5224 msgid "discard session state" msgstr "verwirft den Sitzungszustand" -#: sql_help.c:4782 +#: sql_help.c:5229 msgid "execute an anonymous code block" msgstr "führt einen anonymen Codeblock aus" -#: sql_help.c:4787 +#: sql_help.c:5234 msgid "remove an access method" msgstr "entfernt eine Zugriffsmethode" -#: sql_help.c:4792 +#: sql_help.c:5239 msgid "remove an aggregate function" msgstr "entfernt eine Aggregatfunktion" -#: sql_help.c:4797 +#: sql_help.c:5244 msgid "remove a cast" msgstr "entfernt eine Typumwandlung" -#: sql_help.c:4802 +#: sql_help.c:5249 msgid "remove a collation" msgstr "entfernt eine Sortierfolge" -#: sql_help.c:4807 +#: sql_help.c:5254 msgid "remove a conversion" msgstr "entfernt eine Zeichensatzkonversion" -#: sql_help.c:4812 +#: sql_help.c:5259 msgid "remove a database" msgstr "entfernt eine Datenbank" -#: sql_help.c:4817 +#: sql_help.c:5264 msgid "remove a domain" msgstr "entfernt eine Domäne" -#: sql_help.c:4822 +#: sql_help.c:5269 msgid "remove an event trigger" msgstr "entfernt einen Ereignistrigger" -#: sql_help.c:4827 +#: sql_help.c:5274 msgid "remove an extension" msgstr "entfernt eine Erweiterung" -#: sql_help.c:4832 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" msgstr "entfernt einen Fremddaten-Wrapper" -#: sql_help.c:4837 +#: sql_help.c:5284 msgid "remove a foreign table" msgstr "entfernt eine Fremdtabelle" -#: sql_help.c:4842 +#: sql_help.c:5289 msgid "remove a function" msgstr "entfernt eine Funktion" -#: sql_help.c:4847 sql_help.c:4897 sql_help.c:4972 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" msgstr "entfernt eine Datenbankrolle" -#: sql_help.c:4852 +#: sql_help.c:5299 msgid "remove an index" msgstr "entfernt einen Index" -#: sql_help.c:4857 +#: sql_help.c:5304 msgid "remove a procedural language" msgstr "entfernt eine prozedurale Sprache" -#: sql_help.c:4862 +#: sql_help.c:5309 msgid "remove a materialized view" msgstr "entfernt eine materialisierte Sicht" -#: sql_help.c:4867 +#: sql_help.c:5314 msgid "remove an operator" msgstr "entfernt einen Operator" -#: sql_help.c:4872 +#: sql_help.c:5319 msgid "remove an operator class" msgstr "entfernt eine Operatorklasse" -#: sql_help.c:4877 +#: sql_help.c:5324 msgid "remove an operator family" msgstr "entfernt eine Operatorfamilie" -#: sql_help.c:4882 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" msgstr "entfernt die einer Datenbankrolle gehörenden Datenbankobjekte" -#: sql_help.c:4887 +#: sql_help.c:5334 msgid "remove a row level security policy from a table" msgstr "entfernt eine Policy für Sicherheit auf Zeilenebene von einer Tabelle" -#: sql_help.c:4892 +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "entfernt eine Prozedur" + +#: sql_help.c:5344 msgid "remove a publication" msgstr "entfernt eine Publikation" -#: sql_help.c:4902 +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "entfernt eine Routine" + +#: sql_help.c:5359 msgid "remove a rewrite rule" msgstr "entfernt eine Umschreiberegel" -#: sql_help.c:4907 +#: sql_help.c:5364 msgid "remove a schema" msgstr "entfernt ein Schema" -#: sql_help.c:4912 +#: sql_help.c:5369 msgid "remove a sequence" msgstr "entfernt eine Sequenz" -#: sql_help.c:4917 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" msgstr "entfernt einen Fremdserverdeskriptor" -#: sql_help.c:4922 +#: sql_help.c:5379 +msgid "remove extended statistics" +msgstr "entfernt erweiterte Statistiken" + +#: sql_help.c:5384 msgid "remove a subscription" msgstr "entfernt eine Subskription" -#: sql_help.c:4927 +#: sql_help.c:5389 msgid "remove a table" msgstr "entfernt eine Tabelle" -#: sql_help.c:4932 +#: sql_help.c:5394 msgid "remove a tablespace" msgstr "entfernt einen Tablespace" -#: sql_help.c:4937 +#: sql_help.c:5399 msgid "remove a text search configuration" msgstr "entfernt eine Textsuchekonfiguration" -#: sql_help.c:4942 +#: sql_help.c:5404 msgid "remove a text search dictionary" msgstr "entfernt ein Textsuchewörterbuch" -#: sql_help.c:4947 +#: sql_help.c:5409 msgid "remove a text search parser" msgstr "entfernt einen Textsucheparser" -#: sql_help.c:4952 +#: sql_help.c:5414 msgid "remove a text search template" msgstr "entfernt eine Textsuchevorlage" -#: sql_help.c:4957 +#: sql_help.c:5419 msgid "remove a transform" msgstr "entfernt eine Transformation" -#: sql_help.c:4962 +#: sql_help.c:5424 msgid "remove a trigger" msgstr "entfernt einen Trigger" -#: sql_help.c:4967 +#: sql_help.c:5429 msgid "remove a data type" msgstr "entfernt einen Datentyp" -#: sql_help.c:4977 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" msgstr "entfernt eine Benutzerabbildung für einen Fremdserver" -#: sql_help.c:4982 +#: sql_help.c:5444 msgid "remove a view" msgstr "entfernt eine Sicht" -#: sql_help.c:4992 +#: sql_help.c:5454 msgid "execute a prepared statement" msgstr "führt einen vorbereiteten Befehl aus" -#: sql_help.c:4997 +#: sql_help.c:5459 msgid "show the execution plan of a statement" msgstr "zeigt den Ausführungsplan eines Befehls" -#: sql_help.c:5002 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" msgstr "liest Zeilen aus einer Anfrage mit einem Cursor" -#: sql_help.c:5007 +#: sql_help.c:5469 msgid "define access privileges" msgstr "definiert Zugriffsprivilegien" -#: sql_help.c:5012 +#: sql_help.c:5474 msgid "import table definitions from a foreign server" msgstr "importiert Tabellendefinitionen von einem Fremdserver" -#: sql_help.c:5017 +#: sql_help.c:5479 msgid "create new rows in a table" msgstr "erzeugt neue Zeilen in einer Tabelle" -#: sql_help.c:5022 +#: sql_help.c:5484 msgid "listen for a notification" msgstr "hört auf eine Benachrichtigung" -#: sql_help.c:5027 +#: sql_help.c:5489 msgid "load a shared library file" msgstr "lädt eine dynamische Bibliotheksdatei" -#: sql_help.c:5032 +#: sql_help.c:5494 msgid "lock a table" msgstr "sperrt eine Tabelle" -#: sql_help.c:5037 +#: sql_help.c:5499 msgid "position a cursor" msgstr "positioniert einen Cursor" -#: sql_help.c:5042 +#: sql_help.c:5504 msgid "generate a notification" msgstr "erzeugt eine Benachrichtigung" -#: sql_help.c:5047 +#: sql_help.c:5509 msgid "prepare a statement for execution" msgstr "bereitet einen Befehl zur Ausführung vor" -#: sql_help.c:5052 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" msgstr "bereitet die aktuelle Transaktion für Two-Phase-Commit vor" -#: sql_help.c:5057 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" msgstr "ändert den Eigentümer der der Rolle gehörenden Datenbankobjekte" -#: sql_help.c:5062 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" msgstr "ersetzt den Inhalt einer materialisierten Sicht" -#: sql_help.c:5067 +#: sql_help.c:5529 msgid "rebuild indexes" msgstr "baut Indexe neu" -#: sql_help.c:5072 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" msgstr "gibt einen zuvor definierten Sicherungspunkt frei" -#: sql_help.c:5077 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" msgstr "setzt einen Konfigurationsparameter auf die Voreinstellung zurück" -#: sql_help.c:5082 +#: sql_help.c:5544 msgid "remove access privileges" msgstr "entfernt Zugriffsprivilegien" -#: sql_help.c:5092 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "storniert eine Transaktion, die vorher für Two-Phase-Commit vorbereitet worden war" -#: sql_help.c:5097 +#: sql_help.c:5559 msgid "roll back to a savepoint" msgstr "rollt eine Transaktion bis zu einem Sicherungspunkt zurück" -#: sql_help.c:5102 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" msgstr "definiert einen neuen Sicherungspunkt in der aktuellen Transaktion" -#: sql_help.c:5107 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" msgstr "definiert oder ändert ein Security-Label eines Objektes" -#: sql_help.c:5112 sql_help.c:5157 sql_help.c:5187 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" msgstr "liest Zeilen aus einer Tabelle oder Sicht" -#: sql_help.c:5122 +#: sql_help.c:5584 msgid "change a run-time parameter" msgstr "ändert einen Konfigurationsparameter" -#: sql_help.c:5127 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" msgstr "setzt die Zeitsteuerung für Check-Constraints in der aktuellen Transaktion" -#: sql_help.c:5132 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" msgstr "setzt den aktuellen Benutzernamen der aktuellen Sitzung" -#: sql_help.c:5137 +#: sql_help.c:5599 msgid "set the session user identifier and the current user identifier of the current session" msgstr "setzt den Sitzungsbenutzernamen und den aktuellen Benutzernamen der aktuellen Sitzung" -#: sql_help.c:5142 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" msgstr "setzt die Charakteristika der aktuellen Transaktion" -#: sql_help.c:5147 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" msgstr "zeigt den Wert eines Konfigurationsparameters" -#: sql_help.c:5162 +#: sql_help.c:5624 msgid "empty a table or set of tables" msgstr "leert eine oder mehrere Tabellen" -#: sql_help.c:5167 +#: sql_help.c:5629 msgid "stop listening for a notification" msgstr "beendet das Hören auf eine Benachrichtigung" -#: sql_help.c:5172 +#: sql_help.c:5634 msgid "update rows of a table" msgstr "aktualisiert Zeilen einer Tabelle" -#: sql_help.c:5177 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" msgstr "säubert und analysiert eine Datenbank" -#: sql_help.c:5182 +#: sql_help.c:5644 msgid "compute a set of rows" msgstr "berechnet eine Zeilenmenge" -#: startup.c:184 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s: -1 kann nur im nicht interaktiven Modus verwendet werden\n" -#: startup.c:287 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: konnte Logdatei »%s« nicht öffnen: %s\n" -#: startup.c:387 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5473,27 +6041,27 @@ msgstr "" "Geben Sie »help« für Hilfe ein.\n" "\n" -#: startup.c:536 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s: konnte Ausgabeparameter »%s« nicht setzen\n" -#: startup.c:638 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: startup.c:655 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" msgstr "%s: Warnung: überflüssiges Kommandozeilenargument »%s« ignoriert\n" -#: startup.c:704 +#: startup.c:729 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: konnte eigene Programmdatei nicht finden\n" -#: tab-complete.c:4029 +#: tab-complete.c:4482 #, c-format msgid "" "tab completion query failed: %s\n" @@ -5505,36 +6073,25 @@ msgstr "" "%s\n" #: variables.c:139 -#, fuzzy, c-format -#| msgid "unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n" -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" -msgstr "unbekannter Wert »%s« für »%s«; »%s« wird angenommen\n" +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "unbekannter Wert »%s« für »%s«: Boole'scher Wert erwartet\n" #: variables.c:176 -#, fuzzy, c-format -#| msgid "invalid value \"%s\" for \"%s\"" +#, c-format msgid "invalid value \"%s\" for \"%s\": integer expected\n" -msgstr "ungültiger Wert »%s« für »%s«" +msgstr "ungültiger Wert »%s« für »%s«: ganze Zahl erwartet\n" #: variables.c:224 -#, fuzzy, c-format -#| msgid "invalid locale name: \"%s\"" +#, c-format msgid "invalid variable name: \"%s\"\n" -msgstr "ungültiger Locale-Name: »%s«" +msgstr "ungültiger Variablenname: »%s«\n" #: variables.c:393 -#, fuzzy, c-format -#| msgid "unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n" +#, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" "Available values are: %s.\n" -msgstr "unbekannter Wert »%s« für »%s«; »%s« wird angenommen\n" - -#~ msgid "%s: could not set variable \"%s\"\n" -#~ msgstr "%s: konnte Variable »%s« nicht setzen\n" - -#~ msgid "could not set variable \"%s\"\n" -#~ msgstr "konnte Variable »%s« nicht setzen\n" - -#~ msgid "\\%s: error while setting variable\n" -#~ msgstr "\\%s: Fehler beim Setzen der Variable\n" +msgstr "" +"unbekannter Wert »%s« für »%s«\n" +"Verfügbare Werte sind: %s.\n" diff --git a/src/bin/psql/po/es.po b/src/bin/psql/po/es.po index 0765be4d6d6..29ed806c7ec 100644 --- a/src/bin/psql/po/es.po +++ b/src/bin/psql/po/es.po @@ -1,6 +1,6 @@ # spanish translation of psql. # -# Copyright (C) 2003-2013 PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Alvaro Herrera, , 2003-2015 @@ -9,56 +9,76 @@ # msgid "" msgstr "" -"Project-Id-Version: psql (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:15+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: psql (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:13+0000\n" +"PO-Revision-Date: 2019-06-06 17:26-0400\n" "Last-Translator: Ãlvaro Herrera \n" -"Language-Team: PgSQL Español \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 #, c-format -msgid "could not identify current directory: %s" -msgstr "no se pudo identificar el directorio actual: %s" +msgid "fatal: " +msgstr "fatal:" -#: ../../common/exec.c:146 +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "no se pudo identificar el directorio actual: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "el binario «%s» no es válido" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "no se pudo leer el binario «%s»" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "no se pudo encontrar un «%s» para ejecutar" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "no se pudo cambiar al directorio «%s»: %m" + +#: ../../common/exec.c:288 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "no se pudo cambiar al directorio «%s»: %s" +msgid "could not read symbolic link \"%s\": %m" +msgstr "no se pudo leer el enlace simbólico «%s»: %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:541 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "no se pudo leer el enlace simbólico «%s»" +msgid "pclose failed: %m" +msgstr "pclose falló: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: command.c:1218 input.c:228 mainloop.c:82 mainloop.c:386 #, c-format -msgid "pclose failed: %s" -msgstr "pclose falló: %s" +msgid "out of memory" +msgstr "memoria agotada" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:608 input.c:227 mainloop.c:82 -#: mainloop.c:276 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "memoria agotada\n" @@ -97,22 +117,17 @@ msgstr "orden no encontrada" msgid "child process exited with exit code %d" msgstr "el proceso hijo terminó con código de salida %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "el proceso hijo fue terminado por una excepción 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "el proceso hijo fue terminado por una señal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "el proceso hijo fue terminado por una señal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "el proceso hijo fue terminado por una señal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "el proceso hijo terminó con código no reconocido %d" @@ -124,271 +139,285 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu fila)" msgstr[1] "(%lu filas)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "Interrumpido\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "No se puede agregar un encabezado al contenido de la tabla: la cantidad de columnas de %d ha sido excedida.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "No se puede agregar una celda al contenido de la tabla: la cantidad de celdas de %d ha sido excedida.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "formato de salida no válido (error interno): %d" -#: ../../fe_utils/psqlscan.l:713 +#: ../../fe_utils/psqlscan.l:729 #, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" -msgstr "saltando expansión recursiva de la variable «%s»\n" +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "saltando expansión recursiva de la variable «%s»" -#: command.c:223 +#: command.c:221 #, c-format -msgid "Invalid command \\%s. Try \\? for help.\n" -msgstr "Orden \\%s no válida. Use \\? para obtener ayuda.\n" +msgid "invalid command \\%s" +msgstr "orden \\%s no válida" -#: command.c:225 +#: command.c:223 #, c-format -msgid "invalid command \\%s\n" -msgstr "orden \\%s no válida\n" +msgid "Try \\? for help." +msgstr "Digite \\? para obtener ayuda." -#: command.c:243 +#: command.c:241 #, c-format -msgid "\\%s: extra argument \"%s\" ignored\n" -msgstr "\\%s: argumento extra «%s» ignorado\n" +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: argumento extra «%s» ignorado" -#: command.c:295 +#: command.c:293 #, c-format -msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" -msgstr "" +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "orden \\%s ignorada: use \\endif o Ctrl-C para salir del bloque \\if actual" #: command.c:553 #, c-format -msgid "could not get home directory for user ID %ld: %s\n" -msgstr "no se pudo obtener directorio home para el usuario de ID %ld: %s\n" +msgid "could not get home directory for user ID %ld: %s" +msgstr "no se pudo obtener directorio home para el usuario de ID %ld: %s" #: command.c:571 #, c-format -msgid "\\%s: could not change directory to \"%s\": %s\n" -msgstr "\\%s: no se pudo cambiar directorio a «%s»: %s\n" +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: no se pudo cambiar directorio a «%s»: %m" -#: command.c:596 common.c:648 common.c:706 common.c:1242 +#: command.c:596 #, c-format msgid "You are currently not connected to a database.\n" msgstr "No está conectado a una base de datos.\n" -#: command.c:621 +#: command.c:609 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en la dirección «%s» port «%s».\n" + +#: command.c:612 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Está conectado a la base de datos «%s» como el usuario «%s» a través del socket en «%s» port «%s».\n" -#: command.c:624 +#: command.c:618 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» (dirección «%s») port «%s».\n" + +#: command.c:621 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» port «%s».\n" -#: command.c:912 command.c:1002 command.c:1111 command.c:2520 +#: command.c:930 command.c:1026 command.c:2411 +#, c-format +msgid "no query buffer" +msgstr "no hay búfer de consulta" + +#: command.c:963 command.c:4801 #, c-format -msgid "no query buffer\n" -msgstr "no hay búfer de consulta\n" +msgid "invalid line number: %s" +msgstr "número de línea no válido: %s" -#: command.c:945 command.c:4757 +#: command.c:1017 #, c-format -msgid "invalid line number: %s\n" -msgstr "número de línea no válido: %s\n" +msgid "The server (version %s) does not support editing function source." +msgstr "El servidor (versión %s) no soporta la edición del código fuente de funciones." -#: command.c:995 +#: command.c:1020 #, c-format -msgid "The server (version %s) does not support editing function source.\n" -msgstr "El servidor (versión %s) no soporta la edición del código fuente de funciones.\n" +msgid "The server (version %s) does not support editing view definitions." +msgstr "El servidor (versión %s) no soporta la edición de vistas." -#: command.c:1070 command.c:1151 +#: command.c:1102 msgid "No changes" msgstr "Sin cambios" -#: command.c:1104 -#, c-format -msgid "The server (version %s) does not support editing view definitions.\n" -msgstr "El servidor (versión %s) no soporta la edición de vistas.\n" - -#: command.c:1228 +#: command.c:1179 #, c-format -msgid "%s: invalid encoding name or conversion procedure not found\n" -msgstr "" -"%s: nombre de codificación no válido o procedimiento de conversión\n" -"no encontrado\n" +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: nombre de codificación no válido o procedimiento de conversión no encontrado" -#: command.c:1263 command.c:1885 command.c:3161 command.c:4859 common.c:173 -#: common.c:244 common.c:541 common.c:1288 common.c:1316 common.c:1417 -#: copy.c:489 copy.c:708 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1214 command.c:1853 command.c:3089 command.c:4903 common.c:175 +#: common.c:224 common.c:521 common.c:1362 common.c:1390 common.c:1498 +#: common.c:1601 common.c:1639 copy.c:490 copy.c:709 help.c:63 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 #, c-format msgid "%s" msgstr "%s" -#: command.c:1267 -msgid "out of memory" -msgstr "memoria agotada" - -#: command.c:1270 +#: command.c:1221 msgid "There is no previous error." msgstr "No hay error anterior." -#: command.c:1441 command.c:1746 command.c:1760 command.c:1777 command.c:1937 -#: command.c:2174 command.c:2487 command.c:2527 +#: command.c:1409 command.c:1714 command.c:1728 command.c:1745 command.c:1905 +#: command.c:2142 command.c:2378 command.c:2418 #, c-format -msgid "\\%s: missing required argument\n" -msgstr "\\%s: falta argumento requerido\n" +msgid "\\%s: missing required argument" +msgstr "\\%s: falta argumento requerido" -#: command.c:1572 +#: command.c:1540 #, c-format -msgid "\\elif: cannot occur after \\else\n" -msgstr "" +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: no puede ocurrir después de \\else" -#: command.c:1577 +#: command.c:1545 #, c-format -msgid "\\elif: no matching \\if\n" -msgstr "" +msgid "\\elif: no matching \\if" +msgstr "\\elif: no hay un \\if coincidente" -#: command.c:1641 +#: command.c:1609 #, c-format -msgid "\\else: cannot occur after \\else\n" -msgstr "" +msgid "\\else: cannot occur after \\else" +msgstr "\\else: no puede ocurrir después de \\else" -#: command.c:1646 +#: command.c:1614 #, c-format -msgid "\\else: no matching \\if\n" -msgstr "" +msgid "\\else: no matching \\if" +msgstr "\\else: no hay un \\if coincidente" -#: command.c:1686 +#: command.c:1654 #, c-format -msgid "\\endif: no matching \\if\n" -msgstr "" +msgid "\\endif: no matching \\if" +msgstr "\\endif: no hay un \\if coincidente" -#: command.c:1841 +#: command.c:1809 msgid "Query buffer is empty." msgstr "El búfer de consulta está vacío." -#: command.c:1863 +#: command.c:1831 msgid "Enter new password: " msgstr "Ingrese la nueva contraseña: " -#: command.c:1864 +#: command.c:1832 msgid "Enter it again: " msgstr "Ingrésela nuevamente: " -#: command.c:1868 +#: command.c:1836 #, c-format -msgid "Passwords didn't match.\n" -msgstr "Las constraseñas no coinciden.\n" +msgid "Passwords didn't match." +msgstr "Las constraseñas no coinciden." -#: command.c:1967 -#, fuzzy, c-format -msgid "\\%s: could not read value for variable\n" -msgstr "%s: no se pudo eliminar la variable «%s»\n" +#: command.c:1935 +#, c-format +msgid "\\%s: could not read value for variable" +msgstr "%s: no se pudo leer el valor para la variable" -#: command.c:2070 +#: command.c:2038 msgid "Query buffer reset (cleared)." msgstr "El búfer de consulta ha sido reiniciado (limpiado)." -#: command.c:2092 +#: command.c:2060 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Se escribió la historia en el archivo «%s».\n" -#: command.c:2179 +#: command.c:2147 #, c-format -msgid "\\%s: environment variable name must not contain \"=\"\n" -msgstr "\\%s: el nombre de variable de ambiente no debe contener «=»\n" +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: el nombre de variable de ambiente no debe contener «=»" -#: command.c:2235 +#: command.c:2208 #, c-format -msgid "The server (version %s) does not support showing function source.\n" -msgstr "El servidor (versión %s) no soporta el despliegue del código fuente de funciones.\n" +msgid "The server (version %s) does not support showing function source." +msgstr "El servidor (versión %s) no soporta el despliegue del código fuente de funciones." -#: command.c:2242 +#: command.c:2211 #, c-format -msgid "function name is required\n" -msgstr "el nombre de la función es requerido\n" +msgid "The server (version %s) does not support showing view definitions." +msgstr "El servidor (versión %s) no soporta el despliegue de definiciones de vistas." -#: command.c:2329 +#: command.c:2218 #, c-format -msgid "The server (version %s) does not support showing view definitions.\n" -msgstr "El servidor (versión %s) no soporta el despliegue de definiciones de vistas.\n" +msgid "function name is required" +msgstr "el nombre de la función es requerido" -#: command.c:2336 +#: command.c:2220 #, c-format -msgid "view name is required\n" -msgstr "el nombre de la vista es requerido\n" +msgid "view name is required" +msgstr "el nombre de la vista es requerido" -#: command.c:2459 +#: command.c:2350 msgid "Timing is on." msgstr "El despliegue de duración está activado." -#: command.c:2461 +#: command.c:2352 msgid "Timing is off." msgstr "El despliegue de duración está desactivado." -#: command.c:2546 command.c:2574 command.c:3510 command.c:3513 command.c:3516 -#: command.c:3522 command.c:3524 command.c:3532 command.c:3542 command.c:3551 -#: command.c:3565 command.c:3582 command.c:3640 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:760 psqlscanslash.l:771 -#: psqlscanslash.l:781 +#: command.c:2437 command.c:2465 command.c:3485 command.c:3488 command.c:3491 +#: command.c:3497 command.c:3499 command.c:3507 command.c:3517 command.c:3526 +#: command.c:3540 command.c:3557 command.c:3615 common.c:71 copy.c:333 +#: copy.c:405 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 #, c-format -msgid "%s: %s\n" -msgstr "%s: %s\n" +msgid "%s: %m" +msgstr "%s: %m" -#: command.c:2953 startup.c:202 +#: command.c:2849 startup.c:240 startup.c:291 msgid "Password: " msgstr "Contraseña: " -#: command.c:2958 startup.c:204 +#: command.c:2854 startup.c:288 #, c-format msgid "Password for user %s: " msgstr "Contraseña para usuario %s: " -#: command.c:3008 +#: command.c:2905 #, c-format -msgid "All connection parameters must be supplied because no database connection exists\n" -msgstr "Debe proveer todos los parámetros de conexión porque no existe conexión a una base de datos\n" +msgid "All connection parameters must be supplied because no database connection exists" +msgstr "Debe proveer todos los parámetros de conexión porque no existe conexión a una base de datos" -#: command.c:3165 +#: command.c:3093 #, c-format -msgid "Previous connection kept\n" -msgstr "Se ha mantenido la conexión anterior\n" +msgid "Previous connection kept" +msgstr "Se ha mantenido la conexión anterior" -#: command.c:3169 +#: command.c:3097 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:3205 +#: command.c:3136 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en la dirección «%s» port «%s».\n" + +#: command.c:3139 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» a través del socket en «%s» port «%s».\n" -#: command.c:3208 +#: command.c:3145 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» (dirección «%s») port «%s».\n" + +#: command.c:3148 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Ahora está conectado a la base de datos «%s» como el usuario «%s» en el servidor «%s» port «%s».\n" -#: command.c:3212 +#: command.c:3153 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Ahora está conectado a la base de datos «%s» con el usuario «%s».\n" -#: command.c:3245 +#: command.c:3186 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, servidor %s)\n" -#: command.c:3253 +#: command.c:3194 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -397,24 +426,29 @@ msgstr "" "ADVERTENCIA: %s versión mayor %s, servidor versión mayor %s.\n" " Algunas características de psql podrían no funcionar.\n" -#: command.c:3290 +#: command.c:3232 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "conexión SSL (protocolo: %s, cifrado: %s, bits: %s, compresión: %s)\n" -#: command.c:3291 command.c:3292 command.c:3293 +#: command.c:3233 command.c:3234 command.c:3235 msgid "unknown" msgstr "desconocido" -#: command.c:3294 help.c:45 +#: command.c:3236 help.c:46 msgid "off" msgstr "desactivado" -#: command.c:3294 help.c:45 +#: command.c:3236 help.c:46 msgid "on" msgstr "activado" -#: command.c:3314 +#: command.c:3250 +#, c-format +msgid "GSSAPI Encrypted connection\n" +msgstr "Conexión Cifrada GSSAPI\n" + +#: command.c:3270 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -427,239 +461,259 @@ msgstr "" " Vea la página de referencia de psql «Notes for Windows users»\n" " para obtener más detalles.\n" -#: command.c:3399 +#: command.c:3374 #, c-format -msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" -msgstr "la variable de ambiente PSQL_EDITOR_LINENUMBER_SWITCH debe estar definida para poder especificar un número de línea\n" +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "la variable de ambiente PSQL_EDITOR_LINENUMBER_SWITCH debe estar definida para poder especificar un número de línea" -#: command.c:3428 +#: command.c:3403 #, c-format -msgid "could not start editor \"%s\"\n" -msgstr "no se pudo iniciar el editor «%s»\n" +msgid "could not start editor \"%s\"" +msgstr "no se pudo iniciar el editor «%s»" -#: command.c:3430 +#: command.c:3405 #, c-format -msgid "could not start /bin/sh\n" -msgstr "no se pudo iniciar /bin/sh\n" +msgid "could not start /bin/sh" +msgstr "no se pudo iniciar /bin/sh" -#: command.c:3468 +#: command.c:3443 #, c-format -msgid "could not locate temporary directory: %s\n" -msgstr "no se pudo ubicar el directorio temporal: %s\n" +msgid "could not locate temporary directory: %s" +msgstr "no se pudo ubicar el directorio temporal: %s" -#: command.c:3495 +#: command.c:3470 #, c-format -msgid "could not open temporary file \"%s\": %s\n" -msgstr "no se pudo abrir archivo temporal «%s»: %s\n" +msgid "could not open temporary file \"%s\": %m" +msgstr "no se pudo abrir archivo temporal «%s»: %m" -#: command.c:3769 +#: command.c:3763 #, c-format -msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" -msgstr "\\pset: formatos permitidos son unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: abreviación ambigua «%s» coincide tanto con «%s» como con «%s»" -#: command.c:3787 +#: command.c:3783 #, c-format -msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" -msgstr "\\pset: estilos de línea permitidos son ascii, old-ascii, unicode\n" +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: formatos permitidos son aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" #: command.c:3802 #, c-format -msgid "\\pset: allowed Unicode border line styles are single, double\n" -msgstr "\\pset: estilos de línea Unicode de borde permitidos son single, double\n" +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: estilos de línea permitidos son ascii, old-ascii, unicode" #: command.c:3817 #, c-format -msgid "\\pset: allowed Unicode column line styles are single, double\n" -msgstr "\\pset: estilos de línea Unicode de columna permitidos son single, double\n" +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de borde permitidos son single, double" #: command.c:3832 #, c-format -msgid "\\pset: allowed Unicode header line styles are single, double\n" -msgstr "\\pset: estilos de línea Unicode de encabezado permitidos son single, double\n" +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de columna permitidos son single, double" + +#: command.c:3847 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: estilos de línea Unicode de encabezado permitidos son single, double" + +#: command.c:3890 +#, c-format +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep debe ser un carácter de un solo byte" + +#: command.c:3895 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldset ni puede ser una comilla doble, un salto de línea, o un retorno de carro" -#: command.c:3997 command.c:4176 +#: command.c:4032 command.c:4218 #, c-format -msgid "\\pset: unknown option: %s\n" -msgstr "\\pset: opción desconocida: %s\n" +msgid "\\pset: unknown option: %s" +msgstr "\\pset: opción desconocida: %s" -#: command.c:4015 +#: command.c:4050 #, c-format msgid "Border style is %d.\n" msgstr "El estilo de borde es %d.\n" -#: command.c:4021 +#: command.c:4056 #, c-format msgid "Target width is unset.\n" msgstr "El ancho no está definido.\n" -#: command.c:4023 +#: command.c:4058 #, c-format msgid "Target width is %d.\n" msgstr "El ancho es %d.\n" -#: command.c:4030 +#: command.c:4065 #, c-format msgid "Expanded display is on.\n" msgstr "Se ha activado el despliegue expandido.\n" -#: command.c:4032 +#: command.c:4067 #, c-format msgid "Expanded display is used automatically.\n" msgstr "El despliegue expandido se usa automáticamente.\n" -#: command.c:4034 +#: command.c:4069 #, c-format msgid "Expanded display is off.\n" msgstr "Se ha desactivado el despliegue expandido.\n" -#: command.c:4041 command.c:4049 +#: command.c:4075 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "El separador de campos para CSV es «%s».\n" + +#: command.c:4083 command.c:4091 #, c-format msgid "Field separator is zero byte.\n" msgstr "El separador de campos es el byte cero.\n" -#: command.c:4043 +#: command.c:4085 #, c-format msgid "Field separator is \"%s\".\n" msgstr "El separador de campos es «%s».\n" -#: command.c:4056 +#: command.c:4098 #, c-format msgid "Default footer is on.\n" msgstr "El pie por omisión está activo.\n" -#: command.c:4058 +#: command.c:4100 #, c-format msgid "Default footer is off.\n" msgstr "El pie de página por omisión está desactivado.\n" -#: command.c:4064 +#: command.c:4106 #, c-format msgid "Output format is %s.\n" msgstr "El formato de salida es %s.\n" -#: command.c:4070 +#: command.c:4112 #, c-format msgid "Line style is %s.\n" msgstr "El estilo de línea es %s.\n" -#: command.c:4077 +#: command.c:4119 #, c-format msgid "Null display is \"%s\".\n" msgstr "Despliegue de nulos es «%s».\n" -#: command.c:4085 +#: command.c:4127 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "La salida numérica ajustada localmente está habilitada.\n" -#: command.c:4087 +#: command.c:4129 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "La salida numérica ajustada localmente está deshabilitada.\n" -#: command.c:4094 +#: command.c:4136 #, c-format msgid "Pager is used for long output.\n" msgstr "El paginador se usará para salida larga.\n" -#: command.c:4096 +#: command.c:4138 #, c-format msgid "Pager is always used.\n" msgstr "El paginador se usará siempre.\n" -#: command.c:4098 +#: command.c:4140 #, c-format msgid "Pager usage is off.\n" msgstr "El paginador no se usará.\n" -#: command.c:4104 +#: command.c:4146 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "El paginador no se usará para menos de %d línea.\n" msgstr[1] "El paginador no se usará para menos de %d líneas.\n" -#: command.c:4114 command.c:4124 +#: command.c:4156 command.c:4166 #, c-format msgid "Record separator is zero byte.\n" msgstr "El separador de filas es el byte cero.\n" -#: command.c:4116 +#: command.c:4158 #, c-format msgid "Record separator is .\n" msgstr "El separador de filas es .\n" -#: command.c:4118 +#: command.c:4160 #, c-format msgid "Record separator is \"%s\".\n" msgstr "El separador de filas es «%s».\n" -#: command.c:4131 +#: command.c:4173 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Los atributos de tabla son «%s».\n" -#: command.c:4134 +#: command.c:4176 #, c-format msgid "Table attributes unset.\n" msgstr "Los atributos de tabla han sido indefinidos.\n" -#: command.c:4141 +#: command.c:4183 #, c-format msgid "Title is \"%s\".\n" msgstr "El título es «%s».\n" -#: command.c:4143 +#: command.c:4185 #, c-format msgid "Title is unset.\n" msgstr "El título ha sido indefinido.\n" -#: command.c:4150 +#: command.c:4192 #, c-format msgid "Tuples only is on.\n" msgstr "Mostrar sólo filas está activado.\n" -#: command.c:4152 +#: command.c:4194 #, c-format msgid "Tuples only is off.\n" msgstr "Mostrar sólo filas está desactivado.\n" -#: command.c:4158 +#: command.c:4200 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "El estilo Unicode de borde es «%s».\n" -#: command.c:4164 +#: command.c:4206 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "El estilo de línea Unicode de columna es «%s».\n" -#: command.c:4170 +#: command.c:4212 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "El estilo de línea Unicode de encabezado es «%s».\n" -#: command.c:4330 +#: command.c:4374 #, c-format -msgid "\\!: failed\n" -msgstr "\\!: falló\n" +msgid "\\!: failed" +msgstr "\\!: falló" -#: command.c:4355 common.c:754 +#: command.c:4399 common.c:781 #, c-format -msgid "\\watch cannot be used with an empty query\n" -msgstr "\\watch no puede ser usado con una consulta vacía\n" +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch no puede ser usado con una consulta vacía" -#: command.c:4396 +#: command.c:4440 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (cada %gs)\n" -#: command.c:4399 +#: command.c:4443 #, c-format msgid "%s (every %gs)\n" msgstr "%s (cada %gs)\n" -#: command.c:4453 command.c:4460 common.c:654 common.c:661 common.c:1271 +#: command.c:4497 command.c:4504 common.c:681 common.c:688 common.c:1345 #, c-format msgid "" "********* QUERY **********\n" @@ -672,102 +726,107 @@ msgstr "" "**************************\n" "\n" -#: command.c:4652 +#: command.c:4696 #, c-format -msgid "\"%s.%s\" is not a view\n" -msgstr "«%s.%s» no es una vista\n" +msgid "\"%s.%s\" is not a view" +msgstr "«%s.%s» no es una vista" -#: command.c:4668 +#: command.c:4712 #, c-format -msgid "could not parse reloptions array\n" -msgstr "no se pudo interpretar el array reloptions\n" +msgid "could not parse reloptions array" +msgstr "no se pudo interpretar el array reloptions" -#: common.c:158 +#: common.c:160 #, c-format -msgid "cannot escape without active connection\n" -msgstr "no se puede escapar sin una conexión activa\n" +msgid "cannot escape without active connection" +msgstr "no se puede escapar sin una conexión activa" -#: common.c:199 +#: common.c:201 #, c-format -msgid "shell command argument contains a newline or carriage return: \"%s\"\n" -msgstr "" +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "el argumento de la orden de shell contiene un salto de línea o retorno de carro: «%s»" -#: common.c:415 +#: common.c:395 #, c-format -msgid "connection to server was lost\n" -msgstr "se ha perdido la conexión al servidor\n" +msgid "connection to server was lost" +msgstr "se ha perdido la conexión al servidor" -#: common.c:419 +#: common.c:399 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "La conexión al servidor se ha perdido. Intentando reiniciar: " -#: common.c:424 +#: common.c:404 #, c-format msgid "Failed.\n" msgstr "falló.\n" -#: common.c:431 +#: common.c:411 #, c-format msgid "Succeeded.\n" msgstr "con éxito.\n" -#: common.c:531 common.c:1034 common.c:1206 +#: common.c:511 common.c:1063 common.c:1280 #, c-format -msgid "unexpected PQresultStatus: %d\n" -msgstr "PQresultStatus no esperado: %d\n" +msgid "unexpected PQresultStatus: %d" +msgstr "PQresultStatus no esperado: %d" -#: common.c:593 +#: common.c:620 #, c-format msgid "Time: %.3f ms\n" msgstr "Duración: %.3f ms\n" -#: common.c:608 -#, fuzzy, c-format +#: common.c:635 +#, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" -msgstr "Duración: %.3f ms\n" +msgstr "Duración: %.3f ms (%02d:%06.3f)\n" -#: common.c:617 +#: common.c:644 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" -msgstr "" +msgstr "Duración: %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:624 +#: common.c:651 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -msgstr "" +msgstr "Duración: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:761 +#: common.c:675 common.c:733 common.c:1316 #, c-format -msgid "\\watch cannot be used with COPY\n" -msgstr "no se puede usar \\watch con COPY\n" +msgid "You are currently not connected to a database." +msgstr "No está conectado a una base de datos." -#: common.c:766 +#: common.c:788 #, c-format -msgid "unexpected result status for \\watch\n" -msgstr "Estado de resultado inesperado de \\watch\n" +msgid "\\watch cannot be used with COPY" +msgstr "no se puede usar \\watch con COPY" -#: common.c:795 +#: common.c:793 +#, c-format +msgid "unexpected result status for \\watch" +msgstr "Estado de resultado inesperado de \\watch" + +#: common.c:823 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Notificación asíncrona «%s» con carga «%s» recibida del proceso de servidor con PID %d.\n" -#: common.c:798 +#: common.c:826 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Notificación asíncrona «%s» recibida del proceso de servidor con PID %d.\n" -#: common.c:860 +#: common.c:889 #, c-format -msgid "no rows returned for \\gset\n" -msgstr "\\gset no retornó renglón alguno\n" +msgid "no rows returned for \\gset" +msgstr "\\gset no retornó renglón alguno" -#: common.c:865 +#: common.c:894 #, c-format -msgid "more than one row returned for \\gset\n" -msgstr "\\gset retornó más de un renglón\n" +msgid "more than one row returned for \\gset" +msgstr "\\gset retornó más de un renglón" -#: common.c:1251 +#: common.c:1325 #, c-format msgid "" "***(Single step mode: verify command)*******************************************\n" @@ -778,71 +837,92 @@ msgstr "" "%s\n" "***(presione enter para continuar, o x y enter para cancelar)*******************\n" -#: common.c:1306 +#: common.c:1380 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "El servidor (versión %s) no soporta savepoints para ON_ERROR_ROLLBACK." + +#: common.c:1443 #, c-format -msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" -msgstr "El servidor (versión %s) no soporta savepoints para ON_ERROR_ROLLBACK.\n" +msgid "STATEMENT: %s" +msgstr "SENTENCIA: %s" + +#: common.c:1486 +#, c-format +msgid "unexpected transaction status (%d)" +msgstr "estado de transacción inesperado (%d)" + +#: common.c:1623 describe.c:2002 +msgid "Column" +msgstr "Columna" + +#: common.c:1624 describe.c:179 describe.c:394 describe.c:412 describe.c:457 +#: describe.c:474 describe.c:963 describe.c:1127 describe.c:1712 +#: describe.c:1736 describe.c:2003 describe.c:3673 describe.c:3858 +#: describe.c:4091 describe.c:5297 +msgid "Type" +msgstr "Tipo" -#: common.c:1362 +#: common.c:1673 #, c-format -msgid "STATEMENT: %s\n" -msgstr "SENTENCIA: %s\n" +msgid "The command has no result, or the result has no columns.\n" +msgstr "La orden no tiene resultado, o el resultado no tiene columnas.\n" -#: common.c:1405 +#: copy.c:100 #, c-format -msgid "unexpected transaction status (%d)\n" -msgstr "estado de transacción inesperado (%d)\n" +msgid "\\copy: arguments required" +msgstr "\\copy: argumentos requeridos" -#: copy.c:99 +#: copy.c:255 #, c-format -msgid "\\copy: arguments required\n" -msgstr "\\copy: argumentos requeridos\n" +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: error de procesamiento en «%s»" -#: copy.c:254 +#: copy.c:257 #, c-format -msgid "\\copy: parse error at \"%s\"\n" -msgstr "\\copy: error de procesamiento en «%s»\n" +msgid "\\copy: parse error at end of line" +msgstr "\\copy: error de procesamiento al final de la línea" -#: copy.c:256 +#: copy.c:330 #, c-format -msgid "\\copy: parse error at end of line\n" -msgstr "\\copy: error de procesamiento al final de la línea\n" +msgid "could not execute command \"%s\": %m" +msgstr "no se pudo ejecutar la orden «%s»: %m" -#: copy.c:329 +#: copy.c:346 #, c-format -msgid "could not execute command \"%s\": %s\n" -msgstr "no se pudo ejecutar la orden «%s»: %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "no se pudo hacer stat al archivo «%s»: %m" -#: copy.c:345 +#: copy.c:350 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "no se pudo hacer stat del archivo «%s»: %s\n" +msgid "%s: cannot copy from/to a directory" +msgstr "%s: no se puede copiar desde/hacia un directorio" -#: copy.c:349 +#: copy.c:387 #, c-format -msgid "%s: cannot copy from/to a directory\n" -msgstr "%s: no se puede copiar desde/hacia un directorio\n" +msgid "could not close pipe to external command: %m" +msgstr "no se pudo cerrar la tubería a la orden externa: %m" -#: copy.c:386 +#: copy.c:392 #, c-format -msgid "could not close pipe to external command: %s\n" -msgstr "no se pudo cerrar la tubería a una orden externa: %s\n" +msgid "%s: %s" +msgstr "%s: %s" -#: copy.c:452 copy.c:463 +#: copy.c:455 copy.c:465 #, c-format -msgid "could not write COPY data: %s\n" -msgstr "no se pudo escribir datos COPY: %s\n" +msgid "could not write COPY data: %m" +msgstr "no se pudo escribir datos COPY: %m" -#: copy.c:470 +#: copy.c:471 #, c-format msgid "COPY data transfer failed: %s" msgstr "falló la transferencia de datos COPY: %s" -#: copy.c:531 +#: copy.c:532 msgid "canceled by user" msgstr "cancelada por el usuario" -#: copy.c:542 +#: copy.c:543 msgid "" "Enter data to be copied followed by a newline.\n" "End with a backslash and a period on a line by itself, or an EOF signal." @@ -850,1060 +930,1144 @@ msgstr "" "Ingrese los datos a ser copiados seguidos de un fin de línea.\n" "Termine con un backslash y un punto, o una señal EOF." -#: copy.c:670 +#: copy.c:671 msgid "aborted because of read failure" msgstr "se abortó por un error de lectura" -#: copy.c:704 +#: copy.c:705 msgid "trying to exit copy mode" msgstr "tratando de salir del modo copy" -#: crosstabview.c:123 +#: crosstabview.c:124 #, c-format -msgid "\\crosstabview: statement did not return a result set\n" -msgstr "\\crosstabview: la sentencia no produjo un conjunto de resultados\n" +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: la sentencia no produjo un conjunto de resultados" -#: crosstabview.c:129 +#: crosstabview.c:130 #, c-format -msgid "\\crosstabview: query must return at least three columns\n" -msgstr "\\crosstabview: la consulta debe retornar al menos tres columnas\n" +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: la consulta debe retornar al menos tres columnas" -#: crosstabview.c:156 +#: crosstabview.c:157 #, c-format -msgid "\\crosstabview: vertical and horizontal headers must be different columns\n" -msgstr "\\crosstabview: los encabezados verticales y horizontales deben ser columnas distintas\n" +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: los encabezados verticales y horizontales deben ser columnas distintas" -#: crosstabview.c:172 +#: crosstabview.c:173 #, c-format -msgid "\\crosstabview: data column must be specified when query returns more than three columns\n" -msgstr "\\crosstabview: la columna de datos debe ser especificada cuando la consulta retorna más de tres columnas\n" +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: la columna de datos debe ser especificada cuando la consulta retorna más de tres columnas" -#: crosstabview.c:228 +#: crosstabview.c:229 #, c-format -msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" -msgstr "\\crosstabview: se superó el número máximo de columnas (%d)\n" +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: se superó el número máximo de columnas (%d)" -#: crosstabview.c:397 +#: crosstabview.c:398 #, c-format -msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n" -msgstr "\\crosstabview: el resultado de la consulta contiene múltiples valores para la fila «%s», columna «%s»\n" +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: el resultado de la consulta contiene múltiples valores para la fila «%s», columna «%s»" -#: crosstabview.c:645 +#: crosstabview.c:646 #, c-format -msgid "\\crosstabview: column number %d is out of range 1..%d\n" -msgstr "\\crosstabview: el número de columna %d está fuera del rango 1..%d\n" +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: el número de columna %d está fuera del rango 1..%d" -#: crosstabview.c:670 +#: crosstabview.c:671 #, c-format -msgid "\\crosstabview: ambiguous column name: \"%s\"\n" -msgstr "\\crosstabview: nombre de columna «%s» ambiguo\n" +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: nombre de columna «%s» ambiguo" -#: crosstabview.c:678 +#: crosstabview.c:679 #, c-format -msgid "\\crosstabview: column name not found: \"%s\"\n" -msgstr "\\crosstabview: nombre de columna «%s» no encontrado\n" +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: nombre de columna «%s» no encontrado" -#: describe.c:73 describe.c:342 describe.c:599 describe.c:730 describe.c:874 -#: describe.c:1035 describe.c:1107 describe.c:3335 describe.c:3541 -#: describe.c:3632 describe.c:3880 describe.c:4025 describe.c:4257 -#: describe.c:4332 describe.c:4343 describe.c:4405 describe.c:4825 -#: describe.c:4908 +#: describe.c:77 describe.c:374 describe.c:679 describe.c:811 describe.c:955 +#: describe.c:1116 describe.c:1188 describe.c:3662 describe.c:3845 +#: describe.c:4089 describe.c:4180 describe.c:4447 describe.c:4607 +#: describe.c:4848 describe.c:4923 describe.c:4934 describe.c:4996 +#: describe.c:5421 describe.c:5504 msgid "Schema" msgstr "Esquema" -#: describe.c:74 describe.c:162 describe.c:228 describe.c:236 describe.c:343 -#: describe.c:600 describe.c:731 describe.c:792 describe.c:875 describe.c:1108 -#: describe.c:3336 describe.c:3464 describe.c:3542 describe.c:3633 -#: describe.c:3712 describe.c:3881 describe.c:3950 describe.c:4026 -#: describe.c:4258 describe.c:4333 describe.c:4344 describe.c:4406 -#: describe.c:4598 describe.c:4682 describe.c:4906 describe.c:5075 -#: describe.c:5261 +#: describe.c:78 describe.c:176 describe.c:244 describe.c:252 describe.c:375 +#: describe.c:680 describe.c:812 describe.c:873 describe.c:956 describe.c:1189 +#: describe.c:3663 describe.c:3846 describe.c:4012 describe.c:4090 +#: describe.c:4181 describe.c:4260 describe.c:4448 describe.c:4532 +#: describe.c:4608 describe.c:4849 describe.c:4924 describe.c:4935 +#: describe.c:4997 describe.c:5194 describe.c:5278 describe.c:5502 +#: describe.c:5674 describe.c:5899 msgid "Name" msgstr "Nombre" -#: describe.c:75 describe.c:355 describe.c:401 describe.c:418 +#: describe.c:79 describe.c:387 describe.c:405 describe.c:451 describe.c:468 msgid "Result data type" msgstr "Tipo de dato de salida" -#: describe.c:83 describe.c:96 describe.c:100 describe.c:356 describe.c:402 -#: describe.c:419 +#: describe.c:87 describe.c:100 describe.c:104 describe.c:388 describe.c:406 +#: describe.c:452 describe.c:469 msgid "Argument data types" msgstr "Tipos de datos de argumentos" -#: describe.c:107 describe.c:172 describe.c:259 describe.c:464 describe.c:648 -#: describe.c:746 describe.c:817 describe.c:1110 describe.c:1746 -#: describe.c:3135 describe.c:3370 describe.c:3495 describe.c:3569 -#: describe.c:3642 describe.c:3725 describe.c:3793 describe.c:3893 -#: describe.c:3959 describe.c:4027 describe.c:4163 describe.c:4203 -#: describe.c:4274 describe.c:4336 describe.c:4345 describe.c:4407 -#: describe.c:4624 describe.c:4704 describe.c:4839 describe.c:4909 -#: large_obj.c:289 large_obj.c:299 +#: describe.c:112 describe.c:119 describe.c:187 describe.c:275 describe.c:514 +#: describe.c:728 describe.c:827 describe.c:898 describe.c:1191 describe.c:2021 +#: describe.c:3451 describe.c:3698 describe.c:3892 describe.c:4043 +#: describe.c:4117 describe.c:4190 describe.c:4273 describe.c:4356 +#: describe.c:4475 describe.c:4541 describe.c:4609 describe.c:4750 +#: describe.c:4792 describe.c:4865 describe.c:4927 describe.c:4936 +#: describe.c:4998 describe.c:5220 describe.c:5300 describe.c:5435 +#: describe.c:5505 large_obj.c:290 large_obj.c:300 msgid "Description" msgstr "Descripción" -#: describe.c:125 +#: describe.c:137 msgid "List of aggregate functions" msgstr "Listado de funciones de agregación" -#: describe.c:149 +#: describe.c:162 #, c-format -msgid "The server (version %s) does not support access methods.\n" -msgstr "El servidor (versión %s) no soporta métodos de acceso.\n" +msgid "The server (version %s) does not support access methods." +msgstr "El servidor (versión %s) no soporta métodos de acceso." -#: describe.c:163 +#: describe.c:177 msgid "Index" msgstr "Indice" -#: describe.c:164 describe.c:362 describe.c:407 describe.c:424 describe.c:882 -#: describe.c:1046 describe.c:1706 describe.c:3345 describe.c:3543 -#: describe.c:4701 -msgid "Type" -msgstr "Tipo" +#: describe.c:178 describe.c:3679 describe.c:3871 describe.c:5422 +msgid "Table" +msgstr "Tabla" -#: describe.c:171 describe.c:4603 +#: describe.c:186 describe.c:5199 msgid "Handler" msgstr "Manejador" -#: describe.c:190 +#: describe.c:205 msgid "List of access methods" msgstr "Lista de métodos de acceso" -#: describe.c:215 +#: describe.c:231 #, c-format -msgid "The server (version %s) does not support tablespaces.\n" -msgstr "El servidor (versión %s) no soporta tablespaces.\n" +msgid "The server (version %s) does not support tablespaces." +msgstr "El servidor (versión %s) no soporta tablespaces." -#: describe.c:229 describe.c:237 describe.c:452 describe.c:638 describe.c:793 -#: describe.c:1034 describe.c:3346 describe.c:3468 describe.c:3714 -#: describe.c:3951 describe.c:4599 describe.c:4683 describe.c:5076 -#: describe.c:5262 large_obj.c:288 +#: describe.c:245 describe.c:253 describe.c:502 describe.c:718 describe.c:874 +#: describe.c:1115 describe.c:3674 describe.c:3847 describe.c:4016 +#: describe.c:4262 describe.c:4533 describe.c:5195 describe.c:5279 +#: describe.c:5675 describe.c:5801 describe.c:5900 large_obj.c:289 msgid "Owner" msgstr "Dueño" -#: describe.c:230 describe.c:238 +#: describe.c:246 describe.c:254 msgid "Location" msgstr "Ubicación" -#: describe.c:249 describe.c:2950 +#: describe.c:265 describe.c:3269 msgid "Options" msgstr "Opciones" -#: describe.c:254 describe.c:611 describe.c:809 describe.c:3362 -#: describe.c:3366 +#: describe.c:270 describe.c:691 describe.c:890 describe.c:3690 describe.c:3694 msgid "Size" msgstr "Tamaño" -#: describe.c:276 +#: describe.c:292 msgid "List of tablespaces" msgstr "Listado de tablespaces" -#: describe.c:316 +#: describe.c:334 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df sólo acepta las opciones [antwS+]\n" +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df sólo acepta las opciones [antpwS+]" -#: describe.c:324 +#: describe.c:342 describe.c:353 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df no acepta la opción «w» en un servidor versión %s\n" +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df no acepta la opción «%c» en un servidor versión %s" #. translator: "agg" is short for "aggregate" -#: describe.c:358 describe.c:404 describe.c:421 +#: describe.c:390 describe.c:408 describe.c:454 describe.c:471 msgid "agg" msgstr "agg" -#: describe.c:359 +#: describe.c:391 describe.c:409 msgid "window" msgstr "ventana" -#: describe.c:360 describe.c:405 describe.c:422 describe.c:1244 +#: describe.c:392 +msgid "proc" +msgstr "proc" + +#: describe.c:393 describe.c:411 describe.c:456 describe.c:473 +msgid "func" +msgstr "func" + +#: describe.c:410 describe.c:455 describe.c:472 describe.c:1325 msgid "trigger" msgstr "disparador" -#: describe.c:361 describe.c:406 describe.c:423 -msgid "normal" -msgstr "normal" - -#: describe.c:434 +#: describe.c:484 msgid "immutable" msgstr "inmutable" -#: describe.c:435 +#: describe.c:485 msgid "stable" msgstr "estable" -#: describe.c:436 +#: describe.c:486 msgid "volatile" msgstr "volátil" -#: describe.c:437 +#: describe.c:487 msgid "Volatility" msgstr "Volatilidad" -#: describe.c:445 +#: describe.c:495 msgid "restricted" msgstr "restringida" -#: describe.c:446 +#: describe.c:496 msgid "safe" msgstr "segura" -#: describe.c:447 +#: describe.c:497 msgid "unsafe" msgstr "insegura" -#: describe.c:448 +#: describe.c:498 msgid "Parallel" msgstr "Paralelismo" -#: describe.c:453 +#: describe.c:503 msgid "definer" msgstr "definidor" -#: describe.c:454 +#: describe.c:504 msgid "invoker" msgstr "invocador" -#: describe.c:455 +#: describe.c:505 msgid "Security" msgstr "Seguridad" -#: describe.c:462 +#: describe.c:512 msgid "Language" msgstr "Lenguaje" -#: describe.c:463 +#: describe.c:513 msgid "Source code" msgstr "Código fuente" -#: describe.c:562 +#: describe.c:642 msgid "List of functions" msgstr "Listado de funciones" -#: describe.c:610 +#: describe.c:690 msgid "Internal name" msgstr "Nombre interno" -#: describe.c:632 +#: describe.c:712 msgid "Elements" msgstr "Elementos" -#: describe.c:689 +#: describe.c:769 msgid "List of data types" msgstr "Listado de tipos de dato" -#: describe.c:732 +#: describe.c:813 msgid "Left arg type" msgstr "Tipo arg izq" -#: describe.c:733 +#: describe.c:814 msgid "Right arg type" msgstr "Tipo arg der" -#: describe.c:734 +#: describe.c:815 msgid "Result type" msgstr "Tipo resultado" -#: describe.c:739 describe.c:3784 describe.c:4162 +#: describe.c:820 describe.c:4268 describe.c:4333 describe.c:4339 +#: describe.c:4749 msgid "Function" msgstr "Función" -#: describe.c:764 +#: describe.c:845 msgid "List of operators" msgstr "Listado de operadores" -#: describe.c:794 +#: describe.c:875 msgid "Encoding" msgstr "Codificación" -#: describe.c:799 describe.c:3882 +#: describe.c:880 describe.c:4449 msgid "Collate" msgstr "Collate" -#: describe.c:800 describe.c:3883 +#: describe.c:881 describe.c:4450 msgid "Ctype" msgstr "Ctype" -#: describe.c:813 +#: describe.c:894 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:835 +#: describe.c:916 msgid "List of databases" msgstr "Listado de base de datos" -#: describe.c:876 describe.c:881 describe.c:1037 describe.c:3337 -#: describe.c:3344 +#: describe.c:957 describe.c:1118 describe.c:3664 msgid "table" msgstr "tabla" -#: describe.c:877 describe.c:3338 +#: describe.c:958 describe.c:3665 msgid "view" msgstr "vista" -#: describe.c:878 describe.c:3339 +#: describe.c:959 describe.c:3666 msgid "materialized view" msgstr "vistas materializadas" -#: describe.c:879 describe.c:1039 describe.c:3341 +#: describe.c:960 describe.c:1120 describe.c:3668 msgid "sequence" msgstr "secuencia" -#: describe.c:880 describe.c:3343 +#: describe.c:961 describe.c:3670 msgid "foreign table" msgstr "tabla foránea" -#: describe.c:893 +#: describe.c:962 describe.c:3671 describe.c:3856 +msgid "partitioned table" +msgstr "tabla particionada" + +#: describe.c:974 msgid "Column privileges" msgstr "Privilegios de acceso a columnas" -#: describe.c:924 describe.c:958 +#: describe.c:1005 describe.c:1039 msgid "Policies" msgstr "Políticas" -#: describe.c:990 describe.c:5318 describe.c:5322 +#: describe.c:1071 describe.c:5956 describe.c:5960 msgid "Access privileges" msgstr "Privilegios" -#: describe.c:1021 +#: describe.c:1102 #, c-format -msgid "The server (version %s) does not support altering default privileges.\n" -msgstr "El servidor (versión %s) no soporta la alteración de privilegios por omisión.\n" +msgid "The server (version %s) does not support altering default privileges." +msgstr "El servidor (versión %s) no soporta la alteración de privilegios por omisión." -#: describe.c:1041 +#: describe.c:1122 msgid "function" msgstr "función" -#: describe.c:1043 +#: describe.c:1124 msgid "type" msgstr "tipo" -#: describe.c:1045 -#, fuzzy +#: describe.c:1126 msgid "schema" -msgstr "Esquema" +msgstr "esquema" -#: describe.c:1069 +#: describe.c:1150 msgid "Default access privileges" msgstr "Privilegios de acceso por omisión" -#: describe.c:1109 +#: describe.c:1190 msgid "Object" msgstr "Objeto" -#: describe.c:1123 +#: describe.c:1204 msgid "table constraint" msgstr "restricción de tabla" -#: describe.c:1145 +#: describe.c:1226 msgid "domain constraint" msgstr "restricción de dominio" -#: describe.c:1173 +#: describe.c:1254 msgid "operator class" msgstr "clase de operadores" -#: describe.c:1202 +#: describe.c:1283 msgid "operator family" msgstr "familia de operadores" -#: describe.c:1224 +#: describe.c:1305 msgid "rule" msgstr "regla" -#: describe.c:1266 +#: describe.c:1347 msgid "Object descriptions" msgstr "Descripciones de objetos" -#: describe.c:1320 +#: describe.c:1403 describe.c:3762 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "No se encontró relación llamada «%s»." + +#: describe.c:1406 describe.c:3765 +#, c-format +msgid "Did not find any relations." +msgstr "No se encontró ninguna relación." + +#: describe.c:1661 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "No se encontró relación con OID %s." + +#: describe.c:1713 describe.c:1737 +msgid "Start" +msgstr "Inicio" + +#: describe.c:1714 describe.c:1738 +msgid "Minimum" +msgstr "Mínimo" + +#: describe.c:1715 describe.c:1739 +msgid "Maximum" +msgstr "Máximo" + +#: describe.c:1716 describe.c:1740 +msgid "Increment" +msgstr "Incremento" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4184 +#: describe.c:4350 describe.c:4464 describe.c:4469 +msgid "yes" +msgstr "sí" + +#: describe.c:1718 describe.c:1742 describe.c:1873 describe.c:4184 +#: describe.c:4347 describe.c:4464 +msgid "no" +msgstr "no" + +#: describe.c:1719 describe.c:1743 +msgid "Cycles?" +msgstr "¿Cicla?" + +#: describe.c:1720 describe.c:1744 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1787 +#, c-format +msgid "Owned by: %s" +msgstr "Asociada a: %s" + +#: describe.c:1791 #, c-format -msgid "Did not find any relation named \"%s\".\n" -msgstr "No se encontró relación llamada «%s».\n" +msgid "Sequence for identity column: %s" +msgstr "Secuencia para columna identidad: %s" -#: describe.c:1529 +#: describe.c:1798 #, c-format -msgid "Did not find any relation with OID %s.\n" -msgstr "No se encontró relación con OID %s.\n" +msgid "Sequence \"%s.%s\"" +msgstr "Secuencia «%s.%s»" -#: describe.c:1642 describe.c:1691 +#: describe.c:1934 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Tabla unlogged «%s.%s»" -#: describe.c:1645 describe.c:1694 +#: describe.c:1937 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabla «%s.%s»" -#: describe.c:1649 +#: describe.c:1941 #, c-format msgid "View \"%s.%s\"" msgstr "Vista «%s.%s»" -#: describe.c:1654 +#: describe.c:1946 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Vista materializada unlogged «%s.%s»" -#: describe.c:1657 +#: describe.c:1949 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Vista materializada \"%s.%s\"" -#: describe.c:1661 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Secuencia «%s.%s»" - -#: describe.c:1666 +#: describe.c:1954 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Ãndice unlogged «%s.%s»" -#: describe.c:1669 +#: describe.c:1957 #, c-format msgid "Index \"%s.%s\"" msgstr "Ãndice «%s.%s»" -#: describe.c:1674 +#: describe.c:1962 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Ãndice particionado unlogged «%s.%s»" + +#: describe.c:1965 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Ãndice particionado «%s.%s»" + +#: describe.c:1970 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Relación especial «%s.%s»" -#: describe.c:1678 +#: describe.c:1974 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "Tabla TOAST «%s.%s»" -#: describe.c:1682 +#: describe.c:1978 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Tipo compuesto «%s.%s»" -#: describe.c:1686 +#: describe.c:1982 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Tabla foránea «%s.%s»" -#: describe.c:1705 -msgid "Column" -msgstr "Columna" +#: describe.c:1987 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Tabla unlogged particionada «%s.%s»" + +#: describe.c:1990 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Tabla particionada «%s.%s»" -#: describe.c:1716 describe.c:3549 -#, fuzzy +#: describe.c:2006 describe.c:4097 msgid "Collation" -msgstr "ordenamiento" +msgstr "Ordenamiento" -#: describe.c:1717 describe.c:3556 -#, fuzzy +#: describe.c:2007 describe.c:4104 msgid "Nullable" -msgstr "ordenable" +msgstr "Nulable" -#: describe.c:1718 describe.c:3557 -#, fuzzy +#: describe.c:2008 describe.c:4105 msgid "Default" -msgstr "Por omisión?" +msgstr "Por omisión" -#: describe.c:1723 -msgid "Value" -msgstr "Valor" +#: describe.c:2011 +msgid "Key?" +msgstr "¿Llave?" -#: describe.c:1726 +#: describe.c:2013 msgid "Definition" msgstr "Definición" -#: describe.c:1729 describe.c:4619 describe.c:4703 describe.c:4774 -#: describe.c:4838 -#, fuzzy -#| msgid "FDW Options" +#: describe.c:2015 describe.c:5215 describe.c:5299 describe.c:5370 +#: describe.c:5434 msgid "FDW options" msgstr "Opciones de FDW" -#: describe.c:1733 +#: describe.c:2017 msgid "Storage" msgstr "Almacenamiento" -#: describe.c:1738 +#: describe.c:2019 msgid "Stats target" msgstr "Estadísticas" -#: describe.c:1893 +#: describe.c:2137 #, c-format msgid "Partition of: %s %s" -msgstr "" +msgstr "Partición de: %s %s" -#: describe.c:1899 -#, fuzzy, c-format +#: describe.c:2145 +msgid "No partition constraint" +msgstr "Sin restricción de partición" + +#: describe.c:2147 +#, c-format msgid "Partition constraint: %s" -msgstr "restricción de dominio" +msgstr "Restricción de partición: %s" -#: describe.c:1922 +#: describe.c:2170 #, c-format msgid "Partition key: %s" -msgstr "" +msgstr "Llave de partición: %s" -#: describe.c:1990 +#: describe.c:2239 msgid "primary key, " msgstr "llave primaria, " -#: describe.c:1992 +#: describe.c:2241 msgid "unique, " msgstr "único, " -#: describe.c:1998 +#: describe.c:2247 #, c-format msgid "for table \"%s.%s\"" msgstr "de tabla «%s.%s»" -#: describe.c:2002 +#: describe.c:2251 #, c-format msgid ", predicate (%s)" msgstr ", predicado (%s)" -#: describe.c:2005 +#: describe.c:2254 msgid ", clustered" msgstr ", clustered" -#: describe.c:2008 +#: describe.c:2257 msgid ", invalid" msgstr ", no válido" -#: describe.c:2011 +#: describe.c:2260 msgid ", deferrable" msgstr ", postergable" -#: describe.c:2014 +#: describe.c:2263 msgid ", initially deferred" msgstr ", inicialmente postergada" -#: describe.c:2017 +#: describe.c:2266 msgid ", replica identity" msgstr ", identidad de replicación" -#: describe.c:2056 -#, c-format -msgid "Owned by: %s" -msgstr "Asociada a: %s" - -#: describe.c:2061 -#, c-format -msgid "Sequence for identity column: %s" -msgstr "" - -#: describe.c:2125 +#: describe.c:2325 msgid "Indexes:" msgstr "Ãndices:" -#: describe.c:2209 +#: describe.c:2409 msgid "Check constraints:" msgstr "Restricciones CHECK:" -#: describe.c:2240 +#: describe.c:2477 msgid "Foreign-key constraints:" msgstr "Restricciones de llave foránea:" -#: describe.c:2271 +#: describe.c:2540 msgid "Referenced by:" msgstr "Referenciada por:" -#: describe.c:2331 +#: describe.c:2590 msgid "Policies:" msgstr "Políticas:" -#: describe.c:2334 +#: describe.c:2593 msgid "Policies (forced row security enabled):" msgstr "Políticas (seguridad de registros forzada):" -#: describe.c:2337 +#: describe.c:2596 msgid "Policies (row security enabled): (none)" msgstr "Políticas (seguridad de filas activa): (ninguna)" -#: describe.c:2340 +#: describe.c:2599 msgid "Policies (forced row security enabled): (none)" msgstr "Políticas (seguridad de filas forzada): (ninguna)" -#: describe.c:2343 +#: describe.c:2602 msgid "Policies (row security disabled):" msgstr "Políticas (seguridad de filas inactiva):" -#: describe.c:2405 +#: describe.c:2665 msgid "Statistics objects:" -msgstr "" +msgstr "Objetos de estadísticas:" -#: describe.c:2508 describe.c:2593 +#: describe.c:2774 describe.c:2878 msgid "Rules:" msgstr "Reglas:" -#: describe.c:2511 +#: describe.c:2777 msgid "Disabled rules:" msgstr "Reglas deshabilitadas:" -#: describe.c:2514 +#: describe.c:2780 msgid "Rules firing always:" msgstr "Reglas que se activan siempre:" -#: describe.c:2517 +#: describe.c:2783 msgid "Rules firing on replica only:" msgstr "Reglas que se activan sólo en las réplicas:" -#: describe.c:2557 -#, fuzzy +#: describe.c:2823 msgid "Publications:" -msgstr "Replicación" +msgstr "Publicaciones:" -#: describe.c:2576 +#: describe.c:2861 msgid "View definition:" msgstr "Definición de vista:" -#: describe.c:2711 +#: describe.c:3000 msgid "Triggers:" msgstr "Triggers:" -#: describe.c:2715 +#: describe.c:3004 msgid "Disabled user triggers:" msgstr "Disparadores de usuario deshabilitados:" -#: describe.c:2717 +#: describe.c:3006 msgid "Disabled triggers:" msgstr "Disparadores deshabilitados:" -#: describe.c:2720 +#: describe.c:3009 msgid "Disabled internal triggers:" msgstr "Disparadores internos deshabilitados:" -#: describe.c:2723 +#: describe.c:3012 msgid "Triggers firing always:" msgstr "Disparadores que siempre se ejecutan:" -#: describe.c:2726 +#: describe.c:3015 msgid "Triggers firing on replica only:" msgstr "Disparadores que se ejecutan sólo en las réplicas:" -#: describe.c:2785 +#: describe.c:3074 #, c-format msgid "Server: %s" msgstr "Servidor: %s" -#: describe.c:2793 -#, fuzzy, c-format -#| msgid "FDW Options: (%s)" +#: describe.c:3082 +#, c-format msgid "FDW options: (%s)" msgstr "Opciones de FDW: (%s)" -#: describe.c:2812 +#: describe.c:3101 msgid "Inherits" msgstr "Hereda" -#: describe.c:2866 +#: describe.c:3160 +#, c-format +msgid "Number of partitions: %d" +msgstr "Número de particiones: %d" + +#: describe.c:3169 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Número de tablas hijas: %d (Use \\d+ para listarlas.)" -#: describe.c:2868 -#, fuzzy, c-format +#: describe.c:3171 +#, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" -msgstr "Número de tablas hijas: %d (Use \\d+ para listarlas.)" +msgstr "Número de particiones: %d (Use \\d+ para listarlas.)" -#: describe.c:2876 +#: describe.c:3179 msgid "Child tables" msgstr "Tablas hijas" -#: describe.c:2876 -#, fuzzy +#: describe.c:3179 msgid "Partitions" -msgstr "acción" +msgstr "Particiones" -#: describe.c:2910 +#: describe.c:3222 #, c-format msgid "Typed table of type: %s" msgstr "Tabla tipada de tipo: %s" -#: describe.c:2926 +#: describe.c:3238 msgid "Replica Identity" msgstr "Identidad de replicación" -#: describe.c:2939 +#: describe.c:3251 msgid "Has OIDs: yes" msgstr "Tiene OIDs: sí" -#: describe.c:3023 +#: describe.c:3260 +#, c-format +msgid "Access method: %s" +msgstr "Método de acceso: %s" + +#: describe.c:3339 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace: «%s»" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3035 +#: describe.c:3351 #, c-format msgid ", tablespace \"%s\"" msgstr ", tablespace «%s»" -#: describe.c:3128 +#: describe.c:3444 msgid "List of roles" msgstr "Lista de roles" -#: describe.c:3130 +#: describe.c:3446 msgid "Role name" msgstr "Nombre de rol" -#: describe.c:3131 +#: describe.c:3447 msgid "Attributes" msgstr "Atributos" -#: describe.c:3132 +#: describe.c:3448 msgid "Member of" msgstr "Miembro de" -#: describe.c:3143 +#: describe.c:3459 msgid "Superuser" msgstr "Superusuario" -#: describe.c:3146 +#: describe.c:3462 msgid "No inheritance" msgstr "Sin herencia" -#: describe.c:3149 +#: describe.c:3465 msgid "Create role" msgstr "Crear rol" -#: describe.c:3152 +#: describe.c:3468 msgid "Create DB" msgstr "Crear BD" -#: describe.c:3155 +#: describe.c:3471 msgid "Cannot login" msgstr "No puede conectarse" -#: describe.c:3159 +#: describe.c:3475 msgid "Replication" msgstr "Replicación" -#: describe.c:3163 +#: describe.c:3479 msgid "Bypass RLS" msgstr "Ignora RLS" -#: describe.c:3172 +#: describe.c:3488 msgid "No connections" msgstr "Ninguna conexión" -#: describe.c:3174 +#: describe.c:3490 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d conexión" msgstr[1] "%d conexiones" -#: describe.c:3184 +#: describe.c:3500 msgid "Password valid until " msgstr "Constraseña válida hasta " -#: describe.c:3240 +#: describe.c:3550 +#, c-format +msgid "The server (version %s) does not support per-database role settings." +msgstr "El servidor (versión %s) no soporta parámetros por base de datos y rol." + +#: describe.c:3563 msgid "Role" msgstr "Nombre de rol" -#: describe.c:3241 +#: describe.c:3564 msgid "Database" msgstr "Base de Datos" -#: describe.c:3242 +#: describe.c:3565 msgid "Settings" -msgstr "Seteos" +msgstr "Parámetros" -#: describe.c:3252 +#: describe.c:3586 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "Este servidor no permite parámetros por usuario por base de datos.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "No se encontró ningún parámetro para el rol «%s» y la base de datos «%s»." -#: describe.c:3263 +#: describe.c:3589 #, c-format -msgid "No matching settings found.\n" -msgstr "No se encontraron parámetros coincidentes.\n" +msgid "Did not find any settings for role \"%s\"." +msgstr "No se encontró ningún parámetro para el rol «%s»." -#: describe.c:3265 +#: describe.c:3592 #, c-format -msgid "No settings found.\n" -msgstr "No se encontraron parámetros.\n" +msgid "Did not find any settings." +msgstr "No se encontró ningún parámetro." -#: describe.c:3270 +#: describe.c:3597 msgid "List of settings" msgstr "Listado de parámetros" -#: describe.c:3340 +#: describe.c:3667 msgid "index" msgstr "índice" -#: describe.c:3342 +#: describe.c:3669 msgid "special" msgstr "especial" -#: describe.c:3351 describe.c:4826 -msgid "Table" -msgstr "Tabla" +#: describe.c:3672 describe.c:3857 +msgid "partitioned index" +msgstr "índice particionado" -#: describe.c:3428 -#, c-format -msgid "No matching relations found.\n" -msgstr "No se encontraron relaciones coincidentes.\n" +#: describe.c:3770 +msgid "List of relations" +msgstr "Listado de relaciones" -#: describe.c:3430 +#: describe.c:3818 #, c-format -msgid "No relations found.\n" -msgstr "No se encontraron relaciones.\n" +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "El servidor (versión %s) no soporta particionamiento declarativo de tablas." -#: describe.c:3435 -msgid "List of relations" -msgstr "Listado de relaciones" +#: describe.c:3829 +msgid "List of partitioned indexes" +msgstr "Listado de índices particionados" -#: describe.c:3472 +#: describe.c:3831 +msgid "List of partitioned tables" +msgstr "Listado de tablas particionadas" + +#: describe.c:3835 +msgid "List of partitioned relations" +msgstr "Listado de relaciones particionadas" + +#: describe.c:3866 +msgid "Parent name" +msgstr "Nombre del padre" + +#: describe.c:3879 +msgid "Leaf partition size" +msgstr "Tamaño de particiones hoja" + +#: describe.c:3882 describe.c:3888 +msgid "Total size" +msgstr "Tamaño total" + +#: describe.c:4020 msgid "Trusted" msgstr "Confiable" -#: describe.c:3480 -#, fuzzy -#| msgid "Internal Language" +#: describe.c:4028 msgid "Internal language" msgstr "Lenguaje interno" -#: describe.c:3481 -#, fuzzy -#| msgid "Call Handler" +#: describe.c:4029 msgid "Call handler" msgstr "Manejador de llamada" -#: describe.c:3482 describe.c:4606 +#: describe.c:4030 describe.c:5202 msgid "Validator" msgstr "Validador" -#: describe.c:3485 -#, fuzzy -#| msgid "Inline Handler" +#: describe.c:4033 msgid "Inline handler" msgstr "Manejador en línea" -#: describe.c:3513 +#: describe.c:4061 msgid "List of languages" msgstr "Lista de lenguajes" -#: describe.c:3558 +#: describe.c:4106 msgid "Check" msgstr "Check" -#: describe.c:3600 +#: describe.c:4148 msgid "List of domains" msgstr "Listado de dominios" -#: describe.c:3634 +#: describe.c:4182 msgid "Source" msgstr "Fuente" -#: describe.c:3635 +#: describe.c:4183 msgid "Destination" msgstr "Destino" -#: describe.c:3636 describe.c:3785 -msgid "no" -msgstr "no" - -#: describe.c:3636 describe.c:3787 -msgid "yes" -msgstr "sí" - -#: describe.c:3637 +#: describe.c:4185 msgid "Default?" msgstr "Por omisión?" -#: describe.c:3674 +#: describe.c:4222 msgid "List of conversions" msgstr "Listado de conversiones" -#: describe.c:3713 +#: describe.c:4261 msgid "Event" msgstr "Evento" -#: describe.c:3715 +#: describe.c:4263 msgid "enabled" msgstr "activo" -#: describe.c:3716 +#: describe.c:4264 msgid "replica" msgstr "réplica" -#: describe.c:3717 +#: describe.c:4265 msgid "always" msgstr "siempre" -#: describe.c:3718 +#: describe.c:4266 msgid "disabled" msgstr "inactivo" -#: describe.c:3719 describe.c:5263 +#: describe.c:4267 describe.c:5901 msgid "Enabled" msgstr "Activo" -#: describe.c:3720 -msgid "Procedure" -msgstr "Procedimiento" - -#: describe.c:3721 +#: describe.c:4269 msgid "Tags" msgstr "Etiquetas" -#: describe.c:3740 +#: describe.c:4288 msgid "List of event triggers" msgstr "Listado de disparadores por eventos" -#: describe.c:3782 +#: describe.c:4317 msgid "Source type" msgstr "Tipo fuente" -#: describe.c:3783 +#: describe.c:4318 msgid "Target type" msgstr "Tipo destino" -#: describe.c:3786 +#: describe.c:4349 msgid "in assignment" msgstr "en asignación" -#: describe.c:3788 +#: describe.c:4351 msgid "Implicit?" msgstr "Implícito?" -#: describe.c:3839 +#: describe.c:4406 msgid "List of casts" msgstr "Listado de conversiones de tipo (casts)" -#: describe.c:3867 +#: describe.c:4434 #, c-format -msgid "The server (version %s) does not support collations.\n" -msgstr "El servidor (versión %s) no soporta «collations».\n" +msgid "The server (version %s) does not support collations." +msgstr "El servidor (versión %s) no soporta «collations»." -#: describe.c:3888 -#, fuzzy +#: describe.c:4455 describe.c:4459 msgid "Provider" -msgstr "proveedor" +msgstr "Proveedor" + +#: describe.c:4465 describe.c:4470 +msgid "Deterministic?" +msgstr "¿Determinístico?" -#: describe.c:3923 +#: describe.c:4505 msgid "List of collations" msgstr "Listado de ordenamientos" -#: describe.c:3982 +#: describe.c:4564 msgid "List of schemas" msgstr "Listado de esquemas" -#: describe.c:4007 describe.c:4245 describe.c:4316 describe.c:4387 +#: describe.c:4589 describe.c:4836 describe.c:4907 describe.c:4978 #, c-format -msgid "The server (version %s) does not support full text search.\n" -msgstr "El servidor (versión %s) no soporta búsqueda en texto.\n" +msgid "The server (version %s) does not support full text search." +msgstr "El servidor (versión %s) no soporta búsqueda en texto." -#: describe.c:4042 +#: describe.c:4624 msgid "List of text search parsers" msgstr "Listado de analizadores de búsqueda en texto" -#: describe.c:4085 +#: describe.c:4669 #, c-format -msgid "Did not find any text search parser named \"%s\".\n" -msgstr "No se encontró ningún analizador de búsqueda en texto llamado «%s».\n" +msgid "Did not find any text search parser named \"%s\"." +msgstr "No se encontró ningún analizador de búsqueda en texto llamado «%s»." -#: describe.c:4160 +#: describe.c:4672 +#, c-format +msgid "Did not find any text search parsers." +msgstr "No se encontró ningún analizador de búsqueda en texto." + +#: describe.c:4747 msgid "Start parse" msgstr "Inicio de parse" -#: describe.c:4161 +#: describe.c:4748 msgid "Method" msgstr "Método" -#: describe.c:4165 +#: describe.c:4752 msgid "Get next token" msgstr "Obtener siguiente elemento" -#: describe.c:4167 +#: describe.c:4754 msgid "End parse" msgstr "Fin de parse" -#: describe.c:4169 +#: describe.c:4756 msgid "Get headline" msgstr "Obtener encabezado" -#: describe.c:4171 +#: describe.c:4758 msgid "Get token types" msgstr "Obtener tipos de elemento" -#: describe.c:4181 +#: describe.c:4769 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Analizador de búsqueda en texto «%s.%s»" -#: describe.c:4183 +#: describe.c:4772 #, c-format msgid "Text search parser \"%s\"" msgstr "Analizador de búsqueda en texto «%s»" -#: describe.c:4202 +#: describe.c:4791 msgid "Token name" msgstr "Nombre de elemento" -#: describe.c:4213 +#: describe.c:4802 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Tipos de elemento para el analizador «%s.%s»" -#: describe.c:4215 +#: describe.c:4805 #, c-format msgid "Token types for parser \"%s\"" msgstr "Tipos de elemento para el analizador «%s»" -#: describe.c:4268 +#: describe.c:4859 msgid "Template" msgstr "Plantilla" -#: describe.c:4269 +#: describe.c:4860 msgid "Init options" msgstr "Opciones de inicialización" -#: describe.c:4291 +#: describe.c:4882 msgid "List of text search dictionaries" msgstr "Listado de diccionarios de búsqueda en texto" -#: describe.c:4334 +#: describe.c:4925 msgid "Init" msgstr "Inicializador" -#: describe.c:4335 +#: describe.c:4926 msgid "Lexize" msgstr "Fn. análisis léx." -#: describe.c:4362 +#: describe.c:4953 msgid "List of text search templates" msgstr "Listado de plantillas de búsqueda en texto" -#: describe.c:4422 +#: describe.c:5013 msgid "List of text search configurations" msgstr "Listado de configuraciones de búsqueda en texto" -#: describe.c:4466 +#: describe.c:5059 #, c-format -msgid "Did not find any text search configuration named \"%s\".\n" -msgstr "No se encontró una configuración de búsqueda en texto llamada «%s».\n" +msgid "Did not find any text search configuration named \"%s\"." +msgstr "No se encontró una configuración de búsqueda en texto llamada «%s»." -#: describe.c:4532 +#: describe.c:5062 +#, c-format +msgid "Did not find any text search configurations." +msgstr "No se encontró una configuración de búsqueda en texto." + +#: describe.c:5128 msgid "Token" msgstr "Elemento" -#: describe.c:4533 +#: describe.c:5129 msgid "Dictionaries" msgstr "Diccionarios" -#: describe.c:4544 +#: describe.c:5140 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Configuración de búsqueda en texto «%s.%s»" -#: describe.c:4547 +#: describe.c:5143 #, c-format msgid "Text search configuration \"%s\"" msgstr "Configuración de búsqueda en texto «%s»" -#: describe.c:4551 +#: describe.c:5147 #, c-format msgid "" "\n" @@ -1912,7 +2076,7 @@ msgstr "" "\n" "Analizador: «%s.%s»" -#: describe.c:4554 +#: describe.c:5150 #, c-format msgid "" "\n" @@ -1921,159 +2085,156 @@ msgstr "" "\n" "Analizador: «%s»" -#: describe.c:4588 +#: describe.c:5184 #, c-format -msgid "The server (version %s) does not support foreign-data wrappers.\n" -msgstr "El servidor (versión %s) no soporta conectores de datos externos.\n" +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "El servidor (versión %s) no soporta conectores de datos externos." -#: describe.c:4646 +#: describe.c:5242 msgid "List of foreign-data wrappers" msgstr "Listado de conectores de datos externos" -#: describe.c:4671 +#: describe.c:5267 #, c-format -msgid "The server (version %s) does not support foreign servers.\n" -msgstr "El servidor (versión %s) no soporta servidores foráneos.\n" +msgid "The server (version %s) does not support foreign servers." +msgstr "El servidor (versión %s) no soporta servidores foráneos." -#: describe.c:4684 +#: describe.c:5280 msgid "Foreign-data wrapper" msgstr "Conectores de datos externos" -#: describe.c:4702 describe.c:4907 +#: describe.c:5298 describe.c:5503 msgid "Version" msgstr "Versión" -#: describe.c:4728 +#: describe.c:5324 msgid "List of foreign servers" msgstr "Listado de servidores foráneos" -#: describe.c:4753 +#: describe.c:5349 #, c-format -msgid "The server (version %s) does not support user mappings.\n" -msgstr "El servidor (versión %s) no soporta mapeos de usuario.\n" +msgid "The server (version %s) does not support user mappings." +msgstr "El servidor (versión %s) no soporta mapeos de usuario." -#: describe.c:4763 describe.c:4827 +#: describe.c:5359 describe.c:5423 msgid "Server" msgstr "Servidor" -#: describe.c:4764 +#: describe.c:5360 msgid "User name" msgstr "Nombre de usuario" -#: describe.c:4789 +#: describe.c:5385 msgid "List of user mappings" msgstr "Listado de mapeos de usuario" -#: describe.c:4814 +#: describe.c:5410 #, c-format -msgid "The server (version %s) does not support foreign tables.\n" -msgstr "El servidor (versión %s) no soporta tablas foráneas.\n" +msgid "The server (version %s) does not support foreign tables." +msgstr "El servidor (versión %s) no soporta tablas foráneas." -#: describe.c:4867 +#: describe.c:5463 msgid "List of foreign tables" msgstr "Listado de tablas foráneas" -#: describe.c:4892 describe.c:4949 +#: describe.c:5488 describe.c:5545 #, c-format -msgid "The server (version %s) does not support extensions.\n" -msgstr "El servidor (versión %s) no soporta extensiones.\n" +msgid "The server (version %s) does not support extensions." +msgstr "El servidor (versión %s) no soporta extensiones." -#: describe.c:4924 +#: describe.c:5520 msgid "List of installed extensions" msgstr "Listado de extensiones instaladas" -#: describe.c:4977 +#: describe.c:5573 #, c-format -msgid "Did not find any extension named \"%s\".\n" -msgstr "No se encontró extensión llamada «%s».\n" +msgid "Did not find any extension named \"%s\"." +msgstr "No se encontró extensión llamada «%s»." -#: describe.c:4980 +#: describe.c:5576 #, c-format -msgid "Did not find any extensions.\n" -msgstr "No se encontró ninguna extensión.\n" +msgid "Did not find any extensions." +msgstr "No se encontró ninguna extensión." -#: describe.c:5024 -#, fuzzy -#| msgid "Object descriptions" +#: describe.c:5620 msgid "Object description" -msgstr "Descripciones de objetos" +msgstr "Descripción de objeto" -#: describe.c:5033 +#: describe.c:5630 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objetos en extensión «%s»" -#: describe.c:5060 describe.c:5125 -#, fuzzy, c-format -msgid "The server (version %s) does not support publications.\n" -msgstr "El servidor (versión %s) no soporta «collations».\n" +#: describe.c:5659 describe.c:5730 +#, c-format +msgid "The server (version %s) does not support publications." +msgstr "El servidor (versión %s) no soporta publicaciones." -#: describe.c:5077 describe.c:5170 -#, fuzzy -#| msgid "Child tables" +#: describe.c:5676 describe.c:5802 msgid "All tables" -msgstr "Tablas hijas" +msgstr "Todas las tablas" -#: describe.c:5078 describe.c:5171 -#, fuzzy +#: describe.c:5677 describe.c:5803 msgid "Inserts" -msgstr "insert" +msgstr "Inserts" -#: describe.c:5079 describe.c:5172 -#, fuzzy +#: describe.c:5678 describe.c:5804 msgid "Updates" -msgstr "update" +msgstr "Updates" -#: describe.c:5080 describe.c:5173 -#, fuzzy +#: describe.c:5679 describe.c:5805 msgid "Deletes" -msgstr "delete" +msgstr "Deletes" -#: describe.c:5097 -#, fuzzy +#: describe.c:5683 describe.c:5807 +msgid "Truncates" +msgstr "Truncates" + +#: describe.c:5700 msgid "List of publications" -msgstr "Listado de relaciones" +msgstr "Listado de publicaciones" + +#: describe.c:5768 +#, c-format +msgid "Did not find any publication named \"%s\"." +msgstr "No se encontró publicación llamada «%s»." -#: describe.c:5167 -#, fuzzy, c-format +#: describe.c:5771 +#, c-format +msgid "Did not find any publications." +msgstr "No se encontró ninguna publicación." + +#: describe.c:5798 +#, c-format msgid "Publication %s" -msgstr "Replicación" +msgstr "Publicación %s" -#: describe.c:5205 -#, fuzzy +#: describe.c:5842 msgid "Tables:" -msgstr "Tabla" +msgstr "Tablas:" -#: describe.c:5248 -#, fuzzy, c-format -msgid "The server (version %s) does not support subscriptions.\n" -msgstr "El servidor (versión %s) no soporta «collations».\n" +#: describe.c:5886 +#, c-format +msgid "The server (version %s) does not support subscriptions." +msgstr "El servidor (versión %s) no soporta suscripciones." -#: describe.c:5264 -#, fuzzy +#: describe.c:5902 msgid "Publication" -msgstr "Replicación" +msgstr "Publicación" -#: describe.c:5271 +#: describe.c:5909 msgid "Synchronous commit" -msgstr "" +msgstr "Commit síncrono" -#: describe.c:5272 -#, fuzzy +#: describe.c:5910 msgid "Conninfo" -msgstr "Conexiones\n" +msgstr "Conninfo" -#: describe.c:5294 -#, fuzzy +#: describe.c:5932 msgid "List of subscriptions" -msgstr "Listado de funciones" - -#: help.c:62 -#, c-format -msgid "%s\n" -msgstr "%s\n" +msgstr "Listado de suscripciones" -#: help.c:73 +#: help.c:74 #, c-format msgid "" "psql is the PostgreSQL interactive terminal.\n" @@ -2082,12 +2243,12 @@ msgstr "" "psql es el terminal interactivo de PostgreSQL.\n" "\n" -#: help.c:74 help.c:344 help.c:378 help.c:405 +#: help.c:75 help.c:349 help.c:425 help.c:468 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: help.c:75 +#: help.c:76 #, c-format msgid "" " psql [OPTION]... [DBNAME [USERNAME]]\n" @@ -2096,34 +2257,34 @@ msgstr "" " psql [OPCIONES]... [BASE-DE-DATOS [USUARIO]]\n" "\n" -#: help.c:77 +#: help.c:78 #, c-format msgid "General options:\n" msgstr "Opciones generales:\n" -#: help.c:82 +#: help.c:83 #, c-format msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" msgstr " -c, --command=ORDEN ejecutar sólo una orden (SQL o interna) y salir\n" -#: help.c:83 +#: help.c:84 #, c-format msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" msgstr "" " -d, --dbname=NOMBRE nombre de base de datos a conectarse\n" " (por omisión: «%s»)\n" -#: help.c:84 +#: help.c:85 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" msgstr " -f, --file=ARCHIVO ejecutar órdenes desde archivo, luego salir\n" -#: help.c:85 +#: help.c:86 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr " -l, --list listar bases de datos, luego salir\n" -#: help.c:86 +#: help.c:87 #, c-format msgid "" " -v, --set=, --variable=NAME=VALUE\n" @@ -2134,17 +2295,17 @@ msgstr "" " definir variable de psql NOMBRE a VALOR\n" " (p.ej. -v ON_ERROR_STOP=1)\n" -#: help.c:89 +#: help.c:90 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión, luego salir\n" -#: help.c:90 +#: help.c:91 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" msgstr " -X, --no-psqlrc no leer archivo de configuración (~/.psqlrc)\n" -#: help.c:91 +#: help.c:92 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" @@ -2153,22 +2314,22 @@ msgstr "" " -1 («uno»), --single-transaction\n" " ejecuta órdenes en una única transacción\n" -#: help.c:93 +#: help.c:94 #, c-format msgid " -?, --help[=options] show this help, then exit\n" msgstr " -?, --help[=opcs] mostrar esta ayuda, luego salir\n" -#: help.c:94 +#: help.c:95 #, c-format msgid " --help=commands list backslash commands, then exit\n" msgstr " --help=commands listar órdenes backslash, luego salir\n" -#: help.c:95 +#: help.c:96 #, c-format msgid " --help=variables list special variables, then exit\n" msgstr " --help=variables listar variables especiales, luego salir\n" -#: help.c:97 +#: help.c:98 #, c-format msgid "" "\n" @@ -2177,57 +2338,57 @@ msgstr "" "\n" "Opciones de entrada y salida:\n" -#: help.c:98 +#: help.c:99 #, c-format msgid " -a, --echo-all echo all input from script\n" msgstr " -a, --echo-all mostrar las órdenes del script\n" -#: help.c:99 +#: help.c:100 #, c-format msgid " -b, --echo-errors echo failed commands\n" msgstr " -b, --echo-errors mostrar órdenes fallidas\n" -#: help.c:100 +#: help.c:101 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" msgstr " -e, --echo-queries mostrar órdenes enviadas al servidor\n" -#: help.c:101 +#: help.c:102 #, c-format msgid " -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden mostrar consultas generadas por órdenes internas\n" -#: help.c:102 +#: help.c:103 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" msgstr " -L, --log-file=ARCH envía el registro de la sesión a un archivo\n" -#: help.c:103 +#: help.c:104 #, c-format msgid " -n, --no-readline disable enhanced command line editing (readline)\n" msgstr " -n, --no-readline deshabilitar edición de línea de órdenes (readline)\n" -#: help.c:104 +#: help.c:105 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" msgstr " -o, --output=ARCHIVO enviar resultados de consultas a archivo (u |orden)\n" -#: help.c:105 +#: help.c:106 #, c-format msgid " -q, --quiet run quietly (no messages, only query output)\n" msgstr " -q, --quiet modo silencioso (sin mensajes, sólo resultados)\n" -#: help.c:106 +#: help.c:107 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" msgstr " -s, --single-step modo paso a paso (confirmar cada consulta)\n" -#: help.c:107 +#: help.c:108 #, c-format msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" msgstr " -S, --single-line modo de líneas (fin de línea termina la orden SQL)\n" -#: help.c:109 +#: help.c:110 #, c-format msgid "" "\n" @@ -2236,12 +2397,17 @@ msgstr "" "\n" "Opciones de formato de salida:\n" -#: help.c:110 +#: help.c:111 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align modo de salida desalineado\n" -#: help.c:111 +#: help.c:112 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv modo de salida de tabla CSV (valores separados por comas)\n" + +#: help.c:113 #, c-format msgid "" " -F, --field-separator=STRING\n" @@ -2250,17 +2416,17 @@ msgstr "" " -F, --field-separator=CADENA separador de campos para salida desalineada\n" " (por omisión: «%s»)\n" -#: help.c:114 +#: help.c:116 #, c-format msgid " -H, --html HTML table output mode\n" msgstr " -H, --html modo de salida en tablas HTML\n" -#: help.c:115 +#: help.c:117 #, c-format msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" msgstr " -P, --pset=VAR[=ARG] definir opción de impresión VAR en ARG (ver orden \\pset)\n" -#: help.c:116 +#: help.c:118 #, c-format msgid "" " -R, --record-separator=STRING\n" @@ -2269,24 +2435,24 @@ msgstr "" " -R, --record-separator=CADENA separador de registros para salida desalineada\n" " (por omisión: salto de línea)\n" -#: help.c:118 +#: help.c:120 #, c-format msgid " -t, --tuples-only print rows only\n" msgstr " -t, --tuples-only sólo muestra registros\n" -#: help.c:119 +#: help.c:121 #, c-format msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" msgstr "" " -T, --table-attr=TEXTO\n" " definir atributos de marcas de tabla HTML (ancho, borde)\n" -#: help.c:120 +#: help.c:122 #, c-format msgid " -x, --expanded turn on expanded table output\n" msgstr " -x, --expanded activar modo expandido de salida de tablas\n" -#: help.c:121 +#: help.c:123 #, c-format msgid "" " -z, --field-separator-zero\n" @@ -2295,7 +2461,7 @@ msgstr "" " -z, --field-separator-zero\n" " definir separador de campos para salida desalineada al byte cero\n" -#: help.c:123 +#: help.c:125 #, c-format msgid "" " -0, --record-separator-zero\n" @@ -2304,7 +2470,7 @@ msgstr "" " -0, --record-separator-zero\n" " definir separador de filas para salida desalineada al byte cero\n" -#: help.c:126 +#: help.c:128 #, c-format msgid "" "\n" @@ -2313,42 +2479,42 @@ msgstr "" "\n" "Opciones de conexión:\n" -#: help.c:129 +#: help.c:131 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" msgstr "" " -h, --host=NOMBRE nombre del anfitrión o directorio de socket\n" " (por omisión: «%s»)\n" -#: help.c:130 +#: help.c:132 msgid "local socket" msgstr "socket local" -#: help.c:133 +#: help.c:135 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" msgstr " -p, --port=PUERTO puerto del servidor (por omisión: «%s»)\n" -#: help.c:139 +#: help.c:141 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr "" " -U, --username=NOMBRE\n" " nombre de usuario (por omisión: «%s»)\n" -#: help.c:140 +#: help.c:142 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password nunca pedir contraseña\n" -#: help.c:141 +#: help.c:143 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr "" " -W, --password forzar petición de contraseña\n" " (debería ser automático)\n" -#: help.c:143 +#: help.c:145 #, c-format msgid "" "\n" @@ -2363,491 +2529,499 @@ msgstr "" "en la documentación de PostgreSQL.\n" "\n" -#: help.c:146 +#: help.c:148 #, c-format -msgid "Report bugs to .\n" -msgstr "Reporte errores a .\n" +msgid "Report bugs to .\n" +msgstr "Reporte errores a .\n" -#: help.c:172 +#: help.c:174 #, c-format msgid "General\n" msgstr "General\n" -#: help.c:173 +#: help.c:175 #, c-format msgid " \\copyright show PostgreSQL usage and distribution terms\n" msgstr " \\copyright mostrar términos de uso y distribución de PostgreSQL\n" -#: help.c:174 +#: help.c:176 #, c-format msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" msgstr " \\crosstabview [COLUMNAS] ejecutar la consulta y desplegar en «crosstab»\n" -#: help.c:175 +#: help.c:177 #, c-format msgid " \\errverbose show most recent error message at maximum verbosity\n" msgstr " \\errverbose mostrar error más reciente en máxima verbosidad\n" -#: help.c:176 +#: help.c:178 #, c-format msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" msgstr "" " \\g [ARCH] o ; enviar búfer de consulta al servidor\n" " (y resultados a archivo u |orden)\n" -#: help.c:177 +#: help.c:179 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc describir resultado de la consulta, sin ejecutarla\n" + +#: help.c:180 #, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr " \\gexec ejecutar la consulta, luego ejecuta cada valor del resultado\n" -#: help.c:178 +#: help.c:181 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr "" " \\gset [PREFIJO] ejecutar la consulta y almacenar los resultados en variables\n" " de psql\n" -#: help.c:179 -#, fuzzy, c-format +#: help.c:182 +#, c-format msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" -msgstr " \\a cambiar entre modo de salida alineado y sin alinear\n" +msgstr " \\gx [ARCHIVO] como \\g, pero fuerza modo de salida expandido\n" -#: help.c:180 +#: help.c:183 #, c-format msgid " \\q quit psql\n" msgstr " \\q salir de psql\n" -#: help.c:181 +#: help.c:184 #, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEGS] ejecutar consulta cada SEGS segundos\n" -#: help.c:184 +#: help.c:187 #, c-format msgid "Help\n" msgstr "Ayuda\n" -#: help.c:186 +#: help.c:189 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] desplegar ayuda sobre las órdenes backslash\n" -#: help.c:187 +#: help.c:190 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options desplegar ayuda sobre opciones de línea de órdenes\n" -#: help.c:188 +#: help.c:191 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables desplegar ayuda sobre variables especiales\n" -#: help.c:189 +#: help.c:192 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr "" " \\h [NOMBRE] mostrar ayuda de sintaxis de órdenes SQL;\n" " use «*» para todas las órdenes\n" -#: help.c:192 +#: help.c:195 #, c-format msgid "Query Buffer\n" msgstr "Búfer de consulta\n" -#: help.c:193 +#: help.c:196 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr "" " \\e [ARCHIVO] [LÃNEA]\n" " editar el búfer de consulta (o archivo) con editor externo\n" -#: help.c:194 +#: help.c:197 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr "" " \\ef [NOMBRE-FUNCIÓN [LÃNEA]]\n" " editar una función con editor externo\n" -#: help.c:195 +#: help.c:198 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr "" " \\ev [NOMBRE-VISTA [LÃNEA]]\n" " editar definición de una vista con editor externo\n" -#: help.c:196 +#: help.c:199 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p mostrar el contenido del búfer de consulta\n" -#: help.c:197 +#: help.c:200 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r reiniciar (limpiar) el búfer de consulta\n" -#: help.c:199 +#: help.c:202 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [ARCHIVO] mostrar historial de órdenes o guardarlo en archivo\n" -#: help.c:201 +#: help.c:204 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w ARCHIVO escribir búfer de consulta a archivo\n" -#: help.c:204 +#: help.c:207 #, c-format msgid "Input/Output\n" msgstr "Entrada/Salida\n" -#: help.c:205 +#: help.c:208 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr " \\copy ... ejecutar orden SQL COPY con flujo de datos al cliente\n" -#: help.c:206 +#: help.c:209 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [CADENA] escribir cadena a salida estándar\n" -#: help.c:207 +#: help.c:210 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i ARCHIVO ejecutar órdenes desde archivo\n" -#: help.c:208 +#: help.c:211 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr " \\ir ARCHIVO como \\i, pero relativo a la ubicación del script actual\n" -#: help.c:209 +#: help.c:212 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr " \\o [ARCHIVO] enviar resultados de consultas a archivo u |orden\n" -#: help.c:210 +#: help.c:213 #, c-format msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr " \\qecho [CADENA] escribir cadena a salida de consultas (ver \\o)\n" -#: help.c:213 -#, fuzzy, c-format +#: help.c:216 +#, c-format msgid "Conditional\n" -msgstr "condición" +msgstr "Condicional\n" -#: help.c:214 -#, fuzzy, c-format +#: help.c:217 +#, c-format msgid " \\if EXPR begin conditional block\n" -msgstr " \\i ARCHIVO ejecutar órdenes desde archivo\n" +msgstr " \\if EXPRESIÓN inicia bloque condicional\n" -#: help.c:215 -#, fuzzy, c-format +#: help.c:218 +#, c-format msgid " \\elif EXPR alternative within current conditional block\n" -msgstr " PORT puerto del servidor de la conexión actual\n" +msgstr " \\elif EXPR alternativa dentro del bloque condicional actual\n" -#: help.c:216 -#, fuzzy, c-format +#: help.c:219 +#, c-format msgid " \\else final alternative within current conditional block\n" -msgstr " \\ir ARCHIVO como \\i, pero relativo a la ubicación del script actual\n" +msgstr " \\else alternativa final dentro del bloque condicional actual\n" -#: help.c:217 -#, fuzzy, c-format +#: help.c:220 +#, c-format msgid " \\endif end conditional block\n" -msgstr " \\q salir de psql\n" +msgstr " \\endif termina el bloque condicional\n" -#: help.c:220 +#: help.c:223 #, c-format msgid "Informational\n" msgstr "Informativo\n" -#: help.c:221 +#: help.c:224 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (opciones: S = desplegar objectos de sistema, + = agregar más detalle)\n" -#: help.c:222 +#: help.c:225 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] listar tablas, vistas y secuencias\n" -#: help.c:223 +#: help.c:226 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NOMBRE describir tabla, índice, secuencia o vista\n" -#: help.c:224 +#: help.c:227 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [PATRÓN] listar funciones de agregación\n" -#: help.c:225 +#: help.c:228 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [PATRÓN] listar métodos de acceso\n" -#: help.c:226 +#: help.c:229 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [PATRÓN] listar tablespaces\n" -#: help.c:227 +#: help.c:230 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [PATRÓN] listar conversiones\n" -#: help.c:228 +#: help.c:231 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [PATRÓN] listar conversiones de tipo (casts)\n" -#: help.c:229 +#: help.c:232 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr " \\dd[S] [PATRÓN] listar comentarios de objetos que no aparecen en otra parte\n" -#: help.c:230 +#: help.c:233 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" msgstr " \\dD[S+] [PATRÓN] listar dominios\n" -#: help.c:231 +#: help.c:234 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [PATRÓN] listar privilegios por omisión\n" -#: help.c:232 +#: help.c:235 #, c-format msgid " \\dE[S+] [PATTERN] list foreign tables\n" msgstr " \\dE[S+] [PATRÓN] listar tablas foráneas\n" -#: help.c:233 +#: help.c:236 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [PATRÓN] listar tablas foráneas\n" -#: help.c:234 +#: help.c:237 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [PATRÓN] listar servidores foráneos\n" -#: help.c:235 +#: help.c:238 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [PATRÓN] listar mapeos de usuario\n" -#: help.c:236 +#: help.c:239 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [PATRÓN] listar conectores de datos externos\n" -#: help.c:237 +#: help.c:240 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [PATRÓN] listar funciones [sólo ag./normal/trigger/ventana]\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [PATRÓN] listar funciones [sólo ag./normal/proc./trigger/ventana]\n" -#: help.c:238 +#: help.c:241 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [PATRÓN] listar configuraciones de búsqueda en texto\n" -#: help.c:239 +#: help.c:242 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [PATRÓN] listar diccionarios de búsqueda en texto\n" -#: help.c:240 +#: help.c:243 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [PATRÓN] listar analizadores (parsers) de búsq. en texto\n" -#: help.c:241 +#: help.c:244 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [PATRÓN] listar plantillas de búsqueda en texto\n" -#: help.c:242 +#: help.c:245 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [PATRÓN] listar roles\n" -#: help.c:243 +#: help.c:246 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [PATRÓN] listar índices\n" -#: help.c:244 +#: help.c:247 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl listar objetos grandes, lo mismo que \\lo_list\n" -#: help.c:245 +#: help.c:248 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [PATRÓN] listar lenguajes procedurales\n" -#: help.c:246 +#: help.c:249 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [PATRÓN] listar vistas materializadas\n" -#: help.c:247 +#: help.c:250 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [PATRÓN] listar esquemas\n" -#: help.c:248 +#: help.c:251 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [PATRÓN] listar operadores\n" -#: help.c:249 +#: help.c:252 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S] [PATRÓN] listar ordenamientos (collations)\n" -#: help.c:250 +#: help.c:253 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr " \\dp [PATRÓN] listar privilegios de acceso a tablas, vistas y secuencias\n" -#: help.c:251 +#: help.c:254 +#, c-format +msgid " \\dP[tin+] [PATTERN] list [only table/index] partitioned relations\n" +msgstr " \\dP[tin+] [PATRÓN] listar relaciones particionadas (sólo tablas/índices)\n" + +#: help.c:255 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [PAT1 [PAT2]] listar parámetros de rol por base de datos\n" -#: help.c:252 -#, fuzzy, c-format +#: help.c:256 +#, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" -msgstr " \\dO[S] [PATRÓN] listar ordenamientos (collations)\n" +msgstr " \\dRp[+] [PATRÓN] listar publicaciones de replicación\n" -#: help.c:253 -#, fuzzy, c-format +#: help.c:257 +#, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" -msgstr " \\dx[+] [PATRÓN] listar extensiones\n" +msgstr " \\dRs[+] [PATRÓN] listar suscripciones de replicación\n" -#: help.c:254 +#: help.c:258 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [PATRÓN] listar secuencias\n" -#: help.c:255 +#: help.c:259 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [PATRÓN] listar tablas\n" -#: help.c:256 +#: help.c:260 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [PATRÓN] listar tipos de dato\n" -#: help.c:257 +#: help.c:261 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [PATRÓN] listar roles\n" -#: help.c:258 +#: help.c:262 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [PATRÓN] listar vistas\n" -#: help.c:259 +#: help.c:263 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [PATRÓN] listar extensiones\n" -#: help.c:260 +#: help.c:264 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [PATRÓN] listar disparadores por eventos\n" -#: help.c:261 +#: help.c:265 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [PATRÓN] listar bases de datos\n" -#: help.c:262 +#: help.c:266 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNCIÓN mostrar la definición de una función\n" -#: help.c:263 +#: help.c:267 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] VISTA mostrar la definición de una vista\n" -#: help.c:264 +#: help.c:268 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [PATRÓN] lo mismo que \\dp\n" -#: help.c:267 +#: help.c:271 #, c-format msgid "Formatting\n" msgstr "Formato\n" -#: help.c:268 +#: help.c:272 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr " \\a cambiar entre modo de salida alineado y sin alinear\n" -#: help.c:269 +#: help.c:273 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr " \\C [CADENA] definir título de tabla, o indefinir si es vacío\n" -#: help.c:270 +#: help.c:274 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr "" " \\f [CADENA] mostrar o definir separador de campos para\n" " modo de salida sin alinear\n" -#: help.c:271 +#: help.c:275 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H cambiar modo de salida HTML (actualmente %s)\n" -#: help.c:273 -#, fuzzy, c-format -#| msgid "" -#| " \\pset [NAME [VALUE]] set table output option\n" -#| " (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -#| " numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -#| " unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +#: help.c:277 +#, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" -" footer|format|linestyle|null|numericlocale|pager|\n" -" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" -" tuples_only|unicode_border_linestyle|\n" -" unicode_column_linestyle|unicode_header_linestyle})\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" msgstr "" -" \\pset [NOMBRE [VALOR]] define opción de salida de tabla\n" -" (NOMBRE := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +" \\pset [NOMBRE [VALOR]] define opción de tabla de salida\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|unicode_column_linestyle\n" +" |unicode_header_linestyle)\n" -#: help.c:279 +#: help.c:284 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] mostrar sólo filas (actualmente %s)\n" -#: help.c:281 +#: help.c:286 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr " \\T [CADENA] definir atributos HTML de
, o indefinir si es vacío\n" -#: help.c:282 +#: help.c:287 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] cambiar modo expandido (actualmente %s)\n" -#: help.c:286 +#: help.c:291 #, c-format msgid "Connection\n" msgstr "Conexiones\n" -#: help.c:288 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2856,7 +3030,7 @@ msgstr "" " \\c[onnect] [BASE-DE-DATOS|- USUARIO|- ANFITRIÓN|- PUERTO|- | conninfo]\n" " conectar a una nueva base de datos (actual: «%s»)\n" -#: help.c:292 +#: help.c:297 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2865,84 +3039,84 @@ msgstr "" " \\c[onnect] [BASE-DE-DATOS|- USUARIO|- ANFITRIÓN|- PUERTO|- | conninfo]\n" " conectar a una nueva base de datos (no hay conexión actual)\n" -#: help.c:294 +#: help.c:299 #, c-format msgid " \\conninfo display information about current connection\n" msgstr " \\conninfo despliega la información sobre la conexión actual\n" -#: help.c:295 +#: help.c:300 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr "" " \\encoding [CODIFICACIÓN]\n" " mostrar o definir codificación del cliente\n" -#: help.c:296 +#: help.c:301 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr "" " \\password [USUARIO]\n" " cambiar la contraseña para un usuario en forma segura\n" -#: help.c:299 +#: help.c:304 #, c-format msgid "Operating System\n" msgstr "Sistema Operativo\n" -#: help.c:300 +#: help.c:305 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [DIR] cambiar el directorio de trabajo actual\n" -#: help.c:301 +#: help.c:306 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr "" " \\setenv NOMBRE [VALOR]\n" " definir o indefinir variable de ambiente\n" -#: help.c:302 +#: help.c:307 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr "" " \\timing [on|off] mostrar tiempo de ejecución de órdenes\n" " (actualmente %s)\n" -#: help.c:304 +#: help.c:309 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr "" " \\! [ORDEN] ejecutar orden en intérprete de órdenes (shell),\n" " o iniciar intérprete interactivo\n" -#: help.c:307 +#: help.c:312 #, c-format msgid "Variables\n" msgstr "Variables\n" -#: help.c:308 +#: help.c:313 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr " \\prompt [TEXTO] NOMBRE preguntar al usuario el valor de la variable\n" -#: help.c:309 +#: help.c:314 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr "" " \\set [NOMBRE [VALOR]] definir variables internas,\n" " listar todas si no se dan parámetros\n" -#: help.c:310 +#: help.c:315 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NOMBRE indefinir (eliminar) variable interna\n" -#: help.c:313 +#: help.c:318 #, c-format msgid "Large Objects\n" msgstr "Objetos Grandes\n" -#: help.c:314 +#: help.c:319 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2955,7 +3129,7 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID operaciones con objetos grandes\n" -#: help.c:341 +#: help.c:346 #, c-format msgid "" "List of specially treated variables\n" @@ -2964,12 +3138,12 @@ msgstr "" "Lista de variables con tratamiento especial\n" "\n" -#: help.c:343 +#: help.c:348 #, c-format msgid "psql variables:\n" msgstr "Variables psql:\n" -#: help.c:345 +#: help.c:350 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -2979,160 +3153,275 @@ msgstr "" " psql --set=NOMBRE=VALOR\n" " o \\set NOMBRE VALOR dentro de psql\n" -#: help.c:347 +#: help.c:352 #, c-format -msgid " AUTOCOMMIT if set, successful SQL commands are automatically committed\n" +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" msgstr "" " AUTOCOMMIT si está definida, órdenes SQL exitosas se comprometen\n" " automáticamente\n" -#: help.c:348 +#: help.c:354 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" " COMP_KEYWORD_CASE determina si usar mayúsculas al completar palabras SQL\n" " [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:350 +#: help.c:357 #, c-format -msgid " DBNAME the currently connected database name\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" msgstr " DBNAME la base de datos actualmente conectada\n" -#: help.c:351 +#: help.c:359 #, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" " ECHO controla qué entrada se escribe a la salida estándar\n" " [all, errors, none, queries]\n" -#: help.c:353 +#: help.c:362 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash commands;\n" -" if set to \"noexec\", just show without execution\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" " ECHO_HIDDEN muestra consultas internas usadas por órdenes backslash\n" -" con [noexec] sólo las muestra sin ejecutarlas\n" +" con «noexec» sólo las muestra sin ejecutarlas\n" -#: help.c:355 +#: help.c:365 #, c-format -msgid " ENCODING current client character set encoding\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" msgstr " ENCODING codificación actual del cliente\n" -#: help.c:356 +#: help.c:367 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a time\n" -" (default: 0=unlimited)\n" +" ERROR\n" +" true if last query failed, else false\n" +msgstr " ERROR verdadero si la última consulta falló; si no, falso\n" + +#: help.c:369 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" msgstr "" " FETCH_COUNT número de filas del resultado que extraer y mostrar cada vez\n" " (por omisión: 0=sin límite)\n" -#: help.c:358 +#: help.c:371 +#, c-format +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" ocultar métodos de acceso de tabla\n" + +#: help.c:373 #, c-format -msgid " HISTCONTROL controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" msgstr "" " HISTCONTROL controla la lista de historia de órdenes\n" " [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:359 +#: help.c:375 #, c-format -msgid " HISTFILE file name used to store the command history\n" +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" msgstr " HISTFILE nombre de archivo para almacenar historia de órdenes\n" -#: help.c:360 -#, fuzzy, c-format -msgid " HISTSIZE max number of commands to store in the command history\n" +#: help.c:377 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" msgstr " HISTSIZE número de órdenes a guardar en la historia de órdenes\n" -#: help.c:361 +#: help.c:379 #, c-format -msgid " HOST the currently connected database server host\n" +msgid "" +" HOST\n" +" the currently connected database server host\n" msgstr " HOST el servidor actualmente conectado\n" -#: help.c:362 -#, fuzzy, c-format -msgid " IGNOREEOF number of EOFs needed to terminate an interactive session\n" +#: help.c:381 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" msgstr "" " IGNOREEOF si no está definida, enviar un EOF a sesión interactiva\n" " termina la aplicación\n" -#: help.c:363 +#: help.c:383 #, c-format -msgid " LASTOID value of the last affected OID\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" msgstr " LASTOID el valor del último OID afectado\n" -#: help.c:364 +#: help.c:385 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" mensaje y SQLSTATE del último error, o cadena vacía y\n" +" «00000» si no hubo\n" + +#: help.c:388 #, c-format -msgid " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" msgstr "" " ON_ERROR_ROLLBACK si está definido, un error no aborta la transacción\n" " (usa «savepoints» implícitos)\n" -#: help.c:365 +#: help.c:390 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" msgstr " ON_ERROR_STOP detiene ejecución por lotes al ocurrir un error\n" -#: help.c:366 +#: help.c:392 #, c-format -msgid " PORT server port of the current connection\n" +msgid "" +" PORT\n" +" server port of the current connection\n" msgstr " PORT puerto del servidor de la conexión actual\n" -#: help.c:367 +#: help.c:394 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" msgstr " PROMPT1 especifica el prompt estándar de psql\n" -#: help.c:368 +#: help.c:396 #, c-format -msgid " PROMPT2 specifies the prompt used when a statement continues from a previous line\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" msgstr "" " PROMPT2 especifica el prompt usado cuando una sentencia continúa\n" " de una línea anterior\n" -#: help.c:369 +#: help.c:398 #, c-format -msgid " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" msgstr " PROMPT3 especifica el prompt usado durante COPY ... FROM STDIN\n" -#: help.c:370 +#: help.c:400 #, c-format -msgid " QUIET run quietly (same as -q option)\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" msgstr " QUIET ejecuta silenciosamente (igual que -q)\n" -#: help.c:371 +#: help.c:402 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT número de tuplas retornadas o afectadas por última\n" +" consulta, o 0\n" + +#: help.c:404 #, c-format -msgid " SHOW_CONTEXT controls display of message context fields [never, errors, always]\n" +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" versión del servidor (cadena corta o numérica)\n" + +#: help.c:407 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" msgstr "" " SHOW_CONTEXT controla el despliegue de campos de contexto de mensaje\n" " [never, errors, always]\n" -#: help.c:372 +#: help.c:409 #, c-format -msgid " SINGLELINE end of line terminates SQL command mode (same as -S option)\n" +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" msgstr " SINGLELINE fin de línea termina modo de órdenes SQL (igual que -S)\n" -#: help.c:373 +#: help.c:411 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" msgstr " SINGLESTEP modo paso a paso (igual que -s)\n" -#: help.c:374 +#: help.c:413 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr " SQLSTATE SQLSTATE de la última consulta, o «00000» si no hubo error\n" + +#: help.c:415 #, c-format -msgid " USER the currently connected database user\n" +msgid "" +" USER\n" +" the currently connected database user\n" msgstr " USER el usuario actualmente conectado\n" -#: help.c:375 +#: help.c:417 #, c-format -msgid " VERBOSITY controls verbosity of error reports [default, verbose, terse]\n" -msgstr " VERBOSITY controla la verbosidad de errores [default, verbose, terse]\n" +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY controla la verbosidad de errores [default, verbose,\n" +" terse, sqlstate]\n" -#: help.c:377 +#: help.c:419 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" versión de psql (cadena verbosa, corta o numérica)\n" + +#: help.c:424 #, c-format msgid "" "\n" @@ -3141,7 +3430,7 @@ msgstr "" "\n" "Parámetros de despliegue:\n" -#: help.c:379 +#: help.c:426 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3152,112 +3441,141 @@ msgstr "" " o \\pset NOMBRE [VALOR] dentro de psql\n" "\n" -#: help.c:381 +#: help.c:428 #, c-format -msgid " border border style (number)\n" +msgid "" +" border\n" +" border style (number)\n" msgstr " border estilo de borde (número)\n" -#: help.c:382 +#: help.c:430 #, c-format -msgid " columns target width for the wrapped format\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" msgstr " columns define el ancho para formato «wrapped»\n" -#: help.c:383 +#: help.c:432 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" msgstr " expanded (o x) salida expandida [on, off, auto]\n" -#: help.c:384 +#: help.c:434 #, c-format -msgid " fieldsep field separator for unaligned output (default \"%s\")\n" +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" msgstr "" " fieldsep separador de campos para formato «unaligned»\n" " (por omisión: «%s»)\n" -#: help.c:385 +#: help.c:437 #, c-format -msgid " fieldsep_zero set field separator for unaligned output to zero byte\n" +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" msgstr " fieldsep_zero separador de campos en «unaligned» es byte cero\n" -#: help.c:386 +#: help.c:439 #, c-format -msgid " footer enable or disable display of the table footer [on, off]\n" +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" msgstr " footer activa o desactiva el pie de tabla [on, off]\n" -#: help.c:387 +#: help.c:441 #, c-format -msgid " format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" msgstr " format define el formato de salida [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:388 +#: help.c:443 #, c-format -msgid " linestyle set the border line drawing style [ascii, old-ascii, unicode]\n" +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" msgstr " linestyle define el estilo de dibujo de líneas [ascii, old-ascii, unicode]\n" -#: help.c:389 +#: help.c:445 #, c-format -msgid " null set the string to be printed in place of a null value\n" +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" msgstr " null define la cadena a imprimirse para valores null\n" -#: help.c:390 +#: help.c:447 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale activa o desactiva despliegue de carácter específico del lenguaje para\n" -" separar grupos de dígitos [on, off]\n" +" numericlocale activa despliegue de carácter específico del lenguaje para\n" +" separar grupos de dígitos\n" -#: help.c:392 +#: help.c:449 #, c-format -msgid " pager control when an external pager is used [yes, no, always]\n" +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" msgstr " pager controla cuándo se usará un paginador externo [yes, no, always]\n" -#: help.c:393 +#: help.c:451 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" msgstr " recordsep separador de registros (líneas) para formato «unaligned»\n" -#: help.c:394 +#: help.c:453 #, c-format -msgid " recordsep_zero set record separator for unaligned output to zero byte\n" +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" msgstr " recordsep_zero separador de registros en «unaligned» es byte cero\n" # XXX WTF does this mean? -#: help.c:395 +#: help.c:455 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or proportional\n" -" column widths for left-aligned data types in latex-longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" " tableattr (o T) especifica atributos para el tag «table» en formato «html»,\n" " o ancho proporcional de columnas alineadas a la izquierda\n" " en formato «latex-longtable»\n" -#: help.c:397 +#: help.c:458 #, c-format -msgid " title set the table title for any subsequently printed tables\n" +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" msgstr " title define el título de tablas\n" -#: help.c:398 +#: help.c:460 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" msgstr " tuples_only si está definido, sólo los datos de la tabla se muestran\n" -#: help.c:399 +#: help.c:462 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" " define el estilo de líneas Unicode [single, double]\n" -#: help.c:404 +#: help.c:467 #, c-format msgid "" "\n" @@ -3266,7 +3584,7 @@ msgstr "" "\n" "Variables de ambiente:\n" -#: help.c:408 +#: help.c:471 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3276,7 +3594,7 @@ msgstr "" " NOMBRE=VALOR [NOMBRE=VALOR] psql ...\n" " o \\setenv NOMBRE [VALOR] dentro de psql\n" -#: help.c:410 +#: help.c:473 #, c-format msgid "" " set NAME=VALUE\n" @@ -3288,94 +3606,120 @@ msgstr "" " psql ...\n" " o \\setenv NOMBRE [VALOR] dentro de psql\n" -#: help.c:413 +#: help.c:476 #, c-format -msgid " COLUMNS number of columns for wrapped format\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" msgstr " COLUMNS número de columnas para formato «wrapped»\n" -#: help.c:414 -#, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER nombre de programa paginador externo\n" - -#: help.c:415 +#: help.c:478 #, c-format -msgid " PGAPPNAME same as the application_name connection parameter\n" +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" msgstr " PGAPPNAME igual que el parámetro de conexión application_name\n" -#: help.c:416 +#: help.c:480 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" msgstr " PGDATABASE igual que el parámetro de conexión dbname\n" -#: help.c:417 +#: help.c:482 #, c-format -msgid " PGHOST same as the host connection parameter\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" msgstr " PGHOST igual que el parámetro de conexión host\n" -#: help.c:418 +#: help.c:484 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" msgstr " PGPASSWORD contraseña de la conexión (no recomendado)\n" -#: help.c:419 +#: help.c:486 #, c-format -msgid " PGPASSFILE password file name\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" msgstr " PGPASSFILE nombre de archivo de contraseñas\n" -#: help.c:420 +#: help.c:488 #, c-format -msgid " PGPORT same as the port connection parameter\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" msgstr " PGPORT igual que el parámetro de conexión port\n" -#: help.c:421 +#: help.c:490 #, c-format -msgid " PGUSER same as the user connection parameter\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" msgstr " PGUSER igual que el parámetro de conexión user\n" -#: help.c:422 +#: help.c:492 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" " editor usado por órdenes \\e, \\ef, y \\ev\n" -#: help.c:424 +#: help.c:494 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARGS\n" " cómo especificar número de línea al invocar al editor\n" -#: help.c:426 +#: help.c:496 #, c-format -msgid " PSQL_HISTORY alternative location for the command history file\n" +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" msgstr " PSQL_HISTORY ubicación alternativa del archivo de historia de órdenes\n" -#: help.c:427 +#: help.c:498 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr " PSQL_PAGER, PAGER nombre de programa paginador externo\n" + +#: help.c:500 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" msgstr " PSQLRC ubicación alternativa para el archivo .psqlrc del usuario\n" -#: help.c:428 +#: help.c:502 #, c-format -msgid " SHELL shell used by the \\! command\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" msgstr " SHELL intérprete usado por la orden \\!\n" -#: help.c:429 +#: help.c:504 #, c-format -msgid " TMPDIR directory for temporary files\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" msgstr " TMPDIR directorio para archivos temporales\n" -#: help.c:472 +#: help.c:548 msgid "Available help:\n" msgstr "Ayuda disponible:\n" -#: help.c:556 +#: help.c:636 #, c-format msgid "" "Command: %s\n" @@ -3383,14 +3727,18 @@ msgid "" "Syntax:\n" "%s\n" "\n" +"URL: %s\n" +"\n" msgstr "" "Orden: %s\n" "Descripción: %s\n" "Sintaxis:\n" "%s\n" "\n" +"URL: %s\n" +"\n" -#: help.c:572 +#: help.c:655 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3399,48 +3747,48 @@ msgstr "" "No hay ayuda disponible para «%s».\n" "Pruebe \\h sin argumentos para mostrar los elementos de ayuda disponibles.\n" -#: input.c:216 +#: input.c:218 #, c-format -msgid "could not read from input file: %s\n" -msgstr "no se pudo leer el archivo de entrada: %s\n" +msgid "could not read from input file: %m" +msgstr "no se pudo leer el archivo de entrada: %m" -#: input.c:471 input.c:510 +#: input.c:472 input.c:510 #, c-format -msgid "could not save history to file \"%s\": %s\n" -msgstr "no se pudo guardar historial a archivo «%s»: %s\n" +msgid "could not save history to file \"%s\": %m" +msgstr "no se pudo guardar historial a archivo «%s»: %m" -#: input.c:530 +#: input.c:529 #, c-format -msgid "history is not supported by this installation\n" -msgstr "el historial de órdenes no está soportado en esta instalación\n" +msgid "history is not supported by this installation" +msgstr "el historial de órdenes no está soportado en esta instalación" -#: large_obj.c:64 +#: large_obj.c:65 #, c-format -msgid "%s: not connected to a database\n" -msgstr "%s: no está conectado a una base de datos\n" +msgid "%s: not connected to a database" +msgstr "%s: no está conectado a una base de datos" -#: large_obj.c:83 +#: large_obj.c:84 #, c-format -msgid "%s: current transaction is aborted\n" -msgstr "%s: transacción en curso está abortada\n" +msgid "%s: current transaction is aborted" +msgstr "%s: transacción en curso está abortada" -#: large_obj.c:86 +#: large_obj.c:87 #, c-format -msgid "%s: unknown transaction status\n" -msgstr "%s: estado de transacción desconocido\n" +msgid "%s: unknown transaction status" +msgstr "%s: estado de transacción desconocido" -#: large_obj.c:287 large_obj.c:298 +#: large_obj.c:288 large_obj.c:299 msgid "ID" msgstr "ID" -#: large_obj.c:308 +#: large_obj.c:309 msgid "Large objects" msgstr "Objetos grandes" #: mainloop.c:136 #, c-format -msgid "\\if: escaped\n" -msgstr "" +msgid "\\if: escaped" +msgstr "\\if: escapado" #: mainloop.c:183 #, c-format @@ -3455,11 +3803,19 @@ msgstr "" "La entrada es un dump de PostgreSQL en formato custom.\n" "Use el programa pg_restore para restaurar este dump a una base de datos.\n" -#: mainloop.c:225 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Use \\? para ayuda o presione control-C para limpiar el búfer de entrada." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Digite \\? para obtener ayuda." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Está usando psql, la interfaz de línea de órdenes de PostgreSQL." -#: mainloop.c:226 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3474,2212 +3830,2292 @@ msgstr "" " \\g o punto y coma («;») para ejecutar la consulta\n" " \\q para salir\n" -#: mainloop.c:339 mainloop.c:476 -#, c-format -msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" -msgstr "" - -#: mainloop.c:494 -#, c-format -msgid "reached EOF without finding closing \\endif(s)\n" -msgstr "" - -#: psqlscanslash.l:614 -#, c-format -msgid "unterminated quoted string\n" -msgstr "cadena en comillas sin terminar\n" - -#: psqlscanslash.l:787 -#, c-format -msgid "%s: out of memory\n" -msgstr "%s: memoria agotada\n" - -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 -#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 -#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 -#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 -#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 -#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 -#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 -#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 -#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 -#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 -#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 -#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 -#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 -#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:807 -#: sql_help.c:809 sql_help.c:811 sql_help.c:813 sql_help.c:816 sql_help.c:818 -#: sql_help.c:859 sql_help.c:882 sql_help.c:893 sql_help.c:895 sql_help.c:914 -#: sql_help.c:924 sql_help.c:926 sql_help.c:928 sql_help.c:940 sql_help.c:944 -#: sql_help.c:946 sql_help.c:957 sql_help.c:959 sql_help.c:961 sql_help.c:977 -#: sql_help.c:979 sql_help.c:983 sql_help.c:986 sql_help.c:987 sql_help.c:988 -#: sql_help.c:991 sql_help.c:993 sql_help.c:1084 sql_help.c:1086 -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 -#: sql_help.c:1099 sql_help.c:1102 sql_help.c:1168 sql_help.c:1170 -#: sql_help.c:1172 sql_help.c:1175 sql_help.c:1196 sql_help.c:1199 -#: sql_help.c:1202 sql_help.c:1205 sql_help.c:1209 sql_help.c:1211 -#: sql_help.c:1213 sql_help.c:1215 sql_help.c:1229 sql_help.c:1232 -#: sql_help.c:1234 sql_help.c:1236 sql_help.c:1246 sql_help.c:1248 -#: sql_help.c:1258 sql_help.c:1260 sql_help.c:1270 sql_help.c:1273 -#: sql_help.c:1295 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 -#: sql_help.c:1304 sql_help.c:1306 sql_help.c:1309 sql_help.c:1359 -#: sql_help.c:1397 sql_help.c:1400 sql_help.c:1402 sql_help.c:1404 -#: sql_help.c:1406 sql_help.c:1408 sql_help.c:1411 sql_help.c:1451 -#: sql_help.c:1662 sql_help.c:1726 sql_help.c:1745 sql_help.c:1758 -#: sql_help.c:1814 sql_help.c:1820 sql_help.c:1830 sql_help.c:1850 -#: sql_help.c:1875 sql_help.c:1893 sql_help.c:1922 sql_help.c:2015 -#: sql_help.c:2057 sql_help.c:2079 sql_help.c:2099 sql_help.c:2100 -#: sql_help.c:2135 sql_help.c:2155 sql_help.c:2177 sql_help.c:2191 -#: sql_help.c:2206 sql_help.c:2236 sql_help.c:2261 sql_help.c:2307 -#: sql_help.c:2573 sql_help.c:2586 sql_help.c:2603 sql_help.c:2619 -#: sql_help.c:2659 sql_help.c:2711 sql_help.c:2715 sql_help.c:2717 -#: sql_help.c:2723 sql_help.c:2741 sql_help.c:2768 sql_help.c:2803 -#: sql_help.c:2815 sql_help.c:2824 sql_help.c:2868 sql_help.c:2882 -#: sql_help.c:2910 sql_help.c:2918 sql_help.c:2926 sql_help.c:2934 -#: sql_help.c:2942 sql_help.c:2950 sql_help.c:2958 sql_help.c:2966 -#: sql_help.c:2975 sql_help.c:2986 sql_help.c:2994 sql_help.c:3002 -#: sql_help.c:3010 sql_help.c:3018 sql_help.c:3028 sql_help.c:3037 -#: sql_help.c:3046 sql_help.c:3054 sql_help.c:3063 sql_help.c:3071 -#: sql_help.c:3079 sql_help.c:3088 sql_help.c:3096 sql_help.c:3104 -#: sql_help.c:3112 sql_help.c:3120 sql_help.c:3128 sql_help.c:3136 -#: sql_help.c:3144 sql_help.c:3152 sql_help.c:3160 sql_help.c:3168 -#: sql_help.c:3185 sql_help.c:3194 sql_help.c:3202 sql_help.c:3219 -#: sql_help.c:3234 sql_help.c:3502 sql_help.c:3553 sql_help.c:3582 -#: sql_help.c:3590 sql_help.c:4013 sql_help.c:4061 sql_help.c:4202 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Use \\q para salir." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Use control-D para salir." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Use control-C para salir." + +#: mainloop.c:449 mainloop.c:591 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "consulta ignorada; use \\endif o Ctrl-C para salir del bloque \\if actual" + +#: mainloop.c:609 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "se alcanzó EOF sin encontrar el/los \\endif de cierre" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "una cadena de caracteres entre comillas está inconclusa" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: memoria agotada" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1089 sql_help.c:1091 sql_help.c:1093 sql_help.c:1109 +#: sql_help.c:1111 sql_help.c:1115 sql_help.c:1118 sql_help.c:1119 +#: sql_help.c:1120 sql_help.c:1123 sql_help.c:1125 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1384 +#: sql_help.c:1386 sql_help.c:1388 sql_help.c:1391 sql_help.c:1412 +#: sql_help.c:1415 sql_help.c:1418 sql_help.c:1421 sql_help.c:1425 +#: sql_help.c:1427 sql_help.c:1429 sql_help.c:1431 sql_help.c:1445 +#: sql_help.c:1448 sql_help.c:1450 sql_help.c:1452 sql_help.c:1462 +#: sql_help.c:1464 sql_help.c:1474 sql_help.c:1476 sql_help.c:1486 +#: sql_help.c:1489 sql_help.c:1511 sql_help.c:1513 sql_help.c:1515 +#: sql_help.c:1518 sql_help.c:1520 sql_help.c:1522 sql_help.c:1525 +#: sql_help.c:1575 sql_help.c:1617 sql_help.c:1620 sql_help.c:1622 +#: sql_help.c:1624 sql_help.c:1626 sql_help.c:1628 sql_help.c:1631 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2076 sql_help.c:2083 +#: sql_help.c:2093 sql_help.c:2113 sql_help.c:2138 sql_help.c:2156 +#: sql_help.c:2185 sql_help.c:2280 sql_help.c:2322 sql_help.c:2345 +#: sql_help.c:2366 sql_help.c:2367 sql_help.c:2404 sql_help.c:2424 +#: sql_help.c:2446 sql_help.c:2460 sql_help.c:2480 sql_help.c:2503 +#: sql_help.c:2533 sql_help.c:2558 sql_help.c:2604 sql_help.c:2882 +#: sql_help.c:2895 sql_help.c:2912 sql_help.c:2928 sql_help.c:2968 +#: sql_help.c:3020 sql_help.c:3024 sql_help.c:3026 sql_help.c:3032 +#: sql_help.c:3050 sql_help.c:3077 sql_help.c:3112 sql_help.c:3124 +#: sql_help.c:3133 sql_help.c:3177 sql_help.c:3191 sql_help.c:3219 +#: sql_help.c:3227 sql_help.c:3235 sql_help.c:3243 sql_help.c:3251 +#: sql_help.c:3259 sql_help.c:3267 sql_help.c:3275 sql_help.c:3284 +#: sql_help.c:3295 sql_help.c:3303 sql_help.c:3311 sql_help.c:3319 +#: sql_help.c:3327 sql_help.c:3337 sql_help.c:3346 sql_help.c:3355 +#: sql_help.c:3363 sql_help.c:3373 sql_help.c:3384 sql_help.c:3392 +#: sql_help.c:3401 sql_help.c:3412 sql_help.c:3421 sql_help.c:3429 +#: sql_help.c:3437 sql_help.c:3445 sql_help.c:3453 sql_help.c:3461 +#: sql_help.c:3469 sql_help.c:3477 sql_help.c:3485 sql_help.c:3493 +#: sql_help.c:3501 sql_help.c:3518 sql_help.c:3527 sql_help.c:3535 +#: sql_help.c:3552 sql_help.c:3567 sql_help.c:3837 sql_help.c:3888 +#: sql_help.c:3917 sql_help.c:3925 sql_help.c:4358 sql_help.c:4406 +#: sql_help.c:4547 msgid "name" msgstr "nombre" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1520 -#: sql_help.c:2883 sql_help.c:3807 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3192 sql_help.c:4144 msgid "aggregate_signature" msgstr "signatura_func_agregación" -#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 -#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 -#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 -#: sql_help.c:789 sql_help.c:819 sql_help.c:860 sql_help.c:884 sql_help.c:894 -#: sql_help.c:927 sql_help.c:947 sql_help.c:960 sql_help.c:994 sql_help.c:1093 -#: sql_help.c:1169 sql_help.c:1212 sql_help.c:1233 sql_help.c:1247 -#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1303 sql_help.c:1360 -#: sql_help.c:1405 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1092 sql_help.c:1126 sql_help.c:1266 sql_help.c:1385 +#: sql_help.c:1428 sql_help.c:1449 sql_help.c:1463 sql_help.c:1475 +#: sql_help.c:1488 sql_help.c:1519 sql_help.c:1576 sql_help.c:1625 msgid "new_name" msgstr "nuevo_nombre" -#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 -#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 -#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 -#: sql_help.c:817 sql_help.c:896 sql_help.c:925 sql_help.c:945 sql_help.c:958 -#: sql_help.c:992 sql_help.c:1153 sql_help.c:1171 sql_help.c:1214 -#: sql_help.c:1235 sql_help.c:1298 sql_help.c:1403 sql_help.c:2559 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1090 sql_help.c:1124 sql_help.c:1326 +#: sql_help.c:1387 sql_help.c:1430 sql_help.c:1451 sql_help.c:1514 +#: sql_help.c:1623 sql_help.c:2868 msgid "new_owner" msgstr "nuevo_dueño" -#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 -#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 -#: sql_help.c:774 sql_help.c:929 sql_help.c:962 sql_help.c:1095 -#: sql_help.c:1216 sql_help.c:1237 sql_help.c:1249 sql_help.c:1261 -#: sql_help.c:1305 sql_help.c:1407 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1094 +#: sql_help.c:1268 sql_help.c:1432 sql_help.c:1453 sql_help.c:1465 +#: sql_help.c:1477 sql_help.c:1521 sql_help.c:1627 msgid "new_schema" msgstr "nuevo_esquema" -#: sql_help.c:45 sql_help.c:1576 sql_help.c:2884 sql_help.c:3828 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3193 sql_help.c:4173 msgid "where aggregate_signature is:" msgstr "donde signatura_func_agregación es:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 -#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 -#: sql_help.c:522 sql_help.c:527 sql_help.c:1538 sql_help.c:1577 -#: sql_help.c:1580 sql_help.c:1583 sql_help.c:1727 sql_help.c:1746 -#: sql_help.c:1749 sql_help.c:2016 sql_help.c:2885 sql_help.c:2888 -#: sql_help.c:2891 sql_help.c:2976 sql_help.c:3387 sql_help.c:3720 -#: sql_help.c:3813 sql_help.c:3829 sql_help.c:3832 sql_help.c:3835 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2281 sql_help.c:2481 sql_help.c:3194 sql_help.c:3197 +#: sql_help.c:3200 sql_help.c:3285 sql_help.c:3374 sql_help.c:3402 +#: sql_help.c:3722 sql_help.c:4055 sql_help.c:4150 sql_help.c:4157 +#: sql_help.c:4163 sql_help.c:4174 sql_help.c:4177 sql_help.c:4180 msgid "argmode" msgstr "modo_arg" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 -#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 -#: sql_help.c:523 sql_help.c:528 sql_help.c:1539 sql_help.c:1578 -#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1728 sql_help.c:1747 -#: sql_help.c:1750 sql_help.c:2017 sql_help.c:2886 sql_help.c:2889 -#: sql_help.c:2892 sql_help.c:2977 sql_help.c:3814 sql_help.c:3830 -#: sql_help.c:3833 sql_help.c:3836 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2282 sql_help.c:2482 sql_help.c:3195 sql_help.c:3198 +#: sql_help.c:3201 sql_help.c:3286 sql_help.c:3375 sql_help.c:3403 +#: sql_help.c:4151 sql_help.c:4158 sql_help.c:4164 sql_help.c:4175 +#: sql_help.c:4178 sql_help.c:4181 msgid "argname" msgstr "nombre_arg" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 -#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 -#: sql_help.c:524 sql_help.c:529 sql_help.c:1540 sql_help.c:1579 -#: sql_help.c:1582 sql_help.c:1585 sql_help.c:2018 sql_help.c:2887 -#: sql_help.c:2890 sql_help.c:2893 sql_help.c:2978 sql_help.c:3815 -#: sql_help.c:3831 sql_help.c:3834 sql_help.c:3837 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2283 sql_help.c:2483 sql_help.c:3196 +#: sql_help.c:3199 sql_help.c:3202 sql_help.c:3287 sql_help.c:3376 +#: sql_help.c:3404 sql_help.c:4152 sql_help.c:4159 sql_help.c:4165 +#: sql_help.c:4176 sql_help.c:4179 sql_help.c:4182 msgid "argtype" msgstr "tipo_arg" -#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:854 -#: sql_help.c:942 sql_help.c:1230 sql_help.c:1354 sql_help.c:1382 -#: sql_help.c:1633 sql_help.c:1639 sql_help.c:1925 sql_help.c:1966 -#: sql_help.c:1973 sql_help.c:1982 sql_help.c:2058 sql_help.c:2237 -#: sql_help.c:2329 sql_help.c:2588 sql_help.c:2769 sql_help.c:2791 -#: sql_help.c:3254 sql_help.c:3421 +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1446 sql_help.c:1570 sql_help.c:1602 +#: sql_help.c:1650 sql_help.c:1889 sql_help.c:1896 sql_help.c:2188 +#: sql_help.c:2230 sql_help.c:2237 sql_help.c:2246 sql_help.c:2323 +#: sql_help.c:2534 sql_help.c:2626 sql_help.c:2897 sql_help.c:3078 +#: sql_help.c:3100 sql_help.c:3588 sql_help.c:3756 sql_help.c:4608 msgid "option" msgstr "opción" -#: sql_help.c:114 sql_help.c:855 sql_help.c:1355 sql_help.c:2059 -#: sql_help.c:2238 sql_help.c:2770 +#: sql_help.c:113 sql_help.c:927 sql_help.c:1571 sql_help.c:2324 +#: sql_help.c:2535 sql_help.c:3079 msgid "where option can be:" msgstr "donde opción puede ser:" -#: sql_help.c:115 sql_help.c:1857 +#: sql_help.c:114 sql_help.c:2120 msgid "allowconn" msgstr "allowconn" -#: sql_help.c:116 sql_help.c:856 sql_help.c:1356 sql_help.c:1858 -#: sql_help.c:2239 sql_help.c:2771 +#: sql_help.c:115 sql_help.c:928 sql_help.c:1572 sql_help.c:2121 +#: sql_help.c:2536 sql_help.c:3080 msgid "connlimit" msgstr "límite_conexiones" -#: sql_help.c:117 sql_help.c:1859 +#: sql_help.c:116 sql_help.c:2122 msgid "istemplate" msgstr "esplantilla" -#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1098 -#: sql_help.c:1146 +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "nuevo_tablespace" -#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 -#: sql_help.c:537 sql_help.c:863 sql_help.c:867 sql_help.c:870 sql_help.c:1005 -#: sql_help.c:1008 sql_help.c:1362 sql_help.c:1365 sql_help.c:1367 -#: sql_help.c:2027 sql_help.c:3607 sql_help.c:4002 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1137 sql_help.c:1140 sql_help.c:1579 +#: sql_help.c:1583 sql_help.c:1586 sql_help.c:2293 sql_help.c:2487 +#: sql_help.c:3942 sql_help.c:4347 msgid "configuration_parameter" msgstr "parámetro_de_configuración" -#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 -#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:815 -#: sql_help.c:864 sql_help.c:943 sql_help.c:982 sql_help.c:985 sql_help.c:990 -#: sql_help.c:1006 sql_help.c:1007 sql_help.c:1128 sql_help.c:1148 -#: sql_help.c:1174 sql_help.c:1231 sql_help.c:1363 sql_help.c:1383 -#: sql_help.c:1926 sql_help.c:1967 sql_help.c:1974 sql_help.c:1983 -#: sql_help.c:2028 sql_help.c:2029 sql_help.c:2087 sql_help.c:2119 -#: sql_help.c:2209 sql_help.c:2330 sql_help.c:2360 sql_help.c:2458 -#: sql_help.c:2470 sql_help.c:2483 sql_help.c:2523 sql_help.c:2545 -#: sql_help.c:2562 sql_help.c:2589 sql_help.c:2792 sql_help.c:3422 -#: sql_help.c:4003 sql_help.c:4004 +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1114 sql_help.c:1117 sql_help.c:1122 sql_help.c:1138 +#: sql_help.c:1139 sql_help.c:1301 sql_help.c:1321 sql_help.c:1368 +#: sql_help.c:1390 sql_help.c:1447 sql_help.c:1580 sql_help.c:1603 +#: sql_help.c:2189 sql_help.c:2231 sql_help.c:2238 sql_help.c:2247 +#: sql_help.c:2294 sql_help.c:2295 sql_help.c:2354 sql_help.c:2388 +#: sql_help.c:2488 sql_help.c:2489 sql_help.c:2506 sql_help.c:2627 +#: sql_help.c:2657 sql_help.c:2762 sql_help.c:2775 sql_help.c:2789 +#: sql_help.c:2830 sql_help.c:2854 sql_help.c:2871 sql_help.c:2898 +#: sql_help.c:3101 sql_help.c:3757 sql_help.c:4348 sql_help.c:4349 msgid "value" msgstr "valor" -#: sql_help.c:198 +#: sql_help.c:197 msgid "target_role" msgstr "rol_destino" -#: sql_help.c:199 sql_help.c:1909 sql_help.c:2285 sql_help.c:2290 -#: sql_help.c:3369 sql_help.c:3376 sql_help.c:3390 sql_help.c:3396 -#: sql_help.c:3702 sql_help.c:3709 sql_help.c:3723 sql_help.c:3729 +#: sql_help.c:198 sql_help.c:2172 sql_help.c:2582 sql_help.c:2587 +#: sql_help.c:3704 sql_help.c:3711 sql_help.c:3725 sql_help.c:3731 +#: sql_help.c:4037 sql_help.c:4044 sql_help.c:4058 sql_help.c:4064 msgid "schema_name" msgstr "nombre_de_esquema" -#: sql_help.c:200 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "grant_o_revoke_abreviado" -#: sql_help.c:201 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "donde grant_o_revoke_abreviado es uno de:" -#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 -#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 -#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:874 -#: sql_help.c:1097 sql_help.c:1370 sql_help.c:2062 sql_help.c:2063 -#: sql_help.c:2064 sql_help.c:2065 sql_help.c:2066 sql_help.c:2193 -#: sql_help.c:2242 sql_help.c:2243 sql_help.c:2244 sql_help.c:2245 -#: sql_help.c:2246 sql_help.c:2774 sql_help.c:2775 sql_help.c:2776 -#: sql_help.c:2777 sql_help.c:2778 sql_help.c:3403 sql_help.c:3404 -#: sql_help.c:3405 sql_help.c:3703 sql_help.c:3707 sql_help.c:3710 -#: sql_help.c:3712 sql_help.c:3714 sql_help.c:3716 sql_help.c:3718 -#: sql_help.c:3724 sql_help.c:3726 sql_help.c:3728 sql_help.c:3730 -#: sql_help.c:3732 sql_help.c:3734 sql_help.c:3735 sql_help.c:3736 -#: sql_help.c:4023 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1270 sql_help.c:1590 sql_help.c:2327 sql_help.c:2328 +#: sql_help.c:2329 sql_help.c:2330 sql_help.c:2331 sql_help.c:2462 +#: sql_help.c:2539 sql_help.c:2540 sql_help.c:2541 sql_help.c:2542 +#: sql_help.c:2543 sql_help.c:3083 sql_help.c:3084 sql_help.c:3085 +#: sql_help.c:3086 sql_help.c:3087 sql_help.c:3738 sql_help.c:3739 +#: sql_help.c:3740 sql_help.c:4038 sql_help.c:4042 sql_help.c:4045 +#: sql_help.c:4047 sql_help.c:4049 sql_help.c:4051 sql_help.c:4053 +#: sql_help.c:4059 sql_help.c:4061 sql_help.c:4063 sql_help.c:4065 +#: sql_help.c:4067 sql_help.c:4069 sql_help.c:4070 sql_help.c:4071 +#: sql_help.c:4368 msgid "role_name" msgstr "nombre_de_rol" -#: sql_help.c:237 sql_help.c:451 sql_help.c:1113 sql_help.c:1115 -#: sql_help.c:1399 sql_help.c:1878 sql_help.c:1882 sql_help.c:1986 -#: sql_help.c:1990 sql_help.c:2083 sql_help.c:2454 sql_help.c:2466 -#: sql_help.c:2479 sql_help.c:2487 sql_help.c:2498 sql_help.c:2527 -#: sql_help.c:3453 sql_help.c:3468 sql_help.c:3470 sql_help.c:3888 -#: sql_help.c:3889 sql_help.c:3898 sql_help.c:3939 sql_help.c:3940 -#: sql_help.c:3941 sql_help.c:3942 sql_help.c:3943 sql_help.c:3944 -#: sql_help.c:3977 sql_help.c:3978 sql_help.c:3983 sql_help.c:3988 -#: sql_help.c:4127 sql_help.c:4128 sql_help.c:4137 sql_help.c:4178 -#: sql_help.c:4179 sql_help.c:4180 sql_help.c:4181 sql_help.c:4182 -#: sql_help.c:4183 sql_help.c:4230 sql_help.c:4232 sql_help.c:4265 -#: sql_help.c:4321 sql_help.c:4322 sql_help.c:4331 sql_help.c:4372 -#: sql_help.c:4373 sql_help.c:4374 sql_help.c:4375 sql_help.c:4376 -#: sql_help.c:4377 +#: sql_help.c:236 sql_help.c:459 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1336 sql_help.c:1347 sql_help.c:1372 sql_help.c:1619 +#: sql_help.c:2141 sql_help.c:2145 sql_help.c:2250 sql_help.c:2255 +#: sql_help.c:2349 sql_help.c:2757 sql_help.c:2770 sql_help.c:2784 +#: sql_help.c:2793 sql_help.c:2805 sql_help.c:2834 sql_help.c:3788 +#: sql_help.c:3803 sql_help.c:3805 sql_help.c:4233 sql_help.c:4234 +#: sql_help.c:4243 sql_help.c:4284 sql_help.c:4285 sql_help.c:4286 +#: sql_help.c:4287 sql_help.c:4288 sql_help.c:4289 sql_help.c:4322 +#: sql_help.c:4323 sql_help.c:4328 sql_help.c:4333 sql_help.c:4472 +#: sql_help.c:4473 sql_help.c:4482 sql_help.c:4523 sql_help.c:4524 +#: sql_help.c:4525 sql_help.c:4526 sql_help.c:4527 sql_help.c:4528 +#: sql_help.c:4575 sql_help.c:4577 sql_help.c:4634 sql_help.c:4690 +#: sql_help.c:4691 sql_help.c:4700 sql_help.c:4741 sql_help.c:4742 +#: sql_help.c:4743 sql_help.c:4744 sql_help.c:4745 sql_help.c:4746 msgid "expression" msgstr "expresión" -#: sql_help.c:240 +#: sql_help.c:239 msgid "domain_constraint" msgstr "restricción_de_dominio" -#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 -#: sql_help.c:1090 sql_help.c:1134 sql_help.c:1135 sql_help.c:1136 -#: sql_help.c:1156 sql_help.c:1526 sql_help.c:1528 sql_help.c:1881 -#: sql_help.c:1985 sql_help.c:1989 sql_help.c:2486 sql_help.c:2497 -#: sql_help.c:3465 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1335 sql_help.c:1346 sql_help.c:1363 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2144 sql_help.c:2249 sql_help.c:2254 +#: sql_help.c:2792 sql_help.c:2804 sql_help.c:3800 msgid "constraint_name" msgstr "nombre_restricción" -#: sql_help.c:245 sql_help.c:1091 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "nuevo_nombre_restricción" -#: sql_help.c:316 sql_help.c:941 +#: sql_help.c:317 sql_help.c:1073 msgid "new_version" msgstr "nueva_versión" -#: sql_help.c:320 sql_help.c:322 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "objeto_miembro" -#: sql_help.c:323 +#: sql_help.c:324 msgid "where member_object is:" msgstr "dondo objeto_miembro es:" -#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 -#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 -#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 -#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 -#: sql_help.c:359 sql_help.c:1518 sql_help.c:1523 sql_help.c:1530 -#: sql_help.c:1531 sql_help.c:1532 sql_help.c:1533 sql_help.c:1534 -#: sql_help.c:1535 sql_help.c:1536 sql_help.c:1541 sql_help.c:1543 -#: sql_help.c:1547 sql_help.c:1549 sql_help.c:1553 sql_help.c:1554 -#: sql_help.c:1555 sql_help.c:1558 sql_help.c:1559 sql_help.c:1560 -#: sql_help.c:1561 sql_help.c:1562 sql_help.c:1563 sql_help.c:1564 -#: sql_help.c:1565 sql_help.c:1566 sql_help.c:1567 sql_help.c:1568 -#: sql_help.c:1573 sql_help.c:1574 sql_help.c:3803 sql_help.c:3808 -#: sql_help.c:3809 sql_help.c:3810 sql_help.c:3811 sql_help.c:3817 -#: sql_help.c:3818 sql_help.c:3819 sql_help.c:3820 sql_help.c:3821 -#: sql_help.c:3822 sql_help.c:3823 sql_help.c:3824 sql_help.c:3825 -#: sql_help.c:3826 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4140 sql_help.c:4145 +#: sql_help.c:4146 sql_help.c:4147 sql_help.c:4148 sql_help.c:4154 +#: sql_help.c:4155 sql_help.c:4160 sql_help.c:4161 sql_help.c:4166 +#: sql_help.c:4167 sql_help.c:4168 sql_help.c:4169 sql_help.c:4170 +#: sql_help.c:4171 msgid "object_name" msgstr "nombre_de_objeto" -#: sql_help.c:325 sql_help.c:1519 sql_help.c:3806 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4143 msgid "aggregate_name" msgstr "nombre_función_agregación" -#: sql_help.c:327 sql_help.c:1521 sql_help.c:1792 sql_help.c:1796 -#: sql_help.c:1798 sql_help.c:2901 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3210 msgid "source_type" msgstr "tipo_fuente" -#: sql_help.c:328 sql_help.c:1522 sql_help.c:1793 sql_help.c:1797 -#: sql_help.c:1799 sql_help.c:2902 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3211 msgid "target_type" msgstr "tipo_destino" -#: sql_help.c:335 sql_help.c:756 sql_help.c:1537 sql_help.c:1794 -#: sql_help.c:1833 sql_help.c:1896 sql_help.c:2136 sql_help.c:2167 -#: sql_help.c:2665 sql_help.c:3386 sql_help.c:3719 sql_help.c:3812 -#: sql_help.c:3917 sql_help.c:3921 sql_help.c:3925 sql_help.c:3928 -#: sql_help.c:4156 sql_help.c:4160 sql_help.c:4164 sql_help.c:4167 -#: sql_help.c:4350 sql_help.c:4354 sql_help.c:4358 sql_help.c:4361 +#: sql_help.c:336 sql_help.c:774 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2096 sql_help.c:2159 sql_help.c:2405 sql_help.c:2436 +#: sql_help.c:2974 sql_help.c:4054 sql_help.c:4149 sql_help.c:4262 +#: sql_help.c:4266 sql_help.c:4270 sql_help.c:4273 sql_help.c:4501 +#: sql_help.c:4505 sql_help.c:4509 sql_help.c:4512 sql_help.c:4719 +#: sql_help.c:4723 sql_help.c:4727 sql_help.c:4730 msgid "function_name" msgstr "nombre_de_función" -#: sql_help.c:340 sql_help.c:749 sql_help.c:1544 sql_help.c:2160 +#: sql_help.c:341 sql_help.c:767 sql_help.c:1792 sql_help.c:2429 msgid "operator_name" msgstr "nombre_operador" -#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1545 -#: sql_help.c:2137 sql_help.c:3019 +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1793 +#: sql_help.c:2406 sql_help.c:3328 msgid "left_type" msgstr "tipo_izq" -#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1546 -#: sql_help.c:2138 sql_help.c:3020 +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1794 +#: sql_help.c:2407 sql_help.c:3329 msgid "right_type" msgstr "tipo_der" -#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 -#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 -#: sql_help.c:1548 sql_help.c:1550 sql_help.c:2157 sql_help.c:2178 -#: sql_help.c:2503 sql_help.c:3029 sql_help.c:3038 +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1352 sql_help.c:1796 sql_help.c:1798 sql_help.c:2426 +#: sql_help.c:2447 sql_help.c:2810 sql_help.c:3338 sql_help.c:3347 msgid "index_method" msgstr "método_de_índice" -#: sql_help.c:356 sql_help.c:1152 sql_help.c:1569 sql_help.c:2024 -#: sql_help.c:2461 sql_help.c:2632 sql_help.c:3176 sql_help.c:3400 -#: sql_help.c:3733 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4156 +msgid "procedure_name" +msgstr "nombre_de_procedimiento" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3721 sql_help.c:4162 +msgid "routine_name" +msgstr "nombre_de_rutina" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2289 +#: sql_help.c:2486 sql_help.c:2765 sql_help.c:2941 sql_help.c:3509 +#: sql_help.c:3735 sql_help.c:4068 msgid "type_name" msgstr "nombre_de_tipo" -#: sql_help.c:357 sql_help.c:1570 sql_help.c:2023 sql_help.c:2633 -#: sql_help.c:2859 sql_help.c:3177 sql_help.c:3392 sql_help.c:3725 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2288 sql_help.c:2485 +#: sql_help.c:2942 sql_help.c:3168 sql_help.c:3510 sql_help.c:3727 +#: sql_help.c:4060 msgid "lang_name" msgstr "nombre_lenguaje" -#: sql_help.c:360 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "y signatura_func_agregación es:" -#: sql_help.c:383 sql_help.c:1664 sql_help.c:1923 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2186 msgid "handler_function" msgstr "función_manejadora" -#: sql_help.c:384 sql_help.c:1924 +#: sql_help.c:393 sql_help.c:2187 msgid "validator_function" msgstr "función_validadora" -#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1085 -#: sql_help.c:1296 sql_help.c:2494 sql_help.c:2495 sql_help.c:2511 -#: sql_help.c:2512 +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1258 sql_help.c:1512 msgid "action" msgstr "acción" -#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 -#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 -#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 -#: sql_help.c:660 sql_help.c:662 sql_help.c:923 sql_help.c:1087 -#: sql_help.c:1105 sql_help.c:1109 sql_help.c:1110 sql_help.c:1114 -#: sql_help.c:1116 sql_help.c:1117 sql_help.c:1118 sql_help.c:1120 -#: sql_help.c:1123 sql_help.c:1124 sql_help.c:1126 sql_help.c:1129 -#: sql_help.c:1131 sql_help.c:1398 sql_help.c:1401 sql_help.c:1421 -#: sql_help.c:1525 sql_help.c:1630 sql_help.c:1635 sql_help.c:1649 -#: sql_help.c:1650 sql_help.c:1651 sql_help.c:1964 sql_help.c:1977 -#: sql_help.c:2021 sql_help.c:2082 sql_help.c:2117 sql_help.c:2315 -#: sql_help.c:2343 sql_help.c:2344 sql_help.c:2445 sql_help.c:2453 -#: sql_help.c:2462 sql_help.c:2465 sql_help.c:2474 sql_help.c:2478 -#: sql_help.c:2499 sql_help.c:2501 sql_help.c:2508 sql_help.c:2526 -#: sql_help.c:2543 sql_help.c:2668 sql_help.c:2804 sql_help.c:3371 -#: sql_help.c:3372 sql_help.c:3452 sql_help.c:3467 sql_help.c:3469 -#: sql_help.c:3471 sql_help.c:3704 sql_help.c:3705 sql_help.c:3805 -#: sql_help.c:3948 sql_help.c:4187 sql_help.c:4229 sql_help.c:4231 -#: sql_help.c:4233 sql_help.c:4250 sql_help.c:4253 sql_help.c:4381 +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1348 sql_help.c:1350 sql_help.c:1357 +#: sql_help.c:1366 sql_help.c:1371 sql_help.c:1618 sql_help.c:1621 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1892 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2228 +#: sql_help.c:2241 sql_help.c:2286 sql_help.c:2348 sql_help.c:2352 +#: sql_help.c:2385 sql_help.c:2612 sql_help.c:2640 sql_help.c:2641 +#: sql_help.c:2748 sql_help.c:2756 sql_help.c:2766 sql_help.c:2769 +#: sql_help.c:2779 sql_help.c:2783 sql_help.c:2806 sql_help.c:2808 +#: sql_help.c:2815 sql_help.c:2828 sql_help.c:2833 sql_help.c:2851 +#: sql_help.c:2977 sql_help.c:3113 sql_help.c:3706 sql_help.c:3707 +#: sql_help.c:3787 sql_help.c:3802 sql_help.c:3804 sql_help.c:3806 +#: sql_help.c:4039 sql_help.c:4040 sql_help.c:4142 sql_help.c:4293 +#: sql_help.c:4532 sql_help.c:4574 sql_help.c:4576 sql_help.c:4578 +#: sql_help.c:4622 sql_help.c:4750 msgid "column_name" msgstr "nombre_de_columna" -#: sql_help.c:436 sql_help.c:646 sql_help.c:1088 +#: sql_help.c:444 sql_help.c:664 sql_help.c:1261 msgid "new_column_name" msgstr "nuevo_nombre_de_columna" -#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1104 -#: sql_help.c:1312 +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1277 sql_help.c:1528 msgid "where action is one of:" msgstr "donde acción es una de:" -#: sql_help.c:443 sql_help.c:448 sql_help.c:915 sql_help.c:1106 -#: sql_help.c:1111 sql_help.c:1314 sql_help.c:1318 sql_help.c:1876 -#: sql_help.c:1965 sql_help.c:2156 sql_help.c:2308 sql_help.c:2446 -#: sql_help.c:2713 sql_help.c:3554 +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1530 sql_help.c:1534 sql_help.c:2139 +#: sql_help.c:2229 sql_help.c:2425 sql_help.c:2605 sql_help.c:2749 +#: sql_help.c:3022 sql_help.c:3889 msgid "data_type" msgstr "tipo_de_dato" -#: sql_help.c:444 sql_help.c:449 sql_help.c:1107 sql_help.c:1112 -#: sql_help.c:1315 sql_help.c:1319 sql_help.c:1877 sql_help.c:1968 -#: sql_help.c:2084 sql_help.c:2447 sql_help.c:2455 sql_help.c:2467 -#: sql_help.c:2480 sql_help.c:2714 sql_help.c:2720 sql_help.c:3462 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1531 sql_help.c:1535 sql_help.c:2140 sql_help.c:2232 +#: sql_help.c:2350 sql_help.c:2750 sql_help.c:2758 sql_help.c:2771 +#: sql_help.c:2785 sql_help.c:3023 sql_help.c:3029 sql_help.c:3797 msgid "collation" msgstr "ordenamiento" -#: sql_help.c:445 sql_help.c:1108 sql_help.c:1969 sql_help.c:1978 -#: sql_help.c:2448 sql_help.c:2463 sql_help.c:2475 +#: sql_help.c:453 sql_help.c:1281 sql_help.c:2233 sql_help.c:2242 +#: sql_help.c:2751 sql_help.c:2767 sql_help.c:2780 msgid "column_constraint" msgstr "restricción_de_columna" -#: sql_help.c:455 sql_help.c:656 sql_help.c:1125 +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1298 msgid "integer" msgstr "entero" -#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1127 -#: sql_help.c:1130 +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "opción_de_atributo" -#: sql_help.c:465 sql_help.c:1132 sql_help.c:1970 sql_help.c:1979 -#: sql_help.c:2449 sql_help.c:2464 sql_help.c:2476 +#: sql_help.c:473 sql_help.c:1305 sql_help.c:2234 sql_help.c:2243 +#: sql_help.c:2752 sql_help.c:2768 sql_help.c:2781 msgid "table_constraint" msgstr "restricción_de_tabla" -#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1137 -#: sql_help.c:1138 sql_help.c:1139 sql_help.c:1140 sql_help.c:1571 +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "nombre_disparador" -#: sql_help.c:472 sql_help.c:473 sql_help.c:1150 sql_help.c:1151 -#: sql_help.c:1971 sql_help.c:1976 sql_help.c:2452 sql_help.c:2473 +#: sql_help.c:480 sql_help.c:481 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2235 sql_help.c:2240 sql_help.c:2755 sql_help.c:2778 msgid "parent_table" msgstr "tabla_padre" -#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1275 -#: sql_help.c:1908 +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1491 sql_help.c:2171 msgid "extension_name" msgstr "nombre_de_extensión" -#: sql_help.c:532 sql_help.c:2025 +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2290 msgid "execution_cost" msgstr "costo_de_ejecución" -#: sql_help.c:533 sql_help.c:2026 +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2291 msgid "result_rows" msgstr "núm_de_filas" -#: sql_help.c:554 sql_help.c:556 sql_help.c:853 sql_help.c:861 sql_help.c:865 -#: sql_help.c:868 sql_help.c:871 sql_help.c:1353 sql_help.c:1361 -#: sql_help.c:1364 sql_help.c:1366 sql_help.c:1368 sql_help.c:2286 -#: sql_help.c:2288 sql_help.c:2291 sql_help.c:2292 sql_help.c:3370 -#: sql_help.c:3374 sql_help.c:3377 sql_help.c:3379 sql_help.c:3381 -#: sql_help.c:3383 sql_help.c:3385 sql_help.c:3391 sql_help.c:3393 -#: sql_help.c:3395 sql_help.c:3397 sql_help.c:3399 sql_help.c:3401 +#: sql_help.c:543 sql_help.c:2292 +msgid "support_function" +msgstr "función_de_soporte" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1569 sql_help.c:1577 +#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1587 sql_help.c:2583 +#: sql_help.c:2585 sql_help.c:2588 sql_help.c:2589 sql_help.c:3705 +#: sql_help.c:3709 sql_help.c:3712 sql_help.c:3714 sql_help.c:3716 +#: sql_help.c:3718 sql_help.c:3720 sql_help.c:3726 sql_help.c:3728 +#: sql_help.c:3730 sql_help.c:3732 sql_help.c:3734 sql_help.c:3736 msgid "role_specification" msgstr "especificación_de_rol" -#: sql_help.c:555 sql_help.c:557 sql_help.c:1380 sql_help.c:1851 -#: sql_help.c:2294 sql_help.c:2789 sql_help.c:3210 sql_help.c:4033 +#: sql_help.c:565 sql_help.c:567 sql_help.c:1600 sql_help.c:2114 +#: sql_help.c:2591 sql_help.c:3098 sql_help.c:3543 sql_help.c:4378 msgid "user_name" msgstr "nombre_de_usuario" -#: sql_help.c:558 sql_help.c:873 sql_help.c:1369 sql_help.c:2293 -#: sql_help.c:3402 +#: sql_help.c:568 sql_help.c:945 sql_help.c:1589 sql_help.c:2590 +#: sql_help.c:3737 msgid "where role_specification can be:" msgstr "donde especificación_de_rol puede ser:" -#: sql_help.c:560 +#: sql_help.c:570 msgid "group_name" msgstr "nombre_de_grupo" -#: sql_help.c:578 sql_help.c:1856 sql_help.c:2088 sql_help.c:2120 -#: sql_help.c:2459 sql_help.c:2471 sql_help.c:2484 sql_help.c:2524 -#: sql_help.c:2546 sql_help.c:2558 sql_help.c:3398 sql_help.c:3731 +#: sql_help.c:591 sql_help.c:1369 sql_help.c:2119 sql_help.c:2355 +#: sql_help.c:2389 sql_help.c:2763 sql_help.c:2776 sql_help.c:2790 +#: sql_help.c:2831 sql_help.c:2855 sql_help.c:2867 sql_help.c:3733 +#: sql_help.c:4066 msgid "tablespace_name" msgstr "nombre_de_tablespace" -#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1147 -#: sql_help.c:1149 sql_help.c:2086 sql_help.c:2118 sql_help.c:2457 -#: sql_help.c:2469 sql_help.c:2482 sql_help.c:2522 sql_help.c:2544 +#: sql_help.c:593 sql_help.c:681 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1364 sql_help.c:1707 +msgid "index_name" +msgstr "nombre_índice" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1367 sql_help.c:2353 sql_help.c:2387 +#: sql_help.c:2761 sql_help.c:2774 sql_help.c:2788 sql_help.c:2829 +#: sql_help.c:2853 msgid "storage_parameter" msgstr "parámetro_de_almacenamiento" -#: sql_help.c:608 sql_help.c:1542 sql_help.c:3816 +#: sql_help.c:602 +msgid "column_number" +msgstr "número_de_columna" + +#: sql_help.c:626 sql_help.c:1790 sql_help.c:4153 msgid "large_object_oid" msgstr "oid_de_objeto_grande" -#: sql_help.c:663 sql_help.c:1145 sql_help.c:1154 sql_help.c:1157 -#: sql_help.c:1461 -msgid "index_name" -msgstr "nombre_índice" - -#: sql_help.c:695 sql_help.c:2141 +#: sql_help.c:713 sql_help.c:2410 msgid "res_proc" msgstr "proc_res" -#: sql_help.c:696 sql_help.c:2142 +#: sql_help.c:714 sql_help.c:2411 msgid "join_proc" msgstr "proc_join" -#: sql_help.c:748 sql_help.c:760 sql_help.c:2159 +#: sql_help.c:766 sql_help.c:778 sql_help.c:2428 msgid "strategy_number" msgstr "número_de_estrategia" -#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 -#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2161 -#: sql_help.c:2162 sql_help.c:2165 sql_help.c:2166 +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2430 sql_help.c:2431 +#: sql_help.c:2434 sql_help.c:2435 msgid "op_type" msgstr "tipo_op" -#: sql_help.c:752 sql_help.c:2163 +#: sql_help.c:770 sql_help.c:2432 msgid "sort_family_name" msgstr "nombre_familia_ordenamiento" -#: sql_help.c:753 sql_help.c:763 sql_help.c:2164 +#: sql_help.c:771 sql_help.c:781 sql_help.c:2433 msgid "support_number" msgstr "número_de_soporte" -#: sql_help.c:757 sql_help.c:1795 sql_help.c:2168 sql_help.c:2635 -#: sql_help.c:2637 +#: sql_help.c:775 sql_help.c:2056 sql_help.c:2437 sql_help.c:2944 +#: sql_help.c:2946 msgid "argument_type" msgstr "tipo_argumento" -#: sql_help.c:788 sql_help.c:791 sql_help.c:808 sql_help.c:810 sql_help.c:812 -#: sql_help.c:883 sql_help.c:922 sql_help.c:1271 sql_help.c:1274 -#: sql_help.c:1420 sql_help.c:1460 sql_help.c:1527 sql_help.c:1552 -#: sql_help.c:1557 sql_help.c:1572 sql_help.c:1629 sql_help.c:1634 -#: sql_help.c:1963 sql_help.c:1975 sql_help.c:2080 sql_help.c:2116 -#: sql_help.c:2192 sql_help.c:2207 sql_help.c:2263 sql_help.c:2314 -#: sql_help.c:2345 sql_help.c:2444 sql_help.c:2460 sql_help.c:2472 -#: sql_help.c:2542 sql_help.c:2661 sql_help.c:2838 sql_help.c:3055 -#: sql_help.c:3080 sql_help.c:3186 sql_help.c:3368 sql_help.c:3373 -#: sql_help.c:3418 sql_help.c:3450 sql_help.c:3701 sql_help.c:3706 -#: sql_help.c:3804 sql_help.c:3903 sql_help.c:3905 sql_help.c:3954 -#: sql_help.c:3993 sql_help.c:4142 sql_help.c:4144 sql_help.c:4193 -#: sql_help.c:4227 sql_help.c:4249 sql_help.c:4251 sql_help.c:4252 -#: sql_help.c:4336 sql_help.c:4338 sql_help.c:4387 +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1487 sql_help.c:1490 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1891 +#: sql_help.c:2227 sql_help.c:2239 sql_help.c:2346 sql_help.c:2384 +#: sql_help.c:2461 sql_help.c:2504 sql_help.c:2560 sql_help.c:2611 +#: sql_help.c:2642 sql_help.c:2747 sql_help.c:2764 sql_help.c:2777 +#: sql_help.c:2850 sql_help.c:2970 sql_help.c:3147 sql_help.c:3364 +#: sql_help.c:3413 sql_help.c:3519 sql_help.c:3703 sql_help.c:3708 +#: sql_help.c:3753 sql_help.c:3785 sql_help.c:4036 sql_help.c:4041 +#: sql_help.c:4141 sql_help.c:4248 sql_help.c:4250 sql_help.c:4299 +#: sql_help.c:4338 sql_help.c:4487 sql_help.c:4489 sql_help.c:4538 +#: sql_help.c:4572 sql_help.c:4621 sql_help.c:4705 sql_help.c:4707 +#: sql_help.c:4756 msgid "table_name" msgstr "nombre_de_tabla" -#: sql_help.c:793 sql_help.c:2194 +#: sql_help.c:811 sql_help.c:2463 msgid "using_expression" msgstr "expresión_using" -#: sql_help.c:794 sql_help.c:2195 +#: sql_help.c:812 sql_help.c:2464 msgid "check_expression" msgstr "expresión_check" -#: sql_help.c:814 sql_help.c:2208 -#, fuzzy +#: sql_help.c:886 sql_help.c:2505 msgid "publication_parameter" -msgstr "parámetro_de_configuración" +msgstr "parámetro_de_publicación" -#: sql_help.c:857 sql_help.c:1357 sql_help.c:2060 sql_help.c:2240 -#: sql_help.c:2772 +#: sql_help.c:929 sql_help.c:1573 sql_help.c:2325 sql_help.c:2537 +#: sql_help.c:3081 msgid "password" msgstr "contraseña" -#: sql_help.c:858 sql_help.c:1358 sql_help.c:2061 sql_help.c:2241 -#: sql_help.c:2773 +#: sql_help.c:930 sql_help.c:1574 sql_help.c:2326 sql_help.c:2538 +#: sql_help.c:3082 msgid "timestamp" msgstr "fecha_hora" -#: sql_help.c:862 sql_help.c:866 sql_help.c:869 sql_help.c:872 sql_help.c:3378 -#: sql_help.c:3711 +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1578 +#: sql_help.c:1582 sql_help.c:1585 sql_help.c:1588 sql_help.c:3713 +#: sql_help.c:4046 msgid "database_name" msgstr "nombre_de_base_de_datos" -#: sql_help.c:916 sql_help.c:2309 +#: sql_help.c:1048 sql_help.c:2606 msgid "increment" msgstr "incremento" -#: sql_help.c:917 sql_help.c:2310 +#: sql_help.c:1049 sql_help.c:2607 msgid "minvalue" msgstr "valormin" -#: sql_help.c:918 sql_help.c:2311 +#: sql_help.c:1050 sql_help.c:2608 msgid "maxvalue" msgstr "valormax" -#: sql_help.c:919 sql_help.c:2312 sql_help.c:3901 sql_help.c:3991 -#: sql_help.c:4140 sql_help.c:4269 sql_help.c:4334 +#: sql_help.c:1051 sql_help.c:2609 sql_help.c:4246 sql_help.c:4336 +#: sql_help.c:4485 sql_help.c:4638 sql_help.c:4703 msgid "start" msgstr "inicio" -#: sql_help.c:920 sql_help.c:1122 +#: sql_help.c:1052 sql_help.c:1295 msgid "restart" msgstr "reinicio" -#: sql_help.c:921 sql_help.c:2313 +#: sql_help.c:1053 sql_help.c:2610 msgid "cache" msgstr "cache" -#: sql_help.c:978 sql_help.c:2357 +#: sql_help.c:1110 sql_help.c:2654 msgid "conninfo" -msgstr "" +msgstr "conninfo" -#: sql_help.c:980 sql_help.c:2358 -#, fuzzy +#: sql_help.c:1112 sql_help.c:2655 msgid "publication_name" -msgstr "nombre_relación" +msgstr "nombre_de_publicación" -#: sql_help.c:981 -#, fuzzy +#: sql_help.c:1113 msgid "set_publication_option" -msgstr "nombre_relación" +msgstr "opción_de_conjunto_de_publicación" -#: sql_help.c:984 -#, fuzzy +#: sql_help.c:1116 msgid "refresh_option" -msgstr "opción_de_like" +msgstr "opción_refresh" -#: sql_help.c:989 sql_help.c:2359 -#, fuzzy +#: sql_help.c:1121 sql_help.c:2656 msgid "subscription_parameter" -msgstr "parámetro_de_configuración" +msgstr "parámetro_de_suscripción" -#: sql_help.c:1100 sql_help.c:1103 -#, fuzzy +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" -msgstr "nombre_relación" +msgstr "nombre_de_partición" -#: sql_help.c:1101 sql_help.c:1980 sql_help.c:2477 +#: sql_help.c:1274 sql_help.c:2244 sql_help.c:2782 msgid "partition_bound_spec" -msgstr "" +msgstr "borde_de_partición" -#: sql_help.c:1119 sql_help.c:2489 -#, fuzzy +#: sql_help.c:1292 sql_help.c:1338 sql_help.c:2796 msgid "sequence_options" -msgstr "nombre_secuencia" +msgstr "opciones_de_secuencia" -#: sql_help.c:1121 -#, fuzzy +#: sql_help.c:1294 msgid "sequence_option" -msgstr "nombre_secuencia" +msgstr "opción_de_secuencia" -#: sql_help.c:1133 +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "restricción_de_tabla_con_índice" -#: sql_help.c:1141 sql_help.c:1142 sql_help.c:1143 sql_help.c:1144 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "nombre_regla_de_reescritura" -#: sql_help.c:1155 +#: sql_help.c:1328 sql_help.c:2821 +msgid "and partition_bound_spec is:" +msgstr "y borde_de_partición es:" + +#: sql_help.c:1329 sql_help.c:1330 sql_help.c:1331 sql_help.c:2822 +#: sql_help.c:2823 sql_help.c:2824 +msgid "partition_bound_expr" +msgstr "expresión_de_borde_de_partición" + +#: sql_help.c:1332 sql_help.c:1333 sql_help.c:2825 sql_help.c:2826 +msgid "numeric_literal" +msgstr "literal_numérico" + +#: sql_help.c:1334 +msgid "and column_constraint is:" +msgstr "donde restricción_de_columna es:" + +#: sql_help.c:1337 sql_help.c:2251 sql_help.c:2284 sql_help.c:2484 +#: sql_help.c:2794 +msgid "default_expr" +msgstr "expr_por_omisión" + +#: sql_help.c:1339 sql_help.c:1340 sql_help.c:1349 sql_help.c:1351 +#: sql_help.c:1355 sql_help.c:2797 sql_help.c:2798 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2813 +msgid "index_parameters" +msgstr "parámetros_de_índice" + +#: sql_help.c:1341 sql_help.c:1358 sql_help.c:2799 sql_help.c:2816 +msgid "reftable" +msgstr "tabla_ref" + +#: sql_help.c:1342 sql_help.c:1359 sql_help.c:2800 sql_help.c:2817 +msgid "refcolumn" +msgstr "columna_ref" + +#: sql_help.c:1343 sql_help.c:1344 sql_help.c:1360 sql_help.c:1361 +#: sql_help.c:2801 sql_help.c:2802 sql_help.c:2818 sql_help.c:2819 +msgid "referential_action" +msgstr "acción_referencial" + +#: sql_help.c:1345 sql_help.c:2253 sql_help.c:2803 +msgid "and table_constraint is:" +msgstr "y restricción_de_tabla es:" + +#: sql_help.c:1353 sql_help.c:2811 +msgid "exclude_element" +msgstr "elemento_de_exclusión" + +#: sql_help.c:1354 sql_help.c:2812 sql_help.c:4244 sql_help.c:4334 +#: sql_help.c:4483 sql_help.c:4636 sql_help.c:4701 +msgid "operator" +msgstr "operador" + +#: sql_help.c:1356 sql_help.c:2356 sql_help.c:2814 +msgid "predicate" +msgstr "predicado" + +#: sql_help.c:1362 msgid "and table_constraint_using_index is:" msgstr "y restricción_de_tabla_con_índice es:" -#: sql_help.c:1173 sql_help.c:1176 sql_help.c:2561 +#: sql_help.c:1365 sql_help.c:2827 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "parámetros_de_índice en UNIQUE, PRIMARY KEY y EXCLUDE son:" + +#: sql_help.c:1370 sql_help.c:2832 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "elemento_de_exclusión en una restricción EXCLUDE es:" + +#: sql_help.c:1373 sql_help.c:2351 sql_help.c:2759 sql_help.c:2772 +#: sql_help.c:2786 sql_help.c:2835 sql_help.c:3798 +msgid "opclass" +msgstr "clase_de_ops" + +#: sql_help.c:1389 sql_help.c:1392 sql_help.c:2870 msgid "tablespace_option" msgstr "opción_de_tablespace" -#: sql_help.c:1197 sql_help.c:1200 sql_help.c:1206 sql_help.c:1210 +#: sql_help.c:1413 sql_help.c:1416 sql_help.c:1422 sql_help.c:1426 msgid "token_type" msgstr "tipo_de_token" -#: sql_help.c:1198 sql_help.c:1201 +#: sql_help.c:1414 sql_help.c:1417 msgid "dictionary_name" msgstr "nombre_diccionario" -#: sql_help.c:1203 sql_help.c:1207 +#: sql_help.c:1419 sql_help.c:1423 msgid "old_dictionary" msgstr "diccionario_antiguo" -#: sql_help.c:1204 sql_help.c:1208 +#: sql_help.c:1420 sql_help.c:1424 msgid "new_dictionary" msgstr "diccionario_nuevo" -#: sql_help.c:1300 sql_help.c:1313 sql_help.c:1316 sql_help.c:1317 -#: sql_help.c:2712 +#: sql_help.c:1516 sql_help.c:1529 sql_help.c:1532 sql_help.c:1533 +#: sql_help.c:3021 msgid "attribute_name" msgstr "nombre_atributo" -#: sql_help.c:1301 +#: sql_help.c:1517 msgid "new_attribute_name" msgstr "nuevo_nombre_atributo" -#: sql_help.c:1307 sql_help.c:1311 +#: sql_help.c:1523 sql_help.c:1527 msgid "new_enum_value" msgstr "nuevo_valor_enum" -#: sql_help.c:1308 -#, fuzzy +#: sql_help.c:1524 msgid "neighbor_enum_value" -msgstr "nuevo_valor_enum" +msgstr "valor_enum_vecino" -#: sql_help.c:1310 +#: sql_help.c:1526 msgid "existing_enum_value" msgstr "valor_enum_existente" -#: sql_help.c:1381 sql_help.c:1972 sql_help.c:1981 sql_help.c:2325 -#: sql_help.c:2790 sql_help.c:3211 sql_help.c:3384 sql_help.c:3419 -#: sql_help.c:3717 +#: sql_help.c:1601 sql_help.c:2236 sql_help.c:2245 sql_help.c:2622 +#: sql_help.c:3099 sql_help.c:3544 sql_help.c:3719 sql_help.c:3754 +#: sql_help.c:4052 msgid "server_name" msgstr "nombre_de_servidor" -#: sql_help.c:1409 sql_help.c:1412 sql_help.c:2805 +#: sql_help.c:1629 sql_help.c:1632 sql_help.c:3114 msgid "view_option_name" msgstr "nombre_opción_de_vista" -#: sql_help.c:1410 sql_help.c:2806 +#: sql_help.c:1630 sql_help.c:3115 msgid "view_option_value" msgstr "valor_opción_de_vista" -#: sql_help.c:1435 sql_help.c:4049 sql_help.c:4051 sql_help.c:4075 +#: sql_help.c:1651 sql_help.c:1652 sql_help.c:4609 sql_help.c:4610 +msgid "table_and_columns" +msgstr "tabla_y_columnas" + +#: sql_help.c:1653 sql_help.c:1897 sql_help.c:3591 sql_help.c:4611 +msgid "where option can be one of:" +msgstr "donde opción puede ser una de:" + +#: sql_help.c:1654 sql_help.c:1655 sql_help.c:1899 sql_help.c:1902 +#: sql_help.c:2081 sql_help.c:3592 sql_help.c:3593 sql_help.c:3594 +#: sql_help.c:3595 sql_help.c:3596 sql_help.c:3597 sql_help.c:3598 +#: sql_help.c:4612 sql_help.c:4613 sql_help.c:4614 sql_help.c:4615 +#: sql_help.c:4616 sql_help.c:4617 sql_help.c:4618 sql_help.c:4619 +msgid "boolean" +msgstr "booleano" + +#: sql_help.c:1656 sql_help.c:4620 +msgid "and table_and_columns is:" +msgstr "y tabla_y_columnas es:" + +#: sql_help.c:1672 sql_help.c:4394 sql_help.c:4396 sql_help.c:4420 msgid "transaction_mode" msgstr "modo_de_transacción" -#: sql_help.c:1436 sql_help.c:4052 sql_help.c:4076 +#: sql_help.c:1673 sql_help.c:4397 sql_help.c:4421 msgid "where transaction_mode is one of:" msgstr "donde modo_de_transacción es uno de:" -#: sql_help.c:1524 +#: sql_help.c:1682 sql_help.c:4254 sql_help.c:4263 sql_help.c:4267 +#: sql_help.c:4271 sql_help.c:4274 sql_help.c:4493 sql_help.c:4502 +#: sql_help.c:4506 sql_help.c:4510 sql_help.c:4513 sql_help.c:4711 +#: sql_help.c:4720 sql_help.c:4724 sql_help.c:4728 sql_help.c:4731 +msgid "argument" +msgstr "argumento" + +#: sql_help.c:1772 msgid "relation_name" msgstr "nombre_relación" -#: sql_help.c:1529 sql_help.c:3380 sql_help.c:3713 +#: sql_help.c:1777 sql_help.c:3715 sql_help.c:4048 msgid "domain_name" msgstr "nombre_de_dominio" -#: sql_help.c:1551 +#: sql_help.c:1799 msgid "policy_name" msgstr "nombre_de_política" -#: sql_help.c:1556 +#: sql_help.c:1812 msgid "rule_name" msgstr "nombre_regla" -#: sql_help.c:1575 +#: sql_help.c:1831 msgid "text" msgstr "texto" -#: sql_help.c:1600 sql_help.c:3563 sql_help.c:3751 +#: sql_help.c:1856 sql_help.c:3898 sql_help.c:4086 msgid "transaction_id" msgstr "id_de_transacción" -#: sql_help.c:1631 sql_help.c:1637 sql_help.c:3489 +#: sql_help.c:1887 sql_help.c:1894 sql_help.c:3824 msgid "filename" msgstr "nombre_de_archivo" -#: sql_help.c:1632 sql_help.c:1638 sql_help.c:2265 sql_help.c:2266 -#: sql_help.c:2267 +#: sql_help.c:1888 sql_help.c:1895 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 msgid "command" msgstr "orden" -#: sql_help.c:1636 sql_help.c:2121 sql_help.c:2547 sql_help.c:2807 -#: sql_help.c:2825 sql_help.c:3454 +#: sql_help.c:1890 sql_help.c:2561 sql_help.c:2973 sql_help.c:3150 +#: sql_help.c:3808 sql_help.c:4237 sql_help.c:4239 sql_help.c:4327 +#: sql_help.c:4329 sql_help.c:4476 sql_help.c:4478 sql_help.c:4581 +#: sql_help.c:4694 sql_help.c:4696 +msgid "condition" +msgstr "condición" + +#: sql_help.c:1893 sql_help.c:2390 sql_help.c:2856 sql_help.c:3116 +#: sql_help.c:3134 sql_help.c:3789 msgid "query" msgstr "consulta" -#: sql_help.c:1640 sql_help.c:3257 -msgid "where option can be one of:" -msgstr "donde opción puede ser una de:" - -#: sql_help.c:1641 +#: sql_help.c:1898 msgid "format_name" msgstr "nombre_de_formato" -#: sql_help.c:1642 sql_help.c:1643 sql_help.c:1646 sql_help.c:3258 -#: sql_help.c:3259 sql_help.c:3260 sql_help.c:3261 sql_help.c:3262 -#: sql_help.c:3263 -msgid "boolean" -msgstr "booleano" - -#: sql_help.c:1644 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "carácter_delimitador" -#: sql_help.c:1645 +#: sql_help.c:1901 msgid "null_string" msgstr "cadena_null" -#: sql_help.c:1647 +#: sql_help.c:1903 msgid "quote_character" msgstr "carácter_de_comilla" -#: sql_help.c:1648 +#: sql_help.c:1904 msgid "escape_character" msgstr "carácter_de_escape" -#: sql_help.c:1652 +#: sql_help.c:1908 msgid "encoding_name" msgstr "nombre_codificación" -#: sql_help.c:1663 +#: sql_help.c:1919 msgid "access_method_type" msgstr "tipo_de_método_de_acceso" -#: sql_help.c:1729 sql_help.c:1748 sql_help.c:1751 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "tipo_de_dato_arg" -#: sql_help.c:1730 sql_help.c:1752 sql_help.c:1760 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "func_transición" -#: sql_help.c:1731 sql_help.c:1753 sql_help.c:1761 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "tipo_de_dato_de_estado" -#: sql_help.c:1732 sql_help.c:1754 sql_help.c:1762 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "tamaño_de_dato_de_estado" -#: sql_help.c:1733 sql_help.c:1755 sql_help.c:1763 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "func_final" -#: sql_help.c:1734 sql_help.c:1764 +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "func_combinación" -#: sql_help.c:1735 sql_help.c:1765 +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "func_serial" -#: sql_help.c:1736 sql_help.c:1766 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "func_deserial" -#: sql_help.c:1737 sql_help.c:1756 sql_help.c:1767 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "condición_inicial" -#: sql_help.c:1738 sql_help.c:1768 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "func_transición_m" -#: sql_help.c:1739 sql_help.c:1769 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "func_inv_m" -#: sql_help.c:1740 sql_help.c:1770 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "tipo_de_dato_de_estado_m" -#: sql_help.c:1741 sql_help.c:1771 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "tamaño_de_dato_de_estado_m" -#: sql_help.c:1742 sql_help.c:1772 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "func_final_m" -#: sql_help.c:1743 sql_help.c:1773 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "condición_inicial_m" -#: sql_help.c:1744 sql_help.c:1774 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "operador_de_ordenamiento" -#: sql_help.c:1757 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "o la sintaxis antigua" -#: sql_help.c:1759 +#: sql_help.c:2020 msgid "base_type" msgstr "tipo_base" -#: sql_help.c:1815 +#: sql_help.c:2077 msgid "locale" msgstr "configuración regional" -#: sql_help.c:1816 sql_help.c:1854 +#: sql_help.c:2078 sql_help.c:2117 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1817 sql_help.c:1855 +#: sql_help.c:2079 sql_help.c:2118 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1818 sql_help.c:3802 +#: sql_help.c:2080 sql_help.c:4139 msgid "provider" msgstr "proveedor" -#: sql_help.c:1819 sql_help.c:1910 +#: sql_help.c:2082 sql_help.c:2173 msgid "version" msgstr "versión" -#: sql_help.c:1821 +#: sql_help.c:2084 msgid "existing_collation" msgstr "ordenamiento_existente" -#: sql_help.c:1831 +#: sql_help.c:2094 msgid "source_encoding" msgstr "codificación_origen" -#: sql_help.c:1832 +#: sql_help.c:2095 msgid "dest_encoding" msgstr "codificación_destino" -#: sql_help.c:1852 sql_help.c:2587 +#: sql_help.c:2115 sql_help.c:2896 msgid "template" msgstr "plantilla" -#: sql_help.c:1853 +#: sql_help.c:2116 msgid "encoding" msgstr "codificación" -#: sql_help.c:1879 +#: sql_help.c:2142 msgid "constraint" msgstr "restricción" -#: sql_help.c:1880 +#: sql_help.c:2143 msgid "where constraint is:" msgstr "donde restricción es:" -#: sql_help.c:1894 sql_help.c:2262 sql_help.c:2660 +#: sql_help.c:2157 sql_help.c:2559 sql_help.c:2969 msgid "event" msgstr "evento" -#: sql_help.c:1895 +#: sql_help.c:2158 msgid "filter_variable" msgstr "variable_de_filtrado" -#: sql_help.c:1911 +#: sql_help.c:2174 msgid "old_version" msgstr "versión_antigua" -#: sql_help.c:1984 sql_help.c:2485 +#: sql_help.c:2248 sql_help.c:2791 msgid "where column_constraint is:" msgstr "donde restricción_de_columna es:" -#: sql_help.c:1987 sql_help.c:2019 sql_help.c:2488 -msgid "default_expr" -msgstr "expr_por_omisión" - -#: sql_help.c:1988 sql_help.c:2496 -msgid "and table_constraint is:" -msgstr "y restricción_de_tabla es:" +#: sql_help.c:2252 sql_help.c:2795 +msgid "generation_expr" +msgstr "expr_de_generación" -#: sql_help.c:2020 +#: sql_help.c:2285 msgid "rettype" msgstr "tipo_ret" -#: sql_help.c:2022 +#: sql_help.c:2287 msgid "column_type" msgstr "tipo_columna" -#: sql_help.c:2030 +#: sql_help.c:2296 sql_help.c:2490 msgid "definition" msgstr "definición" -#: sql_help.c:2031 +#: sql_help.c:2297 sql_help.c:2491 msgid "obj_file" msgstr "archivo_obj" -#: sql_help.c:2032 +#: sql_help.c:2298 sql_help.c:2492 msgid "link_symbol" msgstr "símbolo_enlace" -#: sql_help.c:2033 -msgid "attribute" -msgstr "atributo" - -#: sql_help.c:2067 sql_help.c:2247 sql_help.c:2779 +#: sql_help.c:2332 sql_help.c:2544 sql_help.c:3088 msgid "uid" msgstr "uid" -#: sql_help.c:2081 +#: sql_help.c:2347 sql_help.c:2386 sql_help.c:2760 sql_help.c:2773 +#: sql_help.c:2787 sql_help.c:2852 msgid "method" msgstr "método" -#: sql_help.c:2085 sql_help.c:2456 sql_help.c:2468 sql_help.c:2481 -#: sql_help.c:2528 sql_help.c:3463 -msgid "opclass" -msgstr "clase_de_ops" - -#: sql_help.c:2089 sql_help.c:2507 -msgid "predicate" -msgstr "predicado" - -#: sql_help.c:2101 +#: sql_help.c:2368 msgid "call_handler" msgstr "manejador_de_llamada" -#: sql_help.c:2102 +#: sql_help.c:2369 msgid "inline_handler" msgstr "manejador_en_línea" -#: sql_help.c:2103 +#: sql_help.c:2370 msgid "valfunction" msgstr "función_val" -#: sql_help.c:2139 +#: sql_help.c:2408 msgid "com_op" msgstr "op_conm" -#: sql_help.c:2140 +#: sql_help.c:2409 msgid "neg_op" msgstr "op_neg" -#: sql_help.c:2158 +#: sql_help.c:2427 msgid "family_name" msgstr "nombre_familia" -#: sql_help.c:2169 +#: sql_help.c:2438 msgid "storage_type" msgstr "tipo_almacenamiento" -#: sql_help.c:2264 sql_help.c:2664 sql_help.c:2841 sql_help.c:3473 -#: sql_help.c:3892 sql_help.c:3894 sql_help.c:3982 sql_help.c:3984 -#: sql_help.c:4131 sql_help.c:4133 sql_help.c:4236 sql_help.c:4325 -#: sql_help.c:4327 -msgid "condition" -msgstr "condición" - -#: sql_help.c:2268 sql_help.c:2667 +#: sql_help.c:2565 sql_help.c:2976 msgid "where event can be one of:" msgstr "donde evento puede ser una de:" -#: sql_help.c:2287 sql_help.c:2289 +#: sql_help.c:2584 sql_help.c:2586 msgid "schema_element" msgstr "elemento_de_esquema" -#: sql_help.c:2326 +#: sql_help.c:2623 msgid "server_type" msgstr "tipo_de_servidor" -#: sql_help.c:2327 +#: sql_help.c:2624 msgid "server_version" msgstr "versión_de_servidor" -#: sql_help.c:2328 sql_help.c:3382 sql_help.c:3715 +#: sql_help.c:2625 sql_help.c:3717 sql_help.c:4050 msgid "fdw_name" msgstr "nombre_fdw" -#: sql_help.c:2341 -#, fuzzy +#: sql_help.c:2638 msgid "statistics_name" -msgstr "nombre_restricción" +msgstr "nombre_de_estadística" -#: sql_help.c:2342 -#, fuzzy -msgid "statistic_type" -msgstr "tipo_de_dato_de_estado" +#: sql_help.c:2639 +msgid "statistics_kind" +msgstr "tipo_de_estadística" -#: sql_help.c:2356 -#, fuzzy +#: sql_help.c:2653 msgid "subscription_name" -msgstr "nombre_de_función" +msgstr "nombre_de_suscripción" -#: sql_help.c:2450 +#: sql_help.c:2753 msgid "source_table" msgstr "tabla_origen" -#: sql_help.c:2451 +#: sql_help.c:2754 msgid "like_option" msgstr "opción_de_like" -#: sql_help.c:2490 sql_help.c:2491 sql_help.c:2500 sql_help.c:2502 -#: sql_help.c:2506 -msgid "index_parameters" -msgstr "parámetros_de_índice" - -#: sql_help.c:2492 sql_help.c:2509 -msgid "reftable" -msgstr "tabla_ref" - -#: sql_help.c:2493 sql_help.c:2510 -msgid "refcolumn" -msgstr "columna_ref" - -#: sql_help.c:2504 -msgid "exclude_element" -msgstr "elemento_de_exclusión" - -#: sql_help.c:2505 sql_help.c:3899 sql_help.c:3989 sql_help.c:4138 -#: sql_help.c:4267 sql_help.c:4332 -msgid "operator" -msgstr "operador" - -#: sql_help.c:2513 +#: sql_help.c:2820 msgid "and like_option is:" msgstr "y opción_de_like es:" -#: sql_help.c:2514 -msgid "and partition_bound_spec is:" -msgstr "" - -#: sql_help.c:2515 sql_help.c:2517 sql_help.c:2519 -msgid "numeric_literal" -msgstr "" - -#: sql_help.c:2516 sql_help.c:2518 sql_help.c:2520 -#, fuzzy -#| msgid "using_list" -msgid "string_literal" -msgstr "lista_using" - -#: sql_help.c:2521 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "parámetros_de_índice en UNIQUE, PRIMARY KEY y EXCLUDE son:" - -#: sql_help.c:2525 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "elemento_de_exclusión en una restricción EXCLUDE es:" - -#: sql_help.c:2560 +#: sql_help.c:2869 msgid "directory" msgstr "directorio" -#: sql_help.c:2574 +#: sql_help.c:2883 msgid "parser_name" msgstr "nombre_de_parser" -#: sql_help.c:2575 +#: sql_help.c:2884 msgid "source_config" msgstr "config_origen" -#: sql_help.c:2604 +#: sql_help.c:2913 msgid "start_function" msgstr "función_inicio" -#: sql_help.c:2605 +#: sql_help.c:2914 msgid "gettoken_function" msgstr "función_gettoken" -#: sql_help.c:2606 +#: sql_help.c:2915 msgid "end_function" msgstr "función_fin" -#: sql_help.c:2607 +#: sql_help.c:2916 msgid "lextypes_function" msgstr "función_lextypes" -#: sql_help.c:2608 +#: sql_help.c:2917 msgid "headline_function" msgstr "función_headline" -#: sql_help.c:2620 +#: sql_help.c:2929 msgid "init_function" msgstr "función_init" -#: sql_help.c:2621 +#: sql_help.c:2930 msgid "lexize_function" msgstr "función_lexize" -#: sql_help.c:2634 +#: sql_help.c:2943 msgid "from_sql_function_name" msgstr "nombre_de_función_from" -#: sql_help.c:2636 +#: sql_help.c:2945 msgid "to_sql_function_name" msgstr "nombre_de_función_to" -#: sql_help.c:2662 +#: sql_help.c:2971 msgid "referenced_table_name" msgstr "nombre_tabla_referenciada" -#: sql_help.c:2663 -#, fuzzy +#: sql_help.c:2972 msgid "transition_relation_name" -msgstr "nombre_relación" +msgstr "nombre_de_relación_de_transición" -#: sql_help.c:2666 +#: sql_help.c:2975 msgid "arguments" msgstr "argumentos" -#: sql_help.c:2716 sql_help.c:3827 +#: sql_help.c:3025 sql_help.c:4172 msgid "label" msgstr "etiqueta" -#: sql_help.c:2718 +#: sql_help.c:3027 msgid "subtype" msgstr "subtipo" -#: sql_help.c:2719 +#: sql_help.c:3028 msgid "subtype_operator_class" msgstr "clase_de_operador_del_subtipo" -#: sql_help.c:2721 +#: sql_help.c:3030 msgid "canonical_function" msgstr "función_canónica" -#: sql_help.c:2722 +#: sql_help.c:3031 msgid "subtype_diff_function" msgstr "función_diff_del_subtipo" -#: sql_help.c:2724 +#: sql_help.c:3033 msgid "input_function" msgstr "función_entrada" -#: sql_help.c:2725 +#: sql_help.c:3034 msgid "output_function" msgstr "función_salida" -#: sql_help.c:2726 +#: sql_help.c:3035 msgid "receive_function" msgstr "función_receive" -#: sql_help.c:2727 +#: sql_help.c:3036 msgid "send_function" msgstr "función_send" -#: sql_help.c:2728 +#: sql_help.c:3037 msgid "type_modifier_input_function" msgstr "función_entrada_del_modificador_de_tipo" -#: sql_help.c:2729 +#: sql_help.c:3038 msgid "type_modifier_output_function" msgstr "función_salida_del_modificador_de_tipo" -#: sql_help.c:2730 +#: sql_help.c:3039 msgid "analyze_function" msgstr "función_analyze" -#: sql_help.c:2731 +#: sql_help.c:3040 msgid "internallength" msgstr "largo_interno" -#: sql_help.c:2732 +#: sql_help.c:3041 msgid "alignment" msgstr "alineamiento" -#: sql_help.c:2733 +#: sql_help.c:3042 msgid "storage" msgstr "almacenamiento" -#: sql_help.c:2734 +#: sql_help.c:3043 msgid "like_type" msgstr "como_tipo" -#: sql_help.c:2735 +#: sql_help.c:3044 msgid "category" msgstr "categoría" -#: sql_help.c:2736 +#: sql_help.c:3045 msgid "preferred" msgstr "preferido" -#: sql_help.c:2737 +#: sql_help.c:3046 msgid "default" msgstr "valor_por_omisión" -#: sql_help.c:2738 +#: sql_help.c:3047 msgid "element" msgstr "elemento" -#: sql_help.c:2739 +#: sql_help.c:3048 msgid "delimiter" msgstr "delimitador" -#: sql_help.c:2740 +#: sql_help.c:3049 msgid "collatable" msgstr "ordenable" -#: sql_help.c:2837 sql_help.c:3449 sql_help.c:3887 sql_help.c:3976 -#: sql_help.c:4126 sql_help.c:4226 sql_help.c:4320 +#: sql_help.c:3146 sql_help.c:3784 sql_help.c:4232 sql_help.c:4321 +#: sql_help.c:4471 sql_help.c:4571 sql_help.c:4689 msgid "with_query" msgstr "consulta_with" -#: sql_help.c:2839 sql_help.c:3451 sql_help.c:3906 sql_help.c:3912 -#: sql_help.c:3915 sql_help.c:3919 sql_help.c:3923 sql_help.c:3931 -#: sql_help.c:4145 sql_help.c:4151 sql_help.c:4154 sql_help.c:4158 -#: sql_help.c:4162 sql_help.c:4170 sql_help.c:4228 sql_help.c:4339 -#: sql_help.c:4345 sql_help.c:4348 sql_help.c:4352 sql_help.c:4356 -#: sql_help.c:4364 +#: sql_help.c:3148 sql_help.c:3786 sql_help.c:4251 sql_help.c:4257 +#: sql_help.c:4260 sql_help.c:4264 sql_help.c:4268 sql_help.c:4276 +#: sql_help.c:4490 sql_help.c:4496 sql_help.c:4499 sql_help.c:4503 +#: sql_help.c:4507 sql_help.c:4515 sql_help.c:4573 sql_help.c:4708 +#: sql_help.c:4714 sql_help.c:4717 sql_help.c:4721 sql_help.c:4725 +#: sql_help.c:4733 msgid "alias" msgstr "alias" -#: sql_help.c:2840 +#: sql_help.c:3149 msgid "using_list" msgstr "lista_using" -#: sql_help.c:2842 sql_help.c:3289 sql_help.c:3530 sql_help.c:4237 +#: sql_help.c:3151 sql_help.c:3624 sql_help.c:3865 sql_help.c:4582 msgid "cursor_name" msgstr "nombre_de_cursor" -#: sql_help.c:2843 sql_help.c:3457 sql_help.c:4238 +#: sql_help.c:3152 sql_help.c:3792 sql_help.c:4583 msgid "output_expression" msgstr "expresión_de_salida" -#: sql_help.c:2844 sql_help.c:3458 sql_help.c:3890 sql_help.c:3979 -#: sql_help.c:4129 sql_help.c:4239 sql_help.c:4323 +#: sql_help.c:3153 sql_help.c:3793 sql_help.c:4235 sql_help.c:4324 +#: sql_help.c:4474 sql_help.c:4584 sql_help.c:4692 msgid "output_name" msgstr "nombre_de_salida" -#: sql_help.c:2860 +#: sql_help.c:3169 msgid "code" msgstr "código" -#: sql_help.c:3235 +#: sql_help.c:3568 msgid "parameter" msgstr "parámetro" -#: sql_help.c:3255 sql_help.c:3256 sql_help.c:3555 +#: sql_help.c:3589 sql_help.c:3590 sql_help.c:3890 msgid "statement" msgstr "sentencia" -#: sql_help.c:3288 sql_help.c:3529 +#: sql_help.c:3623 sql_help.c:3864 msgid "direction" msgstr "dirección" -#: sql_help.c:3290 sql_help.c:3531 +#: sql_help.c:3625 sql_help.c:3866 msgid "where direction can be empty or one of:" msgstr "donde dirección puede ser vacío o uno de:" -#: sql_help.c:3291 sql_help.c:3292 sql_help.c:3293 sql_help.c:3294 -#: sql_help.c:3295 sql_help.c:3532 sql_help.c:3533 sql_help.c:3534 -#: sql_help.c:3535 sql_help.c:3536 sql_help.c:3900 sql_help.c:3902 -#: sql_help.c:3990 sql_help.c:3992 sql_help.c:4139 sql_help.c:4141 -#: sql_help.c:4268 sql_help.c:4270 sql_help.c:4333 sql_help.c:4335 +#: sql_help.c:3626 sql_help.c:3627 sql_help.c:3628 sql_help.c:3629 +#: sql_help.c:3630 sql_help.c:3867 sql_help.c:3868 sql_help.c:3869 +#: sql_help.c:3870 sql_help.c:3871 sql_help.c:4245 sql_help.c:4247 +#: sql_help.c:4335 sql_help.c:4337 sql_help.c:4484 sql_help.c:4486 +#: sql_help.c:4637 sql_help.c:4639 sql_help.c:4702 sql_help.c:4704 msgid "count" msgstr "cantidad" -#: sql_help.c:3375 sql_help.c:3708 +#: sql_help.c:3710 sql_help.c:4043 msgid "sequence_name" msgstr "nombre_secuencia" -#: sql_help.c:3388 sql_help.c:3721 +#: sql_help.c:3723 sql_help.c:4056 msgid "arg_name" msgstr "nombre_arg" -#: sql_help.c:3389 sql_help.c:3722 +#: sql_help.c:3724 sql_help.c:4057 msgid "arg_type" msgstr "tipo_arg" -#: sql_help.c:3394 sql_help.c:3727 +#: sql_help.c:3729 sql_help.c:4062 msgid "loid" msgstr "loid" -#: sql_help.c:3417 +#: sql_help.c:3752 msgid "remote_schema" msgstr "schema_remoto" -#: sql_help.c:3420 +#: sql_help.c:3755 msgid "local_schema" msgstr "schema_local" -#: sql_help.c:3455 +#: sql_help.c:3790 msgid "conflict_target" msgstr "destino_de_conflict" -#: sql_help.c:3456 +#: sql_help.c:3791 msgid "conflict_action" msgstr "acción_de_conflict" -#: sql_help.c:3459 +#: sql_help.c:3794 msgid "where conflict_target can be one of:" msgstr "donde destino_de_conflict puede ser uno de:" -#: sql_help.c:3460 +#: sql_help.c:3795 msgid "index_column_name" msgstr "nombre_de_columna_de_índice" -#: sql_help.c:3461 +#: sql_help.c:3796 msgid "index_expression" msgstr "expresión_de_índice" -#: sql_help.c:3464 +#: sql_help.c:3799 msgid "index_predicate" msgstr "predicado_de_índice" -#: sql_help.c:3466 +#: sql_help.c:3801 msgid "and conflict_action is one of:" msgstr "donde acción_de_conflict es una de:" -#: sql_help.c:3472 sql_help.c:4234 +#: sql_help.c:3807 sql_help.c:4579 msgid "sub-SELECT" msgstr "sub-SELECT" -#: sql_help.c:3481 sql_help.c:3544 sql_help.c:4210 +#: sql_help.c:3816 sql_help.c:3879 sql_help.c:4555 msgid "channel" msgstr "canal" -#: sql_help.c:3503 +#: sql_help.c:3838 msgid "lockmode" msgstr "modo_bloqueo" -#: sql_help.c:3504 +#: sql_help.c:3839 msgid "where lockmode is one of:" msgstr "donde modo_bloqueo es uno de:" -#: sql_help.c:3545 +#: sql_help.c:3880 msgid "payload" msgstr "carga" -#: sql_help.c:3572 +#: sql_help.c:3907 msgid "old_role" msgstr "rol_antiguo" -#: sql_help.c:3573 +#: sql_help.c:3908 msgid "new_role" msgstr "rol_nuevo" -#: sql_help.c:3598 sql_help.c:3759 sql_help.c:3767 +#: sql_help.c:3933 sql_help.c:4094 sql_help.c:4102 msgid "savepoint_name" msgstr "nombre_de_savepoint" -#: sql_help.c:3891 sql_help.c:3933 sql_help.c:3935 sql_help.c:3981 -#: sql_help.c:4130 sql_help.c:4172 sql_help.c:4174 sql_help.c:4324 -#: sql_help.c:4366 sql_help.c:4368 +#: sql_help.c:4236 sql_help.c:4278 sql_help.c:4280 sql_help.c:4326 +#: sql_help.c:4475 sql_help.c:4517 sql_help.c:4519 sql_help.c:4693 +#: sql_help.c:4735 sql_help.c:4737 msgid "from_item" msgstr "item_de_from" -#: sql_help.c:3893 sql_help.c:3945 sql_help.c:4132 sql_help.c:4184 -#: sql_help.c:4326 sql_help.c:4378 +#: sql_help.c:4238 sql_help.c:4290 sql_help.c:4477 sql_help.c:4529 +#: sql_help.c:4695 sql_help.c:4747 msgid "grouping_element" msgstr "elemento_agrupante" -#: sql_help.c:3895 sql_help.c:3985 sql_help.c:4134 sql_help.c:4328 +#: sql_help.c:4240 sql_help.c:4330 sql_help.c:4479 sql_help.c:4697 msgid "window_name" msgstr "nombre_de_ventana" -#: sql_help.c:3896 sql_help.c:3986 sql_help.c:4135 sql_help.c:4329 +#: sql_help.c:4241 sql_help.c:4331 sql_help.c:4480 sql_help.c:4698 msgid "window_definition" msgstr "definición_de_ventana" -#: sql_help.c:3897 sql_help.c:3911 sql_help.c:3949 sql_help.c:3987 -#: sql_help.c:4136 sql_help.c:4150 sql_help.c:4188 sql_help.c:4330 -#: sql_help.c:4344 sql_help.c:4382 +#: sql_help.c:4242 sql_help.c:4256 sql_help.c:4294 sql_help.c:4332 +#: sql_help.c:4481 sql_help.c:4495 sql_help.c:4533 sql_help.c:4699 +#: sql_help.c:4713 sql_help.c:4751 msgid "select" msgstr "select" -#: sql_help.c:3904 sql_help.c:4143 sql_help.c:4337 +#: sql_help.c:4249 sql_help.c:4488 sql_help.c:4706 msgid "where from_item can be one of:" msgstr "donde item_de_from puede ser uno de:" -#: sql_help.c:3907 sql_help.c:3913 sql_help.c:3916 sql_help.c:3920 -#: sql_help.c:3932 sql_help.c:4146 sql_help.c:4152 sql_help.c:4155 -#: sql_help.c:4159 sql_help.c:4171 sql_help.c:4340 sql_help.c:4346 -#: sql_help.c:4349 sql_help.c:4353 sql_help.c:4365 +#: sql_help.c:4252 sql_help.c:4258 sql_help.c:4261 sql_help.c:4265 +#: sql_help.c:4277 sql_help.c:4491 sql_help.c:4497 sql_help.c:4500 +#: sql_help.c:4504 sql_help.c:4516 sql_help.c:4709 sql_help.c:4715 +#: sql_help.c:4718 sql_help.c:4722 sql_help.c:4734 msgid "column_alias" msgstr "alias_de_columna" -#: sql_help.c:3908 sql_help.c:4147 sql_help.c:4341 +#: sql_help.c:4253 sql_help.c:4492 sql_help.c:4710 msgid "sampling_method" msgstr "método_de_sampleo" -#: sql_help.c:3909 sql_help.c:3918 sql_help.c:3922 sql_help.c:3926 -#: sql_help.c:3929 sql_help.c:4148 sql_help.c:4157 sql_help.c:4161 -#: sql_help.c:4165 sql_help.c:4168 sql_help.c:4342 sql_help.c:4351 -#: sql_help.c:4355 sql_help.c:4359 sql_help.c:4362 -msgid "argument" -msgstr "argumento" - -#: sql_help.c:3910 sql_help.c:4149 sql_help.c:4343 +#: sql_help.c:4255 sql_help.c:4494 sql_help.c:4712 msgid "seed" msgstr "semilla" -#: sql_help.c:3914 sql_help.c:3947 sql_help.c:4153 sql_help.c:4186 -#: sql_help.c:4347 sql_help.c:4380 +#: sql_help.c:4259 sql_help.c:4292 sql_help.c:4498 sql_help.c:4531 +#: sql_help.c:4716 sql_help.c:4749 msgid "with_query_name" msgstr "nombre_consulta_with" -#: sql_help.c:3924 sql_help.c:3927 sql_help.c:3930 sql_help.c:4163 -#: sql_help.c:4166 sql_help.c:4169 sql_help.c:4357 sql_help.c:4360 -#: sql_help.c:4363 +#: sql_help.c:4269 sql_help.c:4272 sql_help.c:4275 sql_help.c:4508 +#: sql_help.c:4511 sql_help.c:4514 sql_help.c:4726 sql_help.c:4729 +#: sql_help.c:4732 msgid "column_definition" msgstr "definición_de_columna" -#: sql_help.c:3934 sql_help.c:4173 sql_help.c:4367 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4736 msgid "join_type" msgstr "tipo_de_join" -#: sql_help.c:3936 sql_help.c:4175 sql_help.c:4369 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4738 msgid "join_condition" msgstr "condición_de_join" -#: sql_help.c:3937 sql_help.c:4176 sql_help.c:4370 +#: sql_help.c:4282 sql_help.c:4521 sql_help.c:4739 msgid "join_column" msgstr "columna_de_join" -#: sql_help.c:3938 sql_help.c:4177 sql_help.c:4371 +#: sql_help.c:4283 sql_help.c:4522 sql_help.c:4740 msgid "and grouping_element can be one of:" msgstr "donde elemento_agrupante puede ser una de:" -#: sql_help.c:3946 sql_help.c:4185 sql_help.c:4379 +#: sql_help.c:4291 sql_help.c:4530 sql_help.c:4748 msgid "and with_query is:" msgstr "y consulta_with es:" -#: sql_help.c:3950 sql_help.c:4189 sql_help.c:4383 +#: sql_help.c:4295 sql_help.c:4534 sql_help.c:4752 msgid "values" msgstr "valores" -#: sql_help.c:3951 sql_help.c:4190 sql_help.c:4384 +#: sql_help.c:4296 sql_help.c:4535 sql_help.c:4753 msgid "insert" msgstr "insert" -#: sql_help.c:3952 sql_help.c:4191 sql_help.c:4385 +#: sql_help.c:4297 sql_help.c:4536 sql_help.c:4754 msgid "update" msgstr "update" -#: sql_help.c:3953 sql_help.c:4192 sql_help.c:4386 +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4755 msgid "delete" msgstr "delete" -#: sql_help.c:3980 +#: sql_help.c:4325 msgid "new_table" msgstr "nueva_tabla" -#: sql_help.c:4005 +#: sql_help.c:4350 msgid "timezone" msgstr "huso_horario" -#: sql_help.c:4050 +#: sql_help.c:4395 msgid "snapshot_id" msgstr "id_de_snapshot" -#: sql_help.c:4235 +#: sql_help.c:4580 msgid "from_list" msgstr "lista_from" -#: sql_help.c:4266 +#: sql_help.c:4635 msgid "sort_expression" msgstr "expresión_orden" -#: sql_help.c:4393 sql_help.c:5178 +#: sql_help.c:4762 sql_help.c:5740 msgid "abort the current transaction" msgstr "aborta la transacción en curso" -#: sql_help.c:4398 +#: sql_help.c:4768 msgid "change the definition of an aggregate function" msgstr "cambia la definición de una función de agregación" -#: sql_help.c:4403 +#: sql_help.c:4774 msgid "change the definition of a collation" msgstr "cambia la definición de un ordenamiento" -#: sql_help.c:4408 +#: sql_help.c:4780 msgid "change the definition of a conversion" msgstr "cambia la definición de una conversión" -#: sql_help.c:4413 +#: sql_help.c:4786 msgid "change a database" msgstr "cambia una base de datos" -#: sql_help.c:4418 +#: sql_help.c:4792 msgid "define default access privileges" msgstr "define privilegios de acceso por omisión" -#: sql_help.c:4423 +#: sql_help.c:4798 msgid "change the definition of a domain" msgstr "cambia la definición de un dominio" -#: sql_help.c:4428 +#: sql_help.c:4804 msgid "change the definition of an event trigger" msgstr "cambia la definición de un disparador por evento" -#: sql_help.c:4433 +#: sql_help.c:4810 msgid "change the definition of an extension" msgstr "cambia la definición de una extensión" -#: sql_help.c:4438 +#: sql_help.c:4816 msgid "change the definition of a foreign-data wrapper" msgstr "cambia la definición de un conector de datos externos" -#: sql_help.c:4443 +#: sql_help.c:4822 msgid "change the definition of a foreign table" msgstr "cambia la definición de una tabla foránea" -#: sql_help.c:4448 +#: sql_help.c:4828 msgid "change the definition of a function" msgstr "cambia la definición de una función" -#: sql_help.c:4453 +#: sql_help.c:4834 msgid "change role name or membership" msgstr "cambiar nombre del rol o membresía" -#: sql_help.c:4458 +#: sql_help.c:4840 msgid "change the definition of an index" msgstr "cambia la definición de un índice" -#: sql_help.c:4463 +#: sql_help.c:4846 msgid "change the definition of a procedural language" msgstr "cambia la definición de un lenguaje procedural" -#: sql_help.c:4468 +#: sql_help.c:4852 msgid "change the definition of a large object" msgstr "cambia la definición de un objeto grande" -#: sql_help.c:4473 +#: sql_help.c:4858 msgid "change the definition of a materialized view" msgstr "cambia la definición de una vista materializada" -#: sql_help.c:4478 +#: sql_help.c:4864 msgid "change the definition of an operator" msgstr "cambia la definición de un operador" -#: sql_help.c:4483 +#: sql_help.c:4870 msgid "change the definition of an operator class" msgstr "cambia la definición de una clase de operadores" -#: sql_help.c:4488 +#: sql_help.c:4876 msgid "change the definition of an operator family" msgstr "cambia la definición de una familia de operadores" -#: sql_help.c:4493 +#: sql_help.c:4882 msgid "change the definition of a row level security policy" msgstr "cambia la definición de una política de seguridad de registros" -#: sql_help.c:4498 -#, fuzzy +#: sql_help.c:4888 +msgid "change the definition of a procedure" +msgstr "cambia la definición de un procedimiento" + +#: sql_help.c:4894 msgid "change the definition of a publication" -msgstr "cambia la definición de una función" +msgstr "cambia la definición de una publicación" -#: sql_help.c:4503 sql_help.c:4583 +#: sql_help.c:4900 sql_help.c:5002 msgid "change a database role" msgstr "cambia un rol de la base de datos" -#: sql_help.c:4508 +#: sql_help.c:4906 +msgid "change the definition of a routine" +msgstr "cambia la definición de una rutina" + +#: sql_help.c:4912 msgid "change the definition of a rule" msgstr "cambia la definición de una regla" -#: sql_help.c:4513 +#: sql_help.c:4918 msgid "change the definition of a schema" msgstr "cambia la definición de un esquema" -#: sql_help.c:4518 +#: sql_help.c:4924 msgid "change the definition of a sequence generator" msgstr "cambia la definición de un generador secuencial" -#: sql_help.c:4523 +#: sql_help.c:4930 msgid "change the definition of a foreign server" msgstr "cambia la definición de un servidor foráneo" -#: sql_help.c:4528 -#, fuzzy +#: sql_help.c:4936 msgid "change the definition of an extended statistics object" -msgstr "cambia la definición de una extensión" +msgstr "cambia la definición de un objeto de estadísticas extendidas" -#: sql_help.c:4533 -#, fuzzy +#: sql_help.c:4942 msgid "change the definition of a subscription" -msgstr "cambia la definición de una función" +msgstr "cambia la definición de una suscripción" -#: sql_help.c:4538 +#: sql_help.c:4948 msgid "change a server configuration parameter" msgstr "cambia un parámetro de configuración del servidor" -#: sql_help.c:4543 +#: sql_help.c:4954 msgid "change the definition of a table" msgstr "cambia la definición de una tabla" -#: sql_help.c:4548 +#: sql_help.c:4960 msgid "change the definition of a tablespace" msgstr "cambia la definición de un tablespace" -#: sql_help.c:4553 +#: sql_help.c:4966 msgid "change the definition of a text search configuration" msgstr "cambia la definición de una configuración de búsqueda en texto" -#: sql_help.c:4558 +#: sql_help.c:4972 msgid "change the definition of a text search dictionary" msgstr "cambia la definición de un diccionario de búsqueda en texto" -#: sql_help.c:4563 +#: sql_help.c:4978 msgid "change the definition of a text search parser" msgstr "cambia la definición de un analizador de búsqueda en texto" -#: sql_help.c:4568 +#: sql_help.c:4984 msgid "change the definition of a text search template" msgstr "cambia la definición de una plantilla de búsqueda en texto" -#: sql_help.c:4573 +#: sql_help.c:4990 msgid "change the definition of a trigger" msgstr "cambia la definición de un disparador" -#: sql_help.c:4578 +#: sql_help.c:4996 msgid "change the definition of a type" msgstr "cambia la definición de un tipo" -#: sql_help.c:4588 +#: sql_help.c:5008 msgid "change the definition of a user mapping" msgstr "cambia la definición de un mapeo de usuario" -#: sql_help.c:4593 +#: sql_help.c:5014 msgid "change the definition of a view" msgstr "cambia la definición de una vista" -#: sql_help.c:4598 +#: sql_help.c:5020 msgid "collect statistics about a database" msgstr "recolecta estadísticas sobre una base de datos" -#: sql_help.c:4603 sql_help.c:5243 +#: sql_help.c:5026 sql_help.c:5818 msgid "start a transaction block" msgstr "inicia un bloque de transacción" -#: sql_help.c:4608 -#, fuzzy +#: sql_help.c:5032 +msgid "invoke a procedure" +msgstr "invocar un procedimiento" + +#: sql_help.c:5038 msgid "force a write-ahead log checkpoint" -msgstr "fuerza un checkpoint del registro de transacciones" +msgstr "fuerza un checkpoint de wal" -#: sql_help.c:4613 +#: sql_help.c:5044 msgid "close a cursor" msgstr "cierra un cursor" -#: sql_help.c:4618 +#: sql_help.c:5050 msgid "cluster a table according to an index" msgstr "reordena una tabla siguiendo un índice" -#: sql_help.c:4623 +#: sql_help.c:5056 msgid "define or change the comment of an object" msgstr "define o cambia un comentario sobre un objeto" -#: sql_help.c:4628 sql_help.c:5078 +#: sql_help.c:5062 sql_help.c:5620 msgid "commit the current transaction" msgstr "compromete la transacción en curso" -#: sql_help.c:4633 +#: sql_help.c:5068 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "confirma una transacción que fue preparada para two-phase commit" -#: sql_help.c:4638 +#: sql_help.c:5074 msgid "copy data between a file and a table" msgstr "copia datos entre un archivo y una tabla" -#: sql_help.c:4643 +#: sql_help.c:5080 msgid "define a new access method" msgstr "define un nuevo método de acceso" -#: sql_help.c:4648 +#: sql_help.c:5086 msgid "define a new aggregate function" msgstr "define una nueva función de agregación" -#: sql_help.c:4653 +#: sql_help.c:5092 msgid "define a new cast" msgstr "define una nueva conversión de tipo" -#: sql_help.c:4658 +#: sql_help.c:5098 msgid "define a new collation" msgstr "define un nuevo ordenamiento" -#: sql_help.c:4663 +#: sql_help.c:5104 msgid "define a new encoding conversion" msgstr "define una nueva conversión de codificación" -#: sql_help.c:4668 +#: sql_help.c:5110 msgid "create a new database" msgstr "crea una nueva base de datos" -#: sql_help.c:4673 +#: sql_help.c:5116 msgid "define a new domain" msgstr "define un nuevo dominio" -#: sql_help.c:4678 +#: sql_help.c:5122 msgid "define a new event trigger" msgstr "define un nuevo disparador por evento" -#: sql_help.c:4683 +#: sql_help.c:5128 msgid "install an extension" msgstr "instala una extensión" -#: sql_help.c:4688 +#: sql_help.c:5134 msgid "define a new foreign-data wrapper" msgstr "define un nuevo conector de datos externos" -#: sql_help.c:4693 +#: sql_help.c:5140 msgid "define a new foreign table" msgstr "define una nueva tabla foránea" -#: sql_help.c:4698 +#: sql_help.c:5146 msgid "define a new function" msgstr "define una nueva función" -#: sql_help.c:4703 sql_help.c:4748 sql_help.c:4833 +#: sql_help.c:5152 sql_help.c:5212 sql_help.c:5314 msgid "define a new database role" msgstr "define un nuevo rol de la base de datos" -#: sql_help.c:4708 +#: sql_help.c:5158 msgid "define a new index" msgstr "define un nuevo índice" -#: sql_help.c:4713 +#: sql_help.c:5164 msgid "define a new procedural language" msgstr "define un nuevo lenguaje procedural" -#: sql_help.c:4718 +#: sql_help.c:5170 msgid "define a new materialized view" msgstr "define una nueva vista materializada" -#: sql_help.c:4723 +#: sql_help.c:5176 msgid "define a new operator" msgstr "define un nuevo operador" -#: sql_help.c:4728 +#: sql_help.c:5182 msgid "define a new operator class" msgstr "define una nueva clase de operadores" -#: sql_help.c:4733 +#: sql_help.c:5188 msgid "define a new operator family" msgstr "define una nueva familia de operadores" -#: sql_help.c:4738 +#: sql_help.c:5194 msgid "define a new row level security policy for a table" msgstr "define una nueva política de seguridad de registros para una tabla" -#: sql_help.c:4743 -#, fuzzy +#: sql_help.c:5200 +msgid "define a new procedure" +msgstr "define un nuevo procedimiento" + +#: sql_help.c:5206 msgid "define a new publication" -msgstr "define una nueva función" +msgstr "define una nueva publicación" -#: sql_help.c:4753 +#: sql_help.c:5218 msgid "define a new rewrite rule" msgstr "define una nueva regla de reescritura" -#: sql_help.c:4758 +#: sql_help.c:5224 msgid "define a new schema" msgstr "define un nuevo schema" -#: sql_help.c:4763 +#: sql_help.c:5230 msgid "define a new sequence generator" msgstr "define un nuevo generador secuencial" -#: sql_help.c:4768 +#: sql_help.c:5236 msgid "define a new foreign server" msgstr "define un nuevo servidor foráneo" -#: sql_help.c:4773 -#, fuzzy +#: sql_help.c:5242 msgid "define extended statistics" -msgstr "define una nueva conversión de tipo" +msgstr "define estadísticas extendidas" -#: sql_help.c:4778 -#, fuzzy +#: sql_help.c:5248 msgid "define a new subscription" -msgstr "define una nueva función" +msgstr "define una nueva suscripción" -#: sql_help.c:4783 +#: sql_help.c:5254 msgid "define a new table" msgstr "define una nueva tabla" -#: sql_help.c:4788 sql_help.c:5208 +#: sql_help.c:5260 sql_help.c:5776 msgid "define a new table from the results of a query" msgstr "crea una nueva tabla usando los resultados de una consulta" -#: sql_help.c:4793 +#: sql_help.c:5266 msgid "define a new tablespace" msgstr "define un nuevo tablespace" -#: sql_help.c:4798 +#: sql_help.c:5272 msgid "define a new text search configuration" msgstr "define una nueva configuración de búsqueda en texto" -#: sql_help.c:4803 +#: sql_help.c:5278 msgid "define a new text search dictionary" msgstr "define un nuevo diccionario de búsqueda en texto" -#: sql_help.c:4808 +#: sql_help.c:5284 msgid "define a new text search parser" msgstr "define un nuevo analizador de búsqueda en texto" -#: sql_help.c:4813 +#: sql_help.c:5290 msgid "define a new text search template" msgstr "define una nueva plantilla de búsqueda en texto" -#: sql_help.c:4818 +#: sql_help.c:5296 msgid "define a new transform" msgstr "define una nueva transformación" -#: sql_help.c:4823 +#: sql_help.c:5302 msgid "define a new trigger" msgstr "define un nuevo disparador" -#: sql_help.c:4828 +#: sql_help.c:5308 msgid "define a new data type" msgstr "define un nuevo tipo de datos" -#: sql_help.c:4838 +#: sql_help.c:5320 msgid "define a new mapping of a user to a foreign server" msgstr "define un nuevo mapa de usuario a servidor foráneo" -#: sql_help.c:4843 +#: sql_help.c:5326 msgid "define a new view" msgstr "define una nueva vista" -#: sql_help.c:4848 +#: sql_help.c:5332 msgid "deallocate a prepared statement" msgstr "elimina una sentencia preparada" -#: sql_help.c:4853 +#: sql_help.c:5338 msgid "define a cursor" msgstr "define un nuevo cursor" -#: sql_help.c:4858 +#: sql_help.c:5344 msgid "delete rows of a table" msgstr "elimina filas de una tabla" -#: sql_help.c:4863 +#: sql_help.c:5350 msgid "discard session state" msgstr "descartar datos de la sesión" -#: sql_help.c:4868 +#: sql_help.c:5356 msgid "execute an anonymous code block" msgstr "ejecutar un bloque anónimo de código" -#: sql_help.c:4873 +#: sql_help.c:5362 msgid "remove an access method" msgstr "elimina un método de acceso" -#: sql_help.c:4878 +#: sql_help.c:5368 msgid "remove an aggregate function" msgstr "elimina una función de agregación" -#: sql_help.c:4883 +#: sql_help.c:5374 msgid "remove a cast" msgstr "elimina una conversión de tipo" -#: sql_help.c:4888 +#: sql_help.c:5380 msgid "remove a collation" msgstr "elimina un ordenamiento" -#: sql_help.c:4893 +#: sql_help.c:5386 msgid "remove a conversion" msgstr "elimina una conversión de codificación" -#: sql_help.c:4898 +#: sql_help.c:5392 msgid "remove a database" msgstr "elimina una base de datos" -#: sql_help.c:4903 +#: sql_help.c:5398 msgid "remove a domain" msgstr "elimina un dominio" -#: sql_help.c:4908 +#: sql_help.c:5404 msgid "remove an event trigger" msgstr "elimina un disparador por evento" -#: sql_help.c:4913 +#: sql_help.c:5410 msgid "remove an extension" msgstr "elimina una extensión" -#: sql_help.c:4918 +#: sql_help.c:5416 msgid "remove a foreign-data wrapper" msgstr "elimina un conector de datos externos" -#: sql_help.c:4923 +#: sql_help.c:5422 msgid "remove a foreign table" msgstr "elimina una tabla foránea" -#: sql_help.c:4928 +#: sql_help.c:5428 msgid "remove a function" msgstr "elimina una función" -#: sql_help.c:4933 sql_help.c:4983 sql_help.c:5063 +#: sql_help.c:5434 sql_help.c:5500 sql_help.c:5602 msgid "remove a database role" msgstr "elimina un rol de base de datos" -#: sql_help.c:4938 +#: sql_help.c:5440 msgid "remove an index" msgstr "elimina un índice" -#: sql_help.c:4943 +#: sql_help.c:5446 msgid "remove a procedural language" msgstr "elimina un lenguaje procedural" -#: sql_help.c:4948 +#: sql_help.c:5452 msgid "remove a materialized view" msgstr "elimina una vista materializada" -#: sql_help.c:4953 +#: sql_help.c:5458 msgid "remove an operator" msgstr "elimina un operador" -#: sql_help.c:4958 +#: sql_help.c:5464 msgid "remove an operator class" msgstr "elimina una clase de operadores" -#: sql_help.c:4963 +#: sql_help.c:5470 msgid "remove an operator family" msgstr "elimina una familia de operadores" -#: sql_help.c:4968 +#: sql_help.c:5476 msgid "remove database objects owned by a database role" msgstr "elimina objetos de propiedad de un rol de la base de datos" -#: sql_help.c:4973 +#: sql_help.c:5482 msgid "remove a row level security policy from a table" msgstr "elimina una política de seguridad de registros de una tabla" -#: sql_help.c:4978 -#, fuzzy +#: sql_help.c:5488 +msgid "remove a procedure" +msgstr "elimina un procedimiento" + +#: sql_help.c:5494 msgid "remove a publication" -msgstr "elimina una función" +msgstr "elimina una publicación" + +#: sql_help.c:5506 +msgid "remove a routine" +msgstr "elimina una rutina" -#: sql_help.c:4988 +#: sql_help.c:5512 msgid "remove a rewrite rule" msgstr "elimina una regla de reescritura" -#: sql_help.c:4993 +#: sql_help.c:5518 msgid "remove a schema" msgstr "elimina un schema" -#: sql_help.c:4998 +#: sql_help.c:5524 msgid "remove a sequence" msgstr "elimina un generador secuencial" -#: sql_help.c:5003 +#: sql_help.c:5530 msgid "remove a foreign server descriptor" msgstr "elimina un descriptor de servidor foráneo" -#: sql_help.c:5008 -#, fuzzy +#: sql_help.c:5536 msgid "remove extended statistics" -msgstr "elimina una extensión" +msgstr "elimina estadísticas extendidas" -#: sql_help.c:5013 -#, fuzzy +#: sql_help.c:5542 msgid "remove a subscription" -msgstr "elimina una función" +msgstr "elimina una suscripción" -#: sql_help.c:5018 +#: sql_help.c:5548 msgid "remove a table" msgstr "elimina una tabla" -#: sql_help.c:5023 +#: sql_help.c:5554 msgid "remove a tablespace" msgstr "elimina un tablespace" -#: sql_help.c:5028 +#: sql_help.c:5560 msgid "remove a text search configuration" msgstr "elimina una configuración de búsqueda en texto" -#: sql_help.c:5033 +#: sql_help.c:5566 msgid "remove a text search dictionary" msgstr "elimina un diccionario de búsqueda en texto" -#: sql_help.c:5038 +#: sql_help.c:5572 msgid "remove a text search parser" msgstr "elimina un analizador de búsqueda en texto" -#: sql_help.c:5043 +#: sql_help.c:5578 msgid "remove a text search template" msgstr "elimina una plantilla de búsqueda en texto" -#: sql_help.c:5048 +#: sql_help.c:5584 msgid "remove a transform" msgstr "elimina una transformación" -#: sql_help.c:5053 +#: sql_help.c:5590 msgid "remove a trigger" msgstr "elimina un disparador" -#: sql_help.c:5058 +#: sql_help.c:5596 msgid "remove a data type" msgstr "elimina un tipo de datos" -#: sql_help.c:5068 +#: sql_help.c:5608 msgid "remove a user mapping for a foreign server" msgstr "elimina un mapeo de usuario para un servidor remoto" -#: sql_help.c:5073 +#: sql_help.c:5614 msgid "remove a view" msgstr "elimina una vista" -#: sql_help.c:5083 +#: sql_help.c:5626 msgid "execute a prepared statement" msgstr "ejecuta una sentencia preparada" -#: sql_help.c:5088 +#: sql_help.c:5632 msgid "show the execution plan of a statement" msgstr "muestra el plan de ejecución de una sentencia" -#: sql_help.c:5093 +#: sql_help.c:5638 msgid "retrieve rows from a query using a cursor" msgstr "recupera filas de una consulta usando un cursor" -#: sql_help.c:5098 +#: sql_help.c:5644 msgid "define access privileges" msgstr "define privilegios de acceso" -#: sql_help.c:5103 +#: sql_help.c:5650 msgid "import table definitions from a foreign server" msgstr "importa definiciones de tablas desde un servidor foráneo" -#: sql_help.c:5108 +#: sql_help.c:5656 msgid "create new rows in a table" msgstr "crea nuevas filas en una tabla" -#: sql_help.c:5113 +#: sql_help.c:5662 msgid "listen for a notification" msgstr "escucha notificaciones" -#: sql_help.c:5118 +#: sql_help.c:5668 msgid "load a shared library file" msgstr "carga un archivo de biblioteca compartida" -#: sql_help.c:5123 +#: sql_help.c:5674 msgid "lock a table" msgstr "bloquea una tabla" -#: sql_help.c:5128 +#: sql_help.c:5680 msgid "position a cursor" msgstr "reposiciona un cursor" -#: sql_help.c:5133 +#: sql_help.c:5686 msgid "generate a notification" msgstr "genera una notificación" -#: sql_help.c:5138 +#: sql_help.c:5692 msgid "prepare a statement for execution" msgstr "prepara una sentencia para ejecución" -#: sql_help.c:5143 +#: sql_help.c:5698 msgid "prepare the current transaction for two-phase commit" msgstr "prepara la transacción actual para two-phase commit" -#: sql_help.c:5148 +#: sql_help.c:5704 msgid "change the ownership of database objects owned by a database role" msgstr "cambia de dueño a los objetos de propiedad de un rol de la base de datos" -#: sql_help.c:5153 +#: sql_help.c:5710 msgid "replace the contents of a materialized view" msgstr "reemplaza los contenidos de una vista materializada" -#: sql_help.c:5158 +#: sql_help.c:5716 msgid "rebuild indexes" msgstr "reconstruye índices" -#: sql_help.c:5163 +#: sql_help.c:5722 msgid "destroy a previously defined savepoint" msgstr "destruye un savepoint previamente definido" -#: sql_help.c:5168 +#: sql_help.c:5728 msgid "restore the value of a run-time parameter to the default value" msgstr "restaura el valor de un parámetro de configuración al valor inicial" -#: sql_help.c:5173 +#: sql_help.c:5734 msgid "remove access privileges" msgstr "revoca privilegios de acceso" -#: sql_help.c:5183 +#: sql_help.c:5746 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "cancela una transacción que fue previamente preparada para two-phase commit." -#: sql_help.c:5188 +#: sql_help.c:5752 msgid "roll back to a savepoint" msgstr "descartar hacia un savepoint" -#: sql_help.c:5193 +#: sql_help.c:5758 msgid "define a new savepoint within the current transaction" msgstr "define un nuevo savepoint en la transacción en curso" -#: sql_help.c:5198 +#: sql_help.c:5764 msgid "define or change a security label applied to an object" msgstr "define o cambia una etiqueta de seguridad sobre un objeto" -#: sql_help.c:5203 sql_help.c:5248 sql_help.c:5278 +#: sql_help.c:5770 sql_help.c:5824 sql_help.c:5860 msgid "retrieve rows from a table or view" msgstr "recupera filas desde una tabla o vista" -#: sql_help.c:5213 +#: sql_help.c:5782 msgid "change a run-time parameter" msgstr "cambia un parámetro de configuración" -#: sql_help.c:5218 +#: sql_help.c:5788 msgid "set constraint check timing for the current transaction" msgstr "define el modo de verificación de las restricciones de la transacción en curso" -#: sql_help.c:5223 +#: sql_help.c:5794 msgid "set the current user identifier of the current session" msgstr "define el identificador de usuario actual de la sesión actual" -#: sql_help.c:5228 +#: sql_help.c:5800 msgid "set the session user identifier and the current user identifier of the current session" msgstr "" "define el identificador del usuario de sesión y el identificador\n" "del usuario actual de la sesión en curso" -#: sql_help.c:5233 +#: sql_help.c:5806 msgid "set the characteristics of the current transaction" msgstr "define las características de la transacción en curso" -#: sql_help.c:5238 +#: sql_help.c:5812 msgid "show the value of a run-time parameter" msgstr "muestra el valor de un parámetro de configuración" -#: sql_help.c:5253 +#: sql_help.c:5830 msgid "empty a table or set of tables" msgstr "vacía una tabla o conjunto de tablas" -#: sql_help.c:5258 +#: sql_help.c:5836 msgid "stop listening for a notification" msgstr "deja de escuchar una notificación" -#: sql_help.c:5263 +#: sql_help.c:5842 msgid "update rows of a table" msgstr "actualiza filas de una tabla" -#: sql_help.c:5268 +#: sql_help.c:5848 msgid "garbage-collect and optionally analyze a database" msgstr "recolecta basura y opcionalmente estadísticas sobre una base de datos" -#: sql_help.c:5273 +#: sql_help.c:5854 msgid "compute a set of rows" msgstr "calcula un conjunto de registros" -#: startup.c:184 +#: startup.c:216 #, c-format -msgid "%s: -1 can only be used in non-interactive mode\n" -msgstr "%s: -1 sólo puede ser usado en modo no interactivo\n" +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 sólo puede ser usado en modo no interactivo" -#: startup.c:287 +#: startup.c:303 #, c-format -msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%s: no se pudo abrir archivo de log «%s»: %s\n" +msgid "could not connect to server: %s" +msgstr "no se pudo conectar al servidor: %s" -#: startup.c:394 +#: startup.c:331 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "no se pudo abrir el archivo de registro «%s»: %m" + +#: startup.c:442 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5688,116 +6124,57 @@ msgstr "" "Digite «help» para obtener ayuda.\n" "\n" -#: startup.c:543 +#: startup.c:592 #, c-format -msgid "%s: could not set printing parameter \"%s\"\n" -msgstr "%s: no se pudo definir parámetro de impresión «%s»\n" +msgid "could not set printing parameter \"%s\"" +msgstr "no se pudo definir parámetro de impresión «%s»" -#: startup.c:645 +#: startup.c:697 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Use «%s --help» para obtener más información.\n" -#: startup.c:662 +#: startup.c:714 #, c-format -msgid "%s: warning: extra command-line argument \"%s\" ignored\n" -msgstr "%s: atención: se ignoró argumento extra «%s» en línea de órdenes\n" +msgid "extra command-line argument \"%s\" ignored" +msgstr "se ignoró argumento extra «%s» en línea de órdenes" -#: startup.c:711 +#: startup.c:763 #, c-format -msgid "%s: could not find own program executable\n" -msgstr "%s: no se pudo encontrar el ejecutable propio\n" +msgid "could not find own program executable" +msgstr "no se pudo encontrar el ejecutable propio" -#: tab-complete.c:4208 +#: tab-complete.c:4380 #, c-format msgid "" "tab completion query failed: %s\n" "Query was:\n" -"%s\n" +"%s" msgstr "" "la consulta para completación por tabulador falló: %s\n" "La consulta era:\n" -"%s\n" +"%s" -#: variables.c:139 -#, fuzzy, c-format -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" -msgstr "valor «%s» no reconocido para «%s»; asumiendo «%s»\n" +#: variables.c:141 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "valor «%s» no reconocido para «%s»: se esperaba booleano" -#: variables.c:176 -#, fuzzy, c-format -msgid "invalid value \"%s\" for \"%s\": integer expected\n" -msgstr "valor «%s» no reconocido para «%s»; asumiendo «%s»\n" +#: variables.c:178 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "valor «%s» no válido para «%s»: se esperaba número entero" -#: variables.c:224 -#, fuzzy, c-format -msgid "invalid variable name: \"%s\"\n" -msgstr "número de línea no válido: %s\n" +#: variables.c:226 +#, c-format +msgid "invalid variable name: \"%s\"" +msgstr "nombre de variable no válido: «%s»" -#: variables.c:393 -#, fuzzy, c-format +#: variables.c:395 +#, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" -"Available values are: %s.\n" -msgstr "valor «%s» no reconocido para «%s»; asumiendo «%s»\n" - -#~ msgid "Password encryption failed.\n" -#~ msgstr "El cifrado de la contraseña falló.\n" - -#~ msgid "\\%s: error while setting variable\n" -#~ msgstr "\\%s: error mientras se definía la variable\n" - -#~ msgid "+ opt(%d) = |%s|\n" -#~ msgstr "+ opt(%d) = |%s|\n" - -#~ msgid "could not set variable \"%s\"\n" -#~ msgstr "no se pudo definir la variable «%s»\n" - -#~ msgid "Modifiers" -#~ msgstr "Modificadores" - -#~ msgid "collate %s" -#~ msgstr "collate %s" - -#~ msgid "not null" -#~ msgstr "not null" - -#~ msgid "default %s" -#~ msgstr "valor por omisión %s" - -#~ msgid "Modifier" -#~ msgstr "Modificador" - -#~ msgid "%s: could not set variable \"%s\"\n" -#~ msgstr "%s: no se pudo definir la variable «%s»\n" - -#~ msgid "SSL connection (unknown cipher)\n" -#~ msgstr "conexión SSL (cifrado desconocido)\n" - -#~ msgid "(No rows)\n" -#~ msgstr "(Sin filas)\n" - -#~ msgid "expression_index" -#~ msgstr "expresión_índice" - -#~ msgid "column_name_index" -#~ msgstr "nombre_de_columna_en_índice" - -#~ msgid " unicode_column_linestyle\n" -#~ msgstr " unicode_column_linestyle\n" - -#~ msgid " unicode_border_linestyle\n" -#~ msgstr " unicode_border_linestyle\n" - -#~ msgid "" -#~ "\n" -#~ "Display influencing variables:\n" -#~ msgstr "" -#~ "\n" -#~ "Variables que influencian el despliegue:\n" - -#~ msgid "Watch every %lds\t%s" -#~ msgstr "Ejecución cada %lds\t%s" - -#~ msgid "Object Description" -#~ msgstr "Descripciones de objetos" +"Available values are: %s." +msgstr "" +"valor «%s» no reconocido para «%s»\n" +"Los valores disponibles son: %s." diff --git a/src/bin/psql/po/fr.po b/src/bin/psql/po/fr.po index 2b5ecb32b7c..a8ef2c83119 100644 --- a/src/bin/psql/po/fr.po +++ b/src/bin/psql/po/fr.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-28 18:44+0000\n" -"PO-Revision-Date: 2017-07-29 09:12+0200\n" +"POT-Creation-Date: 2018-10-08 21:44+0000\n" +"PO-Revision-Date: 2019-01-30 00:06+0100\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.1.1\n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -56,8 +56,7 @@ msgid "pclose failed: %s" msgstr "échec de pclose : %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:608 input.c:227 mainloop.c:82 -#: mainloop.c:276 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 #, c-format msgid "out of memory\n" msgstr "mémoire épuisée\n" @@ -72,7 +71,7 @@ msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n" msgid "could not look up effective user ID %ld: %s" msgstr "n'a pas pu trouver l'identifiant réel %ld de l'utilisateur : %s" -#: ../../common/username.c:45 command.c:555 +#: ../../common/username.c:45 command.c:554 msgid "user does not exist" msgstr "l'utilisateur n'existe pas" @@ -123,275 +122,276 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu ligne)" msgstr[1] "(%lu lignes)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:2915 #, c-format msgid "Interrupted\n" msgstr "Interrompu\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:2979 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "" "Ne peut pas ajouter l'en-tête au contenu de la table : le nombre de colonnes\n" "%d est dépassé.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3019 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "" "Ne peut pas ajouter une cellule au contenu de la table : le nombre total des\n" "cellules %d est dépassé.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3268 #, c-format msgid "invalid output format (internal error): %d" msgstr "format de sortie invalide (erreur interne) : %d" -#: ../../fe_utils/psqlscan.l:713 +#: ../../fe_utils/psqlscan.l:724 #, c-format msgid "skipping recursive expansion of variable \"%s\"\n" msgstr "ignore l'expansion récursive de la variable « %s »\n" -#: command.c:223 +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "Commande \\%s invalide. Essayez \\? pour l'aide-mémoire.\n" -#: command.c:225 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" msgstr "commande \\%s invalide\n" -#: command.c:243 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s : argument « %s » supplémentaire ignoré\n" -#: command.c:295 +#: command.c:292 #, c-format msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "commande \\%s ignorée ; utilisez \\endif ou Ctrl-C pour quitter le bloc \\if courant\n" -#: command.c:553 +#: command.c:552 #, c-format msgid "could not get home directory for user ID %ld: %s\n" msgstr "n'a pas pu obtenir le répertoire principal pour l'identifiant d'utilisateur %ld : %s\n" -#: command.c:571 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s : n'a pas pu accéder au répertoire « %s » : %s\n" -#: command.c:596 common.c:648 common.c:706 common.c:1242 +#: command.c:595 common.c:696 common.c:754 common.c:1292 #, c-format msgid "You are currently not connected to a database.\n" msgstr "Vous n'êtes pas connecté à une base de données.\n" -#: command.c:621 +#: command.c:602 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » via le socket dans « %s » via le port « %s ».\n" -#: command.c:624 +#: command.c:605 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Vous êtes connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » via le port « %s ».\n" -#: command.c:915 command.c:1005 command.c:1114 command.c:2523 +#: command.c:895 command.c:991 command.c:2376 #, c-format msgid "no query buffer\n" msgstr "aucun tampon de requête\n" -#: command.c:948 command.c:4765 +#: command.c:928 command.c:4648 #, c-format msgid "invalid line number: %s\n" msgstr "numéro de ligne invalide : %s\n" -#: command.c:998 +#: command.c:982 #, c-format msgid "The server (version %s) does not support editing function source.\n" msgstr "Le serveur (version %s) ne supporte pas l'édition du code de la fonction.\n" -#: command.c:1073 command.c:1154 -msgid "No changes" -msgstr "Aucun changement" - -#: command.c:1107 +#: command.c:985 #, c-format msgid "The server (version %s) does not support editing view definitions.\n" msgstr "Le serveur (version %s) ne supporte pas l'édition des définitions de vue.\n" -#: command.c:1231 +#: command.c:1067 +msgid "No changes" +msgstr "Aucun changement" + +#: command.c:1144 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "%s : nom d'encodage invalide ou procédure de conversion introuvable\n" -#: command.c:1266 command.c:1888 command.c:3169 command.c:4867 common.c:173 -#: common.c:244 common.c:541 common.c:1288 common.c:1316 common.c:1417 -#: copy.c:489 copy.c:708 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 #, c-format msgid "%s" msgstr "%s" -#: command.c:1270 +#: command.c:1183 msgid "out of memory" msgstr "mémoire épuisée" -#: command.c:1273 +#: command.c:1186 msgid "There is no previous error." msgstr "Il n'y a pas d'erreur précédente." -#: command.c:1444 command.c:1749 command.c:1763 command.c:1780 command.c:1940 -#: command.c:2177 command.c:2490 command.c:2530 +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s : argument requis manquant\n" -#: command.c:1575 +#: command.c:1505 #, c-format msgid "\\elif: cannot occur after \\else\n" msgstr "\\elif : ne peut pas survenir après \\else\n" -#: command.c:1580 +#: command.c:1510 #, c-format msgid "\\elif: no matching \\if\n" msgstr "\\elif : pas de \\if correspondant\n" -#: command.c:1644 +#: command.c:1574 #, c-format msgid "\\else: cannot occur after \\else\n" msgstr "\\else : ne peut pas survenir après \\else\n" -#: command.c:1649 +#: command.c:1579 #, c-format msgid "\\else: no matching \\if\n" msgstr "\\else : pas de \\if correspondant\n" -#: command.c:1689 +#: command.c:1619 #, c-format msgid "\\endif: no matching \\if\n" msgstr "\\endif : pas de \\if correspondant\n" -#: command.c:1844 +#: command.c:1774 msgid "Query buffer is empty." msgstr "Le tampon de requête est vide." -#: command.c:1866 +#: command.c:1796 msgid "Enter new password: " msgstr "Saisissez le nouveau mot de passe : " -#: command.c:1867 +#: command.c:1797 msgid "Enter it again: " msgstr "Saisissez-le à nouveau : " -#: command.c:1871 +#: command.c:1801 #, c-format msgid "Passwords didn't match.\n" msgstr "Les mots de passe ne sont pas identiques.\n" -#: command.c:1970 +#: command.c:1900 #, c-format msgid "\\%s: could not read value for variable\n" msgstr "\\%s : n'a pas pu lire la valeur pour la variable\n" -#: command.c:2073 +#: command.c:2003 msgid "Query buffer reset (cleared)." msgstr "Le tampon de requête a été effacé." -#: command.c:2095 +#: command.c:2025 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Historique sauvegardé dans le fichier « %s ».\n" -#: command.c:2182 +#: command.c:2112 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s : le nom de la variable d'environnement ne doit pas contenir « = »\n" -#: command.c:2238 +#: command.c:2173 #, c-format msgid "The server (version %s) does not support showing function source.\n" msgstr "Le serveur (version %s) ne supporte pas l'affichage du code de la fonction.\n" -#: command.c:2245 -#, c-format -msgid "function name is required\n" -msgstr "le nom de la fonction est requis\n" - -#: command.c:2332 +#: command.c:2176 #, c-format msgid "The server (version %s) does not support showing view definitions.\n" msgstr "Le serveur (version %s) ne supporte pas l'affichage des définitions de vues.\n" -#: command.c:2339 +#: command.c:2183 +#, c-format +msgid "function name is required\n" +msgstr "le nom de la fonction est requis\n" + +#: command.c:2185 #, c-format msgid "view name is required\n" msgstr "le nom de la vue est requis\n" -#: command.c:2462 +#: command.c:2315 msgid "Timing is on." msgstr "Chronométrage activé." -#: command.c:2464 +#: command.c:2317 msgid "Timing is off." msgstr "Chronométrage désactivé." -#: command.c:2549 command.c:2577 command.c:3518 command.c:3521 command.c:3524 -#: command.c:3530 command.c:3532 command.c:3540 command.c:3550 command.c:3559 -#: command.c:3573 command.c:3590 command.c:3648 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:760 psqlscanslash.l:771 -#: psqlscanslash.l:781 +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s : %s\n" -#: command.c:2961 startup.c:202 +#: command.c:2814 startup.c:214 startup.c:265 msgid "Password: " msgstr "Mot de passe : " -#: command.c:2966 startup.c:204 +#: command.c:2819 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "Mot de passe pour l'utilisateur %s : " -#: command.c:3016 +#: command.c:2869 #, c-format msgid "All connection parameters must be supplied because no database connection exists\n" msgstr "" "Tous les paramètres de connexions doivent être fournis car il n'y a pas de connexion\n" "à une base de données existante.\n" -#: command.c:3173 +#: command.c:3037 #, c-format msgid "Previous connection kept\n" msgstr "Connexion précédente conservée\n" -#: command.c:3177 +#: command.c:3041 #, c-format msgid "\\connect: %s" msgstr "\\connect : %s" -#: command.c:3213 +#: command.c:3077 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » via le socket dans « %s » via le port « %s ».\n" -#: command.c:3216 +#: command.c:3080 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s » sur l'hôte « %s » via le port « %s ».\n" -#: command.c:3220 +#: command.c:3084 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Vous êtes maintenant connecté à la base de données « %s » en tant qu'utilisateur « %s ».\n" -#: command.c:3253 +#: command.c:3117 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, serveur %s)\n" -#: command.c:3261 +#: command.c:3125 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -400,24 +400,24 @@ msgstr "" "ATTENTION : %s version majeure %s, version majeure du serveur %s.\n" " Certaines fonctionnalités de psql pourraient ne pas fonctionner.\n" -#: command.c:3298 +#: command.c:3162 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "Connexion SSL (protocole : %s, chiffrement : %s, bits : %s, compression : %s)\n" -#: command.c:3299 command.c:3300 command.c:3301 +#: command.c:3163 command.c:3164 command.c:3165 msgid "unknown" msgstr "inconnu" -#: command.c:3302 help.c:45 +#: command.c:3166 help.c:45 msgid "off" msgstr "désactivé" -#: command.c:3302 help.c:45 +#: command.c:3166 help.c:45 msgid "on" msgstr "activé" -#: command.c:3322 +#: command.c:3186 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -429,243 +429,243 @@ msgstr "" " Voir la section « Notes aux utilisateurs de Windows » de la page\n" " référence de psql pour les détails.\n" -#: command.c:3407 +#: command.c:3290 #, c-format msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" msgstr "" "la variable d'environnement EDITOR_LINENUMBER_SWITCH doit être configurée\n" "pour spécifier un numéro de ligne\n" -#: command.c:3436 +#: command.c:3319 #, c-format msgid "could not start editor \"%s\"\n" msgstr "n'a pas pu exécuter l'éditeur « %s »\n" -#: command.c:3438 +#: command.c:3321 #, c-format msgid "could not start /bin/sh\n" msgstr "n'a pas pu exécuter /bin/sh\n" -#: command.c:3476 +#: command.c:3359 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "n'a pas pu localiser le répertoire temporaire : %s\n" -#: command.c:3503 +#: command.c:3386 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier temporaire « %s » : %s\n" -#: command.c:3777 +#: command.c:3660 #, c-format msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" msgstr "" "\\pset : les formats autorisés sont unaligned, aligned, wrapped, html, asciidoc, latex,\n" "latex-longtable, troff-ms\n" -#: command.c:3795 +#: command.c:3678 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "\\pset: les styles de lignes autorisés sont ascii, old-ascii, unicode\n" -#: command.c:3810 +#: command.c:3693 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double\n" msgstr "\\pset : les styles autorisés de ligne de bordure Unicode sont single, double\n" -#: command.c:3825 +#: command.c:3708 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double\n" msgstr "\\pset : les styles autorisés pour la ligne de colonne Unicode sont single, double\n" -#: command.c:3840 +#: command.c:3723 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double\n" msgstr "\\pset : les styles autorisés pour la ligne d'en-tête Unicode sont single, double\n" -#: command.c:4005 command.c:4184 +#: command.c:3888 command.c:4067 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "\\pset : option inconnue : %s\n" -#: command.c:4023 +#: command.c:3906 #, c-format msgid "Border style is %d.\n" msgstr "Le style de bordure est %d.\n" -#: command.c:4029 +#: command.c:3912 #, c-format msgid "Target width is unset.\n" msgstr "La largeur cible n'est pas configuré.\n" -#: command.c:4031 +#: command.c:3914 #, c-format msgid "Target width is %d.\n" msgstr "La largeur cible est %d.\n" -#: command.c:4038 +#: command.c:3921 #, c-format msgid "Expanded display is on.\n" msgstr "Affichage étendu activé.\n" -#: command.c:4040 +#: command.c:3923 #, c-format msgid "Expanded display is used automatically.\n" msgstr "L'affichage étendu est utilisé automatiquement.\n" -#: command.c:4042 +#: command.c:3925 #, c-format msgid "Expanded display is off.\n" msgstr "Affichage étendu désactivé.\n" -#: command.c:4049 command.c:4057 +#: command.c:3932 command.c:3940 #, c-format msgid "Field separator is zero byte.\n" msgstr "Le séparateur de champs est l'octet zéro.\n" -#: command.c:4051 +#: command.c:3934 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Le séparateur de champs est « %s ».\n" -#: command.c:4064 +#: command.c:3947 #, c-format msgid "Default footer is on.\n" msgstr "Le bas de page pas défaut est activé.\n" -#: command.c:4066 +#: command.c:3949 #, c-format msgid "Default footer is off.\n" msgstr "Le bas de page par défaut est désactivé.\n" -#: command.c:4072 +#: command.c:3955 #, c-format msgid "Output format is %s.\n" msgstr "Le format de sortie est %s.\n" -#: command.c:4078 +#: command.c:3961 #, c-format msgid "Line style is %s.\n" msgstr "Le style de ligne est %s.\n" -#: command.c:4085 +#: command.c:3968 #, c-format msgid "Null display is \"%s\".\n" msgstr "L'affichage de null est « %s ».\n" -#: command.c:4093 +#: command.c:3976 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "L'affichage de la sortie numérique adaptée à la locale est activé.\n" -#: command.c:4095 +#: command.c:3978 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "L'affichage de la sortie numérique adaptée à la locale est désactivé.\n" -#: command.c:4102 +#: command.c:3985 #, c-format msgid "Pager is used for long output.\n" msgstr "Le paginateur est utilisé pour les affichages longs.\n" -#: command.c:4104 +#: command.c:3987 #, c-format msgid "Pager is always used.\n" msgstr "Le paginateur est toujours utilisé.\n" -#: command.c:4106 +#: command.c:3989 #, c-format msgid "Pager usage is off.\n" msgstr "L'utilisation du paginateur est désactivé.\n" -#: command.c:4112 +#: command.c:3995 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "Le paginateur ne sera pas utilisé pour moins que %d ligne.\n" msgstr[1] "Le paginateur ne sera pas utilisé pour moins que %d lignes.\n" -#: command.c:4122 command.c:4132 +#: command.c:4005 command.c:4015 #, c-format msgid "Record separator is zero byte.\n" msgstr "Le séparateur d'enregistrements est l'octet zéro.\n" -#: command.c:4124 +#: command.c:4007 #, c-format msgid "Record separator is .\n" msgstr "Le séparateur d'enregistrement est .\n" -#: command.c:4126 +#: command.c:4009 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Le séparateur d'enregistrements est « %s ».\n" -#: command.c:4139 +#: command.c:4022 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Les attributs de la table sont « %s ».\n" -#: command.c:4142 +#: command.c:4025 #, c-format msgid "Table attributes unset.\n" msgstr "Les attributs de la table ne sont pas définis.\n" -#: command.c:4149 +#: command.c:4032 #, c-format msgid "Title is \"%s\".\n" msgstr "Le titre est « %s ».\n" -#: command.c:4151 +#: command.c:4034 #, c-format msgid "Title is unset.\n" msgstr "Le titre n'est pas défini.\n" -#: command.c:4158 +#: command.c:4041 #, c-format msgid "Tuples only is on.\n" msgstr "L'affichage des tuples seuls est activé.\n" -#: command.c:4160 +#: command.c:4043 #, c-format msgid "Tuples only is off.\n" msgstr "L'affichage des tuples seuls est désactivé.\n" -#: command.c:4166 +#: command.c:4049 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Le style de bordure Unicode est « %s ».\n" -#: command.c:4172 +#: command.c:4055 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Le style de ligne Unicode est « %s ».\n" -#: command.c:4178 +#: command.c:4061 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Le style d'en-tête Unicode est « %s ».\n" -#: command.c:4338 +#: command.c:4221 #, c-format msgid "\\!: failed\n" msgstr "\\! : échec\n" -#: command.c:4363 common.c:754 +#: command.c:4246 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch ne peut pas être utilisé avec une requête vide\n" -#: command.c:4404 +#: command.c:4287 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (chaque %gs)\n" -#: command.c:4407 +#: command.c:4290 #, c-format msgid "%s (every %gs)\n" msgstr "%s (chaque %gs)\n" -#: command.c:4461 command.c:4468 common.c:654 common.c:661 common.c:1271 +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1321 #, c-format msgid "" "********* QUERY **********\n" @@ -678,106 +678,106 @@ msgstr "" "**************************\n" "\n" -#: command.c:4660 +#: command.c:4543 #, c-format msgid "\"%s.%s\" is not a view\n" msgstr "« %s.%s » n'est pas une vue\n" -#: command.c:4676 +#: command.c:4559 #, c-format msgid "could not parse reloptions array\n" msgstr "n'a pas pu analyser le tableau reloptions\n" -#: common.c:158 +#: common.c:159 #, c-format msgid "cannot escape without active connection\n" msgstr "ne peut mettre entre guillemets sans connexion active\n" -#: common.c:199 +#: common.c:200 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "l'argument de la commande shell contient un retour à la ligne ou un retour chariot : « %s »\n" -#: common.c:415 +#: common.c:416 #, c-format msgid "connection to server was lost\n" msgstr "la connexion au serveur a été perdue\n" -#: common.c:419 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "La connexion au serveur a été perdue. Tentative de réinitialisation : " -#: common.c:424 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "Échec.\n" -#: common.c:431 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "Succès.\n" -#: common.c:531 common.c:1034 common.c:1206 +#: common.c:532 common.c:1082 common.c:1256 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "PQresultStatus inattendu : %d\n" -#: common.c:593 +#: common.c:641 #, c-format msgid "Time: %.3f ms\n" msgstr "Temps : %.3f ms\n" -#: common.c:608 +#: common.c:656 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Durée : %.3f ms (%02d:%06.3f)\n" -#: common.c:617 +#: common.c:665 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Durée : %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:624 +#: common.c:672 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Durée : %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:761 +#: common.c:809 #, c-format msgid "\\watch cannot be used with COPY\n" msgstr "\\watch ne peut pas être utilisé avec COPY\n" -#: common.c:766 +#: common.c:814 #, c-format msgid "unexpected result status for \\watch\n" msgstr "statut résultat inattendu pour \\watch\n" -#: common.c:795 +#: common.c:843 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "" "Notification asynchrone « %s » reçue avec le contenu « %s » en provenance du\n" "processus serveur de PID %d.\n" -#: common.c:798 +#: common.c:846 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "" "Notification asynchrone « %s » reçue en provenance du processus serveur de\n" "PID %d.\n" -#: common.c:860 +#: common.c:908 #, c-format msgid "no rows returned for \\gset\n" msgstr "aucune ligne retournée pour \\gset\n" -#: common.c:865 +#: common.c:913 #, c-format msgid "more than one row returned for \\gset\n" msgstr "plus d'une ligne retournée pour \\gset\n" -#: common.c:1251 +#: common.c:1301 #, c-format msgid "" "***(Single step mode: verify command)*******************************************\n" @@ -788,23 +788,39 @@ msgstr "" "%s\n" "***(appuyez sur entrée pour l'exécuter ou tapez x puis entrée pour annuler)***\n" -#: common.c:1306 +#: common.c:1356 #, c-format msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" msgstr "" "Le serveur (version %s) ne supporte pas les points de sauvegarde pour\n" "ON_ERROR_ROLLBACK.\n" -#: common.c:1362 +#: common.c:1419 #, c-format msgid "STATEMENT: %s\n" msgstr "INSTRUCTION : %s\n" -#: common.c:1405 +#: common.c:1462 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "état de la transaction inattendu (%d)\n" +#: common.c:1599 describe.c:1941 +msgid "Column" +msgstr "Colonne" + +#: common.c:1600 describe.c:175 describe.c:390 describe.c:408 describe.c:453 +#: describe.c:470 describe.c:959 describe.c:1123 describe.c:1664 +#: describe.c:1688 describe.c:1942 describe.c:3529 describe.c:3734 +#: describe.c:4925 +msgid "Type" +msgstr "Type" + +#: common.c:1649 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "La commande n'a pas de résultats ou le résultat n'a pas de colonnes.\n" + #: copy.c:99 #, c-format msgid "\\copy: arguments required\n" @@ -883,7 +899,7 @@ msgstr "\\crosstabview : la requête doit renvoyer au moins trois colonnes\n" #: crosstabview.c:156 #, c-format msgid "\\crosstabview: vertical and horizontal headers must be different columns\n" -msgstr "\\crosstabview : les entêtes horizontales et vertivales doivent être des colonnes dofférentes\n" +msgstr "\\crosstabview : les entêtes horizontales et verticales doivent être des colonnes différentes\n" #: crosstabview.c:172 #, c-format @@ -917,1000 +933,1026 @@ msgstr "" msgid "\\crosstabview: column name not found: \"%s\"\n" msgstr "\\crosstabview : nom de colonne non trouvé : « %s »\n" -#: describe.c:74 describe.c:346 describe.c:603 describe.c:735 describe.c:879 -#: describe.c:1040 describe.c:1112 describe.c:3342 describe.c:3554 -#: describe.c:3645 describe.c:3893 describe.c:4038 describe.c:4279 -#: describe.c:4354 describe.c:4365 describe.c:4427 describe.c:4852 -#: describe.c:4935 +#: describe.c:75 describe.c:370 describe.c:675 describe.c:807 describe.c:951 +#: describe.c:1112 describe.c:1184 describe.c:3518 describe.c:3732 +#: describe.c:3823 describe.c:4090 describe.c:4235 describe.c:4476 +#: describe.c:4551 describe.c:4562 describe.c:4624 describe.c:5049 +#: describe.c:5132 msgid "Schema" msgstr "Schéma" -#: describe.c:75 describe.c:164 describe.c:231 describe.c:239 describe.c:347 -#: describe.c:604 describe.c:736 describe.c:797 describe.c:880 describe.c:1113 -#: describe.c:3343 describe.c:3477 describe.c:3555 describe.c:3646 -#: describe.c:3725 describe.c:3894 describe.c:3963 describe.c:4039 -#: describe.c:4280 describe.c:4355 describe.c:4366 describe.c:4428 -#: describe.c:4625 describe.c:4709 describe.c:4933 describe.c:5105 -#: describe.c:5309 +#: describe.c:76 describe.c:173 describe.c:240 describe.c:248 describe.c:371 +#: describe.c:676 describe.c:808 describe.c:869 describe.c:952 describe.c:1185 +#: describe.c:3519 describe.c:3655 describe.c:3733 describe.c:3824 +#: describe.c:3903 describe.c:4091 describe.c:4160 describe.c:4236 +#: describe.c:4477 describe.c:4552 describe.c:4563 describe.c:4625 +#: describe.c:4822 describe.c:4906 describe.c:5130 describe.c:5302 +#: describe.c:5527 msgid "Name" msgstr "Nom" -#: describe.c:76 describe.c:359 describe.c:405 describe.c:422 +#: describe.c:77 describe.c:383 describe.c:401 describe.c:447 describe.c:464 msgid "Result data type" msgstr "Type de données du résultat" -#: describe.c:84 describe.c:97 describe.c:101 describe.c:360 describe.c:406 -#: describe.c:423 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:384 describe.c:402 +#: describe.c:448 describe.c:465 msgid "Argument data types" msgstr "Type de données des paramètres" -#: describe.c:108 describe.c:174 describe.c:262 describe.c:468 describe.c:652 -#: describe.c:751 describe.c:822 describe.c:1115 describe.c:1756 -#: describe.c:3132 describe.c:3377 describe.c:3508 describe.c:3582 -#: describe.c:3655 describe.c:3738 describe.c:3806 describe.c:3906 -#: describe.c:3972 describe.c:4040 describe.c:4181 describe.c:4223 -#: describe.c:4296 describe.c:4358 describe.c:4367 describe.c:4429 -#: describe.c:4651 describe.c:4731 describe.c:4866 describe.c:4936 +#: describe.c:110 describe.c:117 describe.c:183 describe.c:271 describe.c:510 +#: describe.c:724 describe.c:823 describe.c:894 describe.c:1187 describe.c:1960 +#: describe.c:3307 describe.c:3554 describe.c:3686 describe.c:3760 +#: describe.c:3833 describe.c:3916 describe.c:3999 describe.c:4103 +#: describe.c:4169 describe.c:4237 describe.c:4378 describe.c:4420 +#: describe.c:4493 describe.c:4555 describe.c:4564 describe.c:4626 +#: describe.c:4848 describe.c:4928 describe.c:5063 describe.c:5133 #: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "Description" -#: describe.c:126 +#: describe.c:135 msgid "List of aggregate functions" msgstr "Liste des fonctions d'agrégation" -#: describe.c:151 +#: describe.c:160 #, c-format msgid "The server (version %s) does not support access methods.\n" msgstr "Le serveur (version %s) ne supporte pas les méthodes d'accès.\n" -#: describe.c:165 +#: describe.c:174 msgid "Index" msgstr "Index" -#: describe.c:166 describe.c:366 describe.c:411 describe.c:428 describe.c:887 -#: describe.c:1051 describe.c:1716 describe.c:3352 describe.c:3556 -#: describe.c:4728 -msgid "Type" -msgstr "Type" - -#: describe.c:173 describe.c:4630 +#: describe.c:182 describe.c:4827 msgid "Handler" msgstr "Gestionnaire" -#: describe.c:192 +#: describe.c:201 msgid "List of access methods" msgstr "Liste des méthodes d'accès" -#: describe.c:218 +#: describe.c:227 #, c-format msgid "The server (version %s) does not support tablespaces.\n" msgstr "Le serveur (version %s) ne supporte pas les tablespaces.\n" -#: describe.c:232 describe.c:240 describe.c:456 describe.c:642 describe.c:798 -#: describe.c:1039 describe.c:3353 describe.c:3481 describe.c:3727 -#: describe.c:3964 describe.c:4626 describe.c:4710 describe.c:5106 -#: describe.c:5310 large_obj.c:288 +#: describe.c:241 describe.c:249 describe.c:498 describe.c:714 describe.c:870 +#: describe.c:1111 describe.c:3530 describe.c:3659 describe.c:3905 +#: describe.c:4161 describe.c:4823 describe.c:4907 describe.c:5303 +#: describe.c:5429 describe.c:5528 large_obj.c:288 msgid "Owner" msgstr "Propriétaire" -#: describe.c:233 describe.c:241 +#: describe.c:242 describe.c:250 msgid "Location" msgstr "Emplacement" -#: describe.c:252 describe.c:2944 +#: describe.c:261 describe.c:3126 msgid "Options" msgstr "Options" -#: describe.c:257 describe.c:615 describe.c:814 describe.c:3369 describe.c:3373 +#: describe.c:266 describe.c:687 describe.c:886 describe.c:3546 describe.c:3550 msgid "Size" msgstr "Taille" -#: describe.c:279 +#: describe.c:288 msgid "List of tablespaces" msgstr "Liste des tablespaces" -#: describe.c:320 +#: describe.c:330 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df prends seulement [antwS+] comme options\n" +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df prends seulement [anptwS+] comme options\n" -#: describe.c:328 +#: describe.c:338 describe.c:349 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df ne prend pas l'option « w » pour un serveur en version %s.\n" +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "\\df ne prend pas une option « %c » pour un serveur en version %s\n" #. translator: "agg" is short for "aggregate" -#: describe.c:362 describe.c:408 describe.c:425 +#: describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "agg" msgstr "agg" -#: describe.c:363 +#: describe.c:387 describe.c:405 msgid "window" msgstr "window" -#: describe.c:364 describe.c:409 describe.c:426 describe.c:1249 +#: describe.c:388 +msgid "proc" +msgstr "proc" + +#: describe.c:389 describe.c:407 describe.c:452 describe.c:469 +msgid "func" +msgstr "func" + +#: describe.c:406 describe.c:451 describe.c:468 describe.c:1321 msgid "trigger" msgstr "trigger" -#: describe.c:365 describe.c:410 describe.c:427 -msgid "normal" -msgstr "normal" - -#: describe.c:438 +#: describe.c:480 msgid "immutable" msgstr "immutable" -#: describe.c:439 +#: describe.c:481 msgid "stable" msgstr "stable" -#: describe.c:440 +#: describe.c:482 msgid "volatile" msgstr "volatile" -#: describe.c:441 +#: describe.c:483 msgid "Volatility" msgstr "Volatibilité" -#: describe.c:449 +#: describe.c:491 msgid "restricted" msgstr "restricted" -#: describe.c:450 +#: describe.c:492 msgid "safe" msgstr "safe" -#: describe.c:451 +#: describe.c:493 msgid "unsafe" msgstr "unsafe" -#: describe.c:452 +#: describe.c:494 msgid "Parallel" msgstr "Parallèle" -#: describe.c:457 +#: describe.c:499 msgid "definer" msgstr "definer" -#: describe.c:458 +#: describe.c:500 msgid "invoker" msgstr "invoker" -#: describe.c:459 +#: describe.c:501 msgid "Security" msgstr "Sécurité" -#: describe.c:466 +#: describe.c:508 msgid "Language" msgstr "Langage" -#: describe.c:467 +#: describe.c:509 msgid "Source code" msgstr "Code source" -#: describe.c:566 +#: describe.c:638 msgid "List of functions" msgstr "Liste des fonctions" -#: describe.c:614 +#: describe.c:686 msgid "Internal name" msgstr "Nom interne" -#: describe.c:636 +#: describe.c:708 msgid "Elements" msgstr "Éléments" -#: describe.c:693 +#: describe.c:765 msgid "List of data types" msgstr "Liste des types de données" -#: describe.c:737 +#: describe.c:809 msgid "Left arg type" msgstr "Type de l'arg. gauche" -#: describe.c:738 +#: describe.c:810 msgid "Right arg type" msgstr "Type de l'arg. droit" -#: describe.c:739 +#: describe.c:811 msgid "Result type" msgstr "Type du résultat" -#: describe.c:744 describe.c:3797 describe.c:4180 +#: describe.c:816 describe.c:3911 describe.c:3976 describe.c:3982 +#: describe.c:4377 msgid "Function" msgstr "Fonction" -#: describe.c:769 +#: describe.c:841 msgid "List of operators" msgstr "Liste des opérateurs" -#: describe.c:799 +#: describe.c:871 msgid "Encoding" msgstr "Encodage" -#: describe.c:804 describe.c:3895 +#: describe.c:876 describe.c:4092 msgid "Collate" msgstr "Collationnement" -#: describe.c:805 describe.c:3896 +#: describe.c:877 describe.c:4093 msgid "Ctype" msgstr "Type caract." -#: describe.c:818 +#: describe.c:890 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:840 +#: describe.c:912 msgid "List of databases" msgstr "Liste des bases de données" -#: describe.c:881 describe.c:886 describe.c:1042 describe.c:3344 -#: describe.c:3351 +#: describe.c:953 describe.c:958 describe.c:1114 describe.c:3520 +#: describe.c:3527 msgid "table" msgstr "table" -#: describe.c:882 describe.c:3345 +#: describe.c:954 describe.c:3521 msgid "view" msgstr "vue" -#: describe.c:883 describe.c:3346 +#: describe.c:955 describe.c:3522 msgid "materialized view" msgstr "vue matérialisée" -#: describe.c:884 describe.c:1044 describe.c:3348 +#: describe.c:956 describe.c:1116 describe.c:3524 msgid "sequence" msgstr "séquence" -#: describe.c:885 describe.c:3350 +#: describe.c:957 describe.c:3526 msgid "foreign table" msgstr "table distante" -#: describe.c:898 +#: describe.c:970 msgid "Column privileges" msgstr "Droits d'accès à la colonne" -#: describe.c:929 describe.c:963 +#: describe.c:1001 describe.c:1035 msgid "Policies" msgstr "Politiques" -#: describe.c:995 describe.c:5366 describe.c:5370 +#: describe.c:1067 describe.c:5584 describe.c:5588 msgid "Access privileges" msgstr "Droits d'accès" -#: describe.c:1026 +#: describe.c:1098 #, c-format msgid "The server (version %s) does not support altering default privileges.\n" msgstr "Le serveur (version %s) ne supporte pas la modification des droits par défaut.\n" -#: describe.c:1046 +#: describe.c:1118 msgid "function" msgstr "fonction" -#: describe.c:1048 +#: describe.c:1120 msgid "type" msgstr "type" -#: describe.c:1050 +#: describe.c:1122 msgid "schema" msgstr "schéma" -#: describe.c:1074 +#: describe.c:1146 msgid "Default access privileges" msgstr "Droits d'accès par défaut" -#: describe.c:1114 +#: describe.c:1186 msgid "Object" msgstr "Objet" -#: describe.c:1128 +#: describe.c:1200 msgid "table constraint" msgstr "contrainte de table" -#: describe.c:1150 +#: describe.c:1222 msgid "domain constraint" msgstr "contrainte de domaine" -#: describe.c:1178 +#: describe.c:1250 msgid "operator class" msgstr "classe d'opérateur" -#: describe.c:1207 +#: describe.c:1279 msgid "operator family" msgstr "famille d'opérateur" -#: describe.c:1229 +#: describe.c:1301 msgid "rule" msgstr "règle" -#: describe.c:1271 +#: describe.c:1343 msgid "Object descriptions" msgstr "Descriptions des objets" -#: describe.c:1327 describe.c:3440 +#: describe.c:1399 describe.c:3618 #, c-format msgid "Did not find any relation named \"%s\".\n" msgstr "Aucune relation nommée « %s » n'a été trouvée.\n" -#: describe.c:1330 describe.c:3443 +#: describe.c:1402 describe.c:3621 #, c-format msgid "Did not find any relations.\n" msgstr "N'a trouvé aucune relation.\n" -#: describe.c:1539 +#: describe.c:1619 #, c-format msgid "Did not find any relation with OID %s.\n" msgstr "Aucune relation avec l'OID « %s » n'a été trouvée.\n" -#: describe.c:1652 describe.c:1701 +#: describe.c:1665 describe.c:1689 +msgid "Start" +msgstr "Début" + +#: describe.c:1666 describe.c:1690 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1667 describe.c:1691 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1668 describe.c:1692 +msgid "Increment" +msgstr "Incrément" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3827 +#: describe.c:3993 +msgid "yes" +msgstr "oui" + +#: describe.c:1670 describe.c:1694 describe.c:1819 describe.c:3827 +#: describe.c:3990 +msgid "no" +msgstr "non" + +#: describe.c:1671 describe.c:1695 +msgid "Cycles?" +msgstr "Cycles ?" + +#: describe.c:1672 describe.c:1696 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1739 +#, c-format +msgid "Owned by: %s" +msgstr "Propriétaire : %s" + +#: describe.c:1743 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Séquence pour la colonne d'identité : %s" + +#: describe.c:1750 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Séquence « %s.%s »" + +#: describe.c:1880 describe.c:1926 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Table non tracée « %s.%s »" -#: describe.c:1655 describe.c:1704 +#: describe.c:1883 describe.c:1929 #, c-format msgid "Table \"%s.%s\"" msgstr "Table « %s.%s »" -#: describe.c:1659 +#: describe.c:1887 #, c-format msgid "View \"%s.%s\"" msgstr "Vue « %s.%s »" -#: describe.c:1664 +#: describe.c:1892 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Vue matérialisée non journalisée « %s.%s »" -#: describe.c:1667 +#: describe.c:1895 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Vue matérialisée « %s.%s »" -#: describe.c:1671 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Séquence « %s.%s »" - -#: describe.c:1676 +#: describe.c:1901 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Index non tracé « %s.%s »" -#: describe.c:1679 +#: describe.c:1904 #, c-format msgid "Index \"%s.%s\"" msgstr "Index « %s.%s »" -#: describe.c:1684 +#: describe.c:1909 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Relation spéciale « %s.%s »" -#: describe.c:1688 +#: describe.c:1913 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "Table TOAST « %s.%s »" -#: describe.c:1692 +#: describe.c:1917 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Type composé « %s.%s »" -#: describe.c:1696 +#: describe.c:1921 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Table distante « %s.%s »" -#: describe.c:1715 -msgid "Column" -msgstr "Colonne" - -#: describe.c:1726 describe.c:3562 +#: describe.c:1945 describe.c:3740 msgid "Collation" msgstr "Collationnement" -#: describe.c:1727 describe.c:3569 +#: describe.c:1946 describe.c:3747 msgid "Nullable" msgstr "NULL-able" -#: describe.c:1728 describe.c:3570 +#: describe.c:1947 describe.c:3748 msgid "Default" msgstr "Par défaut" -#: describe.c:1733 -msgid "Value" -msgstr "Valeur" +#: describe.c:1950 +msgid "Key?" +msgstr "Clé ?" -#: describe.c:1736 +#: describe.c:1952 msgid "Definition" msgstr "Définition" -#: describe.c:1739 describe.c:4646 describe.c:4730 describe.c:4801 -#: describe.c:4865 +#: describe.c:1954 describe.c:4843 describe.c:4927 describe.c:4998 +#: describe.c:5062 msgid "FDW options" msgstr "Options FDW" -#: describe.c:1743 +#: describe.c:1956 msgid "Storage" msgstr "Stockage" -#: describe.c:1748 +#: describe.c:1958 msgid "Stats target" msgstr "Cible de statistiques" -#: describe.c:1897 +#: describe.c:2072 #, c-format msgid "Partition of: %s %s" msgstr "Partition de : %s %s" -#: describe.c:1903 +#: describe.c:2080 +msgid "No partition constraint" +msgstr "Aucune contrainte de partition" + +#: describe.c:2082 #, c-format msgid "Partition constraint: %s" msgstr "Contrainte de partition : %s" -#: describe.c:1926 +#: describe.c:2105 #, c-format msgid "Partition key: %s" msgstr "Clé de partition : %s" -#: describe.c:1994 +#: describe.c:2174 msgid "primary key, " msgstr "clé primaire, " -#: describe.c:1996 +#: describe.c:2176 msgid "unique, " msgstr "unique, " -#: describe.c:2002 +#: describe.c:2182 #, c-format msgid "for table \"%s.%s\"" msgstr "pour la table « %s.%s »" -#: describe.c:2006 +#: describe.c:2186 #, c-format msgid ", predicate (%s)" msgstr ", prédicat (%s)" -#: describe.c:2009 +#: describe.c:2189 msgid ", clustered" msgstr ", en cluster" -#: describe.c:2012 +#: describe.c:2192 msgid ", invalid" msgstr ", invalide" -#: describe.c:2015 +#: describe.c:2195 msgid ", deferrable" msgstr ", déferrable" -#: describe.c:2018 +#: describe.c:2198 msgid ", initially deferred" msgstr ", initialement déferré" -#: describe.c:2021 +#: describe.c:2201 msgid ", replica identity" msgstr ", identité réplica" -#: describe.c:2060 -#, c-format -msgid "Owned by: %s" -msgstr "Propriétaire : %s" - -#: describe.c:2065 -#, c-format -msgid "Sequence for identity column: %s" -msgstr "Séquence pour la colonne d'identité : %s" - -#: describe.c:2129 +#: describe.c:2260 msgid "Indexes:" msgstr "Index :" -#: describe.c:2213 +#: describe.c:2344 msgid "Check constraints:" msgstr "Contraintes de vérification :" -#: describe.c:2244 +#: describe.c:2380 msgid "Foreign-key constraints:" msgstr "Contraintes de clés étrangères :" -#: describe.c:2275 +#: describe.c:2411 msgid "Referenced by:" msgstr "Référencé par :" -#: describe.c:2325 +#: describe.c:2461 msgid "Policies:" msgstr "Politiques :" -#: describe.c:2328 +#: describe.c:2464 msgid "Policies (forced row security enabled):" msgstr "Politiques (mode sécurité de ligne activé en forcé) :" -#: describe.c:2331 +#: describe.c:2467 msgid "Policies (row security enabled): (none)" msgstr "Politiques (mode sécurité de ligne activé) : (aucune)" -#: describe.c:2334 +#: describe.c:2470 msgid "Policies (forced row security enabled): (none)" msgstr "Politiques (mode sécurité de ligne activé en forcé) : (aucune)" -#: describe.c:2337 +#: describe.c:2473 msgid "Policies (row security disabled):" msgstr "Politiques (mode sécurité de ligne désactivé) :" -#: describe.c:2399 +#: describe.c:2535 msgid "Statistics objects:" msgstr "Objets statistiques :" -#: describe.c:2502 describe.c:2587 +#: describe.c:2638 describe.c:2742 msgid "Rules:" msgstr "Règles :" -#: describe.c:2505 +#: describe.c:2641 msgid "Disabled rules:" msgstr "Règles désactivées :" -#: describe.c:2508 +#: describe.c:2644 msgid "Rules firing always:" msgstr "Règles toujous activées :" -#: describe.c:2511 +#: describe.c:2647 msgid "Rules firing on replica only:" msgstr "Règles activées uniquement sur le réplica :" -#: describe.c:2551 +#: describe.c:2687 msgid "Publications:" msgstr "Publications :" -#: describe.c:2570 +#: describe.c:2725 msgid "View definition:" msgstr "Définition de la vue :" -#: describe.c:2705 +#: describe.c:2864 msgid "Triggers:" msgstr "Triggers :" -#: describe.c:2709 +#: describe.c:2868 msgid "Disabled user triggers:" msgstr "Triggers utilisateurs désactivés :" -#: describe.c:2711 +#: describe.c:2870 msgid "Disabled triggers:" msgstr "Triggers désactivés :" -#: describe.c:2714 +#: describe.c:2873 msgid "Disabled internal triggers:" msgstr "Triggers internes désactivés :" -#: describe.c:2717 +#: describe.c:2876 msgid "Triggers firing always:" msgstr "Triggers toujours activés :" -#: describe.c:2720 +#: describe.c:2879 msgid "Triggers firing on replica only:" msgstr "Triggers activés uniquement sur le réplica :" -#: describe.c:2779 +#: describe.c:2938 #, c-format msgid "Server: %s" msgstr "Serveur : %s" -#: describe.c:2787 +#: describe.c:2946 #, c-format msgid "FDW options: (%s)" msgstr "Options FDW : (%s)" -#: describe.c:2806 +#: describe.c:2965 msgid "Inherits" msgstr "Hérite de" -#: describe.c:2860 +#: describe.c:3024 +#, c-format +msgid "Number of partitions: %d" +msgstr "Nombre de partitions : %d" + +#: describe.c:3033 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Nombre de tables enfants : %d (utilisez \\d+ pour les lister)" -#: describe.c:2862 +#: describe.c:3035 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Nombre de partitions : %d (utilisez \\d+ pour les lister)" -#: describe.c:2870 +#: describe.c:3043 msgid "Child tables" msgstr "Tables enfant :" -#: describe.c:2870 +#: describe.c:3043 msgid "Partitions" msgstr "Partitions" -#: describe.c:2904 +#: describe.c:3086 #, c-format msgid "Typed table of type: %s" msgstr "Table de type : %s" -#: describe.c:2920 +#: describe.c:3102 msgid "Replica Identity" msgstr "Identité de réplicat" -#: describe.c:2933 +#: describe.c:3115 msgid "Has OIDs: yes" msgstr "Contient des OID : oui" -#: describe.c:3020 +#: describe.c:3195 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace : « %s »" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3032 +#: describe.c:3207 #, c-format msgid ", tablespace \"%s\"" msgstr ", tablespace « %s »" -#: describe.c:3125 +#: describe.c:3300 msgid "List of roles" msgstr "Liste des rôles" -#: describe.c:3127 +#: describe.c:3302 msgid "Role name" msgstr "Nom du rôle" -#: describe.c:3128 +#: describe.c:3303 msgid "Attributes" msgstr "Attributs" -#: describe.c:3129 +#: describe.c:3304 msgid "Member of" msgstr "Membre de" -#: describe.c:3140 +#: describe.c:3315 msgid "Superuser" msgstr "Superutilisateur" -#: describe.c:3143 +#: describe.c:3318 msgid "No inheritance" msgstr "Pas d'héritage" -#: describe.c:3146 +#: describe.c:3321 msgid "Create role" msgstr "Créer un rôle" -#: describe.c:3149 +#: describe.c:3324 msgid "Create DB" msgstr "Créer une base" -#: describe.c:3152 +#: describe.c:3327 msgid "Cannot login" msgstr "Ne peut pas se connecter" -#: describe.c:3156 +#: describe.c:3331 msgid "Replication" msgstr "Réplication" -#: describe.c:3160 +#: describe.c:3335 msgid "Bypass RLS" msgstr "Contournement RLS" -#: describe.c:3169 +#: describe.c:3344 msgid "No connections" msgstr "Sans connexions" -#: describe.c:3171 +#: describe.c:3346 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d connexion" msgstr[1] "%d connexions" -#: describe.c:3181 +#: describe.c:3356 msgid "Password valid until " msgstr "Mot de passe valide jusqu'à " -#: describe.c:3231 +#: describe.c:3406 #, c-format msgid "The server (version %s) does not support per-database role settings.\n" msgstr "Le serveur (version %s) ne supporte pas les paramètres de rôles par bases de données.\n" -#: describe.c:3244 +#: describe.c:3419 msgid "Role" msgstr "Rôle" -#: describe.c:3245 +#: describe.c:3420 msgid "Database" msgstr "Base de données" -#: describe.c:3246 +#: describe.c:3421 msgid "Settings" msgstr "Réglages" -#: describe.c:3267 +#: describe.c:3442 #, c-format msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" msgstr "N'a trouvé aucune configuration pour le rôle « %s » et la base de données « %s ».\n" -#: describe.c:3270 +#: describe.c:3445 #, c-format msgid "Did not find any settings for role \"%s\".\n" msgstr "N'a trouvé aucune configuration pour le rôle « %s ».\n" -#: describe.c:3273 +#: describe.c:3448 #, c-format msgid "Did not find any settings.\n" msgstr "N'a trouvé aucune configuration.\n" -#: describe.c:3278 +#: describe.c:3453 msgid "List of settings" msgstr "Liste des paramètres" -#: describe.c:3347 +#: describe.c:3523 describe.c:3528 msgid "index" msgstr "index" -#: describe.c:3349 +#: describe.c:3525 msgid "special" msgstr "spécial" -#: describe.c:3358 describe.c:4853 +#: describe.c:3535 describe.c:5050 msgid "Table" msgstr "Table" -#: describe.c:3448 +#: describe.c:3626 msgid "List of relations" msgstr "Liste des relations" -#: describe.c:3485 +#: describe.c:3663 msgid "Trusted" msgstr "De confiance" -#: describe.c:3493 +#: describe.c:3671 msgid "Internal language" msgstr "Langage interne" -#: describe.c:3494 +#: describe.c:3672 msgid "Call handler" msgstr "Gestionnaire d'appel" -#: describe.c:3495 describe.c:4633 +#: describe.c:3673 describe.c:4830 msgid "Validator" msgstr "Validateur" -#: describe.c:3498 +#: describe.c:3676 msgid "Inline handler" msgstr "Gestionnaire en ligne" -#: describe.c:3526 +#: describe.c:3704 msgid "List of languages" msgstr "Liste des langages" -#: describe.c:3571 +#: describe.c:3749 msgid "Check" msgstr "Vérification" -#: describe.c:3613 +#: describe.c:3791 msgid "List of domains" msgstr "Liste des domaines" -#: describe.c:3647 +#: describe.c:3825 msgid "Source" msgstr "Source" -#: describe.c:3648 +#: describe.c:3826 msgid "Destination" msgstr "Destination" -#: describe.c:3649 describe.c:3798 -msgid "no" -msgstr "non" - -#: describe.c:3649 describe.c:3800 -msgid "yes" -msgstr "oui" - -#: describe.c:3650 +#: describe.c:3828 msgid "Default?" msgstr "Par défaut ?" -#: describe.c:3687 +#: describe.c:3865 msgid "List of conversions" msgstr "Liste des conversions" -#: describe.c:3726 +#: describe.c:3904 msgid "Event" msgstr "Événement" -#: describe.c:3728 +#: describe.c:3906 msgid "enabled" msgstr "activé" -#: describe.c:3729 +#: describe.c:3907 msgid "replica" msgstr "réplicat" -#: describe.c:3730 +#: describe.c:3908 msgid "always" msgstr "toujours" -#: describe.c:3731 +#: describe.c:3909 msgid "disabled" msgstr "désactivé" -#: describe.c:3732 describe.c:5311 +#: describe.c:3910 describe.c:5529 msgid "Enabled" msgstr "Activé" -#: describe.c:3733 -msgid "Procedure" -msgstr "Procédure" - -#: describe.c:3734 +#: describe.c:3912 msgid "Tags" msgstr "Tags" -#: describe.c:3753 +#: describe.c:3931 msgid "List of event triggers" msgstr "Liste des triggers sur évènement" -#: describe.c:3795 +#: describe.c:3960 msgid "Source type" msgstr "Type source" -#: describe.c:3796 +#: describe.c:3961 msgid "Target type" msgstr "Type cible" -#: describe.c:3799 +#: describe.c:3992 msgid "in assignment" msgstr "assigné" -#: describe.c:3801 +#: describe.c:3994 msgid "Implicit?" msgstr "Implicite ?" -#: describe.c:3852 +#: describe.c:4049 msgid "List of casts" msgstr "Liste des conversions explicites" -#: describe.c:3880 +#: describe.c:4077 #, c-format msgid "The server (version %s) does not support collations.\n" msgstr "Le serveur (version %s) ne supporte pas les collationnements.\n" -#: describe.c:3901 +#: describe.c:4098 msgid "Provider" msgstr "Fournisseur" -#: describe.c:3936 +#: describe.c:4133 msgid "List of collations" msgstr "Liste des collationnements" -#: describe.c:3995 +#: describe.c:4192 msgid "List of schemas" msgstr "Liste des schémas" -#: describe.c:4020 describe.c:4267 describe.c:4338 describe.c:4409 +#: describe.c:4217 describe.c:4464 describe.c:4535 describe.c:4606 #, c-format msgid "The server (version %s) does not support full text search.\n" msgstr "Le serveur (version %s) ne supporte pas la recherche plein texte.\n" -#: describe.c:4055 +#: describe.c:4252 msgid "List of text search parsers" msgstr "Liste des analyseurs de la recherche de texte" -#: describe.c:4100 +#: describe.c:4297 #, c-format msgid "Did not find any text search parser named \"%s\".\n" msgstr "Aucun analyseur de la recherche de texte nommé « %s » n'a été trouvé.\n" -#: describe.c:4103 +#: describe.c:4300 #, c-format msgid "Did not find any text search parsers.\n" msgstr "N'a trouvé aucun analyseur de recherche plein texte.\n" -#: describe.c:4178 +#: describe.c:4375 msgid "Start parse" msgstr "Début de l'analyse" -#: describe.c:4179 +#: describe.c:4376 msgid "Method" msgstr "Méthode" -#: describe.c:4183 +#: describe.c:4380 msgid "Get next token" msgstr "Obtenir le prochain jeton" -#: describe.c:4185 +#: describe.c:4382 msgid "End parse" msgstr "Fin de l'analyse" -#: describe.c:4187 +#: describe.c:4384 msgid "Get headline" msgstr "Obtenir l'en-tête" -#: describe.c:4189 +#: describe.c:4386 msgid "Get token types" msgstr "Obtenir les types de jeton" -#: describe.c:4200 +#: describe.c:4397 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Analyseur « %s.%s » de la recherche de texte" -#: describe.c:4203 +#: describe.c:4400 #, c-format msgid "Text search parser \"%s\"" msgstr "Analyseur « %s » de la recherche de texte" -#: describe.c:4222 +#: describe.c:4419 msgid "Token name" msgstr "Nom du jeton" -#: describe.c:4233 +#: describe.c:4430 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Types de jeton pour l'analyseur « %s.%s »" -#: describe.c:4236 +#: describe.c:4433 #, c-format msgid "Token types for parser \"%s\"" msgstr "Types de jeton pour l'analyseur « %s »" -#: describe.c:4290 +#: describe.c:4487 msgid "Template" msgstr "Modèle" -#: describe.c:4291 +#: describe.c:4488 msgid "Init options" msgstr "Options d'initialisation :" -#: describe.c:4313 +#: describe.c:4510 msgid "List of text search dictionaries" msgstr "Liste des dictionnaires de la recherche de texte" -#: describe.c:4356 +#: describe.c:4553 msgid "Init" msgstr "Initialisation" -#: describe.c:4357 +#: describe.c:4554 msgid "Lexize" msgstr "Lexize" -#: describe.c:4384 +#: describe.c:4581 msgid "List of text search templates" msgstr "Liste des modèles de la recherche de texte" -#: describe.c:4444 +#: describe.c:4641 msgid "List of text search configurations" msgstr "Liste des configurations de la recherche de texte" -#: describe.c:4490 +#: describe.c:4687 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" msgstr "Aucune configuration de la recherche de texte nommée « %s » n'a été trouvée.\n" -#: describe.c:4493 +#: describe.c:4690 #, c-format msgid "Did not find any text search configurations.\n" msgstr "N'a trouvé aucune configuration de recherche plein texte.\n" -#: describe.c:4559 +#: describe.c:4756 msgid "Token" msgstr "Jeton" -#: describe.c:4560 +#: describe.c:4757 msgid "Dictionaries" msgstr "Dictionnaires" -#: describe.c:4571 +#: describe.c:4768 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Configuration « %s.%s » de la recherche de texte" -#: describe.c:4574 +#: describe.c:4771 #, c-format msgid "Text search configuration \"%s\"" msgstr "Configuration « %s » de la recherche de texte" -#: describe.c:4578 +#: describe.c:4775 #, c-format msgid "" "\n" @@ -1919,7 +1961,7 @@ msgstr "" "\n" "Analyseur : « %s.%s »" -#: describe.c:4581 +#: describe.c:4778 #, c-format msgid "" "\n" @@ -1928,148 +1970,152 @@ msgstr "" "\n" "Analyseur : « %s »" -#: describe.c:4615 +#: describe.c:4812 #, c-format msgid "The server (version %s) does not support foreign-data wrappers.\n" msgstr "Le serveur (version %s) ne supporte pas les wrappers de données distantes.\n" -#: describe.c:4673 +#: describe.c:4870 msgid "List of foreign-data wrappers" msgstr "Liste des wrappers de données distantes" -#: describe.c:4698 +#: describe.c:4895 #, c-format msgid "The server (version %s) does not support foreign servers.\n" msgstr "Le serveur (version %s) ne supporte pas les serveurs distants.\n" -#: describe.c:4711 +#: describe.c:4908 msgid "Foreign-data wrapper" msgstr "Wrapper des données distantes" -#: describe.c:4729 describe.c:4934 +#: describe.c:4926 describe.c:5131 msgid "Version" msgstr "Version" -#: describe.c:4755 +#: describe.c:4952 msgid "List of foreign servers" msgstr "Liste des serveurs distants" -#: describe.c:4780 +#: describe.c:4977 #, c-format msgid "The server (version %s) does not support user mappings.\n" msgstr "Le serveur (version %s) ne supporte pas les correspondances d'utilisateurs.\n" -#: describe.c:4790 describe.c:4854 +#: describe.c:4987 describe.c:5051 msgid "Server" msgstr "Serveur" -#: describe.c:4791 +#: describe.c:4988 msgid "User name" msgstr "Nom de l'utilisateur" -#: describe.c:4816 +#: describe.c:5013 msgid "List of user mappings" msgstr "Liste des correspondances utilisateurs" -#: describe.c:4841 +#: describe.c:5038 #, c-format msgid "The server (version %s) does not support foreign tables.\n" msgstr "Le serveur (version %s) ne supporte pas les tables distantes.\n" -#: describe.c:4894 +#: describe.c:5091 msgid "List of foreign tables" msgstr "Liste des tables distantes" -#: describe.c:4919 describe.c:4976 +#: describe.c:5116 describe.c:5173 #, c-format msgid "The server (version %s) does not support extensions.\n" msgstr "Le serveur (version %s) ne supporte pas les extensions.\n" -#: describe.c:4951 +#: describe.c:5148 msgid "List of installed extensions" msgstr "Liste des extensions installées" -#: describe.c:5004 +#: describe.c:5201 #, c-format msgid "Did not find any extension named \"%s\".\n" msgstr "N'a trouvé aucune extension nommée « %s ».\n" -#: describe.c:5007 +#: describe.c:5204 #, c-format msgid "Did not find any extensions.\n" msgstr "N'a trouvé aucune extension.\n" -#: describe.c:5051 +#: describe.c:5248 msgid "Object description" msgstr "Description d'objet" -#: describe.c:5061 +#: describe.c:5258 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objets dans l'extension « %s »" -#: describe.c:5090 describe.c:5156 +#: describe.c:5287 describe.c:5358 #, c-format msgid "The server (version %s) does not support publications.\n" msgstr "Le serveur (version %s) ne supporte pas les publications.\n" -#: describe.c:5107 describe.c:5217 +#: describe.c:5304 describe.c:5430 msgid "All tables" msgstr "Toutes les tables" -#: describe.c:5108 describe.c:5218 +#: describe.c:5305 describe.c:5431 msgid "Inserts" msgstr "Insertions" -#: describe.c:5109 describe.c:5219 +#: describe.c:5306 describe.c:5432 msgid "Updates" msgstr "Mises à jour" -#: describe.c:5110 describe.c:5220 +#: describe.c:5307 describe.c:5433 msgid "Deletes" msgstr "Suppressions" -#: describe.c:5127 +#: describe.c:5311 describe.c:5435 +msgid "Truncates" +msgstr "Tronque" + +#: describe.c:5328 msgid "List of publications" msgstr "Liste des publications" -#: describe.c:5187 +#: describe.c:5396 #, c-format msgid "Did not find any publication named \"%s\".\n" msgstr "N'a trouvé aucune publication nommée « %s ».\n" -#: describe.c:5190 +#: describe.c:5399 #, c-format msgid "Did not find any publications.\n" msgstr "N'a trouvé aucune publication.\n" -#: describe.c:5214 +#: describe.c:5426 #, c-format msgid "Publication %s" msgstr "Publication %s" -#: describe.c:5252 +#: describe.c:5470 msgid "Tables:" msgstr "Tables :" -#: describe.c:5296 +#: describe.c:5514 #, c-format msgid "The server (version %s) does not support subscriptions.\n" msgstr "Le serveur (version %s) ne supporte pas les souscriptions.\n" -#: describe.c:5312 +#: describe.c:5530 msgid "Publication" msgstr "Publication" -#: describe.c:5319 +#: describe.c:5537 msgid "Synchronous commit" msgstr "Validation synchrone" -#: describe.c:5320 +#: describe.c:5538 msgid "Conninfo" msgstr "Informations de connexion" -#: describe.c:5342 +#: describe.c:5560 msgid "List of subscriptions" msgstr "Liste des souscriptions" @@ -2087,7 +2133,7 @@ msgstr "" "psql est l'interface interactive de PostgreSQL.\n" "\n" -#: help.c:74 help.c:344 help.c:378 help.c:405 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" msgstr "Usage :\n" @@ -2446,449 +2492,454 @@ msgstr "" #: help.c:177 #, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc décrit le résultat de la requête sans l'exécuter\n" + +#: help.c:178 +#, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr " \\gexec exécute la requête et exécute chaque valeur du résultat\n" -#: help.c:178 +#: help.c:179 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr " \\gset [PRÉFIXE] exécute la requête et stocke les résultats dans des variables psql\n" -#: help.c:179 +#: help.c:180 #, c-format msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" msgstr " \\gx [FICHIER] comme \\g, mais force le mode de sortie étendu\n" -#: help.c:180 +#: help.c:181 #, c-format msgid " \\q quit psql\n" msgstr " \\q quitte psql\n" -#: help.c:181 +#: help.c:182 #, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEC] exécute la requête toutes les SEC secondes\n" -#: help.c:184 +#: help.c:185 #, c-format msgid "Help\n" msgstr "Aide\n" -#: help.c:186 +#: help.c:187 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commandes] affiche l'aide sur les métacommandes\n" -#: help.c:187 +#: help.c:188 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options affiche l'aide sur les options en ligne de commande de psql\n" -#: help.c:188 +#: help.c:189 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables affiche l'aide sur les variables spéciales\n" -#: help.c:189 +#: help.c:190 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr "" " \\h [NOM] aide-mémoire pour les commandes SQL, * pour toutes\n" " les commandes\n" -#: help.c:192 +#: help.c:193 #, c-format msgid "Query Buffer\n" msgstr "Tampon de requête\n" -#: help.c:193 +#: help.c:194 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr "" " \\e [FICHIER] [LIGNE] édite le tampon de requête ou le fichier avec un\n" " éditeur externe\n" -#: help.c:194 +#: help.c:195 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr "" " \\ef [FONCTION [LIGNE]] édite la définition de fonction avec un éditeur\n" " externe\n" -#: help.c:195 +#: help.c:196 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr "" " \\ev [VUE [LIGNE]] édite la définition de vue avec un éditeur\n" " externe\n" -#: help.c:196 +#: help.c:197 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p affiche le contenu du tampon de requête\n" -#: help.c:197 +#: help.c:198 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r efface le tampon de requêtes\n" -#: help.c:199 +#: help.c:200 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr "" " \\s [FICHIER] affiche l'historique ou le sauvegarde dans un\n" " fichier\n" -#: help.c:201 +#: help.c:202 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr "" " \\w [FICHIER] écrit le contenu du tampon de requêtes dans un\n" " fichier\n" -#: help.c:204 +#: help.c:205 #, c-format msgid "Input/Output\n" msgstr "Entrée/Sortie\n" -#: help.c:205 +#: help.c:206 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr "" " \\copy ... exécute SQL COPY avec le flux de données dirigé vers\n" " l'hôte client\n" -#: help.c:206 +#: help.c:207 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [TEXTE] écrit un texte sur la sortie standard\n" -#: help.c:207 +#: help.c:208 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i FICHIER exécute les commandes du fichier\n" -#: help.c:208 +#: help.c:209 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr "" " \\ir FICHIER identique à \\i, mais relatif à l'emplacement du script\n" " ou un |tube\n" -#: help.c:209 +#: help.c:210 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr "" " \\o [FICHIER] envoie les résultats de la requête vers un fichier\n" " ou un |tube\n" -#: help.c:210 +#: help.c:211 #, c-format msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr "" " \\qecho [TEXTE] écrit un texte sur la sortie des résultats des\n" " requêtes (voir \\o)\n" -#: help.c:213 +#: help.c:214 #, c-format msgid "Conditional\n" msgstr "Conditionnel\n" -#: help.c:214 +#: help.c:215 #, c-format msgid " \\if EXPR begin conditional block\n" msgstr " \\if EXPR début du bloc conditionnel\n" -#: help.c:215 +#: help.c:216 #, c-format msgid " \\elif EXPR alternative within current conditional block\n" msgstr " \\elif alternative à l'intérieur du bloc conditionnel courant\n" -#: help.c:216 +#: help.c:217 #, c-format msgid " \\else final alternative within current conditional block\n" msgstr " \\else alternative finale à l'intérieur du bloc conditionnel courant\n" -#: help.c:217 +#: help.c:218 #, c-format msgid " \\endif end conditional block\n" msgstr " \\endif bloc conditionnel de fin\n" -#: help.c:220 +#: help.c:221 #, c-format msgid "Informational\n" msgstr "Informations\n" -#: help.c:221 +#: help.c:222 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (options : S = affiche les objets systèmes, + = informations supplémentaires)\n" -#: help.c:222 +#: help.c:223 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] affiche la liste des tables, vues et séquences\n" -#: help.c:223 +#: help.c:224 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr "" " \\d[S+] NOM affiche la description de la table, de la vue,\n" " de la séquence ou de l'index\n" -#: help.c:224 +#: help.c:225 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [MODÈLE] affiche les aggrégats\n" -#: help.c:225 +#: help.c:226 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [MODÈLE] affiche la liste des méthodes d'accès\n" -#: help.c:226 +#: help.c:227 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [MODÈLE] affiche la liste des tablespaces\n" -#: help.c:227 +#: help.c:228 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [MODÈLE] affiche la liste des conversions\n" -#: help.c:228 +#: help.c:229 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [MODÈLE] affiche la liste des transtypages\n" -#: help.c:229 +#: help.c:230 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr "" " \\dd[S] [MODÈLE] affiche les commentaires des objets dont le commentaire\n" " n'est affiché nul part ailleurs\n" -#: help.c:230 +#: help.c:231 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" msgstr " \\dD[S+] [MODÈLE] affiche la liste des domaines\n" -#: help.c:231 +#: help.c:232 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [MODÈLE] affiche les droits par défaut\n" -#: help.c:232 +#: help.c:233 #, c-format msgid " \\dE[S+] [PATTERN] list foreign tables\n" msgstr " \\dE[S+] [MODÈLE] affiche la liste des tables distantes\n" -#: help.c:233 +#: help.c:234 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [MODÈLE] affiche la liste des tables distantes\n" -#: help.c:234 +#: help.c:235 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [MODÈLE] affiche la liste des serveurs distants\n" -#: help.c:235 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [MODÈLE] affiche la liste des correspondances utilisateurs\n" -#: help.c:236 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [MODÈLE] affiche la liste des wrappers de données distantes\n" -#: help.c:237 +#: help.c:238 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" msgstr "" -" \\df[antw][S+] [PATRN] affiche la liste des fonctions\n" -" [seulement agg/normal/trigger/window]\n" +" \\df[anptw][S+] [PATRN] affiche la liste des fonctions\n" +" [seulement agrégat/normal/procédure/trigger/window]\n" -#: help.c:238 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr "" " \\dF[+] [MODÈLE] affiche la liste des configurations de la recherche\n" " plein texte\n" -#: help.c:239 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr "" " \\dFd[+] [MODÈLE] affiche la liste des dictionnaires de la recherche de\n" " texte\n" -#: help.c:240 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr "" " \\dFp[+] [MODÈLE] affiche la liste des analyseurs de la recherche de\n" " texte\n" -#: help.c:241 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr "" " \\dFt[+] [MODÈLE] affiche la liste des modèles de la recherche de\n" " texte\n" -#: help.c:242 +#: help.c:243 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [MODÈLE] affiche la liste des rôles (utilisateurs)\n" -#: help.c:243 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [MODÈLE] affiche la liste des index\n" -#: help.c:244 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr "" " \\dl affiche la liste des « Large Objects », identique à\n" " \\lo_list\n" -#: help.c:245 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [MODÈLE] affiche la liste des langages procéduraux\n" -#: help.c:246 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [MODÈLE] affiche la liste des vues matérialisées\n" -#: help.c:247 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [MODÈLE] affiche la liste des schémas\n" -#: help.c:248 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [MODÈLE] affiche la liste des opérateurs\n" -#: help.c:249 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [MODÈLE] affiche la liste des collationnements\n" -#: help.c:250 +#: help.c:251 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr "" " \\dp [MODÈLE] affiche la liste des droits d'accès aux tables,\n" " vues, séquences\n" -#: help.c:251 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [MODEL1 [MODEL2]] liste la configuration utilisateur par base de données\n" -#: help.c:252 +#: help.c:253 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[S+] [MODÈLE] affiche la liste des publications de réplication\n" -#: help.c:253 +#: help.c:254 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [MODÈLE] affiche la liste des souscriptions de réplication\n" -#: help.c:254 +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [MODÈLE] affiche la liste des séquences\n" -#: help.c:255 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [MODÈLE] affiche la liste des tables\n" -#: help.c:256 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [MODÈLE] affiche la liste des types de données\n" -#: help.c:257 +#: help.c:258 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [MODÈLE] affiche la liste des rôles (utilisateurs)\n" -#: help.c:258 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [MODÈLE] affiche la liste des vues\n" -#: help.c:259 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [MODÈLE] affiche la liste des extensions\n" -#: help.c:260 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [MODÈLE] affiche les triggers sur évènement\n" -#: help.c:261 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [MODÈLE] affiche la liste des bases de données\n" -#: help.c:262 +#: help.c:263 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] [FONCTION] édite la définition d'une fonction\n" -#: help.c:263 +#: help.c:264 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv [FONCTION] édite la définition d'une vue\n" -#: help.c:264 +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [MODÈLE] identique à \\dp\n" -#: help.c:267 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "Formatage\n" -#: help.c:268 +#: help.c:269 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr "" " \\a bascule entre les modes de sortie alignée et non\n" " alignée\n" -#: help.c:269 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr "" " \\C [CHAÎNE] initialise le titre d'une table, ou le désactive en\n" " l'absence d'argument\n" -#: help.c:270 +#: help.c:271 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr "" " \\f [CHAÎNE] affiche ou initialise le séparateur de champ pour\n" " une sortie non alignée des requêtes\n" -#: help.c:271 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H bascule le mode de sortie HTML (actuellement %s)\n" -#: help.c:273 +#: help.c:274 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" @@ -2905,29 +2956,29 @@ msgstr "" " tuples_only|unicode_border_linestyle|\n" " unicode_column_linestyle|unicode_header_linestyle})\n" -#: help.c:279 +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t affiche uniquement les lignes (actuellement %s)\n" -#: help.c:281 +#: help.c:282 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr "" " \\T [CHAÃŽNE] initialise les attributs HTML de la balise
,\n" " ou l'annule en l'absence d'argument\n" -#: help.c:282 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] bascule l'affichage étendu (actuellement %s)\n" -#: help.c:286 +#: help.c:287 #, c-format msgid "Connection\n" msgstr "Connexions\n" -#: help.c:288 +#: help.c:289 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2937,7 +2988,7 @@ msgstr "" " se connecte à une autre base de données\n" " (actuellement « %s »)\n" -#: help.c:292 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2947,17 +2998,17 @@ msgstr "" " se connecte à une nouvelle base de données\n" " (aucune connexion actuellement)\n" -#: help.c:294 +#: help.c:295 #, c-format msgid " \\conninfo display information about current connection\n" msgstr " \\conninfo affiche des informations sur la connexion en cours\n" -#: help.c:295 +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [ENCODAGE] affiche ou initialise l'encodage du client\n" -#: help.c:296 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr "" @@ -2965,65 +3016,65 @@ msgstr "" " modifie de façon sécurisé le mot de passe d'un\n" " utilisateur\n" -#: help.c:299 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "Système d'exploitation\n" -#: help.c:300 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [RÉPERTOIRE] change de répertoire de travail\n" -#: help.c:301 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NOM [VALEUR] (dés)initialise une variable d'environnement\n" -#: help.c:302 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr "" " \\timing [on|off] bascule l'activation du chronométrage des commandes\n" " (actuellement %s)\n" -#: help.c:304 +#: help.c:305 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr "" " \\! [COMMANDE] exécute la commande dans un shell ou exécute un\n" " shell interactif\n" -#: help.c:307 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "Variables\n" -#: help.c:308 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr "" " \\prompt [TEXTE] NOM demande à l'utilisateur de configurer la variable\n" " interne\n" -#: help.c:309 +#: help.c:310 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr "" " \\set [NOM [VALEUR]] initialise une variable interne ou les affiche\n" " toutes en l'absence de paramètre\n" -#: help.c:310 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NOM désactive (supprime) la variable interne\n" -#: help.c:313 +#: help.c:314 #, c-format msgid "Large Objects\n" msgstr "« Large objects »\n" -#: help.c:314 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -3037,7 +3088,7 @@ msgstr "" " \\lo_unlink OIDLOB\n" " opérations sur les « Large Objects »\n" -#: help.c:341 +#: help.c:342 #, c-format msgid "" "List of specially treated variables\n" @@ -3046,12 +3097,12 @@ msgstr "" "Liste des variables traitées spécialement\n" "\n" -#: help.c:343 +#: help.c:344 #, c-format msgid "psql variables:\n" msgstr "variables psql :\n" -#: help.c:345 +#: help.c:346 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -3062,148 +3113,301 @@ msgstr "" " ou \\set NOM VALEUR dans psql\n" "\n" -#: help.c:347 -#, c-format -msgid " AUTOCOMMIT if set, successful SQL commands are automatically committed\n" -msgstr " AUTOCOMMIT si activé, les commandes SQL réussies sont automatiquement validées\n" - #: help.c:348 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" msgstr "" -" COMP_KEYWORD_CASE détermine la casse utilisée pour compléter les mots clés SQL\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" AUTOCOMMIT\n" +" si activé, les commandes SQL réussies sont automatiquement validées\n" #: help.c:350 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME le nom de base de données actuel\n" - -#: help.c:351 -#, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" ECHO contrôle ce qui est envoyé sur la sortie standard\n" -" [all, errors, none, queries]\n" +" COMP_KEYWORD_CASE\n" +" détermine la casse utilisée pour compléter les mots clés SQL\n" +" [lower, upper, preserve-lower, preserve-upper]\n" #: help.c:353 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash commands;\n" -" if set to \"noexec\", just show without execution\n" +" DBNAME\n" +" the currently connected database name\n" msgstr "" -" ECHO_HIDDEN si activé, affiche les requêtes internes exécutées par les méta-commandes ;\n" -" si configuré à « noexec », affiche les requêtes mais ne les exécute pas\n" +" DBNAME\n" +" le nom de base de données actuel\n" #: help.c:355 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING encodage du jeu de caractères client\n" - -#: help.c:356 -#, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a time\n" -" (default: 0=unlimited)\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" -" FETCH_COUNT le nombre de lignes résultats à récupérer et à afficher à la fois\n" -" (par défaut 0 pour illimité)\n" +" ECHO\n" +" contrôle ce qui est envoyé sur la sortie standard\n" +" [all, errors, none, queries]\n" #: help.c:358 #, c-format -msgid " HISTCONTROL controls command history [ignorespace, ignoredups, ignoreboth]\n" -msgstr " HISTCONTROL contrôle l'historique des commandes [ignorespace, ignoredups, ignoreboth]\n" +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" si activé, affiche les requêtes internes exécutées par les méta-commandes ;\n" +" si configuré à « noexec », affiche les requêtes sans les exécuter\n" -#: help.c:359 +#: help.c:361 #, c-format -msgid " HISTFILE file name used to store the command history\n" -msgstr " HISTFILE nom du fichier utilisé pour stocker l'historique des commandes\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" encodage du jeu de caractères client\n" -#: help.c:360 +#: help.c:363 #, c-format -msgid " HISTSIZE max number of commands to store in the command history\n" -msgstr " HISTSIZE nombre maximum de commandes à stocker dans l'historique de commandes\n" +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" true si la dernière requête a échoué, sinon false\n" -#: help.c:361 +#: help.c:365 #, c-format -msgid " HOST the currently connected database server host\n" -msgstr " HOST l'hôte de la base de données\n" +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" le nombre de lignes résultats à récupérer et à afficher à la fois\n" +" (0 pour illimité)\n" -#: help.c:362 +#: help.c:367 #, c-format -msgid " IGNOREEOF number of EOFs needed to terminate an interactive session\n" -msgstr " IGNOREEOF nombre d'EOF nécessaire pour terminer une session interactive\n" +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" contrôle l'historique des commandes [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:363 +#: help.c:369 #, c-format -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID valeur du dernier OID affecté\n" +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" nom du fichier utilisé pour stocker l'historique des commandes\n" -#: help.c:364 +#: help.c:371 #, c-format -msgid " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit savepoints)\n" -msgstr " ON_ERROR_ROLLBACK si activé, une erreur n'arrête pas une transaction (utilise des savepoints implicites)\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" nombre maximum de commandes à stocker dans l'historique de commandes\n" -#: help.c:365 +#: help.c:373 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr " ON_ERROR_STOP arrête l'exécution d'un batch après une erreur\n" +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" l'hôte de la base de données\n" -#: help.c:366 +#: help.c:375 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT port du server pour la connexion actuelle\n" +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" nombre d'EOF nécessaire pour terminer une session interactive\n" -#: help.c:367 +#: help.c:377 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 spécifie l'invite standard de psql\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" valeur du dernier OID affecté\n" -#: help.c:368 +#: help.c:379 #, c-format -msgid " PROMPT2 specifies the prompt used when a statement continues from a previous line\n" -msgstr " PROMPT2 spécifie l'invite utilisé quand une requête continue après la ligne courante\n" +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message et SQLSTATE de la dernière erreur ou une chaîne vide et \"00000\" if si aucune erreur\n" -#: help.c:369 +#: help.c:382 #, c-format -msgid " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr " PROMPT3 spécifie l'invite utilisée lors d'un COPY ... FROM STDIN\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" si activé, une erreur n'arrête pas une transaction (utilise des savepoints implicites)\n" -#: help.c:370 +#: help.c:384 #, c-format -msgid " QUIET run quietly (same as -q option)\n" -msgstr " QUIET s'exécute en silence (identique à l'option -q)\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" arrête l'exécution d'un batch après une erreur\n" -#: help.c:371 +#: help.c:386 #, c-format -msgid " SHOW_CONTEXT controls display of message context fields [never, errors, always]\n" -msgstr " SHOW_CONTEXT contrôle l'affichage des champs de contexte du message [never, errors, always]\n" +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" port du serveur pour la connexion actuelle\n" -#: help.c:372 +#: help.c:388 #, c-format -msgid " SINGLELINE end of line terminates SQL command mode (same as -S option)\n" -msgstr " SINGLELINE une fin de ligne termine le mode de commande SQL (identique à l'option -S)\n" +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" spécifie l'invite standard de psql\n" -#: help.c:373 +#: help.c:390 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP mode pas à pas (identique à l'option -s)\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" spécifie l'invite utilisé quand une requête continue après la ligne courante\n" -#: help.c:374 +#: help.c:392 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER l'utilisateur actuellement connecté\n" +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" spécifie l'invite utilisée lors d'un COPY ... FROM STDIN\n" -#: help.c:375 +#: help.c:394 #, c-format -msgid " VERBOSITY controls verbosity of error reports [default, verbose, terse]\n" -msgstr " VERBOSITY contrôle la verbosité des rapports d'erreurs [default, verbose, terse]\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" s'exécute en silence (identique à l'option -q)\n" -#: help.c:377 +#: help.c:396 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" nombre de lignes renvoyées ou affectées par la dernière requête, ou 0\n" + +#: help.c:398 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" version du serveur (chaîne courte ou format numérique)\n" + +#: help.c:401 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" contrôle l'affichage des champs de contexte du message [never, errors, always]\n" + +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" une fin de ligne termine le mode de commande SQL (identique à l'option -S)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" mode pas à pas (identique à l'option -s)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE de la dernière requête, ou \"00000\" si aucune erreur\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" l'utilisateur actuellement connecté\n" + +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" contrôle la verbosité des rapports d'erreurs [default, verbose, terse]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" version de psql (chaîne longue, chaîne courte, ou format numérique)\n" + +#: help.c:418 #, c-format msgid "" "\n" @@ -3212,7 +3416,7 @@ msgstr "" "\n" "Paramètres d'affichage :\n" -#: help.c:379 +#: help.c:420 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3223,113 +3427,169 @@ msgstr "" " ou \\pset NOM [VALEUR] dans psql\n" "\n" -#: help.c:381 +#: help.c:422 #, c-format -msgid " border border style (number)\n" -msgstr " border style de bordure (nombre)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" style de bordure (nombre)\n" -#: help.c:382 +#: help.c:424 #, c-format -msgid " columns target width for the wrapped format\n" -msgstr " columns largeur cible pour le format encadré\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" largeur cible pour le format encadré\n" -#: help.c:383 +#: help.c:426 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" -msgstr " expanded (or x) sortie étendue [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (ou x)\n" +" sortie étendue [on, off, auto]\n" -#: help.c:384 +#: help.c:428 #, c-format -msgid " fieldsep field separator for unaligned output (default \"%s\")\n" -msgstr " fieldsep champ séparateur pour l'affichage non aligné (par défaut « %s »)\n" +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" champ séparateur pour l'affichage non aligné (par défaut « %s »)\n" -#: help.c:385 +#: help.c:431 #, c-format -msgid " fieldsep_zero set field separator for unaligned output to zero byte\n" +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" msgstr "" -" fieldsep_zero configure le séparateur de champ pour l'affichage non\\n\n" -" aligné à l'octet zéro\n" +" fieldsep_zero\n" +" configure le séparateur de champ pour l'affichage non alignée à l'octet zéro\n" -#: help.c:386 +#: help.c:433 #, c-format -msgid " footer enable or disable display of the table footer [on, off]\n" -msgstr " footer active ou désactive l'affiche du bas de tableau [on, off]\n" +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" active ou désactive l'affiche du bas de tableau [on, off]\n" -#: help.c:387 +#: help.c:435 #, c-format -msgid " format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -msgstr " format active le format de sortie [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" active le format de sortie [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:388 +#: help.c:437 #, c-format -msgid " linestyle set the border line drawing style [ascii, old-ascii, unicode]\n" -msgstr " linestyle configure l'affichage des lignes de bordure [ascii, old-ascii, unicode]\n" +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" configure l'affichage des lignes de bordure [ascii, old-ascii, unicode]\n" -#: help.c:389 +#: help.c:439 #, c-format -msgid " null set the string to be printed in place of a null value\n" -msgstr " null configure la chaîne à afficher à la place d'une valeur NULL\n" +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" configure la chaîne à afficher à la place d'une valeur NULL\n" -#: help.c:390 +#: help.c:441 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale active ou désactive l'affichage d'un caractère spécigique à la locale pour séparer\n" -" des groupes de chiffres [on, off]\n" +" numericlocale\n" +" active ou désactive l'affichage d'un caractère spécifique à la locale pour séparer\n" +" des groupes de chiffres [on, off]\n" -#: help.c:392 +#: help.c:443 #, c-format -msgid " pager control when an external pager is used [yes, no, always]\n" -msgstr " pager contrôle quand un paginateur externe est utilisé [yes, no, always]\n" +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" contrôle quand un paginateur externe est utilisé [yes, no, always]\n" -#: help.c:393 +#: help.c:445 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" -msgstr " recordsep enregistre le séparateur de ligne pour les affichages non alignés\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" enregistre le séparateur de ligne pour les affichages non alignés\n" -#: help.c:394 +#: help.c:447 #, c-format -msgid " recordsep_zero set record separator for unaligned output to zero byte\n" +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" msgstr "" -" recordsep_zero initialise le séparateur d'enregistrements pour un affichage\n" -" non aligné à l'octet zéro\n" -"\n" +" recordsep_zero\n" +" initialise le séparateur d'enregistrements pour un affichage\n" +" non aligné à l'octet zéro\n" -#: help.c:395 +#: help.c:449 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or proportional\n" -" column widths for left-aligned data types in latex-longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (or T) indique les attributs pour la balise de table dans le format html ou les largeurs\n" -" proportionnelles de colonnes pour les types de données alignés à gauche dans le format latex-longtable\n" +" tableattr (ou T)\n" +" indique les attributs pour la balise de table dans le format html ou les largeurs\n" +" proportionnelles de colonnes pour les types de données alignés à gauche dans le\n" +" format latex-longtable\n" -#: help.c:397 +#: help.c:452 #, c-format -msgid " title set the table title for any subsequently printed tables\n" -msgstr " title configure le titre de la table pour toute table affichée\n" +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" configure le titre de la table pour toute table affichée\n" -#: help.c:398 +#: help.c:454 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" -msgstr " tuples_only si activé, seules les données de la table sont affichées\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" si activé, seules les données de la table sont affichées\n" -#: help.c:399 +#: help.c:456 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" configure le style d'affichage de ligne Unicode [single, double]\n" +" configure le style d'affichage de ligne Unicode [single, double]\n" -#: help.c:404 +#: help.c:461 #, c-format msgid "" "\n" @@ -3338,7 +3598,7 @@ msgstr "" "\n" "Variables d'environnement :\n" -#: help.c:408 +#: help.c:465 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3349,7 +3609,7 @@ msgstr "" " ou \\setenv NOM [VALEUR] dans psql\n" "\n" -#: help.c:410 +#: help.c:467 #, c-format msgid "" " set NAME=VALUE\n" @@ -3362,94 +3622,146 @@ msgstr "" " ou \\setenv NOM [VALEUR] dans psql\n" "\n" -#: help.c:413 -#, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS nombre de colonnes pour le format encadré\n" - -#: help.c:414 +#: help.c:470 #, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER nom du paginateur externe\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" nombre de colonnes pour le format encadré\n" -#: help.c:415 +#: help.c:472 #, c-format -msgid " PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME identique au paramètre de connexion application_name\n" +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" identique au paramètre de connexion application_name\n" -#: help.c:416 +#: help.c:474 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE identique au paramètre de connexion dbname\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" identique au paramètre de connexion dbname\n" -#: help.c:417 +#: help.c:476 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST identique au paramètre de connexion host\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" identique au paramètre de connexion host\n" -#: help.c:418 +#: help.c:478 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" -msgstr " PGPASSWORD mot de passe de connexion (non recommendé)\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" mot de passe de connexion (non recommendé)\n" -#: help.c:419 +#: help.c:480 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE nom du fichier de mot de passe\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" nom du fichier de mot de passe\n" -#: help.c:420 +#: help.c:482 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT identique au paramètre de connexion port\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" identique au paramètre de connexion port\n" -#: help.c:421 +#: help.c:484 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER identique au paramètre de connexion user\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" identique au paramètre de connexion user\n" -#: help.c:422 +#: help.c:486 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" éditeur utilisé par les commandes \\e, \\ef et \\ev\n" +" éditeur utilisé par les commandes \\e, \\ef et \\ev\n" -#: help.c:424 +#: help.c:488 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" comment spécifier un numéro de ligne lors de l'appel de l'éditeur\n" +" comment spécifier un numéro de ligne lors de l'appel de l'éditeur\n" -#: help.c:426 +#: help.c:490 #, c-format -msgid " PSQL_HISTORY alternative location for the command history file\n" -msgstr " PSQL_HISTORY autre emplacement pour le fichier d'historique des commandes\n" +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" autre emplacement pour le fichier d'historique des commandes\n" -#: help.c:427 +#: help.c:492 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" -msgstr " PSQLRC autre emplacement pour le fichier .psqlrc de l'utilisateur\n" +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" nom du paginateur externe\n" -#: help.c:428 +#: help.c:494 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" autre emplacement pour le fichier .psqlrc de l'utilisateur\n" + +#: help.c:496 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL shell utilisé par la commande \\!\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell utilisé par la commande \\!\n" -#: help.c:429 +#: help.c:498 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR répertoire pour les fichiers temporaires\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" répertoire pour les fichiers temporaires\n" -#: help.c:472 +#: help.c:542 msgid "Available help:\n" msgstr "Aide-mémoire disponible :\n" -#: help.c:556 +#: help.c:626 #, c-format msgid "" "Command: %s\n" @@ -3464,7 +3776,7 @@ msgstr "" "%s\n" "\n" -#: help.c:572 +#: help.c:642 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3529,11 +3841,19 @@ msgstr "" "Les données en entrée proviennent d'une sauvegarde PostgreSQL au format custom.\n" "Utilisez l'outil en ligne de commande pg_restore pour restaurer cette sauvegarde dans une base de données.\n" -#: mainloop.c:225 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Utilisez \\? pour l'aide ou appuyez sur control-C pour vider le tampon de saisie." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Utilisez \\? pour l'aide." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Vous utilisez psql, l'interface en ligne de commande de PostgreSQL." -#: mainloop.c:226 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3549,2187 +3869,2279 @@ msgstr "" " \\g ou point-virgule en fin d'instruction pour exécuter la requête\n" " \\q pour quitter\n" -#: mainloop.c:339 mainloop.c:476 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Utilisez \\q pour quitter." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Utilisez control-D pour quitter." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Utilisez control-C pour quitter." + +#: mainloop.c:449 mainloop.c:591 #, c-format msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "requête ignorée ; utilisez \\endif ou Ctrl-C pour quitter le bloc \\if courant\n" -#: mainloop.c:494 +#: mainloop.c:609 #, c-format msgid "reached EOF without finding closing \\endif(s)\n" msgstr "a atteint EOF sans trouver le(s) \\endif fermant\n" -#: psqlscanslash.l:614 +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" msgstr "chaîne entre guillemets non terminée\n" -#: psqlscanslash.l:787 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" msgstr "%s : mémoire épuisée\n" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 -#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 -#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 -#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 -#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 -#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 -#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 -#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 -#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 -#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 -#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 -#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 -#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 -#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:807 -#: sql_help.c:809 sql_help.c:811 sql_help.c:813 sql_help.c:816 sql_help.c:818 -#: sql_help.c:859 sql_help.c:882 sql_help.c:893 sql_help.c:895 sql_help.c:914 -#: sql_help.c:924 sql_help.c:926 sql_help.c:928 sql_help.c:940 sql_help.c:944 -#: sql_help.c:946 sql_help.c:957 sql_help.c:959 sql_help.c:961 sql_help.c:977 -#: sql_help.c:979 sql_help.c:983 sql_help.c:986 sql_help.c:987 sql_help.c:988 -#: sql_help.c:991 sql_help.c:993 sql_help.c:1084 sql_help.c:1086 -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 -#: sql_help.c:1099 sql_help.c:1102 sql_help.c:1168 sql_help.c:1170 -#: sql_help.c:1172 sql_help.c:1175 sql_help.c:1196 sql_help.c:1199 -#: sql_help.c:1202 sql_help.c:1205 sql_help.c:1209 sql_help.c:1211 -#: sql_help.c:1213 sql_help.c:1215 sql_help.c:1229 sql_help.c:1232 -#: sql_help.c:1234 sql_help.c:1236 sql_help.c:1246 sql_help.c:1248 -#: sql_help.c:1258 sql_help.c:1260 sql_help.c:1270 sql_help.c:1273 -#: sql_help.c:1295 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 -#: sql_help.c:1304 sql_help.c:1306 sql_help.c:1309 sql_help.c:1359 -#: sql_help.c:1397 sql_help.c:1400 sql_help.c:1402 sql_help.c:1404 -#: sql_help.c:1406 sql_help.c:1408 sql_help.c:1411 sql_help.c:1451 -#: sql_help.c:1662 sql_help.c:1726 sql_help.c:1745 sql_help.c:1758 -#: sql_help.c:1814 sql_help.c:1820 sql_help.c:1830 sql_help.c:1850 -#: sql_help.c:1875 sql_help.c:1893 sql_help.c:1922 sql_help.c:2015 -#: sql_help.c:2057 sql_help.c:2079 sql_help.c:2099 sql_help.c:2100 -#: sql_help.c:2135 sql_help.c:2155 sql_help.c:2177 sql_help.c:2191 -#: sql_help.c:2206 sql_help.c:2236 sql_help.c:2261 sql_help.c:2307 -#: sql_help.c:2573 sql_help.c:2586 sql_help.c:2603 sql_help.c:2619 -#: sql_help.c:2659 sql_help.c:2711 sql_help.c:2715 sql_help.c:2717 -#: sql_help.c:2723 sql_help.c:2741 sql_help.c:2768 sql_help.c:2803 -#: sql_help.c:2815 sql_help.c:2824 sql_help.c:2868 sql_help.c:2882 -#: sql_help.c:2910 sql_help.c:2918 sql_help.c:2926 sql_help.c:2934 -#: sql_help.c:2942 sql_help.c:2950 sql_help.c:2958 sql_help.c:2966 -#: sql_help.c:2975 sql_help.c:2986 sql_help.c:2994 sql_help.c:3002 -#: sql_help.c:3010 sql_help.c:3018 sql_help.c:3028 sql_help.c:3037 -#: sql_help.c:3046 sql_help.c:3054 sql_help.c:3063 sql_help.c:3071 -#: sql_help.c:3079 sql_help.c:3088 sql_help.c:3096 sql_help.c:3104 -#: sql_help.c:3112 sql_help.c:3120 sql_help.c:3128 sql_help.c:3136 -#: sql_help.c:3144 sql_help.c:3152 sql_help.c:3160 sql_help.c:3168 -#: sql_help.c:3185 sql_help.c:3194 sql_help.c:3202 sql_help.c:3219 -#: sql_help.c:3234 sql_help.c:3502 sql_help.c:3553 sql_help.c:3582 -#: sql_help.c:3590 sql_help.c:4013 sql_help.c:4061 sql_help.c:4202 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 msgid "name" msgstr "nom" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1520 -#: sql_help.c:2883 sql_help.c:3807 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 msgid "aggregate_signature" msgstr "signature_agrégat" -#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 -#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 -#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 -#: sql_help.c:789 sql_help.c:819 sql_help.c:860 sql_help.c:884 sql_help.c:894 -#: sql_help.c:927 sql_help.c:947 sql_help.c:960 sql_help.c:994 sql_help.c:1093 -#: sql_help.c:1169 sql_help.c:1212 sql_help.c:1233 sql_help.c:1247 -#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1303 sql_help.c:1360 -#: sql_help.c:1405 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "nouveau_nom" -#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 -#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 -#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 -#: sql_help.c:817 sql_help.c:896 sql_help.c:925 sql_help.c:945 sql_help.c:958 -#: sql_help.c:992 sql_help.c:1153 sql_help.c:1171 sql_help.c:1214 -#: sql_help.c:1235 sql_help.c:1298 sql_help.c:1403 sql_help.c:2559 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "nouveau_propriétaire" -#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 -#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 -#: sql_help.c:774 sql_help.c:929 sql_help.c:962 sql_help.c:1095 sql_help.c:1216 -#: sql_help.c:1237 sql_help.c:1249 sql_help.c:1261 sql_help.c:1305 -#: sql_help.c:1407 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "nouveau_schéma" -#: sql_help.c:45 sql_help.c:1576 sql_help.c:2884 sql_help.c:3828 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 msgid "where aggregate_signature is:" msgstr "où signature_agrégat est :" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 -#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 -#: sql_help.c:522 sql_help.c:527 sql_help.c:1538 sql_help.c:1577 -#: sql_help.c:1580 sql_help.c:1583 sql_help.c:1727 sql_help.c:1746 -#: sql_help.c:1749 sql_help.c:2016 sql_help.c:2885 sql_help.c:2888 -#: sql_help.c:2891 sql_help.c:2976 sql_help.c:3387 sql_help.c:3720 -#: sql_help.c:3813 sql_help.c:3829 sql_help.c:3832 sql_help.c:3835 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 msgid "argmode" msgstr "mode_argument" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 -#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 -#: sql_help.c:523 sql_help.c:528 sql_help.c:1539 sql_help.c:1578 -#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1728 sql_help.c:1747 -#: sql_help.c:1750 sql_help.c:2017 sql_help.c:2886 sql_help.c:2889 -#: sql_help.c:2892 sql_help.c:2977 sql_help.c:3814 sql_help.c:3830 -#: sql_help.c:3833 sql_help.c:3836 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 msgid "argname" msgstr "nom_agrégat" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 -#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 -#: sql_help.c:524 sql_help.c:529 sql_help.c:1540 sql_help.c:1579 -#: sql_help.c:1582 sql_help.c:1585 sql_help.c:2018 sql_help.c:2887 -#: sql_help.c:2890 sql_help.c:2893 sql_help.c:2978 sql_help.c:3815 -#: sql_help.c:3831 sql_help.c:3834 sql_help.c:3837 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 msgid "argtype" msgstr "type_argument" -#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:854 -#: sql_help.c:942 sql_help.c:1230 sql_help.c:1354 sql_help.c:1382 -#: sql_help.c:1633 sql_help.c:1639 sql_help.c:1925 sql_help.c:1966 -#: sql_help.c:1973 sql_help.c:1982 sql_help.c:2058 sql_help.c:2237 -#: sql_help.c:2329 sql_help.c:2588 sql_help.c:2769 sql_help.c:2791 -#: sql_help.c:3254 sql_help.c:3421 +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "option" -#: sql_help.c:114 sql_help.c:855 sql_help.c:1355 sql_help.c:2059 -#: sql_help.c:2238 sql_help.c:2770 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" msgstr "où option peut être :" -#: sql_help.c:115 sql_help.c:1857 +#: sql_help.c:114 sql_help.c:2118 msgid "allowconn" msgstr "allowconn" -#: sql_help.c:116 sql_help.c:856 sql_help.c:1356 sql_help.c:1858 -#: sql_help.c:2239 sql_help.c:2771 +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" msgstr "limite_de_connexion" -#: sql_help.c:117 sql_help.c:1859 +#: sql_help.c:116 sql_help.c:2120 msgid "istemplate" msgstr "istemplate" -#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1098 sql_help.c:1146 +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "nouveau_tablespace" -#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 -#: sql_help.c:537 sql_help.c:863 sql_help.c:867 sql_help.c:870 sql_help.c:1005 -#: sql_help.c:1008 sql_help.c:1362 sql_help.c:1365 sql_help.c:1367 -#: sql_help.c:2027 sql_help.c:3607 sql_help.c:4002 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" msgstr "paramètre_configuration" -#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 -#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:815 -#: sql_help.c:864 sql_help.c:943 sql_help.c:982 sql_help.c:985 sql_help.c:990 -#: sql_help.c:1006 sql_help.c:1007 sql_help.c:1128 sql_help.c:1148 -#: sql_help.c:1174 sql_help.c:1231 sql_help.c:1363 sql_help.c:1383 -#: sql_help.c:1926 sql_help.c:1967 sql_help.c:1974 sql_help.c:1983 -#: sql_help.c:2028 sql_help.c:2029 sql_help.c:2087 sql_help.c:2119 -#: sql_help.c:2209 sql_help.c:2330 sql_help.c:2360 sql_help.c:2458 -#: sql_help.c:2470 sql_help.c:2483 sql_help.c:2523 sql_help.c:2545 -#: sql_help.c:2562 sql_help.c:2589 sql_help.c:2792 sql_help.c:3422 -#: sql_help.c:4003 sql_help.c:4004 +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "valeur" -#: sql_help.c:198 +#: sql_help.c:197 msgid "target_role" msgstr "rôle_cible" -#: sql_help.c:199 sql_help.c:1909 sql_help.c:2285 sql_help.c:2290 -#: sql_help.c:3369 sql_help.c:3376 sql_help.c:3390 sql_help.c:3396 -#: sql_help.c:3702 sql_help.c:3709 sql_help.c:3723 sql_help.c:3729 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "nom_schéma" -#: sql_help.c:200 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "grant_ou_revoke_raccourci" -#: sql_help.c:201 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "où abbreviated_grant_or_revoke fait partie de :" -#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 -#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 -#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:874 -#: sql_help.c:1097 sql_help.c:1370 sql_help.c:2062 sql_help.c:2063 -#: sql_help.c:2064 sql_help.c:2065 sql_help.c:2066 sql_help.c:2193 -#: sql_help.c:2242 sql_help.c:2243 sql_help.c:2244 sql_help.c:2245 -#: sql_help.c:2246 sql_help.c:2774 sql_help.c:2775 sql_help.c:2776 -#: sql_help.c:2777 sql_help.c:2778 sql_help.c:3403 sql_help.c:3404 -#: sql_help.c:3405 sql_help.c:3703 sql_help.c:3707 sql_help.c:3710 -#: sql_help.c:3712 sql_help.c:3714 sql_help.c:3716 sql_help.c:3718 -#: sql_help.c:3724 sql_help.c:3726 sql_help.c:3728 sql_help.c:3730 -#: sql_help.c:3732 sql_help.c:3734 sql_help.c:3735 sql_help.c:3736 -#: sql_help.c:4023 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "nom_rôle" -#: sql_help.c:237 sql_help.c:451 sql_help.c:1113 sql_help.c:1115 -#: sql_help.c:1399 sql_help.c:1878 sql_help.c:1882 sql_help.c:1986 -#: sql_help.c:1990 sql_help.c:2083 sql_help.c:2454 sql_help.c:2466 -#: sql_help.c:2479 sql_help.c:2487 sql_help.c:2498 sql_help.c:2527 -#: sql_help.c:3453 sql_help.c:3468 sql_help.c:3470 sql_help.c:3888 -#: sql_help.c:3889 sql_help.c:3898 sql_help.c:3939 sql_help.c:3940 -#: sql_help.c:3941 sql_help.c:3942 sql_help.c:3943 sql_help.c:3944 -#: sql_help.c:3977 sql_help.c:3978 sql_help.c:3983 sql_help.c:3988 -#: sql_help.c:4127 sql_help.c:4128 sql_help.c:4137 sql_help.c:4178 -#: sql_help.c:4179 sql_help.c:4180 sql_help.c:4181 sql_help.c:4182 -#: sql_help.c:4183 sql_help.c:4230 sql_help.c:4232 sql_help.c:4265 -#: sql_help.c:4321 sql_help.c:4322 sql_help.c:4331 sql_help.c:4372 -#: sql_help.c:4373 sql_help.c:4374 sql_help.c:4375 sql_help.c:4376 -#: sql_help.c:4377 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "expression" -#: sql_help.c:240 +#: sql_help.c:239 msgid "domain_constraint" msgstr "contrainte_domaine" -#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 -#: sql_help.c:1090 sql_help.c:1134 sql_help.c:1135 sql_help.c:1136 -#: sql_help.c:1156 sql_help.c:1526 sql_help.c:1528 sql_help.c:1881 -#: sql_help.c:1985 sql_help.c:1989 sql_help.c:2486 sql_help.c:2497 -#: sql_help.c:3465 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "nom_contrainte" -#: sql_help.c:245 sql_help.c:1091 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "nouvelle_nom_contrainte" -#: sql_help.c:316 sql_help.c:941 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "nouvelle_version" -#: sql_help.c:320 sql_help.c:322 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "objet_membre" -#: sql_help.c:323 +#: sql_help.c:324 msgid "where member_object is:" msgstr "où objet_membre fait partie de :" -#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 -#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 -#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 -#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 -#: sql_help.c:359 sql_help.c:1518 sql_help.c:1523 sql_help.c:1530 -#: sql_help.c:1531 sql_help.c:1532 sql_help.c:1533 sql_help.c:1534 -#: sql_help.c:1535 sql_help.c:1536 sql_help.c:1541 sql_help.c:1543 -#: sql_help.c:1547 sql_help.c:1549 sql_help.c:1553 sql_help.c:1554 -#: sql_help.c:1555 sql_help.c:1558 sql_help.c:1559 sql_help.c:1560 -#: sql_help.c:1561 sql_help.c:1562 sql_help.c:1563 sql_help.c:1564 -#: sql_help.c:1565 sql_help.c:1566 sql_help.c:1567 sql_help.c:1568 -#: sql_help.c:1573 sql_help.c:1574 sql_help.c:3803 sql_help.c:3808 -#: sql_help.c:3809 sql_help.c:3810 sql_help.c:3811 sql_help.c:3817 -#: sql_help.c:3818 sql_help.c:3819 sql_help.c:3820 sql_help.c:3821 -#: sql_help.c:3822 sql_help.c:3823 sql_help.c:3824 sql_help.c:3825 -#: sql_help.c:3826 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 msgid "object_name" msgstr "nom_objet" -#: sql_help.c:325 sql_help.c:1519 sql_help.c:3806 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 msgid "aggregate_name" msgstr "nom_agrégat" -#: sql_help.c:327 sql_help.c:1521 sql_help.c:1792 sql_help.c:1796 -#: sql_help.c:1798 sql_help.c:2901 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" msgstr "type_source" -#: sql_help.c:328 sql_help.c:1522 sql_help.c:1793 sql_help.c:1797 -#: sql_help.c:1799 sql_help.c:2902 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" msgstr "type_cible" -#: sql_help.c:335 sql_help.c:756 sql_help.c:1537 sql_help.c:1794 -#: sql_help.c:1833 sql_help.c:1896 sql_help.c:2136 sql_help.c:2167 -#: sql_help.c:2665 sql_help.c:3386 sql_help.c:3719 sql_help.c:3812 -#: sql_help.c:3917 sql_help.c:3921 sql_help.c:3925 sql_help.c:3928 -#: sql_help.c:4156 sql_help.c:4160 sql_help.c:4164 sql_help.c:4167 -#: sql_help.c:4350 sql_help.c:4354 sql_help.c:4358 sql_help.c:4361 +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "nom_fonction" -#: sql_help.c:340 sql_help.c:749 sql_help.c:1544 sql_help.c:2160 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "nom_opérateur" -#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1545 -#: sql_help.c:2137 sql_help.c:3019 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "type_argument_gauche" -#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1546 -#: sql_help.c:2138 sql_help.c:3020 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "type_argument_droit" -#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 -#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 -#: sql_help.c:1548 sql_help.c:1550 sql_help.c:2157 sql_help.c:2178 -#: sql_help.c:2503 sql_help.c:3029 sql_help.c:3038 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "méthode_indexage" -#: sql_help.c:356 sql_help.c:1152 sql_help.c:1569 sql_help.c:2024 -#: sql_help.c:2461 sql_help.c:2632 sql_help.c:3176 sql_help.c:3400 -#: sql_help.c:3733 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "nom_procédure" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "nom_routine" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 msgid "type_name" msgstr "nom_type" -#: sql_help.c:357 sql_help.c:1570 sql_help.c:2023 sql_help.c:2633 -#: sql_help.c:2859 sql_help.c:3177 sql_help.c:3392 sql_help.c:3725 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 msgid "lang_name" msgstr "nom_langage" -#: sql_help.c:360 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "et signature_agrégat est :" -#: sql_help.c:383 sql_help.c:1664 sql_help.c:1923 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" msgstr "fonction_gestionnaire" -#: sql_help.c:384 sql_help.c:1924 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "fonction_validateur" -#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1085 sql_help.c:1296 -#: sql_help.c:2494 sql_help.c:2495 sql_help.c:2511 sql_help.c:2512 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "action" -#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 -#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 -#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 -#: sql_help.c:660 sql_help.c:662 sql_help.c:923 sql_help.c:1087 sql_help.c:1105 -#: sql_help.c:1109 sql_help.c:1110 sql_help.c:1114 sql_help.c:1116 -#: sql_help.c:1117 sql_help.c:1118 sql_help.c:1120 sql_help.c:1123 -#: sql_help.c:1124 sql_help.c:1126 sql_help.c:1129 sql_help.c:1131 -#: sql_help.c:1398 sql_help.c:1401 sql_help.c:1421 sql_help.c:1525 -#: sql_help.c:1630 sql_help.c:1635 sql_help.c:1649 sql_help.c:1650 -#: sql_help.c:1651 sql_help.c:1964 sql_help.c:1977 sql_help.c:2021 -#: sql_help.c:2082 sql_help.c:2117 sql_help.c:2315 sql_help.c:2343 -#: sql_help.c:2344 sql_help.c:2445 sql_help.c:2453 sql_help.c:2462 -#: sql_help.c:2465 sql_help.c:2474 sql_help.c:2478 sql_help.c:2499 -#: sql_help.c:2501 sql_help.c:2508 sql_help.c:2526 sql_help.c:2543 -#: sql_help.c:2668 sql_help.c:2804 sql_help.c:3371 sql_help.c:3372 -#: sql_help.c:3452 sql_help.c:3467 sql_help.c:3469 sql_help.c:3471 -#: sql_help.c:3704 sql_help.c:3705 sql_help.c:3805 sql_help.c:3948 -#: sql_help.c:4187 sql_help.c:4229 sql_help.c:4231 sql_help.c:4233 -#: sql_help.c:4250 sql_help.c:4253 sql_help.c:4381 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "nom_colonne" -#: sql_help.c:436 sql_help.c:646 sql_help.c:1088 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "nouvelle_nom_colonne" -#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1104 sql_help.c:1312 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" msgstr "où action fait partie de :" -#: sql_help.c:443 sql_help.c:448 sql_help.c:915 sql_help.c:1106 sql_help.c:1111 -#: sql_help.c:1314 sql_help.c:1318 sql_help.c:1876 sql_help.c:1965 -#: sql_help.c:2156 sql_help.c:2308 sql_help.c:2446 sql_help.c:2713 -#: sql_help.c:3554 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "type_données" -#: sql_help.c:444 sql_help.c:449 sql_help.c:1107 sql_help.c:1112 -#: sql_help.c:1315 sql_help.c:1319 sql_help.c:1877 sql_help.c:1968 -#: sql_help.c:2084 sql_help.c:2447 sql_help.c:2455 sql_help.c:2467 -#: sql_help.c:2480 sql_help.c:2714 sql_help.c:2720 sql_help.c:3462 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "collationnement" -#: sql_help.c:445 sql_help.c:1108 sql_help.c:1969 sql_help.c:1978 -#: sql_help.c:2448 sql_help.c:2463 sql_help.c:2475 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" msgstr "contrainte_colonne" -#: sql_help.c:455 sql_help.c:656 sql_help.c:1125 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "entier" -#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1127 -#: sql_help.c:1130 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "option_attribut" -#: sql_help.c:465 sql_help.c:1132 sql_help.c:1970 sql_help.c:1979 -#: sql_help.c:2449 sql_help.c:2464 sql_help.c:2476 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 msgid "table_constraint" msgstr "contrainte_table" -#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1137 -#: sql_help.c:1138 sql_help.c:1139 sql_help.c:1140 sql_help.c:1571 +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "nom_trigger" -#: sql_help.c:472 sql_help.c:473 sql_help.c:1150 sql_help.c:1151 -#: sql_help.c:1971 sql_help.c:1976 sql_help.c:2452 sql_help.c:2473 +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 msgid "parent_table" msgstr "table_parent" -#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1275 sql_help.c:1908 +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 msgid "extension_name" msgstr "nom_extension" -#: sql_help.c:532 sql_help.c:2025 +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "coût_exécution" -#: sql_help.c:533 sql_help.c:2026 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "lignes_de_résultat" -#: sql_help.c:554 sql_help.c:556 sql_help.c:853 sql_help.c:861 sql_help.c:865 -#: sql_help.c:868 sql_help.c:871 sql_help.c:1353 sql_help.c:1361 -#: sql_help.c:1364 sql_help.c:1366 sql_help.c:1368 sql_help.c:2286 -#: sql_help.c:2288 sql_help.c:2291 sql_help.c:2292 sql_help.c:3370 -#: sql_help.c:3374 sql_help.c:3377 sql_help.c:3379 sql_help.c:3381 -#: sql_help.c:3383 sql_help.c:3385 sql_help.c:3391 sql_help.c:3393 -#: sql_help.c:3395 sql_help.c:3397 sql_help.c:3399 sql_help.c:3401 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 msgid "role_specification" msgstr "specification_role" -#: sql_help.c:555 sql_help.c:557 sql_help.c:1380 sql_help.c:1851 -#: sql_help.c:2294 sql_help.c:2789 sql_help.c:3210 sql_help.c:4033 +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "nom_utilisateur" -#: sql_help.c:558 sql_help.c:873 sql_help.c:1369 sql_help.c:2293 -#: sql_help.c:3402 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 msgid "where role_specification can be:" msgstr "où specification_role peut être :" -#: sql_help.c:560 +#: sql_help.c:569 msgid "group_name" msgstr "nom_groupe" -#: sql_help.c:578 sql_help.c:1856 sql_help.c:2088 sql_help.c:2120 -#: sql_help.c:2459 sql_help.c:2471 sql_help.c:2484 sql_help.c:2524 -#: sql_help.c:2546 sql_help.c:2558 sql_help.c:3398 sql_help.c:3731 +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" msgstr "nom_tablespace" -#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1147 -#: sql_help.c:1149 sql_help.c:2086 sql_help.c:2118 sql_help.c:2457 -#: sql_help.c:2469 sql_help.c:2482 sql_help.c:2522 sql_help.c:2544 +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "nom_index" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "paramètre_stockage" -#: sql_help.c:608 sql_help.c:1542 sql_help.c:3816 +#: sql_help.c:601 +msgid "column_number" +msgstr "numéro_colonne" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" msgstr "oid_large_object" -#: sql_help.c:663 sql_help.c:1145 sql_help.c:1154 sql_help.c:1157 -#: sql_help.c:1461 -msgid "index_name" -msgstr "nom_index" - -#: sql_help.c:695 sql_help.c:2141 +#: sql_help.c:712 sql_help.c:2402 msgid "res_proc" msgstr "res_proc" -#: sql_help.c:696 sql_help.c:2142 +#: sql_help.c:713 sql_help.c:2403 msgid "join_proc" msgstr "join_proc" -#: sql_help.c:748 sql_help.c:760 sql_help.c:2159 +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" msgstr "numéro_de_stratégie" -#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 -#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2161 sql_help.c:2162 -#: sql_help.c:2165 sql_help.c:2166 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "type_op" -#: sql_help.c:752 sql_help.c:2163 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "nom_famille_tri" -#: sql_help.c:753 sql_help.c:763 sql_help.c:2164 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "numéro_de_support" -#: sql_help.c:757 sql_help.c:1795 sql_help.c:2168 sql_help.c:2635 -#: sql_help.c:2637 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "type_argument" -#: sql_help.c:788 sql_help.c:791 sql_help.c:808 sql_help.c:810 sql_help.c:812 -#: sql_help.c:883 sql_help.c:922 sql_help.c:1271 sql_help.c:1274 -#: sql_help.c:1420 sql_help.c:1460 sql_help.c:1527 sql_help.c:1552 -#: sql_help.c:1557 sql_help.c:1572 sql_help.c:1629 sql_help.c:1634 -#: sql_help.c:1963 sql_help.c:1975 sql_help.c:2080 sql_help.c:2116 -#: sql_help.c:2192 sql_help.c:2207 sql_help.c:2263 sql_help.c:2314 -#: sql_help.c:2345 sql_help.c:2444 sql_help.c:2460 sql_help.c:2472 -#: sql_help.c:2542 sql_help.c:2661 sql_help.c:2838 sql_help.c:3055 -#: sql_help.c:3080 sql_help.c:3186 sql_help.c:3368 sql_help.c:3373 -#: sql_help.c:3418 sql_help.c:3450 sql_help.c:3701 sql_help.c:3706 -#: sql_help.c:3804 sql_help.c:3903 sql_help.c:3905 sql_help.c:3954 -#: sql_help.c:3993 sql_help.c:4142 sql_help.c:4144 sql_help.c:4193 -#: sql_help.c:4227 sql_help.c:4249 sql_help.c:4251 sql_help.c:4252 -#: sql_help.c:4336 sql_help.c:4338 sql_help.c:4387 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 msgid "table_name" msgstr "nom_table" -#: sql_help.c:793 sql_help.c:2194 +#: sql_help.c:810 sql_help.c:2455 msgid "using_expression" msgstr "expression_using" -#: sql_help.c:794 sql_help.c:2195 +#: sql_help.c:811 sql_help.c:2456 msgid "check_expression" msgstr "expression_check" -#: sql_help.c:814 sql_help.c:2208 +#: sql_help.c:885 sql_help.c:2497 msgid "publication_parameter" msgstr "paramètre_publication" -#: sql_help.c:857 sql_help.c:1357 sql_help.c:2060 sql_help.c:2240 -#: sql_help.c:2772 +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "mot_de_passe" -#: sql_help.c:858 sql_help.c:1358 sql_help.c:2061 sql_help.c:2241 -#: sql_help.c:2773 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "horodatage" -#: sql_help.c:862 sql_help.c:866 sql_help.c:869 sql_help.c:872 sql_help.c:3378 -#: sql_help.c:3711 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "nom_base_de_donnée" -#: sql_help.c:916 sql_help.c:2309 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" msgstr "incrément" -#: sql_help.c:917 sql_help.c:2310 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "valeur_min" -#: sql_help.c:918 sql_help.c:2311 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "valeur_max" -#: sql_help.c:919 sql_help.c:2312 sql_help.c:3901 sql_help.c:3991 -#: sql_help.c:4140 sql_help.c:4269 sql_help.c:4334 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" msgstr "début" -#: sql_help.c:920 sql_help.c:1122 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" msgstr "nouveau_début" -#: sql_help.c:921 sql_help.c:2313 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" msgstr "cache" -#: sql_help.c:978 sql_help.c:2357 +#: sql_help.c:1109 sql_help.c:2646 msgid "conninfo" msgstr "conninfo" -#: sql_help.c:980 sql_help.c:2358 +#: sql_help.c:1111 sql_help.c:2647 msgid "publication_name" msgstr "nom_publication" -#: sql_help.c:981 +#: sql_help.c:1112 msgid "set_publication_option" msgstr "option_ensemble_publication" -#: sql_help.c:984 +#: sql_help.c:1115 msgid "refresh_option" msgstr "option_rafraichissement" -#: sql_help.c:989 sql_help.c:2359 +#: sql_help.c:1120 sql_help.c:2648 msgid "subscription_parameter" msgstr "paramètre_souscription" -#: sql_help.c:1100 sql_help.c:1103 +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" msgstr "nom_partition" -#: sql_help.c:1101 sql_help.c:1980 sql_help.c:2477 +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 msgid "partition_bound_spec" msgstr "partition_bound_spec" -#: sql_help.c:1119 sql_help.c:2489 +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 msgid "sequence_options" msgstr "options_séquence" -#: sql_help.c:1121 +#: sql_help.c:1294 msgid "sequence_option" msgstr "option_séquence" -#: sql_help.c:1133 +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "contrainte_table_utilisant_index" -#: sql_help.c:1141 sql_help.c:1142 sql_help.c:1143 sql_help.c:1144 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "nom_règle_réécriture" -#: sql_help.c:1155 +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "et partition_bound_spec est :" + +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "numeric_literal" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "littéral_chaîne" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "et contrainte_colonne est :" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "expression_par_défaut" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "paramètres_index" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "table_référence" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "colonne_référence" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "et contrainte_table est :" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "élément_exclusion" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "opérateur" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "prédicat" + +#: sql_help.c:1365 msgid "and table_constraint_using_index is:" msgstr "et contrainte_table_utilisant_index est :" -#: sql_help.c:1173 sql_help.c:1176 sql_help.c:2561 +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "dans les contraintes UNIQUE, PRIMARY KEY et EXCLUDE, les paramètres_index sont :" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "élément_exclusion dans une contrainte EXCLUDE est :" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "classe_d_opérateur" + +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" msgstr "option_tablespace" -#: sql_help.c:1197 sql_help.c:1200 sql_help.c:1206 sql_help.c:1210 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "type_jeton" -#: sql_help.c:1198 sql_help.c:1201 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "nom_dictionnaire" -#: sql_help.c:1203 sql_help.c:1207 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "ancien_dictionnaire" -#: sql_help.c:1204 sql_help.c:1208 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "nouveau_dictionnaire" -#: sql_help.c:1300 sql_help.c:1313 sql_help.c:1316 sql_help.c:1317 -#: sql_help.c:2712 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "nom_attribut" -#: sql_help.c:1301 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "nouveau_nom_attribut" -#: sql_help.c:1307 sql_help.c:1311 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "nouvelle_valeur_enum" -#: sql_help.c:1308 +#: sql_help.c:1527 msgid "neighbor_enum_value" msgstr "valeur_enum_voisine" -#: sql_help.c:1310 +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "valeur_enum_existante" -#: sql_help.c:1381 sql_help.c:1972 sql_help.c:1981 sql_help.c:2325 -#: sql_help.c:2790 sql_help.c:3211 sql_help.c:3384 sql_help.c:3419 -#: sql_help.c:3717 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" msgstr "nom_serveur" -#: sql_help.c:1409 sql_help.c:1412 sql_help.c:2805 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "nom_option_vue" -#: sql_help.c:1410 sql_help.c:2806 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" msgstr "valeur_option_vue" -#: sql_help.c:1435 sql_help.c:4049 sql_help.c:4051 sql_help.c:4075 +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "table_et_colonnes" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "où option fait partie de :" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "et table_et_colonnes est :" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "mode_transaction" -#: sql_help.c:1436 sql_help.c:4052 sql_help.c:4076 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" msgstr "où mode_transaction fait partie de :" -#: sql_help.c:1524 +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1772 msgid "relation_name" msgstr "nom_relation" -#: sql_help.c:1529 sql_help.c:3380 sql_help.c:3713 +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 msgid "domain_name" msgstr "nom_domaine" -#: sql_help.c:1551 +#: sql_help.c:1799 msgid "policy_name" msgstr "nom_politique" -#: sql_help.c:1556 +#: sql_help.c:1812 msgid "rule_name" msgstr "nom_règle" -#: sql_help.c:1575 +#: sql_help.c:1831 msgid "text" msgstr "texte" -#: sql_help.c:1600 sql_help.c:3563 sql_help.c:3751 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" msgstr "id_transaction" -#: sql_help.c:1631 sql_help.c:1637 sql_help.c:3489 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "nom_fichier" -#: sql_help.c:1632 sql_help.c:1638 sql_help.c:2265 sql_help.c:2266 -#: sql_help.c:2267 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "commande" -#: sql_help.c:1636 sql_help.c:2121 sql_help.c:2547 sql_help.c:2807 -#: sql_help.c:2825 sql_help.c:3454 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "requête" -#: sql_help.c:1640 sql_help.c:3257 -msgid "where option can be one of:" -msgstr "où option fait partie de :" - -#: sql_help.c:1641 +#: sql_help.c:1897 msgid "format_name" msgstr "nom_format" -#: sql_help.c:1642 sql_help.c:1643 sql_help.c:1646 sql_help.c:3258 -#: sql_help.c:3259 sql_help.c:3260 sql_help.c:3261 sql_help.c:3262 -#: sql_help.c:3263 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" msgstr "boolean" -#: sql_help.c:1644 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "caractère_délimiteur" -#: sql_help.c:1645 +#: sql_help.c:1901 msgid "null_string" msgstr "chaîne_null" -#: sql_help.c:1647 +#: sql_help.c:1903 msgid "quote_character" msgstr "caractère_guillemet" -#: sql_help.c:1648 +#: sql_help.c:1904 msgid "escape_character" msgstr "chaîne_d_échappement" -#: sql_help.c:1652 +#: sql_help.c:1908 msgid "encoding_name" msgstr "nom_encodage" -#: sql_help.c:1663 +#: sql_help.c:1919 msgid "access_method_type" msgstr "access_method_type" -#: sql_help.c:1729 sql_help.c:1748 sql_help.c:1751 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "type_données_arg" -#: sql_help.c:1730 sql_help.c:1752 sql_help.c:1760 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "sfunc" -#: sql_help.c:1731 sql_help.c:1753 sql_help.c:1761 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "type_de_données_statut" -#: sql_help.c:1732 sql_help.c:1754 sql_help.c:1762 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "taille_de_données_statut" -#: sql_help.c:1733 sql_help.c:1755 sql_help.c:1763 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "ffunc" -#: sql_help.c:1734 sql_help.c:1764 +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "combinefunc" -#: sql_help.c:1735 sql_help.c:1765 +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "serialfunc" -#: sql_help.c:1736 sql_help.c:1766 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "deserialfunc" -#: sql_help.c:1737 sql_help.c:1756 sql_help.c:1767 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "condition_initiale" -#: sql_help.c:1738 sql_help.c:1768 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "msfunc" -#: sql_help.c:1739 sql_help.c:1769 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "minvfunc" -#: sql_help.c:1740 sql_help.c:1770 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "m_type_de_données_statut" -#: sql_help.c:1741 sql_help.c:1771 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "m_taille_de_données_statut" -#: sql_help.c:1742 sql_help.c:1772 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "mffunc" -#: sql_help.c:1743 sql_help.c:1773 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "m_condition_initiale" -#: sql_help.c:1744 sql_help.c:1774 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "opérateur_de_tri" -#: sql_help.c:1757 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "ou l'ancienne syntaxe" -#: sql_help.c:1759 +#: sql_help.c:2020 msgid "base_type" msgstr "type_base" -#: sql_help.c:1815 +#: sql_help.c:2076 msgid "locale" msgstr "locale" -#: sql_help.c:1816 sql_help.c:1854 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1817 sql_help.c:1855 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1818 sql_help.c:3802 +#: sql_help.c:2079 sql_help.c:4122 msgid "provider" msgstr "fournisseur" -#: sql_help.c:1819 sql_help.c:1910 +#: sql_help.c:2080 sql_help.c:2171 msgid "version" msgstr "version" -#: sql_help.c:1821 +#: sql_help.c:2082 msgid "existing_collation" msgstr "collationnement_existant" -#: sql_help.c:1831 +#: sql_help.c:2092 msgid "source_encoding" msgstr "encodage_source" -#: sql_help.c:1832 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "encodage_destination" -#: sql_help.c:1852 sql_help.c:2587 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "modèle" -#: sql_help.c:1853 +#: sql_help.c:2114 msgid "encoding" msgstr "encodage" -#: sql_help.c:1879 +#: sql_help.c:2140 msgid "constraint" msgstr "contrainte" -#: sql_help.c:1880 +#: sql_help.c:2141 msgid "where constraint is:" msgstr "où la contrainte est :" -#: sql_help.c:1894 sql_help.c:2262 sql_help.c:2660 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "événement" -#: sql_help.c:1895 +#: sql_help.c:2156 msgid "filter_variable" msgstr "filter_variable" -#: sql_help.c:1911 +#: sql_help.c:2172 msgid "old_version" msgstr "ancienne_version" -#: sql_help.c:1984 sql_help.c:2485 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" msgstr "où contrainte_colonne est :" -#: sql_help.c:1987 sql_help.c:2019 sql_help.c:2488 -msgid "default_expr" -msgstr "expression_par_défaut" - -#: sql_help.c:1988 sql_help.c:2496 -msgid "and table_constraint is:" -msgstr "et contrainte_table est :" - -#: sql_help.c:2020 +#: sql_help.c:2280 msgid "rettype" msgstr "type_en_retour" -#: sql_help.c:2022 +#: sql_help.c:2282 msgid "column_type" msgstr "type_colonne" -#: sql_help.c:2030 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "définition" -#: sql_help.c:2031 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "fichier_objet" -#: sql_help.c:2032 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "symbole_link" -#: sql_help.c:2033 -msgid "attribute" -msgstr "attribut" - -#: sql_help.c:2067 sql_help.c:2247 sql_help.c:2779 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" msgstr "uid" -#: sql_help.c:2081 +#: sql_help.c:2341 msgid "method" msgstr "méthode" -#: sql_help.c:2085 sql_help.c:2456 sql_help.c:2468 sql_help.c:2481 -#: sql_help.c:2528 sql_help.c:3463 -msgid "opclass" -msgstr "classe_d_opérateur" - -#: sql_help.c:2089 sql_help.c:2507 -msgid "predicate" -msgstr "prédicat" - -#: sql_help.c:2101 +#: sql_help.c:2362 msgid "call_handler" msgstr "gestionnaire_d_appel" -#: sql_help.c:2102 +#: sql_help.c:2363 msgid "inline_handler" msgstr "gestionnaire_en_ligne" -#: sql_help.c:2103 +#: sql_help.c:2364 msgid "valfunction" msgstr "fonction_val" -#: sql_help.c:2139 +#: sql_help.c:2400 msgid "com_op" msgstr "com_op" -#: sql_help.c:2140 +#: sql_help.c:2401 msgid "neg_op" msgstr "neg_op" -#: sql_help.c:2158 +#: sql_help.c:2419 msgid "family_name" msgstr "nom_famille" -#: sql_help.c:2169 +#: sql_help.c:2430 msgid "storage_type" msgstr "type_stockage" -#: sql_help.c:2264 sql_help.c:2664 sql_help.c:2841 sql_help.c:3473 -#: sql_help.c:3892 sql_help.c:3894 sql_help.c:3982 sql_help.c:3984 -#: sql_help.c:4131 sql_help.c:4133 sql_help.c:4236 sql_help.c:4325 -#: sql_help.c:4327 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "condition" -#: sql_help.c:2268 sql_help.c:2667 +#: sql_help.c:2557 sql_help.c:2961 msgid "where event can be one of:" msgstr "où événement fait partie de :" -#: sql_help.c:2287 sql_help.c:2289 +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "élément_schéma" -#: sql_help.c:2326 +#: sql_help.c:2615 msgid "server_type" msgstr "type_serveur" -#: sql_help.c:2327 +#: sql_help.c:2616 msgid "server_version" msgstr "version_serveur" -#: sql_help.c:2328 sql_help.c:3382 sql_help.c:3715 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" msgstr "nom_fdw" -#: sql_help.c:2341 +#: sql_help.c:2630 msgid "statistics_name" msgstr "nom_statistique" -#: sql_help.c:2342 -msgid "statistic_type" -msgstr "type_statistique" +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "statistics_kind" -#: sql_help.c:2356 +#: sql_help.c:2645 msgid "subscription_name" msgstr "nom_souscription" -#: sql_help.c:2450 +#: sql_help.c:2741 msgid "source_table" msgstr "table_source" -#: sql_help.c:2451 +#: sql_help.c:2742 msgid "like_option" msgstr "option_like" -#: sql_help.c:2490 sql_help.c:2491 sql_help.c:2500 sql_help.c:2502 -#: sql_help.c:2506 -msgid "index_parameters" -msgstr "paramètres_index" - -#: sql_help.c:2492 sql_help.c:2509 -msgid "reftable" -msgstr "table_référence" - -#: sql_help.c:2493 sql_help.c:2510 -msgid "refcolumn" -msgstr "colonne_référence" - -#: sql_help.c:2504 -msgid "exclude_element" -msgstr "élément_exclusion" - -#: sql_help.c:2505 sql_help.c:3899 sql_help.c:3989 sql_help.c:4138 -#: sql_help.c:4267 sql_help.c:4332 -msgid "operator" -msgstr "opérateur" - -#: sql_help.c:2513 +#: sql_help.c:2804 msgid "and like_option is:" msgstr "et option_like est :" -#: sql_help.c:2514 -msgid "and partition_bound_spec is:" -msgstr "et partition_bound_spec est :" - -#: sql_help.c:2515 sql_help.c:2517 sql_help.c:2519 -msgid "numeric_literal" -msgstr "numeric_literal" - -#: sql_help.c:2516 sql_help.c:2518 sql_help.c:2520 -msgid "string_literal" -msgstr "littéral_chaîne" - -#: sql_help.c:2521 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "dans les contraintes UNIQUE, PRIMARY KEY et EXCLUDE, les paramètres_index sont :" - -#: sql_help.c:2525 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "élément_exclusion dans une contrainte EXCLUDE est :" - -#: sql_help.c:2560 +#: sql_help.c:2854 msgid "directory" msgstr "répertoire" -#: sql_help.c:2574 +#: sql_help.c:2868 msgid "parser_name" msgstr "nom_analyseur" -#: sql_help.c:2575 +#: sql_help.c:2869 msgid "source_config" msgstr "configuration_source" -#: sql_help.c:2604 +#: sql_help.c:2898 msgid "start_function" msgstr "fonction_start" -#: sql_help.c:2605 +#: sql_help.c:2899 msgid "gettoken_function" msgstr "fonction_gettoken" -#: sql_help.c:2606 +#: sql_help.c:2900 msgid "end_function" msgstr "fonction_end" -#: sql_help.c:2607 +#: sql_help.c:2901 msgid "lextypes_function" msgstr "fonction_lextypes" -#: sql_help.c:2608 +#: sql_help.c:2902 msgid "headline_function" msgstr "fonction_headline" -#: sql_help.c:2620 +#: sql_help.c:2914 msgid "init_function" msgstr "fonction_init" -#: sql_help.c:2621 +#: sql_help.c:2915 msgid "lexize_function" msgstr "fonction_lexize" -#: sql_help.c:2634 +#: sql_help.c:2928 msgid "from_sql_function_name" msgstr "nom_fonction_from_sql" -#: sql_help.c:2636 +#: sql_help.c:2930 msgid "to_sql_function_name" msgstr "nom_fonction_to_sql" -#: sql_help.c:2662 +#: sql_help.c:2956 msgid "referenced_table_name" msgstr "nom_table_référencée" -#: sql_help.c:2663 +#: sql_help.c:2957 msgid "transition_relation_name" msgstr "nom_relation_transition" -#: sql_help.c:2666 +#: sql_help.c:2960 msgid "arguments" msgstr "arguments" -#: sql_help.c:2716 sql_help.c:3827 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "label" -#: sql_help.c:2718 +#: sql_help.c:3012 msgid "subtype" msgstr "sous_type" -#: sql_help.c:2719 +#: sql_help.c:3013 msgid "subtype_operator_class" msgstr "classe_opérateur_sous_type" -#: sql_help.c:2721 +#: sql_help.c:3015 msgid "canonical_function" msgstr "fonction_canonique" -#: sql_help.c:2722 +#: sql_help.c:3016 msgid "subtype_diff_function" msgstr "fonction_diff_sous_type" -#: sql_help.c:2724 +#: sql_help.c:3018 msgid "input_function" msgstr "fonction_en_sortie" -#: sql_help.c:2725 +#: sql_help.c:3019 msgid "output_function" msgstr "fonction_en_sortie" -#: sql_help.c:2726 +#: sql_help.c:3020 msgid "receive_function" msgstr "fonction_receive" -#: sql_help.c:2727 +#: sql_help.c:3021 msgid "send_function" msgstr "fonction_send" -#: sql_help.c:2728 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "fonction_en_entrée_modificateur_type" -#: sql_help.c:2729 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "fonction_en_sortie_modificateur_type" -#: sql_help.c:2730 +#: sql_help.c:3024 msgid "analyze_function" msgstr "fonction_analyze" -#: sql_help.c:2731 +#: sql_help.c:3025 msgid "internallength" msgstr "longueur_interne" -#: sql_help.c:2732 +#: sql_help.c:3026 msgid "alignment" msgstr "alignement" -#: sql_help.c:2733 +#: sql_help.c:3027 msgid "storage" msgstr "stockage" -#: sql_help.c:2734 +#: sql_help.c:3028 msgid "like_type" msgstr "type_like" -#: sql_help.c:2735 +#: sql_help.c:3029 msgid "category" msgstr "catégorie" -#: sql_help.c:2736 +#: sql_help.c:3030 msgid "preferred" msgstr "préféré" -#: sql_help.c:2737 +#: sql_help.c:3031 msgid "default" msgstr "par défaut" -#: sql_help.c:2738 +#: sql_help.c:3032 msgid "element" msgstr "élément" -#: sql_help.c:2739 +#: sql_help.c:3033 msgid "delimiter" msgstr "délimiteur" -#: sql_help.c:2740 +#: sql_help.c:3034 msgid "collatable" msgstr "collationnable" -#: sql_help.c:2837 sql_help.c:3449 sql_help.c:3887 sql_help.c:3976 -#: sql_help.c:4126 sql_help.c:4226 sql_help.c:4320 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "requête_with" -#: sql_help.c:2839 sql_help.c:3451 sql_help.c:3906 sql_help.c:3912 -#: sql_help.c:3915 sql_help.c:3919 sql_help.c:3923 sql_help.c:3931 -#: sql_help.c:4145 sql_help.c:4151 sql_help.c:4154 sql_help.c:4158 -#: sql_help.c:4162 sql_help.c:4170 sql_help.c:4228 sql_help.c:4339 -#: sql_help.c:4345 sql_help.c:4348 sql_help.c:4352 sql_help.c:4356 -#: sql_help.c:4364 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" msgstr "alias" -#: sql_help.c:2840 +#: sql_help.c:3134 msgid "using_list" msgstr "liste_using" -#: sql_help.c:2842 sql_help.c:3289 sql_help.c:3530 sql_help.c:4237 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "nom_curseur" -#: sql_help.c:2843 sql_help.c:3457 sql_help.c:4238 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "expression_en_sortie" -#: sql_help.c:2844 sql_help.c:3458 sql_help.c:3890 sql_help.c:3979 -#: sql_help.c:4129 sql_help.c:4239 sql_help.c:4323 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "nom_en_sortie" -#: sql_help.c:2860 +#: sql_help.c:3154 msgid "code" msgstr "code" -#: sql_help.c:3235 +#: sql_help.c:3553 msgid "parameter" msgstr "paramètre" -#: sql_help.c:3255 sql_help.c:3256 sql_help.c:3555 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "instruction" -#: sql_help.c:3288 sql_help.c:3529 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" msgstr "direction" -#: sql_help.c:3290 sql_help.c:3531 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" msgstr "où direction peut être vide ou faire partie de :" -#: sql_help.c:3291 sql_help.c:3292 sql_help.c:3293 sql_help.c:3294 -#: sql_help.c:3295 sql_help.c:3532 sql_help.c:3533 sql_help.c:3534 -#: sql_help.c:3535 sql_help.c:3536 sql_help.c:3900 sql_help.c:3902 -#: sql_help.c:3990 sql_help.c:3992 sql_help.c:4139 sql_help.c:4141 -#: sql_help.c:4268 sql_help.c:4270 sql_help.c:4333 sql_help.c:4335 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" msgstr "nombre" -#: sql_help.c:3375 sql_help.c:3708 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "nom_séquence" -#: sql_help.c:3388 sql_help.c:3721 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "nom_argument" -#: sql_help.c:3389 sql_help.c:3722 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "type_arg" -#: sql_help.c:3394 sql_help.c:3727 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "loid" -#: sql_help.c:3417 +#: sql_help.c:3735 msgid "remote_schema" msgstr "schema_distant" -#: sql_help.c:3420 +#: sql_help.c:3738 msgid "local_schema" msgstr "schéma_local" -#: sql_help.c:3455 +#: sql_help.c:3773 msgid "conflict_target" msgstr "cible_conflit" -#: sql_help.c:3456 +#: sql_help.c:3774 msgid "conflict_action" msgstr "action_conflit" -#: sql_help.c:3459 +#: sql_help.c:3777 msgid "where conflict_target can be one of:" msgstr "où cible_conflit fait partie de :" -#: sql_help.c:3460 +#: sql_help.c:3778 msgid "index_column_name" msgstr "index_nom_colonne" -#: sql_help.c:3461 +#: sql_help.c:3779 msgid "index_expression" msgstr "index_expression" -#: sql_help.c:3464 +#: sql_help.c:3782 msgid "index_predicate" msgstr "index_prédicat" -#: sql_help.c:3466 +#: sql_help.c:3784 msgid "and conflict_action is one of:" msgstr "où action_conflit fait partie de :" -#: sql_help.c:3472 sql_help.c:4234 +#: sql_help.c:3790 sql_help.c:4562 msgid "sub-SELECT" msgstr "sous-SELECT" -#: sql_help.c:3481 sql_help.c:3544 sql_help.c:4210 +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "canal" -#: sql_help.c:3503 +#: sql_help.c:3821 msgid "lockmode" msgstr "mode_de_verrou" -#: sql_help.c:3504 +#: sql_help.c:3822 msgid "where lockmode is one of:" msgstr "où mode_de_verrou fait partie de :" -#: sql_help.c:3545 +#: sql_help.c:3863 msgid "payload" msgstr "contenu" -#: sql_help.c:3572 +#: sql_help.c:3890 msgid "old_role" msgstr "ancien_rôle" -#: sql_help.c:3573 +#: sql_help.c:3891 msgid "new_role" msgstr "nouveau_rôle" -#: sql_help.c:3598 sql_help.c:3759 sql_help.c:3767 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "nom_savepoint" -#: sql_help.c:3891 sql_help.c:3933 sql_help.c:3935 sql_help.c:3981 -#: sql_help.c:4130 sql_help.c:4172 sql_help.c:4174 sql_help.c:4324 -#: sql_help.c:4366 sql_help.c:4368 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" msgstr "élément_from" -#: sql_help.c:3893 sql_help.c:3945 sql_help.c:4132 sql_help.c:4184 -#: sql_help.c:4326 sql_help.c:4378 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 msgid "grouping_element" msgstr "element_regroupement" -#: sql_help.c:3895 sql_help.c:3985 sql_help.c:4134 sql_help.c:4328 +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "nom_window" -#: sql_help.c:3896 sql_help.c:3986 sql_help.c:4135 sql_help.c:4329 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "définition_window" -#: sql_help.c:3897 sql_help.c:3911 sql_help.c:3949 sql_help.c:3987 -#: sql_help.c:4136 sql_help.c:4150 sql_help.c:4188 sql_help.c:4330 -#: sql_help.c:4344 sql_help.c:4382 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "sélection" -#: sql_help.c:3904 sql_help.c:4143 sql_help.c:4337 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" msgstr "où élément_from fait partie de :" -#: sql_help.c:3907 sql_help.c:3913 sql_help.c:3916 sql_help.c:3920 -#: sql_help.c:3932 sql_help.c:4146 sql_help.c:4152 sql_help.c:4155 -#: sql_help.c:4159 sql_help.c:4171 sql_help.c:4340 sql_help.c:4346 -#: sql_help.c:4349 sql_help.c:4353 sql_help.c:4365 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" msgstr "alias_colonne" -#: sql_help.c:3908 sql_help.c:4147 sql_help.c:4341 +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 msgid "sampling_method" msgstr "méthode_echantillonnage" -#: sql_help.c:3909 sql_help.c:3918 sql_help.c:3922 sql_help.c:3926 -#: sql_help.c:3929 sql_help.c:4148 sql_help.c:4157 sql_help.c:4161 -#: sql_help.c:4165 sql_help.c:4168 sql_help.c:4342 sql_help.c:4351 -#: sql_help.c:4355 sql_help.c:4359 sql_help.c:4362 -msgid "argument" -msgstr "argument" - -#: sql_help.c:3910 sql_help.c:4149 sql_help.c:4343 +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 msgid "seed" msgstr "graine" -#: sql_help.c:3914 sql_help.c:3947 sql_help.c:4153 sql_help.c:4186 -#: sql_help.c:4347 sql_help.c:4380 +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "nom_requête_with" -#: sql_help.c:3924 sql_help.c:3927 sql_help.c:3930 sql_help.c:4163 -#: sql_help.c:4166 sql_help.c:4169 sql_help.c:4357 sql_help.c:4360 -#: sql_help.c:4363 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" msgstr "définition_colonne" -#: sql_help.c:3934 sql_help.c:4173 sql_help.c:4367 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" msgstr "type_de_jointure" -#: sql_help.c:3936 sql_help.c:4175 sql_help.c:4369 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" msgstr "condition_de_jointure" -#: sql_help.c:3937 sql_help.c:4176 sql_help.c:4370 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" msgstr "colonne_de_jointure" -#: sql_help.c:3938 sql_help.c:4177 sql_help.c:4371 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 msgid "and grouping_element can be one of:" msgstr "où element_regroupement fait partie de :" -#: sql_help.c:3946 sql_help.c:4185 sql_help.c:4379 +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" msgstr "et requête_with est :" -#: sql_help.c:3950 sql_help.c:4189 sql_help.c:4383 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "valeurs" -#: sql_help.c:3951 sql_help.c:4190 sql_help.c:4384 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" msgstr "insert" -#: sql_help.c:3952 sql_help.c:4191 sql_help.c:4385 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "update" -#: sql_help.c:3953 sql_help.c:4192 sql_help.c:4386 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "delete" -#: sql_help.c:3980 +#: sql_help.c:4308 msgid "new_table" msgstr "nouvelle_table" -#: sql_help.c:4005 +#: sql_help.c:4333 msgid "timezone" msgstr "fuseau_horaire" -#: sql_help.c:4050 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "id_snapshot" -#: sql_help.c:4235 +#: sql_help.c:4563 msgid "from_list" msgstr "liste_from" -#: sql_help.c:4266 +#: sql_help.c:4607 msgid "sort_expression" msgstr "expression_de_tri" -#: sql_help.c:4393 sql_help.c:5178 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" msgstr "abandonner la transaction en cours" -#: sql_help.c:4398 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" msgstr "modifier la définition d'une fonction d'agrégation" -#: sql_help.c:4403 +#: sql_help.c:4744 msgid "change the definition of a collation" msgstr "modifier la définition d'un collationnement" -#: sql_help.c:4408 +#: sql_help.c:4749 msgid "change the definition of a conversion" msgstr "modifier la définition d'une conversion" -#: sql_help.c:4413 +#: sql_help.c:4754 msgid "change a database" msgstr "modifier une base de données" -#: sql_help.c:4418 +#: sql_help.c:4759 msgid "define default access privileges" msgstr "définir les droits d'accès par défaut" -#: sql_help.c:4423 +#: sql_help.c:4764 msgid "change the definition of a domain" msgstr "modifier la définition d'un domaine" -#: sql_help.c:4428 +#: sql_help.c:4769 msgid "change the definition of an event trigger" msgstr "modifier la définition d'un trigger sur évènement" -#: sql_help.c:4433 +#: sql_help.c:4774 msgid "change the definition of an extension" msgstr "modifier la définition d'une extension" -#: sql_help.c:4438 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" msgstr "modifier la définition d'un wrapper de données distantes" -#: sql_help.c:4443 +#: sql_help.c:4784 msgid "change the definition of a foreign table" msgstr "modifier la définition d'une table distante" -#: sql_help.c:4448 +#: sql_help.c:4789 msgid "change the definition of a function" msgstr "modifier la définition d'une fonction" -#: sql_help.c:4453 +#: sql_help.c:4794 msgid "change role name or membership" msgstr "modifier le nom d'un groupe ou la liste des ses membres" -#: sql_help.c:4458 +#: sql_help.c:4799 msgid "change the definition of an index" msgstr "modifier la définition d'un index" -#: sql_help.c:4463 +#: sql_help.c:4804 msgid "change the definition of a procedural language" msgstr "modifier la définition d'un langage procédural" -#: sql_help.c:4468 +#: sql_help.c:4809 msgid "change the definition of a large object" msgstr "modifier la définition d'un « Large Object »" -#: sql_help.c:4473 +#: sql_help.c:4814 msgid "change the definition of a materialized view" msgstr "modifier la définition d'une vue matérialisée" -#: sql_help.c:4478 +#: sql_help.c:4819 msgid "change the definition of an operator" msgstr "modifier la définition d'un opérateur" -#: sql_help.c:4483 +#: sql_help.c:4824 msgid "change the definition of an operator class" msgstr "modifier la définition d'une classe d'opérateurs" -#: sql_help.c:4488 +#: sql_help.c:4829 msgid "change the definition of an operator family" msgstr "modifier la définition d'une famille d'opérateur" -#: sql_help.c:4493 +#: sql_help.c:4834 msgid "change the definition of a row level security policy" msgstr "modifier la définition d'une politique de sécurité au niveau ligne" -#: sql_help.c:4498 +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "modifier la définition d'une procédure" + +#: sql_help.c:4844 msgid "change the definition of a publication" msgstr "modifier la définition d'une publication" -#: sql_help.c:4503 sql_help.c:4583 +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" msgstr "modifier un rôle" -#: sql_help.c:4508 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "modifier la définition d'une routine" + +#: sql_help.c:4859 msgid "change the definition of a rule" msgstr "modifier la définition d'une règle" -#: sql_help.c:4513 +#: sql_help.c:4864 msgid "change the definition of a schema" msgstr "modifier la définition d'un schéma" -#: sql_help.c:4518 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" msgstr "modifier la définition d'un générateur de séquence" -#: sql_help.c:4523 +#: sql_help.c:4874 msgid "change the definition of a foreign server" msgstr "modifier la définition d'un serveur distant" -#: sql_help.c:4528 +#: sql_help.c:4879 msgid "change the definition of an extended statistics object" msgstr "modifier la définition d'un objet de statistiques étendues" -#: sql_help.c:4533 +#: sql_help.c:4884 msgid "change the definition of a subscription" msgstr "modifier la définition d'une souscription" -#: sql_help.c:4538 +#: sql_help.c:4889 msgid "change a server configuration parameter" msgstr "modifie un paramètre de configuration du serveur" -#: sql_help.c:4543 +#: sql_help.c:4894 msgid "change the definition of a table" msgstr "modifier la définition d'une table" -#: sql_help.c:4548 +#: sql_help.c:4899 msgid "change the definition of a tablespace" msgstr "modifier la définition d'un tablespace" -#: sql_help.c:4553 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" msgstr "modifier la définition d'une configuration de la recherche de texte" -#: sql_help.c:4558 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" msgstr "modifier la définition d'un dictionnaire de la recherche de texte" -#: sql_help.c:4563 +#: sql_help.c:4914 msgid "change the definition of a text search parser" msgstr "modifier la définition d'un analyseur de la recherche de texte" -#: sql_help.c:4568 +#: sql_help.c:4919 msgid "change the definition of a text search template" msgstr "modifier la définition d'un modèle de la recherche de texte" -#: sql_help.c:4573 +#: sql_help.c:4924 msgid "change the definition of a trigger" msgstr "modifier la définition d'un trigger" -#: sql_help.c:4578 +#: sql_help.c:4929 msgid "change the definition of a type" msgstr "modifier la définition d'un type" -#: sql_help.c:4588 +#: sql_help.c:4939 msgid "change the definition of a user mapping" msgstr "modifier la définition d'une correspondance d'utilisateur" -#: sql_help.c:4593 +#: sql_help.c:4944 msgid "change the definition of a view" msgstr "modifier la définition d'une vue" -#: sql_help.c:4598 +#: sql_help.c:4949 msgid "collect statistics about a database" msgstr "acquérir des statistiques concernant la base de données" -#: sql_help.c:4603 sql_help.c:5243 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" msgstr "débuter un bloc de transaction" -#: sql_help.c:4608 +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "appeler une procédure" + +#: sql_help.c:4964 msgid "force a write-ahead log checkpoint" msgstr "forcer un point de vérification des journaux de transactions" -#: sql_help.c:4613 +#: sql_help.c:4969 msgid "close a cursor" msgstr "fermer un curseur" -#: sql_help.c:4618 +#: sql_help.c:4974 msgid "cluster a table according to an index" msgstr "réorganiser (cluster) une table en fonction d'un index" -#: sql_help.c:4623 +#: sql_help.c:4979 msgid "define or change the comment of an object" msgstr "définir ou modifier les commentaires d'un objet" -#: sql_help.c:4628 sql_help.c:5078 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" msgstr "valider la transaction en cours" -#: sql_help.c:4633 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "" "valider une transaction précédemment préparée pour une validation en deux\n" "phases" -#: sql_help.c:4638 +#: sql_help.c:4994 msgid "copy data between a file and a table" msgstr "copier des données entre un fichier et une table" -#: sql_help.c:4643 +#: sql_help.c:4999 msgid "define a new access method" msgstr "définir une nouvelle méthode d'accès" -#: sql_help.c:4648 +#: sql_help.c:5004 msgid "define a new aggregate function" msgstr "définir une nouvelle fonction d'agrégation" -#: sql_help.c:4653 +#: sql_help.c:5009 msgid "define a new cast" msgstr "définir un nouveau transtypage" -#: sql_help.c:4658 +#: sql_help.c:5014 msgid "define a new collation" msgstr "définir un nouveau collationnement" -#: sql_help.c:4663 +#: sql_help.c:5019 msgid "define a new encoding conversion" msgstr "définir une nouvelle conversion d'encodage" -#: sql_help.c:4668 +#: sql_help.c:5024 msgid "create a new database" msgstr "créer une nouvelle base de données" -#: sql_help.c:4673 +#: sql_help.c:5029 msgid "define a new domain" msgstr "définir un nouveau domaine" -#: sql_help.c:4678 +#: sql_help.c:5034 msgid "define a new event trigger" msgstr "définir un nouveau trigger sur évènement" -#: sql_help.c:4683 +#: sql_help.c:5039 msgid "install an extension" msgstr "installer une extension" -#: sql_help.c:4688 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" msgstr "définir un nouveau wrapper de données distantes" -#: sql_help.c:4693 +#: sql_help.c:5049 msgid "define a new foreign table" msgstr "définir une nouvelle table distante" -#: sql_help.c:4698 +#: sql_help.c:5054 msgid "define a new function" msgstr "définir une nouvelle fonction" -#: sql_help.c:4703 sql_help.c:4748 sql_help.c:4833 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" msgstr "définir un nouveau rôle" -#: sql_help.c:4708 +#: sql_help.c:5064 msgid "define a new index" msgstr "définir un nouvel index" -#: sql_help.c:4713 +#: sql_help.c:5069 msgid "define a new procedural language" msgstr "définir un nouveau langage de procédures" -#: sql_help.c:4718 +#: sql_help.c:5074 msgid "define a new materialized view" msgstr "définir une nouvelle vue matérialisée" -#: sql_help.c:4723 +#: sql_help.c:5079 msgid "define a new operator" msgstr "définir un nouvel opérateur" -#: sql_help.c:4728 +#: sql_help.c:5084 msgid "define a new operator class" msgstr "définir une nouvelle classe d'opérateur" -#: sql_help.c:4733 +#: sql_help.c:5089 msgid "define a new operator family" msgstr "définir une nouvelle famille d'opérateur" -#: sql_help.c:4738 +#: sql_help.c:5094 msgid "define a new row level security policy for a table" msgstr "définir une nouvelle politique de sécurité au niveau ligne pour une table" -#: sql_help.c:4743 +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "définir une nouvelle procédure" + +#: sql_help.c:5104 msgid "define a new publication" msgstr "définir une nouvelle publication" -#: sql_help.c:4753 +#: sql_help.c:5114 msgid "define a new rewrite rule" msgstr "définir une nouvelle règle de réécriture" -#: sql_help.c:4758 +#: sql_help.c:5119 msgid "define a new schema" msgstr "définir un nouveau schéma" -#: sql_help.c:4763 +#: sql_help.c:5124 msgid "define a new sequence generator" msgstr "définir un nouveau générateur de séquence" -#: sql_help.c:4768 +#: sql_help.c:5129 msgid "define a new foreign server" msgstr "définir un nouveau serveur distant" -#: sql_help.c:4773 +#: sql_help.c:5134 msgid "define extended statistics" msgstr "définir des statistiques étendues" -#: sql_help.c:4778 +#: sql_help.c:5139 msgid "define a new subscription" msgstr "définir une nouvelle souscription" -#: sql_help.c:4783 +#: sql_help.c:5144 msgid "define a new table" msgstr "définir une nouvelle table" -#: sql_help.c:4788 sql_help.c:5208 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" msgstr "définir une nouvelle table à partir des résultats d'une requête" -#: sql_help.c:4793 +#: sql_help.c:5154 msgid "define a new tablespace" msgstr "définir un nouveau tablespace" -#: sql_help.c:4798 +#: sql_help.c:5159 msgid "define a new text search configuration" msgstr "définir une nouvelle configuration de la recherche de texte" -#: sql_help.c:4803 +#: sql_help.c:5164 msgid "define a new text search dictionary" msgstr "définir un nouveau dictionnaire de la recherche de texte" -#: sql_help.c:4808 +#: sql_help.c:5169 msgid "define a new text search parser" msgstr "définir un nouvel analyseur de la recherche de texte" -#: sql_help.c:4813 +#: sql_help.c:5174 msgid "define a new text search template" msgstr "définir un nouveau modèle de la recherche de texte" -#: sql_help.c:4818 +#: sql_help.c:5179 msgid "define a new transform" msgstr "définir une nouvelle transformation" -#: sql_help.c:4823 +#: sql_help.c:5184 msgid "define a new trigger" msgstr "définir un nouveau trigger" -#: sql_help.c:4828 +#: sql_help.c:5189 msgid "define a new data type" msgstr "définir un nouveau type de données" -#: sql_help.c:4838 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" msgstr "définit une nouvelle correspondance d'un utilisateur vers un serveur distant" -#: sql_help.c:4843 +#: sql_help.c:5204 msgid "define a new view" msgstr "définir une nouvelle vue" -#: sql_help.c:4848 +#: sql_help.c:5209 msgid "deallocate a prepared statement" msgstr "désallouer une instruction préparée" -#: sql_help.c:4853 +#: sql_help.c:5214 msgid "define a cursor" msgstr "définir un curseur" -#: sql_help.c:4858 +#: sql_help.c:5219 msgid "delete rows of a table" msgstr "supprimer des lignes d'une table" -#: sql_help.c:4863 +#: sql_help.c:5224 msgid "discard session state" msgstr "annuler l'état de la session" -#: sql_help.c:4868 +#: sql_help.c:5229 msgid "execute an anonymous code block" msgstr "exécute un bloc de code anonyme" -#: sql_help.c:4873 +#: sql_help.c:5234 msgid "remove an access method" msgstr "supprimer une méthode d'accès" -#: sql_help.c:4878 +#: sql_help.c:5239 msgid "remove an aggregate function" msgstr "supprimer une fonction d'agrégation" -#: sql_help.c:4883 +#: sql_help.c:5244 msgid "remove a cast" msgstr "supprimer un transtypage" -#: sql_help.c:4888 +#: sql_help.c:5249 msgid "remove a collation" msgstr "supprimer un collationnement" -#: sql_help.c:4893 +#: sql_help.c:5254 msgid "remove a conversion" msgstr "supprimer une conversion" -#: sql_help.c:4898 +#: sql_help.c:5259 msgid "remove a database" msgstr "supprimer une base de données" -#: sql_help.c:4903 +#: sql_help.c:5264 msgid "remove a domain" msgstr "supprimer un domaine" -#: sql_help.c:4908 +#: sql_help.c:5269 msgid "remove an event trigger" msgstr "supprimer un trigger sur évènement" -#: sql_help.c:4913 +#: sql_help.c:5274 msgid "remove an extension" msgstr "supprimer une extension" -#: sql_help.c:4918 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" msgstr "supprimer un wrapper de données distantes" -#: sql_help.c:4923 +#: sql_help.c:5284 msgid "remove a foreign table" msgstr "supprimer une table distante" -#: sql_help.c:4928 +#: sql_help.c:5289 msgid "remove a function" msgstr "supprimer une fonction" -#: sql_help.c:4933 sql_help.c:4983 sql_help.c:5063 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" msgstr "supprimer un rôle de la base de données" -#: sql_help.c:4938 +#: sql_help.c:5299 msgid "remove an index" msgstr "supprimer un index" -#: sql_help.c:4943 +#: sql_help.c:5304 msgid "remove a procedural language" msgstr "supprimer un langage procédural" -#: sql_help.c:4948 +#: sql_help.c:5309 msgid "remove a materialized view" msgstr "supprimer une vue matérialisée" -#: sql_help.c:4953 +#: sql_help.c:5314 msgid "remove an operator" msgstr "supprimer un opérateur" -#: sql_help.c:4958 +#: sql_help.c:5319 msgid "remove an operator class" msgstr "supprimer une classe d'opérateur" -#: sql_help.c:4963 +#: sql_help.c:5324 msgid "remove an operator family" msgstr "supprimer une famille d'opérateur" -#: sql_help.c:4968 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" msgstr "supprimer les objets appartenant à un rôle" -#: sql_help.c:4973 +#: sql_help.c:5334 msgid "remove a row level security policy from a table" msgstr "supprimer une nouvelle politique de sécurité au niveau ligne pour une table" -#: sql_help.c:4978 +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "supprimer une procédure" + +#: sql_help.c:5344 msgid "remove a publication" msgstr "supprimer une publication" -#: sql_help.c:4988 +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "supprimer une routine" + +#: sql_help.c:5359 msgid "remove a rewrite rule" msgstr "supprimer une règle de réécriture" -#: sql_help.c:4993 +#: sql_help.c:5364 msgid "remove a schema" msgstr "supprimer un schéma" -#: sql_help.c:4998 +#: sql_help.c:5369 msgid "remove a sequence" msgstr "supprimer une séquence" -#: sql_help.c:5003 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" msgstr "supprimer un descripteur de serveur distant" -#: sql_help.c:5008 +#: sql_help.c:5379 msgid "remove extended statistics" msgstr "supprimer des statistiques étendues" -#: sql_help.c:5013 +#: sql_help.c:5384 msgid "remove a subscription" msgstr "supprimer une souscription" -#: sql_help.c:5018 +#: sql_help.c:5389 msgid "remove a table" msgstr "supprimer une table" -#: sql_help.c:5023 +#: sql_help.c:5394 msgid "remove a tablespace" msgstr "supprimer un tablespace" -#: sql_help.c:5028 +#: sql_help.c:5399 msgid "remove a text search configuration" msgstr "supprimer une configuration de la recherche de texte" -#: sql_help.c:5033 +#: sql_help.c:5404 msgid "remove a text search dictionary" msgstr "supprimer un dictionnaire de la recherche de texte" -#: sql_help.c:5038 +#: sql_help.c:5409 msgid "remove a text search parser" msgstr "supprimer un analyseur de la recherche de texte" -#: sql_help.c:5043 +#: sql_help.c:5414 msgid "remove a text search template" msgstr "supprimer un modèle de la recherche de texte" -#: sql_help.c:5048 +#: sql_help.c:5419 msgid "remove a transform" msgstr "supprimer une transformation" -#: sql_help.c:5053 +#: sql_help.c:5424 msgid "remove a trigger" msgstr "supprimer un trigger" -#: sql_help.c:5058 +#: sql_help.c:5429 msgid "remove a data type" msgstr "supprimer un type de données" -#: sql_help.c:5068 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" msgstr "supprime une correspondance utilisateur pour un serveur distant" -#: sql_help.c:5073 +#: sql_help.c:5444 msgid "remove a view" msgstr "supprimer une vue" -#: sql_help.c:5083 +#: sql_help.c:5454 msgid "execute a prepared statement" msgstr "exécuter une instruction préparée" -#: sql_help.c:5088 +#: sql_help.c:5459 msgid "show the execution plan of a statement" msgstr "afficher le plan d'exécution d'une instruction" -#: sql_help.c:5093 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" msgstr "extraire certaines lignes d'une requête à l'aide d'un curseur" -#: sql_help.c:5098 +#: sql_help.c:5469 msgid "define access privileges" msgstr "définir des privilèges d'accès" -#: sql_help.c:5103 +#: sql_help.c:5474 msgid "import table definitions from a foreign server" msgstr "importer la définition d'une table à partir d'un serveur distant" -#: sql_help.c:5108 +#: sql_help.c:5479 msgid "create new rows in a table" msgstr "créer de nouvelles lignes dans une table" -#: sql_help.c:5113 +#: sql_help.c:5484 msgid "listen for a notification" msgstr "se mettre à l'écoute d'une notification" -#: sql_help.c:5118 +#: sql_help.c:5489 msgid "load a shared library file" msgstr "charger un fichier de bibliothèque partagée" -#: sql_help.c:5123 +#: sql_help.c:5494 msgid "lock a table" msgstr "verrouiller une table" -#: sql_help.c:5128 +#: sql_help.c:5499 msgid "position a cursor" msgstr "positionner un curseur" -#: sql_help.c:5133 +#: sql_help.c:5504 msgid "generate a notification" msgstr "engendrer une notification" -#: sql_help.c:5138 +#: sql_help.c:5509 msgid "prepare a statement for execution" msgstr "préparer une instruction pour exécution" -#: sql_help.c:5143 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" msgstr "préparer la transaction en cours pour une validation en deux phases" -#: sql_help.c:5148 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" msgstr "changer le propriétaire des objets d'un rôle" -#: sql_help.c:5153 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" msgstr "remplacer le contenu d'une vue matérialisée" -#: sql_help.c:5158 +#: sql_help.c:5529 msgid "rebuild indexes" msgstr "reconstruire des index" -#: sql_help.c:5163 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" msgstr "détruire un point de retournement précédemment défini" -#: sql_help.c:5168 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" msgstr "réinitialiser un paramètre d'exécution à sa valeur par défaut" -#: sql_help.c:5173 +#: sql_help.c:5544 msgid "remove access privileges" msgstr "supprimer des privilèges d'accès" -#: sql_help.c:5183 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "" "annuler une transaction précédemment préparée pour une validation en deux\n" "phases" -#: sql_help.c:5188 +#: sql_help.c:5559 msgid "roll back to a savepoint" msgstr "annuler jusqu'au point de retournement" -#: sql_help.c:5193 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" msgstr "définir un nouveau point de retournement pour la transaction en cours" -#: sql_help.c:5198 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" msgstr "définir ou modifier un label de sécurité à un objet" -#: sql_help.c:5203 sql_help.c:5248 sql_help.c:5278 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" msgstr "extraire des lignes d'une table ou d'une vue" -#: sql_help.c:5213 +#: sql_help.c:5584 msgid "change a run-time parameter" msgstr "modifier un paramètre d'exécution" -#: sql_help.c:5218 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" msgstr "définir le moment de la vérification des contraintes pour la transaction en cours" -#: sql_help.c:5223 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" msgstr "définir l'identifiant actuel de l'utilisateur de la session courante" -#: sql_help.c:5228 +#: sql_help.c:5599 msgid "set the session user identifier and the current user identifier of the current session" msgstr "" "définir l'identifiant de l'utilisateur de session et l'identifiant actuel de\n" "l'utilisateur de la session courante" -#: sql_help.c:5233 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" msgstr "définir les caractéristiques de la transaction en cours" -#: sql_help.c:5238 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" msgstr "afficher la valeur d'un paramètre d'exécution" -#: sql_help.c:5253 +#: sql_help.c:5624 msgid "empty a table or set of tables" msgstr "vider une table ou un ensemble de tables" -#: sql_help.c:5258 +#: sql_help.c:5629 msgid "stop listening for a notification" msgstr "arrêter l'écoute d'une notification" -#: sql_help.c:5263 +#: sql_help.c:5634 msgid "update rows of a table" msgstr "actualiser les lignes d'une table" -#: sql_help.c:5268 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" msgstr "compacter et optionnellement analyser une base de données" -#: sql_help.c:5273 +#: sql_help.c:5644 msgid "compute a set of rows" msgstr "calculer un ensemble de lignes" -#: startup.c:184 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s p: -1 peut seulement être utilisé dans un mode non intéractif\n" -#: startup.c:287 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n" -#: startup.c:394 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5738,27 +6150,27 @@ msgstr "" "Saisissez « help » pour l'aide.\n" "\n" -#: startup.c:543 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s : n'a pas pu configurer le paramètre d'impression « %s »\n" -#: startup.c:645 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayez « %s --help » pour plus d'informations.\n" -#: startup.c:662 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" msgstr "%s : attention : option supplémentaire « %s » ignorée\n" -#: startup.c:711 +#: startup.c:729 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s : n'a pas pu trouver son propre exécutable\n" -#: tab-complete.c:4184 +#: tab-complete.c:4497 #, c-format msgid "" "tab completion query failed: %s\n" @@ -5771,8 +6183,8 @@ msgstr "" #: variables.c:139 #, c-format -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" -msgstr "valeur « %s » non reconnue pour « %s » ; booléen attendu\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "valeur « %s » non reconnue pour « %s » : booléen attendu\n" #: variables.c:176 #, c-format @@ -5793,6 +6205,12 @@ msgstr "" "valeur « %s » non reconnue pour « %s »\n" "Les valeurs disponibles sont : %s.\n" +#~ msgid "Value" +#~ msgstr "Valeur" + +#~ msgid "statistic_type" +#~ msgstr "type_statistique" + #~ msgid "serialtype" #~ msgstr "serialtype" @@ -5805,9 +6223,6 @@ msgstr "" #~ msgid "(No rows)\n" #~ msgstr "(Aucune ligne)\n" -#~ msgid "ALTER VIEW name RENAME TO newname" -#~ msgstr "ALTER VIEW nom RENAME TO nouveau_nom" - #~ msgid " \"%s\"" #~ msgstr " « %s »" @@ -5902,1950 +6317,6 @@ msgstr "" #~ msgid " \"%s\" IN %s %s" #~ msgstr " \"%s\" DANS %s %s" -#~ msgid "" -#~ "VALUES ( expression [, ...] ) [, ...]\n" -#~ " [ ORDER BY sort_expression [ ASC | DESC | USING operator ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]" -#~ msgstr "" -#~ "VALUES ( expression [, ...] ) [, ...]\n" -#~ " [ ORDER BY expression_tri [ ASC | DESC | USING opérateur ] [, ...] ]\n" -#~ " [ LIMIT { total | ALL } ]\n" -#~ " [ OFFSET début [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ total ] { ROW | ROWS } ONLY ]" - -#~ msgid "" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]\n" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]" -#~ msgstr "" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]\n" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (colonne [, ...] ) ] ]" - -#~ msgid "" -#~ "UPDATE [ ONLY ] table [ [ AS ] alias ]\n" -#~ " SET { column = { expression | DEFAULT } |\n" -#~ " ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]\n" -#~ " [ FROM fromlist ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "UPDATE [ ONLY ] table [ [ AS ] alias ]\n" -#~ " SET { colonne = { expression | DEFAULT } |\n" -#~ " ( colonne [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]\n" -#~ " [ FROM liste_from ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF nom_curseur ]\n" -#~ " [ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]" - -#~ msgid "UNLISTEN { name | * }" -#~ msgstr "UNLISTEN { nom | * }" - -#~ msgid "" -#~ "TRUNCATE [ TABLE ] [ ONLY ] name [, ... ]\n" -#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "TRUNCATE [ TABLE ] [ ONLY ] nom [, ... ]\n" -#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" - -#~ msgid "" -#~ "START TRANSACTION [ transaction_mode [, ...] ]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "START TRANSACTION [ mode_transaction [, ...] ]\n" -#~ "\n" -#~ "où mode_transaction peut être :\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ |\n" -#~ " READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "" -#~ "SHOW name\n" -#~ "SHOW ALL" -#~ msgstr "" -#~ "SHOW nom\n" -#~ "SHOW ALL" - -#~ msgid "" -#~ "SET TRANSACTION transaction_mode [, ...]\n" -#~ "SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "SET TRANSACTION mode_transaction [, ...]\n" -#~ "SET SESSION CHARACTERISTICS AS TRANSACTION mode_transaction [, ...]\n" -#~ "\n" -#~ "où mode_transaction peut être :\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ |\n" -#~ " READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION username\n" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" -#~ "RESET SESSION AUTHORIZATION" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION nom_utilisateur\n" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" -#~ "RESET SESSION AUTHORIZATION" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] ROLE rolename\n" -#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" -#~ "RESET ROLE" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] ROLE nom_rôle\n" -#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" -#~ "RESET ROLE" - -#~ msgid "SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }" -#~ msgstr "SET CONSTRAINTS { ALL | nom [, ...] } { DEFERRED | IMMEDIATE }" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }\n" -#~ "SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] paramètre { TO | = } { valeur | 'valeur' | DEFAULT }\n" -#~ "SET [ SESSION | LOCAL ] TIME ZONE { zone_horaire | LOCAL | DEFAULT }" - -#~ msgid "" -#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] output_name ] [, ...]\n" -#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table\n" -#~ " [ FROM from_item [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]" -#~ msgstr "" -#~ "[ WITH [ RECURSIVE ] requête_with [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] nom_sortie ] [, ...]\n" -#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] nouvelle_table\n" -#~ " [ FROM élément_from [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW nom_window AS ( définition_window ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING opérateur ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { total | ALL } ]\n" -#~ " [ OFFSET début [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ total ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF nom_table [, ...] ] [ NOWAIT ] [...] ]" - -#~ msgid "" -#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] output_name ] [, ...]\n" -#~ " [ FROM from_item [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]\n" -#~ "\n" -#~ "where from_item can be one of:\n" -#~ "\n" -#~ " [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" -#~ " ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]\n" -#~ " with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" -#~ " function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]\n" -#~ " function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )\n" -#~ " from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]\n" -#~ "\n" -#~ "and with_query is:\n" -#~ "\n" -#~ " with_query_name [ ( column_name [, ...] ) ] AS ( select )\n" -#~ "\n" -#~ "TABLE { [ ONLY ] table_name [ * ] | with_query_name }" -#~ msgstr "" -#~ "[ WITH [ RECURSIVE ] requête_with [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] nom_sortie ] [, ...]\n" -#~ " [ FROM élément_from [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW nom_window AS ( définition_window ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING opérateur ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { total | ALL } ]\n" -#~ " [ OFFSET début [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ total ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF nom_table [, ...] ] [ NOWAIT ] [...] ]\n" -#~ "\n" -#~ "avec élément_from faisant parti de :\n" -#~ "\n" -#~ " [ ONLY ] nom_table [ * ] [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]\n" -#~ " ( select ) [ AS ] alias [ ( alias_colonne [, ...] ) ]\n" -#~ " nom_requête_with [ [ AS ] alias [ ( alias_colonne [, ...] ) ] ]\n" -#~ " nom_fonction ( [ argument [, ...] ] ) [ AS ] alias [ ( alias_colonne [, ...] | définition_colonne [, ...] ) ]\n" -#~ " nom_fonction ( [ argument [, ...] ] ) AS ( définition_colonne [, ...] )\n" -#~ " élément_from [ NATURAL ] type_jointure élément_from [ ON condition_jointure | USING ( colonne_jointure [, ...] ) ]\n" -#~ "\n" -#~ "et requête_with est:\n" -#~ "\n" -#~ " nom_requête_with [ ( nom_colonne [, ...] ) ] AS ( select )\n" -#~ "\n" -#~ "TABLE { [ ONLY ] nom_table [ * ] | nom_requête_with }" - -#~ msgid "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name" -#~ msgstr "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] nom_retour" - -#~ msgid "ROLLBACK PREPARED transaction_id" -#~ msgstr "ROLLBACK PREPARED id_transaction" - -#~ msgid "ROLLBACK [ WORK | TRANSACTION ]" -#~ msgstr "ROLLBACK [ WORK | TRANSACTION ]" - -#~ msgid "" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sequencename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER servername [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE langname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemaname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tablespacename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ ADMIN OPTION FOR ]\n" -#~ " role [, ...] FROM rolename [, ...]\n" -#~ " [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] nom_table [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | REFERENCES } ( colonne [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( colonne [, ...] ) }\n" -#~ " ON [ TABLE ] nom_table [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE nom_séquence [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE nom_base [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER nom_fdw [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER nom_serveur [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE nom_langage [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA nom_schéma [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE nom_tablespace [, ...]\n" -#~ " FROM { [ GROUP ] nom_rôle | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ ADMIN OPTION FOR ]\n" -#~ " role [, ...] FROM nom_rôle [, ...]\n" -#~ " [ CASCADE | RESTRICT ]" - -#~ msgid "RELEASE [ SAVEPOINT ] savepoint_name" -#~ msgstr "RELEASE [ SAVEPOINT ] nom_retour" - -#~ msgid "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]" -#~ msgstr "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } nom [ FORCE ]" - -#~ msgid "REASSIGN OWNED BY old_role [, ...] TO new_role" -#~ msgstr "REASSIGN OWNED BY ancien_role [, ...] TO nouveau_role" - -#~ msgid "PREPARE TRANSACTION transaction_id" -#~ msgstr "PREPARE TRANSACTION id_transaction" - -#~ msgid "PREPARE name [ ( datatype [, ...] ) ] AS statement" -#~ msgstr "PREPARE nom_plan [ ( type_données [, ...] ) ] AS instruction" - -#~ msgid "NOTIFY name" -#~ msgstr "NOTIFY nom" - -#~ msgid "MOVE [ direction { FROM | IN } ] cursorname" -#~ msgstr "MOVE [ direction { FROM | IN } ] nom_de_curseur" - -#~ msgid "" -#~ "LOCK [ TABLE ] [ ONLY ] name [, ...] [ IN lockmode MODE ] [ NOWAIT ]\n" -#~ "\n" -#~ "where lockmode is one of:\n" -#~ "\n" -#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" -#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" -#~ msgstr "" -#~ "LOCK [ TABLE ] [ ONLY ] nom [, ...] [ IN mode_verrouillage MODE ] [ NOWAIT ]\n" -#~ "\n" -#~ "avec mode_verrouillage parmi :\n" -#~ "\n" -#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" -#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" - -#~ msgid "LOAD 'filename'" -#~ msgstr "LOAD 'nom_de_fichier'" - -#~ msgid "LISTEN name" -#~ msgstr "LISTEN nom" - -#~ msgid "" -#~ "INSERT INTO table [ ( column [, ...] ) ]\n" -#~ " { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "INSERT INTO table [ ( colonne [, ...] ) ]\n" -#~ " { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | requête }\n" -#~ " [ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]" - -#~ msgid "" -#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sequencename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER servername [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE langname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemaname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tablespacename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT role [, ...] TO rolename [, ...] [ WITH ADMIN OPTION ]" -#~ msgstr "" -#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] nom_table [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( colonne [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( colonne [, ...] ) }\n" -#~ " ON [ TABLE ] nom_table [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE nom_séquence [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE nom_base [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER nomfdw [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER nom_serveur [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE nom_langage [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA nom_schéma [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE nom_tablespace [, ...]\n" -#~ " TO { [ GROUP ] nom_rôle | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT rôle [, ...] TO nom_rôle [, ...] [ WITH ADMIN OPTION ]" - -#~ msgid "" -#~ "FETCH [ direction { FROM | IN } ] cursorname\n" -#~ "\n" -#~ "where direction can be empty or one of:\n" -#~ "\n" -#~ " NEXT\n" -#~ " PRIOR\n" -#~ " FIRST\n" -#~ " LAST\n" -#~ " ABSOLUTE count\n" -#~ " RELATIVE count\n" -#~ " count\n" -#~ " ALL\n" -#~ " FORWARD\n" -#~ " FORWARD count\n" -#~ " FORWARD ALL\n" -#~ " BACKWARD\n" -#~ " BACKWARD count\n" -#~ " BACKWARD ALL" -#~ msgstr "" -#~ "FETCH [ direction { FROM | IN } ] nom_curseur\n" -#~ "\n" -#~ "sans préciser de direction ou en choissant une des directions suivantes :\n" -#~ "\n" -#~ " NEXT\n" -#~ " PRIOR\n" -#~ " FIRST\n" -#~ " LAST\n" -#~ " ABSOLUTE nombre\n" -#~ " RELATIVE nombre\n" -#~ " count\n" -#~ " ALL\n" -#~ " FORWARD\n" -#~ " FORWARD nombre\n" -#~ " FORWARD ALL\n" -#~ " BACKWARD\n" -#~ " BACKWARD nombre\n" -#~ " BACKWARD ALL" - -#~ msgid "EXPLAIN [ ANALYZE ] [ VERBOSE ] statement" -#~ msgstr "EXPLAIN [ ANALYZE ] [ VERBOSE ] instruction" - -#~ msgid "EXECUTE name [ ( parameter [, ...] ) ]" -#~ msgstr "EXECUTE nom_plan [ ( paramètre [, ...] ) ]" - -#~ msgid "END [ WORK | TRANSACTION ]" -#~ msgstr "END [ WORK | TRANSACTION ]" - -#~ msgid "DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP VIEW [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP USER MAPPING [ IF EXISTS ] FOR { username | USER | CURRENT_USER | PUBLIC } SERVER servername" -#~ msgstr "DROP USER MAPPING [ IF EXISTS ] FOR { nomutilisateur | USER | CURRENT_USER | PUBLIC } SERVER nomserveur" - -#~ msgid "DROP USER [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP USER [IF EXISTS ] nom [, ...]" - -#~ msgid "DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TYPE [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TRIGGER [ IF EXISTS ] name ON table [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TRIGGER [IF EXISTS ] nom ON table [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH PARSER [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TABLESPACE [ IF EXISTS ] tablespacename" -#~ msgstr "DROP TABLESPACE [IF EXISTS ] nom_tablespace" - -#~ msgid "DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TABLE [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP SERVER [ IF EXISTS ] servername [ CASCADE | RESTRICT ]" -#~ msgstr "DROP SERVER [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP SEQUENCE [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP SCHEMA [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP RULE [ IF EXISTS ] name ON relation [ CASCADE | RESTRICT ]" -#~ msgstr "DROP RULE [IF EXISTS ] nom ON relation [ CASCADE | RESTRICT ]" - -#~ msgid "DROP ROLE [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP ROLE [IF EXISTS ] nom [, ...]" - -#~ msgid "DROP OWNED BY name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP OWNED BY nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "DROP OPERATOR FAMILY [IF EXISTS ] nom\n" -#~ " USING méthode_indexage [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "DROP OPERATOR CLASS [IF EXISTS ] nom\n" -#~ " USING méthode_indexage [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR [ IF EXISTS ] name ( { lefttype | NONE } , { righttype | NONE } ) [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "DROP OPERATOR [IF EXISTS ] nom\n" -#~ " ( { type_gauche | NONE } , { type_droit | NONE } )\n" -#~ " [ CASCADE | RESTRICT ]" - -#~ msgid "DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP [ PROCEDURAL ] LANGUAGE [IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP INDEX [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP INDEX [IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP GROUP [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP GROUP [IF EXISTS ] nom [, ...]" - -#~ msgid "" -#~ "DROP FUNCTION [ IF EXISTS ] name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "DROP FUNCTION [IF EXISTS ] nom\n" -#~ " ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] )\n" -#~ " [ CASCADE | RESTRICT ]" - -#~ msgid "DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP FOREIGN DATA WRAPPER [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP DOMAIN [ IF EXISTS ] nom [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP DATABASE [ IF EXISTS ] name" -#~ msgstr "DROP DATABASE [ IF EXISTS ] nom" - -#~ msgid "DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CONVERSION [ IF EXISTS ] nom [ CASCADE | RESTRICT ]" - -#~ msgid "DROP CAST [ IF EXISTS ] (sourcetype AS targettype) [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CAST [ IF EXISTS ] (type_source AS type_cible) [ CASCADE | RESTRICT ]" - -#~ msgid "DROP AGGREGATE [ IF EXISTS ] name ( type [ , ... ] ) [ CASCADE | RESTRICT ]" -#~ msgstr "DROP AGGREGATE [ IF EXISTS ] nom ( type [ , ... ] ) [ CASCADE | RESTRICT ]" - -#~ msgid "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" -#~ msgstr "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" - -#~ msgid "" -#~ "DELETE FROM [ ONLY ] table [ [ AS ] alias ]\n" -#~ " [ USING usinglist ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "DELETE FROM [ ONLY ] table [ [ AS ] alias ]\n" -#~ " [ USING liste_using ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF nom_curseur ]\n" -#~ " [ RETURNING * | expression_sortie [ [ AS ] nom_sortie ] [, ...] ]" - -#~ msgid "" -#~ "DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" -#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR query" -#~ msgstr "" -#~ "DECLARE nom [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" -#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR requête" - -#~ msgid "DEALLOCATE [ PREPARE ] { name | ALL }" -#~ msgstr "DEALLOCATE [ PREPARE ] { nom_plan | ALL }" - -#~ msgid "" -#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]\n" -#~ " AS query" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW nom\n" -#~ " [ ( nom_colonne [, ...] ) ]\n" -#~ " AS requête" - -#~ msgid "" -#~ "CREATE USER MAPPING FOR { username | USER | CURRENT_USER | PUBLIC }\n" -#~ " SERVER servername\n" -#~ " [ OPTIONS ( option 'value' [ , ... ] ) ]" -#~ msgstr "" -#~ "CREATE USER MAPPING FOR { nomutilisateur | USER | CURRENT_USER | PUBLIC }\n" -#~ " SERVER nomserveur\n" -#~ " [ OPTIONS ( option 'valeur' [ , ... ] ) ]" - -#~ msgid "" -#~ "CREATE USER name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE USER nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être :\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT limite_connexion\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE nom_rôle [, ...]\n" -#~ " | IN GROUP nom_rôle [, ...]\n" -#~ " | ROLE nom_rôle [, ...]\n" -#~ " | ADMIN nom_rôle [, ...]\n" -#~ " | USER nom_rôle [, ...]\n" -#~ " | SYSID uid" - -#~ msgid "" -#~ "CREATE TYPE name AS\n" -#~ " ( attribute_name data_type [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE name AS ENUM\n" -#~ " ( 'label' [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE name (\n" -#~ " INPUT = input_function,\n" -#~ " OUTPUT = output_function\n" -#~ " [ , RECEIVE = receive_function ]\n" -#~ " [ , SEND = send_function ]\n" -#~ " [ , TYPMOD_IN = type_modifier_input_function ]\n" -#~ " [ , TYPMOD_OUT = type_modifier_output_function ]\n" -#~ " [ , ANALYZE = analyze_function ]\n" -#~ " [ , INTERNALLENGTH = { internallength | VARIABLE } ]\n" -#~ " [ , PASSEDBYVALUE ]\n" -#~ " [ , ALIGNMENT = alignment ]\n" -#~ " [ , STORAGE = storage ]\n" -#~ " [ , LIKE = like_type ]\n" -#~ " [ , CATEGORY = category ]\n" -#~ " [ , PREFERRED = preferred ]\n" -#~ " [ , DEFAULT = default ]\n" -#~ " [ , ELEMENT = element ]\n" -#~ " [ , DELIMITER = delimiter ]\n" -#~ ")\n" -#~ "\n" -#~ "CREATE TYPE name" -#~ msgstr "" -#~ "CREATE TYPE nom AS\n" -#~ " ( nom_attribut type_donnee [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE nom AS ENUM\n" -#~ " ( 'label' [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE nom (\n" -#~ " INPUT = fonction_entrée,\n" -#~ " OUTPUT = fonction_sortie\n" -#~ " [ , RECEIVE = fonction_réception ]\n" -#~ " [ , SEND = fonction_envoi ]\n" -#~ " [ , TYPMOD_IN = fonction_entrée_modif_type ]\n" -#~ " [ , TYPMOD_OUT = fonction_sortie_modif_type ]\n" -#~ " [ , ANALYZE = fonction_analyse ]\n" -#~ " [ , INTERNALLENGTH = { longueur_interne | VARIABLE } ]\n" -#~ " [ , PASSEDBYVALUE ]\n" -#~ " [ , ALIGNMENT = alignement ]\n" -#~ " [ , STORAGE = stockage ]\n" -#~ " [ , LIKE = type_like ]\n" -#~ " [ , CATEGORY = catégorie ]\n" -#~ " [ , PREFERRED = préféré ]\n" -#~ " [ , DEFAULT = valeur_par_défaut ]\n" -#~ " [ , ELEMENT = élément ]\n" -#~ " [ , DELIMITER = délimiteur ]\n" -#~ ")\n" -#~ "\n" -#~ "CREATE TYPE nom" - -#~ msgid "" -#~ "CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }\n" -#~ " ON table [ FOR [ EACH ] { ROW | STATEMENT } ]\n" -#~ " EXECUTE PROCEDURE funcname ( arguments )" -#~ msgstr "" -#~ "CREATE TRIGGER nom { BEFORE | AFTER } { événement [ OR ... ] }\n" -#~ " ON table [ FOR [ EACH ] { ROW | STATEMENT } ]\n" -#~ " EXECUTE PROCEDURE nom_fonction ( arguments )" - -#~ msgid "" -#~ "CREATE TEXT SEARCH TEMPLATE name (\n" -#~ " [ INIT = init_function , ]\n" -#~ " LEXIZE = lexize_function\n" -#~ ")" -#~ msgstr "" -#~ "CREATE TEXT SEARCH TEMPLATE nom (\n" -#~ " [ INIT = fonction_init , ]\n" -#~ " LEXIZE = fonction_lexize\n" -#~ ")" - -#~ msgid "" -#~ "CREATE TEXT SEARCH PARSER name (\n" -#~ " START = start_function ,\n" -#~ " GETTOKEN = gettoken_function ,\n" -#~ " END = end_function ,\n" -#~ " LEXTYPES = lextypes_function\n" -#~ " [, HEADLINE = headline_function ]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE TEXT SEARCH PARSER nom (\n" -#~ " START = fonction_debut ,\n" -#~ " GETTOKEN = fonction_jeton ,\n" -#~ " END = fonction_fin ,\n" -#~ " LEXTYPES = fonction_typeslexem\n" -#~ " [, HEADLINE = fonction_entete ]\n" -#~ ")" - -#~ msgid "" -#~ "CREATE TEXT SEARCH DICTIONARY name (\n" -#~ " TEMPLATE = template\n" -#~ " [, option = value [, ... ]]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE TEXT SEARCH DICTIONARY nom (\n" -#~ " TEMPLATE = modèle\n" -#~ " [, option = valeur [, ... ]]\n" -#~ ")" - -#~ msgid "" -#~ "CREATE TEXT SEARCH CONFIGURATION name (\n" -#~ " PARSER = parser_name |\n" -#~ " COPY = source_config\n" -#~ ")" -#~ msgstr "" -#~ "CREATE TEXT SEARCH CONFIGURATION nom (\n" -#~ " PARSER = nom_analyseur |\n" -#~ " COPY = config_source\n" -#~ ")" - -#~ msgid "CREATE TABLESPACE tablespacename [ OWNER username ] LOCATION 'directory'" -#~ msgstr "" -#~ "CREATE TABLESPACE nom_tablespace [ OWNER nom_utilisateur ]\n" -#~ " LOCATION 'répertoire'" - -#~ msgid "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name\n" -#~ " [ (column_name [, ...] ) ]\n" -#~ " [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " AS query\n" -#~ " [ WITH [ NO ] DATA ]" -#~ msgstr "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE nom_table\n" -#~ " [ (nom_colonne [, ...] ) ]\n" -#~ " [ WITH ( paramètre_stockage [= valeur] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " AS requête [ WITH [ NO ] DATA ]" - -#~ msgid "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name ( [\n" -#~ " { column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]\n" -#~ " | table_constraint\n" -#~ " | LIKE parent_table [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }\n" -#~ " [, ... ]\n" -#~ "] )\n" -#~ "[ INHERITS ( parent_table [, ... ] ) ]\n" -#~ "[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ "[ TABLESPACE tablespace ]\n" -#~ "\n" -#~ "where column_constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ NOT NULL | \n" -#~ " NULL | \n" -#~ " UNIQUE index_parameters |\n" -#~ " PRIMARY KEY index_parameters |\n" -#~ " CHECK ( expression ) |\n" -#~ " REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" -#~ " [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "and table_constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ UNIQUE ( column_name [, ... ] ) index_parameters |\n" -#~ " PRIMARY KEY ( column_name [, ... ] ) index_parameters |\n" -#~ " CHECK ( expression ) |\n" -#~ " FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]\n" -#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "index_parameters in UNIQUE and PRIMARY KEY constraints are:\n" -#~ "\n" -#~ "[ WITH ( storage_parameter [= value] [, ... ] ) ]\n" -#~ "[ USING INDEX TABLESPACE tablespace ]" -#~ msgstr "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE nom_table ( [\n" -#~ " { nom_colonne type_données [ DEFAULT expr_par_défaut ]\n" -#~ " [ contrainte_colonne [ ... ] ]\n" -#~ " | contrainte_table\n" -#~ " | LIKE table_parent [ { INCLUDING | EXCLUDING }\n" -#~ " { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }\n" -#~ " [, ... ]\n" -#~ "] )\n" -#~ "[ INHERITS ( table_parent [, ... ] ) ]\n" -#~ "[ WITH ( paramètre_stockage [= valeur] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ "[ TABLESPACE tablespace ]\n" -#~ "\n" -#~ "où colonne_contrainte peut être :\n" -#~ "\n" -#~ "[ CONSTRAINT nom_contrainte ]\n" -#~ "{ NOT NULL | \n" -#~ " NULL | \n" -#~ " UNIQUE paramètres_index |\n" -#~ " PRIMARY KEY paramètres_index |\n" -#~ " CHECK (expression) |\n" -#~ " REFERENCES table_référée [ ( colonne_referrée ) ]\n" -#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" -#~ " [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ]\n" -#~ "[ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "et contrainte_table peut être :\n" -#~ "\n" -#~ "[ CONSTRAINT nom_contrainte ]\n" -#~ "{ UNIQUE ( nom_colonne [, ... ] ) paramètres_index |\n" -#~ " PRIMARY KEY ( nom_colonne [, ... ] ) paramètres_index |\n" -#~ " CHECK ( expression ) |\n" -#~ " FOREIGN KEY ( nom_colonne [, ... ] ) REFERENCES\n" -#~ " table_référée [ ( colonne_référée [, ... ] ) ]\n" -#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" -#~ " [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ]\n" -#~ "[ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "les paramètres_index dans les contraintes UNIQUE et PRIMARY KEY sont :\n" -#~ "\n" -#~ "[ WITH ( paramètre_stockage [= valeur] [, ... ] ) ]\n" -#~ "[ USING INDEX TABLESPACE espace_logique ]" - -#~ msgid "" -#~ "CREATE SERVER servername [ TYPE 'servertype' ] [ VERSION 'serverversion' ]\n" -#~ " FOREIGN DATA WRAPPER fdwname\n" -#~ " [ OPTIONS ( option 'value' [, ... ] ) ]" -#~ msgstr "" -#~ "CREATE SERVER nom [ TYPE 'typeserveur' ] [ VERSION 'versionserveur' ]\n" -#~ " FOREIGN DATA WRAPPER nomfdw\n" -#~ " [ OPTIONS ( option 'valeur' [, ... ] ) ]" - -#~ msgid "" -#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]\n" -#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.column | NONE } ]" -#~ msgstr "" -#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE nom [ INCREMENT [ BY ] incrémentation ]\n" -#~ " [ MINVALUE valeur_mini | NO MINVALUE ]\n" -#~ " [ MAXVALUE valeur_maxi | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] valeur_départ ]\n" -#~ " [ CACHE en_cache ]\n" -#~ " [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.colonne | NONE } ]" - -#~ msgid "" -#~ "CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]\n" -#~ "CREATE SCHEMA AUTHORIZATION username [ schema_element [ ... ] ]" -#~ msgstr "" -#~ "CREATE SCHEMA nom_schema [ AUTHORIZATION nom_utilisateur ]\n" -#~ " [ element_schema [ ... ] ]\n" -#~ "CREATE SCHEMA AUTHORIZATION nom_utilisateur [ element_schema [ ... ] ]" - -#~ msgid "" -#~ "CREATE [ OR REPLACE ] RULE name AS ON event\n" -#~ " TO table [ WHERE condition ]\n" -#~ " DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] RULE nom AS ON événement\n" -#~ " TO table [ WHERE condition ]\n" -#~ " DO [ ALSO | INSTEAD ] { NOTHING | commande | ( commande ; commande ... ) }" - -#~ msgid "" -#~ "CREATE ROLE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE ROLE nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être :\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT limite_connexion\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE nom_rôle [, ...]\n" -#~ " | IN GROUP nom_rôle [, ...]\n" -#~ " | ROLE nom_rôle [, ...]\n" -#~ " | ADMIN nom_rôle [, ...]\n" -#~ " | USER nom_rôle [, ...]\n" -#~ " | SYSID uid" - -#~ msgid "CREATE OPERATOR FAMILY name USING index_method" -#~ msgstr "CREATE OPERATOR FAMILY nom USING methode_indexage" - -#~ msgid "" -#~ "CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type\n" -#~ " USING index_method [ FAMILY family_name ] AS\n" -#~ " { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ]\n" -#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" -#~ " | STORAGE storage_type\n" -#~ " } [, ... ]" -#~ msgstr "" -#~ "CREATE OPERATOR CLASS nom [ DEFAULT ] FOR TYPE type_donnée\n" -#~ " USING méthode_indexage [ FAMILY nom_famille ] AS\n" -#~ " { OPERATOR numéro_stratégie nom_operateur [ ( op_type, op_type ) ]\n" -#~ " | FUNCTION numéro_support [ ( type_op [ , type_op ] ) ]\n" -#~ " nom_fonction ( type_argument [, ...] )\n" -#~ " | STORAGE type_stockage\n" -#~ " } [, ... ]" - -#~ msgid "" -#~ "CREATE OPERATOR name (\n" -#~ " PROCEDURE = funcname\n" -#~ " [, LEFTARG = lefttype ] [, RIGHTARG = righttype ]\n" -#~ " [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]\n" -#~ " [, RESTRICT = res_proc ] [, JOIN = join_proc ]\n" -#~ " [, HASHES ] [, MERGES ]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE OPERATOR nom (\n" -#~ " PROCEDURE = nom_fonction\n" -#~ " [, LEFTARG = type_gauche ] [, RIGHTARG = type_droit ]\n" -#~ " [, COMMUTATOR = op_com ] [, NEGATOR = op_neg ]\n" -#~ " [, RESTRICT = proc_res ] [, JOIN = proc_join ]\n" -#~ " [, HASHES ] [, MERGES ]\n" -#~ ")" - -#~ msgid "" -#~ "CREATE [ PROCEDURAL ] LANGUAGE name\n" -#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\n" -#~ " HANDLER call_handler [ VALIDATOR valfunction ]" -#~ msgstr "" -#~ "CREATE [ PROCEDURAL ] LANGUAGE nom\n" -#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE nom\n" -#~ " HANDLER gestionnaire_appels [ VALIDATOR fonction_val ]" - -#~ msgid "" -#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]\n" -#~ " ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )\n" -#~ " [ WITH ( storage_parameter = value [, ... ] ) ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " [ WHERE predicate ]" -#~ msgstr "" -#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] nom ON table [ USING methode ]\n" -#~ " ( { colonne | ( expression ) } [ classe_operateur ]\n" -#~ " [ ASC | DESC ]\n" -#~ " [ NULLS { FIRST | LAST } ] [, ...] )\n" -#~ " [ WITH ( parametre_stockage = valeur [, ... ] ) ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " [ WHERE predicat ]" - -#~ msgid "" -#~ "CREATE GROUP name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE GROUP nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être :\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE nom_rôle [, ...]\n" -#~ " | IN GROUP nom_rôle [, ...]\n" -#~ " | ROLE nom_rôle [, ...]\n" -#~ " | ADMIN nom_rôle [, ...]\n" -#~ " | USER nom_rôle [, ...]\n" -#~ " | SYSID uid" - -#~ msgid "" -#~ "CREATE [ OR REPLACE ] FUNCTION\n" -#~ " name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } defexpr ] [, ...] ] )\n" -#~ " [ RETURNS rettype\n" -#~ " | RETURNS TABLE ( colname coltype [, ...] ) ]\n" -#~ " { LANGUAGE langname\n" -#~ " | WINDOW\n" -#~ " | IMMUTABLE | STABLE | VOLATILE\n" -#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " | COST execution_cost\n" -#~ " | ROWS result_rows\n" -#~ " | SET configuration_parameter { TO value | = value | FROM CURRENT }\n" -#~ " | AS 'definition'\n" -#~ " | AS 'obj_file', 'link_symbol'\n" -#~ " } ...\n" -#~ " [ WITH ( attribute [, ...] ) ]" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] FUNCTION\n" -#~ " nom ( [ [ mode_arg ] [ nom_arg ] type_arg [ { DEFAULT | = } expr_par_défaut ] [, ...] ] )\n" -#~ " [ RETURNS type_ret\n" -#~ " | RETURNS TABLE ( nom_colonne type_colonne [, ...] ) ]\n" -#~ " { LANGUAGE nom_lang\n" -#~ " | WINDOW\n" -#~ " | IMMUTABLE | STABLE | VOLATILE\n" -#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " | COST coût_exécution\n" -#~ " | ROWS lignes_résultats\n" -#~ " | SET paramètre_configuration { TO valeur | = valeur | FROM CURRENT }\n" -#~ " | AS 'définition'\n" -#~ " | AS 'fichier_obj', 'symbôle_lien'\n" -#~ " } ...\n" -#~ " [ WITH ( attribut [, ...] ) ]" - -#~ msgid "" -#~ "CREATE FOREIGN DATA WRAPPER name\n" -#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" -#~ " [ OPTIONS ( option 'value' [, ... ] ) ]" -#~ msgstr "" -#~ "CREATE FOREIGN DATA WRAPPER nom\n" -#~ " [ VALIDATOR fonction_validation | NO VALIDATOR ]\n" -#~ " [ OPTIONS ( option 'valeur' [, ... ] ) ]" - -#~ msgid "" -#~ "CREATE DOMAIN name [ AS ] data_type\n" -#~ " [ DEFAULT expression ]\n" -#~ " [ constraint [ ... ] ]\n" -#~ "\n" -#~ "where constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ NOT NULL | NULL | CHECK (expression) }" -#~ msgstr "" -#~ "CREATE DOMAIN nom [AS] type_données\n" -#~ " [ DEFAULT expression ]\n" -#~ " [ contrainte [ ... ] ]\n" -#~ "\n" -#~ "avec comme contrainte :\n" -#~ "\n" -#~ "[ CONSTRAINT nom_contrainte ]\n" -#~ "{ NOT NULL | NULL | CHECK (expression) }" - -#~ msgid "" -#~ "CREATE DATABASE name\n" -#~ " [ [ WITH ] [ OWNER [=] dbowner ]\n" -#~ " [ TEMPLATE [=] template ]\n" -#~ " [ ENCODING [=] encoding ]\n" -#~ " [ LC_COLLATE [=] lc_collate ]\n" -#~ " [ LC_CTYPE [=] lc_ctype ]\n" -#~ " [ TABLESPACE [=] tablespace ]\n" -#~ " [ CONNECTION LIMIT [=] connlimit ] ]" -#~ msgstr "" -#~ "CREATE DATABASE nom\n" -#~ " [ [ WITH ] [ OWNER [=] nom_propriétaire ]\n" -#~ " [ TEMPLATE [=] modèle ]\n" -#~ " [ ENCODING [=] encodage ]\n" -#~ " [ LC_COLLATE [=] tri_caract ]\n" -#~ " [ LC_CTYPE [=] type_caract ]\n" -#~ " [ TABLESPACE [=] tablespace ]\n" -#~ " [ CONNECTION LIMIT [=] limite_connexion ] ]" - -#~ msgid "" -#~ "CREATE [ DEFAULT ] CONVERSION name\n" -#~ " FOR source_encoding TO dest_encoding FROM funcname" -#~ msgstr "" -#~ "CREATE [DEFAULT] CONVERSION nom\n" -#~ " FOR codage_source TO codage_cible FROM nom_fonction" - -#~ msgid "" -#~ "CREATE CONSTRAINT TRIGGER name\n" -#~ " AFTER event [ OR ... ]\n" -#~ " ON table_name\n" -#~ " [ FROM referenced_table_name ]\n" -#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" -#~ " FOR EACH ROW\n" -#~ " EXECUTE PROCEDURE funcname ( arguments )" -#~ msgstr "" -#~ "CREATE CONSTRAINT TRIGGER nom\n" -#~ " AFTER événement [ OR ... ]\n" -#~ " ON table\n" -#~ " [ FROM table_référencée ]\n" -#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" -#~ " FOR EACH ROW\n" -#~ " EXECUTE PROCEDURE nom_fonction ( arguments )" - -#~ msgid "" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITH FUNCTION funcname (argtypes)\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITHOUT FUNCTION\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITH INOUT\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" -#~ msgstr "" -#~ "CREATE CAST (type_source AS type_cible)\n" -#~ " WITH FUNCTION nom_fonction (type_argument)\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (type_source AS type_cible)\n" -#~ " WITHOUT FUNCTION\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (type_source AS type_cible)\n" -#~ " WITH INOUT\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" - -#~ msgid "" -#~ "CREATE AGGREGATE name ( input_data_type [ , ... ] ) (\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = state_data_type\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = initial_condition ]\n" -#~ " [ , SORTOP = sort_operator ]\n" -#~ ")\n" -#~ "\n" -#~ "or the old syntax\n" -#~ "\n" -#~ "CREATE AGGREGATE name (\n" -#~ " BASETYPE = base_type,\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = state_data_type\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = initial_condition ]\n" -#~ " [ , SORTOP = sort_operator ]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE AGGREGATE nom ( type_données_en_entrée [ , ... ] ) (\n" -#~ " SFUNC = sfonction,\n" -#~ " STYPE = type_données_état\n" -#~ " [ , FINALFUNC = fonction_f ]\n" -#~ " [ , INITCOND = condition_initiale ]\n" -#~ " [ , SORTOP = opérateur_tri ]\n" -#~ ")\n" -#~ "\n" -#~ "ou l'ancienne syntaxe\n" -#~ "\n" -#~ "CREATE AGGREGATE nom (\n" -#~ " BASETYPE = type_base,\n" -#~ " SFUNC = fonction_s,\n" -#~ " STYPE = type_données_état\n" -#~ " [ , FINALFUNC = fonction_f ]\n" -#~ " [ , INITCOND = condition_initiale ]\n" -#~ " [ , SORTOP = opérateur_tri ]\n" -#~ ")" - -#~ msgid "" -#~ "COPY tablename [ ( column [, ...] ) ]\n" -#~ " FROM { 'filename' | STDIN }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" -#~ " [ NULL [ AS ] 'null string' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'quote' ] \n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE NOT NULL column [, ...] ]\n" -#~ "\n" -#~ "COPY { tablename [ ( column [, ...] ) ] | ( query ) }\n" -#~ " TO { 'filename' | STDOUT }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" -#~ " [ NULL [ AS ] 'null string' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'quote' ] \n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE QUOTE column [, ...] ]" -#~ msgstr "" -#~ "COPY nom_table [ ( colonne [, ...] ) ]\n" -#~ " FROM { 'nom_fichier' | STDIN }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'délimiteur' ]\n" -#~ " [ NULL [ AS ] 'chaîne null' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'guillemet' ] \n" -#~ " [ ESCAPE [ AS ] 'échappement' ]\n" -#~ " [ FORCE NOT NULL colonne [, ...] ]\n" -#~ "\n" -#~ "COPY { nom_table [ ( colonne [, ...] ) ] | ( requête ) }\n" -#~ " TO { 'nom_fichier' | STDOUT }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'délimiteur' ]\n" -#~ " [ NULL [ AS ] 'chaîne null' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'guillemet' ] \n" -#~ " [ ESCAPE [ AS ] 'échappement' ]\n" -#~ " [ FORCE QUOTE colonne [, ...] ]" - -#~ msgid "COMMIT PREPARED transaction_id" -#~ msgstr "COMMIT PREPARED id_transaction" - -#~ msgid "COMMIT [ WORK | TRANSACTION ]" -#~ msgstr "COMMIT [ WORK | TRANSACTION ]" - -#~ msgid "" -#~ "COMMENT ON\n" -#~ "{\n" -#~ " TABLE object_name |\n" -#~ " COLUMN table_name.column_name |\n" -#~ " AGGREGATE agg_name (agg_type [, ...] ) |\n" -#~ " CAST (sourcetype AS targettype) |\n" -#~ " CONSTRAINT constraint_name ON table_name |\n" -#~ " CONVERSION object_name |\n" -#~ " DATABASE object_name |\n" -#~ " DOMAIN object_name |\n" -#~ " FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) |\n" -#~ " INDEX object_name |\n" -#~ " LARGE OBJECT large_object_oid |\n" -#~ " OPERATOR op (leftoperand_type, rightoperand_type) |\n" -#~ " OPERATOR CLASS object_name USING index_method |\n" -#~ " OPERATOR FAMILY object_name USING index_method |\n" -#~ " [ PROCEDURAL ] LANGUAGE object_name |\n" -#~ " ROLE object_name |\n" -#~ " RULE rule_name ON table_name |\n" -#~ " SCHEMA object_name |\n" -#~ " SEQUENCE object_name |\n" -#~ " TABLESPACE object_name |\n" -#~ " TEXT SEARCH CONFIGURATION object_name |\n" -#~ " TEXT SEARCH DICTIONARY object_name |\n" -#~ " TEXT SEARCH PARSER object_name |\n" -#~ " TEXT SEARCH TEMPLATE object_name |\n" -#~ " TRIGGER trigger_name ON table_name |\n" -#~ " TYPE object_name |\n" -#~ " VIEW object_name\n" -#~ "} IS 'text'" -#~ msgstr "" -#~ "COMMENT ON\n" -#~ "{\n" -#~ " TABLE nom_objet |\n" -#~ " COLUMN nom_table.nom_colonne |\n" -#~ " AGGREGATE nom_agg (type_agg [, ...] ) |\n" -#~ " CAST (type_source AS type_cible) |\n" -#~ " CONSTRAINT nom_contrainte ON nom_table |\n" -#~ " CONVERSION nom_objet |\n" -#~ " DATABASE nom_objet |\n" -#~ " DOMAIN nom_objet |\n" -#~ " FUNCTION nom_fonction ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] ) |\n" -#~ " INDEX nom_objet |\n" -#~ " LARGE OBJECT oid_LO |\n" -#~ " OPERATOR op (type_operande_gauche, type_operande_droit) |\n" -#~ " OPERATOR CLASS nom_objet USING methode_indexage |\n" -#~ " OPERATOR FAMILY nom_objet USING methode_indexage |\n" -#~ " [ PROCEDURAL ] LANGUAGE nom_objet |\n" -#~ " ROLE nom_objet |\n" -#~ " RULE nom_regle ON nom_table |\n" -#~ " SCHEMA nom_objet |\n" -#~ " SEQUENCE nom_objet |\n" -#~ " TABLESPACE nom_objet |\n" -#~ " TEXT SEARCH CONFIGURATION nom_objet |\n" -#~ " TEXT SEARCH DICTIONARY nom_objet |\n" -#~ " TEXT SEARCH PARSER nom_objet |\n" -#~ " TEXT SEARCH TEMPLATE nom_objet |\n" -#~ " TRIGGER nom_trigger ON nom_objet |\n" -#~ " TYPE nom_objet |\n" -#~ " VIEW nom_objet\n" -#~ "} IS 'text'" - -#~ msgid "" -#~ "CLUSTER [VERBOSE] tablename [ USING indexname ]\n" -#~ "CLUSTER [VERBOSE]" -#~ msgstr "" -#~ "CLUSTER [VERBOSE] nom_table [ USING nom_index ]\n" -#~ "CLUSTER [VERBOSE]" - -#~ msgid "CLOSE { name | ALL }" -#~ msgstr "CLOSE { nom | ALL }" - -#~ msgid "CHECKPOINT" -#~ msgstr "CHECKPOINT" - -#~ msgid "" -#~ "BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]\n" -#~ "\n" -#~ "où transaction_mode peut être :\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ |\n" -#~ " READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "ANALYZE [ VERBOSE ] [ table [ ( column [, ...] ) ] ]" -#~ msgstr "ANALYZE [ VERBOSE ] [ table [ ( colonne [, ...] ) ] ]" - -#~ msgid "" -#~ "ALTER VIEW name ALTER [ COLUMN ] column SET DEFAULT expression\n" -#~ "ALTER VIEW name ALTER [ COLUMN ] column DROP DEFAULT\n" -#~ "ALTER VIEW name OWNER TO new_owner\n" -#~ "ALTER VIEW name RENAME TO new_name\n" -#~ "ALTER VIEW name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER VIEW nom ALTER [ COLUMN ] colonne SET DEFAULT expression\n" -#~ "ALTER VIEW nom ALTER [ COLUMN ] colonne DROP DEFAULT\n" -#~ "ALTER VIEW nom OWNER TO nouveau_propriétaire\n" -#~ "ALTER VIEW nom RENAME TO nouveau_nom\n" -#~ "ALTER VIEW nom SET SCHEMA nouveau_schéma" - -#~ msgid "" -#~ "ALTER USER MAPPING FOR { username | USER | CURRENT_USER | PUBLIC }\n" -#~ " SERVER servername\n" -#~ " OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] )" -#~ msgstr "" -#~ "ALTER USER MAPPING FOR { nom_utilisateur | USER | CURRENT_USER | PUBLIC }\n" -#~ " SERVER nom_serveur\n" -#~ " OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] )" - -#~ msgid "" -#~ "ALTER USER name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER USER name RENAME TO newname\n" -#~ "\n" -#~ "ALTER USER name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER USER name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER USER name RESET configuration_parameter\n" -#~ "ALTER USER name RESET ALL" -#~ msgstr "" -#~ "ALTER USER nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être :\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT limite_connexion\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'motdepasse'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER USER nom RENAME TO nouveau_nom\n" -#~ "\n" -#~ "ALTER USER nom SET paramètre { TO | = } { valeur | DEFAULT }\n" -#~ "ALTER USER name SET paramètre FROM CURRENT\n" -#~ "ALTER USER nom RESET paramètre\n" -#~ "ALTER USER name RESET ALL" - -#~ msgid "" -#~ "ALTER TYPE name RENAME TO new_name\n" -#~ "ALTER TYPE name OWNER TO new_owner \n" -#~ "ALTER TYPE name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER TYPE nom RENAME TO nouveau_nom\n" -#~ "ALTER TYPE nom OWNER TO nouveau_propriétaire\n" -#~ "ALTER TYPE nom SET SCHEMA nouveau_schéma" - -#~ msgid "ALTER TRIGGER name ON table RENAME TO newname" -#~ msgstr "ALTER TRIGGER nom ON table RENAME TO nouveau_nom" - -#~ msgid "ALTER TEXT SEARCH TEMPLATE name RENAME TO newname" -#~ msgstr "ALTER TEXT SEARCH TEMPLATE nom RENAME TO nouveau_nom" - -#~ msgid "ALTER TEXT SEARCH PARSER name RENAME TO newname" -#~ msgstr "ALTER TEXT SEARCH PARSER nom RENAME TO nouveau_nom" - -#~ msgid "" -#~ "ALTER TEXT SEARCH DICTIONARY name (\n" -#~ " option [ = value ] [, ... ]\n" -#~ ")\n" -#~ "ALTER TEXT SEARCH DICTIONARY name RENAME TO newname\n" -#~ "ALTER TEXT SEARCH DICTIONARY name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER TEXT SEARCH DICTIONARY nom (\n" -#~ " option [ = valeur ] [, ... ]\n" -#~ ")\n" -#~ "ALTER TEXT SEARCH DICTIONARY nom RENAME TO nouveau_nom\n" -#~ "ALTER TEXT SEARCH DICTIONARY nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER TEXT SEARCH CONFIGURATION name\n" -#~ " ADD MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name\n" -#~ " ALTER MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name\n" -#~ " ALTER MAPPING REPLACE old_dictionary WITH new_dictionary\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name\n" -#~ " ALTER MAPPING FOR token_type [, ... ] REPLACE old_dictionary WITH new_dictionary\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name\n" -#~ " DROP MAPPING [ IF EXISTS ] FOR token_type [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name RENAME TO newname\n" -#~ "ALTER TEXT SEARCH CONFIGURATION name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER TEXT SEARCH CONFIGURATION nom\n" -#~ " ADD MAPPING FOR type_jeton [, ... ] WITH nom_dictionnaire [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom\n" -#~ " ALTER MAPPING FOR type_jeton [, ... ] WITH nom_dictionnaire [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom\n" -#~ " ALTER MAPPING REPLACE ancien_dictionnaire WITH nouveau_dictionnaire\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom\n" -#~ " ALTER MAPPING FOR type_jeton [, ... ]\n" -#~ " REPLACE ancien_dictionnaire WITH nouveau_dictionnaire\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom\n" -#~ " DROP MAPPING [ IF EXISTS ] FOR type_jeton [, ... ]\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom RENAME TO nouveau_nom\n" -#~ "ALTER TEXT SEARCH CONFIGURATION nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER TABLESPACE name RENAME TO newname\n" -#~ "ALTER TABLESPACE name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER TABLESPACE nom RENAME TO nouveau_nom\n" -#~ "ALTER TABLESPACE nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER TABLE [ ONLY ] name [ * ]\n" -#~ " action [, ... ]\n" -#~ "ALTER TABLE [ ONLY ] name [ * ]\n" -#~ " RENAME [ COLUMN ] column TO new_column\n" -#~ "ALTER TABLE name\n" -#~ " RENAME TO new_name\n" -#~ "ALTER TABLE name\n" -#~ " SET SCHEMA new_schema\n" -#~ "\n" -#~ "where action is one of:\n" -#~ "\n" -#~ " ADD [ COLUMN ] column type [ column_constraint [ ... ] ]\n" -#~ " DROP [ COLUMN ] column [ RESTRICT | CASCADE ]\n" -#~ " ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ]\n" -#~ " ALTER [ COLUMN ] column SET DEFAULT expression\n" -#~ " ALTER [ COLUMN ] column DROP DEFAULT\n" -#~ " ALTER [ COLUMN ] column { SET | DROP } NOT NULL\n" -#~ " ALTER [ COLUMN ] column SET STATISTICS integer\n" -#~ " ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" -#~ " ADD table_constraint\n" -#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" -#~ " DISABLE TRIGGER [ trigger_name | ALL | USER ]\n" -#~ " ENABLE TRIGGER [ trigger_name | ALL | USER ]\n" -#~ " ENABLE REPLICA TRIGGER trigger_name\n" -#~ " ENABLE ALWAYS TRIGGER trigger_name\n" -#~ " DISABLE RULE rewrite_rule_name\n" -#~ " ENABLE RULE rewrite_rule_name\n" -#~ " ENABLE REPLICA RULE rewrite_rule_name\n" -#~ " ENABLE ALWAYS RULE rewrite_rule_name\n" -#~ " CLUSTER ON index_name\n" -#~ " SET WITHOUT CLUSTER\n" -#~ " SET WITH OIDS\n" -#~ " SET WITHOUT OIDS\n" -#~ " SET ( storage_parameter = value [, ... ] )\n" -#~ " RESET ( storage_parameter [, ... ] )\n" -#~ " INHERIT parent_table\n" -#~ " NO INHERIT parent_table\n" -#~ " OWNER TO new_owner\n" -#~ " SET TABLESPACE new_tablespace" -#~ msgstr "" -#~ "ALTER TABLE [ ONLY ] nom [ * ]\n" -#~ " action [, ... ]\n" -#~ "ALTER TABLE [ ONLY ] nom [ * ]\n" -#~ " RENAME [ COLUMN ] colonne TO nouvelle_colonne\n" -#~ "ALTER TABLE nom\n" -#~ " RENAME TO nouveau_nom\n" -#~ "ALTER TABLE nom\n" -#~ " SET SCHEMA nouveau_schema\n" -#~ "\n" -#~ "où action peut être :\n" -#~ "\n" -#~ " ADD [ COLUMN ] colonne type [ contrainte_colonne [ ... ] ]\n" -#~ " DROP [ COLUMN ] colonne [ RESTRICT | CASCADE ]\n" -#~ " ALTER [ COLUMN ] colonne [ SET DATA ] TYPE type [ USING expression ]\n" -#~ " ALTER [ COLUMN ] colonne SET DEFAULT expression\n" -#~ " ALTER [ COLUMN ] colonne DROP DEFAULT\n" -#~ " ALTER [ COLUMN ] colonne { SET | DROP } NOT NULL\n" -#~ " ALTER [ COLUMN ] colonne SET STATISTICS entier\n" -#~ " ALTER [ COLUMN ] colonne SET STORAGE\n" -#~ " { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" -#~ " ADD contrainte_table\n" -#~ " DROP CONSTRAINT nom_contrainte [ RESTRICT | CASCADE ]\n" -#~ " DISABLE TRIGGER [ nom_trigger | ALL | USER ]\n" -#~ " ENABLE TRIGGER [ nom_trigger | ALL | USER ]\n" -#~ " ENABLE REPLICA TRIGGER nom_trigger\n" -#~ " ENABLE ALWAYS TRIGGER nom_trigger\n" -#~ " DISABLE RULE nom_règle_réécriture\n" -#~ " ENABLE RULE nom_règle_réécriture\n" -#~ " ENABLE REPLICA RULE nom_règle_réécriture\n" -#~ " ENABLE ALWAYS RULE nom_règle_réécriture\n" -#~ " CLUSTER ON nom_index\n" -#~ " SET WITHOUT CLUSTER\n" -#~ " SET WITH OIDS\n" -#~ " SET WITHOUT OIDS\n" -#~ " SET ( paramètre_stockage = valeur [, ... ] )\n" -#~ " RESET ( paramètre_stockage [, ... ] )\n" -#~ " INHERIT table_parent\n" -#~ " NO INHERIT table_parent\n" -#~ " OWNER TO nouveau_propriétaire\n" -#~ " SET TABLESPACE nouveau_tablespace" - -#~ msgid "" -#~ "ALTER SERVER servername [ VERSION 'newversion' ]\n" -#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) ]\n" -#~ "ALTER SERVER servername OWNER TO new_owner" -#~ msgstr "" -#~ "ALTER SERVER nom [ VERSION 'nouvelleversion' ]\n" -#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ] ) ]\n" -#~ "ALTER SERVER nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER SEQUENCE name [ INCREMENT [ BY ] increment ]\n" -#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] start ]\n" -#~ " [ RESTART [ [ WITH ] restart ] ]\n" -#~ " [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.column | NONE } ]\n" -#~ "ALTER SEQUENCE name OWNER TO new_owner\n" -#~ "ALTER SEQUENCE name RENAME TO new_name\n" -#~ "ALTER SEQUENCE name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER SEQUENCE nom [ INCREMENT [ BY ] incrément ]\n" -#~ " [ MINVALUE valeur_min | NO MINVALUE ] [ MAXVALUE valeur_max | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] valeur_début ]\n" -#~ " [ RESTART [ [ WITH ] valeur_redémarrage ] ]\n" -#~ " [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.colonne | NONE } ]\n" -#~ "ALTER SEQUENCE nom OWNER TO new_propriétaire\n" -#~ "ALTER SEQUENCE nom RENAME TO new_nom\n" -#~ "ALTER SEQUENCE nom SET SCHEMA new_schéma" - -#~ msgid "" -#~ "ALTER SCHEMA name RENAME TO newname\n" -#~ "ALTER SCHEMA name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER SCHEMA nom RENAME TO nouveau_nom\n" -#~ "ALTER SCHEMA nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER ROLE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER ROLE name RENAME TO newname\n" -#~ "\n" -#~ "ALTER ROLE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER ROLE name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER ROLE name RESET configuration_parameter\n" -#~ "ALTER ROLE name RESET ALL" -#~ msgstr "" -#~ "ALTER ROLE nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être :\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT limite_connexions\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'mot de passe'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER ROLE nom RENAME TO nouveau_nom\n" -#~ "\n" -#~ "ALTER ROLE nom SET paramètre { TO | = } { valeur | DEFAULT }\n" -#~ "ALTER ROLE name SET paramètre FROM CURRENT\n" -#~ "ALTER ROLE nom RESET paramètre\n" -#~ "ALTER ROLE name RESET ALL" - -#~ msgid "" -#~ "ALTER OPERATOR FAMILY name USING index_method ADD\n" -#~ " { OPERATOR strategy_number operator_name ( op_type, op_type )\n" -#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" -#~ " } [, ... ]\n" -#~ "ALTER OPERATOR FAMILY name USING index_method DROP\n" -#~ " { OPERATOR strategy_number ( op_type [ , op_type ] )\n" -#~ " | FUNCTION support_number ( op_type [ , op_type ] )\n" -#~ " } [, ... ]\n" -#~ "ALTER OPERATOR FAMILY name USING index_method RENAME TO newname\n" -#~ "ALTER OPERATOR FAMILY name USING index_method OWNER TO newowner" -#~ msgstr "" -#~ "ALTER OPERATOR FAMILY nom USING méthode_indexage ADD\n" -#~ " { OPERATOR numéro_stratégie nom_opérateur ( type_op, type_op ) \n" -#~ " | FUNCTION numéro_support [ ( type_op [ , type_op ] ) ]\n" -#~ " nom_fonction ( type_argument [, ...] )\n" -#~ " } [, ... ]\n" -#~ "ALTER OPERATOR FAMILY nom USING méthode_indexage DROP\n" -#~ " { OPERATOR numéro_stratégie ( type_op [ , type_op ] )\n" -#~ " | FUNCTION numéro_support ( type_op [ , type_op ] )\n" -#~ " } [, ... ]\n" -#~ "ALTER OPERATOR FAMILY nom USING méthode_indexage\n" -#~ " RENAME TO nouveau_nom\n" -#~ "ALTER OPERATOR FAMILY nom USING méthode_indexage\n" -#~ " OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER OPERATOR CLASS name USING index_method RENAME TO newname\n" -#~ "ALTER OPERATOR CLASS name USING index_method OWNER TO newowner" -#~ msgstr "" -#~ "ALTER OPERATOR CLASS nom USING méthode_indexation\n" -#~ " RENAME TO nouveau_nom\n" -#~ "ALTER OPERATOR CLASS nom USING méthode_indexation\n" -#~ " OWNER TO nouveau_propriétaire" - -#~ msgid "ALTER OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) OWNER TO newowner" -#~ msgstr "" -#~ "ALTER OPERATOR nom ( { lefttype | NONE } , { righttype | NONE } )\n" -#~ " OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO newname\n" -#~ "ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO new_owner" -#~ msgstr "" -#~ "ALTER [ PROCEDURAL ] LANGUAGE nom RENAME TO nouveau_nom\n" -#~ "ALTER [ PROCEDURAL ] LANGUAGE nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER INDEX name RENAME TO new_name\n" -#~ "ALTER INDEX name SET TABLESPACE tablespace_name\n" -#~ "ALTER INDEX name SET ( storage_parameter = value [, ... ] )\n" -#~ "ALTER INDEX name RESET ( storage_parameter [, ... ] )" -#~ msgstr "" -#~ "ALTER INDEX nom RENAME TO nouveau_nom\n" -#~ "ALTER INDEX nom SET TABLESPACE nom_tablespace\n" -#~ "ALTER INDEX nom SET ( paramètre_stockage = valeur [, ... ] )\n" -#~ "ALTER INDEX nom RESET ( paramètre_stockage [, ... ] )" - -#~ msgid "" -#~ "ALTER GROUP groupname ADD USER username [, ... ]\n" -#~ "ALTER GROUP groupname DROP USER username [, ... ]\n" -#~ "\n" -#~ "ALTER GROUP groupname RENAME TO newname" -#~ msgstr "" -#~ "ALTER GROUP nom_groupe ADD USER nom_utilisateur [, ... ]\n" -#~ "ALTER GROUP nom_groupe DROP USER nom_utilisateur [, ... ]\n" -#~ "\n" -#~ "ALTER GROUP nom_groupe RENAME TO nouveau_nom" - -#~ msgid "" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " action [ ... ] [ RESTRICT ]\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " RENAME TO new_name\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " OWNER TO new_owner\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " SET SCHEMA new_schema\n" -#~ "\n" -#~ "where action is one of:\n" -#~ "\n" -#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " IMMUTABLE | STABLE | VOLATILE\n" -#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " COST execution_cost\n" -#~ " ROWS result_rows\n" -#~ " SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ " SET configuration_parameter FROM CURRENT\n" -#~ " RESET configuration_parameter\n" -#~ " RESET ALL" -#~ msgstr "" -#~ "ALTER FUNCTION nom ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] )\n" -#~ " action [, ... ] [ RESTRICT ]\n" -#~ "ALTER FUNCTION nom ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] )\n" -#~ " RENAME TO nouveau_nom\n" -#~ "ALTER FUNCTION nom ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] )\n" -#~ " OWNER TO nouveau_proprietaire\n" -#~ "ALTER FUNCTION nom ( [ [ mode_arg ] [ nom_arg ] type_arg [, ...] ] )\n" -#~ " SET SCHEMA nouveau_schema\n" -#~ "\n" -#~ "où action peut être :\n" -#~ "\n" -#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " IMMUTABLE | STABLE | VOLATILE\n" -#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " COST cout_execution\n" -#~ " ROWS lignes_resultats\n" -#~ " SET paramètre { TO | = } { valeur | DEFAULT }\n" -#~ " SET paramètre FROM CURRENT\n" -#~ " RESET paramètre\n" -#~ " RESET ALL" - -#~ msgid "" -#~ "ALTER FOREIGN DATA WRAPPER name\n" -#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" -#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) ]\n" -#~ "ALTER FOREIGN DATA WRAPPER name OWNER TO new_owner" -#~ msgstr "" -#~ "ALTER FOREIGN DATA WRAPPER nom\n" -#~ " [ VALIDATOR fonction_validation | NO VALIDATOR ]\n" -#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['valeur'] [, ... ]) ]\n" -#~ "ALTER FOREIGN DATA WRAPPER nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER DOMAIN name\n" -#~ " { SET DEFAULT expression | DROP DEFAULT }\n" -#~ "ALTER DOMAIN name\n" -#~ " { SET | DROP } NOT NULL\n" -#~ "ALTER DOMAIN name\n" -#~ " ADD domain_constraint\n" -#~ "ALTER DOMAIN name\n" -#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" -#~ "ALTER DOMAIN name\n" -#~ " OWNER TO new_owner \n" -#~ "ALTER DOMAIN name\n" -#~ " SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER DOMAIN nom\n" -#~ " { SET DEFAULT expression | DROP DEFAULT }\n" -#~ "ALTER DOMAIN nom\n" -#~ " { SET | DROP } NOT NULL\n" -#~ "ALTER DOMAIN nom\n" -#~ " ADD contrainte_domaine\n" -#~ "ALTER DOMAIN nom\n" -#~ " DROP CONSTRAINT nom_contrainte [ RESTRICT | CASCADE ]\n" -#~ "ALTER DOMAIN nom\n" -#~ " OWNER TO nouveau_propriétaire \n" -#~ "ALTER DOMAIN nom\n" -#~ " SET SCHEMA nouveau_schéma" - -#~ msgid "" -#~ "ALTER DATABASE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ "\n" -#~ " CONNECTION LIMIT connlimit\n" -#~ "\n" -#~ "ALTER DATABASE name RENAME TO newname\n" -#~ "\n" -#~ "ALTER DATABASE name OWNER TO new_owner\n" -#~ "\n" -#~ "ALTER DATABASE name SET TABLESPACE new_tablespace\n" -#~ "\n" -#~ "ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER DATABASE name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER DATABASE name RESET configuration_parameter\n" -#~ "ALTER DATABASE name RESET ALL" -#~ msgstr "" -#~ "ALTER DATABASE nom [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "où option peut être:\n" -#~ "\n" -#~ " CONNECTION LIMIT limite_connexion\n" -#~ "\n" -#~ "ALTER DATABASE nom RENAME TO nouveau_nom\n" -#~ "\n" -#~ "ALTER DATABASE nom OWNER TO nouveau_propriétaire\n" -#~ "\n" -#~ "ALTER DATABASE nom SET TABLESPACE nouveau_tablespace\n" -#~ "\n" -#~ "ALTER DATABASE nom SET paramètre_configuration { TO | = } { valeur | DEFAULT }\n" -#~ "ALTER DATABASE nom SET paramètre_configuration FROM CURRENT\n" -#~ "ALTER DATABASE nom RESET paramètre_configuration\n" -#~ "ALTER DATABASE nom RESET ALL" - -#~ msgid "" -#~ "ALTER CONVERSION name RENAME TO newname\n" -#~ "ALTER CONVERSION name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER CONVERSION nom RENAME TO nouveau_nom\n" -#~ "ALTER CONVERSION nom OWNER TO nouveau_propriétaire" - -#~ msgid "" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) RENAME TO new_name\n" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) OWNER TO new_owner\n" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER AGGREGATE nom ( type [ , ... ] ) RENAME TO nouveau_nom\n" -#~ "ALTER AGGREGATE nom ( type [ , ... ] ) OWNER TO nouveau_propriétaire\n" -#~ "ALTER AGGREGATE nom ( type [ , ... ] ) SET SCHEMA nouveau_schéma" - -#~ msgid "ABORT [ WORK | TRANSACTION ]" -#~ msgstr "ABORT [ WORK | TRANSACTION ]" - #~ msgid "number" #~ msgstr "numéro" @@ -7974,3 +6445,24 @@ msgstr "" #~ msgid "No per-database role settings support in this server version.\n" #~ msgstr "Pas de supprot des paramètres rôle par base de données pour la version de ce serveur.\n" + +#~ msgid "attribute" +#~ msgstr "attribut" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM version de psql (format numérique)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME version de psql (chaîne courte)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION version de psql (chaîne verbeuse)\n" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME version du serveur (chaîne courte)\n" + +#~ msgid "Procedure" +#~ msgstr "Procédure" + +#~ msgid "normal" +#~ msgstr "normal" diff --git a/src/bin/psql/po/it.po b/src/bin/psql/po/it.po index e935f8af502..58d5e381f9c 100644 --- a/src/bin/psql/po/it.po +++ b/src/bin/psql/po/it.po @@ -1,40 +1,36 @@ # -# Translation of psql to Italian -# PostgreSQL Project +# psql.po +# Italian message translation file for psql # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Cosimo D'Arcangelo -# * Massimo Mangoni -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017. +# Cosimo D'Arcangelo +# Massimo Mangoni +# Mirko Tebaldi +# Gabriele Bartolini # -# Traduttori precedenti: -# * Mirko Tebaldi -# * Gabriele Bartolini -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: psql (PostgreSQL) 10\n" +"Project-Id-Version: psql (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:45+0000\n" -"PO-Revision-Date: 2017-05-29 22:06+0100\n" +"POT-Creation-Date: 2018-10-08 14:14+0000\n" +"PO-Revision-Date: 2018-10-16 02:28+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-SourceCharset: utf-8\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -72,8 +68,7 @@ msgid "pclose failed: %s" msgstr "pclose fallita: %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:608 input.c:227 mainloop.c:82 -#: mainloop.c:276 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 #, c-format msgid "out of memory\n" msgstr "memoria esaurita\n" @@ -88,7 +83,7 @@ msgstr "impossibile duplicare il puntatore nullo (errore interno)\n" msgid "could not look up effective user ID %ld: %s" msgstr "ID utente effettivo %ld non trovato: %s" -#: ../../common/username.c:45 command.c:555 +#: ../../common/username.c:45 command.c:554 msgid "user does not exist" msgstr "l'utente non esiste" @@ -139,269 +134,270 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu riga)" msgstr[1] "(%lu righe)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:2915 #, c-format msgid "Interrupted\n" msgstr "Interrotto\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:2979 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Non è possibile aggiungere l'intestazione al contenuto della tabella: il numero di colonne %d è stato superato.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3019 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Non è possibile aggiungere celle al contenuto della tabella: il numero totale di celle %d è stato superato.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3268 #, c-format msgid "invalid output format (internal error): %d" msgstr "il formato di output non è valido (errore interno): %d" -#: ../../fe_utils/psqlscan.l:713 +#: ../../fe_utils/psqlscan.l:724 #, c-format msgid "skipping recursive expansion of variable \"%s\"\n" msgstr "espansione ricorsiva della variabile \"%s\" evitata\n" -#: command.c:223 +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "Comando errato \\%s. Prova \\? per la guida.\n" -#: command.c:225 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" msgstr "comando errato \\%s\n" -#: command.c:243 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s: parametro in eccesso \"%s\" ignorato\n" -#: command.c:295 +#: command.c:292 #, c-format msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "comando \\%s ignorato; usa \\endif o Ctrl-C per uscire dal blocco \\if corrente\n" -#: command.c:553 +#: command.c:552 #, c-format msgid "could not get home directory for user ID %ld: %s\n" msgstr "directory home non trovata per l'ID utente %ld: %s\n" -#: command.c:571 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s: spostamento della directory a \"%s\" fallito: %s\n" -#: command.c:596 common.c:648 common.c:706 common.c:1242 +#: command.c:595 common.c:696 common.c:754 common.c:1292 #, c-format msgid "You are currently not connected to a database.\n" msgstr "Al momento non sei connesso ad un database.\n" -#: command.c:621 +#: command.c:602 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Sei collegato al database \"%s\" con nome utente \"%s\" tramite il socket in \"%s\" porta \"%s\".\n" -#: command.c:624 +#: command.c:605 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Sei collegato al database \"%s\" con nome utente \"%s\" sull'host \"%s\" porta \"%s\".\n" -#: command.c:912 command.c:1002 command.c:1111 command.c:2520 +#: command.c:895 command.c:991 command.c:2376 #, c-format msgid "no query buffer\n" msgstr "Nessun buffer query\n" -#: command.c:945 command.c:4757 +#: command.c:928 command.c:4648 #, c-format msgid "invalid line number: %s\n" msgstr "numero di riga non valido: \"%s\"\n" -#: command.c:995 +#: command.c:982 #, c-format msgid "The server (version %s) does not support editing function source.\n" msgstr "Il server (versione %s) non supporta la modifica dei sorgenti delle funzioni.\n" -#: command.c:1070 command.c:1151 -msgid "No changes" -msgstr "Nessuna modifica" - -#: command.c:1104 +#: command.c:985 #, c-format msgid "The server (version %s) does not support editing view definitions.\n" msgstr "Il server (versione %s) non supporta la modifica della definizione delle viste.\n" -#: command.c:1228 +#: command.c:1067 +msgid "No changes" +msgstr "Nessuna modifica" + +#: command.c:1144 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "%s: nome codifica errato oppure non esiste una procedura di conversione\n" -#: command.c:1263 command.c:1885 command.c:3161 command.c:4859 common.c:173 -#: common.c:244 common.c:541 common.c:1288 common.c:1316 common.c:1417 -#: copy.c:489 copy.c:709 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 #, c-format msgid "%s" msgstr "%s" -#: command.c:1267 +#: command.c:1183 msgid "out of memory" msgstr "memoria esaurita" -#: command.c:1270 +#: command.c:1186 msgid "There is no previous error." msgstr "Non c'è un errore precedente." -#: command.c:1441 command.c:1746 command.c:1760 command.c:1777 command.c:1937 -#: command.c:2174 command.c:2487 command.c:2527 +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s: parametro richiesto mancante\n" -#: command.c:1572 +#: command.c:1505 #, c-format msgid "\\elif: cannot occur after \\else\n" msgstr "\\elif: non può apparire dopo \\else\n" -#: command.c:1577 +#: command.c:1510 #, c-format msgid "\\elif: no matching \\if\n" msgstr "\\elif: \\if corrispondente non trovato\n" -#: command.c:1641 +#: command.c:1574 #, c-format msgid "\\else: cannot occur after \\else\n" msgstr "\\else: non può apparire dopo \\else\n" -#: command.c:1646 +#: command.c:1579 #, c-format msgid "\\else: no matching \\if\n" msgstr "\\else: \\if corrispondente non trovato\n" -#: command.c:1686 +#: command.c:1619 #, c-format msgid "\\endif: no matching \\if\n" msgstr "\\endif: \\if corrispondente non trovato\n" -#: command.c:1841 +#: command.c:1774 msgid "Query buffer is empty." msgstr "Il buffer query è vuoto." -#: command.c:1863 +#: command.c:1796 msgid "Enter new password: " msgstr "Inserire la nuova password: " -#: command.c:1864 +#: command.c:1797 msgid "Enter it again: " msgstr "Conferma password: " -#: command.c:1868 +#: command.c:1801 #, c-format msgid "Passwords didn't match.\n" msgstr "Le password non corrispondono.\n" -#: command.c:1967 +#: command.c:1900 #, c-format msgid "\\%s: could not read value for variable\n" msgstr "\\%s: errore nella lettura del valore della variabile\n" -#: command.c:2070 +#: command.c:2003 msgid "Query buffer reset (cleared)." msgstr "Buffer query resettato (svuotato)." -#: command.c:2092 +#: command.c:2025 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Storia scritta nel file \"%s\".\n" -#: command.c:2179 +#: command.c:2112 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s: il nome della variabile d'ambiente non deve contenere \"=\"\n" -#: command.c:2235 +#: command.c:2173 #, c-format msgid "The server (version %s) does not support showing function source.\n" msgstr "Il server (versione %s) non supporta la visualizzazione dei sorgenti delle funzioni.\n" -#: command.c:2242 -#, c-format -msgid "function name is required\n" -msgstr "il nome della funzione è richiesto\n" - -#: command.c:2329 +#: command.c:2176 #, c-format msgid "The server (version %s) does not support showing view definitions.\n" msgstr "-\"Il server (versione %s) non supporta la visualizzazione della definizione delle viste.\n" -#: command.c:2336 +#: command.c:2183 +#, c-format +msgid "function name is required\n" +msgstr "il nome della funzione è richiesto\n" + +#: command.c:2185 #, c-format msgid "view name is required\n" msgstr "il nome della vista è richiesto\n" -#: command.c:2459 +#: command.c:2315 msgid "Timing is on." msgstr "Controllo tempo attivato" -#: command.c:2461 +#: command.c:2317 msgid "Timing is off." msgstr "Controllo tempo disattivato." -#: command.c:2546 command.c:2574 command.c:3510 command.c:3513 command.c:3516 -#: command.c:3522 command.c:3524 command.c:3532 command.c:3542 command.c:3551 -#: command.c:3565 command.c:3582 command.c:3640 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:760 psqlscanslash.l:771 -#: psqlscanslash.l:781 +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:2953 startup.c:202 +#: command.c:2814 startup.c:214 startup.c:265 msgid "Password: " msgstr "Password: " -#: command.c:2958 startup.c:204 +#: command.c:2819 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "Inserisci la password per l'utente %s: " -#: command.c:3008 +#: command.c:2869 #, c-format msgid "All connection parameters must be supplied because no database connection exists\n" msgstr "Tutti i parametri di connessione devono essere forniti perché non esiste alcuna connessione di database\n" -#: command.c:3165 +#: command.c:3037 #, c-format msgid "Previous connection kept\n" msgstr "Connessione precedente mantenuta\n" -#: command.c:3169 +#: command.c:3041 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:3205 +#: command.c:3077 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" msgstr "Adesso sei collegato al database \"%s\" con nome utente \"%s\" tramite socket \"%s\" porta \"%s\".\n" -#: command.c:3208 +#: command.c:3080 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" msgstr "Adesso sei collegato al database \"%s\" con nome utente \"%s\" sull'host \"%s\" porta \"%s\".\n" -#: command.c:3212 +#: command.c:3084 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Sei collegato al database \"%s\" con nome utente \"%s\".\n" -#: command.c:3245 +#: command.c:3117 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, server %s)\n" -#: command.c:3253 +#: command.c:3125 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -410,24 +406,24 @@ msgstr "" "ATTENZIONE: versione maggiore %s %s, versione maggiore server %s.\n" " Alcune caratteristiche di psql potrebbero non funzionare.\n" -#: command.c:3290 +#: command.c:3162 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "connessione SSL (protocollo: %s, cifrario: %s, bit: %s, compressione: %s)\n" -#: command.c:3291 command.c:3292 command.c:3293 +#: command.c:3163 command.c:3164 command.c:3165 msgid "unknown" msgstr "sconosciuto" -#: command.c:3294 help.c:45 +#: command.c:3166 help.c:45 msgid "off" msgstr "disattivato" -#: command.c:3294 help.c:45 +#: command.c:3166 help.c:45 msgid "on" msgstr "attivato" -#: command.c:3314 +#: command.c:3186 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -439,239 +435,239 @@ msgstr "" " funzionare correttamente. Vedi le pagine di riferimento\n" " psql \"Note per utenti Windows\" per i dettagli.\n" -#: command.c:3399 +#: command.c:3290 #, c-format msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" msgstr "la variabile di ambiente PSQL_EDITOR_LINENUMBER_ARG deve specificare un numero di riga\n" -#: command.c:3428 +#: command.c:3319 #, c-format msgid "could not start editor \"%s\"\n" msgstr "avvio dell'editor \"%s\" fallito\n" -#: command.c:3430 +#: command.c:3321 #, c-format msgid "could not start /bin/sh\n" msgstr "avvio di /bin/sh fallito\n" -#: command.c:3468 +#: command.c:3359 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "directory temporanea non trovata: %s\n" -#: command.c:3495 +#: command.c:3386 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "apertura del file temporaneo \"%s\" fallita: %s\n" -#: command.c:3769 +#: command.c:3660 #, c-format msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" msgstr "\\pset: i formati consentiti sono unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" -#: command.c:3787 +#: command.c:3678 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "\\pset: gli stili di linea permessi sono ascii, old-ascii, unicode\n" -#: command.c:3802 +#: command.c:3693 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double\n" msgstr "\\pset: gli stili riga Unicode dei bordi consentiti sono single, double\n" -#: command.c:3817 +#: command.c:3708 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double\n" msgstr "\\pset: gli stili riga Unicode delle colonne consentiti sono single, double\n" -#: command.c:3832 +#: command.c:3723 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double\n" msgstr "\\pset: gli stili riga Unicode delle intestazioni consentiti sono single, double\n" -#: command.c:3997 command.c:4176 +#: command.c:3888 command.c:4067 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "\\pset: opzione sconosciuta: %s\n" -#: command.c:4015 +#: command.c:3906 #, c-format msgid "Border style is %d.\n" msgstr "Lo stile del bordo è %d.\n" -#: command.c:4021 +#: command.c:3912 #, c-format msgid "Target width is unset.\n" msgstr "La lunghezza di destinazione non è impostata.\n" -#: command.c:4023 +#: command.c:3914 #, c-format msgid "Target width is %d.\n" msgstr "La larghezza di destinazione è %d.\n" -#: command.c:4030 +#: command.c:3921 #, c-format msgid "Expanded display is on.\n" msgstr "La visualizzazione espansa è attiva.\n" -#: command.c:4032 +#: command.c:3923 #, c-format msgid "Expanded display is used automatically.\n" msgstr "La visualizzazione espansa è usata automaticamente.\n" -#: command.c:4034 +#: command.c:3925 #, c-format msgid "Expanded display is off.\n" msgstr "La visualizzazione espansa è disattivata.\n" -#: command.c:4041 command.c:4049 +#: command.c:3932 command.c:3940 #, c-format msgid "Field separator is zero byte.\n" msgstr "Il separatore di campo è il byte zero.\n" -#: command.c:4043 +#: command.c:3934 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Il separatore di campo è \"%s\".\n" -#: command.c:4056 +#: command.c:3947 #, c-format msgid "Default footer is on.\n" msgstr "Il piè di pagina di default è attivo.\n" -#: command.c:4058 +#: command.c:3949 #, c-format msgid "Default footer is off.\n" msgstr "Il piè di pagina di default è disattivato.\n" -#: command.c:4064 +#: command.c:3955 #, c-format msgid "Output format is %s.\n" msgstr "Il formato di output è %s.\n" -#: command.c:4070 +#: command.c:3961 #, c-format msgid "Line style is %s.\n" msgstr "Lo stile della linea è %s.\n" -#: command.c:4077 +#: command.c:3968 #, c-format msgid "Null display is \"%s\".\n" msgstr "La visualizzazione dei null è \"%s\".\n" -#: command.c:4085 +#: command.c:3976 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "La correzione dell'output numerico secondo il locale è attiva.\n" -#: command.c:4087 +#: command.c:3978 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "La correzione dell'output numerico secondo il locale è disattivata.\n" -#: command.c:4094 +#: command.c:3985 #, c-format msgid "Pager is used for long output.\n" msgstr "Usa la paginazione per risultati estesi.\n" -#: command.c:4096 +#: command.c:3987 #, c-format msgid "Pager is always used.\n" msgstr "Paginazione sempre attiva.\n" -#: command.c:4098 +#: command.c:3989 #, c-format msgid "Pager usage is off.\n" msgstr "Paginazione disattivata.\n" -#: command.c:4104 +#: command.c:3995 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "La paginazione non verrà usata per meno di %d riga.\n" msgstr[1] "La paginazione non verrà usata per meno di %d righe.\n" -#: command.c:4114 command.c:4124 +#: command.c:4005 command.c:4015 #, c-format msgid "Record separator is zero byte.\n" msgstr "Il separatore di record è il byte zero.\n" -#: command.c:4116 +#: command.c:4007 #, c-format msgid "Record separator is .\n" msgstr "Il separatore di record è .\n" -#: command.c:4118 +#: command.c:4009 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Il separatore di record è \"%s\".\n" -#: command.c:4131 +#: command.c:4022 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Gli attributi di tabella sono \"%s\".\n" -#: command.c:4134 +#: command.c:4025 #, c-format msgid "Table attributes unset.\n" msgstr "Gli attributi di tabella non sono specificati.\n" -#: command.c:4141 +#: command.c:4032 #, c-format msgid "Title is \"%s\".\n" msgstr "Il titolo è \"%s\".\n" -#: command.c:4143 +#: command.c:4034 #, c-format msgid "Title is unset.\n" msgstr "Il titolo non è assegnato.\n" -#: command.c:4150 +#: command.c:4041 #, c-format msgid "Tuples only is on.\n" msgstr "La visualizzazione dei soli dati è attiva.\n" -#: command.c:4152 +#: command.c:4043 #, c-format msgid "Tuples only is off.\n" msgstr "La visualizzazione dei soli dati è disattivata.\n" -#: command.c:4158 +#: command.c:4049 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Lo stile riga Unicode dei bordi è \"%s\".\n" -#: command.c:4164 +#: command.c:4055 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Lo stile riga Unicode delle colonne è \"%s\".\n" -#: command.c:4170 +#: command.c:4061 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Lo stile riga Unicode delle intestazioni è \"%s\".\n" -#: command.c:4330 +#: command.c:4221 #, c-format msgid "\\!: failed\n" msgstr "\\!: fallita\n" -#: command.c:4355 common.c:754 +#: command.c:4246 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch non può essere usato con una query vuota\n" -#: command.c:4396 +#: command.c:4287 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (ogni %gs)\n" -#: command.c:4399 +#: command.c:4290 #, c-format msgid "%s (every %gs)\n" msgstr "%s (ogni %gs)\n" -#: command.c:4453 command.c:4460 common.c:654 common.c:661 common.c:1271 +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1321 #, c-format msgid "" "********* QUERY **********\n" @@ -684,102 +680,102 @@ msgstr "" "**************************\n" "\n" -#: command.c:4652 +#: command.c:4543 #, c-format msgid "\"%s.%s\" is not a view\n" msgstr "\"%s.%s\" non è una vista\n" -#: command.c:4668 +#: command.c:4559 #, c-format msgid "could not parse reloptions array\n" msgstr "interpretazione dell'array reloptions fallita\n" -#: common.c:158 +#: common.c:159 #, c-format msgid "cannot escape without active connection\n" msgstr "non è possibile effettuare l'escape senza una connessione attiva\n" -#: common.c:199 +#: common.c:200 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "l'argomento del comando shell contiene un \"a capo\" o un ritorno carrello: \"%s\"\n" -#: common.c:415 +#: common.c:416 #, c-format msgid "connection to server was lost\n" msgstr "connessione al server persa\n" -#: common.c:419 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Connessione al server persa. Tentativo di reset: " -#: common.c:424 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "Fallito.\n" -#: common.c:431 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "Riuscito.\n" -#: common.c:531 common.c:1034 common.c:1206 +#: common.c:532 common.c:1082 common.c:1256 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "PQresultStatus imprevisto: %d\n" -#: common.c:593 +#: common.c:641 #, c-format msgid "Time: %.3f ms\n" msgstr "Tempo: %.3f ms\n" -#: common.c:608 +#: common.c:656 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Tempo: %.3f ms (%02d:%06.3f)\n" -#: common.c:617 +#: common.c:665 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Tempo: %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:624 +#: common.c:672 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Tempo: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:761 +#: common.c:809 #, c-format msgid "\\watch cannot be used with COPY\n" msgstr "\\watch non può essere usato con COPY\n" -#: common.c:766 +#: common.c:814 #, c-format msgid "unexpected result status for \\watch\n" msgstr "risultato imprevisto per \\watch\n" -#: common.c:795 +#: common.c:843 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Notifica asincrona \"%s\" con payload \"%s\" ricevuta dal processo server con PID %d.\n" -#: common.c:798 +#: common.c:846 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Notifica asincrona \"%s\" ricevuta dal processo server con PID %d.\n" -#: common.c:860 +#: common.c:908 #, c-format msgid "no rows returned for \\gset\n" msgstr "nessuna riga restituita per \\gset\n" -#: common.c:865 +#: common.c:913 #, c-format msgid "more than one row returned for \\gset\n" msgstr "più di una riga restituita per \\gset\n" -#: common.c:1251 +#: common.c:1301 #, c-format msgid "" "***(Single step mode: verify command)*******************************************\n" @@ -790,21 +786,37 @@ msgstr "" "%s\n" "***(premi invio per procedere oppure digita x ed invio per annullare)***********\n" -#: common.c:1306 +#: common.c:1356 #, c-format msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" msgstr "Il server (versione %s) non supporta savepoint per ON_ERROR_ROLLBACK.\n" -#: common.c:1362 +#: common.c:1419 #, c-format msgid "STATEMENT: %s\n" msgstr "COMANDO: %s\n" -#: common.c:1405 +#: common.c:1462 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "stato della transazione imprevisto (%d)\n" +#: common.c:1599 describe.c:1941 +msgid "Column" +msgstr "Colonna" + +#: common.c:1600 describe.c:175 describe.c:390 describe.c:408 describe.c:453 +#: describe.c:470 describe.c:959 describe.c:1123 describe.c:1664 +#: describe.c:1688 describe.c:1942 describe.c:3529 describe.c:3734 +#: describe.c:4925 +msgid "Type" +msgstr "Tipo" + +#: common.c:1649 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Il comando non ha prodotto risultati, o il risultato non ha colonne.\n" + #: copy.c:99 #, c-format msgid "\\copy: arguments required\n" @@ -862,11 +874,11 @@ msgstr "" "Inserire i dati da copiare seguiti da un \"a capo\".\n" "Terminare con un backslash ed un punto su una singola riga, o un segnale EOF." -#: copy.c:671 +#: copy.c:670 msgid "aborted because of read failure" msgstr "interrotto a causa di lettura non riuscita" -#: copy.c:705 +#: copy.c:704 msgid "trying to exit copy mode" msgstr "tentativo di uscita dalla modalità copy" @@ -915,990 +927,1026 @@ msgstr "\\crosstabview: nome di colonna ambiguo: \"%s\"\n" msgid "\\crosstabview: column name not found: \"%s\"\n" msgstr "\\crosstabview: colonna non trovata: \"%s\"\n" -#: describe.c:73 describe.c:342 describe.c:599 describe.c:730 describe.c:874 -#: describe.c:1035 describe.c:1107 describe.c:3332 describe.c:3538 -#: describe.c:3629 describe.c:3877 describe.c:4022 describe.c:4254 -#: describe.c:4329 describe.c:4340 describe.c:4402 describe.c:4822 -#: describe.c:4905 +#: describe.c:75 describe.c:370 describe.c:675 describe.c:807 describe.c:951 +#: describe.c:1112 describe.c:1184 describe.c:3518 describe.c:3732 +#: describe.c:3823 describe.c:4090 describe.c:4235 describe.c:4476 +#: describe.c:4551 describe.c:4562 describe.c:4624 describe.c:5049 +#: describe.c:5132 msgid "Schema" msgstr "Schema" -#: describe.c:74 describe.c:162 describe.c:228 describe.c:236 describe.c:343 -#: describe.c:600 describe.c:731 describe.c:792 describe.c:875 describe.c:1108 -#: describe.c:3333 describe.c:3461 describe.c:3539 describe.c:3630 -#: describe.c:3709 describe.c:3878 describe.c:3947 describe.c:4023 -#: describe.c:4255 describe.c:4330 describe.c:4341 describe.c:4403 -#: describe.c:4595 describe.c:4679 describe.c:4903 describe.c:5071 -#: describe.c:5262 +#: describe.c:76 describe.c:173 describe.c:240 describe.c:248 describe.c:371 +#: describe.c:676 describe.c:808 describe.c:869 describe.c:952 describe.c:1185 +#: describe.c:3519 describe.c:3655 describe.c:3733 describe.c:3824 +#: describe.c:3903 describe.c:4091 describe.c:4160 describe.c:4236 +#: describe.c:4477 describe.c:4552 describe.c:4563 describe.c:4625 +#: describe.c:4822 describe.c:4906 describe.c:5130 describe.c:5302 +#: describe.c:5527 msgid "Name" msgstr "Nome" -#: describe.c:75 describe.c:355 describe.c:401 describe.c:418 +#: describe.c:77 describe.c:383 describe.c:401 describe.c:447 describe.c:464 msgid "Result data type" msgstr "Tipo dato del risultato" -#: describe.c:83 describe.c:96 describe.c:100 describe.c:356 describe.c:402 -#: describe.c:419 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:384 describe.c:402 +#: describe.c:448 describe.c:465 msgid "Argument data types" msgstr "Tipo dato dei parametri" -#: describe.c:107 describe.c:172 describe.c:259 describe.c:464 describe.c:648 -#: describe.c:746 describe.c:817 describe.c:1110 describe.c:1746 -#: describe.c:3132 describe.c:3367 describe.c:3492 describe.c:3566 -#: describe.c:3639 describe.c:3722 describe.c:3790 describe.c:3890 -#: describe.c:3956 describe.c:4024 describe.c:4160 describe.c:4200 -#: describe.c:4271 describe.c:4333 describe.c:4342 describe.c:4404 -#: describe.c:4621 describe.c:4701 describe.c:4836 describe.c:4906 +#: describe.c:110 describe.c:117 describe.c:183 describe.c:271 describe.c:510 +#: describe.c:724 describe.c:823 describe.c:894 describe.c:1187 describe.c:1960 +#: describe.c:3307 describe.c:3554 describe.c:3686 describe.c:3760 +#: describe.c:3833 describe.c:3916 describe.c:3999 describe.c:4103 +#: describe.c:4169 describe.c:4237 describe.c:4378 describe.c:4420 +#: describe.c:4493 describe.c:4555 describe.c:4564 describe.c:4626 +#: describe.c:4848 describe.c:4928 describe.c:5063 describe.c:5133 #: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "Descrizione" -#: describe.c:125 +#: describe.c:135 msgid "List of aggregate functions" msgstr "Lista delle funzione aggregate" -#: describe.c:149 +#: describe.c:160 #, c-format msgid "The server (version %s) does not support access methods.\n" msgstr "Il server (versione %s) non supporta metodi di accesso.\n" -#: describe.c:163 +#: describe.c:174 msgid "Index" msgstr "Indice" -#: describe.c:164 describe.c:362 describe.c:407 describe.c:424 describe.c:882 -#: describe.c:1046 describe.c:1706 describe.c:3342 describe.c:3540 -#: describe.c:4698 -msgid "Type" -msgstr "Tipo" - -#: describe.c:171 describe.c:4600 +#: describe.c:182 describe.c:4827 msgid "Handler" msgstr "Handler" -#: describe.c:190 +#: describe.c:201 msgid "List of access methods" msgstr "Lista dei metodi di accesso" -#: describe.c:215 +#: describe.c:227 #, c-format msgid "The server (version %s) does not support tablespaces.\n" msgstr "Il server (versione %s) non supporta i tablespace.\n" -#: describe.c:229 describe.c:237 describe.c:452 describe.c:638 describe.c:793 -#: describe.c:1034 describe.c:3343 describe.c:3465 describe.c:3711 -#: describe.c:3948 describe.c:4596 describe.c:4680 describe.c:5072 -#: describe.c:5263 large_obj.c:288 +#: describe.c:241 describe.c:249 describe.c:498 describe.c:714 describe.c:870 +#: describe.c:1111 describe.c:3530 describe.c:3659 describe.c:3905 +#: describe.c:4161 describe.c:4823 describe.c:4907 describe.c:5303 +#: describe.c:5429 describe.c:5528 large_obj.c:288 msgid "Owner" msgstr "Proprietario" -#: describe.c:230 describe.c:238 +#: describe.c:242 describe.c:250 msgid "Location" msgstr "Posizione" -#: describe.c:249 describe.c:2947 +#: describe.c:261 describe.c:3126 msgid "Options" msgstr "Opzioni" -#: describe.c:254 describe.c:611 describe.c:809 describe.c:3359 describe.c:3363 +#: describe.c:266 describe.c:687 describe.c:886 describe.c:3546 describe.c:3550 msgid "Size" msgstr "Dimensione" -#: describe.c:276 +#: describe.c:288 msgid "List of tablespaces" msgstr "Lista dei tablespace" -#: describe.c:316 +#: describe.c:330 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df accetta come opzione solo [antwS+]\n" +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df accetta come opzioni solo [anptwS+]\n" -#: describe.c:324 +#: describe.c:338 describe.c:349 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df non accetta un'opzione \"w\" con il server in versione %s\n" +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "\\df non accetta un'opzione \"%c\" con il server in versione %s\n" #. translator: "agg" is short for "aggregate" -#: describe.c:358 describe.c:404 describe.c:421 +#: describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "agg" msgstr "aggr" -#: describe.c:359 +#: describe.c:387 describe.c:405 msgid "window" msgstr "finestra" -#: describe.c:360 describe.c:405 describe.c:422 describe.c:1244 +#: describe.c:388 +msgid "proc" +msgstr "procedura" + +#: describe.c:389 describe.c:407 describe.c:452 describe.c:469 +msgid "func" +msgstr "funzione" + +#: describe.c:406 describe.c:451 describe.c:468 describe.c:1321 msgid "trigger" msgstr "trigger" -#: describe.c:361 describe.c:406 describe.c:423 -msgid "normal" -msgstr "normale" - -#: describe.c:434 +#: describe.c:480 msgid "immutable" msgstr "immutabile" -#: describe.c:435 +#: describe.c:481 msgid "stable" msgstr "stabile" -#: describe.c:436 +#: describe.c:482 msgid "volatile" msgstr "volatile" -#: describe.c:437 +#: describe.c:483 msgid "Volatility" msgstr "Volatilità" -#: describe.c:445 +#: describe.c:491 msgid "restricted" msgstr "ristretta" -#: describe.c:446 +#: describe.c:492 msgid "safe" msgstr "sicura" -#: describe.c:447 +#: describe.c:493 msgid "unsafe" msgstr "non sicura" -#: describe.c:448 +#: describe.c:494 msgid "Parallel" msgstr "Parallela" -#: describe.c:453 +#: describe.c:499 msgid "definer" msgstr "definitore" -#: describe.c:454 +#: describe.c:500 msgid "invoker" msgstr "invocatore" -#: describe.c:455 +#: describe.c:501 msgid "Security" msgstr "Sicurezza" -#: describe.c:462 +#: describe.c:508 msgid "Language" msgstr "Linguaggio" -#: describe.c:463 +#: describe.c:509 msgid "Source code" msgstr "Codice sorgente" -#: describe.c:562 +#: describe.c:638 msgid "List of functions" msgstr "Lista delle funzioni" -#: describe.c:610 +#: describe.c:686 msgid "Internal name" msgstr "Nome interno" -#: describe.c:632 +#: describe.c:708 msgid "Elements" msgstr "Elementi" -#: describe.c:689 +#: describe.c:765 msgid "List of data types" msgstr "Lista dei tipi di dati" -#: describe.c:732 +#: describe.c:809 msgid "Left arg type" msgstr "Argomento sinistro" -#: describe.c:733 +#: describe.c:810 msgid "Right arg type" msgstr "Argomento destro" -#: describe.c:734 +#: describe.c:811 msgid "Result type" msgstr "Tipo di risultato" -#: describe.c:739 describe.c:3781 describe.c:4159 +#: describe.c:816 describe.c:3911 describe.c:3976 describe.c:3982 +#: describe.c:4377 msgid "Function" msgstr "Funzione" -#: describe.c:764 +#: describe.c:841 msgid "List of operators" msgstr "Lista degli operatori" -#: describe.c:794 +#: describe.c:871 msgid "Encoding" msgstr "Codifica" -#: describe.c:799 describe.c:3879 +#: describe.c:876 describe.c:4092 msgid "Collate" msgstr "Ordinamento" -#: describe.c:800 describe.c:3880 +#: describe.c:877 describe.c:4093 msgid "Ctype" msgstr "Ctype" -#: describe.c:813 +#: describe.c:890 msgid "Tablespace" msgstr "Tablespace" -#: describe.c:835 +#: describe.c:912 msgid "List of databases" msgstr "Lista dei database" -#: describe.c:876 describe.c:881 describe.c:1037 describe.c:3334 -#: describe.c:3341 +#: describe.c:953 describe.c:958 describe.c:1114 describe.c:3520 +#: describe.c:3527 msgid "table" msgstr "tabella" -#: describe.c:877 describe.c:3335 +#: describe.c:954 describe.c:3521 msgid "view" msgstr "vista" -#: describe.c:878 describe.c:3336 +#: describe.c:955 describe.c:3522 msgid "materialized view" msgstr "vista materializzata" -#: describe.c:879 describe.c:1039 describe.c:3338 +#: describe.c:956 describe.c:1116 describe.c:3524 msgid "sequence" msgstr "sequenza" -#: describe.c:880 describe.c:3340 +#: describe.c:957 describe.c:3526 msgid "foreign table" msgstr "tabella esterna" -#: describe.c:893 +#: describe.c:970 msgid "Column privileges" msgstr "Privilegi di colonna" -#: describe.c:924 describe.c:958 +#: describe.c:1001 describe.c:1035 msgid "Policies" msgstr "Regole di sicurezza" -#: describe.c:990 describe.c:5319 describe.c:5323 +#: describe.c:1067 describe.c:5584 describe.c:5588 msgid "Access privileges" msgstr "Privilegi di accesso" -#: describe.c:1021 +#: describe.c:1098 #, c-format msgid "The server (version %s) does not support altering default privileges.\n" msgstr "Il server (versione %s) non supporta la modifica dei privilegi di default.\n" -#: describe.c:1041 +#: describe.c:1118 msgid "function" msgstr "funzione" -#: describe.c:1043 +#: describe.c:1120 msgid "type" msgstr "tipo" -#: describe.c:1045 +#: describe.c:1122 msgid "schema" msgstr "schema" -#: describe.c:1069 +#: describe.c:1146 msgid "Default access privileges" msgstr "Privilegi di accesso di default" -#: describe.c:1109 +#: describe.c:1186 msgid "Object" msgstr "Oggetto" -#: describe.c:1123 +#: describe.c:1200 msgid "table constraint" msgstr "vincolo di tabella" -#: describe.c:1145 +#: describe.c:1222 msgid "domain constraint" msgstr "vincolo di dominio" -#: describe.c:1173 +#: describe.c:1250 msgid "operator class" msgstr "classe operatori" -#: describe.c:1202 +#: describe.c:1279 msgid "operator family" msgstr "famiglia operatori" -#: describe.c:1224 +#: describe.c:1301 msgid "rule" msgstr "regola" -#: describe.c:1266 +#: describe.c:1343 msgid "Object descriptions" msgstr "Descrizioni oggetti" -#: describe.c:1320 +#: describe.c:1399 describe.c:3618 #, c-format msgid "Did not find any relation named \"%s\".\n" -msgstr "Non ho trovato alcuna relazione di nome \"%s\".\n" +msgstr "Non è stata trovata nessuna relazione chiamata \"%s\".\n" + +#: describe.c:1402 describe.c:3621 +#, c-format +msgid "Did not find any relations.\n" +msgstr "Non è stata trovata nessuna relazione.\n" -#: describe.c:1529 +#: describe.c:1619 #, c-format msgid "Did not find any relation with OID %s.\n" -msgstr "Non ho trovato nessuna relazione con OID %s.\n" +msgstr "Non è stata trovata nessuna relazione con OID %s.\n" + +#: describe.c:1665 describe.c:1689 +msgid "Start" +msgstr "Inizio" + +#: describe.c:1666 describe.c:1690 +msgid "Minimum" +msgstr "Minimo" + +#: describe.c:1667 describe.c:1691 +msgid "Maximum" +msgstr "Massimo" + +#: describe.c:1668 describe.c:1692 +msgid "Increment" +msgstr "Incremento" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3827 +#: describe.c:3993 +msgid "yes" +msgstr "sì" + +#: describe.c:1670 describe.c:1694 describe.c:1819 describe.c:3827 +#: describe.c:3990 +msgid "no" +msgstr "no" + +#: describe.c:1671 describe.c:1695 +msgid "Cycles?" +msgstr "Riparte?" + +#: describe.c:1672 describe.c:1696 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1739 +#, c-format +msgid "Owned by: %s" +msgstr "Proprietario: %s" + +#: describe.c:1743 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Sequenza per la colonna identità: %s" + +#: describe.c:1750 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sequenza \"%s.%s\"" -#: describe.c:1642 describe.c:1691 +#: describe.c:1880 describe.c:1926 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Tabella non loggata \"%s.%s\"" -#: describe.c:1645 describe.c:1694 +#: describe.c:1883 describe.c:1929 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabella \"%s.%s\"" -#: describe.c:1649 +#: describe.c:1887 #, c-format msgid "View \"%s.%s\"" msgstr "Vista \"%s.%s\"" -#: describe.c:1654 +#: describe.c:1892 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Vista materializzata non loggata \"%s.%s\"" -#: describe.c:1657 +#: describe.c:1895 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Vista materializzata \"%s.%s\"" -#: describe.c:1661 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Sequenza \"%s.%s\"" - -#: describe.c:1666 +#: describe.c:1901 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Indice non loggato \"%s.%s\"" -#: describe.c:1669 +#: describe.c:1904 #, c-format msgid "Index \"%s.%s\"" msgstr "Indice \"%s.%s\"" -#: describe.c:1674 +#: describe.c:1909 #, c-format msgid "Special relation \"%s.%s\"" msgstr "relazione speciale \"%s.%s\"" -#: describe.c:1678 +#: describe.c:1913 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "Tabella TOAST \"%s.%s\"" -#: describe.c:1682 +#: describe.c:1917 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Tipo composito \"%s.%s\"" -#: describe.c:1686 +#: describe.c:1921 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Tabella esterna \"%s.%s\"" -#: describe.c:1705 -msgid "Column" -msgstr "Colonna" - -#: describe.c:1716 describe.c:3546 +#: describe.c:1945 describe.c:3740 msgid "Collation" msgstr "Ordinamento" -#: describe.c:1717 describe.c:3553 +#: describe.c:1946 describe.c:3747 msgid "Nullable" msgstr "Può essere null" -#: describe.c:1718 describe.c:3554 +#: describe.c:1947 describe.c:3748 msgid "Default" msgstr "Default" -#: describe.c:1723 -msgid "Value" -msgstr "Valore" +#: describe.c:1950 +msgid "Key?" +msgstr "Chiave?" -#: describe.c:1726 +#: describe.c:1952 msgid "Definition" msgstr "Definizione" -#: describe.c:1729 describe.c:4616 describe.c:4700 describe.c:4771 -#: describe.c:4835 -msgid "FDW Options" +#: describe.c:1954 describe.c:4843 describe.c:4927 describe.c:4998 +#: describe.c:5062 +msgid "FDW options" msgstr "Opzioni FDW" -#: describe.c:1733 +#: describe.c:1956 msgid "Storage" msgstr "Memorizzazione" -#: describe.c:1738 +#: describe.c:1958 msgid "Stats target" msgstr "Dest. stat." -#: describe.c:1893 +#: describe.c:2072 #, c-format msgid "Partition of: %s %s" msgstr "Partizione di: %s %s" -#: describe.c:1899 +#: describe.c:2080 +msgid "No partition constraint" +msgstr "Nessun vincolo di partizione" + +#: describe.c:2082 #, c-format msgid "Partition constraint: %s" msgstr "Vincolo di partizione: %s" -#: describe.c:1922 +#: describe.c:2105 #, c-format msgid "Partition key: %s" msgstr "Chiave di partizione: %s" -#: describe.c:1990 +#: describe.c:2174 msgid "primary key, " msgstr "chiave primaria, " -#: describe.c:1992 +#: describe.c:2176 msgid "unique, " msgstr "univoco, " -#: describe.c:1998 +#: describe.c:2182 #, c-format msgid "for table \"%s.%s\"" msgstr "per la tabella \"%s.%s\"" -#: describe.c:2002 +#: describe.c:2186 #, c-format msgid ", predicate (%s)" msgstr ", predicato (%s)" -#: describe.c:2005 +#: describe.c:2189 msgid ", clustered" msgstr ", raggruppato" -#: describe.c:2008 +#: describe.c:2192 msgid ", invalid" msgstr ", non valido" -#: describe.c:2011 +#: describe.c:2195 msgid ", deferrable" msgstr ", deferibile" -#: describe.c:2014 +#: describe.c:2198 msgid ", initially deferred" msgstr ", inizialmente deferito" -#: describe.c:2017 +#: describe.c:2201 msgid ", replica identity" msgstr ", identità di replica" -#: describe.c:2056 -#, c-format -msgid "Owned by: %s" -msgstr "Proprietario: %s" - -#: describe.c:2061 -#, c-format -msgid "Sequence for identity column: %s" -msgstr "Sequenza per la colonna identità: %s" - -#: describe.c:2125 +#: describe.c:2260 msgid "Indexes:" msgstr "Indici:" -#: describe.c:2209 +#: describe.c:2344 msgid "Check constraints:" msgstr "Vincoli di controllo:" -#: describe.c:2240 +#: describe.c:2380 msgid "Foreign-key constraints:" msgstr "Vincoli di integrità referenziale" -#: describe.c:2271 +#: describe.c:2411 msgid "Referenced by:" msgstr "Referenziato da:" -#: describe.c:2331 +#: describe.c:2461 msgid "Policies:" msgstr "Regole di sicurezza:" -#: describe.c:2334 +#: describe.c:2464 msgid "Policies (forced row security enabled):" msgstr "Regole (sicurezza per riga forzata abilitata):" -#: describe.c:2337 +#: describe.c:2467 msgid "Policies (row security enabled): (none)" msgstr "Regole (sicurezza per riga abilitata): (nessuna)" -#: describe.c:2340 +#: describe.c:2470 msgid "Policies (forced row security enabled): (none)" msgstr "Regole (sicurezza per riga forzata abilitata): (nessuna)" -#: describe.c:2343 +#: describe.c:2473 msgid "Policies (row security disabled):" msgstr "Regole (sicurezza per riga disabilitata):" -#: describe.c:2405 +#: describe.c:2535 msgid "Statistics objects:" msgstr "Oggetti statistiche:" -#: describe.c:2508 describe.c:2590 +#: describe.c:2638 describe.c:2742 msgid "Rules:" msgstr "Regole:" -#: describe.c:2511 +#: describe.c:2641 msgid "Disabled rules:" msgstr "Regole disabilitate:" -#: describe.c:2514 +#: describe.c:2644 msgid "Rules firing always:" msgstr "Regole sempre abilitate:" -#: describe.c:2517 +#: describe.c:2647 msgid "Rules firing on replica only:" msgstr "Regole abilitate solo su replica:" -#: describe.c:2554 +#: describe.c:2687 msgid "Publications:" msgstr "Pubblicazioni:" -#: describe.c:2573 +#: describe.c:2725 msgid "View definition:" msgstr "Definizione vista:" -#: describe.c:2708 +#: describe.c:2864 msgid "Triggers:" msgstr "Trigger:" -#: describe.c:2712 +#: describe.c:2868 msgid "Disabled user triggers:" msgstr "Trigger utente disabilitati:" -#: describe.c:2714 +#: describe.c:2870 msgid "Disabled triggers:" msgstr "Trigger disabilitati:" -#: describe.c:2717 +#: describe.c:2873 msgid "Disabled internal triggers:" msgstr "Trigger interni disabilitati:" -#: describe.c:2720 +#: describe.c:2876 msgid "Triggers firing always:" msgstr "Trigger sempre abilitati:" -#: describe.c:2723 +#: describe.c:2879 msgid "Triggers firing on replica only:" msgstr "Trigger abilitati solo su replica." -#: describe.c:2782 +#: describe.c:2938 #, c-format msgid "Server: %s" msgstr "Server: %s" -#: describe.c:2790 +#: describe.c:2946 #, c-format -msgid "FDW Options: (%s)" -msgstr "Opzioni FDW: (%s)" +msgid "FDW options: (%s)" +msgstr "Opzioni FDW (%s)" -#: describe.c:2809 +#: describe.c:2965 msgid "Inherits" msgstr "Eredita" -#: describe.c:2863 +#: describe.c:3024 +#, c-format +msgid "Number of partitions: %d" +msgstr "Numero di partizioni: %d" + +#: describe.c:3033 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Numero di tabelle figlio: %d (Usa \\d+ per elencarle.)" -#: describe.c:2865 +#: describe.c:3035 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Numero di partizioni: %d (Usa \\d+ per elencarle.)" -#: describe.c:2873 +#: describe.c:3043 msgid "Child tables" msgstr "Tabelle figlio" -#: describe.c:2873 +#: describe.c:3043 msgid "Partitions" msgstr "Partizioni" -#: describe.c:2907 +#: describe.c:3086 #, c-format msgid "Typed table of type: %s" msgstr "Tabella di tipo: %s" -#: describe.c:2923 +#: describe.c:3102 msgid "Replica Identity" msgstr "Identità di replica" -#: describe.c:2936 +#: describe.c:3115 msgid "Has OIDs: yes" msgstr "Ha OID: sì" -#: describe.c:3020 +#: describe.c:3195 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tablespace: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3032 +#: describe.c:3207 #, c-format msgid ", tablespace \"%s\"" msgstr ", tablespace \"%s\"" -#: describe.c:3125 +#: describe.c:3300 msgid "List of roles" msgstr "Lista dei ruoli" -#: describe.c:3127 +#: describe.c:3302 msgid "Role name" msgstr "Nome ruolo" -#: describe.c:3128 +#: describe.c:3303 msgid "Attributes" msgstr "Attributi" -#: describe.c:3129 +#: describe.c:3304 msgid "Member of" msgstr "Membro di" -#: describe.c:3140 +#: describe.c:3315 msgid "Superuser" msgstr "Superutente" -#: describe.c:3143 +#: describe.c:3318 msgid "No inheritance" msgstr "Nessuna ereditarietà" -#: describe.c:3146 +#: describe.c:3321 msgid "Create role" msgstr "Crea ruoli" -#: describe.c:3149 +#: describe.c:3324 msgid "Create DB" msgstr "Crea DB" -#: describe.c:3152 +#: describe.c:3327 msgid "Cannot login" msgstr "Login non possibile" -#: describe.c:3156 +#: describe.c:3331 msgid "Replication" msgstr "Replica" -#: describe.c:3160 +#: describe.c:3335 msgid "Bypass RLS" msgstr "Scavalca RLS" -#: describe.c:3169 +#: describe.c:3344 msgid "No connections" msgstr "Niente connessioni" -#: describe.c:3171 +#: describe.c:3346 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d connessione" msgstr[1] "%d connessioni" -#: describe.c:3181 +#: describe.c:3356 msgid "Password valid until " msgstr "Password valida fino a " -#: describe.c:3237 +#: describe.c:3406 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "Il server (versione %s) non supporta l'impostazione dei ruoli per database.\n" + +#: describe.c:3419 msgid "Role" msgstr "Ruolo" -#: describe.c:3238 +#: describe.c:3420 msgid "Database" msgstr "Database" -#: describe.c:3239 +#: describe.c:3421 msgid "Settings" msgstr "Impostazioni" -#: describe.c:3249 +#: describe.c:3442 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "Questa versione del server non supporta l'impostazione dei ruoli per database.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "Non è stata trovata nessuna impostazione per il ruolo \"%s\" e il database \"%s\".\n" -#: describe.c:3260 +#: describe.c:3445 #, c-format -msgid "No matching settings found.\n" -msgstr "Nessuna impostazione corrispondente trovata.\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "Non è stata trovata nessuna impostazione per il ruolo \"%s\".\n" -#: describe.c:3262 +#: describe.c:3448 #, c-format -msgid "No settings found.\n" -msgstr "Nessuna impostazione trovata.\n" +msgid "Did not find any settings.\n" +msgstr "Non è stata trovata nessuna impostazione.\n" -#: describe.c:3267 +#: describe.c:3453 msgid "List of settings" msgstr "Lista delle impostazioni" -#: describe.c:3337 +#: describe.c:3523 describe.c:3528 msgid "index" msgstr "indice" -#: describe.c:3339 +#: describe.c:3525 msgid "special" msgstr "speciale" -#: describe.c:3348 describe.c:4823 +#: describe.c:3535 describe.c:5050 msgid "Table" msgstr "Tabella" -#: describe.c:3425 -#, c-format -msgid "No matching relations found.\n" -msgstr "Nessuna relazione corrispondente trovata.\n" - -#: describe.c:3427 -#, c-format -msgid "No relations found.\n" -msgstr "Nessuna relazione trovata.\n" - -#: describe.c:3432 +#: describe.c:3626 msgid "List of relations" msgstr "Lista delle relazioni" -#: describe.c:3469 +#: describe.c:3663 msgid "Trusted" msgstr "Fidato" -#: describe.c:3477 -msgid "Internal Language" +#: describe.c:3671 +msgid "Internal language" msgstr "Linguaggio interno" -#: describe.c:3478 -msgid "Call Handler" -msgstr "Gestore Chiamate" +#: describe.c:3672 +msgid "Call handler" +msgstr "Handler di chiamata" -#: describe.c:3479 describe.c:4603 +#: describe.c:3673 describe.c:4830 msgid "Validator" msgstr "Validatore" -#: describe.c:3482 -msgid "Inline Handler" -msgstr "Handler Inline" +#: describe.c:3676 +msgid "Inline handler" +msgstr "Handler inline" -#: describe.c:3510 +#: describe.c:3704 msgid "List of languages" msgstr "Lista dei linguaggi" -#: describe.c:3555 +#: describe.c:3749 msgid "Check" msgstr "Controllo" -#: describe.c:3597 +#: describe.c:3791 msgid "List of domains" msgstr "Lista dei domini" -#: describe.c:3631 +#: describe.c:3825 msgid "Source" msgstr "Sorgente" -#: describe.c:3632 +#: describe.c:3826 msgid "Destination" msgstr "Destinazione" -#: describe.c:3633 describe.c:3782 -msgid "no" -msgstr "no" - -#: describe.c:3633 describe.c:3784 -msgid "yes" -msgstr "sì" - -#: describe.c:3634 +#: describe.c:3828 msgid "Default?" msgstr "Predefinito?" -#: describe.c:3671 +#: describe.c:3865 msgid "List of conversions" msgstr "Lista delle conversioni" -#: describe.c:3710 +#: describe.c:3904 msgid "Event" msgstr "Evento" -#: describe.c:3712 +#: describe.c:3906 msgid "enabled" msgstr "abilitato" -#: describe.c:3713 +#: describe.c:3907 msgid "replica" msgstr "replica" -#: describe.c:3714 +#: describe.c:3908 msgid "always" msgstr "sempre" -#: describe.c:3715 +#: describe.c:3909 msgid "disabled" msgstr "disabilitato" -#: describe.c:3716 describe.c:5264 +#: describe.c:3910 describe.c:5529 msgid "Enabled" msgstr "Abilitato" -#: describe.c:3717 -msgid "Procedure" -msgstr "Procedura" - -#: describe.c:3718 +#: describe.c:3912 msgid "Tags" msgstr "Tag" -#: describe.c:3737 +#: describe.c:3931 msgid "List of event triggers" msgstr "Lista di trigger di evento" -#: describe.c:3779 +#: describe.c:3960 msgid "Source type" msgstr "Tipo di partenza" -#: describe.c:3780 +#: describe.c:3961 msgid "Target type" msgstr "Tipo di arrivo" -#: describe.c:3783 +#: describe.c:3992 msgid "in assignment" msgstr "in assegnazione" -#: describe.c:3785 +#: describe.c:3994 msgid "Implicit?" msgstr "Implicito?" -#: describe.c:3836 +#: describe.c:4049 msgid "List of casts" msgstr "Lista delle conversioni di tipo" -#: describe.c:3864 +#: describe.c:4077 #, c-format msgid "The server (version %s) does not support collations.\n" msgstr "Il server (versione %s) non supporta gli ordinamenti.\n" -#: describe.c:3885 +#: describe.c:4098 msgid "Provider" msgstr "Provider" -#: describe.c:3920 +#: describe.c:4133 msgid "List of collations" msgstr "Lista degli ordinamenti" -#: describe.c:3979 +#: describe.c:4192 msgid "List of schemas" msgstr "Lista degli schemi" -#: describe.c:4004 describe.c:4242 describe.c:4313 describe.c:4384 +#: describe.c:4217 describe.c:4464 describe.c:4535 describe.c:4606 #, c-format msgid "The server (version %s) does not support full text search.\n" msgstr "Il server (versione %s) non supporta la ricerca full text.\n" -#: describe.c:4039 +#: describe.c:4252 msgid "List of text search parsers" msgstr "Lista degli analizzatori di ricerca resto" -#: describe.c:4082 +#: describe.c:4297 #, c-format msgid "Did not find any text search parser named \"%s\".\n" -msgstr "Non ho trovato alcun analizzatore di ricerca testo chiamato \"%s\".\n" +msgstr "Non è stato trovato nessun analizzatore di ricerca testo chiamato \"%s\".\n" -#: describe.c:4157 +#: describe.c:4300 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "Non è stato trovato nessun analizzatore di ricerca testo.\n" + +#: describe.c:4375 msgid "Start parse" msgstr "Inizio analisi" -#: describe.c:4158 +#: describe.c:4376 msgid "Method" msgstr "Metodo" -#: describe.c:4162 +#: describe.c:4380 msgid "Get next token" msgstr "Ottiene il token successivo" -#: describe.c:4164 +#: describe.c:4382 msgid "End parse" msgstr "Fine analisi" -#: describe.c:4166 +#: describe.c:4384 msgid "Get headline" msgstr "Ottiene intestazione" -#: describe.c:4168 +#: describe.c:4386 msgid "Get token types" msgstr "Ottieni i tipi token" -#: describe.c:4178 +#: describe.c:4397 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Analizzatore di ricerca teso \"%s.%s\"" -#: describe.c:4180 +#: describe.c:4400 #, c-format msgid "Text search parser \"%s\"" msgstr "Analizzatore di ricerca testo \"%s\"" -#: describe.c:4199 +#: describe.c:4419 msgid "Token name" msgstr "Nome token" -#: describe.c:4210 +#: describe.c:4430 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Tipi token per l'analizzatore \"%s.%s\"" -#: describe.c:4212 +#: describe.c:4433 #, c-format msgid "Token types for parser \"%s\"" msgstr "Tipi token per l'analizzatore \"%s\"" -#: describe.c:4265 +#: describe.c:4487 msgid "Template" msgstr "Modello" -#: describe.c:4266 +#: describe.c:4488 msgid "Init options" msgstr "Opzioni iniziali:" -#: describe.c:4288 +#: describe.c:4510 msgid "List of text search dictionaries" msgstr "Lista dei dizionari di ricerca testo" -#: describe.c:4331 +#: describe.c:4553 msgid "Init" msgstr "Init" -#: describe.c:4332 +#: describe.c:4554 msgid "Lexize" msgstr "Lexize" -#: describe.c:4359 +#: describe.c:4581 msgid "List of text search templates" msgstr "Lista dei modelli di ricerca testo" -#: describe.c:4419 +#: describe.c:4641 msgid "List of text search configurations" msgstr "Lista delle configurazioni di ricerca testo" -#: describe.c:4463 +#: describe.c:4687 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" -msgstr "Non trovata alcuna configurazione di ricerca testo chiamata \"%s\".\n" +msgstr "Non è stata trovata nessuna configurazione di ricerca testo chiamata \"%s\".\n" -#: describe.c:4529 +#: describe.c:4690 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "Non è stata trovata nessuna configurazione di ricerca testo.\n" + +#: describe.c:4756 msgid "Token" msgstr "Token" -#: describe.c:4530 +#: describe.c:4757 msgid "Dictionaries" msgstr "Dizionari" -#: describe.c:4541 +#: describe.c:4768 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Configurazione di ricerca testo \"%s.%s\"" -#: describe.c:4544 +#: describe.c:4771 #, c-format msgid "Text search configuration \"%s\"" msgstr "Configurazione di ricerca testo \"%s\"" -#: describe.c:4548 +#: describe.c:4775 #, c-format msgid "" "\n" @@ -1907,7 +1955,7 @@ msgstr "" "\n" "Analizzatore \"%s.%s\"" -#: describe.c:4551 +#: describe.c:4778 #, c-format msgid "" "\n" @@ -1916,134 +1964,152 @@ msgstr "" "\n" "Analizzatore: \"%s\"" -#: describe.c:4585 +#: describe.c:4812 #, c-format msgid "The server (version %s) does not support foreign-data wrappers.\n" msgstr "Il server (versione %s) non supporta i wrapper di dati esterni.\n" -#: describe.c:4643 +#: describe.c:4870 msgid "List of foreign-data wrappers" msgstr "Lista dei wrapper di dati esterni" -#: describe.c:4668 +#: describe.c:4895 #, c-format msgid "The server (version %s) does not support foreign servers.\n" msgstr "Il server (versione %s) non supporta server esterni.\n" -#: describe.c:4681 +#: describe.c:4908 msgid "Foreign-data wrapper" msgstr "Wrapper per dati esterni" -#: describe.c:4699 describe.c:4904 +#: describe.c:4926 describe.c:5131 msgid "Version" msgstr "Versione" -#: describe.c:4725 +#: describe.c:4952 msgid "List of foreign servers" msgstr "Lista dei server esterni" -#: describe.c:4750 +#: describe.c:4977 #, c-format msgid "The server (version %s) does not support user mappings.\n" msgstr "Il server (versione %s) non supporta la mappatura di utenti.\n" -#: describe.c:4760 describe.c:4824 +#: describe.c:4987 describe.c:5051 msgid "Server" msgstr "Server" -#: describe.c:4761 +#: describe.c:4988 msgid "User name" msgstr "Nome utente" -#: describe.c:4786 +#: describe.c:5013 msgid "List of user mappings" msgstr "Lista delle mappature degli utenti" -#: describe.c:4811 +#: describe.c:5038 #, c-format msgid "The server (version %s) does not support foreign tables.\n" msgstr "Il server (versione %s) non supporta tabelle esterne.\n" -#: describe.c:4864 +#: describe.c:5091 msgid "List of foreign tables" msgstr "Lista delle tabelle esterne" -#: describe.c:4889 describe.c:4946 +#: describe.c:5116 describe.c:5173 #, c-format msgid "The server (version %s) does not support extensions.\n" msgstr "Il server (versione %s) non supporta le estensioni.\n" -#: describe.c:4921 +#: describe.c:5148 msgid "List of installed extensions" msgstr "Lista delle estensioni installate" -#: describe.c:4974 +#: describe.c:5201 #, c-format msgid "Did not find any extension named \"%s\".\n" -msgstr "Non ho trovato alcuna estensione nominata \"%s\".\n" +msgstr "Non è stata trovata nessuna estensione chiamata \"%s\".\n" -#: describe.c:4977 +#: describe.c:5204 #, c-format msgid "Did not find any extensions.\n" -msgstr "Non ho trovato alcuna estensione.\n" +msgstr "Non è stata trovata nessuna estensione.\n" -#: describe.c:5021 -msgid "Object Description" -msgstr "Descrizione Oggetto" +#: describe.c:5248 +msgid "Object description" +msgstr "Descrizione dell'oggetto" -#: describe.c:5030 +#: describe.c:5258 #, c-format msgid "Objects in extension \"%s\"" msgstr "Oggetti nell'estensione \"%s\"" -#: describe.c:5057 describe.c:5120 +#: describe.c:5287 describe.c:5358 #, c-format msgid "The server (version %s) does not support publications.\n" msgstr "Il server (versione %s) non supporta pubblicazioni.\n" -#: describe.c:5073 describe.c:5165 +#: describe.c:5304 describe.c:5430 +msgid "All tables" +msgstr "Tutte le tabelle" + +#: describe.c:5305 describe.c:5431 msgid "Inserts" msgstr "Inserimenti" -#: describe.c:5074 describe.c:5166 +#: describe.c:5306 describe.c:5432 msgid "Updates" msgstr "Modifiche" -#: describe.c:5075 describe.c:5167 +#: describe.c:5307 describe.c:5433 msgid "Deletes" msgstr "Cancellazioni" -#: describe.c:5092 +#: describe.c:5311 describe.c:5435 +msgid "Truncates" +msgstr "Troncamenti" + +#: describe.c:5328 msgid "List of publications" msgstr "Lista delle pubblicazioni" -#: describe.c:5162 +#: describe.c:5396 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "Non è stata trovata nessuna pubblicazione chiamata \"%s\".\n" + +#: describe.c:5399 +#, c-format +msgid "Did not find any publications.\n" +msgstr "Non è stata trovata nessuna pubblicazione.\n" + +#: describe.c:5426 #, c-format msgid "Publication %s" msgstr "Pubblicazione %s" -#: describe.c:5207 +#: describe.c:5470 msgid "Tables:" msgstr "Tabelle:" -#: describe.c:5249 +#: describe.c:5514 #, c-format msgid "The server (version %s) does not support subscriptions.\n" msgstr "Il server (versione %s) non supporta sottoscrizioni.\n" -#: describe.c:5265 +#: describe.c:5530 msgid "Publication" msgstr "Pubblicazione" -#: describe.c:5272 +#: describe.c:5537 msgid "Synchronous commit" msgstr "Commit sincrono" -#: describe.c:5273 +#: describe.c:5538 msgid "Conninfo" msgstr "Conninfo" -#: describe.c:5295 +#: describe.c:5560 msgid "List of subscriptions" msgstr "Lista di sottoscrizioni" @@ -2061,7 +2127,7 @@ msgstr "" "psql è il terminale interattivo per PostgreSQL.\n" "\n" -#: help.c:74 help.c:342 help.c:376 help.c:403 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" msgstr "Utilizzo:\n" @@ -2373,238 +2439,238 @@ msgstr " \\copyright mostra i termini di uso e distribuzione di Pos #: help.c:174 #, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLONNE] esegui la query e mostra il risultato in crosstab\n" + +#: help.c:175 +#, c-format msgid " \\errverbose show most recent error message at maximum verbosity\n" msgstr " \\errverbose mostra il messaggio di errore più recente alla massima loquacità\n" -#: help.c:175 +#: help.c:176 #, c-format msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" msgstr "" " \\g [FILE] o ; esegui la query (ed invia i risultati ad un file o\n" " ad una |pipe)\n" -#: help.c:176 +#: help.c:177 #, c-format -msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" -msgstr " \\gx [FILE] come \\g, ma forza un modo di output espanso\n" +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc descrivi il risultato della query, senza eseguirla\n" -#: help.c:177 +#: help.c:178 #, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr " \\gexec esegui la query, poi esegui ogni valore nel suo risultato\n" -#: help.c:178 +#: help.c:179 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr " \\gset [PREFIX] esegui la query e salva il risultato in una variabile psql\n" -#: help.c:179 -#, c-format -msgid " \\q quit psql\n" -msgstr " \\q esci da psql\n" - #: help.c:180 #, c-format -msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" -msgstr " \\crosstabview [COLONNE] esegui la query e mostra il risultato in crosstab\n" +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [FILE] come \\g, ma forza un modo di output espanso\n" #: help.c:181 #, c-format +msgid " \\q quit psql\n" +msgstr " \\q esci da psql\n" + +#: help.c:182 +#, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEC] esegui una query ogni SEC secondi\n" -#: help.c:184 +#: help.c:185 #, c-format msgid "Help\n" msgstr "Aiuto\n" -#: help.c:186 +#: help.c:187 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] mostra aiuto sui comandi backslash\n" -#: help.c:187 +#: help.c:188 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options mostra aiuto sulle opzioni di riga di comando psql\n" -#: help.c:188 +#: help.c:189 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables mostra aiusto sulle variabili speciali\n" -#: help.c:189 +#: help.c:190 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr "" " \\h [NOME] mostra aiuto sulla sintassi dei comandi SQL, * mostra\n" " tutti i comandi\n" -#: help.c:192 +#: help.c:193 #, c-format msgid "Query Buffer\n" msgstr "Buffer Query\n" -#: help.c:193 +#: help.c:194 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr "" " \\e [FILE] [RIGA] modifica il buffer della query (o il file) con\n" " l'editor esterno\n" -#: help.c:194 +#: help.c:195 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr "" " \\ef [FUNZIONE [RIGA]] modifica la definizione della funzione con l'editor\n" " esterno\n" -#: help.c:195 +#: help.c:196 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr " \\ev [VISTA [LINE]] modifica la definizione della vista con un editor esterno\n" -#: help.c:196 +#: help.c:197 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p mostra i contenuti del buffer query\n" -#: help.c:197 +#: help.c:198 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r reimposta (cancella) il buffer query\n" -#: help.c:199 +#: help.c:200 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [FILE] mostra la cronologia salvala in un file\n" -#: help.c:201 +#: help.c:202 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w FILE scrivi il buffer query su file\n" -#: help.c:204 +#: help.c:205 #, c-format msgid "Input/Output\n" msgstr "Input/Output\n" -#: help.c:205 +#: help.c:206 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr " \\copy ... esegui una SQL COPY con flusso di dati dal client\n" -#: help.c:206 +#: help.c:207 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [STRINGA] stampa la stringa su standard output\n" -#: help.c:207 +#: help.c:208 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i FILE esegui i comandi dal file\n" -#: help.c:208 +#: help.c:209 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr "" " \\ir FILE come \\i, ma relativo alla posizione nello script\n" " corrente\n" -#: help.c:209 +#: help.c:210 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr "" " \\o [FILE] invia i risultati della query ad un file oppure\n" " una |pipe\n" -#: help.c:210 +#: help.c:211 #, c-format msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr "" " \\qecho [STRINGA] scrivi la stringa nello stream di output della query\n" " (vedi \\o)\n" -#: help.c:213 +#: help.c:214 #, c-format msgid "Conditional\n" msgstr "Condizionale\n" -#: help.c:214 +#: help.c:215 #, c-format msgid " \\if EXPR begin conditional block\n" msgstr " \\if ESPR inizia un blocco condizionale\n" -#: help.c:215 +#: help.c:216 #, c-format msgid " \\elif EXPR alternative within current conditional block\n" msgstr " \\elif ESPR alternativa all'interno di un blocco condizionale\n" -#: help.c:216 +#: help.c:217 #, c-format msgid " \\else final alternative within current conditional block\n" msgstr " \\else alternativa finale in un blocco condizionale\n" -#: help.c:217 +#: help.c:218 #, c-format msgid " \\endif end conditional block\n" msgstr " \\endif fine del blocco condizionale\n" -#: help.c:220 +#: help.c:221 #, c-format msgid "Informational\n" msgstr "Informativi\n" -#: help.c:221 +#: help.c:222 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (opzioni: S = mostra gli oggetti di sistema, + = dettagli addizionali)\n" -#: help.c:222 +#: help.c:223 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] elenca le tabelle, le viste e le sequenze\n" -#: help.c:223 +#: help.c:224 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NOME descrive la tabella, vista, sequenza o indice\n" -#: help.c:224 +#: help.c:225 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [MODELLO] elenca le funzioni di aggregazione\n" -#: help.c:225 +#: help.c:226 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [MODELLO] elenca i metodi di accesso\n" -#: help.c:226 +#: help.c:227 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [MODELLO] elenca i tablespace\n" -#: help.c:227 +#: help.c:228 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [MODELLO] elenca le conversioni di codifica\n" -#: help.c:228 +#: help.c:229 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [MODELLO] elenca le conversioni di tipo\n" -#: help.c:229 +#: help.c:230 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr " \\dd[S] [MODELLO] mostra la descrizione di oggetti non elencati altrove\n" -#: help.c:230 -#, c-format -msgid " \\ddp [PATTERN] list default privileges\n" -msgstr " \\ddp [MODELLO] elenca i privilegi predefiniti\n" - #: help.c:231 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" @@ -2612,238 +2678,247 @@ msgstr " \\dD[S+] [MODELLO] elenca i domini\n" #: help.c:232 #, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [MODELLO] elenca i privilegi predefiniti\n" + +#: help.c:233 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [MODELLO] elenca le tabelle esterne\n" + +#: help.c:234 +#, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [MODELLO] elenca le tabelle esterne\n" -#: help.c:233 +#: help.c:235 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [MODELLO] elenca i server esterni\n" -#: help.c:234 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [MODELLO] elenca le mappature degli utenti\n" -#: help.c:235 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [MODELLO] elenca i wrapper di dati esterni\n" -#: help.c:236 +#: help.c:238 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [MOD] elenca le funzioni [solo aggr/normali/trigger/finestra]\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [PATRN] elenca le funzioni [solo aggr/normali/procedure/trigger/finestra]\n" -#: help.c:237 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [MODELLO] elenca le configurazioni di ricerca testo\n" -#: help.c:238 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [MODELLO] elenca i dizionari di ricerca testo\n" -#: help.c:239 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [MODELLO] elenca gli analizzatori di ricerca testo\n" -#: help.c:240 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [MODELLO] elenca i modelli di ricerca di testo\n" -#: help.c:241 +#: help.c:243 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [MODELLO] elenca i ruoli\n" -#: help.c:242 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [MODELLO] elenca gli indici\n" -#: help.c:243 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl elenca i large object, stesso risultato di \\lo_list\n" -#: help.c:244 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [MODELLO] elenca i linguaggi procedurali\n" -#: help.c:245 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [PATTERN] elenca le viste materializzate\n" -#: help.c:246 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [MODELLO] elenca gli schemi\n" -#: help.c:247 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [MODELLO] elenca gli operatori\n" -#: help.c:248 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [MODELLO] elenca gli ordinamenti\n" -#: help.c:249 +#: help.c:251 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr "" " \\dp [MODELLO] elenca i permessi di accesso alla tabella, vista\n" " o sequenza\n" -#: help.c:250 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [MOD1 [MOD2]] elenca le impostazioni dei ruoli per database\n" -#: help.c:251 +#: help.c:253 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[+] [MODELLO] elenca le pubblicazioni di replica\n" -#: help.c:252 +#: help.c:254 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [MODELLO] elenca le sottoscrizioni di replica\n" -#: help.c:253 +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [MODELLO] elenca le sequenze\n" -#: help.c:254 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [MODELLO] elenca le tabelle\n" -#: help.c:255 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [MODELLO] elenca i tipi di dato\n" -#: help.c:256 +#: help.c:258 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [MODELLO] elenca i ruoli\n" -#: help.c:257 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [MODELLO] elenca le viste\n" -#: help.c:258 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [MODELLO] elenca le tabelle esterne\n" - -#: help.c:259 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [MODELLO] elenca le estensioni\n" -#: help.c:260 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [PATTERN] elenca i trigger di evento\n" -#: help.c:261 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [PATTERN] elenca i database\n" -#: help.c:262 +#: help.c:263 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNZIONE mostra la definizione di una funzione\n" -#: help.c:263 +#: help.c:264 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] VISTA mostra la definizione di una vista\n" -#: help.c:264 +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [MODELLO] uguale a \\dp\n" -#: help.c:267 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "Formattazione\n" -#: help.c:268 +#: help.c:269 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr " \\a alterna tra modalità di output allineata e disallineata\n" -#: help.c:269 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr "" " \\C [STRINGA] imposta nome tabella oppure elimina se la stringa\n" " non è specificata\n" -#: help.c:270 +#: help.c:271 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr "" " \\f [STRINGA] mostra o imposta il separatore di campo per l'output\n" " query disallineato\n" -#: help.c:271 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H cambia modalità HTML (attualmente %s)\n" -#: help.c:273 +#: help.c:274 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" msgstr "" " \\pset [NOME [VALORE]] imposta opzioni di output tabella\n" -" (NOME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|unicode_header_linestyle})\n" +" (NOME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" -#: help.c:277 +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] mostra solo le righe (attualmente %s)\n" -#: help.c:279 +#: help.c:282 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr "" " \\T [STRINGA] imposta gli attributi HTML di
, se non\n" " specificato allora annullali\n" -#: help.c:280 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr "" " \\x [on|off|auto] cambia modalità output espansa\n" " (attualmente %s)\n" -#: help.c:284 +#: help.c:287 #, c-format msgid "Connection\n" msgstr "Connessione\n" -#: help.c:286 +#: help.c:289 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2852,7 +2927,7 @@ msgstr "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connetti ad un nuovo database (attualmente \"%s\")\n" -#: help.c:290 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2861,78 +2936,78 @@ msgstr "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connetti ad un nuovo database (nessuna connessione attiva)\n" -#: help.c:292 +#: help.c:295 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo mostra le informazioni su la connessione corrente\n" + +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [CODIFICA] mostra o imposta la codifica del client\n" -#: help.c:293 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [UTENTE] cambia la password per un utente in sicurezza\n" -#: help.c:294 -#, c-format -msgid " \\conninfo display information about current connection\n" -msgstr " \\conninfo mostra le informazioni su la connessione corrente\n" - -#: help.c:297 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "Sistema operativo\n" -#: help.c:298 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [DIRECTORY] cambia la directory di lavoro\n" -#: help.c:299 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NOME [VALORE] imposta o elimina una variabile d'ambiente\n" -#: help.c:300 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr "" " \\timing [on|off] imposta cronometro dei comandi\n" " (attualmente %s)\n" -#: help.c:302 +#: help.c:305 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr "" " \\! [COMANDO] esegui un comando in una shell oppure avvia una shell\n" " interattiva\n" -#: help.c:305 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "Variabili\n" -#: help.c:306 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr " \\prompt [TESTO] NOME richiedi all'utente di impostare una variabile interna\n" -#: help.c:307 +#: help.c:310 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr "" " \\set [NOME [VALORE]] imposta una variabile interna, oppure mostrale tutte\n" " se non sono specificati parametri\n" -#: help.c:308 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NOME cancella una variabile interna\n" -#: help.c:311 +#: help.c:314 #, c-format msgid "Large Objects\n" msgstr "Large Object\n" -#: help.c:312 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2945,7 +3020,7 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID operazioni sui large object\n" -#: help.c:339 +#: help.c:342 #, c-format msgid "" "List of specially treated variables\n" @@ -2954,12 +3029,12 @@ msgstr "" "Lista delle variabili speciali\n" "\n" -#: help.c:341 +#: help.c:344 #, c-format msgid "psql variables:\n" msgstr "variabili psql:\n" -#: help.c:343 +#: help.c:346 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -2970,148 +3045,304 @@ msgstr "" " oppure \\set NOME VALORE dentro psql\n" "\n" -#: help.c:345 +#: help.c:348 #, c-format -msgid " AUTOCOMMIT if set, successful SQL commands are automatically committed\n" -msgstr " AUTOCOMMIT se impostato, i comandi SQL riusciti sono salvati automaticamente\n" +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" se impostato, i comandi SQL riusciti sono salvati automaticamente\n" -#: help.c:346 +#: help.c:350 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" COMP_KEYWORD_CASE determina il caso usato per completare le parole chiave SQL\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determina il caso usato per completare le parole chiave SQL\n" +" [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:348 +#: help.c:353 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" il nome del database attualmente connesso\n" + +#: help.c:355 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME il nome del database attualmente connesso\n" +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" controlla quale input è scritto su stardard output\n" +" [all, errors, none, queries]\n" -#: help.c:349 +#: help.c:358 #, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" -" ECHO controlla quale input è scritto su stardard output\n" -" [all, errors, none, queries]\n" +" ECHO_HIDDEN\n" +" se impostato, mostra le query interne dei comandi backslash;\n" +" se impostato a \"noexec\", mostrale solo senza eseguirle\n" -#: help.c:351 +#: help.c:361 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash commands;\n" -" if set to \"noexec\", just show without execution\n" +" ENCODING\n" +" current client character set encoding\n" msgstr "" -" ECHO_HIDDEN se impostato, mostra le query interne dei comandi backslash;\n" -" se impostato a \"noexec\", mostrale solo senza eseguirle\n" +" ENCODING\n" +" codifica del set di caratteri del client corrente\n" -#: help.c:353 +#: help.c:363 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" true se l'ultima query è fallita, altrimenti false\n" + +#: help.c:365 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING codifica del set di caratteri del client corrente\n" +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" il numero di righe del risultato da leggere e mostrare per volta (0 = tutte)\n" -#: help.c:354 +#: help.c:367 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a time\n" -" (default: 0=unlimited)\n" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" msgstr "" -" FETCH_COUNT il numero di righe del risultato da leggere e mostrare pr volta\n" -" (default: 0=tutte)\n" +" HISTCONTROL\n" +" controlla la storia dei comandi [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:356 +#: help.c:369 #, c-format -msgid " HISTCONTROL controls command history [ignorespace, ignoredups, ignoreboth]\n" -msgstr " HISTCONTROL controlla la storia dei comandi [ignorespace, ignoredups, ignoreboth]\n" +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" nome del file usato per memorizzare la storia dei comandi\n" -#: help.c:357 +#: help.c:371 #, c-format -msgid " HISTFILE file name used to store the command history\n" -msgstr " HISTFILE nome del file usato per memorizzare la storia dei comandi\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" numero massimo di comandi da salvare nella storia dei comandi\n" -#: help.c:358 +#: help.c:373 #, c-format -msgid " HISTSIZE max number of commands to store in the command history\n" -msgstr " HISTSIZE numero massimo di comandi da salvare nella storia dei comandi\n" +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" l'host del server del database attualmente connesso\n" -#: help.c:359 +#: help.c:375 #, c-format -msgid " HOST the currently connected database server host\n" -msgstr " HOST l'host del server del database attualmente connesso\n" +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" numero di EOF richiesti per terminare una sessione interattiva\n" -#: help.c:360 +#: help.c:377 #, c-format -msgid " IGNOREEOF number of EOFs needed to terminate an interactive session\n" -msgstr " IGNOREEOF numero di EOF richiesti per terminare una sessione interattiva\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" valore dell'ultimo OID interessato\n" -#: help.c:361 +#: help.c:379 #, c-format -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID valore dell'ultimo OID interessato\n" +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" messaggio e SQLSTATE dell'ultimo errore, o stringa vuota e \"00000\" se non c'è\n" -#: help.c:362 +#: help.c:382 #, c-format -msgid " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit savepoints)\n" -msgstr " ON_ERROR_ROLLBACK se impostato, un errore non termina una transazione (usa punti di salvataggio impliciti)\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" se impostato, un errore non termina una transazione (usa punti di\n" +" salvataggio impliciti)\n" -#: help.c:363 +#: help.c:384 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr " ON_ERROR_STOP termina l'esecuzione batch dopo un errore\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" termina l'esecuzione batch dopo un errore\n" -#: help.c:364 +#: help.c:386 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT porta del server attualmente connesso\n" +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" porta del server attualmente connesso\n" -#: help.c:365 +#: help.c:388 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 specifica il prompt psql standard\n" +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" specifica il prompt psql standard\n" -#: help.c:366 +#: help.c:390 #, c-format -msgid " PROMPT2 specifies the prompt used when a statement continues from a previous line\n" -msgstr " PROMPT2 specifica il prompt usato quando un'istruzione continua da una riga precedente\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" specifica il prompt usato quando un'istruzione continua da una riga\n" +" precedente\n" -#: help.c:367 +#: help.c:392 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" specifica il prompt usato in COPY ... FROM STDIN\n" + +#: help.c:394 #, c-format -msgid " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr " PROMPT3 specifica il prompt usato in COPY ... FROM STDIN\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" esegui silenziosamente (come con l'opzione -q)\n" -#: help.c:368 +#: help.c:396 #, c-format -msgid " QUIET run quietly (same as -q option)\n" -msgstr " QUIET esegui silenziosamente (come con l'opzione -q)\n" +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" numero di righe restituite o toccate dall'ultima query, o 0\n" -#: help.c:369 +#: help.c:398 #, c-format -msgid " SHOW_CONTEXT controls display of message context fields [never, errors, always]\n" -msgstr " SHOW_CONTEXT controlla la visualizzazione dei campi di contesto dei messaggi [never, errors, always]\n" +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" versione del server (come stringa breve o formato numerico)\n" -#: help.c:370 +#: help.c:401 #, c-format -msgid " SINGLELINE end of line terminates SQL command mode (same as -S option)\n" -msgstr " SINGLELINE la fine riga termina i comandi SQL (come con l'opzione -S)\n" +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" controlla la visualizzazione dei campi di contesto dei messaggi [never,\n" +" errors, always]\n" -#: help.c:371 +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" se impostato, la fine riga termina i comandi SQL (come con l'opzione -S)\n" + +#: help.c:405 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP modalità passo singolo (come con l'opzione -s)\n" +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" modalità passo singolo (come con l'opzione -s)\n" -#: help.c:372 +#: help.c:407 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER l'utente database attualmente connesso\n" +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" il codice SQLSTATE dell'ultima query, o \"00000\" se non c'è stato errore\n" -#: help.c:373 +#: help.c:409 #, c-format -msgid " VERBOSITY controls verbosity of error reports [default, verbose, terse]\n" -msgstr " VERBOSITY controlla la loquacità della visualizzazione degli errori [default, verbose, terse]\n" +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" l'utente database attualmente connesso\n" -#: help.c:375 +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" controlla la loquacità della visualizzazione degli errori [default, verbose,\n" +" terse]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" la versione di psql (come stringa estesa, stringa breve, formato numerico)\n" + +#: help.c:418 #, c-format msgid "" "\n" @@ -3120,7 +3351,7 @@ msgstr "" "\n" "Impostazioni di visualizzazione:\n" -#: help.c:377 +#: help.c:420 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3131,109 +3362,170 @@ msgstr "" " oppure \\pset NOME [VALORE] dentro psql\n" "\n" -#: help.c:379 +#: help.c:422 #, c-format -msgid " border border style (number)\n" -msgstr " border stile bordo (numero)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" stile bordo (numero)\n" -#: help.c:380 +#: help.c:424 #, c-format -msgid " columns target width for the wrapped format\n" -msgstr " columns larghezza destinazione per il formato wrapped\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" larghezza destinazione per il formato wrapped\n" -#: help.c:381 +#: help.c:426 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" -msgstr " expanded (o x) output espanso [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (o x)\n" +" output espanso [on, off, auto]\n" -#: help.c:382 +#: help.c:428 #, c-format -msgid " fieldsep field separator for unaligned output (default \"%s\")\n" -msgstr " fieldsep separatore di campo per l'output non allineato (default \"%s\")\n" +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" separatore di campo per l'output non allineato (default \"%s\")\n" -#: help.c:383 +#: help.c:431 #, c-format -msgid " fieldsep_zero set field separator for unaligned output to zero byte\n" -msgstr " fieldsep_zero imposta il separatore di campo per l'output non allineato al byte zero\n" +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" imposta il separatore di campo per l'output non allineato al byte zero\n" -#: help.c:384 +#: help.c:433 #, c-format -msgid " footer enable or disable display of the table footer [on, off]\n" -msgstr " footer abilita o disabilita la visualizzazione del piè di pagina [on, off]\n" +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" abilita o disabilita la visualizzazione del piè di pagina [on, off]\n" -#: help.c:385 +#: help.c:435 #, c-format -msgid " format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -msgstr " format imposta il formato di output [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" imposta il formato di output [unaligned, aligned, wrapped, html, asciidoc,\n" +" ...]\n" -#: help.c:386 +#: help.c:437 #, c-format -msgid " linestyle set the border line drawing style [ascii, old-ascii, unicode]\n" -msgstr " linestyle imposta lo stile di disegno delle righe dei bordi [ascii, old-ascii, unicode]\n" +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" imposta lo stile di disegno delle righe dei bordi [ascii, old-ascii,\n" +" unicode]\n" -#: help.c:387 +#: help.c:439 #, c-format -msgid " null set the string to be printed in place of a null value\n" -msgstr " null imposta la stringa da visualizzare al posto dei valori null\n" +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" imposta la stringa da visualizzare al posto dei valori null\n" -#: help.c:388 +#: help.c:441 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale abilita o disabilita i caratteri specifici per il locale per separare\n" -" i gruppi di cifre [on, off]\n" +" numericlocale\n" +" abilita i caratteri specifici per il locale per separare i gruppi di cifre\n" +" [on, off]\n" -#: help.c:390 +#: help.c:443 #, c-format -msgid " pager control when an external pager is used [yes, no, always]\n" -msgstr " pager controlla quando usare la paginazione esterna [yes, no, always]\n" +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" controlla quando usare la paginazione esterna [yes, no, always]\n" -#: help.c:391 +#: help.c:445 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" -msgstr " recordsep separatore di record (riga) per l'output non allineato\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" separatore di record (riga) per l'output non allineato\n" -#: help.c:392 +#: help.c:447 #, c-format -msgid " recordsep_zero set record separator for unaligned output to zero byte\n" -msgstr " recordsep_zero imposta il separatore di campo per l'output non allineato al byte zero\n" +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" imposta il separatore di campo per l'output non allineato al byte zero\n" -#: help.c:393 +#: help.c:449 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or proportional\n" -" column widths for left-aligned data types in latex-longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (or T) specifica gli attributi per il tag table in formato html o la\n" -" larghezza colonna proporzionale dei dati allineati a sinistra\n" -" in formato latex-longtable\n" +" tableattr (or T)\n" +" specifica gli attributi per il tag table in formato html o la larghezza\n" +" colonna proporzionale dei dati allineati a sinistra in formato\n" +" latex-longtable\n" -#: help.c:395 +#: help.c:452 #, c-format -msgid " title set the table title for any subsequently printed tables\n" -msgstr " title imposta il titolo della tabella per ogni tabella stampata in seguto\n" +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" imposta il titolo della tabella per le tabelle stampate in seguito\n" -#: help.c:396 +#: help.c:454 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" -msgstr " tuples_only se impostato, mostra solo i dati della tabella\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" se impostato, mostra solo i dati della tabella\n" -#: help.c:397 +#: help.c:456 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" imposta lo stile di disegno delle righe Unicode [single, double]\n" +" imposta lo stile di disegno delle righe Unicode [single, double]\n" -#: help.c:402 +#: help.c:461 #, c-format msgid "" "\n" @@ -3242,7 +3534,7 @@ msgstr "" "\n" "Variabili d'ambiente:\n" -#: help.c:406 +#: help.c:465 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3253,7 +3545,7 @@ msgstr "" " oppure \\setenv NOME [VALORE] dentro psql\n" "\n" -#: help.c:408 +#: help.c:467 #, c-format msgid "" " set NAME=VALUE\n" @@ -3266,94 +3558,146 @@ msgstr "" " oppure \\setenv NOME [VALORE] dentro psql\n" "\n" -#: help.c:411 -#, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS numero di colonne per il formato wrapped\n" - -#: help.c:412 +#: help.c:470 #, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER nome del programma di paginazione esterno\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" numero di colonne per il formato wrapped\n" -#: help.c:413 +#: help.c:472 #, c-format -msgid " PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME come il parametro di connessione application_name\n" +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" come il parametro di connessione application_name\n" -#: help.c:414 +#: help.c:474 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE come il parametro di connessione dbname\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" come il parametro di connessione dbname\n" -#: help.c:415 +#: help.c:476 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST come il parametro di connessione host\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" come il parametro di connessione host\n" -#: help.c:416 +#: help.c:478 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT come il parametro di connessione port\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" password di connessione (uso non raccomandato)\n" -#: help.c:417 +#: help.c:480 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER come il parametro di connessione user\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" nome del file delle password\n" -#: help.c:418 +#: help.c:482 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" -msgstr " PGPASSWORD password di connessione (uso non raccomandato)\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" come il parametro di connessione port\n" -#: help.c:419 +#: help.c:484 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE nome del file delle password\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" come il parametro di connessione user\n" -#: help.c:420 +#: help.c:486 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor usato dai comandi \\e, \\ef, \\ev\n" +" editor usato dai comandi \\e, \\ef, \\ev\n" -#: help.c:422 +#: help.c:488 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" come specificare un numero di riga quando si invoca l'editor\n" +" come specificare un numero di riga quando si invoca l'editor\n" -#: help.c:424 +#: help.c:490 #, c-format -msgid " PSQL_HISTORY alternative location for the command history file\n" -msgstr " PSQL_HISTORY posizione alternativa del file della storia dei comandi\n" +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" posizione alternativa del file della storia dei comandi\n" -#: help.c:425 +#: help.c:492 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" -msgstr " PSQLRC posizione alternativa del file .psqlrc dell'utente\n" +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" nome del programma di paginazione esterno\n" -#: help.c:426 +#: help.c:494 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL shell usata dal comando \\!\n" +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" posizione alternativa del file .psqlrc dell'utente\n" -#: help.c:427 +#: help.c:496 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR directory per i file temporanei\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" shell usata dal comando \\!\n" -#: help.c:470 +#: help.c:498 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" directory per i file temporanei\n" + +#: help.c:542 msgid "Available help:\n" msgstr "Aiuti disponibili:\n" -#: help.c:554 +#: help.c:626 #, c-format msgid "" "Command: %s\n" @@ -3368,7 +3712,7 @@ msgstr "" "%s\n" "\n" -#: help.c:570 +#: help.c:642 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3433,11 +3777,19 @@ msgstr "" "L'input è un file di dump in formato PostgreSQL.\n" "Usa il tool di riga di comando pg_restore per ripristinare questo dump in un database.\n" -#: mainloop.c:225 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Usa \\? per avere un aiuto o premi control-C per svuotare il buffer di input." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Usa \\? per avere un aiuto." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Stai utilizzando psql, l'interfaccia a riga di comando di PostgreSQL." -#: mainloop.c:226 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3452,2173 +3804,2273 @@ msgstr "" " \\g o termina con punto e virgola per eseguire la query\n" " \\q per uscire\n" -#: mainloop.c:339 mainloop.c:476 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Usa \\q per uscire." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Usa control-D per uscire." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Usa control-C per uscire." + +#: mainloop.c:449 mainloop.c:591 #, c-format msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "query ignorata: usa \\endif o Ctrl-C per uscire dal blocco \\if corrente\n" -#: mainloop.c:494 +#: mainloop.c:609 #, c-format msgid "reached EOF without finding closing \\endif(s)\n" msgstr "raggiunta fine file senza aver trovato \\endif finali\n" -#: psqlscanslash.l:614 +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" msgstr "stringa tra virgolette non terminata\n" -#: psqlscanslash.l:787 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" msgstr "%s: memoria esaurita\n" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 -#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 -#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 -#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 -#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 -#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 -#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 -#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 -#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 -#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 -#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 -#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 -#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 -#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:807 -#: sql_help.c:809 sql_help.c:811 sql_help.c:813 sql_help.c:816 sql_help.c:818 -#: sql_help.c:859 sql_help.c:882 sql_help.c:893 sql_help.c:895 sql_help.c:914 -#: sql_help.c:924 sql_help.c:926 sql_help.c:928 sql_help.c:940 sql_help.c:944 -#: sql_help.c:946 sql_help.c:957 sql_help.c:959 sql_help.c:961 sql_help.c:977 -#: sql_help.c:979 sql_help.c:983 sql_help.c:986 sql_help.c:987 sql_help.c:988 -#: sql_help.c:991 sql_help.c:993 sql_help.c:1084 sql_help.c:1086 -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 -#: sql_help.c:1099 sql_help.c:1102 sql_help.c:1168 sql_help.c:1170 -#: sql_help.c:1172 sql_help.c:1175 sql_help.c:1196 sql_help.c:1199 -#: sql_help.c:1202 sql_help.c:1205 sql_help.c:1209 sql_help.c:1211 -#: sql_help.c:1213 sql_help.c:1215 sql_help.c:1229 sql_help.c:1232 -#: sql_help.c:1234 sql_help.c:1236 sql_help.c:1246 sql_help.c:1248 -#: sql_help.c:1258 sql_help.c:1260 sql_help.c:1270 sql_help.c:1273 -#: sql_help.c:1295 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 -#: sql_help.c:1304 sql_help.c:1306 sql_help.c:1309 sql_help.c:1359 -#: sql_help.c:1397 sql_help.c:1400 sql_help.c:1402 sql_help.c:1404 -#: sql_help.c:1406 sql_help.c:1408 sql_help.c:1411 sql_help.c:1451 -#: sql_help.c:1662 sql_help.c:1726 sql_help.c:1745 sql_help.c:1758 -#: sql_help.c:1814 sql_help.c:1820 sql_help.c:1830 sql_help.c:1850 -#: sql_help.c:1875 sql_help.c:1893 sql_help.c:1922 sql_help.c:2015 -#: sql_help.c:2057 sql_help.c:2079 sql_help.c:2099 sql_help.c:2100 -#: sql_help.c:2135 sql_help.c:2155 sql_help.c:2177 sql_help.c:2191 -#: sql_help.c:2206 sql_help.c:2236 sql_help.c:2261 sql_help.c:2307 -#: sql_help.c:2569 sql_help.c:2582 sql_help.c:2599 sql_help.c:2615 -#: sql_help.c:2655 sql_help.c:2707 sql_help.c:2711 sql_help.c:2713 -#: sql_help.c:2719 sql_help.c:2737 sql_help.c:2764 sql_help.c:2799 -#: sql_help.c:2811 sql_help.c:2820 sql_help.c:2864 sql_help.c:2878 -#: sql_help.c:2906 sql_help.c:2914 sql_help.c:2922 sql_help.c:2930 -#: sql_help.c:2938 sql_help.c:2946 sql_help.c:2954 sql_help.c:2962 -#: sql_help.c:2971 sql_help.c:2982 sql_help.c:2990 sql_help.c:2998 -#: sql_help.c:3006 sql_help.c:3014 sql_help.c:3024 sql_help.c:3033 -#: sql_help.c:3042 sql_help.c:3050 sql_help.c:3059 sql_help.c:3067 -#: sql_help.c:3075 sql_help.c:3084 sql_help.c:3092 sql_help.c:3100 -#: sql_help.c:3108 sql_help.c:3116 sql_help.c:3124 sql_help.c:3132 -#: sql_help.c:3140 sql_help.c:3148 sql_help.c:3156 sql_help.c:3164 -#: sql_help.c:3181 sql_help.c:3190 sql_help.c:3198 sql_help.c:3215 -#: sql_help.c:3230 sql_help.c:3498 sql_help.c:3549 sql_help.c:3578 -#: sql_help.c:3586 sql_help.c:4009 sql_help.c:4057 sql_help.c:4198 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 msgid "name" msgstr "nome" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1520 -#: sql_help.c:2879 sql_help.c:3803 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 msgid "aggregate_signature" msgstr "signature_aggregato" -#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 -#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 -#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 -#: sql_help.c:789 sql_help.c:819 sql_help.c:860 sql_help.c:884 sql_help.c:894 -#: sql_help.c:927 sql_help.c:947 sql_help.c:960 sql_help.c:994 sql_help.c:1093 -#: sql_help.c:1169 sql_help.c:1212 sql_help.c:1233 sql_help.c:1247 -#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1303 sql_help.c:1360 -#: sql_help.c:1405 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "nuovo_nome" -#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 -#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 -#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 -#: sql_help.c:817 sql_help.c:896 sql_help.c:925 sql_help.c:945 sql_help.c:958 -#: sql_help.c:992 sql_help.c:1153 sql_help.c:1171 sql_help.c:1214 -#: sql_help.c:1235 sql_help.c:1298 sql_help.c:1403 sql_help.c:2555 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "nuovo_proprietario" -#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 -#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 -#: sql_help.c:774 sql_help.c:929 sql_help.c:962 sql_help.c:1095 sql_help.c:1216 -#: sql_help.c:1237 sql_help.c:1249 sql_help.c:1261 sql_help.c:1305 -#: sql_help.c:1407 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "nuovo_schema" -#: sql_help.c:45 sql_help.c:1576 sql_help.c:2880 sql_help.c:3824 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 msgid "where aggregate_signature is:" msgstr "dove signature_aggregato è:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 -#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 -#: sql_help.c:522 sql_help.c:527 sql_help.c:1538 sql_help.c:1577 -#: sql_help.c:1580 sql_help.c:1583 sql_help.c:1727 sql_help.c:1746 -#: sql_help.c:1749 sql_help.c:2016 sql_help.c:2881 sql_help.c:2884 -#: sql_help.c:2887 sql_help.c:2972 sql_help.c:3383 sql_help.c:3716 -#: sql_help.c:3809 sql_help.c:3825 sql_help.c:3828 sql_help.c:3831 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 msgid "argmode" msgstr "modo_arg" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 -#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 -#: sql_help.c:523 sql_help.c:528 sql_help.c:1539 sql_help.c:1578 -#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1728 sql_help.c:1747 -#: sql_help.c:1750 sql_help.c:2017 sql_help.c:2882 sql_help.c:2885 -#: sql_help.c:2888 sql_help.c:2973 sql_help.c:3810 sql_help.c:3826 -#: sql_help.c:3829 sql_help.c:3832 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 msgid "argname" msgstr "nome_arg" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 -#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 -#: sql_help.c:524 sql_help.c:529 sql_help.c:1540 sql_help.c:1579 -#: sql_help.c:1582 sql_help.c:1585 sql_help.c:2018 sql_help.c:2883 -#: sql_help.c:2886 sql_help.c:2889 sql_help.c:2974 sql_help.c:3811 -#: sql_help.c:3827 sql_help.c:3830 sql_help.c:3833 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 msgid "argtype" msgstr "tipo_arg" -#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:854 -#: sql_help.c:942 sql_help.c:1230 sql_help.c:1354 sql_help.c:1382 -#: sql_help.c:1633 sql_help.c:1639 sql_help.c:1925 sql_help.c:1966 -#: sql_help.c:1973 sql_help.c:1982 sql_help.c:2058 sql_help.c:2237 -#: sql_help.c:2329 sql_help.c:2584 sql_help.c:2765 sql_help.c:2787 -#: sql_help.c:3250 sql_help.c:3417 +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "opzione" -#: sql_help.c:114 sql_help.c:855 sql_help.c:1355 sql_help.c:2059 -#: sql_help.c:2238 sql_help.c:2766 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" msgstr "dove opzione può essere:" -#: sql_help.c:115 sql_help.c:1857 +#: sql_help.c:114 sql_help.c:2118 msgid "allowconn" msgstr "permetti_conn" -#: sql_help.c:116 sql_help.c:856 sql_help.c:1356 sql_help.c:1858 -#: sql_help.c:2239 sql_help.c:2767 +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" msgstr "limite_conn" -#: sql_help.c:117 sql_help.c:1859 +#: sql_help.c:116 sql_help.c:2120 msgid "istemplate" msgstr "è_template" -#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1098 sql_help.c:1146 +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "nuovo_tablespace" -#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 -#: sql_help.c:537 sql_help.c:863 sql_help.c:867 sql_help.c:870 sql_help.c:1005 -#: sql_help.c:1008 sql_help.c:1362 sql_help.c:1365 sql_help.c:1367 -#: sql_help.c:2027 sql_help.c:3603 sql_help.c:3998 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" msgstr "parametro_config" -#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 -#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:815 -#: sql_help.c:864 sql_help.c:943 sql_help.c:982 sql_help.c:985 sql_help.c:990 -#: sql_help.c:1006 sql_help.c:1007 sql_help.c:1128 sql_help.c:1148 -#: sql_help.c:1174 sql_help.c:1231 sql_help.c:1363 sql_help.c:1383 -#: sql_help.c:1926 sql_help.c:1967 sql_help.c:1974 sql_help.c:1983 -#: sql_help.c:2028 sql_help.c:2029 sql_help.c:2087 sql_help.c:2119 -#: sql_help.c:2209 sql_help.c:2330 sql_help.c:2360 sql_help.c:2457 -#: sql_help.c:2469 sql_help.c:2482 sql_help.c:2519 sql_help.c:2541 -#: sql_help.c:2558 sql_help.c:2585 sql_help.c:2788 sql_help.c:3418 -#: sql_help.c:3999 sql_help.c:4000 +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "valore" -#: sql_help.c:198 +#: sql_help.c:197 msgid "target_role" msgstr "ruolo_destinazione" -#: sql_help.c:199 sql_help.c:1909 sql_help.c:2285 sql_help.c:2290 -#: sql_help.c:3365 sql_help.c:3372 sql_help.c:3386 sql_help.c:3392 -#: sql_help.c:3698 sql_help.c:3705 sql_help.c:3719 sql_help.c:3725 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "nome_schema" -#: sql_help.c:200 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "grant_o_revoke_abbreviato" -#: sql_help.c:201 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "dove grant_o_revoke_abbreviato è uno di:" -#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 -#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 -#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:874 -#: sql_help.c:1097 sql_help.c:1370 sql_help.c:2062 sql_help.c:2063 -#: sql_help.c:2064 sql_help.c:2065 sql_help.c:2066 sql_help.c:2193 -#: sql_help.c:2242 sql_help.c:2243 sql_help.c:2244 sql_help.c:2245 -#: sql_help.c:2246 sql_help.c:2770 sql_help.c:2771 sql_help.c:2772 -#: sql_help.c:2773 sql_help.c:2774 sql_help.c:3399 sql_help.c:3400 -#: sql_help.c:3401 sql_help.c:3699 sql_help.c:3703 sql_help.c:3706 -#: sql_help.c:3708 sql_help.c:3710 sql_help.c:3712 sql_help.c:3714 -#: sql_help.c:3720 sql_help.c:3722 sql_help.c:3724 sql_help.c:3726 -#: sql_help.c:3728 sql_help.c:3730 sql_help.c:3731 sql_help.c:3732 -#: sql_help.c:4019 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "nome_ruolo" -#: sql_help.c:237 sql_help.c:451 sql_help.c:1113 sql_help.c:1115 -#: sql_help.c:1399 sql_help.c:1878 sql_help.c:1882 sql_help.c:1986 -#: sql_help.c:1990 sql_help.c:2083 sql_help.c:2453 sql_help.c:2465 -#: sql_help.c:2478 sql_help.c:2486 sql_help.c:2497 sql_help.c:2523 -#: sql_help.c:3449 sql_help.c:3464 sql_help.c:3466 sql_help.c:3884 -#: sql_help.c:3885 sql_help.c:3894 sql_help.c:3935 sql_help.c:3936 -#: sql_help.c:3937 sql_help.c:3938 sql_help.c:3939 sql_help.c:3940 -#: sql_help.c:3973 sql_help.c:3974 sql_help.c:3979 sql_help.c:3984 -#: sql_help.c:4123 sql_help.c:4124 sql_help.c:4133 sql_help.c:4174 -#: sql_help.c:4175 sql_help.c:4176 sql_help.c:4177 sql_help.c:4178 -#: sql_help.c:4179 sql_help.c:4226 sql_help.c:4228 sql_help.c:4261 -#: sql_help.c:4317 sql_help.c:4318 sql_help.c:4327 sql_help.c:4368 -#: sql_help.c:4369 sql_help.c:4370 sql_help.c:4371 sql_help.c:4372 -#: sql_help.c:4373 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "espressione" -#: sql_help.c:240 +#: sql_help.c:239 msgid "domain_constraint" msgstr "vincolo_di_dominio" -#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 -#: sql_help.c:1090 sql_help.c:1134 sql_help.c:1135 sql_help.c:1136 -#: sql_help.c:1156 sql_help.c:1526 sql_help.c:1528 sql_help.c:1881 -#: sql_help.c:1985 sql_help.c:1989 sql_help.c:2485 sql_help.c:2496 -#: sql_help.c:3461 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "nome_vincolo" -#: sql_help.c:245 sql_help.c:1091 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "nuovo_nome_vincolo" -#: sql_help.c:316 sql_help.c:941 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "nuova_versione" -#: sql_help.c:320 sql_help.c:322 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "oggetto_membro" -#: sql_help.c:323 +#: sql_help.c:324 msgid "where member_object is:" msgstr "dove oggetto_membro è:" -#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 -#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 -#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 -#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 -#: sql_help.c:359 sql_help.c:1518 sql_help.c:1523 sql_help.c:1530 -#: sql_help.c:1531 sql_help.c:1532 sql_help.c:1533 sql_help.c:1534 -#: sql_help.c:1535 sql_help.c:1536 sql_help.c:1541 sql_help.c:1543 -#: sql_help.c:1547 sql_help.c:1549 sql_help.c:1553 sql_help.c:1554 -#: sql_help.c:1555 sql_help.c:1558 sql_help.c:1559 sql_help.c:1560 -#: sql_help.c:1561 sql_help.c:1562 sql_help.c:1563 sql_help.c:1564 -#: sql_help.c:1565 sql_help.c:1566 sql_help.c:1567 sql_help.c:1568 -#: sql_help.c:1573 sql_help.c:1574 sql_help.c:3799 sql_help.c:3804 -#: sql_help.c:3805 sql_help.c:3806 sql_help.c:3807 sql_help.c:3813 -#: sql_help.c:3814 sql_help.c:3815 sql_help.c:3816 sql_help.c:3817 -#: sql_help.c:3818 sql_help.c:3819 sql_help.c:3820 sql_help.c:3821 -#: sql_help.c:3822 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 msgid "object_name" msgstr "nome_oggetto" -#: sql_help.c:325 sql_help.c:1519 sql_help.c:3802 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 msgid "aggregate_name" msgstr "nome_aggregato" -#: sql_help.c:327 sql_help.c:1521 sql_help.c:1792 sql_help.c:1796 -#: sql_help.c:1798 sql_help.c:2897 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" msgstr "tipo_sorgente" -#: sql_help.c:328 sql_help.c:1522 sql_help.c:1793 sql_help.c:1797 -#: sql_help.c:1799 sql_help.c:2898 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" msgstr "tipo_destinazione" -#: sql_help.c:335 sql_help.c:756 sql_help.c:1537 sql_help.c:1794 -#: sql_help.c:1833 sql_help.c:1896 sql_help.c:2136 sql_help.c:2167 -#: sql_help.c:2661 sql_help.c:3382 sql_help.c:3715 sql_help.c:3808 -#: sql_help.c:3913 sql_help.c:3917 sql_help.c:3921 sql_help.c:3924 -#: sql_help.c:4152 sql_help.c:4156 sql_help.c:4160 sql_help.c:4163 -#: sql_help.c:4346 sql_help.c:4350 sql_help.c:4354 sql_help.c:4357 +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "nome_funzione" -#: sql_help.c:340 sql_help.c:749 sql_help.c:1544 sql_help.c:2160 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "nome_operatore" -#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1545 -#: sql_help.c:2137 sql_help.c:3015 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "tipo_sx" -#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1546 -#: sql_help.c:2138 sql_help.c:3016 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "tipo_dx" -#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 -#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 -#: sql_help.c:1548 sql_help.c:1550 sql_help.c:2157 sql_help.c:2178 -#: sql_help.c:2502 sql_help.c:3025 sql_help.c:3034 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "metodo_indice" -#: sql_help.c:356 sql_help.c:1152 sql_help.c:1569 sql_help.c:2024 -#: sql_help.c:2460 sql_help.c:2628 sql_help.c:3172 sql_help.c:3396 -#: sql_help.c:3729 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "nome_procedura" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "nome_routine" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 msgid "type_name" msgstr "nome_di_tipo" -#: sql_help.c:357 sql_help.c:1570 sql_help.c:2023 sql_help.c:2629 -#: sql_help.c:2855 sql_help.c:3173 sql_help.c:3388 sql_help.c:3721 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 msgid "lang_name" msgstr "nome_linguaggio" -#: sql_help.c:360 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "e signature_aggregato è:" -#: sql_help.c:383 sql_help.c:1664 sql_help.c:1923 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" msgstr "funzione_handler" -#: sql_help.c:384 sql_help.c:1924 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "funzione_validazione" -#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1085 sql_help.c:1296 -#: sql_help.c:2493 sql_help.c:2494 sql_help.c:2510 sql_help.c:2511 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "azione" -#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 -#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 -#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 -#: sql_help.c:660 sql_help.c:662 sql_help.c:923 sql_help.c:1087 sql_help.c:1105 -#: sql_help.c:1109 sql_help.c:1110 sql_help.c:1114 sql_help.c:1116 -#: sql_help.c:1117 sql_help.c:1118 sql_help.c:1120 sql_help.c:1123 -#: sql_help.c:1124 sql_help.c:1126 sql_help.c:1129 sql_help.c:1131 -#: sql_help.c:1398 sql_help.c:1401 sql_help.c:1421 sql_help.c:1525 -#: sql_help.c:1630 sql_help.c:1635 sql_help.c:1649 sql_help.c:1650 -#: sql_help.c:1651 sql_help.c:1964 sql_help.c:1977 sql_help.c:2021 -#: sql_help.c:2082 sql_help.c:2117 sql_help.c:2315 sql_help.c:2343 -#: sql_help.c:2344 sql_help.c:2444 sql_help.c:2452 sql_help.c:2461 -#: sql_help.c:2464 sql_help.c:2473 sql_help.c:2477 sql_help.c:2498 -#: sql_help.c:2500 sql_help.c:2507 sql_help.c:2522 sql_help.c:2539 -#: sql_help.c:2664 sql_help.c:2800 sql_help.c:3367 sql_help.c:3368 -#: sql_help.c:3448 sql_help.c:3463 sql_help.c:3465 sql_help.c:3467 -#: sql_help.c:3700 sql_help.c:3701 sql_help.c:3801 sql_help.c:3944 -#: sql_help.c:4183 sql_help.c:4225 sql_help.c:4227 sql_help.c:4229 -#: sql_help.c:4246 sql_help.c:4249 sql_help.c:4377 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "nome_colonna" -#: sql_help.c:436 sql_help.c:646 sql_help.c:1088 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "nuovo_nome_colonna" -#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1104 sql_help.c:1312 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" msgstr "dove azione è una di:" -#: sql_help.c:443 sql_help.c:448 sql_help.c:915 sql_help.c:1106 sql_help.c:1111 -#: sql_help.c:1314 sql_help.c:1318 sql_help.c:1876 sql_help.c:1965 -#: sql_help.c:2156 sql_help.c:2308 sql_help.c:2445 sql_help.c:2709 -#: sql_help.c:3550 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "tipo_di_dato" -#: sql_help.c:444 sql_help.c:449 sql_help.c:1107 sql_help.c:1112 -#: sql_help.c:1315 sql_help.c:1319 sql_help.c:1877 sql_help.c:1968 -#: sql_help.c:2084 sql_help.c:2446 sql_help.c:2454 sql_help.c:2466 -#: sql_help.c:2479 sql_help.c:2710 sql_help.c:2716 sql_help.c:3458 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "ordinamento" -#: sql_help.c:445 sql_help.c:1108 sql_help.c:1969 sql_help.c:1978 -#: sql_help.c:2447 sql_help.c:2462 sql_help.c:2474 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" msgstr "vincolo_di_colonna" -#: sql_help.c:455 sql_help.c:656 sql_help.c:1125 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "intero" -#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1127 -#: sql_help.c:1130 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "opzione_attributo" -#: sql_help.c:465 sql_help.c:1132 sql_help.c:1970 sql_help.c:1979 -#: sql_help.c:2448 sql_help.c:2463 sql_help.c:2475 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 msgid "table_constraint" msgstr "vincoli_di_tabella" -#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1137 -#: sql_help.c:1138 sql_help.c:1139 sql_help.c:1140 sql_help.c:1571 +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "nome_trigger" -#: sql_help.c:472 sql_help.c:473 sql_help.c:1150 sql_help.c:1151 -#: sql_help.c:1971 sql_help.c:1976 sql_help.c:2451 sql_help.c:2472 +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 msgid "parent_table" msgstr "tabella_padre" -#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1275 sql_help.c:1908 +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 msgid "extension_name" msgstr "nome_estensione" -#: sql_help.c:532 sql_help.c:2025 +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "costo_di_esecuzione" -#: sql_help.c:533 sql_help.c:2026 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "righe_risultato" -#: sql_help.c:554 sql_help.c:556 sql_help.c:853 sql_help.c:861 sql_help.c:865 -#: sql_help.c:868 sql_help.c:871 sql_help.c:1353 sql_help.c:1361 -#: sql_help.c:1364 sql_help.c:1366 sql_help.c:1368 sql_help.c:2286 -#: sql_help.c:2288 sql_help.c:2291 sql_help.c:2292 sql_help.c:3366 -#: sql_help.c:3370 sql_help.c:3373 sql_help.c:3375 sql_help.c:3377 -#: sql_help.c:3379 sql_help.c:3381 sql_help.c:3387 sql_help.c:3389 -#: sql_help.c:3391 sql_help.c:3393 sql_help.c:3395 sql_help.c:3397 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 msgid "role_specification" msgstr "specifica_ruolo" -#: sql_help.c:555 sql_help.c:557 sql_help.c:1380 sql_help.c:1851 -#: sql_help.c:2294 sql_help.c:2785 sql_help.c:3206 sql_help.c:4029 +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "nome_utente" -#: sql_help.c:558 sql_help.c:873 sql_help.c:1369 sql_help.c:2293 -#: sql_help.c:3398 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 msgid "where role_specification can be:" msgstr "dove specifica_ruolo può essere:" -#: sql_help.c:560 +#: sql_help.c:569 msgid "group_name" msgstr "nome_gruppo" -#: sql_help.c:578 sql_help.c:1856 sql_help.c:2088 sql_help.c:2120 -#: sql_help.c:2458 sql_help.c:2470 sql_help.c:2483 sql_help.c:2520 -#: sql_help.c:2542 sql_help.c:2554 sql_help.c:3394 sql_help.c:3727 +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" msgstr "nome_tablespace" -#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1147 -#: sql_help.c:1149 sql_help.c:2086 sql_help.c:2118 sql_help.c:2456 -#: sql_help.c:2468 sql_help.c:2481 sql_help.c:2518 sql_help.c:2540 +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "nome_indice" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "parametro_di_memorizzazione" -#: sql_help.c:608 sql_help.c:1542 sql_help.c:3812 +#: sql_help.c:601 +msgid "column_number" +msgstr "numero_colonna" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" msgstr "oid_large_object" -#: sql_help.c:663 sql_help.c:1145 sql_help.c:1154 sql_help.c:1157 -#: sql_help.c:1461 -msgid "index_name" -msgstr "nome_indice" - -#: sql_help.c:695 sql_help.c:2141 +#: sql_help.c:712 sql_help.c:2402 msgid "res_proc" msgstr "res_proc" -#: sql_help.c:696 sql_help.c:2142 +#: sql_help.c:713 sql_help.c:2403 msgid "join_proc" msgstr "proc_join" -#: sql_help.c:748 sql_help.c:760 sql_help.c:2159 +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" msgstr "strategia_num" -#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 -#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2161 sql_help.c:2162 -#: sql_help.c:2165 sql_help.c:2166 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "tipo_op" -#: sql_help.c:752 sql_help.c:2163 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "nome_famiglia_sort" -#: sql_help.c:753 sql_help.c:763 sql_help.c:2164 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "num_supporto" -#: sql_help.c:757 sql_help.c:1795 sql_help.c:2168 sql_help.c:2631 -#: sql_help.c:2633 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "tipo_argomento" -#: sql_help.c:788 sql_help.c:791 sql_help.c:808 sql_help.c:810 sql_help.c:812 -#: sql_help.c:883 sql_help.c:922 sql_help.c:1271 sql_help.c:1274 -#: sql_help.c:1420 sql_help.c:1460 sql_help.c:1527 sql_help.c:1552 -#: sql_help.c:1557 sql_help.c:1572 sql_help.c:1629 sql_help.c:1634 -#: sql_help.c:1963 sql_help.c:1975 sql_help.c:2080 sql_help.c:2116 -#: sql_help.c:2192 sql_help.c:2207 sql_help.c:2263 sql_help.c:2314 -#: sql_help.c:2345 sql_help.c:2443 sql_help.c:2459 sql_help.c:2471 -#: sql_help.c:2538 sql_help.c:2657 sql_help.c:2834 sql_help.c:3051 -#: sql_help.c:3076 sql_help.c:3182 sql_help.c:3364 sql_help.c:3369 -#: sql_help.c:3414 sql_help.c:3446 sql_help.c:3697 sql_help.c:3702 -#: sql_help.c:3800 sql_help.c:3899 sql_help.c:3901 sql_help.c:3950 -#: sql_help.c:3989 sql_help.c:4138 sql_help.c:4140 sql_help.c:4189 -#: sql_help.c:4223 sql_help.c:4245 sql_help.c:4247 sql_help.c:4248 -#: sql_help.c:4332 sql_help.c:4334 sql_help.c:4383 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 msgid "table_name" msgstr "nome_tabella" -#: sql_help.c:793 sql_help.c:2194 +#: sql_help.c:810 sql_help.c:2455 msgid "using_expression" msgstr "espressione_using" -#: sql_help.c:794 sql_help.c:2195 +#: sql_help.c:811 sql_help.c:2456 msgid "check_expression" msgstr "espressione_check" -#: sql_help.c:814 sql_help.c:2208 +#: sql_help.c:885 sql_help.c:2497 msgid "publication_parameter" msgstr "parametro_pubblicazione" -#: sql_help.c:857 sql_help.c:1357 sql_help.c:2060 sql_help.c:2240 -#: sql_help.c:2768 +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "password" -#: sql_help.c:858 sql_help.c:1358 sql_help.c:2061 sql_help.c:2241 -#: sql_help.c:2769 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "timestamp" -#: sql_help.c:862 sql_help.c:866 sql_help.c:869 sql_help.c:872 sql_help.c:3374 -#: sql_help.c:3707 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "nome_database" -#: sql_help.c:916 sql_help.c:2309 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" msgstr "incremento" -#: sql_help.c:917 sql_help.c:2310 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "valoremin" -#: sql_help.c:918 sql_help.c:2311 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "valoremax" -#: sql_help.c:919 sql_help.c:2312 sql_help.c:3897 sql_help.c:3987 -#: sql_help.c:4136 sql_help.c:4265 sql_help.c:4330 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" msgstr "inizio" -#: sql_help.c:920 sql_help.c:1122 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" msgstr "riavvio" -#: sql_help.c:921 sql_help.c:2313 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" msgstr "cache" -#: sql_help.c:978 sql_help.c:2357 +#: sql_help.c:1109 sql_help.c:2646 msgid "conninfo" msgstr "conninfo" -#: sql_help.c:980 sql_help.c:2358 +#: sql_help.c:1111 sql_help.c:2647 msgid "publication_name" msgstr "nome_pubblicazione" -#: sql_help.c:981 sql_help.c:984 +#: sql_help.c:1112 +msgid "set_publication_option" +msgstr "opzione_set_publication" + +#: sql_help.c:1115 msgid "refresh_option" msgstr "opzione_refresh" -#: sql_help.c:989 sql_help.c:2359 +#: sql_help.c:1120 sql_help.c:2648 msgid "subscription_parameter" msgstr "parametro_sottoscrizione" -#: sql_help.c:1100 sql_help.c:1103 +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" msgstr "nome_partizione" -#: sql_help.c:1101 sql_help.c:1980 sql_help.c:2476 +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 msgid "partition_bound_spec" msgstr "specifica_margine_partizione" -#: sql_help.c:1119 sql_help.c:2488 +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 msgid "sequence_options" msgstr "opzioni_sequenza" -#: sql_help.c:1121 +#: sql_help.c:1294 msgid "sequence_option" msgstr "opzione_sequenza" -#: sql_help.c:1133 +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "vincoli_di_tabella_con_indice" -#: sql_help.c:1141 sql_help.c:1142 sql_help.c:1143 sql_help.c:1144 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "nome_regola_di_riscrittura" -#: sql_help.c:1155 -msgid "and table_constraint_using_index is:" -msgstr "e vincolo_di_tabella_con_indice è:" +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "e specifica_margine_partizione è:" + +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "letterale_numerico" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "letterale_stringa" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "e vincolo_di_colonna è:" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "expr_default" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "parametri_di_indice" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "tabella_ref" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "colonna_ref" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "e vincolo_di_tabella è:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "elemento_di_esclusione" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "operatore" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "predicato" + +#: sql_help.c:1365 +msgid "and table_constraint_using_index is:" +msgstr "e vincolo_di_tabella_con_indice è:" + +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "parametri_di_indice nei vincoli UNIQUE, PRIMARY KEY e EXCLUDE sono:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "elemento_di_esclusione in un vincolo EXCLUDE è:" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "classe_op" -#: sql_help.c:1173 sql_help.c:1176 sql_help.c:2557 +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" msgstr "opzione_tablespace" -#: sql_help.c:1197 sql_help.c:1200 sql_help.c:1206 sql_help.c:1210 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "tipo_di_token" -#: sql_help.c:1198 sql_help.c:1201 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "nome_dizionario" -#: sql_help.c:1203 sql_help.c:1207 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "vecchio_dizionario" -#: sql_help.c:1204 sql_help.c:1208 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "nuovo_dizionario" -#: sql_help.c:1300 sql_help.c:1313 sql_help.c:1316 sql_help.c:1317 -#: sql_help.c:2708 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "nome_attributo" -#: sql_help.c:1301 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "nuovo_nome_attributo" -#: sql_help.c:1307 sql_help.c:1311 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "nuovo_valore_enum" -#: sql_help.c:1308 +#: sql_help.c:1527 msgid "neighbor_enum_value" msgstr "valore_enum_vicino" -#: sql_help.c:1310 +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "valore_enum_esistente" -#: sql_help.c:1381 sql_help.c:1972 sql_help.c:1981 sql_help.c:2325 -#: sql_help.c:2786 sql_help.c:3207 sql_help.c:3380 sql_help.c:3415 -#: sql_help.c:3713 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" msgstr "nome_server" -#: sql_help.c:1409 sql_help.c:1412 sql_help.c:2801 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "nome_opzione_vista" -#: sql_help.c:1410 sql_help.c:2802 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" msgstr "valore_opzione_vista" -#: sql_help.c:1435 sql_help.c:4045 sql_help.c:4047 sql_help.c:4071 +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "tabelle_e_colonne" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "dove opzione può essere una di:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "e tabelle_e_colonne è:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "modalità_transazione" -#: sql_help.c:1436 sql_help.c:4048 sql_help.c:4072 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" msgstr "dove modalità_transazione è una di:" -#: sql_help.c:1524 +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "argomento" + +#: sql_help.c:1772 msgid "relation_name" msgstr "nome_relazione" -#: sql_help.c:1529 sql_help.c:3376 sql_help.c:3709 +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 msgid "domain_name" msgstr "nome_dominio" -#: sql_help.c:1551 +#: sql_help.c:1799 msgid "policy_name" msgstr "nome_regola" -#: sql_help.c:1556 +#: sql_help.c:1812 msgid "rule_name" msgstr "nome_ruolo" -#: sql_help.c:1575 +#: sql_help.c:1831 msgid "text" msgstr "testo" -#: sql_help.c:1600 sql_help.c:3559 sql_help.c:3747 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" msgstr "id_transazione" -#: sql_help.c:1631 sql_help.c:1637 sql_help.c:3485 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "nome_file" -#: sql_help.c:1632 sql_help.c:1638 sql_help.c:2265 sql_help.c:2266 -#: sql_help.c:2267 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "comando" -#: sql_help.c:1636 sql_help.c:2121 sql_help.c:2543 sql_help.c:2803 -#: sql_help.c:2821 sql_help.c:3450 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "query" -#: sql_help.c:1640 sql_help.c:3253 -msgid "where option can be one of:" -msgstr "dove opzione può essere una di:" - -#: sql_help.c:1641 +#: sql_help.c:1897 msgid "format_name" msgstr "nome_formato" -#: sql_help.c:1642 sql_help.c:1643 sql_help.c:1646 sql_help.c:3254 -#: sql_help.c:3255 sql_help.c:3256 sql_help.c:3257 sql_help.c:3258 -#: sql_help.c:3259 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" msgstr "booleano" -#: sql_help.c:1644 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "carattere_delimitatore" -#: sql_help.c:1645 +#: sql_help.c:1901 msgid "null_string" msgstr "stringa_nulla" -#: sql_help.c:1647 +#: sql_help.c:1903 msgid "quote_character" msgstr "carattere_virgolette" -#: sql_help.c:1648 +#: sql_help.c:1904 msgid "escape_character" msgstr "carattere_di_escape" -#: sql_help.c:1652 +#: sql_help.c:1908 msgid "encoding_name" msgstr "nome_codifica" -#: sql_help.c:1663 +#: sql_help.c:1919 msgid "access_method_type" msgstr "tipo_metodo_accesso" -#: sql_help.c:1729 sql_help.c:1748 sql_help.c:1751 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "topo_dato_argomento" -#: sql_help.c:1730 sql_help.c:1752 sql_help.c:1760 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "sfunz" -#: sql_help.c:1731 sql_help.c:1753 sql_help.c:1761 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "tipo_dato_stato" -#: sql_help.c:1732 sql_help.c:1754 sql_help.c:1762 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "dimensione_dato_stato" -#: sql_help.c:1733 sql_help.c:1755 sql_help.c:1763 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "ffunz" -#: sql_help.c:1734 sql_help.c:1764 +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "funz_combine" -#: sql_help.c:1735 sql_help.c:1765 +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "funz_serial" -#: sql_help.c:1736 sql_help.c:1766 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "funz_deserial" -#: sql_help.c:1737 sql_help.c:1756 sql_help.c:1767 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "condizione_iniziale" -#: sql_help.c:1738 sql_help.c:1768 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "msfunz" -#: sql_help.c:1739 sql_help.c:1769 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "minvfunz" -#: sql_help.c:1740 sql_help.c:1770 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "tipo_dato_mstato" -#: sql_help.c:1741 sql_help.c:1771 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "tipo_dato_mstato" -#: sql_help.c:1742 sql_help.c:1772 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "mffunz" -#: sql_help.c:1743 sql_help.c:1773 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "condizione_minima" -#: sql_help.c:1744 sql_help.c:1774 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "operatore_di_ordinamento" -#: sql_help.c:1757 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "o la vecchia sintassi" -#: sql_help.c:1759 +#: sql_help.c:2020 msgid "base_type" msgstr "tipo_base" -#: sql_help.c:1815 +#: sql_help.c:2076 msgid "locale" msgstr "locale" -#: sql_help.c:1816 sql_help.c:1854 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1817 sql_help.c:1855 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1818 sql_help.c:3798 +#: sql_help.c:2079 sql_help.c:4122 msgid "provider" msgstr "provider" -#: sql_help.c:1819 sql_help.c:1910 +#: sql_help.c:2080 sql_help.c:2171 msgid "version" msgstr "versione" -#: sql_help.c:1821 +#: sql_help.c:2082 msgid "existing_collation" msgstr "ordinamento_esistente" -#: sql_help.c:1831 +#: sql_help.c:2092 msgid "source_encoding" msgstr "codifica_origine" -#: sql_help.c:1832 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "codifica_destinazione" -#: sql_help.c:1852 sql_help.c:2583 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "template" -#: sql_help.c:1853 +#: sql_help.c:2114 msgid "encoding" msgstr "codifica" -#: sql_help.c:1879 +#: sql_help.c:2140 msgid "constraint" msgstr "vincolo" -#: sql_help.c:1880 +#: sql_help.c:2141 msgid "where constraint is:" msgstr "dove vincolo di è:" -#: sql_help.c:1894 sql_help.c:2262 sql_help.c:2656 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "evento" -#: sql_help.c:1895 +#: sql_help.c:2156 msgid "filter_variable" msgstr "valiabile_filtro" -#: sql_help.c:1911 +#: sql_help.c:2172 msgid "old_version" msgstr "vecchia_versione" -#: sql_help.c:1984 sql_help.c:2484 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" msgstr "dove vincolo_di_colonna è:" -#: sql_help.c:1987 sql_help.c:2019 sql_help.c:2487 -msgid "default_expr" -msgstr "expr_default" - -#: sql_help.c:1988 sql_help.c:2495 -msgid "and table_constraint is:" -msgstr "e vincolo_di_tabella è:" - -#: sql_help.c:2020 +#: sql_help.c:2280 msgid "rettype" msgstr "tipo_ritorno" -#: sql_help.c:2022 +#: sql_help.c:2282 msgid "column_type" msgstr "tipo_colonna" -#: sql_help.c:2030 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "definizione" -#: sql_help.c:2031 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "file_obj" -#: sql_help.c:2032 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "simbolo_link" -#: sql_help.c:2033 -msgid "attribute" -msgstr "attributo" - -#: sql_help.c:2067 sql_help.c:2247 sql_help.c:2775 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" msgstr "uid" -#: sql_help.c:2081 +#: sql_help.c:2341 msgid "method" msgstr "metodo" -#: sql_help.c:2085 sql_help.c:2455 sql_help.c:2467 sql_help.c:2480 -#: sql_help.c:2524 sql_help.c:3459 -msgid "opclass" -msgstr "classe_op" - -#: sql_help.c:2089 sql_help.c:2506 -msgid "predicate" -msgstr "predicato" - -#: sql_help.c:2101 +#: sql_help.c:2362 msgid "call_handler" msgstr "handler_chiamata" -#: sql_help.c:2102 +#: sql_help.c:2363 msgid "inline_handler" msgstr "handler_inline" -#: sql_help.c:2103 +#: sql_help.c:2364 msgid "valfunction" msgstr "funzione_valid" -#: sql_help.c:2139 +#: sql_help.c:2400 msgid "com_op" msgstr "com_op" -#: sql_help.c:2140 +#: sql_help.c:2401 msgid "neg_op" msgstr "neg_op" -#: sql_help.c:2158 +#: sql_help.c:2419 msgid "family_name" msgstr "nome_famiglia" -#: sql_help.c:2169 +#: sql_help.c:2430 msgid "storage_type" msgstr "tipo_memorizzazione" -#: sql_help.c:2264 sql_help.c:2660 sql_help.c:2837 sql_help.c:3469 -#: sql_help.c:3888 sql_help.c:3890 sql_help.c:3978 sql_help.c:3980 -#: sql_help.c:4127 sql_help.c:4129 sql_help.c:4232 sql_help.c:4321 -#: sql_help.c:4323 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "condizione" -#: sql_help.c:2268 sql_help.c:2663 +#: sql_help.c:2557 sql_help.c:2961 msgid "where event can be one of:" msgstr "dove evento può essere uno di:" -#: sql_help.c:2287 sql_help.c:2289 +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "elemento_di_schema" -#: sql_help.c:2326 +#: sql_help.c:2615 msgid "server_type" msgstr "tipo_di_server" -#: sql_help.c:2327 +#: sql_help.c:2616 msgid "server_version" msgstr "versione_server" -#: sql_help.c:2328 sql_help.c:3378 sql_help.c:3711 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" msgstr "nome_fdw" -#: sql_help.c:2341 +#: sql_help.c:2630 msgid "statistics_name" msgstr "nome_statistica" -#: sql_help.c:2342 -msgid "statistic_type" +#: sql_help.c:2631 +msgid "statistics_kind" msgstr "tipo_statistica" -#: sql_help.c:2356 +#: sql_help.c:2645 msgid "subscription_name" msgstr "nome_sottoscrizione" -#: sql_help.c:2449 +#: sql_help.c:2741 msgid "source_table" msgstr "tabella_origine" -#: sql_help.c:2450 +#: sql_help.c:2742 msgid "like_option" msgstr "opzioni_di_like" -#: sql_help.c:2489 sql_help.c:2490 sql_help.c:2499 sql_help.c:2501 -#: sql_help.c:2505 -msgid "index_parameters" -msgstr "parametri_di_indice" - -#: sql_help.c:2491 sql_help.c:2508 -msgid "reftable" -msgstr "tabella_ref" - -#: sql_help.c:2492 sql_help.c:2509 -msgid "refcolumn" -msgstr "colonna_ref" - -#: sql_help.c:2503 -msgid "exclude_element" -msgstr "elemento_di_esclusione" - -#: sql_help.c:2504 sql_help.c:3895 sql_help.c:3985 sql_help.c:4134 -#: sql_help.c:4263 sql_help.c:4328 -msgid "operator" -msgstr "operatore" - -#: sql_help.c:2512 +#: sql_help.c:2804 msgid "and like_option is:" msgstr "e opzione_like è:" -#: sql_help.c:2513 -msgid "and partition_bound_spec is:" -msgstr "e specifica_margine_partizione è:" - -#: sql_help.c:2514 sql_help.c:2515 sql_help.c:2516 -msgid "bound_literal" -msgstr "letterale_limite" - -#: sql_help.c:2517 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "parametri_di_indice nei vincoli UNIQUE, PRIMARY KEY e EXCLUDE sono:" - -#: sql_help.c:2521 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "elemento_di_esclusione in un vincolo EXCLUDE è:" - -#: sql_help.c:2556 +#: sql_help.c:2854 msgid "directory" msgstr "directory" -#: sql_help.c:2570 +#: sql_help.c:2868 msgid "parser_name" msgstr "nome_parser" -#: sql_help.c:2571 +#: sql_help.c:2869 msgid "source_config" msgstr "config_origine" -#: sql_help.c:2600 +#: sql_help.c:2898 msgid "start_function" msgstr "funzione_inizio" -#: sql_help.c:2601 +#: sql_help.c:2899 msgid "gettoken_function" msgstr "funzione_gettoken" -#: sql_help.c:2602 +#: sql_help.c:2900 msgid "end_function" msgstr "funzione_fine" -#: sql_help.c:2603 +#: sql_help.c:2901 msgid "lextypes_function" msgstr "funzione_lextypes" -#: sql_help.c:2604 +#: sql_help.c:2902 msgid "headline_function" msgstr "funzione_headline" -#: sql_help.c:2616 +#: sql_help.c:2914 msgid "init_function" msgstr "funzione_init" -#: sql_help.c:2617 +#: sql_help.c:2915 msgid "lexize_function" msgstr "funzione_lexize" -#: sql_help.c:2630 +#: sql_help.c:2928 msgid "from_sql_function_name" msgstr "nome_funzione_from_sql" -#: sql_help.c:2632 +#: sql_help.c:2930 msgid "to_sql_function_name" msgstr "nome_funzione_to_sql" -#: sql_help.c:2658 +#: sql_help.c:2956 msgid "referenced_table_name" msgstr "nome_tabella_referenziata" -#: sql_help.c:2659 +#: sql_help.c:2957 msgid "transition_relation_name" msgstr "nome_tabella_transizione" -#: sql_help.c:2662 +#: sql_help.c:2960 msgid "arguments" msgstr "argomenti" -#: sql_help.c:2712 sql_help.c:3823 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "etichetta" -#: sql_help.c:2714 +#: sql_help.c:3012 msgid "subtype" msgstr "sottotipo" -#: sql_help.c:2715 +#: sql_help.c:3013 msgid "subtype_operator_class" msgstr "classe_operatore_sottotipo" -#: sql_help.c:2717 +#: sql_help.c:3015 msgid "canonical_function" msgstr "funzione_canonica" -#: sql_help.c:2718 +#: sql_help.c:3016 msgid "subtype_diff_function" msgstr "funzione_diff_sottotipo" -#: sql_help.c:2720 +#: sql_help.c:3018 msgid "input_function" msgstr "funzione_input" -#: sql_help.c:2721 +#: sql_help.c:3019 msgid "output_function" msgstr "funzione_output" -#: sql_help.c:2722 +#: sql_help.c:3020 msgid "receive_function" msgstr "funzione_receive" -#: sql_help.c:2723 +#: sql_help.c:3021 msgid "send_function" msgstr "funzione_send" -#: sql_help.c:2724 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "funzione_input_modificatore_tipo" -#: sql_help.c:2725 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "funzione_output_modificatore_tipo" -#: sql_help.c:2726 +#: sql_help.c:3024 msgid "analyze_function" msgstr "funzione_analyze" -#: sql_help.c:2727 +#: sql_help.c:3025 msgid "internallength" msgstr "lunghezza_interna" -#: sql_help.c:2728 +#: sql_help.c:3026 msgid "alignment" msgstr "allineamento" -#: sql_help.c:2729 +#: sql_help.c:3027 msgid "storage" msgstr "memorizzazione" -#: sql_help.c:2730 +#: sql_help.c:3028 msgid "like_type" msgstr "tipo_like" -#: sql_help.c:2731 +#: sql_help.c:3029 msgid "category" msgstr "categoria" -#: sql_help.c:2732 +#: sql_help.c:3030 msgid "preferred" msgstr "preferito" -#: sql_help.c:2733 +#: sql_help.c:3031 msgid "default" msgstr "predefinito" -#: sql_help.c:2734 +#: sql_help.c:3032 msgid "element" msgstr "elemento" -#: sql_help.c:2735 +#: sql_help.c:3033 msgid "delimiter" msgstr "delimitatore" -#: sql_help.c:2736 +#: sql_help.c:3034 msgid "collatable" msgstr "ordinabile" -#: sql_help.c:2833 sql_help.c:3445 sql_help.c:3883 sql_help.c:3972 -#: sql_help.c:4122 sql_help.c:4222 sql_help.c:4316 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "query_with" -#: sql_help.c:2835 sql_help.c:3447 sql_help.c:3902 sql_help.c:3908 -#: sql_help.c:3911 sql_help.c:3915 sql_help.c:3919 sql_help.c:3927 -#: sql_help.c:4141 sql_help.c:4147 sql_help.c:4150 sql_help.c:4154 -#: sql_help.c:4158 sql_help.c:4166 sql_help.c:4224 sql_help.c:4335 -#: sql_help.c:4341 sql_help.c:4344 sql_help.c:4348 sql_help.c:4352 -#: sql_help.c:4360 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" msgstr "alias" -#: sql_help.c:2836 +#: sql_help.c:3134 msgid "using_list" msgstr "lista_using" -#: sql_help.c:2838 sql_help.c:3285 sql_help.c:3526 sql_help.c:4233 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "nome_cursore" -#: sql_help.c:2839 sql_help.c:3453 sql_help.c:4234 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "espressione_output" -#: sql_help.c:2840 sql_help.c:3454 sql_help.c:3886 sql_help.c:3975 -#: sql_help.c:4125 sql_help.c:4235 sql_help.c:4319 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "nome_output" -#: sql_help.c:2856 +#: sql_help.c:3154 msgid "code" msgstr "codice" -#: sql_help.c:3231 +#: sql_help.c:3553 msgid "parameter" msgstr "parametro" -#: sql_help.c:3251 sql_help.c:3252 sql_help.c:3551 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "istruzione" -#: sql_help.c:3284 sql_help.c:3525 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" msgstr "direzione" -#: sql_help.c:3286 sql_help.c:3527 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" msgstr "dove direzione può essere vuota o una di:" -#: sql_help.c:3287 sql_help.c:3288 sql_help.c:3289 sql_help.c:3290 -#: sql_help.c:3291 sql_help.c:3528 sql_help.c:3529 sql_help.c:3530 -#: sql_help.c:3531 sql_help.c:3532 sql_help.c:3896 sql_help.c:3898 -#: sql_help.c:3986 sql_help.c:3988 sql_help.c:4135 sql_help.c:4137 -#: sql_help.c:4264 sql_help.c:4266 sql_help.c:4329 sql_help.c:4331 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" msgstr "conteggio" -#: sql_help.c:3371 sql_help.c:3704 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "nome_sequenza" -#: sql_help.c:3384 sql_help.c:3717 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "nome_arg" -#: sql_help.c:3385 sql_help.c:3718 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "tipo_arg" -#: sql_help.c:3390 sql_help.c:3723 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "loid" -#: sql_help.c:3413 +#: sql_help.c:3735 msgid "remote_schema" msgstr "schema_remoto" -#: sql_help.c:3416 +#: sql_help.c:3738 msgid "local_schema" msgstr "schema_locale" -#: sql_help.c:3451 +#: sql_help.c:3773 msgid "conflict_target" msgstr "target_conflitto" -#: sql_help.c:3452 +#: sql_help.c:3774 msgid "conflict_action" msgstr "azione_conflitto" -#: sql_help.c:3455 +#: sql_help.c:3777 msgid "where conflict_target can be one of:" msgstr "dove target_conflitto può essere uno di:" -#: sql_help.c:3456 +#: sql_help.c:3778 msgid "index_column_name" msgstr "nome_colonna_indice" -#: sql_help.c:3457 +#: sql_help.c:3779 msgid "index_expression" msgstr "espressione_indice" -#: sql_help.c:3460 +#: sql_help.c:3782 msgid "index_predicate" msgstr "indice_predicato" -#: sql_help.c:3462 +#: sql_help.c:3784 msgid "and conflict_action is one of:" msgstr "e azione_conflitto è una di:" -#: sql_help.c:3468 sql_help.c:4230 +#: sql_help.c:3790 sql_help.c:4562 msgid "sub-SELECT" msgstr "sub-SELECT" -#: sql_help.c:3477 sql_help.c:3540 sql_help.c:4206 +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "canale" -#: sql_help.c:3499 +#: sql_help.c:3821 msgid "lockmode" msgstr "modalità_lock" -#: sql_help.c:3500 +#: sql_help.c:3822 msgid "where lockmode is one of:" msgstr "dove modalità_lock è una di:" -#: sql_help.c:3541 +#: sql_help.c:3863 msgid "payload" msgstr "payload" -#: sql_help.c:3568 +#: sql_help.c:3890 msgid "old_role" msgstr "vecchio_ruolo" -#: sql_help.c:3569 +#: sql_help.c:3891 msgid "new_role" msgstr "nuovo_ruolo" -#: sql_help.c:3594 sql_help.c:3755 sql_help.c:3763 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "nome_punto_salvataggio" -#: sql_help.c:3887 sql_help.c:3929 sql_help.c:3931 sql_help.c:3977 -#: sql_help.c:4126 sql_help.c:4168 sql_help.c:4170 sql_help.c:4320 -#: sql_help.c:4362 sql_help.c:4364 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" msgstr "elemento_from" -#: sql_help.c:3889 sql_help.c:3941 sql_help.c:4128 sql_help.c:4180 -#: sql_help.c:4322 sql_help.c:4374 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 msgid "grouping_element" msgstr "elemento_raggruppante" -#: sql_help.c:3891 sql_help.c:3981 sql_help.c:4130 sql_help.c:4324 +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "nome_finestra" -#: sql_help.c:3892 sql_help.c:3982 sql_help.c:4131 sql_help.c:4325 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "definizione_finestra" -#: sql_help.c:3893 sql_help.c:3907 sql_help.c:3945 sql_help.c:3983 -#: sql_help.c:4132 sql_help.c:4146 sql_help.c:4184 sql_help.c:4326 -#: sql_help.c:4340 sql_help.c:4378 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "select" -#: sql_help.c:3900 sql_help.c:4139 sql_help.c:4333 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" msgstr "dove from_item può essere uno di:" -#: sql_help.c:3903 sql_help.c:3909 sql_help.c:3912 sql_help.c:3916 -#: sql_help.c:3928 sql_help.c:4142 sql_help.c:4148 sql_help.c:4151 -#: sql_help.c:4155 sql_help.c:4167 sql_help.c:4336 sql_help.c:4342 -#: sql_help.c:4345 sql_help.c:4349 sql_help.c:4361 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" msgstr "alias_colonna" -#: sql_help.c:3904 sql_help.c:4143 sql_help.c:4337 +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 msgid "sampling_method" msgstr "metodo_di_campionamento" -#: sql_help.c:3905 sql_help.c:3914 sql_help.c:3918 sql_help.c:3922 -#: sql_help.c:3925 sql_help.c:4144 sql_help.c:4153 sql_help.c:4157 -#: sql_help.c:4161 sql_help.c:4164 sql_help.c:4338 sql_help.c:4347 -#: sql_help.c:4351 sql_help.c:4355 sql_help.c:4358 -msgid "argument" -msgstr "argomento" - -#: sql_help.c:3906 sql_help.c:4145 sql_help.c:4339 +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 msgid "seed" msgstr "seme" -#: sql_help.c:3910 sql_help.c:3943 sql_help.c:4149 sql_help.c:4182 -#: sql_help.c:4343 sql_help.c:4376 +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "nome_query_with" -#: sql_help.c:3920 sql_help.c:3923 sql_help.c:3926 sql_help.c:4159 -#: sql_help.c:4162 sql_help.c:4165 sql_help.c:4353 sql_help.c:4356 -#: sql_help.c:4359 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" msgstr "definizione_colonna" -#: sql_help.c:3930 sql_help.c:4169 sql_help.c:4363 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" msgstr "tipo_join" -#: sql_help.c:3932 sql_help.c:4171 sql_help.c:4365 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" msgstr "condizione_join" -#: sql_help.c:3933 sql_help.c:4172 sql_help.c:4366 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" msgstr "colonna_join" -#: sql_help.c:3934 sql_help.c:4173 sql_help.c:4367 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 msgid "and grouping_element can be one of:" msgstr "e elemento_raggruppante può essere uno di:" -#: sql_help.c:3942 sql_help.c:4181 sql_help.c:4375 +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" msgstr "e with_query è:" -#: sql_help.c:3946 sql_help.c:4185 sql_help.c:4379 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "valori" -#: sql_help.c:3947 sql_help.c:4186 sql_help.c:4380 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" msgstr "insert" -#: sql_help.c:3948 sql_help.c:4187 sql_help.c:4381 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "update" -#: sql_help.c:3949 sql_help.c:4188 sql_help.c:4382 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "delete" -#: sql_help.c:3976 +#: sql_help.c:4308 msgid "new_table" msgstr "nuova_tabella" -#: sql_help.c:4001 +#: sql_help.c:4333 msgid "timezone" msgstr "timezone" -#: sql_help.c:4046 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "id_snapshot" -#: sql_help.c:4231 +#: sql_help.c:4563 msgid "from_list" msgstr "lista_from" -#: sql_help.c:4262 +#: sql_help.c:4607 msgid "sort_expression" msgstr "espressione_ordinamento" -#: sql_help.c:4389 sql_help.c:5174 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" msgstr "annulla la transazione corrente" -#: sql_help.c:4394 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" msgstr "cambia la definizione di una funzione di aggregazione" -#: sql_help.c:4399 +#: sql_help.c:4744 msgid "change the definition of a collation" msgstr "cambia la definizione di un ordinamento" -#: sql_help.c:4404 +#: sql_help.c:4749 msgid "change the definition of a conversion" msgstr "cambia la definizione di una conversione" -#: sql_help.c:4409 +#: sql_help.c:4754 msgid "change a database" msgstr "cambia un database" -#: sql_help.c:4414 +#: sql_help.c:4759 msgid "define default access privileges" msgstr "definisci i privilegi di accesso di default" -#: sql_help.c:4419 +#: sql_help.c:4764 msgid "change the definition of a domain" msgstr "cambia la definizione di un dominio" -#: sql_help.c:4424 +#: sql_help.c:4769 msgid "change the definition of an event trigger" msgstr "cambia la definizione di un trigger di evento" -#: sql_help.c:4429 +#: sql_help.c:4774 msgid "change the definition of an extension" msgstr "cambia la definizione di una estensione" -#: sql_help.c:4434 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" msgstr "cambia la definizione di un wrapper di dati esterni" -#: sql_help.c:4439 +#: sql_help.c:4784 msgid "change the definition of a foreign table" msgstr "cambia la definizione di una tabella esterna" -#: sql_help.c:4444 +#: sql_help.c:4789 msgid "change the definition of a function" msgstr "cambia la definizione di una funzione" -#: sql_help.c:4449 +#: sql_help.c:4794 msgid "change role name or membership" msgstr "cambia il nome del ruolo o l'appartenenza" -#: sql_help.c:4454 +#: sql_help.c:4799 msgid "change the definition of an index" msgstr "cambia la definizione di un indice" -#: sql_help.c:4459 +#: sql_help.c:4804 msgid "change the definition of a procedural language" msgstr "cambia la definizione di un linguaggio procedurale" -#: sql_help.c:4464 +#: sql_help.c:4809 msgid "change the definition of a large object" msgstr "cambia la definizione di un large object" -#: sql_help.c:4469 +#: sql_help.c:4814 msgid "change the definition of a materialized view" msgstr "cambia la definizione di una vista materializzata" -#: sql_help.c:4474 +#: sql_help.c:4819 msgid "change the definition of an operator" msgstr "cambia la definizione di un operatore" -#: sql_help.c:4479 +#: sql_help.c:4824 msgid "change the definition of an operator class" msgstr "cambia la definizione di una classe di operatori" -#: sql_help.c:4484 +#: sql_help.c:4829 msgid "change the definition of an operator family" msgstr "cambia la definizione di una famiglia di operatori" -#: sql_help.c:4489 +#: sql_help.c:4834 msgid "change the definition of a row level security policy" msgstr "cambia la definizione di una regola di sicurezza per riga" -#: sql_help.c:4494 +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "cambia la definizione di una procedura" + +#: sql_help.c:4844 msgid "change the definition of a publication" msgstr "cambia la definizione di una pubblicazione" -#: sql_help.c:4499 sql_help.c:4579 +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" msgstr "cambia un ruolo di database" -#: sql_help.c:4504 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "cambia la definizione di una routine" + +#: sql_help.c:4859 msgid "change the definition of a rule" msgstr "cambia la definizione di una regola" -#: sql_help.c:4509 +#: sql_help.c:4864 msgid "change the definition of a schema" msgstr "cambia la definizione di uno schema" -#: sql_help.c:4514 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" msgstr "cambia la definizione di un generatore di sequenza" -#: sql_help.c:4519 +#: sql_help.c:4874 msgid "change the definition of a foreign server" msgstr "cambia la definizione di un server esterno" -#: sql_help.c:4524 +#: sql_help.c:4879 msgid "change the definition of an extended statistics object" msgstr "cambia la definizione di una statistica estesa" -#: sql_help.c:4529 +#: sql_help.c:4884 msgid "change the definition of a subscription" msgstr "cambia la definizione di una sottoscrizione" -#: sql_help.c:4534 +#: sql_help.c:4889 msgid "change a server configuration parameter" msgstr "cambia un parametro di configurazione del server" -#: sql_help.c:4539 +#: sql_help.c:4894 msgid "change the definition of a table" msgstr "cambia la definizione di una tabella" -#: sql_help.c:4544 +#: sql_help.c:4899 msgid "change the definition of a tablespace" msgstr "cambia la definizione di un tablespace" -#: sql_help.c:4549 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" msgstr "cambia la definizione di una configurazione di ricerca testo" -#: sql_help.c:4554 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" msgstr "cambia la definizione di un dizionario di ricerca testo" -#: sql_help.c:4559 +#: sql_help.c:4914 msgid "change the definition of a text search parser" msgstr "cambia la definizione di un analizzatore di ricerca testo" -#: sql_help.c:4564 +#: sql_help.c:4919 msgid "change the definition of a text search template" msgstr "cambia la definizione di un modello di ricerca testo" -#: sql_help.c:4569 +#: sql_help.c:4924 msgid "change the definition of a trigger" msgstr "cambia la definizione di un trigger" -#: sql_help.c:4574 +#: sql_help.c:4929 msgid "change the definition of a type" msgstr "cambia la definizione di un tipo di dato" -#: sql_help.c:4584 +#: sql_help.c:4939 msgid "change the definition of a user mapping" msgstr "cambia la definizione di una mappatura degli" -#: sql_help.c:4589 +#: sql_help.c:4944 msgid "change the definition of a view" msgstr "cambia la definizione di una vista" -#: sql_help.c:4594 +#: sql_help.c:4949 msgid "collect statistics about a database" msgstr "raccogli statistiche sul database" -#: sql_help.c:4599 sql_help.c:5239 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" msgstr "avvia un blocco di transazione" -#: sql_help.c:4604 +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "esegui una procedura" + +#: sql_help.c:4964 msgid "force a write-ahead log checkpoint" msgstr "forza un checkpoint del write-ahead log" -#: sql_help.c:4609 +#: sql_help.c:4969 msgid "close a cursor" msgstr "chiudi un cursore" -#: sql_help.c:4614 +#: sql_help.c:4974 msgid "cluster a table according to an index" msgstr "raggruppa una tabella in base ad un indice" -#: sql_help.c:4619 +#: sql_help.c:4979 msgid "define or change the comment of an object" msgstr "definisci o modifica il commento di un oggetto" -#: sql_help.c:4624 sql_help.c:5074 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" msgstr "rendi persistente la transazione corrente" -#: sql_help.c:4629 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "concludi transazione che è stata precedentemente preparata per un commit a due fasi" -#: sql_help.c:4634 +#: sql_help.c:4994 msgid "copy data between a file and a table" msgstr "copia i dati tra un file ed una tabella" -#: sql_help.c:4639 +#: sql_help.c:4999 msgid "define a new access method" msgstr "definisci un nuovo metodo di accesso" -#: sql_help.c:4644 +#: sql_help.c:5004 msgid "define a new aggregate function" msgstr "definisci una nuova funzione aggregata" -#: sql_help.c:4649 +#: sql_help.c:5009 msgid "define a new cast" msgstr "definisci una nuova conversione di tipi" -#: sql_help.c:4654 +#: sql_help.c:5014 msgid "define a new collation" msgstr "definisci un nuovo ordinamento" -#: sql_help.c:4659 +#: sql_help.c:5019 msgid "define a new encoding conversion" msgstr "definisci una nuova conversione di codifica" -#: sql_help.c:4664 +#: sql_help.c:5024 msgid "create a new database" msgstr "crea un nuovo database" -#: sql_help.c:4669 +#: sql_help.c:5029 msgid "define a new domain" msgstr "definisci un nuovo dominio" -#: sql_help.c:4674 +#: sql_help.c:5034 msgid "define a new event trigger" msgstr "definisci un nuovo trigger di evento" -#: sql_help.c:4679 +#: sql_help.c:5039 msgid "install an extension" msgstr "installa un'estensione" -#: sql_help.c:4684 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" msgstr "definisci un nuovo wrapper di dati esterni" -#: sql_help.c:4689 +#: sql_help.c:5049 msgid "define a new foreign table" msgstr "definisci una nuova tabella esterna" -#: sql_help.c:4694 +#: sql_help.c:5054 msgid "define a new function" msgstr "definisci una nuova funzione" -#: sql_help.c:4699 sql_help.c:4744 sql_help.c:4829 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" msgstr "definisci un nuovo ruolo database" -#: sql_help.c:4704 +#: sql_help.c:5064 msgid "define a new index" msgstr "crea un nuovo indice" -#: sql_help.c:4709 +#: sql_help.c:5069 msgid "define a new procedural language" msgstr "definisci un nuovo linguaggio procedurale" -#: sql_help.c:4714 +#: sql_help.c:5074 msgid "define a new materialized view" msgstr "definisci una nuova vista materializzata" -#: sql_help.c:4719 +#: sql_help.c:5079 msgid "define a new operator" msgstr "definisci un nuovo operatore" -#: sql_help.c:4724 +#: sql_help.c:5084 msgid "define a new operator class" msgstr "definisci una nuova classe di operatori" -#: sql_help.c:4729 +#: sql_help.c:5089 msgid "define a new operator family" msgstr "definisci una nuova famiglia operatore" -#: sql_help.c:4734 +#: sql_help.c:5094 msgid "define a new row level security policy for a table" msgstr "definisci una nuova regola di sicurezza per riga per una tabella" -#: sql_help.c:4739 +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "definisci una nuova procedura" + +#: sql_help.c:5104 msgid "define a new publication" msgstr "definisci una nuova pubblicazione" -#: sql_help.c:4749 +#: sql_help.c:5114 msgid "define a new rewrite rule" msgstr "definisci una nuova regola di riscrittura" -#: sql_help.c:4754 +#: sql_help.c:5119 msgid "define a new schema" msgstr "crea un nuovo schema" -#: sql_help.c:4759 +#: sql_help.c:5124 msgid "define a new sequence generator" msgstr "definisci un nuovo generatore di sequenze" -#: sql_help.c:4764 +#: sql_help.c:5129 msgid "define a new foreign server" msgstr "definisci un nuovo server esterno" -#: sql_help.c:4769 +#: sql_help.c:5134 msgid "define extended statistics" msgstr "definisci una statistica estesa" -#: sql_help.c:4774 +#: sql_help.c:5139 msgid "define a new subscription" msgstr "definisci una nuova sottoscrizione" -#: sql_help.c:4779 +#: sql_help.c:5144 msgid "define a new table" msgstr "crea una nuova tabella" -#: sql_help.c:4784 sql_help.c:5204 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" msgstr "crea una nuova tabella dai risultati di una query" -#: sql_help.c:4789 +#: sql_help.c:5154 msgid "define a new tablespace" msgstr "crea un nuovo tablespace" -#: sql_help.c:4794 +#: sql_help.c:5159 msgid "define a new text search configuration" msgstr "definisci una nuova configurazione di ricerca testo" -#: sql_help.c:4799 +#: sql_help.c:5164 msgid "define a new text search dictionary" msgstr "definisci un nuovo dizionario di ricerca testo" -#: sql_help.c:4804 +#: sql_help.c:5169 msgid "define a new text search parser" msgstr "definisci un nuovo analizzatore di ricerca testo" -#: sql_help.c:4809 +#: sql_help.c:5174 msgid "define a new text search template" msgstr "definisci un nuovo modello di ricerca testo" -#: sql_help.c:4814 +#: sql_help.c:5179 msgid "define a new transform" msgstr "definisci una nuova trasformazione" -#: sql_help.c:4819 +#: sql_help.c:5184 msgid "define a new trigger" msgstr "definisci un nuovo trigger" -#: sql_help.c:4824 +#: sql_help.c:5189 msgid "define a new data type" msgstr "definisci un nuovo tipo di dato" -#: sql_help.c:4834 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" msgstr "definisci una nuova mappatura di un utente ad un server esterno" -#: sql_help.c:4839 +#: sql_help.c:5204 msgid "define a new view" msgstr "definisci una nuova vista" -#: sql_help.c:4844 +#: sql_help.c:5209 msgid "deallocate a prepared statement" msgstr "dealloca una istruzione preparata" -#: sql_help.c:4849 +#: sql_help.c:5214 msgid "define a cursor" msgstr "definisci un cursore" -#: sql_help.c:4854 +#: sql_help.c:5219 msgid "delete rows of a table" msgstr "elimina le righe di una tabella" -#: sql_help.c:4859 +#: sql_help.c:5224 msgid "discard session state" msgstr "cancella lo stato della sessione" -#: sql_help.c:4864 +#: sql_help.c:5229 msgid "execute an anonymous code block" msgstr "esegui un blocco di codice anonimo" -#: sql_help.c:4869 +#: sql_help.c:5234 msgid "remove an access method" msgstr "rimuovi un metodo di accesso" -#: sql_help.c:4874 +#: sql_help.c:5239 msgid "remove an aggregate function" msgstr "elimina una funzione aggregata" -#: sql_help.c:4879 +#: sql_help.c:5244 msgid "remove a cast" msgstr "elimina una conversione di tipi" -#: sql_help.c:4884 +#: sql_help.c:5249 msgid "remove a collation" msgstr "elimina un ordinamento" -#: sql_help.c:4889 +#: sql_help.c:5254 msgid "remove a conversion" msgstr "elimina una conversione" -#: sql_help.c:4894 +#: sql_help.c:5259 msgid "remove a database" msgstr "elimina un database" -#: sql_help.c:4899 +#: sql_help.c:5264 msgid "remove a domain" msgstr "elimina un dominio" -#: sql_help.c:4904 +#: sql_help.c:5269 msgid "remove an event trigger" msgstr "elimina un trigger di evento" -#: sql_help.c:4909 +#: sql_help.c:5274 msgid "remove an extension" msgstr "elimina una estensione" -#: sql_help.c:4914 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" msgstr "elimina un wrapper di dati esterni" -#: sql_help.c:4919 +#: sql_help.c:5284 msgid "remove a foreign table" msgstr "elimina una tabella esterna" -#: sql_help.c:4924 +#: sql_help.c:5289 msgid "remove a function" msgstr "elimina una funzione" -#: sql_help.c:4929 sql_help.c:4979 sql_help.c:5059 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" msgstr "elimina un ruolo di database" -#: sql_help.c:4934 +#: sql_help.c:5299 msgid "remove an index" msgstr "elimina un indice" -#: sql_help.c:4939 +#: sql_help.c:5304 msgid "remove a procedural language" msgstr "elimina un linguaggio procedurale" -#: sql_help.c:4944 +#: sql_help.c:5309 msgid "remove a materialized view" msgstr "elimina una vista materializzata" -#: sql_help.c:4949 +#: sql_help.c:5314 msgid "remove an operator" msgstr "elimina un operatore" -#: sql_help.c:4954 +#: sql_help.c:5319 msgid "remove an operator class" msgstr "elimina una classe di operatori" -#: sql_help.c:4959 +#: sql_help.c:5324 msgid "remove an operator family" msgstr "elimina una famiglia operatore" -#: sql_help.c:4964 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" msgstr "elimina gli oggetti database di proprietà di un ruolo di database" -#: sql_help.c:4969 +#: sql_help.c:5334 msgid "remove a row level security policy from a table" msgstr "rimuovi una regola di sicurezza per riga da una tabella" -#: sql_help.c:4974 +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "rimuovi una procedura" + +#: sql_help.c:5344 msgid "remove a publication" msgstr "rimuovi una pubblicazione" -#: sql_help.c:4984 +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "rimuovi una routine" + +#: sql_help.c:5359 msgid "remove a rewrite rule" msgstr "elimina una regola di riscrittura" -#: sql_help.c:4989 +#: sql_help.c:5364 msgid "remove a schema" msgstr "elimina uno schema" -#: sql_help.c:4994 +#: sql_help.c:5369 msgid "remove a sequence" msgstr "elimina una sequenza" -#: sql_help.c:4999 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" msgstr "elimina una descrizione server esterno" -#: sql_help.c:5004 +#: sql_help.c:5379 msgid "remove extended statistics" msgstr "rimuovi una statistica estesa" -#: sql_help.c:5009 +#: sql_help.c:5384 msgid "remove a subscription" msgstr "rimuovi una sottoscrizione" -#: sql_help.c:5014 +#: sql_help.c:5389 msgid "remove a table" msgstr "elimina una tabella" -#: sql_help.c:5019 +#: sql_help.c:5394 msgid "remove a tablespace" msgstr "elimina un tablespace" -#: sql_help.c:5024 +#: sql_help.c:5399 msgid "remove a text search configuration" msgstr "elimina una configurazione di ricerca testo" -#: sql_help.c:5029 +#: sql_help.c:5404 msgid "remove a text search dictionary" msgstr "elimina un dizionario di ricerca testo" -#: sql_help.c:5034 +#: sql_help.c:5409 msgid "remove a text search parser" msgstr "elimina un analizzatore di ricerca testo" -#: sql_help.c:5039 +#: sql_help.c:5414 msgid "remove a text search template" msgstr "elimina un modello di ricerca testo" -#: sql_help.c:5044 +#: sql_help.c:5419 msgid "remove a transform" msgstr "elimina una trasformazione" -#: sql_help.c:5049 +#: sql_help.c:5424 msgid "remove a trigger" msgstr "elimina un trigger" -#: sql_help.c:5054 +#: sql_help.c:5429 msgid "remove a data type" msgstr "elimina un tipo di dato" -#: sql_help.c:5064 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" msgstr "elimina la mappatura degli utenti per un server esterno" -#: sql_help.c:5069 +#: sql_help.c:5444 msgid "remove a view" msgstr "elimina una vista" -#: sql_help.c:5079 +#: sql_help.c:5454 msgid "execute a prepared statement" msgstr "esegui una istruzione preparata" -#: sql_help.c:5084 +#: sql_help.c:5459 msgid "show the execution plan of a statement" msgstr "mostra il piano di esecuzione di una istruzione" -#: sql_help.c:5089 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" msgstr "estrai delle righe da una query utilizzando un cursore" -#: sql_help.c:5094 +#: sql_help.c:5469 msgid "define access privileges" msgstr "definisci i privilegi di accesso" -#: sql_help.c:5099 +#: sql_help.c:5474 msgid "import table definitions from a foreign server" msgstr "importa le definizioni di tabella da un server remoto" -#: sql_help.c:5104 +#: sql_help.c:5479 msgid "create new rows in a table" msgstr "crea nuove righe in una tabella" -#: sql_help.c:5109 +#: sql_help.c:5484 msgid "listen for a notification" msgstr "attendi l'arrivo di notifiche" -#: sql_help.c:5114 +#: sql_help.c:5489 msgid "load a shared library file" msgstr "carica un file di libreria condivisa" -#: sql_help.c:5119 +#: sql_help.c:5494 msgid "lock a table" msgstr "blocca una tabella" -#: sql_help.c:5124 +#: sql_help.c:5499 msgid "position a cursor" msgstr "posiziona un cursore" -#: sql_help.c:5129 +#: sql_help.c:5504 msgid "generate a notification" msgstr "genera una notifica" -#: sql_help.c:5134 +#: sql_help.c:5509 msgid "prepare a statement for execution" msgstr "prepara una istruzione per l'esecuzione" -#: sql_help.c:5139 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" msgstr "prepara la transazione corrente per un commit a due fasi" -#: sql_help.c:5144 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" msgstr "cambia il proprietario degli oggetti del database posseduti da un ruolo" -#: sql_help.c:5149 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" msgstr "sostituisci il contenuto di una vista materializzata" -#: sql_help.c:5154 +#: sql_help.c:5529 msgid "rebuild indexes" msgstr "ricostruisci indici" -#: sql_help.c:5159 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" msgstr "distruggi un punto di salvataggio precedentemente definito" -#: sql_help.c:5164 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" msgstr "ripristina un parametro di esecuzione al suo valore di predefinito" -#: sql_help.c:5169 +#: sql_help.c:5544 msgid "remove access privileges" msgstr "elimina i privilegi di accesso" -#: sql_help.c:5179 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "annulla una transazione che era stata preparata per un commit a due fasi" -#: sql_help.c:5184 +#: sql_help.c:5559 msgid "roll back to a savepoint" msgstr "annulla le modifiche fino a un punto di salvataggio" -#: sql_help.c:5189 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" msgstr "definisci un nuovo punto di salvataggio per la transazione corrente" -#: sql_help.c:5194 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" msgstr "definisci o modifica un'etichetta di sicurezza applicata a un oggetto" -#: sql_help.c:5199 sql_help.c:5244 sql_help.c:5274 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" msgstr "estrai righe da una tabella o una vista" -#: sql_help.c:5209 +#: sql_help.c:5584 msgid "change a run-time parameter" msgstr "modifica un parametro di esecuzione" -#: sql_help.c:5214 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" msgstr "imposta il momento del controllo dei vincoli per la transazione corrente" -#: sql_help.c:5219 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" msgstr "imposta l'identificativo utente della sessione corrente" -#: sql_help.c:5224 +#: sql_help.c:5599 msgid "set the session user identifier and the current user identifier of the current session" msgstr "imposta l'identificazione utente della sessione e l'identificazione utente corrente della sessione corrente" -#: sql_help.c:5229 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" msgstr "imposta le caratteristiche della transazione corrente" -#: sql_help.c:5234 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" msgstr "mostra il valore di un parametro di esecuzione" -#: sql_help.c:5249 +#: sql_help.c:5624 msgid "empty a table or set of tables" msgstr "svuota una tabella o una lista di tabelle" -#: sql_help.c:5254 +#: sql_help.c:5629 msgid "stop listening for a notification" msgstr "termina l'attesa di notifiche" -#: sql_help.c:5259 +#: sql_help.c:5634 msgid "update rows of a table" msgstr "modifica le righe di una tabella" -#: sql_help.c:5264 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" msgstr "pulisci ed eventualmente analizza il database" -#: sql_help.c:5269 +#: sql_help.c:5644 msgid "compute a set of rows" msgstr "genera una sequenza di righe" -#: startup.c:184 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s: -1 può essere usato solo in modalità non interattiva\n" -#: startup.c:287 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: apertura del file di log \"%s\" fallita: %s\n" -#: startup.c:394 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5627,27 +6079,27 @@ msgstr "" "Digita \"help\" per avere un aiuto.\n" "\n" -#: startup.c:543 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s: impostazione del parametro di stampa \"%s\" fallito\n" -#: startup.c:645 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: startup.c:662 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" msgstr "%s: attenzione: parametro in eccesso \"%s\" nella riga di comando ignorato\n" -#: startup.c:711 +#: startup.c:729 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: il proprio programma eseguibile non è stato trovato\n" -#: tab-complete.c:4182 +#: tab-complete.c:4497 #, c-format msgid "" "tab completion query failed: %s\n" @@ -5660,7 +6112,7 @@ msgstr "" #: variables.c:139 #, c-format -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" msgstr "valore \"%s\" non valido per \"%s\": è necessario un booleano\n" #: variables.c:176 diff --git a/src/bin/psql/po/ja.po b/src/bin/psql/po/ja.po index 309fbbdf7a3..b499f79b449 100644 --- a/src/bin/psql/po/ja.po +++ b/src/bin/psql/po/ja.po @@ -1,1695 +1,2197 @@ -# translation of psql. -# HOTTA Michihide , 2010. +# LANGUAGE message translation file for psql +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the psql (PostgreSQL) package. +# Michihide Hotta , 2010. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.4.2\n" +"Project-Id-Version: psql (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2015-05-23 22:59+0900\n" -"PO-Revision-Date: 2015-05-27 18:55+0900\n" -"Last-Translator: KOIZUMI Satoru \n" -"Language-Team: jpug-doc \n" +"POT-Creation-Date: 2018-10-12 14:12+0900\n" +"PO-Revision-Date: 2018-10-12 14:18+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" +"Language-Team: \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format msgid "could not identify current directory: %s" -msgstr "カレントディレクトリを識別ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚: %s" +msgstr "カレントディレクトリを識別ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" #: ../../common/exec.c:146 #, c-format msgid "invalid binary \"%s\"" -msgstr "\"%s\" ã¯æœ‰åйãªãƒã‚¤ãƒŠãƒªãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“。" +msgstr "無効ãªãƒã‚¤ãƒŠãƒª \"%s\"" #: ../../common/exec.c:195 #, c-format msgid "could not read binary \"%s\"" -msgstr "ãƒã‚¤ãƒŠãƒªãƒ•ァイル \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚" +msgstr "ãƒã‚¤ãƒŠãƒª \"%s\" を読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" #: ../../common/exec.c:202 #, c-format msgid "could not find a \"%s\" to execute" -msgstr "実行ã«å¿…è¦ãª \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" +msgstr "実行対象㮠\"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ" #: ../../common/exec.c:257 ../../common/exec.c:293 #, c-format msgid "could not change directory to \"%s\": %s" -msgstr "ディレクトリ\"%s\"ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgstr "ディレクトリ \"%s\" ã«ç§»å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" #: ../../common/exec.c:272 #, c-format msgid "could not read symbolic link \"%s\"" -msgstr "シンボリックリンク \"%s\" を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸã€‚" +msgstr "シンボリックリンク \"%s\" を読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" #: ../../common/exec.c:523 #, c-format msgid "pclose failed: %s" msgstr "pcloseãŒå¤±æ•—ã—ã¾ã—ãŸ: %s" -#: ../../common/fe_memutils.c:33 ../../common/fe_memutils.c:60 -#: ../../common/fe_memutils.c:83 command.c:321 input.c:205 mainloop.c:72 -#: mainloop.c:234 +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 #, c-format msgid "out of memory\n" msgstr "メモリä¸è¶³ã§ã™\n" -#: ../../common/fe_memutils.c:77 +#: ../../common/fe_memutils.c:92 #, c-format msgid "cannot duplicate null pointer (internal error)\n" -msgstr "null ãƒã‚¤ãƒ³ã‚¿ã‚’複製ã§ãã¾ã›ã‚“(内部エラー)。\n" +msgstr "null ãƒã‚¤ãƒ³ã‚¿ãƒ¼ã‚’複製ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“(内部エラー) \n" -#: ../../common/username.c:45 +#: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "実効ユーザID %ld ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s" -#: ../../common/username.c:47 command.c:276 +#: ../../common/username.c:45 command.c:554 msgid "user does not exist" msgstr "ユーザãŒå­˜åœ¨ã—ã¾ã›ã‚“" -#: ../../common/username.c:62 +#: ../../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" -msgstr "ユーザåã®æ¤œç´¢ã«å¤±æ•—: エラーコード %lu" +msgstr "ユーザåã®æ¤œç´¢ã«å¤±æ•—: エラー コード %lu" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" -msgstr "コマンドã¯å®Ÿè¡Œå½¢å¼ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "コマンドãŒå®Ÿè¡Œå½¢å¼ã§ã¯ã‚りã¾ã›ã‚“" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "コマンドãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" -msgstr "å­ãƒ—ロセスãŒçµ‚了コード %d ã§çµ‚了ã—ã¾ã—ãŸã€‚" +msgstr "å­ãƒ—ロセスãŒçµ‚了コード %d ã§çµ‚了ã—ã¾ã—ãŸ" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" -msgstr "å­ãƒ—ロセスãŒä¾‹å¤– 0x%X ã§çµ‚了ã•ã›ã‚‰ã‚Œã¾ã—ãŸã€‚" +msgstr "å­ãƒ—ロセスãŒä¾‹å¤– 0x%X ã§å¼·åˆ¶çµ‚了ã—ã¾ã—ãŸ" -#: ../../common/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" -msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %s ã§çµ‚了ã•ã›ã‚‰ã‚Œã¾ã—ãŸã€‚" +msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %s ã§å¼·åˆ¶çµ‚了ã—ã¾ã—ãŸ" -#: ../../common/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" -msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %d ã§çµ‚了ã•ã›ã‚‰ã‚Œã¾ã—ãŸã€‚" +msgstr "å­ãƒ—ロセスãŒã‚·ã‚°ãƒŠãƒ« %d ã§å¼·åˆ¶çµ‚了ã—ã¾ã—ãŸ" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" -msgstr "å­ãƒ—ロセスãŒä¸æ˜ŽãªçŠ¶æ…‹%dã«ã‚ˆã‚Šçµ‚了ã—ã¾ã—ãŸã€‚" +msgstr "å­ãƒ—ロセスã¯èªè­˜ã§ããªã„ステータス %d ã§çµ‚了ã—ã¾ã—ãŸ" -#: command.c:117 +#: ../../fe_utils/print.c:353 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu 行)" + +#: ../../fe_utils/print.c:2915 +#, c-format +msgid "Interrupted\n" +msgstr "割り込ã¿\n" + +#: ../../fe_utils/print.c:2979 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "" +"テーブルã®å†…容ã«ãƒ˜ãƒƒãƒ€ãƒ¼ã‚’追加ã§ãã¾ã›ã‚“: 列数 %d ãŒåˆ¶é™å€¤ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚\n" + +#: ../../fe_utils/print.c:3019 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "" +"テーブルã®å†…容ã«ã‚»ãƒ«ã‚’追加ã§ãã¾ã›ã‚“: セルã®åˆè¨ˆæ•° %d ãŒåˆ¶é™å€¤ã‚’è¶…ãˆã¦ã„ã¾" +"ã™ã€‚\n" + +#: ../../fe_utils/print.c:3268 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "出力フォーマットãŒç„¡åŠ¹ï¼ˆå†…éƒ¨ã‚¨ãƒ©ãƒ¼ï¼‰ï¼š%d" + +#: ../../fe_utils/psqlscan.l:724 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"\n" +msgstr "変数 \"%s\" ã®å†å¸°å±•開をスキップã—ã¦ã„ã¾ã™\n" + +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" -msgstr "\\%sコマンドã¯ç„¡åйã§ã™ã€‚\\? ã§ãƒ˜ãƒ«ãƒ—ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" +msgstr "\\%s ã¯ç„¡åйãªã‚³ãƒžãƒ³ãƒ‰ã§ã™ã€‚\\? ã§ãƒ˜ãƒ«ãƒ—ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" -#: command.c:119 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" -msgstr "\\%sã¯ç„¡åйãªã‚³ãƒžãƒ³ãƒ‰ã§ã™\n" +msgstr "\\%s ã¯ç„¡åйãªã‚³ãƒžãƒ³ãƒ‰ã§ã™\n" -#: command.c:130 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" -msgstr "\\%s: 余分ãªå¼•æ•° \"%s\" ã¯ç„¡è¦–ã•れã¾ã—ãŸã€‚\n" +msgstr "\\%s: 余分ãªå¼•æ•° \"%s\" ã¯ç„¡è¦–ã•れã¾ã—ãŸ\n" + +#: command.c:292 +#, c-format +msgid "" +"\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "" +"\\%s コマンドã¯ç„¡è¦–ã•れã¾ã™ã€‚ç¾åœ¨ã® \\if ブロックを抜ã‘ã‚‹ã«ã¯ \\endif ã¾ãŸã¯ " +"Ctrl-C を使用ã—ã¾ã™ã€‚\n" -#: command.c:274 +#: command.c:552 #, c-format msgid "could not get home directory for user ID %ld: %s\n" -msgstr "ユーザID %ld ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’特定ã§ãã¾ã›ã‚“: %s\n" +msgstr "ユーザ ID %ld ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—㟠: %s\n" -#: command.c:292 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" -msgstr "\\%s: ディレクトリを \"%s\" ã«å¤‰æ›´ã§ãã¾ã›ã‚“:%s\n" +msgstr "\\%s: ディレクトリを \"%s\" ã«å¤‰æ›´ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: command.c:307 common.c:446 common.c:886 +#: command.c:595 common.c:696 common.c:754 common.c:1292 #, c-format msgid "You are currently not connected to a database.\n" -msgstr "ç¾åœ¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã¯æŽ¥ç¶šã—ã¦ã„ã¾ã›ã‚“。\n" +msgstr "ç¾åœ¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¦ã„ã¾ã›ã‚“。\n" -#: command.c:334 +#: command.c:602 #, c-format -msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" -msgstr "データベース\"%s\"ã«ãƒ¦ãƒ¼ã‚¶\"%s\"ã§ã‚½ã‚±ãƒƒãƒˆ\"%s\"経由ã®ãƒãƒ¼ãƒˆ\"%s\"ã§æŽ¥ç¶šã—ã¦ã„ã¾ã™ã€‚\n" +msgid "" +"You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " +"port \"%s\".\n" +msgstr "" +"データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶ \"%s\" ã¨ã—ã¦ã€ã‚½ã‚±ãƒƒãƒˆ \"%s\" ã®ãƒãƒ¼ãƒˆ \"%s\" " +"を介ã—ã¦æŽ¥ç¶šã—ã¦ã„ã¾ã™ã€‚\n" -#: command.c:337 +#: command.c:605 #, c-format -msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" -msgstr "ホスト\"%3$s\"上ã®ãƒãƒ¼ãƒˆ\"%4$s\"ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%1$s\"ã«ãƒ¦ãƒ¼ã‚¶\"%2$s\"ã§æŽ¥ç¶šã—ã¦ã„ã¾ã™\n" +msgid "" +"You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " +"\"%s\".\n" +msgstr "" +"データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶ \"%s\" ã¨ã—ã¦ã€ãƒ›ã‚¹ãƒˆ \"%s\" 上ã®ãƒãƒ¼ãƒˆ \"%s\" " +"を介ã—ã¦æŽ¥ç¶šã—ã¦ã„ã¾ã™ã€‚\n" -#: command.c:538 command.c:608 command.c:1403 +#: command.c:895 command.c:991 command.c:2376 #, c-format msgid "no query buffer\n" -msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ãŒã‚りã¾ã›ã‚“。\n" +msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ãŒã‚りã¾ã›ã‚“\n" -#: command.c:571 command.c:3035 +#: command.c:928 command.c:4648 #, c-format msgid "invalid line number: %s\n" msgstr "無効ãªè¡Œç•ªå·ã§ã™: %s\n" -#: command.c:602 +#: command.c:982 +#, c-format +msgid "The server (version %s) does not support editing function source.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯é–¢æ•°ã‚½ãƒ¼ã‚¹ã‚³ãƒ¼ãƒ‰ã®ç·¨é›†ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" + +#: command.c:985 #, c-format -msgid "The server (version %d.%d) does not support editing function source.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã¯é–¢æ•°ã®ã‚½ãƒ¼ã‚¹ç·¨é›†ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“\n" +msgid "The server (version %s) does not support editing view definitions.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ“ュー定義ã®ç·¨é›†ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: command.c:682 +#: command.c:1067 msgid "No changes" -msgstr "変更ãªã—" +msgstr "変更ã•れã¦ã„ã¾ã›ã‚“" -#: command.c:736 +#: command.c:1144 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" -msgstr "%s: 符å·åŒ–æ–¹å¼åãŒç„¡åйã€ã¾ãŸã¯å¤‰æ›ç”¨ãƒ—ロシージャãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "" +"%s: エンコーディングåãŒç„¡åйã‹ã€ã¾ãŸã¯å¤‰æ›ãƒ—ロシージャãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" -#: command.c:833 command.c:883 command.c:897 command.c:914 command.c:1021 -#: command.c:1180 command.c:1383 command.c:1414 +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1183 +msgid "out of memory" +msgstr "メモリä¸è¶³ã§ã™" + +#: command.c:1186 +msgid "There is no previous error." +msgstr "ç›´å‰ã®ã‚¨ãƒ©ãƒ¼ã¯ã‚りã¾ã›ã‚“。" + +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s: å¿…è¦ãªå¼•æ•°ãŒã‚りã¾ã›ã‚“\n" -#: command.c:946 +#: command.c:1505 +#, c-format +msgid "\\elif: cannot occur after \\else\n" +msgstr "\\elif: \\else ã®å¾Œã«ã¯ç½®ã‘ã¾ã›ã‚“\n" + +#: command.c:1510 +#, c-format +msgid "\\elif: no matching \\if\n" +msgstr "\\elif: ã“れã«å¯¾å¿œã™ã‚‹ \\if ãŒã‚りã¾ã›ã‚“\n" + +#: command.c:1574 +#, c-format +msgid "\\else: cannot occur after \\else\n" +msgstr "\\else: \\else ã®å¾Œã«ã¯ç½®ã‘ã¾ã›ã‚“\n" + +#: command.c:1579 +#, c-format +msgid "\\else: no matching \\if\n" +msgstr "\\else: ã“れã«å¯¾å¿œã™ã‚‹ \\if ãŒã‚りã¾ã›ã‚“\n" + +#: command.c:1619 +#, c-format +msgid "\\endif: no matching \\if\n" +msgstr "\\endif: ã“れã«å¯¾å¿œã™ã‚‹ \\if ãŒã‚りã¾ã›ã‚“\n" + +#: command.c:1774 msgid "Query buffer is empty." msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ã¯ç©ºã§ã™ã€‚" -#: command.c:956 +#: command.c:1796 msgid "Enter new password: " -msgstr "æ–°ã—ã„パスワード: " +msgstr "æ–°ã—ã„パスワードを入力ã—ã¦ãã ã•ã„: " -#: command.c:957 +#: command.c:1797 msgid "Enter it again: " -msgstr "ã‚‚ã†ä¸€åº¦å…¥åŠ›ã—ã¦ãã ã•ã„:" +msgstr "ã‚‚ã†ä¸€åº¦å…¥åŠ›ã—ã¦ãã ã•ã„: " -#: command.c:961 +#: command.c:1801 #, c-format msgid "Passwords didn't match.\n" -msgstr "パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“。\n" +msgstr "パスワードãŒä¸€è‡´ã—ã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: command.c:979 +#: command.c:1900 #, c-format -msgid "Password encryption failed.\n" -msgstr "ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æš—å·åŒ–ã«å¤±æ•—ã—ã¾ã—ãŸã€‚\n" +msgid "\\%s: could not read value for variable\n" +msgstr "\\%s: 変数ã®å€¤ã‚’読ã¿å–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: command.c:1050 command.c:1161 command.c:1388 -#, c-format -msgid "\\%s: error while setting variable\n" -msgstr "\\%s: 変数を設定ã—ã¦ã„る時ã«ã‚¨ãƒ©ãƒ¼\n" - -#: command.c:1108 +#: command.c:2003 msgid "Query buffer reset (cleared)." msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ãŒãƒªã‚»ãƒƒãƒˆï¼ˆã‚¯ãƒªã‚¢ï¼‰ã•れã¾ã—ãŸã€‚" -#: command.c:1120 +#: command.c:2025 #, c-format msgid "Wrote history to file \"%s\".\n" -msgstr "ファイル\"%s\"ã«å±¥æ­´ã‚’出力ã—ã¾ã—ãŸã€‚\n" +msgstr "ファイル \"%s\" ã«ãƒ’ストリーを出力ã—ã¾ã—ãŸã€‚\n" -#: command.c:1185 +#: command.c:2112 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" -msgstr "\\%s: 環境変数ã®åå‰ã«ã¯\"=\"ã‚’å«ã‚られã¾ã›ã‚“\n" +msgstr "\\%s: 環境変数åã« \"=\" ã‚’å«ã‚ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“\n" + +#: command.c:2173 +#, c-format +msgid "The server (version %s) does not support showing function source.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯é–¢æ•°ã‚½ãƒ¼ã‚¹ã®è¡¨ç¤ºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: command.c:1227 +#: command.c:2176 #, c-format -msgid "The server (version %d.%d) does not support showing function source.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒ(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã¯é–¢æ•°ã‚½ãƒ¼ã‚¹ã®è¡¨ç¤ºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support showing view definitions.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ“ュー定義ã®è¡¨ç¤ºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: command.c:1233 +#: command.c:2183 #, c-format msgid "function name is required\n" -msgstr "関数åãŒå¿…è¦ã§ã™\n" +msgstr "関数åãŒå¿…è¦ã§ã™ã€‚\n" + +#: command.c:2185 +#, c-format +msgid "view name is required\n" +msgstr "ビューåãŒå¿…è¦ã§ã™\n" -#: command.c:1368 +#: command.c:2315 msgid "Timing is on." msgstr "タイミング㯠on ã§ã™ã€‚" -#: command.c:1370 +#: command.c:2317 msgid "Timing is off." msgstr "タイミング㯠off ã§ã™ã€‚" -#: command.c:1431 command.c:1451 command.c:2072 command.c:2075 command.c:2078 -#: command.c:2084 command.c:2086 command.c:2094 command.c:2104 command.c:2113 -#: command.c:2127 command.c:2144 command.c:2203 common.c:74 copy.c:333 -#: copy.c:393 copy.c:408 psqlscan.l:1677 psqlscan.l:1688 psqlscan.l:1698 +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:1530 -#, c-format -msgid "+ opt(%d) = |%s|\n" -msgstr "+ opt(%d) = |%s|\n" - -#: command.c:1556 startup.c:184 +#: command.c:2814 startup.c:214 startup.c:265 msgid "Password: " -msgstr "パスワード: " +msgstr "パスワード: " -#: command.c:1561 startup.c:186 +#: command.c:2819 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "ユーザ %s ã®ãƒ‘スワード: " -#: command.c:1608 -#, c-format -msgid "All connection parameters must be supplied because no database connection exists\n" -msgstr "データベース接続ãŒã‚りã¾ã›ã‚“ã®ã§ã™ã¹ã¦ã®æŽ¥ç¶šãƒ‘ラメータを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" - -#: command.c:1725 command.c:3069 common.c:120 common.c:413 common.c:478 -#: common.c:929 common.c:954 common.c:1051 copy.c:492 copy.c:695 -#: large_obj.c:158 large_obj.c:193 large_obj.c:255 psqlscan.l:1949 +#: command.c:2869 #, c-format -msgid "%s" -msgstr "%s" +msgid "" +"All connection parameters must be supplied because no database connection " +"exists\n" +msgstr "" +"データベース接続ãŒãªã„ãŸã‚ã€ã™ã¹ã¦ã®æŽ¥ç¶šãƒ‘ラメータを指定ã—ãªã‘れã°ãªã‚Šã¾ã›" +"ã‚“\n" -#: command.c:1729 +#: command.c:3037 #, c-format msgid "Previous connection kept\n" msgstr "以å‰ã®æŽ¥ç¶šã¯ä¿æŒã•れã¦ã„ã¾ã™ã€‚\n" -#: command.c:1733 +#: command.c:3041 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:1766 +#: command.c:3077 #, c-format -msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" -msgstr "ãƒãƒ¼ãƒˆ\"%4$s\"ã®ã‚½ã‚±ãƒƒãƒˆ\"%3$s\"経由ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%1$s\"ã«ãƒ¦ãƒ¼ã‚¶\"%2$s\"ã¨ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" +msgid "" +"You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " +"at port \"%s\".\n" +msgstr "" +"データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶ \"%s\" ã¨ã—ã¦ã€ã‚½ã‚±ãƒƒãƒˆ \"%s\" ã®ãƒãƒ¼ãƒˆ \"%s\" " +"を介ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" -#: command.c:1769 +#: command.c:3080 #, c-format -msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" -msgstr "ホスト\"%3$s\"上ã®ãƒãƒ¼ãƒˆ\"%4$s\"ã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹\"%1$s\"ã«ãƒ¦ãƒ¼ã‚¶\"%2$s\"ã¨ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" +msgid "" +"You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " +"port \"%s\".\n" +msgstr "" +"データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶ \"%s\" ã¨ã—ã¦ã€ãƒ›ã‚¹ãƒˆ \"%s\" ã®ãƒãƒ¼ãƒˆ \"%s\" ã‚’" +"介ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" -#: command.c:1773 +#: command.c:3084 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" -msgstr "データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶\"%s\"ã¨ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" +msgstr "データベース \"%s\" ã«ãƒ¦ãƒ¼ã‚¶ \"%s\" ã¨ã—ã¦æŽ¥ç¶šã—ã¾ã—ãŸã€‚\n" -#: command.c:1807 +#: command.c:3117 #, c-format msgid "%s (%s, server %s)\n" -msgstr "%s (%s, サーãƒãƒ¼ %s)\n" +msgstr "%s (%sã€ã‚µãƒ¼ãƒ %s)\n" -#: command.c:1815 +#: command.c:3125 #, c-format msgid "" -"WARNING: %s major version %d.%d, server major version %d.%d.\n" +"WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n" msgstr "" -"注æ„: %s メジャーãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d.%d, サーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d.%d.\n" +"警告: %s ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ %s ã§ã™ãŒã€ã‚µãƒ¼ãƒã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ %s " +"ã§ã™ã€‚\n" " psql ã®æ©Ÿèƒ½ã®ä¸­ã§ã€å‹•作ã—ãªã„ã‚‚ã®ãŒã‚ã‚‹ã‹ã‚‚ã—れã¾ã›ã‚“。\n" -#: command.c:1845 +#: command.c:3162 #, c-format -msgid "SSL connection (protocol: %s, cipher: %s, bits: %d, compression: %s)\n" -msgstr "SSL接続(プロトコル: %s, æš—å·åŒ–æ–¹å¼: %s, ビット長: %d, 圧縮: %s)\n" +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL 接続 (プロトコル: %sã€æš—å·åŒ–æ–¹å¼: %sã€ãƒ“ット長: %sã€åœ§ç¸®: %s)\n" -#: command.c:1847 help.c:46 +#: command.c:3163 command.c:3164 command.c:3165 +msgid "unknown" +msgstr "䏿˜Ž" + +#: command.c:3166 help.c:45 msgid "off" msgstr "オフ" -#: command.c:1847 help.c:46 +#: command.c:3166 help.c:45 msgid "on" msgstr "オン" -#: command.c:1856 -#, c-format -msgid "SSL connection (unknown cipher)\n" -msgstr "SSL 接続 (æœªå®šç¾©ã®æš—å·åŒ–æ–¹å¼)\n" - -#: command.c:1877 +#: command.c:3186 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" " 8-bit characters might not work correctly. See psql reference\n" " page \"Notes for Windows users\" for details.\n" msgstr "" -"警告:コンソールã®ã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ (%u) ㌠Windows ã®ã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ (%u) ã¨\n" -" ç•°ãªã‚‹ãŸã‚ã€8 ãƒ“ãƒƒãƒˆæ–‡å­—åˆ—ãŒæ­£ã—ã動作ã—ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚\n" -" 詳細㯠psql リファレンスマニュアル㮠\"Notes for Windows users\"\n" -" (ウィンドウズユーザã®ãŸã‚ã«ï¼‰ã‚’å‚ç…§ã—ã¦ãã ã•ã„。\n" -"\n" +"警告:コンソールã®ã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ (%u) ㌠Windows ã®ã‚³ãƒ¼ãƒ‰ãƒšãƒ¼ã‚¸ (%u) ã¨ç•°ãªã‚‹ãŸ" +"ã‚ã€\n" +" 8 ãƒ“ãƒƒãƒˆæ–‡å­—åˆ—ãŒæ­£ã—ã動作ã—ãªã„å¯èƒ½æ€§ãŒã‚りã¾ã™ã€‚詳細㯠psql リファレ" +"ンスマニュアルã®\n" +" \"Notes for Windows users\"(Windowsユーザå‘ã‘ã®æ³¨æ„)をå‚ç…§ã—ã¦ãã ã•" +"ã„。\n" -#: command.c:1961 +#: command.c:3290 #, c-format -msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" -msgstr "行番å·ã‚’指定ã™ã‚‹ãŸã‚ã«ã¯PSQL_EDITOR_LINENUMBER_ARG変数を設定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgid "" +"environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " +"line number\n" +msgstr "" +"環境変数 PSQL_EDITOR_LINENUMBER_ARG ã§è¡Œç•ªå·ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" -#: command.c:1990 +#: command.c:3319 #, c-format msgid "could not start editor \"%s\"\n" msgstr "エディタ \"%s\" ã‚’èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: command.c:1992 +#: command.c:3321 #, c-format msgid "could not start /bin/sh\n" msgstr "/bin/sh ã‚’èµ·å‹•ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: command.c:2030 +#: command.c:3359 #, c-format msgid "could not locate temporary directory: %s\n" -msgstr "一時ディレクトリã«ç§»å‹•ã§ãã¾ã›ã‚“: %s\n" +msgstr "一時ディレクトリãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: command.c:2057 +#: command.c:3386 #, c-format msgid "could not open temporary file \"%s\": %s\n" -msgstr "一時ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“: %s\n" +msgstr "一時ファイル \"%s\" ã‚’é–‹ã‘ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: command.c:2325 +#: command.c:3660 #, c-format -msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, latex, troff-ms\n" -msgstr "\\pset: 有効ãªãƒ•ォーマット㯠unaligned, aligned, wrapped, html, latex, troff-ms ã§ã™ã€‚\n" +msgid "" +"\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, " +"latex, latex-longtable, troff-ms\n" +msgstr "" +"\\pset: 有効ãªãƒ•ォーマット㯠unaligned, aligned, wrapped, html, asciidoc, " +"latex, latex-longtable, troff-ms ã§ã™ã€‚\n" -#: command.c:2344 +#: command.c:3678 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" -msgstr "\\pset: 有効ãªè¡Œã‚¹ã‚¿ã‚¤ãƒ«ã¯ ascii, old-ascii, unicode ã§ã™ã€‚\n" +msgstr "\\pset: 有効ãªç·šã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ ascii, old-ascii, unicode ã§ã™ã€‚\n" + +#: command.c:3693 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double\n" +msgstr "\\pset: 有効㪠Unicode 罫線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ single, double ã§ã™ã€‚\n" + +#: command.c:3708 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double\n" +msgstr "\\pset: 有効㪠Unicode 列罫線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ single, double ã§ã™ã€‚\n" -#: command.c:2490 command.c:2641 +#: command.c:3723 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double\n" +msgstr "" +"\\pset: 有効㪠Unicode ヘッダー罫線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ single, double ã§ã™ã€‚\n" + +#: command.c:3888 command.c:4067 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "\\pset: 未定義ã®ã‚ªãƒ—ション:%s\n" -#: command.c:2508 +#: command.c:3906 #, c-format msgid "Border style is %d.\n" -msgstr "境界線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ %d ã§ã™ã€‚\n" +msgstr "罫線スタイル㯠%d ã§ã™ã€‚\n" -#: command.c:2514 +#: command.c:3912 #, c-format msgid "Target width is unset.\n" -msgstr "対象幅ã¯ã‚»ãƒƒãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +msgstr "ターゲットã®å¹…ãŒè¨­å®šã•れã¦ã„ã¾ã›ã‚“。\n" -#: command.c:2516 +#: command.c:3914 #, c-format msgid "Target width is %d.\n" -msgstr "対象幅ã¯%dã§ã™ã€‚\n" +msgstr "ターゲットã®å¹…㯠%d ã§ã™ã€‚\n" -#: command.c:2523 +#: command.c:3921 #, c-format msgid "Expanded display is on.\n" msgstr "拡張表示㯠on ã§ã™ã€‚\n" -#: command.c:2525 +#: command.c:3923 #, c-format msgid "Expanded display is used automatically.\n" -msgstr "拡張表示ãŒè‡ªå‹•çš„ã«ä½¿ç”¨ã•れã¾ã™\n" +msgstr "拡張表示ãŒè‡ªå‹•çš„ã«ä½¿ã‚れã¾ã™ã€‚\n" -#: command.c:2527 +#: command.c:3925 #, c-format msgid "Expanded display is off.\n" msgstr "拡張表示㯠off ã§ã™ã€‚\n" -#: command.c:2534 command.c:2542 +#: command.c:3932 command.c:3940 #, c-format msgid "Field separator is zero byte.\n" msgstr "フィールド区切り文字ã¯ã‚¼ãƒ­ãƒã‚¤ãƒˆã§ã™ã€‚\n" -#: command.c:2536 +#: command.c:3934 #, c-format msgid "Field separator is \"%s\".\n" msgstr "フィールド区切り文字㯠\"%s\" ã§ã™ã€‚\n" -#: command.c:2549 +#: command.c:3947 #, c-format msgid "Default footer is on.\n" -msgstr "デフォルトã®ãƒ•ッタ㯠on ã§ã™ã€‚\n" +msgstr "デフォルトフッター(行数ã®è¡¨ç¤ºï¼‰ã¯ on ã§ã™ã€‚\n" -#: command.c:2551 +#: command.c:3949 #, c-format msgid "Default footer is off.\n" -msgstr "デフォルトã®ãƒ•ッタ㯠off ã§ã™ã€‚\n" +msgstr "デフォルトフッター(行数ã®è¡¨ç¤ºï¼‰ã¯ off ã§ã™ã€‚\n" -#: command.c:2557 +#: command.c:3955 #, c-format msgid "Output format is %s.\n" -msgstr "出力フォーマット㯠%s ã§ã™ã€‚\n" +msgstr "出力形å¼ã¯ %s ã§ã™ã€‚\n" -#: command.c:2563 +#: command.c:3961 #, c-format msgid "Line style is %s.\n" -msgstr "境界線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ %s ã§ã™ã€‚\n" +msgstr "ç·šã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ %s ã§ã™ã€‚\n" -#: command.c:2570 +#: command.c:3968 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null 表示㯠\"%s\" ã§ã™ã€‚\n" -#: command.c:2578 +#: command.c:3976 #, c-format msgid "Locale-adjusted numeric output is on.\n" -msgstr "「数値出力ã®ãƒ­ã‚±ãƒ¼ãƒ«èª¿æ•´ã€ã¯ on ã§ã™ã€‚\n" +msgstr "『数値出力時ã®ãƒ­ã‚±ãƒ¼ãƒ«èª¿æ•´ã€ã¯ on ã§ã™ã€‚\n" -#: command.c:2580 +#: command.c:3978 #, c-format msgid "Locale-adjusted numeric output is off.\n" -msgstr "「数値出力ã®ãƒ­ã‚±ãƒ¼ãƒ«èª¿æ•´ã€ã¯ off ã§ã™ã€‚\n" +msgstr "『数値出力時ã®ãƒ­ã‚±ãƒ¼ãƒ«èª¿æ•´ã€ã¯ off ã§ã™ã€‚\n" -#: command.c:2587 +#: command.c:3985 #, c-format msgid "Pager is used for long output.\n" -msgstr "出力ãŒé•·ã„å ´åˆã¯ãƒšãƒ¼ã‚¸ãƒ£ãŒä½¿ã‚れã¾ã™ã€‚\n" +msgstr "表示ãŒç¸¦ã«é•·ããªã‚‹å ´åˆã¯ãƒšãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’使ã„ã¾ã™ã€‚\n" -#: command.c:2589 +#: command.c:3987 #, c-format msgid "Pager is always used.\n" -msgstr "常ã«ãƒšãƒ¼ã‚¸ãƒ£ãŒä½¿ã‚れã¾ã™ã€‚\n" +msgstr "常ã«ãƒšãƒ¼ã‚¸ãƒ£ãƒ¼ã‚’使ã„ã¾ã™ã€‚\n" -#: command.c:2591 +#: command.c:3989 #, c-format msgid "Pager usage is off.\n" -msgstr "「ページャを使ã†ã€ã¯ off ã§ã™ã€‚\n" +msgstr "「ページャーを使ã†ã€ã¯ off ã§ã™ã€‚\n" + +#: command.c:3995 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "%d 行未満ã®å ´åˆã€ãƒšãƒ¼ã‚¸ãƒ£ãƒ¼ã¯ä½¿ã‚れã¾ã›ã‚“。\n" -#: command.c:2598 command.c:2608 +#: command.c:4005 command.c:4015 #, c-format msgid "Record separator is zero byte.\n" -msgstr "レコード区切り文字ã¯ã‚¼ãƒ­ãƒã‚¤ãƒˆã§ã™ã€‚\n" +msgstr "レコードã®åŒºåˆ‡ã‚Šæ–‡å­—ã¯ã‚¼ãƒ­ãƒã‚¤ãƒˆã§ã™\n" -#: command.c:2600 +#: command.c:4007 #, c-format msgid "Record separator is .\n" msgstr "レコード区切り文字㯠ã§ã™ã€‚\n" -#: command.c:2602 +#: command.c:4009 #, c-format msgid "Record separator is \"%s\".\n" -msgstr "レコード区切り文字㯠\"%s\" ã§ã™ã€‚\n" +msgstr "レコード区切り記å·ã¯ \"%s\"ã§ã™ã€‚\n" -#: command.c:2615 +#: command.c:4022 #, c-format msgid "Table attributes are \"%s\".\n" -msgstr "テーブル属性㯠\"%s\" ã§ã™ã€‚\n" +msgstr "テーブル属性㯠\"%s\"ã§ã™ã€‚\n" -#: command.c:2618 +#: command.c:4025 #, c-format msgid "Table attributes unset.\n" -msgstr "テーブル属性ã¯ã‚»ãƒƒãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +msgstr "テーブル属性ã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“。\n" -#: command.c:2625 +#: command.c:4032 #, c-format msgid "Title is \"%s\".\n" msgstr "タイトル㯠\"%s\" ã§ã™ã€‚\n" -#: command.c:2627 +#: command.c:4034 #, c-format msgid "Title is unset.\n" -msgstr "タイトルã¯ã‚»ãƒƒãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +msgstr "タイトルã¯è¨­å®šã•れã¦ã„ã¾ã›ã‚“。\n" -#: command.c:2634 +#: command.c:4041 #, c-format msgid "Tuples only is on.\n" msgstr "「タプルã®ã¿è¡¨ç¤ºã€ã¯ on ã§ã™ã€‚\n" -#: command.c:2636 +#: command.c:4043 #, c-format msgid "Tuples only is off.\n" msgstr "「タプルã®ã¿è¡¨ç¤ºã€ã¯ off ã§ã™ã€‚\n" -#: command.c:2787 +#: command.c:4049 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Unicode ã®ç½«ç·šã‚¹ã‚¿ã‚¤ãƒ«ã¯ \"%s\" ã§ã™ã€‚\n" + +#: command.c:4055 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Unicode 行罫線ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ \"%s\" ã§ã™ã€‚\n" + +#: command.c:4061 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Unicode ヘッダー行ã®ã‚¹ã‚¿ã‚¤ãƒ«ã¯ \"%s\" ã§ã™ã€‚\n" + +#: command.c:4221 #, c-format msgid "\\!: failed\n" msgstr "\\!: 失敗\n" -#: command.c:2807 command.c:2865 +#: command.c:4246 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" -msgstr "\\watchを空ã®å•ã„åˆã‚ã›ã§ä½¿ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n" +msgstr "\\watch ã¯ç©ºã®å•ã„åˆã‚ã›ã§ã¯ä½¿ãˆã¾ã›ã‚“\n" -#: command.c:2828 +#: command.c:4287 #, c-format -msgid "Watch every %lds\t%s" -msgstr "%ld秒毎ã«ç›£è¦–ã—ã¾ã™\t%s" +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (%g 秒毎)\n" -#: command.c:2872 +#: command.c:4290 #, c-format -msgid "\\watch cannot be used with COPY\n" -msgstr "\\watchã§ã¯COPYを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“\n" +msgid "%s (every %gs)\n" +msgstr "%s (%g 秒毎)\n" -#: command.c:2878 +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1321 #, c-format -msgid "unexpected result status for \\watch\n" -msgstr "\\watchã«å¯¾ã™ã‚‹æƒ³å®šå¤–ã®çµæžœçŠ¶æ…‹\n" +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"******** å•ã„åˆã‚ã› ******\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4543 +#, c-format +msgid "\"%s.%s\" is not a view\n" +msgstr "\"%s.%s\" ã¯ãƒ“ューã§ã¯ã‚りã¾ã›ã‚“\n" -#: common.c:287 +#: command.c:4559 +#, c-format +msgid "could not parse reloptions array\n" +msgstr "reloptions é…列を解æžã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection\n" +msgstr "æœ‰åŠ¹ãªæŽ¥ç¶šãŒãªã„ã®ã§ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã§ãã¾ã›ã‚“。\n" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgstr "" +"シェルコマンドã®å¼•æ•°ã«æ”¹è¡Œ(LF)ã¾ãŸã¯ã‚­ãƒ£ãƒªãƒƒã‚¸ãƒªã‚¿ãƒ¼ãƒ³(CR)ãŒå«ã¾ã‚Œã¦ã„ã¾ã™: " +"\"%s\"\n" + +#: common.c:416 #, c-format msgid "connection to server was lost\n" -msgstr "サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒåˆ‡ã‚Œã¾ã—ãŸã€‚\n" +msgstr "サーãƒã¸ã®æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸã€‚\n" -#: common.c:291 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " -msgstr "サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒåˆ‡ã‚Œã¾ã—ãŸã€‚リセットã—ã¦ã„ã¾ã™: " +msgstr "サーãƒã¸ã®æŽ¥ç¶šãŒå¤±ã‚れã¾ã—ãŸã€‚リセットã—ã¦ã„ã¾ã™: " -#: common.c:296 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "失敗。\n" -#: common.c:303 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "æˆåŠŸã€‚\n" -#: common.c:403 common.c:683 common.c:851 +#: common.c:532 common.c:1082 common.c:1256 #, c-format msgid "unexpected PQresultStatus: %d\n" -msgstr "想定外ã®PQresultStatus: %d\n" +msgstr "予期ã—ãªã„ PQresultStatus: %d\n" -#: common.c:452 common.c:459 common.c:912 +#: common.c:641 #, c-format -msgid "" -"********* QUERY **********\n" -"%s\n" -"**************************\n" -"\n" -msgstr "" -"********* å•ã„åˆã‚ã› ********\n" -"%s\n" -"*****************************\n" -"\n" +msgid "Time: %.3f ms\n" +msgstr "時間: %.3f ミリ秒\n" -#: common.c:513 +#: common.c:656 #, c-format -msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" -msgstr "PID %3$d ã‚’æŒã¤ã‚µãƒ¼ãƒãƒ¼ãƒ—ロセスã‹ã‚‰ã€ãƒšã‚¤ãƒ­ãƒ¼ãƒ‰ \"%2$s\" ã‚’æŒã¤éžåŒæœŸé€šçŸ¥ \"%1$s\" ã‚’å—ä¿¡ã—ã¾ã—ãŸã€‚\n" +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒(%02d:%06.3f)\n" -#: common.c:516 +#: common.c:665 #, c-format -msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" -msgstr "PID %2$d ã‚’æŒã¤ã‚µãƒ¼ãƒãƒ¼ãƒ—ロセスã‹ã‚‰éžåŒæœŸé€šçŸ¥ \"%1$s\" ã‚’å—ä¿¡ã—ã¾ã—ãŸã€‚\n" +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒 (%02d:%02d:%06.3f)\n" -#: common.c:578 +#: common.c:672 #, c-format -msgid "no rows returned for \\gset\n" -msgstr "\\gsetã«å¯¾ã—ã¦è¡ŒãŒè¿”ã•れã¾ã›ã‚“ã§ã—ãŸ\n" +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "時間: %.3f ミリ秒 (%.0f æ—¥ %02d:%02d:%06.3f)\n" -#: common.c:583 +#: common.c:809 #, c-format -msgid "more than one row returned for \\gset\n" -msgstr "\\gsetã«å¯¾ã—ã¦è¤‡æ•°ã®è¡ŒãŒè¿”ã•れã¾ã—ãŸ\n" +msgid "\\watch cannot be used with COPY\n" +msgstr "\\watch 㯠COPY ã¨ä¸€ç·’ã«ã¯ä½¿ãˆã¾ã›ã‚“\n" + +#: common.c:814 +#, c-format +msgid "unexpected result status for \\watch\n" +msgstr "\\watch ã§äºˆæœŸã—ãªã„çµæžœã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹\n" + +#: common.c:843 +#, c-format +msgid "" +"Asynchronous notification \"%s\" with payload \"%s\" received from server " +"process with PID %d.\n" +msgstr "" +"PID %3$d ã®ã‚µãƒ¼ãƒãƒ—ロセスã‹ã‚‰ã€ãƒšã‚¤ãƒ­ãƒ¼ãƒ‰ \"%2$s\" ã‚’æŒã¤éžåŒæœŸé€šçŸ¥ \"%1$s\" " +"ã‚’å—ä¿¡ã—ã¾ã—ãŸã€‚\n" + +#: common.c:846 +#, c-format +msgid "" +"Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "PID %2$d ã®ã‚µãƒ¼ãƒãƒ—ロセスã‹ã‚‰éžåŒæœŸé€šçŸ¥ \"%1$s\" ã‚’å—ä¿¡ã—ã¾ã—ãŸã€‚\n" + +#: common.c:908 +#, c-format +msgid "no rows returned for \\gset\n" +msgstr "\\gset ã«å¯¾ã—ã¦è¿”ã™ã¹ã行ãŒã‚りã¾ã›ã‚“\n" -#: common.c:609 +#: common.c:913 #, c-format -msgid "could not set variable \"%s\"\n" -msgstr "変数 \"%s\" をセットã§ãã¾ã›ã‚“ã§ã—ãŸ\n" +msgid "more than one row returned for \\gset\n" +msgstr "\\gset ã«å¯¾ã—ã¦è¤‡æ•°ã®è¡ŒãŒè¿”ã•れã¾ã—ãŸ\n" -#: common.c:894 +#: common.c:1301 #, c-format msgid "" -"***(Single step mode: verify command)*******************************************\n" +"***(Single step mode: verify command)" +"*******************************************\n" "%s\n" -"***(press return to proceed or enter x and return to cancel)********************\n" +"***(press return to proceed or enter x and return to cancel)" +"********************\n" msgstr "" -"***(シングルステップモード: å•ã„åˆã‚ã›ã‚’検査ã—ã¦ãã ã•ã„)********\n" +"***(シングルステップモード: コマンドを確èªã—ã¦ãã ã•ã„)********\n" "%s\n" "***([Enter] を押ã—ã¦é€²ã‚€ã‹ã€x [Enter] ã§ã‚­ãƒ£ãƒ³ã‚»ãƒ«)**************\n" -#: common.c:945 +#: common.c:1356 +#, c-format +msgid "" +"The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) 㯠ON_ERROR_ROLLBACK 用ã®ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã‚’サãƒãƒ¼ãƒˆ" +"ã—ã¦ã„ã¾ã›ã‚“。\n" + +#: common.c:1419 #, c-format -msgid "The server (version %d.%d) does not support savepoints for ON_ERROR_ROLLBACK.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã§ã¯ã€ON_ERROR_ROLLBACK用ã®ã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "STATEMENT: %s\n" +msgstr "ステートメント: %s\n" -#: common.c:1039 +#: common.c:1462 #, c-format msgid "unexpected transaction status (%d)\n" -msgstr "想定外ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³çŠ¶æ…‹ (%d)\n" +msgstr "予期ã—ãªã„トランザクションã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ (%d)\n" + +#: common.c:1599 describe.c:1941 +msgid "Column" +msgstr "列" -#: common.c:1067 +#: common.c:1600 describe.c:175 describe.c:390 describe.c:408 describe.c:453 +#: describe.c:470 describe.c:959 describe.c:1123 describe.c:1664 +#: describe.c:1688 describe.c:1942 describe.c:3529 describe.c:3734 +#: describe.c:4925 +msgid "Type" +msgstr "åž‹" + +#: common.c:1649 #, c-format -msgid "Time: %.3f ms\n" -msgstr "時間: %.3f ms\n" +msgid "The command has no result, or the result has no columns.\n" +msgstr "ã“ã®ã‚³ãƒžãƒ³ãƒ‰ã¯çµæžœã‚’è¿”å´ã—ãªã„ã‹ã€çµæžœã«ã‚«ãƒ©ãƒ ãŒå«ã¾ã‚Œã¾ã›ã‚“。\n" -#: copy.c:98 +#: copy.c:99 #, c-format msgid "\\copy: arguments required\n" -msgstr "\\copy: 引数ãŒã‚りã¾ã›ã‚“。\n" +msgstr "\\copy: 引数ãŒå¿…è¦ã§ã™\n" -#: copy.c:253 +#: copy.c:254 #, c-format msgid "\\copy: parse error at \"%s\"\n" -msgstr "\\copy: \"%s\" ã§ãƒ‘ースエラー発生\n" +msgstr "\\copy: \"%s\" ã§æ§‹æ–‡è§£æžã‚¨ãƒ©ãƒ¼\n" -#: copy.c:255 +#: copy.c:256 #, c-format msgid "\\copy: parse error at end of line\n" -msgstr "\\copy: 行末ã§ãƒ‘ースエラー発生\n" +msgstr "\\copy: è¡Œã®æœ«å°¾ã§æ§‹æ–‡è§£æžã‚¨ãƒ©ãƒ¼\n" -#: copy.c:330 +#: copy.c:329 #, c-format msgid "could not execute command \"%s\": %s\n" -msgstr "コマンド\"%s\"を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "コマンド \"%s\" を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: copy.c:346 +#: copy.c:345 #, c-format msgid "could not stat file \"%s\": %s\n" -msgstr "ファイル\"%s\"ã®statãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "ファイル \"%s\" ã‚’ stat ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: copy.c:350 +#: copy.c:349 #, c-format msgid "%s: cannot copy from/to a directory\n" msgstr "%s: ディレクトリã‹ã‚‰ï¼ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¸ã®ã‚³ãƒ”ーã¯ã§ãã¾ã›ã‚“。\n" -#: copy.c:387 +#: copy.c:386 #, c-format msgid "could not close pipe to external command: %s\n" -msgstr "外部コマンドã«å¯¾ã™ã‚‹ãƒ‘イプをクローズã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgstr "外部コマンドã¸ã®ãƒ‘イプを閉ã˜ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: copy.c:455 copy.c:466 +#: copy.c:452 copy.c:463 #, c-format msgid "could not write COPY data: %s\n" -msgstr "COPY 対象データを書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸï¼š%s\n" +msgstr "COPY データを書ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: copy.c:473 +#: copy.c:470 #, c-format msgid "COPY data transfer failed: %s" -msgstr "COPY 対象データã®è»¢é€ã«å¤±æ•—ã—ã¾ã—ãŸï¼š%s" +msgstr "COPY データã®è»¢é€ã«å¤±æ•—ã—ã¾ã—ãŸ: %s" -#: copy.c:534 +#: copy.c:531 msgid "canceled by user" -msgstr "ユーザã«ã‚ˆã‚Šã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" +msgstr "ユーザã«ã‚ˆã£ã¦ã‚­ãƒ£ãƒ³ã‚»ãƒ«ã•れã¾ã—ãŸ" -#: copy.c:544 +#: copy.c:542 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" -"コピーã™ã‚‹ãƒ‡ãƒ¼ã‚¿ã«ç¶šã„ã¦æ”¹è¡Œã‚’入力ã—ã¾ã™ã€‚\n" -"ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥(\\)ã¨ãƒ”リオドã ã‘ã®è¡Œã§çµ‚了ã—ã¾ã™ã€‚" +"コピーã™ã‚‹ãƒ‡ãƒ¼ã‚¿ã«ç¶šã„ã¦æ”¹è¡Œã‚’入力ã—ã¦ãã ã•ã„。\n" +"ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã¨ãƒ”リオドã ã‘ã®è¡Œã€ã‚‚ã—ã㯠EOF シグナルã§çµ‚了ã—ã¾ã™ã€‚" -#: copy.c:667 +#: copy.c:670 msgid "aborted because of read failure" -msgstr "読ã¿è¾¼ã¿ã«å¤±æ•—ã—ãŸãŸã‚異常終了ã—ã¾ã—ãŸ" +msgstr "読ã¿å–りエラーã®ãŸã‚中止" -#: copy.c:691 +#: copy.c:704 msgid "trying to exit copy mode" msgstr "コピーモードを終了ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚" -#: describe.c:71 describe.c:259 describe.c:491 describe.c:615 describe.c:758 -#: describe.c:844 describe.c:914 describe.c:2759 describe.c:2964 -#: describe.c:3054 describe.c:3299 describe.c:3436 describe.c:3665 -#: describe.c:3737 describe.c:3748 describe.c:3807 describe.c:4215 -#: describe.c:4294 +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set\n" +msgstr "\\crosstabview: ステートメントã¯çµæžœã‚»ãƒƒãƒˆã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns\n" +msgstr "" +"\\crosstabview: å•ã„åˆã‚ã›ã¯ã€å°‘ãªãã¨ã‚‚3ã¤ã®åˆ—ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™ã€‚\n" + +#: crosstabview.c:156 +#, c-format +msgid "" +"\\crosstabview: vertical and horizontal headers must be different columns\n" +msgstr "" +"\\crosstabview: 垂直方å‘ã¨æ°´å¹³æ–¹å‘ã®ãƒ˜ãƒƒãƒ€ãƒ¼ã¯ç•°ãªã£ãŸåˆ—ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾" +"ã™ã€‚\n" + +#: crosstabview.c:172 +#, c-format +msgid "" +"\\crosstabview: data column must be specified when query returns more than " +"three columns\n" +msgstr "" +"\\crosstabview: å•ã„åˆã‚ã›ãŒ 4 ã¤ä»¥ä¸Šã®åˆ—ã‚’è¿”ã™å ´åˆã€ãƒ‡ãƒ¼ã‚¿åˆ—を指定ã™ã‚‹å¿…è¦ãŒ" +"ã‚りã¾ã™ã€‚\n" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" +msgstr "列数ãŒåˆ¶é™å€¤ (%d) ã‚’è¶…ãˆã¦ã„ã¾ã™ã€‚\n" + +#: crosstabview.c:397 +#, c-format +msgid "" +"\\crosstabview: query result contains multiple data values for row \"%s\", " +"column \"%s\"\n" +msgstr "" +"\\crosstabview: å•ã„åˆã‚ã›çµæžœã®ä¸­ã® \"%s\" 行 \"%s\" 列ã«è¤‡æ•°ã®ãƒ‡ãƒ¼ã‚¿å€¤ãŒå«" +"ã¾ã‚Œã¦ã„ã¾ã™ã€‚\n" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d\n" +msgstr "\\crosstabview: åˆ—ç•ªå· %d ãŒç¯„囲外ã§ã™(1..%d)\n" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"\n" +msgstr "\\crosstabview: 列åを一æ„ã«ç‰¹å®šã§ãã¾ã›ã‚“: \"%s\"\n" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"\n" +msgstr "\\crosstabview: 列åãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: \"%s\"\n" + +#: describe.c:75 describe.c:370 describe.c:675 describe.c:807 describe.c:951 +#: describe.c:1112 describe.c:1184 describe.c:3518 describe.c:3732 +#: describe.c:3823 describe.c:4090 describe.c:4235 describe.c:4476 +#: describe.c:4551 describe.c:4562 describe.c:4624 describe.c:5049 +#: describe.c:5132 msgid "Schema" msgstr "スキーマ" -#: describe.c:72 describe.c:156 describe.c:164 describe.c:260 describe.c:492 -#: describe.c:616 describe.c:677 describe.c:759 describe.c:915 describe.c:2760 -#: describe.c:2886 describe.c:2965 describe.c:3055 describe.c:3134 -#: describe.c:3300 describe.c:3364 describe.c:3437 describe.c:3666 -#: describe.c:3738 describe.c:3749 describe.c:3808 describe.c:3997 -#: describe.c:4078 describe.c:4292 +#: describe.c:76 describe.c:173 describe.c:240 describe.c:248 describe.c:371 +#: describe.c:676 describe.c:808 describe.c:869 describe.c:952 describe.c:1185 +#: describe.c:3519 describe.c:3655 describe.c:3733 describe.c:3824 +#: describe.c:3903 describe.c:4091 describe.c:4160 describe.c:4236 +#: describe.c:4477 describe.c:4552 describe.c:4563 describe.c:4625 +#: describe.c:4822 describe.c:4906 describe.c:5130 describe.c:5302 +#: describe.c:5527 msgid "Name" msgstr "åå‰" -#: describe.c:73 describe.c:272 describe.c:318 describe.c:335 +#: describe.c:77 describe.c:383 describe.c:401 describe.c:447 describe.c:464 msgid "Result data type" msgstr "çµæžœã®ãƒ‡ãƒ¼ã‚¿åž‹" -#: describe.c:81 describe.c:94 describe.c:98 describe.c:273 describe.c:319 -#: describe.c:336 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:384 describe.c:402 +#: describe.c:448 describe.c:465 msgid "Argument data types" msgstr "引数ã®ãƒ‡ãƒ¼ã‚¿åž‹" -#: describe.c:105 describe.c:182 describe.c:365 describe.c:534 describe.c:631 -#: describe.c:702 describe.c:917 describe.c:1486 describe.c:2564 -#: describe.c:2793 describe.c:2917 describe.c:2991 describe.c:3064 -#: describe.c:3147 describe.c:3215 describe.c:3307 describe.c:3373 -#: describe.c:3438 describe.c:3574 describe.c:3614 describe.c:3682 -#: describe.c:3741 describe.c:3750 describe.c:3809 describe.c:4023 -#: describe.c:4100 describe.c:4229 describe.c:4295 large_obj.c:291 -#: large_obj.c:301 +#: describe.c:110 describe.c:117 describe.c:183 describe.c:271 describe.c:510 +#: describe.c:724 describe.c:823 describe.c:894 describe.c:1187 +#: describe.c:1960 describe.c:3307 describe.c:3554 describe.c:3686 +#: describe.c:3760 describe.c:3833 describe.c:3916 describe.c:3999 +#: describe.c:4103 describe.c:4169 describe.c:4237 describe.c:4378 +#: describe.c:4420 describe.c:4493 describe.c:4555 describe.c:4564 +#: describe.c:4626 describe.c:4848 describe.c:4928 describe.c:5063 +#: describe.c:5133 large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "説明" -#: describe.c:123 +#: describe.c:135 msgid "List of aggregate functions" msgstr "集約関数一覧" -#: describe.c:144 +#: describe.c:160 +#, c-format +msgid "The server (version %s) does not support access methods.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ã‚¢ã‚¯ã‚»ã‚¹ãƒ¡ã‚½ãƒƒãƒ‰ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" + +#: describe.c:174 +msgid "Index" +msgstr "インデックス" + +#: describe.c:182 describe.c:4827 +msgid "Handler" +msgstr "ãƒãƒ³ãƒ‰ãƒ©ãƒ¼" + +#: describe.c:201 +msgid "List of access methods" +msgstr "アクセスメソッド一覧" + +#: describe.c:227 #, c-format -msgid "The server (version %d.%d) does not support tablespaces.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã¯ãƒ†ãƒ¼ãƒ–ルスペースをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support tablespaces.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ†ãƒ¼ãƒ–ル空間をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:157 describe.c:165 describe.c:362 describe.c:678 describe.c:843 -#: describe.c:2769 describe.c:2890 describe.c:3136 describe.c:3365 -#: describe.c:3998 describe.c:4079 large_obj.c:290 +#: describe.c:241 describe.c:249 describe.c:498 describe.c:714 describe.c:870 +#: describe.c:1111 describe.c:3530 describe.c:3659 describe.c:3905 +#: describe.c:4161 describe.c:4823 describe.c:4907 describe.c:5303 +#: describe.c:5429 describe.c:5528 large_obj.c:288 msgid "Owner" msgstr "所有者" -#: describe.c:158 describe.c:166 +#: describe.c:242 describe.c:250 msgid "Location" msgstr "場所" -#: describe.c:177 describe.c:2382 +#: describe.c:261 describe.c:3126 msgid "Options" msgstr "オプション" -#: describe.c:199 +#: describe.c:266 describe.c:687 describe.c:886 describe.c:3546 +#: describe.c:3550 +msgid "Size" +msgstr "サイズ" + +#: describe.c:288 msgid "List of tablespaces" -msgstr "テーブルスペース一覧" +msgstr "テーブル空間一覧" -#: describe.c:236 +#: describe.c:330 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\dfã¯ã‚ªãƒ—ションã¨ã—ã¦[antwS+]ã®ã¿ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã™\n" +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df ã§æŒ‡å®šã§ãるオプション㯠[anptwS+] ã®ã¿ã§ã™ã€‚\n" -#: describe.c:242 +#: describe.c:338 describe.c:349 #, c-format -msgid "\\df does not take a \"w\" option with server version %d.%d\n" -msgstr "サーãƒãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%dã§ã¯\\dfã¯\"w\"オプションをå—ã‘付ã‘ã¾ã›ã‚“\n" +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "" +"サーãƒãƒãƒ¼ã‚¸ãƒ§ãƒ³ %2$s ã® \\df ã§ã¯ \"%1$c\" ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã¯æŒ‡å®šã§ãã¾ã›ã‚“。\n" #. translator: "agg" is short for "aggregate" -#: describe.c:275 describe.c:321 describe.c:338 +#: describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "agg" -msgstr "agg(集約)" +msgstr "集約" -#: describe.c:276 +#: describe.c:387 describe.c:405 msgid "window" -msgstr "window(ウィンドウ)" - -#: describe.c:277 describe.c:322 describe.c:339 describe.c:1028 -msgid "trigger" -msgstr "trigger(トリガ)" - -#: describe.c:278 describe.c:323 describe.c:340 -msgid "normal" -msgstr "normal(通常)" - -#: describe.c:279 describe.c:324 describe.c:341 describe.c:765 describe.c:853 -#: describe.c:1455 describe.c:2768 describe.c:2966 describe.c:4097 -msgid "Type" -msgstr "åž‹" +msgstr "ウィンドウ" -#: describe.c:355 -msgid "definer" -msgstr "定義元" +#: describe.c:388 +msgid "proc" +msgstr "プロシージャ" -#: describe.c:356 -msgid "invoker" -msgstr "呼ã³å‡ºã—å…ƒ" +#: describe.c:389 describe.c:407 describe.c:452 describe.c:469 +msgid "func" +msgstr "関数" -#: describe.c:357 -msgid "Security" -msgstr "セキュリティ" +#: describe.c:406 describe.c:451 describe.c:468 describe.c:1321 +msgid "trigger" +msgstr "トリガー" -#: describe.c:358 +#: describe.c:480 msgid "immutable" -msgstr "ä¸å¤‰" +msgstr "IMMUTABLE" -#: describe.c:359 +#: describe.c:481 msgid "stable" -msgstr "安定" +msgstr "STABLE" -#: describe.c:360 +#: describe.c:482 msgid "volatile" -msgstr "æ®ç™ºæ€§" +msgstr "VOLATILE" -#: describe.c:361 +#: describe.c:483 msgid "Volatility" -msgstr "æ®ç™ºæ€§" +msgstr "関数ã®å¤‰å‹•性分類" + +#: describe.c:491 +msgid "restricted" +msgstr "制é™ä»˜ã" -#: describe.c:363 +#: describe.c:492 +msgid "safe" +msgstr "安全" + +#: describe.c:493 +msgid "unsafe" +msgstr "å±é™º" + +#: describe.c:494 +msgid "Parallel" +msgstr "並列実行" + +#: describe.c:499 +msgid "definer" +msgstr "定義ロール" + +#: describe.c:500 +msgid "invoker" +msgstr "起動ロール" + +#: describe.c:501 +msgid "Security" +msgstr "セキュリティ" + +#: describe.c:508 msgid "Language" -msgstr "言語" +msgstr "手続ã言語" -#: describe.c:364 +#: describe.c:509 msgid "Source code" msgstr "ソースコード" -#: describe.c:462 +#: describe.c:638 msgid "List of functions" msgstr "関数一覧" -#: describe.c:502 +#: describe.c:686 msgid "Internal name" msgstr "内部å" -#: describe.c:503 describe.c:694 describe.c:2785 describe.c:2789 -msgid "Size" -msgstr "サイズ" - -#: describe.c:524 +#: describe.c:708 msgid "Elements" -msgstr "è¦ç´ " +msgstr "æ§‹æˆè¦ç´ " -#: describe.c:574 +#: describe.c:765 msgid "List of data types" msgstr "データ型一覧" -#: describe.c:617 +#: describe.c:809 msgid "Left arg type" msgstr "左辺ã®åž‹" -#: describe.c:618 +#: describe.c:810 msgid "Right arg type" msgstr "å³è¾ºã®åž‹" -#: describe.c:619 +#: describe.c:811 msgid "Result type" msgstr "çµæžœã®åž‹" -#: describe.c:624 describe.c:3206 describe.c:3573 +#: describe.c:816 describe.c:3911 describe.c:3976 describe.c:3982 +#: describe.c:4377 msgid "Function" msgstr "関数" -#: describe.c:649 +#: describe.c:841 msgid "List of operators" msgstr "演算å­ä¸€è¦§" -#: describe.c:679 +#: describe.c:871 msgid "Encoding" msgstr "エンコーディング" -#: describe.c:684 describe.c:3301 +#: describe.c:876 describe.c:4092 msgid "Collate" msgstr "ç…§åˆé †åº" -#: describe.c:685 describe.c:3302 +#: describe.c:877 describe.c:4093 msgid "Ctype" msgstr "Ctype(å¤‰æ›æ¼”ç®—å­)" -#: describe.c:698 +#: describe.c:890 msgid "Tablespace" -msgstr "テーブルスペース" +msgstr "テーブル空間" -#: describe.c:720 +#: describe.c:912 msgid "List of databases" msgstr "データベース一覧" -#: describe.c:760 describe.c:846 describe.c:2761 +#: describe.c:953 describe.c:958 describe.c:1114 describe.c:3520 +#: describe.c:3527 msgid "table" msgstr "テーブル" -#: describe.c:761 describe.c:2762 +#: describe.c:954 describe.c:3521 msgid "view" msgstr "ビュー" -#: describe.c:762 describe.c:2763 +#: describe.c:955 describe.c:3522 msgid "materialized view" msgstr "マテリアライズドビュー" -#: describe.c:763 describe.c:848 describe.c:2765 +#: describe.c:956 describe.c:1116 describe.c:3524 msgid "sequence" msgstr "シーケンス" -#: describe.c:764 describe.c:2767 +#: describe.c:957 describe.c:3526 msgid "foreign table" msgstr "外部テーブル" -#: describe.c:776 -msgid "Column access privileges" -msgstr "列ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™" +#: describe.c:970 +msgid "Column privileges" +msgstr "åˆ—ã®æ¨©é™" + +#: describe.c:1001 describe.c:1035 +msgid "Policies" +msgstr "ãƒãƒªã‚·ãƒ¼" -#: describe.c:802 describe.c:4439 describe.c:4443 +#: describe.c:1067 describe.c:5584 describe.c:5588 msgid "Access privileges" -msgstr "アクセス権" +msgstr "アクセス権é™" -#: describe.c:831 +#: describe.c:1098 #, c-format -msgid "The server (version %d.%d) does not support altering default privileges.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã¯ä»£æ›¿ã®ãƒ‡ãƒ•ォルト権é™ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support altering default privileges.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ‡ãƒ•ォルト権é™ã®å¤‰æ›´ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:850 +#: describe.c:1118 msgid "function" msgstr "関数" -#: describe.c:852 +#: describe.c:1120 msgid "type" msgstr "åž‹" -#: describe.c:876 +#: describe.c:1122 +msgid "schema" +msgstr "スキーマ" + +#: describe.c:1146 msgid "Default access privileges" msgstr "デフォルトã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™" -#: describe.c:916 +#: describe.c:1186 msgid "Object" msgstr "オブジェクト" -#: describe.c:930 sql_help.c:1595 -msgid "constraint" -msgstr "制約" +#: describe.c:1200 +msgid "table constraint" +msgstr "テーブル制約" + +#: describe.c:1222 +msgid "domain constraint" +msgstr "ドメイン制約" -#: describe.c:957 +#: describe.c:1250 msgid "operator class" msgstr "演算å­ã‚¯ãƒ©ã‚¹" -#: describe.c:986 +#: describe.c:1279 msgid "operator family" msgstr "æ¼”ç®—å­æ—" -#: describe.c:1008 +#: describe.c:1301 msgid "rule" msgstr "ルール" -#: describe.c:1050 +#: describe.c:1343 msgid "Object descriptions" msgstr "オブジェクトã®èª¬æ˜Ž" -#: describe.c:1104 +#: describe.c:1399 describe.c:3618 #, c-format msgid "Did not find any relation named \"%s\".\n" -msgstr "\"%s\" ã¨ã„ã†åå‰ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "\"%s\" ã¨ã„ã†åå‰ã®ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ã¯è¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:1402 describe.c:3621 +#, c-format +msgid "Did not find any relations.\n" +msgstr "リレーションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:1295 +#: describe.c:1619 #, c-format msgid "Did not find any relation with OID %s.\n" -msgstr "OID %s ã‚’æŒã¤ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "OID %s ã‚’æŒã¤ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:1665 describe.c:1689 +msgid "Start" +msgstr "é–‹å§‹" + +#: describe.c:1666 describe.c:1690 +msgid "Minimum" +msgstr "最å°" + +#: describe.c:1667 describe.c:1691 +msgid "Maximum" +msgstr "最大" + +#: describe.c:1668 describe.c:1692 +msgid "Increment" +msgstr "増分" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3827 +#: describe.c:3993 +msgid "yes" +msgstr "ã¯ã„" + +#: describe.c:1670 describe.c:1694 describe.c:1819 describe.c:3827 +#: describe.c:3990 +msgid "no" +msgstr "ã„ã„ãˆ" -#: describe.c:1399 +#: describe.c:1671 describe.c:1695 +msgid "Cycles?" +msgstr "循環?" + +#: describe.c:1672 describe.c:1696 +msgid "Cache" +msgstr "キャッシュ" + +#: describe.c:1739 +#, c-format +msgid "Owned by: %s" +msgstr "所有者: %s" + +#: describe.c:1743 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "識別列ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹: %s" + +#: describe.c:1750 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "シーケンス \"%s.%s\"" + +#: describe.c:1880 describe.c:1926 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "ログをå–らãªã„テーブル \"%s.%s\"" -#: describe.c:1402 +#: describe.c:1883 describe.c:1929 #, c-format msgid "Table \"%s.%s\"" msgstr "テーブル \"%s.%s\"" -#: describe.c:1406 +#: describe.c:1887 #, c-format msgid "View \"%s.%s\"" msgstr "ビュー \"%s.%s\"" -#: describe.c:1411 +#: describe.c:1892 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "ログをå–らãªã„マテリアライズドビュー \"%s.%s\"" -#: describe.c:1414 +#: describe.c:1895 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "マテリアライズドビュー \"%s.%s\"" -#: describe.c:1418 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "シーケンス \"%s.%s\"" - -#: describe.c:1423 +#: describe.c:1901 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "ログをå–らãªã„インデックス \"%s.%s\"" -#: describe.c:1426 +#: describe.c:1904 #, c-format msgid "Index \"%s.%s\"" msgstr "インデックス \"%s.%s\"" -#: describe.c:1431 +#: describe.c:1909 #, c-format msgid "Special relation \"%s.%s\"" msgstr "特殊ãªãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ \"%s.%s\"" -#: describe.c:1435 +#: describe.c:1913 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST テーブル \"%s.%s\"" -#: describe.c:1439 +#: describe.c:1917 #, c-format msgid "Composite type \"%s.%s\"" msgstr "複åˆåž‹ \"%s.%s\"" -#: describe.c:1443 +#: describe.c:1921 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "外部テーブル \"%s.%s\"" -#: describe.c:1454 -msgid "Column" -msgstr "列" +#: describe.c:1945 describe.c:3740 +msgid "Collation" +msgstr "ç…§åˆé †åº" -#: describe.c:1463 -msgid "Modifiers" -msgstr "修飾語" +#: describe.c:1946 describe.c:3747 +msgid "Nullable" +msgstr "Null 値を許容" -#: describe.c:1468 -msgid "Value" -msgstr "値" +#: describe.c:1947 describe.c:3748 +msgid "Default" +msgstr "デフォルト" + +#: describe.c:1950 +msgid "Key?" +msgstr "キー?" -#: describe.c:1471 +#: describe.c:1952 msgid "Definition" msgstr "定義" -#: describe.c:1474 describe.c:4018 describe.c:4099 describe.c:4167 -#: describe.c:4228 -msgid "FDW Options" -msgstr "FDWオプション" +#: describe.c:1954 describe.c:4843 describe.c:4927 describe.c:4998 +#: describe.c:5062 +msgid "FDW options" +msgstr "FDW オプション" -#: describe.c:1478 +#: describe.c:1956 msgid "Storage" msgstr "ストレージ" -#: describe.c:1481 +#: describe.c:1958 msgid "Stats target" -msgstr "対象統計情報" +msgstr "統計ã®å¯¾è±¡" -#: describe.c:1531 +#: describe.c:2072 #, c-format -msgid "collate %s" -msgstr "ç…§åˆé †åº %s" +msgid "Partition of: %s %s" +msgstr "パーティション: %s %s" -#: describe.c:1539 -msgid "not null" -msgstr "not null" +#: describe.c:2080 +msgid "No partition constraint" +msgstr "パーティション制約ãªã—" -#. translator: default values of column definitions -#: describe.c:1549 +#: describe.c:2082 #, c-format -msgid "default %s" -msgstr "default %s" +msgid "Partition constraint: %s" +msgstr "パーティションã®åˆ¶ç´„: %s" -#: describe.c:1664 +#: describe.c:2105 +#, c-format +msgid "Partition key: %s" +msgstr "パーティションキー: %s" + +#: describe.c:2174 msgid "primary key, " msgstr "プライマリキー, " -#: describe.c:1666 +#: describe.c:2176 msgid "unique, " -msgstr "ユニーク, " +msgstr "ユニーク," -#: describe.c:1672 +#: describe.c:2182 #, c-format msgid "for table \"%s.%s\"" msgstr "テーブル \"%s.%s\" 用" -#: describe.c:1676 +#: describe.c:2186 #, c-format msgid ", predicate (%s)" -msgstr ", 述語 (%s)" +msgstr "ã€è¿°èªž (%s)" -#: describe.c:1679 +#: describe.c:2189 msgid ", clustered" -msgstr ", クラスタ化済ã¿" +msgstr "ã€ã‚¯ãƒ©ã‚¹ã‚¿ãƒ¼åŒ–" -#: describe.c:1682 +#: describe.c:2192 msgid ", invalid" -msgstr ", 無効" +msgstr "無効" -#: describe.c:1685 +#: describe.c:2195 msgid ", deferrable" -msgstr ", é…å»¶å¯èƒ½" +msgstr "ã€é…å»¶å¯èƒ½" -#: describe.c:1688 +#: describe.c:2198 msgid ", initially deferred" -msgstr ", 最åˆã‹ã‚‰é…å»¶ã•れã¦ã„ã‚‹" +msgstr "ã€æœ€åˆã‹ã‚‰é…延中" -#: describe.c:1691 +#: describe.c:2201 msgid ", replica identity" -msgstr "レプリカ特性" - -#: describe.c:1726 -#, c-format -msgid "Owned by: %s" -msgstr "所有者: %s" +msgstr "ã€ãƒ¬ãƒ—リカ㮠id" -#: describe.c:1786 +#: describe.c:2260 msgid "Indexes:" msgstr "インデックス:" -#: describe.c:1870 +#: describe.c:2344 msgid "Check constraints:" -msgstr "検査制約:" +msgstr "Check 制約:" -#: describe.c:1901 +#: describe.c:2380 msgid "Foreign-key constraints:" msgstr "外部キー制約:" -#: describe.c:1932 +#: describe.c:2411 msgid "Referenced by:" -msgstr "å‚照元:" +msgstr "å‚ç…§å…ƒ:" + +#: describe.c:2461 +msgid "Policies:" +msgstr "ãƒãƒªã‚·ãƒ¼:" + +#: describe.c:2464 +msgid "Policies (forced row security enabled):" +msgstr "ãƒãƒªã‚·ãƒ¼(è¡Œã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚’å¼·åˆ¶çš„ã«æœ‰åŠ¹åŒ–):" + +#: describe.c:2467 +msgid "Policies (row security enabled): (none)" +msgstr "ãƒãƒªã‚·ãƒ¼(行セキュリティ有効化): (ãªã—)" + +#: describe.c:2470 +msgid "Policies (forced row security enabled): (none)" +msgstr "ãƒãƒªã‚·ãƒ¼(è¡Œã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ã‚’å¼·åˆ¶çš„ã«æœ‰åŠ¹åŒ–): (ãªã—)" + +#: describe.c:2473 +msgid "Policies (row security disabled):" +msgstr "ãƒãƒªã‚·ãƒ¼(行セキュリティを無効化):" -#: describe.c:2014 describe.c:2064 +#: describe.c:2535 +msgid "Statistics objects:" +msgstr "統計オブジェクト:" + +#: describe.c:2638 describe.c:2742 msgid "Rules:" msgstr "ルール:" -#: describe.c:2017 +#: describe.c:2641 msgid "Disabled rules:" -msgstr "無効ã«ã•れãŸãƒ«ãƒ¼ãƒ«ï¼š" +msgstr "無効化ã•れãŸãƒ«ãƒ¼ãƒ«:" -#: describe.c:2020 +#: describe.c:2644 msgid "Rules firing always:" -msgstr "常ã«ç„¡è¦–ã•れるルール" +msgstr "常ã«é©ç”¨ã™ã‚‹ãƒ«ãƒ¼ãƒ«:" -#: describe.c:2023 +#: describe.c:2647 msgid "Rules firing on replica only:" -msgstr "レプリカã§ã®ã¿ç„¡è¦–ã•れるルール" +msgstr "レプリカ上ã§ã®ã¿é©ç”¨ã™ã‚‹ãƒ«ãƒ¼ãƒ«:" + +#: describe.c:2687 +msgid "Publications:" +msgstr "パブリケーション:" -#: describe.c:2047 +#: describe.c:2725 msgid "View definition:" -msgstr "ビュー定義:" +msgstr "ビューã®å®šç¾©:" -#: describe.c:2182 +#: describe.c:2864 msgid "Triggers:" -msgstr "トリガ:" +msgstr "トリガー:" -#: describe.c:2186 +#: describe.c:2868 msgid "Disabled user triggers:" -msgstr "無効ã«ã•れãŸãƒ¦ãƒ¼ã‚¶ãƒˆãƒªã‚¬ï¼š" +msgstr "無効化ã•れãŸãƒ¦ãƒ¼ã‚¶ãƒˆãƒªã‚¬:" -#: describe.c:2188 +#: describe.c:2870 msgid "Disabled triggers:" -msgstr "無効ã«ã•れãŸãƒˆãƒªã‚¬ï¼š" +msgstr "無効化ã•れãŸãƒˆãƒªã‚¬ãƒ¼:" -#: describe.c:2191 +#: describe.c:2873 msgid "Disabled internal triggers:" -msgstr "無効ã«ã•れãŸå†…部トリガ:" +msgstr "無効化ã•れãŸå†…部トリガー:" -#: describe.c:2194 +#: describe.c:2876 msgid "Triggers firing always:" -msgstr "常ã«ç„¡è¦–ã•れるトリガ" +msgstr "常ã«é©ç”¨ã™ã‚‹ã™ã‚‹ãƒˆãƒªã‚¬ãƒ¼:" -#: describe.c:2197 +#: describe.c:2879 msgid "Triggers firing on replica only:" -msgstr "レプリカã§ã®ã¿ç„¡è¦–ã•れるトリガ" +msgstr "レプリカ上ã§ã®ã¿é©ç”¨ã™ã‚‹ãƒˆãƒªã‚¬ãƒ¼:" + +#: describe.c:2938 +#, c-format +msgid "Server: %s" +msgstr "サーãƒ: %s" + +#: describe.c:2946 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW オプション: (%s)" -#: describe.c:2276 +#: describe.c:2965 msgid "Inherits" -msgstr "継承" +msgstr "継承元" -#: describe.c:2315 +#: describe.c:3024 +#, c-format +msgid "Number of partitions: %d" +msgstr "パーティション数: %d" + +#: describe.c:3033 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" -msgstr "å­ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ•°ï¼š%d(\\d+ ã§ä¸€è¦§è¡¨ç¤ºï¼‰" +msgstr "å­ãƒ†ãƒ¼ãƒ–ル数: %d (\\d+ ã§ä¸€è¦§ã‚’表示)" + +#: describe.c:3035 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "パーティション数: %d (\\d+ ã§ä¸€è¦§ã‚’表示)。" -#: describe.c:2322 +#: describe.c:3043 msgid "Child tables" msgstr "å­ãƒ†ãƒ¼ãƒ–ル" -#: describe.c:2344 +#: describe.c:3043 +msgid "Partitions" +msgstr "パーティション" + +#: describe.c:3086 #, c-format msgid "Typed table of type: %s" -msgstr "型付ã‘ã•れãŸãƒ†ãƒ¼ãƒ–ルã®åž‹ï¼š%s" +msgstr "%s åž‹ã®åž‹ä»˜ãテーブル" -#: describe.c:2358 +#: describe.c:3102 msgid "Replica Identity" -msgstr "レプリカ特性" +msgstr "レプリカ識別" -#: describe.c:2371 +#: describe.c:3115 msgid "Has OIDs: yes" -msgstr "OID ã‚’æŒã¤: ã¯ã„" +msgstr "OID ã‚り: ã¯ã„" -#: describe.c:2460 +#: describe.c:3195 #, c-format msgid "Tablespace: \"%s\"" -msgstr "テーブルスペース \"%s\"" +msgstr "テーブル空間: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:2472 +#: describe.c:3207 #, c-format msgid ", tablespace \"%s\"" -msgstr "テーブルスペース \"%s\"" +msgstr "ã€ãƒ†ãƒ¼ãƒ–ル空間 \"%s\"" -#: describe.c:2557 +#: describe.c:3300 msgid "List of roles" msgstr "ロール一覧" -#: describe.c:2559 +#: describe.c:3302 msgid "Role name" msgstr "ロールå" -#: describe.c:2560 +#: describe.c:3303 msgid "Attributes" msgstr "属性" -#: describe.c:2561 +#: describe.c:3304 msgid "Member of" -msgstr "メンãƒãƒ¼" +msgstr "所属グループ" -#: describe.c:2572 +#: describe.c:3315 msgid "Superuser" msgstr "スーパーユーザ" -#: describe.c:2575 +#: describe.c:3318 msgid "No inheritance" msgstr "継承ãªã—" -#: describe.c:2578 +#: describe.c:3321 msgid "Create role" -msgstr "ロールを作æˆã§ãã‚‹" +msgstr "ロール作æˆå¯" -#: describe.c:2581 +#: describe.c:3324 msgid "Create DB" -msgstr "DBを作æˆã§ãã‚‹" +msgstr "DB作æˆå¯" -#: describe.c:2584 +#: describe.c:3327 msgid "Cannot login" -msgstr "ログインã§ããªã„" +msgstr "ログインã§ãã¾ã›ã‚“" -#: describe.c:2588 +#: describe.c:3331 msgid "Replication" -msgstr "レプリケーション" +msgstr "レプリケーションå¯" -#: describe.c:2597 +#: describe.c:3335 +msgid "Bypass RLS" +msgstr "RLS ã®ãƒã‚¤ãƒ‘ス" + +#: describe.c:3344 msgid "No connections" msgstr "接続ãªã—" -#: describe.c:2599 +#: describe.c:3346 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d å€‹ã®æŽ¥ç¶š" -msgstr[1] "%d å€‹ã®æŽ¥ç¶š" -#: describe.c:2609 +#: describe.c:3356 msgid "Password valid until " -msgstr "パスワード有効期é™" +msgstr "ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰ã®æœ‰åŠ¹æœŸé™ " + +#: describe.c:3406 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã”ã¨ã®ãƒ­ãƒ¼ãƒ«è¨­å®šã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›" +"ã‚“\n" -#: describe.c:2665 +#: describe.c:3419 msgid "Role" msgstr "ロール" -#: describe.c:2666 +#: describe.c:3420 msgid "Database" msgstr "データベース" -#: describe.c:2667 +#: describe.c:3421 msgid "Settings" msgstr "設定" -#: describe.c:2677 +#: describe.c:3442 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚µãƒ¼ãƒãƒ¼ã§ã¯ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹æ¯Žã®ãƒ­ãƒ¼ãƒ«è¨­å®šã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "ロール \"%s\" ã¨ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ \"%s\" ã®è¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:2688 +#: describe.c:3445 #, c-format -msgid "No matching settings found.\n" -msgstr "マッãƒã™ã‚‹è¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "ロール \"%s\" ã®è¨­å®šãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:2690 +#: describe.c:3448 #, c-format -msgid "No settings found.\n" -msgstr "設定ãŒã‚りã¾ã›ã‚“。\n" +msgid "Did not find any settings.\n" +msgstr "設定ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:2695 +#: describe.c:3453 msgid "List of settings" -msgstr "設定ã®ä¸€è¦§" +msgstr "設定一覧" -#: describe.c:2764 +#: describe.c:3523 describe.c:3528 msgid "index" msgstr "インデックス" -#: describe.c:2766 +#: describe.c:3525 msgid "special" msgstr "特殊" -#: describe.c:2774 describe.c:4216 +#: describe.c:3535 describe.c:5050 msgid "Table" msgstr "テーブル" -#: describe.c:2850 -#, c-format -msgid "No matching relations found.\n" -msgstr "マッãƒã™ã‚‹ãƒªãƒ¬ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“\n" - -#: describe.c:2852 -#, c-format -msgid "No relations found.\n" -msgstr "リレーションãŒã‚りã¾ã›ã‚“。\n" - -#: describe.c:2857 +#: describe.c:3626 msgid "List of relations" -msgstr "リレーションã®ä¸€è¦§" +msgstr "リレーション一覧" -#: describe.c:2894 +#: describe.c:3663 msgid "Trusted" -msgstr "ä¿¡é ¼?" +msgstr "信頼済ã¿" -#: describe.c:2902 -msgid "Internal Language" +#: describe.c:3671 +msgid "Internal language" msgstr "内部言語" -#: describe.c:2903 -msgid "Call Handler" +#: describe.c:3672 +msgid "Call handler" msgstr "呼ã³å‡ºã—ãƒãƒ³ãƒ‰ãƒ©ãƒ¼" -#: describe.c:2904 describe.c:4005 +#: describe.c:3673 describe.c:4830 msgid "Validator" -msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚¿" +msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚¿ãƒ¼" -#: describe.c:2907 -msgid "Inline Handler" +#: describe.c:3676 +msgid "Inline handler" msgstr "インラインãƒãƒ³ãƒ‰ãƒ©ãƒ¼" -#: describe.c:2935 +#: describe.c:3704 msgid "List of languages" -msgstr "言語一覧" - -#: describe.c:2979 -msgid "Modifier" -msgstr "修飾語" +msgstr "手続ã言語一覧" -#: describe.c:2980 +#: describe.c:3749 msgid "Check" -msgstr "ãƒã‚§ãƒƒã‚¯" +msgstr "CHECK制約" -#: describe.c:3022 +#: describe.c:3791 msgid "List of domains" msgstr "ドメイン一覧" -#: describe.c:3056 +#: describe.c:3825 msgid "Source" -msgstr "ソース" +msgstr "変æ›å…ƒ" -#: describe.c:3057 +#: describe.c:3826 msgid "Destination" -msgstr "宛先" - -#: describe.c:3058 describe.c:3207 -msgid "no" -msgstr "no" +msgstr "変æ›å…ˆ" -#: describe.c:3058 describe.c:3209 -msgid "yes" -msgstr "yes" - -#: describe.c:3059 +#: describe.c:3828 msgid "Default?" -msgstr "デフォルト?" +msgstr "デフォルト?" -#: describe.c:3096 +#: describe.c:3865 msgid "List of conversions" -msgstr "変æ›ãƒ«ãƒ¼ãƒ«ä¸€è¦§" +msgstr "符å·åŒ–æ–¹å¼ä¸€è¦§" -#: describe.c:3135 +#: describe.c:3904 msgid "Event" msgstr "イベント" -#: describe.c:3137 +#: describe.c:3906 msgid "enabled" msgstr "有効" -#: describe.c:3138 +#: describe.c:3907 msgid "replica" msgstr "レプリカ" -#: describe.c:3139 +#: describe.c:3908 msgid "always" -msgstr "常ã«" +msgstr "常時" -#: describe.c:3140 +#: describe.c:3909 msgid "disabled" msgstr "無効" -#: describe.c:3141 +#: describe.c:3910 describe.c:5529 msgid "Enabled" -msgstr "有効" - -#: describe.c:3142 -msgid "Procedure" -msgstr "プロシージャ" +msgstr "有効状態" -#: describe.c:3143 +#: describe.c:3912 msgid "Tags" msgstr "ã‚¿ã‚°" -#: describe.c:3162 +#: describe.c:3931 msgid "List of event triggers" -msgstr "イベントトリガã®ä¸€è¦§" +msgstr "イベントトリガー一覧" -#: describe.c:3204 +#: describe.c:3960 msgid "Source type" -msgstr "ソースã®åž‹" +msgstr "変æ›å…ƒã®åž‹" -#: describe.c:3205 +#: describe.c:3961 msgid "Target type" -msgstr "ターゲットã®åž‹" +msgstr "変æ›å…ˆã®åž‹" -#: describe.c:3208 +#: describe.c:3992 msgid "in assignment" -msgstr "代入" +msgstr "代入時ã®ã¿" -#: describe.c:3210 +#: describe.c:3994 msgid "Implicit?" -msgstr "æš—é»™?" +msgstr "暗黙的ã«é©ç”¨ ?" -#: describe.c:3261 +#: describe.c:4049 msgid "List of casts" msgstr "キャスト一覧" -#: describe.c:3287 +#: describe.c:4077 #, c-format -msgid "The server (version %d.%d) does not support collations.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã¯ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support collations.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ç…§åˆé †åºã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" + +#: describe.c:4098 +msgid "Provider" +msgstr "プロãƒã‚¤ãƒ€ãƒ¼" -#: describe.c:3337 +#: describe.c:4133 msgid "List of collations" msgstr "ç…§åˆé †åºä¸€è¦§" -#: describe.c:3396 +#: describe.c:4192 msgid "List of schemas" msgstr "スキーマ一覧" -#: describe.c:3419 describe.c:3654 describe.c:3722 describe.c:3790 +#: describe.c:4217 describe.c:4464 describe.c:4535 describe.c:4606 #, c-format -msgid "The server (version %d.%d) does not support full text search.\n" -msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã®ã‚µãƒ¼ãƒãƒ¼ã¯å…¨æ–‡æ¤œç´¢ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support full text search.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯å…¨æ–‡æ¤œç´¢ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:3453 +#: describe.c:4252 msgid "List of text search parsers" msgstr "テキスト検索用パーサ一覧" -#: describe.c:3496 +#: describe.c:4297 #, c-format msgid "Did not find any text search parser named \"%s\".\n" -msgstr "テキスト検索用パーサ \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "テキスト検索用パーサ \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:4300 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "テキスト検索パーサãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:3571 +#: describe.c:4375 msgid "Start parse" -msgstr "パース起動" +msgstr "パース開始" -#: describe.c:3572 +#: describe.c:4376 msgid "Method" msgstr "メソッド" -#: describe.c:3576 +#: describe.c:4380 msgid "Get next token" msgstr "次ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚’å–å¾—" -#: describe.c:3578 +#: describe.c:4382 msgid "End parse" msgstr "パース終了" -#: describe.c:3580 +#: describe.c:4384 msgid "Get headline" -msgstr "見出ã—ã®å–å¾—" +msgstr "見出ã—ã‚’å–å¾—" -#: describe.c:3582 +#: describe.c:4386 msgid "Get token types" -msgstr "トークンタイプã®å–å¾—" +msgstr "トークンタイプをå–å¾—" -#: describe.c:3592 +#: describe.c:4397 #, c-format msgid "Text search parser \"%s.%s\"" -msgstr "テキスト検索用パーサ \"%s.%s\"" +msgstr "テキスト検索パーサ \"%s.%s\"" -#: describe.c:3594 +#: describe.c:4400 #, c-format msgid "Text search parser \"%s\"" -msgstr "テキスト検索用パーサ \"%s\"" +msgstr "テキスト検索パーサ \"%s\"" -#: describe.c:3613 +#: describe.c:4419 msgid "Token name" msgstr "トークンå" -#: describe.c:3624 +#: describe.c:4430 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "パーサ \"%s.%s\" ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚¿ã‚¤ãƒ—" -#: describe.c:3626 +#: describe.c:4433 #, c-format msgid "Token types for parser \"%s\"" msgstr "パーサ \"%s\" ã®ãƒˆãƒ¼ã‚¯ãƒ³ã‚¿ã‚¤ãƒ—" -#: describe.c:3676 +#: describe.c:4487 msgid "Template" msgstr "テンプレート" -#: describe.c:3677 +#: describe.c:4488 msgid "Init options" -msgstr "åˆæœŸåŒ–オプション:" +msgstr "åˆæœŸåŒ–オプション" -#: describe.c:3699 +#: describe.c:4510 msgid "List of text search dictionaries" -msgstr "テキスト検索用辞書ã®ä¸€è¦§" +msgstr "テキスト検索用辞書一覧" -#: describe.c:3739 +#: describe.c:4553 msgid "Init" msgstr "åˆæœŸåŒ–" -#: describe.c:3740 +#: describe.c:4554 msgid "Lexize" msgstr "Lex 処ç†" -#: describe.c:3767 +#: describe.c:4581 msgid "List of text search templates" -msgstr "テキスト検索用テンプレート一覧" +msgstr "テキスト検索テンプレート一覧" -#: describe.c:3824 +#: describe.c:4641 msgid "List of text search configurations" -msgstr "テキスト検索用設定一覧" +msgstr "テキスト検索設定一覧" -#: describe.c:3868 +#: describe.c:4687 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" -msgstr "テキスト検索用設定 \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "テキスト検索用設定 \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:4690 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "テキスト検索設定ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:3934 +#: describe.c:4756 msgid "Token" msgstr "トークン" -#: describe.c:3935 +#: describe.c:4757 msgid "Dictionaries" msgstr "辞書" -#: describe.c:3946 +#: describe.c:4768 #, c-format msgid "Text search configuration \"%s.%s\"" -msgstr "テキスト検索用設定 \"%s.%s\"" +msgstr "テキスト検索設定 \"%s.%s\"" -#: describe.c:3949 +#: describe.c:4771 #, c-format msgid "Text search configuration \"%s\"" -msgstr "テキスト検索用設定 \"%s\"" +msgstr "テキスト検索設定 \"%s\"" -#: describe.c:3953 +#: describe.c:4775 #, c-format msgid "" "\n" "Parser: \"%s.%s\"" msgstr "" "\n" -"パーサ: \"%s.%s\"" +"パーサ: \"%s.%s\"" -#: describe.c:3956 +#: describe.c:4778 #, c-format msgid "" "\n" "Parser: \"%s\"" msgstr "" "\n" -"パーサ:\"%s\"" +"パーサ: \"%s\"" -#: describe.c:3988 +#: describe.c:4812 #, c-format -msgid "The server (version %d.%d) does not support foreign-data wrappers.\n" -msgstr "ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã®ã‚µãƒ¼ãƒãƒ¼ã¯å¤–部データラッパーをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" - -#: describe.c:4002 -msgid "Handler" -msgstr "ãƒãƒ³ãƒ‰ãƒ©ãƒ¼" +msgid "The server (version %s) does not support foreign-data wrappers.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯å¤–部データラッパをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:4045 +#: describe.c:4870 msgid "List of foreign-data wrappers" -msgstr "外部データラッパーã®ä¸€è¦§" +msgstr "外部データラッパ一覧" -#: describe.c:4068 +#: describe.c:4895 #, c-format -msgid "The server (version %d.%d) does not support foreign servers.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã¯å¤–部サーãƒãƒ¼ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support foreign servers.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯å¤–部サーãƒã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:4080 +#: describe.c:4908 msgid "Foreign-data wrapper" -msgstr "外部データラッパー" +msgstr "外部データラッパ" -#: describe.c:4098 describe.c:4293 +#: describe.c:4926 describe.c:5131 msgid "Version" msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: describe.c:4124 +#: describe.c:4952 msgid "List of foreign servers" -msgstr "外部サーãƒãƒ¼ä¸€è¦§" +msgstr "外部サーãƒä¸€è¦§" -#: describe.c:4147 +#: describe.c:4977 #, c-format -msgid "The server (version %d.%d) does not support user mappings.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã¯ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ—をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support user mappings.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:4156 describe.c:4217 +#: describe.c:4987 describe.c:5051 msgid "Server" -msgstr "サーãƒãƒ¼" +msgstr "サーãƒ" -#: describe.c:4157 +#: describe.c:4988 msgid "User name" msgstr "ユーザå" -#: describe.c:4182 +#: describe.c:5013 msgid "List of user mappings" -msgstr "ユーザマッピングã®ä¸€è¦§" +msgstr "ユーザマッピング一覧" -#: describe.c:4205 +#: describe.c:5038 #, c-format -msgid "The server (version %d.%d) does not support foreign tables.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼(ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d)ã¯å¤–部テーブルをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support foreign tables.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯å¤–部テーブルをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:4256 +#: describe.c:5091 msgid "List of foreign tables" msgstr "外部テーブル一覧" -#: describe.c:4279 describe.c:4333 +#: describe.c:5116 describe.c:5173 #, c-format -msgid "The server (version %d.%d) does not support extensions.\n" -msgstr "ã“ã®ã‚µãƒ¼ãƒãƒ¼ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (%d.%d) ã¯æ‹¡å¼µã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "The server (version %s) does not support extensions.\n" +msgstr "ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯æ‹¡å¼µã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" -#: describe.c:4310 +#: describe.c:5148 msgid "List of installed extensions" -msgstr "インストール済ã¿ã®æ‹¡å¼µã®ä¸€è¦§" +msgstr "インストール済ã¿ã®æ‹¡å¼µä¸€è¦§" -#: describe.c:4360 +#: describe.c:5201 #, c-format msgid "Did not find any extension named \"%s\".\n" -msgstr "\"%s\" ã¨ã„ã†åå‰ã®æ‹¡å¼µãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "\"%s\" ã¨ã„ã†åå‰ã®æ‹¡å¼µãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:4363 +#: describe.c:5204 #, c-format msgid "Did not find any extensions.\n" -msgstr "æ‹¡å¼µãŒã¾ã£ãŸã見ã¤ã‹ã‚Šã¾ã›ã‚“。\n" +msgstr "æ‹¡å¼µãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: describe.c:4407 -msgid "Object Description" +#: describe.c:5248 +msgid "Object description" msgstr "オブジェクトã®èª¬æ˜Ž" -#: describe.c:4416 +#: describe.c:5258 #, c-format msgid "Objects in extension \"%s\"" -msgstr "æ‹¡å¼µ\"%s\"内ã®ã‚ªãƒ–ジェクト" +msgstr "æ‹¡å¼µ \"%s\" 内ã®ã‚ªãƒ–ジェクト" + +#: describe.c:5287 describe.c:5358 +#, c-format +msgid "The server (version %s) does not support publications.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ãƒ‘ブリケーションをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" + +#: describe.c:5304 describe.c:5430 +msgid "All tables" +msgstr "全テーブル" + +#: describe.c:5305 describe.c:5431 +msgid "Inserts" +msgstr "Insertæ–‡" + +#: describe.c:5306 describe.c:5432 +msgid "Updates" +msgstr "Updateæ–‡" + +#: describe.c:5307 describe.c:5433 +msgid "Deletes" +msgstr "Deleteæ–‡" + +#: describe.c:5311 describe.c:5435 +msgid "Truncates" +msgstr "Truncateæ–‡" + +#: describe.c:5328 +msgid "List of publications" +msgstr "パブリケーション一覧" + +#: describe.c:5396 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "\"%s\" ã¨ã„ã†åå‰ã®ãƒ‘ブリケーションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:5399 +#, c-format +msgid "Did not find any publications.\n" +msgstr "パブリケーションãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" + +#: describe.c:5426 +#, c-format +msgid "Publication %s" +msgstr "パブリケーション %s" + +#: describe.c:5470 +msgid "Tables:" +msgstr "テーブル:" + +#: describe.c:5514 +#, c-format +msgid "The server (version %s) does not support subscriptions.\n" +msgstr "" +"ã“ã®ã‚µãƒ¼ãƒ (ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %s) ã¯ã‚µãƒ–スクリプションをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" + +#: describe.c:5530 +msgid "Publication" +msgstr "パブリケーション" + +#: describe.c:5537 +msgid "Synchronous commit" +msgstr "åŒæœŸã‚³ãƒŸãƒƒãƒˆ" + +#: describe.c:5538 +msgid "Conninfo" +msgstr "接続情報" + +#: describe.c:5560 +msgid "List of subscriptions" +msgstr "サブスクリプション一覧" #: help.c:62 #, c-format msgid "%s\n" msgstr "%s\n" -#: help.c:67 +#: help.c:73 #, c-format msgid "" "psql is the PostgreSQL interactive terminal.\n" "\n" msgstr "" -"psql 㯠PostgreSQL ã®ä¼šè©±åž‹ã‚¿ãƒ¼ãƒŸãƒŠãƒ«ã§ã™ã€‚\n" +"psql 㯠PostgreSQL ã®å¯¾è©±åž‹ã‚¿ãƒ¼ãƒŸãƒŠãƒ«ã§ã™ã€‚\n" "\n" -#: help.c:68 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" -msgstr "使用方法:\n" +msgstr "ä½¿ã„æ–¹:\n" -#: help.c:69 +#: help.c:75 #, c-format msgid "" " psql [OPTION]... [DBNAME [USERNAME]]\n" @@ -1698,194 +2200,247 @@ msgstr "" " psql [オプション]... [データベースå [ユーザå]]\n" "\n" -#: help.c:71 +#: help.c:77 #, c-format msgid "General options:\n" -msgstr "一般的ãªã‚ªãƒ—ション:\n" +msgstr "一般的ãªã‚ªãƒ—ション:\n" -#: help.c:76 +#: help.c:82 #, c-format -msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" -msgstr " -c, --command=コマンド (SQLã¾ãŸã¯å†…部ã®)å˜ä¸€ã‚³ãƒžãƒ³ãƒ‰ã‚’一ã¤ã ã‘実行ã—ã¦çµ‚了\n" +msgid "" +" -c, --command=COMMAND run only single command (SQL or internal) and " +"exit\n" +msgstr "" +" -c, --command=コマンド å˜ä¸€ã®ï¼ˆSQLã¾ãŸã¯å†…部)コマンドを一ã¤ã ã‘実行ã—ã¦" +"終了\n" -#: help.c:77 +#: help.c:83 #, c-format -msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" -msgstr " -d, --dbname=DBå æŽ¥ç¶šã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹åを指定(デフォルト: \"%s\")\n" +msgid "" +" -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr "" +" -d, --dbname=DBå æŽ¥ç¶šã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å (デフォルト: \"%s\")\n" -#: help.c:78 +#: help.c:84 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" -msgstr " -f, --file=ファイルå ファイルã‹ã‚‰ã‚³ãƒžãƒ³ãƒ‰ã‚’読ã¿è¾¼ã‚“ã§å®Ÿè¡Œå¾Œã€çµ‚了\n" +msgstr "" +" -f, --file=FILENAME ファイルã‹ã‚‰ã‚³ãƒžãƒ³ãƒ‰ã‚’読ã¿è¾¼ã‚“ã§å®Ÿè¡Œå¾Œã€çµ‚了\n" -#: help.c:79 +#: help.c:85 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr " -l(エル), --list 使用å¯èƒ½ãªãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ä¸€è¦§ã‚’表示ã—ã¦çµ‚了\n" -#: help.c:80 +#: help.c:86 #, c-format msgid "" " -v, --set=, --variable=NAME=VALUE\n" " set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" msgstr "" " -v, --set=, --variable=åå‰=値\n" " psql 変数 'åå‰' ã« '値' をセット\n" +" (例: -v ON_ERROR_STOP=1)\n" -#: help.c:82 +#: help.c:89 #, c-format msgid " -V, --version output version information, then exit\n" -msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を表示ã—ã¦çµ‚了\n" -#: help.c:83 +#: help.c:90 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" -msgstr " -X, --no-psqlrc åˆæœŸåŒ–ファイル (~/.psqlrc) を読ã¿ã“ã¾ãªã„\n" +msgstr " -X, --no-psqlrc åˆæœŸåŒ–ファイル (~/.psqlrc) を読ã¿è¾¼ã¾ãªã„\n" -#: help.c:84 +#: help.c:91 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" -" execute as a single transaction (if non-interactive)\n" +" execute as a single transaction (if non-" +"interactive)\n" msgstr "" -" -1(æ•°å­—ã®ï¼‘), --single-transaction\n" -" å˜ä¸€ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¨ã—ã¦å®Ÿè¡Œ(対話å¼ã§ãªã„å ´åˆ)\n" +" -1 (æ•°å­—ã®1), --single-transaction\n" +" (対話形å¼ã§ãªã„å ´åˆ)å˜ä¸€ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¨ã—ã¦å®Ÿ" +"行\n" -#: help.c:86 +#: help.c:93 #, c-format -msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦çµ‚了\n" -#: help.c:88 +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr "" +" --help=commands ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚³ãƒžãƒ³ãƒ‰ã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables 特殊変数ã®ä¸€è¦§ã‚’表示ã—ã¦çµ‚了\n" + +#: help.c:97 #, c-format msgid "" "\n" "Input and output options:\n" msgstr "" "\n" -"入出力オプション:\n" +"入出力オプション:\n" -#: help.c:89 +#: help.c:98 #, c-format msgid " -a, --echo-all echo all input from script\n" -msgstr " -a, --echo-all スクリプトã‹ã‚‰ã®ã™ã¹ã¦ã®å…¥åŠ›ã‚’è¡¨ç¤º\n" +msgstr " -a, --echo-all スクリプトã‹ã‚‰èª­ã¿è¾¼ã‚“ã å…¥åŠ›ã‚’ã™ã¹ã¦è¡¨ç¤º\n" -#: help.c:90 +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -b, --echo-errors 失敗ã—ãŸã‚³ãƒžãƒ³ãƒ‰ã‚’表示\n" + +#: help.c:100 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" -msgstr " -e, --echo-queries サーãƒãƒ¼ã¸é€ä¿¡ã—ãŸã‚³ãƒžãƒ³ãƒ‰ã‚’表示\n" +msgstr " -e, --echo-queries サーãƒã¸é€ä¿¡ã—ãŸã‚³ãƒžãƒ³ãƒ‰ã‚’表示\n" -#: help.c:91 +#: help.c:101 #, c-format -msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgid "" +" -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden 内部コマンドãŒç”Ÿæˆã—ãŸå•ã„åˆã‚ã›ã‚’表示\n" -#: help.c:92 +#: help.c:102 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" -msgstr " -L, --log-file=ファイルå ã‚»ãƒƒã‚·ãƒ§ãƒ³ãƒ­ã‚°ã‚’ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込む\n" +msgstr " -L, --log-file=FILENAME ã‚»ãƒƒã‚·ãƒ§ãƒ³ãƒ­ã‚°ã‚’ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã込む\n" -#: help.c:93 +#: help.c:103 #, c-format -msgid " -n, --no-readline disable enhanced command line editing (readline)\n" -msgstr " -n, --no-readline 拡張コマンドライン編集機能(readline)を無効ã«ã™ã‚‹\n" +msgid "" +" -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr "" +" -n, --no-readline 拡張コマンドライン編集機能(readline)を無効ã«ã™ã‚‹\n" -#: help.c:94 +#: help.c:104 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" -msgstr " -o, --output=ファイルå å•ã„åˆã‚ã›çµæžœã‚’ファイル(ã¾ãŸã¯ |パイプ)ã«é€ã‚‹\n" +msgstr "" +" -o, --output=FILENAME å•ã„åˆã‚ã›ã®çµæžœã‚’ファイル (ã¾ãŸã¯ |パイプ)ã«é€" +"ã‚‹\n" -#: help.c:95 +#: help.c:105 #, c-format -msgid " -q, --quiet run quietly (no messages, only query output)\n" -msgstr " -q, --quiet é™ã‹ã«å®Ÿè¡Œ(メッセージãªã—ã§ã€å•ã„åˆã‚ã›ã®å‡ºåŠ›ã®ã¿)\n" +msgid "" +" -q, --quiet run quietly (no messages, only query output)\n" +msgstr "" +" -q, --quiet é™ã‹ã«å®Ÿè¡Œ (メッセージãªã—ã§ã€å•ã„åˆã‚ã›ã®å‡ºåŠ›ã®" +"ã¿)\n" -#: help.c:96 +#: help.c:106 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" -msgstr " -s, --single-step シングルステップモード(å„å•ã„åˆã‚ã›ã”ã¨ã«ç¢ºèª)\n" +msgstr "" +" -s, --single-step シングルステップモード (å„å•ã„åˆã‚ã›ã”ã¨ã«ç¢ºèª)\n" -#: help.c:97 +#: help.c:107 #, c-format -msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" -msgstr " -S, --single-line å˜ä¸€è¡Œãƒ¢ãƒ¼ãƒ‰(行末を SQL コマンドã®çµ‚了ã¨ã¿ãªã™)\n" +msgid "" +" -S, --single-line single-line mode (end of line terminates SQL " +"command)\n" +msgstr " -S, --single-line å˜ä¸€è¡Œãƒ¢ãƒ¼ãƒ‰ (行末㧠SQL コマンドを終端)\n" -#: help.c:99 +#: help.c:109 #, c-format msgid "" "\n" "Output format options:\n" msgstr "" "\n" -"出力フォーマットオプション:\n" +"出力フォーマットã®ã‚ªãƒ—ション\n" -#: help.c:100 +#: help.c:110 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align æ¡æƒãˆãªã—ã®ãƒ†ãƒ¼ãƒ–ル出力モード\n" -#: help.c:101 +#: help.c:111 #, c-format msgid "" " -F, --field-separator=STRING\n" -" field separator for unaligned output (default: \"%s\")\n" +" field separator for unaligned output (default: " +"\"%s\")\n" msgstr "" " -F, --field-separator=文字列\n" -" æ¡æƒãˆãªã—ã®å‡ºåŠ›ã§ã®ãƒ•ィールド区切り文字(デフォルト: \"%s\")\n" +" æ¡æƒãˆãªã—出力時ã®ãƒ•ィールド区切り文字\n" +" (デフォルト: \"%s\")\n" -#: help.c:104 +#: help.c:114 #, c-format msgid " -H, --html HTML table output mode\n" msgstr " -H, --html HTML テーブル出力モード\n" -#: help.c:105 +#: help.c:115 #, c-format -msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" -msgstr " -P, --pset=変数[=値] 表示オプション '変数' ã‚’ '値' ã«ã‚»ãƒƒãƒˆ (\\pset コマンドをå‚ç…§)\n" +msgid "" +" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " +"command)\n" +msgstr "" +" -P, --pset=変数[=値] 表示オプション '変数' ã‚’ '値' ã«ã‚»ãƒƒãƒˆ\n" +" (\\pset コマンドをå‚ç…§)\n" -#: help.c:106 +#: help.c:116 #, c-format msgid "" " -R, --record-separator=STRING\n" -" record separator for unaligned output (default: newline)\n" +" record separator for unaligned output (default: " +"newline)\n" msgstr "" " -R, --record-separator=文字列\n" -" æ¡æƒãˆãªã—ã®å‡ºåŠ›ã§ã®ãƒ¬ã‚³ãƒ¼ãƒ‰åŒºåˆ‡ã‚Šæ–‡å­—(デフォルト:改行)\n" +" æ¡æƒãˆãªã—出力ã«ãŠã‘るレコード区切り文字\n" +" (デフォルト: 改行)\n" -#: help.c:108 +#: help.c:118 #, c-format msgid " -t, --tuples-only print rows only\n" msgstr " -t, --tuples-only 行ã®ã¿ã‚’表示\n" -#: help.c:109 +#: help.c:119 #, c-format -msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" -msgstr " -T, --table-attr=TEXT HTMLテーブルã®ã‚¿ã‚°å±žæ€§ã‚’セット(width, borderç­‰)\n" +msgid "" +" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " +"border)\n" +msgstr "" +" -T, --table-attr=TEXT HTMLテーブルã®ã‚¿ã‚°å±žæ€§ã‚’セット (width, borderç­‰)\n" -#: help.c:110 +#: help.c:120 #, c-format msgid " -x, --expanded turn on expanded table output\n" -msgstr " -x, --expanded 拡張テーブル出力を有効ã«ã™ã‚‹\n" +msgstr " -x, --expanded 拡張テーブル出力ã«åˆ‡ã‚Šæ›¿ãˆã‚‹\n" -#: help.c:111 +#: help.c:121 #, c-format msgid "" " -z, --field-separator-zero\n" -" set field separator for unaligned output to zero byte\n" +" set field separator for unaligned output to zero " +"byte\n" msgstr "" " -z, --field-separator-zero\n" -" æ¡æƒãˆãªã—ã®å‡ºåŠ›ã§ã®ãƒ•ィールド区切り文字をゼロãƒã‚¤ãƒˆã«è¨­å®š\n" +" æ¡æƒãˆãªã—出力ã®ãƒ•ィールド区切りをãƒã‚¤ãƒˆå€¤ã®0ã«è¨­" +"定\n" -#: help.c:113 +#: help.c:123 #, c-format msgid "" " -0, --record-separator-zero\n" -" set record separator for unaligned output to zero byte\n" +" set record separator for unaligned output to zero " +"byte\n" msgstr "" " -0, --record-separator-zero\n" -" æ¡æƒãˆãªã—ã®å‡ºåŠ›ã§ã®ãƒ¬ã‚³ãƒ¼ãƒ‰åŒºåˆ‡ã‚Šæ–‡å­—をゼロãƒã‚¤ãƒˆã«è¨­å®š\n" +" æ¡æƒãˆãªã—出力ã®ãƒ¬ã‚³ãƒ¼ãƒ‰åŒºåˆ‡ã‚Šã‚’ãƒã‚¤ãƒˆå€¤ã®0ã«è¨­" +"定\n" -#: help.c:116 +#: help.c:126 #, c-format msgid "" "\n" @@ -1894,511 +2449,723 @@ msgstr "" "\n" "接続オプション:\n" -#: help.c:119 +#: help.c:129 #, c-format -msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" -msgstr " -h, --host=ホストå データベースサーãƒãƒ¼ã®ãƒ›ã‚¹ãƒˆã¾ãŸã¯ã‚½ã‚±ãƒƒãƒˆã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª(デフォルト: \"%s\")\n" +msgid "" +" -h, --host=HOSTNAME database server host or socket directory " +"(default: \"%s\")\n" +msgstr "" +" -h, --host=HOSTNAME データベースサーãƒã®ãƒ›ã‚¹ãƒˆã¾ãŸã¯ã‚½ã‚±ãƒƒãƒˆã®\n" +" ディレクトリ(デフォルト: \"%s\")\n" -#: help.c:120 +#: help.c:130 msgid "local socket" msgstr "ローカルソケット" -#: help.c:123 +#: help.c:133 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" -msgstr " -p, --port=ãƒãƒ¼ãƒˆç•ªå· データベースサーãƒãƒ¼ã®ãƒãƒ¼ãƒˆç•ªå·(デフォルト: \"%s\")\n" +msgstr "" +" -p, --port=PORT データベースサーãƒã®ãƒãƒ¼ãƒˆç•ªå·(デフォルト: \"%s" +"\")\n" -#: help.c:129 +#: help.c:139 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" -msgstr " -U, --username=ユーザーå データベースã®ãƒ¦ãƒ¼ã‚¶å(デフォルト: \"%s\")\n" +msgstr "" +" -U, --username=USERNAME データベースã®ãƒ¦ãƒ¼ã‚¶å (デフォルト: \"%s\")\n" -#: help.c:130 +#: help.c:140 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password ãƒ‘ã‚¹ãƒ¯ãƒ¼ãƒ‰å…¥åŠ›ã‚’è¦æ±‚ã—ãªã„\n" -#: help.c:131 +#: help.c:141 #, c-format -msgid " -W, --password force password prompt (should happen automatically)\n" +msgid "" +" -W, --password force password prompt (should happen " +"automatically)\n" msgstr "" -" -W, --password パスワードプロンプトを強制表示ã™ã‚‹\n" -" (本æ¥ã¯è‡ªå‹•çš„ã«è¡¨ç¤ºã•れるã¯ãšã§ã™ï¼‰\n" +" -W, --password パスワードプロンプトã®å¼·åˆ¶è¡¨ç¤º(本æ¥ã¯è‡ªå‹•çš„ã«è¡¨" +"示)\n" -#: help.c:133 +#: help.c:143 #, c-format msgid "" "\n" -"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help" +"\" (for SQL\n" "commands) from within psql, or consult the psql section in the PostgreSQL\n" "documentation.\n" "\n" msgstr "" "\n" -"詳細㯠psql ã®ä¸­ã§ \"\\?\" (内部コマンドã®å ´åˆ) ã¾ãŸã¯ \"\\help\"\n" -"(SQL コマンドã®å ´åˆ) をタイプã™ã‚‹ã‹ã€PostgreSQL ドキュメント㮠psql ã®\n" +"詳細㯠psql ã®ä¸­ã§ \"\\?\" (内部コマンドã®å ´åˆ)ã¾ãŸã¯ \"\\help\"\n" +"(SQL コマンドã®å ´åˆ)をタイプã™ã‚‹ã‹ã€ã¾ãŸã¯ PostgreSQL ドキュメント中㮠psql " +"ã®\n" "セクションをå‚ç…§ã®ã“ã¨ã€‚\n" "\n" -#: help.c:136 +#: help.c:146 #, c-format msgid "Report bugs to .\n" -msgstr "ä¸å…·åˆã¯ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" +msgstr "" +"ä¸å…·åˆã‚’見ã¤ã‘ãŸå ´åˆã€ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„。\n" -#: help.c:157 +#: help.c:172 #, c-format msgid "General\n" msgstr "一般\n" -#: help.c:158 -#, c-format -msgid " \\copyright show PostgreSQL usage and distribution terms\n" -msgstr " \\copyright PostgreSQL ã®ä½¿ã„æ–¹ã¨é…布æ¡ä»¶ã‚’表示\n" - -#: help.c:159 -#, c-format -msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" -msgstr " \\g [ファイル] ã¾ãŸã¯ ';' å•ã„åˆã‚ã›ã‚’実行(ã—ã€çµæžœã‚’ファイルã¾ãŸã¯ |パイプ ã¸æ›¸ã出ã™)\n" - -#: help.c:160 -#, c-format -msgid " \\gset [PREFIX] execute query and store results in psql variables\n" -msgstr "\\gset [PREFIX] å•ã„åˆã‚ã›ã‚’実行ã—çµæžœã‚’psqlå¤‰æ•°ã«æ ¼ç´\n" - -#: help.c:161 -#, c-format -msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" -msgstr " \\h [åå‰] SQL ã‚³ãƒžãƒ³ãƒ‰ã®æ–‡æ³•ヘルプã€* ã§å…¨ã‚³ãƒžãƒ³ãƒ‰\n" - -#: help.c:162 -#, c-format -msgid " \\q quit psql\n" -msgstr " \\q psql を終了ã™ã‚‹\n" - -#: help.c:163 -#, c-format -msgid " \\watch [SEC] execute query every SEC seconds\n" -msgstr " \\watch [SEC] SEC秒毎ã«å•ã„åˆã‚ã›ã‚’実行ã™ã‚‹\n" - -#: help.c:166 -#, c-format -msgid "Query Buffer\n" -msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡\n" - -#: help.c:167 -#, c-format -msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" -msgstr " \\e [ファイル] [行番å·] ç¾åœ¨ã®å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡(やファイル)を外部エディタã§ç·¨é›†ã™ã‚‹\n" - -#: help.c:168 +#: help.c:173 #, c-format -msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" -msgstr " \\ef [関数å [行番å·]] 関数定義を外部エディタã§ç·¨é›†ã™ã‚‹\n" - -#: help.c:169 -#, c-format -msgid " \\p show the contents of the query buffer\n" -msgstr " \\p å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ã®å†…容を表示ã™ã‚‹\n" +msgid "" +" \\copyright show PostgreSQL usage and distribution terms\n" +msgstr "" +" \\copyright PostgreSQL ã®ä½¿ã„æ–¹ã¨é…布æ¡ä»¶ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:170 +#: help.c:174 #, c-format -msgid " \\r reset (clear) the query buffer\n" -msgstr " \\r å•ã„åˆã‚ã›ãƒãƒƒãƒ•ァをリセット(クリア)ã™ã‚‹\n" +msgid "" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [列数] å•ã„åˆã‚ã›ã‚’実行ã—ã€çµæžœã‚’クロスタブã«è¡¨ç¤ºã—ã¾" +"ã™ã€‚\n" -#: help.c:172 +#: help.c:175 #, c-format -msgid " \\s [FILE] display history or save it to file\n" -msgstr " \\s [ファイル] ヒストリを表示ã¾ãŸã¯ãƒ•ァイルã«ä¿å­˜ã™ã‚‹\n" +msgid "" +" \\errverbose show most recent error message at maximum " +"verbosity\n" +msgstr "" +" \\errverbose 最後ã«ç™ºç”Ÿã—ãŸã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’冗長性最大ã§è¡¨ç¤ºã—" +"ã¾ã™ã€‚\n" -#: help.c:174 +#: help.c:176 #, c-format -msgid " \\w FILE write query buffer to file\n" -msgstr " \\w ファイル å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ã®å†…å®¹ã‚’ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã™\n" +msgid "" +" \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +msgstr "" +" \\g [ファイル] ã¾ãŸã¯ ; å•ã„åˆã‚ã›ã‚’実行(ã—ã€çµæžœã‚’ファイルã¾ãŸã¯ |パイプ " +"ã¸å‡ºåŠ›ï¼‰ã—ã¾ã™ã€‚\n" #: help.c:177 #, c-format -msgid "Input/Output\n" -msgstr "入出力\n" +msgid "" +" \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc å•ã„åˆã‚ã›ã‚’実行ã›ãšã«çµæžœã®èª¬æ˜Žã‚’行ã„ã¾ã™\n" #: help.c:178 #, c-format -msgid " \\copy ... perform SQL COPY with data stream to the client host\n" -msgstr " \\copy ... クライアントホストã«å¯¾ã—ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‚’使ã£ã¦SQLコピーを行ã†\n" +msgid "" +" \\gexec execute query, then execute each value in its " +"result\n" +msgstr "" +" \\gexec å•ã„åˆã‚ã›ã‚’実行ã—ã€çµæžœã®ä¸­ã®å€‹ã€…ã®å€¤ã‚’実行ã—ã¾" +"ã™ã€‚\n" #: help.c:179 #, c-format -msgid " \\echo [STRING] write string to standard output\n" -msgstr " \\echo [文字列] æ–‡å­—åˆ—ã‚’æ¨™æº–å‡ºåŠ›ã«æ›¸ã出ã™\n" +msgid "" +" \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr "" +" \\gset [PREFIX] å•ã„åˆã‚ã›ã‚’実行ã—ã¦çµæžœã‚’ psql å¤‰æ•°ã«æ ¼ç´ã—ã¾" +"ã™ã€‚\n" #: help.c:180 #, c-format -msgid " \\i FILE execute commands from file\n" -msgstr " \\i ファイル ファイルã‹ã‚‰ã‚³ãƒžãƒ³ãƒ‰ã‚’読ã¿è¾¼ã‚“ã§å®Ÿè¡Œã™ã‚‹\n" +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr "" +" \\gx [ファイルå] \\g ã¨åŒã˜ã§ã™ãŒã€æ‹¡å¼µå‡ºåŠ›ãƒ¢ãƒ¼ãƒ‰ã§å®Ÿè¡Œã—ã¾ã™ã€‚\n" #: help.c:181 #, c-format -msgid " \\ir FILE as \\i, but relative to location of current script\n" -msgstr " \\ir ファイル \\iã¨åŒã˜ã€‚ãŸã ã—ç¾åœ¨ã®ã‚¹ã‚¯ãƒªãƒ—トã®å ´æ‰€ã‹ã‚‰ã®ç›¸å¯¾ãƒ‘ス\n" +msgid " \\q quit psql\n" +msgstr " \\q psql を終了ã—ã¾ã™ã€‚\n" #: help.c:182 #, c-format -msgid " \\o [FILE] send all query results to file or |pipe\n" -msgstr " \\o [ファイル] ã™ã¹ã¦ã®å•ã„åˆã‚ã›ã®çµæžœã‚’ファイルã¾ãŸã¯ |パイプ ã¸é€ã‚‹\n" - -#: help.c:183 -#, c-format -msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" -msgstr " \\qecho [文字列] 文字列をå•ã„åˆã‚ã›å‡ºåŠ›ã‚¹ãƒˆãƒªãƒ¼ãƒ ã«å‡ºåŠ›(\\o ã‚’å‚ç…§)\n" +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [ç§’æ•°] 指定ã—ãŸç§’æ•°ã”ã¨ã«å•ã„åˆã‚ã›ã‚’実行ã—ã¾ã™ã€‚\n" -#: help.c:186 +#: help.c:185 #, c-format -msgid "Informational\n" -msgstr "情報\n" +msgid "Help\n" +msgstr "ヘルプ\n" #: help.c:187 #, c-format -msgid " (options: S = show system objects, + = additional detail)\n" -msgstr " (修飾å­: S = システムオブジェクトを表示 + = 付加情報)\n" +msgid " \\? [commands] show help on backslash commands\n" +msgstr "" +" \\? [コマンド] ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚³ãƒžãƒ³ãƒ‰ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" #: help.c:188 #, c-format -msgid " \\d[S+] list tables, views, and sequences\n" -msgstr " \\d[S+] テーブルã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid " \\? options show help on psql command-line options\n" +msgstr "" +" \\? オプション psql ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ãƒ»ã‚ªãƒ—ションã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾" +"ã™ã€‚\n" #: help.c:189 #, c-format -msgid " \\d[S+] NAME describe table, view, sequence, or index\n" -msgstr " \\d[S+] åå‰ ãƒ†ãƒ¼ãƒ–ãƒ«ã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®èª¬æ˜Žã‚’表示ã™ã‚‹\n" +msgid " \\? variables show help on special variables\n" +msgstr " \\? 変数å 特殊変数ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" #: help.c:190 #, c-format -msgid " \\da[S] [PATTERN] list aggregates\n" -msgstr " \\da[S] [パターン] 集約関数ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" - -#: help.c:191 -#, c-format -msgid " \\db[+] [PATTERN] list tablespaces\n" -msgstr " \\db[+] [パターン] テーブルスペースã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" - -#: help.c:192 -#, c-format -msgid " \\dc[S+] [PATTERN] list conversions\n" -msgstr " \\dc[S+] [パターン] 変æ›ãƒ«ãƒ¼ãƒ«ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid "" +" \\h [NAME] help on syntax of SQL commands, * for all " +"commands\n" +msgstr "" +" \\h [åå‰] SQL ã‚³ãƒžãƒ³ãƒ‰ã®æ–‡æ³•ヘルプã®è¡¨ç¤ºã€‚* ã§å…¨ã‚³ãƒžãƒ³ãƒ‰ã‚’表" +"示ã—ã¾ã™ã€‚\n" #: help.c:193 #, c-format -msgid " \\dC[+] [PATTERN] list casts\n" -msgstr " \\dC[+] [パターン] キャストã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid "Query Buffer\n" +msgstr "å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡\n" #: help.c:194 #, c-format -msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" -msgstr " \\dd[S] [パターン] ä»–ã§ã¯è¡¨ç¤ºã•れãªã„オブジェクトã®èª¬æ˜Žã‚’表示ã™ã‚‹\n" +msgid "" +" \\e [FILE] [LINE] edit the query buffer (or file) with external " +"editor\n" +msgstr "" +" \\e [ファイル] [行番å·] ç¾åœ¨ã®å•ã„åˆã‚ã›ãƒãƒƒãƒ•ァ(やファイル)を外部エディ" +"ã‚¿ã§ç·¨é›†ã—ã¾ã™ã€‚\n" #: help.c:195 #, c-format -msgid " \\ddp [PATTERN] list default privileges\n" -msgstr " \\ddp [パターン] デフォルト権é™ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid "" +" \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [関数å [行番å·]] 関数定義を外部エディタã§ç·¨é›†ã—ã¾ã™ã€‚\n" #: help.c:196 #, c-format -msgid " \\dD[S+] [PATTERN] list domains\n" -msgstr " \\dD[S+] [パターン] ドメインã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ef [ビューå [行番å·]] ビュー定義を外部エディタã§ç·¨é›†ã—ã¾ã™ã€‚\n" #: help.c:197 #, c-format -msgid " \\det[+] [PATTERN] list foreign tables\n" -msgstr " \\det[+] [パターン] 外部テーブルã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p å•ã„åˆã‚ã›ãƒãƒƒãƒ•ã‚¡ã®ä¸­èº«ã‚’表示ã—ã¾ã™ã€‚\n" #: help.c:198 #, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr "" +" \\r å•ã„åˆã‚ã›ãƒãƒƒãƒ•ァをリセット(クリア)ã—ã¾ã™ã€‚\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [ファイル] ヒストリを表示ã¾ãŸã¯ãƒ•ァイルã«ä¿å­˜ã—ã¾ã™ã€‚\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w ファイル å•ã„åˆã‚ã›ã®ä¸­èº«ã‚’ファイルã«ä¿å­˜ã—ã¾ã™ã€‚\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "入出力\n" + +#: help.c:206 +#, c-format +msgid "" +" \\copy ... perform SQL COPY with data stream to the client " +"host\n" +msgstr "" +" \\copy ... クライアントホストã«å¯¾ã—ã€ãƒ‡ãƒ¼ã‚¿ã‚¹ãƒˆãƒªãƒ¼ãƒ ã‚’使ã£ã¦ " +"SQL コピーを行ã„ã¾ã™ã€‚\n" + +#: help.c:207 +#, c-format +msgid " \\echo [STRING] write string to standard output\n" +msgstr " \\echo [文字列] æ–‡å­—åˆ—ã‚’æ¨™æº–å‡ºåŠ›ã«æ›¸ã出ã—ã¾ã™ã€‚\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr "" +" \\i ファイル ファイルã‹ã‚‰ã‚³ãƒžãƒ³ãƒ‰ã‚’読ã¿è¾¼ã‚“ã§å®Ÿè¡Œã—ã¾ã™ã€‚\n" + +#: help.c:209 +#, c-format +msgid "" +" \\ir FILE as \\i, but relative to location of current " +"script\n" +msgstr "" +" \\ir ファイル \\i ã¨åŒã˜ã€‚ãŸã ã—ç¾åœ¨ã®ã‚¹ã‚¯ãƒªãƒ—トä½ç½®ã‹ã‚‰ã®ç›¸å¯¾ãƒ‘" +"ã‚¹ã§æŒ‡å®šã—ã¾ã™ã€‚\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr "" +" \\o [ファイル] å•ã„åˆã‚ã›çµæžœã‚’ã™ã¹ã¦ãƒ•ァイルã¾ãŸã¯ |パイプ ã¸é€ã‚Š" +"ã¾ã™ã€‚\n" + +#: help.c:211 +#, c-format +msgid "" +" \\qecho [STRING] write string to query output stream (see \\o)\n" +msgstr "" +" \\qecho [文字列] 文字列をå•ã„åˆã‚ã›å‡ºåŠ›ã‚¹ãƒˆãƒªãƒ¼ãƒ ã«å‡ºåŠ›ï¼ˆ\\o ã‚’å‚" +"照)ã—ã¾ã™ã€‚\n" + +#: help.c:214 +#, c-format +msgid "Conditional\n" +msgstr "æ¡ä»¶åˆ†å²\n" + +#: help.c:215 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR æ¡ä»¶ãƒ–ロックã®é–‹å§‹\n" + +#: help.c:216 +#, c-format +msgid "" +" \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR ç¾åœ¨ã®æ¡ä»¶ãƒ–ロック内ã®ä»£æ›¿æ¡ä»¶\n" + +#: help.c:217 +#, c-format +msgid "" +" \\else final alternative within current conditional " +"block\n" +msgstr " \\else ç¾åœ¨ã®æ¡ä»¶ãƒ–ロックã«ãŠã‘る最後ã®é¸æŠžè‚¢\n" + +#: help.c:218 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif æ¡ä»¶ãƒ–ロックã®çµ‚了\n" + +#: help.c:221 +#, c-format +msgid "Informational\n" +msgstr "情報表示\n" + +#: help.c:222 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (オプション:S = システムオブジェクトã®è¡¨ç¤º, + = 詳細表示)\n" + +#: help.c:223 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr "" +" \\d[S+] テーブルã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr "" +" \\d[S+] åå‰ ãƒ†ãƒ¼ãƒ–ãƒ«ã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã€ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã®èª¬æ˜Žã‚’" +"表示ã—ã¾ã™ã€‚\n" + +#: help.c:225 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [パターン] 集約関数一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:226 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [パターン] アクセスメソッド一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:227 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [パターン] テーブル空間一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:228 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [パターン] 符å·åŒ–æ–¹å¼ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" + +#: help.c:229 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [パターン] キャスト一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:230 +#, c-format +msgid "" +" \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr "" +" \\dd[S] [パターン] ä»–ã§ã¯è¡¨ç¤ºã•れãªã„オブジェクトã®èª¬æ˜Žã‚’表示ã—ã¾" +"ã™ã€‚\n" + +#: help.c:231 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [パターン] ドメイン一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:232 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [パターン] デフォルト権é™ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" + +#: help.c:233 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [パターン] 外部テーブル一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:234 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [パターン] 外部テーブル一覧を表示ã—ã¾ã™ã€‚\n" + +#: help.c:235 +#, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" -msgstr " \\des[+] [パターン] 外部サーãƒãƒ¼ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\des[+] [パターン] 外部サーãƒä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:199 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" -msgstr " \\deu[+] [パターン] ユーザマッピングã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\deu[+] [パターン] ユーザマッピング一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:200 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" -msgstr " \\dew[+] [パターン] 外部データラッパーã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dew[+] [パターン] 外部データラッパ一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:201 +#: help.c:238 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [パターン] 関数(集約/通常/トリガー/ウィンドウã®ã¿ï¼‰ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid "" +" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] " +"functions\n" +msgstr "" +" \\df[antw][S+] [パターン] (集約/通常/プロシージャ/トリガー/ウィンドウ)関数" +"(ã®ã¿)ã®ä¸€è¦§ã‚’表示ã—ã¾ã™\n" -#: help.c:202 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" -msgstr " \\dF[+] [パターン] テキスト検索設定ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dF[+] [パターン] テキスト検索設定一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:203 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" -msgstr " \\dFd[+] [パターン] テキスト検索用辞書ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dFd[+] [パターン] テキスト検索用辞書一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:204 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" -msgstr " \\dFp[+] [パターン] テキスト検索用パーサーã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dFp[+] [パターン] テキスト検索用パーサ一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:205 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" -msgstr " \\dFt[+] [パターン] テキスト検索用テンプレートã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr "" +" \\dFt[+] [パターン] テキスト検索用テンプレート一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:206 +#: help.c:243 #, c-format -msgid " \\dg[+] [PATTERN] list roles\n" -msgstr " \\dg[+] [パターン] ロールã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [パターン] ロール一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:207 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" -msgstr " \\di[S+] [パターン] インデックスã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\di[S+] [パターン] インデックス一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:208 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" -msgstr " \\dl ラージオブジェクトã®ä¸€è¦§ã‚’表示ã™ã‚‹ã€‚\\lo_list ã¨åŒã˜ã€‚\n" +msgstr "" +" \\dl ラージオブジェクト一覧を表示ã—ã¾ã™ã€‚\\lo_list ã¨åŒ" +"ã˜ã§ã™ã€‚\n" -#: help.c:209 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" -msgstr " \\dL[S+] [パターン] 手続ã言語ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dL[S+] [パターン] 手続ã言語一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:210 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" -msgstr " \\dm[S+] [パターン] マテリアライズドビューã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dm[S+] [パターン] マテリアライズドビューã®ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:211 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" -msgstr " \\dn[S+] [パターン] スキーマã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dn[S+] [パターン] スキーマ一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:212 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" -msgstr " \\do[S] [åå‰] 演算å­ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\do[S] [åå‰] 演算å­ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:213 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" -msgstr " \\dO[S+] [パターン] ç…§åˆé †åºã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dO[S+] [パターン] ç…§åˆé †åºä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:214 +#: help.c:251 #, c-format -msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" -msgstr " \\dp [パターン] テーブルã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid "" +" \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr "" +" \\dp [パターン] テーブルã€ãƒ“ューã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ä¸€è¦§ã‚’表示" +"ã—ã¾ã™ã€‚\n" -#: help.c:215 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" -msgstr " \\drds [パターン1 [パターン2]] データベース毎ã®ãƒ­ãƒ¼ãƒ«ï¼ˆãƒ¦ãƒ¼ã‚¶ãƒ¼ï¼‰è¨­å®šã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr "" +" \\drds [パターン1 [パターン2]] データベース毎ã®ãƒ­ãƒ¼ãƒ«è¨­å®šä¸€è¦§ã‚’表示ã—ã¾" +"ã™ã€‚\n" -#: help.c:216 +#: help.c:253 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr "" +" \\dRp[+] [パターン] レプリケーションã®ãƒ‘ブリケーション一覧を表示ã—ã¾" +"ã™ã€‚\n" + +#: help.c:254 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr "" +" \\dRs[+] [パターン] レプリケーションã®ã‚µãƒ–スクリプション一覧を表示ã—ã¾" +"ã™ã€‚\n" + +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" -msgstr " \\ds[S+] [パターン] シーケンスã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dc[S+] [パターン] 変æ›ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ä¸€è¦§ã‚’表示ã—ã¾ã™ã€‚\n" -#: help.c:217 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" -msgstr " \\dt[S+] [パターン] テーブルã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\ds[S+] [パターン] テーブル一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:218 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" -msgstr " \\dT[S+] [パターン] データ型ã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dt[S+] [パターン] データ型一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:219 +#: help.c:258 #, c-format -msgid " \\du[+] [PATTERN] list roles\n" -msgstr " \\du[+] [パターン] ロールã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [パターン] ロール一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:220 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" -msgstr " \\dv[S+] [パターン] ビューã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" - -#: help.c:221 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [パターン] 外部テーブルã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dv[S+] [パターン] ビュー一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:222 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" -msgstr " \\dx[+] [パターン] æ‹¡å¼µã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dx[+] [パターン] 拡張一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:223 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" -msgstr " \\dy [パターン] イベントトリガã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\dy [パターン] イベントトリガー一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:224 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" -msgstr " \\l[+] [パターン] データベースã®ä¸€è¦§ã‚’表示ã™ã‚‹\n" +msgstr " \\l[+] [パターン] データベース一覧を表示ã—ã¾ã™ã€‚\n" -#: help.c:225 +#: help.c:263 #, c-format -msgid " \\sf[+] FUNCNAME show a function's definition\n" -msgstr " \\sf[+] 関数å 関数定義を表示ã™ã‚‹\n" +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] 関数å 関数定義を表示ã—ã¾ã™ã€‚\n" -#: help.c:226 +#: help.c:264 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] ビューå ビュー定義を表示ã—ã¾ã™ã€‚\n" + +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" -msgstr " \\z [パターン] \\dp ã¨åŒã˜\n" +msgstr " \\z [パターン] \\dp ã¨åŒã˜ã§ã™ã€‚\n" -#: help.c:229 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "書å¼è¨­å®š\n" -#: help.c:230 +#: help.c:269 #, c-format -msgid " \\a toggle between unaligned and aligned output mode\n" -msgstr " \\a 出力モード㮠'unaligned' / 'aligned' を切り替ãˆã‚‹\n" +msgid "" +" \\a toggle between unaligned and aligned output mode\n" +msgstr "" +" \\a 出力モード(unaligned / aligned)を切り替ãˆã¾ã™ã€‚\n" -#: help.c:231 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" -msgstr " \\C タイトル テーブルã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’設定ã™ã‚‹ã€‚指定ãŒãªã‘れã°è§£é™¤\n" +msgstr "" +" \\C [文字列] テーブルã®ã‚¿ã‚¤ãƒˆãƒ«è¨­å®šã€‚指定ãŒãªã‘れã°è§£é™¤ã—ã¾" +"ã™ã€‚\n" -#: help.c:232 +#: help.c:271 #, c-format -msgid " \\f [STRING] show or set field separator for unaligned query output\n" -msgstr " \\f [文字列] æ¡æƒãˆã‚’行ã‚ãªã„(unaligned)å•ã„åˆã‚ã›å‡ºåŠ›ã«ãŠã‘るフィールド区切り文字を表示ã¾ãŸã¯è¨­å®š\n" +msgid "" +" \\f [STRING] show or set field separator for unaligned query " +"output\n" +msgstr "" +" \\f [文字列] æ¡æƒãˆãªã—ã®å•ã„åˆã‚ã›å‡ºåŠ›ã§ä½¿ã‚れるフィールド区切" +"り文字を表示ã¾ãŸã¯è¨­å®šã—ã¾ã™ã€‚\n" -#: help.c:233 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" -msgstr " \\H HTML ã®å‡ºåŠ›ãƒ¢ãƒ¼ãƒ‰ã‚’åˆ‡ã‚Šæ›¿ãˆã‚‹(ç¾åœ¨: %s)\n" +msgstr " \\H HTML ã®å‡ºåŠ›ãƒ¢ãƒ¼ãƒ‰ã‚’åˆ‡ã‚Šæ›¿ãˆã¾ã™(ç¾åœ¨: %s)\n" -#: help.c:235 +#: help.c:274 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n" +" (NAME := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" +"unicode_header_linestyle})\n" msgstr "" -" \\pset [åå‰ [値]] テーブル出力ã®ã‚ªãƒ—ションを設定ã™ã‚‹\n" -" (åå‰ := {format|border|expanded|fieldsep|fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|title|tableattr|pager})\n" - -#: help.c:238 +" \\pset [åå‰ [値]] テーブル出力ã®ã‚ªãƒ—ション設定\n" +" (åå‰ := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" +"unicode_header_linestyle})\n" + +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" -msgstr " \\t [on|off] 行ã®ã¿ã‚’表示ã™ã‚‹ã‹ï¼Ÿ (ç¾åœ¨: %s)\n" +msgstr " \\t [on|off] 行ã®ã¿è¡¨ç¤ºãƒ¢ãƒ¼ãƒ‰ï¼ˆç¾åœ¨: %s)\n" -#: help.c:240 +#: help.c:282 #, c-format -msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" -msgstr " \\T [文字列] HTML ã®
ã‚¿ã‚°ã®å±žæ€§ã‚’セット。引数ãŒãªã‘れã°è§£é™¤\n" +msgid "" +" \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr "" +" \\T [文字列] HTML ã®
タグ属性ã®ã‚»ãƒƒãƒˆã€‚引数ãŒãªã‘れã°è§£" +"除ã—ã¾ã™ã€‚\n" -#: help.c:241 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" -msgstr " \\x [on|off|auto] 拡張出力ã®åˆ‡ã‚Šæ›¿ãˆ(ç¾åœ¨: %s)\n" +msgstr " \\x [on|off|auto] 拡張出力ã®åˆ‡ã‚Šæ›¿ãˆï¼ˆç¾åœ¨: %s)\n" -#: help.c:245 +#: help.c:287 #, c-format msgid "Connection\n" -msgstr "接続\n" +msgstr "接続関連\n" -#: help.c:247 +#: help.c:289 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently \"%s\")\n" msgstr "" -" \\c[onnect] {[DBå|- ユーザå|- ホストå|- ãƒãƒ¼ãƒˆç•ªå·|-] | conninfo}\n" -" æ–°ã—ã„ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã™ã‚‹ (ç¾åœ¨: \"%s\")\n" +" \\c[onnect] {[DBå|- ユーザå|- ホストå|- ãƒãƒ¼ãƒˆç•ªå·|-] | 接続文字列}\n" +" æ–°ã—ã„ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¾ã™ï¼ˆç¾åœ¨: \"%s\")\n" -#: help.c:251 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " connect to new database (currently no connection)\n" msgstr "" -" \\c[onnect] {[DBå|- ユーザå|- ホストå|- ãƒãƒ¼ãƒˆç•ªå·|-] | conninfo}\n" -" æ–°ã—ã„ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã™ã‚‹ (ç¾åœ¨: 接続無ã—)\n" +" \\c[onnect] {[DBå|- ユーザå|- ホストå|- ãƒãƒ¼ãƒˆç•ªå·|-] | 接続文字列}\n" +" æ–°ã—ã„ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¾ã™ï¼ˆç¾åœ¨: 未接続)\n" -#: help.c:253 +#: help.c:295 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo ç¾åœ¨ã®æŽ¥ç¶šã«é–¢ã™ã‚‹æƒ…報を表示ã—ã¾ã™ã€‚\n" + +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr "" -" \\encoding [エンコーディング]\n" -" クライアントã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã‚’表示ã¾ãŸã¯ã‚»ãƒƒãƒˆ\n" +" \\encoding [エンコーディング] クライアントã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°ã‚’表示ã¾ãŸã¯è¨­" +"定ã—ã¾ã™ã€‚\n" -#: help.c:254 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" -msgstr " \\password [ユーザå] ユーザã®ãƒ‘スワードを安全ã«å¤‰æ›´ã™ã‚‹\n" +msgstr " \\password [ユーザå] ユーザã®ãƒ‘スワードを安全ã«å¤‰æ›´ã—ã¾ã™ã€‚\n" -#: help.c:255 -#, c-format -msgid " \\conninfo display information about current connection\n" -msgstr " \\conninfo ç¾åœ¨ã®æŽ¥ç¶šã«é–¢ã™ã‚‹æƒ…報を表示ã™ã‚‹\n" - -#: help.c:258 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "オペレーティングシステム\n" -#: help.c:259 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" -msgstr " \\cd [DIR] カレントディレクトリを変更\n" +msgstr " \\cd [DIR] カレントディレクトリを変更ã—ã¾ã™ã€‚\n" -#: help.c:260 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" -msgstr " \\setenv NAME [VALUE] 環境変数ã®è¨­å®šã€è¨­å®šè§£é™¤ã‚’行ã†\n" +msgstr " \\setenv åå‰ [値] 環境変数を設定ã¾ãŸã¯è§£é™¤ã—ã¾ã™ã€‚\n" -#: help.c:261 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" -msgstr " \\timing [on|off] コマンドã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’切り替ãˆã‚‹(ç¾åœ¨: %s)\n" +msgstr "" +" \\timing [on|off] コマンドã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’切り替ãˆã¾ã™ï¼ˆç¾åœ¨: %s)\n" -#: help.c:263 +#: help.c:305 #, c-format -msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" -msgstr " \\! [コマンド] シェルã§ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã€ã‚‚ã—ãã¯ä¼šè©±åž‹ã‚·ã‚§ãƒ«ã‚’èµ·å‹•\n" +msgid "" +" \\! [COMMAND] execute command in shell or start interactive " +"shell\n" +msgstr "" +" \\! [コマンド] シェルã§ã‚³ãƒžãƒ³ãƒ‰ã‚’実行ã™ã‚‹ã‹ã€ã‚‚ã—ãã¯å¯¾è©±åž‹ã‚·ã‚§ãƒ«" +"ã‚’èµ·å‹•ã—ã¾ã™ã€‚\n" -#: help.c:266 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "変数\n" -#: help.c:267 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" -msgstr " \\prompt [テキスト] 変数å ユーザã«å†…部変数をセットã™ã‚‹ã‚ˆã†ä¿ƒã™\n" +msgstr "" +" \\prompt [テキスト] 変数å ユーザã«å¯¾ã—ã¦å†…部変数ã®ã‚»ãƒƒãƒˆã‚’促ã—ã¾ã™ã€‚\n" -#: help.c:268 +#: help.c:310 #, c-format -msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgid "" +" \\set [NAME [VALUE]] set internal variable, or list all if no " +"parameters\n" msgstr "" -" \\set [変数å [値]]\n" -" 内部変数ã®å€¤ã‚’セット。引数ãŒãªã„å ´åˆã¯ä¸€è¦§è¡¨ç¤ºã€‚\n" +" \\set [変数å [値]] 内部変数ã®å€¤ã‚’設定ã—ã¾ã™ã€‚引数ãŒãªã„å ´åˆã¯ä¸€è¦§ã‚’表" +"示ã—ã¾ã™ã€‚\n" -#: help.c:269 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" -msgstr " \\unset 変数å 内部変数を削除ã™ã‚‹\n" +msgstr " \\unset 変数å 内部変数を削除ã—ã¾ã™ã€‚\n" -#: help.c:272 +#: help.c:314 #, c-format msgid "Large Objects\n" -msgstr "ラージオブジェクト\n" +msgstr "ラージ オブジェクト\n" -#: help.c:273 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2409,84 +3176,784 @@ msgstr "" " \\lo_export LOBOID ファイルå\n" " \\lo_import ファイルå [コメント]\n" " \\lo_list\n" -" \\lo_unlink LOBOID ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作\n" +" \\lo_unlink LOBOID ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ“作\n" -#: help.c:320 -msgid "Available help:\n" -msgstr "利用å¯èƒ½ãªãƒ˜ãƒ«ãƒ—:\n" +#: help.c:342 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"ç‰¹æ®Šãªæ‰±ã„ã‚’ã™ã‚‹å¤‰æ•°ã®ä¸€è¦§\n" +"\n" + +#: help.c:344 +#, c-format +msgid "psql variables:\n" +msgstr "psql 変数:\n" -#: help.c:404 +#: help.c:346 #, c-format msgid "" -"Command: %s\n" -"Description: %s\n" -"Syntax:\n" -"%s\n" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" "\n" msgstr "" -"コマンド: %s\n" -"説明: %s\n" -"書å¼:\n" -"%s\n" +" psql --set=åå‰=値\n" +" ã¾ãŸã¯ psql ã«å…¥ã£ã¦ã‹ã‚‰ \\set åå‰ å€¤\n" "\n" -#: help.c:420 +#: help.c:348 #, c-format msgid "" -"No help available for \"%s\".\n" -"Try \\h with no arguments to see available help.\n" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" msgstr "" -"\"%s\" ã«ã¤ã„ã¦ã¯ãƒ˜ãƒ«ãƒ—情報ãŒã‚りã¾ã›ã‚“。\n" -"引数ãªã—ã§ \\h ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€ãƒ˜ãƒ«ãƒ—ã®ä¸€è¦§ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n" +" AUTOCOMMIT\n" +" セットã•れã¦ã„ã‚‹å ´åˆã€SQL ã‚³ãƒžãƒ³ãƒ‰ãŒæˆåŠŸã—ãŸéš›ã«è‡ªå‹•çš„ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™\n" -#: input.c:194 +#: help.c:350 #, c-format -msgid "could not read from input file: %s\n" -msgstr "入力ファイルã‹ã‚‰èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" SQLキーワードã®è£œå®Œã«ä½¿ã†æ–‡å­—ケースを指定ã—ã¾ã™\n" +" [lower, upper, preserve-lower, preserve-upper]\n" -#: input.c:446 input.c:485 +#: help.c:353 #, c-format -msgid "could not save history to file \"%s\": %s\n" -msgstr "ファイル \"%s\" ã«ãƒ’ストリをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" ç¾åœ¨æŽ¥ç¶šä¸­ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹å\n" -#: input.c:505 +#: help.c:355 #, c-format -msgid "history is not supported by this installation\n" -msgstr "ã“ã®ç’°å¢ƒã§ã¯ãƒ’ストリ機能をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“。\n" +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" 標準出力ã¸ã®å‡ºåŠ›å¯¾è±¡ã¨ã™ã‚‹å…¥åŠ›ã®ã‚¿ã‚¤ãƒ—を設定ã—ã¾ã™\n" +" [all, errors, none, queries]\n" -#: large_obj.c:66 +#: help.c:358 #, c-format -msgid "%s: not connected to a database\n" -msgstr "%s: ã©ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«ã‚‚接続ã•れã¦ã„ã¾ã›ã‚“\n" +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" セットã•れã¦ã„れã°ã€ãƒãƒƒã‚¯ã‚¹ãƒ©ãƒƒã‚·ãƒ¥ã‚³ãƒžãƒ³ãƒ‰ã§å®Ÿè¡Œã•れる内部å•ã„åˆã‚ã›" +"ã‚’\n" +" 表示ã—ã¾ã™; \"noexec\" ã«ã‚»ãƒƒãƒˆã—ãŸå ´åˆã¯å®Ÿè¡Œã›ãšã«è¡¨ç¤ºã ã‘ã—ã¾ã™\n" -#: large_obj.c:85 +#: help.c:361 #, c-format -msgid "%s: current transaction is aborted\n" -msgstr "%s: トランザクションを中断ã—ã¾ã—ãŸ\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" ç¾åœ¨ã®ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆå´ã®æ–‡å­—セットã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°\n" -#: large_obj.c:88 +#: help.c:363 #, c-format -msgid "%s: unknown transaction status\n" -msgstr "%s: トランザクションã®çŠ¶æ…‹ãŒä¸æ˜Žã§ã™ã€‚\n" +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" 最後ã®å•ã„åˆã‚ã›ãŒå¤±æ•—ã§ã‚れã°çœŸã€ãã†ã§ãªã‘れã°å½\n" -#: large_obj.c:289 large_obj.c:300 -msgid "ID" -msgstr "ID" +#: help.c:365 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = " +"unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" 一度ã«å–å¾—ãŠã‚ˆã³è¡¨ç¤ºã™ã‚‹çµæžœã®è¡Œæ•° (0 = 無制é™ï¼‰\n" + +#: help.c:367 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" コマンド履歴ã®åˆ¶å¾¡ [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:369 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" コマンド履歴をä¿å­˜ã™ã‚‹ãƒ•ァイルã®åå‰\n" + +#: help.c:371 +#, c-format +#| msgid "" +#| " HISTSIZE\n" +#| " max number of commands to store in the command history\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" コマンド履歴ã§ä¿å­˜ã™ã‚‹ã‚³ãƒžãƒ³ãƒ‰æ•°ã®æœ€å¤§å€¤\n" + +#: help.c:373 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" ç¾åœ¨æŽ¥ç¶šä¸­ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚µãƒ¼ãƒãƒ›ã‚¹ãƒˆ\n" + +#: help.c:375 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" 対話形セッションを終ã‚らã›ã‚‹ã®ã«å¿…è¦ãª EOF ã®æ•°\n" + +#: help.c:377 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" 最後ã®å¤‰æ›´ã®å½±éŸ¿ã‚’å—ã‘㟠OID ã®å€¤\n" + +#: help.c:379 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if " +"none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" 最後ã®ã‚¨ãƒ©ãƒ¼ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŠã‚ˆã³ SQLSTATEã€\n" +" ãªã«ã‚‚ãªã‘れã°ç©ºã®æ–‡å­—列ãŠã‚ˆã³\"00000\"\n" + +#: help.c:382 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" セットã•れã¦ã„ã‚‹å ´åˆã€ã‚¨ãƒ©ãƒ¼ã§ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’åœæ­¢ã—ã¾ã›ã‚“(暗黙ã®ã‚»ãƒ¼" +"ブ\n" +" ãƒã‚¤ãƒ³ãƒˆã‚’使用ã—ã¾ã™ï¼‰\n" + +#: help.c:384 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" エラー発生後ã«ãƒãƒƒãƒã®å®Ÿè¡Œã‚’åœæ­¢ã—ã¾ã™\n" + +#: help.c:386 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" ç¾åœ¨ã®æŽ¥ç¶šã®ã‚µãƒ¼ãƒãƒãƒ¼ãƒˆ\n" + +#: help.c:388 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" psql ã®æ¨™æº–ã®ãƒ—ロンプトを指定ã—ã¾ã™\n" + +#: help.c:390 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous " +"line\n" +msgstr "" +" PROMPT2\n" +" ステートメントãŒå‰è¡Œã‹ã‚‰ç¶™ç¶šã™ã‚‹å ´åˆã®ãƒ—ロンプトを指定ã—ã¾ã™\n" + +#: help.c:392 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" COPY ... FROM STDIN ã®æœ€ä¸­ã«ä½¿ã‚れるプロンプトを指定ã—ã¾ã™\n" + +#: help.c:394 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" メッセージを表示ã—ã¾ã›ã‚“(-q オプションã¨åŒã˜ï¼‰\n" + +#: help.c:396 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" 最後ã®å•ã„åˆã‚ã›ã§è¿”å´ã—ãŸã€ã¾ãŸã¯å½±éŸ¿ã‚’与ãˆãŸè¡Œã®æ•°ã€ã¾ãŸã¯0\n" + +#: help.c:398 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (çŸ­ã„æ–‡å­—列ã¾ãŸã¯æ•°å€¤)\n" + +#: help.c:401 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" メッセージコンテキストフィールドã®è¡¨ç¤ºã‚’制御 [never, errors, always]\n" + +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" セットã—ãŸå ´åˆã€æ”¹è¡ŒãŒSQL コマンドを終端ã—ã¾ã™ (-S オプションã¨åŒã˜)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" シングルステップモード (-s オプションã¨åŒã˜)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" 最後ã®å•ã„åˆã‚ã›ã® SQLSTATEã€ã¾ãŸã¯ã‚¨ãƒ©ãƒ¼ã§ãªã‘れã°\"00000\"\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" ç¾åœ¨æŽ¥ç¶šä¸­ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ¦ãƒ¼ã‚¶\n" + +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" エラー報告ã®è©³ç´°åº¦ã‚’制御 [default, verbose, terse]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (é•·ã„æ–‡å­—列ã€çŸ­ã„文字列ã¾ãŸã¯æ•°å€¤)\n" + +#: help.c:418 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"表示設定:\n" + +#: help.c:420 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=åå‰[=値]\n" +" ã¾ãŸã¯ psql ã«å…¥ã£ã¦ã‹ã‚‰ \\pset åå‰ [値]\n" +"\n" + +#: help.c:422 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" border style (number)\n" + +#: help.c:424 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" 折り返ã—表示ã§ç›®æ¨™ã¨ã™ã‚‹æ¨ªå¹…\n" + +#: help.c:426 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (or x)\n" +" 拡張出力 [on, off, auto]\n" + +#: help.c:428 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" æ¡æƒãˆã—ãªã„出力ã§ã®ãƒ•ィールド区切り文字 (デフォルト㯠\"%s\")\n" + +#: help.c:431 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" æ¡æƒãˆã—ãªã„出力ã§ã®ãƒ•ィールド区切り文字をãƒã‚¤ãƒˆå€¤ã®0ã«è¨­å®š\n" + +#: help.c:433 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" テーブルフッター出力ã®è¦å¦ã‚’設定 [on, off]\n" + +#: help.c:435 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" 出力フォーマットを設定 [unaligned, aligned, wrapped, html, " +"asciidoc, ...]\n" + +#: help.c:437 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" å¢ƒç•Œç·šã®æç”»ã‚¹ã‚¿ã‚¤ãƒ«ã‚’è¨­å®š [ascii, old-ascii, unicode]\n" + +#: help.c:439 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" null 値ã®ä»£ã‚りã«è¡¨ç¤ºã™ã‚‹æ–‡å­—列を設定\n" + +#: help.c:441 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of " +"digits\n" +msgstr "" +" numericlocale\n" +" ロケール固有文字ã§ã®æ¡åŒºåˆ‡ã‚Šã‚’表示ã™ã‚‹ã‹ã©ã†ã‹ã‚’指定\n" + +#: help.c:443 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" ã„ã¤å¤–部ページャーを使ã†ã‹ã‚’制御 [yes, no, always]\n" + +#: help.c:445 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" æ¡æƒãˆã—ãªã„出力ã§ã®ãƒ¬ã‚³ãƒ¼ãƒ‰(行)区切り\n" + +#: help.c:447 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" æ¡æƒãˆã—ãªã„出力ã§ãƒ¬ã‚³ãƒ¼ãƒ‰åŒºåˆ‡ã‚Šã«ãƒã‚¤ãƒˆå€¤ã®0ã«è¨­å®š\n" + +#: help.c:449 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" +" tableattr (or T)\n" +" HTML フォーマット時㮠table ã‚¿ã‚°ã®å±žæ€§ã€ã‚‚ã—ã㯠latex-longtable\n" +" フォーマット時ã«å·¦å¯„ã›ã™ã‚‹ãƒ‡ãƒ¼ã‚¿åž‹ã®ç›¸å¯¾ã‚«ãƒ©ãƒ å¹…を指定\n" + +#: help.c:452 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" 以é™ã«è¡¨ç¤ºã•れる表ã®ã‚¿ã‚¤ãƒˆãƒ«ã‚’設定\n" + +#: help.c:454 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" セットã•れãŸå ´åˆã€å®Ÿéš›ã®ãƒ†ãƒ¼ãƒ–ルデータã®ã¿ã‚’表示ã—ã¾ã™\n" + +#: help.c:456 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" Unicode ã«ã‚ˆã‚‹ç·šæç”»æ™‚ã®ã‚¹ã‚¿ã‚¤ãƒ«ã‚’設定 [single, double]\n" + +#: help.c:461 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"環境変数:\n" + +#: help.c:465 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" åå‰=値 [åå‰=値] psql ...\n" +" ã¾ãŸã¯ã€psql ã«å…¥ã£ã¦ã‹ã‚‰ \\setenv åå‰ [値]\n" +"\n" + +#: help.c:467 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set åå‰=値\n" +" psql ...\n" +" ã¾ãŸã¯ã€psql ã«å…¥ã£ã¦ã‹ã‚‰ \\setenv åå‰ [値]\n" +"\n" + +#: help.c:470 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" æŠ˜ã‚Šè¿”ã—æ›¸å¼ã«ãŠã‘るカラム数\n" + +#: help.c:472 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" application_name 接続パラメーターã¨åŒã˜\n" + +#: help.c:474 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" dbname 接続パラメーターã¨åŒã˜\n" + +#: help.c:476 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" host 接続パラメーターã¨åŒã˜\n" + +#: help.c:478 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" 接続用パスワード (推奨ã•れã¾ã›ã‚“)\n" + +#: help.c:480 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" パスワードファイルå\n" + +#: help.c:482 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" port 接続パラメーターã¨åŒã˜\n" + +#: help.c:484 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" user 接続パラメーターã¨åŒã˜\n" + +#: help.c:486 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" \\e, \\ef, \\ev コマンドã§ä½¿ã‚れるエディタ\n" + +#: help.c:488 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" エディタã®èµ·å‹•時ã«è¡Œç•ªå·ã‚’指定ã™ã‚‹æ–¹æ³•\n" + +#: help.c:490 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" コマンドライン履歴ファイルã®ä»£æ›¿ã®å ´æ‰€\n" + +#: help.c:492 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" 外部ページャープログラムã®åå‰\n" -#: large_obj.c:310 +#: help.c:494 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" ユーザ㮠.psqlrc ファイルã®ä»£æ›¿ã®å ´æ‰€\n" + +#: help.c:496 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" \\! コマンドã§ä½¿ã‚れるシェル\n" + +#: help.c:498 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" テンãƒãƒ©ãƒªãƒ•ァイル用ディレクトリ\n" + +#: help.c:542 +msgid "Available help:\n" +msgstr "利用å¯èƒ½ãªãƒ˜ãƒ«ãƒ—:\n" + +#: help.c:626 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +msgstr "" +"コマンド: %s\n" +"説明: %s\n" +"書å¼:\n" +"%s\n" +"\n" + +#: help.c:642 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"\"%s\" ã®ãƒ˜ãƒ«ãƒ—ãŒã‚りã¾ã›ã‚“。\n" +"引数ãªã—ã§ \\h ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€ãƒ˜ãƒ«ãƒ—ã®ä¸€è¦§ãŒè¡¨ç¤ºã•れã¾ã™ã€‚\n" + +#: input.c:216 +#, c-format +msgid "could not read from input file: %s\n" +msgstr "入力ファイルã‹ã‚‰èª­ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: input.c:471 input.c:510 +#, c-format +msgid "could not save history to file \"%s\": %s\n" +msgstr "ファイル \"%s\" ã«ãƒ’ストリーをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: input.c:530 +#, c-format +msgid "history is not supported by this installation\n" +msgstr "ã“ã®ç’°å¢ƒã§ã¯ãƒ’ストリー機能ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" + +#: large_obj.c:64 +#, c-format +msgid "%s: not connected to a database\n" +msgstr "%s: ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã«æŽ¥ç¶šã—ã¦ã„ã¾ã›ã‚“。\n" + +#: large_obj.c:83 +#, c-format +msgid "%s: current transaction is aborted\n" +msgstr "%s: ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã¯ä¸­æ­¢ã•れã¾ã™ã€‚\n" + +#: large_obj.c:86 +#, c-format +msgid "%s: unknown transaction status\n" +msgstr "%s: 䏿˜Žãªãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®çŠ¶æ…‹\n" + +#: large_obj.c:287 large_obj.c:298 +msgid "ID" +msgstr "ID" + +#: large_obj.c:308 msgid "Large objects" -msgstr "ラージオブジェクト" +msgstr "ラージ オブジェクト" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped\n" +msgstr "\\if: ブロックを抜ã‘ã¾ã—ãŸã€‚\n" -#: mainloop.c:159 +#: mainloop.c:183 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "\"\\q\" ã§ %s を抜ã‘ã¾ã™ã€‚\n" -#: mainloop.c:189 +#: mainloop.c:205 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"ã“ã®å…¥åŠ›ãƒ‡ãƒ¼ã‚¿ã¯ PostgreSQL ã®ã‚«ã‚¹ã‚¿ãƒ ãƒ•ォーマットã®ãƒ€ãƒ³ãƒ—ã§ã™ã€‚\n" +"ã“ã®ãƒ€ãƒ³ãƒ—をデータベースã«ãƒªã‚¹ãƒˆã‚¢ã™ã‚‹ã«ã¯ pg_restore コマンドを使ã£ã¦ãã ã•" +"ã„。\n" + +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "\\? ã§ãƒ˜ãƒ«ãƒ—ã®è¡¨ç¤ºã€control-C ã§å…¥åŠ›ãƒãƒƒãƒ•ァをクリアã—ã¾ã™ã€‚" + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr " \\? ã§ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚" + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." -msgstr "PostgreSQL ã¸ã®ã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ãƒ»ã‚¤ãƒ³ã‚¿ãƒ¼ãƒ•ェースã€psql ã¸ã‚ˆã†ã“ã。" +msgstr "" +"PostgreSQL ã¸ã®ã‚³ãƒžãƒ³ãƒ‰ ライン インターフェイスã€psql を使用ã—ã¦ã„ã¾ã™ã€‚" -#: mainloop.c:190 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -2495,1968 +3962,2371 @@ msgid "" " \\g or terminate with semicolon to execute query\n" " \\q to quit\n" msgstr "" -" \\copyright ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€é…布æ¡ä»¶ã‚’表示ã—ã¾ã™ã€‚\n" +"ヒント: \\copyright ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€é…布æ¡ä»¶ã‚’表示ã—ã¾ã™ã€‚\n" " \\h ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€SQL コマンドã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" " \\? ã¨ã‚¿ã‚¤ãƒ—ã™ã‚‹ã¨ã€psql コマンドã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" " \\g ã¨æ‰“ã¤ã‹ã‚»ãƒŸã‚³ãƒ­ãƒ³ã§é–‰ã˜ã‚‹ã¨ã€å•ã„åˆã‚ã›ã‚’実行ã—ã¾ã™ã€‚\n" " \\q ã§çµ‚了ã—ã¾ã™ã€‚\n" -#: print.c:272 -#, c-format -msgid "(%lu row)" -msgid_plural "(%lu rows)" -msgstr[0] "(%lu 行)" -msgstr[1] "(%lu 行)" - -#: print.c:1174 -#, c-format -msgid "(No rows)\n" -msgstr "(行ãŒã‚りã¾ã›ã‚“)\n" - -#: print.c:2238 -#, c-format -msgid "Interrupted\n" -msgstr "中断ã•れã¾ã—ãŸ\n" +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "\\q ã§çµ‚了ã—ã¾ã™ã€‚" -#: print.c:2304 -#, c-format -msgid "Cannot add header to table content: column count of %d exceeded.\n" -msgstr "テーブルã®å†…容ã«è¦‹å‡ºã—を追加ã§ãã¾ã›ã‚“ã§ã—ãŸï¼šåˆ—æ•° %d ãŒåˆ¶é™ã‚’è¶Šãˆã¦ã„ã¾ã™ã€‚\n" +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "control-D ã§çµ‚了ã—ã¾ã™ã€‚" -#: print.c:2344 -#, c-format -msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" -msgstr "テーブルã®å†…容ã«ã‚»ãƒ«ã‚’追加ã§ãã¾ã›ã‚“ã§ã—ãŸï¼šå…¨ã‚»ãƒ«æ•° %d ãŒåˆ¶é™ã‚’è¶Šãˆã¦ã„ã¾ã™ã€‚\n" +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "control-C ã§çµ‚了ã—ã¾ã™ã€‚" -#: print.c:2570 -#, c-format -msgid "invalid output format (internal error): %d" -msgstr "出力フォーマットãŒç„¡åŠ¹ï¼ˆå†…éƒ¨ã‚¨ãƒ©ãƒ¼ï¼‰ï¼š%d" +#: mainloop.c:449 mainloop.c:591 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "" +"å•ã„åˆã‚ã›ã¯ç„¡è¦–ã•れã¾ã—ãŸã€‚\\endif ã‹ Ctrl-C ã§ç¾åœ¨ã® \\if ブロックを抜ã‘ã¦" +"ãã ã•ã„\n" -#: psqlscan.l:727 +#: mainloop.c:609 #, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" -msgstr "変数\"%s\"ã®å†å¸°å±•開をスキップã—ã¦ã„ã¾ã™\n" +msgid "reached EOF without finding closing \\endif(s)\n" +msgstr "" +"ブロックを閉ã˜ã‚‹ \\endif を検索中ã«ã€ãƒ•ァイルã®çµ‚端(EOF)ã«é”ã—ã¾ã—ãŸã€‚\n" -#: psqlscan.l:1604 +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" -msgstr "文字列ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“\n" +msgstr "文字列ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“。\n" -#: psqlscan.l:1704 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" -msgstr "%s: メモリä¸è¶³ã§ã™\n" - -#: psqlscan.l:1933 -#, c-format -msgid "can't escape without active connection\n" -msgstr "æœ‰åŠ¹ãªæŽ¥ç¶šãªã—ã§ã¯ã‚¨ã‚¹ã‚±ãƒ¼ãƒ—ã§ãã¾ã›ã‚“\n" - -#: sql_help.c:32 sql_help.c:35 sql_help.c:38 sql_help.c:60 sql_help.c:62 -#: sql_help.c:64 sql_help.c:75 sql_help.c:77 sql_help.c:79 sql_help.c:103 -#: sql_help.c:107 sql_help.c:109 sql_help.c:111 sql_help.c:113 sql_help.c:116 -#: sql_help.c:118 sql_help.c:120 sql_help.c:213 sql_help.c:215 sql_help.c:216 -#: sql_help.c:218 sql_help.c:220 sql_help.c:223 sql_help.c:225 sql_help.c:227 -#: sql_help.c:229 sql_help.c:241 sql_help.c:242 sql_help.c:243 sql_help.c:245 -#: sql_help.c:290 sql_help.c:292 sql_help.c:294 sql_help.c:296 sql_help.c:354 -#: sql_help.c:359 sql_help.c:361 sql_help.c:396 sql_help.c:398 sql_help.c:401 -#: sql_help.c:403 sql_help.c:460 sql_help.c:465 sql_help.c:470 sql_help.c:475 -#: sql_help.c:515 sql_help.c:517 sql_help.c:519 sql_help.c:522 sql_help.c:524 -#: sql_help.c:535 sql_help.c:537 sql_help.c:577 sql_help.c:579 sql_help.c:582 -#: sql_help.c:584 sql_help.c:586 sql_help.c:612 sql_help.c:616 sql_help.c:629 -#: sql_help.c:632 sql_help.c:635 sql_help.c:655 sql_help.c:667 sql_help.c:675 -#: sql_help.c:678 sql_help.c:681 sql_help.c:711 sql_help.c:717 sql_help.c:719 -#: sql_help.c:723 sql_help.c:726 sql_help.c:729 sql_help.c:738 sql_help.c:749 -#: sql_help.c:751 sql_help.c:768 sql_help.c:777 sql_help.c:779 sql_help.c:781 -#: sql_help.c:793 sql_help.c:797 sql_help.c:799 sql_help.c:878 sql_help.c:880 -#: sql_help.c:883 sql_help.c:886 sql_help.c:888 sql_help.c:890 sql_help.c:951 -#: sql_help.c:953 sql_help.c:955 sql_help.c:958 sql_help.c:979 sql_help.c:982 -#: sql_help.c:985 sql_help.c:988 sql_help.c:992 sql_help.c:994 sql_help.c:996 -#: sql_help.c:998 sql_help.c:1012 sql_help.c:1015 sql_help.c:1017 -#: sql_help.c:1019 sql_help.c:1029 sql_help.c:1031 sql_help.c:1041 -#: sql_help.c:1043 sql_help.c:1052 sql_help.c:1073 sql_help.c:1075 -#: sql_help.c:1077 sql_help.c:1080 sql_help.c:1082 sql_help.c:1084 -#: sql_help.c:1122 sql_help.c:1128 sql_help.c:1130 sql_help.c:1133 -#: sql_help.c:1135 sql_help.c:1137 sql_help.c:1164 sql_help.c:1167 -#: sql_help.c:1169 sql_help.c:1171 sql_help.c:1173 sql_help.c:1175 -#: sql_help.c:1178 sql_help.c:1218 sql_help.c:1456 sql_help.c:1472 -#: sql_help.c:1485 sql_help.c:1536 sql_help.c:1540 sql_help.c:1550 -#: sql_help.c:1568 sql_help.c:1591 sql_help.c:1609 sql_help.c:1637 -#: sql_help.c:1696 sql_help.c:1738 sql_help.c:1760 sql_help.c:1780 -#: sql_help.c:1781 sql_help.c:1816 sql_help.c:1836 sql_help.c:1858 -#: sql_help.c:1886 sql_help.c:1911 sql_help.c:1947 sql_help.c:2133 -#: sql_help.c:2146 sql_help.c:2163 sql_help.c:2179 sql_help.c:2202 -#: sql_help.c:2253 sql_help.c:2257 sql_help.c:2259 sql_help.c:2265 -#: sql_help.c:2283 sql_help.c:2310 sql_help.c:2345 sql_help.c:2357 -#: sql_help.c:2366 sql_help.c:2416 sql_help.c:2444 sql_help.c:2452 -#: sql_help.c:2460 sql_help.c:2468 sql_help.c:2476 sql_help.c:2484 -#: sql_help.c:2492 sql_help.c:2500 sql_help.c:2509 sql_help.c:2520 -#: sql_help.c:2528 sql_help.c:2536 sql_help.c:2544 sql_help.c:2552 -#: sql_help.c:2562 sql_help.c:2571 sql_help.c:2580 sql_help.c:2588 -#: sql_help.c:2596 sql_help.c:2605 sql_help.c:2613 sql_help.c:2621 -#: sql_help.c:2629 sql_help.c:2637 sql_help.c:2645 sql_help.c:2653 -#: sql_help.c:2661 sql_help.c:2669 sql_help.c:2677 sql_help.c:2686 -#: sql_help.c:2694 sql_help.c:2711 sql_help.c:2726 sql_help.c:2932 -#: sql_help.c:2983 sql_help.c:3011 sql_help.c:3019 sql_help.c:3417 -#: sql_help.c:3465 sql_help.c:3585 +msgstr "%s: メモリä¸è¶³ã§ã™ã€‚\n" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 +#: sql_help.c:1024 sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 +#: sql_help.c:1057 sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 +#: sql_help.c:1077 sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 +#: sql_help.c:1108 sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 +#: sql_help.c:1118 sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 +#: sql_help.c:1257 sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 +#: sql_help.c:1267 sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 +#: sql_help.c:1387 sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 +#: sql_help.c:1415 sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 +#: sql_help.c:1428 sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 +#: sql_help.c:1448 sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 +#: sql_help.c:1465 sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 +#: sql_help.c:1489 sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 +#: sql_help.c:1518 sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 +#: sql_help.c:1528 sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 +#: sql_help.c:1625 sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 +#: sql_help.c:1634 sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 +#: sql_help.c:1987 sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 +#: sql_help.c:2081 sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 +#: sql_help.c:2154 sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 +#: sql_help.c:2339 sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 +#: sql_help.c:2416 sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 +#: sql_help.c:2495 sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 +#: sql_help.c:2867 sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 +#: sql_help.c:2953 sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 +#: sql_help.c:3017 sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 +#: sql_help.c:3109 sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 +#: sql_help.c:3204 sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 +#: sql_help.c:3236 sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 +#: sql_help.c:3269 sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 +#: sql_help.c:3304 sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 +#: sql_help.c:3340 sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 +#: sql_help.c:3377 sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 +#: sql_help.c:3414 sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 +#: sql_help.c:3446 sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 +#: sql_help.c:3478 sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 +#: sql_help.c:3520 sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 +#: sql_help.c:3871 sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 +#: sql_help.c:4389 sql_help.c:4530 msgid "name" msgstr "åå‰" -#: sql_help.c:33 sql_help.c:36 sql_help.c:39 sql_help.c:300 sql_help.c:1279 -#: sql_help.c:2417 sql_help.c:3234 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 msgid "aggregate_signature" -msgstr "集約関数ã®å‘¼å‡ºã—情報" - -#: sql_help.c:34 sql_help.c:61 sql_help.c:76 sql_help.c:108 sql_help.c:228 -#: sql_help.c:246 sql_help.c:362 sql_help.c:402 sql_help.c:469 sql_help.c:502 -#: sql_help.c:516 sql_help.c:536 sql_help.c:583 sql_help.c:631 sql_help.c:677 -#: sql_help.c:718 sql_help.c:740 sql_help.c:750 sql_help.c:780 sql_help.c:800 -#: sql_help.c:887 sql_help.c:952 sql_help.c:995 sql_help.c:1016 -#: sql_help.c:1030 sql_help.c:1042 sql_help.c:1054 sql_help.c:1081 -#: sql_help.c:1129 sql_help.c:1172 +msgstr "集約関数ã®ã‚·ã‚°ãƒ‹ãƒãƒ£ãƒ¼" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "æ–°ã—ã„åå‰" -#: sql_help.c:37 sql_help.c:63 sql_help.c:78 sql_help.c:110 sql_help.c:226 -#: sql_help.c:244 sql_help.c:360 sql_help.c:431 sql_help.c:474 sql_help.c:538 -#: sql_help.c:547 sql_help.c:602 sql_help.c:615 sql_help.c:634 sql_help.c:680 -#: sql_help.c:752 sql_help.c:778 sql_help.c:798 sql_help.c:935 sql_help.c:954 -#: sql_help.c:997 sql_help.c:1018 sql_help.c:1076 sql_help.c:1170 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 +#: sql_help.c:1056 sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 +#: sql_help.c:1326 sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 +#: sql_help.c:1517 sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "æ–°ã—ã„æ‰€æœ‰è€…" -#: sql_help.c:40 sql_help.c:65 sql_help.c:80 sql_help.c:230 sql_help.c:293 -#: sql_help.c:404 sql_help.c:479 sql_help.c:585 sql_help.c:619 sql_help.c:637 -#: sql_help.c:683 sql_help.c:782 sql_help.c:889 sql_help.c:999 sql_help.c:1020 -#: sql_help.c:1032 sql_help.c:1044 sql_help.c:1083 sql_help.c:1174 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 +#: sql_help.c:1093 sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 +#: sql_help.c:1468 sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "æ–°ã—ã„スキーマ" -#: sql_help.c:41 sql_help.c:1326 sql_help.c:2418 sql_help.c:3253 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 msgid "where aggregate_signature is:" -msgstr "集約関数ã®å‘¼å‡ºã—情報ã¯ä»¥ä¸‹ã®é€šã‚Šï¼š" - -#: sql_help.c:42 sql_help.c:45 sql_help.c:48 sql_help.c:310 sql_help.c:333 -#: sql_help.c:336 sql_help.c:339 sql_help.c:461 sql_help.c:466 sql_help.c:471 -#: sql_help.c:476 sql_help.c:1295 sql_help.c:1327 sql_help.c:1330 -#: sql_help.c:1333 sql_help.c:1457 sql_help.c:1473 sql_help.c:1476 -#: sql_help.c:1697 sql_help.c:2419 sql_help.c:2422 sql_help.c:2425 -#: sql_help.c:2510 sql_help.c:2870 sql_help.c:3149 sql_help.c:3240 -#: sql_help.c:3254 sql_help.c:3257 sql_help.c:3260 +msgstr "集約関数ã®ã‚·ã‚°ãƒ‹ãƒãƒ£ãƒ¼ã«ã¯ä»¥ä¸‹ã®ã‚‚ã®ãŒã‚りã¾ã™:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 msgid "argmode" msgstr "引数ã®ãƒ¢ãƒ¼ãƒ‰" -#: sql_help.c:43 sql_help.c:46 sql_help.c:49 sql_help.c:311 sql_help.c:334 -#: sql_help.c:337 sql_help.c:340 sql_help.c:462 sql_help.c:467 sql_help.c:472 -#: sql_help.c:477 sql_help.c:1296 sql_help.c:1328 sql_help.c:1331 -#: sql_help.c:1334 sql_help.c:1458 sql_help.c:1474 sql_help.c:1477 -#: sql_help.c:1698 sql_help.c:2420 sql_help.c:2423 sql_help.c:2426 -#: sql_help.c:2511 sql_help.c:3241 sql_help.c:3255 sql_help.c:3258 -#: sql_help.c:3261 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 msgid "argname" -msgstr "引数å" - -#: sql_help.c:44 sql_help.c:47 sql_help.c:50 sql_help.c:312 sql_help.c:335 -#: sql_help.c:338 sql_help.c:341 sql_help.c:463 sql_help.c:468 sql_help.c:473 -#: sql_help.c:478 sql_help.c:1297 sql_help.c:1329 sql_help.c:1332 -#: sql_help.c:1335 sql_help.c:1699 sql_help.c:2421 sql_help.c:2424 -#: sql_help.c:2427 sql_help.c:2512 sql_help.c:3242 sql_help.c:3256 -#: sql_help.c:3259 sql_help.c:3262 +msgstr "引数ã®åå‰" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 msgid "argtype" msgstr "引数ã®åž‹" -#: sql_help.c:104 sql_help.c:357 sql_help.c:425 sql_help.c:432 sql_help.c:712 -#: sql_help.c:795 sql_help.c:1013 sql_help.c:1123 sql_help.c:1149 -#: sql_help.c:1383 sql_help.c:1389 sql_help.c:1640 sql_help.c:1664 -#: sql_help.c:1669 sql_help.c:1739 sql_help.c:1887 sql_help.c:1968 -#: sql_help.c:2148 sql_help.c:2311 sql_help.c:2333 sql_help.c:2745 +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "オプション" -#: sql_help.c:105 sql_help.c:713 sql_help.c:1124 sql_help.c:1740 -#: sql_help.c:1888 sql_help.c:2312 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" -msgstr "オプションã¯ä»¥ä¸‹ã®é€šã‚Šï¼š" +msgstr "オプションã«ã¯ä»¥ä¸‹ã®ã‚‚ã®ãŒã‚りã¾ã™:" -#: sql_help.c:106 sql_help.c:714 sql_help.c:1125 sql_help.c:1575 -#: sql_help.c:1889 sql_help.c:2313 +#: sql_help.c:114 sql_help.c:2118 +msgid "allowconn" +msgstr "接続ã®å¯å¦ï¼ˆçœŸå½å€¤ï¼‰" + +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" -msgstr "最大接続数" +msgstr "æœ€å¤§åŒæ™‚接続数" -#: sql_help.c:112 sql_help.c:526 sql_help.c:588 sql_help.c:603 sql_help.c:892 -#: sql_help.c:936 -msgid "new_tablespace" -msgstr "テーブルスペース" +#: sql_help.c:116 sql_help.c:2120 +msgid "istemplate" +msgstr "テンプレートã‹ã©ã†ã‹ï¼ˆçœŸå½å€¤ï¼‰" -#: sql_help.c:114 sql_help.c:117 sql_help.c:119 sql_help.c:483 sql_help.c:485 -#: sql_help.c:486 sql_help.c:721 sql_help.c:725 sql_help.c:728 sql_help.c:811 -#: sql_help.c:814 sql_help.c:1131 sql_help.c:1134 sql_help.c:1136 -#: sql_help.c:1707 sql_help.c:3036 sql_help.c:3406 +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 +#: sql_help.c:1319 +msgid "new_tablespace" +msgstr "æ–°ã—ã„テーブル空間å" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" -msgstr "設定パラメータ" - -#: sql_help.c:115 sql_help.c:358 sql_help.c:421 sql_help.c:426 sql_help.c:433 -#: sql_help.c:484 sql_help.c:521 sql_help.c:594 sql_help.c:600 sql_help.c:722 -#: sql_help.c:796 sql_help.c:812 sql_help.c:813 sql_help.c:911 sql_help.c:930 -#: sql_help.c:957 sql_help.c:1014 sql_help.c:1132 sql_help.c:1150 -#: sql_help.c:1641 sql_help.c:1665 sql_help.c:1670 sql_help.c:1708 -#: sql_help.c:1709 sql_help.c:1768 sql_help.c:1800 sql_help.c:1969 -#: sql_help.c:2043 sql_help.c:2051 sql_help.c:2083 sql_help.c:2105 -#: sql_help.c:2122 sql_help.c:2149 sql_help.c:2334 sql_help.c:3407 -#: sql_help.c:3408 +msgstr "設定パラメーター" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "値" -#: sql_help.c:177 +#: sql_help.c:197 msgid "target_role" msgstr "対象ã®ãƒ­ãƒ¼ãƒ«" -#: sql_help.c:178 sql_help.c:1624 sql_help.c:1929 sql_help.c:1934 -#: sql_help.c:2852 sql_help.c:2859 sql_help.c:2873 sql_help.c:2879 -#: sql_help.c:3131 sql_help.c:3138 sql_help.c:3152 sql_help.c:3158 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "スキーマå" -#: sql_help.c:179 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" -msgstr "権é™ä»˜ä¸Žï¼å‰¥å¥ªã®çœç•¥å½¢" +msgstr "GRANT/REVOKEã®çœç•¥å½¢" -#: sql_help.c:180 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" -msgstr "権é™ä»˜ä¸Žï¼å‰¥å¥ªã®çœç•¥å½¢ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" - -#: sql_help.c:181 sql_help.c:182 sql_help.c:183 sql_help.c:184 sql_help.c:185 -#: sql_help.c:186 sql_help.c:187 sql_help.c:188 sql_help.c:525 sql_help.c:587 -#: sql_help.c:891 sql_help.c:1743 sql_help.c:1744 sql_help.c:1745 -#: sql_help.c:1746 sql_help.c:1747 sql_help.c:1892 sql_help.c:1893 -#: sql_help.c:1894 sql_help.c:1895 sql_help.c:1896 sql_help.c:2316 -#: sql_help.c:2317 sql_help.c:2318 sql_help.c:2319 sql_help.c:2320 -#: sql_help.c:2853 sql_help.c:2857 sql_help.c:2860 sql_help.c:2862 -#: sql_help.c:2864 sql_help.c:2866 sql_help.c:2868 sql_help.c:2874 -#: sql_help.c:2876 sql_help.c:2878 sql_help.c:2880 sql_help.c:2882 -#: sql_help.c:2884 sql_help.c:2885 sql_help.c:2886 sql_help.c:3132 -#: sql_help.c:3136 sql_help.c:3139 sql_help.c:3141 sql_help.c:3143 -#: sql_help.c:3145 sql_help.c:3147 sql_help.c:3153 sql_help.c:3155 -#: sql_help.c:3157 sql_help.c:3159 sql_help.c:3161 sql_help.c:3163 -#: sql_help.c:3164 sql_help.c:3165 sql_help.c:3427 +msgstr "GRANT/REVOKEã®çœç•¥å½¢ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "ロールå" -#: sql_help.c:214 sql_help.c:414 sql_help.c:902 sql_help.c:904 sql_help.c:1166 -#: sql_help.c:1594 sql_help.c:1598 sql_help.c:1764 sql_help.c:2055 -#: sql_help.c:2065 sql_help.c:2087 sql_help.c:2900 sql_help.c:3303 -#: sql_help.c:3304 sql_help.c:3308 sql_help.c:3313 sql_help.c:3381 -#: sql_help.c:3382 sql_help.c:3387 sql_help.c:3392 sql_help.c:3521 -#: sql_help.c:3522 sql_help.c:3526 sql_help.c:3531 sql_help.c:3611 -#: sql_help.c:3613 sql_help.c:3644 sql_help.c:3690 sql_help.c:3691 -#: sql_help.c:3695 sql_help.c:3700 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "評価å¼" -#: sql_help.c:217 +#: sql_help.c:239 msgid "domain_constraint" msgstr "ドメイン制約" -#: sql_help.c:219 sql_help.c:221 sql_help.c:224 sql_help.c:884 sql_help.c:917 -#: sql_help.c:918 sql_help.c:919 sql_help.c:939 sql_help.c:1285 -#: sql_help.c:1597 sql_help.c:1672 sql_help.c:2054 sql_help.c:2064 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "制約å" -#: sql_help.c:222 sql_help.c:885 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "æ–°ã—ã„制約å" -#: sql_help.c:291 sql_help.c:794 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: sql_help.c:295 sql_help.c:297 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" -msgstr "メンãƒã‚ªãƒ–ジェクト" +msgstr "メンãƒãƒ¼ã‚ªãƒ–ジェクト" -#: sql_help.c:298 +#: sql_help.c:324 msgid "where member_object is:" -msgstr "メンãƒã‚ªãƒ–ジェクトã¯ä»¥ä¸‹ã®é€šã‚Š:" +msgstr "メンãƒãƒ¼ã‚ªãƒ–ジェクトã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 +msgid "object_name" +msgstr "オブジェクトå" -#: sql_help.c:299 sql_help.c:1278 sql_help.c:3233 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 msgid "aggregate_name" -msgstr "集約関数ã®åå‰" +msgstr "集約関数å" -#: sql_help.c:301 sql_help.c:1280 sql_help.c:1516 sql_help.c:1520 -#: sql_help.c:1522 sql_help.c:2435 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" -msgstr "ソースã®åž‹" +msgstr "変æ›å‰ã®åž‹" -#: sql_help.c:302 sql_help.c:1281 sql_help.c:1517 sql_help.c:1521 -#: sql_help.c:1523 sql_help.c:2436 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" -msgstr "ターゲットã®åž‹" - -#: sql_help.c:303 sql_help.c:304 sql_help.c:305 sql_help.c:306 sql_help.c:307 -#: sql_help.c:308 sql_help.c:313 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:322 sql_help.c:323 sql_help.c:324 sql_help.c:325 sql_help.c:326 -#: sql_help.c:327 sql_help.c:328 sql_help.c:329 sql_help.c:330 sql_help.c:331 -#: sql_help.c:1282 sql_help.c:1287 sql_help.c:1288 sql_help.c:1289 -#: sql_help.c:1290 sql_help.c:1291 sql_help.c:1292 sql_help.c:1293 -#: sql_help.c:1298 sql_help.c:1300 sql_help.c:1304 sql_help.c:1306 -#: sql_help.c:1308 sql_help.c:1309 sql_help.c:1312 sql_help.c:1313 -#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 -#: sql_help.c:1318 sql_help.c:1319 sql_help.c:1320 sql_help.c:1323 -#: sql_help.c:1324 sql_help.c:3230 sql_help.c:3235 sql_help.c:3236 -#: sql_help.c:3237 sql_help.c:3238 sql_help.c:3244 sql_help.c:3245 -#: sql_help.c:3246 sql_help.c:3247 sql_help.c:3248 sql_help.c:3249 -#: sql_help.c:3250 sql_help.c:3251 -msgid "object_name" -msgstr "オブジェクトå" - -#: sql_help.c:309 sql_help.c:665 sql_help.c:1294 sql_help.c:1518 -#: sql_help.c:1553 sql_help.c:1612 sql_help.c:1817 sql_help.c:1848 -#: sql_help.c:2207 sql_help.c:2869 sql_help.c:3148 sql_help.c:3239 -#: sql_help.c:3329 sql_help.c:3333 sql_help.c:3337 sql_help.c:3340 -#: sql_help.c:3547 sql_help.c:3551 sql_help.c:3555 sql_help.c:3558 -#: sql_help.c:3716 sql_help.c:3720 sql_help.c:3724 sql_help.c:3727 +msgstr "変æ›å¾Œã®åž‹" + +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "関数å" -#: sql_help.c:314 sql_help.c:658 sql_help.c:1301 sql_help.c:1841 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "演算å­å" -#: sql_help.c:315 sql_help.c:613 sql_help.c:617 sql_help.c:1302 -#: sql_help.c:1818 sql_help.c:2553 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "左辺ã®åž‹" -#: sql_help.c:316 sql_help.c:614 sql_help.c:618 sql_help.c:1303 -#: sql_help.c:1819 sql_help.c:2554 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "å³è¾ºã®åž‹" -#: sql_help.c:318 sql_help.c:320 sql_help.c:630 sql_help.c:633 sql_help.c:636 -#: sql_help.c:656 sql_help.c:668 sql_help.c:676 sql_help.c:679 sql_help.c:682 -#: sql_help.c:1305 sql_help.c:1307 sql_help.c:1838 sql_help.c:1859 -#: sql_help.c:2070 sql_help.c:2563 sql_help.c:2572 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "インデックスメソッド" -#: sql_help.c:332 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "プロシージャå" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "ルーãƒãƒ³å" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 +msgid "type_name" +msgstr "åž‹å" + +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 +msgid "lang_name" +msgstr "言語å" + +#: sql_help.c:369 msgid "and aggregate_signature is:" -msgstr "集約関数ã®å‘¼å‡ºã—情報ã¯ä»¥ä¸‹ã®é€šã‚Š" +msgstr "集約関数ã®ã‚·ã‚°ãƒ‹ãƒãƒ£ãƒ¼ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" -#: sql_help.c:355 sql_help.c:1638 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" -msgstr "ãƒãƒ³ãƒ‰ãƒ©é–¢æ•°" +msgstr "ãƒãƒ³ãƒ‰ãƒ©ãƒ¼é–¢æ•°" -#: sql_help.c:356 sql_help.c:1639 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" -msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚¿é–¢æ•°" +msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚¿ãƒ¼é–¢æ•°" -#: sql_help.c:397 sql_help.c:464 sql_help.c:578 sql_help.c:879 sql_help.c:1074 -#: sql_help.c:2061 sql_help.c:2062 sql_help.c:2078 sql_help.c:2079 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "アクション" -#: sql_help.c:399 sql_help.c:406 sql_help.c:410 sql_help.c:411 sql_help.c:413 -#: sql_help.c:415 sql_help.c:416 sql_help.c:417 sql_help.c:419 sql_help.c:422 -#: sql_help.c:424 sql_help.c:580 sql_help.c:590 sql_help.c:592 sql_help.c:595 -#: sql_help.c:597 sql_help.c:776 sql_help.c:881 sql_help.c:894 sql_help.c:898 -#: sql_help.c:899 sql_help.c:903 sql_help.c:905 sql_help.c:906 sql_help.c:907 -#: sql_help.c:909 sql_help.c:912 sql_help.c:914 sql_help.c:1165 -#: sql_help.c:1168 sql_help.c:1188 sql_help.c:1284 sql_help.c:1380 -#: sql_help.c:1385 sql_help.c:1399 sql_help.c:1400 sql_help.c:1401 -#: sql_help.c:1662 sql_help.c:1702 sql_help.c:1763 sql_help.c:1798 -#: sql_help.c:1954 sql_help.c:2034 sql_help.c:2047 sql_help.c:2066 -#: sql_help.c:2068 sql_help.c:2075 sql_help.c:2086 sql_help.c:2103 -#: sql_help.c:2210 sql_help.c:2346 sql_help.c:2854 sql_help.c:2855 -#: sql_help.c:2899 sql_help.c:3133 sql_help.c:3134 sql_help.c:3232 -#: sql_help.c:3352 sql_help.c:3570 sql_help.c:3610 sql_help.c:3612 -#: sql_help.c:3629 sql_help.c:3632 sql_help.c:3739 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "列å" -#: sql_help.c:400 sql_help.c:581 sql_help.c:882 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "æ–°ã—ã„列å" -#: sql_help.c:405 sql_help.c:480 sql_help.c:589 sql_help.c:893 sql_help.c:1087 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" -msgstr "アクションã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "アクションã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:407 sql_help.c:412 sql_help.c:895 sql_help.c:900 sql_help.c:1089 -#: sql_help.c:1093 sql_help.c:1592 sql_help.c:1663 sql_help.c:1837 -#: sql_help.c:2035 sql_help.c:2255 sql_help.c:2984 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "データ型" -#: sql_help.c:408 sql_help.c:896 sql_help.c:901 sql_help.c:1090 -#: sql_help.c:1094 sql_help.c:1593 sql_help.c:1666 sql_help.c:1765 -#: sql_help.c:2036 sql_help.c:2256 sql_help.c:2262 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "ç…§åˆé †åº" -#: sql_help.c:409 sql_help.c:897 sql_help.c:1667 sql_help.c:2037 -#: sql_help.c:2048 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" -msgstr "列制約" +msgstr "カラム制約" -#: sql_help.c:418 sql_help.c:591 sql_help.c:908 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "æ•´æ•°" -#: sql_help.c:420 sql_help.c:423 sql_help.c:593 sql_help.c:596 sql_help.c:910 -#: sql_help.c:913 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "属性オプション" -#: sql_help.c:427 sql_help.c:428 sql_help.c:429 sql_help.c:430 sql_help.c:920 -#: sql_help.c:921 sql_help.c:922 sql_help.c:923 sql_help.c:1321 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 +msgid "table_constraint" +msgstr "テーブル制約" + +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "トリガーå" -#: sql_help.c:481 sql_help.c:1705 +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 +msgid "parent_table" +msgstr "親テーブル" + +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 +msgid "extension_name" +msgstr "æ‹¡å¼µå" + +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "実行コスト" -#: sql_help.c:482 sql_help.c:1706 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "çµæžœã®è¡Œæ•°" -#: sql_help.c:497 sql_help.c:499 sql_help.c:501 -msgid "group_name" -msgstr "グループå" - -#: sql_help.c:498 sql_help.c:500 sql_help.c:1147 sql_help.c:1569 -#: sql_help.c:1930 sql_help.c:1932 sql_help.c:1935 sql_help.c:1936 -#: sql_help.c:2119 sql_help.c:2331 sql_help.c:2702 sql_help.c:3437 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 +msgid "role_specification" +msgstr "ãƒ­ãƒ¼ãƒ«ã®æŒ‡å®š" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "ユーザå" -#: sql_help.c:518 sql_help.c:1574 sql_help.c:1769 sql_help.c:1801 -#: sql_help.c:2044 sql_help.c:2052 sql_help.c:2084 sql_help.c:2106 -#: sql_help.c:2118 sql_help.c:2881 sql_help.c:3160 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 +msgid "where role_specification can be:" +msgstr "ロール指定ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:569 +msgid "group_name" +msgstr "グループå" + +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" -msgstr "テーブルスペースå" +msgstr "テーブル空間å" + +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "インデックスå" -#: sql_help.c:520 sql_help.c:523 sql_help.c:599 sql_help.c:601 sql_help.c:929 -#: sql_help.c:931 sql_help.c:1767 sql_help.c:1799 sql_help.c:2042 -#: sql_help.c:2050 sql_help.c:2082 sql_help.c:2104 +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "ストレージパラメーター" -#: sql_help.c:546 sql_help.c:1299 sql_help.c:3243 +#: sql_help.c:601 +msgid "column_number" +msgstr "列番å·" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" -msgstr "ラージオブジェクトã®oid" +msgstr "ラージオブジェクトã®OID" -#: sql_help.c:598 sql_help.c:928 sql_help.c:937 sql_help.c:940 sql_help.c:1228 -msgid "index_name" -msgstr "インデックスå" +#: sql_help.c:712 sql_help.c:2402 +msgid "res_proc" +msgstr "åˆ¶ç´„é¸æŠžè©•ä¾¡é–¢æ•°" + +#: sql_help.c:713 sql_help.c:2403 +msgid "join_proc" +msgstr "çµåˆé¸æŠžè©•価関数" -#: sql_help.c:657 sql_help.c:669 sql_help.c:1840 +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" -msgstr "ストラテジー番å·" +msgstr "戦略番å·" -#: sql_help.c:659 sql_help.c:660 sql_help.c:663 sql_help.c:664 sql_help.c:670 -#: sql_help.c:671 sql_help.c:673 sql_help.c:674 sql_help.c:1842 -#: sql_help.c:1843 sql_help.c:1846 sql_help.c:1847 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 +#: sql_help.c:2423 sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "演算å­ã®åž‹" -#: sql_help.c:661 sql_help.c:1844 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "ソートファミリーå" -#: sql_help.c:662 sql_help.c:672 sql_help.c:1845 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "サãƒãƒ¼ãƒˆç•ªå·" -#: sql_help.c:666 sql_help.c:1519 sql_help.c:1849 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "引数ã®åž‹" -#: sql_help.c:715 sql_help.c:1126 sql_help.c:1741 sql_help.c:1890 -#: sql_help.c:2314 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 +msgid "table_name" +msgstr "テーブルå" + +#: sql_help.c:810 sql_help.c:2455 +msgid "using_expression" +msgstr "USING表ç¾" + +#: sql_help.c:811 sql_help.c:2456 +msgid "check_expression" +msgstr "CHECK表ç¾" + +#: sql_help.c:885 sql_help.c:2497 +msgid "publication_parameter" +msgstr "パブリケーションパラメーター" + +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "パスワード" -#: sql_help.c:716 sql_help.c:1127 sql_help.c:1742 sql_help.c:1891 -#: sql_help.c:2315 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "タイムスタンプ" -#: sql_help.c:720 sql_help.c:724 sql_help.c:727 sql_help.c:730 sql_help.c:2861 -#: sql_help.c:3140 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "データベースå" -#: sql_help.c:739 sql_help.c:775 sql_help.c:1053 sql_help.c:1187 -#: sql_help.c:1227 sql_help.c:1286 sql_help.c:1311 sql_help.c:1322 -#: sql_help.c:1379 sql_help.c:1384 sql_help.c:1661 sql_help.c:1761 -#: sql_help.c:1797 sql_help.c:1913 sql_help.c:1953 sql_help.c:2033 -#: sql_help.c:2045 sql_help.c:2102 sql_help.c:2204 sql_help.c:2380 -#: sql_help.c:2597 sql_help.c:2678 sql_help.c:2851 sql_help.c:2856 -#: sql_help.c:2898 sql_help.c:3130 sql_help.c:3135 sql_help.c:3231 -#: sql_help.c:3318 sql_help.c:3320 sql_help.c:3358 sql_help.c:3397 -#: sql_help.c:3536 sql_help.c:3538 sql_help.c:3576 sql_help.c:3608 -#: sql_help.c:3628 sql_help.c:3630 sql_help.c:3631 sql_help.c:3705 -#: sql_help.c:3707 sql_help.c:3745 -msgid "table_name" -msgstr "テーブルå" - -#: sql_help.c:769 sql_help.c:1948 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" -msgstr "増分" +msgstr "増分値" -#: sql_help.c:770 sql_help.c:1949 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "最å°å€¤" -#: sql_help.c:771 sql_help.c:1950 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "最大値" -#: sql_help.c:772 sql_help.c:1951 sql_help.c:3316 sql_help.c:3395 -#: sql_help.c:3534 sql_help.c:3648 sql_help.c:3703 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" -msgstr "開始値" +msgstr "開始番å·" -#: sql_help.c:773 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" -msgstr "å†é–‹å§‹å€¤" +msgstr "å†é–‹å§‹ç•ªå·" -#: sql_help.c:774 sql_help.c:1952 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" -msgstr "キャッシュ" +msgstr "ã‚­ãƒ£ãƒƒã‚·ãƒ¥å‰²ã‚Šå½“ã¦æ•°" -#: sql_help.c:915 sql_help.c:2038 sql_help.c:2049 -msgid "table_constraint" -msgstr "テーブル制約" +#: sql_help.c:1109 sql_help.c:2646 +msgid "conninfo" +msgstr "接続文字列" + +#: sql_help.c:1111 sql_help.c:2647 +msgid "publication_name" +msgstr "パブリケーションå" + +#: sql_help.c:1112 +msgid "set_publication_option" +msgstr "{SET PUBLICATION ã®è¿½åŠ ã‚ªãƒ—ã‚·ãƒ§ãƒ³}" + +#: sql_help.c:1115 +msgid "refresh_option" +msgstr "{REFRESH PUBLICATION ã®è¿½åŠ ã‚ªãƒ—ã‚·ãƒ§ãƒ³}" + +#: sql_help.c:1120 sql_help.c:2648 +msgid "subscription_parameter" +msgstr "{SUBSCRIPTION パラメーターå}" -#: sql_help.c:916 +#: sql_help.c:1273 sql_help.c:1276 +msgid "partition_name" +msgstr "パーティションå" + +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 +msgid "partition_bound_spec" +msgstr "パーティション境界ã®ä»•様" + +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 +msgid "sequence_options" +msgstr "シーケンスオプション" + +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "シーケンスオプション" + +#: sql_help.c:1306 msgid "table_constraint_using_index" -msgstr "インデックスを使用ã™ã‚‹ãƒ†ãƒ¼ãƒ–ル制約" +msgstr "インデックスを使ã†ãƒ†ãƒ¼ãƒ–ルã®åˆ¶ç´„" -#: sql_help.c:924 sql_help.c:925 sql_help.c:926 sql_help.c:927 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«å" -#: sql_help.c:932 sql_help.c:933 sql_help.c:2041 -msgid "parent_table" -msgstr "親テーブル" +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "パーティション境界ã®ä»•様ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" -#: sql_help.c:934 sql_help.c:2046 sql_help.c:2883 sql_help.c:3162 -msgid "type_name" -msgstr "åž‹å" +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "数値定数" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "文字列定数" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "ãã—ã¦ã‚«ãƒ©ãƒ åˆ¶ç´„ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "デフォルト表ç¾" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "インデックスパラメーター" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "å‚照テーブル" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "å‚照列" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "テーブル制約ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "除外対象è¦ç´ " + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "演算å­" -#: sql_help.c:938 +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "インデックスã®è¿°èªž" + +#: sql_help.c:1365 msgid "and table_constraint_using_index is:" -msgstr "ã¾ãŸã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’使用ã™ã‚‹ãƒ†ãƒ¼ãƒ–ルã®åˆ¶ç´„æ¡ä»¶ã¯ä»¥ä¸‹ã®é€šã‚Š:" +msgstr "テーブル制約ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "" +"UNIQUE, PRIMARY KEY, EXCLUDE 制約ã®ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ãƒ‘ラメーターã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "EXCLUDE 制約ã®é™¤å¤–対象è¦ç´ ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "演算å­ã‚¯ãƒ©ã‚¹" -#: sql_help.c:956 sql_help.c:959 sql_help.c:2121 +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" -msgstr "テーブルスペース・オプション" +msgstr "テーブル空間ã®ã‚ªãƒ—ション" -#: sql_help.c:980 sql_help.c:983 sql_help.c:989 sql_help.c:993 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "トークンã®åž‹" -#: sql_help.c:981 sql_help.c:984 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "辞書å" -#: sql_help.c:986 sql_help.c:990 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "å…ƒã®è¾žæ›¸" -#: sql_help.c:987 sql_help.c:991 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "æ–°ã—ã„辞書" -#: sql_help.c:1078 sql_help.c:1088 sql_help.c:1091 sql_help.c:1092 -#: sql_help.c:2254 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "属性å" -#: sql_help.c:1079 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "æ–°ã—ã„属性å" -#: sql_help.c:1085 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "æ–°ã—ã„列挙値" -#: sql_help.c:1086 +#: sql_help.c:1527 +msgid "neighbor_enum_value" +msgstr "隣接ã—ãŸåˆ—挙値" + +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "既存ã®åˆ—挙値" -#: sql_help.c:1148 sql_help.c:1668 sql_help.c:1964 sql_help.c:2332 -#: sql_help.c:2703 sql_help.c:2867 sql_help.c:3146 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" -msgstr "サーãƒãƒ¼å" +msgstr "サーãƒå" -#: sql_help.c:1176 sql_help.c:1179 sql_help.c:2347 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "ビューã®ã‚ªãƒ—ションå" -#: sql_help.c:1177 sql_help.c:2348 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" -msgstr "ビューã®ã‚ªãƒ—ション値" +msgstr "ビューオプションã®å€¤" + +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "テーブルãŠã‚ˆã³åˆ—" -#: sql_help.c:1202 sql_help.c:3453 sql_help.c:3455 sql_help.c:3479 +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "オプションã«ã¯ä»¥ä¸‹ã®ã†ã¡ã®ã„ãšã‚Œã‹ã‚’指定ã—ã¾ã™:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "ãã—ã¦ãƒ†ãƒ¼ãƒ–ルã¨åˆ—ã®æŒ‡å®šã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "トランザクションã®ãƒ¢ãƒ¼ãƒ‰" -#: sql_help.c:1203 sql_help.c:3456 sql_help.c:3480 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" -msgstr "トランザクションã®ãƒ¢ãƒ¼ãƒ‰ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "トランザクションã®ãƒ¢ãƒ¼ãƒ‰ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" + +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "引数" -#: sql_help.c:1283 +#: sql_help.c:1772 msgid "relation_name" -msgstr "æ‹¡å¼µå" +msgstr "リレーションå" + +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 +msgid "domain_name" +msgstr "ドメインå" -#: sql_help.c:1310 +#: sql_help.c:1799 +msgid "policy_name" +msgstr "ãƒãƒªã‚·ãƒ¼å" + +#: sql_help.c:1812 msgid "rule_name" -msgstr "ロールå" +msgstr "ルールå" -#: sql_help.c:1325 +#: sql_help.c:1831 msgid "text" -msgstr "テキスト" +msgstr "コメント文字列" -#: sql_help.c:1350 sql_help.c:2993 sql_help.c:3180 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" -msgstr "トランザクション ID" +msgstr "トランザクションID" -#: sql_help.c:1381 sql_help.c:1387 sql_help.c:2919 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "ファイルå" -#: sql_help.c:1382 sql_help.c:1388 sql_help.c:1915 sql_help.c:1916 -#: sql_help.c:1917 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "コマンド" -#: sql_help.c:1386 sql_help.c:1802 sql_help.c:2107 sql_help.c:2349 -#: sql_help.c:2367 sql_help.c:2901 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "å•ã„åˆã‚ã›" -#: sql_help.c:1390 sql_help.c:2748 -msgid "where option can be one of:" -msgstr "オプションã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" - -#: sql_help.c:1391 +#: sql_help.c:1897 msgid "format_name" msgstr "フォーマットå" -#: sql_help.c:1392 sql_help.c:1393 sql_help.c:1396 sql_help.c:2749 -#: sql_help.c:2750 sql_help.c:2751 sql_help.c:2752 sql_help.c:2753 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" -msgstr "ブール値" +msgstr "真å½å€¤" -#: sql_help.c:1394 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "区切り文字" -#: sql_help.c:1395 +#: sql_help.c:1901 msgid "null_string" -msgstr "null文字列" +msgstr "NULL文字列" -#: sql_help.c:1397 +#: sql_help.c:1903 msgid "quote_character" msgstr "引用符文字" -#: sql_help.c:1398 +#: sql_help.c:1904 msgid "escape_character" msgstr "エスケープ文字" -#: sql_help.c:1402 +#: sql_help.c:1908 msgid "encoding_name" msgstr "エンコーディングå" -#: sql_help.c:1459 sql_help.c:1475 sql_help.c:1478 +#: sql_help.c:1919 +msgid "access_method_type" +msgstr "アクセスメソッドã®åž‹" + +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "入力データ型" -#: sql_help.c:1460 sql_help.c:1479 sql_help.c:1487 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "状態é·ç§»é–¢æ•°" -#: sql_help.c:1461 sql_help.c:1480 sql_help.c:1488 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "状態データã®åž‹" -#: sql_help.c:1462 sql_help.c:1481 sql_help.c:1489 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" -msgstr "状態データã®å¤§ãã•" +msgstr "状態データã®ã‚µã‚¤ã‚º" -#: sql_help.c:1463 sql_help.c:1482 sql_help.c:1490 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "終了関数" -#: sql_help.c:1464 sql_help.c:1483 sql_help.c:1491 +#: sql_help.c:1995 sql_help.c:2025 +msgid "combinefunc" +msgstr "çµåˆé–¢æ•°" + +#: sql_help.c:1996 sql_help.c:2026 +msgid "serialfunc" +msgstr "シリアライズ関数" + +#: sql_help.c:1997 sql_help.c:2027 +msgid "deserialfunc" +msgstr "デシリアライズ関数" + +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "åˆæœŸæ¡ä»¶" -#: sql_help.c:1465 sql_help.c:1492 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "剿–¹çŠ¶æ…‹é·ç§»é–¢æ•°" -#: sql_help.c:1466 sql_help.c:1493 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "逆状態é·ç§»é–¢æ•°" -#: sql_help.c:1467 sql_help.c:1494 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" -msgstr "移動集約モードã§ã®çŠ¶æ…‹ãƒ‡ãƒ¼ã‚¿ã®åž‹" +msgstr "移動集約モード時ã®çŠ¶æ…‹å€¤ã®ãƒ‡ãƒ¼ã‚¿åž‹" -#: sql_help.c:1468 sql_help.c:1495 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" -msgstr "移動集約モードã§ã®çŠ¶æ…‹ãƒ‡ãƒ¼ã‚¿ã®å¤§ãã•" +msgstr "移動集約モード時ã®çŠ¶æ…‹å€¤ã®ãƒ‡ãƒ¼ã‚¿ã‚µã‚¤ã‚º" -#: sql_help.c:1469 sql_help.c:1496 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" -msgstr "移動集約モードã§ã®çµ‚了関数" +msgstr "移動集約モード時ã®çµ‚了関数" -#: sql_help.c:1470 sql_help.c:1497 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" -msgstr "移動集約モードã§ã®åˆæœŸæ¡ä»¶" +msgstr "移動集約モード時ã®åˆæœŸæ¡ä»¶" -#: sql_help.c:1471 sql_help.c:1498 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "ソート演算å­" -#: sql_help.c:1484 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "ã¾ãŸã¯å¤ã„æ§‹æ–‡" -#: sql_help.c:1486 +#: sql_help.c:2020 msgid "base_type" msgstr "基本ã®åž‹" -#: sql_help.c:1537 +#: sql_help.c:2076 msgid "locale" msgstr "ロケール" -#: sql_help.c:1538 sql_help.c:1572 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "ç…§åˆé †åº" -#: sql_help.c:1539 sql_help.c:1573 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "Ctype(å¤‰æ›æ¼”ç®—å­)" -#: sql_help.c:1541 +#: sql_help.c:2079 sql_help.c:4122 +msgid "provider" +msgstr "プロãƒã‚¤ãƒ€" + +#: sql_help.c:2080 sql_help.c:2171 +msgid "version" +msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³" + +#: sql_help.c:2082 msgid "existing_collation" msgstr "既存ã®ç…§åˆé †åº" -#: sql_help.c:1551 +#: sql_help.c:2092 msgid "source_encoding" msgstr "変æ›å…ƒã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°" -#: sql_help.c:1552 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "変æ›å…ˆã®ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚°" -#: sql_help.c:1570 sql_help.c:2147 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "テンプレート" -#: sql_help.c:1571 +#: sql_help.c:2114 msgid "encoding" -msgstr "エンコーディング" +msgstr "エンコード" + +#: sql_help.c:2140 +msgid "constraint" +msgstr "制約æ¡ä»¶" -#: sql_help.c:1596 +#: sql_help.c:2141 msgid "where constraint is:" -msgstr "制約æ¡ä»¶ï¼š" +msgstr "制約æ¡ä»¶ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" -#: sql_help.c:1610 sql_help.c:1912 sql_help.c:2203 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "イベント" -#: sql_help.c:1611 +#: sql_help.c:2156 msgid "filter_variable" -msgstr "フィルタ変数" - -#: sql_help.c:1623 -msgid "extension_name" -msgstr "æ‹¡å¼µå" - -#: sql_help.c:1625 -msgid "version" -msgstr "ãƒãƒ¼ã‚¸ãƒ§ãƒ³" +msgstr "フィルター変数" -#: sql_help.c:1626 +#: sql_help.c:2172 msgid "old_version" -msgstr "å¤ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³" +msgstr "æ—§ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: sql_help.c:1671 sql_help.c:2053 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" -msgstr "列制約:" - -#: sql_help.c:1673 sql_help.c:1700 sql_help.c:2056 -msgid "default_expr" -msgstr "デフォルトã®è©•価å¼" +msgstr "カラム制約ã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" -#: sql_help.c:1701 +#: sql_help.c:2280 msgid "rettype" msgstr "戻り値ã®åž‹" -#: sql_help.c:1703 +#: sql_help.c:2282 msgid "column_type" msgstr "列ã®åž‹" -#: sql_help.c:1704 sql_help.c:2401 sql_help.c:2875 sql_help.c:3154 -msgid "lang_name" -msgstr "言語" - -#: sql_help.c:1710 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "定義" -#: sql_help.c:1711 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "オブジェクトファイルå" -#: sql_help.c:1712 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "リンクシンボル" -#: sql_help.c:1713 -msgid "attribute" -msgstr "属性" - -#: sql_help.c:1748 sql_help.c:1897 sql_help.c:2321 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" -msgstr "ユーザーID" +msgstr "UID" -#: sql_help.c:1762 +#: sql_help.c:2341 msgid "method" -msgstr "メソッド" - -#: sql_help.c:1766 sql_help.c:2088 -msgid "opclass" -msgstr "演算å­ã‚¯ãƒ©ã‚¹" - -#: sql_help.c:1770 sql_help.c:2074 -msgid "predicate" -msgstr "述語" +msgstr "インデックスメソッド" -#: sql_help.c:1782 +#: sql_help.c:2362 msgid "call_handler" msgstr "呼ã³å‡ºã—ãƒãƒ³ãƒ‰ãƒ©ãƒ¼" -#: sql_help.c:1783 +#: sql_help.c:2363 msgid "inline_handler" msgstr "インラインãƒãƒ³ãƒ‰ãƒ©ãƒ¼" -#: sql_help.c:1784 +#: sql_help.c:2364 msgid "valfunction" -msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚¿é–¢æ•°" +msgstr "ãƒãƒªãƒ‡ãƒ¼ã‚·ãƒ§ãƒ³é–¢æ•°" -#: sql_help.c:1820 +#: sql_help.c:2400 msgid "com_op" -msgstr "交æ›ç”¨æ¼”ç®—å­" +msgstr "交代演算å­" -#: sql_help.c:1821 +#: sql_help.c:2401 msgid "neg_op" -msgstr "å¦å®šç”¨æ¼”ç®—å­" +msgstr "å¦å®šæ¼”ç®—å­" -#: sql_help.c:1822 -msgid "res_proc" -msgstr "制約手続ã" - -#: sql_help.c:1823 -msgid "join_proc" -msgstr "JOIN手続ã" - -#: sql_help.c:1839 +#: sql_help.c:2419 msgid "family_name" -msgstr "ファミリーå" +msgstr "æ¼”ç®—å­æ—ã®åå‰" -#: sql_help.c:1850 +#: sql_help.c:2430 msgid "storage_type" -msgstr "ストレージã®åž‹" +msgstr "ストレージタイプ" -#: sql_help.c:1914 sql_help.c:2206 sql_help.c:2383 sql_help.c:3307 -#: sql_help.c:3309 sql_help.c:3386 sql_help.c:3388 sql_help.c:3525 -#: sql_help.c:3527 sql_help.c:3615 sql_help.c:3694 sql_help.c:3696 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "æ¡ä»¶" -#: sql_help.c:1918 sql_help.c:2209 +#: sql_help.c:2557 sql_help.c:2961 msgid "where event can be one of:" -msgstr "イベントã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "イベントã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:1931 sql_help.c:1933 +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "スキーマè¦ç´ " -#: sql_help.c:1965 +#: sql_help.c:2615 msgid "server_type" -msgstr "サーãƒãƒ¼ã®ã‚¿ã‚¤ãƒ—" +msgstr "サーãƒã®ã‚¿ã‚¤ãƒ—" -#: sql_help.c:1966 +#: sql_help.c:2616 msgid "server_version" -msgstr "サーãƒãƒ¼ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³" +msgstr "サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³" -#: sql_help.c:1967 sql_help.c:2865 sql_help.c:3144 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" -msgstr "外部データラッパー" - -#: sql_help.c:2039 -msgid "source_table" -msgstr "ソースã®ãƒ†ãƒ¼ãƒ–ル" - -#: sql_help.c:2040 -msgid "like_option" -msgstr "LIKE オプション:" +msgstr "外部データラッパå" -#: sql_help.c:2057 sql_help.c:2058 sql_help.c:2067 sql_help.c:2069 -#: sql_help.c:2073 -msgid "index_parameters" -msgstr "インデックスã®ãƒ‘ラメーター" - -#: sql_help.c:2059 sql_help.c:2076 -msgid "reftable" -msgstr "å‚照テーブル" +#: sql_help.c:2630 +msgid "statistics_name" +msgstr "統計オブジェクトå" -#: sql_help.c:2060 sql_help.c:2077 -msgid "refcolumn" -msgstr "å‚照列" +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "統計種別" -#: sql_help.c:2063 -msgid "and table_constraint is:" -msgstr "テーブル制約:" +#: sql_help.c:2645 +msgid "subscription_name" +msgstr "サブスクリプションå" -#: sql_help.c:2071 -msgid "exclude_element" -msgstr "排他è¦ç´ " +#: sql_help.c:2741 +msgid "source_table" +msgstr "コピー元ã®ãƒ†ãƒ¼ãƒ–ル" -#: sql_help.c:2072 sql_help.c:3314 sql_help.c:3393 sql_help.c:3532 -#: sql_help.c:3646 sql_help.c:3701 -msgid "operator" -msgstr "演算å­" +#: sql_help.c:2742 +msgid "like_option" +msgstr "LIKEオプション" -#: sql_help.c:2080 +#: sql_help.c:2804 msgid "and like_option is:" -msgstr "LIKE オプション:" - -#: sql_help.c:2081 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "UNIQUE, PRIMARY KEY, EXCLUDE ã«ãŠã‘るインデックスパラメーターã®åˆ¶ç´„æ¡ä»¶ï¼š" - -#: sql_help.c:2085 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "EXCLUDE ã«ãŠã‘る排他è¦ç´ ã®åˆ¶ç´„æ¡ä»¶ï¼š" +msgstr "LIKE オプションã¯ä»¥ä¸‹ã®é€šã‚Šã§ã™:" -#: sql_help.c:2120 +#: sql_help.c:2854 msgid "directory" -msgstr "ディレクトリー" +msgstr "ディレクトリ" -#: sql_help.c:2134 +#: sql_help.c:2868 msgid "parser_name" -msgstr "パーサーå" +msgstr "パーサå" -#: sql_help.c:2135 +#: sql_help.c:2869 msgid "source_config" -msgstr "ソース設定" +msgstr "複製元ã®è¨­å®š" -#: sql_help.c:2164 +#: sql_help.c:2898 msgid "start_function" msgstr "開始関数" -#: sql_help.c:2165 +#: sql_help.c:2899 msgid "gettoken_function" -msgstr "トークンå–得用関数" +msgstr "トークンå–得関数" -#: sql_help.c:2166 +#: sql_help.c:2900 msgid "end_function" msgstr "終了関数" -#: sql_help.c:2167 +#: sql_help.c:2901 msgid "lextypes_function" -msgstr "LEX åž‹ã®é–¢æ•°" +msgstr "LEXTYPE関数" -#: sql_help.c:2168 +#: sql_help.c:2902 msgid "headline_function" msgstr "見出ã—関数" -#: sql_help.c:2180 +#: sql_help.c:2914 msgid "init_function" msgstr "åˆæœŸå‡¦ç†é–¢æ•°" -#: sql_help.c:2181 +#: sql_help.c:2915 msgid "lexize_function" -msgstr "LEX 処ç†é–¢æ•°" +msgstr "LEXIZE関数" -#: sql_help.c:2205 +#: sql_help.c:2928 +msgid "from_sql_function_name" +msgstr "{FROM SQL 関数å}" + +#: sql_help.c:2930 +msgid "to_sql_function_name" +msgstr "{TO SQL 関数å}" + +#: sql_help.c:2956 msgid "referenced_table_name" -msgstr "éžå‚照テーブルå" +msgstr "被å‚照テーブルå" -#: sql_help.c:2208 +#: sql_help.c:2957 +msgid "transition_relation_name" +msgstr "移行用リレーションå" + +#: sql_help.c:2960 msgid "arguments" msgstr "引数" -#: sql_help.c:2258 sql_help.c:3252 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "ラベル" -#: sql_help.c:2260 +#: sql_help.c:3012 msgid "subtype" -msgstr "派生元型" +msgstr "当該範囲ã®ãƒ‡ãƒ¼ã‚¿åž‹" -#: sql_help.c:2261 +#: sql_help.c:3013 msgid "subtype_operator_class" -msgstr "æ´¾ç”Ÿå…ƒåž‹ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹" +msgstr "当該範囲ã®ãƒ‡ãƒ¼ã‚¿åž‹ã®æ¼”ç®—å­ã‚¯ãƒ©ã‚¹" -#: sql_help.c:2263 +#: sql_help.c:3015 msgid "canonical_function" msgstr "æ­£è¦åŒ–関数" -#: sql_help.c:2264 +#: sql_help.c:3016 msgid "subtype_diff_function" -msgstr "派生元型差異関数" +msgstr "当該範囲ã®ãƒ‡ãƒ¼ã‚¿åž‹ã®å·®åˆ†æŠ½å‡ºé–¢æ•°" -#: sql_help.c:2266 +#: sql_help.c:3018 msgid "input_function" msgstr "入力関数" -#: sql_help.c:2267 +#: sql_help.c:3019 msgid "output_function" msgstr "出力関数" -#: sql_help.c:2268 +#: sql_help.c:3020 msgid "receive_function" msgstr "å—信関数" -#: sql_help.c:2269 +#: sql_help.c:3021 msgid "send_function" msgstr "é€ä¿¡é–¢æ•°" -#: sql_help.c:2270 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "型修飾å­ã®å…¥åŠ›é–¢æ•°" -#: sql_help.c:2271 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "型修飾å­ã®å‡ºåŠ›é–¢æ•°" -#: sql_help.c:2272 +#: sql_help.c:3024 msgid "analyze_function" msgstr "分æžé–¢æ•°" -#: sql_help.c:2273 +#: sql_help.c:3025 msgid "internallength" msgstr "内部長" -#: sql_help.c:2274 +#: sql_help.c:3026 msgid "alignment" -msgstr "アラインメント" +msgstr "ãƒã‚¤ãƒˆå¢ƒç•Œ" -#: sql_help.c:2275 +#: sql_help.c:3027 msgid "storage" msgstr "ストレージ" -#: sql_help.c:2276 +#: sql_help.c:3028 msgid "like_type" msgstr "LIKEã®åž‹" -#: sql_help.c:2277 +#: sql_help.c:3029 msgid "category" msgstr "カテゴリー" -#: sql_help.c:2278 +#: sql_help.c:3030 msgid "preferred" -msgstr "推奨" +msgstr "優先データ型ã‹ã©ã†ã‹ï¼ˆçœŸå½å€¤ï¼‰" -#: sql_help.c:2279 +#: sql_help.c:3031 msgid "default" msgstr "デフォルト" -#: sql_help.c:2280 +#: sql_help.c:3032 msgid "element" -msgstr "è¦ç´ " +msgstr "è¦ç´ ã®ãƒ‡ãƒ¼ã‚¿åž‹" -#: sql_help.c:2281 +#: sql_help.c:3033 msgid "delimiter" -msgstr "デリミタ" +msgstr "区切り記å·" -#: sql_help.c:2282 +#: sql_help.c:3034 msgid "collatable" -msgstr "ç…§åˆé †åº" +msgstr "ç…§åˆå¯èƒ½" -#: sql_help.c:2379 sql_help.c:2897 sql_help.c:3302 sql_help.c:3380 -#: sql_help.c:3520 sql_help.c:3607 sql_help.c:3689 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "WITHå•ã„åˆã‚ã›" -#: sql_help.c:2381 sql_help.c:3321 sql_help.c:3324 sql_help.c:3327 -#: sql_help.c:3331 sql_help.c:3335 sql_help.c:3343 sql_help.c:3539 -#: sql_help.c:3542 sql_help.c:3545 sql_help.c:3549 sql_help.c:3553 -#: sql_help.c:3561 sql_help.c:3609 sql_help.c:3708 sql_help.c:3711 -#: sql_help.c:3714 sql_help.c:3718 sql_help.c:3722 sql_help.c:3730 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" -msgstr "別å" +msgstr "エイリアス" -#: sql_help.c:2382 +#: sql_help.c:3134 msgid "using_list" -msgstr "USING リスト" +msgstr "USINGリスト" -#: sql_help.c:2384 sql_help.c:2779 sql_help.c:2960 sql_help.c:3616 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "カーソルå" -#: sql_help.c:2385 sql_help.c:2902 sql_help.c:3617 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "出力表ç¾" -#: sql_help.c:2386 sql_help.c:2903 sql_help.c:3305 sql_help.c:3383 -#: sql_help.c:3523 sql_help.c:3618 sql_help.c:3692 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "出力å" -#: sql_help.c:2402 +#: sql_help.c:3154 msgid "code" -msgstr "コード" +msgstr "コードブロック" -#: sql_help.c:2727 +#: sql_help.c:3553 msgid "parameter" msgstr "パラメータ" -#: sql_help.c:2746 sql_help.c:2747 sql_help.c:2985 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "ステートメント" -#: sql_help.c:2778 sql_help.c:2959 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" -msgstr "æ–¹å‘" +msgstr "å–ã‚Šå‡ºã™æ–¹å‘ã¨è¡Œæ•°" -#: sql_help.c:2780 sql_help.c:2961 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" -msgstr "æ–¹å‘ã¯ç„¡æŒ‡å®šã‚‚ã—ãã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "å–ã‚Šå‡ºã™æ–¹å‘ã¨è¡Œæ•°ã¯ç„¡æŒ‡å®šã‚‚ã—ãã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:2781 sql_help.c:2782 sql_help.c:2783 sql_help.c:2784 -#: sql_help.c:2785 sql_help.c:2962 sql_help.c:2963 sql_help.c:2964 -#: sql_help.c:2965 sql_help.c:2966 sql_help.c:3315 sql_help.c:3317 -#: sql_help.c:3394 sql_help.c:3396 sql_help.c:3533 sql_help.c:3535 -#: sql_help.c:3647 sql_help.c:3649 sql_help.c:3702 sql_help.c:3704 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" -msgstr "カウント" +msgstr "å–り出ã™ä½ç½®ã‚„行数" -#: sql_help.c:2858 sql_help.c:3137 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "シーケンスå" -#: sql_help.c:2863 sql_help.c:3142 -msgid "domain_name" -msgstr "ドメインå" - -#: sql_help.c:2871 sql_help.c:3150 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "引数å" -#: sql_help.c:2872 sql_help.c:3151 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "引数ã®åž‹" -#: sql_help.c:2877 sql_help.c:3156 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "ラージオブジェクトid" -#: sql_help.c:2911 sql_help.c:2974 sql_help.c:3593 +#: sql_help.c:3735 +msgid "remote_schema" +msgstr "リモートスキーマ" + +#: sql_help.c:3738 +msgid "local_schema" +msgstr "ローカルスキーマ" + +#: sql_help.c:3773 +msgid "conflict_target" +msgstr "ç«¶åˆã‚¿ãƒ¼ã‚²ãƒƒãƒˆ" + +#: sql_help.c:3774 +msgid "conflict_action" +msgstr "ç«¶åˆæ™‚アクション" + +#: sql_help.c:3777 +msgid "where conflict_target can be one of:" +msgstr "ç«¶åˆã‚¿ãƒ¼ã‚²ãƒƒãƒˆã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" + +#: sql_help.c:3778 +msgid "index_column_name" +msgstr "インデックスã®ã‚«ãƒ©ãƒ å" + +#: sql_help.c:3779 +msgid "index_expression" +msgstr "インデックス表ç¾" + +#: sql_help.c:3782 +msgid "index_predicate" +msgstr "インデックスã®è¿°èªž" + +#: sql_help.c:3784 +msgid "and conflict_action is one of:" +msgstr "ç«¶åˆæ™‚アクションã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" + +#: sql_help.c:3790 sql_help.c:4562 +msgid "sub-SELECT" +msgstr "副å•ã„åˆã‚ã›å¥" + +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "ãƒãƒ£ãƒãƒ«" -#: sql_help.c:2933 +#: sql_help.c:3821 msgid "lockmode" msgstr "ロックモード" -#: sql_help.c:2934 +#: sql_help.c:3822 msgid "where lockmode is one of:" -msgstr "ロックモードã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "ロックモードã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:2975 +#: sql_help.c:3863 msgid "payload" msgstr "ペイロード" -#: sql_help.c:3001 +#: sql_help.c:3890 msgid "old_role" msgstr "å…ƒã®ãƒ­ãƒ¼ãƒ«" -#: sql_help.c:3002 +#: sql_help.c:3891 msgid "new_role" msgstr "æ–°ã—ã„ロール" -#: sql_help.c:3027 sql_help.c:3188 sql_help.c:3196 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "セーブãƒã‚¤ãƒ³ãƒˆå" -#: sql_help.c:3229 -msgid "provider" -msgstr "プロãƒã‚¤ãƒ€" - -#: sql_help.c:3306 sql_help.c:3345 sql_help.c:3347 sql_help.c:3385 -#: sql_help.c:3524 sql_help.c:3563 sql_help.c:3565 sql_help.c:3693 -#: sql_help.c:3732 sql_help.c:3734 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" -msgstr "FROM é …ç›®" +msgstr "FROMé …ç›®" -#: sql_help.c:3310 sql_help.c:3389 sql_help.c:3528 sql_help.c:3697 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 +msgid "grouping_element" +msgstr "グルーピングè¦ç´ " + +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "ウィンドウå" -#: sql_help.c:3311 sql_help.c:3390 sql_help.c:3529 sql_help.c:3698 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "ウィンドウ定義" -#: sql_help.c:3312 sql_help.c:3323 sql_help.c:3353 sql_help.c:3391 -#: sql_help.c:3530 sql_help.c:3541 sql_help.c:3571 sql_help.c:3699 -#: sql_help.c:3710 sql_help.c:3740 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "SELECTå¥" -#: sql_help.c:3319 sql_help.c:3537 sql_help.c:3706 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" -msgstr "FROMé …ç›®ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ï¼š" +msgstr "FROMé …ç›®ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:3322 sql_help.c:3325 sql_help.c:3328 sql_help.c:3332 -#: sql_help.c:3344 sql_help.c:3540 sql_help.c:3543 sql_help.c:3546 -#: sql_help.c:3550 sql_help.c:3562 sql_help.c:3709 sql_help.c:3712 -#: sql_help.c:3715 sql_help.c:3719 sql_help.c:3731 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" -msgstr "列ã®åˆ¥å" +msgstr "行エイリアス" + +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 +msgid "sampling_method" +msgstr "サンプリングメソッド" -#: sql_help.c:3326 sql_help.c:3351 sql_help.c:3544 sql_help.c:3569 -#: sql_help.c:3713 sql_help.c:3738 +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 +msgid "seed" +msgstr "乱数シード" + +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "WITHå•ã„åˆã‚ã›å" -#: sql_help.c:3330 sql_help.c:3334 sql_help.c:3338 sql_help.c:3341 -#: sql_help.c:3548 sql_help.c:3552 sql_help.c:3556 sql_help.c:3559 -#: sql_help.c:3717 sql_help.c:3721 sql_help.c:3725 sql_help.c:3728 -msgid "argument" -msgstr "引数" - -#: sql_help.c:3336 sql_help.c:3339 sql_help.c:3342 sql_help.c:3554 -#: sql_help.c:3557 sql_help.c:3560 sql_help.c:3723 sql_help.c:3726 -#: sql_help.c:3729 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" -msgstr "列定義" +msgstr "カラム定義" -#: sql_help.c:3346 sql_help.c:3564 sql_help.c:3733 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" -msgstr "çµåˆç¨®é¡ž" +msgstr "JOINタイプ" -#: sql_help.c:3348 sql_help.c:3566 sql_help.c:3735 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" -msgstr "çµåˆæ¡ä»¶" +msgstr "JOINæ¡ä»¶" -#: sql_help.c:3349 sql_help.c:3567 sql_help.c:3736 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" -msgstr "çµåˆåˆ—" +msgstr "JOINカラム" -#: sql_help.c:3350 sql_help.c:3568 sql_help.c:3737 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 +msgid "and grouping_element can be one of:" +msgstr "グルーピングè¦ç´ ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" + +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" -msgstr "WITHå•ã„åˆã‚ã›ï¼š" +msgstr "WITHå•ã„åˆã‚ã›ã¯ä»¥ä¸‹ã®ã„ãšã‚Œã‹ã§ã™:" -#: sql_help.c:3354 sql_help.c:3572 sql_help.c:3741 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "VALUESå¥" -#: sql_help.c:3355 sql_help.c:3573 sql_help.c:3742 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" msgstr "INSERTå¥" -#: sql_help.c:3356 sql_help.c:3574 sql_help.c:3743 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "UPDATEå¥" -#: sql_help.c:3357 sql_help.c:3575 sql_help.c:3744 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "DELETEå¥" -#: sql_help.c:3384 +#: sql_help.c:4308 msgid "new_table" msgstr "æ–°ã—ã„テーブル" -#: sql_help.c:3409 +#: sql_help.c:4333 msgid "timezone" msgstr "タイムゾーン" -#: sql_help.c:3454 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "スナップショットID" -#: sql_help.c:3614 +#: sql_help.c:4563 msgid "from_list" -msgstr "FROM リスト" +msgstr "FROMリスト" -#: sql_help.c:3645 +#: sql_help.c:4607 msgid "sort_expression" msgstr "ソート表ç¾" -#: sql_help.h:191 sql_help.h:891 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’中断ã™ã‚‹" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’中止ã—ã¾ã™" -#: sql_help.h:196 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" -msgstr "集約関数ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "集約関数ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:201 +#: sql_help.c:4744 msgid "change the definition of a collation" -msgstr "ç…§åˆé †åºã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ç…§åˆé †åºã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:206 +#: sql_help.c:4749 msgid "change the definition of a conversion" -msgstr "エンコーディング変æ›ãƒ«ãƒ¼ãƒ«ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "エンコーディング変æ›ãƒ«ãƒ¼ãƒ«ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:211 +#: sql_help.c:4754 msgid "change a database" -msgstr "データベースを変更ã™ã‚‹" +msgstr "データベースを変更ã—ã¾ã™ã€‚" -#: sql_help.h:216 +#: sql_help.c:4759 msgid "define default access privileges" -msgstr "デフォルトã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’定義ã™ã‚‹" +msgstr "デフォルトã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©é™ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:221 +#: sql_help.c:4764 msgid "change the definition of a domain" -msgstr "ドメインã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ドメインã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:226 +#: sql_help.c:4769 msgid "change the definition of an event trigger" -msgstr "イベントトリガã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "イベントトリガーã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:231 +#: sql_help.c:4774 msgid "change the definition of an extension" -msgstr "æ‹¡å¼µã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "æ‹¡å¼µã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:236 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" -msgstr "外部データラッパーã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "外部データラッパã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:241 +#: sql_help.c:4784 msgid "change the definition of a foreign table" -msgstr "外部テーブルã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "外部テーブルã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:246 +#: sql_help.c:4789 msgid "change the definition of a function" -msgstr "関数ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "関数ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:251 +#: sql_help.c:4794 msgid "change role name or membership" -msgstr "ロールã®åå‰ã¾ãŸã¯ãƒ¡ãƒ³ãƒãƒ¼ã‚·ãƒƒãƒ—を変更ã™ã‚‹" +msgstr "ロールåã¾ãŸã¯ãƒ¡ãƒ³ãƒãƒ¼ã‚·ãƒƒãƒ—を変更ã—ã¾ã™ã€‚" -#: sql_help.h:256 +#: sql_help.c:4799 msgid "change the definition of an index" -msgstr "インデックスã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "インデックスã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:261 +#: sql_help.c:4804 msgid "change the definition of a procedural language" -msgstr "手続ã言語ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "手続ã言語ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:266 +#: sql_help.c:4809 msgid "change the definition of a large object" -msgstr "ラージオブジェクトã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ラージオブジェクトã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:271 +#: sql_help.c:4814 msgid "change the definition of a materialized view" -msgstr "マテリアライズドビューã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "マテリアライズドビューã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:276 +#: sql_help.c:4819 msgid "change the definition of an operator" -msgstr "演算å­ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "演算å­ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:281 +#: sql_help.c:4824 msgid "change the definition of an operator class" -msgstr "演算å­ã‚¯ãƒ©ã‚¹ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "演算å­ã‚¯ãƒ©ã‚¹ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:286 +#: sql_help.c:4829 msgid "change the definition of an operator family" -msgstr "演算å­ãƒ•ァミリã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "æ¼”ç®—å­æ—ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" + +#: sql_help.c:4834 +msgid "change the definition of a row level security policy" +msgstr "行レベルã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ ãƒãƒªã‚·ãƒ¼ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" + +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "プロシージャã®å®šç¾©ã‚’変更ã—ã¾ã™" + +#: sql_help.c:4844 +msgid "change the definition of a publication" +msgstr "パブリケーションã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:291 sql_help.h:361 +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" -msgstr "データベースã®ãƒ­ãƒ¼ãƒ«ã‚’変更ã™ã‚‹" +msgstr "データベースロールを変更ã—ã¾ã™ã€‚" -#: sql_help.h:296 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "ルーãƒãƒ³ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" + +#: sql_help.c:4859 msgid "change the definition of a rule" -msgstr "ルールã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ルールã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:301 +#: sql_help.c:4864 msgid "change the definition of a schema" -msgstr "スキーマã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "スキーマã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:306 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" -msgstr "シーケンスジェãƒãƒ¬ãƒ¼ã‚¿ãƒ¼ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "シーケンスジェãƒãƒ¬ãƒ¼ã‚¿ãƒ¼ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:311 +#: sql_help.c:4874 msgid "change the definition of a foreign server" -msgstr "外部サーãƒãƒ¼ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "外部サーãƒã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" + +#: sql_help.c:4879 +msgid "change the definition of an extended statistics object" +msgstr "拡張統計情報オブジェクトã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:316 +#: sql_help.c:4884 +msgid "change the definition of a subscription" +msgstr "サブスクリプションã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" + +#: sql_help.c:4889 msgid "change a server configuration parameter" -msgstr "サーãƒè¨­å®šãƒ‘ラメータを変更ã™ã‚‹" +msgstr "サーãƒã®æ§‹æˆãƒ‘ラメーターを変更ã—ã¾ã™ã€‚" -#: sql_help.h:321 +#: sql_help.c:4894 msgid "change the definition of a table" -msgstr "テーブルã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テーブルã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:326 +#: sql_help.c:4899 msgid "change the definition of a tablespace" -msgstr "テーブルスペースã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テーブル空間ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:331 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" -msgstr "テキスト検索設定ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テキスト検索設定ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:336 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" -msgstr "テキスト検索辞書ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テキスト検索辞書ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:341 +#: sql_help.c:4914 msgid "change the definition of a text search parser" -msgstr "テキスト検索パーサã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テキスト検索パーサã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:346 +#: sql_help.c:4919 msgid "change the definition of a text search template" -msgstr "テキスト検索テンプレートã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "テキスト検索テンプレートã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:351 +#: sql_help.c:4924 msgid "change the definition of a trigger" -msgstr "トリガã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "トリガーã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:356 +#: sql_help.c:4929 msgid "change the definition of a type" -msgstr "åž‹ã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "åž‹ã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:366 +#: sql_help.c:4939 msgid "change the definition of a user mapping" -msgstr "ユーザマッピングã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ユーザマッピングã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:371 +#: sql_help.c:4944 msgid "change the definition of a view" -msgstr "ビューã®å®šç¾©ã‚’変更ã™ã‚‹" +msgstr "ビューã®å®šç¾©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:376 +#: sql_help.c:4949 msgid "collect statistics about a database" -msgstr "データベースã®çµ±è¨ˆæƒ…報をåŽé›†ã™ã‚‹" +msgstr "データベースã®çµ±è¨ˆæƒ…報をåŽé›†ã—ã¾ã™ã€‚" -#: sql_help.h:381 sql_help.h:956 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" -msgstr "トランザクションブロックを開始ã™ã‚‹" +msgstr "トランザクションブロックを開始ã—ã¾ã™ã€‚" + +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "プロシージャを実行ã—ã¾ã™" -#: sql_help.h:386 -msgid "force a transaction log checkpoint" -msgstr "トランザクションログã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚’強制設定ã™ã‚‹" +#: sql_help.c:4964 +msgid "force a write-ahead log checkpoint" +msgstr "先行書ãè¾¼ã¿ãƒ­ã‚°ã®ãƒã‚§ãƒƒã‚¯ãƒã‚¤ãƒ³ãƒˆã‚’強制的ã«å®Ÿè¡Œã—ã¾ã™ã€‚" -#: sql_help.h:391 +#: sql_help.c:4969 msgid "close a cursor" -msgstr "カーソルを閉ã˜ã‚‹" +msgstr "カーソルを閉ã˜ã¾ã™ã€‚" -#: sql_help.h:396 +#: sql_help.c:4974 msgid "cluster a table according to an index" -msgstr "インデックスã«å¾“ã£ã¦ãƒ†ãƒ¼ãƒ–ルをクラスタ化ã™ã‚‹" +msgstr "インデックスã«å¾“ã£ã¦ãƒ†ãƒ¼ãƒ–ルをクラスタ化ã—ã¾ã™ã€‚" -#: sql_help.h:401 +#: sql_help.c:4979 msgid "define or change the comment of an object" -msgstr "オブジェクトã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’定義ã¾ãŸã¯å¤‰æ›´ã™ã‚‹" +msgstr "オブジェクトã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’定義ã¾ãŸã¯å¤‰æ›´ã—ã¾ã™ã€‚" -#: sql_help.h:406 sql_help.h:796 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’コミットã™ã‚‹" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’コミットã—ã¾ã™ã€‚" -#: sql_help.h:411 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" -msgstr "2フェーズコミットã®ãŸã‚ã«äº‹å‰ã«æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’コミットã™ã‚‹" +msgstr "二相コミットã®ãŸã‚ã«äº‹å‰ã«æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’コミットã—ã¾ã™ã€‚" -#: sql_help.h:416 +#: sql_help.c:4994 msgid "copy data between a file and a table" -msgstr "ファイルã¨ãƒ†ãƒ¼ãƒ–ル間ã§ãƒ‡ãƒ¼ã‚¿ã‚’コピーã™ã‚‹" +msgstr "ファイルã¨ãƒ†ãƒ¼ãƒ–ル間ã§ãƒ‡ãƒ¼ã‚¿ã‚’コピーã—ã¾ã™ã€‚" -#: sql_help.h:421 +#: sql_help.c:4999 +msgid "define a new access method" +msgstr "æ–°ã—ã„アクセスメソッドを定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5004 msgid "define a new aggregate function" -msgstr "æ–°ã—ã„集約関数を定義ã™ã‚‹" +msgstr "æ–°ã—ã„集約関数を定義ã—ã¾ã™ã€‚" -#: sql_help.h:426 +#: sql_help.c:5009 msgid "define a new cast" -msgstr "æ–°ã—ã„キャストを定義ã™ã‚‹" +msgstr "æ–°ã—ã„キャストを定義ã—ã¾ã™ã€‚" -#: sql_help.h:431 +#: sql_help.c:5014 msgid "define a new collation" -msgstr "æ–°ã—ã„ç…§åˆé †åºã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„ç…§åˆé †åºã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:436 +#: sql_help.c:5019 msgid "define a new encoding conversion" -msgstr "æ–°ã—ã„エンコーディングã®å¤‰æ›ãƒ«ãƒ¼ãƒ«ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„エンコーディングã®å¤‰æ›ãƒ«ãƒ¼ãƒ«ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:441 +#: sql_help.c:5024 msgid "create a new database" -msgstr "æ–°ã—ã„データベースを作æˆã™ã‚‹" +msgstr "æ–°ã—ã„データベースを作æˆã—ã¾ã™ã€‚" -#: sql_help.h:446 +#: sql_help.c:5029 msgid "define a new domain" -msgstr "æ–°ã—ã„ドメインを定義ã™ã‚‹" +msgstr "æ–°ã—ã„ドメインを定義ã—ã¾ã™ã€‚" -#: sql_help.h:451 +#: sql_help.c:5034 msgid "define a new event trigger" -msgstr "æ–°ã—ã„イベントトリガを定義ã™ã‚‹" +msgstr "æ–°ã—ã„イベントトリガーを定義ã—ã¾ã™ã€‚" -#: sql_help.h:456 +#: sql_help.c:5039 msgid "install an extension" -msgstr "拡張をインストールã™ã‚‹" +msgstr "拡張をインストールã—ã¾ã™ã€‚" -#: sql_help.h:461 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" -msgstr "æ–°ã—ã„外部データラッパーを定義ã™ã‚‹" +msgstr "æ–°ã—ã„外部データラッパを定義ã—ã¾ã™ã€‚" -#: sql_help.h:466 +#: sql_help.c:5049 msgid "define a new foreign table" -msgstr "æ–°ã—ã„外部テーブルを定義ã™ã‚‹" +msgstr "æ–°ã—ã„外部テーブルを定義ã—ã¾ã™ã€‚" -#: sql_help.h:471 +#: sql_help.c:5054 msgid "define a new function" -msgstr "æ–°ã—ã„関数を定義ã™ã‚‹" +msgstr "æ–°ã—ã„関数を定義ã—ã¾ã™ã€‚" -#: sql_help.h:476 sql_help.h:511 sql_help.h:581 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" -msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®æ–°ã—ã„ロールを定義ã™ã‚‹" +msgstr "æ–°ã—ã„データベースロールを定義ã—ã¾ã™ã€‚" -#: sql_help.h:481 +#: sql_help.c:5064 msgid "define a new index" -msgstr "æ–°ã—ã„インデックスを定義ã™ã‚‹" +msgstr "æ–°ã—ã„インデックスを定義ã—ã¾ã™ã€‚" -#: sql_help.h:486 +#: sql_help.c:5069 msgid "define a new procedural language" -msgstr "æ–°ã—ã„æ‰‹ç¶šã言語を定義ã™ã‚‹" +msgstr "æ–°ã—ã„æ‰‹ç¶šã言語を定義ã—ã¾ã™ã€‚" -#: sql_help.h:491 +#: sql_help.c:5074 msgid "define a new materialized view" -msgstr "æ–°ã—ã„マテリアライズドビューを定義ã™ã‚‹" +msgstr "æ–°ã—ã„マテリアライズドビューを定義ã—ã¾ã™ã€‚" -#: sql_help.h:496 +#: sql_help.c:5079 msgid "define a new operator" -msgstr "æ–°ã—ã„æ¼”ç®—å­ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„æ¼”ç®—å­ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:501 +#: sql_help.c:5084 msgid "define a new operator class" -msgstr "æ–°ã—ã„æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„æ¼”ç®—å­ã‚¯ãƒ©ã‚¹ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:506 +#: sql_help.c:5089 msgid "define a new operator family" -msgstr "æ–°ã—ã„æ¼”ç®—å­ãƒ•ァミリを定義ã™ã‚‹" +msgstr "æ–°ã—ã„æ¼”ç®—å­æ—を定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5094 +msgid "define a new row level security policy for a table" +msgstr "テーブルã«å¯¾ã—ã¦æ–°ã—ã„行レベルã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·ãƒ¼ã‚’定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "æ–°ã—ã„プロシージャを定義ã—ã¾ã™" + +#: sql_help.c:5104 +msgid "define a new publication" +msgstr "æ–°ã—ã„パブリケーションを定義ã—ã¾ã™ã€‚" -#: sql_help.h:516 +#: sql_help.c:5114 msgid "define a new rewrite rule" -msgstr "æ–°ã—ã„æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:521 +#: sql_help.c:5119 msgid "define a new schema" -msgstr "æ–°ã—ã„スキーマを定義ã™ã‚‹" +msgstr "æ–°ã—ã„スキーマを定義ã—ã¾ã™ã€‚" -#: sql_help.h:526 +#: sql_help.c:5124 msgid "define a new sequence generator" -msgstr "æ–°ã—ã„シーケンスジェãƒãƒ¬ãƒ¼ã‚¿ãƒ¼ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„シーケンスジェãƒãƒ¬ãƒ¼ã‚¿ãƒ¼ã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:531 +#: sql_help.c:5129 msgid "define a new foreign server" -msgstr "æ–°ã—ã„外部サーãƒãƒ¼ã‚’定義ã™ã‚‹" +msgstr "æ–°ã—ã„外部サーãƒã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:536 +#: sql_help.c:5134 +msgid "define extended statistics" +msgstr "拡張統計情報を定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5139 +msgid "define a new subscription" +msgstr "æ–°ã—ã„サブスクリプションを定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5144 msgid "define a new table" -msgstr "æ–°ã—ã„テーブルを定義ã™ã‚‹" +msgstr "æ–°ã—ã„テーブルを定義ã—ã¾ã™ã€‚" -#: sql_help.h:541 sql_help.h:921 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" -msgstr "å•ã„åˆã‚ã›çµæžœã‹ã‚‰æ–°ã—ã„テーブルを生æˆã™ã‚‹" +msgstr "å•ã„åˆã‚ã›ã®çµæžœã‹ã‚‰æ–°ã—ã„テーブルを定義ã—ã¾ã™ã€‚" -#: sql_help.h:546 +#: sql_help.c:5154 msgid "define a new tablespace" -msgstr "æ–°ã—ã„テーブルスペースを定義ã™ã‚‹" +msgstr "æ–°ã—ã„テーブル空間を定義ã—ã¾ã™ã€‚" -#: sql_help.h:551 +#: sql_help.c:5159 msgid "define a new text search configuration" -msgstr "æ–°ã—ã„テキスト検索設定を定義ã™ã‚‹" +msgstr "æ–°ã—ã„テキスト検索設定を定義ã—ã¾ã™ã€‚" -#: sql_help.h:556 +#: sql_help.c:5164 msgid "define a new text search dictionary" -msgstr "æ–°ã—ã„テキスト検索用辞書を定義ã™ã‚‹" +msgstr "æ–°ã—ã„テキスト検索辞書を定義ã—ã¾ã™ã€‚" -#: sql_help.h:561 +#: sql_help.c:5169 msgid "define a new text search parser" -msgstr "æ–°ã—ã„テキスト検索用パーサを定義ã™ã‚‹" +msgstr "æ–°ã—ã„テキスト検索パーサを定義ã—ã¾ã™ã€‚" -#: sql_help.h:566 +#: sql_help.c:5174 msgid "define a new text search template" -msgstr "æ–°ã—ã„テキスト検索テンプレートを定義ã™ã‚‹" +msgstr "æ–°ã—ã„テキスト検索テンプレートを定義ã—ã¾ã™ã€‚" -#: sql_help.h:571 +#: sql_help.c:5179 +msgid "define a new transform" +msgstr "æ–°ã—ã„変æ›ã‚’定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5184 msgid "define a new trigger" -msgstr "æ–°ã—ã„トリガを定義ã™ã‚‹" +msgstr "æ–°ã—ã„トリガーを定義ã—ã¾ã™ã€‚" -#: sql_help.h:576 +#: sql_help.c:5189 msgid "define a new data type" -msgstr "æ–°ã—ã„データ型を定義ã™ã‚‹" +msgstr "æ–°ã—ã„データ型を定義ã—ã¾ã™ã€‚" -#: sql_help.h:586 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" -msgstr "外部サーãƒãƒ¼ã«å¯¾ã—ã¦ãƒ¦ãƒ¼ã‚¶ã®æ–°ã—ã„マッピングを定義ã™ã‚‹" +msgstr "外部サーãƒã«å¯¾ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ã®æ–°ã—ã„マッピングを定義ã—ã¾ã™ã€‚" -#: sql_help.h:591 +#: sql_help.c:5204 msgid "define a new view" -msgstr "æ–°ã—ã„ビューを定義ã™ã‚‹" +msgstr "æ–°ã—ã„ビューを定義ã—ã¾ã™ã€‚" -#: sql_help.h:596 +#: sql_help.c:5209 msgid "deallocate a prepared statement" -msgstr "プリペアドステートメントを開放ã™ã‚‹" +msgstr "プリペアドステートメントを開放ã—ã¾ã™ã€‚" -#: sql_help.h:601 +#: sql_help.c:5214 msgid "define a cursor" -msgstr "カーソルを定義ã™ã‚‹" +msgstr "カーソルを定義ã—ã¾ã™ã€‚" -#: sql_help.h:606 +#: sql_help.c:5219 msgid "delete rows of a table" -msgstr "テーブルã®è¡Œã‚’削除ã™ã‚‹" +msgstr "テーブルã®è¡Œã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:611 +#: sql_help.c:5224 msgid "discard session state" -msgstr "セッションã®çŠ¶æ…‹ã‚’ç ´æ£„ã™ã‚‹" +msgstr "セッション状態を破棄ã—ã¾ã™ã€‚" -#: sql_help.h:616 +#: sql_help.c:5229 msgid "execute an anonymous code block" -msgstr "ç„¡åコードブロックを実行ã™ã‚‹" +msgstr "ç„¡åコードブロックを実行ã—ã¾ã™ã€‚" + +#: sql_help.c:5234 +msgid "remove an access method" +msgstr "アクセスメソッドを削除ã—ã¾ã™ã€‚" -#: sql_help.h:621 +#: sql_help.c:5239 msgid "remove an aggregate function" -msgstr "集約関数を削除ã™ã‚‹" +msgstr "集約関数を削除ã—ã¾ã™ã€‚" -#: sql_help.h:626 +#: sql_help.c:5244 msgid "remove a cast" -msgstr "キャストを削除ã™ã‚‹" +msgstr "キャストを削除ã—ã¾ã™ã€‚" -#: sql_help.h:631 +#: sql_help.c:5249 msgid "remove a collation" -msgstr "ç…§åˆé †åºã‚’削除ã™ã‚‹" +msgstr "ç…§åˆé †åºã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:636 +#: sql_help.c:5254 msgid "remove a conversion" -msgstr "エンコーディング変æ›ãƒ«ãƒ¼ãƒ«ã‚’削除ã™ã‚‹" +msgstr "符å·åŒ–æ–¹å¼å¤‰æ›ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:641 +#: sql_help.c:5259 msgid "remove a database" -msgstr "データベースを削除ã™ã‚‹" +msgstr "データベースを削除ã—ã¾ã™ã€‚" -#: sql_help.h:646 +#: sql_help.c:5264 msgid "remove a domain" -msgstr "ドメインを削除ã™ã‚‹" +msgstr "ドメインを削除ã—ã¾ã™ã€‚" -#: sql_help.h:651 +#: sql_help.c:5269 msgid "remove an event trigger" -msgstr "イベントトリガを削除ã™ã‚‹" +msgstr "イベントトリガーを削除ã—ã¾ã™ã€‚" -#: sql_help.h:656 +#: sql_help.c:5274 msgid "remove an extension" -msgstr "拡張を削除ã™ã‚‹" +msgstr "拡張を削除ã—ã¾ã™ã€‚" -#: sql_help.h:661 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" -msgstr "外部データラッパーを削除ã™ã‚‹" +msgstr "外部データラッパを削除ã—ã¾ã™ã€‚" -#: sql_help.h:666 +#: sql_help.c:5284 msgid "remove a foreign table" -msgstr "外部テーブルを削除ã™ã‚‹" +msgstr "外部テーブルを削除ã—ã¾ã™ã€‚" -#: sql_help.h:671 +#: sql_help.c:5289 msgid "remove a function" -msgstr "関数を削除ã™ã‚‹" +msgstr "関数を削除ã—ã¾ã™ã€‚" -#: sql_help.h:676 sql_help.h:716 sql_help.h:781 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" -msgstr "データベースã®ãƒ­ãƒ¼ãƒ«ã‚’削除ã™ã‚‹" +msgstr "データベースロールを削除ã—ã¾ã™ã€‚" -#: sql_help.h:681 +#: sql_help.c:5299 msgid "remove an index" -msgstr "インデックスを削除ã™ã‚‹" +msgstr "インデックスを削除ã—ã¾ã™ã€‚" -#: sql_help.h:686 +#: sql_help.c:5304 msgid "remove a procedural language" -msgstr "手続ã言語を削除ã™ã‚‹" +msgstr "手続ã言語を削除ã—ã¾ã™ã€‚" -#: sql_help.h:691 +#: sql_help.c:5309 msgid "remove a materialized view" -msgstr "マテリアライズドビューを削除ã™ã‚‹" +msgstr "マテリアライズドビューを削除ã—ã¾ã™ã€‚" -#: sql_help.h:696 +#: sql_help.c:5314 msgid "remove an operator" -msgstr "演算å­ã‚’削除ã™ã‚‹" +msgstr "演算å­ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:701 +#: sql_help.c:5319 msgid "remove an operator class" -msgstr "演算å­ã‚¯ãƒ©ã‚¹ã‚’削除ã™ã‚‹" +msgstr "演算å­ã‚¯ãƒ©ã‚¹ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:706 +#: sql_help.c:5324 msgid "remove an operator family" -msgstr "演算å­ãƒ•ァミリを削除ã™ã‚‹" +msgstr "æ¼”ç®—å­æ—を削除ã—ã¾ã™ã€‚" -#: sql_help.h:711 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" -msgstr "特定ã®ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«ãŒæ‰€æœ‰ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクトを削除ã™ã‚‹" +msgstr "ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«ãŒæ‰€æœ‰ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ジェクトを削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5334 +msgid "remove a row level security policy from a table" +msgstr "テーブルã‹ã‚‰è¡Œãƒ¬ãƒ™ãƒ«ã®ã‚»ã‚­ãƒ¥ãƒªãƒ†ã‚£ãƒãƒªã‚·ãƒ¼ã‚’削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "プロシージャを削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5344 +msgid "remove a publication" +msgstr "パブリケーションを削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "ルーãƒãƒ³ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:721 +#: sql_help.c:5359 msgid "remove a rewrite rule" -msgstr "æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã‚’削除ã™ã‚‹" +msgstr "æ›¸ãæ›ãˆãƒ«ãƒ¼ãƒ«ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:726 +#: sql_help.c:5364 msgid "remove a schema" -msgstr "スキーマを削除ã™ã‚‹" +msgstr "スキーマを削除ã—ã¾ã™ã€‚" -#: sql_help.h:731 +#: sql_help.c:5369 msgid "remove a sequence" -msgstr "シーケンスを削除ã™ã‚‹" +msgstr "シーケンスを削除ã—ã¾ã™ã€‚" -#: sql_help.h:736 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" -msgstr "外部サーãƒãƒ¼è­˜åˆ¥å­ã‚’削除ã™ã‚‹" +msgstr "外部サーãƒè¨˜è¿°å­ã‚’削除ã—ã¾ã™ã€‚" -#: sql_help.h:741 +#: sql_help.c:5379 +msgid "remove extended statistics" +msgstr "拡張統計情報を削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5384 +msgid "remove a subscription" +msgstr "サブスクリプションを削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5389 msgid "remove a table" -msgstr "テーブルを削除ã™ã‚‹" +msgstr "テーブルを削除ã—ã¾ã™ã€‚" -#: sql_help.h:746 +#: sql_help.c:5394 msgid "remove a tablespace" -msgstr "テーブルスペースを削除ã™ã‚‹" +msgstr "テーブル空間を削除ã—ã¾ã™ã€‚" -#: sql_help.h:751 +#: sql_help.c:5399 msgid "remove a text search configuration" -msgstr "テキスト検索設定を削除ã™ã‚‹" +msgstr "テキスト検索設定を削除ã—ã¾ã™ã€‚" -#: sql_help.h:756 +#: sql_help.c:5404 msgid "remove a text search dictionary" -msgstr "テキスト検索用辞書を削除ã™ã‚‹" +msgstr "テキスト検索辞書を削除ã—ã¾ã™ã€‚" -#: sql_help.h:761 +#: sql_help.c:5409 msgid "remove a text search parser" -msgstr "テキスト検索用パーサを削除ã™ã‚‹" +msgstr "テキスト検索パーサを削除ã—ã¾ã™ã€‚" -#: sql_help.h:766 +#: sql_help.c:5414 msgid "remove a text search template" -msgstr "テキスト検索用テンプレートを削除ã™ã‚‹" +msgstr "テキスト検索テンプレートを削除ã—ã¾ã™ã€‚" -#: sql_help.h:771 +#: sql_help.c:5419 +msgid "remove a transform" +msgstr "自動変æ›ãƒ«ãƒ¼ãƒ«ã‚’削除ã—ã¾ã™ã€‚" + +#: sql_help.c:5424 msgid "remove a trigger" -msgstr "トリガを削除ã™ã‚‹" +msgstr "トリガーを削除ã—ã¾ã™ã€‚" -#: sql_help.h:776 +#: sql_help.c:5429 msgid "remove a data type" -msgstr "データ型を削除ã™ã‚‹" +msgstr "データ型を削除ã—ã¾ã™ã€‚" -#: sql_help.h:786 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" -msgstr "外部サーãƒãƒ¼ã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングを削除" +msgstr "外部サーãƒã®ãƒ¦ãƒ¼ã‚¶ãƒžãƒƒãƒ”ングを削除ã—ã¾ã™ã€‚" -#: sql_help.h:791 +#: sql_help.c:5444 msgid "remove a view" -msgstr "ビューを削除ã™ã‚‹" +msgstr "ビューを削除ã—ã¾ã™ã€‚" -#: sql_help.h:801 +#: sql_help.c:5454 msgid "execute a prepared statement" -msgstr "プリペアドステートメントを実行ã™ã‚‹" +msgstr "プリペアドステートメントを実行ã—ã¾ã™ã€‚" -#: sql_help.h:806 +#: sql_help.c:5459 msgid "show the execution plan of a statement" -msgstr "ステートメントã®å®Ÿè¡Œãƒ—ランを表示ã™ã‚‹" +msgstr "ステートメントã®å®Ÿè¡Œè¨ˆç”»ã‚’表示ã—ã¾ã™ã€‚" -#: sql_help.h:811 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" -msgstr "カーソルを使ã£ã¦å•ã„åˆã‚ã›ã‹ã‚‰è¡Œã‚’å–り出ã™" +msgstr "カーソルを使ã£ã¦å•ã„åˆã‚ã›ã‹ã‚‰è¡Œã‚’å–り出ã—ã¾ã™ã€‚" -#: sql_help.h:816 +#: sql_help.c:5469 msgid "define access privileges" -msgstr "アクセス権é™ã‚’定義ã™ã‚‹" +msgstr "アクセス権é™ã‚’定義ã—ã¾ã™ã€‚" + +#: sql_help.c:5474 +msgid "import table definitions from a foreign server" +msgstr "外部サーãƒã‹ã‚‰ãƒ†ãƒ¼ãƒ–ル定義をインãƒãƒ¼ãƒˆã—ã¾ã™ã€‚" -#: sql_help.h:821 +#: sql_help.c:5479 msgid "create new rows in a table" -msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã«æ–°ã—ã„行を作æˆã™ã‚‹" +msgstr "ãƒ†ãƒ¼ãƒ–ãƒ«ã«æ–°ã—ã„行を作æˆã—ã¾ã™ã€‚" -#: sql_help.h:826 +#: sql_help.c:5484 msgid "listen for a notification" -msgstr "通知メッセージを監視ã™ã‚‹" +msgstr "通知メッセージを監視ã—ã¾ã™ã€‚" -#: sql_help.h:831 +#: sql_help.c:5489 msgid "load a shared library file" -msgstr "共有ライブラリファイルをロードã™ã‚‹" +msgstr "共有ライブラリファイルをロードã—ã¾ã™ã€‚" -#: sql_help.h:836 +#: sql_help.c:5494 msgid "lock a table" -msgstr "テーブルをロックã™ã‚‹" +msgstr "テーブルをロックã—ã¾ã™ã€‚" -#: sql_help.h:841 +#: sql_help.c:5499 msgid "position a cursor" -msgstr "カーソルをä½ç½®ä»˜ã‘ã‚‹" +msgstr "カーソルをä½ç½®ã¥ã‘ã¾ã™ã€‚" -#: sql_help.h:846 +#: sql_help.c:5504 msgid "generate a notification" -msgstr "通知メッセージを生æˆã™ã‚‹" +msgstr "通知を生æˆã—ã¾ã™ã€‚" -#: sql_help.h:851 +#: sql_help.c:5509 msgid "prepare a statement for execution" -msgstr "実行ã«å…ˆç«‹ã£ã¦ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’準備ã™ã‚‹" +msgstr "実行ã«å‚™ãˆã¦ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’準備ã—ã¾ã™ã€‚" -#: sql_help.h:856 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" -msgstr "2フェーズコミット用ã«ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’準備ã™ã‚‹" +msgstr "二相コミットã«å‚™ãˆã¦ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’準備ã—ã¾ã™ã€‚" -#: sql_help.h:861 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" -msgstr "ã‚ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«ãŒæ‰€æœ‰ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ‰€æœ‰è€…を変更ã™ã‚‹" +msgstr "" +"ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ãƒ­ãƒ¼ãƒ«ãŒæ‰€æœ‰ã™ã‚‹ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆã®æ‰€æœ‰æ¨©ã‚’変更ã—ã¾ã™ã€‚" -#: sql_help.h:866 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" -msgstr "マテリアライズドビューã®å†…å®¹ã‚’ç½®ãæ›ãˆã‚‹" +msgstr "マテリアライズドビューã®å†…å®¹ã‚’ç½®ãæ›ãˆã¾ã™ã€‚" -#: sql_help.h:871 +#: sql_help.c:5529 msgid "rebuild indexes" -msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’å†æ§‹ç¯‰ã™ã‚‹" +msgstr "ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã‚’å†æ§‹ç¯‰ã—ã¾ã™ã€‚" -#: sql_help.h:876 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" -msgstr "å‰å›žå®šç¾©ã—ãŸã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã‚’削除ã™ã‚‹" +msgstr "以å‰ã«å®šç¾©ã•れãŸã‚»ãƒ¼ãƒ–ãƒã‚¤ãƒ³ãƒˆã‚’破棄ã—ã¾ã™ã€‚" -#: sql_help.h:881 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" -msgstr "実行時パラメータã®å€¤ã‚’ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã™" +msgstr "実行時パラメーターã®å€¤ã‚’ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆå€¤ã«æˆ»ã—ã¾ã™ã€‚" -#: sql_help.h:886 +#: sql_help.c:5544 msgid "remove access privileges" -msgstr "アクセス権é™ã‚’剥奪ã™ã‚‹" +msgstr "アクセス特権を削除ã—ã¾ã™ã€‚" -#: sql_help.h:896 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" -msgstr "2フェーズコミット用ã«äº‹å‰æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’キャンセルã™ã‚‹" +msgstr "" +"二相コミットã®ãŸã‚ã«äº‹å‰ã«æº–å‚™ã•れãŸãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’キャンセルã—ã¾ã™ã€‚" -#: sql_help.h:901 +#: sql_help.c:5559 msgid "roll back to a savepoint" -msgstr "セーブãƒã‚¤ãƒ³ãƒˆã¾ã§ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã™ã‚‹" +msgstr "セーブãƒã‚¤ãƒ³ãƒˆã¾ã§ãƒ­ãƒ¼ãƒ«ãƒãƒƒã‚¯ã—ã¾ã™ã€‚" -#: sql_help.h:906 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã«å¯¾ã—ã¦æ–°ã—ã„セーブãƒã‚¤ãƒ³ãƒˆã‚’定義ã™ã‚‹" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³å†…ã§æ–°ã—ã„セーブãƒã‚¤ãƒ³ãƒˆã‚’定義ã—ã¾ã™ã€‚" -#: sql_help.h:911 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" -msgstr "オブジェクトã«é©ç”¨ã•れるセキュリティラベルを定義ã¾ãŸã¯å¤‰æ›´ã™ã‚‹" +msgstr "オブジェクトã«é©ç”¨ã•れるセキュリティラベルを定義ã¾ãŸã¯å¤‰æ›´ã—ã¾ã™ã€‚" -#: sql_help.h:916 sql_help.h:961 sql_help.h:991 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" -msgstr "テーブルもã—ãã¯ãƒ“ューã‹ã‚‰è¡Œã‚’å–り出ã™" +msgstr "テーブルã¾ãŸã¯ãƒ“ューã‹ã‚‰è¡Œã‚’å–å¾—ã—ã¾ã™ã€‚" -#: sql_help.h:926 +#: sql_help.c:5584 msgid "change a run-time parameter" -msgstr "実行時パラメータを変更ã™ã‚‹" +msgstr "実行時ã®ãƒ‘ラメーターを変更ã—ã¾ã™ã€‚" -#: sql_help.h:931 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã«å¯¾ã—ã¦åˆ¶ç´„検査ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’設定ã™ã‚‹" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã«ã¤ã„ã¦ã€åˆ¶ç´„ãƒã‚§ãƒƒã‚¯ã®ã‚¿ã‚¤ãƒŸãƒ³ã‚°ã‚’設定ã—ã¾ã™ã€‚" -#: sql_help.h:936 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" -msgstr "ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã«ãŠã‘ã‚‹ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥ã‚’設定ã™ã‚‹" +msgstr "ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥å­ã‚’設定ã—ã¾ã™ã€‚" -#: sql_help.h:941 -msgid "set the session user identifier and the current user identifier of the current session" -msgstr "セッションã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥ã€ãŠã‚ˆã³ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã«ãŠã‘ã‚‹ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥ã‚’設定ã™ã‚‹" +#: sql_help.c:5599 +msgid "" +"set the session user identifier and the current user identifier of the " +"current session" +msgstr "" +"セッションã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥å­ãŠã‚ˆã³ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã®ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶è­˜åˆ¥å­ã‚’設定ã—ã¾" +"ã™ã€‚" -#: sql_help.h:946 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" -msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ç‰¹æ€§ã‚’設定ã—ã¾ã™" +msgstr "ç¾åœ¨ã®ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã®ç‰¹æ€§ã‚’設定ã—ã¾ã™ã€‚" -#: sql_help.h:951 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" -msgstr "実行時パラメータã®å€¤ã‚’表示ã™ã‚‹" +msgstr "実行時パラメーターã®å€¤ã‚’表示ã—ã¾ã™ã€‚" -#: sql_help.h:966 +#: sql_help.c:5624 msgid "empty a table or set of tables" -msgstr "テーブルもã—ãã¯ãƒ†ãƒ¼ãƒ–ルã®ã‚»ãƒƒãƒˆã‚’ 0 ä»¶ã«åˆ‡ã‚Šè©°ã‚ã‚‹" +msgstr "テーブルもã—ãã¯ãƒ†ãƒ¼ãƒ–ルセットを0ä»¶ã«åˆ‡ã‚Šè©°ã‚ã¾ã™ã€‚" -#: sql_help.h:971 +#: sql_help.c:5629 msgid "stop listening for a notification" -msgstr "通知メッセージã®ç›£è¦–を中止ã™ã‚‹" +msgstr "通知メッセージã®ç›£è¦–を中止ã—ã¾ã™ã€‚" -#: sql_help.h:976 +#: sql_help.c:5634 msgid "update rows of a table" -msgstr "テーブルã®è¡Œã‚’æ›´æ–°ã™ã‚‹" +msgstr "テーブルã®è¡Œã‚’æ›´æ–°ã—ã¾ã™ã€‚" -#: sql_help.h:981 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" -msgstr "ガーベジコレクションを行ã„ã€ã‚ªãƒ—ションã§ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®åˆ†æžã‚’ã—ã¾ã™" +msgstr "" +"ガーベッジコレクションを行ã„ã€ã¾ãŸå¿…è¦ã«å¿œã˜ã¦ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’分æžã—ã¾ã™ã€‚" -#: sql_help.h:986 +#: sql_help.c:5644 msgid "compute a set of rows" -msgstr "行セットを計算ã—ã¾ã™" +msgstr "行セットを計算ã—ã¾ã™ã€‚" -#: startup.c:166 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" -msgstr "%s: -1ã¯å¯¾è©±å¼ãƒ¢ãƒ¼ãƒ‰ä»¥å¤–ã§ã®ã¿ä½¿ç”¨ã§ãã¾ã™\n" +msgstr "%s: -1 ãŒä½¿ãˆã‚‹ã®ã¯éžå¯¾è©±åž‹ãƒ¢ãƒ¼ãƒ‰æ™‚ã ã‘ã§ã™\n" -#: startup.c:266 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%s: ログファイル \"%s\" をオープンã§ãã¾ã›ã‚“: %s\n" +msgstr "%s: ログファイル \"%s\" ã‚’é–‹ãã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: startup.c:328 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" "\n" msgstr "" -"\"help\" ã§ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™.\n" +"\"help\" ã§ãƒ˜ãƒ«ãƒ—を表示ã—ã¾ã™ã€‚\n" "\n" -#: startup.c:471 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" -msgstr "%s: 表示用パラメータ \"%s\" をセットã§ãã¾ã›ã‚“ã§ã—ãŸ\n" - -#: startup.c:511 -#, c-format -msgid "%s: could not delete variable \"%s\"\n" -msgstr "%s: 変数 \"%s\" を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" - -#: startup.c:521 -#, c-format -msgid "%s: could not set variable \"%s\"\n" -msgstr "%s: 変数 \"%s\" をセットã§ãã¾ã›ã‚“ã§ã—ãŸ\n" +msgstr "%s: å°åˆ·ãƒ‘ラメーター \"%s\" を設定ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: startup.c:564 startup.c:570 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" -msgstr "詳細㯠'%s --help' ã‚’ã”らんãã ã•ã„\n" +msgstr "詳細㯠\"%s --help\" ã‚’ã”らんãã ã•ã„。\n" -#: startup.c:587 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" -msgstr "%s: 警告:余分ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³ã‚ªãƒ—ション \"%s\" ã¯ç„¡è¦–ã•れã¾ã™\n" +msgstr "%s: 警告: 余分ãªã‚³ãƒžãƒ³ãƒ‰ãƒ©ã‚¤ãƒ³å¼•æ•° \"%s\" ã¯ç„¡è¦–ã•れã¾ã—ãŸã€‚\n" -#: startup.c:609 +#: startup.c:729 #, c-format msgid "%s: could not find own program executable\n" -msgstr "%s: 実行ファイル自体ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ\n" - -#: startup.c:729 startup.c:776 startup.c:797 startup.c:834 variables.c:121 -#, c-format -msgid "unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n" -msgstr "\"%2$s\" ã®ä¸æ˜Žãªå€¤ \"%1$s\"。\"%3$s\"ã¨ä»®å®šã—ã¾ã™\n" +msgstr "%s: 実行å¯èƒ½ãƒ—ログラムファイルãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: tab-complete.c:4098 +#: tab-complete.c:4497 #, c-format msgid "" "tab completion query failed: %s\n" "Query was:\n" "%s\n" msgstr "" -"å•ã„åˆã‚ã›ã®ã‚¿ãƒ–補完ã«å¤±æ•—: %s\n" -"å•ã„åˆã‚ã›ã¯\n" +"タブ補完ã®å•ã„åˆã‚ã›ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" +"実行ã—ãŸå•ã„åˆã‚ã›:\n" "%s\n" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "\"%2$s\" ã®å€¤ \"%1$s\" ãŒèªè­˜ã§ãã¾ã›ã‚“:真å½å€¤ã‚’指定ã—ã¦ãã ã•ã„。\n" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected\n" +msgstr "\"%2$s\" ã®å€¤ \"%1$s\" ãŒç„¡åйã§ã™: 整数を指定ã—ã¦ãã ã•ã„。\n" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"\n" +msgstr "変数åãŒç„¡åйã§ã™: \"%s\"\n" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s.\n" +msgstr "" +"\"%2$s\" ã®å€¤ \"%1$s\" ãŒèªè­˜ã§ãã¾ã›ã‚“。\n" +"有効ãªå€¤ã¯ %3$s ã§ã™ã€‚\n" + +#~ msgid "attribute" +#~ msgstr "属性" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM psql ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (数値フォーマット)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME psql ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (çŸ­ã„æ–‡å­—列)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION psql ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ (è©³ç´°ãªæ–‡å­—列)\n" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME サーãƒã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³å (çŸ­ã„æ–‡å­—列)\n" + +#~ msgid "normal" +#~ msgstr "通常" + +#~ msgid "Procedure" +#~ msgstr "プロシージャーå" diff --git a/src/bin/psql/po/ko.po b/src/bin/psql/po/ko.po index b355b663f6f..88a1cbfbfde 100644 --- a/src/bin/psql/po/ko.po +++ b/src/bin/psql/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: psql (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-27 01:42+0900\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:26+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -51,8 +51,8 @@ msgid "pclose failed: %s" msgstr "pclose 실패: %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:342 input.c:227 mainloop.c:80 -#: mainloop.c:261 +#: ../../common/fe_memutils.c:98 command.c:608 input.c:227 mainloop.c:82 +#: mainloop.c:276 #, c-format msgid "out of memory\n" msgstr "메모리 부족\n" @@ -62,112 +62,125 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 복제할 수 ì—†ìŒ(ë‚´ë¶€ 오류)\n" -#: ../../common/username.c:45 +#: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "UID %ld 해당하는 사용ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: ../../common/username.c:47 command.c:299 +#: ../../common/username.c:45 command.c:555 msgid "user does not exist" msgstr "ì‚¬ìš©ìž ì—†ìŒ" -#: ../../common/username.c:62 +#: ../../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ì‚¬ìš©ìž ì´ë¦„ 찾기 실패: 오류번호 %lu" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "명령어를 ì°¾ì„ ìˆ˜ ì—†ìŒ" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "하위 프로세스가 %d 코드로 종료했ìŒ" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:61 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "0x%X ì˜ˆì™¸ì²˜ë¦¬ì— ì˜í•´ 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:73 +#: ../../common/wait_error.c:71 #, c-format msgid "child process was terminated by signal %s" msgstr "%s ì‹œê·¸ë„ ê°ì§€ë¡œ 하위 프로세스가 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:77 +#: ../../common/wait_error.c:75 #, c-format msgid "child process was terminated by signal %d" msgstr "하위 프로세스가 %d 신호를 받고 종료ë˜ì—ˆìŒ" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:80 #, c-format msgid "child process exited with unrecognized status %d" msgstr "하위 프로세스가 알 수 없는 ìƒíƒœ(%d)로 종료ë˜ì—ˆìŒ" -#: ../../fe_utils/print.c:354 +#: ../../fe_utils/print.c:353 #, c-format msgid "(%lu row)" msgid_plural "(%lu rows)" msgstr[0] "(%luê°œ í–‰)" -#: ../../fe_utils/print.c:2906 +#: ../../fe_utils/print.c:2913 #, c-format msgid "Interrupted\n" msgstr "ì¸íŠ¸ëŸ½íŠ¸ë°œìƒ\n" -#: ../../fe_utils/print.c:2970 +#: ../../fe_utils/print.c:2977 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "í…Œì´ë¸” ë‚´ìš©ì— í—¤ë”를 추가할 수 ì—†ìŒ: ì—´ 수가 %d개를 초과했습니다.\n" -#: ../../fe_utils/print.c:3010 +#: ../../fe_utils/print.c:3017 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "í…Œì´ë¸” ë‚´ìš©ì— ì…€ì„ ì¶”ê°€í•  수 ì—†ìŒ: ì´ ì…€ 수가 %d개를 초과했습니다.\n" -#: ../../fe_utils/print.c:3259 +#: ../../fe_utils/print.c:3266 #, c-format msgid "invalid output format (internal error): %d" msgstr "ìž˜ëª»ëœ ì¶œë ¥ í˜•ì‹ (ë‚´ë¶€ 오류): %d" -#: command.c:129 +#: ../../fe_utils/psqlscan.l:713 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"\n" +msgstr "\"%s\" ë³€ìˆ˜ì˜ ìž¬ê·€ì  í™•ìž¥ì„ ê±´ë„ˆë›°ëŠ” 중\n" + +#: command.c:223 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "ìž˜ëª»ëœ ëª…ë ¹: \\%s. ë„움ë§ì€ \\?.\n" -#: command.c:131 +#: command.c:225 #, c-format msgid "invalid command \\%s\n" msgstr "ìž˜ëª»ëœ ëª…ë ¹: \\%s\n" -#: command.c:142 +#: command.c:243 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s: \"%s\" 추가 ì¸ìˆ˜ê°€ 무시ë˜ì—ˆìŒ\n" -#: command.c:297 +#: command.c:295 +#, c-format +msgid "" +"\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "" +"\\%s ëª…ë ¹ì€ ë¬´ì‹œí•¨; 현재 \\if 블ë¡ì„ 중지하려면, \\endif 명령ì´ë‚˜ Ctrl-C 키" +"를 사용하세요.\n" + +#: command.c:553 #, c-format msgid "could not get home directory for user ID %ld: %s\n" msgstr "UID %ld 사용ìžì˜ 홈 디렉터리를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: command.c:315 +#: command.c:571 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s: \"%s\" 디렉터리로 ì´ë™í•  수 ì—†ìŒ: %s\n" -#: command.c:330 common.c:553 common.c:611 common.c:1144 +#: command.c:596 common.c:648 common.c:706 common.c:1242 #, c-format msgid "You are currently not connected to a database.\n" msgstr "현재 ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²°ë˜ì–´ìžˆì§€ 않습니다.\n" -#: command.c:355 +#: command.c:621 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " @@ -175,7 +188,7 @@ msgid "" msgstr "" "ì ‘ì†ì •ë³´: ë°ì´í„°ë² ì´ìФ=\"%s\", 사용ìž=\"%s\", 소켓=\"%s\", í¬íЏ=\"%s\".\n" -#: command.c:358 +#: command.c:624 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " @@ -183,149 +196,164 @@ msgid "" msgstr "" "ì ‘ì†ì •ë³´: ë°ì´í„°ë² ì´ìФ=\"%s\", 사용ìž=\"%s\", 호스트=\"%s\", í¬íЏ=\"%s\".\n" -#: command.c:574 command.c:647 command.c:746 command.c:1584 +#: command.c:915 command.c:1005 command.c:1114 command.c:2523 #, c-format msgid "no query buffer\n" msgstr "쿼리 버í¼ê°€ ì—†ìŒ\n" -#: command.c:607 command.c:3547 +#: command.c:948 command.c:4784 #, c-format msgid "invalid line number: %s\n" msgstr "ìž˜ëª»ëœ ì¤„ 번호: %s\n" -#: command.c:640 +#: command.c:998 #, c-format msgid "The server (version %s) does not support editing function source.\n" msgstr "ì´ ì„œë²„(%s 버전)는 함수 소스 편집 ê¸°ëŠ¥ì„ ì œê³µí•˜ì§€ 않습니다.\n" -#: command.c:721 command.c:792 +#: command.c:1073 command.c:1154 msgid "No changes" msgstr "변경 ë‚´ìš© ì—†ìŒ" -#: command.c:739 +#: command.c:1107 #, c-format msgid "The server (version %s) does not support editing view definitions.\n" msgstr "ì´ ì„œë²„(%s 버전)는 ë·° ì •ì˜ íŽ¸ì§‘ ê¸°ëŠ¥ì„ ì œê³µí•˜ì§€ 않습니다.\n" -#: command.c:846 +#: command.c:1231 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "%s: 타당치 못한 ì¸ì½”딩 ì´ë¦„ ë˜ëŠ” 문ìžì…‹ 변환 프로시저 ì—†ìŒ\n" -#: command.c:871 command.c:1962 command.c:3649 common.c:153 common.c:200 -#: common.c:497 common.c:1190 common.c:1218 common.c:1319 copy.c:489 -#: copy.c:699 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1266 command.c:1888 command.c:3169 command.c:4886 common.c:173 +#: common.c:244 common.c:541 common.c:1288 common.c:1316 common.c:1417 +#: copy.c:489 copy.c:708 large_obj.c:156 large_obj.c:191 large_obj.c:253 #, c-format msgid "%s" msgstr "%s" -#: command.c:875 +#: command.c:1270 msgid "out of memory" msgstr "메모리 부족" -#: command.c:878 +#: command.c:1273 msgid "There is no previous error." msgstr "ì´ì „ 오류가 없습니다." -#: command.c:972 command.c:1022 command.c:1036 command.c:1053 command.c:1160 -#: command.c:1324 command.c:1564 command.c:1595 +#: command.c:1444 command.c:1749 command.c:1763 command.c:1780 command.c:1940 +#: command.c:2177 command.c:2490 command.c:2530 #, c-format msgid "\\%s: missing required argument\n" msgstr "\\%s: 필요한 ì¸ìˆ˜ê°€ 빠졌ìŒ\n" -#: command.c:1085 +#: command.c:1575 +#, c-format +msgid "\\elif: cannot occur after \\else\n" +msgstr "\\elif: \\else 구문 ë’¤ì— ì˜¬ 수 ì—†ìŒ\n" + +#: command.c:1580 +#, c-format +msgid "\\elif: no matching \\if\n" +msgstr "\\elif: \\if 명령과 ì§ì´ 안맞ìŒ\n" + +#: command.c:1644 +#, c-format +msgid "\\else: cannot occur after \\else\n" +msgstr "\\else: \\else 명령 ë’¤ì— ì˜¬ 수 ì—†ìŒ\n" + +#: command.c:1649 +#, c-format +msgid "\\else: no matching \\if\n" +msgstr "\\else: \\if 명령과 ì§ì´ 안맞ìŒ\n" + +#: command.c:1689 +#, c-format +msgid "\\endif: no matching \\if\n" +msgstr "\\endif: \\if 명령과 ì§ì´ 안맞ìŒ\n" + +#: command.c:1844 msgid "Query buffer is empty." msgstr "쿼리 버í¼ê°€ 비었ìŒ." -#: command.c:1095 +#: command.c:1866 msgid "Enter new password: " msgstr "새 암호를 입력하세요:" -#: command.c:1096 +#: command.c:1867 msgid "Enter it again: " msgstr "다시 입력해 주세요:" -#: command.c:1100 +#: command.c:1871 #, c-format msgid "Passwords didn't match.\n" msgstr "암호가 서로 틀립니다.\n" -#: command.c:1118 -#, c-format -msgid "Password encryption failed.\n" -msgstr "암호 암호화 실패\n" - -#: command.c:1189 command.c:1305 command.c:1569 +#: command.c:1970 #, c-format -msgid "\\%s: error while setting variable\n" -msgstr "\\%s: 변수 지정 실패\n" +msgid "\\%s: could not read value for variable\n" +msgstr "\\%s: 변수 ê°’ì„ ì½ì„ 수 ì—†ìŒ\n" -#: command.c:1252 +#: command.c:2073 msgid "Query buffer reset (cleared)." msgstr "쿼리 ë²„í¼ ì´ˆê¸°í™” (비웠ìŒ)." -#: command.c:1264 +#: command.c:2095 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "명령내역(history)ì„ \"%s\" 파ì¼ì— 기ë¡í–ˆìŠµë‹ˆë‹¤.\n" -#: command.c:1329 +#: command.c:2182 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s: OS 환경 변수 ì´ë¦„ì—는 \"=\" 문ìžê°€ 없어야 함\n" -#: command.c:1373 +#: command.c:2238 #, c-format msgid "The server (version %s) does not support showing function source.\n" msgstr "ì´ ì„œë²„(%s 버전)는 함수 소스 보기 ê¸°ëŠ¥ì„ ì œê³µí•˜ì§€ 않습니다.\n" -#: command.c:1380 +#: command.c:2245 #, c-format msgid "function name is required\n" msgstr "함수 ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤\n" -#: command.c:1455 +#: command.c:2332 #, c-format msgid "The server (version %s) does not support showing view definitions.\n" msgstr "ì´ ì„œë²„(%s 버전)는 ë·° ì •ì˜ ë³´ê¸° ê¸°ëŠ¥ì„ ì œê³µí•˜ì§€ 않습니다.\n" -#: command.c:1462 +#: command.c:2339 #, c-format msgid "view name is required\n" msgstr "ë·° ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤\n" -#: command.c:1549 +#: command.c:2462 msgid "Timing is on." msgstr "작업수행시간 ë³´ìž„" -#: command.c:1551 +#: command.c:2464 msgid "Timing is off." msgstr "작업수행시간 숨김" -#: command.c:1613 command.c:1633 command.c:2311 command.c:2314 command.c:2317 -#: command.c:2323 command.c:2325 command.c:2333 command.c:2343 command.c:2352 -#: command.c:2366 command.c:2383 command.c:2441 common.c:68 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:711 psqlscanslash.l:722 -#: psqlscanslash.l:732 +#: command.c:2549 command.c:2577 command.c:3537 command.c:3540 command.c:3543 +#: command.c:3549 command.c:3551 command.c:3559 command.c:3569 command.c:3578 +#: command.c:3592 command.c:3609 command.c:3667 common.c:69 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:761 psqlscanslash.l:772 +#: psqlscanslash.l:782 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:1727 -#, c-format -msgid "+ opt(%d) = |%s|\n" -msgstr "+ opt(%d) = |%s|\n" - -#: command.c:1753 startup.c:207 +#: command.c:2961 startup.c:205 msgid "Password: " msgstr "암호: " -#: command.c:1758 startup.c:209 +#: command.c:2966 startup.c:207 #, c-format msgid "Password for user %s: " msgstr "%s 사용ìžì˜ 암호: " -#: command.c:1809 +#: command.c:3016 #, c-format msgid "" "All connection parameters must be supplied because no database connection " @@ -333,17 +361,17 @@ msgid "" msgstr "" "현재 ì ‘ì† ì •ë³´ê°€ 없습니다. ì ‘ì†ì„ 위한 ì—°ê²° 관련 매개변수를 지정하세요\n" -#: command.c:1966 +#: command.c:3173 #, c-format msgid "Previous connection kept\n" msgstr "ì´ì „ ì—°ê²°ì´ ìœ ì§€ë˜ì—ˆìŒ\n" -#: command.c:1970 +#: command.c:3177 #, c-format msgid "\\connect: %s" msgstr "\\ì—°ê²°: %s" -#: command.c:2006 +#: command.c:3213 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " @@ -351,7 +379,7 @@ msgid "" msgstr "" "ì ‘ì†ì •ë³´: ë°ì´í„°ë² ì´ìФ=\"%s\", 사용ìž=\"%s\", 소켓=\"%s\", í¬íЏ=\"%s\".\n" -#: command.c:2009 +#: command.c:3216 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " @@ -359,17 +387,17 @@ msgid "" msgstr "" "ì ‘ì†ì •ë³´: ë°ì´í„°ë² ì´ìФ=\"%s\", 사용ìž=\"%s\", 호스트=\"%s\", í¬íЏ=\"%s\".\n" -#: command.c:2013 +#: command.c:3220 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "ì ‘ì†ì •ë³´: ë°ì´í„°ë² ì´ìФ=\"%s\", 사용ìž=\"%s\".\n" -#: command.c:2046 +#: command.c:3253 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s(%s, %s 서버)\n" -#: command.c:2054 +#: command.c:3261 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -378,24 +406,24 @@ msgstr "" "경고: %s ë©”ì´ì € 버전 %s, 서버 ë©”ì´ì € 버전 %s.\n" " ì¼ë¶€ psql ê¸°ëŠ¥ì´ ìž‘ë™í•˜ì§€ ì•Šì„ ìˆ˜ë„ ìžˆìŠµë‹ˆë‹¤.\n" -#: command.c:2091 +#: command.c:3298 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "SSL ì—°ê²°ì •ë³´ (프로토콜: %s, 암호화기법: %s, 비트: %s, ì••ì¶•: %s)\n" -#: command.c:2092 command.c:2093 command.c:2094 +#: command.c:3299 command.c:3300 command.c:3301 msgid "unknown" msgstr "알수없ìŒ" -#: command.c:2095 help.c:46 +#: command.c:3302 help.c:45 msgid "off" msgstr "off" -#: command.c:2095 help.c:46 +#: command.c:3302 help.c:45 msgid "on" msgstr "on" -#: command.c:2115 +#: command.c:3322 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -407,36 +435,36 @@ msgstr "" "참조\n" " 페ì´ì§€ \"Notes for Windows users\"를 참조하십시오.\n" -#: command.c:2200 +#: command.c:3426 #, c-format msgid "" "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " "line number\n" msgstr "" -"지정한 줄번호를 사용하기 위해서는 PSQL_EDITOR_LINENUMBER_ARG ì´ë¦„ì˜ OS 환경" -"변수가 설정ë˜ì–´ 있어야 합니다.\n" +"지정한 줄번호를 사용하기 위해서는 PSQL_EDITOR_LINENUMBER_ARG ì´ë¦„ì˜ OS 환경변" +"수가 설정ë˜ì–´ 있어야 합니다.\n" -#: command.c:2229 +#: command.c:3455 #, c-format msgid "could not start editor \"%s\"\n" msgstr "\"%s\" 문서 편집기를 실행시킬 수 ì—†ìŒ\n" -#: command.c:2231 +#: command.c:3457 #, c-format msgid "could not start /bin/sh\n" msgstr "/bin/sh ëª…ë ¹ì„ ì‹¤í–‰í•  수 ì—†ìŒ\n" -#: command.c:2269 +#: command.c:3495 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "임시 디렉터리 경로를 알 수 ì—†ìŒ: %s\n" -#: command.c:2296 +#: command.c:3522 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "\"%s\" 임시 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: command.c:2570 +#: command.c:3796 #, c-format msgid "" "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, " @@ -445,208 +473,208 @@ msgstr "" "\\pset: 허용ë˜ëŠ” 출력 형ì‹: unaligned, aligned, wrapped, html, asciidoc, " "latex, latex-longtable, troff-ms\n" -#: command.c:2589 +#: command.c:3814 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "\\pset: 사용할 수 있는 ì„  ëª¨ì–‘ì€ ascii, old-ascii, unicode\n" -#: command.c:2605 +#: command.c:3829 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double\n" msgstr "\\pset: 사용할 수 있는 유니코드 í…Œë‘리 ëª¨ì–‘ì€ single, double\n" -#: command.c:2620 +#: command.c:3844 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double\n" msgstr "\\pset: 사용할 수 있는 유니코드 칼럼 ì„  ëª¨ì–‘ì€ single, double\n" -#: command.c:2635 +#: command.c:3859 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double\n" msgstr "\\pset: 사용할 수 있는 유니코드 í—¤ë” ì„  ëª¨ì–‘ì€ single, double\n" -#: command.c:2787 command.c:2966 +#: command.c:4024 command.c:4203 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "\\pset: 알 수 없는 옵션: %s\n" -#: command.c:2805 +#: command.c:4042 #, c-format msgid "Border style is %d.\n" msgstr "html í…Œì´ë¸”ì˜ í…Œë‘리를 %d로 지정했습니다.\n" -#: command.c:2811 +#: command.c:4048 #, c-format msgid "Target width is unset.\n" msgstr "ëŒ€ìƒ ë„ˆë¹„ 미지정.\n" -#: command.c:2813 +#: command.c:4050 #, c-format msgid "Target width is %d.\n" msgstr "ëŒ€ìƒ ë„ˆë¹„ëŠ” %d입니다.\n" -#: command.c:2820 +#: command.c:4057 #, c-format msgid "Expanded display is on.\n" msgstr "칼럼 단위 보기 기능 켬.\n" -#: command.c:2822 +#: command.c:4059 #, c-format msgid "Expanded display is used automatically.\n" msgstr "칼럼 단위 보기 ê¸°ëŠ¥ì„ ìžë™ìœ¼ë¡œ 지정 함.\n" -#: command.c:2824 +#: command.c:4061 #, c-format msgid "Expanded display is off.\n" msgstr "칼럼 단위 보기 기능 ë”.\n" -#: command.c:2831 command.c:2839 +#: command.c:4068 command.c:4076 #, c-format msgid "Field separator is zero byte.\n" msgstr "필드 구분ìžê°€ 0 ë°”ì´íŠ¸ìž…ë‹ˆë‹¤.\n" -#: command.c:2833 +#: command.c:4070 #, c-format msgid "Field separator is \"%s\".\n" msgstr "필드 êµ¬ë¶„ìž \"%s\".\n" -#: command.c:2846 +#: command.c:4083 #, c-format msgid "Default footer is on.\n" msgstr "기본 ê¼¬ë¦¿ë§ ë³´ê¸° 기능 켬.\n" -#: command.c:2848 +#: command.c:4085 #, c-format msgid "Default footer is off.\n" msgstr "기본 ê¼¬ë¦¿ë§ ë³´ê¸° 기능 ë”.\n" -#: command.c:2854 +#: command.c:4091 #, c-format msgid "Output format is %s.\n" msgstr "현재 출력 형ì‹: %s.\n" -#: command.c:2860 +#: command.c:4097 #, c-format msgid "Line style is %s.\n" msgstr "ì„  모양: %s.\n" -#: command.c:2867 +#: command.c:4104 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null ê°’ì€ \"%s\" 문ìžë¡œ ë³´ì—¬ì§.\n" -#: command.c:2875 +#: command.c:4112 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "ë¡œì¼€ì¼ ë§žì¶¤ ìˆ«ìž í‘œê¸° 기능 켬.\n" -#: command.c:2877 +#: command.c:4114 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "ë¡œì¼€ì¼ ë§žì¶¤ ìˆ«ìž í‘œê¸° 기능 ë”.\n" -#: command.c:2884 +#: command.c:4121 #, c-format msgid "Pager is used for long output.\n" msgstr "긴 ì¶œë ¥ì„ ìœ„í•´ 페ì´ì €ê°€ 사용ë¨.\n" -#: command.c:2886 +#: command.c:4123 #, c-format msgid "Pager is always used.\n" msgstr "í•­ìƒ íŽ˜ì´ì €ê°€ 사용ë¨.\n" -#: command.c:2888 +#: command.c:4125 #, c-format msgid "Pager usage is off.\n" msgstr "화면단위 보기 기능 ë”(ì „ì²´ ìžë£Œ ëª¨ë‘ ë³´ì—¬ì¤Œ).\n" -#: command.c:2894 +#: command.c:4131 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "%d 줄보다 ì ì€ 경우는 페ì´ì§€ 단위 보기가 사용ë˜ì§€ 않ìŒ\n" -#: command.c:2904 command.c:2914 +#: command.c:4141 command.c:4151 #, c-format msgid "Record separator is zero byte.\n" msgstr "레코드 구분ìžê°€ 0 ë°”ì´íŠ¸ìž„.\n" -#: command.c:2906 +#: command.c:4143 #, c-format msgid "Record separator is .\n" msgstr "레코드 구분ìžëŠ” 줄바꿈 문ìžìž…니다.\n" -#: command.c:2908 +#: command.c:4145 #, c-format msgid "Record separator is \"%s\".\n" msgstr "레코드 êµ¬ë¶„ìž \"%s\".\n" -#: command.c:2921 +#: command.c:4158 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "í…Œì´ë¸” ì†ì„±: \"%s\".\n" -#: command.c:2924 +#: command.c:4161 #, c-format msgid "Table attributes unset.\n" msgstr "í…Œì´ë¸” ì†ì„± ëª¨ë‘ ì§€ì›€.\n" -#: command.c:2931 +#: command.c:4168 #, c-format msgid "Title is \"%s\".\n" msgstr "출력 í…Œì´ë¸”ì˜ ì œëª©: \"%s\"\n" -#: command.c:2933 +#: command.c:4170 #, c-format msgid "Title is unset.\n" msgstr "출력 í…Œì´ë¸”ì˜ ì œëª©ì„ ì§€ì •í•˜ì§€ 않았습니다.\n" -#: command.c:2940 +#: command.c:4177 #, c-format msgid "Tuples only is on.\n" msgstr "ìžë£Œë§Œ 보기 기능 켬.\n" -#: command.c:2942 +#: command.c:4179 #, c-format msgid "Tuples only is off.\n" msgstr "ìžë£Œë§Œ 보기 기능 ë”.\n" -#: command.c:2948 +#: command.c:4185 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "유니코드 í…Œë‘리 선문ìž: \"%s\".\n" -#: command.c:2954 +#: command.c:4191 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "유니코드 칼럼 선문ìž: \"%s\".\n" -#: command.c:2960 +#: command.c:4197 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "유니코드 í—¤ë” ì„ ë¬¸ìž: \"%s\".\n" -#: command.c:3120 +#: command.c:4357 #, c-format msgid "\\!: failed\n" msgstr "\\!: 실패\n" -#: command.c:3145 common.c:659 +#: command.c:4382 common.c:754 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch 명령으로 수행할 쿼리가 없습니다.\n" -#: command.c:3186 +#: command.c:4423 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (%gì´ˆ 간격)\n" -#: command.c:3189 +#: command.c:4426 #, c-format msgid "%s (every %gs)\n" msgstr "%s (%gì´ˆ 간격)\n" -#: command.c:3243 command.c:3250 common.c:559 common.c:566 common.c:1173 +#: command.c:4480 command.c:4487 common.c:654 common.c:661 common.c:1271 #, c-format msgid "" "********* QUERY **********\n" @@ -659,91 +687,105 @@ msgstr "" "**************************\n" "\n" -#: command.c:3442 +#: command.c:4679 #, c-format msgid "\"%s.%s\" is not a view\n" msgstr "\"%s.%s\" ë·°(view)ê°€ 아님\n" -#: command.c:3458 +#: command.c:4695 #, c-format msgid "could not parse reloptions array\n" msgstr "reloptions ë°°ì—´ì„ ë¶„ì„í•  수 ì—†ìŒ\n" -#: common.c:138 +#: common.c:158 #, c-format msgid "cannot escape without active connection\n" msgstr "현재 ì ‘ì†í•œ ì—°ê²° ì—†ì´ëŠ” 특수문ìžì²˜ë¦¬ë¥¼ í•  수 ì—†ìŒ\n" -#: common.c:371 +#: common.c:199 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgstr "쉘 ëª…ë ¹ì˜ ì¸ìžì— 줄바꿈 문ìžê°€ 있ìŒ: \"%s\"\n" + +#: common.c:415 #, c-format msgid "connection to server was lost\n" msgstr "서버로부터 ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤.\n" -#: common.c:375 +#: common.c:419 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "서버로부터 ì—°ê²°ì´ ëŠì–´ì¡ŒìŠµë‹ˆë‹¤. 다시 ì—°ê²°ì„ ì‹œë„합니다: " -#: common.c:380 +#: common.c:424 #, c-format msgid "Failed.\n" msgstr "실패.\n" -#: common.c:387 +#: common.c:431 #, c-format msgid "Succeeded.\n" msgstr "성공.\n" -#: common.c:487 common.c:936 common.c:1108 +#: common.c:531 common.c:1034 common.c:1206 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "PQresultStatus ë°˜í™˜ê°’ì´ ìž˜ëª»ë¨: %d\n" -#: common.c:666 +#: common.c:593 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "작업시간: %.3f ms\n" + +#: common.c:608 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%02d:%06.3f)\n" + +#: common.c:617 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:624 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "작업시간: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:761 #, c-format msgid "\\watch cannot be used with COPY\n" msgstr "\\watch 작업으로 COPY ëª…ë ¹ì€ ì‚¬ìš©í•  수 ì—†ìŒ\n" -#: common.c:671 +#: common.c:766 #, c-format msgid "unexpected result status for \\watch\n" msgstr "\\watch 쿼리 결과가 비정ìƒì ìž…니다.\n" -#: common.c:682 common.c:1335 -#, c-format -msgid "Time: %.3f ms\n" -msgstr "작업시간: %.3f ms\n" - -#: common.c:700 +#: common.c:795 #, c-format msgid "" "Asynchronous notification \"%s\" with payload \"%s\" received from server " "process with PID %d.\n" -msgstr "" -"\"%s\" 비ë™ê¸° 통지를 ë°›ìŒ, 부가정보: \"%s\", 보낸 프로세스: %d.\n" +msgstr "\"%s\" 비ë™ê¸° 통지를 ë°›ìŒ, 부가정보: \"%s\", 보낸 프로세스: %d.\n" -#: common.c:703 +#: common.c:798 #, c-format msgid "" "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "ë™ê¸°í™” 신호 \"%s\" ë°›ìŒ, 해당 서버 프로세스 PID %d.\n" -#: common.c:761 +#: common.c:860 #, c-format msgid "no rows returned for \\gset\n" msgstr "\\gset 해당 ìžë£Œ ì—†ìŒ\n" -#: common.c:766 +#: common.c:865 #, c-format msgid "more than one row returned for \\gset\n" msgstr "\\gset 실행 결과가 ë‹¨ì¼ ìžë£Œê°€ 아님\n" -#: common.c:792 -#, c-format -msgid "could not set variable \"%s\"\n" -msgstr "\"%s\" 변수를 지정할 수 ì—†ìŒ\n" - -#: common.c:1153 +#: common.c:1251 #, c-format msgid "" "***(Single step mode: verify " @@ -756,20 +798,19 @@ msgstr "" "%s\n" "***(Enter: ê³„ì† ì§„í–‰, x Enter: 중지)********************\n" -#: common.c:1208 +#: common.c:1306 #, c-format msgid "" "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" msgstr "" -"서버(%s 버전)ì—서 ON_ERROR_ROLLBACKì— ì‚¬ìš©í•  savepoint를 ì§€ì›í•˜ì§€ 않습니" -"다.\n" +"서버(%s 버전)ì—서 ON_ERROR_ROLLBACKì— ì‚¬ìš©í•  savepoint를 ì§€ì›í•˜ì§€ 않습니다.\n" -#: common.c:1264 +#: common.c:1362 #, c-format msgid "STATEMENT: %s\n" msgstr "명령 구문: %s\n" -#: common.c:1307 +#: common.c:1405 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "알 수 없는 트랜잭션 ìƒíƒœ (%d)\n" @@ -826,50 +867,51 @@ msgstr "사용ìžì— ì˜í•´ì„œ 취소ë¨" #: copy.c:542 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" "한 ì¤„ì— í•œ 레코드씩 ë°ì´í„°ë¥¼ 입력하고\n" -"ìžë£Œìž…ë ¥ì´ ë나면 backslash ì  (\\.) 마지막 줄 처ìŒì— 입력합니다." +"ìžë£Œìž…ë ¥ì´ ë나면 backslash ì  (\\.) 마지막 줄 처ìŒì— 입력하는 EOF 시그ë„ì„ " +"보내세요." -#: copy.c:671 +#: copy.c:670 msgid "aborted because of read failure" msgstr "ì½ê¸° 실패로 중지ë¨" -#: copy.c:695 +#: copy.c:704 msgid "trying to exit copy mode" msgstr "복사 모드를 종료하는 중" -#: crosstabview.c:125 +#: crosstabview.c:123 #, c-format msgid "\\crosstabview: statement did not return a result set\n" msgstr "\\crosstabview: 구문 결과가 ì§‘í•©ì„ ë°˜í™˜í•˜ì§€ 않았ìŒ\n" -#: crosstabview.c:131 +#: crosstabview.c:129 #, c-format msgid "\\crosstabview: query must return at least three columns\n" msgstr "\\crosstabview: 쿼리 결과는 ì ì–´ë„ 세 ê°œì˜ ì¹¼ëŸ¼ì€ ë°˜í™˜ 해야 함\n" -#: crosstabview.c:158 +#: crosstabview.c:156 #, c-format msgid "" "\\crosstabview: vertical and horizontal headers must be different columns\n" -msgstr "" -"\\crosstabview: 행과 ì—´ì˜ ì¹¼ëŸ¼ì´ ê°ê° 다른 칼럼ì´ì–´ì•¼ 함\n" +msgstr "\\crosstabview: 행과 ì—´ì˜ ì¹¼ëŸ¼ì´ ê°ê° 다른 칼럼ì´ì–´ì•¼ 함\n" -#: crosstabview.c:174 +#: crosstabview.c:172 #, c-format msgid "" "\\crosstabview: data column must be specified when query returns more than " "three columns\n" msgstr "" -"\\crosstabview: 처리할 ì¹¼ëŸ¼ì´ ì„¸ê°œë³´ë‹¤ ë§Žì„ ë•ŒëŠ” ìžë£Œë¡œ 사용할 ì¹¼ëŸ¼ì„ ì§€ì •í•´ì•¼ 함\n" +"\\crosstabview: 처리할 ì¹¼ëŸ¼ì´ ì„¸ê°œë³´ë‹¤ ë§Žì„ ë•ŒëŠ” ìžë£Œë¡œ 사용할 ì¹¼ëŸ¼ì„ ì§€ì •í•´" +"야 함\n" -#: crosstabview.c:230 +#: crosstabview.c:228 #, c-format msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" msgstr "\\crosstabview: 최대 칼럼 수 (%d) 초과\n" -#: crosstabview.c:398 +#: crosstabview.c:397 #, c-format msgid "" "\\crosstabview: query result contains multiple data values for row \"%s\", " @@ -877,958 +919,1015 @@ msgid "" msgstr "" "\\crosstabview: \"%s\" 로우, \"%s\" ì¹¼ëŸ¼ì— ëŒ€í•´ 쿼리 결과는 다중값ì´ì–´ì•¼ 함\n" -#: crosstabview.c:646 +#: crosstabview.c:645 #, c-format msgid "\\crosstabview: column number %d is out of range 1..%d\n" msgstr "\\crosstabview: %d 번째 ì—´ì€ 0..%d 범위를 벗어났ìŒ\n" -#: crosstabview.c:671 +#: crosstabview.c:670 #, c-format msgid "\\crosstabview: ambiguous column name: \"%s\"\n" msgstr "\\crosstabview: 칼럼 ì´ë¦„ì´ ì¤‘ë³µë˜ì—ˆìŒ: \"%s\"\n" -#: crosstabview.c:679 +#: crosstabview.c:678 #, c-format msgid "\\crosstabview: column name not found: \"%s\"\n" msgstr "\\crosstabview: 칼럼 ì´ë¦„ ì—†ìŒ: \"%s\"\n" -#: describe.c:71 describe.c:340 describe.c:597 describe.c:727 describe.c:870 -#: describe.c:990 describe.c:1060 describe.c:3035 describe.c:3240 -#: describe.c:3330 describe.c:3578 describe.c:3718 describe.c:3950 -#: describe.c:4025 describe.c:4036 describe.c:4098 describe.c:4518 -#: describe.c:4601 +#: describe.c:74 describe.c:346 describe.c:603 describe.c:735 describe.c:879 +#: describe.c:1040 describe.c:1112 describe.c:3342 describe.c:3554 +#: describe.c:3645 describe.c:3893 describe.c:4038 describe.c:4279 +#: describe.c:4354 describe.c:4365 describe.c:4427 describe.c:4852 +#: describe.c:4935 msgid "Schema" msgstr "스키마" -#: describe.c:72 describe.c:160 describe.c:226 describe.c:234 describe.c:341 -#: describe.c:598 describe.c:728 describe.c:789 describe.c:871 describe.c:1061 -#: describe.c:3036 describe.c:3162 describe.c:3241 describe.c:3331 -#: describe.c:3410 describe.c:3579 describe.c:3643 describe.c:3719 -#: describe.c:3951 describe.c:4026 describe.c:4037 describe.c:4099 -#: describe.c:4291 describe.c:4375 describe.c:4599 +#: describe.c:75 describe.c:164 describe.c:231 describe.c:239 describe.c:347 +#: describe.c:604 describe.c:736 describe.c:797 describe.c:880 describe.c:1113 +#: describe.c:3343 describe.c:3477 describe.c:3555 describe.c:3646 +#: describe.c:3725 describe.c:3894 describe.c:3963 describe.c:4039 +#: describe.c:4280 describe.c:4355 describe.c:4366 describe.c:4428 +#: describe.c:4625 describe.c:4709 describe.c:4933 describe.c:5105 +#: describe.c:5312 msgid "Name" msgstr "ì´ë¦„" -#: describe.c:73 describe.c:353 describe.c:399 describe.c:416 +#: describe.c:76 describe.c:359 describe.c:405 describe.c:422 msgid "Result data type" msgstr "반환 ìžë£Œí˜•" -#: describe.c:81 describe.c:94 describe.c:98 describe.c:354 describe.c:400 -#: describe.c:417 +#: describe.c:84 describe.c:97 describe.c:101 describe.c:360 describe.c:406 +#: describe.c:423 msgid "Argument data types" msgstr "ì¸ìž ìžë£Œí˜•" -#: describe.c:105 describe.c:170 describe.c:257 describe.c:462 describe.c:646 -#: describe.c:743 describe.c:814 describe.c:1063 describe.c:1676 -#: describe.c:2836 describe.c:3069 describe.c:3193 describe.c:3267 -#: describe.c:3340 describe.c:3423 describe.c:3491 describe.c:3586 -#: describe.c:3652 describe.c:3720 describe.c:3856 describe.c:3896 -#: describe.c:3967 describe.c:4029 describe.c:4038 describe.c:4100 -#: describe.c:4317 describe.c:4397 describe.c:4532 describe.c:4602 +#: describe.c:108 describe.c:174 describe.c:262 describe.c:468 describe.c:652 +#: describe.c:751 describe.c:822 describe.c:1115 describe.c:1756 +#: describe.c:3132 describe.c:3377 describe.c:3508 describe.c:3582 +#: describe.c:3655 describe.c:3738 describe.c:3806 describe.c:3906 +#: describe.c:3972 describe.c:4040 describe.c:4181 describe.c:4223 +#: describe.c:4296 describe.c:4358 describe.c:4367 describe.c:4429 +#: describe.c:4651 describe.c:4731 describe.c:4866 describe.c:4936 #: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "설명" -#: describe.c:123 +#: describe.c:126 msgid "List of aggregate functions" msgstr "통계 함수 목ë¡" -#: describe.c:147 +#: describe.c:151 #, c-format msgid "The server (version %s) does not support access methods.\n" msgstr "서버(%s 버전)ì—서 ì ‘ê·¼ ë°©ë²•ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:161 +#: describe.c:165 msgid "Index" msgstr "ì¸ë±ìФ" -#: describe.c:162 describe.c:360 describe.c:405 describe.c:422 describe.c:877 -#: describe.c:999 describe.c:1645 describe.c:3044 describe.c:3242 -#: describe.c:4394 +#: describe.c:166 describe.c:366 describe.c:411 describe.c:428 describe.c:887 +#: describe.c:1051 describe.c:1716 describe.c:3352 describe.c:3556 +#: describe.c:4728 msgid "Type" msgstr "종류" -#: describe.c:169 describe.c:4296 +#: describe.c:173 describe.c:4630 msgid "Handler" msgstr "핸들러" -#: describe.c:188 +#: describe.c:192 msgid "List of access methods" msgstr "ì ‘ê·¼ 방법 목ë¡" -#: describe.c:213 +#: describe.c:218 #, c-format msgid "The server (version %s) does not support tablespaces.\n" msgstr "서버(%s 버전)ì—서 í…Œì´ë¸”스페ì´ìŠ¤ë¥¼ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:227 describe.c:235 describe.c:450 describe.c:636 describe.c:790 -#: describe.c:989 describe.c:3045 describe.c:3166 describe.c:3412 -#: describe.c:3644 describe.c:4292 describe.c:4376 large_obj.c:288 +#: describe.c:232 describe.c:240 describe.c:456 describe.c:642 describe.c:798 +#: describe.c:1039 describe.c:3353 describe.c:3481 describe.c:3727 +#: describe.c:3964 describe.c:4626 describe.c:4710 describe.c:5106 +#: describe.c:5218 describe.c:5313 large_obj.c:288 msgid "Owner" msgstr "소유주" -#: describe.c:228 describe.c:236 +#: describe.c:233 describe.c:241 msgid "Location" msgstr "위치" -#: describe.c:247 describe.c:2647 +#: describe.c:252 describe.c:2944 msgid "Options" msgstr "옵션" -#: describe.c:252 describe.c:609 describe.c:806 describe.c:3061 -#: describe.c:3065 +#: describe.c:257 describe.c:615 describe.c:814 describe.c:3369 +#: describe.c:3373 msgid "Size" msgstr "í¬ê¸°" -#: describe.c:274 +#: describe.c:279 msgid "List of tablespaces" msgstr "í…Œì´ë¸”스페ì´ìФ 목ë¡" -#: describe.c:314 +#: describe.c:320 #, c-format msgid "\\df only takes [antwS+] as options\n" msgstr "\\df는 [antwS+]ë§Œ 옵션으로 사용함\n" -#: describe.c:322 +#: describe.c:328 #, c-format msgid "\\df does not take a \"w\" option with server version %s\n" msgstr "\\df ëª…ë ¹ì€ %s 버전 서버ì—서는 \"w\" ì˜µì…˜ì„ ì‚¬ìš©í•˜ì§€ 않ìŒ\n" #. translator: "agg" is short for "aggregate" -#: describe.c:356 describe.c:402 describe.c:419 +#: describe.c:362 describe.c:408 describe.c:425 msgid "agg" msgstr "집계" -#: describe.c:357 +#: describe.c:363 msgid "window" msgstr "ì°½" -#: describe.c:358 describe.c:403 describe.c:420 describe.c:1197 +#: describe.c:364 describe.c:409 describe.c:426 describe.c:1249 msgid "trigger" msgstr "트리거" -#: describe.c:359 describe.c:404 describe.c:421 +#: describe.c:365 describe.c:410 describe.c:427 msgid "normal" msgstr "ì¼ë°˜" -#: describe.c:432 +#: describe.c:438 msgid "immutable" msgstr "immutable" -#: describe.c:433 +#: describe.c:439 msgid "stable" msgstr "stable" -#: describe.c:434 +#: describe.c:440 msgid "volatile" msgstr "volatile" -#: describe.c:435 +#: describe.c:441 msgid "Volatility" msgstr "휘발성" -#: describe.c:443 +#: describe.c:449 msgid "restricted" msgstr "엄격함" -#: describe.c:444 +#: describe.c:450 msgid "safe" msgstr "safe" -#: describe.c:445 +#: describe.c:451 msgid "unsafe" msgstr "unsafe" -#: describe.c:446 +#: describe.c:452 msgid "Parallel" msgstr "병렬처리" -#: describe.c:451 +#: describe.c:457 msgid "definer" msgstr "definer" -#: describe.c:452 +#: describe.c:458 msgid "invoker" msgstr "invoker" -#: describe.c:453 +#: describe.c:459 msgid "Security" msgstr "보안" -#: describe.c:460 +#: describe.c:466 msgid "Language" msgstr "언어" -#: describe.c:461 +#: describe.c:467 msgid "Source code" msgstr "소스 코드" -#: describe.c:560 +#: describe.c:566 msgid "List of functions" msgstr "함수 목ë¡" -#: describe.c:608 +#: describe.c:614 msgid "Internal name" msgstr "ë‚´ë¶€ ì´ë¦„" -#: describe.c:630 +#: describe.c:636 msgid "Elements" msgstr "요소" -#: describe.c:686 +#: describe.c:693 msgid "List of data types" msgstr "ìžë£Œí˜• 목ë¡" -#: describe.c:729 +#: describe.c:737 msgid "Left arg type" msgstr "왼쪽 ì¸ìˆ˜ ìžë£Œí˜•" -#: describe.c:730 +#: describe.c:738 msgid "Right arg type" msgstr "오른쪽 ì¸ìˆ˜ ìžë£Œí˜•" -#: describe.c:731 +#: describe.c:739 msgid "Result type" msgstr "반환 ìžë£Œí˜•" -#: describe.c:736 describe.c:3482 describe.c:3855 +#: describe.c:744 describe.c:3797 describe.c:4180 msgid "Function" msgstr "함수" -#: describe.c:761 +#: describe.c:769 msgid "List of operators" msgstr "ì—°ì‚°ìž ëª©ë¡" -#: describe.c:791 +#: describe.c:799 msgid "Encoding" msgstr "ì¸ì½”딩" -#: describe.c:796 describe.c:3580 +#: describe.c:804 describe.c:3895 msgid "Collate" msgstr "Collate" -#: describe.c:797 describe.c:3581 +#: describe.c:805 describe.c:3896 msgid "Ctype" msgstr "Ctype" -#: describe.c:810 +#: describe.c:818 msgid "Tablespace" msgstr "í…Œì´ë¸”스페ì´ìФ" -#: describe.c:832 +#: describe.c:840 msgid "List of databases" msgstr "ë°ì´í„°ë² ì´ìФ 목ë¡" -#: describe.c:872 describe.c:992 describe.c:3037 +#: describe.c:881 describe.c:886 describe.c:1042 describe.c:3344 +#: describe.c:3351 msgid "table" msgstr "í…Œì´ë¸”" -#: describe.c:873 describe.c:3038 +#: describe.c:882 describe.c:3345 msgid "view" msgstr "ë·°(view)" -#: describe.c:874 describe.c:3039 +#: describe.c:883 describe.c:3346 msgid "materialized view" msgstr "êµ¬ì²´í™”ëœ ë·°" -#: describe.c:875 describe.c:994 describe.c:3041 +#: describe.c:884 describe.c:1044 describe.c:3348 msgid "sequence" msgstr "시퀀스" -#: describe.c:876 describe.c:3043 +#: describe.c:885 describe.c:3350 msgid "foreign table" msgstr "외부 í…Œì´ë¸”" -#: describe.c:888 +#: describe.c:898 msgid "Column privileges" msgstr "칼럼 접근권한" -#: describe.c:919 +#: describe.c:929 describe.c:963 msgid "Policies" msgstr "ì •ì±…" -#: describe.c:945 describe.c:4749 describe.c:4753 +#: describe.c:995 describe.c:5369 describe.c:5373 msgid "Access privileges" msgstr "액세스 권한" -#: describe.c:976 +#: describe.c:1026 #, c-format msgid "The server (version %s) does not support altering default privileges.\n" msgstr "ì´ ì„œë²„(%s 버전)는 기본 접근권한 변경 ê¸°ëŠ¥ì„ ì œê³µí•˜ì§€ 않습니다.\n" -#: describe.c:996 +#: describe.c:1046 msgid "function" msgstr "함수" -#: describe.c:998 +#: describe.c:1048 msgid "type" msgstr "type" -#: describe.c:1022 +#: describe.c:1050 +msgid "schema" +msgstr "스키마" + +#: describe.c:1074 msgid "Default access privileges" msgstr "기본 접근권한" -#: describe.c:1062 +#: describe.c:1114 msgid "Object" msgstr "개체" -#: describe.c:1076 +#: describe.c:1128 msgid "table constraint" msgstr "í…Œì´ë¸” 제약 ì¡°ê±´" -#: describe.c:1098 +#: describe.c:1150 msgid "domain constraint" msgstr "ë„ë©”ì¸ ì œì•½ì¡°ê±´" -#: describe.c:1126 +#: describe.c:1178 msgid "operator class" msgstr "ì—°ì‚°ìž í´ëž˜ìФ" -#: describe.c:1155 +#: describe.c:1207 msgid "operator family" msgstr "ì—°ì‚°ìž ë¶€ë¥˜" -#: describe.c:1177 +#: describe.c:1229 msgid "rule" msgstr "룰(rule)" -#: describe.c:1219 +#: describe.c:1271 msgid "Object descriptions" msgstr "개체 설명" -#: describe.c:1273 +#: describe.c:1327 describe.c:3440 #, c-format msgid "Did not find any relation named \"%s\".\n" msgstr "\"%s\" ì´ë¦„ì„ ë¦´ë ˆì´ì…˜(relation) ì—†ìŒ.\n" -#: describe.c:1483 +#: describe.c:1330 describe.c:3443 +#, c-format +msgid "Did not find any relations.\n" +msgstr "관련 릴레ì´ì…˜ ì°¾ì„ ìˆ˜ ì—†ìŒ.\n" + +#: describe.c:1539 #, c-format msgid "Did not find any relation with OID %s.\n" msgstr "%s oidì˜ ì–´ë–¤ 릴레ì´ì…˜(relation)ë„ ì°¾ì„ ìˆ˜ ì—†ìŒ.\n" -#: describe.c:1589 +#: describe.c:1652 describe.c:1701 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "로그 미사용 í…Œì´ë¸” \"%s.%s\"" -#: describe.c:1592 +#: describe.c:1655 describe.c:1704 #, c-format msgid "Table \"%s.%s\"" msgstr "\"%s.%s\" í…Œì´ë¸”" -#: describe.c:1596 +#: describe.c:1659 #, c-format msgid "View \"%s.%s\"" msgstr "\"%s.%s\" ë·°(view)" -#: describe.c:1601 +#: describe.c:1664 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "트랜잭션 로그를 남기지 ì•Šì€ êµ¬ì²´í™”ëœ ë·° \"%s.%s\"" -#: describe.c:1604 +#: describe.c:1667 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Materialized ë·° \"%s.%s\"" -#: describe.c:1608 +#: describe.c:1671 #, c-format msgid "Sequence \"%s.%s\"" msgstr "\"%s.%s\" 시퀀스" -#: describe.c:1613 +#: describe.c:1676 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "\"%s.%s\" 로그 미사용 ì¸ë±ìФ" -#: describe.c:1616 +#: describe.c:1679 #, c-format msgid "Index \"%s.%s\"" msgstr "\"%s.%s\" ì¸ë±ìФ" -#: describe.c:1621 +#: describe.c:1684 #, c-format msgid "Special relation \"%s.%s\"" msgstr "\"%s.%s\" 특수 릴레ì´ì…˜(relation)" -#: describe.c:1625 +#: describe.c:1688 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "\"%s.%s\" TOAST í…Œì´ë¸”" -#: describe.c:1629 +#: describe.c:1692 #, c-format msgid "Composite type \"%s.%s\"" msgstr "\"%s.%s\" 복합ìžë£Œí˜•" -#: describe.c:1633 +#: describe.c:1696 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "\"%s.%s\" 외부 í…Œì´ë¸”" -#: describe.c:1644 +#: describe.c:1715 msgid "Column" msgstr "필드명" -#: describe.c:1653 -msgid "Modifiers" -msgstr "기타 ì¡°ê±´" +#: describe.c:1726 describe.c:3562 +msgid "Collation" +msgstr "Collation" + +#: describe.c:1727 describe.c:3569 +msgid "Nullable" +msgstr "NULL허용" -#: describe.c:1658 +#: describe.c:1728 describe.c:3570 +msgid "Default" +msgstr "초기값" + +#: describe.c:1733 msgid "Value" msgstr "ê°’" -#: describe.c:1661 +#: describe.c:1736 msgid "Definition" msgstr "ì •ì˜" -#: describe.c:1664 describe.c:4312 describe.c:4396 describe.c:4467 -#: describe.c:4531 -msgid "FDW Options" +#: describe.c:1739 describe.c:4646 describe.c:4730 describe.c:4801 +#: describe.c:4865 +msgid "FDW options" msgstr "FDW 옵션" -#: describe.c:1668 +#: describe.c:1743 msgid "Storage" msgstr "스토리지" -#: describe.c:1671 +#: describe.c:1748 msgid "Stats target" msgstr "통계수집량" -#: describe.c:1721 +#: describe.c:1897 #, c-format -msgid "collate %s" -msgstr "collate %s" +msgid "Partition of: %s %s" +msgstr "ì†Œì† íŒŒí‹°ì…˜: %s %s" -#: describe.c:1729 -msgid "not null" -msgstr "Null 아님" +#: describe.c:1903 +#, c-format +msgid "Partition constraint: %s" +msgstr "파티션 제약조건: %s" -#. translator: default values of column definitions -#: describe.c:1739 +#: describe.c:1926 #, c-format -msgid "default %s" -msgstr "초기값 %s" +msgid "Partition key: %s" +msgstr "파티션 키: %s" -#: describe.c:1854 +#: describe.c:1994 msgid "primary key, " msgstr "기본키, " -#: describe.c:1856 +#: describe.c:1996 msgid "unique, " msgstr "고유, " -#: describe.c:1862 +#: describe.c:2002 #, c-format msgid "for table \"%s.%s\"" msgstr "ì ìš©í…Œì´ë¸”: \"%s.%s\"" -#: describe.c:1866 +#: describe.c:2006 #, c-format msgid ", predicate (%s)" msgstr ", predicate (%s)" -#: describe.c:1869 +#: describe.c:2009 msgid ", clustered" msgstr ", í´ëŸ¬ìФë¨" -#: describe.c:1872 +#: describe.c:2012 msgid ", invalid" msgstr ", 잘못ë¨" -#: describe.c:1875 +#: describe.c:2015 msgid ", deferrable" -msgstr "" +msgstr ", 지연가능" -#: describe.c:1878 +#: describe.c:2018 msgid ", initially deferred" -msgstr "" +msgstr ", 트랜잭션단위지연" -#: describe.c:1881 +#: describe.c:2021 msgid ", replica identity" -msgstr "" +msgstr ", 복제 ì‹ë³„ìž" -#: describe.c:1916 +#: describe.c:2060 #, c-format msgid "Owned by: %s" msgstr "소유주: %s" -#: describe.c:1976 +#: describe.c:2065 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "ì‹ë³„ 칼럼용 시퀀스: %s" + +#: describe.c:2129 msgid "Indexes:" msgstr "ì¸ë±ìŠ¤ë“¤:" -#: describe.c:2060 +#: describe.c:2213 msgid "Check constraints:" msgstr "ì²´í¬ ì œì•½ ì¡°ê±´:" -#: describe.c:2091 +#: describe.c:2244 msgid "Foreign-key constraints:" msgstr "참조키 제약 ì¡°ê±´:" -#: describe.c:2122 +#: describe.c:2275 msgid "Referenced by:" msgstr "다ìŒì—서 참조ë¨:" -#: describe.c:2167 +#: describe.c:2325 msgid "Policies:" -msgstr "" +msgstr "ì •ì±…:" -#: describe.c:2170 +#: describe.c:2328 msgid "Policies (forced row security enabled):" -msgstr "" +msgstr "ì •ì±… (로우단위 보안정책 ê°•ì œ 활성화):" -#: describe.c:2173 +#: describe.c:2331 msgid "Policies (row security enabled): (none)" -msgstr "" +msgstr "ì •ì±… (로우단위 보안정책 활성화): (ì—†ìŒ)" -#: describe.c:2176 +#: describe.c:2334 msgid "Policies (forced row security enabled): (none)" -msgstr "" +msgstr "ì •ì±… (로우단위 보안정책 ê°•ì œ 활성화): (ì—†ìŒ)" -#: describe.c:2179 +#: describe.c:2337 msgid "Policies (row security disabled):" -msgstr "" +msgstr "ì •ì±… (로우단위 보안정책 비활성화):" + +#: describe.c:2399 +msgid "Statistics objects:" +msgstr "통계정보 ê°ì²´:" -#: describe.c:2279 describe.c:2329 +#: describe.c:2502 describe.c:2587 msgid "Rules:" msgstr "룰(rule)들:" -#: describe.c:2282 +#: describe.c:2505 msgid "Disabled rules:" msgstr "ì‚¬ìš©ì¤‘ì§€ëœ ê·œì¹™:" -#: describe.c:2285 +#: describe.c:2508 msgid "Rules firing always:" msgstr "í•­ìƒ ë°œìƒí•˜ëŠ” 규칙:" -#: describe.c:2288 +#: describe.c:2511 msgid "Rules firing on replica only:" msgstr "복제본ì—서만 ë°œìƒí•˜ëŠ” 규칙:" -#: describe.c:2312 +#: describe.c:2551 +msgid "Publications:" +msgstr "발행ìž:" + +#: describe.c:2570 msgid "View definition:" msgstr "ë·° ì •ì˜:" -#: describe.c:2447 +#: describe.c:2705 msgid "Triggers:" msgstr "트리거들:" -#: describe.c:2451 +#: describe.c:2709 msgid "Disabled user triggers:" msgstr "ì‚¬ìš©ì¤‘ì§€ëœ ì‚¬ìš©ìž íŠ¸ë¦¬ê±°:" -#: describe.c:2453 +#: describe.c:2711 msgid "Disabled triggers:" msgstr "ì‚¬ìš©ì¤‘ì§€ëœ íŠ¸ë¦¬ê±°:" -#: describe.c:2456 +#: describe.c:2714 msgid "Disabled internal triggers:" msgstr "ì‚¬ìš©ì¤‘ì§€ëœ ë‚´ë¶€ 트리거:" -#: describe.c:2459 +#: describe.c:2717 msgid "Triggers firing always:" msgstr "í•­ìƒ ë°œìƒí•˜ëŠ” 트리거:" -#: describe.c:2462 +#: describe.c:2720 msgid "Triggers firing on replica only:" msgstr "복제본ì—서만 ë°œìƒí•˜ëŠ” 트리거:" -#: describe.c:2541 +#: describe.c:2779 +#, c-format +msgid "Server: %s" +msgstr "서버: %s" + +#: describe.c:2787 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW 옵션들: (%s)" + +#: describe.c:2806 msgid "Inherits" msgstr "ìƒì†" -#: describe.c:2580 +#: describe.c:2860 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "하위 í…Œì´ë¸” 수: %d (\\d+ 명령으로 ë³¼ 수 있ìŒ)" -#: describe.c:2587 +#: describe.c:2862 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "파티션 í…Œì´ë¸” 수: %d (\\d+ 명령으로 ë³¼ 수 있ìŒ)" + +#: describe.c:2870 msgid "Child tables" msgstr "하위 í…Œì´ë¸”" -#: describe.c:2609 +#: describe.c:2870 +msgid "Partitions" +msgstr "파티션들" + +#: describe.c:2904 #, c-format msgid "Typed table of type: %s" -msgstr "" +msgstr "ìžë£Œí˜•ì˜ typed í…Œì´ë¸”: %s" -#: describe.c:2623 +#: describe.c:2920 msgid "Replica Identity" -msgstr "" +msgstr "복제 ì‹ë³„ìž" -#: describe.c:2636 +#: describe.c:2933 msgid "Has OIDs: yes" msgstr "OID 사용: yes" -#: describe.c:2724 +#: describe.c:3020 #, c-format msgid "Tablespace: \"%s\"" msgstr "í…Œì´ë¸”스페ì´ìФ: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:2736 +#: describe.c:3032 #, c-format msgid ", tablespace \"%s\"" msgstr ", \"%s\" í…Œì´ë¸”스페ì´ìФ" -#: describe.c:2829 +#: describe.c:3125 msgid "List of roles" msgstr "롤 목ë¡" -#: describe.c:2831 +#: describe.c:3127 msgid "Role name" msgstr "롤 ì´ë¦„" -#: describe.c:2832 +#: describe.c:3128 msgid "Attributes" msgstr "ì†ì„±" -#: describe.c:2833 +#: describe.c:3129 msgid "Member of" msgstr "ì†Œì† ê·¸ë£¹:" -#: describe.c:2844 +#: describe.c:3140 msgid "Superuser" msgstr "슈í¼ìœ ì €" -#: describe.c:2847 +#: describe.c:3143 msgid "No inheritance" msgstr "ìƒì† ì—†ìŒ" -#: describe.c:2850 +#: describe.c:3146 msgid "Create role" msgstr "롤 만들기" -#: describe.c:2853 +#: describe.c:3149 msgid "Create DB" msgstr "DB 만들기" -#: describe.c:2856 +#: describe.c:3152 msgid "Cannot login" msgstr "로그ì¸í•  수 ì—†ìŒ" -#: describe.c:2860 +#: describe.c:3156 msgid "Replication" msgstr "복제" -#: describe.c:2864 +#: describe.c:3160 msgid "Bypass RLS" -msgstr "" +msgstr "RLS 통과" -#: describe.c:2873 +#: describe.c:3169 msgid "No connections" msgstr "ì—°ê²° ì—†ìŒ" -#: describe.c:2875 +#: describe.c:3171 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%dê°œ ì—°ê²°" -#: describe.c:2885 +#: describe.c:3181 msgid "Password valid until " -msgstr "" +msgstr "비밀번호 만료기한: " -#: describe.c:2941 +#: describe.c:3231 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "ì´ ì„œë²„(%s 버전)는 ë°ì´í„°ë² ì´ìФ 개별 롤 ì„¤ì •ì„ ì§€ì›í•˜ì§€ 않습니다.\n" + +#: describe.c:3244 msgid "Role" msgstr "롤" -#: describe.c:2942 +#: describe.c:3245 msgid "Database" msgstr "ë°ì´í„°ë² ì´ìФ" -#: describe.c:2943 +#: describe.c:3246 msgid "Settings" msgstr "설정" -#: describe.c:2953 +#: describe.c:3267 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "ì´ ë²„ì „ì˜ ì„œë²„ëŠ” ë°ì´í„°ë² ì´ìФ 단위 롤 ì„¤ì •ì´ ì•ˆë©ë‹ˆë‹¤.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "\"%s\" 롤과 \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ëŒ€í•œ 특정 ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤.\n" -#: describe.c:2964 +#: describe.c:3270 #, c-format -msgid "No matching settings found.\n" -msgstr "찾는 ì„¤ì •ì´ ì—†ìŠµë‹ˆë‹¤.\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "\"%s\" 롤용 특정 ì„¤ì •ì´ ì—†ìŒ.\n" -#: describe.c:2966 +#: describe.c:3273 #, c-format -msgid "No settings found.\n" -msgstr "설정 ì—†ìŒ.\n" +msgid "Did not find any settings.\n" +msgstr "추가 설정 ì—†ìŒ.\n" -#: describe.c:2971 +#: describe.c:3278 msgid "List of settings" msgstr "설정 목ë¡" -#: describe.c:3040 +#: describe.c:3347 msgid "index" msgstr "ì¸ë±ìФ" -#: describe.c:3042 +#: describe.c:3349 msgid "special" msgstr "특수" -#: describe.c:3050 describe.c:4519 +#: describe.c:3358 describe.c:4853 msgid "Table" msgstr "í…Œì´ë¸”" -#: describe.c:3126 -#, c-format -msgid "No matching relations found.\n" -msgstr "ê²€ìƒ‰ì¡°ê±´ì— ì¼ì¹˜í•˜ëŠ” 릴레ì´ì…˜(relation) ì—†ìŒ.\n" - -#: describe.c:3128 -#, c-format -msgid "No relations found.\n" -msgstr "릴레ì´ì…˜(relation) ì—†ìŒ.\n" - -#: describe.c:3133 +#: describe.c:3448 msgid "List of relations" msgstr "릴레ì´ì…˜(relation) 목ë¡" -#: describe.c:3170 +#: describe.c:3485 msgid "Trusted" msgstr "신뢰ë¨" -#: describe.c:3178 -msgid "Internal Language" +#: describe.c:3493 +msgid "Internal language" msgstr "ë‚´ë¶€ 언어" -#: describe.c:3179 -msgid "Call Handler" +#: describe.c:3494 +msgid "Call handler" msgstr "호출 핸들러" -#: describe.c:3180 describe.c:4299 +#: describe.c:3495 describe.c:4633 msgid "Validator" msgstr "유효성 검사기" -#: describe.c:3183 -msgid "Inline Handler" +#: describe.c:3498 +msgid "Inline handler" msgstr "ì¸ë¼ì¸ 핸들러" -#: describe.c:3211 +#: describe.c:3526 msgid "List of languages" msgstr "언어 목ë¡" -#: describe.c:3255 -msgid "Modifier" -msgstr "기타 ì¡°ê±´" - -#: describe.c:3256 +#: describe.c:3571 msgid "Check" msgstr "ì²´í¬" -#: describe.c:3298 +#: describe.c:3613 msgid "List of domains" msgstr "ë„ë©”ì¸(domain) 목ë¡" -#: describe.c:3332 +#: describe.c:3647 msgid "Source" msgstr "소스" -#: describe.c:3333 +#: describe.c:3648 msgid "Destination" msgstr "설명" -#: describe.c:3334 describe.c:3483 +#: describe.c:3649 describe.c:3798 msgid "no" msgstr "아니오" -#: describe.c:3334 describe.c:3485 +#: describe.c:3649 describe.c:3800 msgid "yes" msgstr "예" -#: describe.c:3335 +#: describe.c:3650 msgid "Default?" msgstr "초기값?" -#: describe.c:3372 +#: describe.c:3687 msgid "List of conversions" msgstr "문ìžì½”드변환규칙(conversion) 목ë¡" -#: describe.c:3411 +#: describe.c:3726 msgid "Event" msgstr "ì´ë²¤íЏ" -#: describe.c:3413 +#: describe.c:3728 msgid "enabled" msgstr "활성화" -#: describe.c:3414 +#: describe.c:3729 msgid "replica" -msgstr "" +msgstr "replica" -#: describe.c:3415 +#: describe.c:3730 msgid "always" -msgstr "" +msgstr "í•­ìƒ" -#: describe.c:3416 +#: describe.c:3731 msgid "disabled" msgstr "비활성화" -#: describe.c:3417 +#: describe.c:3732 describe.c:5314 msgid "Enabled" msgstr "활성화" -#: describe.c:3418 +#: describe.c:3733 msgid "Procedure" msgstr "프로시져" -#: describe.c:3419 +#: describe.c:3734 msgid "Tags" -msgstr "" +msgstr "태그" -#: describe.c:3438 +#: describe.c:3753 msgid "List of event triggers" msgstr "ì´ë²¤íЏ 트리거 목ë¡" -#: describe.c:3480 +#: describe.c:3795 msgid "Source type" msgstr "Source ìžë£Œí˜•" -#: describe.c:3481 +#: describe.c:3796 msgid "Target type" msgstr "Target ìžë£Œí˜•" -#: describe.c:3484 +#: describe.c:3799 msgid "in assignment" msgstr "in assignment" -#: describe.c:3486 +#: describe.c:3801 msgid "Implicit?" msgstr "Implicit?" -#: describe.c:3537 +#: describe.c:3852 msgid "List of casts" msgstr "í˜•ë³€í™˜ìž ëª©ë¡" -#: describe.c:3565 +#: describe.c:3880 #, c-format msgid "The server (version %s) does not support collations.\n" msgstr "ì´ ì„œë²„(%s 버전)는 ë¬¸ìž ì •ë ¬(collation) ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:3616 +#: describe.c:3901 +msgid "Provider" +msgstr "제공ìž" + +#: describe.c:3936 msgid "List of collations" msgstr "ë¬¸ìž ì •ë ¬ 목ë¡" -#: describe.c:3675 +#: describe.c:3995 msgid "List of schemas" msgstr "스키마(schema) 목ë¡" -#: describe.c:3700 describe.c:3938 describe.c:4009 describe.c:4080 +#: describe.c:4020 describe.c:4267 describe.c:4338 describe.c:4409 #, c-format msgid "The server (version %s) does not support full text search.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 전문 ê²€ìƒ‰ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:3735 +#: describe.c:4055 msgid "List of text search parsers" msgstr "í…스트 검색 파서 목ë¡" -#: describe.c:3778 +#: describe.c:4100 #, c-format msgid "Did not find any text search parser named \"%s\".\n" msgstr "\"%s\"(ì´)ë¼ëŠ” í…스트 검색 파서를 찾지 못했습니다.\n" -#: describe.c:3853 +#: describe.c:4103 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "특정 í…스트 검색 파서를 찾지 못했습니다.\n" + +#: describe.c:4178 msgid "Start parse" msgstr "구문 ë¶„ì„ ì‹œìž‘" -#: describe.c:3854 +#: describe.c:4179 msgid "Method" msgstr "방법" -#: describe.c:3858 +#: describe.c:4183 msgid "Get next token" msgstr "ë‹¤ìŒ í† í° ê°€ì ¸ì˜¤ê¸°" -#: describe.c:3860 +#: describe.c:4185 msgid "End parse" msgstr "구문 ë¶„ì„ ì¢…ë£Œ" -#: describe.c:3862 +#: describe.c:4187 msgid "Get headline" msgstr "헤드ë¼ì¸ 가져오기" -#: describe.c:3864 +#: describe.c:4189 msgid "Get token types" msgstr "í† í° í˜•ì‹ ê°€ì ¸ì˜¤ê¸°" -#: describe.c:3874 +#: describe.c:4200 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "\"%s.%s\" í…스트 검색 파서" -#: describe.c:3876 +#: describe.c:4203 #, c-format msgid "Text search parser \"%s\"" msgstr "\"%s\" í…스트 검색 파서" -#: describe.c:3895 +#: describe.c:4222 msgid "Token name" msgstr "í† í° ì´ë¦„" -#: describe.c:3906 +#: describe.c:4233 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "\"%s.%s\" íŒŒì„œì˜ í† í° í˜•ì‹" -#: describe.c:3908 +#: describe.c:4236 #, c-format msgid "Token types for parser \"%s\"" msgstr "\"%s\" íŒŒì„œì˜ í† í° í˜•ì‹" -#: describe.c:3961 +#: describe.c:4290 msgid "Template" msgstr "템플릿" -#: describe.c:3962 +#: describe.c:4291 msgid "Init options" msgstr "초기화 옵션" -#: describe.c:3984 +#: describe.c:4313 msgid "List of text search dictionaries" msgstr "í…스트 검색 사전 목ë¡" -#: describe.c:4027 +#: describe.c:4356 msgid "Init" msgstr "초기화" -#: describe.c:4028 +#: describe.c:4357 msgid "Lexize" msgstr "Lexize" -#: describe.c:4055 +#: describe.c:4384 msgid "List of text search templates" msgstr "í…스트 검색 템플릿 목ë¡" -#: describe.c:4115 +#: describe.c:4444 msgid "List of text search configurations" msgstr "í…스트 검색 구성 목ë¡" -#: describe.c:4159 +#: describe.c:4490 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" msgstr "\"%s\"(ì´)ë¼ëŠ” í…스트 검색 êµ¬ì„±ì„ ì°¾ì§€ 못했습니다.\n" -#: describe.c:4225 +#: describe.c:4493 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "특정 í…스트 검색 êµ¬ì„±ì„ ì°¾ì§€ 못했습니다.\n" + +#: describe.c:4559 msgid "Token" msgstr "토í°" -#: describe.c:4226 +#: describe.c:4560 msgid "Dictionaries" msgstr "사전" -#: describe.c:4237 +#: describe.c:4571 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "í…스트 검색 구성 \"%s.%s\"" -#: describe.c:4240 +#: describe.c:4574 #, c-format msgid "Text search configuration \"%s\"" msgstr "í…스트 검색 구성 \"%s\"" -#: describe.c:4244 +#: describe.c:4578 #, c-format msgid "" "\n" @@ -1837,7 +1936,7 @@ msgstr "" "\n" "파서: \"%s.%s\"" -#: describe.c:4247 +#: describe.c:4581 #, c-format msgid "" "\n" @@ -1846,92 +1945,157 @@ msgstr "" "\n" "파서: \"%s\"" -#: describe.c:4281 +#: describe.c:4615 #, c-format msgid "The server (version %s) does not support foreign-data wrappers.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 외부 ë°ì´í„° 래í¼ë¥¼ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:4339 +#: describe.c:4673 msgid "List of foreign-data wrappers" msgstr "외부 ë°ì´í„° ëž˜í¼ ëª©ë¡" -#: describe.c:4364 +#: describe.c:4698 #, c-format msgid "The server (version %s) does not support foreign servers.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 외부 서버를 ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:4377 +#: describe.c:4711 msgid "Foreign-data wrapper" msgstr "외부 ë°ì´í„° 래í¼" -#: describe.c:4395 describe.c:4600 +#: describe.c:4729 describe.c:4934 msgid "Version" msgstr "버전" -#: describe.c:4421 +#: describe.c:4755 msgid "List of foreign servers" msgstr "외부 서버 목ë¡" -#: describe.c:4446 +#: describe.c:4780 #, c-format msgid "The server (version %s) does not support user mappings.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 ì‚¬ìš©ìž ë§¤í•‘ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:4456 describe.c:4520 +#: describe.c:4790 describe.c:4854 msgid "Server" msgstr "서버" -#: describe.c:4457 +#: describe.c:4791 msgid "User name" msgstr "ì‚¬ìš©ìž ì´ë¦„" -#: describe.c:4482 +#: describe.c:4816 msgid "List of user mappings" msgstr "ì‚¬ìš©ìž ë§¤í•‘ 목ë¡" -#: describe.c:4507 +#: describe.c:4841 #, c-format msgid "The server (version %s) does not support foreign tables.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 외부 í…Œì´ë¸”ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:4560 +#: describe.c:4894 msgid "List of foreign tables" msgstr "외부 í…Œì´ë¸” 목ë¡" -#: describe.c:4585 describe.c:4642 +#: describe.c:4919 describe.c:4976 #, c-format msgid "The server (version %s) does not support extensions.\n" msgstr "ì´ ì„œë²„(%s 버전)ì—서 í™•ìž¥ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다.\n" -#: describe.c:4617 +#: describe.c:4951 msgid "List of installed extensions" msgstr "ì„¤ì¹˜ëœ í™•ìž¥ê¸°ëŠ¥ 목ë¡" -#: describe.c:4670 +#: describe.c:5004 #, c-format msgid "Did not find any extension named \"%s\".\n" msgstr "\"%s\" ì´ë¦„ì˜ í™•ìž¥ 기능 ëª¨ë“ˆì„ ì°¾ì„ ìˆ˜ 없습니다.\n" -#: describe.c:4673 +#: describe.c:5007 #, c-format msgid "Did not find any extensions.\n" msgstr "추가할 확장 기능 ëª¨ë“ˆì´ ì—†ìŒ.\n" -#: describe.c:4717 -msgid "Object Description" -msgstr "ê°ì²´ 설명" +#: describe.c:5051 +msgid "Object description" +msgstr "개체 설명" -#: describe.c:4726 +#: describe.c:5061 #, c-format msgid "Objects in extension \"%s\"" msgstr "\"%s\" 확장 기능 ì•ˆì— í¬í•¨ëœ ê°ì²´ë“¤" -#: help.c:63 +#: describe.c:5090 describe.c:5156 +#, c-format +msgid "The server (version %s) does not support publications.\n" +msgstr "ì´ ì„œë²„(%s 버전)는 논리 복제 발행 ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다.\n" + +#: describe.c:5107 describe.c:5219 +msgid "All tables" +msgstr "모든 í…Œì´ë¸”" + +#: describe.c:5108 describe.c:5220 +msgid "Inserts" +msgstr "Inserts" + +#: describe.c:5109 describe.c:5221 +msgid "Updates" +msgstr "Updates" + +#: describe.c:5110 describe.c:5222 +msgid "Deletes" +msgstr "Deletes" + +#: describe.c:5127 +msgid "List of publications" +msgstr "발행 목ë¡" + +#: describe.c:5188 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "\"%s\" ì´ë¦„ì˜ ë°œí–‰ ì—†ìŒ.\n" + +#: describe.c:5191 +#, c-format +msgid "Did not find any publications.\n" +msgstr "발행 ì—†ìŒ.\n" + +#: describe.c:5215 +#, c-format +msgid "Publication %s" +msgstr "%s 발행" + +#: describe.c:5255 +msgid "Tables:" +msgstr "í…Œì´ë¸”" + +#: describe.c:5299 +#, c-format +msgid "The server (version %s) does not support subscriptions.\n" +msgstr "ì´ ì„œë²„(%s 버전)는 êµ¬ë… ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않습니다.\n" + +#: describe.c:5315 +msgid "Publication" +msgstr "발행" + +#: describe.c:5322 +msgid "Synchronous commit" +msgstr "ë™ê¸°ì‹ 커밋" + +#: describe.c:5323 +msgid "Conninfo" +msgstr "ì—°ê²°ì •ë³´" + +#: describe.c:5345 +msgid "List of subscriptions" +msgstr "êµ¬ë… ëª©ë¡" + +#: help.c:62 #, c-format msgid "%s\n" msgstr "%s\n" -#: help.c:74 +#: help.c:73 #, c-format msgid "" "psql is the PostgreSQL interactive terminal.\n" @@ -1940,12 +2104,12 @@ msgstr "" "psqlì€ PostgreSQL ëŒ€í™”ì‹ í„°ë¯¸ë„입니다.\n" "\n" -#: help.c:75 help.c:333 help.c:367 help.c:394 +#: help.c:74 help.c:344 help.c:383 help.c:410 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: help.c:76 +#: help.c:75 #, c-format msgid "" " psql [OPTION]... [DBNAME [USERNAME]]\n" @@ -1954,12 +2118,12 @@ msgstr "" " psql [OPTION]... [DBNAME [USERNAME]]\n" "\n" -#: help.c:78 +#: help.c:77 #, c-format msgid "General options:\n" msgstr "ì¼ë°˜ 옵션:\n" -#: help.c:83 +#: help.c:82 #, c-format msgid "" " -c, --command=COMMAND run only single command (SQL or internal) and " @@ -1967,24 +2131,24 @@ msgid "" msgstr "" " -c, --command=COMMAND í•˜ë‚˜ì˜ ëª…ë ¹(SQL ë˜ëŠ” ë‚´ë¶€ 명령)ë§Œ 실행하고 ë냄\n" -#: help.c:84 +#: help.c:83 #, c-format msgid "" " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" msgstr " -d, --dbname=DBNAME ì—°ê²°í•  ë°ì´í„°ë² ì´ìФ ì´ë¦„(기본 ê°’: \"%s\")\n" -#: help.c:85 +#: help.c:84 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" msgstr " -f, --file=FILENAME íŒŒì¼ ì•ˆì— ì§€ì •í•œ ëª…ë ¹ì„ ì‹¤í–‰í•˜ê³  ë냄\n" -#: help.c:86 +#: help.c:85 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr "" " -l, --list 사용 가능한 ë°ì´í„°ë² ì´ìФ 목ë¡ì„ 표시하고 ë냄\n" -#: help.c:87 +#: help.c:86 #, c-format msgid "" " -v, --set=, --variable=NAME=VALUE\n" @@ -1995,17 +2159,17 @@ msgstr "" " psql 변수 NAMEì„ VALUE로 설정\n" " (예, -v ON_ERROR_STOP=1)\n" -#: help.c:90 +#: help.c:89 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: help.c:91 +#: help.c:90 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" msgstr " -X, --no-psqlrc 시작 파ì¼(~/.psqlrc)ì„ ì½ì§€ 않ìŒ\n" -#: help.c:92 +#: help.c:91 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" @@ -2015,25 +2179,24 @@ msgstr "" " -1 (\"one\"), --single-transaction\n" " 명령 파ì¼ì„ í•˜ë‚˜ì˜ íŠ¸ëžœìž­ì…˜ìœ¼ë¡œ 실행\n" -#: help.c:94 +#: help.c:93 #, c-format msgid " -?, --help[=options] show this help, then exit\n" msgstr " -?, --help[=options] ì´ ë„움ë§ì„ 표시하고 종료\n" -#: help.c:95 +#: help.c:94 #, c-format msgid " --help=commands list backslash commands, then exit\n" msgstr "" " --help=commands psql 내장명령어(\\문ìžë¡œ 시작하는)를 표시하고 종" "료\n" -#: help.c:96 +#: help.c:95 #, c-format msgid " --help=variables list special variables, then exit\n" -msgstr "" -" --help=variables 특별 변수들 보여주고, 종료\n" +msgstr " --help=variables 특별 변수들 보여주고, 종료\n" -#: help.c:98 +#: help.c:97 #, c-format msgid "" "\n" @@ -2042,63 +2205,63 @@ msgstr "" "\n" "입출력 옵션:\n" -#: help.c:99 +#: help.c:98 #, c-format msgid " -a, --echo-all echo all input from script\n" msgstr " -a, --echo-all 스í¬ë¦½íŠ¸ì˜ ëª¨ë“  ìž…ë ¥ 표시\n" -#: help.c:100 +#: help.c:99 #, c-format msgid " -b, --echo-errors echo failed commands\n" msgstr " -b, --echo-errors 실패한 명령들 출력\n" -#: help.c:101 +#: help.c:100 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" msgstr " -e, --echo-queries 서버로 보낸 명령 표시\n" -#: help.c:102 +#: help.c:101 #, c-format msgid "" " -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden ë‚´ë¶€ ëª…ë ¹ì´ ìƒì„±í•˜ëŠ” 쿼리 표시\n" -#: help.c:103 +#: help.c:102 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" msgstr " -L, --log-file=FILENAME 세션 로그를 파ì¼ë¡œ 보냄\n" -#: help.c:104 +#: help.c:103 #, c-format msgid "" " -n, --no-readline disable enhanced command line editing (readline)\n" msgstr "" " -n, --no-readline í™•ìž¥ëœ ëª…ë ¹í–‰ 편집 ê¸°ëŠ¥ì„ ì‚¬ìš©ì¤‘ì§€í•¨(readline)\n" -#: help.c:105 +#: help.c:104 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" msgstr " -o, --output=FILENAME 쿼리 결과를 파ì¼(ë˜ëŠ” |파ì´í”„)로 보냄\n" -#: help.c:106 +#: help.c:105 #, c-format msgid "" " -q, --quiet run quietly (no messages, only query output)\n" msgstr " -q, --quiet ìžë™ 실행(메시지 ì—†ì´ ì¿¼ë¦¬ 결과만 표시)\n" -#: help.c:107 +#: help.c:106 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" msgstr " -s, --single-step ë‹¨ë… ìˆœì°¨ 모드(ê° ì¿¼ë¦¬ 확ì¸)\n" -#: help.c:108 +#: help.c:107 #, c-format msgid "" " -S, --single-line single-line mode (end of line terminates SQL " "command)\n" msgstr " -S, --single-line 한 줄 모드(줄 ëì—서 SQL ëª…ë ¹ì´ ì¢…ë£Œë¨)\n" -#: help.c:110 +#: help.c:109 #, c-format msgid "" "\n" @@ -2107,12 +2270,12 @@ msgstr "" "\n" "출력 í˜•ì‹ ì˜µì…˜:\n" -#: help.c:111 +#: help.c:110 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align ì •ë ¬ë˜ì§€ ì•Šì€ í‘œ í˜•íƒœì˜ ì¶œë ¥ 모드\n" -#: help.c:112 +#: help.c:111 #, c-format msgid "" " -F, --field-separator=STRING\n" @@ -2123,12 +2286,12 @@ msgstr "" " unaligned 출력용 필드 êµ¬ë¶„ìž ì„¤ì •(기본 ê°’: \"%s" "\")\n" -#: help.c:115 +#: help.c:114 #, c-format msgid " -H, --html HTML table output mode\n" msgstr " -H, --html HTML 표 형태 출력 모드\n" -#: help.c:116 +#: help.c:115 #, c-format msgid "" " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " @@ -2136,7 +2299,7 @@ msgid "" msgstr "" " -P, --pset=VAR[=ARG] ì¸ì‡„ 옵션 VARì„ ARG로 설정(\\pset 명령 참조)\n" -#: help.c:117 +#: help.c:116 #, c-format msgid "" " -R, --record-separator=STRING\n" @@ -2147,12 +2310,12 @@ msgstr "" " unaligned 출력용 레코드 êµ¬ë¶„ìž ì„¤ì •\n" " (기본 ê°’: 줄바꿈 문ìž)\n" -#: help.c:119 +#: help.c:118 #, c-format msgid " -t, --tuples-only print rows only\n" msgstr " -t, --tuples-only 행만 ì¸ì‡„\n" -#: help.c:120 +#: help.c:119 #, c-format msgid "" " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " @@ -2160,12 +2323,12 @@ msgid "" msgstr "" " -T, --table-attr=TEXT HTML table 태그 ì†ì„± 설정(예: width, border)\n" -#: help.c:121 +#: help.c:120 #, c-format msgid " -x, --expanded turn on expanded table output\n" msgstr " -x, --expanded í™•ìž¥ëœ í‘œ 형태로 출력\n" -#: help.c:122 +#: help.c:121 #, c-format msgid "" " -z, --field-separator-zero\n" @@ -2175,7 +2338,7 @@ msgstr "" " -z, --field-separator-zero\n" " unaligned 출력용 필드 구분ìžë¥¼ 0 ë°”ì´íŠ¸ë¡œ 지정\n" -#: help.c:124 +#: help.c:123 #, c-format msgid "" " -0, --record-separator-zero\n" @@ -2185,7 +2348,7 @@ msgstr "" " -0, --record-separator-zero\n" " unaligned 출력용 레코드 구분ìžë¥¼ 0 ë°”ì´íŠ¸ë¡œ 지정\n" -#: help.c:127 +#: help.c:126 #, c-format msgid "" "\n" @@ -2194,7 +2357,7 @@ msgstr "" "\n" "ì—°ê²° 옵션들:\n" -#: help.c:130 +#: help.c:129 #, c-format msgid "" " -h, --host=HOSTNAME database server host or socket directory " @@ -2203,33 +2366,33 @@ msgstr "" " -h, --host=HOSTNAME ë°ì´í„°ë² ì´ìФ 서버 호스트 ë˜ëŠ” 소켓 디렉터리\n" " (기본값: \"%s\")\n" -#: help.c:131 +#: help.c:130 msgid "local socket" msgstr "로컬 소켓" -#: help.c:134 +#: help.c:133 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" msgstr " -p, --port=PORT ë°ì´í„°ë² ì´ìФ 서버 í¬íЏ(기본 ê°’: \"%s\")\n" -#: help.c:140 +#: help.c:139 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr " -U, --username=USERNAME ë°ì´í„°ë² ì´ìФ ì‚¬ìš©ìž ì´ë¦„(기본 ê°’: \"%s\")\n" -#: help.c:141 +#: help.c:140 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password 암호 프롬프트 표시 안 함\n" -#: help.c:142 +#: help.c:141 #, c-format msgid "" " -W, --password force password prompt (should happen " "automatically)\n" msgstr " -W, --password 암호 ìž…ë ¥ 프롬프트 ë³´ìž„(ìžë™ìœ¼ë¡œ 처리함)\n" -#: help.c:144 +#: help.c:143 #, c-format msgid "" "\n" @@ -2245,22 +2408,29 @@ msgstr "" "설명서ì—서 psql ì„¹ì…˜ì„ ì°¸ì¡°í•˜ì‹­ì‹œì˜¤.\n" "\n" -#: help.c:147 +#: help.c:146 #, c-format msgid "Report bugs to .\n" msgstr "오류보고: .\n" -#: help.c:173 +#: help.c:172 #, c-format msgid "General\n" msgstr "ì¼ë°˜\n" -#: help.c:174 +#: help.c:173 #, c-format msgid "" " \\copyright show PostgreSQL usage and distribution terms\n" msgstr " \\copyright PostgreSQL 사용법 ë° ì €ìž‘ê¶Œ ì •ë³´ 표시\n" +#: help.c:174 +#, c-format +msgid "" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [칼럼들] 쿼리를 실행하고, 피봇 í…Œì´ë¸” 형태로 ìžë£Œë¥¼ 보여줌\n" + #: help.c:175 #, c-format msgid "" @@ -2281,8 +2451,7 @@ msgstr "" msgid "" " \\gexec execute query, then execute each value in its " "result\n" -msgstr "" -" \\gexec 쿼리를 실행하고, ê·¸ 결과를 ê°ê° 실행 함\n" +msgstr " \\gexec 쿼리를 실행하고, ê·¸ 결과를 ê°ê° 실행 함\n" #: help.c:178 #, c-format @@ -2292,15 +2461,14 @@ msgstr " \\gset [PREFIX] 쿼리 실행 ë’¤ ê·¸ 결과를 psql 변수로 #: help.c:179 #, c-format -msgid " \\q quit psql\n" -msgstr " \\q psql 종료\n" +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr "" +" \\gx [FILE] \\g 명령과 같으나, ì¶œë ¥ì„ í™•ìž¥ 모드로 강제함\n" #: help.c:180 #, c-format -msgid "" -" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" -msgstr "" -" \\crosstabview [칼럼들] 쿼리를 실행하고, 피봇 í…Œì´ë¸” 형태로 ìžë£Œë¥¼ 보여줌\n" +msgid " \\q quit psql\n" +msgstr " \\q psql 종료\n" #: help.c:181 #, c-format @@ -2424,242 +2592,280 @@ msgstr " \\qecho [STRING] 문ìžì—´ì„ 쿼리 출력 ìŠ¤íŠ¸ë¦¼ì— ê¸°ë¡ #: help.c:213 #, c-format +msgid "Conditional\n" +msgstr "조건문\n" + +#: help.c:214 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR 조건문 시작\n" + +#: help.c:215 +#, c-format +msgid "" +" \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR else if 구문 시작\n" + +#: help.c:216 +#, c-format +msgid "" +" \\else final alternative within current conditional " +"block\n" +msgstr " \\else ì¡°ê±´ë¬¸ì˜ ê·¸ 외 ì¡°ê±´\n" + +#: help.c:217 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif 조건문 ë\n" + +#: help.c:220 +#, c-format msgid "Informational\n" msgstr "정보보기\n" -#: help.c:214 +#: help.c:221 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (옵션: S = 시스템 개체 표시, + = 추가 ìƒì„¸ ì •ë³´)\n" -#: help.c:215 +#: help.c:222 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] í…Œì´ë¸”, ë·° ë° ì‹œí€€ìŠ¤ 목ë¡\n" -#: help.c:216 +#: help.c:223 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NAME í…Œì´ë¸”, ë·°, 시퀀스 ë˜ëŠ” ì¸ë±ìФ 설명\n" -#: help.c:217 +#: help.c:224 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [PATTERN] 집계 함수 목ë¡\n" -#: help.c:218 +#: help.c:225 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [PATTERN] ì ‘ê·¼ 방법 목ë¡\n" -#: help.c:219 +#: help.c:226 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [PATTERN] í…Œì´ë¸”스페ì´ìФ 목ë¡\n" -#: help.c:220 +#: help.c:227 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [PATTERN] 문ìžì…‹ ë³€í™˜ìž ëª©ë¡\n" -#: help.c:221 +#: help.c:228 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [PATTERN] ìžë£Œí˜• ë³€í™˜ìž ëª©ë¡\n" -#: help.c:222 +#: help.c:229 #, c-format msgid "" " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr "" " \\dd[S] [PATTERN] 다른 ê³³ì—서는 ë³¼ 수 없는 ê°ì²´ ì„¤ëª…ì„ ë³´ì—¬ì¤Œ\n" -#: help.c:223 +#: help.c:230 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] ë„ë©”ì¸ ëª©ë¡\n" + +#: help.c:231 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [PATTERN] 기본 접근권한 목ë¡\n" -#: help.c:224 +#: help.c:232 #, c-format -msgid " \\dD[S+] [PATTERN] list domains\n" -msgstr " \\dD[S+] [PATTERN] ë„ë©”ì¸ ëª©ë¡\n" +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [PATTERN] 외부 í…Œì´ë¸” 목ë¡\n" -#: help.c:225 +#: help.c:233 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [PATTERN] 외부 í…Œì´ë¸” 목ë¡\n" -#: help.c:226 +#: help.c:234 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [PATTERN] 외부 서버 목ë¡\n" -#: help.c:227 +#: help.c:235 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [PATTERN] ì‚¬ìš©ìž ë§¤í•‘ 목ë¡\n" -#: help.c:228 +#: help.c:236 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [PATTERN] 외부 ë°ì´í„° ëž˜í¼ ëª©ë¡\n" -#: help.c:229 +#: help.c:237 #, c-format msgid "" " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" msgstr " \\df[antw][S+] [PATRN] [only agg/normal/trigger/window] 함수 목ë¡\n" -#: help.c:230 +#: help.c:238 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [PATTERN] í…스트 검색 구성 목ë¡\n" -#: help.c:231 +#: help.c:239 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [PATTERN] í…스트 검색 사전 목ë¡\n" -#: help.c:232 +#: help.c:240 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [PATTERN] í…스트 검색 파서 목ë¡\n" -#: help.c:233 +#: help.c:241 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [PATTERN] í…스트 검색 템플릿 목ë¡\n" -#: help.c:234 +#: help.c:242 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [PATTERN] 롤 목ë¡\n" -#: help.c:235 +#: help.c:243 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [PATTERN] ì¸ë±ìФ 목ë¡\n" -#: help.c:236 +#: help.c:244 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl í° ê°œì²´ 목ë¡, \\lo_list 명령과 ê°™ìŒ\n" -#: help.c:237 +#: help.c:245 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [PATTERN] 프로시져 언어 목ë¡\n" -#: help.c:238 +#: help.c:246 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [PATTERN] materialized ë·° 목ë¡\n" -#: help.c:239 +#: help.c:247 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [PATTERN] 스키마 목ë¡\n" -#: help.c:240 +#: help.c:248 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [PATTERN] ì—°ì‚°ìž ëª©ë¡\n" -#: help.c:241 +#: help.c:249 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [PATTERN] collation 목ë¡\n" -#: help.c:242 +#: help.c:250 #, c-format msgid "" " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr " \\dp [PATTERN] í…Œì´ë¸”, ë·° ë° ì‹œí€€ìŠ¤ 액세스 권한 목ë¡\n" -#: help.c:243 +#: help.c:251 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [PATRN1 [PATRN2]] ë°ì´í„°ë² ì´ìŠ¤ë³„ 롤 설정 목ë¡\n" -#: help.c:244 +#: help.c:252 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] 복제 발행 목ë¡\n" + +#: help.c:253 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] 복제 êµ¬ë… ëª©ë¡\n" + +#: help.c:254 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [PATTERN] 시퀀스 목ë¡\n" -#: help.c:245 +#: help.c:255 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [PATTERN] í…Œì´ë¸” 목ë¡\n" -#: help.c:246 +#: help.c:256 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [PATTERN] ë°ì´í„° í˜•ì‹ ëª©ë¡\n" -#: help.c:247 +#: help.c:257 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [PATTERN] 롤 목ë¡\n" -#: help.c:248 +#: help.c:258 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [PATTERN] ë·° 목ë¡\n" -#: help.c:249 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [PATTERN] 외부 í…Œì´ë¸” 목ë¡\n" - -#: help.c:250 +#: help.c:259 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [PATTERN] 확장 모듈 목ë¡\n" -#: help.c:251 +#: help.c:260 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [PATTERN] ì´ë²¤íЏ 트리거 목ë¡\n" -#: help.c:252 +#: help.c:261 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [PATTERN] ë°ì´í„°ë² ì´ìФ 목ë¡\n" -#: help.c:253 +#: help.c:262 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] 함수ì´ë¦„ 함수 ì •ì˜ ë³´ê¸°\n" -#: help.c:254 +#: help.c:263 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] ë·°ì´ë¦„ ë·° ì •ì˜ ë³´ê¸°\n" -#: help.c:255 +#: help.c:264 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [PATTERN] \\dp와 ê°™ìŒ\n" -#: help.c:258 +#: help.c:267 #, c-format msgid "Formatting\n" msgstr "출력 형ì‹\n" -#: help.c:259 +#: help.c:268 #, c-format msgid "" " \\a toggle between unaligned and aligned output mode\n" msgstr "" " \\a ì •ë ¬ë˜ì§€ ì•Šì€ ì¶œë ¥ 모드와 ì •ë ¬ëœ ì¶œë ¥ 모드 전환\n" -#: help.c:260 +#: help.c:269 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr "" " \\C [STRING] í…Œì´ë¸” 제목 설정 ë˜ëŠ” ê°’ì´ ì—†ëŠ” 경우 설정 안 함\n" -#: help.c:261 +#: help.c:270 #, c-format msgid "" " \\f [STRING] show or set field separator for unaligned query " @@ -2667,35 +2873,40 @@ msgid "" msgstr "" " \\f [STRING] unaligned ì¶œë ¥ì— ëŒ€í•´ 필드 êµ¬ë¶„ìž í‘œì‹œ ë˜ëŠ” 설정\n" -#: help.c:262 +#: help.c:271 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H HTML 출력 모드 전환(현재 %s)\n" -#: help.c:264 +#: help.c:273 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|" +" (NAME := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" "unicode_header_linestyle})\n" msgstr "" -" \\pset [NAME [VALUE]] 표 출력 옵션\n" -" (NAME := {format|border|expanded|fieldsep|\n" -" fieldsep_zero|footer|null|numericlocale|recordsep|\n" -" recordsep_zero|tuples_only|title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|\n" -" unicode_header_linestyle})\n" +" \\pset [ì´ë¦„ [ê°’]] í…Œì´ë¸” 출력 옵션 설정\n" +" (ì´ë¦„ := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" +"unicode_header_linestyle})\n" -#: help.c:268 +#: help.c:279 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] 행만 표시(현재 %s)\n" -#: help.c:270 +#: help.c:281 #, c-format msgid "" " \\T [STRING] set HTML
tag attributes, or unset if none\n" @@ -2703,17 +2914,17 @@ msgstr "" " \\T [STRING] HTML
태그 ì†ì„± 설정 ë˜ëŠ” 비었는 경우 설정 " "안 함\n" -#: help.c:271 +#: help.c:282 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] í™•ìž¥ëœ ì¶œë ¥ 전환 (현재 %s)\n" -#: help.c:275 +#: help.c:286 #, c-format msgid "Connection\n" msgstr "ì—°ê²°\n" -#: help.c:277 +#: help.c:288 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2722,7 +2933,7 @@ msgstr "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " 새 ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì† (현재 \"%s\")\n" -#: help.c:281 +#: help.c:292 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2731,61 +2942,61 @@ msgstr "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " 새 ë°ì´í„°ë² ì´ìŠ¤ì— ì ‘ì† (현재 ì ‘ì†í•´ 있지 않ìŒ)\n" -#: help.c:283 +#: help.c:294 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo 현재 ë°ì´í„°ë² ì´ìФ ì ‘ì† ì •ë³´ 보기\n" + +#: help.c:295 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [ENCODING] í´ë¼ì´ì–¸íЏ ì¸ì½”딩 표시 ë˜ëŠ” 설정\n" -#: help.c:284 +#: help.c:296 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [USERNAME] ì‚¬ìš©ìž ì•”í˜¸ë¥¼ 안전하게 변경\n" -#: help.c:285 -#, c-format -msgid "" -" \\conninfo display information about current connection\n" -msgstr " \\conninfo 현재 ë°ì´í„°ë² ì´ìФ ì ‘ì† ì •ë³´ 보기\n" - -#: help.c:288 +#: help.c:299 #, c-format msgid "Operating System\n" msgstr "ìš´ì˜ ì²´ì œ\n" -#: help.c:289 +#: help.c:300 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [DIR] 현재 작업 디렉터리 변경\n" -#: help.c:290 +#: help.c:301 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAME [VALUE] 환경 변수 지정 ë° í•´ì œ\n" -#: help.c:291 +#: help.c:302 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] 명령 실행 시간 전환(현재 %s)\n" -#: help.c:293 +#: help.c:304 #, c-format msgid "" " \\! [COMMAND] execute command in shell or start interactive " "shell\n" msgstr " \\! [COMMAND] ì…¸ 명령 실행 ë˜ëŠ” ëŒ€í™”ì‹ ì…¸ 시작\n" -#: help.c:296 +#: help.c:307 #, c-format msgid "Variables\n" msgstr "변수\n" -#: help.c:297 +#: help.c:308 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr "" " \\prompt [TEXT] NAME 사용ìžì—게 ë‚´ë¶€ 변수를 설정하ë¼ëŠ” 메시지 표시\n" -#: help.c:298 +#: help.c:309 #, c-format msgid "" " \\set [NAME [VALUE]] set internal variable, or list all if no " @@ -2794,17 +3005,17 @@ msgstr "" " \\set [NAME [VALUE]] ë‚´ë¶€ 변수 설정 ë˜ëŠ” 미지정 경우 모든 변수 ëª©ë¡ í‘œ" "시\n" -#: help.c:299 +#: help.c:310 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NAME ë‚´ë¶€ 변수 설정 í•´ì œ(ì‚­ì œ)\n" -#: help.c:302 +#: help.c:313 #, c-format msgid "Large Objects\n" msgstr "í° ê°œì²´\n" -#: help.c:303 +#: help.c:314 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2817,19 +3028,19 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID í° ê°œì²´ 작업\n" -#: help.c:330 +#: help.c:341 #, c-format msgid "" "List of specially treated variables\n" "\n" msgstr "특별한 기능 설정 변수 목ë¡\n" -#: help.c:332 +#: help.c:343 #, c-format msgid "psql variables:\n" msgstr "psql 변수들:\n" -#: help.c:334 +#: help.c:345 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -2840,167 +3051,211 @@ msgstr "" " ë˜ëŠ” psql 명령 모드ì—서는 \\set NAME VALUE\n" "\n" -#: help.c:336 +#: help.c:347 #, c-format msgid "" " AUTOCOMMIT if set, successful SQL commands are automatically " "committed\n" msgstr " AUTOCOMMIT 지정 하면 SQL ëª…ë ¹ì´ ì„±ê³µí•˜ë©´ ìžë™ìœ¼ë¡œ 커밋\n" -#: help.c:337 +#: help.c:348 #, c-format msgid "" " COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" " [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" +" COMP_KEYWORD_CASE SQL 키워드 ìžë™ì™„성ì—서 ëŒ€ì†Œë¬¸ìž ì²˜ë¦¬\n" +" [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:339 +#: help.c:350 #, c-format msgid " DBNAME the currently connected database name\n" msgstr " DBNAME 현재 ì ‘ì†í•œ ë°ì´í„°ë² ì´ìФ ì´ë¦„\n" -#: help.c:340 +#: help.c:351 #, c-format msgid "" " ECHO controls what input is written to standard output\n" " [all, errors, none, queries]\n" msgstr "" +" ECHO ìž…ë ¥ì„ í‘œì¤€ 출력으로 보낼 종류\n" +" [all, errors, none, queries]\n" -#: help.c:342 +#: help.c:353 #, c-format msgid "" " ECHO_HIDDEN if set, display internal queries executed by backslash " "commands;\n" " if set to \"noexec\", just show without execution\n" msgstr "" +" ECHO_HIDDEN 지정 ë˜ë©´ psql 내장 ëª…ë ¹ì–´ì˜ ë‚´ë¶€ 쿼리를 출력함;\n" +" \"noexec\" 값으로 설정하면, 실행ë˜ì§€ 않고 쿼리만 ë³´ì—¬" +"줌\n" -#: help.c:344 +#: help.c:355 #, c-format msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING 현재 í´ë¼ì´ì–¸íЏ ì¸ì½”딩\n" +msgstr " ENCODING 현재 í´ë¼ì´ì–¸íЏ ì¸ì½”딩 지정\n" -#: help.c:345 +#: help.c:356 #, c-format msgid "" " FETCH_COUNT the number of result rows to fetch and display at a " "time\n" " (default: 0=unlimited)\n" msgstr "" +" FETCH_COUNT 쿼리 ê²°ê³¼ì— ëŒ€í•´ì„œ 출력할 최대 로우 개수\n" +" (기본값: 0=제한없ìŒ)\n" -#: help.c:347 +#: help.c:358 #, c-format msgid "" " HISTCONTROL controls command history [ignorespace, ignoredups, " "ignoreboth]\n" msgstr "" +" HISTCONTROL 명령 ë‚´ì—­ 처리 방법 [ignorespace, ignoredups, " +"ignoreboth]\n" -#: help.c:348 +#: help.c:359 #, c-format msgid " HISTFILE file name used to store the command history\n" -msgstr "" +msgstr " HISTFILE 명령 ë‚´ì—­ì„ ì €ìž¥í•  íŒŒì¼ ì´ë¦„\n" -#: help.c:349 +#: help.c:360 #, c-format msgid "" -" HISTSIZE the number of commands to store in the command history\n" -msgstr "" +" HISTSIZE max number of commands to store in the command history\n" +msgstr " HISTSIZE 명령 ë‚´ì—­ 최대 ë³´ê´€ 개수\n" -#: help.c:350 +#: help.c:361 #, c-format msgid " HOST the currently connected database server host\n" msgstr " HOST 현재 ì ‘ì†í•œ ë°ì´í„°ë² ì´ìФ 서버\n" -#: help.c:351 +#: help.c:362 #, c-format msgid "" -" IGNOREEOF if unset, sending an EOF to interactive session " -"terminates application\n" -msgstr "" +" IGNOREEOF number of EOFs needed to terminate an interactive " +"session\n" +msgstr " IGNOREEOF 대화형 세션 종료를 위한 EOF 개수\n" -#: help.c:352 +#: help.c:363 #, c-format msgid " LASTOID value of the last affected OID\n" msgstr " LASTOID 마지막 ì˜í–¥ ë°›ì€ OID\n" -#: help.c:353 +#: help.c:364 #, c-format msgid "" " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses " "implicit savepoints)\n" msgstr "" +" ON_ERROR_ROLLBACK 설정하면 오류 ë°œìƒì‹œì—ë„ íŠ¸ëžœìž­ì…˜ 중지 안함 (savepoint\n" +" ì•”ë¬µì  ì‚¬ìš©)\n" -#: help.c:354 +#: help.c:365 #, c-format msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr "" +msgstr " ON_ERROR_STOP 배치 작업 시 오류가 ë°œìƒí•˜ë©´ 중지함\n" -#: help.c:355 +#: help.c:366 #, c-format msgid " PORT server port of the current connection\n" msgstr " PORT 현재 ì ‘ì†í•œ 서버 í¬íЏ\n" -#: help.c:356 +#: help.c:367 #, c-format msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr "" +msgstr " PROMPT1 기본 psql 프롬프트 ì •ì˜\n" -#: help.c:357 +#: help.c:368 #, c-format msgid "" " PROMPT2 specifies the prompt used when a statement continues " "from a previous line\n" -msgstr "" +msgstr " PROMPT2 ì•„ì§ êµ¬ë¬¸ì´ ëœ ë난 ëª…ë ¹í–‰ì˜ í”„ë¡¬í”„íŠ¸\n" -#: help.c:358 +#: help.c:369 #, c-format msgid "" " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr "" +msgstr " PROMPT3 COPY ... FROM STDIN 작업시 ë³´ì¼ í”„ë¡¬í”„íŠ¸\n" -#: help.c:359 +#: help.c:370 #, c-format msgid " QUIET run quietly (same as -q option)\n" msgstr " QUIET 조용히 실행 (-q 옵션과 ê°™ìŒ)\n" -#: help.c:360 +#: help.c:371 +#, c-format +msgid " SERVER_VERSION_NAME server's version (short string)\n" +msgstr "" + +#: help.c:372 +#, c-format +msgid " SERVER_VERSION_NUM server's version (numeric format)\n" +msgstr "" + +#: help.c:373 #, c-format msgid "" " SHOW_CONTEXT controls display of message context fields [never, " "errors, always]\n" msgstr "" +" SHOW_CONTEXT ìƒí™©ë³„ ìžì„¸í•œ 메시지 ë‚´ìš© 출력 제어 [never, errors,\n" +" always]\n" -#: help.c:361 +#: help.c:374 #, c-format msgid "" " SINGLELINE end of line terminates SQL command mode (same as -S " "option)\n" -msgstr "" +msgstr " SINGLELINE 한 ì¤„ì— í•˜ë‚˜ì˜ SQL 명령 실행 (-S 옵션과 ê°™ìŒ)\n" -#: help.c:362 +#: help.c:375 #, c-format msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr "" +msgstr " SINGLESTEP ê° ëª…ë ¹ì„ í™•ì¸í•˜ë©° 실행 (-s 옵션과 ê°™ìŒ)\n" -#: help.c:363 +#: help.c:376 #, c-format msgid " USER the currently connected database user\n" msgstr " USER 현재 ì ‘ì†í•œ ë°ì´í„°ë² ì´ìФ 사용ìž\n" -#: help.c:364 +#: help.c:377 #, c-format msgid "" " VERBOSITY controls verbosity of error reports [default, verbose, " "terse]\n" msgstr "" +" VERBOSITY 오류 출력시 ìžì„¸ížˆ ë³¼ ë‚´ìš© 범위 [default, verbose, " +"terse]\n" + +#: help.c:378 +#, c-format +msgid " VERSION psql's version (verbose string)\n" +msgstr "" -#: help.c:366 +#: help.c:379 +#, c-format +msgid " VERSION_NAME psql's version (short string)\n" +msgstr "" + +#: help.c:380 +#, c-format +msgid " VERSION_NUM psql's version (numeric format)\n" +msgstr "" + +#: help.c:382 #, c-format msgid "" "\n" "Display settings:\n" -msgstr "\n출력 설정들:\n" +msgstr "" +"\n" +"출력 설정들:\n" -#: help.c:368 +#: help.c:384 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3011,43 +3266,41 @@ msgstr "" " ë˜ëŠ” psql 명령 모드ì—서는 \\pset NAME [VALUE]\n" "\n" -#: help.c:370 +#: help.c:386 #, c-format msgid " border border style (number)\n" msgstr " border í…Œë‘리 모양 (숫ìž)\n" -#: help.c:371 +#: help.c:387 #, c-format msgid " columns target width for the wrapped format\n" msgstr " columns ì¤„ë°”ê¿ˆì„ ìœ„í•œ 너비 지정\n" -#: help.c:372 +#: help.c:388 #, c-format msgid " expanded (or x) expanded output [on, off, auto]\n" msgstr " expanded (ë˜ëŠ” x) í™•ìž¥ëœ ì¶œë ¥ 전환 [on, off, auto]\n" -#: help.c:373 +#: help.c:389 #, c-format msgid "" " fieldsep field separator for unaligned output (default \"%s\")\n" -msgstr "" -" fieldsep unaligned 출력용 필드 êµ¬ë¶„ìž (초기값 \"%s\"')\n" +msgstr " fieldsep unaligned 출력용 필드 êµ¬ë¶„ìž (초기값 \"%s\"')\n" -#: help.c:374 +#: help.c:390 #, c-format msgid "" " fieldsep_zero set field separator for unaligned output to zero byte\n" -msgstr "" -" fieldsep_zero unaligned 출력용 필드 구분ìžë¥¼ 0 ë°”ì´íŠ¸ë¡œ 지정\n" +msgstr " fieldsep_zero unaligned 출력용 필드 구분ìžë¥¼ 0 ë°”ì´íŠ¸ë¡œ 지정\n" -#: help.c:375 +#: help.c:391 #, c-format msgid "" " footer enable or disable display of the table footer [on, " "off]\n" msgstr " footer í…Œì´ë¸” ê¼¬ë¦¬ë§ ë³´ì´ê¸° 전환 [on, off]\n" -#: help.c:376 +#: help.c:392 #, c-format msgid "" " format set output format [unaligned, aligned, wrapped, html, " @@ -3056,47 +3309,50 @@ msgstr "" " format 출력 ì–‘ì‹ ì§€ì • [unaligned, aligned, wrapped, html, " "asciidoc, ...]\n" -#: help.c:377 +#: help.c:393 #, c-format msgid "" " linestyle set the border line drawing style [ascii, old-ascii, " "unicode]\n" -msgstr "" +msgstr " linestyle í…Œë‘리 ì„  모양 지정 [ascii, old-ascii, unicode]\n" -#: help.c:378 +#: help.c:394 #, c-format msgid "" " null set the string to be printed in place of a null value\n" -msgstr "" +msgstr " null null ê°’ 출력 방법\n" -#: help.c:379 +#: help.c:395 #, c-format msgid "" " numericlocale enable or disable display of a locale-specific " "character to separate\n" " groups of digits [on, off]\n" msgstr "" +" numericlocale ìˆ«ìž ì¶œë ¥ì—서 ë¡œì¼€ì¼ ê¸°ë°˜ 천ìžë¦¬ 분리 ë¬¸ìž í™œì„±í™”\n" +" [on, off]\n" -#: help.c:381 +#: help.c:397 #, c-format msgid "" " pager control when an external pager is used [yes, no, " "always]\n" msgstr "" +" pager 외부 페ì´ì§€ 단위 보기 ë„구 사용 여부 [yes, no, always]\n" -#: help.c:382 +#: help.c:398 #, c-format msgid " recordsep record (line) separator for unaligned output\n" msgstr " recordsep unaligned 출력용 레코드(줄) 구분ìž\n" -#: help.c:383 +#: help.c:399 #, c-format msgid "" " recordsep_zero set record separator for unaligned output to zero byte\n" msgstr "" " recordsep_zero unaligned 출력용 레코드 구분ìžë¥¼ 0 ë°”ì´íŠ¸ë¡œ 지정\n" -#: help.c:384 +#: help.c:400 #, c-format msgid "" " tableattr (or T) specify attributes for table tag in html format or " @@ -3104,20 +3360,23 @@ msgid "" " column widths for left-aligned data types in latex-" "longtable format\n" msgstr "" +" tableattr (ë˜ëŠ” T) html í…Œì´ë¸” íƒœê·¸ì— ëŒ€í•œ ì†ì„±ì´ë‚˜,\n" +" latex-longtable ì–‘ì‹ì—서 왼쪽 ì •ë ¬ ìžë£Œìš© 칼럼 ë„“ì´ ì§€" +"ì •\n" -#: help.c:386 +#: help.c:402 #, c-format msgid "" " title set the table title for any subsequently printed " "tables\n" msgstr " title í…Œì´ë¸” 제목 지정\n" -#: help.c:387 +#: help.c:403 #, c-format msgid " tuples_only if set, only actual table data is shown\n" msgstr " tuples_only 지정ë˜ë©´, ìžë£Œë§Œ ë³´ìž„\n" -#: help.c:388 +#: help.c:404 #, c-format msgid "" " unicode_border_linestyle\n" @@ -3130,7 +3389,7 @@ msgstr "" " unicode_header_linestyle\n" " 유니코드 ì„  종류 [single, double]\n" -#: help.c:393 +#: help.c:409 #, c-format msgid "" "\n" @@ -3139,7 +3398,7 @@ msgstr "" "\n" "OS 환경 변수들:\n" -#: help.c:397 +#: help.c:413 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3150,7 +3409,7 @@ msgstr "" " ë˜ëŠ” psql 명령 모드ì—서는 \\setenv NAME [VALUE]\n" "\n" -#: help.c:399 +#: help.c:415 #, c-format msgid "" " set NAME=VALUE\n" @@ -3163,53 +3422,53 @@ msgstr "" " ë˜ëŠ” psql 명령 모드ì—서는 \\setenv NAME [VALUE]\n" "\n" -#: help.c:402 +#: help.c:418 #, c-format msgid " COLUMNS number of columns for wrapped format\n" msgstr " COLUMNS ë‹¤ìŒ ì¤„ë¡œ 넘어갈 칼럼 수\n" -#: help.c:403 +#: help.c:419 #, c-format msgid " PAGER name of external pager program\n" msgstr " PAGER 페ì´ì§€ 단위 보기ì—서 사용할 프로그램\n" -#: help.c:404 +#: help.c:420 #, c-format msgid "" " PGAPPNAME same as the application_name connection parameter\n" msgstr " PGAPPNAME application_name 변수값으로 사용ë¨\n" -#: help.c:405 +#: help.c:421 #, c-format msgid " PGDATABASE same as the dbname connection parameter\n" msgstr " PGDATABASE ì ‘ì†í•  ë°ì´í„°ë² ì´ìФ ì´ë¦„\n" -#: help.c:406 +#: help.c:422 #, c-format msgid " PGHOST same as the host connection parameter\n" msgstr " PGHOST 서버 ì ‘ì†ìš© 호스트 ì´ë¦„\n" -#: help.c:407 -#, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT 서버 ì ‘ì†ìš© í¬íЏ\n" - -#: help.c:408 -#, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER 서버 ì ‘ì†ìš© ë°ì´í„°ë² ì´ìФ ì‚¬ìš©ìž ì´ë¦„\n" - -#: help.c:409 +#: help.c:423 #, c-format msgid " PGPASSWORD connection password (not recommended)\n" msgstr " PGPASSWORD 서버 ì ‘ì† ë¹„ë°€ë²ˆí˜¸ (ë³´ì•ˆì— ì·¨ì•½í•¨)\n" -#: help.c:410 +#: help.c:424 #, c-format msgid " PGPASSFILE password file name\n" msgstr " PGPASSFILE 서버 ì ‘ì†ìš© 비밀번호가 ì €ìž¥ëœ íŒŒì¼ ì´ë¦„\n" -#: help.c:411 +#: help.c:425 +#, c-format +msgid " PGPORT same as the port connection parameter\n" +msgstr " PGPORT 서버 ì ‘ì†ìš© í¬íЏ\n" + +#: help.c:426 +#, c-format +msgid " PGUSER same as the user connection parameter\n" +msgstr " PGUSER 서버 ì ‘ì†ìš© ë°ì´í„°ë² ì´ìФ ì‚¬ìš©ìž ì´ë¦„\n" + +#: help.c:427 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" @@ -3218,7 +3477,7 @@ msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" " \\e, \\ef, \\ev 명령ì—서 사용할 외부 편집기 경로\n" -#: help.c:413 +#: help.c:429 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" @@ -3227,32 +3486,32 @@ msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" " 외부 편집기 호출 시 사용할 줄번호 ì„ íƒ ì˜µì…˜\n" -#: help.c:415 +#: help.c:431 #, c-format msgid "" " PSQL_HISTORY alternative location for the command history file\n" msgstr " PSQL_HISTORY ì‚¬ìš©ìž .psql_history íŒŒì¼ ìž„ì˜ ì§€ì •\n" -#: help.c:416 +#: help.c:432 #, c-format msgid " PSQLRC alternative location for the user's .psqlrc file\n" msgstr " PSQLRC ì‚¬ìš©ìž .psqlrc 파ì¼ì˜ ìž„ì˜ ì§€ì •\n" -#: help.c:417 +#: help.c:433 #, c-format msgid " SHELL shell used by the \\! command\n" msgstr " SHELL \\! 명령ì—서 사용할 쉘\n" -#: help.c:418 +#: help.c:434 #, c-format msgid " TMPDIR directory for temporary files\n" msgstr " TMPDIR 임시 파ì¼ì„ 사용할 디렉터리\n" -#: help.c:461 +#: help.c:477 msgid "Available help:\n" msgstr "사용 가능한 ë„움ë§:\n" -#: help.c:545 +#: help.c:561 #, c-format msgid "" "Command: %s\n" @@ -3267,7 +3526,7 @@ msgstr "" "%s\n" "\n" -#: help.c:561 +#: help.c:577 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3312,24 +3571,32 @@ msgstr "ID" #: large_obj.c:308 msgid "Large objects" -msgstr "Large objects" +msgstr "대형 ê°ì²´ë“¤" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped\n" +msgstr "\\if: escaped\n" -#: mainloop.c:168 +#: mainloop.c:183 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "마치려면 \"\\q\"를 입력하세요: %s\n" -#: mainloop.c:190 +#: mainloop.c:205 msgid "" "The input is a PostgreSQL custom-format dump.\n" "Use the pg_restore command-line client to restore this dump to a database.\n" msgstr "" +"ì´ ìž…ë ¥ì€ PostgreSQL 사용ìžì–‘ì‹ ë¤í”„ 내용입니다.\n" +"ì´ ë¤í”„ ë‚´ìš©ì„ ë°ì´í„°ë² ì´ìŠ¤ì— ë°˜ì˜í•˜ë ¤ë©´,\n" +"pg_restore 명령행 í´ë¼ì´ì–¸íŠ¸ë¥¼ 사용하세요.\n" -#: mainloop.c:210 +#: mainloop.c:225 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "PostgreSQLì— ëŒ€í•œ 명령행 ì¸í„°íŽ˜ì´ìŠ¤ì¸ psqlì„ ì‚¬ìš©í•˜ê³  있습니다." -#: mainloop.c:211 +#: mainloop.c:226 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3344,2053 +3611,2189 @@ msgstr "" " \\g ë˜ëŠ” 명령 ëì— ì„¸ë¯¸ì½œë¡ (;) 쿼리 실행\n" " \\q 종료\n" -#: psqlscan.l:713 +#: mainloop.c:339 mainloop.c:476 #, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" -msgstr "\"%s\" ë³€ìˆ˜ì˜ ìž¬ê·€ì  í™•ìž¥ì„ ê±´ë„ˆë›°ëŠ” 중\n" +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "" +"쿼리 무시ë¨; 현재 \\if 블ë¡ì„ ë내려면 \\endif ë˜ëŠ” Ctrl-C 키를 사용하세요.\n" + +#: mainloop.c:494 +#, c-format +msgid "reached EOF without finding closing \\endif(s)\n" +msgstr "\\endif ì—†ì´ EOF ë„달\n" -#: psqlscanslash.l:584 +#: psqlscanslash.l:615 #, c-format msgid "unterminated quoted string\n" msgstr "ì¸ìš© 부호 ì§ ë§žì§€ 않ìŒ\n" -#: psqlscanslash.l:738 +#: psqlscanslash.l:788 #, c-format msgid "%s: out of memory\n" msgstr "%s: 메모리 부족\n" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:64 sql_help.c:66 -#: sql_help.c:68 sql_help.c:79 sql_help.c:81 sql_help.c:83 sql_help.c:109 -#: sql_help.c:115 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:124 -#: sql_help.c:126 sql_help.c:128 sql_help.c:221 sql_help.c:223 sql_help.c:224 -#: sql_help.c:226 sql_help.c:228 sql_help.c:231 sql_help.c:233 sql_help.c:235 -#: sql_help.c:237 sql_help.c:249 sql_help.c:250 sql_help.c:251 sql_help.c:253 -#: sql_help.c:299 sql_help.c:301 sql_help.c:303 sql_help.c:305 sql_help.c:365 -#: sql_help.c:370 sql_help.c:372 sql_help.c:415 sql_help.c:417 sql_help.c:420 -#: sql_help.c:422 sql_help.c:489 sql_help.c:494 sql_help.c:499 sql_help.c:504 -#: sql_help.c:509 sql_help.c:558 sql_help.c:560 sql_help.c:562 sql_help.c:564 -#: sql_help.c:567 sql_help.c:569 sql_help.c:580 sql_help.c:582 sql_help.c:624 -#: sql_help.c:626 sql_help.c:628 sql_help.c:631 sql_help.c:633 sql_help.c:635 -#: sql_help.c:669 sql_help.c:673 sql_help.c:677 sql_help.c:696 sql_help.c:699 -#: sql_help.c:702 sql_help.c:731 sql_help.c:743 sql_help.c:751 sql_help.c:754 -#: sql_help.c:757 sql_help.c:772 sql_help.c:775 sql_help.c:819 sql_help.c:842 -#: sql_help.c:853 sql_help.c:855 sql_help.c:872 sql_help.c:881 sql_help.c:883 -#: sql_help.c:885 sql_help.c:897 sql_help.c:901 sql_help.c:903 sql_help.c:987 -#: sql_help.c:989 sql_help.c:992 sql_help.c:995 sql_help.c:997 sql_help.c:999 -#: sql_help.c:1060 sql_help.c:1062 sql_help.c:1064 sql_help.c:1067 -#: sql_help.c:1088 sql_help.c:1091 sql_help.c:1094 sql_help.c:1097 -#: sql_help.c:1101 sql_help.c:1103 sql_help.c:1105 sql_help.c:1107 -#: sql_help.c:1121 sql_help.c:1124 sql_help.c:1126 sql_help.c:1128 -#: sql_help.c:1138 sql_help.c:1140 sql_help.c:1150 sql_help.c:1152 -#: sql_help.c:1162 sql_help.c:1165 sql_help.c:1186 sql_help.c:1188 -#: sql_help.c:1190 sql_help.c:1193 sql_help.c:1195 sql_help.c:1197 -#: sql_help.c:1247 sql_help.c:1285 sql_help.c:1288 sql_help.c:1290 -#: sql_help.c:1292 sql_help.c:1294 sql_help.c:1296 sql_help.c:1299 -#: sql_help.c:1339 sql_help.c:1544 sql_help.c:1608 sql_help.c:1627 -#: sql_help.c:1640 sql_help.c:1694 sql_help.c:1698 sql_help.c:1708 -#: sql_help.c:1728 sql_help.c:1753 sql_help.c:1771 sql_help.c:1800 -#: sql_help.c:1875 sql_help.c:1917 sql_help.c:1939 sql_help.c:1959 -#: sql_help.c:1960 sql_help.c:1995 sql_help.c:2015 sql_help.c:2037 -#: sql_help.c:2050 sql_help.c:2081 sql_help.c:2106 sql_help.c:2150 -#: sql_help.c:2336 sql_help.c:2349 sql_help.c:2366 sql_help.c:2382 -#: sql_help.c:2421 sql_help.c:2472 sql_help.c:2476 sql_help.c:2478 -#: sql_help.c:2484 sql_help.c:2502 sql_help.c:2529 sql_help.c:2564 -#: sql_help.c:2576 sql_help.c:2585 sql_help.c:2629 sql_help.c:2643 -#: sql_help.c:2671 sql_help.c:2679 sql_help.c:2687 sql_help.c:2695 -#: sql_help.c:2703 sql_help.c:2711 sql_help.c:2719 sql_help.c:2727 -#: sql_help.c:2736 sql_help.c:2747 sql_help.c:2755 sql_help.c:2763 -#: sql_help.c:2771 sql_help.c:2779 sql_help.c:2789 sql_help.c:2798 -#: sql_help.c:2807 sql_help.c:2815 sql_help.c:2824 sql_help.c:2832 -#: sql_help.c:2841 sql_help.c:2849 sql_help.c:2857 sql_help.c:2865 -#: sql_help.c:2873 sql_help.c:2881 sql_help.c:2889 sql_help.c:2897 -#: sql_help.c:2905 sql_help.c:2922 sql_help.c:2931 sql_help.c:2939 -#: sql_help.c:2956 sql_help.c:2971 sql_help.c:3236 sql_help.c:3287 -#: sql_help.c:3316 sql_help.c:3324 sql_help.c:3743 sql_help.c:3791 -#: sql_help.c:3932 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 +#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 +#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 +#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 +#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 +#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 +#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 +#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 +#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 +#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 +#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 +#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 +#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 +#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:807 +#: sql_help.c:809 sql_help.c:811 sql_help.c:813 sql_help.c:816 sql_help.c:818 +#: sql_help.c:859 sql_help.c:882 sql_help.c:893 sql_help.c:895 sql_help.c:914 +#: sql_help.c:924 sql_help.c:926 sql_help.c:928 sql_help.c:940 sql_help.c:944 +#: sql_help.c:946 sql_help.c:957 sql_help.c:959 sql_help.c:961 sql_help.c:977 +#: sql_help.c:979 sql_help.c:983 sql_help.c:986 sql_help.c:987 sql_help.c:988 +#: sql_help.c:991 sql_help.c:993 sql_help.c:1084 sql_help.c:1086 +#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 +#: sql_help.c:1099 sql_help.c:1102 sql_help.c:1168 sql_help.c:1170 +#: sql_help.c:1172 sql_help.c:1175 sql_help.c:1196 sql_help.c:1199 +#: sql_help.c:1202 sql_help.c:1205 sql_help.c:1209 sql_help.c:1211 +#: sql_help.c:1213 sql_help.c:1215 sql_help.c:1229 sql_help.c:1232 +#: sql_help.c:1234 sql_help.c:1236 sql_help.c:1246 sql_help.c:1248 +#: sql_help.c:1258 sql_help.c:1260 sql_help.c:1270 sql_help.c:1273 +#: sql_help.c:1295 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1306 sql_help.c:1309 sql_help.c:1359 +#: sql_help.c:1401 sql_help.c:1404 sql_help.c:1406 sql_help.c:1408 +#: sql_help.c:1410 sql_help.c:1412 sql_help.c:1415 sql_help.c:1455 +#: sql_help.c:1666 sql_help.c:1730 sql_help.c:1749 sql_help.c:1762 +#: sql_help.c:1818 sql_help.c:1824 sql_help.c:1834 sql_help.c:1854 +#: sql_help.c:1879 sql_help.c:1897 sql_help.c:1926 sql_help.c:2019 +#: sql_help.c:2061 sql_help.c:2083 sql_help.c:2103 sql_help.c:2104 +#: sql_help.c:2139 sql_help.c:2159 sql_help.c:2181 sql_help.c:2195 +#: sql_help.c:2210 sql_help.c:2240 sql_help.c:2265 sql_help.c:2311 +#: sql_help.c:2577 sql_help.c:2590 sql_help.c:2607 sql_help.c:2623 +#: sql_help.c:2663 sql_help.c:2715 sql_help.c:2719 sql_help.c:2721 +#: sql_help.c:2727 sql_help.c:2745 sql_help.c:2772 sql_help.c:2807 +#: sql_help.c:2819 sql_help.c:2828 sql_help.c:2872 sql_help.c:2886 +#: sql_help.c:2914 sql_help.c:2922 sql_help.c:2930 sql_help.c:2938 +#: sql_help.c:2946 sql_help.c:2954 sql_help.c:2962 sql_help.c:2970 +#: sql_help.c:2979 sql_help.c:2990 sql_help.c:2998 sql_help.c:3006 +#: sql_help.c:3014 sql_help.c:3022 sql_help.c:3032 sql_help.c:3041 +#: sql_help.c:3050 sql_help.c:3058 sql_help.c:3067 sql_help.c:3075 +#: sql_help.c:3083 sql_help.c:3092 sql_help.c:3100 sql_help.c:3108 +#: sql_help.c:3116 sql_help.c:3124 sql_help.c:3132 sql_help.c:3140 +#: sql_help.c:3148 sql_help.c:3156 sql_help.c:3164 sql_help.c:3172 +#: sql_help.c:3189 sql_help.c:3198 sql_help.c:3206 sql_help.c:3223 +#: sql_help.c:3238 sql_help.c:3506 sql_help.c:3557 sql_help.c:3586 +#: sql_help.c:3594 sql_help.c:4017 sql_help.c:4065 sql_help.c:4206 msgid "name" msgstr "ì´ë¦„" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:309 sql_help.c:1405 -#: sql_help.c:2644 sql_help.c:3539 +#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1524 +#: sql_help.c:2887 sql_help.c:3811 msgid "aggregate_signature" msgstr "집계함수_ì‹ë³„구문" -#: sql_help.c:38 sql_help.c:65 sql_help.c:80 sql_help.c:116 sql_help.c:236 -#: sql_help.c:254 sql_help.c:373 sql_help.c:421 sql_help.c:498 sql_help.c:544 -#: sql_help.c:559 sql_help.c:581 sql_help.c:632 sql_help.c:698 sql_help.c:753 -#: sql_help.c:774 sql_help.c:820 sql_help.c:844 sql_help.c:854 sql_help.c:884 -#: sql_help.c:904 sql_help.c:996 sql_help.c:1061 sql_help.c:1104 -#: sql_help.c:1125 sql_help.c:1139 sql_help.c:1151 sql_help.c:1164 -#: sql_help.c:1194 sql_help.c:1248 sql_help.c:1293 +#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 +#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 +#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 +#: sql_help.c:789 sql_help.c:819 sql_help.c:860 sql_help.c:884 sql_help.c:894 +#: sql_help.c:927 sql_help.c:947 sql_help.c:960 sql_help.c:994 sql_help.c:1093 +#: sql_help.c:1169 sql_help.c:1212 sql_help.c:1233 sql_help.c:1247 +#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1303 sql_help.c:1360 +#: sql_help.c:1409 msgid "new_name" msgstr "새ì´ë¦„" -#: sql_help.c:41 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:234 -#: sql_help.c:252 sql_help.c:371 sql_help.c:457 sql_help.c:503 sql_help.c:583 -#: sql_help.c:592 sql_help.c:651 sql_help.c:672 sql_help.c:701 sql_help.c:756 -#: sql_help.c:856 sql_help.c:882 sql_help.c:902 sql_help.c:1045 -#: sql_help.c:1063 sql_help.c:1106 sql_help.c:1127 sql_help.c:1189 -#: sql_help.c:1291 sql_help.c:2322 +#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 +#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 +#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 +#: sql_help.c:817 sql_help.c:896 sql_help.c:925 sql_help.c:945 sql_help.c:958 +#: sql_help.c:992 sql_help.c:1153 sql_help.c:1171 sql_help.c:1214 +#: sql_help.c:1235 sql_help.c:1298 sql_help.c:1407 sql_help.c:2563 msgid "new_owner" msgstr "새사용ìž" -#: sql_help.c:44 sql_help.c:69 sql_help.c:84 sql_help.c:238 sql_help.c:302 -#: sql_help.c:423 sql_help.c:508 sql_help.c:634 sql_help.c:676 sql_help.c:704 -#: sql_help.c:759 sql_help.c:886 sql_help.c:998 sql_help.c:1108 -#: sql_help.c:1129 sql_help.c:1141 sql_help.c:1153 sql_help.c:1196 -#: sql_help.c:1295 +#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 +#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 +#: sql_help.c:774 sql_help.c:929 sql_help.c:962 sql_help.c:1095 +#: sql_help.c:1216 sql_help.c:1237 sql_help.c:1249 sql_help.c:1261 +#: sql_help.c:1305 sql_help.c:1411 msgid "new_schema" msgstr "새스키마" -#: sql_help.c:45 sql_help.c:1458 sql_help.c:2645 sql_help.c:3558 +#: sql_help.c:45 sql_help.c:1580 sql_help.c:2888 sql_help.c:3832 msgid "where aggregate_signature is:" msgstr "집계함수_ì‹ë³„구문 사용법:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:319 sql_help.c:344 -#: sql_help.c:347 sql_help.c:350 sql_help.c:490 sql_help.c:495 sql_help.c:500 -#: sql_help.c:505 sql_help.c:510 sql_help.c:1423 sql_help.c:1459 -#: sql_help.c:1462 sql_help.c:1465 sql_help.c:1609 sql_help.c:1628 -#: sql_help.c:1631 sql_help.c:1876 sql_help.c:2646 sql_help.c:2649 -#: sql_help.c:2652 sql_help.c:2737 sql_help.c:3122 sql_help.c:3454 -#: sql_help.c:3545 sql_help.c:3559 sql_help.c:3562 sql_help.c:3565 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 +#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:1542 sql_help.c:1581 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1731 sql_help.c:1750 +#: sql_help.c:1753 sql_help.c:2020 sql_help.c:2889 sql_help.c:2892 +#: sql_help.c:2895 sql_help.c:2980 sql_help.c:3391 sql_help.c:3724 +#: sql_help.c:3817 sql_help.c:3833 sql_help.c:3836 sql_help.c:3839 msgid "argmode" msgstr "ì¸ìžëª¨ë“œ" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:320 sql_help.c:345 -#: sql_help.c:348 sql_help.c:351 sql_help.c:491 sql_help.c:496 sql_help.c:501 -#: sql_help.c:506 sql_help.c:511 sql_help.c:1424 sql_help.c:1460 -#: sql_help.c:1463 sql_help.c:1466 sql_help.c:1610 sql_help.c:1629 -#: sql_help.c:1632 sql_help.c:1877 sql_help.c:2647 sql_help.c:2650 -#: sql_help.c:2653 sql_help.c:2738 sql_help.c:3546 sql_help.c:3560 -#: sql_help.c:3563 sql_help.c:3566 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 +#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:1543 sql_help.c:1582 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1732 sql_help.c:1751 +#: sql_help.c:1754 sql_help.c:2021 sql_help.c:2890 sql_help.c:2893 +#: sql_help.c:2896 sql_help.c:2981 sql_help.c:3818 sql_help.c:3834 +#: sql_help.c:3837 sql_help.c:3840 msgid "argname" msgstr "ì¸ìžì´ë¦„" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:321 sql_help.c:346 -#: sql_help.c:349 sql_help.c:352 sql_help.c:492 sql_help.c:497 sql_help.c:502 -#: sql_help.c:507 sql_help.c:512 sql_help.c:1425 sql_help.c:1461 -#: sql_help.c:1464 sql_help.c:1467 sql_help.c:1878 sql_help.c:2648 -#: sql_help.c:2651 sql_help.c:2654 sql_help.c:2739 sql_help.c:3547 -#: sql_help.c:3561 sql_help.c:3564 sql_help.c:3567 +#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 +#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 +#: sql_help.c:524 sql_help.c:529 sql_help.c:1544 sql_help.c:1583 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2022 sql_help.c:2891 +#: sql_help.c:2894 sql_help.c:2897 sql_help.c:2982 sql_help.c:3819 +#: sql_help.c:3835 sql_help.c:3838 sql_help.c:3841 msgid "argtype" msgstr "ì¸ìžìžë£Œí˜•" -#: sql_help.c:110 sql_help.c:368 sql_help.c:446 sql_help.c:458 sql_help.c:814 -#: sql_help.c:899 sql_help.c:1122 sql_help.c:1242 sql_help.c:1270 -#: sql_help.c:1515 sql_help.c:1521 sql_help.c:1803 sql_help.c:1835 -#: sql_help.c:1842 sql_help.c:1918 sql_help.c:2082 sql_help.c:2171 -#: sql_help.c:2351 sql_help.c:2530 sql_help.c:2552 sql_help.c:2990 -#: sql_help.c:3156 +#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:854 +#: sql_help.c:942 sql_help.c:1230 sql_help.c:1354 sql_help.c:1386 +#: sql_help.c:1637 sql_help.c:1643 sql_help.c:1929 sql_help.c:1970 +#: sql_help.c:1977 sql_help.c:1986 sql_help.c:2062 sql_help.c:2241 +#: sql_help.c:2333 sql_help.c:2592 sql_help.c:2773 sql_help.c:2795 +#: sql_help.c:3258 sql_help.c:3425 msgid "option" msgstr "옵션" -#: sql_help.c:111 sql_help.c:815 sql_help.c:1243 sql_help.c:1919 -#: sql_help.c:2083 sql_help.c:2531 +#: sql_help.c:114 sql_help.c:855 sql_help.c:1355 sql_help.c:2063 +#: sql_help.c:2242 sql_help.c:2774 msgid "where option can be:" msgstr "옵션 사용법:" -#: sql_help.c:112 sql_help.c:1735 +#: sql_help.c:115 sql_help.c:1861 msgid "allowconn" -msgstr "" +msgstr "ì ‘ì†í—ˆìš©" -#: sql_help.c:113 sql_help.c:816 sql_help.c:1244 sql_help.c:1736 -#: sql_help.c:2084 sql_help.c:2532 +#: sql_help.c:116 sql_help.c:856 sql_help.c:1356 sql_help.c:1862 +#: sql_help.c:2243 sql_help.c:2775 msgid "connlimit" -msgstr "" +msgstr "ì ‘ì†ì œí•œ" -#: sql_help.c:114 sql_help.c:1737 +#: sql_help.c:117 sql_help.c:1863 msgid "istemplate" -msgstr "true|false" +msgstr "템플릿?" -#: sql_help.c:120 sql_help.c:571 sql_help.c:637 sql_help.c:652 sql_help.c:1001 -#: sql_help.c:1038 +#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1098 +#: sql_help.c:1146 msgid "new_tablespace" msgstr "새테ì´ë¸”스페ì´ìФ" -#: sql_help.c:122 sql_help.c:125 sql_help.c:127 sql_help.c:517 sql_help.c:519 -#: sql_help.c:520 sql_help.c:823 sql_help.c:827 sql_help.c:830 sql_help.c:915 -#: sql_help.c:918 sql_help.c:1250 sql_help.c:1253 sql_help.c:1255 -#: sql_help.c:1887 sql_help.c:3341 sql_help.c:3732 +#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 +#: sql_help.c:537 sql_help.c:863 sql_help.c:867 sql_help.c:870 sql_help.c:1005 +#: sql_help.c:1008 sql_help.c:1363 sql_help.c:1367 sql_help.c:1370 +#: sql_help.c:2031 sql_help.c:3611 sql_help.c:4006 msgid "configuration_parameter" msgstr "환경설정_매개변수" -#: sql_help.c:123 sql_help.c:369 sql_help.c:441 sql_help.c:447 sql_help.c:459 -#: sql_help.c:518 sql_help.c:566 sql_help.c:643 sql_help.c:649 sql_help.c:824 -#: sql_help.c:900 sql_help.c:916 sql_help.c:917 sql_help.c:1020 -#: sql_help.c:1040 sql_help.c:1066 sql_help.c:1123 sql_help.c:1251 -#: sql_help.c:1271 sql_help.c:1804 sql_help.c:1836 sql_help.c:1843 -#: sql_help.c:1888 sql_help.c:1889 sql_help.c:1947 sql_help.c:1979 -#: sql_help.c:2172 sql_help.c:2246 sql_help.c:2254 sql_help.c:2286 -#: sql_help.c:2308 sql_help.c:2325 sql_help.c:2352 sql_help.c:2553 -#: sql_help.c:3157 sql_help.c:3733 sql_help.c:3734 +#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 +#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:815 +#: sql_help.c:864 sql_help.c:943 sql_help.c:982 sql_help.c:985 sql_help.c:990 +#: sql_help.c:1006 sql_help.c:1007 sql_help.c:1128 sql_help.c:1148 +#: sql_help.c:1174 sql_help.c:1231 sql_help.c:1364 sql_help.c:1387 +#: sql_help.c:1930 sql_help.c:1971 sql_help.c:1978 sql_help.c:1987 +#: sql_help.c:2032 sql_help.c:2033 sql_help.c:2091 sql_help.c:2123 +#: sql_help.c:2213 sql_help.c:2334 sql_help.c:2364 sql_help.c:2462 +#: sql_help.c:2474 sql_help.c:2487 sql_help.c:2527 sql_help.c:2549 +#: sql_help.c:2566 sql_help.c:2593 sql_help.c:2796 sql_help.c:3426 +#: sql_help.c:4007 sql_help.c:4008 msgid "value" msgstr "ê°’" -#: sql_help.c:185 +#: sql_help.c:198 msgid "target_role" msgstr "대ìƒë¡¤" -#: sql_help.c:186 sql_help.c:1787 sql_help.c:2130 sql_help.c:2135 -#: sql_help.c:3104 sql_help.c:3111 sql_help.c:3125 sql_help.c:3131 -#: sql_help.c:3436 sql_help.c:3443 sql_help.c:3457 sql_help.c:3463 +#: sql_help.c:199 sql_help.c:1913 sql_help.c:2289 sql_help.c:2294 +#: sql_help.c:3373 sql_help.c:3380 sql_help.c:3394 sql_help.c:3400 +#: sql_help.c:3706 sql_help.c:3713 sql_help.c:3727 sql_help.c:3733 msgid "schema_name" msgstr "스키마ì´ë¦„" -#: sql_help.c:187 +#: sql_help.c:200 msgid "abbreviated_grant_or_revoke" -msgstr "" +msgstr "grant_ë˜ëŠ”_revoke_ë‚´ìš©" -#: sql_help.c:188 +#: sql_help.c:201 msgid "where abbreviated_grant_or_revoke is one of:" -msgstr "" - -#: sql_help.c:189 sql_help.c:190 sql_help.c:191 sql_help.c:192 sql_help.c:193 -#: sql_help.c:194 sql_help.c:195 sql_help.c:196 sql_help.c:542 sql_help.c:570 -#: sql_help.c:636 sql_help.c:777 sql_help.c:834 sql_help.c:1000 -#: sql_help.c:1258 sql_help.c:1922 sql_help.c:1923 sql_help.c:1924 -#: sql_help.c:1925 sql_help.c:1926 sql_help.c:2052 sql_help.c:2087 -#: sql_help.c:2088 sql_help.c:2089 sql_help.c:2090 sql_help.c:2091 -#: sql_help.c:2535 sql_help.c:2536 sql_help.c:2537 sql_help.c:2538 -#: sql_help.c:2539 sql_help.c:3138 sql_help.c:3139 sql_help.c:3140 -#: sql_help.c:3437 sql_help.c:3441 sql_help.c:3444 sql_help.c:3446 -#: sql_help.c:3448 sql_help.c:3450 sql_help.c:3452 sql_help.c:3458 -#: sql_help.c:3460 sql_help.c:3462 sql_help.c:3464 sql_help.c:3466 -#: sql_help.c:3468 sql_help.c:3469 sql_help.c:3470 sql_help.c:3753 +msgstr "grant_ë˜ëŠ”_revoke_ë‚´ìš©ì— ì‚¬ìš©ë˜ëŠ” 구문:" + +#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 +#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 +#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:874 +#: sql_help.c:1097 sql_help.c:1374 sql_help.c:2066 sql_help.c:2067 +#: sql_help.c:2068 sql_help.c:2069 sql_help.c:2070 sql_help.c:2197 +#: sql_help.c:2246 sql_help.c:2247 sql_help.c:2248 sql_help.c:2249 +#: sql_help.c:2250 sql_help.c:2778 sql_help.c:2779 sql_help.c:2780 +#: sql_help.c:2781 sql_help.c:2782 sql_help.c:3407 sql_help.c:3408 +#: sql_help.c:3409 sql_help.c:3707 sql_help.c:3711 sql_help.c:3714 +#: sql_help.c:3716 sql_help.c:3718 sql_help.c:3720 sql_help.c:3722 +#: sql_help.c:3728 sql_help.c:3730 sql_help.c:3732 sql_help.c:3734 +#: sql_help.c:3736 sql_help.c:3738 sql_help.c:3739 sql_help.c:3740 +#: sql_help.c:4027 msgid "role_name" msgstr "롤ì´ë¦„" -#: sql_help.c:222 sql_help.c:434 sql_help.c:1011 sql_help.c:1013 -#: sql_help.c:1287 sql_help.c:1756 sql_help.c:1760 sql_help.c:1846 -#: sql_help.c:1850 sql_help.c:1943 sql_help.c:2258 sql_help.c:2268 -#: sql_help.c:2290 sql_help.c:3187 sql_help.c:3202 sql_help.c:3204 -#: sql_help.c:3618 sql_help.c:3619 sql_help.c:3628 sql_help.c:3669 -#: sql_help.c:3670 sql_help.c:3671 sql_help.c:3672 sql_help.c:3673 -#: sql_help.c:3674 sql_help.c:3707 sql_help.c:3708 sql_help.c:3713 -#: sql_help.c:3718 sql_help.c:3857 sql_help.c:3858 sql_help.c:3867 -#: sql_help.c:3908 sql_help.c:3909 sql_help.c:3910 sql_help.c:3911 -#: sql_help.c:3912 sql_help.c:3913 sql_help.c:3960 sql_help.c:3962 -#: sql_help.c:3995 sql_help.c:4051 sql_help.c:4052 sql_help.c:4061 -#: sql_help.c:4102 sql_help.c:4103 sql_help.c:4104 sql_help.c:4105 -#: sql_help.c:4106 sql_help.c:4107 +#: sql_help.c:237 sql_help.c:451 sql_help.c:1113 sql_help.c:1115 +#: sql_help.c:1403 sql_help.c:1882 sql_help.c:1886 sql_help.c:1990 +#: sql_help.c:1994 sql_help.c:2087 sql_help.c:2458 sql_help.c:2470 +#: sql_help.c:2483 sql_help.c:2491 sql_help.c:2502 sql_help.c:2531 +#: sql_help.c:3457 sql_help.c:3472 sql_help.c:3474 sql_help.c:3892 +#: sql_help.c:3893 sql_help.c:3902 sql_help.c:3943 sql_help.c:3944 +#: sql_help.c:3945 sql_help.c:3946 sql_help.c:3947 sql_help.c:3948 +#: sql_help.c:3981 sql_help.c:3982 sql_help.c:3987 sql_help.c:3992 +#: sql_help.c:4131 sql_help.c:4132 sql_help.c:4141 sql_help.c:4182 +#: sql_help.c:4183 sql_help.c:4184 sql_help.c:4185 sql_help.c:4186 +#: sql_help.c:4187 sql_help.c:4234 sql_help.c:4236 sql_help.c:4269 +#: sql_help.c:4325 sql_help.c:4326 sql_help.c:4335 sql_help.c:4376 +#: sql_help.c:4377 sql_help.c:4378 sql_help.c:4379 sql_help.c:4380 +#: sql_help.c:4381 msgid "expression" msgstr "표현ì‹" -#: sql_help.c:225 +#: sql_help.c:240 msgid "domain_constraint" msgstr "ë„ë©”ì¸_제약조건" -#: sql_help.c:227 sql_help.c:229 sql_help.c:232 sql_help.c:449 sql_help.c:450 -#: sql_help.c:993 sql_help.c:1026 sql_help.c:1027 sql_help.c:1028 -#: sql_help.c:1048 sql_help.c:1411 sql_help.c:1413 sql_help.c:1759 -#: sql_help.c:1845 sql_help.c:1849 sql_help.c:2257 sql_help.c:2267 -#: sql_help.c:3199 +#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 +#: sql_help.c:1090 sql_help.c:1134 sql_help.c:1135 sql_help.c:1136 +#: sql_help.c:1156 sql_help.c:1530 sql_help.c:1532 sql_help.c:1885 +#: sql_help.c:1989 sql_help.c:1993 sql_help.c:2490 sql_help.c:2501 +#: sql_help.c:3469 msgid "constraint_name" msgstr "제약조건_ì´ë¦„" -#: sql_help.c:230 sql_help.c:994 +#: sql_help.c:245 sql_help.c:1091 msgid "new_constraint_name" msgstr "새제약조건_ì´ë¦„" -#: sql_help.c:300 sql_help.c:898 +#: sql_help.c:316 sql_help.c:941 msgid "new_version" msgstr "새버전" -#: sql_help.c:304 sql_help.c:306 +#: sql_help.c:320 sql_help.c:322 msgid "member_object" -msgstr "" +msgstr "맴버_ê°ì²´" -#: sql_help.c:307 +#: sql_help.c:323 msgid "where member_object is:" -msgstr "" +msgstr "맴버_ê°ì²´ 사용법:" + +#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 +#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 +#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 +#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 +#: sql_help.c:359 sql_help.c:1522 sql_help.c:1527 sql_help.c:1534 +#: sql_help.c:1535 sql_help.c:1536 sql_help.c:1537 sql_help.c:1538 +#: sql_help.c:1539 sql_help.c:1540 sql_help.c:1545 sql_help.c:1547 +#: sql_help.c:1551 sql_help.c:1553 sql_help.c:1557 sql_help.c:1558 +#: sql_help.c:1559 sql_help.c:1562 sql_help.c:1563 sql_help.c:1564 +#: sql_help.c:1565 sql_help.c:1566 sql_help.c:1567 sql_help.c:1568 +#: sql_help.c:1569 sql_help.c:1570 sql_help.c:1571 sql_help.c:1572 +#: sql_help.c:1577 sql_help.c:1578 sql_help.c:3807 sql_help.c:3812 +#: sql_help.c:3813 sql_help.c:3814 sql_help.c:3815 sql_help.c:3821 +#: sql_help.c:3822 sql_help.c:3823 sql_help.c:3824 sql_help.c:3825 +#: sql_help.c:3826 sql_help.c:3827 sql_help.c:3828 sql_help.c:3829 +#: sql_help.c:3830 +msgid "object_name" +msgstr "ê°ì²´ì´ë¦„" -#: sql_help.c:308 sql_help.c:1404 sql_help.c:3538 +#: sql_help.c:325 sql_help.c:1523 sql_help.c:3810 msgid "aggregate_name" msgstr "집계함수ì´ë¦„" -#: sql_help.c:310 sql_help.c:1406 sql_help.c:1674 sql_help.c:1678 -#: sql_help.c:1680 sql_help.c:2662 +#: sql_help.c:327 sql_help.c:1525 sql_help.c:1796 sql_help.c:1800 +#: sql_help.c:1802 sql_help.c:2905 msgid "source_type" msgstr "기존ìžë£Œí˜•" -#: sql_help.c:311 sql_help.c:1407 sql_help.c:1675 sql_help.c:1679 -#: sql_help.c:1681 sql_help.c:2663 +#: sql_help.c:328 sql_help.c:1526 sql_help.c:1797 sql_help.c:1801 +#: sql_help.c:1803 sql_help.c:2906 msgid "target_type" msgstr "대ìƒìžë£Œí˜•" -#: sql_help.c:312 sql_help.c:313 sql_help.c:314 sql_help.c:315 sql_help.c:316 -#: sql_help.c:317 sql_help.c:322 sql_help.c:326 sql_help.c:328 sql_help.c:330 -#: sql_help.c:331 sql_help.c:332 sql_help.c:333 sql_help.c:334 sql_help.c:335 -#: sql_help.c:336 sql_help.c:337 sql_help.c:338 sql_help.c:341 sql_help.c:342 -#: sql_help.c:1403 sql_help.c:1408 sql_help.c:1415 sql_help.c:1416 -#: sql_help.c:1417 sql_help.c:1418 sql_help.c:1419 sql_help.c:1420 -#: sql_help.c:1421 sql_help.c:1426 sql_help.c:1428 sql_help.c:1432 -#: sql_help.c:1434 sql_help.c:1438 sql_help.c:1439 sql_help.c:1442 -#: sql_help.c:1443 sql_help.c:1444 sql_help.c:1445 sql_help.c:1446 -#: sql_help.c:1447 sql_help.c:1448 sql_help.c:1449 sql_help.c:1450 -#: sql_help.c:1455 sql_help.c:1456 sql_help.c:3535 sql_help.c:3540 -#: sql_help.c:3541 sql_help.c:3542 sql_help.c:3543 sql_help.c:3549 -#: sql_help.c:3550 sql_help.c:3551 sql_help.c:3552 sql_help.c:3553 -#: sql_help.c:3554 sql_help.c:3555 sql_help.c:3556 -msgid "object_name" -msgstr "ê°ì²´ì´ë¦„" - -#: sql_help.c:318 sql_help.c:741 sql_help.c:1422 sql_help.c:1676 -#: sql_help.c:1711 sql_help.c:1774 sql_help.c:1996 sql_help.c:2027 -#: sql_help.c:2426 sql_help.c:3121 sql_help.c:3453 sql_help.c:3544 -#: sql_help.c:3647 sql_help.c:3651 sql_help.c:3655 sql_help.c:3658 -#: sql_help.c:3886 sql_help.c:3890 sql_help.c:3894 sql_help.c:3897 -#: sql_help.c:4080 sql_help.c:4084 sql_help.c:4088 sql_help.c:4091 +#: sql_help.c:335 sql_help.c:756 sql_help.c:1541 sql_help.c:1798 +#: sql_help.c:1837 sql_help.c:1900 sql_help.c:2140 sql_help.c:2171 +#: sql_help.c:2669 sql_help.c:3390 sql_help.c:3723 sql_help.c:3816 +#: sql_help.c:3921 sql_help.c:3925 sql_help.c:3929 sql_help.c:3932 +#: sql_help.c:4160 sql_help.c:4164 sql_help.c:4168 sql_help.c:4171 +#: sql_help.c:4354 sql_help.c:4358 sql_help.c:4362 sql_help.c:4365 msgid "function_name" msgstr "함수ì´ë¦„" -#: sql_help.c:323 sql_help.c:734 sql_help.c:1429 sql_help.c:2020 +#: sql_help.c:340 sql_help.c:749 sql_help.c:1548 sql_help.c:2164 msgid "operator_name" msgstr "ì—°ì‚°ìžì´ë¦„" -#: sql_help.c:324 sql_help.c:670 sql_help.c:674 sql_help.c:678 sql_help.c:1430 -#: sql_help.c:1997 sql_help.c:2780 +#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1549 +#: sql_help.c:2141 sql_help.c:3023 msgid "left_type" msgstr "왼쪽ì¸ìž_ìžë£Œí˜•" -#: sql_help.c:325 sql_help.c:671 sql_help.c:675 sql_help.c:679 sql_help.c:1431 -#: sql_help.c:1998 sql_help.c:2781 +#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1550 +#: sql_help.c:2142 sql_help.c:3024 msgid "right_type" msgstr "오른쪽ì¸ìž_ìžë£Œí˜•" -#: sql_help.c:327 sql_help.c:329 sql_help.c:697 sql_help.c:700 sql_help.c:703 -#: sql_help.c:732 sql_help.c:744 sql_help.c:752 sql_help.c:755 sql_help.c:758 -#: sql_help.c:1433 sql_help.c:1435 sql_help.c:2017 sql_help.c:2038 -#: sql_help.c:2273 sql_help.c:2790 sql_help.c:2799 +#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 +#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 +#: sql_help.c:1552 sql_help.c:1554 sql_help.c:2161 sql_help.c:2182 +#: sql_help.c:2507 sql_help.c:3033 sql_help.c:3042 msgid "index_method" msgstr "색ì¸ë°©ë²•" -#: sql_help.c:339 sql_help.c:1044 sql_help.c:1451 sql_help.c:1884 -#: sql_help.c:2249 sql_help.c:2395 sql_help.c:2913 sql_help.c:3135 -#: sql_help.c:3467 +#: sql_help.c:356 sql_help.c:1152 sql_help.c:1573 sql_help.c:2028 +#: sql_help.c:2465 sql_help.c:2636 sql_help.c:3180 sql_help.c:3404 +#: sql_help.c:3737 msgid "type_name" msgstr "ìžë£Œí˜•ì´ë¦„" -#: sql_help.c:340 sql_help.c:1452 sql_help.c:1883 sql_help.c:2396 -#: sql_help.c:2620 sql_help.c:2914 sql_help.c:3127 sql_help.c:3459 +#: sql_help.c:357 sql_help.c:1574 sql_help.c:2027 sql_help.c:2637 +#: sql_help.c:2863 sql_help.c:3181 sql_help.c:3396 sql_help.c:3729 msgid "lang_name" -msgstr "" +msgstr "언어_ì´ë¦„" -#: sql_help.c:343 +#: sql_help.c:360 msgid "and aggregate_signature is:" -msgstr "" +msgstr "집계함수_ì‹ë³„구문 사용법:" -#: sql_help.c:366 sql_help.c:1546 sql_help.c:1801 +#: sql_help.c:383 sql_help.c:1668 sql_help.c:1927 msgid "handler_function" msgstr "핸들러_함수" -#: sql_help.c:367 sql_help.c:1802 +#: sql_help.c:384 sql_help.c:1928 msgid "validator_function" msgstr "유효성검사_함수" -#: sql_help.c:416 sql_help.c:493 sql_help.c:625 sql_help.c:988 sql_help.c:1187 -#: sql_help.c:2264 sql_help.c:2265 sql_help.c:2281 sql_help.c:2282 +#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1085 +#: sql_help.c:1296 sql_help.c:2498 sql_help.c:2499 sql_help.c:2515 +#: sql_help.c:2516 msgid "action" msgstr "ë™ìž‘" -#: sql_help.c:418 sql_help.c:425 sql_help.c:429 sql_help.c:430 sql_help.c:433 -#: sql_help.c:435 sql_help.c:436 sql_help.c:437 sql_help.c:439 sql_help.c:442 -#: sql_help.c:444 sql_help.c:445 sql_help.c:629 sql_help.c:639 sql_help.c:641 -#: sql_help.c:644 sql_help.c:646 sql_help.c:880 sql_help.c:990 sql_help.c:1003 -#: sql_help.c:1007 sql_help.c:1008 sql_help.c:1012 sql_help.c:1014 -#: sql_help.c:1015 sql_help.c:1016 sql_help.c:1018 sql_help.c:1021 -#: sql_help.c:1023 sql_help.c:1286 sql_help.c:1289 sql_help.c:1309 -#: sql_help.c:1410 sql_help.c:1512 sql_help.c:1517 sql_help.c:1531 -#: sql_help.c:1532 sql_help.c:1533 sql_help.c:1833 sql_help.c:1881 -#: sql_help.c:1942 sql_help.c:1977 sql_help.c:2157 sql_help.c:2237 -#: sql_help.c:2250 sql_help.c:2269 sql_help.c:2271 sql_help.c:2278 -#: sql_help.c:2289 sql_help.c:2306 sql_help.c:2429 sql_help.c:2565 -#: sql_help.c:3106 sql_help.c:3107 sql_help.c:3186 sql_help.c:3201 -#: sql_help.c:3203 sql_help.c:3205 sql_help.c:3438 sql_help.c:3439 -#: sql_help.c:3537 sql_help.c:3678 sql_help.c:3917 sql_help.c:3959 -#: sql_help.c:3961 sql_help.c:3963 sql_help.c:3980 sql_help.c:3983 -#: sql_help.c:4111 +#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 +#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 +#: sql_help.c:660 sql_help.c:662 sql_help.c:923 sql_help.c:1087 +#: sql_help.c:1105 sql_help.c:1109 sql_help.c:1110 sql_help.c:1114 +#: sql_help.c:1116 sql_help.c:1117 sql_help.c:1118 sql_help.c:1120 +#: sql_help.c:1123 sql_help.c:1124 sql_help.c:1126 sql_help.c:1129 +#: sql_help.c:1131 sql_help.c:1402 sql_help.c:1405 sql_help.c:1425 +#: sql_help.c:1529 sql_help.c:1634 sql_help.c:1639 sql_help.c:1653 +#: sql_help.c:1654 sql_help.c:1655 sql_help.c:1968 sql_help.c:1981 +#: sql_help.c:2025 sql_help.c:2086 sql_help.c:2121 sql_help.c:2319 +#: sql_help.c:2347 sql_help.c:2348 sql_help.c:2449 sql_help.c:2457 +#: sql_help.c:2466 sql_help.c:2469 sql_help.c:2478 sql_help.c:2482 +#: sql_help.c:2503 sql_help.c:2505 sql_help.c:2512 sql_help.c:2530 +#: sql_help.c:2547 sql_help.c:2672 sql_help.c:2808 sql_help.c:3375 +#: sql_help.c:3376 sql_help.c:3456 sql_help.c:3471 sql_help.c:3473 +#: sql_help.c:3475 sql_help.c:3708 sql_help.c:3709 sql_help.c:3809 +#: sql_help.c:3952 sql_help.c:4191 sql_help.c:4233 sql_help.c:4235 +#: sql_help.c:4237 sql_help.c:4254 sql_help.c:4257 sql_help.c:4385 msgid "column_name" msgstr "칼럼ì´ë¦„" -#: sql_help.c:419 sql_help.c:630 sql_help.c:991 +#: sql_help.c:436 sql_help.c:646 sql_help.c:1088 msgid "new_column_name" msgstr "새칼럼ì´ë¦„" -#: sql_help.c:424 sql_help.c:514 sql_help.c:638 sql_help.c:1002 -#: sql_help.c:1200 +#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1104 +#: sql_help.c:1312 msgid "where action is one of:" msgstr "ë™ìž‘ 사용법:" -#: sql_help.c:426 sql_help.c:431 sql_help.c:1004 sql_help.c:1009 -#: sql_help.c:1202 sql_help.c:1206 sql_help.c:1754 sql_help.c:1834 -#: sql_help.c:2016 sql_help.c:2238 sql_help.c:2474 sql_help.c:3288 +#: sql_help.c:443 sql_help.c:448 sql_help.c:915 sql_help.c:1106 +#: sql_help.c:1111 sql_help.c:1314 sql_help.c:1318 sql_help.c:1880 +#: sql_help.c:1969 sql_help.c:2160 sql_help.c:2312 sql_help.c:2450 +#: sql_help.c:2717 sql_help.c:3558 msgid "data_type" msgstr "ìžë£Œí˜•" -#: sql_help.c:427 sql_help.c:432 sql_help.c:1005 sql_help.c:1010 -#: sql_help.c:1203 sql_help.c:1207 sql_help.c:1755 sql_help.c:1837 -#: sql_help.c:1944 sql_help.c:2239 sql_help.c:2475 sql_help.c:2481 -#: sql_help.c:3196 +#: sql_help.c:444 sql_help.c:449 sql_help.c:1107 sql_help.c:1112 +#: sql_help.c:1315 sql_help.c:1319 sql_help.c:1881 sql_help.c:1972 +#: sql_help.c:2088 sql_help.c:2451 sql_help.c:2459 sql_help.c:2471 +#: sql_help.c:2484 sql_help.c:2718 sql_help.c:2724 sql_help.c:3466 msgid "collation" msgstr "collation" -#: sql_help.c:428 sql_help.c:1006 sql_help.c:1838 sql_help.c:2240 -#: sql_help.c:2251 +#: sql_help.c:445 sql_help.c:1108 sql_help.c:1973 sql_help.c:1982 +#: sql_help.c:2452 sql_help.c:2467 sql_help.c:2479 msgid "column_constraint" msgstr "칼럼_제약조건" -#: sql_help.c:438 sql_help.c:640 sql_help.c:1017 +#: sql_help.c:455 sql_help.c:656 sql_help.c:1125 msgid "integer" msgstr "정수" -#: sql_help.c:440 sql_help.c:443 sql_help.c:642 sql_help.c:645 sql_help.c:1019 -#: sql_help.c:1022 +#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1127 +#: sql_help.c:1130 msgid "attribute_option" msgstr "ì†ì„±_옵션" -#: sql_help.c:448 sql_help.c:1024 sql_help.c:1839 sql_help.c:2241 -#: sql_help.c:2252 +#: sql_help.c:465 sql_help.c:1132 sql_help.c:1974 sql_help.c:1983 +#: sql_help.c:2453 sql_help.c:2468 sql_help.c:2480 msgid "table_constraint" msgstr "í…Œì´ë¸”_제약조건" -#: sql_help.c:451 sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:1029 -#: sql_help.c:1030 sql_help.c:1031 sql_help.c:1032 sql_help.c:1453 +#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1139 sql_help.c:1140 sql_help.c:1575 msgid "trigger_name" msgstr "트리거ì´ë¦„" -#: sql_help.c:455 sql_help.c:456 sql_help.c:1042 sql_help.c:1043 -#: sql_help.c:1840 sql_help.c:2244 +#: sql_help.c:472 sql_help.c:473 sql_help.c:1150 sql_help.c:1151 +#: sql_help.c:1975 sql_help.c:1980 sql_help.c:2456 sql_help.c:2477 msgid "parent_table" msgstr "ìƒìœ„_í…Œì´ë¸”" -#: sql_help.c:513 sql_help.c:563 sql_help.c:627 sql_help.c:1167 -#: sql_help.c:1786 +#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1275 +#: sql_help.c:1912 msgid "extension_name" msgstr "확장모듈ì´ë¦„" -#: sql_help.c:515 sql_help.c:1885 +#: sql_help.c:532 sql_help.c:2029 msgid "execution_cost" msgstr "실행비용" -#: sql_help.c:516 sql_help.c:1886 +#: sql_help.c:533 sql_help.c:2030 msgid "result_rows" -msgstr "" - -#: sql_help.c:537 sql_help.c:539 sql_help.c:813 sql_help.c:821 sql_help.c:825 -#: sql_help.c:828 sql_help.c:831 sql_help.c:1241 sql_help.c:1249 -#: sql_help.c:1252 sql_help.c:1254 sql_help.c:1256 sql_help.c:2131 -#: sql_help.c:2133 sql_help.c:2136 sql_help.c:2137 sql_help.c:3105 -#: sql_help.c:3109 sql_help.c:3112 sql_help.c:3114 sql_help.c:3116 -#: sql_help.c:3118 sql_help.c:3120 sql_help.c:3126 sql_help.c:3128 -#: sql_help.c:3130 sql_help.c:3132 sql_help.c:3134 sql_help.c:3136 +msgstr "반환ìžë£Œìˆ˜" + +#: sql_help.c:554 sql_help.c:556 sql_help.c:853 sql_help.c:861 sql_help.c:865 +#: sql_help.c:868 sql_help.c:871 sql_help.c:1353 sql_help.c:1361 +#: sql_help.c:1365 sql_help.c:1368 sql_help.c:1371 sql_help.c:2290 +#: sql_help.c:2292 sql_help.c:2295 sql_help.c:2296 sql_help.c:3374 +#: sql_help.c:3378 sql_help.c:3381 sql_help.c:3383 sql_help.c:3385 +#: sql_help.c:3387 sql_help.c:3389 sql_help.c:3395 sql_help.c:3397 +#: sql_help.c:3399 sql_help.c:3401 sql_help.c:3403 sql_help.c:3405 msgid "role_specification" msgstr "롤_명세" -#: sql_help.c:538 sql_help.c:540 sql_help.c:1268 sql_help.c:1729 -#: sql_help.c:2139 sql_help.c:2550 sql_help.c:2947 sql_help.c:3763 +#: sql_help.c:555 sql_help.c:557 sql_help.c:1384 sql_help.c:1855 +#: sql_help.c:2298 sql_help.c:2793 sql_help.c:3214 sql_help.c:4037 msgid "user_name" msgstr "사용ìžì´ë¦„" -#: sql_help.c:541 sql_help.c:833 sql_help.c:1257 sql_help.c:2138 -#: sql_help.c:3137 +#: sql_help.c:558 sql_help.c:873 sql_help.c:1373 sql_help.c:2297 +#: sql_help.c:3406 msgid "where role_specification can be:" msgstr "롤_명세 사용법:" -#: sql_help.c:543 +#: sql_help.c:560 msgid "group_name" msgstr "그룹ì´ë¦„" -#: sql_help.c:561 sql_help.c:1734 sql_help.c:1948 sql_help.c:1980 -#: sql_help.c:2247 sql_help.c:2255 sql_help.c:2287 sql_help.c:2309 -#: sql_help.c:2321 sql_help.c:3133 sql_help.c:3465 +#: sql_help.c:578 sql_help.c:1860 sql_help.c:2092 sql_help.c:2124 +#: sql_help.c:2463 sql_help.c:2475 sql_help.c:2488 sql_help.c:2528 +#: sql_help.c:2550 sql_help.c:2562 sql_help.c:3402 sql_help.c:3735 msgid "tablespace_name" msgstr "í…Œì´ë¸”스페ì´ìФì´ë¦„" -#: sql_help.c:565 sql_help.c:568 sql_help.c:648 sql_help.c:650 sql_help.c:1039 -#: sql_help.c:1041 sql_help.c:1946 sql_help.c:1978 sql_help.c:2245 -#: sql_help.c:2253 sql_help.c:2285 sql_help.c:2307 +#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1147 +#: sql_help.c:1149 sql_help.c:2090 sql_help.c:2122 sql_help.c:2461 +#: sql_help.c:2473 sql_help.c:2486 sql_help.c:2526 sql_help.c:2548 msgid "storage_parameter" -msgstr "" +msgstr "스토리지_매개변수" -#: sql_help.c:591 sql_help.c:1427 sql_help.c:3548 +#: sql_help.c:608 sql_help.c:1546 sql_help.c:3820 msgid "large_object_oid" msgstr "대형_ê°ì²´_oid" -#: sql_help.c:647 sql_help.c:1037 sql_help.c:1046 sql_help.c:1049 -#: sql_help.c:1349 +#: sql_help.c:663 sql_help.c:1145 sql_help.c:1154 sql_help.c:1157 +#: sql_help.c:1465 msgid "index_name" msgstr "ì¸ë±ìФì´ë¦„" -#: sql_help.c:680 sql_help.c:2001 +#: sql_help.c:695 sql_help.c:2145 msgid "res_proc" msgstr "" -#: sql_help.c:681 sql_help.c:2002 +#: sql_help.c:696 sql_help.c:2146 msgid "join_proc" msgstr "" -#: sql_help.c:733 sql_help.c:745 sql_help.c:2019 +#: sql_help.c:748 sql_help.c:760 sql_help.c:2163 msgid "strategy_number" -msgstr "" +msgstr "ì „ëžµ_번호" -#: sql_help.c:735 sql_help.c:736 sql_help.c:739 sql_help.c:740 sql_help.c:746 -#: sql_help.c:747 sql_help.c:749 sql_help.c:750 sql_help.c:2021 -#: sql_help.c:2022 sql_help.c:2025 sql_help.c:2026 +#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 +#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2165 +#: sql_help.c:2166 sql_help.c:2169 sql_help.c:2170 msgid "op_type" msgstr "ì—°ì‚°ìžìžë£Œí˜•" -#: sql_help.c:737 sql_help.c:2023 +#: sql_help.c:752 sql_help.c:2167 msgid "sort_family_name" msgstr "" -#: sql_help.c:738 sql_help.c:748 sql_help.c:2024 +#: sql_help.c:753 sql_help.c:763 sql_help.c:2168 msgid "support_number" msgstr "" -#: sql_help.c:742 sql_help.c:1677 sql_help.c:2028 sql_help.c:2398 -#: sql_help.c:2400 +#: sql_help.c:757 sql_help.c:1799 sql_help.c:2172 sql_help.c:2639 +#: sql_help.c:2641 msgid "argument_type" msgstr "ì¸ìžìžë£Œí˜•" -#: sql_help.c:773 sql_help.c:776 sql_help.c:843 sql_help.c:879 sql_help.c:1163 -#: sql_help.c:1166 sql_help.c:1308 sql_help.c:1348 sql_help.c:1412 -#: sql_help.c:1437 sql_help.c:1441 sql_help.c:1454 sql_help.c:1511 -#: sql_help.c:1516 sql_help.c:1832 sql_help.c:1940 sql_help.c:1976 -#: sql_help.c:2051 sql_help.c:2108 sql_help.c:2156 sql_help.c:2236 -#: sql_help.c:2248 sql_help.c:2305 sql_help.c:2423 sql_help.c:2599 -#: sql_help.c:2816 sql_help.c:2833 sql_help.c:2923 sql_help.c:3103 -#: sql_help.c:3108 sql_help.c:3153 sql_help.c:3184 sql_help.c:3435 -#: sql_help.c:3440 sql_help.c:3536 sql_help.c:3633 sql_help.c:3635 -#: sql_help.c:3684 sql_help.c:3723 sql_help.c:3872 sql_help.c:3874 -#: sql_help.c:3923 sql_help.c:3957 sql_help.c:3979 sql_help.c:3981 -#: sql_help.c:3982 sql_help.c:4066 sql_help.c:4068 sql_help.c:4117 +#: sql_help.c:788 sql_help.c:791 sql_help.c:808 sql_help.c:810 sql_help.c:812 +#: sql_help.c:883 sql_help.c:922 sql_help.c:1271 sql_help.c:1274 +#: sql_help.c:1424 sql_help.c:1464 sql_help.c:1531 sql_help.c:1556 +#: sql_help.c:1561 sql_help.c:1576 sql_help.c:1633 sql_help.c:1638 +#: sql_help.c:1967 sql_help.c:1979 sql_help.c:2084 sql_help.c:2120 +#: sql_help.c:2196 sql_help.c:2211 sql_help.c:2267 sql_help.c:2318 +#: sql_help.c:2349 sql_help.c:2448 sql_help.c:2464 sql_help.c:2476 +#: sql_help.c:2546 sql_help.c:2665 sql_help.c:2842 sql_help.c:3059 +#: sql_help.c:3084 sql_help.c:3190 sql_help.c:3372 sql_help.c:3377 +#: sql_help.c:3422 sql_help.c:3454 sql_help.c:3705 sql_help.c:3710 +#: sql_help.c:3808 sql_help.c:3907 sql_help.c:3909 sql_help.c:3958 +#: sql_help.c:3997 sql_help.c:4146 sql_help.c:4148 sql_help.c:4197 +#: sql_help.c:4231 sql_help.c:4253 sql_help.c:4255 sql_help.c:4256 +#: sql_help.c:4340 sql_help.c:4342 sql_help.c:4391 msgid "table_name" msgstr "í…Œì´ë¸”ì´ë¦„" -#: sql_help.c:778 sql_help.c:2053 +#: sql_help.c:793 sql_help.c:2198 msgid "using_expression" msgstr "" -#: sql_help.c:779 sql_help.c:2054 +#: sql_help.c:794 sql_help.c:2199 msgid "check_expression" -msgstr "" +msgstr "ì²´í¬_표현ì‹" + +#: sql_help.c:814 sql_help.c:2212 +msgid "publication_parameter" +msgstr "발행_매개변수" -#: sql_help.c:817 sql_help.c:1245 sql_help.c:1920 sql_help.c:2085 -#: sql_help.c:2533 +#: sql_help.c:857 sql_help.c:1357 sql_help.c:2064 sql_help.c:2244 +#: sql_help.c:2776 msgid "password" msgstr "암호" -#: sql_help.c:818 sql_help.c:1246 sql_help.c:1921 sql_help.c:2086 -#: sql_help.c:2534 +#: sql_help.c:858 sql_help.c:1358 sql_help.c:2065 sql_help.c:2245 +#: sql_help.c:2777 msgid "timestamp" msgstr "" -#: sql_help.c:822 sql_help.c:826 sql_help.c:829 sql_help.c:832 sql_help.c:3113 -#: sql_help.c:3445 +#: sql_help.c:862 sql_help.c:866 sql_help.c:869 sql_help.c:872 sql_help.c:1362 +#: sql_help.c:1366 sql_help.c:1369 sql_help.c:1372 sql_help.c:3382 +#: sql_help.c:3715 msgid "database_name" msgstr "ë°ì´í„°ë² ì´ìФì´ë¦„" -#: sql_help.c:873 sql_help.c:2151 +#: sql_help.c:916 sql_help.c:2313 msgid "increment" msgstr "" -#: sql_help.c:874 sql_help.c:2152 +#: sql_help.c:917 sql_help.c:2314 msgid "minvalue" msgstr "최소값" -#: sql_help.c:875 sql_help.c:2153 +#: sql_help.c:918 sql_help.c:2315 msgid "maxvalue" msgstr "최대값" -#: sql_help.c:876 sql_help.c:2154 sql_help.c:3631 sql_help.c:3721 -#: sql_help.c:3870 sql_help.c:3999 sql_help.c:4064 +#: sql_help.c:919 sql_help.c:2316 sql_help.c:3905 sql_help.c:3995 +#: sql_help.c:4144 sql_help.c:4273 sql_help.c:4338 msgid "start" msgstr "시작" -#: sql_help.c:877 +#: sql_help.c:920 sql_help.c:1122 msgid "restart" msgstr "재시작" -#: sql_help.c:878 sql_help.c:2155 +#: sql_help.c:921 sql_help.c:2317 msgid "cache" msgstr "ìºì‰¬" -#: sql_help.c:1025 +#: sql_help.c:978 sql_help.c:2361 +msgid "conninfo" +msgstr "ì ‘ì†ì •ë³´" + +#: sql_help.c:980 sql_help.c:2362 +msgid "publication_name" +msgstr "발행_ì´ë¦„" + +#: sql_help.c:981 +msgid "set_publication_option" +msgstr "발행_옵션_설정" + +#: sql_help.c:984 +msgid "refresh_option" +msgstr "새로고침_옵션" + +#: sql_help.c:989 sql_help.c:2363 +msgid "subscription_parameter" +msgstr "구ë…_매개변수" + +#: sql_help.c:1100 sql_help.c:1103 +msgid "partition_name" +msgstr "파티션_ì´ë¦„" + +#: sql_help.c:1101 sql_help.c:1984 sql_help.c:2481 +msgid "partition_bound_spec" +msgstr "파티션_범위_ì •ì˜" + +#: sql_help.c:1119 sql_help.c:2493 +msgid "sequence_options" +msgstr "시퀀스_옵션" + +#: sql_help.c:1121 +msgid "sequence_option" +msgstr "시퀀스_옵션" + +#: sql_help.c:1133 msgid "table_constraint_using_index" msgstr "" -#: sql_help.c:1033 sql_help.c:1034 sql_help.c:1035 sql_help.c:1036 +#: sql_help.c:1141 sql_help.c:1142 sql_help.c:1143 sql_help.c:1144 msgid "rewrite_rule_name" msgstr "" -#: sql_help.c:1047 +#: sql_help.c:1155 msgid "and table_constraint_using_index is:" msgstr "" -#: sql_help.c:1065 sql_help.c:1068 sql_help.c:2324 +#: sql_help.c:1173 sql_help.c:1176 sql_help.c:2565 msgid "tablespace_option" msgstr "í…Œì´ë¸”스페ì´ìФ_옵션" -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1098 sql_help.c:1102 +#: sql_help.c:1197 sql_help.c:1200 sql_help.c:1206 sql_help.c:1210 msgid "token_type" msgstr "토í°_종류" -#: sql_help.c:1090 sql_help.c:1093 +#: sql_help.c:1198 sql_help.c:1201 msgid "dictionary_name" msgstr "사전ì´ë¦„" -#: sql_help.c:1095 sql_help.c:1099 +#: sql_help.c:1203 sql_help.c:1207 msgid "old_dictionary" msgstr "옛사전" -#: sql_help.c:1096 sql_help.c:1100 +#: sql_help.c:1204 sql_help.c:1208 msgid "new_dictionary" msgstr "새사전" -#: sql_help.c:1191 sql_help.c:1201 sql_help.c:1204 sql_help.c:1205 -#: sql_help.c:2473 +#: sql_help.c:1300 sql_help.c:1313 sql_help.c:1316 sql_help.c:1317 +#: sql_help.c:2716 msgid "attribute_name" msgstr "ì†ì„±ì´ë¦„" -#: sql_help.c:1192 +#: sql_help.c:1301 msgid "new_attribute_name" msgstr "새ì†ì„±ì´ë¦„" -#: sql_help.c:1198 +#: sql_help.c:1307 sql_help.c:1311 msgid "new_enum_value" msgstr "" -#: sql_help.c:1199 +#: sql_help.c:1308 +msgid "neighbor_enum_value" +msgstr "" + +#: sql_help.c:1310 msgid "existing_enum_value" msgstr "" -#: sql_help.c:1269 sql_help.c:1841 sql_help.c:2167 sql_help.c:2551 -#: sql_help.c:2948 sql_help.c:3119 sql_help.c:3154 sql_help.c:3451 +#: sql_help.c:1385 sql_help.c:1976 sql_help.c:1985 sql_help.c:2329 +#: sql_help.c:2794 sql_help.c:3215 sql_help.c:3388 sql_help.c:3423 +#: sql_help.c:3721 msgid "server_name" msgstr "서버ì´ë¦„" -#: sql_help.c:1297 sql_help.c:1300 sql_help.c:2566 +#: sql_help.c:1413 sql_help.c:1416 sql_help.c:2809 msgid "view_option_name" msgstr "ë·°_옵션ì´ë¦„" -#: sql_help.c:1298 sql_help.c:2567 +#: sql_help.c:1414 sql_help.c:2810 msgid "view_option_value" msgstr "" -#: sql_help.c:1323 sql_help.c:3779 sql_help.c:3781 sql_help.c:3805 +#: sql_help.c:1439 sql_help.c:4053 sql_help.c:4055 sql_help.c:4079 msgid "transaction_mode" msgstr "트랜잭션모드" -#: sql_help.c:1324 sql_help.c:3782 sql_help.c:3806 +#: sql_help.c:1440 sql_help.c:4056 sql_help.c:4080 msgid "where transaction_mode is one of:" msgstr "트랜잭션모드 사용법:" -#: sql_help.c:1409 +#: sql_help.c:1528 msgid "relation_name" msgstr "릴레ì´ì…˜ì´ë¦„" -#: sql_help.c:1414 sql_help.c:3115 sql_help.c:3447 +#: sql_help.c:1533 sql_help.c:3384 sql_help.c:3717 msgid "domain_name" msgstr "ë„ë©”ì¸ì´ë¦„" -#: sql_help.c:1436 +#: sql_help.c:1555 msgid "policy_name" msgstr "ì •ì±…ì´ë¦„" -#: sql_help.c:1440 +#: sql_help.c:1560 msgid "rule_name" msgstr "룰ì´ë¦„" -#: sql_help.c:1457 +#: sql_help.c:1579 msgid "text" msgstr "" -#: sql_help.c:1482 sql_help.c:3297 sql_help.c:3485 +#: sql_help.c:1604 sql_help.c:3567 sql_help.c:3755 msgid "transaction_id" -msgstr "" +msgstr "트랜잭션_id" -#: sql_help.c:1513 sql_help.c:1519 sql_help.c:3223 +#: sql_help.c:1635 sql_help.c:1641 sql_help.c:3493 msgid "filename" msgstr "파ì¼ì´ë¦„" -#: sql_help.c:1514 sql_help.c:1520 sql_help.c:2110 sql_help.c:2111 -#: sql_help.c:2112 +#: sql_help.c:1636 sql_help.c:1642 sql_help.c:2269 sql_help.c:2270 +#: sql_help.c:2271 msgid "command" msgstr "명령어" -#: sql_help.c:1518 sql_help.c:1981 sql_help.c:2310 sql_help.c:2568 -#: sql_help.c:2586 sql_help.c:3188 +#: sql_help.c:1640 sql_help.c:2125 sql_help.c:2551 sql_help.c:2811 +#: sql_help.c:2829 sql_help.c:3458 msgid "query" msgstr "쿼리문" -#: sql_help.c:1522 sql_help.c:2993 +#: sql_help.c:1644 sql_help.c:3261 msgid "where option can be one of:" msgstr "옵션 사용법:" -#: sql_help.c:1523 +#: sql_help.c:1645 msgid "format_name" msgstr "입출력양ì‹ì´ë¦„" -#: sql_help.c:1524 sql_help.c:1525 sql_help.c:1528 sql_help.c:2994 -#: sql_help.c:2995 sql_help.c:2996 sql_help.c:2997 sql_help.c:2998 +#: sql_help.c:1646 sql_help.c:1647 sql_help.c:1650 sql_help.c:3262 +#: sql_help.c:3263 sql_help.c:3264 sql_help.c:3265 sql_help.c:3266 +#: sql_help.c:3267 msgid "boolean" msgstr "" -#: sql_help.c:1526 +#: sql_help.c:1648 msgid "delimiter_character" msgstr "구분문ìž" -#: sql_help.c:1527 +#: sql_help.c:1649 msgid "null_string" msgstr "ë„문ìžì—´" -#: sql_help.c:1529 +#: sql_help.c:1651 msgid "quote_character" msgstr "ì¸ìš©ë¶€í˜¸" -#: sql_help.c:1530 +#: sql_help.c:1652 msgid "escape_character" msgstr "ì´ìŠ¤ì¼€ì´í”„ 문ìž" -#: sql_help.c:1534 +#: sql_help.c:1656 msgid "encoding_name" msgstr "ì¸ì½”딩ì´ë¦„" -#: sql_help.c:1545 +#: sql_help.c:1667 msgid "access_method_type" msgstr "" -#: sql_help.c:1611 sql_help.c:1630 sql_help.c:1633 +#: sql_help.c:1733 sql_help.c:1752 sql_help.c:1755 msgid "arg_data_type" msgstr "ì¸ìžìžë£Œí˜•" -#: sql_help.c:1612 sql_help.c:1634 sql_help.c:1642 +#: sql_help.c:1734 sql_help.c:1756 sql_help.c:1764 msgid "sfunc" msgstr "" -#: sql_help.c:1613 sql_help.c:1635 sql_help.c:1643 +#: sql_help.c:1735 sql_help.c:1757 sql_help.c:1765 msgid "state_data_type" msgstr "" -#: sql_help.c:1614 sql_help.c:1636 sql_help.c:1644 +#: sql_help.c:1736 sql_help.c:1758 sql_help.c:1766 msgid "state_data_size" msgstr "" -#: sql_help.c:1615 sql_help.c:1637 sql_help.c:1645 +#: sql_help.c:1737 sql_help.c:1759 sql_help.c:1767 msgid "ffunc" msgstr "" -#: sql_help.c:1616 sql_help.c:1646 +#: sql_help.c:1738 sql_help.c:1768 msgid "combinefunc" msgstr "" -#: sql_help.c:1617 sql_help.c:1647 +#: sql_help.c:1739 sql_help.c:1769 msgid "serialfunc" msgstr "" -#: sql_help.c:1618 sql_help.c:1648 +#: sql_help.c:1740 sql_help.c:1770 msgid "deserialfunc" msgstr "" -#: sql_help.c:1619 sql_help.c:1638 sql_help.c:1649 +#: sql_help.c:1741 sql_help.c:1760 sql_help.c:1771 msgid "initial_condition" msgstr "" -#: sql_help.c:1620 sql_help.c:1650 +#: sql_help.c:1742 sql_help.c:1772 msgid "msfunc" msgstr "" -#: sql_help.c:1621 sql_help.c:1651 +#: sql_help.c:1743 sql_help.c:1773 msgid "minvfunc" msgstr "" -#: sql_help.c:1622 sql_help.c:1652 +#: sql_help.c:1744 sql_help.c:1774 msgid "mstate_data_type" msgstr "" -#: sql_help.c:1623 sql_help.c:1653 +#: sql_help.c:1745 sql_help.c:1775 msgid "mstate_data_size" msgstr "" -#: sql_help.c:1624 sql_help.c:1654 +#: sql_help.c:1746 sql_help.c:1776 msgid "mffunc" msgstr "" -#: sql_help.c:1625 sql_help.c:1655 +#: sql_help.c:1747 sql_help.c:1777 msgid "minitial_condition" msgstr "" -#: sql_help.c:1626 sql_help.c:1656 +#: sql_help.c:1748 sql_help.c:1778 msgid "sort_operator" msgstr "정렬연산ìž" -#: sql_help.c:1639 +#: sql_help.c:1761 msgid "or the old syntax" -msgstr "" +msgstr "ë˜ëŠ” 옛날 구문" -#: sql_help.c:1641 +#: sql_help.c:1763 msgid "base_type" msgstr "기본ìžë£Œí˜•" -#: sql_help.c:1695 +#: sql_help.c:1819 msgid "locale" msgstr "로케ì¼" -#: sql_help.c:1696 sql_help.c:1732 +#: sql_help.c:1820 sql_help.c:1858 msgid "lc_collate" -msgstr "" +msgstr "lc_collate" -#: sql_help.c:1697 sql_help.c:1733 +#: sql_help.c:1821 sql_help.c:1859 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1699 +#: sql_help.c:1822 sql_help.c:3806 +msgid "provider" +msgstr "제공ìž" + +#: sql_help.c:1823 sql_help.c:1914 +msgid "version" +msgstr "버전" + +#: sql_help.c:1825 msgid "existing_collation" msgstr "" -#: sql_help.c:1709 +#: sql_help.c:1835 msgid "source_encoding" msgstr "ì›ëž˜ì¸ì½”딩" -#: sql_help.c:1710 +#: sql_help.c:1836 msgid "dest_encoding" msgstr "대ìƒì¸ì½”딩" -#: sql_help.c:1730 sql_help.c:2350 +#: sql_help.c:1856 sql_help.c:2591 msgid "template" msgstr "템플릿" -#: sql_help.c:1731 +#: sql_help.c:1857 msgid "encoding" msgstr "ì¸ì½”딩" -#: sql_help.c:1757 +#: sql_help.c:1883 msgid "constraint" msgstr "제약조건" -#: sql_help.c:1758 +#: sql_help.c:1884 msgid "where constraint is:" msgstr "제약조건 사용법:" -#: sql_help.c:1772 sql_help.c:2107 sql_help.c:2422 +#: sql_help.c:1898 sql_help.c:2266 sql_help.c:2664 msgid "event" msgstr "ì´ë²¤íЏ" -#: sql_help.c:1773 +#: sql_help.c:1899 msgid "filter_variable" msgstr "" -#: sql_help.c:1788 -msgid "version" -msgstr "버전" - -#: sql_help.c:1789 +#: sql_help.c:1915 msgid "old_version" msgstr "옛버전" -#: sql_help.c:1844 sql_help.c:2256 +#: sql_help.c:1988 sql_help.c:2489 msgid "where column_constraint is:" msgstr "칼럼_제약조건 사용법:" -#: sql_help.c:1847 sql_help.c:1879 sql_help.c:2259 +#: sql_help.c:1991 sql_help.c:2023 sql_help.c:2492 msgid "default_expr" msgstr "초기값_표현ì‹" -#: sql_help.c:1848 sql_help.c:2266 +#: sql_help.c:1992 sql_help.c:2500 msgid "and table_constraint is:" msgstr "í…Œì´ë¸”_제약조건 사용법:" -#: sql_help.c:1880 +#: sql_help.c:2024 msgid "rettype" msgstr "" -#: sql_help.c:1882 +#: sql_help.c:2026 msgid "column_type" msgstr "" -#: sql_help.c:1890 +#: sql_help.c:2034 msgid "definition" msgstr "함수정ì˜" -#: sql_help.c:1891 +#: sql_help.c:2035 msgid "obj_file" msgstr "오브ì íŠ¸íŒŒì¼" -#: sql_help.c:1892 +#: sql_help.c:2036 msgid "link_symbol" msgstr "ì—°ê²°í• _함수명" -#: sql_help.c:1893 +#: sql_help.c:2037 msgid "attribute" msgstr "ì†ì„±" -#: sql_help.c:1927 sql_help.c:2092 sql_help.c:2540 +#: sql_help.c:2071 sql_help.c:2251 sql_help.c:2783 msgid "uid" msgstr "" -#: sql_help.c:1941 +#: sql_help.c:2085 msgid "method" msgstr "색ì¸ë°©ë²•" -#: sql_help.c:1945 sql_help.c:2291 sql_help.c:3197 +#: sql_help.c:2089 sql_help.c:2460 sql_help.c:2472 sql_help.c:2485 +#: sql_help.c:2532 sql_help.c:3467 msgid "opclass" -msgstr "" +msgstr "ì—°ì‚°ìží´ëž˜ìФ" -#: sql_help.c:1949 sql_help.c:2277 +#: sql_help.c:2093 sql_help.c:2511 msgid "predicate" msgstr "범위한정구문" -#: sql_help.c:1961 +#: sql_help.c:2105 msgid "call_handler" msgstr "" -#: sql_help.c:1962 +#: sql_help.c:2106 msgid "inline_handler" msgstr "" -#: sql_help.c:1963 +#: sql_help.c:2107 msgid "valfunction" msgstr "구문검사함수" -#: sql_help.c:1999 +#: sql_help.c:2143 msgid "com_op" msgstr "" -#: sql_help.c:2000 +#: sql_help.c:2144 msgid "neg_op" msgstr "" -#: sql_help.c:2018 +#: sql_help.c:2162 msgid "family_name" msgstr "" -#: sql_help.c:2029 +#: sql_help.c:2173 msgid "storage_type" msgstr "스토리지_유형" -#: sql_help.c:2109 sql_help.c:2425 sql_help.c:2602 sql_help.c:3207 -#: sql_help.c:3622 sql_help.c:3624 sql_help.c:3712 sql_help.c:3714 -#: sql_help.c:3861 sql_help.c:3863 sql_help.c:3966 sql_help.c:4055 -#: sql_help.c:4057 +#: sql_help.c:2268 sql_help.c:2668 sql_help.c:2845 sql_help.c:3477 +#: sql_help.c:3896 sql_help.c:3898 sql_help.c:3986 sql_help.c:3988 +#: sql_help.c:4135 sql_help.c:4137 sql_help.c:4240 sql_help.c:4329 +#: sql_help.c:4331 msgid "condition" msgstr "ì¡°ê±´" -#: sql_help.c:2113 sql_help.c:2428 +#: sql_help.c:2272 sql_help.c:2671 msgid "where event can be one of:" msgstr "ì´ë²¤íЏ 사용법:" -#: sql_help.c:2132 sql_help.c:2134 +#: sql_help.c:2291 sql_help.c:2293 msgid "schema_element" msgstr "" -#: sql_help.c:2168 +#: sql_help.c:2330 msgid "server_type" msgstr "서버_종류" -#: sql_help.c:2169 +#: sql_help.c:2331 msgid "server_version" msgstr "서버_버전" -#: sql_help.c:2170 sql_help.c:3117 sql_help.c:3449 +#: sql_help.c:2332 sql_help.c:3386 sql_help.c:3719 msgid "fdw_name" -msgstr "" +msgstr "fdw_ì´ë¦„" + +#: sql_help.c:2345 +msgid "statistics_name" +msgstr "통계정보_ì´ë¦„" -#: sql_help.c:2242 +#: sql_help.c:2346 +msgid "statistics_kind" +msgstr "통계정보_종류" + +#: sql_help.c:2360 +msgid "subscription_name" +msgstr "구ë…_ì´ë¦„" + +#: sql_help.c:2454 msgid "source_table" msgstr "ì›ë³¸í…Œì´ë¸”" -#: sql_help.c:2243 +#: sql_help.c:2455 msgid "like_option" msgstr "LIKE구문옵션" -#: sql_help.c:2260 sql_help.c:2261 sql_help.c:2270 sql_help.c:2272 -#: sql_help.c:2276 +#: sql_help.c:2494 sql_help.c:2495 sql_help.c:2504 sql_help.c:2506 +#: sql_help.c:2510 msgid "index_parameters" msgstr "색ì¸ë§¤ê°œë³€ìˆ˜" -#: sql_help.c:2262 sql_help.c:2279 +#: sql_help.c:2496 sql_help.c:2513 msgid "reftable" msgstr "참조테ì´ë¸”" -#: sql_help.c:2263 sql_help.c:2280 +#: sql_help.c:2497 sql_help.c:2514 msgid "refcolumn" msgstr "참조칼럼" -#: sql_help.c:2274 +#: sql_help.c:2508 msgid "exclude_element" msgstr "" -#: sql_help.c:2275 sql_help.c:3629 sql_help.c:3719 sql_help.c:3868 -#: sql_help.c:3997 sql_help.c:4062 +#: sql_help.c:2509 sql_help.c:3903 sql_help.c:3993 sql_help.c:4142 +#: sql_help.c:4271 sql_help.c:4336 msgid "operator" msgstr "ì—°ì‚°ìž" -#: sql_help.c:2283 +#: sql_help.c:2517 msgid "and like_option is:" msgstr "" -#: sql_help.c:2284 +#: sql_help.c:2518 +msgid "and partition_bound_spec is:" +msgstr "" + +#: sql_help.c:2519 sql_help.c:2521 sql_help.c:2523 +msgid "numeric_literal" +msgstr "" + +#: sql_help.c:2520 sql_help.c:2522 sql_help.c:2524 +msgid "string_literal" +msgstr "" + +#: sql_help.c:2525 msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" msgstr "" -#: sql_help.c:2288 +#: sql_help.c:2529 msgid "exclude_element in an EXCLUDE constraint is:" msgstr "" -#: sql_help.c:2323 +#: sql_help.c:2564 msgid "directory" msgstr "디렉터리" -#: sql_help.c:2337 +#: sql_help.c:2578 msgid "parser_name" msgstr "구문분ì„기_ì´ë¦„" -#: sql_help.c:2338 +#: sql_help.c:2579 msgid "source_config" msgstr "ì›ë³¸_설정" -#: sql_help.c:2367 +#: sql_help.c:2608 msgid "start_function" msgstr "시작_함수" -#: sql_help.c:2368 +#: sql_help.c:2609 msgid "gettoken_function" msgstr "gettoken함수" -#: sql_help.c:2369 +#: sql_help.c:2610 msgid "end_function" msgstr "종료_함수" -#: sql_help.c:2370 +#: sql_help.c:2611 msgid "lextypes_function" msgstr "lextypes함수" -#: sql_help.c:2371 +#: sql_help.c:2612 msgid "headline_function" msgstr "headline함수" -#: sql_help.c:2383 +#: sql_help.c:2624 msgid "init_function" msgstr "init함수" -#: sql_help.c:2384 +#: sql_help.c:2625 msgid "lexize_function" msgstr "lexize함수" -#: sql_help.c:2397 +#: sql_help.c:2638 msgid "from_sql_function_name" msgstr "" -#: sql_help.c:2399 +#: sql_help.c:2640 msgid "to_sql_function_name" msgstr "" -#: sql_help.c:2424 +#: sql_help.c:2666 msgid "referenced_table_name" msgstr "" -#: sql_help.c:2427 +#: sql_help.c:2667 +msgid "transition_relation_name" +msgstr "전달_릴레ì´ì…˜ì´ë¦„" + +#: sql_help.c:2670 msgid "arguments" msgstr "ì¸ìžë“¤" -#: sql_help.c:2477 sql_help.c:3557 +#: sql_help.c:2720 sql_help.c:3831 msgid "label" msgstr "" -#: sql_help.c:2479 +#: sql_help.c:2722 msgid "subtype" msgstr "" -#: sql_help.c:2480 +#: sql_help.c:2723 msgid "subtype_operator_class" msgstr "" -#: sql_help.c:2482 +#: sql_help.c:2725 msgid "canonical_function" msgstr "" -#: sql_help.c:2483 +#: sql_help.c:2726 msgid "subtype_diff_function" msgstr "" -#: sql_help.c:2485 +#: sql_help.c:2728 msgid "input_function" msgstr "입력함수" -#: sql_help.c:2486 +#: sql_help.c:2729 msgid "output_function" msgstr "출력함수" -#: sql_help.c:2487 +#: sql_help.c:2730 msgid "receive_function" msgstr "받는함수" -#: sql_help.c:2488 +#: sql_help.c:2731 msgid "send_function" msgstr "주는함수" -#: sql_help.c:2489 +#: sql_help.c:2732 msgid "type_modifier_input_function" msgstr "" -#: sql_help.c:2490 +#: sql_help.c:2733 msgid "type_modifier_output_function" msgstr "" -#: sql_help.c:2491 +#: sql_help.c:2734 msgid "analyze_function" msgstr "ë¶„ì„함수" -#: sql_help.c:2492 +#: sql_help.c:2735 msgid "internallength" msgstr "" -#: sql_help.c:2493 +#: sql_help.c:2736 msgid "alignment" msgstr "ì •ë ¬" -#: sql_help.c:2494 +#: sql_help.c:2737 msgid "storage" msgstr "스토리지" -#: sql_help.c:2495 +#: sql_help.c:2738 msgid "like_type" msgstr "" -#: sql_help.c:2496 +#: sql_help.c:2739 msgid "category" msgstr "" -#: sql_help.c:2497 +#: sql_help.c:2740 msgid "preferred" msgstr "" -#: sql_help.c:2498 +#: sql_help.c:2741 msgid "default" msgstr "기본값" -#: sql_help.c:2499 +#: sql_help.c:2742 msgid "element" msgstr "요소" -#: sql_help.c:2500 +#: sql_help.c:2743 msgid "delimiter" msgstr "구분ìž" -#: sql_help.c:2501 +#: sql_help.c:2744 msgid "collatable" msgstr "" -#: sql_help.c:2598 sql_help.c:3183 sql_help.c:3617 sql_help.c:3706 -#: sql_help.c:3856 sql_help.c:3956 sql_help.c:4050 +#: sql_help.c:2841 sql_help.c:3453 sql_help.c:3891 sql_help.c:3980 +#: sql_help.c:4130 sql_help.c:4230 sql_help.c:4324 msgid "with_query" msgstr "" -#: sql_help.c:2600 sql_help.c:3185 sql_help.c:3636 sql_help.c:3642 -#: sql_help.c:3645 sql_help.c:3649 sql_help.c:3653 sql_help.c:3661 -#: sql_help.c:3875 sql_help.c:3881 sql_help.c:3884 sql_help.c:3888 -#: sql_help.c:3892 sql_help.c:3900 sql_help.c:3958 sql_help.c:4069 -#: sql_help.c:4075 sql_help.c:4078 sql_help.c:4082 sql_help.c:4086 -#: sql_help.c:4094 +#: sql_help.c:2843 sql_help.c:3455 sql_help.c:3910 sql_help.c:3916 +#: sql_help.c:3919 sql_help.c:3923 sql_help.c:3927 sql_help.c:3935 +#: sql_help.c:4149 sql_help.c:4155 sql_help.c:4158 sql_help.c:4162 +#: sql_help.c:4166 sql_help.c:4174 sql_help.c:4232 sql_help.c:4343 +#: sql_help.c:4349 sql_help.c:4352 sql_help.c:4356 sql_help.c:4360 +#: sql_help.c:4368 msgid "alias" -msgstr "" +msgstr "별칭" -#: sql_help.c:2601 +#: sql_help.c:2844 msgid "using_list" msgstr "" -#: sql_help.c:2603 sql_help.c:3024 sql_help.c:3264 sql_help.c:3967 +#: sql_help.c:2846 sql_help.c:3293 sql_help.c:3534 sql_help.c:4241 msgid "cursor_name" msgstr "커서ì´ë¦„" -#: sql_help.c:2604 sql_help.c:3191 sql_help.c:3968 +#: sql_help.c:2847 sql_help.c:3461 sql_help.c:4242 msgid "output_expression" msgstr "출력표현ì‹" -#: sql_help.c:2605 sql_help.c:3192 sql_help.c:3620 sql_help.c:3709 -#: sql_help.c:3859 sql_help.c:3969 sql_help.c:4053 +#: sql_help.c:2848 sql_help.c:3462 sql_help.c:3894 sql_help.c:3983 +#: sql_help.c:4133 sql_help.c:4243 sql_help.c:4327 msgid "output_name" msgstr "" -#: sql_help.c:2621 +#: sql_help.c:2864 msgid "code" msgstr "" -#: sql_help.c:2972 +#: sql_help.c:3239 msgid "parameter" msgstr "매개변수" -#: sql_help.c:2991 sql_help.c:2992 sql_help.c:3289 +#: sql_help.c:3259 sql_help.c:3260 sql_help.c:3559 msgid "statement" msgstr "명령구문" -#: sql_help.c:3023 sql_help.c:3263 +#: sql_help.c:3292 sql_help.c:3533 msgid "direction" msgstr "ë°©í–¥" -#: sql_help.c:3025 sql_help.c:3265 +#: sql_help.c:3294 sql_help.c:3535 msgid "where direction can be empty or one of:" msgstr "ë°©í–¥ ìžë¦¬ëŠ” 비워ë‘거나 ë‹¤ìŒ ì¤‘ 하나:" -#: sql_help.c:3026 sql_help.c:3027 sql_help.c:3028 sql_help.c:3029 -#: sql_help.c:3030 sql_help.c:3266 sql_help.c:3267 sql_help.c:3268 -#: sql_help.c:3269 sql_help.c:3270 sql_help.c:3630 sql_help.c:3632 -#: sql_help.c:3720 sql_help.c:3722 sql_help.c:3869 sql_help.c:3871 -#: sql_help.c:3998 sql_help.c:4000 sql_help.c:4063 sql_help.c:4065 +#: sql_help.c:3295 sql_help.c:3296 sql_help.c:3297 sql_help.c:3298 +#: sql_help.c:3299 sql_help.c:3536 sql_help.c:3537 sql_help.c:3538 +#: sql_help.c:3539 sql_help.c:3540 sql_help.c:3904 sql_help.c:3906 +#: sql_help.c:3994 sql_help.c:3996 sql_help.c:4143 sql_help.c:4145 +#: sql_help.c:4272 sql_help.c:4274 sql_help.c:4337 sql_help.c:4339 msgid "count" msgstr "출력개수" -#: sql_help.c:3110 sql_help.c:3442 +#: sql_help.c:3379 sql_help.c:3712 msgid "sequence_name" msgstr "시퀀스ì´ë¦„" -#: sql_help.c:3123 sql_help.c:3455 +#: sql_help.c:3392 sql_help.c:3725 msgid "arg_name" msgstr "ì¸ìžì´ë¦„" -#: sql_help.c:3124 sql_help.c:3456 +#: sql_help.c:3393 sql_help.c:3726 msgid "arg_type" msgstr "ì¸ìžìžë£Œí˜•" -#: sql_help.c:3129 sql_help.c:3461 +#: sql_help.c:3398 sql_help.c:3731 msgid "loid" msgstr "" -#: sql_help.c:3152 +#: sql_help.c:3421 msgid "remote_schema" msgstr "ì›ê²©_스키마" -#: sql_help.c:3155 +#: sql_help.c:3424 msgid "local_schema" msgstr "로컬_스키마" -#: sql_help.c:3189 +#: sql_help.c:3459 msgid "conflict_target" msgstr "" -#: sql_help.c:3190 +#: sql_help.c:3460 msgid "conflict_action" msgstr "" -#: sql_help.c:3193 +#: sql_help.c:3463 msgid "where conflict_target can be one of:" msgstr "conflict_target 사용법:" -#: sql_help.c:3194 +#: sql_help.c:3464 msgid "index_column_name" msgstr "ì¸ë±ìŠ¤ì¹¼ëŸ¼ì´ë¦„" -#: sql_help.c:3195 +#: sql_help.c:3465 msgid "index_expression" msgstr "ì¸ë±ìŠ¤í‘œí˜„ì‹" -#: sql_help.c:3198 +#: sql_help.c:3468 msgid "index_predicate" msgstr "" -#: sql_help.c:3200 +#: sql_help.c:3470 msgid "and conflict_action is one of:" msgstr "conflict_action 사용법:" -#: sql_help.c:3206 sql_help.c:3964 +#: sql_help.c:3476 sql_help.c:4238 msgid "sub-SELECT" msgstr "" -#: sql_help.c:3215 sql_help.c:3278 sql_help.c:3940 +#: sql_help.c:3485 sql_help.c:3548 sql_help.c:4214 msgid "channel" msgstr "" -#: sql_help.c:3237 +#: sql_help.c:3507 msgid "lockmode" msgstr "" -#: sql_help.c:3238 +#: sql_help.c:3508 msgid "where lockmode is one of:" msgstr "lockmode 사용법:" -#: sql_help.c:3279 +#: sql_help.c:3549 msgid "payload" msgstr "" -#: sql_help.c:3306 +#: sql_help.c:3576 msgid "old_role" msgstr "기존롤" -#: sql_help.c:3307 +#: sql_help.c:3577 msgid "new_role" msgstr "새롤" -#: sql_help.c:3332 sql_help.c:3493 sql_help.c:3501 +#: sql_help.c:3602 sql_help.c:3763 sql_help.c:3771 msgid "savepoint_name" msgstr "savepoint_name" -#: sql_help.c:3534 -msgid "provider" -msgstr "" - -#: sql_help.c:3621 sql_help.c:3663 sql_help.c:3665 sql_help.c:3711 -#: sql_help.c:3860 sql_help.c:3902 sql_help.c:3904 sql_help.c:4054 -#: sql_help.c:4096 sql_help.c:4098 +#: sql_help.c:3895 sql_help.c:3937 sql_help.c:3939 sql_help.c:3985 +#: sql_help.c:4134 sql_help.c:4176 sql_help.c:4178 sql_help.c:4328 +#: sql_help.c:4370 sql_help.c:4372 msgid "from_item" msgstr "" -#: sql_help.c:3623 sql_help.c:3675 sql_help.c:3862 sql_help.c:3914 -#: sql_help.c:4056 sql_help.c:4108 +#: sql_help.c:3897 sql_help.c:3949 sql_help.c:4136 sql_help.c:4188 +#: sql_help.c:4330 sql_help.c:4382 msgid "grouping_element" msgstr "" -#: sql_help.c:3625 sql_help.c:3715 sql_help.c:3864 sql_help.c:4058 +#: sql_help.c:3899 sql_help.c:3989 sql_help.c:4138 sql_help.c:4332 msgid "window_name" msgstr "윈ë„ìš°ì´ë¦„" -#: sql_help.c:3626 sql_help.c:3716 sql_help.c:3865 sql_help.c:4059 +#: sql_help.c:3900 sql_help.c:3990 sql_help.c:4139 sql_help.c:4333 msgid "window_definition" msgstr "ì›ë„ìš°ì •ì˜" -#: sql_help.c:3627 sql_help.c:3641 sql_help.c:3679 sql_help.c:3717 -#: sql_help.c:3866 sql_help.c:3880 sql_help.c:3918 sql_help.c:4060 -#: sql_help.c:4074 sql_help.c:4112 +#: sql_help.c:3901 sql_help.c:3915 sql_help.c:3953 sql_help.c:3991 +#: sql_help.c:4140 sql_help.c:4154 sql_help.c:4192 sql_help.c:4334 +#: sql_help.c:4348 sql_help.c:4386 msgid "select" msgstr "" -#: sql_help.c:3634 sql_help.c:3873 sql_help.c:4067 +#: sql_help.c:3908 sql_help.c:4147 sql_help.c:4341 msgid "where from_item can be one of:" msgstr "" -#: sql_help.c:3637 sql_help.c:3643 sql_help.c:3646 sql_help.c:3650 -#: sql_help.c:3662 sql_help.c:3876 sql_help.c:3882 sql_help.c:3885 -#: sql_help.c:3889 sql_help.c:3901 sql_help.c:4070 sql_help.c:4076 -#: sql_help.c:4079 sql_help.c:4083 sql_help.c:4095 +#: sql_help.c:3911 sql_help.c:3917 sql_help.c:3920 sql_help.c:3924 +#: sql_help.c:3936 sql_help.c:4150 sql_help.c:4156 sql_help.c:4159 +#: sql_help.c:4163 sql_help.c:4175 sql_help.c:4344 sql_help.c:4350 +#: sql_help.c:4353 sql_help.c:4357 sql_help.c:4369 msgid "column_alias" msgstr "칼럼별칭" -#: sql_help.c:3638 sql_help.c:3877 sql_help.c:4071 +#: sql_help.c:3912 sql_help.c:4151 sql_help.c:4345 msgid "sampling_method" msgstr "표본추출방법" -#: sql_help.c:3639 sql_help.c:3648 sql_help.c:3652 sql_help.c:3656 -#: sql_help.c:3659 sql_help.c:3878 sql_help.c:3887 sql_help.c:3891 -#: sql_help.c:3895 sql_help.c:3898 sql_help.c:4072 sql_help.c:4081 -#: sql_help.c:4085 sql_help.c:4089 sql_help.c:4092 +#: sql_help.c:3913 sql_help.c:3922 sql_help.c:3926 sql_help.c:3930 +#: sql_help.c:3933 sql_help.c:4152 sql_help.c:4161 sql_help.c:4165 +#: sql_help.c:4169 sql_help.c:4172 sql_help.c:4346 sql_help.c:4355 +#: sql_help.c:4359 sql_help.c:4363 sql_help.c:4366 msgid "argument" msgstr "ì¸ìž" -#: sql_help.c:3640 sql_help.c:3879 sql_help.c:4073 +#: sql_help.c:3914 sql_help.c:4153 sql_help.c:4347 msgid "seed" msgstr "" -#: sql_help.c:3644 sql_help.c:3677 sql_help.c:3883 sql_help.c:3916 -#: sql_help.c:4077 sql_help.c:4110 +#: sql_help.c:3918 sql_help.c:3951 sql_help.c:4157 sql_help.c:4190 +#: sql_help.c:4351 sql_help.c:4384 msgid "with_query_name" msgstr "" -#: sql_help.c:3654 sql_help.c:3657 sql_help.c:3660 sql_help.c:3893 -#: sql_help.c:3896 sql_help.c:3899 sql_help.c:4087 sql_help.c:4090 -#: sql_help.c:4093 +#: sql_help.c:3928 sql_help.c:3931 sql_help.c:3934 sql_help.c:4167 +#: sql_help.c:4170 sql_help.c:4173 sql_help.c:4361 sql_help.c:4364 +#: sql_help.c:4367 msgid "column_definition" msgstr "칼럼정ì˜" -#: sql_help.c:3664 sql_help.c:3903 sql_help.c:4097 +#: sql_help.c:3938 sql_help.c:4177 sql_help.c:4371 msgid "join_type" msgstr "" -#: sql_help.c:3666 sql_help.c:3905 sql_help.c:4099 +#: sql_help.c:3940 sql_help.c:4179 sql_help.c:4373 msgid "join_condition" msgstr "" -#: sql_help.c:3667 sql_help.c:3906 sql_help.c:4100 +#: sql_help.c:3941 sql_help.c:4180 sql_help.c:4374 msgid "join_column" msgstr "" -#: sql_help.c:3668 sql_help.c:3907 sql_help.c:4101 +#: sql_help.c:3942 sql_help.c:4181 sql_help.c:4375 msgid "and grouping_element can be one of:" msgstr "" -#: sql_help.c:3676 sql_help.c:3915 sql_help.c:4109 +#: sql_help.c:3950 sql_help.c:4189 sql_help.c:4383 msgid "and with_query is:" msgstr "" -#: sql_help.c:3680 sql_help.c:3919 sql_help.c:4113 +#: sql_help.c:3954 sql_help.c:4193 sql_help.c:4387 msgid "values" msgstr "ê°’" -#: sql_help.c:3681 sql_help.c:3920 sql_help.c:4114 +#: sql_help.c:3955 sql_help.c:4194 sql_help.c:4388 msgid "insert" msgstr "" -#: sql_help.c:3682 sql_help.c:3921 sql_help.c:4115 +#: sql_help.c:3956 sql_help.c:4195 sql_help.c:4389 msgid "update" msgstr "" -#: sql_help.c:3683 sql_help.c:3922 sql_help.c:4116 +#: sql_help.c:3957 sql_help.c:4196 sql_help.c:4390 msgid "delete" msgstr "" -#: sql_help.c:3710 +#: sql_help.c:3984 msgid "new_table" msgstr "새테ì´ë¸”" -#: sql_help.c:3735 +#: sql_help.c:4009 msgid "timezone" msgstr "" -#: sql_help.c:3780 +#: sql_help.c:4054 msgid "snapshot_id" msgstr "" -#: sql_help.c:3965 +#: sql_help.c:4239 msgid "from_list" msgstr "" -#: sql_help.c:3996 +#: sql_help.c:4270 msgid "sort_expression" msgstr "" -#: sql_help.c:4123 sql_help.c:4863 +#: sql_help.c:4397 sql_help.c:5182 msgid "abort the current transaction" msgstr "현재 트랜잭션 중지함" -#: sql_help.c:4128 +#: sql_help.c:4402 msgid "change the definition of an aggregate function" msgstr "집계함수 ì •ë³´ 바꾸기" -#: sql_help.c:4133 +#: sql_help.c:4407 msgid "change the definition of a collation" msgstr "collation ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4138 +#: sql_help.c:4412 msgid "change the definition of a conversion" msgstr "문ìžì½”드 변환규칙(conversion) ì •ë³´ 바꾸기" -#: sql_help.c:4143 +#: sql_help.c:4417 msgid "change a database" msgstr "ë°ì´í„°ë² ì´ìФ 변경" -#: sql_help.c:4148 +#: sql_help.c:4422 msgid "define default access privileges" msgstr "기본 ì ‘ê·¼ 권한 ì •ì˜" -#: sql_help.c:4153 +#: sql_help.c:4427 msgid "change the definition of a domain" msgstr "ë„ë©”ì¸ ì •ë³´ 바꾸기" -#: sql_help.c:4158 +#: sql_help.c:4432 msgid "change the definition of an event trigger" msgstr "트리거 ì •ë³´ 바꾸기" -#: sql_help.c:4163 +#: sql_help.c:4437 msgid "change the definition of an extension" msgstr "확장모듈 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4168 +#: sql_help.c:4442 msgid "change the definition of a foreign-data wrapper" msgstr "외부 ë°ì´í„° ëž˜í¼ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4173 +#: sql_help.c:4447 msgid "change the definition of a foreign table" msgstr "외부 í…Œì´ë¸” ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4178 +#: sql_help.c:4452 msgid "change the definition of a function" msgstr "함수 ì •ë³´ 바꾸기" -#: sql_help.c:4183 +#: sql_help.c:4457 msgid "change role name or membership" msgstr "롤 ì´ë¦„ì´ë‚˜ 맴버쉽 바꾸기" -#: sql_help.c:4188 +#: sql_help.c:4462 msgid "change the definition of an index" msgstr "ì¸ë±ìФ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4193 +#: sql_help.c:4467 msgid "change the definition of a procedural language" msgstr "procedural language ì •ë³´ 바꾸기" -#: sql_help.c:4198 +#: sql_help.c:4472 msgid "change the definition of a large object" msgstr "대형 ê°ì²´ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4203 +#: sql_help.c:4477 msgid "change the definition of a materialized view" msgstr "materialized ë·° ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4208 +#: sql_help.c:4482 msgid "change the definition of an operator" msgstr "ì—°ì‚°ìž ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4213 +#: sql_help.c:4487 msgid "change the definition of an operator class" msgstr "ì—°ì‚°ìž í´ëž˜ìФ ì •ë³´ 바꾸기" -#: sql_help.c:4218 +#: sql_help.c:4492 msgid "change the definition of an operator family" msgstr "ì—°ì‚°ìž ë¶€ë¥˜ì˜ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4223 +#: sql_help.c:4497 msgid "change the definition of a row level security policy" msgstr "로우 단위 보안 ì •ì±…ì˜ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4228 sql_help.c:4298 +#: sql_help.c:4502 +msgid "change the definition of a publication" +msgstr "발행 ì •ë³´ 바꾸기" + +#: sql_help.c:4507 sql_help.c:4587 msgid "change a database role" msgstr "ë°ì´í„°ë² ì´ìФ 롤 변경" -#: sql_help.c:4233 +#: sql_help.c:4512 msgid "change the definition of a rule" msgstr "룰 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4238 +#: sql_help.c:4517 msgid "change the definition of a schema" msgstr "스키마 ì´ë¦„ 바꾸기" -#: sql_help.c:4243 +#: sql_help.c:4522 msgid "change the definition of a sequence generator" msgstr "시퀀스 ì •ë³´ 바꾸기" -#: sql_help.c:4248 +#: sql_help.c:4527 msgid "change the definition of a foreign server" msgstr "외부 서버 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4253 +#: sql_help.c:4532 +msgid "change the definition of an extended statistics object" +msgstr "확장 통계정보 ê°ì²´ ì •ì˜ ë°”ê¾¸ê¸°" + +#: sql_help.c:4537 +msgid "change the definition of a subscription" +msgstr "êµ¬ë… ì •ë³´ 바꾸기" + +#: sql_help.c:4542 msgid "change a server configuration parameter" msgstr "서버 환경 설정 매개 변수 바꾸기" -#: sql_help.c:4258 +#: sql_help.c:4547 msgid "change the definition of a table" msgstr "í…Œì´ë¸” ì •ë³´ 바꾸기" -#: sql_help.c:4263 +#: sql_help.c:4552 msgid "change the definition of a tablespace" msgstr "í…Œì´ë¸”스페ì´ìФ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4268 +#: sql_help.c:4557 msgid "change the definition of a text search configuration" msgstr "í…스트 검색 구성 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4273 +#: sql_help.c:4562 msgid "change the definition of a text search dictionary" msgstr "í…스트 검색 사전 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4278 +#: sql_help.c:4567 msgid "change the definition of a text search parser" msgstr "í…스트 검색 파서 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4283 +#: sql_help.c:4572 msgid "change the definition of a text search template" msgstr "í…스트 검색 템플릿 ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4288 +#: sql_help.c:4577 msgid "change the definition of a trigger" msgstr "트리거 ì •ë³´ 바꾸기" -#: sql_help.c:4293 +#: sql_help.c:4582 msgid "change the definition of a type" msgstr "ìžë£Œí˜• ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4303 +#: sql_help.c:4592 msgid "change the definition of a user mapping" msgstr "ì‚¬ìš©ìž ë§¤í•‘ ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4308 +#: sql_help.c:4597 msgid "change the definition of a view" msgstr "ë·° ì •ì˜ ë°”ê¾¸ê¸°" -#: sql_help.c:4313 +#: sql_help.c:4602 msgid "collect statistics about a database" msgstr "ë°ì´í„°ë² ì´ìФ 사용 통계 정보를 갱신함" -#: sql_help.c:4318 sql_help.c:4928 +#: sql_help.c:4607 sql_help.c:5247 msgid "start a transaction block" msgstr "트랜잭션 ë¸”ëŸ­ì„ ì‹œìž‘í•¨" -#: sql_help.c:4323 -msgid "force a transaction log checkpoint" -msgstr "트랜잭션 로그를 강제로 checkpoint함" +#: sql_help.c:4612 +msgid "force a write-ahead log checkpoint" +msgstr "트랜잭션 로그를 강제로 ì²´í¬í¬ì¸íЏ 함" -#: sql_help.c:4328 +#: sql_help.c:4617 msgid "close a cursor" msgstr "커서 닫기" -#: sql_help.c:4333 +#: sql_help.c:4622 msgid "cluster a table according to an index" msgstr "지정한 ì¸ë±ìФ 기준으로 í…Œì´ë¸” ìžë£Œë¥¼ 다시 저장함" -#: sql_help.c:4338 +#: sql_help.c:4627 msgid "define or change the comment of an object" msgstr "해당 ê°œì²´ì˜ ì½”ë©˜íŠ¸ë¥¼ 지정하거나 수정함" -#: sql_help.c:4343 sql_help.c:4763 +#: sql_help.c:4632 sql_help.c:5082 msgid "commit the current transaction" msgstr "현재 트랜잭션 commit" -#: sql_help.c:4348 +#: sql_help.c:4637 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "two-phase ì»¤ë°‹ì„ ìœ„í•´ 먼저 ì¤€ë¹„ëœ íŠ¸ëžœìž­ì…˜ì„ ì»¤ë°‹í•˜ì„¸ìš”." -#: sql_help.c:4353 +#: sql_help.c:4642 msgid "copy data between a file and a table" msgstr "í…Œì´ë¸”ê³¼ íŒŒì¼ ì‚¬ì´ ìžë£Œë¥¼ 복사함" -#: sql_help.c:4358 +#: sql_help.c:4647 msgid "define a new access method" msgstr "새 ì ‘ì† ë°©ë²• ì •ì˜" -#: sql_help.c:4363 +#: sql_help.c:4652 msgid "define a new aggregate function" msgstr "새 집계합수 만들기" -#: sql_help.c:4368 +#: sql_help.c:4657 msgid "define a new cast" msgstr "새 í˜•ë³€í™˜ìž ë§Œë“¤ê¸°" -#: sql_help.c:4373 +#: sql_help.c:4662 msgid "define a new collation" msgstr "새 collation 만들기" -#: sql_help.c:4378 +#: sql_help.c:4667 msgid "define a new encoding conversion" msgstr "새 문ìžì½”드변환규칙(conversion) 만들기" -#: sql_help.c:4383 +#: sql_help.c:4672 msgid "create a new database" msgstr "ë°ì´í„°ë² ì´ìФ ìƒì„±" -#: sql_help.c:4388 +#: sql_help.c:4677 msgid "define a new domain" msgstr "새 ë„ë©”ì¸ ë§Œë“¤ê¸°" -#: sql_help.c:4393 +#: sql_help.c:4682 msgid "define a new event trigger" msgstr "새 ì´ë²¤íЏ 트리거 만들기" -#: sql_help.c:4398 +#: sql_help.c:4687 msgid "install an extension" -msgstr "" +msgstr "확장 모듈 설치" -#: sql_help.c:4403 +#: sql_help.c:4692 msgid "define a new foreign-data wrapper" msgstr "새 외부 ë°ì´í„° ëž˜í¼ ì •ì˜" -#: sql_help.c:4408 +#: sql_help.c:4697 msgid "define a new foreign table" msgstr "새 외부 í…Œì´ë¸” ì •ì˜" -#: sql_help.c:4413 +#: sql_help.c:4702 msgid "define a new function" msgstr "새 함수 만들기" -#: sql_help.c:4418 sql_help.c:4458 sql_help.c:4533 +#: sql_help.c:4707 sql_help.c:4752 sql_help.c:4837 msgid "define a new database role" msgstr "새 ë°ì´í„°ë² ì´ìФ 롤 만들기" -#: sql_help.c:4423 +#: sql_help.c:4712 msgid "define a new index" msgstr "새 ì¸ë±ìФ 만들기" -#: sql_help.c:4428 +#: sql_help.c:4717 msgid "define a new procedural language" msgstr "새 프로시주얼 언어 만들기" -#: sql_help.c:4433 +#: sql_help.c:4722 msgid "define a new materialized view" msgstr "새 materialized ë·° 만들기" -#: sql_help.c:4438 +#: sql_help.c:4727 msgid "define a new operator" msgstr "새 ì—°ì‚°ìž ë§Œë“¤ê¸°" -#: sql_help.c:4443 +#: sql_help.c:4732 msgid "define a new operator class" msgstr "새 ì—°ìž”ìž í´ëž˜ìФ 만들기" -#: sql_help.c:4448 +#: sql_help.c:4737 msgid "define a new operator family" msgstr "새 ì—°ì‚°ìž ë¶€ë¥˜ 만들기" -#: sql_help.c:4453 +#: sql_help.c:4742 msgid "define a new row level security policy for a table" msgstr "특정 í…Œì´ë¸”ì— ë¡œìš° 단위 보안 ì •ì±… ì •ì˜" -#: sql_help.c:4463 +#: sql_help.c:4747 +msgid "define a new publication" +msgstr "새 발행 만들기" + +#: sql_help.c:4757 msgid "define a new rewrite rule" msgstr "새 룰(rule) 만들기" -#: sql_help.c:4468 +#: sql_help.c:4762 msgid "define a new schema" msgstr "새 스키마(schema) 만들기" -#: sql_help.c:4473 +#: sql_help.c:4767 msgid "define a new sequence generator" msgstr "새 시퀀스 만들기" -#: sql_help.c:4478 +#: sql_help.c:4772 msgid "define a new foreign server" msgstr "새 외부 서버 ì •ì˜" -#: sql_help.c:4483 +#: sql_help.c:4777 +msgid "define extended statistics" +msgstr "새 확장 통계정보 만들기" + +#: sql_help.c:4782 +msgid "define a new subscription" +msgstr "새 êµ¬ë… ë§Œë“¤ê¸°" + +#: sql_help.c:4787 msgid "define a new table" msgstr "새 í…Œì´ë¸” 만들기" -#: sql_help.c:4488 sql_help.c:4893 +#: sql_help.c:4792 sql_help.c:5212 msgid "define a new table from the results of a query" msgstr "쿼리 결과를 새 í…Œì´ë¸”로 만들기" -#: sql_help.c:4493 +#: sql_help.c:4797 msgid "define a new tablespace" msgstr "새 í…Œì´ë¸”스페ì´ìФ 만들기" -#: sql_help.c:4498 +#: sql_help.c:4802 msgid "define a new text search configuration" msgstr "새 í…스트 검색 구성 ì •ì˜" -#: sql_help.c:4503 +#: sql_help.c:4807 msgid "define a new text search dictionary" msgstr "새 í…스트 검색 사전 ì •ì˜" -#: sql_help.c:4508 +#: sql_help.c:4812 msgid "define a new text search parser" msgstr "새 í…스트 검색 파서 ì •ì˜" -#: sql_help.c:4513 +#: sql_help.c:4817 msgid "define a new text search template" msgstr "새 í…스트 검색 템플릿 ì •ì˜" -#: sql_help.c:4518 +#: sql_help.c:4822 msgid "define a new transform" msgstr "새 transform 만들기" -#: sql_help.c:4523 +#: sql_help.c:4827 msgid "define a new trigger" msgstr "새 트리거 만들기" -#: sql_help.c:4528 +#: sql_help.c:4832 msgid "define a new data type" msgstr "새 ìžë£Œí˜• 만들기" -#: sql_help.c:4538 +#: sql_help.c:4842 msgid "define a new mapping of a user to a foreign server" msgstr "사용ìžì™€ 외부 서버 ê°„ì˜ ìƒˆ 매핑 ì •ì˜" -#: sql_help.c:4543 +#: sql_help.c:4847 msgid "define a new view" msgstr "새 view 만들기" -#: sql_help.c:4548 +#: sql_help.c:4852 msgid "deallocate a prepared statement" msgstr "ì¤€ë¹„ëœ êµ¬ë¬¸(prepared statement) ì •ì˜" -#: sql_help.c:4553 +#: sql_help.c:4857 msgid "define a cursor" msgstr "커서 지정" -#: sql_help.c:4558 +#: sql_help.c:4862 msgid "delete rows of a table" msgstr "í…Œì´ë¸”ì˜ ìžë£Œ ì‚­ì œ" -#: sql_help.c:4563 +#: sql_help.c:4867 msgid "discard session state" msgstr "세션 ìƒíƒœ ì‚­ì œ" -#: sql_help.c:4568 +#: sql_help.c:4872 msgid "execute an anonymous code block" -msgstr "" +msgstr "ìž„ì˜ ì½”ë“œ ë¸”ë¡ ì‹¤í–‰" -#: sql_help.c:4573 +#: sql_help.c:4877 msgid "remove an access method" msgstr "ì ‘ê·¼ 방법 ì‚­ì œ" -#: sql_help.c:4578 +#: sql_help.c:4882 msgid "remove an aggregate function" msgstr "집계 함수 ì‚­ì œ" -#: sql_help.c:4583 +#: sql_help.c:4887 msgid "remove a cast" msgstr "í˜•ë³€í™˜ìž ì‚­ì œ" -#: sql_help.c:4588 +#: sql_help.c:4892 msgid "remove a collation" msgstr "collation ì‚­ì œ" -#: sql_help.c:4593 +#: sql_help.c:4897 msgid "remove a conversion" msgstr "문ìžì½”드 변환규칙(conversion) ì‚­ì œ" -#: sql_help.c:4598 +#: sql_help.c:4902 msgid "remove a database" msgstr "ë°ì´í„°ë² ì´ìФ ì‚­ì œ" -#: sql_help.c:4603 +#: sql_help.c:4907 msgid "remove a domain" msgstr "ë„ë©”ì¸ ì‚­ì œ" -#: sql_help.c:4608 +#: sql_help.c:4912 msgid "remove an event trigger" msgstr "ì´ë²¤íЏ 트리거 ì‚­ì œ" -#: sql_help.c:4613 +#: sql_help.c:4917 msgid "remove an extension" msgstr "확장 모듈 ì‚­ì œ" -#: sql_help.c:4618 +#: sql_help.c:4922 msgid "remove a foreign-data wrapper" msgstr "외부 ë°ì´í„° ëž˜í¼ ì œê±°" -#: sql_help.c:4623 +#: sql_help.c:4927 msgid "remove a foreign table" msgstr "외부 í…Œì´ë¸” ì‚­ì œ" -#: sql_help.c:4628 +#: sql_help.c:4932 msgid "remove a function" msgstr "함수 ì‚­ì œ" -#: sql_help.c:4633 sql_help.c:4678 sql_help.c:4748 +#: sql_help.c:4937 sql_help.c:4987 sql_help.c:5067 msgid "remove a database role" msgstr "ë°ì´í„°ë² ì´ìФ 롤 ì‚­ì œ" -#: sql_help.c:4638 +#: sql_help.c:4942 msgid "remove an index" msgstr "ì¸ë±ìФ ì‚­ì œ" -#: sql_help.c:4643 +#: sql_help.c:4947 msgid "remove a procedural language" msgstr "프로시주얼 언어 ì‚­ì œ" -#: sql_help.c:4648 +#: sql_help.c:4952 msgid "remove a materialized view" msgstr "materialized ë·° ì‚­ì œ" -#: sql_help.c:4653 +#: sql_help.c:4957 msgid "remove an operator" msgstr "ì—°ì‚°ìž ì‚­ì œ" -#: sql_help.c:4658 +#: sql_help.c:4962 msgid "remove an operator class" msgstr "ì—°ì‚°ìž í´ëž˜ìФ ì‚­ì œ" -#: sql_help.c:4663 +#: sql_help.c:4967 msgid "remove an operator family" msgstr "ì—°ì‚°ìž ë¶€ë¥˜ ì‚­ì œ" -#: sql_help.c:4668 +#: sql_help.c:4972 msgid "remove database objects owned by a database role" msgstr "ë°ì´í„°ë² ì´ìФ 롤로 ê¶Œí•œì´ ë¶€ì—¬ëœ ë°ì´í„°ë² ì´ìФ ê°œì²´ë“¤ì„ ì‚­ì œí•˜ì„¸ìš”" -#: sql_help.c:4673 +#: sql_help.c:4977 msgid "remove a row level security policy from a table" msgstr "특정 í…Œì´ë¸”ì— ì •ì˜ëœ 로우 단위 보안 ì •ì±… ì‚­ì œ" -#: sql_help.c:4683 +#: sql_help.c:4982 +msgid "remove a publication" +msgstr "발행 ì‚­ì œ" + +#: sql_help.c:4992 msgid "remove a rewrite rule" msgstr "룰(rule) ì‚­ì œ" -#: sql_help.c:4688 +#: sql_help.c:4997 msgid "remove a schema" msgstr "스키마(schema) ì‚­ì œ" -#: sql_help.c:4693 +#: sql_help.c:5002 msgid "remove a sequence" msgstr "시퀀스 ì‚­ì œ" -#: sql_help.c:4698 +#: sql_help.c:5007 msgid "remove a foreign server descriptor" msgstr "외부 서버 ì„¤ëª…ìž ì œê±°" -#: sql_help.c:4703 +#: sql_help.c:5012 +msgid "remove extended statistics" +msgstr "확장 통계정보 ì‚­ì œ" + +#: sql_help.c:5017 +msgid "remove a subscription" +msgstr "êµ¬ë… ì‚­ì œ" + +#: sql_help.c:5022 msgid "remove a table" msgstr "í…Œì´ë¸” ì‚­ì œ" -#: sql_help.c:4708 +#: sql_help.c:5027 msgid "remove a tablespace" msgstr "í…Œì´ë¸”스페ì´ìФ ì‚­ì œ" -#: sql_help.c:4713 +#: sql_help.c:5032 msgid "remove a text search configuration" msgstr "í…스트 검색 구성 제거" -#: sql_help.c:4718 +#: sql_help.c:5037 msgid "remove a text search dictionary" msgstr "í…스트 검색 사전 제거" -#: sql_help.c:4723 +#: sql_help.c:5042 msgid "remove a text search parser" msgstr "í…스트 검색 파서 제거" -#: sql_help.c:4728 +#: sql_help.c:5047 msgid "remove a text search template" msgstr "í…스트 검색 템플릿 제거" -#: sql_help.c:4733 +#: sql_help.c:5052 msgid "remove a transform" msgstr "transform ì‚­ì œ" -#: sql_help.c:4738 +#: sql_help.c:5057 msgid "remove a trigger" msgstr "트리거 ì‚­ì œ" -#: sql_help.c:4743 +#: sql_help.c:5062 msgid "remove a data type" msgstr "ìžë£Œí˜• ì‚­ì œ" -#: sql_help.c:4753 +#: sql_help.c:5072 msgid "remove a user mapping for a foreign server" msgstr "외부 ì„œë²„ì— ëŒ€í•œ ì‚¬ìš©ìž ë§¤í•‘ 제거" -#: sql_help.c:4758 +#: sql_help.c:5077 msgid "remove a view" msgstr "ë·°(view) ì‚­ì œ" -#: sql_help.c:4768 +#: sql_help.c:5087 msgid "execute a prepared statement" msgstr "ì¤€ë¹„ëœ êµ¬ë¬¸(prepared statement) 실행" -#: sql_help.c:4773 +#: sql_help.c:5092 msgid "show the execution plan of a statement" msgstr "쿼리 ì‹¤í–‰ê³„íš ë³´ê¸°" -#: sql_help.c:4778 +#: sql_help.c:5097 msgid "retrieve rows from a query using a cursor" msgstr "해당 커서ì—서 ìžë£Œ 뽑기" -#: sql_help.c:4783 +#: sql_help.c:5102 msgid "define access privileges" msgstr "액세스 권한 지정하기" -#: sql_help.c:4788 +#: sql_help.c:5107 msgid "import table definitions from a foreign server" msgstr "외부 서버로부터 í…Œì´ë¸” ì •ì˜ ê°€ì ¸ì˜¤ê¸°" -#: sql_help.c:4793 +#: sql_help.c:5112 msgid "create new rows in a table" msgstr "í…Œì´ë¸” ìžë£Œ 삽입" -#: sql_help.c:4798 +#: sql_help.c:5117 msgid "listen for a notification" msgstr "특정 서버 메시지 수신함" -#: sql_help.c:4803 +#: sql_help.c:5122 msgid "load a shared library file" msgstr "공유 ë¼ì´ë¸ŒëŸ¬ë¦¬ íŒŒì¼ ë¡œë“œ" -#: sql_help.c:4808 +#: sql_help.c:5127 msgid "lock a table" msgstr "í…Œì´ë¸” 잠금" -#: sql_help.c:4813 +#: sql_help.c:5132 msgid "position a cursor" msgstr "커서 위치 옮기기" -#: sql_help.c:4818 +#: sql_help.c:5137 msgid "generate a notification" msgstr "특정 서버 메시지 ë°œìƒ" -#: sql_help.c:4823 +#: sql_help.c:5142 msgid "prepare a statement for execution" msgstr "ì¤€ë¹„ëœ êµ¬ë¬¸(prepared statement) 만들기" -#: sql_help.c:4828 +#: sql_help.c:5147 msgid "prepare the current transaction for two-phase commit" msgstr "two-phase ì»¤ë°‹ì„ ìœ„í•´ 현재 íŠ¸ëžœìž­ì…˜ì„ ì¤€ë¹„í•¨" -#: sql_help.c:4833 +#: sql_help.c:5152 msgid "change the ownership of database objects owned by a database role" msgstr "ë°ì´í„°ë² ì´ìФ 롤로 ê¶Œí•œì´ ë¶€ì—¬ëœ ë°ì´í„°ë² ì´ìФ ê°œì²´ë“¤ì˜ ì†Œìœ ì£¼ 바꾸기" -#: sql_help.c:4838 +#: sql_help.c:5157 msgid "replace the contents of a materialized view" -msgstr "" +msgstr "êµ¬ì²´í™”ëœ ë·°ì˜ ë‚´ìš© 수정" -#: sql_help.c:4843 +#: sql_help.c:5162 msgid "rebuild indexes" msgstr "ì¸ë±ìФ 다시 만들기" -#: sql_help.c:4848 +#: sql_help.c:5167 msgid "destroy a previously defined savepoint" msgstr "ì´ì „ ì •ì˜ëœ savepoint를 파기함" -#: sql_help.c:4853 +#: sql_help.c:5172 msgid "restore the value of a run-time parameter to the default value" msgstr "실시간 환경 ë³€ìˆ˜ê°’ì„ ì´ˆê¸°ê°’ìœ¼ë¡œ 다시 지정" -#: sql_help.c:4858 +#: sql_help.c:5177 msgid "remove access privileges" msgstr "액세스 권한 해제하기" -#: sql_help.c:4868 +#: sql_help.c:5187 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "two-phase ì»¤ë°‹ì„ ìœ„í•´ 먼저 준비ë˜ì—ˆë˜ 트랜잭션 실행취소하기" -#: sql_help.c:4873 +#: sql_help.c:5192 msgid "roll back to a savepoint" msgstr "savepoint 파기하기" -#: sql_help.c:4878 +#: sql_help.c:5197 msgid "define a new savepoint within the current transaction" msgstr "현재 트랜잭션ì—서 새로운 savepoint 만들기" -#: sql_help.c:4883 +#: sql_help.c:5202 msgid "define or change a security label applied to an object" msgstr "해당 ê°œì²´ì— ë³´ì•ˆ ë¼ë²¨ì„ ì •ì˜í•˜ê±°ë‚˜ 변경" -#: sql_help.c:4888 sql_help.c:4933 sql_help.c:4963 +#: sql_help.c:5207 sql_help.c:5252 sql_help.c:5282 msgid "retrieve rows from a table or view" msgstr "í…Œì´ë¸”ì´ë‚˜ ë·°ì˜ ìžë£Œë¥¼ 출력" -#: sql_help.c:4898 +#: sql_help.c:5217 msgid "change a run-time parameter" msgstr "실시간 환경 변수값 바꾸기" -#: sql_help.c:4903 +#: sql_help.c:5222 msgid "set constraint check timing for the current transaction" msgstr "현재 트랜잭션ì—서 제약조건 설정" -#: sql_help.c:4908 +#: sql_help.c:5227 msgid "set the current user identifier of the current session" msgstr "현재 ì„¸ì…˜ì˜ í˜„ìž¬ ì‚¬ìš©ìž ì‹ë³„ìžë¥¼ 지정" -#: sql_help.c:4913 +#: sql_help.c:5232 msgid "" "set the session user identifier and the current user identifier of the " "current session" msgstr "현재 ì„¸ì…˜ì˜ ì‚¬ìš©ìž ì¸ì¦ì„ 지정함 - ì‚¬ìš©ìž ì§€ì •" -#: sql_help.c:4918 +#: sql_help.c:5237 msgid "set the characteristics of the current transaction" msgstr "현재 íŠ¸ëžœìž­ì…˜ì˜ ì„±ì§ˆì„ ì§€ì •í•¨" -#: sql_help.c:4923 +#: sql_help.c:5242 msgid "show the value of a run-time parameter" msgstr "실시간 환경 ë³€ìˆ˜ê°’ë“¤ì„ ë³´ì—¬ì¤Œ" -#: sql_help.c:4938 +#: sql_help.c:5257 msgid "empty a table or set of tables" msgstr "하나 ë˜ëŠ” 지정한 ì—¬ëŸ¬ê°œì˜ í…Œì´ë¸”ì—서 모든 ìžë£Œ 지움" -#: sql_help.c:4943 +#: sql_help.c:5262 msgid "stop listening for a notification" msgstr "특정 서버 메시지 수신 기능 ë”" -#: sql_help.c:4948 +#: sql_help.c:5267 msgid "update rows of a table" msgstr "í…Œì´ë¸” ìžë£Œ 갱신" -#: sql_help.c:4953 +#: sql_help.c:5272 msgid "garbage-collect and optionally analyze a database" msgstr "물리ì ì¸ ìžë£Œ 정리 작업 - 쓰레기값 청소" -#: sql_help.c:4958 +#: sql_help.c:5277 msgid "compute a set of rows" msgstr "compute a set of rows" -#: startup.c:189 +#: startup.c:187 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s: -1 ì˜µì…˜ì€ ë¹„ëŒ€í™”í˜• 모드ì—서만 사용할 수 있ìŒ\n" -#: startup.c:289 +#: startup.c:290 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: \"%s\" 로그 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: startup.c:389 +#: startup.c:397 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5399,21 +5802,11 @@ msgstr "" "ë„움ë§ì„ 보려면 \"help\"를 입력하십시오.\n" "\n" -#: startup.c:538 +#: startup.c:546 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s: 출력 매개 변수 \"%s\" 지정할 수 ì—†ìŒ\n" -#: startup.c:578 -#, c-format -msgid "%s: could not delete variable \"%s\"\n" -msgstr "%s: \"%s\" 변수를 지울 수 ì—†ìŒ\n" - -#: startup.c:588 -#, c-format -msgid "%s: could not set variable \"%s\"\n" -msgstr "%s: \"%s\" 변수를 지정할 수 ì—†ìŒ\n" - #: startup.c:648 #, c-format msgid "Try \"%s --help\" for more information.\n" @@ -5429,13 +5822,7 @@ msgstr "%s: 경고: 추가 명령행 ì¸ìˆ˜ \"%s\" 무시ë¨\n" msgid "%s: could not find own program executable\n" msgstr "%s: 실행 가능한 í”„ë¡œê·¸ëž¨ì„ ì°¾ì„ ìˆ˜ 없습니다\n" -#: startup.c:836 startup.c:883 startup.c:904 startup.c:941 startup.c:963 -#: variables.c:121 -#, c-format -msgid "unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n" -msgstr "\"%s\" ê°’ì€ \"%s\" 변수값으로 사용할 수 ì—†ìŒ; \"%s\" ê°’ì„ ì‚¬ìš©í•¨\n" - -#: tab-complete.c:3704 +#: tab-complete.c:4186 #, c-format msgid "" "tab completion query failed: %s\n" @@ -5445,3 +5832,30 @@ msgstr "" "탭 ìžë™ì™„성용 쿼리 실패: %s\n" "사용한 쿼리:\n" "%s\n" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "ìž˜ëª»ëœ \"%s\" ê°’ì„ \"%s\" 변수값으로 사용함: 불린형ì´ì–´ì•¼ 함\n" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected\n" +msgstr "\"%s\" ê°’ì€ \"%s\" 변수값으로 사용할 수 ì—†ìŒ; 정수형ì´ì–´ì•¼ 함\n" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"\n" +msgstr "ìž˜ëª»ëœ ë³€ìˆ˜ ì´ë¦„: %s\n" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s.\n" +msgstr "" +"\"%s\" ê°’ì€ \"%s\" 변수값으로 사용할 수 ì—†ìŒ\n" +"사용할 수 있는 변수값: %s\n" + +#~ msgid "statistic_type" +#~ msgstr "통계정보_종류" diff --git a/src/bin/psql/po/ru.po b/src/bin/psql/po/ru.po index 5a9a8d7a955..6ae0cd740f9 100644 --- a/src/bin/psql/po/ru.po +++ b/src/bin/psql/po/ru.po @@ -4,14 +4,14 @@ # Serguei A. Mokhov , 2001-2005. # Oleg Bartunov , 2004-2005. # Sergey Burladyan , 2012. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: psql (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-02 23:45+0000\n" -"PO-Revision-Date: 2017-04-03 10:54+0300\n" +"POT-Creation-Date: 2019-02-08 11:42+0300\n" +"PO-Revision-Date: 2018-10-05 21:27+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -19,7 +19,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" #: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 #, c-format @@ -57,8 +56,7 @@ msgid "pclose failed: %s" msgstr "ошибка pclose: %s" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:612 input.c:227 mainloop.c:82 -#: mainloop.c:276 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 #, c-format msgid "out of memory\n" msgstr "нехватка памÑти\n" @@ -73,7 +71,7 @@ msgstr "попытка Ð´ÑƒÐ±Ð»Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½ÑƒÐ»ÐµÐ²Ð¾Ð³Ð¾ указате msgid "could not look up effective user ID %ld: %s" msgstr "выÑÑнить Ñффективный идентификатор Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (%ld) не удалоÑÑŒ: %s" -#: ../../common/username.c:45 command.c:559 +#: ../../common/username.c:45 command.c:554 msgid "user does not exist" msgstr "пользователь не ÑущеÑтвует" @@ -125,49 +123,49 @@ msgstr[0] "(%lu Ñтрока)" msgstr[1] "(%lu Ñтроки)" msgstr[2] "(%lu Ñтрок)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:2939 #, c-format msgid "Interrupted\n" msgstr "Прервано\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3003 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "" "Ошибка Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° таблицы: превышен предел чиÑла Ñтолбцов (%d).\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3043 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "" "Ошибка Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñчейки в таблицу: превышен предел чиÑла Ñчеек (%d).\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3292 #, c-format msgid "invalid output format (internal error): %d" msgstr "неверный формат вывода (внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°): %d" -#: ../../fe_utils/psqlscan.l:713 +#: ../../fe_utils/psqlscan.l:725 #, c-format msgid "skipping recursive expansion of variable \"%s\"\n" msgstr "рекурÑивное раÑширение переменной \"%s\" пропуÑкаетÑÑ\n" -#: command.c:227 +#: command.c:220 #, c-format msgid "Invalid command \\%s. Try \\? for help.\n" msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° \\%s. Справка по командам: \\?\n" -#: command.c:229 +#: command.c:222 #, c-format msgid "invalid command \\%s\n" msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° \\%s\n" -#: command.c:247 +#: command.c:240 #, c-format msgid "\\%s: extra argument \"%s\" ignored\n" msgstr "\\%s: лишний аргумент \"%s\" пропущен\n" -#: command.c:299 +#: command.c:292 #, c-format msgid "" "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" @@ -175,22 +173,22 @@ msgstr "" "команда \\%s игнорируетÑÑ; добавьте \\endif или нажмите Ctrl-C Ð´Ð»Ñ " "Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ блока \\if\n" -#: command.c:557 +#: command.c:552 #, c-format msgid "could not get home directory for user ID %ld: %s\n" msgstr "не удалоÑÑŒ получить домашний каталог Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ c ид. %ld: %s\n" -#: command.c:575 +#: command.c:570 #, c-format msgid "\\%s: could not change directory to \"%s\": %s\n" msgstr "\\%s: не удалоÑÑŒ перейти в каталог \"%s\": %s\n" -#: command.c:600 common.c:648 common.c:706 common.c:1242 +#: command.c:595 common.c:696 common.c:754 common.c:1337 #, c-format msgid "You are currently not connected to a database.\n" msgstr "Ð’ данный момент вы не подключены к базе данных.\n" -#: command.c:625 +#: command.c:602 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " @@ -199,7 +197,7 @@ msgstr "" "Ð’Ñ‹ подключены к базе данных \"%s\" как пользователь \"%s\" через Ñокет в \"%s" "\", порт \"%s\".\n" -#: command.c:628 +#: command.c:605 #, c-format msgid "" "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " @@ -208,174 +206,170 @@ msgstr "" "Ð’Ñ‹ подключены к базе данных \"%s\" как пользователь \"%s\" (Ñервер \"%s\", " "порт \"%s\").\n" -#: command.c:916 command.c:1006 command.c:1115 command.c:2524 +#: command.c:895 command.c:991 command.c:2376 #, c-format msgid "no query buffer\n" msgstr "нет буфера запроÑов\n" -#: command.c:949 command.c:4761 +#: command.c:928 command.c:4648 #, c-format msgid "invalid line number: %s\n" msgstr "неверный номер Ñтроки: %s\n" -#: command.c:999 +#: command.c:982 #, c-format msgid "The server (version %s) does not support editing function source.\n" msgstr "" "Сервер (верÑÐ¸Ñ %s) не поддерживает редактирование иÑходного кода функции.\n" -#: command.c:1074 command.c:1155 -msgid "No changes" -msgstr "Изменений нет" - -#: command.c:1108 +#: command.c:985 #, c-format msgid "The server (version %s) does not support editing view definitions.\n" msgstr "" "Сервер (верÑÐ¸Ñ %s) не поддерживает редактирование Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ " "предÑтавлениÑ.\n" -#: command.c:1232 +#: command.c:1067 +msgid "No changes" +msgstr "Изменений нет" + +#: command.c:1144 #, c-format msgid "%s: invalid encoding name or conversion procedure not found\n" msgstr "" "%s: неверное название кодировки Ñимволов или не найдена процедура " "перекодировки\n" -#: command.c:1267 command.c:3165 command.c:4863 common.c:173 common.c:244 -#: common.c:541 common.c:1288 common.c:1316 common.c:1417 copy.c:489 copy.c:699 -#: large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1383 common.c:1411 common.c:1519 +#: common.c:1622 common.c:1660 copy.c:492 copy.c:711 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 #, c-format msgid "%s" msgstr "%s" -#: command.c:1271 +#: command.c:1183 msgid "out of memory" msgstr "нехватка памÑти" -#: command.c:1274 +#: command.c:1186 msgid "There is no previous error." msgstr "Ошибки не было." -#: command.c:1445 command.c:1750 command.c:1764 command.c:1781 command.c:1941 -#: command.c:2178 command.c:2491 command.c:2531 +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 #, c-format msgid "\\%s: missing required argument\n" msgstr "отÑутÑтвует необходимый аргумент \\%s\n" -#: command.c:1576 +#: command.c:1505 #, c-format msgid "\\elif: cannot occur after \\else\n" msgstr "\\elif не может находитьÑÑ Ð¿Ð¾Ñле \\else\n" -#: command.c:1581 +#: command.c:1510 #, c-format msgid "\\elif: no matching \\if\n" msgstr "\\elif без ÑоответÑтвующего \\if\n" -#: command.c:1645 +#: command.c:1574 #, c-format msgid "\\else: cannot occur after \\else\n" msgstr "\\else не может находитьÑÑ Ð¿Ð¾Ñле \\else\n" -#: command.c:1650 +#: command.c:1579 #, c-format msgid "\\else: no matching \\if\n" msgstr "\\else без ÑоответÑтвующего \\if\n" -#: command.c:1690 +#: command.c:1619 #, c-format msgid "\\endif: no matching \\if\n" msgstr "\\endif без ÑоответÑтвующего \\if\n" -#: command.c:1845 +#: command.c:1774 msgid "Query buffer is empty." msgstr "Буфер запроÑа пуÑÑ‚." -#: command.c:1867 +#: command.c:1796 msgid "Enter new password: " msgstr "Введите новый пароль: " -#: command.c:1868 +#: command.c:1797 msgid "Enter it again: " msgstr "Повторите его: " -#: command.c:1872 +#: command.c:1801 #, c-format msgid "Passwords didn't match.\n" msgstr "Пароли не Ñовпадают.\n" -#: command.c:1889 -#, c-format -msgid "Password encryption failed.\n" -msgstr "Ошибка при шифровании паролÑ.\n" - -#: command.c:1971 +#: command.c:1900 #, c-format msgid "\\%s: could not read value for variable\n" msgstr "\\%s: не удалоÑÑŒ прочитать значение переменной\n" -#: command.c:2074 +#: command.c:2003 msgid "Query buffer reset (cleared)." msgstr "Буфер запроÑа Ñброшен (очищен)." -#: command.c:2096 +#: command.c:2025 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð·Ð°Ð¿Ð¸Ñана в файл \"%s\".\n" -#: command.c:2183 +#: command.c:2112 #, c-format msgid "\\%s: environment variable name must not contain \"=\"\n" msgstr "\\%s: Ð¸Ð¼Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð¾Ð¹ Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ Ð½Ðµ может Ñодержать знак \"=\"\n" -#: command.c:2239 +#: command.c:2173 #, c-format msgid "The server (version %s) does not support showing function source.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает вывод иÑходного кода функции.\n" -#: command.c:2246 -#, c-format -msgid "function name is required\n" -msgstr "требуетÑÑ Ð¸Ð¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸\n" - -#: command.c:2333 +#: command.c:2176 #, c-format msgid "The server (version %s) does not support showing view definitions.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает вывод Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ñтавлений.\n" -#: command.c:2340 +#: command.c:2183 +#, c-format +msgid "function name is required\n" +msgstr "требуетÑÑ Ð¸Ð¼Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸\n" + +#: command.c:2185 #, c-format msgid "view name is required\n" msgstr "требуетÑÑ Ð¸Ð¼Ñ Ð¿Ñ€ÐµÐ´ÑтавлениÑ\n" -#: command.c:2463 +#: command.c:2315 msgid "Timing is on." msgstr "Секундомер включён." -#: command.c:2465 +#: command.c:2317 msgid "Timing is off." msgstr "Секундомер выключен." -#: command.c:2550 command.c:2578 command.c:3514 command.c:3517 command.c:3520 -#: command.c:3526 command.c:3528 command.c:3536 command.c:3546 command.c:3555 -#: command.c:3569 command.c:3586 command.c:3644 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:760 psqlscanslash.l:771 -#: psqlscanslash.l:781 +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" -#: command.c:2957 startup.c:202 +#: command.c:2814 startup.c:214 startup.c:265 msgid "Password: " msgstr "Пароль: " -#: command.c:2962 startup.c:204 +#: command.c:2819 startup.c:262 #, c-format msgid "Password for user %s: " msgstr "Пароль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ %s: " -#: command.c:3012 +#: command.c:2869 #, c-format msgid "" "All connection parameters must be supplied because no database connection " @@ -384,17 +378,17 @@ msgstr "" "Без Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº базе данных необходимо указывать вÑе параметры " "подключениÑ\n" -#: command.c:3169 +#: command.c:3037 #, c-format msgid "Previous connection kept\n" msgstr "Сохранено предыдущее подключение\n" -#: command.c:3173 +#: command.c:3041 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:3209 +#: command.c:3077 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " @@ -403,7 +397,7 @@ msgstr "" "Ð’Ñ‹ подключены к базе данных \"%s\" как пользователь \"%s\" через Ñокет в \"%s" "\", порт \"%s\".\n" -#: command.c:3212 +#: command.c:3080 #, c-format msgid "" "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " @@ -412,17 +406,17 @@ msgstr "" "Ð’Ñ‹ подключены к базе данных \"%s\" как пользователь \"%s\" (Ñервер \"%s\", " "порт \"%s\") .\n" -#: command.c:3216 +#: command.c:3084 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Ð’Ñ‹ подключены к базе данных \"%s\" как пользователь \"%s\".\n" -#: command.c:3249 +#: command.c:3117 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, Ñервер %s)\n" -#: command.c:3257 +#: command.c:3125 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -431,24 +425,24 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: %s имеет базовую верÑию %s, а Ñервер - %s.\n" " ЧаÑть функций psql может не работать.\n" -#: command.c:3294 +#: command.c:3162 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "SSL-Ñоединение (протокол: %s, шифр: %s, бит: %s, Ñжатие: %s)\n" -#: command.c:3295 command.c:3296 command.c:3297 +#: command.c:3163 command.c:3164 command.c:3165 msgid "unknown" msgstr "неизвеÑтно" -#: command.c:3298 help.c:45 +#: command.c:3166 help.c:45 msgid "off" msgstr "выкл." -#: command.c:3298 help.c:45 +#: command.c:3166 help.c:45 msgid "on" msgstr "вкл." -#: command.c:3318 +#: command.c:3186 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -461,7 +455,7 @@ msgstr "" " Подробнее об Ñтом Ñмотрите документацию psql, раздел\n" " \"Notes for Windows users\".\n" -#: command.c:3403 +#: command.c:3290 #, c-format msgid "" "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " @@ -470,27 +464,27 @@ msgstr "" "в переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ PSQL_EDITOR_LINENUMBER_ARG должен быть указан номер " "Ñтроки\n" -#: command.c:3432 +#: command.c:3319 #, c-format msgid "could not start editor \"%s\"\n" msgstr "не удалоÑÑŒ запуÑтить редактор \"%s\"\n" -#: command.c:3434 +#: command.c:3321 #, c-format msgid "could not start /bin/sh\n" msgstr "не удалоÑÑŒ запуÑтить /bin/sh\n" -#: command.c:3472 +#: command.c:3359 #, c-format msgid "could not locate temporary directory: %s\n" msgstr "не удалоÑÑŒ найти временный каталог: %s\n" -#: command.c:3499 +#: command.c:3386 #, c-format msgid "could not open temporary file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть временный файл \"%s\": %s\n" -#: command.c:3773 +#: command.c:3660 #, c-format msgid "" "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, " @@ -499,122 +493,122 @@ msgstr "" "допуÑтимые форматы \\pset: unaligned, aligned, wrapped, html, asciidoc, " "latex, latex-longtable, troff-ms\n" -#: command.c:3791 +#: command.c:3678 #, c-format msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" msgstr "допуÑтимые Ñтили линий Ð´Ð»Ñ \\pset: ascii, old-ascii, unicode\n" -#: command.c:3806 +#: command.c:3693 #, c-format msgid "\\pset: allowed Unicode border line styles are single, double\n" msgstr "допуÑтимые Ñтили Unicode-линий границ Ð´Ð»Ñ \\pset: single, double\n" -#: command.c:3821 +#: command.c:3708 #, c-format msgid "\\pset: allowed Unicode column line styles are single, double\n" msgstr "допуÑтимые Ñтили Unicode-линий Ñтолбцов Ð´Ð»Ñ \\pset: single, double\n" -#: command.c:3836 +#: command.c:3723 #, c-format msgid "\\pset: allowed Unicode header line styles are single, double\n" msgstr "допуÑтимые Ñтили Unicode-линий заголовков Ð´Ð»Ñ \\pset: single, double\n" -#: command.c:4001 command.c:4180 +#: command.c:3888 command.c:4067 #, c-format msgid "\\pset: unknown option: %s\n" msgstr "неизвеÑтный параметр \\pset: %s\n" -#: command.c:4019 +#: command.c:3906 #, c-format msgid "Border style is %d.\n" msgstr "Стиль границ: %d.\n" -#: command.c:4025 +#: command.c:3912 #, c-format msgid "Target width is unset.\n" msgstr "Ширина вывода Ñброшена.\n" -#: command.c:4027 +#: command.c:3914 #, c-format msgid "Target width is %d.\n" msgstr "Ширина вывода: %d.\n" -#: command.c:4034 +#: command.c:3921 #, c-format msgid "Expanded display is on.\n" msgstr "РаÑширенный вывод включён.\n" -#: command.c:4036 +#: command.c:3923 #, c-format msgid "Expanded display is used automatically.\n" msgstr "РаÑширенный вывод применÑетÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки.\n" -#: command.c:4038 +#: command.c:3925 #, c-format msgid "Expanded display is off.\n" msgstr "РаÑширенный вывод выключен.\n" -#: command.c:4045 command.c:4053 +#: command.c:3932 command.c:3940 #, c-format msgid "Field separator is zero byte.\n" msgstr "Разделитель полей - нулевой байт.\n" -#: command.c:4047 +#: command.c:3934 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Разделитель полей: \"%s\".\n" -#: command.c:4060 +#: command.c:3947 #, c-format msgid "Default footer is on.\n" msgstr "Строка итогов включена.\n" -#: command.c:4062 +#: command.c:3949 #, c-format msgid "Default footer is off.\n" msgstr "Строка итогов выключена.\n" -#: command.c:4068 +#: command.c:3955 #, c-format msgid "Output format is %s.\n" msgstr "Формат вывода: %s.\n" -#: command.c:4074 +#: command.c:3961 #, c-format msgid "Line style is %s.\n" msgstr "УÑтановлен Ñтиль линий: %s.\n" -#: command.c:4081 +#: command.c:3968 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null выводитÑÑ ÐºÐ°Ðº: \"%s\".\n" -#: command.c:4089 +#: command.c:3976 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "Локализованный вывод чиÑел включён.\n" -#: command.c:4091 +#: command.c:3978 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "Локализованный вывод чиÑел выключен.\n" -#: command.c:4098 +#: command.c:3985 #, c-format msgid "Pager is used for long output.\n" msgstr "ПоÑтраничник иÑпользуетÑÑ Ð´Ð»Ñ Ð²Ñ‹Ð²Ð¾Ð´Ð° длинного текÑта.\n" -#: command.c:4100 +#: command.c:3987 #, c-format msgid "Pager is always used.\n" msgstr "ПоÑтраничник иÑпользуетÑÑ Ð²Ñегда.\n" -#: command.c:4102 +#: command.c:3989 #, c-format msgid "Pager usage is off.\n" msgstr "ПоÑтраничник выключен.\n" -#: command.c:4108 +#: command.c:3995 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" @@ -622,87 +616,87 @@ msgstr[0] "ПоÑтраничник не будет иÑпользоватьÑÑ msgstr[1] "ПоÑтраничник не будет иÑпользоватьÑÑ, еÑли Ñтрок меньше %d\n" msgstr[2] "ПоÑтраничник не будет иÑпользоватьÑÑ, еÑли Ñтрок меньше %d\n" -#: command.c:4118 command.c:4128 +#: command.c:4005 command.c:4015 #, c-format msgid "Record separator is zero byte.\n" msgstr "Разделитель запиÑей - нулевой байт.\n" -#: command.c:4120 +#: command.c:4007 #, c-format msgid "Record separator is .\n" msgstr "Разделитель запиÑей: <Ð½Ð¾Ð²Ð°Ñ Ñтрока>.\n" -#: command.c:4122 +#: command.c:4009 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Разделитель запиÑей: \"%s\".\n" -#: command.c:4135 +#: command.c:4022 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Ðтрибуты HTML-таблицы: \"%s\".\n" -#: command.c:4138 +#: command.c:4025 #, c-format msgid "Table attributes unset.\n" msgstr "Ðтрибуты HTML-таблицы не заданы.\n" -#: command.c:4145 +#: command.c:4032 #, c-format msgid "Title is \"%s\".\n" msgstr "Заголовок: \"%s\".\n" -#: command.c:4147 +#: command.c:4034 #, c-format msgid "Title is unset.\n" msgstr "Заголовок не задан.\n" -#: command.c:4154 +#: command.c:4041 #, c-format msgid "Tuples only is on.\n" msgstr "Режим вывода только кортежей включён.\n" -#: command.c:4156 +#: command.c:4043 #, c-format msgid "Tuples only is off.\n" msgstr "Режим вывода только кортежей выключен.\n" -#: command.c:4162 +#: command.c:4049 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Стиль Unicode-линий границ: \"%s\".\n" -#: command.c:4168 +#: command.c:4055 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Стиль Unicode-линий Ñтолбцов: \"%s\".\n" -#: command.c:4174 +#: command.c:4061 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Стиль Unicode-линий границ: \"%s\".\n" -#: command.c:4334 +#: command.c:4221 #, c-format msgid "\\!: failed\n" msgstr "\\!: ошибка\n" -#: command.c:4359 common.c:754 +#: command.c:4246 common.c:802 #, c-format msgid "\\watch cannot be used with an empty query\n" msgstr "\\watch Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ Ð¿ÑƒÑтым запроÑом\n" -#: command.c:4400 +#: command.c:4287 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (обновление: %g Ñ)\n" -#: command.c:4403 +#: command.c:4290 #, c-format msgid "%s (every %gs)\n" msgstr "%s (обновление: %g Ñ)\n" -#: command.c:4457 command.c:4464 common.c:654 common.c:661 common.c:1271 +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1366 #, c-format msgid "" "********* QUERY **********\n" @@ -715,84 +709,84 @@ msgstr "" "**************************\n" "\n" -#: command.c:4656 +#: command.c:4543 #, c-format msgid "\"%s.%s\" is not a view\n" msgstr "\"%s.%s\" - не предÑтавление\n" -#: command.c:4672 +#: command.c:4559 #, c-format msgid "could not parse reloptions array\n" msgstr "не удалоÑÑŒ разобрать маÑÑив reloptions\n" -#: common.c:158 +#: common.c:159 #, c-format msgid "cannot escape without active connection\n" msgstr "Ñкранирование Ñтрок не работает без Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº БД\n" -#: common.c:199 +#: common.c:200 #, c-format msgid "shell command argument contains a newline or carriage return: \"%s\"\n" msgstr "" "аргумент команды оболочки Ñодержит Ñимвол новой Ñтроки или перевода каретки: " "\"%s\"\n" -#: common.c:415 +#: common.c:416 #, c-format msgid "connection to server was lost\n" msgstr "подключение к Ñерверу было потерÑно\n" -#: common.c:419 +#: common.c:420 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Подключение к Ñерверу потерÑно. Попытка воÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ " -#: common.c:424 +#: common.c:425 #, c-format msgid "Failed.\n" msgstr "неудачна.\n" -#: common.c:431 +#: common.c:432 #, c-format msgid "Succeeded.\n" msgstr "удачна.\n" -#: common.c:531 common.c:1034 common.c:1206 +#: common.c:532 common.c:1084 common.c:1301 #, c-format msgid "unexpected PQresultStatus: %d\n" msgstr "неожиданное значение PQresultStatus: %d\n" -#: common.c:593 +#: common.c:641 #, c-format msgid "Time: %.3f ms\n" msgstr "ВремÑ: %.3f мÑ\n" -#: common.c:608 +#: common.c:656 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "ВремÑ: %.3f Ð¼Ñ (%02d:%06.3f)\n" -#: common.c:617 +#: common.c:665 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "ВремÑ: %.3f Ð¼Ñ (%02d:%02d:%06.3f)\n" -#: common.c:624 +#: common.c:672 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "ВремÑ: %.3f Ð¼Ñ (%.0f д. %02d:%02d:%06.3f)\n" -#: common.c:761 +#: common.c:809 #, c-format msgid "\\watch cannot be used with COPY\n" msgstr "\\watch Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать Ñ COPY\n" -#: common.c:766 +#: common.c:814 #, c-format msgid "unexpected result status for \\watch\n" msgstr "неожиданное ÑоÑтоÑние результата Ð´Ð»Ñ \\watch\n" -#: common.c:795 +#: common.c:844 #, c-format msgid "" "Asynchronous notification \"%s\" with payload \"%s\" received from server " @@ -801,24 +795,24 @@ msgstr "" "Получено аÑинхронное уведомление \"%s\" Ñ Ñообщением-нагрузкой \"%s\" от " "Ñерверного процеÑÑа Ñ PID %d.\n" -#: common.c:798 +#: common.c:847 #, c-format msgid "" "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "" "Получено аÑинхронное уведомление \"%s\" от Ñерверного процеÑÑа Ñ PID %d.\n" -#: common.c:860 +#: common.c:910 #, c-format msgid "no rows returned for \\gset\n" msgstr "Ñервер не возвратил Ñтрок Ð´Ð»Ñ \\gset\n" -#: common.c:865 +#: common.c:915 #, c-format msgid "more than one row returned for \\gset\n" msgstr "Ñервер возвратил больше одной Ñтроки Ð´Ð»Ñ \\gset\n" -#: common.c:1251 +#: common.c:1346 #, c-format msgid "" "***(Single step mode: verify " @@ -832,23 +826,39 @@ msgstr "" "%s\n" "***(Enter - выполнение; x и Enter - отмена)**************\n" -#: common.c:1306 +#: common.c:1401 #, c-format msgid "" "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" msgstr "" "Сервер (верÑÐ¸Ñ %s) не поддерживает точки ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ON_ERROR_ROLLBACK.\n" -#: common.c:1362 +#: common.c:1464 #, c-format msgid "STATEMENT: %s\n" msgstr "ОПЕРÐТОР: %s\n" -#: common.c:1405 +#: common.c:1507 #, c-format msgid "unexpected transaction status (%d)\n" msgstr "неожиданное ÑоÑтоÑние транзакции (%d)\n" +#: common.c:1644 describe.c:1941 +msgid "Column" +msgstr "Столбец" + +#: common.c:1645 describe.c:175 describe.c:390 describe.c:408 describe.c:453 +#: describe.c:470 describe.c:959 describe.c:1123 describe.c:1664 +#: describe.c:1688 describe.c:1942 describe.c:3529 describe.c:3734 +#: describe.c:4925 +msgid "Type" +msgstr "Тип" + +#: common.c:1694 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Команда не выдала результат, либо в результате нет Ñтолбцов.\n" + #: copy.c:99 #, c-format msgid "\\copy: arguments required\n" @@ -884,33 +894,33 @@ msgstr "COPY FROM/TO не может работать Ñ ÐºÐ°Ñ‚Ð°Ð»Ð¾Ð³Ð¾Ð¼ (%s) msgid "could not close pipe to external command: %s\n" msgstr "не удалоÑÑŒ закрыть канал Ñообщений Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ¹ командой: %s\n" -#: copy.c:452 copy.c:463 +#: copy.c:455 copy.c:466 #, c-format msgid "could not write COPY data: %s\n" msgstr "не удалоÑÑŒ запиÑать данные COPY: %s\n" -#: copy.c:470 +#: copy.c:473 #, c-format msgid "COPY data transfer failed: %s" msgstr "ошибка передачи данных COPY: %s" -#: copy.c:531 +#: copy.c:534 msgid "canceled by user" msgstr "отменено пользователем" -#: copy.c:542 +#: copy.c:545 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" "Вводите данные Ð´Ð»Ñ ÐºÐ¾Ð¿Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ, разделÑÑ Ñтроки переводом Ñтроки.\n" -"Закончите ввод Ñтрокой '\\.'." +"Закончите ввод Ñтрокой '\\.' или Ñигналом EOF." -#: copy.c:671 +#: copy.c:673 msgid "aborted because of read failure" msgstr "прерывание из-за ошибки чтениÑ" -#: copy.c:695 +#: copy.c:707 msgid "trying to exit copy mode" msgstr "попытка выйти из режима копированиÑ" @@ -970,663 +980,728 @@ msgstr "\\crosstabview: неоднозначное Ð¸Ð¼Ñ Ñтолбца: \"%s\" msgid "\\crosstabview: column name not found: \"%s\"\n" msgstr "\\crosstabview: Ð¸Ð¼Ñ Ñтолбца не найдено: \"%s\"\n" -#: describe.c:72 describe.c:341 describe.c:598 describe.c:729 describe.c:873 -#: describe.c:1034 describe.c:1106 describe.c:3268 describe.c:3474 -#: describe.c:3565 describe.c:3813 describe.c:3958 describe.c:4190 -#: describe.c:4265 describe.c:4276 describe.c:4338 describe.c:4758 -#: describe.c:4841 +#: describe.c:75 describe.c:370 describe.c:675 describe.c:807 describe.c:951 +#: describe.c:1112 describe.c:1184 describe.c:3518 describe.c:3732 +#: describe.c:3823 describe.c:4090 describe.c:4235 describe.c:4476 +#: describe.c:4551 describe.c:4562 describe.c:4624 describe.c:5049 +#: describe.c:5132 msgid "Schema" msgstr "Схема" -#: describe.c:73 describe.c:161 describe.c:227 describe.c:235 describe.c:342 -#: describe.c:599 describe.c:730 describe.c:791 describe.c:874 describe.c:1107 -#: describe.c:3269 describe.c:3397 describe.c:3475 describe.c:3566 -#: describe.c:3645 describe.c:3814 describe.c:3883 describe.c:3959 -#: describe.c:4191 describe.c:4266 describe.c:4277 describe.c:4339 -#: describe.c:4531 describe.c:4615 describe.c:4839 describe.c:5006 -#: describe.c:5194 +#: describe.c:76 describe.c:173 describe.c:240 describe.c:248 describe.c:371 +#: describe.c:676 describe.c:808 describe.c:869 describe.c:952 describe.c:1185 +#: describe.c:3519 describe.c:3655 describe.c:3733 describe.c:3824 +#: describe.c:3903 describe.c:4091 describe.c:4160 describe.c:4236 +#: describe.c:4477 describe.c:4552 describe.c:4563 describe.c:4625 +#: describe.c:4822 describe.c:4906 describe.c:5130 describe.c:5302 +#: describe.c:5527 msgid "Name" msgstr "ИмÑ" -#: describe.c:74 describe.c:354 describe.c:400 describe.c:417 +#: describe.c:77 describe.c:383 describe.c:401 describe.c:447 describe.c:464 msgid "Result data type" msgstr "Тип данных результата" -#: describe.c:82 describe.c:95 describe.c:99 describe.c:355 describe.c:401 -#: describe.c:418 +#: describe.c:85 describe.c:98 describe.c:102 describe.c:384 describe.c:402 +#: describe.c:448 describe.c:465 msgid "Argument data types" msgstr "Типы данных аргументов" -#: describe.c:106 describe.c:171 describe.c:258 describe.c:463 describe.c:647 -#: describe.c:745 describe.c:816 describe.c:1109 describe.c:1741 -#: describe.c:3068 describe.c:3303 describe.c:3428 describe.c:3502 -#: describe.c:3575 describe.c:3658 describe.c:3726 describe.c:3826 -#: describe.c:3892 describe.c:3960 describe.c:4096 describe.c:4136 -#: describe.c:4207 describe.c:4269 describe.c:4278 describe.c:4340 -#: describe.c:4557 describe.c:4637 describe.c:4772 describe.c:4842 +#: describe.c:110 describe.c:117 describe.c:183 describe.c:271 describe.c:510 +#: describe.c:724 describe.c:823 describe.c:894 describe.c:1187 describe.c:1960 +#: describe.c:3307 describe.c:3554 describe.c:3686 describe.c:3760 +#: describe.c:3833 describe.c:3916 describe.c:3999 describe.c:4103 +#: describe.c:4169 describe.c:4237 describe.c:4378 describe.c:4420 +#: describe.c:4493 describe.c:4555 describe.c:4564 describe.c:4626 +#: describe.c:4848 describe.c:4928 describe.c:5063 describe.c:5133 #: large_obj.c:289 large_obj.c:299 msgid "Description" msgstr "ОпиÑание" -#: describe.c:124 +#: describe.c:135 msgid "List of aggregate functions" msgstr "СпиÑок агрегатных функций" -#: describe.c:148 +#: describe.c:160 #, c-format msgid "The server (version %s) does not support access methods.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает методы доÑтупа.\n" -#: describe.c:162 +#: describe.c:174 msgid "Index" msgstr "ИндекÑ" -#: describe.c:163 describe.c:361 describe.c:406 describe.c:423 describe.c:881 -#: describe.c:1045 describe.c:1701 describe.c:3278 describe.c:3476 -#: describe.c:4634 -msgid "Type" -msgstr "Тип" - -#: describe.c:170 describe.c:4536 +#: describe.c:182 describe.c:4827 msgid "Handler" msgstr "Обработчик" -#: describe.c:189 +#: describe.c:201 msgid "List of access methods" msgstr "СпиÑок методов доÑтупа" -#: describe.c:214 +#: describe.c:227 #, c-format msgid "The server (version %s) does not support tablespaces.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает табличные проÑтранÑтва.\n" -#: describe.c:228 describe.c:236 describe.c:451 describe.c:637 describe.c:792 -#: describe.c:1033 describe.c:3279 describe.c:3401 describe.c:3647 -#: describe.c:3884 describe.c:4532 describe.c:4616 describe.c:5007 -#: describe.c:5195 large_obj.c:288 +#: describe.c:241 describe.c:249 describe.c:498 describe.c:714 describe.c:870 +#: describe.c:1111 describe.c:3530 describe.c:3659 describe.c:3905 +#: describe.c:4161 describe.c:4823 describe.c:4907 describe.c:5303 +#: describe.c:5429 describe.c:5528 large_obj.c:288 msgid "Owner" msgstr "Владелец" -#: describe.c:229 describe.c:237 +#: describe.c:242 describe.c:250 msgid "Location" msgstr "РаÑположение" -#: describe.c:248 describe.c:2883 +#: describe.c:261 describe.c:3126 msgid "Options" msgstr "Параметры" -#: describe.c:253 describe.c:610 describe.c:808 describe.c:3295 describe.c:3299 +#: describe.c:266 describe.c:687 describe.c:886 describe.c:3546 describe.c:3550 msgid "Size" msgstr "Размер" -#: describe.c:275 +#: describe.c:288 msgid "List of tablespaces" msgstr "СпиÑок табличных проÑтранÑтв" -#: describe.c:315 +#: describe.c:330 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df принимает в качеÑтве параметров только [antwS+]\n" +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df принимает в качеÑтве параметров только [anptwS+]\n" -#: describe.c:323 +#: describe.c:338 describe.c:349 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df не поддерживает параметр \"w\" Ñ Ñервером верÑии %s\n" +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "\\df не поддерживает параметр \"%c\" Ñ Ñервером верÑии %s\n" # well-spelled: агр #. translator: "agg" is short for "aggregate" -#: describe.c:357 describe.c:403 describe.c:420 +#: describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "agg" msgstr "агр." -#: describe.c:358 +#: describe.c:387 describe.c:405 msgid "window" msgstr "оконнаÑ" -#: describe.c:359 describe.c:404 describe.c:421 describe.c:1243 +#: describe.c:388 +msgid "proc" +msgstr "проц." + +# well-spelled: функ +#: describe.c:389 describe.c:407 describe.c:452 describe.c:469 +msgid "func" +msgstr "функ." + +#: describe.c:406 describe.c:451 describe.c:468 describe.c:1321 msgid "trigger" msgstr "триггернаÑ" -#: describe.c:360 describe.c:405 describe.c:422 -msgid "normal" -msgstr "обычнаÑ" - -#: describe.c:433 +#: describe.c:480 msgid "immutable" msgstr "поÑтоÑннаÑ" -#: describe.c:434 +#: describe.c:481 msgid "stable" msgstr "ÑтабильнаÑ" -#: describe.c:435 +#: describe.c:482 msgid "volatile" msgstr "изменчиваÑ" -#: describe.c:436 +#: describe.c:483 msgid "Volatility" msgstr "ИзменчивоÑть" -#: describe.c:444 +#: describe.c:491 msgid "restricted" msgstr "ограниченнаÑ" -#: describe.c:445 +#: describe.c:492 msgid "safe" msgstr "безопаÑнаÑ" -#: describe.c:446 +#: describe.c:493 msgid "unsafe" msgstr "небезопаÑнаÑ" -#: describe.c:447 +#: describe.c:494 msgid "Parallel" msgstr "ПараллельноÑть" -#: describe.c:452 +#: describe.c:499 msgid "definer" msgstr "определившего" -#: describe.c:453 +#: describe.c:500 msgid "invoker" msgstr "вызывающего" -#: describe.c:454 +#: describe.c:501 msgid "Security" msgstr "БезопаÑноÑть" -#: describe.c:461 +#: describe.c:508 msgid "Language" msgstr "Язык" -#: describe.c:462 +#: describe.c:509 msgid "Source code" msgstr "ИÑходный код" -#: describe.c:561 +#: describe.c:638 msgid "List of functions" msgstr "СпиÑок функций" -#: describe.c:609 +#: describe.c:686 msgid "Internal name" msgstr "Внутреннее имÑ" -#: describe.c:631 +#: describe.c:708 msgid "Elements" msgstr "Элементы" -#: describe.c:688 +#: describe.c:765 msgid "List of data types" msgstr "СпиÑок типов данных" -#: describe.c:731 +#: describe.c:809 msgid "Left arg type" msgstr "Тип левого аргумента" -#: describe.c:732 +#: describe.c:810 msgid "Right arg type" msgstr "Тип правого аргумента" -#: describe.c:733 +#: describe.c:811 msgid "Result type" msgstr "Результирующий тип" -#: describe.c:738 describe.c:3717 describe.c:4095 +#: describe.c:816 describe.c:3911 describe.c:3976 describe.c:3982 +#: describe.c:4377 msgid "Function" msgstr "ФункциÑ" -#: describe.c:763 +#: describe.c:841 msgid "List of operators" msgstr "СпиÑок операторов" -#: describe.c:793 +#: describe.c:871 msgid "Encoding" msgstr "Кодировка" -#: describe.c:798 describe.c:3815 +#: describe.c:876 describe.c:4092 msgid "Collate" msgstr "LC_COLLATE" -#: describe.c:799 describe.c:3816 +#: describe.c:877 describe.c:4093 msgid "Ctype" msgstr "LC_CTYPE" -#: describe.c:812 +#: describe.c:890 msgid "Tablespace" msgstr "Табл. проÑтранÑтво" -#: describe.c:834 +#: describe.c:912 msgid "List of databases" msgstr "СпиÑок баз данных" -#: describe.c:875 describe.c:880 describe.c:1036 describe.c:3270 -#: describe.c:3277 +#: describe.c:953 describe.c:958 describe.c:1114 describe.c:3520 +#: describe.c:3527 msgid "table" msgstr "таблица" -#: describe.c:876 describe.c:3271 +#: describe.c:954 describe.c:3521 msgid "view" msgstr "предÑтавление" -#: describe.c:877 describe.c:3272 +#: describe.c:955 describe.c:3522 msgid "materialized view" msgstr "материализованное предÑтавление" -#: describe.c:878 describe.c:1038 describe.c:3274 +#: describe.c:956 describe.c:1116 describe.c:3524 msgid "sequence" msgstr "поÑледовательноÑть" -#: describe.c:879 describe.c:3276 +#: describe.c:957 describe.c:3526 msgid "foreign table" msgstr "ÑтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð°" -#: describe.c:892 +#: describe.c:970 msgid "Column privileges" msgstr "Права Ð´Ð»Ñ Ñтолбцов" -#: describe.c:923 describe.c:957 +#: describe.c:1001 describe.c:1035 msgid "Policies" msgstr "Политики" -#: describe.c:989 describe.c:5249 describe.c:5253 +#: describe.c:1067 describe.c:5584 describe.c:5588 msgid "Access privileges" msgstr "Права доÑтупа" -#: describe.c:1020 +#: describe.c:1098 #, c-format msgid "The server (version %s) does not support altering default privileges.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает изменение прав по умолчанию.\n" -#: describe.c:1040 +#: describe.c:1118 msgid "function" msgstr "функциÑ" -#: describe.c:1042 +#: describe.c:1120 msgid "type" msgstr "тип" -#: describe.c:1044 +#: describe.c:1122 msgid "schema" msgstr "Ñхема" -#: describe.c:1068 +#: describe.c:1146 msgid "Default access privileges" msgstr "Права доÑтупа по умолчанию" -#: describe.c:1108 +#: describe.c:1186 msgid "Object" msgstr "Объект" -#: describe.c:1122 +#: describe.c:1200 msgid "table constraint" msgstr "ограничение таблицы" -#: describe.c:1144 +#: describe.c:1222 msgid "domain constraint" msgstr "ограничение домена" -#: describe.c:1172 +#: describe.c:1250 msgid "operator class" msgstr "клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð²" -#: describe.c:1201 +#: describe.c:1279 msgid "operator family" msgstr "ÑемейÑтво операторов" -#: describe.c:1223 +#: describe.c:1301 msgid "rule" msgstr "правило" -#: describe.c:1265 +#: describe.c:1343 msgid "Object descriptions" msgstr "ОпиÑание объекта" -#: describe.c:1319 +#: describe.c:1399 describe.c:3618 #, c-format msgid "Did not find any relation named \"%s\".\n" msgstr "Отношение \"%s\" не найдено.\n" -#: describe.c:1528 +#: describe.c:1402 describe.c:3621 +#, c-format +msgid "Did not find any relations.\n" +msgstr "ÐžÑ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" + +#: describe.c:1619 #, c-format msgid "Did not find any relation with OID %s.\n" msgstr "Отношение Ñ OID %s не найдено.\n" -#: describe.c:1637 describe.c:1686 +#: describe.c:1665 describe.c:1689 +msgid "Start" +msgstr "Ðачальное_значение" + +#: describe.c:1666 describe.c:1690 +msgid "Minimum" +msgstr "Минимум" + +#: describe.c:1667 describe.c:1691 +msgid "Maximum" +msgstr "МакÑимум" + +#: describe.c:1668 describe.c:1692 +msgid "Increment" +msgstr "Шаг" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3827 +#: describe.c:3993 +msgid "yes" +msgstr "да" + +#: describe.c:1670 describe.c:1694 describe.c:1819 describe.c:3827 +#: describe.c:3990 +msgid "no" +msgstr "нет" + +#: describe.c:1671 describe.c:1695 +msgid "Cycles?" +msgstr "ЗацикливаетÑÑ?" + +#: describe.c:1672 describe.c:1696 +msgid "Cache" +msgstr "КешируетÑÑ" + +#: describe.c:1739 +#, c-format +msgid "Owned by: %s" +msgstr "Владелец: %s" + +#: describe.c:1743 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "ПоÑледовательноÑть Ð´Ð»Ñ Ñтолбца идентификации: %s" + +#: describe.c:1750 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "ПоÑледовательноÑть \"%s.%s\"" + +#: describe.c:1880 describe.c:1926 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "ÐÐµÐ¶ÑƒÑ€Ð½Ð°Ð»Ð¸Ñ€ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s.%s\"" -#: describe.c:1640 describe.c:1689 +#: describe.c:1883 describe.c:1929 #, c-format msgid "Table \"%s.%s\"" msgstr "Таблица \"%s.%s\"" -#: describe.c:1644 +#: describe.c:1887 #, c-format msgid "View \"%s.%s\"" msgstr "ПредÑтавление \"%s.%s\"" -#: describe.c:1649 +#: describe.c:1892 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Ðежурналируемое материализованное предÑтавление \"%s.%s\"" -#: describe.c:1652 +#: describe.c:1895 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Материализованное предÑтавление \"%s.%s\"" -#: describe.c:1656 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "ПоÑледовательноÑть \"%s.%s\"" - -#: describe.c:1661 +#: describe.c:1901 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Ðежурналируемый Ð¸Ð½Ð´ÐµÐºÑ \"%s.%s\"" -#: describe.c:1664 +#: describe.c:1904 #, c-format msgid "Index \"%s.%s\"" msgstr "Ð˜Ð½Ð´ÐµÐºÑ \"%s.%s\"" -#: describe.c:1669 +#: describe.c:1909 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Специальное отношение \"%s.%s\"" -#: describe.c:1673 +#: describe.c:1913 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST-таблица \"%s.%s\"" -#: describe.c:1677 +#: describe.c:1917 #, c-format msgid "Composite type \"%s.%s\"" msgstr "СоÑтавной тип \"%s.%s\"" -#: describe.c:1681 +#: describe.c:1921 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "СтороннÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° \"%s.%s\"" -#: describe.c:1700 -msgid "Column" -msgstr "Столбец" - -#: describe.c:1711 describe.c:3482 +#: describe.c:1945 describe.c:3740 msgid "Collation" msgstr "Правило Ñортировки" -#: describe.c:1712 describe.c:3489 +#: describe.c:1946 describe.c:3747 msgid "Nullable" msgstr "ДопуÑтимоÑть NULL" -#: describe.c:1713 describe.c:3490 +#: describe.c:1947 describe.c:3748 msgid "Default" msgstr "По умолчанию" -#: describe.c:1718 -msgid "Value" -msgstr "Значение" +#: describe.c:1950 +msgid "Key?" +msgstr "Ключевой?" -#: describe.c:1721 +#: describe.c:1952 msgid "Definition" msgstr "Определение" # well-spelled: ОСД -#: describe.c:1724 describe.c:4552 describe.c:4636 describe.c:4707 -#: describe.c:4771 -msgid "FDW Options" +#: describe.c:1954 describe.c:4843 describe.c:4927 describe.c:4998 +#: describe.c:5062 +msgid "FDW options" msgstr "Параметры ОСД" -#: describe.c:1728 +#: describe.c:1956 msgid "Storage" msgstr "Хранилище" -#: describe.c:1733 +#: describe.c:1958 msgid "Stats target" msgstr "Цель Ð´Ð»Ñ ÑтатиÑтики" -#: describe.c:1859 +#: describe.c:2072 #, c-format msgid "Partition of: %s %s" msgstr "Ð¡ÐµÐºÑ†Ð¸Ñ Ð¸Ð·: %s %s" -#: describe.c:1880 +#: describe.c:2080 +msgid "No partition constraint" +msgstr "Ðет Ð¾Ð³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ñекции" + +#: describe.c:2082 +#, c-format +msgid "Partition constraint: %s" +msgstr "Ограничение Ñекции: %s" + +#: describe.c:2105 #, c-format msgid "Partition key: %s" msgstr "Ключ разбиениÑ: %s" -#: describe.c:1948 +#: describe.c:2174 msgid "primary key, " msgstr "первичный ключ, " -#: describe.c:1950 +#: describe.c:2176 msgid "unique, " msgstr "уникальный, " -#: describe.c:1956 +#: describe.c:2182 #, c-format msgid "for table \"%s.%s\"" msgstr "Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹ \"%s.%s\"" -#: describe.c:1960 +#: describe.c:2186 #, c-format msgid ", predicate (%s)" msgstr ", предикат (%s)" -#: describe.c:1963 +#: describe.c:2189 msgid ", clustered" msgstr ", клаÑтеризованный" -#: describe.c:1966 +#: describe.c:2192 msgid ", invalid" msgstr ", нерабочий" -#: describe.c:1969 +#: describe.c:2195 msgid ", deferrable" msgstr ", откладываемый" -#: describe.c:1972 +#: describe.c:2198 msgid ", initially deferred" msgstr ", изначально отложенный" -#: describe.c:1975 +#: describe.c:2201 msgid ", replica identity" msgstr ", репликационный" -#: describe.c:2010 -#, c-format -msgid "Owned by: %s" -msgstr "Владелец: %s" - -#: describe.c:2072 +#: describe.c:2260 msgid "Indexes:" msgstr "ИндекÑÑ‹:" -#: describe.c:2156 +#: describe.c:2344 msgid "Check constraints:" msgstr "ОграничениÑ-проверки:" # TO REWVIEW -#: describe.c:2187 +#: describe.c:2380 msgid "Foreign-key constraints:" msgstr "ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ ключа:" -#: describe.c:2218 +#: describe.c:2411 msgid "Referenced by:" msgstr "СÑылки извне:" -#: describe.c:2278 +#: describe.c:2461 msgid "Policies:" msgstr "Политики:" -#: describe.c:2281 +#: describe.c:2464 msgid "Policies (forced row security enabled):" msgstr "Политики (уÑÐ¸Ð»ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ð° Ñтрок включена):" -#: describe.c:2284 +#: describe.c:2467 msgid "Policies (row security enabled): (none)" msgstr "Политики (защита Ñтрок включена): (Ðет)" -#: describe.c:2287 +#: describe.c:2470 msgid "Policies (forced row security enabled): (none)" msgstr "Политики (уÑÐ¸Ð»ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ñ‰Ð¸Ñ‚Ð° Ñтрок включена): (Ðет)" -#: describe.c:2290 +#: describe.c:2473 msgid "Policies (row security disabled):" msgstr "Политики (защита Ñтрок выключена):" -#: describe.c:2347 -msgid "Statistics:" -msgstr "СтатиÑтика:" +#: describe.c:2535 +msgid "Statistics objects:" +msgstr "Объекты ÑтатиÑтики:" -#: describe.c:2444 describe.c:2526 +#: describe.c:2638 describe.c:2742 msgid "Rules:" msgstr "Правила:" -#: describe.c:2447 +#: describe.c:2641 msgid "Disabled rules:" msgstr "Отключённые правила:" -#: describe.c:2450 +#: describe.c:2644 msgid "Rules firing always:" msgstr "Правила, Ñрабатывающие вÑегда:" -#: describe.c:2453 +#: describe.c:2647 msgid "Rules firing on replica only:" msgstr "Правила, Ñрабатывающие только в реплике:" -#: describe.c:2490 +#: describe.c:2687 msgid "Publications:" msgstr "Публикации:" -#: describe.c:2509 +#: describe.c:2725 msgid "View definition:" msgstr "Определение предÑтавлениÑ:" -#: describe.c:2644 +#: describe.c:2864 msgid "Triggers:" msgstr "Триггеры:" -#: describe.c:2648 +#: describe.c:2868 msgid "Disabled user triggers:" msgstr "Отключённые пользовательÑкие триггеры:" -#: describe.c:2650 +#: describe.c:2870 msgid "Disabled triggers:" msgstr "Отключённые триггеры:" -#: describe.c:2653 +#: describe.c:2873 msgid "Disabled internal triggers:" msgstr "Отключённые внутренние триггеры:" -#: describe.c:2656 +#: describe.c:2876 msgid "Triggers firing always:" msgstr "Триггеры, Ñрабатывающие вÑегда:" -#: describe.c:2659 +#: describe.c:2879 msgid "Triggers firing on replica only:" msgstr "Триггеры, Ñрабатывающие только в реплике:" -#: describe.c:2745 +#: describe.c:2938 +#, c-format +msgid "Server: %s" +msgstr "Сервер: %s" + +# well-spelled: ОСД +#: describe.c:2946 +#, c-format +msgid "FDW options: (%s)" +msgstr "Параметр ОСД: (%s)" + +#: describe.c:2965 msgid "Inherits" msgstr "ÐаÑледует" -#: describe.c:2799 +#: describe.c:3024 +#, c-format +msgid "Number of partitions: %d" +msgstr "ЧиÑло Ñекций: %d" + +#: describe.c:3033 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Дочерних таблиц: %d (чтобы проÑмотреть и их, воÑпользуйтеÑÑŒ \\d+)" -#: describe.c:2801 +#: describe.c:3035 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "ЧиÑло Ñекций: %d (чтобы проÑмотреть их, введите \\d+)" -#: describe.c:2809 +#: describe.c:3043 msgid "Child tables" msgstr "Дочерние таблицы" -#: describe.c:2809 +#: describe.c:3043 msgid "Partitions" msgstr "Секции" -#: describe.c:2843 +#: describe.c:3086 #, c-format msgid "Typed table of type: %s" msgstr "Ð¢Ð¸Ð¿Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° типа: %s" -#: describe.c:2859 +#: describe.c:3102 msgid "Replica Identity" msgstr "Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ¸" -#: describe.c:2872 +#: describe.c:3115 msgid "Has OIDs: yes" msgstr "Содержит OID: да" -#: describe.c:2956 +#: describe.c:3195 #, c-format msgid "Tablespace: \"%s\"" msgstr "Табличное проÑтранÑтво: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:2968 +#: describe.c:3207 #, c-format msgid ", tablespace \"%s\"" msgstr ", табл. проÑтранÑтво \"%s\"" -#: describe.c:3061 +#: describe.c:3300 msgid "List of roles" msgstr "СпиÑок ролей" -#: describe.c:3063 +#: describe.c:3302 msgid "Role name" msgstr "Ð˜Ð¼Ñ Ñ€Ð¾Ð»Ð¸" -#: describe.c:3064 +#: describe.c:3303 msgid "Attributes" msgstr "Ðтрибуты" -#: describe.c:3065 +#: describe.c:3304 msgid "Member of" msgstr "Член ролей" -#: describe.c:3076 +#: describe.c:3315 msgid "Superuser" msgstr "Суперпользователь" -#: describe.c:3079 +#: describe.c:3318 msgid "No inheritance" msgstr "Ðе наÑледуетÑÑ" -#: describe.c:3082 +#: describe.c:3321 msgid "Create role" msgstr "Создаёт роли" -#: describe.c:3085 +#: describe.c:3324 msgid "Create DB" msgstr "Создаёт БД" -#: describe.c:3088 +#: describe.c:3327 msgid "Cannot login" msgstr "Вход запрещён" -#: describe.c:3092 +#: describe.c:3331 msgid "Replication" msgstr "РепликациÑ" -#: describe.c:3096 +#: describe.c:3335 msgid "Bypass RLS" msgstr "ПропуÑкать RLS" -#: describe.c:3105 +#: describe.c:3344 msgid "No connections" msgstr "Ðет подключений" -#: describe.c:3107 +#: describe.c:3346 #, c-format msgid "%d connection" msgid_plural "%d connections" @@ -1634,312 +1709,306 @@ msgstr[0] "%d подключение" msgstr[1] "%d подключениÑ" msgstr[2] "%d подключений" -#: describe.c:3117 +#: describe.c:3356 msgid "Password valid until " msgstr "Пароль дейÑтвует до " -#: describe.c:3173 +#: describe.c:3406 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "" +"Сервер (верÑÐ¸Ñ %s) не поддерживает назначение параметров ролей Ð´Ð»Ñ Ð±Ð°Ð· " +"данных.\n" + +#: describe.c:3419 msgid "Role" msgstr "Роль" -#: describe.c:3174 +#: describe.c:3420 msgid "Database" msgstr "БД" -#: describe.c:3175 +#: describe.c:3421 msgid "Settings" msgstr "Параметры" -#: describe.c:3185 +#: describe.c:3442 #, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "" -"Это верÑÐ¸Ñ Ñервера не поддерживает параметры ролей на уровне базы данных.\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "Параметры Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸ \"%s\" и базы данных \"%s\" не найдены.\n" -#: describe.c:3196 +#: describe.c:3445 #, c-format -msgid "No matching settings found.\n" -msgstr "СоответÑтвующие параметры не найдены.\n" +msgid "Did not find any settings for role \"%s\".\n" +msgstr "Параметры Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸ \"%s\" не найдены.\n" -#: describe.c:3198 +#: describe.c:3448 #, c-format -msgid "No settings found.\n" -msgstr "Параметры не найдены.\n" +msgid "Did not find any settings.\n" +msgstr "Ðикакие параметры не найдены.\n" -#: describe.c:3203 +#: describe.c:3453 msgid "List of settings" msgstr "СпиÑок параметров" -#: describe.c:3273 +#: describe.c:3523 describe.c:3528 msgid "index" msgstr "индекÑ" # skip-rule: capital-letter-first -#: describe.c:3275 +#: describe.c:3525 msgid "special" msgstr "Ñпец. отношение" -#: describe.c:3284 describe.c:4759 +#: describe.c:3535 describe.c:5050 msgid "Table" msgstr "Таблица" -#: describe.c:3361 -#, c-format -msgid "No matching relations found.\n" -msgstr "СоответÑтвующие Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" - -#: describe.c:3363 -#, c-format -msgid "No relations found.\n" -msgstr "ÐžÑ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" - -#: describe.c:3368 +#: describe.c:3626 msgid "List of relations" msgstr "СпиÑок отношений" -#: describe.c:3405 +#: describe.c:3663 msgid "Trusted" msgstr "Доверенный" -#: describe.c:3413 -msgid "Internal Language" +#: describe.c:3671 +msgid "Internal language" msgstr "Внутренний Ñзык" -#: describe.c:3414 -msgid "Call Handler" +#: describe.c:3672 +msgid "Call handler" msgstr "Обработчик вызова" -#: describe.c:3415 describe.c:4539 +#: describe.c:3673 describe.c:4830 msgid "Validator" msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸" -#: describe.c:3418 -msgid "Inline Handler" +#: describe.c:3676 +msgid "Inline handler" msgstr "Обработчик внедрённого кода" -#: describe.c:3446 +#: describe.c:3704 msgid "List of languages" msgstr "СпиÑок Ñзыков" -#: describe.c:3491 +#: describe.c:3749 msgid "Check" msgstr "Проверка" -#: describe.c:3533 +#: describe.c:3791 msgid "List of domains" msgstr "СпиÑок доменов" -#: describe.c:3567 +#: describe.c:3825 msgid "Source" msgstr "ИÑточник" -#: describe.c:3568 +#: describe.c:3826 msgid "Destination" msgstr "Ðазначение" -#: describe.c:3569 describe.c:3718 -msgid "no" -msgstr "нет" - -#: describe.c:3569 describe.c:3720 -msgid "yes" -msgstr "да" - -#: describe.c:3570 +#: describe.c:3828 msgid "Default?" msgstr "По умолчанию?" -#: describe.c:3607 +#: describe.c:3865 msgid "List of conversions" msgstr "СпиÑок преобразований" -#: describe.c:3646 +#: describe.c:3904 msgid "Event" msgstr "Событие" -#: describe.c:3648 +#: describe.c:3906 msgid "enabled" msgstr "включён" -#: describe.c:3649 +#: describe.c:3907 msgid "replica" msgstr "реплика" -#: describe.c:3650 +#: describe.c:3908 msgid "always" msgstr "вÑегда" -#: describe.c:3651 +#: describe.c:3909 msgid "disabled" msgstr "отключён" -#: describe.c:3652 describe.c:5196 +#: describe.c:3910 describe.c:5529 msgid "Enabled" msgstr "Включён" -#: describe.c:3653 -msgid "Procedure" -msgstr "Процедура" - -#: describe.c:3654 +#: describe.c:3912 msgid "Tags" msgstr "Теги" -#: describe.c:3673 +#: describe.c:3931 msgid "List of event triggers" msgstr "СпиÑок Ñобытийных триггеров" -#: describe.c:3715 +#: describe.c:3960 msgid "Source type" msgstr "ИÑходный тип" -#: describe.c:3716 +#: describe.c:3961 msgid "Target type" msgstr "Целевой тип" -#: describe.c:3719 +#: describe.c:3992 msgid "in assignment" msgstr "в приÑваивании" -#: describe.c:3721 +#: describe.c:3994 msgid "Implicit?" msgstr "ÐеÑвное?" -#: describe.c:3772 +#: describe.c:4049 msgid "List of casts" msgstr "СпиÑок приведений типов" -#: describe.c:3800 +#: describe.c:4077 #, c-format msgid "The server (version %s) does not support collations.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает правила ÑравнениÑ.\n" -#: describe.c:3821 +#: describe.c:4098 msgid "Provider" msgstr "ПоÑтавщик" -#: describe.c:3856 +#: describe.c:4133 msgid "List of collations" msgstr "СпиÑок правил Ñортировки" -#: describe.c:3915 +#: describe.c:4192 msgid "List of schemas" msgstr "СпиÑок Ñхем" -#: describe.c:3940 describe.c:4178 describe.c:4249 describe.c:4320 +#: describe.c:4217 describe.c:4464 describe.c:4535 describe.c:4606 #, c-format msgid "The server (version %s) does not support full text search.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает полнотекÑтовый поиÑк.\n" -#: describe.c:3975 +#: describe.c:4252 msgid "List of text search parsers" msgstr "СпиÑок анализаторов текÑтового поиÑка" -#: describe.c:4018 +#: describe.c:4297 #, c-format msgid "Did not find any text search parser named \"%s\".\n" msgstr "Ðнализатор текÑтового поиÑка \"%s\" не найден.\n" -#: describe.c:4093 +#: describe.c:4300 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "Ðикакие анализаторы текÑтового поиÑка не найдены.\n" + +#: describe.c:4375 msgid "Start parse" msgstr "Ðачало разбора" -#: describe.c:4094 +#: describe.c:4376 msgid "Method" msgstr "Метод" -#: describe.c:4098 +#: describe.c:4380 msgid "Get next token" msgstr "Получение Ñледующего фрагмента" -#: describe.c:4100 +#: describe.c:4382 msgid "End parse" msgstr "Окончание разбора" -#: describe.c:4102 +#: describe.c:4384 msgid "Get headline" msgstr "Получение выдержки" -#: describe.c:4104 +#: describe.c:4386 msgid "Get token types" msgstr "Получение типов фрагментов" -#: describe.c:4114 +#: describe.c:4397 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Ðнализатор текÑтового поиÑка \"%s.%s\"" -#: describe.c:4116 +#: describe.c:4400 #, c-format msgid "Text search parser \"%s\"" msgstr "Ðнализатор текÑтового поиÑка \"%s\"" -#: describe.c:4135 +#: describe.c:4419 msgid "Token name" msgstr "Ð˜Ð¼Ñ Ñ„Ñ€Ð°Ð³Ð¼ÐµÐ½Ñ‚Ð°" -#: describe.c:4146 +#: describe.c:4430 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Типы фрагментов Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°Ñ‚Ð¾Ñ€Ð° \"%s.%s\"" -#: describe.c:4148 +#: describe.c:4433 #, c-format msgid "Token types for parser \"%s\"" msgstr "Типы фрагментов Ð´Ð»Ñ Ð°Ð½Ð°Ð»Ð¸Ð·Ð°Ñ‚Ð¾Ñ€Ð° \"%s\"" -#: describe.c:4201 +#: describe.c:4487 msgid "Template" msgstr "Шаблон" -#: describe.c:4202 +#: describe.c:4488 msgid "Init options" msgstr "Параметры инициализации" -#: describe.c:4224 +#: describe.c:4510 msgid "List of text search dictionaries" msgstr "СпиÑок Ñловарей текÑтового поиÑка" -#: describe.c:4267 +#: describe.c:4553 msgid "Init" msgstr "ИнициализациÑ" -#: describe.c:4268 +#: describe.c:4554 msgid "Lexize" msgstr "Выделение лекÑем" -#: describe.c:4295 +#: describe.c:4581 msgid "List of text search templates" msgstr "СпиÑок шаблонов текÑтового поиÑка" -#: describe.c:4355 +#: describe.c:4641 msgid "List of text search configurations" msgstr "СпиÑок конфигураций текÑтового поиÑка" -#: describe.c:4399 +#: describe.c:4687 #, c-format msgid "Did not find any text search configuration named \"%s\".\n" msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\" не найдена.\n" -#: describe.c:4465 +#: describe.c:4690 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "Ðикакие конфигурации текÑтового поиÑка не найдены.\n" + +#: describe.c:4756 msgid "Token" msgstr "Фрагмент" -#: describe.c:4466 +#: describe.c:4757 msgid "Dictionaries" msgstr "Словари" -#: describe.c:4477 +#: describe.c:4768 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s.%s\"" -#: describe.c:4480 +#: describe.c:4771 #, c-format msgid "Text search configuration \"%s\"" msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ Ñ‚ÐµÐºÑтового поиÑка \"%s\"" -#: describe.c:4484 +#: describe.c:4775 #, c-format msgid "" "\n" @@ -1948,7 +2017,7 @@ msgstr "" "\n" "Ðнализатор: \"%s.%s\"" -#: describe.c:4487 +#: describe.c:4778 #, c-format msgid "" "\n" @@ -1957,130 +2026,152 @@ msgstr "" "\n" "Ðнализатор: \"%s\"" -#: describe.c:4521 +#: describe.c:4812 #, c-format msgid "The server (version %s) does not support foreign-data wrappers.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает обёртки Ñторонних данных.\n" -#: describe.c:4579 +#: describe.c:4870 msgid "List of foreign-data wrappers" msgstr "СпиÑок обёрток Ñторонних данных" -#: describe.c:4604 +#: describe.c:4895 #, c-format msgid "The server (version %s) does not support foreign servers.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает Ñторонние Ñерверы.\n" -#: describe.c:4617 +#: describe.c:4908 msgid "Foreign-data wrapper" msgstr "Обёртка Ñторонних данных" -#: describe.c:4635 describe.c:4840 +#: describe.c:4926 describe.c:5131 msgid "Version" msgstr "ВерÑиÑ" -#: describe.c:4661 +#: describe.c:4952 msgid "List of foreign servers" msgstr "СпиÑок Ñторонних Ñерверов" -#: describe.c:4686 +#: describe.c:4977 #, c-format msgid "The server (version %s) does not support user mappings.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает ÑопоÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¹.\n" -#: describe.c:4696 describe.c:4760 +#: describe.c:4987 describe.c:5051 msgid "Server" msgstr "Сервер" -#: describe.c:4697 +#: describe.c:4988 msgid "User name" msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ" -#: describe.c:4722 +#: describe.c:5013 msgid "List of user mappings" msgstr "СпиÑок ÑопоÑтавлений пользователей" -#: describe.c:4747 +#: describe.c:5038 #, c-format msgid "The server (version %s) does not support foreign tables.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает Ñторонние таблицы.\n" -#: describe.c:4800 +#: describe.c:5091 msgid "List of foreign tables" msgstr "СпиÑок Ñторонних таблиц" -#: describe.c:4825 describe.c:4882 +#: describe.c:5116 describe.c:5173 #, c-format msgid "The server (version %s) does not support extensions.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает раÑширениÑ.\n" -#: describe.c:4857 +#: describe.c:5148 msgid "List of installed extensions" msgstr "СпиÑок уÑтановленных раÑширений" -#: describe.c:4910 +#: describe.c:5201 #, c-format msgid "Did not find any extension named \"%s\".\n" msgstr "РаÑширение \"%s\" не найдено.\n" -#: describe.c:4913 +#: describe.c:5204 #, c-format msgid "Did not find any extensions.\n" msgstr "РаÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" -#: describe.c:4957 -msgid "Object Description" +#: describe.c:5248 +msgid "Object description" msgstr "ОпиÑание объекта" -#: describe.c:4966 +#: describe.c:5258 #, c-format msgid "Objects in extension \"%s\"" msgstr "Объекты в раÑширении \"%s\"" -#: describe.c:4992 describe.c:5054 +#: describe.c:5287 describe.c:5358 #, c-format msgid "The server (version %s) does not support publications.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает публикации.\n" -#: describe.c:5008 describe.c:5099 +#: describe.c:5304 describe.c:5430 +msgid "All tables" +msgstr "Ð’Ñе таблицы" + +#: describe.c:5305 describe.c:5431 msgid "Inserts" msgstr "ДобавлениÑ" -#: describe.c:5009 describe.c:5100 +#: describe.c:5306 describe.c:5432 msgid "Updates" msgstr "ИзменениÑ" -#: describe.c:5010 describe.c:5101 +#: describe.c:5307 describe.c:5433 msgid "Deletes" msgstr "УдалениÑ" -#: describe.c:5027 +#: describe.c:5311 describe.c:5435 +msgid "Truncates" +msgstr "ОпуÑтошениÑ" + +#: describe.c:5328 msgid "List of publications" msgstr "СпиÑок публикаций" -#: describe.c:5096 +#: describe.c:5396 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ \"%s\" не найдена.\n" + +#: describe.c:5399 +#, c-format +msgid "Did not find any publications.\n" +msgstr "Ðикакие публикации не найдены.\n" + +#: describe.c:5426 #, c-format msgid "Publication %s" msgstr "ÐŸÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ñ %s" -#: describe.c:5141 +#: describe.c:5470 msgid "Tables:" msgstr "Таблицы:" -#: describe.c:5181 +#: describe.c:5514 #, c-format msgid "The server (version %s) does not support subscriptions.\n" msgstr "Сервер (верÑÐ¸Ñ %s) не поддерживает подпиÑки.\n" -#: describe.c:5197 +#: describe.c:5530 msgid "Publication" msgstr "ПубликациÑ" -#: describe.c:5203 +#: describe.c:5537 +msgid "Synchronous commit" +msgstr "Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð½Ð°Ñ Ñ„Ð¸ÐºÑациÑ" + +#: describe.c:5538 msgid "Conninfo" msgstr "Строка подключениÑ" -#: describe.c:5225 +#: describe.c:5560 msgid "List of subscriptions" msgstr "СпиÑок подпиÑок" @@ -2098,7 +2189,7 @@ msgstr "" "psql - Ñто интерактивный терминал PostgreSQL.\n" "\n" -#: help.c:74 help.c:342 help.c:376 help.c:403 +#: help.c:74 help.c:345 help.c:419 help.c:462 #, c-format msgid "Usage:\n" msgstr "ИÑпользование:\n" @@ -2443,13 +2534,21 @@ msgstr "" #: help.c:174 #, c-format msgid "" +" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr "" +" \\crosstabview [СТОЛБЦЫ] выполнить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸ вывеÑти результат в " +"перекрёÑтном виде\n" + +#: help.c:175 +#, c-format +msgid "" " \\errverbose show most recent error message at maximum " "verbosity\n" msgstr "" " \\errverbose вывеÑти макÑимально подробное Ñообщение о " "поÑледней ошибке\n" -#: help.c:175 +#: help.c:176 #, c-format msgid "" " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" @@ -2457,13 +2556,14 @@ msgstr "" " \\g [ФÐЙЛ] или ; выполнить запроÑ\n" " (и направить результаты в файл или канал |)\n" -#: help.c:176 +#: help.c:177 #, c-format -msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgid "" +" \\gdesc describe result of query, without executing it\n" msgstr "" -" \\gx [ФÐЙЛ] то же, что и \\g, но в режиме развёрнутого вывода\n" +" \\gdesc опиÑать результат запроÑа, но не выполнÑть его\n" -#: help.c:177 +#: help.c:178 #, c-format msgid "" " \\gexec execute query, then execute each value in its " @@ -2472,7 +2572,7 @@ msgstr "" " \\gexec выполнить запроÑ, а затем выполнить каждую Ñтроку " "в результате\n" -#: help.c:178 +#: help.c:179 #, c-format msgid "" " \\gset [PREFIX] execute query and store results in psql variables\n" @@ -2481,48 +2581,46 @@ msgstr "" "переменных\n" " psql\n" -#: help.c:179 -#, c-format -msgid " \\q quit psql\n" -msgstr " \\q выйти из psql\n" - #: help.c:180 #, c-format -msgid "" -" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" msgstr "" -" \\crosstabview [СТОЛБЦЫ] выполнить Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸ вывеÑти результат в " -"перекрёÑтном виде\n" +" \\gx [ФÐЙЛ] то же, что и \\g, но в режиме развёрнутого вывода\n" #: help.c:181 #, c-format +msgid " \\q quit psql\n" +msgstr " \\q выйти из psql\n" + +#: help.c:182 +#, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr "" " \\watch [СЕК] повторÑть Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð² цикле через заданное чиÑло " "Ñекунд\n" -#: help.c:184 +#: help.c:185 #, c-format msgid "Help\n" msgstr "Справка\n" -#: help.c:186 +#: help.c:187 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] Ñправка по командам psql c \\\n" -#: help.c:187 +#: help.c:188 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr "" " \\? options Ñправка по параметрам командной Ñтроки psql\n" -#: help.c:188 +#: help.c:189 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables Ñправка по Ñпециальным переменным\n" -#: help.c:189 +#: help.c:190 #, c-format msgid "" " \\h [NAME] help on syntax of SQL commands, * for all " @@ -2530,12 +2628,12 @@ msgid "" msgstr "" " \\h [ИМЯ] Ñправка по заданному SQL-оператору; * - по вÑем\n" -#: help.c:192 +#: help.c:193 #, c-format msgid "Query Buffer\n" msgstr "Буфер запроÑа\n" -#: help.c:193 +#: help.c:194 #, c-format msgid "" " \\e [FILE] [LINE] edit the query buffer (or file) with external " @@ -2544,63 +2642,63 @@ msgstr "" " \\e [ФÐЙЛ] [СТРОКÐ] править буфер запроÑа (или файл) во внешнем " "редакторе\n" -#: help.c:194 +#: help.c:195 #, c-format msgid "" " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr "" " \\ef [ФУÐКЦИЯ [СТРОКÐ]] править определение функции во внешнем редакторе\n" -#: help.c:195 +#: help.c:196 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr "" " \\ev [VIEWNAME [LINE]] править определение предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð²Ð¾ внешнем " "редакторе\n" -#: help.c:196 +#: help.c:197 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p вывеÑти Ñодержимое буфера запроÑов\n" -#: help.c:197 +#: help.c:198 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r очиÑтить буфер запроÑа\n" -#: help.c:199 +#: help.c:200 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [ФÐЙЛ] вывеÑти иÑторию или Ñохранить её в файл\n" -#: help.c:201 +#: help.c:202 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w ФÐЙЛ запиÑать буфер запроÑа в файл\n" -#: help.c:204 +#: help.c:205 #, c-format msgid "Input/Output\n" msgstr "Ввод/Вывод\n" -#: help.c:205 +#: help.c:206 #, c-format msgid "" " \\copy ... perform SQL COPY with data stream to the client " "host\n" msgstr " \\copy ... выполнить SQL COPY на Ñтороне клиента\n" -#: help.c:206 +#: help.c:207 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [СТРОКÐ] запиÑать Ñтроку в Ñтандартный вывод\n" -#: help.c:207 +#: help.c:208 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i ФÐЙЛ выполнить команды из файла\n" -#: help.c:208 +#: help.c:209 #, c-format msgid "" " \\ir FILE as \\i, but relative to location of current " @@ -2609,14 +2707,14 @@ msgstr "" " \\ir ФÐЙЛ подобно \\i, но путь задаётÑÑ Ð¾Ñ‚Ð½Ð¾Ñительно\n" " текущего Ñкрипта\n" -#: help.c:209 +#: help.c:210 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr "" " \\o [ФÐЙЛ] выводить вÑе результаты запроÑов в файл или канал " "|\n" -#: help.c:210 +#: help.c:211 #, c-format msgid "" " \\qecho [STRING] write string to query output stream (see \\o)\n" @@ -2624,24 +2722,24 @@ msgstr "" " \\qecho [СТРОКÐ] запиÑать Ñтроку в поток результатов запроÑа (Ñм. " "\\o)\n" -#: help.c:213 +#: help.c:214 #, c-format msgid "Conditional\n" msgstr "УÑловиÑ\n" -#: help.c:214 +#: help.c:215 #, c-format msgid " \\if EXPR begin conditional block\n" msgstr " \\if ВЫРÐЖЕÐИЕ начало блока уÑловиÑ\n" -#: help.c:215 +#: help.c:216 #, c-format msgid "" " \\elif EXPR alternative within current conditional block\n" msgstr "" " \\elif ВЫРÐЖЕÐИЕ Ð°Ð»ÑŒÑ‚ÐµÑ€Ð½Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð²ÐµÑ‚Ð²ÑŒ в текущем блоке уÑловиÑ\n" -#: help.c:216 +#: help.c:217 #, c-format msgid "" " \\else final alternative within current conditional " @@ -2649,31 +2747,31 @@ msgid "" msgstr "" " \\else Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð²ÐµÑ‚Ð²ÑŒ в текущем блоке уÑловиÑ\n" -#: help.c:217 +#: help.c:218 #, c-format msgid " \\endif end conditional block\n" msgstr " \\endif конец блока уÑловиÑ\n" -#: help.c:220 +#: help.c:221 #, c-format msgid "Informational\n" msgstr "Информационные\n" -#: help.c:221 +#: help.c:222 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr "" " (дополнениÑ: S = показывать ÑиÑтемные объекты, + = дополнительные " "подробноÑти)\n" -#: help.c:222 +#: help.c:223 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr "" " \\d[S+] ÑпиÑок таблиц, предÑтавлений и " "поÑледовательноÑтей\n" -#: help.c:223 +#: help.c:224 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr "" @@ -2681,43 +2779,38 @@ msgstr "" "поÑледовательноÑти\n" " или индекÑа\n" -#: help.c:224 +#: help.c:225 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [МÐСКÐ] ÑпиÑок агрегатных функций\n" -#: help.c:225 +#: help.c:226 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [МÐСКÐ] ÑпиÑок методов доÑтупа\n" -#: help.c:226 +#: help.c:227 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [МÐСКÐ] ÑпиÑок табличных проÑтранÑтв\n" -#: help.c:227 +#: help.c:228 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [МÐСКÐ] ÑпиÑок преобразований\n" -#: help.c:228 +#: help.c:229 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [МÐСКÐ] ÑпиÑок приведений типов\n" -#: help.c:229 +#: help.c:230 #, c-format msgid "" " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr "" " \\dd[S] [МÐСКÐ] опиÑÐ°Ð½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¾Ð², не выводимые в других режимах\n" -#: help.c:230 -#, c-format -msgid " \\ddp [PATTERN] list default privileges\n" -msgstr " \\ddp [МÐСКÐ] ÑпиÑок прав по умолчанию\n" - #: help.c:231 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" @@ -2725,94 +2818,105 @@ msgstr " \\dD[S+] [МÐСКÐ] ÑпиÑок доменов\n" #: help.c:232 #, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [МÐСКÐ] ÑпиÑок прав по умолчанию\n" + +#: help.c:233 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [МÐСКÐ] ÑпиÑок Ñторонних таблиц\n" + +#: help.c:234 +#, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [МÐСКÐ] ÑпиÑок Ñторонних таблиц\n" -#: help.c:233 +#: help.c:235 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [МÐСКÐ] ÑпиÑок Ñторонних Ñерверов\n" -#: help.c:234 +#: help.c:236 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [МÐСКÐ] ÑпиÑок ÑопоÑтавлений пользователей\n" -#: help.c:235 +#: help.c:237 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [МÐСКÐ] ÑпиÑок обёрток Ñторонних данных\n" -#: help.c:236 +#: help.c:238 #, c-format msgid "" -" \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" +" \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] " +"functions\n" msgstr "" -" \\df[antw][S+] [МÐСКÐ] ÑпиÑок [агрегатных/нормальных/триггерных/оконных]\n" -" функций ÑоответÑтвенно\n" +" \\df[anptw][S+] [МÐСКÐ] ÑпиÑок [только агрегатных/обычных/(процедур)/\n" +" триггерных/оконных] функций\n" -#: help.c:237 +#: help.c:239 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [МÐСКÐ] ÑпиÑок конфигураций текÑтового поиÑка\n" -#: help.c:238 +#: help.c:240 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [МÐСКÐ] ÑпиÑок Ñловарей текÑтового поиÑка\n" -#: help.c:239 +#: help.c:241 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [МÐСКÐ] ÑпиÑок анализаторов текÑтового поиÑка\n" -#: help.c:240 +#: help.c:242 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [МÐСКÐ] ÑпиÑок шаблонов текÑтового поиÑка\n" -#: help.c:241 +#: help.c:243 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [МÐСКÐ] ÑпиÑок ролей\n" -#: help.c:242 +#: help.c:244 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [МÐСКÐ] ÑпиÑок индекÑов\n" -#: help.c:243 +#: help.c:245 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr "" " \\dl ÑпиÑок больших объектов (то же, что и \\lo_list)\n" -#: help.c:244 +#: help.c:246 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [МÐСКÐ] ÑпиÑок Ñзыков процедур\n" -#: help.c:245 +#: help.c:247 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [МÐСКÐ] ÑпиÑок материализованных предÑтавлений\n" -#: help.c:246 +#: help.c:248 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [МÐСКÐ] ÑпиÑок Ñхем\n" -#: help.c:247 +#: help.c:249 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [МÐСКÐ] ÑпиÑок операторов\n" -#: help.c:248 +#: help.c:250 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" msgstr " \\dO[S+] [МÐСКÐ] ÑпиÑок правил Ñортировки\n" -#: help.c:249 +#: help.c:251 #, c-format msgid "" " \\dp [PATTERN] list table, view, and sequence access privileges\n" @@ -2821,88 +2925,83 @@ msgstr "" " поÑледовательноÑÑ‚Ñм\n" # well-spelled: МÐСК -#: help.c:250 +#: help.c:252 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [МÐСК1 [МÐСК2]] ÑпиÑок параметров роли на уровне БД\n" -#: help.c:251 +#: help.c:253 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[+] [МÐСКÐ] ÑпиÑок публикаций Ð´Ð»Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸\n" -#: help.c:252 +#: help.c:254 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [МÐСКÐ] ÑпиÑок подпиÑок на репликацию\n" -#: help.c:253 +#: help.c:255 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [МÐСКÐ] ÑпиÑок поÑледовательноÑтей\n" -#: help.c:254 +#: help.c:256 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [МÐСКÐ] ÑпиÑок таблиц\n" -#: help.c:255 +#: help.c:257 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [МÐСКÐ] ÑпиÑок типов данных\n" -#: help.c:256 +#: help.c:258 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [МÐСКÐ] ÑпиÑок ролей\n" -#: help.c:257 +#: help.c:259 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [МÐСКÐ] ÑпиÑок предÑтавлений\n" -#: help.c:258 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [МÐСКÐ] ÑпиÑок Ñторонних таблиц\n" - -#: help.c:259 +#: help.c:260 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [МÐСКÐ] ÑпиÑок раÑширений\n" -#: help.c:260 +#: help.c:261 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [МÐСКÐ] ÑпиÑок Ñобытийных триггеров\n" -#: help.c:261 +#: help.c:262 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [МÐСКÐ] ÑпиÑок баз данных\n" -#: help.c:262 +#: help.c:263 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] ИМЯ_ФУÐКЦИИ показать определение функции\n" # well-spelled: ПРЕДСТ -#: help.c:263 +#: help.c:264 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] ИМЯ_ПРЕДСТ показать определение предÑтавлениÑ\n" -#: help.c:264 +#: help.c:265 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [МÐСКÐ] то же, что и \\dp\n" -#: help.c:267 +#: help.c:268 #, c-format msgid "Formatting\n" msgstr "Форматирование\n" -#: help.c:268 +#: help.c:269 #, c-format msgid "" " \\a toggle between unaligned and aligned output mode\n" @@ -2910,14 +3009,14 @@ msgstr "" " \\a переключение режимов вывода:\n" " неформатированный/выровненный\n" -#: help.c:269 +#: help.c:270 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr "" " \\C [СТРОКÐ] задать заголовок таблицы или убрать, еÑли не " "задан\n" -#: help.c:270 +#: help.c:271 #, c-format msgid "" " \\f [STRING] show or set field separator for unaligned query " @@ -2926,37 +3025,41 @@ msgstr "" " \\f [СТРОКÐ] показать или уÑтановить разделитель полей длÑ\n" " неформатированного вывода\n" -#: help.c:271 +#: help.c:272 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr "" " \\H переключить режим вывода в HTML (текущий: %s)\n" -#: help.c:273 +#: help.c:274 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|" +" (NAME := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" "unicode_header_linestyle})\n" msgstr "" " \\pset [ИМЯ [ЗÐÐЧЕÐИЕ]] уÑтановить параметр вывода таблицы, где\n" -" ИМЯ := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|" +" (ИМЯ := {border|columns|expanded|fieldsep|" +"fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|" +"title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|" "unicode_header_linestyle})\n" -#: help.c:277 +#: help.c:280 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] режим вывода только Ñтрок (ÑейчаÑ: %s)\n" -#: help.c:279 +#: help.c:282 #, c-format msgid "" " \\T [STRING] set HTML
tag attributes, or unset if none\n" @@ -2964,19 +3067,19 @@ msgstr "" " \\T [СТРОКÐ] задать атрибуты длÑ
или убрать, еÑли не " "заданы\n" -#: help.c:280 +#: help.c:283 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr "" " \\x [on|off|auto] переключить режим раÑширенного вывода (ÑейчаÑ: " "%s)\n" -#: help.c:284 +#: help.c:287 #, c-format msgid "Connection\n" msgstr "Соединение\n" -#: help.c:286 +#: help.c:289 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2986,7 +3089,7 @@ msgstr "" " подключитьÑÑ Ðº другой базе данных\n" " (текущаÑ: \"%s\")\n" -#: help.c:290 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2996,44 +3099,44 @@ msgstr "" " подключитьÑÑ Ðº другой базе данных\n" " (ÑÐµÐ¹Ñ‡Ð°Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚)\n" -#: help.c:292 +#: help.c:295 +#, c-format +msgid "" +" \\conninfo display information about current connection\n" +msgstr " \\conninfo Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ текущем Ñоединении\n" + +#: help.c:296 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [КОДИРОВКÐ] показать/уÑтановить клиентÑкую кодировку\n" -#: help.c:293 +#: help.c:297 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [ИМЯ] безопаÑно Ñменить пароль пользователÑ\n" -#: help.c:294 -#, c-format -msgid "" -" \\conninfo display information about current connection\n" -msgstr " \\conninfo Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ текущем Ñоединении\n" - -#: help.c:297 +#: help.c:300 #, c-format msgid "Operating System\n" msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема\n" -#: help.c:298 +#: help.c:301 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [ПУТЬ] Ñменить текущий каталог\n" -#: help.c:299 +#: help.c:302 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr "" " \\setenv ИМЯ [ЗÐÐЧЕÐИЕ] уÑтановить или ÑброÑить переменную окружениÑ\n" -#: help.c:300 +#: help.c:303 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] включить/выключить Ñекундомер (ÑейчаÑ: %s)\n" -#: help.c:302 +#: help.c:305 #, c-format msgid "" " \\! [COMMAND] execute command in shell or start interactive " @@ -3042,19 +3145,19 @@ msgstr "" " \\! [КОМÐÐДÐ] выполнить команду в командной оболочке\n" " или запуÑтить интерактивную оболочку\n" -#: help.c:305 +#: help.c:308 #, c-format msgid "Variables\n" msgstr "Переменные\n" -#: help.c:306 +#: help.c:309 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr "" " \\prompt [ТЕКСТ] ИМЯ предложить пользователю задать внутреннюю " "переменную\n" -#: help.c:307 +#: help.c:310 #, c-format msgid "" " \\set [NAME [VALUE]] set internal variable, or list all if no " @@ -3063,17 +3166,17 @@ msgstr "" " \\set [ИМЯ [ЗÐÐЧЕÐИЕ]] уÑтановить внутреннюю переменную или вывеÑти вÑе,\n" " еÑли Ð¸Ð¼Ñ Ð½Ðµ задано\n" -#: help.c:308 +#: help.c:311 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset ИМЯ ÑброÑить (удалить) внутреннюю переменную\n" -#: help.c:311 +#: help.c:314 #, c-format msgid "Large Objects\n" msgstr "Большие объекты\n" -#: help.c:312 +#: help.c:315 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -3086,7 +3189,7 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID операции Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð¼Ð¸ объектами\n" -#: help.c:339 +#: help.c:342 #, c-format msgid "" "List of specially treated variables\n" @@ -3095,12 +3198,12 @@ msgstr "" "СпиÑок Ñпециальных переменных\n" "\n" -#: help.c:341 +#: help.c:344 #, c-format msgid "psql variables:\n" msgstr "Переменные psql:\n" -#: help.c:343 +#: help.c:346 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -3111,198 +3214,317 @@ msgstr "" " или \\set ИМЯ ЗÐÐЧЕÐИЕ в приглашении psql\n" "\n" -#: help.c:345 +#: help.c:348 #, c-format msgid "" -" AUTOCOMMIT if set, successful SQL commands are automatically " -"committed\n" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" msgstr "" -" AUTOCOMMIT еÑли уÑтановлен, уÑпешные SQL-команды фикÑируютÑÑ " -"автоматичеÑки\n" +" AUTOCOMMIT\n" +" еÑли уÑтановлен, уÑпешные SQL-команды фикÑируютÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки\n" -#: help.c:346 +#: help.c:350 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" COMP_KEYWORD_CASE определÑет региÑтр Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов " -"SQL\n" +" COMP_KEYWORD_CASE\n" +" определÑет региÑтр Ð´Ð»Ñ Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов SQL\n" " [lower (нижний), upper (верхний),\n" " preserve-lower (ÑохранÑть нижний),\n" " preserve-upper (ÑохранÑть верхний)]\n" -#: help.c:348 +#: help.c:353 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME Ð¸Ð¼Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ подключённой базы данных\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" Ð¸Ð¼Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ подключённой базы данных\n" -#: help.c:349 +#: help.c:355 #, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" -" ECHO определÑет, что выдаётÑÑ Ð½Ð° Ñтандартный вывод\n" -" [all (вÑÑ‘), errors (ошибки), none (ничего),\n" -" queries (запроÑÑ‹)]\n" +" ECHO\n" +" определÑет, что выдаётÑÑ Ð½Ð° Ñтандартный вывод\n" +" [all (вÑÑ‘), errors (ошибки), none (ничего),\n" +" queries (запроÑÑ‹)]\n" -#: help.c:351 +#: help.c:358 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash " -"commands;\n" -" if set to \"noexec\", just show without execution\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" -" ECHO_HIDDEN еÑли уÑтановлено, выводит внутренние запроÑÑ‹, " -"порождаемые командами Ñ \\;\n" -" еÑли уÑтановлено значение \"noexec\", они выводÑÑ‚ÑÑ, но " -"не выполнÑÑŽÑ‚ÑÑ\n" +" ECHO_HIDDEN\n" +" еÑли включено, выводит внутренние запроÑÑ‹, порождаемые командами Ñ \\;\n" +" еÑли уÑтановлено значение \"noexec\", они выводÑÑ‚ÑÑ, но не выполнÑÑŽÑ‚ÑÑ\n" -#: help.c:353 +#: help.c:361 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° клиентÑкого набора Ñимволов\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²ÐºÐ° клиентÑкого набора Ñимволов\n" -#: help.c:354 +#: help.c:363 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a " -"time\n" -" (default: 0=unlimited)\n" +" ERROR\n" +" true if last query failed, else false\n" msgstr "" -" FETCH_COUNT чиÑло результирующих Ñтрок, извлекаемых и отображаемых " -"за раз\n" -" (по умолчанию: 0=без ограничений)\n" +" ERROR\n" +" true в Ñлучае ошибки в поÑледнем запроÑе, иначе — false\n" -#: help.c:356 +#: help.c:365 #, c-format msgid "" -" HISTCONTROL controls command history [ignorespace, ignoredups, " -"ignoreboth]\n" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = " +"unlimited)\n" msgstr "" -" HISTCONTROL управлÑет иÑторией команд [ignorespace (игнорировать " -"пробелы),\n" -" ignoredups (игнорировать дубли), ignoreboth (и то, и " -"другое)]\n" +" FETCH_COUNT\n" +" чиÑло результирующих Ñтрок, извлекаемых и отображаемых за раз\n" +" (0 = без ограничений)\n" -#: help.c:357 +#: help.c:367 #, c-format -msgid " HISTFILE file name used to store the command history\n" +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" msgstr "" -" HISTFILE Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°, в котором будет ÑохранÑтьÑÑ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´\n" +" HISTCONTROL\n" +" управлÑет иÑторией команд [ignorespace (игнорировать пробелы),\n" +" ignoredups (игнорировать дубли), ignoreboth (и то, и другое)]\n" -#: help.c:358 +#: help.c:369 #, c-format msgid "" -" HISTSIZE max number of commands to store in the command history\n" -msgstr " HISTSIZE макÑ. чиÑло команд, ÑохранÑемых в иÑтории\n" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°, в котором будет ÑохранÑтьÑÑ Ð¸ÑÑ‚Ð¾Ñ€Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´\n" -#: help.c:359 +#: help.c:371 #, c-format -msgid " HOST the currently connected database server host\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" msgstr "" -" HOST Ñервер баз данных, к которому уÑтановлено подключение\n" +" HISTSIZE\n" +" макÑимальное чиÑло команд, ÑохранÑемых в иÑтории\n" -#: help.c:360 +#: help.c:373 #, c-format msgid "" -" IGNOREEOF number of EOFs needed to terminate an interactive " -"session\n" +" HOST\n" +" the currently connected database server host\n" msgstr "" -" IGNOREEOF количеÑтво EOF Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾Ð³Ð¾ ÑеанÑа\n" +" HOST\n" +" Ñервер баз данных, к которому уÑтановлено подключение\n" -#: help.c:361 +#: help.c:375 #, c-format -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID значение поÑледнего задейÑтвованного OID\n" +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" количеÑтво EOF Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾Ð³Ð¾ ÑеанÑа\n" -#: help.c:362 +#: help.c:377 #, c-format msgid "" -" ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses " -"implicit savepoints)\n" +" LASTOID\n" +" value of the last affected OID\n" msgstr "" -" ON_ERROR_ROLLBACK еÑли уÑтановлено, Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð½Ðµ прекращаетÑÑ Ð¿Ñ€Ð¸ ошибке " -"(иÑпользуютÑÑ Ð½ÐµÑвные точки ÑохранениÑ)\n" +" LASTOID\n" +" значение поÑледнего задейÑтвованного OID\n" -#: help.c:363 +#: help.c:379 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if " +"none\n" msgstr "" -" ON_ERROR_STOP оÑтанавливать выполнение пакета команд поÑле ошибки\n" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" Ñообщение и код SQLSTATE поÑледней ошибки, либо пуÑÑ‚Ð°Ñ Ñтрока и " +"\"00000\",\n" +" еÑли ошибки не было\n" -#: help.c:364 +#: help.c:382 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT порт Ñервера Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑоединениÑ\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" еÑли уÑтановлено, Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ Ð½Ðµ прекращаетÑÑ Ð¿Ñ€Ð¸ ошибке\n" +" (иÑпользуютÑÑ Ð½ÐµÑвные точки ÑохранениÑ)\n" -#: help.c:365 +#: help.c:384 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 уÑтанавливает Ñтандартное приглашение psql\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" оÑтанавливать выполнение пакета команд поÑле ошибки\n" -#: help.c:366 +#: help.c:386 #, c-format msgid "" -" PROMPT2 specifies the prompt used when a statement continues " -"from a previous line\n" +" PORT\n" +" server port of the current connection\n" msgstr "" -" PROMPT2 уÑтанавливает приглашение, которое выводитÑÑ Ð¿Ñ€Ð¸ " -"переноÑе оператора на новую Ñтроку\n" +" PORT\n" +" порт Ñервера Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ ÑоединениÑ\n" -#: help.c:367 +#: help.c:388 #, c-format msgid "" -" PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" +" PROMPT1\n" +" specifies the standard psql prompt\n" msgstr "" -" PROMPT3 уÑтанавливает Ð¿Ñ€Ð¸Ð³Ð»Ð°ÑˆÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ COPY ... FROM " -"STDIN\n" +" PROMPT1\n" +" уÑтанавливает Ñтандартное приглашение psql\n" -#: help.c:368 +#: help.c:390 #, c-format -msgid " QUIET run quietly (same as -q option)\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous " +"line\n" msgstr "" -" QUIET выводить минимум Ñообщений (как и Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -q)\n" +" PROMPT2\n" +" уÑтанавливает приглашение, которое выводитÑÑ Ð¿Ñ€Ð¸ переноÑе оператора\n" +" на новую Ñтроку\n" -#: help.c:369 +#: help.c:392 #, c-format msgid "" -" SHOW_CONTEXT controls display of message context fields [never, " -"errors, always]\n" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" msgstr "" -" SHOW_CONTEXT управлÑет отображением полей контекÑта Ñообщений " -"[never, errors, always]\n" +" PROMPT3\n" +" уÑтанавливает приглашение Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ COPY ... FROM STDIN\n" -#: help.c:370 +#: help.c:394 #, c-format msgid "" -" SINGLELINE end of line terminates SQL command mode (same as -S " -"option)\n" +" QUIET\n" +" run quietly (same as -q option)\n" msgstr "" -" SINGLELINE конец Ñтроки завершает режим ввода SQL-команды (как и Ñ " -"параметром -S)\n" +" QUIET\n" +" выводить минимум Ñообщений (как и Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -q)\n" -#: help.c:371 +#: help.c:396 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP пошаговый режим (как и Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -s)\n" +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" чиÑло Ñтрок, возвращённых или обработанных поÑледним SQL-запроÑом, либо " +"0\n" -#: help.c:372 +#: help.c:398 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER текущий пользователь, подключённый к БД\n" +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" верÑÐ¸Ñ Ñервера (в коротком текÑтовом и чиÑловом формате)\n" -#: help.c:373 +#: help.c:401 #, c-format msgid "" -" VERBOSITY controls verbosity of error reports [default, verbose, " -"terse]\n" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" msgstr "" -" VERBOSITY управлÑет детализацией отчётов об ошибке [default (по " -"умолчанию), verbose (подробно), terse (кратко)]\n" +" SHOW_CONTEXT\n" +" управлÑет отображением полей контекÑта Ñообщений\n" +" [never (не отображать никогда), errors (ошибки), always (вÑегда]\n" -#: help.c:375 +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" еÑли уÑтановлено, конец Ñтроки завершает режим ввода SQL-команды\n" +" (как и Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -S)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" пошаговый режим (как и Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð¾Ð¼ -s)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE поÑледнего запроÑа или \"00000\", еÑли он выполнилÑÑ Ð±ÐµÐ· " +"ошибок\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" текущий пользователь, подключённый к БД\n" + +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" управлÑет детализацией отчётов об ошибках [default (по умолчанию),\n" +" verbose (подробно), terse (кратко)]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" верÑÐ¸Ñ psql (в развёрнутом, в коротком текÑтовом и в чиÑловом формате)\n" + +#: help.c:418 #, c-format msgid "" "\n" @@ -3311,7 +3533,7 @@ msgstr "" "\n" "Параметры отображениÑ:\n" -#: help.c:377 +#: help.c:420 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3322,153 +3544,171 @@ msgstr "" " или \\pset ИМЯ [ЗÐÐЧЕÐИЕ] в приглашении psql\n" "\n" -#: help.c:379 +#: help.c:422 #, c-format -msgid " border border style (number)\n" -msgstr " border Ñтиль границы (чиÑло)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" Ñтиль границы (чиÑло)\n" -#: help.c:380 +#: help.c:424 #, c-format -msgid " columns target width for the wrapped format\n" -msgstr " columns Ñ†ÐµÐ»ÐµÐ²Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" Ñ†ÐµÐ»ÐµÐ²Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом\n" -#: help.c:381 +#: help.c:426 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" msgstr "" -" expanded (или x) раÑширенный вывод [on (вкл.), off (выкл.), auto " -"(авто)]\n" +" expanded (или x)\n" +" раÑширенный вывод [on (вкл.), off (выкл.), auto (авто)]\n" -#: help.c:382 +#: help.c:428 #, c-format msgid "" -" fieldsep field separator for unaligned output (default \"%s\")\n" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" msgstr "" -" fieldsep разделитель полей Ð´Ð»Ñ Ð½ÐµÑ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ вывода (по " -"умолчанию \"%s\")\n" +" fieldsep\n" +" разделитель полей Ð´Ð»Ñ Ð½ÐµÑ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ вывода (по умолчанию \"%s\")\n" -#: help.c:383 +#: help.c:431 #, c-format msgid "" -" fieldsep_zero set field separator for unaligned output to zero byte\n" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" msgstr "" -" fieldsep_zero уÑтанавливает ноль разделителем полей при " -"неформатированном выводе\n" +" fieldsep_zero\n" +" уÑтанавливает ноль разделителем полей при неформатированном выводе\n" -#: help.c:384 +#: help.c:433 #, c-format msgid "" -" footer enable or disable display of the table footer [on, " -"off]\n" +" footer\n" +" enable or disable display of the table footer [on, off]\n" msgstr "" -" footer включает или выключает вывод подпиÑей таблицы [on " -"(вкл.), off (выкл.)]\n" +" footer\n" +" включает или выключает вывод подпиÑей таблицы [on (вкл.), off (выкл.)]\n" -#: help.c:385 +#: help.c:435 #, c-format msgid "" -" format set output format [unaligned, aligned, wrapped, html, " -"asciidoc, ...]\n" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" msgstr "" -" format уÑтанавливает формат вывода [unaligned " -"(неформатированный), aligned (выровненный), wrapped (Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом), html, " -"asciidoc, ...]\n" +" format\n" +" уÑтанавливает формат вывода [unaligned (неформатированный),\n" +"\n" +" aligned (выровненный), wrapped (Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом), html, asciidoc, ...]\n" -#: help.c:386 +#: help.c:437 #, c-format msgid "" -" linestyle set the border line drawing style [ascii, old-ascii, " -"unicode]\n" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" msgstr "" -" linestyle задаёт Ñтиль риÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ð½Ð¸Ð¹ границы [ascii, old-ascii, " -"unicode]\n" +" linestyle\n" +" задаёт Ñтиль риÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ð½Ð¸Ð¹ границы [ascii, old-ascii, unicode]\n" -#: help.c:387 +#: help.c:439 #, c-format msgid "" -" null set the string to be printed in place of a null value\n" +" null\n" +" set the string to be printed in place of a null value\n" msgstr "" -" null уÑтанавливает Ñтроку, выводимую вмеÑто Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NULL\n" +" null\n" +" уÑтанавливает Ñтроку, выводимую вмеÑто Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ NULL\n" -#: help.c:388 +#: help.c:441 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific " -"character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of " +"digits\n" msgstr "" -" numericlocale включает или отключает вывод заданного локалью " -"разделителÑ\n" -" группы цифр [on (вкл.), off (выкл.)]\n" +" numericlocale\n" +" отключает вывод заданного локалью Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ñ‹ цифр\n" -#: help.c:390 +#: help.c:443 #, c-format msgid "" -" pager control when an external pager is used [yes, no, " -"always]\n" +" pager\n" +" control when an external pager is used [yes, no, always]\n" msgstr "" -" pager определÑет, иÑпользуетÑÑ Ð»Ð¸ внешний " -"поÑтраничник [yes (да), no (нет), always (вÑегда)]\n" +" pager\n" +" определÑет, иÑпользуетÑÑ Ð»Ð¸ внешний поÑтраничник\n" +" [yes (да), no (нет), always (вÑегда)]\n" -#: help.c:391 +#: help.c:445 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" msgstr "" -" recordsep разделитель запиÑей (Ñтрок) при неформатированном " -"выводе\n" +" recordsep\n" +" разделитель запиÑей (Ñтрок) при неформатированном выводе\n" -#: help.c:392 +#: help.c:447 #, c-format msgid "" -" recordsep_zero set record separator for unaligned output to zero byte\n" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" msgstr "" -" recordsep_zero уÑтанавливает ноль разделителем запиÑей при " -"неформатированном выводе\n" +" recordsep_zero\n" +" уÑтанавливает ноль разделителем запиÑей при неформатированном выводе\n" -#: help.c:393 +#: help.c:449 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or " -"proportional\n" -" column widths for left-aligned data types in latex-" -"longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (или T) задаёт атрибуты Ð´Ð»Ñ Ñ‚ÐµÐ³Ð° table в формате html или " -"пропорциональные\n" -" ширины Ñтолбцов Ð´Ð»Ñ Ð²Ñ‹Ñ€Ð¾Ð²Ð½ÐµÐ½Ð½Ñ‹Ñ… влево данных, в формате " -"latex-longtable\n" +" tableattr (или T)\n" +" задаёт атрибуты Ð´Ð»Ñ Ñ‚ÐµÐ³Ð° table в формате html или пропорциональные\n" +" ширины Ñтолбцов Ð´Ð»Ñ Ð²Ñ‹Ñ€Ð¾Ð²Ð½ÐµÐ½Ð½Ñ‹Ñ… влево данных, в формате latex-longtable\n" -#: help.c:395 +#: help.c:452 #, c-format msgid "" -" title set the table title for any subsequently printed " -"tables\n" +" title\n" +" set the table title for subsequently printed tables\n" msgstr "" -" title задаёт заголовок таблицы Ð´Ð»Ñ Ð¿Ð¾Ñледовательно печатаемых " -"таблиц\n" +" title\n" +" задаёт заголовок таблицы Ð´Ð»Ñ Ð¿Ð¾Ñледовательно печатаемых таблиц\n" -#: help.c:396 +#: help.c:454 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" msgstr "" -" tuples_only еÑли уÑтановлено, выводÑÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ непоÑредÑтвенно " -"табличные данные\n" +" tuples_only\n" +" еÑли уÑтановлено, выводÑÑ‚ÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ непоÑредÑтвенно табличные данные\n" -#: help.c:397 +#: help.c:456 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" задаёт Ñтиль риÑуемых линий Unicode [single " -"(одинарные), double (двойные)]\n" +" задаёт Ñтиль риÑуемых линий Unicode [single (одинарные), double " +"(двойные)]\n" -#: help.c:402 +#: help.c:461 #, c-format msgid "" "\n" @@ -3477,7 +3717,7 @@ msgstr "" "\n" "Переменные окружениÑ:\n" -#: help.c:406 +#: help.c:465 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3488,7 +3728,7 @@ msgstr "" " или \\setenv ИМЯ [ЗÐÐЧЕÐИЕ] в приглашении psql\n" "\n" -#: help.c:408 +#: help.c:467 #, c-format msgid "" " set NAME=VALUE\n" @@ -3501,101 +3741,146 @@ msgstr "" " или \\setenv ИМЯ ЗÐÐЧЕÐИЕ в приглашении psql\n" "\n" -#: help.c:411 -#, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS чиÑло Ñтолбцов Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом\n" - -#: help.c:412 +#: help.c:470 #, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ внешнего поÑтраничника\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" чиÑло Ñтолбцов Ð´Ð»Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñом\n" -#: help.c:413 +#: help.c:472 #, c-format msgid "" -" PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ application_name\n" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ application_name\n" -#: help.c:414 +#: help.c:474 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ dbname\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ dbname\n" -#: help.c:415 +#: help.c:476 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ host\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ host\n" -#: help.c:416 +#: help.c:478 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ port\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (иÑпользовать не рекомендуетÑÑ)\n" -#: help.c:417 +#: help.c:480 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ user\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼\n" -#: help.c:418 +#: help.c:482 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" msgstr "" -" PGPASSWORD пароль Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ (иÑпользовать не рекомендуетÑÑ)\n" +" PGPORT\n" +" Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ port\n" -#: help.c:419 +#: help.c:484 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ñ Ð¿Ð°Ñ€Ð¾Ð»ÐµÐ¼\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" Ñиноним параметра Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ user\n" -#: help.c:420 +#: help.c:486 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" редактор, вызываемый командами \\e, \\ef и \\ev\n" +" редактор, вызываемый командами \\e, \\ef и \\ev\n" -#: help.c:422 +#: help.c:488 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" определÑет ÑпоÑоб передачи номера Ñтроки при вызове " -"редактора\n" +" определÑет ÑпоÑоб передачи номера Ñтроки при вызове редактора\n" -#: help.c:424 +#: help.c:490 #, c-format msgid "" -" PSQL_HISTORY alternative location for the command history file\n" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" msgstr "" -" PSQL_HISTORY альтернативное размещение файла Ñ Ð¸Ñторией команд\n" +" PSQL_HISTORY\n" +" альтернативное размещение файла Ñ Ð¸Ñторией команд\n" -#: help.c:425 +#: help.c:492 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" msgstr "" -" PSQLRC альтернативное Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÑкого файла ." -"psqlrc\n" +" PSQL_PAGER, PAGER\n" +" Ð¸Ð¼Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ñ‹ внешнего поÑтраничника\n" -#: help.c:426 +#: help.c:494 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" альтернативное размещение пользовательÑкого файла .psqlrc\n" + +#: help.c:496 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL оболочка, Ð²Ñ‹Ð·Ñ‹Ð²Ð°ÐµÐ¼Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ \\!\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" оболочка, Ð²Ñ‹Ð·Ñ‹Ð²Ð°ÐµÐ¼Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ \\!\n" -#: help.c:427 +#: help.c:498 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR каталог Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" каталог Ð´Ð»Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ñ‹Ñ… файлов\n" -#: help.c:470 +#: help.c:542 msgid "Available help:\n" msgstr "ИмеющаÑÑÑ Ñправка:\n" -#: help.c:554 +#: help.c:626 #, c-format msgid "" "Command: %s\n" @@ -3610,7 +3895,7 @@ msgstr "" "%s\n" "\n" -#: help.c:570 +#: help.c:642 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3676,12 +3961,22 @@ msgstr "" "Чтобы воÑÑтановить базу данных из Ñтого формата, воÑпользуйтеÑÑŒ программой " "командной Ñтроки pg_restore.\n" -#: mainloop.c:225 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "" +"Введите \\? Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки или нажмите Control-C Ð´Ð»Ñ Ð¾Ñ‡Ð¸Ñтки буфера " +"ввода." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Введите \\? Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñправки." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Ð’Ñ‹ иÑпользуете psql - Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¾Ð¹ Ñтроки к PostgreSQL." # skip-rule: copyright -#: mainloop.c:226 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3696,2128 +3991,2234 @@ msgstr "" " \\g или ; в конце Ñтроки - выполнение запроÑа\n" " \\q - выход\n" -#: mainloop.c:339 mainloop.c:476 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Введите \\q Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð°." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Ðажмите Control-D Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð°." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Ðажмите Control-C Ð´Ð»Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð°." + +#: mainloop.c:449 mainloop.c:591 #, c-format msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" msgstr "" "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð³Ð½Ð¾Ñ€Ð¸Ñ€ÑƒÐµÑ‚ÑÑ; добавьте \\endif или нажмите Ctrl-C Ð´Ð»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð¸Ñ " "текущего блока \\if\n" -#: mainloop.c:494 +#: mainloop.c:609 #, c-format msgid "reached EOF without finding closing \\endif(s)\n" msgstr "в закончившемÑÑ Ð¿Ð¾Ñ‚Ð¾ÐºÐµ команд не хватает \\endif\n" -#: psqlscanslash.l:614 +#: psqlscanslash.l:637 #, c-format msgid "unterminated quoted string\n" msgstr "Ð½ÐµÐ·Ð°Ð²ÐµÑ€ÑˆÑ‘Ð½Ð½Ð°Ñ Ñтрока в кавычках\n" -#: psqlscanslash.l:787 +#: psqlscanslash.l:810 #, c-format msgid "%s: out of memory\n" msgstr "%s: нехватка памÑти\n" -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 -#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 -#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 -#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 -#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 -#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 -#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 -#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 -#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 -#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 -#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 -#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 -#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 -#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:813 -#: sql_help.c:816 sql_help.c:818 sql_help.c:820 sql_help.c:822 sql_help.c:863 -#: sql_help.c:886 sql_help.c:897 sql_help.c:899 sql_help.c:918 sql_help.c:928 -#: sql_help.c:930 sql_help.c:932 sql_help.c:944 sql_help.c:948 sql_help.c:950 -#: sql_help.c:961 sql_help.c:963 sql_help.c:965 sql_help.c:990 sql_help.c:994 -#: sql_help.c:997 sql_help.c:1000 sql_help.c:1002 sql_help.c:1004 -#: sql_help.c:1005 sql_help.c:1092 sql_help.c:1094 sql_help.c:1097 -#: sql_help.c:1100 sql_help.c:1102 sql_help.c:1104 sql_help.c:1107 -#: sql_help.c:1110 sql_help.c:1170 sql_help.c:1172 sql_help.c:1174 -#: sql_help.c:1177 sql_help.c:1198 sql_help.c:1201 sql_help.c:1204 -#: sql_help.c:1207 sql_help.c:1211 sql_help.c:1213 sql_help.c:1215 -#: sql_help.c:1217 sql_help.c:1231 sql_help.c:1234 sql_help.c:1236 -#: sql_help.c:1238 sql_help.c:1248 sql_help.c:1250 sql_help.c:1260 -#: sql_help.c:1262 sql_help.c:1272 sql_help.c:1275 sql_help.c:1297 -#: sql_help.c:1299 sql_help.c:1301 sql_help.c:1304 sql_help.c:1306 -#: sql_help.c:1308 sql_help.c:1311 sql_help.c:1361 sql_help.c:1399 -#: sql_help.c:1402 sql_help.c:1404 sql_help.c:1406 sql_help.c:1408 -#: sql_help.c:1410 sql_help.c:1413 sql_help.c:1453 sql_help.c:1664 -#: sql_help.c:1728 sql_help.c:1747 sql_help.c:1760 sql_help.c:1816 -#: sql_help.c:1822 sql_help.c:1832 sql_help.c:1852 sql_help.c:1877 -#: sql_help.c:1895 sql_help.c:1924 sql_help.c:2017 sql_help.c:2059 -#: sql_help.c:2081 sql_help.c:2101 sql_help.c:2102 sql_help.c:2137 -#: sql_help.c:2157 sql_help.c:2179 sql_help.c:2193 sql_help.c:2214 -#: sql_help.c:2244 sql_help.c:2269 sql_help.c:2315 sql_help.c:2582 -#: sql_help.c:2595 sql_help.c:2612 sql_help.c:2628 sql_help.c:2668 -#: sql_help.c:2720 sql_help.c:2724 sql_help.c:2726 sql_help.c:2732 -#: sql_help.c:2750 sql_help.c:2777 sql_help.c:2812 sql_help.c:2824 -#: sql_help.c:2833 sql_help.c:2877 sql_help.c:2891 sql_help.c:2919 -#: sql_help.c:2927 sql_help.c:2935 sql_help.c:2943 sql_help.c:2951 -#: sql_help.c:2959 sql_help.c:2967 sql_help.c:2975 sql_help.c:2984 -#: sql_help.c:2995 sql_help.c:3003 sql_help.c:3011 sql_help.c:3019 -#: sql_help.c:3027 sql_help.c:3037 sql_help.c:3046 sql_help.c:3055 -#: sql_help.c:3063 sql_help.c:3072 sql_help.c:3080 sql_help.c:3088 -#: sql_help.c:3097 sql_help.c:3105 sql_help.c:3113 sql_help.c:3121 -#: sql_help.c:3129 sql_help.c:3137 sql_help.c:3145 sql_help.c:3153 -#: sql_help.c:3161 sql_help.c:3169 sql_help.c:3177 sql_help.c:3194 -#: sql_help.c:3203 sql_help.c:3211 sql_help.c:3228 sql_help.c:3243 -#: sql_help.c:3510 sql_help.c:3561 sql_help.c:3590 sql_help.c:3598 -#: sql_help.c:4021 sql_help.c:4069 sql_help.c:4210 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 msgid "name" msgstr "имÑ" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1522 -#: sql_help.c:2892 sql_help.c:3815 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 msgid "aggregate_signature" msgstr "Ñигнатура_агр_функции" -#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 -#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 -#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 -#: sql_help.c:789 sql_help.c:864 sql_help.c:888 sql_help.c:898 sql_help.c:931 -#: sql_help.c:951 sql_help.c:964 sql_help.c:1101 sql_help.c:1171 -#: sql_help.c:1214 sql_help.c:1235 sql_help.c:1249 sql_help.c:1261 -#: sql_help.c:1274 sql_help.c:1305 sql_help.c:1362 sql_help.c:1407 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 msgid "new_name" msgstr "новое_имÑ" -#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 -#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 -#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 -#: sql_help.c:817 sql_help.c:900 sql_help.c:929 sql_help.c:949 sql_help.c:962 -#: sql_help.c:1001 sql_help.c:1155 sql_help.c:1173 sql_help.c:1216 -#: sql_help.c:1237 sql_help.c:1300 sql_help.c:1405 sql_help.c:2568 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 msgid "new_owner" msgstr "новый_владелец" -#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 -#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 -#: sql_help.c:774 sql_help.c:933 sql_help.c:966 sql_help.c:1103 sql_help.c:1218 -#: sql_help.c:1239 sql_help.c:1251 sql_help.c:1263 sql_help.c:1307 -#: sql_help.c:1409 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 msgid "new_schema" msgstr "новаÑ_Ñхема" -#: sql_help.c:45 sql_help.c:1578 sql_help.c:2893 sql_help.c:3836 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 msgid "where aggregate_signature is:" msgstr "где Ñигнатура_агр_функции:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 -#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 -#: sql_help.c:522 sql_help.c:527 sql_help.c:1540 sql_help.c:1579 -#: sql_help.c:1582 sql_help.c:1585 sql_help.c:1729 sql_help.c:1748 -#: sql_help.c:1751 sql_help.c:2018 sql_help.c:2894 sql_help.c:2897 -#: sql_help.c:2900 sql_help.c:2985 sql_help.c:3396 sql_help.c:3728 -#: sql_help.c:3821 sql_help.c:3837 sql_help.c:3840 sql_help.c:3843 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 msgid "argmode" msgstr "режим_аргумента" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 -#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 -#: sql_help.c:523 sql_help.c:528 sql_help.c:1541 sql_help.c:1580 -#: sql_help.c:1583 sql_help.c:1586 sql_help.c:1730 sql_help.c:1749 -#: sql_help.c:1752 sql_help.c:2019 sql_help.c:2895 sql_help.c:2898 -#: sql_help.c:2901 sql_help.c:2986 sql_help.c:3822 sql_help.c:3838 -#: sql_help.c:3841 sql_help.c:3844 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 msgid "argname" msgstr "имÑ_аргумента" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 -#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 -#: sql_help.c:524 sql_help.c:529 sql_help.c:1542 sql_help.c:1581 -#: sql_help.c:1584 sql_help.c:1587 sql_help.c:2020 sql_help.c:2896 -#: sql_help.c:2899 sql_help.c:2902 sql_help.c:2987 sql_help.c:3823 -#: sql_help.c:3839 sql_help.c:3842 sql_help.c:3845 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 msgid "argtype" msgstr "тип_аргумента" -#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:814 -#: sql_help.c:858 sql_help.c:946 sql_help.c:1232 sql_help.c:1356 -#: sql_help.c:1384 sql_help.c:1635 sql_help.c:1641 sql_help.c:1927 -#: sql_help.c:1968 sql_help.c:1975 sql_help.c:1984 sql_help.c:2060 -#: sql_help.c:2216 sql_help.c:2245 sql_help.c:2337 sql_help.c:2373 -#: sql_help.c:2597 sql_help.c:2778 sql_help.c:2800 sql_help.c:3263 -#: sql_help.c:3430 +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 msgid "option" msgstr "параметр" -#: sql_help.c:114 sql_help.c:815 sql_help.c:859 sql_help.c:1357 sql_help.c:2061 -#: sql_help.c:2217 sql_help.c:2246 sql_help.c:2374 sql_help.c:2779 +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 msgid "where option can be:" msgstr "где допуÑтимые параметры:" -#: sql_help.c:115 sql_help.c:1859 +#: sql_help.c:114 sql_help.c:2118 msgid "allowconn" msgstr "разр_подключениÑ" -#: sql_help.c:116 sql_help.c:860 sql_help.c:1358 sql_help.c:1860 -#: sql_help.c:2247 sql_help.c:2780 +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 msgid "connlimit" msgstr "предел_подключений" -#: sql_help.c:117 sql_help.c:1861 +#: sql_help.c:116 sql_help.c:2120 msgid "istemplate" msgstr "Ñто_шаблон" -#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1106 sql_help.c:1148 +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "новое_табл_проÑтранÑтво" -#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 -#: sql_help.c:537 sql_help.c:867 sql_help.c:871 sql_help.c:874 sql_help.c:1016 -#: sql_help.c:1019 sql_help.c:1364 sql_help.c:1367 sql_help.c:1369 -#: sql_help.c:2029 sql_help.c:3615 sql_help.c:4010 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 msgid "configuration_parameter" msgstr "параметр_конфигурации" -#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 -#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:868 -#: sql_help.c:947 sql_help.c:1017 sql_help.c:1018 sql_help.c:1130 -#: sql_help.c:1150 sql_help.c:1176 sql_help.c:1233 sql_help.c:1365 -#: sql_help.c:1385 sql_help.c:1928 sql_help.c:1969 sql_help.c:1976 -#: sql_help.c:1985 sql_help.c:2030 sql_help.c:2031 sql_help.c:2089 -#: sql_help.c:2121 sql_help.c:2338 sql_help.c:2471 sql_help.c:2483 -#: sql_help.c:2496 sql_help.c:2532 sql_help.c:2554 sql_help.c:2571 -#: sql_help.c:2598 sql_help.c:2801 sql_help.c:3431 sql_help.c:4011 -#: sql_help.c:4012 +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 msgid "value" msgstr "значение" -#: sql_help.c:198 +#: sql_help.c:197 msgid "target_role" msgstr "целеваÑ_роль" -#: sql_help.c:199 sql_help.c:1911 sql_help.c:2293 sql_help.c:2298 -#: sql_help.c:3378 sql_help.c:3385 sql_help.c:3399 sql_help.c:3405 -#: sql_help.c:3710 sql_help.c:3717 sql_help.c:3731 sql_help.c:3737 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 msgid "schema_name" msgstr "имÑ_Ñхемы" -#: sql_help.c:200 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "предложение_GRANT_или_REVOKE" -#: sql_help.c:201 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "где допуÑтимое предложение_GRANT_или_REVOKE:" -#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 -#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 -#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:878 -#: sql_help.c:1105 sql_help.c:1372 sql_help.c:2064 sql_help.c:2065 -#: sql_help.c:2066 sql_help.c:2067 sql_help.c:2068 sql_help.c:2195 -#: sql_help.c:2250 sql_help.c:2251 sql_help.c:2252 sql_help.c:2253 -#: sql_help.c:2254 sql_help.c:2783 sql_help.c:2784 sql_help.c:2785 -#: sql_help.c:2786 sql_help.c:2787 sql_help.c:3412 sql_help.c:3413 -#: sql_help.c:3414 sql_help.c:3711 sql_help.c:3715 sql_help.c:3718 -#: sql_help.c:3720 sql_help.c:3722 sql_help.c:3724 sql_help.c:3726 -#: sql_help.c:3732 sql_help.c:3734 sql_help.c:3736 sql_help.c:3738 -#: sql_help.c:3740 sql_help.c:3742 sql_help.c:3743 sql_help.c:3744 -#: sql_help.c:4031 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 msgid "role_name" msgstr "имÑ_роли" -#: sql_help.c:237 sql_help.c:451 sql_help.c:1121 sql_help.c:1123 -#: sql_help.c:1401 sql_help.c:1880 sql_help.c:1884 sql_help.c:1988 -#: sql_help.c:1992 sql_help.c:2085 sql_help.c:2467 sql_help.c:2479 -#: sql_help.c:2492 sql_help.c:2500 sql_help.c:2510 sql_help.c:2536 -#: sql_help.c:3461 sql_help.c:3476 sql_help.c:3478 sql_help.c:3896 -#: sql_help.c:3897 sql_help.c:3906 sql_help.c:3947 sql_help.c:3948 -#: sql_help.c:3949 sql_help.c:3950 sql_help.c:3951 sql_help.c:3952 -#: sql_help.c:3985 sql_help.c:3986 sql_help.c:3991 sql_help.c:3996 -#: sql_help.c:4135 sql_help.c:4136 sql_help.c:4145 sql_help.c:4186 -#: sql_help.c:4187 sql_help.c:4188 sql_help.c:4189 sql_help.c:4190 -#: sql_help.c:4191 sql_help.c:4238 sql_help.c:4240 sql_help.c:4273 -#: sql_help.c:4329 sql_help.c:4330 sql_help.c:4339 sql_help.c:4380 -#: sql_help.c:4381 sql_help.c:4382 sql_help.c:4383 sql_help.c:4384 -#: sql_help.c:4385 +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 msgid "expression" msgstr "выражение" -#: sql_help.c:240 +#: sql_help.c:239 msgid "domain_constraint" msgstr "ограничение_домена" -#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 -#: sql_help.c:1098 sql_help.c:1136 sql_help.c:1137 sql_help.c:1138 -#: sql_help.c:1158 sql_help.c:1528 sql_help.c:1530 sql_help.c:1883 -#: sql_help.c:1987 sql_help.c:1991 sql_help.c:2499 sql_help.c:2509 -#: sql_help.c:3473 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 msgid "constraint_name" msgstr "имÑ_ограничениÑ" -#: sql_help.c:245 sql_help.c:1099 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "имÑ_нового_ограничениÑ" -#: sql_help.c:316 sql_help.c:945 +#: sql_help.c:317 sql_help.c:1072 msgid "new_version" msgstr "новаÑ_верÑиÑ" -#: sql_help.c:320 sql_help.c:322 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "Ñлемент_объект" -#: sql_help.c:323 +#: sql_help.c:324 msgid "where member_object is:" msgstr "где Ñлемент_объект:" -#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 -#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 -#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 -#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 -#: sql_help.c:359 sql_help.c:1520 sql_help.c:1525 sql_help.c:1532 -#: sql_help.c:1533 sql_help.c:1534 sql_help.c:1535 sql_help.c:1536 -#: sql_help.c:1537 sql_help.c:1538 sql_help.c:1543 sql_help.c:1545 -#: sql_help.c:1549 sql_help.c:1551 sql_help.c:1555 sql_help.c:1556 -#: sql_help.c:1557 sql_help.c:1560 sql_help.c:1561 sql_help.c:1562 -#: sql_help.c:1563 sql_help.c:1564 sql_help.c:1565 sql_help.c:1566 -#: sql_help.c:1567 sql_help.c:1568 sql_help.c:1569 sql_help.c:1570 -#: sql_help.c:1575 sql_help.c:1576 sql_help.c:3811 sql_help.c:3816 -#: sql_help.c:3817 sql_help.c:3818 sql_help.c:3819 sql_help.c:3825 -#: sql_help.c:3826 sql_help.c:3827 sql_help.c:3828 sql_help.c:3829 -#: sql_help.c:3830 sql_help.c:3831 sql_help.c:3832 sql_help.c:3833 -#: sql_help.c:3834 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 msgid "object_name" msgstr "имÑ_объекта" # well-spelled: агр -#: sql_help.c:325 sql_help.c:1521 sql_help.c:3814 +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 msgid "aggregate_name" msgstr "имÑ_агр_функции" -#: sql_help.c:327 sql_help.c:1523 sql_help.c:1794 sql_help.c:1798 -#: sql_help.c:1800 sql_help.c:2910 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 msgid "source_type" msgstr "иÑходный_тип" -#: sql_help.c:328 sql_help.c:1524 sql_help.c:1795 sql_help.c:1799 -#: sql_help.c:1801 sql_help.c:2911 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 msgid "target_type" msgstr "целевой_тип" -#: sql_help.c:335 sql_help.c:756 sql_help.c:1539 sql_help.c:1796 -#: sql_help.c:1835 sql_help.c:1898 sql_help.c:2138 sql_help.c:2169 -#: sql_help.c:2674 sql_help.c:3395 sql_help.c:3727 sql_help.c:3820 -#: sql_help.c:3925 sql_help.c:3929 sql_help.c:3933 sql_help.c:3936 -#: sql_help.c:4164 sql_help.c:4168 sql_help.c:4172 sql_help.c:4175 -#: sql_help.c:4358 sql_help.c:4362 sql_help.c:4366 sql_help.c:4369 +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 msgid "function_name" msgstr "имÑ_функции" -#: sql_help.c:340 sql_help.c:749 sql_help.c:1546 sql_help.c:2162 +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 msgid "operator_name" msgstr "имÑ_оператора" -#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1547 -#: sql_help.c:2139 sql_help.c:3028 +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 msgid "left_type" msgstr "тип_Ñлева" -#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1548 -#: sql_help.c:2140 sql_help.c:3029 +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 msgid "right_type" msgstr "тип_Ñправа" -#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 -#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 -#: sql_help.c:1550 sql_help.c:1552 sql_help.c:2159 sql_help.c:2180 -#: sql_help.c:2515 sql_help.c:3038 sql_help.c:3047 +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 msgid "index_method" msgstr "метод_индекÑа" -#: sql_help.c:356 sql_help.c:1154 sql_help.c:1571 sql_help.c:2026 -#: sql_help.c:2474 sql_help.c:2641 sql_help.c:3185 sql_help.c:3409 -#: sql_help.c:3741 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "имÑ_процедуры" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +msgid "routine_name" +msgstr "имÑ_подпрограммы" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 msgid "type_name" msgstr "имÑ_типа" -#: sql_help.c:357 sql_help.c:1572 sql_help.c:2025 sql_help.c:2642 -#: sql_help.c:2868 sql_help.c:3186 sql_help.c:3401 sql_help.c:3733 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 msgid "lang_name" msgstr "имÑ_Ñзыка" -#: sql_help.c:360 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "и Ñигнатура_агр_функции:" -#: sql_help.c:383 sql_help.c:1666 sql_help.c:1925 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 msgid "handler_function" msgstr "функциÑ_обработчик" -#: sql_help.c:384 sql_help.c:1926 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "функциÑ_проверки" -#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1093 sql_help.c:1298 -#: sql_help.c:2506 sql_help.c:2507 sql_help.c:2523 sql_help.c:2524 +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 msgid "action" msgstr "дейÑтвие" -#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 -#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 -#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 -#: sql_help.c:660 sql_help.c:662 sql_help.c:927 sql_help.c:1095 sql_help.c:1113 -#: sql_help.c:1117 sql_help.c:1118 sql_help.c:1122 sql_help.c:1124 -#: sql_help.c:1125 sql_help.c:1126 sql_help.c:1128 sql_help.c:1131 -#: sql_help.c:1133 sql_help.c:1400 sql_help.c:1403 sql_help.c:1423 -#: sql_help.c:1527 sql_help.c:1632 sql_help.c:1637 sql_help.c:1651 -#: sql_help.c:1652 sql_help.c:1653 sql_help.c:1966 sql_help.c:1979 -#: sql_help.c:2023 sql_help.c:2084 sql_help.c:2119 sql_help.c:2323 -#: sql_help.c:2349 sql_help.c:2350 sql_help.c:2458 sql_help.c:2466 -#: sql_help.c:2475 sql_help.c:2478 sql_help.c:2487 sql_help.c:2491 -#: sql_help.c:2511 sql_help.c:2513 sql_help.c:2520 sql_help.c:2535 -#: sql_help.c:2552 sql_help.c:2677 sql_help.c:2813 sql_help.c:3380 -#: sql_help.c:3381 sql_help.c:3460 sql_help.c:3475 sql_help.c:3477 -#: sql_help.c:3479 sql_help.c:3712 sql_help.c:3713 sql_help.c:3813 -#: sql_help.c:3956 sql_help.c:4195 sql_help.c:4237 sql_help.c:4239 -#: sql_help.c:4241 sql_help.c:4258 sql_help.c:4261 sql_help.c:4389 +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 msgid "column_name" msgstr "имÑ_Ñтолбца" -#: sql_help.c:436 sql_help.c:646 sql_help.c:1096 +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 msgid "new_column_name" msgstr "новое_имÑ_Ñтолбца" -#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1112 sql_help.c:1314 +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 msgid "where action is one of:" msgstr "где допуÑтимое дейÑтвие:" -#: sql_help.c:443 sql_help.c:448 sql_help.c:919 sql_help.c:1114 sql_help.c:1119 -#: sql_help.c:1316 sql_help.c:1320 sql_help.c:1878 sql_help.c:1967 -#: sql_help.c:2158 sql_help.c:2316 sql_help.c:2459 sql_help.c:2722 -#: sql_help.c:3562 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 msgid "data_type" msgstr "тип_данных" -#: sql_help.c:444 sql_help.c:449 sql_help.c:1115 sql_help.c:1120 -#: sql_help.c:1317 sql_help.c:1321 sql_help.c:1879 sql_help.c:1970 -#: sql_help.c:2086 sql_help.c:2460 sql_help.c:2468 sql_help.c:2480 -#: sql_help.c:2493 sql_help.c:2723 sql_help.c:2729 sql_help.c:3470 +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 msgid "collation" msgstr "правило_Ñортировки" -#: sql_help.c:445 sql_help.c:1116 sql_help.c:1971 sql_help.c:1980 -#: sql_help.c:2461 sql_help.c:2476 sql_help.c:2488 +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 msgid "column_constraint" msgstr "ограничение_Ñтолбца" -#: sql_help.c:455 sql_help.c:656 sql_help.c:1127 +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 msgid "integer" msgstr "целое" -#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1129 -#: sql_help.c:1132 +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "атрибут" -#: sql_help.c:465 sql_help.c:1134 sql_help.c:1972 sql_help.c:1981 -#: sql_help.c:2462 sql_help.c:2477 sql_help.c:2489 +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 msgid "table_constraint" msgstr "ограничение_таблицы" -#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1139 -#: sql_help.c:1140 sql_help.c:1141 sql_help.c:1142 sql_help.c:1573 +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "имÑ_триггера" -#: sql_help.c:472 sql_help.c:473 sql_help.c:1152 sql_help.c:1153 -#: sql_help.c:1973 sql_help.c:1978 sql_help.c:2465 sql_help.c:2486 +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 msgid "parent_table" msgstr "таблица_родитель" -#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1277 sql_help.c:1910 +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 msgid "extension_name" msgstr "имÑ_раÑширениÑ" -#: sql_help.c:532 sql_help.c:2027 +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 msgid "execution_cost" msgstr "ÑтоимоÑть_выполнениÑ" -#: sql_help.c:533 sql_help.c:2028 +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 msgid "result_rows" msgstr "Ñтрок_в_результате" -#: sql_help.c:554 sql_help.c:556 sql_help.c:857 sql_help.c:865 sql_help.c:869 -#: sql_help.c:872 sql_help.c:875 sql_help.c:1355 sql_help.c:1363 -#: sql_help.c:1366 sql_help.c:1368 sql_help.c:1370 sql_help.c:2294 -#: sql_help.c:2296 sql_help.c:2299 sql_help.c:2300 sql_help.c:3379 -#: sql_help.c:3383 sql_help.c:3386 sql_help.c:3388 sql_help.c:3390 -#: sql_help.c:3392 sql_help.c:3394 sql_help.c:3400 sql_help.c:3402 -#: sql_help.c:3404 sql_help.c:3406 sql_help.c:3408 sql_help.c:3410 +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 msgid "role_specification" msgstr "указание_роли" -#: sql_help.c:555 sql_help.c:557 sql_help.c:1382 sql_help.c:1853 -#: sql_help.c:2302 sql_help.c:2798 sql_help.c:3219 sql_help.c:4041 +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 msgid "user_name" msgstr "имÑ_пользователÑ" -#: sql_help.c:558 sql_help.c:877 sql_help.c:1371 sql_help.c:2301 -#: sql_help.c:3411 +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 msgid "where role_specification can be:" msgstr "где допуÑтимое указание_роли:" -#: sql_help.c:560 +#: sql_help.c:569 msgid "group_name" msgstr "имÑ_группы" -#: sql_help.c:578 sql_help.c:1858 sql_help.c:2090 sql_help.c:2122 -#: sql_help.c:2472 sql_help.c:2484 sql_help.c:2497 sql_help.c:2533 -#: sql_help.c:2555 sql_help.c:2567 sql_help.c:3407 sql_help.c:3739 +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 msgid "tablespace_name" msgstr "табл_проÑтранÑтво" -#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1149 -#: sql_help.c:1151 sql_help.c:2088 sql_help.c:2120 sql_help.c:2470 -#: sql_help.c:2482 sql_help.c:2495 sql_help.c:2531 sql_help.c:2553 +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "имÑ_индекÑа" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 msgid "storage_parameter" msgstr "параметр_хранениÑ" -#: sql_help.c:608 sql_help.c:1544 sql_help.c:3824 +#: sql_help.c:601 +msgid "column_number" +msgstr "номер_Ñтолбца" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 msgid "large_object_oid" msgstr "oid_большого_объекта" -#: sql_help.c:663 sql_help.c:1147 sql_help.c:1156 sql_help.c:1159 -#: sql_help.c:1463 -msgid "index_name" -msgstr "имÑ_индекÑа" - -#: sql_help.c:695 sql_help.c:2143 +#: sql_help.c:712 sql_help.c:2402 msgid "res_proc" msgstr "процедура_ограничениÑ" -#: sql_help.c:696 sql_help.c:2144 +#: sql_help.c:713 sql_help.c:2403 msgid "join_proc" msgstr "процедура_ÑоединениÑ" -#: sql_help.c:748 sql_help.c:760 sql_help.c:2161 +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 msgid "strategy_number" msgstr "номер_Ñтратегии" -#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 -#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2163 sql_help.c:2164 -#: sql_help.c:2167 sql_help.c:2168 +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 msgid "op_type" msgstr "тип_операции" -#: sql_help.c:752 sql_help.c:2165 +#: sql_help.c:769 sql_help.c:2424 msgid "sort_family_name" msgstr "ÑемейÑтво_Ñортировки" -#: sql_help.c:753 sql_help.c:763 sql_help.c:2166 +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 msgid "support_number" msgstr "номер_опорной_процедуры" -#: sql_help.c:757 sql_help.c:1797 sql_help.c:2170 sql_help.c:2644 -#: sql_help.c:2646 +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 msgid "argument_type" msgstr "тип_аргумента" -#: sql_help.c:788 sql_help.c:791 sql_help.c:819 sql_help.c:821 sql_help.c:823 -#: sql_help.c:887 sql_help.c:926 sql_help.c:1273 sql_help.c:1276 -#: sql_help.c:1422 sql_help.c:1462 sql_help.c:1529 sql_help.c:1554 -#: sql_help.c:1559 sql_help.c:1574 sql_help.c:1631 sql_help.c:1636 -#: sql_help.c:1965 sql_help.c:1977 sql_help.c:2082 sql_help.c:2118 -#: sql_help.c:2194 sql_help.c:2215 sql_help.c:2271 sql_help.c:2322 -#: sql_help.c:2351 sql_help.c:2457 sql_help.c:2473 sql_help.c:2485 -#: sql_help.c:2551 sql_help.c:2670 sql_help.c:2847 sql_help.c:3064 -#: sql_help.c:3089 sql_help.c:3195 sql_help.c:3377 sql_help.c:3382 -#: sql_help.c:3427 sql_help.c:3458 sql_help.c:3709 sql_help.c:3714 -#: sql_help.c:3812 sql_help.c:3911 sql_help.c:3913 sql_help.c:3962 -#: sql_help.c:4001 sql_help.c:4150 sql_help.c:4152 sql_help.c:4201 -#: sql_help.c:4235 sql_help.c:4257 sql_help.c:4259 sql_help.c:4260 -#: sql_help.c:4344 sql_help.c:4346 sql_help.c:4395 +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 msgid "table_name" msgstr "имÑ_таблицы" -#: sql_help.c:793 sql_help.c:2196 +#: sql_help.c:810 sql_help.c:2455 msgid "using_expression" msgstr "выражение_иÑпользованиÑ" -#: sql_help.c:794 sql_help.c:2197 +#: sql_help.c:811 sql_help.c:2456 msgid "check_expression" msgstr "выражение_проверки" -#: sql_help.c:861 sql_help.c:1359 sql_help.c:2062 sql_help.c:2248 -#: sql_help.c:2781 +#: sql_help.c:885 sql_help.c:2497 +msgid "publication_parameter" +msgstr "параметр_публикации" + +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 msgid "password" msgstr "пароль" -#: sql_help.c:862 sql_help.c:1360 sql_help.c:2063 sql_help.c:2249 -#: sql_help.c:2782 +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 msgid "timestamp" msgstr "timestamp" -#: sql_help.c:866 sql_help.c:870 sql_help.c:873 sql_help.c:876 sql_help.c:3387 -#: sql_help.c:3719 +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 msgid "database_name" msgstr "имÑ_БД" -#: sql_help.c:920 sql_help.c:2317 +#: sql_help.c:1047 sql_help.c:2598 msgid "increment" msgstr "шаг" -#: sql_help.c:921 sql_help.c:2318 +#: sql_help.c:1048 sql_help.c:2599 msgid "minvalue" msgstr "мин_значение" -#: sql_help.c:922 sql_help.c:2319 +#: sql_help.c:1049 sql_help.c:2600 msgid "maxvalue" msgstr "макÑ_значение" -#: sql_help.c:923 sql_help.c:2320 sql_help.c:3909 sql_help.c:3999 -#: sql_help.c:4148 sql_help.c:4277 sql_help.c:4342 +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 msgid "start" msgstr "начальное_значение" -#: sql_help.c:924 +#: sql_help.c:1051 sql_help.c:1295 msgid "restart" msgstr "значение_перезапуÑка" -#: sql_help.c:925 sql_help.c:2321 +#: sql_help.c:1052 sql_help.c:2602 msgid "cache" msgstr "кеш" -#: sql_help.c:991 -msgid "suboption" -msgstr "подпараметр" - -#: sql_help.c:992 -msgid "where suboption can be:" -msgstr "где допуÑтимые подпараметры:" - -#: sql_help.c:993 sql_help.c:2375 -msgid "slot_name" -msgstr "имÑ_Ñлота" +#: sql_help.c:1109 sql_help.c:2646 +msgid "conninfo" +msgstr "Ñтрока_подключениÑ" -#: sql_help.c:995 sql_help.c:2372 +#: sql_help.c:1111 sql_help.c:2647 msgid "publication_name" msgstr "имÑ_публикации" -#: sql_help.c:996 sql_help.c:998 -msgid "puboption" -msgstr "параметр_публикации" +#: sql_help.c:1112 +msgid "set_publication_option" +msgstr "параметр_set_publication" -#: sql_help.c:999 -msgid "where puboption can be:" -msgstr "где допуÑтимый параметр_публикации:" +#: sql_help.c:1115 +msgid "refresh_option" +msgstr "параметр_обновлениÑ" -#: sql_help.c:1003 sql_help.c:2371 -msgid "conninfo" -msgstr "Ñтрока_подключениÑ" +#: sql_help.c:1120 sql_help.c:2648 +msgid "subscription_parameter" +msgstr "параметр_подпиÑки" -#: sql_help.c:1108 sql_help.c:1111 +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" msgstr "имÑ_Ñекции" -#: sql_help.c:1109 sql_help.c:1982 sql_help.c:2490 +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 msgid "partition_bound_spec" msgstr "указание_границ_Ñекции" -#: sql_help.c:1135 +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 +msgid "sequence_options" +msgstr "параметры_поÑледовательноÑти" + +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "параметр_поÑледовательноÑти" + +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "ограничение_таблицы_Ñ_индекÑом" -#: sql_help.c:1143 sql_help.c:1144 sql_help.c:1145 sql_help.c:1146 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "имÑ_правила_перезапиÑи" -#: sql_help.c:1157 +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "и указание_границ_Ñекции:" + +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "чиÑловаÑ_конÑтанта" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "ÑтроковаÑ_конÑтанта" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "и ограничение_Ñтолбца:" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "выражение_по_умолчанию" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "параметры_индекÑа" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "целеваÑ_таблица" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "целевой_Ñтолбец" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "и ограничение_таблицы:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "объект_иÑключениÑ" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "оператор" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "предикат" + +#: sql_help.c:1365 msgid "and table_constraint_using_index is:" msgstr "и ограничение_таблицы_Ñ_индекÑом:" -#: sql_help.c:1175 sql_help.c:1178 sql_help.c:2570 +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "параметры_индекÑа в ограничениÑÑ… UNIQUE, PRIMARY KEY и EXCLUDE:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "объект_иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² ограничении EXCLUDE:" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "клаÑÑ_оператора" + +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 msgid "tablespace_option" msgstr "параметр_табл_проÑтранÑтва" -#: sql_help.c:1199 sql_help.c:1202 sql_help.c:1208 sql_help.c:1212 +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 msgid "token_type" msgstr "тип_фрагмента" -#: sql_help.c:1200 sql_help.c:1203 +#: sql_help.c:1417 sql_help.c:1420 msgid "dictionary_name" msgstr "имÑ_ÑловарÑ" -#: sql_help.c:1205 sql_help.c:1209 +#: sql_help.c:1422 sql_help.c:1426 msgid "old_dictionary" msgstr "Ñтарый_Ñловарь" -#: sql_help.c:1206 sql_help.c:1210 +#: sql_help.c:1423 sql_help.c:1427 msgid "new_dictionary" msgstr "новый_Ñловарь" -#: sql_help.c:1302 sql_help.c:1315 sql_help.c:1318 sql_help.c:1319 -#: sql_help.c:2721 +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 msgid "attribute_name" msgstr "имÑ_атрибута" -#: sql_help.c:1303 +#: sql_help.c:1520 msgid "new_attribute_name" msgstr "новое_имÑ_атрибута" -#: sql_help.c:1309 sql_help.c:1313 +#: sql_help.c:1526 sql_help.c:1530 msgid "new_enum_value" msgstr "новое_значение_перечиÑлениÑ" -#: sql_help.c:1310 +#: sql_help.c:1527 msgid "neighbor_enum_value" msgstr "ÑоÑеднее_значение_перечиÑлениÑ" -#: sql_help.c:1312 +#: sql_help.c:1529 msgid "existing_enum_value" msgstr "ÑущеÑтвующее_значение_перечиÑлениÑ" -#: sql_help.c:1383 sql_help.c:1974 sql_help.c:1983 sql_help.c:2333 -#: sql_help.c:2799 sql_help.c:3220 sql_help.c:3393 sql_help.c:3428 -#: sql_help.c:3725 +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 msgid "server_name" msgstr "имÑ_Ñервера" -#: sql_help.c:1411 sql_help.c:1414 sql_help.c:2814 +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 msgid "view_option_name" msgstr "имÑ_параметра_предÑтавлениÑ" -#: sql_help.c:1412 sql_help.c:2815 +#: sql_help.c:1633 sql_help.c:3100 msgid "view_option_value" msgstr "значение_параметра_предÑтавлениÑ" -#: sql_help.c:1437 sql_help.c:4057 sql_help.c:4059 sql_help.c:4083 +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "таблица_и_Ñтолбцы" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "где допуÑтимый параметр:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "и таблица_и_Ñтолбцы:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 msgid "transaction_mode" msgstr "режим_транзакции" -#: sql_help.c:1438 sql_help.c:4060 sql_help.c:4084 +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 msgid "where transaction_mode is one of:" msgstr "где допуÑтимый режим_транзакции:" -#: sql_help.c:1526 +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "аргумент" + +#: sql_help.c:1772 msgid "relation_name" msgstr "имÑ_отношениÑ" -#: sql_help.c:1531 sql_help.c:3389 sql_help.c:3721 +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 msgid "domain_name" msgstr "имÑ_домена" -#: sql_help.c:1553 +#: sql_help.c:1799 msgid "policy_name" msgstr "имÑ_политики" -#: sql_help.c:1558 +#: sql_help.c:1812 msgid "rule_name" msgstr "имÑ_правила" -#: sql_help.c:1577 +#: sql_help.c:1831 msgid "text" msgstr "текÑÑ‚" -#: sql_help.c:1602 sql_help.c:3571 sql_help.c:3759 +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 msgid "transaction_id" msgstr "код_транзакции" -#: sql_help.c:1633 sql_help.c:1639 sql_help.c:3497 +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 msgid "filename" msgstr "имÑ_файла" -#: sql_help.c:1634 sql_help.c:1640 sql_help.c:2273 sql_help.c:2274 -#: sql_help.c:2275 +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 msgid "command" msgstr "команда" -#: sql_help.c:1638 sql_help.c:2123 sql_help.c:2556 sql_help.c:2816 -#: sql_help.c:2834 sql_help.c:3462 +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 msgid "query" msgstr "запроÑ" -#: sql_help.c:1642 sql_help.c:3266 -msgid "where option can be one of:" -msgstr "где допуÑтимый параметр:" - -#: sql_help.c:1643 +#: sql_help.c:1897 msgid "format_name" msgstr "имÑ_формата" -#: sql_help.c:1644 sql_help.c:1645 sql_help.c:1648 sql_help.c:3267 -#: sql_help.c:3268 sql_help.c:3269 sql_help.c:3270 sql_help.c:3271 -#: sql_help.c:3272 +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 msgid "boolean" msgstr "логичеÑкое_значение" -#: sql_help.c:1646 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "Ñимвол_разделитель" -#: sql_help.c:1647 +#: sql_help.c:1901 msgid "null_string" msgstr "предÑтавление_NULL" -#: sql_help.c:1649 +#: sql_help.c:1903 msgid "quote_character" msgstr "Ñимвол_кавычек" -#: sql_help.c:1650 +#: sql_help.c:1904 msgid "escape_character" msgstr "ÑпецÑимвол" -#: sql_help.c:1654 +#: sql_help.c:1908 msgid "encoding_name" msgstr "имÑ_кодировки" -#: sql_help.c:1665 +#: sql_help.c:1919 msgid "access_method_type" msgstr "тип_метода_доÑтупа" -#: sql_help.c:1731 sql_help.c:1750 sql_help.c:1753 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "тип_данных_аргумента" -#: sql_help.c:1732 sql_help.c:1754 sql_help.c:1762 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "функциÑ_ÑоÑтоÑниÑ" -#: sql_help.c:1733 sql_help.c:1755 sql_help.c:1763 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "тип_данных_ÑоÑтоÑниÑ" -#: sql_help.c:1734 sql_help.c:1756 sql_help.c:1764 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "размер_данных_ÑоÑтоÑниÑ" -#: sql_help.c:1735 sql_help.c:1757 sql_help.c:1765 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "функциÑ_завершениÑ" -#: sql_help.c:1736 sql_help.c:1766 +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "комбинирующаÑ_функциÑ" -#: sql_help.c:1737 sql_help.c:1767 +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "функциÑ_Ñериализации" -#: sql_help.c:1738 sql_help.c:1768 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "функциÑ_деÑериализации" -#: sql_help.c:1739 sql_help.c:1758 sql_help.c:1769 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "начальное_уÑловие" -#: sql_help.c:1740 sql_help.c:1770 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "функциÑ_ÑоÑтоÑниÑ_движ" -#: sql_help.c:1741 sql_help.c:1771 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "обратнаÑ_функциÑ_движ" -#: sql_help.c:1742 sql_help.c:1772 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "тип_данных_ÑоÑтоÑниÑ_движ" -#: sql_help.c:1743 sql_help.c:1773 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "размер_данных_ÑоÑтоÑниÑ_движ" -#: sql_help.c:1744 sql_help.c:1774 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "функциÑ_завершениÑ_движ" -#: sql_help.c:1745 sql_help.c:1775 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "начальное_уÑловие_движ" -#: sql_help.c:1746 sql_help.c:1776 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "оператор_Ñортировки" -#: sql_help.c:1759 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "или Ñтарый ÑинтакÑиÑ" -#: sql_help.c:1761 +#: sql_help.c:2020 msgid "base_type" msgstr "базовый_тип" -#: sql_help.c:1817 +#: sql_help.c:2076 msgid "locale" msgstr "код_локали" -#: sql_help.c:1818 sql_help.c:1856 +#: sql_help.c:2077 sql_help.c:2115 msgid "lc_collate" msgstr "код_правила_Ñортировки" -#: sql_help.c:1819 sql_help.c:1857 +#: sql_help.c:2078 sql_help.c:2116 msgid "lc_ctype" msgstr "код_клаÑÑификации_Ñимволов" -#: sql_help.c:1820 sql_help.c:3810 +#: sql_help.c:2079 sql_help.c:4122 msgid "provider" msgstr "поÑтавщик" -#: sql_help.c:1821 sql_help.c:1912 +#: sql_help.c:2080 sql_help.c:2171 msgid "version" msgstr "верÑиÑ" -#: sql_help.c:1823 +#: sql_help.c:2082 msgid "existing_collation" msgstr "ÑущеÑтвующее_правило_Ñортировки" -#: sql_help.c:1833 +#: sql_help.c:2092 msgid "source_encoding" msgstr "иÑходнаÑ_кодировка" -#: sql_help.c:1834 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "целеваÑ_кодировка" -#: sql_help.c:1854 sql_help.c:2596 +#: sql_help.c:2113 sql_help.c:2881 msgid "template" msgstr "шаблон" -#: sql_help.c:1855 +#: sql_help.c:2114 msgid "encoding" msgstr "кодировка" -#: sql_help.c:1881 +#: sql_help.c:2140 msgid "constraint" msgstr "ограничение" -#: sql_help.c:1882 +#: sql_help.c:2141 msgid "where constraint is:" msgstr "где ограничение:" -#: sql_help.c:1896 sql_help.c:2270 sql_help.c:2669 +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 msgid "event" msgstr "Ñобытие" -#: sql_help.c:1897 +#: sql_help.c:2156 msgid "filter_variable" msgstr "переменнаÑ_фильтра" -#: sql_help.c:1913 +#: sql_help.c:2172 msgid "old_version" msgstr "ÑтараÑ_верÑиÑ" -#: sql_help.c:1986 sql_help.c:2498 +#: sql_help.c:2245 sql_help.c:2776 msgid "where column_constraint is:" msgstr "где ограничение_Ñтолбца:" -#: sql_help.c:1989 sql_help.c:2021 sql_help.c:2501 -msgid "default_expr" -msgstr "выражение_по_умолчанию" - -#: sql_help.c:1990 sql_help.c:2508 -msgid "and table_constraint is:" -msgstr "и ограничение_таблицы:" - -#: sql_help.c:2022 +#: sql_help.c:2280 msgid "rettype" msgstr "тип_возврата" -#: sql_help.c:2024 +#: sql_help.c:2282 msgid "column_type" msgstr "тип_Ñтолбца" -#: sql_help.c:2032 +#: sql_help.c:2290 sql_help.c:2482 msgid "definition" msgstr "определение" -#: sql_help.c:2033 +#: sql_help.c:2291 sql_help.c:2483 msgid "obj_file" msgstr "объектный_файл" -#: sql_help.c:2034 +#: sql_help.c:2292 sql_help.c:2484 msgid "link_symbol" msgstr "Ñимвол_в_ÑкÑпорте" -#: sql_help.c:2035 -msgid "attribute" -msgstr "атрибут" - -#: sql_help.c:2069 sql_help.c:2255 sql_help.c:2788 +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 msgid "uid" msgstr "uid" -#: sql_help.c:2083 +#: sql_help.c:2341 msgid "method" msgstr "метод" -#: sql_help.c:2087 sql_help.c:2469 sql_help.c:2481 sql_help.c:2494 -#: sql_help.c:2537 sql_help.c:3471 -msgid "opclass" -msgstr "клаÑÑ_оператора" - -#: sql_help.c:2091 sql_help.c:2519 -msgid "predicate" -msgstr "предикат" - -#: sql_help.c:2103 +#: sql_help.c:2362 msgid "call_handler" msgstr "обработчик_вызова" -#: sql_help.c:2104 +#: sql_help.c:2363 msgid "inline_handler" msgstr "обработчик_внедрённого_кода" -#: sql_help.c:2105 +#: sql_help.c:2364 msgid "valfunction" msgstr "функциÑ_проверки" -#: sql_help.c:2141 +#: sql_help.c:2400 msgid "com_op" msgstr "коммут_оператор" -#: sql_help.c:2142 +#: sql_help.c:2401 msgid "neg_op" msgstr "обратный_оператор" -#: sql_help.c:2160 +#: sql_help.c:2419 msgid "family_name" msgstr "имÑ_ÑемейÑтва" -#: sql_help.c:2171 +#: sql_help.c:2430 msgid "storage_type" msgstr "тип_хранениÑ" -#: sql_help.c:2272 sql_help.c:2673 sql_help.c:2850 sql_help.c:3481 -#: sql_help.c:3900 sql_help.c:3902 sql_help.c:3990 sql_help.c:3992 -#: sql_help.c:4139 sql_help.c:4141 sql_help.c:4244 sql_help.c:4333 -#: sql_help.c:4335 +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 msgid "condition" msgstr "уÑловие" -#: sql_help.c:2276 sql_help.c:2676 +#: sql_help.c:2557 sql_help.c:2961 msgid "where event can be one of:" msgstr "где допуÑтимое Ñобытие:" -#: sql_help.c:2295 sql_help.c:2297 +#: sql_help.c:2576 sql_help.c:2578 msgid "schema_element" msgstr "Ñлемент_Ñхемы" -#: sql_help.c:2334 +#: sql_help.c:2615 msgid "server_type" msgstr "тип_Ñервера" -#: sql_help.c:2335 +#: sql_help.c:2616 msgid "server_version" msgstr "верÑиÑ_Ñервера" -#: sql_help.c:2336 sql_help.c:3391 sql_help.c:3723 +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 msgid "fdw_name" msgstr "имÑ_обёртки_Ñторонних_данных" -#: sql_help.c:2348 +#: sql_help.c:2630 msgid "statistics_name" msgstr "имÑ_ÑтатиÑтики" -#: sql_help.c:2370 +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "вид_ÑтатиÑтики" + +#: sql_help.c:2645 msgid "subscription_name" msgstr "имÑ_подпиÑки" -#: sql_help.c:2463 +#: sql_help.c:2741 msgid "source_table" msgstr "иÑходнаÑ_таблица" -#: sql_help.c:2464 +#: sql_help.c:2742 msgid "like_option" msgstr "параметр_порождениÑ" -#: sql_help.c:2502 sql_help.c:2503 sql_help.c:2512 sql_help.c:2514 -#: sql_help.c:2518 -msgid "index_parameters" -msgstr "параметры_индекÑа" - -#: sql_help.c:2504 sql_help.c:2521 -msgid "reftable" -msgstr "целеваÑ_таблица" - -#: sql_help.c:2505 sql_help.c:2522 -msgid "refcolumn" -msgstr "целевой_Ñтолбец" - -#: sql_help.c:2516 -msgid "exclude_element" -msgstr "объект_иÑключениÑ" - -#: sql_help.c:2517 sql_help.c:3907 sql_help.c:3997 sql_help.c:4146 -#: sql_help.c:4275 sql_help.c:4340 -msgid "operator" -msgstr "оператор" - -#: sql_help.c:2525 +#: sql_help.c:2804 msgid "and like_option is:" msgstr "и параметр_порождениÑ:" -#: sql_help.c:2526 -msgid "and partition_bound_spec is:" -msgstr "и указание_границ_Ñекции:" - -#: sql_help.c:2527 sql_help.c:2528 sql_help.c:2529 -msgid "bound_literal" -msgstr "конÑтанта_границы" - -#: sql_help.c:2530 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "параметры_индекÑа в ограничениÑÑ… UNIQUE, PRIMARY KEY и EXCLUDE:" - -#: sql_help.c:2534 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "объект_иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð² ограничении EXCLUDE:" - -#: sql_help.c:2569 +#: sql_help.c:2854 msgid "directory" msgstr "каталог" -#: sql_help.c:2583 +#: sql_help.c:2868 msgid "parser_name" msgstr "имÑ_анализатора" -#: sql_help.c:2584 +#: sql_help.c:2869 msgid "source_config" msgstr "иÑходнаÑ_конфигурациÑ" -#: sql_help.c:2613 +#: sql_help.c:2898 msgid "start_function" msgstr "функциÑ_начала" -#: sql_help.c:2614 +#: sql_help.c:2899 msgid "gettoken_function" msgstr "функциÑ_выдачи_фрагмента" -#: sql_help.c:2615 +#: sql_help.c:2900 msgid "end_function" msgstr "функциÑ_окончаниÑ" -#: sql_help.c:2616 +#: sql_help.c:2901 msgid "lextypes_function" msgstr "функциÑ_лекÑ_типов" -#: sql_help.c:2617 +#: sql_help.c:2902 msgid "headline_function" msgstr "функциÑ_ÑозданиÑ_выдержек" -#: sql_help.c:2629 +#: sql_help.c:2914 msgid "init_function" msgstr "функциÑ_инициализации" -#: sql_help.c:2630 +#: sql_help.c:2915 msgid "lexize_function" msgstr "функциÑ_выделениÑ_лекÑем" -#: sql_help.c:2643 +#: sql_help.c:2928 msgid "from_sql_function_name" msgstr "имÑ_функции_из_sql" -#: sql_help.c:2645 +#: sql_help.c:2930 msgid "to_sql_function_name" msgstr "имÑ_функции_в_sql" -#: sql_help.c:2671 +#: sql_help.c:2956 msgid "referenced_table_name" msgstr "ÑÑылающаÑÑÑ_таблица" -#: sql_help.c:2672 +#: sql_help.c:2957 msgid "transition_relation_name" msgstr "имÑ_переходного_отношениÑ" -#: sql_help.c:2675 +#: sql_help.c:2960 msgid "arguments" msgstr "аргументы" -#: sql_help.c:2725 sql_help.c:3835 +#: sql_help.c:3010 sql_help.c:4155 msgid "label" msgstr "метка" -#: sql_help.c:2727 +#: sql_help.c:3012 msgid "subtype" msgstr "подтип" -#: sql_help.c:2728 +#: sql_help.c:3013 msgid "subtype_operator_class" msgstr "клаÑÑ_оператора_подтипа" -#: sql_help.c:2730 +#: sql_help.c:3015 msgid "canonical_function" msgstr "каноничеÑкаÑ_функциÑ" -#: sql_help.c:2731 +#: sql_help.c:3016 msgid "subtype_diff_function" msgstr "функциÑ_различий_подтипа" -#: sql_help.c:2733 +#: sql_help.c:3018 msgid "input_function" msgstr "функциÑ_ввода" -#: sql_help.c:2734 +#: sql_help.c:3019 msgid "output_function" msgstr "функциÑ_вывода" -#: sql_help.c:2735 +#: sql_help.c:3020 msgid "receive_function" msgstr "функциÑ_получениÑ" -#: sql_help.c:2736 +#: sql_help.c:3021 msgid "send_function" msgstr "функциÑ_отправки" -#: sql_help.c:2737 +#: sql_help.c:3022 msgid "type_modifier_input_function" msgstr "функциÑ_ввода_модификатора_типа" -#: sql_help.c:2738 +#: sql_help.c:3023 msgid "type_modifier_output_function" msgstr "функциÑ_вывода_модификатора_типа" -#: sql_help.c:2739 +#: sql_help.c:3024 msgid "analyze_function" msgstr "функциÑ_анализа" -#: sql_help.c:2740 +#: sql_help.c:3025 msgid "internallength" msgstr "внутр_длина" -#: sql_help.c:2741 +#: sql_help.c:3026 msgid "alignment" msgstr "выравнивание" -#: sql_help.c:2742 +#: sql_help.c:3027 msgid "storage" msgstr "хранение" -#: sql_help.c:2743 +#: sql_help.c:3028 msgid "like_type" msgstr "тип_образец" -#: sql_help.c:2744 +#: sql_help.c:3029 msgid "category" msgstr "категориÑ" -#: sql_help.c:2745 +#: sql_help.c:3030 msgid "preferred" msgstr "предпочитаемый" -#: sql_help.c:2746 +#: sql_help.c:3031 msgid "default" msgstr "по_умолчанию" -#: sql_help.c:2747 +#: sql_help.c:3032 msgid "element" msgstr "Ñлемент" -#: sql_help.c:2748 +#: sql_help.c:3033 msgid "delimiter" msgstr "разделитель" -#: sql_help.c:2749 +#: sql_help.c:3034 msgid "collatable" msgstr "Ñортируемый" -#: sql_help.c:2846 sql_help.c:3457 sql_help.c:3895 sql_help.c:3984 -#: sql_help.c:4134 sql_help.c:4234 sql_help.c:4328 +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 msgid "with_query" msgstr "запроÑ_WITH" -#: sql_help.c:2848 sql_help.c:3459 sql_help.c:3914 sql_help.c:3920 -#: sql_help.c:3923 sql_help.c:3927 sql_help.c:3931 sql_help.c:3939 -#: sql_help.c:4153 sql_help.c:4159 sql_help.c:4162 sql_help.c:4166 -#: sql_help.c:4170 sql_help.c:4178 sql_help.c:4236 sql_help.c:4347 -#: sql_help.c:4353 sql_help.c:4356 sql_help.c:4360 sql_help.c:4364 -#: sql_help.c:4372 +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 msgid "alias" msgstr "пÑевдоним" -#: sql_help.c:2849 +#: sql_help.c:3134 msgid "using_list" msgstr "ÑпиÑок_USING" -#: sql_help.c:2851 sql_help.c:3298 sql_help.c:3538 sql_help.c:4245 +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 msgid "cursor_name" msgstr "имÑ_курÑора" -#: sql_help.c:2852 sql_help.c:3465 sql_help.c:4246 +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 msgid "output_expression" msgstr "выражение_результата" -#: sql_help.c:2853 sql_help.c:3466 sql_help.c:3898 sql_help.c:3987 -#: sql_help.c:4137 sql_help.c:4247 sql_help.c:4331 +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 msgid "output_name" msgstr "имÑ_результата" -#: sql_help.c:2869 +#: sql_help.c:3154 msgid "code" msgstr "внедрённый_код" -#: sql_help.c:3244 +#: sql_help.c:3553 msgid "parameter" msgstr "параметр" -#: sql_help.c:3264 sql_help.c:3265 sql_help.c:3563 +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 msgid "statement" msgstr "оператор" -#: sql_help.c:3297 sql_help.c:3537 +#: sql_help.c:3606 sql_help.c:3847 msgid "direction" msgstr "направление" -#: sql_help.c:3299 sql_help.c:3539 +#: sql_help.c:3608 sql_help.c:3849 msgid "where direction can be empty or one of:" msgstr "где допуÑтимое направление пуÑтое или:" -#: sql_help.c:3300 sql_help.c:3301 sql_help.c:3302 sql_help.c:3303 -#: sql_help.c:3304 sql_help.c:3540 sql_help.c:3541 sql_help.c:3542 -#: sql_help.c:3543 sql_help.c:3544 sql_help.c:3908 sql_help.c:3910 -#: sql_help.c:3998 sql_help.c:4000 sql_help.c:4147 sql_help.c:4149 -#: sql_help.c:4276 sql_help.c:4278 sql_help.c:4341 sql_help.c:4343 +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 msgid "count" msgstr "чиÑло" -#: sql_help.c:3384 sql_help.c:3716 +#: sql_help.c:3693 sql_help.c:4026 msgid "sequence_name" msgstr "имÑ_поÑледовательноÑти" -#: sql_help.c:3397 sql_help.c:3729 +#: sql_help.c:3706 sql_help.c:4039 msgid "arg_name" msgstr "имÑ_аргумента" -#: sql_help.c:3398 sql_help.c:3730 +#: sql_help.c:3707 sql_help.c:4040 msgid "arg_type" msgstr "тип_аргумента" -#: sql_help.c:3403 sql_help.c:3735 +#: sql_help.c:3712 sql_help.c:4045 msgid "loid" msgstr "код_БО" -#: sql_help.c:3426 +#: sql_help.c:3735 msgid "remote_schema" msgstr "удалённаÑ_Ñхема" -#: sql_help.c:3429 +#: sql_help.c:3738 msgid "local_schema" msgstr "локальнаÑ_Ñхема" -#: sql_help.c:3463 +#: sql_help.c:3773 msgid "conflict_target" msgstr "объект_конфликта" -#: sql_help.c:3464 +#: sql_help.c:3774 msgid "conflict_action" msgstr "дейÑтвие_при_конфликте" -#: sql_help.c:3467 +#: sql_help.c:3777 msgid "where conflict_target can be one of:" msgstr "где допуÑтимый объект_конфликта:" -#: sql_help.c:3468 +#: sql_help.c:3778 msgid "index_column_name" msgstr "имÑ_Ñтолбца_индекÑа" -#: sql_help.c:3469 +#: sql_help.c:3779 msgid "index_expression" msgstr "выражение_индекÑа" -#: sql_help.c:3472 +#: sql_help.c:3782 msgid "index_predicate" msgstr "предикат_индекÑа" -#: sql_help.c:3474 +#: sql_help.c:3784 msgid "and conflict_action is one of:" msgstr "а допуÑтимое дейÑтвие_при_конфликте:" -#: sql_help.c:3480 sql_help.c:4242 +#: sql_help.c:3790 sql_help.c:4562 msgid "sub-SELECT" msgstr "вложенный_SELECT" -#: sql_help.c:3489 sql_help.c:3552 sql_help.c:4218 +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 msgid "channel" msgstr "канал" -#: sql_help.c:3511 +#: sql_help.c:3821 msgid "lockmode" msgstr "режим_блокировки" -#: sql_help.c:3512 +#: sql_help.c:3822 msgid "where lockmode is one of:" msgstr "где допуÑтимый режим_блокировки:" -#: sql_help.c:3553 +#: sql_help.c:3863 msgid "payload" msgstr "Ñообщение_нагрузка" -#: sql_help.c:3580 +#: sql_help.c:3890 msgid "old_role" msgstr "ÑтараÑ_роль" -#: sql_help.c:3581 +#: sql_help.c:3891 msgid "new_role" msgstr "новаÑ_роль" -#: sql_help.c:3606 sql_help.c:3767 sql_help.c:3775 +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 msgid "savepoint_name" msgstr "имÑ_точки_ÑохранениÑ" -#: sql_help.c:3899 sql_help.c:3941 sql_help.c:3943 sql_help.c:3989 -#: sql_help.c:4138 sql_help.c:4180 sql_help.c:4182 sql_help.c:4332 -#: sql_help.c:4374 sql_help.c:4376 +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 msgid "from_item" msgstr "иÑточник_данных" -#: sql_help.c:3901 sql_help.c:3953 sql_help.c:4140 sql_help.c:4192 -#: sql_help.c:4334 sql_help.c:4386 +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 msgid "grouping_element" msgstr "Ñлемент_группированиÑ" -#: sql_help.c:3903 sql_help.c:3993 sql_help.c:4142 sql_help.c:4336 +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 msgid "window_name" msgstr "имÑ_окна" -#: sql_help.c:3904 sql_help.c:3994 sql_help.c:4143 sql_help.c:4337 +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 msgid "window_definition" msgstr "определение_окна" -#: sql_help.c:3905 sql_help.c:3919 sql_help.c:3957 sql_help.c:3995 -#: sql_help.c:4144 sql_help.c:4158 sql_help.c:4196 sql_help.c:4338 -#: sql_help.c:4352 sql_help.c:4390 +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 msgid "select" msgstr "select" -#: sql_help.c:3912 sql_help.c:4151 sql_help.c:4345 +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 msgid "where from_item can be one of:" msgstr "где допуÑтимый иÑточник_данных:" -#: sql_help.c:3915 sql_help.c:3921 sql_help.c:3924 sql_help.c:3928 -#: sql_help.c:3940 sql_help.c:4154 sql_help.c:4160 sql_help.c:4163 -#: sql_help.c:4167 sql_help.c:4179 sql_help.c:4348 sql_help.c:4354 -#: sql_help.c:4357 sql_help.c:4361 sql_help.c:4373 +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 msgid "column_alias" msgstr "пÑевдоним_Ñтолбца" -#: sql_help.c:3916 sql_help.c:4155 sql_help.c:4349 +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 msgid "sampling_method" msgstr "метод_выборки" -#: sql_help.c:3917 sql_help.c:3926 sql_help.c:3930 sql_help.c:3934 -#: sql_help.c:3937 sql_help.c:4156 sql_help.c:4165 sql_help.c:4169 -#: sql_help.c:4173 sql_help.c:4176 sql_help.c:4350 sql_help.c:4359 -#: sql_help.c:4363 sql_help.c:4367 sql_help.c:4370 -msgid "argument" -msgstr "аргумент" - -#: sql_help.c:3918 sql_help.c:4157 sql_help.c:4351 +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 msgid "seed" msgstr "начальное_чиÑло" -#: sql_help.c:3922 sql_help.c:3955 sql_help.c:4161 sql_help.c:4194 -#: sql_help.c:4355 sql_help.c:4388 +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 msgid "with_query_name" msgstr "имÑ_запроÑа_WITH" -#: sql_help.c:3932 sql_help.c:3935 sql_help.c:3938 sql_help.c:4171 -#: sql_help.c:4174 sql_help.c:4177 sql_help.c:4365 sql_help.c:4368 -#: sql_help.c:4371 +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 msgid "column_definition" msgstr "определение_Ñтолбца" -#: sql_help.c:3942 sql_help.c:4181 sql_help.c:4375 +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 msgid "join_type" msgstr "тип_ÑоединениÑ" -#: sql_help.c:3944 sql_help.c:4183 sql_help.c:4377 +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 msgid "join_condition" msgstr "уÑловие_ÑоединениÑ" -#: sql_help.c:3945 sql_help.c:4184 sql_help.c:4378 +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 msgid "join_column" msgstr "Ñтолбец_ÑоединениÑ" -#: sql_help.c:3946 sql_help.c:4185 sql_help.c:4379 +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 msgid "and grouping_element can be one of:" msgstr "где допуÑтимый Ñлемент_группированиÑ:" -#: sql_help.c:3954 sql_help.c:4193 sql_help.c:4387 +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 msgid "and with_query is:" msgstr "и запроÑ_WITH:" -#: sql_help.c:3958 sql_help.c:4197 sql_help.c:4391 +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 msgid "values" msgstr "значениÑ" -#: sql_help.c:3959 sql_help.c:4198 sql_help.c:4392 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 msgid "insert" msgstr "insert" -#: sql_help.c:3960 sql_help.c:4199 sql_help.c:4393 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 msgid "update" msgstr "update" -#: sql_help.c:3961 sql_help.c:4200 sql_help.c:4394 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 msgid "delete" msgstr "delete" -#: sql_help.c:3988 +#: sql_help.c:4308 msgid "new_table" msgstr "новаÑ_таблица" -#: sql_help.c:4013 +#: sql_help.c:4333 msgid "timezone" msgstr "чаÑовой_поÑÑ" -#: sql_help.c:4058 +#: sql_help.c:4378 msgid "snapshot_id" msgstr "код_Ñнимка" -#: sql_help.c:4243 +#: sql_help.c:4563 msgid "from_list" msgstr "ÑпиÑок_FROM" -#: sql_help.c:4274 +#: sql_help.c:4607 msgid "sort_expression" msgstr "выражение_Ñортировки" -#: sql_help.c:4401 sql_help.c:5186 +#: sql_help.c:4734 sql_help.c:5549 msgid "abort the current transaction" msgstr "прервать текущую транзакцию" -#: sql_help.c:4406 +#: sql_help.c:4739 msgid "change the definition of an aggregate function" msgstr "изменить определение агрегатной функции" -#: sql_help.c:4411 +#: sql_help.c:4744 msgid "change the definition of a collation" msgstr "изменить определение правила Ñортировки" -#: sql_help.c:4416 +#: sql_help.c:4749 msgid "change the definition of a conversion" msgstr "изменить определение преобразованиÑ" -#: sql_help.c:4421 +#: sql_help.c:4754 msgid "change a database" msgstr "изменить атрибуты базы данных" -#: sql_help.c:4426 +#: sql_help.c:4759 msgid "define default access privileges" msgstr "определить права доÑтупа по умолчанию" -#: sql_help.c:4431 +#: sql_help.c:4764 msgid "change the definition of a domain" msgstr "изменить определение домена" -#: sql_help.c:4436 +#: sql_help.c:4769 msgid "change the definition of an event trigger" msgstr "изменить определение Ñобытийного триггера" -#: sql_help.c:4441 +#: sql_help.c:4774 msgid "change the definition of an extension" msgstr "изменить определение раÑширениÑ" -#: sql_help.c:4446 +#: sql_help.c:4779 msgid "change the definition of a foreign-data wrapper" msgstr "изменить определение обёртки Ñторонних данных" -#: sql_help.c:4451 +#: sql_help.c:4784 msgid "change the definition of a foreign table" msgstr "изменить определение Ñторонней таблицы" -#: sql_help.c:4456 +#: sql_help.c:4789 msgid "change the definition of a function" msgstr "изменить определение функции" -#: sql_help.c:4461 +#: sql_help.c:4794 msgid "change role name or membership" msgstr "изменить Ð¸Ð¼Ñ Ñ€Ð¾Ð»Ð¸ или членÑтво" -#: sql_help.c:4466 +#: sql_help.c:4799 msgid "change the definition of an index" msgstr "изменить определение индекÑа" -#: sql_help.c:4471 +#: sql_help.c:4804 msgid "change the definition of a procedural language" msgstr "изменить определение процедурного Ñзыка" -#: sql_help.c:4476 +#: sql_help.c:4809 msgid "change the definition of a large object" msgstr "изменить определение большого объекта" -#: sql_help.c:4481 +#: sql_help.c:4814 msgid "change the definition of a materialized view" msgstr "изменить определение материализованного предÑтавлениÑ" -#: sql_help.c:4486 +#: sql_help.c:4819 msgid "change the definition of an operator" msgstr "изменить определение оператора" -#: sql_help.c:4491 +#: sql_help.c:4824 msgid "change the definition of an operator class" msgstr "изменить определение клаÑÑа операторов" -#: sql_help.c:4496 +#: sql_help.c:4829 msgid "change the definition of an operator family" msgstr "изменить определение ÑемейÑтва операторов" -#: sql_help.c:4501 +#: sql_help.c:4834 msgid "change the definition of a row level security policy" msgstr "изменить определение политики безопаÑноÑти на уровне Ñтрок" -#: sql_help.c:4506 +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "изменить определение процедуры" + +#: sql_help.c:4844 msgid "change the definition of a publication" msgstr "изменить определение публикации" -#: sql_help.c:4511 sql_help.c:4591 +#: sql_help.c:4849 sql_help.c:4934 msgid "change a database role" msgstr "изменить роль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð‘Ð”" -#: sql_help.c:4516 +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "изменить определение подпрограммы" + +#: sql_help.c:4859 msgid "change the definition of a rule" msgstr "изменить определение правила" -#: sql_help.c:4521 +#: sql_help.c:4864 msgid "change the definition of a schema" msgstr "изменить определение Ñхемы" -#: sql_help.c:4526 +#: sql_help.c:4869 msgid "change the definition of a sequence generator" msgstr "изменить определение генератора поÑледовательноÑти" -#: sql_help.c:4531 +#: sql_help.c:4874 msgid "change the definition of a foreign server" msgstr "изменить определение Ñтороннего Ñервера" -#: sql_help.c:4536 -msgid "change the definition of a extended statistics" -msgstr "изменить определение раÑширенной ÑтатиÑтики" +#: sql_help.c:4879 +msgid "change the definition of an extended statistics object" +msgstr "изменить определение объекта раÑширенной ÑтатиÑтики" -#: sql_help.c:4541 +#: sql_help.c:4884 msgid "change the definition of a subscription" msgstr "изменить определение подпиÑки" -#: sql_help.c:4546 +#: sql_help.c:4889 msgid "change a server configuration parameter" msgstr "изменить параметр конфигурации Ñервера" -#: sql_help.c:4551 +#: sql_help.c:4894 msgid "change the definition of a table" msgstr "изменить определение таблицы" -#: sql_help.c:4556 +#: sql_help.c:4899 msgid "change the definition of a tablespace" msgstr "изменить определение табличного проÑтранÑтва" -#: sql_help.c:4561 +#: sql_help.c:4904 msgid "change the definition of a text search configuration" msgstr "изменить определение конфигурации текÑтового поиÑка" -#: sql_help.c:4566 +#: sql_help.c:4909 msgid "change the definition of a text search dictionary" msgstr "изменить определение ÑÐ»Ð¾Ð²Ð°Ñ€Ñ Ñ‚ÐµÐºÑтового поиÑка" -#: sql_help.c:4571 +#: sql_help.c:4914 msgid "change the definition of a text search parser" msgstr "изменить определение анализатора текÑтового поиÑка" -#: sql_help.c:4576 +#: sql_help.c:4919 msgid "change the definition of a text search template" msgstr "изменить определение шаблона текÑтового поиÑка" -#: sql_help.c:4581 +#: sql_help.c:4924 msgid "change the definition of a trigger" msgstr "изменить определение триггера" -#: sql_help.c:4586 +#: sql_help.c:4929 msgid "change the definition of a type" msgstr "изменить определение типа" -#: sql_help.c:4596 +#: sql_help.c:4939 msgid "change the definition of a user mapping" msgstr "изменить ÑопоÑтавление пользователей" -#: sql_help.c:4601 +#: sql_help.c:4944 msgid "change the definition of a view" msgstr "изменить определение предÑтавлениÑ" -#: sql_help.c:4606 +#: sql_help.c:4949 msgid "collect statistics about a database" msgstr "Ñобрать ÑтатиÑтику о базе данных" -#: sql_help.c:4611 sql_help.c:5251 +#: sql_help.c:4954 sql_help.c:5614 msgid "start a transaction block" msgstr "начать транзакцию" -#: sql_help.c:4616 -msgid "force a transaction log checkpoint" -msgstr "отметить контрольную точку в журнале транзакций" +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "вызвать процедуру" -#: sql_help.c:4621 +#: sql_help.c:4964 +msgid "force a write-ahead log checkpoint" +msgstr "произвеÑти контрольную точку в журнале предзапиÑи" + +#: sql_help.c:4969 msgid "close a cursor" msgstr "закрыть курÑор" -#: sql_help.c:4626 +#: sql_help.c:4974 msgid "cluster a table according to an index" msgstr "перегруппировать таблицу по индекÑу" -#: sql_help.c:4631 +#: sql_help.c:4979 msgid "define or change the comment of an object" msgstr "задать или изменить комментарий объекта" -#: sql_help.c:4636 sql_help.c:5086 +#: sql_help.c:4984 sql_help.c:5449 msgid "commit the current transaction" msgstr "зафикÑировать текущую транзакцию" -#: sql_help.c:4641 +#: sql_help.c:4989 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "зафикÑировать транзакцию, ранее подготовленную Ð´Ð»Ñ Ð´Ð²ÑƒÑ…Ñ„Ð°Ð·Ð½Ð¾Ð¹ фикÑации" -#: sql_help.c:4646 +#: sql_help.c:4994 msgid "copy data between a file and a table" msgstr "импорт/ÑкÑпорт данных в файл" -#: sql_help.c:4651 +#: sql_help.c:4999 msgid "define a new access method" msgstr "Ñоздать новый метод доÑтупа" -#: sql_help.c:4656 +#: sql_help.c:5004 msgid "define a new aggregate function" msgstr "Ñоздать агрегатную функцию" -#: sql_help.c:4661 +#: sql_help.c:5009 msgid "define a new cast" msgstr "Ñоздать приведение типов" -#: sql_help.c:4666 +#: sql_help.c:5014 msgid "define a new collation" msgstr "Ñоздать правило Ñортировки" -#: sql_help.c:4671 +#: sql_help.c:5019 msgid "define a new encoding conversion" msgstr "Ñоздать преобразование кодировки" -#: sql_help.c:4676 +#: sql_help.c:5024 msgid "create a new database" msgstr "Ñоздать базу данных" -#: sql_help.c:4681 +#: sql_help.c:5029 msgid "define a new domain" msgstr "Ñоздать домен" -#: sql_help.c:4686 +#: sql_help.c:5034 msgid "define a new event trigger" msgstr "Ñоздать Ñобытийный триггер" -#: sql_help.c:4691 +#: sql_help.c:5039 msgid "install an extension" msgstr "уÑтановить раÑширение" -#: sql_help.c:4696 +#: sql_help.c:5044 msgid "define a new foreign-data wrapper" msgstr "Ñоздать обёртку Ñторонних данных" -#: sql_help.c:4701 +#: sql_help.c:5049 msgid "define a new foreign table" msgstr "Ñоздать Ñтороннюю таблицу" -#: sql_help.c:4706 +#: sql_help.c:5054 msgid "define a new function" msgstr "Ñоздать функцию" -#: sql_help.c:4711 sql_help.c:4756 sql_help.c:4841 +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 msgid "define a new database role" msgstr "Ñоздать роль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð‘Ð”" -#: sql_help.c:4716 +#: sql_help.c:5064 msgid "define a new index" msgstr "Ñоздать индекÑ" -#: sql_help.c:4721 +#: sql_help.c:5069 msgid "define a new procedural language" msgstr "Ñоздать процедурный Ñзык" -#: sql_help.c:4726 +#: sql_help.c:5074 msgid "define a new materialized view" msgstr "Ñоздать материализованное предÑтавление" -#: sql_help.c:4731 +#: sql_help.c:5079 msgid "define a new operator" msgstr "Ñоздать оператор" -#: sql_help.c:4736 +#: sql_help.c:5084 msgid "define a new operator class" msgstr "Ñоздать клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð²" -#: sql_help.c:4741 +#: sql_help.c:5089 msgid "define a new operator family" msgstr "Ñоздать ÑемейÑтво операторов" -#: sql_help.c:4746 +#: sql_help.c:5094 msgid "define a new row level security policy for a table" msgstr "Ñоздать новую политику безопаÑноÑти на уровне Ñтрок Ð´Ð»Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ñ‹" -#: sql_help.c:4751 +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "Ñоздать процедуру" + +#: sql_help.c:5104 msgid "define a new publication" msgstr "Ñоздать публикацию" -#: sql_help.c:4761 +#: sql_help.c:5114 msgid "define a new rewrite rule" msgstr "Ñоздать правило перезапиÑи" -#: sql_help.c:4766 +#: sql_help.c:5119 msgid "define a new schema" msgstr "Ñоздать Ñхему" -#: sql_help.c:4771 +#: sql_help.c:5124 msgid "define a new sequence generator" msgstr "Ñоздать генератор поÑледовательноÑтей" -#: sql_help.c:4776 +#: sql_help.c:5129 msgid "define a new foreign server" msgstr "Ñоздать Ñторонний Ñервер" -#: sql_help.c:4781 +#: sql_help.c:5134 msgid "define extended statistics" msgstr "Ñоздать раÑширенную ÑтатиÑтику" -#: sql_help.c:4786 +#: sql_help.c:5139 msgid "define a new subscription" msgstr "Ñоздать подпиÑку" -#: sql_help.c:4791 +#: sql_help.c:5144 msgid "define a new table" msgstr "Ñоздать таблицу" -#: sql_help.c:4796 sql_help.c:5216 +#: sql_help.c:5149 sql_help.c:5579 msgid "define a new table from the results of a query" msgstr "Ñоздать таблицу из результатов запроÑа" -#: sql_help.c:4801 +#: sql_help.c:5154 msgid "define a new tablespace" msgstr "Ñоздать табличное проÑтранÑтво" -#: sql_help.c:4806 +#: sql_help.c:5159 msgid "define a new text search configuration" msgstr "Ñоздать конфигурацию текÑтового поиÑка" -#: sql_help.c:4811 +#: sql_help.c:5164 msgid "define a new text search dictionary" msgstr "Ñоздать Ñловарь текÑтового поиÑка" -#: sql_help.c:4816 +#: sql_help.c:5169 msgid "define a new text search parser" msgstr "Ñоздать анализатор текÑтового поиÑка" -#: sql_help.c:4821 +#: sql_help.c:5174 msgid "define a new text search template" msgstr "Ñоздать шаблон текÑтового поиÑка" -#: sql_help.c:4826 +#: sql_help.c:5179 msgid "define a new transform" msgstr "Ñоздать преобразование" -#: sql_help.c:4831 +#: sql_help.c:5184 msgid "define a new trigger" msgstr "Ñоздать триггер" -#: sql_help.c:4836 +#: sql_help.c:5189 msgid "define a new data type" msgstr "Ñоздать тип данных" -#: sql_help.c:4846 +#: sql_help.c:5199 msgid "define a new mapping of a user to a foreign server" msgstr "Ñоздать ÑопоÑтавление Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ñтороннего Ñервера" -#: sql_help.c:4851 +#: sql_help.c:5204 msgid "define a new view" msgstr "Ñоздать предÑтавление" -#: sql_help.c:4856 +#: sql_help.c:5209 msgid "deallocate a prepared statement" msgstr "оÑвободить подготовленный оператор" -#: sql_help.c:4861 +#: sql_help.c:5214 msgid "define a cursor" msgstr "Ñоздать курÑор" -#: sql_help.c:4866 +#: sql_help.c:5219 msgid "delete rows of a table" msgstr "удалить запиÑи таблицы" -#: sql_help.c:4871 +#: sql_help.c:5224 msgid "discard session state" msgstr "очиÑтить ÑоÑтоÑние ÑеанÑа" -#: sql_help.c:4876 +#: sql_help.c:5229 msgid "execute an anonymous code block" msgstr "выполнить анонимный блок кода" -#: sql_help.c:4881 +#: sql_help.c:5234 msgid "remove an access method" msgstr "удалить метод доÑтупа" -#: sql_help.c:4886 +#: sql_help.c:5239 msgid "remove an aggregate function" msgstr "удалить агрегатную функцию" -#: sql_help.c:4891 +#: sql_help.c:5244 msgid "remove a cast" msgstr "удалить приведение типа" -#: sql_help.c:4896 +#: sql_help.c:5249 msgid "remove a collation" msgstr "удалить правило Ñортировки" -#: sql_help.c:4901 +#: sql_help.c:5254 msgid "remove a conversion" msgstr "удалить преобразование" -#: sql_help.c:4906 +#: sql_help.c:5259 msgid "remove a database" msgstr "удалить базу данных" -#: sql_help.c:4911 +#: sql_help.c:5264 msgid "remove a domain" msgstr "удалить домен" -#: sql_help.c:4916 +#: sql_help.c:5269 msgid "remove an event trigger" msgstr "удалить Ñобытийный триггер" -#: sql_help.c:4921 +#: sql_help.c:5274 msgid "remove an extension" msgstr "удалить раÑширение" -#: sql_help.c:4926 +#: sql_help.c:5279 msgid "remove a foreign-data wrapper" msgstr "удалить обёртку Ñторонних данных" -#: sql_help.c:4931 +#: sql_help.c:5284 msgid "remove a foreign table" msgstr "удалить Ñтороннюю таблицу" -#: sql_help.c:4936 +#: sql_help.c:5289 msgid "remove a function" msgstr "удалить функцию" -#: sql_help.c:4941 sql_help.c:4991 sql_help.c:5071 +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 msgid "remove a database role" msgstr "удалить роль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð‘Ð”" -#: sql_help.c:4946 +#: sql_help.c:5299 msgid "remove an index" msgstr "удалить индекÑ" -#: sql_help.c:4951 +#: sql_help.c:5304 msgid "remove a procedural language" msgstr "удалить процедурный Ñзык" -#: sql_help.c:4956 +#: sql_help.c:5309 msgid "remove a materialized view" msgstr "удалить материализованное предÑтавление" -#: sql_help.c:4961 +#: sql_help.c:5314 msgid "remove an operator" msgstr "удалить оператор" -#: sql_help.c:4966 +#: sql_help.c:5319 msgid "remove an operator class" msgstr "удалить клаÑÑ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð¾Ð²" -#: sql_help.c:4971 +#: sql_help.c:5324 msgid "remove an operator family" msgstr "удалить ÑемейÑтво операторов" -#: sql_help.c:4976 +#: sql_help.c:5329 msgid "remove database objects owned by a database role" msgstr "удалить объекты базы данных, принадлежащие роли" -#: sql_help.c:4981 +#: sql_help.c:5334 msgid "remove a row level security policy from a table" msgstr "удалить политику безопаÑноÑти на уровне Ñтрок из таблицы" -#: sql_help.c:4986 +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "удалить процедуру" + +#: sql_help.c:5344 msgid "remove a publication" msgstr "удалить публикацию" -#: sql_help.c:4996 +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "удалить подпрограмму" + +#: sql_help.c:5359 msgid "remove a rewrite rule" msgstr "удалить правило перезапиÑи" -#: sql_help.c:5001 +#: sql_help.c:5364 msgid "remove a schema" msgstr "удалить Ñхему" -#: sql_help.c:5006 +#: sql_help.c:5369 msgid "remove a sequence" msgstr "удалить поÑледовательноÑть" -#: sql_help.c:5011 +#: sql_help.c:5374 msgid "remove a foreign server descriptor" msgstr "удалить опиÑание Ñтороннего Ñервера" -#: sql_help.c:5016 +#: sql_help.c:5379 msgid "remove extended statistics" msgstr "удалить раÑширенную ÑтатиÑтику" -#: sql_help.c:5021 +#: sql_help.c:5384 msgid "remove a subscription" msgstr "удалить подпиÑку" -#: sql_help.c:5026 +#: sql_help.c:5389 msgid "remove a table" msgstr "удалить таблицу" -#: sql_help.c:5031 +#: sql_help.c:5394 msgid "remove a tablespace" msgstr "удалить табличное проÑтранÑтво" -#: sql_help.c:5036 +#: sql_help.c:5399 msgid "remove a text search configuration" msgstr "удалить конфигурацию текÑтового поиÑка" -#: sql_help.c:5041 +#: sql_help.c:5404 msgid "remove a text search dictionary" msgstr "удалить Ñловарь текÑтового поиÑка" -#: sql_help.c:5046 +#: sql_help.c:5409 msgid "remove a text search parser" msgstr "удалить анализатор текÑтового поиÑка" -#: sql_help.c:5051 +#: sql_help.c:5414 msgid "remove a text search template" msgstr "удалить шаблон текÑтового поиÑка" -#: sql_help.c:5056 +#: sql_help.c:5419 msgid "remove a transform" msgstr "удалить преобразование" -#: sql_help.c:5061 +#: sql_help.c:5424 msgid "remove a trigger" msgstr "удалить триггер" -#: sql_help.c:5066 +#: sql_help.c:5429 msgid "remove a data type" msgstr "удалить тип данных" -#: sql_help.c:5076 +#: sql_help.c:5439 msgid "remove a user mapping for a foreign server" msgstr "удалить ÑопоÑтавление Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ñтороннего Ñервера" -#: sql_help.c:5081 +#: sql_help.c:5444 msgid "remove a view" msgstr "удалить предÑтавление" -#: sql_help.c:5091 +#: sql_help.c:5454 msgid "execute a prepared statement" msgstr "выполнить подготовленный оператор" -#: sql_help.c:5096 +#: sql_help.c:5459 msgid "show the execution plan of a statement" msgstr "показать план Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð°" -#: sql_help.c:5101 +#: sql_help.c:5464 msgid "retrieve rows from a query using a cursor" msgstr "получить результат запроÑа через курÑор" -#: sql_help.c:5106 +#: sql_help.c:5469 msgid "define access privileges" msgstr "определить права доÑтупа" -#: sql_help.c:5111 +#: sql_help.c:5474 msgid "import table definitions from a foreign server" msgstr "импортировать Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ† Ñо Ñтороннего Ñервера" -#: sql_help.c:5116 +#: sql_help.c:5479 msgid "create new rows in a table" msgstr "добавить Ñтроки в таблицу" -#: sql_help.c:5121 +#: sql_help.c:5484 msgid "listen for a notification" msgstr "ожидать уведомлениÑ" -#: sql_help.c:5126 +#: sql_help.c:5489 msgid "load a shared library file" msgstr "загрузить файл разделÑемой библиотеки" -#: sql_help.c:5131 +#: sql_help.c:5494 msgid "lock a table" msgstr "заблокировать таблицу" -#: sql_help.c:5136 +#: sql_help.c:5499 msgid "position a cursor" msgstr "уÑтановить курÑор" -#: sql_help.c:5141 +#: sql_help.c:5504 msgid "generate a notification" msgstr "Ñгенерировать уведомление" -#: sql_help.c:5146 +#: sql_help.c:5509 msgid "prepare a statement for execution" msgstr "подготовить оператор Ð´Ð»Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ" -#: sql_help.c:5151 +#: sql_help.c:5514 msgid "prepare the current transaction for two-phase commit" msgstr "подготовить текущую транзакцию Ð´Ð»Ñ Ð´Ð²ÑƒÑ…Ñ„Ð°Ð·Ð½Ð¾Ð¹ фикÑации" -#: sql_help.c:5156 +#: sql_help.c:5519 msgid "change the ownership of database objects owned by a database role" msgstr "изменить владельца объектов БД, принадлежащих заданной роли" -#: sql_help.c:5161 +#: sql_help.c:5524 msgid "replace the contents of a materialized view" msgstr "заменить Ñодержимое материализованного предÑтавлениÑ" -#: sql_help.c:5166 +#: sql_help.c:5529 msgid "rebuild indexes" msgstr "переÑтроить индекÑÑ‹" -#: sql_help.c:5171 +#: sql_help.c:5534 msgid "destroy a previously defined savepoint" msgstr "удалить ранее определённую точку ÑохранениÑ" -#: sql_help.c:5176 +#: sql_help.c:5539 msgid "restore the value of a run-time parameter to the default value" msgstr "воÑÑтановить иÑходное значение параметра выполнениÑ" -#: sql_help.c:5181 +#: sql_help.c:5544 msgid "remove access privileges" msgstr "удалить права доÑтупа" -#: sql_help.c:5191 +#: sql_help.c:5554 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "отменить транзакцию, подготовленную ранее Ð´Ð»Ñ Ð´Ð²ÑƒÑ…Ñ„Ð°Ð·Ð½Ð¾Ð¹ фикÑации" -#: sql_help.c:5196 +#: sql_help.c:5559 msgid "roll back to a savepoint" msgstr "откатитьÑÑ Ðº точке ÑохранениÑ" -#: sql_help.c:5201 +#: sql_help.c:5564 msgid "define a new savepoint within the current transaction" msgstr "определить новую точку ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð² текущей транзакции" -#: sql_help.c:5206 +#: sql_help.c:5569 msgid "define or change a security label applied to an object" msgstr "задать или изменить метку безопаÑноÑти, применённую к объекту" -#: sql_help.c:5211 sql_help.c:5256 sql_help.c:5286 +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 msgid "retrieve rows from a table or view" msgstr "выбрать Ñтроки из таблицы или предÑтавлениÑ" -#: sql_help.c:5221 +#: sql_help.c:5584 msgid "change a run-time parameter" msgstr "изменить параметр выполнениÑ" -#: sql_help.c:5226 +#: sql_help.c:5589 msgid "set constraint check timing for the current transaction" msgstr "уÑтановить Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ ограничений Ð´Ð»Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ транзакции" -#: sql_help.c:5231 +#: sql_help.c:5594 msgid "set the current user identifier of the current session" msgstr "задать идентификатор текущего Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² текущем ÑеанÑе" -#: sql_help.c:5236 +#: sql_help.c:5599 msgid "" "set the session user identifier and the current user identifier of the " "current session" @@ -5825,45 +6226,45 @@ msgstr "" "задать идентификатор Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ ÑеанÑа и идентификатор текущего " "Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð² текущем ÑеанÑе" -#: sql_help.c:5241 +#: sql_help.c:5604 msgid "set the characteristics of the current transaction" msgstr "задать ÑвойÑтва текущей транзакции" -#: sql_help.c:5246 +#: sql_help.c:5609 msgid "show the value of a run-time parameter" msgstr "показать значение параметра выполнениÑ" -#: sql_help.c:5261 +#: sql_help.c:5624 msgid "empty a table or set of tables" msgstr "опуÑтошить таблицу или набор таблиц" -#: sql_help.c:5266 +#: sql_help.c:5629 msgid "stop listening for a notification" msgstr "прекратить ожидание уведомлений" -#: sql_help.c:5271 +#: sql_help.c:5634 msgid "update rows of a table" msgstr "изменить Ñтроки таблицы" -#: sql_help.c:5276 +#: sql_help.c:5639 msgid "garbage-collect and optionally analyze a database" msgstr "произвеÑти Ñборку муÑора и проанализировать базу данных" -#: sql_help.c:5281 +#: sql_help.c:5644 msgid "compute a set of rows" msgstr "получить набор Ñтрок" -#: startup.c:184 +#: startup.c:190 #, c-format msgid "%s: -1 can only be used in non-interactive mode\n" msgstr "%s: -1 можно иÑпользовать только в неинтерактивном режиме\n" -#: startup.c:287 +#: startup.c:305 #, c-format msgid "%s: could not open log file \"%s\": %s\n" msgstr "%s: не удалоÑÑŒ открыть файл протокола \"%s\": %s\n" -#: startup.c:394 +#: startup.c:412 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5872,27 +6273,27 @@ msgstr "" "Введите \"help\", чтобы получить Ñправку.\n" "\n" -#: startup.c:543 +#: startup.c:561 #, c-format msgid "%s: could not set printing parameter \"%s\"\n" msgstr "%s: не удалоÑÑŒ уÑтановить параметр печати \"%s\"\n" -#: startup.c:645 +#: startup.c:663 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: startup.c:662 +#: startup.c:680 #, c-format msgid "%s: warning: extra command-line argument \"%s\" ignored\n" msgstr "%s: предупреждение: лишний аргумент \"%s\" проигнорирован\n" -#: startup.c:711 +#: startup.c:729 #, c-format msgid "%s: could not find own program executable\n" msgstr "%s: не удалоÑÑŒ найти Ñвой иÑполнÑемый файл\n" -#: tab-complete.c:4084 +#: tab-complete.c:4543 #, c-format msgid "" "tab completion query failed: %s\n" @@ -5905,7 +6306,7 @@ msgstr "" #: variables.c:139 #, c-format -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" msgstr "" "нераÑпознанное значение \"%s\" Ð´Ð»Ñ \"%s\": ожидалоÑÑŒ булевÑкое значение\n" @@ -5928,6 +6329,71 @@ msgstr "" "нераÑпознанное значение \"%s\" Ð´Ð»Ñ \"%s\"\n" "ДопуÑтимые значениÑ: %s.\n" +#~ msgid "normal" +#~ msgstr "обычнаÑ" + +#~ msgid "Procedure" +#~ msgstr "Процедура" + +#~ msgid " SERVER_VERSION_NAME server's version (short string)\n" +#~ msgstr " SERVER_VERSION_NAME верÑÐ¸Ñ Ñервера (ÐºÐ¾Ñ€Ð¾Ñ‚ÐºÐ°Ñ Ñтрока)\n" + +#~ msgid " VERSION psql's version (verbose string)\n" +#~ msgstr " VERSION верÑÐ¸Ñ psql (Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ð½ÑƒÑ‚Ð°Ñ Ñтрока)\n" + +#~ msgid " VERSION_NAME psql's version (short string)\n" +#~ msgstr " VERSION_NAME верÑÐ¸Ñ psql (ÐºÐ¾Ñ€Ð¾Ñ‚ÐºÐ°Ñ Ñтрока)\n" + +#~ msgid " VERSION_NUM psql's version (numeric format)\n" +#~ msgstr " VERSION_NUM верÑÐ¸Ñ psql (в чиÑловом формате)\n" + +#~ msgid "attribute" +#~ msgstr "атрибут" + +#~ msgid "Value" +#~ msgstr "Значение" + +#~ msgid "statistic_type" +#~ msgstr "тип_ÑтатиÑтики" + +#~ msgid "No per-database role settings support in this server version.\n" +#~ msgstr "" +#~ "Это верÑÐ¸Ñ Ñервера не поддерживает параметры ролей на уровне базы " +#~ "данных.\n" + +#~ msgid "No matching settings found.\n" +#~ msgstr "СоответÑтвующие параметры не найдены.\n" + +#~ msgid "No settings found.\n" +#~ msgstr "Параметры не найдены.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "СоответÑтвующие Ð¾Ñ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" + +#~ msgid "No relations found.\n" +#~ msgstr "ÐžÑ‚Ð½Ð¾ÑˆÐµÐ½Ð¸Ñ Ð½Ðµ найдены.\n" + +#~ msgid "Object Description" +#~ msgstr "ОпиÑание объекта" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "Ошибка при шифровании паролÑ.\n" + +#~ msgid "suboption" +#~ msgstr "подпараметр" + +#~ msgid "where suboption can be:" +#~ msgstr "где допуÑтимые подпараметры:" + +#~ msgid "slot_name" +#~ msgstr "имÑ_Ñлота" + +#~ msgid "puboption" +#~ msgstr "параметр_публикации" + +#~ msgid "where puboption can be:" +#~ msgstr "где допуÑтимый параметр_публикации:" + #~ msgid "+ opt(%d) = |%s|\n" #~ msgstr "+ opt(%d) = |%s|\n" diff --git a/src/bin/psql/po/sv.po b/src/bin/psql/po/sv.po index 2f9fac08528..6023974db28 100644 --- a/src/bin/psql/po/sv.po +++ b/src/bin/psql/po/sv.po @@ -1,15 +1,15 @@ # Swedish message translation file for psql # Peter Eisentraut , 2001, 2009, 2010. -# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. # # Use these quotes: "%s" # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-02 18:14+0000\n" -"PO-Revision-Date: 2017-08-06 08:09+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 16:45+0000\n" +"PO-Revision-Date: 2019-04-29 20:16+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -18,44 +18,64 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/fe_utils/logging.c:182 #, c-format -msgid "could not identify current directory: %s" -msgstr "kunde inte identifiera aktuell katalog: %s" +msgid "fatal: " +msgstr "fatalt: " -#: ../../common/exec.c:146 +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " + +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, c-format +msgid "could not identify current directory: %m" +msgstr "kunde inte identifiera aktuell katalog: %m" + +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "ogiltig binär \"%s\"" -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "kunde inte läsa binär \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "kunde inte hitta en \"%s\" att köra" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 +#, c-format +msgid "could not change directory to \"%s\": %m" +msgstr "kunde inte byta katalog till \"%s\": %m" + +#: ../../common/exec.c:288 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "kunde inte byta katalog till \"%s\": %s" +msgid "could not read symbolic link \"%s\": %m" +msgstr "kan inte läsa symbolisk länk \"%s\": %m" -#: ../../common/exec.c:272 +#: ../../common/exec.c:541 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "kunde inte läsa symbolisk länk \"%s\"" +msgid "pclose failed: %m" +msgstr "pclose misslyckades: %m" -#: ../../common/exec.c:523 +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: command.c:1218 input.c:228 mainloop.c:82 mainloop.c:386 #, c-format -msgid "pclose failed: %s" -msgstr "pclose misslyckades: %s" +msgid "out of memory" +msgstr "slut pÃ¥ minne" #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:608 input.c:227 mainloop.c:82 -#: mainloop.c:276 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "slut pÃ¥ minne\n" @@ -94,22 +114,17 @@ msgstr "kommandot kan ej hittas" msgid "child process exited with exit code %d" msgstr "barnprocess avslutade med kod %d" -#: ../../common/wait_error.c:61 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "barnprocess terminerades med avbrott 0x%X" -#: ../../common/wait_error.c:71 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "barnprocess terminerades av signal %s" - -#: ../../common/wait_error.c:75 +#: ../../common/wait_error.c:66 #, c-format -msgid "child process was terminated by signal %d" -msgstr "barnprocess terminerades av signal %d" +msgid "child process was terminated by signal %d: %s" +msgstr "barnprocess terminerades av signal %d: %s" -#: ../../common/wait_error.c:80 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "barnprocess avslutade med okänd statuskod %d" @@ -121,269 +136,285 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu rad)" msgstr[1] "(%lu rader)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "Avbruten\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kan inte lägga till rubrik till tabellinnehÃ¥ll: antal kolumner (%d) överskridet.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Kan inte lägga till cell till tabellinnehÃ¥ll: totala cellantalet (%d) överskridet.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "ogiltigt utdataformat (internt fel): %d" -#: ../../fe_utils/psqlscan.l:713 +#: ../../fe_utils/psqlscan.l:729 #, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" -msgstr "hoppar över rekursiv expandering av variabeln \"%s\"\n" +msgid "skipping recursive expansion of variable \"%s\"" +msgstr "hoppar över rekursiv expandering av variabeln \"%s\"" -#: command.c:223 +#: command.c:221 #, c-format -msgid "Invalid command \\%s. Try \\? for help.\n" -msgstr "Ogiltigt kommando \\%s. Försök med \\? för hjälp.\n" +msgid "invalid command \\%s" +msgstr "ogiltigt kommando \\%s" -#: command.c:225 +#: command.c:223 #, c-format -msgid "invalid command \\%s\n" -msgstr "ogiltigt kommando \\%s\n" +msgid "Try \\? for help." +msgstr "Försök med \\? för hjälp." -#: command.c:243 +#: command.c:241 #, c-format -msgid "\\%s: extra argument \"%s\" ignored\n" -msgstr "\\%s: extra argument \"%s\" ignorerat\n" +msgid "\\%s: extra argument \"%s\" ignored" +msgstr "\\%s: extra argument \"%s\" ignorerat" -#: command.c:295 +#: command.c:293 #, c-format -msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" -msgstr "kommandot \\%s ignorerat; använd \\endif eller Ctrl-C för att avsluta nuvarande \\if-block\n" +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "kommandot \\%s ignorerat; använd \\endif eller Ctrl-C för att avsluta nuvarande \\if-block" #: command.c:553 #, c-format -msgid "could not get home directory for user ID %ld: %s\n" -msgstr "kunde inte hämta hemkatalog för användar-ID %ld: %s\n" +msgid "could not get home directory for user ID %ld: %s" +msgstr "kunde inte hämta hemkatalog för användar-ID %ld: %s" #: command.c:571 #, c-format -msgid "\\%s: could not change directory to \"%s\": %s\n" -msgstr "\\%s: kunde inte byta katalog till \"%s\": %s\n" +msgid "\\%s: could not change directory to \"%s\": %m" +msgstr "\\%s: kunde inte byta katalog till \"%s\": %m" -#: command.c:596 common.c:648 common.c:706 common.c:1242 +#: command.c:596 #, c-format msgid "You are currently not connected to a database.\n" msgstr "Du är för närvarande inte uppkopplad mot en databas.\n" -#: command.c:621 +#: command.c:609 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" pÃ¥ adress \"%s\" pÃ¥ port \"%s\".\n" + +#: command.c:612 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" -msgstr "Du är uppkopplad mot databas \"%s\" som användare \"%s\" via uttag i \"%s\" vid port \"%s\".\n" +msgstr "Du är uppkopplad mot databas \"%s\" som användare \"%s\" via uttag i \"%s\" pÃ¥ port \"%s\".\n" + +#: command.c:618 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" (adress \"%s\") pÃ¥ port \"%s\".\n" -#: command.c:624 +#: command.c:621 #, c-format msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" -msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" via port \"%s\".\n" +msgstr "Du är uppkopplad upp mot databas \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" pÃ¥ port \"%s\".\n" -#: command.c:915 command.c:1005 command.c:1114 command.c:2523 +#: command.c:930 command.c:1026 command.c:2411 #, c-format -msgid "no query buffer\n" -msgstr "ingen frÃ¥gebuffert\n" +msgid "no query buffer" +msgstr "ingen frÃ¥gebuffert" -#: command.c:948 command.c:4765 +#: command.c:963 command.c:4801 #, c-format -msgid "invalid line number: %s\n" -msgstr "ogiltigt radnummer: %s\n" +msgid "invalid line number: %s" +msgstr "ogiltigt radnummer: %s" -#: command.c:998 +#: command.c:1017 #, c-format -msgid "The server (version %s) does not support editing function source.\n" -msgstr "Servern (version %s) stöder inte redigering av funktionskällkod.\n" +msgid "The server (version %s) does not support editing function source." +msgstr "Servern (version %s) stöder inte redigering av funktionskällkod." -#: command.c:1073 command.c:1154 +#: command.c:1020 +#, c-format +msgid "The server (version %s) does not support editing view definitions." +msgstr "Servern (version %s) stöder inte redigering av vydefinitioner." + +#: command.c:1102 msgid "No changes" msgstr "Inga ändringar" -#: command.c:1107 -#, c-format -msgid "The server (version %s) does not support editing view definitions.\n" -msgstr "Servern (version %s) stöder inte redigering av vydefinitioner.\n" - -#: command.c:1231 +#: command.c:1179 #, c-format -msgid "%s: invalid encoding name or conversion procedure not found\n" -msgstr "%s: ogiltigt kodningsnamn eller konverteringsprocedur hittades inte\n" +msgid "%s: invalid encoding name or conversion procedure not found" +msgstr "%s: ogiltigt kodningsnamn eller konverteringsprocedur hittades inte" -#: command.c:1266 command.c:1888 command.c:3169 command.c:4867 common.c:173 -#: common.c:244 common.c:541 common.c:1288 common.c:1316 common.c:1417 -#: copy.c:489 copy.c:708 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1214 command.c:1853 command.c:3089 command.c:4903 common.c:175 +#: common.c:224 common.c:521 common.c:1362 common.c:1390 common.c:1498 +#: common.c:1601 common.c:1639 copy.c:490 copy.c:709 help.c:63 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 #, c-format msgid "%s" msgstr "%s" -#: command.c:1270 -msgid "out of memory" -msgstr "slut pÃ¥ minne" - -#: command.c:1273 +#: command.c:1221 msgid "There is no previous error." msgstr "Det finns inget tidigare fel." -#: command.c:1444 command.c:1749 command.c:1763 command.c:1780 command.c:1940 -#: command.c:2177 command.c:2490 command.c:2530 +#: command.c:1409 command.c:1714 command.c:1728 command.c:1745 command.c:1905 +#: command.c:2142 command.c:2378 command.c:2418 #, c-format -msgid "\\%s: missing required argument\n" -msgstr "\\%s: obligatoriskt argument saknas\n" +msgid "\\%s: missing required argument" +msgstr "\\%s: obligatoriskt argument saknas" -#: command.c:1575 +#: command.c:1540 #, c-format -msgid "\\elif: cannot occur after \\else\n" -msgstr "\\elif: kan inte komma efter \\else\n" +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif: kan inte komma efter \\else" -#: command.c:1580 +#: command.c:1545 #, c-format -msgid "\\elif: no matching \\if\n" -msgstr "\\elif: ingen matchande \\if\n" +msgid "\\elif: no matching \\if" +msgstr "\\elif: ingen matchande \\if" -#: command.c:1644 +#: command.c:1609 #, c-format -msgid "\\else: cannot occur after \\else\n" -msgstr "\\else: kan inte komma efter \\else\n" +msgid "\\else: cannot occur after \\else" +msgstr "\\else: kan inte komma efter \\else" -#: command.c:1649 +#: command.c:1614 #, c-format -msgid "\\else: no matching \\if\n" -msgstr "\\else: ingen matchande \\if\n" +msgid "\\else: no matching \\if" +msgstr "\\else: ingen matchande \\if" -#: command.c:1689 +#: command.c:1654 #, c-format -msgid "\\endif: no matching \\if\n" -msgstr "\\endif: ingen matchande \\if\n" +msgid "\\endif: no matching \\if" +msgstr "\\endif: ingen matchande \\if" -#: command.c:1844 +#: command.c:1809 msgid "Query buffer is empty." msgstr "FrÃ¥gebufferten är tom." -#: command.c:1866 +#: command.c:1831 msgid "Enter new password: " msgstr "Mata in nytt lösenord: " -#: command.c:1867 +#: command.c:1832 msgid "Enter it again: " msgstr "Mata in det igen: " -#: command.c:1871 +#: command.c:1836 #, c-format -msgid "Passwords didn't match.\n" -msgstr "Lösenorden stämde inte överens.\n" +msgid "Passwords didn't match." +msgstr "Lösenorden stämde inte överens." -#: command.c:1970 +#: command.c:1935 #, c-format -msgid "\\%s: could not read value for variable\n" -msgstr "\\%s: kunde inte läsa värde pÃ¥ varibeln\n" +msgid "\\%s: could not read value for variable" +msgstr "\\%s: kunde inte läsa värde pÃ¥ varibeln" -#: command.c:2073 +#: command.c:2038 msgid "Query buffer reset (cleared)." msgstr "FrÃ¥gebufferten har blivit borttagen." -#: command.c:2095 +#: command.c:2060 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "Skrev historiken till fil \"%s\".\n" -#: command.c:2182 +#: command.c:2147 #, c-format -msgid "\\%s: environment variable name must not contain \"=\"\n" -msgstr "\\%s: omgivningsvariabelnamn fÃ¥r ej innehÃ¥lla \"=\"\n" +msgid "\\%s: environment variable name must not contain \"=\"" +msgstr "\\%s: omgivningsvariabelnamn fÃ¥r ej innehÃ¥lla \"=\"" -#: command.c:2238 +#: command.c:2208 #, c-format -msgid "The server (version %s) does not support showing function source.\n" -msgstr "Servern (version %s) stöder inte visning av funktionskällkod.\n" +msgid "The server (version %s) does not support showing function source." +msgstr "Servern (version %s) stöder inte visning av funktionskällkod." -#: command.c:2245 +#: command.c:2211 #, c-format -msgid "function name is required\n" -msgstr "funktionsnamn krävs\n" +msgid "The server (version %s) does not support showing view definitions." +msgstr "Servern (version %s) stöder inte visning av vydefinitioner." -#: command.c:2332 +#: command.c:2218 #, c-format -msgid "The server (version %s) does not support showing view definitions.\n" -msgstr "Servern (version %s) stöder inte visning av vydefinitioner.\n" +msgid "function name is required" +msgstr "funktionsnamn krävs" -#: command.c:2339 +#: command.c:2220 #, c-format -msgid "view name is required\n" -msgstr "vynamn krävs\n" +msgid "view name is required" +msgstr "vynamn krävs" -#: command.c:2462 +#: command.c:2350 msgid "Timing is on." msgstr "Tidtagning är pÃ¥." -#: command.c:2464 +#: command.c:2352 msgid "Timing is off." msgstr "Tidtagning är av." -#: command.c:2549 command.c:2577 command.c:3518 command.c:3521 command.c:3524 -#: command.c:3530 command.c:3532 command.c:3540 command.c:3550 command.c:3559 -#: command.c:3573 command.c:3590 command.c:3648 common.c:69 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:760 psqlscanslash.l:771 -#: psqlscanslash.l:781 +#: command.c:2437 command.c:2465 command.c:3485 command.c:3488 command.c:3491 +#: command.c:3497 command.c:3499 command.c:3507 command.c:3517 command.c:3526 +#: command.c:3540 command.c:3557 command.c:3615 common.c:71 copy.c:333 +#: copy.c:405 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 #, c-format -msgid "%s: %s\n" -msgstr "%s: %s\n" +msgid "%s: %m" +msgstr "%s: %m" -#: command.c:2961 startup.c:202 +#: command.c:2849 startup.c:239 startup.c:290 msgid "Password: " msgstr "Lösenord: " -#: command.c:2966 startup.c:204 +#: command.c:2854 startup.c:287 #, c-format msgid "Password for user %s: " msgstr "Lösenord för användare %s: " -#: command.c:3016 +#: command.c:2905 #, c-format -msgid "All connection parameters must be supplied because no database connection exists\n" -msgstr "Alla anslutningsparametrar mÃ¥ste anges dÃ¥ ingen databasuppkoppling är gjord\n" +msgid "All connection parameters must be supplied because no database connection exists" +msgstr "Alla anslutningsparametrar mÃ¥ste anges dÃ¥ ingen databasuppkoppling är gjord" -#: command.c:3173 +#: command.c:3093 #, c-format -msgid "Previous connection kept\n" -msgstr "FöregÃ¥ende förbindelse bevarad\n" +msgid "Previous connection kept" +msgstr "FöregÃ¥ende förbindelse bevarad" -#: command.c:3177 +#: command.c:3097 #, c-format msgid "\\connect: %s" msgstr "\\connect: %s" -#: command.c:3213 +#: command.c:3136 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" pÃ¥ adress \"%s\" pÃ¥ port \"%s\".\n" + +#: command.c:3139 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" -msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" via uttag i \"%s\" vid port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" via uttag i \"%s\" pÃ¥ port \"%s\".\n" + +#: command.c:3145 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" (adress \"%s\") pÃ¥ port \"%s\".\n" -#: command.c:3216 +#: command.c:3148 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" -msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" vid port \"%s\".\n" +msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\" pÃ¥ värd \"%s\" pÃ¥ port \"%s\".\n" -#: command.c:3220 +#: command.c:3153 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "Du är nu uppkopplad mot databasen \"%s\" som användare \"%s\".\n" -#: command.c:3253 +#: command.c:3186 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, server %s)\n" -#: command.c:3261 +#: command.c:3194 #, c-format msgid "" "WARNING: %s major version %s, server major version %s.\n" @@ -392,24 +423,29 @@ msgstr "" "VARNING: %s huvudversion %s, server huvudversion %s.\n" " En del psql-finesser kommer kanske inte fungera.\n" -#: command.c:3298 +#: command.c:3232 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "SSL-förbindelse (protokoll: %s, krypto: %s, bitar: %s, komprimering: %s)\n" -#: command.c:3299 command.c:3300 command.c:3301 +#: command.c:3233 command.c:3234 command.c:3235 msgid "unknown" msgstr "okänd" -#: command.c:3302 help.c:45 +#: command.c:3236 help.c:46 msgid "off" msgstr "av" -#: command.c:3302 help.c:45 +#: command.c:3236 help.c:46 msgid "on" msgstr "pÃ¥" -#: command.c:3322 +#: command.c:3250 +#, c-format +msgid "GSSAPI Encrypted connection\n" +msgstr "GSSAPI-krypterad anslutning\n" + +#: command.c:3270 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -420,239 +456,259 @@ msgstr "" " 8-bitars tecken kommer troligen inte fungera korrekt. Se psql:s\n" " referensmanual i sektionen \"Notes for Windows users\" för mer detaljer.\n" -#: command.c:3407 +#: command.c:3374 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" +msgstr "omgivningsvariabeln PSQL_EDITOR_LINENUMBER_ARG mÃ¥ste ange ett radnummer" + +#: command.c:3403 +#, c-format +msgid "could not start editor \"%s\"" +msgstr "kunde inte starta editorn \"%s\"" + +#: command.c:3405 +#, c-format +msgid "could not start /bin/sh" +msgstr "kunde inte starta /bin/sh" + +#: command.c:3443 #, c-format -msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" -msgstr "omgivningsvariabeln PSQL_EDITOR_LINENUMBER_ARG mÃ¥ste ange ett radnummer\n" +msgid "could not locate temporary directory: %s" +msgstr "kunde inte hitta temp-katalog: %s" -#: command.c:3436 +#: command.c:3470 #, c-format -msgid "could not start editor \"%s\"\n" -msgstr "kunde inte starta editorn \"%s\"\n" +msgid "could not open temporary file \"%s\": %m" +msgstr "kunde inte öppna temporär fil \"%s\": %m" -#: command.c:3438 +#: command.c:3763 #, c-format -msgid "could not start /bin/sh\n" -msgstr "kunde inte starta /bin/sh\n" +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" +msgstr "\\pset: tvetydig förkortning \"%s\" matchar bÃ¥de \"%s\" och \"%s\"" -#: command.c:3476 +#: command.c:3783 #, c-format -msgid "could not locate temporary directory: %s\n" -msgstr "kunde inte hitta temp-katalog: %s\n" +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: tillÃ¥tna format är aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" -#: command.c:3503 +#: command.c:3802 #, c-format -msgid "could not open temporary file \"%s\": %s\n" -msgstr "kunde inte öppna temporär fil \"%s\": %s\n" +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" +msgstr "\\pset: tillÃ¥tna linjestilar är ascii, old-ascii, unicode" -#: command.c:3777 +#: command.c:3817 #, c-format -msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" -msgstr "\\pset: tillÃ¥tna format är unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" +msgid "\\pset: allowed Unicode border line styles are single, double" +msgstr "\\pset: tillÃ¥tna Unicode-ramstilar är single, double" -#: command.c:3795 +#: command.c:3832 #, c-format -msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" -msgstr "\\pset: tillÃ¥tna linjestilar är ascii, old-ascii, unicode\n" +msgid "\\pset: allowed Unicode column line styles are single, double" +msgstr "\\pset: tillÃ¥tna Unicode-kolumnlinjestilar ärsingle, double" -#: command.c:3810 +#: command.c:3847 #, c-format -msgid "\\pset: allowed Unicode border line styles are single, double\n" -msgstr "\\pset: tillÃ¥tna Unicode-ramstilar är single, double\n" +msgid "\\pset: allowed Unicode header line styles are single, double" +msgstr "\\pset: tillÃ¥tna Unicode-rubriklinjestilar är single, double" -#: command.c:3825 +#: command.c:3890 #, c-format -msgid "\\pset: allowed Unicode column line styles are single, double\n" -msgstr "\\pset: tillÃ¥tna Unicode-kolumnlinjestilar ärsingle, double\n" +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "\\pset: csv_fieldsep mÃ¥ste vara ett ensamt en-byte-tecken" -#: command.c:3840 +#: command.c:3895 #, c-format -msgid "\\pset: allowed Unicode header line styles are single, double\n" -msgstr "\\pset: tillÃ¥tna Unicode-rubriklinjestilar är single, double\n" +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "\\pset: csv_fieldset kan inte vara dubbelcitat, nyrad eller vagnretur" -#: command.c:4005 command.c:4184 +#: command.c:4032 command.c:4218 #, c-format -msgid "\\pset: unknown option: %s\n" -msgstr "\\pset: okänd parameter: %s\n" +msgid "\\pset: unknown option: %s" +msgstr "\\pset: okänd parameter: %s" -#: command.c:4023 +#: command.c:4050 #, c-format msgid "Border style is %d.\n" msgstr "Ramstil är %d.\n" -#: command.c:4029 +#: command.c:4056 #, c-format msgid "Target width is unset.\n" msgstr "MÃ¥lvidd är inte satt.\n" -#: command.c:4031 +#: command.c:4058 #, c-format msgid "Target width is %d.\n" msgstr "MÃ¥lvidd är %d.\n" -#: command.c:4038 +#: command.c:4065 #, c-format msgid "Expanded display is on.\n" msgstr "Utökad visning är pÃ¥.\n" -#: command.c:4040 +#: command.c:4067 #, c-format msgid "Expanded display is used automatically.\n" msgstr "Utökad visning används automatiskt.\n" -#: command.c:4042 +#: command.c:4069 #, c-format msgid "Expanded display is off.\n" msgstr "Utökad visning är av.\n" -#: command.c:4049 command.c:4057 +#: command.c:4075 +#, c-format +msgid "Field separator for CSV is \"%s\".\n" +msgstr "Fältseparatorn för CSV är \"%s\".\n" + +#: command.c:4083 command.c:4091 #, c-format msgid "Field separator is zero byte.\n" msgstr "Fältseparatorn är noll-byte.\n" -#: command.c:4051 +#: command.c:4085 #, c-format msgid "Field separator is \"%s\".\n" msgstr "Fältseparatorn är \"%s\".\n" -#: command.c:4064 +#: command.c:4098 #, c-format msgid "Default footer is on.\n" msgstr "Standard sidfot är pÃ¥.\n" -#: command.c:4066 +#: command.c:4100 #, c-format msgid "Default footer is off.\n" msgstr "Standard sidfot är av.\n" -#: command.c:4072 +#: command.c:4106 #, c-format msgid "Output format is %s.\n" msgstr "Utdataformatet är \"%s\".\n" -#: command.c:4078 +#: command.c:4112 #, c-format msgid "Line style is %s.\n" msgstr "Linjestil är %s.\n" -#: command.c:4085 +#: command.c:4119 #, c-format msgid "Null display is \"%s\".\n" msgstr "Null-visare är \"%s\".\n" -#: command.c:4093 +#: command.c:4127 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "Lokal-anpassad numerisk utdata är pÃ¥.\n" -#: command.c:4095 +#: command.c:4129 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "Lokal-anpassad numerisk utdata är av.\n" -#: command.c:4102 +#: command.c:4136 #, c-format msgid "Pager is used for long output.\n" msgstr "Siduppdelare är pÃ¥ för lÃ¥ng utdata.\n" -#: command.c:4104 +#: command.c:4138 #, c-format msgid "Pager is always used.\n" msgstr "Siduppdelare används alltid.\n" -#: command.c:4106 +#: command.c:4140 #, c-format msgid "Pager usage is off.\n" msgstr "Siduppdelare är av.\n" -#: command.c:4112 +#: command.c:4146 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "Siduppdelare kommer inte användas för färre än %d linje.\n" msgstr[1] "Siduppdelare kommer inte användas för färre än %d linjer.\n" -#: command.c:4122 command.c:4132 +#: command.c:4156 command.c:4166 #, c-format msgid "Record separator is zero byte.\n" msgstr "Postseparatorn är noll-byte.\n" -#: command.c:4124 +#: command.c:4158 #, c-format msgid "Record separator is .\n" msgstr "Postseparatorn är .\n" -#: command.c:4126 +#: command.c:4160 #, c-format msgid "Record separator is \"%s\".\n" msgstr "Postseparatorn är \"%s\".\n" -#: command.c:4139 +#: command.c:4173 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "Tabellattributen är \"%s\".\n" -#: command.c:4142 +#: command.c:4176 #, c-format msgid "Table attributes unset.\n" msgstr "Tabellattributen är ej satta.\n" -#: command.c:4149 +#: command.c:4183 #, c-format msgid "Title is \"%s\".\n" msgstr "Titeln är \"%s\".\n" -#: command.c:4151 +#: command.c:4185 #, c-format msgid "Title is unset.\n" msgstr "Titeln är inte satt.\n" -#: command.c:4158 +#: command.c:4192 #, c-format msgid "Tuples only is on.\n" msgstr "Visa bara tupler är pÃ¥.\n" -#: command.c:4160 +#: command.c:4194 #, c-format msgid "Tuples only is off.\n" msgstr "Visa bara tupler är av.\n" -#: command.c:4166 +#: command.c:4200 #, c-format msgid "Unicode border line style is \"%s\".\n" msgstr "Unicode-ramstil är \"%s\".\n" -#: command.c:4172 +#: command.c:4206 #, c-format msgid "Unicode column line style is \"%s\".\n" msgstr "Unicode-kolumnLinjestil är \"%s\".\n" -#: command.c:4178 +#: command.c:4212 #, c-format msgid "Unicode header line style is \"%s\".\n" msgstr "Unicode-rubriklinjestil är \"%s\".\n" -#: command.c:4338 +#: command.c:4374 #, c-format -msgid "\\!: failed\n" -msgstr "\\!: misslyckades\n" +msgid "\\!: failed" +msgstr "\\!: misslyckades" -#: command.c:4363 common.c:754 +#: command.c:4399 common.c:781 #, c-format -msgid "\\watch cannot be used with an empty query\n" -msgstr "\\watch kan inte användas pÃ¥ en tom frÃ¥ga\n" +msgid "\\watch cannot be used with an empty query" +msgstr "\\watch kan inte användas pÃ¥ en tom frÃ¥ga" -#: command.c:4404 +#: command.c:4440 #, c-format msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (varje %gs)\n" -#: command.c:4407 +#: command.c:4443 #, c-format msgid "%s (every %gs)\n" msgstr "%s (varje %gs)\n" -#: command.c:4461 command.c:4468 common.c:654 common.c:661 common.c:1271 +#: command.c:4497 command.c:4504 common.c:681 common.c:688 common.c:1345 #, c-format msgid "" "********* QUERY **********\n" @@ -665,102 +721,107 @@ msgstr "" "**************************\n" "\n" -#: command.c:4660 +#: command.c:4696 #, c-format -msgid "\"%s.%s\" is not a view\n" -msgstr "\"%s.%s\" är inte en vy\n" +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\" är inte en vy" -#: command.c:4676 +#: command.c:4712 #, c-format -msgid "could not parse reloptions array\n" -msgstr "kunde inte parsa arrayen reloptions\n" +msgid "could not parse reloptions array" +msgstr "kunde inte parsa arrayen reloptions" -#: common.c:158 +#: common.c:160 #, c-format -msgid "cannot escape without active connection\n" -msgstr "kan inte escape:a utan en aktiv upppkoppling\n" +msgid "cannot escape without active connection" +msgstr "kan inte escape:a utan en aktiv uppkoppling" -#: common.c:199 +#: common.c:201 #, c-format -msgid "shell command argument contains a newline or carriage return: \"%s\"\n" -msgstr "shell-kommandots argument innehÃ¥ller nyrad eller vagnretur: \"%s\"\n" +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "shell-kommandots argument innehÃ¥ller nyrad eller vagnretur: \"%s\"" -#: common.c:415 +#: common.c:395 #, c-format -msgid "connection to server was lost\n" -msgstr "förbindelsen till servern har brutits\n" +msgid "connection to server was lost" +msgstr "förbindelsen till servern har brutits" -#: common.c:419 +#: common.c:399 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "Förbindelsen till servern har brutits. Försöker starta om: " -#: common.c:424 +#: common.c:404 #, c-format msgid "Failed.\n" msgstr "Misslyckades.\n" -#: common.c:431 +#: common.c:411 #, c-format msgid "Succeeded.\n" msgstr "Lyckades.\n" -#: common.c:531 common.c:1034 common.c:1206 +#: common.c:511 common.c:1063 common.c:1280 #, c-format -msgid "unexpected PQresultStatus: %d\n" -msgstr "oväntad PQresultStatus: %d\n" +msgid "unexpected PQresultStatus: %d" +msgstr "oväntad PQresultStatus: %d" -#: common.c:593 +#: common.c:620 #, c-format msgid "Time: %.3f ms\n" msgstr "Tid: %.3f ms\n" -#: common.c:608 +#: common.c:635 #, c-format msgid "Time: %.3f ms (%02d:%06.3f)\n" msgstr "Tid: %.3f ms (%02d:%06.3f)\n" -#: common.c:617 +#: common.c:644 #, c-format msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" msgstr "Tid: %.3f ms (%02d:%02d:%06.3f)\n" -#: common.c:624 +#: common.c:651 #, c-format msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" msgstr "Tid: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" -#: common.c:761 +#: common.c:675 common.c:733 common.c:1316 +#, c-format +msgid "You are currently not connected to a database." +msgstr "Du är för närvarande inte uppkopplad mot en databas." + +#: common.c:788 #, c-format -msgid "\\watch cannot be used with COPY\n" -msgstr "\\watch kan inte användas med COPY\n" +msgid "\\watch cannot be used with COPY" +msgstr "\\watch kan inte användas med COPY" -#: common.c:766 +#: common.c:793 #, c-format -msgid "unexpected result status for \\watch\n" -msgstr "oväntat resultatstatus för \\watch\n" +msgid "unexpected result status for \\watch" +msgstr "oväntat resultatstatus för \\watch" -#: common.c:795 +#: common.c:823 #, c-format msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" msgstr "Asynkron notificering \"%s\" mottagen med innehÃ¥ll \"%s\" frÃ¥n serverprocess med PID %d.\n" -#: common.c:798 +#: common.c:826 #, c-format msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "Asynkron notificering \"%s\" mottagen frÃ¥n serverprocess med PID %d.\n" -#: common.c:860 +#: common.c:889 #, c-format -msgid "no rows returned for \\gset\n" -msgstr "inga rader returnerades för \\gset\n" +msgid "no rows returned for \\gset" +msgstr "inga rader returnerades för \\gset" -#: common.c:865 +#: common.c:894 #, c-format -msgid "more than one row returned for \\gset\n" -msgstr "mer än en rad returnerades för \\gset\n" +msgid "more than one row returned for \\gset" +msgstr "mer än en rad returnerades för \\gset" -#: common.c:1251 +#: common.c:1325 #, c-format msgid "" "***(Single step mode: verify command)*******************************************\n" @@ -771,71 +832,92 @@ msgstr "" "%s\n" "***(tryck return för att fortsätta eller skriv x och return för att avbryta)*****\n" -#: common.c:1306 +#: common.c:1380 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "Servern (version %s) stöder inte sparpunkter för ON_ERROR_ROLLBACK." + +#: common.c:1443 +#, c-format +msgid "STATEMENT: %s" +msgstr "SATS: %s" + +#: common.c:1486 #, c-format -msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" -msgstr "Servern (version %s) stöder inte sparpunkter för ON_ERROR_ROLLBACK.\n" +msgid "unexpected transaction status (%d)" +msgstr "oväntad transaktionsstatus (%d)" + +#: common.c:1623 describe.c:2001 +msgid "Column" +msgstr "Kolumn" -#: common.c:1362 +#: common.c:1624 describe.c:178 describe.c:393 describe.c:411 describe.c:456 +#: describe.c:473 describe.c:962 describe.c:1126 describe.c:1711 +#: describe.c:1735 describe.c:2002 describe.c:3672 describe.c:3857 +#: describe.c:4090 describe.c:5296 +msgid "Type" +msgstr "Typ" + +#: common.c:1673 #, c-format -msgid "STATEMENT: %s\n" -msgstr "SATS: %s\n" +msgid "The command has no result, or the result has no columns.\n" +msgstr "Kommandot hade inget resultat eller sÃ¥ hade resultatet inga kolumner.\n" -#: common.c:1405 +#: copy.c:100 #, c-format -msgid "unexpected transaction status (%d)\n" -msgstr "oväntad transaktionsstatus (%d)\n" +msgid "\\copy: arguments required" +msgstr "\\copy: argument krävs" -#: copy.c:99 +#: copy.c:255 #, c-format -msgid "\\copy: arguments required\n" -msgstr "\\copy: argument krävs\n" +msgid "\\copy: parse error at \"%s\"" +msgstr "\\copy: parsfel vid \"%s\"" -#: copy.c:254 +#: copy.c:257 #, c-format -msgid "\\copy: parse error at \"%s\"\n" -msgstr "\\copy: parsfel vid \"%s\"\n" +msgid "\\copy: parse error at end of line" +msgstr "\\copy: parsfel vid radslutet" -#: copy.c:256 +#: copy.c:330 #, c-format -msgid "\\copy: parse error at end of line\n" -msgstr "\\copy: parsfel vid radslutet\n" +msgid "could not execute command \"%s\": %m" +msgstr "kunde inte köra kommandot \"%s\": %m" -#: copy.c:329 +#: copy.c:346 #, c-format -msgid "could not execute command \"%s\": %s\n" -msgstr "kunde inte utföra kommandot \"%s\": %s\n" +msgid "could not stat file \"%s\": %m" +msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %m" -#: copy.c:345 +#: copy.c:350 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "kunde inte göra stat() pÃ¥ fil \"%s\": %s\n" +msgid "%s: cannot copy from/to a directory" +msgstr "%s: kan inte kopiera frÃ¥n/till en katalog" -#: copy.c:349 +#: copy.c:387 #, c-format -msgid "%s: cannot copy from/to a directory\n" -msgstr "%s: kan inte kopiera frÃ¥n/till en katalog\n" +msgid "could not close pipe to external command: %m" +msgstr "kunde inte stänga rör till externt komamndo: %m" -#: copy.c:386 +#: copy.c:392 #, c-format -msgid "could not close pipe to external command: %s\n" -msgstr "kunde inte stänga rör till externt komamndo: %s\n" +msgid "%s: %s" +msgstr "%s: %s" -#: copy.c:452 copy.c:463 +#: copy.c:455 copy.c:465 #, c-format -msgid "could not write COPY data: %s\n" -msgstr "kunde inte skriva COPY-data: %s\n" +msgid "could not write COPY data: %m" +msgstr "kunde inte skriva COPY-data: %m" -#: copy.c:470 +#: copy.c:471 #, c-format msgid "COPY data transfer failed: %s" msgstr "COPY-överföring av data misslyckades: %s" -#: copy.c:531 +#: copy.c:532 msgid "canceled by user" msgstr "avbruten av användaren" -#: copy.c:542 +#: copy.c:543 msgid "" "Enter data to be copied followed by a newline.\n" "End with a backslash and a period on a line by itself, or an EOF signal." @@ -843,1054 +925,1144 @@ msgstr "" "Mata in data som skall kopieras följt av en nyrad.\n" "Avsluta med bakstreck och en punkt ensamma pÃ¥ en rad eller av en EOF." -#: copy.c:670 +#: copy.c:671 msgid "aborted because of read failure" msgstr "avbruten pÃ¥ grund av läsfel" -#: copy.c:704 +#: copy.c:705 msgid "trying to exit copy mode" msgstr "försöker avsluta kopieringsläge" -#: crosstabview.c:123 +#: crosstabview.c:124 #, c-format -msgid "\\crosstabview: statement did not return a result set\n" -msgstr "\\crosstabview: satsen returnerade ingen resultatmängd\n" +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview: satsen returnerade ingen resultatmängd" -#: crosstabview.c:129 +#: crosstabview.c:130 #, c-format -msgid "\\crosstabview: query must return at least three columns\n" -msgstr "\\crosstabview: frÃ¥gan mÃ¥ste returnera minst tre kolumner\n" +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview: frÃ¥gan mÃ¥ste returnera minst tre kolumner" -#: crosstabview.c:156 +#: crosstabview.c:157 #, c-format -msgid "\\crosstabview: vertical and horizontal headers must be different columns\n" -msgstr "\\crosstabview: vertikala och horisontala rubriker mÃ¥ste vara olika kolumner\n" +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: vertikala och horisontala rubriker mÃ¥ste vara olika kolumner" -#: crosstabview.c:172 +#: crosstabview.c:173 #, c-format -msgid "\\crosstabview: data column must be specified when query returns more than three columns\n" -msgstr "\\crosstabview: datakolumn mÃ¥ste anges när frÃ¥gan returnerar mer än tre kolumner\n" +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: datakolumn mÃ¥ste anges när frÃ¥gan returnerar mer än tre kolumner" -#: crosstabview.c:228 +#: crosstabview.c:229 #, c-format -msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" -msgstr "\\crosstabview: maximalt antal kolumner (%d) överskridet\n" +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: maximalt antal kolumner (%d) överskridet" -#: crosstabview.c:397 +#: crosstabview.c:398 #, c-format -msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n" -msgstr "\\crosstabview: frÃ¥geresultatet innehÃ¥ller multipla värden för rad \"%s\", kolumn \"%s\"\n" +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: frÃ¥geresultatet innehÃ¥ller multipla värden för rad \"%s\", kolumn \"%s\"" -#: crosstabview.c:645 +#: crosstabview.c:646 #, c-format -msgid "\\crosstabview: column number %d is out of range 1..%d\n" -msgstr "\\crosstabview: kolumnnummer %d är utanför giltigt intervall 1..%d\n" +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: kolumnnummer %d är utanför giltigt intervall 1..%d" -#: crosstabview.c:670 +#: crosstabview.c:671 #, c-format -msgid "\\crosstabview: ambiguous column name: \"%s\"\n" -msgstr "\\crosstabview: tvetydigt kolumnnamn: \"%s\"\n" +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: tvetydigt kolumnnamn: \"%s\"" -#: crosstabview.c:678 +#: crosstabview.c:679 #, c-format -msgid "\\crosstabview: column name not found: \"%s\"\n" -msgstr "\\crosstabview: hittar ej kolumnnamn: \"%s\"\n" +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: hittar ej kolumnnamn: \"%s\"" -#: describe.c:74 describe.c:346 describe.c:603 describe.c:735 describe.c:879 -#: describe.c:1040 describe.c:1112 describe.c:3342 describe.c:3554 -#: describe.c:3645 describe.c:3893 describe.c:4038 describe.c:4279 -#: describe.c:4354 describe.c:4365 describe.c:4427 describe.c:4852 -#: describe.c:4935 +#: describe.c:76 describe.c:373 describe.c:678 describe.c:810 describe.c:954 +#: describe.c:1115 describe.c:1187 describe.c:3661 describe.c:3844 +#: describe.c:4088 describe.c:4179 describe.c:4446 describe.c:4606 +#: describe.c:4847 describe.c:4922 describe.c:4933 describe.c:4995 +#: describe.c:5420 describe.c:5503 msgid "Schema" msgstr "Schema" -#: describe.c:75 describe.c:164 describe.c:231 describe.c:239 describe.c:347 -#: describe.c:604 describe.c:736 describe.c:797 describe.c:880 describe.c:1113 -#: describe.c:3343 describe.c:3477 describe.c:3555 describe.c:3646 -#: describe.c:3725 describe.c:3894 describe.c:3963 describe.c:4039 -#: describe.c:4280 describe.c:4355 describe.c:4366 describe.c:4428 -#: describe.c:4625 describe.c:4709 describe.c:4933 describe.c:5105 -#: describe.c:5312 +#: describe.c:77 describe.c:175 describe.c:243 describe.c:251 describe.c:374 +#: describe.c:679 describe.c:811 describe.c:872 describe.c:955 describe.c:1188 +#: describe.c:3662 describe.c:3845 describe.c:4011 describe.c:4089 +#: describe.c:4180 describe.c:4259 describe.c:4447 describe.c:4531 +#: describe.c:4607 describe.c:4848 describe.c:4923 describe.c:4934 +#: describe.c:4996 describe.c:5193 describe.c:5277 describe.c:5501 +#: describe.c:5673 describe.c:5898 msgid "Name" msgstr "Namn" -#: describe.c:76 describe.c:359 describe.c:405 describe.c:422 +#: describe.c:78 describe.c:386 describe.c:404 describe.c:450 describe.c:467 msgid "Result data type" msgstr "Resultatdatatyp" -#: describe.c:84 describe.c:97 describe.c:101 describe.c:360 describe.c:406 -#: describe.c:423 +#: describe.c:86 describe.c:99 describe.c:103 describe.c:387 describe.c:405 +#: describe.c:451 describe.c:468 msgid "Argument data types" msgstr "Argumentdatatyp" -#: describe.c:108 describe.c:174 describe.c:262 describe.c:468 describe.c:652 -#: describe.c:751 describe.c:822 describe.c:1115 describe.c:1756 -#: describe.c:3132 describe.c:3377 describe.c:3508 describe.c:3582 -#: describe.c:3655 describe.c:3738 describe.c:3806 describe.c:3906 -#: describe.c:3972 describe.c:4040 describe.c:4181 describe.c:4223 -#: describe.c:4296 describe.c:4358 describe.c:4367 describe.c:4429 -#: describe.c:4651 describe.c:4731 describe.c:4866 describe.c:4936 -#: large_obj.c:289 large_obj.c:299 +#: describe.c:111 describe.c:118 describe.c:186 describe.c:274 describe.c:513 +#: describe.c:727 describe.c:826 describe.c:897 describe.c:1190 describe.c:2020 +#: describe.c:3450 describe.c:3697 describe.c:3891 describe.c:4042 +#: describe.c:4116 describe.c:4189 describe.c:4272 describe.c:4355 +#: describe.c:4474 describe.c:4540 describe.c:4608 describe.c:4749 +#: describe.c:4791 describe.c:4864 describe.c:4926 describe.c:4935 +#: describe.c:4997 describe.c:5219 describe.c:5299 describe.c:5434 +#: describe.c:5504 large_obj.c:290 large_obj.c:300 msgid "Description" msgstr "Beskrivning" -#: describe.c:126 +#: describe.c:136 msgid "List of aggregate functions" msgstr "Lista med aggregatfunktioner" -#: describe.c:151 +#: describe.c:161 #, c-format -msgid "The server (version %s) does not support access methods.\n" -msgstr "Servern (version %s) stöder inte accessmetoder.\n" +msgid "The server (version %s) does not support access methods." +msgstr "Servern (version %s) stöder inte accessmetoder." -#: describe.c:165 +#: describe.c:176 msgid "Index" msgstr "Index" -#: describe.c:166 describe.c:366 describe.c:411 describe.c:428 describe.c:887 -#: describe.c:1051 describe.c:1716 describe.c:3352 describe.c:3556 -#: describe.c:4728 -msgid "Type" -msgstr "Typ" +#: describe.c:177 describe.c:3678 describe.c:3870 describe.c:5421 +msgid "Table" +msgstr "Tabell" -#: describe.c:173 describe.c:4630 +#: describe.c:185 describe.c:5198 msgid "Handler" msgstr "Hanterare" -#: describe.c:192 +#: describe.c:204 msgid "List of access methods" msgstr "Lista med accessmetoder" -#: describe.c:218 +#: describe.c:230 #, c-format -msgid "The server (version %s) does not support tablespaces.\n" -msgstr "Servern (version %s) stöder inte tabellutrymmen.\n" +msgid "The server (version %s) does not support tablespaces." +msgstr "Servern (version %s) stöder inte tabellutrymmen." -#: describe.c:232 describe.c:240 describe.c:456 describe.c:642 describe.c:798 -#: describe.c:1039 describe.c:3353 describe.c:3481 describe.c:3727 -#: describe.c:3964 describe.c:4626 describe.c:4710 describe.c:5106 -#: describe.c:5218 describe.c:5313 large_obj.c:288 +#: describe.c:244 describe.c:252 describe.c:501 describe.c:717 describe.c:873 +#: describe.c:1114 describe.c:3673 describe.c:3846 describe.c:4015 +#: describe.c:4261 describe.c:4532 describe.c:5194 describe.c:5278 +#: describe.c:5674 describe.c:5800 describe.c:5899 large_obj.c:289 msgid "Owner" msgstr "Ägare" -#: describe.c:233 describe.c:241 +#: describe.c:245 describe.c:253 msgid "Location" msgstr "Plats" -#: describe.c:252 describe.c:2944 +#: describe.c:264 describe.c:3268 msgid "Options" msgstr "Alternativ" -#: describe.c:257 describe.c:615 describe.c:814 describe.c:3369 -#: describe.c:3373 +#: describe.c:269 describe.c:690 describe.c:889 describe.c:3689 describe.c:3693 msgid "Size" msgstr "Storlek" -#: describe.c:279 +#: describe.c:291 msgid "List of tablespaces" msgstr "Lista med tabellutrymmen" -#: describe.c:320 +#: describe.c:333 #, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df tar bara [antwS+] som flaggor\n" +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df tar bara [anptwS+] som flaggor" -#: describe.c:328 +#: describe.c:341 describe.c:352 #, c-format -msgid "\\df does not take a \"w\" option with server version %s\n" -msgstr "\\df tar inte en \"w\"-flagga med serverversion %s\n" +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df tar inte en \"%c\"-flagga med serverversion %s" #. translator: "agg" is short for "aggregate" -#: describe.c:362 describe.c:408 describe.c:425 +#: describe.c:389 describe.c:407 describe.c:453 describe.c:470 msgid "agg" msgstr "agg" -#: describe.c:363 +#: describe.c:390 describe.c:408 msgid "window" msgstr "fönster" -#: describe.c:364 describe.c:409 describe.c:426 describe.c:1249 +#: describe.c:391 +msgid "proc" +msgstr "proc" + +#: describe.c:392 describe.c:410 describe.c:455 describe.c:472 +msgid "func" +msgstr "funk" + +#: describe.c:409 describe.c:454 describe.c:471 describe.c:1324 msgid "trigger" msgstr "utlösare" -#: describe.c:365 describe.c:410 describe.c:427 -msgid "normal" -msgstr "normal" - -#: describe.c:438 +#: describe.c:483 msgid "immutable" msgstr "oföränderlig" -#: describe.c:439 +#: describe.c:484 msgid "stable" msgstr "stabil" -#: describe.c:440 +#: describe.c:485 msgid "volatile" msgstr "flyktig" -#: describe.c:441 +#: describe.c:486 msgid "Volatility" msgstr "Flyktighet" -#: describe.c:449 +#: describe.c:494 msgid "restricted" msgstr "begränsad" -#: describe.c:450 +#: describe.c:495 msgid "safe" msgstr "säker" -#: describe.c:451 +#: describe.c:496 msgid "unsafe" msgstr "osäker" -#: describe.c:452 +#: describe.c:497 msgid "Parallel" msgstr "Parallell" -#: describe.c:457 +#: describe.c:502 msgid "definer" msgstr "definierare" -#: describe.c:458 +#: describe.c:503 msgid "invoker" msgstr "anropare" -#: describe.c:459 +#: describe.c:504 msgid "Security" msgstr "Säkerhet" -#: describe.c:466 +#: describe.c:511 msgid "Language" msgstr "SprÃ¥k" -#: describe.c:467 +#: describe.c:512 msgid "Source code" msgstr "Källkod" -#: describe.c:566 +#: describe.c:641 msgid "List of functions" msgstr "Lista med funktioner" -#: describe.c:614 +#: describe.c:689 msgid "Internal name" msgstr "Internt namn" -#: describe.c:636 +#: describe.c:711 msgid "Elements" msgstr "Element" -#: describe.c:693 +#: describe.c:768 msgid "List of data types" msgstr "Lista med datatyper" -#: describe.c:737 +#: describe.c:812 msgid "Left arg type" msgstr "Vänster argumenttyp" -#: describe.c:738 +#: describe.c:813 msgid "Right arg type" msgstr "Höger argumenttyp" -#: describe.c:739 +#: describe.c:814 msgid "Result type" msgstr "Resultattyp" -#: describe.c:744 describe.c:3797 describe.c:4180 +#: describe.c:819 describe.c:4267 describe.c:4332 describe.c:4338 +#: describe.c:4748 msgid "Function" msgstr "Funktion" -#: describe.c:769 +#: describe.c:844 msgid "List of operators" msgstr "Lista med operatorer" -#: describe.c:799 +#: describe.c:874 msgid "Encoding" msgstr "Kodning" -#: describe.c:804 describe.c:3895 +#: describe.c:879 describe.c:4448 msgid "Collate" msgstr "Jämförelse" -#: describe.c:805 describe.c:3896 +#: describe.c:880 describe.c:4449 msgid "Ctype" msgstr "Ctype" -#: describe.c:818 +#: describe.c:893 msgid "Tablespace" msgstr "Tabellutrymme" -#: describe.c:840 +#: describe.c:915 msgid "List of databases" msgstr "Lista med databaser" -#: describe.c:881 describe.c:886 describe.c:1042 describe.c:3344 -#: describe.c:3351 +#: describe.c:956 describe.c:1117 describe.c:3663 msgid "table" msgstr "tabell" -#: describe.c:882 describe.c:3345 +#: describe.c:957 describe.c:3664 msgid "view" msgstr "vy" -#: describe.c:883 describe.c:3346 +#: describe.c:958 describe.c:3665 msgid "materialized view" msgstr "materialiserad vy" -#: describe.c:884 describe.c:1044 describe.c:3348 +#: describe.c:959 describe.c:1119 describe.c:3667 msgid "sequence" msgstr "sekvens" -#: describe.c:885 describe.c:3350 +#: describe.c:960 describe.c:3669 msgid "foreign table" msgstr "främmande tabell" -#: describe.c:898 +#: describe.c:961 describe.c:3670 describe.c:3855 +msgid "partitioned table" +msgstr "partitionerad tabell" + +#: describe.c:973 msgid "Column privileges" msgstr "Kolumnrättigheter" -#: describe.c:929 describe.c:963 +#: describe.c:1004 describe.c:1038 msgid "Policies" msgstr "Policys" -#: describe.c:995 describe.c:5369 describe.c:5373 +#: describe.c:1070 describe.c:5955 describe.c:5959 msgid "Access privileges" msgstr "Ã…tkomsträttigheter" -#: describe.c:1026 +#: describe.c:1101 #, c-format -msgid "The server (version %s) does not support altering default privileges.\n" -msgstr "Servern (version %s) stöder inte ändring av standardrättigheter.\n" +msgid "The server (version %s) does not support altering default privileges." +msgstr "Servern (version %s) stöder inte ändring av standardrättigheter." -#: describe.c:1046 +#: describe.c:1121 msgid "function" msgstr "funktion" -#: describe.c:1048 +#: describe.c:1123 msgid "type" msgstr "typ" -#: describe.c:1050 +#: describe.c:1125 msgid "schema" msgstr "schema" -#: describe.c:1074 +#: describe.c:1149 msgid "Default access privileges" msgstr "Standard accessrättigheter" -#: describe.c:1114 +#: describe.c:1189 msgid "Object" msgstr "Objekt" -#: describe.c:1128 +#: describe.c:1203 msgid "table constraint" msgstr "tabellvillkor" -#: describe.c:1150 +#: describe.c:1225 msgid "domain constraint" msgstr "domänvillkor" -#: describe.c:1178 +#: describe.c:1253 msgid "operator class" msgstr "operatorklass" -#: describe.c:1207 +#: describe.c:1282 msgid "operator family" msgstr "operatorfamilj" -#: describe.c:1229 +#: describe.c:1304 msgid "rule" msgstr "rule" -#: describe.c:1271 +#: describe.c:1346 msgid "Object descriptions" msgstr "Objektbeskrivningar" -#: describe.c:1327 describe.c:3440 +#: describe.c:1402 describe.c:3761 +#, c-format +msgid "Did not find any relation named \"%s\"." +msgstr "Kunde inte hitta en relation med namn \"%s\"." + +#: describe.c:1405 describe.c:3764 +#, c-format +msgid "Did not find any relations." +msgstr "Kunde inte hitta nÃ¥gra relationer." + +#: describe.c:1660 +#, c-format +msgid "Did not find any relation with OID %s." +msgstr "Kunde inte hitta en relation med OID %s." + +#: describe.c:1712 describe.c:1736 +msgid "Start" +msgstr "Start" + +#: describe.c:1713 describe.c:1737 +msgid "Minimum" +msgstr "Minimum" + +#: describe.c:1714 describe.c:1738 +msgid "Maximum" +msgstr "Maximum" + +#: describe.c:1715 describe.c:1739 +msgid "Increment" +msgstr "Ökning" + +#: describe.c:1716 describe.c:1740 describe.c:1871 describe.c:4183 +#: describe.c:4349 describe.c:4463 describe.c:4468 +msgid "yes" +msgstr "ja" + +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4183 +#: describe.c:4346 describe.c:4463 +msgid "no" +msgstr "nej" + +#: describe.c:1718 describe.c:1742 +msgid "Cycles?" +msgstr "Cyklisk?" + +#: describe.c:1719 describe.c:1743 +msgid "Cache" +msgstr "Cache" + +#: describe.c:1786 #, c-format -msgid "Did not find any relation named \"%s\".\n" -msgstr "Kunde inte hitta en relation med namn \"%s\".\n" +msgid "Owned by: %s" +msgstr "Ägd av: %s" -#: describe.c:1330 describe.c:3443 +#: describe.c:1790 #, c-format -msgid "Did not find any relations.\n" -msgstr "Kunde inte hitta nÃ¥gra relationer.\n" +msgid "Sequence for identity column: %s" +msgstr "Sekvens för identitetskolumn: %s" -#: describe.c:1539 +#: describe.c:1797 #, c-format -msgid "Did not find any relation with OID %s.\n" -msgstr "Kunde inte hitta en relation med OID %s.\n" +msgid "Sequence \"%s.%s\"" +msgstr "Sekvens \"%s.%s\"" -#: describe.c:1652 describe.c:1701 +#: describe.c:1933 #, c-format msgid "Unlogged table \"%s.%s\"" msgstr "Ologgad tabell \"%s.%s\"" -#: describe.c:1655 describe.c:1704 +#: describe.c:1936 #, c-format msgid "Table \"%s.%s\"" msgstr "Tabell \"%s.%s\"" -#: describe.c:1659 +#: describe.c:1940 #, c-format msgid "View \"%s.%s\"" msgstr "Vy \"%s.%s\"" -#: describe.c:1664 +#: describe.c:1945 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "Ologgad materialiserad vy \"%s.%s\"" -#: describe.c:1667 +#: describe.c:1948 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "Materialiserad vy \"%s.%s\"" -#: describe.c:1671 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "Sekvens \"%s.%s\"" - -#: describe.c:1676 +#: describe.c:1953 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "Ologgat index \"%s.%s\"" -#: describe.c:1679 +#: describe.c:1956 #, c-format msgid "Index \"%s.%s\"" msgstr "Index \"%s.%s\"" -#: describe.c:1684 +#: describe.c:1961 +#, c-format +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "Ologgat partitionerat index \"%s.%s\"" + +#: describe.c:1964 +#, c-format +msgid "Partitioned index \"%s.%s\"" +msgstr "Partitionerat index \"%s.%s\"" + +#: describe.c:1969 #, c-format msgid "Special relation \"%s.%s\"" msgstr "Särskild relation \"%s.%s\"" -#: describe.c:1688 +#: describe.c:1973 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST-tabell \"%s.%s\"" -#: describe.c:1692 +#: describe.c:1977 #, c-format msgid "Composite type \"%s.%s\"" msgstr "Sammansatt typ \"%s.%s\"" -#: describe.c:1696 +#: describe.c:1981 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "Främmande tabell \"%s.%s\"" -#: describe.c:1715 -msgid "Column" -msgstr "Kolumn" +#: describe.c:1986 +#, c-format +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "Ologgad partitionerad tabell \"%s.%s\"" + +#: describe.c:1989 +#, c-format +msgid "Partitioned table \"%s.%s\"" +msgstr "Partitionerad tabell \"%s.%s\"" -#: describe.c:1726 describe.c:3562 +#: describe.c:2005 describe.c:4096 msgid "Collation" -msgstr "Collation" +msgstr "Jämförelse" -#: describe.c:1727 describe.c:3569 +#: describe.c:2006 describe.c:4103 msgid "Nullable" msgstr "Nullbar" -#: describe.c:1728 describe.c:3570 +#: describe.c:2007 describe.c:4104 msgid "Default" msgstr "Standard" -#: describe.c:1733 -msgid "Value" -msgstr "Värde" +#: describe.c:2010 +msgid "Key?" +msgstr "Nyckel?" -#: describe.c:1736 +#: describe.c:2012 msgid "Definition" msgstr "Definition" -#: describe.c:1739 describe.c:4646 describe.c:4730 describe.c:4801 -#: describe.c:4865 +#: describe.c:2014 describe.c:5214 describe.c:5298 describe.c:5369 +#: describe.c:5433 msgid "FDW options" msgstr "FDW-alternativ" -#: describe.c:1743 +#: describe.c:2016 msgid "Storage" msgstr "Lagring" -#: describe.c:1748 +#: describe.c:2018 msgid "Stats target" msgstr "StatistikmÃ¥l" -#: describe.c:1897 +#: describe.c:2136 #, c-format msgid "Partition of: %s %s" msgstr "Partition av: %s %s" -#: describe.c:1903 +#: describe.c:2144 +msgid "No partition constraint" +msgstr "Inget partitioneringsvillkor" + +#: describe.c:2146 #, c-format msgid "Partition constraint: %s" msgstr "Partitioneringsvillkor: %s" -#: describe.c:1926 +#: describe.c:2169 #, c-format msgid "Partition key: %s" -msgstr "Partioneringsnyckel: %s" +msgstr "Partitioneringsnyckel: %s" -#: describe.c:1994 +#: describe.c:2238 msgid "primary key, " msgstr "primärnyckel, " -#: describe.c:1996 +#: describe.c:2240 msgid "unique, " msgstr "unik, " -#: describe.c:2002 +#: describe.c:2246 #, c-format msgid "for table \"%s.%s\"" msgstr "för tabell \"%s.%s\"" -#: describe.c:2006 +#: describe.c:2250 #, c-format msgid ", predicate (%s)" msgstr ", predikat (%s)" -#: describe.c:2009 +#: describe.c:2253 msgid ", clustered" msgstr ", klustrad" -#: describe.c:2012 +#: describe.c:2256 msgid ", invalid" msgstr ", ogiltig" -#: describe.c:2015 +#: describe.c:2259 msgid ", deferrable" msgstr ", uppskjutbar" -#: describe.c:2018 +#: describe.c:2262 msgid ", initially deferred" msgstr ", initialt uppskjuten" -#: describe.c:2021 +#: describe.c:2265 msgid ", replica identity" msgstr ", replikaidentitet" -#: describe.c:2060 -#, c-format -msgid "Owned by: %s" -msgstr "Ägd av: %s" - -#: describe.c:2065 -#, c-format -msgid "Sequence for identity column: %s" -msgstr "Sekvens för identitetskolumn: %s" - -#: describe.c:2129 +#: describe.c:2324 msgid "Indexes:" msgstr "Index:" -#: describe.c:2213 +#: describe.c:2408 msgid "Check constraints:" msgstr "Kontrollvillkor:" -#: describe.c:2244 +#: describe.c:2476 msgid "Foreign-key constraints:" msgstr "Främmande nyckel-villkor:" -#: describe.c:2275 +#: describe.c:2539 msgid "Referenced by:" msgstr "Refererad av:" -#: describe.c:2325 +#: describe.c:2589 msgid "Policies:" msgstr "Policys:" -#: describe.c:2328 +#: describe.c:2592 msgid "Policies (forced row security enabled):" msgstr "Policys (tvingad radsäkerhet pÃ¥slagen):" -#: describe.c:2331 +#: describe.c:2595 msgid "Policies (row security enabled): (none)" msgstr "Policys (radsäkerhet pÃ¥slagna): (ingen)" -#: describe.c:2334 +#: describe.c:2598 msgid "Policies (forced row security enabled): (none)" msgstr "Policys (tvingad radsäkerhet pÃ¥slagen): (ingen)" -#: describe.c:2337 +#: describe.c:2601 msgid "Policies (row security disabled):" msgstr "Policys (radsäkerhet avstängd):" -#: describe.c:2399 +#: describe.c:2664 msgid "Statistics objects:" msgstr "Statistikobjekt:" -#: describe.c:2502 describe.c:2587 +#: describe.c:2773 describe.c:2877 msgid "Rules:" msgstr "Regler:" -#: describe.c:2505 +#: describe.c:2776 msgid "Disabled rules:" msgstr "Avstängda regler:" -#: describe.c:2508 +#: describe.c:2779 msgid "Rules firing always:" msgstr "Regler som alltid utförs:" -#: describe.c:2511 +#: describe.c:2782 msgid "Rules firing on replica only:" msgstr "Regler som utförs enbart pÃ¥ replika:" -#: describe.c:2551 +#: describe.c:2822 msgid "Publications:" msgstr "Publiceringar:" -#: describe.c:2570 +#: describe.c:2860 msgid "View definition:" msgstr "Vydefinition:" -#: describe.c:2705 +#: describe.c:2999 msgid "Triggers:" msgstr "Utlösare:" -#: describe.c:2709 +#: describe.c:3003 msgid "Disabled user triggers:" msgstr "Avstängda användarutlösare:" -#: describe.c:2711 +#: describe.c:3005 msgid "Disabled triggers:" msgstr "Avstängda utlösare:" -#: describe.c:2714 +#: describe.c:3008 msgid "Disabled internal triggers:" msgstr "Avstängda interna utlösare:" -#: describe.c:2717 +#: describe.c:3011 msgid "Triggers firing always:" msgstr "Utlösare som alltid aktiveras:" -#: describe.c:2720 +#: describe.c:3014 msgid "Triggers firing on replica only:" msgstr "Utlösare som aktiveras enbart pÃ¥ replika:" -#: describe.c:2779 +#: describe.c:3073 #, c-format msgid "Server: %s" msgstr "Server: %s" -#: describe.c:2787 +#: describe.c:3081 #, c-format msgid "FDW options: (%s)" msgstr "FDW-alternativ: (%s)" -#: describe.c:2806 +#: describe.c:3100 msgid "Inherits" msgstr "Ärver" -#: describe.c:2860 +#: describe.c:3159 +#, c-format +msgid "Number of partitions: %d" +msgstr "Antal partitioner: %d" + +#: describe.c:3168 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "Antal barntabeller: %d (Använd \\d+ för att lista dem.)" -#: describe.c:2862 +#: describe.c:3170 #, c-format msgid "Number of partitions: %d (Use \\d+ to list them.)" msgstr "Antal partitioner: %d (Använd \\d+ för att lista dem.)" -#: describe.c:2870 +#: describe.c:3178 msgid "Child tables" msgstr "Barntabeller" -#: describe.c:2870 +#: describe.c:3178 msgid "Partitions" msgstr "Partitioner" -#: describe.c:2904 +#: describe.c:3221 #, c-format msgid "Typed table of type: %s" msgstr "Typad tabell av typ: %s" -#: describe.c:2920 +#: describe.c:3237 msgid "Replica Identity" msgstr "Replikaidentitet" -#: describe.c:2933 +#: describe.c:3250 msgid "Has OIDs: yes" msgstr "Har OID:er: ja" -#: describe.c:3020 +#: describe.c:3259 +#, c-format +msgid "Access method: %s" +msgstr "Accessmetod: %s" + +#: describe.c:3338 #, c-format msgid "Tablespace: \"%s\"" msgstr "Tabellutrymme: \"%s\"" #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:3032 +#: describe.c:3350 #, c-format msgid ", tablespace \"%s\"" msgstr ", tabellutrymme: \"%s\"" -#: describe.c:3125 +#: describe.c:3443 msgid "List of roles" msgstr "Lista med roller" -#: describe.c:3127 +#: describe.c:3445 msgid "Role name" msgstr "Rollnamn" -#: describe.c:3128 +#: describe.c:3446 msgid "Attributes" msgstr "Attribut" -#: describe.c:3129 +#: describe.c:3447 msgid "Member of" msgstr "Medlem av" -#: describe.c:3140 +#: describe.c:3458 msgid "Superuser" msgstr "Superanvändare" -#: describe.c:3143 +#: describe.c:3461 msgid "No inheritance" msgstr "Inget arv" -#: describe.c:3146 +#: describe.c:3464 msgid "Create role" msgstr "Skapa roll" -#: describe.c:3149 +#: describe.c:3467 msgid "Create DB" msgstr "Skapa DB" -#: describe.c:3152 +#: describe.c:3470 msgid "Cannot login" msgstr "Kan inte logga in" -#: describe.c:3156 +#: describe.c:3474 msgid "Replication" msgstr "Replikering" -#: describe.c:3160 +#: describe.c:3478 msgid "Bypass RLS" msgstr "Hopp över RLS" -#: describe.c:3169 +#: describe.c:3487 msgid "No connections" msgstr "Inga uppkopplingar" -#: describe.c:3171 +#: describe.c:3489 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d uppkoppling" msgstr[1] "%d uppkopplingar" -#: describe.c:3181 +#: describe.c:3499 msgid "Password valid until " msgstr "Lösenord giltigt till " -#: describe.c:3231 +#: describe.c:3549 #, c-format -msgid "The server (version %s) does not support per-database role settings.\n" -msgstr "Servern (version %s) stöder inte rollinställningar per databas.\n" +msgid "The server (version %s) does not support per-database role settings." +msgstr "Servern (version %s) stöder inte rollinställningar per databas." -#: describe.c:3244 +#: describe.c:3562 msgid "Role" msgstr "Roll" -#: describe.c:3245 +#: describe.c:3563 msgid "Database" msgstr "Databas" -#: describe.c:3246 +#: describe.c:3564 msgid "Settings" msgstr "Inställningar" -#: describe.c:3267 +#: describe.c:3585 #, c-format -msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" -msgstr "Kunde inte hitta nÃ¥gra inställningar för roll \"%s\" och databas \"%s\".\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "Kunde inte hitta nÃ¥gra inställningar för roll \"%s\" och databas \"%s\"." -#: describe.c:3270 +#: describe.c:3588 #, c-format -msgid "Did not find any settings for role \"%s\".\n" -msgstr "Kunde inte hitta nÃ¥gra inställningar för roll \"%s\".\n" +msgid "Did not find any settings for role \"%s\"." +msgstr "Kunde inte hitta nÃ¥gra inställningar för roll \"%s\"." -#: describe.c:3273 +#: describe.c:3591 #, c-format -msgid "Did not find any settings.\n" -msgstr "Kunde inte hitta nÃ¥gra inställningar.\n" +msgid "Did not find any settings." +msgstr "Kunde inte hitta nÃ¥gra inställningar." -#: describe.c:3278 +#: describe.c:3596 msgid "List of settings" msgstr "Lista med inställningar" -#: describe.c:3347 +#: describe.c:3666 msgid "index" msgstr "index" -#: describe.c:3349 +#: describe.c:3668 msgid "special" msgstr "särskild" -#: describe.c:3358 describe.c:4853 -msgid "Table" -msgstr "Tabell" +#: describe.c:3671 describe.c:3856 +msgid "partitioned index" +msgstr "partitionerat index" -#: describe.c:3448 +#: describe.c:3769 msgid "List of relations" msgstr "Lista med relationer" -#: describe.c:3485 +#: describe.c:3817 +#, c-format +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "Servern (version %s) stöder inte deklarativ tabellpartitionering." + +#: describe.c:3828 +msgid "List of partitioned indexes" +msgstr "Lista med partitionerade index" + +#: describe.c:3830 +msgid "List of partitioned tables" +msgstr "Lista med partitionerade tabeller" + +#: describe.c:3834 +msgid "List of partitioned relations" +msgstr "Lista med partitionerade relationer" + +#: describe.c:3865 +msgid "Parent name" +msgstr "Föräldranamn" + +#: describe.c:3878 +msgid "Leaf partition size" +msgstr "Partitionsstorlek av löv" + +#: describe.c:3881 describe.c:3887 +msgid "Total size" +msgstr "Total storlek" + +#: describe.c:4019 msgid "Trusted" msgstr "Tillförlitlig" -#: describe.c:3493 +#: describe.c:4027 msgid "Internal language" msgstr "Internt sprÃ¥k" -#: describe.c:3494 +#: describe.c:4028 msgid "Call handler" msgstr "Anropshanterare" -#: describe.c:3495 describe.c:4633 +#: describe.c:4029 describe.c:5201 msgid "Validator" msgstr "Validerare" -#: describe.c:3498 +#: describe.c:4032 msgid "Inline handler" msgstr "Inline-hanterare" -#: describe.c:3526 +#: describe.c:4060 msgid "List of languages" msgstr "Lista med sprÃ¥k" -#: describe.c:3571 +#: describe.c:4105 msgid "Check" msgstr "Check" -#: describe.c:3613 +#: describe.c:4147 msgid "List of domains" msgstr "Lista med domäner" -#: describe.c:3647 +#: describe.c:4181 msgid "Source" msgstr "Källa" -#: describe.c:3648 +#: describe.c:4182 msgid "Destination" msgstr "MÃ¥l" -#: describe.c:3649 describe.c:3798 -msgid "no" -msgstr "nej" - -#: describe.c:3649 describe.c:3800 -msgid "yes" -msgstr "ja" - -#: describe.c:3650 +#: describe.c:4184 msgid "Default?" msgstr "Standard?" -#: describe.c:3687 +#: describe.c:4221 msgid "List of conversions" msgstr "Lista med konverteringar" -#: describe.c:3726 +#: describe.c:4260 msgid "Event" msgstr "Händelse" -#: describe.c:3728 +#: describe.c:4262 msgid "enabled" msgstr "pÃ¥slagen" -#: describe.c:3729 +#: describe.c:4263 msgid "replica" msgstr "replika" -#: describe.c:3730 +#: describe.c:4264 msgid "always" msgstr "alltid" -#: describe.c:3731 +#: describe.c:4265 msgid "disabled" msgstr "avstängd" -#: describe.c:3732 describe.c:5314 +#: describe.c:4266 describe.c:5900 msgid "Enabled" msgstr "PÃ¥slagen" -#: describe.c:3733 -msgid "Procedure" -msgstr "Procedur" - -#: describe.c:3734 +#: describe.c:4268 msgid "Tags" msgstr "Etiketter" -#: describe.c:3753 +#: describe.c:4287 msgid "List of event triggers" msgstr "Lista med händelseutlösare" -#: describe.c:3795 +#: describe.c:4316 msgid "Source type" msgstr "Källtyp" -#: describe.c:3796 +#: describe.c:4317 msgid "Target type" msgstr "MÃ¥ltyp" -#: describe.c:3799 +#: describe.c:4348 msgid "in assignment" msgstr "i tilldelning" -#: describe.c:3801 +#: describe.c:4350 msgid "Implicit?" msgstr "Implicit?" -#: describe.c:3852 +#: describe.c:4405 msgid "List of casts" msgstr "Lista med typomvandlingar" -#: describe.c:3880 +#: describe.c:4433 #, c-format -msgid "The server (version %s) does not support collations.\n" -msgstr "Servern (version %s) stöder inte jämförelser (collations).\n" +msgid "The server (version %s) does not support collations." +msgstr "Servern (version %s) stöder inte jämförelser (collations)." -#: describe.c:3901 +#: describe.c:4454 describe.c:4458 msgid "Provider" msgstr "Leverantör" -#: describe.c:3936 +#: describe.c:4464 describe.c:4469 +msgid "Deterministic?" +msgstr "Deterministisk?" + +#: describe.c:4504 msgid "List of collations" msgstr "Lista med jämförelser (collations)" -#: describe.c:3995 +#: describe.c:4563 msgid "List of schemas" msgstr "Lista med scheman" -#: describe.c:4020 describe.c:4267 describe.c:4338 describe.c:4409 +#: describe.c:4588 describe.c:4835 describe.c:4906 describe.c:4977 #, c-format -msgid "The server (version %s) does not support full text search.\n" -msgstr "Servern (version %s) stöder inte fulltextsökning.\n" +msgid "The server (version %s) does not support full text search." +msgstr "Servern (version %s) stöder inte fulltextsökning." -#: describe.c:4055 +#: describe.c:4623 msgid "List of text search parsers" msgstr "Lista med textsökparsrar" -#: describe.c:4100 +#: describe.c:4668 #, c-format -msgid "Did not find any text search parser named \"%s\".\n" -msgstr "Kunde inte hitta en textsökparser med namn \"%s\".\n" +msgid "Did not find any text search parser named \"%s\"." +msgstr "Kunde inte hitta en textsökparser med namn \"%s\"." -#: describe.c:4103 +#: describe.c:4671 #, c-format -msgid "Did not find any text search parsers.\n" -msgstr "Kunde inte hitta nÃ¥gra textsökparsrar.\n" +msgid "Did not find any text search parsers." +msgstr "Kunde inte hitta nÃ¥gra textsökparsrar." -#: describe.c:4178 +#: describe.c:4746 msgid "Start parse" msgstr "Starta parsning" -#: describe.c:4179 +#: describe.c:4747 msgid "Method" msgstr "Metod" -#: describe.c:4183 +#: describe.c:4751 msgid "Get next token" msgstr "Hämta nästa symbol" -#: describe.c:4185 +#: describe.c:4753 msgid "End parse" msgstr "Avsluta parsning" -#: describe.c:4187 +#: describe.c:4755 msgid "Get headline" msgstr "Hämta rubrik" -#: describe.c:4189 +#: describe.c:4757 msgid "Get token types" msgstr "Hämta symboltyper" -#: describe.c:4200 +#: describe.c:4768 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "Textsökparser \"%s.%s\"" -#: describe.c:4203 +#: describe.c:4771 #, c-format msgid "Text search parser \"%s\"" msgstr "Textsökparser \"%s\"" -#: describe.c:4222 +#: describe.c:4790 msgid "Token name" msgstr "Symbolnamn" -#: describe.c:4233 +#: describe.c:4801 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "Symboltyper för parser \"%s.%s\"" -#: describe.c:4236 +#: describe.c:4804 #, c-format msgid "Token types for parser \"%s\"" msgstr "Symboltyper för parser \"%s\"" -#: describe.c:4290 +#: describe.c:4858 msgid "Template" msgstr "Mall" -#: describe.c:4291 +#: describe.c:4859 msgid "Init options" msgstr "Initieringsalternativ" -#: describe.c:4313 +#: describe.c:4881 msgid "List of text search dictionaries" msgstr "Lista med textsökordlistor" -#: describe.c:4356 +#: describe.c:4924 msgid "Init" msgstr "Init" -#: describe.c:4357 +#: describe.c:4925 msgid "Lexize" msgstr "Symboluppdelning" -#: describe.c:4384 +#: describe.c:4952 msgid "List of text search templates" msgstr "Lista med textsökmallar" -#: describe.c:4444 +#: describe.c:5012 msgid "List of text search configurations" msgstr "Lista med textsökkonfigurationer" -#: describe.c:4490 +#: describe.c:5058 #, c-format -msgid "Did not find any text search configuration named \"%s\".\n" -msgstr "Kunde inte hitta en textsökkonfiguration med namn \"%s\".\n" +msgid "Did not find any text search configuration named \"%s\"." +msgstr "Kunde inte hitta en textsökkonfiguration med namn \"%s\"." -#: describe.c:4493 +#: describe.c:5061 #, c-format -msgid "Did not find any text search configurations.\n" -msgstr "Kunde inte hitta nÃ¥gra textsökkonfigurationer.\n" +msgid "Did not find any text search configurations." +msgstr "Kunde inte hitta nÃ¥gra textsökkonfigurationer." -#: describe.c:4559 +#: describe.c:5127 msgid "Token" msgstr "Symbol" -#: describe.c:4560 +#: describe.c:5128 msgid "Dictionaries" msgstr "Ordlistor" -#: describe.c:4571 +#: describe.c:5139 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "Textsökkonfiguration \"%s.%s\"" -#: describe.c:4574 +#: describe.c:5142 #, c-format msgid "Text search configuration \"%s\"" msgstr "Textsökkonfiguration \"%s\"" -#: describe.c:4578 +#: describe.c:5146 #, c-format msgid "" "\n" @@ -1899,7 +2071,7 @@ msgstr "" "\n" "Parser: \"%s.%s\"" -#: describe.c:4581 +#: describe.c:5149 #, c-format msgid "" "\n" @@ -1908,157 +2080,156 @@ msgstr "" "\n" "Parser: \"%s\"" -#: describe.c:4615 +#: describe.c:5183 #, c-format -msgid "The server (version %s) does not support foreign-data wrappers.\n" -msgstr "Servern (version %s) stöder inte främmande data-omvandlare.\n" +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "Servern (version %s) stöder inte främmande data-omvandlare." -#: describe.c:4673 +#: describe.c:5241 msgid "List of foreign-data wrappers" msgstr "Lista med främmande data-omvandlare" -#: describe.c:4698 +#: describe.c:5266 #, c-format -msgid "The server (version %s) does not support foreign servers.\n" -msgstr "Servern (version %s) stöder inte främmande servrar.\n" +msgid "The server (version %s) does not support foreign servers." +msgstr "Servern (version %s) stöder inte främmande servrar." -#: describe.c:4711 +#: describe.c:5279 msgid "Foreign-data wrapper" msgstr "Främmande data-omvandlare" -#: describe.c:4729 describe.c:4934 +#: describe.c:5297 describe.c:5502 msgid "Version" msgstr "Version" -#: describe.c:4755 +#: describe.c:5323 msgid "List of foreign servers" msgstr "Lista med främmande servrar" -#: describe.c:4780 +#: describe.c:5348 #, c-format -msgid "The server (version %s) does not support user mappings.\n" -msgstr "Servern (version %s) stöder inte användarmappningar.\n" +msgid "The server (version %s) does not support user mappings." +msgstr "Servern (version %s) stöder inte användarmappningar." -#: describe.c:4790 describe.c:4854 +#: describe.c:5358 describe.c:5422 msgid "Server" msgstr "Server" -#: describe.c:4791 +#: describe.c:5359 msgid "User name" msgstr "Användarnamn" -#: describe.c:4816 +#: describe.c:5384 msgid "List of user mappings" msgstr "Lista av användarmappningar" -#: describe.c:4841 +#: describe.c:5409 #, c-format -msgid "The server (version %s) does not support foreign tables.\n" -msgstr "Servern (version %s) stöder inte främmande tabeller.\n" +msgid "The server (version %s) does not support foreign tables." +msgstr "Servern (version %s) stöder inte främmande tabeller." -#: describe.c:4894 +#: describe.c:5462 msgid "List of foreign tables" msgstr "Lista med främmande tabeller" -#: describe.c:4919 describe.c:4976 +#: describe.c:5487 describe.c:5544 #, c-format -msgid "The server (version %s) does not support extensions.\n" -msgstr "Servern (version %s) stöder inte utökningar.\n" +msgid "The server (version %s) does not support extensions." +msgstr "Servern (version %s) stöder inte utökningar." -#: describe.c:4951 +#: describe.c:5519 msgid "List of installed extensions" msgstr "Lista med installerade utökningar" -#: describe.c:5004 +#: describe.c:5572 #, c-format -msgid "Did not find any extension named \"%s\".\n" -msgstr "Kunde inte hitta en utökning med namn \"%s\".\n" +msgid "Did not find any extension named \"%s\"." +msgstr "Kunde inte hitta en utökning med namn \"%s\"." -#: describe.c:5007 +#: describe.c:5575 #, c-format -msgid "Did not find any extensions.\n" -msgstr "Kunde inte hitta nÃ¥gra utökningar.\n" +msgid "Did not find any extensions." +msgstr "Kunde inte hitta nÃ¥gra utökningar." -#: describe.c:5051 +#: describe.c:5619 msgid "Object description" msgstr "Objektbeskrivning" -#: describe.c:5061 +#: describe.c:5629 #, c-format msgid "Objects in extension \"%s\"" msgstr "Objekt i utökning \"%s\"" -#: describe.c:5090 describe.c:5156 +#: describe.c:5658 describe.c:5729 #, c-format -msgid "The server (version %s) does not support publications.\n" -msgstr "Servern (version %s) stöder inte publiceringar.\n" +msgid "The server (version %s) does not support publications." +msgstr "Servern (version %s) stöder inte publiceringar." -#: describe.c:5107 describe.c:5219 +#: describe.c:5675 describe.c:5801 msgid "All tables" msgstr "Alla tabeller" -#: describe.c:5108 describe.c:5220 +#: describe.c:5676 describe.c:5802 msgid "Inserts" msgstr "Insättningar" -#: describe.c:5109 describe.c:5221 +#: describe.c:5677 describe.c:5803 msgid "Updates" msgstr "Uppdateringar" -#: describe.c:5110 describe.c:5222 +#: describe.c:5678 describe.c:5804 msgid "Deletes" msgstr "Borttagningar" -#: describe.c:5127 +#: describe.c:5682 describe.c:5806 +msgid "Truncates" +msgstr "Trunkerar" + +#: describe.c:5699 msgid "List of publications" msgstr "Lista med publiceringar" -#: describe.c:5188 +#: describe.c:5767 #, c-format -msgid "Did not find any publication named \"%s\".\n" -msgstr "Kunde inte hitta nÃ¥gon publicering med namn \"%s\".\n" +msgid "Did not find any publication named \"%s\"." +msgstr "Kunde inte hitta nÃ¥gon publicering med namn \"%s\"." -#: describe.c:5191 +#: describe.c:5770 #, c-format -msgid "Did not find any publications.\n" -msgstr "Kunde inte hitta nÃ¥gra publiceringar.\n" +msgid "Did not find any publications." +msgstr "Kunde inte hitta nÃ¥gra publiceringar." -#: describe.c:5215 +#: describe.c:5797 #, c-format msgid "Publication %s" msgstr "Publicering %s" -#: describe.c:5255 +#: describe.c:5841 msgid "Tables:" msgstr "Tabeller:" -#: describe.c:5299 +#: describe.c:5885 #, c-format -msgid "The server (version %s) does not support subscriptions.\n" -msgstr "Denna server (version %s) stöder inte prenumerationer.\n" +msgid "The server (version %s) does not support subscriptions." +msgstr "Denna server (version %s) stöder inte prenumerationer." -#: describe.c:5315 +#: describe.c:5901 msgid "Publication" msgstr "Publicering" -#: describe.c:5322 +#: describe.c:5908 msgid "Synchronous commit" msgstr "Synkron commit" -#: describe.c:5323 +#: describe.c:5909 msgid "Conninfo" msgstr "Förbindelseinfo" -#: describe.c:5345 +#: describe.c:5931 msgid "List of subscriptions" msgstr "Lista med prenumerationer" -#: help.c:62 -#, c-format -msgid "%s\n" -msgstr "%s\n" - -#: help.c:73 +#: help.c:74 #, c-format msgid "" "psql is the PostgreSQL interactive terminal.\n" @@ -2067,12 +2238,12 @@ msgstr "" "psql är den interaktiva PostgreSQL-terminalen.\n" "\n" -#: help.c:74 help.c:344 help.c:378 help.c:405 +#: help.c:75 help.c:349 help.c:425 help.c:468 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: help.c:75 +#: help.c:76 #, c-format msgid "" " psql [OPTION]... [DBNAME [USERNAME]]\n" @@ -2081,32 +2252,32 @@ msgstr "" " psql [FLAGGA]... [DBNAMN [ANVÄNDARNAMN]]\n" "\n" -#: help.c:77 +#: help.c:78 #, c-format msgid "General options:\n" msgstr "Allmänna flaggor:\n" -#: help.c:82 +#: help.c:83 #, c-format msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" msgstr " -c, --command=KOMMANDO kör ett kommando (SQL eller internt) och avsluta sedan\n" -#: help.c:83 +#: help.c:84 #, c-format msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" msgstr " -d, --dbname=DBNAMN databasnamn att koppla upp mot (standard: \"%s\")\n" -#: help.c:84 +#: help.c:85 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" msgstr " -f, --file=FILNAMN kör kommandon frÃ¥n fil och avsluta sedan\n" -#: help.c:85 +#: help.c:86 #, c-format msgid " -l, --list list available databases, then exit\n" msgstr " -l, --list lista befintliga databaser och avsluta sedan\n" -#: help.c:86 +#: help.c:87 #, c-format msgid "" " -v, --set=, --variable=NAME=VALUE\n" @@ -2117,17 +2288,17 @@ msgstr "" " sätt psql-variabel NAMN till VÄRDE\n" " (t.ex. -v ON_ERROR_STOP=1)\n" -#: help.c:89 +#: help.c:90 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: help.c:90 +#: help.c:91 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" msgstr " -X, --no-psqlrc läs inte startfilen (~/.psqlrc)\n" -#: help.c:91 +#: help.c:92 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" @@ -2136,22 +2307,22 @@ msgstr "" " -1 (\"ett\"), --single-transaction\n" " kör kommandofilen som en transaktion (om icke-interaktiv)\n" -#: help.c:93 +#: help.c:94 #, c-format msgid " -?, --help[=options] show this help, then exit\n" msgstr " -?, --help[=alternativ] visa denna hjälp, avsluta sedan\n" -#: help.c:94 +#: help.c:95 #, c-format msgid " --help=commands list backslash commands, then exit\n" msgstr " --help=commands lista bakstreck-kommandon, avsluta sedan\n" -#: help.c:95 +#: help.c:96 #, c-format msgid " --help=variables list special variables, then exit\n" msgstr " --help=variabler lista speciella variabler, avsluta sedan\n" -#: help.c:97 +#: help.c:98 #, c-format msgid "" "\n" @@ -2160,57 +2331,57 @@ msgstr "" "\n" "Flaggor för in-/utmatning:\n" -#: help.c:98 +#: help.c:99 #, c-format msgid " -a, --echo-all echo all input from script\n" msgstr " -a, --echo-all visa all indata frÃ¥n skript\n" -#: help.c:99 +#: help.c:100 #, c-format msgid " -b, --echo-errors echo failed commands\n" msgstr " -b, --echo-errors visa misslyckade kommandon\n" -#: help.c:100 +#: help.c:101 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" msgstr " -e, --echo-queries visa kommandon som skickas till servern\n" -#: help.c:101 +#: help.c:102 #, c-format msgid " -E, --echo-hidden display queries that internal commands generate\n" msgstr " -E, --echo-hidden visa frÃ¥gor som interna kommandon skapar\n" -#: help.c:102 +#: help.c:103 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" msgstr " -L, --log-file=FILENAME skicka sessions-logg till fil\n" -#: help.c:103 +#: help.c:104 #, c-format msgid " -n, --no-readline disable enhanced command line editing (readline)\n" msgstr " -n, --no-readline slÃ¥ av förbättrad kommandoradsredigering (readline)\n" -#: help.c:104 +#: help.c:105 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" msgstr " -o, --output=FILNAMN skriv frÃ¥geresultat till fil (eller |rör)\n" -#: help.c:105 +#: help.c:106 #, c-format msgid " -q, --quiet run quietly (no messages, only query output)\n" msgstr " -q, --quiet kör tyst (inga meddelanden, endast frÃ¥geutdata)\n" -#: help.c:106 +#: help.c:107 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" msgstr " -s, --single-step stegningsläge (bekräfta varje frÃ¥ga)\n" -#: help.c:107 +#: help.c:108 #, c-format msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" msgstr " -S, --single-line enradsläge (slutet pÃ¥ raden avslutar SQL-kommando)\n" -#: help.c:109 +#: help.c:110 #, c-format msgid "" "\n" @@ -2219,12 +2390,17 @@ msgstr "" "\n" "Flaggor för utdataformat:\n" -#: help.c:110 +#: help.c:111 #, c-format msgid " -A, --no-align unaligned table output mode\n" msgstr " -A, --no-align ojusterad utskrift av tabeller\n" -#: help.c:111 +#: help.c:112 +#, c-format +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " --csv CSV-utmarningsläge (kommaseparerade värden)\n" + +#: help.c:113 #, c-format msgid "" " -F, --field-separator=STRING\n" @@ -2233,17 +2409,17 @@ msgstr "" " -F, --field-separator=STRÄNG\n" " fältseparator för icke justerad utdata (standard: \"%s\")\n" -#: help.c:114 +#: help.c:116 #, c-format msgid " -H, --html HTML table output mode\n" msgstr " -H, --html HTML-utskrift av tabeller\n" -#: help.c:115 +#: help.c:117 #, c-format msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" msgstr " -P, --pset=VAR[=ARG] sätt utskriftsvariabel VAR till ARG (se kommando \\pset)\n" -#: help.c:116 +#: help.c:118 #, c-format msgid "" " -R, --record-separator=STRING\n" @@ -2252,22 +2428,22 @@ msgstr "" " -R, --record-separator=STRÄNG\n" " sätt postseparator för icke justerad utdata (standard: newline)\n" -#: help.c:118 +#: help.c:120 #, c-format msgid " -t, --tuples-only print rows only\n" msgstr " -t, --tuples-only visa endast rader\n" -#: help.c:119 +#: help.c:121 #, c-format msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" msgstr " -T, --table-attr=TEXT sätt HTML-tabellers flaggor (t.ex. width, border)\n" -#: help.c:120 +#: help.c:122 #, c-format msgid " -x, --expanded turn on expanded table output\n" msgstr " -x, --expanded slÃ¥ pÃ¥ utökad utsrift av tabeller\n" -#: help.c:121 +#: help.c:123 #, c-format msgid "" " -z, --field-separator-zero\n" @@ -2276,7 +2452,7 @@ msgstr "" " -z, --field-separator-zero\n" " sätt fältseparator för icke justerad utdata till noll-byte\n" -#: help.c:123 +#: help.c:125 #, c-format msgid "" " -0, --record-separator-zero\n" @@ -2285,7 +2461,7 @@ msgstr "" " -0, --record-separator=zero\n" " sätt postseparator för icke justerad utdata till noll-byte\n" -#: help.c:126 +#: help.c:128 #, c-format msgid "" "\n" @@ -2294,38 +2470,38 @@ msgstr "" "\n" "Flaggor för anslutning:\n" -#: help.c:129 +#: help.c:131 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" msgstr "" " -h, --host=VÄRDNAMN databasens värdnamn eller uttagkatalog (socket)\n" " (standard: \"%s\")\n" -#: help.c:130 +#: help.c:132 msgid "local socket" msgstr "lokalt uttag (socket)" -#: help.c:133 +#: help.c:135 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" msgstr " -p, --port=PORT databasens serverport (standard: \"%s\")\n" -#: help.c:139 +#: help.c:141 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr " -U, --username=ANVNAMN användarnamn för databasen (standard: \"%s\")\n" -#: help.c:140 +#: help.c:142 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password frÃ¥ga aldrig efter lösenord\n" -#: help.c:141 +#: help.c:143 #, c-format msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password frÃ¥ga om lösenord (borde ske automatiskt)\n" -#: help.c:143 +#: help.c:145 #, c-format msgid "" "\n" @@ -2340,474 +2516,486 @@ msgstr "" "i PostgreSQL-dokumentationen.\n" "\n" -#: help.c:146 +#: help.c:148 #, c-format -msgid "Report bugs to .\n" -msgstr "Rapportera fel till .\n" +msgid "Report bugs to .\n" +msgstr "Rapportera buggar till .\n" -#: help.c:172 +#: help.c:174 #, c-format msgid "General\n" msgstr "Allmänna\n" -#: help.c:173 +#: help.c:175 #, c-format msgid " \\copyright show PostgreSQL usage and distribution terms\n" msgstr " \\copyright visa PostgreSQL-upphovsrättsinformation\n" -#: help.c:174 +#: help.c:176 #, c-format msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" msgstr " \\crosstabview [KOLUMNER] kör frÃ¥ga och visa resultatet i en korstabell\n" -#: help.c:175 +#: help.c:177 #, c-format msgid " \\errverbose show most recent error message at maximum verbosity\n" msgstr " \\errverbose visa senste felmeddelande vid maximal verbositet\n" -#: help.c:176 +#: help.c:178 #, c-format msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" msgstr " \\g [FILNAMN] eller ; kör frÃ¥gan (och skriv resultatet till fil eller |rör)\n" -#: help.c:177 +#: help.c:179 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc beskriv resultatet av frÃ¥ga utan att köra den\n" + +#: help.c:180 #, c-format msgid " \\gexec execute query, then execute each value in its result\n" msgstr " \\gexec kör frÃ¥ga, kör sen varje värde i resultatet\n" -#: help.c:178 +#: help.c:181 #, c-format msgid " \\gset [PREFIX] execute query and store results in psql variables\n" msgstr " \\gset [PREFIX] kör frÃ¥gan och spara resultatet i psql-variabler\n" -#: help.c:179 +#: help.c:182 #, c-format msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" msgstr " \\gx [FIL] som \\g, men tvinga expanderat utmatningsläge\n" -#: help.c:180 +#: help.c:183 #, c-format msgid " \\q quit psql\n" msgstr " \\q avsluta psql\n" -#: help.c:181 +#: help.c:184 #, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEK] kör frÃ¥ga var SEK sekund\n" -#: help.c:184 +#: help.c:187 #, c-format msgid "Help\n" msgstr "Hjälp\n" -#: help.c:186 +#: help.c:189 #, c-format msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [kommandon] visa hjälp om backstreckkommandon\n" -#: help.c:187 +#: help.c:190 #, c-format msgid " \\? options show help on psql command-line options\n" msgstr " \\? options visa hjälp för psqls kommandoradflaggor\n" -#: help.c:188 +#: help.c:191 #, c-format msgid " \\? variables show help on special variables\n" msgstr " \\? variables visa hjälp om speciella variabler\n" -#: help.c:189 +#: help.c:192 #, c-format msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr " \\h [NAMN] hjälp med syntaxen för SQL-kommandon, * för alla kommandon\n" -#: help.c:192 +#: help.c:195 #, c-format msgid "Query Buffer\n" msgstr "FrÃ¥gebuffert\n" -#: help.c:193 +#: help.c:196 #, c-format msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr " \\e [FIL] [RAD] redigera frÃ¥gebufferten (eller filen) med extern redigerare\n" -#: help.c:194 +#: help.c:197 #, c-format msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr " \\ef [FUNKNAMN [RAD]] redigera funktionsdefinition med extern redigerare\n" -#: help.c:195 +#: help.c:198 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr " \\ev [FUNKNAMN [RAD]] redigera vydefinition med extern redigerare\n" -#: help.c:196 +#: help.c:199 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p visa innehÃ¥llet i frÃ¥gebufferten\n" -#: help.c:197 +#: help.c:200 #, c-format msgid " \\r reset (clear) the query buffer\n" msgstr " \\r nollställ (radera) frÃ¥gebufferten\n" -#: help.c:199 +#: help.c:202 #, c-format msgid " \\s [FILE] display history or save it to file\n" msgstr " \\s [FILNAMN] visa kommandohistorien eller spara den i fil\n" -#: help.c:201 +#: help.c:204 #, c-format msgid " \\w FILE write query buffer to file\n" msgstr " \\w FILNAMN skriv frÃ¥gebuffert till fil\n" -#: help.c:204 +#: help.c:207 #, c-format msgid "Input/Output\n" msgstr "In-/Utmatning\n" -#: help.c:205 +#: help.c:208 #, c-format msgid " \\copy ... perform SQL COPY with data stream to the client host\n" msgstr " \\copy ... utför SQL COPY med dataström till klientvärden\n" -#: help.c:206 +#: help.c:209 #, c-format msgid " \\echo [STRING] write string to standard output\n" msgstr " \\echo [TEXT] skriv text till standard ut\n" -#: help.c:207 +#: help.c:210 #, c-format msgid " \\i FILE execute commands from file\n" msgstr " \\i FILNAMN kör kommandon frÃ¥n fil\n" -#: help.c:208 +#: help.c:211 #, c-format msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr " \\ir FIL som \\i, men relativt platsen för aktuellt script\n" -#: help.c:209 +#: help.c:212 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" msgstr " \\o [FIL] skicka frÃ¥geresultat till fil eller |rör\n" -#: help.c:210 +#: help.c:213 #, c-format msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" msgstr " \\qecho [TEXT] skriv text till frÃ¥geutdataströmmen (se \\o)\n" -#: help.c:213 +#: help.c:216 #, c-format msgid "Conditional\n" msgstr "Villkor\n" -#: help.c:214 +#: help.c:217 #, c-format msgid " \\if EXPR begin conditional block\n" msgstr " \\if EXPR starta villkorsblock\n" -#: help.c:215 +#: help.c:218 #, c-format msgid " \\elif EXPR alternative within current conditional block\n" msgstr " \\elif EXPR alternativ inom aktuellt villkorsblock\n" -#: help.c:216 +#: help.c:219 #, c-format msgid " \\else final alternative within current conditional block\n" msgstr " \\else avslutningsalternativ inom aktuellt villkorsblock\n" -#: help.c:217 +#: help.c:220 #, c-format msgid " \\endif end conditional block\n" msgstr " \\endif avsluta villkorsblock\n" -#: help.c:220 +#: help.c:223 #, c-format msgid "Informational\n" msgstr "Informationer\n" -#: help.c:221 +#: help.c:224 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (flaggor: S = lista systemobjekt, + = mer detaljer)\n" -#: help.c:222 +#: help.c:225 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" msgstr " \\d[S+] lista tabeller, vyer och sekvenser\n" -#: help.c:223 +#: help.c:226 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" msgstr " \\d[S+] NAMN beskriv tabell, vy, sekvens eller index\n" -#: help.c:224 +#: help.c:227 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" msgstr " \\da[S] [MALL] lista aggregatfunktioner\n" -#: help.c:225 +#: help.c:228 #, c-format msgid " \\dA[+] [PATTERN] list access methods\n" msgstr " \\dA[+] [MALL] lista accessmetoder\n" -#: help.c:226 +#: help.c:229 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" msgstr " \\db[+] [MALL] lista tabellutrymmen\n" -#: help.c:227 +#: help.c:230 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" msgstr " \\dc[S+] [MALL] lista konverteringar\n" -#: help.c:228 +#: help.c:231 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" msgstr " \\dC[+] [MALL] lista typomvandlingar\n" -#: help.c:229 +#: help.c:232 #, c-format msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" msgstr " \\dd[S] [MALL] visa objektbeskrivning som inte visas pÃ¥ andra ställen\n" -#: help.c:230 +#: help.c:233 #, c-format msgid " \\dD[S+] [PATTERN] list domains\n" msgstr " \\dD[S+] [MALL] lista domäner\n" -#: help.c:231 +#: help.c:234 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" msgstr " \\ddp [MALL] lista standardrättigheter\n" -#: help.c:232 +#: help.c:235 #, c-format msgid " \\dE[S+] [PATTERN] list foreign tables\n" msgstr " \\dE[S+] [MALL] lista främmande tabeller\n" -#: help.c:233 +#: help.c:236 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" msgstr " \\det[+] [MALL] lista främmande tabeller\n" -#: help.c:234 +#: help.c:237 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" msgstr " \\des[+] [MALL] lista främmande servrar\n" -#: help.c:235 +#: help.c:238 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" msgstr " \\deu[+] [MALL] lista användarmappning\n" -#: help.c:236 +#: help.c:239 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" msgstr " \\dew[+] [MALL] lista främmande data-omvandlare\n" -#: help.c:237 +#: help.c:240 #, c-format -msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [MALL] lista [endast agg/normala/utlösar/window] funktioner\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [MALL] lista [endast agg/normala/procedur/utlösar/window] funktioner\n" -#: help.c:238 +#: help.c:241 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" msgstr " \\dF[+] [MALL] lista textsökkonfigurationer\n" -#: help.c:239 +#: help.c:242 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" msgstr " \\dFd[+] [MALL] lista textsökordlistor\n" -#: help.c:240 +#: help.c:243 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" msgstr " \\dFp[+] [MALL] lista textsökparsrar\n" -#: help.c:241 +#: help.c:244 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" msgstr " \\dFt[+] [MALL] lista textsökmallar\n" -#: help.c:242 +#: help.c:245 #, c-format msgid " \\dg[S+] [PATTERN] list roles\n" msgstr " \\dg[S+] [MALL] lista roller\n" -#: help.c:243 +#: help.c:246 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" msgstr " \\di[S+] [MALL] lista index\n" -#: help.c:244 +#: help.c:247 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" msgstr " \\dl lista stora objekt, samma som \\lo_list\n" -#: help.c:245 +#: help.c:248 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" msgstr " \\dL[S+] [MALL] lista procedursprÃ¥k\n" -#: help.c:246 +#: help.c:249 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" msgstr " \\dm[S+] [MALL] lista materialiserade vyer\n" -#: help.c:247 +#: help.c:250 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" msgstr " \\dn[S+] [MALL] lista scheman\n" -#: help.c:248 +#: help.c:251 #, c-format msgid " \\do[S] [PATTERN] list operators\n" msgstr " \\do[S] [MALL] lista operatorer\n" -#: help.c:249 +#: help.c:252 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" -msgstr " \\dO[S+] [MALL] lista sorteringar (collation)\n" +msgstr " \\dO[S+] [MALL] lista jämförelser (collation)\n" -#: help.c:250 +#: help.c:253 #, c-format msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" msgstr " \\dp [MALL] lista Ã¥tkomsträttigheter för tabeller, vyer och sekvenser\n" -#: help.c:251 +#: help.c:254 +#, c-format +msgid " \\dP[tin+] [PATTERN] list [only table/index] partitioned relations\n" +msgstr " \\dP[tin+] [MALL] lista [bara tabell/index] partitionerade relationer\n" + +#: help.c:255 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" msgstr " \\drds [MALL1 [MALL2]] lista rollinställningar per databas\n" -#: help.c:252 +#: help.c:256 #, c-format msgid " \\dRp[+] [PATTERN] list replication publications\n" msgstr " \\dRp[+] [MALL] lista replikeringspubliceringar\n" -#: help.c:253 +#: help.c:257 #, c-format msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" msgstr " \\dRs[+] [MALL] lista replikeringsprenumerationer\n" -#: help.c:254 +#: help.c:258 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" msgstr " \\ds[S+] [MALL] lista sekvenser\n" -#: help.c:255 +#: help.c:259 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" msgstr " \\dt[S+] [MALL] lista tabeller\n" -#: help.c:256 +#: help.c:260 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" msgstr " \\dT[S+] [MALL] lista datatyper\n" -#: help.c:257 +#: help.c:261 #, c-format msgid " \\du[S+] [PATTERN] list roles\n" msgstr " \\du[S+] [MALL] lista roller\n" -#: help.c:258 +#: help.c:262 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" msgstr " \\dv[S+] [MALL] lista vyer\n" -#: help.c:259 +#: help.c:263 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" msgstr " \\dx[+] [MALL] lista utökningar\n" -#: help.c:260 +#: help.c:264 #, c-format msgid " \\dy [PATTERN] list event triggers\n" msgstr " \\dy [MALL] lista händelseutlösare\n" -#: help.c:261 +#: help.c:265 #, c-format msgid " \\l[+] [PATTERN] list databases\n" msgstr " \\l[+] [MALL] lista databaser\n" -#: help.c:262 +#: help.c:266 #, c-format msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNKNAMN visa en funktions definition\n" -#: help.c:263 +#: help.c:267 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] VYNAMN visa en vys definition\n" -#: help.c:264 +#: help.c:268 #, c-format msgid " \\z [PATTERN] same as \\dp\n" msgstr " \\z [MALL] samma som \\dp\n" -#: help.c:267 +#: help.c:271 #, c-format msgid "Formatting\n" msgstr "Formatering\n" -#: help.c:268 +#: help.c:272 #, c-format msgid " \\a toggle between unaligned and aligned output mode\n" msgstr " \\a byt mellan ojusterat och justerat utdataformat\n" -#: help.c:269 +#: help.c:273 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" msgstr " \\C [TEXT] sätt tabelltitel, eller nollställ\n" -#: help.c:270 +#: help.c:274 #, c-format msgid " \\f [STRING] show or set field separator for unaligned query output\n" msgstr " \\f [TEXT] visa eller sätt fältseparatorn för ojusterad utmatning\n" -#: help.c:271 +#: help.c:275 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" msgstr " \\H slÃ¥ pÃ¥/av HTML-utskriftsläge (för närvarande: %s)\n" -#: help.c:273 +#: help.c:277 #, c-format msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" -" footer|format|linestyle|null|numericlocale|pager|\n" -" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" -" tuples_only|unicode_border_linestyle|\n" -" unicode_column_linestyle|unicode_header_linestyle})\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" msgstr "" " \\pset [NAMN [VÄRDE]] sätt utmatningsalternativ för tabeller\n" -" (NAMN := {border|columns|expanded|fieldsep|fieldsep_zero|\n" -" footer|format|linestyle|null|numericlocale|pager|\n" -" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" -" tuples_only|unicode_border_linestyle|\n" -" unicode_column_linestyle|unicode_header_linestyle})\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" -#: help.c:279 +#: help.c:284 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" msgstr " \\t [on|off] visa endast rader (för närvarande: %s)\n" -#: help.c:281 +#: help.c:286 #, c-format msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" msgstr " \\T [TEXT] sätt HTML-tabellens
-attribut, eller nollställ\n" -#: help.c:282 +#: help.c:287 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] slå på/av utökad utskrift (för närvarande: %s)\n" -#: help.c:286 +#: help.c:291 #, c-format msgid "Connection\n" msgstr "Förbindelse\n" -#: help.c:288 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2816,7 +3004,7 @@ msgstr "" " \\c[onnect] {[DBNAMN|- ANVÄNDARE|- VÄRD|- PORT|-] | conninfo}\n" " koppla upp mot ny databas (för närvarande \"%s\")\n" -#: help.c:292 +#: help.c:297 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -2825,72 +3013,72 @@ msgstr "" " \\c[onnect] {[DBNAMN|- ANVÄNDARE|- VÄRD|- PORT|-] | conninfo}\n" " koppla upp mot ny databas (för närvarande ingen uppkoppling)\n" -#: help.c:294 +#: help.c:299 #, c-format msgid " \\conninfo display information about current connection\n" msgstr " \\conninfo visa information om aktuell uppkoppling\n" -#: help.c:295 +#: help.c:300 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" msgstr " \\encoding [KODNING] visa eller sätt klientens teckenkodning\n" -#: help.c:296 +#: help.c:301 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" msgstr " \\password [ANVÄNDARNAMN] byt användares lösenord på ett säkert sätt\n" -#: help.c:299 +#: help.c:304 #, c-format msgid "Operating System\n" msgstr "Operativsystem\n" -#: help.c:300 +#: help.c:305 #, c-format msgid " \\cd [DIR] change the current working directory\n" msgstr " \\cd [KATALOG] byt den aktuella katalogen\n" -#: help.c:301 +#: help.c:306 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAMN [VÄRDE] sätt eller nollställ omgivningsvariabel\n" -#: help.c:302 +#: help.c:307 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" msgstr " \\timing [on|off] slå på/av tidstagning av kommandon (för närvarande: %s)\n" -#: help.c:304 +#: help.c:309 #, c-format msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" msgstr " \\! [KOMMANDO] kör kommando i skal eller starta interaktivt skal\n" -#: help.c:307 +#: help.c:312 #, c-format msgid "Variables\n" msgstr "Variabler\n" -#: help.c:308 +#: help.c:313 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" msgstr " \\prompt [TEXT] NAMN be användaren att sätta en intern variabel\n" -#: help.c:309 +#: help.c:314 #, c-format msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" msgstr " \\set [NAMN [VÄRDE]] sätt intern variabel, eller lista alla om ingen param\n" -#: help.c:310 +#: help.c:315 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" msgstr " \\unset NAME ta bort intern variabel\n" -#: help.c:313 +#: help.c:318 #, c-format msgid "Large Objects\n" msgstr "Stora objekt\n" -#: help.c:314 +#: help.c:319 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -2903,19 +3091,19 @@ msgstr "" " \\lo_list\n" " \\lo_unlink LOBOID operationer på stora objekt\n" -#: help.c:341 +#: help.c:346 #, c-format msgid "" "List of specially treated variables\n" "\n" msgstr "Lista av variabler som hanteras speciellt\n" -#: help.c:343 +#: help.c:348 #, c-format msgid "psql variables:\n" msgstr "psql-variabler:\n" -#: help.c:345 +#: help.c:350 #, c-format msgid "" " psql --set=NAME=VALUE\n" @@ -2926,148 +3114,309 @@ msgstr "" " eller \\set NAMN VÄRDE inne i psql\n" "\n" -#: help.c:347 +#: help.c:352 #, c-format -msgid " AUTOCOMMIT if set, successful SQL commands are automatically committed\n" -msgstr " AUTOCOMMIT om satt, efterföljande SQL-kommandon commit:as automatiskt\n" +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" om satt så kommer efterföljande SQL-kommandon commit:as automatiskt\n" -#: help.c:348 +#: help.c:354 #, c-format msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" COMP_KEYWORD_CASE bestämmer skiftläge för att komplettera SQL-nyckelord\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" bestämmer skiftläge för att komplettera SQL-nyckelord\n" +" [lower, upper, preserve-lower, preserve-upper]\n" -#: help.c:350 +#: help.c:357 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME den uppkopplade databasens namn\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" den uppkopplade databasens namn\n" -#: help.c:351 +#: help.c:359 #, c-format msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" -" ECHO bestämmer vilken indata som skrivs till standard ut\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" bestämmer vilken indata som skrivs till standard ut\n" +" [all, errors, none, queries]\n" -#: help.c:353 +#: help.c:362 #, c-format msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash commands;\n" -" if set to \"noexec\", just show without execution\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" -" ECHO_HIDDEN om satt, visa interna frågor som körs av backåtstreckkommandon:\n" -" om satt till \"noexec\", bara visa dem utan att köra\n" +" ECHO_HIDDEN\n" +" om satt, visa interna frågor som körs av backåtstreckkommandon:\n" +" om satt till \"noexec\", bara visa dem utan att köra\n" -#: help.c:355 +#: help.c:365 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING aktuell teckenkodning för klient\n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" aktuell teckenkodning för klient\n" -#: help.c:356 +#: help.c:367 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a time\n" -" (default: 0=unlimited)\n" +" ERROR\n" +" true if last query failed, else false\n" msgstr "" -" FETCH_COUNT antal resultatrader som hämtas och visas åt gången\n" -" (standard: 0=obegränsat)\n" +" ERROR\n" +" sant om sista frågan misslyckades, falskt annars\n" -#: help.c:358 +#: help.c:369 #, c-format -msgid " HISTCONTROL controls command history [ignorespace, ignoredups, ignoreboth]\n" -msgstr " HISTCONTROL styr kommandohistoriken [ignorespace, ignoredups, ignoreboth]\n" +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" antal resultatrader som hämtas och visas åt gången (0=obegränsat)\n" -#: help.c:359 +#: help.c:371 #, c-format -msgid " HISTFILE file name used to store the command history\n" -msgstr " HISTFILE filnamn för att spara kommandohistoriken i\n" +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" +" HIDE_TABLEAM\n" +" om satt så visas inte accessmetoder\n" -#: help.c:360 +#: help.c:373 #, c-format -msgid " HISTSIZE max number of commands to store in the command history\n" -msgstr " HISTSIZE max antal kommandon som sparas i kommandohistoriken\n" +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" styr kommandohistoriken [ignorespace, ignoredups, ignoreboth]\n" -#: help.c:361 +#: help.c:375 #, c-format -msgid " HOST the currently connected database server host\n" -msgstr " HOST den uppkopplade databasens värd\n" +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" filnamn för att spara kommandohistoriken i\n" -#: help.c:362 +#: help.c:377 #, c-format -msgid " IGNOREEOF number of EOFs needed to terminate an interactive session\n" -msgstr " IGNOREEOF antal EOF som behövs för att avsluta en interaktiv session\n" +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" maximalt antal kommandon som sparas i kommandohistoriken\n" -#: help.c:363 +#: help.c:379 #, c-format -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID värdet av den senast påverkade OID\n" +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" den uppkopplade databasens värd\n" -#: help.c:364 +#: help.c:381 #, c-format -msgid " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses implicit savepoints)\n" -msgstr " ON_ERROR_ROLLBACK om satt, ett fel stoppar inte en transaktion (använder implicita sparpunkter)\n" +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" antal EOF som behövs för att avsluta en interaktiv session\n" -#: help.c:365 +#: help.c:383 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr " ON_ERROR_STOP avsluta batchkörning vid fel\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" värdet av den senast påverkade OID:en\n" -#: help.c:366 +#: help.c:385 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT värdport för den aktuella uppkopplingen\n" +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" meddelande och SQLSTATE för sista felet eller en tom sträng och \"00000\" om det inte varit fel\n" -#: help.c:367 +#: help.c:388 #, c-format -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 anger standardprompten för psql\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" om satt, ett fel stoppar inte en transaktion (använder implicita sparpunkter)\n" -#: help.c:368 +#: help.c:390 #, c-format -msgid " PROMPT2 specifies the prompt used when a statement continues from a previous line\n" -msgstr " PROMPT2 anger den prompt som används om en sats forsätter på efterföljande rad\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" avsluta batchkörning vid fel\n" -#: help.c:369 +#: help.c:392 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" värdport för den aktuella uppkopplingen\n" + +#: help.c:394 #, c-format -msgid " PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr " PROMPT3 anger den prompt som används för COPY ... FROM STDIN\n" +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" anger standardprompten för psql\n" -#: help.c:370 +#: help.c:396 #, c-format -msgid " QUIET run quietly (same as -q option)\n" -msgstr " QUIET kör tyst (samma som flaggan -q)\n" +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" anger den prompt som används om en sats forsätter på efterföljande rad\n" -#: help.c:371 +#: help.c:398 #, c-format -msgid " SHOW_CONTEXT controls display of message context fields [never, errors, always]\n" -msgstr " SHOW_CONTEXT styr visning av meddelandekontextfält [never, errors, always]\n" +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" anger den prompt som används för COPY ... FROM STDIN\n" -#: help.c:372 +#: help.c:400 #, c-format -msgid " SINGLELINE end of line terminates SQL command mode (same as -S option)\n" -msgstr " SINGLELINE läge där slut på raden avslutar SQL-kommandon (samma som flaggan -S )\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" kör tyst (samma som flaggan -q)\n" -#: help.c:373 +#: help.c:402 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" antal rader som returnerades eller påverkades av senaste frågan alternativt 0\n" + +#: help.c:404 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP stegningsläge (samma som flaggan -s)\n" +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NUM\n" +" SERVER_VERSION_NAME\n" +" serverns version (i kort sträng eller numeriskt format)\n" -#: help.c:374 +#: help.c:407 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER den uppkopplade databasanvändaren\n" +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" styr visning av meddelandekontextfält [never, errors, always]\n" -#: help.c:375 +#: help.c:409 #, c-format -msgid " VERBOSITY controls verbosity of error reports [default, verbose, terse]\n" -msgstr " VERBOSITY styr verbositet för felrapporter [default, verbose, terse]\n" +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" om satt, slut på raden avslutar SQL-kommandon (samma som flaggan -S )\n" -#: help.c:377 +#: help.c:411 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" stegningsläge (samma som flaggan -s)\n" + +#: help.c:413 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" SQLSTATE för sista frågan eller \"00000\" om det inte varit fel\n" + +#: help.c:415 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" den uppkopplade databasanvändaren\n" + +#: help.c:417 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" styr verbositet för felrapporter [default, verbose, terse, sqlstate]\n" + +#: help.c:419 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql:s version (i lång sträng, kort sträng eller numeriskt format)\n" + +#: help.c:424 #, c-format msgid "" "\n" @@ -3076,7 +3425,7 @@ msgstr "" "\n" "Visningsinställningar:\n" -#: help.c:379 +#: help.c:426 #, c-format msgid "" " psql --pset=NAME[=VALUE]\n" @@ -3087,108 +3436,166 @@ msgstr "" " eller \\pset NAMN [VÄRDE] inne i psql\n" "\n" -#: help.c:381 +#: help.c:428 #, c-format -msgid " border border style (number)\n" -msgstr " border ramstil (nummer)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" ramstil (nummer)\n" -#: help.c:382 +#: help.c:430 #, c-format -msgid " columns target width for the wrapped format\n" -msgstr " columns målvidd för wrappade format\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" målvidd för wrappade format\n" -#: help.c:383 +#: help.c:432 #, c-format -msgid " expanded (or x) expanded output [on, off, auto]\n" -msgstr " expanded (eller x) expanderad utdata [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (eller x)\n" +" expanderad utdata [on, off, auto]\n" -#: help.c:384 +#: help.c:434 #, c-format -msgid " fieldsep field separator for unaligned output (default \"%s\")\n" -msgstr " fieldsep fältseparator för ej justeras utdata (standard \"%s\")\n" +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" fältseparator för ej justerad utdata (standard \"%s\")\n" -#: help.c:385 +#: help.c:437 #, c-format -msgid " fieldsep_zero set field separator for unaligned output to zero byte\n" -msgstr " fieldsep_zero sätt fältseparator för ej justerad utdata till noll-byte\n" +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" sätt fältseparator för ej justerad utdata till noll-byte\n" -#: help.c:386 +#: help.c:439 #, c-format -msgid " footer enable or disable display of the table footer [on, off]\n" -msgstr " footer slå på/av visning av tabellfot [on, off]\n" +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" slå på/av visning av tabellfot [on, off]\n" -#: help.c:387 +#: help.c:441 #, c-format -msgid " format set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -msgstr " format sätt utdataformat [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" sätt utdataformat [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:388 +#: help.c:443 #, c-format -msgid " linestyle set the border line drawing style [ascii, old-ascii, unicode]\n" -msgstr " linestyle sätt ramlinjestil [ascii, old-ascii, unicode]\n" +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" sätt ramlinjestil [ascii, old-ascii, unicode]\n" -#: help.c:389 +#: help.c:445 #, c-format -msgid " null set the string to be printed in place of a null value\n" -msgstr " null sätt sträng som visas istället för null-värden\n" +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" sätt sträng som visas istället för null-värden\n" -#: help.c:390 +#: help.c:447 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale slå på/av visning av lokalspecifika tecken för gruppering\n" -" av siffror [on, off]\n" +" numericlocale\n" +" slå på visning av lokalspecifika tecken för gruppering av siffror\n" -#: help.c:392 +#: help.c:449 #, c-format -msgid " pager control when an external pager is used [yes, no, always]\n" -msgstr " pager styr när en extern pagenerare används [yes, no, always]\n" +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" styr när en extern pagenerare används [yes, no, always]\n" -#: help.c:393 +#: help.c:451 #, c-format -msgid " recordsep record (line) separator for unaligned output\n" -msgstr " recordsep post (rad) separator för ej justerad utdata\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" post (rad) separator för ej justerad utdata\n" -#: help.c:394 +#: help.c:453 #, c-format -msgid " recordsep_zero set record separator for unaligned output to zero byte\n" -msgstr " recordsep_zero sätt postseparator för ej justerad utdata till noll-byte\n" +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" sätt postseparator för ej justerad utdata till noll-byte\n" -#: help.c:395 +#: help.c:455 #, c-format msgid "" -" tableattr (or T) specify attributes for table tag in html format or proportional\n" -" column widths for left-aligned data types in latex-longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (el. T) ange attribut för tabelltaggen i html-format eller proportionella\n" -" kolumnvidder för vänsterjusterade datatypet i latex-longtable-format\n" +" tableattr (el. T)\n" +" ange attribut för tabelltaggen i html-format eller proportionella\n" +" kolumnvidder för vänsterjusterade datatypet i latex-longtable-format\n" -#: help.c:397 +#: help.c:458 #, c-format -msgid " title set the table title for any subsequently printed tables\n" -msgstr " title sätt tabelltitel för efterkommande tabellutskrifter\n" +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" sätt tabelltitel för efterkommande tabellutskrifter\n" -#: help.c:398 +#: help.c:460 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" -msgstr " tuples_only om satt, bara tabelldatan visas\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" om satt, bara tabelldatan visas\n" -#: help.c:399 +#: help.c:462 #, c-format msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" sätter stilen på Unicode-linjer [single, double]\n" +" sätter stilen på Unicode-linjer [single, double]\n" -#: help.c:404 +#: help.c:467 #, c-format msgid "" "\n" @@ -3197,7 +3604,7 @@ msgstr "" "\n" "Omgivningsvariabler:\n" -#: help.c:408 +#: help.c:471 #, c-format msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" @@ -3208,7 +3615,7 @@ msgstr "" " eller \\setenv NAMN [VÄRDE] inne psql\n" "\n" -#: help.c:410 +#: help.c:473 #, c-format msgid "" " set NAME=VALUE\n" @@ -3221,94 +3628,146 @@ msgstr "" " eller \\setenv NAMN [VÄRDE] inne i psql\n" "\n" -#: help.c:413 +#: help.c:476 #, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS antal kolumner i wrappade format\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" antal kolumner i wrappade format\n" -#: help.c:414 +#: help.c:478 #, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER namnet på den externa pageneraren\n" - -#: help.c:415 -#, c-format -msgid " PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME samma som anslutningsparametern \"application_name\"\n" +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" samma som anslutningsparametern \"application_name\"\n" -#: help.c:416 +#: help.c:480 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE samma som anslutningsparametern \"dbname\"\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" samma som anslutningsparametern \"dbname\"\n" -#: help.c:417 +#: help.c:482 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST samma som anslutningsparametern \"host\"\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" samma som anslutningsparametern \"host\"\n" -#: help.c:418 +#: help.c:484 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" -msgstr " PGPASSWORD uppkoppingens lösenord (rekommenderas inte)\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" uppkoppingens lösenord (rekommenderas inte)\n" -#: help.c:419 +#: help.c:486 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE lösenordsfilnamn\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" lösenordsfilnamn\n" -#: help.c:420 +#: help.c:488 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT samma som anslutingsparametern \"port\"\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" samma som anslutingsparametern \"port\"\n" -#: help.c:421 +#: help.c:490 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER samma som anslutningsparametern \"user\"\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" samma som anslutningsparametern \"user\"\n" -#: help.c:422 +#: help.c:492 #, c-format msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" redigerare som används av kommanona \\e, \\ef och \\ev\n" +" redigerare som används av kommanona \\e, \\ef och \\ev\n" -#: help.c:424 +#: help.c:494 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" hur radnummer anges när redigerare startas\n" +" hur radnummer anges när redigerare startas\n" -#: help.c:426 +#: help.c:496 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" alternativ plats för kommandohistorikfilen\n" + +#: help.c:498 #, c-format -msgid " PSQL_HISTORY alternative location for the command history file\n" -msgstr " PSQL_HISTORY alternativ plats för kommandohistorikfilen\n" +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PAGER\n" +" namnet på den externa pageneraren\n" -#: help.c:427 +#: help.c:500 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" -msgstr " PSQLRC alternativ plats för användarens \".psqlrc\"-fil\n" +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" alternativ plats för användarens \".psqlrc\"-fil\n" -#: help.c:428 +#: help.c:502 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL skalet som används av kommandot \\!\n" +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" skalet som används av kommandot \\!\n" -#: help.c:429 +#: help.c:504 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR katalog för temporärfiler\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" katalog för temporärfiler\n" -#: help.c:472 +#: help.c:548 msgid "Available help:\n" msgstr "Tillgänglig hjälp:\n" -#: help.c:556 +#: help.c:636 #, c-format msgid "" "Command: %s\n" @@ -3316,14 +3775,18 @@ msgid "" "Syntax:\n" "%s\n" "\n" +"URL: %s\n" +"\n" msgstr "" "Kommando: %s\n" "Beskrivning: %s\n" "Syntax:\n" "%s\n" "\n" +"URL: %s\n" +"\n" -#: help.c:572 +#: help.c:655 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3332,48 +3795,48 @@ msgstr "" "Ingen hjälp tillgänglig för \"%s\".\n" "Försök med \\h utan argument för att se den tillgängliga hjälpen.\n" -#: input.c:216 +#: input.c:218 #, c-format -msgid "could not read from input file: %s\n" -msgstr "kunde inte läsa från infilen: %s\n" +msgid "could not read from input file: %m" +msgstr "kunde inte läsa från infilen: %m" -#: input.c:471 input.c:510 +#: input.c:472 input.c:510 #, c-format -msgid "could not save history to file \"%s\": %s\n" -msgstr "kunde inte skriva kommandohistorien till \"%s\": %s\n" +msgid "could not save history to file \"%s\": %m" +msgstr "kunde inte skriva kommandohistorien till \"%s\": %m" -#: input.c:530 +#: input.c:529 #, c-format -msgid "history is not supported by this installation\n" -msgstr "historia stöds inte av denna installationen\n" +msgid "history is not supported by this installation" +msgstr "historia stöds inte av denna installationen" -#: large_obj.c:64 +#: large_obj.c:65 #, c-format -msgid "%s: not connected to a database\n" -msgstr "%s: ej uppkopplad mot en databas\n" +msgid "%s: not connected to a database" +msgstr "%s: ej uppkopplad mot en databas" -#: large_obj.c:83 +#: large_obj.c:84 #, c-format -msgid "%s: current transaction is aborted\n" -msgstr "%s: aktuell transaktion är avbruten\n" +msgid "%s: current transaction is aborted" +msgstr "%s: aktuell transaktion är avbruten" -#: large_obj.c:86 +#: large_obj.c:87 #, c-format -msgid "%s: unknown transaction status\n" -msgstr "%s: okänd transaktionsstatus\n" +msgid "%s: unknown transaction status" +msgstr "%s: okänd transaktionsstatus" -#: large_obj.c:287 large_obj.c:298 +#: large_obj.c:288 large_obj.c:299 msgid "ID" msgstr "ID" -#: large_obj.c:308 +#: large_obj.c:309 msgid "Large objects" msgstr "Stora objekt" #: mainloop.c:136 #, c-format -msgid "\\if: escaped\n" -msgstr "\\if: escape:ad\n" +msgid "\\if: escaped" +msgstr "\\if: escape:ad" #: mainloop.c:183 #, c-format @@ -3388,11 +3851,19 @@ msgstr "" "Indatan är en PostgreSQL-specifik dump.\n" "Använd kommandoradsprogrammet pg_restore för att läsa in denna dump till databasen.\n" -#: mainloop.c:225 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Använd \\? för hjälp eller tryck control-C för att nollställa inmatningsbufferten." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Använd \\? för hjälp." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "Du använder psql, den interaktiva PostgreSQL-terminalen." -#: mainloop.c:226 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3407,2185 +3878,2290 @@ msgstr "" " \\g eller avsluta med semikolon för att köra en fråga\n" " \\q för att avsluta\n" -#: mainloop.c:339 mainloop.c:476 -#, c-format -msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" -msgstr "fråga ignorerat; använd \\endif eller Ctrl-C för att avsluta aktuellt \\if-block\n" - -#: mainloop.c:494 -#, c-format -msgid "reached EOF without finding closing \\endif(s)\n" -msgstr "kom till EOF utan att hitta avslutande \\endif\n" - -#: psqlscanslash.l:614 -#, c-format -msgid "unterminated quoted string\n" -msgstr "icketerminerad citerat sträng\n" - -#: psqlscanslash.l:787 -#, c-format -msgid "%s: out of memory\n" -msgstr "%s: slut på minne\n" - -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:66 sql_help.c:67 -#: sql_help.c:69 sql_help.c:71 sql_help.c:82 sql_help.c:84 sql_help.c:86 -#: sql_help.c:112 sql_help.c:118 sql_help.c:120 sql_help.c:122 sql_help.c:124 -#: sql_help.c:127 sql_help.c:129 sql_help.c:131 sql_help.c:236 sql_help.c:238 -#: sql_help.c:239 sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:248 -#: sql_help.c:250 sql_help.c:252 sql_help.c:264 sql_help.c:265 sql_help.c:266 -#: sql_help.c:268 sql_help.c:315 sql_help.c:317 sql_help.c:319 sql_help.c:321 -#: sql_help.c:382 sql_help.c:387 sql_help.c:389 sql_help.c:432 sql_help.c:434 -#: sql_help.c:437 sql_help.c:439 sql_help.c:506 sql_help.c:511 sql_help.c:516 -#: sql_help.c:521 sql_help.c:526 sql_help.c:575 sql_help.c:577 sql_help.c:579 -#: sql_help.c:581 sql_help.c:584 sql_help.c:586 sql_help.c:597 sql_help.c:599 -#: sql_help.c:640 sql_help.c:642 sql_help.c:644 sql_help.c:647 sql_help.c:649 -#: sql_help.c:651 sql_help.c:684 sql_help.c:688 sql_help.c:692 sql_help.c:711 -#: sql_help.c:714 sql_help.c:717 sql_help.c:746 sql_help.c:758 sql_help.c:766 -#: sql_help.c:769 sql_help.c:772 sql_help.c:787 sql_help.c:790 sql_help.c:807 -#: sql_help.c:809 sql_help.c:811 sql_help.c:813 sql_help.c:816 sql_help.c:818 -#: sql_help.c:859 sql_help.c:882 sql_help.c:893 sql_help.c:895 sql_help.c:914 -#: sql_help.c:924 sql_help.c:926 sql_help.c:928 sql_help.c:940 sql_help.c:944 -#: sql_help.c:946 sql_help.c:957 sql_help.c:959 sql_help.c:961 sql_help.c:977 -#: sql_help.c:979 sql_help.c:983 sql_help.c:986 sql_help.c:987 sql_help.c:988 -#: sql_help.c:991 sql_help.c:993 sql_help.c:1084 sql_help.c:1086 -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1094 sql_help.c:1096 -#: sql_help.c:1099 sql_help.c:1102 sql_help.c:1168 sql_help.c:1170 -#: sql_help.c:1172 sql_help.c:1175 sql_help.c:1196 sql_help.c:1199 -#: sql_help.c:1202 sql_help.c:1205 sql_help.c:1209 sql_help.c:1211 -#: sql_help.c:1213 sql_help.c:1215 sql_help.c:1229 sql_help.c:1232 -#: sql_help.c:1234 sql_help.c:1236 sql_help.c:1246 sql_help.c:1248 -#: sql_help.c:1258 sql_help.c:1260 sql_help.c:1270 sql_help.c:1273 -#: sql_help.c:1295 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 -#: sql_help.c:1304 sql_help.c:1306 sql_help.c:1309 sql_help.c:1359 -#: sql_help.c:1397 sql_help.c:1400 sql_help.c:1402 sql_help.c:1404 -#: sql_help.c:1406 sql_help.c:1408 sql_help.c:1411 sql_help.c:1451 -#: sql_help.c:1662 sql_help.c:1726 sql_help.c:1745 sql_help.c:1758 -#: sql_help.c:1814 sql_help.c:1820 sql_help.c:1830 sql_help.c:1850 -#: sql_help.c:1875 sql_help.c:1893 sql_help.c:1922 sql_help.c:2015 -#: sql_help.c:2057 sql_help.c:2079 sql_help.c:2099 sql_help.c:2100 -#: sql_help.c:2135 sql_help.c:2155 sql_help.c:2177 sql_help.c:2191 -#: sql_help.c:2206 sql_help.c:2236 sql_help.c:2261 sql_help.c:2307 -#: sql_help.c:2573 sql_help.c:2586 sql_help.c:2603 sql_help.c:2619 -#: sql_help.c:2659 sql_help.c:2711 sql_help.c:2715 sql_help.c:2717 -#: sql_help.c:2723 sql_help.c:2741 sql_help.c:2768 sql_help.c:2803 -#: sql_help.c:2815 sql_help.c:2824 sql_help.c:2868 sql_help.c:2882 -#: sql_help.c:2910 sql_help.c:2918 sql_help.c:2926 sql_help.c:2934 -#: sql_help.c:2942 sql_help.c:2950 sql_help.c:2958 sql_help.c:2966 -#: sql_help.c:2975 sql_help.c:2986 sql_help.c:2994 sql_help.c:3002 -#: sql_help.c:3010 sql_help.c:3018 sql_help.c:3028 sql_help.c:3037 -#: sql_help.c:3046 sql_help.c:3054 sql_help.c:3063 sql_help.c:3071 -#: sql_help.c:3079 sql_help.c:3088 sql_help.c:3096 sql_help.c:3104 -#: sql_help.c:3112 sql_help.c:3120 sql_help.c:3128 sql_help.c:3136 -#: sql_help.c:3144 sql_help.c:3152 sql_help.c:3160 sql_help.c:3168 -#: sql_help.c:3185 sql_help.c:3194 sql_help.c:3202 sql_help.c:3219 -#: sql_help.c:3234 sql_help.c:3502 sql_help.c:3553 sql_help.c:3582 -#: sql_help.c:3590 sql_help.c:4013 sql_help.c:4061 sql_help.c:4202 +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Använd \\q för att avsluta." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Använd control-D för att avsluta." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Använd control-C för att avsluta." + +#: mainloop.c:449 mainloop.c:591 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "fråga ignorerat; använd \\endif eller Ctrl-C för att avsluta aktuellt \\if-block" + +#: mainloop.c:609 +#, c-format +msgid "reached EOF without finding closing \\endif(s)" +msgstr "kom till EOF utan att hitta avslutande \\endif" + +#: psqlscanslash.l:638 +#, c-format +msgid "unterminated quoted string" +msgstr "icketerminerad citerad sträng" + +#: psqlscanslash.l:811 +#, c-format +msgid "%s: out of memory" +msgstr "%s: slut på minne" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1089 sql_help.c:1091 sql_help.c:1093 sql_help.c:1109 +#: sql_help.c:1111 sql_help.c:1115 sql_help.c:1118 sql_help.c:1119 +#: sql_help.c:1120 sql_help.c:1123 sql_help.c:1125 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1384 +#: sql_help.c:1386 sql_help.c:1388 sql_help.c:1391 sql_help.c:1412 +#: sql_help.c:1415 sql_help.c:1418 sql_help.c:1421 sql_help.c:1425 +#: sql_help.c:1427 sql_help.c:1429 sql_help.c:1431 sql_help.c:1445 +#: sql_help.c:1448 sql_help.c:1450 sql_help.c:1452 sql_help.c:1462 +#: sql_help.c:1464 sql_help.c:1474 sql_help.c:1476 sql_help.c:1486 +#: sql_help.c:1489 sql_help.c:1511 sql_help.c:1513 sql_help.c:1515 +#: sql_help.c:1518 sql_help.c:1520 sql_help.c:1522 sql_help.c:1525 +#: sql_help.c:1575 sql_help.c:1617 sql_help.c:1620 sql_help.c:1622 +#: sql_help.c:1624 sql_help.c:1626 sql_help.c:1628 sql_help.c:1631 +#: sql_help.c:1679 sql_help.c:1695 sql_help.c:1916 sql_help.c:1985 +#: sql_help.c:2004 sql_help.c:2017 sql_help.c:2074 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2278 sql_help.c:2320 sql_help.c:2343 +#: sql_help.c:2364 sql_help.c:2365 sql_help.c:2402 sql_help.c:2422 +#: sql_help.c:2444 sql_help.c:2458 sql_help.c:2478 sql_help.c:2501 +#: sql_help.c:2531 sql_help.c:2556 sql_help.c:2602 sql_help.c:2880 +#: sql_help.c:2893 sql_help.c:2910 sql_help.c:2926 sql_help.c:2966 +#: sql_help.c:3018 sql_help.c:3022 sql_help.c:3024 sql_help.c:3030 +#: sql_help.c:3048 sql_help.c:3075 sql_help.c:3110 sql_help.c:3122 +#: sql_help.c:3131 sql_help.c:3175 sql_help.c:3189 sql_help.c:3217 +#: sql_help.c:3225 sql_help.c:3233 sql_help.c:3241 sql_help.c:3249 +#: sql_help.c:3257 sql_help.c:3265 sql_help.c:3273 sql_help.c:3282 +#: sql_help.c:3293 sql_help.c:3301 sql_help.c:3309 sql_help.c:3317 +#: sql_help.c:3325 sql_help.c:3335 sql_help.c:3344 sql_help.c:3353 +#: sql_help.c:3361 sql_help.c:3371 sql_help.c:3382 sql_help.c:3390 +#: sql_help.c:3399 sql_help.c:3410 sql_help.c:3419 sql_help.c:3427 +#: sql_help.c:3435 sql_help.c:3443 sql_help.c:3451 sql_help.c:3459 +#: sql_help.c:3467 sql_help.c:3475 sql_help.c:3483 sql_help.c:3491 +#: sql_help.c:3499 sql_help.c:3516 sql_help.c:3525 sql_help.c:3533 +#: sql_help.c:3550 sql_help.c:3565 sql_help.c:3835 sql_help.c:3886 +#: sql_help.c:3915 sql_help.c:3923 sql_help.c:4356 sql_help.c:4404 +#: sql_help.c:4545 msgid "name" msgstr "namn" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:326 sql_help.c:1520 -#: sql_help.c:2883 sql_help.c:3807 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1766 +#: sql_help.c:3190 sql_help.c:4142 msgid "aggregate_signature" msgstr "aggregatsignatur" -#: sql_help.c:38 sql_help.c:68 sql_help.c:83 sql_help.c:119 sql_help.c:251 -#: sql_help.c:269 sql_help.c:390 sql_help.c:438 sql_help.c:515 sql_help.c:561 -#: sql_help.c:576 sql_help.c:598 sql_help.c:648 sql_help.c:713 sql_help.c:768 -#: sql_help.c:789 sql_help.c:819 sql_help.c:860 sql_help.c:884 sql_help.c:894 -#: sql_help.c:927 sql_help.c:947 sql_help.c:960 sql_help.c:994 sql_help.c:1093 -#: sql_help.c:1169 sql_help.c:1212 sql_help.c:1233 sql_help.c:1247 -#: sql_help.c:1259 sql_help.c:1272 sql_help.c:1303 sql_help.c:1360 -#: sql_help.c:1405 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1092 sql_help.c:1126 sql_help.c:1266 sql_help.c:1385 +#: sql_help.c:1428 sql_help.c:1449 sql_help.c:1463 sql_help.c:1475 +#: sql_help.c:1488 sql_help.c:1519 sql_help.c:1576 sql_help.c:1625 msgid "new_name" msgstr "nytt_namn" -#: sql_help.c:41 sql_help.c:70 sql_help.c:85 sql_help.c:121 sql_help.c:249 -#: sql_help.c:267 sql_help.c:388 sql_help.c:474 sql_help.c:520 sql_help.c:600 -#: sql_help.c:609 sql_help.c:667 sql_help.c:687 sql_help.c:716 sql_help.c:771 -#: sql_help.c:817 sql_help.c:896 sql_help.c:925 sql_help.c:945 sql_help.c:958 -#: sql_help.c:992 sql_help.c:1153 sql_help.c:1171 sql_help.c:1214 -#: sql_help.c:1235 sql_help.c:1298 sql_help.c:1403 sql_help.c:2559 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1090 sql_help.c:1124 sql_help.c:1326 +#: sql_help.c:1387 sql_help.c:1430 sql_help.c:1451 sql_help.c:1514 +#: sql_help.c:1623 sql_help.c:2866 msgid "new_owner" msgstr "ny_ägare" -#: sql_help.c:44 sql_help.c:72 sql_help.c:87 sql_help.c:253 sql_help.c:318 -#: sql_help.c:440 sql_help.c:525 sql_help.c:650 sql_help.c:691 sql_help.c:719 -#: sql_help.c:774 sql_help.c:929 sql_help.c:962 sql_help.c:1095 -#: sql_help.c:1216 sql_help.c:1237 sql_help.c:1249 sql_help.c:1261 -#: sql_help.c:1305 sql_help.c:1407 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1094 +#: sql_help.c:1268 sql_help.c:1432 sql_help.c:1453 sql_help.c:1465 +#: sql_help.c:1477 sql_help.c:1521 sql_help.c:1627 msgid "new_schema" msgstr "nytt_schema" -#: sql_help.c:45 sql_help.c:1576 sql_help.c:2884 sql_help.c:3828 +#: sql_help.c:44 sql_help.c:1830 sql_help.c:3191 sql_help.c:4171 msgid "where aggregate_signature is:" msgstr "där aggregatsignatur är:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:336 sql_help.c:361 -#: sql_help.c:364 sql_help.c:367 sql_help.c:507 sql_help.c:512 sql_help.c:517 -#: sql_help.c:522 sql_help.c:527 sql_help.c:1538 sql_help.c:1577 -#: sql_help.c:1580 sql_help.c:1583 sql_help.c:1727 sql_help.c:1746 -#: sql_help.c:1749 sql_help.c:2016 sql_help.c:2885 sql_help.c:2888 -#: sql_help.c:2891 sql_help.c:2976 sql_help.c:3387 sql_help.c:3720 -#: sql_help.c:3813 sql_help.c:3829 sql_help.c:3832 sql_help.c:3835 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1784 +#: sql_help.c:1801 sql_help.c:1807 sql_help.c:1831 sql_help.c:1834 +#: sql_help.c:1837 sql_help.c:1986 sql_help.c:2005 sql_help.c:2008 +#: sql_help.c:2279 sql_help.c:2479 sql_help.c:3192 sql_help.c:3195 +#: sql_help.c:3198 sql_help.c:3283 sql_help.c:3372 sql_help.c:3400 +#: sql_help.c:3720 sql_help.c:4053 sql_help.c:4148 sql_help.c:4155 +#: sql_help.c:4161 sql_help.c:4172 sql_help.c:4175 sql_help.c:4178 msgid "argmode" msgstr "arg_läge" -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:337 sql_help.c:362 -#: sql_help.c:365 sql_help.c:368 sql_help.c:508 sql_help.c:513 sql_help.c:518 -#: sql_help.c:523 sql_help.c:528 sql_help.c:1539 sql_help.c:1578 -#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1728 sql_help.c:1747 -#: sql_help.c:1750 sql_help.c:2017 sql_help.c:2886 sql_help.c:2889 -#: sql_help.c:2892 sql_help.c:2977 sql_help.c:3814 sql_help.c:3830 -#: sql_help.c:3833 sql_help.c:3836 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1785 +#: sql_help.c:1802 sql_help.c:1808 sql_help.c:1832 sql_help.c:1835 +#: sql_help.c:1838 sql_help.c:1987 sql_help.c:2006 sql_help.c:2009 +#: sql_help.c:2280 sql_help.c:2480 sql_help.c:3193 sql_help.c:3196 +#: sql_help.c:3199 sql_help.c:3284 sql_help.c:3373 sql_help.c:3401 +#: sql_help.c:4149 sql_help.c:4156 sql_help.c:4162 sql_help.c:4173 +#: sql_help.c:4176 sql_help.c:4179 msgid "argname" msgstr "arg_namn" -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:338 sql_help.c:363 -#: sql_help.c:366 sql_help.c:369 sql_help.c:509 sql_help.c:514 sql_help.c:519 -#: sql_help.c:524 sql_help.c:529 sql_help.c:1540 sql_help.c:1579 -#: sql_help.c:1582 sql_help.c:1585 sql_help.c:2018 sql_help.c:2887 -#: sql_help.c:2890 sql_help.c:2893 sql_help.c:2978 sql_help.c:3815 -#: sql_help.c:3831 sql_help.c:3834 sql_help.c:3837 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:2281 sql_help.c:2481 sql_help.c:3194 +#: sql_help.c:3197 sql_help.c:3200 sql_help.c:3285 sql_help.c:3374 +#: sql_help.c:3402 sql_help.c:4150 sql_help.c:4157 sql_help.c:4163 +#: sql_help.c:4174 sql_help.c:4177 sql_help.c:4180 msgid "argtype" msgstr "arg_typ" -#: sql_help.c:113 sql_help.c:385 sql_help.c:463 sql_help.c:475 sql_help.c:854 -#: sql_help.c:942 sql_help.c:1230 sql_help.c:1354 sql_help.c:1382 -#: sql_help.c:1633 sql_help.c:1639 sql_help.c:1925 sql_help.c:1966 -#: sql_help.c:1973 sql_help.c:1982 sql_help.c:2058 sql_help.c:2237 -#: sql_help.c:2329 sql_help.c:2588 sql_help.c:2769 sql_help.c:2791 -#: sql_help.c:3254 sql_help.c:3421 +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1446 sql_help.c:1570 sql_help.c:1602 +#: sql_help.c:1650 sql_help.c:1887 sql_help.c:1894 sql_help.c:2186 +#: sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 sql_help.c:2321 +#: sql_help.c:2532 sql_help.c:2624 sql_help.c:2895 sql_help.c:3076 +#: sql_help.c:3098 sql_help.c:3586 sql_help.c:3754 sql_help.c:4605 msgid "option" msgstr "flaggor" -#: sql_help.c:114 sql_help.c:855 sql_help.c:1355 sql_help.c:2059 -#: sql_help.c:2238 sql_help.c:2770 +#: sql_help.c:113 sql_help.c:927 sql_help.c:1571 sql_help.c:2322 +#: sql_help.c:2533 sql_help.c:3077 msgid "where option can be:" msgstr "där flaggor kan vara:" -#: sql_help.c:115 sql_help.c:1857 +#: sql_help.c:114 sql_help.c:2118 msgid "allowconn" msgstr "tillåtansl" -#: sql_help.c:116 sql_help.c:856 sql_help.c:1356 sql_help.c:1858 -#: sql_help.c:2239 sql_help.c:2771 +#: sql_help.c:115 sql_help.c:928 sql_help.c:1572 sql_help.c:2119 +#: sql_help.c:2534 sql_help.c:3078 msgid "connlimit" msgstr "anslutningstak" -#: sql_help.c:117 sql_help.c:1859 +#: sql_help.c:116 sql_help.c:2120 msgid "istemplate" msgstr "ärmall" -#: sql_help.c:123 sql_help.c:588 sql_help.c:653 sql_help.c:1098 -#: sql_help.c:1146 +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "nytt_tabellutrymme" -#: sql_help.c:125 sql_help.c:128 sql_help.c:130 sql_help.c:534 sql_help.c:536 -#: sql_help.c:537 sql_help.c:863 sql_help.c:867 sql_help.c:870 sql_help.c:1005 -#: sql_help.c:1008 sql_help.c:1362 sql_help.c:1365 sql_help.c:1367 -#: sql_help.c:2027 sql_help.c:3607 sql_help.c:4002 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1137 sql_help.c:1140 sql_help.c:1579 +#: sql_help.c:1583 sql_help.c:1586 sql_help.c:2291 sql_help.c:2485 +#: sql_help.c:3940 sql_help.c:4345 msgid "configuration_parameter" msgstr "konfigurationsparameter" -#: sql_help.c:126 sql_help.c:386 sql_help.c:458 sql_help.c:464 sql_help.c:476 -#: sql_help.c:535 sql_help.c:583 sql_help.c:659 sql_help.c:665 sql_help.c:815 -#: sql_help.c:864 sql_help.c:943 sql_help.c:982 sql_help.c:985 sql_help.c:990 -#: sql_help.c:1006 sql_help.c:1007 sql_help.c:1128 sql_help.c:1148 -#: sql_help.c:1174 sql_help.c:1231 sql_help.c:1363 sql_help.c:1383 -#: sql_help.c:1926 sql_help.c:1967 sql_help.c:1974 sql_help.c:1983 -#: sql_help.c:2028 sql_help.c:2029 sql_help.c:2087 sql_help.c:2119 -#: sql_help.c:2209 sql_help.c:2330 sql_help.c:2360 sql_help.c:2458 -#: sql_help.c:2470 sql_help.c:2483 sql_help.c:2523 sql_help.c:2545 -#: sql_help.c:2562 sql_help.c:2589 sql_help.c:2792 sql_help.c:3422 -#: sql_help.c:4003 sql_help.c:4004 +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1114 sql_help.c:1117 sql_help.c:1122 sql_help.c:1138 +#: sql_help.c:1139 sql_help.c:1301 sql_help.c:1321 sql_help.c:1368 +#: sql_help.c:1390 sql_help.c:1447 sql_help.c:1580 sql_help.c:1603 +#: sql_help.c:2187 sql_help.c:2229 sql_help.c:2236 sql_help.c:2245 +#: sql_help.c:2292 sql_help.c:2293 sql_help.c:2352 sql_help.c:2386 +#: sql_help.c:2486 sql_help.c:2487 sql_help.c:2504 sql_help.c:2625 +#: sql_help.c:2655 sql_help.c:2760 sql_help.c:2773 sql_help.c:2787 +#: sql_help.c:2828 sql_help.c:2852 sql_help.c:2869 sql_help.c:2896 +#: sql_help.c:3099 sql_help.c:3755 sql_help.c:4346 sql_help.c:4347 msgid "value" msgstr "värde" -#: sql_help.c:198 +#: sql_help.c:197 msgid "target_role" msgstr "målroll" -#: sql_help.c:199 sql_help.c:1909 sql_help.c:2285 sql_help.c:2290 -#: sql_help.c:3369 sql_help.c:3376 sql_help.c:3390 sql_help.c:3396 +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2580 sql_help.c:2585 #: sql_help.c:3702 sql_help.c:3709 sql_help.c:3723 sql_help.c:3729 +#: sql_help.c:4035 sql_help.c:4042 sql_help.c:4056 sql_help.c:4062 msgid "schema_name" msgstr "schemanamn" -#: sql_help.c:200 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "förkortad_grant_eller_revoke" -#: sql_help.c:201 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "där förkortad_grant_eller_revok är en av:" -#: sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 sql_help.c:206 -#: sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 sql_help.c:211 -#: sql_help.c:559 sql_help.c:587 sql_help.c:652 sql_help.c:792 sql_help.c:874 -#: sql_help.c:1097 sql_help.c:1370 sql_help.c:2062 sql_help.c:2063 -#: sql_help.c:2064 sql_help.c:2065 sql_help.c:2066 sql_help.c:2193 -#: sql_help.c:2242 sql_help.c:2243 sql_help.c:2244 sql_help.c:2245 -#: sql_help.c:2246 sql_help.c:2774 sql_help.c:2775 sql_help.c:2776 -#: sql_help.c:2777 sql_help.c:2778 sql_help.c:3403 sql_help.c:3404 -#: sql_help.c:3405 sql_help.c:3703 sql_help.c:3707 sql_help.c:3710 -#: sql_help.c:3712 sql_help.c:3714 sql_help.c:3716 sql_help.c:3718 -#: sql_help.c:3724 sql_help.c:3726 sql_help.c:3728 sql_help.c:3730 -#: sql_help.c:3732 sql_help.c:3734 sql_help.c:3735 sql_help.c:3736 -#: sql_help.c:4023 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1270 sql_help.c:1590 sql_help.c:2325 sql_help.c:2326 +#: sql_help.c:2327 sql_help.c:2328 sql_help.c:2329 sql_help.c:2460 +#: sql_help.c:2537 sql_help.c:2538 sql_help.c:2539 sql_help.c:2540 +#: sql_help.c:2541 sql_help.c:3081 sql_help.c:3082 sql_help.c:3083 +#: sql_help.c:3084 sql_help.c:3085 sql_help.c:3736 sql_help.c:3737 +#: sql_help.c:3738 sql_help.c:4036 sql_help.c:4040 sql_help.c:4043 +#: sql_help.c:4045 sql_help.c:4047 sql_help.c:4049 sql_help.c:4051 +#: sql_help.c:4057 sql_help.c:4059 sql_help.c:4061 sql_help.c:4063 +#: sql_help.c:4065 sql_help.c:4067 sql_help.c:4068 sql_help.c:4069 +#: sql_help.c:4366 msgid "role_name" msgstr "rollnamn" -#: sql_help.c:237 sql_help.c:451 sql_help.c:1113 sql_help.c:1115 -#: sql_help.c:1399 sql_help.c:1878 sql_help.c:1882 sql_help.c:1986 -#: sql_help.c:1990 sql_help.c:2083 sql_help.c:2454 sql_help.c:2466 -#: sql_help.c:2479 sql_help.c:2487 sql_help.c:2498 sql_help.c:2527 -#: sql_help.c:3453 sql_help.c:3468 sql_help.c:3470 sql_help.c:3888 -#: sql_help.c:3889 sql_help.c:3898 sql_help.c:3939 sql_help.c:3940 -#: sql_help.c:3941 sql_help.c:3942 sql_help.c:3943 sql_help.c:3944 -#: sql_help.c:3977 sql_help.c:3978 sql_help.c:3983 sql_help.c:3988 -#: sql_help.c:4127 sql_help.c:4128 sql_help.c:4137 sql_help.c:4178 -#: sql_help.c:4179 sql_help.c:4180 sql_help.c:4181 sql_help.c:4182 -#: sql_help.c:4183 sql_help.c:4230 sql_help.c:4232 sql_help.c:4265 -#: sql_help.c:4321 sql_help.c:4322 sql_help.c:4331 sql_help.c:4372 -#: sql_help.c:4373 sql_help.c:4374 sql_help.c:4375 sql_help.c:4376 -#: sql_help.c:4377 +#: sql_help.c:236 sql_help.c:459 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1336 sql_help.c:1347 sql_help.c:1372 sql_help.c:1619 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2248 sql_help.c:2253 +#: sql_help.c:2347 sql_help.c:2755 sql_help.c:2768 sql_help.c:2782 +#: sql_help.c:2791 sql_help.c:2803 sql_help.c:2832 sql_help.c:3786 +#: sql_help.c:3801 sql_help.c:3803 sql_help.c:4231 sql_help.c:4232 +#: sql_help.c:4241 sql_help.c:4282 sql_help.c:4283 sql_help.c:4284 +#: sql_help.c:4285 sql_help.c:4286 sql_help.c:4287 sql_help.c:4320 +#: sql_help.c:4321 sql_help.c:4326 sql_help.c:4331 sql_help.c:4470 +#: sql_help.c:4471 sql_help.c:4480 sql_help.c:4521 sql_help.c:4522 +#: sql_help.c:4523 sql_help.c:4524 sql_help.c:4525 sql_help.c:4526 +#: sql_help.c:4573 sql_help.c:4575 sql_help.c:4630 sql_help.c:4686 +#: sql_help.c:4687 sql_help.c:4696 sql_help.c:4737 sql_help.c:4738 +#: sql_help.c:4739 sql_help.c:4740 sql_help.c:4741 sql_help.c:4742 msgid "expression" msgstr "uttryck" -#: sql_help.c:240 +#: sql_help.c:239 msgid "domain_constraint" msgstr "domain_villkor" -#: sql_help.c:242 sql_help.c:244 sql_help.c:247 sql_help.c:466 sql_help.c:467 -#: sql_help.c:1090 sql_help.c:1134 sql_help.c:1135 sql_help.c:1136 -#: sql_help.c:1156 sql_help.c:1526 sql_help.c:1528 sql_help.c:1881 -#: sql_help.c:1985 sql_help.c:1989 sql_help.c:2486 sql_help.c:2497 -#: sql_help.c:3465 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1335 sql_help.c:1346 sql_help.c:1363 sql_help.c:1772 +#: sql_help.c:1774 sql_help.c:2142 sql_help.c:2247 sql_help.c:2252 +#: sql_help.c:2790 sql_help.c:2802 sql_help.c:3798 msgid "constraint_name" msgstr "villkorsnamn" -#: sql_help.c:245 sql_help.c:1091 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "nyy_villkorsnamn" -#: sql_help.c:316 sql_help.c:941 +#: sql_help.c:317 sql_help.c:1073 msgid "new_version" msgstr "ny_version" -#: sql_help.c:320 sql_help.c:322 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "medlemsobjekt" -#: sql_help.c:323 +#: sql_help.c:324 msgid "where member_object is:" msgstr "där medlemsobjekt är:" -#: sql_help.c:324 sql_help.c:329 sql_help.c:330 sql_help.c:331 sql_help.c:332 -#: sql_help.c:333 sql_help.c:334 sql_help.c:339 sql_help.c:343 sql_help.c:345 -#: sql_help.c:347 sql_help.c:348 sql_help.c:349 sql_help.c:350 sql_help.c:351 -#: sql_help.c:352 sql_help.c:353 sql_help.c:354 sql_help.c:355 sql_help.c:358 -#: sql_help.c:359 sql_help.c:1518 sql_help.c:1523 sql_help.c:1530 -#: sql_help.c:1531 sql_help.c:1532 sql_help.c:1533 sql_help.c:1534 -#: sql_help.c:1535 sql_help.c:1536 sql_help.c:1541 sql_help.c:1543 -#: sql_help.c:1547 sql_help.c:1549 sql_help.c:1553 sql_help.c:1554 -#: sql_help.c:1555 sql_help.c:1558 sql_help.c:1559 sql_help.c:1560 -#: sql_help.c:1561 sql_help.c:1562 sql_help.c:1563 sql_help.c:1564 -#: sql_help.c:1565 sql_help.c:1566 sql_help.c:1567 sql_help.c:1568 -#: sql_help.c:1573 sql_help.c:1574 sql_help.c:3803 sql_help.c:3808 -#: sql_help.c:3809 sql_help.c:3810 sql_help.c:3811 sql_help.c:3817 -#: sql_help.c:3818 sql_help.c:3819 sql_help.c:3820 sql_help.c:3821 -#: sql_help.c:3822 sql_help.c:3823 sql_help.c:3824 sql_help.c:3825 -#: sql_help.c:3826 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1764 sql_help.c:1769 sql_help.c:1776 +#: sql_help.c:1777 sql_help.c:1778 sql_help.c:1779 sql_help.c:1780 +#: sql_help.c:1781 sql_help.c:1782 sql_help.c:1787 sql_help.c:1789 +#: sql_help.c:1793 sql_help.c:1795 sql_help.c:1799 sql_help.c:1804 +#: sql_help.c:1805 sql_help.c:1812 sql_help.c:1813 sql_help.c:1814 +#: sql_help.c:1815 sql_help.c:1816 sql_help.c:1817 sql_help.c:1818 +#: sql_help.c:1819 sql_help.c:1820 sql_help.c:1821 sql_help.c:1822 +#: sql_help.c:1827 sql_help.c:1828 sql_help.c:4138 sql_help.c:4143 +#: sql_help.c:4144 sql_help.c:4145 sql_help.c:4146 sql_help.c:4152 +#: sql_help.c:4153 sql_help.c:4158 sql_help.c:4159 sql_help.c:4164 +#: sql_help.c:4165 sql_help.c:4166 sql_help.c:4167 sql_help.c:4168 +#: sql_help.c:4169 msgid "object_name" msgstr "objektnamn" -#: sql_help.c:325 sql_help.c:1519 sql_help.c:3806 +#: sql_help.c:326 sql_help.c:1765 sql_help.c:4141 msgid "aggregate_name" msgstr "aggregatnamn" -#: sql_help.c:327 sql_help.c:1521 sql_help.c:1792 sql_help.c:1796 -#: sql_help.c:1798 sql_help.c:2901 +#: sql_help.c:328 sql_help.c:1767 sql_help.c:2051 sql_help.c:2055 +#: sql_help.c:2057 sql_help.c:3208 msgid "source_type" msgstr "källtyp" -#: sql_help.c:328 sql_help.c:1522 sql_help.c:1793 sql_help.c:1797 -#: sql_help.c:1799 sql_help.c:2902 +#: sql_help.c:329 sql_help.c:1768 sql_help.c:2052 sql_help.c:2056 +#: sql_help.c:2058 sql_help.c:3209 msgid "target_type" msgstr "måltyp" -#: sql_help.c:335 sql_help.c:756 sql_help.c:1537 sql_help.c:1794 -#: sql_help.c:1833 sql_help.c:1896 sql_help.c:2136 sql_help.c:2167 -#: sql_help.c:2665 sql_help.c:3386 sql_help.c:3719 sql_help.c:3812 -#: sql_help.c:3917 sql_help.c:3921 sql_help.c:3925 sql_help.c:3928 -#: sql_help.c:4156 sql_help.c:4160 sql_help.c:4164 sql_help.c:4167 -#: sql_help.c:4350 sql_help.c:4354 sql_help.c:4358 sql_help.c:4361 +#: sql_help.c:336 sql_help.c:774 sql_help.c:1783 sql_help.c:2053 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2403 sql_help.c:2434 +#: sql_help.c:2972 sql_help.c:4052 sql_help.c:4147 sql_help.c:4260 +#: sql_help.c:4264 sql_help.c:4268 sql_help.c:4271 sql_help.c:4499 +#: sql_help.c:4503 sql_help.c:4507 sql_help.c:4510 sql_help.c:4715 +#: sql_help.c:4719 sql_help.c:4723 sql_help.c:4726 msgid "function_name" msgstr "funktionsnamn" -#: sql_help.c:340 sql_help.c:749 sql_help.c:1544 sql_help.c:2160 +#: sql_help.c:341 sql_help.c:767 sql_help.c:1790 sql_help.c:2427 msgid "operator_name" msgstr "operatornamn" -#: sql_help.c:341 sql_help.c:685 sql_help.c:689 sql_help.c:693 sql_help.c:1545 -#: sql_help.c:2137 sql_help.c:3019 +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1791 +#: sql_help.c:2404 sql_help.c:3326 msgid "left_type" msgstr "vänster_typ" -#: sql_help.c:342 sql_help.c:686 sql_help.c:690 sql_help.c:694 sql_help.c:1546 -#: sql_help.c:2138 sql_help.c:3020 +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1792 +#: sql_help.c:2405 sql_help.c:3327 msgid "right_type" msgstr "höger_typ" -#: sql_help.c:344 sql_help.c:346 sql_help.c:712 sql_help.c:715 sql_help.c:718 -#: sql_help.c:747 sql_help.c:759 sql_help.c:767 sql_help.c:770 sql_help.c:773 -#: sql_help.c:1548 sql_help.c:1550 sql_help.c:2157 sql_help.c:2178 -#: sql_help.c:2503 sql_help.c:3029 sql_help.c:3038 +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1352 sql_help.c:1794 sql_help.c:1796 sql_help.c:2424 +#: sql_help.c:2445 sql_help.c:2808 sql_help.c:3336 sql_help.c:3345 msgid "index_method" msgstr "indexmetod" -#: sql_help.c:356 sql_help.c:1152 sql_help.c:1569 sql_help.c:2024 -#: sql_help.c:2461 sql_help.c:2632 sql_help.c:3176 sql_help.c:3400 -#: sql_help.c:3733 +#: sql_help.c:349 sql_help.c:1800 sql_help.c:4154 +msgid "procedure_name" +msgstr "procedurnamn" + +#: sql_help.c:353 sql_help.c:1806 sql_help.c:3719 sql_help.c:4160 +msgid "routine_name" +msgstr "rutinnamn" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1823 sql_help.c:2287 +#: sql_help.c:2484 sql_help.c:2763 sql_help.c:2939 sql_help.c:3507 +#: sql_help.c:3733 sql_help.c:4066 msgid "type_name" msgstr "typnamn" -#: sql_help.c:357 sql_help.c:1570 sql_help.c:2023 sql_help.c:2633 -#: sql_help.c:2859 sql_help.c:3177 sql_help.c:3392 sql_help.c:3725 +#: sql_help.c:366 sql_help.c:1824 sql_help.c:2286 sql_help.c:2483 +#: sql_help.c:2940 sql_help.c:3166 sql_help.c:3508 sql_help.c:3725 +#: sql_help.c:4058 msgid "lang_name" msgstr "språknamn" -#: sql_help.c:360 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "och aggregatsignatur är:" -#: sql_help.c:383 sql_help.c:1664 sql_help.c:1923 +#: sql_help.c:392 sql_help.c:1918 sql_help.c:2184 msgid "handler_function" msgstr "hanterarfunktion" -#: sql_help.c:384 sql_help.c:1924 +#: sql_help.c:393 sql_help.c:2185 msgid "validator_function" msgstr "valideringsfunktion" -#: sql_help.c:433 sql_help.c:510 sql_help.c:641 sql_help.c:1085 -#: sql_help.c:1296 sql_help.c:2494 sql_help.c:2495 sql_help.c:2511 -#: sql_help.c:2512 +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1258 sql_help.c:1512 msgid "action" msgstr "aktion" -#: sql_help.c:435 sql_help.c:442 sql_help.c:446 sql_help.c:447 sql_help.c:450 -#: sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:456 sql_help.c:459 -#: sql_help.c:461 sql_help.c:462 sql_help.c:645 sql_help.c:655 sql_help.c:657 -#: sql_help.c:660 sql_help.c:662 sql_help.c:923 sql_help.c:1087 -#: sql_help.c:1105 sql_help.c:1109 sql_help.c:1110 sql_help.c:1114 -#: sql_help.c:1116 sql_help.c:1117 sql_help.c:1118 sql_help.c:1120 -#: sql_help.c:1123 sql_help.c:1124 sql_help.c:1126 sql_help.c:1129 -#: sql_help.c:1131 sql_help.c:1398 sql_help.c:1401 sql_help.c:1421 -#: sql_help.c:1525 sql_help.c:1630 sql_help.c:1635 sql_help.c:1649 -#: sql_help.c:1650 sql_help.c:1651 sql_help.c:1964 sql_help.c:1977 -#: sql_help.c:2021 sql_help.c:2082 sql_help.c:2117 sql_help.c:2315 -#: sql_help.c:2343 sql_help.c:2344 sql_help.c:2445 sql_help.c:2453 -#: sql_help.c:2462 sql_help.c:2465 sql_help.c:2474 sql_help.c:2478 -#: sql_help.c:2499 sql_help.c:2501 sql_help.c:2508 sql_help.c:2526 -#: sql_help.c:2543 sql_help.c:2668 sql_help.c:2804 sql_help.c:3371 -#: sql_help.c:3372 sql_help.c:3452 sql_help.c:3467 sql_help.c:3469 -#: sql_help.c:3471 sql_help.c:3704 sql_help.c:3705 sql_help.c:3805 -#: sql_help.c:3948 sql_help.c:4187 sql_help.c:4229 sql_help.c:4231 -#: sql_help.c:4233 sql_help.c:4250 sql_help.c:4253 sql_help.c:4381 +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1348 sql_help.c:1350 sql_help.c:1357 +#: sql_help.c:1366 sql_help.c:1371 sql_help.c:1618 sql_help.c:1621 +#: sql_help.c:1656 sql_help.c:1771 sql_help.c:1884 sql_help.c:1890 +#: sql_help.c:1903 sql_help.c:1904 sql_help.c:1905 sql_help.c:2226 +#: sql_help.c:2239 sql_help.c:2284 sql_help.c:2346 sql_help.c:2350 +#: sql_help.c:2383 sql_help.c:2610 sql_help.c:2638 sql_help.c:2639 +#: sql_help.c:2746 sql_help.c:2754 sql_help.c:2764 sql_help.c:2767 +#: sql_help.c:2777 sql_help.c:2781 sql_help.c:2804 sql_help.c:2806 +#: sql_help.c:2813 sql_help.c:2826 sql_help.c:2831 sql_help.c:2849 +#: sql_help.c:2975 sql_help.c:3111 sql_help.c:3704 sql_help.c:3705 +#: sql_help.c:3785 sql_help.c:3800 sql_help.c:3802 sql_help.c:3804 +#: sql_help.c:4037 sql_help.c:4038 sql_help.c:4140 sql_help.c:4291 +#: sql_help.c:4530 sql_help.c:4572 sql_help.c:4574 sql_help.c:4576 +#: sql_help.c:4618 sql_help.c:4746 msgid "column_name" msgstr "kolumnnamn" -#: sql_help.c:436 sql_help.c:646 sql_help.c:1088 +#: sql_help.c:444 sql_help.c:664 sql_help.c:1261 msgid "new_column_name" msgstr "nytt_kolumnnamn" -#: sql_help.c:441 sql_help.c:531 sql_help.c:654 sql_help.c:1104 -#: sql_help.c:1312 +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1277 sql_help.c:1528 msgid "where action is one of:" msgstr "där aktion är en av:" -#: sql_help.c:443 sql_help.c:448 sql_help.c:915 sql_help.c:1106 -#: sql_help.c:1111 sql_help.c:1314 sql_help.c:1318 sql_help.c:1876 -#: sql_help.c:1965 sql_help.c:2156 sql_help.c:2308 sql_help.c:2446 -#: sql_help.c:2713 sql_help.c:3554 +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1530 sql_help.c:1534 sql_help.c:2137 +#: sql_help.c:2227 sql_help.c:2423 sql_help.c:2603 sql_help.c:2747 +#: sql_help.c:3020 sql_help.c:3887 msgid "data_type" msgstr "datatyp" -#: sql_help.c:444 sql_help.c:449 sql_help.c:1107 sql_help.c:1112 -#: sql_help.c:1315 sql_help.c:1319 sql_help.c:1877 sql_help.c:1968 -#: sql_help.c:2084 sql_help.c:2447 sql_help.c:2455 sql_help.c:2467 -#: sql_help.c:2480 sql_help.c:2714 sql_help.c:2720 sql_help.c:3462 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1531 sql_help.c:1535 sql_help.c:2138 sql_help.c:2230 +#: sql_help.c:2348 sql_help.c:2748 sql_help.c:2756 sql_help.c:2769 +#: sql_help.c:2783 sql_help.c:3021 sql_help.c:3027 sql_help.c:3795 msgid "collation" -msgstr "sortering" +msgstr "jämförelse" -#: sql_help.c:445 sql_help.c:1108 sql_help.c:1969 sql_help.c:1978 -#: sql_help.c:2448 sql_help.c:2463 sql_help.c:2475 +#: sql_help.c:453 sql_help.c:1281 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2749 sql_help.c:2765 sql_help.c:2778 msgid "column_constraint" msgstr "kolumnvillkor" -#: sql_help.c:455 sql_help.c:656 sql_help.c:1125 +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1298 msgid "integer" msgstr "heltal" -#: sql_help.c:457 sql_help.c:460 sql_help.c:658 sql_help.c:661 sql_help.c:1127 -#: sql_help.c:1130 +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "attributalternativ" -#: sql_help.c:465 sql_help.c:1132 sql_help.c:1970 sql_help.c:1979 -#: sql_help.c:2449 sql_help.c:2464 sql_help.c:2476 +#: sql_help.c:473 sql_help.c:1305 sql_help.c:2232 sql_help.c:2241 +#: sql_help.c:2750 sql_help.c:2766 sql_help.c:2779 msgid "table_constraint" msgstr "tabellvillkor" -#: sql_help.c:468 sql_help.c:469 sql_help.c:470 sql_help.c:471 sql_help.c:1137 -#: sql_help.c:1138 sql_help.c:1139 sql_help.c:1140 sql_help.c:1571 +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1825 msgid "trigger_name" msgstr "utlösarnamn" -#: sql_help.c:472 sql_help.c:473 sql_help.c:1150 sql_help.c:1151 -#: sql_help.c:1971 sql_help.c:1976 sql_help.c:2452 sql_help.c:2473 +#: sql_help.c:480 sql_help.c:481 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2233 sql_help.c:2238 sql_help.c:2753 sql_help.c:2776 msgid "parent_table" msgstr "föräldertabell" -#: sql_help.c:530 sql_help.c:580 sql_help.c:643 sql_help.c:1275 -#: sql_help.c:1908 +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1491 sql_help.c:2169 msgid "extension_name" msgstr "utökningsnamn" -#: sql_help.c:532 sql_help.c:2025 +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2288 msgid "execution_cost" msgstr "körkostnad" -#: sql_help.c:533 sql_help.c:2026 +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2289 msgid "result_rows" msgstr "resultatrader" -#: sql_help.c:554 sql_help.c:556 sql_help.c:853 sql_help.c:861 sql_help.c:865 -#: sql_help.c:868 sql_help.c:871 sql_help.c:1353 sql_help.c:1361 -#: sql_help.c:1364 sql_help.c:1366 sql_help.c:1368 sql_help.c:2286 -#: sql_help.c:2288 sql_help.c:2291 sql_help.c:2292 sql_help.c:3370 -#: sql_help.c:3374 sql_help.c:3377 sql_help.c:3379 sql_help.c:3381 -#: sql_help.c:3383 sql_help.c:3385 sql_help.c:3391 sql_help.c:3393 -#: sql_help.c:3395 sql_help.c:3397 sql_help.c:3399 sql_help.c:3401 +#: sql_help.c:543 sql_help.c:2290 +msgid "support_function" +msgstr "supportfunktion" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1569 sql_help.c:1577 +#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1587 sql_help.c:2581 +#: sql_help.c:2583 sql_help.c:2586 sql_help.c:2587 sql_help.c:3703 +#: sql_help.c:3707 sql_help.c:3710 sql_help.c:3712 sql_help.c:3714 +#: sql_help.c:3716 sql_help.c:3718 sql_help.c:3724 sql_help.c:3726 +#: sql_help.c:3728 sql_help.c:3730 sql_help.c:3732 sql_help.c:3734 msgid "role_specification" msgstr "rollspecifikation" -#: sql_help.c:555 sql_help.c:557 sql_help.c:1380 sql_help.c:1851 -#: sql_help.c:2294 sql_help.c:2789 sql_help.c:3210 sql_help.c:4033 +#: sql_help.c:565 sql_help.c:567 sql_help.c:1600 sql_help.c:2112 +#: sql_help.c:2589 sql_help.c:3096 sql_help.c:3541 sql_help.c:4376 msgid "user_name" msgstr "användarnamn" -#: sql_help.c:558 sql_help.c:873 sql_help.c:1369 sql_help.c:2293 -#: sql_help.c:3402 +#: sql_help.c:568 sql_help.c:945 sql_help.c:1589 sql_help.c:2588 +#: sql_help.c:3735 msgid "where role_specification can be:" msgstr "där rollspecifikation kan vara:" -#: sql_help.c:560 +#: sql_help.c:570 msgid "group_name" msgstr "gruppnamn" -#: sql_help.c:578 sql_help.c:1856 sql_help.c:2088 sql_help.c:2120 -#: sql_help.c:2459 sql_help.c:2471 sql_help.c:2484 sql_help.c:2524 -#: sql_help.c:2546 sql_help.c:2558 sql_help.c:3398 sql_help.c:3731 +#: sql_help.c:591 sql_help.c:1369 sql_help.c:2117 sql_help.c:2353 +#: sql_help.c:2387 sql_help.c:2761 sql_help.c:2774 sql_help.c:2788 +#: sql_help.c:2829 sql_help.c:2853 sql_help.c:2865 sql_help.c:3731 +#: sql_help.c:4064 msgid "tablespace_name" msgstr "tabellutrymmesnamn" -#: sql_help.c:582 sql_help.c:585 sql_help.c:664 sql_help.c:666 sql_help.c:1147 -#: sql_help.c:1149 sql_help.c:2086 sql_help.c:2118 sql_help.c:2457 -#: sql_help.c:2469 sql_help.c:2482 sql_help.c:2522 sql_help.c:2544 +#: sql_help.c:593 sql_help.c:681 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1364 sql_help.c:1705 +msgid "index_name" +msgstr "indexnamn" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1367 sql_help.c:2351 sql_help.c:2385 +#: sql_help.c:2759 sql_help.c:2772 sql_help.c:2786 sql_help.c:2827 +#: sql_help.c:2851 msgid "storage_parameter" msgstr "lagringsparameter" -#: sql_help.c:608 sql_help.c:1542 sql_help.c:3816 +#: sql_help.c:602 +msgid "column_number" +msgstr "kolumnnummer" + +#: sql_help.c:626 sql_help.c:1788 sql_help.c:4151 msgid "large_object_oid" msgstr "stort_objekt_oid" -#: sql_help.c:663 sql_help.c:1145 sql_help.c:1154 sql_help.c:1157 -#: sql_help.c:1461 -msgid "index_name" -msgstr "indexnamn" - -#: sql_help.c:695 sql_help.c:2141 +#: sql_help.c:713 sql_help.c:2408 msgid "res_proc" msgstr "res_proc" -#: sql_help.c:696 sql_help.c:2142 +#: sql_help.c:714 sql_help.c:2409 msgid "join_proc" msgstr "join_proc" -#: sql_help.c:748 sql_help.c:760 sql_help.c:2159 +#: sql_help.c:766 sql_help.c:778 sql_help.c:2426 msgid "strategy_number" msgstr "strateginummer" -#: sql_help.c:750 sql_help.c:751 sql_help.c:754 sql_help.c:755 sql_help.c:761 -#: sql_help.c:762 sql_help.c:764 sql_help.c:765 sql_help.c:2161 -#: sql_help.c:2162 sql_help.c:2165 sql_help.c:2166 +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2428 sql_help.c:2429 +#: sql_help.c:2432 sql_help.c:2433 msgid "op_type" msgstr "op_typ" -#: sql_help.c:752 sql_help.c:2163 +#: sql_help.c:770 sql_help.c:2430 msgid "sort_family_name" msgstr "sorteringsfamiljnamn" -#: sql_help.c:753 sql_help.c:763 sql_help.c:2164 +#: sql_help.c:771 sql_help.c:781 sql_help.c:2431 msgid "support_number" msgstr "supportnummer" -#: sql_help.c:757 sql_help.c:1795 sql_help.c:2168 sql_help.c:2635 -#: sql_help.c:2637 +#: sql_help.c:775 sql_help.c:2054 sql_help.c:2435 sql_help.c:2942 +#: sql_help.c:2944 msgid "argument_type" msgstr "argumenttyp" -#: sql_help.c:788 sql_help.c:791 sql_help.c:808 sql_help.c:810 sql_help.c:812 -#: sql_help.c:883 sql_help.c:922 sql_help.c:1271 sql_help.c:1274 -#: sql_help.c:1420 sql_help.c:1460 sql_help.c:1527 sql_help.c:1552 -#: sql_help.c:1557 sql_help.c:1572 sql_help.c:1629 sql_help.c:1634 -#: sql_help.c:1963 sql_help.c:1975 sql_help.c:2080 sql_help.c:2116 -#: sql_help.c:2192 sql_help.c:2207 sql_help.c:2263 sql_help.c:2314 -#: sql_help.c:2345 sql_help.c:2444 sql_help.c:2460 sql_help.c:2472 -#: sql_help.c:2542 sql_help.c:2661 sql_help.c:2838 sql_help.c:3055 -#: sql_help.c:3080 sql_help.c:3186 sql_help.c:3368 sql_help.c:3373 -#: sql_help.c:3418 sql_help.c:3450 sql_help.c:3701 sql_help.c:3706 -#: sql_help.c:3804 sql_help.c:3903 sql_help.c:3905 sql_help.c:3954 -#: sql_help.c:3993 sql_help.c:4142 sql_help.c:4144 sql_help.c:4193 -#: sql_help.c:4227 sql_help.c:4249 sql_help.c:4251 sql_help.c:4252 -#: sql_help.c:4336 sql_help.c:4338 sql_help.c:4387 +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1487 sql_help.c:1490 +#: sql_help.c:1655 sql_help.c:1704 sql_help.c:1773 sql_help.c:1798 +#: sql_help.c:1811 sql_help.c:1826 sql_help.c:1883 sql_help.c:1889 +#: sql_help.c:2225 sql_help.c:2237 sql_help.c:2344 sql_help.c:2382 +#: sql_help.c:2459 sql_help.c:2502 sql_help.c:2558 sql_help.c:2609 +#: sql_help.c:2640 sql_help.c:2745 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2848 sql_help.c:2968 sql_help.c:3145 sql_help.c:3362 +#: sql_help.c:3411 sql_help.c:3517 sql_help.c:3701 sql_help.c:3706 +#: sql_help.c:3751 sql_help.c:3783 sql_help.c:4034 sql_help.c:4039 +#: sql_help.c:4139 sql_help.c:4246 sql_help.c:4248 sql_help.c:4297 +#: sql_help.c:4336 sql_help.c:4485 sql_help.c:4487 sql_help.c:4536 +#: sql_help.c:4570 sql_help.c:4617 sql_help.c:4701 sql_help.c:4703 +#: sql_help.c:4752 msgid "table_name" msgstr "tabellnamn" -#: sql_help.c:793 sql_help.c:2194 +#: sql_help.c:811 sql_help.c:2461 msgid "using_expression" msgstr "using-uttryck" -#: sql_help.c:794 sql_help.c:2195 +#: sql_help.c:812 sql_help.c:2462 msgid "check_expression" msgstr "check-uttryck" -#: sql_help.c:814 sql_help.c:2208 +#: sql_help.c:886 sql_help.c:2503 msgid "publication_parameter" msgstr "publiceringsparameter" -#: sql_help.c:857 sql_help.c:1357 sql_help.c:2060 sql_help.c:2240 -#: sql_help.c:2772 +#: sql_help.c:929 sql_help.c:1573 sql_help.c:2323 sql_help.c:2535 +#: sql_help.c:3079 msgid "password" msgstr "lösenord" -#: sql_help.c:858 sql_help.c:1358 sql_help.c:2061 sql_help.c:2241 -#: sql_help.c:2773 +#: sql_help.c:930 sql_help.c:1574 sql_help.c:2324 sql_help.c:2536 +#: sql_help.c:3080 msgid "timestamp" msgstr "tidsstämpel" -#: sql_help.c:862 sql_help.c:866 sql_help.c:869 sql_help.c:872 sql_help.c:3378 -#: sql_help.c:3711 +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1578 +#: sql_help.c:1582 sql_help.c:1585 sql_help.c:1588 sql_help.c:3711 +#: sql_help.c:4044 msgid "database_name" msgstr "databasnamn" -#: sql_help.c:916 sql_help.c:2309 +#: sql_help.c:1048 sql_help.c:2604 msgid "increment" msgstr "ökningsvärde" -#: sql_help.c:917 sql_help.c:2310 +#: sql_help.c:1049 sql_help.c:2605 msgid "minvalue" msgstr "minvärde" -#: sql_help.c:918 sql_help.c:2311 +#: sql_help.c:1050 sql_help.c:2606 msgid "maxvalue" msgstr "maxvärde" -#: sql_help.c:919 sql_help.c:2312 sql_help.c:3901 sql_help.c:3991 -#: sql_help.c:4140 sql_help.c:4269 sql_help.c:4334 +#: sql_help.c:1051 sql_help.c:2607 sql_help.c:4244 sql_help.c:4334 +#: sql_help.c:4483 sql_help.c:4634 sql_help.c:4699 msgid "start" msgstr "start" -#: sql_help.c:920 sql_help.c:1122 +#: sql_help.c:1052 sql_help.c:1295 msgid "restart" msgstr "starta om" -#: sql_help.c:921 sql_help.c:2313 +#: sql_help.c:1053 sql_help.c:2608 msgid "cache" msgstr "cache" -#: sql_help.c:978 sql_help.c:2357 +#: sql_help.c:1110 sql_help.c:2652 msgid "conninfo" msgstr "anslinfo" -#: sql_help.c:980 sql_help.c:2358 +#: sql_help.c:1112 sql_help.c:2653 msgid "publication_name" msgstr "publiceringsnamn" -#: sql_help.c:981 +#: sql_help.c:1113 msgid "set_publication_option" msgstr "sätt_publicerings_alternativ" -#: sql_help.c:984 +#: sql_help.c:1116 msgid "refresh_option" msgstr "refresh_alternativ" -#: sql_help.c:989 sql_help.c:2359 +#: sql_help.c:1121 sql_help.c:2654 msgid "subscription_parameter" msgstr "prenumerationsparameter" -#: sql_help.c:1100 sql_help.c:1103 +#: sql_help.c:1273 sql_help.c:1276 msgid "partition_name" msgstr "paritionsnamn" -#: sql_help.c:1101 sql_help.c:1980 sql_help.c:2477 +#: sql_help.c:1274 sql_help.c:2242 sql_help.c:2780 msgid "partition_bound_spec" -msgstr "partionerings_spec" +msgstr "partitionsgränsspec" -#: sql_help.c:1119 sql_help.c:2489 +#: sql_help.c:1292 sql_help.c:1338 sql_help.c:2794 msgid "sequence_options" msgstr "sekvensalternativ" -#: sql_help.c:1121 +#: sql_help.c:1294 msgid "sequence_option" msgstr "sekvensalternativ" -#: sql_help.c:1133 +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "tabellvillkor_för_index" -#: sql_help.c:1141 sql_help.c:1142 sql_help.c:1143 sql_help.c:1144 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "omskrivningsregelnamn" -#: sql_help.c:1155 +#: sql_help.c:1328 sql_help.c:2819 +msgid "and partition_bound_spec is:" +msgstr "och partitionsgränsspec är:" + +#: sql_help.c:1329 sql_help.c:1330 sql_help.c:1331 sql_help.c:2820 +#: sql_help.c:2821 sql_help.c:2822 +msgid "partition_bound_expr" +msgstr "partitionsgränsuttryck" + +#: sql_help.c:1332 sql_help.c:1333 sql_help.c:2823 sql_help.c:2824 +msgid "numeric_literal" +msgstr "numerisk_literal" + +#: sql_help.c:1334 +msgid "and column_constraint is:" +msgstr "och kolumnvillkor är:" + +#: sql_help.c:1337 sql_help.c:2249 sql_help.c:2282 sql_help.c:2482 +#: sql_help.c:2792 +msgid "default_expr" +msgstr "default_uttryck" + +#: sql_help.c:1339 sql_help.c:1340 sql_help.c:1349 sql_help.c:1351 +#: sql_help.c:1355 sql_help.c:2795 sql_help.c:2796 sql_help.c:2805 +#: sql_help.c:2807 sql_help.c:2811 +msgid "index_parameters" +msgstr "indexparametrar" + +#: sql_help.c:1341 sql_help.c:1358 sql_help.c:2797 sql_help.c:2814 +msgid "reftable" +msgstr "reftabell" + +#: sql_help.c:1342 sql_help.c:1359 sql_help.c:2798 sql_help.c:2815 +msgid "refcolumn" +msgstr "refkolumn" + +#: sql_help.c:1343 sql_help.c:1344 sql_help.c:1360 sql_help.c:1361 +#: sql_help.c:2799 sql_help.c:2800 sql_help.c:2816 sql_help.c:2817 +msgid "referential_action" +msgstr "referentiell_aktion" + +#: sql_help.c:1345 sql_help.c:2251 sql_help.c:2801 +msgid "and table_constraint is:" +msgstr "och tabellvillkor är:" + +#: sql_help.c:1353 sql_help.c:2809 +msgid "exclude_element" +msgstr "uteslutelement" + +#: sql_help.c:1354 sql_help.c:2810 sql_help.c:4242 sql_help.c:4332 +#: sql_help.c:4481 sql_help.c:4632 sql_help.c:4697 +msgid "operator" +msgstr "operator" + +#: sql_help.c:1356 sql_help.c:2354 sql_help.c:2812 +msgid "predicate" +msgstr "predikat" + +#: sql_help.c:1362 msgid "and table_constraint_using_index is:" msgstr "och tabellvillkor_för_index är:" -#: sql_help.c:1173 sql_help.c:1176 sql_help.c:2561 +#: sql_help.c:1365 sql_help.c:2825 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "indexparametrar i UNIQUE-, PRIMARY KEY- och EXCLUDE-villkor är:" + +#: sql_help.c:1370 sql_help.c:2830 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "uteslutelement i ett EXCLUDE-villkort är:" + +#: sql_help.c:1373 sql_help.c:2349 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2784 sql_help.c:2833 sql_help.c:3796 +msgid "opclass" +msgstr "op-klass" + +#: sql_help.c:1389 sql_help.c:1392 sql_help.c:2868 msgid "tablespace_option" msgstr "tabellutrymmesalternativ" -#: sql_help.c:1197 sql_help.c:1200 sql_help.c:1206 sql_help.c:1210 +#: sql_help.c:1413 sql_help.c:1416 sql_help.c:1422 sql_help.c:1426 msgid "token_type" msgstr "symboltyp" -#: sql_help.c:1198 sql_help.c:1201 +#: sql_help.c:1414 sql_help.c:1417 msgid "dictionary_name" msgstr "ordlistnamn" -#: sql_help.c:1203 sql_help.c:1207 +#: sql_help.c:1419 sql_help.c:1423 msgid "old_dictionary" msgstr "gammal_ordlista" -#: sql_help.c:1204 sql_help.c:1208 +#: sql_help.c:1420 sql_help.c:1424 msgid "new_dictionary" msgstr "ny_ordlista" -#: sql_help.c:1300 sql_help.c:1313 sql_help.c:1316 sql_help.c:1317 -#: sql_help.c:2712 +#: sql_help.c:1516 sql_help.c:1529 sql_help.c:1532 sql_help.c:1533 +#: sql_help.c:3019 msgid "attribute_name" msgstr "attributnamn" -#: sql_help.c:1301 +#: sql_help.c:1517 msgid "new_attribute_name" msgstr "nytt_attributnamn" -#: sql_help.c:1307 sql_help.c:1311 +#: sql_help.c:1523 sql_help.c:1527 msgid "new_enum_value" msgstr "nytt_enumvärde" -#: sql_help.c:1308 +#: sql_help.c:1524 msgid "neighbor_enum_value" msgstr "närliggande_enumvärde" -#: sql_help.c:1310 +#: sql_help.c:1526 msgid "existing_enum_value" msgstr "existerande_enumvärde" -#: sql_help.c:1381 sql_help.c:1972 sql_help.c:1981 sql_help.c:2325 -#: sql_help.c:2790 sql_help.c:3211 sql_help.c:3384 sql_help.c:3419 -#: sql_help.c:3717 +#: sql_help.c:1601 sql_help.c:2234 sql_help.c:2243 sql_help.c:2620 +#: sql_help.c:3097 sql_help.c:3542 sql_help.c:3717 sql_help.c:3752 +#: sql_help.c:4050 msgid "server_name" msgstr "servernamn" -#: sql_help.c:1409 sql_help.c:1412 sql_help.c:2805 +#: sql_help.c:1629 sql_help.c:1632 sql_help.c:3112 msgid "view_option_name" msgstr "visningsalternativnamn" -#: sql_help.c:1410 sql_help.c:2806 +#: sql_help.c:1630 sql_help.c:3113 msgid "view_option_value" msgstr "visningsalternativvärde" -#: sql_help.c:1435 sql_help.c:4049 sql_help.c:4051 sql_help.c:4075 +#: sql_help.c:1651 sql_help.c:1652 sql_help.c:4606 sql_help.c:4607 +msgid "table_and_columns" +msgstr "tabell_och_kolumner" + +#: sql_help.c:1653 sql_help.c:1895 sql_help.c:3589 sql_help.c:4608 +msgid "where option can be one of:" +msgstr "där flaggor kan vara en av:" + +#: sql_help.c:1654 sql_help.c:4616 +msgid "and table_and_columns is:" +msgstr "och tabell_och_kolumner är:" + +#: sql_help.c:1670 sql_help.c:4392 sql_help.c:4394 sql_help.c:4418 msgid "transaction_mode" msgstr "transaktionsläge" -#: sql_help.c:1436 sql_help.c:4052 sql_help.c:4076 +#: sql_help.c:1671 sql_help.c:4395 sql_help.c:4419 msgid "where transaction_mode is one of:" msgstr "där transaktionsläge är en av:" -#: sql_help.c:1524 +#: sql_help.c:1680 sql_help.c:4252 sql_help.c:4261 sql_help.c:4265 +#: sql_help.c:4269 sql_help.c:4272 sql_help.c:4491 sql_help.c:4500 +#: sql_help.c:4504 sql_help.c:4508 sql_help.c:4511 sql_help.c:4707 +#: sql_help.c:4716 sql_help.c:4720 sql_help.c:4724 sql_help.c:4727 +msgid "argument" +msgstr "argument" + +#: sql_help.c:1770 msgid "relation_name" msgstr "relationsnamn" -#: sql_help.c:1529 sql_help.c:3380 sql_help.c:3713 +#: sql_help.c:1775 sql_help.c:3713 sql_help.c:4046 msgid "domain_name" msgstr "domännamn" -#: sql_help.c:1551 +#: sql_help.c:1797 msgid "policy_name" msgstr "policynamn" -#: sql_help.c:1556 +#: sql_help.c:1810 msgid "rule_name" msgstr "regelnamn" -#: sql_help.c:1575 +#: sql_help.c:1829 msgid "text" msgstr "text" -#: sql_help.c:1600 sql_help.c:3563 sql_help.c:3751 +#: sql_help.c:1854 sql_help.c:3896 sql_help.c:4084 msgid "transaction_id" msgstr "transaktions-id" -#: sql_help.c:1631 sql_help.c:1637 sql_help.c:3489 +#: sql_help.c:1885 sql_help.c:1892 sql_help.c:3822 msgid "filename" msgstr "filnamn" -#: sql_help.c:1632 sql_help.c:1638 sql_help.c:2265 sql_help.c:2266 -#: sql_help.c:2267 +#: sql_help.c:1886 sql_help.c:1893 sql_help.c:2560 sql_help.c:2561 +#: sql_help.c:2562 msgid "command" msgstr "kommando" -#: sql_help.c:1636 sql_help.c:2121 sql_help.c:2547 sql_help.c:2807 -#: sql_help.c:2825 sql_help.c:3454 +#: sql_help.c:1888 sql_help.c:2559 sql_help.c:2971 sql_help.c:3148 +#: sql_help.c:3806 sql_help.c:4235 sql_help.c:4237 sql_help.c:4325 +#: sql_help.c:4327 sql_help.c:4474 sql_help.c:4476 sql_help.c:4579 +#: sql_help.c:4690 sql_help.c:4692 +msgid "condition" +msgstr "villkor" + +#: sql_help.c:1891 sql_help.c:2388 sql_help.c:2854 sql_help.c:3114 +#: sql_help.c:3132 sql_help.c:3787 msgid "query" msgstr "fråga" -#: sql_help.c:1640 sql_help.c:3257 -msgid "where option can be one of:" -msgstr "där flaggor kan vara en av:" - -#: sql_help.c:1641 +#: sql_help.c:1896 msgid "format_name" msgstr "formatnamn" -#: sql_help.c:1642 sql_help.c:1643 sql_help.c:1646 sql_help.c:3258 -#: sql_help.c:3259 sql_help.c:3260 sql_help.c:3261 sql_help.c:3262 -#: sql_help.c:3263 +#: sql_help.c:1897 sql_help.c:1900 sql_help.c:2079 sql_help.c:3590 +#: sql_help.c:3591 sql_help.c:3592 sql_help.c:3593 sql_help.c:3594 +#: sql_help.c:3595 sql_help.c:3596 sql_help.c:4609 sql_help.c:4610 +#: sql_help.c:4611 sql_help.c:4612 sql_help.c:4613 sql_help.c:4614 +#: sql_help.c:4615 msgid "boolean" msgstr "boolean" -#: sql_help.c:1644 +#: sql_help.c:1898 msgid "delimiter_character" msgstr "avdelartecken" -#: sql_help.c:1645 +#: sql_help.c:1899 msgid "null_string" msgstr "null-sträng" -#: sql_help.c:1647 +#: sql_help.c:1901 msgid "quote_character" msgstr "citattecken" -#: sql_help.c:1648 +#: sql_help.c:1902 msgid "escape_character" msgstr "escape-tecken" -#: sql_help.c:1652 +#: sql_help.c:1906 msgid "encoding_name" msgstr "kodningsnamn" -#: sql_help.c:1663 +#: sql_help.c:1917 msgid "access_method_type" msgstr "accessmetodtyp" -#: sql_help.c:1729 sql_help.c:1748 sql_help.c:1751 +#: sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 msgid "arg_data_type" msgstr "arg_datatyp" -#: sql_help.c:1730 sql_help.c:1752 sql_help.c:1760 +#: sql_help.c:1989 sql_help.c:2011 sql_help.c:2019 msgid "sfunc" msgstr "sfunc" -#: sql_help.c:1731 sql_help.c:1753 sql_help.c:1761 +#: sql_help.c:1990 sql_help.c:2012 sql_help.c:2020 msgid "state_data_type" msgstr "tillståndsdatatyp" -#: sql_help.c:1732 sql_help.c:1754 sql_help.c:1762 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "state_data_size" msgstr "tillståndsdatastorlek" -#: sql_help.c:1733 sql_help.c:1755 sql_help.c:1763 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "ffunc" msgstr "ffunc" -#: sql_help.c:1734 sql_help.c:1764 +#: sql_help.c:1993 sql_help.c:2023 msgid "combinefunc" msgstr "kombinerafunk" -#: sql_help.c:1735 sql_help.c:1765 +#: sql_help.c:1994 sql_help.c:2024 msgid "serialfunc" msgstr "serialiseringsfunk" -#: sql_help.c:1736 sql_help.c:1766 +#: sql_help.c:1995 sql_help.c:2025 msgid "deserialfunc" msgstr "deserialiseringsfunk" -#: sql_help.c:1737 sql_help.c:1756 sql_help.c:1767 +#: sql_help.c:1996 sql_help.c:2015 sql_help.c:2026 msgid "initial_condition" msgstr "startvärde" -#: sql_help.c:1738 sql_help.c:1768 +#: sql_help.c:1997 sql_help.c:2027 msgid "msfunc" msgstr "msfunk" -#: sql_help.c:1739 sql_help.c:1769 +#: sql_help.c:1998 sql_help.c:2028 msgid "minvfunc" msgstr "minvfunk" -#: sql_help.c:1740 sql_help.c:1770 +#: sql_help.c:1999 sql_help.c:2029 msgid "mstate_data_type" msgstr "mtillståndsdatatyp" -#: sql_help.c:1741 sql_help.c:1771 +#: sql_help.c:2000 sql_help.c:2030 msgid "mstate_data_size" msgstr "ntillståndsstorlek" -#: sql_help.c:1742 sql_help.c:1772 +#: sql_help.c:2001 sql_help.c:2031 msgid "mffunc" msgstr "mffunk" -#: sql_help.c:1743 sql_help.c:1773 +#: sql_help.c:2002 sql_help.c:2032 msgid "minitial_condition" msgstr "mstartvärde" -#: sql_help.c:1744 sql_help.c:1774 +#: sql_help.c:2003 sql_help.c:2033 msgid "sort_operator" msgstr "sorteringsoperator" -#: sql_help.c:1757 +#: sql_help.c:2016 msgid "or the old syntax" msgstr "eller gamla syntaxen" -#: sql_help.c:1759 +#: sql_help.c:2018 msgid "base_type" msgstr "bastyp" -#: sql_help.c:1815 +#: sql_help.c:2075 msgid "locale" msgstr "lokal" -#: sql_help.c:1816 sql_help.c:1854 +#: sql_help.c:2076 sql_help.c:2115 msgid "lc_collate" msgstr "lc_collate" -#: sql_help.c:1817 sql_help.c:1855 +#: sql_help.c:2077 sql_help.c:2116 msgid "lc_ctype" msgstr "lc_ctype" -#: sql_help.c:1818 sql_help.c:3802 +#: sql_help.c:2078 sql_help.c:4137 msgid "provider" msgstr "leverantör" -#: sql_help.c:1819 sql_help.c:1910 +#: sql_help.c:2080 sql_help.c:2171 msgid "version" msgstr "version" -#: sql_help.c:1821 +#: sql_help.c:2082 msgid "existing_collation" -msgstr "existerande_sortering" +msgstr "existerande_jämförelse" -#: sql_help.c:1831 +#: sql_help.c:2092 msgid "source_encoding" msgstr "källkodning" -#: sql_help.c:1832 +#: sql_help.c:2093 msgid "dest_encoding" msgstr "målkodning" -#: sql_help.c:1852 sql_help.c:2587 +#: sql_help.c:2113 sql_help.c:2894 msgid "template" msgstr "mall" -#: sql_help.c:1853 +#: sql_help.c:2114 msgid "encoding" msgstr "kodning" -#: sql_help.c:1879 +#: sql_help.c:2140 msgid "constraint" msgstr "villkor" -#: sql_help.c:1880 +#: sql_help.c:2141 msgid "where constraint is:" msgstr "där villkor är:" -#: sql_help.c:1894 sql_help.c:2262 sql_help.c:2660 +#: sql_help.c:2155 sql_help.c:2557 sql_help.c:2967 msgid "event" msgstr "händelse" -#: sql_help.c:1895 +#: sql_help.c:2156 msgid "filter_variable" msgstr "filtervariabel" -#: sql_help.c:1911 +#: sql_help.c:2172 msgid "old_version" msgstr "gammal_version" -#: sql_help.c:1984 sql_help.c:2485 +#: sql_help.c:2246 sql_help.c:2789 msgid "where column_constraint is:" msgstr "där kolumnvillkor är:" -#: sql_help.c:1987 sql_help.c:2019 sql_help.c:2488 -msgid "default_expr" -msgstr "default_uttryck" +#: sql_help.c:2250 sql_help.c:2793 +msgid "generation_expr" +msgstr "generatoruttryck" -#: sql_help.c:1988 sql_help.c:2496 -msgid "and table_constraint is:" -msgstr "och tabellvillkor är:" - -#: sql_help.c:2020 +#: sql_help.c:2283 msgid "rettype" msgstr "rettyp" -#: sql_help.c:2022 +#: sql_help.c:2285 msgid "column_type" msgstr "kolumntyp" -#: sql_help.c:2030 +#: sql_help.c:2294 sql_help.c:2488 msgid "definition" msgstr "definition" -#: sql_help.c:2031 +#: sql_help.c:2295 sql_help.c:2489 msgid "obj_file" msgstr "obj-fil" -#: sql_help.c:2032 +#: sql_help.c:2296 sql_help.c:2490 msgid "link_symbol" msgstr "linksymbol" -#: sql_help.c:2033 -msgid "attribute" -msgstr "attribut" - -#: sql_help.c:2067 sql_help.c:2247 sql_help.c:2779 +#: sql_help.c:2330 sql_help.c:2542 sql_help.c:3086 msgid "uid" msgstr "uid" -#: sql_help.c:2081 +#: sql_help.c:2345 sql_help.c:2384 sql_help.c:2758 sql_help.c:2771 +#: sql_help.c:2785 sql_help.c:2850 msgid "method" msgstr "metod" -#: sql_help.c:2085 sql_help.c:2456 sql_help.c:2468 sql_help.c:2481 -#: sql_help.c:2528 sql_help.c:3463 -msgid "opclass" -msgstr "op-klass" - -#: sql_help.c:2089 sql_help.c:2507 -msgid "predicate" -msgstr "predikat" - -#: sql_help.c:2101 +#: sql_help.c:2366 msgid "call_handler" msgstr "anropshanterare" -#: sql_help.c:2102 +#: sql_help.c:2367 msgid "inline_handler" msgstr "inline-hanterare" -#: sql_help.c:2103 +#: sql_help.c:2368 msgid "valfunction" msgstr "val-funktion" -#: sql_help.c:2139 +#: sql_help.c:2406 msgid "com_op" msgstr "com_op" -#: sql_help.c:2140 +#: sql_help.c:2407 msgid "neg_op" msgstr "neg_op" -#: sql_help.c:2158 +#: sql_help.c:2425 msgid "family_name" msgstr "familjenamn" -#: sql_help.c:2169 +#: sql_help.c:2436 msgid "storage_type" msgstr "lagringstyp" -#: sql_help.c:2264 sql_help.c:2664 sql_help.c:2841 sql_help.c:3473 -#: sql_help.c:3892 sql_help.c:3894 sql_help.c:3982 sql_help.c:3984 -#: sql_help.c:4131 sql_help.c:4133 sql_help.c:4236 sql_help.c:4325 -#: sql_help.c:4327 -msgid "condition" -msgstr "villkor" - -#: sql_help.c:2268 sql_help.c:2667 +#: sql_help.c:2563 sql_help.c:2974 msgid "where event can be one of:" msgstr "där händelse kan vara en av:" -#: sql_help.c:2287 sql_help.c:2289 +#: sql_help.c:2582 sql_help.c:2584 msgid "schema_element" msgstr "schema-element" -#: sql_help.c:2326 +#: sql_help.c:2621 msgid "server_type" msgstr "servertyp" -#: sql_help.c:2327 +#: sql_help.c:2622 msgid "server_version" msgstr "serverversion" -#: sql_help.c:2328 sql_help.c:3382 sql_help.c:3715 +#: sql_help.c:2623 sql_help.c:3715 sql_help.c:4048 msgid "fdw_name" msgstr "fdw-namn" -#: sql_help.c:2341 +#: sql_help.c:2636 msgid "statistics_name" msgstr "statistiknamn" -#: sql_help.c:2342 -msgid "statistic_type" -msgstr "statistiktyp" +#: sql_help.c:2637 +msgid "statistics_kind" +msgstr "statistiksort" -#: sql_help.c:2356 +#: sql_help.c:2651 msgid "subscription_name" msgstr "prenumerationsnamn" -#: sql_help.c:2450 +#: sql_help.c:2751 msgid "source_table" msgstr "källtabell" -#: sql_help.c:2451 +#: sql_help.c:2752 msgid "like_option" msgstr "like_alternativ" -#: sql_help.c:2490 sql_help.c:2491 sql_help.c:2500 sql_help.c:2502 -#: sql_help.c:2506 -msgid "index_parameters" -msgstr "indexparametrar" - -#: sql_help.c:2492 sql_help.c:2509 -msgid "reftable" -msgstr "reftabell" - -#: sql_help.c:2493 sql_help.c:2510 -msgid "refcolumn" -msgstr "refkolumn" - -#: sql_help.c:2504 -msgid "exclude_element" -msgstr "uteslutelement" - -#: sql_help.c:2505 sql_help.c:3899 sql_help.c:3989 sql_help.c:4138 -#: sql_help.c:4267 sql_help.c:4332 -msgid "operator" -msgstr "operator" - -#: sql_help.c:2513 +#: sql_help.c:2818 msgid "and like_option is:" msgstr "och likealternativ är:" -#: sql_help.c:2514 -msgid "and partition_bound_spec is:" -msgstr "och partionerings_spec är:" - -#: sql_help.c:2515 sql_help.c:2517 sql_help.c:2519 -msgid "numeric_literal" -msgstr "numerisk_literal" - -#: sql_help.c:2516 sql_help.c:2518 sql_help.c:2520 -msgid "string_literal" -msgstr "strängliteral" - -#: sql_help.c:2521 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "indexparametrar i UNIQUE-, PRIMARY KEY- och EXCLUDE-villkor är:" - -#: sql_help.c:2525 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "uteslutelement i ett EXCLUDE-villkort är:" - -#: sql_help.c:2560 +#: sql_help.c:2867 msgid "directory" msgstr "katalog" -#: sql_help.c:2574 +#: sql_help.c:2881 msgid "parser_name" msgstr "parsernamn" -#: sql_help.c:2575 +#: sql_help.c:2882 msgid "source_config" msgstr "källkonfig" -#: sql_help.c:2604 +#: sql_help.c:2911 msgid "start_function" msgstr "startfunktion" -#: sql_help.c:2605 +#: sql_help.c:2912 msgid "gettoken_function" msgstr "gettoken_funktion" -#: sql_help.c:2606 +#: sql_help.c:2913 msgid "end_function" msgstr "slutfunktion" -#: sql_help.c:2607 +#: sql_help.c:2914 msgid "lextypes_function" msgstr "symboltypfunktion" -#: sql_help.c:2608 +#: sql_help.c:2915 msgid "headline_function" msgstr "rubrikfunktion" -#: sql_help.c:2620 +#: sql_help.c:2927 msgid "init_function" msgstr "init_funktion" -#: sql_help.c:2621 +#: sql_help.c:2928 msgid "lexize_function" msgstr "symboluppdelningsfunktion" -#: sql_help.c:2634 +#: sql_help.c:2941 msgid "from_sql_function_name" msgstr "från_sql_funktionsnamn" -#: sql_help.c:2636 +#: sql_help.c:2943 msgid "to_sql_function_name" msgstr "till_sql_funktionsnamn" -#: sql_help.c:2662 +#: sql_help.c:2969 msgid "referenced_table_name" msgstr "refererat_tabellnamn" -#: sql_help.c:2663 +#: sql_help.c:2970 msgid "transition_relation_name" msgstr "övergångsrelationsnamn" -#: sql_help.c:2666 +#: sql_help.c:2973 msgid "arguments" msgstr "argument" -#: sql_help.c:2716 sql_help.c:3827 +#: sql_help.c:3023 sql_help.c:4170 msgid "label" msgstr "etikett" -#: sql_help.c:2718 +#: sql_help.c:3025 msgid "subtype" msgstr "subtyp" -#: sql_help.c:2719 +#: sql_help.c:3026 msgid "subtype_operator_class" msgstr "subtypoperatorklass" -#: sql_help.c:2721 +#: sql_help.c:3028 msgid "canonical_function" msgstr "kanonisk_funktion" -#: sql_help.c:2722 +#: sql_help.c:3029 msgid "subtype_diff_function" msgstr "subtyp_diff_funktion" -#: sql_help.c:2724 +#: sql_help.c:3031 msgid "input_function" msgstr "inmatningsfunktion" -#: sql_help.c:2725 +#: sql_help.c:3032 msgid "output_function" msgstr "utmatningsfunktion" -#: sql_help.c:2726 +#: sql_help.c:3033 msgid "receive_function" msgstr "mottagarfunktion" -#: sql_help.c:2727 +#: sql_help.c:3034 msgid "send_function" msgstr "sändfunktion" -#: sql_help.c:2728 +#: sql_help.c:3035 msgid "type_modifier_input_function" msgstr "typmodifiering_indatafunktion" -#: sql_help.c:2729 +#: sql_help.c:3036 msgid "type_modifier_output_function" msgstr "typmodifiering_utdatafunktion" -#: sql_help.c:2730 +#: sql_help.c:3037 msgid "analyze_function" msgstr "analysfunktion" -#: sql_help.c:2731 +#: sql_help.c:3038 msgid "internallength" msgstr "internlängd" -#: sql_help.c:2732 +#: sql_help.c:3039 msgid "alignment" msgstr "justering" -#: sql_help.c:2733 +#: sql_help.c:3040 msgid "storage" msgstr "lagring" -#: sql_help.c:2734 +#: sql_help.c:3041 msgid "like_type" msgstr "liketyp" -#: sql_help.c:2735 +#: sql_help.c:3042 msgid "category" msgstr "kategori" -#: sql_help.c:2736 +#: sql_help.c:3043 msgid "preferred" msgstr "föredragen" -#: sql_help.c:2737 +#: sql_help.c:3044 msgid "default" msgstr "standard" -#: sql_help.c:2738 +#: sql_help.c:3045 msgid "element" msgstr "element" -#: sql_help.c:2739 +#: sql_help.c:3046 msgid "delimiter" msgstr "avskiljare" -#: sql_help.c:2740 +#: sql_help.c:3047 msgid "collatable" msgstr "sorterbar" -#: sql_help.c:2837 sql_help.c:3449 sql_help.c:3887 sql_help.c:3976 -#: sql_help.c:4126 sql_help.c:4226 sql_help.c:4320 +#: sql_help.c:3144 sql_help.c:3782 sql_help.c:4230 sql_help.c:4319 +#: sql_help.c:4469 sql_help.c:4569 sql_help.c:4685 msgid "with_query" msgstr "with_fråga" -#: sql_help.c:2839 sql_help.c:3451 sql_help.c:3906 sql_help.c:3912 -#: sql_help.c:3915 sql_help.c:3919 sql_help.c:3923 sql_help.c:3931 -#: sql_help.c:4145 sql_help.c:4151 sql_help.c:4154 sql_help.c:4158 -#: sql_help.c:4162 sql_help.c:4170 sql_help.c:4228 sql_help.c:4339 -#: sql_help.c:4345 sql_help.c:4348 sql_help.c:4352 sql_help.c:4356 -#: sql_help.c:4364 +#: sql_help.c:3146 sql_help.c:3784 sql_help.c:4249 sql_help.c:4255 +#: sql_help.c:4258 sql_help.c:4262 sql_help.c:4266 sql_help.c:4274 +#: sql_help.c:4488 sql_help.c:4494 sql_help.c:4497 sql_help.c:4501 +#: sql_help.c:4505 sql_help.c:4513 sql_help.c:4571 sql_help.c:4704 +#: sql_help.c:4710 sql_help.c:4713 sql_help.c:4717 sql_help.c:4721 +#: sql_help.c:4729 msgid "alias" msgstr "alias" -#: sql_help.c:2840 +#: sql_help.c:3147 msgid "using_list" msgstr "using_lista" -#: sql_help.c:2842 sql_help.c:3289 sql_help.c:3530 sql_help.c:4237 +#: sql_help.c:3149 sql_help.c:3622 sql_help.c:3863 sql_help.c:4580 msgid "cursor_name" msgstr "markörnamn" -#: sql_help.c:2843 sql_help.c:3457 sql_help.c:4238 +#: sql_help.c:3150 sql_help.c:3790 sql_help.c:4581 msgid "output_expression" msgstr "utdatauttryck" -#: sql_help.c:2844 sql_help.c:3458 sql_help.c:3890 sql_help.c:3979 -#: sql_help.c:4129 sql_help.c:4239 sql_help.c:4323 +#: sql_help.c:3151 sql_help.c:3791 sql_help.c:4233 sql_help.c:4322 +#: sql_help.c:4472 sql_help.c:4582 sql_help.c:4688 msgid "output_name" msgstr "utdatanamn" -#: sql_help.c:2860 +#: sql_help.c:3167 msgid "code" msgstr "kod" -#: sql_help.c:3235 +#: sql_help.c:3566 msgid "parameter" msgstr "parameter" -#: sql_help.c:3255 sql_help.c:3256 sql_help.c:3555 +#: sql_help.c:3587 sql_help.c:3588 sql_help.c:3888 msgid "statement" msgstr "sats" -#: sql_help.c:3288 sql_help.c:3529 +#: sql_help.c:3621 sql_help.c:3862 msgid "direction" msgstr "riktning" -#: sql_help.c:3290 sql_help.c:3531 +#: sql_help.c:3623 sql_help.c:3864 msgid "where direction can be empty or one of:" msgstr "där riktning kan vara tom eller en av:" -#: sql_help.c:3291 sql_help.c:3292 sql_help.c:3293 sql_help.c:3294 -#: sql_help.c:3295 sql_help.c:3532 sql_help.c:3533 sql_help.c:3534 -#: sql_help.c:3535 sql_help.c:3536 sql_help.c:3900 sql_help.c:3902 -#: sql_help.c:3990 sql_help.c:3992 sql_help.c:4139 sql_help.c:4141 -#: sql_help.c:4268 sql_help.c:4270 sql_help.c:4333 sql_help.c:4335 +#: sql_help.c:3624 sql_help.c:3625 sql_help.c:3626 sql_help.c:3627 +#: sql_help.c:3628 sql_help.c:3865 sql_help.c:3866 sql_help.c:3867 +#: sql_help.c:3868 sql_help.c:3869 sql_help.c:4243 sql_help.c:4245 +#: sql_help.c:4333 sql_help.c:4335 sql_help.c:4482 sql_help.c:4484 +#: sql_help.c:4633 sql_help.c:4635 sql_help.c:4698 sql_help.c:4700 msgid "count" msgstr "antal" -#: sql_help.c:3375 sql_help.c:3708 +#: sql_help.c:3708 sql_help.c:4041 msgid "sequence_name" msgstr "sekvensnamn" -#: sql_help.c:3388 sql_help.c:3721 +#: sql_help.c:3721 sql_help.c:4054 msgid "arg_name" msgstr "arg_namn" -#: sql_help.c:3389 sql_help.c:3722 +#: sql_help.c:3722 sql_help.c:4055 msgid "arg_type" msgstr "arg_typ" -#: sql_help.c:3394 sql_help.c:3727 +#: sql_help.c:3727 sql_help.c:4060 msgid "loid" msgstr "loid" -#: sql_help.c:3417 +#: sql_help.c:3750 msgid "remote_schema" msgstr "externt_schema" -#: sql_help.c:3420 +#: sql_help.c:3753 msgid "local_schema" msgstr "lokalt_schema" -#: sql_help.c:3455 +#: sql_help.c:3788 msgid "conflict_target" msgstr "konfliktmål" -#: sql_help.c:3456 +#: sql_help.c:3789 msgid "conflict_action" msgstr "konfliktaktion" -#: sql_help.c:3459 +#: sql_help.c:3792 msgid "where conflict_target can be one of:" msgstr "där konfliktmål kan vara en av:" -#: sql_help.c:3460 +#: sql_help.c:3793 msgid "index_column_name" msgstr "indexkolumnnamn" -#: sql_help.c:3461 +#: sql_help.c:3794 msgid "index_expression" msgstr "indexuttryck" -#: sql_help.c:3464 +#: sql_help.c:3797 msgid "index_predicate" msgstr "indexpredikat" -#: sql_help.c:3466 +#: sql_help.c:3799 msgid "and conflict_action is one of:" msgstr "och konfliktaktion är en av:" -#: sql_help.c:3472 sql_help.c:4234 +#: sql_help.c:3805 sql_help.c:4577 msgid "sub-SELECT" msgstr "sub-SELECT" -#: sql_help.c:3481 sql_help.c:3544 sql_help.c:4210 +#: sql_help.c:3814 sql_help.c:3877 sql_help.c:4553 msgid "channel" msgstr "kanal" -#: sql_help.c:3503 +#: sql_help.c:3836 msgid "lockmode" msgstr "låsläge" -#: sql_help.c:3504 +#: sql_help.c:3837 msgid "where lockmode is one of:" msgstr "där låsläge är en av:" -#: sql_help.c:3545 +#: sql_help.c:3878 msgid "payload" msgstr "innehåll" -#: sql_help.c:3572 +#: sql_help.c:3905 msgid "old_role" msgstr "gammal_roll" -#: sql_help.c:3573 +#: sql_help.c:3906 msgid "new_role" msgstr "ny_roll" -#: sql_help.c:3598 sql_help.c:3759 sql_help.c:3767 +#: sql_help.c:3931 sql_help.c:4092 sql_help.c:4100 msgid "savepoint_name" msgstr "sparpunktnamn" -#: sql_help.c:3891 sql_help.c:3933 sql_help.c:3935 sql_help.c:3981 -#: sql_help.c:4130 sql_help.c:4172 sql_help.c:4174 sql_help.c:4324 -#: sql_help.c:4366 sql_help.c:4368 +#: sql_help.c:4234 sql_help.c:4276 sql_help.c:4278 sql_help.c:4324 +#: sql_help.c:4473 sql_help.c:4515 sql_help.c:4517 sql_help.c:4689 +#: sql_help.c:4731 sql_help.c:4733 msgid "from_item" msgstr "frånval" -#: sql_help.c:3893 sql_help.c:3945 sql_help.c:4132 sql_help.c:4184 -#: sql_help.c:4326 sql_help.c:4378 +#: sql_help.c:4236 sql_help.c:4288 sql_help.c:4475 sql_help.c:4527 +#: sql_help.c:4691 sql_help.c:4743 msgid "grouping_element" msgstr "gruperingselement" -#: sql_help.c:3895 sql_help.c:3985 sql_help.c:4134 sql_help.c:4328 +#: sql_help.c:4238 sql_help.c:4328 sql_help.c:4477 sql_help.c:4693 msgid "window_name" msgstr "fönsternamn" -#: sql_help.c:3896 sql_help.c:3986 sql_help.c:4135 sql_help.c:4329 +#: sql_help.c:4239 sql_help.c:4329 sql_help.c:4478 sql_help.c:4694 msgid "window_definition" msgstr "fönsterdefinition" -#: sql_help.c:3897 sql_help.c:3911 sql_help.c:3949 sql_help.c:3987 -#: sql_help.c:4136 sql_help.c:4150 sql_help.c:4188 sql_help.c:4330 -#: sql_help.c:4344 sql_help.c:4382 +#: sql_help.c:4240 sql_help.c:4254 sql_help.c:4292 sql_help.c:4330 +#: sql_help.c:4479 sql_help.c:4493 sql_help.c:4531 sql_help.c:4695 +#: sql_help.c:4709 sql_help.c:4747 msgid "select" msgstr "select" -#: sql_help.c:3904 sql_help.c:4143 sql_help.c:4337 +#: sql_help.c:4247 sql_help.c:4486 sql_help.c:4702 msgid "where from_item can be one of:" msgstr "där frånval kan vara en av:" -#: sql_help.c:3907 sql_help.c:3913 sql_help.c:3916 sql_help.c:3920 -#: sql_help.c:3932 sql_help.c:4146 sql_help.c:4152 sql_help.c:4155 -#: sql_help.c:4159 sql_help.c:4171 sql_help.c:4340 sql_help.c:4346 -#: sql_help.c:4349 sql_help.c:4353 sql_help.c:4365 +#: sql_help.c:4250 sql_help.c:4256 sql_help.c:4259 sql_help.c:4263 +#: sql_help.c:4275 sql_help.c:4489 sql_help.c:4495 sql_help.c:4498 +#: sql_help.c:4502 sql_help.c:4514 sql_help.c:4705 sql_help.c:4711 +#: sql_help.c:4714 sql_help.c:4718 sql_help.c:4730 msgid "column_alias" msgstr "kolumnalias" -#: sql_help.c:3908 sql_help.c:4147 sql_help.c:4341 +#: sql_help.c:4251 sql_help.c:4490 sql_help.c:4706 msgid "sampling_method" msgstr "samplingsmetod" -#: sql_help.c:3909 sql_help.c:3918 sql_help.c:3922 sql_help.c:3926 -#: sql_help.c:3929 sql_help.c:4148 sql_help.c:4157 sql_help.c:4161 -#: sql_help.c:4165 sql_help.c:4168 sql_help.c:4342 sql_help.c:4351 -#: sql_help.c:4355 sql_help.c:4359 sql_help.c:4362 -msgid "argument" -msgstr "argument" - -#: sql_help.c:3910 sql_help.c:4149 sql_help.c:4343 +#: sql_help.c:4253 sql_help.c:4492 sql_help.c:4708 msgid "seed" msgstr "frö" -#: sql_help.c:3914 sql_help.c:3947 sql_help.c:4153 sql_help.c:4186 -#: sql_help.c:4347 sql_help.c:4380 +#: sql_help.c:4257 sql_help.c:4290 sql_help.c:4496 sql_help.c:4529 +#: sql_help.c:4712 sql_help.c:4745 msgid "with_query_name" msgstr "with_frågenamn" -#: sql_help.c:3924 sql_help.c:3927 sql_help.c:3930 sql_help.c:4163 -#: sql_help.c:4166 sql_help.c:4169 sql_help.c:4357 sql_help.c:4360 -#: sql_help.c:4363 +#: sql_help.c:4267 sql_help.c:4270 sql_help.c:4273 sql_help.c:4506 +#: sql_help.c:4509 sql_help.c:4512 sql_help.c:4722 sql_help.c:4725 +#: sql_help.c:4728 msgid "column_definition" msgstr "kolumndefinition" -#: sql_help.c:3934 sql_help.c:4173 sql_help.c:4367 +#: sql_help.c:4277 sql_help.c:4516 sql_help.c:4732 msgid "join_type" msgstr "join-typ" -#: sql_help.c:3936 sql_help.c:4175 sql_help.c:4369 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4734 msgid "join_condition" msgstr "join-villkor" -#: sql_help.c:3937 sql_help.c:4176 sql_help.c:4370 +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4735 msgid "join_column" msgstr "join-kolumn" -#: sql_help.c:3938 sql_help.c:4177 sql_help.c:4371 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4736 msgid "and grouping_element can be one of:" msgstr "och grupperingselement kan vara en av:" -#: sql_help.c:3946 sql_help.c:4185 sql_help.c:4379 +#: sql_help.c:4289 sql_help.c:4528 sql_help.c:4744 msgid "and with_query is:" msgstr "och with_fråga är:" -#: sql_help.c:3950 sql_help.c:4189 sql_help.c:4383 +#: sql_help.c:4293 sql_help.c:4532 sql_help.c:4748 msgid "values" msgstr "värden" -#: sql_help.c:3951 sql_help.c:4190 sql_help.c:4384 +#: sql_help.c:4294 sql_help.c:4533 sql_help.c:4749 msgid "insert" msgstr "insert" -#: sql_help.c:3952 sql_help.c:4191 sql_help.c:4385 +#: sql_help.c:4295 sql_help.c:4534 sql_help.c:4750 msgid "update" msgstr "update" -#: sql_help.c:3953 sql_help.c:4192 sql_help.c:4386 +#: sql_help.c:4296 sql_help.c:4535 sql_help.c:4751 msgid "delete" msgstr "delete" -#: sql_help.c:3980 +#: sql_help.c:4323 msgid "new_table" msgstr "ny_tabell" -#: sql_help.c:4005 +#: sql_help.c:4348 msgid "timezone" msgstr "tidszon" -#: sql_help.c:4050 +#: sql_help.c:4393 msgid "snapshot_id" msgstr "snapshot_id" -#: sql_help.c:4235 +#: sql_help.c:4578 msgid "from_list" msgstr "frånlista" -#: sql_help.c:4266 +#: sql_help.c:4631 msgid "sort_expression" msgstr "sorteringsuttryck" -#: sql_help.c:4393 sql_help.c:5178 +#: sql_help.c:4758 sql_help.c:5736 msgid "abort the current transaction" msgstr "avbryt aktuell transaktion" -#: sql_help.c:4398 +#: sql_help.c:4764 msgid "change the definition of an aggregate function" msgstr "ändra definitionen av en aggregatfunktion" -#: sql_help.c:4403 +#: sql_help.c:4770 msgid "change the definition of a collation" -msgstr "ändra definitionen av en sortering" +msgstr "ändra definitionen av en jämförelse" -#: sql_help.c:4408 +#: sql_help.c:4776 msgid "change the definition of a conversion" msgstr "ändra definitionen av en konvertering" -#: sql_help.c:4413 +#: sql_help.c:4782 msgid "change a database" msgstr "ändra en databas" -#: sql_help.c:4418 +#: sql_help.c:4788 msgid "define default access privileges" msgstr "definiera standardaccessrättigheter" -#: sql_help.c:4423 +#: sql_help.c:4794 msgid "change the definition of a domain" msgstr "ändra definitionen av en domän" -#: sql_help.c:4428 +#: sql_help.c:4800 msgid "change the definition of an event trigger" msgstr "ändra definitionen av en händelseutlösare" -#: sql_help.c:4433 +#: sql_help.c:4806 msgid "change the definition of an extension" msgstr "ändra definitionen av en utökning" -#: sql_help.c:4438 +#: sql_help.c:4812 msgid "change the definition of a foreign-data wrapper" msgstr "ändra definitionen av en främmande data-omvandlare" -#: sql_help.c:4443 +#: sql_help.c:4818 msgid "change the definition of a foreign table" msgstr "ändra definitionen av en främmande tabell" -#: sql_help.c:4448 +#: sql_help.c:4824 msgid "change the definition of a function" msgstr "ändra definitionen av en funktion" -#: sql_help.c:4453 +#: sql_help.c:4830 msgid "change role name or membership" msgstr "ändra rollnamn eller medlemskap" -#: sql_help.c:4458 +#: sql_help.c:4836 msgid "change the definition of an index" msgstr "ändra definitionen av ett index" -#: sql_help.c:4463 +#: sql_help.c:4842 msgid "change the definition of a procedural language" msgstr "ändra definitionen av ett procedur-språk" -#: sql_help.c:4468 +#: sql_help.c:4848 msgid "change the definition of a large object" msgstr "ändra definitionen av ett stort objekt" -#: sql_help.c:4473 +#: sql_help.c:4854 msgid "change the definition of a materialized view" msgstr "ändra definitionen av en materialiserad vy" -#: sql_help.c:4478 +#: sql_help.c:4860 msgid "change the definition of an operator" msgstr "ändra definitionen av en operator" -#: sql_help.c:4483 +#: sql_help.c:4866 msgid "change the definition of an operator class" msgstr "ändra definitionen av en operatorklass" -#: sql_help.c:4488 +#: sql_help.c:4872 msgid "change the definition of an operator family" msgstr "ändra definitionen av en operatorfamilj" -#: sql_help.c:4493 +#: sql_help.c:4878 msgid "change the definition of a row level security policy" msgstr "ändra definitionen av en säkerhetspolicy på radnivå" -#: sql_help.c:4498 +#: sql_help.c:4884 +msgid "change the definition of a procedure" +msgstr "ändra definitionen av en procedur" + +#: sql_help.c:4890 msgid "change the definition of a publication" msgstr "ändra definitionen av en publicering" -#: sql_help.c:4503 sql_help.c:4583 +#: sql_help.c:4896 sql_help.c:4998 msgid "change a database role" msgstr "ändra databasroll" -#: sql_help.c:4508 +#: sql_help.c:4902 +msgid "change the definition of a routine" +msgstr "ändra definitionen av en rutin" + +#: sql_help.c:4908 msgid "change the definition of a rule" msgstr "ändra definitionen av en regel" -#: sql_help.c:4513 +#: sql_help.c:4914 msgid "change the definition of a schema" msgstr "ändra definitionen av ett schema" -#: sql_help.c:4518 +#: sql_help.c:4920 msgid "change the definition of a sequence generator" msgstr "ändra definitionen av en sekvensgenerator" -#: sql_help.c:4523 +#: sql_help.c:4926 msgid "change the definition of a foreign server" msgstr "ändra definitionen av en främmande server" -#: sql_help.c:4528 +#: sql_help.c:4932 msgid "change the definition of an extended statistics object" msgstr "ändra definitionen av ett utökat statistikobjekt" -#: sql_help.c:4533 +#: sql_help.c:4938 msgid "change the definition of a subscription" msgstr "ändra definitionen av en prenumerering" -#: sql_help.c:4538 +#: sql_help.c:4944 msgid "change a server configuration parameter" msgstr "ändra en servers konfigurationsparameter" -#: sql_help.c:4543 +#: sql_help.c:4950 msgid "change the definition of a table" msgstr "ändra definitionen av en tabell" -#: sql_help.c:4548 +#: sql_help.c:4956 msgid "change the definition of a tablespace" msgstr "ändra definitionen av ett tabellutrymme" -#: sql_help.c:4553 +#: sql_help.c:4962 msgid "change the definition of a text search configuration" msgstr "ändra definitionen av en textsökkonfiguration" -#: sql_help.c:4558 +#: sql_help.c:4968 msgid "change the definition of a text search dictionary" msgstr "ändra definitionen av en textsökordlista" -#: sql_help.c:4563 +#: sql_help.c:4974 msgid "change the definition of a text search parser" msgstr "ändra definitionen av en textsökparser" -#: sql_help.c:4568 +#: sql_help.c:4980 msgid "change the definition of a text search template" msgstr "ändra definitionen av en textsökmall" -#: sql_help.c:4573 +#: sql_help.c:4986 msgid "change the definition of a trigger" msgstr "ändra definitionen av en utlösare" -#: sql_help.c:4578 +#: sql_help.c:4992 msgid "change the definition of a type" msgstr "ändra definitionen av en typ" -#: sql_help.c:4588 +#: sql_help.c:5004 msgid "change the definition of a user mapping" msgstr "ändra definitionen av en användarmappning" -#: sql_help.c:4593 +#: sql_help.c:5010 msgid "change the definition of a view" msgstr "ändra definitionen av en vy" -#: sql_help.c:4598 +#: sql_help.c:5016 msgid "collect statistics about a database" msgstr "samla in statistik om en databas" -#: sql_help.c:4603 sql_help.c:5243 +#: sql_help.c:5022 sql_help.c:5814 msgid "start a transaction block" msgstr "starta ett transaktionsblock" -#: sql_help.c:4608 +#: sql_help.c:5028 +msgid "invoke a procedure" +msgstr "anropa en procedur" + +#: sql_help.c:5034 msgid "force a write-ahead log checkpoint" msgstr "tvinga checkpoint i transaktionsloggen" -#: sql_help.c:4613 +#: sql_help.c:5040 msgid "close a cursor" msgstr "stäng en markör" -#: sql_help.c:4618 +#: sql_help.c:5046 msgid "cluster a table according to an index" msgstr "klustra en tabell efter ett index" -#: sql_help.c:4623 +#: sql_help.c:5052 msgid "define or change the comment of an object" msgstr "definiera eller ändra en kommentar på ett objekt" -#: sql_help.c:4628 sql_help.c:5078 +#: sql_help.c:5058 sql_help.c:5616 msgid "commit the current transaction" msgstr "utför den aktuella transaktionen" -#: sql_help.c:4633 +#: sql_help.c:5064 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "utför commit på en transaktion som tidigare förberetts för två-fas-commit" -#: sql_help.c:4638 +#: sql_help.c:5070 msgid "copy data between a file and a table" msgstr "kopiera data mellan en fil och en tabell" -#: sql_help.c:4643 +#: sql_help.c:5076 msgid "define a new access method" msgstr "definiera en ny accessmetod" -#: sql_help.c:4648 +#: sql_help.c:5082 msgid "define a new aggregate function" msgstr "definiera en ny aggregatfunktion" -#: sql_help.c:4653 +#: sql_help.c:5088 msgid "define a new cast" msgstr "definiera en ny typomvandling" -#: sql_help.c:4658 +#: sql_help.c:5094 msgid "define a new collation" -msgstr "definiera en ny sortering" +msgstr "definiera en ny jämförelse" -#: sql_help.c:4663 +#: sql_help.c:5100 msgid "define a new encoding conversion" msgstr "definiera en ny teckenkodningskonvertering" -#: sql_help.c:4668 +#: sql_help.c:5106 msgid "create a new database" msgstr "skapa en ny databas" -#: sql_help.c:4673 +#: sql_help.c:5112 msgid "define a new domain" msgstr "definiera en ny domän" -#: sql_help.c:4678 +#: sql_help.c:5118 msgid "define a new event trigger" msgstr "definiera en ny händelseutlösare" -#: sql_help.c:4683 +#: sql_help.c:5124 msgid "install an extension" msgstr "installera en utökning" -#: sql_help.c:4688 +#: sql_help.c:5130 msgid "define a new foreign-data wrapper" msgstr "definiera en ny främmande data-omvandlare" -#: sql_help.c:4693 +#: sql_help.c:5136 msgid "define a new foreign table" msgstr "definiera en ny främmande tabell" -#: sql_help.c:4698 +#: sql_help.c:5142 msgid "define a new function" msgstr "definiera en ny funktion" -#: sql_help.c:4703 sql_help.c:4748 sql_help.c:4833 +#: sql_help.c:5148 sql_help.c:5208 sql_help.c:5310 msgid "define a new database role" msgstr "definiera en ny databasroll" -#: sql_help.c:4708 +#: sql_help.c:5154 msgid "define a new index" msgstr "skapa ett nytt index" -#: sql_help.c:4713 +#: sql_help.c:5160 msgid "define a new procedural language" msgstr "definiera ett nytt procedur-språk" -#: sql_help.c:4718 +#: sql_help.c:5166 msgid "define a new materialized view" msgstr "definiera en ny materialiserad vy" -#: sql_help.c:4723 +#: sql_help.c:5172 msgid "define a new operator" msgstr "definiera en ny operator" -#: sql_help.c:4728 +#: sql_help.c:5178 msgid "define a new operator class" msgstr "definiera en ny operatorklass" -#: sql_help.c:4733 +#: sql_help.c:5184 msgid "define a new operator family" msgstr "definiera en ny operatorfamilj" -#: sql_help.c:4738 +#: sql_help.c:5190 msgid "define a new row level security policy for a table" msgstr "definiera en ny säkerhetspolicy på radnivå för en tabell" -#: sql_help.c:4743 +#: sql_help.c:5196 +msgid "define a new procedure" +msgstr "definiera ett ny procedur" + +#: sql_help.c:5202 msgid "define a new publication" msgstr "definiera en ny publicering" -#: sql_help.c:4753 +#: sql_help.c:5214 msgid "define a new rewrite rule" msgstr "definiera en ny omskrivningsregel" -#: sql_help.c:4758 +#: sql_help.c:5220 msgid "define a new schema" msgstr "definiera ett nytt schema" -#: sql_help.c:4763 +#: sql_help.c:5226 msgid "define a new sequence generator" msgstr "definiera en ny sekvensgenerator" -#: sql_help.c:4768 +#: sql_help.c:5232 msgid "define a new foreign server" msgstr "definiera en ny främmande server" -#: sql_help.c:4773 +#: sql_help.c:5238 msgid "define extended statistics" msgstr "definiera utökad statistik" -#: sql_help.c:4778 +#: sql_help.c:5244 msgid "define a new subscription" msgstr "definiera en ny prenumeration" -#: sql_help.c:4783 +#: sql_help.c:5250 msgid "define a new table" msgstr "definiera en ny tabell" -#: sql_help.c:4788 sql_help.c:5208 +#: sql_help.c:5256 sql_help.c:5772 msgid "define a new table from the results of a query" msgstr "definiera en ny tabell utifrån resultatet av en fråga" -#: sql_help.c:4793 +#: sql_help.c:5262 msgid "define a new tablespace" msgstr "definiera ett nytt tabellutrymme" -#: sql_help.c:4798 +#: sql_help.c:5268 msgid "define a new text search configuration" msgstr "definiera en ny textsökkonfiguration" -#: sql_help.c:4803 +#: sql_help.c:5274 msgid "define a new text search dictionary" msgstr "definiera en ny textsökordlista" -#: sql_help.c:4808 +#: sql_help.c:5280 msgid "define a new text search parser" msgstr "definiera en ny textsökparser" -#: sql_help.c:4813 +#: sql_help.c:5286 msgid "define a new text search template" msgstr "definiera en ny textsökmall" -#: sql_help.c:4818 +#: sql_help.c:5292 msgid "define a new transform" msgstr "definiera en ny transform" -#: sql_help.c:4823 +#: sql_help.c:5298 msgid "define a new trigger" msgstr "definiera en ny utlösare" -#: sql_help.c:4828 +#: sql_help.c:5304 msgid "define a new data type" msgstr "definiera en ny datatyp" -#: sql_help.c:4838 +#: sql_help.c:5316 msgid "define a new mapping of a user to a foreign server" msgstr "definiera en ny mappning av en användare till en främmande server" -#: sql_help.c:4843 +#: sql_help.c:5322 msgid "define a new view" msgstr "definiera en ny vy" -#: sql_help.c:4848 +#: sql_help.c:5328 msgid "deallocate a prepared statement" msgstr "deallokera en förberedd sats" -#: sql_help.c:4853 +#: sql_help.c:5334 msgid "define a cursor" msgstr "definiera en markör" -#: sql_help.c:4858 +#: sql_help.c:5340 msgid "delete rows of a table" msgstr "radera rader i en tabell" -#: sql_help.c:4863 +#: sql_help.c:5346 msgid "discard session state" msgstr "släng sessionstillstånd" -#: sql_help.c:4868 +#: sql_help.c:5352 msgid "execute an anonymous code block" msgstr "kör ett annonymt kodblock" -#: sql_help.c:4873 +#: sql_help.c:5358 msgid "remove an access method" msgstr "ta bort en accessmetod" -#: sql_help.c:4878 +#: sql_help.c:5364 msgid "remove an aggregate function" msgstr "ta bort en aggregatfunktioner" -#: sql_help.c:4883 +#: sql_help.c:5370 msgid "remove a cast" msgstr "ta bort en typomvandling" -#: sql_help.c:4888 +#: sql_help.c:5376 msgid "remove a collation" -msgstr "ta bort en sortering" +msgstr "ta bort en jämförelse" -#: sql_help.c:4893 +#: sql_help.c:5382 msgid "remove a conversion" msgstr "ta bort en konvertering" -#: sql_help.c:4898 +#: sql_help.c:5388 msgid "remove a database" msgstr "ta bort en databas" -#: sql_help.c:4903 +#: sql_help.c:5394 msgid "remove a domain" msgstr "ta bort en domän" -#: sql_help.c:4908 +#: sql_help.c:5400 msgid "remove an event trigger" msgstr "ta bort en händelseutlösare" -#: sql_help.c:4913 +#: sql_help.c:5406 msgid "remove an extension" msgstr "ta bort en utökning" -#: sql_help.c:4918 +#: sql_help.c:5412 msgid "remove a foreign-data wrapper" msgstr "ta bort en frammande data-omvandlare" -#: sql_help.c:4923 +#: sql_help.c:5418 msgid "remove a foreign table" msgstr "ta bort en främmande tabell" -#: sql_help.c:4928 +#: sql_help.c:5424 msgid "remove a function" msgstr "ta bort en funktion" -#: sql_help.c:4933 sql_help.c:4983 sql_help.c:5063 +#: sql_help.c:5430 sql_help.c:5496 sql_help.c:5598 msgid "remove a database role" msgstr "ta bort en databasroll" -#: sql_help.c:4938 +#: sql_help.c:5436 msgid "remove an index" msgstr "ta bort ett index" -#: sql_help.c:4943 +#: sql_help.c:5442 msgid "remove a procedural language" msgstr "ta bort ett procedur-språk" -#: sql_help.c:4948 +#: sql_help.c:5448 msgid "remove a materialized view" msgstr "ta bort en materialiserad vy" -#: sql_help.c:4953 +#: sql_help.c:5454 msgid "remove an operator" msgstr "ta bort en operator" -#: sql_help.c:4958 +#: sql_help.c:5460 msgid "remove an operator class" msgstr "ta bort en operatorklass" -#: sql_help.c:4963 +#: sql_help.c:5466 msgid "remove an operator family" msgstr "ta bort en operatorfamilj" -#: sql_help.c:4968 +#: sql_help.c:5472 msgid "remove database objects owned by a database role" msgstr "ta bort databasobjekt som ägs av databasroll" -#: sql_help.c:4973 +#: sql_help.c:5478 msgid "remove a row level security policy from a table" msgstr "ta bort en säkerhetspolicy på radnivå från en tabell" -#: sql_help.c:4978 +#: sql_help.c:5484 +msgid "remove a procedure" +msgstr "ta bort en procedur" + +#: sql_help.c:5490 msgid "remove a publication" msgstr "ta bort en publicering" -#: sql_help.c:4988 +#: sql_help.c:5502 +msgid "remove a routine" +msgstr "ta bort en rutin" + +#: sql_help.c:5508 msgid "remove a rewrite rule" msgstr "ta bort en omskrivningsregel" -#: sql_help.c:4993 +#: sql_help.c:5514 msgid "remove a schema" msgstr "ta bort ett schema" -#: sql_help.c:4998 +#: sql_help.c:5520 msgid "remove a sequence" msgstr "ta bort en sekvens" -#: sql_help.c:5003 +#: sql_help.c:5526 msgid "remove a foreign server descriptor" msgstr "ta bort en främmande server-deskriptor" -#: sql_help.c:5008 +#: sql_help.c:5532 msgid "remove extended statistics" msgstr "ta bort utökad statistik" -#: sql_help.c:5013 +#: sql_help.c:5538 msgid "remove a subscription" msgstr "ta bort en prenumeration" -#: sql_help.c:5018 +#: sql_help.c:5544 msgid "remove a table" msgstr "ta bort en tabell" -#: sql_help.c:5023 +#: sql_help.c:5550 msgid "remove a tablespace" msgstr "ta bort ett tabellutrymme" -#: sql_help.c:5028 +#: sql_help.c:5556 msgid "remove a text search configuration" msgstr "ta bort en textsökkonfiguration" -#: sql_help.c:5033 +#: sql_help.c:5562 msgid "remove a text search dictionary" msgstr "ta bort en textsökordlista" -#: sql_help.c:5038 +#: sql_help.c:5568 msgid "remove a text search parser" msgstr "ta bort en textsökparser" -#: sql_help.c:5043 +#: sql_help.c:5574 msgid "remove a text search template" msgstr "ta bort en textsökmall" -#: sql_help.c:5048 +#: sql_help.c:5580 msgid "remove a transform" msgstr "ta bort en transform" -#: sql_help.c:5053 +#: sql_help.c:5586 msgid "remove a trigger" msgstr "ta bort en utlösare" -#: sql_help.c:5058 +#: sql_help.c:5592 msgid "remove a data type" msgstr "ta bort en datatyp" -#: sql_help.c:5068 +#: sql_help.c:5604 msgid "remove a user mapping for a foreign server" msgstr "ta bort en användarmappning för en främmande server" -#: sql_help.c:5073 +#: sql_help.c:5610 msgid "remove a view" msgstr "ta bort en vy" -#: sql_help.c:5083 +#: sql_help.c:5622 msgid "execute a prepared statement" msgstr "utför en förberedd sats" -#: sql_help.c:5088 +#: sql_help.c:5628 msgid "show the execution plan of a statement" msgstr "visa körningsplanen för en sats" -#: sql_help.c:5093 +#: sql_help.c:5634 msgid "retrieve rows from a query using a cursor" msgstr "hämta rader från en fråga med hjälp av en markör" -#: sql_help.c:5098 +#: sql_help.c:5640 msgid "define access privileges" msgstr "definera åtkomsträttigheter" -#: sql_help.c:5103 +#: sql_help.c:5646 msgid "import table definitions from a foreign server" msgstr "importera tabelldefinitioner från en främmande server" -#: sql_help.c:5108 +#: sql_help.c:5652 msgid "create new rows in a table" msgstr "skapa nya rader i en tabell" -#: sql_help.c:5113 +#: sql_help.c:5658 msgid "listen for a notification" msgstr "lyssna efter notifiering" -#: sql_help.c:5118 +#: sql_help.c:5664 msgid "load a shared library file" msgstr "ladda en delad biblioteksfil (shared library)" -#: sql_help.c:5123 +#: sql_help.c:5670 msgid "lock a table" msgstr "lås en tabell" -#: sql_help.c:5128 +#: sql_help.c:5676 msgid "position a cursor" msgstr "flytta en markör" -#: sql_help.c:5133 +#: sql_help.c:5682 msgid "generate a notification" msgstr "generera en notifiering" -#: sql_help.c:5138 +#: sql_help.c:5688 msgid "prepare a statement for execution" msgstr "förbered en sats för körning" -#: sql_help.c:5143 +#: sql_help.c:5694 msgid "prepare the current transaction for two-phase commit" msgstr "avbryt aktuell transaktion för två-fas-commit" -#: sql_help.c:5148 +#: sql_help.c:5700 msgid "change the ownership of database objects owned by a database role" msgstr "byt ägare på databasobjekt som ägs av en databasroll" -#: sql_help.c:5153 +#: sql_help.c:5706 msgid "replace the contents of a materialized view" msgstr "ersätt innehållet av en materialiserad vy" -#: sql_help.c:5158 +#: sql_help.c:5712 msgid "rebuild indexes" msgstr "återskapa index" -#: sql_help.c:5163 +#: sql_help.c:5718 msgid "destroy a previously defined savepoint" msgstr "ta bort en tidigare definierad sparpunkt" -#: sql_help.c:5168 +#: sql_help.c:5724 msgid "restore the value of a run-time parameter to the default value" msgstr "återställ värde av körningsparameter till standardvärdet" -#: sql_help.c:5173 +#: sql_help.c:5730 msgid "remove access privileges" msgstr "ta bort åtkomsträttigheter" -#: sql_help.c:5183 +#: sql_help.c:5742 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "avbryt en transaktion som tidigare förberetts för två-fas-commit" -#: sql_help.c:5188 +#: sql_help.c:5748 msgid "roll back to a savepoint" msgstr "rulla tillbaka till sparpunkt" -#: sql_help.c:5193 +#: sql_help.c:5754 msgid "define a new savepoint within the current transaction" msgstr "definera en ny sparpunkt i den aktuella transaktionen" -#: sql_help.c:5198 +#: sql_help.c:5760 msgid "define or change a security label applied to an object" msgstr "definiera eller ändra en säkerhetsetikett på ett objekt" -#: sql_help.c:5203 sql_help.c:5248 sql_help.c:5278 +#: sql_help.c:5766 sql_help.c:5820 sql_help.c:5856 msgid "retrieve rows from a table or view" msgstr "hämta rader från en tabell eller vy" -#: sql_help.c:5213 +#: sql_help.c:5778 msgid "change a run-time parameter" -msgstr "ändra en körningsparamter" +msgstr "ändra en körningsparameter" -#: sql_help.c:5218 +#: sql_help.c:5784 msgid "set constraint check timing for the current transaction" msgstr "sätt integritetsvillkorstiming för nuvarande transaktion" -#: sql_help.c:5223 +#: sql_help.c:5790 msgid "set the current user identifier of the current session" msgstr "sätt användare för den aktiva sessionen" -#: sql_help.c:5228 +#: sql_help.c:5796 msgid "set the session user identifier and the current user identifier of the current session" msgstr "sätt sessionsanvändaridentifierare och nuvarande användaridentifierare för den aktiva sessionen" -#: sql_help.c:5233 +#: sql_help.c:5802 msgid "set the characteristics of the current transaction" msgstr "sätt inställningar för nuvarande transaktionen" -#: sql_help.c:5238 +#: sql_help.c:5808 msgid "show the value of a run-time parameter" msgstr "visa värde på en körningsparameter" -#: sql_help.c:5253 +#: sql_help.c:5826 msgid "empty a table or set of tables" msgstr "töm en eller flera tabeller" -#: sql_help.c:5258 +#: sql_help.c:5832 msgid "stop listening for a notification" msgstr "sluta att lyssna efter notifiering" -#: sql_help.c:5263 +#: sql_help.c:5838 msgid "update rows of a table" msgstr "uppdatera rader i en tabell" -#: sql_help.c:5268 +#: sql_help.c:5844 msgid "garbage-collect and optionally analyze a database" msgstr "skräpsamla och eventuellt analysera en databas" -#: sql_help.c:5273 +#: sql_help.c:5850 msgid "compute a set of rows" msgstr "beräkna en mängd rader" -#: startup.c:184 +#: startup.c:215 #, c-format -msgid "%s: -1 can only be used in non-interactive mode\n" -msgstr "%s: -1 kan bara användas i icke-interaktivt läge\n" +msgid "-1 can only be used in non-interactive mode" +msgstr "-1 kan bara användas i icke-interaktivt läge" -#: startup.c:287 +#: startup.c:302 #, c-format -msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%s: kunde inte öppna logg-fil \"%s\": %s\n" +msgid "could not connect to server: %s" +msgstr "kunde inte ansluta till server: %s" -#: startup.c:394 +#: startup.c:330 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "kunde inte öppna loggfil \"%s\": %m" + +#: startup.c:441 #, c-format msgid "" "Type \"help\" for help.\n" @@ -5594,1857 +6170,117 @@ msgstr "" "Skriv \"help\" för hjälp.\n" "\n" -#: startup.c:543 +#: startup.c:591 #, c-format -msgid "%s: could not set printing parameter \"%s\"\n" -msgstr "%s: kunde inte sätta utskriftsparameter \"%s\"\n" +msgid "could not set printing parameter \"%s\"" +msgstr "kunde inte sätta utskriftsparameter \"%s\"" -#: startup.c:645 +#: startup.c:696 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: startup.c:662 +#: startup.c:713 #, c-format -msgid "%s: warning: extra command-line argument \"%s\" ignored\n" -msgstr "%s: varning: extra kommandoradsargument \"%s\" ignorerad\n" +msgid "extra command-line argument \"%s\" ignored" +msgstr "extra kommandoradsargument \"%s\" ignorerad" -#: startup.c:711 +#: startup.c:762 #, c-format -msgid "%s: could not find own program executable\n" -msgstr "%s: kunde inte hitta det egna programmets körbara fil\n" +msgid "could not find own program executable" +msgstr "kunde inte hitta det egna programmets körbara fil" -#: tab-complete.c:4184 +#: tab-complete.c:4361 #, c-format msgid "" "tab completion query failed: %s\n" "Query was:\n" -"%s\n" +"%s" msgstr "" "tab-kompletteringsfråga misslyckades: %s\n" "Frågan var:\n" -"%s\n" +"%s" -#: variables.c:139 +#: variables.c:141 #, c-format -msgid "unrecognized value \"%s\" for \"%s\": boolean expected\n" -msgstr "okänt värde \"%s\" för \"%s\": förväntade sig en boolean\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "okänt värde \"%s\" för \"%s\": förväntade sig en Boolean" -#: variables.c:176 +#: variables.c:178 #, c-format -msgid "invalid value \"%s\" for \"%s\": integer expected\n" -msgstr "ogiltigt värde \"%s\" för \"%s\": förväntade sig ett heltal\n" +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "ogiltigt värde \"%s\" för \"%s\": förväntade sig ett heltal" -#: variables.c:224 +#: variables.c:226 #, c-format -msgid "invalid variable name: \"%s\"\n" -msgstr "ogiltigt variabelnamn: \"%s\"\n" +msgid "invalid variable name: \"%s\"" +msgstr "ogiltigt variabelnamn: \"%s\"" -#: variables.c:393 +#: variables.c:395 #, c-format msgid "" "unrecognized value \"%s\" for \"%s\"\n" -"Available values are: %s.\n" +"Available values are: %s." msgstr "" "okänt värde \"%s\" för \"%s\"\n" -"Tillgängliga värden är: %s.\n" - -#~ msgid "" -#~ "WARNING: You are connected to a server with major version %d.%d,\n" -#~ "but your %s client is major version %d.%d. Some backslash commands,\n" -#~ "such as \\d, might not work properly.\n" -#~ "\n" -#~ msgstr "" -#~ "VARNING: Du är uppkopplad mot en server med version %d.%d,\n" -#~ "men din klient %s är version %d.%d. En del snedstreckkommandon\n" -#~ "så som \\d kommer eventuellt inte att fungera som de skall.\n" -#~ "\n" - -#~ msgid "" -#~ "VALUES ( expression [, ...] ) [, ...]\n" -#~ " [ ORDER BY sort_expression [ ASC | DESC | USING operator ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]" -#~ msgstr "" -#~ "VALUES ( uttryck [, ...] ) [, ...]\n" -#~ " [ ORDER BY sorteringsuttryck [ ASC | DESC | USING operator ] [, ...] ]\n" -#~ " [ LIMIT { antal | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ antal ] { ROW | ROWS } ONLY ]" - -#~ msgid "" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]\n" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]" -#~ msgstr "" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ tabell ]\n" -#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ tabell [ (kolumn [, ...] ) ] ]" - -#~ msgid "" -#~ "UPDATE [ ONLY ] table [ [ AS ] alias ]\n" -#~ " SET { column = { expression | DEFAULT } |\n" -#~ " ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]\n" -#~ " [ FROM fromlist ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "UPDATE [ ONLY ] tabell [ [ AS ] alias ]\n" -#~ " SET { kolumn = { uttryck | DEFAULT } |\n" -#~ " ( kolumn [, ...] ) = ( { uttryck | DEFAULT } [, ...] ) } [, ...]\n" -#~ " [ FROM frånlista ]\n" -#~ " [ WHERE villkor | WHERE CURRENT OF markörnamn ]\n" -#~ " [ RETURNING * | utdatauttryck [ [ AS ] utdatanamn ] [, ...] ]" - -#~ msgid "UNLISTEN { name | * }" -#~ msgstr "UNLISTEN { namn | * }" - -#~ msgid "" -#~ "TRUNCATE [ TABLE ] [ ONLY ] name [, ... ]\n" -#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "TRUNCATE [ TABLE ] [ ONLY ] namn [, ... ]\n" -#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" - -#~ msgid "" -#~ "START TRANSACTION [ transaction_mode [, ...] ]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "START TRANSACTION [ transaktionsläge [, ...] ]\n" -#~ "\n" -#~ "där transaktionsläge är en av:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "" -#~ "SHOW name\n" -#~ "SHOW ALL" -#~ msgstr "" -#~ "SHOW namn\n" -#~ "SHOW ALL" - -#~ msgid "" -#~ "SET TRANSACTION transaction_mode [, ...]\n" -#~ "SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "SET TRANSACTION transaktionsläge [, ...]\n" -#~ "SET SESSION CHARACTERISTICS AS TRANSACTION transaktionsläge [, ...]\n" -#~ "\n" -#~ "där transaktionsläge är en av:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION username\n" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" -#~ "RESET SESSION AUTHORIZATION" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION användarnamn\n" -#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" -#~ "RESET SESSION AUTHORIZATION" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] ROLE rolename\n" -#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" -#~ "RESET ROLE" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] ROLE rollnamn\n" -#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" -#~ "RESET ROLE" - -#~ msgid "SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }" -#~ msgstr "SET CONSTRAINTS { ALL | namn [, ...] } { DEFERRED | IMMEDIATE }" - -#~ msgid "" -#~ "SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }\n" -#~ "SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }" -#~ msgstr "" -#~ "SET [ SESSION | LOCAL ] konfigurationsparameter { TO | = } { värde | 'värde' | DEFAULT }\n" -#~ "SET [ SESSION | LOCAL ] TIME ZONE { tidszon | LOCAL | DEFAULT }" - -#, fuzzy -#~ msgid "" -#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] output_name ] [, ...]\n" -#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table\n" -#~ " [ FROM from_item [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]" -#~ msgstr "" -#~ "SELECT [ ALL | DISTINCT [ ON ( uttryck [, ...] ) ] ]\n" -#~ " * | uttryck [ AS utnamn ] [, ...]\n" -#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] ny_tabell\n" -#~ " [ FROM frånval [, ...] ]\n" -#~ " [ WHERE villkor ]\n" -#~ " [ GROUP BY uttryck [, ...] ]\n" -#~ " [ HAVING villkor [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY uttryck [ ASC | DESC | USING operator ] [, ...] ]\n" -#~ " [ LIMIT { antal | ALL } ]\n" -#~ " [ OFFSET start ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF tabellnamn [, ...] ] [ NOWAIT ] [...] ]" - -#, fuzzy -#~ msgid "" -#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" -#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" -#~ " * | expression [ [ AS ] output_name ] [, ...]\n" -#~ " [ FROM from_item [, ...] ]\n" -#~ " [ WHERE condition ]\n" -#~ " [ GROUP BY expression [, ...] ]\n" -#~ " [ HAVING condition [, ...] ]\n" -#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" -#~ " [ LIMIT { count | ALL } ]\n" -#~ " [ OFFSET start [ ROW | ROWS ] ]\n" -#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]\n" -#~ "\n" -#~ "where from_item can be one of:\n" -#~ "\n" -#~ " [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" -#~ " ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]\n" -#~ " with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" -#~ " function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]\n" -#~ " function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )\n" -#~ " from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]\n" -#~ "\n" -#~ "and with_query is:\n" -#~ "\n" -#~ " with_query_name [ ( column_name [, ...] ) ] AS ( select )\n" -#~ "\n" -#~ "TABLE { [ ONLY ] table_name [ * ] | with_query_name }" -#~ msgstr "" -#~ "SELECT [ ALL | DISTINCT [ ON ( uttryck [, ...] ) ] ]\n" -#~ " * | uttryck [ AS utnamn ] [, ...]\n" -#~ " [ FROM frånval [, ...] ]\n" -#~ " [ WHERE villkor ]\n" -#~ " [ GROUP BY uttryck [, ...] ]\n" -#~ " [ HAVING villkor [, ...] ]\n" -#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" -#~ " [ ORDER BY uttryck [ ASC | DESC | USING operator ] [, ...] ]\n" -#~ " [ LIMIT { antal | ALL } ]\n" -#~ " [ OFFSET start ]\n" -#~ " [ FOR { UPDATE | SHARE } [ OF tabellnamn [, ...] ] [ NOWAIT ] [...] ]\n" -#~ "\n" -#~ "där frånval kan vara en av:\n" -#~ "\n" -#~ " [ ONLY ] tabellnamn [ * ] [ [ AS ] alias [ ( kolumnalias [, ...] ) ] ]\n" -#~ " ( select ) [ AS ] alias [ ( kolumnalias [, ...] ) ]\n" -#~ " funktionsnamn ( [ argument [, ...] ] ) [ AS ] alias [ ( kolumnalias [, ...] | kolumndefinition [, ...] ) ]\n" -#~ " funktionsnamn ( [ argument [, ...] ] ) AS ( kolumndefinition [, ...] )\n" -#~ " frånval [ NATURAL ] join-typ frånval [ ON join-villkor | USING ( join-kolumn [, ...] ) ]" - -#~ msgid "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name" -#~ msgstr "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] sparpunktsnamn" - -#~ msgid "ROLLBACK PREPARED transaction_id" -#~ msgstr "ROLLBACK PREPARED transaktions_id" - -#~ msgid "ROLLBACK [ WORK | TRANSACTION ]" -#~ msgstr "ROLLBACK [ WORK | TRANSACTION ]" - -#, fuzzy -#~ msgid "" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sequencename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER servername [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE langname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemaname [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tablespacename [, ...]\n" -#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ ADMIN OPTION FOR ]\n" -#~ " role [, ...] FROM rolename [, ...]\n" -#~ " [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tabellnamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sekvensnamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbnamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funknamn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] ) [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE språknamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemanamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ GRANT OPTION FOR ]\n" -#~ " { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tabellutrymmesnamn [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]\n" -#~ "\n" -#~ "REVOKE [ ADMIN OPTION FOR ]\n" -#~ " rolk [, ...]\n" -#~ " FROM { användarnamn | GROUP gruppnamn | PUBLIC } [, ...]\n" -#~ " [ CASCADE | RESTRICT ]" - -#~ msgid "RELEASE [ SAVEPOINT ] savepoint_name" -#~ msgstr "RELEASE [ SAVEPOINT ] sparpunktsnamn" - -#~ msgid "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]" -#~ msgstr "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } namn [ FORCE ]" - -#~ msgid "REASSIGN OWNED BY old_role [, ...] TO new_role" -#~ msgstr "REASSIGN OWNED BY gammal_roll [, ...] TO ny_roll" - -#~ msgid "PREPARE TRANSACTION transaction_id" -#~ msgstr "PREPARE TRANSACTION transaktions_id" - -#~ msgid "PREPARE name [ ( datatype [, ...] ) ] AS statement" -#~ msgstr "PREPARE namn [ ( datatyp [, ...] ) ] AS sats" - -#~ msgid "NOTIFY name" -#~ msgstr "NOTIFY namn" - -#~ msgid "MOVE [ direction { FROM | IN } ] cursorname" -#~ msgstr "MOVE [ riktning { FROM | IN } ] markörnamn" - -#~ msgid "" -#~ "LOCK [ TABLE ] [ ONLY ] name [, ...] [ IN lockmode MODE ] [ NOWAIT ]\n" -#~ "\n" -#~ "where lockmode is one of:\n" -#~ "\n" -#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" -#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" -#~ msgstr "" -#~ "LOCK [ TABLE ] [ ONLY ] namn [, ...] [ IN låsläge MODE ] [ NOWAIT ]\n" -#~ "\n" -#~ "där låsläge är en av:\n" -#~ "\n" -#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" -#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" - -#~ msgid "LOAD 'filename'" -#~ msgstr "LOAD 'filnamn'" - -#~ msgid "LISTEN name" -#~ msgstr "LISTEN namn" - -#~ msgid "" -#~ "INSERT INTO table [ ( column [, ...] ) ]\n" -#~ " { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "INSERT INTO tabell [ ( kolumn [, ...] ) ]\n" -#~ " { DEFAULT VALUES | VALUES ( { uttryck | DEFAULT } [, ...] ) [, ...] | fråga }\n" -#~ " [ RETURNING * | utdatauttryck [ [ AS ] utdatanamn ] [, ...] ]" - -#, fuzzy -#~ msgid "" -#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" -#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" -#~ " ON [ TABLE ] tablename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sequencename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON FOREIGN SERVER servername [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE langname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemaname [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tablespacename [, ...]\n" -#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT role [, ...] TO rolename [, ...] [ WITH ADMIN OPTION ]" -#~ msgstr "" -#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON [ TABLE ] tabellnamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { USAGE | SELECT | UPDATE }\n" -#~ " [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SEQUENCE sekvensnamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON DATABASE dbnamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" -#~ " ON FUNCTION funkname ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] ) [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" -#~ " ON LANGUAGE språknamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" -#~ " ON SCHEMA schemanamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" -#~ " ON TABLESPACE tabellutrymmesnamn [, ...]\n" -#~ " TO { användarnamn | GROUP gruppnamn | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" -#~ "\n" -#~ "GRANT roll [, ...] TO användarnamn [, ...] [ WITH ADMIN OPTION ]" - -#~ msgid "" -#~ "FETCH [ direction { FROM | IN } ] cursorname\n" -#~ "\n" -#~ "where direction can be empty or one of:\n" -#~ "\n" -#~ " NEXT\n" -#~ " PRIOR\n" -#~ " FIRST\n" -#~ " LAST\n" -#~ " ABSOLUTE count\n" -#~ " RELATIVE count\n" -#~ " count\n" -#~ " ALL\n" -#~ " FORWARD\n" -#~ " FORWARD count\n" -#~ " FORWARD ALL\n" -#~ " BACKWARD\n" -#~ " BACKWARD count\n" -#~ " BACKWARD ALL" -#~ msgstr "" -#~ "FETCH [ riktning { FROM | IN } ] markörsnamn\n" -#~ "\n" -#~ "där riktning kan vara tom eller en av:\n" -#~ "\n" -#~ " NEXT\n" -#~ " PRIOR\n" -#~ " FIRST\n" -#~ " LAST\n" -#~ " ABSOLUTE antal\n" -#~ " RELATIVE antal\n" -#~ " antal\n" -#~ " ALL\n" -#~ " FORWARD\n" -#~ " FORWARD antal\n" -#~ " FORWARD ALL\n" -#~ " BACKWARD\n" -#~ " BACKWARD antal\n" -#~ " BACKWARD ALL" - -#~ msgid "EXPLAIN [ ANALYZE ] [ VERBOSE ] statement" -#~ msgstr "EXPLAIN [ ANALYZE ] [ VERBOSE ] sats" - -#~ msgid "EXECUTE name [ ( parameter [, ...] ) ]" -#~ msgstr "EXECUTE namn [ ( parameter [, ...] ) ]" - -#~ msgid "END [ WORK | TRANSACTION ]" -#~ msgstr "END [ WORK | TRANSACTION ]" - -#~ msgid "DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP VIEW [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP USER [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP USER [ IF EXISTS ] namn [, ...]" - -#~ msgid "DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TYPE [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TRIGGER [ IF EXISTS ] name ON table [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TRIGGER [ IF EXISTS ] namn ON tabell [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH PARSER [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP TABLESPACE [ IF EXISTS ] tablespacename" -#~ msgstr "DROP TABLESPACE [ IF EXISTS ] tabellutrymmesnamn" - -#~ msgid "DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP TABLE [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#, fuzzy -#~ msgid "DROP SERVER [ IF EXISTS ] servername [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CONVERSION [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP SEQUENCE [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP SCHEMA [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP RULE [ IF EXISTS ] name ON relation [ CASCADE | RESTRICT ]" -#~ msgstr "DROP RULE [ IF EXISTS ] namn ON relation [ CASCADE | RESTRICT ]" - -#~ msgid "DROP ROLE [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP ROLE [ IF EXISTS ] namn [, ...]" - -#~ msgid "DROP OWNED BY name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP OWNED BY namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" -#~ msgstr "DROP OPERATOR FAMILY [ IF EXISTS ] namn USING indexmetod [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" -#~ msgstr "DROP OPERATOR CLASS [ IF EXISTS ] namn USING indexmetod [ CASCADE | RESTRICT ]" - -#~ msgid "DROP OPERATOR [ IF EXISTS ] name ( { lefttype | NONE } , { righttype | NONE } ) [ CASCADE | RESTRICT ]" -#~ msgstr "DROP OPERATOR [ IF EXISTS ] namn ( { vänster_typ | NONE } , { höger_typ | NONE } ) [ CASCADE | RESTRICT ]" - -#~ msgid "DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP INDEX [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP INDEX [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP GROUP [ IF EXISTS ] name [, ...]" -#~ msgstr "DROP GROUP [ IF EXISTS ] namn [, ...]" - -#~ msgid "" -#~ "DROP FUNCTION [ IF EXISTS ] name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " [ CASCADE | RESTRICT ]" -#~ msgstr "" -#~ "DROP FUNCTION [ IF EXISTS ] namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " [ CASCADE | RESTRICT ]" - -#, fuzzy -#~ msgid "DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CONVERSION [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" -#~ msgstr "DROP DOMAIN [ IF EXISTS ] namn [, ...] [ CASCADE | RESTRICT ]" - -#~ msgid "DROP DATABASE [ IF EXISTS ] name" -#~ msgstr "DROP DATABASE [ IF EXISTS ] namn" - -#~ msgid "DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CONVERSION [ IF EXISTS ] namn [ CASCADE | RESTRICT ]" - -#~ msgid "DROP CAST [ IF EXISTS ] (sourcetype AS targettype) [ CASCADE | RESTRICT ]" -#~ msgstr "DROP CAST [ IF EXISTS ] (källtyp AS måltyp) [ CASCADE | RESTRICT ]" - -#~ msgid "DROP AGGREGATE [ IF EXISTS ] name ( type [ , ... ] ) [ CASCADE | RESTRICT ]" -#~ msgstr "DROP AGGREGATE [ IF EXISTS ] namn ( typ [ , ... ] ) [ CASCADE | RESTRICT ]" - -#~ msgid "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" -#~ msgstr "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" - -#~ msgid "" -#~ "DELETE FROM [ ONLY ] table [ [ AS ] alias ]\n" -#~ " [ USING usinglist ]\n" -#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" -#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" -#~ msgstr "" -#~ "DELETE FROM [ ONLY ] tabell [ [ AS ] alias ]\n" -#~ " [ USING using-lista ]\n" -#~ " [ WHERE villkor | WHERE CURRENT OF märkörnamn ]\n" -#~ " [ RETURNING * | utdatauttryck [ [ AS ] utdatanamn ] [, ...] ]" - -#~ msgid "" -#~ "DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" -#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR query" -#~ msgstr "" -#~ "DECLARE namn [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" -#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR fråga" - -#~ msgid "DEALLOCATE [ PREPARE ] { name | ALL }" -#~ msgstr "DEALLOCATE [ PREPARE ] { namn | ALL }" - -#~ msgid "" -#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]\n" -#~ " AS query" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW namn [ ( kolumnnamn [, ...] ) ]\n" -#~ " AS fråga" - -#~ msgid "" -#~ "CREATE USER name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE USER namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT anslutningstak\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'lösenord'\n" -#~ " | VALID UNTIL 'tidsstämpel' \n" -#~ " | IN ROLE rollnamn [, ...]\n" -#~ " | IN GROUP rollnamn [, ...]\n" -#~ " | ROLE rollnamn [, ...]\n" -#~ " | ADMIN rollnamn [, ...]\n" -#~ " | USER rollnamn [, ...]\n" -#~ " | SYSID uid" - -#, fuzzy -#~ msgid "" -#~ "CREATE TYPE name AS\n" -#~ " ( attribute_name data_type [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE name AS ENUM\n" -#~ " ( 'label' [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE name (\n" -#~ " INPUT = input_function,\n" -#~ " OUTPUT = output_function\n" -#~ " [ , RECEIVE = receive_function ]\n" -#~ " [ , SEND = send_function ]\n" -#~ " [ , TYPMOD_IN = type_modifier_input_function ]\n" -#~ " [ , TYPMOD_OUT = type_modifier_output_function ]\n" -#~ " [ , ANALYZE = analyze_function ]\n" -#~ " [ , INTERNALLENGTH = { internallength | VARIABLE } ]\n" -#~ " [ , PASSEDBYVALUE ]\n" -#~ " [ , ALIGNMENT = alignment ]\n" -#~ " [ , STORAGE = storage ]\n" -#~ " [ , LIKE = like_type ]\n" -#~ " [ , CATEGORY = category ]\n" -#~ " [ , PREFERRED = preferred ]\n" -#~ " [ , DEFAULT = default ]\n" -#~ " [ , ELEMENT = element ]\n" -#~ " [ , DELIMITER = delimiter ]\n" -#~ ")\n" -#~ "\n" -#~ "CREATE TYPE name" -#~ msgstr "" -#~ "CREATE TYPE namn AS\n" -#~ " ( attributnamn datatyp [, ... ] )\n" -#~ "\n" -#~ "CREATE TYPE namn (\n" -#~ " INPUT = inmatningsfunktion,\n" -#~ " OUTPUT = utmatningsfunktion\n" -#~ " [ , RECEIVE = mottagarfunktion ]\n" -#~ " [ , SEND = sändfunktion ]\n" -#~ " [ , ANALYZE = analysfunktion ]\n" -#~ " [ , INTERNALLENGTH = { internlängd | VARIABLE } ]\n" -#~ " [ , PASSEDBYVALUE ]\n" -#~ " [ , ALIGNMENT = justering ]\n" -#~ " [ , STORAGE = lagring ]\n" -#~ " [ , DEFAULT = standard ]\n" -#~ " [ , ELEMENT = element ]\n" -#~ " [ , DELIMITER = avskiljare ]\n" -#~ ")\n" -#~ "\n" -#~ "CREATE TYPE namn" - -#~ msgid "" -#~ "CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }\n" -#~ " ON table [ FOR [ EACH ] { ROW | STATEMENT } ]\n" -#~ " EXECUTE PROCEDURE funcname ( arguments )" -#~ msgstr "" -#~ "CREATE TRIGGER namn { BEFORE | AFTER } { händelse [ OR ... ] }\n" -#~ " ON tabell [ FOR [ EACH ] { ROW | STATEMENT } ]\n" -#~ " EXECUTE PROCEDURE funknamn ( argument )" - -#~ msgid "CREATE TABLESPACE tablespacename [ OWNER username ] LOCATION 'directory'" -#~ msgstr "CREATE TABLESPACE tabellutrymmesnamn [ OWNER användarnamn ] LOCATION 'katalog'" - -#~ msgid "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name\n" -#~ " [ (column_name [, ...] ) ]\n" -#~ " [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " AS query\n" -#~ " [ WITH [ NO ] DATA ]" -#~ msgstr "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE tabellnamn\n" -#~ " [ (kolumnnamn [, ...] ) ]\n" -#~ " [ WITH ( lagringsparameter [= värde] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ " [ TABLESPACE tabellutrymme ]\n" -#~ " AS fråga\n" -#~ " [ WITH [ NO ] DATA ]" - -#, fuzzy -#~ msgid "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name ( [\n" -#~ " { column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]\n" -#~ " | table_constraint\n" -#~ " | LIKE parent_table [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }\n" -#~ " [, ... ]\n" -#~ "] )\n" -#~ "[ INHERITS ( parent_table [, ... ] ) ]\n" -#~ "[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" -#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ "[ TABLESPACE tablespace ]\n" -#~ "\n" -#~ "where column_constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ NOT NULL | \n" -#~ " NULL | \n" -#~ " UNIQUE index_parameters |\n" -#~ " PRIMARY KEY index_parameters |\n" -#~ " CHECK ( expression ) |\n" -#~ " REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" -#~ " [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "and table_constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ UNIQUE ( column_name [, ... ] ) index_parameters |\n" -#~ " PRIMARY KEY ( column_name [, ... ] ) index_parameters |\n" -#~ " CHECK ( expression ) |\n" -#~ " FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]\n" -#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "index_parameters in UNIQUE and PRIMARY KEY constraints are:\n" -#~ "\n" -#~ "[ WITH ( storage_parameter [= value] [, ... ] ) ]\n" -#~ "[ USING INDEX TABLESPACE tablespace ]" -#~ msgstr "" -#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE tabellnamn ( [\n" -#~ " { kolumnname datatyp [ DEFAULT default_uttryck ] [ kolumnvillkor [ ... ] ]\n" -#~ " | tabellvillkor\n" -#~ " | LIKE föräldratabell [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS } ] ... } \n" -#~ " [, ... ]\n" -#~ "] )\n" -#~ "[ INHERITS ( föräldratabell [, ... ] ) ]\n" -#~ "[ WITH ( lagringsparameter [= värde] [, ... ] ) | WITH OIDS | WITHOUT \"\n" -#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" -#~ "[ TABLESPACE tabellutrymme ]\n" -#~ "\n" -#~ "där kolumnvillkor är:\n" -#~ "\n" -#~ "[ CONSTRAINT villkorsnamn ]\n" -#~ "{ NOT NULL |\n" -#~ " NULL |\n" -#~ " UNIQUE index_parameter |\n" -#~ " PRIMARY KEY index_parameter |\n" -#~ " CHECK (uttryck) |\n" -#~ " REFERENCES reftabell [ ( refkolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" -#~ " [ ON DELETE aktion ] [ ON UPDATE aktion ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "och tabellvillkor är:\n" -#~ "\n" -#~ "[ CONSTRAINT villkorsnamn ]\n" -#~ "{ UNIQUE ( kolumnnamn [, ... ] ) index_parameter |\n" -#~ " PRIMARY KEY ( kolumnnamn [, ... ] ) index_parameter |\n" -#~ " CHECK ( uttryck ) |\n" -#~ " FOREIGN KEY ( kolumnnamn [, ... ] ) REFERENCES reftabell [ ( refkolumn [, ... ] ) ]\n" -#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE aktion ] [ ON UPDATE aktion ] }\n" -#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" -#~ "\n" -#~ "index_parameter i UNIQUE och PRIMARY KEY villkoren är:\\n\"\n" -#~ "\n" -#~ "[ WITH ( lagringsparameter [= värde] [, ... ] ) ]\n" -#~ "[ USING INDEX TABLESPACE tabellutrymme ]" - -#~ msgid "" -#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]\n" -#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.column | NONE } ]" -#~ msgstr "" -#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE namn [ INCREMENT [ BY ] ökningsvärde ]\n" -#~ " [ MINVALUE minvärde | NO MINVALUE ] [ MAXVALUE maxvärde | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { tabell.kolumn | NONE } ]" - -#~ msgid "" -#~ "CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]\n" -#~ "CREATE SCHEMA AUTHORIZATION username [ schema_element [ ... ] ]" -#~ msgstr "" -#~ "CREATE SCHEMA schema-namn [ AUTHORIZATION användarnamn ] [ schema-element [ ... ] ]\n" -#~ "CREATE SCHEMA AUTHORIZATION användarnamn [ schema-element [ ... ] ]" - -#~ msgid "" -#~ "CREATE [ OR REPLACE ] RULE name AS ON event\n" -#~ " TO table [ WHERE condition ]\n" -#~ " DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] RULE namn AS ON händelse\n" -#~ " TO tabell [ WHERE villkor ]\n" -#~ " DO [ ALSO | INSTEAD ] { NOTHING | kommando | ( kommando ; kommando ... ) }" - -#~ msgid "" -#~ "CREATE ROLE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE ROLE namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT anslutningstak\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'lösenord'\n" -#~ " | VALID UNTIL 'tidsstämpel' \n" -#~ " | IN ROLE rollnamn [, ...]\n" -#~ " | IN GROUP rollnamn [, ...]\n" -#~ " | ROLE rollnamn [, ...]\n" -#~ " | ADMIN rollnamn [, ...]\n" -#~ " | USER rollnamn [, ...]\n" -#~ " | SYSID uid" - -#~ msgid "CREATE OPERATOR FAMILY name USING index_method" -#~ msgstr "CREATE OPERATOR FAMILY namn USING indexmetod" - -#, fuzzy -#~ msgid "" -#~ "CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type\n" -#~ " USING index_method [ FAMILY family_name ] AS\n" -#~ " { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ]\n" -#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" -#~ " | STORAGE storage_type\n" -#~ " } [, ... ]" -#~ msgstr "" -#~ "CREATE OPERATOR CLASS namn [ DEFAULT ] FOR TYPE datatyp USING indexmetod AS\n" -#~ " { OPERATOR strateginummer operatornamn [ ( op_typ, op_typ ) ] [ RECHECK ]\n" -#~ " | FUNCTION supportnummer funknamn ( argumenttyp [, ...] )\n" -#~ " | STORAGE lagringstyp\n" -#~ " } [, ... ]" - -#~ msgid "" -#~ "CREATE OPERATOR name (\n" -#~ " PROCEDURE = funcname\n" -#~ " [, LEFTARG = lefttype ] [, RIGHTARG = righttype ]\n" -#~ " [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]\n" -#~ " [, RESTRICT = res_proc ] [, JOIN = join_proc ]\n" -#~ " [, HASHES ] [, MERGES ]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE OPERATOR namn (\n" -#~ " PROCEDURE = funknamn\n" -#~ " [, LEFTARG = vänster-typ ] [, RIGHTARG = höger-typ ]\n" -#~ " [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]\n" -#~ " [, RESTRICT = res_proc ] [, JOIN = join_proc ]\n" -#~ " [, HASHES ] [, MERGES ]\n" -#~ ")" - -#~ msgid "" -#~ "CREATE [ PROCEDURAL ] LANGUAGE name\n" -#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\n" -#~ " HANDLER call_handler [ VALIDATOR valfunction ]" -#~ msgstr "" -#~ "CREATE [ PROCEDURAL ] LANGUAGE namn\n" -#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE namn\n" -#~ " HANDLER anropshanterare [ VALIDATOR val-funktion ]" - -#~ msgid "" -#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]\n" -#~ " ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )\n" -#~ " [ WITH ( storage_parameter = value [, ... ] ) ]\n" -#~ " [ TABLESPACE tablespace ]\n" -#~ " [ WHERE predicate ]" -#~ msgstr "" -#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] namn ON tabell [ USING metod ]\n" -#~ " ( { kolumn | ( uttryck ) } [ op-klass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )\n" -#~ " [ WITH ( lagringsparameter = värde [, ... ] ) ]\n" -#~ " [ TABLESPACE tabellutrymme ]\n" -#~ " [ WHERE predikat ]" - -#~ msgid "" -#~ "CREATE GROUP name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ " | IN ROLE rolename [, ...]\n" -#~ " | IN GROUP rolename [, ...]\n" -#~ " | ROLE rolename [, ...]\n" -#~ " | ADMIN rolename [, ...]\n" -#~ " | USER rolename [, ...]\n" -#~ " | SYSID uid" -#~ msgstr "" -#~ "CREATE GROUP namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'lösenord'\n" -#~ " | VALID UNTIL 'tidsstämpel' \n" -#~ " | IN ROLE rollnamn [, ...]\n" -#~ " | IN GROUP rollnamn [, ...]\n" -#~ " | ROLE rollnamn [, ...]\n" -#~ " | ADMIN rollnamn [, ...]\n" -#~ " | USER rollnamn [, ...]\n" -#~ " | SYSID uid" - -#, fuzzy -#~ msgid "" -#~ "CREATE [ OR REPLACE ] FUNCTION\n" -#~ " name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } defexpr ] [, ...] ] )\n" -#~ " [ RETURNS rettype\n" -#~ " | RETURNS TABLE ( colname coltype [, ...] ) ]\n" -#~ " { LANGUAGE langname\n" -#~ " | WINDOW\n" -#~ " | IMMUTABLE | STABLE | VOLATILE\n" -#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " | COST execution_cost\n" -#~ " | ROWS result_rows\n" -#~ " | SET configuration_parameter { TO value | = value | FROM CURRENT }\n" -#~ " | AS 'definition'\n" -#~ " | AS 'obj_file', 'link_symbol'\n" -#~ " } ...\n" -#~ " [ WITH ( attribute [, ...] ) ]" -#~ msgstr "" -#~ "CREATE [ OR REPLACE ] FUNCTION\n" -#~ " namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " [ RETURNS rettyp ]\n" -#~ " { LANGUAGE språknamn\n" -#~ " | IMMUTABLE | STABLE | VOLATILE\n" -#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " | [EXTERNAL] SECURITY INVOKER | [EXTERNAL] SECURITY DEFINER\n" -#~ " | AS 'definition'\n" -#~ " | AS 'obj-fil', 'länksymbol'\n" -#~ " } ...\n" -#~ " [ WITH ( attribut [, ...] ) ]" - -#~ msgid "" -#~ "CREATE DOMAIN name [ AS ] data_type\n" -#~ " [ DEFAULT expression ]\n" -#~ " [ constraint [ ... ] ]\n" -#~ "\n" -#~ "where constraint is:\n" -#~ "\n" -#~ "[ CONSTRAINT constraint_name ]\n" -#~ "{ NOT NULL | NULL | CHECK (expression) }" -#~ msgstr "" -#~ "CREATE DOMAIN namn [ AS ] datatyp\n" -#~ " [ DEFAULT uttryck ]\n" -#~ " [ villkor [ ... ] ]\n" -#~ "\n" -#~ "där villkor är:\n" -#~ "\n" -#~ "[ CONSTRAINT villkorsnamn ]\n" -#~ "{ NOT NULL | NULL | CHECK (uttryck) }" - -#, fuzzy -#~ msgid "" -#~ "CREATE DATABASE name\n" -#~ " [ [ WITH ] [ OWNER [=] dbowner ]\n" -#~ " [ TEMPLATE [=] template ]\n" -#~ " [ ENCODING [=] encoding ]\n" -#~ " [ LC_COLLATE [=] lc_collate ]\n" -#~ " [ LC_CTYPE [=] lc_ctype ]\n" -#~ " [ TABLESPACE [=] tablespace ]\n" -#~ " [ CONNECTION LIMIT [=] connlimit ] ]" -#~ msgstr "" -#~ "CREATE DATABASE namn\n" -#~ " [ [ WITH ] [ OWNER [=] db-ägare ]\n" -#~ " [ TEMPLATE [=] mall ]\n" -#~ " [ ENCODING [=] kodning ]\n" -#~ " [ TABLESPACE [=] tabellutrymme ] ]\n" -#~ " [ CONNECTION LIMIT [=] anslutningstak ] ]" - -#~ msgid "" -#~ "CREATE [ DEFAULT ] CONVERSION name\n" -#~ " FOR source_encoding TO dest_encoding FROM funcname" -#~ msgstr "" -#~ "CREATE [ DEFAULT ] CONVERSION namn\n" -#~ " FOR källkodning TO målkodning FROM funknamn" - -#~ msgid "" -#~ "CREATE CONSTRAINT TRIGGER name\n" -#~ " AFTER event [ OR ... ]\n" -#~ " ON table_name\n" -#~ " [ FROM referenced_table_name ]\n" -#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" -#~ " FOR EACH ROW\n" -#~ " EXECUTE PROCEDURE funcname ( arguments )" -#~ msgstr "" -#~ "CREATE CONSTRAINT TRIGGER namn \n" -#~ " AFTER händelse [ OR ... ]\n" -#~ " ON tabellnamn\n" -#~ " [ FROM refererat_tabellnamn ]\n" -#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" -#~ " FOR EACH ROW\n" -#~ " EXECUTE PROCEDURE funktionsnamn ( argument )" - -#~ msgid "" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITH FUNCTION funcname (argtypes)\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITHOUT FUNCTION\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (sourcetype AS targettype)\n" -#~ " WITH INOUT\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" -#~ msgstr "" -#~ "CREATE CAST (källtyp AS måltyp)\n" -#~ " WITH FUNCTION funknamn (argtyper)\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (källtyp AS måltyp)\n" -#~ " WITHOUT FUNCTION\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" -#~ "\n" -#~ "CREATE CAST (källtyp AS måltyp)\n" -#~ " WITH INOUT\n" -#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" - -#~ msgid "" -#~ "CREATE AGGREGATE name ( input_data_type [ , ... ] ) (\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = state_data_type\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = initial_condition ]\n" -#~ " [ , SORTOP = sort_operator ]\n" -#~ ")\n" -#~ "\n" -#~ "or the old syntax\n" -#~ "\n" -#~ "CREATE AGGREGATE name (\n" -#~ " BASETYPE = base_type,\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = state_data_type\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = initial_condition ]\n" -#~ " [ , SORTOP = sort_operator ]\n" -#~ ")" -#~ msgstr "" -#~ "CREATE AGGREGATE namn ( indatatyp [ , ... ] ) (\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = tillståndsdatatyp\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = startvärde ]\n" -#~ " [ , SORTOP = sorteringsoperator ]\n" -#~ ")\n" -#~ "\n" -#~ "eller den gamla syntaxen\n" -#~ "\n" -#~ "CREATE AGGREGATE namn (\n" -#~ " BASETYPE = indatatyp\n" -#~ " SFUNC = sfunc,\n" -#~ " STYPE = tillståndsdatatyp\n" -#~ " [ , FINALFUNC = ffunc ]\n" -#~ " [ , INITCOND = startvärde ]\n" -#~ " [ , SORTOP = sorteringsoperator ]\n" -#~ ")" - -#, fuzzy -#~ msgid "" -#~ "COPY tablename [ ( column [, ...] ) ]\n" -#~ " FROM { 'filename' | STDIN }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" -#~ " [ NULL [ AS ] 'null string' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'quote' ] \n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE NOT NULL column [, ...] ]\n" -#~ "\n" -#~ "COPY { tablename [ ( column [, ...] ) ] | ( query ) }\n" -#~ " TO { 'filename' | STDOUT }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" -#~ " [ NULL [ AS ] 'null string' ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'quote' ] \n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE QUOTE column [, ...] ]" -#~ msgstr "" -#~ "COPY tabellnamn [ ( kolumn [, ...] ) ]\n" -#~ " FROM { 'filnamn' | STDIN }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ] \n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'avdelare' ]\n" -#~ " [ NULL [ AS ] 'null-sträng' ] ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'citat' ]\n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE NOT NULL kolumn [, ...] ]\n" -#~ "\n" -#~ "COPY { tabellnamn [ ( kolumn [, ...] ) ] | ( fråga ) }\n" -#~ " TO { 'filnamn' | STDOUT }\n" -#~ " [ [ WITH ] \n" -#~ " [ BINARY ]\n" -#~ " [ HEADER ]\n" -#~ " [ OIDS ]\n" -#~ " [ DELIMITER [ AS ] 'avdelare' ]\n" -#~ " [ NULL [ AS ] 'null-sträng' ] ]\n" -#~ " [ CSV [ HEADER ]\n" -#~ " [ QUOTE [ AS ] 'citat' ]\n" -#~ " [ ESCAPE [ AS ] 'escape' ]\n" -#~ " [ FORCE QUOTE kolumn [, ...] ]" - -#~ msgid "COMMIT PREPARED transaction_id" -#~ msgstr "COMMIT PREPARED transaktions-id" - -#~ msgid "COMMIT [ WORK | TRANSACTION ]" -#~ msgstr "COMMIT [ WORK | TRANSACTION ]" - -#, fuzzy -#~ msgid "" -#~ "COMMENT ON\n" -#~ "{\n" -#~ " TABLE object_name |\n" -#~ " COLUMN table_name.column_name |\n" -#~ " AGGREGATE agg_name (agg_type [, ...] ) |\n" -#~ " CAST (sourcetype AS targettype) |\n" -#~ " CONSTRAINT constraint_name ON table_name |\n" -#~ " CONVERSION object_name |\n" -#~ " DATABASE object_name |\n" -#~ " DOMAIN object_name |\n" -#~ " FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) |\n" -#~ " INDEX object_name |\n" -#~ " LARGE OBJECT large_object_oid |\n" -#~ " OPERATOR op (leftoperand_type, rightoperand_type) |\n" -#~ " OPERATOR CLASS object_name USING index_method |\n" -#~ " OPERATOR FAMILY object_name USING index_method |\n" -#~ " [ PROCEDURAL ] LANGUAGE object_name |\n" -#~ " ROLE object_name |\n" -#~ " RULE rule_name ON table_name |\n" -#~ " SCHEMA object_name |\n" -#~ " SEQUENCE object_name |\n" -#~ " TABLESPACE object_name |\n" -#~ " TEXT SEARCH CONFIGURATION object_name |\n" -#~ " TEXT SEARCH DICTIONARY object_name |\n" -#~ " TEXT SEARCH PARSER object_name |\n" -#~ " TEXT SEARCH TEMPLATE object_name |\n" -#~ " TRIGGER trigger_name ON table_name |\n" -#~ " TYPE object_name |\n" -#~ " VIEW object_name\n" -#~ "} IS 'text'" -#~ msgstr "" -#~ "COMMENT ON\n" -#~ "{\n" -#~ " TABLE objektname |\n" -#~ " COLUMN tabellnamn.kolumnnamn |\n" -#~ " AGGREGATE agg_namn (agg_typ) |\n" -#~ " CAST (källtyp AS måltyp) |\n" -#~ " CONSTRAINT villkorsnamn ON tabellnamn |\n" -#~ " CONVERSION objektnamn |\n" -#~ " DATABASE objektnamn |\n" -#~ " DOMAIN objektnamn |\n" -#~ " FUNCTION funk_namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] ) |\n" -#~ " INDEX objektnamn |\n" -#~ " LARGE OBJECT stort_objekt_oid |\n" -#~ " OPERATOR op (vänster operandstyp, höger operandstyp) |\n" -#~ " OPERATOR CLASS objektnamn USING indexmetod |\n" -#~ " [ PROCEDURAL ] LANGUAGE objektnamn |\n" -#~ " ROLE objektnamn |\n" -#~ " RULE regelnamn ON tabellnamn |\n" -#~ " SCHEMA objektnamn |\n" -#~ " SEQUENCE objektnamn |\n" -#~ " TRIGGER utlösarnamn ON tabellnamn |\n" -#~ " TYPE objektnamn |\n" -#~ " VIEW objektnamn\n" -#~ "} IS 'text'" - -#~ msgid "" -#~ "CLUSTER [VERBOSE] tablename [ USING indexname ]\n" -#~ "CLUSTER [VERBOSE]" -#~ msgstr "" -#~ "CLUSTER [VERBOSE] tabellnamn [ USING indexnamn ]\n" -#~ "CLUSTER [VERBOSE]" - -#~ msgid "CLOSE { name | ALL }" -#~ msgstr "CLOSE { namn | ALL }" - -#~ msgid "CHECKPOINT" -#~ msgstr "CHECKPOINT" - -#~ msgid "" -#~ "BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]\n" -#~ "\n" -#~ "where transaction_mode is one of:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" -#~ msgstr "" -#~ "BEGIN [ WORK | TRANSACTION ] [ transaktionsläge [, ...] ]\n" -#~ "\n" -#~ "där transaktionsläge är en av:\n" -#~ "\n" -#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" -#~ " READ WRITE | READ ONLY" - -#~ msgid "ANALYZE [ VERBOSE ] [ table [ ( column [, ...] ) ] ]" -#~ msgstr "ANALYZE [ VERBOSE ] [ tabell [ ( kolumn [, ...] ) ] ]" - -#~ msgid "" -#~ "ALTER VIEW name ALTER [ COLUMN ] column SET DEFAULT expression\n" -#~ "ALTER VIEW name ALTER [ COLUMN ] column DROP DEFAULT\n" -#~ "ALTER VIEW name OWNER TO new_owner\n" -#~ "ALTER VIEW name RENAME TO new_name\n" -#~ "ALTER VIEW name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER VIEW namn ALTER [ COLUMN ] kolumn SET DEFAULT uttryck\n" -#~ "ALTER VIEW namn ALTER [ COLUMN ] kolumn DROP DEFAULT\n" -#~ "ALTER VIEW namn OWNER TO ny_ägare\n" -#~ "ALTER VIEW namn RENAME TO nytt_namn\n" -#~ "ALTER VIEW namn SET SCHEMA nytt_schema" - -#, fuzzy -#~ msgid "" -#~ "ALTER USER name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER USER name RENAME TO newname\n" -#~ "\n" -#~ "ALTER USER name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER USER name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER USER name RESET configuration_parameter\n" -#~ "ALTER USER name RESET ALL" -#~ msgstr "" -#~ "ALTER USER namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ "\n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT anslutningstak\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'lösenord' \n" -#~ " | VALID UNTIL 'tidsstämpel'\n" -#~ "\n" -#~ "ALTER USER namn RENAME TO nytt_namn\n" -#~ "\n" -#~ "ALTER USER namn SET konfigurationsparameter { TO | = } { värde | DEFAULT }\n" -#~ "ALTER USER namn RESET konfigurationsparameter" - -#~ msgid "" -#~ "ALTER TYPE name RENAME TO new_name\n" -#~ "ALTER TYPE name OWNER TO new_owner \n" -#~ "ALTER TYPE name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER TYPE namn RENAME TO nytt_namn\n" -#~ "ALTER TYPE namn OWNER TO ny_ägare \n" -#~ "ALTER TYPE namn SET SCHEMA nytt_schema" - -#~ msgid "ALTER TRIGGER name ON table RENAME TO newname" -#~ msgstr "ALTER TRIGGER namb ON tabell RENAME TO nyttnamn" - -#~ msgid "ALTER TEXT SEARCH TEMPLATE name RENAME TO newname" -#~ msgstr "ALTER TEXT SEARCH TEMPLATE namn RENAME TO nyttnamn" - -#~ msgid "ALTER TEXT SEARCH PARSER name RENAME TO newname" -#~ msgstr "ALTER TEXT SEARCH PARSER namn RENAME TO nyttnamn" - -#~ msgid "" -#~ "ALTER TABLESPACE name RENAME TO newname\n" -#~ "ALTER TABLESPACE name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER TABLESPACE namn RENAME TO nytt_namn\n" -#~ "ALTER TABLESPACE namn OWNER TO ny_ägare" - -#, fuzzy -#~ msgid "" -#~ "ALTER TABLE [ ONLY ] name [ * ]\n" -#~ " action [, ... ]\n" -#~ "ALTER TABLE [ ONLY ] name [ * ]\n" -#~ " RENAME [ COLUMN ] column TO new_column\n" -#~ "ALTER TABLE name\n" -#~ " RENAME TO new_name\n" -#~ "ALTER TABLE name\n" -#~ " SET SCHEMA new_schema\n" -#~ "\n" -#~ "where action is one of:\n" -#~ "\n" -#~ " ADD [ COLUMN ] column type [ column_constraint [ ... ] ]\n" -#~ " DROP [ COLUMN ] column [ RESTRICT | CASCADE ]\n" -#~ " ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ]\n" -#~ " ALTER [ COLUMN ] column SET DEFAULT expression\n" -#~ " ALTER [ COLUMN ] column DROP DEFAULT\n" -#~ " ALTER [ COLUMN ] column { SET | DROP } NOT NULL\n" -#~ " ALTER [ COLUMN ] column SET STATISTICS integer\n" -#~ " ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" -#~ " ADD table_constraint\n" -#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" -#~ " DISABLE TRIGGER [ trigger_name | ALL | USER ]\n" -#~ " ENABLE TRIGGER [ trigger_name | ALL | USER ]\n" -#~ " ENABLE REPLICA TRIGGER trigger_name\n" -#~ " ENABLE ALWAYS TRIGGER trigger_name\n" -#~ " DISABLE RULE rewrite_rule_name\n" -#~ " ENABLE RULE rewrite_rule_name\n" -#~ " ENABLE REPLICA RULE rewrite_rule_name\n" -#~ " ENABLE ALWAYS RULE rewrite_rule_name\n" -#~ " CLUSTER ON index_name\n" -#~ " SET WITHOUT CLUSTER\n" -#~ " SET WITH OIDS\n" -#~ " SET WITHOUT OIDS\n" -#~ " SET ( storage_parameter = value [, ... ] )\n" -#~ " RESET ( storage_parameter [, ... ] )\n" -#~ " INHERIT parent_table\n" -#~ " NO INHERIT parent_table\n" -#~ " OWNER TO new_owner\n" -#~ " SET TABLESPACE new_tablespace" -#~ msgstr "" -#~ "ALTER TABLE [ ONLY ] namn [ * ]\n" -#~ " aktion [, ... ]\n" -#~ "ALTER TABLE [ ONLY ] namn [ * ]\n" -#~ " RENAME [ COLUMN ] kolumn TO ny_kolumn\n" -#~ "ALTER TABLE namn\n" -#~ " RENAME TO nytt_namn\n" -#~ "ALTER TABLE namn\n" -#~ " SET SCHEMA nytt_schema\n" -#~ "\n" -#~ "där aktion är en av:\n" -#~ "\n" -#~ " ADD [ COLUMN ] kolumn type [ kolumnvillkor [ ... ] ]\n" -#~ " DROP [ COLUMN ] kolumn [ RESTRICT | CASCADE ]\n" -#~ " ALTER [ COLUMN ] kolumn TYPE type [ USING uttryck ]\n" -#~ " ALTER [ COLUMN ] kolumn SET DEFAULT uttryck\n" -#~ " ALTER [ COLUMN ] kolumn DROP DEFAULT\n" -#~ " ALTER [ COLUMN ] kolumn { SET | DROP } NOT NULL\n" -#~ " ALTER [ COLUMN ] kolumn SET STATISTICS heltal\n" -#~ " ALTER [ COLUMN ] kolumn SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" -#~ " ADD tabellvillkor\n" -#~ " DROP CONSTRAINT villkorsnamn [ RESTRICT | CASCADE ]\n" -#~ " DISABLE TRIGGER [ utlösarnamn | ALL | USER ]\n" -#~ " ENABLE TRIGGER [ utlösarnamn | ALL | USER ]\n" -#~ " CLUSTER ON indexnamn\n" -#~ " SET WITHOUT CLUSTER\n" -#~ " SET WITHOUT OIDS\n" -#~ " SET ( lagringsparameter = värde [, ... ] )\n" -#~ " RESET ( lagringsparameter [, ... ] )\n" -#~ " INHERIT föräldertabell\n" -#~ " NO INHERIT föräldertabell\n" -#~ " OWNER TO ny_ägare\n" -#~ " SET TABLESPACE tabellutrymme" - -#, fuzzy -#~ msgid "" -#~ "ALTER SEQUENCE name [ INCREMENT [ BY ] increment ]\n" -#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" -#~ " [ START [ WITH ] start ]\n" -#~ " [ RESTART [ [ WITH ] restart ] ]\n" -#~ " [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { table.column | NONE } ]\n" -#~ "ALTER SEQUENCE name OWNER TO new_owner\n" -#~ "ALTER SEQUENCE name RENAME TO new_name\n" -#~ "ALTER SEQUENCE name SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER SEQUENCE namn [ INCREMENT [ BY ] ökningsvärde ]\n" -#~ " [ MINVALUE minvärde | NO MINVALUE ] [ MAXVALUE maxvärde | NO MAXVALUE ]\n" -#~ " [ RESTART [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" -#~ " [ OWNED BY { tabell.kolumn | NONE } ]\n" -#~ "ALTER SEQUENCE namn SET SCHEMA nytt_schema" - -#~ msgid "" -#~ "ALTER SCHEMA name RENAME TO newname\n" -#~ "ALTER SCHEMA name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER SCHEMA namn RENAME TO nytt_namn\n" -#~ "ALTER SCHEMA namn OWNER TO ny_ägare" - -#, fuzzy -#~ msgid "" -#~ "ALTER ROLE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT connlimit\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" -#~ " | VALID UNTIL 'timestamp' \n" -#~ "\n" -#~ "ALTER ROLE name RENAME TO newname\n" -#~ "\n" -#~ "ALTER ROLE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER ROLE name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER ROLE name RESET configuration_parameter\n" -#~ "ALTER ROLE name RESET ALL" -#~ msgstr "" -#~ "ALTER ROLE namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ " \n" -#~ " SUPERUSER | NOSUPERUSER\n" -#~ " | CREATEDB | NOCREATEDB\n" -#~ " | CREATEROLE | NOCREATEROLE\n" -#~ " | CREATEUSER | NOCREATEUSER\n" -#~ " | INHERIT | NOINHERIT\n" -#~ " | LOGIN | NOLOGIN\n" -#~ " | CONNECTION LIMIT anslutningstak\n" -#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'lösenord'\n" -#~ " | VALID UNTIL 'tidsstämpel' \n" -#~ "\n" -#~ "ALTER ROLE namn RENAME TO nytt_namn\n" -#~ "\n" -#~ "ALTER ROLE namn SET konfigurationsparameter { TO | = } { värde | DEFAULT }\n" -#~ "ALTER ROLE namn RESET konfigurationsparameter" - -#~ msgid "" -#~ "ALTER OPERATOR CLASS name USING index_method RENAME TO newname\n" -#~ "ALTER OPERATOR CLASS name USING index_method OWNER TO newowner" -#~ msgstr "" -#~ "ALTER OPERATOR CLASS namn USING indexmetod RENAME TO nytt_namn\n" -#~ "ALTER OPERATOR CLASS namn USING indexmetod OWNER TO ny_ägare" - -#~ msgid "ALTER OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) OWNER TO newowner" -#~ msgstr "ALTER OPERATOR namn ( { vänster_typ | NONE }, { höger_typ | NONE } ) OWNER TO ny_ägare" - -#, fuzzy -#~ msgid "" -#~ "ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO newname\n" -#~ "ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO new_owner" -#~ msgstr "" -#~ "ALTER SCHEMA namn RENAME TO nytt_namn\n" -#~ "ALTER SCHEMA namn OWNER TO ny_ägare" - -#~ msgid "" -#~ "ALTER INDEX name RENAME TO new_name\n" -#~ "ALTER INDEX name SET TABLESPACE tablespace_name\n" -#~ "ALTER INDEX name SET ( storage_parameter = value [, ... ] )\n" -#~ "ALTER INDEX name RESET ( storage_parameter [, ... ] )" -#~ msgstr "" -#~ "ALTER INDEX namn RENAME TO nytt_namn\n" -#~ "ALTER INDEX namn SET TABLESPACE tabellutrymmesnamn\n" -#~ "ALTER INDEX namn SET ( lagringsparameter = värde [, ... ] )\n" -#~ "ALTER INDEX namn RESET ( lagringsparameter [, ... ] )" - -#~ msgid "" -#~ "ALTER GROUP groupname ADD USER username [, ... ]\n" -#~ "ALTER GROUP groupname DROP USER username [, ... ]\n" -#~ "\n" -#~ "ALTER GROUP groupname RENAME TO newname" -#~ msgstr "" -#~ "ALTER GROUP gruppnamn ADD USER användarnamn [, ... ]\n" -#~ "ALTER GROUP gruppnamn DROP USER användarnamn [, ... ]\n" -#~ "\n" -#~ "ALTER GROUP gruppnamn RENAME TO nyttnamn" - -#, fuzzy -#~ msgid "" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " action [ ... ] [ RESTRICT ]\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " RENAME TO new_name\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " OWNER TO new_owner\n" -#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" -#~ " SET SCHEMA new_schema\n" -#~ "\n" -#~ "where action is one of:\n" -#~ "\n" -#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " IMMUTABLE | STABLE | VOLATILE\n" -#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" -#~ " COST execution_cost\n" -#~ " ROWS result_rows\n" -#~ " SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ " SET configuration_parameter FROM CURRENT\n" -#~ " RESET configuration_parameter\n" -#~ " RESET ALL" -#~ msgstr "" -#~ "ALTER FUNCTION namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " aktion [, ... ] [ RESTRICT ]\n" -#~ "ALTER FUNCTION namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " RENAME TO nytt_namn\n" -#~ "ALTER FUNCTION namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " OWNER TO ny_ägare\n" -#~ "ALTER FUNCTION namn ( [ [ arg_läge ] [ arg_namn ] arg_typ [, ...] ] )\n" -#~ " SET SCHEMA nytt_schema\n" -#~ "\n" -#~ "där aktion är en av:\n" -#~ "\n" -#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" -#~ " IMMUTABLE | STABLE | VOLATILE\n" -#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER" - -#~ msgid "" -#~ "ALTER DOMAIN name\n" -#~ " { SET DEFAULT expression | DROP DEFAULT }\n" -#~ "ALTER DOMAIN name\n" -#~ " { SET | DROP } NOT NULL\n" -#~ "ALTER DOMAIN name\n" -#~ " ADD domain_constraint\n" -#~ "ALTER DOMAIN name\n" -#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" -#~ "ALTER DOMAIN name\n" -#~ " OWNER TO new_owner \n" -#~ "ALTER DOMAIN name\n" -#~ " SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER DOMAIN namn\n" -#~ " { SET DEFAULT uttryck | DROP DEFAULT }\n" -#~ "ALTER DOMAIN namn\n" -#~ " { SET | DROP } NOT NULL\n" -#~ "ALTER DOMAIN namn\n" -#~ " ADD domain_villkor (constraint)\n" -#~ "ALTER DOMAIN namn\n" -#~ " DROP CONSTRAINT villkorsnamn [ RESTRICT | CASCADE ]\n" -#~ "ALTER DOMAIN namn\n" -#~ " OWNER TO ny_ägare\n" -#~ "ALTER DOMAIN namn\n" -#~ " SET SCHEMA nytt_schema" - -#, fuzzy -#~ msgid "" -#~ "ALTER DATABASE name [ [ WITH ] option [ ... ] ]\n" -#~ "\n" -#~ "where option can be:\n" -#~ "\n" -#~ " CONNECTION LIMIT connlimit\n" -#~ "\n" -#~ "ALTER DATABASE name RENAME TO newname\n" -#~ "\n" -#~ "ALTER DATABASE name OWNER TO new_owner\n" -#~ "\n" -#~ "ALTER DATABASE name SET TABLESPACE new_tablespace\n" -#~ "\n" -#~ "ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" -#~ "ALTER DATABASE name SET configuration_parameter FROM CURRENT\n" -#~ "ALTER DATABASE name RESET configuration_parameter\n" -#~ "ALTER DATABASE name RESET ALL" -#~ msgstr "" -#~ "ALTER DATABASE namn [ [ WITH ] alternativ [ ... ] ]\n" -#~ "\n" -#~ "där alternativ kan vara:\n" -#~ "\n" -#~ " CONNECTION LIMIT anslutningstak\n" -#~ "\n" -#~ "ALTER DATABASE namn SET parameter { TO | = } { värde | DEFAULT }\n" -#~ "ALTER DATABASE namn RESET parameter\n" -#~ "\n" -#~ "ALTER DATABASE namn RENAME TO nyttnamn\n" -#~ "\n" -#~ "ALTER DATABASE namn OWNER TO ny_ägare" - -#~ msgid "" -#~ "ALTER CONVERSION name RENAME TO newname\n" -#~ "ALTER CONVERSION name OWNER TO newowner" -#~ msgstr "" -#~ "ALTER CONVERSION namn RENAME TO nytt_namn\n" -#~ "ALTER CONVERSION namn OWNER TO ny_ägare" - -#~ msgid "" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) RENAME TO new_name\n" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) OWNER TO new_owner\n" -#~ "ALTER AGGREGATE name ( type [ , ... ] ) SET SCHEMA new_schema" -#~ msgstr "" -#~ "ALTER AGGREGATE namn ( typ [ , ... ] ) RENAME TO nytt_namn\n" -#~ "ALTER AGGREGATE name ( typ [ , ... ] ) OWNER TO ny_ägare\n" -#~ "ALTER AGGREGATE namn ( typ [ , ... ] ) SET SCHEMA nytt_schema" - -#~ msgid "ABORT [ WORK | TRANSACTION ]" -#~ msgstr "ABORT [ WORK | TRANSACTION ]" - -#~ msgid "could not change directory to \"%s\"" -#~ msgstr "kunde inte byta katalog till \"%s\"" - -#~ msgid "tablespace" -#~ msgstr "tabellutrymme" - -#~ msgid "input_data_type" -#~ msgstr "indatatyp" - -#~ msgid "agg_type" -#~ msgstr "agg_typ" - -#~ msgid "agg_name" -#~ msgstr "agg_namn" - -#~ msgid "new_column" -#~ msgstr "ny_kolumn" - -#~ msgid "column" -#~ msgstr "kolumn" - -#~ msgid "define a new constraint trigger" -#~ msgstr "definiera en ny villkorsutlösare" - -#~ msgid "Modifier" -#~ msgstr "Modifierare" - -#~ msgid "default %s" -#~ msgstr "default %s" - -#~ msgid "not null" -#~ msgstr "inte null" - -#~ msgid "Modifiers" -#~ msgstr "Modifierare" - -#~ msgid "data type" -#~ msgstr "datatyp" - -#~ msgid "contains support for command-line editing" -#~ msgstr "innehåller stöd för kommandoradsredigering" - -#~ msgid "%s: could not set variable \"%s\"\n" -#~ msgstr "%s: kunde inte sätta variabeln \"%s\"\n" - -#~ msgid "(No rows)\n" -#~ msgstr "(Inga rader)\n" - -#~ msgid "" -#~ " \\pset NAME [VALUE] set table output option\n" -#~ " (NAME := {format|border|expanded|fieldsep|footer|null|\n" -#~ " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n" -#~ msgstr "" -#~ " \\pset NAMN [VÄRDE] sätt tabellutskriftsval\n" -#~ " (NAMN := {format|border|expanded|fieldsep|footer|null|\n" -#~ " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n" - -#~ msgid " \\l[+] list all databases\n" -#~ msgstr " \\l[+] lista alla databaser\n" - -#~ msgid " \\du[+] [PATTERN] list roles (users)\n" -#~ msgstr " \\du[+] [MALL] lista roller (användare)\n" +"Tillgängliga värden är: %s." -#~ msgid " \\dg[+] [PATTERN] list roles (groups)\n" -#~ msgstr " \\dg[+] [MALL] lista roller (grupper)\n" +#~ msgid "Procedure" +#~ msgstr "Procedur" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version visa versionsinformation och avsluta sedan\n" +#~ msgid "%s: could not open log file \"%s\": %s\n" +#~ msgstr "%s: kunde inte öppna logg-fil \"%s\": %s\n" -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help visa denna hjälp och avsluta sedan\n" +#~ msgid "string_literal" +#~ msgstr "strängliteral" -#~ msgid "could not get current user name: %s\n" -#~ msgstr "kunde inte hämta det aktuella användarnamnet: %s\n" +#~ msgid "unterminated quoted string\n" +#~ msgstr "icketerminerad citerat sträng\n" -#~ msgid "\\copy: unexpected response (%d)\n" -#~ msgstr "\\copy: oväntat svar (%d)\n" +#~ msgid "could not read from input file: %s\n" +#~ msgstr "kunde inte läsa från infilen: %s\n" -#~ msgid "\\copy: %s" -#~ msgstr "\\copy: %s" +#~ msgid "Report bugs to .\n" +#~ msgstr "Rapportera fel till .\n" -#~ msgid "%s: pg_strdup: cannot duplicate null pointer (internal error)\n" -#~ msgstr "%s: pg_strdup: kan inte duplicera null-pekare (internt fel)\n" +#~ msgid "%s\n" +#~ msgstr "%s\n" -#~ msgid "Showing only tuples." -#~ msgstr "Visar bara tupler." +#~ msgid "could not close pipe to external command: %s\n" +#~ msgstr "kunde inte stänga rör till externt komamndo: %s\n" -#~ msgid "Showing locale-adjusted numeric output." -#~ msgstr "Visar lokal-anpassad numerisk utdata." +#~ msgid "could not stat file \"%s\": %s\n" +#~ msgstr "kunde inte göra stat() på fil \"%s\": %s\n" -#~ msgid "SSL connection (unknown cipher)\n" -#~ msgstr "SSL-förbindelse (okänt krypto)\n" +#~ msgid "could not execute command \"%s\": %s\n" +#~ msgstr "kunde inte utföra kommandot \"%s\": %s\n" -#~ msgid " as user \"%s\"" -#~ msgstr " som användare \"%s\"" +#~ msgid "could not parse reloptions array\n" +#~ msgstr "kunde inte parsa arrayen reloptions\n" -#~ msgid " at port \"%s\"" -#~ msgstr " port \"%s\"" +#~ msgid "could not open temporary file \"%s\": %s\n" +#~ msgstr "kunde inte öppna temporär fil \"%s\": %s\n" -#~ msgid " on host \"%s\"" -#~ msgstr " på värd \"%s\"" +#~ msgid "%s: %s\n" +#~ msgstr "%s: %s\n" -#~ msgid "\\%s: error\n" -#~ msgstr "\\%s: fel\n" +#~ msgid "Invalid command \\%s. Try \\? for help.\n" +#~ msgstr "Ogiltigt kommando \\%s. Försök med \\? för hjälp.\n" -#~ msgid "Password encryption failed.\n" -#~ msgstr "Lösenordskryptering misslyckades.\n" +#~ msgid "child process was terminated by signal %d" +#~ msgstr "barnprocess terminerades av signal %d" -#~ msgid "No relations found.\n" -#~ msgstr "Inga relationer funna.\n" +#~ msgid "child process was terminated by signal %s" +#~ msgstr "barnprocess terminerades av signal %s" -#~ msgid "No matching relations found.\n" -#~ msgstr "Inga matchande relationer funna.\n" +#~ msgid "pclose failed: %s" +#~ msgstr "pclose misslyckades: %s" -#~ msgid "No settings found.\n" -#~ msgstr "Inga inställningar funna.\n" +#~ msgid "could not read symbolic link \"%s\"" +#~ msgstr "kunde inte läsa symbolisk länk \"%s\"" -#~ msgid "No matching settings found.\n" -#~ msgstr "Inga matchande inställningar funna.\n" +#~ msgid "could not change directory to \"%s\": %s" +#~ msgstr "kunde inte byta katalog till \"%s\": %s" -#~ msgid "No per-database role settings support in this server version.\n" -#~ msgstr "Inga rollinställningar per databas stöds i denna serverversion.\n" +#~ msgid "could not identify current directory: %s" +#~ msgstr "kunde inte identifiera aktuell katalog: %s" diff --git a/src/bin/psql/po/tr.po b/src/bin/psql/po/tr.po new file mode 100644 index 00000000000..99730ec02a7 --- /dev/null +++ b/src/bin/psql/po/tr.po @@ -0,0 +1,8229 @@ +# translation of psql-tr.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2006, 2007. +# Nicolai Tufar , 2004, 2005, 2006, 2007. +# Abdullah GÜLNER , 2017, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: psql-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-08-06 20:15+0000\n" +"PO-Revision-Date: 2018-10-16 14:25+0300\n" +"Last-Translator: Abdullah Gülner <>\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=0;\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 1.8.7.1\n" +"X-Poedit-Basepath: /home/devrim/PostgreSQL/pgsql-cvs/pgsql\n" +"X-Poedit-Bookmarks: -1,-1,333,-1,-1,-1,-1,-1,-1,-1\n" + +#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#, c-format +msgid "could not identify current directory: %s" +msgstr "geçerli dizin tespit edilemedi: %s" + +#: ../../common/exec.c:146 +#, c-format +msgid "invalid binary \"%s\"" +msgstr "geçersiz ikili (binary) \"%s\"" + +#: ../../common/exec.c:195 +#, c-format +msgid "could not read binary \"%s\"" +msgstr "\"%s\" ikili (binary) dosyası okunamadı" + +#: ../../common/exec.c:202 +#, c-format +msgid "could not find a \"%s\" to execute" +msgstr "çalıştırılacak \"%s\" bulunamadı" + +#: ../../common/exec.c:257 ../../common/exec.c:293 +#, c-format +msgid "could not change directory to \"%s\": %s" +msgstr "çalışma dizini \"%s\" olarak değiştirilemedi: %s" + +#: ../../common/exec.c:272 +#, c-format +msgid "could not read symbolic link \"%s\"" +msgstr "sembolik link \"%s\" okuma hatası" + +#: ../../common/exec.c:523 +#, c-format +msgid "pclose failed: %s" +msgstr "pclose başarısız oldu: %s" + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 input.c:227 mainloop.c:82 mainloop.c:386 +#, c-format +msgid "out of memory\n" +msgstr "yetersiz bellek\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "geçerli kullanıcı ID si bulunamadı %ld: %s" + +#: ../../common/username.c:45 command.c:554 +msgid "user does not exist" +msgstr "kullanıcı mevcut değil" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "kullanıcı adı arama başarısız: hata kodu %lu" + +#: ../../common/wait_error.c:45 +#, c-format +msgid "command not executable" +msgstr "komut çalıştırılabilir değil" + +#: ../../common/wait_error.c:49 +#, c-format +msgid "command not found" +msgstr "komut bulunamadı" + +#: ../../common/wait_error.c:54 +#, c-format +msgid "child process exited with exit code %d" +msgstr "alt süreç %d çıkış koduyla sonuçlandırılmıştır" + +#: ../../common/wait_error.c:61 +#, c-format +msgid "child process was terminated by exception 0x%X" +msgstr "alt süreç 0x%X exception tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:71 +#, c-format +msgid "child process was terminated by signal %s" +msgstr "alt süreç %s sinyali tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:75 +#, c-format +msgid "child process was terminated by signal %d" +msgstr "alt süreç %d sinyali tarafından sonlandırılmıştır" + +#: ../../common/wait_error.c:80 +#, c-format +msgid "child process exited with unrecognized status %d" +msgstr "alt süreç %d bilinmeyen durumu ile sonlandırılmıştır" + +#: ../../fe_utils/print.c:353 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu satır)" +msgstr[1] "(%lu satır)" + +#: ../../fe_utils/print.c:2915 +#, c-format +msgid "Interrupted\n" +msgstr "kesildi\n" + +#: ../../fe_utils/print.c:2979 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "Başlık tablo içeriğine eklenemedi: %d kolon sayısı aşıldı.\n" + +#: ../../fe_utils/print.c:3019 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Hücre tablo içeriğine eklenemedi: %d olan toplam hücre sayısı aşıldı.\n" + +#: ../../fe_utils/print.c:3268 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "geçersiz çıktı biçimi (iç hata): %d" + +#: ../../fe_utils/psqlscan.l:715 +#, c-format +msgid "skipping recursive expansion of variable \"%s\"\n" +msgstr "\"%s\" değişkeninin özyinelemeli genişlemesi (recursive expansion) atlanıyor \n" + +#: command.c:220 +#, c-format +msgid "Invalid command \\%s. Try \\? for help.\n" +msgstr "Geçersiz komut \\%s. Yardım için \\? yazınız.\n" + +#: command.c:222 +#, c-format +msgid "invalid command \\%s\n" +msgstr "geçersiz komut \\%s\n" + +#: command.c:240 +#, c-format +msgid "\\%s: extra argument \"%s\" ignored\n" +msgstr "\\%s: \"%s\" parametresi fazla, yok sayıldı\n" + +#: command.c:292 +#, c-format +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "\\%s komut yok sayıldı; güncel \\if blokundan çıkmak için \\endif veya Ctrl-C kullanınız\n" + +#: command.c:552 +#, c-format +msgid "could not get home directory for user ID %ld: %s\n" +msgstr "%ld kullanıcı ID'si için home dizinine ulaşılamadı: %s\n" + +#: command.c:570 +#, c-format +msgid "\\%s: could not change directory to \"%s\": %s\n" +msgstr "\\%s: \"%s\" dizinine geçiş yapılamadı: %s\n" + +#: command.c:595 common.c:696 common.c:754 common.c:1292 +#, c-format +msgid "You are currently not connected to a database.\n" +msgstr "Şu anda bir veritabanına bağlı değilsiniz.\n" + +#: command.c:602 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "\"%s\" veritabanına \"%s\" kullanıcısıyla \"%s\" içindeki soket ile \"%s\" port'undan bağlandınız.\n" + +#: command.c:605 +#, c-format +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "\"%s\" veritabanına \"%s\" kullanıcısyla \"%s\" sunucusu üzrerinden \"%s\" porttan bağlandınız.\n" + +#: command.c:895 command.c:991 command.c:2376 +#, c-format +msgid "no query buffer\n" +msgstr "sorgu tamponu mevcut değil\n" + +#: command.c:928 command.c:4648 +#, c-format +msgid "invalid line number: %s\n" +msgstr "geçersiz satır numarası: %s\n" + +#: command.c:982 +#, c-format +msgid "The server (version %s) does not support editing function source.\n" +msgstr "Sunucu (%s sürümü) fonksiyon kaynak kodunda düzenlemeyi desteklememektedir.\n" + +#: command.c:985 +#, c-format +msgid "The server (version %s) does not support editing view definitions.\n" +msgstr "Sunucu (%s sürümü) görünüm tanımları üzerinde düzenlemeyi desteklememektedir.\n" + +#: command.c:1067 +msgid "No changes" +msgstr "Değişiklik yok" + +#: command.c:1144 +#, c-format +msgid "%s: invalid encoding name or conversion procedure not found\n" +msgstr "%s: dil kodlama adı geçersiz ya da dönüştürme fonksiyonu bulunamadı\n" + +#: command.c:1179 command.c:1818 command.c:3033 command.c:4750 common.c:174 +#: common.c:245 common.c:542 common.c:1338 common.c:1366 common.c:1474 +#: common.c:1577 common.c:1615 copy.c:489 copy.c:708 large_obj.c:156 +#: large_obj.c:191 large_obj.c:253 +#, c-format +msgid "%s" +msgstr "%s" + +#: command.c:1183 +msgid "out of memory" +msgstr "yetersiz bellek" + +#: command.c:1186 +msgid "There is no previous error." +msgstr "Önceden kalan hata bulunmuyor." + +#: command.c:1374 command.c:1679 command.c:1693 command.c:1710 command.c:1870 +#: command.c:2107 command.c:2343 command.c:2383 +#, c-format +msgid "\\%s: missing required argument\n" +msgstr "\\%s: zorunlu argüman eksik\n" + +#: command.c:1505 +#, c-format +msgid "\\elif: cannot occur after \\else\n" +msgstr "\\elif: \\else den sonra gelemez\n" + +#: command.c:1510 +#, c-format +msgid "\\elif: no matching \\if\n" +msgstr "\\elif: eşleşen \\if bulunmuyor\n" + +#: command.c:1574 +#, c-format +msgid "\\else: cannot occur after \\else\n" +msgstr "\\else: \\else den sonra gelemez\n" + +#: command.c:1579 +#, c-format +msgid "\\else: no matching \\if\n" +msgstr "\\else: eşleşen \\if bulunmuyor\n" + +#: command.c:1619 +#, c-format +msgid "\\endif: no matching \\if\n" +msgstr "\\endif: eşleşen \\if bulunmuyor\n" + +#: command.c:1774 +msgid "Query buffer is empty." +msgstr "Sorgu tamponu boş." + +#: command.c:1796 +msgid "Enter new password: " +msgstr "Yeni parola girin:" + +#: command.c:1797 +msgid "Enter it again: " +msgstr "Yeniden girin:" + +#: command.c:1801 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Parolalar uyuşmıyor.\n" + +#: command.c:1900 +#, c-format +msgid "\\%s: could not read value for variable\n" +msgstr "\\%s: değişken için değer okunamadı\n" + +#: command.c:2003 +msgid "Query buffer reset (cleared)." +msgstr "Sorgu tamponu sıfırlanmış." + +#: command.c:2025 +#, c-format +msgid "Wrote history to file \"%s\".\n" +msgstr "Geçmiş (history), \"%s\" dosyasına yazıldı.\n" + +#: command.c:2112 +#, c-format +msgid "\\%s: environment variable name must not contain \"=\"\n" +msgstr "\\%s: ortam değişkeni \"=\" içermemelidir\n" + +#: command.c:2173 +#, c-format +msgid "The server (version %s) does not support showing function source.\n" +msgstr "Sunucu (%s sürümü) fonksiyon kaynağını görüntülemeyi desteklemiyor.\n" + +#: command.c:2176 +#, c-format +msgid "The server (version %s) does not support showing view definitions.\n" +msgstr "Sunucu (%s sürümü) görünüm (view) tanımlarını göstermeyi desteklememektedir.\n" + +#: command.c:2183 +#, c-format +msgid "function name is required\n" +msgstr "fonksiyon adı gerekli\n" + +#: command.c:2185 +#, c-format +msgid "view name is required\n" +msgstr "görünüm (view) adı gerekli\n" + +#: command.c:2315 +msgid "Timing is on." +msgstr "Zamanlama açık." + +#: command.c:2317 +msgid "Timing is off." +msgstr "Zamanlama kapalı." + +#: command.c:2402 command.c:2430 command.c:3401 command.c:3404 command.c:3407 +#: command.c:3413 command.c:3415 command.c:3423 command.c:3433 command.c:3442 +#: command.c:3456 command.c:3473 command.c:3531 common.c:70 copy.c:332 +#: copy.c:392 copy.c:405 psqlscanslash.l:783 psqlscanslash.l:794 +#: psqlscanslash.l:804 +#, c-format +msgid "%s: %s\n" +msgstr "%s: %s\n" + +#: command.c:2814 startup.c:214 startup.c:265 +msgid "Password: " +msgstr "Parola: " + +#: command.c:2819 startup.c:262 +#, c-format +msgid "Password for user %s: " +msgstr "%s kullanıcısının parolası: " + +#: command.c:2869 +#, c-format +msgid "All connection parameters must be supplied because no database connection exists\n" +msgstr "Bütün bağlantı parametreleri sağlanmalı çünkü hiçbir veritabanı bağlantısı bulunmuyor\n" + +#: command.c:3037 +#, c-format +msgid "Previous connection kept\n" +msgstr "Önceki bağlantı kullanılacaktır\n" + +#: command.c:3041 +#, c-format +msgid "\\connect: %s" +msgstr "\\connect: %s" + +#: command.c:3077 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "Şu anda \"%s\" veritabanına \"%s\" kullanıcısıyla \"%s\" içindeki soket ile \"%s\" port'undan bağlısınız.\n" + +#: command.c:3080 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "Şu anda \"%s\" veritabanına \"%s\" kullanıcısı ile \"%s\" sunucusunda \"%s\". porttan bağlısınız.\n" + +#: command.c:3084 +#, c-format +msgid "You are now connected to database \"%s\" as user \"%s\".\n" +msgstr "Şu anda \"%s\" veritabanına \"%s\" kullanıcısı ile bağlısınız.\n" + +#: command.c:3117 +#, c-format +msgid "%s (%s, server %s)\n" +msgstr "%s (%s, sunucu %s)\n" + +#: command.c:3125 +#, c-format +msgid "" +"WARNING: %s major version %s, server major version %s.\n" +" Some psql features might not work.\n" +msgstr "" +"UYARI: %s ana sürümü %s, sunucu ana sürümü %s.\n" +" Bazı psql özellikleri çalışmayabilir.\n" + +#: command.c:3162 +#, c-format +msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" +msgstr "SSL bağlantısı (protokol:%s, cipher: %s, bit sayısı: %s, sıkıştırma: %s)\n" + +#: command.c:3163 command.c:3164 command.c:3165 +msgid "unknown" +msgstr "bilinmeyen" + +#: command.c:3166 help.c:45 +msgid "off" +msgstr "kapalı" + +#: command.c:3166 help.c:45 +msgid "on" +msgstr "açık" + +#: command.c:3186 +#, c-format +msgid "" +"WARNING: Console code page (%u) differs from Windows code page (%u)\n" +" 8-bit characters might not work correctly. See psql reference\n" +" page \"Notes for Windows users\" for details.\n" +msgstr "" +"UYARI: Uçbirimin kod sayfası (%u), Windows kod sayfasından (%u) farklıdır\n" +" 8-bitlik karakterler doğru çalışmayabilir. Ayrıntılar için psql referans\n" +" belgelerinde \"Windows kullanıcılarına notlar\" bölümüne bakın.\n" + +#: command.c:3290 +#, c-format +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" +msgstr "bir satır numarası belirtmek için PSQL_EDITOR_LINENUMBER_ARG çevresel değişkenini ayarlamanız gereklidir\n" + +#: command.c:3319 +#, c-format +msgid "could not start editor \"%s\"\n" +msgstr "\"%s\" metin düzenleyicisi çalıştırılamadı\n" + +#: command.c:3321 +#, c-format +msgid "could not start /bin/sh\n" +msgstr "/bin/sh başlatılamıyor\n" + +#: command.c:3359 +#, c-format +msgid "could not locate temporary directory: %s\n" +msgstr "geçici dizin bulunamıyor: %s\n" + +#: command.c:3386 +#, c-format +msgid "could not open temporary file \"%s\": %s\n" +msgstr "\"%s\" geçici dosya açılamıyor: %s\n" + +#: command.c:3660 +#, c-format +msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" +msgstr "\\pset: izin verilen biçimler: unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" + +#: command.c:3678 +#, c-format +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" +msgstr "\\pset: izin verilen çizgi biçimleri: ascii, old-ascii, unicode\n" + +#: command.c:3693 +#, c-format +msgid "\\pset: allowed Unicode border line styles are single, double\n" +msgstr "\\pset: izin verilen Unicode kenar çizgi biçimleri single, double\n" + +#: command.c:3708 +#, c-format +msgid "\\pset: allowed Unicode column line styles are single, double\n" +msgstr "\\pset: izin verilen Unicode sütun çizgi biçimleri: single, double\n" + +#: command.c:3723 +#, c-format +msgid "\\pset: allowed Unicode header line styles are single, double\n" +msgstr "\\pset: izin verilen Unicode üst bilgi çizgi biçimleri: single, double\n" + +#: command.c:3888 command.c:4067 +#, c-format +msgid "\\pset: unknown option: %s\n" +msgstr "\\pset: bilinmeyen seçenek: %s\n" + +#: command.c:3906 +#, c-format +msgid "Border style is %d.\n" +msgstr "Kenar stili: %d.\n" + +#: command.c:3912 +#, c-format +msgid "Target width is unset.\n" +msgstr "Hedef genişlik ayarı kaldırıldı.\n" + +#: command.c:3914 +#, c-format +msgid "Target width is %d.\n" +msgstr "Hedef genişlik %d.\n" + +#: command.c:3921 +#, c-format +msgid "Expanded display is on.\n" +msgstr "Geniş gösterme açık.\n" + +#: command.c:3923 +#, c-format +msgid "Expanded display is used automatically.\n" +msgstr "Geniş gösterme otomatik olarak kullanılıyor.\n" + +#: command.c:3925 +#, c-format +msgid "Expanded display is off.\n" +msgstr "Geniş gösterme kapalı.\n" + +#: command.c:3932 command.c:3940 +#, c-format +msgid "Field separator is zero byte.\n" +msgstr "Alan ayıracı sıfır bayttır.\n" + +#: command.c:3934 +#, c-format +msgid "Field separator is \"%s\".\n" +msgstr "Alan ayıracı: \"%s\".\n" + +#: command.c:3947 +#, c-format +msgid "Default footer is on.\n" +msgstr "Varsayılan sayfa altbilgisi açık.\n" + +#: command.c:3949 +#, c-format +msgid "Default footer is off.\n" +msgstr "Varsayılan sayfa altbilgisi kapalı.\n" + +#: command.c:3955 +#, c-format +msgid "Output format is %s.\n" +msgstr "Çıktı formatı: %s.\n" + +#: command.c:3961 +#, c-format +msgid "Line style is %s.\n" +msgstr "Satır stili: %s.\n" + +#: command.c:3968 +#, c-format +msgid "Null display is \"%s\".\n" +msgstr "Null display is \"%s\".\n" + +#: command.c:3976 +#, c-format +msgid "Locale-adjusted numeric output is on.\n" +msgstr "Yerel duyarlı sayısal çıktı açık.\n" + +#: command.c:3978 +#, c-format +msgid "Locale-adjusted numeric output is off.\n" +msgstr "Yerel duyarlı sayısal çıktı kapalı.\n" + +#: command.c:3985 +#, c-format +msgid "Pager is used for long output.\n" +msgstr "Uzun çıktı için sayfalama kullanılacaktır.\n" + +#: command.c:3987 +#, c-format +msgid "Pager is always used.\n" +msgstr "Sayfalama her zaman kullanılacak.\n" + +#: command.c:3989 +#, c-format +msgid "Pager usage is off.\n" +msgstr "Sayfalama kullanımı kapalı.\n" + +#: command.c:3995 +#, c-format +msgid "Pager won't be used for less than %d line.\n" +msgid_plural "Pager won't be used for less than %d lines.\n" +msgstr[0] "%d sayısından düşük satır için sayfalama kullanılmayacak.\n" +msgstr[1] "%d sayısından düşük satır için sayfalama kullanılmayacak.\n" + +#: command.c:4005 command.c:4015 +#, c-format +msgid "Record separator is zero byte.\n" +msgstr "Kayıt ayıracı sıfır bayt'tır.\n" + +#: command.c:4007 +#, c-format +msgid "Record separator is .\n" +msgstr "Kayıt ayıracı 'dır.\n" + +#: command.c:4009 +#, c-format +msgid "Record separator is \"%s\".\n" +msgstr "Kayıt ayıracı \"%s\".\n" + +#: command.c:4022 +#, c-format +msgid "Table attributes are \"%s\".\n" +msgstr "Tablo özellikleri: \"%s\".\n" + +#: command.c:4025 +#, c-format +msgid "Table attributes unset.\n" +msgstr "Tablo özellikleri kaldırıldı.\n" + +#: command.c:4032 +#, c-format +msgid "Title is \"%s\".\n" +msgstr "Başlık \"%s\".\n" + +#: command.c:4034 +#, c-format +msgid "Title is unset.\n" +msgstr "Başlık kaldırıldı\n" + +#: command.c:4041 +#, c-format +msgid "Tuples only is on.\n" +msgstr "Sadece kayıtları gösterme açık.\n" + +#: command.c:4043 +#, c-format +msgid "Tuples only is off.\n" +msgstr "Sadece kayıtları gösterme kapalı.\n" + +#: command.c:4049 +#, c-format +msgid "Unicode border line style is \"%s\".\n" +msgstr "Unicode kenar çizgi stili: \"%s\".\n" + +#: command.c:4055 +#, c-format +msgid "Unicode column line style is \"%s\".\n" +msgstr "Unicode sütun çizgi stili: \"%s\".\n" + +#: command.c:4061 +#, c-format +msgid "Unicode header line style is \"%s\".\n" +msgstr "Unicode sayfa üstbilgi çizgi stili: \"%s\".\n" + +#: command.c:4221 +#, c-format +msgid "\\!: failed\n" +msgstr "\\!: başarısız\n" + +#: command.c:4246 common.c:802 +#, c-format +msgid "\\watch cannot be used with an empty query\n" +msgstr "\\watch boş bir sorgu ile kullanılamaz\n" + +#: command.c:4287 +#, c-format +msgid "%s\t%s (every %gs)\n" +msgstr "%s\t%s (her %gs)\n" + +#: command.c:4290 +#, c-format +msgid "%s (every %gs)\n" +msgstr "%s (her %gs)\n" + +#: command.c:4344 command.c:4351 common.c:702 common.c:709 common.c:1321 +#, c-format +msgid "" +"********* QUERY **********\n" +"%s\n" +"**************************\n" +"\n" +msgstr "" +"********* SORGU **********\n" +"%s\n" +"**************************\n" +"\n" + +#: command.c:4543 +#, c-format +msgid "\"%s.%s\" is not a view\n" +msgstr "\"%s.%s\" bir görünüm (view) değildir\n" + +#: command.c:4559 +#, c-format +msgid "could not parse reloptions array\n" +msgstr "reloptions dizisi (array) ayrıştırılamadı\n" + +#: common.c:159 +#, c-format +msgid "cannot escape without active connection\n" +msgstr "aktif bağlantı olmadan vazgeçilemez (escape)\n" + +#: common.c:200 +#, c-format +msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgstr "kabuk komut argümanı yeni satır ya da satırbaşı karakteri içeriyor: \"%s\"\n" + +#: common.c:416 +#, c-format +msgid "connection to server was lost\n" +msgstr "sunucuya bağlantı kesildi\n" + +#: common.c:420 +#, c-format +msgid "The connection to the server was lost. Attempting reset: " +msgstr "Sunucuya bağlantı kesildi. Yeniden bağlantı deneniyor:" + +#: common.c:425 +#, c-format +msgid "Failed.\n" +msgstr "Başarısız.\n" + +#: common.c:432 +#, c-format +msgid "Succeeded.\n" +msgstr "Başarılı.\n" + +#: common.c:532 common.c:1082 common.c:1256 +#, c-format +msgid "unexpected PQresultStatus: %d\n" +msgstr "beklenmeyen PQresultStatus: %d\n" + +#: common.c:641 +#, c-format +msgid "Time: %.3f ms\n" +msgstr "Süre: %.3f milisaniye\n" + +#: common.c:656 +#, c-format +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "Süre: %.3f ms (%02d:%06.3f)\n" + +#: common.c:665 +#, c-format +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "Süre: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:672 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "Süre: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +#: common.c:809 +#, c-format +msgid "\\watch cannot be used with COPY\n" +msgstr "\\watch COPY ile birlikte kullanılamaz\n" + +#: common.c:814 +#, c-format +msgid "unexpected result status for \\watch\n" +msgstr "\\watch için beklenmedik sonuç durumu\n" + +#: common.c:843 +#, c-format +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "PID %3$d olan sunucu sürecinden \"%2$s\" payload'lı \"%1$s\" asenkon bildiri alınmış.\n" + +#: common.c:846 +#, c-format +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgstr "PID %2$d olan sunucu sürecinden \"%1$s\" asenkon bildiri alınmış.\n" + +#: common.c:908 +#, c-format +msgid "no rows returned for \\gset\n" +msgstr "\\gset için hiç bir satır dönmedi\n" + +#: common.c:913 +#, c-format +msgid "more than one row returned for \\gset\n" +msgstr "\\gset için birden fazla satır döndü\n" + +#: common.c:1301 +#, c-format +msgid "" +"***(Single step mode: verify command)*******************************************\n" +"%s\n" +"***(press return to proceed or enter x and return to cancel)********************\n" +msgstr "" +"***(Tek adım modu: verify command)*******************************************\n" +"%s\n" +"***(devam etmek için return, durdurmak için x ve return'e basınız)********************\n" + +#: common.c:1356 +#, c-format +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" +msgstr "Sunucu (%s sürümü) ON_ERROR_ROLLBACK için savepointleri desteklememektedir.\n" + +#: common.c:1419 +#, c-format +msgid "STATEMENT: %s\n" +msgstr "KOMUT: %s\n" + +#: common.c:1462 +#, c-format +msgid "unexpected transaction status (%d)\n" +msgstr "beklenmeyen işlem (transaction) durumu (%d)\n" + +#: common.c:1599 describe.c:1940 +msgid "Column" +msgstr "Kolon" + +#: common.c:1600 describe.c:174 describe.c:389 describe.c:407 describe.c:452 +#: describe.c:469 describe.c:958 describe.c:1122 describe.c:1663 +#: describe.c:1687 describe.c:1941 describe.c:3528 describe.c:3733 +#: describe.c:4905 +msgid "Type" +msgstr "Veri tipi" + +#: common.c:1649 +#, c-format +msgid "The command has no result, or the result has no columns.\n" +msgstr "Komut sonulç döndürmedi, veya sonuçta hiç sütun yok.\n" + +#: copy.c:99 +#, c-format +msgid "\\copy: arguments required\n" +msgstr "\\copy: parametre eksik\n" + +#: copy.c:254 +#, c-format +msgid "\\copy: parse error at \"%s\"\n" +msgstr "\\copy: \"%s\" ifadesinde ayrıştırma hatası\n" + +#: copy.c:256 +#, c-format +msgid "\\copy: parse error at end of line\n" +msgstr "\\copy: satır sonunda ayrıştırma hatası\n" + +#: copy.c:329 +#, c-format +msgid "could not execute command \"%s\": %s\n" +msgstr "\"%s\" komutu yürütülemedi: %s\n" + +#: copy.c:345 +#, c-format +msgid "could not stat file \"%s\": %s\n" +msgstr "\"%s\" dosyasının durumu görüntülenemedi (stat): %s\n" + +#: copy.c:349 +#, c-format +msgid "%s: cannot copy from/to a directory\n" +msgstr "%s: dizinden ya da dizine kopyalanamıyor\n" + +#: copy.c:386 +#, c-format +msgid "could not close pipe to external command: %s\n" +msgstr "dış komuta doğru olan pipe kapatılamadı: %s\n" + +#: copy.c:452 copy.c:463 +#, c-format +msgid "could not write COPY data: %s\n" +msgstr "COPY verisi yazılamadı: %s\n" + +#: copy.c:470 +#, c-format +msgid "COPY data transfer failed: %s" +msgstr "COPY veri aktarımı başarısız: %s" + +#: copy.c:531 +msgid "canceled by user" +msgstr "kullanıcı tarafından iptal edildi" + +#: copy.c:542 +msgid "" +"Enter data to be copied followed by a newline.\n" +"End with a backslash and a period on a line by itself, or an EOF signal." +msgstr "" +"Kopyalanacak veriyi girin ve ardından enter'a basın.\n" +"Sonuçlandırmak için yeni satırda ters taksim işareti ve nokta veya bir EOF işareti girin." + +#: copy.c:670 +msgid "aborted because of read failure" +msgstr "okuma hatası nedeniyle kesildi" + +#: copy.c:704 +msgid "trying to exit copy mode" +msgstr "copy modundan çıkmaya çalışıyor" + +#: crosstabview.c:123 +#, c-format +msgid "\\crosstabview: statement did not return a result set\n" +msgstr "\\crosstabview: komut bir sonuç kümesi döndürmedi\n" + +#: crosstabview.c:129 +#, c-format +msgid "\\crosstabview: query must return at least three columns\n" +msgstr "\\crosstabview: sorgu en az üç sütun döndürmelidir\n" + +#: crosstabview.c:156 +#, c-format +msgid "\\crosstabview: vertical and horizontal headers must be different columns\n" +msgstr "\\crostabview: dikey ve yatayda üstbilgiler farklı sütunlar olmalıdır\n" + +#: crosstabview.c:172 +#, c-format +msgid "\\crosstabview: data column must be specified when query returns more than three columns\n" +msgstr "\\crosstabview: sorgu üçten fazla sütun döndürüyorsa veri sütunu belirtilmelidir\n" + +#: crosstabview.c:228 +#, c-format +msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" +msgstr "\\crosstabview: azami sütun sayısı (%d) aşılmıştır\n" + +#: crosstabview.c:397 +#, c-format +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n" +msgstr "\\crosstabview: sorgu sonucu \"%s\" satırı, \"%s\" sütunu için çoklu veri değerleri içermektedir\n" + +#: crosstabview.c:645 +#, c-format +msgid "\\crosstabview: column number %d is out of range 1..%d\n" +msgstr "\\crosstabview: %d sütun numarası, 1..%d aralığının dışında\n" + +#: crosstabview.c:670 +#, c-format +msgid "\\crosstabview: ambiguous column name: \"%s\"\n" +msgstr "\\crosstabview: belirsiz sütun adı: \"%s\"\n" + +#: crosstabview.c:678 +#, c-format +msgid "\\crosstabview: column name not found: \"%s\"\n" +msgstr "\\crosstabview: sütun adı bulunamadı: \"%s\"\n" + +#: describe.c:74 describe.c:369 describe.c:674 describe.c:806 describe.c:950 +#: describe.c:1111 describe.c:1183 describe.c:3517 describe.c:3731 +#: describe.c:3822 describe.c:4070 describe.c:4215 describe.c:4456 +#: describe.c:4531 describe.c:4542 describe.c:4604 describe.c:5029 +#: describe.c:5112 +msgid "Schema" +msgstr "Şema" + +#: describe.c:75 describe.c:172 describe.c:239 describe.c:247 describe.c:370 +#: describe.c:675 describe.c:807 describe.c:868 describe.c:951 describe.c:1184 +#: describe.c:3518 describe.c:3654 describe.c:3732 describe.c:3823 +#: describe.c:3902 describe.c:4071 describe.c:4140 describe.c:4216 +#: describe.c:4457 describe.c:4532 describe.c:4543 describe.c:4605 +#: describe.c:4802 describe.c:4886 describe.c:5110 describe.c:5282 +#: describe.c:5507 +msgid "Name" +msgstr "Adı" + +#: describe.c:76 describe.c:382 describe.c:400 describe.c:446 describe.c:463 +msgid "Result data type" +msgstr "Sonuç veri tipi" + +#: describe.c:84 describe.c:97 describe.c:101 describe.c:383 describe.c:401 +#: describe.c:447 describe.c:464 +msgid "Argument data types" +msgstr "Argüman veri tipi" + +#: describe.c:109 describe.c:116 describe.c:182 describe.c:270 describe.c:509 +#: describe.c:723 describe.c:822 describe.c:893 describe.c:1186 describe.c:1959 +#: describe.c:3306 describe.c:3553 describe.c:3685 describe.c:3759 +#: describe.c:3832 describe.c:3915 describe.c:3983 describe.c:4083 +#: describe.c:4149 describe.c:4217 describe.c:4358 describe.c:4400 +#: describe.c:4473 describe.c:4535 describe.c:4544 describe.c:4606 +#: describe.c:4828 describe.c:4908 describe.c:5043 describe.c:5113 +#: large_obj.c:289 large_obj.c:299 +msgid "Description" +msgstr "Açıklama" + +#: describe.c:134 +msgid "List of aggregate functions" +msgstr "Aggregate fonksiyonların listesi" + +#: describe.c:159 +#, c-format +msgid "The server (version %s) does not support access methods.\n" +msgstr "Bu sunucu (%s sürümü) erişim yöntemlerini desteklememektedir.\n" + +#: describe.c:173 +msgid "Index" +msgstr "İndeks" + +#: describe.c:181 describe.c:4807 +msgid "Handler" +msgstr "İşleyici (handler)" + +#: describe.c:200 +msgid "List of access methods" +msgstr "Erişim yöntemlerinin listesi" + +#: describe.c:226 +#, c-format +msgid "The server (version %s) does not support tablespaces.\n" +msgstr "Sunucu (%s sürümü) tablespace'leri desteklememektedir.\n" + +#: describe.c:240 describe.c:248 describe.c:497 describe.c:713 describe.c:869 +#: describe.c:1110 describe.c:3529 describe.c:3658 describe.c:3904 +#: describe.c:4141 describe.c:4803 describe.c:4887 describe.c:5283 +#: describe.c:5409 describe.c:5508 large_obj.c:288 +msgid "Owner" +msgstr "Sahibi" + +#: describe.c:241 describe.c:249 +msgid "Location" +msgstr "Yer" + +#: describe.c:260 describe.c:3125 +msgid "Options" +msgstr "Seçenekler" + +#: describe.c:265 describe.c:686 describe.c:885 describe.c:3545 describe.c:3549 +msgid "Size" +msgstr "Boyut" + +#: describe.c:287 +msgid "List of tablespaces" +msgstr "Tablespace listesi" + +#: describe.c:329 +#, c-format +msgid "\\df only takes [anptwS+] as options\n" +msgstr "\\df sadece [anptwS+] seçeneklerini alır\n" + +#: describe.c:337 describe.c:348 +#, c-format +msgid "\\df does not take a \"%c\" option with server version %s\n" +msgstr "\\df \"%c\" seçeneğini %s sunucu sürümünde almaz\n" + +#. translator: "agg" is short for "aggregate" +#: describe.c:385 describe.c:403 describe.c:449 describe.c:466 +msgid "agg" +msgstr "agg" + +#: describe.c:386 describe.c:404 +msgid "window" +msgstr "pencere" + +#: describe.c:387 +msgid "proc" +msgstr "proc" + +#: describe.c:388 describe.c:406 describe.c:451 describe.c:468 +msgid "func" +msgstr "func" + +#: describe.c:405 describe.c:450 describe.c:467 describe.c:1320 +msgid "trigger" +msgstr "tetikleyici (trigger)" + +#: describe.c:479 +msgid "immutable" +msgstr "durağan" + +#: describe.c:480 +msgid "stable" +msgstr "kararlı" + +#: describe.c:481 +msgid "volatile" +msgstr "oynaklık" + +#: describe.c:482 +msgid "Volatility" +msgstr "Oynaklık" + +#: describe.c:490 +msgid "restricted" +msgstr "kısıtlı" + +#: describe.c:491 +msgid "safe" +msgstr "güvenli" + +#: describe.c:492 +msgid "unsafe" +msgstr "güvensiz" + +#: describe.c:493 +msgid "Parallel" +msgstr "Paralel" + +#: describe.c:498 +msgid "definer" +msgstr "tanımlayıcı" + +#: describe.c:499 +msgid "invoker" +msgstr "çağıran" + +#: describe.c:500 +msgid "Security" +msgstr "Güvenlik" + +#: describe.c:507 +msgid "Language" +msgstr "Dil" + +#: describe.c:508 +msgid "Source code" +msgstr "Kaynak kodu" + +#: describe.c:637 +msgid "List of functions" +msgstr "Fonksiyonların listesi" + +#: describe.c:685 +msgid "Internal name" +msgstr "Dahili adı" + +#: describe.c:707 +msgid "Elements" +msgstr "Elemanlar" + +#: describe.c:764 +msgid "List of data types" +msgstr "Veri tiplerinin listesi" + +#: describe.c:808 +msgid "Left arg type" +msgstr "Sol argüman veri tipi" + +#: describe.c:809 +msgid "Right arg type" +msgstr "Sağ argüman veri tipi" + +#: describe.c:810 +msgid "Result type" +msgstr "Sonuç veri tipi" + +#: describe.c:815 describe.c:3974 describe.c:4357 +msgid "Function" +msgstr "Fonksiyon" + +#: describe.c:840 +msgid "List of operators" +msgstr "Operatörlerin listesi" + +#: describe.c:870 +msgid "Encoding" +msgstr "Dil Kodlaması" + +#: describe.c:875 describe.c:4072 +msgid "Collate" +msgstr "Sıralama(collate)" + +#: describe.c:876 describe.c:4073 +msgid "Ctype" +msgstr "Ctype" + +#: describe.c:889 +msgid "Tablespace" +msgstr "Tablespace" + +#: describe.c:911 +msgid "List of databases" +msgstr "Veritabanlarının listesi" + +#: describe.c:952 describe.c:957 describe.c:1113 describe.c:3519 +#: describe.c:3526 +msgid "table" +msgstr "tablo" + +#: describe.c:953 describe.c:3520 +msgid "view" +msgstr "view" + +#: describe.c:954 describe.c:3521 +msgid "materialized view" +msgstr "maddileştirilmiş görünüm(materialized view)" + +#: describe.c:955 describe.c:1115 describe.c:3523 +msgid "sequence" +msgstr "sequence" + +#: describe.c:956 describe.c:3525 +msgid "foreign table" +msgstr "uzak (foreign) tablosu" + +#: describe.c:969 +msgid "Column privileges" +msgstr "Sütun erişim hakları" + +#: describe.c:1000 describe.c:1034 +msgid "Policies" +msgstr "İlkeler" + +#: describe.c:1066 describe.c:5564 describe.c:5568 +msgid "Access privileges" +msgstr "Erişim hakları" + +#: describe.c:1097 +#, c-format +msgid "The server (version %s) does not support altering default privileges.\n" +msgstr "Sunucu (%s sürümü) varsayılan (default) hakların değiştirilmesini desteklemiyor.\n" + +#: describe.c:1117 +msgid "function" +msgstr "fonksiyon" + +#: describe.c:1119 +msgid "type" +msgstr "tip" + +#: describe.c:1121 +msgid "schema" +msgstr "şema" + +#: describe.c:1145 +msgid "Default access privileges" +msgstr "Varsayılan erişim hakları" + +#: describe.c:1185 +msgid "Object" +msgstr "Nesne" + +#: describe.c:1199 +msgid "table constraint" +msgstr "tablo kısıtlaması (constraint)" + +#: describe.c:1221 +msgid "domain constraint" +msgstr "alan kısıtlaması (domain constraint)" + +#: describe.c:1249 +msgid "operator class" +msgstr "operatör sınıfı" + +#: describe.c:1278 +msgid "operator family" +msgstr "operatör ailesi" + +#: describe.c:1300 +msgid "rule" +msgstr "rule" + +#: describe.c:1342 +msgid "Object descriptions" +msgstr "Nesne açıklamaları" + +#: describe.c:1398 describe.c:3617 +#, c-format +msgid "Did not find any relation named \"%s\".\n" +msgstr "\"%s\" adında nesne bulunamadı.\n" + +#: describe.c:1401 describe.c:3620 +#, c-format +msgid "Did not find any relations.\n" +msgstr "Hiç bir nesne bulunamadı.\n" + +#: describe.c:1618 +#, c-format +msgid "Did not find any relation with OID %s.\n" +msgstr "OID %s olan nesne bulunamadı.\n" + +#: describe.c:1664 describe.c:1688 +msgid "Start" +msgstr "Başlat" + +#: describe.c:1665 describe.c:1689 +msgid "Minimum" +msgstr "Asgari (min)" + +#: describe.c:1666 describe.c:1690 +msgid "Maximum" +msgstr "Azami (max)" + +#: describe.c:1667 describe.c:1691 +msgid "Increment" +msgstr "Artım" + +#: describe.c:1668 describe.c:1692 describe.c:1817 describe.c:3826 +#: describe.c:3977 +msgid "yes" +msgstr "evet" + +#: describe.c:1669 describe.c:1693 describe.c:1818 describe.c:3826 +#: describe.c:3975 +msgid "no" +msgstr "hayır" + +#: describe.c:1670 describe.c:1694 +msgid "Cycles?" +msgstr "Döngüler?" + +#: describe.c:1671 describe.c:1695 +msgid "Cache" +msgstr "Önbellek" + +#: describe.c:1738 +#, c-format +msgid "Owned by: %s" +msgstr "Sahibi: %s" + +#: describe.c:1742 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "Kimlik (identity) sütunu için sıra (seq.) : %s" + +#: describe.c:1749 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "Sequence \"%s.%s\"" + +#: describe.c:1879 describe.c:1925 +#, c-format +msgid "Unlogged table \"%s.%s\"" +msgstr "Loglanmayan tablo \"%s.%s\" " + +#: describe.c:1882 describe.c:1928 +#, c-format +msgid "Table \"%s.%s\"" +msgstr "Tablo \"%s.%s\"" + +#: describe.c:1886 +#, c-format +msgid "View \"%s.%s\"" +msgstr "View \"%s.%s\"" + +#: describe.c:1891 +#, c-format +msgid "Unlogged materialized view \"%s.%s\"" +msgstr "Loglanmayan maddileştirilmiş görünüm (materialized view) \"%s.%s\"" + +#: describe.c:1894 +#, c-format +msgid "Materialized view \"%s.%s\"" +msgstr "\"%s.%s\" maddileştirilmiş görünümü (materialized view)" + +#: describe.c:1900 +#, c-format +msgid "Unlogged index \"%s.%s\"" +msgstr "Loglanmayan index \"%s.%s\"" + +#: describe.c:1903 +#, c-format +msgid "Index \"%s.%s\"" +msgstr "İndex \"%s.%s\"" + +#: describe.c:1908 +#, c-format +msgid "Special relation \"%s.%s\"" +msgstr "Özel nesne \"%s.%s\"" + +#: describe.c:1912 +#, c-format +msgid "TOAST table \"%s.%s\"" +msgstr "TOAST tablosu \"%s.%s\"" + +#: describe.c:1916 +#, c-format +msgid "Composite type \"%s.%s\"" +msgstr "Birleşik veri tipi \"%s.%s\"" + +#: describe.c:1920 +#, c-format +msgid "Foreign table \"%s.%s\"" +msgstr "\"%s.%s\" uzak (foreign) tablosu " + +#: describe.c:1944 describe.c:3739 +msgid "Collation" +msgstr "Sıralama (collation)" + +#: describe.c:1945 describe.c:3746 +msgid "Nullable" +msgstr "Boş (null) olabilir" + +#: describe.c:1946 describe.c:3747 +msgid "Default" +msgstr "Varsayılan" + +#: describe.c:1949 +msgid "Key?" +msgstr "Anahtar?" + +#: describe.c:1951 +msgid "Definition" +msgstr "Tanım" + +#: describe.c:1953 describe.c:4823 describe.c:4907 describe.c:4978 +#: describe.c:5042 +msgid "FDW options" +msgstr "FDW Seçenekleri" + +#: describe.c:1955 +msgid "Storage" +msgstr "Saklama" + +#: describe.c:1957 +msgid "Stats target" +msgstr "Stats hedefi" + +#: describe.c:2071 +#, c-format +msgid "Partition of: %s %s" +msgstr "" + +#: describe.c:2079 +msgid "No partition constraint" +msgstr "Bölümleme kısıtlaması yok" + +#: describe.c:2081 +#, c-format +msgid "Partition constraint: %s" +msgstr "Bölümleme kısıtlaması: %s" + +#: describe.c:2104 +#, c-format +msgid "Partition key: %s" +msgstr "Bölümleme anahtarı: %s" + +#: describe.c:2173 +msgid "primary key, " +msgstr "birincil anahtar, " + +#: describe.c:2175 +msgid "unique, " +msgstr "tekil, " + +#: describe.c:2181 +#, c-format +msgid "for table \"%s.%s\"" +msgstr "\"%s.%s\" tablosu için " + +#: describe.c:2185 +#, c-format +msgid ", predicate (%s)" +msgstr ", belirli (%s)" + +#: describe.c:2188 +msgid ", clustered" +msgstr ", clustered" + +#: describe.c:2191 +msgid ", invalid" +msgstr ", geçersiz" + +#: describe.c:2194 +msgid ", deferrable" +msgstr ", ertelenebilir" + +#: describe.c:2197 +msgid ", initially deferred" +msgstr ", başlangıçta ertelenmiş" + +#: describe.c:2200 +msgid ", replica identity" +msgstr ", replika kimliği " + +#: describe.c:2259 +msgid "Indexes:" +msgstr "İndeksler:" + +#: describe.c:2343 +msgid "Check constraints:" +msgstr "Check constraints:" + +#: describe.c:2379 +msgid "Foreign-key constraints:" +msgstr "İkincil anahtar sınırlamaları:" + +#: describe.c:2410 +msgid "Referenced by:" +msgstr "Referans veren:" + +#: describe.c:2460 +msgid "Policies:" +msgstr "İlkeler:" + +#: describe.c:2463 +msgid "Policies (forced row security enabled):" +msgstr "İlkeler (zorunlu satır güvenliği etkin):" + +#: describe.c:2466 +msgid "Policies (row security enabled): (none)" +msgstr "İlkeler (satır güvenliği etkin): (hiçbiri)" + +#: describe.c:2469 +msgid "Policies (forced row security enabled): (none)" +msgstr "İlkeler (zorunlu satır güvenliği etkin): (hiçbiri)" + +#: describe.c:2472 +msgid "Policies (row security disabled):" +msgstr "İlkeler (satır güvenliği devre dışı):" + +#: describe.c:2534 +msgid "Statistics objects:" +msgstr "İstatistik nesneleri:" + +#: describe.c:2637 describe.c:2741 +msgid "Rules:" +msgstr "Rulelar:" + +#: describe.c:2640 +msgid "Disabled rules:" +msgstr "Devre dışı bırakılmış rule'lar:" + +#: describe.c:2643 +msgid "Rules firing always:" +msgstr "Her zaman çalıştırılan rule'ler:" + +#: describe.c:2646 +msgid "Rules firing on replica only:" +msgstr "Sadece kopyada çalıştırılan rule'ler:" + +#: describe.c:2686 +msgid "Publications:" +msgstr "Yayınlar (publication):" + +#: describe.c:2724 +msgid "View definition:" +msgstr "View tanımı:" + +#: describe.c:2863 +msgid "Triggers:" +msgstr "Tetikleyiciler(Triggers):" + +#: describe.c:2867 +msgid "Disabled user triggers:" +msgstr "Devre dışı kullanıcı tetikleyicileri:" + +#: describe.c:2869 +msgid "Disabled triggers:" +msgstr "Devre dışı bırakılmış tetikleyiciler:" + +#: describe.c:2872 +msgid "Disabled internal triggers:" +msgstr "Devre dışı dahili tetikleyiciler:" + +#: describe.c:2875 +msgid "Triggers firing always:" +msgstr "Her zaman çalıştırılan tetikleyiciler:" + +#: describe.c:2878 +msgid "Triggers firing on replica only:" +msgstr "Sadece kopyada çalıştırılan tetikleyiciler:" + +#: describe.c:2937 +#, c-format +msgid "Server: %s" +msgstr "Sunucu: %s" + +#: describe.c:2945 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW Seçenekleri: (%s)" + +#: describe.c:2964 +msgid "Inherits" +msgstr "Inherits" + +#: describe.c:3023 +#, c-format +msgid "Number of partitions: %d" +msgstr "Bölümlemelerin (partition) sayısı: %d" + +#: describe.c:3032 +#, c-format +msgid "Number of child tables: %d (Use \\d+ to list them.)" +msgstr "alt tabloların sayısı: %d (Listelemek için \\d+ kullanabilirsiniz.)" + +#: describe.c:3034 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "Bölümlemelerin (partition) sayısı: %d (Listelemek için \\d+ kullanabilirsiniz.)" + +#: describe.c:3042 +msgid "Child tables" +msgstr "Alt tablolar" + +#: describe.c:3042 +msgid "Partitions" +msgstr "Bölümlemeler (partition)" + +#: describe.c:3085 +#, c-format +msgid "Typed table of type: %s" +msgstr "%s tipi için tipli tablo" + +#: describe.c:3101 +msgid "Replica Identity" +msgstr "Replika özdeşliği" + +#: describe.c:3114 +msgid "Has OIDs: yes" +msgstr "OID'ler mevcut: evet" + +#: describe.c:3194 +#, c-format +msgid "Tablespace: \"%s\"" +msgstr "Tablespace: \"%s\"" + +#. translator: before this string there's an index description like +#. '"foo_pkey" PRIMARY KEY, btree (a)' +#: describe.c:3206 +#, c-format +msgid ", tablespace \"%s\"" +msgstr ", tablespace \"%s\"" + +#: describe.c:3299 +msgid "List of roles" +msgstr "Veritabanı rolleri listesi" + +#: describe.c:3301 +msgid "Role name" +msgstr "Rol adı" + +#: describe.c:3302 +msgid "Attributes" +msgstr "Özellikler" + +#: describe.c:3303 +msgid "Member of" +msgstr "Üyesidir" + +#: describe.c:3314 +msgid "Superuser" +msgstr "Superuser" + +#: describe.c:3317 +msgid "No inheritance" +msgstr "Miras yok" + +#: describe.c:3320 +msgid "Create role" +msgstr "Rol oluştur" + +#: describe.c:3323 +msgid "Create DB" +msgstr "Veritabanı Oluştur" + +#: describe.c:3326 +msgid "Cannot login" +msgstr "Giriş yapılamıyor" + +#: describe.c:3330 +msgid "Replication" +msgstr "Replikasyon" + +#: describe.c:3334 +msgid "Bypass RLS" +msgstr "RLS'yi atlat" + +#: describe.c:3343 +msgid "No connections" +msgstr "Bağlantı yok" + +#: describe.c:3345 +#, c-format +msgid "%d connection" +msgid_plural "%d connections" +msgstr[0] "%d bağlantı" +msgstr[1] "1 bağlantı" + +#: describe.c:3355 +msgid "Password valid until " +msgstr "Parola geçerlilik tarihi" + +#: describe.c:3405 +#, c-format +msgid "The server (version %s) does not support per-database role settings.\n" +msgstr "Bu sunucu (%s sürümü) veritabanlarına özgü rol ayarlarını desteklememektedir.\n" + +#: describe.c:3418 +msgid "Role" +msgstr "Rol" + +#: describe.c:3419 +msgid "Database" +msgstr "Veritabanı" + +#: describe.c:3420 +msgid "Settings" +msgstr "Ayarlar" + +#: describe.c:3441 +#, c-format +msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgstr "\"%s\" rolü ve \"%s\" veritabanı için ayar bulunamadı.\n" + +#: describe.c:3444 +#, c-format +msgid "Did not find any settings for role \"%s\".\n" +msgstr "\"%s\" rolü için ayar bulunamadı.\n" + +#: describe.c:3447 +#, c-format +msgid "Did not find any settings.\n" +msgstr "Hiç bir ayar bulunamadı.\n" + +#: describe.c:3452 +msgid "List of settings" +msgstr "Seçeneklerin lsitesi" + +#: describe.c:3522 describe.c:3527 +msgid "index" +msgstr "indeks" + +#: describe.c:3524 +msgid "special" +msgstr "özel" + +#: describe.c:3534 describe.c:5030 +msgid "Table" +msgstr "Tablo" + +#: describe.c:3625 +msgid "List of relations" +msgstr "Nesnelerin listesi" + +#: describe.c:3662 +msgid "Trusted" +msgstr "Güvenilir" + +#: describe.c:3670 +msgid "Internal language" +msgstr "Dahili dil" + +#: describe.c:3671 +msgid "Call handler" +msgstr "Çağrı işleyici" + +#: describe.c:3672 describe.c:4810 +msgid "Validator" +msgstr "Onaylayan" + +#: describe.c:3675 +msgid "Inline handler" +msgstr "Satır içi işleyici" + +#: describe.c:3703 +msgid "List of languages" +msgstr "Dil listesi" + +#: describe.c:3748 +msgid "Check" +msgstr "Check" + +#: describe.c:3790 +msgid "List of domains" +msgstr "Domainlerin listesi" + +#: describe.c:3824 +msgid "Source" +msgstr "Kaynak" + +#: describe.c:3825 +msgid "Destination" +msgstr "Hedef" + +#: describe.c:3827 +msgid "Default?" +msgstr "Varsayılan?" + +#: describe.c:3864 +msgid "List of conversions" +msgstr "Dönüşümlerin listesi" + +#: describe.c:3903 +msgid "Event" +msgstr "Olay" + +#: describe.c:3905 +msgid "enabled" +msgstr "etkin" + +#: describe.c:3906 +msgid "replica" +msgstr "replika" + +#: describe.c:3907 +msgid "always" +msgstr "daima" + +#: describe.c:3908 +msgid "disabled" +msgstr "devre dışı bırakılmış" + +#: describe.c:3909 describe.c:5509 +msgid "Enabled" +msgstr "Etkin" + +#: describe.c:3910 +msgid "Procedure" +msgstr "Prosedür" + +#: describe.c:3911 +msgid "Tags" +msgstr "Etiketler (tag)" + +#: describe.c:3930 +msgid "List of event triggers" +msgstr "Olay tetikleyicilerin listesi" + +#: describe.c:3972 +msgid "Source type" +msgstr "Kaynak tipi" + +#: describe.c:3973 +msgid "Target type" +msgstr "Hedef tipi" + +#: describe.c:3976 +msgid "in assignment" +msgstr "in assignment" + +#: describe.c:3978 +msgid "Implicit?" +msgstr "Örtülü mü?" + +#: describe.c:4029 +msgid "List of casts" +msgstr "Castlerin listesi" + +#: describe.c:4057 +#, c-format +msgid "The server (version %s) does not support collations.\n" +msgstr "Bu sunucu (%s sürümü) karşılaştırmaları (collations) desteklememektedir.\n" + +#: describe.c:4078 +msgid "Provider" +msgstr "Sağlayıcı" + +#: describe.c:4113 +msgid "List of collations" +msgstr "Karşılaştırma (collations) listesi" + +#: describe.c:4172 +msgid "List of schemas" +msgstr "Şemaların listesi" + +#: describe.c:4197 describe.c:4444 describe.c:4515 describe.c:4586 +#, c-format +msgid "The server (version %s) does not support full text search.\n" +msgstr "Bu sunucu (%s sürümü) tam metin aramayı desteklememektedir.\n" + +#: describe.c:4232 +msgid "List of text search parsers" +msgstr "Metin arama ayrıştıcılarının listesi" + +#: describe.c:4277 +#, c-format +msgid "Did not find any text search parser named \"%s\".\n" +msgstr "\"%s\" adında metin arama ayrıştırıcısı bulunamadı.\n" + +#: describe.c:4280 +#, c-format +msgid "Did not find any text search parsers.\n" +msgstr "Metin arama ayrıştırıcısı bulunamadı.\n" + +#: describe.c:4355 +msgid "Start parse" +msgstr "Ayrıştırmayı başlat" + +#: describe.c:4356 +msgid "Method" +msgstr "Yöntem" + +#: describe.c:4360 +msgid "Get next token" +msgstr "Sıradaki tokeni al" + +#: describe.c:4362 +msgid "End parse" +msgstr "Ayrıştırmayı bitir" + +#: describe.c:4364 +msgid "Get headline" +msgstr "Başlığı al" + +#: describe.c:4366 +msgid "Get token types" +msgstr "Token tiplerini al" + +#: describe.c:4377 +#, c-format +msgid "Text search parser \"%s.%s\"" +msgstr "Metin arama ayrıştırıcısı \"%s.%s\"" + +#: describe.c:4380 +#, c-format +msgid "Text search parser \"%s\"" +msgstr "\"%s\" metin arama ayrıştırıcısı" + +#: describe.c:4399 +msgid "Token name" +msgstr "Token adı" + +#: describe.c:4410 +#, c-format +msgid "Token types for parser \"%s.%s\"" +msgstr "\"%s.%s\" ayrıştırıcısı için token tipleri" + +#: describe.c:4413 +#, c-format +msgid "Token types for parser \"%s\"" +msgstr "\"%s\" ayrıştırıcısı için token tipleri" + +#: describe.c:4467 +msgid "Template" +msgstr "Şablon" + +#: describe.c:4468 +msgid "Init options" +msgstr "İnit seçenekleri" + +#: describe.c:4490 +msgid "List of text search dictionaries" +msgstr "Metin arama sözlüklerinin listesi" + +#: describe.c:4533 +msgid "Init" +msgstr "Init" + +#: describe.c:4534 +msgid "Lexize" +msgstr "Lexize" + +#: describe.c:4561 +msgid "List of text search templates" +msgstr "Metin arama şablonlarının listesi" + +#: describe.c:4621 +msgid "List of text search configurations" +msgstr "Metin arama yapılandırmalarının listesi" + +#: describe.c:4667 +#, c-format +msgid "Did not find any text search configuration named \"%s\".\n" +msgstr "\"%s\" adında metin arama yapılandırması bulunamadı.\n" + +#: describe.c:4670 +#, c-format +msgid "Did not find any text search configurations.\n" +msgstr "Metin arama yapılandırması bulunamadı.\n" + +#: describe.c:4736 +msgid "Token" +msgstr "Token" + +#: describe.c:4737 +msgid "Dictionaries" +msgstr "Sözlükler" + +#: describe.c:4748 +#, c-format +msgid "Text search configuration \"%s.%s\"" +msgstr "Metin arama yapılandırması \"%s.%s\"" + +#: describe.c:4751 +#, c-format +msgid "Text search configuration \"%s\"" +msgstr "Metin arama yapılandırması \"%s\"" + +#: describe.c:4755 +#, c-format +msgid "" +"\n" +"Parser: \"%s.%s\"" +msgstr "" +"\n" +"Ayrıştırıcı \"%s.%s\"" + +#: describe.c:4758 +#, c-format +msgid "" +"\n" +"Parser: \"%s\"" +msgstr "" +"\n" +"Ayrıştırıcı: \"%s\"" + +#: describe.c:4792 +#, c-format +msgid "The server (version %s) does not support foreign-data wrappers.\n" +msgstr "Sunucu (%s sürümü) foreign-data wrapperlarını desteklememektedir.\n" + +#: describe.c:4850 +msgid "List of foreign-data wrappers" +msgstr "Foreign-data wrapperlarının listesi" + +#: describe.c:4875 +#, c-format +msgid "The server (version %s) does not support foreign servers.\n" +msgstr "Bu sunucu (%s sürümü) uzak (foreign) sunucuları desteklemiyor.\n" + +#: describe.c:4888 +msgid "Foreign-data wrapper" +msgstr "Foreign-data wrapper" + +#: describe.c:4906 describe.c:5111 +msgid "Version" +msgstr "Sürüm" + +#: describe.c:4932 +msgid "List of foreign servers" +msgstr "Foreign sunucuların listesi" + +#: describe.c:4957 +#, c-format +msgid "The server (version %s) does not support user mappings.\n" +msgstr "Sunucu (%s sürümü) kullanıcı haritalamasını desteklememektedir.\n" + +#: describe.c:4967 describe.c:5031 +msgid "Server" +msgstr "Sunucu" + +#: describe.c:4968 +msgid "User name" +msgstr "Kullanıcı adı" + +#: describe.c:4993 +msgid "List of user mappings" +msgstr "Kullanıcı eşlemelerinin listesi" + +#: describe.c:5018 +#, c-format +msgid "The server (version %s) does not support foreign tables.\n" +msgstr "Bu sunucu (%s sürümü) uzak (foreign) tabloları desteklemiyor.\n" + +#: describe.c:5071 +msgid "List of foreign tables" +msgstr "Uzak (foreign) tabloların listesi" + +#: describe.c:5096 describe.c:5153 +#, c-format +msgid "The server (version %s) does not support extensions.\n" +msgstr "Bu sunucu (%s sürümü) uzantıları (extension) desteklememektedir.\n" + +#: describe.c:5128 +msgid "List of installed extensions" +msgstr "Kurulu uzantıların (extension) listesi" + +#: describe.c:5181 +#, c-format +msgid "Did not find any extension named \"%s\".\n" +msgstr "\"%s\" adında uzantı (extension) bulunamadı.\n" + +#: describe.c:5184 +#, c-format +msgid "Did not find any extensions.\n" +msgstr "Hiç bir uzantı bulunamadı.\n" + +#: describe.c:5228 +msgid "Object description" +msgstr "Nesne açıklaması" + +#: describe.c:5238 +#, c-format +msgid "Objects in extension \"%s\"" +msgstr "\"%s\" uzantısındaki nesneler" + +#: describe.c:5267 describe.c:5338 +#, c-format +msgid "The server (version %s) does not support publications.\n" +msgstr "Bu sunucu (%s sürümü) yayınları (publication) desteklememektedir.\n" + +#: describe.c:5284 describe.c:5410 +msgid "All tables" +msgstr "Bütün tablolar" + +#: describe.c:5285 describe.c:5411 +msgid "Inserts" +msgstr "Eklemeler (insert)" + +#: describe.c:5286 describe.c:5412 +msgid "Updates" +msgstr "Güncelleştirmeler (update)" + +#: describe.c:5287 describe.c:5413 +msgid "Deletes" +msgstr "Silmeler (delete)" + +#: describe.c:5291 describe.c:5415 +msgid "Truncates" +msgstr "Budamalar (truncate)" + +#: describe.c:5308 +msgid "List of publications" +msgstr "Yayınların (publication) listesi" + +#: describe.c:5376 +#, c-format +msgid "Did not find any publication named \"%s\".\n" +msgstr "\"%s\" adında yayın bulunamadı.\n" + +#: describe.c:5379 +#, c-format +msgid "Did not find any publications.\n" +msgstr "Hiç yayın bulunamadı.\n" + +#: describe.c:5406 +#, c-format +msgid "Publication %s" +msgstr "%s yayını (publication)" + +#: describe.c:5450 +msgid "Tables:" +msgstr "Tablolar:" + +#: describe.c:5494 +#, c-format +msgid "The server (version %s) does not support subscriptions.\n" +msgstr "Sunucu (%s sürümü) abonelikleri (subscription) desteklememektedir.\n" + +#: describe.c:5510 +msgid "Publication" +msgstr "Yayın (publication)" + +#: describe.c:5517 +msgid "Synchronous commit" +msgstr "Eşzamanlı commit" + +#: describe.c:5518 +msgid "Conninfo" +msgstr "Conninfo" + +#: describe.c:5540 +msgid "List of subscriptions" +msgstr "Aboneliklerin listesi" + +#: help.c:62 +#, c-format +msgid "%s\n" +msgstr "%s\n" + +#: help.c:73 +#, c-format +msgid "" +"psql is the PostgreSQL interactive terminal.\n" +"\n" +msgstr "" +"psql PostgreSQL'in etkilişimli arayüzüdür.\n" +"\n" + +#: help.c:74 help.c:345 help.c:419 help.c:462 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: help.c:75 +#, c-format +msgid "" +" psql [OPTION]... [DBNAME [USERNAME]]\n" +"\n" +msgstr "" +" psql [SEÇENEK]... [VERİTABANI ADI [KULLANICI ADI]]\n" +"\n" + +#: help.c:77 +#, c-format +msgid "General options:\n" +msgstr "Genel seçenekler:\n" + +#: help.c:82 +#, c-format +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" +msgstr " -c, --command=KOMUT tek bir komut çalıştır (SQL ya da dahili) ve çık\n" + +#: help.c:83 +#, c-format +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DBNAME bağlanılacak veritabanının adı (öntanımlı: \"%s\")\n" + +#: help.c:84 +#, c-format +msgid " -f, --file=FILENAME execute commands from file, then exit\n" +msgstr " -f, --file=DOSYA ADI dosyadan komutları çalıştır ve çık\n" + +#: help.c:85 +#, c-format +msgid " -l, --list list available databases, then exit\n" +msgstr " -l, --list veritabanlarını listele ve çık\n" + +#: help.c:86 +#, c-format +msgid "" +" -v, --set=, --variable=NAME=VALUE\n" +" set psql variable NAME to VALUE\n" +" (e.g., -v ON_ERROR_STOP=1)\n" +msgstr "" +" -v, --set=, --variable=ADI=DEĞER\n" +" ADI kısmında belirtilen psql değişkeninin değerini DEĞER ile belirtilen değer olarak ata\n" +" (örnek, -v ON_ERROR_STOP=1)\n" +"\n" + +#: help.c:89 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: help.c:90 +#, c-format +msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" +msgstr " -X , --no-psqlrc başlangıç dosyasını (~/.psqlrc) okuma\n" + +#: help.c:91 +#, c-format +msgid "" +" -1 (\"one\"), --single-transaction\n" +" execute as a single transaction (if non-interactive)\n" +msgstr "" +" -1 (\"one\"), --single-transaction\n" +" komut dosyasını tek bir transaction olarak çalıştır (interaktif değilse)\n" + +#: help.c:93 +#, c-format +msgid " -?, --help[=options] show this help, then exit\n" +msgstr " -?, --help[=options] bu yardımı göster, sonra çık\n" + +#: help.c:94 +#, c-format +msgid " --help=commands list backslash commands, then exit\n" +msgstr " --help=commands \"\\\"komutlarını listele, sonra çık\n" + +#: help.c:95 +#, c-format +msgid " --help=variables list special variables, then exit\n" +msgstr " --help=variables özel değişkenleri listele, sonra çık\n" + +#: help.c:97 +#, c-format +msgid "" +"\n" +"Input and output options:\n" +msgstr "" +"\n" +"Giriş ve çıkış tercihleri:\n" + +#: help.c:98 +#, c-format +msgid " -a, --echo-all echo all input from script\n" +msgstr " -a, --echo-all betik dosyasının içeriğini yansıt\n" + +#: help.c:99 +#, c-format +msgid " -b, --echo-errors echo failed commands\n" +msgstr " -e, --echo-errors başarısız komutları yansıt\n" + +#: help.c:100 +#, c-format +msgid " -e, --echo-queries echo commands sent to server\n" +msgstr " -e, --echo-queries sunucuya gönderilen komutları yansıt\n" + +#: help.c:101 +#, c-format +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden dahili komutların ürettiği sorguları göster\n" + +#: help.c:102 +#, c-format +msgid " -L, --log-file=FILENAME send session log to file\n" +msgstr " -L, --log-file=DOSYA ADI oturum kaydını dosyaya kaydet\n" + +#: help.c:103 +#, c-format +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline gelişmiş komut satırı düzenleyicisini devre dışı bırak (readline)\n" + +#: help.c:104 +#, c-format +msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" +msgstr " -o, --output=DOSYA ADI sorgu sonuçlarını dosyaya aktar (ya da |pipe)\n" + +#: help.c:105 +#, c-format +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet sessiz biçim (mesajlar kapalı, sadece sorgu sonuçları açık)\n" + +#: help.c:106 +#, c-format +msgid " -s, --single-step single-step mode (confirm each query)\n" +msgstr " -s, --single-step tek adım biçimi (her sorguyu onaylama)\n" + +#: help.c:107 +#, c-format +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" +msgstr " -S, --single-line tek satır modu (satır sonu SQL komutunu sonlandırır)\n" + +#: help.c:109 +#, c-format +msgid "" +"\n" +"Output format options:\n" +msgstr "" +"\n" +"Çıktı biçimi seçenekleri:\n" + +#: help.c:110 +#, c-format +msgid " -A, --no-align unaligned table output mode\n" +msgstr " -A, --no-align dizilmemiş tablo çıktı modu\n" + +#: help.c:111 +#, c-format +msgid "" +" -F, --field-separator=STRING\n" +" field separator for unaligned output (default: \"%s\")\n" +msgstr "" +" -F, --field-separator=DİZGİ\n" +" hizalanmamış çıktı için alan ayırıcısı (varsayılan: \"%s\")\n" + +#: help.c:114 +#, c-format +msgid " -H, --html HTML table output mode\n" +msgstr " -H, --html HTML tablosu çıktı modu\n" + +#: help.c:115 +#, c-format +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=VAR[=ARG] VAR yazma ayarınına ARG değerini ata (\\pset komutuna bak)\n" + +#: help.c:116 +#, c-format +msgid "" +" -R, --record-separator=STRING\n" +" record separator for unaligned output (default: newline)\n" +msgstr "" +" -R, --record-separator=DİZGİ\n" +" hizalanmamış çıktı için kayıt ayırıcısı (varsayılan: yeni satır)\n" + +#: help.c:118 +#, c-format +msgid " -t, --tuples-only print rows only\n" +msgstr " -t, --tuples-only sadece satırları yaz\n" + +#: help.c:119 +#, c-format +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=TEXT HTML tablo tag parametrelerini ayarla (genişlik, kenarlık)\n" + +#: help.c:120 +#, c-format +msgid " -x, --expanded turn on expanded table output\n" +msgstr " -x, --expanded gelişmiş tablo çıktısını atkinleştir\n" + +#: help.c:121 +#, c-format +msgid "" +" -z, --field-separator-zero\n" +" set field separator for unaligned output to zero byte\n" +msgstr "" +" -z, --field-separator-zero\n" +" hizalanmamış çıktı için alan ayırıcısını sıfır bayt'a ayarla\n" + +#: help.c:123 +#, c-format +msgid "" +" -0, --record-separator-zero\n" +" set record separator for unaligned output to zero byte\n" +msgstr "" +" -0, --record-separator-zero\n" +" hizalanmamış çıktı için kayıt ayırıcısını sıfır bayt'a ayarla\n" + +#: help.c:126 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"Bağlantı seçenekleri:\n" + +#: help.c:129 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr " -h, --host= HOST ADI veritabanı sunucu adresi ya da soket dizini (varsayılan: \"%s\")\n" + +#: help.c:130 +msgid "local socket" +msgstr "yerel soket" + +#: help.c:133 +#, c-format +msgid " -p, --port=PORT database server port (default: \"%s\")\n" +msgstr " -p, --port=PORT veritabanı sunucusu port numarası (varsayılan: \"%s\")\n" + +#: help.c:139 +#, c-format +msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" +msgstr " -U, --username=KULLANICI ADI veritabanı kullanıcı adı (varsayılan: \"%s\")\n" + +#: help.c:140 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -W, --no-password bağlanmak için kesinlikle parola sorma\n" + +#: help.c:141 +#, c-format +msgid " -W, --password force password prompt (should happen automatically)\n" +msgstr " -W şifre sor (otomatik olarak her zaman açık)\n" + +#: help.c:143 +#, c-format +msgid "" +"\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" +"commands) from within psql, or consult the psql section in the PostgreSQL\n" +"documentation.\n" +"\n" +msgstr "" +"\n" +"Daha fazla bilgi için yapsql içinde: \"\\?\" (dahili komutlar için) ya \"\\help\"\n" +"(SQL komutlar için) yazın, ya da PostgreSQL belgelerinin psql bölümüne \n" +"bakın.\n" +"\n" + +#: help.c:146 +#, c-format +msgid "Report bugs to .\n" +msgstr "Hataları adresine bildirebilirsiniz.\n" + +#: help.c:172 +#, c-format +msgid "General\n" +msgstr "Genel\n" + +#: help.c:173 +#, c-format +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright PostgreSQL kullanım ve dağıtım şartlarını göster\n" + +#: help.c:174 +#, c-format +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLUMNS] sorguyu çalıştır ve sonuçları çapraz tablo içinde göster\n" + +#: help.c:175 +#, c-format +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose en son hata mesajını azami açıklamalı olarak göster\n" + +#: help.c:176 +#, c-format +msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +msgstr " \\g [DOSYA] or ; sorguyu çalıştır (ve sonucu dosyaya ya da |pipe'a gönder)\n" + +#: help.c:177 +#, c-format +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc sorguyu çalıştırmadan sonuçlarını tarif et\n" + +#: help.c:178 +#, c-format +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr "" + +#: help.c:179 +#, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] sorguyu çalıştır ve sonuçları psql değişkenlerinde sakla\n" + +#: help.c:180 +#, c-format +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [DOSYA] \\g gibi fakat genişletilmiş çıktı modu zorunlu\n" + +#: help.c:181 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q psql'den çık\n" + +#: help.c:182 +#, c-format +msgid " \\watch [SEC] execute query every SEC seconds\n" +msgstr " \\watch [SNY] sorguyu her SNY saniyede bir çalıştır\n" + +#: help.c:185 +#, c-format +msgid "Help\n" +msgstr "Yardım\n" + +#: help.c:187 +#, c-format +msgid " \\? [commands] show help on backslash commands\n" +msgstr " \\? [komutlar] \"\\\" komutları için yardım gösterir\n" + +#: help.c:188 +#, c-format +msgid " \\? options show help on psql command-line options\n" +msgstr "" +" \\? options psql komut satırı seçenekleri için yardım göster\n" +"\n" + +#: help.c:189 +#, c-format +msgid " \\? variables show help on special variables\n" +msgstr " \\? variables özel değişkenler hakkında yardım göster\n" + +#: help.c:190 +#, c-format +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" +msgstr " \\h [NAME] SQL komutları için sözdizimi yardımı, tüm komutlar için * ekleyin\n" + +#: help.c:193 +#, c-format +msgid "Query Buffer\n" +msgstr "Sorgu Tamponu (buffer)\n" + +#: help.c:194 +#, c-format +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" +msgstr " \\e [FILE] [LINE] sorgu tamponunu (ya da dosyasını) harici bir metin düzenleyici ile düzenle\n" + +#: help.c:195 +#, c-format +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgstr " \\ef [FUNCNAME [LINE]] fonksiyon tanımını harici bir metin düzenleyici ile düzenle\n" + +#: help.c:196 +#, c-format +msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" +msgstr " \\ev [VIEWNAME [LINE]] görünüm (view) tanımını harici bir metin düzenleyici ile düzenle\n" + +#: help.c:197 +#, c-format +msgid " \\p show the contents of the query buffer\n" +msgstr " \\p sorgu tamponunun içeriğini göster\n" + +#: help.c:198 +#, c-format +msgid " \\r reset (clear) the query buffer\n" +msgstr " \\r sorgu tamponunu sıfırla (temizle)\n" + +#: help.c:200 +#, c-format +msgid " \\s [FILE] display history or save it to file\n" +msgstr " \\s [DOSYA] geçmişi göster ya da dosyaya kaydet\n" + +#: help.c:202 +#, c-format +msgid " \\w FILE write query buffer to file\n" +msgstr " \\w DOSYA sorgu tamponunu dosyaya kaydet\n" + +#: help.c:205 +#, c-format +msgid "Input/Output\n" +msgstr "Giriş/Çıkış\n" + +#: help.c:206 +#, c-format +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... istemci sisteminden veri akımı ile SQL COPY komutunu çalıştır\n" + +#: help.c:207 +#, c-format +msgid " \\echo [STRING] write string to standard output\n" +msgstr " \\echo [METIN] standart çıktıya bir satır gönder\n" + +#: help.c:208 +#, c-format +msgid " \\i FILE execute commands from file\n" +msgstr " \\i DOSYA dosyadaki komutları çalıştıre\n" + +#: help.c:209 +#, c-format +msgid " \\ir FILE as \\i, but relative to location of current script\n" +msgstr " \\ir DOSYA \\i gibi, fakat geçerli betiğin bulunduğu yere göre\n" + +#: help.c:210 +#, c-format +msgid " \\o [FILE] send all query results to file or |pipe\n" +msgstr " \\o [DOSYA] tüm sorgu sonuçlarını dosyaya ya da |pipe'e gönder\n" + +#: help.c:211 +#, c-format +msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" +msgstr " \\qecho [STRING] sorgu çıktı akımına dizgi yaz (\\o seçeneğine bakınız)\n" + +#: help.c:214 +#, c-format +msgid "Conditional\n" +msgstr "Şartlı\n" + +#: help.c:215 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR şartlı bloğa başla\n" + +#: help.c:216 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR geçerli şartlı blok içinde alternatif\n" + +#: help.c:217 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else geçerli şartlı blok içinde son alternatif\n" + +#: help.c:218 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif şartlı bloğu sonlandır\n" + +#: help.c:221 +#, c-format +msgid "Informational\n" +msgstr "Bilgi edinme\n" + +#: help.c:222 +#, c-format +msgid " (options: S = show system objects, + = additional detail)\n" +msgstr " (seçenekler: S = sistem nesnelerini göster, + = ek ayrıntılar)\n" + +#: help.c:223 +#, c-format +msgid " \\d[S+] list tables, views, and sequences\n" +msgstr " \\d[S+] tablo, views, ve sequenceleri listele\n" + +#: help.c:224 +#, c-format +msgid " \\d[S+] NAME describe table, view, sequence, or index\n" +msgstr " \\d[S+} AD tablo, indeks, sequence, ya da view tanımlarını göster\n" + +#: help.c:225 +#, c-format +msgid " \\da[S] [PATTERN] list aggregates\n" +msgstr " \\da[S] [PATTERN] aggregateleri listele\n" + +#: help.c:226 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [PATTERN] erişim yöntemlerini listele\n" + +#: help.c:227 +#, c-format +msgid " \\db[+] [PATTERN] list tablespaces\n" +msgstr " \\db[+] [PATTERN] tablespaceleri listele\n" + +#: help.c:228 +#, c-format +msgid " \\dc[S+] [PATTERN] list conversions\n" +msgstr " \\dc[S+] [PATTERN] dönüşümleri listele\n" + +#: help.c:229 +#, c-format +msgid " \\dC[+] [PATTERN] list casts\n" +msgstr " \\dC[+] [PATTERN] castleri listele\n" + +#: help.c:230 +#, c-format +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [PATTERN] başka yerde gösterilmeyen nesne açıklamalarını göster\n" + +#: help.c:231 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [PATTERN] domainleri listele\n" + +#: help.c:232 +#, c-format +msgid " \\ddp [PATTERN] list default privileges\n" +msgstr " \\ddp [PATTERN] öntanımlı izinleri listele\n" + +#: help.c:233 +#, c-format +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [PATTERN] uzak (foreign) tabloları listele\n" + +#: help.c:234 +#, c-format +msgid " \\det[+] [PATTERN] list foreign tables\n" +msgstr " \\det[+] [PATTERN] foreign tabloları listele\n" + +#: help.c:235 +#, c-format +msgid " \\des[+] [PATTERN] list foreign servers\n" +msgstr " \\des[+] [PATTERN] foreign sunucuları listele\n" + +#: help.c:236 +#, c-format +msgid " \\deu[+] [PATTERN] list user mappings\n" +msgstr " \\deu[+] [PATTERN] kullanıcı haritalamasını listele\n" + +#: help.c:237 +#, c-format +msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" +msgstr " \\dew[+] [PATTERN] foreign-data wrapperlarını listele\n" + +#: help.c:238 +#, fuzzy, c-format +#| msgid " \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[antw][S+] [PATRN] [sadece agg/normal/trigger/window] fonksiyonlarını listele\n" + +#: help.c:239 +#, c-format +msgid " \\dF[+] [PATTERN] list text search configurations\n" +msgstr " \\dF[+] [PATTERN] metin arama yapılandırmalarını listele\n" + +#: help.c:240 +#, c-format +msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" +msgstr " \\dFd[+] [PATTERN] metin arama sözlüklerini listele\n" + +#: help.c:241 +#, c-format +msgid " \\dFp[+] [PATTERN] list text search parsers\n" +msgstr " \\dFp[+] [PATTERN] metin arama ayrıştırıcılarını listele\n" + +#: help.c:242 +#, c-format +msgid " \\dFt[+] [PATTERN] list text search templates\n" +msgstr " \\dFt[+] [PATTERN] metin arama şablonlarını listele\n" + +#: help.c:243 +#, c-format +msgid " \\dg[S+] [PATTERN] list roles\n" +msgstr " \\dg[S+] [PATTERN] rolleri listele\n" + +#: help.c:244 +#, c-format +msgid " \\di[S+] [PATTERN] list indexes\n" +msgstr " \\di[S+] [PATTERN] indexleri göster\n" + +#: help.c:245 +#, c-format +msgid " \\dl list large objects, same as \\lo_list\n" +msgstr " \\dl large objectleri göster; \\lo_list ile aynıdır\n" + +#: help.c:246 +#, c-format +msgid " \\dL[S+] [PATTERN] list procedural languages\n" +msgstr " \\dL[S+] [PATTERN] yordamsal dilleri listele\n" + +#: help.c:247 +#, c-format +msgid " \\dm[S+] [PATTERN] list materialized views\n" +msgstr " \\dm[S+] [PATTERN] maddileştirilmiş görünümleri (materialized view) listele\n" + +#: help.c:248 +#, c-format +msgid " \\dn[S+] [PATTERN] list schemas\n" +msgstr " \\dn[S+] [PATTERN] şemaları listele\n" + +#: help.c:249 +#, c-format +msgid " \\do[S] [PATTERN] list operators\n" +msgstr " \\do[S] [PATTERN] operatörleri listele\n" + +#: help.c:250 +#, c-format +msgid " \\dO[S+] [PATTERN] list collations\n" +msgstr " \\dO[S+] [PATTERN] collationları listele\n" + +#: help.c:251 +#, c-format +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [PATTERN] tablo, view, ve sequence erişim izinlerini listele\n" + +#: help.c:252 +#, c-format +msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" +msgstr " \\drds [PATRN1 [PATRN2]] veritabanı başına rol ayarlarını listele\n" + +#: help.c:253 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [PATTERN] replikasyon yayınlarını listele\n" + +#: help.c:254 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [PATTERN] replikasyon aboneliklerini listele\n" + +#: help.c:255 +#, c-format +msgid " \\ds[S+] [PATTERN] list sequences\n" +msgstr " \\ds[S+] [PATTERN] sequenceları listele\n" + +#: help.c:256 +#, c-format +msgid " \\dt[S+] [PATTERN] list tables\n" +msgstr " \\dt[S+] [PATTERN] tabloları listele\n" + +#: help.c:257 +#, c-format +msgid " \\dT[S+] [PATTERN] list data types\n" +msgstr " \\dT[S+] [PATTERN] veri tiplerini listele\n" + +#: help.c:258 +#, c-format +msgid " \\du[S+] [PATTERN] list roles\n" +msgstr " \\du[S+] [PATTERN] rolleri listele\n" + +#: help.c:259 +#, c-format +msgid " \\dv[S+] [PATTERN] list views\n" +msgstr " \\dv[S+] [PATTERN] viewları listele\n" + +#: help.c:260 +#, c-format +msgid " \\dx[+] [PATTERN] list extensions\n" +msgstr " \\dx[+] [PATTERN] uzantıları listele\n" + +#: help.c:261 +#, c-format +msgid " \\dy [PATTERN] list event triggers\n" +msgstr " \\dy [PATTERN] olay tetikleyicilerini listele\n" + +#: help.c:262 +#, c-format +msgid " \\l[+] [PATTERN] list databases\n" +msgstr " \\l[+] [PATTERN] veritabanlarını listele\n" + +#: help.c:263 +#, c-format +msgid " \\sf[+] FUNCNAME show a function's definition\n" +msgstr " \\sf[+] FUNCNAME fonksiyonun tanımını göster\n" + +#: help.c:264 +#, c-format +msgid " \\sv[+] VIEWNAME show a view's definition\n" +msgstr " \\sv[+] VIEWNAME görünümün (view) tanımını göster\n" + +#: help.c:265 +#, c-format +msgid " \\z [PATTERN] same as \\dp\n" +msgstr " \\z [PATTERN] \\dp ile aynı\n" + +#: help.c:268 +#, c-format +msgid "Formatting\n" +msgstr "Biçimlendirme:\n" + +#: help.c:269 +#, c-format +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a düzenli ve düzensiz çıktı modu arasında geçiş yap\n" + +#: help.c:270 +#, c-format +msgid " \\C [STRING] set table title, or unset if none\n" +msgstr " \\C [DİZİ] tablo başlığını ayarla, ya da boş bırakılırsa kaldır\n" + +#: help.c:271 +#, c-format +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [DİZİ] düzensiz sorgu çıktısı için alan ayracını göster ya da tanımla\n" + +#: help.c:272 +#, c-format +msgid " \\H toggle HTML output mode (currently %s)\n" +msgstr " \\H HTML çıktı modunu değiştir (şu anda %s)\n" + +#: help.c:274 +#, c-format +msgid "" +" \\pset [NAME [VALUE]] set table output option\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" +msgstr "" +" \\pset [NAME [VALUE]] tablo çıktı seçeneğini ayarla\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" + +#: help.c:280 +#, c-format +msgid " \\t [on|off] show only rows (currently %s)\n" +msgstr " \\t [on|off] sadece satırları göster (şu an %s)\n" + +#: help.c:282 +#, c-format +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [DİZGİ] HTML
parametrelerini tanımla, boÅŸ ise tüm parametrelerini kaldır\n" + +#: help.c:283 +#, c-format +msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" +msgstr " \\x [on|off|auto] geniÅŸ çıktı ayarla (ÅŸu an %s)\n" + +#: help.c:287 +#, c-format +msgid "Connection\n" +msgstr "BaÄŸlantı\n" + +#: help.c:289 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently \"%s\")\n" +msgstr "" +" \\c[onnect] {[VTADI|- KULLANICIADI|- KARÅžISUNUCU|- PORT|-] | conninfo}\n" +" yeni veritabanına baÄŸlan (geçerli veritabanı \"%s\")\n" + +#: help.c:293 +#, c-format +msgid "" +" \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" +" connect to new database (currently no connection)\n" +msgstr "" +" \\c[onnect] {[VTADI|- KULLANICIADI|- KARÅžISUNUCU|- PORT|-] | conninfo}\n" +" yeni veritabanına baÄŸlan (geçerli baÄŸlantı yok)\n" + +#: help.c:295 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo geçerli baÄŸlantı ile ilgili bilgi göster\n" + +#: help.c:296 +#, c-format +msgid " \\encoding [ENCODING] show or set client encoding\n" +msgstr " \\encoding [KODLAMA] istemci dil kodlamasını göster\n" + +#: help.c:297 +#, c-format +msgid " \\password [USERNAME] securely change the password for a user\n" +msgstr " \\password [KULLANICI ADI] kullanıcının parolasını güvenli ÅŸekilde deÄŸiÅŸtir\n" + +#: help.c:300 +#, c-format +msgid "Operating System\n" +msgstr "iÅŸletim Sistemi\n" + +#: help.c:301 +#, c-format +msgid " \\cd [DIR] change the current working directory\n" +msgstr " \\cd [DIR] geçerli çalışma dizinini deÄŸiÅŸtir\n" + +#: help.c:302 +#, c-format +msgid " \\setenv NAME [VALUE] set or unset environment variable\n" +msgstr " \\setenv NAME [VALUE] ortam deÄŸiÅŸkenini ayarla ya da ayarları sıfırla\n" + +#: help.c:303 +#, c-format +msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" +msgstr " \\timing [on|off] komutların çalışma zamanlamasının gösterilmesini deÄŸiÅŸtir (ÅŸu anda %s)\n" + +#: help.c:305 +#, c-format +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [KOMUT] komutu kabukta çalıştır ya da etkileÅŸimli kabuÄŸu baÅŸlat\n" + +#: help.c:308 +#, c-format +msgid "Variables\n" +msgstr "DeÄŸiÅŸkenler\n" + +#: help.c:309 +#, c-format +msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" +msgstr " \\prompt [METİN] AD kullanıcıdan dahili deÄŸiÅŸkeni deÄŸiÅŸtirmesini iste\n" + +#: help.c:310 +#, c-format +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [AD [DEÄžER]] dahili deÄŸiÅŸkene deÄŸer ata, DEÄžER boÅŸ ise tüm deÄŸiÅŸkenlerin listesini göster\n" + +#: help.c:311 +#, c-format +msgid " \\unset NAME unset (delete) internal variable\n" +msgstr " \\unset AD dahili deÄŸiÅŸkenleri sıfırla(sil)\n" + +#: help.c:314 +#, c-format +msgid "Large Objects\n" +msgstr "Large Objectler\n" + +#: help.c:315 +#, c-format +msgid "" +" \\lo_export LOBOID FILE\n" +" \\lo_import FILE [COMMENT]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operations\n" +msgstr "" +" \\lo_export LOBOID DOSYA\n" +" \\lo_import DOSYA [YORUM]\n" +" \\lo_list\n" +" \\lo_unlink LOBOID large object operasyonları\n" + +#: help.c:342 +#, c-format +msgid "" +"List of specially treated variables\n" +"\n" +msgstr "" +"Özel deÄŸiÅŸkenlerin listesi\n" +"\n" + +#: help.c:344 +#, c-format +msgid "psql variables:\n" +msgstr "psql deÄŸiÅŸkenleri:\n" + +#: help.c:346 +#, c-format +msgid "" +" psql --set=NAME=VALUE\n" +" or \\set NAME VALUE inside psql\n" +"\n" +msgstr "" +" psql --set=NAME=VALUE\n" +" veya psql içinde \\set NAME VALUE\n" +"\n" + +#: help.c:348 +#, c-format +msgid "" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" ayarlanırsa, baÅŸarılı SQL komutları otomatik olarak \"commit\" edilir\n" + +#: help.c:350 +#, c-format +msgid "" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" +msgstr "" +" COMP_KEYWORD_CASE\n" +" SQL anahtar kelimeleri tamamlanırken kullanılacak büyük/küçük harf seçeneÄŸini belirler\n" +" [lower, upper, preserve-lower, preserve-upper]\n" + +#: help.c:353 +#, c-format +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" geçerli durumda baÄŸlanılan veritabanının adı\n" + +#: help.c:355 +#, c-format +msgid "" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" +msgstr "" +" ECHO\n" +" hangi girdinin standart çıktıya yazılacağını kontrol eder\n" +" [all, errors, none, queries]\n" + +#: help.c:358 +#, c-format +msgid "" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" +msgstr "" +" ECHO_HIDDEN\n" +" ayarlanırsa ters-taksimli komutlar tarafından çalıştırılan dahili sorguları gösterir ;\n" +" \"noexec\" olarak ayarlanırsa, çalıştırmadan sadece gösterir \n" + +#: help.c:361 +#, c-format +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" geçerli istemci karakter kümesi kodlaması\n" + +#: help.c:363 +#, c-format +msgid "" +" ERROR\n" +" true if last query failed, else false\n" +msgstr "" +" ERROR\n" +" son sorgu hatalıysa true, deÄŸilse false\n" + +#: help.c:365 +#, c-format +msgid "" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" +msgstr "" +" FETCH_COUNT\n" +" bir defada alınacak ve gösterilecek sonuç satırı sayısı ( 0=sınırsız)\n" + +#: help.c:367 +#, c-format +msgid "" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL \n" +" komut geçmiÅŸini kontrol eder [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:369 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE \n" +" komut geçmiÅŸini saklamak için kullanılacak dosya adı\n" + +#: help.c:371 +#, c-format +msgid "" +" HISTSIZE\n" +" max number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" komut geçmiÅŸinde saklanacak komut sayısı üst sınırı\n" + +#: help.c:373 +#, c-format +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" geçerli durumda baÄŸlanılan veritabanı sunucu makinesi\n" + +#: help.c:375 +#, c-format +msgid "" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" interaktif bir oturumu sonlandırmak için gereken EOF (dosya sonu) sayısı\n" + +#: help.c:377 +#, c-format +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" etkilenen son OID'nin deÄŸeri\n" + +#: help.c:379 +#, c-format +msgid "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" +msgstr "" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" son hatanın mesajı ve SQLSTATE deÄŸeri, veya boÅŸ dizgi ve \"00000\" eÄŸer hiçbiri yoksa\n" + +#: help.c:382 +#, c-format +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" ayarlanırsa, bir hata bir iÅŸlemi (transaction) durdurmaz (örtük kayıt noktaları (savepoint) kullanır)\n" + +#: help.c:384 +#, c-format +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" hata sonrası yığın çalıştırmayı durdurur\n" + +#: help.c:386 +#, c-format +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" geçerli baÄŸlantının sunucu port'u\n" + +#: help.c:388 +#, c-format +msgid "" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" standart psql komut istemi\n" + +#: help.c:390 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" bir komut önceki satırdan beri devam ediyorsa kullanılan komut istemini belirtir\n" + +#: help.c:392 +#, c-format +msgid "" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" COPY ... FROM STDIN sırasında kullanılan komut istemini belirtir\n" + +#: help.c:394 +#, c-format +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" sessizce çalış (-q seçeneÄŸiyle aynı)\n" + +#: help.c:396 +#, c-format +msgid "" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" son sorgu tarafından döndürülen veya etkilenen satır sayısı, veya 0\n" + +#: help.c:398 +#, c-format +msgid "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" sunucunun sürümü (kısa metin veya sayısal formatta)\n" + +#: help.c:401 +#, c-format +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" mesaj baÄŸlam (context) alanlarının gösterimini kontrol eder [never, errors, always]\n" + +#: help.c:403 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" satır sonu SQL komut modunu sonlandırır (-S seçeneÄŸiyle aynı)\n" + +#: help.c:405 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" single-step modu (-s seçeneÄŸiyle aynı)\n" + +#: help.c:407 +#, c-format +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" son sorgunun SQLSTATE deÄŸeri, veya eÄŸer hata yoksa \"00000\"\n" + +#: help.c:409 +#, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" mevcut durumda baÄŸlı veritabanı kullanıcısı\n" + +#: help.c:411 +#, c-format +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse]\n" +msgstr "" +" VERBOSITY\n" +" hata raporlarının ayrıntı seviyesini kontrol eder [default, verbose, terse]\n" + +#: help.c:413 +#, c-format +msgid "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" +msgstr "" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql'in sürümü (detaylı metin, kısa metin veya sayısal formatta)\n" + +#: help.c:418 +#, c-format +msgid "" +"\n" +"Display settings:\n" +msgstr "" +"\n" +"Görüntüleme ayarları:\n" + +#: help.c:420 +#, c-format +msgid "" +" psql --pset=NAME[=VALUE]\n" +" or \\pset NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" psql --pset=NAME[=VALUE]\n" +" veya psql içinde \\pset NAME [VALUE]\n" +"\n" + +#: help.c:422 +#, c-format +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" kenar biçimi (number)\n" + +#: help.c:424 +#, c-format +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" \"wrapped\" biçimi için hedef geniÅŸlik\n" + +#: help.c:426 +#, c-format +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr " expanded (veya x) geniÅŸletilmiÅŸ çıktı [on, off, auto]\n" + +#: help.c:428 +#, c-format +msgid "" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" hizalanmamış çıktı için alan ayrıcısı (varsayılan \"%s\")\n" + +#: help.c:431 +#, c-format +msgid "" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" hizalanmamış çıktı için alan ayırıcısını sıfır bayt'a ayarla\n" + +#: help.c:433 +#, c-format +msgid "" +" footer\n" +" enable or disable display of the table footer [on, off]\n" +msgstr "" +" footer\n" +" tablo alt bilgi alanının etkinleÅŸtirilme veya devre dışı bırakılması [on, off]\n" + +#: help.c:435 +#, c-format +msgid "" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" çıktı biçimini ayarla [unaligned, aligned, wrapped, html, asciidoc, ...]\n" + +#: help.c:437 +#, c-format +msgid "" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" kenar çizgisi biçimini ayarla [ascii, old-ascii, unicode]\n" + +#: help.c:439 +#, c-format +msgid "" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" null deÄŸer yerine yazılacak dizgeyi ayarla\n" + +#: help.c:441 +#, c-format +msgid "" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" +msgstr "" +" numericlocale\n" +" basamak gruplarını ayırmak için yerel-özel bir karakterin gösterilmesini etkinleÅŸtir\n" + +#: help.c:443 +#, c-format +msgid "" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" harici sayfalamanın ne zaman kullanılacağını kontrol eder [yes, no, always]\n" + +#: help.c:445 +#, c-format +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" hizalanmamış çıktı için kayıt (satır) ayırıcısı\n" + +#: help.c:447 +#, c-format +msgid "" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" hizalanmamış çıktı için kayıt ayırıcısını sıfır bayt'a ayarla\n" + +#: help.c:449 +#, c-format +msgid "" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" +msgstr "" + +#: help.c:452 +#, c-format +msgid "" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" sonradan basılan tablolar için tablo baÅŸlığını ayarla\n" + +#: help.c:454 +#, c-format +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" ayarlanırsa, sadece gerçek tablo verisi gösterilir\n" + +#: help.c:456 +#, c-format +msgid "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" set the style of Unicode line drawing [single, double]\n" +msgstr "" +" unicode_border_linestyle\n" +" unicode_column_linestyle\n" +" unicode_header_linestyle\n" +" Unicode çizgi çizme biçimini ayarlar [single, double]\n" + +#: help.c:461 +#, c-format +msgid "" +"\n" +"Environment variables:\n" +msgstr "" +"\n" +"Ortam deÄŸiÅŸkenleri:\n" + +#: help.c:465 +#, c-format +msgid "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" NAME=VALUE [NAME=VALUE] psql ...\n" +" veya psql içinde \\setenv NAME [VALUE]\n" +"\n" + +#: help.c:467 +#, c-format +msgid "" +" set NAME=VALUE\n" +" psql ...\n" +" or \\setenv NAME [VALUE] inside psql\n" +"\n" +msgstr "" +" set NAME=VALUE\n" +" psql ...\n" +" veya psql içinde \\setenv NAME [VALUE]\n" +"\n" + +#: help.c:470 +#, c-format +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" wrapped biçim için sütun sayısı\n" + +#: help.c:472 +#, c-format +msgid "" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" application_name baÄŸlantı parametresinin aynısı\n" + +#: help.c:474 +#, c-format +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" dbname baÄŸlantı parametresinin aynı\n" + +#: help.c:476 +#, c-format +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" host baÄŸlantı parametresinin aynı\n" + +#: help.c:478 +#, c-format +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" baÄŸlantı parolası (tavsiye edilmez)\n" + +#: help.c:480 +#, c-format +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" parola dosya adı\n" + +#: help.c:482 +#, c-format +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" port baÄŸlantı parametresiyle aynı\n" + +#: help.c:484 +#, c-format +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" kullanıcı baÄŸlantı parametresiyle aynı\n" + +#: help.c:486 +#, c-format +msgid "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" editor used by the \\e, \\ef, and \\ev commands\n" +msgstr "" +" PSQL_EDITOR, EDITOR, VISUAL\n" +" \\e, \\ef, ve \\ev komutları tarafından kullanılan editör\n" + +#: help.c:488 +#, c-format +msgid "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" how to specify a line number when invoking the editor\n" +msgstr "" +" PSQL_EDITOR_LINENUMBER_ARG\n" +" editörü çağırırken bir satır numarasının nasıl belirtileceÄŸi\n" + +#: help.c:490 +#, c-format +msgid "" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" komut geçmiÅŸi dosyası için alternatif konum\n" + +#: help.c:492 +#, c-format +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" harici sayfalama programının ismi\n" + +#: help.c:494 +#, c-format +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" kulanıcının .psqlrc dosyası için alternatif konum\n" + +#: help.c:496 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" \\! komutu tarafından kullanılan kabuk\n" + +#: help.c:498 +#, c-format +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" geçici dosyalar için dizin\n" + +#: help.c:542 +msgid "Available help:\n" +msgstr "Yardım:\n" + +#: help.c:626 +#, c-format +msgid "" +"Command: %s\n" +"Description: %s\n" +"Syntax:\n" +"%s\n" +"\n" +msgstr "" +"Komut: %s\n" +"Açıklama: %s\n" +"Söz dizimi:\n" +"%s\n" +"\n" + +#: help.c:642 +#, c-format +msgid "" +"No help available for \"%s\".\n" +"Try \\h with no arguments to see available help.\n" +msgstr "" +"\"%s\" için yardım bulunmamaktadır.\n" +"\\h yazarak yardım konularının listesini görüntüleyin.\n" + +#: input.c:216 +#, c-format +msgid "could not read from input file: %s\n" +msgstr "girdi dosyasından okunamadı: %s\n" + +#: input.c:471 input.c:510 +#, c-format +msgid "could not save history to file \"%s\": %s\n" +msgstr "İşlem geçmiÅŸi \"%s\" dosyasına kaydedilemiyor: %s\n" + +#: input.c:530 +#, c-format +msgid "history is not supported by this installation\n" +msgstr "bu kurulum iÅŸlem geçmiÅŸini desteklemiyor\n" + +#: large_obj.c:64 +#, c-format +msgid "%s: not connected to a database\n" +msgstr "%s: veritabanına baÄŸlı deÄŸil\n" + +#: large_obj.c:83 +#, c-format +msgid "%s: current transaction is aborted\n" +msgstr "%s: geçerli transaction iptal edildi\n" + +#: large_obj.c:86 +#, c-format +msgid "%s: unknown transaction status\n" +msgstr "%s: bilinmeyen transaction durumu\n" + +#: large_obj.c:287 large_obj.c:298 +msgid "ID" +msgstr "ID" + +#: large_obj.c:308 +msgid "Large objects" +msgstr "Large objectler" + +#: mainloop.c:136 +#, c-format +msgid "\\if: escaped\n" +msgstr "\\if: yarıda kesildi(escaped)\n" + +#: mainloop.c:183 +#, c-format +msgid "Use \"\\q\" to leave %s.\n" +msgstr "%s'den çıkmak için \"\\q\" kullanın.\n" + +#: mainloop.c:205 +msgid "" +"The input is a PostgreSQL custom-format dump.\n" +"Use the pg_restore command-line client to restore this dump to a database.\n" +msgstr "" +"Girdi özel formatta bir PostgreSQL dökümüdür (dump).\n" +"Bu dökümü bir veritabanına geri yüklemek için pg_restore komut satırı istemcisini kullanın.\n" + +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "Yardım için \\? yazınız veya input bufffer'ı temzilemek için kontrol-C'ye basınız." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "Yardım için \\? yazınız." + +#: mainloop.c:288 +msgid "You are using psql, the command-line interface to PostgreSQL." +msgstr "PostgreSQL'in komut satırı arabirimi olan psql'i kullanıyorsunuz." + +#: mainloop.c:289 +#, c-format +msgid "" +"Type: \\copyright for distribution terms\n" +" \\h for help with SQL commands\n" +" \\? for help with psql commands\n" +" \\g or terminate with semicolon to execute query\n" +" \\q to quit\n" +msgstr "" +"Komutlar: \\copyright dağıtım koÅŸulları için\n" +" \\h SQL komutları hakkında yardım için\n" +" \\? psql dahili komutlarının yardımı için\n" +" \\g ya da noktalı virgül: sorguyu çalıştırmak için\n" +" \\q çıkmak için\n" + +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "Çıkmak için \\q yazınız." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "Çıkmak için kontrol-D'ye basınız." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "Çıkmak için kontrol-C'ye basınız." + +#: mainloop.c:449 mainloop.c:591 +#, c-format +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgstr "\\sorgu yoksayıldı; güncel \\if blokundan çıkmak için \\endif veya Ctrl-C kullanınız\n" + +#: mainloop.c:609 +#, c-format +msgid "reached EOF without finding closing \\endif(s)\n" +msgstr "" + +#: psqlscanslash.l:637 +#, c-format +msgid "unterminated quoted string\n" +msgstr "sonuçlandırılmamış tırnakla sınırlandırılmış dizgi\n" + +#: psqlscanslash.l:810 +#, c-format +msgid "%s: out of memory\n" +msgstr "%s: yetersiz bellek\n" + +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:441 sql_help.c:443 +#: sql_help.c:446 sql_help.c:448 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:587 sql_help.c:589 sql_help.c:591 +#: sql_help.c:593 sql_help.c:595 sql_help.c:598 sql_help.c:600 sql_help.c:603 +#: sql_help.c:614 sql_help.c:616 sql_help.c:657 sql_help.c:659 sql_help.c:661 +#: sql_help.c:664 sql_help.c:666 sql_help.c:668 sql_help.c:701 sql_help.c:705 +#: sql_help.c:709 sql_help.c:728 sql_help.c:731 sql_help.c:734 sql_help.c:763 +#: sql_help.c:775 sql_help.c:783 sql_help.c:786 sql_help.c:789 sql_help.c:804 +#: sql_help.c:807 sql_help.c:836 sql_help.c:841 sql_help.c:846 sql_help.c:851 +#: sql_help.c:856 sql_help.c:878 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:887 sql_help.c:889 sql_help.c:930 sql_help.c:974 sql_help.c:979 +#: sql_help.c:984 sql_help.c:989 sql_help.c:994 sql_help.c:1013 sql_help.c:1024 +#: sql_help.c:1026 sql_help.c:1045 sql_help.c:1055 sql_help.c:1057 +#: sql_help.c:1059 sql_help.c:1071 sql_help.c:1075 sql_help.c:1077 +#: sql_help.c:1088 sql_help.c:1090 sql_help.c:1092 sql_help.c:1108 +#: sql_help.c:1110 sql_help.c:1114 sql_help.c:1117 sql_help.c:1118 +#: sql_help.c:1119 sql_help.c:1122 sql_help.c:1124 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1387 +#: sql_help.c:1389 sql_help.c:1391 sql_help.c:1394 sql_help.c:1415 +#: sql_help.c:1418 sql_help.c:1421 sql_help.c:1424 sql_help.c:1428 +#: sql_help.c:1430 sql_help.c:1432 sql_help.c:1434 sql_help.c:1448 +#: sql_help.c:1451 sql_help.c:1453 sql_help.c:1455 sql_help.c:1465 +#: sql_help.c:1467 sql_help.c:1477 sql_help.c:1479 sql_help.c:1489 +#: sql_help.c:1492 sql_help.c:1514 sql_help.c:1516 sql_help.c:1518 +#: sql_help.c:1521 sql_help.c:1523 sql_help.c:1525 sql_help.c:1528 +#: sql_help.c:1578 sql_help.c:1620 sql_help.c:1623 sql_help.c:1625 +#: sql_help.c:1627 sql_help.c:1629 sql_help.c:1631 sql_help.c:1634 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2075 sql_help.c:2081 +#: sql_help.c:2091 sql_help.c:2111 sql_help.c:2136 sql_help.c:2154 +#: sql_help.c:2183 sql_help.c:2275 sql_help.c:2316 sql_help.c:2339 +#: sql_help.c:2360 sql_help.c:2361 sql_help.c:2396 sql_help.c:2416 +#: sql_help.c:2438 sql_help.c:2452 sql_help.c:2472 sql_help.c:2495 +#: sql_help.c:2525 sql_help.c:2550 sql_help.c:2596 sql_help.c:2867 +#: sql_help.c:2880 sql_help.c:2897 sql_help.c:2913 sql_help.c:2953 +#: sql_help.c:3005 sql_help.c:3009 sql_help.c:3011 sql_help.c:3017 +#: sql_help.c:3035 sql_help.c:3062 sql_help.c:3097 sql_help.c:3109 +#: sql_help.c:3118 sql_help.c:3162 sql_help.c:3176 sql_help.c:3204 +#: sql_help.c:3212 sql_help.c:3220 sql_help.c:3228 sql_help.c:3236 +#: sql_help.c:3244 sql_help.c:3252 sql_help.c:3260 sql_help.c:3269 +#: sql_help.c:3280 sql_help.c:3288 sql_help.c:3296 sql_help.c:3304 +#: sql_help.c:3312 sql_help.c:3322 sql_help.c:3331 sql_help.c:3340 +#: sql_help.c:3348 sql_help.c:3358 sql_help.c:3369 sql_help.c:3377 +#: sql_help.c:3386 sql_help.c:3397 sql_help.c:3406 sql_help.c:3414 +#: sql_help.c:3422 sql_help.c:3430 sql_help.c:3438 sql_help.c:3446 +#: sql_help.c:3454 sql_help.c:3462 sql_help.c:3470 sql_help.c:3478 +#: sql_help.c:3486 sql_help.c:3503 sql_help.c:3512 sql_help.c:3520 +#: sql_help.c:3537 sql_help.c:3552 sql_help.c:3820 sql_help.c:3871 +#: sql_help.c:3900 sql_help.c:3908 sql_help.c:4341 sql_help.c:4389 +#: sql_help.c:4530 +msgid "name" +msgstr "ad" + +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3177 sql_help.c:4127 +msgid "aggregate_signature" +msgstr "aggregate_imzası" + +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:447 sql_help.c:524 sql_help.c:570 +#: sql_help.c:588 sql_help.c:615 sql_help.c:665 sql_help.c:730 sql_help.c:785 +#: sql_help.c:806 sql_help.c:845 sql_help.c:890 sql_help.c:931 sql_help.c:983 +#: sql_help.c:1015 sql_help.c:1025 sql_help.c:1058 sql_help.c:1078 +#: sql_help.c:1091 sql_help.c:1125 sql_help.c:1266 sql_help.c:1388 +#: sql_help.c:1431 sql_help.c:1452 sql_help.c:1466 sql_help.c:1478 +#: sql_help.c:1491 sql_help.c:1522 sql_help.c:1579 sql_help.c:1628 +msgid "new_name" +msgstr "yeni_adı" + +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:483 sql_help.c:529 sql_help.c:617 +#: sql_help.c:626 sql_help.c:684 sql_help.c:704 sql_help.c:733 sql_help.c:788 +#: sql_help.c:850 sql_help.c:888 sql_help.c:988 sql_help.c:1027 sql_help.c:1056 +#: sql_help.c:1076 sql_help.c:1089 sql_help.c:1123 sql_help.c:1326 +#: sql_help.c:1390 sql_help.c:1433 sql_help.c:1454 sql_help.c:1517 +#: sql_help.c:1626 sql_help.c:2853 +msgid "new_owner" +msgstr "yeni_sahibi" + +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:449 sql_help.c:534 sql_help.c:667 sql_help.c:708 sql_help.c:736 +#: sql_help.c:791 sql_help.c:855 sql_help.c:993 sql_help.c:1060 sql_help.c:1093 +#: sql_help.c:1268 sql_help.c:1435 sql_help.c:1456 sql_help.c:1468 +#: sql_help.c:1480 sql_help.c:1524 sql_help.c:1630 +msgid "new_schema" +msgstr "yeni_ÅŸema" + +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3178 sql_help.c:4156 +msgid "where aggregate_signature is:" +msgstr "aggregate_imzası ÅŸu ÅŸekilde olabilir:" + +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:837 +#: sql_help.c:842 sql_help.c:847 sql_help.c:852 sql_help.c:857 sql_help.c:975 +#: sql_help.c:980 sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2276 sql_help.c:2473 sql_help.c:3179 sql_help.c:3182 +#: sql_help.c:3185 sql_help.c:3270 sql_help.c:3359 sql_help.c:3387 +#: sql_help.c:3705 sql_help.c:4038 sql_help.c:4133 sql_help.c:4140 +#: sql_help.c:4146 sql_help.c:4157 sql_help.c:4160 sql_help.c:4163 +msgid "argmode" +msgstr "" + +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2277 sql_help.c:2474 sql_help.c:3180 sql_help.c:3183 +#: sql_help.c:3186 sql_help.c:3271 sql_help.c:3360 sql_help.c:3388 +#: sql_help.c:4134 sql_help.c:4141 sql_help.c:4147 sql_help.c:4158 +#: sql_help.c:4161 sql_help.c:4164 +msgid "argname" +msgstr "bağımsız deÄŸiÅŸken adı" + +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2278 sql_help.c:2475 sql_help.c:3181 +#: sql_help.c:3184 sql_help.c:3187 sql_help.c:3272 sql_help.c:3361 +#: sql_help.c:3389 sql_help.c:4135 sql_help.c:4142 sql_help.c:4148 +#: sql_help.c:4159 sql_help.c:4162 sql_help.c:4165 +#, fuzzy +msgid "argtype" +msgstr "Hedef tipi" + +#: sql_help.c:112 sql_help.c:394 sql_help.c:472 sql_help.c:484 sql_help.c:925 +#: sql_help.c:1073 sql_help.c:1449 sql_help.c:1573 sql_help.c:1605 +#: sql_help.c:1652 sql_help.c:1889 sql_help.c:1895 sql_help.c:2186 +#: sql_help.c:2227 sql_help.c:2234 sql_help.c:2243 sql_help.c:2317 +#: sql_help.c:2526 sql_help.c:2618 sql_help.c:2882 sql_help.c:3063 +#: sql_help.c:3085 sql_help.c:3572 sql_help.c:3739 sql_help.c:4588 +msgid "option" +msgstr "seçenek" + +#: sql_help.c:113 sql_help.c:926 sql_help.c:1574 sql_help.c:2318 +#: sql_help.c:2527 sql_help.c:3064 +msgid "where option can be:" +msgstr "seçenek ÅŸunlar olabilir:" + +#: sql_help.c:114 sql_help.c:2118 +msgid "allowconn" +msgstr "" + +#: sql_help.c:115 sql_help.c:927 sql_help.c:1575 sql_help.c:2119 +#: sql_help.c:2528 sql_help.c:3065 +#, fuzzy +msgid "connlimit" +msgstr "sınırsız" + +#: sql_help.c:116 sql_help.c:2120 +#, fuzzy +msgid "istemplate" +msgstr "Åžablon" + +#: sql_help.c:122 sql_help.c:605 sql_help.c:670 sql_help.c:1271 sql_help.c:1319 +msgid "new_tablespace" +msgstr "yeni_tablespace" + +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:543 sql_help.c:545 +#: sql_help.c:546 sql_help.c:862 sql_help.c:864 sql_help.c:865 sql_help.c:934 +#: sql_help.c:938 sql_help.c:941 sql_help.c:1002 sql_help.c:1004 +#: sql_help.c:1005 sql_help.c:1136 sql_help.c:1139 sql_help.c:1582 +#: sql_help.c:1586 sql_help.c:1589 sql_help.c:2287 sql_help.c:2479 +#: sql_help.c:3925 sql_help.c:4330 +msgid "configuration_parameter" +msgstr "yapılandırma_parametresi" + +#: sql_help.c:125 sql_help.c:395 sql_help.c:467 sql_help.c:473 sql_help.c:485 +#: sql_help.c:544 sql_help.c:597 sql_help.c:676 sql_help.c:682 sql_help.c:863 +#: sql_help.c:886 sql_help.c:935 sql_help.c:1003 sql_help.c:1074 +#: sql_help.c:1113 sql_help.c:1116 sql_help.c:1121 sql_help.c:1137 +#: sql_help.c:1138 sql_help.c:1301 sql_help.c:1321 sql_help.c:1371 +#: sql_help.c:1393 sql_help.c:1450 sql_help.c:1583 sql_help.c:1606 +#: sql_help.c:2187 sql_help.c:2228 sql_help.c:2235 sql_help.c:2244 +#: sql_help.c:2288 sql_help.c:2289 sql_help.c:2348 sql_help.c:2380 +#: sql_help.c:2480 sql_help.c:2481 sql_help.c:2498 sql_help.c:2619 +#: sql_help.c:2649 sql_help.c:2749 sql_help.c:2761 sql_help.c:2774 +#: sql_help.c:2817 sql_help.c:2839 sql_help.c:2856 sql_help.c:2883 +#: sql_help.c:3086 sql_help.c:3740 sql_help.c:4331 sql_help.c:4332 +msgid "value" +msgstr "deÄŸer" + +#: sql_help.c:197 +msgid "target_role" +msgstr "hedef_rol" + +#: sql_help.c:198 sql_help.c:2170 sql_help.c:2574 sql_help.c:2579 +#: sql_help.c:3687 sql_help.c:3694 sql_help.c:3708 sql_help.c:3714 +#: sql_help.c:4020 sql_help.c:4027 sql_help.c:4041 sql_help.c:4047 +msgid "schema_name" +msgstr "ÅŸema_adı" + +#: sql_help.c:199 +msgid "abbreviated_grant_or_revoke" +msgstr "" + +#: sql_help.c:200 +msgid "where abbreviated_grant_or_revoke is one of:" +msgstr "" + +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:568 sql_help.c:604 sql_help.c:669 sql_help.c:809 sql_help.c:945 +#: sql_help.c:1270 sql_help.c:1593 sql_help.c:2321 sql_help.c:2322 +#: sql_help.c:2323 sql_help.c:2324 sql_help.c:2325 sql_help.c:2454 +#: sql_help.c:2531 sql_help.c:2532 sql_help.c:2533 sql_help.c:2534 +#: sql_help.c:2535 sql_help.c:3068 sql_help.c:3069 sql_help.c:3070 +#: sql_help.c:3071 sql_help.c:3072 sql_help.c:3721 sql_help.c:3722 +#: sql_help.c:3723 sql_help.c:4021 sql_help.c:4025 sql_help.c:4028 +#: sql_help.c:4030 sql_help.c:4032 sql_help.c:4034 sql_help.c:4036 +#: sql_help.c:4042 sql_help.c:4044 sql_help.c:4046 sql_help.c:4048 +#: sql_help.c:4050 sql_help.c:4052 sql_help.c:4053 sql_help.c:4054 +#: sql_help.c:4351 +msgid "role_name" +msgstr "rol_adı" + +#: sql_help.c:236 sql_help.c:460 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1339 sql_help.c:1350 sql_help.c:1375 sql_help.c:1622 +#: sql_help.c:2139 sql_help.c:2143 sql_help.c:2247 sql_help.c:2251 +#: sql_help.c:2343 sql_help.c:2745 sql_help.c:2757 sql_help.c:2770 +#: sql_help.c:2778 sql_help.c:2789 sql_help.c:2821 sql_help.c:3771 +#: sql_help.c:3786 sql_help.c:3788 sql_help.c:4216 sql_help.c:4217 +#: sql_help.c:4226 sql_help.c:4267 sql_help.c:4268 sql_help.c:4269 +#: sql_help.c:4270 sql_help.c:4271 sql_help.c:4272 sql_help.c:4305 +#: sql_help.c:4306 sql_help.c:4311 sql_help.c:4316 sql_help.c:4455 +#: sql_help.c:4456 sql_help.c:4465 sql_help.c:4506 sql_help.c:4507 +#: sql_help.c:4508 sql_help.c:4509 sql_help.c:4510 sql_help.c:4511 +#: sql_help.c:4558 sql_help.c:4560 sql_help.c:4606 sql_help.c:4662 +#: sql_help.c:4663 sql_help.c:4672 sql_help.c:4713 sql_help.c:4714 +#: sql_help.c:4715 sql_help.c:4716 sql_help.c:4717 sql_help.c:4718 +msgid "expression" +msgstr "ifade" + +#: sql_help.c:239 +msgid "domain_constraint" +msgstr "alan(domain)_kısıtlaması" + +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:475 sql_help.c:476 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1338 sql_help.c:1349 sql_help.c:1366 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2142 sql_help.c:2246 sql_help.c:2250 +#: sql_help.c:2777 sql_help.c:2788 sql_help.c:3783 +msgid "constraint_name" +msgstr "%kısıtlama_adı" + +#: sql_help.c:244 sql_help.c:1264 +msgid "new_constraint_name" +msgstr "yeni_kısıtlama_adı" + +#: sql_help.c:317 sql_help.c:1072 +msgid "new_version" +msgstr "yeni_sürüm" + +#: sql_help.c:321 sql_help.c:323 +msgid "member_object" +msgstr "üye_nesnesi" + +#: sql_help.c:324 +msgid "where member_object is:" +msgstr "" + +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4123 sql_help.c:4128 +#: sql_help.c:4129 sql_help.c:4130 sql_help.c:4131 sql_help.c:4137 +#: sql_help.c:4138 sql_help.c:4143 sql_help.c:4144 sql_help.c:4149 +#: sql_help.c:4150 sql_help.c:4151 sql_help.c:4152 sql_help.c:4153 +#: sql_help.c:4154 +msgid "object_name" +msgstr "nesne_adı" + +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4126 +msgid "aggregate_name" +msgstr "toplam(aggregate)_adı" + +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3195 +#, fuzzy +msgid "source_type" +msgstr "Kaynak tipi" + +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3196 +#, fuzzy +msgid "target_type" +msgstr "Hedef tipi" + +#: sql_help.c:336 sql_help.c:773 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2094 sql_help.c:2157 sql_help.c:2397 sql_help.c:2428 +#: sql_help.c:2959 sql_help.c:4037 sql_help.c:4132 sql_help.c:4245 +#: sql_help.c:4249 sql_help.c:4253 sql_help.c:4256 sql_help.c:4484 +#: sql_help.c:4488 sql_help.c:4492 sql_help.c:4495 sql_help.c:4691 +#: sql_help.c:4695 sql_help.c:4699 sql_help.c:4702 +msgid "function_name" +msgstr "fonksiyon_adı" + +#: sql_help.c:341 sql_help.c:766 sql_help.c:1792 sql_help.c:2421 +msgid "operator_name" +msgstr "operatör_adı" + +#: sql_help.c:342 sql_help.c:702 sql_help.c:706 sql_help.c:710 sql_help.c:1793 +#: sql_help.c:2398 sql_help.c:3313 +msgid "left_type" +msgstr "sol_argüman_veri_tipi" + +#: sql_help.c:343 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1794 +#: sql_help.c:2399 sql_help.c:3314 +#, fuzzy +msgid "right_type" +msgstr "SaÄŸ argüman veri tipi" + +#: sql_help.c:345 sql_help.c:347 sql_help.c:729 sql_help.c:732 sql_help.c:735 +#: sql_help.c:764 sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 +#: sql_help.c:1355 sql_help.c:1796 sql_help.c:1798 sql_help.c:2418 +#: sql_help.c:2439 sql_help.c:2794 sql_help.c:3323 sql_help.c:3332 +msgid "index_method" +msgstr "index_yöntemi" + +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4139 +msgid "procedure_name" +msgstr "prosedür_adı" + +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3704 sql_help.c:4145 +#, fuzzy +#| msgid "role_name" +msgid "routine_name" +msgstr "rol_adı" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2284 +#: sql_help.c:2478 sql_help.c:2752 sql_help.c:2926 sql_help.c:3494 +#: sql_help.c:3718 sql_help.c:4051 +msgid "type_name" +msgstr "tip_adı" + +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2283 sql_help.c:2477 +#: sql_help.c:2927 sql_help.c:3153 sql_help.c:3495 sql_help.c:3710 +#: sql_help.c:4043 +msgid "lang_name" +msgstr "dil_adı" + +#: sql_help.c:369 +msgid "and aggregate_signature is:" +msgstr "" + +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2184 +msgid "handler_function" +msgstr "iÅŸleyici_fonksiyon" + +#: sql_help.c:393 sql_help.c:2185 +msgid "validator_function" +msgstr "doÄŸrulayıcı_fonksiyon" + +#: sql_help.c:442 sql_help.c:519 sql_help.c:658 sql_help.c:840 sql_help.c:978 +#: sql_help.c:1258 sql_help.c:1346 sql_help.c:1347 sql_help.c:1363 +#: sql_help.c:1364 sql_help.c:1515 sql_help.c:2785 sql_help.c:2786 +#: sql_help.c:2802 sql_help.c:2803 +msgid "action" +msgstr "hareket" + +#: sql_help.c:444 sql_help.c:451 sql_help.c:455 sql_help.c:456 sql_help.c:459 +#: sql_help.c:461 sql_help.c:462 sql_help.c:463 sql_help.c:465 sql_help.c:468 +#: sql_help.c:470 sql_help.c:471 sql_help.c:662 sql_help.c:672 sql_help.c:674 +#: sql_help.c:677 sql_help.c:679 sql_help.c:1054 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1351 sql_help.c:1353 sql_help.c:1360 +#: sql_help.c:1369 sql_help.c:1374 sql_help.c:1621 sql_help.c:1624 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1891 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2225 +#: sql_help.c:2238 sql_help.c:2281 sql_help.c:2342 sql_help.c:2346 +#: sql_help.c:2378 sql_help.c:2604 sql_help.c:2632 sql_help.c:2633 +#: sql_help.c:2736 sql_help.c:2744 sql_help.c:2753 sql_help.c:2756 +#: sql_help.c:2765 sql_help.c:2769 sql_help.c:2790 sql_help.c:2792 +#: sql_help.c:2799 sql_help.c:2815 sql_help.c:2820 sql_help.c:2837 +#: sql_help.c:2962 sql_help.c:3098 sql_help.c:3689 sql_help.c:3690 +#: sql_help.c:3770 sql_help.c:3785 sql_help.c:3787 sql_help.c:3789 +#: sql_help.c:4022 sql_help.c:4023 sql_help.c:4125 sql_help.c:4276 +#: sql_help.c:4515 sql_help.c:4557 sql_help.c:4559 sql_help.c:4561 +#: sql_help.c:4594 sql_help.c:4722 +msgid "column_name" +msgstr "sütun_adı" + +#: sql_help.c:445 sql_help.c:663 sql_help.c:1261 +msgid "new_column_name" +msgstr "yeni_sütun_adı" + +#: sql_help.c:450 sql_help.c:540 sql_help.c:671 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1277 sql_help.c:1531 +msgid "where action is one of:" +msgstr "hareket aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:452 sql_help.c:457 sql_help.c:1046 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1533 sql_help.c:1537 sql_help.c:2137 +#: sql_help.c:2226 sql_help.c:2417 sql_help.c:2597 sql_help.c:2737 +#: sql_help.c:3007 sql_help.c:3872 +msgid "data_type" +msgstr "veri_tipi" + +#: sql_help.c:453 sql_help.c:458 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1534 sql_help.c:1538 sql_help.c:2138 sql_help.c:2229 +#: sql_help.c:2344 sql_help.c:2738 sql_help.c:2746 sql_help.c:2758 +#: sql_help.c:2771 sql_help.c:3008 sql_help.c:3014 sql_help.c:3780 +msgid "collation" +msgstr "sıralama (collation)" + +#: sql_help.c:454 sql_help.c:1281 sql_help.c:2230 sql_help.c:2239 +#: sql_help.c:2739 sql_help.c:2754 sql_help.c:2766 +msgid "column_constraint" +msgstr "kolon_kısıtlaması" + +#: sql_help.c:464 sql_help.c:602 sql_help.c:673 sql_help.c:1298 +msgid "integer" +msgstr "tamsayı" + +#: sql_help.c:466 sql_help.c:469 sql_help.c:675 sql_help.c:678 sql_help.c:1300 +#: sql_help.c:1303 +msgid "attribute_option" +msgstr "özellik_seçeneÄŸi" + +#: sql_help.c:474 sql_help.c:1305 sql_help.c:2231 sql_help.c:2240 +#: sql_help.c:2740 sql_help.c:2755 sql_help.c:2767 +msgid "table_constraint" +msgstr "tablo_kısıtlaması" + +#: sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:480 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 +msgid "trigger_name" +msgstr "tetikleyici_adı" + +#: sql_help.c:481 sql_help.c:482 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2232 sql_help.c:2237 sql_help.c:2743 sql_help.c:2764 +msgid "parent_table" +msgstr "üst_tablo" + +#: sql_help.c:539 sql_help.c:594 sql_help.c:660 sql_help.c:860 sql_help.c:998 +#: sql_help.c:1494 sql_help.c:2169 +msgid "extension_name" +msgstr "uzantı_adı" + +#: sql_help.c:541 sql_help.c:1000 sql_help.c:2285 +msgid "execution_cost" +msgstr "execution_cost" + +#: sql_help.c:542 sql_help.c:1001 sql_help.c:2286 +msgid "result_rows" +msgstr "sonuç_satırları" + +#: sql_help.c:563 sql_help.c:565 sql_help.c:924 sql_help.c:932 sql_help.c:936 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1572 sql_help.c:1580 +#: sql_help.c:1584 sql_help.c:1587 sql_help.c:1590 sql_help.c:2575 +#: sql_help.c:2577 sql_help.c:2580 sql_help.c:2581 sql_help.c:3688 +#: sql_help.c:3692 sql_help.c:3695 sql_help.c:3697 sql_help.c:3699 +#: sql_help.c:3701 sql_help.c:3703 sql_help.c:3709 sql_help.c:3711 +#: sql_help.c:3713 sql_help.c:3715 sql_help.c:3717 sql_help.c:3719 +msgid "role_specification" +msgstr "rol_tanımlaması" + +#: sql_help.c:564 sql_help.c:566 sql_help.c:1603 sql_help.c:2112 +#: sql_help.c:2583 sql_help.c:3083 sql_help.c:3528 sql_help.c:4361 +msgid "user_name" +msgstr "kullanıcı_adı" + +#: sql_help.c:567 sql_help.c:944 sql_help.c:1592 sql_help.c:2582 +#: sql_help.c:3720 +msgid "where role_specification can be:" +msgstr "rol tanımlaması ÅŸunlar olabilir:" + +#: sql_help.c:569 +msgid "group_name" +msgstr "grup_adı" + +#: sql_help.c:590 sql_help.c:1372 sql_help.c:2117 sql_help.c:2349 +#: sql_help.c:2381 sql_help.c:2750 sql_help.c:2762 sql_help.c:2775 +#: sql_help.c:2818 sql_help.c:2840 sql_help.c:2852 sql_help.c:3716 +#: sql_help.c:4049 +msgid "tablespace_name" +msgstr "tablespace_adı" + +#: sql_help.c:592 sql_help.c:680 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1367 sql_help.c:1707 +msgid "index_name" +msgstr "index_adı" + +#: sql_help.c:596 sql_help.c:599 sql_help.c:681 sql_help.c:683 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1370 sql_help.c:2347 sql_help.c:2379 +#: sql_help.c:2748 sql_help.c:2760 sql_help.c:2773 sql_help.c:2816 +#: sql_help.c:2838 +msgid "storage_parameter" +msgstr "saklama_parametresi" + +#: sql_help.c:601 +msgid "column_number" +msgstr "sütun_sayısı" + +#: sql_help.c:625 sql_help.c:1790 sql_help.c:4136 +msgid "large_object_oid" +msgstr "büyük_nesne_oid" + +#: sql_help.c:712 sql_help.c:2402 +msgid "res_proc" +msgstr "res_proc" + +#: sql_help.c:713 sql_help.c:2403 +msgid "join_proc" +msgstr "join_proc" + +#: sql_help.c:765 sql_help.c:777 sql_help.c:2420 +msgid "strategy_number" +msgstr "strateji_sayısı" + +#: sql_help.c:767 sql_help.c:768 sql_help.c:771 sql_help.c:772 sql_help.c:778 +#: sql_help.c:779 sql_help.c:781 sql_help.c:782 sql_help.c:2422 sql_help.c:2423 +#: sql_help.c:2426 sql_help.c:2427 +msgid "op_type" +msgstr "operatör_tipi" + +#: sql_help.c:769 sql_help.c:2424 +msgid "sort_family_name" +msgstr "sıralama_family_adı" + +#: sql_help.c:770 sql_help.c:780 sql_help.c:2425 +msgid "support_number" +msgstr "destek_numarası" + +#: sql_help.c:774 sql_help.c:2056 sql_help.c:2429 sql_help.c:2929 +#: sql_help.c:2931 +msgid "argument_type" +msgstr "bağımsız_deÄŸiÅŸken_tipi" + +#: sql_help.c:805 sql_help.c:808 sql_help.c:879 sql_help.c:881 sql_help.c:883 +#: sql_help.c:1014 sql_help.c:1053 sql_help.c:1490 sql_help.c:1493 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1890 +#: sql_help.c:2224 sql_help.c:2236 sql_help.c:2340 sql_help.c:2377 +#: sql_help.c:2453 sql_help.c:2496 sql_help.c:2552 sql_help.c:2603 +#: sql_help.c:2634 sql_help.c:2735 sql_help.c:2751 sql_help.c:2763 +#: sql_help.c:2836 sql_help.c:2955 sql_help.c:3132 sql_help.c:3349 +#: sql_help.c:3398 sql_help.c:3504 sql_help.c:3686 sql_help.c:3691 +#: sql_help.c:3736 sql_help.c:3768 sql_help.c:4019 sql_help.c:4024 +#: sql_help.c:4124 sql_help.c:4231 sql_help.c:4233 sql_help.c:4282 +#: sql_help.c:4321 sql_help.c:4470 sql_help.c:4472 sql_help.c:4521 +#: sql_help.c:4555 sql_help.c:4593 sql_help.c:4677 sql_help.c:4679 +#: sql_help.c:4728 +msgid "table_name" +msgstr "tablo_adı" + +#: sql_help.c:810 sql_help.c:2455 +msgid "using_expression" +msgstr "using_ifadesi" + +#: sql_help.c:811 sql_help.c:2456 +msgid "check_expression" +msgstr "check_ifadesi" + +#: sql_help.c:885 sql_help.c:2497 +msgid "publication_parameter" +msgstr "yayın_parametresi" + +#: sql_help.c:928 sql_help.c:1576 sql_help.c:2319 sql_help.c:2529 +#: sql_help.c:3066 +msgid "password" +msgstr "parola" + +#: sql_help.c:929 sql_help.c:1577 sql_help.c:2320 sql_help.c:2530 +#: sql_help.c:3067 +msgid "timestamp" +msgstr "timestamp" + +#: sql_help.c:933 sql_help.c:937 sql_help.c:940 sql_help.c:943 sql_help.c:1581 +#: sql_help.c:1585 sql_help.c:1588 sql_help.c:1591 sql_help.c:3696 +#: sql_help.c:4029 +msgid "database_name" +msgstr "veritabanı_adı" + +#: sql_help.c:1047 sql_help.c:2598 +msgid "increment" +msgstr "artım" + +#: sql_help.c:1048 sql_help.c:2599 +msgid "minvalue" +msgstr "en düşük deÄŸer" + +#: sql_help.c:1049 sql_help.c:2600 +msgid "maxvalue" +msgstr "en yüksek deÄŸer" + +#: sql_help.c:1050 sql_help.c:2601 sql_help.c:4229 sql_help.c:4319 +#: sql_help.c:4468 sql_help.c:4610 sql_help.c:4675 +msgid "start" +msgstr "baÅŸlat" + +#: sql_help.c:1051 sql_help.c:1295 +msgid "restart" +msgstr "yeniden baÅŸlat" + +#: sql_help.c:1052 sql_help.c:2602 +msgid "cache" +msgstr "önbellek" + +#: sql_help.c:1109 sql_help.c:2646 +msgid "conninfo" +msgstr "conninfo" + +#: sql_help.c:1111 sql_help.c:2647 +msgid "publication_name" +msgstr "yayın_adı" + +#: sql_help.c:1112 +#, fuzzy +msgid "set_publication_option" +msgstr "set_publication_option" + +#: sql_help.c:1115 +msgid "refresh_option" +msgstr "tazeleme_seçeneÄŸi" + +#: sql_help.c:1120 sql_help.c:2648 +msgid "subscription_parameter" +msgstr "abonelik_parametresi" + +#: sql_help.c:1273 sql_help.c:1276 +msgid "partition_name" +msgstr "bölümleme(partition)_adı" + +#: sql_help.c:1274 sql_help.c:2241 sql_help.c:2768 +msgid "partition_bound_spec" +msgstr "" + +#: sql_help.c:1292 sql_help.c:1341 sql_help.c:2780 +msgid "sequence_options" +msgstr "sequence_seçenekleri" + +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "sequence_seçeneÄŸi" + +#: sql_help.c:1306 +msgid "table_constraint_using_index" +msgstr "ve indeks_kullanan_tablo_kısıtlaması şöyledir:" + +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 +msgid "rewrite_rule_name" +msgstr "rewrite_kural_adı" + +#: sql_help.c:1328 sql_help.c:2805 +msgid "and partition_bound_spec is:" +msgstr "ve partition_bound_spec şöyledir:" + +#: sql_help.c:1329 sql_help.c:1331 sql_help.c:1333 sql_help.c:1335 +#: sql_help.c:1336 sql_help.c:2806 sql_help.c:2808 sql_help.c:2810 +#: sql_help.c:2812 sql_help.c:2813 +msgid "numeric_literal" +msgstr "sayısal_sabit" + +#: sql_help.c:1330 sql_help.c:1332 sql_help.c:1334 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2811 +msgid "string_literal" +msgstr "dizgi_sabiti" + +#: sql_help.c:1337 +msgid "and column_constraint is:" +msgstr "ve kolon_kısıtlaması şöyledir :" + +#: sql_help.c:1340 sql_help.c:2248 sql_help.c:2279 sql_help.c:2476 +#: sql_help.c:2779 +msgid "default_expr" +msgstr "öntanımlı_ifade" + +#: sql_help.c:1342 sql_help.c:1343 sql_help.c:1352 sql_help.c:1354 +#: sql_help.c:1358 sql_help.c:2781 sql_help.c:2782 sql_help.c:2791 +#: sql_help.c:2793 sql_help.c:2797 +msgid "index_parameters" +msgstr "indeks_parametreleri" + +#: sql_help.c:1344 sql_help.c:1361 sql_help.c:2783 sql_help.c:2800 +msgid "reftable" +msgstr "referans tablosu" + +#: sql_help.c:1345 sql_help.c:1362 sql_help.c:2784 sql_help.c:2801 +msgid "refcolumn" +msgstr "referans kolonu" + +#: sql_help.c:1348 sql_help.c:2249 sql_help.c:2787 +msgid "and table_constraint is:" +msgstr "ve tablo_kısıtlaması şöyledir:" + +#: sql_help.c:1356 sql_help.c:2795 +msgid "exclude_element" +msgstr "hariçtutma(ecxlude)_öğesi" + +#: sql_help.c:1357 sql_help.c:2796 sql_help.c:4227 sql_help.c:4317 +#: sql_help.c:4466 sql_help.c:4608 sql_help.c:4673 +msgid "operator" +msgstr "operatör" + +#: sql_help.c:1359 sql_help.c:2350 sql_help.c:2798 +msgid "predicate" +msgstr "yüklem (predicate)" + +#: sql_help.c:1365 +msgid "and table_constraint_using_index is:" +msgstr "ve indeks_kullanan_tablo_kısıtlaması şöyledir:" + +#: sql_help.c:1368 sql_help.c:2814 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "UNIQUE, PRIMARY KEY ve EXCLUDE kısıtlamalarında index_parametreleri ÅŸunlar olabilir:" + +#: sql_help.c:1373 sql_help.c:2819 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "" + +#: sql_help.c:1376 sql_help.c:2345 sql_help.c:2747 sql_help.c:2759 +#: sql_help.c:2772 sql_help.c:2822 sql_help.c:3781 +msgid "opclass" +msgstr "opclass" + +#: sql_help.c:1392 sql_help.c:1395 sql_help.c:2855 +msgid "tablespace_option" +msgstr "tablespace_seçeneÄŸi" + +#: sql_help.c:1416 sql_help.c:1419 sql_help.c:1425 sql_help.c:1429 +msgid "token_type" +msgstr "token_tipi" + +#: sql_help.c:1417 sql_help.c:1420 +msgid "dictionary_name" +msgstr "sözlük_adı" + +#: sql_help.c:1422 sql_help.c:1426 +msgid "old_dictionary" +msgstr "eski_sözlük" + +#: sql_help.c:1423 sql_help.c:1427 +msgid "new_dictionary" +msgstr "yeni_sözlük" + +#: sql_help.c:1519 sql_help.c:1532 sql_help.c:1535 sql_help.c:1536 +#: sql_help.c:3006 +msgid "attribute_name" +msgstr "özellik_adı" + +#: sql_help.c:1520 +msgid "new_attribute_name" +msgstr "yeni_özellik_adı" + +#: sql_help.c:1526 sql_help.c:1530 +msgid "new_enum_value" +msgstr "yeni_enum_deÄŸeri" + +#: sql_help.c:1527 +msgid "neighbor_enum_value" +msgstr "komÅŸu_enum_deÄŸeri" + +#: sql_help.c:1529 +msgid "existing_enum_value" +msgstr "mevcut_enum_deÄŸeri" + +#: sql_help.c:1604 sql_help.c:2233 sql_help.c:2242 sql_help.c:2614 +#: sql_help.c:3084 sql_help.c:3529 sql_help.c:3702 sql_help.c:3737 +#: sql_help.c:4035 +msgid "server_name" +msgstr "sunucu_adı" + +#: sql_help.c:1632 sql_help.c:1635 sql_help.c:3099 +msgid "view_option_name" +msgstr "seçenek_adı_görüntüle" + +#: sql_help.c:1633 sql_help.c:3100 +msgid "view_option_value" +msgstr "seçenek_deÄŸeri_görüntüle" + +#: sql_help.c:1653 sql_help.c:1654 sql_help.c:4589 sql_help.c:4590 +msgid "table_and_columns" +msgstr "tablolar_ve_sütunlar" + +#: sql_help.c:1655 sql_help.c:1896 sql_help.c:3575 sql_help.c:4591 +msgid "where option can be one of:" +msgstr "seçenek aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:1656 sql_help.c:4592 +msgid "and table_and_columns is:" +msgstr "ve tablolar_ve_sütunlar şöyledir:" + +#: sql_help.c:1672 sql_help.c:4377 sql_help.c:4379 sql_help.c:4403 +msgid "transaction_mode" +msgstr "transaction_modu" + +#: sql_help.c:1673 sql_help.c:4380 sql_help.c:4404 +msgid "where transaction_mode is one of:" +msgstr "transaction_modu aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:1682 sql_help.c:4237 sql_help.c:4246 sql_help.c:4250 +#: sql_help.c:4254 sql_help.c:4257 sql_help.c:4476 sql_help.c:4485 +#: sql_help.c:4489 sql_help.c:4493 sql_help.c:4496 sql_help.c:4683 +#: sql_help.c:4692 sql_help.c:4696 sql_help.c:4700 sql_help.c:4703 +msgid "argument" +msgstr "bağımsız deÄŸiÅŸken" + +#: sql_help.c:1772 +msgid "relation_name" +msgstr "nesne_adı" + +#: sql_help.c:1777 sql_help.c:3698 sql_help.c:4031 +msgid "domain_name" +msgstr "domain_adı" + +#: sql_help.c:1799 +msgid "policy_name" +msgstr "ilke(policy)_adı" + +#: sql_help.c:1812 +msgid "rule_name" +msgstr "kural_adı" + +#: sql_help.c:1831 +msgid "text" +msgstr "metin" + +#: sql_help.c:1856 sql_help.c:3881 sql_help.c:4069 +msgid "transaction_id" +msgstr "iÅŸlem(transaction)_id" + +#: sql_help.c:1887 sql_help.c:1893 sql_help.c:3807 +msgid "filename" +msgstr "dosyaadı" + +#: sql_help.c:1888 sql_help.c:1894 sql_help.c:2554 sql_help.c:2555 +#: sql_help.c:2556 +msgid "command" +msgstr "komut" + +#: sql_help.c:1892 sql_help.c:2382 sql_help.c:2841 sql_help.c:3101 +#: sql_help.c:3119 sql_help.c:3772 +msgid "query" +msgstr "sorgu" + +#: sql_help.c:1897 +msgid "format_name" +msgstr "biçim(format)_adı" + +#: sql_help.c:1898 sql_help.c:1899 sql_help.c:1902 sql_help.c:3576 +#: sql_help.c:3577 sql_help.c:3578 sql_help.c:3579 sql_help.c:3580 +#: sql_help.c:3581 +msgid "boolean" +msgstr "boolean" + +#: sql_help.c:1900 +msgid "delimiter_character" +msgstr "ayrıştırıcı_karakteri" + +#: sql_help.c:1901 +msgid "null_string" +msgstr "null_dizi" + +#: sql_help.c:1903 +msgid "quote_character" +msgstr " quote_karakteri" + +#: sql_help.c:1904 +msgid "escape_character" +msgstr "kaçış(escape)_karakteri" + +#: sql_help.c:1908 +msgid "encoding_name" +msgstr "dilkodlaması_adı" + +#: sql_help.c:1919 +msgid "access_method_type" +msgstr "eriÅŸim_yöntemi_tipi" + +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 +msgid "arg_data_type" +msgstr "arg_veri_tipi" + +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 +msgid "sfunc" +msgstr "sfunc" + +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 +msgid "state_data_type" +msgstr "durum(state)_veri_tipi" + +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 +msgid "state_data_size" +msgstr "durum(state)_veri_boyutu" + +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 +msgid "ffunc" +msgstr "ffunc" + +#: sql_help.c:1995 sql_help.c:2025 +msgid "combinefunc" +msgstr "" + +#: sql_help.c:1996 sql_help.c:2026 +msgid "serialfunc" +msgstr "serialfunc" + +#: sql_help.c:1997 sql_help.c:2027 +msgid "deserialfunc" +msgstr "deserialfunc" + +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 +msgid "initial_condition" +msgstr "ilk_durum" + +#: sql_help.c:1999 sql_help.c:2029 +msgid "msfunc" +msgstr "msfunc" + +#: sql_help.c:2000 sql_help.c:2030 +msgid "minvfunc" +msgstr "en düşük deÄŸer fonksiyonu (minvfunc)" + +#: sql_help.c:2001 sql_help.c:2031 +msgid "mstate_data_type" +msgstr "mstate_veri_tipi" + +#: sql_help.c:2002 sql_help.c:2032 +msgid "mstate_data_size" +msgstr "mstate_veri_boyutu" + +#: sql_help.c:2003 sql_help.c:2033 +msgid "mffunc" +msgstr "mffunc" + +#: sql_help.c:2004 sql_help.c:2034 +#, fuzzy +#| msgid "initial_condition" +msgid "minitial_condition" +msgstr "ilk_durum" + +#: sql_help.c:2005 sql_help.c:2035 +msgid "sort_operator" +msgstr "sıralama(sort)_operatörü" + +#: sql_help.c:2018 +msgid "or the old syntax" +msgstr "ya da eski sözdizimi" + +#: sql_help.c:2020 +#, fuzzy +msgid "base_type" +msgstr "Hedef tipi" + +#: sql_help.c:2076 +msgid "locale" +msgstr "yerel ayar" + +#: sql_help.c:2077 sql_help.c:2115 +msgid "lc_collate" +msgstr "lc_collate" + +#: sql_help.c:2078 sql_help.c:2116 +msgid "lc_ctype" +msgstr "lc_ctype" + +#: sql_help.c:2079 sql_help.c:4122 +msgid "provider" +msgstr "saÄŸlayıcı" + +#: sql_help.c:2080 sql_help.c:2171 +msgid "version" +msgstr "sürüm" + +#: sql_help.c:2082 +msgid "existing_collation" +msgstr "mevcut_sıralama(collation)" + +#: sql_help.c:2092 +msgid "source_encoding" +msgstr "kaynak_dil kodlaması" + +#: sql_help.c:2093 +msgid "dest_encoding" +msgstr "hedef_dil kodlaması" + +#: sql_help.c:2113 sql_help.c:2881 +msgid "template" +msgstr "ÅŸablon" + +#: sql_help.c:2114 +msgid "encoding" +msgstr "dil kodlaması" + +#: sql_help.c:2140 +msgid "constraint" +msgstr "kısıtlama" + +#: sql_help.c:2141 +msgid "where constraint is:" +msgstr "kısıtlama ÅŸu ÅŸekilde olabilir:" + +#: sql_help.c:2155 sql_help.c:2551 sql_help.c:2954 +msgid "event" +msgstr "olay" + +#: sql_help.c:2156 +msgid "filter_variable" +msgstr "filtre_deÄŸiÅŸkeni" + +#: sql_help.c:2172 +msgid "old_version" +msgstr "eski_sürüm" + +#: sql_help.c:2245 sql_help.c:2776 +msgid "where column_constraint is:" +msgstr "kolon_kısıtlaması aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:2280 +msgid "rettype" +msgstr "dönüş tipi" + +#: sql_help.c:2282 +msgid "column_type" +msgstr "kolon_tipi" + +#: sql_help.c:2290 sql_help.c:2482 +msgid "definition" +msgstr "tanımı" + +#: sql_help.c:2291 sql_help.c:2483 +msgid "obj_file" +msgstr "obj_file" + +#: sql_help.c:2292 sql_help.c:2484 +msgid "link_symbol" +msgstr "link_sembolü" + +#: sql_help.c:2326 sql_help.c:2536 sql_help.c:3073 +msgid "uid" +msgstr "kullanıcı numarası" + +#: sql_help.c:2341 +msgid "method" +msgstr "yöntem" + +#: sql_help.c:2362 +msgid "call_handler" +msgstr "call_handler" + +#: sql_help.c:2363 +msgid "inline_handler" +msgstr "inline_handler" + +#: sql_help.c:2364 +msgid "valfunction" +msgstr "valfunction" + +#: sql_help.c:2400 +msgid "com_op" +msgstr "com_op" + +#: sql_help.c:2401 +msgid "neg_op" +msgstr "neg_op" + +#: sql_help.c:2419 +msgid "family_name" +msgstr "family_name" + +#: sql_help.c:2430 +msgid "storage_type" +msgstr "saklama_tipi" + +#: sql_help.c:2553 sql_help.c:2958 sql_help.c:3135 sql_help.c:3791 +#: sql_help.c:4220 sql_help.c:4222 sql_help.c:4310 sql_help.c:4312 +#: sql_help.c:4459 sql_help.c:4461 sql_help.c:4564 sql_help.c:4666 +#: sql_help.c:4668 +msgid "condition" +msgstr "ÅŸart" + +#: sql_help.c:2557 sql_help.c:2961 +msgid "where event can be one of:" +msgstr "olay (event) aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:2576 sql_help.c:2578 +msgid "schema_element" +msgstr "ÅŸema_elemanı" + +#: sql_help.c:2615 +msgid "server_type" +msgstr "sunucu_tipi" + +#: sql_help.c:2616 +msgid "server_version" +msgstr "sunucu_sürümü" + +#: sql_help.c:2617 sql_help.c:3700 sql_help.c:4033 +msgid "fdw_name" +msgstr "fdw_adı" + +#: sql_help.c:2630 +msgid "statistics_name" +msgstr "istatistik_adı" + +#: sql_help.c:2631 +msgid "statistics_kind" +msgstr "istatistik_tipi" + +#: sql_help.c:2645 +msgid "subscription_name" +msgstr "abonelik_adı(subsciption)" + +#: sql_help.c:2741 +msgid "source_table" +msgstr "kaynak_tablo" + +#: sql_help.c:2742 +msgid "like_option" +msgstr "like_seçeneÄŸi" + +#: sql_help.c:2804 +msgid "and like_option is:" +msgstr "like_seçeneÄŸi ÅŸu olabilir:" + +#: sql_help.c:2854 +msgid "directory" +msgstr "dizin" + +#: sql_help.c:2868 +msgid "parser_name" +msgstr "ayrıştırıcı_adı" + +#: sql_help.c:2869 +msgid "source_config" +msgstr "source_config" + +#: sql_help.c:2898 +msgid "start_function" +msgstr "baÅŸlangıç_fonksiyonu" + +#: sql_help.c:2899 +msgid "gettoken_function" +msgstr "gettoken_fonksiyonu" + +#: sql_help.c:2900 +msgid "end_function" +msgstr "end_fonksiyonu" + +#: sql_help.c:2901 +msgid "lextypes_function" +msgstr "lextypes_fonksiyonu" + +#: sql_help.c:2902 +#, fuzzy +msgid "headline_function" +msgstr "fonksiyon" + +#: sql_help.c:2914 +msgid "init_function" +msgstr "ilkendirme_fonksiyonu" + +#: sql_help.c:2915 +msgid "lexize_function" +msgstr "lexize_fonksiyonu" + +#: sql_help.c:2928 +msgid "from_sql_function_name" +msgstr "from_sql_fonksiyon_adı" + +#: sql_help.c:2930 +msgid "to_sql_function_name" +msgstr "to_sql_fonksiyon_adı" + +#: sql_help.c:2956 +msgid "referenced_table_name" +msgstr "referans_edilen_tablo_adı" + +#: sql_help.c:2957 +#, fuzzy +msgid "transition_relation_name" +msgstr "dil_adı" + +#: sql_help.c:2960 +msgid "arguments" +msgstr "argümanlar" + +#: sql_help.c:3010 sql_help.c:4155 +msgid "label" +msgstr "etiket" + +#: sql_help.c:3012 +msgid "subtype" +msgstr "alttip" + +#: sql_help.c:3013 +msgid "subtype_operator_class" +msgstr "alttip_operatör_sınıfı" + +#: sql_help.c:3015 +msgid "canonical_function" +msgstr "canonical_fonksiyon" + +#: sql_help.c:3016 +msgid "subtype_diff_function" +msgstr "subtype-diff_fonksiyonu" + +#: sql_help.c:3018 +msgid "input_function" +msgstr "giriÅŸ_fonksiyonu" + +#: sql_help.c:3019 +msgid "output_function" +msgstr "çıktı_fonksiyonu" + +#: sql_help.c:3020 +msgid "receive_function" +msgstr "alma_fonksiyonu" + +#: sql_help.c:3021 +msgid "send_function" +msgstr "gönderme_fonksiyonu" + +#: sql_help.c:3022 +msgid "type_modifier_input_function" +msgstr "type_modifier_input_function" + +#: sql_help.c:3023 +msgid "type_modifier_output_function" +msgstr "type_modifier_output_function" + +#: sql_help.c:3024 +msgid "analyze_function" +msgstr "analiz_fonksiyonu" + +#: sql_help.c:3025 +msgid "internallength" +msgstr "internallength" + +#: sql_help.c:3026 +msgid "alignment" +msgstr "hizalama" + +#: sql_help.c:3027 +msgid "storage" +msgstr "saklama" + +#: sql_help.c:3028 +msgid "like_type" +msgstr "like_type" + +#: sql_help.c:3029 +msgid "category" +msgstr "category" + +#: sql_help.c:3030 +msgid "preferred" +msgstr "tercih edilen" + +#: sql_help.c:3031 +msgid "default" +msgstr "öntanımlı" + +#: sql_help.c:3032 +msgid "element" +msgstr "öğe" + +#: sql_help.c:3033 +msgid "delimiter" +msgstr "sınırlayıcı" + +#: sql_help.c:3034 +msgid "collatable" +msgstr "sıralanabilir" + +#: sql_help.c:3131 sql_help.c:3767 sql_help.c:4215 sql_help.c:4304 +#: sql_help.c:4454 sql_help.c:4554 sql_help.c:4661 +msgid "with_query" +msgstr "with_sorgusu" + +#: sql_help.c:3133 sql_help.c:3769 sql_help.c:4234 sql_help.c:4240 +#: sql_help.c:4243 sql_help.c:4247 sql_help.c:4251 sql_help.c:4259 +#: sql_help.c:4473 sql_help.c:4479 sql_help.c:4482 sql_help.c:4486 +#: sql_help.c:4490 sql_help.c:4498 sql_help.c:4556 sql_help.c:4680 +#: sql_help.c:4686 sql_help.c:4689 sql_help.c:4693 sql_help.c:4697 +#: sql_help.c:4705 +msgid "alias" +msgstr "takma ad" + +#: sql_help.c:3134 +msgid "using_list" +msgstr "using_list" + +#: sql_help.c:3136 sql_help.c:3607 sql_help.c:3848 sql_help.c:4565 +msgid "cursor_name" +msgstr "imleç_adı" + +#: sql_help.c:3137 sql_help.c:3775 sql_help.c:4566 +msgid "output_expression" +msgstr "çıktı_ifadesi" + +#: sql_help.c:3138 sql_help.c:3776 sql_help.c:4218 sql_help.c:4307 +#: sql_help.c:4457 sql_help.c:4567 sql_help.c:4664 +msgid "output_name" +msgstr "output_name" + +#: sql_help.c:3154 +msgid "code" +msgstr "kod" + +#: sql_help.c:3553 +msgid "parameter" +msgstr "deÄŸiÅŸken" + +#: sql_help.c:3573 sql_help.c:3574 sql_help.c:3873 +msgid "statement" +msgstr "ifade" + +#: sql_help.c:3606 sql_help.c:3847 +msgid "direction" +msgstr "yön" + +#: sql_help.c:3608 sql_help.c:3849 +msgid "where direction can be empty or one of:" +msgstr "yön boÅŸ ya da ÅŸunlardan biri olabilir:" + +#: sql_help.c:3609 sql_help.c:3610 sql_help.c:3611 sql_help.c:3612 +#: sql_help.c:3613 sql_help.c:3850 sql_help.c:3851 sql_help.c:3852 +#: sql_help.c:3853 sql_help.c:3854 sql_help.c:4228 sql_help.c:4230 +#: sql_help.c:4318 sql_help.c:4320 sql_help.c:4467 sql_help.c:4469 +#: sql_help.c:4609 sql_help.c:4611 sql_help.c:4674 sql_help.c:4676 +msgid "count" +msgstr "toplam sayı" + +#: sql_help.c:3693 sql_help.c:4026 +msgid "sequence_name" +msgstr "sequence_adı" + +#: sql_help.c:3706 sql_help.c:4039 +msgid "arg_name" +msgstr "arg_adı" + +#: sql_help.c:3707 sql_help.c:4040 +msgid "arg_type" +msgstr "bağımsız_deÄŸiÅŸken_tipi" + +#: sql_help.c:3712 sql_help.c:4045 +msgid "loid" +msgstr "" + +#: sql_help.c:3735 +msgid "remote_schema" +msgstr "uzak_ÅŸema" + +#: sql_help.c:3738 +msgid "local_schema" +msgstr "yerel_ÅŸema" + +#: sql_help.c:3773 +msgid "conflict_target" +msgstr "çakışma_hedefi" + +#: sql_help.c:3774 +msgid "conflict_action" +msgstr "çakışma_eylemi" + +#: sql_help.c:3777 +msgid "where conflict_target can be one of:" +msgstr "çakışma_hedefi aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:3778 +msgid "index_column_name" +msgstr "indeks_sütun_adı" + +#: sql_help.c:3779 +msgid "index_expression" +msgstr "indeks_ifadesi" + +#: sql_help.c:3782 +msgid "index_predicate" +msgstr "index_yüklemi" + +#: sql_help.c:3784 +msgid "and conflict_action is one of:" +msgstr "ve çakışma_eylemi aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:3790 sql_help.c:4562 +msgid "sub-SELECT" +msgstr "alt-SELECT" + +#: sql_help.c:3799 sql_help.c:3862 sql_help.c:4538 +msgid "channel" +msgstr "kanal" + +#: sql_help.c:3821 +msgid "lockmode" +msgstr "kilitleme modu" + +#: sql_help.c:3822 +msgid "where lockmode is one of:" +msgstr "kilitleme modu ÅŸunlardan biri olabilir:" + +#: sql_help.c:3863 +msgid "payload" +msgstr "yük (payload)" + +#: sql_help.c:3890 +msgid "old_role" +msgstr "eski_rol" + +#: sql_help.c:3891 +msgid "new_role" +msgstr "yeni_rol" + +#: sql_help.c:3916 sql_help.c:4077 sql_help.c:4085 +msgid "savepoint_name" +msgstr "savepoint_adı" + +#: sql_help.c:4219 sql_help.c:4261 sql_help.c:4263 sql_help.c:4309 +#: sql_help.c:4458 sql_help.c:4500 sql_help.c:4502 sql_help.c:4665 +#: sql_help.c:4707 sql_help.c:4709 +msgid "from_item" +msgstr "from_item" + +#: sql_help.c:4221 sql_help.c:4273 sql_help.c:4460 sql_help.c:4512 +#: sql_help.c:4667 sql_help.c:4719 +msgid "grouping_element" +msgstr "gruplama_öğesi" + +#: sql_help.c:4223 sql_help.c:4313 sql_help.c:4462 sql_help.c:4669 +msgid "window_name" +msgstr "pencere_adı" + +#: sql_help.c:4224 sql_help.c:4314 sql_help.c:4463 sql_help.c:4670 +msgid "window_definition" +msgstr "window_tanımı" + +#: sql_help.c:4225 sql_help.c:4239 sql_help.c:4277 sql_help.c:4315 +#: sql_help.c:4464 sql_help.c:4478 sql_help.c:4516 sql_help.c:4671 +#: sql_help.c:4685 sql_help.c:4723 +msgid "select" +msgstr "select" + +#: sql_help.c:4232 sql_help.c:4471 sql_help.c:4678 +msgid "where from_item can be one of:" +msgstr "from_öğesi ÅŸunlardan biri olabilir" + +#: sql_help.c:4235 sql_help.c:4241 sql_help.c:4244 sql_help.c:4248 +#: sql_help.c:4260 sql_help.c:4474 sql_help.c:4480 sql_help.c:4483 +#: sql_help.c:4487 sql_help.c:4499 sql_help.c:4681 sql_help.c:4687 +#: sql_help.c:4690 sql_help.c:4694 sql_help.c:4706 +msgid "column_alias" +msgstr "kolon_takma_adı" + +#: sql_help.c:4236 sql_help.c:4475 sql_help.c:4682 +msgid "sampling_method" +msgstr "örnekleme_yöntemi" + +#: sql_help.c:4238 sql_help.c:4477 sql_help.c:4684 +msgid "seed" +msgstr "baÅŸlangıç deÄŸeri" + +#: sql_help.c:4242 sql_help.c:4275 sql_help.c:4481 sql_help.c:4514 +#: sql_help.c:4688 sql_help.c:4721 +msgid "with_query_name" +msgstr "with_sorgu_adı" + +#: sql_help.c:4252 sql_help.c:4255 sql_help.c:4258 sql_help.c:4491 +#: sql_help.c:4494 sql_help.c:4497 sql_help.c:4698 sql_help.c:4701 +#: sql_help.c:4704 +msgid "column_definition" +msgstr "kolon_tanımı" + +#: sql_help.c:4262 sql_help.c:4501 sql_help.c:4708 +msgid "join_type" +msgstr "join_tipi" + +#: sql_help.c:4264 sql_help.c:4503 sql_help.c:4710 +msgid "join_condition" +msgstr "join_ÅŸartı" + +#: sql_help.c:4265 sql_help.c:4504 sql_help.c:4711 +msgid "join_column" +msgstr "join_sütunu" + +#: sql_help.c:4266 sql_help.c:4505 sql_help.c:4712 +msgid "and grouping_element can be one of:" +msgstr "ve grouplama-elemanı aÅŸağıdakilerden birisi olabilir:" + +#: sql_help.c:4274 sql_help.c:4513 sql_help.c:4720 +msgid "and with_query is:" +msgstr "ve with_sorgusu :" + +#: sql_help.c:4278 sql_help.c:4517 sql_help.c:4724 +msgid "values" +msgstr "deÄŸerler" + +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4725 +msgid "insert" +msgstr "ekle (insert)" + +#: sql_help.c:4280 sql_help.c:4519 sql_help.c:4726 +msgid "update" +msgstr "güncelle (update)" + +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4727 +msgid "delete" +msgstr "sil (delete)" + +#: sql_help.c:4308 +msgid "new_table" +msgstr "yeni_tablo" + +#: sql_help.c:4333 +msgid "timezone" +msgstr "saat dilimi" + +#: sql_help.c:4378 +msgid "snapshot_id" +msgstr "snapshot_id" + +#: sql_help.c:4563 +msgid "from_list" +msgstr "from_listesi" + +#: sql_help.c:4607 +msgid "sort_expression" +msgstr "sort_ifadesi" + +#: sql_help.c:4734 sql_help.c:5549 +msgid "abort the current transaction" +msgstr "aktif transcation'ı iptal et" + +#: sql_help.c:4739 +msgid "change the definition of an aggregate function" +msgstr "aggregate fonksiyonunun tanımını deÄŸiÅŸtir" + +#: sql_help.c:4744 +msgid "change the definition of a collation" +msgstr "karşılaÅŸtırma (collation) tanımını deÄŸiÅŸtir" + +#: sql_help.c:4749 +msgid "change the definition of a conversion" +msgstr "bir dönüşümün tanımını deÄŸiÅŸtir" + +#: sql_help.c:4754 +msgid "change a database" +msgstr "veritabanını deÄŸiÅŸtir" + +#: sql_help.c:4759 +msgid "define default access privileges" +msgstr "varsayılan eriÅŸim haklarını tanımla" + +#: sql_help.c:4764 +msgid "change the definition of a domain" +msgstr "domain tanımını deÄŸiÅŸtir" + +#: sql_help.c:4769 +msgid "change the definition of an event trigger" +msgstr "olay tetikleyici tanımını deÄŸiÅŸtir" + +#: sql_help.c:4774 +msgid "change the definition of an extension" +msgstr "uzantı tanımını deÄŸiÅŸtir" + +#: sql_help.c:4779 +msgid "change the definition of a foreign-data wrapper" +msgstr "foreign-data wrapper tanımını deÄŸiÅŸtir" + +#: sql_help.c:4784 +msgid "change the definition of a foreign table" +msgstr "uzak (foreign) tablo tanımını deÄŸiÅŸtir" + +#: sql_help.c:4789 +msgid "change the definition of a function" +msgstr "fonksiyon tanımını deÄŸiÅŸtir" + +#: sql_help.c:4794 +msgid "change role name or membership" +msgstr "üyeliÄŸi veya rol adını deÄŸiÅŸtir" + +#: sql_help.c:4799 +msgid "change the definition of an index" +msgstr "index tanımını deÄŸiÅŸtir" + +#: sql_help.c:4804 +msgid "change the definition of a procedural language" +msgstr "yordamsal dilinin tanımını deÄŸiÅŸtir" + +#: sql_help.c:4809 +msgid "change the definition of a large object" +msgstr "büyük nesne tanımını deÄŸiÅŸtir" + +#: sql_help.c:4814 +msgid "change the definition of a materialized view" +msgstr "maddileÅŸtirilmiÅŸ görünüm (materialized view) tanımını deÄŸiÅŸtir" + +#: sql_help.c:4819 +msgid "change the definition of an operator" +msgstr "operatör tanımını deÄŸiÅŸtir" + +#: sql_help.c:4824 +msgid "change the definition of an operator class" +msgstr "operatör sınıfının tanımını deÄŸiÅŸtir" + +#: sql_help.c:4829 +msgid "change the definition of an operator family" +msgstr "operatör ailesinin tanımını deÄŸiÅŸtir" + +#: sql_help.c:4834 +msgid "change the definition of a row level security policy" +msgstr "satır seviyesi güvenlik ilkesi tanımını deÄŸiÅŸtir" + +#: sql_help.c:4839 +msgid "change the definition of a procedure" +msgstr "prosedür tanımını deÄŸiÅŸtir" + +#: sql_help.c:4844 +msgid "change the definition of a publication" +msgstr "yayın tanımını deÄŸiÅŸtir" + +#: sql_help.c:4849 sql_help.c:4934 +msgid "change a database role" +msgstr "veritabanı dolünü deÄŸiÅŸtir" + +#: sql_help.c:4854 +msgid "change the definition of a routine" +msgstr "yordam (routine) tanımını deÄŸiÅŸtir" + +#: sql_help.c:4859 +msgid "change the definition of a rule" +msgstr "kural tanımını deÄŸiÅŸtir" + +#: sql_help.c:4864 +msgid "change the definition of a schema" +msgstr "ÅŸema tanımını deÄŸiÅŸtir" + +#: sql_help.c:4869 +msgid "change the definition of a sequence generator" +msgstr "sequence üretecinin tanımını deÄŸiÅŸtir" + +#: sql_help.c:4874 +msgid "change the definition of a foreign server" +msgstr "foreign server tanımını deÄŸiÅŸtir" + +#: sql_help.c:4879 +msgid "change the definition of an extended statistics object" +msgstr "geniÅŸletilmiÅŸ istatistik nesnesinin tanımını deÄŸiÅŸtir" + +#: sql_help.c:4884 +msgid "change the definition of a subscription" +msgstr "abonelik tanımını deÄŸiÅŸtir" + +#: sql_help.c:4889 +msgid "change a server configuration parameter" +msgstr "bir sunucu yapılandırma parametresini deÄŸiÅŸtir" + +#: sql_help.c:4894 +msgid "change the definition of a table" +msgstr "tablonun tanımını deÄŸiÅŸtir" + +#: sql_help.c:4899 +msgid "change the definition of a tablespace" +msgstr "tablespace tanımını deÄŸiÅŸtir" + +#: sql_help.c:4904 +msgid "change the definition of a text search configuration" +msgstr "metin arama yapılandırmasının tanımını deÄŸiÅŸtir" + +#: sql_help.c:4909 +msgid "change the definition of a text search dictionary" +msgstr "metin arama sözlüğünün tanımını deÄŸiÅŸtir" + +#: sql_help.c:4914 +msgid "change the definition of a text search parser" +msgstr "metin arama ayrıştırıcısının tanımını deÄŸiÅŸtir" + +#: sql_help.c:4919 +msgid "change the definition of a text search template" +msgstr "metin arama ÅŸablonunun tanımını deÄŸiÅŸtir" + +#: sql_help.c:4924 +msgid "change the definition of a trigger" +msgstr "trigger tanımını deÄŸiÅŸtir" + +#: sql_help.c:4929 +msgid "change the definition of a type" +msgstr "type tanımını deÄŸiÅŸtir" + +#: sql_help.c:4939 +msgid "change the definition of a user mapping" +msgstr "kullanıcı haritalama tanımını deÄŸiÅŸtir" + +#: sql_help.c:4944 +msgid "change the definition of a view" +msgstr "view tanımını deÄŸiÅŸtir" + +#: sql_help.c:4949 +msgid "collect statistics about a database" +msgstr "database hakkında istatistikleri topla" + +#: sql_help.c:4954 sql_help.c:5614 +msgid "start a transaction block" +msgstr "transaction bloÄŸunu baÅŸlat" + +#: sql_help.c:4959 +msgid "invoke a procedure" +msgstr "bir prosedürü çağır" + +#: sql_help.c:4964 +msgid "force a write-ahead log checkpoint" +msgstr "write-ahead log checkpoint'i gerçekleÅŸtir" + +#: sql_help.c:4969 +msgid "close a cursor" +msgstr "cursor'u kapat" + +#: sql_help.c:4974 +msgid "cluster a table according to an index" +msgstr "indexe dayanarak tabloyu cluster iÅŸlemine tabi tut" + +#: sql_help.c:4979 +msgid "define or change the comment of an object" +msgstr "Nesne yorumunu tanımla ya da deÄŸiÅŸtir" + +#: sql_help.c:4984 sql_help.c:5449 +msgid "commit the current transaction" +msgstr "geçerli transaction'u commit et" + +#: sql_help.c:4989 +msgid "commit a transaction that was earlier prepared for two-phase commit" +msgstr "daha önce two-phase commit için hazırlanmış transaction'u commit et" + +#: sql_help.c:4994 +msgid "copy data between a file and a table" +msgstr "dosya ile veritabanı tablosu arasında veriyi transfer et" + +#: sql_help.c:4999 +msgid "define a new access method" +msgstr "yeni eriÅŸim yöntemi tanımla" + +#: sql_help.c:5004 +msgid "define a new aggregate function" +msgstr "yeni aggregate fonksiyonunu tanımla" + +#: sql_help.c:5009 +msgid "define a new cast" +msgstr "yeni cast tanımla" + +#: sql_help.c:5014 +msgid "define a new collation" +msgstr "yeni karşılaÅŸtırma (collation) tanımla" + +#: sql_help.c:5019 +msgid "define a new encoding conversion" +msgstr "yeni kodlama dönüşümü tanımla" + +#: sql_help.c:5024 +msgid "create a new database" +msgstr "yeni veritabanı oluÅŸtur" + +#: sql_help.c:5029 +msgid "define a new domain" +msgstr "yeni domaın tanımla" + +#: sql_help.c:5034 +msgid "define a new event trigger" +msgstr "yeni olay tetikleyici tanımla" + +#: sql_help.c:5039 +msgid "install an extension" +msgstr "bir uzantı kur" + +#: sql_help.c:5044 +msgid "define a new foreign-data wrapper" +msgstr "yeni foreign-data wrapper tanımla" + +#: sql_help.c:5049 +msgid "define a new foreign table" +msgstr "yeni uzak (foreign) tablo tanımla" + +#: sql_help.c:5054 +msgid "define a new function" +msgstr "yeni fonksiyonu tanımla" + +#: sql_help.c:5059 sql_help.c:5109 sql_help.c:5194 +msgid "define a new database role" +msgstr "yeni veritabanı rolü tanımla" + +#: sql_help.c:5064 +msgid "define a new index" +msgstr "yeni indeks tanımla" + +#: sql_help.c:5069 +msgid "define a new procedural language" +msgstr "yeni yordamsal dil tanımla" + +#: sql_help.c:5074 +msgid "define a new materialized view" +msgstr "yeni maddileÅŸtirilmiÅŸ görünüm (materialized view) tanımla" + +#: sql_help.c:5079 +msgid "define a new operator" +msgstr "yeni operator tanımla" + +#: sql_help.c:5084 +msgid "define a new operator class" +msgstr "yeni operator class tanımla" + +#: sql_help.c:5089 +msgid "define a new operator family" +msgstr "yeni operatör ailesini tanımla" + +#: sql_help.c:5094 +msgid "define a new row level security policy for a table" +msgstr "bir tablo için yeni satır-seviyesi güvenlik ilkesi tanımla" + +#: sql_help.c:5099 +msgid "define a new procedure" +msgstr "yeni bir prosedür tanımla" + +#: sql_help.c:5104 +msgid "define a new publication" +msgstr "yeni bir yayın tanımla" + +#: sql_help.c:5114 +msgid "define a new rewrite rule" +msgstr "yeni rewriter rule tanımla" + +#: sql_help.c:5119 +msgid "define a new schema" +msgstr "yeni ÅŸema tanımla" + +#: sql_help.c:5124 +msgid "define a new sequence generator" +msgstr "yeni sequence generator tanımla" + +#: sql_help.c:5129 +msgid "define a new foreign server" +msgstr "yeni foreign sunucu tanımla" + +#: sql_help.c:5134 +msgid "define extended statistics" +msgstr "geniÅŸletilmiÅŸ istatistikleri tanımla" + +#: sql_help.c:5139 +msgid "define a new subscription" +msgstr "yeni abonelik tanımla" + +#: sql_help.c:5144 +msgid "define a new table" +msgstr "yeni tablo tanımla" + +#: sql_help.c:5149 sql_help.c:5579 +msgid "define a new table from the results of a query" +msgstr "sorgu sonuçlarından yeni tablo tanımla" + +#: sql_help.c:5154 +msgid "define a new tablespace" +msgstr "yeni tablespace tanımla" + +#: sql_help.c:5159 +msgid "define a new text search configuration" +msgstr "yeni metin arama yapılandırması tanımla" + +#: sql_help.c:5164 +msgid "define a new text search dictionary" +msgstr "yeni metin arama sözlüğü tanımla" + +#: sql_help.c:5169 +msgid "define a new text search parser" +msgstr "yeni metin arama ayrıştırıcısı tanımla" + +#: sql_help.c:5174 +msgid "define a new text search template" +msgstr "yeni metin arama ÅŸablonu tanımla" + +#: sql_help.c:5179 +msgid "define a new transform" +msgstr "yeni bir dönüşüm (transform) tanımla" + +#: sql_help.c:5184 +msgid "define a new trigger" +msgstr "yeni trigger tanımla" + +#: sql_help.c:5189 +msgid "define a new data type" +msgstr "yeni veri tipi tanımla" + +#: sql_help.c:5199 +msgid "define a new mapping of a user to a foreign server" +msgstr "bir foreign sunucuya yeni kullanıcı haritalamasını tanımla" + +#: sql_help.c:5204 +msgid "define a new view" +msgstr "yeni vew tanımla" + +#: sql_help.c:5209 +msgid "deallocate a prepared statement" +msgstr "deallocate a prepared statement" + +#: sql_help.c:5214 +msgid "define a cursor" +msgstr "cursor tanımla" + +#: sql_help.c:5219 +msgid "delete rows of a table" +msgstr "tablodan satırları sil" + +#: sql_help.c:5224 +msgid "discard session state" +msgstr "oturum bilgileri unut" + +#: sql_help.c:5229 +msgid "execute an anonymous code block" +msgstr "bir anonim kod bloÄŸu çalıştır" + +#: sql_help.c:5234 +msgid "remove an access method" +msgstr "bir eriÅŸim yöntemini kaldır" + +#: sql_help.c:5239 +msgid "remove an aggregate function" +msgstr "aggregate function'u kaldır" + +#: sql_help.c:5244 +msgid "remove a cast" +msgstr "cast kaldır" + +#: sql_help.c:5249 +msgid "remove a collation" +msgstr "karşılaÅŸtırma (collation) kaldır" + +#: sql_help.c:5254 +msgid "remove a conversion" +msgstr "conversion kaldır" + +#: sql_help.c:5259 +msgid "remove a database" +msgstr "veritabanını kaldır" + +#: sql_help.c:5264 +msgid "remove a domain" +msgstr "domain kaldır" + +#: sql_help.c:5269 +msgid "remove an event trigger" +msgstr "olay tetikleyici kaldır" + +#: sql_help.c:5274 +msgid "remove an extension" +msgstr "uzantı kaldır" + +#: sql_help.c:5279 +msgid "remove a foreign-data wrapper" +msgstr "foreign-data wrapper'ını kaldır" + +#: sql_help.c:5284 +msgid "remove a foreign table" +msgstr "uzak (foreign) tablo kaldır" + +#: sql_help.c:5289 +msgid "remove a function" +msgstr "function kaldır" + +#: sql_help.c:5294 sql_help.c:5349 sql_help.c:5434 +msgid "remove a database role" +msgstr "veritabanı rolünü kaldır" + +#: sql_help.c:5299 +msgid "remove an index" +msgstr "indeks kaldır" + +#: sql_help.c:5304 +msgid "remove a procedural language" +msgstr "yordamsal dili kaldır" + +#: sql_help.c:5309 +msgid "remove a materialized view" +msgstr "maddileÅŸtirilmiÅŸ görünüm (materialized view) kaldır" + +#: sql_help.c:5314 +msgid "remove an operator" +msgstr "opeartor kaldır" + +#: sql_help.c:5319 +msgid "remove an operator class" +msgstr "operator class kaldır" + +#: sql_help.c:5324 +msgid "remove an operator family" +msgstr "opeartör ailesini kaldır" + +#: sql_help.c:5329 +msgid "remove database objects owned by a database role" +msgstr "veritabanı rolüne ait veritabanı nesneleri kaldır" + +#: sql_help.c:5334 +msgid "remove a row level security policy from a table" +msgstr "bir tablodan satır-seviyesi güvenlik politikası kaldır" + +#: sql_help.c:5339 +msgid "remove a procedure" +msgstr "bir prosedür kaldır" + +#: sql_help.c:5344 +msgid "remove a publication" +msgstr "yayın kaldır" + +#: sql_help.c:5354 +msgid "remove a routine" +msgstr "yordam (routine) kaldır" + +#: sql_help.c:5359 +msgid "remove a rewrite rule" +msgstr "rewrite rule kaldır" + +#: sql_help.c:5364 +msgid "remove a schema" +msgstr "ÅŸema kaldır" + +#: sql_help.c:5369 +msgid "remove a sequence" +msgstr "sequence kaldır" + +#: sql_help.c:5374 +msgid "remove a foreign server descriptor" +msgstr "foreign sunucu tanımını kaldır" + +#: sql_help.c:5379 +msgid "remove extended statistics" +msgstr "geniÅŸletilmiÅŸ istatistikleri kaldır" + +#: sql_help.c:5384 +msgid "remove a subscription" +msgstr "abonelik kaldır" + +#: sql_help.c:5389 +msgid "remove a table" +msgstr "tablo kaldır" + +#: sql_help.c:5394 +msgid "remove a tablespace" +msgstr "tablespace kaldır" + +#: sql_help.c:5399 +msgid "remove a text search configuration" +msgstr "metin arama yapılandırmasını kaldır" + +#: sql_help.c:5404 +msgid "remove a text search dictionary" +msgstr "biri metin arama sözlüğünü kaldır" + +#: sql_help.c:5409 +msgid "remove a text search parser" +msgstr "bir metin arama ayrıştırıcısını kaldır" + +#: sql_help.c:5414 +msgid "remove a text search template" +msgstr "bir metin arama ÅŸablonunu kaldır" + +#: sql_help.c:5419 +msgid "remove a transform" +msgstr "dönüşüm (transform) kaldır" + +#: sql_help.c:5424 +msgid "remove a trigger" +msgstr "trigger kaldır" + +#: sql_help.c:5429 +msgid "remove a data type" +msgstr "veri tipi kaldır" + +#: sql_help.c:5439 +msgid "remove a user mapping for a foreign server" +msgstr "bir foreign sunucu için kullanıcı haritalamasını kaldır" + +#: sql_help.c:5444 +msgid "remove a view" +msgstr "view kaldır" + +#: sql_help.c:5454 +msgid "execute a prepared statement" +msgstr "hazırlanmış komutu çalıştır" + +#: sql_help.c:5459 +msgid "show the execution plan of a statement" +msgstr "sorgunun execution planını göster" + +#: sql_help.c:5464 +msgid "retrieve rows from a query using a cursor" +msgstr "cursor kullanarak sorgunun sonucundan satırları getir" + +#: sql_help.c:5469 +msgid "define access privileges" +msgstr "eriÅŸim haklarını tanımla" + +#: sql_help.c:5474 +msgid "import table definitions from a foreign server" +msgstr "uzak sunucudan (foreign server) tablo tanımlarını al" + +#: sql_help.c:5479 +msgid "create new rows in a table" +msgstr "tabloda yeni satırları ekliyor" + +#: sql_help.c:5484 +msgid "listen for a notification" +msgstr "bildiri bekleme durumuna geç" + +#: sql_help.c:5489 +msgid "load a shared library file" +msgstr "shared library dosyası yükle" + +#: sql_help.c:5494 +msgid "lock a table" +msgstr "tabloyu kilitle" + +#: sql_help.c:5499 +msgid "position a cursor" +msgstr "cursor'u yereÅŸtir" + +#: sql_help.c:5504 +msgid "generate a notification" +msgstr "bildiri üret" + +#: sql_help.c:5509 +msgid "prepare a statement for execution" +msgstr "çalıştırmak için sorguyu hazırla" + +#: sql_help.c:5514 +msgid "prepare the current transaction for two-phase commit" +msgstr "geçerli transaction'u two-phase commit için hazırla" + +#: sql_help.c:5519 +msgid "change the ownership of database objects owned by a database role" +msgstr "veritabanı rolünün sahip olduÄŸu nesnelerinin sahipliÄŸini deÄŸiÅŸtir" + +#: sql_help.c:5524 +msgid "replace the contents of a materialized view" +msgstr "bir maddileÅŸtirilmiÅŸ görünümün (materialized view) içeriÄŸini deÄŸiÅŸtir" + +#: sql_help.c:5529 +msgid "rebuild indexes" +msgstr "indeksleri yeniden oluÅŸtur" + +#: sql_help.c:5534 +msgid "destroy a previously defined savepoint" +msgstr "önceki tanımlanmış savepoint'i kaldır" + +#: sql_help.c:5539 +msgid "restore the value of a run-time parameter to the default value" +msgstr "çalıştırma zamanı parametresini öntanımlı deÄŸerine getir" + +#: sql_help.c:5544 +msgid "remove access privileges" +msgstr "eriÅŸim hakkını kaldır" + +#: sql_help.c:5554 +msgid "cancel a transaction that was earlier prepared for two-phase commit" +msgstr "daha önce two-phase commit için hazırlanmış transaction'u iptal et" + +#: sql_help.c:5559 +msgid "roll back to a savepoint" +msgstr "savepoint'a rollback" + +#: sql_help.c:5564 +msgid "define a new savepoint within the current transaction" +msgstr "geerli transaction içinde savepoint tanımla" + +#: sql_help.c:5569 +msgid "define or change a security label applied to an object" +msgstr "bir nesneye uygulanan güvenlik etiketini tanımla ya da deÄŸiÅŸtir" + +#: sql_help.c:5574 sql_help.c:5619 sql_help.c:5649 +msgid "retrieve rows from a table or view" +msgstr "tablo ya da view'dan satırları getir" + +#: sql_help.c:5584 +msgid "change a run-time parameter" +msgstr "çalışma zamanı parametresini deÄŸiÅŸtir" + +#: sql_help.c:5589 +msgid "set constraint check timing for the current transaction" +msgstr "geçerli iÅŸlem (transaction) için kısıtlama doÄŸrulama zamanlamasını belirle" + +#: sql_help.c:5594 +msgid "set the current user identifier of the current session" +msgstr "geçerli oturumun geçerli kullanıcısını tanımla" + +#: sql_help.c:5599 +msgid "set the session user identifier and the current user identifier of the current session" +msgstr "ilk oturum ve geçerli oturum için kullanıcı tanımla" + +#: sql_help.c:5604 +msgid "set the characteristics of the current transaction" +msgstr "geçerli transcation'ın karakteristiklerini ayarla" + +#: sql_help.c:5609 +msgid "show the value of a run-time parameter" +msgstr "çalıştırma zaman parametresinın deÄŸerini göster" + +#: sql_help.c:5624 +msgid "empty a table or set of tables" +msgstr "bir veya birden fazla tabloyu kısalt" + +#: sql_help.c:5629 +msgid "stop listening for a notification" +msgstr "bildiriyi beklemeyi durdur" + +#: sql_help.c:5634 +msgid "update rows of a table" +msgstr "tablodaki satırları güncelle" + +#: sql_help.c:5639 +msgid "garbage-collect and optionally analyze a database" +msgstr "Veritabanındaki çöpleri-toparla ve veritabanını (tercihe baÅŸlı) analiz et" + +#: sql_help.c:5644 +msgid "compute a set of rows" +msgstr "compute a set of rows" + +#: startup.c:190 +#, c-format +msgid "%s: -1 can only be used in non-interactive mode\n" +msgstr "%s: -1 sadece interaktif olmayan modda kullanılabilir\n" + +#: startup.c:305 +#, c-format +msgid "%s: could not open log file \"%s\": %s\n" +msgstr "%s: \"%s\" kayıti dosyası açılamıyor: %s\n" + +#: startup.c:412 +#, c-format +msgid "" +"Type \"help\" for help.\n" +"\n" +msgstr "" +"Yardım için \"help\" yazınız.\n" +"\n" + +#: startup.c:561 +#, c-format +msgid "%s: could not set printing parameter \"%s\"\n" +msgstr "%s: \"%s\" yazdırma parametrlesi ayarlanamıyor\n" + +#: startup.c:663 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" yazın.\n" + +#: startup.c:680 +#, c-format +msgid "%s: warning: extra command-line argument \"%s\" ignored\n" +msgstr "%s: uyarı: \"%s\" fazla argümanı atlanmıştır\n" + +#: startup.c:729 +#, c-format +msgid "%s: could not find own program executable\n" +msgstr "%s: çalıştırılabilir dosya bulunamadı\n" + +#: tab-complete.c:4480 +#, c-format +msgid "" +"tab completion query failed: %s\n" +"Query was:\n" +"%s\n" +msgstr "" +"sekme tamamlama sorgusu baÅŸarısız oldu: %s\n" +"Sorgu ÅŸudur: \n" +"%s\n" + +#: variables.c:139 +#, c-format +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgstr "\"%2$s\" için tanınmayan deÄŸer \"%1$s\": Boolean bekleniyor\n" + +#: variables.c:176 +#, c-format +msgid "invalid value \"%s\" for \"%s\": integer expected\n" +msgstr "\"%2$s\" için geçersiz deÄŸer \"%1$s\": tamsayı bekleniyor\n" + +#: variables.c:224 +#, c-format +msgid "invalid variable name: \"%s\"\n" +msgstr "geçersiz deÄŸiÅŸken adı: \"%s\"\n" + +#: variables.c:393 +#, c-format +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s.\n" +msgstr "" +"\"%2$s\" için tanınmayan deÄŸer \"%1$s\"\n" +"Mevcut deÄŸerler: %3$s.\n" + +#~ msgid "Password encryption failed.\n" +#~ msgstr "Parola ÅŸifrleme hatası.\n" + +#, fuzzy +#~ msgid "\\%s: error while setting variable\n" +#~ msgstr "%s: \"%s\" deÄŸiÅŸkeni atanamıyor\n" + +#~ msgid "SSL connection (unknown cipher)\n" +#~ msgstr "SSL baÄŸlantısı (bilinmeyen cipher)\n" + +#~ msgid "Showing locale-adjusted numeric output." +#~ msgstr "Yerel duyarlı sayısal çıktı gösteriliyor." + +#~ msgid "Showing only tuples." +#~ msgstr "Sadece kayıtlar gösteriliyor." + +#~ msgid "%s: pg_strdup: cannot duplicate null pointer (internal error)\n" +#~ msgstr "%s: pg_strdup: null pointer duplicate edilemiyor (iç hata)\n" + +#~ msgid "\\copy: %s" +#~ msgstr "\\copy: %s" + +#~ msgid "\\copy: unexpected response (%d)\n" +#~ msgstr "\\copy: beklenmeyen yanıt (%d)\n" + +#~ msgid "could not get current user name: %s\n" +#~ msgstr "geçerli kullanıcı adı alınamadı: %s\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı gösterir ve çıkar\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini gösterir ve çıkar\n" + +#~ msgid " \\l[+] list all databases\n" +#~ msgstr " \\l[+] tüm tablespaceleri listele\n" + +#~ msgid "" +#~ " \\pset NAME [VALUE] set table output option\n" +#~ " (NAME := {format|border|expanded|fieldsep|footer|null|\n" +#~ " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n" +#~ msgstr "" +#~ " \\pset AD [VALUE] tablo çıktısı biçimini ayarla\n" +#~ " (AD := {format|border|expanded|fieldsep|footer|null|\n" +#~ " numericlocale|recordsep|tuples_only|title|tableattr|pager})\n" + +#~ msgid "(No rows)\n" +#~ msgstr "(Satır yok)\n" + +#~ msgid "%s: could not set variable \"%s\"\n" +#~ msgstr "%s: \"%s\" deÄŸiÅŸkeni atanamıyor\n" + +#~ msgid "contains support for command-line editing" +#~ msgstr "komut satırı düzenleme desteÄŸi mevcuttur" + +#~ msgid "normal" +#~ msgstr "normal" + +#~ msgid "Modifiers" +#~ msgstr "Modifiers" + +#~ msgid "Value" +#~ msgstr "DeÄŸer" + +#~ msgid "not null" +#~ msgstr "Null deÄŸil" + +#~ msgid "default %s" +#~ msgstr "öntanımlı %s" + +#, fuzzy +#~ msgid "No matching settings found.\n" +#~ msgstr "EÅŸleÅŸen nesne bulunamadı.\n" + +#, fuzzy +#~ msgid "No settings found.\n" +#~ msgstr "Nesne bulunamadı.\n" + +#~ msgid "No matching relations found.\n" +#~ msgstr "EÅŸleÅŸen nesne bulunamadı.\n" + +#~ msgid "No relations found.\n" +#~ msgstr "Nesne bulunamadı.\n" + +#~ msgid "Modifier" +#~ msgstr "Düzenleyici" + +#, fuzzy +#~ msgid "Object Description" +#~ msgstr "Nesne açıklamaları" + +#, fuzzy +#~ msgid "agg_type" +#~ msgstr "Hedef tipi" + +#~ msgid "column" +#~ msgstr "kolon" + +#~ msgid "new_column" +#~ msgstr "yeni_kolon" + +#, fuzzy +#~ msgid "input_data_type" +#~ msgstr "veri tipi" + +#, fuzzy +#~ msgid "tablespace" +#~ msgstr "Tablespace" + +#, fuzzy +#~ msgid "attribute" +#~ msgstr "Özellikler" + +#~ msgid "could not change directory to \"%s\"" +#~ msgstr "çalışma dizini \"%s\" olarak deÄŸiÅŸtirilemedi" + +#~ msgid "\\%s: error\n" +#~ msgstr "\\%s: hata\n" + +#~ msgid " on host \"%s\"" +#~ msgstr " \"%s\" sistemi" + +#~ msgid " at port \"%s\"" +#~ msgstr " \"%s\" portunda" + +#~ msgid " as user \"%s\"" +#~ msgstr " \"%s\" kullanıcısı" + +#~ msgid "data type" +#~ msgstr "veri tipi" + +#~ msgid "define a new constraint trigger" +#~ msgstr "yeni constraint trigger tanımla" + +#~ msgid "ABORT [ WORK | TRANSACTION ]" +#~ msgstr "ABORT [ WORK | TRANSACTION ]" + +#~ msgid "" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) RENAME TO new_name\n" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) OWNER TO new_owner\n" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) SET SCHEMA new_schema" +#~ msgstr "" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) RENAME TO new_name\n" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) OWNER TO new_owner\n" +#~ "ALTER AGGREGATE name ( type [ , ... ] ) SET SCHEMA new_schema" + +#~ msgid "" +#~ "ALTER CONVERSION name RENAME TO newname\n" +#~ "ALTER CONVERSION name OWNER TO newowner" +#~ msgstr "" +#~ "ALTER CONVERSION dönüşüm_adı RENAME TO yeni_ad\n" +#~ "ALTER CONVERSION dönüşüm_adı OWNER TO yeni_sahip" + +#~ msgid "" +#~ "ALTER DATABASE name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ "\n" +#~ " CONNECTION LIMIT connlimit\n" +#~ "\n" +#~ "ALTER DATABASE name RENAME TO newname\n" +#~ "\n" +#~ "ALTER DATABASE name OWNER TO new_owner\n" +#~ "\n" +#~ "ALTER DATABASE name SET TABLESPACE new_tablespace\n" +#~ "\n" +#~ "ALTER DATABASE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" +#~ "ALTER DATABASE name SET configuration_parameter FROM CURRENT\n" +#~ "ALTER DATABASE name RESET configuration_parameter\n" +#~ "ALTER DATABASE name RESET ALL" +#~ msgstr "" +#~ "ALTER DATABASE veritabanı_adı [ [ WITH ] seçenek [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " CONNECTION LIMIT baÄŸlantı limiti\n" +#~ "\n" +#~ "ALTER DATABASE veritabanı_adı RENAME TO yeni_adı\n" +#~ "\n" +#~ "ALTER DATABASE veritabanı_adı OWNER TO yeni_sahibi\n" +#~ "\n" +#~ "ALTER DATABASE veritabanı_adı SET yapılandırma_parametresi { TO | = } { deÄŸer | DEFAULT }\n" +#~ "ALTER DATABASE veritabanı_adı SET yapılandırma_parametresi FROM CURRENT\n" +#~ "ALTER DATABASE veritabanı_adı RESET yapılandırma_parametresi\n" +#~ "ALTER DATABASE veritabanı_adı RESET ALL" + +#~ msgid "" +#~ "ALTER DOMAIN name\n" +#~ " { SET DEFAULT expression | DROP DEFAULT }\n" +#~ "ALTER DOMAIN name\n" +#~ " { SET | DROP } NOT NULL\n" +#~ "ALTER DOMAIN name\n" +#~ " ADD domain_constraint\n" +#~ "ALTER DOMAIN name\n" +#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" +#~ "ALTER DOMAIN name\n" +#~ " OWNER TO new_owner \n" +#~ "ALTER DOMAIN name\n" +#~ " SET SCHEMA new_schema" +#~ msgstr "" +#~ "ALTER DOMAIN name\n" +#~ " { SET DEFAULT expression | DROP DEFAULT }\n" +#~ "ALTER DOMAIN name\n" +#~ " { SET | DROP } NOT NULL\n" +#~ "ALTER DOMAIN name\n" +#~ " ADD domain_constraint\n" +#~ "ALTER DOMAIN name\n" +#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" +#~ "ALTER DOMAIN name\n" +#~ " OWNER TO new_owner \n" +#~ "ALTER DOMAIN name\n" +#~ " SET SCHEMA new_schema" + +#~ msgid "" +#~ "ALTER FOREIGN DATA WRAPPER name\n" +#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" +#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ]) ]\n" +#~ "ALTER FOREIGN DATA WRAPPER name OWNER TO new_owner" +#~ msgstr "" +#~ "ALTER FOREIGN DATA WRAPPER ad\n" +#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" +#~ " [ SEÇENEKLER ( [ ADD | SET | DROP ] seçenek ['deÄŸer'] [, ... ]) ]\n" +#~ "ALTER FOREIGN DATA WRAPPER ad OWNER TO yeni sahibi" + +#~ msgid "" +#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " action [ ... ] [ RESTRICT ]\n" +#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " RENAME TO new_name\n" +#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " OWNER TO new_owner\n" +#~ "ALTER FUNCTION name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " SET SCHEMA new_schema\n" +#~ "\n" +#~ "where action is one of:\n" +#~ "\n" +#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" +#~ " IMMUTABLE | STABLE | VOLATILE\n" +#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" +#~ " COST execution_cost\n" +#~ " ROWS result_rows\n" +#~ " SET configuration_parameter { TO | = } { value | DEFAULT }\n" +#~ " SET configuration_parameter FROM CURRENT\n" +#~ " RESET configuration_parameter\n" +#~ " RESET ALL" +#~ msgstr "" +#~ "ALTER FUNCTION fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " iÅŸlem [ ... ] [ RESTRICT ]\n" +#~ "ALTER FUNCTION fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " RENAME TO yeni_adı\n" +#~ "ALTER FUNCTION fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " OWNER TO yeni_sahibi\n" +#~ "ALTER FUNCTION fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " SET SCHEMA yeni_ÅŸema\n" +#~ "\n" +#~ "iÅŸlem aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" +#~ " IMMUTABLE | STABLE | VOLATILE\n" +#~ " [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" +#~ " COST çalıştırma_maliyeti(execution cost)\n" +#~ " ROWS result_rows\n" +#~ " SET yapılandırma_parametresi { TO | = } { value | DEFAULT }\n" +#~ " SET yapılandırma_parametresi FROM CURRENT\n" +#~ " RESET yapılandırma_parametresi\n" +#~ " RESET ALL" + +#~ msgid "" +#~ "ALTER GROUP groupname ADD USER username [, ... ]\n" +#~ "ALTER GROUP groupname DROP USER username [, ... ]\n" +#~ "\n" +#~ "ALTER GROUP groupname RENAME TO newname" +#~ msgstr "" +#~ "ALTER GROUP grup_adı ADD USER kullanıcı_adı [, ... ]\n" +#~ "ALTER GROUP grup_adı DROP USER kullanıcı_adı [, ... ]\n" +#~ "\n" +#~ "ALTER GROUP grup_adı RENAME TO yeni_ad" + +#~ msgid "" +#~ "ALTER INDEX name RENAME TO new_name\n" +#~ "ALTER INDEX name SET TABLESPACE tablespace_name\n" +#~ "ALTER INDEX name SET ( storage_parameter = value [, ... ] )\n" +#~ "ALTER INDEX name RESET ( storage_parameter [, ... ] )" +#~ msgstr "" +#~ "ALTER INDEX name RENAME TO new_name\n" +#~ "ALTER INDEX name SET TABLESPACE tablespace_name\n" +#~ "ALTER INDEX name SET ( storage_parameter = value [, ... ] )\n" +#~ "ALTER INDEX name RESET ( storage_parameter [, ... ] )" + +#~ msgid "" +#~ "ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO newname\n" +#~ "ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO new_owner" +#~ msgstr "" +#~ "ALTER [ PROCEDURAL ] LANGUAGE name RENAME TO newname\n" +#~ "ALTER [ PROCEDURAL ] LANGUAGE name OWNER TO new_owner" + +#~ msgid "ALTER OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) OWNER TO newowner" +#~ msgstr "ALTER OPERATOR name ( { lefttype | NONE } , { righttype | NONE } ) OWNER TO yeni_sahip" + +#~ msgid "" +#~ "ALTER OPERATOR CLASS name USING index_method RENAME TO newname\n" +#~ "ALTER OPERATOR CLASS name USING index_method OWNER TO newowner" +#~ msgstr "" +#~ "ALTER OPERATOR CLASS ad USING index_method RENAME TO yeni_ad\n" +#~ "ALTER OPERATOR CLASS ad USING index_method OWNER TO yeni_sahip" + +#~ msgid "" +#~ "ALTER OPERATOR FAMILY name USING index_method ADD\n" +#~ " { OPERATOR strategy_number operator_name ( op_type, op_type )\n" +#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" +#~ " } [, ... ]\n" +#~ "ALTER OPERATOR FAMILY name USING index_method DROP\n" +#~ " { OPERATOR strategy_number ( op_type [ , op_type ] )\n" +#~ " | FUNCTION support_number ( op_type [ , op_type ] )\n" +#~ " } [, ... ]\n" +#~ "ALTER OPERATOR FAMILY name USING index_method RENAME TO newname\n" +#~ "ALTER OPERATOR FAMILY name USING index_method OWNER TO newowner" +#~ msgstr "" +#~ "ALTER OPERATOR FAMILY adı USING index_methodu ADD\n" +#~ " { OPERATOR strategy_number operator_name ( op_type, op_type )\n" +#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" +#~ " } [, ... ]\n" +#~ "ALTER OPERATOR FAMILY ad USING index_methodu DROP\n" +#~ " { OPERATOR strategy_number ( op_type [ , op_type ] )\n" +#~ " | FUNCTION support_number ( op_type [ , op_type ] )\n" +#~ " } [, ... ]\n" +#~ "ALTER OPERATOR FAMILY ad USING index_methodu RENAME TO yeni ad\n" +#~ "ALTER OPERATOR FAMILY ad USING index_methodu OWNER TO yeni sahibi" + +#~ msgid "" +#~ "ALTER ROLE name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ "\n" +#~ "ALTER ROLE name RENAME TO newname\n" +#~ "\n" +#~ "ALTER ROLE name SET configuration_parameter { TO | = } { value | DEFAULT }\n" +#~ "ALTER ROLE name SET configuration_parameter FROM CURRENT\n" +#~ "ALTER ROLE name RESET configuration_parameter\n" +#~ "ALTER ROLE name RESET ALL" +#~ msgstr "" +#~ "ALTER ROLE rol_adı [ [ WITH ] seçenek [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT baÄŸlantı_sayısı_sınırı\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ "\n" +#~ "ALTER ROLE rol_adı RENAME TO yeni_adı\n" +#~ "\n" +#~ "ALTER ROLE rol_adı SET yapılandırma_parametresi { TO | = } { value | DEFAULT }\n" +#~ "ALTER ROLE rol_adı SET yapılandırma_parametresi FROM CURRENT\n" +#~ "ALTER ROLE rol_adı RESET yapılandırma_parametresi\n" +#~ "ALTER ROLE rol_adı RESET ALL" + +#~ msgid "" +#~ "ALTER SCHEMA name RENAME TO newname\n" +#~ "ALTER SCHEMA name OWNER TO newowner" +#~ msgstr "" +#~ "ALTER SCHEMA ÅŸema_adı RENAME TO yeni_ad\n" +#~ "ALTER SCHEMA ÅŸema_adı OWNER TO yeni_sahip" + +#~ msgid "" +#~ "ALTER SEQUENCE name [ INCREMENT [ BY ] increment ]\n" +#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" +#~ " [ START [ WITH ] start ]\n" +#~ " [ RESTART [ [ WITH ] restart ] ]\n" +#~ " [ CACHE cache ] [ [ NO ] CYCLE ]\n" +#~ " [ OWNED BY { table.column | NONE } ]\n" +#~ "ALTER SEQUENCE name OWNER TO new_owner\n" +#~ "ALTER SEQUENCE name RENAME TO new_name\n" +#~ "ALTER SEQUENCE name SET SCHEMA new_schema" +#~ msgstr "" +#~ "ALTER SEQUENCE ad [ INCREMENT [ BY ] arttırma miktarı ]\n" +#~ " [ MINVALUE en az deÄŸer | NO MINVALUE ] [ MAXVALUE üst deÄŸer | NO MAXVALUE ]\n" +#~ " [ START [ WITH ] baÅŸlama sayısı ]\n" +#~ " [ RESTART [ [ WITH ] yeniden baÅŸlama sayısı ] ]\n" +#~ " [ CACHE önbellek ] [ [ NO ] CYCLE ]\n" +#~ " [ OWNED BY { tablo.kolon | NONE } ]\n" +#~ "ALTER SEQUENCE ad OWNER TO yeni sahibir\n" +#~ "ALTER SEQUENCE ad RENAME TO yeni adı\n" +#~ "ALTER SEQUENCE namade SET SCHEMA yeni ÅŸeması" + +#~ msgid "" +#~ "ALTER SERVER servername [ VERSION 'newversion' ]\n" +#~ " [ OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] ) ]\n" +#~ "ALTER SERVER servername OWNER TO new_owner" +#~ msgstr "" +#~ "ALTER SERVER sunucu adı [ VERSION 'yeni sürüm' ]\n" +#~ " [ OPTIONS ( [ ADD | SET | DROP ] seçenek ['deÄŸer'] [, ... ] ) ]\n" +#~ "ALTER SERVER sunucu adı OWNER TO yeni sahibi" + +#~ msgid "" +#~ "ALTER TABLE [ ONLY ] name [ * ]\n" +#~ " action [, ... ]\n" +#~ "ALTER TABLE [ ONLY ] name [ * ]\n" +#~ " RENAME [ COLUMN ] column TO new_column\n" +#~ "ALTER TABLE name\n" +#~ " RENAME TO new_name\n" +#~ "ALTER TABLE name\n" +#~ " SET SCHEMA new_schema\n" +#~ "\n" +#~ "where action is one of:\n" +#~ "\n" +#~ " ADD [ COLUMN ] column type [ column_constraint [ ... ] ]\n" +#~ " DROP [ COLUMN ] column [ RESTRICT | CASCADE ]\n" +#~ " ALTER [ COLUMN ] column [ SET DATA ] TYPE type [ USING expression ]\n" +#~ " ALTER [ COLUMN ] column SET DEFAULT expression\n" +#~ " ALTER [ COLUMN ] column DROP DEFAULT\n" +#~ " ALTER [ COLUMN ] column { SET | DROP } NOT NULL\n" +#~ " ALTER [ COLUMN ] column SET STATISTICS integer\n" +#~ " ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" +#~ " ADD table_constraint\n" +#~ " DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]\n" +#~ " DISABLE TRIGGER [ trigger_name | ALL | USER ]\n" +#~ " ENABLE TRIGGER [ trigger_name | ALL | USER ]\n" +#~ " ENABLE REPLICA TRIGGER trigger_name\n" +#~ " ENABLE ALWAYS TRIGGER trigger_name\n" +#~ " DISABLE RULE rewrite_rule_name\n" +#~ " ENABLE RULE rewrite_rule_name\n" +#~ " ENABLE REPLICA RULE rewrite_rule_name\n" +#~ " ENABLE ALWAYS RULE rewrite_rule_name\n" +#~ " CLUSTER ON index_name\n" +#~ " SET WITHOUT CLUSTER\n" +#~ " SET WITH OIDS\n" +#~ " SET WITHOUT OIDS\n" +#~ " SET ( storage_parameter = value [, ... ] )\n" +#~ " RESET ( storage_parameter [, ... ] )\n" +#~ " INHERIT parent_table\n" +#~ " NO INHERIT parent_table\n" +#~ " OWNER TO new_owner\n" +#~ " SET TABLESPACE new_tablespace" +#~ msgstr "" +#~ "ALTER TABLE [ ONLY ] ad [ * ]\n" +#~ " action [, ... ]\n" +#~ "ALTER TABLE [ ONLY ] ad [ * ]\n" +#~ " RENAME [ COLUMN ] kolon TO yeni kolon\n" +#~ "ALTER TABLE ad\n" +#~ " RENAME TO yeni ad\n" +#~ "ALTER TABLE ad\n" +#~ " SET SCHEMA yeni ÅŸema\n" +#~ "\n" +#~ "action aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " ADD [ COLUMN ] kolon kolon_tipi [ kolon kısıtlaması [ ... ] ]\n" +#~ " DROP [ COLUMN ] kolon [ RESTRICT | CASCADE ]\n" +#~ " ALTER [ COLUMN ] kolon [ SET DATA ] TYPE type [ USING ifade ]\n" +#~ " ALTER [ COLUMN ] kolon SET DEFAULT ifade\n" +#~ " ALTER [ COLUMN ] kolon DROP DEFAULT\n" +#~ " ALTER [ COLUMN ] kolon { SET | DROP } NOT NULL\n" +#~ " ALTER [ COLUMN ] kolon SET STATISTICS tamsayı\n" +#~ " ALTER [ COLUMN ] kolon SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }\n" +#~ " ADD tablo kısıtlaması\n" +#~ " DROP CONSTRAINT kısıtlama adı [ RESTRICT | CASCADE ]\n" +#~ " DISABLE TRIGGER [ trigger adı | ALL | USER ]\n" +#~ " ENABLE TRIGGER[ trigger adı | ALL | USER ]\n" +#~ " ENABLE REPLICA TRIGGER trigger adı\n" +#~ " ENABLE ALWAYS TRIGGER trigger adı\n" +#~ " DISABLE RULE rewrite_rule_name\n" +#~ " ENABLE RULE rewrite_rule_name\n" +#~ " ENABLE REPLICA RULE rewrite_rule_name\n" +#~ " ENABLE ALWAYS RULE rewrite_rule_name\n" +#~ " CLUSTER ON index adı\n" +#~ " SET WITHOUT CLUSTER\n" +#~ " SET WITH OIDS\n" +#~ " SET WITHOUT OIDS\n" +#~ " SET ( storage_parameter = value [, ... ] )\n" +#~ " RESET ( storage_parameter [, ... ] )\n" +#~ " INHERIT üst tablo\n" +#~ " NO INHERIT üst tablo\n" +#~ " OWNER TO yeni sahibi\n" +#~ " SET TABLESPACE yeni tablespace" + +#~ msgid "" +#~ "ALTER TABLESPACE name RENAME TO newname\n" +#~ "ALTER TABLESPACE name OWNER TO newowner" +#~ msgstr "" +#~ "ALTER TABLESPACE tablespace_adı RENAME TO yeni_ad\n" +#~ "ALTER TABLESPACE tablespace_adı OWNER TO yeni_sahip" + +#~ msgid "" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ADD MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING REPLACE old_dictionary WITH new_dictionary\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING FOR token_type [, ... ] REPLACE old_dictionary WITH new_dictionary\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " DROP MAPPING [ IF EXISTS ] FOR token_type [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name RENAME TO newname\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name OWNER TO newowner" +#~ msgstr "" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ADD MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING FOR token_type [, ... ] WITH dictionary_name [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING REPLACE old_dictionary WITH new_dictionary\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " ALTER MAPPING FOR token_type [, ... ] REPLACE old_dictionary WITH new_dictionary\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name\n" +#~ " DROP MAPPING [ IF EXISTS ] FOR token_type [, ... ]\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name RENAME TO newname\n" +#~ "ALTER TEXT SEARCH CONFIGURATION name OWNER TO newowner" + +#~ msgid "" +#~ "ALTER TEXT SEARCH DICTIONARY name (\n" +#~ " option [ = value ] [, ... ]\n" +#~ ")\n" +#~ "ALTER TEXT SEARCH DICTIONARY name RENAME TO newname\n" +#~ "ALTER TEXT SEARCH DICTIONARY name OWNER TO newowner" +#~ msgstr "" +#~ "ALTER TEXT SEARCH DICTIONARY ad (\n" +#~ " option [ = value ] [, ... ]\n" +#~ ")\n" +#~ "ALTER TEXT SEARCH DICTIONARY ad RENAME TO yeni adı\n" +#~ "ALTER TEXT SEARCH DICTIONARY ad OWNER TO yeni sahibi" + +#~ msgid "ALTER TEXT SEARCH PARSER name RENAME TO newname" +#~ msgstr "ALTER TEXT SEARCH PARSER ayrıştırıcı_adı RENAME TO yeni_adı" + +#~ msgid "ALTER TEXT SEARCH TEMPLATE name RENAME TO newname" +#~ msgstr "ALTER TEXT SEARCH TEMPLATE ÅŸablon_adı RENAME TO yeni_adı" + +#~ msgid "ALTER TRIGGER name ON table RENAME TO newname" +#~ msgstr "ALTER TRIGGER trigger_adı ON tablo_adı RENAME TO yeni_ad" + +#~ msgid "" +#~ "ALTER TYPE name RENAME TO new_name\n" +#~ "ALTER TYPE name OWNER TO new_owner \n" +#~ "ALTER TYPE name SET SCHEMA new_schema" +#~ msgstr "" +#~ "ALTER TYPE ad RENAME TO yeni adı\n" +#~ "ALTER TYPE ad OWNER TO yeni sahibi \n" +#~ "ALTER TYPE ad SET SCHEMA yeni ÅŸema" + +#~ msgid "" +#~ "ALTER USER name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ "\n" +#~ "ALTER USER name RENAME TO newname\n" +#~ "\n" +#~ "ALTER USER name SET configuration_parameter { TO | = } { value | DEFAULT }\n" +#~ "ALTER USER name SET configuration_parameter FROM CURRENT\n" +#~ "ALTER USER name RESET configuration_parameter\n" +#~ "ALTER USER name RESET ALL" +#~ msgstr "" +#~ "ALTER USER kullanıcı_adı [ [ WITH ] seçenek [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT baÄŸlantı_sayısı_sınırı\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ "\n" +#~ "ALTER USER kullanıcı_adı RENAME TO yeni_adı\n" +#~ "\n" +#~ "ALTER USER kullanıcı_adı SET yapılandırma_parametresi { TO | = } { value | DEFAULT }\n" +#~ "ALTER USER kullanıcı_adı SET yapılandırma_parametresi FROM CURRENT\n" +#~ "ALTER USER kullanıcı_adı RESET yapılandırma_parametresi\n" +#~ "ALTER USER kullanıcı_adı RESET ALL" + +#~ msgid "" +#~ "ALTER USER MAPPING FOR { username | USER | CURRENT_USER | PUBLIC }\n" +#~ " SERVER servername\n" +#~ " OPTIONS ( [ ADD | SET | DROP ] option ['value'] [, ... ] )" +#~ msgstr "" +#~ "ALTER USER MAPPING FOR { kullanıcı adı | USER | CURRENT_USER | PUBLIC }\n" +#~ " SERVER sunucu adı\n" +#~ " OPTIONS ( [ ADD | SET | DROP ] seçenek ['deÄŸer'] [, ... ] )" + +#~ msgid "" +#~ "ALTER VIEW name ALTER [ COLUMN ] column SET DEFAULT expression\n" +#~ "ALTER VIEW name ALTER [ COLUMN ] column DROP DEFAULT\n" +#~ "ALTER VIEW name OWNER TO new_owner\n" +#~ "ALTER VIEW name RENAME TO new_name\n" +#~ "ALTER VIEW name SET SCHEMA new_schema" +#~ msgstr "" +#~ "ALTER VIEW ad ALTER [ COLUMN ] kolon SET DEFAULT ifade\n" +#~ "ALTER VIEW ad ALTER [ COLUMN ] kolon DROP DEFAULT\n" +#~ "ALTER VIEW ad OWNER TO yeni sahibi\n" +#~ "ALTER VIEW ad RENAME TO yeni adı\n" +#~ "ALTER VIEW ad SET SCHEMA yeni ÅŸema" + +#~ msgid "ANALYZE [ VERBOSE ] [ table [ ( column [, ...] ) ] ]" +#~ msgstr "ANALYZE [ VERBOSE ] [ tablo [ ( kolon [, ...] ) ] ]" + +#~ msgid "" +#~ "BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]\n" +#~ "\n" +#~ "where transaction_mode is one of:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" +#~ msgstr "" +#~ "BEGIN [ WORK | TRANSACTION ] [ transaction_modu [, ...] ]\n" +#~ "\n" +#~ "transaction_modu aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" + +#~ msgid "CHECKPOINT" +#~ msgstr "CHECKPOINT" + +#~ msgid "CLOSE { name | ALL }" +#~ msgstr "CLOSE { name | ALL }" + +#~ msgid "" +#~ "CLUSTER [VERBOSE] tablename [ USING indexname ]\n" +#~ "CLUSTER [VERBOSE]" +#~ msgstr "" +#~ "CLUSTER [VERBOSE] tablo adı [ USING index adı ]\n" +#~ "CLUSTER [VERBOSE]" + +#~ msgid "" +#~ "COMMENT ON\n" +#~ "{\n" +#~ " TABLE object_name |\n" +#~ " COLUMN table_name.column_name |\n" +#~ " AGGREGATE agg_name (agg_type [, ...] ) |\n" +#~ " CAST (sourcetype AS targettype) |\n" +#~ " CONSTRAINT constraint_name ON table_name |\n" +#~ " CONVERSION object_name |\n" +#~ " DATABASE object_name |\n" +#~ " DOMAIN object_name |\n" +#~ " FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [, ...] ] ) |\n" +#~ " INDEX object_name |\n" +#~ " LARGE OBJECT large_object_oid |\n" +#~ " OPERATOR op (leftoperand_type, rightoperand_type) |\n" +#~ " OPERATOR CLASS object_name USING index_method |\n" +#~ " OPERATOR FAMILY object_name USING index_method |\n" +#~ " [ PROCEDURAL ] LANGUAGE object_name |\n" +#~ " ROLE object_name |\n" +#~ " RULE rule_name ON table_name |\n" +#~ " SCHEMA object_name |\n" +#~ " SEQUENCE object_name |\n" +#~ " TABLESPACE object_name |\n" +#~ " TEXT SEARCH CONFIGURATION object_name |\n" +#~ " TEXT SEARCH DICTIONARY object_name |\n" +#~ " TEXT SEARCH PARSER object_name |\n" +#~ " TEXT SEARCH TEMPLATE object_name |\n" +#~ " TRIGGER trigger_name ON table_name |\n" +#~ " TYPE object_name |\n" +#~ " VIEW object_name\n" +#~ "} IS 'text'" +#~ msgstr "" +#~ "COMMENT ON\n" +#~ "{\n" +#~ " TABLE nesne_ado |\n" +#~ " COLUMN tablo_adı.kolon_adı |\n" +#~ " AGGREGATE agg_name (agg_type [, ...] ) |\n" +#~ " CAST (sourcetype AS targettype) |\n" +#~ " CONSTRAINT constraint_name ON table_name |\n" +#~ " CONVERSION nesne_adı |\n" +#~ " DATABASE nesne_adı |\n" +#~ " DOMAIN nesne_adı |\n" +#~ " FUNCTION fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] ) |\n" +#~ " INDEX nesne_adı |\n" +#~ " LARGE OBJECT large_object_oid |\n" +#~ " OPERATOR op (leftoperand_type, rightoperand_type) |\n" +#~ " OPERATOR CLASS nesne_adı USING index_yöntemi |\n" +#~ " OPERATOR FAMILY nesne_adı USING index_yöntemi |\n" +#~ " [ PROCEDURAL ] LANGUAGE nesne_adı |\n" +#~ " ROLE nesne_adı |\n" +#~ " RULE kural_adı ON tablo_adı |\n" +#~ " SCHEMA nesne_adı |\n" +#~ " SEQUENCE nesne_adı |\n" +#~ " TABLESPACE nesne_adı |\n" +#~ " TEXT SEARCH CONFIGURATION nesne_adı |\n" +#~ " TEXT SEARCH DICTIONARY nesne_adı |\n" +#~ " TEXT SEARCH PARSER nesne_adı |\n" +#~ " TEXT SEARCH TEMPLATE nesne_adı |\n" +#~ " TRIGGER tetikleyici_adı ON table_name |\n" +#~ " TYPE nesne_adı |\n" +#~ " VIEW nesne_adı\n" +#~ "} IS 'text'" + +#~ msgid "COMMIT [ WORK | TRANSACTION ]" +#~ msgstr "COMMIT [ WORK | TRANSACTION ]" + +#~ msgid "COMMIT PREPARED transaction_id" +#~ msgstr "COMMIT PREPARED transaction_id" + +#~ msgid "" +#~ "COPY tablename [ ( column [, ...] ) ]\n" +#~ " FROM { 'filename' | STDIN }\n" +#~ " [ [ WITH ] \n" +#~ " [ BINARY ]\n" +#~ " [ OIDS ]\n" +#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" +#~ " [ NULL [ AS ] 'null string' ]\n" +#~ " [ CSV [ HEADER ]\n" +#~ " [ QUOTE [ AS ] 'quote' ] \n" +#~ " [ ESCAPE [ AS ] 'escape' ]\n" +#~ " [ FORCE NOT NULL column [, ...] ]\n" +#~ "\n" +#~ "COPY { tablename [ ( column [, ...] ) ] | ( query ) }\n" +#~ " TO { 'filename' | STDOUT }\n" +#~ " [ [ WITH ] \n" +#~ " [ BINARY ]\n" +#~ " [ OIDS ]\n" +#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" +#~ " [ NULL [ AS ] 'null string' ]\n" +#~ " [ CSV [ HEADER ]\n" +#~ " [ QUOTE [ AS ] 'quote' ] \n" +#~ " [ ESCAPE [ AS ] 'escape' ]\n" +#~ " [ FORCE QUOTE column [, ...] ]" +#~ msgstr "" +#~ "COPY tablo adı [ ( kolon [, ...] ) ]\n" +#~ " FROM { 'dosya adı' | STDIN }\n" +#~ " [ [ WITH ] \n" +#~ " [ BINARY ]\n" +#~ " [ OIDS ]\n" +#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" +#~ " [ NULL [ AS ] 'null string' ]\n" +#~ " [ CSV [ HEADER ]\n" +#~ " [ QUOTE [ AS ] 'quote' ] \n" +#~ " [ ESCAPE [ AS ] 'escape' ]\n" +#~ " [ FORCE NOT NULL column [, ...] ]\n" +#~ "\n" +#~ "COPY { tablo adı [ ( kolon [, ...] ) ] | ( sorgu ) }\n" +#~ " TO { 'dosya adı' | STDOUT }\n" +#~ " [ [ WITH ] \n" +#~ " [ BINARY ]\n" +#~ " [ OIDS ]\n" +#~ " [ DELIMITER [ AS ] 'delimiter' ]\n" +#~ " [ NULL [ AS ] 'null string' ]\n" +#~ " [ CSV [ HEADER ]\n" +#~ " [ QUOTE [ AS ] 'quote' ] \n" +#~ " [ ESCAPE [ AS ] 'escape' ]\n" +#~ " [ FORCE QUOTE column [, ...] ]" + +#~ msgid "" +#~ "CREATE AGGREGATE name ( input_data_type [ , ... ] ) (\n" +#~ " SFUNC = sfunc,\n" +#~ " STYPE = state_data_type\n" +#~ " [ , FINALFUNC = ffunc ]\n" +#~ " [ , INITCOND = initial_condition ]\n" +#~ " [ , SORTOP = sort_operator ]\n" +#~ ")\n" +#~ "\n" +#~ "or the old syntax\n" +#~ "\n" +#~ "CREATE AGGREGATE name (\n" +#~ " BASETYPE = base_type,\n" +#~ " SFUNC = sfunc,\n" +#~ " STYPE = state_data_type\n" +#~ " [ , FINALFUNC = ffunc ]\n" +#~ " [ , INITCOND = initial_condition ]\n" +#~ " [ , SORTOP = sort_operator ]\n" +#~ ")" +#~ msgstr "" +#~ "CREATE AGGREGATE name ( input_data_type [ , ... ] ) (\n" +#~ " SFUNC = sfunc,\n" +#~ " STYPE = state_data_type\n" +#~ " [ , FINALFUNC = ffunc ]\n" +#~ " [ , INITCOND = initial_condition ]\n" +#~ " [ , SORTOP = sort_operator ]\n" +#~ ")\n" +#~ "\n" +#~ "or the old syntax\n" +#~ "\n" +#~ "CREATE AGGREGATE name (\n" +#~ " BASETYPE = base_type,\n" +#~ " SFUNC = sfunc,\n" +#~ " STYPE = state_data_type\n" +#~ " [ , FINALFUNC = ffunc ]\n" +#~ " [ , INITCOND = initial_condition ]\n" +#~ " [ , SORTOP = sort_operator ]\n" +#~ ")" + +#~ msgid "" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITH FUNCTION funcname (argtypes)\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" +#~ "\n" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITHOUT FUNCTION\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" +#~ "\n" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITH INOUT\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" +#~ msgstr "" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITH FUNCTION funcname (argtypes)\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" +#~ "\n" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITHOUT FUNCTION\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]\n" +#~ "\n" +#~ "CREATE CAST (sourcetype AS targettype)\n" +#~ " WITH INOUT\n" +#~ " [ AS ASSIGNMENT | AS IMPLICIT ]" + +#~ msgid "" +#~ "CREATE CONSTRAINT TRIGGER name\n" +#~ " AFTER event [ OR ... ]\n" +#~ " ON table_name\n" +#~ " [ FROM referenced_table_name ]\n" +#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" +#~ " FOR EACH ROW\n" +#~ " EXECUTE PROCEDURE funcname ( arguments )" +#~ msgstr "" +#~ "CREATE CONSTRAINT TRIGGER name\n" +#~ " AFTER event [ OR ... ]\n" +#~ " ON table_name\n" +#~ " [ FROM referenced_table_name ]\n" +#~ " { NOT DEFERRABLE | [ DEFERRABLE ] { INITIALLY IMMEDIATE | INITIALLY DEFERRED } }\n" +#~ " FOR EACH ROW\n" +#~ " EXECUTE PROCEDURE funcname ( arguments )" + +#~ msgid "" +#~ "CREATE [ DEFAULT ] CONVERSION name\n" +#~ " FOR source_encoding TO dest_encoding FROM funcname" +#~ msgstr "" +#~ "CREATE [ DEFAULT ] CONVERSION name\n" +#~ " FOR source_encoding TO dest_encoding FROM funcname" + +#~ msgid "" +#~ "CREATE DATABASE name\n" +#~ " [ [ WITH ] [ OWNER [=] dbowner ]\n" +#~ " [ TEMPLATE [=] template ]\n" +#~ " [ ENCODING [=] encoding ]\n" +#~ " [ LC_COLLATE [=] lc_collate ]\n" +#~ " [ LC_CTYPE [=] lc_ctype ]\n" +#~ " [ TABLESPACE [=] tablespace ]\n" +#~ " [ CONNECTION LIMIT [=] connlimit ] ]" +#~ msgstr "" +#~ "CREATE DATABASE ad\n" +#~ " [ [ WITH ] [ OWNER [=] veritabanı sahibi ]\n" +#~ " [ TEMPLATE [=] ÅŸablon ]\n" +#~ " [ ENCODING [=] dil kodlaması ]\n" +#~ " [ LC_COLLATE [=] lc_collate ]\n" +#~ " [ LC_CTYPE [=] lc_ctype ]\n" +#~ " [ TABLESPACE [=] tablespace ]\n" +#~ " [ CONNECTION LIMIT [=] baÄŸlantı sınırı ] ]" + +#~ msgid "" +#~ "CREATE DOMAIN name [ AS ] data_type\n" +#~ " [ DEFAULT expression ]\n" +#~ " [ constraint [ ... ] ]\n" +#~ "\n" +#~ "where constraint is:\n" +#~ "\n" +#~ "[ CONSTRAINT constraint_name ]\n" +#~ "{ NOT NULL | NULL | CHECK (expression) }" +#~ msgstr "" +#~ "CREATE DOMAIN name [ AS ] data_type\n" +#~ " [ DEFAULT expression ]\n" +#~ " [ constraint [ ... ] ]\n" +#~ "\n" +#~ "constraint aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ "[ CONSTRAINT constraint_name ]\n" +#~ "{ NOT NULL | NULL | CHECK (expression) }" + +#~ msgid "" +#~ "CREATE FOREIGN DATA WRAPPER name\n" +#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" +#~ " [ OPTIONS ( option 'value' [, ... ] ) ]" +#~ msgstr "" +#~ "CREATE FOREIGN DATA WRAPPER ad\n" +#~ " [ VALIDATOR valfunction | NO VALIDATOR ]\n" +#~ " [ OPTIONS ( option 'value' [, ... ] ) ]" + +#~ msgid "" +#~ "CREATE [ OR REPLACE ] FUNCTION\n" +#~ " name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } defexpr ] [, ...] ] )\n" +#~ " [ RETURNS rettype\n" +#~ " | RETURNS TABLE ( colname coltype [, ...] ) ]\n" +#~ " { LANGUAGE langname\n" +#~ " | WINDOW\n" +#~ " | IMMUTABLE | STABLE | VOLATILE\n" +#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" +#~ " | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" +#~ " | COST execution_cost\n" +#~ " | ROWS result_rows\n" +#~ " | SET configuration_parameter { TO value | = value | FROM CURRENT }\n" +#~ " | AS 'definition'\n" +#~ " | AS 'obj_file', 'link_symbol'\n" +#~ " } ...\n" +#~ " [ WITH ( attribute [, ...] ) ]" +#~ msgstr "" +#~ "CREATE [ OR REPLACE ] FUNCTION\n" +#~ " ad ( [ [ argüman modu ] [ argüman adı ] argüman tipi [ { DEFAULT | = } defexpr ] [, ...] ] )\n" +#~ " [ RETURNS rettype\n" +#~ " | RETURNS TABLE ( kolon_adı kolon_tipi [, ...] ) ]\n" +#~ " { LANGUAGE dil adı\n" +#~ " | WINDOW\n" +#~ " | IMMUTABLE | STABLE | VOLATILE\n" +#~ " | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT\n" +#~ " | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER\n" +#~ " | COST execution_cost\n" +#~ " | ROWS result_rows\n" +#~ " | SET yapılandırma parametresi { TO deÄŸer | = deÄŸer | FROM CURRENT }\n" +#~ " | AS 'tanım'\n" +#~ " | AS 'obj_file', 'link_symbol'\n" +#~ " } ...\n" +#~ " [ WITH ( attribute [, ...] ) ]" + +#~ msgid "" +#~ "CREATE GROUP name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" +#~ msgstr "" +#~ "CREATE GROUP name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'ÅŸifre'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" + +#~ msgid "" +#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]\n" +#~ " ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )\n" +#~ " [ WITH ( storage_parameter = value [, ... ] ) ]\n" +#~ " [ TABLESPACE tablespace ]\n" +#~ " [ WHERE predicate ]" +#~ msgstr "" +#~ "CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] name ON table [ USING method ]\n" +#~ " ( { column | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )\n" +#~ " [ WITH ( storage_parameter = value [, ... ] ) ]\n" +#~ " [ TABLESPACE tablespace ]\n" +#~ " [ WHERE predicate ]" + +#~ msgid "" +#~ "CREATE [ PROCEDURAL ] LANGUAGE name\n" +#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\n" +#~ " HANDLER call_handler [ VALIDATOR valfunction ]" +#~ msgstr "" +#~ "CREATE [ PROCEDURAL ] LANGUAGE name\n" +#~ "CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name\n" +#~ " HANDLER call_handler [ VALIDATOR valfunction ]" + +#~ msgid "" +#~ "CREATE OPERATOR name (\n" +#~ " PROCEDURE = funcname\n" +#~ " [, LEFTARG = lefttype ] [, RIGHTARG = righttype ]\n" +#~ " [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]\n" +#~ " [, RESTRICT = res_proc ] [, JOIN = join_proc ]\n" +#~ " [, HASHES ] [, MERGES ]\n" +#~ ")" +#~ msgstr "" +#~ "CREATE OPERATOR name (\n" +#~ " PROCEDURE = funcname\n" +#~ " [, LEFTARG = lefttype ] [, RIGHTARG = righttype ]\n" +#~ " [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]\n" +#~ " [, RESTRICT = res_proc ] [, JOIN = join_proc ]\n" +#~ " [, HASHES ] [, MERGES ]\n" +#~ ")" + +#~ msgid "" +#~ "CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type\n" +#~ " USING index_method [ FAMILY family_name ] AS\n" +#~ " { OPERATOR strategy_number operator_name [ ( op_type, op_type ) ]\n" +#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] funcname ( argument_type [, ...] )\n" +#~ " | STORAGE storage_type\n" +#~ " } [, ... ]" +#~ msgstr "" +#~ "CREATE OPERATOR CLASS ad [ DEFAULT ] FOR TYPE veri tipi\n" +#~ " USING index metodu [ FAMILY family_name ] AS\n" +#~ " { OPERATOR strategy_number operatör adı [ ( op_type, op_type ) ]\n" +#~ " | FUNCTION support_number [ ( op_type [ , op_type ] ) ] fonksiyon adı ( argument_type [, ...] )\n" +#~ " | STORAGE storage_type\n" +#~ " } [, ... ]" + +#~ msgid "CREATE OPERATOR FAMILY name USING index_method" +#~ msgstr "CREATE OPERATOR FAMILY name USING index_method" + +#~ msgid "" +#~ "CREATE ROLE name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" +#~ msgstr "" +#~ "CREATE ROLE name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" + +#~ msgid "" +#~ "CREATE [ OR REPLACE ] RULE name AS ON event\n" +#~ " TO table [ WHERE condition ]\n" +#~ " DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }" +#~ msgstr "" +#~ "CREATE [ OR REPLACE ] RULE name AS ON event\n" +#~ " TO tablo_adı [ WHERE condition ]\n" +#~ " DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }" + +#~ msgid "" +#~ "CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ schema_element [ ... ] ]\n" +#~ "CREATE SCHEMA AUTHORIZATION username [ schema_element [ ... ] ]" +#~ msgstr "" +#~ "CREATE SCHEMA schemaname [ AUTHORIZATION username ] [ TABLESPACE tablespace ] [ schema_element [ ... ] ]\n" +#~ "CREATE SCHEMA AUTHORIZATION username [ TABLESPACE tablespace ] [ schema_element [ ... ] ]" + +#~ msgid "" +#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]\n" +#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" +#~ " [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" +#~ " [ OWNED BY { table.column | NONE } ]" +#~ msgstr "" +#~ "CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]\n" +#~ " [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]\n" +#~ " [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]\n" +#~ " [ OWNED BY { table.column | NONE } ]" + +#~ msgid "" +#~ "CREATE SERVER servername [ TYPE 'servertype' ] [ VERSION 'serverversion' ]\n" +#~ " FOREIGN DATA WRAPPER fdwname\n" +#~ " [ OPTIONS ( option 'value' [, ... ] ) ]" +#~ msgstr "" +#~ "CREATE SERVER sunucu adı [ TYPE 'sunucu tipi' ] [ VERSION 'sunucu sürümü' ]\n" +#~ " FOREIGN DATA WRAPPER fdw adı\n" +#~ " [ OPTIONS ( seçenek 'deÄŸer' [, ... ] ) ]" + +#~ msgid "" +#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name ( [\n" +#~ " { column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]\n" +#~ " | table_constraint\n" +#~ " | LIKE parent_table [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }\n" +#~ " [, ... ]\n" +#~ "] )\n" +#~ "[ INHERITS ( parent_table [, ... ] ) ]\n" +#~ "[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" +#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" +#~ "[ TABLESPACE tablespace ]\n" +#~ "\n" +#~ "where column_constraint is:\n" +#~ "\n" +#~ "[ CONSTRAINT constraint_name ]\n" +#~ "{ NOT NULL | \n" +#~ " NULL | \n" +#~ " UNIQUE index_parameters |\n" +#~ " PRIMARY KEY index_parameters |\n" +#~ " CHECK ( expression ) |\n" +#~ " REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" +#~ " [ ON DELETE action ] [ ON UPDATE action ] }\n" +#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" +#~ "\n" +#~ "and table_constraint is:\n" +#~ "\n" +#~ "[ CONSTRAINT constraint_name ]\n" +#~ "{ UNIQUE ( column_name [, ... ] ) index_parameters |\n" +#~ " PRIMARY KEY ( column_name [, ... ] ) index_parameters |\n" +#~ " CHECK ( expression ) |\n" +#~ " FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]\n" +#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }\n" +#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" +#~ "\n" +#~ "index_parameters in UNIQUE and PRIMARY KEY constraints are:\n" +#~ "\n" +#~ "[ WITH ( storage_parameter [= value] [, ... ] ) ]\n" +#~ "[ USING INDEX TABLESPACE tablespace ]" +#~ msgstr "" +#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE tablo_adı ( [\n" +#~ " { kolon_adı veri_tipi [ DEFAULT default_expr ] [ kolon_kısıtlayıcısı [ ... ] ]\n" +#~ " | tablo_kısıtlayıcısı\n" +#~ " | LIKE parent_table [ { INCLUDING | EXCLUDING } { DEFAULTS | CONSTRAINTS | INDEXES } ] ... }\n" +#~ " [, ... ]\n" +#~ "] )\n" +#~ "[ INHERITS ( parent_table [, ... ] ) ]\n" +#~ "[ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" +#~ "[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" +#~ "[ TABLESPACE tablo_uzayı ]\n" +#~ "\n" +#~ "kolon_kısıtlayıcısı aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ "im[ CONSTRAINT constraint_name ]\n" +#~ "{ NOT NULL | \n" +#~ " NULL | \n" +#~ " UNIQUE index_parametreleri |\n" +#~ " PRIMARY KEY index_parametreleri |\n" +#~ " CHECK ( ifade ) |\n" +#~ " REFERENCES referans_tablosu [ ( referans_kolonu ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]\n" +#~ " [ ON DELETE iÅŸlem ] [ ON UPDATE iÅŸlem ] }\n" +#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" +#~ "\n" +#~ "ve tablo_kısıtlayıcısı aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ "[ CONSTRAINT constraint_name ]\n" +#~ "{ UNIQUE ( column_name [, ... ] ) index_parameters |\n" +#~ " PRIMARY KEY ( column_name [, ... ] ) index_parameters |\n" +#~ " CHECK ( expression ) |\n" +#~ " FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]\n" +#~ " [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }\n" +#~ "[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]\n" +#~ "\n" +#~ "UNIQUE ve PRIMARY KEY kısıtlamalarındaki index parametreleri aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ "[ WITH ( storage_parameter [= value] [, ... ] ) ]\n" +#~ "[ USING INDEX TABLESPACE tablo_uzayı ]" + +#~ msgid "" +#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name\n" +#~ " [ (column_name [, ...] ) ]\n" +#~ " [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" +#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" +#~ " [ TABLESPACE tablespace ]\n" +#~ " AS query\n" +#~ " [ WITH [ NO ] DATA ]" +#~ msgstr "" +#~ "CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE tablo adı\n" +#~ " [ (kolon adı [, ...] ) ]\n" +#~ " [ WITH ( storage_parameter [= value] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]\n" +#~ " [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]\n" +#~ " [ TABLESPACE tablespace ]\n" +#~ " AS sorgu\n" +#~ " [ WITH [ NO ] DATA ]" + +#~ msgid "CREATE TABLESPACE tablespacename [ OWNER username ] LOCATION 'directory'" +#~ msgstr "CREATE TABLESPACE tablespacename [ OWNER username ] LOCATION 'directory'" + +#~ msgid "" +#~ "CREATE TEXT SEARCH CONFIGURATION name (\n" +#~ " PARSER = parser_name |\n" +#~ " COPY = source_config\n" +#~ ")" +#~ msgstr "" +#~ "CREATE TEXT SEARCH CONFIGURATION name (\n" +#~ " PARSER = parser_name |\n" +#~ " COPY = source_config\n" +#~ ")" + +#~ msgid "" +#~ "CREATE TEXT SEARCH DICTIONARY name (\n" +#~ " TEMPLATE = template\n" +#~ " [, option = value [, ... ]]\n" +#~ ")" +#~ msgstr "" +#~ "CREATE TEXT SEARCH DICTIONARY ad (\n" +#~ " TEMPLATE = ÅŸablon\n" +#~ " [, option = value [, ... ]]\n" +#~ ")" + +#~ msgid "" +#~ "CREATE TEXT SEARCH PARSER name (\n" +#~ " START = start_function ,\n" +#~ " GETTOKEN = gettoken_function ,\n" +#~ " END = end_function ,\n" +#~ " LEXTYPES = lextypes_function\n" +#~ " [, HEADLINE = headline_function ]\n" +#~ ")" +#~ msgstr "" +#~ "CREATE TEXT SEARCH PARSER name (\n" +#~ " START = start_function ,\n" +#~ " GETTOKEN = gettoken_function ,\n" +#~ " END = end_function ,\n" +#~ " LEXTYPES = lextypes_function\n" +#~ " [, HEADLINE = headline_function ]\n" +#~ ")" + +#~ msgid "" +#~ "CREATE TEXT SEARCH TEMPLATE name (\n" +#~ " [ INIT = init_function , ]\n" +#~ " LEXIZE = lexize_function\n" +#~ ")" +#~ msgstr "" +#~ "CREATE TEXT SEARCH TEMPLATE ad (\n" +#~ " [ INIT = init_function , ]\n" +#~ " LEXIZE = lexize_function\n" +#~ ")" + +#~ msgid "" +#~ "CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }\n" +#~ " ON table [ FOR [ EACH ] { ROW | STATEMENT } ]\n" +#~ " EXECUTE PROCEDURE funcname ( arguments )" +#~ msgstr "" +#~ "CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }\n" +#~ " ON table [ FOR [ EACH ] { ROW | STATEMENT } ]\n" +#~ " EXECUTE PROCEDURE funcname ( arguments )" + +#~ msgid "" +#~ "CREATE TYPE name AS\n" +#~ " ( attribute_name data_type [, ... ] )\n" +#~ "\n" +#~ "CREATE TYPE name AS ENUM\n" +#~ " ( 'label' [, ... ] )\n" +#~ "\n" +#~ "CREATE TYPE name (\n" +#~ " INPUT = input_function,\n" +#~ " OUTPUT = output_function\n" +#~ " [ , RECEIVE = receive_function ]\n" +#~ " [ , SEND = send_function ]\n" +#~ " [ , TYPMOD_IN = type_modifier_input_function ]\n" +#~ " [ , TYPMOD_OUT = type_modifier_output_function ]\n" +#~ " [ , ANALYZE = analyze_function ]\n" +#~ " [ , INTERNALLENGTH = { internallength | VARIABLE } ]\n" +#~ " [ , PASSEDBYVALUE ]\n" +#~ " [ , ALIGNMENT = alignment ]\n" +#~ " [ , STORAGE = storage ]\n" +#~ " [ , LIKE = like_type ]\n" +#~ " [ , CATEGORY = category ]\n" +#~ " [ , PREFERRED = preferred ]\n" +#~ " [ , DEFAULT = default ]\n" +#~ " [ , ELEMENT = element ]\n" +#~ " [ , DELIMITER = delimiter ]\n" +#~ ")\n" +#~ "\n" +#~ "CREATE TYPE name" +#~ msgstr "" +#~ "CREATE TYPE ad AS\n" +#~ " ( attribute_name veri tipi [, ... ] )\n" +#~ "\n" +#~ "CREATE TYPE ad AS ENUM\n" +#~ " ( 'label' [, ... ] )\n" +#~ "\n" +#~ "CREATE TYPE ad (\n" +#~ " INPUT = input_function,\n" +#~ " OUTPUT = output_function\n" +#~ " [ , RECEIVE = receive_function ]\n" +#~ " [ , SEND = send_function ]\n" +#~ " [ , TYPMOD_IN = type_modifier_input_function ]\n" +#~ " [ , TYPMOD_OUT = type_modifier_output_function ]\n" +#~ " [ , ANALYZE = analyze_function ]\n" +#~ " [ , INTERNALLENGTH = { internallength | VARIABLE } ]\n" +#~ " [ , PASSEDBYVALUE ]\n" +#~ " [ , ALIGNMENT = alignment ]\n" +#~ " [ , STORAGE = storage ]\n" +#~ " [ , LIKE = like_type ]\n" +#~ " [ , CATEGORY = category ]\n" +#~ " [ , PREFERRED = preferred ]\n" +#~ " [ , DEFAULT = default ]\n" +#~ " [ , ELEMENT = element ]\n" +#~ " [ , DELIMITER = delimiter ]\n" +#~ ")\n" +#~ "\n" +#~ "CREATE TYPE name" + +#~ msgid "" +#~ "CREATE USER name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "where option can be:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" +#~ msgstr "" +#~ "CREATE USER name [ [ WITH ] option [ ... ] ]\n" +#~ "\n" +#~ "seçenek aÅŸağıdakilerden birisi olabilir:\n" +#~ " \n" +#~ " SUPERUSER | NOSUPERUSER\n" +#~ " | CREATEDB | NOCREATEDB\n" +#~ " | CREATEROLE | NOCREATEROLE\n" +#~ " | CREATEUSER | NOCREATEUSER\n" +#~ " | INHERIT | NOINHERIT\n" +#~ " | LOGIN | NOLOGIN\n" +#~ " | CONNECTION LIMIT connlimit\n" +#~ " | [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'\n" +#~ " | VALID UNTIL 'timestamp' \n" +#~ " | IN ROLE rolename [, ...]\n" +#~ " | IN GROUP rolename [, ...]\n" +#~ " | ROLE rolename [, ...]\n" +#~ " | ADMIN rolename [, ...]\n" +#~ " | USER rolename [, ...]\n" +#~ " | SYSID uid" + +#~ msgid "" +#~ "CREATE USER MAPPING FOR { username | USER | CURRENT_USER | PUBLIC }\n" +#~ " SERVER servername\n" +#~ " [ OPTIONS ( option 'value' [ , ... ] ) ]" +#~ msgstr "" +#~ "CREATE USER MAPPING FOR { kullanıcı adı | USER | CURRENT_USER | PUBLIC }\n" +#~ " SERVER sunucu adı\n" +#~ " [ OPTIONS ( seçenek 'deÄŸer' [ , ... ] ) ]" + +#~ msgid "" +#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]\n" +#~ " AS query" +#~ msgstr "" +#~ "CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]\n" +#~ " AS query" + +#~ msgid "DEALLOCATE [ PREPARE ] { name | ALL }" +#~ msgstr "DEALLOCATE [ PREPARE ] { name | ALL }" + +#~ msgid "" +#~ "DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" +#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR query" +#~ msgstr "" +#~ "DECLARE ad [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]\n" +#~ " CURSOR [ { WITH | WITHOUT } HOLD ] FOR sorgu" + +#~ msgid "" +#~ "DELETE FROM [ ONLY ] table [ [ AS ] alias ]\n" +#~ " [ USING usinglist ]\n" +#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" +#~ msgstr "" +#~ "DELETE FROM [ ONLY ] tablo [ [ AS ] takma_adı ]\n" +#~ " [ USING usinglist ]\n" +#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" + +#~ msgid "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" +#~ msgstr "DISCARD { ALL | PLANS | TEMPORARY | TEMP }" + +#~ msgid "DROP AGGREGATE [ IF EXISTS ] name ( type [ , ... ] ) [ CASCADE | RESTRICT ]" +#~ msgstr "DROP AGGREGATE [ IF EXISTS ] name ( type [ , ... ] ) [ CASCADE | RESTRICT ]" + +#~ msgid "DROP CAST [ IF EXISTS ] (sourcetype AS targettype) [ CASCADE | RESTRICT ]" +#~ msgstr "DROP CAST [ IF EXISTS ] (sourcetype AS targettype) [ CASCADE | RESTRICT ]" + +#~ msgid "DROP CONVERSION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP CONVERSION [ IF EXISTS ] conversion_adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP DATABASE [ IF EXISTS ] name" +#~ msgstr "DROP DATABASE [ IF EXISTS ] veritabanı_adı" + +#~ msgid "DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP DOMAIN [ IF EXISTS ] adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP FOREIGN DATA WRAPPER [ IF EXISTS ] ad [ CASCADE | RESTRICT ]" + +#~ msgid "" +#~ "DROP FUNCTION [ IF EXISTS ] name ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " [ CASCADE | RESTRICT ]" +#~ msgstr "" +#~ "DROP FUNCTION [ IF EXISTS ] fonksiyon_adı ( [ [ argmode ] [ argname ] argtype [, ...] ] )\n" +#~ " [ CASCADE | RESTRICT ]" + +#~ msgid "DROP GROUP [ IF EXISTS ] name [, ...]" +#~ msgstr "DROP GROUP [ IF EXISTS ] name [, ...]" + +#~ msgid "DROP INDEX [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP INDEX [ IF EXISTS ] index_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP [ PROCEDURAL ] LANGUAGE [ IF EXISTS ] dil_adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP OPERATOR [ IF EXISTS ] name ( { lefttype | NONE } , { righttype | NONE } ) [ CASCADE | RESTRICT ]" +#~ msgstr "DROP OPERATOR [ IF EXISTS ] name ( { lefttype | NONE } , { righttype | NONE } ) [ CASCADE | RESTRICT ]" + +#~ msgid "DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" +#~ msgstr "DROP OPERATOR CLASS [ IF EXISTS ] ad USING index_method [ CASCADE | RESTRICT ]" + +#~ msgid "DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" +#~ msgstr "DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]" + +#~ msgid "DROP OWNED BY name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP OWNED BY name [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP ROLE [ IF EXISTS ] name [, ...]" +#~ msgstr "DROP ROLE [ IF EXISTS ] name [, ...]" + +#~ msgid "DROP RULE [ IF EXISTS ] name ON relation [ CASCADE | RESTRICT ]" +#~ msgstr "DROP RULE [ IF EXISTS ] rule_adı ON relation [ CASCADE | RESTRICT ]" + +#~ msgid "DROP SCHEMA [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP SCHEMA [ IF EXISTS ] ÅŸema_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP SEQUENCE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP SEQUENCE [ IF EXISTS ] sequence_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP SERVER [ IF EXISTS ] servername [ CASCADE | RESTRICT ]" +#~ msgstr "DROP SERVER [ IF EXISTS ] sunucu adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TABLE [ IF EXISTS ] tablo_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TABLESPACE [ IF EXISTS ] tablespacename" +#~ msgstr "DROP TABLESPACE [ IF EXISTS ] tablespace_adı" + +#~ msgid "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TEXT SEARCH CONFIGURATION [ IF EXISTS ] adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TEXT SEARCH DICTIONARY [ IF EXISTS ] adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TEXT SEARCH PARSER [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TEXT SEARCH PARSER [ IF EXISTS ] adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] name [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TEXT SEARCH TEMPLATE [ IF EXISTS ] adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TRIGGER [ IF EXISTS ] name ON table [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TRIGGER [ IF EXISTS ] trigger_adı ON tablo_adı [ CASCADE | RESTRICT ]" + +#~ msgid "DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP TYPE [ IF EXISTS ] tip_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "DROP USER [ IF EXISTS ] name [, ...]" +#~ msgstr "DROP USER [ IF EXISTS ] name [, ...]" + +#~ msgid "DROP USER MAPPING [ IF EXISTS ] FOR { username | USER | CURRENT_USER | PUBLIC } SERVER servername" +#~ msgstr "DROP USER MAPPING [ IF EXISTS ] FOR { kullanıcı adı | USER | CURRENT_USER | PUBLIC } SERVER sunucu adı" + +#~ msgid "DROP VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]" +#~ msgstr "DROP VIEW [ IF EXISTS ] view_adı [, ...] [ CASCADE | RESTRICT ]" + +#~ msgid "END [ WORK | TRANSACTION ]" +#~ msgstr "END [ WORK | TRANSACTION ]" + +#~ msgid "EXECUTE name [ ( parameter [, ...] ) ]" +#~ msgstr "EXECUTE adı [ ( parameter [, ...] ) ]" + +#~ msgid "EXPLAIN [ ANALYZE ] [ VERBOSE ] statement" +#~ msgstr "EXPLAIN [ ANALYZE ] [ VERBOSE ] ifade" + +#~ msgid "" +#~ "FETCH [ direction { FROM | IN } ] cursorname\n" +#~ "\n" +#~ "where direction can be empty or one of:\n" +#~ "\n" +#~ " NEXT\n" +#~ " PRIOR\n" +#~ " FIRST\n" +#~ " LAST\n" +#~ " ABSOLUTE count\n" +#~ " RELATIVE count\n" +#~ " count\n" +#~ " ALL\n" +#~ " FORWARD\n" +#~ " FORWARD count\n" +#~ " FORWARD ALL\n" +#~ " BACKWARD\n" +#~ " BACKWARD count\n" +#~ " BACKWARD ALL" +#~ msgstr "" +#~ "FETCH [ direction { FROM | IN } ] cursorname\n" +#~ "\n" +#~ "direction boÅŸ ya da aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " NEXT\n" +#~ " PRIOR\n" +#~ " FIRST\n" +#~ " LAST\n" +#~ " ABSOLUTE count\n" +#~ " RELATIVE count\n" +#~ " count\n" +#~ " ALL\n" +#~ " FORWARD\n" +#~ " FORWARD count\n" +#~ " FORWARD ALL\n" +#~ " BACKWARD\n" +#~ " BACKWARD count\n" +#~ " BACKWARD ALL" + +#~ msgid "" +#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON [ TABLE ] tablename [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" +#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" +#~ " ON [ TABLE ] tablename [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { USAGE | SELECT | UPDATE }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SEQUENCE sequencename [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON DATABASE dbname [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN SERVER servername [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" +#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON LANGUAGE langname [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SCHEMA schemaname [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" +#~ " ON TABLESPACE tablespacename [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT role [, ...] TO rolename [, ...] [ WITH ADMIN OPTION ]" +#~ msgstr "" +#~ "GRANT { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON [ TABLE ] tablo adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { SELECT | INSERT | UPDATE | REFERENCES } ( kolon [, ...] )\n" +#~ " [,...] | ALL [ PRIVILEGES ] ( kolon [, ...] ) }\n" +#~ " ON [ TABLE ] tablo adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { USAGE | SELECT | UPDATE }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SEQUENCE sequence adı [, ...]\n" +#~ " TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON DATABASE veritabanı adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN DATA WRAPPER fdw adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN SERVER sunucu adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { EXECUTE | ALL [ PRIVILEGES ] }\n" +#~ " ON FUNCTION fonksiyon adı ( [ [ argüman modu ] [ argüman adı ] argüman tipi [, ...] ] ) [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON LANGUAGE dil adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SCHEMA ÅŸema adı [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT { CREATE | ALL [ PRIVILEGES ] }\n" +#~ " ON TABLESPACE tablespacename [, ...]\n" +#~ " TO { [ GROUP ] rol adı | PUBLIC } [, ...] [ WITH GRANT OPTION ]\n" +#~ "\n" +#~ "GRANT role [, ...] TO rol adı [, ...] [ WITH ADMIN OPTION ]" + +#~ msgid "" +#~ "INSERT INTO table [ ( column [, ...] ) ]\n" +#~ " { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" +#~ msgstr "" +#~ "IINSERT INTO table [ ( column [, ...] ) ]\n" +#~ " { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) [, ...] | query }\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" + +#~ msgid "LISTEN name" +#~ msgstr "LISTEN ad" + +#~ msgid "LOAD 'filename'" +#~ msgstr "LOAD 'dosya adı'" + +#~ msgid "" +#~ "LOCK [ TABLE ] [ ONLY ] name [, ...] [ IN lockmode MODE ] [ NOWAIT ]\n" +#~ "\n" +#~ "where lockmode is one of:\n" +#~ "\n" +#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" +#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" +#~ msgstr "" +#~ "LOCK [ TABLE ] [ ONLY ] ad [, ...] [ IN kilit modu MODE ] [ NOWAIT ]\n" +#~ "\n" +#~ "kilit modu aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE\n" +#~ " | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE" + +#~ msgid "MOVE [ direction { FROM | IN } ] cursorname" +#~ msgstr "MOVE [ direction { FROM | IN } ] cursor_adı" + +#~ msgid "NOTIFY name" +#~ msgstr "NOTIFY ad" + +#~ msgid "PREPARE name [ ( datatype [, ...] ) ] AS statement" +#~ msgstr "PREPARE adı [ ( veri_tipi [, ...] ) ] AS ifade" + +#~ msgid "PREPARE TRANSACTION transaction_id" +#~ msgstr "PREPARE TRANSACTION transaction_id" + +#~ msgid "REASSIGN OWNED BY old_role [, ...] TO new_role" +#~ msgstr "REASSIGN OWNED BY eski_rol [, ...] TO yeni_rol" + +#~ msgid "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } name [ FORCE ]" +#~ msgstr "REINDEX { INDEX | TABLE | DATABASE | SYSTEM } adı [ FORCE ]" + +#~ msgid "RELEASE [ SAVEPOINT ] savepoint_name" +#~ msgstr "RELEASE [ SAVEPOINT ] savepoint_adı" + +#~ msgid "" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON [ TABLE ] tablename [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { SELECT | INSERT | UPDATE | REFERENCES } ( column [, ...] )\n" +#~ " [,...] | ALL [ PRIVILEGES ] ( column [, ...] ) }\n" +#~ " ON [ TABLE ] tablename [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { USAGE | SELECT | UPDATE }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SEQUENCE sequencename [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON DATABASE dbname [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN DATA WRAPPER fdwname [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN SERVER servername [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" +#~ " ON FUNCTION funcname ( [ [ argmode ] [ argname ] argtype [, ...] ] ) [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON LANGUAGE langname [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SCHEMA schemaname [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { CREATE | ALL [ PRIVILEGES ] }\n" +#~ " ON TABLESPACE tablespacename [, ...]\n" +#~ " FROM { [ GROUP ] rolename | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ ADMIN OPTION FOR ]\n" +#~ " role [, ...] FROM rolename [, ...]\n" +#~ " [ CASCADE | RESTRICT ]" +#~ msgstr "" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES | TRIGGER }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON [ TABLE ] tablo adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { SELECT | INSERT | UPDATE | REFERENCES } ( kolon [, ...] )\n" +#~ " [,...] | ALL [ PRIVILEGES ] ( kolon [, ...] ) }\n" +#~ " ON [ TABLE ] tablo adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { USAGE | SELECT | UPDATE }\n" +#~ " [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SEQUENCE sequence adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON DATABASE veritabanı adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN DATA WRAPPER fdw adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON FOREIGN SERVER sunucu adu [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { EXECUTE | ALL [ PRIVILEGES ] }\n" +#~ " ON FUNCTION fonksiyon adı ( [ [ argüman modu ] [ argüman adı ] argüman tipi [, ...] ] ) [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { USAGE | ALL [ PRIVILEGES ] }\n" +#~ " ON LANGUAGE dil adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }\n" +#~ " ON SCHEMA ÅŸema adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ GRANT OPTION FOR ]\n" +#~ " { CREATE | ALL [ PRIVILEGES ] }\n" +#~ " ON TABLESPACE tablespace adı [, ...]\n" +#~ " FROM { [ GROUP ] rol adı | PUBLIC } [, ...]\n" +#~ " [ CASCADE | RESTRICT ]\n" +#~ "\n" +#~ "REVOKE [ ADMIN OPTION FOR ]\n" +#~ " role [, ...] FROM rol adı [, ...]\n" +#~ " [ CASCADE | RESTRICT ]" + +#~ msgid "ROLLBACK [ WORK | TRANSACTION ]" +#~ msgstr "ROLLBACK [ WORK | TRANSACTION ]" + +#~ msgid "ROLLBACK PREPARED transaction_id" +#~ msgstr "ROLLBACK PREPARED transaction_id" + +#~ msgid "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name" +#~ msgstr "ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_adı" + +#~ msgid "" +#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" +#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" +#~ " * | expression [ [ AS ] output_name ] [, ...]\n" +#~ " [ FROM from_item [, ...] ]\n" +#~ " [ WHERE condition ]\n" +#~ " [ GROUP BY expression [, ...] ]\n" +#~ " [ HAVING condition [, ...] ]\n" +#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" +#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" +#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" +#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]\n" +#~ "\n" +#~ "where from_item can be one of:\n" +#~ "\n" +#~ " [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" +#~ " ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]\n" +#~ " with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" +#~ " function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]\n" +#~ " function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )\n" +#~ " from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]\n" +#~ "\n" +#~ "and with_query is:\n" +#~ "\n" +#~ " with_query_name [ ( column_name [, ...] ) ] AS ( select )\n" +#~ "\n" +#~ "TABLE { [ ONLY ] table_name [ * ] | with_query_name }" +#~ msgstr "" +#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" +#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" +#~ " * | expression [ [ AS ] output_name ] [, ...]\n" +#~ " [ FROM from_item [, ...] ]\n" +#~ " [ WHERE condition ]\n" +#~ " [ GROUP BY expression [, ...] ]\n" +#~ " [ HAVING condition [, ...] ]\n" +#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" +#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" +#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" +#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]\n" +#~ "\n" +#~ "where from_item can be one of:\n" +#~ "\n" +#~ " [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" +#~ " ( select ) [ AS ] alias [ ( column_alias [, ...] ) ]\n" +#~ " with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]\n" +#~ " function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]\n" +#~ " function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )\n" +#~ " from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]\n" +#~ "\n" +#~ "and with_query is:\n" +#~ "\n" +#~ " with_query_name [ ( column_name [, ...] ) ] AS ( select )\n" +#~ "\n" +#~ "TABLE { [ ONLY ] table_name [ * ] | with_query_name }" + +#~ msgid "" +#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" +#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" +#~ " * | expression [ [ AS ] output_name ] [, ...]\n" +#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table\n" +#~ " [ FROM from_item [, ...] ]\n" +#~ " [ WHERE condition ]\n" +#~ " [ GROUP BY expression [, ...] ]\n" +#~ " [ HAVING condition [, ...] ]\n" +#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" +#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" +#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" +#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]" +#~ msgstr "" +#~ "[ WITH [ RECURSIVE ] with_query [, ...] ]\n" +#~ "SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]\n" +#~ " * | expression [ [ AS ] output_name ] [, ...]\n" +#~ " INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table\n" +#~ " [ FROM from_item [, ...] ]\n" +#~ " [ WHERE condition ]\n" +#~ " [ GROUP BY expression [, ...] ]\n" +#~ " [ HAVING condition [, ...] ]\n" +#~ " [ WINDOW window_name AS ( window_definition ) [, ...] ]\n" +#~ " [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]\n" +#~ " [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]\n" +#~ " [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ]" + +#~ msgid "" +#~ "SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }\n" +#~ "SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }" +#~ msgstr "" +#~ "SET [ SESSION | LOCAL ] configuration_parameter { TO | = } { value | 'value' | DEFAULT }\n" +#~ "SET [ SESSION | LOCAL ] TIME ZONE { timezone | LOCAL | DEFAULT }" + +#~ msgid "SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }" +#~ msgstr "SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }" + +#~ msgid "" +#~ "SET [ SESSION | LOCAL ] ROLE rolename\n" +#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" +#~ "RESET ROLE" +#~ msgstr "" +#~ "SET [ SESSION | LOCAL ] ROLE rol_adı\n" +#~ "SET [ SESSION | LOCAL ] ROLE NONE\n" +#~ "RESET ROLE" + +#~ msgid "" +#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION username\n" +#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" +#~ "RESET SESSION AUTHORIZATION" +#~ msgstr "" +#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION kullanıcı_adı\n" +#~ "SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT\n" +#~ "RESET SESSION AUTHORIZATION" + +#~ msgid "" +#~ "SET TRANSACTION transaction_mode [, ...]\n" +#~ "SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]\n" +#~ "\n" +#~ "where transaction_mode is one of:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" +#~ msgstr "" +#~ "SET TRANSACTION transaction_mode [, ...]\n" +#~ "SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]\n" +#~ "\n" +#~ "transaction_mode aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" + +#~ msgid "" +#~ "SHOW name\n" +#~ "SHOW ALL" +#~ msgstr "" +#~ "SHOW name\n" +#~ "SHOW ALL" + +#~ msgid "" +#~ "START TRANSACTION [ transaction_mode [, ...] ]\n" +#~ "\n" +#~ "where transaction_mode is one of:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" +#~ msgstr "" +#~ "START TRANSACTION [ transaction_mode [, ...] ]\n" +#~ "\n" +#~ "transaction_mode aÅŸağıdakilerden birisi olabilir:\n" +#~ "\n" +#~ " ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED }\n" +#~ " READ WRITE | READ ONLY" + +#~ msgid "" +#~ "TRUNCATE [ TABLE ] [ ONLY ] name [, ... ]\n" +#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" +#~ msgstr "" +#~ "TRUNCATE [ TABLE ] [ ONLY ] ad [, ... ]\n" +#~ " [ RESTART IDENTITY | CONTINUE IDENTITY ] [ CASCADE | RESTRICT ]" + +#~ msgid "UNLISTEN { name | * }" +#~ msgstr "UNLISTEN { name | * }" + +#~ msgid "" +#~ "UPDATE [ ONLY ] table [ [ AS ] alias ]\n" +#~ " SET { column = { expression | DEFAULT } |\n" +#~ " ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]\n" +#~ " [ FROM fromlist ]\n" +#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" +#~ msgstr "" +#~ "UPDATE [ ONLY ] table [ [ AS ] alias ]\n" +#~ " SET { column = { expression | DEFAULT } |\n" +#~ " ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) } [, ...]\n" +#~ " [ FROM fromlist ]\n" +#~ " [ WHERE condition | WHERE CURRENT OF cursor_name ]\n" +#~ " [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]" + +#~ msgid "" +#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]\n" +#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]" +#~ msgstr "" +#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]\n" +#~ "VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]" + +#~ msgid "" +#~ "VALUES ( expression [, ...] ) [, ...]\n" +#~ " [ ORDER BY sort_expression [ ASC | DESC | USING operator ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]" +#~ msgstr "" +#~ "VALUES ( expression [, ...] ) [, ...]\n" +#~ " [ ORDER BY sort_expression [ ASC | DESC | USING operator ] [, ...] ]\n" +#~ " [ LIMIT { count | ALL } ]\n" +#~ " [ OFFSET start [ ROW | ROWS ] ]\n" +#~ " [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]" + +#~ msgid " \"%s\" IN %s %s" +#~ msgstr " \"%s\", %s %s içinde" + +#~ msgid "(1 row)" +#~ msgid_plural "(%lu rows)" +#~ msgstr[0] "(%lu satır)" +#~ msgstr[1] "(1 satır)" + +#~ msgid "Usage:" +#~ msgstr "Kullanımı:" + +#~ msgid "General options:" +#~ msgstr "Genel tercihler:" + +#~ msgid " -1 (\"one\") execute command file as a single transaction" +#~ msgstr " -1 (rakamla bir) komutu tek bir transaction olarak iÅŸle" + +#~ msgid " --help show this help, then exit" +#~ msgstr " --help yardım metnini göster ve çık" + +#~ msgid " --version output version information, then exit" +#~ msgstr " --version sürüm bilgisini göster ve çık" + +#~ msgid " -t print rows only (-P tuples_only)" +#~ msgstr " -t sadece satırları göster (-P tuples_only)" + +#~ msgid "" +#~ "\n" +#~ "Connection options:" +#~ msgstr "" +#~ "\n" +#~ "BaÄŸlantı tercihleri:" + +#~ msgid " -W force password prompt (should happen automatically)" +#~ msgstr " -W ÅŸifre sorulmasını saÄŸla (otomatik olarak olmalı)" + +#~ msgid "" +#~ " \\d{t|i|s|v|S} [PATTERN] (add \"+\" for more detail)\n" +#~ " list tables/indexes/sequences/views/system tables\n" +#~ msgstr "" +#~ " \\d{t|i|s|v|S} [PATTERN] (daha fazla ayrıntı için \"+\" ekleyin)\n" +#~ " tablolar/indeksler/sequenceler/viewlar/system tablolarını listele\n" + +#~ msgid " \\db [PATTERN] list tablespaces (add \"+\" for more detail)\n" +#~ msgstr " \\db [PATTERN] tablespaceleri listele (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\df [PATTERN] list functions (add \"+\" for more detail)\n" +#~ msgstr " \\df [PATTERN] fonksiyonları göster (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\dFd [PATTERN] list text search dictionaries (add \"+\" for more detail)\n" +#~ msgstr " \\dFd [PATTERN] metin arama sözlüklerini listele (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\dFp [PATTERN] list text search parsers (add \"+\" for more detail)\n" +#~ msgstr " \\dFp [PATTERN] metin arama ayrıştırıcılarını listele (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\dn [PATTERN] list schemas (add \"+\" for more detail)\n" +#~ msgstr " \\dn [PATTERN] ÅŸemaları göster (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\dT [PATTERN] list data types (add \"+\" for more detail)\n" +#~ msgstr " \\dT [PATTERN] veri tipleri listele (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\l list all databases (add \"+\" for more detail)\n" +#~ msgstr " \\l tüm veritabanlarını listele (daha fazla ayrıntı için \"+\" ekleyin)\n" + +#~ msgid " \\z [PATTERN] list table, view, and sequence access privileges (same as \\dp)\n" +#~ msgstr " \\z [PATTERN] tablo, view, ve sequence eriÅŸim haklarını listele (\\dp ile aynı)\n" + +#~ msgid "Copy, Large Object\n" +#~ msgstr "Copy, Large Object\n" + +#~ msgid "" +#~ "Welcome to %s %s (server %s), the PostgreSQL interactive terminal.\n" +#~ "\n" +#~ msgstr "" +#~ "PostgreSQL etkiliÅŸimli arayüzü %s %s(server %s).\n" +#~ "\n" + +#~ msgid "" +#~ "Welcome to %s %s, the PostgreSQL interactive terminal.\n" +#~ "\n" +#~ msgstr "" +#~ "PostgreSQL etkiliÅŸimli arayüzü %s %s.\n" +#~ "\n" + +#~ msgid "" +#~ "WARNING: You are connected to a server with major version %d.%d,\n" +#~ "but your %s client is major version %d.%d. Some backslash commands,\n" +#~ "such as \\d, might not work properly.\n" +#~ "\n" +#~ msgstr "" +#~ "UYARI: Üst sürümü %d.%d olan sunucuya baÄŸlısınız,\n" +#~ "ancak %s istemcinizin sürümü %d.%d. \\d gibi bazı backslash ile baÅŸlayan komutlar düzgün çalışmayabilir\n" +#~ "\n" + +#~ msgid "Access privileges for database \"%s\"" +#~ msgstr "\"%s\" veritabanının eriÅŸim hakları" + +#~ msgid "?%c? \"%s.%s\"" +#~ msgstr "?%c? \"%s.%s\"" + +#~ msgid " \"%s\"" +#~ msgstr " \"%s\"" + +#~ msgid "ALTER VIEW name RENAME TO newname" +#~ msgstr "ALTER VIEW view_adı RENAME TO yeni_ad" + +#~ msgid "%s: Warning: The -u option is deprecated. Use -U.\n" +#~ msgstr "%s: Uyarı: -u parametresi kullanımdan kalkmıştır. -U kullanın.\n" + +#~ msgid "(binary compatible)" +#~ msgstr "(ikili (binary) uyumlu)" diff --git a/src/bin/psql/po/zh_CN.po b/src/bin/psql/po/zh_CN.po index c9177f175d9..e9063a854fd 100644 --- a/src/bin/psql/po/zh_CN.po +++ b/src/bin/psql/po/zh_CN.po @@ -1,11 +1,11 @@ msgid "" msgstr "" -"Project-Id-Version: psql (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:44+0000\n" -"PO-Revision-Date: 2016-06-12 15:59+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Chinese (Simplified)\n" +"Project-Id-Version: psql (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:13+0000\n" +"PO-Revision-Date: 2019-05-17 17:50+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -15,52 +15,73 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.5.7\n" -# command.c:240 -#: ../../common/exec.c:127 ../../common/exec.c:241 ../../common/exec.c:284 +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "" + +#: ../../../src/common/logging.c:195 #, c-format -msgid "could not identify current directory: %s" +msgid "error: " +msgstr "" + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "" + +# command.c:240 +#: ../../common/exec.c:138 ../../common/exec.c:255 ../../common/exec.c:301 +#, fuzzy, c-format +#| msgid "could not identify current directory: %s" +msgid "could not identify current directory: %m" msgstr "无法识别目å‰ç›®å½•:%s" # command.c:122 -#: ../../common/exec.c:146 +#: ../../common/exec.c:157 #, c-format msgid "invalid binary \"%s\"" msgstr "æ— æ•ˆçš„äºŒè¿›åˆ¶ç  \"%s\"" # command.c:1103 -#: ../../common/exec.c:195 +#: ../../common/exec.c:207 #, c-format msgid "could not read binary \"%s\"" msgstr "无法读å–äºŒè¿›åˆ¶ç  \"%s\"" -#: ../../common/exec.c:202 +#: ../../common/exec.c:215 #, c-format msgid "could not find a \"%s\" to execute" msgstr "未能找到一个 \"%s\" æ¥æ‰§è¡Œ" -#: ../../common/exec.c:257 ../../common/exec.c:293 +#: ../../common/exec.c:271 ../../common/exec.c:310 #, c-format -msgid "could not change directory to \"%s\": %s" -msgstr "无法跳转到目录 \"%s\" 中: %s" +msgid "could not change directory to \"%s\": %m" +msgstr "无法跳转到目录 \"%s\" 中: %m" -# command.c:1103 -#: ../../common/exec.c:272 +#: ../../common/exec.c:288 #, c-format -msgid "could not read symbolic link \"%s\"" -msgstr "无法读å–符å·é“¾æŽ¥ \"%s\"" +msgid "could not read symbolic link \"%s\": %m" +msgstr "无法读å–符å·é“¾æŽ¥ \"%s\": %m" -#: ../../common/exec.c:523 -#, c-format -msgid "pclose failed: %s" +#: ../../common/exec.c:541 +#, fuzzy, c-format +#| msgid "pclose failed: %s" +msgid "pclose failed: %m" msgstr "pclose调用失败: %s" +#: ../../common/exec.c:670 ../../common/exec.c:715 ../../common/exec.c:807 +#: command.c:1218 input.c:228 mainloop.c:82 mainloop.c:386 +#, c-format +msgid "out of memory" +msgstr "内存用尽" + # command.c:681 # common.c:85 # common.c:99 # mainloop.c:71 #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 -#: ../../common/fe_memutils.c:98 command.c:330 input.c:227 mainloop.c:80 -#: mainloop.c:261 +#: ../../common/fe_memutils.c:98 #, c-format msgid "out of memory\n" msgstr "内存耗尽\n" @@ -71,173 +92,190 @@ msgstr "内存耗尽\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "无法å¤åˆ¶ç©ºæŒ‡é’ˆ (内部错误)\n" -#: ../../common/username.c:45 +#: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "无法找到有效的用户ID %ld: %s" -#: ../../common/username.c:47 command.c:287 +#: ../../common/username.c:45 command.c:555 msgid "user does not exist" msgstr "用户ä¸å­˜åœ¨" -#: ../../common/username.c:62 +#: ../../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ç”¨æˆ·åæŸ¥æ‰¾å¤±è´¥ï¼šé”™è¯¯ä»£ç %lu" -#: ../../common/wait_error.c:47 +#: ../../common/wait_error.c:45 #, c-format msgid "command not executable" msgstr "无法执行命令" -#: ../../common/wait_error.c:51 +#: ../../common/wait_error.c:49 #, c-format msgid "command not found" msgstr "没有找到命令" -#: ../../common/wait_error.c:56 +#: ../../common/wait_error.c:54 #, c-format msgid "child process exited with exit code %d" msgstr "å­è¿›ç¨‹ç»“æŸï¼Œç»“æŸä»£ç  %d" -#: ../../common/wait_error.c:63 +#: ../../common/wait_error.c:62 #, c-format msgid "child process was terminated by exception 0x%X" msgstr "å­è¿›ç¨‹è¢«å¼‚常(exception) 0x%X 终止" -#: ../../common/wait_error.c:73 -#, c-format -msgid "child process was terminated by signal %s" -msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %s 终止" - -#: ../../common/wait_error.c:77 -#, c-format -msgid "child process was terminated by signal %d" +#: ../../common/wait_error.c:66 +#, fuzzy, c-format +#| msgid "child process was terminated by signal %d" +msgid "child process was terminated by signal %d: %s" msgstr "å­è¿›ç¨‹è¢«ä¿¡å· %d 终止" -#: ../../common/wait_error.c:82 +#: ../../common/wait_error.c:72 #, c-format msgid "child process exited with unrecognized status %d" msgstr "å­è¿›ç¨‹ç»“æŸï¼Œä¸æ˜Žçжæ€ä»£ç  %d" # print.c:1202 -#: ../../fe_utils/print.c:354 +#: ../../fe_utils/print.c:353 #, c-format msgid "(%lu row)" msgid_plural "(%lu rows)" msgstr[0] "(%lu 行记录)" -#: ../../fe_utils/print.c:2906 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "已中断\n" -#: ../../fe_utils/print.c:2970 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "无法对表的内容增加标题:å·²ç»è¶…过%d列的数é‡.\n" -#: ../../fe_utils/print.c:3010 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "无法对表的内容添加å•å…ƒ: 总共有%d个å•元超过.\n" -#: ../../fe_utils/print.c:3259 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "æ— æ•ˆçš„è¾“å‡ºæ ¼å¼ (内部错误): %d" -#: ../../fe_utils/psqlscan.l:713 -#, c-format -msgid "skipping recursive expansion of variable \"%s\"\n" +#: ../../fe_utils/psqlscan.l:729 +#, fuzzy, c-format +#| msgid "skipping recursive expansion of variable \"%s\"\n" +msgid "skipping recursive expansion of variable \"%s\"" msgstr "跳过å˜é‡ \"%s\"的递归扩展\n" -# command.c:120 -#: command.c:128 -#, c-format -msgid "Invalid command \\%s. Try \\? for help.\n" -msgstr "无效的命令 \\%s,用 \\? 查看帮助。\n" - # command.c:122 -#: command.c:130 -#, c-format -msgid "invalid command \\%s\n" +#: command.c:221 +#, fuzzy, c-format +#| msgid "invalid command \\%s\n" +msgid "invalid command \\%s" msgstr "无效的命令 \\%s\n" +#: command.c:223 +#, fuzzy, c-format +#| msgid "Use \\? for help." +msgid "Try \\? for help." +msgstr "使用\\?获å–帮助." + # command.c:131 -#: command.c:141 -#, c-format -msgid "\\%s: extra argument \"%s\" ignored\n" +#: command.c:241 +#, fuzzy, c-format +#| msgid "\\%s: extra argument \"%s\" ignored\n" +msgid "\\%s: extra argument \"%s\" ignored" msgstr "\\%sï¼šå¿½ç•¥å¤šä½™çš„å‚æ•° \"%s\" \n" +#: command.c:293 +#, fuzzy, c-format +#| msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgid "\\%s command ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "忽略\\%s命令;使用\\endif或Ctrl-C退出当å‰\\ifå—\n" + # command.c:240 -#: command.c:285 -#, c-format -msgid "could not get home directory for user ID %ld: %s\n" +#: command.c:553 +#, fuzzy, c-format +#| msgid "could not get home directory for user ID %ld: %s\n" +msgid "could not get home directory for user ID %ld: %s" msgstr "无法获å–用户ID %ld: %s对应的home 目录\n" # command.c:256 -#: command.c:303 -#, c-format -msgid "\\%s: could not change directory to \"%s\": %s\n" +#: command.c:571 +#, fuzzy, c-format +#| msgid "\\%s: could not change directory to \"%s\": %s\n" +msgid "\\%s: could not change directory to \"%s\": %m" msgstr "\\%s: 无法切æ¢ç›®å½•至 \"%s\": %s\n" # common.c:636 # common.c:871 -#: command.c:318 common.c:548 common.c:606 common.c:1139 +#: command.c:596 #, c-format msgid "You are currently not connected to a database.\n" msgstr "ä½ ç›®å‰æ²¡æœ‰è¿žæŽ¥åˆ°æ•°æ®åº“。\n" -#: command.c:343 +#: command.c:609 +#, fuzzy, c-format +#| msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgid "You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "以用户 \"%2$s\" 的身份, 在主机\"%3$s\", 端å£\"%4$s\"连接到数æ®åº“ \"%1$s\"\n" + +#: command.c:612 #, c-format -msgid "" -"You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at " -"port \"%s\".\n" -msgstr "" -"以用户 \"%2$s\" 的身份,通过套接字\"%3$s\"在端å£\"%4$s\"连接到数æ®åº“ \"%1$s" -"\"\n" +msgid "You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "以用户 \"%2$s\" 的身份,通过套接字\"%3$s\"在端å£\"%4$s\"连接到数æ®åº“ \"%1$s\"\n" + +#: command.c:618 +#, fuzzy, c-format +#| msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "以用户 \"%2$s\" 的身份, 在主机\"%3$s\", 端å£\"%4$s\"连接到数æ®åº“ \"%1$s\"\n" -#: command.c:346 +#: command.c:621 #, c-format -msgid "" -"You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port " -"\"%s\".\n" -msgstr "" -"以用户 \"%2$s\" 的身份, 在主机\"%3$s\", 端å£\"%4$s\"连接到数æ®åº“ \"%1$s\"\n" +msgid "You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "以用户 \"%2$s\" 的身份, 在主机\"%3$s\", 端å£\"%4$s\"连接到数æ®åº“ \"%1$s\"\n" # command.c:370 # command.c:760 -#: command.c:559 command.c:629 command.c:725 command.c:1557 -#, c-format -msgid "no query buffer\n" +#: command.c:930 command.c:1026 command.c:2411 +#, fuzzy, c-format +#| msgid "no query buffer\n" +msgid "no query buffer" msgstr "没有查询缓存区\n" -#: command.c:592 command.c:3408 -#, c-format -msgid "invalid line number: %s\n" +#: command.c:963 command.c:4801 +#, fuzzy, c-format +#| msgid "invalid line number: %s\n" +msgid "invalid line number: %s" msgstr "è¡Œå·æ— æ•ˆ: %s\n" # describe.c:117 -#: command.c:623 -#, c-format -msgid "The server (version %d.%d) does not support editing function source.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒç¼–辑函数æºç .\n" +#: command.c:1017 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support editing function source.\n" +msgid "The server (version %s) does not support editing function source." +msgstr "æœåС噍(版本%s)䏿”¯æŒç¼–辑函数æºç .\n" + +# describe.c:117 +#: command.c:1020 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support editing view definitions.\n" +msgid "The server (version %s) does not support editing view definitions." +msgstr "æœåŠ¡å™¨ï¼ˆç‰ˆæœ¬%sï¼‰ä¸æ”¯æŒç¼–辑视图定义。\n" -#: command.c:703 command.c:771 +#: command.c:1102 msgid "No changes" msgstr "没有å‘生更改" -# describe.c:117 -#: command.c:719 -#, c-format -msgid "The server (version %d.%d) does not support editing view definitions.\n" -msgstr "æœåŠ¡å™¨ï¼ˆç‰ˆæœ¬%d.%dï¼‰ä¸æ”¯æŒç¼–辑视图定义。\n" - # command.c:433 -#: command.c:825 -#, c-format -msgid "%s: invalid encoding name or conversion procedure not found\n" +#: command.c:1179 +#, fuzzy, c-format +#| msgid "%s: invalid encoding name or conversion procedure not found\n" +msgid "%s: invalid encoding name or conversion procedure not found" msgstr "%s:无效的编ç å称或找ä¸åˆ°è½¬æ¢ç¨‹åº\n" # command.c:953 @@ -245,19 +283,16 @@ msgstr "%s:无效的编ç å称或找ä¸åˆ°è½¬æ¢ç¨‹åº\n" # common.c:605 # common.c:660 # common.c:903 -#: command.c:850 command.c:1897 command.c:3510 common.c:152 common.c:199 -#: common.c:492 common.c:1185 common.c:1210 common.c:1311 copy.c:489 -#: copy.c:699 large_obj.c:156 large_obj.c:191 large_obj.c:253 +#: command.c:1214 command.c:1853 command.c:3089 command.c:4903 common.c:175 +#: common.c:224 common.c:521 common.c:1362 common.c:1390 common.c:1498 +#: common.c:1601 common.c:1639 copy.c:490 copy.c:709 help.c:63 large_obj.c:157 +#: large_obj.c:192 large_obj.c:254 #, c-format msgid "%s" msgstr "%s" -#: command.c:854 -msgid "out of memory" -msgstr "内存用尽" - -#: command.c:857 -msgid "There was no previous error." +#: command.c:1221 +msgid "There is no previous error." msgstr "没有之å‰çš„错误。" # command.c:501 @@ -267,14 +302,45 @@ msgstr "没有之å‰çš„错误。" # command.c:612 # command.c:740 # command.c:771 -#: command.c:951 command.c:1001 command.c:1015 command.c:1032 command.c:1139 -#: command.c:1303 command.c:1537 command.c:1568 -#, c-format -msgid "\\%s: missing required argument\n" +#: command.c:1409 command.c:1714 command.c:1728 command.c:1745 command.c:1905 +#: command.c:2142 command.c:2378 command.c:2418 +#, fuzzy, c-format +#| msgid "\\%s: missing required argument\n" +msgid "\\%s: missing required argument" msgstr "\\%sï¼šç¼ºå°‘æ‰€éœ€å‚æ•°\n" +#: command.c:1540 +#, fuzzy, c-format +#| msgid "\\elif: cannot occur after \\else\n" +msgid "\\elif: cannot occur after \\else" +msgstr "\\elif:ä¸èƒ½å‡ºçŽ°åœ¨\\else之åŽ\n" + +#: command.c:1545 +#, fuzzy, c-format +#| msgid "\\elif: no matching \\if\n" +msgid "\\elif: no matching \\if" +msgstr "\\elif: ä¸åŒ¹é…\\if\n" + +#: command.c:1609 +#, fuzzy, c-format +#| msgid "\\else: cannot occur after \\else\n" +msgid "\\else: cannot occur after \\else" +msgstr "\\else: ä¸èƒ½å‡ºçŽ°åœ¨ \\else\n" + +#: command.c:1614 +#, fuzzy, c-format +#| msgid "\\else: no matching \\if\n" +msgid "\\else: no matching \\if" +msgstr "\\else: ä¸åŒ¹é…\\if\n" + +#: command.c:1654 +#, fuzzy, c-format +#| msgid "\\endif: no matching \\if\n" +msgid "\\endif: no matching \\if" +msgstr "\\endif:ä¸åŒ¹é…\\if\n" + # command.c:598 -#: command.c:1064 +#: command.c:1809 msgid "Query buffer is empty." msgstr "查询缓存区是空的。" @@ -282,77 +348,79 @@ msgstr "查询缓存区是空的。" # command.c:939 # startup.c:187 # startup.c:205 -#: command.c:1074 +#: command.c:1831 msgid "Enter new password: " msgstr "输入新的密ç ï¼š" -#: command.c:1075 +#: command.c:1832 msgid "Enter it again: " msgstr "冿¬¡è¾“入:" -#: command.c:1079 -#, c-format -msgid "Passwords didn't match.\n" +#: command.c:1836 +#, fuzzy, c-format +#| msgid "Passwords didn't match.\n" +msgid "Passwords didn't match." msgstr "两次密ç ä¸åŒ¹é…。\n" -#: command.c:1097 -#, c-format -msgid "Password encryption failed.\n" -msgstr "密ç åŠ å¯†å¤±è´¥ã€‚\n" - -# startup.c:502 -#: command.c:1168 command.c:1284 command.c:1542 -#, c-format -msgid "\\%s: error while setting variable\n" -msgstr "\\%s: 设定å˜é‡å€¼æ—¶å‡ºé”™\n" +# startup.c:492 +#: command.c:1935 +#, fuzzy, c-format +#| msgid "\\%s: could not read value for variable\n" +msgid "\\%s: could not read value for variable" +msgstr "\\%s:无法读å–å˜é‡çš„值\n" # command.c:632 -#: command.c:1231 +#: command.c:2038 msgid "Query buffer reset (cleared)." msgstr "查询缓存区é‡ç½®(已清空)。" # command.c:646 -#: command.c:1243 +#: command.c:2060 #, c-format msgid "Wrote history to file \"%s\".\n" msgstr "写入历å²è®°å½•到文件 \"%s\".\n" -#: command.c:1308 -#, c-format -msgid "\\%s: environment variable name must not contain \"=\"\n" +#: command.c:2147 +#, fuzzy, c-format +#| msgid "\\%s: environment variable name must not contain \"=\"\n" +msgid "\\%s: environment variable name must not contain \"=\"" msgstr "\\%s: 环境å˜é‡ä¸èƒ½åŒ…å« \"=\"\n" # describe.c:117 -#: command.c:1350 -#, c-format -msgid "The server (version %d.%d) does not support showing function source.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒæ˜¾ç¤ºå‡½æ•°æºç .\n" +#: command.c:2208 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support showing function source.\n" +msgid "The server (version %s) does not support showing function source." +msgstr "æœåС噍(版本%s)䏿”¯æŒæ˜¾ç¤ºå‡½æ•°æºç .\n" + +# describe.c:117 +#: command.c:2211 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support showing view definitions.\n" +msgid "The server (version %s) does not support showing view definitions." +msgstr "æœåŠ¡å™¨ï¼ˆç‰ˆæœ¬%sï¼‰ä¸æ”¯æŒæ˜¾ç¤ºè§†å›¾å®šä¹‰ã€‚\n" # copy.c:122 -#: command.c:1356 -#, c-format -msgid "function name is required\n" +#: command.c:2218 +#, fuzzy, c-format +#| msgid "function name is required\n" +msgid "function name is required" msgstr "需è¦å‡½æ•°å\n" -# describe.c:117 -#: command.c:1429 -#, c-format -msgid "The server (version %d.%d) does not support showing view definitions.\n" -msgstr "æœåŠ¡å™¨ï¼ˆç‰ˆæœ¬%d.%dï¼‰ä¸æ”¯æŒæ˜¾ç¤ºè§†å›¾å®šä¹‰ã€‚\n" - # copy.c:122 -#: command.c:1435 -#, c-format -msgid "view name is required\n" +#: command.c:2220 +#, fuzzy, c-format +#| msgid "view name is required\n" +msgid "view name is required" msgstr "需è¦è§†å›¾å\n" # command.c:726 -#: command.c:1522 +#: command.c:2350 msgid "Timing is on." msgstr "å¯ç”¨è®¡æ—¶åŠŸèƒ½." # command.c:728 -#: command.c:1524 +#: command.c:2352 msgid "Timing is off." msgstr "åœæ­¢è®¡æ—¶åŠŸèƒ½." @@ -369,25 +437,20 @@ msgstr "åœæ­¢è®¡æ—¶åŠŸèƒ½." # common.c:170 # copy.c:530 # copy.c:575 -#: command.c:1586 command.c:1606 command.c:2240 command.c:2243 command.c:2246 -#: command.c:2252 command.c:2254 command.c:2262 command.c:2272 command.c:2281 -#: command.c:2295 command.c:2312 command.c:2370 common.c:67 copy.c:332 -#: copy.c:392 copy.c:405 psqlscanslash.l:710 psqlscanslash.l:721 -#: psqlscanslash.l:731 -#, c-format -msgid "%s: %s\n" -msgstr "%s: %s\n" - -#: command.c:1700 -#, c-format -msgid "+ opt(%d) = |%s|\n" -msgstr "+ opt(%d) = |%s|\n" +#: command.c:2437 command.c:2465 command.c:3485 command.c:3488 command.c:3491 +#: command.c:3497 command.c:3499 command.c:3507 command.c:3517 command.c:3526 +#: command.c:3540 command.c:3557 command.c:3615 common.c:71 copy.c:333 +#: copy.c:405 psqlscanslash.l:784 psqlscanslash.l:795 psqlscanslash.l:805 +#, fuzzy, c-format +#| msgid "%s: %s" +msgid "%s: %m" +msgstr "%s: %s" # command.c:915 # command.c:939 # startup.c:187 # startup.c:205 -#: command.c:1726 startup.c:207 +#: command.c:2849 startup.c:240 startup.c:291 msgid "Password: " msgstr "å£ä»¤ï¼š" @@ -395,90 +458,102 @@ msgstr "å£ä»¤ï¼š" # command.c:939 # startup.c:187 # startup.c:205 -#: command.c:1731 startup.c:209 +#: command.c:2854 startup.c:288 #, c-format msgid "Password for user %s: " msgstr "用户 %s çš„å£ä»¤ï¼š" -#: command.c:1778 -#, c-format -msgid "" -"All connection parameters must be supplied because no database connection " -"exists\n" +#: command.c:2905 +#, fuzzy, c-format +#| msgid "All connection parameters must be supplied because no database connection exists\n" +msgid "All connection parameters must be supplied because no database connection exists" msgstr "没有å¯ç”¨çš„æ•°æ®åº“连接,所以必须æä¾›æ‰€æœ‰çš„è¿žæŽ¥å‚æ•°\n" # command.c:957 -#: command.c:1901 -#, c-format -msgid "Previous connection kept\n" +#: command.c:3093 +#, fuzzy, c-format +#| msgid "Previous connection kept\n" +msgid "Previous connection kept" msgstr "ä¿ç•™ä¸Šä¸€æ¬¡è¿žæŽ¥\n" # command.c:969 -#: command.c:1905 +#: command.c:3097 #, c-format msgid "\\connect: %s" msgstr "\\连接:%s" # command.c:981 -#: command.c:1937 +#: command.c:3136 +#, fuzzy, c-format +#| msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgid "You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n" +msgstr "您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户 \"%s\",主机 \"%s\",端å£å· \"%s\".\n" + +# command.c:981 +#: command.c:3139 #, c-format -msgid "" -"You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" " -"at port \"%s\".\n" -msgstr "" -"您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户å \"%s\" , 套接字 \"%s\", 端å£å· \"%s" -"\".\n" +msgid "You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n" +msgstr "您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户å \"%s\" , 套接字 \"%s\", 端å£å· \"%s\".\n" # command.c:981 -#: command.c:1940 +#: command.c:3145 +#, fuzzy, c-format +#| msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n" +msgstr "您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户 \"%s\",主机 \"%s\",端å£å· \"%s\".\n" + +# command.c:981 +#: command.c:3148 #, c-format -msgid "" -"You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at " -"port \"%s\".\n" -msgstr "" -"您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户 \"%s\",主机 \"%s\",端å£å· \"%s\".\n" +msgid "You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n" +msgstr "您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\", 用户 \"%s\",主机 \"%s\",端å£å· \"%s\".\n" # command.c:981 -#: command.c:1944 +#: command.c:3153 #, c-format msgid "You are now connected to database \"%s\" as user \"%s\".\n" msgstr "您现在已ç»è¿žæŽ¥åˆ°æ•°æ®åº“ \"%s\",用户 \"%s\".\n" -#: command.c:1978 +#: command.c:3186 #, c-format msgid "%s (%s, server %s)\n" msgstr "%s (%s, æœåС噍 %s)\n" -#: command.c:1986 +#: command.c:3194 #, c-format msgid "" -"WARNING: %s major version %d.%d, server major version %d.%d.\n" +"WARNING: %s major version %s, server major version %s.\n" " Some psql features might not work.\n" msgstr "" -"警告:%s 主版本%d.%d,æœåŠ¡å™¨ä¸»ç‰ˆæœ¬ä¸º%d.%d.\n" -" 一些psql功能å¯èƒ½æ— æ³•正常使用。\n" +"警告:%s 主版本%s,æœåŠ¡å™¨ä¸»ç‰ˆæœ¬ä¸º%s.\n" +" 一些psql功能å¯èƒ½æ— æ³•正常使用.\n" # startup.c:652 -#: command.c:2020 +#: command.c:3232 #, c-format msgid "SSL connection (protocol: %s, cipher: %s, bits: %s, compression: %s)\n" msgstr "SSL 连接(å议:%s,密ç ï¼š%s,密钥ä½ï¼š%s,压缩:%s)\n" -#: command.c:2021 command.c:2022 command.c:2023 +#: command.c:3233 command.c:3234 command.c:3235 msgid "unknown" msgstr "未知" # help.c:48 -#: command.c:2024 help.c:46 +#: command.c:3236 help.c:46 msgid "off" msgstr "关闭" # help.c:48 -#: command.c:2024 help.c:46 +#: command.c:3236 help.c:46 msgid "on" msgstr "å¼€å¯" -#: command.c:2044 +#: command.c:3250 +#, c-format +msgid "GSSAPI Encrypted connection\n" +msgstr "" + +#: command.c:3270 #, c-format msgid "" "WARNING: Console code page (%u) differs from Windows code page (%u)\n" @@ -489,285 +564,305 @@ msgstr "" " 8-bit 字符å¯èƒ½æ— æ³•正常工作。请查阅 psql å‚考\n" " 页 \"Windows 用户注æ„事项\" 的详细说明。\n" -#: command.c:2129 -#, c-format -msgid "" -"environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a " -"line number\n" +#: command.c:3374 +#, fuzzy, c-format +#| msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number\n" +msgid "environment variable PSQL_EDITOR_LINENUMBER_ARG must be set to specify a line number" msgstr "必须设置环境å˜é‡ PSQL_EDITOR_LINENUMBER_ARG,用于指定行å·\n" # command.c:1103 -#: command.c:2158 -#, c-format -msgid "could not start editor \"%s\"\n" +#: command.c:3403 +#, fuzzy, c-format +#| msgid "could not start editor \"%s\"\n" +msgid "could not start editor \"%s\"" msgstr "无法å¯åŠ¨ç¼–è¾‘å™¨ \"%s\"\n" # command.c:1105 -#: command.c:2160 -#, c-format -msgid "could not start /bin/sh\n" +#: command.c:3405 +#, fuzzy, c-format +#| msgid "could not start /bin/sh\n" +msgid "could not start /bin/sh" msgstr "无法å¯åЍ /bin/sh\n" # command.c:1148 -#: command.c:2198 -#, c-format -msgid "could not locate temporary directory: %s\n" +#: command.c:3443 +#, fuzzy, c-format +#| msgid "could not locate temporary directory: %s\n" +msgid "could not locate temporary directory: %s" msgstr "找ä¸åˆ°ä¸´æ—¶ç›®å½•:%s\n" # command.c:1148 -#: command.c:2225 +#: command.c:3470 #, c-format -msgid "could not open temporary file \"%s\": %s\n" -msgstr "无法打开临时文件 \"%s\": %s\n" +msgid "could not open temporary file \"%s\": %m" +msgstr "无法打开临时文件 \"%s\": %m" -# command.c:1340 -#: command.c:2499 +#: command.c:3763 #, c-format -msgid "" -"\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, " -"latex, latex-longtable, troff-ms\n" +msgid "\\pset: ambiguous abbreviation \"%s\" matches both \"%s\" and \"%s\"" msgstr "" -"\\pset: å…è®¸çš„æ ¼å¼æ˜¯ unaligned, aligned, wrapped, html, asciidoc, latex, " -"latex-longtable, troff-ms\n" -#: command.c:2518 -#, c-format -msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" +# command.c:1340 +#: command.c:3783 +#, fuzzy, c-format +#| msgid "\\pset: allowed formats are unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" +msgid "\\pset: allowed formats are aligned, asciidoc, csv, html, latex, latex-longtable, troff-ms, unaligned, wrapped" +msgstr "\\pset: å…è®¸çš„æ ¼å¼æ˜¯ unaligned, aligned, wrapped, html, asciidoc, latex, latex-longtable, troff-ms\n" + +#: command.c:3802 +#, fuzzy, c-format +#| msgid "\\pset: allowed line styles are ascii, old-ascii, unicode\n" +msgid "\\pset: allowed line styles are ascii, old-ascii, unicode" msgstr "\\pset: 所å…许使用的文本风格是ASCII, OLD-ASCII, UNICODE\n" -#: command.c:2534 -#, c-format -#| msgid "\\pset: allowed unicode border linestyles are single, double\n" -msgid "\\pset: allowed Unicode border line styles are single, double\n" +#: command.c:3817 +#, fuzzy, c-format +#| msgid "\\pset: allowed Unicode border line styles are single, double\n" +msgid "\\pset: allowed Unicode border line styles are single, double" msgstr "\\pset:å…许的 Unicode 边界线型是 single å’Œ double\n" -#: command.c:2549 -#, c-format -#| msgid "\\pset: allowed unicode column linestyles are single, double\n" -msgid "\\pset: allowed Unicode column line styles are single, double\n" +#: command.c:3832 +#, fuzzy, c-format +#| msgid "\\pset: allowed Unicode column line styles are single, double\n" +msgid "\\pset: allowed Unicode column line styles are single, double" msgstr "\\pset:å…许的 Unicode 列线型是 single å’Œ double\n" -#: command.c:2564 -#, c-format -#| msgid "\\pset: allowed unicode header linestyles are single, double\n" -msgid "\\pset: allowed Unicode header line styles are single, double\n" +#: command.c:3847 +#, fuzzy, c-format +#| msgid "\\pset: allowed Unicode header line styles are single, double\n" +msgid "\\pset: allowed Unicode header line styles are single, double" msgstr "\\pset:å…许的 Unicode 页眉线型是 single å’Œ double\n" -# command.c:1493 -#: command.c:2716 command.c:2895 +#: command.c:3890 #, c-format -msgid "\\pset: unknown option: %s\n" +msgid "\\pset: csv_fieldsep must be a single one-byte character" +msgstr "" + +#: command.c:3895 +#, c-format +msgid "\\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return" +msgstr "" + +# command.c:1493 +#: command.c:4032 command.c:4218 +#, fuzzy, c-format +#| msgid "\\pset: unknown option: %s\n" +msgid "\\pset: unknown option: %s" msgstr "\\pset: 䏿˜Žé€‰é¡¹: %s\n" # command.c:1355 -#: command.c:2734 +#: command.c:4050 #, c-format msgid "Border style is %d.\n" msgstr "边缘风格是 %d。\n" -#: command.c:2740 +#: command.c:4056 #, c-format msgid "Target width is unset.\n" msgstr "目标宽度未设置.\n" -#: command.c:2742 +#: command.c:4058 #, c-format msgid "Target width is %d.\n" msgstr "目标宽度为 %d.\n" # command.c:1364 -#: command.c:2749 +#: command.c:4065 #, c-format msgid "Expanded display is on.\n" msgstr "扩展显示已打开。\n" # command.c:1364 -#: command.c:2751 +#: command.c:4067 #, c-format msgid "Expanded display is used automatically.\n" msgstr "扩展显示已自动打开。\n" # command.c:1365 -#: command.c:2753 +#: command.c:4069 #, c-format msgid "Expanded display is off.\n" msgstr "扩展显示已关闭。\n" # command.c:1389 -#: command.c:2760 command.c:2768 +#: command.c:4075 +#, fuzzy, c-format +#| msgid "Field separator is \"%s\".\n" +msgid "Field separator for CSV is \"%s\".\n" +msgstr "æ ä½åˆ†éš”ç¬¦å·æ˜¯ \"%s\"。\n" + +# command.c:1389 +#: command.c:4083 command.c:4091 #, c-format msgid "Field separator is zero byte.\n" msgstr "æ ä½åˆ†éš”ç¬¦å·æ˜¯0字节\n" # command.c:1389 -#: command.c:2762 +#: command.c:4085 #, c-format msgid "Field separator is \"%s\".\n" msgstr "æ ä½åˆ†éš”ç¬¦å·æ˜¯ \"%s\"。\n" # command.c:1485 -#: command.c:2775 +#: command.c:4098 #, c-format msgid "Default footer is on.\n" msgstr "打开默认步进器。\n" # command.c:1487 -#: command.c:2777 +#: command.c:4100 #, c-format msgid "Default footer is off.\n" msgstr "关闭默认步进器。\n" # command.c:1345 -#: command.c:2783 +#: command.c:4106 #, c-format msgid "Output format is %s.\n" msgstr "è¾“å‡ºæ ¼å¼æ˜¯ %s。\n" # command.c:1355 -#: command.c:2789 +#: command.c:4112 #, c-format msgid "Line style is %s.\n" msgstr "文本的风格是%s. \n" # command.c:1377 -#: command.c:2796 +#: command.c:4119 #, c-format msgid "Null display is \"%s\".\n" msgstr " \"%s\" 是空值显示。\n" -#: command.c:2804 +#: command.c:4127 #, c-format msgid "Locale-adjusted numeric output is on.\n" msgstr "å¯åŠ¨è¯­è¨€çŽ¯å¢ƒè°ƒæ•´åŽçš„æ•°å€¼è¾“出。\n" -#: command.c:2806 +#: command.c:4129 #, c-format msgid "Locale-adjusted numeric output is off.\n" msgstr "关闭语言环境调整åŽçš„æ•°å€¼è¾“出。\n" # command.c:1470 -#: command.c:2813 +#: command.c:4136 #, c-format msgid "Pager is used for long output.\n" msgstr "æ˜¾ç¤ºå¤§é‡æ•°æ®æ—¶ä½¿ç”¨åˆ†é¡µå™¨ã€‚\n" # command.c:1472 -#: command.c:2815 +#: command.c:4138 #, c-format msgid "Pager is always used.\n" msgstr "总是使用分页器。\n" # command.c:1474 -#: command.c:2817 +#: command.c:4140 #, c-format msgid "Pager usage is off.\n" msgstr "ä¸ä½¿ç”¨åˆ†é¡µå™¨ã€‚\n" -#: command.c:2823 +#: command.c:4146 #, c-format msgid "Pager won't be used for less than %d line.\n" msgid_plural "Pager won't be used for less than %d lines.\n" msgstr[0] "分页器ä¸èƒ½è¢«ç”¨äºŽå°‘于%d行。\n" # command.c:1405 -#: command.c:2833 command.c:2843 +#: command.c:4156 command.c:4166 #, c-format msgid "Record separator is zero byte.\n" msgstr "è®°å½•åˆ†éš”ç¬¦å·æ˜¯ 0字节。\n" # command.c:1403 -#: command.c:2835 +#: command.c:4158 #, c-format msgid "Record separator is .\n" msgstr "è®°å½•åˆ†éš”ç¬¦å·æ˜¯ 。\n" # command.c:1405 -#: command.c:2837 +#: command.c:4160 #, c-format msgid "Record separator is \"%s\".\n" msgstr "è®°å½•åˆ†éš”ç¬¦å·æ˜¯ \"%s\"。\n" # command.c:1452 -#: command.c:2850 +#: command.c:4173 #, c-format msgid "Table attributes are \"%s\".\n" msgstr "表属性是 \"%s\".\n" # command.c:1454 -#: command.c:2853 +#: command.c:4176 #, c-format msgid "Table attributes unset.\n" msgstr "未设置数æ®è¡¨å±žæ€§ã€‚\n" # command.c:1434 -#: command.c:2860 +#: command.c:4183 #, c-format msgid "Title is \"%s\".\n" msgstr "标题是 \"%s\"。\n" # command.c:1436 -#: command.c:2862 +#: command.c:4185 #, c-format msgid "Title is unset.\n" msgstr "无标题。\n" # command.c:1418 -#: command.c:2869 +#: command.c:4192 #, c-format msgid "Tuples only is on.\n" msgstr "å¼€å¯åªæ˜¾ç¤ºå…ƒç»„。\n" # command.c:1418 -#: command.c:2871 +#: command.c:4194 #, c-format msgid "Tuples only is off.\n" msgstr "å…³é—­åªæ˜¾ç¤ºå…ƒç»„。\n" # command.c:1355 -#: command.c:2877 +#: command.c:4200 #, c-format -#| msgid "Unicode border linestyle is \"%s\".\n" msgid "Unicode border line style is \"%s\".\n" msgstr "Unicode 边界线型是 \"%s\"。\n" # command.c:1355 -#: command.c:2883 +#: command.c:4206 #, c-format -#| msgid "Unicode column linestyle is \"%s\".\n" msgid "Unicode column line style is \"%s\".\n" msgstr "Unicode 列线型是 \"%s\"。\n" # command.c:1355 -#: command.c:2889 +#: command.c:4212 #, c-format -#| msgid "Unicode header linestyle is \"%s\".\n" msgid "Unicode header line style is \"%s\".\n" msgstr "Unicode 页眉线型是 \"%s\"。\n" # command.c:1532 -#: command.c:3049 -#, c-format -msgid "\\!: failed\n" +#: command.c:4374 +#, fuzzy, c-format +#| msgid "\\!: failed\n" +msgid "\\!: failed" msgstr "\\!:失败\n" -#: command.c:3073 common.c:654 -#, c-format -msgid "\\watch cannot be used with an empty query\n" +#: command.c:4399 common.c:781 +#, fuzzy, c-format +#| msgid "\\watch cannot be used with an empty query\n" +msgid "\\watch cannot be used with an empty query" msgstr "\\watch命令ä¸èƒ½ç”¨äºŽç©ºæŸ¥è¯¢\n" -#: command.c:3110 +#: command.c:4440 #, c-format -#| msgid "%s (%s, server %s)\n" msgid "%s\t%s (every %gs)\n" msgstr "%s\t%s (æ¯ %gs)\n" -#: command.c:3113 +#: command.c:4443 #, c-format -#| msgid "%s (%s, server %s)\n" msgid "%s (every %gs)\n" msgstr "%s (æ¯ %gs)\n" -#: command.c:3167 command.c:3174 common.c:554 common.c:561 common.c:1168 +#: command.c:4497 command.c:4504 common.c:681 common.c:688 common.c:1345 #, c-format msgid "" "********* QUERY **********\n" @@ -780,200 +875,331 @@ msgstr "" "**************************\n" "\n" -#: command.c:3325 -#, c-format -#| msgid "\"%s\" is not a view" -msgid "%s.%s is not a view\n" -msgstr "%s.%s 䏿˜¯ä¸€ä¸ªè§†å›¾\n" - -#: common.c:137 -#, c-format -msgid "can't escape without active connection\n" +#: command.c:4696 +#, fuzzy, c-format +#| msgid "\"%s.%s\" is not a view\n" +msgid "\"%s.%s\" is not a view" +msgstr "\"%s.%s\"䏿˜¯ä¸€ä¸ªè§†å›¾\n" + +#: command.c:4712 +#, fuzzy, c-format +#| msgid "could not parse reloptions array\n" +msgid "could not parse reloptions array" +msgstr "æ— æ³•è§£æž reloptions 数组\n" + +#: common.c:160 +#, fuzzy, c-format +#| msgid "cannot escape without active connection\n" +msgid "cannot escape without active connection" msgstr "没有数æ®åº“连接时无法escape\n" +#: common.c:201 +#, fuzzy, c-format +#| msgid "shell command argument contains a newline or carriage return: \"%s\"\n" +msgid "shell command argument contains a newline or carriage return: \"%s\"" +msgstr "shell命令傿•°åŒ…嫿¢è¡Œç¬¦æˆ–回车符: \"%s\"\n" + # common.c:298 -#: common.c:366 -#, c-format -msgid "connection to server was lost\n" +#: common.c:395 +#, fuzzy, c-format +#| msgid "connection to server was lost\n" +msgid "connection to server was lost" msgstr "与数æ®åº“çš„è¿žæŽ¥å·²ç»æ–­å¼€\n" # common.c:302 -#: common.c:370 +#: common.c:399 #, c-format msgid "The connection to the server was lost. Attempting reset: " msgstr "与æœåŠ¡å™¨çš„è¿žæŽ¥å·²æ–­å¼€ï¼Œæ­£åœ¨è¯•å›¾é‡ç½®: " # common.c:307 -#: common.c:375 +#: common.c:404 #, c-format msgid "Failed.\n" msgstr "失败。\n" # common.c:314 -#: common.c:382 +#: common.c:411 #, c-format msgid "Succeeded.\n" msgstr "完æˆã€‚\n" # fe-exec.c:1371 -#: common.c:482 common.c:931 common.c:1103 -#, c-format -msgid "unexpected PQresultStatus: %d\n" +#: common.c:511 common.c:1063 common.c:1280 +#, fuzzy, c-format +#| msgid "unexpected PQresultStatus: %d\n" +msgid "unexpected PQresultStatus: %d" msgstr "æ„外的 PQresultStatus: %d\n" -#: common.c:661 +# common.c:930 +#: common.c:620 #, c-format -msgid "\\watch cannot be used with COPY\n" -msgstr "\\watchä¸èƒ½ç”¨äºŽCOPY命令中\n" +msgid "Time: %.3f ms\n" +msgstr "时间:%.3f ms\n" -# fe-exec.c:1371 -#: common.c:666 +# common.c:930 +#: common.c:635 #, c-format -msgid "unexpected result status for \\watch\n" -msgstr "\\Watch出现æ„外的结果状æ€\n" +msgid "Time: %.3f ms (%02d:%06.3f)\n" +msgstr "时间:%.3f ms (%02d:%06.3f)\n" -# common.c:930 -#: common.c:677 common.c:1327 +#: common.c:644 #, c-format -msgid "Time: %.3f ms\n" -msgstr "时间:%.3f ms\n" +msgid "Time: %.3f ms (%02d:%02d:%06.3f)\n" +msgstr "时间: %.3f ms (%02d:%02d:%06.3f)\n" + +#: common.c:651 +#, c-format +msgid "Time: %.3f ms (%.0f d %02d:%02d:%06.3f)\n" +msgstr "时间:%.3f ms (%.0f d %02d:%02d:%06.3f)\n" + +# common.c:636 +# common.c:871 +#: common.c:675 common.c:733 common.c:1316 +#, fuzzy, c-format +#| msgid "You are currently not connected to a database.\n" +msgid "You are currently not connected to a database." +msgstr "ä½ ç›®å‰æ²¡æœ‰è¿žæŽ¥åˆ°æ•°æ®åº“。\n" + +#: common.c:788 +#, fuzzy, c-format +#| msgid "\\watch cannot be used with COPY\n" +msgid "\\watch cannot be used with COPY" +msgstr "\\watchä¸èƒ½ç”¨äºŽCOPY命令中\n" + +# fe-exec.c:1371 +#: common.c:793 +#, fuzzy, c-format +#| msgid "unexpected result status for \\watch\n" +msgid "unexpected result status for \\watch" +msgstr "\\Watch出现æ„外的结果状æ€\n" # common.c:691 -#: common.c:695 +#: common.c:823 #, c-format -msgid "" -"Asynchronous notification \"%s\" with payload \"%s\" received from server " -"process with PID %d.\n" -msgstr "" -"从PID为%3$dçš„æœåŠ¡å™¨è¿›ç¨‹æŽ¥æ”¶åˆ°å¸¦æœ‰å­—èŠ‚æµé‡\"%2$s\"的异步通知消æ¯\"%1$s\".\n" +msgid "Asynchronous notification \"%s\" with payload \"%s\" received from server process with PID %d.\n" +msgstr "从PID为%3$dçš„æœåŠ¡å™¨è¿›ç¨‹æŽ¥æ”¶åˆ°å¸¦æœ‰å­—èŠ‚æµé‡\"%2$s\"的异步通知消æ¯\"%1$s\".\n" # common.c:691 -#: common.c:698 +#: common.c:826 #, c-format -msgid "" -"Asynchronous notification \"%s\" received from server process with PID %d.\n" +msgid "Asynchronous notification \"%s\" received from server process with PID %d.\n" msgstr "收到æ¥è‡ªæœåС噍 \"%s\" 进程 PID %d éžåŒæ­¥é€šçŸ¥ã€‚\n" -#: common.c:756 -#, c-format -msgid "no rows returned for \\gset\n" +#: common.c:889 +#, fuzzy, c-format +#| msgid "no rows returned for \\gset\n" +msgid "no rows returned for \\gset" msgstr "\\gset没有记录行返回\n" -#: common.c:761 -#, c-format -msgid "more than one row returned for \\gset\n" +#: common.c:894 +#, fuzzy, c-format +#| msgid "more than one row returned for \\gset\n" +msgid "more than one row returned for \\gset" msgstr "\\gset返回超过1个记录行\n" -# startup.c:502 -#: common.c:787 -#, c-format -msgid "could not set variable \"%s\"\n" -msgstr "无法设置å˜é‡ \"%s\"\n" - # common.c:879 -#: common.c:1148 +#: common.c:1325 #, c-format msgid "" -"***(Single step mode: verify command)" -"*******************************************\n" +"***(Single step mode: verify command)*******************************************\n" "%s\n" -"***(press return to proceed or enter x and return to cancel)" -"********************\n" +"***(press return to proceed or enter x and return to cancel)********************\n" msgstr "" "***(啿­¥æ¨¡å¼ï¼šéªŒè¯å‘½ä»¤)*******************************************\n" "%s\n" "***(按 Enter 键继续或键入 x æ¥å–消)********************\n" # describe.c:117 -#: common.c:1201 -#, c-format -msgid "" -"The server (version %d.%d) does not support savepoints for " -"ON_ERROR_ROLLBACK.\n" -msgstr "æœåС噍(版本 %d.%d)䏿”¯æŒä¿å­˜ç‚¹(Savepoint)ON_ERROR_ROLLBACK。\n" - -#: common.c:1256 -#, c-format -msgid "STATEMENT: %s\n" +#: common.c:1380 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK.\n" +msgid "The server (version %s) does not support savepoints for ON_ERROR_ROLLBACK." +msgstr "æœåС噍(版本 %s)䏿”¯æŒä¿å­˜ç‚¹(Savepoint)ON_ERROR_ROLLBACK。\n" + +#: common.c:1443 +#, fuzzy, c-format +#| msgid "STATEMENT: %s\n" +msgid "STATEMENT: %s" msgstr "语å¥ï¼š%s\n" # large_obj.c:58 -#: common.c:1299 -#, c-format -msgid "unexpected transaction status (%d)\n" +#: common.c:1486 +#, fuzzy, c-format +#| msgid "unexpected transaction status (%d)\n" +msgid "unexpected transaction status (%d)" msgstr "æ„外的事务状æ€å€¼ (%d)\n" -# copy.c:122 -#: copy.c:99 +# describe.c:744 +#: common.c:1623 describe.c:2002 +msgid "Column" +msgstr "æ ä½" + +# describe.c:415 +# describe.c:745 +# describe.c:1478 +# describe.c:1587 +#: common.c:1624 describe.c:179 describe.c:394 describe.c:412 describe.c:457 +#: describe.c:474 describe.c:963 describe.c:1127 describe.c:1712 +#: describe.c:1736 describe.c:2003 describe.c:3673 describe.c:3858 +#: describe.c:4091 describe.c:5297 +msgid "Type" +msgstr "类型" + +#: common.c:1673 #, c-format -msgid "\\copy: arguments required\n" +msgid "The command has no result, or the result has no columns.\n" +msgstr "命令没有结果,或者结果没有列.\n" + +# copy.c:122 +#: copy.c:100 +#, fuzzy, c-format +#| msgid "\\copy: arguments required\n" +msgid "\\copy: arguments required" msgstr "\\copy:需è¦å‚æ•°\n" # copy.c:408 -#: copy.c:254 -#, c-format -msgid "\\copy: parse error at \"%s\"\n" +#: copy.c:255 +#, fuzzy, c-format +#| msgid "\\copy: parse error at \"%s\"\n" +msgid "\\copy: parse error at \"%s\"" msgstr "\\copy:在 \"%s\" å‘生解读错误\n" # copy.c:410 -#: copy.c:256 -#, c-format -msgid "\\copy: parse error at end of line\n" +#: copy.c:257 +#, fuzzy, c-format +#| msgid "\\copy: parse error at end of line\n" +msgid "\\copy: parse error at end of line" msgstr "\\copy:在行尾å‘生解读错误\n" -#: copy.c:329 +#: copy.c:330 #, c-format -msgid "could not execute command \"%s\": %s\n" -msgstr "无法执行命令 \"%s\": %s\n" +msgid "could not execute command \"%s\": %m" +msgstr "无法执行命令 \"%s\": %m" -#: copy.c:345 +#: copy.c:346 #, c-format -msgid "could not stat file \"%s\": %s\n" -msgstr "æ— æ³•èŽ·å–æ–‡ä»¶ \"%s\":%s 的状æ€\n" +msgid "could not stat file \"%s\": %m" +msgstr "æ— æ³•å–æ–‡ä»¶ \"%s\" 的状æ€: %m" # copy.c:541 -#: copy.c:349 -#, c-format -msgid "%s: cannot copy from/to a directory\n" +#: copy.c:350 +#, fuzzy, c-format +#| msgid "%s: cannot copy from/to a directory\n" +msgid "%s: cannot copy from/to a directory" msgstr "%s:无法从目录å¤åˆ¶æˆ–å¤åˆ¶åˆ°ç›®å½•\n" -#: copy.c:386 +#: copy.c:387 #, c-format -msgid "could not close pipe to external command: %s\n" -msgstr "无法为外部命令: %s关闭管é“\n" +msgid "could not close pipe to external command: %m" +msgstr "无法为外部命令: %m关闭管é“" -# command.c:1103 -#: copy.c:452 copy.c:463 +# command.c:788 +# command.c:808 +# command.c:1163 +# command.c:1170 +# command.c:1180 +# command.c:1192 +# command.c:1205 +# command.c:1219 +# command.c:1241 +# command.c:1272 +# common.c:170 +# copy.c:530 +# copy.c:575 +#: copy.c:392 #, c-format -msgid "could not write COPY data: %s\n" +msgid "%s: %s" +msgstr "%s: %s" + +# command.c:1103 +#: copy.c:455 copy.c:465 +#, fuzzy, c-format +#| msgid "could not write COPY data: %s\n" +msgid "could not write COPY data: %m" msgstr "无法写入 COPY æ•°æ®ï¼š%s\n" -#: copy.c:470 +#: copy.c:471 #, c-format msgid "COPY data transfer failed: %s" msgstr "COPY æ•°æ®è½¬æ¢å¤±è´¥ï¼š%s" -#: copy.c:531 +#: copy.c:532 msgid "canceled by user" msgstr "ä¾ç”¨æˆ·å–消" # copy.c:668 -#: copy.c:542 +#: copy.c:543 msgid "" "Enter data to be copied followed by a newline.\n" -"End with a backslash and a period on a line by itself." +"End with a backslash and a period on a line by itself, or an EOF signal." msgstr "" "输入è¦å¤åˆ¶çš„æ•°æ®å¹¶ä¸”æ¢è¡Œã€‚\n" -"åœ¨ç‹¬ç«‹çš„ä¸€è¡Œä¸Šè¾“å…¥ä¸€ä¸ªåæ–œçº¿å’Œä¸€ä¸ªå¥ç‚¹ç»“æŸã€‚" +"åœ¨ç‹¬ç«‹çš„ä¸€è¡Œä¸Šè¾“å…¥ä¸€ä¸ªåæ–œçº¿å’Œä¸€ä¸ªå¥ç‚¹ç»“æŸï¼Œæˆ–者以一个EOFä¿¡å·ç»“æŸ." #: copy.c:671 msgid "aborted because of read failure" msgstr "因读å–失败已被中止" -#: copy.c:695 +#: copy.c:705 msgid "trying to exit copy mode" msgstr "正在å°è¯•退出" +#: crosstabview.c:124 +#, fuzzy, c-format +#| msgid "\\crosstabview: statement did not return a result set\n" +msgid "\\crosstabview: statement did not return a result set" +msgstr "\\crosstabview:è¯­å¥æœªè¿”回结果集\n" + +#: crosstabview.c:130 +#, fuzzy, c-format +#| msgid "\\crosstabview: query must return at least three columns\n" +msgid "\\crosstabview: query must return at least three columns" +msgstr "\\crosstabview:查询必须返回至少三列\n" + +#: crosstabview.c:157 +#, fuzzy, c-format +#| msgid "\\crosstabview: vertical and horizontal headers must be different columns\n" +msgid "\\crosstabview: vertical and horizontal headers must be different columns" +msgstr "\\crosstabview: 垂直和水平表头必须是ä¸åŒçš„列\n" + +#: crosstabview.c:173 +#, fuzzy, c-format +#| msgid "\\crosstabview: data column must be specified when query returns more than three columns\n" +msgid "\\crosstabview: data column must be specified when query returns more than three columns" +msgstr "\\crosstabview: 当查询返回三列以上时,必须指定数æ®åˆ—\n" + +#: crosstabview.c:229 +#, fuzzy, c-format +#| msgid "\\crosstabview: maximum number of columns (%d) exceeded\n" +msgid "\\crosstabview: maximum number of columns (%d) exceeded" +msgstr "\\crosstabview: 超过最大列数(%d)\n" + +#: crosstabview.c:398 +#, fuzzy, c-format +#| msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"\n" +msgid "\\crosstabview: query result contains multiple data values for row \"%s\", column \"%s\"" +msgstr "\\crosstabview: 查询结果包å«è¡Œ\"%s\"ã€åˆ—\"%s\"的多个数æ®å€¼\n" + +# fe-exec.c:2108 fe-exec.c:2141 +#: crosstabview.c:646 +#, fuzzy, c-format +#| msgid "\\crosstabview: column number %d is out of range 1..%d\n" +msgid "\\crosstabview: column number %d is out of range 1..%d" +msgstr "\\crosstabview: 列å·ç  %d 超出了范围 1..%d\n" + +#: crosstabview.c:671 +#, fuzzy, c-format +#| msgid "\\crosstabview: ambiguous column name: \"%s\"\n" +msgid "\\crosstabview: ambiguous column name: \"%s\"" +msgstr "\\crosstabview: 䏿˜Žç¡®çš„列å: \"%s\"\n" + +#: crosstabview.c:679 +#, fuzzy, c-format +#| msgid "\\crosstabview: column name not found: \"%s\"\n" +msgid "\\crosstabview: column name not found: \"%s\"" +msgstr "\\crosstabview: 找ä¸åˆ°åˆ—å: \"%s\"\n" + # describe.c:82 # describe.c:177 # describe.c:247 @@ -983,11 +1209,11 @@ msgstr "正在å°è¯•退出" # describe.c:1476 # describe.c:1585 # describe.c:1633 -#: describe.c:71 describe.c:264 describe.c:496 describe.c:626 describe.c:769 -#: describe.c:886 describe.c:956 describe.c:2931 describe.c:3136 -#: describe.c:3226 describe.c:3471 describe.c:3608 describe.c:3837 -#: describe.c:3909 describe.c:3920 describe.c:3979 describe.c:4387 -#: describe.c:4467 +#: describe.c:77 describe.c:374 describe.c:679 describe.c:811 describe.c:955 +#: describe.c:1116 describe.c:1188 describe.c:3662 describe.c:3845 +#: describe.c:4089 describe.c:4180 describe.c:4447 describe.c:4607 +#: describe.c:4848 describe.c:4923 describe.c:4934 describe.c:4996 +#: describe.c:5421 describe.c:5504 msgid "Schema" msgstr "架构模å¼" @@ -1003,23 +1229,24 @@ msgstr "架构模å¼" # describe.c:1586 # describe.c:1634 # describe.c:1727 -#: describe.c:72 describe.c:156 describe.c:164 describe.c:265 describe.c:497 -#: describe.c:627 describe.c:688 describe.c:770 describe.c:957 describe.c:2932 -#: describe.c:3058 describe.c:3137 describe.c:3227 describe.c:3306 -#: describe.c:3472 describe.c:3536 describe.c:3609 describe.c:3838 -#: describe.c:3910 describe.c:3921 describe.c:3980 describe.c:4169 -#: describe.c:4250 describe.c:4465 +#: describe.c:78 describe.c:176 describe.c:244 describe.c:252 describe.c:375 +#: describe.c:680 describe.c:812 describe.c:873 describe.c:956 describe.c:1189 +#: describe.c:3663 describe.c:3846 describe.c:4012 describe.c:4090 +#: describe.c:4181 describe.c:4260 describe.c:4448 describe.c:4532 +#: describe.c:4608 describe.c:4849 describe.c:4924 describe.c:4935 +#: describe.c:4997 describe.c:5194 describe.c:5278 describe.c:5502 +#: describe.c:5674 describe.c:5899 msgid "Name" msgstr "åç§°" # describe.c:177 -#: describe.c:73 describe.c:277 describe.c:323 describe.c:340 +#: describe.c:79 describe.c:387 describe.c:405 describe.c:451 describe.c:468 msgid "Result data type" msgstr "结果数æ®ç±»åž‹" # describe.c:178 -#: describe.c:81 describe.c:94 describe.c:98 describe.c:278 describe.c:324 -#: describe.c:341 +#: describe.c:87 describe.c:100 describe.c:104 describe.c:388 describe.c:406 +#: describe.c:452 describe.c:469 msgid "Argument data types" msgstr "傿•°æ•°æ®ç±»åž‹" @@ -1033,193 +1260,236 @@ msgstr "傿•°æ•°æ®ç±»åž‹" # describe.c:1488 # describe.c:1733 # large_obj.c:256 -#: describe.c:105 describe.c:187 describe.c:370 describe.c:545 describe.c:642 -#: describe.c:713 describe.c:959 describe.c:1572 describe.c:2732 -#: describe.c:2965 describe.c:3089 describe.c:3163 describe.c:3236 -#: describe.c:3319 describe.c:3387 describe.c:3479 describe.c:3545 -#: describe.c:3610 describe.c:3746 describe.c:3786 describe.c:3854 -#: describe.c:3913 describe.c:3922 describe.c:3981 describe.c:4195 -#: describe.c:4272 describe.c:4401 describe.c:4468 large_obj.c:289 -#: large_obj.c:299 +#: describe.c:112 describe.c:119 describe.c:187 describe.c:275 describe.c:514 +#: describe.c:728 describe.c:827 describe.c:898 describe.c:1191 describe.c:2021 +#: describe.c:3451 describe.c:3698 describe.c:3892 describe.c:4043 +#: describe.c:4117 describe.c:4190 describe.c:4273 describe.c:4356 +#: describe.c:4475 describe.c:4541 describe.c:4609 describe.c:4750 +#: describe.c:4792 describe.c:4865 describe.c:4927 describe.c:4936 +#: describe.c:4998 describe.c:5220 describe.c:5300 describe.c:5435 +#: describe.c:5505 large_obj.c:290 large_obj.c:300 msgid "Description" msgstr "æè¿°" # describe.c:97 -#: describe.c:123 +#: describe.c:137 msgid "List of aggregate functions" msgstr "èšé›†å‡½æ•°åˆ—表" # describe.c:117 -#: describe.c:144 -#, c-format -msgid "The server (version %d.%d) does not support tablespaces.\n" -msgstr "æœåС噍(版本%d.%d) 䏿”¯æŒä½¿ç”¨è¡¨ç©ºé—´.\n" +#: describe.c:162 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support access methods.\n" +msgid "The server (version %s) does not support access methods." +msgstr "æœåС噍(版本%s) 䏿”¯æŒè®¿é—®æ–¹æ³•.\n" + +# describe.c:543 +# describe.c:1477 +#: describe.c:177 +msgid "Index" +msgstr "索引" + +# describe.c:1483 +#: describe.c:178 describe.c:3679 describe.c:3871 describe.c:5422 +msgid "Table" +msgstr "æ•°æ®è¡¨" + +#: describe.c:186 describe.c:5199 +msgid "Handler" +msgstr "处ç†å‡½æ•°" + +#: describe.c:205 +msgid "List of access methods" +msgstr "访问方法列表" + +# describe.c:117 +#: describe.c:231 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support tablespaces.\n" +msgid "The server (version %s) does not support tablespaces." +msgstr "æœåС噍(版本%s) 䏿”¯æŒä½¿ç”¨è¡¨ç©ºé—´.\n" # describe.c:128 # describe.c:186 # describe.c:362 # describe.c:1478 # describe.c:1727 -#: describe.c:157 describe.c:165 describe.c:367 describe.c:535 describe.c:689 -#: describe.c:885 describe.c:2941 describe.c:3062 describe.c:3308 -#: describe.c:3537 describe.c:4170 describe.c:4251 large_obj.c:288 +#: describe.c:245 describe.c:253 describe.c:502 describe.c:718 describe.c:874 +#: describe.c:1115 describe.c:3674 describe.c:3847 describe.c:4016 +#: describe.c:4262 describe.c:4533 describe.c:5195 describe.c:5279 +#: describe.c:5675 describe.c:5801 describe.c:5900 large_obj.c:289 msgid "Owner" msgstr "拥有者" # describe.c:128 -#: describe.c:158 describe.c:166 +#: describe.c:246 describe.c:254 msgid "Location" msgstr "所在地" -#: describe.c:177 describe.c:2543 +#: describe.c:265 describe.c:3269 msgid "Options" msgstr "选项" # describe.c:257 -#: describe.c:182 describe.c:508 describe.c:705 describe.c:2957 -#: describe.c:2961 +#: describe.c:270 describe.c:691 describe.c:890 describe.c:3690 describe.c:3694 msgid "Size" msgstr "大å°" # describe.c:150 -#: describe.c:204 +#: describe.c:292 msgid "List of tablespaces" msgstr "表空间列表" -#: describe.c:241 -#, c-format -msgid "\\df only takes [antwS+] as options\n" -msgstr "\\df åªèƒ½å°† [antwS+]作为选项\n" +#: describe.c:334 +#, fuzzy, c-format +#| msgid "\\df only takes [anptwS+] as options\n" +msgid "\\df only takes [anptwS+] as options" +msgstr "\\df åªèƒ½å°† [anptwS+]作为选项\n" -#: describe.c:247 -#, c-format -msgid "\\df does not take a \"w\" option with server version %d.%d\n" -msgstr "\\df ä¸èƒ½æœ‰å¸¦ç€æœåŠ¡å™¨ç‰ˆæœ¬%d.%d 的选项\"w\" \n" +#: describe.c:342 describe.c:353 +#, fuzzy, c-format +#| msgid "\\df does not take a \"%c\" option with server version %s\n" +msgid "\\df does not take a \"%c\" option with server version %s" +msgstr "\\df ä¸èƒ½æœ‰å¸¦ç€æœåŠ¡å™¨ç‰ˆæœ¬%2$s 的选项\"%1$c\"\n" #. translator: "agg" is short for "aggregate" -#: describe.c:280 describe.c:326 describe.c:343 +#: describe.c:390 describe.c:408 describe.c:454 describe.c:471 msgid "agg" msgstr "agg" -#: describe.c:281 +#: describe.c:391 describe.c:409 msgid "window" msgstr "窗å£" -# describe.c:575 -#: describe.c:282 describe.c:327 describe.c:344 describe.c:1093 -msgid "trigger" -msgstr "触å‘器" - -# help.c:211 -#: describe.c:283 describe.c:328 describe.c:345 -msgid "normal" -msgstr "常规" +#: describe.c:392 +msgid "proc" +msgstr "proc" # describe.c:415 -# describe.c:745 -# describe.c:1478 -# describe.c:1587 -#: describe.c:284 describe.c:329 describe.c:346 describe.c:776 describe.c:895 -#: describe.c:1541 describe.c:2940 describe.c:3138 describe.c:4269 -msgid "Type" -msgstr "类型" - -# sql_help.h:221 -#: describe.c:360 -msgid "definer" -msgstr "定义者" - -#: describe.c:361 -msgid "invoker" -msgstr "调用者" +# describe.c:543 +# describe.c:1477 +#: describe.c:393 describe.c:411 describe.c:456 describe.c:473 +msgid "func" +msgstr "函数" -#: describe.c:362 -msgid "Security" -msgstr "安全" +# describe.c:575 +#: describe.c:410 describe.c:455 describe.c:472 describe.c:1325 +msgid "trigger" +msgstr "触å‘器" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:363 +#: describe.c:484 msgid "immutable" msgstr "ä¸å¯æ›´æ”¹" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:364 +#: describe.c:485 msgid "stable" msgstr "稳定" -#: describe.c:365 +#: describe.c:486 msgid "volatile" msgstr "ä¸ç¨³å®šæ€§" -#: describe.c:366 +#: describe.c:487 msgid "Volatility" msgstr "æŒ¥å‘æ€§" +#: describe.c:495 +msgid "restricted" +msgstr "å—é™åˆ¶çš„" + +#: describe.c:496 +msgid "safe" +msgstr "安全的" + +#: describe.c:497 +msgid "unsafe" +msgstr "ä¸å®‰å…¨çš„" + +#: describe.c:498 +msgid "Parallel" +msgstr "平行" + +# sql_help.h:221 +#: describe.c:503 +msgid "definer" +msgstr "定义者" + +#: describe.c:504 +msgid "invoker" +msgstr "调用者" + +#: describe.c:505 +msgid "Security" +msgstr "安全" + # describe.c:186 -#: describe.c:368 +#: describe.c:512 msgid "Language" msgstr "程åºè¯­è¨€" # describe.c:187 -#: describe.c:369 +#: describe.c:513 msgid "Source code" msgstr "原始程å¼" # describe.c:221 -#: describe.c:467 +#: describe.c:642 msgid "List of functions" msgstr "函数列表" # describe.c:257 -#: describe.c:507 +#: describe.c:690 msgid "Internal name" msgstr "内部åç§°" -#: describe.c:529 +#: describe.c:712 msgid "Elements" msgstr "æˆå‘˜" # describe.c:289 -#: describe.c:585 +#: describe.c:769 msgid "List of data types" msgstr "æ•°æ®ç±»åž‹åˆ—表" # describe.c:321 -#: describe.c:628 +#: describe.c:813 msgid "Left arg type" msgstr "左傿•°ç±»åž‹" # describe.c:321 -#: describe.c:629 +#: describe.c:814 msgid "Right arg type" msgstr "å³å‚数类型" # describe.c:322 -#: describe.c:630 +#: describe.c:815 msgid "Result type" msgstr "结果类型" # describe.c:1691 -#: describe.c:635 describe.c:3378 describe.c:3745 +#: describe.c:820 describe.c:4268 describe.c:4333 describe.c:4339 +#: describe.c:4749 msgid "Function" msgstr "函数" # describe.c:336 -#: describe.c:660 +#: describe.c:845 msgid "List of operators" msgstr "è¿ç®—å­åˆ—表" # describe.c:365 -#: describe.c:690 +#: describe.c:875 msgid "Encoding" msgstr "字元编ç " # describe.c:128 -#: describe.c:695 describe.c:3473 +#: describe.c:880 describe.c:4449 msgid "Collate" msgstr "校对规则" @@ -1227,77 +1497,83 @@ msgstr "校对规则" # describe.c:745 # describe.c:1478 # describe.c:1587 -#: describe.c:696 describe.c:3474 +#: describe.c:881 describe.c:4450 msgid "Ctype" msgstr "Ctype" # describe.c:1342 -#: describe.c:709 +#: describe.c:894 msgid "Tablespace" msgstr "表空间" # describe.c:381 -#: describe.c:731 +#: describe.c:916 msgid "List of databases" msgstr "æ•°æ®åº“列表" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:771 describe.c:888 describe.c:2933 +#: describe.c:957 describe.c:1118 describe.c:3664 msgid "table" msgstr "æ•°æ®è¡¨" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:772 describe.c:2934 +#: describe.c:958 describe.c:3665 msgid "view" msgstr "视图" -#: describe.c:773 describe.c:2935 +#: describe.c:959 describe.c:3666 msgid "materialized view" msgstr "物化视图" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:774 describe.c:890 describe.c:2937 +#: describe.c:960 describe.c:1120 describe.c:3668 msgid "sequence" msgstr "åºåˆ—æ•°" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:775 describe.c:2939 +#: describe.c:961 describe.c:3670 msgid "foreign table" msgstr "所引用的外表" +#: describe.c:962 describe.c:3671 describe.c:3856 +#, fuzzy +#| msgid "partition_name" +msgid "partitioned table" +msgstr "分区å" + # sql_help.h:325 -#: describe.c:787 +#: describe.c:974 msgid "Column privileges" msgstr "列特æƒ" -#: describe.c:818 +#: describe.c:1005 describe.c:1039 msgid "Policies" msgstr "ç­–ç•¥" # describe.c:133 # describe.c:415 # describe.c:1733 -#: describe.c:844 describe.c:4612 describe.c:4616 +#: describe.c:1071 describe.c:5956 describe.c:5960 msgid "Access privileges" msgstr "å­˜å–æƒé™" # describe.c:117 -#: describe.c:873 -#, c-format -msgid "" -"The server (version %d.%d) does not support altering default privileges.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä¿®æ”¹é»˜è®¤æƒé™.\n" +#: describe.c:1102 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support altering default privileges.\n" +msgid "The server (version %s) does not support altering default privileges." +msgstr "æœåС噍(版本%s)䏿”¯æŒä¿®æ”¹é»˜è®¤æƒé™.\n" # describe.c:498 -#: describe.c:892 +#: describe.c:1122 msgid "function" msgstr "函数" @@ -1305,352 +1581,487 @@ msgstr "函数" # describe.c:745 # describe.c:1478 # describe.c:1587 -#: describe.c:894 +#: describe.c:1124 msgid "type" msgstr "类型Ctype" +# describe.c:82 +# describe.c:177 +# describe.c:247 +# describe.c:320 +# describe.c:415 +# describe.c:469 +# describe.c:1476 +# describe.c:1585 +# describe.c:1633 +#: describe.c:1126 +msgid "schema" +msgstr "架构模å¼" + # sql_help.h:325 -#: describe.c:918 +#: describe.c:1150 msgid "Default access privileges" msgstr "默认的访问æƒé™" # describe.c:469 -#: describe.c:958 +#: describe.c:1190 msgid "Object" msgstr "对象" -#: describe.c:972 +#: describe.c:1204 msgid "table constraint" msgstr "表约æŸ" -#: describe.c:994 +#: describe.c:1226 msgid "domain constraint" msgstr "域约æŸ" -#: describe.c:1022 +#: describe.c:1254 msgid "operator class" msgstr "æ“作符类" # sql_help.h:269 -#: describe.c:1051 +#: describe.c:1283 msgid "operator family" msgstr "æ“作符家æ—" # describe.c:559 -#: describe.c:1073 +#: describe.c:1305 msgid "rule" msgstr "规则" # describe.c:593 -#: describe.c:1115 +#: describe.c:1347 msgid "Object descriptions" msgstr "对象æè¿°" # describe.c:641 -#: describe.c:1169 -#, c-format -msgid "Did not find any relation named \"%s\".\n" +#: describe.c:1403 describe.c:3762 +#, fuzzy, c-format +#| msgid "Did not find any relation named \"%s\".\n" +msgid "Did not find any relation named \"%s\"." msgstr "没有找到任何å称为 \"%s\" 的关è”。\n" +# describe.c:641 +#: describe.c:1406 describe.c:3765 +#, fuzzy, c-format +#| msgid "Did not find any relations.\n" +msgid "Did not find any relations." +msgstr "没有找到任何关系.\n" + # describe.c:728 -#: describe.c:1379 -#, c-format -msgid "Did not find any relation with OID %s.\n" +#: describe.c:1661 +#, fuzzy, c-format +#| msgid "Did not find any relation with OID %s.\n" +msgid "Did not find any relation with OID %s." msgstr "没有找到任何OID为 %s 的关è”。\n" -# describe.c:933 -#: describe.c:1485 -#, c-format +#: describe.c:1713 describe.c:1737 +msgid "Start" +msgstr "起始值" + +#: describe.c:1714 describe.c:1738 +msgid "Minimum" +msgstr "最å°å€¼" + +#: describe.c:1715 describe.c:1739 +msgid "Maximum" +msgstr "最大值" + +#: describe.c:1716 describe.c:1740 +msgid "Increment" +msgstr "增é‡" + +# describe.c:1262 +# describe.c:1637 +# describe.c:1694 +#: describe.c:1717 describe.c:1741 describe.c:1872 describe.c:4184 +#: describe.c:4350 describe.c:4464 describe.c:4469 +msgid "yes" +msgstr "是" + +# describe.c:1262 +# describe.c:1638 +# describe.c:1692 +#: describe.c:1718 describe.c:1742 describe.c:1873 describe.c:4184 +#: describe.c:4347 describe.c:4464 +msgid "no" +msgstr "å¦" + +#: describe.c:1719 describe.c:1743 +msgid "Cycles?" +msgstr "循环?" + +#: describe.c:1720 describe.c:1744 +msgid "Cache" +msgstr "缓存" + +#: describe.c:1787 +#, c-format +msgid "Owned by: %s" +msgstr "属于: %s" + +#: describe.c:1791 +#, c-format +msgid "Sequence for identity column: %s" +msgstr "标识列的åºåˆ—: %s" + +# describe.c:867 +#: describe.c:1798 +#, c-format +msgid "Sequence \"%s.%s\"" +msgstr "åºåˆ—æ•° \"%s.%s\"" + +# describe.c:933 +#: describe.c:1934 +#, c-format msgid "Unlogged table \"%s.%s\"" msgstr "ä¸è®°å½•日志的表 \"%s.%s\"" # describe.c:859 -#: describe.c:1488 +#: describe.c:1937 #, c-format msgid "Table \"%s.%s\"" msgstr "æ•°æ®è¡¨ \"%s.%s\"" # describe.c:863 -#: describe.c:1492 +#: describe.c:1941 #, c-format msgid "View \"%s.%s\"" msgstr "视图 \"%s.%s\"" # describe.c:933 -#: describe.c:1497 +#: describe.c:1946 #, c-format msgid "Unlogged materialized view \"%s.%s\"" msgstr "ä¸è®°å½•日志的物化视图 \"%s.%s\"" -#: describe.c:1500 +#: describe.c:1949 #, c-format msgid "Materialized view \"%s.%s\"" msgstr "物化视图 \"%s.%s\"" -# describe.c:867 -#: describe.c:1504 -#, c-format -msgid "Sequence \"%s.%s\"" -msgstr "åºåˆ—æ•° \"%s.%s\"" - # describe.c:871 -#: describe.c:1509 +#: describe.c:1954 #, c-format msgid "Unlogged index \"%s.%s\"" msgstr "ä¸è®°å½•日志的索引 \"%s.%s\"" # describe.c:871 -#: describe.c:1512 +#: describe.c:1957 #, c-format msgid "Index \"%s.%s\"" msgstr "索引 \"%s.%s\"" +# describe.c:871 +#: describe.c:1962 +#, fuzzy, c-format +#| msgid "Unlogged index \"%s.%s\"" +msgid "Unlogged partitioned index \"%s.%s\"" +msgstr "ä¸è®°å½•日志的索引 \"%s.%s\"" + +# describe.c:871 +#: describe.c:1965 +#, fuzzy, c-format +#| msgid "Unlogged index \"%s.%s\"" +msgid "Partitioned index \"%s.%s\"" +msgstr "ä¸è®°å½•日志的索引 \"%s.%s\"" + # describe.c:875 -#: describe.c:1517 +#: describe.c:1970 #, c-format msgid "Special relation \"%s.%s\"" msgstr "ç‰¹æ®Šå…³è” \"%s.%s\"" # describe.c:879 -#: describe.c:1521 +#: describe.c:1974 #, c-format msgid "TOAST table \"%s.%s\"" msgstr "TOAST æ•°æ®è¡¨ \"%s.%s\"" # describe.c:883 -#: describe.c:1525 +#: describe.c:1978 #, c-format msgid "Composite type \"%s.%s\"" msgstr "åˆæˆç±»åž‹ \"%s.%s\"" # describe.c:933 -#: describe.c:1529 +#: describe.c:1982 #, c-format msgid "Foreign table \"%s.%s\"" msgstr "引用的外部表 \"%s.%s\"" -# describe.c:744 -#: describe.c:1540 -msgid "Column" -msgstr "æ ä½" +# describe.c:933 +#: describe.c:1987 +#, fuzzy, c-format +#| msgid "Unlogged table \"%s.%s\"" +msgid "Unlogged partitioned table \"%s.%s\"" +msgstr "ä¸è®°å½•日志的表 \"%s.%s\"" -# describe.c:752 -#: describe.c:1549 -msgid "Modifiers" -msgstr "修饰è¯" +# describe.c:933 +#: describe.c:1990 +#, fuzzy, c-format +#| msgid "Foreign table \"%s.%s\"" +msgid "Partitioned table \"%s.%s\"" +msgstr "引用的外部表 \"%s.%s\"" -# describe.c:415 -# describe.c:543 -# describe.c:1477 -#: describe.c:1554 -msgid "Value" -msgstr "值" +# describe.c:128 +#: describe.c:2006 describe.c:4097 +msgid "Collation" +msgstr "校对规则" + +#: describe.c:2007 describe.c:4104 +msgid "Nullable" +msgstr "å¯ç©ºçš„" + +# describe.c:1639 +#: describe.c:2008 describe.c:4105 +msgid "Default" +msgstr "预设" + +#: describe.c:2011 +msgid "Key?" +msgstr "键值?" # describe.c:1636 -#: describe.c:1557 +#: describe.c:2013 msgid "Definition" msgstr "定义" -#: describe.c:1560 describe.c:4190 describe.c:4271 describe.c:4339 -#: describe.c:4400 -msgid "FDW Options" +#: describe.c:2015 describe.c:5215 describe.c:5299 describe.c:5370 +#: describe.c:5434 +msgid "FDW options" msgstr "FDW选项" # describe.c:1635 -#: describe.c:1564 +#: describe.c:2017 msgid "Storage" msgstr "存储" -#: describe.c:1567 +#: describe.c:2019 msgid "Stats target" msgstr "统计目标" -#: describe.c:1617 +#: describe.c:2137 #, c-format -msgid "collate %s" -msgstr "校对%s" +msgid "Partition of: %s %s" +msgstr "分区: %s %s" -#: describe.c:1625 -msgid "not null" -msgstr "éžç©º" +#: describe.c:2145 +msgid "No partition constraint" +msgstr "无分区约æŸ" -# describe.c:1639 -#. translator: default values of column definitions -#: describe.c:1635 +#: describe.c:2147 +#, c-format +msgid "Partition constraint: %s" +msgstr "分区约æŸ: %s" + +#: describe.c:2170 #, c-format -msgid "default %s" -msgstr "默认 %s" +msgid "Partition key: %s" +msgstr "分区键值: %s" # describe.c:925 -#: describe.c:1750 +#: describe.c:2239 msgid "primary key, " msgstr "主键(PK)," # describe.c:927 -#: describe.c:1752 +#: describe.c:2241 msgid "unique, " msgstr "唯一的," # describe.c:933 -#: describe.c:1758 +#: describe.c:2247 #, c-format msgid "for table \"%s.%s\"" msgstr "给数æ®è¡¨ \"%s.%s\"" # describe.c:937 -#: describe.c:1762 +#: describe.c:2251 #, c-format msgid ", predicate (%s)" msgstr ", å™è¿° (%s)" # describe.c:940 -#: describe.c:1765 +#: describe.c:2254 msgid ", clustered" msgstr ", 已丛集" -#: describe.c:1768 +#: describe.c:2257 msgid ", invalid" msgstr ", 无效的" -#: describe.c:1771 +#: describe.c:2260 msgid ", deferrable" msgstr ",å¯å»¶è¿Ÿ" -#: describe.c:1774 +#: describe.c:2263 msgid ", initially deferred" msgstr ",开始被延迟" -#: describe.c:1777 +#: describe.c:2266 msgid ", replica identity" msgstr ",å¤åˆ¶æ ‡è¯†" -#: describe.c:1812 -#, c-format -msgid "Owned by: %s" -msgstr "属于: %s" - # describe.c:1138 -#: describe.c:1872 +#: describe.c:2325 msgid "Indexes:" msgstr "索引:" # describe.c:1174 -#: describe.c:1956 +#: describe.c:2409 msgid "Check constraints:" msgstr "检查约æŸé™åˆ¶" # describe.c:1189 -#: describe.c:1987 +#: describe.c:2477 msgid "Foreign-key constraints:" msgstr "外部键(FK)é™åˆ¶ï¼š" -#: describe.c:2018 +#: describe.c:2540 msgid "Referenced by:" msgstr "由引用:" -#: describe.c:2063 +#: describe.c:2590 msgid "Policies:" msgstr "策略:" -#: describe.c:2066 -#| msgid "Policies (Forced Row Security Enabled):" +#: describe.c:2593 msgid "Policies (forced row security enabled):" msgstr "策略(强制行安全性å¯ç”¨ï¼‰ï¼š" -#: describe.c:2069 -#| msgid "Policies (Row Security Enabled): (None)" +#: describe.c:2596 msgid "Policies (row security enabled): (none)" msgstr "策略(行安全性å¯ç”¨ï¼‰ï¼šï¼ˆæ— ï¼‰" -#: describe.c:2072 -#| msgid "Policies (Forced Row Security Enabled): (None)" +#: describe.c:2599 msgid "Policies (forced row security enabled): (none)" msgstr "策略(强制行安全性å¯ç”¨ï¼‰ï¼šï¼ˆæ— ï¼‰" -#: describe.c:2075 -#| msgid "Policies (Row Security Disabled):" +#: describe.c:2602 msgid "Policies (row security disabled):" msgstr "策略(行安全性ç¦ç”¨ï¼‰ï¼š" +#: describe.c:2665 +msgid "Statistics objects:" +msgstr "统计信æ¯å¯¹è±¡:" + # describe.c:983 # describe.c:1204 -#: describe.c:2175 describe.c:2225 +#: describe.c:2774 describe.c:2878 msgid "Rules:" msgstr "规则:" -#: describe.c:2178 +#: describe.c:2777 msgid "Disabled rules:" msgstr "å·²åœç”¨è§„则:" -#: describe.c:2181 +#: describe.c:2780 msgid "Rules firing always:" msgstr "永远触å‘规则" -#: describe.c:2184 +#: describe.c:2783 msgid "Rules firing on replica only:" msgstr "åªæœ‰åœ¨å¤åˆ¶æ—¶è§¦å‘规则:" +# describe.c:1636 +#: describe.c:2823 +msgid "Publications:" +msgstr "出版物:" + # describe.c:977 -#: describe.c:2208 +#: describe.c:2861 msgid "View definition:" msgstr "视图定义:" # describe.c:1223 -#: describe.c:2343 +#: describe.c:3000 msgid "Triggers:" msgstr "触å‘器:" -#: describe.c:2347 +#: describe.c:3004 msgid "Disabled user triggers:" msgstr "ç¦ç”¨ç”¨æˆ·è§¦å‘器:" -#: describe.c:2349 +#: describe.c:3006 msgid "Disabled triggers:" msgstr "åœç”¨è§¦å‘器:" -#: describe.c:2352 +#: describe.c:3009 msgid "Disabled internal triggers:" msgstr "ç¦ç”¨å†…部触å‘器:" -#: describe.c:2355 +#: describe.c:3012 msgid "Triggers firing always:" msgstr "永远激活触å‘器" -#: describe.c:2358 +#: describe.c:3015 msgid "Triggers firing on replica only:" msgstr "åªæœ‰åœ¨å¤åˆ¶æ—¶æ¿€æ´»è§¦å‘器" +#: describe.c:3074 +#, c-format +msgid "Server: %s" +msgstr "æœåС噍 %s" + +#: describe.c:3082 +#, c-format +msgid "FDW options: (%s)" +msgstr "FDW选项: (%s)" + # describe.c:1245 -#: describe.c:2437 +#: describe.c:3101 msgid "Inherits" msgstr "继承" -#: describe.c:2476 +#: describe.c:3160 +#, c-format +msgid "Number of partitions: %d" +msgstr "分区数: %d" + +#: describe.c:3169 #, c-format msgid "Number of child tables: %d (Use \\d+ to list them.)" msgstr "å­è¡¨çš„æ•°é‡ï¼š%d(å¯ä»¥ä½¿ç”¨ \\d+ æ¥åˆ—出它们)" -#: describe.c:2483 +#: describe.c:3171 +#, c-format +msgid "Number of partitions: %d (Use \\d+ to list them.)" +msgstr "分区的数é‡ï¼š%d(å¯ä»¥ä½¿ç”¨ \\d+ æ¥åˆ—出它们)" + +#: describe.c:3179 msgid "Child tables" msgstr "å­è¡¨" -#: describe.c:2505 +# describe.c:128 +#: describe.c:3179 +msgid "Partitions" +msgstr "分区" + +#: describe.c:3222 #, c-format msgid "Typed table of type: %s" msgstr "类型的已确定类型表(typed table):%s" # describe.c:1636 -#: describe.c:2519 +#: describe.c:3238 msgid "Replica Identity" msgstr "å¤åˆ¶æ ‡è¯†" # describe.c:1259 -#: describe.c:2532 +#: describe.c:3251 msgid "Has OIDs: yes" msgstr "有 OIDs:yes" +#: describe.c:3260 +#, fuzzy, c-format +#| msgid "List of access methods" +msgid "Access method: %s" +msgstr "访问方法列表" + # describe.c:1342 -#: describe.c:2620 +#: describe.c:3339 #, c-format msgid "Tablespace: \"%s\"" msgstr "表空间:\"%s\"" @@ -1658,430 +2069,479 @@ msgstr "表空间:\"%s\"" # describe.c:1342 #. translator: before this string there's an index description like #. '"foo_pkey" PRIMARY KEY, btree (a)' -#: describe.c:2632 +#: describe.c:3351 #, c-format msgid ", tablespace \"%s\"" msgstr ", 表空间 \"%s\"" # describe.c:1431 -#: describe.c:2725 +#: describe.c:3444 msgid "List of roles" msgstr "角色列表" # describe.c:1375 -#: describe.c:2727 +#: describe.c:3446 msgid "Role name" msgstr "角色åç§°" -#: describe.c:2728 +#: describe.c:3447 msgid "Attributes" msgstr "属性" -#: describe.c:2729 +#: describe.c:3448 msgid "Member of" msgstr "æˆå‘˜å±žäºŽ" # describe.c:1377 -#: describe.c:2740 +#: describe.c:3459 msgid "Superuser" msgstr "超级用户" -#: describe.c:2743 +#: describe.c:3462 msgid "No inheritance" msgstr "没有继承" -#: describe.c:2746 +#: describe.c:3465 msgid "Create role" msgstr "建立角色" -#: describe.c:2749 +#: describe.c:3468 msgid "Create DB" msgstr "建立 DB" -#: describe.c:2752 +#: describe.c:3471 msgid "Cannot login" msgstr "无法登录" # describe.c:1636 -#: describe.c:2756 +#: describe.c:3475 msgid "Replication" msgstr "å¤åˆ¶" -#: describe.c:2760 +#: describe.c:3479 msgid "Bypass RLS" msgstr "绕过RLS" # help.c:123 -#: describe.c:2769 +#: describe.c:3488 msgid "No connections" msgstr "没有连接" # help.c:123 -#: describe.c:2771 +#: describe.c:3490 #, c-format msgid "%d connection" msgid_plural "%d connections" msgstr[0] "%d个连接" -#: describe.c:2781 +#: describe.c:3500 msgid "Password valid until " msgstr "å¯†ç æœ‰æ•ˆç›´è‡³" +# describe.c:117 +#: describe.c:3550 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support per-database role settings.\n" +msgid "The server (version %s) does not support per-database role settings." +msgstr "æœåС噍(版本%s) æ¯ä¸ªæ•°æ®åº“角色设置.\n" + # describe.c:1375 -#: describe.c:2837 +#: describe.c:3563 msgid "Role" msgstr "角色" -#: describe.c:2838 +#: describe.c:3564 msgid "Database" msgstr "æ•°æ®åº“" -#: describe.c:2839 +#: describe.c:3565 msgid "Settings" msgstr "设置" -#: describe.c:2849 -#, c-format -msgid "No per-database role settings support in this server version.\n" -msgstr "在这个版本的æœåС噍䏭䏿”¯æŒå¯¹æ¯ä¸ªæ•°æ®åº“的角色进行设定.\n" +# describe.c:641 +#: describe.c:3586 +#, fuzzy, c-format +#| msgid "Did not find any settings for role \"%s\" and database \"%s\".\n" +msgid "Did not find any settings for role \"%s\" and database \"%s\"." +msgstr "找ä¸åˆ°è§’色\"%s\"和数æ®åº“\"%s\"的任何设置.\n" -# describe.c:1542 -#: describe.c:2860 -#, c-format -msgid "No matching settings found.\n" -msgstr "没有找到所匹é…的设置.\n" +# describe.c:641 +#: describe.c:3589 +#, fuzzy, c-format +#| msgid "Did not find any settings for role \"%s\".\n" +msgid "Did not find any settings for role \"%s\"." +msgstr "找ä¸åˆ°è§’色\"%s\"的任何设置.\n" -# describe.c:1544 -#: describe.c:2862 -#, c-format -msgid "No settings found.\n" -msgstr "没有找到设置.\n" +# describe.c:641 +#: describe.c:3592 +#, fuzzy, c-format +#| msgid "Did not find any settings.\n" +msgid "Did not find any settings." +msgstr "找ä¸åˆ°ä»»ä½•设置.\n" # describe.c:1549 -#: describe.c:2867 +#: describe.c:3597 msgid "List of settings" msgstr "设置的列表" # describe.c:543 # describe.c:1477 -#: describe.c:2936 +#: describe.c:3667 msgid "index" msgstr "索引" # describe.c:1478 -#: describe.c:2938 +#: describe.c:3669 msgid "special" msgstr "特殊" -# describe.c:1483 -#: describe.c:2946 describe.c:4388 -msgid "Table" -msgstr "æ•°æ®è¡¨" +#: describe.c:3672 describe.c:3857 +#, fuzzy +#| msgid "partition_name" +msgid "partitioned index" +msgstr "分区å" -# describe.c:1542 -#: describe.c:3022 -#, c-format -msgid "No matching relations found.\n" -msgstr "没有找到符åˆçš„å…³è”。\n" +# describe.c:1549 +#: describe.c:3770 +msgid "List of relations" +msgstr "å…³è”列表" -# describe.c:1544 -#: describe.c:3024 -#, c-format -msgid "No relations found.\n" -msgstr "找ä¸åˆ°å…³è”。\n" +# describe.c:117 +#: describe.c:3818 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support collations.\n" +msgid "The server (version %s) does not support declarative table partitioning." +msgstr "æœåС噍(版本%s)䏿”¯æŒæŽ’åºæ ¡å¯¹ã€‚\n" # describe.c:1549 -#: describe.c:3029 -msgid "List of relations" +#: describe.c:3829 +#, fuzzy +#| msgid "List of publications" +msgid "List of partitioned indexes" +msgstr "出版物列表" + +# describe.c:1653 +#: describe.c:3831 +#, fuzzy +#| msgid "List of foreign tables" +msgid "List of partitioned tables" +msgstr "引用表列表" + +# describe.c:1549 +#: describe.c:3835 +#, fuzzy +#| msgid "List of relations" +msgid "List of partitioned relations" msgstr "å…³è”列表" -#: describe.c:3066 +# describe.c:1375 +#: describe.c:3866 +#, fuzzy +#| msgid "Token name" +msgid "Parent name" +msgstr "标志åç§°" + +# describe.c:128 +#: describe.c:3879 +#, fuzzy +#| msgid "Partitions" +msgid "Leaf partition size" +msgstr "分区" + +#: describe.c:3882 describe.c:3888 +msgid "Total size" +msgstr "" + +#: describe.c:4020 msgid "Trusted" msgstr "ä¿¡ä»»" # describe.c:257 -#: describe.c:3074 -msgid "Internal Language" +#: describe.c:4028 +msgid "Internal language" msgstr "内部语言" -#: describe.c:3075 -msgid "Call Handler" +#: describe.c:4029 +msgid "Call handler" msgstr "调用函数" -#: describe.c:3076 describe.c:4177 +#: describe.c:4030 describe.c:5202 msgid "Validator" msgstr "验è¯" -#: describe.c:3079 -msgid "Inline Handler" +#: describe.c:4033 +msgid "Inline handler" msgstr "内è”函数" # describe.c:1431 -#: describe.c:3107 +#: describe.c:4061 msgid "List of languages" msgstr "语言列表" -# describe.c:1588 -#: describe.c:3151 -msgid "Modifier" -msgstr "修饰è¯" - -#: describe.c:3152 +#: describe.c:4106 msgid "Check" msgstr "检查" # describe.c:1602 -#: describe.c:3194 +#: describe.c:4148 msgid "List of domains" msgstr "å…±åŒå€¼åŸŸåˆ—表" # describe.c:1635 -#: describe.c:3228 +#: describe.c:4182 msgid "Source" msgstr "æ¥æº" # describe.c:1636 -#: describe.c:3229 +#: describe.c:4183 msgid "Destination" msgstr "目的地" -# describe.c:1262 -# describe.c:1638 -# describe.c:1692 -#: describe.c:3230 describe.c:3379 -msgid "no" -msgstr "å¦" - -# describe.c:1262 -# describe.c:1637 -# describe.c:1694 -#: describe.c:3230 describe.c:3381 -msgid "yes" -msgstr "是" - # describe.c:1639 -#: describe.c:3231 +#: describe.c:4185 msgid "Default?" msgstr "预设?" # describe.c:1653 -#: describe.c:3268 +#: describe.c:4222 msgid "List of conversions" msgstr "字元编ç è½¬æ¢åˆ—表" -#: describe.c:3307 +#: describe.c:4261 msgid "Event" msgstr "Event" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:3309 +#: describe.c:4263 msgid "enabled" msgstr "å¯ç”¨" # describe.c:1636 -#: describe.c:3310 +#: describe.c:4264 msgid "replica" msgstr "replica" -#: describe.c:3311 +#: describe.c:4265 msgid "always" msgstr "ç»å¸¸" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:3312 +#: describe.c:4266 msgid "disabled" msgstr "ç¦ç”¨" # describe.c:415 # describe.c:543 # describe.c:1477 -#: describe.c:3313 +#: describe.c:4267 describe.c:5901 msgid "Enabled" msgstr "使能" -#: describe.c:3314 -msgid "Procedure" -msgstr "过程" - -#: describe.c:3315 +#: describe.c:4269 msgid "Tags" msgstr "标签" # describe.c:1549 -#: describe.c:3334 +#: describe.c:4288 msgid "List of event triggers" msgstr "事件触å‘器列表" # describe.c:1688 -#: describe.c:3376 +#: describe.c:4317 msgid "Source type" msgstr "æ¥æºç±»åž‹" # describe.c:1689 -#: describe.c:3377 +#: describe.c:4318 msgid "Target type" msgstr "目标类型" # describe.c:1693 -#: describe.c:3380 +#: describe.c:4349 msgid "in assignment" msgstr "在指派中" # describe.c:1695 -#: describe.c:3382 +#: describe.c:4351 msgid "Implicit?" msgstr "éšå«çš„?" # describe.c:1703 -#: describe.c:3433 +#: describe.c:4406 msgid "List of casts" msgstr "类型转æ¢åˆ—表" # describe.c:117 -#: describe.c:3459 -#, c-format -msgid "The server (version %d.%d) does not support collations.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒæŽ’åºæ ¡å¯¹ã€‚\n" +#: describe.c:4434 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support collations.\n" +msgid "The server (version %s) does not support collations." +msgstr "æœåС噍(版本%s)䏿”¯æŒæŽ’åºæ ¡å¯¹ã€‚\n" + +#: describe.c:4455 describe.c:4459 +msgid "Provider" +msgstr "æä¾›è€…" + +#: describe.c:4465 describe.c:4470 +msgid "Deterministic?" +msgstr "" # describe.c:1549 -#: describe.c:3509 +#: describe.c:4505 msgid "List of collations" msgstr "校对列表" # describe.c:1753 -#: describe.c:3568 +#: describe.c:4564 msgid "List of schemas" msgstr "架构模å¼åˆ—表" # describe.c:117 -#: describe.c:3591 describe.c:3826 describe.c:3894 describe.c:3962 -#, c-format -msgid "The server (version %d.%d) does not support full text search.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä½¿ç”¨å…¨æ–‡æœç´¢.\n" +#: describe.c:4589 describe.c:4836 describe.c:4907 describe.c:4978 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support full text search.\n" +msgid "The server (version %s) does not support full text search." +msgstr "æœåС噍(版本%s)䏿”¯æŒä½¿ç”¨å…¨æ–‡æœç´¢.\n" # describe.c:150 -#: describe.c:3625 +#: describe.c:4624 msgid "List of text search parsers" msgstr "文本剖æžå™¨åˆ—表" # describe.c:641 -#: describe.c:3668 -#, c-format -msgid "Did not find any text search parser named \"%s\".\n" +#: describe.c:4669 +#, fuzzy, c-format +#| msgid "Did not find any text search parser named \"%s\".\n" +msgid "Did not find any text search parser named \"%s\"." msgstr "没有找到任何命å为 \"%s\" 的文本剖æžå™¨ã€‚\n" -#: describe.c:3743 +# describe.c:641 +#: describe.c:4672 +#, fuzzy, c-format +#| msgid "Did not find any text search parsers.\n" +msgid "Did not find any text search parsers." +msgstr "找ä¸åˆ°ä»»ä½•文本æœç´¢è§£æžå™¨.\n" + +#: describe.c:4747 msgid "Start parse" msgstr "开始剖æž" -#: describe.c:3744 +#: describe.c:4748 msgid "Method" msgstr "方法" -#: describe.c:3748 +#: describe.c:4752 msgid "Get next token" msgstr "å–得下一个标志符" -#: describe.c:3750 +#: describe.c:4754 msgid "End parse" msgstr "结æŸå‰–æž" -#: describe.c:3752 +#: describe.c:4756 msgid "Get headline" msgstr "å–得首行" -#: describe.c:3754 +#: describe.c:4758 msgid "Get token types" msgstr "å–得标志符类型" -#: describe.c:3764 +#: describe.c:4769 #, c-format msgid "Text search parser \"%s.%s\"" msgstr "文本æœç´¢å‰–æžå™¨ \"%s.%s\"" -#: describe.c:3766 +#: describe.c:4772 #, c-format msgid "Text search parser \"%s\"" msgstr "文本æœç´¢å‰–æžå™¨ \"%s\"" # describe.c:1375 -#: describe.c:3785 +#: describe.c:4791 msgid "Token name" msgstr "标志åç§°" -#: describe.c:3796 +#: describe.c:4802 #, c-format msgid "Token types for parser \"%s.%s\"" msgstr "标志符别型给剖æžå™¨ \"%s.%s\"" -#: describe.c:3798 +#: describe.c:4805 #, c-format msgid "Token types for parser \"%s\"" msgstr "标志符类型给剖æžå™¨ \"%s\"" -#: describe.c:3848 +#: describe.c:4859 msgid "Template" msgstr "模版" # help.c:88 -#: describe.c:3849 +#: describe.c:4860 msgid "Init options" msgstr "åˆå§‹é€‰é¡¹" # describe.c:1549 -#: describe.c:3871 +#: describe.c:4882 msgid "List of text search dictionaries" msgstr "文本æœç´¢å­—典列表" -#: describe.c:3911 +#: describe.c:4925 msgid "Init" msgstr "åˆå§‹åŒ–" # describe.c:257 -#: describe.c:3912 +#: describe.c:4926 msgid "Lexize" msgstr "è¯æ±‡" # describe.c:1753 -#: describe.c:3939 +#: describe.c:4953 msgid "List of text search templates" msgstr "文本æœç´¢æ ·å¼åˆ—表" # describe.c:97 -#: describe.c:3996 +#: describe.c:5013 msgid "List of text search configurations" msgstr "文本æœç´¢ç»„æ€åˆ—表" # describe.c:641 -#: describe.c:4040 -#, c-format -msgid "Did not find any text search configuration named \"%s\".\n" +#: describe.c:5059 +#, fuzzy, c-format +#| msgid "Did not find any text search configuration named \"%s\".\n" +msgid "Did not find any text search configuration named \"%s\"." msgstr "没有找到任何命å为 \"%s\" 的文本æœç´¢ç»„æ€ã€‚\n" -#: describe.c:4106 +# describe.c:641 +#: describe.c:5062 +#, fuzzy, c-format +#| msgid "Did not find any text search configurations.\n" +msgid "Did not find any text search configurations." +msgstr "未找到任何文本æœç´¢é…ç½®.\n" + +#: describe.c:5128 msgid "Token" msgstr "标志符" -#: describe.c:4107 +#: describe.c:5129 msgid "Dictionaries" msgstr "å­—å…¸" -#: describe.c:4118 +#: describe.c:5140 #, c-format msgid "Text search configuration \"%s.%s\"" msgstr "文本æœç´¢ç»„æ€ \"%s.%s\"" -#: describe.c:4121 +#: describe.c:5143 #, c-format msgid "Text search configuration \"%s\"" msgstr "文本æœç´¢ç»„æ€ \"%s\"" # describe.c:859 -#: describe.c:4125 +#: describe.c:5147 #, c-format msgid "" "\n" @@ -2091,7 +2551,7 @@ msgstr "" "剖æžå™¨ï¼š\"%s.%s\"" # describe.c:1342 -#: describe.c:4128 +#: describe.c:5150 #, c-format msgid "" "\n" @@ -2101,112 +2561,187 @@ msgstr "" "剖æžå™¨ï¼š\"%s\"" # describe.c:117 -#: describe.c:4160 -#, c-format -msgid "The server (version %d.%d) does not support foreign-data wrappers.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä½¿ç”¨å¤–部数æ®å°è£…器。\n" - -#: describe.c:4174 -msgid "Handler" -msgstr "处ç†å‡½æ•°" +#: describe.c:5184 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support foreign-data wrappers.\n" +msgid "The server (version %s) does not support foreign-data wrappers." +msgstr "æœåС噍(版本%s)䏿”¯æŒä½¿ç”¨å¤–部数æ®å°è£…器。\n" # describe.c:289 -#: describe.c:4217 +#: describe.c:5242 msgid "List of foreign-data wrappers" msgstr "外部数æ®å°è£…器列表" # describe.c:117 -#: describe.c:4240 -#, c-format -msgid "The server (version %d.%d) does not support foreign servers.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä½¿ç”¨å¤–部æœåС噍.\n" +#: describe.c:5267 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support foreign servers.\n" +msgid "The server (version %s) does not support foreign servers." +msgstr "æœåС噍(版本%s)䏿”¯æŒä½¿ç”¨å¤–部æœåС噍.\n" -#: describe.c:4252 +#: describe.c:5280 msgid "Foreign-data wrapper" msgstr "外部数æ®å°è£…器" -#: describe.c:4270 describe.c:4466 +#: describe.c:5298 describe.c:5503 msgid "Version" msgstr "版本" # describe.c:1653 -#: describe.c:4296 +#: describe.c:5324 msgid "List of foreign servers" msgstr "外部æœåŠ¡å™¨åˆ—è¡¨" # describe.c:117 -#: describe.c:4319 -#, c-format -msgid "The server (version %d.%d) does not support user mappings.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä½¿ç”¨ç”¨æˆ·æ˜ å°„。\n" +#: describe.c:5349 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support user mappings.\n" +msgid "The server (version %s) does not support user mappings." +msgstr "æœåС噍(版本%s)䏿”¯æŒä½¿ç”¨ç”¨æˆ·æ˜ å°„。\n" # describe.c:1377 -#: describe.c:4328 describe.c:4389 +#: describe.c:5359 describe.c:5423 msgid "Server" msgstr "æœåС噍" -#: describe.c:4329 +#: describe.c:5360 msgid "User name" msgstr "用户å: " # describe.c:1602 -#: describe.c:4354 +#: describe.c:5385 msgid "List of user mappings" msgstr "列出用户映射" # describe.c:117 -#: describe.c:4377 -#, c-format -msgid "The server (version %d.%d) does not support foreign tables.\n" -msgstr "æœåС噍(版本%d.%d)䏿”¯æŒä½¿ç”¨å¼•用表.\n" +#: describe.c:5410 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support foreign tables.\n" +msgid "The server (version %s) does not support foreign tables." +msgstr "æœåС噍(版本%s)䏿”¯æŒä½¿ç”¨å¼•用表.\n" # describe.c:1653 -#: describe.c:4429 +#: describe.c:5463 msgid "List of foreign tables" msgstr "引用表列表" # describe.c:117 -#: describe.c:4452 describe.c:4506 -#, c-format -msgid "The server (version %d.%d) does not support extensions.\n" -msgstr "æœåС噍(版本%d.%d) 䏿”¯æŒä½¿ç”¨æ‰©å±•.\n" +#: describe.c:5488 describe.c:5545 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support extensions.\n" +msgid "The server (version %s) does not support extensions." +msgstr "æœåС噍(版本%s) 䏿”¯æŒä½¿ç”¨æ‰©å±•.\n" # describe.c:1653 -#: describe.c:4483 +#: describe.c:5520 msgid "List of installed extensions" msgstr "已安装扩展列表" # describe.c:641 -#: describe.c:4533 -#, c-format -msgid "Did not find any extension named \"%s\".\n" +#: describe.c:5573 +#, fuzzy, c-format +#| msgid "Did not find any extension named \"%s\".\n" +msgid "Did not find any extension named \"%s\"." msgstr "没有找到任何å称为 \"%s\" 的扩展。\n" # describe.c:641 -#: describe.c:4536 -#, c-format -msgid "Did not find any extensions.\n" +#: describe.c:5576 +#, fuzzy, c-format +#| msgid "Did not find any extensions.\n" +msgid "Did not find any extensions." msgstr "没有找到任何扩展.\n" # describe.c:593 -#: describe.c:4580 -msgid "Object Description" +#: describe.c:5620 +msgid "Object description" msgstr "对象æè¿°" -#: describe.c:4589 +#: describe.c:5630 #, c-format msgid "Objects in extension \"%s\"" msgstr "对象用于扩展 \"%s\"" -# command.c:953 -# common.c:216 -# common.c:605 -# common.c:660 -# common.c:903 -#: help.c:63 +# describe.c:117 +#: describe.c:5659 describe.c:5730 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support publications.\n" +msgid "The server (version %s) does not support publications." +msgstr "æœåС噍(版本%s)䏿”¯æŒå‡ºç‰ˆç‰©.\n" + +#: describe.c:5676 describe.c:5802 +msgid "All tables" +msgstr "所有表" + +#: describe.c:5677 describe.c:5803 +msgid "Inserts" +msgstr "æ’å…¥" + +#: describe.c:5678 describe.c:5804 +msgid "Updates" +msgstr "æ›´æ–°" + +#: describe.c:5679 describe.c:5805 +msgid "Deletes" +msgstr "删除" + +#: describe.c:5683 describe.c:5807 +msgid "Truncates" +msgstr "截断" + +# describe.c:1549 +#: describe.c:5700 +msgid "List of publications" +msgstr "出版物列表" + +# describe.c:641 +#: describe.c:5768 +#, fuzzy, c-format +#| msgid "Did not find any publication named \"%s\".\n" +msgid "Did not find any publication named \"%s\"." +msgstr "没有找到任何å称为 \"%s\" 的出版物.\n" + +# describe.c:641 +#: describe.c:5771 +#, fuzzy, c-format +#| msgid "Did not find any publications.\n" +msgid "Did not find any publications." +msgstr "没有找到任何出版物.\n" + +#: describe.c:5798 #, c-format -msgid "%s\n" -msgstr "%s\n" +msgid "Publication %s" +msgstr "出版物 %s" + +# describe.c:1483 +#: describe.c:5842 +msgid "Tables:" +msgstr "æ•°æ®è¡¨" + +# describe.c:117 +#: describe.c:5886 +#, fuzzy, c-format +#| msgid "The server (version %s) does not support subscriptions.\n" +msgid "The server (version %s) does not support subscriptions." +msgstr "æœåС噍(版本%s)䏿”¯æŒè®¢é˜…。\n" + +# describe.c:1636 +#: describe.c:5902 +msgid "Publication" +msgstr "出版" + +#: describe.c:5909 +msgid "Synchronous commit" +msgstr "åŒæ­¥æäº¤" + +# help.c:123 +#: describe.c:5910 +msgid "Conninfo" +msgstr "连接信æ¯" + +# describe.c:221 +#: describe.c:5932 +msgid "List of subscriptions" +msgstr "订阅列表" # help.c:83 #: help.c:74 @@ -2216,7 +2751,7 @@ msgid "" "\n" msgstr "psql是PostgreSQL 的交互å¼å®¢æˆ·ç«¯å·¥å…·ã€‚\n" -#: help.c:75 help.c:332 help.c:366 help.c:393 +#: help.c:75 help.c:349 help.c:425 help.c:468 #, c-format msgid "Usage:\n" msgstr "使用方法:\n" @@ -2237,29 +2772,26 @@ msgstr "通用选项:\n" # help.c:94 #: help.c:83 #, c-format -msgid "" -" -c, --command=COMMAND run only single command (SQL or internal) and " -"exit\n" +msgid " -c, --command=COMMAND run only single command (SQL or internal) and exit\n" msgstr " -c,--command=命令 执行å•一命令(SQL或内部指令)ç„¶åŽç»“æŸ\n" # help.c:93 #: help.c:84 #, c-format -msgid "" -" -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" -msgstr " -d, --dbname=æ•°æ®åº“åç§° 指定è¦è¿žæŽ¥çš„æ•°æ®åº“ (默认:\"%s\")\n" +msgid " -d, --dbname=DBNAME database name to connect to (default: \"%s\")\n" +msgstr " -d, --dbname=DBNAME 指定è¦è¿žæŽ¥çš„æ•°æ®åº“ (默认:\"%s\")\n" # help.c:95 #: help.c:85 #, c-format msgid " -f, --file=FILENAME execute commands from file, then exit\n" -msgstr " -f, --file=文件å 从文件中执行命令然åŽé€€å‡º\n" +msgstr " -f, --file=文件å 从文件中执行命令然åŽé€€å‡º\n" # help.c:96 #: help.c:86 #, c-format msgid " -l, --list list available databases, then exit\n" -msgstr " -l, --list 列出所有å¯ç”¨çš„æ•°æ®åº“,ç„¶åŽé€€å‡º\n" +msgstr " -l, --list 列出所有å¯ç”¨çš„æ•°æ®åº“,ç„¶åŽé€€å‡º\n" # help.c:97 #: help.c:87 @@ -2282,17 +2814,16 @@ msgstr " -V, --version 输出版本信æ¯, ç„¶åŽé€€å‡º\n" #: help.c:91 #, c-format msgid " -X, --no-psqlrc do not read startup file (~/.psqlrc)\n" -msgstr " -X, --no-psqlrc ä¸è¯»å–å¯åŠ¨æ–‡æ¡£(~/.psqlrc)\n" +msgstr " -X, --no-psqlrc ä¸è¯»å–å¯åŠ¨æ–‡æ¡£(~/.psqlrc)\n" #: help.c:92 #, c-format msgid "" " -1 (\"one\"), --single-transaction\n" -" execute as a single transaction (if non-" -"interactive)\n" +" execute as a single transaction (if non-interactive)\n" msgstr "" " -1 (\"one\"), --single-transaction\n" -" 作为一个å•ä¸€äº‹åŠ¡æ¥æ‰§è¡Œå‘½ä»¤æ–‡ä»¶(如果是éžäº¤äº’型的)\n" +" 作为一个å•ä¸€äº‹åŠ¡æ¥æ‰§è¡Œå‘½ä»¤æ–‡ä»¶(如果是éžäº¤äº’型的)\n" #: help.c:94 #, c-format @@ -2323,7 +2854,7 @@ msgstr "" #: help.c:99 #, c-format msgid " -a, --echo-all echo all input from script\n" -msgstr " -a, --echo-all 显示所有æ¥è‡ªäºŽè„šæœ¬çš„è¾“å…¥\n" +msgstr " -a, --echo-all 显示所有æ¥è‡ªäºŽè„šæœ¬çš„è¾“å…¥\n" # help.c:104 #: help.c:100 @@ -2335,53 +2866,48 @@ msgstr " -b, --echo-errors 回显失败的命令\n" #: help.c:101 #, c-format msgid " -e, --echo-queries echo commands sent to server\n" -msgstr " -e, --echo-queries 显示å‘é€ç»™æœåŠ¡å™¨çš„å‘½ä»¤\n" +msgstr " -e, --echo-queries 显示å‘é€ç»™æœåŠ¡å™¨çš„å‘½ä»¤\n" # help.c:105 #: help.c:102 #, c-format -msgid "" -" -E, --echo-hidden display queries that internal commands generate\n" -msgstr " -E, --echo-hidden 显示内部命令产生的查询\n" +msgid " -E, --echo-hidden display queries that internal commands generate\n" +msgstr " -E, --echo-hidden 显示内部命令产生的查询\n" # help.c:107 #: help.c:103 #, c-format msgid " -L, --log-file=FILENAME send session log to file\n" -msgstr " -L, --log-file=文件å å°†ä¼šè¯æ—¥å¿—写入文件\n" +msgstr " -L, --log-file=文件å å°†ä¼šè¯æ—¥å¿—写入文件\n" # help.c:108 #: help.c:104 #, c-format -msgid "" -" -n, --no-readline disable enhanced command line editing (readline)\n" -msgstr " -n, --no-readline ç¦ç”¨å¢žå¼ºå‘½ä»¤è¡Œç¼–辑功能(readline)\n" +msgid " -n, --no-readline disable enhanced command line editing (readline)\n" +msgstr " -n, --no-readline ç¦ç”¨å¢žå¼ºå‘½ä»¤è¡Œç¼–辑功能(readline)\n" # help.c:107 #: help.c:105 #, c-format msgid " -o, --output=FILENAME send query results to file (or |pipe)\n" -msgstr " -o, --output=FILENAME 将查询结果写入文件(或 |管é“)\n" +msgstr " -o, --output=FILENAME 将查询结果写入文件(或 |管é“)\n" # help.c:106 #: help.c:106 #, c-format -msgid "" -" -q, --quiet run quietly (no messages, only query output)\n" -msgstr " -q, --quiet 以沉默模å¼è¿è¡Œ(䏿˜¾ç¤ºæ¶ˆæ¯ï¼Œåªæœ‰æŸ¥è¯¢ç»“æžœ)\n" +msgid " -q, --quiet run quietly (no messages, only query output)\n" +msgstr " -q, --quiet 以沉默模å¼è¿è¡Œ(䏿˜¾ç¤ºæ¶ˆæ¯ï¼Œåªæœ‰æŸ¥è¯¢ç»“æžœ)\n" # help.c:109 #: help.c:107 #, c-format msgid " -s, --single-step single-step mode (confirm each query)\n" -msgstr " -s, --single-step 啿­¥æ¨¡å¼ (确认æ¯ä¸ªæŸ¥è¯¢)\n" +msgstr " -s, --single-step 啿­¥æ¨¡å¼ (确认æ¯ä¸ªæŸ¥è¯¢)\n" # help.c:110 #: help.c:108 #, c-format -msgid "" -" -S, --single-line single-line mode (end of line terminates SQL " -"command)\n" +msgid " -S, --single-line single-line mode (end of line terminates SQL command)\n" msgstr " -S, --single-line å•è¡Œæ¨¡å¼ (ä¸€è¡Œå°±æ˜¯ä¸€æ¡ SQL 命令)\n" # help.c:112 @@ -2398,88 +2924,86 @@ msgstr "" #: help.c:111 #, c-format msgid " -A, --no-align unaligned table output mode\n" -msgstr " -A, --no-align 使用éžå¯¹é½è¡¨æ ¼è¾“出模å¼\n" +msgstr " -A, --no-align 使用éžå¯¹é½è¡¨æ ¼è¾“出模å¼\n" -# help.c:119 +# help.c:234 #: help.c:112 +#, fuzzy, c-format +#| msgid " \\a toggle between unaligned and aligned output mode\n" +msgid " --csv CSV (Comma-Separated Values) table output mode\n" +msgstr " \\a 在éžå¯¹é½æ¨¡å¼å’Œå¯¹é½æ¨¡å¼ä¹‹é—´åˆ‡æ¢\n" + +# help.c:119 +#: help.c:113 #, c-format msgid "" " -F, --field-separator=STRING\n" -" field separator for unaligned output (default: " -"\"%s\")\n" +" field separator for unaligned output (default: \"%s\")\n" msgstr "" " -F, --field-separator=STRING\n" -" 为字段设置分隔符,ç”¨äºŽä¸æ•´é½çš„输出(默认:\"%s\")\n" +" 为字段设置分隔符,ç”¨äºŽä¸æ•´é½çš„输出(默认:\"%s\")\n" # help.c:114 -#: help.c:115 +#: help.c:116 #, c-format msgid " -H, --html HTML table output mode\n" -msgstr " -H, --html HTML 表格输出模å¼\n" +msgstr " -H, --html HTML 表格输出模å¼\n" # help.c:118 -#: help.c:116 +#: help.c:117 #, c-format -msgid "" -" -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset " -"command)\n" -msgstr "" -" -P, --pset=å˜é‡[=傿•°] 设置将å˜é‡æ‰“å°åˆ°å‚数的选项(查阅 \\pset 命令)\n" +msgid " -P, --pset=VAR[=ARG] set printing option VAR to ARG (see \\pset command)\n" +msgstr " -P, --pset=å˜é‡[=傿•°] 设置将å˜é‡æ‰“å°åˆ°å‚数的选项(查阅 \\pset 命令)\n" # help.c:121 -#: help.c:117 +#: help.c:118 #, c-format msgid "" " -R, --record-separator=STRING\n" -" record separator for unaligned output (default: " -"newline)\n" +" record separator for unaligned output (default: newline)\n" msgstr "" " -R, --record-separator=STRING\n" -" ä¸ºä¸æ•´é½çš„输出设置字录的分隔符(默认:æ¢è¡Œç¬¦å·)\n" +" ä¸ºä¸æ•´é½çš„输出设置字录的分隔符(默认:æ¢è¡Œç¬¦å·)\n" # help.c:115 -#: help.c:119 +#: help.c:120 #, c-format msgid " -t, --tuples-only print rows only\n" -msgstr " -t, --tuples-only åªæ‰“å°è®°å½•i\n" +msgstr " -t, --tuples-only åªæ‰“å°è®°å½•i\n" # help.c:116 -#: help.c:120 +#: help.c:121 #, c-format -msgid "" -" -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, " -"border)\n" -msgstr " -T, --table-attr=文本 设定 HTML 表格标记属性(例如,宽度,边界)\n" +msgid " -T, --table-attr=TEXT set HTML table tag attributes (e.g., width, border)\n" +msgstr " -T, --table-attr=文本 设定 HTML 表格标记属性(例如,宽度,边界)\n" # help.c:117 -#: help.c:121 +#: help.c:122 #, c-format msgid " -x, --expanded turn on expanded table output\n" msgstr " -x, --expanded 打开扩展表格输出\n" # help.c:119 -#: help.c:122 +#: help.c:123 #, c-format msgid "" " -z, --field-separator-zero\n" -" set field separator for unaligned output to zero " -"byte\n" +" set field separator for unaligned output to zero byte\n" msgstr "" " -z, --field-separator-zero\n" " ä¸ºä¸æ•´é½çš„输出设置字段分隔符为字节0\n" # help.c:121 -#: help.c:124 +#: help.c:125 #, c-format msgid "" " -0, --record-separator-zero\n" -" set record separator for unaligned output to zero " -"byte\n" +" set record separator for unaligned output to zero byte\n" msgstr "" " -0, --record-separator-zero\n" " ä¸ºä¸æ•´é½çš„输出设置记录分隔符为字节0\n" -#: help.c:127 +#: help.c:128 #, c-format msgid "" "\n" @@ -2489,50 +3013,44 @@ msgstr "" "è”æŽ¥é€‰é¡¹:\n" # help.c:126 -#: help.c:130 +#: help.c:131 #, c-format -msgid "" -" -h, --host=HOSTNAME database server host or socket directory " -"(default: \"%s\")\n" -msgstr "" -" -h, --host=ä¸»æœºå æ•°æ®åº“æœåŠ¡å™¨ä¸»æœºæˆ–socket目录(默认:\"%s\")\n" +msgid " -h, --host=HOSTNAME database server host or socket directory (default: \"%s\")\n" +msgstr " -h, --host=ä¸»æœºå æ•°æ®åº“æœåŠ¡å™¨ä¸»æœºæˆ–socket目录(默认:\"%s\")\n" # help.c:127 -#: help.c:131 +#: help.c:132 msgid "local socket" msgstr "本地接å£" # help.c:130 -#: help.c:134 +#: help.c:135 #, c-format msgid " -p, --port=PORT database server port (default: \"%s\")\n" -msgstr " -p, --port=ç«¯å£ æ•°æ®åº“æœåŠ¡å™¨çš„ç«¯å£(默认:\"%s\")\n" +msgstr " -p, --port=ç«¯å£ æ•°æ®åº“æœåŠ¡å™¨çš„ç«¯å£(默认:\"%s\")\n" # help.c:136 -#: help.c:140 +#: help.c:141 #, c-format msgid " -U, --username=USERNAME database user name (default: \"%s\")\n" msgstr " -U, --username=ç”¨æˆ·å æŒ‡å®šæ•°æ®åº“用户å(默认:\"%s\")\n" -#: help.c:141 +#: help.c:142 #, c-format msgid " -w, --no-password never prompt for password\n" -msgstr " -w, --no-password æ°¸è¿œä¸æç¤ºè¾“å…¥å£ä»¤\n" +msgstr " -w, --no-password æ°¸è¿œä¸æç¤ºè¾“å…¥å£ä»¤\n" -#: help.c:142 +#: help.c:143 #, c-format -msgid "" -" -W, --password force password prompt (should happen " -"automatically)\n" +msgid " -W, --password force password prompt (should happen automatically)\n" msgstr " -W, --password 强制å£ä»¤æç¤º (自动)\n" # help.c:140 -#: help.c:144 +#: help.c:145 #, c-format msgid "" "\n" -"For more information, type \"\\?\" (for internal commands) or \"\\help" -"\" (for SQL\n" +"For more information, type \"\\?\" (for internal commands) or \"\\help\" (for SQL\n" "commands) from within psql, or consult the psql section in the PostgreSQL\n" "documentation.\n" "\n" @@ -2542,543 +3060,575 @@ msgstr "" "或者å‚考PostgreSQL文档中的psql章节.\n" "\n" -#: help.c:147 -#, c-format -msgid "Report bugs to .\n" +#: help.c:148 +#, fuzzy, c-format +#| msgid "Report bugs to .\n" +msgid "Report bugs to .\n" msgstr "臭虫报告至 .\n" # help.c:174 -#: help.c:173 +#: help.c:174 #, c-format msgid "General\n" msgstr "一般性\n" # help.c:179 -#: help.c:174 -#, c-format -msgid "" -" \\copyright show PostgreSQL usage and distribution terms\n" -msgstr " \\copyright 显示PostgreSQL的使用和å‘è¡Œè®¸å¯æ¡æ¬¾\n" - #: help.c:175 #, c-format -msgid "" -" \\errverbose show most recent error message at maximum " -"verbosity\n" -msgstr " \\errverbose ä»¥æœ€å†—é•¿çš„å½¢å¼æ˜¾ç¤ºæœ€è¿‘的错误消æ¯\n" +msgid " \\copyright show PostgreSQL usage and distribution terms\n" +msgstr " \\copyright 显示PostgreSQL的使用和å‘è¡Œè®¸å¯æ¡æ¬¾\n" -# help.c:194 #: help.c:176 #, c-format -msgid "" -" \\g [FILE] or ; execute query (and send results to file or |pipe)\n" -msgstr " \\g [文件] or; 执行查询 (并把结果写入文件或 |管é“)\n" +msgid " \\crosstabview [COLUMNS] execute query and display results in crosstab\n" +msgstr " \\crosstabview [COLUMNS] 执行查询并且以交å‰è¡¨æ˜¾ç¤ºç»“æžœ\n" -# help.c:194 #: help.c:177 #, c-format -#| msgid "" -#| " \\gset [PREFIX] execute query and store results in psql " -#| "variables\n" -msgid "" -" \\gexec execute query, then execute each value in its " -"result\n" -msgstr " \\gexec æ‰§è¡Œç­–ç•¥ï¼Œç„¶åŽæ‰§è¡Œå…¶ç»“果中的æ¯ä¸ªå€¼\n" +msgid " \\errverbose show most recent error message at maximum verbosity\n" +msgstr " \\errverbose ä»¥æœ€å†—é•¿çš„å½¢å¼æ˜¾ç¤ºæœ€è¿‘的错误消æ¯\n" # help.c:194 #: help.c:178 #, c-format -msgid "" -" \\gset [PREFIX] execute query and store results in psql variables\n" -msgstr " \\gset [PREFIX] 执行查询并把结果存到psqlå˜é‡ä¸­\n" +msgid " \\g [FILE] or ; execute query (and send results to file or |pipe)\n" +msgstr " \\g [文件] or; 执行查询 (并把结果写入文件或 |管é“)\n" -# help.c:183 +# help.c:194 #: help.c:179 #, c-format -msgid " \\q quit psql\n" -msgstr " \\q 退出 psql\n" +msgid " \\gdesc describe result of query, without executing it\n" +msgstr " \\gdesc æè¿°æŸ¥è¯¢ç»“æžœï¼Œè€Œä¸æ‰§è¡Œå®ƒ\n" +# help.c:194 #: help.c:180 #, c-format -msgid "" -" \\crosstabview [COLUMNS] execute query and display results in crosstab\n" -msgstr " \\crosstabview [COLUMNS] 执行查询并且以交å‰è¡¨æ˜¾ç¤ºç»“æžœ\n" +msgid " \\gexec execute query, then execute each value in its result\n" +msgstr " \\gexec æ‰§è¡Œç­–ç•¥ï¼Œç„¶åŽæ‰§è¡Œå…¶ç»“果中的æ¯ä¸ªå€¼\n" +# help.c:194 #: help.c:181 #, c-format +msgid " \\gset [PREFIX] execute query and store results in psql variables\n" +msgstr " \\gset [PREFIX] 执行查询并把结果存到psqlå˜é‡ä¸­\n" + +# help.c:234 +#: help.c:182 +#, c-format +msgid " \\gx [FILE] as \\g, but forces expanded output mode\n" +msgstr " \\gx [FILE] å°±åƒ\\g,但强制扩展输出模å¼\n" + +# help.c:183 +#: help.c:183 +#, c-format +msgid " \\q quit psql\n" +msgstr " \\q 退出 psql\n" + +#: help.c:184 +#, c-format msgid " \\watch [SEC] execute query every SEC seconds\n" msgstr " \\watch [SEC] æ¯éš”SEC秒执行一次查询\n" -#: help.c:184 +#: help.c:187 #, c-format msgid "Help\n" msgstr "帮助\n" -#: help.c:186 +#: help.c:189 #, c-format -#| msgid "" -#| " \\? [commands] description of all psql backslash commands\n" msgid " \\? [commands] show help on backslash commands\n" msgstr " \\? [commands] æ˜¾ç¤ºåæ–œçº¿å‘½ä»¤çš„帮助\n" -#: help.c:187 +#: help.c:190 #, c-format -#| msgid "" -#| " \\? options description of all psql commandline options\n" msgid " \\? options show help on psql command-line options\n" msgstr " \\? options 显示 psql 命令行选项的帮助\n" -#: help.c:188 +#: help.c:191 #, c-format -#| msgid "" -#| " \\? variables description of all psql configuration " -#| "variables\n" msgid " \\? variables show help on special variables\n" msgstr " \\? variables 显示特殊å˜é‡çš„帮助\n" # help.c:182 -#: help.c:189 +#: help.c:192 #, c-format -msgid "" -" \\h [NAME] help on syntax of SQL commands, * for all " -"commands\n" +msgid " \\h [NAME] help on syntax of SQL commands, * for all commands\n" msgstr " \\h [åç§°] SQL命令语法上的说明,用*显示全部命令的语法说明\n" # help.c:192 -#: help.c:192 +#: help.c:195 #, c-format msgid "Query Buffer\n" msgstr "查询缓存区\n" # help.c:193 -#: help.c:193 +#: help.c:196 #, c-format -msgid "" -" \\e [FILE] [LINE] edit the query buffer (or file) with external " -"editor\n" +msgid " \\e [FILE] [LINE] edit the query buffer (or file) with external editor\n" msgstr " \\e [FILE] [LINE] 使用外部编辑器编辑查询缓存区(或文件)\n" # help.c:193 -#: help.c:194 +#: help.c:197 #, c-format -msgid "" -" \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" +msgid " \\ef [FUNCNAME [LINE]] edit function definition with external editor\n" msgstr " \\ef [FUNCNAME [LINE]] 使用外部编辑器编辑函数定义\n" # help.c:193 -#: help.c:195 +#: help.c:198 #, c-format msgid " \\ev [VIEWNAME [LINE]] edit view definition with external editor\n" msgstr " \\ev [VIEWNAME [LINE]] 用外部编辑器编辑视图定义\n" # help.c:195 -#: help.c:196 +#: help.c:199 #, c-format msgid " \\p show the contents of the query buffer\n" msgstr " \\p 显示查询缓存区的内容\n" # help.c:196 -#: help.c:197 +#: help.c:200 #, c-format msgid " \\r reset (clear) the query buffer\n" -msgstr " \\r é‡ç½®(清除)查询缓存区\n" +msgstr " \\r é‡ç½®(清除)查询缓存区\n" # help.c:198 -#: help.c:199 +#: help.c:202 #, c-format msgid " \\s [FILE] display history or save it to file\n" -msgstr " \\s [文件] 显示历å²è®°å½•或将历å²è®°å½•ä¿å­˜åœ¨æ–‡ä»¶ä¸­\n" +msgstr " \\s [文件] 显示历å²è®°å½•或将历å²è®°å½•ä¿å­˜åœ¨æ–‡ä»¶ä¸­\n" # help.c:200 -#: help.c:201 +#: help.c:204 #, c-format msgid " \\w FILE write query buffer to file\n" -msgstr " \\w 文件 将查询缓存区的内容写入文件\n" +msgstr " \\w 文件 将查询缓存区的内容写入文件\n" # help.c:203 -#: help.c:204 +#: help.c:207 #, c-format msgid "Input/Output\n" msgstr "输入/输出\n" # help.c:251 -#: help.c:205 +#: help.c:208 #, c-format -msgid "" -" \\copy ... perform SQL COPY with data stream to the client " -"host\n" -msgstr " \\copy ... 执行 SQL COPYï¼Œå°†æ•°æ®æµå‘é€åˆ°å®¢æˆ·ç«¯ä¸»æœº\n" +msgid " \\copy ... perform SQL COPY with data stream to the client host\n" +msgstr " \\copy ... 执行 SQL COPYï¼Œå°†æ•°æ®æµå‘é€åˆ°å®¢æˆ·ç«¯ä¸»æœº\n" # help.c:204 -#: help.c:206 +#: help.c:209 #, c-format msgid " \\echo [STRING] write string to standard output\n" -msgstr " \\echo [字符串] 将字符串写到标准输出\n" +msgstr " \\echo [字符串] 将字符串写到标准输出\n" # help.c:205 -#: help.c:207 +#: help.c:210 #, c-format msgid " \\i FILE execute commands from file\n" -msgstr " \\i 文件 从文件中执行命令\n" +msgstr " \\i 文件 从文件中执行命令\n" # help.c:206 -#: help.c:208 +#: help.c:211 #, c-format -msgid "" -" \\ir FILE as \\i, but relative to location of current " -"script\n" +msgid " \\ir FILE as \\i, but relative to location of current script\n" msgstr " \\ir FILE 与 \\i类似, 但是相对于当å‰è„šæœ¬çš„ä½ç½®\n" # help.c:206 -#: help.c:209 +#: help.c:212 #, c-format msgid " \\o [FILE] send all query results to file or |pipe\n" -msgstr " \\o [文件] 将全部查询结果写入文件或 |管é“\n" +msgstr " \\o [文件] 将全部查询结果写入文件或 |管é“\n" # help.c:207 -#: help.c:210 +#: help.c:213 #, c-format -msgid "" -" \\qecho [STRING] write string to query output stream (see \\o)\n" -msgstr " \\qecho [字符串] 将字符串写到查询输出串æµ(å‚考 \\o)\n" +msgid " \\qecho [STRING] write string to query output stream (see \\o)\n" +msgstr " \\qecho [字符串] 将字符串写到查询输出串æµ(å‚考 \\o)\n" + +# help.c:123 +#: help.c:216 +#, c-format +msgid "Conditional\n" +msgstr "æ¡ä»¶\n" + +#: help.c:217 +#, c-format +msgid " \\if EXPR begin conditional block\n" +msgstr " \\if EXPR 开始æ¡ä»¶å—\n" + +#: help.c:218 +#, c-format +msgid " \\elif EXPR alternative within current conditional block\n" +msgstr " \\elif EXPR 当剿¡ä»¶å—内的备选方案\n" + +# help.c:206 +#: help.c:219 +#, c-format +msgid " \\else final alternative within current conditional block\n" +msgstr " \\else 当剿¡ä»¶å—内的最终备选方案\n" + +#: help.c:220 +#, c-format +msgid " \\endif end conditional block\n" +msgstr " \\endif æ¡ä»¶å—的结尾\n" # help.c:211 -#: help.c:213 +#: help.c:223 #, c-format msgid "Informational\n" msgstr "资讯性\n" -#: help.c:214 +#: help.c:224 #, c-format msgid " (options: S = show system objects, + = additional detail)\n" msgstr " (选项: S = 显示系统对象, + = 其余的详细信æ¯)\n" # help.c:226 -#: help.c:215 +#: help.c:225 #, c-format msgid " \\d[S+] list tables, views, and sequences\n" -msgstr " \\d[S+] 列出表,视图和åºåˆ—\n" +msgstr " \\d[S+] 列出表,视图和åºåˆ—\n" # help.c:212 -#: help.c:216 +#: help.c:226 #, c-format msgid " \\d[S+] NAME describe table, view, sequence, or index\n" -msgstr " \\d[S+] åç§° æè¿°è¡¨ï¼Œè§†å›¾ï¼Œåºåˆ—,或索引\n" +msgstr " \\d[S+] åç§° æè¿°è¡¨ï¼Œè§†å›¾ï¼Œåºåˆ—,或索引\n" # help.c:215 -#: help.c:217 +#: help.c:227 #, c-format msgid " \\da[S] [PATTERN] list aggregates\n" -msgstr " \\da[S] [模å¼] 列出èšåˆå‡½æ•°\n" +msgstr " \\da[S] [模å¼] 列出èšåˆå‡½æ•°\n" + +# help.c:218 +#: help.c:228 +#, c-format +msgid " \\dA[+] [PATTERN] list access methods\n" +msgstr " \\dA[+] [模å¼] 列出访问方法\n" # help.c:228 -#: help.c:218 +#: help.c:229 #, c-format msgid " \\db[+] [PATTERN] list tablespaces\n" -msgstr " \\db[+] [模å¼] 列出表空间\n" +msgstr " \\db[+] [模å¼] 列出表空间\n" # help.c:217 -#: help.c:219 +#: help.c:230 #, c-format msgid " \\dc[S+] [PATTERN] list conversions\n" -msgstr " \\dc[S+] [PATTERN] 列表转æ¢\n" +msgstr " \\dc[S+] [模å¼] 列表转æ¢\n" # help.c:218 -#: help.c:220 +#: help.c:231 #, c-format msgid " \\dC[+] [PATTERN] list casts\n" -msgstr " \\dC[+] [PATTERN] 列出类型强制转æ¢\n" +msgstr " \\dC[+] [模å¼] 列出类型强制转æ¢\n" # help.c:219 -#: help.c:221 +#: help.c:232 #, c-format -msgid "" -" \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" -msgstr " \\dd[S] [PATTERN] 显示没有在别处显示的对象æè¿°\n" +msgid " \\dd[S] [PATTERN] show object descriptions not displayed elsewhere\n" +msgstr " \\dd[S] [模å¼] 显示没有在别处显示的对象æè¿°\n" + +# help.c:220 +#: help.c:233 +#, c-format +msgid " \\dD[S+] [PATTERN] list domains\n" +msgstr " \\dD[S+] [模å¼] 列出共åŒå€¼åŸŸ\n" # help.c:218 -#: help.c:222 +#: help.c:234 #, c-format msgid " \\ddp [PATTERN] list default privileges\n" -msgstr " \\ddp [模å¼] 列出默认æƒé™\n" +msgstr " \\ddp [模å¼] 列出默认æƒé™\n" -# help.c:220 -#: help.c:223 +# help.c:228 +#: help.c:235 #, c-format -msgid " \\dD[S+] [PATTERN] list domains\n" -msgstr " \\dD[S+] [PATTERN] 列出共åŒå€¼åŸŸ\n" +msgid " \\dE[S+] [PATTERN] list foreign tables\n" +msgstr " \\dE[S+] [模å¼] 列出引用表\n" # help.c:228 -#: help.c:224 +#: help.c:236 #, c-format msgid " \\det[+] [PATTERN] list foreign tables\n" -msgstr " \\det[+] [PATTERN] 列出引用表\n" +msgstr " \\det[+] [模å¼] 列出引用表\n" # help.c:228 -#: help.c:225 +#: help.c:237 #, c-format msgid " \\des[+] [PATTERN] list foreign servers\n" -msgstr " \\des[+] [模å¼] 列出外部æœåС噍\n" +msgstr " \\des[+] [模å¼] 列出外部æœåС噍\n" # help.c:228 -#: help.c:226 +#: help.c:238 #, c-format msgid " \\deu[+] [PATTERN] list user mappings\n" -msgstr " \\deu[+] [模å¼] 列出用户映射\n" +msgstr " \\deu[+] [模å¼] 列出用户映射\n" # help.c:222 -#: help.c:227 +#: help.c:239 #, c-format msgid " \\dew[+] [PATTERN] list foreign-data wrappers\n" -msgstr " \\dew[+] [模å¼] 列出外部数æ®å°è£…器\n" +msgstr " \\dew[+] [模å¼] 列出外部数æ®å°è£…器\n" # help.c:215 -#: help.c:228 +#: help.c:240 #, c-format -msgid "" -" \\df[antw][S+] [PATRN] list [only agg/normal/trigger/window] functions\n" -msgstr " \\df[antw][S+] [模å¼] 列出[åªåŒ…括 èšåˆ/常规/触å‘器/窗å£]函数 \n" +msgid " \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/trigger/window] functions\n" +msgstr " \\df[anptw][S+] [PATRN] 列出[åªåŒ…括 èšåˆ/常规/程åº/触å‘器/窗å£]函数 \n" # help.c:221 -#: help.c:229 +#: help.c:241 #, c-format msgid " \\dF[+] [PATTERN] list text search configurations\n" -msgstr " \\dF[+] [模å¼] 列出文本æœç´¢é…ç½®\n" +msgstr " \\dF[+] [模å¼] 列出文本æœç´¢é…ç½®\n" # help.c:228 -#: help.c:230 +#: help.c:242 #, c-format msgid " \\dFd[+] [PATTERN] list text search dictionaries\n" -msgstr " \\dFd[+] [模å¼] 列出文本æœç´¢å­—å…¸\n" +msgstr " \\dFd[+] [模å¼] 列出文本æœç´¢å­—å…¸\n" # help.c:228 -#: help.c:231 +#: help.c:243 #, c-format msgid " \\dFp[+] [PATTERN] list text search parsers\n" -msgstr " \\dFp[+] [模å¼] 列出文本æœç´¢è§£æžå™¨\n" +msgstr " \\dFp[+] [模å¼] 列出文本æœç´¢è§£æžå™¨\n" # help.c:228 -#: help.c:232 +#: help.c:244 #, c-format msgid " \\dFt[+] [PATTERN] list text search templates\n" -msgstr " \\dFt[+] [模å¼] 列出文本æœç´¢æ¨¡ç‰ˆ\n" +msgstr " \\dFt[+] [模å¼] 列出文本æœç´¢æ¨¡ç‰ˆ\n" # help.c:222 -#: help.c:233 +#: help.c:245 #, c-format -#| msgid " \\dg[+] [PATTERN] list roles\n" msgid " \\dg[S+] [PATTERN] list roles\n" -msgstr " \\dg[S+] [PATTERN] 列出角色\n" +msgstr " \\dg[S+] [模å¼] 列出角色\n" # help.c:220 -#: help.c:234 +#: help.c:246 #, c-format msgid " \\di[S+] [PATTERN] list indexes\n" -msgstr " \\di[S+] [模å¼] 列出索引\n" +msgstr " \\di[S+] [模å¼] 列出索引\n" # help.c:225 -#: help.c:235 +#: help.c:247 #, c-format msgid " \\dl list large objects, same as \\lo_list\n" -msgstr " \\dl 列出大对象, 功能与\\lo_list相åŒ\n" +msgstr " \\dl 列出大对象, 功能与\\lo_list相åŒ\n" # help.c:228 -#: help.c:236 +#: help.c:248 #, c-format msgid " \\dL[S+] [PATTERN] list procedural languages\n" -msgstr " \\dL[S+] [PATTERN] 列出所有过程语言\n" +msgstr " \\dL[S+] [模å¼] 列出所有过程语言\n" # help.c:228 -#: help.c:237 +#: help.c:249 #, c-format msgid " \\dm[S+] [PATTERN] list materialized views\n" -msgstr " \\dm[S+] [PATTERN] 列出所有物化视图\n" +msgstr " \\dm[S+] [模å¼] 列出所有物化视图\n" # help.c:228 -#: help.c:238 +#: help.c:250 #, c-format msgid " \\dn[S+] [PATTERN] list schemas\n" -msgstr " \\dn[S+] [PATTERN] 列出所有模å¼\n" +msgstr " \\dn[S+] [模å¼] 列出所有模å¼\n" # help.c:224 -#: help.c:239 +#: help.c:251 #, c-format msgid " \\do[S] [PATTERN] list operators\n" -msgstr " \\do[S] [模å¼] 列出è¿ç®—符\n" +msgstr " \\do[S] [模å¼] 列出è¿ç®—符\n" # help.c:220 -#: help.c:240 +#: help.c:252 #, c-format msgid " \\dO[S+] [PATTERN] list collations\n" -msgstr " \\dO[S+] [PATTERN] 列出所有校对规则\n" +msgstr " \\dO[S+] [模å¼] 列出所有校对规则\n" # help.c:226 -#: help.c:241 +#: help.c:253 #, c-format -msgid "" -" \\dp [PATTERN] list table, view, and sequence access privileges\n" -msgstr " \\dp [模å¼] 列出表,视图和åºåˆ—的访问æƒé™\n" +msgid " \\dp [PATTERN] list table, view, and sequence access privileges\n" +msgstr " \\dp [模å¼] 列出表,视图和åºåˆ—的访问æƒé™\n" -#: help.c:242 +# help.c:220 +#: help.c:254 +#, fuzzy, c-format +#| msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgid " \\dP[tin+] [PATTERN] list [only table/index] partitioned relations\n" +msgstr " \\dRp[+] [模å¼] 列出å¤åˆ¶å‡ºç‰ˆç‰©\n" + +#: help.c:255 #, c-format msgid " \\drds [PATRN1 [PATRN2]] list per-database role settings\n" -msgstr " \\drds [模å¼1 [模å¼2]] 列出æ¯ä¸ªæ•°æ®åº“的角色设置\n" +msgstr " \\drds [模å¼1 [模å¼2]] 列出æ¯ä¸ªæ•°æ®åº“的角色设置\n" + +# help.c:220 +#: help.c:256 +#, c-format +msgid " \\dRp[+] [PATTERN] list replication publications\n" +msgstr " \\dRp[+] [模å¼] 列出å¤åˆ¶å‡ºç‰ˆç‰©\n" + +# help.c:217 +#: help.c:257 +#, c-format +msgid " \\dRs[+] [PATTERN] list replication subscriptions\n" +msgstr " \\dRs[+] [模å¼] 列出å¤åˆ¶è®¢é˜…\n" # help.c:228 -#: help.c:243 +#: help.c:258 #, c-format msgid " \\ds[S+] [PATTERN] list sequences\n" -msgstr " \\ds[S+] [模å¼] 列出åºåˆ—\n" +msgstr " \\ds[S+] [模å¼] 列出åºåˆ—\n" # help.c:228 -#: help.c:244 +#: help.c:259 #, c-format msgid " \\dt[S+] [PATTERN] list tables\n" -msgstr " \\dt[S+] [模å¼] 列出表\n" +msgstr " \\dt[S+] [模å¼] 列出表\n" # help.c:220 -#: help.c:245 +#: help.c:260 #, c-format msgid " \\dT[S+] [PATTERN] list data types\n" -msgstr " \\dT[S+] [模å¼] 列出数æ®ç±»åž‹\n" +msgstr " \\dT[S+] [模å¼] 列出数æ®ç±»åž‹\n" # help.c:228 -#: help.c:246 +#: help.c:261 #, c-format -#| msgid " \\du[+] [PATTERN] list roles\n" msgid " \\du[S+] [PATTERN] list roles\n" -msgstr " \\du[S+] [PATTERN] 列出角色\n" +msgstr " \\du[S+] [模å¼] 列出角色\n" # help.c:228 -#: help.c:247 +#: help.c:262 #, c-format msgid " \\dv[S+] [PATTERN] list views\n" -msgstr " \\dv[S+] [模å¼] 列出视图\n" - -# help.c:228 -#: help.c:248 -#, c-format -msgid " \\dE[S+] [PATTERN] list foreign tables\n" -msgstr " \\dE[S+] [PATTERN] 列出引用表\n" +msgstr " \\dv[S+] [模å¼] 列出视图\n" # help.c:217 -#: help.c:249 +#: help.c:263 #, c-format msgid " \\dx[+] [PATTERN] list extensions\n" -msgstr " \\dx[+] [PATTERN] 列出扩展\n" +msgstr " \\dx[+] [模å¼] 列出扩展\n" # help.c:218 -#: help.c:250 +#: help.c:264 #, c-format msgid " \\dy [PATTERN] list event triggers\n" -msgstr " \\dy [PATTERN] 列出所有事件触å‘器\n" +msgstr " \\dy [模å¼] 列出所有事件触å‘器\n" # help.c:228 -#: help.c:251 +#: help.c:265 #, c-format msgid " \\l[+] [PATTERN] list databases\n" -msgstr " \\l[+] [PATTERN] 列出所有数æ®åº“\n" +msgstr " \\l[+] [模å¼] 列出所有数æ®åº“\n" # help.c:193 -#: help.c:252 +#: help.c:266 #, c-format -#| msgid " \\sf[+] FUNCNAME show a function's definition\n" msgid " \\sf[+] FUNCNAME show a function's definition\n" msgstr " \\sf[+] FUNCNAME 显示一个函数的定义\n" # help.c:193 -#: help.c:253 +#: help.c:267 #, c-format msgid " \\sv[+] VIEWNAME show a view's definition\n" msgstr " \\sv[+] VIEWNAME 显示一个视图的定义\n" # help.c:218 -#: help.c:254 +#: help.c:268 #, c-format msgid " \\z [PATTERN] same as \\dp\n" -msgstr " \\z [模å¼] å’Œ\\dp的功能相åŒ\n" +msgstr " \\z [模å¼] å’Œ\\dp的功能相åŒ\n" # help.c:233 -#: help.c:257 +#: help.c:271 #, c-format msgid "Formatting\n" msgstr "æ ¼å¼åŒ–\n" # help.c:234 -#: help.c:258 +#: help.c:272 #, c-format -msgid "" -" \\a toggle between unaligned and aligned output mode\n" -msgstr " \\a 在éžå¯¹é½æ¨¡å¼å’Œå¯¹é½æ¨¡å¼ä¹‹é—´åˆ‡æ¢\n" +msgid " \\a toggle between unaligned and aligned output mode\n" +msgstr " \\a 在éžå¯¹é½æ¨¡å¼å’Œå¯¹é½æ¨¡å¼ä¹‹é—´åˆ‡æ¢\n" # help.c:235 -#: help.c:259 +#: help.c:273 #, c-format msgid " \\C [STRING] set table title, or unset if none\n" -msgstr " \\C [字符串] è®¾ç½®è¡¨çš„æ ‡é¢˜ï¼Œæˆ–å¦‚æžœæ²¡æœ‰çš„æ ‡é¢˜å°±å–æ¶ˆ\n" +msgstr " \\C [字符串] è®¾ç½®è¡¨çš„æ ‡é¢˜ï¼Œæˆ–å¦‚æžœæ²¡æœ‰çš„æ ‡é¢˜å°±å–æ¶ˆ\n" # help.c:236 -#: help.c:260 +#: help.c:274 #, c-format -msgid "" -" \\f [STRING] show or set field separator for unaligned query " -"output\n" -msgstr " \\f [字符串] 显示或设定éžå¯¹é½æ¨¡å¼æŸ¥è¯¢è¾“出的字段分隔符\n" +msgid " \\f [STRING] show or set field separator for unaligned query output\n" +msgstr " \\f [字符串] 显示或设定éžå¯¹é½æ¨¡å¼æŸ¥è¯¢è¾“出的字段分隔符\n" # help.c:237 -#: help.c:261 +#: help.c:275 #, c-format msgid " \\H toggle HTML output mode (currently %s)\n" -msgstr " \\H 切æ¢HTMLè¾“å‡ºæ¨¡å¼ (ç›®å‰æ˜¯ %s)\n" +msgstr " \\H 切æ¢HTMLè¾“å‡ºæ¨¡å¼ (ç›®å‰æ˜¯ %s)\n" # help.c:239 -#: help.c:263 -#, c-format +#: help.c:277 +#, fuzzy, c-format +#| msgid "" +#| " \\pset [NAME [VALUE]] set table output option\n" +#| " (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +#| " footer|format|linestyle|null|numericlocale|pager|\n" +#| " pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +#| " tuples_only|unicode_border_linestyle|\n" +#| " unicode_column_linestyle|unicode_header_linestyle})\n" msgid "" " \\pset [NAME [VALUE]] set table output option\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|" -"unicode_header_linestyle})\n" +" (border|columns|csv_fieldsep|expanded|fieldsep|\n" +" fieldsep_zero|footer|format|linestyle|null|\n" +" numericlocale|pager|pager_min_lines|recordsep|\n" +" recordsep_zero|tableattr|title|tuples_only|\n" +" unicode_border_linestyle|unicode_column_linestyle|\n" +" unicode_header_linestyle)\n" msgstr "" " \\pset [NAME [VALUE]] 设置表输出选项\n" -" (NAME := {format|border|expanded|fieldsep|" -"fieldsep_zero|footer|null|\n" -" numericlocale|recordsep|recordsep_zero|tuples_only|" -"title|tableattr|pager|\n" -" unicode_border_linestyle|unicode_column_linestyle|" -"unicode_header_linestyle})\n" +" (NAME := {border|columns|expanded|fieldsep|fieldsep_zero|\n" +" footer|format|linestyle|null|numericlocale|pager|\n" +" pager_min_lines|recordsep|recordsep_zero|tableattr|title|\n" +" tuples_only|unicode_border_linestyle|\n" +" unicode_column_linestyle|unicode_header_linestyle})\n" # help.c:243 -#: help.c:267 +#: help.c:284 #, c-format msgid " \\t [on|off] show only rows (currently %s)\n" -msgstr " \\t [å¼€|å…³] åªæ˜¾ç¤ºè®°å½• (ç›®å‰æ˜¯ %s)\n" +msgstr " \\t [å¼€|å…³] åªæ˜¾ç¤ºè®°å½• (ç›®å‰æ˜¯ %s)\n" # help.c:245 -#: help.c:269 +#: help.c:286 #, c-format -msgid "" -" \\T [STRING] set HTML
tag attributes, or unset if none\n" -msgstr "" -" \\T [字符串] 设置HTML <表格>标签属性, 或者如果没有的è¯å–消设置\n" +msgid " \\T [STRING] set HTML
tag attributes, or unset if none\n" +msgstr " \\T [字符串] 设置HTML <表格>标签属性, 或者如果没有的è¯å–消设置\n" # help.c:246 -#: help.c:270 +#: help.c:287 #, c-format msgid " \\x [on|off|auto] toggle expanded output (currently %s)\n" msgstr " \\x [on|off|auto] åˆ‡æ¢æ‰©å±•输出模å¼(ç›®å‰æ˜¯ %s)\n" # help.c:123 -#: help.c:274 +#: help.c:291 #, c-format msgid "Connection\n" msgstr "连接\n" # help.c:175 -#: help.c:276 +#: help.c:293 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -3088,7 +3638,7 @@ msgstr "" " 连接到新数æ®åº“ï¼ˆå½“å‰æ˜¯\"%s\")\n" # help.c:175 -#: help.c:280 +#: help.c:297 #, c-format msgid "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" @@ -3097,87 +3647,82 @@ msgstr "" " \\c[onnect] {[DBNAME|- USER|- HOST|- PORT|-] | conninfo}\n" " 连接到新数æ®åº“ï¼ˆå½“å‰æ— è¿žæŽ¥ï¼‰\n" +#: help.c:299 +#, c-format +msgid " \\conninfo display information about current connection\n" +msgstr " \\conninfo 显示当å‰è¿žæŽ¥çš„相关信æ¯\n" + # help.c:180 -#: help.c:282 +#: help.c:300 #, c-format msgid " \\encoding [ENCODING] show or set client encoding\n" -msgstr " \\encoding [ç¼–ç åç§°] 显示或设定客户端编ç \n" +msgstr " \\encoding [ç¼–ç åç§°] 显示或设定客户端编ç \n" -#: help.c:283 +#: help.c:301 #, c-format msgid " \\password [USERNAME] securely change the password for a user\n" -msgstr " \\password [USERNAME] 安全地为用户更改å£ä»¤\n" +msgstr " \\password [USERNAME] 安全地为用户更改å£ä»¤\n" -#: help.c:284 -#, c-format -msgid "" -" \\conninfo display information about current connection\n" -msgstr " \\conninfo 显示当å‰è¿žæŽ¥çš„相关信æ¯\n" - -#: help.c:287 +#: help.c:304 #, c-format msgid "Operating System\n" msgstr "æ“作系统\n" # help.c:178 -#: help.c:288 +#: help.c:305 #, c-format msgid " \\cd [DIR] change the current working directory\n" -msgstr " \\cd [目录] 更改目å‰çš„工作目录\n" +msgstr " \\cd [目录] 更改目å‰çš„工作目录\n" # help.c:188 -#: help.c:289 +#: help.c:306 #, c-format msgid " \\setenv NAME [VALUE] set or unset environment variable\n" msgstr " \\setenv NAME [VALUE] 设置或清空环境å˜é‡\n" # help.c:186 -#: help.c:290 +#: help.c:307 #, c-format msgid " \\timing [on|off] toggle timing of commands (currently %s)\n" -msgstr " \\timing [å¼€|å…³] 切æ¢å‘½ä»¤è®¡æ—¶å¼€å…³ (ç›®å‰æ˜¯ %s)\n" +msgstr " \\timing [å¼€|å…³] 切æ¢å‘½ä»¤è®¡æ—¶å¼€å…³ (ç›®å‰æ˜¯ %s)\n" # help.c:189 -#: help.c:292 +#: help.c:309 #, c-format -msgid "" -" \\! [COMMAND] execute command in shell or start interactive " -"shell\n" -msgstr " \\! [命令] 在 shell中执行命令或å¯åŠ¨ä¸€ä¸ªäº¤äº’å¼shell\n" +msgid " \\! [COMMAND] execute command in shell or start interactive shell\n" +msgstr " \\! [命令] 在 shell中执行命令或å¯åŠ¨ä¸€ä¸ªäº¤äº’å¼shell\n" -#: help.c:295 +#: help.c:312 #, c-format msgid "Variables\n" msgstr "å˜é‡\n" # help.c:188 -#: help.c:296 +#: help.c:313 #, c-format msgid " \\prompt [TEXT] NAME prompt user to set internal variable\n" -msgstr " \\prompt [文本] åç§° æç¤ºç”¨æˆ·è®¾å®šå†…部å˜é‡\n" +msgstr " \\prompt [文本] åç§° æç¤ºç”¨æˆ·è®¾å®šå†…部å˜é‡\n" # help.c:184 -#: help.c:297 +#: help.c:314 #, c-format -msgid "" -" \\set [NAME [VALUE]] set internal variable, or list all if no " -"parameters\n" -msgstr " \\set [åç§° [值数]] 设定内部å˜é‡ï¼Œè‹¥æ— å‚数则列出全部å˜é‡\n" +msgid " \\set [NAME [VALUE]] set internal variable, or list all if no parameters\n" +msgstr " \\set [åç§° [值数]] 设定内部å˜é‡ï¼Œè‹¥æ— å‚数则列出全部å˜é‡\n" # help.c:188 -#: help.c:298 +#: help.c:315 #, c-format msgid " \\unset NAME unset (delete) internal variable\n" -msgstr " \\unset åç§° 清空(删除)内部å˜é‡\n" +msgstr " \\unset åç§° 清空(删除)内部å˜é‡\n" # large_obj.c:264 -#: help.c:301 +#: help.c:318 #, c-format msgid "Large Objects\n" msgstr "大对象\n" # help.c:252 -#: help.c:302 +#: help.c:319 #, c-format msgid "" " \\lo_export LOBOID FILE\n" @@ -3188,11 +3733,10 @@ msgstr "" " \\lo_export LOBOID 文件\n" " \\lo_import 文件 [注释]\n" " \\lo_list\n" -" \\lo_unlink LOBOID 大对象è¿ç®—\n" +" \\lo_unlink LOBOID 大对象è¿ç®—\n" -#: help.c:329 +#: help.c:346 #, c-format -#| msgid "List of specially treated variables.\n" msgid "" "List of specially treated variables\n" "\n" @@ -3200,17 +3744,13 @@ msgstr "" "特殊对待的å˜é‡çš„列表\n" "\n" -#: help.c:331 +#: help.c:348 #, c-format msgid "psql variables:\n" msgstr "psqlå˜é‡ï¼š\n" -#: help.c:333 +#: help.c:350 #, c-format -#| msgid "" -#| " psql --set=NAME=VALUE\n" -#| " or \\set NAME VALUE in interactive mode\n" -#| "\n" msgid "" " psql --set=NAME=VALUE\n" " or \\set NAME VALUE inside psql\n" @@ -3220,208 +3760,318 @@ msgstr "" " 或者在 psql 中的 \\set NAME VALUE\n" "\n" -#: help.c:335 +#: help.c:352 #, c-format msgid "" -" AUTOCOMMIT if set, successful SQL commands are automatically " -"committed\n" -msgstr " AUTOCOMMIT 如果被设置,æˆåŠŸçš„SQL命令将会被自动æäº¤\n" +" AUTOCOMMIT\n" +" if set, successful SQL commands are automatically committed\n" +msgstr "" +" AUTOCOMMIT\n" +" 如果被设置,æˆåŠŸçš„SQL命令将会被自动æäº¤\n" -#: help.c:336 +#: help.c:354 #, c-format -#| msgid "" -#| " COMP_KEYWORD_CASE determine the case used to complete SQL keywords\n" -#| " [lower, upper, preserve-lower, preserve-upper]\n" msgid "" -" COMP_KEYWORD_CASE determines the case used to complete SQL key words\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" determines the case used to complete SQL key words\n" +" [lower, upper, preserve-lower, preserve-upper]\n" msgstr "" -" COMP_KEYWORD_CASE å†³å®šç”¨äºŽå®Œæˆ SQL 关键è¯çš„大å°å†™\n" -" [lower, upper, preserve-lower, preserve-upper]\n" +" COMP_KEYWORD_CASE\n" +" å†³å®šç”¨äºŽå®Œæˆ SQL 关键è¯çš„大å°å†™\n" +" [lower, upper, preserve-lower, preserve-upper]\n" # common.c:636 # common.c:871 -#: help.c:338 +#: help.c:357 #, c-format -msgid " DBNAME the currently connected database name\n" -msgstr " DBNAME 当å‰å·²è¿žæŽ¥çš„æ•°æ®åº“å\n" +msgid "" +" DBNAME\n" +" the currently connected database name\n" +msgstr "" +" DBNAME\n" +" 当å‰å·²è¿žæŽ¥çš„æ•°æ®åº“å\n" -#: help.c:339 +#: help.c:359 #, c-format -#| msgid "" -#| " ECHO control what input is written to standard output\n" -#| " [all, errors, none, queries]\n" msgid "" -" ECHO controls what input is written to standard output\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" controls what input is written to standard output\n" +" [all, errors, none, queries]\n" msgstr "" -" ECHO 控制哪些输入被写入到标准输出\n" -" [all, errors, none, queries]\n" +" ECHO\n" +" 控制哪些输入被写入到标准输出\n" +" [all, errors, none, queries]\n" -#: help.c:341 +#: help.c:362 #, c-format -#| msgid "" -#| " ECHO_HIDDEN display internal queries executed by backslash " -#| "commands when it is set\n" -#| " or with [noexec] just show without execution\n" msgid "" -" ECHO_HIDDEN if set, display internal queries executed by backslash " -"commands;\n" -" if set to \"noexec\", just show without execution\n" +" ECHO_HIDDEN\n" +" if set, display internal queries executed by backslash commands;\n" +" if set to \"noexec\", just show them without execution\n" msgstr "" -" ECHO_HIDDEN å¦‚æžœè¢«è®¾ç½®ï¼Œæ˜¾ç¤ºåæ–œçº¿å‘½ä»¤æ‰§è¡Œçš„内部命令;\n" -" 如果被设置为 \"noexec\"ï¼Œåªæ˜¾ç¤ºä½†ä¸æ‰§è¡Œ\n" +" ECHO_HIDDEN\n" +" å¦‚æžœè¢«è®¾ç½®ï¼Œæ˜¾ç¤ºåæ–œçº¿å‘½ä»¤æ‰§è¡Œçš„内部命令;\n" +" 如果被设置为 \"noexec\"ï¼Œåªæ˜¾ç¤ºä½†ä¸æ‰§è¡Œ\n" # help.c:180 -#: help.c:343 +#: help.c:365 #, c-format -msgid " ENCODING current client character set encoding\n" -msgstr " ENCODING 当å‰çš„客户端字符集编ç \n" +msgid "" +" ENCODING\n" +" current client character set encoding\n" +msgstr "" +" ENCODING\n" +" 当å‰çš„客户端字符集编ç \n" -#: help.c:344 +#: help.c:367 #, c-format msgid "" -" FETCH_COUNT the number of result rows to fetch and display at a " -"time\n" -" (default: 0=unlimited)\n" +" ERROR\n" +" true if last query failed, else false\n" msgstr "" -" FETCH_COUNT 一次å–得并显示的结果行的数é‡\n" -" (默认:0=æ— é™)\n" +" 错误\n" +" 如果上次查询失败,则为true,å¦åˆ™ä¸ºfalse\n" -#: help.c:346 +#: help.c:369 #, c-format -#| msgid "" -#| " HISTCONTROL control history list [ignorespace, ignoredups, " -#| "ignoreboth]\n" msgid "" -" HISTCONTROL controls command history [ignorespace, ignoredups, " -"ignoreboth]\n" +" FETCH_COUNT\n" +" the number of result rows to fetch and display at a time (0 = unlimited)\n" msgstr "" -" HISTCONTROL æŽ§åˆ¶å‘½ä»¤åŽ†å² [ignorespace, ignoredups, ignoreboth]\n" +" FETCH_COUNT\n" +" 一次å–å¾—å¹¶æ˜¾ç¤ºçš„ç»“æžœè¡Œçš„æ•°é‡ (0=æ— é™)\n" -#: help.c:347 +#: help.c:371 #, c-format -#| msgid " HISTFILE file name used to store the history list\n" -msgid " HISTFILE file name used to store the command history\n" -msgstr " HISTFILE 用æ¥å­˜å‚¨å‘½ä»¤åކå²çš„æ–‡ä»¶å\n" +msgid "" +" HIDE_TABLEAM\n" +" if set, table access methods are not displayed\n" +msgstr "" -#: help.c:348 +#: help.c:373 #, c-format msgid "" -" HISTSIZE the number of commands to store in the command history\n" -msgstr " HISTSIZE ä¿å­˜åœ¨å‘½ä»¤åކå²ä¸­çš„命令数é‡\n" +" HISTCONTROL\n" +" controls command history [ignorespace, ignoredups, ignoreboth]\n" +msgstr "" +" HISTCONTROL\n" +" æŽ§åˆ¶å‘½ä»¤åŽ†å² [ignorespace, ignoredups, ignoreboth]\n" + +#: help.c:375 +#, c-format +msgid "" +" HISTFILE\n" +" file name used to store the command history\n" +msgstr "" +" HISTFILE\n" +" 用æ¥å­˜å‚¨å‘½ä»¤åކå²çš„æ–‡ä»¶å\n" + +#: help.c:377 +#, c-format +msgid "" +" HISTSIZE\n" +" maximum number of commands to store in the command history\n" +msgstr "" +" HISTSIZE\n" +" ä¿å­˜åœ¨å‘½ä»¤åކå²ä¸­çš„æœ€å¤§å‘½ä»¤æ•°\n" # help.c:178 -#: help.c:349 +#: help.c:379 #, c-format -#| msgid " HOST the currently connected database server\n" -msgid " HOST the currently connected database server host\n" -msgstr " HOST 当å‰è¿žæŽ¥çš„æ•°æ®åº“æœåŠ¡å™¨ä¸»æœº\n" +msgid "" +" HOST\n" +" the currently connected database server host\n" +msgstr "" +" HOST\n" +" 当å‰è¿žæŽ¥çš„æ•°æ®åº“æœåŠ¡å™¨ä¸»æœº\n" -#: help.c:350 +#: help.c:381 #, c-format msgid "" -" IGNOREEOF if unset, sending an EOF to interactive session " -"terminates application\n" -msgstr " IGNOREEOF å¦‚æžœå–æ¶ˆè®¾ç½®ï¼Œå‘é€ä¸€ä¸ªEOF给交互的会è¯å°†ä¸­æ–­åº”用\n" +" IGNOREEOF\n" +" number of EOFs needed to terminate an interactive session\n" +msgstr "" +" IGNOREEOF\n" +" 终止交互å¼ä¼šè¯æ‰€éœ€çš„EOFæ•°\n" -#: help.c:351 +#: help.c:383 #, c-format -#| msgid " LASTOID the value of last affected OID\n" -msgid " LASTOID value of the last affected OID\n" -msgstr " LASTOID 最åŽä¸€ä¸ªå—å½±å“çš„ OID 的值\n" +msgid "" +" LASTOID\n" +" value of the last affected OID\n" +msgstr "" +" LASTOID\n" +" 最åŽä¸€ä¸ªå—å½±å“çš„ OID 的值\n" -#: help.c:352 +#: help.c:385 #, c-format -#| msgid "" -#| " ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses " -#| "implicit SAVEPOINTs)\n" msgid "" -" ON_ERROR_ROLLBACK if set, an error doesn't stop a transaction (uses " -"implicit savepoints)\n" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" message and SQLSTATE of last error, or empty string and \"00000\" if none\n" msgstr "" -" ON_ERROR_ROLLBACK 如果被设置,则错误ä¸ä¼šåœæ­¢ä¸€ä¸ªäº‹åŠ¡ï¼ˆä½¿ç”¨éšå¼ä¿å­˜ç‚¹ï¼‰\n" +" LAST_ERROR_MESSAGE\n" +" LAST_ERROR_SQLSTATE\n" +" 最åŽä¸€ä¸ªé”™è¯¯çš„æ¶ˆæ¯å’ŒSQL状æ€ï¼Œå¦‚果没有,则为空字符串和\"00000\"\n" -#: help.c:353 +#: help.c:388 #, c-format -msgid " ON_ERROR_STOP stop batch execution after error\n" -msgstr " ON_ERROR_STOP å‘生错误åŽåœæ­¢æ‰¹é‡æ‰§è¡Œ\n" +msgid "" +" ON_ERROR_ROLLBACK\n" +" if set, an error doesn't stop a transaction (uses implicit savepoints)\n" +msgstr "" +" ON_ERROR_ROLLBACK\n" +" 如果被设置,则错误ä¸ä¼šåœæ­¢ä¸€ä¸ªäº‹åŠ¡ï¼ˆä½¿ç”¨éšå¼ä¿å­˜ç‚¹ï¼‰\n" -#: help.c:354 +#: help.c:390 #, c-format -msgid " PORT server port of the current connection\n" -msgstr " PORT 当å‰è¿žæŽ¥çš„æœåŠ¡å™¨ç«¯å£\n" +msgid "" +" ON_ERROR_STOP\n" +" stop batch execution after error\n" +msgstr "" +" ON_ERROR_STOP\n" +" å‘生错误åŽåœæ­¢æ‰¹é‡æ‰§è¡Œ\n" -#: help.c:355 +#: help.c:392 #, c-format -#| msgid " PROMPT1 specify the standard psql prompt\n" -msgid " PROMPT1 specifies the standard psql prompt\n" -msgstr " PROMPT1 指定标准的 psql æç¤ºç¬¦\n" +msgid "" +" PORT\n" +" server port of the current connection\n" +msgstr "" +" PORT\n" +" 当å‰è¿žæŽ¥çš„æœåŠ¡å™¨ç«¯å£\n" -#: help.c:356 +#: help.c:394 #, c-format -#| msgid "" -#| " PROMPT2 specify the prompt used when a statement continues " -#| "from a previous line\n" msgid "" -" PROMPT2 specifies the prompt used when a statement continues " -"from a previous line\n" -msgstr " PROMPT2 指定在语å¥è·¨è¡Œæ—¶ä½¿ç”¨çš„æç¤ºç¬¦\n" +" PROMPT1\n" +" specifies the standard psql prompt\n" +msgstr "" +" PROMPT1\n" +" 指定标准的 psql æç¤ºç¬¦\n" -#: help.c:357 +#: help.c:396 +#, c-format +msgid "" +" PROMPT2\n" +" specifies the prompt used when a statement continues from a previous line\n" +msgstr "" +" PROMPT2\n" +" 指定在语å¥è·¨è¡Œæ—¶ä½¿ç”¨çš„æç¤ºç¬¦\n" + +#: help.c:398 #, c-format -#| msgid "" -#| " PROMPT3 specify the prompt used during COPY ... FROM STDIN\n" msgid "" -" PROMPT3 specifies the prompt used during COPY ... FROM STDIN\n" -msgstr " PROMPT3 指定 COPY ... FROM STDIN 期间使用的æç¤ºç¬¦\n" +" PROMPT3\n" +" specifies the prompt used during COPY ... FROM STDIN\n" +msgstr "" +" PROMPT3\n" +" 指定 COPY ... FROM STDIN 期间使用的æç¤ºç¬¦\n" # help.c:106 -#: help.c:358 +#: help.c:400 #, c-format -msgid " QUIET run quietly (same as -q option)\n" -msgstr " QUIET é™é»˜åœ°è¿è¡Œï¼ˆå’Œ-q选项相åŒï¼‰\n" +msgid "" +" QUIET\n" +" run quietly (same as -q option)\n" +msgstr "" +" QUIET\n" +" é™é»˜åœ°è¿è¡Œï¼ˆå’Œ-q选项相åŒï¼‰\n" -#: help.c:359 +#: help.c:402 #, c-format msgid "" -" SHOW_CONTEXT controls display of message context fields [never, " -"errors, always]\n" -msgstr " SHOW_CONTEXT 控制消æ¯ä¸Šä¸‹æ–‡åŸŸçš„æ˜¾ç¤º [never, errors, always]\n" +" ROW_COUNT\n" +" number of rows returned or affected by last query, or 0\n" +msgstr "" +" ROW_COUNT\n" +" 上一个查询返回或影å“的行数,或0\n" -#: help.c:360 +#: help.c:404 #, c-format msgid "" -" SINGLELINE end of line terminates SQL command mode (same as -S " -"option)\n" -msgstr " SINGLELINE 行尾会终止SQL命令模å¼ï¼ˆä¸Ž-S选项相åŒï¼‰\n" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" server's version (in short string or numeric format)\n" +msgstr "" +" SERVER_VERSION_NAME\n" +" SERVER_VERSION_NUM\n" +" æœåŠ¡å™¨ç‰ˆæœ¬ï¼ˆçŸ­å­—ç¬¦ä¸²æˆ–æ•°å­—æ ¼å¼ï¼‰\n" -#: help.c:361 +#: help.c:407 #, c-format -msgid " SINGLESTEP single-step mode (same as -s option)\n" -msgstr " SINGLESTEP 啿­¥æ¨¡å¼ï¼ˆä¸Ž-s选项相åŒï¼‰\n" +msgid "" +" SHOW_CONTEXT\n" +" controls display of message context fields [never, errors, always]\n" +msgstr "" +" SHOW_CONTEXT\n" +" 控制消æ¯ä¸Šä¸‹æ–‡åŸŸçš„æ˜¾ç¤º [never, errors, always]\n" -# help.c:178 -#: help.c:362 +#: help.c:409 +#, c-format +msgid "" +" SINGLELINE\n" +" if set, end of line terminates SQL commands (same as -S option)\n" +msgstr "" +" SINGLELINE\n" +" 设置的è¯ï¼Œè¡Œå°¾ä¼šç»ˆæ­¢SQL命令模å¼ï¼ˆä¸Ž-S选项相åŒï¼‰\n" + +#: help.c:411 +#, c-format +msgid "" +" SINGLESTEP\n" +" single-step mode (same as -s option)\n" +msgstr "" +" SINGLESTEP\n" +" 啿­¥æ¨¡å¼ï¼ˆä¸Ž-s选项相åŒï¼‰\n" + +#: help.c:413 #, c-format -msgid " USER the currently connected database user\n" -msgstr " USER 当å‰è¿žæŽ¥ä¸Šçš„æ•°æ®åº“用户\n" +msgid "" +" SQLSTATE\n" +" SQLSTATE of last query, or \"00000\" if no error\n" +msgstr "" +" SQLSTATE\n" +" 上次查询的SQL状æ€ï¼Œå¦‚果没有错误,则为\"00000\"\n" -#: help.c:363 +# help.c:178 +#: help.c:415 #, c-format +msgid "" +" USER\n" +" the currently connected database user\n" +msgstr "" +" USER\n" +" 当å‰è¿žæŽ¥ä¸Šçš„æ•°æ®åº“用户\n" + +#: help.c:417 +#, fuzzy, c-format #| msgid "" -#| " VERBOSITY control verbosity of error reports [default, " -#| "verbose, terse]\n" +#| " VERBOSITY\n" +#| " controls verbosity of error reports [default, verbose, terse]\n" +msgid "" +" VERBOSITY\n" +" controls verbosity of error reports [default, verbose, terse, sqlstate]\n" +msgstr "" +" VERBOSITY\n" +" 控制错误报告的冗长程度 [default, verbose, terse]\n" + +#: help.c:419 +#, c-format msgid "" -" VERBOSITY controls verbosity of error reports [default, verbose, " -"terse]\n" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql's version (in verbose string, short string, or numeric format)\n" msgstr "" -" VERBOSITY 控制错误报告的冗长程度 [default, verbose, terse]\n" +" VERSION\n" +" VERSION_NAME\n" +" VERSION_NUM\n" +" psql版本(详细字符串ã€çŸ­å­—符串或数字格å¼ï¼‰\n" # describe.c:1549 -#: help.c:365 +#: help.c:424 #, c-format -#| msgid "List of settings" msgid "" "\n" "Display settings:\n" @@ -3429,12 +4079,8 @@ msgstr "" "\n" "显示设置:\n" -#: help.c:367 +#: help.c:426 #, c-format -#| msgid "" -#| " psql --pset=NAME[=VALUE]\n" -#| " or \\pset NAME [VALUE] in interactive mode\n" -#| "\n" msgid "" " psql --pset=NAME[=VALUE]\n" " or \\pset NAME [VALUE] inside psql\n" @@ -3444,154 +4090,173 @@ msgstr "" " 或者 psql 中的 \\pset NAME [VALUE]\n" "\n" -#: help.c:369 +#: help.c:428 #, c-format -msgid " border border style (number)\n" -msgstr " border 边界样å¼ï¼ˆæ•°å­—)\n" +msgid "" +" border\n" +" border style (number)\n" +msgstr "" +" border\n" +" 边界样å¼ï¼ˆæ•°å­—)\n" -#: help.c:370 +#: help.c:430 #, c-format -#| msgid " columns set the target width for the wrapped format\n" -msgid " columns target width for the wrapped format\n" -msgstr " columns ç”¨äºŽå›žå·æ ¼å¼çš„目标宽度\n" +msgid "" +" columns\n" +" target width for the wrapped format\n" +msgstr "" +" columns\n" +" ç”¨äºŽå›žå·æ ¼å¼çš„目标宽度\n" # help.c:117 -#: help.c:371 +#: help.c:432 #, c-format -#| msgid " expanded (or x) toggle expanded output\n" -msgid " expanded (or x) expanded output [on, off, auto]\n" -msgstr " expanded (或者 x) 扩展输出 [on, off, auto]\n" +msgid "" +" expanded (or x)\n" +" expanded output [on, off, auto]\n" +msgstr "" +" expanded (or x)\n" +" 扩展输出 [on, off, auto]\n" # help.c:119 -#: help.c:372 +#: help.c:434 #, c-format -#| msgid "" -#| " fieldsep field separator for unaligned output (default '|')\n" msgid "" -" fieldsep field separator for unaligned output (default \"%s\")\n" -msgstr " fieldsep 用于éžå¯¹é½è¾“出的域分隔符(默认是 \"%s\")\n" +" fieldsep\n" +" field separator for unaligned output (default \"%s\")\n" +msgstr "" +" fieldsep\n" +" 用于éžå¯¹é½è¾“出的域分隔符(默认是 \"%s\")\n" # help.c:119 -#: help.c:373 +#: help.c:437 #, c-format -#| msgid " fieldsep_zero set field separator in unaligned mode to zero\n" msgid "" -" fieldsep_zero set field separator for unaligned output to zero byte\n" -msgstr " fieldsep_zero 将用于éžå¯¹é½æ¨¡å¼ä¸­çš„域分隔符设置为零字节\n" +" fieldsep_zero\n" +" set field separator for unaligned output to a zero byte\n" +msgstr "" +" fieldsep_zero\n" +" 将用于éžå¯¹é½æ¨¡å¼ä¸­çš„域分隔符设置为零字节\n" -# command.c:1340 -#: help.c:374 +#: help.c:439 #, c-format msgid "" -" format set output format [unaligned, aligned, wrapped, html, " -"asciidoc, ...]\n" +" footer\n" +" enable or disable display of the table footer [on, off]\n" msgstr "" -" format è®¾ç½®è¾“å‡ºæ ¼å¼ [unaligned, aligned, wrapped, html, " -"asciidoc, ...]\n" +" footer\n" +" å¯ç”¨æˆ–ç¦ç”¨è¡¨æ ¼é¡µè„šçš„æ˜¾ç¤º [on, off]\n" -#: help.c:375 +# command.c:1340 +#: help.c:441 #, c-format msgid "" -" footer enable or disable display of the table footer [on, " -"off]\n" -msgstr " footer å¯ç”¨æˆ–ç¦ç”¨è¡¨æ ¼é¡µè„šçš„æ˜¾ç¤º [on, off]\n" +" format\n" +" set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n" +msgstr "" +" format\n" +" è®¾ç½®è¾“å‡ºæ ¼å¼ [unaligned, aligned, wrapped, html, asciidoc, ...]\n" -#: help.c:376 +#: help.c:443 #, c-format msgid "" -" linestyle set the border line drawing style [ascii, old-ascii, " -"unicode]\n" -msgstr " linestyle 设置边界线绘制风格 [ascii, old-ascii, unicode]\n" +" linestyle\n" +" set the border line drawing style [ascii, old-ascii, unicode]\n" +msgstr "" +" linestyle\n" +" 设置边界线绘制风格 [ascii, old-ascii, unicode]\n" -#: help.c:377 +#: help.c:445 #, c-format msgid "" -" null set the string to be printed in place of a null value\n" -msgstr " null 设置代替空值被打å°çš„字符串\n" +" null\n" +" set the string to be printed in place of a null value\n" +msgstr "" +" null\n" +" 设置代替空值被打å°çš„字符串\n" -#: help.c:378 +#: help.c:447 #, c-format msgid "" -" numericlocale enable or disable display of a locale-specific " -"character to separate\n" -" groups of digits [on, off]\n" +" numericlocale\n" +" enable display of a locale-specific character to separate groups of digits\n" msgstr "" -" numericlocale å¯ç”¨æˆ–者ç¦ç”¨åˆ†é𔿕°å­—分组的区域相关字符的显示 [on, off]\n" +" numericlocale\n" +" å…许显示特定于区域设置的字符以分隔数字组\n" -#: help.c:380 +#: help.c:449 #, c-format msgid "" -" pager control when an external pager is used [yes, no, " -"always]\n" -msgstr " pager 控制何时使用一个外部分页器 [yes, no, always]\n" +" pager\n" +" control when an external pager is used [yes, no, always]\n" +msgstr "" +" pager\n" +" 控制何时使用一个外部分页器 [yes, no, always]\n" # help.c:121 -#: help.c:381 +#: help.c:451 #, c-format -#| msgid "" -#| " recordsep specify the record (line) separator to use in " -#| "unaligned output format\n" -msgid " recordsep record (line) separator for unaligned output\n" -msgstr " recordsep 用于éžå¯¹é½è¾“出中的记录(行)分隔符\n" +msgid "" +" recordsep\n" +" record (line) separator for unaligned output\n" +msgstr "" +" recordsep\n" +" 用于éžå¯¹é½è¾“出中的记录(行)分隔符\n" # help.c:121 -#: help.c:382 +#: help.c:453 #, c-format -#| msgid "" -#| " recordsep_zero set the record separator to use in unaligned output " -#| "format to a zero byte.\n" msgid "" -" recordsep_zero set record separator for unaligned output to zero byte\n" -msgstr " recordsep_zero 将用于éžå¯¹é½è¾“出中的记录分隔符设置为零字节\n" +" recordsep_zero\n" +" set record separator for unaligned output to a zero byte\n" +msgstr "" +" recordsep_zero\n" +" 将用于éžå¯¹é½è¾“出中的记录分隔符设置为零字节\n" -#: help.c:383 +#: help.c:455 #, c-format -#| msgid "" -#| " tableattr (or T) specify attributes for table tag in html format or " -#| "proportional\n" -#| " column width of left aligned data type in latex " -#| "format\n" msgid "" -" tableattr (or T) specify attributes for table tag in html format or " -"proportional\n" -" column widths for left-aligned data types in latex-" -"longtable format\n" +" tableattr (or T)\n" +" specify attributes for table tag in html format, or proportional\n" +" column widths for left-aligned data types in latex-longtable format\n" msgstr "" -" tableattr (或者 T) 指定 html æ ¼å¼ä¸­è¡¨æ ‡ç­¾çš„属性\n" -" 或者 latex-longtable æ ¼å¼ä¸­å·¦å¯¹é½æ•°æ®ç±»åž‹çš„æ¯”例列" -"宽\n" +" tableattr (或者 T)\n" +" 指定 html æ ¼å¼ä¸­è¡¨æ ‡ç­¾çš„属性\n" +" 或者 latex-longtable æ ¼å¼ä¸­å·¦å¯¹é½æ•°æ®ç±»åž‹çš„æ¯”例列宽\n" # help.c:235 -#: help.c:385 +#: help.c:458 #, c-format msgid "" -" title set the table title for any subsequently printed " -"tables\n" -msgstr " title 为任何åŽç»­è¢«æ‰“å°çš„表设置表标题\n" +" title\n" +" set the table title for subsequently printed tables\n" +msgstr "" +" title\n" +" 为任何åŽç»­è¢«æ‰“å°çš„表设置表标题\n" -#: help.c:386 +#: help.c:460 #, c-format -msgid " tuples_only if set, only actual table data is shown\n" -msgstr " tuples_only å¦‚æžœè¢«è®¾ç½®ï¼Œåªæœ‰çœŸå®žçš„表数æ®ä¼šè¢«æ˜¾ç¤º\n" +msgid "" +" tuples_only\n" +" if set, only actual table data is shown\n" +msgstr "" +" tuples_only\n" +" å¦‚æžœè¢«è®¾ç½®ï¼Œåªæœ‰çœŸå®žçš„表数æ®ä¼šè¢«æ˜¾ç¤º\n" -#: help.c:387 +#: help.c:462 #, c-format -#| msgid "" -#| " unicode_header_linestyle\n" -#| " set the style of unicode line drawing [single, " -#| "double]\n" msgid "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" set the style of Unicode line drawing [single, double]\n" +" set the style of Unicode line drawing [single, double]\n" msgstr "" " unicode_border_linestyle\n" " unicode_column_linestyle\n" " unicode_header_linestyle\n" -" 设置 Unicode 线绘制的风格 [single, double]\n" +" 设置 Unicode 线绘制的风格 [single, double]\n" -#: help.c:392 +#: help.c:467 #, c-format msgid "" "\n" @@ -3600,12 +4265,8 @@ msgstr "" "\n" "环境å˜é‡ï¼š\n" -#: help.c:396 +#: help.c:471 #, c-format -#| msgid "" -#| " NAME=VALUE [NAME=VALUE] psql ...\n" -#| " or \\setenv NAME [VALUE] in interactive mode\n" -#| "\n" msgid "" " NAME=VALUE [NAME=VALUE] psql ...\n" " or \\setenv NAME [VALUE] inside psql\n" @@ -3615,13 +4276,8 @@ msgstr "" " 或者 psql 中的 \\setenv NAME [VALUE]\n" "\n" -#: help.c:398 +#: help.c:473 #, c-format -#| msgid "" -#| " set NAME=VALUE\n" -#| " psql ...\n" -#| " or \\setenv NAME VALUE in interactive mode\n" -#| "\n" msgid "" " set NAME=VALUE\n" " psql ...\n" @@ -3633,110 +4289,165 @@ msgstr "" " 或者 psql 中的 \\setenv NAME [VALUE]\n" "\n" -#: help.c:401 +#: help.c:476 #, c-format -msgid " COLUMNS number of columns for wrapped format\n" -msgstr " COLUMNS å›žå·æ ¼å¼çš„列数\n" - -#: help.c:402 -#, c-format -msgid " PAGER name of external pager program\n" -msgstr " PAGER 外部分页程åºçš„åç§°\n" +msgid "" +" COLUMNS\n" +" number of columns for wrapped format\n" +msgstr "" +" COLUMNS\n" +" å›žå·æ ¼å¼çš„列数\n" -#: help.c:403 +#: help.c:478 #, c-format msgid "" -" PGAPPNAME same as the application_name connection parameter\n" -msgstr " PGAPPNAME å’Œapplication_nameè¿žæŽ¥å‚æ•°ç›¸åŒ\n" +" PGAPPNAME\n" +" same as the application_name connection parameter\n" +msgstr "" +" PGAPPNAME\n" +" å’Œapplication_nameè¿žæŽ¥å‚æ•°ç›¸åŒ\n" -#: help.c:404 +#: help.c:480 #, c-format -msgid " PGDATABASE same as the dbname connection parameter\n" -msgstr " PGDATABASE å’Œdbnameè¿žæŽ¥å‚æ•°ç›¸åŒ\n" +msgid "" +" PGDATABASE\n" +" same as the dbname connection parameter\n" +msgstr "" +" PGDATABASE\n" +" å’Œdbnameè¿žæŽ¥å‚æ•°ç›¸åŒ\n" -#: help.c:405 +#: help.c:482 #, c-format -msgid " PGHOST same as the host connection parameter\n" -msgstr " PGHOST ä¸Žä¸»æœºè¿žæŽ¥å‚æ•°ç›¸åŒ\n" +msgid "" +" PGHOST\n" +" same as the host connection parameter\n" +msgstr "" +" PGHOST\n" +" ä¸Žä¸»æœºè¿žæŽ¥å‚æ•°ç›¸åŒ\n" -#: help.c:406 +#: help.c:484 #, c-format -msgid " PGPORT same as the port connection parameter\n" -msgstr " PGPORT 与端å£è¿žæŽ¥å‚数相åŒ\n" +msgid "" +" PGPASSWORD\n" +" connection password (not recommended)\n" +msgstr "" +" PGPASSWORD\n" +" 连接å£ä»¤ï¼ˆä¸æŽ¨è)\n" -# help.c:136 -#: help.c:407 +#: help.c:486 #, c-format -msgid " PGUSER same as the user connection parameter\n" -msgstr " PGUSER ä¸Žç”¨æˆ·è¿žæŽ¥å‚æ•°ç›¸åŒ\n" +msgid "" +" PGPASSFILE\n" +" password file name\n" +msgstr "" +" PGPASSFILE\n" +" å£ä»¤æ–‡ä»¶å\n" -#: help.c:408 +#: help.c:488 #, c-format -msgid " PGPASSWORD connection password (not recommended)\n" -msgstr " PGPASSWORD 连接å£ä»¤ï¼ˆä¸æŽ¨è)\n" +msgid "" +" PGPORT\n" +" same as the port connection parameter\n" +msgstr "" +" PGPORT\n" +" 与端å£è¿žæŽ¥å‚数相åŒ\n" -#: help.c:409 +# help.c:136 +#: help.c:490 #, c-format -msgid " PGPASSFILE password file name\n" -msgstr " PGPASSFILE å£ä»¤æ–‡ä»¶å\n" +msgid "" +" PGUSER\n" +" same as the user connection parameter\n" +msgstr "" +" PGUSER\n" +" ä¸Žç”¨æˆ·è¿žæŽ¥å‚æ•°ç›¸åŒ\n" -#: help.c:410 +#: help.c:492 #, c-format -#| msgid "" -#| " PSQL_EDITOR, EDITOR, VISUAL\n" -#| " editor used by the \\e and \\ef commands\n" msgid "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" editor used by the \\e, \\ef, and \\ev commands\n" +" editor used by the \\e, \\ef, and \\ev commands\n" msgstr "" " PSQL_EDITOR, EDITOR, VISUAL\n" -" \\e, \\ef, å’Œ \\ev 命令使用的编辑器\n" +" \\e, \\ef, å’Œ \\ev 命令使用的编辑器\n" -#: help.c:412 +#: help.c:494 #, c-format msgid "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" how to specify a line number when invoking the editor\n" +" how to specify a line number when invoking the editor\n" msgstr "" " PSQL_EDITOR_LINENUMBER_ARG\n" -" 调用编辑器时如何指定一个行å·\n" +" 调用编辑器时如何指定一个行å·\n" -#: help.c:414 +#: help.c:496 #, c-format msgid "" -" PSQL_HISTORY alternative location for the command history file\n" -msgstr " PSQL_HISTORY å‘½ä»¤åŽ†å²æ–‡ä»¶çš„å¯é€‰ä½ç½®\n" +" PSQL_HISTORY\n" +" alternative location for the command history file\n" +msgstr "" +" PSQL_HISTORY\n" +" å‘½ä»¤åŽ†å²æ–‡ä»¶çš„å¯é€‰ä½ç½®\n" -#: help.c:415 +#: help.c:498 #, c-format -msgid " PSQLRC alternative location for the user's .psqlrc file\n" -msgstr " PSQLRC 用户的.psqlrc文件的å¯é€‰ä½ç½®\n" +msgid "" +" PSQL_PAGER, PAGER\n" +" name of external pager program\n" +msgstr "" +" PSQL_PAGER, PAGER\n" +" 外部分页程åºçš„åç§°\n" -#: help.c:416 +#: help.c:500 #, c-format -msgid " SHELL shell used by the \\! command\n" -msgstr " SHELL \\! 命令使用的shell\n" +msgid "" +" PSQLRC\n" +" alternative location for the user's .psqlrc file\n" +msgstr "" +" PSQLRC\n" +" 用户的.psqlrc文件的å¯é€‰ä½ç½®\n" + +#: help.c:502 +#, c-format +msgid "" +" SHELL\n" +" shell used by the \\! command\n" +msgstr "" +" SHELL\n" +" \\! 命令使用的shell\n" # help.c:200 -#: help.c:417 +#: help.c:504 #, c-format -msgid " TMPDIR directory for temporary files\n" -msgstr " TMPDIR 临时文件的目录\n" +msgid "" +" TMPDIR\n" +" directory for temporary files\n" +msgstr "" +" TMPDIR\n" +" 临时文件的目录\n" # help.c:285 -#: help.c:460 +#: help.c:548 msgid "Available help:\n" msgstr "å¯ç”¨çš„说明:\n" # help.c:344 -#: help.c:544 -#, c-format +#: help.c:636 +#, fuzzy, c-format +#| msgid "" +#| "Command: %s\n" +#| "Description: %s\n" +#| "Syntax:\n" +#| "%s\n" +#| "\n" msgid "" "Command: %s\n" "Description: %s\n" "Syntax:\n" "%s\n" "\n" +"URL: %s\n" +"\n" msgstr "" "命令: %s\n" "æè¿°ï¼š %s\n" @@ -3745,7 +4456,7 @@ msgstr "" "\n" # help.c:357 -#: help.c:560 +#: help.c:655 #, c-format msgid "" "No help available for \"%s\".\n" @@ -3755,57 +4466,69 @@ msgstr "" "请å°è¯•用ä¸å¸¦å‚æ•°çš„ \\h æ¥çœ‹ä¸€ä¸‹æ˜¯å¦æœ‰å¯ä½¿ç”¨çš„帮助信æ¯.\n" # input.c:210 -#: input.c:216 -#, c-format -msgid "could not read from input file: %s\n" +#: input.c:218 +#, fuzzy, c-format +#| msgid "could not read from input file: %s\n" +msgid "could not read from input file: %m" msgstr "无法从输入档案读å–:%s\n" # input.c:210 -#: input.c:471 input.c:510 -#, c-format -msgid "could not save history to file \"%s\": %s\n" +#: input.c:472 input.c:510 +#, fuzzy, c-format +#| msgid "could not save history to file \"%s\": %s\n" +msgid "could not save history to file \"%s\": %m" msgstr "无法将历å²è®°å½•储存到 \"%s\":%s\n" # input.c:213 -#: input.c:530 -#, c-format -msgid "history is not supported by this installation\n" +#: input.c:529 +#, fuzzy, c-format +#| msgid "history is not supported by this installation\n" +msgid "history is not supported by this installation" msgstr "è¿™ä¸ªå®‰è£…ä¸æ”¯æ´å‘½ä»¤è®°å½•\n" # large_obj.c:36 -#: large_obj.c:64 -#, c-format -msgid "%s: not connected to a database\n" +#: large_obj.c:65 +#, fuzzy, c-format +#| msgid "%s: not connected to a database\n" +msgid "%s: not connected to a database" msgstr "%s:尚未与数æ®åº“连接\n" # large_obj.c:55 -#: large_obj.c:83 -#, c-format -msgid "%s: current transaction is aborted\n" +#: large_obj.c:84 +#, fuzzy, c-format +#| msgid "%s: current transaction is aborted\n" +msgid "%s: current transaction is aborted" msgstr "%s:目å‰çš„事务被中止\n" # large_obj.c:58 -#: large_obj.c:86 -#, c-format -msgid "%s: unknown transaction status\n" +#: large_obj.c:87 +#, fuzzy, c-format +#| msgid "%s: unknown transaction status\n" +msgid "%s: unknown transaction status" msgstr "%sï¼šä¸æ˜Žäº‹åŠ¡çŠ¶æ€\n" -#: large_obj.c:287 large_obj.c:298 +#: large_obj.c:288 large_obj.c:299 msgid "ID" msgstr "ID" # large_obj.c:264 -#: large_obj.c:308 +#: large_obj.c:309 msgid "Large objects" msgstr "大型对象" +#: mainloop.c:136 +#, fuzzy, c-format +#| msgid "\\if: escaped\n" +msgid "\\if: escaped" +msgstr "\\if: 逃脱\n" + # mainloop.c:172 -#: mainloop.c:168 +#: mainloop.c:183 #, c-format msgid "Use \"\\q\" to leave %s.\n" msgstr "使用 \"\\q\" 离开 %s。\n" -#: mainloop.c:190 +#: mainloop.c:205 msgid "" "The input is a PostgreSQL custom-format dump.\n" "Use the pg_restore command-line client to restore this dump to a database.\n" @@ -3813,12 +4536,20 @@ msgstr "" "该输入是一个PostgreSQL自定义格å¼çš„转储。\n" "请使用pg_restore命令行客户端æ¥å°†è¿™ä¸ªè½¬å‚¨æ¢å¤åˆ°æ•°æ®åº“。\n" -#: mainloop.c:210 +#: mainloop.c:282 +msgid "Use \\? for help or press control-C to clear the input buffer." +msgstr "使用\\?获得帮助或按control-C清除输入缓冲区." + +#: mainloop.c:284 +msgid "Use \\? for help." +msgstr "使用\\?获å–帮助." + +#: mainloop.c:288 msgid "You are using psql, the command-line interface to PostgreSQL." msgstr "您正在使用psql, 这是一ç§ç”¨äºŽè®¿é—®PostgreSQL的命令行界é¢" # startup.c:292 -#: mainloop.c:211 +#: mainloop.c:289 #, c-format msgid "" "Type: \\copyright for distribution terms\n" @@ -3833,14 +4564,39 @@ msgstr "" " \\g 或者以分å·(;)结尾以执行查询\n" " \\q 退出\n" -#: psqlscanslash.l:584 -#, c-format -msgid "unterminated quoted string\n" -msgstr "未结æŸçš„引用字符串\n" +#: mainloop.c:313 +msgid "Use \\q to quit." +msgstr "使用\\q 退出." + +#: mainloop.c:316 mainloop.c:340 +msgid "Use control-D to quit." +msgstr "使用control-D退出." + +#: mainloop.c:318 mainloop.c:342 +msgid "Use control-C to quit." +msgstr "使用control-C退出." + +#: mainloop.c:449 mainloop.c:591 +#, fuzzy, c-format +#| msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block\n" +msgid "query ignored; use \\endif or Ctrl-C to exit current \\if block" +msgstr "查询被忽略;使用\\endif或Ctrl-C退出当å‰\\ifå—\n" + +#: mainloop.c:609 +#, fuzzy, c-format +#| msgid "reached EOF without finding closing \\endif(s)\n" +msgid "reached EOF without finding closing \\endif(s)" +msgstr "已到达EOF,但未找到结æŸç¬¦\\endif\n" -#: psqlscanslash.l:737 +#: psqlscanslash.l:638 #, c-format -msgid "%s: out of memory\n" +msgid "unterminated quoted string" +msgstr "未结æŸçš„引用字符串" + +#: psqlscanslash.l:811 +#, fuzzy, c-format +#| msgid "%s: out of memory\n" +msgid "%s: out of memory" msgstr "%s: 内存溢出\n" # describe.c:82 @@ -3855,507 +4611,568 @@ msgstr "%s: 内存溢出\n" # describe.c:1586 # describe.c:1634 # describe.c:1727 -#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:64 sql_help.c:66 -#: sql_help.c:68 sql_help.c:79 sql_help.c:81 sql_help.c:83 sql_help.c:109 -#: sql_help.c:115 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:124 -#: sql_help.c:126 sql_help.c:128 sql_help.c:221 sql_help.c:223 sql_help.c:224 -#: sql_help.c:226 sql_help.c:228 sql_help.c:231 sql_help.c:233 sql_help.c:235 -#: sql_help.c:237 sql_help.c:249 sql_help.c:250 sql_help.c:251 sql_help.c:253 -#: sql_help.c:299 sql_help.c:301 sql_help.c:303 sql_help.c:305 sql_help.c:365 -#: sql_help.c:370 sql_help.c:372 sql_help.c:415 sql_help.c:417 sql_help.c:420 -#: sql_help.c:422 sql_help.c:489 sql_help.c:494 sql_help.c:499 sql_help.c:504 -#: sql_help.c:509 sql_help.c:558 sql_help.c:560 sql_help.c:562 sql_help.c:564 -#: sql_help.c:567 sql_help.c:569 sql_help.c:580 sql_help.c:582 sql_help.c:624 -#: sql_help.c:626 sql_help.c:628 sql_help.c:631 sql_help.c:633 sql_help.c:635 -#: sql_help.c:669 sql_help.c:673 sql_help.c:677 sql_help.c:696 sql_help.c:699 -#: sql_help.c:702 sql_help.c:731 sql_help.c:743 sql_help.c:751 sql_help.c:754 -#: sql_help.c:757 sql_help.c:772 sql_help.c:775 sql_help.c:819 sql_help.c:842 -#: sql_help.c:853 sql_help.c:855 sql_help.c:872 sql_help.c:881 sql_help.c:883 -#: sql_help.c:885 sql_help.c:897 sql_help.c:901 sql_help.c:903 sql_help.c:987 -#: sql_help.c:989 sql_help.c:992 sql_help.c:995 sql_help.c:997 sql_help.c:999 -#: sql_help.c:1060 sql_help.c:1062 sql_help.c:1064 sql_help.c:1067 -#: sql_help.c:1088 sql_help.c:1091 sql_help.c:1094 sql_help.c:1097 -#: sql_help.c:1101 sql_help.c:1103 sql_help.c:1105 sql_help.c:1107 -#: sql_help.c:1121 sql_help.c:1124 sql_help.c:1126 sql_help.c:1128 -#: sql_help.c:1138 sql_help.c:1140 sql_help.c:1150 sql_help.c:1152 -#: sql_help.c:1162 sql_help.c:1165 sql_help.c:1186 sql_help.c:1188 -#: sql_help.c:1190 sql_help.c:1193 sql_help.c:1195 sql_help.c:1197 -#: sql_help.c:1247 sql_help.c:1285 sql_help.c:1288 sql_help.c:1290 -#: sql_help.c:1292 sql_help.c:1294 sql_help.c:1296 sql_help.c:1299 -#: sql_help.c:1339 sql_help.c:1542 sql_help.c:1613 sql_help.c:1633 -#: sql_help.c:1650 sql_help.c:1705 sql_help.c:1709 sql_help.c:1719 -#: sql_help.c:1739 sql_help.c:1764 sql_help.c:1782 sql_help.c:1811 -#: sql_help.c:1886 sql_help.c:1928 sql_help.c:1950 sql_help.c:1970 -#: sql_help.c:1971 sql_help.c:2006 sql_help.c:2026 sql_help.c:2048 -#: sql_help.c:2061 sql_help.c:2092 sql_help.c:2117 sql_help.c:2161 -#: sql_help.c:2347 sql_help.c:2360 sql_help.c:2377 sql_help.c:2393 -#: sql_help.c:2432 sql_help.c:2483 sql_help.c:2487 sql_help.c:2489 -#: sql_help.c:2495 sql_help.c:2513 sql_help.c:2540 sql_help.c:2575 -#: sql_help.c:2587 sql_help.c:2596 sql_help.c:2640 sql_help.c:2654 -#: sql_help.c:2682 sql_help.c:2690 sql_help.c:2698 sql_help.c:2706 -#: sql_help.c:2714 sql_help.c:2722 sql_help.c:2730 sql_help.c:2738 -#: sql_help.c:2747 sql_help.c:2758 sql_help.c:2766 sql_help.c:2774 -#: sql_help.c:2782 sql_help.c:2790 sql_help.c:2800 sql_help.c:2809 -#: sql_help.c:2818 sql_help.c:2826 sql_help.c:2835 sql_help.c:2843 -#: sql_help.c:2852 sql_help.c:2860 sql_help.c:2868 sql_help.c:2876 -#: sql_help.c:2884 sql_help.c:2892 sql_help.c:2900 sql_help.c:2908 -#: sql_help.c:2916 sql_help.c:2933 sql_help.c:2942 sql_help.c:2950 -#: sql_help.c:2967 sql_help.c:2982 sql_help.c:3247 sql_help.c:3298 -#: sql_help.c:3327 sql_help.c:3335 sql_help.c:3754 sql_help.c:3802 -#: sql_help.c:3943 +#: sql_help.c:35 sql_help.c:38 sql_help.c:41 sql_help.c:65 sql_help.c:66 +#: sql_help.c:68 sql_help.c:70 sql_help.c:81 sql_help.c:83 sql_help.c:85 +#: sql_help.c:111 sql_help.c:117 sql_help.c:119 sql_help.c:121 sql_help.c:123 +#: sql_help.c:126 sql_help.c:128 sql_help.c:130 sql_help.c:235 sql_help.c:237 +#: sql_help.c:238 sql_help.c:240 sql_help.c:242 sql_help.c:245 sql_help.c:247 +#: sql_help.c:249 sql_help.c:251 sql_help.c:263 sql_help.c:264 sql_help.c:265 +#: sql_help.c:267 sql_help.c:316 sql_help.c:318 sql_help.c:320 sql_help.c:322 +#: sql_help.c:391 sql_help.c:396 sql_help.c:398 sql_help.c:440 sql_help.c:442 +#: sql_help.c:445 sql_help.c:447 sql_help.c:515 sql_help.c:520 sql_help.c:525 +#: sql_help.c:530 sql_help.c:535 sql_help.c:588 sql_help.c:590 sql_help.c:592 +#: sql_help.c:594 sql_help.c:596 sql_help.c:599 sql_help.c:601 sql_help.c:604 +#: sql_help.c:615 sql_help.c:617 sql_help.c:658 sql_help.c:660 sql_help.c:662 +#: sql_help.c:665 sql_help.c:667 sql_help.c:669 sql_help.c:702 sql_help.c:706 +#: sql_help.c:710 sql_help.c:729 sql_help.c:732 sql_help.c:735 sql_help.c:764 +#: sql_help.c:776 sql_help.c:784 sql_help.c:787 sql_help.c:790 sql_help.c:805 +#: sql_help.c:808 sql_help.c:837 sql_help.c:842 sql_help.c:847 sql_help.c:852 +#: sql_help.c:857 sql_help.c:879 sql_help.c:881 sql_help.c:883 sql_help.c:885 +#: sql_help.c:888 sql_help.c:890 sql_help.c:931 sql_help.c:975 sql_help.c:980 +#: sql_help.c:985 sql_help.c:990 sql_help.c:995 sql_help.c:1014 sql_help.c:1025 +#: sql_help.c:1027 sql_help.c:1046 sql_help.c:1056 sql_help.c:1058 +#: sql_help.c:1060 sql_help.c:1072 sql_help.c:1076 sql_help.c:1078 +#: sql_help.c:1089 sql_help.c:1091 sql_help.c:1093 sql_help.c:1109 +#: sql_help.c:1111 sql_help.c:1115 sql_help.c:1118 sql_help.c:1119 +#: sql_help.c:1120 sql_help.c:1123 sql_help.c:1125 sql_help.c:1257 +#: sql_help.c:1259 sql_help.c:1262 sql_help.c:1265 sql_help.c:1267 +#: sql_help.c:1269 sql_help.c:1272 sql_help.c:1275 sql_help.c:1384 +#: sql_help.c:1386 sql_help.c:1388 sql_help.c:1391 sql_help.c:1412 +#: sql_help.c:1415 sql_help.c:1418 sql_help.c:1421 sql_help.c:1425 +#: sql_help.c:1427 sql_help.c:1429 sql_help.c:1431 sql_help.c:1445 +#: sql_help.c:1448 sql_help.c:1450 sql_help.c:1452 sql_help.c:1462 +#: sql_help.c:1464 sql_help.c:1474 sql_help.c:1476 sql_help.c:1486 +#: sql_help.c:1489 sql_help.c:1511 sql_help.c:1513 sql_help.c:1515 +#: sql_help.c:1518 sql_help.c:1520 sql_help.c:1522 sql_help.c:1525 +#: sql_help.c:1575 sql_help.c:1617 sql_help.c:1620 sql_help.c:1622 +#: sql_help.c:1624 sql_help.c:1626 sql_help.c:1628 sql_help.c:1631 +#: sql_help.c:1681 sql_help.c:1697 sql_help.c:1918 sql_help.c:1987 +#: sql_help.c:2006 sql_help.c:2019 sql_help.c:2076 sql_help.c:2083 +#: sql_help.c:2093 sql_help.c:2113 sql_help.c:2138 sql_help.c:2156 +#: sql_help.c:2185 sql_help.c:2280 sql_help.c:2322 sql_help.c:2345 +#: sql_help.c:2366 sql_help.c:2367 sql_help.c:2404 sql_help.c:2424 +#: sql_help.c:2446 sql_help.c:2460 sql_help.c:2480 sql_help.c:2503 +#: sql_help.c:2533 sql_help.c:2558 sql_help.c:2604 sql_help.c:2882 +#: sql_help.c:2895 sql_help.c:2912 sql_help.c:2928 sql_help.c:2968 +#: sql_help.c:3020 sql_help.c:3024 sql_help.c:3026 sql_help.c:3032 +#: sql_help.c:3050 sql_help.c:3077 sql_help.c:3112 sql_help.c:3124 +#: sql_help.c:3133 sql_help.c:3177 sql_help.c:3191 sql_help.c:3219 +#: sql_help.c:3227 sql_help.c:3235 sql_help.c:3243 sql_help.c:3251 +#: sql_help.c:3259 sql_help.c:3267 sql_help.c:3275 sql_help.c:3284 +#: sql_help.c:3295 sql_help.c:3303 sql_help.c:3311 sql_help.c:3319 +#: sql_help.c:3327 sql_help.c:3337 sql_help.c:3346 sql_help.c:3355 +#: sql_help.c:3363 sql_help.c:3373 sql_help.c:3384 sql_help.c:3392 +#: sql_help.c:3401 sql_help.c:3412 sql_help.c:3421 sql_help.c:3429 +#: sql_help.c:3437 sql_help.c:3445 sql_help.c:3453 sql_help.c:3461 +#: sql_help.c:3469 sql_help.c:3477 sql_help.c:3485 sql_help.c:3493 +#: sql_help.c:3501 sql_help.c:3518 sql_help.c:3527 sql_help.c:3535 +#: sql_help.c:3552 sql_help.c:3567 sql_help.c:3837 sql_help.c:3888 +#: sql_help.c:3917 sql_help.c:3925 sql_help.c:4358 sql_help.c:4406 +#: sql_help.c:4547 msgid "name" msgstr "åç§°" -#: sql_help.c:37 sql_help.c:40 sql_help.c:43 sql_help.c:309 sql_help.c:1403 -#: sql_help.c:2655 sql_help.c:3550 +#: sql_help.c:36 sql_help.c:39 sql_help.c:42 sql_help.c:327 sql_help.c:1768 +#: sql_help.c:3192 sql_help.c:4144 msgid "aggregate_signature" msgstr "aggregate_signature" -#: sql_help.c:38 sql_help.c:65 sql_help.c:80 sql_help.c:116 sql_help.c:236 -#: sql_help.c:254 sql_help.c:373 sql_help.c:421 sql_help.c:498 sql_help.c:544 -#: sql_help.c:559 sql_help.c:581 sql_help.c:632 sql_help.c:698 sql_help.c:753 -#: sql_help.c:774 sql_help.c:820 sql_help.c:844 sql_help.c:854 sql_help.c:884 -#: sql_help.c:904 sql_help.c:996 sql_help.c:1061 sql_help.c:1104 -#: sql_help.c:1125 sql_help.c:1139 sql_help.c:1151 sql_help.c:1164 -#: sql_help.c:1194 sql_help.c:1248 sql_help.c:1293 +#: sql_help.c:37 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:250 +#: sql_help.c:268 sql_help.c:399 sql_help.c:446 sql_help.c:524 sql_help.c:571 +#: sql_help.c:589 sql_help.c:616 sql_help.c:666 sql_help.c:731 sql_help.c:786 +#: sql_help.c:807 sql_help.c:846 sql_help.c:891 sql_help.c:932 sql_help.c:984 +#: sql_help.c:1016 sql_help.c:1026 sql_help.c:1059 sql_help.c:1079 +#: sql_help.c:1092 sql_help.c:1126 sql_help.c:1266 sql_help.c:1385 +#: sql_help.c:1428 sql_help.c:1449 sql_help.c:1463 sql_help.c:1475 +#: sql_help.c:1488 sql_help.c:1519 sql_help.c:1576 sql_help.c:1625 msgid "new_name" msgstr "æ–°çš„åç§°" -#: sql_help.c:41 sql_help.c:67 sql_help.c:82 sql_help.c:118 sql_help.c:234 -#: sql_help.c:252 sql_help.c:371 sql_help.c:457 sql_help.c:503 sql_help.c:583 -#: sql_help.c:592 sql_help.c:651 sql_help.c:672 sql_help.c:701 sql_help.c:756 -#: sql_help.c:856 sql_help.c:882 sql_help.c:902 sql_help.c:1045 -#: sql_help.c:1063 sql_help.c:1106 sql_help.c:1127 sql_help.c:1189 -#: sql_help.c:1291 sql_help.c:2333 +#: sql_help.c:40 sql_help.c:69 sql_help.c:84 sql_help.c:120 sql_help.c:248 +#: sql_help.c:266 sql_help.c:397 sql_help.c:482 sql_help.c:529 sql_help.c:618 +#: sql_help.c:627 sql_help.c:685 sql_help.c:705 sql_help.c:734 sql_help.c:789 +#: sql_help.c:851 sql_help.c:889 sql_help.c:989 sql_help.c:1028 sql_help.c:1057 +#: sql_help.c:1077 sql_help.c:1090 sql_help.c:1124 sql_help.c:1326 +#: sql_help.c:1387 sql_help.c:1430 sql_help.c:1451 sql_help.c:1514 +#: sql_help.c:1623 sql_help.c:2868 msgid "new_owner" msgstr "新的属主" -#: sql_help.c:44 sql_help.c:69 sql_help.c:84 sql_help.c:238 sql_help.c:302 -#: sql_help.c:423 sql_help.c:508 sql_help.c:634 sql_help.c:676 sql_help.c:704 -#: sql_help.c:759 sql_help.c:886 sql_help.c:998 sql_help.c:1108 -#: sql_help.c:1129 sql_help.c:1141 sql_help.c:1153 sql_help.c:1196 -#: sql_help.c:1295 +#: sql_help.c:43 sql_help.c:71 sql_help.c:86 sql_help.c:252 sql_help.c:319 +#: sql_help.c:448 sql_help.c:534 sql_help.c:668 sql_help.c:709 sql_help.c:737 +#: sql_help.c:792 sql_help.c:856 sql_help.c:994 sql_help.c:1061 sql_help.c:1094 +#: sql_help.c:1268 sql_help.c:1432 sql_help.c:1453 sql_help.c:1465 +#: sql_help.c:1477 sql_help.c:1521 sql_help.c:1627 msgid "new_schema" msgstr "新的模å¼" # describe.c:1174 -#: sql_help.c:45 sql_help.c:1456 sql_help.c:2656 sql_help.c:3569 +#: sql_help.c:44 sql_help.c:1832 sql_help.c:3193 sql_help.c:4173 msgid "where aggregate_signature is:" msgstr "其中 aggregate_signature 是:" -#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:319 sql_help.c:344 -#: sql_help.c:347 sql_help.c:350 sql_help.c:490 sql_help.c:495 sql_help.c:500 -#: sql_help.c:505 sql_help.c:510 sql_help.c:1421 sql_help.c:1457 -#: sql_help.c:1460 sql_help.c:1463 sql_help.c:1614 sql_help.c:1634 -#: sql_help.c:1637 sql_help.c:1887 sql_help.c:2657 sql_help.c:2660 -#: sql_help.c:2663 sql_help.c:2748 sql_help.c:3133 sql_help.c:3465 -#: sql_help.c:3556 sql_help.c:3570 sql_help.c:3573 sql_help.c:3576 +#: sql_help.c:45 sql_help.c:48 sql_help.c:51 sql_help.c:337 sql_help.c:350 +#: sql_help.c:354 sql_help.c:370 sql_help.c:373 sql_help.c:376 sql_help.c:516 +#: sql_help.c:521 sql_help.c:526 sql_help.c:531 sql_help.c:536 sql_help.c:838 +#: sql_help.c:843 sql_help.c:848 sql_help.c:853 sql_help.c:858 sql_help.c:976 +#: sql_help.c:981 sql_help.c:986 sql_help.c:991 sql_help.c:996 sql_help.c:1786 +#: sql_help.c:1803 sql_help.c:1809 sql_help.c:1833 sql_help.c:1836 +#: sql_help.c:1839 sql_help.c:1988 sql_help.c:2007 sql_help.c:2010 +#: sql_help.c:2281 sql_help.c:2481 sql_help.c:3194 sql_help.c:3197 +#: sql_help.c:3200 sql_help.c:3285 sql_help.c:3374 sql_help.c:3402 +#: sql_help.c:3722 sql_help.c:4055 sql_help.c:4150 sql_help.c:4157 +#: sql_help.c:4163 sql_help.c:4174 sql_help.c:4177 sql_help.c:4180 msgid "argmode" msgstr "傿•°æ¨¡å¼" # describe.c:480 -#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:320 sql_help.c:345 -#: sql_help.c:348 sql_help.c:351 sql_help.c:491 sql_help.c:496 sql_help.c:501 -#: sql_help.c:506 sql_help.c:511 sql_help.c:1422 sql_help.c:1458 -#: sql_help.c:1461 sql_help.c:1464 sql_help.c:1615 sql_help.c:1635 -#: sql_help.c:1638 sql_help.c:1888 sql_help.c:2658 sql_help.c:2661 -#: sql_help.c:2664 sql_help.c:2749 sql_help.c:3557 sql_help.c:3571 -#: sql_help.c:3574 sql_help.c:3577 +#: sql_help.c:46 sql_help.c:49 sql_help.c:52 sql_help.c:338 sql_help.c:351 +#: sql_help.c:355 sql_help.c:371 sql_help.c:374 sql_help.c:377 sql_help.c:517 +#: sql_help.c:522 sql_help.c:527 sql_help.c:532 sql_help.c:537 sql_help.c:839 +#: sql_help.c:844 sql_help.c:849 sql_help.c:854 sql_help.c:859 sql_help.c:977 +#: sql_help.c:982 sql_help.c:987 sql_help.c:992 sql_help.c:997 sql_help.c:1787 +#: sql_help.c:1804 sql_help.c:1810 sql_help.c:1834 sql_help.c:1837 +#: sql_help.c:1840 sql_help.c:1989 sql_help.c:2008 sql_help.c:2011 +#: sql_help.c:2282 sql_help.c:2482 sql_help.c:3195 sql_help.c:3198 +#: sql_help.c:3201 sql_help.c:3286 sql_help.c:3375 sql_help.c:3403 +#: sql_help.c:4151 sql_help.c:4158 sql_help.c:4164 sql_help.c:4175 +#: sql_help.c:4178 sql_help.c:4181 msgid "argname" msgstr "傿•°åç§°" # describe.c:1689 -#: sql_help.c:48 sql_help.c:51 sql_help.c:54 sql_help.c:321 sql_help.c:346 -#: sql_help.c:349 sql_help.c:352 sql_help.c:492 sql_help.c:497 sql_help.c:502 -#: sql_help.c:507 sql_help.c:512 sql_help.c:1423 sql_help.c:1459 -#: sql_help.c:1462 sql_help.c:1465 sql_help.c:1889 sql_help.c:2659 -#: sql_help.c:2662 sql_help.c:2665 sql_help.c:2750 sql_help.c:3558 -#: sql_help.c:3572 sql_help.c:3575 sql_help.c:3578 +#: sql_help.c:47 sql_help.c:50 sql_help.c:53 sql_help.c:339 sql_help.c:352 +#: sql_help.c:356 sql_help.c:372 sql_help.c:375 sql_help.c:378 sql_help.c:518 +#: sql_help.c:523 sql_help.c:528 sql_help.c:533 sql_help.c:538 sql_help.c:840 +#: sql_help.c:845 sql_help.c:850 sql_help.c:855 sql_help.c:860 sql_help.c:978 +#: sql_help.c:983 sql_help.c:988 sql_help.c:993 sql_help.c:998 sql_help.c:1788 +#: sql_help.c:1805 sql_help.c:1811 sql_help.c:1835 sql_help.c:1838 +#: sql_help.c:1841 sql_help.c:2283 sql_help.c:2483 sql_help.c:3196 +#: sql_help.c:3199 sql_help.c:3202 sql_help.c:3287 sql_help.c:3376 +#: sql_help.c:3404 sql_help.c:4152 sql_help.c:4159 sql_help.c:4165 +#: sql_help.c:4176 sql_help.c:4179 sql_help.c:4182 msgid "argtype" msgstr "傿•°ç±»åž‹" -#: sql_help.c:110 sql_help.c:368 sql_help.c:446 sql_help.c:458 sql_help.c:814 -#: sql_help.c:899 sql_help.c:1122 sql_help.c:1242 sql_help.c:1270 -#: sql_help.c:1513 sql_help.c:1519 sql_help.c:1814 sql_help.c:1846 -#: sql_help.c:1853 sql_help.c:1929 sql_help.c:2093 sql_help.c:2182 -#: sql_help.c:2362 sql_help.c:2541 sql_help.c:2563 sql_help.c:3001 -#: sql_help.c:3167 +#: sql_help.c:112 sql_help.c:394 sql_help.c:471 sql_help.c:483 sql_help.c:926 +#: sql_help.c:1074 sql_help.c:1446 sql_help.c:1570 sql_help.c:1602 +#: sql_help.c:1650 sql_help.c:1889 sql_help.c:1896 sql_help.c:2188 +#: sql_help.c:2230 sql_help.c:2237 sql_help.c:2246 sql_help.c:2323 +#: sql_help.c:2534 sql_help.c:2626 sql_help.c:2897 sql_help.c:3078 +#: sql_help.c:3100 sql_help.c:3588 sql_help.c:3756 sql_help.c:4608 msgid "option" msgstr "选项" -#: sql_help.c:111 sql_help.c:815 sql_help.c:1243 sql_help.c:1930 -#: sql_help.c:2094 sql_help.c:2542 +#: sql_help.c:113 sql_help.c:927 sql_help.c:1571 sql_help.c:2324 +#: sql_help.c:2535 sql_help.c:3079 msgid "where option can be:" msgstr "选项å¯ä»¥æ˜¯" -#: sql_help.c:112 sql_help.c:1746 +#: sql_help.c:114 sql_help.c:2120 msgid "allowconn" msgstr "allowconn" -#: sql_help.c:113 sql_help.c:816 sql_help.c:1244 sql_help.c:1747 -#: sql_help.c:2095 sql_help.c:2543 +#: sql_help.c:115 sql_help.c:928 sql_help.c:1572 sql_help.c:2121 +#: sql_help.c:2536 sql_help.c:3080 msgid "connlimit" msgstr "连接é™åˆ¶" -#: sql_help.c:114 sql_help.c:1748 +#: sql_help.c:116 sql_help.c:2122 msgid "istemplate" msgstr "istemplate" # describe.c:1342 -#: sql_help.c:120 sql_help.c:571 sql_help.c:637 sql_help.c:652 sql_help.c:1001 -#: sql_help.c:1038 +#: sql_help.c:122 sql_help.c:606 sql_help.c:671 sql_help.c:1271 sql_help.c:1319 msgid "new_tablespace" msgstr "新的表空间" # sql_help.h:366 -#: sql_help.c:122 sql_help.c:125 sql_help.c:127 sql_help.c:517 sql_help.c:519 -#: sql_help.c:520 sql_help.c:823 sql_help.c:827 sql_help.c:830 sql_help.c:915 -#: sql_help.c:918 sql_help.c:1250 sql_help.c:1253 sql_help.c:1255 -#: sql_help.c:1898 sql_help.c:3352 sql_help.c:3743 +#: sql_help.c:124 sql_help.c:127 sql_help.c:129 sql_help.c:544 sql_help.c:546 +#: sql_help.c:547 sql_help.c:863 sql_help.c:865 sql_help.c:866 sql_help.c:935 +#: sql_help.c:939 sql_help.c:942 sql_help.c:1003 sql_help.c:1005 +#: sql_help.c:1006 sql_help.c:1137 sql_help.c:1140 sql_help.c:1579 +#: sql_help.c:1583 sql_help.c:1586 sql_help.c:2293 sql_help.c:2487 +#: sql_help.c:3942 sql_help.c:4347 msgid "configuration_parameter" msgstr "é…ç½®å‚æ•°" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:123 sql_help.c:369 sql_help.c:441 sql_help.c:447 sql_help.c:459 -#: sql_help.c:518 sql_help.c:566 sql_help.c:643 sql_help.c:649 sql_help.c:824 -#: sql_help.c:900 sql_help.c:916 sql_help.c:917 sql_help.c:1020 -#: sql_help.c:1040 sql_help.c:1066 sql_help.c:1123 sql_help.c:1251 -#: sql_help.c:1271 sql_help.c:1815 sql_help.c:1847 sql_help.c:1854 -#: sql_help.c:1899 sql_help.c:1900 sql_help.c:1958 sql_help.c:1990 -#: sql_help.c:2183 sql_help.c:2257 sql_help.c:2265 sql_help.c:2297 -#: sql_help.c:2319 sql_help.c:2336 sql_help.c:2363 sql_help.c:2564 -#: sql_help.c:3168 sql_help.c:3744 sql_help.c:3745 +#: sql_help.c:125 sql_help.c:395 sql_help.c:466 sql_help.c:472 sql_help.c:484 +#: sql_help.c:545 sql_help.c:598 sql_help.c:677 sql_help.c:683 sql_help.c:864 +#: sql_help.c:887 sql_help.c:936 sql_help.c:1004 sql_help.c:1075 +#: sql_help.c:1114 sql_help.c:1117 sql_help.c:1122 sql_help.c:1138 +#: sql_help.c:1139 sql_help.c:1301 sql_help.c:1321 sql_help.c:1368 +#: sql_help.c:1390 sql_help.c:1447 sql_help.c:1580 sql_help.c:1603 +#: sql_help.c:2189 sql_help.c:2231 sql_help.c:2238 sql_help.c:2247 +#: sql_help.c:2294 sql_help.c:2295 sql_help.c:2354 sql_help.c:2388 +#: sql_help.c:2488 sql_help.c:2489 sql_help.c:2506 sql_help.c:2627 +#: sql_help.c:2657 sql_help.c:2762 sql_help.c:2775 sql_help.c:2789 +#: sql_help.c:2830 sql_help.c:2854 sql_help.c:2871 sql_help.c:2898 +#: sql_help.c:3101 sql_help.c:3757 sql_help.c:4348 sql_help.c:4349 msgid "value" msgstr "值" -#: sql_help.c:185 +#: sql_help.c:197 msgid "target_role" msgstr "目标角色" -#: sql_help.c:186 sql_help.c:1798 sql_help.c:2141 sql_help.c:2146 -#: sql_help.c:3115 sql_help.c:3122 sql_help.c:3136 sql_help.c:3142 -#: sql_help.c:3447 sql_help.c:3454 sql_help.c:3468 sql_help.c:3474 +#: sql_help.c:198 sql_help.c:2172 sql_help.c:2582 sql_help.c:2587 +#: sql_help.c:3704 sql_help.c:3711 sql_help.c:3725 sql_help.c:3731 +#: sql_help.c:4037 sql_help.c:4044 sql_help.c:4058 sql_help.c:4064 msgid "schema_name" msgstr "模å¼åç§°" -#: sql_help.c:187 +#: sql_help.c:199 msgid "abbreviated_grant_or_revoke" msgstr "简写形å¼çš„å¯æŽˆäºˆæˆ–å›žæ”¶çš„æƒé™" -#: sql_help.c:188 +#: sql_help.c:200 msgid "where abbreviated_grant_or_revoke is one of:" msgstr "简写形å¼çš„å¯æŽˆäºˆæˆ–å›žæ”¶æƒé™æ˜¯ä¸‹åˆ—内容之一" # describe.c:1375 -#: sql_help.c:189 sql_help.c:190 sql_help.c:191 sql_help.c:192 sql_help.c:193 -#: sql_help.c:194 sql_help.c:195 sql_help.c:196 sql_help.c:542 sql_help.c:570 -#: sql_help.c:636 sql_help.c:777 sql_help.c:834 sql_help.c:1000 -#: sql_help.c:1258 sql_help.c:1933 sql_help.c:1934 sql_help.c:1935 -#: sql_help.c:1936 sql_help.c:1937 sql_help.c:2063 sql_help.c:2098 -#: sql_help.c:2099 sql_help.c:2100 sql_help.c:2101 sql_help.c:2102 -#: sql_help.c:2546 sql_help.c:2547 sql_help.c:2548 sql_help.c:2549 -#: sql_help.c:2550 sql_help.c:3149 sql_help.c:3150 sql_help.c:3151 -#: sql_help.c:3448 sql_help.c:3452 sql_help.c:3455 sql_help.c:3457 -#: sql_help.c:3459 sql_help.c:3461 sql_help.c:3463 sql_help.c:3469 -#: sql_help.c:3471 sql_help.c:3473 sql_help.c:3475 sql_help.c:3477 -#: sql_help.c:3479 sql_help.c:3480 sql_help.c:3481 sql_help.c:3764 +#: sql_help.c:201 sql_help.c:202 sql_help.c:203 sql_help.c:204 sql_help.c:205 +#: sql_help.c:206 sql_help.c:207 sql_help.c:208 sql_help.c:209 sql_help.c:210 +#: sql_help.c:569 sql_help.c:605 sql_help.c:670 sql_help.c:810 sql_help.c:946 +#: sql_help.c:1270 sql_help.c:1590 sql_help.c:2327 sql_help.c:2328 +#: sql_help.c:2329 sql_help.c:2330 sql_help.c:2331 sql_help.c:2462 +#: sql_help.c:2539 sql_help.c:2540 sql_help.c:2541 sql_help.c:2542 +#: sql_help.c:2543 sql_help.c:3083 sql_help.c:3084 sql_help.c:3085 +#: sql_help.c:3086 sql_help.c:3087 sql_help.c:3738 sql_help.c:3739 +#: sql_help.c:3740 sql_help.c:4038 sql_help.c:4042 sql_help.c:4045 +#: sql_help.c:4047 sql_help.c:4049 sql_help.c:4051 sql_help.c:4053 +#: sql_help.c:4059 sql_help.c:4061 sql_help.c:4063 sql_help.c:4065 +#: sql_help.c:4067 sql_help.c:4069 sql_help.c:4070 sql_help.c:4071 +#: sql_help.c:4368 msgid "role_name" msgstr "角色åç§°" -#: sql_help.c:222 sql_help.c:434 sql_help.c:1011 sql_help.c:1013 -#: sql_help.c:1287 sql_help.c:1767 sql_help.c:1771 sql_help.c:1857 -#: sql_help.c:1861 sql_help.c:1954 sql_help.c:2269 sql_help.c:2279 -#: sql_help.c:2301 sql_help.c:3198 sql_help.c:3213 sql_help.c:3215 -#: sql_help.c:3629 sql_help.c:3630 sql_help.c:3639 sql_help.c:3680 -#: sql_help.c:3681 sql_help.c:3682 sql_help.c:3683 sql_help.c:3684 -#: sql_help.c:3685 sql_help.c:3718 sql_help.c:3719 sql_help.c:3724 -#: sql_help.c:3729 sql_help.c:3868 sql_help.c:3869 sql_help.c:3878 -#: sql_help.c:3919 sql_help.c:3920 sql_help.c:3921 sql_help.c:3922 -#: sql_help.c:3923 sql_help.c:3924 sql_help.c:3971 sql_help.c:3973 -#: sql_help.c:4006 sql_help.c:4062 sql_help.c:4063 sql_help.c:4072 -#: sql_help.c:4113 sql_help.c:4114 sql_help.c:4115 sql_help.c:4116 -#: sql_help.c:4117 sql_help.c:4118 +#: sql_help.c:236 sql_help.c:459 sql_help.c:1286 sql_help.c:1288 +#: sql_help.c:1336 sql_help.c:1347 sql_help.c:1372 sql_help.c:1619 +#: sql_help.c:2141 sql_help.c:2145 sql_help.c:2250 sql_help.c:2255 +#: sql_help.c:2349 sql_help.c:2757 sql_help.c:2770 sql_help.c:2784 +#: sql_help.c:2793 sql_help.c:2805 sql_help.c:2834 sql_help.c:3788 +#: sql_help.c:3803 sql_help.c:3805 sql_help.c:4233 sql_help.c:4234 +#: sql_help.c:4243 sql_help.c:4284 sql_help.c:4285 sql_help.c:4286 +#: sql_help.c:4287 sql_help.c:4288 sql_help.c:4289 sql_help.c:4322 +#: sql_help.c:4323 sql_help.c:4328 sql_help.c:4333 sql_help.c:4472 +#: sql_help.c:4473 sql_help.c:4482 sql_help.c:4523 sql_help.c:4524 +#: sql_help.c:4525 sql_help.c:4526 sql_help.c:4527 sql_help.c:4528 +#: sql_help.c:4575 sql_help.c:4577 sql_help.c:4634 sql_help.c:4690 +#: sql_help.c:4691 sql_help.c:4700 sql_help.c:4741 sql_help.c:4742 +#: sql_help.c:4743 sql_help.c:4744 sql_help.c:4745 sql_help.c:4746 msgid "expression" msgstr "表达å¼" -#: sql_help.c:225 +#: sql_help.c:239 msgid "domain_constraint" msgstr "域_约æŸ" -#: sql_help.c:227 sql_help.c:229 sql_help.c:232 sql_help.c:449 sql_help.c:450 -#: sql_help.c:993 sql_help.c:1026 sql_help.c:1027 sql_help.c:1028 -#: sql_help.c:1048 sql_help.c:1409 sql_help.c:1411 sql_help.c:1770 -#: sql_help.c:1856 sql_help.c:1860 sql_help.c:2268 sql_help.c:2278 -#: sql_help.c:3210 +#: sql_help.c:241 sql_help.c:243 sql_help.c:246 sql_help.c:474 sql_help.c:475 +#: sql_help.c:1263 sql_help.c:1307 sql_help.c:1308 sql_help.c:1309 +#: sql_help.c:1335 sql_help.c:1346 sql_help.c:1363 sql_help.c:1774 +#: sql_help.c:1776 sql_help.c:2144 sql_help.c:2249 sql_help.c:2254 +#: sql_help.c:2792 sql_help.c:2804 sql_help.c:3800 msgid "constraint_name" msgstr "约æŸåç§°" -#: sql_help.c:230 sql_help.c:994 +#: sql_help.c:244 sql_help.c:1264 msgid "new_constraint_name" msgstr "new_constraint_name(新约æŸå)" -#: sql_help.c:300 sql_help.c:898 +#: sql_help.c:317 sql_help.c:1073 msgid "new_version" msgstr "新版本" -#: sql_help.c:304 sql_help.c:306 +#: sql_help.c:321 sql_help.c:323 msgid "member_object" msgstr "member_object" -#: sql_help.c:307 +#: sql_help.c:324 msgid "where member_object is:" msgstr "member_objectçš„ä½ç½®:" -#: sql_help.c:308 sql_help.c:1402 sql_help.c:3549 +# describe.c:1375 +#: sql_help.c:325 sql_help.c:330 sql_help.c:331 sql_help.c:332 sql_help.c:333 +#: sql_help.c:334 sql_help.c:335 sql_help.c:340 sql_help.c:344 sql_help.c:346 +#: sql_help.c:348 sql_help.c:357 sql_help.c:358 sql_help.c:359 sql_help.c:360 +#: sql_help.c:361 sql_help.c:362 sql_help.c:363 sql_help.c:364 sql_help.c:367 +#: sql_help.c:368 sql_help.c:1766 sql_help.c:1771 sql_help.c:1778 +#: sql_help.c:1779 sql_help.c:1780 sql_help.c:1781 sql_help.c:1782 +#: sql_help.c:1783 sql_help.c:1784 sql_help.c:1789 sql_help.c:1791 +#: sql_help.c:1795 sql_help.c:1797 sql_help.c:1801 sql_help.c:1806 +#: sql_help.c:1807 sql_help.c:1814 sql_help.c:1815 sql_help.c:1816 +#: sql_help.c:1817 sql_help.c:1818 sql_help.c:1819 sql_help.c:1820 +#: sql_help.c:1821 sql_help.c:1822 sql_help.c:1823 sql_help.c:1824 +#: sql_help.c:1829 sql_help.c:1830 sql_help.c:4140 sql_help.c:4145 +#: sql_help.c:4146 sql_help.c:4147 sql_help.c:4148 sql_help.c:4154 +#: sql_help.c:4155 sql_help.c:4160 sql_help.c:4161 sql_help.c:4166 +#: sql_help.c:4167 sql_help.c:4168 sql_help.c:4169 sql_help.c:4170 +#: sql_help.c:4171 +msgid "object_name" +msgstr "对象_åç§°" + +#: sql_help.c:326 sql_help.c:1767 sql_help.c:4143 msgid "aggregate_name" msgstr "aggregate_name" # describe.c:1688 -#: sql_help.c:310 sql_help.c:1404 sql_help.c:1685 sql_help.c:1689 -#: sql_help.c:1691 sql_help.c:2673 +#: sql_help.c:328 sql_help.c:1769 sql_help.c:2053 sql_help.c:2057 +#: sql_help.c:2059 sql_help.c:3210 msgid "source_type" msgstr "ç±»åž‹æŒ‡æ´¾ä¸­çš„æºæ•°æ®ç±»åž‹" # describe.c:1689 -#: sql_help.c:311 sql_help.c:1405 sql_help.c:1686 sql_help.c:1690 -#: sql_help.c:1692 sql_help.c:2674 +#: sql_help.c:329 sql_help.c:1770 sql_help.c:2054 sql_help.c:2058 +#: sql_help.c:2060 sql_help.c:3211 msgid "target_type" msgstr "类型指派中的目标数æ®ç±»åž‹" -# describe.c:1375 -#: sql_help.c:312 sql_help.c:313 sql_help.c:314 sql_help.c:315 sql_help.c:316 -#: sql_help.c:317 sql_help.c:322 sql_help.c:326 sql_help.c:328 sql_help.c:330 -#: sql_help.c:331 sql_help.c:332 sql_help.c:333 sql_help.c:334 sql_help.c:335 -#: sql_help.c:336 sql_help.c:337 sql_help.c:338 sql_help.c:341 sql_help.c:342 -#: sql_help.c:1406 sql_help.c:1413 sql_help.c:1414 sql_help.c:1415 -#: sql_help.c:1416 sql_help.c:1417 sql_help.c:1418 sql_help.c:1419 -#: sql_help.c:1424 sql_help.c:1426 sql_help.c:1430 sql_help.c:1432 -#: sql_help.c:1436 sql_help.c:1437 sql_help.c:1440 sql_help.c:1441 -#: sql_help.c:1442 sql_help.c:1443 sql_help.c:1444 sql_help.c:1445 -#: sql_help.c:1446 sql_help.c:1447 sql_help.c:1448 sql_help.c:1453 -#: sql_help.c:1454 sql_help.c:3546 sql_help.c:3551 sql_help.c:3552 -#: sql_help.c:3553 sql_help.c:3554 sql_help.c:3560 sql_help.c:3561 -#: sql_help.c:3562 sql_help.c:3563 sql_help.c:3564 sql_help.c:3565 -#: sql_help.c:3566 sql_help.c:3567 -msgid "object_name" -msgstr "对象_åç§°" - # describe.c:498 -#: sql_help.c:318 sql_help.c:741 sql_help.c:1420 sql_help.c:1687 -#: sql_help.c:1722 sql_help.c:1785 sql_help.c:2007 sql_help.c:2038 -#: sql_help.c:2437 sql_help.c:3132 sql_help.c:3464 sql_help.c:3555 -#: sql_help.c:3658 sql_help.c:3662 sql_help.c:3666 sql_help.c:3669 -#: sql_help.c:3897 sql_help.c:3901 sql_help.c:3905 sql_help.c:3908 -#: sql_help.c:4091 sql_help.c:4095 sql_help.c:4099 sql_help.c:4102 +#: sql_help.c:336 sql_help.c:774 sql_help.c:1785 sql_help.c:2055 +#: sql_help.c:2096 sql_help.c:2159 sql_help.c:2405 sql_help.c:2436 +#: sql_help.c:2974 sql_help.c:4054 sql_help.c:4149 sql_help.c:4262 +#: sql_help.c:4266 sql_help.c:4270 sql_help.c:4273 sql_help.c:4501 +#: sql_help.c:4505 sql_help.c:4509 sql_help.c:4512 sql_help.c:4719 +#: sql_help.c:4723 sql_help.c:4727 sql_help.c:4730 msgid "function_name" msgstr "函数åç§°" # describe.c:512 -#: sql_help.c:323 sql_help.c:734 sql_help.c:1427 sql_help.c:2031 +#: sql_help.c:341 sql_help.c:767 sql_help.c:1792 sql_help.c:2429 msgid "operator_name" msgstr "æ“作符åç§°" # describe.c:321 -#: sql_help.c:324 sql_help.c:670 sql_help.c:674 sql_help.c:678 sql_help.c:1428 -#: sql_help.c:2008 sql_help.c:2791 +#: sql_help.c:342 sql_help.c:703 sql_help.c:707 sql_help.c:711 sql_help.c:1793 +#: sql_help.c:2406 sql_help.c:3328 msgid "left_type" msgstr "æ“作符左边æ“作数的类型" # describe.c:321 -#: sql_help.c:325 sql_help.c:671 sql_help.c:675 sql_help.c:679 sql_help.c:1429 -#: sql_help.c:2009 sql_help.c:2792 +#: sql_help.c:343 sql_help.c:704 sql_help.c:708 sql_help.c:712 sql_help.c:1794 +#: sql_help.c:2407 sql_help.c:3329 msgid "right_type" msgstr "æ“作符å³è¾¹æ“作数的类型" -#: sql_help.c:327 sql_help.c:329 sql_help.c:697 sql_help.c:700 sql_help.c:703 -#: sql_help.c:732 sql_help.c:744 sql_help.c:752 sql_help.c:755 sql_help.c:758 -#: sql_help.c:1431 sql_help.c:1433 sql_help.c:2028 sql_help.c:2049 -#: sql_help.c:2284 sql_help.c:2801 sql_help.c:2810 +#: sql_help.c:345 sql_help.c:347 sql_help.c:730 sql_help.c:733 sql_help.c:736 +#: sql_help.c:765 sql_help.c:777 sql_help.c:785 sql_help.c:788 sql_help.c:791 +#: sql_help.c:1352 sql_help.c:1796 sql_help.c:1798 sql_help.c:2426 +#: sql_help.c:2447 sql_help.c:2810 sql_help.c:3338 sql_help.c:3347 msgid "index_method" msgstr "访问索引的方法" -#: sql_help.c:339 sql_help.c:1044 sql_help.c:1449 sql_help.c:1895 -#: sql_help.c:2260 sql_help.c:2406 sql_help.c:2924 sql_help.c:3146 -#: sql_help.c:3478 +#: sql_help.c:349 sql_help.c:1802 sql_help.c:4156 +msgid "procedure_name" +msgstr "程åºåç§° " + +# describe.c:1375 +#: sql_help.c:353 sql_help.c:1808 sql_help.c:3721 sql_help.c:4162 +msgid "routine_name" +msgstr "程åºåç§°" + +#: sql_help.c:365 sql_help.c:1325 sql_help.c:1825 sql_help.c:2289 +#: sql_help.c:2486 sql_help.c:2765 sql_help.c:2941 sql_help.c:3509 +#: sql_help.c:3735 sql_help.c:4068 msgid "type_name" msgstr "类型åç§°" -#: sql_help.c:340 sql_help.c:1450 sql_help.c:1894 sql_help.c:2407 -#: sql_help.c:2631 sql_help.c:2925 sql_help.c:3138 sql_help.c:3470 +#: sql_help.c:366 sql_help.c:1826 sql_help.c:2288 sql_help.c:2485 +#: sql_help.c:2942 sql_help.c:3168 sql_help.c:3510 sql_help.c:3727 +#: sql_help.c:4060 msgid "lang_name" msgstr "语言åç§°" -#: sql_help.c:343 +#: sql_help.c:369 msgid "and aggregate_signature is:" msgstr "aggregate_signature指的是:" # describe.c:498 -#: sql_help.c:366 sql_help.c:1544 sql_help.c:1812 +#: sql_help.c:392 sql_help.c:1920 sql_help.c:2186 msgid "handler_function" msgstr "handler_function(处ç†_函数)" # describe.c:498 -#: sql_help.c:367 sql_help.c:1813 +#: sql_help.c:393 sql_help.c:2187 msgid "validator_function" msgstr "validator_function(验è¯_函数)" # describe.c:128 -#: sql_help.c:416 sql_help.c:493 sql_help.c:625 sql_help.c:988 sql_help.c:1187 -#: sql_help.c:2275 sql_help.c:2276 sql_help.c:2292 sql_help.c:2293 +#: sql_help.c:441 sql_help.c:519 sql_help.c:659 sql_help.c:841 sql_help.c:979 +#: sql_help.c:1258 sql_help.c:1512 msgid "action" msgstr "æ“作" # describe.c:1375 -#: sql_help.c:418 sql_help.c:425 sql_help.c:429 sql_help.c:430 sql_help.c:433 -#: sql_help.c:435 sql_help.c:436 sql_help.c:437 sql_help.c:439 sql_help.c:442 -#: sql_help.c:444 sql_help.c:445 sql_help.c:629 sql_help.c:639 sql_help.c:641 -#: sql_help.c:644 sql_help.c:646 sql_help.c:880 sql_help.c:990 sql_help.c:1003 -#: sql_help.c:1007 sql_help.c:1008 sql_help.c:1012 sql_help.c:1014 -#: sql_help.c:1015 sql_help.c:1016 sql_help.c:1018 sql_help.c:1021 -#: sql_help.c:1023 sql_help.c:1286 sql_help.c:1289 sql_help.c:1309 -#: sql_help.c:1408 sql_help.c:1510 sql_help.c:1515 sql_help.c:1529 -#: sql_help.c:1530 sql_help.c:1531 sql_help.c:1844 sql_help.c:1892 -#: sql_help.c:1953 sql_help.c:1988 sql_help.c:2168 sql_help.c:2248 -#: sql_help.c:2261 sql_help.c:2280 sql_help.c:2282 sql_help.c:2289 -#: sql_help.c:2300 sql_help.c:2317 sql_help.c:2440 sql_help.c:2576 -#: sql_help.c:3117 sql_help.c:3118 sql_help.c:3197 sql_help.c:3212 -#: sql_help.c:3214 sql_help.c:3216 sql_help.c:3449 sql_help.c:3450 -#: sql_help.c:3548 sql_help.c:3689 sql_help.c:3928 sql_help.c:3970 -#: sql_help.c:3972 sql_help.c:3974 sql_help.c:3991 sql_help.c:3994 -#: sql_help.c:4122 +#: sql_help.c:443 sql_help.c:450 sql_help.c:454 sql_help.c:455 sql_help.c:458 +#: sql_help.c:460 sql_help.c:461 sql_help.c:462 sql_help.c:464 sql_help.c:467 +#: sql_help.c:469 sql_help.c:470 sql_help.c:663 sql_help.c:673 sql_help.c:675 +#: sql_help.c:678 sql_help.c:680 sql_help.c:1055 sql_help.c:1260 +#: sql_help.c:1278 sql_help.c:1282 sql_help.c:1283 sql_help.c:1287 +#: sql_help.c:1289 sql_help.c:1290 sql_help.c:1291 sql_help.c:1293 +#: sql_help.c:1296 sql_help.c:1297 sql_help.c:1299 sql_help.c:1302 +#: sql_help.c:1304 sql_help.c:1348 sql_help.c:1350 sql_help.c:1357 +#: sql_help.c:1366 sql_help.c:1371 sql_help.c:1618 sql_help.c:1621 +#: sql_help.c:1658 sql_help.c:1773 sql_help.c:1886 sql_help.c:1892 +#: sql_help.c:1905 sql_help.c:1906 sql_help.c:1907 sql_help.c:2228 +#: sql_help.c:2241 sql_help.c:2286 sql_help.c:2348 sql_help.c:2352 +#: sql_help.c:2385 sql_help.c:2612 sql_help.c:2640 sql_help.c:2641 +#: sql_help.c:2748 sql_help.c:2756 sql_help.c:2766 sql_help.c:2769 +#: sql_help.c:2779 sql_help.c:2783 sql_help.c:2806 sql_help.c:2808 +#: sql_help.c:2815 sql_help.c:2828 sql_help.c:2833 sql_help.c:2851 +#: sql_help.c:2977 sql_help.c:3113 sql_help.c:3706 sql_help.c:3707 +#: sql_help.c:3787 sql_help.c:3802 sql_help.c:3804 sql_help.c:3806 +#: sql_help.c:4039 sql_help.c:4040 sql_help.c:4142 sql_help.c:4293 +#: sql_help.c:4532 sql_help.c:4574 sql_help.c:4576 sql_help.c:4578 +#: sql_help.c:4622 sql_help.c:4750 msgid "column_name" msgstr "列åç§°" # describe.c:1375 -#: sql_help.c:419 sql_help.c:630 sql_help.c:991 +#: sql_help.c:444 sql_help.c:664 sql_help.c:1261 msgid "new_column_name" msgstr "new_column_name(新列å)" -#: sql_help.c:424 sql_help.c:514 sql_help.c:638 sql_help.c:1002 -#: sql_help.c:1200 +#: sql_help.c:449 sql_help.c:540 sql_help.c:672 sql_help.c:862 sql_help.c:1000 +#: sql_help.c:1277 sql_help.c:1528 msgid "where action is one of:" msgstr "æ“作å¯ä»¥æ˜¯ä¸‹åˆ—选项之一" # describe.c:526 -#: sql_help.c:426 sql_help.c:431 sql_help.c:1004 sql_help.c:1009 -#: sql_help.c:1202 sql_help.c:1206 sql_help.c:1765 sql_help.c:1845 -#: sql_help.c:2027 sql_help.c:2249 sql_help.c:2485 sql_help.c:3299 +#: sql_help.c:451 sql_help.c:456 sql_help.c:1047 sql_help.c:1279 +#: sql_help.c:1284 sql_help.c:1530 sql_help.c:1534 sql_help.c:2139 +#: sql_help.c:2229 sql_help.c:2425 sql_help.c:2605 sql_help.c:2749 +#: sql_help.c:3022 sql_help.c:3889 msgid "data_type" msgstr "æ•°æ®_类型" # describe.c:128 -#: sql_help.c:427 sql_help.c:432 sql_help.c:1005 sql_help.c:1010 -#: sql_help.c:1203 sql_help.c:1207 sql_help.c:1766 sql_help.c:1848 -#: sql_help.c:1955 sql_help.c:2250 sql_help.c:2486 sql_help.c:2492 -#: sql_help.c:3207 +#: sql_help.c:452 sql_help.c:457 sql_help.c:1280 sql_help.c:1285 +#: sql_help.c:1531 sql_help.c:1535 sql_help.c:2140 sql_help.c:2232 +#: sql_help.c:2350 sql_help.c:2750 sql_help.c:2758 sql_help.c:2771 +#: sql_help.c:2785 sql_help.c:3023 sql_help.c:3029 sql_help.c:3797 msgid "collation" msgstr "校对规则" -#: sql_help.c:428 sql_help.c:1006 sql_help.c:1849 sql_help.c:2251 -#: sql_help.c:2262 +#: sql_help.c:453 sql_help.c:1281 sql_help.c:2233 sql_help.c:2242 +#: sql_help.c:2751 sql_help.c:2767 sql_help.c:2780 msgid "column_constraint" msgstr "列约æŸ" -#: sql_help.c:438 sql_help.c:640 sql_help.c:1017 +#: sql_help.c:463 sql_help.c:603 sql_help.c:674 sql_help.c:1298 msgid "integer" msgstr "æ•´æ•°" -#: sql_help.c:440 sql_help.c:443 sql_help.c:642 sql_help.c:645 sql_help.c:1019 -#: sql_help.c:1022 +#: sql_help.c:465 sql_help.c:468 sql_help.c:676 sql_help.c:679 sql_help.c:1300 +#: sql_help.c:1303 msgid "attribute_option" msgstr "属性选项" -#: sql_help.c:448 sql_help.c:1024 sql_help.c:1850 sql_help.c:2252 -#: sql_help.c:2263 +#: sql_help.c:473 sql_help.c:1305 sql_help.c:2234 sql_help.c:2243 +#: sql_help.c:2752 sql_help.c:2768 sql_help.c:2781 msgid "table_constraint" msgstr "表约æŸ" # describe.c:575 -#: sql_help.c:451 sql_help.c:452 sql_help.c:453 sql_help.c:454 sql_help.c:1029 -#: sql_help.c:1030 sql_help.c:1031 sql_help.c:1032 sql_help.c:1451 +#: sql_help.c:476 sql_help.c:477 sql_help.c:478 sql_help.c:479 sql_help.c:1310 +#: sql_help.c:1311 sql_help.c:1312 sql_help.c:1313 sql_help.c:1827 msgid "trigger_name" msgstr "触å‘器_åç§°" -#: sql_help.c:455 sql_help.c:456 sql_help.c:1042 sql_help.c:1043 -#: sql_help.c:1851 sql_help.c:2255 +#: sql_help.c:480 sql_help.c:481 sql_help.c:1323 sql_help.c:1324 +#: sql_help.c:2235 sql_help.c:2240 sql_help.c:2755 sql_help.c:2778 msgid "parent_table" msgstr "父表" # describe.c:498 -#: sql_help.c:513 sql_help.c:563 sql_help.c:627 sql_help.c:1167 -#: sql_help.c:1797 +#: sql_help.c:539 sql_help.c:595 sql_help.c:661 sql_help.c:861 sql_help.c:999 +#: sql_help.c:1491 sql_help.c:2171 msgid "extension_name" msgstr "extension_name(扩展å)" -#: sql_help.c:515 sql_help.c:1896 +#: sql_help.c:541 sql_help.c:1001 sql_help.c:2290 msgid "execution_cost" msgstr "执行函数的开销" -#: sql_help.c:516 sql_help.c:1897 +#: sql_help.c:542 sql_help.c:1002 sql_help.c:2291 msgid "result_rows" msgstr "返回记录的数é‡" +# describe.c:498 +#: sql_help.c:543 sql_help.c:2292 +#, fuzzy +#| msgid "start_function" +msgid "support_function" +msgstr "å¯åЍ_函数" + # describe.c:1636 -#: sql_help.c:537 sql_help.c:539 sql_help.c:813 sql_help.c:821 sql_help.c:825 -#: sql_help.c:828 sql_help.c:831 sql_help.c:1241 sql_help.c:1249 -#: sql_help.c:1252 sql_help.c:1254 sql_help.c:1256 sql_help.c:2142 -#: sql_help.c:2144 sql_help.c:2147 sql_help.c:2148 sql_help.c:3116 -#: sql_help.c:3120 sql_help.c:3123 sql_help.c:3125 sql_help.c:3127 -#: sql_help.c:3129 sql_help.c:3131 sql_help.c:3137 sql_help.c:3139 -#: sql_help.c:3141 sql_help.c:3143 sql_help.c:3145 sql_help.c:3147 +#: sql_help.c:564 sql_help.c:566 sql_help.c:925 sql_help.c:933 sql_help.c:937 +#: sql_help.c:940 sql_help.c:943 sql_help.c:1569 sql_help.c:1577 +#: sql_help.c:1581 sql_help.c:1584 sql_help.c:1587 sql_help.c:2583 +#: sql_help.c:2585 sql_help.c:2588 sql_help.c:2589 sql_help.c:3705 +#: sql_help.c:3709 sql_help.c:3712 sql_help.c:3714 sql_help.c:3716 +#: sql_help.c:3718 sql_help.c:3720 sql_help.c:3726 sql_help.c:3728 +#: sql_help.c:3730 sql_help.c:3732 sql_help.c:3734 sql_help.c:3736 msgid "role_specification" msgstr "role_specification" -#: sql_help.c:538 sql_help.c:540 sql_help.c:1268 sql_help.c:1740 -#: sql_help.c:2150 sql_help.c:2561 sql_help.c:2958 sql_help.c:3774 +#: sql_help.c:565 sql_help.c:567 sql_help.c:1600 sql_help.c:2114 +#: sql_help.c:2591 sql_help.c:3098 sql_help.c:3543 sql_help.c:4378 msgid "user_name" msgstr "用户å" -#: sql_help.c:541 sql_help.c:833 sql_help.c:1257 sql_help.c:2149 -#: sql_help.c:3148 +#: sql_help.c:568 sql_help.c:945 sql_help.c:1589 sql_help.c:2590 +#: sql_help.c:3737 msgid "where role_specification can be:" msgstr "这里role_specificationå¯ä»¥æ˜¯ï¼š" -#: sql_help.c:543 +#: sql_help.c:570 msgid "group_name" msgstr "组åç§°" # describe.c:1342 -#: sql_help.c:561 sql_help.c:1745 sql_help.c:1959 sql_help.c:1991 -#: sql_help.c:2258 sql_help.c:2266 sql_help.c:2298 sql_help.c:2320 -#: sql_help.c:2332 sql_help.c:3144 sql_help.c:3476 +#: sql_help.c:591 sql_help.c:1369 sql_help.c:2119 sql_help.c:2355 +#: sql_help.c:2389 sql_help.c:2763 sql_help.c:2776 sql_help.c:2790 +#: sql_help.c:2831 sql_help.c:2855 sql_help.c:2867 sql_help.c:3733 +#: sql_help.c:4066 msgid "tablespace_name" msgstr "表空间的åç§°" -#: sql_help.c:565 sql_help.c:568 sql_help.c:648 sql_help.c:650 sql_help.c:1039 -#: sql_help.c:1041 sql_help.c:1957 sql_help.c:1989 sql_help.c:2256 -#: sql_help.c:2264 sql_help.c:2296 sql_help.c:2318 +# describe.c:543 +# describe.c:1477 +#: sql_help.c:593 sql_help.c:681 sql_help.c:1318 sql_help.c:1327 +#: sql_help.c:1364 sql_help.c:1707 +msgid "index_name" +msgstr "索引åç§°" + +#: sql_help.c:597 sql_help.c:600 sql_help.c:682 sql_help.c:684 sql_help.c:1320 +#: sql_help.c:1322 sql_help.c:1367 sql_help.c:2353 sql_help.c:2387 +#: sql_help.c:2761 sql_help.c:2774 sql_help.c:2788 sql_help.c:2829 +#: sql_help.c:2853 msgid "storage_parameter" msgstr "å­˜å‚¨å‚æ•°" +# describe.c:1375 +#: sql_help.c:602 +msgid "column_number" +msgstr "列数" + # large_obj.c:264 -#: sql_help.c:591 sql_help.c:1425 sql_help.c:3559 +#: sql_help.c:626 sql_help.c:1790 sql_help.c:4153 msgid "large_object_oid" msgstr "大对象的OID" -# describe.c:543 -# describe.c:1477 -#: sql_help.c:647 sql_help.c:1037 sql_help.c:1046 sql_help.c:1049 -#: sql_help.c:1349 -msgid "index_name" -msgstr "索引åç§°" - -#: sql_help.c:680 sql_help.c:2012 +#: sql_help.c:713 sql_help.c:2410 msgid "res_proc" msgstr "é™åˆ¶é€‰æ‹©æ€§ä¼°ç®—函数" -#: sql_help.c:681 sql_help.c:2013 +#: sql_help.c:714 sql_help.c:2411 msgid "join_proc" msgstr "连接选择性估算函数" -#: sql_help.c:733 sql_help.c:745 sql_help.c:2030 +#: sql_help.c:766 sql_help.c:778 sql_help.c:2428 msgid "strategy_number" msgstr "访问索引所用方法的编å·" @@ -4363,365 +5180,525 @@ msgstr "访问索引所用方法的编å·" # describe.c:745 # describe.c:1478 # describe.c:1587 -#: sql_help.c:735 sql_help.c:736 sql_help.c:739 sql_help.c:740 sql_help.c:746 -#: sql_help.c:747 sql_help.c:749 sql_help.c:750 sql_help.c:2032 -#: sql_help.c:2033 sql_help.c:2036 sql_help.c:2037 +#: sql_help.c:768 sql_help.c:769 sql_help.c:772 sql_help.c:773 sql_help.c:779 +#: sql_help.c:780 sql_help.c:782 sql_help.c:783 sql_help.c:2430 sql_help.c:2431 +#: sql_help.c:2434 sql_help.c:2435 msgid "op_type" msgstr "æ“作数类型" -#: sql_help.c:737 sql_help.c:2034 +#: sql_help.c:770 sql_help.c:2432 msgid "sort_family_name" msgstr "sort_family_name(排åºå®¶æ—å)" -#: sql_help.c:738 sql_help.c:748 sql_help.c:2035 +#: sql_help.c:771 sql_help.c:781 sql_help.c:2433 msgid "support_number" msgstr "访问索引所使用函数的编å·" # describe.c:1689 -#: sql_help.c:742 sql_help.c:1688 sql_help.c:2039 sql_help.c:2409 -#: sql_help.c:2411 +#: sql_help.c:775 sql_help.c:2056 sql_help.c:2437 sql_help.c:2944 +#: sql_help.c:2946 msgid "argument_type" msgstr "傿•°ç±»åž‹" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:773 sql_help.c:776 sql_help.c:843 sql_help.c:879 sql_help.c:1163 -#: sql_help.c:1166 sql_help.c:1308 sql_help.c:1348 sql_help.c:1410 -#: sql_help.c:1435 sql_help.c:1439 sql_help.c:1452 sql_help.c:1509 -#: sql_help.c:1514 sql_help.c:1843 sql_help.c:1951 sql_help.c:1987 -#: sql_help.c:2062 sql_help.c:2119 sql_help.c:2167 sql_help.c:2247 -#: sql_help.c:2259 sql_help.c:2316 sql_help.c:2434 sql_help.c:2610 -#: sql_help.c:2827 sql_help.c:2844 sql_help.c:2934 sql_help.c:3114 -#: sql_help.c:3119 sql_help.c:3164 sql_help.c:3195 sql_help.c:3446 -#: sql_help.c:3451 sql_help.c:3547 sql_help.c:3644 sql_help.c:3646 -#: sql_help.c:3695 sql_help.c:3734 sql_help.c:3883 sql_help.c:3885 -#: sql_help.c:3934 sql_help.c:3968 sql_help.c:3990 sql_help.c:3992 -#: sql_help.c:3993 sql_help.c:4077 sql_help.c:4079 sql_help.c:4128 +#: sql_help.c:806 sql_help.c:809 sql_help.c:880 sql_help.c:882 sql_help.c:884 +#: sql_help.c:1015 sql_help.c:1054 sql_help.c:1487 sql_help.c:1490 +#: sql_help.c:1657 sql_help.c:1706 sql_help.c:1775 sql_help.c:1800 +#: sql_help.c:1813 sql_help.c:1828 sql_help.c:1885 sql_help.c:1891 +#: sql_help.c:2227 sql_help.c:2239 sql_help.c:2346 sql_help.c:2384 +#: sql_help.c:2461 sql_help.c:2504 sql_help.c:2560 sql_help.c:2611 +#: sql_help.c:2642 sql_help.c:2747 sql_help.c:2764 sql_help.c:2777 +#: sql_help.c:2850 sql_help.c:2970 sql_help.c:3147 sql_help.c:3364 +#: sql_help.c:3413 sql_help.c:3519 sql_help.c:3703 sql_help.c:3708 +#: sql_help.c:3753 sql_help.c:3785 sql_help.c:4036 sql_help.c:4041 +#: sql_help.c:4141 sql_help.c:4248 sql_help.c:4250 sql_help.c:4299 +#: sql_help.c:4338 sql_help.c:4487 sql_help.c:4489 sql_help.c:4538 +#: sql_help.c:4572 sql_help.c:4621 sql_help.c:4705 sql_help.c:4707 +#: sql_help.c:4756 msgid "table_name" msgstr "表å" -#: sql_help.c:778 sql_help.c:2064 +#: sql_help.c:811 sql_help.c:2463 msgid "using_expression" msgstr "using_expression" -#: sql_help.c:779 sql_help.c:2065 +#: sql_help.c:812 sql_help.c:2464 msgid "check_expression" msgstr "check_expression" +# sql_help.h:366 +#: sql_help.c:886 sql_help.c:2505 +msgid "publication_parameter" +msgstr "å‡ºç‰ˆå‚æ•°" + # command.c:915 # command.c:939 # startup.c:187 # startup.c:205 -#: sql_help.c:817 sql_help.c:1245 sql_help.c:1931 sql_help.c:2096 -#: sql_help.c:2544 +#: sql_help.c:929 sql_help.c:1573 sql_help.c:2325 sql_help.c:2537 +#: sql_help.c:3081 msgid "password" msgstr "å£ä»¤" -#: sql_help.c:818 sql_help.c:1246 sql_help.c:1932 sql_help.c:2097 -#: sql_help.c:2545 +#: sql_help.c:930 sql_help.c:1574 sql_help.c:2326 sql_help.c:2538 +#: sql_help.c:3082 msgid "timestamp" msgstr "时间戳" -#: sql_help.c:822 sql_help.c:826 sql_help.c:829 sql_help.c:832 sql_help.c:3124 -#: sql_help.c:3456 +#: sql_help.c:934 sql_help.c:938 sql_help.c:941 sql_help.c:944 sql_help.c:1578 +#: sql_help.c:1582 sql_help.c:1585 sql_help.c:1588 sql_help.c:3713 +#: sql_help.c:4046 msgid "database_name" msgstr "æ•°æ®åº“åç§°" -#: sql_help.c:873 sql_help.c:2162 +#: sql_help.c:1048 sql_help.c:2606 msgid "increment" msgstr "增é‡" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:874 sql_help.c:2163 +#: sql_help.c:1049 sql_help.c:2607 msgid "minvalue" msgstr "最å°å€¼" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:875 sql_help.c:2164 +#: sql_help.c:1050 sql_help.c:2608 msgid "maxvalue" msgstr "最大值" -#: sql_help.c:876 sql_help.c:2165 sql_help.c:3642 sql_help.c:3732 -#: sql_help.c:3881 sql_help.c:4010 sql_help.c:4075 +#: sql_help.c:1051 sql_help.c:2609 sql_help.c:4246 sql_help.c:4336 +#: sql_help.c:4485 sql_help.c:4638 sql_help.c:4703 msgid "start" msgstr "起始值" -#: sql_help.c:877 +#: sql_help.c:1052 sql_help.c:1295 msgid "restart" msgstr "釿–°å¯åЍåŽçš„åºåˆ—值" -#: sql_help.c:878 sql_help.c:2166 +#: sql_help.c:1053 sql_help.c:2610 msgid "cache" msgstr "缓存" -#: sql_help.c:1025 +#: sql_help.c:1110 sql_help.c:2654 +msgid "conninfo" +msgstr "连接信æ¯" + +#: sql_help.c:1112 sql_help.c:2655 +msgid "publication_name" +msgstr "publication_name(出版å)" + +# describe.c:1636 +#: sql_help.c:1113 +msgid "set_publication_option" +msgstr "设置出版选项" + +# help.c:88 +#: sql_help.c:1116 +msgid "refresh_option" +msgstr "refresh选项" + +# sql_help.h:366 +#: sql_help.c:1121 sql_help.c:2656 +msgid "subscription_parameter" +msgstr "è®¢é˜…å‚æ•°" + +#: sql_help.c:1273 sql_help.c:1276 +msgid "partition_name" +msgstr "分区å" + +#: sql_help.c:1274 sql_help.c:2244 sql_help.c:2782 +msgid "partition_bound_spec" +msgstr "分区绑定规范" + +# describe.c:415 +# describe.c:543 +# describe.c:1477 +#: sql_help.c:1292 sql_help.c:1338 sql_help.c:2796 +msgid "sequence_options" +msgstr "åºåˆ—选项" + +# describe.c:415 +# describe.c:543 +# describe.c:1477 +#: sql_help.c:1294 +msgid "sequence_option" +msgstr "åºåˆ—选项" + +#: sql_help.c:1306 msgid "table_constraint_using_index" msgstr "table_constraint_using_index(表约æŸä½¿ç”¨ç´¢å¼•)" -#: sql_help.c:1033 sql_help.c:1034 sql_help.c:1035 sql_help.c:1036 +#: sql_help.c:1314 sql_help.c:1315 sql_help.c:1316 sql_help.c:1317 msgid "rewrite_rule_name" msgstr "é‡å†™è§„则åç§°" -#: sql_help.c:1047 +#: sql_help.c:1328 sql_help.c:2821 +msgid "and partition_bound_spec is:" +msgstr "并且分区绑定的规范是:" + +#: sql_help.c:1329 sql_help.c:1330 sql_help.c:1331 sql_help.c:2822 +#: sql_help.c:2823 sql_help.c:2824 +#, fuzzy +#| msgid "partition_bound_spec" +msgid "partition_bound_expr" +msgstr "分区绑定规范" + +#: sql_help.c:1332 sql_help.c:1333 sql_help.c:2825 sql_help.c:2826 +msgid "numeric_literal" +msgstr "æ•°å­—_文字" + +# describe.c:1174 +#: sql_help.c:1334 +msgid "and column_constraint is:" +msgstr "å¹¶ä¸”åˆ—çš„çº¦æŸæ˜¯:" + +# describe.c:1639 +#: sql_help.c:1337 sql_help.c:2251 sql_help.c:2284 sql_help.c:2484 +#: sql_help.c:2794 +msgid "default_expr" +msgstr "默认_表达å¼" + +#: sql_help.c:1339 sql_help.c:1340 sql_help.c:1349 sql_help.c:1351 +#: sql_help.c:1355 sql_help.c:2797 sql_help.c:2798 sql_help.c:2807 +#: sql_help.c:2809 sql_help.c:2813 +msgid "index_parameters" +msgstr "ç´¢å¼•å‚æ•°" + +# describe.c:415 +# describe.c:543 +# describe.c:1477 +#: sql_help.c:1341 sql_help.c:1358 sql_help.c:2799 sql_help.c:2816 +msgid "reftable" +msgstr "所引用的表" + +# describe.c:744 +#: sql_help.c:1342 sql_help.c:1359 sql_help.c:2800 sql_help.c:2817 +msgid "refcolumn" +msgstr "所引用的列" + +#: sql_help.c:1343 sql_help.c:1344 sql_help.c:1360 sql_help.c:1361 +#: sql_help.c:2801 sql_help.c:2802 sql_help.c:2818 sql_help.c:2819 +#, fuzzy +#| msgid "initial_condition" +msgid "referential_action" +msgstr "åˆå§‹æ¡ä»¶" + +#: sql_help.c:1345 sql_help.c:2253 sql_help.c:2803 +msgid "and table_constraint is:" +msgstr "è¡¨çº¦æŸæ˜¯:" + +#: sql_help.c:1353 sql_help.c:2811 +msgid "exclude_element" +msgstr "排除项" + +# describe.c:512 +#: sql_help.c:1354 sql_help.c:2812 sql_help.c:4244 sql_help.c:4334 +#: sql_help.c:4483 sql_help.c:4636 sql_help.c:4701 +msgid "operator" +msgstr "è¿ç®—å­" + +# describe.c:937 +#: sql_help.c:1356 sql_help.c:2356 sql_help.c:2814 +msgid "predicate" +msgstr "è¿°è¯" + +#: sql_help.c:1362 msgid "and table_constraint_using_index is:" msgstr "table_constraint_using_index 是:" +#: sql_help.c:1365 sql_help.c:2827 +msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" +msgstr "在UNIQUE, PRIMARY KEYå’ŒEXCLUDEä¸­çš„ç´¢å¼•å‚æ•°æ˜¯ï¼š" + +#: sql_help.c:1370 sql_help.c:2832 +msgid "exclude_element in an EXCLUDE constraint is:" +msgstr "在EXCLUDE约æŸä¸­çš„æŽ’除项是:" + +#: sql_help.c:1373 sql_help.c:2351 sql_help.c:2759 sql_help.c:2772 +#: sql_help.c:2786 sql_help.c:2835 sql_help.c:3798 +msgid "opclass" +msgstr "æ“作符类型的åç§°" + # describe.c:1342 -#: sql_help.c:1065 sql_help.c:1068 sql_help.c:2335 +#: sql_help.c:1389 sql_help.c:1392 sql_help.c:2870 msgid "tablespace_option" msgstr "表空间_选项" -#: sql_help.c:1089 sql_help.c:1092 sql_help.c:1098 sql_help.c:1102 +#: sql_help.c:1413 sql_help.c:1416 sql_help.c:1422 sql_help.c:1426 msgid "token_type" msgstr "符å·ç±»åž‹" -#: sql_help.c:1090 sql_help.c:1093 +#: sql_help.c:1414 sql_help.c:1417 msgid "dictionary_name" msgstr "å­—å…¸åç§°" -#: sql_help.c:1095 sql_help.c:1099 +#: sql_help.c:1419 sql_help.c:1423 msgid "old_dictionary" msgstr "旧的字典" -#: sql_help.c:1096 sql_help.c:1100 +#: sql_help.c:1420 sql_help.c:1424 msgid "new_dictionary" msgstr "新的字典" -#: sql_help.c:1191 sql_help.c:1201 sql_help.c:1204 sql_help.c:1205 -#: sql_help.c:2484 +#: sql_help.c:1516 sql_help.c:1529 sql_help.c:1532 sql_help.c:1533 +#: sql_help.c:3021 msgid "attribute_name" msgstr "属性_åç§°" -#: sql_help.c:1192 +#: sql_help.c:1517 msgid "new_attribute_name" msgstr "new_attribute_name(新属性å)" -#: sql_help.c:1198 +#: sql_help.c:1523 sql_help.c:1527 msgid "new_enum_value" msgstr "new_enum_value(新枚举å)" -#: sql_help.c:1199 +#: sql_help.c:1524 +msgid "neighbor_enum_value" +msgstr "相邻的枚举值" + +#: sql_help.c:1526 msgid "existing_enum_value" -msgstr "existing_enum_value" +msgstr "现有枚举值" -#: sql_help.c:1269 sql_help.c:1852 sql_help.c:2178 sql_help.c:2562 -#: sql_help.c:2959 sql_help.c:3130 sql_help.c:3165 sql_help.c:3462 +#: sql_help.c:1601 sql_help.c:2236 sql_help.c:2245 sql_help.c:2622 +#: sql_help.c:3099 sql_help.c:3544 sql_help.c:3719 sql_help.c:3754 +#: sql_help.c:4052 msgid "server_name" msgstr "æœåС噍åç§°" # help.c:88 -#: sql_help.c:1297 sql_help.c:1300 sql_help.c:2577 +#: sql_help.c:1629 sql_help.c:1632 sql_help.c:3114 msgid "view_option_name" msgstr "view_option_name(视图选项å)" # help.c:88 -#: sql_help.c:1298 sql_help.c:2578 +#: sql_help.c:1630 sql_help.c:3115 msgid "view_option_value" msgstr "view_option_value(视图选项值)" -#: sql_help.c:1323 sql_help.c:3790 sql_help.c:3792 sql_help.c:3816 +#: sql_help.c:1651 sql_help.c:1652 sql_help.c:4609 sql_help.c:4610 +msgid "table_and_columns" +msgstr "表和列" + +#: sql_help.c:1653 sql_help.c:1897 sql_help.c:3591 sql_help.c:4611 +msgid "where option can be one of:" +msgstr "选项å¯ä»¥æ˜¯ä¸‹åˆ—内容之一:" + +#: sql_help.c:1654 sql_help.c:1655 sql_help.c:1899 sql_help.c:1902 +#: sql_help.c:2081 sql_help.c:3592 sql_help.c:3593 sql_help.c:3594 +#: sql_help.c:3595 sql_help.c:3596 sql_help.c:3597 sql_help.c:3598 +#: sql_help.c:4612 sql_help.c:4613 sql_help.c:4614 sql_help.c:4615 +#: sql_help.c:4616 sql_help.c:4617 sql_help.c:4618 sql_help.c:4619 +msgid "boolean" +msgstr "布尔" + +#: sql_help.c:1656 sql_help.c:4620 +msgid "and table_and_columns is:" +msgstr "并且表和列:" + +#: sql_help.c:1672 sql_help.c:4394 sql_help.c:4396 sql_help.c:4420 msgid "transaction_mode" msgstr "事务模å¼" -#: sql_help.c:1324 sql_help.c:3793 sql_help.c:3817 +#: sql_help.c:1673 sql_help.c:4397 sql_help.c:4421 msgid "where transaction_mode is one of:" msgstr "事务模å¼å¯ä»¥æ˜¯ä¸‹åˆ—选项之一:" -#: sql_help.c:1407 +#: sql_help.c:1682 sql_help.c:4254 sql_help.c:4263 sql_help.c:4267 +#: sql_help.c:4271 sql_help.c:4274 sql_help.c:4493 sql_help.c:4502 +#: sql_help.c:4506 sql_help.c:4510 sql_help.c:4513 sql_help.c:4711 +#: sql_help.c:4720 sql_help.c:4724 sql_help.c:4728 sql_help.c:4731 +msgid "argument" +msgstr "傿•°" + +#: sql_help.c:1772 msgid "relation_name" msgstr "relation_name(关系å)" # describe.c:1375 -#: sql_help.c:1412 sql_help.c:3126 sql_help.c:3458 +#: sql_help.c:1777 sql_help.c:3715 sql_help.c:4048 msgid "domain_name" msgstr "域_åç§°" # describe.c:1375 -#: sql_help.c:1434 +#: sql_help.c:1799 msgid "policy_name" msgstr "policy_name" # describe.c:1375 -#: sql_help.c:1438 +#: sql_help.c:1812 msgid "rule_name" msgstr "规则_åç§°" -#: sql_help.c:1455 +#: sql_help.c:1831 msgid "text" msgstr "文本" -#: sql_help.c:1480 sql_help.c:3308 sql_help.c:3496 +#: sql_help.c:1856 sql_help.c:3898 sql_help.c:4086 msgid "transaction_id" msgstr "事务_ID" # describe.c:1375 -#: sql_help.c:1511 sql_help.c:1517 sql_help.c:3234 +#: sql_help.c:1887 sql_help.c:1894 sql_help.c:3824 msgid "filename" msgstr "文件å" -#: sql_help.c:1512 sql_help.c:1518 sql_help.c:2121 sql_help.c:2122 -#: sql_help.c:2123 +#: sql_help.c:1888 sql_help.c:1895 sql_help.c:2562 sql_help.c:2563 +#: sql_help.c:2564 msgid "command" msgstr "命令" -#: sql_help.c:1516 sql_help.c:1992 sql_help.c:2321 sql_help.c:2579 -#: sql_help.c:2597 sql_help.c:3199 +# help.c:123 +#: sql_help.c:1890 sql_help.c:2561 sql_help.c:2973 sql_help.c:3150 +#: sql_help.c:3808 sql_help.c:4237 sql_help.c:4239 sql_help.c:4327 +#: sql_help.c:4329 sql_help.c:4476 sql_help.c:4478 sql_help.c:4581 +#: sql_help.c:4694 sql_help.c:4696 +msgid "condition" +msgstr "æ¡ä»¶" + +#: sql_help.c:1893 sql_help.c:2390 sql_help.c:2856 sql_help.c:3116 +#: sql_help.c:3134 sql_help.c:3789 msgid "query" msgstr "查询" -#: sql_help.c:1520 sql_help.c:3004 -msgid "where option can be one of:" -msgstr "选项å¯ä»¥æ˜¯ä¸‹åˆ—内容之一:" - # help.c:211 -#: sql_help.c:1521 +#: sql_help.c:1898 msgid "format_name" msgstr "æ ¼å¼_åç§°" -#: sql_help.c:1522 sql_help.c:1523 sql_help.c:1526 sql_help.c:3005 -#: sql_help.c:3006 sql_help.c:3007 sql_help.c:3008 sql_help.c:3009 -msgid "boolean" -msgstr "布尔" - -#: sql_help.c:1524 +#: sql_help.c:1900 msgid "delimiter_character" msgstr "分隔字符" -#: sql_help.c:1525 +#: sql_help.c:1901 msgid "null_string" msgstr "空字符串" -#: sql_help.c:1527 +#: sql_help.c:1903 msgid "quote_character" msgstr "引用字符" -#: sql_help.c:1528 +#: sql_help.c:1904 msgid "escape_character" msgstr "转义字符" # describe.c:365 -#: sql_help.c:1532 +#: sql_help.c:1908 msgid "encoding_name" msgstr "encoding_name(ç¼–ç å)" -#: sql_help.c:1543 +#: sql_help.c:1919 msgid "access_method_type" msgstr "access_method_type" # describe.c:526 -#: sql_help.c:1616 sql_help.c:1636 sql_help.c:1639 +#: sql_help.c:1990 sql_help.c:2009 sql_help.c:2012 msgid "arg_data_type" msgstr "arg_data_type" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:1617 sql_help.c:1640 sql_help.c:1652 +#: sql_help.c:1991 sql_help.c:2013 sql_help.c:2021 msgid "sfunc" msgstr "状æ€è½¬æ¢å‡½æ•°åç§°" # describe.c:526 -#: sql_help.c:1618 sql_help.c:1641 sql_help.c:1653 +#: sql_help.c:1992 sql_help.c:2014 sql_help.c:2022 msgid "state_data_type" msgstr "状æ€å€¼çš„æ•°æ®ç±»åž‹" # describe.c:526 -#: sql_help.c:1619 sql_help.c:1642 sql_help.c:1654 +#: sql_help.c:1993 sql_help.c:2015 sql_help.c:2023 msgid "state_data_size" msgstr "state_data_size" # describe.c:498 -#: sql_help.c:1620 sql_help.c:1643 sql_help.c:1655 +#: sql_help.c:1994 sql_help.c:2016 sql_help.c:2024 msgid "ffunc" msgstr "计算最终结果集的函数åç§°" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:1621 sql_help.c:1644 sql_help.c:1656 -#| msgid "minvfunc" +#: sql_help.c:1995 sql_help.c:2025 msgid "combinefunc" msgstr "combinefunc" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:1622 sql_help.c:1645 sql_help.c:1657 -#| msgid "sfunc" +#: sql_help.c:1996 sql_help.c:2026 msgid "serialfunc" msgstr "serialfunc" -#: sql_help.c:1623 sql_help.c:1646 sql_help.c:1658 +#: sql_help.c:1997 sql_help.c:2027 msgid "deserialfunc" msgstr "deserialfunc" -#: sql_help.c:1624 sql_help.c:1647 sql_help.c:1659 -#| msgid "server_type" -msgid "serialtype" -msgstr "serialtype" - -#: sql_help.c:1625 sql_help.c:1648 sql_help.c:1660 +#: sql_help.c:1998 sql_help.c:2017 sql_help.c:2028 msgid "initial_condition" msgstr "åˆå§‹æ¡ä»¶" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:1626 sql_help.c:1661 +#: sql_help.c:1999 sql_help.c:2029 msgid "msfunc" msgstr "msfunc" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:1627 sql_help.c:1662 +#: sql_help.c:2000 sql_help.c:2030 msgid "minvfunc" msgstr "minvfunc" # describe.c:526 -#: sql_help.c:1628 sql_help.c:1663 +#: sql_help.c:2001 sql_help.c:2031 msgid "mstate_data_type" msgstr "mstate_data_type" # describe.c:526 -#: sql_help.c:1629 sql_help.c:1664 +#: sql_help.c:2002 sql_help.c:2032 msgid "mstate_data_size" msgstr "mstate_data_size" # describe.c:498 -#: sql_help.c:1630 sql_help.c:1665 +#: sql_help.c:2003 sql_help.c:2033 msgid "mffunc" msgstr "mffunc" -#: sql_help.c:1631 sql_help.c:1666 +#: sql_help.c:2004 sql_help.c:2034 msgid "minitial_condition" msgstr "minitial_condition" # describe.c:512 -#: sql_help.c:1632 sql_help.c:1667 +#: sql_help.c:2005 sql_help.c:2035 msgid "sort_operator" msgstr "排åº_æ“作符" -#: sql_help.c:1649 +#: sql_help.c:2018 msgid "or the old syntax" msgstr "或者是旧的语法" # describe.c:1689 -#: sql_help.c:1651 +#: sql_help.c:2020 msgid "base_type" msgstr "基础_类型" # help.c:127 -#: sql_help.c:1706 +#: sql_help.c:2077 msgid "locale" msgstr "本地化语言" -#: sql_help.c:1707 sql_help.c:1743 +#: sql_help.c:2078 sql_help.c:2117 msgid "lc_collate" msgstr "排åºè§„则" @@ -4729,292 +5706,253 @@ msgstr "排åºè§„则" # describe.c:745 # describe.c:1478 # describe.c:1587 -#: sql_help.c:1708 sql_help.c:1744 +#: sql_help.c:2079 sql_help.c:2118 msgid "lc_ctype" msgstr "字符分类" +#: sql_help.c:2080 sql_help.c:4139 +msgid "provider" +msgstr "provider(æä¾›è€…)" + +#: sql_help.c:2082 sql_help.c:2173 +msgid "version" +msgstr "version(版本)" + # describe.c:1636 -#: sql_help.c:1710 +#: sql_help.c:2084 msgid "existing_collation" msgstr "existing_collation(当å‰çš„æœ¬åœ°åŒ–语言)" # describe.c:187 -#: sql_help.c:1720 +#: sql_help.c:2094 msgid "source_encoding" msgstr "æº_ç¼–ç " # describe.c:365 -#: sql_help.c:1721 +#: sql_help.c:2095 msgid "dest_encoding" msgstr "目的_ç¼–ç " -#: sql_help.c:1741 sql_help.c:2361 +#: sql_help.c:2115 sql_help.c:2896 msgid "template" msgstr "模版" # describe.c:365 -#: sql_help.c:1742 +#: sql_help.c:2116 msgid "encoding" msgstr "字符集编ç " -#: sql_help.c:1768 +#: sql_help.c:2142 msgid "constraint" msgstr "约æŸ" # describe.c:1174 -#: sql_help.c:1769 +#: sql_help.c:2143 msgid "where constraint is:" msgstr "çº¦æŸæ˜¯:" -#: sql_help.c:1783 sql_help.c:2118 sql_help.c:2433 +#: sql_help.c:2157 sql_help.c:2559 sql_help.c:2969 msgid "event" msgstr "事件" -#: sql_help.c:1784 +#: sql_help.c:2158 msgid "filter_variable" msgstr "过滤器å˜é‡" -#: sql_help.c:1799 -msgid "version" -msgstr "version(版本)" - -#: sql_help.c:1800 +#: sql_help.c:2174 msgid "old_version" msgstr "è€ç‰ˆæœ¬" # describe.c:1174 -#: sql_help.c:1855 sql_help.c:2267 +#: sql_help.c:2248 sql_help.c:2791 msgid "where column_constraint is:" msgstr "åˆ—çš„çº¦æŸæ˜¯:" -# describe.c:1639 -#: sql_help.c:1858 sql_help.c:1890 sql_help.c:2270 -msgid "default_expr" -msgstr "默认_表达å¼" - -#: sql_help.c:1859 sql_help.c:2277 -msgid "and table_constraint is:" -msgstr "è¡¨çº¦æŸæ˜¯:" +#: sql_help.c:2252 sql_help.c:2795 +msgid "generation_expr" +msgstr "" # describe.c:1689 -#: sql_help.c:1891 +#: sql_help.c:2285 msgid "rettype" msgstr "返回类型" -#: sql_help.c:1893 +#: sql_help.c:2287 msgid "column_type" msgstr "列的类型" # describe.c:977 -#: sql_help.c:1901 +#: sql_help.c:2296 sql_help.c:2490 msgid "definition" msgstr "定义" -#: sql_help.c:1902 +#: sql_help.c:2297 sql_help.c:2491 msgid "obj_file" msgstr "目标文件" -#: sql_help.c:1903 +#: sql_help.c:2298 sql_help.c:2492 msgid "link_symbol" msgstr "链接_符å·" -#: sql_help.c:1904 -msgid "attribute" -msgstr "属性" - -#: sql_help.c:1938 sql_help.c:2103 sql_help.c:2551 +#: sql_help.c:2332 sql_help.c:2544 sql_help.c:3088 msgid "uid" msgstr "uid" -#: sql_help.c:1952 +#: sql_help.c:2347 sql_help.c:2386 sql_help.c:2760 sql_help.c:2773 +#: sql_help.c:2787 sql_help.c:2852 msgid "method" msgstr "方法" -#: sql_help.c:1956 sql_help.c:2302 sql_help.c:3208 -msgid "opclass" -msgstr "æ“作符类型的åç§°" - -# describe.c:937 -#: sql_help.c:1960 sql_help.c:2288 -msgid "predicate" -msgstr "è¿°è¯" - -#: sql_help.c:1972 +#: sql_help.c:2368 msgid "call_handler" msgstr "调用函数" -#: sql_help.c:1973 +#: sql_help.c:2369 msgid "inline_handler" msgstr "匿å代ç å—" # describe.c:498 -#: sql_help.c:1974 +#: sql_help.c:2370 msgid "valfunction" msgstr "验è¯å‡½æ•°" -#: sql_help.c:2010 +#: sql_help.c:2408 msgid "com_op" msgstr "äº¤æ¢æ“作符" -#: sql_help.c:2011 +#: sql_help.c:2409 msgid "neg_op" msgstr "å–è´Ÿæ“作符" -#: sql_help.c:2029 +#: sql_help.c:2427 msgid "family_name" msgstr "æ“作符群的åç§°" # describe.c:1635 -#: sql_help.c:2040 +#: sql_help.c:2438 msgid "storage_type" msgstr "存储类型" -# help.c:123 -#: sql_help.c:2120 sql_help.c:2436 sql_help.c:2613 sql_help.c:3218 -#: sql_help.c:3633 sql_help.c:3635 sql_help.c:3723 sql_help.c:3725 -#: sql_help.c:3872 sql_help.c:3874 sql_help.c:3977 sql_help.c:4066 -#: sql_help.c:4068 -msgid "condition" -msgstr "æ¡ä»¶" - -#: sql_help.c:2124 sql_help.c:2439 +#: sql_help.c:2565 sql_help.c:2976 msgid "where event can be one of:" msgstr "事件å¯ä»¥ä¸‹è¿°ä¹‹ä¸€:" -#: sql_help.c:2143 sql_help.c:2145 +#: sql_help.c:2584 sql_help.c:2586 msgid "schema_element" msgstr "模å¼ä¸­å¯¹è±¡" -#: sql_help.c:2179 +#: sql_help.c:2623 msgid "server_type" msgstr "æœåŠ¡å™¨ç±»åž‹" -#: sql_help.c:2180 +#: sql_help.c:2624 msgid "server_version" msgstr "æœåŠ¡å™¨ç‰ˆæœ¬" -#: sql_help.c:2181 sql_help.c:3128 sql_help.c:3460 +#: sql_help.c:2625 sql_help.c:3717 sql_help.c:4050 msgid "fdw_name" msgstr "外部数æ®å°è£…器的åç§°" +#: sql_help.c:2638 +msgid "statistics_name" +msgstr "统计信æ¯_åç§°" + +#: sql_help.c:2639 +msgid "statistics_kind" +msgstr "统计信æ¯_æ–¹å¼" + +# describe.c:498 +#: sql_help.c:2653 +msgid "subscription_name" +msgstr "订阅_åç§°" + # describe.c:1688 -#: sql_help.c:2253 +#: sql_help.c:2753 msgid "source_table" msgstr "æºè¡¨" # help.c:88 -#: sql_help.c:2254 +#: sql_help.c:2754 msgid "like_option" msgstr "like选项" -#: sql_help.c:2271 sql_help.c:2272 sql_help.c:2281 sql_help.c:2283 -#: sql_help.c:2287 -msgid "index_parameters" -msgstr "ç´¢å¼•å‚æ•°" - -# describe.c:415 -# describe.c:543 -# describe.c:1477 -#: sql_help.c:2273 sql_help.c:2290 -msgid "reftable" -msgstr "所引用的表" - -# describe.c:744 -#: sql_help.c:2274 sql_help.c:2291 -msgid "refcolumn" -msgstr "所引用的列" - -#: sql_help.c:2285 -msgid "exclude_element" -msgstr "排除项" - -# describe.c:512 -#: sql_help.c:2286 sql_help.c:3640 sql_help.c:3730 sql_help.c:3879 -#: sql_help.c:4008 sql_help.c:4073 -msgid "operator" -msgstr "è¿ç®—å­" - -#: sql_help.c:2294 +#: sql_help.c:2820 msgid "and like_option is:" msgstr "like_选项是" -#: sql_help.c:2295 -msgid "index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:" -msgstr "在UNIQUE, PRIMARY KEYå’ŒEXCLUDEä¸­çš„ç´¢å¼•å‚æ•°æ˜¯ï¼š" - -#: sql_help.c:2299 -msgid "exclude_element in an EXCLUDE constraint is:" -msgstr "在EXCLUDE约æŸä¸­çš„æŽ’除项是:" - -#: sql_help.c:2334 +#: sql_help.c:2869 msgid "directory" msgstr "目录" -#: sql_help.c:2348 +#: sql_help.c:2883 msgid "parser_name" msgstr "è§£æžå™¨åç§° " -#: sql_help.c:2349 +#: sql_help.c:2884 msgid "source_config" msgstr "已存在的文本æœç´¢é…ç½®åç§°" # describe.c:498 -#: sql_help.c:2378 +#: sql_help.c:2913 msgid "start_function" msgstr "å¯åЍ_函数" # sql_help.h:249 -#: sql_help.c:2379 +#: sql_help.c:2914 msgid "gettoken_function" msgstr "获å–下一个符å·å‡½æ•°çš„åç§°" # describe.c:498 -#: sql_help.c:2380 +#: sql_help.c:2915 msgid "end_function" msgstr "结æŸ_函数" # describe.c:498 -#: sql_help.c:2381 +#: sql_help.c:2916 msgid "lextypes_function" msgstr "语义类型_函数" # describe.c:498 -#: sql_help.c:2382 +#: sql_help.c:2917 msgid "headline_function" msgstr "标题_函数" # describe.c:498 -#: sql_help.c:2394 +#: sql_help.c:2929 msgid "init_function" msgstr "åˆå§‹åŒ–_函数" # describe.c:498 -#: sql_help.c:2395 +#: sql_help.c:2930 msgid "lexize_function" msgstr "LEXIZE函数" # describe.c:498 -#: sql_help.c:2408 +#: sql_help.c:2943 msgid "from_sql_function_name" msgstr "from_sql_function_name" # describe.c:498 -#: sql_help.c:2410 +#: sql_help.c:2945 msgid "to_sql_function_name" msgstr "to_sql_function_name" -#: sql_help.c:2435 +#: sql_help.c:2971 msgid "referenced_table_name" msgstr "被引用表的åç§°" -#: sql_help.c:2438 +#: sql_help.c:2972 +msgid "transition_relation_name" +msgstr "transition_relation_name(转æ¢å…³ç³»å)" + +#: sql_help.c:2975 msgid "arguments" msgstr "傿•°" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:2488 sql_help.c:3568 +#: sql_help.c:3025 sql_help.c:4172 msgid "label" msgstr "标签" @@ -5022,1189 +5960,1249 @@ msgstr "标签" # describe.c:745 # describe.c:1478 # describe.c:1587 -#: sql_help.c:2490 +#: sql_help.c:3027 msgid "subtype" msgstr "å­ç±»åž‹" # describe.c:512 -#: sql_help.c:2491 +#: sql_help.c:3028 msgid "subtype_operator_class" msgstr "subtype_operator_class(å­ç±»åž‹_æ“作符_ç±»)" # describe.c:498 -#: sql_help.c:2493 +#: sql_help.c:3030 msgid "canonical_function" msgstr "标准_函数" # describe.c:498 -#: sql_help.c:2494 +#: sql_help.c:3031 msgid "subtype_diff_function" msgstr "subtype_diff_function(å­ç±»åž‹_区分_函数)" # describe.c:498 -#: sql_help.c:2496 +#: sql_help.c:3033 msgid "input_function" msgstr "输入_函数" # describe.c:498 -#: sql_help.c:2497 +#: sql_help.c:3034 msgid "output_function" msgstr "输出_函数" # sql_help.h:249 -#: sql_help.c:2498 +#: sql_help.c:3035 msgid "receive_function" msgstr "接收_函数" # describe.c:498 -#: sql_help.c:2499 +#: sql_help.c:3036 msgid "send_function" msgstr "å‘é€_函数" -#: sql_help.c:2500 +#: sql_help.c:3037 msgid "type_modifier_input_function" msgstr "类型修改器数组输入函数åç§°" -#: sql_help.c:2501 +#: sql_help.c:3038 msgid "type_modifier_output_function" msgstr "类型修改器输出函数åç§°" # describe.c:498 -#: sql_help.c:2502 +#: sql_help.c:3039 msgid "analyze_function" msgstr "分æž_函数" -#: sql_help.c:2503 +#: sql_help.c:3040 msgid "internallength" msgstr "内部长度" # describe.c:1693 -#: sql_help.c:2504 +#: sql_help.c:3041 msgid "alignment" msgstr "é¡ºåºæŽ’åˆ—(alignment)" # describe.c:1635 -#: sql_help.c:2505 +#: sql_help.c:3042 msgid "storage" msgstr "存储" -#: sql_help.c:2506 +#: sql_help.c:3043 msgid "like_type" msgstr "LIKE类型(like_type)" -#: sql_help.c:2507 +#: sql_help.c:3044 msgid "category" msgstr "类型" -#: sql_help.c:2508 +#: sql_help.c:3045 msgid "preferred" msgstr "优先" # describe.c:1639 -#: sql_help.c:2509 +#: sql_help.c:3046 msgid "default" msgstr "默认" -#: sql_help.c:2510 +#: sql_help.c:3047 msgid "element" msgstr "æˆå‘˜é¡¹" -#: sql_help.c:2511 +#: sql_help.c:3048 msgid "delimiter" msgstr "分隔符" -#: sql_help.c:2512 +#: sql_help.c:3049 msgid "collatable" msgstr "è¦æ ¡å¯¹çš„" -#: sql_help.c:2609 sql_help.c:3194 sql_help.c:3628 sql_help.c:3717 -#: sql_help.c:3867 sql_help.c:3967 sql_help.c:4061 +#: sql_help.c:3146 sql_help.c:3784 sql_help.c:4232 sql_help.c:4321 +#: sql_help.c:4471 sql_help.c:4571 sql_help.c:4689 msgid "with_query" msgstr "with查询语å¥(with_query)" -#: sql_help.c:2611 sql_help.c:3196 sql_help.c:3647 sql_help.c:3653 -#: sql_help.c:3656 sql_help.c:3660 sql_help.c:3664 sql_help.c:3672 -#: sql_help.c:3886 sql_help.c:3892 sql_help.c:3895 sql_help.c:3899 -#: sql_help.c:3903 sql_help.c:3911 sql_help.c:3969 sql_help.c:4080 -#: sql_help.c:4086 sql_help.c:4089 sql_help.c:4093 sql_help.c:4097 -#: sql_help.c:4105 +#: sql_help.c:3148 sql_help.c:3786 sql_help.c:4251 sql_help.c:4257 +#: sql_help.c:4260 sql_help.c:4264 sql_help.c:4268 sql_help.c:4276 +#: sql_help.c:4490 sql_help.c:4496 sql_help.c:4499 sql_help.c:4503 +#: sql_help.c:4507 sql_help.c:4515 sql_help.c:4573 sql_help.c:4708 +#: sql_help.c:4714 sql_help.c:4717 sql_help.c:4721 sql_help.c:4725 +#: sql_help.c:4733 msgid "alias" msgstr "别å" -#: sql_help.c:2612 +#: sql_help.c:3149 msgid "using_list" msgstr "USING列表(using_list)" -#: sql_help.c:2614 sql_help.c:3035 sql_help.c:3275 sql_help.c:3978 +#: sql_help.c:3151 sql_help.c:3624 sql_help.c:3865 sql_help.c:4582 msgid "cursor_name" msgstr "游标åç§°" -#: sql_help.c:2615 sql_help.c:3202 sql_help.c:3979 +#: sql_help.c:3152 sql_help.c:3792 sql_help.c:4583 msgid "output_expression" msgstr "输出表达å¼" -#: sql_help.c:2616 sql_help.c:3203 sql_help.c:3631 sql_help.c:3720 -#: sql_help.c:3870 sql_help.c:3980 sql_help.c:4064 +#: sql_help.c:3153 sql_help.c:3793 sql_help.c:4235 sql_help.c:4324 +#: sql_help.c:4474 sql_help.c:4584 sql_help.c:4692 msgid "output_name" msgstr "输出åç§°" -#: sql_help.c:2632 +#: sql_help.c:3169 msgid "code" msgstr "ç¼–ç " -#: sql_help.c:2983 +#: sql_help.c:3568 msgid "parameter" msgstr "傿•°" -#: sql_help.c:3002 sql_help.c:3003 sql_help.c:3300 +#: sql_help.c:3589 sql_help.c:3590 sql_help.c:3890 msgid "statement" msgstr "语å¥" # help.c:123 -#: sql_help.c:3034 sql_help.c:3274 +#: sql_help.c:3623 sql_help.c:3864 msgid "direction" msgstr "æ–¹å‘" -#: sql_help.c:3036 sql_help.c:3276 +#: sql_help.c:3625 sql_help.c:3866 msgid "where direction can be empty or one of:" msgstr "æ–¹å‘å¯ä»¥ä¸ºç©ºæˆ–者是下列选项之一:" -#: sql_help.c:3037 sql_help.c:3038 sql_help.c:3039 sql_help.c:3040 -#: sql_help.c:3041 sql_help.c:3277 sql_help.c:3278 sql_help.c:3279 -#: sql_help.c:3280 sql_help.c:3281 sql_help.c:3641 sql_help.c:3643 -#: sql_help.c:3731 sql_help.c:3733 sql_help.c:3880 sql_help.c:3882 -#: sql_help.c:4009 sql_help.c:4011 sql_help.c:4074 sql_help.c:4076 +#: sql_help.c:3626 sql_help.c:3627 sql_help.c:3628 sql_help.c:3629 +#: sql_help.c:3630 sql_help.c:3867 sql_help.c:3868 sql_help.c:3869 +#: sql_help.c:3870 sql_help.c:3871 sql_help.c:4245 sql_help.c:4247 +#: sql_help.c:4335 sql_help.c:4337 sql_help.c:4484 sql_help.c:4486 +#: sql_help.c:4637 sql_help.c:4639 sql_help.c:4702 sql_help.c:4704 msgid "count" msgstr "查询所用返回记录的最大数é‡" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:3121 sql_help.c:3453 +#: sql_help.c:3710 sql_help.c:4043 msgid "sequence_name" msgstr "åºåˆ—åç§°" -#: sql_help.c:3134 sql_help.c:3466 +#: sql_help.c:3723 sql_help.c:4056 msgid "arg_name" msgstr "傿•°åç§°" # describe.c:1689 -#: sql_help.c:3135 sql_help.c:3467 +#: sql_help.c:3724 sql_help.c:4057 msgid "arg_type" msgstr "傿•°ç±»åž‹" -#: sql_help.c:3140 sql_help.c:3472 +#: sql_help.c:3729 sql_help.c:4062 msgid "loid" msgstr "loid" # sql_help.h:277 -#: sql_help.c:3163 +#: sql_help.c:3752 msgid "remote_schema" msgstr "remote_schema" # help.c:127 -#: sql_help.c:3166 +#: sql_help.c:3755 msgid "local_schema" msgstr "local_schema" -#: sql_help.c:3200 +#: sql_help.c:3790 msgid "conflict_target" -msgstr "conflict_target" +msgstr "冲çªç›®æ ‡" # describe.c:498 -#: sql_help.c:3201 +#: sql_help.c:3791 msgid "conflict_action" -msgstr "conflict_action" +msgstr "冲çªè¡ŒåЍ" -#: sql_help.c:3204 +#: sql_help.c:3794 msgid "where conflict_target can be one of:" msgstr "这里conflict_targetå¯ä»¥æ˜¯ä¸‹åˆ—之一:" # describe.c:1375 -#: sql_help.c:3205 -#| msgid "new_column_name" +#: sql_help.c:3795 msgid "index_column_name" -msgstr "index_column_name" +msgstr "索引列åç§°" -#: sql_help.c:3206 -#| msgid "using_expression" +#: sql_help.c:3796 msgid "index_expression" -msgstr "index_expression" +msgstr "索引表达å¼" # describe.c:937 -#: sql_help.c:3209 +#: sql_help.c:3799 msgid "index_predicate" msgstr "index_predicate" -#: sql_help.c:3211 +#: sql_help.c:3801 msgid "and conflict_action is one of:" msgstr "并且conflict_action是下列之一:" -#: sql_help.c:3217 sql_help.c:3975 +#: sql_help.c:3807 sql_help.c:4579 msgid "sub-SELECT" msgstr "sub-SELECT" -#: sql_help.c:3226 sql_help.c:3289 sql_help.c:3951 +#: sql_help.c:3816 sql_help.c:3879 sql_help.c:4555 msgid "channel" msgstr "通é“" -#: sql_help.c:3248 +#: sql_help.c:3838 msgid "lockmode" msgstr "锿¨¡å¼" -#: sql_help.c:3249 +#: sql_help.c:3839 msgid "where lockmode is one of:" msgstr "锿¨¡å¼å¯ä»¥æ˜¯ä¸‹åˆ—选项之一:" -#: sql_help.c:3290 +#: sql_help.c:3880 msgid "payload" msgstr "消æ¯ä¸­è´Ÿè½½æµé‡(payload)" -#: sql_help.c:3317 +#: sql_help.c:3907 msgid "old_role" msgstr "旧的角色" -#: sql_help.c:3318 +#: sql_help.c:3908 msgid "new_role" msgstr "新的角色" # sql_help.h:382 -#: sql_help.c:3343 sql_help.c:3504 sql_help.c:3512 +#: sql_help.c:3933 sql_help.c:4094 sql_help.c:4102 msgid "savepoint_name" msgstr "ä¿å­˜ç‚¹åç§°" -#: sql_help.c:3545 -msgid "provider" -msgstr "provider(æä¾›è€…)" - -#: sql_help.c:3632 sql_help.c:3674 sql_help.c:3676 sql_help.c:3722 -#: sql_help.c:3871 sql_help.c:3913 sql_help.c:3915 sql_help.c:4065 -#: sql_help.c:4107 sql_help.c:4109 +#: sql_help.c:4236 sql_help.c:4278 sql_help.c:4280 sql_help.c:4326 +#: sql_help.c:4475 sql_help.c:4517 sql_help.c:4519 sql_help.c:4693 +#: sql_help.c:4735 sql_help.c:4737 msgid "from_item" msgstr "from列表中项" -#: sql_help.c:3634 sql_help.c:3686 sql_help.c:3873 sql_help.c:3925 -#: sql_help.c:4067 sql_help.c:4119 +#: sql_help.c:4238 sql_help.c:4290 sql_help.c:4477 sql_help.c:4529 +#: sql_help.c:4695 sql_help.c:4747 msgid "grouping_element" msgstr "grouping_element" -#: sql_help.c:3636 sql_help.c:3726 sql_help.c:3875 sql_help.c:4069 +#: sql_help.c:4240 sql_help.c:4330 sql_help.c:4479 sql_help.c:4697 msgid "window_name" msgstr "窗å£åç§°" # describe.c:977 -#: sql_help.c:3637 sql_help.c:3727 sql_help.c:3876 sql_help.c:4070 +#: sql_help.c:4241 sql_help.c:4331 sql_help.c:4480 sql_help.c:4698 msgid "window_definition" msgstr "窗å£å®šä¹‰" -#: sql_help.c:3638 sql_help.c:3652 sql_help.c:3690 sql_help.c:3728 -#: sql_help.c:3877 sql_help.c:3891 sql_help.c:3929 sql_help.c:4071 -#: sql_help.c:4085 sql_help.c:4123 +#: sql_help.c:4242 sql_help.c:4256 sql_help.c:4294 sql_help.c:4332 +#: sql_help.c:4481 sql_help.c:4495 sql_help.c:4533 sql_help.c:4699 +#: sql_help.c:4713 sql_help.c:4751 msgid "select" msgstr "查询" -#: sql_help.c:3645 sql_help.c:3884 sql_help.c:4078 +#: sql_help.c:4249 sql_help.c:4488 sql_help.c:4706 msgid "where from_item can be one of:" msgstr "from 列表中的项å¯ä»¥æ˜¯ä¸‹åˆ—内容之一" -#: sql_help.c:3648 sql_help.c:3654 sql_help.c:3657 sql_help.c:3661 -#: sql_help.c:3673 sql_help.c:3887 sql_help.c:3893 sql_help.c:3896 -#: sql_help.c:3900 sql_help.c:3912 sql_help.c:4081 sql_help.c:4087 -#: sql_help.c:4090 sql_help.c:4094 sql_help.c:4106 +#: sql_help.c:4252 sql_help.c:4258 sql_help.c:4261 sql_help.c:4265 +#: sql_help.c:4277 sql_help.c:4491 sql_help.c:4497 sql_help.c:4500 +#: sql_help.c:4504 sql_help.c:4516 sql_help.c:4709 sql_help.c:4715 +#: sql_help.c:4718 sql_help.c:4722 sql_help.c:4734 msgid "column_alias" msgstr "列的别å" -#: sql_help.c:3649 sql_help.c:3888 sql_help.c:4082 +#: sql_help.c:4253 sql_help.c:4492 sql_help.c:4710 msgid "sampling_method" msgstr "sampling_method" -#: sql_help.c:3650 sql_help.c:3659 sql_help.c:3663 sql_help.c:3667 -#: sql_help.c:3670 sql_help.c:3889 sql_help.c:3898 sql_help.c:3902 -#: sql_help.c:3906 sql_help.c:3909 sql_help.c:4083 sql_help.c:4092 -#: sql_help.c:4096 sql_help.c:4100 sql_help.c:4103 -msgid "argument" -msgstr "傿•°" - -#: sql_help.c:3651 sql_help.c:3890 sql_help.c:4084 +#: sql_help.c:4255 sql_help.c:4494 sql_help.c:4712 msgid "seed" msgstr "ç§å­" -#: sql_help.c:3655 sql_help.c:3688 sql_help.c:3894 sql_help.c:3927 -#: sql_help.c:4088 sql_help.c:4121 +#: sql_help.c:4259 sql_help.c:4292 sql_help.c:4498 sql_help.c:4531 +#: sql_help.c:4716 sql_help.c:4749 msgid "with_query_name" msgstr "WITH查询语å¥åç§°(with_query_name)" # describe.c:977 -#: sql_help.c:3665 sql_help.c:3668 sql_help.c:3671 sql_help.c:3904 -#: sql_help.c:3907 sql_help.c:3910 sql_help.c:4098 sql_help.c:4101 -#: sql_help.c:4104 +#: sql_help.c:4269 sql_help.c:4272 sql_help.c:4275 sql_help.c:4508 +#: sql_help.c:4511 sql_help.c:4514 sql_help.c:4726 sql_help.c:4729 +#: sql_help.c:4732 msgid "column_definition" msgstr "列定义" -#: sql_help.c:3675 sql_help.c:3914 sql_help.c:4108 +#: sql_help.c:4279 sql_help.c:4518 sql_help.c:4736 msgid "join_type" msgstr "连接æ“作的类型" -#: sql_help.c:3677 sql_help.c:3916 sql_help.c:4110 +#: sql_help.c:4281 sql_help.c:4520 sql_help.c:4738 msgid "join_condition" msgstr "用连接æ“作的æ¡ä»¶" -#: sql_help.c:3678 sql_help.c:3917 sql_help.c:4111 +#: sql_help.c:4282 sql_help.c:4521 sql_help.c:4739 msgid "join_column" msgstr "用于连接æ“作的列" -#: sql_help.c:3679 sql_help.c:3918 sql_help.c:4112 +#: sql_help.c:4283 sql_help.c:4522 sql_help.c:4740 msgid "and grouping_element can be one of:" msgstr "并且grouping_elementå¯ä»¥æ˜¯ä¸‹åˆ—之一:" -#: sql_help.c:3687 sql_help.c:3926 sql_help.c:4120 +#: sql_help.c:4291 sql_help.c:4530 sql_help.c:4748 msgid "and with_query is:" msgstr "withæŸ¥è¯¢è¯­å¥æ˜¯ï¼š" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:3691 sql_help.c:3930 sql_help.c:4124 +#: sql_help.c:4295 sql_help.c:4534 sql_help.c:4752 msgid "values" msgstr "值" -#: sql_help.c:3692 sql_help.c:3931 sql_help.c:4125 +#: sql_help.c:4296 sql_help.c:4535 sql_help.c:4753 msgid "insert" msgstr "insert" -#: sql_help.c:3693 sql_help.c:3932 sql_help.c:4126 +#: sql_help.c:4297 sql_help.c:4536 sql_help.c:4754 msgid "update" msgstr "update" -#: sql_help.c:3694 sql_help.c:3933 sql_help.c:4127 +#: sql_help.c:4298 sql_help.c:4537 sql_help.c:4755 msgid "delete" msgstr "delete" # describe.c:415 # describe.c:543 # describe.c:1477 -#: sql_help.c:3721 +#: sql_help.c:4325 msgid "new_table" msgstr "新的表" -#: sql_help.c:3746 +#: sql_help.c:4350 msgid "timezone" msgstr "时区" -#: sql_help.c:3791 +#: sql_help.c:4395 msgid "snapshot_id" msgstr "å¿«ç…§id" -#: sql_help.c:3976 +#: sql_help.c:4580 msgid "from_list" msgstr "from列表(from_list)" -#: sql_help.c:4007 +#: sql_help.c:4635 msgid "sort_expression" msgstr "排åºè¡¨è¾¾å¼" # sql_help.h:25 # sql_help.h:373 -#: sql_help.c:4134 sql_help.c:4874 +#: sql_help.c:4762 sql_help.c:5740 msgid "abort the current transaction" msgstr "中止目å‰çš„事务" # sql_help.h:29 -#: sql_help.c:4139 +#: sql_help.c:4768 msgid "change the definition of an aggregate function" msgstr "更改èšé›†å‡½æ•°çš„定义" # sql_help.h:45 -#: sql_help.c:4144 +#: sql_help.c:4774 msgid "change the definition of a collation" msgstr "更改校对规则的定义" # sql_help.h:33 -#: sql_help.c:4149 +#: sql_help.c:4780 msgid "change the definition of a conversion" msgstr "更改一个字符编ç è½¬æ¢çš„定义" # sql_help.h:37 -#: sql_help.c:4154 +#: sql_help.c:4786 msgid "change a database" msgstr "更改一个数æ®åº“" # sql_help.h:325 -#: sql_help.c:4159 +#: sql_help.c:4792 msgid "define default access privileges" msgstr "定义默认的访问æƒé™" # sql_help.h:41 -#: sql_help.c:4164 +#: sql_help.c:4798 msgid "change the definition of a domain" msgstr "更改共åŒå€¼åŸŸçš„定义" # sql_help.h:85 -#: sql_help.c:4169 +#: sql_help.c:4804 msgid "change the definition of an event trigger" msgstr "更改事件触å‘器的定义" # sql_help.h:33 -#: sql_help.c:4174 +#: sql_help.c:4810 msgid "change the definition of an extension" msgstr "更改扩展的定义" # sql_help.h:85 -#: sql_help.c:4179 +#: sql_help.c:4816 msgid "change the definition of a foreign-data wrapper" msgstr "更改外部数æ®å°è£…器的定义" # sql_help.h:85 -#: sql_help.c:4184 +#: sql_help.c:4822 msgid "change the definition of a foreign table" msgstr "更改外部表的定义" # sql_help.h:45 -#: sql_help.c:4189 +#: sql_help.c:4828 msgid "change the definition of a function" msgstr "更改函数的定义" -#: sql_help.c:4194 +#: sql_help.c:4834 msgid "change role name or membership" msgstr "更改角色å称或æˆå‘˜çжæ€" # sql_help.h:53 -#: sql_help.c:4199 +#: sql_help.c:4840 msgid "change the definition of an index" msgstr "更改索引的定义" # sql_help.h:57 -#: sql_help.c:4204 +#: sql_help.c:4846 msgid "change the definition of a procedural language" msgstr "更改程åºè¯­è¨€çš„定义" # sql_help.h:77 -#: sql_help.c:4209 +#: sql_help.c:4852 msgid "change the definition of a large object" msgstr "更改大对象的定义" # sql_help.h:53 -#: sql_help.c:4214 +#: sql_help.c:4858 msgid "change the definition of a materialized view" msgstr "更改物化视图的定义" # sql_help.h:65 -#: sql_help.c:4219 +#: sql_help.c:4864 msgid "change the definition of an operator" msgstr "更改è¿ç®—å­çš„定义" # sql_help.h:61 -#: sql_help.c:4224 +#: sql_help.c:4870 msgid "change the definition of an operator class" msgstr "更改è¿ç®—å­ç±»åˆ«çš„定义" # sql_help.h:65 -#: sql_help.c:4229 +#: sql_help.c:4876 msgid "change the definition of an operator family" msgstr "更改一个è¿ç®—å­å®¶æ—的识别" # sql_help.h:41 -#: sql_help.c:4234 -#| msgid "change the definition of a policy" +#: sql_help.c:4882 msgid "change the definition of a row level security policy" msgstr "更改一æ¡è¡Œçº§å®‰å…¨æ€§ç­–略的定义" +# sql_help.h:77 +#: sql_help.c:4888 +msgid "change the definition of a procedure" +msgstr "更改程åºçš„定义" + +# sql_help.h:45 +#: sql_help.c:4894 +msgid "change the definition of a publication" +msgstr "更改出版的定义" + # sql_help.h:37 -#: sql_help.c:4239 sql_help.c:4309 +#: sql_help.c:4900 sql_help.c:5002 msgid "change a database role" msgstr "更改数æ®åº“角色" # sql_help.h:77 -#: sql_help.c:4244 +#: sql_help.c:4906 +msgid "change the definition of a routine" +msgstr "更改程åºçš„定义" + +# sql_help.h:77 +#: sql_help.c:4912 msgid "change the definition of a rule" msgstr "更改规则的定义" # sql_help.h:69 -#: sql_help.c:4249 +#: sql_help.c:4918 msgid "change the definition of a schema" msgstr "更改架构模å¼çš„定义" # sql_help.h:73 -#: sql_help.c:4254 +#: sql_help.c:4924 msgid "change the definition of a sequence generator" msgstr "更改åºåˆ—数产生器的定义" # sql_help.h:85 -#: sql_help.c:4259 +#: sql_help.c:4930 msgid "change the definition of a foreign server" msgstr "更改外部æœåŠ¡å™¨çš„å®šä¹‰" +# sql_help.h:33 +#: sql_help.c:4936 +msgid "change the definition of an extended statistics object" +msgstr "更改扩展统计信æ¯å¯¹è±¡çš„定义" + +# sql_help.h:45 +#: sql_help.c:4942 +msgid "change the definition of a subscription" +msgstr "更改订阅的定义" + # sql_help.h:366 -#: sql_help.c:4264 +#: sql_help.c:4948 msgid "change a server configuration parameter" msgstr "更改æœåŠ¡å™¨çš„é…ç½®å‚æ•°" # sql_help.h:77 -#: sql_help.c:4269 +#: sql_help.c:4954 msgid "change the definition of a table" msgstr "更改数æ®è¡¨çš„定义" # sql_help.h:81 -#: sql_help.c:4274 +#: sql_help.c:4960 msgid "change the definition of a tablespace" msgstr "更改表空间的定义" # sql_help.h:33 -#: sql_help.c:4279 +#: sql_help.c:4966 msgid "change the definition of a text search configuration" msgstr "更改一个文本æœç´¢ç»„æ€çš„定义" # sql_help.h:45 -#: sql_help.c:4284 +#: sql_help.c:4972 msgid "change the definition of a text search dictionary" msgstr "更改一个文本æœç´¢å­—典的定义" # sql_help.h:81 -#: sql_help.c:4289 +#: sql_help.c:4978 msgid "change the definition of a text search parser" msgstr "更改一个文本æœç´¢å‰–æžå™¨çš„定义" # sql_help.h:69 -#: sql_help.c:4294 +#: sql_help.c:4984 msgid "change the definition of a text search template" msgstr "更改一个文本æœç´¢æ¨¡ç‰ˆçš„定义" # sql_help.h:85 -#: sql_help.c:4299 +#: sql_help.c:4990 msgid "change the definition of a trigger" msgstr "更改触å‘器的定义" # sql_help.h:89 -#: sql_help.c:4304 +#: sql_help.c:4996 msgid "change the definition of a type" msgstr "更改数æ®ç±»åž‹çš„定义" # sql_help.h:41 -#: sql_help.c:4314 +#: sql_help.c:5008 msgid "change the definition of a user mapping" msgstr "更改用户映射的定义" # sql_help.h:53 -#: sql_help.c:4319 +#: sql_help.c:5014 msgid "change the definition of a view" msgstr "更改视图的定义" # sql_help.h:97 -#: sql_help.c:4324 +#: sql_help.c:5020 msgid "collect statistics about a database" msgstr "收集数æ®åº“的统计信æ¯" # sql_help.h:101 # sql_help.h:413 -#: sql_help.c:4329 sql_help.c:4939 +#: sql_help.c:5026 sql_help.c:5818 msgid "start a transaction block" msgstr "开始一个事务区å—" +# sql_help.h:261 +#: sql_help.c:5032 +msgid "invoke a procedure" +msgstr "调用过程" + # sql_help.h:105 -#: sql_help.c:4334 -msgid "force a transaction log checkpoint" -msgstr "å¼ºåˆ¶ä¸€ä¸ªäº‹åŠ¡è§¦å‘æ£€æŸ¥ç‚¹" +#: sql_help.c:5038 +msgid "force a write-ahead log checkpoint" +msgstr "强制一个预写日志检查点" # sql_help.h:109 -#: sql_help.c:4339 +#: sql_help.c:5044 msgid "close a cursor" msgstr "关闭游标" # sql_help.h:113 -#: sql_help.c:4344 +#: sql_help.c:5050 msgid "cluster a table according to an index" msgstr "按照索引进行表的èšé›†" # sql_help.h:117 -#: sql_help.c:4349 +#: sql_help.c:5056 msgid "define or change the comment of an object" msgstr "定义或更改一个对象的注解" # sql_help.h:121 # sql_help.h:309 -#: sql_help.c:4354 sql_help.c:4774 +#: sql_help.c:5062 sql_help.c:5620 msgid "commit the current transaction" msgstr "确认目å‰çš„事务" -#: sql_help.c:4359 +#: sql_help.c:5068 msgid "commit a transaction that was earlier prepared for two-phase commit" msgstr "æäº¤ä¸€é¡¹äº‹åŠ¡è¿™æ˜¯ä¸¤é˜¶æ®µæäº¤çš„å…ˆå‰å‡†å¤‡" # sql_help.h:125 -#: sql_help.c:4364 +#: sql_help.c:5074 msgid "copy data between a file and a table" msgstr "在档案和数æ®è¡¨é—´å¤åˆ¶æ•°æ®" # sql_help.h:133 -#: sql_help.c:4369 -#| msgid "define a new cast" +#: sql_help.c:5080 msgid "define a new access method" msgstr "定义新的访问方法" # sql_help.h:129 -#: sql_help.c:4374 +#: sql_help.c:5086 msgid "define a new aggregate function" msgstr "定义一个新的èšé›†å‡½æ•°" # sql_help.h:133 -#: sql_help.c:4379 +#: sql_help.c:5092 msgid "define a new cast" msgstr "建立新的类型转æ¢" # sql_help.h:153 -#: sql_help.c:4384 +#: sql_help.c:5098 msgid "define a new collation" msgstr "建立新的校对规则" # sql_help.h:141 -#: sql_help.c:4389 +#: sql_help.c:5104 msgid "define a new encoding conversion" msgstr "定义一个新的字元编ç è½¬æ¢" # sql_help.h:145 -#: sql_help.c:4394 +#: sql_help.c:5110 msgid "create a new database" msgstr "建立新的数æ®åº“" # sql_help.h:149 -#: sql_help.c:4399 +#: sql_help.c:5116 msgid "define a new domain" msgstr "建立新的共åŒå€¼åŸŸ" # sql_help.h:201 -#: sql_help.c:4404 +#: sql_help.c:5122 msgid "define a new event trigger" msgstr "定义新的事件触å‘器" -#: sql_help.c:4409 +#: sql_help.c:5128 msgid "install an extension" msgstr "安装一个扩展" # sql_help.h:205 -#: sql_help.c:4414 +#: sql_help.c:5134 msgid "define a new foreign-data wrapper" msgstr "定义一个新的外部数æ®å°è£…器" # sql_help.h:201 -#: sql_help.c:4419 +#: sql_help.c:5140 msgid "define a new foreign table" msgstr "建立新的外部表" # sql_help.h:153 -#: sql_help.c:4424 +#: sql_help.c:5146 msgid "define a new function" msgstr "建立新的函数" # sql_help.h:189 -#: sql_help.c:4429 sql_help.c:4469 sql_help.c:4544 +#: sql_help.c:5152 sql_help.c:5212 sql_help.c:5314 msgid "define a new database role" msgstr "定义一个新数æ®åº“角色" # sql_help.h:161 -#: sql_help.c:4434 +#: sql_help.c:5158 msgid "define a new index" msgstr "建立新的索引" # sql_help.h:165 -#: sql_help.c:4439 +#: sql_help.c:5164 msgid "define a new procedural language" msgstr "建立新的程åºè¯­è¨€" # sql_help.h:213 -#: sql_help.c:4444 +#: sql_help.c:5170 msgid "define a new materialized view" msgstr "建立新的物化视图" # sql_help.h:173 -#: sql_help.c:4449 +#: sql_help.c:5176 msgid "define a new operator" msgstr "建立新的è¿ç®—å­" # sql_help.h:169 -#: sql_help.c:4454 +#: sql_help.c:5182 msgid "define a new operator class" msgstr "建立新的è¿ç®—å­ç±»åˆ«" # sql_help.h:173 -#: sql_help.c:4459 +#: sql_help.c:5188 msgid "define a new operator family" msgstr "定义一个新的è¿ç®—å­å®¶æ—" # sql_help.h:201 -#: sql_help.c:4464 -#| msgid "define a new policy for a table" +#: sql_help.c:5194 msgid "define a new row level security policy for a table" msgstr "ä¸ºä¸€ä¸ªè¡¨å®šä¹‰ä¸€æ¡æ–°çš„行级安全性策略" +# sql_help.h:165 +#: sql_help.c:5200 +msgid "define a new procedure" +msgstr "建立新的程åº" + +# sql_help.h:153 +#: sql_help.c:5206 +msgid "define a new publication" +msgstr "建立新的出版" + # sql_help.h:177 -#: sql_help.c:4474 +#: sql_help.c:5218 msgid "define a new rewrite rule" msgstr "建立新的é‡å†™è§„则" # sql_help.h:181 -#: sql_help.c:4479 +#: sql_help.c:5224 msgid "define a new schema" msgstr "建立新的架构模å¼" # sql_help.h:185 -#: sql_help.c:4484 +#: sql_help.c:5230 msgid "define a new sequence generator" msgstr "建立新的åºåˆ—数产生器" # sql_help.h:201 -#: sql_help.c:4489 +#: sql_help.c:5236 msgid "define a new foreign server" msgstr "建立新的触å‘器" +# sql_help.h:133 +#: sql_help.c:5242 +msgid "define extended statistics" +msgstr "建立新的扩展统计" + +# sql_help.h:153 +#: sql_help.c:5248 +msgid "define a new subscription" +msgstr "建立新的订阅" + # sql_help.h:189 -#: sql_help.c:4494 +#: sql_help.c:5254 msgid "define a new table" msgstr "建立新的数æ®è¡¨" # sql_help.h:193 # sql_help.h:389 -#: sql_help.c:4499 sql_help.c:4904 +#: sql_help.c:5260 sql_help.c:5776 msgid "define a new table from the results of a query" msgstr "以查询结果建立新的数æ®è¡¨" # sql_help.h:197 -#: sql_help.c:4504 +#: sql_help.c:5266 msgid "define a new tablespace" msgstr "建立新的表空间" # sql_help.h:129 -#: sql_help.c:4509 +#: sql_help.c:5272 msgid "define a new text search configuration" msgstr "定义一个新文本æœç´¢ç»„æ€" # sql_help.h:129 -#: sql_help.c:4514 +#: sql_help.c:5278 msgid "define a new text search dictionary" msgstr "定义一个新文本æœç´¢å­—å…¸" # sql_help.h:197 -#: sql_help.c:4519 +#: sql_help.c:5284 msgid "define a new text search parser" msgstr "定义一个新文本æœç´¢å‰–æžå™¨" # sql_help.h:181 -#: sql_help.c:4524 +#: sql_help.c:5290 msgid "define a new text search template" msgstr "定义一个新文本æœç´¢æ¨¡ç‰ˆ" # sql_help.h:173 -#: sql_help.c:4529 +#: sql_help.c:5296 msgid "define a new transform" msgstr "定义一个新的转æ¢" # sql_help.h:201 -#: sql_help.c:4534 +#: sql_help.c:5302 msgid "define a new trigger" msgstr "建立新的触å‘器" # sql_help.h:205 -#: sql_help.c:4539 +#: sql_help.c:5308 msgid "define a new data type" msgstr "建立新的数æ®ç±»åž‹" -#: sql_help.c:4549 +#: sql_help.c:5320 msgid "define a new mapping of a user to a foreign server" msgstr "将用户的新映射定义到一个外部æœåС噍" # sql_help.h:213 -#: sql_help.c:4554 +#: sql_help.c:5326 msgid "define a new view" msgstr "建立新的视图" # sql_help.h:217 -#: sql_help.c:4559 +#: sql_help.c:5332 msgid "deallocate a prepared statement" msgstr "释放一个已预备好的å™è¿°åŒºå—" # sql_help.h:221 -#: sql_help.c:4564 +#: sql_help.c:5338 msgid "define a cursor" msgstr "建立一个 cursor" # sql_help.h:225 -#: sql_help.c:4569 +#: sql_help.c:5344 msgid "delete rows of a table" msgstr "删除数æ®è¡¨ä¸­çš„æ•°æ®åˆ—" -#: sql_help.c:4574 +#: sql_help.c:5350 msgid "discard session state" msgstr "抛弃 session 状æ€" -#: sql_help.c:4579 +#: sql_help.c:5356 msgid "execute an anonymous code block" msgstr "执行一个匿å代ç å—" # sql_help.h:233 -#: sql_help.c:4584 -#| msgid "remove a cast" +#: sql_help.c:5362 msgid "remove an access method" msgstr "移除一ç§è®¿é—®æ–¹æ³•" # sql_help.h:229 -#: sql_help.c:4589 +#: sql_help.c:5368 msgid "remove an aggregate function" msgstr "移除一个èšé›†å‡½æ•°" # sql_help.h:233 -#: sql_help.c:4594 +#: sql_help.c:5374 msgid "remove a cast" msgstr "移除一个类型转æ¢" # sql_help.h:249 -#: sql_help.c:4599 +#: sql_help.c:5380 msgid "remove a collation" msgstr "移除一个校对规则" # sql_help.h:237 -#: sql_help.c:4604 +#: sql_help.c:5386 msgid "remove a conversion" msgstr "移除一个字元编ç è½¬æ¢" # sql_help.h:241 -#: sql_help.c:4609 +#: sql_help.c:5392 msgid "remove a database" msgstr "移除数æ®åº“" # sql_help.h:245 -#: sql_help.c:4614 +#: sql_help.c:5398 msgid "remove a domain" msgstr "移除一个共åŒå€¼åŸŸ" # sql_help.h:293 -#: sql_help.c:4619 +#: sql_help.c:5404 msgid "remove an event trigger" msgstr "移除事件触å‘器" # sql_help.h:237 -#: sql_help.c:4624 +#: sql_help.c:5410 msgid "remove an extension" msgstr "移除一个扩展" # sql_help.h:297 -#: sql_help.c:4629 +#: sql_help.c:5416 msgid "remove a foreign-data wrapper" msgstr "删除一个外部数æ®å°è£…器" # sql_help.h:285 -#: sql_help.c:4634 +#: sql_help.c:5422 msgid "remove a foreign table" msgstr "移除外部引用表" # sql_help.h:249 -#: sql_help.c:4639 +#: sql_help.c:5428 msgid "remove a function" msgstr "移除函数" # sql_help.h:241 -#: sql_help.c:4644 sql_help.c:4689 sql_help.c:4759 +#: sql_help.c:5434 sql_help.c:5500 sql_help.c:5602 msgid "remove a database role" msgstr "移除一个数æ®åº“æˆå‘˜" # sql_help.h:257 -#: sql_help.c:4649 +#: sql_help.c:5440 msgid "remove an index" msgstr "移除一个索引" # sql_help.h:261 -#: sql_help.c:4654 +#: sql_help.c:5446 msgid "remove a procedural language" msgstr "移除一个程åºè¯­è¨€" # sql_help.h:305 -#: sql_help.c:4659 +#: sql_help.c:5452 msgid "remove a materialized view" msgstr "移除一个物化视图" # sql_help.h:269 -#: sql_help.c:4664 +#: sql_help.c:5458 msgid "remove an operator" msgstr "移除è¿ç®—å­" # sql_help.h:265 -#: sql_help.c:4669 +#: sql_help.c:5464 msgid "remove an operator class" msgstr "移除一个è¿ç®—å­ç±»åˆ«" # sql_help.h:269 -#: sql_help.c:4674 +#: sql_help.c:5470 msgid "remove an operator family" msgstr "移除一个è¿ç®—å­å®¶æ—" -#: sql_help.c:4679 +#: sql_help.c:5476 msgid "remove database objects owned by a database role" msgstr "ä¾ç…§ä¸€ä¸ªæ•°æ®åº“角色拥有的数æ®åº“对象æ¥ç§»é™¤" # sql_help.h:285 -#: sql_help.c:4684 -#| msgid "remove a policy from a table" +#: sql_help.c:5482 msgid "remove a row level security policy from a table" msgstr "从一个表移除一æ¡è¡Œçº§å®‰å…¨æ€§ç­–ç•¥" +# sql_help.h:261 +#: sql_help.c:5488 +msgid "remove a procedure" +msgstr "移除一个程åº" + +# sql_help.h:249 +#: sql_help.c:5494 +msgid "remove a publication" +msgstr "移除出版" + +# sql_help.h:249 +#: sql_help.c:5506 +msgid "remove a routine" +msgstr "移除程åº" + # sql_help.h:273 -#: sql_help.c:4694 +#: sql_help.c:5512 msgid "remove a rewrite rule" msgstr "移除一个é‡å†™è§„则" # sql_help.h:277 -#: sql_help.c:4699 +#: sql_help.c:5518 msgid "remove a schema" msgstr "移除一个模å¼" # sql_help.h:281 -#: sql_help.c:4704 +#: sql_help.c:5524 msgid "remove a sequence" msgstr "移除åºåˆ—" # sql_help.h:237 -#: sql_help.c:4709 +#: sql_help.c:5530 msgid "remove a foreign server descriptor" msgstr "删除一个外部æœåС噍æè¿°ç¬¦" +# sql_help.h:237 +#: sql_help.c:5536 +msgid "remove extended statistics" +msgstr "移除一个扩展统计" + +# sql_help.h:249 +#: sql_help.c:5542 +msgid "remove a subscription" +msgstr "移除一个订阅" + # sql_help.h:285 -#: sql_help.c:4714 +#: sql_help.c:5548 msgid "remove a table" msgstr "移除数æ®è¡¨" # sql_help.h:289 -#: sql_help.c:4719 +#: sql_help.c:5554 msgid "remove a tablespace" msgstr "移除一个表空间" # sql_help.h:301 -#: sql_help.c:4724 +#: sql_help.c:5560 msgid "remove a text search configuration" msgstr "移除一个文本æœç´¢é…ç½®" # sql_help.h:301 -#: sql_help.c:4729 +#: sql_help.c:5566 msgid "remove a text search dictionary" msgstr "移除一个文本æœç´¢å­—å…¸" # sql_help.h:289 -#: sql_help.c:4734 +#: sql_help.c:5572 msgid "remove a text search parser" msgstr "移除一个文本æœç´¢å‰–æžå™¨" # sql_help.h:277 -#: sql_help.c:4739 +#: sql_help.c:5578 msgid "remove a text search template" msgstr "移除一个文本æœç´¢æ¨¡ç‰ˆ" # sql_help.h:269 -#: sql_help.c:4744 +#: sql_help.c:5584 msgid "remove a transform" msgstr "移除一个转æ¢" # sql_help.h:293 -#: sql_help.c:4749 +#: sql_help.c:5590 msgid "remove a trigger" msgstr "移除触å‘器" # sql_help.h:297 -#: sql_help.c:4754 +#: sql_help.c:5596 msgid "remove a data type" msgstr "移除数æ®ç±»åž‹" -#: sql_help.c:4764 +#: sql_help.c:5608 msgid "remove a user mapping for a foreign server" msgstr "为外部æœåŠ¡å™¨åˆ é™¤ç”¨æˆ·æ˜ å°„" # sql_help.h:305 -#: sql_help.c:4769 +#: sql_help.c:5614 msgid "remove a view" msgstr "移除一个视图" # sql_help.h:313 -#: sql_help.c:4779 +#: sql_help.c:5626 msgid "execute a prepared statement" msgstr "执行一个已准备好的语å¥å—" # sql_help.h:317 -#: sql_help.c:4784 +#: sql_help.c:5632 msgid "show the execution plan of a statement" msgstr "显示一个语å¥å—的执行计划" # sql_help.h:321 -#: sql_help.c:4789 +#: sql_help.c:5638 msgid "retrieve rows from a query using a cursor" msgstr "ä»Žä½¿ç”¨æ¸¸æ ‡çš„æŸ¥è¯¢è¯»å–æ•°æ®" # sql_help.h:325 -#: sql_help.c:4794 +#: sql_help.c:5644 msgid "define access privileges" msgstr "å®šä¹‰å­˜å–æƒé™" # sql_help.h:85 -#: sql_help.c:4799 +#: sql_help.c:5650 msgid "import table definitions from a foreign server" msgstr "从一个外部æœåŠ¡å™¨å¯¼å…¥è¡¨å®šä¹‰" # sql_help.h:329 -#: sql_help.c:4804 +#: sql_help.c:5656 msgid "create new rows in a table" msgstr "在表中创建新数æ®è¡Œ" # sql_help.h:333 -#: sql_help.c:4809 +#: sql_help.c:5662 msgid "listen for a notification" msgstr "等待通知" # sql_help.h:337 -#: sql_help.c:4814 +#: sql_help.c:5668 msgid "load a shared library file" msgstr "加载一个共享库文件" # sql_help.h:341 -#: sql_help.c:4819 +#: sql_help.c:5674 msgid "lock a table" msgstr "é”定数æ®è¡¨" # sql_help.h:345 -#: sql_help.c:4824 +#: sql_help.c:5680 msgid "position a cursor" msgstr "移动游标ä½ç½®" # sql_help.h:349 -#: sql_help.c:4829 +#: sql_help.c:5686 msgid "generate a notification" msgstr "产生通知" # sql_help.h:353 -#: sql_help.c:4834 +#: sql_help.c:5692 msgid "prepare a statement for execution" msgstr "预先编译语å¥ä»¥æ‰§è¡Œ" # sql_help.h:25 # sql_help.h:373 -#: sql_help.c:4839 +#: sql_help.c:5698 msgid "prepare the current transaction for two-phase commit" msgstr "准备将当å‰äº‹åŠ¡è¿›è¡ŒäºŒæ®µå¼æäº¤" -#: sql_help.c:4844 +#: sql_help.c:5704 msgid "change the ownership of database objects owned by a database role" msgstr "ä¾ç…§ä¸€ä¸ªæ•°æ®åº“角色拥有的的数æ®åº“å¯¹è±¡æ¥æ›´å˜æ‰€æœ‰æƒ" -#: sql_help.c:4849 +#: sql_help.c:5710 msgid "replace the contents of a materialized view" msgstr "替æ¢ç‰©åŒ–视图的内容" # sql_help.h:357 -#: sql_help.c:4854 +#: sql_help.c:5716 msgid "rebuild indexes" msgstr "釿–°å»ºæž„索引" # sql_help.h:361 -#: sql_help.c:4859 +#: sql_help.c:5722 msgid "destroy a previously defined savepoint" msgstr "删除先å‰å»ºç«‹çš„储存点(Savepoint)" # sql_help.h:365 -#: sql_help.c:4864 +#: sql_help.c:5728 msgid "restore the value of a run-time parameter to the default value" msgstr "å°†æ‰§è¡Œæ—¶æœŸå‚æ•°è¿˜åŽŸæˆé¢„设值" # sql_help.h:369 -#: sql_help.c:4869 +#: sql_help.c:5734 msgid "remove access privileges" msgstr "ç§»é™¤å­˜å–æƒé™" -#: sql_help.c:4879 +#: sql_help.c:5746 msgid "cancel a transaction that was earlier prepared for two-phase commit" msgstr "å–æ¶ˆä¸€ä¸ªå¯ä»¥ä¸ºä¸¤é˜¶æ®µæäº¤å®¹æ˜“é…置的事务" # sql_help.h:377 -#: sql_help.c:4884 +#: sql_help.c:5752 msgid "roll back to a savepoint" msgstr "还原至一个储存点(Savepoint)" # sql_help.h:381 -#: sql_help.c:4889 +#: sql_help.c:5758 msgid "define a new savepoint within the current transaction" msgstr "在当å‰äº‹åŠ¡ä¸­å»ºç«‹æ–°çš„å‚¨å­˜ç‚¹(Savepoint)" # sql_help.h:117 -#: sql_help.c:4894 +#: sql_help.c:5764 msgid "define or change a security label applied to an object" msgstr "定义或更改一个对象的安全标签" # sql_help.h:385 -#: sql_help.c:4899 sql_help.c:4944 sql_help.c:4974 +#: sql_help.c:5770 sql_help.c:5824 sql_help.c:5860 msgid "retrieve rows from a table or view" msgstr "从数æ®è¡¨æˆ–è§†å›¾ä¸­è¯»å–æ•°æ®" # sql_help.h:393 -#: sql_help.c:4909 +#: sql_help.c:5782 msgid "change a run-time parameter" msgstr "更改一个è¿è¡ŒæœŸå‚æ•°" # sql_help.h:397 -#: sql_help.c:4914 +#: sql_help.c:5788 msgid "set constraint check timing for the current transaction" msgstr "为当å‰äº‹åŠ¡è®¾å®šçº¦æŸé™åˆ¶æ£€æŸ¥çš„æ—¶é—´æ¨¡å¼" # sql_help.h:405 -#: sql_help.c:4919 +#: sql_help.c:5794 msgid "set the current user identifier of the current session" msgstr "为当å‰ä¼šè¯çš„当å‰ç”¨æˆ·çš„设置身份标识" # sql_help.h:401 -#: sql_help.c:4924 -msgid "" -"set the session user identifier and the current user identifier of the " -"current session" +#: sql_help.c:5800 +msgid "set the session user identifier and the current user identifier of the current session" msgstr "为当å‰ä¼šè¯è®¾ç½®ä¼šè¯ç”¨æˆ·æ ‡è¯†ç¬¦å’Œå½“å‰ç”¨æˆ·æ ‡è¯†ç¬¦" # sql_help.h:405 -#: sql_help.c:4929 +#: sql_help.c:5806 msgid "set the characteristics of the current transaction" msgstr "设定当å‰äº‹åŠ¡å±žæ€§" # sql_help.h:409 -#: sql_help.c:4934 +#: sql_help.c:5812 msgid "show the value of a run-time parameter" msgstr "显示è¿è¡ŒæœŸçš„傿•°å€¼" # sql_help.h:425 -#: sql_help.c:4949 +#: sql_help.c:5830 msgid "empty a table or set of tables" msgstr "空的数æ®è¡¨æˆ–æ•°æ®è¡¨é›†åˆ" # sql_help.h:421 -#: sql_help.c:4954 +#: sql_help.c:5836 msgid "stop listening for a notification" msgstr "åœæ­¢ç›‘å¬é€šçŸ¥" # sql_help.h:425 -#: sql_help.c:4959 +#: sql_help.c:5842 msgid "update rows of a table" msgstr "æ›´æ–°æ•°æ®è¡¨ä¸­çš„æ•°æ®åˆ—" # sql_help.h:429 -#: sql_help.c:4964 +#: sql_help.c:5848 msgid "garbage-collect and optionally analyze a database" msgstr "垃圾收集(GC)å¹¶é€‰æ‹©åœ°åˆ†æžæ•°æ®åº“" -#: sql_help.c:4969 +#: sql_help.c:5854 msgid "compute a set of rows" msgstr "计算一个数æ®åˆ—的集åˆ" -#: startup.c:189 -#, c-format -msgid "%s: -1 can only be used in non-interactive mode\n" +#: startup.c:216 +#, fuzzy, c-format +#| msgid "%s: -1 can only be used in non-interactive mode\n" +msgid "-1 can only be used in non-interactive mode" msgstr "%s: -1 åªèƒ½ç”¨äºŽéžäº¤äº’模å¼ä¸‹\n" -# command.c:1148 -#: startup.c:289 +#: startup.c:303 #, c-format -msgid "%s: could not open log file \"%s\": %s\n" -msgstr "%sï¼šæ— æ³•å¼€å¯æ—¥å¿—文件 \"%s\":%s\n" +msgid "could not connect to server: %s" +msgstr "无法连接到æœåŠ¡å™¨ï¼š%s" -#: startup.c:389 +#: startup.c:331 +#, c-format +msgid "could not open log file \"%s\": %m" +msgstr "无法打开事务日志文件 \"%s\": %m" + +#: startup.c:442 #, c-format msgid "" "Type \"help\" for help.\n" @@ -6214,57 +7212,73 @@ msgstr "" "\n" # startup.c:446 -#: startup.c:538 -#, c-format -msgid "%s: could not set printing parameter \"%s\"\n" +#: startup.c:592 +#, fuzzy, c-format +#| msgid "%s: could not set printing parameter \"%s\"\n" +msgid "could not set printing parameter \"%s\"" msgstr "%s:无法设定列打å°å‚æ•° \"%s\"\n" -# startup.c:492 -#: startup.c:578 -#, c-format -msgid "%s: could not delete variable \"%s\"\n" -msgstr "%s:无法删除å˜é‡ \"%s\"\n" - -# startup.c:502 -#: startup.c:588 -#, c-format -msgid "%s: could not set variable \"%s\"\n" -msgstr "%s:无法设定å˜é‡ \"%s\"\n" - # startup.c:533 # startup.c:539 -#: startup.c:648 +#: startup.c:697 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "å°è¯• \"%s --help\" 以得到更多信æ¯ã€‚\n" # startup.c:557 -#: startup.c:665 -#, c-format -msgid "%s: warning: extra command-line argument \"%s\" ignored\n" +#: startup.c:714 +#, fuzzy, c-format +#| msgid "%s: warning: extra command-line argument \"%s\" ignored\n" +msgid "extra command-line argument \"%s\" ignored" msgstr "%sï¼šè­¦å‘Šï¼šå¿½ç•¥å¤šä½™çš„å‘½ä»¤è¡Œå‚æ•° \"%s\"\n" -#: startup.c:714 -#, c-format -msgid "%s: could not find own program executable\n" +#: startup.c:763 +#, fuzzy, c-format +#| msgid "%s: could not find own program executable\n" +msgid "could not find own program executable" msgstr "%s: 找ä¸åˆ°å¯æ‰§è¡Œæ–‡ä»¶\n" -#: startup.c:836 startup.c:883 startup.c:904 startup.c:941 startup.c:963 -#: variables.c:121 -#, c-format -msgid "unrecognized value \"%s\" for \"%s\"; assuming \"%s\"\n" -msgstr "\"%2$s\"çš„ä¸èƒ½è¯†åˆ«çš„值\"%1$s\"ï¼›å‡å®šä¸º\"%3$s\"\n" - -#: tab-complete.c:3682 -#, c-format +#: tab-complete.c:4380 +#, fuzzy, c-format +#| msgid "" +#| "tab completion query failed: %s\n" +#| "Query was:\n" +#| "%s\n" msgid "" "tab completion query failed: %s\n" "Query was:\n" -"%s\n" +"%s" msgstr "" "自动补全查询失败: %s\n" "查询是:\n" "%s\n" -#~ msgid " \\l[+] list all databases\n" -#~ msgstr " \\l[+] 列出所有的数æ®åº“\n" +#: variables.c:141 +#, fuzzy, c-format +#| msgid "unrecognized value \"%s\" for \"%s\": Boolean expected\n" +msgid "unrecognized value \"%s\" for \"%s\": Boolean expected" +msgstr "\"%2$s\"çš„ä¸èƒ½è¯†åˆ«çš„值\"%1$s\":应为布尔值\n" + +#: variables.c:178 +#, fuzzy, c-format +#| msgid "invalid value \"%s\" for \"%s\": integer expected\n" +msgid "invalid value \"%s\" for \"%s\": integer expected" +msgstr "\"%s\"的值\"%s\"无效: 应为整数\n" + +#: variables.c:226 +#, fuzzy, c-format +#| msgid "invalid variable name: \"%s\"\n" +msgid "invalid variable name: \"%s\"" +msgstr "无效的语言环境åç§°: \"%s\"\n" + +#: variables.c:395 +#, fuzzy, c-format +#| msgid "" +#| "unrecognized value \"%s\" for \"%s\"\n" +#| "Available values are: %s.\n" +msgid "" +"unrecognized value \"%s\" for \"%s\"\n" +"Available values are: %s." +msgstr "" +"\"%2$s\"çš„ä¸èƒ½è¯†åˆ«çš„值\"%1$s\"\n" +"å¯ç”¨å€¼ä¸º\"%3$s\".\n" diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c index b176972884f..0fcb8c77832 100644 --- a/src/bin/psql/prompt.c +++ b/src/bin/psql/prompt.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/prompt.c */ @@ -22,6 +22,7 @@ #include "prompt.h" #include "settings.h" +#include "common/string.h" /*-------------------------- * get_prompt @@ -181,7 +182,7 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) case '5': case '6': case '7': - *buf = (char) strtol(p, (char **) &p, 8); + *buf = (char) strtol(p, unconstify(char **, &p), 8); --p; break; case 'R': @@ -274,8 +275,10 @@ get_prompt(promptStatus_t status, ConditionalStack cstack) buf[0] = '\0'; pclose(fd); } - if (strlen(buf) > 0 && buf[strlen(buf) - 1] == '\n') - buf[strlen(buf) - 1] = '\0'; + + /* strip trailing newline and carriage return */ + (void) pg_strip_crlf(buf); + free(file); p += cmdend + 1; break; diff --git a/src/bin/psql/prompt.h b/src/bin/psql/prompt.h index 3a84565e4b8..905ee3d88f8 100644 --- a/src/bin/psql/prompt.h +++ b/src/bin/psql/prompt.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/prompt.h */ diff --git a/src/bin/psql/psqlscanslash.h b/src/bin/psql/psqlscanslash.h index 8e8efb2f0b3..f25ccf32f05 100644 --- a/src/bin/psql/psqlscanslash.h +++ b/src/bin/psql/psqlscanslash.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/psqlscanslash.h */ diff --git a/src/bin/psql/psqlscanslash.l b/src/bin/psql/psqlscanslash.l index 34df35e5f43..c2e3bfe9d0c 100644 --- a/src/bin/psql/psqlscanslash.l +++ b/src/bin/psql/psqlscanslash.l @@ -8,7 +8,7 @@ * * See fe_utils/psqlscan_int.h for additional commentary. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -19,6 +19,7 @@ #include "postgres_fe.h" #include "psqlscanslash.h" +#include "common/logging.h" #include "fe_utils/conditional.h" #include "libpq-fe.h" @@ -633,7 +634,7 @@ psql_scan_slash_option(PsqlScanState state, case xslashbackquote: case xslashdquote: /* must have hit EOL inside quotes */ - state->callbacks->write_error("unterminated quoted string\n"); + pg_log_error("unterminated quoted string"); termPQExpBuffer(&mybuf); return NULL; case xslashwholeline: @@ -779,7 +780,7 @@ evaluate_backtick(PsqlScanState state) fd = popen(cmd, PG_BINARY_R); if (!fd) { - state->callbacks->write_error("%s: %s\n", cmd, strerror(errno)); + pg_log_error("%s: %m", cmd); error = true; } @@ -790,7 +791,7 @@ evaluate_backtick(PsqlScanState state) result = fread(buf, 1, sizeof(buf), fd); if (ferror(fd)) { - state->callbacks->write_error("%s: %s\n", cmd, strerror(errno)); + pg_log_error("%s: %m", cmd); error = true; break; } @@ -800,13 +801,13 @@ evaluate_backtick(PsqlScanState state) if (fd && pclose(fd) == -1) { - state->callbacks->write_error("%s: %s\n", cmd, strerror(errno)); + pg_log_error("%s: %m", cmd); error = true; } if (PQExpBufferDataBroken(cmd_output)) { - state->callbacks->write_error("%s: out of memory\n", cmd); + pg_log_error("%s: out of memory", cmd); error = true; } diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 69e617e6b5f..5be5091f0e9 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/settings.h */ @@ -12,6 +12,7 @@ #include "variables.h" #include "fe_utils/print.h" +#define DEFAULT_CSV_FIELD_SEP ',' #define DEFAULT_FIELD_SEP "|" #define DEFAULT_RECORD_SEP "\n" @@ -126,6 +127,7 @@ typedef struct _psqlSettings bool quiet; bool singleline; bool singlestep; + bool hide_tableam; int fetch_count; int histsize; int ignoreeof; diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index be57574cd32..e4c0a7eacbf 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/startup.c */ @@ -16,13 +16,15 @@ #include "getopt_long.h" +#include "common/logging.h" +#include "fe_utils/print.h" + #include "command.h" #include "common.h" #include "describe.h" #include "help.h" #include "input.h" #include "mainloop.h" -#include "fe_utils/print.h" #include "settings.h" @@ -79,9 +81,9 @@ struct adhoc_opts }; static void parse_psql_options(int argc, char *argv[], - struct adhoc_opts *options); + struct adhoc_opts *options); static void simple_action_list_append(SimpleActionList *list, - enum _actions action, const char *val); + enum _actions action, const char *val); static void process_psqlrc(char *argv0); static void process_psqlrc_file(char *filename); static void showVersion(void); @@ -89,6 +91,28 @@ static void EstablishVariableSpace(void); #define NOPAGER 0 +static void +log_pre_callback(void) +{ + if (pset.queryFout && pset.queryFout != stdout) + fflush(pset.queryFout); +} + +static void +log_locus_callback(const char **filename, uint64 *lineno) +{ + if (pset.inputfile) + { + *filename = pset.inputfile; + *lineno = pset.lineno; + } + else + { + *filename = NULL; + *lineno = 0; + } +} + /* * * main @@ -103,6 +127,9 @@ main(int argc, char *argv[]) char password[100]; bool new_pass; + pg_logging_init(argv[0]); + pg_logging_set_pre_callback(log_pre_callback); + pg_logging_set_locus_callback(log_locus_callback); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql")); if (argc > 1) @@ -119,10 +146,6 @@ main(int argc, char *argv[]) } } -#ifdef WIN32 - setvbuf(stderr, NULL, _IONBF, 0); -#endif - pset.progname = get_progname(argv[0]); pset.db = NULL; @@ -144,6 +167,9 @@ main(int argc, char *argv[]) pset.popt.topt.stop_table = true; pset.popt.topt.default_footer = true; + pset.popt.topt.csvFieldSep[0] = DEFAULT_CSV_FIELD_SEP; + pset.popt.topt.csvFieldSep[1] = '\0'; + pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE; pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE; pset.popt.topt.unicode_header_linestyle = UNICODE_LINESTYLE_SINGLE; @@ -187,7 +213,7 @@ main(int argc, char *argv[]) /* Bail out if -1 was specified but will be ignored. */ if (options.single_txn && options.actions.head == NULL) { - fprintf(stderr, _("%s: -1 can only be used in non-interactive mode\n"), pset.progname); + pg_log_fatal("-1 can only be used in non-interactive mode"); exit(EXIT_FAILURE); } @@ -274,7 +300,7 @@ main(int argc, char *argv[]) if (PQstatus(pset.db) == CONNECTION_BAD) { - fprintf(stderr, "%s: %s", pset.progname, PQerrorMessage(pset.db)); + pg_log_error("could not connect to server: %s", PQerrorMessage(pset.db)); PQfinish(pset.db); exit(EXIT_BADCONN); } @@ -302,8 +328,8 @@ main(int argc, char *argv[]) pset.logfile = fopen(options.logfilename, "a"); if (!pset.logfile) { - fprintf(stderr, _("%s: could not open log file \"%s\": %s\n"), - pset.progname, options.logfilename, strerror(errno)); + pg_log_fatal("could not open log file \"%s\": %m", + options.logfilename); exit(EXIT_FAILURE); } } @@ -340,6 +366,8 @@ main(int argc, char *argv[]) { if (cell->action == ACT_SINGLE_QUERY) { + pg_logging_config(PG_LOG_FLAG_TERSE); + if (pset.echo == PSQL_ECHO_ALL) puts(cell->val); @@ -351,6 +379,8 @@ main(int argc, char *argv[]) PsqlScanState scan_state; ConditionalStack cond_stack; + pg_logging_config(PG_LOG_FLAG_TERSE); + if (pset.echo == PSQL_ECHO_ALL) puts(cell->val); @@ -407,6 +437,7 @@ main(int argc, char *argv[]) */ else { + pg_logging_config(PG_LOG_FLAG_TERSE); connection_warnings(true); if (!pset.quiet) printf(_("Type \"help\" for help.\n\n")); @@ -468,6 +499,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) {"expanded", no_argument, NULL, 'x'}, {"no-psqlrc", no_argument, NULL, 'X'}, {"help", optional_argument, NULL, 1}, + {"csv", no_argument, NULL, 2}, {NULL, 0, NULL, 0} }; @@ -558,7 +590,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) if (!result) { - fprintf(stderr, _("%s: could not set printing parameter \"%s\"\n"), pset.progname, value); + pg_log_fatal("could not set printing parameter \"%s\"", value); exit(EXIT_FAILURE); } @@ -634,15 +666,18 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) options->single_txn = true; break; case '?': - /* Actual help option given */ - if (strcmp(argv[optind - 1], "-?") == 0) + if (optind <= argc && + strcmp(argv[optind - 1], "-?") == 0) { + /* actual help option given */ usage(NOPAGER); exit(EXIT_SUCCESS); } - /* unknown option reported by getopt */ else + { + /* getopt error (unknown option or missing argument) */ goto unknown_option; + } break; case 1: { @@ -658,6 +693,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) exit(EXIT_SUCCESS); } break; + case 2: + pset.popt.topt.format = PRINT_CSV; + break; default: unknown_option: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), @@ -677,8 +715,8 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options) else if (!options->username) options->username = argv[optind]; else if (!pset.quiet) - fprintf(stderr, _("%s: warning: extra command-line argument \"%s\" ignored\n"), - pset.progname, argv[optind]); + pg_log_warning("extra command-line argument \"%s\" ignored", + argv[optind]); optind++; } @@ -726,7 +764,7 @@ process_psqlrc(char *argv0) if (find_my_exec(argv0, my_exec_path) < 0) { - fprintf(stderr, _("%s: could not find own program executable\n"), argv0); + pg_log_fatal("could not find own program executable"); exit(EXIT_FAILURE); } @@ -1077,13 +1115,15 @@ verbosity_hook(const char *newval) Assert(newval != NULL); /* else substitute hook messed up */ if (pg_strcasecmp(newval, "default") == 0) pset.verbosity = PQERRORS_DEFAULT; - else if (pg_strcasecmp(newval, "terse") == 0) - pset.verbosity = PQERRORS_TERSE; else if (pg_strcasecmp(newval, "verbose") == 0) pset.verbosity = PQERRORS_VERBOSE; + else if (pg_strcasecmp(newval, "terse") == 0) + pset.verbosity = PQERRORS_TERSE; + else if (pg_strcasecmp(newval, "sqlstate") == 0) + pset.verbosity = PQERRORS_SQLSTATE; else { - PsqlVarEnumError("VERBOSITY", newval, "default, terse, verbose"); + PsqlVarEnumError("VERBOSITY", newval, "default, verbose, terse, sqlstate"); return false; } @@ -1121,6 +1161,11 @@ show_context_hook(const char *newval) return true; } +static bool +hide_tableam_hook(const char *newval) +{ + return ParseVariableBool(newval, "HIDE_TABLEAM", &pset.hide_tableam); +} static void EstablishVariableSpace(void) @@ -1184,4 +1229,7 @@ EstablishVariableSpace(void) SetVariableHooks(pset.vars, "SHOW_CONTEXT", show_context_substitute_hook, show_context_hook); + SetVariableHooks(pset.vars, "HIDE_TABLEAM", + bool_substitute_hook, + hide_tableam_hook); } diff --git a/src/bin/psql/stringutils.c b/src/bin/psql/stringutils.c index 29b9c9c7f03..8c8b4c2fbf1 100644 --- a/src/bin/psql/stringutils.c +++ b/src/bin/psql/stringutils.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/stringutils.c */ diff --git a/src/bin/psql/stringutils.h b/src/bin/psql/stringutils.h index d843d7119bc..16a7af0b520 100644 --- a/src/bin/psql/stringutils.h +++ b/src/bin/psql/stringutils.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/stringutils.h */ @@ -11,17 +11,17 @@ /* The cooler version of strtok() which knows about quotes and doesn't * overwrite your input */ extern char *strtokx(const char *s, - const char *whitespace, - const char *delim, - const char *quote, - char escape, - bool e_strings, - bool del_quotes, - int encoding); + const char *whitespace, + const char *delim, + const char *quote, + char escape, + bool e_strings, + bool del_quotes, + int encoding); extern void strip_quotes(char *source, char quote, char escape, int encoding); extern char *quote_if_needed(const char *source, const char *entails_quote, - char quote, char escape, int encoding); + char quote, char escape, int encoding); #endif /* STRINGUTILS_H */ diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 061de8e6d46..e00dbab5aa1 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/tab-complete.c */ @@ -41,6 +41,7 @@ #include +#include "catalog/pg_am_d.h" #include "catalog/pg_class_d.h" #include "libpq-fe.h" @@ -173,10 +174,10 @@ static bool completion_case_sensitive; /* completion is case sensitive */ * 2) The results from a schema query you pass it. * We support both simple and versioned schema queries. * 3) The items from a null-pointer-terminated list (with or without - * case-sensitive comparison; see also COMPLETE_WITH_LISTn, below). - * 4) A string constant. - * 5) The list of attributes of the given table (possibly schema-qualified). - * 6/ The list of arguments to the given function (possibly schema-qualified). + * case-sensitive comparison); if the list is constant you can build it + * with COMPLETE_WITH() or COMPLETE_WITH_CS(). + * 4) The list of attributes of the given table (possibly schema-qualified). + * 5) The list of arguments to the given function (possibly schema-qualified). */ #define COMPLETE_WITH_QUERY(query) \ do { \ @@ -204,25 +205,37 @@ do { \ matches = completion_matches(text, complete_from_versioned_schema_query); \ } while (0) -#define COMPLETE_WITH_LIST_CS(list) \ +/* + * Caution: COMPLETE_WITH_CONST is not for general-purpose use; you probably + * want COMPLETE_WITH() with one element, instead. + */ +#define COMPLETE_WITH_CONST(cs, con) \ do { \ - completion_charpp = list; \ - completion_case_sensitive = true; \ - matches = completion_matches(text, complete_from_list); \ + completion_case_sensitive = (cs); \ + completion_charp = (con); \ + matches = completion_matches(text, complete_from_const); \ } while (0) -#define COMPLETE_WITH_LIST(list) \ +#define COMPLETE_WITH_LIST_INT(cs, list) \ do { \ - completion_charpp = list; \ - completion_case_sensitive = false; \ + completion_case_sensitive = (cs); \ + completion_charpp = (list); \ matches = completion_matches(text, complete_from_list); \ } while (0) -#define COMPLETE_WITH_CONST(string) \ +#define COMPLETE_WITH_LIST(list) COMPLETE_WITH_LIST_INT(false, list) +#define COMPLETE_WITH_LIST_CS(list) COMPLETE_WITH_LIST_INT(true, list) + +#define COMPLETE_WITH(...) \ do { \ - completion_charp = string; \ - completion_case_sensitive = false; \ - matches = completion_matches(text, complete_from_const); \ + static const char *const list[] = { __VA_ARGS__, NULL }; \ + COMPLETE_WITH_LIST(list); \ +} while (0) + +#define COMPLETE_WITH_CS(...) \ +do { \ + static const char *const list[] = { __VA_ARGS__, NULL }; \ + COMPLETE_WITH_LIST_CS(list); \ } while (0) #define COMPLETE_WITH_ATTR(relation, addon) \ @@ -300,531 +313,271 @@ do { \ matches = completion_matches(text, complete_from_query); \ } while (0) -/* - * These macros simplify use of COMPLETE_WITH_LIST for short, fixed lists. - * There is no COMPLETE_WITH_LIST1; use COMPLETE_WITH_CONST for that case. - */ -#define COMPLETE_WITH_LIST2(s1, s2) \ -do { \ - static const char *const list[] = { s1, s2, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST3(s1, s2, s3) \ -do { \ - static const char *const list[] = { s1, s2, s3, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST4(s1, s2, s3, s4) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST5(s1, s2, s3, s4, s5) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST6(s1, s2, s3, s4, s5, s6) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST7(s1, s2, s3, s4, s5, s6, s7) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST8(s1, s2, s3, s4, s5, s6, s7, s8) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST9(s1, s2, s3, s4, s5, s6, s7, s8, s9) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -#define COMPLETE_WITH_LIST10(s1, s2, s3, s4, s5, s6, s7, s8, s9, s10) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, NULL }; \ - COMPLETE_WITH_LIST(list); \ -} while (0) - -/* - * Likewise for COMPLETE_WITH_LIST_CS. - */ -#define COMPLETE_WITH_LIST_CS2(s1, s2) \ -do { \ - static const char *const list[] = { s1, s2, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS3(s1, s2, s3) \ -do { \ - static const char *const list[] = { s1, s2, s3, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS4(s1, s2, s3, s4) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - -#define COMPLETE_WITH_LIST_CS5(s1, s2, s3, s4, s5) \ -do { \ - static const char *const list[] = { s1, s2, s3, s4, s5, NULL }; \ - COMPLETE_WITH_LIST_CS(list); \ -} while (0) - /* * Assembly instructions for schema queries */ static const SchemaQuery Query_for_list_of_aggregates[] = { { - /* min_server_version */ - 110000, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - "p.prokind = 'a'", - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .min_server_version = 110000, + .catname = "pg_catalog.pg_proc p", + .selcondition = "p.prokind = 'a'", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", }, { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - "p.proisagg", - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_proc p", + .selcondition = "p.proisagg", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", } }; static const SchemaQuery Query_for_list_of_datatypes = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_type t", + .catname = "pg_catalog.pg_type t", /* selcondition --- ignore table rowtypes and array types */ - "(t.typrelid = 0 " + .selcondition = "(t.typrelid = 0 " " OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE) " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) " "AND t.typname !~ '^_'", - /* viscondition */ - "pg_catalog.pg_type_is_visible(t.oid)", - /* namespace */ - "t.typnamespace", - /* result */ - "pg_catalog.format_type(t.oid, NULL)", - /* qualresult */ - "pg_catalog.quote_ident(t.typname)" + .viscondition = "pg_catalog.pg_type_is_visible(t.oid)", + .namespace = "t.typnamespace", + .result = "pg_catalog.format_type(t.oid, NULL)", + .qualresult = "pg_catalog.quote_ident(t.typname)", +}; + +static const SchemaQuery Query_for_list_of_composite_datatypes = { + .catname = "pg_catalog.pg_type t", + /* selcondition --- only get composite types */ + .selcondition = "(SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE) + " FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid) " + "AND t.typname !~ '^_'", + .viscondition = "pg_catalog.pg_type_is_visible(t.oid)", + .namespace = "t.typnamespace", + .result = "pg_catalog.format_type(t.oid, NULL)", + .qualresult = "pg_catalog.quote_ident(t.typname)", }; static const SchemaQuery Query_for_list_of_domains = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_type t", - /* selcondition */ - "t.typtype = 'd'", - /* viscondition */ - "pg_catalog.pg_type_is_visible(t.oid)", - /* namespace */ - "t.typnamespace", - /* result */ - "pg_catalog.quote_ident(t.typname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_type t", + .selcondition = "t.typtype = 'd'", + .viscondition = "pg_catalog.pg_type_is_visible(t.oid)", + .namespace = "t.typnamespace", + .result = "pg_catalog.quote_ident(t.typname)", }; /* Note: this intentionally accepts aggregates as well as plain functions */ static const SchemaQuery Query_for_list_of_functions[] = { { - /* min_server_version */ - 110000, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - "p.prokind != 'p'", - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .min_server_version = 110000, + .catname = "pg_catalog.pg_proc p", + .selcondition = "p.prokind != 'p'", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", }, { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - NULL, - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_proc p", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", } }; -static const SchemaQuery Query_for_list_of_indexes = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", " - CppAsString2(RELKIND_PARTITIONED_INDEX) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL -}; - static const SchemaQuery Query_for_list_of_procedures[] = { { - /* min_server_version */ - 110000, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - "p.prokind = 'p'", - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .min_server_version = 110000, + .catname = "pg_catalog.pg_proc p", + .selcondition = "p.prokind = 'p'", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", }, - {0, NULL} + { + /* not supported in older versions */ + .catname = NULL, + } }; static const SchemaQuery Query_for_list_of_routines = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_proc p", - /* selcondition */ - NULL, - /* viscondition */ - "pg_catalog.pg_function_is_visible(p.oid)", - /* namespace */ - "p.pronamespace", - /* result */ - "pg_catalog.quote_ident(p.proname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_proc p", + .viscondition = "pg_catalog.pg_function_is_visible(p.oid)", + .namespace = "p.pronamespace", + .result = "pg_catalog.quote_ident(p.proname)", }; static const SchemaQuery Query_for_list_of_sequences = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_SEQUENCE) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; static const SchemaQuery Query_for_list_of_foreign_tables = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_FOREIGN_TABLE) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; static const SchemaQuery Query_for_list_of_tables = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_PARTITIONED_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; static const SchemaQuery Query_for_list_of_partitioned_tables = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_constraints_with_schema = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_constraint c", - /* selcondition */ - "c.conrelid <> 0", - /* viscondition */ - "true", /* there is no pg_constraint_is_visible */ - /* namespace */ - "c.connamespace", - /* result */ - "pg_catalog.quote_ident(c.conname)", - /* qualresult */ - NULL +static const SchemaQuery Query_for_list_of_views = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + +static const SchemaQuery Query_for_list_of_matviews = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + +static const SchemaQuery Query_for_list_of_indexes = { + .catname = "pg_catalog.pg_class c", + .selcondition = + "c.relkind IN (" CppAsString2(RELKIND_INDEX) ", " + CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + +static const SchemaQuery Query_for_list_of_partitioned_indexes = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind = " CppAsString2(RELKIND_PARTITIONED_INDEX), + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + + +/* All relations */ +static const SchemaQuery Query_for_list_of_relations = { + .catname = "pg_catalog.pg_class c", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", +}; + +/* partitioned relations */ +static const SchemaQuery Query_for_list_of_partitioned_relations = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_PARTITIONED_TABLE) + ", " CppAsString2(RELKIND_PARTITIONED_INDEX) ")", + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; /* Relations supporting INSERT, UPDATE or DELETE */ static const SchemaQuery Query_for_list_of_updatables = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_FOREIGN_TABLE) ", " CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_PARTITIONED_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL -}; - -/* Relations supporting MERGE */ -static const SchemaQuery Query_for_list_of_mergetargets = { - /* min_server_version */ - 110000, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_PARTITIONED_TABLE) ") AND " - "c.relhasrules = false AND " - "(c.relhassubclass = false OR " - " c.relkind = " CppAsString2(RELKIND_PARTITIONED_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL -}; - -static const SchemaQuery Query_for_list_of_relations = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - NULL, - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_tsvmf = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ +/* Relations supporting SELECT */ +static const SchemaQuery Query_for_list_of_selectables = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_SEQUENCE) ", " CppAsString2(RELKIND_VIEW) ", " CppAsString2(RELKIND_MATVIEW) ", " CppAsString2(RELKIND_FOREIGN_TABLE) ", " CppAsString2(RELKIND_PARTITIONED_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_tmf = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ +/* Relations supporting GRANT are currently same as those supporting SELECT */ +#define Query_for_list_of_grantables Query_for_list_of_selectables + +/* Relations supporting ANALYZE */ +static const SchemaQuery Query_for_list_of_analyzables = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_PARTITIONED_TABLE) ", " CppAsString2(RELKIND_MATVIEW) ", " CppAsString2(RELKIND_FOREIGN_TABLE) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_tpm = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ +/* Relations supporting index creation */ +static const SchemaQuery Query_for_list_of_indexables = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_PARTITIONED_TABLE) ", " CppAsString2(RELKIND_MATVIEW) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_tm = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ +/* Relations supporting VACUUM */ +static const SchemaQuery Query_for_list_of_vacuumables = { + .catname = "pg_catalog.pg_class c", + .selcondition = "c.relkind IN (" CppAsString2(RELKIND_RELATION) ", " CppAsString2(RELKIND_MATVIEW) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL + .viscondition = "pg_catalog.pg_table_is_visible(c.oid)", + .namespace = "c.relnamespace", + .result = "pg_catalog.quote_ident(c.relname)", }; -static const SchemaQuery Query_for_list_of_views = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_VIEW) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL -}; +/* Relations supporting CLUSTER are currently same as those supporting VACUUM */ +#define Query_for_list_of_clusterables Query_for_list_of_vacuumables -static const SchemaQuery Query_for_list_of_matviews = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_class c", - /* selcondition */ - "c.relkind IN (" CppAsString2(RELKIND_MATVIEW) ")", - /* viscondition */ - "pg_catalog.pg_table_is_visible(c.oid)", - /* namespace */ - "c.relnamespace", - /* result */ - "pg_catalog.quote_ident(c.relname)", - /* qualresult */ - NULL +static const SchemaQuery Query_for_list_of_constraints_with_schema = { + .catname = "pg_catalog.pg_constraint c", + .selcondition = "c.conrelid <> 0", + .viscondition = "true", /* there is no pg_constraint_is_visible */ + .namespace = "c.connamespace", + .result = "pg_catalog.quote_ident(c.conname)", }; static const SchemaQuery Query_for_list_of_statistics = { - /* min_server_version */ - 0, - /* catname */ - "pg_catalog.pg_statistic_ext s", - /* selcondition */ - NULL, - /* viscondition */ - "pg_catalog.pg_statistics_obj_is_visible(s.oid)", - /* namespace */ - "s.stxnamespace", - /* result */ - "pg_catalog.quote_ident(s.stxname)", - /* qualresult */ - NULL + .catname = "pg_catalog.pg_statistic_ext s", + .viscondition = "pg_catalog.pg_statistics_obj_is_visible(s.oid)", + .namespace = "s.stxnamespace", + .result = "pg_catalog.quote_ident(s.stxname)", }; @@ -853,6 +606,17 @@ static const SchemaQuery Query_for_list_of_statistics = { " OR '\"' || relname || '\"'='%s') "\ " AND pg_catalog.pg_table_is_visible(c.oid)" +#define Query_for_list_of_attribute_numbers \ +"SELECT attnum "\ +" FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\ +" WHERE c.oid = a.attrelid "\ +" AND a.attnum > 0 "\ +" AND NOT a.attisdropped "\ +" AND substring(attnum::pg_catalog.text,1,%d)='%s' "\ +" AND (pg_catalog.quote_ident(relname)='%s' "\ +" OR '\"' || relname || '\"'='%s') "\ +" AND pg_catalog.pg_table_is_visible(c.oid)" + #define Query_for_list_of_attributes_with_schema \ "SELECT pg_catalog.quote_ident(attname) "\ " FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c, pg_catalog.pg_namespace n "\ @@ -954,15 +718,6 @@ static const SchemaQuery Query_for_list_of_statistics = { " UNION ALL SELECT 'CURRENT_USER'"\ " UNION ALL SELECT 'SESSION_USER'" -/* the silly-looking length condition is just to eat up the current word */ -#define Query_for_table_owning_index \ -"SELECT pg_catalog.quote_ident(c1.relname) "\ -" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\ -" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\ -" and (%d = pg_catalog.length('%s'))"\ -" and pg_catalog.quote_ident(c2.relname)='%s'"\ -" and pg_catalog.pg_table_is_visible(c2.oid)" - /* the silly-looking length condition is just to eat up the current word */ #define Query_for_index_of_table \ "SELECT pg_catalog.quote_ident(c2.relname) "\ @@ -1073,6 +828,18 @@ static const SchemaQuery Query_for_list_of_statistics = { " FROM pg_catalog.pg_am "\ " WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s'" +#define Query_for_list_of_index_access_methods \ +" SELECT pg_catalog.quote_ident(amname) "\ +" FROM pg_catalog.pg_am "\ +" WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s' AND "\ +" amtype=" CppAsString2(AMTYPE_INDEX) + +#define Query_for_list_of_table_access_methods \ +" SELECT pg_catalog.quote_ident(amname) "\ +" FROM pg_catalog.pg_am "\ +" WHERE substring(pg_catalog.quote_ident(amname),1,%d)='%s' AND "\ +" amtype=" CppAsString2(AMTYPE_TABLE) + /* the silly-looking length condition is just to eat up the current word */ #define Query_for_list_of_arguments \ "SELECT pg_catalog.oidvectortypes(proargtypes)||')' "\ @@ -1240,6 +1007,7 @@ static const pgsql_thing_t words_after_create[] = { {"MATERIALIZED VIEW", NULL, NULL, &Query_for_list_of_matviews}, {"OPERATOR", NULL, NULL, NULL}, /* Querying for this is probably not such * a good idea. */ + {"OR REPLACE", NULL, NULL, NULL, THING_NO_DROP | THING_NO_ALTER}, {"OWNED", NULL, NULL, NULL, THING_NO_CREATE | THING_NO_ALTER}, /* for DROP OWNED BY ... */ {"PARSER", Query_for_list_of_ts_parsers, NULL, NULL, THING_NO_SHOW}, {"POLICY", NULL, NULL, NULL}, @@ -1275,6 +1043,45 @@ static const pgsql_thing_t words_after_create[] = { {NULL} /* end of list */ }; +/* Storage parameters for CREATE TABLE and ALTER TABLE */ +static const char *const table_storage_parameters[] = { + "autovacuum_analyze_scale_factor", + "autovacuum_analyze_threshold", + "autovacuum_enabled", + "autovacuum_freeze_max_age", + "autovacuum_freeze_min_age", + "autovacuum_freeze_table_age", + "autovacuum_multixact_freeze_max_age", + "autovacuum_multixact_freeze_min_age", + "autovacuum_multixact_freeze_table_age", + "autovacuum_vacuum_cost_delay", + "autovacuum_vacuum_cost_limit", + "autovacuum_vacuum_scale_factor", + "autovacuum_vacuum_threshold", + "fillfactor", + "log_autovacuum_min_duration", + "parallel_workers", + "toast.autovacuum_enabled", + "toast.autovacuum_freeze_max_age", + "toast.autovacuum_freeze_min_age", + "toast.autovacuum_freeze_table_age", + "toast.autovacuum_multixact_freeze_max_age", + "toast.autovacuum_multixact_freeze_min_age", + "toast.autovacuum_multixact_freeze_table_age", + "toast.autovacuum_vacuum_cost_delay", + "toast.autovacuum_vacuum_cost_limit", + "toast.autovacuum_vacuum_scale_factor", + "toast.autovacuum_vacuum_threshold", + "toast.log_autovacuum_min_duration", + "toast.vacuum_index_cleanup", + "toast.vacuum_truncate", + "toast_tuple_target", + "user_catalog_table", + "vacuum_index_cleanup", + "vacuum_truncate", + NULL +}; + /* Forward declaration of functions */ static char **psql_completion(const char *text, int start, int end); @@ -1286,15 +1093,15 @@ static char *complete_from_versioned_query(const char *text, int state); static char *complete_from_schema_query(const char *text, int state); static char *complete_from_versioned_schema_query(const char *text, int state); static char *_complete_from_query(const char *simple_query, - const SchemaQuery *schema_query, - const char *text, int state); + const SchemaQuery *schema_query, + const char *text, int state); static char *complete_from_list(const char *text, int state); static char *complete_from_const(const char *text, int state); static void append_variable_names(char ***varnames, int *nvars, - int *maxvars, const char *varname, - const char *prefix, const char *suffix); + int *maxvars, const char *varname, + const char *prefix, const char *suffix); static char **complete_from_variables(const char *text, - const char *prefix, const char *suffix, bool need_value); + const char *prefix, const char *suffix, bool need_value); static char *complete_from_files(const char *text, int state); static char *pg_strdup_keyword_case(const char *s, const char *ref); @@ -1337,9 +1144,8 @@ initialize_readline(void) * If pattern is NULL, it's a wild card that matches any word. * If pattern begins with '!', the result is negated, ie we check that 'word' * does *not* match any alternative appearing in the rest of 'pattern'. - * Any alternative can end with '*' which is a wild card, i.e., it means - * match any word that matches the characters so far. (We do not currently - * support '*' elsewhere than the end of an alternative.) + * Any alternative can contain '*' which is a wild card, i.e., it can match + * any substring; however, we allow at most one '*' per alternative. * * For readability, callers should use the macros MatchAny and MatchAnyExcept * to invoke those two special cases for 'pattern'. (But '|' and '*' must @@ -1349,12 +1155,14 @@ initialize_readline(void) #define MatchAnyExcept(pattern) ("!" pattern) static bool -word_matches_internal(const char *pattern, - const char *word, - bool case_sensitive) +word_matches(const char *pattern, + const char *word, + bool case_sensitive) { - size_t wordlen, - patternlen; + size_t wordlen; + +#define cimatch(s1, s2, n) \ + (case_sensitive ? strncmp(s1, s2, n) == 0 : pg_strncasecmp(s1, s2, n) == 0) /* NULL pattern matches anything. */ if (pattern == NULL) @@ -1362,37 +1170,40 @@ word_matches_internal(const char *pattern, /* Handle negated patterns from the MatchAnyExcept macro. */ if (*pattern == '!') - return !word_matches_internal(pattern + 1, word, case_sensitive); + return !word_matches(pattern + 1, word, case_sensitive); /* Else consider each alternative in the pattern. */ wordlen = strlen(word); for (;;) { + const char *star = NULL; const char *c; - /* Find end of current alternative. */ + /* Find end of current alternative, and locate any wild card. */ c = pattern; while (*c != '\0' && *c != '|') + { + if (*c == '*') + star = c; c++; - /* Was there a wild card? (Assumes first alternative is not empty) */ - if (c[-1] == '*') + } + /* Was there a wild card? */ + if (star) { /* Yes, wildcard match? */ - patternlen = c - pattern - 1; - if (wordlen >= patternlen && - (case_sensitive ? - strncmp(word, pattern, patternlen) == 0 : - pg_strncasecmp(word, pattern, patternlen) == 0)) + size_t beforelen = star - pattern, + afterlen = c - star - 1; + + if (wordlen >= (beforelen + afterlen) && + cimatch(word, pattern, beforelen) && + cimatch(word + wordlen - afterlen, star + 1, afterlen)) return true; } else { /* No, plain match? */ - patternlen = c - pattern; - if (wordlen == patternlen && - (case_sensitive ? - strncmp(word, pattern, wordlen) == 0 : - pg_strncasecmp(word, pattern, wordlen) == 0)) + if (wordlen == (c - pattern) && + cimatch(word, pattern, wordlen)) return true; } /* Out of alternatives? */ @@ -1406,24 +1217,105 @@ word_matches_internal(const char *pattern, } /* - * There are enough matching calls below that it seems worth having these two - * interface routines rather than including a third parameter in every call. + * Implementation of TailMatches and TailMatchesCS macros: do the last N words + * in previous_words match the variadic arguments? * - * word_matches --- match case-insensitively. + * The array indexing might look backwards, but remember that + * previous_words[0] contains the *last* word on the line, not the first. */ static bool -word_matches(const char *pattern, const char *word) +TailMatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) { - return word_matches_internal(pattern, word, false); + va_list args; + + if (previous_words_count < narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[narg - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; } /* - * word_matches_cs --- match case-sensitively. + * Implementation of Matches and MatchesCS macros: do all of the words + * in previous_words match the variadic arguments? */ static bool -word_matches_cs(const char *pattern, const char *word) +MatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) { - return word_matches_internal(pattern, word, true); + va_list args; + + if (previous_words_count != narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[narg - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; +} + +/* + * Implementation of HeadMatches and HeadMatchesCS macros: do the first N + * words in previous_words match the variadic arguments? + */ +static bool +HeadMatchesImpl(bool case_sensitive, + int previous_words_count, char **previous_words, + int narg,...) +{ + va_list args; + + if (previous_words_count < narg) + return false; + + va_start(args, narg); + + for (int argno = 0; argno < narg; argno++) + { + const char *arg = va_arg(args, const char *); + + if (!word_matches(arg, previous_words[previous_words_count - argno - 1], + case_sensitive)) + { + va_end(args); + return false; + } + } + + va_end(args); + + return true; } /* @@ -1477,149 +1369,35 @@ psql_completion(const char *text, int start, int end) #define prev8_wd (previous_words[7]) #define prev9_wd (previous_words[8]) - /* Macros for matching the last N words before point, case-insensitively. */ -#define TailMatches1(p1) \ - (previous_words_count >= 1 && \ - word_matches(p1, prev_wd)) - -#define TailMatches2(p2, p1) \ - (previous_words_count >= 2 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd)) - -#define TailMatches3(p3, p2, p1) \ - (previous_words_count >= 3 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd)) - -#define TailMatches4(p4, p3, p2, p1) \ - (previous_words_count >= 4 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd)) - -#define TailMatches5(p5, p4, p3, p2, p1) \ - (previous_words_count >= 5 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd)) - -#define TailMatches6(p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 6 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd)) - -#define TailMatches7(p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 7 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd)) - -#define TailMatches8(p8, p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 8 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd) && \ - word_matches(p8, prev8_wd)) - -#define TailMatches9(p9, p8, p7, p6, p5, p4, p3, p2, p1) \ - (previous_words_count >= 9 && \ - word_matches(p1, prev_wd) && \ - word_matches(p2, prev2_wd) && \ - word_matches(p3, prev3_wd) && \ - word_matches(p4, prev4_wd) && \ - word_matches(p5, prev5_wd) && \ - word_matches(p6, prev6_wd) && \ - word_matches(p7, prev7_wd) && \ - word_matches(p8, prev8_wd) && \ - word_matches(p9, prev9_wd)) - - /* Macros for matching the last N words before point, case-sensitively. */ -#define TailMatchesCS1(p1) \ - (previous_words_count >= 1 && \ - word_matches_cs(p1, prev_wd)) -#define TailMatchesCS2(p2, p1) \ - (previous_words_count >= 2 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd)) -#define TailMatchesCS3(p3, p2, p1) \ - (previous_words_count >= 3 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd) && \ - word_matches_cs(p3, prev3_wd)) -#define TailMatchesCS4(p4, p3, p2, p1) \ - (previous_words_count >= 4 && \ - word_matches_cs(p1, prev_wd) && \ - word_matches_cs(p2, prev2_wd) && \ - word_matches_cs(p3, prev3_wd) && \ - word_matches_cs(p4, prev4_wd)) + /* Match the last N words before point, case-insensitively. */ +#define TailMatches(...) \ + TailMatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) - /* - * Macros for matching N words beginning at the start of the line, - * case-insensitively. - */ -#define Matches1(p1) \ - (previous_words_count == 1 && \ - TailMatches1(p1)) -#define Matches2(p1, p2) \ - (previous_words_count == 2 && \ - TailMatches2(p1, p2)) -#define Matches3(p1, p2, p3) \ - (previous_words_count == 3 && \ - TailMatches3(p1, p2, p3)) -#define Matches4(p1, p2, p3, p4) \ - (previous_words_count == 4 && \ - TailMatches4(p1, p2, p3, p4)) -#define Matches5(p1, p2, p3, p4, p5) \ - (previous_words_count == 5 && \ - TailMatches5(p1, p2, p3, p4, p5)) -#define Matches6(p1, p2, p3, p4, p5, p6) \ - (previous_words_count == 6 && \ - TailMatches6(p1, p2, p3, p4, p5, p6)) -#define Matches7(p1, p2, p3, p4, p5, p6, p7) \ - (previous_words_count == 7 && \ - TailMatches7(p1, p2, p3, p4, p5, p6, p7)) -#define Matches8(p1, p2, p3, p4, p5, p6, p7, p8) \ - (previous_words_count == 8 && \ - TailMatches8(p1, p2, p3, p4, p5, p6, p7, p8)) -#define Matches9(p1, p2, p3, p4, p5, p6, p7, p8, p9) \ - (previous_words_count == 9 && \ - TailMatches9(p1, p2, p3, p4, p5, p6, p7, p8, p9)) + /* Match the last N words before point, case-sensitively. */ +#define TailMatchesCS(...) \ + TailMatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) - /* - * Macros for matching N words at the start of the line, regardless of - * what is after them, case-insensitively. - */ -#define HeadMatches1(p1) \ - (previous_words_count >= 1 && \ - word_matches(p1, previous_words[previous_words_count - 1])) + /* Match N words representing all of the line, case-insensitively. */ +#define Matches(...) \ + MatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) + + /* Match N words representing all of the line, case-sensitively. */ +#define MatchesCS(...) \ + MatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) -#define HeadMatches2(p1, p2) \ - (previous_words_count >= 2 && \ - word_matches(p1, previous_words[previous_words_count - 1]) && \ - word_matches(p2, previous_words[previous_words_count - 2])) + /* Match the first N words on the line, case-insensitively. */ +#define HeadMatches(...) \ + HeadMatchesImpl(false, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) -#define HeadMatches3(p1, p2, p3) \ - (previous_words_count >= 3 && \ - word_matches(p1, previous_words[previous_words_count - 1]) && \ - word_matches(p2, previous_words[previous_words_count - 2]) && \ - word_matches(p3, previous_words[previous_words_count - 3])) + /* Match the first N words on the line, case-sensitively. */ +#define HeadMatchesCS(...) \ + HeadMatchesImpl(true, previous_words_count, previous_words, \ + VA_ARGS_NARGS(__VA_ARGS__), __VA_ARGS__) /* Known command-starting keywords. */ static const char *const sql_commands[] = { @@ -1627,7 +1405,7 @@ psql_completion(const char *text, int start, int end) "COMMENT", "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE FROM", "DISCARD", "DO", "DROP", "END", "EXECUTE", "EXPLAIN", "FETCH", "GRANT", "IMPORT", "INSERT", "LISTEN", "LOAD", "LOCK", - "MERGE", "MOVE", "NOTIFY", "PREPARE", + "MOVE", "NOTIFY", "PREPARE", "REASSIGN", "REFRESH MATERIALIZED VIEW", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK", "SAVEPOINT", "SECURITY LABEL", "SELECT", "SET", "SHOW", "START", @@ -1643,7 +1421,7 @@ psql_completion(const char *text, int start, int end) "\\d", "\\da", "\\dA", "\\db", "\\dc", "\\dC", "\\dd", "\\ddp", "\\dD", "\\des", "\\det", "\\deu", "\\dew", "\\dE", "\\df", "\\dF", "\\dFd", "\\dFp", "\\dFt", "\\dg", "\\di", "\\dl", "\\dL", - "\\dm", "\\dn", "\\do", "\\dO", "\\dp", + "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\dP", "\\dPi", "\\dPt", "\\drds", "\\dRs", "\\dRp", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy", "\\e", "\\echo", "\\ef", "\\elif", "\\else", "\\encoding", @@ -1661,7 +1439,7 @@ psql_completion(const char *text, int start, int end) "\\t", "\\T", "\\timing", "\\unset", "\\x", - "\\w", "\\watch", + "\\w", "\\warn", "\\watch", "\\z", "\\!", "\\?", NULL @@ -1709,363 +1487,372 @@ psql_completion(const char *text, int start, int end) /* CREATE */ /* complete with something you can create */ - else if (TailMatches1("CREATE")) + else if (TailMatches("CREATE")) matches = completion_matches(text, create_command_generator); + /* complete with somthing you can create or replace */ + else if (TailMatches("CREATE", "OR", "REPLACE")) + COMPLETE_WITH("FUNCTION", "PROCEDURE", "LANGUAGE", "RULE", "VIEW", + "AGGREGATE", "TRANSFORM"); + /* DROP, but not DROP embedded in other commands */ /* complete with something you can drop */ - else if (Matches1("DROP")) + else if (Matches("DROP")) matches = completion_matches(text, drop_command_generator); /* ALTER */ /* ALTER TABLE */ - else if (Matches2("ALTER", "TABLE")) + else if (Matches("ALTER", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER something */ - else if (Matches1("ALTER")) + else if (Matches("ALTER")) matches = completion_matches(text, alter_command_generator); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx */ - else if (TailMatches4("ALL", "IN", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST2("SET TABLESPACE", "OWNED BY"); + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny)) + COMPLETE_WITH("SET TABLESPACE", "OWNED BY"); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY */ - else if (TailMatches6("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY")) + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* ALTER TABLE,INDEX,MATERIALIZED VIEW ALL IN TABLESPACE xxx OWNED BY xxx */ - else if (TailMatches7("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny)) - COMPLETE_WITH_CONST("SET TABLESPACE"); + else if (TailMatches("ALL", "IN", "TABLESPACE", MatchAny, "OWNED", "BY", MatchAny)) + COMPLETE_WITH("SET TABLESPACE"); /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE */ - else if (Matches3("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) + COMPLETE_WITH("("); /* ALTER AGGREGATE,FUNCTION,PROCEDURE,ROUTINE (...) */ - else if (Matches4("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) + else if (Matches("ALTER", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny)) { if (ends_with(prev_wd, ')')) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); else COMPLETE_WITH_FUNCTION_ARG(prev2_wd); } /* ALTER PUBLICATION */ - else if (Matches3("ALTER", "PUBLICATION", MatchAny)) - COMPLETE_WITH_LIST5("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET"); + else if (Matches("ALTER", "PUBLICATION", MatchAny)) + COMPLETE_WITH("ADD TABLE", "DROP TABLE", "OWNER TO", "RENAME TO", "SET"); /* ALTER PUBLICATION SET */ - else if (Matches4("ALTER", "PUBLICATION", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "TABLE"); + else if (Matches("ALTER", "PUBLICATION", MatchAny, "SET")) + COMPLETE_WITH("(", "TABLE"); /* ALTER PUBLICATION SET ( */ - else if (HeadMatches3("ALTER", "PUBLICATION", MatchAny) && TailMatches2("SET", "(")) - COMPLETE_WITH_CONST("publish"); + else if (HeadMatches("ALTER", "PUBLICATION", MatchAny) && TailMatches("SET", "(")) + COMPLETE_WITH("publish"); /* ALTER SUBSCRIPTION */ - else if (Matches3("ALTER", "SUBSCRIPTION", MatchAny)) - COMPLETE_WITH_LIST7("CONNECTION", "ENABLE", "DISABLE", "OWNER TO", - "RENAME TO", "REFRESH PUBLICATION", "SET"); + else if (Matches("ALTER", "SUBSCRIPTION", MatchAny)) + COMPLETE_WITH("CONNECTION", "ENABLE", "DISABLE", "OWNER TO", + "RENAME TO", "REFRESH PUBLICATION", "SET"); /* ALTER SUBSCRIPTION REFRESH PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches2("REFRESH", "PUBLICATION")) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("REFRESH", "PUBLICATION")) + COMPLETE_WITH("WITH ("); /* ALTER SUBSCRIPTION REFRESH PUBLICATION WITH ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches4("REFRESH", "PUBLICATION", "WITH", "(")) - COMPLETE_WITH_CONST("copy_data"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("REFRESH", "PUBLICATION", "WITH", "(")) + COMPLETE_WITH("copy_data"); /* ALTER SUBSCRIPTION SET */ - else if (Matches4("ALTER", "SUBSCRIPTION", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "PUBLICATION"); + else if (Matches("ALTER", "SUBSCRIPTION", MatchAny, "SET")) + COMPLETE_WITH("(", "PUBLICATION"); /* ALTER SUBSCRIPTION SET ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "(")) - COMPLETE_WITH_LIST2("slot_name", "synchronous_commit"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "(")) + COMPLETE_WITH("slot_name", "synchronous_commit"); /* ALTER SUBSCRIPTION SET PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches2("SET", "PUBLICATION")) + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && TailMatches("SET", "PUBLICATION")) { /* complete with nothing here as this refers to remote publications */ } /* ALTER SUBSCRIPTION SET PUBLICATION */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches3("SET", "PUBLICATION", MatchAny)) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("SET", "PUBLICATION", MatchAny)) + COMPLETE_WITH("WITH ("); /* ALTER SUBSCRIPTION SET PUBLICATION WITH ( */ - else if (HeadMatches3("ALTER", "SUBSCRIPTION", MatchAny) && - TailMatches5("SET", "PUBLICATION", MatchAny, "WITH", "(")) - COMPLETE_WITH_LIST2("copy_data", "refresh"); + else if (HeadMatches("ALTER", "SUBSCRIPTION", MatchAny) && + TailMatches("SET", "PUBLICATION", MatchAny, "WITH", "(")) + COMPLETE_WITH("copy_data", "refresh"); /* ALTER SCHEMA */ - else if (Matches3("ALTER", "SCHEMA", MatchAny)) - COMPLETE_WITH_LIST2("OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "SCHEMA", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO"); /* ALTER COLLATION */ - else if (Matches3("ALTER", "COLLATION", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "COLLATION", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); /* ALTER CONVERSION */ - else if (Matches3("ALTER", "CONVERSION", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "CONVERSION", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); /* ALTER DATABASE */ - else if (Matches3("ALTER", "DATABASE", MatchAny)) - COMPLETE_WITH_LIST7("RESET", "SET", "OWNER TO", "RENAME TO", - "IS_TEMPLATE", "ALLOW_CONNECTIONS", - "CONNECTION LIMIT"); + else if (Matches("ALTER", "DATABASE", MatchAny)) + COMPLETE_WITH("RESET", "SET", "OWNER TO", "RENAME TO", + "IS_TEMPLATE", "ALLOW_CONNECTIONS", + "CONNECTION LIMIT"); + + /* ALTER DATABASE SET TABLESPACE */ + else if (Matches("ALTER", "DATABASE", MatchAny, "SET", "TABLESPACE")) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); /* ALTER EVENT TRIGGER */ - else if (Matches3("ALTER", "EVENT", "TRIGGER")) + else if (Matches("ALTER", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* ALTER EVENT TRIGGER */ - else if (Matches4("ALTER", "EVENT", "TRIGGER", MatchAny)) - COMPLETE_WITH_LIST4("DISABLE", "ENABLE", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny)) + COMPLETE_WITH("DISABLE", "ENABLE", "OWNER TO", "RENAME TO"); /* ALTER EVENT TRIGGER ENABLE */ - else if (Matches5("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE")) - COMPLETE_WITH_LIST2("REPLICA", "ALWAYS"); + else if (Matches("ALTER", "EVENT", "TRIGGER", MatchAny, "ENABLE")) + COMPLETE_WITH("REPLICA", "ALWAYS"); /* ALTER EXTENSION */ - else if (Matches3("ALTER", "EXTENSION", MatchAny)) - COMPLETE_WITH_LIST4("ADD", "DROP", "UPDATE", "SET SCHEMA"); + else if (Matches("ALTER", "EXTENSION", MatchAny)) + COMPLETE_WITH("ADD", "DROP", "UPDATE", "SET SCHEMA"); /* ALTER EXTENSION UPDATE */ - else if (Matches4("ALTER", "EXTENSION", MatchAny, "UPDATE")) + else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions_with_TO); } /* ALTER EXTENSION UPDATE TO */ - else if (Matches5("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO")) + else if (Matches("ALTER", "EXTENSION", MatchAny, "UPDATE", "TO")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions); } /* ALTER FOREIGN */ - else if (Matches2("ALTER", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("ALTER", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* ALTER FOREIGN DATA WRAPPER */ - else if (Matches5("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny)) - COMPLETE_WITH_LIST5("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS", "OWNER TO", "RENAME TO"); /* ALTER FOREIGN TABLE */ - else if (Matches4("ALTER", "FOREIGN", "TABLE", MatchAny)) - { - static const char *const list_ALTER_FOREIGN_TABLE[] = - {"ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", "INHERIT", - "NO INHERIT", "OPTIONS", "OWNER TO", "RENAME", "SET", - "VALIDATE CONSTRAINT", NULL}; - - COMPLETE_WITH_LIST(list_ALTER_FOREIGN_TABLE); - } + else if (Matches("ALTER", "FOREIGN", "TABLE", MatchAny)) + COMPLETE_WITH("ADD", "ALTER", "DISABLE TRIGGER", "DROP", "ENABLE", + "INHERIT", "NO INHERIT", "OPTIONS", "OWNER TO", + "RENAME", "SET", "VALIDATE CONSTRAINT"); /* ALTER INDEX */ - else if (Matches2("ALTER", "INDEX")) + else if (Matches("ALTER", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER INDEX */ - else if (Matches3("ALTER", "INDEX", MatchAny)) - COMPLETE_WITH_LIST6("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET", - "RESET", "ATTACH PARTITION"); - else if (Matches4("ALTER", "INDEX", MatchAny, "ATTACH")) - COMPLETE_WITH_CONST("PARTITION"); - else if (Matches5("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION")) + else if (Matches("ALTER", "INDEX", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", "SET", + "RESET", "ATTACH PARTITION"); + else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH")) + COMPLETE_WITH("PARTITION"); + else if (Matches("ALTER", "INDEX", MatchAny, "ATTACH", "PARTITION")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + /* ALTER INDEX ALTER */ + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER")) + COMPLETE_WITH("COLUMN"); + /* ALTER INDEX ALTER COLUMN */ + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN")) + { + completion_info_charp = prev3_wd; + COMPLETE_WITH_QUERY(Query_for_list_of_attribute_numbers); + } /* ALTER INDEX ALTER COLUMN */ - else if (Matches6("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny)) - COMPLETE_WITH_CONST("SET STATISTICS"); + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny)) + COMPLETE_WITH("SET STATISTICS"); + /* ALTER INDEX ALTER COLUMN SET */ + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET")) + COMPLETE_WITH("STATISTICS"); + /* ALTER INDEX ALTER COLUMN SET STATISTICS */ + else if (Matches("ALTER", "INDEX", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS")) + { + /* Enforce no completion here, as an integer has to be specified */ + } /* ALTER INDEX SET */ - else if (Matches4("ALTER", "INDEX", MatchAny, "SET")) - COMPLETE_WITH_LIST2("(", "TABLESPACE"); + else if (Matches("ALTER", "INDEX", MatchAny, "SET")) + COMPLETE_WITH("(", "TABLESPACE"); /* ALTER INDEX RESET */ - else if (Matches4("ALTER", "INDEX", MatchAny, "RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "INDEX", MatchAny, "RESET")) + COMPLETE_WITH("("); /* ALTER INDEX SET|RESET ( */ - else if (Matches5("ALTER", "INDEX", MatchAny, "RESET", "(")) - COMPLETE_WITH_LIST7("fillfactor", "recheck_on_update", - "fastupdate", "gin_pending_list_limit", /* GIN */ - "buffering", /* GiST */ - "pages_per_range", "autosummarize" /* BRIN */ + else if (Matches("ALTER", "INDEX", MatchAny, "RESET", "(")) + COMPLETE_WITH("fillfactor", + "vacuum_cleanup_index_scale_factor", /* BTREE */ + "fastupdate", "gin_pending_list_limit", /* GIN */ + "buffering", /* GiST */ + "pages_per_range", "autosummarize" /* BRIN */ ); - else if (Matches5("ALTER", "INDEX", MatchAny, "SET", "(")) - COMPLETE_WITH_LIST7("fillfactor =", "recheck_on_update =", - "fastupdate =", "gin_pending_list_limit =", /* GIN */ - "buffering =", /* GiST */ - "pages_per_range =", "autosummarize =" /* BRIN */ + else if (Matches("ALTER", "INDEX", MatchAny, "SET", "(")) + COMPLETE_WITH("fillfactor =", + "vacuum_cleanup_index_scale_factor =", /* BTREE */ + "fastupdate =", "gin_pending_list_limit =", /* GIN */ + "buffering =", /* GiST */ + "pages_per_range =", "autosummarize =" /* BRIN */ ); /* ALTER LANGUAGE */ - else if (Matches3("ALTER", "LANGUAGE", MatchAny)) - COMPLETE_WITH_LIST2("OWNER_TO", "RENAME TO"); + else if (Matches("ALTER", "LANGUAGE", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO"); /* ALTER LARGE OBJECT */ - else if (Matches4("ALTER", "LARGE", "OBJECT", MatchAny)) - COMPLETE_WITH_CONST("OWNER TO"); + else if (Matches("ALTER", "LARGE", "OBJECT", MatchAny)) + COMPLETE_WITH("OWNER TO"); /* ALTER MATERIALIZED VIEW */ - else if (Matches3("ALTER", "MATERIALIZED", "VIEW")) + else if (Matches("ALTER", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, "UNION SELECT 'ALL IN TABLESPACE'"); /* ALTER USER,ROLE */ - else if (Matches3("ALTER", "USER|ROLE", MatchAny) && - !TailMatches2("USER", "MAPPING")) - { - static const char *const list_ALTERUSER[] = - {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO", - "REPLICATION", "RESET", "SET", "SUPERUSER", - "VALID UNTIL", "WITH", NULL}; - - COMPLETE_WITH_LIST(list_ALTERUSER); - } + else if (Matches("ALTER", "USER|ROLE", MatchAny) && + !TailMatches("USER", "MAPPING")) + COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", + "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER", + "VALID UNTIL", "WITH"); /* ALTER USER,ROLE WITH */ - else if (Matches4("ALTER", "USER|ROLE", MatchAny, "WITH")) - { + else if (Matches("ALTER", "USER|ROLE", MatchAny, "WITH")) /* Similar to the above, but don't complete "WITH" again. */ - static const char *const list_ALTERUSER_WITH[] = - {"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO", - "REPLICATION", "RESET", "SET", "SUPERUSER", - "VALID UNTIL", NULL}; - - COMPLETE_WITH_LIST(list_ALTERUSER_WITH); - } + COMPLETE_WITH("BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", + "ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "RENAME TO", "REPLICATION", "RESET", "SET", "SUPERUSER", + "VALID UNTIL"); /* ALTER DEFAULT PRIVILEGES */ - else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("FOR ROLE", "IN SCHEMA"); /* ALTER DEFAULT PRIVILEGES FOR */ - else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "FOR")) - COMPLETE_WITH_CONST("ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR")) + COMPLETE_WITH("ROLE"); /* ALTER DEFAULT PRIVILEGES IN */ - else if (Matches4("ALTER", "DEFAULT", "PRIVILEGES", "IN")) - COMPLETE_WITH_CONST("SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN")) + COMPLETE_WITH("SCHEMA"); /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... */ - else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", - MatchAny)) - COMPLETE_WITH_LIST3("GRANT", "REVOKE", "IN SCHEMA"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE", "IN SCHEMA"); /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... */ - else if (Matches6("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny)) - COMPLETE_WITH_LIST3("GRANT", "REVOKE", "FOR ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE", "FOR ROLE"); /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR */ - else if (Matches7("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny, "FOR")) - COMPLETE_WITH_CONST("ROLE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR")) + COMPLETE_WITH("ROLE"); /* ALTER DEFAULT PRIVILEGES FOR ROLE|USER ... IN SCHEMA ... */ /* ALTER DEFAULT PRIVILEGES IN SCHEMA ... FOR ROLE|USER ... */ - else if (Matches9("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", - MatchAny, "IN", "SCHEMA", MatchAny) || - Matches9("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", - MatchAny, "FOR", "ROLE|USER", MatchAny)) - COMPLETE_WITH_LIST2("GRANT", "REVOKE"); + else if (Matches("ALTER", "DEFAULT", "PRIVILEGES", "FOR", "ROLE|USER", + MatchAny, "IN", "SCHEMA", MatchAny) || + Matches("ALTER", "DEFAULT", "PRIVILEGES", "IN", "SCHEMA", + MatchAny, "FOR", "ROLE|USER", MatchAny)) + COMPLETE_WITH("GRANT", "REVOKE"); /* ALTER DOMAIN */ - else if (Matches3("ALTER", "DOMAIN", MatchAny)) - COMPLETE_WITH_LIST6("ADD", "DROP", "OWNER TO", "RENAME", "SET", - "VALIDATE CONSTRAINT"); + else if (Matches("ALTER", "DOMAIN", MatchAny)) + COMPLETE_WITH("ADD", "DROP", "OWNER TO", "RENAME", "SET", + "VALIDATE CONSTRAINT"); /* ALTER DOMAIN DROP */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "DROP")) - COMPLETE_WITH_LIST3("CONSTRAINT", "DEFAULT", "NOT NULL"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP")) + COMPLETE_WITH("CONSTRAINT", "DEFAULT", "NOT NULL"); /* ALTER DOMAIN DROP|RENAME|VALIDATE CONSTRAINT */ - else if (Matches5("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT")) + else if (Matches("ALTER", "DOMAIN", MatchAny, "DROP|RENAME|VALIDATE", "CONSTRAINT")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_constraint_of_type); } /* ALTER DOMAIN RENAME */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "RENAME")) - COMPLETE_WITH_LIST2("CONSTRAINT", "TO"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME")) + COMPLETE_WITH("CONSTRAINT", "TO"); /* ALTER DOMAIN RENAME CONSTRAINT */ - else if (Matches6("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "RENAME", "CONSTRAINT", MatchAny)) + COMPLETE_WITH("TO"); /* ALTER DOMAIN SET */ - else if (Matches4("ALTER", "DOMAIN", MatchAny, "SET")) - COMPLETE_WITH_LIST3("DEFAULT", "NOT NULL", "SCHEMA"); + else if (Matches("ALTER", "DOMAIN", MatchAny, "SET")) + COMPLETE_WITH("DEFAULT", "NOT NULL", "SCHEMA"); /* ALTER SEQUENCE */ - else if (Matches3("ALTER", "SEQUENCE", MatchAny)) - { - static const char *const list_ALTERSEQUENCE[] = - {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", - "SET SCHEMA", "OWNED BY", "OWNER TO", "RENAME TO", NULL}; - - COMPLETE_WITH_LIST(list_ALTERSEQUENCE); - } + else if (Matches("ALTER", "SEQUENCE", MatchAny)) + COMPLETE_WITH("INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", + "CACHE", "CYCLE", "SET SCHEMA", "OWNED BY", "OWNER TO", + "RENAME TO"); /* ALTER SEQUENCE NO */ - else if (Matches4("ALTER", "SEQUENCE", MatchAny, "NO")) - COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE"); + else if (Matches("ALTER", "SEQUENCE", MatchAny, "NO")) + COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE"); /* ALTER SERVER */ - else if (Matches3("ALTER", "SERVER", MatchAny)) - COMPLETE_WITH_LIST4("VERSION", "OPTIONS", "OWNER TO", "RENAME TO"); + else if (Matches("ALTER", "SERVER", MatchAny)) + COMPLETE_WITH("VERSION", "OPTIONS", "OWNER TO", "RENAME TO"); /* ALTER SERVER VERSION */ - else if (Matches5("ALTER", "SERVER", MatchAny, "VERSION", MatchAny)) - COMPLETE_WITH_CONST("OPTIONS"); + else if (Matches("ALTER", "SERVER", MatchAny, "VERSION", MatchAny)) + COMPLETE_WITH("OPTIONS"); /* ALTER SYSTEM SET, RESET, RESET ALL */ - else if (Matches2("ALTER", "SYSTEM")) - COMPLETE_WITH_LIST2("SET", "RESET"); - else if (Matches3("ALTER", "SYSTEM", "SET|RESET")) + else if (Matches("ALTER", "SYSTEM")) + COMPLETE_WITH("SET", "RESET"); + else if (Matches("ALTER", "SYSTEM", "SET|RESET")) COMPLETE_WITH_QUERY(Query_for_list_of_alter_system_set_vars); - else if (Matches4("ALTER", "SYSTEM", "SET", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "SYSTEM", "SET", MatchAny)) + COMPLETE_WITH("TO"); /* ALTER VIEW */ - else if (Matches3("ALTER", "VIEW", MatchAny)) - COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO", - "SET SCHEMA"); + else if (Matches("ALTER", "VIEW", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", + "SET SCHEMA"); /* ALTER MATERIALIZED VIEW */ - else if (Matches4("ALTER", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_LIST4("ALTER COLUMN", "OWNER TO", "RENAME TO", - "SET SCHEMA"); + else if (Matches("ALTER", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("ALTER COLUMN", "OWNER TO", "RENAME TO", + "SET SCHEMA"); /* ALTER POLICY */ - else if (Matches2("ALTER", "POLICY")) + else if (Matches("ALTER", "POLICY")) COMPLETE_WITH_QUERY(Query_for_list_of_policies); /* ALTER POLICY ON */ - else if (Matches3("ALTER", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* ALTER POLICY ON
*/ - else if (Matches4("ALTER", "POLICY", MatchAny, "ON")) + else if (Matches("ALTER", "POLICY", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy); } /* ALTER POLICY ON
- show options */ - else if (Matches5("ALTER", "POLICY", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST4("RENAME TO", "TO", "USING (", "WITH CHECK ("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO", "TO", "USING (", "WITH CHECK ("); /* ALTER POLICY ON
TO */ - else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO")) + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* ALTER POLICY ON
USING ( */ - else if (Matches6("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "USING")) + COMPLETE_WITH("("); /* ALTER POLICY ON
WITH CHECK ( */ - else if (Matches7("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "POLICY", MatchAny, "ON", MatchAny, "WITH", "CHECK")) + COMPLETE_WITH("("); /* ALTER RULE , add ON */ - else if (Matches3("ALTER", "RULE", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "RULE", MatchAny)) + COMPLETE_WITH("ON"); /* If we have ALTER RULE ON, then add the correct tablename */ - else if (Matches4("ALTER", "RULE", MatchAny, "ON")) + else if (Matches("ALTER", "RULE", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule); } /* ALTER RULE ON */ - else if (Matches5("ALTER", "RULE", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_CONST("RENAME TO"); + else if (Matches("ALTER", "RULE", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO"); /* ALTER STATISTICS */ - else if (Matches3("ALTER", "STATISTICS", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "STATISTICS", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA", "SET STATISTICS"); /* ALTER TRIGGER , add ON */ - else if (Matches3("ALTER", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("ALTER", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); - else if (Matches4("ALTER", "TRIGGER", MatchAny, MatchAny)) + else if (Matches("ALTER", "TRIGGER", MatchAny, MatchAny)) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); @@ -2074,369 +1861,356 @@ psql_completion(const char *text, int start, int end) /* * If we have ALTER TRIGGER ON, then add the correct tablename */ - else if (Matches4("ALTER", "TRIGGER", MatchAny, "ON")) + else if (Matches("ALTER", "TRIGGER", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* ALTER TRIGGER ON */ - else if (Matches5("ALTER", "TRIGGER", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_CONST("RENAME TO"); + else if (Matches("ALTER", "TRIGGER", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("RENAME TO"); /* * If we detect ALTER TABLE , suggest sub commands */ - else if (Matches3("ALTER", "TABLE", MatchAny)) - { - static const char *const list_ALTER2[] = - {"ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", "ENABLE", "INHERIT", - "NO INHERIT", "RENAME", "RESET", "OWNER TO", "SET", - "VALIDATE CONSTRAINT", "REPLICA IDENTITY", "ATTACH PARTITION", - "DETACH PARTITION", NULL}; - - COMPLETE_WITH_LIST(list_ALTER2); - } + else if (Matches("ALTER", "TABLE", MatchAny)) + COMPLETE_WITH("ADD", "ALTER", "CLUSTER ON", "DISABLE", "DROP", + "ENABLE", "INHERIT", "NO INHERIT", "RENAME", "RESET", + "OWNER TO", "SET", "VALIDATE CONSTRAINT", + "REPLICA IDENTITY", "ATTACH PARTITION", + "DETACH PARTITION"); /* ALTER TABLE xxx ENABLE */ - else if (Matches4("ALTER", "TABLE", MatchAny, "ENABLE")) - COMPLETE_WITH_LIST5("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE", - "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS")) - COMPLETE_WITH_LIST2("RULE", "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE")) + COMPLETE_WITH("ALWAYS", "REPLICA", "ROW LEVEL SECURITY", "RULE", + "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "REPLICA|ALWAYS")) + COMPLETE_WITH("RULE", "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "RULE")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "RULE")) { completion_info_charp = prev4_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches5("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", "TRIGGER")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ENABLE", MatchAny, "TRIGGER")) { completion_info_charp = prev4_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } /* ALTER TABLE xxx INHERIT */ - else if (Matches4("ALTER", "TABLE", MatchAny, "INHERIT")) + else if (Matches("ALTER", "TABLE", MatchAny, "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* ALTER TABLE xxx NO INHERIT */ - else if (Matches5("ALTER", "TABLE", MatchAny, "NO", "INHERIT")) + else if (Matches("ALTER", "TABLE", MatchAny, "NO", "INHERIT")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* ALTER TABLE xxx DISABLE */ - else if (Matches4("ALTER", "TABLE", MatchAny, "DISABLE")) - COMPLETE_WITH_LIST3("ROW LEVEL SECURITY", "RULE", "TRIGGER"); - else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "RULE")) + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE")) + COMPLETE_WITH("ROW LEVEL SECURITY", "RULE", "TRIGGER"); + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "RULE")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_rule_of_table); } - else if (Matches5("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER")) + else if (Matches("ALTER", "TABLE", MatchAny, "DISABLE", "TRIGGER")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_trigger_of_table); } /* ALTER TABLE xxx ALTER */ - else if (Matches4("ALTER", "TABLE", MatchAny, "ALTER")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER")) COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT'"); /* ALTER TABLE xxx RENAME */ - else if (Matches4("ALTER", "TABLE", MatchAny, "RENAME")) + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME")) COMPLETE_WITH_ATTR(prev2_wd, " UNION SELECT 'COLUMN' UNION SELECT 'CONSTRAINT' UNION SELECT 'TO'"); - else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|RENAME", "COLUMN")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* ALTER TABLE xxx RENAME yyy */ - else if (Matches5("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO"))) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", MatchAnyExcept("CONSTRAINT|TO"))) + COMPLETE_WITH("TO"); /* ALTER TABLE xxx RENAME COLUMN/CONSTRAINT yyy */ - else if (Matches6("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO"))) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TABLE", MatchAny, "RENAME", "COLUMN|CONSTRAINT", MatchAnyExcept("TO"))) + COMPLETE_WITH("TO"); /* If we have ALTER TABLE DROP, provide COLUMN or CONSTRAINT */ - else if (Matches4("ALTER", "TABLE", MatchAny, "DROP")) - COMPLETE_WITH_LIST2("COLUMN", "CONSTRAINT"); + else if (Matches("ALTER", "TABLE", MatchAny, "DROP")) + COMPLETE_WITH("COLUMN", "CONSTRAINT"); /* If we have ALTER TABLE DROP COLUMN, provide list of columns */ - else if (Matches5("ALTER", "TABLE", MatchAny, "DROP", "COLUMN")) + else if (Matches("ALTER", "TABLE", MatchAny, "DROP", "COLUMN")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* * If we have ALTER TABLE ALTER|DROP|RENAME|VALIDATE CONSTRAINT, * provide list of constraints */ - else if (Matches5("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER|DROP|RENAME|VALIDATE", "CONSTRAINT")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_constraint_of_table); } /* ALTER TABLE ALTER [COLUMN] */ - else if (Matches6("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) || - Matches5("ALTER", "TABLE", MatchAny, "ALTER", MatchAny)) - COMPLETE_WITH_LIST6("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny) || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny)) + COMPLETE_WITH("TYPE", "SET", "RESET", "RESTART", "ADD", "DROP"); /* ALTER TABLE ALTER [COLUMN] SET */ - else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") || - Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET")) - COMPLETE_WITH_LIST5("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET")) + COMPLETE_WITH("(", "DEFAULT", "NOT NULL", "STATISTICS", "STORAGE"); /* ALTER TABLE ALTER [COLUMN] SET ( */ - else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") || - Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "(")) - COMPLETE_WITH_LIST2("n_distinct", "n_distinct_inherited"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "(") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "(")) + COMPLETE_WITH("n_distinct", "n_distinct_inherited"); /* ALTER TABLE ALTER [COLUMN] SET STORAGE */ - else if (Matches8("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") || - Matches7("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE")) - COMPLETE_WITH_LIST4("PLAIN", "EXTERNAL", "EXTENDED", "MAIN"); + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STORAGE") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STORAGE")) + COMPLETE_WITH("PLAIN", "EXTERNAL", "EXTENDED", "MAIN"); + /* ALTER TABLE ALTER [COLUMN] SET STATISTICS */ + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "SET", "STATISTICS") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "SET", "STATISTICS")) + { + /* Enforce no completion here, as an integer has to be specified */ + } /* ALTER TABLE ALTER [COLUMN] DROP */ - else if (Matches7("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") || - Matches6("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP")) - COMPLETE_WITH_LIST3("DEFAULT", "IDENTITY", "NOT NULL"); - else if (Matches4("ALTER", "TABLE", MatchAny, "CLUSTER")) - COMPLETE_WITH_CONST("ON"); - else if (Matches5("ALTER", "TABLE", MatchAny, "CLUSTER", "ON")) + else if (Matches("ALTER", "TABLE", MatchAny, "ALTER", "COLUMN", MatchAny, "DROP") || + Matches("ALTER", "TABLE", MatchAny, "ALTER", MatchAny, "DROP")) + COMPLETE_WITH("DEFAULT", "IDENTITY", "NOT NULL"); + else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER")) + COMPLETE_WITH("ON"); + else if (Matches("ALTER", "TABLE", MatchAny, "CLUSTER", "ON")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } /* If we have ALTER TABLE SET, provide list of attributes and '(' */ - else if (Matches4("ALTER", "TABLE", MatchAny, "SET")) - COMPLETE_WITH_LIST7("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED", - "WITH", "WITHOUT"); + else if (Matches("ALTER", "TABLE", MatchAny, "SET")) + COMPLETE_WITH("(", "LOGGED", "SCHEMA", "TABLESPACE", "UNLOGGED", + "WITH", "WITHOUT"); /* * If we have ALTER TABLE SET TABLESPACE provide a list of * tablespaces */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE")) + else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - /* If we have ALTER TABLE SET WITH provide OIDS */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITH")) - COMPLETE_WITH_CONST("OIDS"); /* If we have ALTER TABLE SET WITHOUT provide CLUSTER or OIDS */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET", "WITHOUT")) - COMPLETE_WITH_LIST2("CLUSTER", "OIDS"); + else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT")) + COMPLETE_WITH("CLUSTER", "OIDS"); /* ALTER TABLE RESET */ - else if (Matches4("ALTER", "TABLE", MatchAny, "RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "TABLE", MatchAny, "RESET")) + COMPLETE_WITH("("); /* ALTER TABLE SET|RESET ( */ - else if (Matches5("ALTER", "TABLE", MatchAny, "SET|RESET", "(")) - { - static const char *const list_TABLEOPTIONS[] = - { - "autovacuum_analyze_scale_factor", - "autovacuum_analyze_threshold", - "autovacuum_enabled", - "autovacuum_freeze_max_age", - "autovacuum_freeze_min_age", - "autovacuum_freeze_table_age", - "autovacuum_multixact_freeze_max_age", - "autovacuum_multixact_freeze_min_age", - "autovacuum_multixact_freeze_table_age", - "autovacuum_vacuum_cost_delay", - "autovacuum_vacuum_cost_limit", - "autovacuum_vacuum_scale_factor", - "autovacuum_vacuum_threshold", - "fillfactor", - "parallel_workers", - "log_autovacuum_min_duration", - "toast.autovacuum_enabled", - "toast.autovacuum_freeze_max_age", - "toast.autovacuum_freeze_min_age", - "toast.autovacuum_freeze_table_age", - "toast.autovacuum_multixact_freeze_max_age", - "toast.autovacuum_multixact_freeze_min_age", - "toast.autovacuum_multixact_freeze_table_age", - "toast.autovacuum_vacuum_cost_delay", - "toast.autovacuum_vacuum_cost_limit", - "toast.autovacuum_vacuum_scale_factor", - "toast.autovacuum_vacuum_threshold", - "toast.log_autovacuum_min_duration", - "user_catalog_table", - NULL - }; - - COMPLETE_WITH_LIST(list_TABLEOPTIONS); - } - else if (Matches7("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX")) + else if (Matches("ALTER", "TABLE", MatchAny, "SET|RESET", "(")) + COMPLETE_WITH_LIST(table_storage_parameters); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING", "INDEX")) { completion_info_charp = prev5_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } - else if (Matches6("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING")) - COMPLETE_WITH_CONST("INDEX"); - else if (Matches5("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY")) - COMPLETE_WITH_LIST4("FULL", "NOTHING", "DEFAULT", "USING"); - else if (Matches4("ALTER", "TABLE", MatchAny, "REPLICA")) - COMPLETE_WITH_CONST("IDENTITY"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY", "USING")) + COMPLETE_WITH("INDEX"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA", "IDENTITY")) + COMPLETE_WITH("FULL", "NOTHING", "DEFAULT", "USING"); + else if (Matches("ALTER", "TABLE", MatchAny, "REPLICA")) + COMPLETE_WITH("IDENTITY"); /* * If we have ALTER TABLE ATTACH PARTITION, provide a list of * tables. */ - else if (Matches5("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION")) + else if (Matches("ALTER", "TABLE", MatchAny, "ATTACH", "PARTITION")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* Limited completion support for partition bound specification */ - else if (TailMatches3("ATTACH", "PARTITION", MatchAny)) - COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT"); - else if (TailMatches2("FOR", "VALUES")) - COMPLETE_WITH_LIST3("FROM (", "IN (", "WITH ("); + else if (TailMatches("ATTACH", "PARTITION", MatchAny)) + COMPLETE_WITH("FOR VALUES", "DEFAULT"); + else if (TailMatches("FOR", "VALUES")) + COMPLETE_WITH("FROM (", "IN (", "WITH ("); /* * If we have ALTER TABLE DETACH PARTITION, provide a list of * partitions of . */ - else if (Matches5("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION")) + else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION")) { completion_info_charp = prev3_wd; COMPLETE_WITH_QUERY(Query_for_partition_of_table); } /* ALTER TABLESPACE with RENAME TO, OWNER TO, SET, RESET */ - else if (Matches3("ALTER", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST4("RENAME TO", "OWNER TO", "SET", "RESET"); + else if (Matches("ALTER", "TABLESPACE", MatchAny)) + COMPLETE_WITH("RENAME TO", "OWNER TO", "SET", "RESET"); /* ALTER TABLESPACE SET|RESET */ - else if (Matches4("ALTER", "TABLESPACE", MatchAny, "SET|RESET")) - COMPLETE_WITH_CONST("("); + else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET")) + COMPLETE_WITH("("); /* ALTER TABLESPACE SET|RESET ( */ - else if (Matches5("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "(")) - COMPLETE_WITH_LIST3("seq_page_cost", "random_page_cost", - "effective_io_concurrency"); + else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "(")) + COMPLETE_WITH("seq_page_cost", "random_page_cost", + "effective_io_concurrency"); /* ALTER TEXT SEARCH */ - else if (Matches3("ALTER", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny)) - COMPLETE_WITH_LIST2("RENAME TO", "SET SCHEMA"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny)) - COMPLETE_WITH_LIST3("OWNER TO", "RENAME TO", "SET SCHEMA"); - else if (Matches5("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) - COMPLETE_WITH_LIST6("ADD MAPPING FOR", "ALTER MAPPING", - "DROP MAPPING FOR", - "OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("ALTER", "TEXT", "SEARCH", "TEMPLATE|PARSER", MatchAny)) + COMPLETE_WITH("RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH", "DICTIONARY", MatchAny)) + COMPLETE_WITH("OWNER TO", "RENAME TO", "SET SCHEMA"); + else if (Matches("ALTER", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) + COMPLETE_WITH("ADD MAPPING FOR", "ALTER MAPPING", + "DROP MAPPING FOR", + "OWNER TO", "RENAME TO", "SET SCHEMA"); /* complete ALTER TYPE with actions */ - else if (Matches3("ALTER", "TYPE", MatchAny)) - COMPLETE_WITH_LIST7("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE", - "DROP ATTRIBUTE", - "OWNER TO", "RENAME", "SET SCHEMA"); + else if (Matches("ALTER", "TYPE", MatchAny)) + COMPLETE_WITH("ADD ATTRIBUTE", "ADD VALUE", "ALTER ATTRIBUTE", + "DROP ATTRIBUTE", + "OWNER TO", "RENAME", "SET SCHEMA"); /* complete ALTER TYPE ADD with actions */ - else if (Matches4("ALTER", "TYPE", MatchAny, "ADD")) - COMPLETE_WITH_LIST2("ATTRIBUTE", "VALUE"); + else if (Matches("ALTER", "TYPE", MatchAny, "ADD")) + COMPLETE_WITH("ATTRIBUTE", "VALUE"); /* ALTER TYPE RENAME */ - else if (Matches4("ALTER", "TYPE", MatchAny, "RENAME")) - COMPLETE_WITH_LIST3("ATTRIBUTE", "TO", "VALUE"); + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME")) + COMPLETE_WITH("ATTRIBUTE", "TO", "VALUE"); /* ALTER TYPE xxx RENAME (ATTRIBUTE|VALUE) yyy */ - else if (Matches6("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "ATTRIBUTE|VALUE", MatchAny)) + COMPLETE_WITH("TO"); /* * If we have ALTER TYPE ALTER/DROP/RENAME ATTRIBUTE, provide list * of attributes */ - else if (Matches5("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE")) + else if (Matches("ALTER", "TYPE", MatchAny, "ALTER|DROP|RENAME", "ATTRIBUTE")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* ALTER TYPE ALTER ATTRIBUTE */ - else if (Matches6("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny)) - COMPLETE_WITH_CONST("TYPE"); + else if (Matches("ALTER", "TYPE", MatchAny, "ALTER", "ATTRIBUTE", MatchAny)) + COMPLETE_WITH("TYPE"); /* complete ALTER GROUP */ - else if (Matches3("ALTER", "GROUP", MatchAny)) - COMPLETE_WITH_LIST3("ADD USER", "DROP USER", "RENAME TO"); + else if (Matches("ALTER", "GROUP", MatchAny)) + COMPLETE_WITH("ADD USER", "DROP USER", "RENAME TO"); /* complete ALTER GROUP ADD|DROP with USER */ - else if (Matches4("ALTER", "GROUP", MatchAny, "ADD|DROP")) - COMPLETE_WITH_CONST("USER"); + else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP")) + COMPLETE_WITH("USER"); /* complete ALTER GROUP ADD|DROP USER with a user name */ - else if (Matches5("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER")) + else if (Matches("ALTER", "GROUP", MatchAny, "ADD|DROP", "USER")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* * If we have ALTER TYPE RENAME VALUE, provide list of enum values */ - else if (Matches5("ALTER", "TYPE", MatchAny, "RENAME", "VALUE")) + else if (Matches("ALTER", "TYPE", MatchAny, "RENAME", "VALUE")) COMPLETE_WITH_ENUM_VALUE(prev3_wd); +/* + * ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ] + * ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ] + */ + else if (Matches("ANALYZE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, + " UNION SELECT 'VERBOSE'"); + else if (HeadMatches("ANALYZE", "(*") && + !HeadMatches("ANALYZE", "(*)")) + { + /* + * This fires if we're in an unfinished parenthesized option list. + * get_previous_words treats a completed parenthesized option list as + * one word, so the above test is correct. + */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + COMPLETE_WITH("VERBOSE", "SKIP_LOCKED"); + else if (TailMatches("VERBOSE|SKIP_LOCKED")) + COMPLETE_WITH("ON", "OFF"); + } + else if (HeadMatches("ANALYZE") && TailMatches("(")) + /* "ANALYZE (" should be caught above, so assume we want columns */ + COMPLETE_WITH_ATTR(prev2_wd, ""); + else if (HeadMatches("ANALYZE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_analyzables, NULL); + /* BEGIN */ - else if (Matches1("BEGIN")) - COMPLETE_WITH_LIST6("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("BEGIN")) + COMPLETE_WITH("WORK", "TRANSACTION", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); /* END, ABORT */ - else if (Matches1("END|ABORT")) - COMPLETE_WITH_LIST2("WORK", "TRANSACTION"); + else if (Matches("END|ABORT")) + COMPLETE_WITH("AND", "WORK", "TRANSACTION"); /* COMMIT */ - else if (Matches1("COMMIT")) - COMPLETE_WITH_LIST3("WORK", "TRANSACTION", "PREPARED"); + else if (Matches("COMMIT")) + COMPLETE_WITH("AND", "WORK", "TRANSACTION", "PREPARED"); /* RELEASE SAVEPOINT */ - else if (Matches1("RELEASE")) - COMPLETE_WITH_CONST("SAVEPOINT"); + else if (Matches("RELEASE")) + COMPLETE_WITH("SAVEPOINT"); /* ROLLBACK */ - else if (Matches1("ROLLBACK")) - COMPLETE_WITH_LIST4("WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED"); + else if (Matches("ROLLBACK")) + COMPLETE_WITH("AND", "WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED"); + else if (Matches("ABORT|END|COMMIT|ROLLBACK", "AND")) + COMPLETE_WITH("CHAIN"); /* CALL */ - else if (Matches1("CALL")) + else if (Matches("CALL")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL); - else if (Matches2("CALL", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("CALL", MatchAny)) + COMPLETE_WITH("("); /* CLUSTER */ - else if (Matches1("CLUSTER")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, "UNION SELECT 'VERBOSE'"); - else if (Matches2("CLUSTER", "VERBOSE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL); + else if (Matches("CLUSTER")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, "UNION SELECT 'VERBOSE'"); + else if (Matches("CLUSTER", "VERBOSE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_clusterables, NULL); /* If we have CLUSTER , then add "USING" */ - else if (Matches2("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) - COMPLETE_WITH_CONST("USING"); + else if (Matches("CLUSTER", MatchAnyExcept("VERBOSE|ON"))) + COMPLETE_WITH("USING"); /* If we have CLUSTER VERBOSE , then add "USING" */ - else if (Matches3("CLUSTER", "VERBOSE", MatchAny)) - COMPLETE_WITH_CONST("USING"); + else if (Matches("CLUSTER", "VERBOSE", MatchAny)) + COMPLETE_WITH("USING"); /* If we have CLUSTER USING, then add the index as well */ - else if (Matches3("CLUSTER", MatchAny, "USING") || - Matches4("CLUSTER", "VERBOSE", MatchAny, "USING")) + else if (Matches("CLUSTER", MatchAny, "USING") || + Matches("CLUSTER", "VERBOSE", MatchAny, "USING")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_index_of_table); } /* COMMENT */ - else if (Matches1("COMMENT")) - COMPLETE_WITH_CONST("ON"); - else if (Matches2("COMMENT", "ON")) - { - static const char *const list_COMMENT[] = - {"ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", "DATABASE", - "EVENT TRIGGER", "EXTENSION", - "FOREIGN DATA WRAPPER", "FOREIGN TABLE", - "SERVER", "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE", - "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION", - "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", "COLUMN", "AGGREGATE", "FUNCTION", - "PROCEDURE", "ROUTINE", - "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", - "TABLESPACE", "TEXT SEARCH", "ROLE", NULL}; - - COMPLETE_WITH_LIST(list_COMMENT); - } - else if (Matches4("COMMENT", "ON", "ACCESS", "METHOD")) + else if (Matches("COMMENT")) + COMPLETE_WITH("ON"); + else if (Matches("COMMENT", "ON")) + COMPLETE_WITH("ACCESS METHOD", "CAST", "COLLATION", "CONVERSION", + "DATABASE", "EVENT TRIGGER", "EXTENSION", + "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "SERVER", + "INDEX", "LANGUAGE", "POLICY", "PUBLICATION", "RULE", + "SCHEMA", "SEQUENCE", "STATISTICS", "SUBSCRIPTION", + "TABLE", "TYPE", "VIEW", "MATERIALIZED VIEW", + "COLUMN", "AGGREGATE", "FUNCTION", + "PROCEDURE", "ROUTINE", + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", + "LARGE OBJECT", "TABLESPACE", "TEXT SEARCH", "ROLE"); + else if (Matches("COMMENT", "ON", "ACCESS", "METHOD")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (Matches3("COMMENT", "ON", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); - else if (Matches4("COMMENT", "ON", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches3("COMMENT", "ON", "CONSTRAINT")) + else if (Matches("COMMENT", "ON", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); + else if (Matches("COMMENT", "ON", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("COMMENT", "ON", "CONSTRAINT")) COMPLETE_WITH_QUERY(Query_for_all_table_constraints); - else if (Matches4("COMMENT", "ON", "CONSTRAINT", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches5("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON")) + else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("COMMENT", "ON", "CONSTRAINT", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_constraint); } - else if (Matches4("COMMENT", "ON", "MATERIALIZED", "VIEW")) + else if (Matches("COMMENT", "ON", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (Matches4("COMMENT", "ON", "EVENT", "TRIGGER")) + else if (Matches("COMMENT", "ON", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); - else if (Matches4("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) || - Matches5("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) || - Matches6("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS"))) - COMPLETE_WITH_CONST("IS"); + else if (Matches("COMMENT", "ON", MatchAny, MatchAnyExcept("IS")) || + Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAnyExcept("IS")) || + Matches("COMMENT", "ON", MatchAny, MatchAny, MatchAny, MatchAnyExcept("IS"))) + COMPLETE_WITH("IS"); /* COPY */ @@ -2444,626 +2218,775 @@ psql_completion(const char *text, int start, int end) * If we have COPY, offer list of tables or "(" (Also cover the analogous * backslash command). */ - else if (Matches1("COPY|\\copy")) + else if (Matches("COPY|\\copy")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, " UNION ALL SELECT '('"); /* If we have COPY BINARY, complete with list of tables */ - else if (Matches2("COPY", "BINARY")) + else if (Matches("COPY", "BINARY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* If we have COPY (, complete it with legal commands */ - else if (Matches2("COPY|\\copy", "(")) - COMPLETE_WITH_LIST7("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH"); + else if (Matches("COPY|\\copy", "(")) + COMPLETE_WITH("SELECT", "TABLE", "VALUES", "INSERT", "UPDATE", "DELETE", "WITH"); /* If we have COPY [BINARY] , complete it with "TO" or "FROM" */ - else if (Matches2("COPY|\\copy", MatchAny) || - Matches3("COPY", "BINARY", MatchAny)) - COMPLETE_WITH_LIST2("FROM", "TO"); + else if (Matches("COPY|\\copy", MatchAny) || + Matches("COPY", "BINARY", MatchAny)) + COMPLETE_WITH("FROM", "TO"); /* If we have COPY [BINARY] FROM|TO, complete with filename */ - else if (Matches3("COPY|\\copy", MatchAny, "FROM|TO") || - Matches4("COPY", "BINARY", MatchAny, "FROM|TO")) + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO") || + Matches("COPY", "BINARY", MatchAny, "FROM|TO")) { completion_charp = ""; matches = completion_matches(text, complete_from_files); } /* Handle COPY [BINARY] FROM|TO filename */ - else if (Matches4("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) || - Matches5("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny)) - COMPLETE_WITH_LIST6("BINARY", "OIDS", "DELIMITER", "NULL", "CSV", - "ENCODING"); + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) || + Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny)) + COMPLETE_WITH("BINARY", "DELIMITER", "NULL", "CSV", + "ENCODING"); /* Handle COPY [BINARY] FROM|TO filename CSV */ - else if (Matches5("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") || - Matches6("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV")) - COMPLETE_WITH_LIST5("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", - "FORCE NOT NULL"); + else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny, "CSV") || + Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny, "CSV")) + COMPLETE_WITH("HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", + "FORCE NOT NULL"); /* CREATE ACCESS METHOD */ /* Complete "CREATE ACCESS METHOD " */ - else if (Matches4("CREATE", "ACCESS", "METHOD", MatchAny)) - COMPLETE_WITH_CONST("TYPE"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny)) + COMPLETE_WITH("TYPE"); /* Complete "CREATE ACCESS METHOD TYPE" */ - else if (Matches5("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE")) - COMPLETE_WITH_CONST("INDEX"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE")) + COMPLETE_WITH("INDEX", "TABLE"); /* Complete "CREATE ACCESS METHOD TYPE " */ - else if (Matches6("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny)) - COMPLETE_WITH_CONST("HANDLER"); + else if (Matches("CREATE", "ACCESS", "METHOD", MatchAny, "TYPE", MatchAny)) + COMPLETE_WITH("HANDLER"); /* CREATE DATABASE */ - else if (Matches3("CREATE", "DATABASE", MatchAny)) - COMPLETE_WITH_LIST9("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", - "IS_TEMPLATE", - "ALLOW_CONNECTIONS", "CONNECTION LIMIT", - "LC_COLLATE", "LC_CTYPE"); + else if (Matches("CREATE", "DATABASE", MatchAny)) + COMPLETE_WITH("OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", + "IS_TEMPLATE", + "ALLOW_CONNECTIONS", "CONNECTION LIMIT", + "LC_COLLATE", "LC_CTYPE"); - else if (Matches4("CREATE", "DATABASE", MatchAny, "TEMPLATE")) + else if (Matches("CREATE", "DATABASE", MatchAny, "TEMPLATE")) COMPLETE_WITH_QUERY(Query_for_list_of_template_databases); /* CREATE EXTENSION */ /* Complete with available extensions rather than installed ones. */ - else if (Matches2("CREATE", "EXTENSION")) + else if (Matches("CREATE", "EXTENSION")) COMPLETE_WITH_QUERY(Query_for_list_of_available_extensions); /* CREATE EXTENSION */ - else if (Matches3("CREATE", "EXTENSION", MatchAny)) - COMPLETE_WITH_LIST3("WITH SCHEMA", "CASCADE", "VERSION"); + else if (Matches("CREATE", "EXTENSION", MatchAny)) + COMPLETE_WITH("WITH SCHEMA", "CASCADE", "VERSION"); /* CREATE EXTENSION VERSION */ - else if (Matches4("CREATE", "EXTENSION", MatchAny, "VERSION")) + else if (Matches("CREATE", "EXTENSION", MatchAny, "VERSION")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_available_extension_versions); } /* CREATE FOREIGN */ - else if (Matches2("CREATE", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("CREATE", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* CREATE FOREIGN DATA WRAPPER */ - else if (Matches5("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny)) - COMPLETE_WITH_LIST3("HANDLER", "VALIDATOR", "OPTIONS"); + else if (Matches("CREATE", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + COMPLETE_WITH("HANDLER", "VALIDATOR", "OPTIONS"); /* CREATE INDEX --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* First off we complete CREATE UNIQUE with "INDEX" */ - else if (TailMatches2("CREATE", "UNIQUE")) - COMPLETE_WITH_CONST("INDEX"); + else if (TailMatches("CREATE", "UNIQUE")) + COMPLETE_WITH("INDEX"); /* * If we have CREATE|UNIQUE INDEX, then add "ON", "CONCURRENTLY", and * existing indexes */ - else if (TailMatches2("CREATE|UNIQUE", "INDEX")) + else if (TailMatches("CREATE|UNIQUE", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'ON'" " UNION SELECT 'CONCURRENTLY'"); + /* * Complete ... INDEX|CONCURRENTLY [] ON with a list of relations - * that can indexes can be created on + * that indexes can be created on */ - else if (TailMatches3("INDEX|CONCURRENTLY", MatchAny, "ON") || - TailMatches2("INDEX|CONCURRENTLY", "ON")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tpm, NULL); + else if (TailMatches("INDEX|CONCURRENTLY", MatchAny, "ON") || + TailMatches("INDEX|CONCURRENTLY", "ON")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL); /* * Complete CREATE|UNIQUE INDEX CONCURRENTLY with "ON" and existing * indexes */ - else if (TailMatches3("CREATE|UNIQUE", "INDEX", "CONCURRENTLY")) + else if (TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'ON'"); /* Complete CREATE|UNIQUE INDEX [CONCURRENTLY] with "ON" */ - else if (TailMatches3("CREATE|UNIQUE", "INDEX", MatchAny) || - TailMatches4("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (TailMatches("CREATE|UNIQUE", "INDEX", MatchAny) || + TailMatches("CREATE|UNIQUE", "INDEX", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("ON"); /* * Complete INDEX ON
with a list of table columns (which * should really be in parens) */ - else if (TailMatches4("INDEX", MatchAny, "ON", MatchAny) || - TailMatches3("INDEX|CONCURRENTLY", "ON", MatchAny)) - COMPLETE_WITH_LIST2("(", "USING"); - else if (TailMatches5("INDEX", MatchAny, "ON", MatchAny, "(") || - TailMatches4("INDEX|CONCURRENTLY", "ON", MatchAny, "(")) + else if (TailMatches("INDEX", MatchAny, "ON", MatchAny) || + TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny)) + COMPLETE_WITH("(", "USING"); + else if (TailMatches("INDEX", MatchAny, "ON", MatchAny, "(") || + TailMatches("INDEX|CONCURRENTLY", "ON", MatchAny, "(")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* same if you put in USING */ - else if (TailMatches5("ON", MatchAny, "USING", MatchAny, "(")) + else if (TailMatches("ON", MatchAny, "USING", MatchAny, "(")) COMPLETE_WITH_ATTR(prev4_wd, ""); /* Complete USING with an index method */ - else if (TailMatches6("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") || - TailMatches5("INDEX", MatchAny, "ON", MatchAny, "USING") || - TailMatches4("INDEX", "ON", MatchAny, "USING")) - COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (TailMatches4("ON", MatchAny, "USING", MatchAny) && - !TailMatches6("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) && - !TailMatches4("FOR", MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("("); + else if (TailMatches("INDEX", MatchAny, MatchAny, "ON", MatchAny, "USING") || + TailMatches("INDEX", MatchAny, "ON", MatchAny, "USING") || + TailMatches("INDEX", "ON", MatchAny, "USING")) + COMPLETE_WITH_QUERY(Query_for_list_of_index_access_methods); + else if (TailMatches("ON", MatchAny, "USING", MatchAny) && + !TailMatches("POLICY", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny) && + !TailMatches("FOR", MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("("); + + /* CREATE OR REPLACE */ + else if (Matches("CREATE", "OR")) + COMPLETE_WITH("REPLACE"); /* CREATE POLICY */ /* Complete "CREATE POLICY ON" */ - else if (Matches3("CREATE", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("CREATE", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* Complete "CREATE POLICY ON
" */ - else if (Matches4("CREATE", "POLICY", MatchAny, "ON")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* Complete "CREATE POLICY ON
AS|FOR|TO|USING|WITH CHECK" */ - else if (Matches5("CREATE", "POLICY", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST5("AS", "FOR", "TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("AS", "FOR", "TO", "USING (", "WITH CHECK ("); /* CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS")) - COMPLETE_WITH_LIST2("PERMISSIVE", "RESTRICTIVE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS")) + COMPLETE_WITH("PERMISSIVE", "RESTRICTIVE"); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE * FOR|TO|USING|WITH CHECK */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny)) - COMPLETE_WITH_LIST4("FOR", "TO", "USING", "WITH CHECK"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny)) + COMPLETE_WITH("FOR", "TO", "USING", "WITH CHECK"); /* CREATE POLICY ON
FOR ALL|SELECT|INSERT|UPDATE|DELETE */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR")) - COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR")) + COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); /* Complete "CREATE POLICY ON
FOR INSERT TO|WITH CHECK" */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT")) - COMPLETE_WITH_LIST2("TO", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "INSERT")) + COMPLETE_WITH("TO", "WITH CHECK ("); /* Complete "CREATE POLICY ON
FOR SELECT|DELETE TO|USING" */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE")) - COMPLETE_WITH_LIST2("TO", "USING ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "SELECT|DELETE")) + COMPLETE_WITH("TO", "USING ("); /* CREATE POLICY ON
FOR ALL|UPDATE TO|USING|WITH CHECK */ - else if (Matches7("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE")) - COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "FOR", "ALL|UPDATE")) + COMPLETE_WITH("TO", "USING (", "WITH CHECK ("); /* Complete "CREATE POLICY ON
TO " */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "CREATE POLICY ON
USING (" */ - else if (Matches6("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "USING")) + COMPLETE_WITH("("); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * ALL|SELECT|INSERT|UPDATE|DELETE */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR")) - COMPLETE_WITH_LIST5("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR")) + COMPLETE_WITH("ALL", "SELECT", "INSERT", "UPDATE", "DELETE"); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * INSERT TO|WITH CHECK" */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT")) - COMPLETE_WITH_LIST2("TO", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "INSERT")) + COMPLETE_WITH("TO", "WITH CHECK ("); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * SELECT|DELETE TO|USING" */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE")) - COMPLETE_WITH_LIST2("TO", "USING ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "SELECT|DELETE")) + COMPLETE_WITH("TO", "USING ("); /* * CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE FOR * ALL|UPDATE TO|USING|WITH CHECK */ - else if (Matches9("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE")) - COMPLETE_WITH_LIST3("TO", "USING (", "WITH CHECK ("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "FOR", "ALL|UPDATE")) + COMPLETE_WITH("TO", "USING (", "WITH CHECK ("); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE TO * " */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO")) + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* * Complete "CREATE POLICY ON
AS PERMISSIVE|RESTRICTIVE * USING (" */ - else if (Matches8("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING")) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "POLICY", MatchAny, "ON", MatchAny, "AS", MatchAny, "USING")) + COMPLETE_WITH("("); /* CREATE PUBLICATION */ - else if (Matches3("CREATE", "PUBLICATION", MatchAny)) - COMPLETE_WITH_LIST3("FOR TABLE", "FOR ALL TABLES", "WITH ("); - else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR")) - COMPLETE_WITH_LIST2("TABLE", "ALL TABLES"); - /* Complete "CREATE PUBLICATION FOR TABLE
" */ - else if (Matches4("CREATE", "PUBLICATION", MatchAny, "FOR TABLE")) + else if (Matches("CREATE", "PUBLICATION", MatchAny)) + COMPLETE_WITH("FOR TABLE", "FOR ALL TABLES", "WITH ("); + else if (Matches("CREATE", "PUBLICATION", MatchAny, "FOR")) + COMPLETE_WITH("TABLE", "ALL TABLES"); + /* Complete "CREATE PUBLICATION FOR TABLE
, ..." */ + else if (HeadMatches("CREATE", "PUBLICATION", MatchAny, "FOR", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* Complete "CREATE PUBLICATION [...] WITH" */ - else if (HeadMatches2("CREATE", "PUBLICATION") && TailMatches2("WITH", "(")) - COMPLETE_WITH_CONST("publish"); + else if (HeadMatches("CREATE", "PUBLICATION") && TailMatches("WITH", "(")) + COMPLETE_WITH("publish"); /* CREATE RULE */ - /* Complete "CREATE RULE " with "AS ON" */ - else if (Matches3("CREATE", "RULE", MatchAny)) - COMPLETE_WITH_CONST("AS ON"); - /* Complete "CREATE RULE AS" with "ON" */ - else if (Matches4("CREATE", "RULE", MatchAny, "AS")) - COMPLETE_WITH_CONST("ON"); - /* Complete "CREATE RULE AS ON" with SELECT|UPDATE|INSERT|DELETE */ - else if (Matches5("CREATE", "RULE", MatchAny, "AS", "ON")) - COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE"); + /* Complete "CREATE [ OR REPLACE ] RULE " with "AS ON" */ + else if (Matches("CREATE", "RULE", MatchAny) || + Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny)) + COMPLETE_WITH("AS ON"); + /* Complete "CREATE [ OR REPLACE ] RULE AS" with "ON" */ + else if (Matches("CREATE", "RULE", MatchAny, "AS") || + Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS")) + COMPLETE_WITH("ON"); + /* Complete "CREATE [ OR REPLACE ] RULE AS ON" with SELECT|UPDATE|INSERT|DELETE */ + else if (Matches("CREATE", "RULE", MatchAny, "AS", "ON") || + Matches("CREATE", "OR", "REPLACE", "RULE", MatchAny, "AS", "ON")) + COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE"); /* Complete "AS ON SELECT|UPDATE|INSERT|DELETE" with a "TO" */ - else if (TailMatches3("AS", "ON", "SELECT|UPDATE|INSERT|DELETE")) - COMPLETE_WITH_CONST("TO"); + else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE")) + COMPLETE_WITH("TO"); /* Complete "AS ON TO" with a table name */ - else if (TailMatches4("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO")) + else if (TailMatches("AS", "ON", "SELECT|UPDATE|INSERT|DELETE", "TO")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* CREATE SEQUENCE --- is allowed inside CREATE SCHEMA, so use TailMatches */ - else if (TailMatches3("CREATE", "SEQUENCE", MatchAny) || - TailMatches4("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny)) - COMPLETE_WITH_LIST8("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE", - "CYCLE", "OWNED BY", "START WITH"); - else if (TailMatches4("CREATE", "SEQUENCE", MatchAny, "NO") || - TailMatches5("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO")) - COMPLETE_WITH_LIST3("MINVALUE", "MAXVALUE", "CYCLE"); + else if (TailMatches("CREATE", "SEQUENCE", MatchAny) || + TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny)) + COMPLETE_WITH("INCREMENT BY", "MINVALUE", "MAXVALUE", "NO", "CACHE", + "CYCLE", "OWNED BY", "START WITH"); + else if (TailMatches("CREATE", "SEQUENCE", MatchAny, "NO") || + TailMatches("CREATE", "TEMP|TEMPORARY", "SEQUENCE", MatchAny, "NO")) + COMPLETE_WITH("MINVALUE", "MAXVALUE", "CYCLE"); /* CREATE SERVER */ - else if (Matches3("CREATE", "SERVER", MatchAny)) - COMPLETE_WITH_LIST3("TYPE", "VERSION", "FOREIGN DATA WRAPPER"); + else if (Matches("CREATE", "SERVER", MatchAny)) + COMPLETE_WITH("TYPE", "VERSION", "FOREIGN DATA WRAPPER"); /* CREATE STATISTICS */ - else if (Matches3("CREATE", "STATISTICS", MatchAny)) - COMPLETE_WITH_LIST2("(", "ON"); - else if (Matches4("CREATE", "STATISTICS", MatchAny, "(")) - COMPLETE_WITH_LIST2("ndistinct", "dependencies"); - else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) && - previous_words[0][0] == '(' && - previous_words[0][strlen(previous_words[0]) - 1] == ')') - COMPLETE_WITH_CONST("ON"); - else if (HeadMatches3("CREATE", "STATISTICS", MatchAny) && - TailMatches1("FROM")) + else if (Matches("CREATE", "STATISTICS", MatchAny)) + COMPLETE_WITH("(", "ON"); + else if (Matches("CREATE", "STATISTICS", MatchAny, "(")) + COMPLETE_WITH("ndistinct", "dependencies", "mcv"); + else if (Matches("CREATE", "STATISTICS", MatchAny, "(*)")) + COMPLETE_WITH("ON"); + else if (HeadMatches("CREATE", "STATISTICS", MatchAny) && + TailMatches("FROM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* CREATE TABLE --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* Complete "CREATE TEMP/TEMPORARY" with the possible temp objects */ - else if (TailMatches2("CREATE", "TEMP|TEMPORARY")) - COMPLETE_WITH_LIST3("SEQUENCE", "TABLE", "VIEW"); + else if (TailMatches("CREATE", "TEMP|TEMPORARY")) + COMPLETE_WITH("SEQUENCE", "TABLE", "VIEW"); /* Complete "CREATE UNLOGGED" with TABLE or MATVIEW */ - else if (TailMatches2("CREATE", "UNLOGGED")) - COMPLETE_WITH_LIST2("TABLE", "MATERIALIZED VIEW"); + else if (TailMatches("CREATE", "UNLOGGED")) + COMPLETE_WITH("TABLE", "MATERIALIZED VIEW"); /* Complete PARTITION BY with RANGE ( or LIST ( or ... */ - else if (TailMatches2("PARTITION", "BY")) - COMPLETE_WITH_LIST2("RANGE (", "LIST ("); + else if (TailMatches("PARTITION", "BY")) + COMPLETE_WITH("RANGE (", "LIST (", "HASH ("); /* If we have xxx PARTITION OF, provide a list of partitioned tables */ - else if (TailMatches2("PARTITION", "OF")) + else if (TailMatches("PARTITION", "OF")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, ""); /* Limited completion support for partition bound specification */ - else if (TailMatches3("PARTITION", "OF", MatchAny)) - COMPLETE_WITH_LIST2("FOR VALUES", "DEFAULT"); + else if (TailMatches("PARTITION", "OF", MatchAny)) + COMPLETE_WITH("FOR VALUES", "DEFAULT"); + /* Complete CREATE TABLE with '(', OF or PARTITION OF */ + else if (TailMatches("CREATE", "TABLE", MatchAny) || + TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny)) + COMPLETE_WITH("(", "OF", "PARTITION OF"); + /* Complete CREATE TABLE OF with list of composite types */ + else if (TailMatches("CREATE", "TABLE", MatchAny, "OF") || + TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "OF")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes, NULL); + /* Complete CREATE TABLE name (...) with supported options */ + else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)") || + TailMatches("CREATE", "UNLOGGED", "TABLE", MatchAny, "(*)")) + COMPLETE_WITH("INHERITS (", "PARTITION BY", "USING", "TABLESPACE", "WITH ("); + else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)")) + COMPLETE_WITH("INHERITS (", "ON COMMIT", "PARTITION BY", + "TABLESPACE", "WITH ("); + /* Complete CREATE TABLE (...) USING with table access methods */ + else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "USING") || + TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "USING")) + COMPLETE_WITH_QUERY(Query_for_list_of_table_access_methods); + /* Complete CREATE TABLE (...) WITH with storage parameters */ + else if (TailMatches("CREATE", "TABLE", MatchAny, "(*)", "WITH", "(") || + TailMatches("CREATE", "TEMP|TEMPORARY|UNLOGGED", "TABLE", MatchAny, "(*)", "WITH", "(")) + COMPLETE_WITH_LIST(table_storage_parameters); + /* Complete CREATE TABLE ON COMMIT with actions */ + else if (TailMatches("CREATE", "TEMP|TEMPORARY", "TABLE", MatchAny, "(*)", "ON", "COMMIT")) + COMPLETE_WITH("DELETE ROWS", "DROP", "PRESERVE ROWS"); /* CREATE TABLESPACE */ - else if (Matches3("CREATE", "TABLESPACE", MatchAny)) - COMPLETE_WITH_LIST2("OWNER", "LOCATION"); + else if (Matches("CREATE", "TABLESPACE", MatchAny)) + COMPLETE_WITH("OWNER", "LOCATION"); /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */ - else if (Matches5("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny)) - COMPLETE_WITH_CONST("LOCATION"); + else if (Matches("CREATE", "TABLESPACE", MatchAny, "OWNER", MatchAny)) + COMPLETE_WITH("LOCATION"); /* CREATE TEXT SEARCH */ - else if (Matches3("CREATE", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (Matches5("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (Matches("CREATE", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("CREATE", "TEXT", "SEARCH", "CONFIGURATION", MatchAny)) + COMPLETE_WITH("("); /* CREATE SUBSCRIPTION */ - else if (Matches3("CREATE", "SUBSCRIPTION", MatchAny)) - COMPLETE_WITH_CONST("CONNECTION"); - else if (Matches5("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny)) - COMPLETE_WITH_CONST("PUBLICATION"); - else if (Matches6("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", - MatchAny, "PUBLICATION")) + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny)) + COMPLETE_WITH("CONNECTION"); + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", MatchAny)) + COMPLETE_WITH("PUBLICATION"); + else if (Matches("CREATE", "SUBSCRIPTION", MatchAny, "CONNECTION", + MatchAny, "PUBLICATION")) { /* complete with nothing here as this refers to remote publications */ } - else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("PUBLICATION", MatchAny)) - COMPLETE_WITH_CONST("WITH ("); + else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("PUBLICATION", MatchAny)) + COMPLETE_WITH("WITH ("); /* Complete "CREATE SUBSCRIPTION ... WITH ( " */ - else if (HeadMatches2("CREATE", "SUBSCRIPTION") && TailMatches2("WITH", "(")) - COMPLETE_WITH_LIST6("copy_data", "connect", "create_slot", "enabled", - "slot_name", "synchronous_commit"); + else if (HeadMatches("CREATE", "SUBSCRIPTION") && TailMatches("WITH", "(")) + COMPLETE_WITH("copy_data", "connect", "create_slot", "enabled", + "slot_name", "synchronous_commit"); /* CREATE TRIGGER --- is allowed inside CREATE SCHEMA, so use TailMatches */ /* complete CREATE TRIGGER with BEFORE,AFTER,INSTEAD OF */ - else if (TailMatches3("CREATE", "TRIGGER", MatchAny)) - COMPLETE_WITH_LIST3("BEFORE", "AFTER", "INSTEAD OF"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny)) + COMPLETE_WITH("BEFORE", "AFTER", "INSTEAD OF"); /* complete CREATE TRIGGER BEFORE,AFTER with an event */ - else if (TailMatches4("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER")) - COMPLETE_WITH_LIST4("INSERT", "DELETE", "UPDATE", "TRUNCATE"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER")) + COMPLETE_WITH("INSERT", "DELETE", "UPDATE", "TRUNCATE"); /* complete CREATE TRIGGER INSTEAD OF with an event */ - else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF")) - COMPLETE_WITH_LIST3("INSERT", "DELETE", "UPDATE"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF")) + COMPLETE_WITH("INSERT", "DELETE", "UPDATE"); /* complete CREATE TRIGGER BEFORE,AFTER sth with OR,ON */ - else if (TailMatches5("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || - TailMatches6("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) - COMPLETE_WITH_LIST2("ON", "OR"); + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny) || + TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny)) + COMPLETE_WITH("ON", "OR"); /* * complete CREATE TRIGGER BEFORE,AFTER event ON with a list of - * tables + * tables. EXECUTE FUNCTION is the recommended grammar instead of EXECUTE + * PROCEDURE in version 11 and upwards. */ - else if (TailMatches6("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "BEFORE|AFTER", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* complete CREATE TRIGGER ... INSTEAD OF event ON with a list of views */ - else if (TailMatches7("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) + else if (TailMatches("CREATE", "TRIGGER", MatchAny, "INSTEAD", "OF", MatchAny, "ON")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("ON", MatchAny)) - COMPLETE_WITH_LIST7("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", - "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches1("DEFERRABLE") || TailMatches2("INITIALLY", "IMMEDIATE|DEFERRED"))) - COMPLETE_WITH_LIST4("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("REFERENCING")) - COMPLETE_WITH_LIST2("OLD TABLE", "NEW TABLE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("OLD|NEW", "TABLE")) - COMPLETE_WITH_CONST("AS"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches5("REFERENCING", "OLD", "TABLE", "AS", MatchAny) || - TailMatches4("REFERENCING", "OLD", "TABLE", MatchAny))) - COMPLETE_WITH_LIST4("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches5("REFERENCING", "NEW", "TABLE", "AS", MatchAny) || - TailMatches4("REFERENCING", "NEW", "TABLE", MatchAny))) - COMPLETE_WITH_LIST4("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches9("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || - TailMatches8("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || - TailMatches8("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) || - TailMatches7("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny))) - COMPLETE_WITH_LIST3("FOR", "WHEN (", "EXECUTE PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("FOR")) - COMPLETE_WITH_LIST3("EACH", "ROW", "STATEMENT"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("FOR", "EACH")) - COMPLETE_WITH_LIST2("ROW", "STATEMENT"); - else if (HeadMatches2("CREATE", "TRIGGER") && - (TailMatches3("FOR", "EACH", "ROW|STATEMENT") || - TailMatches2("FOR", "ROW|STATEMENT"))) - COMPLETE_WITH_LIST2("WHEN (", "EXECUTE PROCEDURE"); - /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE */ - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches1("EXECUTE")) - COMPLETE_WITH_CONST("PROCEDURE"); - else if (HeadMatches2("CREATE", "TRIGGER") && TailMatches2("EXECUTE", "PROCEDURE")) + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("ON", MatchAny)) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", + "REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("NOT DEFERRABLE", "DEFERRABLE", "INITIALLY", + "REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("DEFERRABLE") || TailMatches("INITIALLY", "IMMEDIATE|DEFERRED"))) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("REFERENCING", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("REFERENCING")) + COMPLETE_WITH("OLD TABLE", "NEW TABLE"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("OLD|NEW", "TABLE")) + COMPLETE_WITH("AS"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "OLD", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD", "TABLE", MatchAny))) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("NEW TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "NEW", "TABLE", MatchAny))) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("OLD TABLE", "FOR", "WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", "AS", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", "AS", MatchAny, "OLD|NEW", "TABLE", MatchAny) || + TailMatches("REFERENCING", "OLD|NEW", "TABLE", MatchAny, "OLD|NEW", "TABLE", MatchAny))) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("FOR", "WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("FOR", "WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR")) + COMPLETE_WITH("EACH", "ROW", "STATEMENT"); + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("FOR", "EACH")) + COMPLETE_WITH("ROW", "STATEMENT"); + else if (HeadMatches("CREATE", "TRIGGER") && + (TailMatches("FOR", "EACH", "ROW|STATEMENT") || + TailMatches("FOR", "ROW|STATEMENT"))) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("WHEN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("WHEN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("WHEN", "(*)")) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("EXECUTE FUNCTION"); + else + COMPLETE_WITH("EXECUTE PROCEDURE"); + } + /* complete CREATE TRIGGER ... EXECUTE with PROCEDURE|FUNCTION */ + else if (HeadMatches("CREATE", "TRIGGER") && TailMatches("EXECUTE")) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("FUNCTION"); + else + COMPLETE_WITH("PROCEDURE"); + } + else if (HeadMatches("CREATE", "TRIGGER") && + TailMatches("EXECUTE", "FUNCTION|PROCEDURE")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); /* CREATE ROLE,USER,GROUP */ - else if (Matches3("CREATE", "ROLE|GROUP|USER", MatchAny) && - !TailMatches2("USER", "MAPPING")) - { - static const char *const list_CREATEROLE[] = - {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", - "REPLICATION", "ROLE", "SUPERUSER", "SYSID", - "VALID UNTIL", "WITH", NULL}; - - COMPLETE_WITH_LIST(list_CREATEROLE); - } + else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny) && + !TailMatches("USER", "MAPPING")) + COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", + "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT", + "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "REPLICATION", "ROLE", "SUPERUSER", "SYSID", + "VALID UNTIL", "WITH"); /* CREATE ROLE,USER,GROUP WITH */ - else if (Matches4("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH")) - { + else if (Matches("CREATE", "ROLE|GROUP|USER", MatchAny, "WITH")) /* Similar to the above, but don't complete "WITH" again. */ - static const char *const list_CREATEROLE_WITH[] = - {"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", - "ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS", - "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", - "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", - "REPLICATION", "ROLE", "SUPERUSER", "SYSID", - "VALID UNTIL", NULL}; - - COMPLETE_WITH_LIST(list_CREATEROLE_WITH); - } + COMPLETE_WITH("ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", + "CREATEROLE", "ENCRYPTED PASSWORD", "IN", "INHERIT", + "LOGIN", "NOBYPASSRLS", + "NOCREATEDB", "NOCREATEROLE", "NOINHERIT", + "NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", + "REPLICATION", "ROLE", "SUPERUSER", "SYSID", + "VALID UNTIL"); /* complete CREATE ROLE,USER,GROUP IN with ROLE,GROUP */ - else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN")) - COMPLETE_WITH_LIST2("GROUP", "ROLE"); + else if (Matches("CREATE", "ROLE|USER|GROUP", MatchAny, "IN")) + COMPLETE_WITH("GROUP", "ROLE"); + +/* CREATE TYPE */ + else if (Matches("CREATE", "TYPE", MatchAny)) + COMPLETE_WITH("(", "AS"); + else if (Matches("CREATE", "TYPE", MatchAny, "AS")) + COMPLETE_WITH("ENUM", "RANGE", "("); + else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "(")) + { + if (TailMatches("(|*,", MatchAny)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (TailMatches("(|*,", MatchAny, MatchAnyExcept("*)"))) + COMPLETE_WITH("COLLATE", ",", ")"); + } + else if (Matches("CREATE", "TYPE", MatchAny, "AS", "ENUM|RANGE")) + COMPLETE_WITH("("); + else if (HeadMatches("CREATE", "TYPE", MatchAny, "(")) + { + if (TailMatches("(|*,")) + COMPLETE_WITH("INPUT", "OUTPUT", "RECEIVE", "SEND", + "TYPMOD_IN", "TYPMOD_OUT", "ANALYZE", + "INTERNALLENGTH", "PASSEDBYVALUE", "ALIGNMENT", + "STORAGE", "LIKE", "CATEGORY", "PREFERRED", + "DEFAULT", "ELEMENT", "DELIMITER", + "COLLATABLE"); + else if (TailMatches("(*|*,", MatchAnyExcept("*="))) + COMPLETE_WITH("="); + else if (TailMatches("=", MatchAnyExcept("*)"))) + COMPLETE_WITH(",", ")"); + } + else if (HeadMatches("CREATE", "TYPE", MatchAny, "AS", "RANGE", "(")) + { + if (TailMatches("(|*,")) + COMPLETE_WITH("SUBTYPE", "SUBTYPE_OPCLASS", "COLLATION", + "CANONICAL", "SUBTYPE_DIFF"); + else if (TailMatches("(*|*,", MatchAnyExcept("*="))) + COMPLETE_WITH("="); + else if (TailMatches("=", MatchAnyExcept("*)"))) + COMPLETE_WITH(",", ")"); + } /* CREATE VIEW --- is allowed inside CREATE SCHEMA, so use TailMatches */ - /* Complete CREATE VIEW with AS */ - else if (TailMatches3("CREATE", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("AS"); - /* Complete "CREATE VIEW AS with "SELECT" */ - else if (TailMatches4("CREATE", "VIEW", MatchAny, "AS")) - COMPLETE_WITH_CONST("SELECT"); + /* Complete CREATE [ OR REPLACE ] VIEW with AS */ + else if (TailMatches("CREATE", "VIEW", MatchAny) || + TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny)) + COMPLETE_WITH("AS"); + /* Complete "CREATE [ OR REPLACE ] VIEW AS with "SELECT" */ + else if (TailMatches("CREATE", "VIEW", MatchAny, "AS") || + TailMatches("CREATE", "OR", "REPLACE", "VIEW", MatchAny, "AS")) + COMPLETE_WITH("SELECT"); /* CREATE MATERIALIZED VIEW */ - else if (Matches2("CREATE", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); + else if (Matches("CREATE", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); /* Complete CREATE MATERIALIZED VIEW with AS */ - else if (Matches4("CREATE", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("AS"); + else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("AS"); /* Complete "CREATE MATERIALIZED VIEW AS with "SELECT" */ - else if (Matches5("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS")) - COMPLETE_WITH_CONST("SELECT"); + else if (Matches("CREATE", "MATERIALIZED", "VIEW", MatchAny, "AS")) + COMPLETE_WITH("SELECT"); /* CREATE EVENT TRIGGER */ - else if (Matches2("CREATE", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); + else if (Matches("CREATE", "EVENT")) + COMPLETE_WITH("TRIGGER"); /* Complete CREATE EVENT TRIGGER with ON */ - else if (Matches4("CREATE", "EVENT", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); /* Complete CREATE EVENT TRIGGER ON with event_type */ - else if (Matches5("CREATE", "EVENT", "TRIGGER", MatchAny, "ON")) - COMPLETE_WITH_LIST3("ddl_command_start", "ddl_command_end", "sql_drop"); + else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON")) + COMPLETE_WITH("ddl_command_start", "ddl_command_end", "sql_drop"); + + /* + * Complete CREATE EVENT TRIGGER ON . EXECUTE FUNCTION + * is the recommended grammar instead of EXECUTE PROCEDURE in version 11 + * and upwards. + */ + else if (Matches("CREATE", "EVENT", "TRIGGER", MatchAny, "ON", MatchAny)) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("WHEN TAG IN (", "EXECUTE FUNCTION"); + else + COMPLETE_WITH("WHEN TAG IN (", "EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "EVENT", "TRIGGER") && + TailMatches("WHEN|AND", MatchAny, "IN", "(*)")) + { + if (pset.sversion >= 110000) + COMPLETE_WITH("EXECUTE FUNCTION"); + else + COMPLETE_WITH("EXECUTE PROCEDURE"); + } + else if (HeadMatches("CREATE", "EVENT", "TRIGGER") && + TailMatches("EXECUTE", "FUNCTION|PROCEDURE")) + COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); /* DEALLOCATE */ - else if (Matches1("DEALLOCATE")) + else if (Matches("DEALLOCATE")) COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements); /* DECLARE */ - else if (Matches2("DECLARE", MatchAny)) - COMPLETE_WITH_LIST5("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", - "CURSOR"); - else if (HeadMatches1("DECLARE") && TailMatches1("CURSOR")) - COMPLETE_WITH_LIST3("WITH HOLD", "WITHOUT HOLD", "FOR"); + else if (Matches("DECLARE", MatchAny)) + COMPLETE_WITH("BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", + "CURSOR"); + else if (HeadMatches("DECLARE") && TailMatches("CURSOR")) + COMPLETE_WITH("WITH HOLD", "WITHOUT HOLD", "FOR"); /* DELETE --- can be inside EXPLAIN, RULE, etc */ /* ... despite which, only complete DELETE with FROM at start of line */ - else if (Matches1("DELETE")) - COMPLETE_WITH_CONST("FROM"); + else if (Matches("DELETE")) + COMPLETE_WITH("FROM"); /* Complete DELETE FROM with a list of tables */ - else if (TailMatches2("DELETE", "FROM")) + else if (TailMatches("DELETE", "FROM")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete DELETE FROM
*/ - else if (TailMatches3("DELETE", "FROM", MatchAny)) - COMPLETE_WITH_LIST2("USING", "WHERE"); + else if (TailMatches("DELETE", "FROM", MatchAny)) + COMPLETE_WITH("USING", "WHERE"); /* XXX: implement tab completion for DELETE ... USING */ /* DISCARD */ - else if (Matches1("DISCARD")) - COMPLETE_WITH_LIST4("ALL", "PLANS", "SEQUENCES", "TEMP"); + else if (Matches("DISCARD")) + COMPLETE_WITH("ALL", "PLANS", "SEQUENCES", "TEMP"); /* DO */ - else if (Matches1("DO")) - COMPLETE_WITH_CONST("LANGUAGE"); + else if (Matches("DO")) + COMPLETE_WITH("LANGUAGE"); /* DROP */ /* Complete DROP object with CASCADE / RESTRICT */ - else if (Matches3("DROP", - "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW", - MatchAny) || - Matches4("DROP", "ACCESS", "METHOD", MatchAny) || - (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) && + else if (Matches("DROP", + "COLLATION|CONVERSION|DOMAIN|EXTENSION|LANGUAGE|PUBLICATION|SCHEMA|SEQUENCE|SERVER|SUBSCRIPTION|STATISTICS|TABLE|TYPE|VIEW", + MatchAny) || + Matches("DROP", "ACCESS", "METHOD", MatchAny) || + (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, MatchAny) && ends_with(prev_wd, ')')) || - Matches4("DROP", "EVENT", "TRIGGER", MatchAny) || - Matches5("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) || - Matches4("DROP", "FOREIGN", "TABLE", MatchAny) || - Matches5("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + Matches("DROP", "EVENT", "TRIGGER", MatchAny) || + Matches("DROP", "FOREIGN", "DATA", "WRAPPER", MatchAny) || + Matches("DROP", "FOREIGN", "TABLE", MatchAny) || + Matches("DROP", "TEXT", "SEARCH", "CONFIGURATION|DICTIONARY|PARSER|TEMPLATE", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* help completing some of the variants */ - else if (Matches3("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) - COMPLETE_WITH_CONST("("); - else if (Matches4("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "(")) + else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny)) + COMPLETE_WITH("("); + else if (Matches("DROP", "AGGREGATE|FUNCTION|PROCEDURE|ROUTINE", MatchAny, "(")) COMPLETE_WITH_FUNCTION_ARG(prev2_wd); - else if (Matches2("DROP", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); + else if (Matches("DROP", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); /* DROP INDEX */ - else if (Matches2("DROP", "INDEX")) + else if (Matches("DROP", "INDEX")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, " UNION SELECT 'CONCURRENTLY'"); - else if (Matches3("DROP", "INDEX", "CONCURRENTLY")) + else if (Matches("DROP", "INDEX", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (Matches3("DROP", "INDEX", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); - else if (Matches4("DROP", "INDEX", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "INDEX", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); + else if (Matches("DROP", "INDEX", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* DROP MATERIALIZED VIEW */ - else if (Matches2("DROP", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (Matches3("DROP", "MATERIALIZED", "VIEW")) + else if (Matches("DROP", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (Matches("DROP", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); /* DROP OWNED BY */ - else if (Matches2("DROP", "OWNED")) - COMPLETE_WITH_CONST("BY"); - else if (Matches3("DROP", "OWNED", "BY")) + else if (Matches("DROP", "OWNED")) + COMPLETE_WITH("BY"); + else if (Matches("DROP", "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* DROP TEXT SEARCH */ - else if (Matches3("DROP", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (Matches("DROP", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); /* DROP TRIGGER */ - else if (Matches3("DROP", "TRIGGER", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches4("DROP", "TRIGGER", MatchAny, "ON")) + else if (Matches("DROP", "TRIGGER", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("DROP", "TRIGGER", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); } - else if (Matches5("DROP", "TRIGGER", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "TRIGGER", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* DROP ACCESS METHOD */ - else if (Matches2("DROP", "ACCESS")) - COMPLETE_WITH_CONST("METHOD"); - else if (Matches3("DROP", "ACCESS", "METHOD")) + else if (Matches("DROP", "ACCESS")) + COMPLETE_WITH("METHOD"); + else if (Matches("DROP", "ACCESS", "METHOD")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); /* DROP EVENT TRIGGER */ - else if (Matches2("DROP", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); - else if (Matches3("DROP", "EVENT", "TRIGGER")) + else if (Matches("DROP", "EVENT")) + COMPLETE_WITH("TRIGGER"); + else if (Matches("DROP", "EVENT", "TRIGGER")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* DROP POLICY */ - else if (Matches2("DROP", "POLICY")) + else if (Matches("DROP", "POLICY")) COMPLETE_WITH_QUERY(Query_for_list_of_policies); /* DROP POLICY ON */ - else if (Matches3("DROP", "POLICY", MatchAny)) - COMPLETE_WITH_CONST("ON"); + else if (Matches("DROP", "POLICY", MatchAny)) + COMPLETE_WITH("ON"); /* DROP POLICY ON
*/ - else if (Matches4("DROP", "POLICY", MatchAny, "ON")) + else if (Matches("DROP", "POLICY", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_policy); } /* DROP RULE */ - else if (Matches3("DROP", "RULE", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches4("DROP", "RULE", MatchAny, "ON")) + else if (Matches("DROP", "RULE", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("DROP", "RULE", MatchAny, "ON")) { completion_info_charp = prev2_wd; COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule); } - else if (Matches5("DROP", "RULE", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("CASCADE", "RESTRICT"); + else if (Matches("DROP", "RULE", MatchAny, "ON", MatchAny)) + COMPLETE_WITH("CASCADE", "RESTRICT"); /* EXECUTE */ - else if (Matches1("EXECUTE")) + else if (Matches("EXECUTE")) COMPLETE_WITH_QUERY(Query_for_list_of_prepared_statements); -/* EXPLAIN */ - - /* - * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands - */ - else if (Matches1("EXPLAIN")) - COMPLETE_WITH_LIST8("SELECT", "INSERT", "DELETE", "UPDATE", "MERGE", - "DECLARE", "ANALYZE", "VERBOSE"); - else if (Matches2("EXPLAIN", "ANALYZE")) - COMPLETE_WITH_LIST7("SELECT", "INSERT", "DELETE", "UPDATE", "MERGE", - "DECLARE", "VERBOSE"); - else if (Matches2("EXPLAIN", "VERBOSE") || - Matches3("EXPLAIN", "ANALYZE", "VERBOSE")) - COMPLETE_WITH_LIST6("SELECT", "INSERT", "DELETE", "UPDATE", "MERGE", - "DECLARE"); +/* + * EXPLAIN [ ( option [, ...] ) ] statement + * EXPLAIN [ ANALYZE ] [ VERBOSE ] statement + */ + else if (Matches("EXPLAIN")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", + "ANALYZE", "VERBOSE"); + else if (HeadMatches("EXPLAIN", "(*") && + !HeadMatches("EXPLAIN", "(*)")) + { + /* + * This fires if we're in an unfinished parenthesized option list. + * get_previous_words treats a completed parenthesized option list as + * one word, so the above test is correct. + */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + COMPLETE_WITH("ANALYZE", "VERBOSE", "COSTS", "SETTINGS", + "BUFFERS", "TIMING", "SUMMARY", "FORMAT"); + else if (TailMatches("ANALYZE|VERBOSE|COSTS|SETTINGS|BUFFERS|TIMING|SUMMARY")) + COMPLETE_WITH("ON", "OFF"); + else if (TailMatches("FORMAT")) + COMPLETE_WITH("TEXT", "XML", "JSON", "YAML"); + } + else if (Matches("EXPLAIN", "ANALYZE")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", + "VERBOSE"); + else if (Matches("EXPLAIN", "(*)") || + Matches("EXPLAIN", "VERBOSE") || + Matches("EXPLAIN", "ANALYZE", "VERBOSE")) + COMPLETE_WITH("SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE"); /* FETCH && MOVE */ /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ - else if (Matches1("FETCH|MOVE")) - COMPLETE_WITH_LIST4("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE"); + else if (Matches("FETCH|MOVE")) + COMPLETE_WITH("ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE"); /* Complete FETCH with one of ALL, NEXT, PRIOR */ - else if (Matches2("FETCH|MOVE", MatchAny)) - COMPLETE_WITH_LIST3("ALL", "NEXT", "PRIOR"); + else if (Matches("FETCH|MOVE", MatchAny)) + COMPLETE_WITH("ALL", "NEXT", "PRIOR"); /* * Complete FETCH with "FROM" or "IN". These are equivalent, * but we may as well tab-complete both: perhaps some users prefer one * variant or the other. */ - else if (Matches3("FETCH|MOVE", MatchAny, MatchAny)) - COMPLETE_WITH_LIST2("FROM", "IN"); + else if (Matches("FETCH|MOVE", MatchAny, MatchAny)) + COMPLETE_WITH("FROM", "IN"); /* FOREIGN DATA WRAPPER */ /* applies in ALTER/DROP FDW and in CREATE SERVER */ - else if (TailMatches3("FOREIGN", "DATA", "WRAPPER") && - !TailMatches4("CREATE", MatchAny, MatchAny, MatchAny)) + else if (TailMatches("FOREIGN", "DATA", "WRAPPER") && + !TailMatches("CREATE", MatchAny, MatchAny, MatchAny)) COMPLETE_WITH_QUERY(Query_for_list_of_fdws); /* applies in CREATE SERVER */ - else if (TailMatches4("FOREIGN", "DATA", "WRAPPER", MatchAny) && - HeadMatches2("CREATE", "SERVER")) - COMPLETE_WITH_CONST("OPTIONS"); + else if (TailMatches("FOREIGN", "DATA", "WRAPPER", MatchAny) && + HeadMatches("CREATE", "SERVER")) + COMPLETE_WITH("OPTIONS"); /* FOREIGN TABLE */ - else if (TailMatches2("FOREIGN", "TABLE") && - !TailMatches3("CREATE", MatchAny, MatchAny)) + else if (TailMatches("FOREIGN", "TABLE") && + !TailMatches("CREATE", MatchAny, MatchAny)) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); /* FOREIGN SERVER */ - else if (TailMatches2("FOREIGN", "SERVER")) + else if (TailMatches("FOREIGN", "SERVER")) COMPLETE_WITH_QUERY(Query_for_list_of_servers); /* @@ -3071,16 +2994,16 @@ psql_completion(const char *text, int start, int end) * ALTER DEFAULT PRIVILEGES, so use TailMatches */ /* Complete GRANT/REVOKE with a list of roles and privileges */ - else if (TailMatches1("GRANT|REVOKE")) + else if (TailMatches("GRANT|REVOKE")) { /* * With ALTER DEFAULT PRIVILEGES, restrict completion to grantable * privileges (can't grant roles) */ - if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST10("SELECT", "INSERT", "UPDATE", - "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", - "EXECUTE", "USAGE", "ALL"); + if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("SELECT", "INSERT", "UPDATE", + "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", + "EXECUTE", "USAGE", "ALL"); else COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'SELECT'" @@ -3102,19 +3025,18 @@ psql_completion(const char *text, int start, int end) * Complete GRANT/REVOKE with "ON", GRANT/REVOKE with * TO/FROM */ - else if (TailMatches2("GRANT|REVOKE", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny)) { - if (TailMatches1("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL")) - COMPLETE_WITH_CONST("ON"); - else if (TailMatches2("GRANT", MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("SELECT|INSERT|UPDATE|DELETE|TRUNCATE|REFERENCES|TRIGGER|CREATE|CONNECT|TEMPORARY|TEMP|EXECUTE|USAGE|ALL")) + COMPLETE_WITH("ON"); + else if (TailMatches("GRANT", MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* - * Complete GRANT/REVOKE ON with a list of tables, views, and - * sequences. + * Complete GRANT/REVOKE ON with a list of appropriate relations. * * Keywords like DATABASE, FUNCTION, LANGUAGE and SCHEMA added to query * result via UNION; seems to work intuitively. @@ -3123,16 +3045,16 @@ psql_completion(const char *text, int start, int end) * here will only work if the privilege list contains exactly one * privilege. */ - else if (TailMatches3("GRANT|REVOKE", MatchAny, "ON")) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON")) { /* * With ALTER DEFAULT PRIVILEGES, restrict completion to the kinds of * objects supported. */ - if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES")) - COMPLETE_WITH_LIST7("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS"); + if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES")) + COMPLETE_WITH("TABLES", "SEQUENCES", "FUNCTIONS", "PROCEDURES", "ROUTINES", "TYPES", "SCHEMAS"); else - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, " UNION SELECT 'ALL FUNCTIONS IN SCHEMA'" " UNION SELECT 'ALL PROCEDURES IN SCHEMA'" " UNION SELECT 'ALL ROUTINES IN SCHEMA'" @@ -3153,14 +3075,14 @@ psql_completion(const char *text, int start, int end) " UNION SELECT 'TABLESPACE'" " UNION SELECT 'TYPE'"); } - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "ALL")) - COMPLETE_WITH_LIST5("FUNCTIONS IN SCHEMA", - "PROCEDURES IN SCHEMA", - "ROUTINES IN SCHEMA", - "SEQUENCES IN SCHEMA", - "TABLES IN SCHEMA"); - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "SERVER"); + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL")) + COMPLETE_WITH("FUNCTIONS IN SCHEMA", + "PROCEDURES IN SCHEMA", + "ROUTINES IN SCHEMA", + "SEQUENCES IN SCHEMA", + "TABLES IN SCHEMA"); + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "SERVER"); /* * Complete "GRANT/REVOKE * ON DATABASE/DOMAIN/..." with a list of @@ -3168,235 +3090,183 @@ psql_completion(const char *text, int start, int end) * * Complete "GRANT/REVOKE * ON *" with "TO/FROM". */ - else if (TailMatches4("GRANT|REVOKE", MatchAny, "ON", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", MatchAny)) { - if (TailMatches1("DATABASE")) + if (TailMatches("DATABASE")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); - else if (TailMatches1("DOMAIN")) + else if (TailMatches("DOMAIN")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); - else if (TailMatches1("FUNCTION")) + else if (TailMatches("FUNCTION")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); - else if (TailMatches1("LANGUAGE")) + else if (TailMatches("LANGUAGE")) COMPLETE_WITH_QUERY(Query_for_list_of_languages); - else if (TailMatches1("PROCEDURE")) + else if (TailMatches("PROCEDURE")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_procedures, NULL); - else if (TailMatches1("ROUTINE")) + else if (TailMatches("ROUTINE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatches1("SCHEMA")) + else if (TailMatches("SCHEMA")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (TailMatches1("SEQUENCE")) + else if (TailMatches("SEQUENCE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); - else if (TailMatches1("TABLE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL); - else if (TailMatches1("TABLESPACE")) + else if (TailMatches("TABLE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); + else if (TailMatches("TABLESPACE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - else if (TailMatches1("TYPE")) + else if (TailMatches("TYPE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); - else if (TailMatches4("GRANT", MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + else if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* * Complete "GRANT/REVOKE ... TO/FROM" with username, PUBLIC, * CURRENT_USER, or SESSION_USER. */ - else if ((HeadMatches1("GRANT") && TailMatches1("TO")) || - (HeadMatches1("REVOKE") && TailMatches1("FROM"))) + else if ((HeadMatches("GRANT") && TailMatches("TO")) || + (HeadMatches("REVOKE") && TailMatches("FROM"))) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "ALTER DEFAULT PRIVILEGES ... GRANT/REVOKE ... TO/FROM */ - else if (HeadMatches3("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches1("TO|FROM")) + else if (HeadMatches("ALTER", "DEFAULT", "PRIVILEGES") && TailMatches("TO|FROM")) COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); /* Complete "GRANT/REVOKE ... ON * *" with TO/FROM */ - else if (HeadMatches1("GRANT") && TailMatches3("ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); - else if (HeadMatches1("REVOKE") && TailMatches3("ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("FROM"); + else if (HeadMatches("GRANT") && TailMatches("ON", MatchAny, MatchAny)) + COMPLETE_WITH("TO"); + else if (HeadMatches("REVOKE") && TailMatches("ON", MatchAny, MatchAny)) + COMPLETE_WITH("FROM"); /* Complete "GRANT/REVOKE * ON ALL * IN SCHEMA *" with TO/FROM */ - else if (TailMatches8("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "ALL", MatchAny, "IN", "SCHEMA", MatchAny)) { - if (TailMatches8("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* Complete "GRANT/REVOKE * ON FOREIGN DATA WRAPPER *" with TO/FROM */ - else if (TailMatches7("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "DATA", "WRAPPER", MatchAny)) { - if (TailMatches7("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* Complete "GRANT/REVOKE * ON FOREIGN SERVER *" with TO/FROM */ - else if (TailMatches6("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny)) + else if (TailMatches("GRANT|REVOKE", MatchAny, "ON", "FOREIGN", "SERVER", MatchAny)) { - if (TailMatches6("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) - COMPLETE_WITH_CONST("TO"); + if (TailMatches("GRANT", MatchAny, MatchAny, MatchAny, MatchAny, MatchAny)) + COMPLETE_WITH("TO"); else - COMPLETE_WITH_CONST("FROM"); + COMPLETE_WITH("FROM"); } /* GROUP BY */ - else if (TailMatches3("FROM", MatchAny, "GROUP")) - COMPLETE_WITH_CONST("BY"); + else if (TailMatches("FROM", MatchAny, "GROUP")) + COMPLETE_WITH("BY"); /* IMPORT FOREIGN SCHEMA */ - else if (Matches1("IMPORT")) - COMPLETE_WITH_CONST("FOREIGN SCHEMA"); - else if (Matches2("IMPORT", "FOREIGN")) - COMPLETE_WITH_CONST("SCHEMA"); + else if (Matches("IMPORT")) + COMPLETE_WITH("FOREIGN SCHEMA"); + else if (Matches("IMPORT", "FOREIGN")) + COMPLETE_WITH("SCHEMA"); /* INSERT --- can be inside EXPLAIN, RULE, etc */ - /* Complete NOT MATCHED THEN INSERT */ - else if (TailMatches4("NOT", "MATCHED", "THEN", "INSERT")) - COMPLETE_WITH_LIST2("VALUES", "("); /* Complete INSERT with "INTO" */ - else if (TailMatches1("INSERT")) - COMPLETE_WITH_CONST("INTO"); + else if (TailMatches("INSERT")) + COMPLETE_WITH("INTO"); /* Complete INSERT INTO with table names */ - else if (TailMatches2("INSERT", "INTO")) + else if (TailMatches("INSERT", "INTO")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete "INSERT INTO
(" with attribute names */ - else if (TailMatches4("INSERT", "INTO", MatchAny, "(")) + else if (TailMatches("INSERT", "INTO", MatchAny, "(")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* * Complete INSERT INTO
with "(" or "VALUES" or "SELECT" or * "TABLE" or "DEFAULT VALUES" or "OVERRIDING" */ - else if (TailMatches3("INSERT", "INTO", MatchAny)) - COMPLETE_WITH_LIST6("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING"); + else if (TailMatches("INSERT", "INTO", MatchAny)) + COMPLETE_WITH("(", "DEFAULT VALUES", "SELECT", "TABLE", "VALUES", "OVERRIDING"); /* * Complete INSERT INTO
(attribs) with "VALUES" or "SELECT" or * "TABLE" or "OVERRIDING" */ - else if (TailMatches4("INSERT", "INTO", MatchAny, MatchAny) && + else if (TailMatches("INSERT", "INTO", MatchAny, MatchAny) && ends_with(prev_wd, ')')) - COMPLETE_WITH_LIST4("SELECT", "TABLE", "VALUES", "OVERRIDING"); + COMPLETE_WITH("SELECT", "TABLE", "VALUES", "OVERRIDING"); /* Complete OVERRIDING */ - else if (TailMatches1("OVERRIDING")) - COMPLETE_WITH_LIST2("SYSTEM VALUE", "USER VALUE"); + else if (TailMatches("OVERRIDING")) + COMPLETE_WITH("SYSTEM VALUE", "USER VALUE"); /* Complete after OVERRIDING clause */ - else if (TailMatches3("OVERRIDING", MatchAny, "VALUE")) - COMPLETE_WITH_LIST3("SELECT", "TABLE", "VALUES"); + else if (TailMatches("OVERRIDING", MatchAny, "VALUE")) + COMPLETE_WITH("SELECT", "TABLE", "VALUES"); /* Insert an open parenthesis after "VALUES" */ - else if (TailMatches1("VALUES") && !TailMatches2("DEFAULT", "VALUES")) - COMPLETE_WITH_CONST("("); + else if (TailMatches("VALUES") && !TailMatches("DEFAULT", "VALUES")) + COMPLETE_WITH("("); /* LOCK */ /* Complete LOCK [TABLE] with a list of tables */ - else if (Matches1("LOCK")) + else if (Matches("LOCK")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, " UNION SELECT 'TABLE'"); - else if (Matches2("LOCK", "TABLE")) + else if (Matches("LOCK", "TABLE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, ""); /* For the following, handle the case of a single table only for now */ /* Complete LOCK [TABLE]
with "IN" */ - else if (Matches2("LOCK", MatchAnyExcept("TABLE")) || - Matches3("LOCK", "TABLE", MatchAny)) - COMPLETE_WITH_CONST("IN"); + else if (Matches("LOCK", MatchAnyExcept("TABLE")) || + Matches("LOCK", "TABLE", MatchAny)) + COMPLETE_WITH("IN"); /* Complete LOCK [TABLE]
IN with a lock mode */ - else if (Matches3("LOCK", MatchAny, "IN") || - Matches4("LOCK", "TABLE", MatchAny, "IN")) - COMPLETE_WITH_LIST8("ACCESS SHARE MODE", - "ROW SHARE MODE", "ROW EXCLUSIVE MODE", - "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", - "SHARE ROW EXCLUSIVE MODE", - "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE"); + else if (Matches("LOCK", MatchAny, "IN") || + Matches("LOCK", "TABLE", MatchAny, "IN")) + COMPLETE_WITH("ACCESS SHARE MODE", + "ROW SHARE MODE", "ROW EXCLUSIVE MODE", + "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", + "SHARE ROW EXCLUSIVE MODE", + "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE"); /* Complete LOCK [TABLE]
IN ACCESS|ROW with rest of lock mode */ - else if (Matches4("LOCK", MatchAny, "IN", "ACCESS|ROW") || - Matches5("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW")) - COMPLETE_WITH_LIST2("EXCLUSIVE MODE", "SHARE MODE"); + else if (Matches("LOCK", MatchAny, "IN", "ACCESS|ROW") || + Matches("LOCK", "TABLE", MatchAny, "IN", "ACCESS|ROW")) + COMPLETE_WITH("EXCLUSIVE MODE", "SHARE MODE"); /* Complete LOCK [TABLE]
IN SHARE with rest of lock mode */ - else if (Matches4("LOCK", MatchAny, "IN", "SHARE") || - Matches5("LOCK", "TABLE", MatchAny, "IN", "SHARE")) - COMPLETE_WITH_LIST3("MODE", "ROW EXCLUSIVE MODE", - "UPDATE EXCLUSIVE MODE"); -/* MERGE --- can be inside EXPLAIN */ - else if (TailMatches1("MERGE")) - COMPLETE_WITH_CONST("INTO"); - else if (TailMatches2("MERGE", "INTO")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_mergetargets, NULL); - else if (TailMatches3("MERGE", "INTO", MatchAny)) - COMPLETE_WITH_LIST2("USING", "AS"); - else if (TailMatches4("MERGE", "INTO", MatchAny, "USING")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - /* with [AS] alias */ - else if (TailMatches5("MERGE", "INTO", MatchAny, "AS", MatchAny)) - COMPLETE_WITH_CONST("USING"); - else if (TailMatches4("MERGE", "INTO", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("USING"); - else if (TailMatches6("MERGE", "INTO", MatchAny, "AS", MatchAny, "USING")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - else if (TailMatches5("MERGE", "INTO", MatchAny, MatchAny, "USING")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - /* ON */ - else if (TailMatches5("MERGE", "INTO", MatchAny, "USING", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (TailMatches8("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (TailMatches6("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("ON"); - /* ON condition */ - else if (TailMatches5("INTO", MatchAny, "USING", MatchAny, "ON")) - COMPLETE_WITH_ATTR(prev4_wd, ""); - else if (TailMatches9("INTO", MatchAny, "AS", MatchAny, "USING", MatchAny, "AS", MatchAny, "ON")) - COMPLETE_WITH_ATTR(prev8_wd, ""); - else if (TailMatches7("INTO", MatchAny, MatchAny, "USING", MatchAny, MatchAny, "ON")) - COMPLETE_WITH_ATTR(prev6_wd, ""); - /* WHEN [NOT] MATCHED */ - else if (TailMatches4("USING", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("WHEN MATCHED", "WHEN NOT MATCHED"); - else if (TailMatches6("USING", MatchAny, "AS", MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("WHEN MATCHED", "WHEN NOT MATCHED"); - else if (TailMatches5("USING", MatchAny, MatchAny, "ON", MatchAny)) - COMPLETE_WITH_LIST2("WHEN MATCHED", "WHEN NOT MATCHED"); - else if (TailMatches2("WHEN", "MATCHED")) - COMPLETE_WITH_LIST2("THEN", "AND"); - else if (TailMatches3("WHEN", "NOT", "MATCHED")) - COMPLETE_WITH_LIST2("THEN", "AND"); - else if (TailMatches3("WHEN", "MATCHED", "THEN")) - COMPLETE_WITH_LIST2("UPDATE", "DELETE"); - else if (TailMatches4("WHEN", "NOT", "MATCHED", "THEN")) - COMPLETE_WITH_LIST2("INSERT", "DO"); - else if (TailMatches5("WHEN", "NOT", "MATCHED", "THEN", "DO")) - COMPLETE_WITH_CONST("NOTHING"); + else if (Matches("LOCK", MatchAny, "IN", "SHARE") || + Matches("LOCK", "TABLE", MatchAny, "IN", "SHARE")) + COMPLETE_WITH("MODE", "ROW EXCLUSIVE MODE", + "UPDATE EXCLUSIVE MODE"); /* NOTIFY --- can be inside EXPLAIN, RULE, etc */ - else if (TailMatches1("NOTIFY")) + else if (TailMatches("NOTIFY")) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s'"); /* OPTIONS */ - else if (TailMatches1("OPTIONS")) - COMPLETE_WITH_CONST("("); + else if (TailMatches("OPTIONS")) + COMPLETE_WITH("("); /* OWNER TO - complete with available roles */ - else if (TailMatches2("OWNER", "TO")) + else if (TailMatches("OWNER", "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* ORDER BY */ - else if (TailMatches3("FROM", MatchAny, "ORDER")) - COMPLETE_WITH_CONST("BY"); - else if (TailMatches4("FROM", MatchAny, "ORDER", "BY")) + else if (TailMatches("FROM", MatchAny, "ORDER")) + COMPLETE_WITH("BY"); + else if (TailMatches("FROM", MatchAny, "ORDER", "BY")) COMPLETE_WITH_ATTR(prev3_wd, ""); /* PREPARE xx AS */ - else if (Matches3("PREPARE", MatchAny, "AS")) - COMPLETE_WITH_LIST4("SELECT", "UPDATE", "INSERT", "DELETE FROM"); + else if (Matches("PREPARE", MatchAny, "AS")) + COMPLETE_WITH("SELECT", "UPDATE", "INSERT", "DELETE FROM"); /* * PREPARE TRANSACTION is missing on purpose. It's intended for transaction @@ -3404,154 +3274,166 @@ psql_completion(const char *text, int start, int end) */ /* REASSIGN OWNED BY xxx TO yyy */ - else if (Matches1("REASSIGN")) - COMPLETE_WITH_CONST("OWNED BY"); - else if (Matches2("REASSIGN", "OWNED")) - COMPLETE_WITH_CONST("BY"); - else if (Matches3("REASSIGN", "OWNED", "BY")) + else if (Matches("REASSIGN")) + COMPLETE_WITH("OWNED BY"); + else if (Matches("REASSIGN", "OWNED")) + COMPLETE_WITH("BY"); + else if (Matches("REASSIGN", "OWNED", "BY")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (Matches4("REASSIGN", "OWNED", "BY", MatchAny)) - COMPLETE_WITH_CONST("TO"); - else if (Matches5("REASSIGN", "OWNED", "BY", MatchAny, "TO")) + else if (Matches("REASSIGN", "OWNED", "BY", MatchAny)) + COMPLETE_WITH("TO"); + else if (Matches("REASSIGN", "OWNED", "BY", MatchAny, "TO")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* REFRESH MATERIALIZED VIEW */ - else if (Matches1("REFRESH")) - COMPLETE_WITH_CONST("MATERIALIZED VIEW"); - else if (Matches2("REFRESH", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (Matches3("REFRESH", "MATERIALIZED", "VIEW")) + else if (Matches("REFRESH")) + COMPLETE_WITH("MATERIALIZED VIEW"); + else if (Matches("REFRESH", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, " UNION SELECT 'CONCURRENTLY'"); - else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY")) + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (Matches4("REFRESH", "MATERIALIZED", "VIEW", MatchAny)) - COMPLETE_WITH_CONST("WITH"); - else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny)) - COMPLETE_WITH_CONST("WITH"); - else if (Matches5("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH")) - COMPLETE_WITH_LIST2("NO DATA", "DATA"); - else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH")) - COMPLETE_WITH_LIST2("NO DATA", "DATA"); - else if (Matches6("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO")) - COMPLETE_WITH_CONST("DATA"); - else if (Matches7("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO")) - COMPLETE_WITH_CONST("DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny)) + COMPLETE_WITH("WITH"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny)) + COMPLETE_WITH("WITH"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH")) + COMPLETE_WITH("NO DATA", "DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH")) + COMPLETE_WITH("NO DATA", "DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", MatchAny, "WITH", "NO")) + COMPLETE_WITH("DATA"); + else if (Matches("REFRESH", "MATERIALIZED", "VIEW", "CONCURRENTLY", MatchAny, "WITH", "NO")) + COMPLETE_WITH("DATA"); /* REINDEX */ - else if (Matches1("REINDEX")) - COMPLETE_WITH_LIST5("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE"); - else if (Matches2("REINDEX", "TABLE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL); - else if (Matches2("REINDEX", "INDEX")) + else if (Matches("REINDEX")) + COMPLETE_WITH("TABLE", "INDEX", "SYSTEM", "SCHEMA", "DATABASE"); + else if (Matches("REINDEX", "TABLE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, + " UNION SELECT 'CONCURRENTLY'"); + else if (Matches("REINDEX", "INDEX")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, + " UNION SELECT 'CONCURRENTLY'"); + else if (Matches("REINDEX", "SCHEMA")) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas + " UNION SELECT 'CONCURRENTLY'"); + else if (Matches("REINDEX", "SYSTEM|DATABASE")) + COMPLETE_WITH_QUERY(Query_for_list_of_databases + " UNION SELECT 'CONCURRENTLY'"); + else if (Matches("REINDEX", "TABLE", "CONCURRENTLY")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexables, NULL); + else if (Matches("REINDEX", "INDEX", "CONCURRENTLY")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (Matches2("REINDEX", "SCHEMA")) + else if (Matches("REINDEX", "SCHEMA", "CONCURRENTLY")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (Matches2("REINDEX", "SYSTEM|DATABASE")) + else if (Matches("REINDEX", "SYSTEM|DATABASE", "CONCURRENTLY")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); /* SECURITY LABEL */ - else if (Matches1("SECURITY")) - COMPLETE_WITH_CONST("LABEL"); - else if (Matches2("SECURITY", "LABEL")) - COMPLETE_WITH_LIST2("ON", "FOR"); - else if (Matches4("SECURITY", "LABEL", "FOR", MatchAny)) - COMPLETE_WITH_CONST("ON"); - else if (Matches3("SECURITY", "LABEL", "ON") || - Matches5("SECURITY", "LABEL", "FOR", MatchAny, "ON")) - { - static const char *const list_SECURITY_LABEL[] = - {"TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN", - "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", "LARGE OBJECT", - "MATERIALIZED VIEW", "LANGUAGE", "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", - "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW", NULL}; - - COMPLETE_WITH_LIST(list_SECURITY_LABEL); - } - else if (Matches5("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) - COMPLETE_WITH_CONST("IS"); + else if (Matches("SECURITY")) + COMPLETE_WITH("LABEL"); + else if (Matches("SECURITY", "LABEL")) + COMPLETE_WITH("ON", "FOR"); + else if (Matches("SECURITY", "LABEL", "FOR", MatchAny)) + COMPLETE_WITH("ON"); + else if (Matches("SECURITY", "LABEL", "ON") || + Matches("SECURITY", "LABEL", "FOR", MatchAny, "ON")) + COMPLETE_WITH("TABLE", "COLUMN", "AGGREGATE", "DATABASE", "DOMAIN", + "EVENT TRIGGER", "FOREIGN TABLE", "FUNCTION", + "LARGE OBJECT", "MATERIALIZED VIEW", "LANGUAGE", + "PUBLICATION", "PROCEDURE", "ROLE", "ROUTINE", "SCHEMA", + "SEQUENCE", "SUBSCRIPTION", "TABLESPACE", "TYPE", "VIEW"); + else if (Matches("SECURITY", "LABEL", "ON", MatchAny, MatchAny)) + COMPLETE_WITH("IS"); /* SELECT */ /* naah . . . */ /* SET, RESET, SHOW */ /* Complete with a variable name */ - else if (TailMatches1("SET|RESET") && !TailMatches3("UPDATE", MatchAny, "SET")) + else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET")) COMPLETE_WITH_QUERY(Query_for_list_of_set_vars); - else if (Matches1("SHOW")) + else if (Matches("SHOW")) COMPLETE_WITH_QUERY(Query_for_list_of_show_vars); /* Complete "SET TRANSACTION" */ - else if (Matches2("SET", "TRANSACTION")) - COMPLETE_WITH_LIST5("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); - else if (Matches2("BEGIN|START", "TRANSACTION") || - Matches2("BEGIN", "WORK") || - Matches1("BEGIN") || - Matches5("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION")) - COMPLETE_WITH_LIST4("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") || - Matches2("BEGIN", "NOT") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT")) - COMPLETE_WITH_CONST("DEFERRABLE"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") || - Matches2("BEGIN", "ISOLATION") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION")) - COMPLETE_WITH_CONST("LEVEL"); - else if (Matches4("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") || - Matches3("BEGIN", "ISOLATION", "LEVEL") || - Matches7("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL")) - COMPLETE_WITH_LIST3("READ", "REPEATABLE READ", "SERIALIZABLE"); - else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") || - Matches4("BEGIN", "ISOLATION", "LEVEL", "READ") || - Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ")) - COMPLETE_WITH_LIST2("UNCOMMITTED", "COMMITTED"); - else if (Matches5("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") || - Matches4("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") || - Matches8("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE")) - COMPLETE_WITH_CONST("READ"); - else if (Matches3("SET|BEGIN|START", "TRANSACTION|WORK", "READ") || - Matches2("BEGIN", "READ") || - Matches6("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ")) - COMPLETE_WITH_LIST2("ONLY", "WRITE"); + else if (Matches("SET", "TRANSACTION")) + COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("BEGIN|START", "TRANSACTION") || + Matches("BEGIN", "WORK") || + Matches("BEGIN") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION")) + COMPLETE_WITH("ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "NOT") || + Matches("BEGIN", "NOT") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "NOT")) + COMPLETE_WITH("DEFERRABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION") || + Matches("BEGIN", "ISOLATION") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION")) + COMPLETE_WITH("LEVEL"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL") || + Matches("BEGIN", "ISOLATION", "LEVEL") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL")) + COMPLETE_WITH("READ", "REPEATABLE READ", "SERIALIZABLE"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "READ") || + Matches("BEGIN", "ISOLATION", "LEVEL", "READ") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "READ")) + COMPLETE_WITH("UNCOMMITTED", "COMMITTED"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "ISOLATION", "LEVEL", "REPEATABLE") || + Matches("BEGIN", "ISOLATION", "LEVEL", "REPEATABLE") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "ISOLATION", "LEVEL", "REPEATABLE")) + COMPLETE_WITH("READ"); + else if (Matches("SET|BEGIN|START", "TRANSACTION|WORK", "READ") || + Matches("BEGIN", "READ") || + Matches("SET", "SESSION", "CHARACTERISTICS", "AS", "TRANSACTION", "READ")) + COMPLETE_WITH("ONLY", "WRITE"); /* SET CONSTRAINTS */ - else if (Matches2("SET", "CONSTRAINTS")) + else if (Matches("SET", "CONSTRAINTS")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_constraints_with_schema, "UNION SELECT 'ALL'"); /* Complete SET CONSTRAINTS with DEFERRED|IMMEDIATE */ - else if (Matches3("SET", "CONSTRAINTS", MatchAny)) - COMPLETE_WITH_LIST2("DEFERRED", "IMMEDIATE"); + else if (Matches("SET", "CONSTRAINTS", MatchAny)) + COMPLETE_WITH("DEFERRED", "IMMEDIATE"); /* Complete SET ROLE */ - else if (Matches2("SET", "ROLE")) + else if (Matches("SET", "ROLE")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ - else if (Matches2("SET", "SESSION")) - COMPLETE_WITH_LIST2("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION"); + else if (Matches("SET", "SESSION")) + COMPLETE_WITH("AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION"); /* Complete SET SESSION AUTHORIZATION with username */ - else if (Matches3("SET", "SESSION", "AUTHORIZATION")) + else if (Matches("SET", "SESSION", "AUTHORIZATION")) COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'DEFAULT'"); /* Complete RESET SESSION with AUTHORIZATION */ - else if (Matches2("RESET", "SESSION")) - COMPLETE_WITH_CONST("AUTHORIZATION"); + else if (Matches("RESET", "SESSION")) + COMPLETE_WITH("AUTHORIZATION"); /* Complete SET with "TO" */ - else if (Matches2("SET", MatchAny)) - COMPLETE_WITH_CONST("TO"); - /* Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET */ - else if (HeadMatches2("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && - TailMatches2("SET", MatchAny)) - COMPLETE_WITH_LIST2("FROM CURRENT", "TO"); - /* Suggest possible variable values */ - else if (TailMatches3("SET", MatchAny, "TO|=")) + else if (Matches("SET", MatchAny)) + COMPLETE_WITH("TO"); + + /* + * Complete ALTER DATABASE|FUNCTION||PROCEDURE|ROLE|ROUTINE|USER ... SET + * + */ + else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") && + TailMatches("SET", MatchAny)) + COMPLETE_WITH("FROM CURRENT", "TO"); + + /* + * Suggest possible variable values in SET variable TO|=, along with the + * preceding ALTER syntaxes. + */ + else if (TailMatches("SET", MatchAny, "TO|=") && + !TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|=")) { /* special cased code for individual GUCs */ - if (TailMatches2("DateStyle", "TO|=")) - { - static const char *const my_list[] = - {"ISO", "SQL", "Postgres", "German", - "YMD", "DMY", "MDY", - "US", "European", "NonEuropean", - "DEFAULT", NULL}; - - COMPLETE_WITH_LIST(my_list); - } - else if (TailMatches2("search_path", "TO|=")) + if (TailMatches("DateStyle", "TO|=")) + COMPLETE_WITH("ISO", "SQL", "Postgres", "German", + "YMD", "DMY", "MDY", + "US", "European", "NonEuropean", + "DEFAULT"); + else if (TailMatches("search_path", "TO|=")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas " AND nspname not like 'pg\\_toast%%' " " AND nspname not like 'pg\\_temp%%' " @@ -3561,103 +3443,128 @@ psql_completion(const char *text, int start, int end) /* generic, type based, GUC support */ char *guctype = get_guctype(prev2_wd); - if (guctype && strcmp(guctype, "enum") == 0) + /* + * Note: if we don't recognize the GUC name, it's important to not + * offer any completions, as most likely we've misinterpreted the + * context and this isn't a GUC-setting command at all. + */ + if (guctype) { - char querybuf[1024]; + if (strcmp(guctype, "enum") == 0) + { + char querybuf[1024]; - snprintf(querybuf, sizeof(querybuf), Query_for_enum, prev2_wd); - COMPLETE_WITH_QUERY(querybuf); - } - else if (guctype && strcmp(guctype, "bool") == 0) - COMPLETE_WITH_LIST9("on", "off", "true", "false", "yes", "no", - "1", "0", "DEFAULT"); - else - COMPLETE_WITH_CONST("DEFAULT"); + snprintf(querybuf, sizeof(querybuf), + Query_for_enum, prev2_wd); + COMPLETE_WITH_QUERY(querybuf); + } + else if (strcmp(guctype, "bool") == 0) + COMPLETE_WITH("on", "off", "true", "false", "yes", "no", + "1", "0", "DEFAULT"); + else + COMPLETE_WITH("DEFAULT"); - if (guctype) free(guctype); + } } } /* START TRANSACTION */ - else if (Matches1("START")) - COMPLETE_WITH_CONST("TRANSACTION"); + else if (Matches("START")) + COMPLETE_WITH("TRANSACTION"); /* TABLE, but not TABLE embedded in other commands */ - else if (Matches1("TABLE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); + else if (Matches("TABLE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* TABLESAMPLE */ - else if (TailMatches1("TABLESAMPLE")) + else if (TailMatches("TABLESAMPLE")) COMPLETE_WITH_QUERY(Query_for_list_of_tablesample_methods); - else if (TailMatches2("TABLESAMPLE", MatchAny)) - COMPLETE_WITH_CONST("("); + else if (TailMatches("TABLESAMPLE", MatchAny)) + COMPLETE_WITH("("); /* TRUNCATE */ - else if (Matches1("TRUNCATE")) + else if (Matches("TRUNCATE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); /* UNLISTEN */ - else if (Matches1("UNLISTEN")) + else if (Matches("UNLISTEN")) COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(channel) FROM pg_catalog.pg_listening_channels() AS channel WHERE substring(pg_catalog.quote_ident(channel),1,%d)='%s' UNION SELECT '*'"); /* UPDATE --- can be inside EXPLAIN, RULE, etc */ /* If prev. word is UPDATE suggest a list of tables */ - else if (TailMatches1("UPDATE")) + else if (TailMatches("UPDATE")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_updatables, NULL); /* Complete UPDATE
with "SET" */ - else if (TailMatches2("UPDATE", MatchAny)) - COMPLETE_WITH_CONST("SET"); + else if (TailMatches("UPDATE", MatchAny)) + COMPLETE_WITH("SET"); /* Complete UPDATE
SET with list of attributes */ - else if (TailMatches3("UPDATE", MatchAny, "SET")) + else if (TailMatches("UPDATE", MatchAny, "SET")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* UPDATE
SET = */ - else if (TailMatches4("UPDATE", MatchAny, "SET", MatchAny)) - COMPLETE_WITH_CONST("="); + else if (TailMatches("UPDATE", MatchAny, "SET", MatchAnyExcept("*="))) + COMPLETE_WITH("="); /* USER MAPPING */ - else if (Matches3("ALTER|CREATE|DROP", "USER", "MAPPING")) - COMPLETE_WITH_CONST("FOR"); - else if (Matches4("CREATE", "USER", "MAPPING", "FOR")) + else if (Matches("ALTER|CREATE|DROP", "USER", "MAPPING")) + COMPLETE_WITH("FOR"); + else if (Matches("CREATE", "USER", "MAPPING", "FOR")) COMPLETE_WITH_QUERY(Query_for_list_of_roles " UNION SELECT 'CURRENT_USER'" " UNION SELECT 'PUBLIC'" " UNION SELECT 'USER'"); - else if (Matches4("ALTER|DROP", "USER", "MAPPING", "FOR")) + else if (Matches("ALTER|DROP", "USER", "MAPPING", "FOR")) COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); - else if (Matches5("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny)) - COMPLETE_WITH_CONST("SERVER"); - else if (Matches7("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny)) - COMPLETE_WITH_CONST("OPTIONS"); + else if (Matches("CREATE|ALTER|DROP", "USER", "MAPPING", "FOR", MatchAny)) + COMPLETE_WITH("SERVER"); + else if (Matches("CREATE|ALTER", "USER", "MAPPING", "FOR", MatchAny, "SERVER", MatchAny)) + COMPLETE_WITH("OPTIONS"); /* - * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ] - * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ] + * VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ] + * VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ] */ - else if (Matches1("VACUUM")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, + else if (Matches("VACUUM")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'FULL'" " UNION SELECT 'FREEZE'" " UNION SELECT 'ANALYZE'" " UNION SELECT 'VERBOSE'"); - else if (Matches2("VACUUM", "FULL|FREEZE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, + else if (Matches("VACUUM", "FULL")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, + " UNION SELECT 'FREEZE'" " UNION SELECT 'ANALYZE'" " UNION SELECT 'VERBOSE'"); - else if (Matches3("VACUUM", "FULL|FREEZE", "ANALYZE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, - " UNION SELECT 'VERBOSE'"); - else if (Matches3("VACUUM", "FULL|FREEZE", "VERBOSE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, + else if (Matches("VACUUM", "FREEZE") || + Matches("VACUUM", "FULL", "FREEZE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, + " UNION SELECT 'VERBOSE'" " UNION SELECT 'ANALYZE'"); - else if (Matches2("VACUUM", "VERBOSE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, + else if (Matches("VACUUM", "VERBOSE") || + Matches("VACUUM", "FULL|FREEZE", "VERBOSE") || + Matches("VACUUM", "FULL", "FREEZE", "VERBOSE")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, " UNION SELECT 'ANALYZE'"); - else if (Matches2("VACUUM", "ANALYZE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, - " UNION SELECT 'VERBOSE'"); - else if (HeadMatches1("VACUUM")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tm, NULL); + else if (HeadMatches("VACUUM", "(*") && + !HeadMatches("VACUUM", "(*)")) + { + /* + * This fires if we're in an unfinished parenthesized option list. + * get_previous_words treats a completed parenthesized option list as + * one word, so the above test is correct. + */ + if (ends_with(prev_wd, '(') || ends_with(prev_wd, ',')) + COMPLETE_WITH("FULL", "FREEZE", "ANALYZE", "VERBOSE", + "DISABLE_PAGE_SKIPPING", "SKIP_LOCKED", + "INDEX_CLEANUP", "TRUNCATE"); + else if (TailMatches("FULL|FREEZE|ANALYZE|VERBOSE|DISABLE_PAGE_SKIPPING|SKIP_LOCKED|INDEX_CLEANUP|TRUNCATE")) + COMPLETE_WITH("ON", "OFF"); + } + else if (HeadMatches("VACUUM") && TailMatches("(")) + /* "VACUUM (" should be caught above, so assume we want columns */ + COMPLETE_WITH_ATTR(prev2_wd, ""); + else if (HeadMatches("VACUUM")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_vacuumables, NULL); /* WITH [RECURSIVE] */ @@ -3665,114 +3572,115 @@ psql_completion(const char *text, int start, int end) * Only match when WITH is the first word, as WITH may appear in many * other contexts. */ - else if (Matches1("WITH")) - COMPLETE_WITH_CONST("RECURSIVE"); - -/* ANALYZE */ - /* Complete with list of tables */ - else if (Matches1("ANALYZE")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tmf, NULL); + else if (Matches("WITH")) + COMPLETE_WITH("RECURSIVE"); /* WHERE */ /* Simple case of the word before the where being the table name */ - else if (TailMatches2(MatchAny, "WHERE")) + else if (TailMatches(MatchAny, "WHERE")) COMPLETE_WITH_ATTR(prev2_wd, ""); /* ... FROM ... */ /* TODO: also include SRF ? */ - else if (TailMatches1("FROM") && !Matches3("COPY|\\copy", MatchAny, "FROM")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL); + else if (TailMatches("FROM") && !Matches("COPY|\\copy", MatchAny, "FROM")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* ... JOIN ... */ - else if (TailMatches1("JOIN")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL); + else if (TailMatches("JOIN")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_selectables, NULL); /* Backslash commands */ /* TODO: \dc \dd \dl */ - else if (TailMatchesCS1("\\?")) - COMPLETE_WITH_LIST_CS3("commands", "options", "variables"); - else if (TailMatchesCS1("\\connect|\\c")) + else if (TailMatchesCS("\\?")) + COMPLETE_WITH_CS("commands", "options", "variables"); + else if (TailMatchesCS("\\connect|\\c")) { if (!recognized_connection_string(text)) COMPLETE_WITH_QUERY(Query_for_list_of_databases); } - else if (TailMatchesCS2("\\connect|\\c", MatchAny)) + else if (TailMatchesCS("\\connect|\\c", MatchAny)) { if (!recognized_connection_string(prev_wd)) COMPLETE_WITH_QUERY(Query_for_list_of_roles); } - else if (TailMatchesCS1("\\da*")) + else if (TailMatchesCS("\\da*")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); - else if (TailMatchesCS1("\\dA*")) + else if (TailMatchesCS("\\dA*")) COMPLETE_WITH_QUERY(Query_for_list_of_access_methods); - else if (TailMatchesCS1("\\db*")) + else if (TailMatchesCS("\\db*")) COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); - else if (TailMatchesCS1("\\dD*")) + else if (TailMatchesCS("\\dD*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); - else if (TailMatchesCS1("\\des*")) + else if (TailMatchesCS("\\des*")) COMPLETE_WITH_QUERY(Query_for_list_of_servers); - else if (TailMatchesCS1("\\deu*")) + else if (TailMatchesCS("\\deu*")) COMPLETE_WITH_QUERY(Query_for_list_of_user_mappings); - else if (TailMatchesCS1("\\dew*")) + else if (TailMatchesCS("\\dew*")) COMPLETE_WITH_QUERY(Query_for_list_of_fdws); - else if (TailMatchesCS1("\\df*")) + else if (TailMatchesCS("\\df*")) COMPLETE_WITH_VERSIONED_SCHEMA_QUERY(Query_for_list_of_functions, NULL); - else if (TailMatchesCS1("\\dFd*")) + else if (TailMatchesCS("\\dFd*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_dictionaries); - else if (TailMatchesCS1("\\dFp*")) + else if (TailMatchesCS("\\dFp*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_parsers); - else if (TailMatchesCS1("\\dFt*")) + else if (TailMatchesCS("\\dFt*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_templates); /* must be at end of \dF alternatives: */ - else if (TailMatchesCS1("\\dF*")) + else if (TailMatchesCS("\\dF*")) COMPLETE_WITH_QUERY(Query_for_list_of_ts_configurations); - else if (TailMatchesCS1("\\di*")) + else if (TailMatchesCS("\\di*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); - else if (TailMatchesCS1("\\dL*")) + else if (TailMatchesCS("\\dL*")) COMPLETE_WITH_QUERY(Query_for_list_of_languages); - else if (TailMatchesCS1("\\dn*")) + else if (TailMatchesCS("\\dn*")) COMPLETE_WITH_QUERY(Query_for_list_of_schemas); - else if (TailMatchesCS1("\\dp") || TailMatchesCS1("\\z")) - COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsvmf, NULL); - else if (TailMatchesCS1("\\ds*")) + else if (TailMatchesCS("\\dp") || TailMatchesCS("\\z")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_grantables, NULL); + else if (TailMatchesCS("\\dPi*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_indexes, NULL); + else if (TailMatchesCS("\\dPt*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_tables, NULL); + else if (TailMatchesCS("\\dP*")) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_partitioned_relations, NULL); + else if (TailMatchesCS("\\ds*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); - else if (TailMatchesCS1("\\dt*")) + else if (TailMatchesCS("\\dt*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - else if (TailMatchesCS1("\\dT*")) + else if (TailMatchesCS("\\dT*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); - else if (TailMatchesCS1("\\du*") || TailMatchesCS1("\\dg*")) + else if (TailMatchesCS("\\du*") || TailMatchesCS("\\dg*")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (TailMatchesCS1("\\dv*")) + else if (TailMatchesCS("\\dv*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\dx*")) + else if (TailMatchesCS("\\dx*")) COMPLETE_WITH_QUERY(Query_for_list_of_extensions); - else if (TailMatchesCS1("\\dm*")) + else if (TailMatchesCS("\\dm*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_matviews, NULL); - else if (TailMatchesCS1("\\dE*")) + else if (TailMatchesCS("\\dE*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_foreign_tables, NULL); - else if (TailMatchesCS1("\\dy*")) + else if (TailMatchesCS("\\dy*")) COMPLETE_WITH_QUERY(Query_for_list_of_event_triggers); /* must be at end of \d alternatives: */ - else if (TailMatchesCS1("\\d*")) + else if (TailMatchesCS("\\d*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_relations, NULL); - else if (TailMatchesCS1("\\ef")) + else if (TailMatchesCS("\\ef")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatchesCS1("\\ev")) + else if (TailMatchesCS("\\ev")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\encoding")) + else if (TailMatchesCS("\\encoding")) COMPLETE_WITH_QUERY(Query_for_list_of_encodings); - else if (TailMatchesCS1("\\h|\\help")) + else if (TailMatchesCS("\\h|\\help")) COMPLETE_WITH_LIST(sql_commands); - else if (TailMatchesCS2("\\h|\\help", MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny)) { - if (TailMatches1("DROP")) + if (TailMatches("DROP")) matches = completion_matches(text, drop_command_generator); - else if (TailMatches1("ALTER")) + else if (TailMatches("ALTER")) matches = completion_matches(text, alter_command_generator); /* @@ -3780,101 +3688,96 @@ psql_completion(const char *text, int start, int end) * repeated here */ } - else if (TailMatchesCS3("\\h|\\help", MatchAny, MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny)) { - if (TailMatches2("CREATE|DROP", "ACCESS")) - COMPLETE_WITH_CONST("METHOD"); - else if (TailMatches2("ALTER", "DEFAULT")) - COMPLETE_WITH_CONST("PRIVILEGES"); - else if (TailMatches2("CREATE|ALTER|DROP", "EVENT")) - COMPLETE_WITH_CONST("TRIGGER"); - else if (TailMatches2("CREATE|ALTER|DROP", "FOREIGN")) - COMPLETE_WITH_LIST2("DATA WRAPPER", "TABLE"); - else if (TailMatches2("ALTER", "LARGE")) - COMPLETE_WITH_CONST("OBJECT"); - else if (TailMatches2("CREATE|ALTER|DROP", "MATERIALIZED")) - COMPLETE_WITH_CONST("VIEW"); - else if (TailMatches2("CREATE|ALTER|DROP", "TEXT")) - COMPLETE_WITH_CONST("SEARCH"); - else if (TailMatches2("CREATE|ALTER|DROP", "USER")) - COMPLETE_WITH_CONST("MAPPING FOR"); + if (TailMatches("CREATE|DROP", "ACCESS")) + COMPLETE_WITH("METHOD"); + else if (TailMatches("ALTER", "DEFAULT")) + COMPLETE_WITH("PRIVILEGES"); + else if (TailMatches("CREATE|ALTER|DROP", "EVENT")) + COMPLETE_WITH("TRIGGER"); + else if (TailMatches("CREATE|ALTER|DROP", "FOREIGN")) + COMPLETE_WITH("DATA WRAPPER", "TABLE"); + else if (TailMatches("ALTER", "LARGE")) + COMPLETE_WITH("OBJECT"); + else if (TailMatches("CREATE|ALTER|DROP", "MATERIALIZED")) + COMPLETE_WITH("VIEW"); + else if (TailMatches("CREATE|ALTER|DROP", "TEXT")) + COMPLETE_WITH("SEARCH"); + else if (TailMatches("CREATE|ALTER|DROP", "USER")) + COMPLETE_WITH("MAPPING FOR"); } - else if (TailMatchesCS4("\\h|\\help", MatchAny, MatchAny, MatchAny)) + else if (TailMatchesCS("\\h|\\help", MatchAny, MatchAny, MatchAny)) { - if (TailMatches3("CREATE|ALTER|DROP", "FOREIGN", "DATA")) - COMPLETE_WITH_CONST("WRAPPER"); - else if (TailMatches3("CREATE|ALTER|DROP", "TEXT", "SEARCH")) - COMPLETE_WITH_LIST4("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); - else if (TailMatches3("CREATE|ALTER|DROP", "USER", "MAPPING")) - COMPLETE_WITH_CONST("FOR"); + if (TailMatches("CREATE|ALTER|DROP", "FOREIGN", "DATA")) + COMPLETE_WITH("WRAPPER"); + else if (TailMatches("CREATE|ALTER|DROP", "TEXT", "SEARCH")) + COMPLETE_WITH("CONFIGURATION", "DICTIONARY", "PARSER", "TEMPLATE"); + else if (TailMatches("CREATE|ALTER|DROP", "USER", "MAPPING")) + COMPLETE_WITH("FOR"); } - else if (TailMatchesCS1("\\l*") && !TailMatchesCS1("\\lo*")) + else if (TailMatchesCS("\\l*") && !TailMatchesCS("\\lo*")) COMPLETE_WITH_QUERY(Query_for_list_of_databases); - else if (TailMatchesCS1("\\password")) + else if (TailMatchesCS("\\password")) COMPLETE_WITH_QUERY(Query_for_list_of_roles); - else if (TailMatchesCS1("\\pset")) - { - static const char *const my_list[] = - {"border", "columns", "expanded", "fieldsep", "fieldsep_zero", - "footer", "format", "linestyle", "null", "numericlocale", - "pager", "pager_min_lines", "recordsep", "recordsep_zero", - "tableattr", "title", "tuples_only", "unicode_border_linestyle", - "unicode_column_linestyle", "unicode_header_linestyle", NULL}; - - COMPLETE_WITH_LIST_CS(my_list); - } - else if (TailMatchesCS2("\\pset", MatchAny)) + else if (TailMatchesCS("\\pset")) + COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded", + "fieldsep", "fieldsep_zero", "footer", "format", + "linestyle", "null", "numericlocale", + "pager", "pager_min_lines", + "recordsep", "recordsep_zero", + "tableattr", "title", "tuples_only", + "unicode_border_linestyle", + "unicode_column_linestyle", + "unicode_header_linestyle"); + else if (TailMatchesCS("\\pset", MatchAny)) { - if (TailMatchesCS1("format")) - { - static const char *const my_list[] = - {"unaligned", "aligned", "wrapped", "html", "asciidoc", - "latex", "latex-longtable", "troff-ms", NULL}; - - COMPLETE_WITH_LIST_CS(my_list); - } - else if (TailMatchesCS1("linestyle")) - COMPLETE_WITH_LIST_CS3("ascii", "old-ascii", "unicode"); - else if (TailMatchesCS1("pager")) - COMPLETE_WITH_LIST_CS3("on", "off", "always"); - else if (TailMatchesCS1("unicode_border_linestyle|" - "unicode_column_linestyle|" - "unicode_header_linestyle")) - COMPLETE_WITH_LIST_CS2("single", "double"); + if (TailMatchesCS("format")) + COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex", + "latex-longtable", "troff-ms", "unaligned", + "wrapped"); + else if (TailMatchesCS("linestyle")) + COMPLETE_WITH_CS("ascii", "old-ascii", "unicode"); + else if (TailMatchesCS("pager")) + COMPLETE_WITH_CS("on", "off", "always"); + else if (TailMatchesCS("unicode_border_linestyle|" + "unicode_column_linestyle|" + "unicode_header_linestyle")) + COMPLETE_WITH_CS("single", "double"); } - else if (TailMatchesCS1("\\unset")) + else if (TailMatchesCS("\\unset")) matches = complete_from_variables(text, "", "", true); - else if (TailMatchesCS1("\\set")) + else if (TailMatchesCS("\\set")) matches = complete_from_variables(text, "", "", false); - else if (TailMatchesCS2("\\set", MatchAny)) + else if (TailMatchesCS("\\set", MatchAny)) { - if (TailMatchesCS1("AUTOCOMMIT|ON_ERROR_STOP|QUIET|" - "SINGLELINE|SINGLESTEP")) - COMPLETE_WITH_LIST_CS2("on", "off"); - else if (TailMatchesCS1("COMP_KEYWORD_CASE")) - COMPLETE_WITH_LIST_CS4("lower", "upper", - "preserve-lower", "preserve-upper"); - else if (TailMatchesCS1("ECHO")) - COMPLETE_WITH_LIST_CS4("errors", "queries", "all", "none"); - else if (TailMatchesCS1("ECHO_HIDDEN")) - COMPLETE_WITH_LIST_CS3("noexec", "off", "on"); - else if (TailMatchesCS1("HISTCONTROL")) - COMPLETE_WITH_LIST_CS4("ignorespace", "ignoredups", - "ignoreboth", "none"); - else if (TailMatchesCS1("ON_ERROR_ROLLBACK")) - COMPLETE_WITH_LIST_CS3("on", "off", "interactive"); - else if (TailMatchesCS1("SHOW_CONTEXT")) - COMPLETE_WITH_LIST_CS3("never", "errors", "always"); - else if (TailMatchesCS1("VERBOSITY")) - COMPLETE_WITH_LIST_CS3("default", "verbose", "terse"); + if (TailMatchesCS("AUTOCOMMIT|ON_ERROR_STOP|QUIET|" + "SINGLELINE|SINGLESTEP")) + COMPLETE_WITH_CS("on", "off"); + else if (TailMatchesCS("COMP_KEYWORD_CASE")) + COMPLETE_WITH_CS("lower", "upper", + "preserve-lower", "preserve-upper"); + else if (TailMatchesCS("ECHO")) + COMPLETE_WITH_CS("errors", "queries", "all", "none"); + else if (TailMatchesCS("ECHO_HIDDEN")) + COMPLETE_WITH_CS("noexec", "off", "on"); + else if (TailMatchesCS("HISTCONTROL")) + COMPLETE_WITH_CS("ignorespace", "ignoredups", + "ignoreboth", "none"); + else if (TailMatchesCS("ON_ERROR_ROLLBACK")) + COMPLETE_WITH_CS("on", "off", "interactive"); + else if (TailMatchesCS("SHOW_CONTEXT")) + COMPLETE_WITH_CS("never", "errors", "always"); + else if (TailMatchesCS("VERBOSITY")) + COMPLETE_WITH_CS("default", "verbose", "terse", "sqlstate"); } - else if (TailMatchesCS1("\\sf*")) + else if (TailMatchesCS("\\sf*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_routines, NULL); - else if (TailMatchesCS1("\\sv*")) + else if (TailMatchesCS("\\sv*")) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); - else if (TailMatchesCS1("\\cd|\\e|\\edit|\\g|\\i|\\include|" - "\\ir|\\include_relative|\\o|\\out|" - "\\s|\\w|\\write|\\lo_import")) + else if (TailMatchesCS("\\cd|\\e|\\edit|\\g|\\i|\\include|" + "\\ir|\\include_relative|\\o|\\out|" + "\\s|\\w|\\write|\\lo_import")) { completion_charp = "\\"; matches = completion_matches(text, complete_from_files); @@ -3912,7 +3815,7 @@ psql_completion(const char *text, int start, int end) */ if (matches == NULL) { - COMPLETE_WITH_CONST(""); + COMPLETE_WITH_CONST(true, ""); #ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER rl_completion_append_character = '\0'; #endif @@ -4342,10 +4245,21 @@ complete_from_list(const char *text, int state) /* * This function returns one fixed string the first time even if it doesn't - * match what's there, and nothing the second time. This should be used if - * there is only one possibility that can appear at a certain spot, so - * misspellings will be overwritten. The string to be passed must be in - * completion_charp. + * match what's there, and nothing the second time. The string + * to be used must be in completion_charp. + * + * If the given string is "", this has the effect of preventing readline + * from doing any completion. (Without this, readline tries to do filename + * completion which is seldom the right thing.) + * + * If the given string is not empty, readline will replace whatever the + * user typed with that string. This behavior might be useful if it's + * completely certain that we know what must appear at a certain spot, + * so that it's okay to overwrite misspellings. In practice, given the + * relatively lame parsing technology used in this file, the level of + * certainty is seldom that high, so that you probably don't want to + * use this. Use complete_from_list with a one-element list instead; + * that won't try to auto-correct "misspellings". */ static char * complete_from_const(const char *text, int state) @@ -4545,8 +4459,8 @@ exec_query(const char *query) if (PQresultStatus(result) != PGRES_TUPLES_OK) { #ifdef NOT_USED - psql_error("tab completion query failed: %s\nQuery was:\n%s\n", - PQerrorMessage(pset.db), query); + pg_log_error("tab completion query failed: %s\nQuery was:\n%s", + PQerrorMessage(pset.db), query); #endif PQclear(result); result = NULL; diff --git a/src/bin/psql/tab-complete.h b/src/bin/psql/tab-complete.h index 544318c36d8..bc553cef2b3 100644 --- a/src/bin/psql/tab-complete.h +++ b/src/bin/psql/tab-complete.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/tab-complete.h */ diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c index f0934426443..1d2a31cd65d 100644 --- a/src/bin/psql/variables.c +++ b/src/bin/psql/variables.c @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/bin/psql/variables.c */ @@ -10,6 +10,8 @@ #include "common.h" #include "variables.h" +#include "common/logging.h" + /* * Check whether a variable's name is allowed. @@ -136,8 +138,8 @@ ParseVariableBool(const char *value, const char *name, bool *result) { /* string is not recognized; don't clobber *result */ if (name) - psql_error("unrecognized value \"%s\" for \"%s\": Boolean expected\n", - value, name); + pg_log_error("unrecognized value \"%s\" for \"%s\": Boolean expected", + value, name); valid = false; } return valid; @@ -173,8 +175,8 @@ ParseVariableNum(const char *value, const char *name, int *result) { /* string is not recognized; don't clobber *result */ if (name) - psql_error("invalid value \"%s\" for \"%s\": integer expected\n", - value, name); + pg_log_error("invalid value \"%s\" for \"%s\": integer expected", + value, name); return false; } } @@ -221,7 +223,7 @@ SetVariable(VariableSpace space, const char *name, const char *value) /* Deletion of non-existent variable is not an error */ if (!value) return true; - psql_error("invalid variable name: \"%s\"\n", name); + pg_log_error("invalid variable name: \"%s\"", name); return false; } @@ -390,6 +392,7 @@ DeleteVariable(VariableSpace space, const char *name) void PsqlVarEnumError(const char *name, const char *value, const char *suggestions) { - psql_error("unrecognized value \"%s\" for \"%s\"\nAvailable values are: %s.\n", - value, name, suggestions); + pg_log_error("unrecognized value \"%s\" for \"%s\"\n" + "Available values are: %s.", + value, name, suggestions); } diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h index 03af11197ca..9d4cf547134 100644 --- a/src/bin/psql/variables.h +++ b/src/bin/psql/variables.h @@ -1,7 +1,7 @@ /* * psql - the PostgreSQL interactive terminal * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * This implements a sort of variable repository. One could also think of it * as a cheap version of an associative array. Each variable has a string @@ -21,7 +21,7 @@ * An assign hook function is called before any attempted assignment, with the * proposed new value of the variable (or with NULL, if an \unset is being * attempted). If it returns false, the assignment doesn't occur --- it - * should print an error message with psql_error() to tell the user why. + * should print an error message with pg_log_error() to tell the user why. * * When an assign hook function is installed with SetVariableHooks(), it is * called with the variable's current value (or with NULL, if it wasn't set @@ -75,11 +75,11 @@ typedef struct _variable *VariableSpace; VariableSpace CreateVariableSpace(void); const char *GetVariable(VariableSpace space, const char *name); -bool ParseVariableBool(const char *value, const char *name, - bool *result); +bool ParseVariableBool(const char *value, const char *name, + bool *result); -bool ParseVariableNum(const char *value, const char *name, - int *result); +bool ParseVariableNum(const char *value, const char *name, + int *result); void PrintVariables(VariableSpace space); @@ -87,9 +87,9 @@ bool SetVariable(VariableSpace space, const char *name, const char *value); bool SetVariableBool(VariableSpace space, const char *name); bool DeleteVariable(VariableSpace space, const char *name); -void SetVariableHooks(VariableSpace space, const char *name, - VariableSubstituteHook shook, - VariableAssignHook ahook); +void SetVariableHooks(VariableSpace space, const char *name, + VariableSubstituteHook shook, + VariableAssignHook ahook); void PsqlVarEnumError(const char *name, const char *value, const char *suggestions); diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile index 4c6e4b93952..ede665090f7 100644 --- a/src/bin/scripts/Makefile +++ b/src/bin/scripts/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/bin/scripts # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/bin/scripts/Makefile @@ -23,17 +23,14 @@ LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) all: $(PROGRAMS) -%: %.o $(WIN32RES) - $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X) - -createdb: createdb.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -createuser: createuser.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -dropdb: dropdb.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -dropuser: dropuser.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -clusterdb: clusterdb.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -vacuumdb: vacuumdb.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -reindexdb: reindexdb.o common.o | submake-libpq submake-libpgport submake-libpgfeutils -pg_isready: pg_isready.o common.o | submake-libpq submake-libpgport submake-libpgfeutils +createdb: createdb.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +createuser: createuser.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +dropdb: dropdb.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +dropuser: dropuser.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +clusterdb: clusterdb.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +vacuumdb: vacuumdb.o common.o scripts_parallel.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +reindexdb: reindexdb.o common.o scripts_parallel.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils +pg_isready: pg_isready.o common.o $(WIN32RES) | submake-libpq submake-libpgport submake-libpgfeutils install: all installdirs $(INSTALL_PROGRAM) createdb$(X) '$(DESTDIR)$(bindir)'/createdb$(X) @@ -53,7 +50,7 @@ uninstall: clean distclean maintainer-clean: rm -f $(addsuffix $(X), $(PROGRAMS)) $(addsuffix .o, $(PROGRAMS)) - rm -f common.o $(WIN32RES) + rm -f common.o scripts_parallel.o $(WIN32RES) rm -rf tmp_check check: diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c index 650d2ae2610..d3801273566 100644 --- a/src/bin/scripts/clusterdb.c +++ b/src/bin/scripts/clusterdb.c @@ -2,7 +2,7 @@ * * clusterdb * - * Portions Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2002-2019, PostgreSQL Global Development Group * * src/bin/scripts/clusterdb.c * @@ -11,18 +11,19 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #include "fe_utils/simple_list.h" #include "fe_utils/string_utils.h" static void cluster_one_database(const char *dbname, bool verbose, const char *table, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo); + const char *host, const char *port, + const char *username, enum trivalue prompt_password, + const char *progname, bool echo); static void cluster_all_databases(bool verbose, const char *maintenance_db, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo, bool quiet); + const char *host, const char *port, + const char *username, enum trivalue prompt_password, + const char *progname, bool echo, bool quiet); static void help(const char *progname); @@ -62,6 +63,7 @@ main(int argc, char *argv[]) bool verbose = false; SimpleStringList tables = {NULL, NULL}; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); @@ -125,8 +127,8 @@ main(int argc, char *argv[]) if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -137,15 +139,13 @@ main(int argc, char *argv[]) { if (dbname) { - fprintf(stderr, _("%s: cannot cluster all databases and a specific one at the same time\n"), - progname); + pg_log_error("cannot cluster all databases and a specific one at the same time"); exit(1); } if (tables.head != NULL) { - fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"), - progname); + pg_log_error("cannot cluster specific table(s) in all databases"); exit(1); } @@ -206,18 +206,18 @@ cluster_one_database(const char *dbname, bool verbose, const char *table, if (table) { appendPQExpBufferChar(&sql, ' '); - appendQualifiedRelation(&sql, table, conn, progname, echo); + appendQualifiedRelation(&sql, table, conn, echo); } appendPQExpBufferChar(&sql, ';'); if (!executeMaintenanceCommand(conn, sql.data, echo)) { if (table) - fprintf(stderr, _("%s: clustering of table \"%s\" in database \"%s\" failed: %s"), - progname, table, PQdb(conn), PQerrorMessage(conn)); + pg_log_error("clustering of table \"%s\" in database \"%s\" failed: %s", + table, PQdb(conn), PQerrorMessage(conn)); else - fprintf(stderr, _("%s: clustering of database \"%s\" failed: %s"), - progname, PQdb(conn), PQerrorMessage(conn)); + pg_log_error("clustering of database \"%s\" failed: %s", + PQdb(conn), PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -239,7 +239,7 @@ cluster_all_databases(bool verbose, const char *maintenance_db, conn = connectMaintenanceDatabase(maintenance_db, host, port, username, prompt_password, progname, echo); - result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); + result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", echo); PQfinish(conn); initPQExpBuffer(&connstr); @@ -254,7 +254,7 @@ cluster_all_databases(bool verbose, const char *maintenance_db, } resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, dbname); cluster_one_database(connstr.data, verbose, NULL, @@ -290,5 +290,5 @@ help(const char *progname) printf(_(" -W, --password force password prompt\n")); printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); printf(_("\nRead the description of the SQL command CLUSTER for details.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c index db2b9f0d683..1b38a1da494 100644 --- a/src/bin/scripts/common.c +++ b/src/bin/scripts/common.c @@ -4,7 +4,7 @@ * Common support routines for bin/scripts/ * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/common.c @@ -18,9 +18,12 @@ #include #include "common.h" +#include "common/logging.h" #include "fe_utils/connect.h" #include "fe_utils/string_utils.h" +#define ERRCODE_UNDEFINED_TABLE "42P01" + static PGcancel *volatile cancelConn = NULL; bool CancelRequested = false; @@ -113,8 +116,8 @@ connectDatabase(const char *dbname, const char *pghost, if (!conn) { - fprintf(stderr, _("%s: could not connect to database %s: out of memory\n"), - progname, dbname); + pg_log_error("could not connect to database %s: out of memory", + dbname); exit(1); } @@ -140,14 +143,12 @@ connectDatabase(const char *dbname, const char *pghost, PQfinish(conn); return NULL; } - fprintf(stderr, _("%s: could not connect to database %s: %s"), - progname, dbname, PQerrorMessage(conn)); + pg_log_error("could not connect to database %s: %s", + dbname, PQerrorMessage(conn)); exit(1); } - if (PQserverVersion(conn) >= 70300) - PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, - progname, echo)); + PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo)); return conn; } @@ -178,11 +179,35 @@ connectMaintenanceDatabase(const char *maintenance_db, return conn; } +/* + * Disconnect the given connection, canceling any statement if one is active. + */ +void +disconnectDatabase(PGconn *conn) +{ + char errbuf[256]; + + Assert(conn != NULL); + + if (PQtransactionStatus(conn) == PQTRANS_ACTIVE) + { + PGcancel *cancel; + + if ((cancel = PQgetCancel(conn))) + { + (void) PQcancel(cancel, errbuf, sizeof(errbuf)); + PQfreeCancel(cancel); + } + } + + PQfinish(conn); +} + /* * Run a query, return the results, exit program on failure. */ PGresult * -executeQuery(PGconn *conn, const char *query, const char *progname, bool echo) +executeQuery(PGconn *conn, const char *query, bool echo) { PGresult *res; @@ -193,10 +218,8 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo) if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr, _("%s: query failed: %s"), - progname, PQerrorMessage(conn)); - fprintf(stderr, _("%s: query was: %s\n"), - progname, query); + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_info("query was: %s", query); PQfinish(conn); exit(1); } @@ -209,8 +232,7 @@ executeQuery(PGconn *conn, const char *query, const char *progname, bool echo) * As above for a SQL command (which returns nothing). */ void -executeCommand(PGconn *conn, const char *query, - const char *progname, bool echo) +executeCommand(PGconn *conn, const char *query, bool echo) { PGresult *res; @@ -221,10 +243,8 @@ executeCommand(PGconn *conn, const char *query, if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: query failed: %s"), - progname, PQerrorMessage(conn)); - fprintf(stderr, _("%s: query was: %s\n"), - progname, query); + pg_log_error("query failed: %s", PQerrorMessage(conn)); + pg_log_info("query was: %s", query); PQfinish(conn); exit(1); } @@ -259,15 +279,66 @@ executeMaintenanceCommand(PGconn *conn, const char *query, bool echo) return r; } +/* + * Consume all the results generated for the given connection until + * nothing remains. If at least one error is encountered, return false. + * Note that this will block if the connection is busy. + */ +bool +consumeQueryResult(PGconn *conn) +{ + bool ok = true; + PGresult *result; + + SetCancelConn(conn); + while ((result = PQgetResult(conn)) != NULL) + { + if (!processQueryResult(conn, result)) + ok = false; + } + ResetCancelConn(); + return ok; +} + +/* + * Process (and delete) a query result. Returns true if there's no error, + * false otherwise -- but errors about trying to work on a missing relation + * are reported and subsequently ignored. + */ +bool +processQueryResult(PGconn *conn, PGresult *result) +{ + /* + * If it's an error, report it. Errors about a missing table are harmless + * so we continue processing; but die for other errors. + */ + if (PQresultStatus(result) != PGRES_COMMAND_OK) + { + char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE); + + pg_log_error("processing of database \"%s\" failed: %s", + PQdb(conn), PQerrorMessage(conn)); + + if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) != 0) + { + PQclear(result); + return false; + } + } + + PQclear(result); + return true; +} + /* * Split TABLE[(COLUMNS)] into TABLE and [(COLUMNS)] portions. When you * finish using them, pg_free(*table). *columns is a pointer into "spec", * possibly to its NUL terminator. */ -static void -split_table_columns_spec(const char *spec, int encoding, - char **table, const char **columns) +void +splitTableColumnsSpec(const char *spec, int encoding, + char **table, const char **columns) { bool inquotes = false; const char *cp = spec; @@ -303,7 +374,7 @@ split_table_columns_spec(const char *spec, int encoding, */ void appendQualifiedRelation(PQExpBuffer buf, const char *spec, - PGconn *conn, const char *progname, bool echo) + PGconn *conn, bool echo) { char *table; const char *columns; @@ -311,14 +382,7 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec, PGresult *res; int ntups; - /* Before 7.3, the concept of qualifying a name did not exist. */ - if (PQserverVersion(conn) < 70300) - { - appendPQExpBufferStr(&sql, spec); - return; - } - - split_table_columns_spec(spec, PQclientEncoding(conn), &table, &columns); + splitTableColumnsSpec(spec, PQclientEncoding(conn), &table, &columns); /* * Query must remain ABSOLUTELY devoid of unqualified names. This would @@ -335,7 +399,7 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec, appendStringLiteralConn(&sql, table, conn); appendPQExpBufferStr(&sql, "::pg_catalog.regclass;"); - executeCommand(conn, "RESET search_path", progname, echo); + executeCommand(conn, "RESET search_path;", echo); /* * One row is a typical result, as is a nonexistent relation ERROR. @@ -343,29 +407,26 @@ appendQualifiedRelation(PQExpBuffer buf, const char *spec, * relation has that OID; this query returns no rows. Catalog corruption * might elicit other row counts. */ - res = executeQuery(conn, sql.data, progname, echo); + res = executeQuery(conn, sql.data, echo); ntups = PQntuples(res); if (ntups != 1) { - fprintf(stderr, - ngettext("%s: query returned %d row instead of one: %s\n", - "%s: query returned %d rows instead of one: %s\n", - ntups), - progname, ntups, sql.data); + pg_log_error(ngettext("query returned %d row instead of one: %s", + "query returned %d rows instead of one: %s", + ntups), + ntups, sql.data); PQfinish(conn); exit(1); } appendPQExpBufferStr(buf, - fmtQualifiedId(PQserverVersion(conn), - PQgetvalue(res, 0, 1), + fmtQualifiedId(PQgetvalue(res, 0, 1), PQgetvalue(res, 0, 0))); appendPQExpBufferStr(buf, columns); PQclear(res); termPQExpBuffer(&sql); pg_free(table); - PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, - progname, echo)); + PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo)); } diff --git a/src/bin/scripts/common.h b/src/bin/scripts/common.h index 30a39a62475..f36b26a5765 100644 --- a/src/bin/scripts/common.h +++ b/src/bin/scripts/common.h @@ -2,7 +2,7 @@ * common.h * Common support routines for bin/scripts/ * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/bin/scripts/common.h */ @@ -26,30 +26,37 @@ extern bool CancelRequested; typedef void (*help_handler) (const char *progname); extern void handle_help_version_opts(int argc, char *argv[], - const char *fixed_progname, - help_handler hlp); + const char *fixed_progname, + help_handler hlp); extern PGconn *connectDatabase(const char *dbname, const char *pghost, - const char *pgport, const char *pguser, - enum trivalue prompt_password, const char *progname, - bool echo, bool fail_ok, bool allow_password_reuse); + const char *pgport, const char *pguser, + enum trivalue prompt_password, const char *progname, + bool echo, bool fail_ok, bool allow_password_reuse); extern PGconn *connectMaintenanceDatabase(const char *maintenance_db, - const char *pghost, const char *pgport, - const char *pguser, enum trivalue prompt_password, - const char *progname, bool echo); + const char *pghost, const char *pgport, + const char *pguser, enum trivalue prompt_password, + const char *progname, bool echo); -extern PGresult *executeQuery(PGconn *conn, const char *query, - const char *progname, bool echo); +extern void disconnectDatabase(PGconn *conn); -extern void executeCommand(PGconn *conn, const char *query, - const char *progname, bool echo); +extern PGresult *executeQuery(PGconn *conn, const char *query, bool echo); + +extern void executeCommand(PGconn *conn, const char *query, bool echo); extern bool executeMaintenanceCommand(PGconn *conn, const char *query, - bool echo); + bool echo); + +extern bool consumeQueryResult(PGconn *conn); + +extern bool processQueryResult(PGconn *conn, PGresult *result); + +extern void splitTableColumnsSpec(const char *spec, int encoding, + char **table, const char **columns); extern void appendQualifiedRelation(PQExpBuffer buf, const char *name, - PGconn *conn, const char *progname, bool echo); + PGconn *conn, bool echo); extern bool yesno_prompt(const char *question); diff --git a/src/bin/scripts/createdb.c b/src/bin/scripts/createdb.c index fc108882e43..64bcc20cb48 100644 --- a/src/bin/scripts/createdb.c +++ b/src/bin/scripts/createdb.c @@ -2,7 +2,7 @@ * * createdb * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/createdb.c @@ -12,6 +12,7 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #include "fe_utils/string_utils.h" @@ -64,6 +65,7 @@ main(int argc, char *argv[]) PGconn *conn; PGresult *result; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); @@ -133,8 +135,8 @@ main(int argc, char *argv[]) comment = argv[optind + 1]; break; default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 2]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind + 2]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -143,14 +145,12 @@ main(int argc, char *argv[]) { if (lc_ctype) { - fprintf(stderr, _("%s: only one of --locale and --lc-ctype can be specified\n"), - progname); + pg_log_error("only one of --locale and --lc-ctype can be specified"); exit(1); } if (lc_collate) { - fprintf(stderr, _("%s: only one of --locale and --lc-collate can be specified\n"), - progname); + pg_log_error("only one of --locale and --lc-collate can be specified"); exit(1); } lc_ctype = locale; @@ -161,8 +161,7 @@ main(int argc, char *argv[]) { if (pg_char_to_encoding(encoding) < 0) { - fprintf(stderr, _("%s: \"%s\" is not a valid encoding name\n"), - progname, encoding); + pg_log_error("\"%s\" is not a valid encoding name", encoding); exit(1); } } @@ -210,8 +209,7 @@ main(int argc, char *argv[]) if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: database creation failed: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("database creation failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -230,8 +228,8 @@ main(int argc, char *argv[]) if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: comment creation failed (database was created): %s"), - progname, PQerrorMessage(conn)); + pg_log_error("comment creation failed (database was created): %s", + PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -270,5 +268,5 @@ help(const char *progname) printf(_(" -W, --password force password prompt\n")); printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); printf(_("\nBy default, a database with the same name as the current user is created.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c index 3420e62fdd9..973ba525b25 100644 --- a/src/bin/scripts/createuser.c +++ b/src/bin/scripts/createuser.c @@ -2,7 +2,7 @@ * * createuser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/createuser.c @@ -12,6 +12,7 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #include "fe_utils/simple_list.h" #include "fe_utils/string_utils.h" @@ -81,6 +82,7 @@ main(int argc, char *argv[]) PGconn *conn; PGresult *result; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); @@ -176,8 +178,8 @@ main(int argc, char *argv[]) newuser = argv[optind]; break; default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 1]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind + 1]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -269,8 +271,8 @@ main(int argc, char *argv[]) NULL); if (!encrypted_password) { - fprintf(stderr, _("%s: password encryption failed: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("password encryption failed: %s", + PQerrorMessage(conn)); exit(1); } appendStringLiteralConn(&sql, encrypted_password, conn); @@ -324,8 +326,7 @@ main(int argc, char *argv[]) if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: creation of new role failed: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("creation of new role failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -370,5 +371,5 @@ help(const char *progname) printf(_(" -U, --username=USERNAME user name to connect as (not the one to create)\n")); printf(_(" -w, --no-password never prompt for password\n")); printf(_(" -W, --password force password prompt\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/dropdb.c b/src/bin/scripts/dropdb.c index ba0038891d6..dacd8e5f1dc 100644 --- a/src/bin/scripts/dropdb.c +++ b/src/bin/scripts/dropdb.c @@ -2,7 +2,7 @@ * * dropdb * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/dropdb.c @@ -12,6 +12,7 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #include "fe_utils/string_utils.h" @@ -54,6 +55,7 @@ main(int argc, char *argv[]) PGconn *conn; PGresult *result; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); @@ -99,15 +101,15 @@ main(int argc, char *argv[]) switch (argc - optind) { case 0: - fprintf(stderr, _("%s: missing required argument database name\n"), progname); + pg_log_error("missing required argument database name"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); case 1: dbname = argv[optind]; break; default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 1]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind + 1]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -137,8 +139,7 @@ main(int argc, char *argv[]) result = PQexec(conn, sql.data); if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: database removal failed: %s"), - progname, PQerrorMessage(conn)); + pg_log_error("database removal failed: %s", PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -168,5 +169,5 @@ help(const char *progname) printf(_(" -w, --no-password never prompt for password\n")); printf(_(" -W, --password force password prompt\n")); printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/dropuser.c b/src/bin/scripts/dropuser.c index d9e7f7b0364..3501a06ecb1 100644 --- a/src/bin/scripts/dropuser.c +++ b/src/bin/scripts/dropuser.c @@ -2,7 +2,7 @@ * * dropuser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/dropuser.c @@ -12,6 +12,7 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #include "fe_utils/string_utils.h" @@ -53,6 +54,7 @@ main(int argc, char *argv[]) PGconn *conn; PGresult *result; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); @@ -100,8 +102,8 @@ main(int argc, char *argv[]) dropuser = argv[optind]; break; default: - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind + 1]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind + 1]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -116,7 +118,7 @@ main(int argc, char *argv[]) } else { - fprintf(stderr, _("%s: missing required argument role name\n"), progname); + pg_log_error("missing required argument role name"); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -142,8 +144,8 @@ main(int argc, char *argv[]) if (PQresultStatus(result) != PGRES_COMMAND_OK) { - fprintf(stderr, _("%s: removal of role \"%s\" failed: %s"), - progname, dropuser, PQerrorMessage(conn)); + pg_log_error("removal of role \"%s\" failed: %s", + dropuser, PQerrorMessage(conn)); PQfinish(conn); exit(1); } @@ -173,5 +175,5 @@ help(const char *progname) printf(_(" -U, --username=USERNAME user name to connect as (not the one to drop)\n")); printf(_(" -w, --no-password never prompt for password\n")); printf(_(" -W, --password force password prompt\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/nls.mk b/src/bin/scripts/nls.mk index 63f4b0b7eb8..2c99a6a4618 100644 --- a/src/bin/scripts/nls.mk +++ b/src/bin/scripts/nls.mk @@ -1,11 +1,13 @@ # src/bin/scripts/nls.mk CATALOG_NAME = pgscripts -AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv zh_CN -GETTEXT_FILES = createdb.c createuser.c \ +AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN +GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ + createdb.c createuser.c \ dropdb.c dropuser.c \ clusterdb.c vacuumdb.c reindexdb.c \ pg_isready.c \ common.c \ ../../fe_utils/print.c \ ../../common/fe_memutils.c ../../common/username.c -GETTEXT_TRIGGERS = simple_prompt yesno_prompt +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt yesno_prompt +GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/scripts/pg_isready.c b/src/bin/scripts/pg_isready.c index f7ad7b40f0d..079447f9510 100644 --- a/src/bin/scripts/pg_isready.c +++ b/src/bin/scripts/pg_isready.c @@ -2,7 +2,7 @@ * * pg_isready --- checks the status of the PostgreSQL server * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * src/bin/scripts/pg_isready.c * @@ -11,6 +11,7 @@ #include "postgres_fe.h" #include "common.h" +#include "common/logging.h" #define DEFAULT_CONNECT_TIMEOUT "3" @@ -63,6 +64,7 @@ main(int argc, char **argv) {NULL, 0, NULL, 0} }; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); handle_help_version_opts(argc, argv, progname, help); @@ -102,8 +104,8 @@ main(int argc, char **argv) if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); /* @@ -139,7 +141,7 @@ main(int argc, char **argv) opts = PQconninfoParse(pgdbname, &errmsg); if (opts == NULL) { - fprintf(stderr, _("%s: %s"), progname, errmsg); + pg_log_error("%s", errmsg); exit(PQPING_NO_ATTEMPT); } } @@ -147,7 +149,7 @@ main(int argc, char **argv) defs = PQconndefaults(); if (defs == NULL) { - fprintf(stderr, _("%s: could not fetch default options\n"), progname); + pg_log_error("could not fetch default options"); exit(PQPING_NO_ATTEMPT); } @@ -233,5 +235,5 @@ help(const char *progname) printf(_(" -p, --port=PORT database server port\n")); printf(_(" -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n"), DEFAULT_CONNECT_TIMEOUT); printf(_(" -U, --username=USERNAME user name to connect as\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/po/de.po b/src/bin/scripts/po/de.po index b9c8c3b6eab..f0a579d1a52 100644 --- a/src/bin/scripts/po/de.po +++ b/src/bin/scripts/po/de.po @@ -1,22 +1,37 @@ # German message translation file for "scripts". -# Peter Eisentraut , 2003 - 2017. +# Peter Eisentraut , 2003 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-12 23:46+0000\n" -"PO-Revision-Date: 2017-05-13 09:24-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-14 07:47+0000\n" +"PO-Revision-Date: 2019-05-14 15:49+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "Fatal: " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "Fehler: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "Warnung: " + #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 #, c-format @@ -49,67 +64,66 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu Zeile)" msgstr[1] "(%lu Zeilen)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "Unterbrochen\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kann keinen weiteren Spaltenkopf zur Tabelle hinzufügen: Spaltenzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Cann keine weitere Zelle zur Tabelle hinzufügen: Zellengesamtzahl %d überschritten.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "ungültiges Ausgabeformat (interner Fehler): %d" -#: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 -#: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 -#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 -#: pg_isready.c:107 reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 -#: vacuumdb.c:232 +#: clusterdb.c:113 clusterdb.c:132 createdb.c:121 createdb.c:140 +#: createuser.c:168 createuser.c:183 dropdb.c:96 dropdb.c:105 dropdb.c:113 +#: dropuser.c:92 dropuser.c:107 dropuser.c:122 pg_isready.c:95 pg_isready.c:109 +#: reindexdb.c:139 reindexdb.c:158 vacuumdb.c:246 vacuumdb.c:265 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: clusterdb.c:128 createdb.c:136 createuser.c:179 dropdb.c:109 dropuser.c:103 -#: pg_isready.c:105 reindexdb.c:148 vacuumdb.c:230 +#: clusterdb.c:130 createdb.c:138 createuser.c:181 dropdb.c:111 dropuser.c:105 +#: pg_isready.c:107 reindexdb.c:156 vacuumdb.c:263 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: zu viele Kommandozeilenargumente (das erste ist »%s«)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)" -#: clusterdb.c:140 +#: clusterdb.c:142 #, c-format -msgid "%s: cannot cluster all databases and a specific one at the same time\n" -msgstr "%s: kann nicht alle Datenbanken und eine bestimmte gleichzeitig clustern\n" +msgid "cannot cluster all databases and a specific one at the same time" +msgstr "kann nicht alle Datenbanken und eine bestimmte gleichzeitig clustern" -#: clusterdb.c:147 +#: clusterdb.c:148 #, c-format -msgid "%s: cannot cluster specific table(s) in all databases\n" -msgstr "%s: kann nicht bestimmte Tabelle(n) in allen Datenbanken clustern\n" +msgid "cannot cluster specific table(s) in all databases" +msgstr "kann nicht bestimmte Tabelle(n) in allen Datenbanken clustern" -#: clusterdb.c:212 +#: clusterdb.c:216 #, c-format -msgid "%s: clustering of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: Clustern der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" +msgid "clustering of table \"%s\" in database \"%s\" failed: %s" +msgstr "Clustern der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: clusterdb.c:215 +#: clusterdb.c:219 #, c-format -msgid "%s: clustering of database \"%s\" failed: %s" -msgstr "%s: Clustern der Datenbank »%s« fehlgeschlagen: %s" +msgid "clustering of database \"%s\" failed: %s" +msgstr "Clustern der Datenbank »%s« fehlgeschlagen: %s" -#: clusterdb.c:248 +#: clusterdb.c:252 #, c-format msgid "%s: clustering database \"%s\"\n" msgstr "%s: clustere Datenbank »%s«\n" -#: clusterdb.c:269 +#: clusterdb.c:273 #, c-format msgid "" "%s clusters all previously clustered tables in a database.\n" @@ -118,19 +132,19 @@ msgstr "" "%s clustert alle vorher geclusterten Tabellen in einer Datenbank.\n" "\n" -#: clusterdb.c:270 createdb.c:252 createuser.c:343 dropdb.c:155 dropuser.c:161 -#: pg_isready.c:222 reindexdb.c:401 vacuumdb.c:952 +#: clusterdb.c:274 createdb.c:250 createuser.c:344 dropdb.c:157 dropuser.c:163 +#: pg_isready.c:224 reindexdb.c:425 vacuumdb.c:1216 #, c-format msgid "Usage:\n" msgstr "Aufruf:\n" -#: clusterdb.c:271 reindexdb.c:402 vacuumdb.c:953 +#: clusterdb.c:275 reindexdb.c:426 vacuumdb.c:1217 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPTION]... [DBNAME]\n" -#: clusterdb.c:272 createdb.c:254 createuser.c:345 dropdb.c:157 dropuser.c:163 -#: pg_isready.c:225 reindexdb.c:403 vacuumdb.c:954 +#: clusterdb.c:276 createdb.c:252 createuser.c:346 dropdb.c:159 dropuser.c:165 +#: pg_isready.c:227 reindexdb.c:427 vacuumdb.c:1218 #, c-format msgid "" "\n" @@ -139,53 +153,50 @@ msgstr "" "\n" "Optionen:\n" -#: clusterdb.c:273 +#: clusterdb.c:277 #, c-format msgid " -a, --all cluster all databases\n" msgstr " -a, --all clustere alle Datenbanken\n" -#: clusterdb.c:274 +#: clusterdb.c:278 #, c-format msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=DBNAME zu clusternde Datenbank\n" -#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 -#: reindexdb.c:406 +#: clusterdb.c:279 createuser.c:350 dropdb.c:160 dropuser.c:166 reindexdb.c:431 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr "" " -e, --echo zeige die Befehle, die an den Server\n" " gesendet werden\n" -#: clusterdb.c:276 reindexdb.c:408 +#: clusterdb.c:280 reindexdb.c:433 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet unterdrücke alle Mitteilungen\n" -#: clusterdb.c:277 +#: clusterdb.c:281 #, c-format msgid " -t, --table=TABLE cluster specific table(s) only\n" msgstr " -t, --table=TABELLE clustere nur bestimmte Tabelle(n)\n" -#: clusterdb.c:278 reindexdb.c:412 +#: clusterdb.c:282 reindexdb.c:437 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose erzeuge viele Meldungen\n" -#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 -#: reindexdb.c:413 +#: clusterdb.c:283 createuser.c:362 dropdb.c:162 dropuser.c:169 reindexdb.c:438 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 -#: reindexdb.c:414 +#: clusterdb.c:284 createuser.c:367 dropdb.c:164 dropuser.c:171 reindexdb.c:439 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: clusterdb.c:281 createdb.c:265 createuser.c:367 dropdb.c:163 dropuser.c:170 -#: pg_isready.c:231 reindexdb.c:415 vacuumdb.c:970 +#: clusterdb.c:285 createdb.c:263 createuser.c:368 dropdb.c:165 dropuser.c:172 +#: pg_isready.c:233 reindexdb.c:440 vacuumdb.c:1238 #, c-format msgid "" "\n" @@ -194,41 +205,41 @@ msgstr "" "\n" "Verbindungsoptionen:\n" -#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 -#: reindexdb.c:416 vacuumdb.c:971 +#: clusterdb.c:286 createuser.c:369 dropdb.c:166 dropuser.c:173 reindexdb.c:441 +#: vacuumdb.c:1239 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 -#: reindexdb.c:417 vacuumdb.c:972 +#: clusterdb.c:287 createuser.c:370 dropdb.c:167 dropuser.c:174 reindexdb.c:442 +#: vacuumdb.c:1240 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT Port des Datenbankservers\n" -#: clusterdb.c:284 dropdb.c:166 reindexdb.c:418 vacuumdb.c:973 +#: clusterdb.c:288 dropdb.c:168 reindexdb.c:443 vacuumdb.c:1241 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 -#: reindexdb.c:419 vacuumdb.c:974 +#: clusterdb.c:289 createuser.c:372 dropdb.c:169 dropuser.c:176 reindexdb.c:444 +#: vacuumdb.c:1242 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 -#: reindexdb.c:420 vacuumdb.c:975 +#: clusterdb.c:290 createuser.c:373 dropdb.c:170 dropuser.c:177 reindexdb.c:445 +#: vacuumdb.c:1243 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password Passwortfrage erzwingen\n" -#: clusterdb.c:287 dropdb.c:169 reindexdb.c:421 vacuumdb.c:976 +#: clusterdb.c:291 dropdb.c:171 reindexdb.c:446 vacuumdb.c:1244 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAME alternative Wartungsdatenbank\n" -#: clusterdb.c:288 +#: clusterdb.c:292 #, c-format msgid "" "\n" @@ -238,98 +249,105 @@ msgstr "" "Für weitere Informationen lesen Sie bitte die Beschreibung des\n" "SQL-Befehls CLUSTER.\n" -#: clusterdb.c:289 createdb.c:273 createuser.c:373 dropdb.c:170 dropuser.c:176 -#: pg_isready.c:236 reindexdb.c:423 vacuumdb.c:978 +#: clusterdb.c:293 createdb.c:271 createuser.c:374 dropdb.c:172 dropuser.c:178 +#: pg_isready.c:238 reindexdb.c:448 vacuumdb.c:1246 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Berichten Sie Fehler an .\n" +"Berichten Sie Fehler an .\n" -#: common.c:80 common.c:126 +#: common.c:84 common.c:130 msgid "Password: " msgstr "Passwort: " -#: common.c:113 +#: common.c:117 #, c-format -msgid "%s: could not connect to database %s: out of memory\n" -msgstr "%s: konnte nicht mit Datenbank %s verbinden: Speicher aufgebraucht\n" +msgid "could not connect to database %s: out of memory" +msgstr "konnte nicht mit Datenbank %s verbinden: Speicher aufgebraucht" -#: common.c:140 +#: common.c:144 #, c-format -msgid "%s: could not connect to database %s: %s" -msgstr "%s: konnte nicht mit Datenbank %s verbinden: %s" +msgid "could not connect to database %s: %s" +msgstr "konnte nicht mit Datenbank %s verbinden: %s" -#: common.c:189 common.c:217 +#: common.c:196 common.c:222 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: Anfrage fehlgeschlagen: %s" +msgid "query failed: %s" +msgstr "Anfrage fehlgeschlagen: %s" -#: common.c:191 common.c:219 +#: common.c:197 common.c:223 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: Anfrage war: %s\n" +msgid "query was: %s" +msgstr "Anfrage war: %s" + +#: common.c:339 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "Anfrage ergab %d Zeile anstatt einer: %s" +msgstr[1] "Anfrage ergab %d Zeilen anstatt einer: %s" #. translator: abbreviation for "yes" -#: common.c:260 +#: common.c:364 msgid "y" msgstr "j" #. translator: abbreviation for "no" -#: common.c:262 +#: common.c:366 msgid "n" msgstr "n" #. translator: This is a question followed by the translated options for #. "yes" and "no". -#: common.c:272 +#: common.c:376 #, c-format msgid "%s (%s/%s) " msgstr "%s (%s/%s) " -#: common.c:286 +#: common.c:390 #, c-format msgid "Please answer \"%s\" or \"%s\".\n" msgstr "Bitte antworten Sie »%s« oder »%s«.\n" -#: common.c:365 common.c:402 +#: common.c:469 common.c:506 #, c-format msgid "Cancel request sent\n" msgstr "Abbruchsanforderung gesendet\n" -#: common.c:368 common.c:406 +#: common.c:472 common.c:510 #, c-format msgid "Could not send cancel request: %s" msgstr "Konnte Abbruchsanforderung nicht senden: %s" -#: createdb.c:146 +#: createdb.c:148 #, c-format -msgid "%s: only one of --locale and --lc-ctype can be specified\n" -msgstr "%s: --locale und --lc-ctype können nicht zusammen angegeben werden\n" +msgid "only one of --locale and --lc-ctype can be specified" +msgstr "--locale und --lc-ctype können nicht zusammen angegeben werden" -#: createdb.c:152 +#: createdb.c:153 #, c-format -msgid "%s: only one of --locale and --lc-collate can be specified\n" -msgstr "%s: --locale und --lc-collate können nicht zusammen angegeben werden\n" +msgid "only one of --locale and --lc-collate can be specified" +msgstr "--locale und --lc-collate können nicht zusammen angegeben werden" #: createdb.c:164 #, c-format -msgid "%s: \"%s\" is not a valid encoding name\n" -msgstr "%s: »%s« ist kein gültiger Kodierungsname\n" +msgid "\"%s\" is not a valid encoding name" +msgstr "»%s« ist kein gültiger Kodierungsname" -#: createdb.c:213 +#: createdb.c:212 #, c-format -msgid "%s: database creation failed: %s" -msgstr "%s: Erzeugen der Datenbank ist fehlgeschlagen: %s" +msgid "database creation failed: %s" +msgstr "Erzeugen der Datenbank ist fehlgeschlagen: %s" -#: createdb.c:233 +#: createdb.c:231 #, c-format -msgid "%s: comment creation failed (database was created): %s" -msgstr "%s: Erzeugen des Kommentars ist fehlgeschlagen (Datenbank wurde erzeugt): %s" +msgid "comment creation failed (database was created): %s" +msgstr "Erzeugen des Kommentars ist fehlgeschlagen (Datenbank wurde erzeugt): %s" -#: createdb.c:251 +#: createdb.c:249 #, c-format msgid "" "%s creates a PostgreSQL database.\n" @@ -338,94 +356,94 @@ msgstr "" "%s erzeugt eine PostgreSQL-Datenbank.\n" "\n" -#: createdb.c:253 +#: createdb.c:251 #, c-format msgid " %s [OPTION]... [DBNAME] [DESCRIPTION]\n" msgstr " %s [OPTION]... [DBNAME] [BESCHREIBUNG]\n" -#: createdb.c:255 +#: createdb.c:253 #, c-format msgid " -D, --tablespace=TABLESPACE default tablespace for the database\n" msgstr " -D, --tablespace=TABLESPACE Standard-Tablespace der Datenbank\n" -#: createdb.c:256 +#: createdb.c:254 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr "" " -e, --echo zeige die Befehle, die an den Server\n" " gesendet werden\n" -#: createdb.c:257 +#: createdb.c:255 #, c-format msgid " -E, --encoding=ENCODING encoding for the database\n" msgstr " -E, --encoding=KODIERUNG Kodierung für die Datenbank\n" -#: createdb.c:258 +#: createdb.c:256 #, c-format msgid " -l, --locale=LOCALE locale settings for the database\n" msgstr " -l, --locale=LOCALE Lokale-Einstellungen für die Datenbank\n" -#: createdb.c:259 +#: createdb.c:257 #, c-format msgid " --lc-collate=LOCALE LC_COLLATE setting for the database\n" msgstr " --lc-collate=LOCALE LC_COLLATE-Einstellung für die Datenbank\n" -#: createdb.c:260 +#: createdb.c:258 #, c-format msgid " --lc-ctype=LOCALE LC_CTYPE setting for the database\n" msgstr " --lc-ctype=LOCALE LC_CTYPE-Einstellung für die Datenbank\n" -#: createdb.c:261 +#: createdb.c:259 #, c-format msgid " -O, --owner=OWNER database user to own the new database\n" msgstr " -O, --owner=EIGENTÜMER Eigentümer der neuen Datenbank\n" -#: createdb.c:262 +#: createdb.c:260 #, c-format msgid " -T, --template=TEMPLATE template database to copy\n" msgstr " -T, --template=TEMPLATE zu kopierende Template-Datenbank\n" -#: createdb.c:263 +#: createdb.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: createdb.c:264 +#: createdb.c:262 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: createdb.c:266 +#: createdb.c:264 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: createdb.c:267 +#: createdb.c:265 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT Port des Datenbankservers\n" -#: createdb.c:268 +#: createdb.c:266 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: createdb.c:269 +#: createdb.c:267 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password niemals nach Passwort fragen\n" -#: createdb.c:270 +#: createdb.c:268 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password Passwortfrage erzwingen\n" -#: createdb.c:271 +#: createdb.c:269 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAME alternative Wartungsdatenbank\n" -#: createdb.c:272 +#: createdb.c:270 #, c-format msgid "" "\n" @@ -435,46 +453,46 @@ msgstr "" "Wenn nichts anderes angegeben ist, dann wird eine Datenbank mit dem Namen\n" "des aktuellen Benutzers erzeugt.\n" -#: createuser.c:189 +#: createuser.c:191 msgid "Enter name of role to add: " msgstr "Geben Sie den Namen der neuen Rolle ein: " -#: createuser.c:206 +#: createuser.c:208 msgid "Enter password for new role: " msgstr "Geben Sie das Passwort der neuen Rolle ein: " -#: createuser.c:208 +#: createuser.c:210 msgid "Enter it again: " msgstr "Geben Sie es noch einmal ein: " -#: createuser.c:211 +#: createuser.c:213 #, c-format msgid "Passwords didn't match.\n" msgstr "Passwörter stimmten nicht überein.\n" -#: createuser.c:219 +#: createuser.c:221 msgid "Shall the new role be a superuser?" msgstr "Soll die neue Rolle ein Superuser sein?" -#: createuser.c:234 +#: createuser.c:236 msgid "Shall the new role be allowed to create databases?" msgstr "Soll die neue Rolle Datenbanken erzeugen dürfen?" -#: createuser.c:242 +#: createuser.c:244 msgid "Shall the new role be allowed to create more new roles?" msgstr "Soll die neue Rolle weitere neue Rollen erzeugen dürfen?" -#: createuser.c:272 +#: createuser.c:274 #, c-format -msgid "%s: password encryption failed: %s" -msgstr "%s: Passwortverschlüsselung ist fehlgeschlagen: %s" +msgid "password encryption failed: %s" +msgstr "Passwortverschlüsselung ist fehlgeschlagen: %s" -#: createuser.c:327 +#: createuser.c:329 #, c-format -msgid "%s: creation of new role failed: %s" -msgstr "%s: Erzeugen der neuen Rolle fehlgeschlagen: %s" +msgid "creation of new role failed: %s" +msgstr "Erzeugen der neuen Rolle fehlgeschlagen: %s" -#: createuser.c:342 +#: createuser.c:343 #, c-format msgid "" "%s creates a new PostgreSQL role.\n" @@ -483,34 +501,34 @@ msgstr "" "%s erzeugt eine neue PostgreSQL-Rolle.\n" "\n" -#: createuser.c:344 dropuser.c:162 +#: createuser.c:345 dropuser.c:164 #, c-format msgid " %s [OPTION]... [ROLENAME]\n" msgstr " %s [OPTION]... [ROLLENNAME]\n" -#: createuser.c:346 +#: createuser.c:347 #, c-format msgid " -c, --connection-limit=N connection limit for role (default: no limit)\n" msgstr "" " -c, --connection-limit=N Hochzahl an Verbindungen für Rolle\n" " (Voreinstellung: keine Begrenzung)\n" -#: createuser.c:347 +#: createuser.c:348 #, c-format msgid " -d, --createdb role can create new databases\n" msgstr " -d, --createdb Rolle kann neue Datenbanken erzeugen\n" -#: createuser.c:348 +#: createuser.c:349 #, c-format msgid " -D, --no-createdb role cannot create databases (default)\n" msgstr " -D, --no-createdb Rolle kann keine Datenbanken erzeugen (Voreinstellung)\n" -#: createuser.c:350 +#: createuser.c:351 #, c-format msgid " -g, --role=ROLE new role will be a member of this role\n" msgstr " -g, --role=ROLLE neue Rolle wird Mitglied dieser Rolle\n" -#: createuser.c:351 +#: createuser.c:352 #, c-format msgid "" " -i, --inherit role inherits privileges of roles it is a\n" @@ -519,47 +537,47 @@ msgstr "" " -i, --inherit Rolle erbt alle Privilegien von Rollen, deren\n" " Mitglied sie ist (Voreinstellung)\n" -#: createuser.c:353 +#: createuser.c:354 #, c-format msgid " -I, --no-inherit role does not inherit privileges\n" msgstr " -I, --no-inherit Rolle erbt keine Privilegien\n" -#: createuser.c:354 +#: createuser.c:355 #, c-format msgid " -l, --login role can login (default)\n" msgstr " -l, --login Rolle kann sich anmelden (Voreinstellung)\n" -#: createuser.c:355 +#: createuser.c:356 #, c-format msgid " -L, --no-login role cannot login\n" msgstr " -L, --no-login Rolle kann sich nicht anmelden\n" -#: createuser.c:356 +#: createuser.c:357 #, c-format msgid " -P, --pwprompt assign a password to new role\n" msgstr " -P, --pwprompt weise der neuen Rolle ein Passwort zu\n" -#: createuser.c:357 +#: createuser.c:358 #, c-format msgid " -r, --createrole role can create new roles\n" msgstr " -r, --createrole Rolle kann neue Rollen erzeugen\n" -#: createuser.c:358 +#: createuser.c:359 #, c-format msgid " -R, --no-createrole role cannot create roles (default)\n" msgstr " -R, --no-createrole Rolle kann keine Rollen erzeugen (Voreinstellung)\n" -#: createuser.c:359 +#: createuser.c:360 #, c-format msgid " -s, --superuser role will be superuser\n" msgstr " -s, --superuser Rolle wird Superuser\n" -#: createuser.c:360 +#: createuser.c:361 #, c-format msgid " -S, --no-superuser role will not be superuser (default)\n" msgstr " -S, --no-superuser Rolle wird kein Superuser (Voreinstellung)\n" -#: createuser.c:362 +#: createuser.c:363 #, c-format msgid "" " --interactive prompt for missing role name and attributes rather\n" @@ -568,43 +586,43 @@ msgstr "" " --interactive nach fehlenden Rollennamen und -attributen fragen\n" " anstatt Vorgabewerte zu nehmen\n" -#: createuser.c:364 +#: createuser.c:365 #, c-format msgid " --replication role can initiate replication\n" msgstr " --replication Rolle kann Replikation einleiten\n" -#: createuser.c:365 +#: createuser.c:366 #, c-format msgid " --no-replication role cannot initiate replication\n" msgstr " --no-replication Rolle kann Replikation nicht einleiten\n" -#: createuser.c:370 +#: createuser.c:371 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to create)\n" msgstr "" " -U, --username=NAME Datenbankbenutzername für die Verbindung\n" " (nicht der Name des neuen Benutzers)\n" -#: dropdb.c:102 +#: dropdb.c:104 #, c-format -msgid "%s: missing required argument database name\n" -msgstr "%s: Datenbankname als Argument fehlt\n" +msgid "missing required argument database name" +msgstr "Datenbankname als Argument fehlt" -#: dropdb.c:117 +#: dropdb.c:119 #, c-format msgid "Database \"%s\" will be permanently removed.\n" msgstr "Datenbank »%s« wird unwiderruflich gelöscht werden.\n" -#: dropdb.c:118 dropuser.c:128 +#: dropdb.c:120 dropuser.c:130 msgid "Are you sure?" msgstr "Sind Sie sich sicher?" -#: dropdb.c:139 +#: dropdb.c:142 #, c-format -msgid "%s: database removal failed: %s" -msgstr "%s: Löschen der Datenbank fehlgeschlagen: %s" +msgid "database removal failed: %s" +msgstr "Löschen der Datenbank fehlgeschlagen: %s" -#: dropdb.c:154 +#: dropdb.c:156 #, c-format msgid "" "%s removes a PostgreSQL database.\n" @@ -613,41 +631,41 @@ msgstr "" "%s löscht eine PostgreSQL-Datenbank.\n" "\n" -#: dropdb.c:156 +#: dropdb.c:158 #, c-format msgid " %s [OPTION]... DBNAME\n" msgstr " %s [OPTION]... DBNAME\n" -#: dropdb.c:159 +#: dropdb.c:161 #, c-format msgid " -i, --interactive prompt before deleting anything\n" msgstr " -i, --interactive frage nach, bevor irgendetwas gelöscht wird\n" -#: dropdb.c:161 +#: dropdb.c:163 #, c-format msgid " --if-exists don't report error if database doesn't exist\n" msgstr " --if-exists keinen Fehler ausgeben, wenn Datenbank nicht existiert\n" -#: dropuser.c:113 +#: dropuser.c:115 msgid "Enter name of role to drop: " msgstr "Geben Sie den Namen der zu löschenden Rolle ein: " -#: dropuser.c:119 +#: dropuser.c:121 #, c-format -msgid "%s: missing required argument role name\n" -msgstr "%s: Rollenname als Argument fehlt\n" +msgid "missing required argument role name" +msgstr "Rollenname als Argument fehlt" -#: dropuser.c:127 +#: dropuser.c:129 #, c-format msgid "Role \"%s\" will be permanently removed.\n" msgstr "Rolle »%s« wird unwiderruflich gelöscht werden.\n" -#: dropuser.c:145 +#: dropuser.c:147 #, c-format -msgid "%s: removal of role \"%s\" failed: %s" -msgstr "%s: Löschen der Rolle »%s« fehlgeschlagen: %s" +msgid "removal of role \"%s\" failed: %s" +msgstr "Löschen der Rolle »%s« fehlgeschlagen: %s" -#: dropuser.c:160 +#: dropuser.c:162 #, c-format msgid "" "%s removes a PostgreSQL role.\n" @@ -656,7 +674,7 @@ msgstr "" "%s löscht eine PostgreSQL-Rolle.\n" "\n" -#: dropuser.c:165 +#: dropuser.c:167 #, c-format msgid "" " -i, --interactive prompt before deleting anything, and prompt for\n" @@ -665,54 +683,54 @@ msgstr "" " -i, --interactive nachfragen, bevor irgendetwas gelöscht wird, und\n" " nach Rollennamen fragen, wenn nicht angegeben\n" -#: dropuser.c:168 +#: dropuser.c:170 #, c-format msgid " --if-exists don't report error if user doesn't exist\n" msgstr " --if-exists keinen Fehler ausgeben, wenn Benutzer nicht existiert\n" -#: dropuser.c:173 +#: dropuser.c:175 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to drop)\n" msgstr "" " -U, --username=NAME Datenbankbenutzername für die Verbindung\n" " (nicht der Name des zu löschenden Benutzers)\n" -#: pg_isready.c:142 +#: pg_isready.c:144 #, c-format -msgid "%s: %s" -msgstr "%s: %s" +msgid "%s" +msgstr "%s" -#: pg_isready.c:150 +#: pg_isready.c:152 #, c-format -msgid "%s: could not fetch default options\n" -msgstr "%s: konnte Standardoptionen nicht ermitteln\n" +msgid "could not fetch default options" +msgstr "konnte Standardoptionen nicht ermitteln" -#: pg_isready.c:199 +#: pg_isready.c:201 #, c-format msgid "accepting connections\n" msgstr "Verbindungen werden angenommen\n" -#: pg_isready.c:202 +#: pg_isready.c:204 #, c-format msgid "rejecting connections\n" msgstr "Verbindungen werden abgelehnt\n" -#: pg_isready.c:205 +#: pg_isready.c:207 #, c-format msgid "no response\n" msgstr "keine Antwort\n" -#: pg_isready.c:208 +#: pg_isready.c:210 #, c-format msgid "no attempt\n" msgstr "kein Verbindungsversuch\n" -#: pg_isready.c:211 +#: pg_isready.c:213 #, c-format msgid "unknown\n" msgstr "unbekannt\n" -#: pg_isready.c:221 +#: pg_isready.c:223 #, c-format msgid "" "%s issues a connection check to a PostgreSQL database.\n" @@ -721,122 +739,127 @@ msgstr "" "%s führt eine Verbindungsprüfung gegen eine PostgreSQL-Datenbank aus.\n" "\n" -#: pg_isready.c:223 +#: pg_isready.c:225 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPTION]...\n" -#: pg_isready.c:226 +#: pg_isready.c:228 #, c-format msgid " -d, --dbname=DBNAME database name\n" msgstr " -d, --dbname=DBNAME Datenbankname\n" -#: pg_isready.c:227 +#: pg_isready.c:229 #, c-format msgid " -q, --quiet run quietly\n" msgstr " -q, --quiet weniger ausgeben\n" -#: pg_isready.c:228 +#: pg_isready.c:230 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: pg_isready.c:229 +#: pg_isready.c:231 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: pg_isready.c:232 +#: pg_isready.c:234 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n" -#: pg_isready.c:233 +#: pg_isready.c:235 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT Port des Datenbankservers\n" -#: pg_isready.c:234 +#: pg_isready.c:236 #, c-format msgid " -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n" msgstr " -t, --timeout=SEK Sekunden auf Verbindung warten, 0 schaltet aus (Vorgabe: %s)\n" -#: pg_isready.c:235 +#: pg_isready.c:237 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=NAME Datenbankbenutzername\n" -#: reindexdb.c:160 +#: reindexdb.c:168 #, c-format -msgid "%s: cannot reindex all databases and a specific one at the same time\n" -msgstr "%s: kann nicht alle Datenbanken und eine bestimmte gleichzeitig reindizieren\n" +msgid "cannot reindex all databases and a specific one at the same time" +msgstr "kann nicht alle Datenbanken und eine bestimmte gleichzeitig reindizieren" -#: reindexdb.c:165 +#: reindexdb.c:173 #, c-format -msgid "%s: cannot reindex all databases and system catalogs at the same time\n" -msgstr "%s: kann nicht alle Datenbanken und Systemkataloge gleichzeitig reindizieren\n" +msgid "cannot reindex all databases and system catalogs at the same time" +msgstr "kann nicht alle Datenbanken und Systemkataloge gleichzeitig reindizieren" -#: reindexdb.c:170 +#: reindexdb.c:178 #, c-format -msgid "%s: cannot reindex specific schema(s) in all databases\n" -msgstr "%s: kann nicht bestimmte Schemas in allen Datenbanken reindizieren\n" +msgid "cannot reindex specific schema(s) in all databases" +msgstr "kann nicht bestimmte Schemas in allen Datenbanken reindizieren" -#: reindexdb.c:175 +#: reindexdb.c:183 #, c-format -msgid "%s: cannot reindex specific table(s) in all databases\n" -msgstr "%s: kann nicht bestimmte Tabelle(n) in allen Datenbanken reindizieren\n" +msgid "cannot reindex specific table(s) in all databases" +msgstr "kann nicht bestimmte Tabelle(n) in allen Datenbanken reindizieren" -#: reindexdb.c:180 +#: reindexdb.c:188 #, c-format -msgid "%s: cannot reindex specific index(es) in all databases\n" -msgstr "%s: kann nicht bestimmte Indexe in allen Datenbanken reindizieren\n" +msgid "cannot reindex specific index(es) in all databases" +msgstr "kann nicht bestimmte Indexe in allen Datenbanken reindizieren" -#: reindexdb.c:191 +#: reindexdb.c:199 #, c-format -msgid "%s: cannot reindex specific schema(s) and system catalogs at the same time\n" -msgstr "%s: kann nicht bestimmte Schemas und Systemkataloge gleichzeitig reindizieren\n" +msgid "cannot reindex specific schema(s) and system catalogs at the same time" +msgstr "kann nicht bestimmte Schemas und Systemkataloge gleichzeitig reindizieren" -#: reindexdb.c:196 +#: reindexdb.c:204 #, c-format -msgid "%s: cannot reindex specific table(s) and system catalogs at the same time\n" -msgstr "%s: kann nicht bestimmte Tabelle(n) und Systemkataloge gleichzeitig reindizieren\n" +msgid "cannot reindex specific table(s) and system catalogs at the same time" +msgstr "kann nicht bestimmte Tabelle(n) und Systemkataloge gleichzeitig reindizieren" -#: reindexdb.c:201 +#: reindexdb.c:209 #, c-format -msgid "%s: cannot reindex specific index(es) and system catalogs at the same time\n" -msgstr "%s: kann nicht bestimmte Index und Systemkataloge gleichzeitig reindizieren\n" +msgid "cannot reindex specific index(es) and system catalogs at the same time" +msgstr "kann nicht bestimmte Indexe und Systemkataloge gleichzeitig reindizieren" -#: reindexdb.c:307 +#: reindexdb.c:298 vacuumdb.c:412 vacuumdb.c:420 vacuumdb.c:427 vacuumdb.c:434 #, c-format -msgid "%s: reindexing of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: Reindizieren der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL %s" +msgstr "Option »%s« kann nicht mit Serverversionen älter als PostgreSQL %s verwendet werden" -#: reindexdb.c:310 +#: reindexdb.c:326 #, c-format -msgid "%s: reindexing of index \"%s\" in database \"%s\" failed: %s" -msgstr "%s: Reindizieren des Index »%s« in Datenbank »%s« fehlgeschlagen: %s" +msgid "reindexing of table \"%s\" in database \"%s\" failed: %s" +msgstr "Reindizieren der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: reindexdb.c:313 +#: reindexdb.c:329 #, c-format -msgid "%s: reindexing of schema \"%s\" in database \"%s\" failed: %s" -msgstr "%s: Reindizieren des Schemas »%s« in Datenbank »%s« fehlgeschlagen: %s" +msgid "reindexing of index \"%s\" in database \"%s\" failed: %s" +msgstr "Reindizieren des Index »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: reindexdb.c:316 +#: reindexdb.c:332 #, c-format -msgid "%s: reindexing of database \"%s\" failed: %s" -msgstr "%s: Reindizieren der Datenbank »%s« fehlgeschlagen: %s" +msgid "reindexing of schema \"%s\" in database \"%s\" failed: %s" +msgstr "Reindizieren des Schemas »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: reindexdb.c:349 +#: reindexdb.c:335 +#, c-format +msgid "reindexing of database \"%s\" failed: %s" +msgstr "Reindizieren der Datenbank »%s« fehlgeschlagen: %s" + +#: reindexdb.c:369 #, c-format msgid "%s: reindexing database \"%s\"\n" msgstr "%s: reindiziere Datenbank »%s«\n" -#: reindexdb.c:388 +#: reindexdb.c:412 #, c-format -msgid "%s: reindexing of system catalogs failed: %s" -msgstr "%s: Reindizieren der Systemkataloge fehlgeschlagen: %s" +msgid "reindexing of system catalogs failed: %s" +msgstr "Reindizieren der Systemkataloge fehlgeschlagen: %s" -#: reindexdb.c:400 +#: reindexdb.c:424 #, c-format msgid "" "%s reindexes a PostgreSQL database.\n" @@ -845,37 +868,42 @@ msgstr "" "%s reindiziert eine PostgreSQL-Datenbank.\n" "\n" -#: reindexdb.c:404 +#: reindexdb.c:428 #, c-format msgid " -a, --all reindex all databases\n" msgstr " -a, --all alle Datenbanken reindizieren\n" -#: reindexdb.c:405 +#: reindexdb.c:429 +#, c-format +msgid " --concurrently reindex concurrently\n" +msgstr " --concurrently nebenläufig reindizieren\n" + +#: reindexdb.c:430 #, c-format msgid " -d, --dbname=DBNAME database to reindex\n" msgstr " -d, --dbname=DBNAME zu reindizierende Datenbank\n" -#: reindexdb.c:407 +#: reindexdb.c:432 #, c-format msgid " -i, --index=INDEX recreate specific index(es) only\n" msgstr " -i, --index=INDEX nur bestimmte(n) Index(e) erneuern\n" -#: reindexdb.c:409 +#: reindexdb.c:434 #, c-format msgid " -s, --system reindex system catalogs\n" msgstr " -s, --system Systemkataloge reindizieren\n" -#: reindexdb.c:410 +#: reindexdb.c:435 #, c-format msgid " -S, --schema=SCHEMA reindex specific schema(s) only\n" msgstr " -S, --schema=SCHEMA nur bestimmte(s) Schema(s) reindizieren\n" -#: reindexdb.c:411 +#: reindexdb.c:436 #, c-format msgid " -t, --table=TABLE reindex specific table(s) only\n" msgstr " -t, --table=TABELLE nur bestimmte Tabelle(n) reindizieren\n" -#: reindexdb.c:422 +#: reindexdb.c:447 #, c-format msgid "" "\n" @@ -885,69 +913,74 @@ msgstr "" "Für weitere Informationen lesen Sie bitte die Beschreibung des\n" "SQL-Befehls REINDEX.\n" -#: vacuumdb.c:195 +#: vacuumdb.c:207 #, c-format -msgid "%s: number of parallel jobs must be at least 1\n" -msgstr "%s: Anzahl paralleler Jobs muss mindestens 1 sein\n" +msgid "number of parallel jobs must be at least 1" +msgstr "Anzahl paralleler Jobs muss mindestens 1 sein" -#: vacuumdb.c:201 +#: vacuumdb.c:212 #, c-format -msgid "%s: too many parallel jobs requested (maximum: %d)\n" -msgstr "%s: zu viele parallele Jobs angefordert (Maximum: %d)\n" +msgid "too many parallel jobs requested (maximum: %d)" +msgstr "zu viele parallele Jobs angefordert (Maximum: %d)" -#: vacuumdb.c:240 vacuumdb.c:246 +#: vacuumdb.c:233 #, c-format -msgid "%s: cannot use the \"%s\" option when performing only analyze\n" -msgstr "%s: kann Option »%s« nicht verwenden, wenn nur Analyze durchgeführt wird\n" +msgid "minimum transaction ID age must be at least 1" +msgstr "minimales Transaktions-ID-Alter muss mindestens 1 sein" -#: vacuumdb.c:263 +#: vacuumdb.c:241 #, c-format -msgid "%s: cannot vacuum all databases and a specific one at the same time\n" -msgstr "%s: kann nicht alle Datenbanken und eine bestimmte gleichzeitig vacuumen\n" +msgid "minimum multixact ID age must be at least 1" +msgstr "minimales Multixact-ID-Alter muss mindestens 1 sein" -#: vacuumdb.c:269 +#: vacuumdb.c:273 vacuumdb.c:279 vacuumdb.c:285 #, c-format -msgid "%s: cannot vacuum specific table(s) in all databases\n" -msgstr "%s: kann nicht bestimmte Tabelle(n) in allen Datenbanken vacuumen\n" +msgid "cannot use the \"%s\" option when performing only analyze" +msgstr "kann Option »%s« nicht verwenden, wenn nur Analyze durchgeführt wird" -#: vacuumdb.c:355 +#: vacuumdb.c:302 +#, c-format +msgid "cannot vacuum all databases and a specific one at the same time" +msgstr "kann nicht alle Datenbanken und eine bestimmte gleichzeitig vacuumen" + +#: vacuumdb.c:307 +#, c-format +msgid "cannot vacuum specific table(s) in all databases" +msgstr "kann nicht bestimmte Tabelle(n) in allen Datenbanken vacuumen" + +#: vacuumdb.c:398 msgid "Generating minimal optimizer statistics (1 target)" msgstr "Erzeuge minimale Optimierer-Statistiken (1 Ziel)" -#: vacuumdb.c:356 +#: vacuumdb.c:399 msgid "Generating medium optimizer statistics (10 targets)" msgstr "Erzeuge mittlere Optimierer-Statistiken (10 Ziele)" -#: vacuumdb.c:357 +#: vacuumdb.c:400 msgid "Generating default (full) optimizer statistics" msgstr "Erzeuge volle Optimierer-Statistiken" -#: vacuumdb.c:369 +#: vacuumdb.c:442 #, c-format msgid "%s: processing database \"%s\": %s\n" msgstr "%s: bearbeite Datenbank »%s«: %s\n" -#: vacuumdb.c:372 +#: vacuumdb.c:445 #, c-format msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: führe Vacuum in Datenbank »%s« aus\n" -#: vacuumdb.c:708 -#, c-format -msgid "%s: vacuuming of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: Vacuum der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" - -#: vacuumdb.c:711 vacuumdb.c:828 +#: vacuumdb.c:942 #, c-format -msgid "%s: vacuuming of database \"%s\" failed: %s" -msgstr "%s: Vacuum der Datenbank »%s« fehlgeschlagen: %s" +msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" +msgstr "Vacuum der Tabelle »%s« in Datenbank »%s« fehlgeschlagen: %s" -#: vacuumdb.c:942 +#: vacuumdb.c:945 vacuumdb.c:1080 #, c-format -msgid "%s: invalid socket: %s" -msgstr "%s: ungültiges Socket: %s" +msgid "vacuuming of database \"%s\" failed: %s" +msgstr "Vacuum der Datenbank »%s« fehlgeschlagen: %s" -#: vacuumdb.c:951 +#: vacuumdb.c:1215 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -956,75 +989,101 @@ msgstr "" "%s säubert und analysiert eine PostgreSQL-Datenbank.\n" "\n" -#: vacuumdb.c:955 +#: vacuumdb.c:1219 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all führe Vacuum in allen Datenbanken aus\n" -#: vacuumdb.c:956 +#: vacuumdb.c:1220 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=DBNAME führe Vacuum in dieser Datenbank aus\n" -#: vacuumdb.c:957 +#: vacuumdb.c:1221 +#, c-format +msgid " --disable-page-skipping disable all page-skipping behavior\n" +msgstr " --disable-page-skipping Page-Skipping-Verhalten abschalten\n" + +#: vacuumdb.c:1222 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr "" " -e, --echo zeige die Befehle, die an den Server\n" " gesendet werden\n" -#: vacuumdb.c:958 +#: vacuumdb.c:1223 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full führe volles Vacuum durch\n" -#: vacuumdb.c:959 +#: vacuumdb.c:1224 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze Zeilentransaktionsinformationen einfrieren\n" -#: vacuumdb.c:960 +#: vacuumdb.c:1225 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr "" " -j, --jobs=NUM so viele parallele Verbindungen zum Vacuum\n" " verwenden\n" -#: vacuumdb.c:961 +#: vacuumdb.c:1226 +#, c-format +msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" +msgstr "" +" --min-mxid-age=MXID-ALTER minimales Multixact-ID-Alter zu bearbeitender\n" +" Tabellen\n" + +#: vacuumdb.c:1227 +#, c-format +msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" +msgstr "" +" --min-xid-age=XID-ALTER minimales Transaktions-ID-Alter zu bearbeitender\n" +" Tabellen\n" + +#: vacuumdb.c:1228 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet unterdrücke alle Mitteilungen\n" -#: vacuumdb.c:962 +#: vacuumdb.c:1229 +#, c-format +msgid " --skip-locked skip relations that cannot be immediately locked\n" +msgstr "" +" --skip-locked Relationen überspringen, die nicht sofort\n" +" gesperrt werden können\n" + +#: vacuumdb.c:1230 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr "" " -t, --table='TABELLE[(SPALTEN)]'\n" " führe Vacuum für bestimmte Tabelle(n) aus\n" -#: vacuumdb.c:963 +#: vacuumdb.c:1231 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose erzeuge viele Meldungen\n" -#: vacuumdb.c:964 +#: vacuumdb.c:1232 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n" -#: vacuumdb.c:965 +#: vacuumdb.c:1233 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze aktualisiere Statistiken für den Optimierer\n" -#: vacuumdb.c:966 +#: vacuumdb.c:1234 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr "" " -Z, --analyze-only aktualisiere nur Statistiken für den Optimierer;\n" " kein Vacuum\n" -#: vacuumdb.c:967 +#: vacuumdb.c:1235 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -1034,12 +1093,12 @@ msgstr "" " in mehreren Phasen für schnellere Ergebnisse;\n" " kein Vacuum\n" -#: vacuumdb.c:969 +#: vacuumdb.c:1237 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n" -#: vacuumdb.c:977 +#: vacuumdb.c:1245 #, c-format msgid "" "\n" diff --git a/src/bin/scripts/po/es.po b/src/bin/scripts/po/es.po index d6e9368d832..e1be74094a7 100644 --- a/src/bin/scripts/po/es.po +++ b/src/bin/scripts/po/es.po @@ -1,6 +1,6 @@ # pgscripts spanish translation # -# Copyright (C) 2003-2013 PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Alvaro Herrera, , 2003-2013 @@ -11,11 +11,11 @@ msgid "" msgstr "" "Project-Id-Version: pgscripts (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:16+0000\n" -"PO-Revision-Date: 2017-07-11 11:26-0500\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:15+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: Castellano \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,6 +23,21 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.0.2\n" +#: ../../../src/common/logging.c:188 +#, c-format +msgid "fatal: " +msgstr "fatal: " + +#: ../../../src/common/logging.c:195 +#, c-format +msgid "error: " +msgstr "error: " + +#: ../../../src/common/logging.c:202 +#, c-format +msgid "warning: " +msgstr "precaución: " + #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 #, c-format @@ -55,73 +70,66 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu fila)" msgstr[1] "(%lu filas)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "Interrumpido\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "No se puede agregar un encabezado al contenido de la tabla: la cantidad de columnas de %d ha sido excedida.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "No se puede agregar una celda al contenido de la tabla: la cantidad de celdas de %d ha sido excedida.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "formato de salida no válido (error interno): %d" -#: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 -#: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 -#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 pg_isready.c:107 -#: reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 vacuumdb.c:232 +#: clusterdb.c:113 clusterdb.c:132 createdb.c:121 createdb.c:140 +#: createuser.c:168 createuser.c:183 dropdb.c:96 dropdb.c:105 dropdb.c:113 +#: dropuser.c:92 dropuser.c:107 dropuser.c:122 pg_isready.c:95 pg_isready.c:109 +#: reindexdb.c:139 reindexdb.c:158 vacuumdb.c:246 vacuumdb.c:265 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Use «%s --help» para mayor información.\n" -#: clusterdb.c:128 createdb.c:136 createuser.c:179 dropdb.c:109 dropuser.c:103 -#: pg_isready.c:105 reindexdb.c:148 vacuumdb.c:230 +#: clusterdb.c:130 createdb.c:138 createuser.c:181 dropdb.c:111 dropuser.c:105 +#: pg_isready.c:107 reindexdb.c:156 vacuumdb.c:263 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: demasiados argumentos (el primero es «%s»)\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)" -#: clusterdb.c:140 +#: clusterdb.c:142 #, c-format -msgid "%s: cannot cluster all databases and a specific one at the same time\n" -msgstr "" -"%s: no se pueden reordenar todas las bases de datos y una de ellas\n" -"en particular simultáneamente\n" +msgid "cannot cluster all databases and a specific one at the same time" +msgstr "no se pueden reordenar todas las bases de datos y una de ellas en particular simultáneamente" -#: clusterdb.c:147 +#: clusterdb.c:148 #, c-format -msgid "%s: cannot cluster specific table(s) in all databases\n" -msgstr "%s: no es posible reordenar tablas específicas en todas las bases de datos\n" +msgid "cannot cluster specific table(s) in all databases" +msgstr "no es posible reordenar tablas específicas en todas las bases de datos" -#: clusterdb.c:212 +#: clusterdb.c:216 #, c-format -msgid "%s: clustering of table \"%s\" in database \"%s\" failed: %s" -msgstr "" -"%s: falló el reordenamiento de la tabla «%s» en\n" -"la base de datos «%s»:\n" -"%s" +msgid "clustering of table \"%s\" in database \"%s\" failed: %s" +msgstr "falló el reordenamiento de la tabla «%s» en la base de datos «%s»: %s" -#: clusterdb.c:215 +#: clusterdb.c:219 #, c-format -msgid "%s: clustering of database \"%s\" failed: %s" -msgstr "" -"%s: falló el reordenamiento de la base de datos «%s»:\n" -"%s" +msgid "clustering of database \"%s\" failed: %s" +msgstr "falló el reordenamiento de la base de datos «%s»: %s" -#: clusterdb.c:248 +#: clusterdb.c:252 #, c-format msgid "%s: clustering database \"%s\"\n" msgstr "%s: reordenando la base de datos «%s»\n" -#: clusterdb.c:269 +#: clusterdb.c:273 #, c-format msgid "" "%s clusters all previously clustered tables in a database.\n" @@ -131,19 +139,19 @@ msgstr "" "en una base de datos.\n" "\n" -#: clusterdb.c:270 createdb.c:252 createuser.c:343 dropdb.c:155 dropuser.c:161 -#: pg_isready.c:222 reindexdb.c:401 vacuumdb.c:952 +#: clusterdb.c:274 createdb.c:250 createuser.c:344 dropdb.c:157 dropuser.c:163 +#: pg_isready.c:224 reindexdb.c:425 vacuumdb.c:1216 #, c-format msgid "Usage:\n" msgstr "Empleo:\n" -#: clusterdb.c:271 reindexdb.c:402 vacuumdb.c:953 +#: clusterdb.c:275 reindexdb.c:426 vacuumdb.c:1217 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [OPCIÓN]... [BASE-DE-DATOS]\n" -#: clusterdb.c:272 createdb.c:254 createuser.c:345 dropdb.c:157 dropuser.c:163 -#: pg_isready.c:225 reindexdb.c:403 vacuumdb.c:954 +#: clusterdb.c:276 createdb.c:252 createuser.c:346 dropdb.c:159 dropuser.c:165 +#: pg_isready.c:227 reindexdb.c:427 vacuumdb.c:1218 #, c-format msgid "" "\n" @@ -152,48 +160,48 @@ msgstr "" "\n" "Opciones:\n" -#: clusterdb.c:273 +#: clusterdb.c:277 #, c-format msgid " -a, --all cluster all databases\n" msgstr " -a, --all reordenar todas las bases de datos\n" -#: clusterdb.c:274 +#: clusterdb.c:278 #, c-format msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=BASE base de datos a reordenar\n" -#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 reindexdb.c:406 +#: clusterdb.c:279 createuser.c:350 dropdb.c:160 dropuser.c:166 reindexdb.c:431 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo mostrar las órdenes a medida que se ejecutan\n" -#: clusterdb.c:276 reindexdb.c:408 +#: clusterdb.c:280 reindexdb.c:433 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet no escribir ningún mensaje\n" -#: clusterdb.c:277 +#: clusterdb.c:281 #, c-format msgid " -t, --table=TABLE cluster specific table(s) only\n" msgstr " -t, --table=TABLA reordenar sólo esta(s) tabla(s)\n" -#: clusterdb.c:278 reindexdb.c:412 +#: clusterdb.c:282 reindexdb.c:437 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose desplegar varios mensajes informativos\n" -#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 reindexdb.c:413 +#: clusterdb.c:283 createuser.c:362 dropdb.c:162 dropuser.c:169 reindexdb.c:438 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 reindexdb.c:414 +#: clusterdb.c:284 createuser.c:367 dropdb.c:164 dropuser.c:171 reindexdb.c:439 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: clusterdb.c:281 createdb.c:265 createuser.c:367 dropdb.c:163 dropuser.c:170 -#: pg_isready.c:231 reindexdb.c:415 vacuumdb.c:970 +#: clusterdb.c:285 createdb.c:263 createuser.c:368 dropdb.c:165 dropuser.c:172 +#: pg_isready.c:233 reindexdb.c:440 vacuumdb.c:1238 #, c-format msgid "" "\n" @@ -202,41 +210,41 @@ msgstr "" "\n" "Opciones de conexión:\n" -#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 reindexdb.c:416 -#: vacuumdb.c:971 +#: clusterdb.c:286 createuser.c:369 dropdb.c:166 dropuser.c:173 reindexdb.c:441 +#: vacuumdb.c:1239 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=ANFITRIÓN nombre del servidor o directorio del socket\n" -#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 reindexdb.c:417 -#: vacuumdb.c:972 +#: clusterdb.c:287 createuser.c:370 dropdb.c:167 dropuser.c:174 reindexdb.c:442 +#: vacuumdb.c:1240 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PUERTO puerto del servidor\n" -#: clusterdb.c:284 dropdb.c:166 reindexdb.c:418 vacuumdb.c:973 +#: clusterdb.c:288 dropdb.c:168 reindexdb.c:443 vacuumdb.c:1241 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=USUARIO nombre de usuario para la conexión\n" -#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 reindexdb.c:419 -#: vacuumdb.c:974 +#: clusterdb.c:289 createuser.c:372 dropdb.c:169 dropuser.c:176 reindexdb.c:444 +#: vacuumdb.c:1242 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password nunca pedir contraseña\n" -#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 reindexdb.c:420 -#: vacuumdb.c:975 +#: clusterdb.c:290 createuser.c:373 dropdb.c:170 dropuser.c:177 reindexdb.c:445 +#: vacuumdb.c:1243 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password forzar la petición de contraseña\n" -#: clusterdb.c:287 dropdb.c:169 reindexdb.c:421 vacuumdb.c:976 +#: clusterdb.c:291 dropdb.c:171 reindexdb.c:446 vacuumdb.c:1244 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=BASE base de datos de mantención alternativa\n" -#: clusterdb.c:288 +#: clusterdb.c:292 #, c-format msgid "" "\n" @@ -245,102 +253,105 @@ msgstr "" "\n" "Lea la descripción de la orden CLUSTER de SQL para obtener mayores detalles.\n" -#: clusterdb.c:289 createdb.c:273 createuser.c:373 dropdb.c:170 dropuser.c:176 -#: pg_isready.c:236 reindexdb.c:423 vacuumdb.c:978 +#: clusterdb.c:293 createdb.c:271 createuser.c:374 dropdb.c:172 dropuser.c:178 +#: pg_isready.c:238 reindexdb.c:448 vacuumdb.c:1246 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" -#: common.c:80 common.c:126 +#: common.c:84 common.c:130 msgid "Password: " msgstr "Contraseña: " -#: common.c:113 +#: common.c:117 #, c-format -msgid "%s: could not connect to database %s: out of memory\n" -msgstr "%s: no se pudo conectar a la base de datos %s: memoria agotada\n" +msgid "could not connect to database %s: out of memory" +msgstr "no se pudo conectar a la base de datos %s: memoria agotada" -#: common.c:140 +#: common.c:144 #, c-format -msgid "%s: could not connect to database %s: %s" -msgstr "%s: no se pudo conectar a la base de datos %s: %s" +msgid "could not connect to database %s: %s" +msgstr "no se pudo conectar a la base de datos %s: %s" -#: common.c:189 common.c:217 +#: common.c:196 common.c:222 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: la consulta falló: %s" +msgid "query failed: %s" +msgstr "la consulta falló: %s" -#: common.c:191 common.c:219 +#: common.c:197 common.c:223 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: la consulta era: %s\n" +msgid "query was: %s" +msgstr "la consulta era: %s" + +#: common.c:339 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "la consulta retornó %d fila en lugar de una: %s" +msgstr[1] "la consulta retornó %d filas en lugar de una: %s" #. translator: abbreviation for "yes" -#: common.c:260 +#: common.c:364 msgid "y" msgstr "s" #. translator: abbreviation for "no" -#: common.c:262 +#: common.c:366 msgid "n" msgstr "n" #. translator: This is a question followed by the translated options for #. "yes" and "no". -#: common.c:272 +#: common.c:376 #, c-format msgid "%s (%s/%s) " msgstr "%s (%s/%s) " -#: common.c:286 +#: common.c:390 #, c-format msgid "Please answer \"%s\" or \"%s\".\n" msgstr "Por favor conteste «%s» o «%s».\n" -#: common.c:365 common.c:402 +#: common.c:469 common.c:506 #, c-format msgid "Cancel request sent\n" msgstr "Petición de cancelación enviada\n" -#: common.c:368 common.c:406 +#: common.c:472 common.c:510 #, c-format msgid "Could not send cancel request: %s" msgstr "No se pudo enviar el paquete de cancelación: %s" -#: createdb.c:146 +#: createdb.c:148 #, c-format -msgid "%s: only one of --locale and --lc-ctype can be specified\n" -msgstr "%s: sólo uno de --locale y --lc-ctype puede ser especificado\n" +msgid "only one of --locale and --lc-ctype can be specified" +msgstr "sólo uno de --locale y --lc-ctype puede ser especificado" -#: createdb.c:152 +#: createdb.c:153 #, c-format -msgid "%s: only one of --locale and --lc-collate can be specified\n" -msgstr "%s: sólo uno de --locale y --lc-collate puede ser especificado\n" +msgid "only one of --locale and --lc-collate can be specified" +msgstr "sólo uno de --locale y --lc-collate puede ser especificado" #: createdb.c:164 #, c-format -msgid "%s: \"%s\" is not a valid encoding name\n" -msgstr "%s: «%s» no es un nombre de codificación válido\n" +msgid "\"%s\" is not a valid encoding name" +msgstr "«%s» no es un nombre válido de codificación" -#: createdb.c:213 +#: createdb.c:212 #, c-format -msgid "%s: database creation failed: %s" -msgstr "" -"%s: falló la creación de la base de datos:\n" -"%s" +msgid "database creation failed: %s" +msgstr "falló la creación de la base de datos: %s" -#: createdb.c:233 +#: createdb.c:231 #, c-format -msgid "%s: comment creation failed (database was created): %s" -msgstr "" -"%s: falló la creación del comentario (la base de datos fue creada):\n" -"%s" +msgid "comment creation failed (database was created): %s" +msgstr "falló la creación del comentario (la base de datos fue creada): %s" -#: createdb.c:251 +#: createdb.c:249 #, c-format msgid "" "%s creates a PostgreSQL database.\n" @@ -349,92 +360,92 @@ msgstr "" "%s crea una base de datos PostgreSQL.\n" "\n" -#: createdb.c:253 +#: createdb.c:251 #, c-format msgid " %s [OPTION]... [DBNAME] [DESCRIPTION]\n" msgstr " %s [OPCIÓN]... [NOMBRE] [DESCRIPCIÓN]\n" -#: createdb.c:255 +#: createdb.c:253 #, c-format msgid " -D, --tablespace=TABLESPACE default tablespace for the database\n" msgstr " -D, --tablespace=TBLSPC tablespace por omisión de la base de datos\n" -#: createdb.c:256 +#: createdb.c:254 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo mostrar las órdenes enviadas al servidor\n" -#: createdb.c:257 +#: createdb.c:255 #, c-format msgid " -E, --encoding=ENCODING encoding for the database\n" msgstr " -E, --encoding=CODIF codificación para la base de datos\n" -#: createdb.c:258 +#: createdb.c:256 #, c-format msgid " -l, --locale=LOCALE locale settings for the database\n" msgstr " -l, --locale=LOCALE configuración regional para la base de datos\n" -#: createdb.c:259 +#: createdb.c:257 #, c-format msgid " --lc-collate=LOCALE LC_COLLATE setting for the database\n" msgstr " --lc-collate=LOCALE configuración LC_COLLATE para la base de datos\n" -#: createdb.c:260 +#: createdb.c:258 #, c-format msgid " --lc-ctype=LOCALE LC_CTYPE setting for the database\n" msgstr " --lc-ctype=LOCALE configuración LC_CTYPE para la base de datos\n" -#: createdb.c:261 +#: createdb.c:259 #, c-format msgid " -O, --owner=OWNER database user to own the new database\n" msgstr " -O, --owner=DUEÑO usuario que será dueño de la base de datos\n" -#: createdb.c:262 +#: createdb.c:260 #, c-format msgid " -T, --template=TEMPLATE template database to copy\n" msgstr " -T, --template=PATRÓN base de datos patrón a copiar\n" -#: createdb.c:263 +#: createdb.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: createdb.c:264 +#: createdb.c:262 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: createdb.c:266 +#: createdb.c:264 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=ANFITRIÓN nombre del servidor o directorio del socket\n" -#: createdb.c:267 +#: createdb.c:265 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PUERTO puerto del servidor\n" -#: createdb.c:268 +#: createdb.c:266 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=USUARIO nombre de usuario para la conexión\n" -#: createdb.c:269 +#: createdb.c:267 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password nunca pedir contraseña\n" -#: createdb.c:270 +#: createdb.c:268 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password forzar la petición de contraseña\n" -#: createdb.c:271 +#: createdb.c:269 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=BASE base de datos de mantención alternativa\n" -#: createdb.c:272 +#: createdb.c:270 #, c-format msgid "" "\n" @@ -444,48 +455,46 @@ msgstr "" "Si no se especifica, se creará una base de datos con el mismo nombre que\n" "el usuario actual.\n" -#: createuser.c:189 +#: createuser.c:191 msgid "Enter name of role to add: " msgstr "Ingrese el nombre del rol a agregar: " -#: createuser.c:206 +#: createuser.c:208 msgid "Enter password for new role: " msgstr "Ingrese la contraseña para el nuevo rol: " -#: createuser.c:208 +#: createuser.c:210 msgid "Enter it again: " msgstr "Ingrésela nuevamente: " -#: createuser.c:211 +#: createuser.c:213 #, c-format msgid "Passwords didn't match.\n" msgstr "Las contraseñas no coinciden.\n" -#: createuser.c:219 +#: createuser.c:221 msgid "Shall the new role be a superuser?" msgstr "¿Será el nuevo rol un superusuario?" -#: createuser.c:234 +#: createuser.c:236 msgid "Shall the new role be allowed to create databases?" msgstr "¿Debe permitírsele al rol la creación de bases de datos?" -#: createuser.c:242 +#: createuser.c:244 msgid "Shall the new role be allowed to create more new roles?" msgstr "¿Debe permitírsele al rol la creación de otros roles?" -#: createuser.c:272 +#: createuser.c:274 #, c-format -msgid "%s: password encryption failed: %s" -msgstr "%s: el cifrado de la contraseña falló: %s" +msgid "password encryption failed: %s" +msgstr "el cifrado de la contraseña falló: %s" -#: createuser.c:327 +#: createuser.c:329 #, c-format -msgid "%s: creation of new role failed: %s" -msgstr "" -"%s: falló la creación del nuevo rol:\n" -"%s" +msgid "creation of new role failed: %s" +msgstr "falló la creación del nuevo rol: %s" -#: createuser.c:342 +#: createuser.c:343 #, c-format msgid "" "%s creates a new PostgreSQL role.\n" @@ -494,34 +503,34 @@ msgstr "" "%s crea un nuevo rol de PostgreSQL.\n" "\n" -#: createuser.c:344 dropuser.c:162 +#: createuser.c:345 dropuser.c:164 #, c-format msgid " %s [OPTION]... [ROLENAME]\n" msgstr " %s [OPCIÓN]... [ROL]\n" -#: createuser.c:346 +#: createuser.c:347 #, c-format msgid " -c, --connection-limit=N connection limit for role (default: no limit)\n" msgstr "" " -c, --connection-limit=N límite de conexiones para el rol\n" " (predeterminado: sin límite)\n" -#: createuser.c:347 +#: createuser.c:348 #, c-format msgid " -d, --createdb role can create new databases\n" msgstr " -d, --createdb el rol podrá crear bases de datos\n" -#: createuser.c:348 +#: createuser.c:349 #, c-format msgid " -D, --no-createdb role cannot create databases (default)\n" msgstr " -D, --no-createdb el rol no podrá crear bases de datos (predeterm.)\n" -#: createuser.c:350 +#: createuser.c:351 #, c-format msgid " -g, --role=ROLE new role will be a member of this role\n" msgstr " -g, --role=ROL el nuevo rol será un miembro de este rol\n" -#: createuser.c:351 +#: createuser.c:352 #, c-format msgid "" " -i, --inherit role inherits privileges of roles it is a\n" @@ -530,47 +539,47 @@ msgstr "" " -i, --inherit el rol heredará los privilegios de los roles de\n" " los cuales es miembro (predeterminado)\n" -#: createuser.c:353 +#: createuser.c:354 #, c-format msgid " -I, --no-inherit role does not inherit privileges\n" msgstr " -I, --no-inherit rol no heredará privilegios\n" -#: createuser.c:354 +#: createuser.c:355 #, c-format msgid " -l, --login role can login (default)\n" msgstr " -l, --login el rol podrá conectarse (predeterminado)\n" -#: createuser.c:355 +#: createuser.c:356 #, c-format msgid " -L, --no-login role cannot login\n" msgstr " -L, --no-login el rol no podrá conectarse\n" -#: createuser.c:356 +#: createuser.c:357 #, c-format msgid " -P, --pwprompt assign a password to new role\n" msgstr " -P, --pwprompt asignar una contraseña al nuevo rol\n" -#: createuser.c:357 +#: createuser.c:358 #, c-format msgid " -r, --createrole role can create new roles\n" msgstr " -r, --createrole el rol podrá crear otros roles\n" -#: createuser.c:358 +#: createuser.c:359 #, c-format msgid " -R, --no-createrole role cannot create roles (default)\n" msgstr " -R, --no-createrole el rol no podrá crear otros roles (predeterminado)\n" -#: createuser.c:359 +#: createuser.c:360 #, c-format msgid " -s, --superuser role will be superuser\n" msgstr " -s, --superuser el rol será un superusuario\n" -#: createuser.c:360 +#: createuser.c:361 #, c-format msgid " -S, --no-superuser role will not be superuser (default)\n" msgstr " -S, --no-superuser el rol no será un superusuario (predeterminado)\n" -#: createuser.c:362 +#: createuser.c:363 #, c-format msgid "" " --interactive prompt for missing role name and attributes rather\n" @@ -579,43 +588,43 @@ msgstr "" " --interactive preguntar los nombres y atributos de rol faltantes\n" " en lugar de asumir los valores por omisión\n" -#: createuser.c:364 +#: createuser.c:365 #, c-format msgid " --replication role can initiate replication\n" msgstr " --replication el rol podrá iniciar replicación\n" -#: createuser.c:365 +#: createuser.c:366 #, c-format msgid " --no-replication role cannot initiate replication\n" msgstr " --no-replication el rol no podrá iniciar replicación\n" -#: createuser.c:370 +#: createuser.c:371 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to create)\n" msgstr "" " -U, --username=NOMBRE nombre de usuario con el cual conectarse\n" " (no el usuario a crear)\n" -#: dropdb.c:102 +#: dropdb.c:104 #, c-format -msgid "%s: missing required argument database name\n" -msgstr "%s: falta el nombre de base de datos requerido\n" +msgid "missing required argument database name" +msgstr "falta el nombre de base de datos requerido" -#: dropdb.c:117 +#: dropdb.c:119 #, c-format msgid "Database \"%s\" will be permanently removed.\n" msgstr "La base de datos «%s» será eliminada permanentemente.\n" -#: dropdb.c:118 dropuser.c:128 +#: dropdb.c:120 dropuser.c:130 msgid "Are you sure?" msgstr "¿Está seguro?" -#: dropdb.c:139 +#: dropdb.c:142 #, c-format -msgid "%s: database removal failed: %s" -msgstr "%s: falló la eliminación de la base de datos: %s" +msgid "database removal failed: %s" +msgstr "falló la eliminación de la base de datos: %s" -#: dropdb.c:154 +#: dropdb.c:156 #, c-format msgid "" "%s removes a PostgreSQL database.\n" @@ -624,43 +633,41 @@ msgstr "" "%s elimina una base de datos de PostgreSQL.\n" "\n" -#: dropdb.c:156 +#: dropdb.c:158 #, c-format msgid " %s [OPTION]... DBNAME\n" msgstr " %s [OPCIÓN]... BASE-DE-DATOS\n" -#: dropdb.c:159 +#: dropdb.c:161 #, c-format msgid " -i, --interactive prompt before deleting anything\n" msgstr " -i, --interactive preguntar antes de eliminar\n" -#: dropdb.c:161 +#: dropdb.c:163 #, c-format msgid " --if-exists don't report error if database doesn't exist\n" msgstr " --if-exists no reportar error si la base de datos no existe\n" -#: dropuser.c:113 +#: dropuser.c:115 msgid "Enter name of role to drop: " msgstr "Ingrese el nombre del rol a eliminar: " -#: dropuser.c:119 +#: dropuser.c:121 #, c-format -msgid "%s: missing required argument role name\n" -msgstr "%s: falta el nombre de rol requerido\n" +msgid "missing required argument role name" +msgstr "falta el nombre de rol requerido" -#: dropuser.c:127 +#: dropuser.c:129 #, c-format msgid "Role \"%s\" will be permanently removed.\n" msgstr "El rol «%s» será eliminado permanentemente.\n" -#: dropuser.c:145 +#: dropuser.c:147 #, c-format -msgid "%s: removal of role \"%s\" failed: %s" -msgstr "" -"%s: falló la eliminación del rol «%s»:\n" -"%s" +msgid "removal of role \"%s\" failed: %s" +msgstr "falló la eliminación del rol «%s»: %s" -#: dropuser.c:160 +#: dropuser.c:162 #, c-format msgid "" "%s removes a PostgreSQL role.\n" @@ -669,7 +676,7 @@ msgstr "" "%s elimina un rol de PostgreSQL.\n" "\n" -#: dropuser.c:165 +#: dropuser.c:167 #, c-format msgid "" " -i, --interactive prompt before deleting anything, and prompt for\n" @@ -678,54 +685,54 @@ msgstr "" " -i, --interactive preguntar antes de eliminar cualquier cosa, y\n" " preguntar el nombre de rol si no se especifica\n" -#: dropuser.c:168 +#: dropuser.c:170 #, c-format msgid " --if-exists don't report error if user doesn't exist\n" msgstr " --if-exists no reportar error si el usuario no existe\n" -#: dropuser.c:173 +#: dropuser.c:175 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to drop)\n" msgstr "" " -U, --username=USUARIO nombre del usuario con el cual conectarse\n" " (no el usuario a eliminar)\n" -#: pg_isready.c:142 +#: pg_isready.c:144 #, c-format -msgid "%s: %s" -msgstr "%s: %s" +msgid "%s" +msgstr "%s" -#: pg_isready.c:150 +#: pg_isready.c:152 #, c-format -msgid "%s: could not fetch default options\n" -msgstr "%s: no se pudo extraer las opciones por omisión\n" +msgid "could not fetch default options" +msgstr "no se pudo extraer las opciones por omisión" -#: pg_isready.c:199 +#: pg_isready.c:201 #, c-format msgid "accepting connections\n" msgstr "aceptando conexiones\n" -#: pg_isready.c:202 +#: pg_isready.c:204 #, c-format msgid "rejecting connections\n" msgstr "rechazando conexiones\n" -#: pg_isready.c:205 +#: pg_isready.c:207 #, c-format msgid "no response\n" msgstr "sin respuesta\n" -#: pg_isready.c:208 +#: pg_isready.c:210 #, c-format msgid "no attempt\n" msgstr "sin intentos\n" -#: pg_isready.c:211 +#: pg_isready.c:213 #, c-format msgid "unknown\n" msgstr "desconocido\n" -#: pg_isready.c:221 +#: pg_isready.c:223 #, c-format msgid "" "%s issues a connection check to a PostgreSQL database.\n" @@ -734,134 +741,129 @@ msgstr "" "%s emite una prueba de conexión a una base de datos PostgreSQL.\n" "\n" -#: pg_isready.c:223 +#: pg_isready.c:225 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [OPCIÓN]...\n" -#: pg_isready.c:226 +#: pg_isready.c:228 #, c-format msgid " -d, --dbname=DBNAME database name\n" msgstr " -d, --dbname=DBNAME nombre de la base de datos\n" -#: pg_isready.c:227 +#: pg_isready.c:229 #, c-format msgid " -q, --quiet run quietly\n" msgstr " -q, --quiet ejecutar de forma silenciosa\n" -#: pg_isready.c:228 +#: pg_isready.c:230 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: pg_isready.c:229 +#: pg_isready.c:231 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: pg_isready.c:232 +#: pg_isready.c:234 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=ANFITRIÓN nombre del servidor o directorio del socket\n" -#: pg_isready.c:233 +#: pg_isready.c:235 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PUERTO puerto del servidor\n" -#: pg_isready.c:234 +#: pg_isready.c:236 #, c-format msgid " -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n" msgstr "" " -t, --timeout=SEGUNDOS segundos a esperar al intentar conectarse\n" " 0 lo deshabilita (por omisión: %s)\n" -#: pg_isready.c:235 +#: pg_isready.c:237 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=USUARIO nombre de usuario para la conexión\n" -#: reindexdb.c:160 +#: reindexdb.c:168 #, c-format -msgid "%s: cannot reindex all databases and a specific one at the same time\n" -msgstr "" -"%s: no se pueden reindexar todas las bases de datos y una de ellas\n" -"en particular simultáneamente\n" +msgid "cannot reindex all databases and a specific one at the same time" +msgstr "no se pueden reindexar todas las bases de datos y una de ellas en particular simultáneamente" -#: reindexdb.c:165 +#: reindexdb.c:173 #, c-format -msgid "%s: cannot reindex all databases and system catalogs at the same time\n" -msgstr "" -"%s: no se pueden reindexar todas las bases de datos y los catálogos\n" -"del sistema simultáneamente\n" +msgid "cannot reindex all databases and system catalogs at the same time" +msgstr "no se pueden reindexar todas las bases de datos y los catálogos del sistema simultáneamente" -#: reindexdb.c:170 +#: reindexdb.c:178 #, c-format -msgid "%s: cannot reindex specific schema(s) in all databases\n" -msgstr "%s: no es posible reindexar esquemas específicos en todas las bases de datos\n" +msgid "cannot reindex specific schema(s) in all databases" +msgstr "no es posible reindexar esquemas específicos en todas las bases de datos" -#: reindexdb.c:175 +#: reindexdb.c:183 #, c-format -msgid "%s: cannot reindex specific table(s) in all databases\n" -msgstr "%s: no es posible reindexar tablas específicas en todas las bases de datos\n" +msgid "cannot reindex specific table(s) in all databases" +msgstr "no es posible reindexar tablas específicas en todas las bases de datos" -#: reindexdb.c:180 +#: reindexdb.c:188 #, c-format -msgid "%s: cannot reindex specific index(es) in all databases\n" -msgstr "%s: no es posible reindexar índices específicos en todas las bases de datos\n" +msgid "cannot reindex specific index(es) in all databases" +msgstr "no es posible reindexar índices específicos en todas las bases de datos" -#: reindexdb.c:191 +#: reindexdb.c:199 #, c-format -msgid "%s: cannot reindex specific schema(s) and system catalogs at the same time\n" -msgstr "" -"%s: no es posible reindexar esquemas específicos y los catálogos\n" -"del sistema simultáneamente\n" +msgid "cannot reindex specific schema(s) and system catalogs at the same time" +msgstr "no es posible reindexar esquemas específicos y los catálogos del sistema simultáneamente" -#: reindexdb.c:196 +#: reindexdb.c:204 #, c-format -msgid "%s: cannot reindex specific table(s) and system catalogs at the same time\n" -msgstr "" -"%s: no es posible reindexar tablas específicas y los catálogos\n" -"del sistema simultáneamente\n" +msgid "cannot reindex specific table(s) and system catalogs at the same time" +msgstr "no es posible reindexar tablas específicas y los catálogos del sistema simultáneamente" -#: reindexdb.c:201 +#: reindexdb.c:209 #, c-format -msgid "%s: cannot reindex specific index(es) and system catalogs at the same time\n" -msgstr "" -"%s: no es posible reindexar índices específicos y los catálogos\n" -"del sistema simultáneamente\n" +msgid "cannot reindex specific index(es) and system catalogs at the same time" +msgstr "no es posible reindexar índices específicos y los catálogos del sistema simultáneamente" -#: reindexdb.c:307 +#: reindexdb.c:298 vacuumdb.c:412 vacuumdb.c:420 vacuumdb.c:427 vacuumdb.c:434 #, c-format -msgid "%s: reindexing of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: falló la reindexación de la tabla «%s» en la base de datos «%s»: %s" +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL %s" +msgstr "no se puede usar la opción «%s» cuando con versiones más antiguas que PostgreSQL %s" -#: reindexdb.c:310 +#: reindexdb.c:326 #, c-format -msgid "%s: reindexing of index \"%s\" in database \"%s\" failed: %s" -msgstr "%s: falló la reindexación del índice «%s» en la base de datos «%s»: %s" +msgid "reindexing of table \"%s\" in database \"%s\" failed: %s" +msgstr "falló la reindexación de la tabla «%s» en la base de datos «%s»: %s" -#: reindexdb.c:313 +#: reindexdb.c:329 #, c-format -msgid "%s: reindexing of schema \"%s\" in database \"%s\" failed: %s" -msgstr "%s: falló la reindexación del esquema «%s» en la base de datos «%s»: %s" +msgid "reindexing of index \"%s\" in database \"%s\" failed: %s" +msgstr "falló la reindexación del índice «%s» en la base de datos «%s»: %s" -#: reindexdb.c:316 +#: reindexdb.c:332 #, c-format -msgid "%s: reindexing of database \"%s\" failed: %s" -msgstr "%s: falló la reindexación de la base de datos «%s»: %s" +msgid "reindexing of schema \"%s\" in database \"%s\" failed: %s" +msgstr "falló la reindexación del esquema «%s» en la base de datos «%s»: %s" -#: reindexdb.c:349 +#: reindexdb.c:335 +#, c-format +msgid "reindexing of database \"%s\" failed: %s" +msgstr "falló la reindexación de la base de datos «%s»: %s" + +#: reindexdb.c:369 #, c-format msgid "%s: reindexing database \"%s\"\n" msgstr "%s: reindexando la base de datos «%s»\n" -#: reindexdb.c:388 +#: reindexdb.c:412 #, c-format -msgid "%s: reindexing of system catalogs failed: %s" -msgstr "%s: falló la reindexación de los catálogos del sistema: %s" +msgid "reindexing of system catalogs failed: %s" +msgstr "falló la reindexación de los catálogos del sistema: %s" -#: reindexdb.c:400 +#: reindexdb.c:424 #, c-format msgid "" "%s reindexes a PostgreSQL database.\n" @@ -870,37 +872,42 @@ msgstr "" "%s reindexa una base de datos PostgreSQL.\n" "\n" -#: reindexdb.c:404 +#: reindexdb.c:428 #, c-format msgid " -a, --all reindex all databases\n" msgstr " -a, --all reindexar todas las bases de datos\n" -#: reindexdb.c:405 +#: reindexdb.c:429 +#, c-format +msgid " --concurrently reindex concurrently\n" +msgstr " --concurrently reindexar en modo concurrente\n" + +#: reindexdb.c:430 #, c-format msgid " -d, --dbname=DBNAME database to reindex\n" msgstr " -d, --dbname=DBNAME base de datos a reindexar\n" -#: reindexdb.c:407 +#: reindexdb.c:432 #, c-format msgid " -i, --index=INDEX recreate specific index(es) only\n" msgstr " -i, --index=INDEX recrear sólo este o estos índice(s)\n" -#: reindexdb.c:409 +#: reindexdb.c:434 #, c-format msgid " -s, --system reindex system catalogs\n" msgstr " -s, --system reindexa los catálogos del sistema\n" -#: reindexdb.c:410 +#: reindexdb.c:435 #, c-format msgid " -S, --schema=SCHEMA reindex specific schema(s) only\n" msgstr " -S, --schema=ESQUEMA reindexar sólo este o estos esquemas\n" -#: reindexdb.c:411 +#: reindexdb.c:436 #, c-format msgid " -t, --table=TABLE reindex specific table(s) only\n" msgstr " -t, --table=TABLE reindexar sólo esta(s) tabla(s)\n" -#: reindexdb.c:422 +#: reindexdb.c:447 #, c-format msgid "" "\n" @@ -909,79 +916,74 @@ msgstr "" "\n" "Lea la descripción de la orden REINDEX de SQL para obtener mayores detalles.\n" -#: vacuumdb.c:195 +#: vacuumdb.c:207 #, c-format -msgid "%s: number of parallel jobs must be at least 1\n" -msgstr "%s: número de trabajos en paralelo debe ser al menos 1\n" +msgid "number of parallel jobs must be at least 1" +msgstr "número de trabajos en paralelo debe ser al menos 1" -#: vacuumdb.c:201 +#: vacuumdb.c:212 #, c-format -msgid "%s: too many parallel jobs requested (maximum: %d)\n" -msgstr "%s: demasiados trabajos paralelos solicitados (máximo: %d)\n" +msgid "too many parallel jobs requested (maximum: %d)" +msgstr "demasiados trabajos paralelos solicitados (máximo: %d)" -#: vacuumdb.c:240 vacuumdb.c:246 +#: vacuumdb.c:233 #, c-format -msgid "%s: cannot use the \"%s\" option when performing only analyze\n" -msgstr "" -"%s: no se puede usar la opción «%s» cuando se está sólo\n" -"actualizando estadísticas\n" +msgid "minimum transaction ID age must be at least 1" +msgstr "edad mínima del ID de transacción debe ser al menos 1" -#: vacuumdb.c:263 +#: vacuumdb.c:241 #, c-format -msgid "%s: cannot vacuum all databases and a specific one at the same time\n" -msgstr "" -"%s: no se pueden limpiar todas las bases de datos y una de ellas\n" -"en particular simultáneamente\n" +msgid "minimum multixact ID age must be at least 1" +msgstr "edad mínima del ID de multixact debe ser al menos 1" -#: vacuumdb.c:269 +#: vacuumdb.c:273 vacuumdb.c:279 vacuumdb.c:285 #, c-format -msgid "%s: cannot vacuum specific table(s) in all databases\n" -msgstr "" -"%s: no es posible limpiar tablas específicas en todas\n" -"las bases de datos\n" +msgid "cannot use the \"%s\" option when performing only analyze" +msgstr "no se puede usar la opción «%s» cuando se está sólo actualizando estadísticas" + +#: vacuumdb.c:302 +#, c-format +msgid "cannot vacuum all databases and a specific one at the same time" +msgstr "no se pueden limpiar todas las bases de datos y una de ellas en particular simultáneamente" -#: vacuumdb.c:355 +#: vacuumdb.c:307 +#, c-format +msgid "cannot vacuum specific table(s) in all databases" +msgstr "no es posible limpiar tablas específicas en todas las bases de datos" + +#: vacuumdb.c:398 msgid "Generating minimal optimizer statistics (1 target)" msgstr "Generando estadísticas mínimas para el optimizador (tamaño = 1)" -#: vacuumdb.c:356 +#: vacuumdb.c:399 msgid "Generating medium optimizer statistics (10 targets)" msgstr "Generando estadísticas medias para el optimizador (tamaño = 10)" -#: vacuumdb.c:357 +#: vacuumdb.c:400 msgid "Generating default (full) optimizer statistics" msgstr "Generando estadísticas predeterminadas (completas) para el optimizador" -#: vacuumdb.c:369 +#: vacuumdb.c:442 #, c-format msgid "%s: processing database \"%s\": %s\n" msgstr "%s: procesando la base de datos «%s»: %s\n" -#: vacuumdb.c:372 +#: vacuumdb.c:445 #, c-format msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: limpiando la base de datos «%s»\n" -#: vacuumdb.c:708 -#, c-format -msgid "%s: vacuuming of table \"%s\" in database \"%s\" failed: %s" -msgstr "" -"%s: falló la limpieza de la tabla «%s» en la base de datos «%s»:\n" -"%s" - -#: vacuumdb.c:711 vacuumdb.c:828 +#: vacuumdb.c:942 #, c-format -msgid "%s: vacuuming of database \"%s\" failed: %s" -msgstr "" -"%s: falló la limpieza de la base de datos «%s»:\n" -"%s" +msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" +msgstr "falló la limpieza de la tabla «%s» en la base de datos «%s»: %s" -#: vacuumdb.c:942 +#: vacuumdb.c:945 vacuumdb.c:1080 #, c-format -msgid "%s: invalid socket: %s" -msgstr "%s: el socket no es válido: %s" +msgid "vacuuming of database \"%s\" failed: %s" +msgstr "falló la limpieza de la base de datos «%s»: %s" -#: vacuumdb.c:951 +#: vacuumdb.c:1215 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -990,71 +992,91 @@ msgstr "" "%s limpia (VACUUM) y analiza una base de datos PostgreSQL.\n" "\n" -#: vacuumdb.c:955 +#: vacuumdb.c:1219 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all limpia todas las bases de datos\n" -#: vacuumdb.c:956 +#: vacuumdb.c:1220 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=BASE base de datos a limpiar\n" -#: vacuumdb.c:957 +#: vacuumdb.c:1221 +#, c-format +msgid " --disable-page-skipping disable all page-skipping behavior\n" +msgstr " --disable-page-skipping desactiva todo comportamiento de saltar páginas\n" + +#: vacuumdb.c:1222 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo mostrar las órdenes enviadas al servidor\n" -#: vacuumdb.c:958 +#: vacuumdb.c:1223 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full usar «vacuum full»\n" -#: vacuumdb.c:959 +#: vacuumdb.c:1224 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze usar «vacuum freeze»\n" -#: vacuumdb.c:960 +#: vacuumdb.c:1225 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr " -j, --jobs=NUM usar esta cantidad de conexiones concurrentes\n" -#: vacuumdb.c:961 +#: vacuumdb.c:1226 +#, c-format +msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" +msgstr " --min-mxid-age=EDAD_MXID edad de multixact ID mínima de tablas a limpiar\n" + +#: vacuumdb.c:1227 +#, c-format +msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" +msgstr " --min-xid-age=EDAD_XID edad de ID de transacción mínima de tablas a limpiar\n" + +#: vacuumdb.c:1228 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet no desplegar mensajes\n" -#: vacuumdb.c:962 +#: vacuumdb.c:1229 +#, c-format +msgid " --skip-locked skip relations that cannot be immediately locked\n" +msgstr " --skip-locked ignorar relaciones que no pueden bloquearse inmediatamente\n" + +#: vacuumdb.c:1230 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr "" " -t, --table='TABLA[(COLUMNAS)]'\n" " limpiar sólo esta(s) tabla(s)\n" -#: vacuumdb.c:963 +#: vacuumdb.c:1231 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose desplegar varios mensajes informativos\n" -#: vacuumdb.c:964 +#: vacuumdb.c:1232 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostrar información de versión y salir\n" -#: vacuumdb.c:965 +#: vacuumdb.c:1233 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze actualizar las estadísticas del optimizador\n" -#: vacuumdb.c:966 +#: vacuumdb.c:1234 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr "" " -Z, --analyze-only sólo actualizar las estadísticas del optimizador;\n" " no hacer vacuum\n" -#: vacuumdb.c:967 +#: vacuumdb.c:1235 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -1064,12 +1086,12 @@ msgstr "" " en múltiples etapas para resultados más rápidos;\n" " no hacer vacuum\n" -#: vacuumdb.c:969 +#: vacuumdb.c:1237 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostrar esta ayuda y salir\n" -#: vacuumdb.c:977 +#: vacuumdb.c:1245 #, c-format msgid "" "\n" @@ -1077,69 +1099,3 @@ msgid "" msgstr "" "\n" "Lea la descripción de la orden VACUUM de SQL para obtener mayores detalles.\n" - -#~ msgid "Name" -#~ msgstr "Nombre" - -#~ msgid "no" -#~ msgstr "no" - -#~ msgid "yes" -#~ msgstr "sí" - -#~ msgid "Trusted?" -#~ msgstr "Confiable?" - -#~ msgid "Procedural Languages" -#~ msgstr "Lenguajes Procedurales" - -#~ msgid "%s: missing required argument language name\n" -#~ msgstr "%s: falta el nombre de lenguaje requerido\n" - -#~ msgid "%s: language \"%s\" is already installed in database \"%s\"\n" -#~ msgstr "%s: el lenguaje «%s» ya está instalado en la base de datos «%s»\n" - -#~ msgid "%s: language installation failed: %s" -#~ msgstr "" -#~ "%s: falló la instalación del lenguaje:\n" -#~ "%s" - -#~ msgid "" -#~ "%s installs a procedural language into a PostgreSQL database.\n" -#~ "\n" -#~ msgstr "" -#~ "%s instala un lenguaje procedural en una base de datos PostgreSQL.\n" -#~ "\n" - -#~ msgid " %s [OPTION]... LANGNAME [DBNAME]\n" -#~ msgstr " %s [OPCIÓN]... LENGUAJE [BASE-DE-DATOS]\n" - -#~ msgid " -d, --dbname=DBNAME database to install language in\n" -#~ msgstr " -d, --dbname=BASE base de datos en que instalar el lenguaje\n" - -#~ msgid " -l, --list show a list of currently installed languages\n" -#~ msgstr " -l, --list listar los lenguajes instalados actualmente\n" - -#~ msgid " -E, --encrypted encrypt stored password\n" -#~ msgstr " -E, --encrypted almacenar la constraseña cifrada\n" - -#~ msgid " -N, --unencrypted do not encrypt stored password\n" -#~ msgstr " -N, --unencrypted almacenar la contraseña sin cifrar\n" - -#~ msgid "%s: language \"%s\" is not installed in database \"%s\"\n" -#~ msgstr "%s: el lenguaje «%s» no está instalado en la base de datos «%s»\n" - -#~ msgid "%s: language removal failed: %s" -#~ msgstr "%s: falló la eliminación del lenguaje: %s" - -#~ msgid "" -#~ "%s removes a procedural language from a database.\n" -#~ "\n" -#~ msgstr "" -#~ "%s elimina un lenguaje procedural de una base de datos.\n" -#~ "\n" - -#~ msgid " -d, --dbname=DBNAME database from which to remove the language\n" -#~ msgstr "" -#~ " -d, --dbname=BASE nombre de la base de datos de la cual\n" -#~ " eliminar el lenguaje\n" diff --git a/src/bin/scripts/po/it.po b/src/bin/scripts/po/it.po index 5aab660ebfb..6edbb273033 100644 --- a/src/bin/scripts/po/it.po +++ b/src/bin/scripts/po/it.po @@ -1,28 +1,20 @@ # -# Translation of pgscripts to Italian -# PostgreSQL Project +# pgscripts.po +# Italian message translation file for pgscripts # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Emanuele Zamprogno -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Diego Cinelli +# Daniele Varrazzo , 2012-2017. +# Emanuele Zamprogno , 2009. +# Mirko Tebaldi , 2004. +# Fabrizio Mazzoni , 2003. # -# Traduttori precedenti: -# * Primo traduttore: Fabrizio Mazzoni , 2003. -# * Secondo traduttore: Mirko Tebaldi , 2004. +# This file is distributed under the same license as the PostgreSQL package. # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project -# -# Italian message translation file for pgscripts -# Primo traduttore: Fabrizio Mazzoni , 2003. -# Secondo traduttore: Mirko Tebaldi , 2004. -# Attuale traduttore: Emanuele Zamprogno , 2009. msgid "" msgstr "" "Project-Id-Version: pgscripts (PostgreSQL) 10\n" @@ -30,7 +22,7 @@ msgstr "" "POT-Creation-Date: 2017-05-22 07:46+0000\n" "PO-Revision-Date: 2017-05-29 17:28+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -93,8 +85,9 @@ msgstr "formato di output non valido (errore interno): %d" #: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 #: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 -#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 pg_isready.c:107 -#: reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 vacuumdb.c:232 +#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 +#: pg_isready.c:107 reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 +#: vacuumdb.c:232 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" @@ -170,7 +163,8 @@ msgstr " -a, --all raggruppa tutti i database\n" msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=NOMEDB database da raggruppare\n" -#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 reindexdb.c:406 +#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 +#: reindexdb.c:406 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo mostra i comandi inviati al server\n" @@ -190,12 +184,14 @@ msgstr " -t, --table=TABELLA raggruppa solo le tabelle specificate\n" msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose mostra un output completo\n" -#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 reindexdb.c:413 +#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 +#: reindexdb.c:413 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version mostra informazioni sulla versione ed esci\n" -#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 reindexdb.c:414 +#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 +#: reindexdb.c:414 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help mostra questo aiuto ed esci\n" @@ -210,14 +206,14 @@ msgstr "" "\n" "Opzioni di connessione:\n" -#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 reindexdb.c:416 -#: vacuumdb.c:971 +#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 +#: reindexdb.c:416 vacuumdb.c:971 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=HOSTNAME host del server database o directory socket\n" -#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 reindexdb.c:417 -#: vacuumdb.c:972 +#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 +#: reindexdb.c:417 vacuumdb.c:972 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORTA porta del server database\n" @@ -227,14 +223,14 @@ msgstr " -p, --port=PORTA porta del server database\n" msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=UTENTE nome utente da utilizzare per la connessione\n" -#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 reindexdb.c:419 -#: vacuumdb.c:974 +#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 +#: reindexdb.c:419 vacuumdb.c:974 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password non richiedere mai una password\n" -#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 reindexdb.c:420 -#: vacuumdb.c:975 +#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 +#: reindexdb.c:420 vacuumdb.c:975 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password forza la richiesta di una password\n" diff --git a/src/bin/scripts/po/ko.po b/src/bin/scripts/po/ko.po index a688749d04d..af878688281 100644 --- a/src/bin/scripts/po/ko.po +++ b/src/bin/scripts/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: pgscripts (PostgreSQL 9.6)\n" +"Project-Id-Version: pgscripts (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 19:04+0900\n" +"POT-Creation-Date: 2017-08-16 10:59+0900\n" +"PO-Revision-Date: 2017-08-16 17:45+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -26,59 +26,57 @@ msgstr "메모리 부족\n" msgid "cannot duplicate null pointer (internal error)\n" msgstr "null í¬ì¸í„°ë¥¼ 복제할 수 ì—†ìŒ(ë‚´ë¶€ 오류)\n" -#: ../../common/username.c:45 +#: ../../common/username.c:43 #, c-format msgid "could not look up effective user ID %ld: %s" msgstr "UID %ld 해당하는 사용ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s" -#: ../../common/username.c:47 +#: ../../common/username.c:45 msgid "user does not exist" msgstr "ì‚¬ìš©ìž ì—†ìŒ" -#: ../../common/username.c:62 +#: ../../common/username.c:60 #, c-format msgid "user name lookup failure: error code %lu" msgstr "ì‚¬ìš©ìž ì´ë¦„ 찾기 실패: 오류번호 %lu" -#: ../../fe_utils/print.c:354 +#: ../../fe_utils/print.c:353 #, c-format msgid "(%lu row)" msgid_plural "(%lu rows)" msgstr[0] "(%luê°œ í–‰)" -#: ../../fe_utils/print.c:2906 +#: ../../fe_utils/print.c:2913 #, c-format msgid "Interrupted\n" msgstr "ì¸íŠ¸ëŸ½íŠ¸ë°œìƒ\n" -#: ../../fe_utils/print.c:2970 +#: ../../fe_utils/print.c:2977 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "í…Œì´ë¸” ë‚´ìš©ì— í—¤ë”를 추가할 수 ì—†ìŒ: ì—´ 수가 %d개를 초과했습니다.\n" -#: ../../fe_utils/print.c:3010 +#: ../../fe_utils/print.c:3017 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "í…Œì´ë¸” ë‚´ìš©ì— ì…€ì„ ì¶”ê°€í•  수 ì—†ìŒ: ì´ ì…€ 수가 %d개를 초과했습니다.\n" -#: ../../fe_utils/print.c:3259 +#: ../../fe_utils/print.c:3266 #, c-format msgid "invalid output format (internal error): %d" msgstr "ìž˜ëª»ëœ ì¶œë ¥ í˜•ì‹ (ë‚´ë¶€ 오류): %d" #: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 -#: createlang.c:89 createlang.c:119 createlang.c:174 createuser.c:169 -#: createuser.c:184 dropdb.c:94 dropdb.c:103 dropdb.c:111 droplang.c:88 -#: droplang.c:118 droplang.c:174 dropuser.c:89 dropuser.c:104 dropuser.c:115 -#: pg_isready.c:93 pg_isready.c:107 reindexdb.c:131 reindexdb.c:150 -#: vacuumdb.c:207 vacuumdb.c:226 +#: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 +#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 +#: pg_isready.c:107 reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 +#: vacuumdb.c:232 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "보다 ìžì„¸í•œ ì‚¬ìš©ë²•ì€ \"%s --help\"\n" -#: clusterdb.c:128 createdb.c:136 createlang.c:117 createuser.c:182 -#: dropdb.c:109 droplang.c:116 dropuser.c:102 pg_isready.c:105 reindexdb.c:148 -#: vacuumdb.c:224 +#: clusterdb.c:128 createdb.c:136 createuser.c:179 dropdb.c:109 dropuser.c:103 +#: pg_isready.c:105 reindexdb.c:148 vacuumdb.c:230 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" msgstr "%s: 너무 ë§Žì€ ëª…ë ¹í–‰ ì¸ìˆ˜ë“¤ (시작 \"%s\")\n" @@ -118,21 +116,19 @@ msgstr "" "다시 í´ëŸ¬ìŠ¤í„° ìž‘ì—…ì„ í•©ë‹ˆë‹¤.\n" "\n" -#: clusterdb.c:270 createdb.c:252 createlang.c:236 createuser.c:349 -#: dropdb.c:155 droplang.c:237 dropuser.c:156 pg_isready.c:222 reindexdb.c:401 -#: vacuumdb.c:942 +#: clusterdb.c:270 createdb.c:252 createuser.c:343 dropdb.c:155 dropuser.c:161 +#: pg_isready.c:222 reindexdb.c:401 vacuumdb.c:952 #, c-format msgid "Usage:\n" msgstr "사용법:\n" -#: clusterdb.c:271 reindexdb.c:402 vacuumdb.c:943 +#: clusterdb.c:271 reindexdb.c:402 vacuumdb.c:953 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [옵션]... [DBì´ë¦„]\n" -#: clusterdb.c:272 createdb.c:254 createlang.c:238 createuser.c:351 -#: dropdb.c:157 droplang.c:239 dropuser.c:158 pg_isready.c:225 reindexdb.c:403 -#: vacuumdb.c:944 +#: clusterdb.c:272 createdb.c:254 createuser.c:345 dropdb.c:157 dropuser.c:163 +#: pg_isready.c:225 reindexdb.c:403 vacuumdb.c:954 #, c-format msgid "" "\n" @@ -151,8 +147,8 @@ msgstr " -a, --all 모든 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 대ìƒìœ¼ë¡œ\n" msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=DBNAME í´ëŸ¬ìŠ¤í„° 작업할 DB\n" -#: clusterdb.c:275 createlang.c:240 createuser.c:355 dropdb.c:158 -#: droplang.c:241 dropuser.c:159 reindexdb.c:406 +#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 +#: reindexdb.c:406 #, c-format msgid "" " -e, --echo show the commands being sent to the server\n" @@ -173,21 +169,20 @@ msgstr " -t, --table=TABLE 지정한 í…Œì´ë¸”들만 í´ëŸ¬ìŠ¤í„°\n" msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose ë§Žì€ ì¶œë ¥ 작성\n" -#: clusterdb.c:279 createlang.c:242 createuser.c:369 dropdb.c:160 -#: droplang.c:243 dropuser.c:162 reindexdb.c:413 +#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 +#: reindexdb.c:413 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: clusterdb.c:280 createlang.c:243 createuser.c:374 dropdb.c:162 -#: droplang.c:244 dropuser.c:164 reindexdb.c:414 +#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 +#: reindexdb.c:414 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 보여주고 마침\n" -#: clusterdb.c:281 createdb.c:265 createlang.c:244 createuser.c:375 -#: dropdb.c:163 droplang.c:245 dropuser.c:165 pg_isready.c:231 reindexdb.c:415 -#: vacuumdb.c:960 +#: clusterdb.c:281 createdb.c:265 createuser.c:367 dropdb.c:163 dropuser.c:170 +#: pg_isready.c:231 reindexdb.c:415 vacuumdb.c:970 #, c-format msgid "" "\n" @@ -196,38 +191,37 @@ msgstr "" "\n" "ì—°ê²° 옵션들:\n" -#: clusterdb.c:282 createlang.c:245 createuser.c:376 dropdb.c:164 -#: droplang.c:246 dropuser.c:166 reindexdb.c:416 vacuumdb.c:961 +#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 +#: reindexdb.c:416 vacuumdb.c:971 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=HOSTNAME ë°ì´í„°ë² ì´ìФ 서버 호스트 ë˜ëŠ” 소켓 디렉터리\n" -#: clusterdb.c:283 createlang.c:246 createuser.c:377 dropdb.c:165 -#: droplang.c:247 dropuser.c:167 reindexdb.c:417 vacuumdb.c:962 +#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 +#: reindexdb.c:417 vacuumdb.c:972 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT ë°ì´í„°ë² ì´ìФ 서버 í¬íЏ\n" -#: clusterdb.c:284 createlang.c:247 dropdb.c:166 droplang.c:248 -#: reindexdb.c:418 vacuumdb.c:963 +#: clusterdb.c:284 dropdb.c:166 reindexdb.c:418 vacuumdb.c:973 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=USERNAME ì ‘ì†í•  사용ìžì´ë¦„\n" -#: clusterdb.c:285 createlang.c:248 createuser.c:379 dropdb.c:167 -#: droplang.c:249 dropuser.c:169 reindexdb.c:419 vacuumdb.c:964 +#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 +#: reindexdb.c:419 vacuumdb.c:974 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password 암호 프롬프트 표시 안 함\n" -#: clusterdb.c:286 createlang.c:249 createuser.c:380 dropdb.c:168 -#: droplang.c:250 dropuser.c:170 reindexdb.c:420 vacuumdb.c:965 +#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 +#: reindexdb.c:420 vacuumdb.c:975 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password 암호 프롬프트 표시함\n" -#: clusterdb.c:287 dropdb.c:169 reindexdb.c:421 vacuumdb.c:966 +#: clusterdb.c:287 dropdb.c:169 reindexdb.c:421 vacuumdb.c:976 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAME 대체용 관리 ëŒ€ìƒ ë°ì´í„°ë² ì´ìФ\n" @@ -241,9 +235,8 @@ msgstr "" "\n" "보다 ìžì„¸í•œ ë‚´ìš©ì€ CLUSTER SQL 명령어 설명서를 참조하십시오.\n" -#: clusterdb.c:289 createdb.c:273 createlang.c:250 createuser.c:381 -#: dropdb.c:170 droplang.c:251 dropuser.c:171 pg_isready.c:236 reindexdb.c:423 -#: vacuumdb.c:968 +#: clusterdb.c:289 createdb.c:273 createuser.c:373 dropdb.c:170 dropuser.c:176 +#: pg_isready.c:236 reindexdb.c:423 vacuumdb.c:978 #, c-format msgid "" "\n" @@ -252,7 +245,7 @@ msgstr "" "\n" "오류보고: .\n" -#: common.c:82 common.c:128 +#: common.c:80 common.c:126 msgid "Password: " msgstr "암호:" @@ -261,49 +254,49 @@ msgstr "암호:" msgid "%s: could not connect to database %s: out of memory\n" msgstr "%s: %s ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²° í•  수 ì—†ìŒ: 메모리 부족\n" -#: common.c:141 +#: common.c:140 #, c-format msgid "%s: could not connect to database %s: %s" msgstr "%s: %s ë°ì´í„°ë² ì´ìŠ¤ì— ì—°ê²° í•  수 ì—†ìŒ: %s" -#: common.c:190 common.c:218 +#: common.c:189 common.c:217 #, c-format msgid "%s: query failed: %s" msgstr "%s: 쿼리 실패: %s" -#: common.c:192 common.c:220 +#: common.c:191 common.c:219 #, c-format msgid "%s: query was: %s\n" msgstr "%s: ì‚¬ìš©ëœ ì¿¼ë¦¬: %s\n" #. translator: abbreviation for "yes" -#: common.c:261 +#: common.c:260 msgid "y" msgstr "y" #. translator: abbreviation for "no" -#: common.c:263 +#: common.c:262 msgid "n" msgstr "n" #. translator: This is a question followed by the translated options for #. "yes" and "no". -#: common.c:273 +#: common.c:272 #, c-format msgid "%s (%s/%s) " msgstr "%s (%s/%s) " -#: common.c:294 +#: common.c:286 #, c-format msgid "Please answer \"%s\" or \"%s\".\n" msgstr "\"%s\" ë˜ëŠ” \"%s\" ë§Œ 허용합니다.\n" -#: common.c:373 common.c:410 +#: common.c:365 common.c:402 #, c-format msgid "Cancel request sent\n" msgstr "취소 ìš”ì²­ì„ ì „ì†¡í•¨\n" -#: common.c:376 common.c:414 +#: common.c:368 common.c:406 #, c-format msgid "Could not send cancel request: %s" msgstr "취소 ìš”ì²­ì„ ì „ì†¡í•  수 ì—†ìŒ: %s" @@ -441,67 +434,7 @@ msgstr "" "초기값으로, DBì´ë¦„ì„ ì§€ì •í•˜ì§€ 않으면, 현재 사용ìžì˜ ì´ë¦„ê³¼ ê°™ì€ ë°ì´í„°ë² ì´ìФ" "ê°€ 만들어집니다.\n" -#: createlang.c:149 droplang.c:148 -msgid "Name" -msgstr "ì´ë¦„" - -#: createlang.c:150 droplang.c:149 -msgid "no" -msgstr "아니오" - -#: createlang.c:150 droplang.c:149 -msgid "yes" -msgstr "예" - -#: createlang.c:151 droplang.c:150 -msgid "Trusted?" -msgstr "신뢰ëœ?" - -#: createlang.c:160 droplang.c:159 -msgid "Procedural Languages" -msgstr "프로시쥬얼 언어들" - -#: createlang.c:173 droplang.c:172 -#, c-format -msgid "%s: missing required argument language name\n" -msgstr "%s: 필수 항목ì¸, 언어 ì´ë¦„ì„ ì§€ì •í•  ì¸ìˆ˜ê°€ 빠졌습니다\n" - -#: createlang.c:196 -#, c-format -msgid "%s: language \"%s\" is already installed in database \"%s\"\n" -msgstr "%s: \"%s\" 언어는 ì´ë¯¸ \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì„¤ì¹˜ë˜ì–´ 있습니다.\n" - -#: createlang.c:219 -#, c-format -msgid "%s: language installation failed: %s" -msgstr "%s: 언어 설치 실패: %s" - -#: createlang.c:235 -#, c-format -msgid "" -"%s installs a procedural language into a PostgreSQL database.\n" -"\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ë°ì´í„°ë² ì´ìŠ¤ì— í”„ë¡œì‹œì¥¬ì–¼ 언어를 설치합니다.\n" -"\n" - -#: createlang.c:237 droplang.c:238 -#, c-format -msgid " %s [OPTION]... LANGNAME [DBNAME]\n" -msgstr " %s [옵션]... 언어ì´ë¦„ [DBì´ë¦„]\n" - -#: createlang.c:239 -#, c-format -msgid " -d, --dbname=DBNAME database to install language in\n" -msgstr " -d, --dbname=DBNAME 언어를 설치할 DBì´ë¦„\n" - -#: createlang.c:241 droplang.c:242 -#, c-format -msgid "" -" -l, --list show a list of currently installed languages\n" -msgstr " -l, --list 현재 설치 ë˜ì–´ìžˆëŠ” ì–¸ì–´ë“¤ì„ ë³´ì—¬ì¤Œ\n" - -#: createuser.c:191 +#: createuser.c:189 msgid "Enter name of role to add: " msgstr "추가할 새 롤(role)ì´ë¦„: " @@ -509,11 +442,11 @@ msgstr "추가할 새 롤(role)ì´ë¦„: " msgid "Enter password for new role: " msgstr "새 ë¡¤ì˜ ì•”í˜¸: " -#: createuser.c:207 +#: createuser.c:208 msgid "Enter it again: " msgstr "암호 확ì¸: " -#: createuser.c:210 +#: createuser.c:211 #, c-format msgid "Passwords didn't match.\n" msgstr "암호가 서로 틀림.\n" @@ -530,17 +463,17 @@ msgstr "ì´ ìƒˆ 롤ì—게 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 만들 수 있는 ê¶Œí• ì„ ì¤„ msgid "Shall the new role be allowed to create more new roles?" msgstr "ì´ ìƒˆ 롤ì—게 ë˜ ë‹¤ë¥¸ ë¡¤ì„ ë§Œë“¤ 수 있는 ê¶Œí•œì„ ì¤„ê¹Œìš”?" -#: createuser.c:276 +#: createuser.c:272 #, c-format -msgid "Password encryption failed.\n" -msgstr "암호 암호화 실패.\n" +msgid "%s: password encryption failed: %s" +msgstr "%s: 암호 암호화 실패: %s" -#: createuser.c:333 +#: createuser.c:327 #, c-format msgid "%s: creation of new role failed: %s" msgstr "%s: 새 롤 만들기 실패: %s" -#: createuser.c:348 +#: createuser.c:342 #, c-format msgid "" "%s creates a new PostgreSQL role.\n" @@ -549,39 +482,34 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ë¡¤ì„ ë§Œë“­ë‹ˆë‹¤.\n" "\n" -#: createuser.c:350 dropuser.c:157 +#: createuser.c:344 dropuser.c:162 #, c-format msgid " %s [OPTION]... [ROLENAME]\n" msgstr " %s [옵션]... [롤ì´ë¦„]\n" -#: createuser.c:352 +#: createuser.c:346 #, c-format msgid "" " -c, --connection-limit=N connection limit for role (default: no limit)\n" msgstr " -c, --connection-limit=N ì—°ê²° 제한 수 (초기값: 무제한)\n" -#: createuser.c:353 +#: createuser.c:347 #, c-format msgid " -d, --createdb role can create new databases\n" msgstr " -d, --createdb 새 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 만들 수 있ìŒ\n" -#: createuser.c:354 +#: createuser.c:348 #, c-format msgid " -D, --no-createdb role cannot create databases (default)\n" msgstr "" " -D, --no-createdb ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 만들 수 있는 권한 ì—†ìŒ (초기값)\n" -#: createuser.c:356 -#, c-format -msgid " -E, --encrypted encrypt stored password\n" -msgstr " -E, --encrypted ì•”í˜¸í™”ëœ ì•”í˜¸ 사용\n" - -#: createuser.c:357 +#: createuser.c:350 #, c-format msgid " -g, --role=ROLE new role will be a member of this role\n" msgstr " -g, --role=ROLE 만들어지는 ë¡¤ì´ ì´ ë¡¤ì˜ êµ¬ì„±ì›ì´ ë¨\n" -#: createuser.c:358 +#: createuser.c:351 #, c-format msgid "" " -i, --inherit role inherits privileges of roles it is a\n" @@ -590,52 +518,47 @@ msgstr "" " -i, --inherit ë¡¤ì˜ ê¶Œí•œì„ ìƒì†í•  수 있ìŒ\n" " (초기값)\n" -#: createuser.c:360 +#: createuser.c:353 #, c-format msgid " -I, --no-inherit role does not inherit privileges\n" msgstr " -I, --no-inherit ì´ ë¡¤ì˜ ê¶Œí•œì„ ìƒì†í•  수 ì—†ìŒ\n" -#: createuser.c:361 +#: createuser.c:354 #, c-format msgid " -l, --login role can login (default)\n" msgstr " -l, --login ë¡œê·¸ì¸ í—ˆìš© (초기값)\n" -#: createuser.c:362 +#: createuser.c:355 #, c-format msgid " -L, --no-login role cannot login\n" msgstr " -L, --no-login ë¡œê·¸ì¸ í•  수 ì—†ìŒ\n" -#: createuser.c:363 -#, c-format -msgid " -N, --unencrypted do not encrypt stored password\n" -msgstr " -N, --unencrypted 암호화 ë˜ì§€ ì•Šì€ ì•”í˜¸ 사용\n" - -#: createuser.c:364 +#: createuser.c:356 #, c-format msgid " -P, --pwprompt assign a password to new role\n" msgstr " -P, --pwprompt 새 ë¡¤ì˜ ì•”í˜¸ 지정\n" -#: createuser.c:365 +#: createuser.c:357 #, c-format msgid " -r, --createrole role can create new roles\n" msgstr " -r, --createrole 새 ë¡¤ì„ ë§Œë“¤ 수 있ìŒ\n" -#: createuser.c:366 +#: createuser.c:358 #, c-format msgid " -R, --no-createrole role cannot create roles (default)\n" msgstr " -R, --no-createrole 롤 만들 수 있는 권한 ì—†ìŒ (초기값)\n" -#: createuser.c:367 +#: createuser.c:359 #, c-format msgid " -s, --superuser role will be superuser\n" msgstr " -s, --superuser superuser 권한으로 지정\n" -#: createuser.c:368 +#: createuser.c:360 #, c-format msgid " -S, --no-superuser role will not be superuser (default)\n" msgstr " -S, --no-superuser 슈í¼ìœ ì € 권한 ì—†ìŒ (초기값)\n" -#: createuser.c:370 +#: createuser.c:362 #, c-format msgid "" " --interactive prompt for missing role name and attributes " @@ -645,17 +568,17 @@ msgstr "" " --interactive 롤 ì´ë¦„ê³¼ ì†ì„±ì„ ì´ˆê¸°ê°’ì„ ì“°ì§€ 않고\n" " ê°ê° ì§ì ‘ ìž…ë ¥ ì„ íƒ í•¨\n" -#: createuser.c:372 +#: createuser.c:364 #, c-format msgid " --replication role can initiate replication\n" msgstr " --replication 복제 기능 ì´ìš©í•  수 있는 롤\n" -#: createuser.c:373 +#: createuser.c:365 #, c-format msgid " --no-replication role cannot initiate replication\n" msgstr " --no-replication 복제 ê¸°ëŠ¥ì„ ì´ìš©í•  수 ì—†ìŒ\n" -#: createuser.c:378 +#: createuser.c:370 #, c-format msgid "" " -U, --username=USERNAME user name to connect as (not the one to create)\n" @@ -673,7 +596,7 @@ msgstr "%s: 필수 í•­ëª©ì¸ ë°ì´í„°ë² ì´ìФ ì´ë¦„ì´ ë¹ ì¡ŒìŠµë‹ˆë‹¤\n" msgid "Database \"%s\" will be permanently removed.\n" msgstr "\"%s\" ë°ì´í„°ë² ì´ìŠ¤ê°€ 완전히 ì‚­ì œ ë  ê²ƒìž…ë‹ˆë‹¤.\n" -#: dropdb.c:118 dropuser.c:123 +#: dropdb.c:118 dropuser.c:128 msgid "Are you sure?" msgstr "ì •ë§ ê³„ì† í• ê¹Œìš”? (y/n) " @@ -708,51 +631,26 @@ msgid "" msgstr "" " --if-exists 해당 ë°ì´í„°ë² ì´ìŠ¤ê°€ ì—†ì–´ë„ ì˜¤ë¥˜ë¥¼ 보고하지 않ìŒ\n" -#: droplang.c:202 -#, c-format -msgid "%s: language \"%s\" is not installed in database \"%s\"\n" -msgstr "%s: \"%s\" 언어는 \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì„¤ì¹˜ ë˜ì–´ìžˆì§€ 않습니다\n" - -#: droplang.c:221 -#, c-format -msgid "%s: language removal failed: %s" -msgstr "%s: 언어 ì‚­ì œ 실패: %s" - -#: droplang.c:236 -#, c-format -msgid "" -"%s removes a procedural language from a database.\n" -"\n" -msgstr "" -"%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФì—서 프로시쥬얼 언어를 삭제합니다.\n" -"\n" - -#: droplang.c:240 -#, c-format -msgid "" -" -d, --dbname=DBNAME database from which to remove the language\n" -msgstr " -d, --dbname=DBNAME 언어를 삭제할 ë°ì´í„°ë² ì´ìФ\n" - -#: dropuser.c:111 +#: dropuser.c:113 msgid "Enter name of role to drop: " msgstr "삭제할 롤 ì´ë¦„ì„ ìž…ë ¥í•˜ì‹­ì‹œì˜¤: " -#: dropuser.c:114 +#: dropuser.c:119 #, c-format msgid "%s: missing required argument role name\n" msgstr "%s: 롤 ì´ë¦„ì€ í•„ìˆ˜ ìž…ë ¥ ì¸ìžìž…니다\n" -#: dropuser.c:122 +#: dropuser.c:127 #, c-format msgid "Role \"%s\" will be permanently removed.\n" msgstr "\"%s\" ë¡¤ì€ ì˜êµ¬ížˆ ì‚­ì œë  ê²ƒìž…ë‹ˆë‹¤.\n" -#: dropuser.c:140 +#: dropuser.c:145 #, c-format msgid "%s: removal of role \"%s\" failed: %s" msgstr "%s: \"%s\" 롤 ì‚­ì œ 실패: %s" -#: dropuser.c:155 +#: dropuser.c:160 #, c-format msgid "" "%s removes a PostgreSQL role.\n" @@ -761,7 +659,7 @@ msgstr "" "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ë¡¤ì„ ì‚­ì œí•©ë‹ˆë‹¤.\n" "\n" -#: dropuser.c:160 +#: dropuser.c:165 #, c-format msgid "" " -i, --interactive prompt before deleting anything, and prompt for\n" @@ -770,12 +668,12 @@ msgstr "" " -i, --interactive 롤 ì´ë¦„ì„ ìž…ë ¥í•˜ì§€ 않았다면,\n" " 해당 ì´ë¦„ì„ ë¬¼ì–´ë´„\n" -#: dropuser.c:163 +#: dropuser.c:168 #, c-format msgid " --if-exists don't report error if user doesn't exist\n" msgstr " --if-exists 해당 ë¡¤ì´ ì—†ì–´ë„ ì˜¤ë¥˜ë¥¼ 보고하지 않ìŒ\n" -#: dropuser.c:168 +#: dropuser.c:173 #, c-format msgid "" " -U, --username=USERNAME user name to connect as (not the one to drop)\n" @@ -863,10 +761,10 @@ msgstr " -p, --port=PORT ë°ì´í„°ë² ì´ìФ 서버 í¬íЏ\n" #: pg_isready.c:234 #, c-format -msgid " -t, --timeout=SECS seconds to wait when attempting connection, " -"0 disables (default: %s)\n" -msgstr "" -" -t, --timeout=ì´ˆ ì—°ê²° 제한 시간, 0 무제한 (초기값: %s)\n" +msgid "" +" -t, --timeout=SECS seconds to wait when attempting connection, 0 " +"disables (default: %s)\n" +msgstr " -t, --timeout=ì´ˆ ì—°ê²° 제한 시간, 0 무제한 (초기값: %s)\n" #: pg_isready.c:235 #, c-format @@ -1007,71 +905,71 @@ msgstr "" "\n" "보다 ìžì„¸í•œ ë‚´ìš©ì€ REINDEX SQL 명령어 설명서를 참조하십시오.\n" -#: vacuumdb.c:189 +#: vacuumdb.c:195 #, c-format msgid "%s: number of parallel jobs must be at least 1\n" msgstr "%s: 병렬 작업 숫ìžëŠ” 최소 1ì´ì–´ì•¼ 함\n" -#: vacuumdb.c:195 +#: vacuumdb.c:201 #, c-format msgid "%s: too many parallel jobs requested (maximum: %d)\n" msgstr "%s: 너무 ë§Žì€ ë³‘ë ¬ 작업 요청 (최대: %d)\n" -#: vacuumdb.c:234 vacuumdb.c:240 +#: vacuumdb.c:240 vacuumdb.c:246 #, c-format msgid "%s: cannot use the \"%s\" option when performing only analyze\n" msgstr "%s: 통계 수집 ì „ìš© 작업ì—서는 \"%s\" ì˜µì…˜ì„ ì‚¬ìš©í•  수 ì—†ìŒ\n" -#: vacuumdb.c:257 +#: vacuumdb.c:263 #, c-format msgid "%s: cannot vacuum all databases and a specific one at the same time\n" msgstr "" "%s: -a ì˜µì…˜ì´ ìžˆì„ ê²½ìš°ëŠ” 한 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 대ìƒìœ¼ë¡œ ìž‘ì—…ì„ ì§„í–‰í•  수 없습니" "다.\n" -#: vacuumdb.c:263 +#: vacuumdb.c:269 #, c-format msgid "%s: cannot vacuum specific table(s) in all databases\n" msgstr "%s: 모든 ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 대ìƒìœ¼ë¡œ 특정 í…Œì´ë¸”ë“¤ì„ ì²­ì†Œí•  수는 ì—†ìŒ\n" -#: vacuumdb.c:349 +#: vacuumdb.c:355 msgid "Generating minimal optimizer statistics (1 target)" msgstr "최소 최ì í™” 통계 수집 수행 중 (1% 대ìƒ)" -#: vacuumdb.c:350 +#: vacuumdb.c:356 msgid "Generating medium optimizer statistics (10 targets)" msgstr "ì¼ë°˜ 최ì í™” 통계 수집 수행 중 (10% 대ìƒ)" -#: vacuumdb.c:351 +#: vacuumdb.c:357 msgid "Generating default (full) optimizer statistics" msgstr "최대 최ì í™” 통계 수집 수행중 (모든 ìžë£Œ 대ìƒ)" -#: vacuumdb.c:363 +#: vacuumdb.c:369 #, c-format msgid "%s: processing database \"%s\": %s\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìФ 작업 중: %s\n" -#: vacuumdb.c:366 +#: vacuumdb.c:372 #, c-format msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìŠ¤ë¥¼ 청소 중\n" -#: vacuumdb.c:698 +#: vacuumdb.c:708 #, c-format msgid "%s: vacuuming of table \"%s\" in database \"%s\" failed: %s" msgstr "%s: \"%s\" í…Œì´ë¸” (해당 DB: \"%s\") 청소하기 실패: %s" -#: vacuumdb.c:701 vacuumdb.c:818 +#: vacuumdb.c:711 vacuumdb.c:828 #, c-format msgid "%s: vacuuming of database \"%s\" failed: %s" msgstr "%s: \"%s\" ë°ì´í„°ë² ì´ìФ 청소하기 실패: %s" -#: vacuumdb.c:932 +#: vacuumdb.c:942 #, c-format msgid "%s: invalid socket: %s" msgstr "%s: ìž˜ëª»ëœ ì†Œì¼“: %s" -#: vacuumdb.c:941 +#: vacuumdb.c:951 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -1081,34 +979,34 @@ msgstr "" "퀴리 최ì í™”ê¸°ì˜ ì°¸ê³  ìžë£Œë¥¼ 갱신합니다.\n" "\n" -#: vacuumdb.c:945 +#: vacuumdb.c:955 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all 모든 ë°ì´í„°ë² ì´ìФ 청소\n" -#: vacuumdb.c:946 +#: vacuumdb.c:956 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=DBNAME DBNAME ë°ì´í„°ë² ì´ìФ 청소\n" -#: vacuumdb.c:947 +#: vacuumdb.c:957 #, c-format msgid "" " -e, --echo show the commands being sent to the " "server\n" msgstr " -e, --echo 서버로 보내는 ëª…ë ¹ë“¤ì„ ë³´ì—¬ì¤Œ\n" -#: vacuumdb.c:948 +#: vacuumdb.c:958 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full 대청소\n" -#: vacuumdb.c:949 +#: vacuumdb.c:959 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze í–‰ 트랜잭션 ì •ë³´ ë™ê²°\n" -#: vacuumdb.c:950 +#: vacuumdb.c:960 #, c-format msgid "" " -j, --jobs=NUM use this many concurrent connections to " @@ -1116,33 +1014,33 @@ msgid "" msgstr "" " -j, --jobs=NUM 청소 ìž‘ì—…ì„ ì—¬ëŸ¬ê°œì˜ ì—°ê²°ë¡œ ë™ì‹œì— 작업함\n" -#: vacuumdb.c:951 +#: vacuumdb.c:961 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet 어떠한 ë©”ì‹œì§€ë„ ë³´ì—¬ì£¼ì§€ 않ìŒ\n" -#: vacuumdb.c:952 +#: vacuumdb.c:962 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr " -t, --table='TABLE[(COLUMNS)]' 지정한 특정 í…Œì´ë¸”들만 청소\n" -#: vacuumdb.c:953 +#: vacuumdb.c:963 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose ìž‘ì—…ë‚´ì—­ì˜ ìžì„¸í•œ 출력\n" -#: vacuumdb.c:954 +#: vacuumdb.c:964 #, c-format msgid "" " -V, --version output version information, then exit\n" msgstr " -V, --version 버전 정보를 보여주고 마침\n" -#: vacuumdb.c:955 +#: vacuumdb.c:965 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze 쿼리최ì í™” 통계 정보를 갱신함\n" -#: vacuumdb.c:956 +#: vacuumdb.c:966 #, c-format msgid "" " -Z, --analyze-only only update optimizer statistics; no " @@ -1151,22 +1049,22 @@ msgstr "" " -Z, --analyze-only 청소 작업 ì—†ì´ ì¿¼ë¦¬ìµœì í™” 통계 ì •ë³´ë§Œ 갱신" "함\n" -#: vacuumdb.c:957 +#: vacuumdb.c:967 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in " "multiple\n" " stages for faster results; no vacuum\n" msgstr "" -" --analyze-in-stages 보다 빠른 결과를 위해 다중 스테ì´ì§€ì—서" -" 최ì í™” 통계치만 갱신함;청소 안함\n" +" --analyze-in-stages 보다 빠른 결과를 위해 다중 스테ì´ì§€ì—" +"서 최ì í™” 통계치만 갱신함;청소 안함\n" -#: vacuumdb.c:959 +#: vacuumdb.c:969 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help ì´ ë„움ë§ì„ 표시하고 종료\n" -#: vacuumdb.c:967 +#: vacuumdb.c:977 #, c-format msgid "" "\n" @@ -1174,3 +1072,67 @@ msgid "" msgstr "" "\n" "보다 ìžì„¸í•œ ë‚´ìš©ì€ VACUUM SQL 명령어 설명서를 참조하십시오.\n" + +#~ msgid "Name" +#~ msgstr "ì´ë¦„" + +#~ msgid "no" +#~ msgstr "아니오" + +#~ msgid "yes" +#~ msgstr "예" + +#~ msgid "Trusted?" +#~ msgstr "신뢰ëœ?" + +#~ msgid "Procedural Languages" +#~ msgstr "프로시쥬얼 언어들" + +#~ msgid "%s: missing required argument language name\n" +#~ msgstr "%s: 필수 항목ì¸, 언어 ì´ë¦„ì„ ì§€ì •í•  ì¸ìˆ˜ê°€ 빠졌습니다\n" + +#~ msgid "%s: language \"%s\" is already installed in database \"%s\"\n" +#~ msgstr "%s: \"%s\" 언어는 ì´ë¯¸ \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì„¤ì¹˜ë˜ì–´ 있습니다.\n" + +#~ msgid "%s: language installation failed: %s" +#~ msgstr "%s: 언어 설치 실패: %s" + +#~ msgid "" +#~ "%s installs a procedural language into a PostgreSQL database.\n" +#~ "\n" +#~ msgstr "" +#~ "%s í”„ë¡œê·¸ëž¨ì€ PostgreSQL ë°ì´í„°ë² ì´ìŠ¤ì— í”„ë¡œì‹œì¥¬ì–¼ 언어를 설치합니다.\n" +#~ "\n" + +#~ msgid " %s [OPTION]... LANGNAME [DBNAME]\n" +#~ msgstr " %s [옵션]... 언어ì´ë¦„ [DBì´ë¦„]\n" + +#~ msgid " -d, --dbname=DBNAME database to install language in\n" +#~ msgstr " -d, --dbname=DBNAME 언어를 설치할 DBì´ë¦„\n" + +#~ msgid "" +#~ " -l, --list show a list of currently installed languages\n" +#~ msgstr " -l, --list 현재 설치 ë˜ì–´ìžˆëŠ” ì–¸ì–´ë“¤ì„ ë³´ì—¬ì¤Œ\n" + +#~ msgid " -E, --encrypted encrypt stored password\n" +#~ msgstr " -E, --encrypted ì•”í˜¸í™”ëœ ì•”í˜¸ 사용\n" + +#~ msgid " -N, --unencrypted do not encrypt stored password\n" +#~ msgstr " -N, --unencrypted 암호화 ë˜ì§€ ì•Šì€ ì•”í˜¸ 사용\n" + +#~ msgid "%s: language \"%s\" is not installed in database \"%s\"\n" +#~ msgstr "%s: \"%s\" 언어는 \"%s\" ë°ì´í„°ë² ì´ìŠ¤ì— ì„¤ì¹˜ ë˜ì–´ìžˆì§€ 않습니다\n" + +#~ msgid "%s: language removal failed: %s" +#~ msgstr "%s: 언어 ì‚­ì œ 실패: %s" + +#~ msgid "" +#~ "%s removes a procedural language from a database.\n" +#~ "\n" +#~ msgstr "" +#~ "%s í”„ë¡œê·¸ëž¨ì€ ë°ì´í„°ë² ì´ìФì—서 프로시쥬얼 언어를 삭제합니다.\n" +#~ "\n" + +#~ msgid "" +#~ " -d, --dbname=DBNAME database from which to remove the language\n" +#~ msgstr " -d, --dbname=DBNAME 언어를 삭제할 ë°ì´í„°ë² ì´ìФ\n" diff --git a/src/bin/scripts/po/ru.po b/src/bin/scripts/po/ru.po index 476f72ab476..c58ff818ff2 100644 --- a/src/bin/scripts/po/ru.po +++ b/src/bin/scripts/po/ru.po @@ -4,13 +4,12 @@ # Serguei A. Mokhov, , 2003-2004. # Oleg Bartunov , 2004. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: pgscripts (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:46+0000\n" -"PO-Revision-Date: 2016-11-24 14:26+0300\n" +"POT-Creation-Date: 2017-08-17 23:15+0000\n" +"PO-Revision-Date: 2017-05-27 15:01+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -78,14 +77,14 @@ msgid "invalid output format (internal error): %d" msgstr "неверный формат вывода (внутреннÑÑ Ð¾ÑˆÐ¸Ð±ÐºÐ°): %d" #: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 -#: createuser.c:171 createuser.c:186 dropdb.c:94 dropdb.c:103 dropdb.c:111 +#: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 #: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 pg_isready.c:107 #: reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 vacuumdb.c:232 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Ð”Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации попробуйте \"%s --help\".\n" -#: clusterdb.c:128 createdb.c:136 createuser.c:184 dropdb.c:109 dropuser.c:103 +#: clusterdb.c:128 createdb.c:136 createuser.c:179 dropdb.c:109 dropuser.c:103 #: pg_isready.c:105 reindexdb.c:148 vacuumdb.c:230 #, c-format msgid "%s: too many command-line arguments (first is \"%s\")\n" @@ -125,7 +124,7 @@ msgstr "" "%s упорÑдочивает данные вÑех клаÑтеризованных таблиц в базе данных.\n" "\n" -#: clusterdb.c:270 createdb.c:252 createuser.c:354 dropdb.c:155 dropuser.c:161 +#: clusterdb.c:270 createdb.c:252 createuser.c:343 dropdb.c:155 dropuser.c:161 #: pg_isready.c:222 reindexdb.c:401 vacuumdb.c:952 #, c-format msgid "Usage:\n" @@ -136,7 +135,7 @@ msgstr "ИÑпользование:\n" msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [ПÐРÐМЕТР]... [ИМЯ_БД]\n" -#: clusterdb.c:272 createdb.c:254 createuser.c:356 dropdb.c:157 dropuser.c:163 +#: clusterdb.c:272 createdb.c:254 createuser.c:345 dropdb.c:157 dropuser.c:163 #: pg_isready.c:225 reindexdb.c:403 vacuumdb.c:954 #, c-format msgid "" @@ -156,7 +155,7 @@ msgstr " -a, --all клаÑтеризовать вÑе базы msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=ИМЯ_БД Ð¸Ð¼Ñ Ð±Ð°Ð·Ñ‹ данных Ð´Ð»Ñ ÐºÐ»Ð°Ñтеризации\n" -#: clusterdb.c:275 createuser.c:360 dropdb.c:158 dropuser.c:164 reindexdb.c:406 +#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 reindexdb.c:406 #, c-format msgid "" " -e, --echo show the commands being sent to the server\n" @@ -178,17 +177,17 @@ msgstr "" msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose выводить иÑчерпывающие ÑообщениÑ\n" -#: clusterdb.c:279 createuser.c:374 dropdb.c:160 dropuser.c:167 reindexdb.c:413 +#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 reindexdb.c:413 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version показать верÑию и выйти\n" -#: clusterdb.c:280 createuser.c:379 dropdb.c:162 dropuser.c:169 reindexdb.c:414 +#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 reindexdb.c:414 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help показать Ñту Ñправку и выйти\n" -#: clusterdb.c:281 createdb.c:265 createuser.c:380 dropdb.c:163 dropuser.c:170 +#: clusterdb.c:281 createdb.c:265 createuser.c:367 dropdb.c:163 dropuser.c:170 #: pg_isready.c:231 reindexdb.c:415 vacuumdb.c:970 #, c-format msgid "" @@ -198,14 +197,14 @@ msgstr "" "\n" "Параметры подключениÑ:\n" -#: clusterdb.c:282 createuser.c:381 dropdb.c:164 dropuser.c:171 reindexdb.c:416 +#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 reindexdb.c:416 #: vacuumdb.c:971 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr "" " -h, --host=ИМЯ Ð¸Ð¼Ñ Ñервера баз данных или каталог Ñокетов\n" -#: clusterdb.c:283 createuser.c:382 dropdb.c:165 dropuser.c:172 reindexdb.c:417 +#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 reindexdb.c:417 #: vacuumdb.c:972 #, c-format msgid " -p, --port=PORT database server port\n" @@ -217,13 +216,13 @@ msgid " -U, --username=USERNAME user name to connect as\n" msgstr "" " -U, --username=ИМЯ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу\n" -#: clusterdb.c:285 createuser.c:384 dropdb.c:167 dropuser.c:174 reindexdb.c:419 +#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 reindexdb.c:419 #: vacuumdb.c:974 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password не запрашивать пароль\n" -#: clusterdb.c:286 createuser.c:385 dropdb.c:168 dropuser.c:175 reindexdb.c:420 +#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 reindexdb.c:420 #: vacuumdb.c:975 #, c-format msgid " -W, --password force password prompt\n" @@ -243,7 +242,7 @@ msgstr "" "\n" "Подробнее о клаÑтеризации вы можете узнать в опиÑании SQL-команды CLUSTER.\n" -#: clusterdb.c:289 createdb.c:273 createuser.c:386 dropdb.c:170 dropuser.c:176 +#: clusterdb.c:289 createdb.c:273 createuser.c:373 dropdb.c:170 dropuser.c:176 #: pg_isready.c:236 reindexdb.c:423 vacuumdb.c:978 #, c-format msgid "" @@ -447,46 +446,46 @@ msgstr "" "\n" "По умолчанию именем базы данных ÑчитаетÑÑ Ð¸Ð¼Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ³Ð¾ пользователÑ.\n" -#: createuser.c:194 +#: createuser.c:189 msgid "Enter name of role to add: " msgstr "Введите Ð¸Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð¹ роли: " -#: createuser.c:211 +#: createuser.c:206 msgid "Enter password for new role: " msgstr "Введите пароль Ð´Ð»Ñ Ð½Ð¾Ð²Ð¾Ð¹ роли: " -#: createuser.c:213 +#: createuser.c:208 msgid "Enter it again: " msgstr "Повторите его: " -#: createuser.c:216 +#: createuser.c:211 #, c-format msgid "Passwords didn't match.\n" msgstr "Пароли не Ñовпадают.\n" -#: createuser.c:224 +#: createuser.c:219 msgid "Shall the new role be a superuser?" msgstr "Должна ли Ð½Ð¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ иметь Ð¿Ð¾Ð»Ð½Ð¾Ð¼Ð¾Ñ‡Ð¸Ñ ÑуперпользователÑ?" -#: createuser.c:239 +#: createuser.c:234 msgid "Shall the new role be allowed to create databases?" msgstr "ÐÐ¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ должна иметь право Ñоздавать базы данных?" -#: createuser.c:247 +#: createuser.c:242 msgid "Shall the new role be allowed to create more new roles?" msgstr "ÐÐ¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ должна иметь право Ñоздавать другие роли?" -#: createuser.c:281 +#: createuser.c:272 #, c-format -msgid "Password encryption failed.\n" -msgstr "Ошибка при шифровании паролÑ.\n" +msgid "%s: password encryption failed: %s" +msgstr "%s: ошибка при шифровании паролÑ: %s" -#: createuser.c:338 +#: createuser.c:327 #, c-format msgid "%s: creation of new role failed: %s" msgstr "%s: Ñоздать роль не удалоÑÑŒ: %s" -#: createuser.c:353 +#: createuser.c:342 #, c-format msgid "" "%s creates a new PostgreSQL role.\n" @@ -495,12 +494,12 @@ msgstr "" "%s Ñоздаёт роль Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ PostgreSQL.\n" "\n" -#: createuser.c:355 dropuser.c:162 +#: createuser.c:344 dropuser.c:162 #, c-format msgid " %s [OPTION]... [ROLENAME]\n" msgstr " %s [ПÐРÐМЕТР]... [ИМЯ_РОЛИ]\n" -#: createuser.c:357 +#: createuser.c:346 #, c-format msgid "" " -c, --connection-limit=N connection limit for role (default: no limit)\n" @@ -508,29 +507,24 @@ msgstr "" " -c, --connection-limit=N предел подключений Ð´Ð»Ñ Ñ€Ð¾Ð»Ð¸\n" " (по умолчанию предела нет)\n" -#: createuser.c:358 +#: createuser.c:347 #, c-format msgid " -d, --createdb role can create new databases\n" msgstr " -d, --createdb роль Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð¼ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð°Ð· данных\n" -#: createuser.c:359 +#: createuser.c:348 #, c-format msgid " -D, --no-createdb role cannot create databases (default)\n" msgstr "" " -D, --no-createdb роль без права ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð±Ð°Ð· данных (по " "умолчанию)\n" -#: createuser.c:361 -#, c-format -msgid " -E, --encrypted encrypt stored password\n" -msgstr " -E, --encrypted зашифровать Ñохранённый пароль\n" - -#: createuser.c:362 +#: createuser.c:350 #, c-format msgid " -g, --role=ROLE new role will be a member of this role\n" msgstr " -g, --role=РОЛЬ Ð½Ð¾Ð²Ð°Ñ Ñ€Ð¾Ð»ÑŒ будет включена в Ñту роль\n" -#: createuser.c:363 +#: createuser.c:351 #, c-format msgid "" " -i, --inherit role inherits privileges of roles it is a\n" @@ -540,57 +534,52 @@ msgstr "" "она\n" " включена (по умолчанию)\n" -#: createuser.c:365 +#: createuser.c:353 #, c-format msgid " -I, --no-inherit role does not inherit privileges\n" msgstr " -I, --no-inherit роль не наÑледует права\n" -#: createuser.c:366 +#: createuser.c:354 #, c-format msgid " -l, --login role can login (default)\n" msgstr "" " -l, --login роль Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð¼ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº Ñерверу (по " "умолчанию)\n" -#: createuser.c:367 +#: createuser.c:355 #, c-format msgid " -L, --no-login role cannot login\n" msgstr " -L, --no-login роль без права подключениÑ\n" -#: createuser.c:368 -#, c-format -msgid " -N, --unencrypted do not encrypt stored password\n" -msgstr " -N, --unencrypted не шифровать Ñохранённый пароль\n" - -#: createuser.c:369 +#: createuser.c:356 #, c-format msgid " -P, --pwprompt assign a password to new role\n" msgstr " -P, --pwprompt назначить пароль новой роли\n" -#: createuser.c:370 +#: createuser.c:357 #, c-format msgid " -r, --createrole role can create new roles\n" msgstr " -r, --createrole роль Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð¼ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… ролей\n" -#: createuser.c:371 +#: createuser.c:358 #, c-format msgid " -R, --no-createrole role cannot create roles (default)\n" msgstr "" " -R, --no-createrole роль без права ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ€Ð¾Ð»ÐµÐ¹ (по умолчанию)\n" -#: createuser.c:372 +#: createuser.c:359 #, c-format msgid " -s, --superuser role will be superuser\n" msgstr " -s, --superuser роль Ñ Ð¿Ð¾Ð»Ð½Ð¾Ð¼Ð¾Ñ‡Ð¸Ñми ÑуперпользователÑ\n" -#: createuser.c:373 +#: createuser.c:360 #, c-format msgid " -S, --no-superuser role will not be superuser (default)\n" msgstr "" " -S, --no-superuser роль без полномочий ÑÑƒÐ¿ÐµÑ€Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ (по " "умолчанию)\n" -#: createuser.c:375 +#: createuser.c:362 #, c-format msgid "" " --interactive prompt for missing role name and attributes " @@ -600,17 +589,17 @@ msgstr "" " --interactive запрашивать отÑутÑтвующие атрибуты и Ð¸Ð¼Ñ Ñ€Ð¾Ð»Ð¸,\n" " а не иÑпользовать Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию\n" -#: createuser.c:377 +#: createuser.c:364 #, c-format msgid " --replication role can initiate replication\n" msgstr " --replication роль может инициировать репликацию\n" -#: createuser.c:378 +#: createuser.c:365 #, c-format msgid " --no-replication role cannot initiate replication\n" msgstr " --no-replication роль не может инициировать репликацию\n" -#: createuser.c:383 +#: createuser.c:370 #, c-format msgid "" " -U, --username=USERNAME user name to connect as (not the one to create)\n" @@ -1114,6 +1103,12 @@ msgstr "" "\n" "Подробнее об очиÑтке вы можете узнать в опиÑании SQL-команды VACUUM.\n" +#~ msgid " -E, --encrypted encrypt stored password\n" +#~ msgstr " -E, --encrypted зашифровать Ñохранённый пароль\n" + +#~ msgid " -N, --unencrypted do not encrypt stored password\n" +#~ msgstr " -N, --unencrypted не шифровать Ñохранённый пароль\n" + #~ msgid "Name" #~ msgstr "ИмÑ" diff --git a/src/bin/scripts/po/sv.po b/src/bin/scripts/po/sv.po index fe7ed56f895..6dd3c803d0e 100644 --- a/src/bin/scripts/po/sv.po +++ b/src/bin/scripts/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for postgresql -# Dennis Björklund , 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2003, 2004, 2005, 2006, 2017, 2018, 2019. # Peter Eisentraut , 2013. # Mats Erik Andersson , 2014. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-10 05:46+0000\n" -"PO-Revision-Date: 2017-07-20 21:44+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 18:47+0000\n" +"PO-Revision-Date: 2019-04-29 20:55+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,6 +17,21 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "fatalt: " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "fel: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "varning: " + #: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 #: ../../common/fe_memutils.c:98 #, c-format @@ -49,67 +64,66 @@ msgid_plural "(%lu rows)" msgstr[0] "(%lu rad)" msgstr[1] "(%lu rader)" -#: ../../fe_utils/print.c:2913 +#: ../../fe_utils/print.c:3058 #, c-format msgid "Interrupted\n" msgstr "Avbruten\n" -#: ../../fe_utils/print.c:2977 +#: ../../fe_utils/print.c:3122 #, c-format msgid "Cannot add header to table content: column count of %d exceeded.\n" msgstr "Kan inte lägga till rubrik till tabellinnehÃ¥ll: antal kolumner (%d) överskridet.\n" -#: ../../fe_utils/print.c:3017 +#: ../../fe_utils/print.c:3162 #, c-format msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" msgstr "Kan inte lägga till cell till tabellinnehÃ¥ll: totala cellantalet (%d) överskridet.\n" -#: ../../fe_utils/print.c:3266 +#: ../../fe_utils/print.c:3417 #, c-format msgid "invalid output format (internal error): %d" msgstr "ogiltigt utdataformat (internt fel): %d" -#: clusterdb.c:111 clusterdb.c:130 createdb.c:119 createdb.c:138 -#: createuser.c:166 createuser.c:181 dropdb.c:94 dropdb.c:103 dropdb.c:111 -#: dropuser.c:90 dropuser.c:105 dropuser.c:120 pg_isready.c:93 -#: pg_isready.c:107 reindexdb.c:131 reindexdb.c:150 vacuumdb.c:213 -#: vacuumdb.c:232 +#: clusterdb.c:113 clusterdb.c:132 createdb.c:121 createdb.c:140 +#: createuser.c:168 createuser.c:183 dropdb.c:96 dropdb.c:105 dropdb.c:113 +#: dropuser.c:92 dropuser.c:107 dropuser.c:122 pg_isready.c:95 pg_isready.c:109 +#: reindexdb.c:139 reindexdb.c:158 vacuumdb.c:246 vacuumdb.c:265 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Försök med \"%s --help\" för mer information.\n" -#: clusterdb.c:128 createdb.c:136 createuser.c:179 dropdb.c:109 dropuser.c:103 -#: pg_isready.c:105 reindexdb.c:148 vacuumdb.c:230 +#: clusterdb.c:130 createdb.c:138 createuser.c:181 dropdb.c:111 dropuser.c:105 +#: pg_isready.c:107 reindexdb.c:156 vacuumdb.c:263 #, c-format -msgid "%s: too many command-line arguments (first is \"%s\")\n" -msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" +msgid "too many command-line arguments (first is \"%s\")" +msgstr "för mÃ¥nga kommandoradsargument (första är \"%s\")" -#: clusterdb.c:140 +#: clusterdb.c:142 #, c-format -msgid "%s: cannot cluster all databases and a specific one at the same time\n" -msgstr "%s: kan inte klustra alla databaser och en angiven pÃ¥ samma gÃ¥ng\n" +msgid "cannot cluster all databases and a specific one at the same time" +msgstr "kan inte klustra alla databaser och en angiven pÃ¥ samma gÃ¥ng" -#: clusterdb.c:147 +#: clusterdb.c:148 #, c-format -msgid "%s: cannot cluster specific table(s) in all databases\n" -msgstr "%s: kan inte klustra angivna tabeller i alla databaser\n" +msgid "cannot cluster specific table(s) in all databases" +msgstr "kan inte klustra angivna tabeller i alla databaser" -#: clusterdb.c:212 +#: clusterdb.c:216 #, c-format -msgid "%s: clustering of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: klustring av tabell \"%s\" i databas \"%s\" misslyckades: %s" +msgid "clustering of table \"%s\" in database \"%s\" failed: %s" +msgstr "klustring av tabell \"%s\" i databas \"%s\" misslyckades: %s" -#: clusterdb.c:215 +#: clusterdb.c:219 #, c-format -msgid "%s: clustering of database \"%s\" failed: %s" -msgstr "%s: klustring av databas \"%s\" misslyckades: %s" +msgid "clustering of database \"%s\" failed: %s" +msgstr "klustring av databas \"%s\" misslyckades: %s" -#: clusterdb.c:248 +#: clusterdb.c:252 #, c-format msgid "%s: clustering database \"%s\"\n" msgstr "%s: klustring av databas \"%s\"\n" -#: clusterdb.c:269 +#: clusterdb.c:273 #, c-format msgid "" "%s clusters all previously clustered tables in a database.\n" @@ -118,111 +132,112 @@ msgstr "" "%s klustrar alla tidigare klustrade tabeller i en databas.\n" "\n" -#: clusterdb.c:270 createdb.c:252 createuser.c:343 dropdb.c:155 dropuser.c:161 -#: pg_isready.c:222 reindexdb.c:401 vacuumdb.c:952 +#: clusterdb.c:274 createdb.c:250 createuser.c:344 dropdb.c:157 dropuser.c:163 +#: pg_isready.c:224 reindexdb.c:425 vacuumdb.c:1213 #, c-format msgid "Usage:\n" msgstr "Användning:\n" -#: clusterdb.c:271 reindexdb.c:402 vacuumdb.c:953 +#: clusterdb.c:275 reindexdb.c:426 vacuumdb.c:1214 #, c-format msgid " %s [OPTION]... [DBNAME]\n" msgstr " %s [FLAGGA]... [DBNAMN]\n" -#: clusterdb.c:272 createdb.c:254 createuser.c:345 dropdb.c:157 dropuser.c:163 -#: pg_isready.c:225 reindexdb.c:403 vacuumdb.c:954 +#: clusterdb.c:276 createdb.c:252 createuser.c:346 dropdb.c:159 dropuser.c:165 +#: pg_isready.c:227 reindexdb.c:427 vacuumdb.c:1215 #, c-format msgid "" "\n" "Options:\n" -msgstr "\nFlaggor:\n" +msgstr "" +"\n" +"Flaggor:\n" -#: clusterdb.c:273 +#: clusterdb.c:277 #, c-format msgid " -a, --all cluster all databases\n" msgstr " -a, --all klustra alla databaser\n" -#: clusterdb.c:274 +#: clusterdb.c:278 #, c-format msgid " -d, --dbname=DBNAME database to cluster\n" msgstr " -d, --dbname=DBNAME databas att klustra\n" -#: clusterdb.c:275 createuser.c:349 dropdb.c:158 dropuser.c:164 -#: reindexdb.c:406 +#: clusterdb.c:279 createuser.c:350 dropdb.c:160 dropuser.c:166 reindexdb.c:431 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo visa kommandon som skickas till servern\n" -#: clusterdb.c:276 reindexdb.c:408 +#: clusterdb.c:280 reindexdb.c:433 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet skriv inte ut nÃ¥gra meddelanden\n" -#: clusterdb.c:277 +#: clusterdb.c:281 #, c-format msgid " -t, --table=TABLE cluster specific table(s) only\n" msgstr " -t, --table=TABELL klustra enbart ingivna tabeller\n" -#: clusterdb.c:278 reindexdb.c:412 +#: clusterdb.c:282 reindexdb.c:437 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose skriv massor med utdata\n" -#: clusterdb.c:279 createuser.c:361 dropdb.c:160 dropuser.c:167 -#: reindexdb.c:413 +#: clusterdb.c:283 createuser.c:362 dropdb.c:162 dropuser.c:169 reindexdb.c:438 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: clusterdb.c:280 createuser.c:366 dropdb.c:162 dropuser.c:169 -#: reindexdb.c:414 +#: clusterdb.c:284 createuser.c:367 dropdb.c:164 dropuser.c:171 reindexdb.c:439 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: clusterdb.c:281 createdb.c:265 createuser.c:367 dropdb.c:163 dropuser.c:170 -#: pg_isready.c:231 reindexdb.c:415 vacuumdb.c:970 +#: clusterdb.c:285 createdb.c:263 createuser.c:368 dropdb.c:165 dropuser.c:172 +#: pg_isready.c:233 reindexdb.c:440 vacuumdb.c:1235 #, c-format msgid "" "\n" "Connection options:\n" -msgstr "\nFlaggor för anslutning:\n" +msgstr "" +"\n" +"Flaggor för anslutning:\n" -#: clusterdb.c:282 createuser.c:368 dropdb.c:164 dropuser.c:171 -#: reindexdb.c:416 vacuumdb.c:971 +#: clusterdb.c:286 createuser.c:369 dropdb.c:166 dropuser.c:173 reindexdb.c:441 +#: vacuumdb.c:1236 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=VÄRDNAMN databasens värdnamn eller socketkatalog\n" -#: clusterdb.c:283 createuser.c:369 dropdb.c:165 dropuser.c:172 -#: reindexdb.c:417 vacuumdb.c:972 +#: clusterdb.c:287 createuser.c:370 dropdb.c:167 dropuser.c:174 reindexdb.c:442 +#: vacuumdb.c:1237 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT databasserverns port\n" -#: clusterdb.c:284 dropdb.c:166 reindexdb.c:418 vacuumdb.c:973 +#: clusterdb.c:288 dropdb.c:168 reindexdb.c:443 vacuumdb.c:1238 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=ANVÄNDARE användarnamn att ansluta som\n" -#: clusterdb.c:285 createuser.c:371 dropdb.c:167 dropuser.c:174 -#: reindexdb.c:419 vacuumdb.c:974 +#: clusterdb.c:289 createuser.c:372 dropdb.c:169 dropuser.c:176 reindexdb.c:444 +#: vacuumdb.c:1239 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password frÃ¥ga ej efter lösenord\n" -#: clusterdb.c:286 createuser.c:372 dropdb.c:168 dropuser.c:175 -#: reindexdb.c:420 vacuumdb.c:975 +#: clusterdb.c:290 createuser.c:373 dropdb.c:170 dropuser.c:177 reindexdb.c:445 +#: vacuumdb.c:1240 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password framtvinga frÃ¥ga om lösenord\n" -#: clusterdb.c:287 dropdb.c:169 reindexdb.c:421 vacuumdb.c:976 +#: clusterdb.c:291 dropdb.c:171 reindexdb.c:446 vacuumdb.c:1241 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAMN annat val av underhÃ¥llsdatabas\n" -#: clusterdb.c:288 +#: clusterdb.c:292 #, c-format msgid "" "\n" @@ -231,268 +246,281 @@ msgstr "" "\n" "Läs beskrivningen av SQL-kommandot CLUSTER för detaljer.\n" -#: clusterdb.c:289 createdb.c:273 createuser.c:373 dropdb.c:170 dropuser.c:176 -#: pg_isready.c:236 reindexdb.c:423 vacuumdb.c:978 +#: clusterdb.c:293 createdb.c:271 createuser.c:374 dropdb.c:172 dropuser.c:178 +#: pg_isready.c:238 reindexdb.c:448 vacuumdb.c:1243 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapportera fel till .\n" +"Rapportera fel till .\n" -#: common.c:80 common.c:126 +#: common.c:84 common.c:130 msgid "Password: " msgstr "Lösenord: " -#: common.c:113 +#: common.c:117 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "kunde inte ansluta till databas %s: slut pÃ¥ minne" + +#: common.c:144 #, c-format -msgid "%s: could not connect to database %s: out of memory\n" -msgstr "%s: kunde inte ansluta till databas %s: slut pÃ¥ minne\n" +msgid "could not connect to database %s: %s" +msgstr "kunde inte ansluta till databas %s: %s" -#: common.c:140 +#: common.c:197 common.c:223 #, c-format -msgid "%s: could not connect to database %s: %s" -msgstr "%s: kunde inte ansluta till databas %s: %s" +msgid "query failed: %s" +msgstr "frÃ¥ga misslyckades: %s" -#: common.c:189 common.c:217 +#: common.c:198 common.c:224 #, c-format -msgid "%s: query failed: %s" -msgstr "%s: frÃ¥ga misslyckades: %s" +msgid "query was: %s" +msgstr "frÃ¥gan var: %s" -#: common.c:191 common.c:219 +#: common.c:347 #, c-format -msgid "%s: query was: %s\n" -msgstr "%s: frÃ¥gan var: %s\n" +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "frÃ¥ga gav %d rad istället för en: %s" +msgstr[1] "frÃ¥ga gav %d rader istället för en: %s" #. translator: abbreviation for "yes" -#: common.c:260 +#: common.c:372 msgid "y" msgstr "j" #. translator: abbreviation for "no" -#: common.c:262 +#: common.c:374 msgid "n" msgstr "n" #. translator: This is a question followed by the translated options for #. "yes" and "no". -#: common.c:272 +#: common.c:384 #, c-format msgid "%s (%s/%s) " msgstr "%s (%s/%s) " -#: common.c:286 +#: common.c:398 #, c-format msgid "Please answer \"%s\" or \"%s\".\n" msgstr "Var vänlig att svara \"%s\" eller \"%s\".\n" -#: common.c:365 common.c:402 +#: common.c:477 common.c:514 #, c-format msgid "Cancel request sent\n" msgstr "Avbrottsbegäran skickad.\n" -#: common.c:368 common.c:406 +#: common.c:480 common.c:518 #, c-format msgid "Could not send cancel request: %s" msgstr "Kunde inte skicka avbrottsbegäran: %s" -#: createdb.c:146 +#: createdb.c:148 #, c-format -msgid "%s: only one of --locale and --lc-ctype can be specified\n" -msgstr "%s: endast en av --locale och --lc-ctype kan anges\n" +msgid "only one of --locale and --lc-ctype can be specified" +msgstr "endast en av --locale och --lc-ctype kan anges" -#: createdb.c:152 +#: createdb.c:153 #, c-format -msgid "%s: only one of --locale and --lc-collate can be specified\n" -msgstr "%s: endast en av --locale och --lc-collate kan anges\n" +msgid "only one of --locale and --lc-collate can be specified" +msgstr "endast en av --locale och --lc-collate kan anges" #: createdb.c:164 #, c-format -msgid "%s: \"%s\" is not a valid encoding name\n" -msgstr "%s: \"%s\" är inte en giltig teckenkodning.\n" +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\" är inte ett giltigt kodningsnamn" -#: createdb.c:213 +#: createdb.c:212 #, c-format -msgid "%s: database creation failed: %s" -msgstr "%s: misslyckades att skapa databas: %s" +msgid "database creation failed: %s" +msgstr "misslyckades att skapa databas: %s" -#: createdb.c:233 +#: createdb.c:231 #, c-format -msgid "%s: comment creation failed (database was created): %s" -msgstr "%s: misslyckades att skapa kommentar (databasen skapades): %s" +msgid "comment creation failed (database was created): %s" +msgstr "misslyckades att skapa kommentar (databasen skapades): %s" -#: createdb.c:251 +#: createdb.c:249 #, c-format msgid "" "%s creates a PostgreSQL database.\n" "\n" -msgstr "%s skapar en PostgreSQL-databas.\n\n" +msgstr "" +"%s skapar en PostgreSQL-databas.\n" +"\n" -#: createdb.c:253 +#: createdb.c:251 #, c-format msgid " %s [OPTION]... [DBNAME] [DESCRIPTION]\n" msgstr " %s [FLAGGA]... [DBNAMN] [BESKRIVNING]\n" -#: createdb.c:255 +#: createdb.c:253 #, c-format msgid " -D, --tablespace=TABLESPACE default tablespace for the database\n" msgstr " -D, --tablespace=TABELLRYMD förvalt tabellutrymme för databasen\n" -#: createdb.c:256 +#: createdb.c:254 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo visa kommandon som skickas till servern\n" -#: createdb.c:257 +#: createdb.c:255 #, c-format msgid " -E, --encoding=ENCODING encoding for the database\n" msgstr " -E, --encoding=KODNING teckenkodning för databasen\n" -#: createdb.c:258 +#: createdb.c:256 #, c-format msgid " -l, --locale=LOCALE locale settings for the database\n" msgstr " -l, --locale=LOKAL lokalnamn för databasen\n" -#: createdb.c:259 +#: createdb.c:257 #, c-format msgid " --lc-collate=LOCALE LC_COLLATE setting for the database\n" msgstr " --lc-collate=LOKAL värde pÃ¥ LC_COLLATE för databasen\n" -#: createdb.c:260 +#: createdb.c:258 #, c-format msgid " --lc-ctype=LOCALE LC_CTYPE setting for the database\n" msgstr " --lc-ctype=LOKAL värde pÃ¥ LC_CTYPE för databasen\n" -#: createdb.c:261 +#: createdb.c:259 #, c-format msgid " -O, --owner=OWNER database user to own the new database\n" msgstr " -O, --owner=ÄGARE databasanvändare som äger nya databasen\n" -#: createdb.c:262 +#: createdb.c:260 #, c-format msgid " -T, --template=TEMPLATE template database to copy\n" msgstr " -T, --template=MALL databasmall att kopiera\n" -#: createdb.c:263 +#: createdb.c:261 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: createdb.c:264 +#: createdb.c:262 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: createdb.c:266 +#: createdb.c:264 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=VÄRDNAMN databasens värdnamn eller socketkatalog\n" -#: createdb.c:267 +#: createdb.c:265 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT databasserverns port\n" -#: createdb.c:268 +#: createdb.c:266 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=ANVÄNDARE användarnamn att ansluta som\n" -#: createdb.c:269 +#: createdb.c:267 #, c-format msgid " -w, --no-password never prompt for password\n" msgstr " -w, --no-password frÃ¥ga ej efter lösenord\n" -#: createdb.c:270 +#: createdb.c:268 #, c-format msgid " -W, --password force password prompt\n" msgstr " -W, --password framtvinga frÃ¥ga om lösenord\n" -#: createdb.c:271 +#: createdb.c:269 #, c-format msgid " --maintenance-db=DBNAME alternate maintenance database\n" msgstr " --maintenance-db=DBNAMN annat val av underhÃ¥llsdatabas\n" -#: createdb.c:272 +#: createdb.c:270 #, c-format msgid "" "\n" "By default, a database with the same name as the current user is created.\n" -msgstr "\nSom standard skapas en databas med samma namn som den nuvarande användares namn.\n" +msgstr "" +"\n" +"Som standard skapas en databas med samma namn som den nuvarande användares namn.\n" -#: createuser.c:189 +#: createuser.c:191 msgid "Enter name of role to add: " msgstr "Mata in namn pÃ¥ den roll som skall läggas till: " -#: createuser.c:206 +#: createuser.c:208 msgid "Enter password for new role: " msgstr "Mata in lösenord för den nya rollen: " -#: createuser.c:208 +#: createuser.c:210 msgid "Enter it again: " msgstr "Mata in det igen: " -#: createuser.c:211 +#: createuser.c:213 #, c-format msgid "Passwords didn't match.\n" msgstr "Lösenorden stämde inte överens.\n" -#: createuser.c:219 +#: createuser.c:221 msgid "Shall the new role be a superuser?" msgstr "Skall den nya rollen vara en superanvändare?" -#: createuser.c:234 +#: createuser.c:236 msgid "Shall the new role be allowed to create databases?" msgstr "Skall den nya rollen tillÃ¥tas skapa databaser?" -#: createuser.c:242 +#: createuser.c:244 msgid "Shall the new role be allowed to create more new roles?" msgstr "Skall den nya rollen tillÃ¥tas skapa fler nya roller?" -#: createuser.c:272 +#: createuser.c:274 #, c-format -msgid "%s: password encryption failed: %s" -msgstr "%s: misslyckades med lösenordskryptering: %s" +msgid "password encryption failed: %s" +msgstr "misslyckades med lösenordskryptering: %s" -#: createuser.c:327 +#: createuser.c:329 #, c-format -msgid "%s: creation of new role failed: %s" -msgstr "%s: misslyckades med att skapa ny roll: %s" +msgid "creation of new role failed: %s" +msgstr "misslyckades med att skapa ny roll: %s" -#: createuser.c:342 +#: createuser.c:343 #, c-format msgid "" "%s creates a new PostgreSQL role.\n" "\n" -msgstr "%s skapar en ny PostgreSQL-roll.\n\n" +msgstr "" +"%s skapar en ny PostgreSQL-roll.\n" +"\n" -#: createuser.c:344 dropuser.c:162 +#: createuser.c:345 dropuser.c:164 #, c-format msgid " %s [OPTION]... [ROLENAME]\n" msgstr " %s [FLAGGA]... [ROLLNAMN]\n" -#: createuser.c:346 +#: createuser.c:347 #, c-format msgid " -c, --connection-limit=N connection limit for role (default: no limit)\n" msgstr " -c, --connection-limit=N anslutningsgräns för roll (standard: ingen gräns)\n" -#: createuser.c:347 +#: createuser.c:348 #, c-format msgid " -d, --createdb role can create new databases\n" msgstr " -d, --createdb rollen kan skapa nya databaser\n" -#: createuser.c:348 +#: createuser.c:349 #, c-format msgid " -D, --no-createdb role cannot create databases (default)\n" msgstr " -D, --no-createdb rollen kan inte skapa databaser (standard)\n" -#: createuser.c:350 +#: createuser.c:351 #, c-format msgid " -g, --role=ROLE new role will be a member of this role\n" msgstr " -g, --role=ROLL nya rollen kommer bli medlem i denna roll\n" -#: createuser.c:351 +#: createuser.c:352 #, c-format msgid "" " -i, --inherit role inherits privileges of roles it is a\n" @@ -501,47 +529,47 @@ msgstr "" " -i, --inherit rollen ärver rättigheter frÃ¥n roller den\n" " är medlem i (standard)\n" -#: createuser.c:353 +#: createuser.c:354 #, c-format msgid " -I, --no-inherit role does not inherit privileges\n" msgstr " -I, --no-inherit rollen ärver inga rättigheter\n" -#: createuser.c:354 +#: createuser.c:355 #, c-format msgid " -l, --login role can login (default)\n" msgstr " -l, --login rollen kan logga in (standard)\n" -#: createuser.c:355 +#: createuser.c:356 #, c-format msgid " -L, --no-login role cannot login\n" msgstr " -L, --no-login rollen kan inte logga in\n" -#: createuser.c:356 +#: createuser.c:357 #, c-format msgid " -P, --pwprompt assign a password to new role\n" msgstr " -P, --pwprompt tilldela den nya rollen ett lösenord\n" -#: createuser.c:357 +#: createuser.c:358 #, c-format msgid " -r, --createrole role can create new roles\n" msgstr " -r, --createrole rollen kan skapa nya roller\n" -#: createuser.c:358 +#: createuser.c:359 #, c-format msgid " -R, --no-createrole role cannot create roles (default)\n" msgstr " -R, --no-createrole rollen kan inte skapa roller (standard)\n" -#: createuser.c:359 +#: createuser.c:360 #, c-format msgid " -s, --superuser role will be superuser\n" msgstr " -s, --superuser rollen blir en superanvändare\n" -#: createuser.c:360 +#: createuser.c:361 #, c-format msgid " -S, --no-superuser role will not be superuser (default)\n" msgstr " -S, --no-superuser rollen blir inte superanvändare (standard)\n" -#: createuser.c:362 +#: createuser.c:363 #, c-format msgid "" " --interactive prompt for missing role name and attributes rather\n" @@ -550,41 +578,41 @@ msgstr "" " --interactive frÃ¥ga efter rollnamn och egenskaper, snarare än\n" " att falla tillbaka pÃ¥ förval\n" -#: createuser.c:364 +#: createuser.c:365 #, c-format msgid " --replication role can initiate replication\n" msgstr " --replication rollen kan starta replikering\n" -#: createuser.c:365 +#: createuser.c:366 #, c-format msgid " --no-replication role cannot initiate replication\n" msgstr " --no-replication rollen fÃ¥r inte starta replikering\n" -#: createuser.c:370 +#: createuser.c:371 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to create)\n" msgstr " -U, --username=ANVÄNDARE användarnamn att ansluta som (ej den som skapas)\n" -#: dropdb.c:102 +#: dropdb.c:104 #, c-format -msgid "%s: missing required argument database name\n" -msgstr "%s: saknar nödvändigt databasnamn\n" +msgid "missing required argument database name" +msgstr "saknar nödvändigt databasnamn" -#: dropdb.c:117 +#: dropdb.c:119 #, c-format msgid "Database \"%s\" will be permanently removed.\n" msgstr "Databasen \"%s\" kommer att tas bort permanent.\n" -#: dropdb.c:118 dropuser.c:128 +#: dropdb.c:120 dropuser.c:130 msgid "Are you sure?" msgstr "Är du säker?" -#: dropdb.c:139 +#: dropdb.c:142 #, c-format -msgid "%s: database removal failed: %s" -msgstr "%s: borttagning av databas misslyckades: %s" +msgid "database removal failed: %s" +msgstr "borttagning av databas misslyckades: %s" -#: dropdb.c:154 +#: dropdb.c:156 #, c-format msgid "" "%s removes a PostgreSQL database.\n" @@ -593,48 +621,48 @@ msgstr "" "%s tar bort en PostgreSQL-databas.\n" "\n" -#: dropdb.c:156 +#: dropdb.c:158 #, c-format msgid " %s [OPTION]... DBNAME\n" msgstr " %s [FLAGGA]... DBNAMN\n" -#: dropdb.c:159 +#: dropdb.c:161 #, c-format msgid " -i, --interactive prompt before deleting anything\n" msgstr " -i, --interactive frÃ¥ga innan nÃ¥got tas bort\n" -#: dropdb.c:161 +#: dropdb.c:163 #, c-format msgid " --if-exists don't report error if database doesn't exist\n" msgstr " --if-exists felrapportera ej om databasen saknas\n" -#: dropuser.c:113 +#: dropuser.c:115 msgid "Enter name of role to drop: " msgstr "Mata inn namnet pÃ¥ den roll som skall tas bort: " -#: dropuser.c:119 +#: dropuser.c:121 #, c-format -msgid "%s: missing required argument role name\n" -msgstr "%s: saknar ett nödvändigt rollnamn\n" +msgid "missing required argument role name" +msgstr "saknar ett nödvändigt rollnamn" -#: dropuser.c:127 +#: dropuser.c:129 #, c-format msgid "Role \"%s\" will be permanently removed.\n" msgstr "Rollen \"%s\" kommer att tas bort permanent.\n" -#: dropuser.c:145 +#: dropuser.c:147 #, c-format -msgid "%s: removal of role \"%s\" failed: %s" -msgstr "%s: borttagning av rollen \"%s\" misslyckades: %s" +msgid "removal of role \"%s\" failed: %s" +msgstr "borttagning av rollen \"%s\" misslyckades: %s" -#: dropuser.c:160 +#: dropuser.c:162 #, c-format msgid "" "%s removes a PostgreSQL role.\n" "\n" msgstr "%s tar bort en PostgreSQL-roll.\n" -#: dropuser.c:165 +#: dropuser.c:167 #, c-format msgid "" " -i, --interactive prompt before deleting anything, and prompt for\n" @@ -643,211 +671,225 @@ msgstr "" " -i, --interactive frÃ¥ga innan nÃ¥got tas bort och frÃ¥ga efter\n" " rollnamn om sÃ¥dant saknas\n" -#: dropuser.c:168 +#: dropuser.c:170 #, c-format msgid " --if-exists don't report error if user doesn't exist\n" msgstr " --if-exists felrapportera ej om användaren saknas\n" -#: dropuser.c:173 +#: dropuser.c:175 #, c-format msgid " -U, --username=USERNAME user name to connect as (not the one to drop)\n" msgstr " -U, --username=ANVÄNDARE användare som ansluter (inte den som tas bort)\n" -#: pg_isready.c:142 +#: pg_isready.c:144 #, c-format -msgid "%s: %s" -msgstr "%s: %s" +msgid "%s" +msgstr "%s" -#: pg_isready.c:150 +#: pg_isready.c:152 #, c-format -msgid "%s: could not fetch default options\n" -msgstr "%s: kunde inte hämta förvalda värde.\n" +msgid "could not fetch default options" +msgstr "kunde inte hämta förvalda värde." -#: pg_isready.c:199 +#: pg_isready.c:201 #, c-format msgid "accepting connections\n" msgstr "accepterar anslutningar\n" -#: pg_isready.c:202 +#: pg_isready.c:204 #, c-format msgid "rejecting connections\n" msgstr "vägrar anslutningar\n" -#: pg_isready.c:205 +#: pg_isready.c:207 #, c-format msgid "no response\n" msgstr "inget svar\n" -#: pg_isready.c:208 +#: pg_isready.c:210 #, c-format msgid "no attempt\n" msgstr "inget försök\n" -#: pg_isready.c:211 +#: pg_isready.c:213 #, c-format msgid "unknown\n" msgstr "okänt\n" -#: pg_isready.c:221 +#: pg_isready.c:223 #, c-format msgid "" "%s issues a connection check to a PostgreSQL database.\n" "\n" -msgstr "%s utför en anslutningskontroll mot en PostgreSQL-databas.\n\n" +msgstr "" +"%s utför en anslutningskontroll mot en PostgreSQL-databas.\n" +"\n" -#: pg_isready.c:223 +#: pg_isready.c:225 #, c-format msgid " %s [OPTION]...\n" msgstr " %s [FLAGGA]...\n" -#: pg_isready.c:226 +#: pg_isready.c:228 #, c-format msgid " -d, --dbname=DBNAME database name\n" msgstr " -d, --dbname=DBNAMN databasens namn\n" -#: pg_isready.c:227 +#: pg_isready.c:229 #, c-format msgid " -q, --quiet run quietly\n" msgstr " -q, --quiet tyst körning\n" -#: pg_isready.c:228 +#: pg_isready.c:230 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: pg_isready.c:229 +#: pg_isready.c:231 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: pg_isready.c:232 +#: pg_isready.c:234 #, c-format msgid " -h, --host=HOSTNAME database server host or socket directory\n" msgstr " -h, --host=VÄRDNAMN databasens värdnamn eller socketkatalog\n" -#: pg_isready.c:233 +#: pg_isready.c:235 #, c-format msgid " -p, --port=PORT database server port\n" msgstr " -p, --port=PORT databasserverns port\n" -#: pg_isready.c:234 +#: pg_isready.c:236 #, c-format msgid " -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n" msgstr " -t, --timeout=SEK sekunder att vänta pÃ¥ anslutning; 0 stänger av (förval: %s)\n" -#: pg_isready.c:235 +#: pg_isready.c:237 #, c-format msgid " -U, --username=USERNAME user name to connect as\n" msgstr " -U, --username=ANVÄNDARE användarnamn att ansluta som\n" -#: reindexdb.c:160 +#: reindexdb.c:168 +#, c-format +msgid "cannot reindex all databases and a specific one at the same time" +msgstr "kan inte omindexera alla databaser och samtidigt en specifik databas" + +#: reindexdb.c:173 #, c-format -msgid "%s: cannot reindex all databases and a specific one at the same time\n" -msgstr "%s: kan inte omindexera alla databaser och samtidigt en specifik databas\n" +msgid "cannot reindex all databases and system catalogs at the same time" +msgstr "kan inte omindexera alla databaser samtidigt med systemkatalogerna" -#: reindexdb.c:165 +#: reindexdb.c:178 #, c-format -msgid "%s: cannot reindex all databases and system catalogs at the same time\n" -msgstr "%s: kan inte omindexera alla databaser samtidigt med systemkatalogerna\n" +msgid "cannot reindex specific schema(s) in all databases" +msgstr "kan inte omindexera angivna scheman i alla databaser" -#: reindexdb.c:170 +#: reindexdb.c:183 #, c-format -msgid "%s: cannot reindex specific schema(s) in all databases\n" -msgstr "%s: kan inte omindexera angivna scheman i alla databaser\n" +msgid "cannot reindex specific table(s) in all databases" +msgstr "Kan inte indexera specifik tabell i alla databaser" -#: reindexdb.c:175 +#: reindexdb.c:188 #, c-format -msgid "%s: cannot reindex specific table(s) in all databases\n" -msgstr "%s: Kan inte indexera specifik tabell i alla databaser\n" +msgid "cannot reindex specific index(es) in all databases" +msgstr "Kan inte omindexera angivet index i alla databaser" -#: reindexdb.c:180 +#: reindexdb.c:199 #, c-format -msgid "%s: cannot reindex specific index(es) in all databases\n" -msgstr "%s: Kan inte omindexera angivet index i alla databaser\n" +msgid "cannot reindex specific schema(s) and system catalogs at the same time" +msgstr "kan inte omindexera angivna scheman och systemkataloger pÃ¥ samma gÃ¥ng" -#: reindexdb.c:191 +#: reindexdb.c:204 #, c-format -msgid "%s: cannot reindex specific schema(s) and system catalogs at the same time\n" -msgstr "%s: kan inte omindexera angivna scheman och systemkataloger pÃ¥ samma gÃ¥ng\n" +msgid "cannot reindex specific table(s) and system catalogs at the same time" +msgstr "kan inte omindexera specifik tabell och systemkatalogerna samtidigt" -#: reindexdb.c:196 +#: reindexdb.c:209 #, c-format -msgid "%s: cannot reindex specific table(s) and system catalogs at the same time\n" -msgstr "%s: kan inte omindexera specifik tabell och systemkatalogerna samtidigt\n" +msgid "cannot reindex specific index(es) and system catalogs at the same time" +msgstr "kan inte omindexera angivna index och systemkatalogerna samtidigt." -#: reindexdb.c:201 +#: reindexdb.c:298 vacuumdb.c:412 vacuumdb.c:420 vacuumdb.c:427 vacuumdb.c:434 #, c-format -msgid "%s: cannot reindex specific index(es) and system catalogs at the same time\n" -msgstr "%s: kan inte omindexera angivna index och systemkatalogerna samtidigt.\n" +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL %s" +msgstr "flaggan \"%s\" kan inte användas pÃ¥ serverversioner äldre än PostgreSQL %s" -#: reindexdb.c:307 +#: reindexdb.c:326 #, c-format -msgid "%s: reindexing of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: omindexering av tabell \"%s\" i databasen \"%s\" misslyckades: %s" +msgid "reindexing of table \"%s\" in database \"%s\" failed: %s" +msgstr "omindexering av tabell \"%s\" i databasen \"%s\" misslyckades: %s" -#: reindexdb.c:310 +#: reindexdb.c:329 #, c-format -msgid "%s: reindexing of index \"%s\" in database \"%s\" failed: %s" -msgstr "%s: omindexering av index \"%s\" i databasen \"%s\" misslyckades: %s" +msgid "reindexing of index \"%s\" in database \"%s\" failed: %s" +msgstr "omindexering av index \"%s\" i databasen \"%s\" misslyckades: %s" -#: reindexdb.c:313 +#: reindexdb.c:332 #, c-format -msgid "%s: reindexing of schema \"%s\" in database \"%s\" failed: %s" -msgstr "%s: omindexering av schemat \"%s\" i databasen \"%s\" misslyckades: %s" +msgid "reindexing of schema \"%s\" in database \"%s\" failed: %s" +msgstr "omindexering av schemat \"%s\" i databasen \"%s\" misslyckades: %s" -#: reindexdb.c:316 +#: reindexdb.c:335 #, c-format -msgid "%s: reindexing of database \"%s\" failed: %s" -msgstr "%s: omindexering av databasen \"%s\" misslyckades: %s" +msgid "reindexing of database \"%s\" failed: %s" +msgstr "omindexering av databasen \"%s\" misslyckades: %s" -#: reindexdb.c:349 +#: reindexdb.c:369 #, c-format msgid "%s: reindexing database \"%s\"\n" msgstr "%s: omindexering av databasen \"%s\"\n" -#: reindexdb.c:388 +#: reindexdb.c:412 #, c-format -msgid "%s: reindexing of system catalogs failed: %s" -msgstr "%s: omindexering av systemkatalogerna misslyckades: %s" +msgid "reindexing of system catalogs failed: %s" +msgstr "omindexering av systemkatalogerna misslyckades: %s" -#: reindexdb.c:400 +#: reindexdb.c:424 #, c-format msgid "" "%s reindexes a PostgreSQL database.\n" "\n" -msgstr "%s indexerar om en PostgreSQL-databas.\n\n" +msgstr "" +"%s indexerar om en PostgreSQL-databas.\n" +"\n" -#: reindexdb.c:404 +#: reindexdb.c:428 #, c-format msgid " -a, --all reindex all databases\n" msgstr " -a, --all indexera om alla databaser\n" -#: reindexdb.c:405 +#: reindexdb.c:429 +#, c-format +msgid " --concurrently reindex concurrently\n" +msgstr " --concurrently indexer om utan att lÃ¥sa\n" + +#: reindexdb.c:430 #, c-format msgid " -d, --dbname=DBNAME database to reindex\n" msgstr " -d, --dbname=DBNAME databas att indexera om\n" -#: reindexdb.c:407 +#: reindexdb.c:432 #, c-format msgid " -i, --index=INDEX recreate specific index(es) only\n" msgstr " -i, --index=INDEX Ã¥terskapa enbart angivna index\n" -#: reindexdb.c:409 +#: reindexdb.c:434 #, c-format msgid " -s, --system reindex system catalogs\n" msgstr " -s, --system indexera om systemkatalogerna\n" -#: reindexdb.c:410 +#: reindexdb.c:435 #, c-format msgid " -S, --schema=SCHEMA reindex specific schema(s) only\n" msgstr " -S, --schema=SCHEMA indexera enbart om angivna scheman\n" -#: reindexdb.c:411 +#: reindexdb.c:436 #, c-format msgid " -t, --table=TABLE reindex specific table(s) only\n" msgstr " -t, --table=TABELL indexera endast om angivna tabeller\n" -#: reindexdb.c:422 +#: reindexdb.c:447 #, c-format msgid "" "\n" @@ -856,69 +898,74 @@ msgstr "" "\n" "Läs beskrivningen av SQL-kommandot REINDEX för detaljer.\n" -#: vacuumdb.c:195 +#: vacuumdb.c:207 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "antalet parallella jobb mÃ¥ste vara minst 1" + +#: vacuumdb.c:212 +#, c-format +msgid "too many parallel jobs requested (maximum: %d)" +msgstr "för mÃ¥nga parallella job (maximum: %d)" + +#: vacuumdb.c:233 #, c-format -msgid "%s: number of parallel jobs must be at least 1\n" -msgstr "%s: antalet parallella jobb mÃ¥ste vara minst 1\n" +msgid "minimum transaction ID age must be at least 1" +msgstr "minimal transaktions-ID-Ã¥lder mÃ¥ste vara minst 1" -#: vacuumdb.c:201 +#: vacuumdb.c:241 #, c-format -msgid "%s: too many parallel jobs requested (maximum: %d)\n" -msgstr "%s: för mÃ¥nga parallella job (maximum: %d)\n" +msgid "minimum multixact ID age must be at least 1" +msgstr "minimal multixact-ID-Ã¥lder mÃ¥ste vara minst 1" -#: vacuumdb.c:240 vacuumdb.c:246 +#: vacuumdb.c:273 vacuumdb.c:279 vacuumdb.c:285 #, c-format -msgid "%s: cannot use the \"%s\" option when performing only analyze\n" -msgstr "%s: flaggan \"%s\" kan inte användas vid enbart analys\n" +msgid "cannot use the \"%s\" option when performing only analyze" +msgstr "flaggan \"%s\" kan inte användas vid enbart analys" -#: vacuumdb.c:263 +#: vacuumdb.c:302 #, c-format -msgid "%s: cannot vacuum all databases and a specific one at the same time\n" -msgstr "%s: kan inte städa alla databaser och endast en angiven pÃ¥ samma gÃ¥ng\n" +msgid "cannot vacuum all databases and a specific one at the same time" +msgstr "kan inte städa alla databaser och endast en angiven pÃ¥ samma gÃ¥ng" -#: vacuumdb.c:269 +#: vacuumdb.c:307 #, c-format -msgid "%s: cannot vacuum specific table(s) in all databases\n" -msgstr "%s: kan inte städa en specifik tabell i alla databaser.\n" +msgid "cannot vacuum specific table(s) in all databases" +msgstr "kan inte städa en specifik tabell i alla databaser." -#: vacuumdb.c:355 +#: vacuumdb.c:398 msgid "Generating minimal optimizer statistics (1 target)" msgstr "Skapar minimal optimeringsstatistik (1 mÃ¥l)" -#: vacuumdb.c:356 +#: vacuumdb.c:399 msgid "Generating medium optimizer statistics (10 targets)" msgstr "Skapar medium optimeringsstatistik (10 mÃ¥l)" -#: vacuumdb.c:357 +#: vacuumdb.c:400 msgid "Generating default (full) optimizer statistics" msgstr "Skapar förvald (full) optimeringsstatistik" -#: vacuumdb.c:369 +#: vacuumdb.c:442 #, c-format msgid "%s: processing database \"%s\": %s\n" msgstr "%s: processar databasen \"%s\": %s\n" -#: vacuumdb.c:372 +#: vacuumdb.c:445 #, c-format msgid "%s: vacuuming database \"%s\"\n" msgstr "%s: städar databasen \"%s\".\n" -#: vacuumdb.c:708 +#: vacuumdb.c:939 #, c-format -msgid "%s: vacuuming of table \"%s\" in database \"%s\" failed: %s" -msgstr "%s: städning av tabell \"%s\" i databasen \"%s\" misslyckades: %s" +msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" +msgstr "städning av tabell \"%s\" i databasen \"%s\" misslyckades: %s" -#: vacuumdb.c:711 vacuumdb.c:828 +#: vacuumdb.c:942 vacuumdb.c:1077 #, c-format -msgid "%s: vacuuming of database \"%s\" failed: %s" -msgstr "%s: städning av databasen \"%s\" misslyckades: %s" +msgid "vacuuming of database \"%s\" failed: %s" +msgstr "städning av databasen \"%s\" misslyckades: %s" -#: vacuumdb.c:942 -#, c-format -msgid "%s: invalid socket: %s" -msgstr "%s: ogiltigt uttag: %s" - -#: vacuumdb.c:951 +#: vacuumdb.c:1212 #, c-format msgid "" "%s cleans and analyzes a PostgreSQL database.\n" @@ -927,67 +974,87 @@ msgstr "" "%s städar och analyserar en PostgreSQL-databas.\n" "\n" -#: vacuumdb.c:955 +#: vacuumdb.c:1216 #, c-format msgid " -a, --all vacuum all databases\n" msgstr " -a, --all städa i alla databaser\n" -#: vacuumdb.c:956 +#: vacuumdb.c:1217 #, c-format msgid " -d, --dbname=DBNAME database to vacuum\n" msgstr " -d, --dbname=DBNAMN databas att städa i\n" -#: vacuumdb.c:957 +#: vacuumdb.c:1218 +#, c-format +msgid " --disable-page-skipping disable all page-skipping behavior\n" +msgstr " --disable-page-skipping stäng av alla sidöverhoppande beteeenden\n" + +#: vacuumdb.c:1219 #, c-format msgid " -e, --echo show the commands being sent to the server\n" msgstr " -e, --echo visa kommandon som skickas till servern\n" -#: vacuumdb.c:958 +#: vacuumdb.c:1220 #, c-format msgid " -f, --full do full vacuuming\n" msgstr " -f, --full utför full städning\n" -#: vacuumdb.c:959 +#: vacuumdb.c:1221 #, c-format msgid " -F, --freeze freeze row transaction information\n" msgstr " -F, --freeze frys information om radtransaktioner\n" -#: vacuumdb.c:960 +#: vacuumdb.c:1222 #, c-format msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" msgstr " -j, --jobs=NUM använd sÃ¥ här mÃ¥nga samtida anslutningar för städning\n" -#: vacuumdb.c:961 +#: vacuumdb.c:1223 +#, c-format +msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" +msgstr " --min-mxid-age=MXID_Ã…LDER minimal multixact-ID-Ã¥lder i tabeller som skall städas\n" + +#: vacuumdb.c:1224 +#, c-format +msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" +msgstr " --min-xid-age=XID_Ã…LDER minimal transaktions-ID-Ã¥lder i tabeller som skall städas\n" + +#: vacuumdb.c:1225 #, c-format msgid " -q, --quiet don't write any messages\n" msgstr " -q, --quiet skriv inte ut nÃ¥gra meddelanden\n" -#: vacuumdb.c:962 +#: vacuumdb.c:1226 +#, c-format +msgid " --skip-locked skip relations that cannot be immediately locked\n" +msgstr " --skip-locked hoppa äver relationer som inte kan lÃ¥sas direkt\n" + +#: vacuumdb.c:1227 #, c-format msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" msgstr " -t, --table='TABELL[(KOLUMNER)]' städa enbart i dessa tabeller\n" -#: vacuumdb.c:963 +#: vacuumdb.c:1228 #, c-format msgid " -v, --verbose write a lot of output\n" msgstr " -v, --verbose skriv massor med utdata\n" -#: vacuumdb.c:964 +#: vacuumdb.c:1229 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version visa versionsinformation, avsluta sedan\n" -#: vacuumdb.c:965 +#: vacuumdb.c:1230 #, c-format msgid " -z, --analyze update optimizer statistics\n" msgstr " -z, --analyze uppdatera optimeringsstatistik\n" -#: vacuumdb.c:966 +#: vacuumdb.c:1231 #, c-format msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" msgstr " -Z, --analyze-only uppdatera bara optimeringsstatistik; ingen städning\n" -#: vacuumdb.c:967 +#: vacuumdb.c:1232 #, c-format msgid "" " --analyze-in-stages only update optimizer statistics, in multiple\n" @@ -996,12 +1063,12 @@ msgstr "" " --analyze-in-stages uppdatera bara optimeringsstatistik, men i\n" " flera steg för snabbare resultat; ingen städning\n" -#: vacuumdb.c:969 +#: vacuumdb.c:1234 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help visa denna hjälp, avsluta sedan\n" -#: vacuumdb.c:977 +#: vacuumdb.c:1242 #, c-format msgid "" "\n" @@ -1010,39 +1077,59 @@ msgstr "" "\n" "Läs beskrivningen av SQL-kommandot VACUUM för detaljer.\n" -#~ msgid "%s: cannot use the \"freeze\" option when performing only analyze\n" -#~ msgstr "%s: Växeln \"freeze\" kan inte utföras med enbart analys.\n" - -#~ msgid " -d, --dbname=DBNAME database from which to remove the language\n" -#~ msgstr " -d, --dbname=DBNAMN databas frÃ¥n vilken sprÃ¥ket skall tas bort\n" +#~ msgid "%s: too many command-line arguments (first is \"%s\")\n" +#~ msgstr "%s: för mÃ¥nga kommandoradsargument (första är \"%s\")\n" #~ msgid "" -#~ "%s removes a procedural language from a database.\n" #~ "\n" +#~ "Report bugs to .\n" #~ msgstr "" -#~ "%s tar bort ett procedursprÃ¥k frÃ¥n en databas.\n" #~ "\n" +#~ "Rapportera fel till .\n" -#~ msgid "%s: language removal failed: %s" -#~ msgstr "%s: Borttagning av sprÃ¥k misslyckades: %s" +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: frÃ¥ga misslyckades: %s" -#~ msgid "%s: language \"%s\" is not installed in database \"%s\"\n" -#~ msgstr "%s: SprÃ¥k \"%s\" är inte installerat i databasen \"%s\".\n" +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: frÃ¥gan var: %s\n" -#~ msgid " -N, --unencrypted do not encrypt stored password\n" -#~ msgstr " -N, --unencrypted lösenordet sparas okrypterat\n" +#~ msgid "%s: query returned %d row instead of one: %s\n" +#~ msgid_plural "%s: query returned %d rows instead of one: %s\n" +#~ msgstr[0] "%s: frÃ¥ga gav %d rad istället för en: %s\n" +#~ msgstr[1] "%s: frÃ¥ga gav %d rader istället för en: %s\n" -#~ msgid " -E, --encrypted encrypt stored password\n" -#~ msgstr " -E, --encrypted lösenordet skall sparas krypterat\n" +#~ msgid "%s: \"%s\" is not a valid encoding name\n" +#~ msgstr "%s: \"%s\" är inte en giltig teckenkodning.\n" -#~ msgid " -l, --list show a list of currently installed languages\n" -#~ msgstr " -l, --list lista alla nu installerade sprÃ¥k\n" +#~ msgid "%s: %s" +#~ msgstr "%s: %s" -#~ msgid " -d, --dbname=DBNAME database to install language in\n" -#~ msgstr " -d, --dbname=DBNAMN databas där sprÃ¥ket installeras\n" +#~ msgid "%s: invalid socket: %s" +#~ msgstr "%s: ogiltigt uttag: %s" -#~ msgid " %s [OPTION]... LANGNAME [DBNAME]\n" -#~ msgstr " %s [FLAGGA]... SPRÃ…K [DBNAMN]\n" +#~ msgid "Name" +#~ msgstr "Namn" + +#~ msgid "no" +#~ msgstr "nej" + +#~ msgid "yes" +#~ msgstr "ja" + +#~ msgid "Trusted?" +#~ msgstr "Tillförlitligt?" + +#~ msgid "Procedural Languages" +#~ msgstr "ProcedursprÃ¥k" + +#~ msgid "%s: missing required argument language name\n" +#~ msgstr "%s: Saknar nödvändigt sprÃ¥knamnsargument.\n" + +#~ msgid "%s: language \"%s\" is already installed in database \"%s\"\n" +#~ msgstr "%s: SprÃ¥ket \"%s\" är redan installerat i databasen \"%s\".\n" + +#~ msgid "%s: language installation failed: %s" +#~ msgstr "%s: SprÃ¥kinstallation misslyckades: %s" #~ msgid "" #~ "%s installs a procedural language into a PostgreSQL database.\n" @@ -1051,26 +1138,42 @@ msgstr "" #~ "%s installerar ett procedursprÃ¥k i en PostgreSQL-databas.\n" #~ "\n" -#~ msgid "%s: language installation failed: %s" -#~ msgstr "%s: SprÃ¥kinstallation misslyckades: %s" +#~ msgid " %s [OPTION]... LANGNAME [DBNAME]\n" +#~ msgstr " %s [FLAGGA]... SPRÃ…K [DBNAMN]\n" -#~ msgid "%s: language \"%s\" is already installed in database \"%s\"\n" -#~ msgstr "%s: SprÃ¥ket \"%s\" är redan installerat i databasen \"%s\".\n" +#~ msgid " -d, --dbname=DBNAME database to install language in\n" +#~ msgstr " -d, --dbname=DBNAMN databas där sprÃ¥ket installeras\n" -#~ msgid "%s: missing required argument language name\n" -#~ msgstr "%s: Saknar nödvändigt sprÃ¥knamnsargument.\n" +#~ msgid " -l, --list show a list of currently installed languages\n" +#~ msgstr " -l, --list lista alla nu installerade sprÃ¥k\n" -#~ msgid "Procedural Languages" -#~ msgstr "ProcedursprÃ¥k" +#~ msgid " -E, --encrypted encrypt stored password\n" +#~ msgstr " -E, --encrypted lösenordet skall sparas krypterat\n" -#~ msgid "Trusted?" -#~ msgstr "Tillförlitligt?" +#~ msgid " -N, --unencrypted do not encrypt stored password\n" +#~ msgstr " -N, --unencrypted lösenordet sparas okrypterat\n" -#~ msgid "yes" -#~ msgstr "ja" +#~ msgid "%s: language \"%s\" is not installed in database \"%s\"\n" +#~ msgstr "%s: SprÃ¥k \"%s\" är inte installerat i databasen \"%s\".\n" -#~ msgid "no" -#~ msgstr "nej" +#~ msgid "%s: language removal failed: %s" +#~ msgstr "%s: Borttagning av sprÃ¥k misslyckades: %s" -#~ msgid "Name" -#~ msgstr "Namn" +#~ msgid "" +#~ "%s removes a procedural language from a database.\n" +#~ "\n" +#~ msgstr "" +#~ "%s tar bort ett procedursprÃ¥k frÃ¥n en databas.\n" +#~ "\n" + +#~ msgid " -d, --dbname=DBNAME database from which to remove the language\n" +#~ msgstr " -d, --dbname=DBNAMN databas frÃ¥n vilken sprÃ¥ket skall tas bort\n" + +#~ msgid "%s: cannot use the \"freeze\" option when performing only analyze\n" +#~ msgstr "%s: Växeln \"freeze\" kan inte utföras med enbart analys.\n" + +#~ msgid "cannot use the \"%s\" option on server versions older than PostgreSQL 12" +#~ msgstr "flaggan \"%s\" kan inte användas pÃ¥ serverversioner äldre än PostgresSQL 12" + +#~ msgid "cannot use the \"%s\" option on server versions older than PostgreSQL 9.6" +#~ msgstr "flaggan \"%s\" kan inte användas pÃ¥ serverversioner äldre än PostgreSQL 9.6" diff --git a/src/bin/scripts/po/tr.po b/src/bin/scripts/po/tr.po new file mode 100644 index 00000000000..f815827916c --- /dev/null +++ b/src/bin/scripts/po/tr.po @@ -0,0 +1,1224 @@ +# translation of pgscripts-tr.po to Turkish +# Devrim GUNDUZ , 2004, 2005, 2006, 2007. +# Nicolai Tufar , 2005, 2006, 2007. +# İbrahim Edib Kökdemir <>, 2018. +# Abdullah G. GÜLNER <>, 2018. +msgid "" +msgstr "" +"Project-Id-Version: pgscripts-tr\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:47+0000\n" +"PO-Revision-Date: 2019-06-13 14:10+0300\n" +"Last-Translator: Abdullah G. GüLNER\n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Basepath: /home/ntufar/pg/pgsql/src/bin/scripts\n" +"X-Poedit-SearchPath-0: /home/ntufar/pg/pgsql/src/bin/scripts\n" + +#: ../../../src/fe_utils/logging.c:182 +#, c-format +msgid "fatal: " +msgstr "ölümcül (fatal): " + +#: ../../../src/fe_utils/logging.c:189 +#, c-format +msgid "error: " +msgstr "hata: " + +#: ../../../src/fe_utils/logging.c:196 +#, c-format +msgid "warning: " +msgstr "uyarı: " + +#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75 +#: ../../common/fe_memutils.c:98 +#, c-format +msgid "out of memory\n" +msgstr "bellek yetersiz\n" + +#: ../../common/fe_memutils.c:92 +#, c-format +msgid "cannot duplicate null pointer (internal error)\n" +msgstr "null pointer duplicate edilemiyor (iç hata)\n" + +#: ../../common/username.c:43 +#, c-format +msgid "could not look up effective user ID %ld: %s" +msgstr "geçerli kullanıcı ID si bulunamadı %ld: %s" + +#: ../../common/username.c:45 +msgid "user does not exist" +msgstr "kullanıcı mevcut deÄŸil" + +#: ../../common/username.c:60 +#, c-format +msgid "user name lookup failure: error code %lu" +msgstr "kullanıcı adı arama baÅŸarısız: hata kodu %lu" + +#: ../../fe_utils/print.c:353 +#, c-format +msgid "(%lu row)" +msgid_plural "(%lu rows)" +msgstr[0] "(%lu satır)" +msgstr[1] "(%lu satır)" + +#: ../../fe_utils/print.c:3058 +#, c-format +msgid "Interrupted\n" +msgstr "kesildi\n" + +#: ../../fe_utils/print.c:3122 +#, c-format +msgid "Cannot add header to table content: column count of %d exceeded.\n" +msgstr "B aÅŸlık tablo içeriÄŸine eklenemedi: %d kolon sayısı aşıldı.\n" + +#: ../../fe_utils/print.c:3162 +#, c-format +msgid "Cannot add cell to table content: total cell count of %d exceeded.\n" +msgstr "Hücre tablo içeriÄŸine eklenemedi: %d olan toplan hücre sayısı açıldı.\n" + +#: ../../fe_utils/print.c:3417 +#, c-format +msgid "invalid output format (internal error): %d" +msgstr "geçersiz çıktı biçimi (iç hata): %d" + +#: clusterdb.c:113 clusterdb.c:132 createdb.c:121 createdb.c:140 +#: createuser.c:168 createuser.c:183 dropdb.c:96 dropdb.c:105 dropdb.c:113 +#: dropuser.c:92 dropuser.c:107 dropuser.c:122 pg_isready.c:95 pg_isready.c:109 +#: reindexdb.c:139 reindexdb.c:158 vacuumdb.c:246 vacuumdb.c:265 +#, c-format +msgid "Try \"%s --help\" for more information.\n" +msgstr "Daha fazla bilgi için \"%s --help\" komutunu deneyiniz.\n" + +#: clusterdb.c:130 createdb.c:138 createuser.c:181 dropdb.c:111 dropuser.c:105 +#: pg_isready.c:107 reindexdb.c:156 vacuumdb.c:263 +#, c-format +msgid "too many command-line arguments (first is \"%s\")" +msgstr "çok sayıda komut satırı argümanı (ilki \"%s\")" + +#: clusterdb.c:142 +#, c-format +msgid "cannot cluster all databases and a specific one at the same time" +msgstr "aynı anda tüm veritabanları ve de belirli bir tanesi cluster edilemez" + +#: clusterdb.c:148 +#, c-format +msgid "cannot cluster specific table(s) in all databases" +msgstr "tüm veritabanlarındaki belirli tablo(lar) cluster edilemez" + +#: clusterdb.c:216 +#, c-format +msgid "clustering of table \"%s\" in database \"%s\" failed: %s" +msgstr "\"%2$s\" veritabanındaki \"%1$s\"tablosunun cluster iÅŸlemi baÅŸarısız oldu: %3$s" + +#: clusterdb.c:219 +#, c-format +msgid "clustering of database \"%s\" failed: %s" +msgstr "\"%s\" veritabanının cluster iÅŸlemi baÅŸarısız oldu: %s" + +#: clusterdb.c:252 +#, c-format +msgid "%s: clustering database \"%s\"\n" +msgstr "%s: \"%s\" veritabanı cluster ediliyor\n" + +#: clusterdb.c:273 +#, c-format +msgid "" +"%s clusters all previously clustered tables in a database.\n" +"\n" +msgstr "" +"%s komutu bir veritabanında daha önceden cluster edilmiÅŸ tüm tabloları cluster eder.\n" +"\n" + +#: clusterdb.c:274 createdb.c:250 createuser.c:344 dropdb.c:157 dropuser.c:163 +#: pg_isready.c:224 reindexdb.c:425 vacuumdb.c:1213 +#, c-format +msgid "Usage:\n" +msgstr "Kullanımı:\n" + +#: clusterdb.c:275 reindexdb.c:426 vacuumdb.c:1214 +#, c-format +msgid " %s [OPTION]... [DBNAME]\n" +msgstr " %s [SEÇENEK]... [VERİTABANI_ADI]\n" + +#: clusterdb.c:276 createdb.c:252 createuser.c:346 dropdb.c:159 dropuser.c:165 +#: pg_isready.c:227 reindexdb.c:427 vacuumdb.c:1215 +#, c-format +msgid "" +"\n" +"Options:\n" +msgstr "" +"\n" +"Seçenekler:\n" + +#: clusterdb.c:277 +#, c-format +msgid " -a, --all cluster all databases\n" +msgstr " -a, --all tüm veritabanlarını cluster eder\n" + +#: clusterdb.c:278 +#, c-format +msgid " -d, --dbname=DBNAME database to cluster\n" +msgstr " -d, --dbname=VERİTABANI_ADI cluster edilecek veritabanı adı\n" + +#: clusterdb.c:279 createuser.c:350 dropdb.c:160 dropuser.c:166 reindexdb.c:431 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo sunucuya gönderilen komutları göster\n" + +#: clusterdb.c:280 reindexdb.c:433 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet hiçbir ileti yazma\n" + +#: clusterdb.c:281 +#, c-format +msgid " -t, --table=TABLE cluster specific table(s) only\n" +msgstr " -t, --table=TABLO_ADI sadece belirli (bir) tabloyu/tabloları cluster eder\n" + +#: clusterdb.c:282 reindexdb.c:437 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose bolca çıktı yaz\n" + +#: clusterdb.c:283 createuser.c:362 dropdb.c:162 dropuser.c:169 reindexdb.c:438 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini gösterir ve sonra çıkar\n" + +#: clusterdb.c:284 createuser.c:367 dropdb.c:164 dropuser.c:171 reindexdb.c:439 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: clusterdb.c:285 createdb.c:263 createuser.c:368 dropdb.c:165 dropuser.c:172 +#: pg_isready.c:233 reindexdb.c:440 vacuumdb.c:1235 +#, c-format +msgid "" +"\n" +"Connection options:\n" +msgstr "" +"\n" +"BaÄŸlantı seçenekleri:\n" + +#: clusterdb.c:286 createuser.c:369 dropdb.c:166 dropuser.c:173 reindexdb.c:441 +#: vacuumdb.c:1236 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME veritabanı sunucusu adresi ya da soket dizini\n" + +#: clusterdb.c:287 createuser.c:370 dropdb.c:167 dropuser.c:174 reindexdb.c:442 +#: vacuumdb.c:1237 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT veritabanı sunucusunun portu\n" + +#: clusterdb.c:288 dropdb.c:168 reindexdb.c:443 vacuumdb.c:1238 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı\n" + +#: clusterdb.c:289 createuser.c:372 dropdb.c:169 dropuser.c:176 reindexdb.c:444 +#: vacuumdb.c:1239 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password parola sorma\n" + +#: clusterdb.c:290 createuser.c:373 dropdb.c:170 dropuser.c:177 reindexdb.c:445 +#: vacuumdb.c:1240 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password parola sorulmasını saÄŸla\n" + +#: clusterdb.c:291 dropdb.c:171 reindexdb.c:446 vacuumdb.c:1241 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=VTADI alternatif bakım veritabanı\n" + +#: clusterdb.c:292 +#, c-format +msgid "" +"\n" +"Read the description of the SQL command CLUSTER for details.\n" +msgstr "" +"\n" +"Ayrıntılar için bir SQL komutu olan CLUSTER'in açıklamasını okuyabilirsiniz.\n" + +#: clusterdb.c:293 createdb.c:271 createuser.c:374 dropdb.c:172 dropuser.c:178 +#: pg_isready.c:238 reindexdb.c:448 vacuumdb.c:1243 +#, c-format +msgid "" +"\n" +"Report bugs to .\n" +msgstr "" +"\n" +"Hataları adresine bildirebilirsiniz.\n" + +#: common.c:84 common.c:130 +msgid "Password: " +msgstr "Parola: " + +#: common.c:117 +#, c-format +msgid "could not connect to database %s: out of memory" +msgstr "%s veritabanına baÄŸlanılamadı: bellek yetersiz" + +#: common.c:144 +#, c-format +msgid "could not connect to database %s: %s" +msgstr "%s veritabanına baÄŸlanılamadı: %s" + +#: common.c:197 common.c:223 +#, c-format +msgid "query failed: %s" +msgstr "sorgu baÅŸarısız oldu: %s" + +#: common.c:198 common.c:224 +#, c-format +msgid "query was: %s" +msgstr "sorgu ÅŸu idi: %s" + +#: common.c:347 +#, c-format +msgid "query returned %d row instead of one: %s" +msgid_plural "query returned %d rows instead of one: %s" +msgstr[0] "sorgu 1 yerine %d satır döndürdü: %s" +msgstr[1] "sorgu 1 yerine %d satır döndürdü: %s" + +#. translator: abbreviation for "yes" +#: common.c:372 +msgid "y" +msgstr "e" + +#. translator: abbreviation for "no" +#: common.c:374 +msgid "n" +msgstr "h" + +#. translator: This is a question followed by the translated options for +#. "yes" and "no". +#: common.c:384 +#, c-format +msgid "%s (%s/%s) " +msgstr "%s (%s/%s) " + +#: common.c:398 +#, c-format +msgid "Please answer \"%s\" or \"%s\".\n" +msgstr "Lütfen yanıtlayınız: \"%s\" veya \"%s\".\n" + +#: common.c:477 common.c:514 +#, c-format +msgid "Cancel request sent\n" +msgstr "İptal isteÄŸi gönderildi\n" + +#: common.c:480 common.c:518 +#, c-format +msgid "Could not send cancel request: %s" +msgstr "İptal isteÄŸi gönderilemedi: %s" + +#: createdb.c:148 +#, c-format +msgid "only one of --locale and --lc-ctype can be specified" +msgstr "--locale ve --lc-ctype seçeneklerinden sadece birisi belirtilebilir" + +#: createdb.c:153 +#, c-format +msgid "only one of --locale and --lc-collate can be specified" +msgstr "--locale ve --lc-collate seçeneklerinden sadece birisi belirtilebilir" + +#: createdb.c:164 +#, c-format +msgid "\"%s\" is not a valid encoding name" +msgstr "\"%s\" geçerli bir dil kodlaması adı deÄŸildir" + +#: createdb.c:212 +#, c-format +msgid "database creation failed: %s" +msgstr "veritabanı yaratma baÅŸarısız oldu: %s" + +#: createdb.c:231 +#, c-format +msgid "comment creation failed (database was created): %s" +msgstr "yorum yaratma iÅŸlemi baÅŸarısız oldu (veritabanı yaratıldı): %s" + +#: createdb.c:249 +#, c-format +msgid "" +"%s creates a PostgreSQL database.\n" +"\n" +msgstr "" +"%s bir PostgreSQL veritabanı yaratır.\n" +"\n" + +#: createdb.c:251 +#, c-format +msgid " %s [OPTION]... [DBNAME] [DESCRIPTION]\n" +msgstr " %s [SEÇENEK]... [VERİTABANI_ADI] [TANIM]\n" + +#: createdb.c:253 +#, c-format +msgid " -D, --tablespace=TABLESPACE default tablespace for the database\n" +msgstr " -D, --tablespace=TABLESPACE veritabanı için öntanımlı tablo uzayı\n" + +#: createdb.c:254 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo sunucuya gönderilen komutları göster\n" + +#: createdb.c:255 +#, c-format +msgid " -E, --encoding=ENCODING encoding for the database\n" +msgstr " -E, --encoding=ENCODING veritabanı için dil kodlaması\n" + +#: createdb.c:256 +#, c-format +msgid " -l, --locale=LOCALE locale settings for the database\n" +msgstr " -l, --locale=LOCALE veritabanı için yerel ayarları\n" + +#: createdb.c:257 +#, c-format +msgid " --lc-collate=LOCALE LC_COLLATE setting for the database\n" +msgstr " --lc-collate=LOCALE Veritabanı için LC_COLLATE ayarı\n" + +#: createdb.c:258 +#, c-format +msgid " --lc-ctype=LOCALE LC_CTYPE setting for the database\n" +msgstr " --lc-ctype=LOCALE Veritabanı için LC_CTYPE ayarı\n" + +#: createdb.c:259 +#, c-format +msgid " -O, --owner=OWNER database user to own the new database\n" +msgstr " -O, --owner=OWNER yeni veritabanının sahibi olacak veritabanı kullanıcısı\n" + +#: createdb.c:260 +#, c-format +msgid " -T, --template=TEMPLATE template database to copy\n" +msgstr " -T, --template=TEMPLATE kopyalanacak ÅŸablon veritabanı\n" + +#: createdb.c:261 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: createdb.c:262 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonra çık\n" + +#: createdb.c:264 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME veritabanı sunucusu adresi ya da soket dizini\n" + +#: createdb.c:265 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT veritabanı sunucu portu\n" + +#: createdb.c:266 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı\n" + +#: createdb.c:267 +#, c-format +msgid " -w, --no-password never prompt for password\n" +msgstr " -w, --no-password asla parola sorma\n" + +#: createdb.c:268 +#, c-format +msgid " -W, --password force password prompt\n" +msgstr " -W, --password parola sormasını saÄŸla\n" + +#: createdb.c:269 +#, c-format +msgid " --maintenance-db=DBNAME alternate maintenance database\n" +msgstr " --maintenance-db=VTADI alternatif bakım veritabanı\n" + +#: createdb.c:270 +#, c-format +msgid "" +"\n" +"By default, a database with the same name as the current user is created.\n" +msgstr "" +"\n" +"Öntanımlı olarak , mevcut kullanıcı ile aynı adda veritabanı yaratılır.\n" + +#: createuser.c:191 +msgid "Enter name of role to add: " +msgstr "Eklenecek rol adını girin: " + +#: createuser.c:208 +msgid "Enter password for new role: " +msgstr "Yeni rol için parola girin: " + +#: createuser.c:210 +msgid "Enter it again: " +msgstr "Yeniden girin: " + +#: createuser.c:213 +#, c-format +msgid "Passwords didn't match.\n" +msgstr "Parolalar uyuÅŸmadı.\n" + +#: createuser.c:221 +msgid "Shall the new role be a superuser?" +msgstr "Yeni rol superuser olsun mu?" + +#: createuser.c:236 +msgid "Shall the new role be allowed to create databases?" +msgstr "Yeni rol, veritabanı oluÅŸturabilsin mi?" + +#: createuser.c:244 +msgid "Shall the new role be allowed to create more new roles?" +msgstr "Yeni rol, baÅŸka yeni roller oluÅŸturabilsin mi?" + +#: createuser.c:274 +#, c-format +msgid "password encryption failed: %s" +msgstr "parola ÅŸifreleme hatası: %s" + +#: createuser.c:329 +#, c-format +msgid "creation of new role failed: %s" +msgstr "yeni rol oluÅŸturma iÅŸlemi baÅŸarısız oldu: %s" + +#: createuser.c:343 +#, c-format +msgid "" +"%s creates a new PostgreSQL role.\n" +"\n" +msgstr "" +"%s yeni bir PostgreSQL rol oluÅŸturur.\n" +"\n" + +#: createuser.c:345 dropuser.c:164 +#, c-format +msgid " %s [OPTION]... [ROLENAME]\n" +msgstr " %s [SEÇENEKLER]... [ROL_ADI]\n" + +#: createuser.c:347 +#, c-format +msgid " -c, --connection-limit=N connection limit for role (default: no limit)\n" +msgstr " -c, --connection-limit=N rol için azami baÄŸlantı sayısı (varsayılan: sınırsız)\n" + +#: createuser.c:348 +#, c-format +msgid " -d, --createdb role can create new databases\n" +msgstr " -d, --createdb rol yeni veritabanı oluÅŸturabiliyor\n" + +#: createuser.c:349 +#, c-format +msgid " -D, --no-createdb role cannot create databases (default)\n" +msgstr " -D, --no-createdb rol veritabanı oluÅŸturamaz (varsayılan)\n" + +#: createuser.c:351 +#, c-format +msgid " -g, --role=ROLE new role will be a member of this role\n" +msgstr " -g, --role=ROL yeni rol bu rolün üyesi olacaktır\n" + +#: createuser.c:352 +#, c-format +msgid "" +" -i, --inherit role inherits privileges of roles it is a\n" +" member of (default)\n" +msgstr "" +" -i, --inherit rol, üye olduÄŸu rollerin yetkilerini \n" +" miras alır (varsayılan)\n" +"\n" + +#: createuser.c:354 +#, c-format +msgid " -I, --no-inherit role does not inherit privileges\n" +msgstr " -I, --no-inherit rol, hiçbir yetkiyi miras almaz\n" + +#: createuser.c:355 +#, c-format +msgid " -l, --login role can login (default)\n" +msgstr " -l, --login rol giriÅŸ yapabiliyor\n" + +#: createuser.c:356 +#, c-format +msgid " -L, --no-login role cannot login\n" +msgstr " -L, --no-login role giriÅŸ yapamaz\n" + +#: createuser.c:357 +#, c-format +msgid " -P, --pwprompt assign a password to new role\n" +msgstr " -P, --pwprompt yeni role bir ÅŸifre atar\n" + +#: createuser.c:358 +#, c-format +msgid " -r, --createrole role can create new roles\n" +msgstr " -r, --createrole rol yeni rol oluÅŸturabiliyor\n" + +#: createuser.c:359 +#, c-format +msgid " -R, --no-createrole role cannot create roles (default)\n" +msgstr " -R, --no-createrole rol baÅŸka bir rol oluÅŸturamaz (varsayılan)\n" + +#: createuser.c:360 +#, c-format +msgid " -s, --superuser role will be superuser\n" +msgstr " -s, --superuser rol, superuser olacaktır\n" + +#: createuser.c:361 +#, c-format +msgid " -S, --no-superuser role will not be superuser (default)\n" +msgstr " -S, --no-superuser rol, superuser olmayacaktır (varsayılan)\n" + +#: createuser.c:363 +#, c-format +msgid "" +" --interactive prompt for missing role name and attributes rather\n" +" than using defaults\n" +msgstr "" +" --interactive varsayılanları kullanmaktansa eksik rol ve niteliklerin\n" +" girilmesini saÄŸla\n" + +#: createuser.c:365 +#, c-format +msgid " --replication role can initiate replication\n" +msgstr " --replication rol replikasyon baÅŸlatabilir\n" + +#: createuser.c:366 +#, c-format +msgid " --no-replication role cannot initiate replication\n" +msgstr " --no-replication rol replikasyon baÅŸlatamaz\n" + +#: createuser.c:371 +#, c-format +msgid " -U, --username=USERNAME user name to connect as (not the one to create)\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı (yaratılacak deÄŸil)\n" + +#: dropdb.c:104 +#, c-format +msgid "missing required argument database name" +msgstr "gerekli argüman eksik: veritabanı adı" + +#: dropdb.c:119 +#, c-format +msgid "Database \"%s\" will be permanently removed.\n" +msgstr "\"%s\" veritabanı kalıcı olarak silinecektir.\n" + +#: dropdb.c:120 dropuser.c:130 +msgid "Are you sure?" +msgstr "Emin misiniz?" + +#: dropdb.c:142 +#, c-format +msgid "database removal failed: %s" +msgstr "veritabanı silme iÅŸlemi baÅŸarısız oldu: %s" + +#: dropdb.c:156 +#, c-format +msgid "" +"%s removes a PostgreSQL database.\n" +"\n" +msgstr "" +"%s PostgreSQL veritabanını siler.\n" +"\n" + +#: dropdb.c:158 +#, c-format +msgid " %s [OPTION]... DBNAME\n" +msgstr " %s [SEÇENEK]... VERİTABANI_ADI\n" + +#: dropdb.c:161 +#, c-format +msgid " -i, --interactive prompt before deleting anything\n" +msgstr " -i, --interactive herhangi birÅŸeyi silmeden önce uyarı verir\n" + +#: dropdb.c:163 +#, c-format +msgid " --if-exists don't report error if database doesn't exist\n" +msgstr " --if-exists don't report error if database doesn't exist\n" + +#: dropuser.c:115 +msgid "Enter name of role to drop: " +msgstr "Silinecek rolün adını giriniz: " + +#: dropuser.c:121 +#, c-format +msgid "missing required argument role name" +msgstr "gerekli bir argüman olan rol adı eksik" + +#: dropuser.c:129 +#, c-format +msgid "Role \"%s\" will be permanently removed.\n" +msgstr "\"%s\" rolü kalıcı olarak silinecektir.\n" + +#: dropuser.c:147 +#, c-format +msgid "removal of role \"%s\" failed: %s" +msgstr "\"%s\" rolünün silinmesi baÅŸarısız oldu: %s" + +#: dropuser.c:162 +#, c-format +msgid "" +"%s removes a PostgreSQL role.\n" +"\n" +msgstr "" +"%s bir PostgreSQL rolünü siler.\n" +"\n" + +#: dropuser.c:167 +#, c-format +msgid "" +" -i, --interactive prompt before deleting anything, and prompt for\n" +" role name if not specified\n" +msgstr "" +" -i, --interactive herhangi birÅŸeyi silmeden önce uyarı ver, ve\n" +" belirtilmemiÅŸse rol adının girilmesini iste\n" + +#: dropuser.c:170 +#, c-format +msgid " --if-exists don't report error if user doesn't exist\n" +msgstr " --if-exists kullanıcı mevcut deÄŸilse bildirimde bulunma\n" + +#: dropuser.c:175 +#, c-format +msgid " -U, --username=USERNAME user name to connect as (not the one to drop)\n" +msgstr " -U, --username=KULLANICI _ADI baÄŸlanırken kullanılacak kullanıcı adı (silinecek olan deÄŸil)\n" + +#: pg_isready.c:144 +#, c-format +msgid "%s" +msgstr "%s" + +#: pg_isready.c:152 +#, c-format +msgid "could not fetch default options" +msgstr "varsayılan seçenekler getirilemedi" + +#: pg_isready.c:201 +#, c-format +msgid "accepting connections\n" +msgstr "baÄŸlantılar kabul ediliyor\n" + +#: pg_isready.c:204 +#, c-format +msgid "rejecting connections\n" +msgstr "baÄŸlantılar reddediliyor\n" + +#: pg_isready.c:207 +#, c-format +msgid "no response\n" +msgstr "cevap yok\n" + +#: pg_isready.c:210 +#, c-format +msgid "no attempt\n" +msgstr "deneme yok\n" + +#: pg_isready.c:213 +#, c-format +msgid "unknown\n" +msgstr "bilinmeyen\n" + +#: pg_isready.c:223 +#, c-format +msgid "" +"%s issues a connection check to a PostgreSQL database.\n" +"\n" +msgstr "" +"%s bir PostgreSQL veritabanına baÄŸlantı kontrolü saÄŸlar.\n" +"\n" + +#: pg_isready.c:225 +#, c-format +msgid " %s [OPTION]...\n" +msgstr " %s [SEÇENEK]...\n" + +#: pg_isready.c:228 +#, c-format +msgid " -d, --dbname=DBNAME database name\n" +msgstr " -d, --dbname=VERİTABANI_ADI veritabanı adı\n" + +#: pg_isready.c:229 +#, c-format +msgid " -q, --quiet run quietly\n" +msgstr " -q, --quiet sessizce çalış\n" + +#: pg_isready.c:230 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini gösterir ve sonra çıkar\n" + +#: pg_isready.c:231 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı gösterir ve sonra çıkar\n" + +#: pg_isready.c:234 +#, c-format +msgid " -h, --host=HOSTNAME database server host or socket directory\n" +msgstr " -h, --host=HOSTNAME veritabanı sunucusu adresi ya da soket dizini\n" + +#: pg_isready.c:235 +#, c-format +msgid " -p, --port=PORT database server port\n" +msgstr " -p, --port=PORT veritabanı sunucusunun portu\n" + +#: pg_isready.c:236 +#, c-format +msgid " -t, --timeout=SECS seconds to wait when attempting connection, 0 disables (default: %s)\n" +msgstr " -t, --timeout=SANİYE baÄŸlantı denenirken beklenecek saniye, 0 devre dışı bırakır (vrsayılan: %s)\n" + +#: pg_isready.c:237 +#, c-format +msgid " -U, --username=USERNAME user name to connect as\n" +msgstr " -U, --username=KULLANICI_ADI baÄŸlanılacak kullanıcı adı\n" + +#: reindexdb.c:168 +#, c-format +msgid "cannot reindex all databases and a specific one at the same time" +msgstr "aynı anda hem tüm veritabanları hem belirli bir veritabanı tekrar indekslenemez" + +#: reindexdb.c:173 +#, c-format +msgid "cannot reindex all databases and system catalogs at the same time" +msgstr "aynı anda tüm veritabanları ve sistem katalogları reindex edilemez" + +#: reindexdb.c:178 +#, c-format +msgid "cannot reindex specific schema(s) in all databases" +msgstr "tüm veritabanlarındaki belirli ÅŸema(lar) tekrar indekslenemez" + +#: reindexdb.c:183 +#, c-format +msgid "cannot reindex specific table(s) in all databases" +msgstr "tüm veritabanlarındaki belirli tablo(lar) tekrar indekslenemez" + +#: reindexdb.c:188 +#, c-format +msgid "cannot reindex specific index(es) in all databases" +msgstr "tüm veritabanlarındaki belirli ndeks(ler) tekrar indekslenemez" + +#: reindexdb.c:199 +#, c-format +msgid "cannot reindex specific schema(s) and system catalogs at the same time" +msgstr "aynı anda belirli ÅŸema(lar) ve sistem katalogları tekrar indekslenemez" + +#: reindexdb.c:204 +#, c-format +msgid "cannot reindex specific table(s) and system catalogs at the same time" +msgstr "aynı anda belirli tablo(lar) ve sistem katalogları tekrar indekslenemez" + +#: reindexdb.c:209 +#, c-format +msgid "cannot reindex specific index(es) and system catalogs at the same time" +msgstr "aynı anda belirli indeks(ler) ve sistem katalogları tekrar indekslenemez" + +#: reindexdb.c:298 +#, c-format +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL %s" +msgstr "PostgreSQL %2$s den eski sunucu sürümlerinde \"%1$s\" seçeneÄŸi kullanılamaz" + +#: reindexdb.c:326 +#, c-format +msgid "reindexing of table \"%s\" in database \"%s\" failed: %s" +msgstr "\"%2$s\" veritabanındaki \"%1$s\" tablosunun tekrar indeksleme iÅŸlemi baÅŸarısız: %3$s" + +#: reindexdb.c:329 +#, c-format +msgid "reindexing of index \"%s\" in database \"%s\" failed: %s" +msgstr "\"%2$s\" veritabanındaki \"%1$s\" indeksinin yeniden oluÅŸturulması baÅŸarısız: %3$s" + +#: reindexdb.c:332 +#, c-format +msgid "reindexing of schema \"%s\" in database \"%s\" failed: %s" +msgstr "\"%2$s\" veritabanındaki \"%1$s\" ÅŸemasının tekrar indeksleme iÅŸlemi baÅŸarısız: %3$s" + +#: reindexdb.c:335 +#, c-format +msgid "reindexing of database \"%s\" failed: %s" +msgstr "\"%s\" veritabanının yeniden indekslenmesi baÅŸarısız oldu: %s" + +#: reindexdb.c:369 +#, c-format +msgid "%s: reindexing database \"%s\"\n" +msgstr "%s: \"%s\" veritabanı yeniden indeksleniyor\n" + +#: reindexdb.c:412 +#, c-format +msgid "reindexing of system catalogs failed: %s" +msgstr "sistem kataloglarının yeniden indekslemesi baÅŸarısız: %s" + +#: reindexdb.c:424 +#, c-format +msgid "" +"%s reindexes a PostgreSQL database.\n" +"\n" +msgstr "" +"%s PostgreSQL veritabanını yeniden indeksler.\n" +"\n" + +#: reindexdb.c:428 +#, c-format +msgid " -a, --all reindex all databases\n" +msgstr " -a, --all tüm veritabanlarını yeniden indeksle\n" + +#: reindexdb.c:429 +#, c-format +msgid " --concurrently reindex concurrently\n" +msgstr " --concurrently eÅŸzamanlı olarak yeniden indeksle\n" + +#: reindexdb.c:430 +#, c-format +msgid " -d, --dbname=DBNAME database to reindex\n" +msgstr " -d, --dbname=VERİTABANI_ADI yeniden indekslenecek veritabanı adı\n" + +#: reindexdb.c:432 +#, c-format +msgid " -i, --index=INDEX recreate specific index(es) only\n" +msgstr " -i, --index=INDEX sadece belirli indeks(ler)i yeniden oluÅŸtur\n" + +#: reindexdb.c:434 +#, c-format +msgid " -s, --system reindex system catalogs\n" +msgstr " -s, --system sistem kataloglarını yeniden indeksle\n" + +#: reindexdb.c:435 +#, c-format +msgid " -S, --schema=SCHEMA reindex specific schema(s) only\n" +msgstr " -S, --schema=ÅžEMA sadece belirtilen ÅŸema veya ÅŸemaları tekrar indeksle\n" + +#: reindexdb.c:436 +#, c-format +msgid " -t, --table=TABLE reindex specific table(s) only\n" +msgstr " -t, --table=TABLO_ADI sadece belirli bir tablonun veya tabloların indekslerini yeniden oluÅŸtur\n" + +#: reindexdb.c:447 +#, c-format +msgid "" +"\n" +"Read the description of the SQL command REINDEX for details.\n" +msgstr "" +"\n" +"Ayrıntılar için bir REINDEX SQL komutunun açıklamasını okuyabilirsiniz.\n" + +#: vacuumdb.c:207 +#, c-format +msgid "number of parallel jobs must be at least 1" +msgstr "paralel iÅŸ sayısı en azından 1 olmalı" + +#: vacuumdb.c:212 +#, c-format +msgid "too many parallel jobs requested (maximum: %d)" +msgstr "çok fazla paralel iÅŸ talep edildi (azami: %d)" + +#: vacuumdb.c:233 +#, c-format +msgid "minimum transaction ID age must be at least 1" +msgstr "asgari transaction ID yaşı en az 1 olmalı" + +#: vacuumdb.c:241 +#, c-format +msgid "minimum multixact ID age must be at least 1" +msgstr "asgari multixact ID yaşı en az 1 olmalı" + +#: vacuumdb.c:273 vacuumdb.c:279 vacuumdb.c:285 +#, c-format +msgid "cannot use the \"%s\" option when performing only analyze" +msgstr "sadece analyze gerçekleÅŸtirilirken \"%s\" seçeneÄŸi kullanılamaz" + +#: vacuumdb.c:302 +#, c-format +msgid "cannot vacuum all databases and a specific one at the same time" +msgstr "aynı anda tüm veritabanları ve de belirli bir tanesi vakumlanamaz" + +#: vacuumdb.c:307 +#, c-format +msgid "cannot vacuum specific table(s) in all databases" +msgstr "tüm veritabanlarındaki belirli (bir) tablo(lar) vakumlanamaz" + +#: vacuumdb.c:398 +msgid "Generating minimal optimizer statistics (1 target)" +msgstr "Minimal optimizer istatistikleri oluÅŸturuluyor (1 hedef)" + +#: vacuumdb.c:399 +msgid "Generating medium optimizer statistics (10 targets)" +msgstr "Orta ölçekte optimizer istatistikleri oluÅŸturuluyor (10 hedef)" + +#: vacuumdb.c:400 +msgid "Generating default (full) optimizer statistics" +msgstr "Varsayılan (tam) optimizer istatistikleri oluÅŸturuluyor" + +#: vacuumdb.c:412 vacuumdb.c:427 vacuumdb.c:434 +#, c-format +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL 9.6" +msgstr "PostgreSQL 9,6'dan eski sunucu sürümlerinde \"%s\" seçeneÄŸi kullanılamaz" + +#: vacuumdb.c:420 +#, c-format +msgid "cannot use the \"%s\" option on server versions older than PostgreSQL 12" +msgstr "PostgreSQL 12'den eski sunucu sürümlerinde \"%s\" seçeneÄŸi kullanılamaz" + +#: vacuumdb.c:442 +#, c-format +msgid "%s: processing database \"%s\": %s\n" +msgstr "%s: \"%s\" veritabanı üzerinde iÅŸlem yapılıyor: %s\n" + +#: vacuumdb.c:445 +#, c-format +msgid "%s: vacuuming database \"%s\"\n" +msgstr "%s: \"%s\" veritabanı vakumlanıyor\n" + +#: vacuumdb.c:939 +#, c-format +msgid "vacuuming of table \"%s\" in database \"%s\" failed: %s" +msgstr "\"%2$s\" veritabanındaki \"%1$s\" tablosunun vakumlama iÅŸlemi baÅŸarısız oldu: %3$s" + +#: vacuumdb.c:942 vacuumdb.c:1077 +#, c-format +msgid "vacuuming of database \"%s\" failed: %s" +msgstr "\"%s\" veritabanının vakumlanması baÅŸarısız oldu: %s" + +#: vacuumdb.c:1212 +#, c-format +msgid "" +"%s cleans and analyzes a PostgreSQL database.\n" +"\n" +msgstr "" +"%s bir PostgreSQL veritabanını temizler ve analiz eder.\n" +"\n" + +#: vacuumdb.c:1216 +#, c-format +msgid " -a, --all vacuum all databases\n" +msgstr " -a, --all tüm veritabanlarını vakumlar\n" + +#: vacuumdb.c:1217 +#, c-format +msgid " -d, --dbname=DBNAME database to vacuum\n" +msgstr " -d, --dbname=VERİTABANI_ADI vakumlanacak veritabanı\n" + +#: vacuumdb.c:1218 +#, c-format +msgid " --disable-page-skipping disable all page-skipping behavior\n" +msgstr " --disable-page-skipping bütün sayfa atlama davranışını devre dışı bırak\n" + +#: vacuumdb.c:1219 +#, c-format +msgid " -e, --echo show the commands being sent to the server\n" +msgstr " -e, --echo sunucuya gönderilen komutları yaz\n" + +#: vacuumdb.c:1220 +#, c-format +msgid " -f, --full do full vacuuming\n" +msgstr " -f, --full tam (FULL) vakumlama yap\n" + +#: vacuumdb.c:1221 +#, c-format +msgid " -F, --freeze freeze row transaction information\n" +msgstr " -F, --freeze Dondurulan satır transaction bilgisi\n" + +#: vacuumdb.c:1222 +#, c-format +msgid " -j, --jobs=NUM use this many concurrent connections to vacuum\n" +msgstr " -j, --jobs=SAYI vakum için bu sayı kadar eÅŸzamanlı baÄŸlantı kullan\n" + +#: vacuumdb.c:1223 +#, c-format +msgid " --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n" +msgstr " --min-mxid-age=MXID_AGE vakumlanacak tabloların asgari multixact ID yaşı\n" + +#: vacuumdb.c:1224 +#, c-format +msgid " --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n" +msgstr " --min-xid-age=XID_AGE vakumlanacak tabloların asgari transaction ID yaşı\n" + +#: vacuumdb.c:1225 +#, c-format +msgid " -q, --quiet don't write any messages\n" +msgstr " -q, --quiet hiçbir mesaj yazma\n" + +#: vacuumdb.c:1226 +#, c-format +msgid " --skip-locked skip relations that cannot be immediately locked\n" +msgstr " --skip-locked hemen kilitlenemeyecek tabloları atla\n" + +#: vacuumdb.c:1227 +#, c-format +msgid " -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n" +msgstr " -t, --table='TABLO[(KOLONLAR)]' sadece belirli bir tabloyu / tabloları vakumlar\n" + +#: vacuumdb.c:1228 +#, c-format +msgid " -v, --verbose write a lot of output\n" +msgstr " -v, --verbose bolca çıktı yaz\n" + +#: vacuumdb.c:1229 +#, c-format +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version sürüm bilgisini göster, sonra çık\n" + +#: vacuumdb.c:1230 +#, c-format +msgid " -z, --analyze update optimizer statistics\n" +msgstr " -z, --analyze optimizer istatistiklerini güncelle\n" + +#: vacuumdb.c:1231 +#, c-format +msgid " -Z, --analyze-only only update optimizer statistics; no vacuum\n" +msgstr " -z, --analyze-only sadece optimizer bilgilerini güncelle; vakum iÅŸlemi yok\n" + +#: vacuumdb.c:1232 +#, c-format +msgid "" +" --analyze-in-stages only update optimizer statistics, in multiple\n" +" stages for faster results; no vacuum\n" +msgstr "" +" --analyze-in-stages sadece optimizer istatistiklerini güncelle, daha hızlı\n" +" sonuç için birden fazla aÅŸamada; vakum iÅŸlemi yok\n" + +#: vacuumdb.c:1234 +#, c-format +msgid " -?, --help show this help, then exit\n" +msgstr " -?, --help bu yardımı göster, sonrasında çık\n" + +#: vacuumdb.c:1242 +#, c-format +msgid "" +"\n" +"Read the description of the SQL command VACUUM for details.\n" +msgstr "" +"\n" +"Ayrıntılar için, bir SQL komutu olan VACUUM'un tanımlarını okuyun.\n" + +#~ msgid "%s: invalid socket: %s" +#~ msgstr "%s: geçersiz soket: %s" + +#~ msgid "Could not send cancel request: %s\n" +#~ msgstr "İptal isteÄŸi gönderilemedi: %s\n" + +#~ msgid " -q, --quiet don't write any messages\n" +#~ msgstr " -q, --quiet Hiç bir mesaj yazma\n" + +#~ msgid "pg_strdup: cannot duplicate null pointer (internal error)\n" +#~ msgstr "pg_strdup: null pointer duplicate edilemiyor (iç hata)\n" + +#~ msgid "%s: out of memory\n" +#~ msgstr "%s: yetersiz bellek\n" + +#~ msgid "%s: could not get current user name: %s\n" +#~ msgstr "%s: geçerli kullanıcı adı alınamadı: %s\n" + +#~ msgid "%s: could not obtain information about current user: %s\n" +#~ msgstr "%s: geçerli kullanıcı hakkında bilgi alınamadı: %s\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini göster ve çık\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve çık\n" + +#~ msgid "%s: cannot use the \"freeze\" option when performing only analyze\n" +#~ msgstr "%s: sadece analyze iÅŸlemi yapıldığında \"freeze\" seçeneÄŸini kullanamaz\n" + +#~ msgid " -d, --dbname=DBNAME database from which to remove the language\n" +#~ msgstr " -d, --dbname=VERİTABANI_ADI dilin sileneceÄŸi veritabanının adı\n" + +#~ msgid "" +#~ "%s removes a procedural language from a database.\n" +#~ "\n" +#~ msgstr "" +#~ "%s veritabanından yordamsal bir dili siler.\n" +#~ "\n" + +#~ msgid "%s: language removal failed: %s" +#~ msgstr "%s: dil silme iÅŸlemi baÅŸarısız oldu: %s" + +#~ msgid "%s: still %s functions declared in language \"%s\"; language not removed\n" +#~ msgstr "%s: %s fonksiyon, \"%s\" dilinde tanımlanmış durumda; dil kaldırılamadı\n" + +#~ msgid "%s: language \"%s\" is not installed in database \"%s\"\n" +#~ msgstr "%s: \"%s\" dili \"%s\" veritabanında kurulu deÄŸil \n" + +#~ msgid "" +#~ "\n" +#~ "If one of -d, -D, -r, -R, -s, -S, and ROLENAME is not specified, you will\n" +#~ "be prompted interactively.\n" +#~ msgstr "" +#~ "\n" +#~ "EÄŸer -d, -D, -r, -R, -s, -S ve ROLENAME'den birisi belirtilmezse, bunlar size\n" +#~ "etkileÅŸimli olarak sorulacaktır.\n" + +#~ msgid " -N, --unencrypted do not encrypt stored password\n" +#~ msgstr " -N, --unencrypted saklanmış ÅŸifreyi kriptolamaz\n" + +#~ msgid " -E, --encrypted encrypt stored password\n" +#~ msgstr " -E, --encrypted saklanan ÅŸifreleri encrypt eder\n" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini göster ve çık\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve çık\n" + +#~ msgid " -l, --list show a list of currently installed languages\n" +#~ msgstr " -l, --list Åžu anda kurulu olan dilleri göster\n" + +#~ msgid " -d, --dbname=DBNAME database to install language in\n" +#~ msgstr " -d, --dbname=VERİTABANI_ADI dilin kurulacağı veritabanının adı\n" + +#~ msgid " %s [OPTION]... LANGNAME [DBNAME]\n" +#~ msgstr " %s [SEÇENEK]... DİL_ADI [VERİTABANI_ADI]\n" + +#~ msgid "" +#~ "%s installs a procedural language into a PostgreSQL database.\n" +#~ "\n" +#~ msgstr "" +#~ "%s Bir PostgreSQL veritabanına yordamsal bir dil kurar.\n" +#~ "\n" + +#~ msgid "%s: language installation failed: %s" +#~ msgstr "%s: Dil kurulumu baÅŸarısız oldu: %s" + +#~ msgid "%s: language \"%s\" is already installed in database \"%s\"\n" +#~ msgstr "%s: \"%s\" dili daha önceden veritabanına yüklenmiÅŸtir \"%s\"\n" + +#~ msgid "Procedural Languages" +#~ msgstr "Yordamsal Diller" + +#~ msgid "Trusted?" +#~ msgstr "Güvenilir mi?" + +#~ msgid "no" +#~ msgstr "hayır" + +#~ msgid "yes" +#~ msgstr "evet" + +#~ msgid "Name" +#~ msgstr "Adı" + +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version sürüm bilgisini göster ve çık\n" + +#~ msgid " --help show this help, then exit\n" +#~ msgstr " --help bu yardımı göster ve çık\n" + +#~ msgid "%s: %s" +#~ msgstr "%s: %s" + +#~ msgid "%s: \"%s\" is not a valid encoding name\n" +#~ msgstr "%s: \"%s\" geçerli bir dil kodlaması deÄŸil\n" + +#~ msgid "%s: query returned %d row instead of one: %s\n" +#~ msgid_plural "%s: query returned %d rows instead of one: %s\n" +#~ msgstr[0] "%s: sorgu bir yerine %d satır döndürdü: %s\n" +#~ msgstr[1] "%s: sorgu bir yerine %d satır döndürdü: %s\n" + +#~ msgid "%s: query was: %s\n" +#~ msgstr "%s: sorgu ÅŸu idi: %s\n" + +#~ msgid "%s: query failed: %s" +#~ msgstr "%s: sorgu baÅŸarısız oldu: %s" diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c index be1c06ebbdb..f00aec15de3 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -2,7 +2,7 @@ * * reindexdb * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/bin/scripts/reindexdb.c * @@ -10,25 +10,45 @@ */ #include "postgres_fe.h" + +#include "catalog/pg_class_d.h" #include "common.h" +#include "common/logging.h" +#include "fe_utils/connect.h" #include "fe_utils/simple_list.h" #include "fe_utils/string_utils.h" +#include "scripts_parallel.h" - -static void reindex_one_database(const char *name, const char *dbname, - const char *type, const char *host, - const char *port, const char *username, - enum trivalue prompt_password, const char *progname, - bool echo, bool verbose); +typedef enum ReindexType +{ + REINDEX_DATABASE, + REINDEX_INDEX, + REINDEX_SCHEMA, + REINDEX_SYSTEM, + REINDEX_TABLE +} ReindexType; + + +static SimpleStringList *get_parallel_object_list(PGconn *conn, + ReindexType type, + SimpleStringList *user_list, + bool echo); +static void reindex_one_database(const char *dbname, ReindexType type, + SimpleStringList *user_list, const char *host, + const char *port, const char *username, + enum trivalue prompt_password, const char *progname, + bool echo, bool verbose, bool concurrently, + int concurrentCons); static void reindex_all_databases(const char *maintenance_db, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo, - bool quiet, bool verbose); -static void reindex_system_catalogs(const char *dbname, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo, bool verbose); + const char *host, const char *port, + const char *username, enum trivalue prompt_password, + const char *progname, bool echo, + bool quiet, bool verbose, bool concurrently, + int concurrentCons); +static void run_reindex_command(PGconn *conn, ReindexType type, + const char *name, bool echo, bool verbose, + bool concurrently, bool async); + static void help(const char *progname); int @@ -48,7 +68,9 @@ main(int argc, char *argv[]) {"system", no_argument, NULL, 's'}, {"table", required_argument, NULL, 't'}, {"index", required_argument, NULL, 'i'}, + {"jobs", required_argument, NULL, 'j'}, {"verbose", no_argument, NULL, 'v'}, + {"concurrently", no_argument, NULL, 1}, {"maintenance-db", required_argument, NULL, 2}, {NULL, 0, NULL, 0} }; @@ -68,17 +90,20 @@ main(int argc, char *argv[]) bool echo = false; bool quiet = false; bool verbose = false; + bool concurrently = false; SimpleStringList indexes = {NULL, NULL}; SimpleStringList tables = {NULL, NULL}; SimpleStringList schemas = {NULL, NULL}; + int concurrentCons = 1; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); handle_help_version_opts(argc, argv, "reindexdb", help); /* process command-line options */ - while ((c = getopt_long(argc, argv, "h:p:U:wWeqS:d:ast:i:v", long_options, &optindex)) != -1) + while ((c = getopt_long(argc, argv, "h:p:U:wWeqS:d:ast:i:j:v", long_options, &optindex)) != -1) { switch (c) { @@ -121,9 +146,20 @@ main(int argc, char *argv[]) case 'i': simple_string_list_append(&indexes, optarg); break; + case 'j': + concurrentCons = atoi(optarg); + if (concurrentCons <= 0) + { + pg_log_error("number of parallel jobs must be at least 1"); + exit(1); + } + break; case 'v': verbose = true; break; + case 1: + concurrently = true; + break; case 2: maintenance_db = pg_strdup(optarg); break; @@ -145,8 +181,8 @@ main(int argc, char *argv[]) if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -157,48 +193,55 @@ main(int argc, char *argv[]) { if (dbname) { - fprintf(stderr, _("%s: cannot reindex all databases and a specific one at the same time\n"), progname); + pg_log_error("cannot reindex all databases and a specific one at the same time"); exit(1); } if (syscatalog) { - fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname); + pg_log_error("cannot reindex all databases and system catalogs at the same time"); exit(1); } if (schemas.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific schema(s) in all databases\n"), progname); + pg_log_error("cannot reindex specific schema(s) in all databases"); exit(1); } if (tables.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname); + pg_log_error("cannot reindex specific table(s) in all databases"); exit(1); } if (indexes.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname); + pg_log_error("cannot reindex specific index(es) in all databases"); exit(1); } reindex_all_databases(maintenance_db, host, port, username, - prompt_password, progname, echo, quiet, verbose); + prompt_password, progname, echo, quiet, verbose, + concurrently, concurrentCons); } else if (syscatalog) { if (schemas.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific schema(s) and system catalogs at the same time\n"), progname); + pg_log_error("cannot reindex specific schema(s) and system catalogs at the same time"); exit(1); } if (tables.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname); + pg_log_error("cannot reindex specific table(s) and system catalogs at the same time"); exit(1); } if (indexes.head != NULL) { - fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname); + pg_log_error("cannot reindex specific index(es) and system catalogs at the same time"); + exit(1); + } + + if (concurrentCons > 1) + { + pg_log_error("cannot use multiple jobs to reindex system catalogs"); exit(1); } @@ -212,11 +255,23 @@ main(int argc, char *argv[]) dbname = get_user_name_or_exit(progname); } - reindex_system_catalogs(dbname, host, port, username, prompt_password, - progname, echo, verbose); + reindex_one_database(dbname, REINDEX_SYSTEM, NULL, host, + port, username, prompt_password, progname, + echo, verbose, concurrently, 1); } else { + /* + * Index-level REINDEX is not supported with multiple jobs as we + * cannot control the concurrent processing of multiple indexes + * depending on the same relation. + */ + if (concurrentCons > 1 && indexes.head != NULL) + { + pg_log_error("cannot use multiple jobs to reindex indexes"); + exit(1); + } + if (dbname == NULL) { if (getenv("PGDATABASE")) @@ -228,62 +283,213 @@ main(int argc, char *argv[]) } if (schemas.head != NULL) - { - SimpleStringListCell *cell; - - for (cell = schemas.head; cell; cell = cell->next) - { - reindex_one_database(cell->val, dbname, "SCHEMA", host, port, - username, prompt_password, progname, echo, verbose); - } - } + reindex_one_database(dbname, REINDEX_SCHEMA, &schemas, host, + port, username, prompt_password, progname, + echo, verbose, concurrently, concurrentCons); if (indexes.head != NULL) - { - SimpleStringListCell *cell; + reindex_one_database(dbname, REINDEX_INDEX, &indexes, host, + port, username, prompt_password, progname, + echo, verbose, concurrently, 1); - for (cell = indexes.head; cell; cell = cell->next) - { - reindex_one_database(cell->val, dbname, "INDEX", host, port, - username, prompt_password, progname, echo, verbose); - } - } if (tables.head != NULL) - { - SimpleStringListCell *cell; - - for (cell = tables.head; cell; cell = cell->next) - { - reindex_one_database(cell->val, dbname, "TABLE", host, port, - username, prompt_password, progname, echo, verbose); - } - } + reindex_one_database(dbname, REINDEX_TABLE, &tables, host, + port, username, prompt_password, progname, + echo, verbose, concurrently, + concurrentCons); /* * reindex database only if neither index nor table nor schema is * specified */ if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL) - reindex_one_database(NULL, dbname, "DATABASE", host, port, - username, prompt_password, progname, echo, verbose); + reindex_one_database(dbname, REINDEX_DATABASE, NULL, host, + port, username, prompt_password, progname, + echo, verbose, concurrently, concurrentCons); } exit(0); } static void -reindex_one_database(const char *name, const char *dbname, const char *type, - const char *host, const char *port, const char *username, +reindex_one_database(const char *dbname, ReindexType type, + SimpleStringList *user_list, const char *host, + const char *port, const char *username, enum trivalue prompt_password, const char *progname, bool echo, - bool verbose) + bool verbose, bool concurrently, int concurrentCons) { - PQExpBufferData sql; - PGconn *conn; + SimpleStringListCell *cell; + bool parallel = concurrentCons > 1; + SimpleStringList *process_list = user_list; + ReindexType process_type = type; + ParallelSlot *slots; + bool failed = false; + int items_count = 0; conn = connectDatabase(dbname, host, port, username, prompt_password, progname, echo, false, false); + if (concurrently && PQserverVersion(conn) < 120000) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "concurrently", "12"); + exit(1); + } + + if (!parallel) + { + switch (process_type) + { + case REINDEX_DATABASE: + case REINDEX_SYSTEM: + + /* + * Database and system reindexes only need to work on the + * database itself, so build a list with a single entry. + */ + Assert(user_list == NULL); + process_list = pg_malloc0(sizeof(SimpleStringList)); + simple_string_list_append(process_list, PQdb(conn)); + break; + + case REINDEX_INDEX: + case REINDEX_SCHEMA: + case REINDEX_TABLE: + Assert(user_list != NULL); + break; + } + } + else + { + switch (process_type) + { + case REINDEX_DATABASE: + + /* + * Database-wide parallel reindex requires special processing. + * If multiple jobs were asked, we have to reindex system + * catalogs first as they cannot be processed in parallel. + */ + if (concurrently) + pg_log_warning("cannot reindex system catalogs concurrently, skipping all"); + else + run_reindex_command(conn, REINDEX_SYSTEM, PQdb(conn), echo, + verbose, concurrently, false); + + /* Build a list of relations from the database */ + process_list = get_parallel_object_list(conn, process_type, + user_list, echo); + process_type = REINDEX_TABLE; + + /* Bail out if nothing to process */ + if (process_list == NULL) + return; + break; + + case REINDEX_SCHEMA: + Assert(user_list != NULL); + + /* Build a list of relations from all the schemas */ + process_list = get_parallel_object_list(conn, process_type, + user_list, echo); + process_type = REINDEX_TABLE; + + /* Bail out if nothing to process */ + if (process_list == NULL) + return; + break; + + case REINDEX_SYSTEM: + case REINDEX_INDEX: + /* not supported */ + Assert(false); + break; + + case REINDEX_TABLE: + + /* + * Fall through. The list of items for tables is already + * created. + */ + break; + } + } + + /* + * Adjust the number of concurrent connections depending on the items in + * the list. We choose the minimum between the number of concurrent + * connections and the number of items in the list. + */ + for (cell = process_list->head; cell; cell = cell->next) + { + items_count++; + + /* no need to continue if there are more elements than jobs */ + if (items_count >= concurrentCons) + break; + } + concurrentCons = Min(concurrentCons, items_count); + Assert(concurrentCons > 0); + + Assert(process_list != NULL); + + slots = ParallelSlotsSetup(dbname, host, port, username, prompt_password, + progname, echo, conn, concurrentCons); + + cell = process_list->head; + do + { + const char *objname = cell->val; + ParallelSlot *free_slot = NULL; + + if (CancelRequested) + { + failed = true; + goto finish; + } + + free_slot = ParallelSlotsGetIdle(slots, concurrentCons); + if (!free_slot) + { + failed = true; + goto finish; + } + + run_reindex_command(free_slot->connection, process_type, objname, + echo, verbose, concurrently, true); + + cell = cell->next; + } while (cell != NULL); + + if (!ParallelSlotsWaitCompletion(slots, concurrentCons)) + failed = true; + +finish: + if (process_list != user_list) + { + simple_string_list_destroy(process_list); + pg_free(process_list); + } + + ParallelSlotsTerminate(slots, concurrentCons); + pfree(slots); + + if (failed) + exit(1); +} + +static void +run_reindex_command(PGconn *conn, ReindexType type, const char *name, + bool echo, bool verbose, bool concurrently, bool async) +{ + PQExpBufferData sql; + bool status; + + Assert(name); + + /* build the REINDEX query */ initPQExpBuffer(&sql); appendPQExpBufferStr(&sql, "REINDEX "); @@ -291,44 +497,218 @@ reindex_one_database(const char *name, const char *dbname, const char *type, if (verbose) appendPQExpBufferStr(&sql, "(VERBOSE) "); - appendPQExpBufferStr(&sql, type); - appendPQExpBufferChar(&sql, ' '); - if (strcmp(type, "TABLE") == 0 || - strcmp(type, "INDEX") == 0) - appendQualifiedRelation(&sql, name, conn, progname, echo); - else if (strcmp(type, "SCHEMA") == 0) - appendPQExpBufferStr(&sql, name); - else if (strcmp(type, "DATABASE") == 0) - appendPQExpBufferStr(&sql, fmtId(PQdb(conn))); + /* object type */ + switch (type) + { + case REINDEX_DATABASE: + appendPQExpBufferStr(&sql, "DATABASE "); + break; + case REINDEX_INDEX: + appendPQExpBufferStr(&sql, "INDEX "); + break; + case REINDEX_SCHEMA: + appendPQExpBufferStr(&sql, "SCHEMA "); + break; + case REINDEX_SYSTEM: + appendPQExpBufferStr(&sql, "SYSTEM "); + break; + case REINDEX_TABLE: + appendPQExpBufferStr(&sql, "TABLE "); + break; + } + + if (concurrently) + appendPQExpBufferStr(&sql, "CONCURRENTLY "); + + /* object name */ + switch (type) + { + case REINDEX_DATABASE: + case REINDEX_SYSTEM: + appendPQExpBufferStr(&sql, fmtId(name)); + break; + case REINDEX_INDEX: + case REINDEX_TABLE: + appendQualifiedRelation(&sql, name, conn, echo); + break; + case REINDEX_SCHEMA: + appendPQExpBufferStr(&sql, name); + break; + } + + /* finish the query */ appendPQExpBufferChar(&sql, ';'); - if (!executeMaintenanceCommand(conn, sql.data, echo)) + if (async) { - if (strcmp(type, "TABLE") == 0) - fprintf(stderr, _("%s: reindexing of table \"%s\" in database \"%s\" failed: %s"), - progname, name, PQdb(conn), PQerrorMessage(conn)); - if (strcmp(type, "INDEX") == 0) - fprintf(stderr, _("%s: reindexing of index \"%s\" in database \"%s\" failed: %s"), - progname, name, PQdb(conn), PQerrorMessage(conn)); - if (strcmp(type, "SCHEMA") == 0) - fprintf(stderr, _("%s: reindexing of schema \"%s\" in database \"%s\" failed: %s"), - progname, name, PQdb(conn), PQerrorMessage(conn)); - else - fprintf(stderr, _("%s: reindexing of database \"%s\" failed: %s"), - progname, PQdb(conn), PQerrorMessage(conn)); - PQfinish(conn); - exit(1); + if (echo) + printf("%s\n", sql.data); + + status = PQsendQuery(conn, sql.data) == 1; + } + else + status = executeMaintenanceCommand(conn, sql.data, echo); + + if (!status) + { + switch (type) + { + case REINDEX_DATABASE: + pg_log_error("reindexing of database \"%s\" failed: %s", + PQdb(conn), PQerrorMessage(conn)); + break; + case REINDEX_INDEX: + pg_log_error("reindexing of index \"%s\" in database \"%s\" failed: %s", + name, PQdb(conn), PQerrorMessage(conn)); + break; + case REINDEX_SCHEMA: + pg_log_error("reindexing of schema \"%s\" in database \"%s\" failed: %s", + name, PQdb(conn), PQerrorMessage(conn)); + break; + case REINDEX_SYSTEM: + pg_log_error("reindexing of system catalogs on database \"%s\" failed: %s", + PQdb(conn), PQerrorMessage(conn)); + break; + case REINDEX_TABLE: + pg_log_error("reindexing of table \"%s\" in database \"%s\" failed: %s", + name, PQdb(conn), PQerrorMessage(conn)); + break; + } + if (!async) + { + PQfinish(conn); + exit(1); + } } - PQfinish(conn); termPQExpBuffer(&sql); } +/* + * Prepare the list of objects to process by querying the catalogs. + * + * This function will return a SimpleStringList object containing the entire + * list of tables in the given database that should be processed by a parallel + * database-wide reindex (excluding system tables), or NULL if there's no such + * table. + */ +static SimpleStringList * +get_parallel_object_list(PGconn *conn, ReindexType type, + SimpleStringList *user_list, bool echo) +{ + PQExpBufferData catalog_query; + PQExpBufferData buf; + PGresult *res; + SimpleStringList *tables; + int ntups, + i; + + initPQExpBuffer(&catalog_query); + + /* + * The queries here are using a safe search_path, so there's no need to + * fully qualify everything. + */ + switch (type) + { + case REINDEX_DATABASE: + Assert(user_list == NULL); + appendPQExpBuffer(&catalog_query, + "SELECT c.relname, ns.nspname\n" + " FROM pg_catalog.pg_class c\n" + " JOIN pg_catalog.pg_namespace ns" + " ON c.relnamespace = ns.oid\n" + " WHERE ns.nspname != 'pg_catalog'\n" + " AND c.relkind IN (" + CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_MATVIEW) ")\n" + " ORDER BY c.relpages DESC;"); + break; + + case REINDEX_SCHEMA: + { + SimpleStringListCell *cell; + bool nsp_listed = false; + + Assert(user_list != NULL); + + /* + * All the tables from all the listed schemas are grabbed at + * once. + */ + appendPQExpBuffer(&catalog_query, + "SELECT c.relname, ns.nspname\n" + " FROM pg_catalog.pg_class c\n" + " JOIN pg_catalog.pg_namespace ns" + " ON c.relnamespace = ns.oid\n" + " WHERE c.relkind IN (" + CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_MATVIEW) ")\n" + " AND ns.nspname IN ("); + + for (cell = user_list->head; cell; cell = cell->next) + { + const char *nspname = cell->val; + + if (nsp_listed) + appendPQExpBuffer(&catalog_query, ", "); + else + nsp_listed = true; + + appendStringLiteralConn(&catalog_query, nspname, conn); + } + + appendPQExpBuffer(&catalog_query, ")\n" + " ORDER BY c.relpages DESC;"); + } + break; + + case REINDEX_SYSTEM: + case REINDEX_INDEX: + case REINDEX_TABLE: + Assert(false); + break; + } + + res = executeQuery(conn, catalog_query.data, echo); + termPQExpBuffer(&catalog_query); + + /* + * If no rows are returned, there are no matching tables, so we are done. + */ + ntups = PQntuples(res); + if (ntups == 0) + { + PQclear(res); + PQfinish(conn); + return NULL; + } + + tables = pg_malloc0(sizeof(SimpleStringList)); + + /* Build qualified identifiers for each table */ + initPQExpBuffer(&buf); + for (i = 0; i < ntups; i++) + { + appendPQExpBufferStr(&buf, + fmtQualifiedId(PQgetvalue(res, i, 1), + PQgetvalue(res, i, 0))); + + simple_string_list_append(tables, buf.data); + resetPQExpBuffer(&buf); + } + termPQExpBuffer(&buf); + PQclear(res); + + return tables; +} + static void reindex_all_databases(const char *maintenance_db, const char *host, const char *port, const char *username, enum trivalue prompt_password, - const char *progname, bool echo, bool quiet, bool verbose) + const char *progname, bool echo, bool quiet, bool verbose, + bool concurrently, int concurrentCons) { PGconn *conn; PGresult *result; @@ -337,7 +717,7 @@ reindex_all_databases(const char *maintenance_db, conn = connectMaintenanceDatabase(maintenance_db, host, port, username, prompt_password, progname, echo); - result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", progname, echo); + result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", echo); PQfinish(conn); initPQExpBuffer(&connstr); @@ -352,49 +732,19 @@ reindex_all_databases(const char *maintenance_db, } resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, dbname); - reindex_one_database(NULL, connstr.data, "DATABASE", host, + reindex_one_database(connstr.data, REINDEX_DATABASE, NULL, host, port, username, prompt_password, - progname, echo, verbose); + progname, echo, verbose, concurrently, + concurrentCons); } termPQExpBuffer(&connstr); PQclear(result); } -static void -reindex_system_catalogs(const char *dbname, const char *host, const char *port, - const char *username, enum trivalue prompt_password, - const char *progname, bool echo, bool verbose) -{ - PGconn *conn; - PQExpBufferData sql; - - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, echo, false, false); - - initPQExpBuffer(&sql); - - appendPQExpBuffer(&sql, "REINDEX"); - - if (verbose) - appendPQExpBuffer(&sql, " (VERBOSE)"); - - appendPQExpBuffer(&sql, " SYSTEM %s;", fmtId(PQdb(conn))); - - if (!executeMaintenanceCommand(conn, sql.data, echo)) - { - fprintf(stderr, _("%s: reindexing of system catalogs failed: %s"), - progname, PQerrorMessage(conn)); - PQfinish(conn); - exit(1); - } - PQfinish(conn); - termPQExpBuffer(&sql); -} - static void help(const char *progname) { @@ -403,9 +753,11 @@ help(const char *progname) printf(_(" %s [OPTION]... [DBNAME]\n"), progname); printf(_("\nOptions:\n")); printf(_(" -a, --all reindex all databases\n")); + printf(_(" --concurrently reindex concurrently\n")); printf(_(" -d, --dbname=DBNAME database to reindex\n")); printf(_(" -e, --echo show the commands being sent to the server\n")); printf(_(" -i, --index=INDEX recreate specific index(es) only\n")); + printf(_(" -j, --jobs=NUM use this many concurrent connections to reindex\n")); printf(_(" -q, --quiet don't write any messages\n")); printf(_(" -s, --system reindex system catalogs\n")); printf(_(" -S, --schema=SCHEMA reindex specific schema(s) only\n")); @@ -421,5 +773,5 @@ help(const char *progname) printf(_(" -W, --password force password prompt\n")); printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); printf(_("\nRead the description of the SQL command REINDEX for details.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/bin/scripts/scripts_parallel.c b/src/bin/scripts/scripts_parallel.c new file mode 100644 index 00000000000..97435160e95 --- /dev/null +++ b/src/bin/scripts/scripts_parallel.c @@ -0,0 +1,299 @@ +/*------------------------------------------------------------------------- + * + * scripts_parallel.c + * Parallel support for bin/scripts/ + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/bin/scripts/scripts_parallel.c + * + *------------------------------------------------------------------------- + */ + +#ifdef WIN32 +#define FD_SETSIZE 1024 /* must set before winsock2.h is included */ +#endif + +#include "postgres_fe.h" + +#ifdef HAVE_SYS_SELECT_H +#include +#endif + +#include "common.h" +#include "common/logging.h" +#include "scripts_parallel.h" + +static void init_slot(ParallelSlot *slot, PGconn *conn); +static int select_loop(int maxFd, fd_set *workerset, bool *aborting); + +static void +init_slot(ParallelSlot *slot, PGconn *conn) +{ + slot->connection = conn; + /* Initially assume connection is idle */ + slot->isFree = true; +} + +/* + * Loop on select() until a descriptor from the given set becomes readable. + * + * If we get a cancel request while we're waiting, we forego all further + * processing and set the *aborting flag to true. The return value must be + * ignored in this case. Otherwise, *aborting is set to false. + */ +static int +select_loop(int maxFd, fd_set *workerset, bool *aborting) +{ + int i; + fd_set saveSet = *workerset; + + if (CancelRequested) + { + *aborting = true; + return -1; + } + else + *aborting = false; + + for (;;) + { + /* + * On Windows, we need to check once in a while for cancel requests; + * on other platforms we rely on select() returning when interrupted. + */ + struct timeval *tvp; +#ifdef WIN32 + struct timeval tv = {0, 1000000}; + + tvp = &tv; +#else + tvp = NULL; +#endif + + *workerset = saveSet; + i = select(maxFd + 1, workerset, NULL, NULL, tvp); + +#ifdef WIN32 + if (i == SOCKET_ERROR) + { + i = -1; + + if (WSAGetLastError() == WSAEINTR) + errno = EINTR; + } +#endif + + if (i < 0 && errno == EINTR) + continue; /* ignore this */ + if (i < 0 || CancelRequested) + *aborting = true; /* but not this */ + if (i == 0) + continue; /* timeout (Win32 only) */ + break; + } + + return i; +} + +/* + * ParallelSlotsGetIdle + * Return a connection slot that is ready to execute a command. + * + * This returns the first slot we find that is marked isFree, if one is; + * otherwise, we loop on select() until one socket becomes available. When + * this happens, we read the whole set and mark as free all sockets that + * become available. If an error occurs, NULL is returned. + */ +ParallelSlot * +ParallelSlotsGetIdle(ParallelSlot *slots, int numslots) +{ + int i; + int firstFree = -1; + + /* + * Look for any connection currently free. If there is one, mark it as + * taken and let the caller know the slot to use. + */ + for (i = 0; i < numslots; i++) + { + if (slots[i].isFree) + { + slots[i].isFree = false; + return slots + i; + } + } + + /* + * No free slot found, so wait until one of the connections has finished + * its task and return the available slot. + */ + while (firstFree < 0) + { + fd_set slotset; + int maxFd = 0; + bool aborting; + + /* We must reconstruct the fd_set for each call to select_loop */ + FD_ZERO(&slotset); + + for (i = 0; i < numslots; i++) + { + int sock = PQsocket(slots[i].connection); + + /* + * We don't really expect any connections to lose their sockets + * after startup, but just in case, cope by ignoring them. + */ + if (sock < 0) + continue; + + FD_SET(sock, &slotset); + if (sock > maxFd) + maxFd = sock; + } + + SetCancelConn(slots->connection); + i = select_loop(maxFd, &slotset, &aborting); + ResetCancelConn(); + + if (aborting) + { + /* + * We set the cancel-receiving connection to the one in the zeroth + * slot above, so fetch the error from there. + */ + consumeQueryResult(slots->connection); + return NULL; + } + Assert(i != 0); + + for (i = 0; i < numslots; i++) + { + int sock = PQsocket(slots[i].connection); + + if (sock >= 0 && FD_ISSET(sock, &slotset)) + { + /* select() says input is available, so consume it */ + PQconsumeInput(slots[i].connection); + } + + /* Collect result(s) as long as any are available */ + while (!PQisBusy(slots[i].connection)) + { + PGresult *result = PQgetResult(slots[i].connection); + + if (result != NULL) + { + /* Check and discard the command result */ + if (!processQueryResult(slots[i].connection, result)) + return NULL; + } + else + { + /* This connection has become idle */ + slots[i].isFree = true; + if (firstFree < 0) + firstFree = i; + break; + } + } + } + } + + slots[firstFree].isFree = false; + return slots + firstFree; +} + +/* + * ParallelSlotsSetup + * Prepare a set of parallel slots to use on a given database. + * + * This creates and initializes a set of connections to the database + * using the information given by the caller, marking all parallel slots + * as free and ready to use. "conn" is an initial connection set up + * by the caller and is associated with the first slot in the parallel + * set. + */ +ParallelSlot * +ParallelSlotsSetup(const char *dbname, const char *host, const char *port, + const char *username, bool prompt_password, + const char *progname, bool echo, + PGconn *conn, int numslots) +{ + ParallelSlot *slots; + int i; + + Assert(conn != NULL); + + slots = (ParallelSlot *) pg_malloc(sizeof(ParallelSlot) * numslots); + init_slot(slots, conn); + if (numslots > 1) + { + for (i = 1; i < numslots; i++) + { + conn = connectDatabase(dbname, host, port, username, prompt_password, + progname, echo, false, true); + + /* + * Fail and exit immediately if trying to use a socket in an + * unsupported range. POSIX requires open(2) to use the lowest + * unused file descriptor and the hint given relies on that. + */ + if (PQsocket(conn) >= FD_SETSIZE) + { + pg_log_fatal("too many jobs for this platform -- try %d", i); + exit(1); + } + + init_slot(slots + i, conn); + } + } + + return slots; +} + +/* + * ParallelSlotsTerminate + * Clean up a set of parallel slots + * + * Iterate through all connections in a given set of ParallelSlots and + * terminate all connections. + */ +void +ParallelSlotsTerminate(ParallelSlot *slots, int numslots) +{ + int i; + + for (i = 0; i < numslots; i++) + { + PGconn *conn = slots[i].connection; + + if (conn == NULL) + continue; + + disconnectDatabase(conn); + } +} + +/* + * ParallelSlotsWaitCompletion + * + * Wait for all connections to finish, returning false if at least one + * error has been found on the way. + */ +bool +ParallelSlotsWaitCompletion(ParallelSlot *slots, int numslots) +{ + int i; + + for (i = 0; i < numslots; i++) + { + if (!consumeQueryResult((slots + i)->connection)) + return false; + } + + return true; +} diff --git a/src/bin/scripts/scripts_parallel.h b/src/bin/scripts/scripts_parallel.h new file mode 100644 index 00000000000..ab82c5e6a96 --- /dev/null +++ b/src/bin/scripts/scripts_parallel.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * scripts_parallel.h + * Parallel support for bin/scripts/ + * + * Copyright (c) 2003-2019, PostgreSQL Global Development Group + * + * src/bin/scripts/scripts_parallel.h + * + *------------------------------------------------------------------------- + */ +#ifndef SCRIPTS_PARALLEL_H +#define SCRIPTS_PARALLEL_H + +#include "libpq-fe.h" + + +typedef struct ParallelSlot +{ + PGconn *connection; /* One connection */ + bool isFree; /* Is it known to be idle? */ +} ParallelSlot; + +extern ParallelSlot *ParallelSlotsGetIdle(ParallelSlot *slots, int numslots); + +extern ParallelSlot *ParallelSlotsSetup(const char *dbname, const char *host, + const char *port, + const char *username, + bool prompt_password, + const char *progname, bool echo, + PGconn *conn, int numslots); + +extern void ParallelSlotsTerminate(ParallelSlot *slots, int numslots); + +extern bool ParallelSlotsWaitCompletion(ParallelSlot *slots, int numslots); + + +#endif /* SCRIPTS_PARALLEL_H */ diff --git a/src/bin/scripts/t/010_clusterdb.pl b/src/bin/scripts/t/010_clusterdb.pl index a767338f920..ba093fa3a7a 100644 --- a/src/bin/scripts/t/010_clusterdb.pl +++ b/src/bin/scripts/t/010_clusterdb.pl @@ -22,7 +22,7 @@ 'fails with nonexistent table'); $node->safe_psql('postgres', -'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a); CLUSTER test1 USING test1x' + 'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a); CLUSTER test1 USING test1x' ); $node->issues_sql_like( [ 'clusterdb', '-t', 'test1' ], diff --git a/src/bin/scripts/t/040_createuser.pl b/src/bin/scripts/t/040_createuser.pl index f4fc7ea3a45..916d9259479 100644 --- a/src/bin/scripts/t/040_createuser.pl +++ b/src/bin/scripts/t/040_createuser.pl @@ -15,19 +15,19 @@ $node->issues_sql_like( [ 'createuser', 'regress_user1' ], -qr/statement: CREATE ROLE regress_user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;/, + qr/statement: CREATE ROLE regress_user1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN;/, 'SQL CREATE USER run'); $node->issues_sql_like( [ 'createuser', '-L', 'regress_role1' ], -qr/statement: CREATE ROLE regress_role1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN;/, + qr/statement: CREATE ROLE regress_role1 NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT NOLOGIN;/, 'create a non-login role'); $node->issues_sql_like( [ 'createuser', '-r', 'regress_user2' ], -qr/statement: CREATE ROLE regress_user2 NOSUPERUSER NOCREATEDB CREATEROLE INHERIT LOGIN;/, + qr/statement: CREATE ROLE regress_user2 NOSUPERUSER NOCREATEDB CREATEROLE INHERIT LOGIN;/, 'create a CREATEROLE user'); $node->issues_sql_like( [ 'createuser', '-s', 'regress_user3' ], -qr/statement: CREATE ROLE regress_user3 SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;/, + qr/statement: CREATE ROLE regress_user3 SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN;/, 'create a superuser'); $node->command_fails([ 'createuser', 'regress_user1' ], diff --git a/src/bin/scripts/t/080_pg_isready.pl b/src/bin/scripts/t/080_pg_isready.pl index d01804da371..6da89e1b04f 100644 --- a/src/bin/scripts/t/080_pg_isready.pl +++ b/src/bin/scripts/t/080_pg_isready.pl @@ -16,4 +16,5 @@ $node->start; # use a long timeout for the benefit of very slow buildfarm machines -$node->command_ok([qw(pg_isready --timeout=60)], 'succeeds with server running'); +$node->command_ok([qw(pg_isready --timeout=60)], + 'succeeds with server running'); diff --git a/src/bin/scripts/t/090_reindexdb.pl b/src/bin/scripts/t/090_reindexdb.pl index e57a5e2bad5..c20ffbd505c 100644 --- a/src/bin/scripts/t/090_reindexdb.pl +++ b/src/bin/scripts/t/090_reindexdb.pl @@ -3,7 +3,7 @@ use PostgresNode; use TestLib; -use Test::More tests => 23; +use Test::More tests => 44; program_help_ok('reindexdb'); program_version_ok('reindexdb'); @@ -43,6 +43,32 @@ qr/statement: REINDEX \(VERBOSE\) TABLE public\.test1;/, 'reindex with verbose output'); +# the same with --concurrently +$node->issues_sql_like( + [ 'reindexdb', '--concurrently', 'postgres' ], + qr/statement: REINDEX DATABASE CONCURRENTLY postgres;/, + 'SQL REINDEX CONCURRENTLY run'); + +$node->issues_sql_like( + [ 'reindexdb', '--concurrently', '-t', 'test1', 'postgres' ], + qr/statement: REINDEX TABLE CONCURRENTLY public\.test1;/, + 'reindex specific table concurrently'); +$node->issues_sql_like( + [ 'reindexdb', '--concurrently', '-i', 'test1x', 'postgres' ], + qr/statement: REINDEX INDEX CONCURRENTLY public\.test1x;/, + 'reindex specific index concurrently'); +$node->issues_sql_like( + [ 'reindexdb', '--concurrently', '-S', 'public', 'postgres' ], + qr/statement: REINDEX SCHEMA CONCURRENTLY public;/, + 'reindex specific schema concurrently'); +$node->command_fails([ 'reindexdb', '--concurrently', '-s', 'postgres' ], + 'reindex system tables concurrently'); +$node->issues_sql_like( + [ 'reindexdb', '-v', '-t', 'test1', 'postgres' ], + qr/statement: REINDEX \(VERBOSE\) TABLE public\.test1;/, + 'reindex with verbose output'); + +# connection strings $node->command_ok([qw(reindexdb --echo --table=pg_am dbname=template1)], 'reindexdb table with connection string'); $node->command_ok( @@ -51,3 +77,45 @@ $node->command_ok( [qw(reindexdb --echo --system dbname=template1)], 'reindexdb system with connection string'); + +# parallel processing +$node->safe_psql( + 'postgres', q| + CREATE SCHEMA s1; + CREATE TABLE s1.t1(id integer); + CREATE INDEX ON s1.t1(id); + CREATE SCHEMA s2; + CREATE TABLE s2.t2(id integer); + CREATE INDEX ON s2.t2(id); + -- empty schema + CREATE SCHEMA s3; +|); + +$node->command_fails( + [ 'reindexdb', '-j', '2', '-s', 'postgres' ], + 'parallel reindexdb cannot process system catalogs'); +$node->command_fails( + [ 'reindexdb', '-j', '2', '-i', 'i1', 'postgres' ], + 'parallel reindexdb cannot process indexes'); +$node->issues_sql_like( + [ 'reindexdb', '-j', '2', 'postgres' ], + qr/statement:\ REINDEX SYSTEM postgres; +.*statement:\ REINDEX TABLE public\.test1/s, + 'parallel reindexdb for database issues REINDEX SYSTEM first'); +# Note that the ordering of the commands is not stable, so the second +# command for s2.t2 is not checked after. +$node->issues_sql_like( + [ 'reindexdb', '-j', '2', '-S', 's1', '-S', 's2', 'postgres' ], + qr/statement:\ REINDEX TABLE s1.t1;/, + 'parallel reindexdb for schemas does a per-table REINDEX'); +$node->command_ok( + ['reindexdb', '-j', '2', '-S', 's3'], + 'parallel reindexdb with empty schema'); +$node->command_checks_all( + [ 'reindexdb', '-j', '2', '--concurrently', '-d', 'postgres' ], + 0, + [qr/^$/], + [ + qr/^reindexdb: warning: cannot reindex system catalogs concurrently, skipping all/s + ], + 'parallel reindexdb for system with --concurrently skips catalogs'); diff --git a/src/bin/scripts/t/100_vacuumdb.pl b/src/bin/scripts/t/100_vacuumdb.pl index 382210e3b6e..b685b352828 100644 --- a/src/bin/scripts/t/100_vacuumdb.pl +++ b/src/bin/scripts/t/100_vacuumdb.pl @@ -3,7 +3,7 @@ use PostgresNode; use TestLib; -use Test::More tests => 23; +use Test::More tests => 44; program_help_ok('vacuumdb'); program_version_ok('vacuumdb'); @@ -15,35 +15,56 @@ $node->issues_sql_like( [ 'vacuumdb', 'postgres' ], - qr/statement: VACUUM;/, + qr/statement: VACUUM.*;/, 'SQL VACUUM run'); $node->issues_sql_like( [ 'vacuumdb', '-f', 'postgres' ], - qr/statement: VACUUM \(FULL\);/, + qr/statement: VACUUM \(FULL\).*;/, 'vacuumdb -f'); $node->issues_sql_like( [ 'vacuumdb', '-F', 'postgres' ], - qr/statement: VACUUM \(FREEZE\);/, + qr/statement: VACUUM \(FREEZE\).*;/, 'vacuumdb -F'); $node->issues_sql_like( [ 'vacuumdb', '-zj2', 'postgres' ], - qr/statement: VACUUM \(ANALYZE\) pg_catalog\./, + qr/statement: VACUUM \(ANALYZE\).*;/, 'vacuumdb -zj2'); $node->issues_sql_like( [ 'vacuumdb', '-Z', 'postgres' ], - qr/statement: ANALYZE;/, + qr/statement: ANALYZE.*;/, 'vacuumdb -Z'); +$node->issues_sql_like( + [ 'vacuumdb', '--disable-page-skipping', 'postgres' ], + qr/statement: VACUUM \(DISABLE_PAGE_SKIPPING\).*;/, + 'vacuumdb --disable-page-skipping'); +$node->issues_sql_like( + [ 'vacuumdb', '--skip-locked', 'postgres' ], + qr/statement: VACUUM \(SKIP_LOCKED\).*;/, + 'vacuumdb --skip-locked'); +$node->issues_sql_like( + [ 'vacuumdb', '--skip-locked', '--analyze-only', 'postgres' ], + qr/statement: ANALYZE \(SKIP_LOCKED\).*;/, + 'vacuumdb --skip-locked --analyze-only'); +$node->command_fails( + [ 'vacuumdb', '--analyze-only', '--disable-page-skipping', 'postgres' ], + '--analyze-only and --disable-page-skipping specified together'); $node->command_ok([qw(vacuumdb -Z --table=pg_am dbname=template1)], 'vacuumdb with connection string'); -$node->command_fails([qw(vacuumdb -Zt pg_am;ABORT postgres)], +$node->command_fails( + [qw(vacuumdb -Zt pg_am;ABORT postgres)], 'trailing command in "-t", without COLUMNS'); + # Unwanted; better if it failed. -$node->command_ok([qw(vacuumdb -Zt pg_am(amname);ABORT postgres)], +$node->command_ok( + [qw(vacuumdb -Zt pg_am(amname);ABORT postgres)], 'trailing command in "-t", with COLUMNS'); -$node->safe_psql('postgres', q| +$node->safe_psql( + 'postgres', q| CREATE TABLE "need""q(uot" (")x" text); + CREATE TABLE vactable (a int, b int); + CREATE VIEW vacview AS SELECT 1 as a; CREATE FUNCTION f0(int) RETURNS int LANGUAGE SQL AS 'SELECT $1 * $1'; CREATE FUNCTION f1(int) RETURNS int LANGUAGE SQL AS 'SELECT f0($1)'; @@ -53,5 +74,41 @@ |); $node->command_ok([qw|vacuumdb -Z --table="need""q(uot"(")x") postgres|], 'column list'); -$node->command_fails([qw|vacuumdb -Zt funcidx postgres|], +$node->command_fails( + [qw|vacuumdb -Zt funcidx postgres|], 'unqualifed name via functional index'); + +$node->command_fails( + [ 'vacuumdb', '--analyze', '--table', 'vactable(c)', 'postgres' ], + 'incorrect column name with ANALYZE'); +$node->issues_sql_like( + [ 'vacuumdb', '--analyze', '--table', 'vactable(a, b)', 'postgres' ], + qr/statement: VACUUM \(ANALYZE\) public.vactable\(a, b\);/, + 'vacuumdb --analyze with complete column list'); +$node->issues_sql_like( + [ 'vacuumdb', '--analyze-only', '--table', 'vactable(b)', 'postgres' ], + qr/statement: ANALYZE public.vactable\(b\);/, + 'vacuumdb --analyze-only with partial column list'); +$node->command_checks_all( + [ 'vacuumdb', '--analyze', '--table', 'vacview', 'postgres' ], + 0, + [qr/^.*vacuuming database "postgres"/], + [qr/^WARNING.*cannot vacuum non-tables or special system tables/s], + 'vacuumdb with view'); +$node->command_fails( + [ 'vacuumdb', '--table', 'vactable', '--min-mxid-age', '0', 'postgres' ], + 'vacuumdb --min-mxid-age with incorrect value'); +$node->command_fails( + [ 'vacuumdb', '--table', 'vactable', '--min-xid-age', '0', 'postgres' ], + 'vacuumdb --min-xid-age with incorrect value'); +$node->issues_sql_like( + [ + 'vacuumdb', '--table', 'vactable', '--min-mxid-age', + '2147483000', 'postgres' + ], + qr/GREATEST.*relminmxid.*2147483000/, + 'vacuumdb --table --min-mxid-age'); +$node->issues_sql_like( + [ 'vacuumdb', '--min-xid-age', '2147483001', 'postgres' ], + qr/GREATEST.*relfrozenxid.*2147483001/, + 'vacuumdb --table --min-xid-age'); diff --git a/src/bin/scripts/t/102_vacuumdb_stages.pl b/src/bin/scripts/t/102_vacuumdb_stages.pl index 1300aa79057..17a7fc720d2 100644 --- a/src/bin/scripts/t/102_vacuumdb_stages.pl +++ b/src/bin/scripts/t/102_vacuumdb_stages.pl @@ -10,26 +10,26 @@ $node->issues_sql_like( [ 'vacuumdb', '--analyze-in-stages', 'postgres' ], -qr/.*statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0; - .*statement:\ ANALYZE.* + qr/statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0; + .*statement:\ ANALYZE .*statement:\ SET\ default_statistics_target=10;\ RESET\ vacuum_cost_delay; - .*statement:\ ANALYZE.* + .*statement:\ ANALYZE .*statement:\ RESET\ default_statistics_target; .*statement:\ ANALYZE/sx, 'analyze three times'); $node->issues_sql_like( [ 'vacuumdb', '--analyze-in-stages', '--all' ], -qr/.*statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0; - .*statement:\ ANALYZE.* + qr/statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0; + .*statement:\ ANALYZE .*statement:\ SET\ default_statistics_target=1;\ SET\ vacuum_cost_delay=0; - .*statement:\ ANALYZE.* + .*statement:\ ANALYZE .*statement:\ SET\ default_statistics_target=10;\ RESET\ vacuum_cost_delay; - .*statement:\ ANALYZE.* + .*statement:\ ANALYZE .*statement:\ SET\ default_statistics_target=10;\ RESET\ vacuum_cost_delay; - .*statement:\ ANALYZE.* + .*statement:\ ANALYZE .*statement:\ RESET\ default_statistics_target; - .*statement:\ ANALYZE.* + .*statement:\ ANALYZE .*statement:\ RESET\ default_statistics_target; .*statement:\ ANALYZE/sx, 'analyze more than one database in stages'); diff --git a/src/bin/scripts/t/200_connstr.pl b/src/bin/scripts/t/200_connstr.pl index a3aeee762f3..ee2523d0858 100644 --- a/src/bin/scripts/t/200_connstr.pl +++ b/src/bin/scripts/t/200_connstr.pl @@ -7,10 +7,8 @@ # Tests to check connection string handling in utilities -# In a SQL_ASCII database, pgwin32_message_to_UTF16() needs to -# interpret everything as UTF8. We're going to use byte sequences -# that aren't valid UTF-8 strings, so that would fail. Use LATIN1, -# which accepts any byte and has a conversion from each byte to UTF-8. +# We're going to use byte sequences that aren't valid UTF-8 strings. Use +# LATIN1, which accepts any byte and has a conversion from each byte to UTF-8. $ENV{LC_ALL} = 'C'; $ENV{PGCLIENTENCODING} = 'LATIN1'; diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c index 60f8b1c3948..2c7219239f9 100644 --- a/src/bin/scripts/vacuumdb.c +++ b/src/bin/scripts/vacuumdb.c @@ -2,7 +2,7 @@ * * vacuumdb * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/bin/scripts/vacuumdb.c @@ -12,26 +12,16 @@ #include "postgres_fe.h" -#ifdef HAVE_SYS_SELECT_H -#include -#endif - #include "catalog/pg_class_d.h" #include "common.h" +#include "common/logging.h" +#include "fe_utils/connect.h" #include "fe_utils/simple_list.h" #include "fe_utils/string_utils.h" +#include "scripts_parallel.h" -#define ERRCODE_UNDEFINED_TABLE "42P01" - -/* Parallel vacuuming stuff */ -typedef struct ParallelSlot -{ - PGconn *connection; /* One connection */ - bool isFree; /* Is it known to be idle? */ -} ParallelSlot; - /* vacuum options controlled by user flags */ typedef struct vacuumingOptions { @@ -40,46 +30,34 @@ typedef struct vacuumingOptions bool and_analyze; bool full; bool freeze; + bool disable_page_skipping; + bool skip_locked; + int min_xid_age; + int min_mxid_age; } vacuumingOptions; static void vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, - int stage, - SimpleStringList *tables, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet); + int stage, + SimpleStringList *tables, + const char *host, const char *port, + const char *username, enum trivalue prompt_password, + int concurrentCons, + const char *progname, bool echo, bool quiet); static void vacuum_all_databases(vacuumingOptions *vacopts, - bool analyze_in_stages, - const char *maintenance_db, - const char *host, const char *port, - const char *username, enum trivalue prompt_password, - int concurrentCons, - const char *progname, bool echo, bool quiet); + bool analyze_in_stages, + const char *maintenance_db, + const char *host, const char *port, + const char *username, enum trivalue prompt_password, + int concurrentCons, + const char *progname, bool echo, bool quiet); -static void prepare_vacuum_command(PQExpBuffer sql, PGconn *conn, - vacuumingOptions *vacopts, const char *table, - bool table_pre_qualified, - const char *progname, bool echo); +static void prepare_vacuum_command(PQExpBuffer sql, int serverVersion, + vacuumingOptions *vacopts, const char *table); static void run_vacuum_command(PGconn *conn, const char *sql, bool echo, - const char *table, const char *progname, bool async); - -static ParallelSlot *GetIdleSlot(ParallelSlot slots[], int numslots, - const char *progname); - -static bool ProcessQueryResult(PGconn *conn, PGresult *result, - const char *progname); - -static bool GetQueryResult(PGconn *conn, const char *progname); - -static void DisconnectDatabase(ParallelSlot *slot); - -static int select_loop(int maxFd, fd_set *workerset, bool *aborting); - -static void init_slot(ParallelSlot *slot, PGconn *conn); + const char *table); static void help(const char *progname); @@ -110,6 +88,10 @@ main(int argc, char *argv[]) {"jobs", required_argument, NULL, 'j'}, {"maintenance-db", required_argument, NULL, 2}, {"analyze-in-stages", no_argument, NULL, 3}, + {"disable-page-skipping", no_argument, NULL, 4}, + {"skip-locked", no_argument, NULL, 5}, + {"min-xid-age", required_argument, NULL, 6}, + {"min-mxid-age", required_argument, NULL, 7}, {NULL, 0, NULL, 0} }; @@ -134,8 +116,8 @@ main(int argc, char *argv[]) /* initialize options to all false */ memset(&vacopts, 0, sizeof(vacopts)); + pg_logging_init(argv[0]); progname = get_progname(argv[0]); - set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts")); handle_help_version_opts(argc, argv, "vacuumdb", help); @@ -196,14 +178,7 @@ main(int argc, char *argv[]) concurrentCons = atoi(optarg); if (concurrentCons <= 0) { - fprintf(stderr, _("%s: number of parallel jobs must be at least 1\n"), - progname); - exit(1); - } - if (concurrentCons > FD_SETSIZE - 1) - { - fprintf(stderr, _("%s: too many parallel jobs requested (maximum: %d)\n"), - progname, FD_SETSIZE - 1); + pg_log_error("number of parallel jobs must be at least 1"); exit(1); } break; @@ -213,6 +188,28 @@ main(int argc, char *argv[]) case 3: analyze_in_stages = vacopts.analyze_only = true; break; + case 4: + vacopts.disable_page_skipping = true; + break; + case 5: + vacopts.skip_locked = true; + break; + case 6: + vacopts.min_xid_age = atoi(optarg); + if (vacopts.min_xid_age <= 0) + { + pg_log_error("minimum transaction ID age must be at least 1"); + exit(1); + } + break; + case 7: + vacopts.min_mxid_age = atoi(optarg); + if (vacopts.min_mxid_age <= 0) + { + pg_log_error("minimum multixact ID age must be at least 1"); + exit(1); + } + break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); @@ -231,8 +228,8 @@ main(int argc, char *argv[]) if (optind < argc) { - fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"), - progname, argv[optind]); + pg_log_error("too many command-line arguments (first is \"%s\")", + argv[optind]); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); exit(1); } @@ -241,14 +238,20 @@ main(int argc, char *argv[]) { if (vacopts.full) { - fprintf(stderr, _("%s: cannot use the \"%s\" option when performing only analyze\n"), - progname, "full"); + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "full"); exit(1); } if (vacopts.freeze) { - fprintf(stderr, _("%s: cannot use the \"%s\" option when performing only analyze\n"), - progname, "freeze"); + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "freeze"); + exit(1); + } + if (vacopts.disable_page_skipping) + { + pg_log_error("cannot use the \"%s\" option when performing only analyze", + "disable-page-skipping"); exit(1); } /* allow 'and_analyze' with 'analyze_only' */ @@ -264,14 +267,12 @@ main(int argc, char *argv[]) { if (dbname) { - fprintf(stderr, _("%s: cannot vacuum all databases and a specific one at the same time\n"), - progname); + pg_log_error("cannot vacuum all databases and a specific one at the same time"); exit(1); } if (tables.head != NULL) { - fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"), - progname); + pg_log_error("cannot vacuum specific table(s) in all databases"); exit(1); } @@ -343,13 +344,19 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, const char *progname, bool echo, bool quiet) { PQExpBufferData sql; + PQExpBufferData buf; + PQExpBufferData catalog_query; + PGresult *res; PGconn *conn; SimpleStringListCell *cell; ParallelSlot *slots; SimpleStringList dbtables = {NULL, NULL}; int i; + int ntups; bool failed = false; bool parallel = concurrentCons > 1; + bool tables_listed = false; + bool has_where = false; const char *stage_commands[] = { "SET default_statistics_target=1; SET vacuum_cost_delay=0;", "SET default_statistics_target=10; RESET vacuum_cost_delay;", @@ -367,65 +374,215 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, conn = connectDatabase(dbname, host, port, username, prompt_password, progname, echo, false, true); + if (vacopts->disable_page_skipping && PQserverVersion(conn) < 90600) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "disable-page-skipping", "9.6"); + exit(1); + } + + if (vacopts->skip_locked && PQserverVersion(conn) < 120000) + { + PQfinish(conn); + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "skip-locked", "12"); + exit(1); + } + + if (vacopts->min_xid_age != 0 && PQserverVersion(conn) < 90600) + { + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "--min-xid-age", "9.6"); + exit(1); + } + + if (vacopts->min_mxid_age != 0 && PQserverVersion(conn) < 90600) + { + pg_log_error("cannot use the \"%s\" option on server versions older than PostgreSQL %s", + "--min-mxid-age", "9.6"); + exit(1); + } + if (!quiet) { if (stage != ANALYZE_NO_STAGE) printf(_("%s: processing database \"%s\": %s\n"), - progname, PQdb(conn), stage_messages[stage]); + progname, PQdb(conn), _(stage_messages[stage])); else printf(_("%s: vacuuming database \"%s\"\n"), progname, PQdb(conn)); fflush(stdout); } - initPQExpBuffer(&sql); - /* - * If a table list is not provided and we're using multiple connections, - * prepare the list of tables by querying the catalogs. + * Prepare the list of tables to process by querying the catalogs. + * + * Since we execute the constructed query with the default search_path + * (which could be unsafe), everything in this query MUST be fully + * qualified. + * + * First, build a WITH clause for the catalog query if any tables were + * specified, with a set of values made of relation names and their + * optional set of columns. This is used to match any provided column + * lists with the generated qualified identifiers and to filter for the + * tables provided via --table. If a listed table does not exist, the + * catalog query will fail. */ - if (parallel && (!tables || !tables->head)) + initPQExpBuffer(&catalog_query); + for (cell = tables ? tables->head : NULL; cell; cell = cell->next) { - PQExpBufferData buf; - PGresult *res; - int ntups; - - initPQExpBuffer(&buf); - - res = executeQuery(conn, - "SELECT c.relname, ns.nspname" - " FROM pg_class c, pg_namespace ns\n" - " WHERE relkind IN (" - CppAsString2(RELKIND_RELATION) ", " - CppAsString2(RELKIND_MATVIEW) ")" - " AND c.relnamespace = ns.oid\n" - " ORDER BY c.relpages DESC;", - progname, echo); - - ntups = PQntuples(res); - for (i = 0; i < ntups; i++) - { - appendPQExpBufferStr(&buf, - fmtQualifiedId(PQserverVersion(conn), - PQgetvalue(res, i, 1), - PQgetvalue(res, i, 0))); + char *just_table; + const char *just_columns; - simple_string_list_append(&dbtables, buf.data); - resetPQExpBuffer(&buf); + /* + * Split relation and column names given by the user, this is used to + * feed the CTE with values on which are performed pre-run validity + * checks as well. For now these happen only on the relation name. + */ + splitTableColumnsSpec(cell->val, PQclientEncoding(conn), + &just_table, &just_columns); + + if (!tables_listed) + { + appendPQExpBufferStr(&catalog_query, + "WITH listed_tables (table_oid, column_list) " + "AS (\n VALUES ("); + tables_listed = true; } + else + appendPQExpBufferStr(&catalog_query, ",\n ("); - termPQExpBuffer(&buf); - tables = &dbtables; + appendStringLiteralConn(&catalog_query, just_table, conn); + appendPQExpBufferStr(&catalog_query, "::pg_catalog.regclass, "); - /* - * If there are more connections than vacuumable relations, we don't - * need to use them all. - */ + if (just_columns && just_columns[0] != '\0') + appendStringLiteralConn(&catalog_query, just_columns, conn); + else + appendPQExpBufferStr(&catalog_query, "NULL"); + + appendPQExpBufferStr(&catalog_query, "::pg_catalog.text)"); + + pg_free(just_table); + } + + /* Finish formatting the CTE */ + if (tables_listed) + appendPQExpBufferStr(&catalog_query, "\n)\n"); + + appendPQExpBufferStr(&catalog_query, "SELECT c.relname, ns.nspname"); + + if (tables_listed) + appendPQExpBufferStr(&catalog_query, ", listed_tables.column_list"); + + appendPQExpBufferStr(&catalog_query, + " FROM pg_catalog.pg_class c\n" + " JOIN pg_catalog.pg_namespace ns" + " ON c.relnamespace OPERATOR(pg_catalog.=) ns.oid\n" + " LEFT JOIN pg_catalog.pg_class t" + " ON c.reltoastrelid OPERATOR(pg_catalog.=) t.oid\n"); + + /* Used to match the tables listed by the user */ + if (tables_listed) + appendPQExpBufferStr(&catalog_query, " JOIN listed_tables" + " ON listed_tables.table_oid OPERATOR(pg_catalog.=) c.oid\n"); + + /* + * If no tables were listed, filter for the relevant relation types. If + * tables were given via --table, don't bother filtering by relation type. + * Instead, let the server decide whether a given relation can be + * processed in which case the user will know about it. + */ + if (!tables_listed) + { + appendPQExpBufferStr(&catalog_query, " WHERE c.relkind OPERATOR(pg_catalog.=) ANY (array[" + CppAsString2(RELKIND_RELATION) ", " + CppAsString2(RELKIND_MATVIEW) "])\n"); + has_where = true; + } + + /* + * For --min-xid-age and --min-mxid-age, the age of the relation is the + * greatest of the ages of the main relation and its associated TOAST + * table. The commands generated by vacuumdb will also process the TOAST + * table for the relation if necessary, so it does not need to be + * considered separately. + */ + if (vacopts->min_xid_age != 0) + { + appendPQExpBuffer(&catalog_query, + " %s GREATEST(pg_catalog.age(c.relfrozenxid)," + " pg_catalog.age(t.relfrozenxid)) " + " OPERATOR(pg_catalog.>=) '%d'::pg_catalog.int4\n" + " AND c.relfrozenxid OPERATOR(pg_catalog.!=)" + " '0'::pg_catalog.xid\n", + has_where ? "AND" : "WHERE", vacopts->min_xid_age); + has_where = true; + } + + if (vacopts->min_mxid_age != 0) + { + appendPQExpBuffer(&catalog_query, + " %s GREATEST(pg_catalog.mxid_age(c.relminmxid)," + " pg_catalog.mxid_age(t.relminmxid)) OPERATOR(pg_catalog.>=)" + " '%d'::pg_catalog.int4\n" + " AND c.relminmxid OPERATOR(pg_catalog.!=)" + " '0'::pg_catalog.xid\n", + has_where ? "AND" : "WHERE", vacopts->min_mxid_age); + has_where = true; + } + + /* + * Execute the catalog query. We use the default search_path for this + * query for consistency with table lookups done elsewhere by the user. + */ + appendPQExpBufferStr(&catalog_query, " ORDER BY c.relpages DESC;"); + executeCommand(conn, "RESET search_path;", echo); + res = executeQuery(conn, catalog_query.data, echo); + termPQExpBuffer(&catalog_query); + PQclear(executeQuery(conn, ALWAYS_SECURE_SEARCH_PATH_SQL, echo)); + + /* + * If no rows are returned, there are no matching tables, so we are done. + */ + ntups = PQntuples(res); + if (ntups == 0) + { + PQclear(res); + PQfinish(conn); + return; + } + + /* + * Build qualified identifiers for each table, including the column list + * if given. + */ + initPQExpBuffer(&buf); + for (i = 0; i < ntups; i++) + { + appendPQExpBufferStr(&buf, + fmtQualifiedId(PQgetvalue(res, i, 1), + PQgetvalue(res, i, 0))); + + if (tables_listed && !PQgetisnull(res, i, 2)) + appendPQExpBufferStr(&buf, PQgetvalue(res, i, 2)); + + simple_string_list_append(&dbtables, buf.data); + resetPQExpBuffer(&buf); + } + termPQExpBuffer(&buf); + PQclear(res); + + /* + * If there are more connections than vacuumable relations, we don't need + * to use them all. + */ + if (parallel) + { if (concurrentCons > ntups) concurrentCons = ntups; if (concurrentCons <= 1) parallel = false; - PQclear(res); } /* @@ -435,17 +592,9 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, */ if (concurrentCons <= 0) concurrentCons = 1; - slots = (ParallelSlot *) pg_malloc(sizeof(ParallelSlot) * concurrentCons); - init_slot(slots, conn); - if (parallel) - { - for (i = 1; i < concurrentCons; i++) - { - conn = connectDatabase(dbname, host, port, username, prompt_password, - progname, echo, false, true); - init_slot(slots + i, conn); - } - } + + slots = ParallelSlotsSetup(dbname, host, port, username, prompt_password, + progname, echo, conn, concurrentCons); /* * Prepare all the connections to run the appropriate analyze stage, if @@ -459,13 +608,15 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, for (j = 0; j < concurrentCons; j++) executeCommand((slots + j)->connection, - stage_commands[stage], progname, echo); + stage_commands[stage], echo); } - cell = tables ? tables->head : NULL; + initPQExpBuffer(&sql); + + cell = dbtables.head; do { - const char *tabname = cell ? cell->val : NULL; + const char *tabname = cell->val; ParallelSlot *free_slot; if (CancelRequested) @@ -474,65 +625,32 @@ vacuum_one_database(const char *dbname, vacuumingOptions *vacopts, goto finish; } - /* - * Get the connection slot to use. If in parallel mode, here we wait - * for one connection to become available if none already is. In - * non-parallel mode we simply use the only slot we have, which we - * know to be free. - */ - if (parallel) + free_slot = ParallelSlotsGetIdle(slots, concurrentCons); + if (!free_slot) { - /* - * Get a free slot, waiting until one becomes free if none - * currently is. - */ - free_slot = GetIdleSlot(slots, concurrentCons, progname); - if (!free_slot) - { - failed = true; - goto finish; - } - - free_slot->isFree = false; + failed = true; + goto finish; } - else - free_slot = slots; - /* - * Prepare the vacuum command. Note that in some cases this requires - * query execution, so be sure to use the free connection. - */ - prepare_vacuum_command(&sql, free_slot->connection, vacopts, tabname, - tables == &dbtables, progname, echo); + prepare_vacuum_command(&sql, PQserverVersion(free_slot->connection), + vacopts, tabname); /* - * Execute the vacuum. If not in parallel mode, this terminates the - * program in case of an error. (The parallel case handles query - * errors in ProcessQueryResult through GetIdleSlot.) + * Execute the vacuum. All errors are handled in processQueryResult + * through ParallelSlotsGetIdle. */ run_vacuum_command(free_slot->connection, sql.data, - echo, tabname, progname, parallel); + echo, tabname); - if (cell) - cell = cell->next; + cell = cell->next; } while (cell != NULL); - if (parallel) - { - int j; - - /* wait for all connections to finish */ - for (j = 0; j < concurrentCons; j++) - { - if (!GetQueryResult((slots + j)->connection, progname)) - goto finish; - } - } + if (!ParallelSlotsWaitCompletion(slots, concurrentCons)) + failed = true; finish: - for (i = 0; i < concurrentCons; i++) - DisconnectDatabase(slots + i); - pfree(slots); + ParallelSlotsTerminate(slots, concurrentCons); + pg_free(slots); termPQExpBuffer(&sql); @@ -566,7 +684,7 @@ vacuum_all_databases(vacuumingOptions *vacopts, prompt_password, progname, echo); result = executeQuery(conn, "SELECT datname FROM pg_database WHERE datallowconn ORDER BY 1;", - progname, echo); + echo); PQfinish(conn); initPQExpBuffer(&connstr); @@ -585,7 +703,7 @@ vacuum_all_databases(vacuumingOptions *vacopts, for (i = 0; i < PQntuples(result); i++) { resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, PQgetvalue(result, i, 0)); vacuum_one_database(connstr.data, vacopts, @@ -602,7 +720,7 @@ vacuum_all_databases(vacuumingOptions *vacopts, for (i = 0; i < PQntuples(result); i++) { resetPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, PQgetvalue(result, i, 0)); vacuum_one_database(connstr.data, vacopts, @@ -622,32 +740,68 @@ vacuum_all_databases(vacuumingOptions *vacopts, * Construct a vacuum/analyze command to run based on the given options, in the * given string buffer, which may contain previous garbage. * - * An optional table name can be passed; this must be already be properly - * quoted. The command is semicolon-terminated. + * The table name used must be already properly quoted. The command generated + * depends on the server version involved and it is semicolon-terminated. */ static void -prepare_vacuum_command(PQExpBuffer sql, PGconn *conn, - vacuumingOptions *vacopts, const char *table, - bool table_pre_qualified, - const char *progname, bool echo) +prepare_vacuum_command(PQExpBuffer sql, int serverVersion, + vacuumingOptions *vacopts, const char *table) { + const char *paren = " ("; + const char *comma = ", "; + const char *sep = paren; + resetPQExpBuffer(sql); if (vacopts->analyze_only) { appendPQExpBufferStr(sql, "ANALYZE"); - if (vacopts->verbose) - appendPQExpBufferStr(sql, " VERBOSE"); + + /* parenthesized grammar of ANALYZE is supported since v11 */ + if (serverVersion >= 110000) + { + if (vacopts->skip_locked) + { + /* SKIP_LOCKED is supported since v12 */ + Assert(serverVersion >= 120000); + appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep); + sep = comma; + } + if (vacopts->verbose) + { + appendPQExpBuffer(sql, "%sVERBOSE", sep); + sep = comma; + } + if (sep != paren) + appendPQExpBufferChar(sql, ')'); + } + else + { + if (vacopts->verbose) + appendPQExpBufferStr(sql, " VERBOSE"); + } } else { appendPQExpBufferStr(sql, "VACUUM"); - if (PQserverVersion(conn) >= 90000) - { - const char *paren = " ("; - const char *comma = ", "; - const char *sep = paren; + /* parenthesized grammar of VACUUM is supported since v9.0 */ + if (serverVersion >= 90000) + { + if (vacopts->disable_page_skipping) + { + /* DISABLE_PAGE_SKIPPING is supported since v9.6 */ + Assert(serverVersion >= 90600); + appendPQExpBuffer(sql, "%sDISABLE_PAGE_SKIPPING", sep); + sep = comma; + } + if (vacopts->skip_locked) + { + /* SKIP_LOCKED is supported since v12 */ + Assert(serverVersion >= 120000); + appendPQExpBuffer(sql, "%sSKIP_LOCKED", sep); + sep = comma; + } if (vacopts->full) { appendPQExpBuffer(sql, "%sFULL", sep); @@ -684,312 +838,35 @@ prepare_vacuum_command(PQExpBuffer sql, PGconn *conn, } } - if (table) - { - appendPQExpBufferChar(sql, ' '); - if (table_pre_qualified) - appendPQExpBufferStr(sql, table); - else - appendQualifiedRelation(sql, table, conn, progname, echo); - } - appendPQExpBufferChar(sql, ';'); + appendPQExpBuffer(sql, " %s;", table); } /* - * Send a vacuum/analyze command to the server. In async mode, return after - * sending the command; else, wait for it to finish. + * Send a vacuum/analyze command to the server, returning after sending the + * command. * - * Any errors during command execution are reported to stderr. If async is - * false, this function exits the program after reporting the error. + * Any errors during command execution are reported to stderr. */ static void run_vacuum_command(PGconn *conn, const char *sql, bool echo, - const char *table, const char *progname, bool async) + const char *table) { bool status; - if (async) - { - if (echo) - printf("%s\n", sql); + if (echo) + printf("%s\n", sql); - status = PQsendQuery(conn, sql) == 1; - } - else - status = executeMaintenanceCommand(conn, sql, echo); + status = PQsendQuery(conn, sql) == 1; if (!status) { if (table) - fprintf(stderr, - _("%s: vacuuming of table \"%s\" in database \"%s\" failed: %s"), - progname, table, PQdb(conn), PQerrorMessage(conn)); + pg_log_error("vacuuming of table \"%s\" in database \"%s\" failed: %s", + table, PQdb(conn), PQerrorMessage(conn)); else - fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"), - progname, PQdb(conn), PQerrorMessage(conn)); - - if (!async) - { - PQfinish(conn); - exit(1); - } - } -} - -/* - * GetIdleSlot - * Return a connection slot that is ready to execute a command. - * - * We return the first slot we find that is marked isFree, if one is; - * otherwise, we loop on select() until one socket becomes available. When - * this happens, we read the whole set and mark as free all sockets that become - * available. - * - * If an error occurs, NULL is returned. - */ -static ParallelSlot * -GetIdleSlot(ParallelSlot slots[], int numslots, - const char *progname) -{ - int i; - int firstFree = -1; - - /* Any connection already known free? */ - for (i = 0; i < numslots; i++) - { - if (slots[i].isFree) - return slots + i; - } - - /* - * No free slot found, so wait until one of the connections has finished - * its task and return the available slot. - */ - while (firstFree < 0) - { - fd_set slotset; - int maxFd = 0; - bool aborting; - - /* We must reconstruct the fd_set for each call to select_loop */ - FD_ZERO(&slotset); - - for (i = 0; i < numslots; i++) - { - int sock = PQsocket(slots[i].connection); - - /* - * We don't really expect any connections to lose their sockets - * after startup, but just in case, cope by ignoring them. - */ - if (sock < 0) - continue; - - FD_SET(sock, &slotset); - if (sock > maxFd) - maxFd = sock; - } - - SetCancelConn(slots->connection); - i = select_loop(maxFd, &slotset, &aborting); - ResetCancelConn(); - - if (aborting) - { - /* - * We set the cancel-receiving connection to the one in the zeroth - * slot above, so fetch the error from there. - */ - GetQueryResult(slots->connection, progname); - return NULL; - } - Assert(i != 0); - - for (i = 0; i < numslots; i++) - { - int sock = PQsocket(slots[i].connection); - - if (sock >= 0 && FD_ISSET(sock, &slotset)) - { - /* select() says input is available, so consume it */ - PQconsumeInput(slots[i].connection); - } - - /* Collect result(s) as long as any are available */ - while (!PQisBusy(slots[i].connection)) - { - PGresult *result = PQgetResult(slots[i].connection); - - if (result != NULL) - { - /* Check and discard the command result */ - if (!ProcessQueryResult(slots[i].connection, result, - progname)) - return NULL; - } - else - { - /* This connection has become idle */ - slots[i].isFree = true; - if (firstFree < 0) - firstFree = i; - break; - } - } - } + pg_log_error("vacuuming of database \"%s\" failed: %s", + PQdb(conn), PQerrorMessage(conn)); } - - return slots + firstFree; -} - -/* - * ProcessQueryResult - * - * Process (and delete) a query result. Returns true if there's no error, - * false otherwise -- but errors about trying to vacuum a missing relation - * are reported and subsequently ignored. - */ -static bool -ProcessQueryResult(PGconn *conn, PGresult *result, const char *progname) -{ - /* - * If it's an error, report it. Errors about a missing table are harmless - * so we continue processing; but die for other errors. - */ - if (PQresultStatus(result) != PGRES_COMMAND_OK) - { - char *sqlState = PQresultErrorField(result, PG_DIAG_SQLSTATE); - - fprintf(stderr, _("%s: vacuuming of database \"%s\" failed: %s"), - progname, PQdb(conn), PQerrorMessage(conn)); - - if (sqlState && strcmp(sqlState, ERRCODE_UNDEFINED_TABLE) != 0) - { - PQclear(result); - return false; - } - } - - PQclear(result); - return true; -} - -/* - * GetQueryResult - * - * Pump the conn till it's dry of results; return false if any are errors. - * Note that this will block if the conn is busy. - */ -static bool -GetQueryResult(PGconn *conn, const char *progname) -{ - bool ok = true; - PGresult *result; - - SetCancelConn(conn); - while ((result = PQgetResult(conn)) != NULL) - { - if (!ProcessQueryResult(conn, result, progname)) - ok = false; - } - ResetCancelConn(); - return ok; -} - -/* - * DisconnectDatabase - * Disconnect the connection associated with the given slot - */ -static void -DisconnectDatabase(ParallelSlot *slot) -{ - char errbuf[256]; - - if (!slot->connection) - return; - - if (PQtransactionStatus(slot->connection) == PQTRANS_ACTIVE) - { - PGcancel *cancel; - - if ((cancel = PQgetCancel(slot->connection))) - { - (void) PQcancel(cancel, errbuf, sizeof(errbuf)); - PQfreeCancel(cancel); - } - } - - PQfinish(slot->connection); - slot->connection = NULL; -} - -/* - * Loop on select() until a descriptor from the given set becomes readable. - * - * If we get a cancel request while we're waiting, we forego all further - * processing and set the *aborting flag to true. The return value must be - * ignored in this case. Otherwise, *aborting is set to false. - */ -static int -select_loop(int maxFd, fd_set *workerset, bool *aborting) -{ - int i; - fd_set saveSet = *workerset; - - if (CancelRequested) - { - *aborting = true; - return -1; - } - else - *aborting = false; - - for (;;) - { - /* - * On Windows, we need to check once in a while for cancel requests; - * on other platforms we rely on select() returning when interrupted. - */ - struct timeval *tvp; -#ifdef WIN32 - struct timeval tv = {0, 1000000}; - - tvp = &tv; -#else - tvp = NULL; -#endif - - *workerset = saveSet; - i = select(maxFd + 1, workerset, NULL, NULL, tvp); - -#ifdef WIN32 - if (i == SOCKET_ERROR) - { - i = -1; - - if (WSAGetLastError() == WSAEINTR) - errno = EINTR; - } -#endif - - if (i < 0 && errno == EINTR) - continue; /* ignore this */ - if (i < 0 || CancelRequested) - *aborting = true; /* but not this */ - if (i == 0) - continue; /* timeout (Win32 only) */ - break; - } - - return i; -} - -static void -init_slot(ParallelSlot *slot, PGconn *conn) -{ - slot->connection = conn; - /* Initially assume connection is idle */ - slot->isFree = true; } static void @@ -1001,11 +878,15 @@ help(const char *progname) printf(_("\nOptions:\n")); printf(_(" -a, --all vacuum all databases\n")); printf(_(" -d, --dbname=DBNAME database to vacuum\n")); + printf(_(" --disable-page-skipping disable all page-skipping behavior\n")); printf(_(" -e, --echo show the commands being sent to the server\n")); printf(_(" -f, --full do full vacuuming\n")); printf(_(" -F, --freeze freeze row transaction information\n")); printf(_(" -j, --jobs=NUM use this many concurrent connections to vacuum\n")); + printf(_(" --min-mxid-age=MXID_AGE minimum multixact ID age of tables to vacuum\n")); + printf(_(" --min-xid-age=XID_AGE minimum transaction ID age of tables to vacuum\n")); printf(_(" -q, --quiet don't write any messages\n")); + printf(_(" --skip-locked skip relations that cannot be immediately locked\n")); printf(_(" -t, --table='TABLE[(COLUMNS)]' vacuum specific table(s) only\n")); printf(_(" -v, --verbose write a lot of output\n")); printf(_(" -V, --version output version information, then exit\n")); @@ -1022,5 +903,5 @@ help(const char *progname) printf(_(" -W, --password force password prompt\n")); printf(_(" --maintenance-db=DBNAME alternate maintenance database\n")); printf(_("\nRead the description of the SQL command VACUUM for details.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } diff --git a/src/common/.gitignore b/src/common/.gitignore new file mode 100644 index 00000000000..ffa3284fbfe --- /dev/null +++ b/src/common/.gitignore @@ -0,0 +1 @@ +/kwlist_d.h diff --git a/src/common/Makefile b/src/common/Makefile index 1fc2c66225b..2f22b9b101d 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -3,17 +3,21 @@ # Makefile # Makefile for src/common # -# This makefile generates two outputs: +# These files are used by the Postgres backend, and also by frontend +# programs. These files provide common functionality that isn't directly +# concerned with portability and thus doesn't belong in src/port. +# +# This makefile generates three outputs: # # libpgcommon.a - contains object files with FRONTEND defined, # for use by client applications # -# libpgcommon_srv.a - contains object files without FRONTEND defined, -# for use only by the backend binaries +# libpgcommon_shlib.a - contains object files with FRONTEND defined, +# built suitably for use in shared libraries; for use +# by frontend libraries # -# You can also symlink/copy individual source files from this directory, -# to compile with different options. (libpq does that, because it needs -# to use -fPIC on some platforms.) +# libpgcommon_srv.a - contains object files without FRONTEND defined, +# for use only by the backend # # IDENTIFICATION # src/common/Makefile @@ -37,11 +41,14 @@ override CPPFLAGS += -DVAL_LDFLAGS_EX="\"$(LDFLAGS_EX)\"" override CPPFLAGS += -DVAL_LDFLAGS_SL="\"$(LDFLAGS_SL)\"" override CPPFLAGS += -DVAL_LIBS="\"$(LIBS)\"" -override CPPFLAGS := -DFRONTEND $(CPPFLAGS) +override CPPFLAGS := -DFRONTEND -I. -I$(top_srcdir)/src/common $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) -OBJS_COMMON = base64.o config_info.o controldata_utils.o exec.o file_perm.o \ - ip.o keywords.o md5.o pg_lzcompress.o pgfnames.o psprintf.o relpath.o \ +# If you add objects here, see also src/tools/msvc/Mkvcbuild.pm + +OBJS_COMMON = base64.o config_info.o controldata_utils.o d2s.o exec.o f2s.o \ + file_perm.o ip.o keywords.o kwlookup.o link-canary.o md5.o \ + pg_lzcompress.o pgfnames.o psprintf.o relpath.o \ rmtree.o saslprep.o scram-common.o string.o unicode_norm.o \ username.o wait_error.o @@ -51,26 +58,57 @@ else OBJS_COMMON += sha2.o endif -OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o file_utils.o restricted_token.o +# A few files are currently only built for frontend, not server +# (Mkvcbuild.pm has a copy of this list, too) +OBJS_FRONTEND = $(OBJS_COMMON) fe_memutils.o file_utils.o \ + logging.o restricted_token.o +# foo.o, foo_shlib.o, and foo_srv.o are all built from foo.c +OBJS_SHLIB = $(OBJS_FRONTEND:%.o=%_shlib.o) OBJS_SRV = $(OBJS_COMMON:%.o=%_srv.o) -all: libpgcommon.a libpgcommon_srv.a +# where to find gen_keywordlist.pl and subsidiary files +TOOLSDIR = $(top_srcdir)/src/tools +GEN_KEYWORDLIST = $(PERL) -I $(TOOLSDIR) $(TOOLSDIR)/gen_keywordlist.pl +GEN_KEYWORDLIST_DEPS = $(TOOLSDIR)/gen_keywordlist.pl $(TOOLSDIR)/PerfectHash.pm + +all: libpgcommon.a libpgcommon_shlib.a libpgcommon_srv.a + +distprep: kwlist_d.h # libpgcommon is needed by some contrib install: all installdirs $(INSTALL_STLIB) libpgcommon.a '$(DESTDIR)$(libdir)/libpgcommon.a' + $(INSTALL_STLIB) libpgcommon_shlib.a '$(DESTDIR)$(libdir)/libpgcommon_shlib.a' installdirs: $(MKDIR_P) '$(DESTDIR)$(libdir)' uninstall: rm -f '$(DESTDIR)$(libdir)/libpgcommon.a' + rm -f '$(DESTDIR)$(libdir)/libpgcommon_shlib.a' libpgcommon.a: $(OBJS_FRONTEND) rm -f $@ $(AR) $(AROPT) $@ $^ +# +# Shared library versions of object files +# + +libpgcommon_shlib.a: $(OBJS_SHLIB) + rm -f $@ + $(AR) $(AROPT) $@ $^ + +# Because this uses its own compilation rule, it doesn't use the +# dependency tracking logic from Makefile.global. To make sure that +# dependency tracking works anyway for the *_shlib.o files, depend on +# their *.o siblings as well, which do have proper dependencies. It's +# a hack that might fail someday if there is a *_shlib.o without a +# corresponding *.o, but there seems little reason for that. +%_shlib.o: %.c %.o + $(CC) $(CFLAGS) $(CFLAGS_SL) $(CPPFLAGS) -c $< -o $@ + # # Server versions of object files # @@ -86,16 +124,27 @@ libpgcommon_srv.a: $(OBJS_SRV) # a hack that might fail someday if there is a *_srv.o without a # corresponding *.o, but it works for now. %_srv.o: %.c %.o - $(CC) $(CFLAGS) $(subst -DFRONTEND ,, $(CPPFLAGS)) -c $< -o $@ + $(CC) $(CFLAGS) $(subst -DFRONTEND,, $(CPPFLAGS)) -c $< -o $@ + +# generate SQL keyword lookup table to be included into keywords*.o. +kwlist_d.h: $(top_srcdir)/src/include/parser/kwlist.h $(GEN_KEYWORDLIST_DEPS) + $(GEN_KEYWORDLIST) --extern $< -# Dependencies of keywords.o need to be managed explicitly to make sure +# Dependencies of keywords*.o need to be managed explicitly to make sure # that you don't get broken parsing code, even in a non-enable-depend build. -# Note that gram.h isn't required for the frontend version of keywords.o. -$(top_builddir)/src/include/parser/gram.h: $(top_srcdir)/src/backend/parser/gram.y - $(MAKE) -C $(top_builddir)/src/backend $(top_builddir)/src/include/parser/gram.h +keywords.o keywords_shlib.o keywords_srv.o: kwlist_d.h + +# The code imported from Ryu gets a pass on declaration-after-statement, +# in order to keep it more closely aligned with its upstream. +RYU_FILES = d2s.o f2s.o +RYU_OBJS = $(RYU_FILES) $(RYU_FILES:%.o=%_shlib.o) $(RYU_FILES:%.o=%_srv.o) + +$(RYU_OBJS): CFLAGS += $(PERMIT_DECLARATION_AFTER_STATEMENT) -keywords.o: $(top_srcdir)/src/include/parser/kwlist.h -keywords_srv.o: $(top_builddir)/src/include/parser/gram.h $(top_srcdir)/src/include/parser/kwlist.h +# kwlist_d.h is in the distribution tarball, so it is not cleaned here. +clean distclean: + rm -f libpgcommon.a libpgcommon_shlib.a libpgcommon_srv.a + rm -f $(OBJS_FRONTEND) $(OBJS_SHLIB) $(OBJS_SRV) -clean distclean maintainer-clean: - rm -f libpgcommon.a libpgcommon_srv.a $(OBJS_FRONTEND) $(OBJS_SRV) +maintainer-clean: distclean + rm -f kwlist_d.h diff --git a/src/common/base64.c b/src/common/base64.c index c6fde2a8dd6..57ec06c3a95 100644 --- a/src/common/base64.c +++ b/src/common/base64.c @@ -3,7 +3,7 @@ * base64.c * Encoding and decoding routines for base64 without whitespace. * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * * IDENTIFICATION @@ -42,10 +42,11 @@ static const int8 b64lookup[128] = { * pg_b64_encode * * Encode into base64 the given string. Returns the length of the encoded - * string. + * string, and -1 in the event of an error with the result buffer zeroed + * for safety. */ int -pg_b64_encode(const char *src, int len, char *dst) +pg_b64_encode(const char *src, int len, char *dst, int dstlen) { char *p; const char *s, @@ -65,6 +66,13 @@ pg_b64_encode(const char *src, int len, char *dst) /* write it out */ if (pos < 0) { + /* + * Leave if there is an overflow in the area allocated for the + * encoded string. + */ + if ((p - dst + 4) > dstlen) + goto error; + *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = _base64[(buf >> 6) & 0x3f]; @@ -76,23 +84,36 @@ pg_b64_encode(const char *src, int len, char *dst) } if (pos != 2) { + /* + * Leave if there is an overflow in the area allocated for the encoded + * string. + */ + if ((p - dst + 4) > dstlen) + goto error; + *p++ = _base64[(buf >> 18) & 0x3f]; *p++ = _base64[(buf >> 12) & 0x3f]; *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; *p++ = '='; } + Assert((p - dst) <= dstlen); return p - dst; + +error: + memset(dst, 0, dstlen); + return -1; } /* * pg_b64_decode * * Decode the given base64 string. Returns the length of the decoded - * string on success, and -1 in the event of an error. + * string on success, and -1 in the event of an error with the result + * buffer zeroed for safety. */ int -pg_b64_decode(const char *src, int len, char *dst) +pg_b64_decode(const char *src, int len, char *dst, int dstlen) { const char *srcend = src + len, *s = src; @@ -109,7 +130,7 @@ pg_b64_decode(const char *src, int len, char *dst) /* Leave if a whitespace is found */ if (c == ' ' || c == '\t' || c == '\n' || c == '\r') - return -1; + goto error; if (c == '=') { @@ -126,7 +147,7 @@ pg_b64_decode(const char *src, int len, char *dst) * Unexpected "=" character found while decoding base64 * sequence. */ - return -1; + goto error; } } b = 0; @@ -139,7 +160,7 @@ pg_b64_decode(const char *src, int len, char *dst) if (b < 0) { /* invalid symbol found */ - return -1; + goto error; } } /* add it to buffer */ @@ -147,11 +168,28 @@ pg_b64_decode(const char *src, int len, char *dst) pos++; if (pos == 4) { + /* + * Leave if there is an overflow in the area allocated for the + * decoded string. + */ + if ((p - dst + 1) > dstlen) + goto error; *p++ = (buf >> 16) & 255; + if (end == 0 || end > 1) + { + /* overflow check */ + if ((p - dst + 1) > dstlen) + goto error; *p++ = (buf >> 8) & 255; + } if (end == 0 || end > 2) + { + /* overflow check */ + if ((p - dst + 1) > dstlen) + goto error; *p++ = buf & 255; + } buf = 0; pos = 0; } @@ -163,10 +201,15 @@ pg_b64_decode(const char *src, int len, char *dst) * base64 end sequence is invalid. Input data is missing padding, is * truncated or is otherwise corrupted. */ - return -1; + goto error; } + Assert((p - dst) <= dstlen); return p - dst; + +error: + memset(dst, 0, dstlen); + return -1; } /* diff --git a/src/common/config_info.c b/src/common/config_info.c index 55e688e6561..dd34fbfc009 100644 --- a/src/common/config_info.c +++ b/src/common/config_info.c @@ -4,7 +4,7 @@ * Common code for pg_config output * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c index f12a1888562..39c27c92292 100644 --- a/src/common/controldata_utils.c +++ b/src/common/controldata_utils.c @@ -4,7 +4,7 @@ * Common code for control data file output. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -24,12 +24,22 @@ #include #include +#include "access/xlog_internal.h" #include "catalog/pg_control.h" #include "common/controldata_utils.h" +#include "common/file_perm.h" +#ifdef FRONTEND +#include "common/logging.h" +#endif #include "port/pg_crc32c.h" +#ifndef FRONTEND +#include "pgstat.h" +#include "storage/fd.h" +#endif + /* - * get_controlfile(char *DataDir, const char *progname, bool *crc_ok_p) + * get_controlfile() * * Get controlfile values. The result is returned as a palloc'd copy of the * control file data. @@ -38,47 +48,77 @@ * file data is correct. */ ControlFileData * -get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p) +get_controlfile(const char *DataDir, bool *crc_ok_p) { ControlFileData *ControlFile; int fd; char ControlFilePath[MAXPGPATH]; pg_crc32c crc; + int r; AssertArg(crc_ok_p); ControlFile = palloc(sizeof(ControlFileData)); snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); - if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1) #ifndef FRONTEND + if ((fd = OpenTransientFile(ControlFilePath, O_RDONLY | PG_BINARY)) == -1) ereport(ERROR, (errcode_for_file_access(), errmsg("could not open file \"%s\" for reading: %m", ControlFilePath))); #else + if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1) { - fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), - progname, ControlFilePath, strerror(errno)); + pg_log_fatal("could not open file \"%s\" for reading: %m", + ControlFilePath); exit(EXIT_FAILURE); } #endif - if (read(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) + r = read(fd, ControlFile, sizeof(ControlFileData)); + if (r != sizeof(ControlFileData)) + { + if (r < 0) +#ifndef FRONTEND + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\": %m", ControlFilePath))); +#else + { + pg_log_fatal("could not read file \"%s\": %m", ControlFilePath); + exit(EXIT_FAILURE); + } +#endif + else +#ifndef FRONTEND + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("could not read file \"%s\": read %d of %zu", + ControlFilePath, r, sizeof(ControlFileData)))); +#else + { + pg_log_fatal("could not read file \"%s\": read %d of %zu", + ControlFilePath, r, sizeof(ControlFileData)); + exit(EXIT_FAILURE); + } +#endif + } + #ifndef FRONTEND + if (CloseTransientFile(fd) != 0) ereport(ERROR, (errcode_for_file_access(), - errmsg("could not read file \"%s\": %m", ControlFilePath))); + errmsg("could not close file \"%s\": %m", + ControlFilePath))); #else + if (close(fd) != 0) { - fprintf(stderr, _("%s: could not read file \"%s\": %s\n"), - progname, ControlFilePath, strerror(errno)); + pg_log_fatal("could not close file \"%s\": %m", ControlFilePath); exit(EXIT_FAILURE); } #endif - close(fd); - /* Check the CRC. */ INIT_CRC32C(crc); COMP_CRC32C(crc, @@ -94,11 +134,130 @@ get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p) #ifndef FRONTEND elog(ERROR, _("byte ordering mismatch")); #else - printf(_("WARNING: possible byte ordering mismatch\n" - "The byte ordering used to store the pg_control file might not match the one\n" - "used by this program. In that case the results below would be incorrect, and\n" - "the PostgreSQL installation would be incompatible with this data directory.\n")); + pg_log_warning("possible byte ordering mismatch\n" + "The byte ordering used to store the pg_control file might not match the one\n" + "used by this program. In that case the results below would be incorrect, and\n" + "the PostgreSQL installation would be incompatible with this data directory."); #endif return ControlFile; } + +/* + * update_controlfile() + * + * Update controlfile values with the contents given by caller. The + * contents to write are included in "ControlFile". "do_sync" can be + * optionally used to flush the updated control file. Note that it is up + * to the caller to properly lock ControlFileLock when calling this + * routine in the backend. + */ +void +update_controlfile(const char *DataDir, + ControlFileData *ControlFile, bool do_sync) +{ + int fd; + char buffer[PG_CONTROL_FILE_SIZE]; + char ControlFilePath[MAXPGPATH]; + + /* + * Apply the same static assertions as in backend's WriteControlFile(). + */ + StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE, + "pg_control is too large for atomic disk writes"); + StaticAssertStmt(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE, + "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE"); + + /* Recalculate CRC of control file */ + INIT_CRC32C(ControlFile->crc); + COMP_CRC32C(ControlFile->crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile->crc); + + /* + * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding + * the excess over sizeof(ControlFileData), to avoid premature EOF related + * errors when reading it. + */ + memset(buffer, 0, PG_CONTROL_FILE_SIZE); + memcpy(buffer, ControlFile, sizeof(ControlFileData)); + + snprintf(ControlFilePath, sizeof(ControlFilePath), "%s/%s", DataDir, XLOG_CONTROL_FILE); + +#ifndef FRONTEND + + /* + * All errors issue a PANIC, so no need to use OpenTransientFile() and to + * worry about file descriptor leaks. + */ + if ((fd = BasicOpenFile(ControlFilePath, O_RDWR | PG_BINARY)) < 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not open file \"%s\": %m", + ControlFilePath))); +#else + if ((fd = open(ControlFilePath, O_WRONLY | PG_BINARY, + pg_file_create_mode)) == -1) + { + pg_log_fatal("could not open file \"%s\": %m", ControlFilePath); + exit(EXIT_FAILURE); + } +#endif + + errno = 0; +#ifndef FRONTEND + pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE); +#endif + if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE) + { + /* if write didn't set errno, assume problem is no disk space */ + if (errno == 0) + errno = ENOSPC; + +#ifndef FRONTEND + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not write file \"%s\": %m", + ControlFilePath))); +#else + pg_log_fatal("could not write file \"%s\": %m", ControlFilePath); + exit(EXIT_FAILURE); +#endif + } +#ifndef FRONTEND + pgstat_report_wait_end(); +#endif + + if (do_sync) + { +#ifndef FRONTEND + pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE); + if (pg_fsync(fd) != 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\": %m", + ControlFilePath))); + pgstat_report_wait_end(); +#else + if (fsync(fd) != 0) + { + pg_log_fatal("could not fsync file \"%s\": %m", ControlFilePath); + exit(EXIT_FAILURE); + } +#endif + } + + if (close(fd) != 0) + { +#ifndef FRONTEND + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not close file \"%s\": %m", + ControlFilePath))); +#else + pg_log_fatal("could not close file \"%s\": %m", ControlFilePath); + exit(EXIT_FAILURE); +#endif + } +} diff --git a/src/common/d2s.c b/src/common/d2s.c new file mode 100644 index 00000000000..8f4bc2a63c7 --- /dev/null +++ b/src/common/d2s.c @@ -0,0 +1,1076 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output for double precision. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/d2s.c + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ + +/* + * Runtime compiler options: + * + * -DRYU_ONLY_64_BIT_OPS Avoid using uint128 or 64-bit intrinsics. Slower, + * depending on your compiler. + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include "common/shortest_dec.h" + +/* + * For consistency, we use 128-bit types if and only if the rest of PG also + * does, even though we could use them here without worrying about the + * alignment concerns that apply elsewhere. + */ +#if !defined(HAVE_INT128) && defined(_MSC_VER) \ + && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) +#define HAS_64_BIT_INTRINSICS +#endif + +#include "ryu_common.h" +#include "digit_table.h" +#include "d2s_full_table.h" +#include "d2s_intrinsics.h" + +#define DOUBLE_MANTISSA_BITS 52 +#define DOUBLE_EXPONENT_BITS 11 +#define DOUBLE_BIAS 1023 + +#define DOUBLE_POW5_INV_BITCOUNT 122 +#define DOUBLE_POW5_BITCOUNT 121 + + +static inline uint32 +pow5Factor(uint64 value) +{ + uint32 count = 0; + + for (;;) + { + Assert(value != 0); + const uint64 q = div5(value); + const uint32 r = (uint32) (value - 5 * q); + + if (r != 0) + break; + + value = q; + ++count; + } + return count; +} + +/* Returns true if value is divisible by 5^p. */ +static inline bool +multipleOfPowerOf5(const uint64 value, const uint32 p) +{ + /* + * I tried a case distinction on p, but there was no performance + * difference. + */ + return pow5Factor(value) >= p; +} + +/* Returns true if value is divisible by 2^p. */ +static inline bool +multipleOfPowerOf2(const uint64 value, const uint32 p) +{ + /* return __builtin_ctzll(value) >= p; */ + return (value & ((UINT64CONST(1) << p) - 1)) == 0; +} + +/* + * We need a 64x128-bit multiplication and a subsequent 128-bit shift. + * + * Multiplication: + * + * The 64-bit factor is variable and passed in, the 128-bit factor comes + * from a lookup table. We know that the 64-bit factor only has 55 + * significant bits (i.e., the 9 topmost bits are zeros). The 128-bit + * factor only has 124 significant bits (i.e., the 4 topmost bits are + * zeros). + * + * Shift: + * + * In principle, the multiplication result requires 55 + 124 = 179 bits to + * represent. However, we then shift this value to the right by j, which is + * at least j >= 115, so the result is guaranteed to fit into 179 - 115 = + * 64 bits. This means that we only need the topmost 64 significant bits of + * the 64x128-bit multiplication. + * + * There are several ways to do this: + * + * 1. Best case: the compiler exposes a 128-bit type. + * We perform two 64x64-bit multiplications, add the higher 64 bits of the + * lower result to the higher result, and shift by j - 64 bits. + * + * We explicitly cast from 64-bit to 128-bit, so the compiler can tell + * that these are only 64-bit inputs, and can map these to the best + * possible sequence of assembly instructions. x86-64 machines happen to + * have matching assembly instructions for 64x64-bit multiplications and + * 128-bit shifts. + * + * 2. Second best case: the compiler exposes intrinsics for the x86-64 + * assembly instructions mentioned in 1. + * + * 3. We only have 64x64 bit instructions that return the lower 64 bits of + * the result, i.e., we have to use plain C. + * + * Our inputs are less than the full width, so we have three options: + * a. Ignore this fact and just implement the intrinsics manually. + * b. Split both into 31-bit pieces, which guarantees no internal + * overflow, but requires extra work upfront (unless we change the + * lookup table). + * c. Split only the first factor into 31-bit pieces, which also + * guarantees no internal overflow, but requires extra work since the + * intermediate results are not perfectly aligned. + */ +#if defined(HAVE_INT128) + +/* Best case: use 128-bit type. */ +static inline uint64 +mulShift(const uint64 m, const uint64 *const mul, const int32 j) +{ + const uint128 b0 = ((uint128) m) * mul[0]; + const uint128 b2 = ((uint128) m) * mul[1]; + + return (uint64) (((b0 >> 64) + b2) >> (j - 64)); +} + +static inline uint64 +mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j, + uint64 *const vp, uint64 *const vm, const uint32 mmShift) +{ + *vp = mulShift(4 * m + 2, mul, j); + *vm = mulShift(4 * m - 1 - mmShift, mul, j); + return mulShift(4 * m, mul, j); +} + +#elif defined(HAS_64_BIT_INTRINSICS) + +static inline uint64 +mulShift(const uint64 m, const uint64 *const mul, const int32 j) +{ + /* m is maximum 55 bits */ + uint64 high1; + + /* 128 */ + const uint64 low1 = umul128(m, mul[1], &high1); + + /* 64 */ + uint64 high0; + uint64 sum; + + /* 64 */ + umul128(m, mul[0], &high0); + /* 0 */ + sum = high0 + low1; + + if (sum < high0) + { + ++high1; + /* overflow into high1 */ + } + return shiftright128(sum, high1, j - 64); +} + +static inline uint64 +mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j, + uint64 *const vp, uint64 *const vm, const uint32 mmShift) +{ + *vp = mulShift(4 * m + 2, mul, j); + *vm = mulShift(4 * m - 1 - mmShift, mul, j); + return mulShift(4 * m, mul, j); +} + +#else /* // !defined(HAVE_INT128) && + * !defined(HAS_64_BIT_INTRINSICS) */ + +static inline uint64 +mulShiftAll(uint64 m, const uint64 *const mul, const int32 j, + uint64 *const vp, uint64 *const vm, const uint32 mmShift) +{ + m <<= 1; /* m is maximum 55 bits */ + + uint64 tmp; + const uint64 lo = umul128(m, mul[0], &tmp); + uint64 hi; + const uint64 mid = tmp + umul128(m, mul[1], &hi); + + hi += mid < tmp; /* overflow into hi */ + + const uint64 lo2 = lo + mul[0]; + const uint64 mid2 = mid + mul[1] + (lo2 < lo); + const uint64 hi2 = hi + (mid2 < mid); + + *vp = shiftright128(mid2, hi2, j - 64 - 1); + + if (mmShift == 1) + { + const uint64 lo3 = lo - mul[0]; + const uint64 mid3 = mid - mul[1] - (lo3 > lo); + const uint64 hi3 = hi - (mid3 > mid); + + *vm = shiftright128(mid3, hi3, j - 64 - 1); + } + else + { + const uint64 lo3 = lo + lo; + const uint64 mid3 = mid + mid + (lo3 < lo); + const uint64 hi3 = hi + hi + (mid3 < mid); + const uint64 lo4 = lo3 - mul[0]; + const uint64 mid4 = mid3 - mul[1] - (lo4 > lo3); + const uint64 hi4 = hi3 - (mid4 > mid3); + + *vm = shiftright128(mid4, hi4, j - 64); + } + + return shiftright128(mid, hi, j - 64 - 1); +} + +#endif /* // HAS_64_BIT_INTRINSICS */ + +static inline uint32 +decimalLength(const uint64 v) +{ + /* This is slightly faster than a loop. */ + /* The average output length is 16.38 digits, so we check high-to-low. */ + /* Function precondition: v is not an 18, 19, or 20-digit number. */ + /* (17 digits are sufficient for round-tripping.) */ + Assert(v < 100000000000000000L); + if (v >= 10000000000000000L) + { + return 17; + } + if (v >= 1000000000000000L) + { + return 16; + } + if (v >= 100000000000000L) + { + return 15; + } + if (v >= 10000000000000L) + { + return 14; + } + if (v >= 1000000000000L) + { + return 13; + } + if (v >= 100000000000L) + { + return 12; + } + if (v >= 10000000000L) + { + return 11; + } + if (v >= 1000000000L) + { + return 10; + } + if (v >= 100000000L) + { + return 9; + } + if (v >= 10000000L) + { + return 8; + } + if (v >= 1000000L) + { + return 7; + } + if (v >= 100000L) + { + return 6; + } + if (v >= 10000L) + { + return 5; + } + if (v >= 1000L) + { + return 4; + } + if (v >= 100L) + { + return 3; + } + if (v >= 10L) + { + return 2; + } + return 1; +} + +/* A floating decimal representing m * 10^e. */ +typedef struct floating_decimal_64 +{ + uint64 mantissa; + int32 exponent; +} floating_decimal_64; + +static inline floating_decimal_64 +d2d(const uint64 ieeeMantissa, const uint32 ieeeExponent) +{ + int32 e2; + uint64 m2; + + if (ieeeExponent == 0) + { + /* We subtract 2 so that the bounds computation has 2 additional bits. */ + e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; + m2 = ieeeMantissa; + } + else + { + e2 = ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; + m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa; + } + +#if STRICTLY_SHORTEST + const bool even = (m2 & 1) == 0; + const bool acceptBounds = even; +#else + const bool acceptBounds = false; +#endif + + /* Step 2: Determine the interval of legal decimal representations. */ + const uint64 mv = 4 * m2; + + /* Implicit bool -> int conversion. True is 1, false is 0. */ + const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; + + /* We would compute mp and mm like this: */ + /* uint64 mp = 4 * m2 + 2; */ + /* uint64 mm = mv - 1 - mmShift; */ + + /* Step 3: Convert to a decimal power base using 128-bit arithmetic. */ + uint64 vr, + vp, + vm; + int32 e10; + bool vmIsTrailingZeros = false; + bool vrIsTrailingZeros = false; + + if (e2 >= 0) + { + /* + * I tried special-casing q == 0, but there was no effect on + * performance. + * + * This expr is slightly faster than max(0, log10Pow2(e2) - 1). + */ + const uint32 q = log10Pow2(e2) - (e2 > 3); + const int32 k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q) - 1; + const int32 i = -e2 + q + k; + + e10 = q; + + vr = mulShiftAll(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift); + + if (q <= 21) + { + /* + * This should use q <= 22, but I think 21 is also safe. Smaller + * values may still be safe, but it's more difficult to reason + * about them. + * + * Only one of mp, mv, and mm can be a multiple of 5, if any. + */ + const uint32 mvMod5 = (uint32) (mv - 5 * div5(mv)); + + if (mvMod5 == 0) + { + vrIsTrailingZeros = multipleOfPowerOf5(mv, q); + } + else if (acceptBounds) + { + /*---- + * Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q + * <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q + * <=> true && pow5Factor(mm) >= q, since e2 >= q. + *---- + */ + vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q); + } + else + { + /* Same as min(e2 + 1, pow5Factor(mp)) >= q. */ + vp -= multipleOfPowerOf5(mv + 2, q); + } + } + } + else + { + /* + * This expression is slightly faster than max(0, log10Pow5(-e2) - 1). + */ + const uint32 q = log10Pow5(-e2) - (-e2 > 1); + const int32 i = -e2 - q; + const int32 k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; + const int32 j = q - k; + + e10 = q + e2; + + vr = mulShiftAll(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift); + + if (q <= 1) + { + /* + * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q + * trailing 0 bits. + */ + /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ + vrIsTrailingZeros = true; + if (acceptBounds) + { + /* + * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff + * mmShift == 1. + */ + vmIsTrailingZeros = mmShift == 1; + } + else + { + /* + * mp = mv + 2, so it always has at least one trailing 0 bit. + */ + --vp; + } + } + else if (q < 63) + { + /* TODO(ulfjack):Use a tighter bound here. */ + /* + * We need to compute min(ntz(mv), pow5Factor(mv) - e2) >= q - 1 + */ + /* <=> ntz(mv) >= q - 1 && pow5Factor(mv) - e2 >= q - 1 */ + /* <=> ntz(mv) >= q - 1 (e2 is negative and -e2 >= q) */ + /* <=> (mv & ((1 << (q - 1)) - 1)) == 0 */ + + /* + * We also need to make sure that the left shift does not + * overflow. + */ + vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); + } + } + + /* + * Step 4: Find the shortest decimal representation in the interval of + * legal representations. + */ + uint32 removed = 0; + uint8 lastRemovedDigit = 0; + uint64 output; + + /* On average, we remove ~2 digits. */ + if (vmIsTrailingZeros || vrIsTrailingZeros) + { + /* General case, which happens rarely (~0.7%). */ + for (;;) + { + const uint64 vpDiv10 = div10(vp); + const uint64 vmDiv10 = div10(vm); + + if (vpDiv10 <= vmDiv10) + break; + + const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10); + const uint64 vrDiv10 = div10(vr); + const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); + + vmIsTrailingZeros &= vmMod10 == 0; + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) vrMod10; + vr = vrDiv10; + vp = vpDiv10; + vm = vmDiv10; + ++removed; + } + + if (vmIsTrailingZeros) + { + for (;;) + { + const uint64 vmDiv10 = div10(vm); + const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10); + + if (vmMod10 != 0) + break; + + const uint64 vpDiv10 = div10(vp); + const uint64 vrDiv10 = div10(vr); + const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); + + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) vrMod10; + vr = vrDiv10; + vp = vpDiv10; + vm = vmDiv10; + ++removed; + } + } + + if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) + { + /* Round even if the exact number is .....50..0. */ + lastRemovedDigit = 4; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); + } + else + { + /* + * Specialized for the common case (~99.3%). Percentages below are + * relative to this. + */ + bool roundUp = false; + const uint64 vpDiv100 = div100(vp); + const uint64 vmDiv100 = div100(vm); + + if (vpDiv100 > vmDiv100) + { + /* Optimization:remove two digits at a time(~86.2 %). */ + const uint64 vrDiv100 = div100(vr); + const uint32 vrMod100 = (uint32) (vr - 100 * vrDiv100); + + roundUp = vrMod100 >= 50; + vr = vrDiv100; + vp = vpDiv100; + vm = vmDiv100; + removed += 2; + } + + /*---- + * Loop iterations below (approximately), without optimization + * above: + * + * 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, + * 6+: 0.02% + * + * Loop iterations below (approximately), with optimization + * above: + * + * 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% + *---- + */ + for (;;) + { + const uint64 vpDiv10 = div10(vp); + const uint64 vmDiv10 = div10(vm); + + if (vpDiv10 <= vmDiv10) + break; + + const uint64 vrDiv10 = div10(vr); + const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); + + roundUp = vrMod10 >= 5; + vr = vrDiv10; + vp = vpDiv10; + vm = vmDiv10; + ++removed; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + (vr == vm || roundUp); + } + + const int32 exp = e10 + removed; + + floating_decimal_64 fd; + + fd.exponent = exp; + fd.mantissa = output; + return fd; +} + +static inline int +to_chars_df(const floating_decimal_64 v, const uint32 olength, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint64 output = v.mantissa; + int32 exp = v.exponent; + + /*---- + * On entry, mantissa * 10^exp is the result to be output. + * Caller has already done the - sign if needed. + * + * We want to insert the point somewhere depending on the output length + * and exponent, which might mean adding zeros: + * + * exp | format + * 1+ | ddddddddd000000 + * 0 | ddddddddd + * -1 .. -len+1 | dddddddd.d to d.ddddddddd + * -len ... | 0.ddddddddd to 0.000dddddd + */ + uint32 i = 0; + int32 nexp = exp + olength; + + if (nexp <= 0) + { + /* -nexp is number of 0s to add after '.' */ + Assert(nexp >= -3); + /* 0.000ddddd */ + index = 2 - nexp; + /* won't need more than this many 0s */ + memcpy(result, "0.000000", 8); + } + else if (exp < 0) + { + /* + * dddd.dddd; leave space at the start and move the '.' in after + */ + index = 1; + } + else + { + /* + * We can save some code later by pre-filling with zeros. We know that + * there can be no more than 16 output digits in this form, otherwise + * we would not choose fixed-point output. + */ + Assert(exp < 16 && exp + olength <= 16); + memset(result, '0', 16); + } + + /* + * We prefer 32-bit operations, even on 64-bit platforms. We have at most + * 17 digits, and uint32 can store 9 digits. If output doesn't fit into + * uint32, we cut off 8 digits, so the rest will fit into uint32. + */ + if ((output >> 32) != 0) + { + /* Expensive 64-bit division. */ + const uint64 q = div1e8(output); + uint32 output2 = (uint32) (output - 100000000 * q); + const uint32 c = output2 % 10000; + + output = q; + output2 /= 10000; + + const uint32 d = output2 % 10000; + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + const uint32 d0 = (d % 100) << 1; + const uint32 d1 = (d / 100) << 1; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + memcpy(result + index + olength - i - 6, DIGIT_TABLE + d0, 2); + memcpy(result + index + olength - i - 8, DIGIT_TABLE + d1, 2); + i += 8; + } + + uint32 output2 = (uint32) output; + + while (output2 >= 10000) + { + const uint32 c = output2 - 10000 * (output2 / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output2 /= 10000; + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output2 >= 100) + { + const uint32 c = (output2 % 100) << 1; + + output2 /= 100; + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + i += 2; + } + if (output2 >= 10) + { + const uint32 c = output2 << 1; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + } + else + { + result[index] = (char) ('0' + output2); + } + + if (index == 1) + { + /* + * nexp is 1..15 here, representing the number of digits before the + * point. A value of 16 is not possible because we switch to + * scientific notation when the display exponent reaches 15. + */ + Assert(nexp < 16); + /* gcc only seems to want to optimize memmove for small 2^n */ + if (nexp & 8) + { + memmove(result + index - 1, result + index, 8); + index += 8; + } + if (nexp & 4) + { + memmove(result + index - 1, result + index, 4); + index += 4; + } + if (nexp & 2) + { + memmove(result + index - 1, result + index, 2); + index += 2; + } + if (nexp & 1) + { + result[index - 1] = result[index]; + } + result[nexp] = '.'; + index = olength + 1; + } + else if (exp >= 0) + { + /* we supplied the trailing zeros earlier, now just set the length. */ + index = olength + exp; + } + else + { + index = olength + (2 - nexp); + } + + return index; +} + +static inline int +to_chars(floating_decimal_64 v, const bool sign, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint64 output = v.mantissa; + uint32 olength = decimalLength(output); + int32 exp = v.exponent + olength - 1; + + if (sign) + { + result[index++] = '-'; + } + + /* + * The thresholds for fixed-point output are chosen to match printf + * defaults. Beware that both the code of to_chars_df and the value of + * DOUBLE_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. + */ + if (exp >= -4 && exp < 15) + return to_chars_df(v, olength, result + index) + sign; + + /* + * If v.exponent is exactly 0, we might have reached here via the small + * integer fast path, in which case v.mantissa might contain trailing + * (decimal) zeros. For scientific notation we need to move these zeros + * into the exponent. (For fixed point this doesn't matter, which is why + * we do this here rather than above.) + * + * Since we already calculated the display exponent (exp) above based on + * the old decimal length, that value does not change here. Instead, we + * just reduce the display length for each digit removed. + * + * If we didn't get here via the fast path, the raw exponent will not + * usually be 0, and there will be no trailing zeros, so we pay no more + * than one div10/multiply extra cost. We claw back half of that by + * checking for divisibility by 2 before dividing by 10. + */ + if (v.exponent == 0) + { + while ((output & 1) == 0) + { + const uint64 q = div10(output); + const uint32 r = (uint32) (output - 10 * q); + + if (r != 0) + break; + output = q; + --olength; + } + } + + /*---- + * Print the decimal digits. + * + * The following code is equivalent to: + * + * for (uint32 i = 0; i < olength - 1; ++i) { + * const uint32 c = output % 10; output /= 10; + * result[index + olength - i] = (char) ('0' + c); + * } + * result[index] = '0' + output % 10; + *---- + */ + + uint32 i = 0; + + /* + * We prefer 32-bit operations, even on 64-bit platforms. We have at most + * 17 digits, and uint32 can store 9 digits. If output doesn't fit into + * uint32, we cut off 8 digits, so the rest will fit into uint32. + */ + if ((output >> 32) != 0) + { + /* Expensive 64-bit division. */ + const uint64 q = div1e8(output); + uint32 output2 = (uint32) (output - 100000000 * q); + + output = q; + + const uint32 c = output2 % 10000; + + output2 /= 10000; + + const uint32 d = output2 % 10000; + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + const uint32 d0 = (d % 100) << 1; + const uint32 d1 = (d / 100) << 1; + + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + memcpy(result + index + olength - i - 5, DIGIT_TABLE + d0, 2); + memcpy(result + index + olength - i - 7, DIGIT_TABLE + d1, 2); + i += 8; + } + + uint32 output2 = (uint32) output; + + while (output2 >= 10000) + { + const uint32 c = output2 - 10000 * (output2 / 10000); + + output2 /= 10000; + + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output2 >= 100) + { + const uint32 c = (output2 % 100) << 1; + + output2 /= 100; + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); + i += 2; + } + if (output2 >= 10) + { + const uint32 c = output2 << 1; + + /* + * We can't use memcpy here: the decimal dot goes between these two + * digits. + */ + result[index + olength - i] = DIGIT_TABLE[c + 1]; + result[index] = DIGIT_TABLE[c]; + } + else + { + result[index] = (char) ('0' + output2); + } + + /* Print decimal point if needed. */ + if (olength > 1) + { + result[index + 1] = '.'; + index += olength + 1; + } + else + { + ++index; + } + + /* Print the exponent. */ + result[index++] = 'e'; + if (exp < 0) + { + result[index++] = '-'; + exp = -exp; + } + else + result[index++] = '+'; + + if (exp >= 100) + { + const int32 c = exp % 10; + + memcpy(result + index, DIGIT_TABLE + 2 * (exp / 10), 2); + result[index + 2] = (char) ('0' + c); + index += 3; + } + else + { + memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); + index += 2; + } + + return index; +} + +static inline bool +d2d_small_int(const uint64 ieeeMantissa, + const uint32 ieeeExponent, + floating_decimal_64 *v) +{ + const int32 e2 = (int32) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS; + + /* + * Avoid using multiple "return false;" here since it tends to provoke the + * compiler into inlining multiple copies of d2d, which is undesirable. + */ + + if (e2 >= -DOUBLE_MANTISSA_BITS && e2 <= 0) + { + /*---- + * Since 2^52 <= m2 < 2^53 and 0 <= -e2 <= 52: + * 1 <= f = m2 / 2^-e2 < 2^53. + * + * Test if the lower -e2 bits of the significand are 0, i.e. whether + * the fraction is 0. We can use ieeeMantissa here, since the implied + * 1 bit can never be tested by this; the implied 1 can only be part + * of a fraction if e2 < -DOUBLE_MANTISSA_BITS which we already + * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -53) + */ + const uint64 mask = (UINT64CONST(1) << -e2) - 1; + const uint64 fraction = ieeeMantissa & mask; + + if (fraction == 0) + { + /*---- + * f is an integer in the range [1, 2^53). + * Note: mantissa might contain trailing (decimal) 0's. + * Note: since 2^53 < 10^16, there is no need to adjust + * decimalLength(). + */ + const uint64 m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa; + + v->mantissa = m2 >> -e2; + v->exponent = 0; + return true; + } + } + + return false; +} + +/* + * Store the shortest decimal representation of the given double as an + * UNTERMINATED string in the caller's supplied buffer (which must be at least + * DOUBLE_SHORTEST_DECIMAL_LEN-1 bytes long). + * + * Returns the number of bytes stored. + */ +int +double_to_shortest_decimal_bufn(double f, char *result) +{ + /* + * Step 1: Decode the floating-point number, and unify normalized and + * subnormal cases. + */ + const uint64 bits = double_to_bits(f); + + /* Decode bits into sign, mantissa, and exponent. */ + const bool ieeeSign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; + const uint64 ieeeMantissa = bits & ((UINT64CONST(1) << DOUBLE_MANTISSA_BITS) - 1); + const uint32 ieeeExponent = (uint32) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1)); + + /* Case distinction; exit early for the easy cases. */ + if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) + { + return copy_special_str(result, ieeeSign, (ieeeExponent != 0), (ieeeMantissa != 0)); + } + + floating_decimal_64 v; + const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v); + + if (!isSmallInt) + { + v = d2d(ieeeMantissa, ieeeExponent); + } + + return to_chars(v, ieeeSign, result); +} + +/* + * Store the shortest decimal representation of the given double as a + * null-terminated string in the caller's supplied buffer (which must be at + * least DOUBLE_SHORTEST_DECIMAL_LEN bytes long). + * + * Returns the string length. + */ +int +double_to_shortest_decimal_buf(double f, char *result) +{ + const int index = double_to_shortest_decimal_bufn(f, result); + + /* Terminate the string. */ + Assert(index < DOUBLE_SHORTEST_DECIMAL_LEN); + result[index] = '\0'; + return index; +} + +/* + * Return the shortest decimal representation as a null-terminated palloc'd + * string (outside the backend, uses malloc() instead). + * + * Caller is responsible for freeing the result. + */ +char * +double_to_shortest_decimal(double f) +{ + char *const result = (char *) palloc(DOUBLE_SHORTEST_DECIMAL_LEN); + + double_to_shortest_decimal_buf(f, result); + return result; +} diff --git a/src/common/d2s_full_table.h b/src/common/d2s_full_table.h new file mode 100644 index 00000000000..d6520b437b7 --- /dev/null +++ b/src/common/d2s_full_table.h @@ -0,0 +1,358 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output for double precision. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/d2s_full_table.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ + +#ifndef RYU_D2S_FULL_TABLE_H +#define RYU_D2S_FULL_TABLE_H + +/* + * These tables are generated (by the upstream) using PrintDoubleLookupTable + * from the upstream sources at github.com/ulfjack/ryu, and then modified (by + * us) by adding UINT64CONST. + */ +static const uint64 DOUBLE_POW5_INV_SPLIT[292][2] = { + {UINT64CONST(1), UINT64CONST(288230376151711744)}, {UINT64CONST(3689348814741910324), UINT64CONST(230584300921369395)}, + {UINT64CONST(2951479051793528259), UINT64CONST(184467440737095516)}, {UINT64CONST(17118578500402463900), UINT64CONST(147573952589676412)}, + {UINT64CONST(12632330341676300947), UINT64CONST(236118324143482260)}, {UINT64CONST(10105864273341040758), UINT64CONST(188894659314785808)}, + {UINT64CONST(15463389048156653253), UINT64CONST(151115727451828646)}, {UINT64CONST(17362724847566824558), UINT64CONST(241785163922925834)}, + {UINT64CONST(17579528692795369969), UINT64CONST(193428131138340667)}, {UINT64CONST(6684925324752475329), UINT64CONST(154742504910672534)}, + {UINT64CONST(18074578149087781173), UINT64CONST(247588007857076054)}, {UINT64CONST(18149011334012135262), UINT64CONST(198070406285660843)}, + {UINT64CONST(3451162622983977240), UINT64CONST(158456325028528675)}, {UINT64CONST(5521860196774363583), UINT64CONST(253530120045645880)}, + {UINT64CONST(4417488157419490867), UINT64CONST(202824096036516704)}, {UINT64CONST(7223339340677503017), UINT64CONST(162259276829213363)}, + {UINT64CONST(7867994130342094503), UINT64CONST(259614842926741381)}, {UINT64CONST(2605046489531765280), UINT64CONST(207691874341393105)}, + {UINT64CONST(2084037191625412224), UINT64CONST(166153499473114484)}, {UINT64CONST(10713157136084480204), UINT64CONST(265845599156983174)}, + {UINT64CONST(12259874523609494487), UINT64CONST(212676479325586539)}, {UINT64CONST(13497248433629505913), UINT64CONST(170141183460469231)}, + {UINT64CONST(14216899864323388813), UINT64CONST(272225893536750770)}, {UINT64CONST(11373519891458711051), UINT64CONST(217780714829400616)}, + {UINT64CONST(5409467098425058518), UINT64CONST(174224571863520493)}, {UINT64CONST(4965798542738183305), UINT64CONST(278759314981632789)}, + {UINT64CONST(7661987648932456967), UINT64CONST(223007451985306231)}, {UINT64CONST(2440241304404055250), UINT64CONST(178405961588244985)}, + {UINT64CONST(3904386087046488400), UINT64CONST(285449538541191976)}, {UINT64CONST(17880904128604832013), UINT64CONST(228359630832953580)}, + {UINT64CONST(14304723302883865611), UINT64CONST(182687704666362864)}, {UINT64CONST(15133127457049002812), UINT64CONST(146150163733090291)}, + {UINT64CONST(16834306301794583852), UINT64CONST(233840261972944466)}, {UINT64CONST(9778096226693756759), UINT64CONST(187072209578355573)}, + {UINT64CONST(15201174610838826053), UINT64CONST(149657767662684458)}, {UINT64CONST(2185786488890659746), UINT64CONST(239452428260295134)}, + {UINT64CONST(5437978005854438120), UINT64CONST(191561942608236107)}, {UINT64CONST(15418428848909281466), UINT64CONST(153249554086588885)}, + {UINT64CONST(6222742084545298729), UINT64CONST(245199286538542217)}, {UINT64CONST(16046240111861969953), UINT64CONST(196159429230833773)}, + {UINT64CONST(1768945645263844993), UINT64CONST(156927543384667019)}, {UINT64CONST(10209010661905972635), UINT64CONST(251084069415467230)}, + {UINT64CONST(8167208529524778108), UINT64CONST(200867255532373784)}, {UINT64CONST(10223115638361732810), UINT64CONST(160693804425899027)}, + {UINT64CONST(1599589762411131202), UINT64CONST(257110087081438444)}, {UINT64CONST(4969020624670815285), UINT64CONST(205688069665150755)}, + {UINT64CONST(3975216499736652228), UINT64CONST(164550455732120604)}, {UINT64CONST(13739044029062464211), UINT64CONST(263280729171392966)}, + {UINT64CONST(7301886408508061046), UINT64CONST(210624583337114373)}, {UINT64CONST(13220206756290269483), UINT64CONST(168499666669691498)}, + {UINT64CONST(17462981995322520850), UINT64CONST(269599466671506397)}, {UINT64CONST(6591687966774196033), UINT64CONST(215679573337205118)}, + {UINT64CONST(12652048002903177473), UINT64CONST(172543658669764094)}, {UINT64CONST(9175230360419352987), UINT64CONST(276069853871622551)}, + {UINT64CONST(3650835473593572067), UINT64CONST(220855883097298041)}, {UINT64CONST(17678063637842498946), UINT64CONST(176684706477838432)}, + {UINT64CONST(13527506561580357021), UINT64CONST(282695530364541492)}, {UINT64CONST(3443307619780464970), UINT64CONST(226156424291633194)}, + {UINT64CONST(6443994910566282300), UINT64CONST(180925139433306555)}, {UINT64CONST(5155195928453025840), UINT64CONST(144740111546645244)}, + {UINT64CONST(15627011115008661990), UINT64CONST(231584178474632390)}, {UINT64CONST(12501608892006929592), UINT64CONST(185267342779705912)}, + {UINT64CONST(2622589484121723027), UINT64CONST(148213874223764730)}, {UINT64CONST(4196143174594756843), UINT64CONST(237142198758023568)}, + {UINT64CONST(10735612169159626121), UINT64CONST(189713759006418854)}, {UINT64CONST(12277838550069611220), UINT64CONST(151771007205135083)}, + {UINT64CONST(15955192865369467629), UINT64CONST(242833611528216133)}, {UINT64CONST(1696107848069843133), UINT64CONST(194266889222572907)}, + {UINT64CONST(12424932722681605476), UINT64CONST(155413511378058325)}, {UINT64CONST(1433148282581017146), UINT64CONST(248661618204893321)}, + {UINT64CONST(15903913885032455010), UINT64CONST(198929294563914656)}, {UINT64CONST(9033782293284053685), UINT64CONST(159143435651131725)}, + {UINT64CONST(14454051669254485895), UINT64CONST(254629497041810760)}, {UINT64CONST(11563241335403588716), UINT64CONST(203703597633448608)}, + {UINT64CONST(16629290697806691620), UINT64CONST(162962878106758886)}, {UINT64CONST(781423413297334329), UINT64CONST(260740604970814219)}, + {UINT64CONST(4314487545379777786), UINT64CONST(208592483976651375)}, {UINT64CONST(3451590036303822229), UINT64CONST(166873987181321100)}, + {UINT64CONST(5522544058086115566), UINT64CONST(266998379490113760)}, {UINT64CONST(4418035246468892453), UINT64CONST(213598703592091008)}, + {UINT64CONST(10913125826658934609), UINT64CONST(170878962873672806)}, {UINT64CONST(10082303693170474728), UINT64CONST(273406340597876490)}, + {UINT64CONST(8065842954536379782), UINT64CONST(218725072478301192)}, {UINT64CONST(17520720807854834795), UINT64CONST(174980057982640953)}, + {UINT64CONST(5897060404116273733), UINT64CONST(279968092772225526)}, {UINT64CONST(1028299508551108663), UINT64CONST(223974474217780421)}, + {UINT64CONST(15580034865808528224), UINT64CONST(179179579374224336)}, {UINT64CONST(17549358155809824511), UINT64CONST(286687326998758938)}, + {UINT64CONST(2971440080422128639), UINT64CONST(229349861599007151)}, {UINT64CONST(17134547323305344204), UINT64CONST(183479889279205720)}, + {UINT64CONST(13707637858644275364), UINT64CONST(146783911423364576)}, {UINT64CONST(14553522944347019935), UINT64CONST(234854258277383322)}, + {UINT64CONST(4264120725993795302), UINT64CONST(187883406621906658)}, {UINT64CONST(10789994210278856888), UINT64CONST(150306725297525326)}, + {UINT64CONST(9885293106962350374), UINT64CONST(240490760476040522)}, {UINT64CONST(529536856086059653), UINT64CONST(192392608380832418)}, + {UINT64CONST(7802327114352668369), UINT64CONST(153914086704665934)}, {UINT64CONST(1415676938738538420), UINT64CONST(246262538727465495)}, + {UINT64CONST(1132541550990830736), UINT64CONST(197010030981972396)}, {UINT64CONST(15663428499760305882), UINT64CONST(157608024785577916)}, + {UINT64CONST(17682787970132668764), UINT64CONST(252172839656924666)}, {UINT64CONST(10456881561364224688), UINT64CONST(201738271725539733)}, + {UINT64CONST(15744202878575200397), UINT64CONST(161390617380431786)}, {UINT64CONST(17812026976236499989), UINT64CONST(258224987808690858)}, + {UINT64CONST(3181575136763469022), UINT64CONST(206579990246952687)}, {UINT64CONST(13613306553636506187), UINT64CONST(165263992197562149)}, + {UINT64CONST(10713244041592678929), UINT64CONST(264422387516099439)}, {UINT64CONST(12259944048016053467), UINT64CONST(211537910012879551)}, + {UINT64CONST(6118606423670932450), UINT64CONST(169230328010303641)}, {UINT64CONST(2411072648389671274), UINT64CONST(270768524816485826)}, + {UINT64CONST(16686253377679378312), UINT64CONST(216614819853188660)}, {UINT64CONST(13349002702143502650), UINT64CONST(173291855882550928)}, + {UINT64CONST(17669055508687693916), UINT64CONST(277266969412081485)}, {UINT64CONST(14135244406950155133), UINT64CONST(221813575529665188)}, + {UINT64CONST(240149081334393137), UINT64CONST(177450860423732151)}, {UINT64CONST(11452284974360759988), UINT64CONST(283921376677971441)}, + {UINT64CONST(5472479164746697667), UINT64CONST(227137101342377153)}, {UINT64CONST(11756680961281178780), UINT64CONST(181709681073901722)}, + {UINT64CONST(2026647139541122378), UINT64CONST(145367744859121378)}, {UINT64CONST(18000030682233437097), UINT64CONST(232588391774594204)}, + {UINT64CONST(18089373360528660001), UINT64CONST(186070713419675363)}, {UINT64CONST(3403452244197197031), UINT64CONST(148856570735740291)}, + {UINT64CONST(16513570034941246220), UINT64CONST(238170513177184465)}, {UINT64CONST(13210856027952996976), UINT64CONST(190536410541747572)}, + {UINT64CONST(3189987192878576934), UINT64CONST(152429128433398058)}, {UINT64CONST(1414630693863812771), UINT64CONST(243886605493436893)}, + {UINT64CONST(8510402184574870864), UINT64CONST(195109284394749514)}, {UINT64CONST(10497670562401807014), UINT64CONST(156087427515799611)}, + {UINT64CONST(9417575270359070576), UINT64CONST(249739884025279378)}, {UINT64CONST(14912757845771077107), UINT64CONST(199791907220223502)}, + {UINT64CONST(4551508647133041040), UINT64CONST(159833525776178802)}, {UINT64CONST(10971762650154775986), UINT64CONST(255733641241886083)}, + {UINT64CONST(16156107749607641435), UINT64CONST(204586912993508866)}, {UINT64CONST(9235537384944202825), UINT64CONST(163669530394807093)}, + {UINT64CONST(11087511001168814197), UINT64CONST(261871248631691349)}, {UINT64CONST(12559357615676961681), UINT64CONST(209496998905353079)}, + {UINT64CONST(13736834907283479668), UINT64CONST(167597599124282463)}, {UINT64CONST(18289587036911657145), UINT64CONST(268156158598851941)}, + {UINT64CONST(10942320814787415393), UINT64CONST(214524926879081553)}, {UINT64CONST(16132554281313752961), UINT64CONST(171619941503265242)}, + {UINT64CONST(11054691591134363444), UINT64CONST(274591906405224388)}, {UINT64CONST(16222450902391311402), UINT64CONST(219673525124179510)}, + {UINT64CONST(12977960721913049122), UINT64CONST(175738820099343608)}, {UINT64CONST(17075388340318968271), UINT64CONST(281182112158949773)}, + {UINT64CONST(2592264228029443648), UINT64CONST(224945689727159819)}, {UINT64CONST(5763160197165465241), UINT64CONST(179956551781727855)}, + {UINT64CONST(9221056315464744386), UINT64CONST(287930482850764568)}, {UINT64CONST(14755542681855616155), UINT64CONST(230344386280611654)}, + {UINT64CONST(15493782960226403247), UINT64CONST(184275509024489323)}, {UINT64CONST(1326979923955391628), UINT64CONST(147420407219591459)}, + {UINT64CONST(9501865507812447252), UINT64CONST(235872651551346334)}, {UINT64CONST(11290841220991868125), UINT64CONST(188698121241077067)}, + {UINT64CONST(1653975347309673853), UINT64CONST(150958496992861654)}, {UINT64CONST(10025058185179298811), UINT64CONST(241533595188578646)}, + {UINT64CONST(4330697733401528726), UINT64CONST(193226876150862917)}, {UINT64CONST(14532604630946953951), UINT64CONST(154581500920690333)}, + {UINT64CONST(1116074521063664381), UINT64CONST(247330401473104534)}, {UINT64CONST(4582208431592841828), UINT64CONST(197864321178483627)}, + {UINT64CONST(14733813189500004432), UINT64CONST(158291456942786901)}, {UINT64CONST(16195403473716186445), UINT64CONST(253266331108459042)}, + {UINT64CONST(5577625149489128510), UINT64CONST(202613064886767234)}, {UINT64CONST(8151448934333213131), UINT64CONST(162090451909413787)}, + {UINT64CONST(16731667109675051333), UINT64CONST(259344723055062059)}, {UINT64CONST(17074682502481951390), UINT64CONST(207475778444049647)}, + {UINT64CONST(6281048372501740465), UINT64CONST(165980622755239718)}, {UINT64CONST(6360328581260874421), UINT64CONST(265568996408383549)}, + {UINT64CONST(8777611679750609860), UINT64CONST(212455197126706839)}, {UINT64CONST(10711438158542398211), UINT64CONST(169964157701365471)}, + {UINT64CONST(9759603424184016492), UINT64CONST(271942652322184754)}, {UINT64CONST(11497031554089123517), UINT64CONST(217554121857747803)}, + {UINT64CONST(16576322872755119460), UINT64CONST(174043297486198242)}, {UINT64CONST(11764721337440549842), UINT64CONST(278469275977917188)}, + {UINT64CONST(16790474699436260520), UINT64CONST(222775420782333750)}, {UINT64CONST(13432379759549008416), UINT64CONST(178220336625867000)}, + {UINT64CONST(3045063541568861850), UINT64CONST(285152538601387201)}, {UINT64CONST(17193446092222730773), UINT64CONST(228122030881109760)}, + {UINT64CONST(13754756873778184618), UINT64CONST(182497624704887808)}, {UINT64CONST(18382503128506368341), UINT64CONST(145998099763910246)}, + {UINT64CONST(3586563302416817083), UINT64CONST(233596959622256395)}, {UINT64CONST(2869250641933453667), UINT64CONST(186877567697805116)}, + {UINT64CONST(17052795772514404226), UINT64CONST(149502054158244092)}, {UINT64CONST(12527077977055405469), UINT64CONST(239203286653190548)}, + {UINT64CONST(17400360011128145022), UINT64CONST(191362629322552438)}, {UINT64CONST(2852241564676785048), UINT64CONST(153090103458041951)}, + {UINT64CONST(15631632947708587046), UINT64CONST(244944165532867121)}, {UINT64CONST(8815957543424959314), UINT64CONST(195955332426293697)}, + {UINT64CONST(18120812478965698421), UINT64CONST(156764265941034957)}, {UINT64CONST(14235904707377476180), UINT64CONST(250822825505655932)}, + {UINT64CONST(4010026136418160298), UINT64CONST(200658260404524746)}, {UINT64CONST(17965416168102169531), UINT64CONST(160526608323619796)}, + {UINT64CONST(2919224165770098987), UINT64CONST(256842573317791675)}, {UINT64CONST(2335379332616079190), UINT64CONST(205474058654233340)}, + {UINT64CONST(1868303466092863352), UINT64CONST(164379246923386672)}, {UINT64CONST(6678634360490491686), UINT64CONST(263006795077418675)}, + {UINT64CONST(5342907488392393349), UINT64CONST(210405436061934940)}, {UINT64CONST(4274325990713914679), UINT64CONST(168324348849547952)}, + {UINT64CONST(10528270399884173809), UINT64CONST(269318958159276723)}, {UINT64CONST(15801313949391159694), UINT64CONST(215455166527421378)}, + {UINT64CONST(1573004715287196786), UINT64CONST(172364133221937103)}, {UINT64CONST(17274202803427156150), UINT64CONST(275782613155099364)}, + {UINT64CONST(17508711057483635243), UINT64CONST(220626090524079491)}, {UINT64CONST(10317620031244997871), UINT64CONST(176500872419263593)}, + {UINT64CONST(12818843235250086271), UINT64CONST(282401395870821749)}, {UINT64CONST(13944423402941979340), UINT64CONST(225921116696657399)}, + {UINT64CONST(14844887537095493795), UINT64CONST(180736893357325919)}, {UINT64CONST(15565258844418305359), UINT64CONST(144589514685860735)}, + {UINT64CONST(6457670077359736959), UINT64CONST(231343223497377177)}, {UINT64CONST(16234182506113520537), UINT64CONST(185074578797901741)}, + {UINT64CONST(9297997190148906106), UINT64CONST(148059663038321393)}, {UINT64CONST(11187446689496339446), UINT64CONST(236895460861314229)}, + {UINT64CONST(12639306166338981880), UINT64CONST(189516368689051383)}, {UINT64CONST(17490142562555006151), UINT64CONST(151613094951241106)}, + {UINT64CONST(2158786396894637579), UINT64CONST(242580951921985771)}, {UINT64CONST(16484424376483351356), UINT64CONST(194064761537588616)}, + {UINT64CONST(9498190686444770762), UINT64CONST(155251809230070893)}, {UINT64CONST(11507756283569722895), UINT64CONST(248402894768113429)}, + {UINT64CONST(12895553841597688639), UINT64CONST(198722315814490743)}, {UINT64CONST(17695140702761971558), UINT64CONST(158977852651592594)}, + {UINT64CONST(17244178680193423523), UINT64CONST(254364564242548151)}, {UINT64CONST(10105994129412828495), UINT64CONST(203491651394038521)}, + {UINT64CONST(4395446488788352473), UINT64CONST(162793321115230817)}, {UINT64CONST(10722063196803274280), UINT64CONST(260469313784369307)}, + {UINT64CONST(1198952927958798777), UINT64CONST(208375451027495446)}, {UINT64CONST(15716557601334680315), UINT64CONST(166700360821996356)}, + {UINT64CONST(17767794532651667857), UINT64CONST(266720577315194170)}, {UINT64CONST(14214235626121334286), UINT64CONST(213376461852155336)}, + {UINT64CONST(7682039686155157106), UINT64CONST(170701169481724269)}, {UINT64CONST(1223217053622520399), UINT64CONST(273121871170758831)}, + {UINT64CONST(15735968901865657612), UINT64CONST(218497496936607064)}, {UINT64CONST(16278123936234436413), UINT64CONST(174797997549285651)}, + {UINT64CONST(219556594781725998), UINT64CONST(279676796078857043)}, {UINT64CONST(7554342905309201445), UINT64CONST(223741436863085634)}, + {UINT64CONST(9732823138989271479), UINT64CONST(178993149490468507)}, {UINT64CONST(815121763415193074), UINT64CONST(286389039184749612)}, + {UINT64CONST(11720143854957885429), UINT64CONST(229111231347799689)}, {UINT64CONST(13065463898708218666), UINT64CONST(183288985078239751)}, + {UINT64CONST(6763022304224664610), UINT64CONST(146631188062591801)}, {UINT64CONST(3442138057275642729), UINT64CONST(234609900900146882)}, + {UINT64CONST(13821756890046245153), UINT64CONST(187687920720117505)}, {UINT64CONST(11057405512036996122), UINT64CONST(150150336576094004)}, + {UINT64CONST(6623802375033462826), UINT64CONST(240240538521750407)}, {UINT64CONST(16367088344252501231), UINT64CONST(192192430817400325)}, + {UINT64CONST(13093670675402000985), UINT64CONST(153753944653920260)}, {UINT64CONST(2503129006933649959), UINT64CONST(246006311446272417)}, + {UINT64CONST(13070549649772650937), UINT64CONST(196805049157017933)}, {UINT64CONST(17835137349301941396), UINT64CONST(157444039325614346)}, + {UINT64CONST(2710778055689733971), UINT64CONST(251910462920982955)}, {UINT64CONST(2168622444551787177), UINT64CONST(201528370336786364)}, + {UINT64CONST(5424246770383340065), UINT64CONST(161222696269429091)}, {UINT64CONST(1300097203129523457), UINT64CONST(257956314031086546)}, + {UINT64CONST(15797473021471260058), UINT64CONST(206365051224869236)}, {UINT64CONST(8948629602435097724), UINT64CONST(165092040979895389)}, + {UINT64CONST(3249760919670425388), UINT64CONST(264147265567832623)}, {UINT64CONST(9978506365220160957), UINT64CONST(211317812454266098)}, + {UINT64CONST(15361502721659949412), UINT64CONST(169054249963412878)}, {UINT64CONST(2442311466204457120), UINT64CONST(270486799941460606)}, + {UINT64CONST(16711244431931206989), UINT64CONST(216389439953168484)}, {UINT64CONST(17058344360286875914), UINT64CONST(173111551962534787)}, + {UINT64CONST(12535955717491360170), UINT64CONST(276978483140055660)}, {UINT64CONST(10028764573993088136), UINT64CONST(221582786512044528)}, + {UINT64CONST(15401709288678291155), UINT64CONST(177266229209635622)}, {UINT64CONST(9885339602917624555), UINT64CONST(283625966735416996)}, + {UINT64CONST(4218922867592189321), UINT64CONST(226900773388333597)}, {UINT64CONST(14443184738299482427), UINT64CONST(181520618710666877)}, + {UINT64CONST(4175850161155765295), UINT64CONST(145216494968533502)}, {UINT64CONST(10370709072591134795), UINT64CONST(232346391949653603)}, + {UINT64CONST(15675264887556728482), UINT64CONST(185877113559722882)}, {UINT64CONST(5161514280561562140), UINT64CONST(148701690847778306)}, + {UINT64CONST(879725219414678777), UINT64CONST(237922705356445290)}, {UINT64CONST(703780175531743021), UINT64CONST(190338164285156232)}, + {UINT64CONST(11631070584651125387), UINT64CONST(152270531428124985)}, {UINT64CONST(162968861732249003), UINT64CONST(243632850284999977)}, + {UINT64CONST(11198421533611530172), UINT64CONST(194906280227999981)}, {UINT64CONST(5269388412147313814), UINT64CONST(155925024182399985)}, + {UINT64CONST(8431021459435702103), UINT64CONST(249480038691839976)}, {UINT64CONST(3055468352806651359), UINT64CONST(199584030953471981)}, + {UINT64CONST(17201769941212962380), UINT64CONST(159667224762777584)}, {UINT64CONST(16454785461715008838), UINT64CONST(255467559620444135)}, + {UINT64CONST(13163828369372007071), UINT64CONST(204374047696355308)}, {UINT64CONST(17909760324981426303), UINT64CONST(163499238157084246)}, + {UINT64CONST(2830174816776909822), UINT64CONST(261598781051334795)}, {UINT64CONST(2264139853421527858), UINT64CONST(209279024841067836)}, + {UINT64CONST(16568707141704863579), UINT64CONST(167423219872854268)}, {UINT64CONST(4373838538276319787), UINT64CONST(267877151796566830)}, + {UINT64CONST(3499070830621055830), UINT64CONST(214301721437253464)}, {UINT64CONST(6488605479238754987), UINT64CONST(171441377149802771)}, + {UINT64CONST(3003071137298187333), UINT64CONST(274306203439684434)}, {UINT64CONST(6091805724580460189), UINT64CONST(219444962751747547)}, + {UINT64CONST(15941491023890099121), UINT64CONST(175555970201398037)}, {UINT64CONST(10748990379256517301), UINT64CONST(280889552322236860)}, + {UINT64CONST(8599192303405213841), UINT64CONST(224711641857789488)}, {UINT64CONST(14258051472207991719), UINT64CONST(179769313486231590)} +}; + +static const uint64 DOUBLE_POW5_SPLIT[326][2] = { + {UINT64CONST(0), UINT64CONST(72057594037927936)}, {UINT64CONST(0), UINT64CONST(90071992547409920)}, + {UINT64CONST(0), UINT64CONST(112589990684262400)}, {UINT64CONST(0), UINT64CONST(140737488355328000)}, + {UINT64CONST(0), UINT64CONST(87960930222080000)}, {UINT64CONST(0), UINT64CONST(109951162777600000)}, + {UINT64CONST(0), UINT64CONST(137438953472000000)}, {UINT64CONST(0), UINT64CONST(85899345920000000)}, + {UINT64CONST(0), UINT64CONST(107374182400000000)}, {UINT64CONST(0), UINT64CONST(134217728000000000)}, + {UINT64CONST(0), UINT64CONST(83886080000000000)}, {UINT64CONST(0), UINT64CONST(104857600000000000)}, + {UINT64CONST(0), UINT64CONST(131072000000000000)}, {UINT64CONST(0), UINT64CONST(81920000000000000)}, + {UINT64CONST(0), UINT64CONST(102400000000000000)}, {UINT64CONST(0), UINT64CONST(128000000000000000)}, + {UINT64CONST(0), UINT64CONST(80000000000000000)}, {UINT64CONST(0), UINT64CONST(100000000000000000)}, + {UINT64CONST(0), UINT64CONST(125000000000000000)}, {UINT64CONST(0), UINT64CONST(78125000000000000)}, + {UINT64CONST(0), UINT64CONST(97656250000000000)}, {UINT64CONST(0), UINT64CONST(122070312500000000)}, + {UINT64CONST(0), UINT64CONST(76293945312500000)}, {UINT64CONST(0), UINT64CONST(95367431640625000)}, + {UINT64CONST(0), UINT64CONST(119209289550781250)}, {UINT64CONST(4611686018427387904), UINT64CONST(74505805969238281)}, + {UINT64CONST(10376293541461622784), UINT64CONST(93132257461547851)}, {UINT64CONST(8358680908399640576), UINT64CONST(116415321826934814)}, + {UINT64CONST(612489549322387456), UINT64CONST(72759576141834259)}, {UINT64CONST(14600669991935148032), UINT64CONST(90949470177292823)}, + {UINT64CONST(13639151471491547136), UINT64CONST(113686837721616029)}, {UINT64CONST(3213881284082270208), UINT64CONST(142108547152020037)}, + {UINT64CONST(4314518811765112832), UINT64CONST(88817841970012523)}, {UINT64CONST(781462496279003136), UINT64CONST(111022302462515654)}, + {UINT64CONST(10200200157203529728), UINT64CONST(138777878078144567)}, {UINT64CONST(13292654125893287936), UINT64CONST(86736173798840354)}, + {UINT64CONST(7392445620511834112), UINT64CONST(108420217248550443)}, {UINT64CONST(4628871007212404736), UINT64CONST(135525271560688054)}, + {UINT64CONST(16728102434789916672), UINT64CONST(84703294725430033)}, {UINT64CONST(7075069988205232128), UINT64CONST(105879118406787542)}, + {UINT64CONST(18067209522111315968), UINT64CONST(132348898008484427)}, {UINT64CONST(8986162942105878528), UINT64CONST(82718061255302767)}, + {UINT64CONST(6621017659204960256), UINT64CONST(103397576569128459)}, {UINT64CONST(3664586055578812416), UINT64CONST(129246970711410574)}, + {UINT64CONST(16125424340018921472), UINT64CONST(80779356694631608)}, {UINT64CONST(1710036351314100224), UINT64CONST(100974195868289511)}, + {UINT64CONST(15972603494424788992), UINT64CONST(126217744835361888)}, {UINT64CONST(9982877184015493120), UINT64CONST(78886090522101180)}, + {UINT64CONST(12478596480019366400), UINT64CONST(98607613152626475)}, {UINT64CONST(10986559581596820096), UINT64CONST(123259516440783094)}, + {UINT64CONST(2254913720070624656), UINT64CONST(77037197775489434)}, {UINT64CONST(12042014186943056628), UINT64CONST(96296497219361792)}, + {UINT64CONST(15052517733678820785), UINT64CONST(120370621524202240)}, {UINT64CONST(9407823583549262990), UINT64CONST(75231638452626400)}, + {UINT64CONST(11759779479436578738), UINT64CONST(94039548065783000)}, {UINT64CONST(14699724349295723422), UINT64CONST(117549435082228750)}, + {UINT64CONST(4575641699882439235), UINT64CONST(73468396926392969)}, {UINT64CONST(10331238143280436948), UINT64CONST(91835496157991211)}, + {UINT64CONST(8302361660673158281), UINT64CONST(114794370197489014)}, {UINT64CONST(1154580038986672043), UINT64CONST(143492962746861268)}, + {UINT64CONST(9944984561221445835), UINT64CONST(89683101716788292)}, {UINT64CONST(12431230701526807293), UINT64CONST(112103877145985365)}, + {UINT64CONST(1703980321626345405), UINT64CONST(140129846432481707)}, {UINT64CONST(17205888765512323542), UINT64CONST(87581154020301066)}, + {UINT64CONST(12283988920035628619), UINT64CONST(109476442525376333)}, {UINT64CONST(1519928094762372062), UINT64CONST(136845553156720417)}, + {UINT64CONST(12479170105294952299), UINT64CONST(85528470722950260)}, {UINT64CONST(15598962631618690374), UINT64CONST(106910588403687825)}, + {UINT64CONST(5663645234241199255), UINT64CONST(133638235504609782)}, {UINT64CONST(17374836326682913246), UINT64CONST(83523897190381113)}, + {UINT64CONST(7883487353071477846), UINT64CONST(104404871487976392)}, {UINT64CONST(9854359191339347308), UINT64CONST(130506089359970490)}, + {UINT64CONST(10770660513014479971), UINT64CONST(81566305849981556)}, {UINT64CONST(13463325641268099964), UINT64CONST(101957882312476945)}, + {UINT64CONST(2994098996302961243), UINT64CONST(127447352890596182)}, {UINT64CONST(15706369927971514489), UINT64CONST(79654595556622613)}, + {UINT64CONST(5797904354682229399), UINT64CONST(99568244445778267)}, {UINT64CONST(2635694424925398845), UINT64CONST(124460305557222834)}, + {UINT64CONST(6258995034005762182), UINT64CONST(77787690973264271)}, {UINT64CONST(3212057774079814824), UINT64CONST(97234613716580339)}, + {UINT64CONST(17850130272881932242), UINT64CONST(121543267145725423)}, {UINT64CONST(18073860448192289507), UINT64CONST(75964541966078389)}, + {UINT64CONST(8757267504958198172), UINT64CONST(94955677457597987)}, {UINT64CONST(6334898362770359811), UINT64CONST(118694596821997484)}, + {UINT64CONST(13182683513586250689), UINT64CONST(74184123013748427)}, {UINT64CONST(11866668373555425458), UINT64CONST(92730153767185534)}, + {UINT64CONST(5609963430089506015), UINT64CONST(115912692208981918)}, {UINT64CONST(17341285199088104971), UINT64CONST(72445432630613698)}, + {UINT64CONST(12453234462005355406), UINT64CONST(90556790788267123)}, {UINT64CONST(10954857059079306353), UINT64CONST(113195988485333904)}, + {UINT64CONST(13693571323849132942), UINT64CONST(141494985606667380)}, {UINT64CONST(17781854114260483896), UINT64CONST(88434366004167112)}, + {UINT64CONST(3780573569116053255), UINT64CONST(110542957505208891)}, {UINT64CONST(114030942967678664), UINT64CONST(138178696881511114)}, + {UINT64CONST(4682955357782187069), UINT64CONST(86361685550944446)}, {UINT64CONST(15077066234082509644), UINT64CONST(107952106938680557)}, + {UINT64CONST(5011274737320973344), UINT64CONST(134940133673350697)}, {UINT64CONST(14661261756894078100), UINT64CONST(84337583545844185)}, + {UINT64CONST(4491519140835433913), UINT64CONST(105421979432305232)}, {UINT64CONST(5614398926044292391), UINT64CONST(131777474290381540)}, + {UINT64CONST(12732371365632458552), UINT64CONST(82360921431488462)}, {UINT64CONST(6692092170185797382), UINT64CONST(102951151789360578)}, + {UINT64CONST(17588487249587022536), UINT64CONST(128688939736700722)}, {UINT64CONST(15604490549419276989), UINT64CONST(80430587335437951)}, + {UINT64CONST(14893927168346708332), UINT64CONST(100538234169297439)}, {UINT64CONST(14005722942005997511), UINT64CONST(125672792711621799)}, + {UINT64CONST(15671105866394830300), UINT64CONST(78545495444763624)}, {UINT64CONST(1142138259283986260), UINT64CONST(98181869305954531)}, + {UINT64CONST(15262730879387146537), UINT64CONST(122727336632443163)}, {UINT64CONST(7233363790403272633), UINT64CONST(76704585395276977)}, + {UINT64CONST(13653390756431478696), UINT64CONST(95880731744096221)}, {UINT64CONST(3231680390257184658), UINT64CONST(119850914680120277)}, + {UINT64CONST(4325643253124434363), UINT64CONST(74906821675075173)}, {UINT64CONST(10018740084832930858), UINT64CONST(93633527093843966)}, + {UINT64CONST(3300053069186387764), UINT64CONST(117041908867304958)}, {UINT64CONST(15897591223523656064), UINT64CONST(73151193042065598)}, + {UINT64CONST(10648616992549794273), UINT64CONST(91438991302581998)}, {UINT64CONST(4087399203832467033), UINT64CONST(114298739128227498)}, + {UINT64CONST(14332621041645359599), UINT64CONST(142873423910284372)}, {UINT64CONST(18181260187883125557), UINT64CONST(89295889943927732)}, + {UINT64CONST(4279831161144355331), UINT64CONST(111619862429909666)}, {UINT64CONST(14573160988285219972), UINT64CONST(139524828037387082)}, + {UINT64CONST(13719911636105650386), UINT64CONST(87203017523366926)}, {UINT64CONST(7926517508277287175), UINT64CONST(109003771904208658)}, + {UINT64CONST(684774848491833161), UINT64CONST(136254714880260823)}, {UINT64CONST(7345513307948477581), UINT64CONST(85159196800163014)}, + {UINT64CONST(18405263671790372785), UINT64CONST(106448996000203767)}, {UINT64CONST(18394893571310578077), UINT64CONST(133061245000254709)}, + {UINT64CONST(13802651491282805250), UINT64CONST(83163278125159193)}, {UINT64CONST(3418256308821342851), UINT64CONST(103954097656448992)}, + {UINT64CONST(4272820386026678563), UINT64CONST(129942622070561240)}, {UINT64CONST(2670512741266674102), UINT64CONST(81214138794100775)}, + {UINT64CONST(17173198981865506339), UINT64CONST(101517673492625968)}, {UINT64CONST(3019754653622331308), UINT64CONST(126897091865782461)}, + {UINT64CONST(4193189667727651020), UINT64CONST(79310682416114038)}, {UINT64CONST(14464859121514339583), UINT64CONST(99138353020142547)}, + {UINT64CONST(13469387883465536574), UINT64CONST(123922941275178184)}, {UINT64CONST(8418367427165960359), UINT64CONST(77451838296986365)}, + {UINT64CONST(15134645302384838353), UINT64CONST(96814797871232956)}, {UINT64CONST(471562554271496325), UINT64CONST(121018497339041196)}, + {UINT64CONST(9518098633274461011), UINT64CONST(75636560836900747)}, {UINT64CONST(7285937273165688360), UINT64CONST(94545701046125934)}, + {UINT64CONST(18330793628311886258), UINT64CONST(118182126307657417)}, {UINT64CONST(4539216990053847055), UINT64CONST(73863828942285886)}, + {UINT64CONST(14897393274422084627), UINT64CONST(92329786177857357)}, {UINT64CONST(4786683537745442072), UINT64CONST(115412232722321697)}, + {UINT64CONST(14520892257159371055), UINT64CONST(72132645451451060)}, {UINT64CONST(18151115321449213818), UINT64CONST(90165806814313825)}, + {UINT64CONST(8853836096529353561), UINT64CONST(112707258517892282)}, {UINT64CONST(1843923083806916143), UINT64CONST(140884073147365353)}, + {UINT64CONST(12681666973447792349), UINT64CONST(88052545717103345)}, {UINT64CONST(2017025661527576725), UINT64CONST(110065682146379182)}, + {UINT64CONST(11744654113764246714), UINT64CONST(137582102682973977)}, {UINT64CONST(422879793461572340), UINT64CONST(85988814176858736)}, + {UINT64CONST(528599741826965425), UINT64CONST(107486017721073420)}, {UINT64CONST(660749677283706782), UINT64CONST(134357522151341775)}, + {UINT64CONST(7330497575943398595), UINT64CONST(83973451344588609)}, {UINT64CONST(13774807988356636147), UINT64CONST(104966814180735761)}, + {UINT64CONST(3383451930163631472), UINT64CONST(131208517725919702)}, {UINT64CONST(15949715511634433382), UINT64CONST(82005323578699813)}, + {UINT64CONST(6102086334260878016), UINT64CONST(102506654473374767)}, {UINT64CONST(3015921899398709616), UINT64CONST(128133318091718459)}, + {UINT64CONST(18025852251620051174), UINT64CONST(80083323807324036)}, {UINT64CONST(4085571240815512351), UINT64CONST(100104154759155046)}, + {UINT64CONST(14330336087874166247), UINT64CONST(125130193448943807)}, {UINT64CONST(15873989082562435760), UINT64CONST(78206370905589879)}, + {UINT64CONST(15230800334775656796), UINT64CONST(97757963631987349)}, {UINT64CONST(5203442363187407284), UINT64CONST(122197454539984187)}, + {UINT64CONST(946308467778435600), UINT64CONST(76373409087490117)}, {UINT64CONST(5794571603150432404), UINT64CONST(95466761359362646)}, + {UINT64CONST(16466586540792816313), UINT64CONST(119333451699203307)}, {UINT64CONST(7985773578781816244), UINT64CONST(74583407312002067)}, + {UINT64CONST(5370530955049882401), UINT64CONST(93229259140002584)}, {UINT64CONST(6713163693812353001), UINT64CONST(116536573925003230)}, + {UINT64CONST(18030785363914884337), UINT64CONST(72835358703127018)}, {UINT64CONST(13315109668038829614), UINT64CONST(91044198378908773)}, + {UINT64CONST(2808829029766373305), UINT64CONST(113805247973635967)}, {UINT64CONST(17346094342490130344), UINT64CONST(142256559967044958)}, + {UINT64CONST(6229622945628943561), UINT64CONST(88910349979403099)}, {UINT64CONST(3175342663608791547), UINT64CONST(111137937474253874)}, + {UINT64CONST(13192550366365765242), UINT64CONST(138922421842817342)}, {UINT64CONST(3633657960551215372), UINT64CONST(86826513651760839)}, + {UINT64CONST(18377130505971182927), UINT64CONST(108533142064701048)}, {UINT64CONST(4524669058754427043), UINT64CONST(135666427580876311)}, + {UINT64CONST(9745447189362598758), UINT64CONST(84791517238047694)}, {UINT64CONST(2958436949848472639), UINT64CONST(105989396547559618)}, + {UINT64CONST(12921418224165366607), UINT64CONST(132486745684449522)}, {UINT64CONST(12687572408530742033), UINT64CONST(82804216052780951)}, + {UINT64CONST(11247779492236039638), UINT64CONST(103505270065976189)}, {UINT64CONST(224666310012885835), UINT64CONST(129381587582470237)}, + {UINT64CONST(2446259452971747599), UINT64CONST(80863492239043898)}, {UINT64CONST(12281196353069460307), UINT64CONST(101079365298804872)}, + {UINT64CONST(15351495441336825384), UINT64CONST(126349206623506090)}, {UINT64CONST(14206370669262903769), UINT64CONST(78968254139691306)}, + {UINT64CONST(8534591299723853903), UINT64CONST(98710317674614133)}, {UINT64CONST(15279925143082205283), UINT64CONST(123387897093267666)}, + {UINT64CONST(14161639232853766206), UINT64CONST(77117435683292291)}, {UINT64CONST(13090363022639819853), UINT64CONST(96396794604115364)}, + {UINT64CONST(16362953778299774816), UINT64CONST(120495993255144205)}, {UINT64CONST(12532689120651053212), UINT64CONST(75309995784465128)}, + {UINT64CONST(15665861400813816515), UINT64CONST(94137494730581410)}, {UINT64CONST(10358954714162494836), UINT64CONST(117671868413226763)}, + {UINT64CONST(4168503687137865320), UINT64CONST(73544917758266727)}, {UINT64CONST(598943590494943747), UINT64CONST(91931147197833409)}, + {UINT64CONST(5360365506546067587), UINT64CONST(114913933997291761)}, {UINT64CONST(11312142901609972388), UINT64CONST(143642417496614701)}, + {UINT64CONST(9375932322719926695), UINT64CONST(89776510935384188)}, {UINT64CONST(11719915403399908368), UINT64CONST(112220638669230235)}, + {UINT64CONST(10038208235822497557), UINT64CONST(140275798336537794)}, {UINT64CONST(10885566165816448877), UINT64CONST(87672373960336121)}, + {UINT64CONST(18218643725697949000), UINT64CONST(109590467450420151)}, {UINT64CONST(18161618638695048346), UINT64CONST(136988084313025189)}, + {UINT64CONST(13656854658398099168), UINT64CONST(85617552695640743)}, {UINT64CONST(12459382304570236056), UINT64CONST(107021940869550929)}, + {UINT64CONST(1739169825430631358), UINT64CONST(133777426086938662)}, {UINT64CONST(14922039196176308311), UINT64CONST(83610891304336663)}, + {UINT64CONST(14040862976792997485), UINT64CONST(104513614130420829)}, {UINT64CONST(3716020665709083144), UINT64CONST(130642017663026037)}, + {UINT64CONST(4628355925281870917), UINT64CONST(81651261039391273)}, {UINT64CONST(10397130925029726550), UINT64CONST(102064076299239091)}, + {UINT64CONST(8384727637859770284), UINT64CONST(127580095374048864)}, {UINT64CONST(5240454773662356427), UINT64CONST(79737559608780540)}, + {UINT64CONST(6550568467077945534), UINT64CONST(99671949510975675)}, {UINT64CONST(3576524565420044014), UINT64CONST(124589936888719594)}, + {UINT64CONST(6847013871814915412), UINT64CONST(77868710555449746)}, {UINT64CONST(17782139376623420074), UINT64CONST(97335888194312182)}, + {UINT64CONST(13004302183924499284), UINT64CONST(121669860242890228)}, {UINT64CONST(17351060901807587860), UINT64CONST(76043662651806392)}, + {UINT64CONST(3242082053549933210), UINT64CONST(95054578314757991)}, {UINT64CONST(17887660622219580224), UINT64CONST(118818222893447488)}, + {UINT64CONST(11179787888887237640), UINT64CONST(74261389308404680)}, {UINT64CONST(13974734861109047050), UINT64CONST(92826736635505850)}, + {UINT64CONST(8245046539531533005), UINT64CONST(116033420794382313)}, {UINT64CONST(16682369133275677888), UINT64CONST(72520887996488945)}, + {UINT64CONST(7017903361312433648), UINT64CONST(90651109995611182)}, {UINT64CONST(17995751238495317868), UINT64CONST(113313887494513977)}, + {UINT64CONST(8659630992836983623), UINT64CONST(141642359368142472)}, {UINT64CONST(5412269370523114764), UINT64CONST(88526474605089045)}, + {UINT64CONST(11377022731581281359), UINT64CONST(110658093256361306)}, {UINT64CONST(4997906377621825891), UINT64CONST(138322616570451633)}, + {UINT64CONST(14652906532082110942), UINT64CONST(86451635356532270)}, {UINT64CONST(9092761128247862869), UINT64CONST(108064544195665338)}, + {UINT64CONST(2142579373455052779), UINT64CONST(135080680244581673)}, {UINT64CONST(12868327154477877747), UINT64CONST(84425425152863545)}, + {UINT64CONST(2250350887815183471), UINT64CONST(105531781441079432)}, {UINT64CONST(2812938609768979339), UINT64CONST(131914726801349290)}, + {UINT64CONST(6369772649532999991), UINT64CONST(82446704250843306)}, {UINT64CONST(17185587848771025797), UINT64CONST(103058380313554132)}, + {UINT64CONST(3035240737254230630), UINT64CONST(128822975391942666)}, {UINT64CONST(6508711479211282048), UINT64CONST(80514359619964166)}, + {UINT64CONST(17359261385868878368), UINT64CONST(100642949524955207)}, {UINT64CONST(17087390713908710056), UINT64CONST(125803686906194009)}, + {UINT64CONST(3762090168551861929), UINT64CONST(78627304316371256)}, {UINT64CONST(4702612710689827411), UINT64CONST(98284130395464070)}, + {UINT64CONST(15101637925217060072), UINT64CONST(122855162994330087)}, {UINT64CONST(16356052730901744401), UINT64CONST(76784476871456304)}, + {UINT64CONST(1998321839917628885), UINT64CONST(95980596089320381)}, {UINT64CONST(7109588318324424010), UINT64CONST(119975745111650476)}, + {UINT64CONST(13666864735807540814), UINT64CONST(74984840694781547)}, {UINT64CONST(12471894901332038114), UINT64CONST(93731050868476934)}, + {UINT64CONST(6366496589810271835), UINT64CONST(117163813585596168)}, {UINT64CONST(3979060368631419896), UINT64CONST(73227383490997605)}, + {UINT64CONST(9585511479216662775), UINT64CONST(91534229363747006)}, {UINT64CONST(2758517312166052660), UINT64CONST(114417786704683758)}, + {UINT64CONST(12671518677062341634), UINT64CONST(143022233380854697)}, {UINT64CONST(1002170145522881665), UINT64CONST(89388895863034186)}, + {UINT64CONST(10476084718758377889), UINT64CONST(111736119828792732)}, {UINT64CONST(13095105898447972362), UINT64CONST(139670149785990915)}, + {UINT64CONST(5878598177316288774), UINT64CONST(87293843616244322)}, {UINT64CONST(16571619758500136775), UINT64CONST(109117304520305402)}, + {UINT64CONST(11491152661270395161), UINT64CONST(136396630650381753)}, {UINT64CONST(264441385652915120), UINT64CONST(85247894156488596)}, + {UINT64CONST(330551732066143900), UINT64CONST(106559867695610745)}, {UINT64CONST(5024875683510067779), UINT64CONST(133199834619513431)}, + {UINT64CONST(10058076329834874218), UINT64CONST(83249896637195894)}, {UINT64CONST(3349223375438816964), UINT64CONST(104062370796494868)}, + {UINT64CONST(4186529219298521205), UINT64CONST(130077963495618585)}, {UINT64CONST(14145795808130045513), UINT64CONST(81298727184761615)}, + {UINT64CONST(13070558741735168987), UINT64CONST(101623408980952019)}, {UINT64CONST(11726512408741573330), UINT64CONST(127029261226190024)}, + {UINT64CONST(7329070255463483331), UINT64CONST(79393288266368765)}, {UINT64CONST(13773023837756742068), UINT64CONST(99241610332960956)}, + {UINT64CONST(17216279797195927585), UINT64CONST(124052012916201195)}, {UINT64CONST(8454331864033760789), UINT64CONST(77532508072625747)}, + {UINT64CONST(5956228811614813082), UINT64CONST(96915635090782184)}, {UINT64CONST(7445286014518516353), UINT64CONST(121144543863477730)}, + {UINT64CONST(9264989777501460624), UINT64CONST(75715339914673581)}, {UINT64CONST(16192923240304213684), UINT64CONST(94644174893341976)}, + {UINT64CONST(1794409976670715490), UINT64CONST(118305218616677471)}, {UINT64CONST(8039035263060279037), UINT64CONST(73940761635423419)}, + {UINT64CONST(5437108060397960892), UINT64CONST(92425952044279274)}, {UINT64CONST(16019757112352226923), UINT64CONST(115532440055349092)}, + {UINT64CONST(788976158365366019), UINT64CONST(72207775034593183)}, {UINT64CONST(14821278253238871236), UINT64CONST(90259718793241478)}, + {UINT64CONST(9303225779693813237), UINT64CONST(112824648491551848)}, {UINT64CONST(11629032224617266546), UINT64CONST(141030810614439810)}, + {UINT64CONST(11879831158813179495), UINT64CONST(88144256634024881)}, {UINT64CONST(1014730893234310657), UINT64CONST(110180320792531102)}, + {UINT64CONST(10491785653397664129), UINT64CONST(137725400990663877)}, {UINT64CONST(8863209042587234033), UINT64CONST(86078375619164923)}, + {UINT64CONST(6467325284806654637), UINT64CONST(107597969523956154)}, {UINT64CONST(17307528642863094104), UINT64CONST(134497461904945192)}, + {UINT64CONST(10817205401789433815), UINT64CONST(84060913690590745)}, {UINT64CONST(18133192770664180173), UINT64CONST(105076142113238431)}, + {UINT64CONST(18054804944902837312), UINT64CONST(131345177641548039)}, {UINT64CONST(18201782118205355176), UINT64CONST(82090736025967524)}, + {UINT64CONST(4305483574047142354), UINT64CONST(102613420032459406)}, {UINT64CONST(14605226504413703751), UINT64CONST(128266775040574257)}, + {UINT64CONST(2210737537617482988), UINT64CONST(80166734400358911)}, {UINT64CONST(16598479977304017447), UINT64CONST(100208418000448638)}, + {UINT64CONST(11524727934775246001), UINT64CONST(125260522500560798)}, {UINT64CONST(2591268940807140847), UINT64CONST(78287826562850499)}, + {UINT64CONST(17074144231291089770), UINT64CONST(97859783203563123)}, {UINT64CONST(16730994270686474309), UINT64CONST(122324729004453904)}, + {UINT64CONST(10456871419179046443), UINT64CONST(76452955627783690)}, {UINT64CONST(3847717237119032246), UINT64CONST(95566194534729613)}, + {UINT64CONST(9421332564826178211), UINT64CONST(119457743168412016)}, {UINT64CONST(5888332853016361382), UINT64CONST(74661089480257510)}, + {UINT64CONST(16583788103125227536), UINT64CONST(93326361850321887)}, {UINT64CONST(16118049110479146516), UINT64CONST(116657952312902359)}, + {UINT64CONST(16991309721690548428), UINT64CONST(72911220195563974)}, {UINT64CONST(12015765115258409727), UINT64CONST(91139025244454968)}, + {UINT64CONST(15019706394073012159), UINT64CONST(113923781555568710)}, {UINT64CONST(9551260955736489391), UINT64CONST(142404726944460888)}, + {UINT64CONST(5969538097335305869), UINT64CONST(89002954340288055)}, {UINT64CONST(2850236603241744433), UINT64CONST(111253692925360069)} +}; + +#endif /* RYU_D2S_FULL_TABLE_H */ diff --git a/src/common/d2s_intrinsics.h b/src/common/d2s_intrinsics.h new file mode 100644 index 00000000000..248889e6493 --- /dev/null +++ b/src/common/d2s_intrinsics.h @@ -0,0 +1,202 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output for double precision. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/d2s_intrinsics.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ +#ifndef RYU_D2S_INTRINSICS_H +#define RYU_D2S_INTRINSICS_H + +#if defined(HAS_64_BIT_INTRINSICS) + +#include + +static inline uint64 +umul128(const uint64 a, const uint64 b, uint64 *const productHi) +{ + return _umul128(a, b, productHi); +} + +static inline uint64 +shiftright128(const uint64 lo, const uint64 hi, const uint32 dist) +{ + /* + * For the __shiftright128 intrinsic, the shift value is always modulo 64. + * In the current implementation of the double-precision version of Ryu, + * the shift value is always < 64. (In the case RYU_OPTIMIZE_SIZE == 0, + * the shift value is in the range [49, 58]. Otherwise in the range [2, + * 59].) Check this here in case a future change requires larger shift + * values. In this case this function needs to be adjusted. + */ + Assert(dist < 64); + return __shiftright128(lo, hi, (unsigned char) dist); +} + +#else /* defined(HAS_64_BIT_INTRINSICS) */ + +static inline uint64 +umul128(const uint64 a, const uint64 b, uint64 *const productHi) +{ + /* + * The casts here help MSVC to avoid calls to the __allmul library + * function. + */ + const uint32 aLo = (uint32) a; + const uint32 aHi = (uint32) (a >> 32); + const uint32 bLo = (uint32) b; + const uint32 bHi = (uint32) (b >> 32); + + const uint64 b00 = (uint64) aLo * bLo; + const uint64 b01 = (uint64) aLo * bHi; + const uint64 b10 = (uint64) aHi * bLo; + const uint64 b11 = (uint64) aHi * bHi; + + const uint32 b00Lo = (uint32) b00; + const uint32 b00Hi = (uint32) (b00 >> 32); + + const uint64 mid1 = b10 + b00Hi; + const uint32 mid1Lo = (uint32) (mid1); + const uint32 mid1Hi = (uint32) (mid1 >> 32); + + const uint64 mid2 = b01 + mid1Lo; + const uint32 mid2Lo = (uint32) (mid2); + const uint32 mid2Hi = (uint32) (mid2 >> 32); + + const uint64 pHi = b11 + mid1Hi + mid2Hi; + const uint64 pLo = ((uint64) mid2Lo << 32) + b00Lo; + + *productHi = pHi; + return pLo; +} + +static inline uint64 +shiftright128(const uint64 lo, const uint64 hi, const uint32 dist) +{ + /* We don't need to handle the case dist >= 64 here (see above). */ + Assert(dist < 64); +#if !defined(RYU_32_BIT_PLATFORM) + Assert(dist > 0); + return (hi << (64 - dist)) | (lo >> dist); +#else + /* Avoid a 64-bit shift by taking advantage of the range of shift values. */ + Assert(dist >= 32); + return (hi << (64 - dist)) | ((uint32) (lo >> 32) >> (dist - 32)); +#endif +} + +#endif /* // defined(HAS_64_BIT_INTRINSICS) */ + +#ifdef RYU_32_BIT_PLATFORM + +/* Returns the high 64 bits of the 128-bit product of a and b. */ +static inline uint64 +umulh(const uint64 a, const uint64 b) +{ + /* + * Reuse the umul128 implementation. Optimizers will likely eliminate the + * instructions used to compute the low part of the product. + */ + uint64 hi; + + umul128(a, b, &hi); + return hi; +} + +/*---- + * On 32-bit platforms, compilers typically generate calls to library + * functions for 64-bit divisions, even if the divisor is a constant. + * + * E.g.: + * https://bugs.llvm.org/show_bug.cgi?id=37932 + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958 + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443 + * + * The functions here perform division-by-constant using multiplications + * in the same way as 64-bit compilers would do. + * + * NB: + * The multipliers and shift values are the ones generated by clang x64 + * for expressions like x/5, x/10, etc. + *---- + */ + +static inline uint64 +div5(const uint64 x) +{ + return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 2; +} + +static inline uint64 +div10(const uint64 x) +{ + return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 3; +} + +static inline uint64 +div100(const uint64 x) +{ + return umulh(x >> 2, UINT64CONST(0x28F5C28F5C28F5C3)) >> 2; +} + +static inline uint64 +div1e8(const uint64 x) +{ + return umulh(x, UINT64CONST(0xABCC77118461CEFD)) >> 26; +} + +#else /* RYU_32_BIT_PLATFORM */ + +static inline uint64 +div5(const uint64 x) +{ + return x / 5; +} + +static inline uint64 +div10(const uint64 x) +{ + return x / 10; +} + +static inline uint64 +div100(const uint64 x) +{ + return x / 100; +} + +static inline uint64 +div1e8(const uint64 x) +{ + return x / 100000000; +} + +#endif /* RYU_32_BIT_PLATFORM */ + +#endif /* RYU_D2S_INTRINSICS_H */ diff --git a/src/common/digit_table.h b/src/common/digit_table.h new file mode 100644 index 00000000000..483aa171424 --- /dev/null +++ b/src/common/digit_table.h @@ -0,0 +1,21 @@ +#ifndef RYU_DIGIT_TABLE_H +#define RYU_DIGIT_TABLE_H + +/* + * A table of all two-digit numbers. This is used to speed up decimal digit + * generation by copying pairs of digits into the final output. + */ +static const char DIGIT_TABLE[200] = { + '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', + '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', + '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', + '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', + '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', + '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', + '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', + '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', + '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', + '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9' +}; + +#endif /* RYU_DIGIT_TABLE_H */ diff --git a/src/common/exec.c b/src/common/exec.c index e3e81c1db85..f7f3890be47 100644 --- a/src/common/exec.c +++ b/src/common/exec.c @@ -4,7 +4,7 @@ * Functions for finding and validating executable files * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -25,14 +25,24 @@ #include #include +/* + * Hacky solution to allow expressing both frontend and backend error reports + * in one macro call. First argument of log_error is an errcode() call of + * some sort (ignored if FRONTEND); the rest are errmsg_internal() arguments, + * i.e. message string and any parameters for it. + * + * Caller must provide the gettext wrapper around the message string, if + * appropriate, so that it gets translated in the FRONTEND case; this + * motivates using errmsg_internal() not errmsg(). We handle appending a + * newline, if needed, inside the macro, so that there's only one translatable + * string per call not two. + */ #ifndef FRONTEND -/* We use only 3- and 4-parameter elog calls in this file, for simplicity */ -/* NOTE: caller must provide gettext call around str! */ -#define log_error(str, param) elog(LOG, str, param) -#define log_error4(str, param, arg1) elog(LOG, str, param, arg1) +#define log_error(errcodefn, ...) \ + ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__))) #else -#define log_error(str, param) (fprintf(stderr, str, param), fputc('\n', stderr)) -#define log_error4(str, param, arg1) (fprintf(stderr, str, param, arg1), fputc('\n', stderr)) +#define log_error(errcodefn, ...) \ + (fprintf(stderr, __VA_ARGS__), fputc('\n', stderr)) #endif #ifdef _MSC_VER @@ -124,8 +134,8 @@ find_my_exec(const char *argv0, char *retpath) if (!getcwd(cwd, MAXPGPATH)) { - log_error(_("could not identify current directory: %s"), - strerror(errno)); + log_error(errcode_for_file_access(), + _("could not identify current directory: %m")); return -1; } @@ -143,7 +153,8 @@ find_my_exec(const char *argv0, char *retpath) if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); - log_error(_("invalid binary \"%s\""), retpath); + log_error(errcode(ERRCODE_WRONG_OBJECT_TYPE), + _("invalid binary \"%s\""), retpath); return -1; } @@ -158,6 +169,8 @@ find_my_exec(const char *argv0, char *retpath) * Since no explicit path was supplied, the user must have been relying on * PATH. We'll search the same PATH. */ + path = getenv("PATH"); + Assert(path != NULL); if ((path = getenv("PATH")) && *path) { char *startp = NULL, @@ -184,7 +197,6 @@ find_my_exec(const char *argv0, char *retpath) join_path_components(retpath, retpath, argv0); } canonicalize_path(retpath); - switch (validate_exec(retpath)) { case 0: /* found ok */ @@ -192,14 +204,15 @@ find_my_exec(const char *argv0, char *retpath) case -1: /* wasn't even a candidate, keep looking */ break; case -2: /* found but disqualified */ - log_error(_("could not read binary \"%s\""), + log_error(errcode(ERRCODE_WRONG_OBJECT_TYPE), + _("could not read binary \"%s\""), retpath); break; } } while (*endp); } - - log_error(_("could not find a \"%s\" to execute"), argv0); + log_error(errcode(ERRCODE_UNDEFINED_FILE), + _("could not find a \"%s\" to execute"), argv0); return -1; } @@ -238,8 +251,8 @@ resolve_symlinks(char *path) */ if (!getcwd(orig_wd, MAXPGPATH)) { - log_error(_("could not identify current directory: %s"), - strerror(errno)); + log_error(errcode_for_file_access(), + _("could not identify current directory: %m")); return -1; } @@ -254,7 +267,8 @@ resolve_symlinks(char *path) *lsep = '\0'; if (chdir(path) == -1) { - log_error4(_("could not change directory to \"%s\": %s"), path, strerror(errno)); + log_error(errcode_for_file_access(), + _("could not change directory to \"%s\": %m"), path); return -1; } fname = lsep + 1; @@ -266,10 +280,12 @@ resolve_symlinks(char *path) !S_ISLNK(buf.st_mode)) break; + errno = 0; rllen = readlink(fname, link_buf, sizeof(link_buf)); if (rllen < 0 || rllen >= sizeof(link_buf)) { - log_error(_("could not read symbolic link \"%s\""), fname); + log_error(errcode_for_file_access(), + _("could not read symbolic link \"%s\": %m"), fname); return -1; } link_buf[rllen] = '\0'; @@ -281,8 +297,8 @@ resolve_symlinks(char *path) if (!getcwd(path, MAXPGPATH)) { - log_error(_("could not identify current directory: %s"), - strerror(errno)); + log_error(errcode_for_file_access(), + _("could not identify current directory: %m")); return -1; } join_path_components(path, path, link_buf); @@ -290,7 +306,8 @@ resolve_symlinks(char *path) if (chdir(orig_wd) == -1) { - log_error4(_("could not change directory to \"%s\": %s"), orig_wd, strerror(errno)); + log_error(errcode_for_file_access(), + _("could not change directory to \"%s\": %m"), orig_wd); return -1; } #endif /* HAVE_READLINK */ @@ -308,7 +325,7 @@ find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath) { char cmd[MAXPGPATH]; - char line[100]; + char line[MAXPGPATH]; if (find_my_exec(argv0, retpath) < 0) return -1; @@ -520,17 +537,15 @@ pclose_check(FILE *stream) if (exitstatus == -1) { /* pclose() itself failed, and hopefully set errno */ - log_error(_("pclose failed: %s"), strerror(errno)); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + _("pclose failed: %m")); } else { reason = wait_result_to_str(exitstatus); - log_error("%s", reason); -#ifdef FRONTEND - free(reason); -#else + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "%s", reason); pfree(reason); -#endif } return exitstatus; } @@ -651,19 +666,24 @@ AddUserToTokenDacl(HANDLE hToken) ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize); if (ptdd == NULL) { - log_error("could not allocate %lu bytes of memory", dwSize); + log_error(errcode(ERRCODE_OUT_OF_MEMORY), + _("out of memory")); goto cleanup; } if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize)) { - log_error("could not get token information: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get token information: error code %lu", + GetLastError()); goto cleanup; } } else { - log_error("could not get token information buffer size: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get token information buffer size: error code %lu", + GetLastError()); goto cleanup; } } @@ -673,7 +693,9 @@ AddUserToTokenDacl(HANDLE hToken) (DWORD) sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) { - log_error("could not get ACL information: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get ACL information: error code %lu", + GetLastError()); goto cleanup; } @@ -689,13 +711,15 @@ AddUserToTokenDacl(HANDLE hToken) pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize); if (pacl == NULL) { - log_error("could not allocate %lu bytes of memory", dwNewAclSize); + log_error(errcode(ERRCODE_OUT_OF_MEMORY), + _("out of memory")); goto cleanup; } if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION)) { - log_error("could not initialize ACL: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not initialize ACL: error code %lu", GetLastError()); goto cleanup; } @@ -704,13 +728,15 @@ AddUserToTokenDacl(HANDLE hToken) { if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *) &pace)) { - log_error("could not get ACE: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get ACE: error code %lu", GetLastError()); goto cleanup; } if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize)) { - log_error("could not add ACE: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not add ACE: error code %lu", GetLastError()); goto cleanup; } } @@ -718,7 +744,9 @@ AddUserToTokenDacl(HANDLE hToken) /* Add the new ACE for the current user */ if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid)) { - log_error("could not add access allowed ACE: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not add access allowed ACE: error code %lu", + GetLastError()); goto cleanup; } @@ -727,7 +755,9 @@ AddUserToTokenDacl(HANDLE hToken) if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize)) { - log_error("could not set token information: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not set token information: error code %lu", + GetLastError()); goto cleanup; } @@ -773,13 +803,16 @@ GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser) if (*ppTokenUser == NULL) { - log_error("could not allocate %lu bytes of memory", dwLength); + log_error(errcode(ERRCODE_OUT_OF_MEMORY), + _("out of memory")); return FALSE; } } else { - log_error("could not get token information buffer size: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get token information buffer size: error code %lu", + GetLastError()); return FALSE; } } @@ -793,7 +826,9 @@ GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser) LocalFree(*ppTokenUser); *ppTokenUser = NULL; - log_error("could not get token information: error code %lu", GetLastError()); + log_error(errcode(ERRCODE_SYSTEM_ERROR), + "could not get token information: error code %lu", + GetLastError()); return FALSE; } diff --git a/src/common/f2s.c b/src/common/f2s.c new file mode 100644 index 00000000000..e3325573b28 --- /dev/null +++ b/src/common/f2s.c @@ -0,0 +1,804 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output for single precision. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/f2s.c + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ + +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif + +#include "common/shortest_dec.h" + +#include "ryu_common.h" +#include "digit_table.h" + +#define FLOAT_MANTISSA_BITS 23 +#define FLOAT_EXPONENT_BITS 8 +#define FLOAT_BIAS 127 + +/* + * This table is generated (by the upstream) by PrintFloatLookupTable, + * and modified (by us) to add UINT64CONST. + */ +#define FLOAT_POW5_INV_BITCOUNT 59 +static const uint64 FLOAT_POW5_INV_SPLIT[31] = { + UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826), + UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670), + UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688), + UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727), + UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350), + UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234), + UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971), + UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730) +}; +#define FLOAT_POW5_BITCOUNT 61 +static const uint64 FLOAT_POW5_SPLIT[47] = { + UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000), + UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000), + UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000), + UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000), + UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000), + UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000), + UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031), + UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594), + UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675), + UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678), + UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187), + UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221) +}; + +static inline uint32 +pow5Factor(uint32 value) +{ + uint32 count = 0; + + for (;;) + { + Assert(value != 0); + const uint32 q = value / 5; + const uint32 r = value % 5; + + if (r != 0) + break; + + value = q; + ++count; + } + return count; +} + +/* Returns true if value is divisible by 5^p. */ +static inline bool +multipleOfPowerOf5(const uint32 value, const uint32 p) +{ + return pow5Factor(value) >= p; +} + +/* Returns true if value is divisible by 2^p. */ +static inline bool +multipleOfPowerOf2(const uint32 value, const uint32 p) +{ + /* return __builtin_ctz(value) >= p; */ + return (value & ((1u << p) - 1)) == 0; +} + +/* + * It seems to be slightly faster to avoid uint128_t here, although the + * generated code for uint128_t looks slightly nicer. + */ +static inline uint32 +mulShift(const uint32 m, const uint64 factor, const int32 shift) +{ + /* + * The casts here help MSVC to avoid calls to the __allmul library + * function. + */ + const uint32 factorLo = (uint32) (factor); + const uint32 factorHi = (uint32) (factor >> 32); + const uint64 bits0 = (uint64) m * factorLo; + const uint64 bits1 = (uint64) m * factorHi; + + Assert(shift > 32); + +#ifdef RYU_32_BIT_PLATFORM + + /* + * On 32-bit platforms we can avoid a 64-bit shift-right since we only + * need the upper 32 bits of the result and the shift value is > 32. + */ + const uint32 bits0Hi = (uint32) (bits0 >> 32); + uint32 bits1Lo = (uint32) (bits1); + uint32 bits1Hi = (uint32) (bits1 >> 32); + + bits1Lo += bits0Hi; + bits1Hi += (bits1Lo < bits0Hi); + + const int32 s = shift - 32; + + return (bits1Hi << (32 - s)) | (bits1Lo >> s); + +#else /* RYU_32_BIT_PLATFORM */ + + const uint64 sum = (bits0 >> 32) + bits1; + const uint64 shiftedSum = sum >> (shift - 32); + + Assert(shiftedSum <= PG_UINT32_MAX); + return (uint32) shiftedSum; + +#endif /* RYU_32_BIT_PLATFORM */ +} + +static inline uint32 +mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j) +{ + return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j); +} + +static inline uint32 +mulPow5divPow2(const uint32 m, const uint32 i, const int32 j) +{ + return mulShift(m, FLOAT_POW5_SPLIT[i], j); +} + +static inline uint32 +decimalLength(const uint32 v) +{ + /* Function precondition: v is not a 10-digit number. */ + /* (9 digits are sufficient for round-tripping.) */ + Assert(v < 1000000000); + if (v >= 100000000) + { + return 9; + } + if (v >= 10000000) + { + return 8; + } + if (v >= 1000000) + { + return 7; + } + if (v >= 100000) + { + return 6; + } + if (v >= 10000) + { + return 5; + } + if (v >= 1000) + { + return 4; + } + if (v >= 100) + { + return 3; + } + if (v >= 10) + { + return 2; + } + return 1; +} + +/* A floating decimal representing m * 10^e. */ +typedef struct floating_decimal_32 +{ + uint32 mantissa; + int32 exponent; +} floating_decimal_32; + +static inline floating_decimal_32 +f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent) +{ + int32 e2; + uint32 m2; + + if (ieeeExponent == 0) + { + /* We subtract 2 so that the bounds computation has 2 additional bits. */ + e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = ieeeMantissa; + } + else + { + e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; + m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; + } + +#if STRICTLY_SHORTEST + const bool even = (m2 & 1) == 0; + const bool acceptBounds = even; +#else + const bool acceptBounds = false; +#endif + + /* Step 2: Determine the interval of legal decimal representations. */ + const uint32 mv = 4 * m2; + const uint32 mp = 4 * m2 + 2; + + /* Implicit bool -> int conversion. True is 1, false is 0. */ + const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; + const uint32 mm = 4 * m2 - 1 - mmShift; + + /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */ + uint32 vr, + vp, + vm; + int32 e10; + bool vmIsTrailingZeros = false; + bool vrIsTrailingZeros = false; + uint8 lastRemovedDigit = 0; + + if (e2 >= 0) + { + const uint32 q = log10Pow2(e2); + + e10 = q; + + const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1; + const int32 i = -e2 + q + k; + + vr = mulPow5InvDivPow2(mv, q, i); + vp = mulPow5InvDivPow2(mp, q, i); + vm = mulPow5InvDivPow2(mm, q, i); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) + { + /* + * We need to know one removed digit even if we are not going to + * loop below. We could use q = X - 1 above, except that would + * require 33 bits for the result, and we've found that 32-bit + * arithmetic is faster even on 64-bit machines. + */ + const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1; + + lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10); + } + if (q <= 9) + { + /* + * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 + * seems to be safe as well. + * + * Only one of mp, mv, and mm can be a multiple of 5, if any. + */ + if (mv % 5 == 0) + { + vrIsTrailingZeros = multipleOfPowerOf5(mv, q); + } + else if (acceptBounds) + { + vmIsTrailingZeros = multipleOfPowerOf5(mm, q); + } + else + { + vp -= multipleOfPowerOf5(mp, q); + } + } + } + else + { + const uint32 q = log10Pow5(-e2); + + e10 = q + e2; + + const int32 i = -e2 - q; + const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT; + int32 j = q - k; + + vr = mulPow5divPow2(mv, i, j); + vp = mulPow5divPow2(mp, i, j); + vm = mulPow5divPow2(mm, i, j); + + if (q != 0 && (vp - 1) / 10 <= vm / 10) + { + j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); + lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10); + } + if (q <= 1) + { + /* + * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q + * trailing 0 bits. + */ + /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ + vrIsTrailingZeros = true; + if (acceptBounds) + { + /* + * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff + * mmShift == 1. + */ + vmIsTrailingZeros = mmShift == 1; + } + else + { + /* + * mp = mv + 2, so it always has at least one trailing 0 bit. + */ + --vp; + } + } + else if (q < 31) + { + /* TODO(ulfjack):Use a tighter bound here. */ + vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); + } + } + + /* + * Step 4: Find the shortest decimal representation in the interval of + * legal representations. + */ + uint32 removed = 0; + uint32 output; + + if (vmIsTrailingZeros || vrIsTrailingZeros) + { + /* General case, which happens rarely (~4.0%). */ + while (vp / 10 > vm / 10) + { + vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + if (vmIsTrailingZeros) + { + while (vm % 10 == 0) + { + vrIsTrailingZeros &= lastRemovedDigit == 0; + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + } + + if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) + { + /* Round even if the exact number is .....50..0. */ + lastRemovedDigit = 4; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); + } + else + { + /* + * Specialized for the common case (~96.0%). Percentages below are + * relative to this. + * + * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2: + * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% + */ + while (vp / 10 > vm / 10) + { + lastRemovedDigit = (uint8) (vr % 10); + vr /= 10; + vp /= 10; + vm /= 10; + ++removed; + } + + /* + * We need to take vr + 1 if vr is outside bounds or we need to round + * up. + */ + output = vr + (vr == vm || lastRemovedDigit >= 5); + } + + const int32 exp = e10 + removed; + + floating_decimal_32 fd; + + fd.exponent = exp; + fd.mantissa = output; + return fd; +} + +static inline int +to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + int32 exp = v.exponent; + + /*---- + * On entry, mantissa * 10^exp is the result to be output. + * Caller has already done the - sign if needed. + * + * We want to insert the point somewhere depending on the output length + * and exponent, which might mean adding zeros: + * + * exp | format + * 1+ | ddddddddd000000 + * 0 | ddddddddd + * -1 .. -len+1 | dddddddd.d to d.ddddddddd + * -len ... | 0.ddddddddd to 0.000dddddd + */ + uint32 i = 0; + int32 nexp = exp + olength; + + if (nexp <= 0) + { + /* -nexp is number of 0s to add after '.' */ + Assert(nexp >= -3); + /* 0.000ddddd */ + index = 2 - nexp; + /* copy 8 bytes rather than 5 to let compiler optimize */ + memcpy(result, "0.000000", 8); + } + else if (exp < 0) + { + /* + * dddd.dddd; leave space at the start and move the '.' in after + */ + index = 1; + } + else + { + /* + * We can save some code later by pre-filling with zeros. We know that + * there can be no more than 6 output digits in this form, otherwise + * we would not choose fixed-point output. memset 8 rather than 6 + * bytes to let the compiler optimize it. + */ + Assert(exp < 6 && exp + olength <= 6); + memset(result, '0', 8); + } + + while (output >= 10000) + { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) + { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) + { + const uint32 c = output << 1; + + memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); + } + else + { + result[index] = (char) ('0' + output); + } + + if (index == 1) + { + /* + * nexp is 1..6 here, representing the number of digits before the + * point. A value of 7+ is not possible because we switch to + * scientific notation when the display exponent reaches 6. + */ + Assert(nexp < 7); + /* gcc only seems to want to optimize memmove for small 2^n */ + if (nexp & 4) + { + memmove(result + index - 1, result + index, 4); + index += 4; + } + if (nexp & 2) + { + memmove(result + index - 1, result + index, 2); + index += 2; + } + if (nexp & 1) + { + result[index - 1] = result[index]; + } + result[nexp] = '.'; + index = olength + 1; + } + else if (exp >= 0) + { + /* we supplied the trailing zeros earlier, now just set the length. */ + index = olength + exp; + } + else + { + index = olength + (2 - nexp); + } + + return index; +} + +static inline int +to_chars(const floating_decimal_32 v, const bool sign, char *const result) +{ + /* Step 5: Print the decimal representation. */ + int index = 0; + + uint32 output = v.mantissa; + uint32 olength = decimalLength(output); + int32 exp = v.exponent + olength - 1; + + if (sign) + result[index++] = '-'; + + /* + * The thresholds for fixed-point output are chosen to match printf + * defaults. Beware that both the code of to_chars_f and the value of + * FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. + */ + if (exp >= -4 && exp < 6) + return to_chars_f(v, olength, result + index) + sign; + + /* + * If v.exponent is exactly 0, we might have reached here via the small + * integer fast path, in which case v.mantissa might contain trailing + * (decimal) zeros. For scientific notation we need to move these zeros + * into the exponent. (For fixed point this doesn't matter, which is why + * we do this here rather than above.) + * + * Since we already calculated the display exponent (exp) above based on + * the old decimal length, that value does not change here. Instead, we + * just reduce the display length for each digit removed. + * + * If we didn't get here via the fast path, the raw exponent will not + * usually be 0, and there will be no trailing zeros, so we pay no more + * than one div10/multiply extra cost. We claw back half of that by + * checking for divisibility by 2 before dividing by 10. + */ + if (v.exponent == 0) + { + while ((output & 1) == 0) + { + const uint32 q = output / 10; + const uint32 r = output - 10 * q; + + if (r != 0) + break; + output = q; + --olength; + } + } + + /*---- + * Print the decimal digits. + * The following code is equivalent to: + * + * for (uint32 i = 0; i < olength - 1; ++i) { + * const uint32 c = output % 10; output /= 10; + * result[index + olength - i] = (char) ('0' + c); + * } + * result[index] = '0' + output % 10; + */ + uint32 i = 0; + + while (output >= 10000) + { + const uint32 c = output - 10000 * (output / 10000); + const uint32 c0 = (c % 100) << 1; + const uint32 c1 = (c / 100) << 1; + + output /= 10000; + + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); + memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); + i += 4; + } + if (output >= 100) + { + const uint32 c = (output % 100) << 1; + + output /= 100; + memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); + i += 2; + } + if (output >= 10) + { + const uint32 c = output << 1; + + /* + * We can't use memcpy here: the decimal dot goes between these two + * digits. + */ + result[index + olength - i] = DIGIT_TABLE[c + 1]; + result[index] = DIGIT_TABLE[c]; + } + else + { + result[index] = (char) ('0' + output); + } + + /* Print decimal point if needed. */ + if (olength > 1) + { + result[index + 1] = '.'; + index += olength + 1; + } + else + { + ++index; + } + + /* Print the exponent. */ + result[index++] = 'e'; + if (exp < 0) + { + result[index++] = '-'; + exp = -exp; + } + else + result[index++] = '+'; + + memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); + index += 2; + + return index; +} + +static inline bool +f2d_small_int(const uint32 ieeeMantissa, + const uint32 ieeeExponent, + floating_decimal_32 *v) +{ + const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS; + + /* + * Avoid using multiple "return false;" here since it tends to provoke the + * compiler into inlining multiple copies of f2d, which is undesirable. + */ + + if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0) + { + /*---- + * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23: + * 1 <= f = m2 / 2^-e2 < 2^24. + * + * Test if the lower -e2 bits of the significand are 0, i.e. whether + * the fraction is 0. We can use ieeeMantissa here, since the implied + * 1 bit can never be tested by this; the implied 1 can only be part + * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already + * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24) + */ + const uint32 mask = (1U << -e2) - 1; + const uint32 fraction = ieeeMantissa & mask; + + if (fraction == 0) + { + /*---- + * f is an integer in the range [1, 2^24). + * Note: mantissa might contain trailing (decimal) 0's. + * Note: since 2^24 < 10^9, there is no need to adjust + * decimalLength(). + */ + const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa; + + v->mantissa = m2 >> -e2; + v->exponent = 0; + return true; + } + } + + return false; +} + +/* + * Store the shortest decimal representation of the given float as an + * UNTERMINATED string in the caller's supplied buffer (which must be at least + * FLOAT_SHORTEST_DECIMAL_LEN-1 bytes long). + * + * Returns the number of bytes stored. + */ +int +float_to_shortest_decimal_bufn(float f, char *result) +{ + /* + * Step 1: Decode the floating-point number, and unify normalized and + * subnormal cases. + */ + const uint32 bits = float_to_bits(f); + + /* Decode bits into sign, mantissa, and exponent. */ + const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; + const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); + const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); + + /* Case distinction; exit early for the easy cases. */ + if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) + { + return copy_special_str(result, ieeeSign, (ieeeExponent != 0), (ieeeMantissa != 0)); + } + + floating_decimal_32 v; + const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); + + if (!isSmallInt) + { + v = f2d(ieeeMantissa, ieeeExponent); + } + + return to_chars(v, ieeeSign, result); +} + +/* + * Store the shortest decimal representation of the given float as a + * null-terminated string in the caller's supplied buffer (which must be at + * least FLOAT_SHORTEST_DECIMAL_LEN bytes long). + * + * Returns the string length. + */ +int +float_to_shortest_decimal_buf(float f, char *result) +{ + const int index = float_to_shortest_decimal_bufn(f, result); + + /* Terminate the string. */ + Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); + result[index] = '\0'; + return index; +} + +/* + * Return the shortest decimal representation as a null-terminated palloc'd + * string (outside the backend, uses malloc() instead). + * + * Caller is responsible for freeing the result. + */ +char * +float_to_shortest_decimal(float f) +{ + char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN); + + float_to_shortest_decimal_buf(f, result); + return result; +} diff --git a/src/common/fe_memutils.c b/src/common/fe_memutils.c index 2538661e19f..ce99b4f4da1 100644 --- a/src/common/fe_memutils.c +++ b/src/common/fe_memutils.c @@ -3,7 +3,7 @@ * fe_memutils.c * memory management support for frontend code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/common/file_perm.c b/src/common/file_perm.c index f2c8f846093..ff5fb13feb0 100644 --- a/src/common/file_perm.c +++ b/src/common/file_perm.c @@ -3,16 +3,15 @@ * File and directory permission routines * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/include/common/file_perm.c + * src/common/file_perm.c * *------------------------------------------------------------------------- */ -#include - #include "c.h" + #include "common/file_perm.h" /* Modes for creating directories and files in the data directory */ diff --git a/src/common/file_utils.c b/src/common/file_utils.c index 48876061c38..8b9ebcb314f 100644 --- a/src/common/file_utils.c +++ b/src/common/file_utils.c @@ -5,7 +5,7 @@ * Assorted utility functions to work on files. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/common/file_utils.c @@ -20,6 +20,7 @@ #include #include "common/file_utils.h" +#include "common/logging.h" /* Define PG_FLUSH_DATA_WORKS if we have an implementation for pg_flush_data */ @@ -35,12 +36,11 @@ #define MINIMUM_VERSION_FOR_PG_WAL 100000 #ifdef PG_FLUSH_DATA_WORKS -static int pre_sync_fname(const char *fname, bool isdir, - const char *progname); +static int pre_sync_fname(const char *fname, bool isdir); #endif static void walkdir(const char *path, - int (*action) (const char *fname, bool isdir, const char *progname), - bool process_symlinks, const char *progname); + int (*action) (const char *fname, bool isdir), + bool process_symlinks); /* * Issue fsync recursively on PGDATA and all its contents. @@ -56,7 +56,6 @@ static void walkdir(const char *path, */ void fsync_pgdata(const char *pg_data, - const char *progname, int serverVersion) { bool xlog_is_symlink; @@ -79,8 +78,7 @@ fsync_pgdata(const char *pg_data, struct stat st; if (lstat(pg_wal, &st) < 0) - fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), - progname, pg_wal, strerror(errno)); + pg_log_error("could not stat file \"%s\": %m", pg_wal); else if (S_ISLNK(st.st_mode)) xlog_is_symlink = true; } @@ -94,10 +92,10 @@ fsync_pgdata(const char *pg_data, * directory and its contents. */ #ifdef PG_FLUSH_DATA_WORKS - walkdir(pg_data, pre_sync_fname, false, progname); + walkdir(pg_data, pre_sync_fname, false); if (xlog_is_symlink) - walkdir(pg_wal, pre_sync_fname, false, progname); - walkdir(pg_tblspc, pre_sync_fname, true, progname); + walkdir(pg_wal, pre_sync_fname, false); + walkdir(pg_tblspc, pre_sync_fname, true); #endif /* @@ -109,10 +107,10 @@ fsync_pgdata(const char *pg_data, * in pg_tblspc, they'll get fsync'd twice. That's not an expected case * so we don't worry about optimizing it. */ - walkdir(pg_data, fsync_fname, false, progname); + walkdir(pg_data, fsync_fname, false); if (xlog_is_symlink) - walkdir(pg_wal, fsync_fname, false, progname); - walkdir(pg_tblspc, fsync_fname, true, progname); + walkdir(pg_wal, fsync_fname, false); + walkdir(pg_tblspc, fsync_fname, true); } /* @@ -121,17 +119,17 @@ fsync_pgdata(const char *pg_data, * This is a convenient wrapper on top of walkdir(). */ void -fsync_dir_recurse(const char *dir, const char *progname) +fsync_dir_recurse(const char *dir) { /* * If possible, hint to the kernel that we're soon going to fsync the data * directory and its contents. */ #ifdef PG_FLUSH_DATA_WORKS - walkdir(dir, pre_sync_fname, false, progname); + walkdir(dir, pre_sync_fname, false); #endif - walkdir(dir, fsync_fname, false, progname); + walkdir(dir, fsync_fname, false); } /* @@ -150,8 +148,8 @@ fsync_dir_recurse(const char *dir, const char *progname) */ static void walkdir(const char *path, - int (*action) (const char *fname, bool isdir, const char *progname), - bool process_symlinks, const char *progname) + int (*action) (const char *fname, bool isdir), + bool process_symlinks) { DIR *dir; struct dirent *de; @@ -159,8 +157,7 @@ walkdir(const char *path, dir = opendir(path); if (dir == NULL) { - fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not open directory \"%s\": %m", path); return; } @@ -183,20 +180,18 @@ walkdir(const char *path, if (sret < 0) { - fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), - progname, subpath, strerror(errno)); + pg_log_error("could not stat file \"%s\": %m", subpath); continue; } if (S_ISREG(fst.st_mode)) - (*action) (subpath, false, progname); + (*action) (subpath, false); else if (S_ISDIR(fst.st_mode)) - walkdir(subpath, action, false, progname); + walkdir(subpath, action, false); } if (errno) - fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"), - progname, path, strerror(errno)); + pg_log_error("could not read directory \"%s\": %m", path); (void) closedir(dir); @@ -206,7 +201,7 @@ walkdir(const char *path, * synced. Recent versions of ext4 have made the window much wider but * it's been an issue for ext3 and other filesystems in the past. */ - (*action) (path, true, progname); + (*action) (path, true); } /* @@ -218,18 +213,17 @@ walkdir(const char *path, #ifdef PG_FLUSH_DATA_WORKS static int -pre_sync_fname(const char *fname, bool isdir, const char *progname) +pre_sync_fname(const char *fname, bool isdir) { int fd; - fd = open(fname, O_RDONLY | PG_BINARY); + fd = open(fname, O_RDONLY | PG_BINARY, 0); if (fd < 0) { if (errno == EACCES || (isdir && errno == EISDIR)) return 0; - fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), - progname, fname, strerror(errno)); + pg_log_error("could not open file \"%s\": %m", fname); return -1; } @@ -260,7 +254,7 @@ pre_sync_fname(const char *fname, bool isdir, const char *progname) * other errors non-fatally. */ int -fsync_fname(const char *fname, bool isdir, const char *progname) +fsync_fname(const char *fname, bool isdir) { int fd; int flags; @@ -283,13 +277,12 @@ fsync_fname(const char *fname, bool isdir, const char *progname) * unsupported operations, e.g. opening a directory under Windows), and * logging others. */ - fd = open(fname, flags); + fd = open(fname, flags, 0); if (fd < 0) { if (errno == EACCES || (isdir && errno == EISDIR)) return 0; - fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), - progname, fname, strerror(errno)); + pg_log_error("could not open file \"%s\": %m", fname); return -1; } @@ -299,10 +292,9 @@ fsync_fname(const char *fname, bool isdir, const char *progname) * Some OSes don't allow us to fsync directories at all, so we can ignore * those errors. Anything else needs to be reported. */ - if (returncode != 0 && !(isdir && errno == EBADF)) + if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL))) { - fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"), - progname, fname, strerror(errno)); + pg_log_error("could not fsync file \"%s\": %m", fname); (void) close(fd); return -1; } @@ -318,7 +310,7 @@ fsync_fname(const char *fname, bool isdir, const char *progname) * an OS crash or power failure. */ int -fsync_parent_path(const char *fname, const char *progname) +fsync_parent_path(const char *fname) { char parentpath[MAXPGPATH]; @@ -333,7 +325,7 @@ fsync_parent_path(const char *fname, const char *progname) if (strlen(parentpath) == 0) strlcpy(parentpath, ".", MAXPGPATH); - if (fsync_fname(parentpath, true, progname) != 0) + if (fsync_fname(parentpath, true) != 0) return -1; return 0; @@ -345,7 +337,7 @@ fsync_parent_path(const char *fname, const char *progname) * Wrapper around rename, similar to the backend version. */ int -durable_rename(const char *oldfile, const char *newfile, const char *progname) +durable_rename(const char *oldfile, const char *newfile) { int fd; @@ -356,7 +348,7 @@ durable_rename(const char *oldfile, const char *newfile, const char *progname) * because it's then guaranteed that either source or target file exists * after a crash. */ - if (fsync_fname(oldfile, false, progname) != 0) + if (fsync_fname(oldfile, false) != 0) return -1; fd = open(newfile, PG_BINARY | O_RDWR, 0); @@ -364,8 +356,7 @@ durable_rename(const char *oldfile, const char *newfile, const char *progname) { if (errno != ENOENT) { - fprintf(stderr, _("%s: could not open file \"%s\": %s\n"), - progname, newfile, strerror(errno)); + pg_log_error("could not open file \"%s\": %m", newfile); return -1; } } @@ -373,8 +364,7 @@ durable_rename(const char *oldfile, const char *newfile, const char *progname) { if (fsync(fd) != 0) { - fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"), - progname, newfile, strerror(errno)); + pg_log_error("could not fsync file \"%s\": %m", newfile); close(fd); return -1; } @@ -384,8 +374,8 @@ durable_rename(const char *oldfile, const char *newfile, const char *progname) /* Time to do the real deal... */ if (rename(oldfile, newfile) != 0) { - fprintf(stderr, _("%s: could not rename file \"%s\" to \"%s\": %s\n"), - progname, oldfile, newfile, strerror(errno)); + pg_log_error("could not rename file \"%s\" to \"%s\": %m", + oldfile, newfile); return -1; } @@ -393,10 +383,10 @@ durable_rename(const char *oldfile, const char *newfile, const char *progname) * To guarantee renaming the file is persistent, fsync the file with its * new name, and its containing directory. */ - if (fsync_fname(newfile, false, progname) != 0) + if (fsync_fname(newfile, false) != 0) return -1; - if (fsync_parent_path(newfile, progname) != 0) + if (fsync_parent_path(newfile) != 0) return -1; return 0; diff --git a/src/common/ip.c b/src/common/ip.c index caca7be9e57..7897fdc9ffe 100644 --- a/src/common/ip.c +++ b/src/common/ip.c @@ -3,7 +3,7 @@ * ip.c * IPv6-aware network access. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -39,14 +39,14 @@ #ifdef HAVE_UNIX_SOCKETS -static int getaddrinfo_unix(const char *path, - const struct addrinfo *hintsp, - struct addrinfo **result); - -static int getnameinfo_unix(const struct sockaddr_un *sa, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); +static int getaddrinfo_unix(const char *path, + const struct addrinfo *hintsp, + struct addrinfo **result); + +static int getnameinfo_unix(const struct sockaddr_un *sa, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); #endif @@ -233,7 +233,7 @@ getnameinfo_unix(const struct sockaddr_un *sa, int salen, char *service, int servicelen, int flags) { - int ret = -1; + int ret; /* Invalid arguments. */ if (sa == NULL || sa->sun_family != AF_UNIX || @@ -243,14 +243,14 @@ getnameinfo_unix(const struct sockaddr_un *sa, int salen, if (node) { ret = snprintf(node, nodelen, "%s", "[local]"); - if (ret == -1 || ret > nodelen) + if (ret < 0 || ret >= nodelen) return EAI_MEMORY; } if (service) { ret = snprintf(service, servicelen, "%s", sa->sun_path); - if (ret == -1 || ret > servicelen) + if (ret < 0 || ret >= servicelen) return EAI_MEMORY; } diff --git a/src/common/keywords.c b/src/common/keywords.c index 0c0c794c686..84f779feb91 100644 --- a/src/common/keywords.c +++ b/src/common/keywords.c @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * keywords.c - * lexical token lookup for key words in PostgreSQL + * PostgreSQL's list of SQL keywords * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -13,102 +13,21 @@ * *------------------------------------------------------------------------- */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif +#include "c.h" -#ifndef FRONTEND - -#include "parser/gramparse.h" +#include "common/keywords.h" -#define PG_KEYWORD(a,b,c) {a,b,c}, -#else +/* ScanKeywordList lookup data for SQL keywords */ -#include "common/keywords.h" - -/* - * We don't need the token number for frontend uses, so leave it out to avoid - * requiring backend headers that won't compile cleanly here. - */ -#define PG_KEYWORD(a,b,c) {a,0,c}, +#include "kwlist_d.h" -#endif /* FRONTEND */ +/* Keyword categories for SQL keywords */ +#define PG_KEYWORD(kwname, value, category) category, -const ScanKeyword ScanKeywords[] = { +const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS] = { #include "parser/kwlist.h" }; -const int NumScanKeywords = lengthof(ScanKeywords); - - -/* - * ScanKeywordLookup - see if a given word is a keyword - * - * The table to be searched is passed explicitly, so that this can be used - * to search keyword lists other than the standard list appearing above. - * - * Returns a pointer to the ScanKeyword table entry, or NULL if no match. - * - * The match is done case-insensitively. Note that we deliberately use a - * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', - * even if we are in a locale where tolower() would produce more or different - * translations. This is to conform to the SQL99 spec, which says that - * keywords are to be matched in this way even though non-keyword identifiers - * receive a different case-normalization mapping. - */ -const ScanKeyword * -ScanKeywordLookup(const char *text, - const ScanKeyword *keywords, - int num_keywords) -{ - int len, - i; - char word[NAMEDATALEN]; - const ScanKeyword *low; - const ScanKeyword *high; - - len = strlen(text); - /* We assume all keywords are shorter than NAMEDATALEN. */ - if (len >= NAMEDATALEN) - return NULL; - - /* - * Apply an ASCII-only downcasing. We must not use tolower() since it may - * produce the wrong translation in some locales (eg, Turkish). - */ - for (i = 0; i < len; i++) - { - char ch = text[i]; - - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - word[i] = ch; - } - word[len] = '\0'; - - /* - * Now do a binary search using plain strcmp() comparison. - */ - low = keywords; - high = keywords + (num_keywords - 1); - while (low <= high) - { - const ScanKeyword *middle; - int difference; - - middle = low + (high - low) / 2; - difference = strcmp(middle->name, word); - if (difference == 0) - return middle; - else if (difference < 0) - low = middle + 1; - else - high = middle - 1; - } - - return NULL; -} +#undef PG_KEYWORD diff --git a/src/common/kwlookup.c b/src/common/kwlookup.c new file mode 100644 index 00000000000..6545480b5c7 --- /dev/null +++ b/src/common/kwlookup.c @@ -0,0 +1,85 @@ +/*------------------------------------------------------------------------- + * + * kwlookup.c + * Key word lookup for PostgreSQL + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/common/kwlookup.c + * + *------------------------------------------------------------------------- + */ +#include "c.h" + +#include "common/kwlookup.h" + + +/* + * ScanKeywordLookup - see if a given word is a keyword + * + * The list of keywords to be matched against is passed as a ScanKeywordList. + * + * Returns the keyword number (0..N-1) of the keyword, or -1 if no match. + * Callers typically use the keyword number to index into information + * arrays, but that is no concern of this code. + * + * The match is done case-insensitively. Note that we deliberately use a + * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', + * even if we are in a locale where tolower() would produce more or different + * translations. This is to conform to the SQL99 spec, which says that + * keywords are to be matched in this way even though non-keyword identifiers + * receive a different case-normalization mapping. + */ +int +ScanKeywordLookup(const char *str, + const ScanKeywordList *keywords) +{ + size_t len; + int h; + const char *kw; + + /* + * Reject immediately if too long to be any keyword. This saves useless + * hashing and downcasing work on long strings. + */ + len = strlen(str); + if (len > keywords->max_kw_len) + return -1; + + /* + * Compute the hash function. We assume it was generated to produce + * case-insensitive results. Since it's a perfect hash, we need only + * match to the specific keyword it identifies. + */ + h = keywords->hash(str, len); + + /* An out-of-range result implies no match */ + if (h < 0 || h >= keywords->num_keywords) + return -1; + + /* + * Compare character-by-character to see if we have a match, applying an + * ASCII-only downcasing to the input characters. We must not use + * tolower() since it may produce the wrong translation in some locales + * (eg, Turkish). + */ + kw = GetScanKeyword(h, keywords); + while (*str != '\0') + { + char ch = *str++; + + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + if (ch != *kw++) + return -1; + } + if (*kw != '\0') + return -1; + + /* Success! */ + return h; +} diff --git a/src/common/link-canary.c b/src/common/link-canary.c new file mode 100644 index 00000000000..9809a3b076c --- /dev/null +++ b/src/common/link-canary.c @@ -0,0 +1,36 @@ +/*------------------------------------------------------------------------- + * link-canary.c + * Detect whether src/common functions came from frontend or backend. + * + * Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/link-canary.c + * + *------------------------------------------------------------------------- + */ +#include "c.h" + +#include "common/link-canary.h" + +/* + * This function just reports whether this file was compiled for frontend + * or backend environment. We need this because in some systems, mainly + * ELF-based platforms, it is possible for a shlib (such as libpq) loaded + * into the backend to call a backend function named XYZ in preference to + * the shlib's own function XYZ. That's bad if the two functions don't + * act identically. This exact situation comes up for many functions in + * src/common and src/port, where the same function names exist in both + * libpq and the backend but they don't act quite identically. To verify + * that appropriate measures have been taken to prevent incorrect symbol + * resolution, libpq should test that this function returns true. + */ +bool +pg_link_canary_is_frontend(void) +{ +#ifdef FRONTEND + return true; +#else + return false; +#endif +} diff --git a/src/common/logging.c b/src/common/logging.c new file mode 100644 index 00000000000..895da7150e7 --- /dev/null +++ b/src/common/logging.c @@ -0,0 +1,237 @@ +/*------------------------------------------------------------------------- + * Logging framework for frontend programs + * + * Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * src/common/logging.c + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include + +#include "common/logging.h" + +enum pg_log_level __pg_log_level; + +static const char *progname; +static int log_flags; + +static void (*log_pre_callback) (void); +static void (*log_locus_callback) (const char **, uint64 *); + +static const char *sgr_error = NULL; +static const char *sgr_warning = NULL; +static const char *sgr_locus = NULL; + +#define SGR_ERROR_DEFAULT "01;31" +#define SGR_WARNING_DEFAULT "01;35" +#define SGR_LOCUS_DEFAULT "01" + +#define ANSI_ESCAPE_FMT "\x1b[%sm" +#define ANSI_ESCAPE_RESET "\x1b[0m" + +/* + * This should be called before any output happens. + */ +void +pg_logging_init(const char *argv0) +{ + const char *pg_color_env = getenv("PG_COLOR"); + bool log_color = false; + + /* usually the default, but not on Windows */ + setvbuf(stderr, NULL, _IONBF, 0); + + progname = get_progname(argv0); + __pg_log_level = PG_LOG_INFO; + + if (pg_color_env) + { + if (strcmp(pg_color_env, "always") == 0 || + (strcmp(pg_color_env, "auto") == 0 && isatty(fileno(stderr)))) + log_color = true; + } + + if (log_color) + { + const char *pg_colors_env = getenv("PG_COLORS"); + + if (pg_colors_env) + { + char *colors = strdup(pg_colors_env); + + if (colors) + { + for (char *token = strtok(colors, ":"); token; token = strtok(NULL, ":")) + { + char *e = strchr(token, '='); + + if (e) + { + char *name; + char *value; + + *e = '\0'; + name = token; + value = e + 1; + + if (strcmp(name, "error") == 0) + sgr_error = strdup(value); + if (strcmp(name, "warning") == 0) + sgr_warning = strdup(value); + if (strcmp(name, "locus") == 0) + sgr_locus = strdup(value); + } + } + + free(colors); + } + } + else + { + sgr_error = SGR_ERROR_DEFAULT; + sgr_warning = SGR_WARNING_DEFAULT; + sgr_locus = SGR_LOCUS_DEFAULT; + } + } +} + +void +pg_logging_config(int new_flags) +{ + log_flags = new_flags; +} + +void +pg_logging_set_level(enum pg_log_level new_level) +{ + __pg_log_level = new_level; +} + +void +pg_logging_set_pre_callback(void (*cb) (void)) +{ + log_pre_callback = cb; +} + +void +pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)) +{ + log_locus_callback = cb; +} + +void +pg_log_generic(enum pg_log_level level, const char *pg_restrict fmt,...) +{ + va_list ap; + + va_start(ap, fmt); + pg_log_generic_v(level, fmt, ap); + va_end(ap); +} + +void +pg_log_generic_v(enum pg_log_level level, const char *pg_restrict fmt, va_list ap) +{ + int save_errno = errno; + const char *filename = NULL; + uint64 lineno = 0; + va_list ap2; + size_t required_len; + char *buf; + + Assert(progname); + Assert(level); + Assert(fmt); + Assert(fmt[strlen(fmt) - 1] != '\n'); + + /* + * Flush stdout before output to stderr, to ensure sync even when stdout + * is buffered. + */ + fflush(stdout); + + if (log_pre_callback) + log_pre_callback(); + + if (log_locus_callback) + log_locus_callback(&filename, &lineno); + + fmt = _(fmt); + + if (!(log_flags & PG_LOG_FLAG_TERSE) || filename) + { + if (sgr_locus) + fprintf(stderr, ANSI_ESCAPE_FMT, sgr_locus); + if (!(log_flags & PG_LOG_FLAG_TERSE)) + fprintf(stderr, "%s:", progname); + if (filename) + { + fprintf(stderr, "%s:", filename); + if (lineno > 0) + fprintf(stderr, UINT64_FORMAT ":", lineno); + } + fprintf(stderr, " "); + if (sgr_locus) + fprintf(stderr, ANSI_ESCAPE_RESET); + } + + if (!(log_flags & PG_LOG_FLAG_TERSE)) + { + switch (level) + { + case PG_LOG_FATAL: + if (sgr_error) + fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error); + fprintf(stderr, _("fatal: ")); + if (sgr_error) + fprintf(stderr, ANSI_ESCAPE_RESET); + break; + case PG_LOG_ERROR: + if (sgr_error) + fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error); + fprintf(stderr, _("error: ")); + if (sgr_error) + fprintf(stderr, ANSI_ESCAPE_RESET); + break; + case PG_LOG_WARNING: + if (sgr_warning) + fprintf(stderr, ANSI_ESCAPE_FMT, sgr_warning); + fprintf(stderr, _("warning: ")); + if (sgr_warning) + fprintf(stderr, ANSI_ESCAPE_RESET); + break; + default: + break; + } + } + + errno = save_errno; + + va_copy(ap2, ap); + required_len = vsnprintf(NULL, 0, fmt, ap2) + 1; + va_end(ap2); + + buf = pg_malloc_extended(required_len, MCXT_ALLOC_NO_OOM); + + errno = save_errno; /* malloc might change errno */ + + if (!buf) + { + /* memory trouble, just print what we can and get out of here */ + vfprintf(stderr, fmt, ap); + return; + } + + vsnprintf(buf, required_len, fmt, ap); + + /* strip one newline, for PQerrorMessage() */ + if (required_len >= 2 && buf[required_len - 2] == '\n') + buf[required_len - 2] = '\0'; + + fprintf(stderr, "%s\n", buf); + + free(buf); +} diff --git a/src/common/md5.c b/src/common/md5.c index c3936618b66..55eaeed8286 100644 --- a/src/common/md5.c +++ b/src/common/md5.c @@ -10,7 +10,7 @@ * * Sverre H. Huseby * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -277,7 +277,7 @@ bytesToHex(uint8 b[16], char *s) * * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of * hexadecimal digits. an MD5 sum is 16 bytes long. - * each byte is represented by two heaxadecimal + * each byte is represented by two hexadecimal * characters. you thus need to provide an array * of 33 characters, including the trailing '\0'. * diff --git a/src/common/pg_lzcompress.c b/src/common/pg_lzcompress.c index a2f87cff8b5..3adad62d9a4 100644 --- a/src/common/pg_lzcompress.c +++ b/src/common/pg_lzcompress.c @@ -29,7 +29,7 @@ * * int32 * pglz_decompress(const char *source, int32 slen, char *dest, - * int32 rawsize) + * int32 rawsize, bool check_complete) * * source is the compressed input. * @@ -44,6 +44,12 @@ * * rawsize is the length of the uncompressed data. * + * check_complete is a flag to let us know if -1 should be + * returned in cases where we don't reach the end of the + * source or dest buffers, or not. This should be false + * if the caller is asking for only a partial result and + * true otherwise. + * * The return value is the number of bytes written in the * buffer dest, or -1 if decompression fails. * @@ -159,14 +165,14 @@ * scanned for the history add's, otherwise a literal character * is omitted and only his history entry added. * - * Acknowledgements: + * Acknowledgments: * * Many thanks to Adisak Pochanayon, who's article about SLZ * inspired me to write the PostgreSQL compression this way. * * Jan Wieck * - * Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Copyright (c) 1999-2019, PostgreSQL Global Development Group * * src/common/pg_lzcompress.c * ---------- @@ -674,13 +680,14 @@ pglz_compress(const char *source, int32 slen, char *dest, * pglz_decompress - * * Decompresses source into dest. Returns the number of bytes - * decompressed in the destination buffer, or -1 if decompression - * fails. + * decompressed in the destination buffer, and *optionally* + * checks that both the source and dest buffers have been + * fully read and written to, respectively. * ---------- */ int32 pglz_decompress(const char *source, int32 slen, char *dest, - int32 rawsize) + int32 rawsize, bool check_complete) { const unsigned char *sp; const unsigned char *srcend; @@ -701,8 +708,9 @@ pglz_decompress(const char *source, int32 slen, char *dest, unsigned char ctrl = *sp++; int ctrlc; - for (ctrlc = 0; ctrlc < 8 && sp < srcend; ctrlc++) + for (ctrlc = 0; ctrlc < 8 && sp < srcend && dp < destend; ctrlc++) { + if (ctrl & 1) { /* @@ -721,25 +729,13 @@ pglz_decompress(const char *source, int32 slen, char *dest, if (len == 18) len += *sp++; - /* - * Check for output buffer overrun, to ensure we don't clobber - * memory in case of corrupt input. Note: we must advance dp - * here to ensure the error is detected below the loop. We - * don't simply put the elog inside the loop since that will - * probably interfere with optimization. - */ - if (dp + len > destend) - { - dp += len; - break; - } - /* * Now we copy the bytes specified by the tag from OUTPUT to * OUTPUT. It is dangerous and platform dependent to use * memcpy() here, because the copied areas could overlap * extremely! */ + len = Min(len, destend - dp); while (len--) { *dp = dp[-off]; @@ -752,9 +748,6 @@ pglz_decompress(const char *source, int32 slen, char *dest, * An unset control bit means LITERAL BYTE. So we just copy * one from INPUT to OUTPUT. */ - if (dp >= destend) /* check for buffer overrun */ - break; /* do not clobber memory */ - *dp++ = *sp++; } @@ -766,13 +759,52 @@ pglz_decompress(const char *source, int32 slen, char *dest, } /* - * Check we decompressed the right amount. + * Check we decompressed the right amount. If we are slicing, then we + * won't necessarily be at the end of the source or dest buffers when we + * hit a stop, so we don't test them. */ - if (dp != destend || sp != srcend) + if (check_complete && (dp != destend || sp != srcend)) return -1; /* * That's it. */ - return rawsize; + return (char *) dp - dest; +} + + +/* ---------- + * pglz_max_compressed_size - + * + * Calculate the maximum compressed size for a given amount of raw data. + * Return the maximum size, or total compressed size if maximum size is + * larger than total compressed size. + * + * We can't use PGLZ_MAX_OUTPUT for this purpose, because that's used to size + * the compression buffer (and abort the compression). It does not really say + * what's the maximum compressed size for an input of a given length, and it + * may happen that while the whole value is compressible (and thus fits into + * PGLZ_MAX_OUTPUT nicely), the prefix is not compressible at all. + * ---------- + */ +int32 +pglz_maximum_compressed_size(int32 rawsize, int32 total_compressed_size) +{ + int32 compressed_size; + + /* + * pglz uses one control bit per byte, so we need (rawsize * 9) bits. We + * care about bytes though, so we add 7 to make sure we include the last + * incomplete byte (integer division rounds down). + * + * XXX Use int64 to prevent overflow during calculation. + */ + compressed_size = (int32) ((int64) rawsize * 9 + 7) / 8; + + /* + * Maximum compressed size can't be larger than total compressed size. + */ + compressed_size = Min(compressed_size, total_compressed_size); + + return compressed_size; } diff --git a/src/common/pgfnames.c b/src/common/pgfnames.c index ec50a36db7c..c99c4822015 100644 --- a/src/common/pgfnames.c +++ b/src/common/pgfnames.c @@ -3,7 +3,7 @@ * pgfnames.c * directory handling functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,6 +20,12 @@ #include +#ifndef FRONTEND +#define pg_log_warning(...) elog(WARNING, __VA_ARGS__) +#else +#include "common/logging.h" +#endif + /* * pgfnames * @@ -39,12 +45,7 @@ pgfnames(const char *path) dir = opendir(path); if (dir == NULL) { -#ifndef FRONTEND - elog(WARNING, "could not open directory \"%s\": %m", path); -#else - fprintf(stderr, _("could not open directory \"%s\": %s\n"), - path, strerror(errno)); -#endif + pg_log_warning("could not open directory \"%s\": %m", path); return NULL; } @@ -65,26 +66,12 @@ pgfnames(const char *path) } if (errno) - { -#ifndef FRONTEND - elog(WARNING, "could not read directory \"%s\": %m", path); -#else - fprintf(stderr, _("could not read directory \"%s\": %s\n"), - path, strerror(errno)); -#endif - } + pg_log_warning("could not read directory \"%s\": %m", path); filenames[numnames] = NULL; if (closedir(dir)) - { -#ifndef FRONTEND - elog(WARNING, "could not close directory \"%s\": %m", path); -#else - fprintf(stderr, _("could not close directory \"%s\": %s\n"), - path, strerror(errno)); -#endif - } + pg_log_warning("could not close directory \"%s\": %m", path); return filenames; } diff --git a/src/common/psprintf.c b/src/common/psprintf.c index b974a99be12..e8a7e44554c 100644 --- a/src/common/psprintf.c +++ b/src/common/psprintf.c @@ -4,7 +4,7 @@ * sprintf into an allocated-on-demand buffer * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -45,6 +45,7 @@ char * psprintf(const char *fmt,...) { + int save_errno = errno; size_t len = 128; /* initial assumption about buffer size */ for (;;) @@ -60,6 +61,7 @@ psprintf(const char *fmt,...) result = (char *) palloc(len); /* Try to format the data. */ + errno = save_errno; va_start(args, fmt); newlen = pvsnprintf(result, len, fmt, args); va_end(args); @@ -77,7 +79,7 @@ psprintf(const char *fmt,...) * pvsnprintf * * Attempt to format text data under the control of fmt (an sprintf-style - * format string) and insert it into buf (which has length len, len > 0). + * format string) and insert it into buf (which has length len). * * If successful, return the number of bytes emitted, not counting the * trailing zero byte. This will always be strictly less than len. @@ -89,14 +91,14 @@ psprintf(const char *fmt,...) * Other error cases do not return, but exit via elog(ERROR) or exit(). * Hence, this shouldn't be used inside libpq. * - * This function exists mainly to centralize our workarounds for - * non-C99-compliant vsnprintf implementations. Generally, any call that - * pays any attention to the return value should go through here rather - * than calling snprintf or vsnprintf directly. + * Caution: callers must be sure to preserve their entry-time errno + * when looping, in case the fmt contains "%m". * * Note that the semantics of the return value are not exactly C99's. * First, we don't promise that the estimated buffer size is exactly right; * callers must be prepared to loop multiple times to get the right size. + * (Given a C99-compliant vsnprintf, that won't happen, but it is rumored + * that some implementations don't always return the same value ...) * Second, we return the recommended buffer size, not one less than that; * this lets overflow concerns be handled here rather than in the callers. */ @@ -105,73 +107,35 @@ pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) { int nprinted; - Assert(len > 0); - - errno = 0; - - /* - * Assert check here is to catch buggy vsnprintf that overruns the - * specified buffer length. Solaris 7 in 64-bit mode is an example of a - * platform with such a bug. - */ -#ifdef USE_ASSERT_CHECKING - buf[len - 1] = '\0'; -#endif - nprinted = vsnprintf(buf, len, fmt, args); - Assert(buf[len - 1] == '\0'); - - /* - * If vsnprintf reports an error other than ENOMEM, fail. The possible - * causes of this are not user-facing errors, so elog should be enough. - */ - if (nprinted < 0 && errno != 0 && errno != ENOMEM) + /* We assume failure means the fmt is bogus, hence hard failure is OK */ + if (unlikely(nprinted < 0)) { #ifndef FRONTEND - elog(ERROR, "vsnprintf failed: %m"); + elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt); #else - fprintf(stderr, "vsnprintf failed: %s\n", strerror(errno)); + fprintf(stderr, "vsnprintf failed: %s with format string \"%s\"\n", + strerror(errno), fmt); exit(EXIT_FAILURE); #endif } - /* - * Note: some versions of vsnprintf return the number of chars actually - * stored, not the total space needed as C99 specifies. And at least one - * returns -1 on failure. Be conservative about believing whether the - * print worked. - */ - if (nprinted >= 0 && (size_t) nprinted < len - 1) + if ((size_t) nprinted < len) { /* Success. Note nprinted does not include trailing null. */ return (size_t) nprinted; } - if (nprinted >= 0 && (size_t) nprinted > len) - { - /* - * This appears to be a C99-compliant vsnprintf, so believe its - * estimate of the required space. (If it's wrong, the logic will - * still work, but we may loop multiple times.) Note that the space - * needed should be only nprinted+1 bytes, but we'd better allocate - * one more than that so that the test above will succeed next time. - * - * In the corner case where the required space just barely overflows, - * fall through so that we'll error out below (possibly after - * looping). - */ - if ((size_t) nprinted <= MaxAllocSize - 2) - return nprinted + 2; - } - /* - * Buffer overrun, and we don't know how much space is needed. Estimate - * twice the previous buffer size, but not more than MaxAllocSize; if we - * are already at MaxAllocSize, choke. Note we use this palloc-oriented - * overflow limit even when in frontend. + * We assume a C99-compliant vsnprintf, so believe its estimate of the + * required space, and add one for the trailing null. (If it's wrong, the + * logic will still work, but we may loop multiple times.) + * + * Choke if the required space would exceed MaxAllocSize. Note we use + * this palloc-oriented overflow limit even when in frontend. */ - if (len >= MaxAllocSize) + if (unlikely((size_t) nprinted > MaxAllocSize - 1)) { #ifndef FRONTEND ereport(ERROR, @@ -183,8 +147,5 @@ pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) #endif } - if (len >= MaxAllocSize / 2) - return MaxAllocSize; - - return len * 2; + return nprinted + 1; } diff --git a/src/common/relpath.c b/src/common/relpath.c index e8170ed712e..62b9553f1bc 100644 --- a/src/common/relpath.c +++ b/src/common/relpath.c @@ -4,7 +4,7 @@ * * This module also contains some logic associated with fork names. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/common/restricted_token.c b/src/common/restricted_token.c index 8c5583da7a2..dd077a6e0e2 100644 --- a/src/common/restricted_token.c +++ b/src/common/restricted_token.c @@ -4,7 +4,7 @@ * helper routine to ensure restricted token on Windows * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -20,6 +20,7 @@ #include "postgres_fe.h" +#include "common/logging.h" #include "common/restricted_token.h" #ifdef WIN32 @@ -43,7 +44,7 @@ typedef BOOL (WINAPI * __CreateRestrictedToken) (HANDLE, DWORD, DWORD, PSID_AND_ * NOT execute anything. */ HANDLE -CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char *progname) +CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo) { BOOL b; STARTUPINFO si; @@ -65,7 +66,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char if (_CreateRestrictedToken == NULL) { - fprintf(stderr, _("%s: WARNING: cannot create restricted tokens on this platform\n"), progname); + pg_log_warning("cannot create restricted tokens on this platform"); if (Advapi32Handle != NULL) FreeLibrary(Advapi32Handle); return 0; @@ -74,7 +75,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char /* Open the current token to use as a base for the restricted one */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) { - fprintf(stderr, _("%s: could not open process token: error code %lu\n"), progname, GetLastError()); + pg_log_error("could not open process token: error code %lu", GetLastError()); return 0; } @@ -87,8 +88,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, 0, &dropSids[1].Sid)) { - fprintf(stderr, _("%s: could not allocate SIDs: error code %lu\n"), - progname, GetLastError()); + pg_log_error("could not allocate SIDs: error code %lu", GetLastError()); return 0; } @@ -107,8 +107,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char if (!b) { - fprintf(stderr, _("%s: could not create restricted token: error code %lu\n"), - progname, GetLastError()); + pg_log_error("could not create restricted token: error code %lu", GetLastError()); return 0; } @@ -129,7 +128,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char processInfo)) { - fprintf(stderr, _("%s: could not start process for command \"%s\": error code %lu\n"), progname, cmd, GetLastError()); + pg_log_error("could not start process for command \"%s\": error code %lu", cmd, GetLastError()); return 0; } @@ -143,7 +142,7 @@ CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char * On other platforms do nothing. */ void -get_restricted_token(const char *progname) +get_restricted_token(void) { #ifdef WIN32 HANDLE restrictedToken; @@ -165,9 +164,9 @@ get_restricted_token(const char *progname) putenv("PG_RESTRICT_EXEC=1"); - if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi, progname)) == 0) + if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi)) == 0) { - fprintf(stderr, _("%s: could not re-execute with restricted token: error code %lu\n"), progname, GetLastError()); + pg_log_error("could not re-execute with restricted token: error code %lu", GetLastError()); } else { @@ -183,7 +182,7 @@ get_restricted_token(const char *progname) if (!GetExitCodeProcess(pi.hProcess, &x)) { - fprintf(stderr, _("%s: could not get exit code from subprocess: error code %lu\n"), progname, GetLastError()); + pg_log_error("could not get exit code from subprocess: error code %lu", GetLastError()); exit(1); } exit(x); diff --git a/src/common/rmtree.c b/src/common/rmtree.c index fcf63eb953d..3c207917b5b 100644 --- a/src/common/rmtree.c +++ b/src/common/rmtree.c @@ -2,7 +2,7 @@ * * rmtree.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -20,6 +20,12 @@ #include #include +#ifndef FRONTEND +#define pg_log_warning(...) elog(WARNING, __VA_ARGS__) +#else +#include "common/logging.h" +#endif + /* * rmtree @@ -62,7 +68,7 @@ rmtree(const char *path, bool rmtopdir) * This is not an academic possibility. One scenario where this * happens is when bgwriter has a pending unlink request for a file in * a database that's being dropped. In dropdb(), we call - * ForgetDatabaseFsyncRequests() to flush out any such pending unlink + * ForgetDatabaseSyncRequests() to flush out any such pending unlink * requests, but because that's asynchronous, it's not guaranteed that * the bgwriter receives the message in time. */ @@ -70,13 +76,8 @@ rmtree(const char *path, bool rmtopdir) { if (errno != ENOENT) { -#ifndef FRONTEND - elog(WARNING, "could not stat file or directory \"%s\": %m", - pathbuf); -#else - fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"), - pathbuf, strerror(errno)); -#endif + pg_log_warning("could not stat file or directory \"%s\": %m", + pathbuf); result = false; } continue; @@ -97,13 +98,8 @@ rmtree(const char *path, bool rmtopdir) { if (errno != ENOENT) { -#ifndef FRONTEND - elog(WARNING, "could not remove file or directory \"%s\": %m", - pathbuf); -#else - fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), - pathbuf, strerror(errno)); -#endif + pg_log_warning("could not remove file or directory \"%s\": %m", + pathbuf); result = false; } } @@ -114,13 +110,8 @@ rmtree(const char *path, bool rmtopdir) { if (rmdir(path) != 0) { -#ifndef FRONTEND - elog(WARNING, "could not remove file or directory \"%s\": %m", - path); -#else - fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), - path, strerror(errno)); -#endif + pg_log_warning("could not remove file or directory \"%s\": %m", + path); result = false; } } diff --git a/src/common/ryu_common.h b/src/common/ryu_common.h new file mode 100644 index 00000000000..14639aff9c3 --- /dev/null +++ b/src/common/ryu_common.h @@ -0,0 +1,133 @@ +/*--------------------------------------------------------------------------- + * + * Common routines for Ryu floating-point output. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/common/ryu_common.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ +#ifndef RYU_COMMON_H +#define RYU_COMMON_H + +/* + * Upstream Ryu's output is always the shortest possible. But we adjust that + * slightly to improve portability: we avoid outputting the exact midpoint + * value between two representable floats, since that relies on the reader + * getting the round-to-even rule correct, which seems to be the common + * failure mode. + * + * Defining this to 1 would restore the upstream behavior. + */ +#define STRICTLY_SHORTEST 0 + +#if SIZEOF_SIZE_T < 8 +#define RYU_32_BIT_PLATFORM +#endif + +/* Returns e == 0 ? 1 : ceil(log_2(5^e)). */ +static inline uint32 +pow5bits(const int32 e) +{ + /* + * This approximation works up to the point that the multiplication + * overflows at e = 3529. + * + * If the multiplication were done in 64 bits, it would fail at 5^4004 + * which is just greater than 2^9297. + */ + Assert(e >= 0); + Assert(e <= 3528); + return ((((uint32) e) * 1217359) >> 19) + 1; +} + +/* Returns floor(log_10(2^e)). */ +static inline int32 +log10Pow2(const int32 e) +{ + /* + * The first value this approximation fails for is 2^1651 which is just + * greater than 10^297. + */ + Assert(e >= 0); + Assert(e <= 1650); + return (int32) ((((uint32) e) * 78913) >> 18); +} + +/* Returns floor(log_10(5^e)). */ +static inline int32 +log10Pow5(const int32 e) +{ + /* + * The first value this approximation fails for is 5^2621 which is just + * greater than 10^1832. + */ + Assert(e >= 0); + Assert(e <= 2620); + return (int32) ((((uint32) e) * 732923) >> 20); +} + +static inline int +copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) +{ + if (mantissa) + { + memcpy(result, "NaN", 3); + return 3; + } + if (sign) + { + result[0] = '-'; + } + if (exponent) + { + memcpy(result + sign, "Infinity", 8); + return sign + 8; + } + result[sign] = '0'; + return sign + 1; +} + +static inline uint32 +float_to_bits(const float f) +{ + uint32 bits = 0; + + memcpy(&bits, &f, sizeof(float)); + return bits; +} + +static inline uint64 +double_to_bits(const double d) +{ + uint64 bits = 0; + + memcpy(&bits, &d, sizeof(double)); + return bits; +} + +#endif /* RYU_COMMON_H */ diff --git a/src/common/saslprep.c b/src/common/saslprep.c index 271021550ad..23379610ae0 100644 --- a/src/common/saslprep.c +++ b/src/common/saslprep.c @@ -12,7 +12,7 @@ * http://www.ietf.org/rfc/rfc4013.txt * * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/common/saslprep.c @@ -1081,6 +1081,9 @@ pg_saslprep(const char *input, char **output) unsigned char *p; pg_wchar *wp; + /* Ensure we return *output as NULL on failure */ + *output = NULL; + /* Check that the password isn't stupendously long */ if (strlen(input) > MAX_PASSWORD_LENGTH) { @@ -1112,10 +1115,7 @@ pg_saslprep(const char *input, char **output) */ input_size = pg_utf8_string_len(input); if (input_size < 0) - { - *output = NULL; return SASLPREP_INVALID_UTF8; - } input_chars = ALLOC((input_size + 1) * sizeof(pg_wchar)); if (!input_chars) @@ -1246,6 +1246,11 @@ pg_saslprep(const char *input, char **output) result = ALLOC(result_size + 1); if (!result) goto oom; + + /* + * There are no error exits below here, so the error exit paths don't need + * to worry about possibly freeing "result". + */ p = (unsigned char *) result; for (wp = output_chars; *wp; wp++) { diff --git a/src/common/scram-common.c b/src/common/scram-common.c index dc4160714f9..dff9723e67f 100644 --- a/src/common/scram-common.c +++ b/src/common/scram-common.c @@ -6,7 +6,7 @@ * backend, for implement the Salted Challenge Response Authentication * Mechanism (SCRAM), per IETF's RFC 5802. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/common/scram-common.c @@ -198,6 +198,10 @@ scram_build_verifier(const char *salt, int saltlen, int iterations, char *result; char *p; int maxlen; + int encoded_salt_len; + int encoded_stored_len; + int encoded_server_len; + int encoded_result; if (iterations <= 0) iterations = SCRAM_DEFAULT_ITERATIONS; @@ -215,11 +219,15 @@ scram_build_verifier(const char *salt, int saltlen, int iterations, * SCRAM-SHA-256$:$: *---------- */ + encoded_salt_len = pg_b64_enc_len(saltlen); + encoded_stored_len = pg_b64_enc_len(SCRAM_KEY_LEN); + encoded_server_len = pg_b64_enc_len(SCRAM_KEY_LEN); + maxlen = strlen("SCRAM-SHA-256") + 1 + 10 + 1 /* iteration count */ - + pg_b64_enc_len(saltlen) + 1 /* Base64-encoded salt */ - + pg_b64_enc_len(SCRAM_KEY_LEN) + 1 /* Base64-encoded StoredKey */ - + pg_b64_enc_len(SCRAM_KEY_LEN) + 1; /* Base64-encoded ServerKey */ + + encoded_salt_len + 1 /* Base64-encoded salt */ + + encoded_stored_len + 1 /* Base64-encoded StoredKey */ + + encoded_server_len + 1; /* Base64-encoded ServerKey */ #ifdef FRONTEND result = malloc(maxlen); @@ -231,11 +239,50 @@ scram_build_verifier(const char *salt, int saltlen, int iterations, p = result + sprintf(result, "SCRAM-SHA-256$%d:", iterations); - p += pg_b64_encode(salt, saltlen, p); + /* salt */ + encoded_result = pg_b64_encode(salt, saltlen, p, encoded_salt_len); + if (encoded_result < 0) + { +#ifdef FRONTEND + free(result); + return NULL; +#else + elog(ERROR, "could not encode salt"); +#endif + } + p += encoded_result; *(p++) = '$'; - p += pg_b64_encode((char *) stored_key, SCRAM_KEY_LEN, p); + + /* stored key */ + encoded_result = pg_b64_encode((char *) stored_key, SCRAM_KEY_LEN, p, + encoded_stored_len); + if (encoded_result < 0) + { +#ifdef FRONTEND + free(result); + return NULL; +#else + elog(ERROR, "could not encode stored key"); +#endif + } + + p += encoded_result; *(p++) = ':'; - p += pg_b64_encode((char *) server_key, SCRAM_KEY_LEN, p); + + /* server key */ + encoded_result = pg_b64_encode((char *) server_key, SCRAM_KEY_LEN, p, + encoded_server_len); + if (encoded_result < 0) + { +#ifdef FRONTEND + free(result); + return NULL; +#else + elog(ERROR, "could not encode server key"); +#endif + } + + p += encoded_result; *(p++) = '\0'; Assert(p - result <= maxlen); diff --git a/src/common/sha2.c b/src/common/sha2.c index 5aa678f8e36..ae0a1a34095 100644 --- a/src/common/sha2.c +++ b/src/common/sha2.c @@ -6,7 +6,7 @@ * This is the set of in-core functions used when there are no other * alternative options like OpenSSL. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/common/sha2.c diff --git a/src/common/sha2_openssl.c b/src/common/sha2_openssl.c index 362e1318db1..d23ba758c74 100644 --- a/src/common/sha2_openssl.c +++ b/src/common/sha2_openssl.c @@ -6,7 +6,7 @@ * * This should only be used if code is compiled with OpenSSL support. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/common/sha2_openssl.c diff --git a/src/common/string.c b/src/common/string.c index 3260d37a84e..c9b8482cb06 100644 --- a/src/common/string.c +++ b/src/common/string.c @@ -4,7 +4,7 @@ * string handling helpers * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -56,3 +56,59 @@ strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base) errno = ERANGE; return (int) val; } + + +/* + * pg_clean_ascii -- Replace any non-ASCII chars with a '?' char + * + * Modifies the string passed in which must be '\0'-terminated. + * + * This function exists specifically to deal with filtering out + * non-ASCII characters in a few places where the client can provide an almost + * arbitrary string (and it isn't checked to ensure it's a valid username or + * database name or similar) and we don't want to have control characters or other + * things ending up in the log file where server admins might end up with a + * messed up terminal when looking at them. + * + * In general, this function should NOT be used- instead, consider how to handle + * the string without needing to filter out the non-ASCII characters. + * + * Ultimately, we'd like to improve the situation to not require stripping out + * all non-ASCII but perform more intelligent filtering which would allow UTF or + * similar, but it's unclear exactly what we should allow, so stick to ASCII only + * for now. + */ +void +pg_clean_ascii(char *str) +{ + /* Only allow clean ASCII chars in the string */ + char *p; + + for (p = str; *p != '\0'; p++) + { + if (*p < 32 || *p > 126) + *p = '?'; + } +} + + +/* + * pg_strip_crlf -- Remove any trailing newline and carriage return + * + * Removes any trailing newline and carriage return characters (\r on + * Windows) in the input string, zero-terminating it. + * + * The passed in string must be zero-terminated. This function returns + * the new length of the string. + */ +int +pg_strip_crlf(char *str) +{ + int len = strlen(str); + + while (len > 0 && (str[len - 1] == '\n' || + str[len - 1] == '\r')) + str[--len] = '\0'; + + return len; +} diff --git a/src/common/unicode/README b/src/common/unicode/README index 7c1c433b61e..5aa79044d36 100644 --- a/src/common/unicode/README +++ b/src/common/unicode/README @@ -10,7 +10,7 @@ Generating unicode_norm_table.h 1. Download the Unicode data file, UnicodeData.txt, from the Unicode consortium and place it to the current directory. Run the perl script -"norm_test_generate.pl", to process it, and to generate the +"generate-unicode_norm_table.pl", to process it, and to generate the "unicode_norm_table.h" file. The Makefile contains a rule to download the data files if they don't exist. diff --git a/src/common/unicode/generate-norm_test_table.pl b/src/common/unicode/generate-norm_test_table.pl index e3510b5c81b..3ff5ee3c5ed 100644 --- a/src/common/unicode/generate-norm_test_table.pl +++ b/src/common/unicode/generate-norm_test_table.pl @@ -5,7 +5,7 @@ # # NormalizationTest.txt is part of the Unicode Character Database. # -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use strict; use warnings; @@ -30,7 +30,7 @@ * norm_test_table.h * Test strings for Unicode normalization. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/common/unicode/norm_test_table.h @@ -56,7 +56,7 @@ print $OUTPUT "static const pg_unicode_test UnicodeNormalizationTests[] =\n{\n"; -# Helper routine to conver a space-separated list of Unicode characters to +# Helper routine to convert a space-separated list of Unicode characters to # hexadecimal list format, suitable for outputting in a C array. sub codepoint_string_to_hex { diff --git a/src/common/unicode/generate-unicode_norm_table.pl b/src/common/unicode/generate-unicode_norm_table.pl index f9cb406f1bf..7002fdf98c1 100644 --- a/src/common/unicode/generate-unicode_norm_table.pl +++ b/src/common/unicode/generate-unicode_norm_table.pl @@ -5,7 +5,7 @@ # Input: UnicodeData.txt and CompositionExclusions.txt # Output: unicode_norm_table.h # -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use strict; use warnings; @@ -74,7 +74,7 @@ * unicode_norm_table.h * Composition table used for Unicode normalization * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/unicode_norm_table.h @@ -97,7 +97,8 @@ } pg_unicode_decomposition; #define DECOMP_NO_COMPOSE 0x80 /* don't use for re-composition */ -#define DECOMP_INLINE 0x40 /* decomposition is stored inline in dec_index */ +#define DECOMP_INLINE 0x40 /* decomposition is stored inline in + * dec_index */ #define DECOMPOSITION_SIZE(x) ((x)->dec_size_flags & 0x3F) #define DECOMPOSITION_NO_COMPOSE(x) (((x)->dec_size_flags & DECOMP_NO_COMPOSE) != 0) diff --git a/src/common/unicode/norm_test.c b/src/common/unicode/norm_test.c index 56759bee8db..fee58a184aa 100644 --- a/src/common/unicode/norm_test.c +++ b/src/common/unicode/norm_test.c @@ -2,10 +2,10 @@ * norm_test.c * Program to test Unicode normalization functions. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION - * src/common/unicode_norm.c + * src/common/unicode/norm_test.c * *------------------------------------------------------------------------- */ @@ -66,7 +66,7 @@ main(int argc, char **argv) if (pg_wcscmp(test->output, result) != 0) { - printf("FAILURE (Normalizationdata.txt line %d):\n", test->linenum); + printf("FAILURE (NormalizationTest.txt line %d):\n", test->linenum); printf("input:\t%s\n", print_wchar_str(test->input)); printf("expected:\t%s\n", print_wchar_str(test->output)); printf("got\t%s\n", print_wchar_str(result)); diff --git a/src/common/unicode_norm.c b/src/common/unicode_norm.c index 1eacdb298f3..89c55332128 100644 --- a/src/common/unicode_norm.c +++ b/src/common/unicode_norm.c @@ -5,7 +5,7 @@ * This implements Unicode normalization, per the documentation at * http://www.unicode.org/reports/tr15/. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/common/unicode_norm.c @@ -59,7 +59,7 @@ static pg_unicode_decomposition * get_code_entry(pg_wchar code) { return bsearch(&(code), - (void *) UnicodeDecompMain, + UnicodeDecompMain, lengthof(UnicodeDecompMain), sizeof(pg_unicode_decomposition), conv_compare); @@ -178,7 +178,7 @@ recompose_code(uint32 start, uint32 code, uint32 *result) ((start - SBASE) % TCOUNT) == 0 && code >= TBASE && code < (TBASE + TCOUNT)) { - /* make syllable of from LVT */ + /* make syllable of form LVT */ uint32 tindex = code - TBASE; *result = start + tindex; diff --git a/src/common/username.c b/src/common/username.c index af382f95a5b..146c3be7fdf 100644 --- a/src/common/username.c +++ b/src/common/username.c @@ -3,7 +3,7 @@ * username.c * get user name * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/common/wait_error.c b/src/common/wait_error.c index 941b606999b..fec25b29b1e 100644 --- a/src/common/wait_error.c +++ b/src/common/wait_error.c @@ -4,7 +4,7 @@ * Convert a wait/waitpid(2) result code to a human-readable string * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -56,25 +56,17 @@ wait_result_to_str(int exitstatus) } } else if (WIFSIGNALED(exitstatus)) + { #if defined(WIN32) snprintf(str, sizeof(str), _("child process was terminated by exception 0x%X"), WTERMSIG(exitstatus)); -#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST - { - char str2[256]; - - snprintf(str2, sizeof(str2), "%d: %s", WTERMSIG(exitstatus), - WTERMSIG(exitstatus) < NSIG ? - sys_siglist[WTERMSIG(exitstatus)] : "(unknown)"); - snprintf(str, sizeof(str), - _("child process was terminated by signal %s"), str2); - } #else snprintf(str, sizeof(str), - _("child process was terminated by signal %d"), - WTERMSIG(exitstatus)); + _("child process was terminated by signal %d: %s"), + WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus))); #endif + } else snprintf(str, sizeof(str), _("child process exited with unrecognized status %d"), @@ -82,3 +74,46 @@ wait_result_to_str(int exitstatus) return pstrdup(str); } + +/* + * Return true if a wait(2) result indicates that the child process + * died due to the specified signal. + * + * The reason this is worth having a wrapper function for is that + * there are two cases: the signal might have been received by our + * immediate child process, or there might've been a shell process + * between us and the child that died. The shell will, per POSIX, + * report the child death using exit code 128 + signal number. + * + * If there is no possibility of an intermediate shell, this function + * need not (and probably should not) be used. + */ +bool +wait_result_is_signal(int exit_status, int signum) +{ + if (WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum) + return true; + if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 128 + signum) + return true; + return false; +} + +/* + * Return true if a wait(2) result indicates that the child process + * died due to any signal. We consider either direct child death + * or a shell report of child process death as matching the condition. + * + * If include_command_not_found is true, also return true for shell + * exit codes indicating "command not found" and the like + * (specifically, exit codes 126 and 127; see above). + */ +bool +wait_result_is_any_signal(int exit_status, bool include_command_not_found) +{ + if (WIFSIGNALED(exit_status)) + return true; + if (WIFEXITED(exit_status) && + WEXITSTATUS(exit_status) > (include_command_not_found ? 125 : 128)) + return true; + return false; +} diff --git a/src/fe_utils/Makefile b/src/fe_utils/Makefile index 5362cffd573..f2e516a2aa3 100644 --- a/src/fe_utils/Makefile +++ b/src/fe_utils/Makefile @@ -5,7 +5,7 @@ # This makefile generates a static library, libpgfeutils.a, # for use by client applications # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # IDENTIFICATION @@ -19,7 +19,8 @@ include $(top_builddir)/src/Makefile.global override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS) -OBJS = mbprint.o print.o psqlscan.o simple_list.o string_utils.o conditional.o +OBJS = conditional.o mbprint.o print.o psqlscan.o recovery_gen.o \ + simple_list.o string_utils.o all: libpgfeutils.a diff --git a/src/fe_utils/conditional.c b/src/fe_utils/conditional.c index 0af80521ce1..6a80c4087f5 100644 --- a/src/fe_utils/conditional.c +++ b/src/fe_utils/conditional.c @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * A stack of automaton states to handle nested conditionals. * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/fe_utils/conditional.c * @@ -75,8 +75,9 @@ conditional_stack_depth(ConditionalStack cstack) return -1; else { - IfStackElem *p = cstack->head; + IfStackElem *p = cstack->head; int depth = 0; + while (p != NULL) { depth++; diff --git a/src/fe_utils/mbprint.c b/src/fe_utils/mbprint.c index 07c348ec496..f3a6fdf794e 100644 --- a/src/fe_utils/mbprint.c +++ b/src/fe_utils/mbprint.c @@ -3,7 +3,7 @@ * Multibyte character printing support for frontend code * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/fe_utils/mbprint.c diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index cb9a9a06131..e41f42ea981 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -8,7 +8,7 @@ * pager open/close functions, all that stuff came with it. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/fe_utils/print.c @@ -200,10 +200,10 @@ static const unicodeStyleFormat unicode_style = { /* Local functions */ static int strlen_max_width(unsigned char *str, int *target_width, int encoding); static void IsPagerNeeded(const printTableContent *cont, int extra_lines, bool expanded, - FILE **fout, bool *is_pager); + FILE **fout, bool *is_pager); static void print_aligned_vertical(const printTableContent *cont, - FILE *fout, bool is_pager); + FILE *fout, bool is_pager); /* Count number of digits in integral part of number */ @@ -1737,7 +1737,119 @@ print_aligned_vertical(const printTableContent *cont, /**********************/ -/* HTML printing ******/ +/* CSV format */ +/**********************/ + + +static void +csv_escaped_print(const char *str, FILE *fout) +{ + const char *p; + + fputc('"', fout); + for (p = str; *p; p++) + { + if (*p == '"') + fputc('"', fout); /* double quotes are doubled */ + fputc(*p, fout); + } + fputc('"', fout); +} + +static void +csv_print_field(const char *str, FILE *fout, char sep) +{ + /*---------------- + * Enclose and escape field contents when one of these conditions is met: + * - the field separator is found in the contents. + * - the field contains a CR or LF. + * - the field contains a double quote. + * - the field is exactly "\.". + * - the field separator is either "\" or ".". + * The last two cases prevent producing a line that the server's COPY + * command would interpret as an end-of-data marker. We only really + * need to ensure that the complete line isn't exactly "\.", but for + * simplicity we apply stronger restrictions here. + *---------------- + */ + if (strchr(str, sep) != NULL || + strcspn(str, "\r\n\"") != strlen(str) || + strcmp(str, "\\.") == 0 || + sep == '\\' || sep == '.') + csv_escaped_print(str, fout); + else + fputs(str, fout); +} + +static void +print_csv_text(const printTableContent *cont, FILE *fout) +{ + const char *const *ptr; + int i; + + if (cancel_pressed) + return; + + /* + * The title and footer are never printed in csv format. The header is + * printed if opt_tuples_only is false. + * + * Despite RFC 4180 saying that end of lines are CRLF, terminate lines + * with '\n', which prints out as the system-dependent EOL string in text + * mode (typically LF on Unix and CRLF on Windows). + */ + if (cont->opt->start_table && !cont->opt->tuples_only) + { + /* print headers */ + for (ptr = cont->headers; *ptr; ptr++) + { + if (ptr != cont->headers) + fputc(cont->opt->csvFieldSep[0], fout); + csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]); + } + fputc('\n', fout); + } + + /* print cells */ + for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) + { + csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]); + if ((i + 1) % cont->ncolumns) + fputc(cont->opt->csvFieldSep[0], fout); + else + fputc('\n', fout); + } +} + +static void +print_csv_vertical(const printTableContent *cont, FILE *fout) +{ + const char *const *ptr; + int i; + + /* print records */ + for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) + { + if (cancel_pressed) + return; + + /* print name of column */ + csv_print_field(cont->headers[i % cont->ncolumns], fout, + cont->opt->csvFieldSep[0]); + + /* print field separator */ + fputc(cont->opt->csvFieldSep[0], fout); + + /* print field value */ + csv_print_field(*ptr, fout, cont->opt->csvFieldSep[0]); + + fputc('\n', fout); + } +} + + +/**********************/ +/* HTML */ /**********************/ @@ -1953,9 +2065,10 @@ print_html_vertical(const printTableContent *cont, FILE *fout) /*************************/ -/* ASCIIDOC */ +/* ASCIIDOC */ /*************************/ + static void asciidoc_escaped_print(const char *in, FILE *fout) { @@ -2174,6 +2287,7 @@ print_asciidoc_vertical(const printTableContent *cont, FILE *fout) } } + /*************************/ /* LaTeX */ /*************************/ @@ -2187,14 +2301,34 @@ latex_escaped_print(const char *in, FILE *fout) for (p = in; *p; p++) switch (*p) { - case '&': - fputs("\\&", fout); + /* + * We convert ASCII characters per the recommendations in + * Scott Pakin's "The Comprehensive LATEX Symbol List", + * available from CTAN. For non-ASCII, you're on your own. + */ + case '#': + fputs("\\#", fout); + break; + case '$': + fputs("\\$", fout); break; case '%': fputs("\\%", fout); break; - case '$': - fputs("\\$", fout); + case '&': + fputs("\\&", fout); + break; + case '<': + fputs("\\textless{}", fout); + break; + case '>': + fputs("\\textgreater{}", fout); + break; + case '\\': + fputs("\\textbackslash{}", fout); + break; + case '^': + fputs("\\^{}", fout); break; case '_': fputs("\\_", fout); @@ -2202,13 +2336,17 @@ latex_escaped_print(const char *in, FILE *fout) case '{': fputs("\\{", fout); break; + case '|': + fputs("\\textbar{}", fout); + break; case '}': fputs("\\}", fout); break; - case '\\': - fputs("\\backslash", fout); + case '~': + fputs("\\~{}", fout); break; case '\n': + /* This is not right, but doing it right seems too hard */ fputs("\\\\", fout); break; default: @@ -2319,6 +2457,11 @@ print_latex_text(const printTableContent *cont, FILE *fout) } +/*************************/ +/* LaTeX longtable */ +/*************************/ + + static void print_latex_longtable_text(const printTableContent *cont, FILE *fout) { @@ -2564,7 +2707,7 @@ print_latex_vertical(const printTableContent *cont, FILE *fout) /*************************/ -/* Troff -ms */ +/* Troff -ms */ /*************************/ @@ -3107,7 +3250,7 @@ printTableCleanup(printTableContent *const content) for (i = 0; i < content->nrows * content->ncolumns; i++) { if (content->cellmustfree[i]) - free((char *) content->cells[i]); + free(unconstify(char *, content->cells[i])); } free(content->cellmustfree); content->cellmustfree = NULL; @@ -3234,6 +3377,12 @@ printTable(const printTableContent *cont, else print_aligned_text(cont, fout, is_pager); break; + case PRINT_CSV: + if (cont->opt->expanded == 1) + print_csv_vertical(cont, fout); + else + print_csv_text(cont, fout); + break; case PRINT_HTML: if (cont->opt->expanded == 1) print_html_vertical(cont, fout); diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index 1cc587be34c..ce209363399 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -23,7 +23,8 @@ * * See psqlscan_int.h for additional commentary. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -33,12 +34,16 @@ */ #include "postgres_fe.h" +#include "common/logging.h" #include "fe_utils/psqlscan.h" #include "libpq-fe.h" } %{ + +/* LCOV_EXCL_START */ + #include "fe_utils/psqlscan_int.h" /* @@ -71,8 +76,6 @@ typedef int YYSTYPE; extern int psql_yyget_column(yyscan_t yyscanner); extern void psql_yyset_column(int column_no, yyscan_t yyscanner); -/* LCOV_EXCL_START */ - %} %option reentrant @@ -128,8 +131,8 @@ extern void psql_yyset_column(int column_no, yyscan_t yyscanner); %x xc %x xd %x xh -%x xe %x xq +%x xe %x xdolq %x xui %x xuiend @@ -151,7 +154,7 @@ extern void psql_yyset_column(int column_no, yyscan_t yyscanner); * XXX perhaps \f (formfeed) should be treated as a newline as well? * * XXX if you change the set of whitespace characters, fix scanner_isspace() - * to agree, and see also the plpgsql lexer. + * to agree. */ space [ \t\n\r\f] @@ -298,6 +301,15 @@ identifier {ident_start}{ident_cont}* typecast "::" dot_dot \.\. colon_equals ":=" + +/* + * These operator-like tokens (unlike the above ones) also match the {operator} + * rule, which means that they might be overridden by a longer match if they + * are followed by a comment start or a + or - character. Accordingly, if you + * add to this list, you must also add corresponding code to the {operator} + * block to return the correct token in such cases. (This is not needed in + * psqlscan.l since the token value is ignored there.) + */ equals_greater "=>" less_equals "<=" greater_equals ">=" @@ -393,14 +405,15 @@ other . ECHO; } -{xcstart} { +{ +{xcstart} { cur_state->xcdepth++; /* Put back any characters past slash-star; see above */ yyless(2); ECHO; } -{xcstop} { +{xcstop} { if (cur_state->xcdepth <= 0) BEGIN(INITIAL); else @@ -408,17 +421,18 @@ other . ECHO; } -{xcinside} { +{xcinside} { ECHO; } -{op_chars} { +{op_chars} { ECHO; } -\*+ { +\*+ { ECHO; } +} /* */ {xbstart} { BEGIN(xb); @@ -681,7 +695,7 @@ other . */ "\\"[;:] { - /* Force a semicolon or colon into the query buffer */ + /* Force a semi-colon or colon into the query buffer */ psqlscan_emit(cur_state, yytext + 1, 1); } @@ -712,7 +726,7 @@ other . if (psqlscan_var_is_current_source(cur_state, varname)) { /* Recursive expansion --- don't go there */ - cur_state->callbacks->write_error("skipping recursive expansion of variable \"%s\"\n", + pg_log_warning("skipping recursive expansion of variable \"%s\"", varname); /* Instead copy the string as is */ ECHO; @@ -817,20 +831,33 @@ other . * to forbid operator names like '?-' that could not be * sequences of SQL operators. */ - while (nchars > 1 && - (yytext[nchars - 1] == '+' || - yytext[nchars - 1] == '-')) + if (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')) { int ic; for (ic = nchars - 2; ic >= 0; ic--) { - if (strchr("~!@#^&|`?%", yytext[ic])) + char c = yytext[ic]; + if (c == '~' || c == '!' || c == '@' || + c == '#' || c == '^' || c == '&' || + c == '|' || c == '`' || c == '?' || + c == '%') break; } - if (ic >= 0) - break; /* found a char that makes it OK */ - nchars--; /* else remove the +/-, and check again */ + if (ic < 0) + { + /* + * didn't find a qualifying character, so remove + * all trailing [+-] + */ + do { + nchars--; + } while (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')); + } } if (nchars < yyleng) @@ -861,10 +888,9 @@ other . } {realfail1} { /* - * throw back the [Ee], and treat as {decimal}. Note - * that it is possible the input is actually {integer}, - * but since this case will almost certainly lead to a - * syntax error anyway, we don't bother to distinguish. + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. + * (in psql, we don't actually care...) */ yyless(yyleng - 1); ECHO; diff --git a/src/fe_utils/recovery_gen.c b/src/fe_utils/recovery_gen.c new file mode 100644 index 00000000000..6641f95f071 --- /dev/null +++ b/src/fe_utils/recovery_gen.c @@ -0,0 +1,176 @@ +/*------------------------------------------------------------------------- + * + * recovery_gen.c + * Generator for recovery configuration + * + * Portions Copyright (c) 2011-2019, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#include "postgres_fe.h" + +#include "common/logging.h" +#include "fe_utils/string_utils.h" +#include "fe_utils/recovery_gen.h" + + +static char *escape_quotes(const char *src); + +/* + * Write recovery configuration contents into a fresh PQExpBuffer, and + * return it. + */ +PQExpBuffer +GenerateRecoveryConfig(PGconn *pgconn, char *replication_slot) +{ + PQconninfoOption *connOptions; + PQExpBufferData conninfo_buf; + char *escaped; + PQExpBuffer contents; + + Assert(pgconn != NULL); + + contents = createPQExpBuffer(); + if (!contents) + { + pg_log_error("out of memory"); + exit(1); + } + + /* + * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by + * standby.signal to trigger a standby state at recovery. + */ + if (PQserverVersion(pgconn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) + appendPQExpBufferStr(contents, "standby_mode = 'on'\n"); + + connOptions = PQconninfo(pgconn); + if (connOptions == NULL) + { + pg_log_error("out of memory"); + exit(1); + } + + initPQExpBuffer(&conninfo_buf); + for (PQconninfoOption *opt = connOptions; opt && opt->keyword; opt++) + { + /* Omit empty settings and those libpqwalreceiver overrides. */ + if (strcmp(opt->keyword, "replication") == 0 || + strcmp(opt->keyword, "dbname") == 0 || + strcmp(opt->keyword, "fallback_application_name") == 0 || + (opt->val == NULL) || + (opt->val != NULL && opt->val[0] == '\0')) + continue; + + /* Separate key-value pairs with spaces */ + if (conninfo_buf.len != 0) + appendPQExpBufferChar(&conninfo_buf, ' '); + + /* + * Write "keyword=value" pieces, the value string is escaped and/or + * quoted if necessary. + */ + appendPQExpBuffer(&conninfo_buf, "%s=", opt->keyword); + appendConnStrVal(&conninfo_buf, opt->val); + } + if (PQExpBufferDataBroken(conninfo_buf)) + { + pg_log_error("out of memory"); + exit(1); + } + + /* + * Escape the connection string, so that it can be put in the config file. + * Note that this is different from the escaping of individual connection + * options above! + */ + escaped = escape_quotes(conninfo_buf.data); + termPQExpBuffer(&conninfo_buf); + appendPQExpBuffer(contents, "primary_conninfo = '%s'\n", escaped); + free(escaped); + + if (replication_slot) + { + /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */ + appendPQExpBuffer(contents, "primary_slot_name = '%s'\n", + replication_slot); + } + + if (PQExpBufferBroken(contents)) + { + pg_log_error("out of memory"); + exit(1); + } + + PQconninfoFree(connOptions); + + return contents; +} + +/* + * Write the configuration file in the directory specified in target_dir, + * with the contents already collected in memory appended. Then write + * the signal file into the target_dir. If the server does not support + * recovery parameters as GUCs, the signal file is not necessary, and + * configuration is written to recovery.conf. + */ +void +WriteRecoveryConfig(PGconn *pgconn, char *target_dir, PQExpBuffer contents) +{ + char filename[MAXPGPATH]; + FILE *cf; + bool use_recovery_conf; + + Assert(pgconn != NULL); + + use_recovery_conf = + PQserverVersion(pgconn) < MINIMUM_VERSION_FOR_RECOVERY_GUC; + + snprintf(filename, MAXPGPATH, "%s/%s", target_dir, + use_recovery_conf ? "recovery.conf" : "postgresql.auto.conf"); + + cf = fopen(filename, use_recovery_conf ? "a" : "w"); + if (cf == NULL) + { + pg_log_error("could not open file \"%s\": %m", filename); + exit(1); + } + + if (fwrite(contents->data, contents->len, 1, cf) != 1) + { + pg_log_error("could not write to file \"%s\": %m", filename); + exit(1); + } + + fclose(cf); + + if (!use_recovery_conf) + { + snprintf(filename, MAXPGPATH, "%s/%s", target_dir, "standby.signal"); + cf = fopen(filename, "w"); + if (cf == NULL) + { + pg_log_error("could not create file \"%s\": %m", filename); + exit(1); + } + + fclose(cf); + } +} + +/* + * Escape a string so that it can be used as a value in a key-value pair + * a configuration file. + */ +static char * +escape_quotes(const char *src) +{ + char *result = escape_single_quotes_ascii(src); + + if (!result) + { + pg_log_error("out of memory"); + exit(1); + } + return result; +} diff --git a/src/fe_utils/simple_list.c b/src/fe_utils/simple_list.c index ef94b34cd12..cfdb7dc87af 100644 --- a/src/fe_utils/simple_list.c +++ b/src/fe_utils/simple_list.c @@ -7,7 +7,7 @@ * it's all we need in, eg, pg_dump. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/fe_utils/simple_list.c @@ -99,6 +99,44 @@ simple_string_list_member(SimpleStringList *list, const char *val) return false; } +/* + * Destroy an OID list + */ +void +simple_oid_list_destroy(SimpleOidList *list) +{ + SimpleOidListCell *cell; + + cell = list->head; + while (cell != NULL) + { + SimpleOidListCell *next; + + next = cell->next; + pg_free(cell); + cell = next; + } +} + +/* + * Destroy a string list + */ +void +simple_string_list_destroy(SimpleStringList *list) +{ + SimpleStringListCell *cell; + + cell = list->head; + while (cell != NULL) + { + SimpleStringListCell *next; + + next = cell->next; + pg_free(cell); + cell = next; + } +} + /* * Find first not-touched list entry, if there is one. */ diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c index b47a396af15..8c3a603cf1d 100644 --- a/src/fe_utils/string_utils.c +++ b/src/fe_utils/string_utils.c @@ -6,7 +6,7 @@ * and interpreting backend output. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/fe_utils/string_utils.c @@ -104,11 +104,9 @@ fmtId(const char *rawid) * Note: ScanKeywordLookup() does case-insensitive comparison, but * that's fine, since we already know we have all-lower-case. */ - const ScanKeyword *keyword = ScanKeywordLookup(rawid, - ScanKeywords, - NumScanKeywords); + int kwnum = ScanKeywordLookup(rawid, &ScanKeywords); - if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD) + if (kwnum >= 0 && ScanKeywordCategories[kwnum] != UNRESERVED_KEYWORD) need_quotes = true; } @@ -138,8 +136,7 @@ fmtId(const char *rawid) } /* - * fmtQualifiedId - convert a qualified name to the proper format for - * the source database. + * fmtQualifiedId - construct a schema-qualified name, with quoting as needed. * * Like fmtId, use the result before calling again. * @@ -147,13 +144,13 @@ fmtId(const char *rawid) * use that buffer until we're finished with calling fmtId(). */ const char * -fmtQualifiedId(int remoteVersion, const char *schema, const char *id) +fmtQualifiedId(const char *schema, const char *id) { PQExpBuffer id_return; PQExpBuffer lcl_pqexp = createPQExpBuffer(); - /* Suppress schema name if fetching from pre-7.3 DB */ - if (remoteVersion >= 70300 && schema && *schema) + /* Some callers might fail to provide a schema name */ + if (schema && *schema) { appendPQExpBuffer(lcl_pqexp, "%s.", fmtId(schema)); } @@ -544,8 +541,7 @@ appendShellStringNoError(PQExpBuffer buf, const char *str) /* * Append the given string to the buffer, with suitable quoting for passing - * the string as a value, in a keyword/pair value in a libpq connection - * string + * the string as a value in a keyword/value pair in a libpq connection string. */ void appendConnStrVal(PQExpBuffer buf, const char *str) @@ -628,10 +624,10 @@ appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname) PQExpBufferData connstr; initPQExpBuffer(&connstr); - appendPQExpBuffer(&connstr, "dbname="); + appendPQExpBufferStr(&connstr, "dbname="); appendConnStrVal(&connstr, dbname); - appendPQExpBuffer(buf, "-reuse-previous=on "); + appendPQExpBufferStr(buf, "-reuse-previous=on "); /* * As long as the name does not contain a newline, SQL identifier @@ -959,6 +955,12 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, * Now decide what we need to emit. We may run under a hostile * search_path, so qualify EVERY name. Note there will be a leading "^(" * in the patterns in any case. + * + * We want the regex matches to use the database's default collation where + * collation-sensitive behavior is required (for example, which characters + * match '\w'). That happened by default before PG v12, but if the server + * is >= v12 then we need to force it through explicit COLLATE clauses, + * otherwise the "C" collation attached to "name" catalog columns wins. */ if (namebuf.len > 2) { @@ -974,16 +976,22 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, appendPQExpBuffer(buf, "(%s OPERATOR(pg_catalog.~) ", namevar); appendStringLiteralConn(buf, namebuf.data, conn); + if (PQserverVersion(conn) >= 120000) + appendPQExpBufferStr(buf, " COLLATE pg_catalog.default"); appendPQExpBuffer(buf, "\n OR %s OPERATOR(pg_catalog.~) ", altnamevar); appendStringLiteralConn(buf, namebuf.data, conn); + if (PQserverVersion(conn) >= 120000) + appendPQExpBufferStr(buf, " COLLATE pg_catalog.default"); appendPQExpBufferStr(buf, ")\n"); } else { appendPQExpBuffer(buf, "%s OPERATOR(pg_catalog.~) ", namevar); appendStringLiteralConn(buf, namebuf.data, conn); + if (PQserverVersion(conn) >= 120000) + appendPQExpBufferStr(buf, " COLLATE pg_catalog.default"); appendPQExpBufferChar(buf, '\n'); } } @@ -1000,6 +1008,8 @@ processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, WHEREAND(); appendPQExpBuffer(buf, "%s OPERATOR(pg_catalog.~) ", schemavar); appendStringLiteralConn(buf, schemabuf.data, conn); + if (PQserverVersion(conn) >= 120000) + appendPQExpBufferStr(buf, " COLLATE pg_catalog.default"); appendPQExpBufferChar(buf, '\n'); } } diff --git a/src/include/.gitignore b/src/include/.gitignore index 49d108dbed3..51819fb4ddd 100644 --- a/src/include/.gitignore +++ b/src/include/.gitignore @@ -3,4 +3,3 @@ /pg_config.h /pg_config_ext.h /pg_config_os.h -/dynloader.h diff --git a/src/include/Makefile b/src/include/Makefile index 19d2524e531..c557375ae31 100644 --- a/src/include/Makefile +++ b/src/include/Makefile @@ -18,9 +18,10 @@ all: pg_config.h pg_config_ext.h pg_config_os.h # Subdirectories containing installable headers SUBDIRS = access bootstrap catalog commands common datatype \ - executor fe_utils foreign \ - lib libpq mb nodes optimizer parser postmaster regex replication \ - rewrite statistics storage tcop snowball snowball/libstemmer tsearch \ + executor fe_utils foreign jit \ + lib libpq mb nodes optimizer parser partitioning postmaster \ + regex replication rewrite \ + statistics storage tcop snowball snowball/libstemmer tsearch \ tsearch/dicts utils port port/atomics port/win32 port/win32_msvc \ port/win32_msvc/sys port/win32/arpa port/win32/netinet \ port/win32/sys portability @@ -53,7 +54,7 @@ install: all installdirs cp $(srcdir)/$$dir/*.h '$(DESTDIR)$(includedir_server)'/$$dir/ || exit; \ done ifeq ($(vpath_build),yes) - for file in dynloader.h catalog/schemapg.h catalog/pg_*_d.h parser/gram.h storage/lwlocknames.h utils/probes.h; do \ + for file in catalog/schemapg.h catalog/pg_*_d.h parser/gram.h storage/lwlocknames.h utils/probes.h; do \ cp $$file '$(DESTDIR)$(includedir_server)'/$$file || exit; \ done endif @@ -76,9 +77,9 @@ uninstall: clean: - rm -f utils/fmgroids.h utils/fmgrprotos.h utils/errcodes.h + rm -f utils/fmgroids.h utils/fmgrprotos.h utils/errcodes.h utils/header-stamp rm -f parser/gram.h storage/lwlocknames.h utils/probes.h rm -f catalog/schemapg.h catalog/pg_*_d.h catalog/header-stamp distclean maintainer-clean: clean - rm -f pg_config.h pg_config_ext.h pg_config_os.h dynloader.h stamp-h stamp-ext-h + rm -f pg_config.h pg_config_ext.h pg_config_os.h stamp-h stamp-ext-h diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index 14526a6bb2c..6e3db06eed2 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -3,7 +3,7 @@ * amapi.h * API for Postgres index access methods. * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * src/include/access/amapi.h * @@ -108,6 +108,9 @@ typedef bool (*amproperty_function) (Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull); +/* name of phase as used in progress reporting */ +typedef char *(*ambuildphasename_function) (int64 phasenum); + /* validate definition of an opclass for this AM */ typedef bool (*amvalidate_function) (Oid opclassoid); @@ -213,6 +216,7 @@ typedef struct IndexAmRoutine amcostestimate_function amcostestimate; amoptions_function amoptions; amproperty_function amproperty; /* can be NULL */ + ambuildphasename_function ambuildphasename; /* can be NULL */ amvalidate_function amvalidate; ambeginscan_function ambeginscan; amrescan_function amrescan; diff --git a/src/include/access/amvalidate.h b/src/include/access/amvalidate.h index e50afbd5565..317e1e68938 100644 --- a/src/include/access/amvalidate.h +++ b/src/include/access/amvalidate.h @@ -3,7 +3,7 @@ * amvalidate.h * Support routines for index access methods' amvalidate functions. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/access/amvalidate.h * @@ -28,9 +28,9 @@ typedef struct OpFamilyOpFuncGroup /* Functions in access/index/amvalidate.c */ extern List *identify_opfamily_groups(CatCList *oprlist, CatCList *proclist); extern bool check_amproc_signature(Oid funcid, Oid restype, bool exact, - int minargs, int maxargs,...); + int minargs, int maxargs,...); extern bool check_amop_signature(Oid opno, Oid restype, - Oid lefttype, Oid righttype); + Oid lefttype, Oid righttype); extern bool opfamily_can_sort_type(Oid opfamilyoid, Oid datatypeoid); #endif /* AMVALIDATE_H */ diff --git a/src/include/access/attnum.h b/src/include/access/attnum.h index c45a1acaaac..093eee86c6c 100644 --- a/src/include/access/attnum.h +++ b/src/include/access/attnum.h @@ -4,7 +4,7 @@ * POSTGRES attribute number definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/attnum.h @@ -55,7 +55,7 @@ typedef int16 AttrNumber; ) /* - * AttributeOffsetGetAttributeNumber + * AttrOffsetGetAttrNumber * Returns the attribute number for an attribute offset. */ #define AttrOffsetGetAttrNumber(attributeOffset) \ diff --git a/src/include/access/brin.h b/src/include/access/brin.h index 10999a38b58..fb351b36e03 100644 --- a/src/include/access/brin.h +++ b/src/include/access/brin.h @@ -1,7 +1,7 @@ /* * AM-callable functions for BRIN indexes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -10,7 +10,6 @@ #ifndef BRIN_H #define BRIN_H -#include "fmgr.h" #include "nodes/execnodes.h" #include "utils/relcache.h" diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h index d3134f9dcda..b1c91999469 100644 --- a/src/include/access/brin_internal.h +++ b/src/include/access/brin_internal.h @@ -2,7 +2,7 @@ * brin_internal.h * internal declarations for BRIN indexes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -85,23 +85,23 @@ typedef struct BrinDesc extern BrinDesc *brin_build_desc(Relation rel); extern void brin_free_desc(BrinDesc *bdesc); extern IndexBuildResult *brinbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void brinbuildempty(Relation index); extern bool brininsert(Relation idxRel, Datum *values, bool *nulls, - ItemPointer heaptid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer heaptid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern IndexScanDesc brinbeginscan(Relation r, int nkeys, int norderbys); extern int64 bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern void brinrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void brinendscan(IndexScanDesc scan); extern IndexBulkDeleteResult *brinbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *brinvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern bytea *brinoptions(Datum reloptions, bool validate); /* brin_validate.c */ diff --git a/src/include/access/brin_page.h b/src/include/access/brin_page.h index 82d5972c857..c8089300839 100644 --- a/src/include/access/brin_page.h +++ b/src/include/access/brin_page.h @@ -2,7 +2,7 @@ * brin_page.h * Prototypes and definitions for BRIN page layouts * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/include/access/brin_pageops.h b/src/include/access/brin_pageops.h index 5189d5ddc2a..04492358105 100644 --- a/src/include/access/brin_pageops.h +++ b/src/include/access/brin_pageops.h @@ -2,7 +2,7 @@ * brin_pageops.h * Prototypes for operating on BRIN pages. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -14,24 +14,24 @@ #include "access/brin_revmap.h" extern bool brin_doupdate(Relation idxrel, BlockNumber pagesPerRange, - BrinRevmap *revmap, BlockNumber heapBlk, - Buffer oldbuf, OffsetNumber oldoff, - const BrinTuple *origtup, Size origsz, - const BrinTuple *newtup, Size newsz, - bool samepage); + BrinRevmap *revmap, BlockNumber heapBlk, + Buffer oldbuf, OffsetNumber oldoff, + const BrinTuple *origtup, Size origsz, + const BrinTuple *newtup, Size newsz, + bool samepage); extern bool brin_can_do_samepage_update(Buffer buffer, Size origsz, - Size newsz); + Size newsz); extern OffsetNumber brin_doinsert(Relation idxrel, BlockNumber pagesPerRange, - BrinRevmap *revmap, Buffer *buffer, BlockNumber heapBlk, - BrinTuple *tup, Size itemsz); + BrinRevmap *revmap, Buffer *buffer, BlockNumber heapBlk, + BrinTuple *tup, Size itemsz); extern void brin_page_init(Page page, uint16 type); extern void brin_metapage_init(Page page, BlockNumber pagesPerRange, - uint16 version); + uint16 version); extern bool brin_start_evacuating_page(Relation idxRel, Buffer buf); extern void brin_evacuate_page(Relation idxRel, BlockNumber pagesPerRange, - BrinRevmap *revmap, Buffer buf); + BrinRevmap *revmap, Buffer buf); extern void brin_page_cleanup(Relation idxrel, Buffer buf); diff --git a/src/include/access/brin_revmap.h b/src/include/access/brin_revmap.h index 4dd844888fe..4351dcca1f8 100644 --- a/src/include/access/brin_revmap.h +++ b/src/include/access/brin_revmap.h @@ -2,7 +2,7 @@ * brin_revmap.h * Prototypes for BRIN reverse range maps * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -24,18 +24,18 @@ typedef struct BrinRevmap BrinRevmap; extern BrinRevmap *brinRevmapInitialize(Relation idxrel, - BlockNumber *pagesPerRange, Snapshot snapshot); + BlockNumber *pagesPerRange, Snapshot snapshot); extern void brinRevmapTerminate(BrinRevmap *revmap); extern void brinRevmapExtend(BrinRevmap *revmap, - BlockNumber heapBlk); + BlockNumber heapBlk); extern Buffer brinLockRevmapPageForUpdate(BrinRevmap *revmap, - BlockNumber heapBlk); -extern void brinSetHeapBlockItemptr(Buffer rmbuf, BlockNumber pagesPerRange, - BlockNumber heapBlk, ItemPointerData tid); + BlockNumber heapBlk); +extern void brinSetHeapBlockItemptr(Buffer buf, BlockNumber pagesPerRange, + BlockNumber heapBlk, ItemPointerData tid); extern BrinTuple *brinGetTupleForHeapBlock(BrinRevmap *revmap, - BlockNumber heapBlk, Buffer *buf, OffsetNumber *off, - Size *size, int mode, Snapshot snapshot); + BlockNumber heapBlk, Buffer *buf, OffsetNumber *off, + Size *size, int mode, Snapshot snapshot); extern bool brinRevmapDesummarizeRange(Relation idxrel, BlockNumber heapBlk); #endif /* BRIN_REVMAP_H */ diff --git a/src/include/access/brin_tuple.h b/src/include/access/brin_tuple.h index 2adaf9125e8..474541eba46 100644 --- a/src/include/access/brin_tuple.h +++ b/src/include/access/brin_tuple.h @@ -2,7 +2,7 @@ * brin_tuple.h * Declarations for dealing with BRIN-specific tuples. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -84,19 +84,19 @@ typedef struct BrinTuple extern BrinTuple *brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, - BrinMemTuple *tuple, Size *size); + BrinMemTuple *tuple, Size *size); extern BrinTuple *brin_form_placeholder_tuple(BrinDesc *brdesc, - BlockNumber blkno, Size *size); + BlockNumber blkno, Size *size); extern void brin_free_tuple(BrinTuple *tuple); extern BrinTuple *brin_copy_tuple(BrinTuple *tuple, Size len, - BrinTuple *dest, Size *destsz); + BrinTuple *dest, Size *destsz); extern bool brin_tuples_equal(const BrinTuple *a, Size alen, - const BrinTuple *b, Size blen); + const BrinTuple *b, Size blen); extern BrinMemTuple *brin_new_memtuple(BrinDesc *brdesc); extern BrinMemTuple *brin_memtuple_initialize(BrinMemTuple *dtuple, - BrinDesc *brdesc); + BrinDesc *brdesc); extern BrinMemTuple *brin_deform_tuple(BrinDesc *brdesc, - BrinTuple *tuple, BrinMemTuple *dMemtuple); + BrinTuple *tuple, BrinMemTuple *dMemtuple); #endif /* BRIN_TUPLE_H */ diff --git a/src/include/access/brin_xlog.h b/src/include/access/brin_xlog.h index 40e9772c89a..5583ea71543 100644 --- a/src/include/access/brin_xlog.h +++ b/src/include/access/brin_xlog.h @@ -4,7 +4,7 @@ * POSTGRES BRIN access XLOG definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/brin_xlog.h @@ -77,7 +77,7 @@ typedef struct xl_brin_insert * A cross-page update is the same as an insert, but also stores information * about the old tuple. * - * Like in xlog_brin_update: + * Like in xl_brin_insert: * Backup block 0: new page, block data includes the new BrinTuple. * Backup block 1: revmap page * diff --git a/src/include/access/bufmask.h b/src/include/access/bufmask.h index c00be32ff6a..fce0339d275 100644 --- a/src/include/access/bufmask.h +++ b/src/include/access/bufmask.h @@ -7,7 +7,7 @@ * individual rmgr, but we make things easier by providing some * common routines to handle cases which occur in multiple rmgrs. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/access/bufmask.h * diff --git a/src/include/access/clog.h b/src/include/access/clog.h index 7681ed90aed..90ca61e7f67 100644 --- a/src/include/access/clog.h +++ b/src/include/access/clog.h @@ -3,7 +3,7 @@ * * PostgreSQL transaction-commit-log manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/clog.h @@ -36,7 +36,7 @@ typedef struct xl_clog_truncate } xl_clog_truncate; extern void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, - TransactionId *subxids, XidStatus status, XLogRecPtr lsn); + TransactionId *subxids, XidStatus status, XLogRecPtr lsn); extern XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn); extern Size CLOGShmemBuffers(void); diff --git a/src/include/access/commit_ts.h b/src/include/access/commit_ts.h index 2f40d596959..1433aa3ff7a 100644 --- a/src/include/access/commit_ts.h +++ b/src/include/access/commit_ts.h @@ -3,7 +3,7 @@ * * PostgreSQL commit timestamp manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/commit_ts.h @@ -20,29 +20,29 @@ extern PGDLLIMPORT bool track_commit_timestamp; extern bool check_track_commit_timestamp(bool *newval, void **extra, - GucSource source); + GucSource source); extern void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, - TransactionId *subxids, TimestampTz timestamp, - RepOriginId nodeid, bool write_xlog); + TransactionId *subxids, TimestampTz timestamp, + RepOriginId nodeid, bool write_xlog); extern bool TransactionIdGetCommitTsData(TransactionId xid, - TimestampTz *ts, RepOriginId *nodeid); + TimestampTz *ts, RepOriginId *nodeid); extern TransactionId GetLatestCommitTsData(TimestampTz *ts, - RepOriginId *nodeid); + RepOriginId *nodeid); extern Size CommitTsShmemBuffers(void); extern Size CommitTsShmemSize(void); extern void CommitTsShmemInit(void); extern void BootStrapCommitTs(void); extern void StartupCommitTs(void); -extern void CommitTsParameterChange(bool xlrecvalue, bool pgcontrolvalue); +extern void CommitTsParameterChange(bool newvalue, bool oldvalue); extern void CompleteCommitTsInitialization(void); extern void ShutdownCommitTs(void); extern void CheckPointCommitTs(void); extern void ExtendCommitTs(TransactionId newestXact); extern void TruncateCommitTs(TransactionId oldestXact); extern void SetCommitTsLimit(TransactionId oldestXact, - TransactionId newestXact); + TransactionId newestXact); extern void AdvanceOldestCommitTsXid(TransactionId oldestXact); /* XLOG stuff */ diff --git a/src/include/access/detoast.h b/src/include/access/detoast.h new file mode 100644 index 00000000000..02029a991fd --- /dev/null +++ b/src/include/access/detoast.h @@ -0,0 +1,92 @@ +/*------------------------------------------------------------------------- + * + * detoast.h + * Access to compressed and external varlena values. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * src/include/access/detoast.h + * + *------------------------------------------------------------------------- + */ +#ifndef DETOAST_H +#define DETOAST_H + +/* + * Testing whether an externally-stored value is compressed now requires + * comparing extsize (the actual length of the external data) to rawsize + * (the original uncompressed datum's size). The latter includes VARHDRSZ + * overhead, the former doesn't. We never use compression unless it actually + * saves space, so we expect either equality or less-than. + */ +#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \ + ((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ) + +/* + * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum + * into a local "struct varatt_external" toast pointer. This should be + * just a memcpy, but some versions of gcc seem to produce broken code + * that assumes the datum contents are aligned. Introducing an explicit + * intermediate "varattrib_1b_e *" variable seems to fix it. + */ +#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \ +do { \ + varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \ + Assert(VARATT_IS_EXTERNAL(attre)); \ + Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \ + memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \ +} while (0) + +/* Size of an EXTERNAL datum that contains a standard TOAST pointer */ +#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external)) + +/* Size of an EXTERNAL datum that contains an indirection pointer */ +#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect)) + +/* ---------- + * heap_tuple_fetch_attr() - + * + * Fetches an external stored attribute from the toast + * relation. Does NOT decompress it, if stored external + * in compressed format. + * ---------- + */ +extern struct varlena *heap_tuple_fetch_attr(struct varlena *attr); + +/* ---------- + * heap_tuple_untoast_attr() - + * + * Fully detoasts one attribute, fetching and/or decompressing + * it as needed. + * ---------- + */ +extern struct varlena *heap_tuple_untoast_attr(struct varlena *attr); + +/* ---------- + * heap_tuple_untoast_attr_slice() - + * + * Fetches only the specified portion of an attribute. + * (Handles all cases for attribute storage) + * ---------- + */ +extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena *attr, + int32 sliceoffset, + int32 slicelength); + +/* ---------- + * toast_raw_datum_size - + * + * Return the raw (detoasted) size of a varlena datum + * ---------- + */ +extern Size toast_raw_datum_size(Datum value); + +/* ---------- + * toast_datum_size - + * + * Return the storage size of a varlena datum + * ---------- + */ +extern Size toast_datum_size(Datum value); + +#endif /* DETOAST_H */ diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 24c720bf421..a813b004be7 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -4,7 +4,7 @@ * POSTGRES generalized index access method definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/genam.h @@ -45,6 +45,7 @@ typedef struct IndexVacuumInfo { Relation index; /* the index being vacuumed */ bool analyze_only; /* ANALYZE (without any actual vacuum) */ + bool report_progress; /* emit progress.h status reports */ bool estimated_count; /* num_heap_tuples is an estimate */ int message_level; /* ereport level for progress messages */ double num_heap_tuples; /* tuples remaining in heap */ @@ -117,6 +118,13 @@ typedef enum IndexUniqueCheck } IndexUniqueCheck; +/* Nullable "ORDER BY col op const" distance */ +typedef struct IndexOrderByDistance +{ + double value; + bool isnull; +} IndexOrderByDistance; + /* * generalized index_ interface routines (in indexam.c) */ @@ -131,76 +139,87 @@ extern Relation index_open(Oid relationId, LOCKMODE lockmode); extern void index_close(Relation relation, LOCKMODE lockmode); extern bool index_insert(Relation indexRelation, - Datum *values, bool *isnull, - ItemPointer heap_t_ctid, - Relation heapRelation, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + Datum *values, bool *isnull, + ItemPointer heap_t_ctid, + Relation heapRelation, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern IndexScanDesc index_beginscan(Relation heapRelation, - Relation indexRelation, - Snapshot snapshot, - int nkeys, int norderbys); + Relation indexRelation, + Snapshot snapshot, + int nkeys, int norderbys); extern IndexScanDesc index_beginscan_bitmap(Relation indexRelation, - Snapshot snapshot, - int nkeys); + Snapshot snapshot, + int nkeys); extern void index_rescan(IndexScanDesc scan, - ScanKey keys, int nkeys, - ScanKey orderbys, int norderbys); + ScanKey keys, int nkeys, + ScanKey orderbys, int norderbys); extern void index_endscan(IndexScanDesc scan); extern void index_markpos(IndexScanDesc scan); extern void index_restrpos(IndexScanDesc scan); extern Size index_parallelscan_estimate(Relation indexrel, Snapshot snapshot); extern void index_parallelscan_initialize(Relation heaprel, Relation indexrel, - Snapshot snapshot, ParallelIndexScanDesc target); + Snapshot snapshot, ParallelIndexScanDesc target); extern void index_parallelrescan(IndexScanDesc scan); extern IndexScanDesc index_beginscan_parallel(Relation heaprel, - Relation indexrel, int nkeys, int norderbys, - ParallelIndexScanDesc pscan); + Relation indexrel, int nkeys, int norderbys, + ParallelIndexScanDesc pscan); extern ItemPointer index_getnext_tid(IndexScanDesc scan, - ScanDirection direction); -extern HeapTuple index_fetch_heap(IndexScanDesc scan); -extern HeapTuple index_getnext(IndexScanDesc scan, ScanDirection direction); + ScanDirection direction); +struct TupleTableSlot; +extern bool index_fetch_heap(IndexScanDesc scan, struct TupleTableSlot *slot); +extern bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, + struct TupleTableSlot *slot); extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap); extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *index_vacuum_cleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern bool index_can_return(Relation indexRelation, int attno); extern RegProcedure index_getprocid(Relation irel, AttrNumber attnum, - uint16 procnum); + uint16 procnum); extern FmgrInfo *index_getprocinfo(Relation irel, AttrNumber attnum, - uint16 procnum); + uint16 procnum); +extern void index_store_float8_orderby_distances(IndexScanDesc scan, + Oid *orderByTypes, + IndexOrderByDistance *distances, + bool recheckOrderBy); /* * index access method support routines (in genam.c) */ extern IndexScanDesc RelationGetIndexScan(Relation indexRelation, - int nkeys, int norderbys); + int nkeys, int norderbys); extern void IndexScanEnd(IndexScanDesc scan); extern char *BuildIndexValueDescription(Relation indexRelation, - Datum *values, bool *isnull); + Datum *values, bool *isnull); +extern TransactionId index_compute_xid_horizon_for_tuples(Relation irel, + Relation hrel, + Buffer ibuf, + OffsetNumber *itemnos, + int nitems); /* * heap-or-index access to system catalogs (in genam.c) */ extern SysScanDesc systable_beginscan(Relation heapRelation, - Oid indexId, - bool indexOK, - Snapshot snapshot, - int nkeys, ScanKey key); + Oid indexId, + bool indexOK, + Snapshot snapshot, + int nkeys, ScanKey key); extern HeapTuple systable_getnext(SysScanDesc sysscan); extern bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup); extern void systable_endscan(SysScanDesc sysscan); extern SysScanDesc systable_beginscan_ordered(Relation heapRelation, - Relation indexRelation, - Snapshot snapshot, - int nkeys, ScanKey key); + Relation indexRelation, + Snapshot snapshot, + int nkeys, ScanKey key); extern HeapTuple systable_getnext_ordered(SysScanDesc sysscan, - ScanDirection direction); + ScanDirection direction); extern void systable_endscan_ordered(SysScanDesc sysscan); #endif /* GENAM_H */ diff --git a/src/include/access/generic_xlog.h b/src/include/access/generic_xlog.h index b23e1f684be..129c15cc271 100644 --- a/src/include/access/generic_xlog.h +++ b/src/include/access/generic_xlog.h @@ -4,7 +4,7 @@ * Generic xlog API definition. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/generic_xlog.h @@ -32,7 +32,7 @@ typedef struct GenericXLogState GenericXLogState; /* API for construction of generic xlog records */ extern GenericXLogState *GenericXLogStart(Relation relation); extern Page GenericXLogRegisterBuffer(GenericXLogState *state, Buffer buffer, - int flags); + int flags); extern XLogRecPtr GenericXLogFinish(GenericXLogState *state); extern void GenericXLogAbort(GenericXLogState *state); diff --git a/src/include/access/gin.h b/src/include/access/gin.h index 3d8a130b69b..a8eef5a3795 100644 --- a/src/include/access/gin.h +++ b/src/include/access/gin.h @@ -2,7 +2,7 @@ * gin.h * Public header file for Generalized Inverted Index access method. * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/include/access/gin.h *-------------------------------------------------------------------------- @@ -71,6 +71,7 @@ extern int gin_pending_list_limit; /* ginutil.c */ extern void ginGetStats(Relation index, GinStatsData *stats); -extern void ginUpdateStats(Relation index, const GinStatsData *stats); +extern void ginUpdateStats(Relation index, const GinStatsData *stats, + bool is_build); #endif /* GIN_H */ diff --git a/src/include/access/gin_private.h b/src/include/access/gin_private.h index d1df3033a6d..78fcd826f18 100644 --- a/src/include/access/gin_private.h +++ b/src/include/access/gin_private.h @@ -2,7 +2,7 @@ * gin_private.h * header file for postgres inverted index access method implementation. * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/include/access/gin_private.h *-------------------------------------------------------------------------- @@ -54,7 +54,7 @@ typedef struct GinState bool oneCol; /* true if single-column index */ /* - * origTupDesc is the nominal tuple descriptor of the index, ie, the i'th + * origTupdesc is the nominal tuple descriptor of the index, ie, the i'th * attribute shows the key type (not the input data type!) of the i'th * index column. In a single-column index this describes the actual leaf * index tuples. In a multi-column index, the actual leaf tuples contain @@ -90,34 +90,32 @@ extern Buffer GinNewBuffer(Relation index); extern void GinInitBuffer(Buffer b, uint32 f); extern void GinInitPage(Page page, uint32 f, Size pageSize); extern void GinInitMetabuffer(Buffer b); -extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, - Datum a, GinNullCategory categorya, - Datum b, GinNullCategory categoryb); -extern int ginCompareAttEntries(GinState *ginstate, - OffsetNumber attnuma, Datum a, GinNullCategory categorya, - OffsetNumber attnumb, Datum b, GinNullCategory categoryb); +extern int ginCompareEntries(GinState *ginstate, OffsetNumber attnum, + Datum a, GinNullCategory categorya, + Datum b, GinNullCategory categoryb); +extern int ginCompareAttEntries(GinState *ginstate, + OffsetNumber attnuma, Datum a, GinNullCategory categorya, + OffsetNumber attnumb, Datum b, GinNullCategory categoryb); extern Datum *ginExtractEntries(GinState *ginstate, OffsetNumber attnum, - Datum value, bool isNull, - int32 *nentries, GinNullCategory **categories); + Datum value, bool isNull, + int32 *nentries, GinNullCategory **categories); extern OffsetNumber gintuple_get_attrnum(GinState *ginstate, IndexTuple tuple); extern Datum gintuple_get_key(GinState *ginstate, IndexTuple tuple, - GinNullCategory *category); -extern void GinCheckForSerializableConflictIn(Relation relation, - HeapTuple tuple, Buffer buffer); + GinNullCategory *category); /* gininsert.c */ extern IndexBuildResult *ginbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void ginbuildempty(Relation index); extern bool gininsert(Relation index, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern void ginEntryInsert(GinState *ginstate, - OffsetNumber attnum, Datum key, GinNullCategory category, - ItemPointerData *items, uint32 nitem, - GinStatsData *buildStats); + OffsetNumber attnum, Datum key, GinNullCategory category, + ItemPointerData *items, uint32 nitem, + GinStatsData *buildStats); /* ginbtree.c */ @@ -197,37 +195,37 @@ typedef struct * PostingItem */ -extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode, Snapshot snapshot); +extern GinBtreeStack *ginFindLeafPage(GinBtree btree, bool searchMode, + bool rootConflictCheck, Snapshot snapshot); extern Buffer ginStepRight(Buffer buffer, Relation index, int lockmode); extern void freeGinBtreeStack(GinBtreeStack *stack); extern void ginInsertValue(GinBtree btree, GinBtreeStack *stack, - void *insertdata, GinStatsData *buildStats); + void *insertdata, GinStatsData *buildStats); /* ginentrypage.c */ extern IndexTuple GinFormTuple(GinState *ginstate, - OffsetNumber attnum, Datum key, GinNullCategory category, - Pointer data, Size dataSize, int nipd, bool errorTooBig); + OffsetNumber attnum, Datum key, GinNullCategory category, + Pointer data, Size dataSize, int nipd, bool errorTooBig); extern void ginPrepareEntryScan(GinBtree btree, OffsetNumber attnum, - Datum key, GinNullCategory category, - GinState *ginstate); + Datum key, GinNullCategory category, + GinState *ginstate); extern void ginEntryFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); extern ItemPointer ginReadTuple(GinState *ginstate, OffsetNumber attnum, - IndexTuple itup, int *nitems); + IndexTuple itup, int *nitems); /* gindatapage.c */ extern ItemPointer GinDataLeafPageGetItems(Page page, int *nitems, ItemPointerData advancePast); extern int GinDataLeafPageGetItemsToTbm(Page page, TIDBitmap *tbm); extern BlockNumber createPostingTree(Relation index, - ItemPointerData *items, uint32 nitems, - GinStatsData *buildStats, Buffer entrybuffer); + ItemPointerData *items, uint32 nitems, + GinStatsData *buildStats, Buffer entrybuffer); extern void GinDataPageAddPostingItem(Page page, PostingItem *data, OffsetNumber offset); extern void GinPageDeletePostingItem(Page page, OffsetNumber offset); extern void ginInsertItemPointers(Relation index, BlockNumber rootBlkno, - ItemPointerData *items, uint32 nitem, - GinStatsData *buildStats); + ItemPointerData *items, uint32 nitem, + GinStatsData *buildStats); extern GinBtreeStack *ginScanBeginPostingTree(GinBtree btree, Relation index, BlockNumber rootBlkno, Snapshot snapshot); extern void ginDataFillRoot(GinBtree btree, Page root, BlockNumber lblkno, Page lpage, BlockNumber rblkno, Page rpage); -extern void ginPrepareDataScan(GinBtree btree, Relation index, BlockNumber rootBlkno); /* * This is declared in ginvacuum.c, but is passed between ginVacuumItemPointers @@ -368,7 +366,7 @@ typedef GinScanOpaqueData *GinScanOpaque; extern IndexScanDesc ginbeginscan(Relation rel, int nkeys, int norderbys); extern void ginendscan(IndexScanDesc scan); extern void ginrescan(IndexScanDesc scan, ScanKey key, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void ginNewScanKey(IndexScanDesc scan); extern void ginFreeScanKeys(GinScanOpaque so); @@ -380,13 +378,13 @@ extern void ginInitConsistentFunction(GinState *ginstate, GinScanKey key); /* ginvacuum.c */ extern IndexBulkDeleteResult *ginbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *ginvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern ItemPointer ginVacuumItemPointers(GinVacuumState *gvs, - ItemPointerData *items, int nitem, int *nremaining); + ItemPointerData *items, int nitem, int *nremaining); /* ginvalidate.c */ extern bool ginvalidate(Oid opclassoid); @@ -394,7 +392,7 @@ extern bool ginvalidate(Oid opclassoid); /* ginbulk.c */ typedef struct GinEntryAccumulator { - RBNode rbnode; + RBTNode rbtnode; Datum key; GinNullCategory category; OffsetNumber attnum; @@ -416,13 +414,13 @@ typedef struct extern void ginInitBA(BuildAccumulator *accum); extern void ginInsertBAEntries(BuildAccumulator *accum, - ItemPointer heapptr, OffsetNumber attnum, - Datum *entries, GinNullCategory *categories, - int32 nentries); + ItemPointer heapptr, OffsetNumber attnum, + Datum *entries, GinNullCategory *categories, + int32 nentries); extern void ginBeginBAScan(BuildAccumulator *accum); extern ItemPointerData *ginGetBAEntry(BuildAccumulator *accum, - OffsetNumber *attnum, Datum *key, GinNullCategory *category, - uint32 *n); + OffsetNumber *attnum, Datum *key, GinNullCategory *category, + uint32 *n); /* ginfast.c */ @@ -435,25 +433,25 @@ typedef struct GinTupleCollector } GinTupleCollector; extern void ginHeapTupleFastInsert(GinState *ginstate, - GinTupleCollector *collector); + GinTupleCollector *collector); extern void ginHeapTupleFastCollect(GinState *ginstate, - GinTupleCollector *collector, - OffsetNumber attnum, Datum value, bool isNull, - ItemPointer ht_ctid); + GinTupleCollector *collector, + OffsetNumber attnum, Datum value, bool isNull, + ItemPointer ht_ctid); extern void ginInsertCleanup(GinState *ginstate, bool full_clean, - bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats); + bool fill_fsm, bool forceCleanup, IndexBulkDeleteResult *stats); /* ginpostinglist.c */ -extern GinPostingList *ginCompressPostingList(const ItemPointer ptrs, int nptrs, - int maxsize, int *nwritten); +extern GinPostingList *ginCompressPostingList(const ItemPointer ipd, int nipd, + int maxsize, int *nwritten); extern int ginPostingListDecodeAllSegmentsToTbm(GinPostingList *ptr, int totalsize, TIDBitmap *tbm); extern ItemPointer ginPostingListDecodeAllSegments(GinPostingList *ptr, int len, int *ndecoded); extern ItemPointer ginPostingListDecode(GinPostingList *ptr, int *ndecoded); extern ItemPointer ginMergeItemPointers(ItemPointerData *a, uint32 na, - ItemPointerData *b, uint32 nb, - int *nmerged); + ItemPointerData *b, uint32 nb, + int *nmerged); /* * Merging the results of several gin scans compares item pointers a lot, diff --git a/src/include/access/ginblock.h b/src/include/access/ginblock.h index 553566529a4..e7d49b152eb 100644 --- a/src/include/access/ginblock.h +++ b/src/include/access/ginblock.h @@ -2,7 +2,7 @@ * ginblock.h * details of structures stored in GIN index blocks * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/include/access/ginblock.h *-------------------------------------------------------------------------- @@ -10,6 +10,7 @@ #ifndef GINBLOCK_H #define GINBLOCK_H +#include "access/transam.h" #include "storage/block.h" #include "storage/itemptr.h" #include "storage/off.h" @@ -127,6 +128,15 @@ typedef struct GinMetaPageData #define GinPageRightMost(page) ( GinPageGetOpaque(page)->rightlink == InvalidBlockNumber) +/* + * We should reclaim deleted page only once every transaction started before + * its deletion is over. + */ +#define GinPageGetDeleteXid(page) ( ((PageHeader) (page))->pd_prune_xid ) +#define GinPageSetDeleteXid(page, xid) ( ((PageHeader) (page))->pd_prune_xid = xid) +#define GinPageIsRecyclable(page) ( PageIsNew(page) || (GinPageIsDeleted(page) \ + && TransactionIdPrecedes(GinPageGetDeleteXid(page), RecentGlobalXmin))) + /* * We use our own ItemPointerGet(BlockNumber|OffsetNumber) * to avoid Asserts, since sometimes the ip_posid isn't "valid" @@ -161,9 +171,6 @@ typedef struct GinMetaPageData GinItemPointerGetBlockNumber(p) == (BlockNumber)0) #define ItemPointerSetMax(p) \ ItemPointerSet((p), InvalidBlockNumber, (OffsetNumber)0xffff) -#define ItemPointerIsMax(p) \ - (GinItemPointerGetOffsetNumber(p) == (OffsetNumber)0xffff && \ - GinItemPointerGetBlockNumber(p) == InvalidBlockNumber) #define ItemPointerSetLossyPage(p, b) \ ItemPointerSet((p), (b), (OffsetNumber)0xffff) #define ItemPointerIsLossyPage(p) \ diff --git a/src/include/access/ginxlog.h b/src/include/access/ginxlog.h index 64a3c9e18b4..7ef3bcf7658 100644 --- a/src/include/access/ginxlog.h +++ b/src/include/access/ginxlog.h @@ -2,7 +2,7 @@ * ginxlog.h * header file for postgres inverted index xlog implementation. * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/include/access/ginxlog.h *-------------------------------------------------------------------------- @@ -16,8 +16,6 @@ #include "lib/stringinfo.h" #include "storage/off.h" -#define XLOG_GIN_CREATE_INDEX 0x00 - #define XLOG_GIN_CREATE_PTREE 0x10 typedef struct ginxlogCreatePostingTree @@ -129,7 +127,7 @@ typedef struct ginxlogSplit /* * Vacuum simply WAL-logs the whole page, when anything is modified. This - * is functionally identical to heap_newpage records, but is kept separate for + * is functionally identical to XLOG_FPI records, but is kept separate for * debugging purposes. (When inspecting the WAL stream, it's easier to see * what's going on when GIN vacuum records are marked as such, not as heap * records.) This is currently only used for entry tree leaf pages. @@ -158,6 +156,7 @@ typedef struct ginxlogDeletePage { OffsetNumber parentOffset; BlockNumber rightLink; + TransactionId deleteXid; /* last Xid which could see this page in scan */ } ginxlogDeletePage; #define XLOG_GIN_UPDATE_META_PAGE 0x60 diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 827566dc6e7..8292956cc09 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -6,7 +6,7 @@ * changes should be made with care. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gist.h @@ -16,6 +16,7 @@ #ifndef GIST_H #define GIST_H +#include "access/transam.h" #include "access/xlog.h" #include "access/xlogdefs.h" #include "storage/block.h" @@ -49,6 +50,13 @@ typedef XLogRecPtr GistNSN; +/* + * A bogus LSN / NSN value used during index build. Must be smaller than any + * real or fake unlogged LSN, so that after an index build finishes, all the + * splits are considered completed. + */ +#define GistBuildLSN ((XLogRecPtr) 1) + /* * For on-disk compatibility with pre-9.3 servers, NSN is stored as two * 32-bit fields on disk, same as LSNs. @@ -133,8 +141,6 @@ typedef struct GISTENTRY #define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page)) #define GistPageIsDeleted(page) ( GistPageGetOpaque(page)->flags & F_DELETED) -#define GistPageSetDeleted(page) ( GistPageGetOpaque(page)->flags |= F_DELETED) -#define GistPageSetNonDeleted(page) ( GistPageGetOpaque(page)->flags &= ~F_DELETED) #define GistTuplesDeleted(page) ( GistPageGetOpaque(page)->flags & F_TUPLES_DELETED) #define GistMarkTuplesDeleted(page) ( GistPageGetOpaque(page)->flags |= F_TUPLES_DELETED) @@ -151,6 +157,46 @@ typedef struct GISTENTRY #define GistPageGetNSN(page) ( PageXLogRecPtrGet(GistPageGetOpaque(page)->nsn)) #define GistPageSetNSN(page, val) ( PageXLogRecPtrSet(GistPageGetOpaque(page)->nsn, val)) + +/* + * On a deleted page, we store this struct. A deleted page doesn't contain any + * tuples, so we don't use the normal page layout with line pointers. Instead, + * this struct is stored right after the standard page header. pd_lower points + * to the end of this struct. If we add fields to this struct in the future, we + * can distinguish the old and new formats by pd_lower. + */ +typedef struct GISTDeletedPageContents +{ + /* last xid which could see the page in a scan */ + FullTransactionId deleteXid; +} GISTDeletedPageContents; + +static inline void +GistPageSetDeleted(Page page, FullTransactionId deletexid) +{ + Assert(PageIsEmpty(page)); + + GistPageGetOpaque(page)->flags |= F_DELETED; + ((PageHeader) page)->pd_lower = MAXALIGN(SizeOfPageHeaderData) + sizeof(GISTDeletedPageContents); + + ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid = deletexid; +} + +static inline FullTransactionId +GistPageGetDeleteXid(Page page) +{ + Assert(GistPageIsDeleted(page)); + + /* Is the deleteXid field present? */ + if (((PageHeader) page)->pd_lower >= MAXALIGN(SizeOfPageHeaderData) + + offsetof(GISTDeletedPageContents, deleteXid) + sizeof(FullTransactionId)) + { + return ((GISTDeletedPageContents *) PageGetContents(page))->deleteXid; + } + else + return FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId); +} + /* * Vector of GISTENTRY structs; user-defined methods union and picksplit * take it as one of their arguments diff --git a/src/include/access/gist_private.h b/src/include/access/gist_private.h index 36ed7244ba0..a409975db16 100644 --- a/src/include/access/gist_private.h +++ b/src/include/access/gist_private.h @@ -4,7 +4,7 @@ * private declarations for GiST -- declarations related to the * internal implementation of GiST, not the public API * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gist_private.h @@ -17,7 +17,6 @@ #include "access/amapi.h" #include "access/gist.h" #include "access/itup.h" -#include "fmgr.h" #include "lib/pairingheap.h" #include "storage/bufmgr.h" #include "storage/buffile.h" @@ -78,7 +77,9 @@ typedef struct GISTSTATE MemoryContext scanCxt; /* context for scan-lifespan data */ MemoryContext tempCxt; /* short-term context for calling functions */ - TupleDesc tupdesc; /* index's tuple descriptor */ + TupleDesc leafTupdesc; /* index's tuple descriptor */ + TupleDesc nonLeafTupdesc; /* truncated tuple descriptor for non-leaf + * pages */ TupleDesc fetchTupdesc; /* tuple descriptor for tuples returned in an * index-only scan */ @@ -136,13 +137,16 @@ typedef struct GISTSearchItem /* we must store parentlsn to detect whether a split occurred */ GISTSearchHeapItem heap; /* heap info, if heap tuple */ } data; - double distances[FLEXIBLE_ARRAY_MEMBER]; /* numberOfOrderBys - * entries */ + + /* numberOfOrderBys entries */ + IndexOrderByDistance distances[FLEXIBLE_ARRAY_MEMBER]; } GISTSearchItem; #define GISTSearchItemIsHeap(item) ((item).blkno == InvalidBlockNumber) -#define SizeOfGISTSearchItem(n_distances) (offsetof(GISTSearchItem, distances) + sizeof(double) * (n_distances)) +#define SizeOfGISTSearchItem(n_distances) \ + (offsetof(GISTSearchItem, distances) + \ + sizeof(IndexOrderByDistance) * (n_distances)) /* * GISTScanOpaqueData: private state for a scan of a GiST index @@ -158,7 +162,7 @@ typedef struct GISTScanOpaqueData bool firstCall; /* true until first gistgettuple call */ /* pre-allocated workspace arrays */ - double *distances; /* output area for gistindex_keytest */ + IndexOrderByDistance *distances; /* output area for gistindex_keytest */ /* info about killed items if any (killedItems is NULL if never used) */ OffsetNumber *killedItems; /* offset numbers of killed items */ @@ -213,6 +217,13 @@ typedef struct GISTInsertStack */ GistNSN lsn; + /* + * If set, we split the page while descending the tree to find an + * insertion target. It means that we need to retry from the parent, + * because the downlink of this page might no longer cover the new key. + */ + bool retry_from_parent; + /* offset of the downlink in the parent page, that points to this page */ OffsetNumber downlinkoffnum; @@ -240,7 +251,9 @@ typedef struct GistSplitVector typedef struct { Relation r; + Relation heapRel; Size freespace; /* free space to be left */ + bool is_build; GISTInsertStack *stack; } GISTInsertState; @@ -367,6 +380,14 @@ typedef struct GISTBuildBuffers int rootlevel; } GISTBuildBuffers; +/* GiSTOptions->buffering_mode values */ +typedef enum GistOptBufferingMode +{ + GIST_OPTION_BUFFERING_AUTO, + GIST_OPTION_BUFFERING_ON, + GIST_OPTION_BUFFERING_OFF +} GistOptBufferingMode; + /* * Storage type for GiST's reloptions */ @@ -374,22 +395,24 @@ typedef struct GiSTOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ int fillfactor; /* page fill factor in percent (0..100) */ - int bufferingModeOffset; /* use buffering build? */ + GistOptBufferingMode buffering_mode; /* buffering build mode */ } GiSTOptions; /* gist.c */ extern void gistbuildempty(Relation index); extern bool gistinsert(Relation r, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern MemoryContext createTempGistContext(void); extern GISTSTATE *initGISTstate(Relation index); extern void freeGISTstate(GISTSTATE *giststate); extern void gistdoinsert(Relation r, - IndexTuple itup, - Size freespace, - GISTSTATE *GISTstate); + IndexTuple itup, + Size freespace, + GISTSTATE *giststate, + Relation heapRel, + bool is_build); /* A List of these is returned from gistplacetopage() in *splitinfo */ typedef struct @@ -399,25 +422,38 @@ typedef struct } GISTPageSplitInfo; extern bool gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, - Buffer buffer, - IndexTuple *itup, int ntup, - OffsetNumber oldoffnum, BlockNumber *newblkno, - Buffer leftchildbuf, - List **splitinfo, - bool markleftchild); + Buffer buffer, + IndexTuple *itup, int ntup, + OffsetNumber oldoffnum, BlockNumber *newblkno, + Buffer leftchildbuf, + List **splitinfo, + bool markfollowright, + Relation heapRel, + bool is_build); extern SplitedPageLayout *gistSplit(Relation r, Page page, IndexTuple *itup, - int len, GISTSTATE *giststate); + int len, GISTSTATE *giststate); + +/* gistxlog.c */ +extern XLogRecPtr gistXLogPageDelete(Buffer buffer, + FullTransactionId xid, Buffer parentBuffer, + OffsetNumber downlinkOffset); + +extern void gistXLogPageReuse(Relation rel, BlockNumber blkno, + FullTransactionId latestRemovedXid); extern XLogRecPtr gistXLogUpdate(Buffer buffer, - OffsetNumber *todelete, int ntodelete, - IndexTuple *itup, int ntup, - Buffer leftchild); + OffsetNumber *todelete, int ntodelete, + IndexTuple *itup, int ntup, + Buffer leftchild); + +extern XLogRecPtr gistXLogDelete(Buffer buffer, OffsetNumber *todelete, + int ntodelete, TransactionId latestRemovedXid); extern XLogRecPtr gistXLogSplit(bool page_is_leaf, - SplitedPageLayout *dist, - BlockNumber origrlink, GistNSN oldnsn, - Buffer leftchild, bool markfollowright); + SplitedPageLayout *dist, + BlockNumber origrlink, GistNSN oldnsn, + Buffer leftchild, bool markfollowright); /* gistget.c */ extern bool gistgettuple(IndexScanDesc scan, ScanDirection dir); @@ -437,89 +473,89 @@ extern bool gistvalidate(Oid opclassoid); extern bytea *gistoptions(Datum reloptions, bool validate); extern bool gistproperty(Oid index_oid, int attno, - IndexAMProperty prop, const char *propname, - bool *res, bool *isnull); + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); extern bool gistfitpage(IndexTuple *itvec, int len); extern bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace); extern void gistcheckpage(Relation rel, Buffer buf); extern Buffer gistNewBuffer(Relation r); +extern bool gistPageRecyclable(Page page); extern void gistfillbuffer(Page page, IndexTuple *itup, int len, - OffsetNumber off); + OffsetNumber off); extern IndexTuple *gistextractpage(Page page, int *len /* out */ ); -extern IndexTuple *gistjoinvector( - IndexTuple *itvec, int *len, - IndexTuple *additvec, int addlen); +extern IndexTuple *gistjoinvector(IndexTuple *itvec, int *len, + IndexTuple *additvec, int addlen); extern IndexTupleData *gistfillitupvec(IndexTuple *vec, int veclen, int *memlen); extern IndexTuple gistunion(Relation r, IndexTuple *itvec, - int len, GISTSTATE *giststate); + int len, GISTSTATE *giststate); extern IndexTuple gistgetadjusted(Relation r, - IndexTuple oldtup, - IndexTuple addtup, - GISTSTATE *giststate); + IndexTuple oldtup, + IndexTuple addtup, + GISTSTATE *giststate); extern IndexTuple gistFormTuple(GISTSTATE *giststate, - Relation r, Datum *attdata, bool *isnull, bool isleaf); + Relation r, Datum *attdata, bool *isnull, bool isleaf); extern OffsetNumber gistchoose(Relation r, Page p, - IndexTuple it, - GISTSTATE *giststate); + IndexTuple it, + GISTSTATE *giststate); extern void GISTInitBuffer(Buffer b, uint32 f); extern void gistdentryinit(GISTSTATE *giststate, int nkey, GISTENTRY *e, - Datum k, Relation r, Page pg, OffsetNumber o, - bool l, bool isNull); + Datum k, Relation r, Page pg, OffsetNumber o, + bool l, bool isNull); extern float gistpenalty(GISTSTATE *giststate, int attno, - GISTENTRY *key1, bool isNull1, - GISTENTRY *key2, bool isNull2); + GISTENTRY *key1, bool isNull1, + GISTENTRY *key2, bool isNull2); extern void gistMakeUnionItVec(GISTSTATE *giststate, IndexTuple *itvec, int len, - Datum *attr, bool *isnull); + Datum *attr, bool *isnull); extern bool gistKeyIsEQ(GISTSTATE *giststate, int attno, Datum a, Datum b); extern void gistDeCompressAtt(GISTSTATE *giststate, Relation r, IndexTuple tuple, Page p, - OffsetNumber o, GISTENTRY *attdata, bool *isnull); + OffsetNumber o, GISTENTRY *attdata, bool *isnull); extern HeapTuple gistFetchTuple(GISTSTATE *giststate, Relation r, - IndexTuple tuple); + IndexTuple tuple); extern void gistMakeUnionKey(GISTSTATE *giststate, int attno, - GISTENTRY *entry1, bool isnull1, - GISTENTRY *entry2, bool isnull2, - Datum *dst, bool *dstisnull); + GISTENTRY *entry1, bool isnull1, + GISTENTRY *entry2, bool isnull2, + Datum *dst, bool *dstisnull); extern XLogRecPtr gistGetFakeLSN(Relation rel); /* gistvacuum.c */ extern IndexBulkDeleteResult *gistbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *gistvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); /* gistsplit.c */ extern void gistSplitByKey(Relation r, Page page, IndexTuple *itup, - int len, GISTSTATE *giststate, - GistSplitVector *v, - int attno); + int len, GISTSTATE *giststate, + GistSplitVector *v, + int attno); /* gistbuild.c */ extern IndexBuildResult *gistbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void gistValidateBufferingOption(const char *value); /* gistbuildbuffers.c */ extern GISTBuildBuffers *gistInitBuildBuffers(int pagesPerBuffer, int levelStep, - int maxLevel); + int maxLevel); extern GISTNodeBuffer *gistGetNodeBuffer(GISTBuildBuffers *gfbb, - GISTSTATE *giststate, - BlockNumber blkno, int level); + GISTSTATE *giststate, + BlockNumber blkno, int level); extern void gistPushItupToNodeBuffer(GISTBuildBuffers *gfbb, - GISTNodeBuffer *nodeBuffer, IndexTuple item); + GISTNodeBuffer *nodeBuffer, IndexTuple item); extern bool gistPopItupFromNodeBuffer(GISTBuildBuffers *gfbb, - GISTNodeBuffer *nodeBuffer, IndexTuple *item); + GISTNodeBuffer *nodeBuffer, IndexTuple *item); extern void gistFreeBuildBuffers(GISTBuildBuffers *gfbb); extern void gistRelocateBuildBuffersOnSplit(GISTBuildBuffers *gfbb, - GISTSTATE *giststate, Relation r, - int level, Buffer buffer, - List *splitinfo); + GISTSTATE *giststate, Relation r, + int level, Buffer buffer, + List *splitinfo); extern void gistUnloadNodeBuffers(GISTBuildBuffers *gfbb); #endif /* GIST_PRIVATE_H */ diff --git a/src/include/access/gistscan.h b/src/include/access/gistscan.h index e04409afc05..c02445a6980 100644 --- a/src/include/access/gistscan.h +++ b/src/include/access/gistscan.h @@ -4,7 +4,7 @@ * routines defined in access/gist/gistscan.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gistscan.h @@ -18,7 +18,7 @@ extern IndexScanDesc gistbeginscan(Relation r, int nkeys, int norderbys); extern void gistrescan(IndexScanDesc scan, ScanKey key, int nkeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void gistendscan(IndexScanDesc scan); #endif /* GISTSCAN_H */ diff --git a/src/include/access/gistxlog.h b/src/include/access/gistxlog.h index 1a2b9496d0d..e44922d915c 100644 --- a/src/include/access/gistxlog.h +++ b/src/include/access/gistxlog.h @@ -3,7 +3,7 @@ * gistxlog.h * gist xlog routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/gistxlog.h @@ -18,11 +18,14 @@ #include "lib/stringinfo.h" #define XLOG_GIST_PAGE_UPDATE 0x00 - /* #define XLOG_GIST_NEW_ROOT 0x20 */ /* not used anymore */ +#define XLOG_GIST_DELETE 0x10 /* delete leaf index tuples for a + * page */ +#define XLOG_GIST_PAGE_REUSE 0x20 /* old page is about to be reused + * from FSM */ #define XLOG_GIST_PAGE_SPLIT 0x30 /* #define XLOG_GIST_INSERT_COMPLETE 0x40 */ /* not used anymore */ -#define XLOG_GIST_CREATE_INDEX 0x50 - /* #define XLOG_GIST_PAGE_DELETE 0x60 */ /* not used anymore */ + /* #define XLOG_GIST_CREATE_INDEX 0x50 */ /* not used anymore */ +#define XLOG_GIST_PAGE_DELETE 0x60 /* * Backup Blk 0: updated page. @@ -40,6 +43,21 @@ typedef struct gistxlogPageUpdate */ } gistxlogPageUpdate; +/* + * Backup Blk 0: Leaf page, whose index tuples are deleted. + */ +typedef struct gistxlogDelete +{ + TransactionId latestRemovedXid; + uint16 ntodelete; /* number of deleted offsets */ + + /* + * In payload of blk 0 : todelete OffsetNumbers + */ +} gistxlogDelete; + +#define SizeOfGistxlogDelete (offsetof(gistxlogDelete, ntodelete) + sizeof(uint16)) + /* * Backup Blk 0: If this operation completes a page split, by inserting a * downlink for the split page, the left half of the split @@ -59,6 +77,32 @@ typedef struct gistxlogPageSplit */ } gistxlogPageSplit; +/* + * Backup Blk 0: page that was deleted. + * Backup Blk 1: parent page, containing the downlink to the deleted page. + */ +typedef struct gistxlogPageDelete +{ + FullTransactionId deleteXid; /* last Xid which could see page in scan */ + OffsetNumber downlinkOffset; /* Offset of downlink referencing this + * page */ +} gistxlogPageDelete; + +#define SizeOfGistxlogPageDelete (offsetof(gistxlogPageDelete, downlinkOffset) + sizeof(OffsetNumber)) + + +/* + * This is what we need to know about page reuse, for hot standby. + */ +typedef struct gistxlogPageReuse +{ + RelFileNode node; + BlockNumber block; + FullTransactionId latestRemovedFullXid; +} gistxlogPageReuse; + +#define SizeOfGistxlogPageReuse (offsetof(gistxlogPageReuse, latestRemovedFullXid) + sizeof(FullTransactionId)) + extern void gist_redo(XLogReaderState *record); extern void gist_desc(StringInfo buf, XLogReaderState *record); extern const char *gist_identify(uint8 info); diff --git a/src/include/access/hash.h b/src/include/access/hash.h index d6c306e9695..24af778fdf8 100644 --- a/src/include/access/hash.h +++ b/src/include/access/hash.h @@ -4,7 +4,7 @@ * header file for postgres hash access method implementation * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/hash.h @@ -20,10 +20,10 @@ #include "access/amapi.h" #include "access/itup.h" #include "access/sdir.h" -#include "fmgr.h" #include "lib/stringinfo.h" #include "storage/bufmgr.h" #include "storage/lockdefs.h" +#include "utils/hashutils.h" #include "utils/hsearch.h" #include "utils/relcache.h" @@ -38,17 +38,6 @@ typedef uint32 Bucket; #define BUCKET_TO_BLKNO(metap,B) \ ((BlockNumber) ((B) + ((B) ? (metap)->hashm_spares[_hash_spareindex((B)+1)-1] : 0)) + 1) -/* - * Rotate the high 32 bits and the low 32 bits separately. The standard - * hash function sometimes rotates the low 32 bits by one bit when - * combining elements. We want extended hash functions to be compatible with - * that algorithm when the seed is 0, so we can't just do a normal rotation. - * This works, though. - */ -#define ROTATE_HIGH_AND_LOW_32BITS(v) \ - ((((v) << 1) & UINT64CONST(0xfffffffefffffffe)) | \ - (((v) >> 31) & UINT64CONST(0x100000001))) - /* * Special space for hash index pages. * @@ -230,9 +219,12 @@ typedef HashScanOpaqueData *HashScanOpaque; * * There is no particular upper limit on the size of mapp[], other than * needing to fit into the metapage. (With 8K block size, 1024 bitmaps - * limit us to 256 GB of overflow space...) + * limit us to 256 GB of overflow space...). For smaller block size we + * can not use 1024 bitmaps as it will lead to the meta page data crossing + * the block size boundary. So we use BLCKSZ to determine the maximum number + * of bitmaps. */ -#define HASH_MAX_BITMAPS 1024 +#define HASH_MAX_BITMAPS Min(BLCKSZ / 8, 1024) #define HASH_SPLITPOINT_PHASE_BITS 2 #define HASH_SPLITPOINT_PHASES_PER_GRP (1 << HASH_SPLITPOINT_PHASE_BITS) @@ -259,11 +251,11 @@ typedef struct HashMetaPageData uint32 hashm_maxbucket; /* ID of maximum bucket in use */ uint32 hashm_highmask; /* mask to modulo into entire table */ uint32 hashm_lowmask; /* mask to modulo into lower half of table */ - uint32 hashm_ovflpoint; /* splitpoint from which ovflpgs being + uint32 hashm_ovflpoint; /* splitpoint from which ovflpage being * allocated */ uint32 hashm_firstfree; /* lowest-number free ovflpage (bit#) */ uint32 hashm_nmaps; /* number of bitmap pages */ - RegProcedure hashm_procid; /* hash procedure id from pg_proc */ + RegProcedure hashm_procid; /* hash function id from pg_proc */ uint32 hashm_spares[HASH_MAX_SPLITPOINTS]; /* spare pages before each * splitpoint */ BlockNumber hashm_mapp[HASH_MAX_BITMAPS]; /* blknos of ovfl bitmaps */ @@ -330,23 +322,17 @@ typedef HashMetaPageData *HashMetaPage; #define HASH_WRITE BUFFER_LOCK_EXCLUSIVE #define HASH_NOLOCK (-1) -/* - * Strategy number. There's only one valid strategy for hashing: equality. - */ -#define HTEqualStrategyNumber 1 -#define HTMaxStrategyNumber 1 - /* * When a new operator class is declared, we require that the user supply - * us with an amproc procedure for hashing a key of the new type, returning - * a 32-bit hash value. We call this the "standard" hash procedure. We - * also allow an optional "extended" hash procedure which accepts a salt and + * us with an amproc function for hashing a key of the new type, returning + * a 32-bit hash value. We call this the "standard" hash function. We + * also allow an optional "extended" hash function which accepts a salt and * returns a 64-bit hash value. This is highly recommended but, for reasons * of backward compatibility, optional. * * When the salt is 0, the low 32 bits of the value returned by the extended - * hash procedure should match the value that would have been returned by the - * standard hash procedure. + * hash function should match the value that would have been returned by the + * standard hash function. */ #define HASHSTANDARD_PROC 1 #define HASHEXTENDED_PROC 2 @@ -356,84 +342,78 @@ typedef HashMetaPageData *HashMetaPage; /* public routines */ extern IndexBuildResult *hashbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void hashbuildempty(Relation index); extern bool hashinsert(Relation rel, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern bool hashgettuple(IndexScanDesc scan, ScanDirection dir); extern int64 hashgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern IndexScanDesc hashbeginscan(Relation rel, int nkeys, int norderbys); extern void hashrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void hashendscan(IndexScanDesc scan); extern IndexBulkDeleteResult *hashbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *hashvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern bytea *hashoptions(Datum reloptions, bool validate); extern bool hashvalidate(Oid opclassoid); -extern Datum hash_any(register const unsigned char *k, register int keylen); -extern Datum hash_any_extended(register const unsigned char *k, - register int keylen, uint64 seed); -extern Datum hash_uint32(uint32 k); -extern Datum hash_uint32_extended(uint32 k, uint64 seed); - /* private routines */ /* hashinsert.c */ extern void _hash_doinsert(Relation rel, IndexTuple itup, Relation heapRel); extern OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf, - Size itemsize, IndexTuple itup); + Size itemsize, IndexTuple itup); extern void _hash_pgaddmultitup(Relation rel, Buffer buf, IndexTuple *itups, - OffsetNumber *itup_offsets, uint16 nitups); + OffsetNumber *itup_offsets, uint16 nitups); /* hashovfl.c */ extern Buffer _hash_addovflpage(Relation rel, Buffer metabuf, Buffer buf, bool retain_pin); extern BlockNumber _hash_freeovflpage(Relation rel, Buffer bucketbuf, Buffer ovflbuf, - Buffer wbuf, IndexTuple *itups, OffsetNumber *itup_offsets, - Size *tups_size, uint16 nitups, BufferAccessStrategy bstrategy); + Buffer wbuf, IndexTuple *itups, OffsetNumber *itup_offsets, + Size *tups_size, uint16 nitups, BufferAccessStrategy bstrategy); extern void _hash_initbitmapbuffer(Buffer buf, uint16 bmsize, bool initpage); extern void _hash_squeezebucket(Relation rel, - Bucket bucket, BlockNumber bucket_blkno, - Buffer bucket_buf, - BufferAccessStrategy bstrategy); + Bucket bucket, BlockNumber bucket_blkno, + Buffer bucket_buf, + BufferAccessStrategy bstrategy); extern uint32 _hash_ovflblkno_to_bitno(HashMetaPage metap, BlockNumber ovflblkno); /* hashpage.c */ extern Buffer _hash_getbuf(Relation rel, BlockNumber blkno, - int access, int flags); + int access, int flags); extern Buffer _hash_getbuf_with_condlock_cleanup(Relation rel, - BlockNumber blkno, int flags); + BlockNumber blkno, int flags); extern HashMetaPage _hash_getcachedmetap(Relation rel, Buffer *metabuf, - bool force_refresh); + bool force_refresh); extern Buffer _hash_getbucketbuf_from_hashkey(Relation rel, uint32 hashkey, - int access, - HashMetaPage *cachedmetap); + int access, + HashMetaPage *cachedmetap); extern Buffer _hash_getinitbuf(Relation rel, BlockNumber blkno); extern void _hash_initbuf(Buffer buf, uint32 max_bucket, uint32 num_bucket, - uint32 flag, bool initpage); + uint32 flag, bool initpage); extern Buffer _hash_getnewbuf(Relation rel, BlockNumber blkno, - ForkNumber forkNum); + ForkNumber forkNum); extern Buffer _hash_getbuf_with_strategy(Relation rel, BlockNumber blkno, - int access, int flags, - BufferAccessStrategy bstrategy); + int access, int flags, + BufferAccessStrategy bstrategy); extern void _hash_relbuf(Relation rel, Buffer buf); extern void _hash_dropbuf(Relation rel, Buffer buf); extern void _hash_dropscanbuf(Relation rel, HashScanOpaque so); extern uint32 _hash_init(Relation rel, double num_tuples, - ForkNumber forkNum); + ForkNumber forkNum); extern void _hash_init_metabuffer(Buffer buf, double num_tuples, - RegProcedure procid, uint16 ffactor, bool initpage); + RegProcedure procid, uint16 ffactor, bool initpage); extern void _hash_pageinit(Page page, Size size); extern void _hash_expandtable(Relation rel, Buffer metabuf); extern void _hash_finish_split(Relation rel, Buffer metabuf, Buffer obuf, - Bucket obucket, uint32 maxbucket, uint32 highmask, - uint32 lowmask); + Bucket obucket, uint32 maxbucket, uint32 highmask, + uint32 lowmask); /* hashsearch.c */ extern bool _hash_next(IndexScanDesc scan, ScanDirection dir); @@ -445,7 +425,7 @@ typedef struct HSpool HSpool; /* opaque struct in hashsort.c */ extern HSpool *_h_spoolinit(Relation heap, Relation index, uint32 num_buckets); extern void _h_spooldestroy(HSpool *hspool); extern void _h_spool(HSpool *hspool, ItemPointer self, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern void _h_indexbuild(HSpool *hspool, Relation heapRel); /* hashutil.c */ @@ -453,30 +433,30 @@ extern bool _hash_checkqual(IndexScanDesc scan, IndexTuple itup); extern uint32 _hash_datum2hashkey(Relation rel, Datum key); extern uint32 _hash_datum2hashkey_type(Relation rel, Datum key, Oid keytype); extern Bucket _hash_hashkey2bucket(uint32 hashkey, uint32 maxbucket, - uint32 highmask, uint32 lowmask); + uint32 highmask, uint32 lowmask); extern uint32 _hash_log2(uint32 num); extern uint32 _hash_spareindex(uint32 num_bucket); extern uint32 _hash_get_totalbuckets(uint32 splitpoint_phase); extern void _hash_checkpage(Relation rel, Buffer buf, int flags); extern uint32 _hash_get_indextuple_hashkey(IndexTuple itup); extern bool _hash_convert_tuple(Relation index, - Datum *user_values, bool *user_isnull, - Datum *index_values, bool *index_isnull); + Datum *user_values, bool *user_isnull, + Datum *index_values, bool *index_isnull); extern OffsetNumber _hash_binsearch(Page page, uint32 hash_value); extern OffsetNumber _hash_binsearch_last(Page page, uint32 hash_value); extern BlockNumber _hash_get_oldblock_from_newbucket(Relation rel, Bucket new_bucket); extern BlockNumber _hash_get_newblock_from_oldbucket(Relation rel, Bucket old_bucket); extern Bucket _hash_get_newbucket_from_oldbucket(Relation rel, Bucket old_bucket, - uint32 lowmask, uint32 maxbucket); + uint32 lowmask, uint32 maxbucket); extern void _hash_kill_items(IndexScanDesc scan); /* hash.c */ extern void hashbucketcleanup(Relation rel, Bucket cur_bucket, - Buffer bucket_buf, BlockNumber bucket_blkno, - BufferAccessStrategy bstrategy, - uint32 maxbucket, uint32 highmask, uint32 lowmask, - double *tuples_removed, double *num_index_tuples, - bool bucket_has_garbage, - IndexBulkDeleteCallback callback, void *callback_state); + Buffer bucket_buf, BlockNumber bucket_blkno, + BufferAccessStrategy bstrategy, + uint32 maxbucket, uint32 highmask, uint32 lowmask, + double *tuples_removed, double *num_index_tuples, + bool split_cleanup, + IndexBulkDeleteCallback callback, void *callback_state); #endif /* HASH_H */ diff --git a/src/include/access/hash_xlog.h b/src/include/access/hash_xlog.h index 527138440b3..7d52145a2a7 100644 --- a/src/include/access/hash_xlog.h +++ b/src/include/access/hash_xlog.h @@ -4,7 +4,7 @@ * header file for Postgres hash AM implementation * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/hash_xlog.h @@ -51,19 +51,6 @@ #define XLH_SPLIT_META_UPDATE_MASKS (1<<0) #define XLH_SPLIT_META_UPDATE_SPLITPOINT (1<<1) -/* - * This is what we need to know about a HASH index create. - * - * Backup block 0: metapage - */ -typedef struct xl_hash_createidx -{ - double num_tuples; - RegProcedure procid; - uint16 ffactor; -} xl_hash_createidx; -#define SizeOfHashCreateIdx (offsetof(xl_hash_createidx, ffactor) + sizeof(uint16)) - /* * This is what we need to know about simple (without split) insert. * @@ -263,7 +250,7 @@ typedef struct xl_hash_init_bitmap_page */ typedef struct xl_hash_vacuum_one_page { - RelFileNode hnode; + TransactionId latestRemovedXid; int ntuples; /* TARGET OFFSET NUMBERS FOLLOW AT THE END */ diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 7d756f20b08..858bcb6bc96 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -4,7 +4,7 @@ * POSTGRES heap access method definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/heapam.h @@ -14,8 +14,12 @@ #ifndef HEAPAM_H #define HEAPAM_H +#include "access/relation.h" /* for backward compatibility */ +#include "access/relscan.h" #include "access/sdir.h" #include "access/skey.h" +#include "access/table.h" /* for backward compatibility */ +#include "access/tableam.h" #include "nodes/lockoptions.h" #include "nodes/primnodes.h" #include "storage/bufpage.h" @@ -25,64 +29,68 @@ /* "options" flag bits for heap_insert */ -#define HEAP_INSERT_SKIP_WAL 0x0001 -#define HEAP_INSERT_SKIP_FSM 0x0002 -#define HEAP_INSERT_FROZEN 0x0004 -#define HEAP_INSERT_SPECULATIVE 0x0008 +#define HEAP_INSERT_SKIP_WAL TABLE_INSERT_SKIP_WAL +#define HEAP_INSERT_SKIP_FSM TABLE_INSERT_SKIP_FSM +#define HEAP_INSERT_FROZEN TABLE_INSERT_FROZEN +#define HEAP_INSERT_NO_LOGICAL TABLE_INSERT_NO_LOGICAL +#define HEAP_INSERT_SPECULATIVE 0x0010 typedef struct BulkInsertStateData *BulkInsertState; +struct TupleTableSlot; + +#define MaxLockTupleMode LockTupleExclusive /* - * Possible lock modes for a tuple. + * Descriptor for heap table scans. */ -typedef enum LockTupleMode +typedef struct HeapScanDescData { - /* SELECT FOR KEY SHARE */ - LockTupleKeyShare, - /* SELECT FOR SHARE */ - LockTupleShare, - /* SELECT FOR NO KEY UPDATE, and UPDATEs that don't modify key columns */ - LockTupleNoKeyExclusive, - /* SELECT FOR UPDATE, UPDATEs that modify key columns, and DELETE */ - LockTupleExclusive -} LockTupleMode; - -#define MaxLockTupleMode LockTupleExclusive + TableScanDescData rs_base; /* AM independent part of the descriptor */ + + /* state set up at initscan time */ + BlockNumber rs_nblocks; /* total number of blocks in rel */ + BlockNumber rs_startblock; /* block # to start at */ + BlockNumber rs_numblocks; /* max number of blocks to scan */ + /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */ + + /* scan current state */ + bool rs_inited; /* false = scan not init'd yet */ + BlockNumber rs_cblock; /* current block # in scan, if any */ + Buffer rs_cbuf; /* current buffer in scan, if any */ + /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ + + /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */ + BufferAccessStrategy rs_strategy; /* access strategy for reads */ + + HeapTupleData rs_ctup; /* current tuple in scan, if any */ + + /* these fields only used in page-at-a-time mode and for bitmap scans */ + int rs_cindex; /* current tuple's index in vistuples */ + int rs_ntuples; /* number of visible tuples on page */ + OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */ +} HeapScanDescData; +typedef struct HeapScanDescData *HeapScanDesc; /* - * When heap_update, heap_delete, or heap_lock_tuple fail because the target - * tuple is already outdated, they fill in this struct to provide information - * to the caller about what happened. - * - * result is the result of HeapTupleSatisfiesUpdate, leading to the failure. - * It's set to HeapTupleMayBeUpdated when there is no failure. - * - * ctid is the target's ctid link: it is the same as the target's TID if the - * target was deleted, or the location of the replacement tuple if the target - * was updated. - * - * xmax is the outdating transaction's XID. If the caller wants to visit the - * replacement tuple, it must check that this matches before believing the - * replacement is really a match. - * - * cmax is the outdating command's CID, but only when the failure code is - * HeapTupleSelfUpdated (i.e., something in the current transaction outdated - * the tuple); otherwise cmax is zero. (We make this restriction because - * HeapTupleHeaderGetCmax doesn't work for tuples outdated in other - * transactions.) - * - * lockmode is only relevant for callers of heap_update() and is the mode which - * the caller should use in case it needs to lock the updated tuple. + * Descriptor for fetches from heap via an index. */ -typedef struct HeapUpdateFailureData +typedef struct IndexFetchHeapData { - HTSU_Result result; - ItemPointerData ctid; - TransactionId xmax; - CommandId cmax; - LockTupleMode lockmode; -} HeapUpdateFailureData; + IndexFetchTableData xs_base; /* AM independent part of the descriptor */ + + Buffer xs_cbuf; /* current heap buffer in scan, if any */ + /* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ +} IndexFetchHeapData; +/* Result codes for HeapTupleSatisfiesVacuum */ +typedef enum +{ + HEAPTUPLE_DEAD, /* tuple is dead and deletable */ + HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */ + HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */ + HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ + HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */ +} HTSV_Result; /* ---------------- * function prototypes for heap access method @@ -92,24 +100,6 @@ typedef struct HeapUpdateFailureData * ---------------- */ -/* in heap/heapam.c */ -extern Relation relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation relation_openrv_extended(const RangeVar *relation, - LOCKMODE lockmode, bool missing_ok); -extern void relation_close(Relation relation, LOCKMODE lockmode); - -extern Relation heap_open(Oid relationId, LOCKMODE lockmode); -extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation heap_openrv_extended(const RangeVar *relation, - LOCKMODE lockmode, bool missing_ok); - -#define heap_close(r,l) relation_close(r,l) - -/* struct definitions appear in relscan.h */ -typedef struct HeapScanDescData *HeapScanDesc; -typedef struct ParallelHeapScanDescData *ParallelHeapScanDesc; /* * HeapScanIsValid @@ -117,92 +107,80 @@ typedef struct ParallelHeapScanDescData *ParallelHeapScanDesc; */ #define HeapScanIsValid(scan) PointerIsValid(scan) -extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key); -extern HeapScanDesc heap_beginscan_catalog(Relation relation, int nkeys, - ScanKey key); -extern HeapScanDesc heap_beginscan_strat(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key, - bool allow_strat, bool allow_sync); -extern HeapScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot, - int nkeys, ScanKey key); -extern HeapScanDesc heap_beginscan_sampling(Relation relation, - Snapshot snapshot, int nkeys, ScanKey key, +extern TableScanDesc heap_beginscan(Relation relation, Snapshot snapshot, + int nkeys, ScanKey key, + ParallelTableScanDesc parallel_scan, + uint32 flags); +extern void heap_setscanlimits(TableScanDesc scan, BlockNumber startBlk, + BlockNumber numBlks); +extern void heapgetpage(TableScanDesc scan, BlockNumber page); +extern void heap_rescan(TableScanDesc scan, ScanKey key, bool set_params, bool allow_strat, bool allow_sync, bool allow_pagemode); -extern void heap_setscanlimits(HeapScanDesc scan, BlockNumber startBlk, - BlockNumber endBlk); -extern void heapgetpage(HeapScanDesc scan, BlockNumber page); -extern void heap_rescan(HeapScanDesc scan, ScanKey key); -extern void heap_rescan_set_params(HeapScanDesc scan, ScanKey key, - bool allow_strat, bool allow_sync, bool allow_pagemode); -extern void heap_endscan(HeapScanDesc scan); -extern HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction); - -extern Size heap_parallelscan_estimate(Snapshot snapshot); -extern void heap_parallelscan_initialize(ParallelHeapScanDesc target, - Relation relation, Snapshot snapshot); -extern void heap_parallelscan_reinitialize(ParallelHeapScanDesc parallel_scan); -extern HeapScanDesc heap_beginscan_parallel(Relation, ParallelHeapScanDesc); +extern void heap_endscan(TableScanDesc scan); +extern HeapTuple heap_getnext(TableScanDesc scan, ScanDirection direction); +extern bool heap_getnextslot(TableScanDesc sscan, + ScanDirection direction, struct TupleTableSlot *slot); extern bool heap_fetch(Relation relation, Snapshot snapshot, - HeapTuple tuple, Buffer *userbuf, bool keep_buf, - Relation stats_relation); + HeapTuple tuple, Buffer *userbuf); extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation, - Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, - bool *all_dead, bool first_call); -extern bool heap_hot_search(ItemPointer tid, Relation relation, - Snapshot snapshot, bool *all_dead); + Buffer buffer, Snapshot snapshot, HeapTuple heapTuple, + bool *all_dead, bool first_call); -extern void heap_get_latest_tid(Relation relation, Snapshot snapshot, - ItemPointer tid); +extern void heap_get_latest_tid(TableScanDesc scan, ItemPointer tid); extern void setLastTid(const ItemPointer tid); extern BulkInsertState GetBulkInsertState(void); extern void FreeBulkInsertState(BulkInsertState); extern void ReleaseBulkInsertStatePin(BulkInsertState bistate); -extern Oid heap_insert(Relation relation, HeapTuple tup, CommandId cid, - int options, BulkInsertState bistate); -extern void heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples, - CommandId cid, int options, BulkInsertState bistate); -extern HTSU_Result heap_delete(Relation relation, ItemPointer tid, - CommandId cid, Snapshot crosscheck, bool wait, - HeapUpdateFailureData *hufd, bool changingPart); -extern void heap_finish_speculative(Relation relation, HeapTuple tuple); -extern void heap_abort_speculative(Relation relation, HeapTuple tuple); -extern HTSU_Result heap_update(Relation relation, ItemPointer otid, - HeapTuple newtup, - CommandId cid, Snapshot crosscheck, bool wait, - HeapUpdateFailureData *hufd); -extern HTSU_Result heap_lock_tuple(Relation relation, HeapTuple tuple, - CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, - bool follow_update, - Buffer *buffer, HeapUpdateFailureData *hufd); +extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid, + int options, BulkInsertState bistate); +extern void heap_multi_insert(Relation relation, struct TupleTableSlot **slots, + int ntuples, CommandId cid, int options, + BulkInsertState bistate); +extern TM_Result heap_delete(Relation relation, ItemPointer tid, + CommandId cid, Snapshot crosscheck, bool wait, + struct TM_FailureData *tmfd, bool changingPart); +extern void heap_finish_speculative(Relation relation, ItemPointer tid); +extern void heap_abort_speculative(Relation relation, ItemPointer tid); +extern TM_Result heap_update(Relation relation, ItemPointer otid, + HeapTuple newtup, + CommandId cid, Snapshot crosscheck, bool wait, + struct TM_FailureData *tmfd, LockTupleMode *lockmode); +extern TM_Result heap_lock_tuple(Relation relation, HeapTuple tuple, + CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, + bool follow_update, + Buffer *buffer, struct TM_FailureData *tmfd); + extern void heap_inplace_update(Relation relation, HeapTuple tuple); extern bool heap_freeze_tuple(HeapTupleHeader tuple, - TransactionId relfrozenxid, TransactionId relminmxid, - TransactionId cutoff_xid, TransactionId cutoff_multi); + TransactionId relfrozenxid, TransactionId relminmxid, + TransactionId cutoff_xid, TransactionId cutoff_multi); extern bool heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_xid, - MultiXactId cutoff_multi, Buffer buf); + MultiXactId cutoff_multi, Buffer buf); extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple); -extern Oid simple_heap_insert(Relation relation, HeapTuple tup); +extern void simple_heap_insert(Relation relation, HeapTuple tup); extern void simple_heap_delete(Relation relation, ItemPointer tid); extern void simple_heap_update(Relation relation, ItemPointer otid, - HeapTuple tup); + HeapTuple tup); extern void heap_sync(Relation relation); -extern void heap_update_snapshot(HeapScanDesc scan, Snapshot snapshot); + +extern TransactionId heap_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *items, + int nitems); /* in heap/pruneheap.c */ extern void heap_page_prune_opt(Relation relation, Buffer buffer); -extern int heap_page_prune(Relation relation, Buffer buffer, - TransactionId OldestXmin, - bool report_stats, TransactionId *latestRemovedXid); +extern int heap_page_prune(Relation relation, Buffer buffer, + TransactionId OldestXmin, + bool report_stats, TransactionId *latestRemovedXid); extern void heap_page_prune_execute(Buffer buffer, - OffsetNumber *redirected, int nredirected, - OffsetNumber *nowdead, int ndead, - OffsetNumber *nowunused, int nunused); + OffsetNumber *redirected, int nredirected, + OffsetNumber *nowdead, int ndead, + OffsetNumber *nowunused, int nunused); extern void heap_get_root_tuples(Page page, OffsetNumber *root_offsets); /* in heap/syncscan.c */ @@ -211,4 +189,33 @@ extern BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks); extern void SyncScanShmemInit(void); extern Size SyncScanShmemSize(void); +/* in heap/vacuumlazy.c */ +struct VacuumParams; +extern void heap_vacuum_rel(Relation onerel, + struct VacuumParams *params, BufferAccessStrategy bstrategy); + +/* in heap/heapam_visibility.c */ +extern bool HeapTupleSatisfiesVisibility(HeapTuple stup, Snapshot snapshot, + Buffer buffer); +extern TM_Result HeapTupleSatisfiesUpdate(HeapTuple stup, CommandId curcid, + Buffer buffer); +extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple stup, TransactionId OldestXmin, + Buffer buffer); +extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, + uint16 infomask, TransactionId xid); +extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); +extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); +extern bool HeapTupleIsSurelyDead(HeapTuple htup, TransactionId OldestXmin); + +/* + * To avoid leaking too much knowledge about reorderbuffer implementation + * details this is implemented in reorderbuffer.c not heapam_visibility.c + */ +struct HTAB; +extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data, + Snapshot snapshot, + HeapTuple htup, + Buffer buffer, + CommandId *cmin, CommandId *cmax); + #endif /* HEAPAM_H */ diff --git a/src/include/access/heapam_xlog.h b/src/include/access/heapam_xlog.h index cf88ff7cb44..d72d4e1b8e1 100644 --- a/src/include/access/heapam_xlog.h +++ b/src/include/access/heapam_xlog.h @@ -4,7 +4,7 @@ * POSTGRES heap access XLOG definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/heapam_xlog.h @@ -111,7 +111,7 @@ typedef struct xl_heap_delete #define SizeOfHeapDelete (offsetof(xl_heap_delete, flags) + sizeof(uint8)) /* - * xl_heap_delete flag values, 8 bits are available. + * xl_heap_truncate flag values, 8 bits are available. */ #define XLH_TRUNCATE_CASCADE (1<<0) #define XLH_TRUNCATE_RESTART_SEQS (1<<1) @@ -126,7 +126,7 @@ typedef struct xl_heap_truncate Oid dbId; uint32 nrelids; uint8 flags; - Oid relids[FLEXIBLE_ARRAY_MEMBER]; + Oid relids[FLEXIBLE_ARRAY_MEMBER]; } xl_heap_truncate; #define SizeOfHeapTruncate (offsetof(xl_heap_truncate, relids)) @@ -168,7 +168,7 @@ typedef struct xl_heap_insert * * In block 0's data portion, there is an xl_multi_insert_tuple struct, * followed by the tuple data for each tuple. There is padding to align - * each xl_multi_insert struct. + * each xl_multi_insert_tuple struct. */ typedef struct xl_heap_multi_insert { @@ -195,14 +195,14 @@ typedef struct xl_multi_insert_tuple * * Backup blk 0: new page * - * If XLOG_HEAP_PREFIX_FROM_OLD or XLOG_HEAP_SUFFIX_FROM_OLD flags are set, + * If XLH_UPDATE_PREFIX_FROM_OLD or XLH_UPDATE_SUFFIX_FROM_OLD flags are set, * the prefix and/or suffix come first, as one or two uint16s. * * After that, xl_heap_header and new tuple data follow. The new tuple * data doesn't include the prefix and suffix, which are copied from the * old tuple on replay. * - * If HEAP_CONTAINS_NEW_TUPLE_DATA flag is given, the tuple data is + * If XLH_UPDATE_CONTAINS_NEW_TUPLE flag is given, the tuple data is * included even if a full-page image was taken. * * Backup blk 1: old page, if different. (no data, just a reference to the blk) @@ -217,8 +217,8 @@ typedef struct xl_heap_update OffsetNumber new_offnum; /* new tuple's offset */ /* - * If XLOG_HEAP_CONTAINS_OLD_TUPLE or XLOG_HEAP_CONTAINS_OLD_KEY flags are - * set, a xl_heap_header struct and tuple data for the old tuple follows. + * If XLH_UPDATE_CONTAINS_OLD_TUPLE or XLH_UPDATE_CONTAINS_OLD_KEY flags + * are set, xl_heap_header and tuple data for the old tuple follow. */ } xl_heap_update; @@ -384,7 +384,7 @@ typedef struct xl_heap_rewrite_mapping } xl_heap_rewrite_mapping; extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple, - TransactionId *latestRemovedXid); + TransactionId *latestRemovedXid); extern void heap_redo(XLogReaderState *record); extern void heap_desc(StringInfo buf, XLogReaderState *record); @@ -396,25 +396,25 @@ extern const char *heap2_identify(uint8 info); extern void heap_xlog_logical_rewrite(XLogReaderState *r); extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode, - TransactionId latestRemovedXid); + TransactionId latestRemovedXid); extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer, - OffsetNumber *redirected, int nredirected, - OffsetNumber *nowdead, int ndead, - OffsetNumber *nowunused, int nunused, - TransactionId latestRemovedXid); + OffsetNumber *redirected, int nredirected, + OffsetNumber *nowdead, int ndead, + OffsetNumber *nowunused, int nunused, + TransactionId latestRemovedXid); extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer, - TransactionId cutoff_xid, xl_heap_freeze_tuple *tuples, - int ntuples); + TransactionId cutoff_xid, xl_heap_freeze_tuple *tuples, + int ntuples); extern bool heap_prepare_freeze_tuple(HeapTupleHeader tuple, - TransactionId relfrozenxid, - TransactionId relminmxid, - TransactionId cutoff_xid, - TransactionId cutoff_multi, - xl_heap_freeze_tuple *frz, - bool *totally_frozen); + TransactionId relfrozenxid, + TransactionId relminmxid, + TransactionId cutoff_xid, + TransactionId cutoff_multi, + xl_heap_freeze_tuple *frz, + bool *totally_frozen); extern void heap_execute_freeze_tuple(HeapTupleHeader tuple, - xl_heap_freeze_tuple *xlrec_tp); + xl_heap_freeze_tuple *xlrec_tp); extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer, - Buffer vm_buffer, TransactionId cutoff_xid, uint8 flags); + Buffer vm_buffer, TransactionId cutoff_xid, uint8 flags); #endif /* HEAPAM_XLOG_H */ diff --git a/src/include/access/tuptoaster.h b/src/include/access/heaptoast.h similarity index 54% rename from src/include/access/tuptoaster.h rename to src/include/access/heaptoast.h index f99291e30d4..bf02d2c6001 100644 --- a/src/include/access/tuptoaster.h +++ b/src/include/access/heaptoast.h @@ -1,29 +1,22 @@ /*------------------------------------------------------------------------- * - * tuptoaster.h - * POSTGRES definitions for external and compressed storage + * heaptoast.h + * Heap-specific definitions for external and compressed storage * of variable size attributes. * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * - * src/include/access/tuptoaster.h + * src/include/access/heaptoast.h * *------------------------------------------------------------------------- */ -#ifndef TUPTOASTER_H -#define TUPTOASTER_H +#ifndef HEAPTOAST_H +#define HEAPTOAST_H #include "access/htup_details.h" #include "storage/lockdefs.h" #include "utils/relcache.h" -/* - * This enables de-toasting of index entries. Needed until VACUUM is - * smart enough to rebuild indexes from scratch. - */ -#define TOAST_INDEX_HACK - - /* * Find the maximum size of a tuple if there are to be N tuples per page. */ @@ -95,37 +88,6 @@ sizeof(int32) - \ VARHDRSZ) -/* Size of an EXTERNAL datum that contains a standard TOAST pointer */ -#define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external)) - -/* Size of an EXTERNAL datum that contains an indirection pointer */ -#define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect)) - -/* - * Testing whether an externally-stored value is compressed now requires - * comparing extsize (the actual length of the external data) to rawsize - * (the original uncompressed datum's size). The latter includes VARHDRSZ - * overhead, the former doesn't. We never use compression unless it actually - * saves space, so we expect either equality or less-than. - */ -#define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \ - ((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ) - -/* - * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum - * into a local "struct varatt_external" toast pointer. This should be - * just a memcpy, but some versions of gcc seem to produce broken code - * that assumes the datum contents are aligned. Introducing an explicit - * intermediate "varattrib_1b_e *" variable seems to fix it. - */ -#define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \ -do { \ - varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \ - Assert(VARATT_IS_EXTERNAL(attre)); \ - Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \ - memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \ -} while (0) - /* ---------- * toast_insert_or_update - * @@ -133,8 +95,8 @@ do { \ * ---------- */ extern HeapTuple toast_insert_or_update(Relation rel, - HeapTuple newtup, HeapTuple oldtup, - int options); + HeapTuple newtup, HeapTuple oldtup, + int options); /* ---------- * toast_delete - @@ -144,36 +106,6 @@ extern HeapTuple toast_insert_or_update(Relation rel, */ extern void toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative); -/* ---------- - * heap_tuple_fetch_attr() - - * - * Fetches an external stored attribute from the toast - * relation. Does NOT decompress it, if stored external - * in compressed format. - * ---------- - */ -extern struct varlena *heap_tuple_fetch_attr(struct varlena *attr); - -/* ---------- - * heap_tuple_untoast_attr() - - * - * Fully detoasts one attribute, fetching and/or decompressing - * it as needed. - * ---------- - */ -extern struct varlena *heap_tuple_untoast_attr(struct varlena *attr); - -/* ---------- - * heap_tuple_untoast_attr_slice() - - * - * Fetches only the specified portion of an attribute. - * (Handles all cases for attribute storage) - * ---------- - */ -extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena *attr, - int32 sliceoffset, - int32 slicelength); - /* ---------- * toast_flatten_tuple - * @@ -190,8 +122,8 @@ extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc); * ---------- */ extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, - uint32 tup_len, - TupleDesc tupleDesc); + uint32 tup_len, + TupleDesc tupleDesc); /* ---------- * toast_build_flattened_tuple - @@ -201,39 +133,7 @@ extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup, * ---------- */ extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc, - Datum *values, - bool *isnull); - -/* ---------- - * toast_compress_datum - - * - * Create a compressed version of a varlena datum, if possible - * ---------- - */ -extern Datum toast_compress_datum(Datum value); - -/* ---------- - * toast_raw_datum_size - - * - * Return the raw (detoasted) size of a varlena datum - * ---------- - */ -extern Size toast_raw_datum_size(Datum value); - -/* ---------- - * toast_datum_size - - * - * Return the storage size of a varlena datum - * ---------- - */ -extern Size toast_datum_size(Datum value); - -/* ---------- - * toast_get_valid_index - - * - * Return OID of valid index associated to a toast relation - * ---------- - */ -extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock); + Datum *values, + bool *isnull); -#endif /* TUPTOASTER_H */ +#endif /* HEAPTOAST_H */ diff --git a/src/include/access/hio.h b/src/include/access/hio.h index 9993d5be70b..dbaabcc073d 100644 --- a/src/include/access/hio.h +++ b/src/include/access/hio.h @@ -4,7 +4,7 @@ * POSTGRES heap access method input/output definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/hio.h @@ -14,7 +14,6 @@ #ifndef HIO_H #define HIO_H -#include "access/heapam.h" #include "access/htup.h" #include "utils/relcache.h" #include "storage/buf.h" @@ -32,14 +31,14 @@ typedef struct BulkInsertStateData { BufferAccessStrategy strategy; /* our BULKWRITE strategy object */ Buffer current_buf; /* current insertion target page */ -} BulkInsertStateData; +} BulkInsertStateData; extern void RelationPutHeapTuple(Relation relation, Buffer buffer, - HeapTuple tuple, bool token); + HeapTuple tuple, bool token); extern Buffer RelationGetBufferForTuple(Relation relation, Size len, - Buffer otherBuffer, int options, - BulkInsertState bistate, - Buffer *vmbuffer, Buffer *vmbuffer_other); + Buffer otherBuffer, int options, + BulkInsertStateData *bistate, + Buffer *vmbuffer, Buffer *vmbuffer_other); #endif /* HIO_H */ diff --git a/src/include/access/htup.h b/src/include/access/htup.h index 5a4e5b05f50..c716c7ee26c 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -4,7 +4,7 @@ * POSTGRES heap tuple definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/htup.h @@ -81,7 +81,7 @@ typedef HeapTupleData *HeapTuple; extern CommandId HeapTupleHeaderGetCmin(HeapTupleHeader tup); extern CommandId HeapTupleHeaderGetCmax(HeapTupleHeader tup); extern void HeapTupleHeaderAdjustCmax(HeapTupleHeader tup, - CommandId *cmax, bool *iscombo); + CommandId *cmax, bool *iscombo); /* Prototype for HeapTupleHeader accessors in heapam.c */ extern TransactionId HeapTupleGetUpdateXid(HeapTupleHeader tuple); diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h index cf56d4ace43..66d61fd5700 100644 --- a/src/include/access/htup_details.h +++ b/src/include/access/htup_details.h @@ -4,7 +4,7 @@ * POSTGRES heap tuple header definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/htup_details.h @@ -65,7 +65,8 @@ * fixed fields (HeapTupleHeaderData struct) * nulls bitmap (if HEAP_HASNULL is set in t_infomask) * alignment padding (as needed to make user data MAXALIGN'd) - * object ID (if HEAP_HASOID is set in t_infomask) + * object ID (if HEAP_HASOID_OLD is set in t_infomask, not created + * anymore) * user data fields * * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three @@ -83,13 +84,15 @@ * * A word about t_ctid: whenever a new tuple is stored on disk, its t_ctid * is initialized with its own TID (location). If the tuple is ever updated, - * its t_ctid is changed to point to the replacement version of the tuple or - * the block number (ip_blkid) is invalidated if the tuple is moved from one - * partition to another partition relation due to an update of the partition - * key. Thus, a tuple is the latest version of its row iff XMAX is invalid or + * its t_ctid is changed to point to the replacement version of the tuple. Or + * if the tuple is moved from one partition to another, due to an update of + * the partition key, t_ctid is set to a special value to indicate that + * (see ItemPointerSetMovedPartitions). Thus, a tuple is the latest version + * of its row iff XMAX is invalid or * t_ctid points to itself (in which case, if XMAX is valid, the tuple is * either locked or deleted). One can follow the chain of t_ctid links - * to find the newest version of the row. Beware however that VACUUM might + * to find the newest version of the row, unless it was moved to a different + * partition. Beware however that VACUUM might * erase the pointed-to (newer) tuple before erasing the pointing (older) * tuple. Hence, when following a t_ctid link, it is necessary to check * to see if the referenced slot is empty or contains an unrelated tuple. @@ -186,7 +189,7 @@ struct HeapTupleHeaderData #define HEAP_HASNULL 0x0001 /* has null attribute(s) */ #define HEAP_HASVARWIDTH 0x0002 /* has variable-width attribute(s) */ #define HEAP_HASEXTERNAL 0x0004 /* has external stored attribute(s) */ -#define HEAP_HASOID 0x0008 /* has an object-id field */ +#define HEAP_HASOID_OLD 0x0008 /* has an object-id field */ #define HEAP_XMAX_KEYSHR_LOCK 0x0010 /* xmax is a key-shared locker */ #define HEAP_COMBOCID 0x0020 /* t_cid is a combo cid */ #define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ @@ -230,7 +233,7 @@ struct HeapTupleHeaderData /* * A tuple that has HEAP_XMAX_IS_MULTI and HEAP_XMAX_LOCK_ONLY but neither of - * XMAX_EXCL_LOCK and XMAX_KEYSHR_LOCK must come from a tuple that was + * HEAP_XMAX_EXCL_LOCK and HEAP_XMAX_KEYSHR_LOCK must come from a tuple that was * share-locked in 9.2 or earlier and then pg_upgrade'd. * * In 9.2 and prior, HEAP_XMAX_IS_MULTI was only set when there were multiple @@ -287,14 +290,6 @@ struct HeapTupleHeaderData */ #define HEAP_TUPLE_HAS_MATCH HEAP_ONLY_TUPLE /* tuple has a join match */ -/* - * Special value used in t_ctid.ip_posid, to indicate that it holds a - * speculative insertion token rather than a real TID. This must be higher - * than MaxOffsetNumber, so that it can be distinguished from a valid - * offset number in a regular item pointer. - */ -#define SpecTokenOffsetNumber 0xfffe - /* * HeapTupleHeader accessor macros * @@ -447,11 +442,12 @@ do { \ ItemPointerSet(&(tup)->t_ctid, token, SpecTokenOffsetNumber) \ ) -#define HeapTupleHeaderSetMovedPartitions(tup) \ - ItemPointerSetMovedPartitions(&(tup)->t_ctid) - #define HeapTupleHeaderIndicatesMovedPartitions(tup) \ - ItemPointerIndicatesMovedPartitions(&tup->t_ctid) + (ItemPointerGetOffsetNumber(&(tup)->t_ctid) == MovedPartitionsOffsetNumber && \ + ItemPointerGetBlockNumberNoCheck(&(tup)->t_ctid) == MovedPartitionsBlockNumber) + +#define HeapTupleHeaderSetMovedPartitions(tup) \ + ItemPointerSet(&(tup)->t_ctid, MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber) #define HeapTupleHeaderGetDatumLength(tup) \ VARSIZE(tup) @@ -479,20 +475,6 @@ do { \ (tup)->t_choice.t_datum.datum_typmod = (typmod) \ ) -#define HeapTupleHeaderGetOid(tup) \ -( \ - ((tup)->t_infomask & HEAP_HASOID) ? \ - *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \ - : \ - InvalidOid \ -) - -#define HeapTupleHeaderSetOid(tup, oid) \ -do { \ - Assert((tup)->t_infomask & HEAP_HASOID); \ - *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \ -} while (0) - /* * Note that we stop considering a tuple HOT-updated as soon as it is known * aborted or the would-be updating transaction is known aborted. For best @@ -582,7 +564,7 @@ do { \ * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can * fit on one heap page. (Note that indexes could have more, because they * use a smaller tuple header.) We arrive at the divisor because each tuple - * must be maxaligned, and it must have an associated item pointer. + * must be maxaligned, and it must have an associated line pointer. * * Note: with HOT, there could theoretically be more line pointers (not actual * tuples) than this on a heap page. However we constrain the number of line @@ -709,12 +691,6 @@ struct MinimalTupleData #define HeapTupleClearHeapOnly(tuple) \ HeapTupleHeaderClearHeapOnly((tuple)->t_data) -#define HeapTupleGetOid(tuple) \ - HeapTupleHeaderGetOid((tuple)->t_data) - -#define HeapTupleSetOid(tuple, oid) \ - HeapTupleHeaderSetOid((tuple)->t_data, (oid)) - /* ---------------- * fastgetattr @@ -764,7 +740,7 @@ struct MinimalTupleData #else /* defined(DISABLE_COMPLEX_MACRO) */ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, - bool *isnull); + bool *isnull); #endif /* defined(DISABLE_COMPLEX_MACRO) */ @@ -788,10 +764,7 @@ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, ((attnum) > 0) ? \ ( \ ((attnum) > (int) HeapTupleHeaderGetNatts((tup)->t_data)) ? \ - ( \ - (*(isnull) = true), \ - (Datum)NULL \ - ) \ + getmissingattr((tupleDesc), (attnum), (isnull)) \ : \ fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \ ) \ @@ -802,37 +775,39 @@ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, /* prototypes for functions in common/heaptuple.c */ extern Size heap_compute_data_size(TupleDesc tupleDesc, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern void heap_fill_tuple(TupleDesc tupleDesc, - Datum *values, bool *isnull, - char *data, Size data_size, - uint16 *infomask, bits8 *bit); + Datum *values, bool *isnull, + char *data, Size data_size, + uint16 *infomask, bits8 *bit); extern bool heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc); extern Datum nocachegetattr(HeapTuple tup, int attnum, - TupleDesc att); + TupleDesc att); extern Datum heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, - bool *isnull); + bool *isnull); +extern Datum getmissingattr(TupleDesc tupleDesc, + int attnum, bool *isnull); extern HeapTuple heap_copytuple(HeapTuple tuple); extern void heap_copytuple_with_tuple(HeapTuple src, HeapTuple dest); extern Datum heap_copy_tuple_as_datum(HeapTuple tuple, TupleDesc tupleDesc); extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern HeapTuple heap_modify_tuple(HeapTuple tuple, - TupleDesc tupleDesc, - Datum *replValues, - bool *replIsnull, - bool *doReplace); + TupleDesc tupleDesc, + Datum *replValues, + bool *replIsnull, + bool *doReplace); extern HeapTuple heap_modify_tuple_by_cols(HeapTuple tuple, - TupleDesc tupleDesc, - int nCols, - int *replCols, - Datum *replValues, - bool *replIsnull); + TupleDesc tupleDesc, + int nCols, + int *replCols, + Datum *replValues, + bool *replIsnull); extern void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern void heap_freetuple(HeapTuple htup); extern MinimalTuple heap_form_minimal_tuple(TupleDesc tupleDescriptor, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern void heap_free_minimal_tuple(MinimalTuple mtup); extern MinimalTuple heap_copy_minimal_tuple(MinimalTuple mtup); extern HeapTuple heap_tuple_from_minimal_tuple(MinimalTuple mtup); diff --git a/src/include/access/itup.h b/src/include/access/itup.h index 04526a8e59f..744ffb6c61c 100644 --- a/src/include/access/itup.h +++ b/src/include/access/itup.h @@ -4,7 +4,7 @@ * POSTGRES index tuple definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/itup.h @@ -131,9 +131,17 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap; * fit on one index page. An index tuple must have either data or a null * bitmap, so we can safely assume it's at least 1 byte bigger than a bare * IndexTupleData struct. We arrive at the divisor because each tuple - * must be maxaligned, and it must have an associated item pointer. + * must be maxaligned, and it must have an associated line pointer. + * + * To be index-type-independent, this does not account for any special space + * on the page, and is thus conservative. + * + * Note: in btree non-leaf pages, the first tuple has no key (it's implicitly + * minus infinity), thus breaking the "at least 1 byte bigger" assumption. + * On such a page, N tuples could take one MAXALIGN quantum less space than + * estimated here, seemingly allowing one more tuple than estimated here. + * But such a page always has at least MAXALIGN special space, so we're safe. */ -#define MinIndexTupleSize MAXALIGN(sizeof(IndexTupleData) + 1) #define MaxIndexTuplesPerPage \ ((int) ((BLCKSZ - SizeOfPageHeaderData) / \ (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData)))) @@ -141,13 +149,13 @@ typedef IndexAttributeBitMapData * IndexAttributeBitMap; /* routines in indextuple.c */ extern IndexTuple index_form_tuple(TupleDesc tupleDescriptor, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern Datum nocache_index_getattr(IndexTuple tup, int attnum, - TupleDesc tupleDesc); + TupleDesc tupleDesc); extern void index_deform_tuple(IndexTuple tup, TupleDesc tupleDescriptor, - Datum *values, bool *isnull); + Datum *values, bool *isnull); extern IndexTuple CopyIndexTuple(IndexTuple source); -extern IndexTuple index_truncate_tuple(TupleDesc tupleDescriptor, - IndexTuple olditup, int new_indnatts); +extern IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor, + IndexTuple source, int leavenatts); #endif /* ITUP_H */ diff --git a/src/include/access/multixact.h b/src/include/access/multixact.h index 18fe380c5f4..79e4c8d6927 100644 --- a/src/include/access/multixact.h +++ b/src/include/access/multixact.h @@ -3,7 +3,7 @@ * * PostgreSQL multi-transaction-log manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/multixact.h @@ -100,21 +100,21 @@ typedef struct xl_multixact_truncate extern MultiXactId MultiXactIdCreate(TransactionId xid1, - MultiXactStatus status1, TransactionId xid2, - MultiXactStatus status2); + MultiXactStatus status1, TransactionId xid2, + MultiXactStatus status2); extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid, - MultiXactStatus status); + MultiXactStatus status); extern MultiXactId MultiXactIdCreateFromMembers(int nmembers, - MultiXactMember *members); + MultiXactMember *members); extern MultiXactId ReadNextMultiXactId(void); extern bool MultiXactIdIsRunning(MultiXactId multi, bool isLockOnly); extern void MultiXactIdSetOldestMember(void); -extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **xids, - bool allow_old, bool isLockOnly); +extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **xids, + bool allow_old, bool isLockOnly); extern bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2); extern bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, - MultiXactId multi2); + MultiXactId multi2); extern void AtEOXact_MultiXact(void); extern void AtPrepare_MultiXact(void); @@ -127,34 +127,34 @@ extern void StartupMultiXact(void); extern void TrimMultiXact(void); extern void ShutdownMultiXact(void); extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, - Oid oldest_datoid, - bool is_startup); + Oid oldest_datoid, + bool is_startup); extern void MultiXactGetCheckptMulti(bool is_shutdown, - MultiXactId *nextMulti, - MultiXactOffset *nextMultiOffset, - MultiXactId *oldestMulti, - Oid *oldestMultiDB); + MultiXactId *nextMulti, + MultiXactOffset *nextMultiOffset, + MultiXactId *oldestMulti, + Oid *oldestMultiDB); extern void CheckPointMultiXact(void); extern MultiXactId GetOldestMultiXactId(void); extern void TruncateMultiXact(MultiXactId oldestMulti, Oid oldestMultiDB); extern void MultiXactSetNextMXact(MultiXactId nextMulti, - MultiXactOffset nextMultiOffset); + MultiXactOffset nextMultiOffset); extern void MultiXactAdvanceNextMXact(MultiXactId minMulti, - MultiXactOffset minMultiOffset); + MultiXactOffset minMultiOffset); extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB); extern int MultiXactMemberFreezeThreshold(void); extern void multixact_twophase_recover(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void multixact_twophase_postcommit(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void multixact_twophase_postabort(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void multixact_redo(XLogReaderState *record); extern void multixact_desc(StringInfo buf, XLogReaderState *record); extern const char *multixact_identify(uint8 info); extern char *mxid_to_string(MultiXactId multi, int nmembers, - MultiXactMember *members); + MultiXactMember *members); #endif /* MULTIXACT_H */ diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 36619b220f1..4a80e84aa74 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -4,7 +4,7 @@ * header file for postgres btree access method implementation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/nbtree.h @@ -97,33 +97,60 @@ typedef BTPageOpaqueData *BTPageOpaque; typedef struct BTMetaPageData { uint32 btm_magic; /* should contain BTREE_MAGIC */ - uint32 btm_version; /* should contain BTREE_VERSION */ + uint32 btm_version; /* nbtree version (always <= BTREE_VERSION) */ BlockNumber btm_root; /* current root location */ uint32 btm_level; /* tree level of the root page */ BlockNumber btm_fastroot; /* current "fast" root location */ uint32 btm_fastlevel; /* tree level of the "fast" root page */ - /* following fields are available since page version 3 */ - TransactionId btm_oldest_btpo_xact; /* oldest btpo_xact among of - * deleted pages */ - float4 btm_last_cleanup_num_heap_tuples; /* number of heap tuples - * during last cleanup */ + /* remaining fields only valid when btm_version >= BTREE_NOVAC_VERSION */ + TransactionId btm_oldest_btpo_xact; /* oldest btpo_xact among all deleted + * pages */ + float8 btm_last_cleanup_num_heap_tuples; /* number of heap tuples + * during last cleanup */ } BTMetaPageData; #define BTPageGetMeta(p) \ ((BTMetaPageData *) PageGetContents(p)) +/* + * The current Btree version is 4. That's what you'll get when you create + * a new index. + * + * Btree version 3 was used in PostgreSQL v11. It is mostly the same as + * version 4, but heap TIDs were not part of the keyspace. Index tuples + * with duplicate keys could be stored in any order. We continue to + * support reading and writing Btree versions 2 and 3, so that they don't + * need to be immediately re-indexed at pg_upgrade. In order to get the + * new heapkeyspace semantics, however, a REINDEX is needed. + * + * Btree version 2 is mostly the same as version 3. There are two new + * fields in the metapage that were introduced in version 3. A version 2 + * metapage will be automatically upgraded to version 3 on the first + * insert to it. INCLUDE indexes cannot use version 2. + */ #define BTREE_METAPAGE 0 /* first page is meta */ -#define BTREE_MAGIC 0x053162 /* magic number of btree pages */ -#define BTREE_VERSION 3 /* current version number */ -#define BTREE_MIN_VERSION 2 /* minimal supported version number */ +#define BTREE_MAGIC 0x053162 /* magic number in metapage */ +#define BTREE_VERSION 4 /* current version number */ +#define BTREE_MIN_VERSION 2 /* minimal supported version number */ +#define BTREE_NOVAC_VERSION 3 /* minimal version with all meta fields */ /* * Maximum size of a btree index entry, including its tuple header. * * We actually need to be able to fit three items on every page, * so restrict any one item to 1/3 the per-page available space. + * + * There are rare cases where _bt_truncate() will need to enlarge + * a heap index tuple to make space for a tiebreaker heap TID + * attribute, which we account for here. */ #define BTMaxItemSize(page) \ + MAXALIGN_DOWN((PageGetPageSize(page) - \ + MAXALIGN(SizeOfPageHeaderData + \ + 3*sizeof(ItemIdData) + \ + 3*sizeof(ItemPointerData)) - \ + MAXALIGN(sizeof(BTPageOpaqueData))) / 3) +#define BTMaxItemSizeNoHeapTid(page) \ MAXALIGN_DOWN((PageGetPageSize(page) - \ MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \ MAXALIGN(sizeof(BTPageOpaqueData))) / 3) @@ -133,11 +160,15 @@ typedef struct BTMetaPageData * For pages above the leaf level, we use a fixed 70% fillfactor. * The fillfactor is applied during index build and when splitting * a rightmost page; when splitting non-rightmost pages we try to - * divide the data equally. + * divide the data equally. When splitting a page that's entirely + * filled with a single value (duplicates), the effective leaf-page + * fillfactor is 96%, regardless of whether the page is a rightmost + * page. */ #define BTREE_MIN_FILLFACTOR 10 #define BTREE_DEFAULT_FILLFACTOR 90 #define BTREE_NONLEAF_FILLFACTOR 70 +#define BTREE_SINGLEVAL_FILLFACTOR 96 /* * In general, the btree code tries to localize its knowledge about @@ -166,12 +197,13 @@ typedef struct BTMetaPageData /* * Lehman and Yao's algorithm requires a ``high key'' on every non-rightmost - * page. The high key is not a data key, but gives info about what range of - * keys is supposed to be on this page. The high key on a page is required - * to be greater than or equal to any data key that appears on the page. - * If we find ourselves trying to insert a key > high key, we know we need - * to move right (this should only happen if the page was split since we - * examined the parent page). + * page. The high key is not a tuple that is used to visit the heap. It is + * a pivot tuple (see "Notes on B-Tree tuple format" below for definition). + * The high key on a page is required to be greater than or equal to any + * other key that appears on the page. If we find ourselves trying to + * insert a key that is strictly > high key, we know we need to move right + * (this should only happen if the page was split since we examined the + * parent page). * * Our insertion algorithm guarantees that we can use the initial least key * on our right sibling as the high key. Once a page is created, its high @@ -186,68 +218,151 @@ typedef struct BTMetaPageData #define P_FIRSTKEY ((OffsetNumber) 2) #define P_FIRSTDATAKEY(opaque) (P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY) - /* - * B-tree index with INCLUDE clause has non-key (included) attributes, which - * are used solely in index-only scans. Those non-key attributes are present - * in leaf index tuples which point to corresponding heap tuples. However, - * tree also contains "pivot" tuples. Pivot tuples are used for navigation - * during tree traversal. Pivot tuples include tuples on non-leaf pages and - * high key tuples. Such, tuples don't need to included attributes, because - * they have no use during tree traversal. This is why we truncate them in - * order to save some space. Therefore, B-tree index with INCLUDE clause - * contain tuples with variable number of attributes. - * - * In order to keep on-disk compatibility with upcoming suffix truncation of - * pivot tuples, we store number of attributes present inside tuple itself. - * Thankfully, offset number is always unused in pivot tuple. So, we use free - * bit of index tuple flags as sign that offset have alternative meaning: it - * stores number of keys present in index tuple (12 bit is far enough for that). - * And we have 4 bits reserved for future usage. - * - * Right now INDEX_ALT_TID_MASK is set only on truncation of non-key - * attributes of included indexes. But potentially every pivot index tuple - * might have INDEX_ALT_TID_MASK set. Then this tuple should have number of - * attributes correctly set in BT_N_KEYS_OFFSET_MASK, and in future it might - * use some bits of BT_RESERVED_OFFSET_MASK. - * - * Non-pivot tuples might also use bit of BT_RESERVED_OFFSET_MASK. Despite - * they store heap tuple offset, higher bits of offset are always free. - */ -#define INDEX_ALT_TID_MASK INDEX_AM_RESERVED_BIT /* flag indicating t_tid - * offset has an - * alternative meaning */ -#define BT_RESERVED_OFFSET_MASK 0xF000 /* mask of bits in t_tid offset - * reserved for future usage */ -#define BT_N_KEYS_OFFSET_MASK 0x0FFF /* mask of bits in t_tid offset - * holding number of attributes - * actually present in index tuple */ - -/* Acess to downlink block number */ + * Notes on B-Tree tuple format, and key and non-key attributes: + * + * INCLUDE B-Tree indexes have non-key attributes. These are extra + * attributes that may be returned by index-only scans, but do not influence + * the order of items in the index (formally, non-key attributes are not + * considered to be part of the key space). Non-key attributes are only + * present in leaf index tuples whose item pointers actually point to heap + * tuples (non-pivot tuples). _bt_check_natts() enforces the rules + * described here. + * + * Non-pivot tuple format: + * + * t_tid | t_info | key values | INCLUDE columns, if any + * + * t_tid points to the heap TID, which is a tiebreaker key column as of + * BTREE_VERSION 4. Currently, the INDEX_ALT_TID_MASK status bit is never + * set for non-pivot tuples. + * + * All other types of index tuples ("pivot" tuples) only have key columns, + * since pivot tuples only exist to represent how the key space is + * separated. In general, any B-Tree index that has more than one level + * (i.e. any index that does not just consist of a metapage and a single + * leaf root page) must have some number of pivot tuples, since pivot + * tuples are used for traversing the tree. Suffix truncation can omit + * trailing key columns when a new pivot is formed, which makes minus + * infinity their logical value. Since BTREE_VERSION 4 indexes treat heap + * TID as a trailing key column that ensures that all index tuples are + * physically unique, it is necessary to represent heap TID as a trailing + * key column in pivot tuples, though very often this can be truncated + * away, just like any other key column. (Actually, the heap TID is + * omitted rather than truncated, since its representation is different to + * the non-pivot representation.) + * + * Pivot tuple format: + * + * t_tid | t_info | key values | [heap TID] + * + * We store the number of columns present inside pivot tuples by abusing + * their t_tid offset field, since pivot tuples never need to store a real + * offset (downlinks only need to store a block number in t_tid). The + * offset field only stores the number of columns/attributes when the + * INDEX_ALT_TID_MASK bit is set, which doesn't count the trailing heap + * TID column sometimes stored in pivot tuples -- that's represented by + * the presence of BT_HEAP_TID_ATTR. The INDEX_ALT_TID_MASK bit in t_info + * is always set on BTREE_VERSION 4. BT_HEAP_TID_ATTR can only be set on + * BTREE_VERSION 4. + * + * In version 3 indexes, the INDEX_ALT_TID_MASK flag might not be set in + * pivot tuples. In that case, the number of key columns is implicitly + * the same as the number of key columns in the index. It is not usually + * set on version 2 indexes, which predate the introduction of INCLUDE + * indexes. (Only explicitly truncated pivot tuples explicitly represent + * the number of key columns on versions 2 and 3, whereas all pivot tuples + * are formed using truncation on version 4. A version 2 index will have + * it set for an internal page negative infinity item iff internal page + * split occurred after upgrade to Postgres 11+.) + * + * The 12 least significant offset bits from t_tid are used to represent + * the number of columns in INDEX_ALT_TID_MASK tuples, leaving 4 status + * bits (BT_RESERVED_OFFSET_MASK bits), 3 of which that are reserved for + * future use. BT_N_KEYS_OFFSET_MASK should be large enough to store any + * number of columns/attributes <= INDEX_MAX_KEYS. + * + * Note well: The macros that deal with the number of attributes in tuples + * assume that a tuple with INDEX_ALT_TID_MASK set must be a pivot tuple, + * and that a tuple without INDEX_ALT_TID_MASK set must be a non-pivot + * tuple (or must have the same number of attributes as the index has + * generally in the case of !heapkeyspace indexes). They will need to be + * updated if non-pivot tuples ever get taught to use INDEX_ALT_TID_MASK + * for something else. + */ +#define INDEX_ALT_TID_MASK INDEX_AM_RESERVED_BIT + +/* Item pointer offset bits */ +#define BT_RESERVED_OFFSET_MASK 0xF000 +#define BT_N_KEYS_OFFSET_MASK 0x0FFF +#define BT_HEAP_TID_ATTR 0x1000 + +/* Get/set downlink block number */ #define BTreeInnerTupleGetDownLink(itup) \ ItemPointerGetBlockNumberNoCheck(&((itup)->t_tid)) - #define BTreeInnerTupleSetDownLink(itup, blkno) \ ItemPointerSetBlockNumber(&((itup)->t_tid), (blkno)) -/* Set number of attributes to B-tree index tuple overriding t_tid offset */ -#define BTreeTupSetNAtts(itup, n) \ +/* + * Get/set leaf page highkey's link. During the second phase of deletion, the + * target leaf page's high key may point to an ancestor page (at all other + * times, the leaf level high key's link is not used). See the nbtree README + * for full details. + */ +#define BTreeTupleGetTopParent(itup) \ + ItemPointerGetBlockNumberNoCheck(&((itup)->t_tid)) +#define BTreeTupleSetTopParent(itup, blkno) \ do { \ - (itup)->t_info |= INDEX_ALT_TID_MASK; \ - ItemPointerSetOffsetNumber(&(itup)->t_tid, n); \ + ItemPointerSetBlockNumber(&((itup)->t_tid), (blkno)); \ + BTreeTupleSetNAtts((itup), 0); \ } while(0) -/* Get number of attributes in B-tree index tuple */ -#define BTreeTupGetNAtts(itup, index) \ +/* + * Get/set number of attributes within B-tree index tuple. + * + * Note that this does not include an implicit tiebreaker heap TID + * attribute, if any. Note also that the number of key attributes must be + * explicitly represented in all heapkeyspace pivot tuples. + */ +#define BTreeTupleGetNAtts(itup, rel) \ ( \ (itup)->t_info & INDEX_ALT_TID_MASK ? \ ( \ - AssertMacro((ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_RESERVED_OFFSET_MASK) == 0), \ ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_N_KEYS_OFFSET_MASK \ ) \ : \ - IndexRelationGetNumberOfAttributes(index) \ + IndexRelationGetNumberOfAttributes(rel) \ ) +#define BTreeTupleSetNAtts(itup, n) \ + do { \ + (itup)->t_info |= INDEX_ALT_TID_MASK; \ + ItemPointerSetOffsetNumber(&(itup)->t_tid, (n) & BT_N_KEYS_OFFSET_MASK); \ + } while(0) + +/* + * Get tiebreaker heap TID attribute, if any. Macro works with both pivot + * and non-pivot tuples, despite differences in how heap TID is represented. + */ +#define BTreeTupleGetHeapTID(itup) \ + ( \ + (itup)->t_info & INDEX_ALT_TID_MASK && \ + (ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_HEAP_TID_ATTR) != 0 ? \ + ( \ + (ItemPointer) (((char *) (itup) + IndexTupleSize(itup)) - \ + sizeof(ItemPointerData)) \ + ) \ + : (itup)->t_info & INDEX_ALT_TID_MASK ? NULL : (ItemPointer) &((itup)->t_tid) \ + ) +/* + * Set the heap TID attribute for a tuple that uses the INDEX_ALT_TID_MASK + * representation (currently limited to pivot tuples) + */ +#define BTreeTupleSetAltHeapTID(itup) \ + do { \ + Assert((itup)->t_info & INDEX_ALT_TID_MASK); \ + ItemPointerSetOffsetNumber(&(itup)->t_tid, \ + ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) | BT_HEAP_TID_ATTR); \ + } while(0) /* * Operator strategy numbers for B-tree have been moved to access/stratnum.h, @@ -262,8 +377,7 @@ typedef struct BTMetaPageData * When a new operator class is declared, we require that the user * supply us with an amproc procedure (BTORDER_PROC) for determining * whether, for two keys a and b, a < b, a = b, or a > b. This routine - * must return < 0, 0, > 0, respectively, in these three cases. (It must - * not return INT_MIN, since we may negate the result before using it.) + * must return < 0, 0, > 0, respectively, in these three cases. * * To facilitate accelerated sorting, an operator class may choose to * offer a second procedure (BTSORTSUPPORT_PROC). For full details, see @@ -289,25 +403,114 @@ typedef struct BTMetaPageData #define BT_WRITE BUFFER_LOCK_EXCLUSIVE /* - * BTStackData -- As we descend a tree, we push the (location, downlink) - * pairs from internal pages onto a private stack. If we split a - * leaf, we use this stack to walk back up the tree and insert data - * into parent pages (and possibly to split them, too). Lehman and - * Yao's update algorithm guarantees that under no circumstances can - * our private stack give us an irredeemably bad picture up the tree. - * Again, see the paper for details. + * BTStackData -- As we descend a tree, we push the location of pivot + * tuples whose downlink we are about to follow onto a private stack. If + * we split a leaf, we use this stack to walk back up the tree and insert + * data into its parent page at the correct location. We also have to + * recursively insert into the grandparent page if and when the parent page + * splits. Our private stack can become stale due to concurrent page + * splits and page deletions, but it should never give us an irredeemably + * bad picture. */ - typedef struct BTStackData { BlockNumber bts_blkno; OffsetNumber bts_offset; - BlockNumber bts_btentry; struct BTStackData *bts_parent; } BTStackData; typedef BTStackData *BTStack; +/* + * BTScanInsertData is the btree-private state needed to find an initial + * position for an indexscan, or to insert new tuples -- an "insertion + * scankey" (not to be confused with a search scankey). It's used to descend + * a B-Tree using _bt_search. + * + * heapkeyspace indicates if we expect all keys in the index to be physically + * unique because heap TID is used as a tiebreaker attribute, and if index may + * have truncated key attributes in pivot tuples. This is actually a property + * of the index relation itself (not an indexscan). heapkeyspace indexes are + * indexes whose version is >= version 4. It's convenient to keep this close + * by, rather than accessing the metapage repeatedly. + * + * anynullkeys indicates if any of the keys had NULL value when scankey was + * built from index tuple (note that already-truncated tuple key attributes + * set NULL as a placeholder key value, which also affects value of + * anynullkeys). This is a convenience for unique index non-pivot tuple + * insertion, which usually temporarily unsets scantid, but shouldn't iff + * anynullkeys is true. Value generally matches non-pivot tuple's HasNulls + * bit, but may not when inserting into an INCLUDE index (tuple header value + * is affected by the NULL-ness of both key and non-key attributes). + * + * When nextkey is false (the usual case), _bt_search and _bt_binsrch will + * locate the first item >= scankey. When nextkey is true, they will locate + * the first item > scan key. + * + * pivotsearch is set to true by callers that want to re-find a leaf page + * using a scankey built from a leaf page's high key. Most callers set this + * to false. + * + * scantid is the heap TID that is used as a final tiebreaker attribute. It + * is set to NULL when index scan doesn't need to find a position for a + * specific physical tuple. Must be set when inserting new tuples into + * heapkeyspace indexes, since every tuple in the tree unambiguously belongs + * in one exact position (it's never set with !heapkeyspace indexes, though). + * Despite the representational difference, nbtree search code considers + * scantid to be just another insertion scankey attribute. + * + * scankeys is an array of scan key entries for attributes that are compared + * before scantid (user-visible attributes). keysz is the size of the array. + * During insertion, there must be a scan key for every attribute, but when + * starting a regular index scan some can be omitted. The array is used as a + * flexible array member, though it's sized in a way that makes it possible to + * use stack allocations. See nbtree/README for full details. + */ +typedef struct BTScanInsertData +{ + bool heapkeyspace; + bool anynullkeys; + bool nextkey; + bool pivotsearch; + ItemPointer scantid; /* tiebreaker for scankeys */ + int keysz; /* Size of scankeys array */ + ScanKeyData scankeys[INDEX_MAX_KEYS]; /* Must appear last */ +} BTScanInsertData; + +typedef BTScanInsertData *BTScanInsert; + +/* + * BTInsertStateData is a working area used during insertion. + * + * This is filled in after descending the tree to the first leaf page the new + * tuple might belong on. Tracks the current position while performing + * uniqueness check, before we have determined which exact page to insert + * to. + * + * (This should be private to nbtinsert.c, but it's also used by + * _bt_binsrch_insert) + */ +typedef struct BTInsertStateData +{ + IndexTuple itup; /* Item we're inserting */ + Size itemsz; /* Size of itup -- should be MAXALIGN()'d */ + BTScanInsert itup_key; /* Insertion scankey */ + + /* Buffer containing leaf page we're likely to insert itup on */ + Buffer buf; + + /* + * Cache of bounds within the current buffer. Only used for insertions + * where _bt_check_unique is called. See _bt_binsrch_insert and + * _bt_findinsertloc for details. + */ + bool bounds_valid; + OffsetNumber low; + OffsetNumber stricthigh; +} BTInsertStateData; + +typedef BTInsertStateData *BTInsertState; + /* * BTScanOpaqueData is the btree-private state needed for an indexscan. * This consists of preprocessed scan keys (see _bt_preprocess_keys() for @@ -477,31 +680,41 @@ typedef BTScanOpaqueData *BTScanOpaque; #define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT) #define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT) +/* + * Constant definition for progress reporting. Phase numbers must match + * btbuildphasename. + */ +/* PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE is 1 (see progress.h) */ +#define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN 2 +#define PROGRESS_BTREE_PHASE_PERFORMSORT_1 3 +#define PROGRESS_BTREE_PHASE_PERFORMSORT_2 4 +#define PROGRESS_BTREE_PHASE_LEAF_LOAD 5 + /* * external entry points for btree, in nbtree.c */ extern void btbuildempty(Relation index); extern bool btinsert(Relation rel, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); extern IndexScanDesc btbeginscan(Relation rel, int nkeys, int norderbys); extern Size btestimateparallelscan(void); extern void btinitparallelscan(void *target); extern bool btgettuple(IndexScanDesc scan, ScanDirection dir); extern int64 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern void btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern void btparallelrescan(IndexScanDesc scan); extern void btendscan(IndexScanDesc scan); extern void btmarkpos(IndexScanDesc scan); extern void btrestrpos(IndexScanDesc scan); extern IndexBulkDeleteResult *btbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *btvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); extern bool btcanreturn(Relation index, int attno); /* @@ -516,59 +729,60 @@ extern void _bt_parallel_advance_array_keys(IndexScanDesc scan); * prototypes for functions in nbtinsert.c */ extern bool _bt_doinsert(Relation rel, IndexTuple itup, - IndexUniqueCheck checkUnique, Relation heapRel); -extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, int access); + IndexUniqueCheck checkUnique, Relation heapRel); extern void _bt_finish_split(Relation rel, Buffer bbuf, BTStack stack); +extern Buffer _bt_getstackbuf(Relation rel, BTStack stack, BlockNumber child); + +/* + * prototypes for functions in nbtsplitloc.c + */ +extern OffsetNumber _bt_findsplitloc(Relation rel, Page page, + OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem, + bool *newitemonleft); /* * prototypes for functions in nbtpage.c */ extern void _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level); extern void _bt_update_meta_cleanup_info(Relation rel, - TransactionId oldestBtpoXact, float8 numHeapTuples); + TransactionId oldestBtpoXact, float8 numHeapTuples); extern void _bt_upgrademetapage(Page page); extern Buffer _bt_getroot(Relation rel, int access); extern Buffer _bt_gettrueroot(Relation rel); extern int _bt_getrootheight(Relation rel); +extern bool _bt_heapkeyspace(Relation rel); extern void _bt_checkpage(Relation rel, Buffer buf); extern Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access); extern Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, - BlockNumber blkno, int access); + BlockNumber blkno, int access); extern void _bt_relbuf(Relation rel, Buffer buf); extern void _bt_pageinit(Page page, Size size); extern bool _bt_page_recyclable(Page page); extern void _bt_delitems_delete(Relation rel, Buffer buf, - OffsetNumber *itemnos, int nitems, Relation heapRel); + OffsetNumber *itemnos, int nitems, Relation heapRel); extern void _bt_delitems_vacuum(Relation rel, Buffer buf, - OffsetNumber *itemnos, int nitems, - BlockNumber lastBlockVacuumed); + OffsetNumber *itemnos, int nitems, + BlockNumber lastBlockVacuumed); extern int _bt_pagedel(Relation rel, Buffer buf); /* * prototypes for functions in nbtsearch.c */ -extern BTStack _bt_search(Relation rel, - int keysz, ScanKey scankey, bool nextkey, - Buffer *bufP, int access, Snapshot snapshot); -extern Buffer _bt_moveright(Relation rel, Buffer buf, int keysz, - ScanKey scankey, bool nextkey, bool forupdate, BTStack stack, - int access, Snapshot snapshot); -extern OffsetNumber _bt_binsrch(Relation rel, Buffer buf, int keysz, - ScanKey scankey, bool nextkey); -extern int32 _bt_compare(Relation rel, int keysz, ScanKey scankey, - Page page, OffsetNumber offnum); +extern BTStack _bt_search(Relation rel, BTScanInsert key, Buffer *bufP, + int access, Snapshot snapshot); +extern Buffer _bt_moveright(Relation rel, BTScanInsert key, Buffer buf, + bool forupdate, BTStack stack, int access, Snapshot snapshot); +extern OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate); +extern int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum); extern bool _bt_first(IndexScanDesc scan, ScanDirection dir); extern bool _bt_next(IndexScanDesc scan, ScanDirection dir); extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost, - Snapshot snapshot); -extern bool _bt_check_natts(Relation index, Page page, OffsetNumber offnum); + Snapshot snapshot); /* * prototypes for functions in nbtutils.c */ -extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup); -extern ScanKey _bt_mkscankey_nodata(Relation rel); -extern void _bt_freeskey(ScanKey skey); +extern BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup); extern void _bt_freestack(BTStack stack); extern void _bt_preprocess_array_keys(IndexScanDesc scan); extern void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir); @@ -576,9 +790,8 @@ extern bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir); extern void _bt_mark_array_keys(IndexScanDesc scan); extern void _bt_restore_array_keys(IndexScanDesc scan); extern void _bt_preprocess_keys(IndexScanDesc scan); -extern IndexTuple _bt_checkkeys(IndexScanDesc scan, - Page page, OffsetNumber offnum, - ScanDirection dir, bool *continuescan); +extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, + int tupnatts, ScanDirection dir, bool *continuescan); extern void _bt_killitems(IndexScanDesc scan); extern BTCycleId _bt_vacuum_cycleid(Relation rel); extern BTCycleId _bt_start_vacuum(Relation rel); @@ -588,9 +801,17 @@ extern Size BTreeShmemSize(void); extern void BTreeShmemInit(void); extern bytea *btoptions(Datum reloptions, bool validate); extern bool btproperty(Oid index_oid, int attno, - IndexAMProperty prop, const char *propname, - bool *res, bool *isnull); -extern IndexTuple _bt_truncate_tuple(Relation idxrel, IndexTuple olditup); + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); +extern char *btbuildphasename(int64 phasenum); +extern IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, + IndexTuple firstright, BTScanInsert itup_key); +extern int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, + IndexTuple firstright); +extern bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, + OffsetNumber offnum); +extern void _bt_check_third_page(Relation rel, Relation heap, + bool needheaptidspace, Page page, IndexTuple newtup); /* * prototypes for functions in nbtvalidate.c @@ -601,7 +822,7 @@ extern bool btvalidate(Oid opclassoid); * prototypes for functions in nbtsort.c */ extern IndexBuildResult *btbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc); #endif /* NBTREE_H */ diff --git a/src/include/access/nbtxlog.h b/src/include/access/nbtxlog.h index c55b618ff7d..91b9ee00cfc 100644 --- a/src/include/access/nbtxlog.h +++ b/src/include/access/nbtxlog.h @@ -3,7 +3,7 @@ * nbtxlog.h * header file for postgres btree xlog routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/nbtxlog.h @@ -28,8 +28,7 @@ #define XLOG_BTREE_INSERT_META 0x20 /* same, plus update metapage */ #define XLOG_BTREE_SPLIT_L 0x30 /* add index tuple with split */ #define XLOG_BTREE_SPLIT_R 0x40 /* as above, new item on right */ -#define XLOG_BTREE_SPLIT_L_HIGHKEY 0x50 /* as above, include truncated highkey */ -#define XLOG_BTREE_SPLIT_R_HIGHKEY 0x60 /* as above, include truncated highkey */ +/* 0x50 and 0x60 are unused */ #define XLOG_BTREE_DELETE 0x70 /* delete leaf index tuples for a page */ #define XLOG_BTREE_UNLINK_PAGE 0x80 /* delete a half-dead page */ #define XLOG_BTREE_UNLINK_PAGE_META 0x90 /* same, and update metapage */ @@ -47,12 +46,13 @@ */ typedef struct xl_btree_metadata { + uint32 version; BlockNumber root; uint32 level; BlockNumber fastroot; uint32 fastlevel; TransactionId oldest_btpo_xact; - double last_cleanup_num_heap_tuples; + float8 last_cleanup_num_heap_tuples; } xl_btree_metadata; /* @@ -80,27 +80,29 @@ typedef struct xl_btree_insert * whole page image. The left page, however, is handled in the normal * incremental-update fashion. * - * Note: the four XLOG_BTREE_SPLIT xl_info codes all use this data record. - * The _L and _R variants indicate whether the inserted tuple went into the - * left or right split page (and thus, whether newitemoff and the new item - * are stored or not). The _HIGHKEY variants indicate that we've logged - * explicitly left page high key value, otherwise redo should use right page - * leftmost key as a left page high key. _HIGHKEY is specified for internal - * pages where right page leftmost key is suppressed, and for leaf pages - * of covering indexes where high key have non-key attributes truncated. + * Note: XLOG_BTREE_SPLIT_L and XLOG_BTREE_SPLIT_R share this data record. + * There are two variants to indicate whether the inserted tuple went into the + * left or right split page (and thus, whether the new item is stored or not). + * We always log the left page high key because suffix truncation can generate + * a new leaf high key using user-defined code. This is also necessary on + * internal pages, since the first right item that the left page's high key + * was based on will have been truncated to zero attributes in the right page + * (the original is unavailable from the right page). * * Backup Blk 0: original page / new left page * * The left page's data portion contains the new item, if it's the _L variant. - * (In the _R variants, the new item is one of the right page's tuples.) - * If level > 0, an IndexTuple representing the HIKEY of the left page - * follows. We don't need this on leaf pages, because it's the same as the - * leftmost key in the new right page. + * An IndexTuple representing the high key of the left page must follow with + * either variant. * * Backup Blk 1: new right page * - * The right page's data portion contains the right page's tuples in the - * form used by _bt_restore_page. + * The right page's data portion contains the right page's tuples in the form + * used by _bt_restore_page. This includes the new item, if it's the _R + * variant. The right page's tuples also include the right page's high key + * with either variant (moved from the left/original page during the split), + * unless the split happened to be of the rightmost page on its level, where + * there is no high key for new right page. * * Backup Blk 2: next block (orig page's rightlink), if any * Backup Blk 3: child's left sibling, if non-leaf split @@ -109,7 +111,7 @@ typedef struct xl_btree_split { uint32 level; /* tree level of page being split */ OffsetNumber firstright; /* first item moved to right page */ - OffsetNumber newitemoff; /* new item's offset (if placed on left page) */ + OffsetNumber newitemoff; /* new item's offset (useful for _L variant) */ } xl_btree_split; #define SizeOfBtreeSplit (offsetof(xl_btree_split, newitemoff) + sizeof(OffsetNumber)) @@ -123,8 +125,7 @@ typedef struct xl_btree_split */ typedef struct xl_btree_delete { - RelFileNode hnode; /* RelFileNode of the heap the index currently - * points at */ + TransactionId latestRemovedXid; int nitems; /* TARGET OFFSET NUMBERS FOLLOW AT THE END */ @@ -257,4 +258,4 @@ extern void btree_desc(StringInfo buf, XLogReaderState *record); extern const char *btree_identify(uint8 info); extern void btree_mask(char *pagedata, BlockNumber blkno); -#endif /* NBXLOG_H */ +#endif /* NBTXLOG_H */ diff --git a/src/include/access/parallel.h b/src/include/access/parallel.h index 025691fd82d..c00ae6424c2 100644 --- a/src/include/access/parallel.h +++ b/src/include/access/parallel.h @@ -3,7 +3,7 @@ * parallel.h * Infrastructure for launching parallel workers * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/parallel.h @@ -60,8 +60,7 @@ extern PGDLLIMPORT bool InitializingParallelWorker; #define IsParallelWorker() (ParallelWorkerNumber >= 0) extern ParallelContext *CreateParallelContext(const char *library_name, - const char *function_name, int nworkers, - bool serializable_okay); + const char *function_name, int nworkers); extern void InitializeParallelDSM(ParallelContext *pcxt); extern void ReinitializeParallelDSM(ParallelContext *pcxt); extern void LaunchParallelWorkers(ParallelContext *pcxt); diff --git a/src/include/access/printsimple.h b/src/include/access/printsimple.h index 4184f16560c..be81f361917 100644 --- a/src/include/access/printsimple.h +++ b/src/include/access/printsimple.h @@ -3,7 +3,7 @@ * printsimple.h * print simple tuples without catalog access * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/printsimple.h @@ -18,6 +18,6 @@ extern bool printsimple(TupleTableSlot *slot, DestReceiver *self); extern void printsimple_startup(DestReceiver *self, int operation, - TupleDesc tupdesc); + TupleDesc tupdesc); #endif /* PRINTSIMPLE_H */ diff --git a/src/include/access/printtup.h b/src/include/access/printtup.h index 94f8d705b52..ab78c5e8803 100644 --- a/src/include/access/printtup.h +++ b/src/include/access/printtup.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/printtup.h @@ -21,15 +21,15 @@ extern DestReceiver *printtup_create_DR(CommandDest dest); extern void SetRemoteDestReceiverParams(DestReceiver *self, Portal portal); extern void SendRowDescriptionMessage(StringInfo buf, - TupleDesc typeinfo, List *targetlist, int16 *formats); + TupleDesc typeinfo, List *targetlist, int16 *formats); extern void debugStartup(DestReceiver *self, int operation, - TupleDesc typeinfo); + TupleDesc typeinfo); extern bool debugtup(TupleTableSlot *slot, DestReceiver *self); /* XXX these are really in executor/spi.c */ extern void spi_dest_startup(DestReceiver *self, int operation, - TupleDesc typeinfo); + TupleDesc typeinfo); extern bool spi_printtup(TupleTableSlot *slot, DestReceiver *self); #endif /* PRINTTUP_H */ diff --git a/src/include/access/relation.h b/src/include/access/relation.h new file mode 100644 index 00000000000..38acaa5a2e9 --- /dev/null +++ b/src/include/access/relation.h @@ -0,0 +1,29 @@ +/*------------------------------------------------------------------------- + * + * relation.h + * Generic relation related routines. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/relation.h + * + *------------------------------------------------------------------------- + */ +#ifndef ACCESS_RELATION_H +#define ACCESS_RELATION_H + +#include "nodes/primnodes.h" +#include "utils/relcache.h" +#include "storage/lockdefs.h" + + +extern Relation relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); +extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation relation_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern void relation_close(Relation relation, LOCKMODE lockmode); + +#endif /* ACCESS_RELATION_H */ diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h index ef09611e0d6..6bde2093d61 100644 --- a/src/include/access/reloptions.h +++ b/src/include/access/reloptions.h @@ -9,7 +9,7 @@ * into a lot of low-level code. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/reloptions.h @@ -31,6 +31,7 @@ typedef enum relopt_type RELOPT_TYPE_BOOL, RELOPT_TYPE_INT, RELOPT_TYPE_REAL, + RELOPT_TYPE_ENUM, RELOPT_TYPE_STRING } relopt_type; @@ -51,7 +52,6 @@ typedef enum relopt_kind RELOPT_KIND_PARTITIONED = (1 << 11), /* if you add a new kind, make sure you update "last_default" too */ RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_PARTITIONED, - RELOPT_KIND_INDEX = RELOPT_KIND_BTREE|RELOPT_KIND_HASH|RELOPT_KIND_GIN|RELOPT_KIND_SPGIST, /* some compilers treat enums as signed ints, so we can't use 1 << 31 */ RELOPT_KIND_MAX = (1 << 30) } relopt_kind; @@ -81,6 +81,7 @@ typedef struct relopt_value bool bool_val; int int_val; double real_val; + int enum_val; char *string_val; /* allocated separately */ } values; } relopt_value; @@ -108,6 +109,25 @@ typedef struct relopt_real double max; } relopt_real; +/* + * relopt_enum_elt_def -- One member of the array of acceptable values + * of an enum reloption. + */ +typedef struct relopt_enum_elt_def +{ + const char *string_val; + int symbol_val; +} relopt_enum_elt_def; + +typedef struct relopt_enum +{ + relopt_gen gen; + relopt_enum_elt_def *members; + int default_val; + const char *detailmsg; + /* null-terminated array of members */ +} relopt_enum; + /* validation routines for strings */ typedef void (*validate_string_relopt) (const char *value); @@ -238,7 +258,7 @@ typedef struct /* * For use by code reading options already parsed: get a pointer to the string - * value itself. "optstruct" is the StdRdOption struct or equivalent, "member" + * value itself. "optstruct" is the StdRdOptions struct or equivalent, "member" * is the struct member corresponding to the string option */ #define GET_STRING_RELOPTION(optstruct, member) \ @@ -248,36 +268,41 @@ typedef struct extern relopt_kind add_reloption_kind(void); extern void add_bool_reloption(bits32 kinds, const char *name, const char *desc, - bool default_val); + bool default_val, LOCKMODE lockmode); extern void add_int_reloption(bits32 kinds, const char *name, const char *desc, - int default_val, int min_val, int max_val); + int default_val, int min_val, int max_val, + LOCKMODE lockmode); extern void add_real_reloption(bits32 kinds, const char *name, const char *desc, - double default_val, double min_val, double max_val); + double default_val, double min_val, double max_val, + LOCKMODE lockmode); +extern void add_enum_reloption(bits32 kinds, const char *name, const char *desc, + relopt_enum_elt_def *members, int default_val, + const char *detailmsg, LOCKMODE lockmode); extern void add_string_reloption(bits32 kinds, const char *name, const char *desc, - const char *default_val, validate_string_relopt validator); + const char *default_val, validate_string_relopt validator, + LOCKMODE lockmode); extern Datum transformRelOptions(Datum oldOptions, List *defList, - const char *namspace, char *validnsps[], - bool ignoreOids, bool isReset); + const char *namspace, char *validnsps[], + bool acceptOidsOff, bool isReset); extern List *untransformRelOptions(Datum options); extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc, - amoptions_function amoptions); + amoptions_function amoptions); extern relopt_value *parseRelOptions(Datum options, bool validate, - relopt_kind kind, int *numrelopts); + relopt_kind kind, int *numrelopts); extern void *allocateReloptStruct(Size base, relopt_value *options, - int numoptions); + int numoptions); extern void fillRelOptions(void *rdopts, Size basesize, - relopt_value *options, int numoptions, - bool validate, - const relopt_parse_elt *elems, int nelems); + relopt_value *options, int numoptions, + bool validate, + const relopt_parse_elt *elems, int nelems); extern bytea *default_reloptions(Datum reloptions, bool validate, - relopt_kind kind); + relopt_kind kind); extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate); extern bytea *view_reloptions(Datum reloptions, bool validate); extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions, - bool validate); -extern bytea *index_generic_reloptions(Datum reloptions, bool validate); + bool validate); extern bytea *attribute_reloptions(Datum reloptions, bool validate); extern bytea *tablespace_reloptions(Datum reloptions, bool validate); extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList); diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 18c7dedd5d3..2bde2c2bc4e 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -4,7 +4,7 @@ * POSTGRES relation scan descriptor definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/relscan.h @@ -14,70 +14,82 @@ #ifndef RELSCAN_H #define RELSCAN_H -#include "access/genam.h" -#include "access/heapam.h" #include "access/htup_details.h" #include "access/itup.h" -#include "access/tupdesc.h" +#include "port/atomics.h" +#include "storage/buf.h" #include "storage/spin.h" +#include "utils/relcache.h" + + +struct ParallelTableScanDescData; /* - * Shared state for parallel heap scan. + * Generic descriptor for table scans. This is the base-class for table scans, + * which needs to be embedded in the scans of individual AMs. + */ +typedef struct TableScanDescData +{ + /* scan parameters */ + Relation rs_rd; /* heap relation descriptor */ + struct SnapshotData *rs_snapshot; /* snapshot to see */ + int rs_nkeys; /* number of scan keys */ + struct ScanKeyData *rs_key; /* array of scan key descriptors */ + + /* + * Information about type and behaviour of the scan, a bitmask of members + * of the ScanOptions enum (see tableam.h). + */ + uint32 rs_flags; + + struct ParallelTableScanDescData *rs_parallel; /* parallel scan + * information */ + +} TableScanDescData; +typedef struct TableScanDescData *TableScanDesc; + +/* + * Shared state for parallel table scan. * - * Each backend participating in a parallel heap scan has its own - * HeapScanDesc in backend-private memory, and those objects all contain - * a pointer to this structure. The information here must be sufficient - * to properly initialize each new HeapScanDesc as workers join the scan, - * and it must act as a font of block numbers for those workers. + * Each backend participating in a parallel table scan has its own + * TableScanDesc in backend-private memory, and those objects all contain a + * pointer to this structure. The information here must be sufficient to + * properly initialize each new TableScanDesc as workers join the scan, and it + * must act as a information what to scan for those workers. */ -typedef struct ParallelHeapScanDescData +typedef struct ParallelTableScanDescData { Oid phs_relid; /* OID of relation to scan */ bool phs_syncscan; /* report location to syncscan logic? */ + bool phs_snapshot_any; /* SnapshotAny, not phs_snapshot_data? */ + Size phs_snapshot_off; /* data for snapshot */ +} ParallelTableScanDescData; +typedef struct ParallelTableScanDescData *ParallelTableScanDesc; + +/* + * Shared state for parallel table scans, for block oriented storage. + */ +typedef struct ParallelBlockTableScanDescData +{ + ParallelTableScanDescData base; + BlockNumber phs_nblocks; /* # blocks in relation at start of scan */ slock_t phs_mutex; /* mutual exclusion for setting startblock */ BlockNumber phs_startblock; /* starting block number */ pg_atomic_uint64 phs_nallocated; /* number of blocks allocated to * workers so far. */ - bool phs_snapshot_any; /* SnapshotAny, not phs_snapshot_data? */ - char phs_snapshot_data[FLEXIBLE_ARRAY_MEMBER]; -} ParallelHeapScanDescData; +} ParallelBlockTableScanDescData; +typedef struct ParallelBlockTableScanDescData *ParallelBlockTableScanDesc; -typedef struct HeapScanDescData +/* + * Base class for fetches from a table via an index. This is the base-class + * for such scans, which needs to be embedded in the respective struct for + * individual AMs. + */ +typedef struct IndexFetchTableData { - /* scan parameters */ - Relation rs_rd; /* heap relation descriptor */ - Snapshot rs_snapshot; /* snapshot to see */ - int rs_nkeys; /* number of scan keys */ - ScanKey rs_key; /* array of scan key descriptors */ - bool rs_bitmapscan; /* true if this is really a bitmap scan */ - bool rs_samplescan; /* true if this is really a sample scan */ - bool rs_pageatatime; /* verify visibility page-at-a-time? */ - bool rs_allow_strat; /* allow or disallow use of access strategy */ - bool rs_allow_sync; /* allow or disallow use of syncscan */ - bool rs_temp_snap; /* unregister snapshot at scan end? */ - - /* state set up at initscan time */ - BlockNumber rs_nblocks; /* total number of blocks in rel */ - BlockNumber rs_startblock; /* block # to start at */ - BlockNumber rs_numblocks; /* max number of blocks to scan */ - /* rs_numblocks is usually InvalidBlockNumber, meaning "scan whole rel" */ - BufferAccessStrategy rs_strategy; /* access strategy for reads */ - bool rs_syncscan; /* report location to syncscan logic? */ - - /* scan current state */ - bool rs_inited; /* false = scan not init'd yet */ - HeapTupleData rs_ctup; /* current tuple in scan, if any */ - BlockNumber rs_cblock; /* current block # in scan, if any */ - Buffer rs_cbuf; /* current buffer in scan, if any */ - /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ - ParallelHeapScanDesc rs_parallel; /* parallel scan information */ - - /* these fields only used in page-at-a-time mode and for bitmap scans */ - int rs_cindex; /* current tuple's index in vistuples */ - int rs_ntuples; /* number of visible tuples on page */ - OffsetNumber rs_vistuples[MaxHeapTuplesPerPage]; /* their offsets */ -} HeapScanDescData; + Relation rel; +} IndexFetchTableData; /* * We use the same IndexScanDescData structure for both amgettuple-based @@ -89,11 +101,11 @@ typedef struct IndexScanDescData /* scan parameters */ Relation heapRelation; /* heap relation descriptor, or NULL */ Relation indexRelation; /* index relation descriptor */ - Snapshot xs_snapshot; /* snapshot to see */ + struct SnapshotData *xs_snapshot; /* snapshot to see */ int numberOfKeys; /* number of index qualifier conditions */ int numberOfOrderBys; /* number of ordering operators */ - ScanKey keyData; /* array of index qualifier descriptors */ - ScanKey orderByData; /* array of ordering op descriptors */ + struct ScanKeyData *keyData; /* array of index qualifier descriptors */ + struct ScanKeyData *orderByData; /* array of ordering op descriptors */ bool xs_want_itup; /* caller requests index tuples */ bool xs_temp_snap; /* unregister snapshot at scan end? */ @@ -113,14 +125,15 @@ typedef struct IndexScanDescData * format will be used. */ IndexTuple xs_itup; /* index tuple returned by AM */ - TupleDesc xs_itupdesc; /* rowtype descriptor of xs_itup */ + struct TupleDescData *xs_itupdesc; /* rowtype descriptor of xs_itup */ HeapTuple xs_hitup; /* index data returned by AM, as HeapTuple */ - TupleDesc xs_hitupdesc; /* rowtype descriptor of xs_hitup */ + struct TupleDescData *xs_hitupdesc; /* rowtype descriptor of xs_hitup */ + + ItemPointerData xs_heaptid; /* result */ + bool xs_heap_continue; /* T if must keep walking, potential + * further results */ + IndexFetchTableData *xs_heapfetch; - /* xs_ctup/xs_cbuf/xs_recheck are valid after a successful index_getnext */ - HeapTupleData xs_ctup; /* current heap tuple, if any */ - Buffer xs_cbuf; /* current heap buffer in scan, if any */ - /* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */ bool xs_recheck; /* T means scan keys must be rechecked */ /* @@ -134,11 +147,8 @@ typedef struct IndexScanDescData bool *xs_orderbynulls; bool xs_recheckorderby; - /* state data for traversing HOT chains in index_getnext */ - bool xs_continue_hot; /* T if must keep walking HOT chain */ - /* parallel index scan information, in shared memory */ - ParallelIndexScanDesc parallel_scan; + struct ParallelIndexScanDescData *parallel_scan; } IndexScanDescData; /* Generic structure for parallel scans */ @@ -150,14 +160,17 @@ typedef struct ParallelIndexScanDescData char ps_snapshot_data[FLEXIBLE_ARRAY_MEMBER]; } ParallelIndexScanDescData; -/* Struct for heap-or-index scans of system tables */ +struct TupleTableSlot; + +/* Struct for storage-or-index scans of system tables */ typedef struct SysScanDescData { Relation heap_rel; /* catalog being scanned */ Relation irel; /* NULL if doing heap scan */ - HeapScanDesc scan; /* only valid in heap-scan case */ - IndexScanDesc iscan; /* only valid in index-scan case */ - Snapshot snapshot; /* snapshot to unregister at end of scan */ + struct TableScanDescData *scan; /* only valid in storage-scan case */ + struct IndexScanDescData *iscan; /* only valid in index-scan case */ + struct SnapshotData *snapshot; /* snapshot to unregister at end of scan */ + struct TupleTableSlot *slot; } SysScanDescData; #endif /* RELSCAN_H */ diff --git a/src/include/access/rewriteheap.h b/src/include/access/rewriteheap.h index 6d7f669cbca..80562539161 100644 --- a/src/include/access/rewriteheap.h +++ b/src/include/access/rewriteheap.h @@ -3,7 +3,7 @@ * rewriteheap.h * Declarations for heap rewrite support functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/access/rewriteheap.h @@ -22,11 +22,11 @@ typedef struct RewriteStateData *RewriteState; extern RewriteState begin_heap_rewrite(Relation OldHeap, Relation NewHeap, - TransactionId OldestXmin, TransactionId FreezeXid, - MultiXactId MultiXactCutoff, bool use_wal); + TransactionId OldestXmin, TransactionId FreezeXid, + MultiXactId MultiXactCutoff, bool use_wal); extern void end_heap_rewrite(RewriteState state); extern void rewrite_heap_tuple(RewriteState state, HeapTuple oldTuple, - HeapTuple newTuple); + HeapTuple newTuple); extern bool rewrite_heap_dead_tuple(RewriteState state, HeapTuple oldTuple); /* @@ -45,9 +45,9 @@ typedef struct LogicalRewriteMappingData * components: * 1) database oid or InvalidOid for shared relations * 2) the oid of the relation - * 3) xid we are mapping for - * 4) upper 32bit of the LSN at which a rewrite started - * 5) lower 32bit of the LSN at which a rewrite started + * 3) upper 32bit of the LSN at which a rewrite started + * 4) lower 32bit of the LSN at which a rewrite started + * 5) xid we are mapping for * 6) xid of the xact performing the mapping * --- */ diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h index 0bbe9879ca1..3c0db2ccf5f 100644 --- a/src/include/access/rmgrlist.h +++ b/src/include/access/rmgrlist.h @@ -6,7 +6,7 @@ * by the PG_RMGR macro, which is not defined in this file; it can be * defined by the caller for special purposes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/rmgrlist.h diff --git a/src/include/access/sdir.h b/src/include/access/sdir.h index 490bac11d31..664e72ef5df 100644 --- a/src/include/access/sdir.h +++ b/src/include/access/sdir.h @@ -4,7 +4,7 @@ * POSTGRES scan direction definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/sdir.h diff --git a/src/include/access/session.h b/src/include/access/session.h index 37971c1c667..8fba5680299 100644 --- a/src/include/access/session.h +++ b/src/include/access/session.h @@ -3,7 +3,7 @@ * session.h * Encapsulation of user session. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/access/session.h * diff --git a/src/include/access/skey.h b/src/include/access/skey.h index ab3bb2c8eb8..b181ef930fe 100644 --- a/src/include/access/skey.h +++ b/src/include/access/skey.h @@ -4,7 +4,7 @@ * POSTGRES scan key definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/skey.h @@ -127,25 +127,25 @@ typedef ScanKeyData *ScanKey; * prototypes for functions in access/common/scankey.c */ extern void ScanKeyInit(ScanKey entry, - AttrNumber attributeNumber, - StrategyNumber strategy, - RegProcedure procedure, - Datum argument); + AttrNumber attributeNumber, + StrategyNumber strategy, + RegProcedure procedure, + Datum argument); extern void ScanKeyEntryInitialize(ScanKey entry, - int flags, - AttrNumber attributeNumber, - StrategyNumber strategy, - Oid subtype, - Oid collation, - RegProcedure procedure, - Datum argument); + int flags, + AttrNumber attributeNumber, + StrategyNumber strategy, + Oid subtype, + Oid collation, + RegProcedure procedure, + Datum argument); extern void ScanKeyEntryInitializeWithInfo(ScanKey entry, - int flags, - AttrNumber attributeNumber, - StrategyNumber strategy, - Oid subtype, - Oid collation, - FmgrInfo *finfo, - Datum argument); + int flags, + AttrNumber attributeNumber, + StrategyNumber strategy, + Oid subtype, + Oid collation, + FmgrInfo *finfo, + Datum argument); #endif /* SKEY_H */ diff --git a/src/include/access/slru.h b/src/include/access/slru.h index 0e89e48c974..b37eddb3464 100644 --- a/src/include/access/slru.h +++ b/src/include/access/slru.h @@ -3,7 +3,7 @@ * slru.h * Simple LRU buffering for transaction status logfiles * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/slru.h @@ -139,12 +139,12 @@ typedef SlruCtlData *SlruCtl; extern Size SimpleLruShmemSize(int nslots, int nlsns); extern void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, - LWLock *ctllock, const char *subdir, int tranche_id); + LWLock *ctllock, const char *subdir, int tranche_id); extern int SimpleLruZeroPage(SlruCtl ctl, int pageno); -extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, - TransactionId xid); -extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, - TransactionId xid); +extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, + TransactionId xid); +extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, + TransactionId xid); extern void SimpleLruWritePage(SlruCtl ctl, int slotno); extern void SimpleLruFlush(SlruCtl ctl, bool allow_redirtied); extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage); @@ -157,8 +157,8 @@ extern void SlruDeleteSegment(SlruCtl ctl, int segno); /* SlruScanDirectory public callbacks */ extern bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, - int segpage, void *data); + int segpage, void *data); extern bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, - void *data); + void *data); #endif /* SLRU_H */ diff --git a/src/include/access/spgist.h b/src/include/access/spgist.h index c6d7e22a389..d787ab213dc 100644 --- a/src/include/access/spgist.h +++ b/src/include/access/spgist.h @@ -4,7 +4,7 @@ * Public header file for SP-GiST access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/spgist.h @@ -16,7 +16,6 @@ #include "access/amapi.h" #include "access/xlogreader.h" -#include "fmgr.h" #include "lib/stringinfo.h" @@ -136,7 +135,10 @@ typedef struct spgPickSplitOut typedef struct spgInnerConsistentIn { ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ Datum reconstructedValue; /* value reconstructed at parent */ void *traversalValue; /* opclass-specific traverse value */ @@ -159,6 +161,7 @@ typedef struct spgInnerConsistentOut int *levelAdds; /* increment level by this much for each */ Datum *reconstructedValues; /* associated reconstructed values */ void **traversalValues; /* opclass-specific traverse values */ + double **distances; /* associated distances */ } spgInnerConsistentOut; /* @@ -167,7 +170,10 @@ typedef struct spgInnerConsistentOut typedef struct spgLeafConsistentIn { ScanKey scankeys; /* array of operators and comparison values */ - int nkeys; /* length of array */ + ScanKey orderbys; /* array of ordering operators and comparison + * values */ + int nkeys; /* length of scankeys array */ + int norderbys; /* length of orderbys array */ Datum reconstructedValue; /* value reconstructed at parent */ void *traversalValue; /* opclass-specific traverse value */ @@ -181,6 +187,8 @@ typedef struct spgLeafConsistentOut { Datum leafValue; /* reconstructed original data, if any */ bool recheck; /* set true if operator must be rechecked */ + bool recheckDistances; /* set true if distances must be rechecked */ + double *distances; /* associated distances */ } spgLeafConsistentOut; @@ -189,29 +197,29 @@ extern bytea *spgoptions(Datum reloptions, bool validate); /* spginsert.c */ extern IndexBuildResult *spgbuild(Relation heap, Relation index, - struct IndexInfo *indexInfo); + struct IndexInfo *indexInfo); extern void spgbuildempty(Relation index); extern bool spginsert(Relation index, Datum *values, bool *isnull, - ItemPointer ht_ctid, Relation heapRel, - IndexUniqueCheck checkUnique, - struct IndexInfo *indexInfo); + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + struct IndexInfo *indexInfo); /* spgscan.c */ extern IndexScanDesc spgbeginscan(Relation rel, int keysz, int orderbysz); extern void spgendscan(IndexScanDesc scan); extern void spgrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, - ScanKey orderbys, int norderbys); + ScanKey orderbys, int norderbys); extern int64 spggetbitmap(IndexScanDesc scan, TIDBitmap *tbm); extern bool spggettuple(IndexScanDesc scan, ScanDirection dir); extern bool spgcanreturn(Relation index, int attno); /* spgvacuum.c */ extern IndexBulkDeleteResult *spgbulkdelete(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats, - IndexBulkDeleteCallback callback, - void *callback_state); + IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, + void *callback_state); extern IndexBulkDeleteResult *spgvacuumcleanup(IndexVacuumInfo *info, - IndexBulkDeleteResult *stats); + IndexBulkDeleteResult *stats); /* spgvalidate.c */ extern bool spgvalidate(Oid opclassoid); diff --git a/src/include/access/spgist_private.h b/src/include/access/spgist_private.h index c5f1ee9ed9b..428e54bfbd2 100644 --- a/src/include/access/spgist_private.h +++ b/src/include/access/spgist_private.h @@ -4,7 +4,7 @@ * Private declarations for SP-GiST access method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/spgist_private.h @@ -18,6 +18,7 @@ #include "access/spgist.h" #include "nodes/tidbitmap.h" #include "storage/buf.h" +#include "utils/geo_decls.h" #include "utils/relcache.h" @@ -120,7 +121,7 @@ typedef struct SpGistState spgConfigOut config; /* filled in by opclass config method */ SpGistTypeDesc attType; /* type of values to be indexed/restored */ - SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ + SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */ SpGistTypeDesc attLabelType; /* type of node label values */ @@ -130,14 +131,35 @@ typedef struct SpGistState bool isBuild; /* true if doing index build */ } SpGistState; +typedef struct SpGistSearchItem +{ + pairingheap_node phNode; /* pairing heap node */ + Datum value; /* value reconstructed from parent or + * leafValue if heaptuple */ + void *traversalValue; /* opclass-specific traverse value */ + int level; /* level of items on this page */ + ItemPointerData heapPtr; /* heap info, if heap tuple */ + bool isNull; /* SearchItem is NULL item */ + bool isLeaf; /* SearchItem is heap item */ + bool recheck; /* qual recheck is needed */ + bool recheckDistances; /* distance recheck is needed */ + + /* array with numberOfOrderBys entries */ + double distances[FLEXIBLE_ARRAY_MEMBER]; +} SpGistSearchItem; + +#define SizeOfSpGistSearchItem(n_distances) \ + (offsetof(SpGistSearchItem, distances) + sizeof(double) * (n_distances)) + /* * Private state of an index scan */ typedef struct SpGistScanOpaqueData { SpGistState state; /* see above */ + pairingheap *scanQueue; /* queue of to be visited items */ MemoryContext tempCxt; /* short-lived memory context */ - MemoryContext traversalCxt; /* memory context for traversalValues */ + MemoryContext traversalCxt; /* single scan lifetime memory context */ /* Control flags showing whether to search nulls and/or non-nulls */ bool searchNulls; /* scan matches (all) null entries */ @@ -146,9 +168,22 @@ typedef struct SpGistScanOpaqueData /* Index quals to be passed to opclass (null-related quals removed) */ int numberOfKeys; /* number of index qualifier conditions */ ScanKey keyData; /* array of index qualifier descriptors */ - - /* Stack of yet-to-be-visited pages */ - List *scanStack; /* List of ScanStackEntrys */ + int numberOfOrderBys; /* number of ordering operators */ + int numberOfNonNullOrderBys; /* number of ordering operators + * with non-NULL arguments */ + ScanKey orderByData; /* array of ordering op descriptors */ + Oid *orderByTypes; /* array of ordering op return types */ + int *nonNullOrderByOffsets; /* array of offset of non-NULL + * ordering keys in the original array */ + Oid indexCollation; /* collation of index column */ + + /* Opclass defined functions: */ + FmgrInfo innerConsistentFn; + FmgrInfo leafConsistentFn; + + /* Pre-allocated workspace arrays: */ + double *zeroDistances; + double *infDistances; /* These fields are only used in amgetbitmap scans: */ TIDBitmap *tbm; /* bitmap being filled */ @@ -161,8 +196,13 @@ typedef struct SpGistScanOpaqueData int iPtr; /* index for scanning through same */ ItemPointerData heapPtrs[MaxIndexTuplesPerPage]; /* TIDs from cur page */ bool recheck[MaxIndexTuplesPerPage]; /* their recheck flags */ + bool recheckDistances[MaxIndexTuplesPerPage]; /* distance recheck + * flags */ HeapTuple reconTups[MaxIndexTuplesPerPage]; /* reconstructed tuples */ + /* distances (for recheck) */ + IndexOrderByDistance *distances[MaxIndexTuplesPerPage]; + /* * Note: using MaxIndexTuplesPerPage above is a bit hokey since * SpGistLeafTuples aren't exactly IndexTuples; however, they are larger, @@ -181,7 +221,7 @@ typedef struct SpGistCache spgConfigOut config; /* filled in by opclass config method */ SpGistTypeDesc attType; /* type of values to be indexed/restored */ - SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ + SpGistTypeDesc attLeafType; /* type of leaf-tuple values */ SpGistTypeDesc attPrefixType; /* type of inner-tuple prefix values */ SpGistTypeDesc attLabelType; /* type of node label values */ @@ -294,7 +334,7 @@ typedef struct SpGistLeafTupleData { unsigned int tupstate:2, /* LIVE/REDIRECT/DEAD/PLACEHOLDER */ size:30; /* large enough for any palloc'able value */ - OffsetNumber nextOffset; /* next tuple in chain, or InvalidOffset */ + OffsetNumber nextOffset; /* next tuple in chain, or InvalidOffsetNumber */ ItemPointerData heapPtr; /* TID of represented heap tuple */ /* leaf datum follows */ } SpGistLeafTupleData; @@ -388,37 +428,45 @@ extern void initSpGistState(SpGistState *state, Relation index); extern Buffer SpGistNewBuffer(Relation index); extern void SpGistUpdateMetaPage(Relation index); extern Buffer SpGistGetBuffer(Relation index, int flags, - int needSpace, bool *isNew); + int needSpace, bool *isNew); extern void SpGistSetLastUsedPage(Relation index, Buffer buffer); extern void SpGistInitPage(Page page, uint16 f); extern void SpGistInitBuffer(Buffer b, uint16 f); extern void SpGistInitMetapage(Page page); extern unsigned int SpGistGetTypeSize(SpGistTypeDesc *att, Datum datum); extern SpGistLeafTuple spgFormLeafTuple(SpGistState *state, - ItemPointer heapPtr, - Datum datum, bool isnull); + ItemPointer heapPtr, + Datum datum, bool isnull); extern SpGistNodeTuple spgFormNodeTuple(SpGistState *state, - Datum label, bool isnull); + Datum label, bool isnull); extern SpGistInnerTuple spgFormInnerTuple(SpGistState *state, - bool hasPrefix, Datum prefix, - int nNodes, SpGistNodeTuple *nodes); + bool hasPrefix, Datum prefix, + int nNodes, SpGistNodeTuple *nodes); extern SpGistDeadTuple spgFormDeadTuple(SpGistState *state, int tupstate, - BlockNumber blkno, OffsetNumber offnum); + BlockNumber blkno, OffsetNumber offnum); extern Datum *spgExtractNodeLabels(SpGistState *state, - SpGistInnerTuple innerTuple); + SpGistInnerTuple innerTuple); extern OffsetNumber SpGistPageAddNewItem(SpGistState *state, Page page, - Item item, Size size, - OffsetNumber *startOffset, - bool errorOK); + Item item, Size size, + OffsetNumber *startOffset, + bool errorOK); +extern bool spgproperty(Oid index_oid, int attno, + IndexAMProperty prop, const char *propname, + bool *res, bool *isnull); /* spgdoinsert.c */ extern void spgUpdateNodeLink(SpGistInnerTuple tup, int nodeN, - BlockNumber blkno, OffsetNumber offset); + BlockNumber blkno, OffsetNumber offset); extern void spgPageIndexMultiDelete(SpGistState *state, Page page, - OffsetNumber *itemnos, int nitems, - int firststate, int reststate, - BlockNumber blkno, OffsetNumber offnum); + OffsetNumber *itemnos, int nitems, + int firststate, int reststate, + BlockNumber blkno, OffsetNumber offnum); extern bool spgdoinsert(Relation index, SpGistState *state, - ItemPointer heapPtr, Datum datum, bool isnull); + ItemPointer heapPtr, Datum datum, bool isnull); + +/* spgproc.c */ +extern double *spg_key_orderbys_distances(Datum key, bool isLeaf, + ScanKey orderbys, int norderbys); +extern BOX *box_copy(BOX *orig); #endif /* SPGIST_PRIVATE_H */ diff --git a/src/include/access/spgxlog.h b/src/include/access/spgxlog.h index b72ccb5cc48..073f740a13f 100644 --- a/src/include/access/spgxlog.h +++ b/src/include/access/spgxlog.h @@ -3,7 +3,7 @@ * spgxlog.h * xlog declarations for SP-GiST access method. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/spgxlog.h @@ -18,7 +18,7 @@ #include "storage/off.h" /* XLOG record types for SPGiST */ -#define XLOG_SPGIST_CREATE_INDEX 0x00 + /* #define XLOG_SPGIST_CREATE_INDEX 0x00 */ /* not used anymore */ #define XLOG_SPGIST_ADD_LEAF 0x10 #define XLOG_SPGIST_MOVE_LEAFS 0x20 #define XLOG_SPGIST_ADD_NODE 0x30 diff --git a/src/include/access/stratnum.h b/src/include/access/stratnum.h index 0db11a11179..65b52236416 100644 --- a/src/include/access/stratnum.h +++ b/src/include/access/stratnum.h @@ -4,7 +4,7 @@ * POSTGRES strategy number definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/stratnum.h @@ -34,6 +34,13 @@ typedef uint16 StrategyNumber; #define BTMaxStrategyNumber 5 +/* + * Strategy numbers for hash indexes. There's only one valid strategy for + * hashing: equality. + */ +#define HTEqualStrategyNumber 1 + +#define HTMaxStrategyNumber 1 /* * Strategy numbers common to (some) GiST, SP-GiST and BRIN opclasses. diff --git a/src/include/access/subtrans.h b/src/include/access/subtrans.h index ce700a60ded..ce31d7464fc 100644 --- a/src/include/access/subtrans.h +++ b/src/include/access/subtrans.h @@ -3,7 +3,7 @@ * * PostgreSQL subtransaction-log manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/subtrans.h diff --git a/src/include/access/sysattr.h b/src/include/access/sysattr.h index c6f244011ab..2130ab7e895 100644 --- a/src/include/access/sysattr.h +++ b/src/include/access/sysattr.h @@ -4,7 +4,7 @@ * POSTGRES system attribute definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/sysattr.h @@ -19,12 +19,11 @@ * Attribute numbers for the system-defined attributes */ #define SelfItemPointerAttributeNumber (-1) -#define ObjectIdAttributeNumber (-2) -#define MinTransactionIdAttributeNumber (-3) -#define MinCommandIdAttributeNumber (-4) -#define MaxTransactionIdAttributeNumber (-5) -#define MaxCommandIdAttributeNumber (-6) -#define TableOidAttributeNumber (-7) -#define FirstLowInvalidHeapAttributeNumber (-8) +#define MinTransactionIdAttributeNumber (-2) +#define MinCommandIdAttributeNumber (-3) +#define MaxTransactionIdAttributeNumber (-4) +#define MaxCommandIdAttributeNumber (-5) +#define TableOidAttributeNumber (-6) +#define FirstLowInvalidHeapAttributeNumber (-7) #endif /* SYSATTR_H */ diff --git a/src/include/access/table.h b/src/include/access/table.h new file mode 100644 index 00000000000..44b0af70f4e --- /dev/null +++ b/src/include/access/table.h @@ -0,0 +1,38 @@ +/*------------------------------------------------------------------------- + * + * table.h + * Generic routines for table related code. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/table.h + * + *------------------------------------------------------------------------- + */ +#ifndef TABLE_H +#define TABLE_H + +#include "nodes/primnodes.h" +#include "utils/relcache.h" +#include "storage/lockdefs.h" + + +extern Relation table_open(Oid relationId, LOCKMODE lockmode); +extern Relation table_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation table_openrv_extended(const RangeVar *relation, + LOCKMODE lockmode, bool missing_ok); +extern void table_close(Relation relation, LOCKMODE lockmode); + +/* + * heap_ used to be the prefix for these routines, and a lot of code will just + * continue to work without adaptions after the introduction of pluggable + * storage, therefore just map these names. + */ +#define heap_open(r, l) table_open(r, l) +#define heap_openrv(r, l) table_openrv(r, l) +#define heap_openrv_extended(r, l, m) table_openrv_extended(r, l, m) +#define heap_close(r, l) table_close(r, l) + +#endif /* TABLE_H */ diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h new file mode 100644 index 00000000000..7f81703b783 --- /dev/null +++ b/src/include/access/tableam.h @@ -0,0 +1,1753 @@ +/*------------------------------------------------------------------------- + * + * tableam.h + * POSTGRES table access method definitions. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/access/tableam.h + * + * NOTES + * See tableam.sgml for higher level documentation. + * + *------------------------------------------------------------------------- + */ +#ifndef TABLEAM_H +#define TABLEAM_H + +#include "access/relscan.h" +#include "access/sdir.h" +#include "utils/guc.h" +#include "utils/rel.h" +#include "utils/snapshot.h" + + +#define DEFAULT_TABLE_ACCESS_METHOD "heap" + +/* GUCs */ +extern char *default_table_access_method; +extern bool synchronize_seqscans; + + +struct BulkInsertStateData; +struct IndexInfo; +struct SampleScanState; +struct TBMIterateResult; +struct VacuumParams; +struct ValidateIndexState; + +/* + * Bitmask values for the flags argument to the scan_begin callback. + */ +typedef enum ScanOptions +{ + /* one of SO_TYPE_* may be specified */ + SO_TYPE_SEQSCAN = 1 << 0, + SO_TYPE_BITMAPSCAN = 1 << 1, + SO_TYPE_SAMPLESCAN = 1 << 2, + SO_TYPE_ANALYZE = 1 << 3, + + /* several of SO_ALLOW_* may be specified */ + /* allow or disallow use of access strategy */ + SO_ALLOW_STRAT = 1 << 4, + /* report location to syncscan logic? */ + SO_ALLOW_SYNC = 1 << 5, + /* verify visibility page-at-a-time? */ + SO_ALLOW_PAGEMODE = 1 << 6, + + /* unregister snapshot at scan end? */ + SO_TEMP_SNAPSHOT = 1 << 7 +} ScanOptions; + +/* + * Result codes for table_{update,delete,lock_tuple}, and for visibility + * routines inside table AMs. + */ +typedef enum TM_Result +{ + /* + * Signals that the action succeeded (i.e. update/delete performed, lock + * was acquired) + */ + TM_Ok, + + /* The affected tuple wasn't visible to the relevant snapshot */ + TM_Invisible, + + /* The affected tuple was already modified by the calling backend */ + TM_SelfModified, + + /* + * The affected tuple was updated by another transaction. This includes + * the case where tuple was moved to another partition. + */ + TM_Updated, + + /* The affected tuple was deleted by another transaction */ + TM_Deleted, + + /* + * The affected tuple is currently being modified by another session. This + * will only be returned if table_(update/delete/lock_tuple) are + * instructed not to wait. + */ + TM_BeingModified, + + /* lock couldn't be acquired, action skipped. Only used by lock_tuple */ + TM_WouldBlock +} TM_Result; + +/* + * When table_tuple_update, table_tuple_delete, or table_tuple_lock fail + * because the target tuple is already outdated, they fill in this struct to + * provide information to the caller about what happened. + * + * ctid is the target's ctid link: it is the same as the target's TID if the + * target was deleted, or the location of the replacement tuple if the target + * was updated. + * + * xmax is the outdating transaction's XID. If the caller wants to visit the + * replacement tuple, it must check that this matches before believing the + * replacement is really a match. + * + * cmax is the outdating command's CID, but only when the failure code is + * TM_SelfModified (i.e., something in the current transaction outdated the + * tuple); otherwise cmax is zero. (We make this restriction because + * HeapTupleHeaderGetCmax doesn't work for tuples outdated in other + * transactions.) + */ +typedef struct TM_FailureData +{ + ItemPointerData ctid; + TransactionId xmax; + CommandId cmax; + bool traversed; +} TM_FailureData; + +/* "options" flag bits for table_tuple_insert */ +#define TABLE_INSERT_SKIP_WAL 0x0001 +#define TABLE_INSERT_SKIP_FSM 0x0002 +#define TABLE_INSERT_FROZEN 0x0004 +#define TABLE_INSERT_NO_LOGICAL 0x0008 + +/* flag bits for table_tuple_lock */ +/* Follow tuples whose update is in progress if lock modes don't conflict */ +#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS (1 << 0) +/* Follow update chain and lock latest version of tuple */ +#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION (1 << 1) + + +/* Typedef for callback function for table_index_build_scan */ +typedef void (*IndexBuildCallback) (Relation index, + HeapTuple htup, + Datum *values, + bool *isnull, + bool tupleIsAlive, + void *state); + +/* + * API struct for a table AM. Note this must be allocated in a + * server-lifetime manner, typically as a static const struct, which then gets + * returned by FormData_pg_am.amhandler. + * + * In most cases it's not appropriate to call the callbacks directly, use the + * table_* wrapper functions instead. + * + * GetTableAmRoutine() asserts that required callbacks are filled in, remember + * to update when adding a callback. + */ +typedef struct TableAmRoutine +{ + /* this must be set to T_TableAmRoutine */ + NodeTag type; + + + /* ------------------------------------------------------------------------ + * Slot related callbacks. + * ------------------------------------------------------------------------ + */ + + /* + * Return slot implementation suitable for storing a tuple of this AM. + */ + const TupleTableSlotOps *(*slot_callbacks) (Relation rel); + + + /* ------------------------------------------------------------------------ + * Table scan callbacks. + * ------------------------------------------------------------------------ + */ + + /* + * Start a scan of `rel`. The callback has to return a TableScanDesc, + * which will typically be embedded in a larger, AM specific, struct. + * + * If nkeys != 0, the results need to be filtered by those scan keys. + * + * pscan, if not NULL, will have already been initialized with + * parallelscan_initialize(), and has to be for the same relation. Will + * only be set coming from table_beginscan_parallel(). + * + * `flags` is a bitmask indicating the type of scan (ScanOptions's + * SO_TYPE_*, currently only one may be specified), options controlling + * the scan's behaviour (ScanOptions's SO_ALLOW_*, several may be + * specified, an AM may ignore unsupported ones) and whether the snapshot + * needs to be deallocated at scan_end (ScanOptions's SO_TEMP_SNAPSHOT). + */ + TableScanDesc (*scan_begin) (Relation rel, + Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + ParallelTableScanDesc pscan, + uint32 flags); + + /* + * Release resources and deallocate scan. If TableScanDesc.temp_snap, + * TableScanDesc.rs_snapshot needs to be unregistered. + */ + void (*scan_end) (TableScanDesc scan); + + /* + * Restart relation scan. If set_params is set to true, allow_{strat, + * sync, pagemode} (see scan_begin) changes should be taken into account. + */ + void (*scan_rescan) (TableScanDesc scan, struct ScanKeyData *key, + bool set_params, bool allow_strat, + bool allow_sync, bool allow_pagemode); + + /* + * Return next tuple from `scan`, store in slot. + */ + bool (*scan_getnextslot) (TableScanDesc scan, + ScanDirection direction, + TupleTableSlot *slot); + + + /* ------------------------------------------------------------------------ + * Parallel table scan related functions. + * ------------------------------------------------------------------------ + */ + + /* + * Estimate the size of shared memory needed for a parallel scan of this + * relation. The snapshot does not need to be accounted for. + */ + Size (*parallelscan_estimate) (Relation rel); + + /* + * Initialize ParallelTableScanDesc for a parallel scan of this relation. + * `pscan` will be sized according to parallelscan_estimate() for the same + * relation. + */ + Size (*parallelscan_initialize) (Relation rel, + ParallelTableScanDesc pscan); + + /* + * Reinitialize `pscan` for a new scan. `rel` will be the same relation as + * when `pscan` was initialized by parallelscan_initialize. + */ + void (*parallelscan_reinitialize) (Relation rel, + ParallelTableScanDesc pscan); + + + /* ------------------------------------------------------------------------ + * Index Scan Callbacks + * ------------------------------------------------------------------------ + */ + + /* + * Prepare to fetch tuples from the relation, as needed when fetching + * tuples for an index scan. The callback has to return an + * IndexFetchTableData, which the AM will typically embed in a larger + * structure with additional information. + * + * Tuples for an index scan can then be fetched via index_fetch_tuple. + */ + struct IndexFetchTableData *(*index_fetch_begin) (Relation rel); + + /* + * Reset index fetch. Typically this will release cross index fetch + * resources held in IndexFetchTableData. + */ + void (*index_fetch_reset) (struct IndexFetchTableData *data); + + /* + * Release resources and deallocate index fetch. + */ + void (*index_fetch_end) (struct IndexFetchTableData *data); + + /* + * Fetch tuple at `tid` into `slot`, after doing a visibility test + * according to `snapshot`. If a tuple was found and passed the visibility + * test, return true, false otherwise. + * + * Note that AMs that do not necessarily update indexes when indexed + * columns do not change, need to return the current/correct version of + * the tuple that is visible to the snapshot, even if the tid points to an + * older version of the tuple. + * + * *call_again is false on the first call to index_fetch_tuple for a tid. + * If there potentially is another tuple matching the tid, *call_again + * needs be set to true by index_fetch_tuple, signalling to the caller + * that index_fetch_tuple should be called again for the same tid. + * + * *all_dead, if all_dead is not NULL, should be set to true by + * index_fetch_tuple iff it is guaranteed that no backend needs to see + * that tuple. Index AMs can use that to avoid returning that tid in + * future searches. + */ + bool (*index_fetch_tuple) (struct IndexFetchTableData *scan, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + bool *call_again, bool *all_dead); + + + /* ------------------------------------------------------------------------ + * Callbacks for non-modifying operations on individual tuples + * ------------------------------------------------------------------------ + */ + + /* + * Fetch tuple at `tid` into `slot`, after doing a visibility test + * according to `snapshot`. If a tuple was found and passed the visibility + * test, returns true, false otherwise. + */ + bool (*tuple_fetch_row_version) (Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot); + + /* + * Is tid valid for a scan of this relation. + */ + bool (*tuple_tid_valid) (TableScanDesc scan, + ItemPointer tid); + + /* + * Return the latest version of the tuple at `tid`, by updating `tid` to + * point at the newest version. + */ + void (*tuple_get_latest_tid) (TableScanDesc scan, + ItemPointer tid); + + /* + * Does the tuple in `slot` satisfy `snapshot`? The slot needs to be of + * the appropriate type for the AM. + */ + bool (*tuple_satisfies_snapshot) (Relation rel, + TupleTableSlot *slot, + Snapshot snapshot); + + /* see table_compute_xid_horizon_for_tuples() */ + TransactionId (*compute_xid_horizon_for_tuples) (Relation rel, + ItemPointerData *items, + int nitems); + + + /* ------------------------------------------------------------------------ + * Manipulations of physical tuples. + * ------------------------------------------------------------------------ + */ + + /* see table_tuple_insert() for reference about parameters */ + void (*tuple_insert) (Relation rel, TupleTableSlot *slot, + CommandId cid, int options, + struct BulkInsertStateData *bistate); + + /* see table_tuple_insert_speculative() for reference about parameters */ + void (*tuple_insert_speculative) (Relation rel, + TupleTableSlot *slot, + CommandId cid, + int options, + struct BulkInsertStateData *bistate, + uint32 specToken); + + /* see table_tuple_complete_speculative() for reference about parameters */ + void (*tuple_complete_speculative) (Relation rel, + TupleTableSlot *slot, + uint32 specToken, + bool succeeded); + + /* see table_multi_insert() for reference about parameters */ + void (*multi_insert) (Relation rel, TupleTableSlot **slots, int nslots, + CommandId cid, int options, struct BulkInsertStateData *bistate); + + /* see table_tuple_delete() for reference about parameters */ + TM_Result (*tuple_delete) (Relation rel, + ItemPointer tid, + CommandId cid, + Snapshot snapshot, + Snapshot crosscheck, + bool wait, + TM_FailureData *tmfd, + bool changingPart); + + /* see table_tuple_update() for reference about parameters */ + TM_Result (*tuple_update) (Relation rel, + ItemPointer otid, + TupleTableSlot *slot, + CommandId cid, + Snapshot snapshot, + Snapshot crosscheck, + bool wait, + TM_FailureData *tmfd, + LockTupleMode *lockmode, + bool *update_indexes); + + /* see table_tuple_lock() for reference about parameters */ + TM_Result (*tuple_lock) (Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + CommandId cid, + LockTupleMode mode, + LockWaitPolicy wait_policy, + uint8 flags, + TM_FailureData *tmfd); + + /* + * Perform operations necessary to complete insertions made via + * tuple_insert and multi_insert with a BulkInsertState specified. This + * may for example be used to flush the relation, when the + * TABLE_INSERT_SKIP_WAL option was used. + * + * Typically callers of tuple_insert and multi_insert will just pass all + * the flags that apply to them, and each AM has to decide which of them + * make sense for it, and then only take actions in finish_bulk_insert for + * those flags, and ignore others. + * + * Optional callback. + */ + void (*finish_bulk_insert) (Relation rel, int options); + + + /* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + + /* + * This callback needs to create a new relation filenode for `rel`, with + * appropriate durability behaviour for `persistence`. + * + * Note that only the subset of the relcache filled by + * RelationBuildLocalRelation() can be relied upon and that the relation's + * catalog entries will either not yet exist (new relation), or will still + * reference the old relfilenode. + * + * As output *freezeXid, *minmulti must be set to the values appropriate + * for pg_class.{relfrozenxid, relminmxid}. For AMs that don't need those + * fields to be filled they can be set to InvalidTransactionId and + * InvalidMultiXactId, respectively. + * + * See also table_relation_set_new_filenode(). + */ + void (*relation_set_new_filenode) (Relation rel, + const RelFileNode *newrnode, + char persistence, + TransactionId *freezeXid, + MultiXactId *minmulti); + + /* + * This callback needs to remove all contents from `rel`'s current + * relfilenode. No provisions for transactional behaviour need to be made. + * Often this can be implemented by truncating the underlying storage to + * its minimal size. + * + * See also table_relation_nontransactional_truncate(). + */ + void (*relation_nontransactional_truncate) (Relation rel); + + /* + * See table_relation_copy_data(). + * + * This can typically be implemented by directly copying the underlying + * storage, unless it contains references to the tablespace internally. + */ + void (*relation_copy_data) (Relation rel, + const RelFileNode *newrnode); + + /* See table_relation_copy_for_cluster() */ + void (*relation_copy_for_cluster) (Relation NewTable, + Relation OldTable, + Relation OldIndex, + bool use_sort, + TransactionId OldestXmin, + TransactionId *xid_cutoff, + MultiXactId *multi_cutoff, + double *num_tuples, + double *tups_vacuumed, + double *tups_recently_dead); + + /* + * React to VACUUM command on the relation. The VACUUM can be + * triggered by a user or by autovacuum. The specific actions + * performed by the AM will depend heavily on the individual AM. + * + * On entry a transaction is already established, and the relation is + * locked with a ShareUpdateExclusive lock. + * + * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through + * this routine, even if (for ANALYZE) it is part of the same VACUUM + * command. + * + * There probably, in the future, needs to be a separate callback to + * integrate with autovacuum's scheduling. + */ + void (*relation_vacuum) (Relation onerel, + struct VacuumParams *params, + BufferAccessStrategy bstrategy); + + /* + * Prepare to analyze block `blockno` of `scan`. The scan has been started + * with table_beginscan_analyze(). See also + * table_scan_analyze_next_block(). + * + * The callback may acquire resources like locks that are held until + * table_scan_analyze_next_tuple() returns false. It e.g. can make sense + * to hold a lock until all tuples on a block have been analyzed by + * scan_analyze_next_tuple. + * + * The callback can return false if the block is not suitable for + * sampling, e.g. because it's a metapage that could never contain tuples. + * + * XXX: This obviously is primarily suited for block-based AMs. It's not + * clear what a good interface for non block based AMs would be, so there + * isn't one yet. + */ + bool (*scan_analyze_next_block) (TableScanDesc scan, + BlockNumber blockno, + BufferAccessStrategy bstrategy); + + /* + * See table_scan_analyze_next_tuple(). + * + * Not every AM might have a meaningful concept of dead rows, in which + * case it's OK to not increment *deadrows - but note that that may + * influence autovacuum scheduling (see comment for relation_vacuum + * callback). + */ + bool (*scan_analyze_next_tuple) (TableScanDesc scan, + TransactionId OldestXmin, + double *liverows, + double *deadrows, + TupleTableSlot *slot); + + /* see table_index_build_range_scan for reference about parameters */ + double (*index_build_range_scan) (Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool anyvisible, + bool progress, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan); + + /* see table_index_validate_scan for reference about parameters */ + void (*index_validate_scan) (Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state); + + + /* ------------------------------------------------------------------------ + * Miscellaneous functions. + * ------------------------------------------------------------------------ + */ + + /* + * See table_relation_size(). + * + * Note that currently a few callers use the MAIN_FORKNUM size to figure + * out the range of potentially interesting blocks (brin, analyze). It's + * probable that we'll need to revise the interface for those at some + * point. + */ + uint64 (*relation_size) (Relation rel, ForkNumber forkNumber); + + + /* + * This callback should return true if the relation requires a TOAST table + * and false if it does not. It may wish to examine the relation's tuple + * descriptor before making a decision, but if it uses some other method + * of storing large values (or if it does not support them) it can simply + * return false. + */ + bool (*relation_needs_toast_table) (Relation rel); + + + /* ------------------------------------------------------------------------ + * Planner related functions. + * ------------------------------------------------------------------------ + */ + + /* + * See table_relation_estimate_size(). + * + * While block oriented, it shouldn't be too hard for an AM that doesn't + * internally use blocks to convert into a usable representation. + * + * This differs from the relation_size callback by returning size + * estimates (both relation size and tuple count) for planning purposes, + * rather than returning a currently correct estimate. + */ + void (*relation_estimate_size) (Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac); + + + /* ------------------------------------------------------------------------ + * Executor related functions. + * ------------------------------------------------------------------------ + */ + + /* + * Prepare to fetch / check / return tuples from `tbmres->blockno` as part + * of a bitmap table scan. `scan` was started via table_beginscan_bm(). + * Return false if there are no tuples to be found on the page, true + * otherwise. + * + * This will typically read and pin the target block, and do the necessary + * work to allow scan_bitmap_next_tuple() to return tuples (e.g. it might + * make sense to perform tuple visibility checks at this time). For some + * AMs it will make more sense to do all the work referencing `tbmres` + * contents here, for others it might be better to defer more work to + * scan_bitmap_next_tuple. + * + * If `tbmres->blockno` is -1, this is a lossy scan and all visible tuples + * on the page have to be returned, otherwise the tuples at offsets in + * `tbmres->offsets` need to be returned. + * + * XXX: Currently this may only be implemented if the AM uses md.c as its + * storage manager, and uses ItemPointer->ip_blkid in a manner that maps + * blockids directly to the underlying storage. nodeBitmapHeapscan.c + * performs prefetching directly using that interface. This probably + * needs to be rectified at a later point. + * + * XXX: Currently this may only be implemented if the AM uses the + * visibilitymap, as nodeBitmapHeapscan.c unconditionally accesses it to + * perform prefetching. This probably needs to be rectified at a later + * point. + * + * Optional callback, but either both scan_bitmap_next_block and + * scan_bitmap_next_tuple need to exist, or neither. + */ + bool (*scan_bitmap_next_block) (TableScanDesc scan, + struct TBMIterateResult *tbmres); + + /* + * Fetch the next tuple of a bitmap table scan into `slot` and return true + * if a visible tuple was found, false otherwise. + * + * For some AMs it will make more sense to do all the work referencing + * `tbmres` contents in scan_bitmap_next_block, for others it might be + * better to defer more work to this callback. + * + * Optional callback, but either both scan_bitmap_next_block and + * scan_bitmap_next_tuple need to exist, or neither. + */ + bool (*scan_bitmap_next_tuple) (TableScanDesc scan, + struct TBMIterateResult *tbmres, + TupleTableSlot *slot); + + /* + * Prepare to fetch tuples from the next block in a sample scan. Return + * false if the sample scan is finished, true otherwise. `scan` was + * started via table_beginscan_sampling(). + * + * Typically this will first determine the target block by calling the + * TsmRoutine's NextSampleBlock() callback if not NULL, or alternatively + * perform a sequential scan over all blocks. The determined block is + * then typically read and pinned. + * + * As the TsmRoutine interface is block based, a block needs to be passed + * to NextSampleBlock(). If that's not appropriate for an AM, it + * internally needs to perform mapping between the internal and a block + * based representation. + * + * Note that it's not acceptable to hold deadlock prone resources such as + * lwlocks until scan_sample_next_tuple() has exhausted the tuples on the + * block - the tuple is likely to be returned to an upper query node, and + * the next call could be off a long while. Holding buffer pins and such + * is obviously OK. + * + * Currently it is required to implement this interface, as there's no + * alternative way (contrary e.g. to bitmap scans) to implement sample + * scans. If infeasible to implement, the AM may raise an error. + */ + bool (*scan_sample_next_block) (TableScanDesc scan, + struct SampleScanState *scanstate); + + /* + * This callback, only called after scan_sample_next_block has returned + * true, should determine the next tuple to be returned from the selected + * block using the TsmRoutine's NextSampleTuple() callback. + * + * The callback needs to perform visibility checks, and only return + * visible tuples. That obviously can mean calling NextSampleTuple() + * multiple times. + * + * The TsmRoutine interface assumes that there's a maximum offset on a + * given page, so if that doesn't apply to an AM, it needs to emulate that + * assumption somehow. + */ + bool (*scan_sample_next_tuple) (TableScanDesc scan, + struct SampleScanState *scanstate, + TupleTableSlot *slot); + +} TableAmRoutine; + + +/* ---------------------------------------------------------------------------- + * Slot functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Returns slot callbacks suitable for holding tuples of the appropriate type + * for the relation. Works for tables, views, foreign tables and partitioned + * tables. + */ +extern const TupleTableSlotOps *table_slot_callbacks(Relation rel); + +/* + * Returns slot using the callbacks returned by table_slot_callbacks(), and + * registers it on *reglist. + */ +extern TupleTableSlot *table_slot_create(Relation rel, List **reglist); + + +/* ---------------------------------------------------------------------------- + * Table scan functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Start a scan of `rel`. Returned tuples pass a visibility test of + * `snapshot`, and if nkeys != 0, the results are filtered by those scan keys. + */ +static inline TableScanDesc +table_beginscan(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_TYPE_SEQSCAN | + SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * Like table_beginscan(), but for scanning catalog. It'll automatically use a + * snapshot appropriate for scanning catalog relations. + */ +extern TableScanDesc table_beginscan_catalog(Relation rel, int nkeys, + struct ScanKeyData *key); + +/* + * Like table_beginscan(), but table_beginscan_strat() offers an extended API + * that lets the caller control whether a nondefault buffer access strategy + * can be used, and whether syncscan can be chosen (possibly resulting in the + * scan not starting from block zero). Both of these default to true with + * plain table_beginscan. + */ +static inline TableScanDesc +table_beginscan_strat(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + bool allow_strat, bool allow_sync) +{ + uint32 flags = SO_TYPE_SEQSCAN | SO_ALLOW_PAGEMODE; + + if (allow_strat) + flags |= SO_ALLOW_STRAT; + if (allow_sync) + flags |= SO_ALLOW_SYNC; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_bm is an alternative entry point for setting up a + * TableScanDesc for a bitmap heap scan. Although that scan technology is + * really quite unlike a standard seqscan, there is just enough commonality to + * make it worth using the same data structure. + */ +static inline TableScanDesc +table_beginscan_bm(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key) +{ + uint32 flags = SO_TYPE_BITMAPSCAN | SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_sampling is an alternative entry point for setting up a + * TableScanDesc for a TABLESAMPLE scan. As with bitmap scans, it's worth + * using the same data structure although the behavior is rather different. + * In addition to the options offered by table_beginscan_strat, this call + * also allows control of whether page-mode visibility checking is used. + */ +static inline TableScanDesc +table_beginscan_sampling(Relation rel, Snapshot snapshot, + int nkeys, struct ScanKeyData *key, + bool allow_strat, bool allow_sync, + bool allow_pagemode) +{ + uint32 flags = SO_TYPE_SAMPLESCAN; + + if (allow_strat) + flags |= SO_ALLOW_STRAT; + if (allow_sync) + flags |= SO_ALLOW_SYNC; + if (allow_pagemode) + flags |= SO_ALLOW_PAGEMODE; + + return rel->rd_tableam->scan_begin(rel, snapshot, nkeys, key, NULL, flags); +} + +/* + * table_beginscan_analyze is an alternative entry point for setting up a + * TableScanDesc for an ANALYZE scan. As with bitmap scans, it's worth using + * the same data structure although the behavior is rather different. + */ +static inline TableScanDesc +table_beginscan_analyze(Relation rel) +{ + uint32 flags = SO_TYPE_ANALYZE; + + return rel->rd_tableam->scan_begin(rel, NULL, 0, NULL, NULL, flags); +} + +/* + * End relation scan. + */ +static inline void +table_endscan(TableScanDesc scan) +{ + scan->rs_rd->rd_tableam->scan_end(scan); +} + +/* + * Restart a relation scan. + */ +static inline void +table_rescan(TableScanDesc scan, + struct ScanKeyData *key) +{ + scan->rs_rd->rd_tableam->scan_rescan(scan, key, false, false, false, false); +} + +/* + * Restart a relation scan after changing params. + * + * This call allows changing the buffer strategy, syncscan, and pagemode + * options before starting a fresh scan. Note that although the actual use of + * syncscan might change (effectively, enabling or disabling reporting), the + * previously selected startblock will be kept. + */ +static inline void +table_rescan_set_params(TableScanDesc scan, struct ScanKeyData *key, + bool allow_strat, bool allow_sync, bool allow_pagemode) +{ + scan->rs_rd->rd_tableam->scan_rescan(scan, key, true, + allow_strat, allow_sync, + allow_pagemode); +} + +/* + * Update snapshot used by the scan. + */ +extern void table_scan_update_snapshot(TableScanDesc scan, Snapshot snapshot); + +/* + * Return next tuple from `scan`, store in slot. + */ +static inline bool +table_scan_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot *slot) +{ + slot->tts_tableOid = RelationGetRelid(sscan->rs_rd); + return sscan->rs_rd->rd_tableam->scan_getnextslot(sscan, direction, slot); +} + + +/* ---------------------------------------------------------------------------- + * Parallel table scan related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Estimate the size of shared memory needed for a parallel scan of this + * relation. + */ +extern Size table_parallelscan_estimate(Relation rel, Snapshot snapshot); + +/* + * Initialize ParallelTableScanDesc for a parallel scan of this + * relation. `pscan` needs to be sized according to parallelscan_estimate() + * for the same relation. Call this just once in the leader process; then, + * individual workers attach via table_beginscan_parallel. + */ +extern void table_parallelscan_initialize(Relation rel, + ParallelTableScanDesc pscan, + Snapshot snapshot); + +/* + * Begin a parallel scan. `pscan` needs to have been initialized with + * table_parallelscan_initialize(), for the same relation. The initialization + * does not need to have happened in this backend. + * + * Caller must hold a suitable lock on the relation. + */ +extern TableScanDesc table_beginscan_parallel(Relation rel, + ParallelTableScanDesc pscan); + +/* + * Restart a parallel scan. Call this in the leader process. Caller is + * responsible for making sure that all workers have finished the scan + * beforehand. + */ +static inline void +table_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan) +{ + rel->rd_tableam->parallelscan_reinitialize(rel, pscan); +} + + +/* ---------------------------------------------------------------------------- + * Index scan related functions. + * ---------------------------------------------------------------------------- + */ + +/* + * Prepare to fetch tuples from the relation, as needed when fetching tuples + * for an index scan. + * + * Tuples for an index scan can then be fetched via table_index_fetch_tuple(). + */ +static inline IndexFetchTableData * +table_index_fetch_begin(Relation rel) +{ + return rel->rd_tableam->index_fetch_begin(rel); +} + +/* + * Reset index fetch. Typically this will release cross index fetch resources + * held in IndexFetchTableData. + */ +static inline void +table_index_fetch_reset(struct IndexFetchTableData *scan) +{ + scan->rel->rd_tableam->index_fetch_reset(scan); +} + +/* + * Release resources and deallocate index fetch. + */ +static inline void +table_index_fetch_end(struct IndexFetchTableData *scan) +{ + scan->rel->rd_tableam->index_fetch_end(scan); +} + +/* + * Fetches, as part of an index scan, tuple at `tid` into `slot`, after doing + * a visibility test according to `snapshot`. If a tuple was found and passed + * the visibility test, returns true, false otherwise. + * + * *call_again needs to be false on the first call to table_index_fetch_tuple() for + * a tid. If there potentially is another tuple matching the tid, *call_again + * will be set to true, signalling that table_index_fetch_tuple() should be called + * again for the same tid. + * + * *all_dead, if all_dead is not NULL, will be set to true by + * table_index_fetch_tuple() iff it is guaranteed that no backend needs to see + * that tuple. Index AMs can use that to avoid returning that tid in future + * searches. + * + * The difference between this function and table_fetch_row_version is that + * this function returns the currently visible version of a row if the AM + * supports storing multiple row versions reachable via a single index entry + * (like heap's HOT). Whereas table_fetch_row_version only evaluates the + * tuple exactly at `tid`. Outside of index entry ->table tuple lookups, + * table_tuple_fetch_row_version is what's usually needed. + */ +static inline bool +table_index_fetch_tuple(struct IndexFetchTableData *scan, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot, + bool *call_again, bool *all_dead) +{ + + return scan->rel->rd_tableam->index_fetch_tuple(scan, tid, snapshot, + slot, call_again, + all_dead); +} + +/* + * This is a convenience wrapper around table_index_fetch_tuple() which + * returns whether there are table tuple items corresponding to an index + * entry. This likely is only useful to verify if there's a conflict in a + * unique index. + */ +extern bool table_index_fetch_tuple_check(Relation rel, + ItemPointer tid, + Snapshot snapshot, + bool *all_dead); + + +/* ------------------------------------------------------------------------ + * Functions for non-modifying operations on individual tuples + * ------------------------------------------------------------------------ + */ + + +/* + * Fetch tuple at `tid` into `slot`, after doing a visibility test according to + * `snapshot`. If a tuple was found and passed the visibility test, returns + * true, false otherwise. + * + * See table_index_fetch_tuple's comment about what the difference between + * these functions is. It is correct to use this function outside of index + * entry->table tuple lookups. + */ +static inline bool +table_tuple_fetch_row_version(Relation rel, + ItemPointer tid, + Snapshot snapshot, + TupleTableSlot *slot) +{ + return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot); +} + +/* + * Verify that `tid` is a potentially valid tuple identifier. That doesn't + * mean that the pointed to row needs to exist or be visible, but that + * attempting to fetch the row (e.g. with table_get_latest_tid() or + * table_fetch_row_version()) should not error out if called with that tid. + * + * `scan` needs to have been started via table_beginscan(). + */ +static inline bool +table_tuple_tid_valid(TableScanDesc scan, ItemPointer tid) +{ + return scan->rs_rd->rd_tableam->tuple_tid_valid(scan, tid); +} + +/* + * Return the latest version of the tuple at `tid`, by updating `tid` to + * point at the newest version. + */ +extern void table_tuple_get_latest_tid(TableScanDesc scan, ItemPointer tid); + +/* + * Return true iff tuple in slot satisfies the snapshot. + * + * This assumes the slot's tuple is valid, and of the appropriate type for the + * AM. + * + * Some AMs might modify the data underlying the tuple as a side-effect. If so + * they ought to mark the relevant buffer dirty. + */ +static inline bool +table_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, + Snapshot snapshot) +{ + return rel->rd_tableam->tuple_satisfies_snapshot(rel, slot, snapshot); +} + +/* + * Compute the newest xid among the tuples pointed to by items. This is used + * to compute what snapshots to conflict with when replaying WAL records for + * page-level index vacuums. + */ +static inline TransactionId +table_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *items, + int nitems) +{ + return rel->rd_tableam->compute_xid_horizon_for_tuples(rel, items, nitems); +} + + +/* ---------------------------------------------------------------------------- + * Functions for manipulations of physical tuples. + * ---------------------------------------------------------------------------- + */ + +/* + * Insert a tuple from a slot into table AM routine. + * + * The options bitmask allows the caller to specify options that may change the + * behaviour of the AM. The AM will ignore options that it does not support. + * + * If the TABLE_INSERT_SKIP_WAL option is specified, the new tuple doesn't + * need to be logged to WAL, even for a non-temp relation. It is the AMs + * choice whether this optimization is supported. + * + * If the TABLE_INSERT_SKIP_FSM option is specified, AMs are free to not reuse + * free space in the relation. This can save some cycles when we know the + * relation is new and doesn't contain useful amounts of free space. + * TABLE_INSERT_SKIP_FSM is commonly passed directly to + * RelationGetBufferForTuple. See that method for more information. + * + * TABLE_INSERT_FROZEN should only be specified for inserts into + * relfilenodes created during the current subtransaction and when + * there are no prior snapshots or pre-existing portals open. + * This causes rows to be frozen, which is an MVCC violation and + * requires explicit options chosen by user. + * + * TABLE_INSERT_NO_LOGICAL force-disables the emitting of logical decoding + * information for the tuple. This should solely be used during table rewrites + * where RelationIsLogicallyLogged(relation) is not yet accurate for the new + * relation. + * + * Note that most of these options will be applied when inserting into the + * heap's TOAST table, too, if the tuple requires any out-of-line data. + * + * The BulkInsertState object (if any; bistate can be NULL for default + * behavior) is also just passed through to RelationGetBufferForTuple. If + * `bistate` is provided, table_finish_bulk_insert() needs to be called. + * + * On return the slot's tts_tid and tts_tableOid are updated to reflect the + * insertion. But note that any toasting of fields within the slot is NOT + * reflected in the slots contents. + */ +static inline void +table_tuple_insert(Relation rel, TupleTableSlot *slot, CommandId cid, + int options, struct BulkInsertStateData *bistate) +{ + rel->rd_tableam->tuple_insert(rel, slot, cid, options, + bistate); +} + +/* + * Perform a "speculative insertion". These can be backed out afterwards + * without aborting the whole transaction. Other sessions can wait for the + * speculative insertion to be confirmed, turning it into a regular tuple, or + * aborted, as if it never existed. Speculatively inserted tuples behave as + * "value locks" of short duration, used to implement INSERT .. ON CONFLICT. + * + * A transaction having performed a speculative insertion has to either abort, + * or finish the speculative insertion with + * table_tuple_complete_speculative(succeeded = ...). + */ +static inline void +table_tuple_insert_speculative(Relation rel, TupleTableSlot *slot, + CommandId cid, int options, + struct BulkInsertStateData *bistate, + uint32 specToken) +{ + rel->rd_tableam->tuple_insert_speculative(rel, slot, cid, options, + bistate, specToken); +} + +/* + * Complete "speculative insertion" started in the same transaction. If + * succeeded is true, the tuple is fully inserted, if false, it's removed. + */ +static inline void +table_tuple_complete_speculative(Relation rel, TupleTableSlot *slot, + uint32 specToken, bool succeeded) +{ + rel->rd_tableam->tuple_complete_speculative(rel, slot, specToken, + succeeded); +} + +/* + * Insert multiple tuples into a table. + * + * This is like table_insert(), but inserts multiple tuples in one + * operation. That's often faster than calling table_insert() in a loop, + * because e.g. the AM can reduce WAL logging and page locking overhead. + * + * Except for taking `nslots` tuples as input, as an array of TupleTableSlots + * in `slots`, the parameters for table_multi_insert() are the same as for + * table_tuple_insert(). + * + * Note: this leaks memory into the current memory context. You can create a + * temporary context before calling this, if that's a problem. + */ +static inline void +table_multi_insert(Relation rel, TupleTableSlot **slots, int nslots, + CommandId cid, int options, struct BulkInsertStateData *bistate) +{ + rel->rd_tableam->multi_insert(rel, slots, nslots, + cid, options, bistate); +} + +/* + * Delete a tuple. + * + * NB: do not call this directly unless prepared to deal with + * concurrent-update conditions. Use simple_table_tuple_delete instead. + * + * Input parameters: + * relation - table to be modified (caller must hold suitable lock) + * tid - TID of tuple to be deleted + * cid - delete command ID (used for visibility test, and stored into + * cmax if successful) + * crosscheck - if not InvalidSnapshot, also check tuple against this + * wait - true if should wait for any conflicting update to commit/abort + * Output parameters: + * tmfd - filled in failure cases (see below) + * changingPart - true iff the tuple is being moved to another partition + * table due to an update of the partition key. Otherwise, false. + * + * Normal, successful return value is TM_Ok, which means we did actually + * delete it. Failure return codes are TM_SelfModified, TM_Updated, and + * TM_BeingModified (the last only possible if wait == false). + * + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax, and, if possible, and, if possible, t_cmax. See comments for + * struct TM_FailureData for additional info. + */ +static inline TM_Result +table_tuple_delete(Relation rel, ItemPointer tid, CommandId cid, + Snapshot snapshot, Snapshot crosscheck, bool wait, + TM_FailureData *tmfd, bool changingPart) +{ + return rel->rd_tableam->tuple_delete(rel, tid, cid, + snapshot, crosscheck, + wait, tmfd, changingPart); +} + +/* + * Update a tuple. + * + * NB: do not call this directly unless you are prepared to deal with + * concurrent-update conditions. Use simple_table_tuple_update instead. + * + * Input parameters: + * relation - table to be modified (caller must hold suitable lock) + * otid - TID of old tuple to be replaced + * slot - newly constructed tuple data to store + * cid - update command ID (used for visibility test, and stored into + * cmax/cmin if successful) + * crosscheck - if not InvalidSnapshot, also check old tuple against this + * wait - true if should wait for any conflicting update to commit/abort + * Output parameters: + * tmfd - filled in failure cases (see below) + * lockmode - filled with lock mode acquired on tuple + * update_indexes - in success cases this is set to true if new index entries + * are required for this tuple + * + * Normal, successful return value is TM_Ok, which means we did actually + * update it. Failure return codes are TM_SelfModified, TM_Updated, and + * TM_BeingModified (the last only possible if wait == false). + * + * On success, the slot's tts_tid and tts_tableOid are updated to match the new + * stored tuple; in particular, slot->tts_tid is set to the TID where the + * new tuple was inserted, and its HEAP_ONLY_TUPLE flag is set iff a HOT + * update was done. However, any TOAST changes in the new tuple's + * data are not reflected into *newtup. + * + * In the failure cases, the routine fills *tmfd with the tuple's t_ctid, + * t_xmax, and, if possible, t_cmax. See comments for struct TM_FailureData + * for additional info. + */ +static inline TM_Result +table_tuple_update(Relation rel, ItemPointer otid, TupleTableSlot *slot, + CommandId cid, Snapshot snapshot, Snapshot crosscheck, + bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, + bool *update_indexes) +{ + return rel->rd_tableam->tuple_update(rel, otid, slot, + cid, snapshot, crosscheck, + wait, tmfd, + lockmode, update_indexes); +} + +/* + * Lock a tuple in the specified mode. + * + * Input parameters: + * relation: relation containing tuple (caller must hold suitable lock) + * tid: TID of tuple to lock + * snapshot: snapshot to use for visibility determinations + * cid: current command ID (used for visibility test, and stored into + * tuple's cmax if lock is successful) + * mode: lock mode desired + * wait_policy: what to do if tuple lock is not available + * flags: + * If TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS, follow the update chain to + * also lock descendant tuples if lock modes don't conflict. + * If TUPLE_LOCK_FLAG_FIND_LAST_VERSION, follow the update chain and lock + * latest version. + * + * Output parameters: + * *slot: contains the target tuple + * *tmfd: filled in failure cases (see below) + * + * Function result may be: + * TM_Ok: lock was successfully acquired + * TM_Invisible: lock failed because tuple was never visible to us + * TM_SelfModified: lock failed because tuple updated by self + * TM_Updated: lock failed because tuple updated by other xact + * TM_Deleted: lock failed because tuple deleted by other xact + * TM_WouldBlock: lock couldn't be acquired and wait_policy is skip + * + * In the failure cases other than TM_Invisible and TM_Deleted, the routine + * fills *tmfd with the tuple's t_ctid, t_xmax, and, if possible, t_cmax. See + * comments for struct TM_FailureData for additional info. + */ +static inline TM_Result +table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, + TupleTableSlot *slot, CommandId cid, LockTupleMode mode, + LockWaitPolicy wait_policy, uint8 flags, + TM_FailureData *tmfd) +{ + return rel->rd_tableam->tuple_lock(rel, tid, snapshot, slot, + cid, mode, wait_policy, + flags, tmfd); +} + +/* + * Perform operations necessary to complete insertions made via + * tuple_insert and multi_insert with a BulkInsertState specified. This + * e.g. may e.g. used to flush the relation when inserting with + * TABLE_INSERT_SKIP_WAL specified. + */ +static inline void +table_finish_bulk_insert(Relation rel, int options) +{ + /* optional callback */ + if (rel->rd_tableam && rel->rd_tableam->finish_bulk_insert) + rel->rd_tableam->finish_bulk_insert(rel, options); +} + + +/* ------------------------------------------------------------------------ + * DDL related functionality. + * ------------------------------------------------------------------------ + */ + +/* + * Create storage for `rel` in `newrnode`, with persistence set to + * `persistence`. + * + * This is used both during relation creation and various DDL operations to + * create a new relfilenode that can be filled from scratch. When creating + * new storage for an existing relfilenode, this should be called before the + * relcache entry has been updated. + * + * *freezeXid, *minmulti are set to the xid / multixact horizon for the table + * that pg_class.{relfrozenxid, relminmxid} have to be set to. + */ +static inline void +table_relation_set_new_filenode(Relation rel, + const RelFileNode *newrnode, + char persistence, + TransactionId *freezeXid, + MultiXactId *minmulti) +{ + rel->rd_tableam->relation_set_new_filenode(rel, newrnode, persistence, + freezeXid, minmulti); +} + +/* + * Remove all table contents from `rel`, in a non-transactional manner. + * Non-transactional meaning that there's no need to support rollbacks. This + * commonly only is used to perform truncations for relfilenodes created in the + * current transaction. + */ +static inline void +table_relation_nontransactional_truncate(Relation rel) +{ + rel->rd_tableam->relation_nontransactional_truncate(rel); +} + +/* + * Copy data from `rel` into the new relfilenode `newrnode`. The new + * relfilenode may not have storage associated before this function is + * called. This is only supposed to be used for low level operations like + * changing a relation's tablespace. + */ +static inline void +table_relation_copy_data(Relation rel, const RelFileNode *newrnode) +{ + rel->rd_tableam->relation_copy_data(rel, newrnode); +} + +/* + * Copy data from `OldTable` into `NewTable`, as part of a CLUSTER or VACUUM + * FULL. + * + * Additional Input parameters: + * - use_sort - if true, the table contents are sorted appropriate for + * `OldIndex`; if false and OldIndex is not InvalidOid, the data is copied + * in that index's order; if false and OldIndex is InvalidOid, no sorting is + * performed + * - OldIndex - see use_sort + * - OldestXmin - computed by vacuum_set_xid_limits(), even when + * not needed for the relation's AM + * - *xid_cutoff - ditto + * - *multi_cutoff - ditto + * + * Output parameters: + * - *xid_cutoff - rel's new relfrozenxid value, may be invalid + * - *multi_cutoff - rel's new relminmxid value, may be invalid + * - *tups_vacuumed - stats, for logging, if appropriate for AM + * - *tups_recently_dead - stats, for logging, if appropriate for AM + */ +static inline void +table_relation_copy_for_cluster(Relation OldTable, Relation NewTable, + Relation OldIndex, + bool use_sort, + TransactionId OldestXmin, + TransactionId *xid_cutoff, + MultiXactId *multi_cutoff, + double *num_tuples, + double *tups_vacuumed, + double *tups_recently_dead) +{ + OldTable->rd_tableam->relation_copy_for_cluster(OldTable, NewTable, OldIndex, + use_sort, OldestXmin, + xid_cutoff, multi_cutoff, + num_tuples, tups_vacuumed, + tups_recently_dead); +} + +/* + * Perform VACUUM on the relation. The VACUUM can be triggered by a user or by + * autovacuum. The specific actions performed by the AM will depend heavily on + * the individual AM. + * + * On entry a transaction needs to already been established, and the + * table is locked with a ShareUpdateExclusive lock. + * + * Note that neither VACUUM FULL (and CLUSTER), nor ANALYZE go through this + * routine, even if (for ANALYZE) it is part of the same VACUUM command. + */ +static inline void +table_relation_vacuum(Relation rel, struct VacuumParams *params, + BufferAccessStrategy bstrategy) +{ + rel->rd_tableam->relation_vacuum(rel, params, bstrategy); +} + +/* + * Prepare to analyze block `blockno` of `scan`. The scan needs to have been + * started with table_beginscan_analyze(). Note that this routine might + * acquire resources like locks that are held until + * table_scan_analyze_next_tuple() returns false. + * + * Returns false if block is unsuitable for sampling, true otherwise. + */ +static inline bool +table_scan_analyze_next_block(TableScanDesc scan, BlockNumber blockno, + BufferAccessStrategy bstrategy) +{ + return scan->rs_rd->rd_tableam->scan_analyze_next_block(scan, blockno, + bstrategy); +} + +/* + * Iterate over tuples in the block selected with + * table_scan_analyze_next_block() (which needs to have returned true, and + * this routine may not have returned false for the same block before). If a + * tuple that's suitable for sampling is found, true is returned and a tuple + * is stored in `slot`. + * + * *liverows and *deadrows are incremented according to the encountered + * tuples. + */ +static inline bool +table_scan_analyze_next_tuple(TableScanDesc scan, TransactionId OldestXmin, + double *liverows, double *deadrows, + TupleTableSlot *slot) +{ + return scan->rs_rd->rd_tableam->scan_analyze_next_tuple(scan, OldestXmin, + liverows, deadrows, + slot); +} + +/* + * table_index_build_scan - scan the table to find tuples to be indexed + * + * This is called back from an access-method-specific index build procedure + * after the AM has done whatever setup it needs. The parent table relation + * is scanned to find tuples that should be entered into the index. Each + * such tuple is passed to the AM's callback routine, which does the right + * things to add it to the new index. After we return, the AM's index + * build procedure does whatever cleanup it needs. + * + * The total count of live tuples is returned. This is for updating pg_class + * statistics. (It's annoying not to be able to do that here, but we want to + * merge that update with others; see index_update_stats.) Note that the + * index AM itself must keep track of the number of index tuples; we don't do + * so here because the AM might reject some of the tuples for its own reasons, + * such as being unable to store NULLs. + * + * If 'progress', the PROGRESS_SCAN_BLOCKS_TOTAL counter is updated when + * starting the scan, and PROGRESS_SCAN_BLOCKS_DONE is updated as we go along. + * + * A side effect is to set indexInfo->ii_BrokenHotChain to true if we detect + * any potentially broken HOT chains. Currently, we set this if there are any + * RECENTLY_DEAD or DELETE_IN_PROGRESS entries in a HOT chain, without trying + * very hard to detect whether they're really incompatible with the chain tip. + * This only really makes sense for heap AM, it might need to be generalized + * for other AMs later. + */ +static inline double +table_index_build_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool progress, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return table_rel->rd_tableam->index_build_range_scan(table_rel, + index_rel, + index_info, + allow_sync, + false, + progress, + 0, + InvalidBlockNumber, + callback, + callback_state, + scan); +} + +/* + * As table_index_build_scan(), except that instead of scanning the complete + * table, only the given number of blocks are scanned. Scan to end-of-rel can + * be signalled by passing InvalidBlockNumber as numblocks. Note that + * restricting the range to scan cannot be done when requesting syncscan. + * + * When "anyvisible" mode is requested, all tuples visible to any transaction + * are indexed and counted as live, including those inserted or deleted by + * transactions that are still in progress. + */ +static inline double +table_index_build_range_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + bool allow_sync, + bool anyvisible, + bool progress, + BlockNumber start_blockno, + BlockNumber numblocks, + IndexBuildCallback callback, + void *callback_state, + TableScanDesc scan) +{ + return table_rel->rd_tableam->index_build_range_scan(table_rel, + index_rel, + index_info, + allow_sync, + anyvisible, + progress, + start_blockno, + numblocks, + callback, + callback_state, + scan); +} + +/* + * table_index_validate_scan - second table scan for concurrent index build + * + * See validate_index() for an explanation. + */ +static inline void +table_index_validate_scan(Relation table_rel, + Relation index_rel, + struct IndexInfo *index_info, + Snapshot snapshot, + struct ValidateIndexState *state) +{ + table_rel->rd_tableam->index_validate_scan(table_rel, + index_rel, + index_info, + snapshot, + state); +} + + +/* ---------------------------------------------------------------------------- + * Miscellaneous functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Return the current size of `rel` in bytes. If `forkNumber` is + * InvalidForkNumber, return the relation's overall size, otherwise the size + * for the indicated fork. + * + * Note that the overall size might not be the equivalent of the sum of sizes + * for the individual forks for some AMs, e.g. because the AMs storage does + * not neatly map onto the builtin types of forks. + */ +static inline uint64 +table_relation_size(Relation rel, ForkNumber forkNumber) +{ + return rel->rd_tableam->relation_size(rel, forkNumber); +} + +/* + * table_relation_needs_toast_table - does this relation need a toast table? + */ +static inline bool +table_relation_needs_toast_table(Relation rel) +{ + return rel->rd_tableam->relation_needs_toast_table(rel); +} + + +/* ---------------------------------------------------------------------------- + * Planner related functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Estimate the current size of the relation, as an AM specific workhorse for + * estimate_rel_size(). Look there for an explanation of the parameters. + */ +static inline void +table_relation_estimate_size(Relation rel, int32 *attr_widths, + BlockNumber *pages, double *tuples, + double *allvisfrac) +{ + rel->rd_tableam->relation_estimate_size(rel, attr_widths, pages, tuples, + allvisfrac); +} + + +/* ---------------------------------------------------------------------------- + * Executor related functionality + * ---------------------------------------------------------------------------- + */ + +/* + * Prepare to fetch / check / return tuples from `tbmres->blockno` as part of + * a bitmap table scan. `scan` needs to have been started via + * table_beginscan_bm(). Returns false if there are no tuples to be found on + * the page, true otherwise. + * + * Note, this is an optionally implemented function, therefore should only be + * used after verifying the presence (at plan time or such). + */ +static inline bool +table_scan_bitmap_next_block(TableScanDesc scan, + struct TBMIterateResult *tbmres) +{ + return scan->rs_rd->rd_tableam->scan_bitmap_next_block(scan, + tbmres); +} + +/* + * Fetch the next tuple of a bitmap table scan into `slot` and return true if + * a visible tuple was found, false otherwise. + * table_scan_bitmap_next_block() needs to previously have selected a + * block (i.e. returned true), and no previous + * table_scan_bitmap_next_tuple() for the same block may have + * returned false. + */ +static inline bool +table_scan_bitmap_next_tuple(TableScanDesc scan, + struct TBMIterateResult *tbmres, + TupleTableSlot *slot) +{ + return scan->rs_rd->rd_tableam->scan_bitmap_next_tuple(scan, + tbmres, + slot); +} + +/* + * Prepare to fetch tuples from the next block in a sample scan. Returns false + * if the sample scan is finished, true otherwise. `scan` needs to have been + * started via table_beginscan_sampling(). + * + * This will call the TsmRoutine's NextSampleBlock() callback if necessary + * (i.e. NextSampleBlock is not NULL), or perform a sequential scan over the + * underlying relation. + */ +static inline bool +table_scan_sample_next_block(TableScanDesc scan, + struct SampleScanState *scanstate) +{ + return scan->rs_rd->rd_tableam->scan_sample_next_block(scan, scanstate); +} + +/* + * Fetch the next sample tuple into `slot` and return true if a visible tuple + * was found, false otherwise. table_scan_sample_next_block() needs to + * previously have selected a block (i.e. returned true), and no previous + * table_scan_sample_next_tuple() for the same block may have returned false. + * + * This will call the TsmRoutine's NextSampleTuple() callback. + */ +static inline bool +table_scan_sample_next_tuple(TableScanDesc scan, + struct SampleScanState *scanstate, + TupleTableSlot *slot) +{ + return scan->rs_rd->rd_tableam->scan_sample_next_tuple(scan, scanstate, + slot); +} + + +/* ---------------------------------------------------------------------------- + * Functions to make modifications a bit simpler. + * ---------------------------------------------------------------------------- + */ + +extern void simple_table_tuple_insert(Relation rel, TupleTableSlot *slot); +extern void simple_table_tuple_delete(Relation rel, ItemPointer tid, + Snapshot snapshot); +extern void simple_table_tuple_update(Relation rel, ItemPointer otid, + TupleTableSlot *slot, Snapshot snapshot, + bool *update_indexes); + + +/* ---------------------------------------------------------------------------- + * Helper functions to implement parallel scans for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +extern Size table_block_parallelscan_estimate(Relation rel); +extern Size table_block_parallelscan_initialize(Relation rel, + ParallelTableScanDesc pscan); +extern void table_block_parallelscan_reinitialize(Relation rel, + ParallelTableScanDesc pscan); +extern BlockNumber table_block_parallelscan_nextpage(Relation rel, + ParallelBlockTableScanDesc pbscan); +extern void table_block_parallelscan_startblock_init(Relation rel, + ParallelBlockTableScanDesc pbscan); + + +/* ---------------------------------------------------------------------------- + * Helper functions to implement relation sizing for block oriented AMs. + * ---------------------------------------------------------------------------- + */ + +extern uint64 table_block_relation_size(Relation rel, ForkNumber forkNumber); +extern void table_block_relation_estimate_size(Relation rel, + int32 *attr_widths, + BlockNumber *pages, + double *tuples, + double *allvisfrac, + Size overhead_bytes_per_tuple, + Size usable_bytes_per_page); + +/* ---------------------------------------------------------------------------- + * Functions in tableamapi.c + * ---------------------------------------------------------------------------- + */ + +extern const TableAmRoutine *GetTableAmRoutine(Oid amhandler); +extern const TableAmRoutine *GetHeapamTableAmRoutine(void); +extern bool check_default_table_access_method(char **newval, void **extra, + GucSource source); + +#endif /* TABLEAM_H */ diff --git a/src/include/access/timeline.h b/src/include/access/timeline.h index a9bf18cab6b..e83a73a3f1e 100644 --- a/src/include/access/timeline.h +++ b/src/include/access/timeline.h @@ -3,7 +3,7 @@ * * Functions for reading and writing timeline history files. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/timeline.h @@ -33,12 +33,12 @@ extern List *readTimeLineHistory(TimeLineID targetTLI); extern bool existsTimeLineHistory(TimeLineID probeTLI); extern TimeLineID findNewestTimeLine(TimeLineID startTLI); extern void writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI, - XLogRecPtr switchpoint, char *reason); + XLogRecPtr switchpoint, char *reason); extern void writeTimeLineHistoryFile(TimeLineID tli, char *content, int size); extern void restoreTimeLineHistoryFiles(TimeLineID begin, TimeLineID end); -extern bool tliInHistory(TimeLineID tli, List *expectedTLIs); +extern bool tliInHistory(TimeLineID tli, List *expectedTLEs); extern TimeLineID tliOfPointInHistory(XLogRecPtr ptr, List *history); extern XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, - TimeLineID *nextTLI); + TimeLineID *nextTLI); #endif /* TIMELINE_H */ diff --git a/src/include/access/toast_helper.h b/src/include/access/toast_helper.h new file mode 100644 index 00000000000..7cefacb0eaa --- /dev/null +++ b/src/include/access/toast_helper.h @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------- + * + * toast_helper.h + * Helper functions for table AMs implementing compressed or + * out-of-line storage of varlena attributes. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * src/include/access/toast_helper.h + * + *------------------------------------------------------------------------- + */ + +#ifndef TOAST_HELPER_H +#define TOAST_HELPER_H + +#include "utils/rel.h" + +/* + * Information about one column of a tuple being toasted. + * + * NOTE: toast_action[i] can have these values: + * ' ' default handling + * 'p' already processed --- don't touch it + * 'x' incompressible, but OK to move off + * + * NOTE: toast_attr[i].tai_size is only made valid for varlena attributes with + * toast_action[i] different from 'p'. + */ +typedef struct +{ + struct varlena *tai_oldexternal; + int32 tai_size; + uint8 tai_colflags; +} ToastAttrInfo; + +/* + * Information about one tuple being toasted. + */ +typedef struct +{ + /* + * Before calling toast_tuple_init, the caller must initialize the + * following fields. Each array must have a length equal to + * ttc_rel->rd_att->natts. The tts_oldvalues and tts_oldisnull fields + * should be NULL in the case of an insert. + */ + Relation ttc_rel; /* the relation that contains the tuple */ + Datum *ttc_values; /* values from the tuple columns */ + bool *ttc_isnull; /* null flags for the tuple columns */ + Datum *ttc_oldvalues; /* values from previous tuple */ + bool *ttc_oldisnull; /* null flags from previous tuple */ + + /* + * Before calling toast_tuple_init, the caller should set tts_attr to + * point to an array of ToastAttrInfo structures of a length equal to + * tts_rel->rd_att->natts. The contents of the array need not be + * initialized. ttc_flags also does not need to be initialized. + */ + uint8 ttc_flags; + ToastAttrInfo *ttc_attr; +} ToastTupleContext; + +/* + * Flags indicating the overall state of a TOAST operation. + * + * TOAST_NEEDS_DELETE_OLD indicates that one or more old TOAST datums need + * to be deleted. + * + * TOAST_NEEDS_FREE indicates that one or more TOAST values need to be freed. + * + * TOAST_HAS_NULLS indicates that nulls were found in the tuple being toasted. + * + * TOAST_NEEDS_CHANGE indicates that a new tuple needs to built; in other + * words, the toaster did something. + */ +#define TOAST_NEEDS_DELETE_OLD 0x0001 +#define TOAST_NEEDS_FREE 0x0002 +#define TOAST_HAS_NULLS 0x0004 +#define TOAST_NEEDS_CHANGE 0x0008 + +/* + * Flags indicating the status of a TOAST operation with respect to a + * particular column. + * + * TOASTCOL_NEEDS_DELETE_OLD indicates that the old TOAST datums for this + * column need to be deleted. + * + * TOASTCOL_NEEDS_FREE indicates that the value for this column needs to + * be freed. + * + * TOASTCOL_IGNORE indicates that the toaster should not further process + * this column. + * + * TOASTCOL_INCOMPRESSIBLE indicates that this column has been found to + * be incompressible, but could be moved out-of-line. + */ +#define TOASTCOL_NEEDS_DELETE_OLD TOAST_NEEDS_DELETE_OLD +#define TOASTCOL_NEEDS_FREE TOAST_NEEDS_FREE +#define TOASTCOL_IGNORE 0x0010 +#define TOASTCOL_INCOMPRESSIBLE 0x0020 + +extern void toast_tuple_init(ToastTupleContext *ttc); +extern int toast_tuple_find_biggest_attribute(ToastTupleContext *ttc, + bool for_compression, + bool check_main); +extern void toast_tuple_try_compression(ToastTupleContext *ttc, int attribute); +extern void toast_tuple_externalize(ToastTupleContext *ttc, int attribute, + int options); +extern void toast_tuple_cleanup(ToastTupleContext *ttc); + +extern void toast_delete_external(Relation rel, Datum *values, bool *isnull, + bool is_speculative); + +#endif diff --git a/src/include/access/toast_internals.h b/src/include/access/toast_internals.h new file mode 100644 index 00000000000..9bd1c97771a --- /dev/null +++ b/src/include/access/toast_internals.h @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * toast_internals.h + * Internal definitions for the TOAST system. + * + * Copyright (c) 2000-2019, PostgreSQL Global Development Group + * + * src/include/access/toast_internals.h + * + *------------------------------------------------------------------------- + */ +#ifndef TOAST_INTERNALS_H +#define TOAST_INTERNALS_H + +#include "storage/lockdefs.h" +#include "utils/relcache.h" +#include "utils/snapshot.h" + +/* + * The information at the start of the compressed toast data. + */ +typedef struct toast_compress_header +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int32 rawsize; +} toast_compress_header; + +/* + * Utilities for manipulation of header information for compressed + * toast entries. + */ +#define TOAST_COMPRESS_HDRSZ ((int32) sizeof(toast_compress_header)) +#define TOAST_COMPRESS_RAWSIZE(ptr) (((toast_compress_header *) (ptr))->rawsize) +#define TOAST_COMPRESS_SIZE(ptr) ((int32) VARSIZE_ANY(ptr) - TOAST_COMPRESS_HDRSZ) +#define TOAST_COMPRESS_RAWDATA(ptr) \ + (((char *) (ptr)) + TOAST_COMPRESS_HDRSZ) +#define TOAST_COMPRESS_SET_RAWSIZE(ptr, len) \ + (((toast_compress_header *) (ptr))->rawsize = (len)) + +extern Datum toast_compress_datum(Datum value); +extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock); + +extern void toast_delete_datum(Relation rel, Datum value, bool is_speculative); +extern Datum toast_save_datum(Relation rel, Datum value, + struct varlena *oldexternal, int options); + +extern int toast_open_indexes(Relation toastrel, + LOCKMODE lock, + Relation **toastidxs, + int *num_indexes); +extern void toast_close_indexes(Relation *toastidxs, int num_indexes, + LOCKMODE lock); +extern void init_toast_snapshot(Snapshot toast_snapshot); + +#endif /* TOAST_INTERNALS_H */ diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 83ec3f19797..33fd052156f 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -4,7 +4,7 @@ * postgres transaction access method support code * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/transam.h @@ -44,6 +44,33 @@ #define TransactionIdStore(xid, dest) (*(dest) = (xid)) #define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId) +#define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32)) +#define XidFromFullTransactionId(x) ((uint32) (x).value) +#define U64FromFullTransactionId(x) ((x).value) +#define FullTransactionIdPrecedes(a, b) ((a).value < (b).value) +#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x)) +#define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId) + +/* + * A 64 bit value that contains an epoch and a TransactionId. This is + * wrapped in a struct to prevent implicit conversion to/from TransactionId. + * Not all values represent valid normal XIDs. + */ +typedef struct FullTransactionId +{ + uint64 value; +} FullTransactionId; + +static inline FullTransactionId +FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid) +{ + FullTransactionId result; + + result.value = ((uint64) epoch) << 32 | xid; + + return result; +} + /* advance a transaction ID variable, handling wraparound correctly */ #define TransactionIdAdvance(dest) \ do { \ @@ -52,6 +79,15 @@ (dest) = FirstNormalTransactionId; \ } while(0) +/* advance a FullTransactionId variable, stepping over special XIDs */ +static inline void +FullTransactionIdAdvance(FullTransactionId *dest) +{ + dest->value++; + while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId) + dest->value++; +} + /* back up a transaction ID variable, handling wraparound correctly */ #define TransactionIdRetreat(dest) \ do { \ @@ -71,26 +107,37 @@ /* ---------- * Object ID (OID) zero is InvalidOid. * - * OIDs 1-9999 are reserved for manual assignment (see the files - * in src/include/catalog/). + * OIDs 1-9999 are reserved for manual assignment (see .dat files in + * src/include/catalog/). Of these, 8000-9999 are reserved for + * development purposes (such as in-progress patches and forks); + * they should not appear in released versions. + * + * OIDs 10000-11999 are reserved for assignment by genbki.pl, for use + * when the .dat files in src/include/catalog/ do not specify an OID + * for a catalog entry that requires one. * - * OIDS 10000-16383 are reserved for assignment during initdb - * using the OID generator. (We start the generator at 10000.) + * OIDS 12000-16383 are reserved for assignment during initdb + * using the OID generator. (We start the generator at 12000.) * * OIDs beginning at 16384 are assigned from the OID generator * during normal multiuser operation. (We force the generator up to * 16384 as soon as we are in normal operation.) * - * The choices of 10000 and 16384 are completely arbitrary, and can be moved - * if we run low on OIDs in either category. Changing the macros below - * should be sufficient to do this. + * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be + * moved if we run low on OIDs in any category. Changing the macros below, + * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES), + * should be sufficient to do this. Moving the 16384 boundary between + * initdb-assigned OIDs and user-defined objects would be substantially + * more painful, however, since some user-defined OIDs will appear in + * on-disk data; such a change would probably break pg_upgrade. * * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383 * and resume with 16384. This minimizes the odds of OID conflict, by not * reassigning OIDs that might have been assigned during initdb. * ---------- */ -#define FirstBootstrapObjectId 10000 +#define FirstGenbkiObjectId 10000 +#define FirstBootstrapObjectId 12000 #define FirstNormalObjectId 16384 /* @@ -114,12 +161,12 @@ typedef struct VariableCacheData /* * These fields are protected by XidGenLock. */ - TransactionId nextXid; /* next XID to assign */ + FullTransactionId nextFullXid; /* next full XID to assign */ TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ TransactionId xidVacLimit; /* start forcing autovacuums here */ TransactionId xidWarnLimit; /* start complaining here */ - TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */ + TransactionId xidStopLimit; /* refuse to advance nextFullXid beyond here */ TransactionId xidWrapLimit; /* where the world ends */ Oid oldestXidDB; /* database with minimum datfrozenxid */ @@ -162,7 +209,6 @@ extern PGDLLIMPORT VariableCache ShmemVariableCache; extern bool TransactionIdDidCommit(TransactionId transactionId); extern bool TransactionIdDidAbort(TransactionId transactionId); extern bool TransactionIdIsKnownCompleted(TransactionId transactionId); -extern void TransactionIdAbort(TransactionId transactionId); extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids); extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn); extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids); @@ -171,16 +217,35 @@ extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2); extern bool TransactionIdFollows(TransactionId id1, TransactionId id2); extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2); extern TransactionId TransactionIdLatest(TransactionId mainxid, - int nxids, const TransactionId *xids); + int nxids, const TransactionId *xids); extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); /* in transam/varsup.c */ -extern TransactionId GetNewTransactionId(bool isSubXact); -extern TransactionId ReadNewTransactionId(void); +extern FullTransactionId GetNewTransactionId(bool isSubXact); +extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid); +extern FullTransactionId ReadNextFullTransactionId(void); extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, - Oid oldest_datoid); + Oid oldest_datoid); extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid); extern bool ForceTransactionIdLimitUpdate(void); extern Oid GetNewObjectId(void); -#endif /* TRAMSAM_H */ +/* + * Some frontend programs include this header. For compilers that emit static + * inline functions even when they're unused, that leads to unsatisfied + * external references; hence hide them with #ifndef FRONTEND. + */ +#ifndef FRONTEND + +/* + * For callers that just need the XID part of the next transaction ID. + */ +static inline TransactionId +ReadNewTransactionId(void) +{ + return XidFromFullTransactionId(ReadNextFullTransactionId()); +} + +#endif /* FRONTEND */ + +#endif /* TRANSAM_H */ diff --git a/src/include/access/tsmapi.h b/src/include/access/tsmapi.h index 3ecd4737e5d..d3bdb754b5b 100644 --- a/src/include/access/tsmapi.h +++ b/src/include/access/tsmapi.h @@ -3,7 +3,7 @@ * tsmapi.h * API for tablesample methods * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * src/include/access/tsmapi.h * @@ -13,7 +13,7 @@ #define TSMAPI_H #include "nodes/execnodes.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" /* @@ -34,7 +34,8 @@ typedef void (*BeginSampleScan_function) (SampleScanState *node, int nparams, uint32 seed); -typedef BlockNumber (*NextSampleBlock_function) (SampleScanState *node); +typedef BlockNumber (*NextSampleBlock_function) (SampleScanState *node, + BlockNumber nblocks); typedef OffsetNumber (*NextSampleTuple_function) (SampleScanState *node, BlockNumber blockno, diff --git a/src/include/access/tupconvert.h b/src/include/access/tupconvert.h index 66c0ed0882a..6d095f8e0d1 100644 --- a/src/include/access/tupconvert.h +++ b/src/include/access/tupconvert.h @@ -4,7 +4,7 @@ * Tuple conversion support. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupconvert.h @@ -16,6 +16,7 @@ #include "access/htup.h" #include "access/tupdesc.h" +#include "executor/tuptable.h" typedef struct TupleConversionMap @@ -31,18 +32,20 @@ typedef struct TupleConversionMap extern TupleConversionMap *convert_tuples_by_position(TupleDesc indesc, - TupleDesc outdesc, - const char *msg); + TupleDesc outdesc, + const char *msg); extern TupleConversionMap *convert_tuples_by_name(TupleDesc indesc, - TupleDesc outdesc, - const char *msg); + TupleDesc outdesc); extern AttrNumber *convert_tuples_by_name_map(TupleDesc indesc, - TupleDesc outdesc, - const char *msg); + TupleDesc outdesc); +extern AttrNumber *convert_tuples_by_name_map_if_req(TupleDesc indesc, + TupleDesc outdesc); -extern HeapTuple do_convert_tuple(HeapTuple tuple, TupleConversionMap *map); +extern HeapTuple execute_attr_map_tuple(HeapTuple tuple, TupleConversionMap *map); +extern TupleTableSlot *execute_attr_map_slot(AttrNumber *attrMap, + TupleTableSlot *in_slot, TupleTableSlot *out_slot); extern void free_conversion_map(TupleConversionMap *map); diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h index 708160f645e..a06800555c8 100644 --- a/src/include/access/tupdesc.h +++ b/src/include/access/tupdesc.h @@ -4,7 +4,7 @@ * POSTGRES tuple descriptor definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupdesc.h @@ -19,15 +19,13 @@ #include "nodes/pg_list.h" -typedef struct attrDefault +typedef struct AttrDefault { AttrNumber adnum; char *adbin; /* nodeToString representation of expr */ } AttrDefault; -typedef struct attrMissing *MissingPtr; - -typedef struct constrCheck +typedef struct ConstrCheck { char *ccname; char *ccbin; /* nodeToString representation of expr */ @@ -36,14 +34,15 @@ typedef struct constrCheck } ConstrCheck; /* This structure contains constraints of a tuple */ -typedef struct tupleConstr +typedef struct TupleConstr { AttrDefault *defval; /* array */ ConstrCheck *check; /* array */ - MissingPtr missing; /* missing attributes values, NULL if none */ + struct AttrMissing *missing; /* missing attributes values, NULL if none */ uint16 num_defval; uint16 num_check; bool has_not_null; + bool has_generated_stored; } TupleConstr; /* @@ -55,7 +54,7 @@ typedef struct tupleConstr * structure is designed to let the constraints be omitted efficiently. * * Note that only user attributes, not system attributes, are mentioned in - * TupleDesc; with the exception that tdhasoid indicates if OID is present. + * TupleDesc. * * If the tupdesc is known to correspond to a named rowtype (such as a table's * rowtype) then tdtypeid identifies that type and tdtypmod is -1. Otherwise @@ -77,38 +76,37 @@ typedef struct tupleConstr * field of such a descriptor to -1, while reference-counted descriptors * always have tdrefcount >= 0. */ -typedef struct tupleDesc +typedef struct TupleDescData { int natts; /* number of attributes in the tuple */ Oid tdtypeid; /* composite type ID for tuple type */ int32 tdtypmod; /* typmod for tuple type */ - bool tdhasoid; /* tuple has oid attribute in its header */ int tdrefcount; /* reference count, or -1 if not counting */ TupleConstr *constr; /* constraints, or NULL if none */ /* attrs[N] is the description of Attribute Number N+1 */ FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER]; -} *TupleDesc; +} TupleDescData; +typedef struct TupleDescData *TupleDesc; /* Accessor for the i'th attribute of tupdesc. */ #define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)]) -extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid); +extern TupleDesc CreateTemplateTupleDesc(int natts); -extern TupleDesc CreateTupleDesc(int natts, bool hasoid, - Form_pg_attribute *attrs); +extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs); extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc); extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc); #define TupleDescSize(src) \ - (offsetof(struct tupleDesc, attrs) + \ + (offsetof(struct TupleDescData, attrs) + \ (src)->natts * sizeof(FormData_pg_attribute)) extern void TupleDescCopy(TupleDesc dst, TupleDesc src); extern void TupleDescCopyEntry(TupleDesc dst, AttrNumber dstAttno, - TupleDesc src, AttrNumber srcAttno); + TupleDesc src, AttrNumber srcAttno); extern void FreeTupleDesc(TupleDesc tupdesc); @@ -132,22 +130,22 @@ extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2); extern uint32 hashTupleDesc(TupleDesc tupdesc); extern void TupleDescInitEntry(TupleDesc desc, - AttrNumber attributeNumber, - const char *attributeName, - Oid oidtypeid, - int32 typmod, - int attdim); + AttrNumber attributeNumber, + const char *attributeName, + Oid oidtypeid, + int32 typmod, + int attdim); extern void TupleDescInitBuiltinEntry(TupleDesc desc, - AttrNumber attributeNumber, - const char *attributeName, - Oid oidtypeid, - int32 typmod, - int attdim); + AttrNumber attributeNumber, + const char *attributeName, + Oid oidtypeid, + int32 typmod, + int attdim); extern void TupleDescInitEntryCollation(TupleDesc desc, - AttrNumber attributeNumber, - Oid collationid); + AttrNumber attributeNumber, + Oid collationid); extern TupleDesc BuildDescForRelation(List *schema); diff --git a/src/include/access/tupdesc_details.h b/src/include/access/tupdesc_details.h index 741e996b3cc..a0b2be100f3 100644 --- a/src/include/access/tupdesc_details.h +++ b/src/include/access/tupdesc_details.h @@ -4,7 +4,7 @@ * POSTGRES tuple descriptor definitions we can't include everywhere * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupdesc_details.h @@ -19,11 +19,10 @@ * Structure used to represent value to be used when the attribute is not * present at all in a tuple, i.e. when the column was created after the tuple */ - -typedef struct attrMissing +typedef struct AttrMissing { - bool ammissingPresent; /* true if non-NULL missing value exists */ - Datum ammissing; /* value when attribute is missing */ + bool am_present; /* true if non-NULL missing value exists */ + Datum am_value; /* value when attribute is missing */ } AttrMissing; #endif /* TUPDESC_DETAILS_H */ diff --git a/src/include/access/tupmacs.h b/src/include/access/tupmacs.h index 1c3741da65b..23cf481e785 100644 --- a/src/include/access/tupmacs.h +++ b/src/include/access/tupmacs.h @@ -4,7 +4,7 @@ * Tuple macros used by both index tuples and heap tuples. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/tupmacs.h @@ -16,7 +16,9 @@ /* - * check to see if the ATT'th bit of an array of 8-bit bytes is set. + * Check a tuple's null bitmap to determine whether the attribute is null. + * Note that a 0 in the null bitmap indicates a null, while 1 indicates + * non-null. */ #define att_isnull(ATT, BITS) (!((BITS)[(ATT) >> 3] & (1 << ((ATT) & 0x07)))) diff --git a/src/include/access/twophase.h b/src/include/access/twophase.h index f05cde202f7..b9a531c96e3 100644 --- a/src/include/access/twophase.h +++ b/src/include/access/twophase.h @@ -4,7 +4,7 @@ * Two-phase-commit related declarations. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/twophase.h @@ -34,21 +34,21 @@ extern void TwoPhaseShmemInit(void); extern void AtAbort_Twophase(void); extern void PostPrepare_Twophase(void); -extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid); -extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid); +extern PGPROC *TwoPhaseGetDummyProc(TransactionId xid, bool lock_held); +extern BackendId TwoPhaseGetDummyBackendId(TransactionId xid, bool lock_held); extern GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, - TimestampTz prepared_at, - Oid owner, Oid databaseid); + TimestampTz prepared_at, + Oid owner, Oid databaseid); extern void StartPrepare(GlobalTransaction gxact); extern void EndPrepare(GlobalTransaction gxact); extern bool StandbyTransactionIdIsPrepared(TransactionId xid); extern TransactionId PrescanPreparedTransactions(TransactionId **xids_p, - int *nxids_p); + int *nxids_p); extern void ParsePrepareRecord(uint8 info, char *xlrec, - xl_xact_parsed_prepare *parsed); + xl_xact_parsed_prepare *parsed); extern void StandbyRecoverPreparedTransactions(void); extern void RecoverPreparedTransactions(void); @@ -57,7 +57,7 @@ extern void CheckPointTwoPhase(XLogRecPtr redo_horizon); extern void FinishPreparedTransaction(const char *gid, bool isCommit); extern void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, - XLogRecPtr end_lsn, RepOriginId origin_id); + XLogRecPtr end_lsn, RepOriginId origin_id); extern void PrepareRedoRemove(TransactionId xid, bool giveWarning); extern void restoreTwoPhaseData(void); #endif /* TWOPHASE_H */ diff --git a/src/include/access/twophase_rmgr.h b/src/include/access/twophase_rmgr.h index ba9cd932a7a..b20f94b4752 100644 --- a/src/include/access/twophase_rmgr.h +++ b/src/include/access/twophase_rmgr.h @@ -4,7 +4,7 @@ * Two-phase-commit resource managers definition * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/twophase_rmgr.h @@ -35,6 +35,6 @@ extern const TwoPhaseCallback twophase_standby_recover_callbacks[]; extern void RegisterTwoPhaseRecord(TwoPhaseRmgrId rmid, uint16 info, - const void *data, uint32 len); + const void *data, uint32 len); #endif /* TWOPHASE_RMGR_H */ diff --git a/src/include/access/valid.h b/src/include/access/valid.h index 1e2d23f6455..6c6ecdf1cc9 100644 --- a/src/include/access/valid.h +++ b/src/include/access/valid.h @@ -4,7 +4,7 @@ * POSTGRES tuple qualification validity definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/valid.h diff --git a/src/include/access/visibilitymap.h b/src/include/access/visibilitymap.h index b168612b4bb..0532b04e349 100644 --- a/src/include/access/visibilitymap.h +++ b/src/include/access/visibilitymap.h @@ -4,7 +4,7 @@ * visibility map interface * * - * Portions Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2007-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/visibilitymap.h @@ -35,15 +35,16 @@ ((visibilitymap_get_status((r), (b), (v)) & VISIBILITYMAP_ALL_FROZEN) != 0) extern bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, - Buffer vmbuf, uint8 flags); + Buffer vmbuf, uint8 flags); extern void visibilitymap_pin(Relation rel, BlockNumber heapBlk, - Buffer *vmbuf); + Buffer *vmbuf); extern bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf); extern void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, - XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, - uint8 flags); + XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, + uint8 flags); extern uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf); extern void visibilitymap_count(Relation rel, BlockNumber *all_visible, BlockNumber *all_frozen); -extern void visibilitymap_truncate(Relation rel, BlockNumber nheapblocks); +extern BlockNumber visibilitymap_prepare_truncate(Relation rel, + BlockNumber nheapblocks); #endif /* VISIBILITYMAP_H */ diff --git a/src/include/access/xact.h b/src/include/access/xact.h index a46396f2d92..d7145517047 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -4,7 +4,7 @@ * postgres transaction system definitions * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xact.h @@ -14,6 +14,7 @@ #ifndef XACT_H #define XACT_H +#include "access/transam.h" #include "access/xlogreader.h" #include "lib/stringinfo.h" #include "nodes/pg_list.h" @@ -54,6 +55,9 @@ extern PGDLLIMPORT int XactIsoLevel; extern bool DefaultXactReadOnly; extern bool XactReadOnly; +/* flag for logging statements in this transaction */ +extern bool xact_is_sampled; + /* * Xact is deferrable -- only meaningful (currently) for read only * SERIALIZABLE transactions @@ -87,10 +91,10 @@ extern int synchronous_commit; extern int MyXactFlags; /* - * XACT_FLAGS_ACCESSEDTEMPREL - set when a temporary relation is accessed. We - * don't allow PREPARE TRANSACTION in that case. + * XACT_FLAGS_ACCESSEDTEMPNAMESPACE - set when a temporary object is accessed. + * We don't allow PREPARE TRANSACTION in that case. */ -#define XACT_FLAGS_ACCESSEDTEMPREL (1U << 0) +#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE (1U << 0) /* * XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK - records whether the top level xact @@ -98,7 +102,6 @@ extern int MyXactFlags; */ #define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK (1U << 1) - /* * start- and end-of-transaction callbacks for dynamically loaded modules */ @@ -269,6 +272,7 @@ typedef struct xl_xact_commit /* xl_xact_relfilenodes follows if XINFO_HAS_RELFILENODES */ /* xl_xact_invals follows if XINFO_HAS_INVALS */ /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */ + /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */ /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */ } xl_xact_commit; #define MinSizeOfXactCommit (offsetof(xl_xact_commit, xact_time) + sizeof(TimestampTz)) @@ -278,11 +282,13 @@ typedef struct xl_xact_abort TimestampTz xact_time; /* time of abort */ /* xl_xact_xinfo follows if XLOG_XACT_HAS_INFO */ - /* No db_info required */ - /* xl_xact_subxacts follows if HAS_SUBXACT */ - /* xl_xact_relfilenodes follows if HAS_RELFILENODES */ + /* xl_xact_dbinfo follows if XINFO_HAS_DBINFO */ + /* xl_xact_subxacts follows if XINFO_HAS_SUBXACT */ + /* xl_xact_relfilenodes follows if XINFO_HAS_RELFILENODES */ /* No invalidation messages needed. */ /* xl_xact_twophase follows if XINFO_HAS_TWOPHASE */ + /* twophase_gid follows if XINFO_HAS_GID. As a null-terminated string. */ + /* xl_xact_origin follows if XINFO_HAS_ORIGIN, stored unaligned! */ } xl_xact_abort; #define MinSizeOfXactAbort sizeof(xl_xact_abort) @@ -309,7 +315,7 @@ typedef struct xl_xact_parsed_commit SharedInvalidationMessage *msgs; TransactionId twophase_xid; /* only for 2PC */ - char twophase_gid[GIDSIZE]; /* only for 2PC */ + char twophase_gid[GIDSIZE]; /* only for 2PC */ int nabortrels; /* only for 2PC */ RelFileNode *abortnodes; /* only for 2PC */ @@ -334,7 +340,7 @@ typedef struct xl_xact_parsed_abort RelFileNode *xnodes; TransactionId twophase_xid; /* only for 2PC */ - char twophase_gid[GIDSIZE]; /* only for 2PC */ + char twophase_gid[GIDSIZE]; /* only for 2PC */ XLogRecPtr origin_lsn; TimestampTz origin_timestamp; @@ -353,9 +359,14 @@ extern TransactionId GetCurrentTransactionId(void); extern TransactionId GetCurrentTransactionIdIfAny(void); extern TransactionId GetStableLatestTransactionId(void); extern SubTransactionId GetCurrentSubTransactionId(void); +extern FullTransactionId GetTopFullTransactionId(void); +extern FullTransactionId GetTopFullTransactionIdIfAny(void); +extern FullTransactionId GetCurrentFullTransactionId(void); +extern FullTransactionId GetCurrentFullTransactionIdIfAny(void); extern void MarkCurrentTransactionIdLoggedIfAny(void); extern bool SubTransactionIsActive(SubTransactionId subxid); extern CommandId GetCurrentCommandId(bool used); +extern void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts); extern TimestampTz GetCurrentTransactionStartTimestamp(void); extern TimestampTz GetCurrentStatementStartTimestamp(void); extern TimestampTz GetCurrentTransactionStopTimestamp(void); @@ -365,12 +376,14 @@ extern bool TransactionIdIsCurrentTransactionId(TransactionId xid); extern void CommandCounterIncrement(void); extern void ForceSyncCommit(void); extern void StartTransactionCommand(void); +extern void SaveTransactionCharacteristics(void); +extern void RestoreTransactionCharacteristics(void); extern void CommitTransactionCommand(void); extern void AbortCurrentTransaction(void); extern void BeginTransactionBlock(void); -extern bool EndTransactionBlock(void); +extern bool EndTransactionBlock(bool chain); extern bool PrepareTransactionBlock(const char *gid); -extern void UserAbortTransactionBlock(void); +extern void UserAbortTransactionBlock(bool chain); extern void BeginImplicitTransactionBlock(void); extern void EndImplicitTransactionBlock(void); extern void ReleaseSavepoint(const char *name); @@ -400,19 +413,19 @@ extern void UnregisterSubXactCallback(SubXactCallback callback, void *arg); extern int xactGetCommittedChildren(TransactionId **ptr); extern XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, - int nsubxacts, TransactionId *subxacts, - int nrels, RelFileNode *rels, - int nmsgs, SharedInvalidationMessage *msgs, - bool relcacheInval, bool forceSync, - int xactflags, - TransactionId twophase_xid, - const char *twophase_gid); + int nsubxacts, TransactionId *subxacts, + int nrels, RelFileNode *rels, + int nmsgs, SharedInvalidationMessage *msgs, + bool relcacheInval, bool forceSync, + int xactflags, + TransactionId twophase_xid, + const char *twophase_gid); extern XLogRecPtr XactLogAbortRecord(TimestampTz abort_time, - int nsubxacts, TransactionId *subxacts, - int nrels, RelFileNode *rels, - int xactflags, TransactionId twophase_xid, - const char *twophase_gid); + int nsubxacts, TransactionId *subxacts, + int nrels, RelFileNode *rels, + int xactflags, TransactionId twophase_xid, + const char *twophase_gid); extern void xact_redo(XLogReaderState *record); /* xactdesc.c */ diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 421ba6d7755..d519252aad7 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -3,7 +3,7 @@ * * PostgreSQL write-ahead log manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlog.h @@ -75,7 +75,7 @@ extern HotStandbyState standbyState; /* * Recovery target type. - * Only set during a Point in Time recovery, not when standby_mode = on + * Only set during a Point in Time recovery, not when in standby mode. */ typedef enum { @@ -87,6 +87,16 @@ typedef enum RECOVERY_TARGET_IMMEDIATE } RecoveryTargetType; +/* + * Recovery target TimeLine goal + */ +typedef enum +{ + RECOVERY_TARGET_TIMELINE_CONTROLFILE, + RECOVERY_TARGET_TIMELINE_LATEST, + RECOVERY_TARGET_TIMELINE_NUMERIC +} RecoveryTargetTimeLineGoal; + extern XLogRecPtr ProcLastRecPtr; extern XLogRecPtr XactLastRecEnd; extern PGDLLIMPORT XLogRecPtr XactLastCommitEnd; @@ -106,12 +116,37 @@ extern bool EnableHotStandby; extern bool fullPageWrites; extern bool wal_log_hints; extern bool wal_compression; +extern bool wal_init_zero; +extern bool wal_recycle; extern bool *wal_consistency_checking; extern char *wal_consistency_checking_string; extern bool log_checkpoints; +extern char *recoveryRestoreCommand; +extern char *recoveryEndCommand; +extern char *archiveCleanupCommand; +extern bool recoveryTargetInclusive; +extern int recoveryTargetAction; +extern int recovery_min_apply_delay; +extern char *PrimaryConnInfo; +extern char *PrimarySlotName; + +/* indirectly set via GUC system */ +extern TransactionId recoveryTargetXid; +extern char *recovery_target_time_string; +extern const char *recoveryTargetName; +extern XLogRecPtr recoveryTargetLSN; +extern RecoveryTargetType recoveryTarget; +extern char *PromoteTriggerFile; +extern RecoveryTargetTimeLineGoal recoveryTargetTimeLineGoal; +extern TimeLineID recoveryTargetTLIRequested; +extern TimeLineID recoveryTargetTLI; extern int CheckPointSegments; +/* option set locally in startup process only when signal files exist */ +extern bool StandbyModeRequested; +extern bool StandbyMode; + /* Archive modes */ typedef enum ArchiveMode { @@ -182,9 +217,10 @@ extern bool XLOG_DEBUG; * belonging to unlogged tables */ /* These are important to RequestCheckpoint */ #define CHECKPOINT_WAIT 0x0020 /* Wait for completion */ +#define CHECKPOINT_REQUESTED 0x0040 /* Checkpoint request has been made */ /* These indicate the cause of a checkpoint request */ -#define CHECKPOINT_CAUSE_XLOG 0x0040 /* XLOG consumption */ -#define CHECKPOINT_CAUSE_TIME 0x0080 /* Elapsed time */ +#define CHECKPOINT_CAUSE_XLOG 0x0080 /* XLOG consumption */ +#define CHECKPOINT_CAUSE_TIME 0x0100 /* Elapsed time */ /* * Flag bits for the record being inserted, set using XLogSetRecordFlags(). @@ -221,8 +257,8 @@ extern CheckpointStatsData CheckpointStats; struct XLogRecData; extern XLogRecPtr XLogInsertRecord(struct XLogRecData *rdata, - XLogRecPtr fpw_lsn, - uint8 flags); + XLogRecPtr fpw_lsn, + uint8 flags); extern void XLogFlush(XLogRecPtr RecPtr); extern bool XLogBackgroundFlush(void); extern bool XLogNeedsFlush(XLogRecPtr RecPtr); @@ -276,7 +312,6 @@ extern XLogRecPtr GetRedoRecPtr(void); extern XLogRecPtr GetInsertRecPtr(void); extern XLogRecPtr GetFlushRecPtr(void); extern XLogRecPtr GetLastImportantRecPtr(void); -extern void GetNextXidAndEpoch(TransactionId *xid, uint32 *epoch); extern void RemovePromoteSignalFiles(void); extern bool CheckPromoteSignal(void); @@ -310,19 +345,25 @@ typedef enum SessionBackupState } SessionBackupState; extern XLogRecPtr do_pg_start_backup(const char *backupidstr, bool fast, - TimeLineID *starttli_p, StringInfo labelfile, - List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, - bool needtblspcmapfile); + TimeLineID *starttli_p, StringInfo labelfile, + List **tablespaces, StringInfo tblspcmapfile, bool infotbssize, + bool needtblspcmapfile); extern XLogRecPtr do_pg_stop_backup(char *labelfile, bool waitforarchive, - TimeLineID *stoptli_p); + TimeLineID *stoptli_p); extern void do_pg_abort_backup(void); extern SessionBackupState get_backup_status(void); /* File path names (all relative to $PGDATA) */ +#define RECOVERY_SIGNAL_FILE "recovery.signal" +#define STANDBY_SIGNAL_FILE "standby.signal" #define BACKUP_LABEL_FILE "backup_label" #define BACKUP_LABEL_OLD "backup_label.old" #define TABLESPACE_MAP "tablespace_map" #define TABLESPACE_MAP_OLD "tablespace_map.old" +/* files to signal promotion to primary */ +#define PROMOTE_SIGNAL_FILE "promote" +#define FALLBACK_PROMOTE_SIGNAL_FILE "fallback_promote" + #endif /* XLOG_H */ diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index a5c074642f6..3f0de6625d7 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -11,7 +11,7 @@ * Note: This file must be includable in both frontend and backend contexts, * to allow stand-alone tools like pg_receivewal to deal with WAL files. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD097 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD101 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { @@ -45,7 +45,7 @@ typedef struct XLogPageHeaderData * continue on the next page. xlp_rem_len is the number of bytes * remaining from a previous page. * - * Note that xl_rem_len includes backup-block data; that is, it tracks + * Note that xlp_rem_len includes backup-block data; that is, it tracks * xl_tot_len not xl_len in the initial header. Also note that the * continuation data isn't necessarily aligned. */ @@ -101,7 +101,7 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define XLogSegmentsPerXLogId(wal_segsz_bytes) \ (UINT64CONST(0x100000000) / (wal_segsz_bytes)) -#define XLogSegNoOffsetToRecPtr(segno, offset, dest, wal_segsz_bytes) \ +#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \ (dest) = (segno) * (wal_segsz_bytes) + (offset) #define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ @@ -226,6 +226,7 @@ typedef struct xl_parameter_change { int MaxConnections; int max_worker_processes; + int max_wal_senders; int max_prepared_xacts; int max_locks_per_xact; int wal_level; @@ -267,7 +268,7 @@ typedef enum RECOVERY_TARGET_ACTION_PAUSE, RECOVERY_TARGET_ACTION_PROMOTE, RECOVERY_TARGET_ACTION_SHUTDOWN -} RecoveryTargetAction; +} RecoveryTargetAction; /* * Method table for resource managers. @@ -319,10 +320,10 @@ extern char *recoveryRestoreCommand; * Prototypes for functions in xlogarchive.c */ extern bool RestoreArchivedFile(char *path, const char *xlogfname, - const char *recovername, off_t expectedSize, - bool cleanupEnabled); + const char *recovername, off_t expectedSize, + bool cleanupEnabled); extern void ExecuteRecoveryCommand(const char *command, const char *commandName, - bool failOnerror); + bool failOnSignal); extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname); extern void XLogArchiveNotify(const char *xlog); extern void XLogArchiveNotifySeg(XLogSegNo segno); diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h index 0a48d1cfb40..daded3dca05 100644 --- a/src/include/access/xlogdefs.h +++ b/src/include/access/xlogdefs.h @@ -4,7 +4,7 @@ * Postgres write-ahead log manager record pointer and * timeline number definitions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlogdefs.h @@ -22,12 +22,19 @@ typedef uint64 XLogRecPtr; /* * Zero is used indicate an invalid pointer. Bootstrap skips the first possible - * WAL segment, initializing the first WAL page at XLOG_SEG_SIZE, so no XLOG + * WAL segment, initializing the first WAL page at WAL segment size, so no XLOG * record can begin at zero. */ #define InvalidXLogRecPtr 0 #define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr) +/* + * First LSN to use for "fake" LSNs. + * + * Values smaller than this can be used for special per-AM purposes. + */ +#define FirstNormalUnloggedLSN ((XLogRecPtr) 1000) + /* * XLogSegNo - physical log file sequence number. */ diff --git a/src/include/access/xloginsert.h b/src/include/access/xloginsert.h index fa62f915afc..eeb0412b662 100644 --- a/src/include/access/xloginsert.h +++ b/src/include/access/xloginsert.h @@ -3,7 +3,7 @@ * * Functions for generating WAL records * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xloginsert.h @@ -16,6 +16,7 @@ #include "storage/block.h" #include "storage/buf.h" #include "storage/relfilenode.h" +#include "utils/relcache.h" /* * The minimum size of the WAL construction working area. If you need to @@ -41,19 +42,21 @@ extern void XLogBeginInsert(void); extern void XLogSetRecordFlags(uint8 flags); extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info); -extern void XLogEnsureRecordSpace(int nbuffers, int ndatas); +extern void XLogEnsureRecordSpace(int max_block_id, int ndatas); extern void XLogRegisterData(char *data, int len); extern void XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags); extern void XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, - ForkNumber forknum, BlockNumber blknum, char *page, - uint8 flags); + ForkNumber forknum, BlockNumber blknum, char *page, + uint8 flags); extern void XLogRegisterBufData(uint8 block_id, char *data, int len); extern void XLogResetInsertion(void); extern bool XLogCheckBufferNeedsBackup(Buffer buffer); extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, - BlockNumber blk, char *page, bool page_std); + BlockNumber blk, char *page, bool page_std); extern XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std); +extern void log_newpage_range(Relation rel, ForkNumber forkNum, + BlockNumber startblk, BlockNumber endblk, bool page_std); extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std); extern void InitXLogInsert(void); diff --git a/src/include/access/xlogreader.h b/src/include/access/xlogreader.h index 688422f61c4..1bbee386e8d 100644 --- a/src/include/access/xlogreader.h +++ b/src/include/access/xlogreader.h @@ -3,7 +3,7 @@ * xlogreader.h * Definitions for the generic XLog reading facility * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/access/xlogreader.h @@ -25,8 +25,28 @@ #ifndef XLOGREADER_H #define XLOGREADER_H +#ifndef FRONTEND +#include "access/transam.h" +#endif + #include "access/xlogrecord.h" +/* WALOpenSegment represents a WAL segment being read. */ +typedef struct WALOpenSegment +{ + int ws_file; /* segment file descriptor */ + XLogSegNo ws_segno; /* segment number */ + uint32 ws_off; /* offset in the segment */ + TimeLineID ws_tli; /* timeline ID of the currently open file */ +} WALOpenSegment; + +/* WALSegmentContext carries context information about WAL segments to read */ +typedef struct WALSegmentContext +{ + char ws_dir[MAXPGPATH]; + int ws_segsize; +} WALSegmentContext; + typedef struct XLogReaderState XLogReaderState; /* Function type definition for the read_page callback */ @@ -34,8 +54,7 @@ typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, - char *readBuf, - TimeLineID *pageTLI); + char *readBuf); typedef struct { @@ -73,11 +92,6 @@ struct XLogReaderState * ---------------------------------------- */ - /* - * Segment size of the to-be-parsed data (mandatory). - */ - int wal_segment_size; - /* * Data input callback (mandatory). * @@ -95,9 +109,8 @@ struct XLogReaderState * actual WAL record it's interested in. In that case, targetRecPtr can * be used to determine which timeline to read the page from. * - * The callback shall set *pageTLI to the TLI of the file the page was - * read from. It is currently used only for error reporting purposes, to - * reconstruct the name of the WAL file where an error occurred. + * The callback shall set ->seg.ws_tli to the TLI of the file the page was + * read from. */ XLogPageReadCB read_page; @@ -152,10 +165,9 @@ struct XLogReaderState char *readBuf; uint32 readLen; - /* last read segment, segment offset, TLI for data currently in readBuf */ - XLogSegNo readSegNo; - uint32 readOff; - TimeLineID readPageTLI; + /* last read XLOG position for data currently in readBuf */ + WALSegmentContext segcxt; + WALOpenSegment seg; /* * beginning of prior page read, and its TLI. Doesn't necessarily @@ -185,7 +197,10 @@ struct XLogReaderState */ TimeLineID nextTLI; - /* Buffer for current ReadRecord result (expandable) */ + /* + * Buffer for current ReadRecord result (expandable), used when a record + * crosses a page boundary. + */ char *readRecordBuf; uint32 readRecordBufSize; @@ -195,27 +210,32 @@ struct XLogReaderState /* Get a new XLogReader */ extern XLogReaderState *XLogReaderAllocate(int wal_segment_size, - XLogPageReadCB pagereadfunc, - void *private_data); + const char *waldir, + XLogPageReadCB pagereadfunc, + void *private_data); /* Free an XLogReader */ extern void XLogReaderFree(XLogReaderState *state); +/* Initialize supporting structures */ +extern void WALOpenSegmentInit(WALOpenSegment *seg, WALSegmentContext *segcxt, + int segsize, const char *waldir); + /* Read the next XLog record. Returns NULL on end-of-WAL or failure */ extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, - XLogRecPtr recptr, char **errormsg); + XLogRecPtr recptr, char **errormsg); -/* Invalidate read state */ -extern void XLogReaderInvalReadState(XLogReaderState *state); +/* Validate a page */ +extern bool XLogReaderValidatePageHeader(XLogReaderState *state, + XLogRecPtr recptr, char *phdr); #ifdef FRONTEND extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); #endif /* FRONTEND */ - /* Functions for decoding an XLogRecord */ extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, - char **errmsg); + char **errmsg); #define XLogRecGetTotalLen(decoder) ((decoder)->decoded_record->xl_tot_len) #define XLogRecGetPrev(decoder) ((decoder)->decoded_record->xl_prev) @@ -233,10 +253,14 @@ extern bool DecodeXLogRecord(XLogReaderState *state, XLogRecord *record, #define XLogRecBlockImageApply(decoder, block_id) \ ((decoder)->blocks[block_id].apply_image) -extern bool RestoreBlockImage(XLogReaderState *recoder, uint8 block_id, char *dst); +#ifndef FRONTEND +extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record); +#endif + +extern bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page); extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len); extern bool XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, - RelFileNode *rnode, ForkNumber *forknum, - BlockNumber *blknum); + RelFileNode *rnode, ForkNumber *forknum, + BlockNumber *blknum); #endif /* XLOGREADER_H */ diff --git a/src/include/access/xlogrecord.h b/src/include/access/xlogrecord.h index 863781937e4..9375e54195f 100644 --- a/src/include/access/xlogrecord.h +++ b/src/include/access/xlogrecord.h @@ -3,7 +3,7 @@ * * Definitions for the WAL record format. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlogrecord.h @@ -107,15 +107,14 @@ typedef struct XLogRecordBlockHeader * Additional header information when a full-page image is included * (i.e. when BKPBLOCK_HAS_IMAGE is set). * - * As a trivial form of data compression, the XLOG code is aware that - * PG data pages usually contain an unused "hole" in the middle, which - * contains only zero bytes. If the length of "hole" > 0 then we have removed - * such a "hole" from the stored data (and it's not counted in the - * XLOG record's CRC, either). Hence, the amount of block data actually - * present is BLCKSZ - the length of "hole" bytes. + * The XLOG code is aware that PG data pages usually contain an unused "hole" + * in the middle, which contains only zero bytes. Since we know that the + * "hole" is all zeros, we remove it from the stored data (and it's not counted + * in the XLOG record's CRC, either). Hence, the amount of block data actually + * present is (BLCKSZ - ). * - * When wal_compression is enabled, a full page image which "hole" was - * removed is additionally compressed using PGLZ compression algorithm. + * Additionally, when wal_compression is enabled, we will try to compress full + * page images using the PGLZ compression algorithm, after removing the "hole". * This can reduce the WAL volume, but at some extra cost of CPU spent * on the compression during WAL logging. In this case, since the "hole" * length cannot be calculated by subtracting the number of page image bytes diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h index c4066999365..2df98e45b20 100644 --- a/src/include/access/xlogutils.h +++ b/src/include/access/xlogutils.h @@ -3,7 +3,7 @@ * * Utilities for replaying WAL records. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/access/xlogutils.h @@ -21,7 +21,7 @@ extern void XLogCheckInvalidPages(void); extern void XLogDropRelation(RelFileNode rnode, ForkNumber forknum); extern void XLogDropDatabase(Oid dbid); extern void XLogTruncateRelation(RelFileNode rnode, ForkNumber forkNum, - BlockNumber nblocks); + BlockNumber nblocks); /* Result codes for XLogReadBufferForRedo[Extended] */ typedef enum @@ -34,25 +34,24 @@ typedef enum } XLogRedoAction; extern XLogRedoAction XLogReadBufferForRedo(XLogReaderState *record, - uint8 buffer_id, Buffer *buf); + uint8 buffer_id, Buffer *buf); extern Buffer XLogInitBufferForRedo(XLogReaderState *record, uint8 block_id); extern XLogRedoAction XLogReadBufferForRedoExtended(XLogReaderState *record, - uint8 buffer_id, - ReadBufferMode mode, bool get_cleanup_lock, - Buffer *buf); + uint8 buffer_id, + ReadBufferMode mode, bool get_cleanup_lock, + Buffer *buf); extern Buffer XLogReadBufferExtended(RelFileNode rnode, ForkNumber forknum, - BlockNumber blkno, ReadBufferMode mode); + BlockNumber blkno, ReadBufferMode mode); extern Relation CreateFakeRelcacheEntry(RelFileNode rnode); extern void FreeFakeRelcacheEntry(Relation fakerel); -extern int read_local_xlog_page(XLogReaderState *state, - XLogRecPtr targetPagePtr, int reqLen, - XLogRecPtr targetRecPtr, char *cur_page, - TimeLineID *pageTLI); +extern int read_local_xlog_page(XLogReaderState *state, + XLogRecPtr targetPagePtr, int reqLen, + XLogRecPtr targetRecPtr, char *cur_page); extern void XLogReadDetermineTimeline(XLogReaderState *state, - XLogRecPtr wantPage, uint32 wantLength); + XLogRecPtr wantPage, uint32 wantLength); #endif diff --git a/src/include/bootstrap/bootstrap.h b/src/include/bootstrap/bootstrap.h index 4f4129419f2..85705602cb3 100644 --- a/src/include/bootstrap/bootstrap.h +++ b/src/include/bootstrap/bootstrap.h @@ -4,7 +4,7 @@ * include file for the bootstrapping code * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/bootstrap/bootstrap.h @@ -34,29 +34,25 @@ extern int numattr; extern void AuxiliaryProcessMain(int argc, char *argv[]) pg_attribute_noreturn(); -extern void err_out(void); - extern void closerel(char *name); extern void boot_openrel(char *name); extern void DefineAttr(char *name, char *type, int attnum, int nullness); -extern void InsertOneTuple(Oid objectid); +extern void InsertOneTuple(void); extern void InsertOneValue(char *value, int i); extern void InsertOneNull(int i); -extern char *MapArrayTypeName(const char *s); - extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo); extern void build_indices(void); extern void boot_get_type_io_data(Oid typid, - int16 *typlen, - bool *typbyval, - char *typalign, - char *typdelim, - Oid *typioparam, - Oid *typinput, - Oid *typoutput); + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *typinput, + Oid *typoutput); extern int boot_yyparse(void); diff --git a/src/include/c.h b/src/include/c.h index 95e9aeded9d..f461628a24e 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -9,7 +9,7 @@ * polluting the namespace with lots of stuff... * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/c.h @@ -224,6 +224,39 @@ #define CppAsString2(x) CppAsString(x) #define CppConcat(x, y) x##y +/* + * VA_ARGS_NARGS + * Returns the number of macro arguments it is passed. + * + * An empty argument still counts as an argument, so effectively, this is + * "one more than the number of commas in the argument list". + * + * This works for up to 63 arguments. Internally, VA_ARGS_NARGS_() is passed + * 64+N arguments, and the C99 standard only requires macros to allow up to + * 127 arguments, so we can't portably go higher. The implementation is + * pretty trivial: VA_ARGS_NARGS_() returns its 64th argument, and we set up + * the call so that that is the appropriate one of the list of constants. + * This idea is due to Laurent Deniau. + */ +#define VA_ARGS_NARGS(...) \ + VA_ARGS_NARGS_(__VA_ARGS__, \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define VA_ARGS_NARGS_( \ + _01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63, N, ...) \ + (N) + /* * dummyret is used to set return values in macros that use ?: to make * assignments. gcc wants these to be void, other compilers like char @@ -272,7 +305,7 @@ #else #ifndef bool -typedef char bool; +typedef unsigned char bool; #endif #ifndef true @@ -381,15 +414,15 @@ typedef unsigned long long int uint64; typedef PG_INT128_TYPE int128 #if defined(pg_attribute_aligned) -pg_attribute_aligned(MAXIMUM_ALIGNOF) + pg_attribute_aligned(MAXIMUM_ALIGNOF) #endif -; + ; typedef unsigned PG_INT128_TYPE uint128 #if defined(pg_attribute_aligned) -pg_attribute_aligned(MAXIMUM_ALIGNOF) + pg_attribute_aligned(MAXIMUM_ALIGNOF) #endif -; + ; #endif #endif @@ -722,7 +755,7 @@ typedef NameData *Name; #define Trap(condition, errorType) \ do { \ if (condition) \ - ExceptionalCondition(CppAsString(condition), (errorType), \ + ExceptionalCondition(#condition, (errorType), \ __FILE__, __LINE__); \ } while (0) @@ -735,20 +768,34 @@ typedef NameData *Name; */ #define TrapMacro(condition, errorType) \ ((bool) (! (condition) || \ - (ExceptionalCondition(CppAsString(condition), (errorType), \ + (ExceptionalCondition(#condition, (errorType), \ __FILE__, __LINE__), 0))) #define Assert(condition) \ - Trap(!(condition), "FailedAssertion") + do { \ + if (!(condition)) \ + ExceptionalCondition(#condition, "FailedAssertion", \ + __FILE__, __LINE__); \ + } while (0) #define AssertMacro(condition) \ - ((void) TrapMacro(!(condition), "FailedAssertion")) + ((void) ((condition) || \ + (ExceptionalCondition(#condition, "FailedAssertion", \ + __FILE__, __LINE__), 0))) #define AssertArg(condition) \ - Trap(!(condition), "BadArgument") + do { \ + if (!(condition)) \ + ExceptionalCondition(#condition, "BadArgument", \ + __FILE__, __LINE__); \ + } while (0) #define AssertState(condition) \ - Trap(!(condition), "BadState") + do { \ + if (!(condition)) \ + ExceptionalCondition(#condition, "BadState", \ + __FILE__, __LINE__); \ + } while (0) /* * Check that `ptr' is `bndr' aligned. @@ -767,8 +814,8 @@ typedef NameData *Name; */ #ifndef FRONTEND extern void ExceptionalCondition(const char *conditionName, - const char *errorType, - const char *fileName, int lineNumber) pg_attribute_noreturn(); + const char *errorType, + const char *fileName, int lineNumber) pg_attribute_noreturn(); #endif /* @@ -989,6 +1036,40 @@ extern void ExceptionalCondition(const char *conditionName, * ---------------------------------------------------------------- */ +/* + * Invert the sign of a qsort-style comparison result, ie, exchange negative + * and positive integer values, being careful not to get the wrong answer + * for INT_MIN. The argument should be an integral variable. + */ +#define INVERT_COMPARE_RESULT(var) \ + ((var) = ((var) < 0) ? 1 : -(var)) + +/* + * Use this, not "char buf[BLCKSZ]", to declare a field or local variable + * holding a page buffer, if that page might be accessed as a page and not + * just a string of bytes. Otherwise the variable might be under-aligned, + * causing problems on alignment-picky hardware. (In some places, we use + * this to declare buffers even though we only pass them to read() and + * write(), because copying to/from aligned buffers is usually faster than + * using unaligned buffers.) We include both "double" and "int64" in the + * union to ensure that the compiler knows the value must be MAXALIGN'ed + * (cf. configure's computation of MAXIMUM_ALIGNOF). + */ +typedef union PGAlignedBlock +{ + char data[BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedBlock; + +/* Same, but for an XLOG_BLCKSZ-sized buffer */ +typedef union PGAlignedXLogBlock +{ + char data[XLOG_BLCKSZ]; + double force_align_d; + int64 force_align_i64; +} PGAlignedXLogBlock; + /* msb for char */ #define HIGHBIT (0x80) #define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) @@ -1054,6 +1135,36 @@ extern void ExceptionalCondition(const char *conditionName, #define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) #endif +/* + * Macro that allows to cast constness and volatile away from an expression, but doesn't + * allow changing the underlying type. Enforcement of the latter + * currently only works for gcc like compilers. + * + * Please note IT IS NOT SAFE to cast constness away if the result will ever + * be modified (it would be undefined behaviour). Doing so anyway can cause + * compiler misoptimizations or runtime crashes (modifying readonly memory). + * It is only safe to use when the result will not be modified, but API + * design or language restrictions prevent you from declaring that + * (e.g. because a function returns both const and non-const variables). + * + * Note that this only works in function scope, not for global variables (it'd + * be nice, but not trivial, to improve that). + */ +#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) +#define unconstify(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile underlying_type), \ + "wrong cast"), \ + (underlying_type) (expr)) +#else +#define unconstify(underlying_type, expr) \ + ((underlying_type) (expr)) +#define unvolatize(underlying_type, expr) \ + ((underlying_type) (expr)) +#endif /* ---------------------------------------------------------------- * Section 9: system-specific hacks @@ -1088,14 +1199,41 @@ extern void ExceptionalCondition(const char *conditionName, * standard C library. */ -#if !HAVE_DECL_SNPRINTF -extern int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); +#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC +extern int fdatasync(int fildes); #endif -#if !HAVE_DECL_VSNPRINTF -extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args); +#ifdef HAVE_LONG_LONG_INT +/* Older platforms may provide strto[u]ll functionality under other names */ +#if !defined(HAVE_STRTOLL) && defined(HAVE___STRTOLL) +#define strtoll __strtoll +#define HAVE_STRTOLL 1 +#endif + +#if !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ) +#define strtoll strtoq +#define HAVE_STRTOLL 1 +#endif + +#if !defined(HAVE_STRTOULL) && defined(HAVE___STRTOULL) +#define strtoull __strtoull +#define HAVE_STRTOULL 1 +#endif + +#if !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ) +#define strtoull strtouq +#define HAVE_STRTOULL 1 +#endif + +#if defined(HAVE_STRTOLL) && !HAVE_DECL_STRTOLL +extern long long strtoll(const char *str, char **endptr, int base); #endif +#if defined(HAVE_STRTOULL) && !HAVE_DECL_STRTOULL +extern unsigned long long strtoull(const char *str, char **endptr, int base); +#endif +#endif /* HAVE_LONG_LONG_INT */ + #if !defined(HAVE_MEMMOVE) && !defined(memmove) #define memmove(d, s, c) bcopy(s, d, c) #endif @@ -1132,22 +1270,6 @@ extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args); #define siglongjmp longjmp #endif -#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC -extern int fdatasync(int fildes); -#endif - -/* If strtoq() exists, rename it to the more standard strtoll() */ -#if defined(HAVE_LONG_LONG_INT_64) && !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ) -#define strtoll strtoq -#define HAVE_STRTOLL 1 -#endif - -/* If strtouq() exists, rename it to the more standard strtoull() */ -#if defined(HAVE_LONG_LONG_INT_64) && !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ) -#define strtoull strtouq -#define HAVE_STRTOULL 1 -#endif - /* EXEC_BACKEND defines */ #ifdef EXEC_BACKEND #define NON_EXEC_STATIC diff --git a/src/include/catalog/Makefile b/src/include/catalog/Makefile index 1da3ea7f441..33fbcf7677f 100644 --- a/src/include/catalog/Makefile +++ b/src/include/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/include/catalog # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/Makefile @@ -13,19 +13,16 @@ subdir = src/include/catalog top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -# location of Catalog.pm -catalogdir = $(top_srcdir)/src/backend/catalog - # 'make reformat-dat-files' is a convenience target for rewriting the # catalog data files in our standard format. This includes collapsing # out any entries that are redundant with a BKI_DEFAULT annotation. reformat-dat-files: - $(PERL) -I $(catalogdir) reformat_dat_file.pl pg_*.dat + $(PERL) $(srcdir)/reformat_dat_file.pl --output $(srcdir) $(srcdir)/pg_*.dat # 'make expand-dat-files' is a convenience target for expanding out all # default values in the catalog data files. This should be run before # altering or removing any BKI_DEFAULT annotation. expand-dat-files: - $(PERL) -I $(catalogdir) reformat_dat_file.pl pg_*.dat --full-tuples + $(PERL) $(srcdir)/reformat_dat_file.pl --output $(srcdir) $(srcdir)/pg_*.dat --full-tuples .PHONY: reformat-dat-files expand-dat-files diff --git a/src/include/catalog/binary_upgrade.h b/src/include/catalog/binary_upgrade.h index abc6e1ae1da..2927b7a4d3c 100644 --- a/src/include/catalog/binary_upgrade.h +++ b/src/include/catalog/binary_upgrade.h @@ -4,7 +4,7 @@ * variables used for binary upgrades * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/binary_upgrade.h diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index 197e77f7f4f..0e8542d8222 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -4,7 +4,7 @@ * prototypes for functions in backend/catalog/catalog.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/catalog.h @@ -24,19 +24,19 @@ extern bool IsCatalogRelation(Relation relation); extern bool IsSystemClass(Oid relid, Form_pg_class reltuple); extern bool IsToastClass(Form_pg_class reltuple); -extern bool IsCatalogClass(Oid relid, Form_pg_class reltuple); -extern bool IsSystemNamespace(Oid namespaceId); +extern bool IsCatalogRelationOid(Oid relid); + +extern bool IsCatalogNamespace(Oid namespaceId); extern bool IsToastNamespace(Oid namespaceId); extern bool IsReservedName(const char *name); extern bool IsSharedRelation(Oid relationId); -extern Oid GetNewOid(Relation relation); -extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, - AttrNumber oidcolumn); -extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, - char relpersistence); +extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, + AttrNumber oidcolumn); +extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class, + char relpersistence); #endif /* CATALOG_H */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index acd6791563b..c689b8fd0b2 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -25,8 +25,8 @@ * * The rule for developers is: if you commit a change that requires * an initdb, you should update the catalog version number (as well as - * notifying the pghackers mailing list, which has been the informal - * practice for a long time). + * notifying the pgsql-hackers mailing list, which has been the + * informal practice for a long time). * * The catalog version number is placed here since modifying files in * include/catalog is the most common kind of initdb-forcing change. @@ -34,7 +34,7 @@ * database contents or layout, such as altering tuple headers. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201804091 +#define CATALOG_VERSION_NO 201909251 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 46c271a46c6..ff50d594f69 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -4,7 +4,7 @@ * Routines to support inter-object dependencies. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/dependency.h @@ -24,64 +24,8 @@ * * In all cases, a dependency relationship indicates that the referenced * object may not be dropped without also dropping the dependent object. - * However, there are several subflavors: - * - * DEPENDENCY_NORMAL ('n'): normal relationship between separately-created - * objects. The dependent object may be dropped without affecting the - * referenced object. The referenced object may only be dropped by - * specifying CASCADE, in which case the dependent object is dropped too. - * Example: a table column has a normal dependency on its datatype. - * - * DEPENDENCY_AUTO ('a'): the dependent object can be dropped separately - * from the referenced object, and should be automatically dropped - * (regardless of RESTRICT or CASCADE mode) if the referenced object - * is dropped. - * Example: a named constraint on a table is made auto-dependent on - * the table, so that it will go away if the table is dropped. - * - * DEPENDENCY_INTERNAL ('i'): the dependent object was created as part - * of creation of the referenced object, and is really just a part of - * its internal implementation. A DROP of the dependent object will be - * disallowed outright (we'll tell the user to issue a DROP against the - * referenced object, instead). A DROP of the referenced object will be - * propagated through to drop the dependent object whether CASCADE is - * specified or not. - * Example: a trigger that's created to enforce a foreign-key constraint - * is made internally dependent on the constraint's pg_constraint entry. - * - * DEPENDENCY_INTERNAL_AUTO ('I'): the dependent object was created as - * part of creation of the referenced object, and is really just a part - * of its internal implementation. A DROP of the dependent object will - * be disallowed outright (we'll tell the user to issue a DROP against the - * referenced object, instead). While a regular internal dependency will - * prevent the dependent object from being dropped while any such - * dependencies remain, DEPENDENCY_INTERNAL_AUTO will allow such a drop as - * long as the object can be found by following any of such dependencies. - * Example: an index on a partition is made internal-auto-dependent on - * both the partition itself as well as on the index on the parent - * partitioned table; so the partition index is dropped together with - * either the partition it indexes, or with the parent index it is attached - * to. - - * DEPENDENCY_EXTENSION ('e'): the dependent object is a member of the - * extension that is the referenced object. The dependent object can be - * dropped only via DROP EXTENSION on the referenced object. Functionally - * this dependency type acts the same as an internal dependency, but it's - * kept separate for clarity and to simplify pg_dump. - * - * DEPENDENCY_AUTO_EXTENSION ('x'): the dependent object is not a member - * of the extension that is the referenced object (and so should not be - * ignored by pg_dump), but cannot function without the extension and - * should be dropped when the extension itself is. The dependent object - * may be dropped on its own as well. - * - * DEPENDENCY_PIN ('p'): there is no dependent object; this type of entry - * is a signal that the system itself depends on the referenced object, - * and so that object must never be deleted. Entries of this type are - * created only during initdb. The fields for the dependent object - * contain zeroes. - * - * Other dependency flavors may be needed in future. + * However, there are several subflavors; see the description of pg_depend + * in catalogs.sgml for details. */ typedef enum DependencyType @@ -89,7 +33,8 @@ typedef enum DependencyType DEPENDENCY_NORMAL = 'n', DEPENDENCY_AUTO = 'a', DEPENDENCY_INTERNAL = 'i', - DEPENDENCY_INTERNAL_AUTO = 'I', + DEPENDENCY_PARTITION_PRI = 'P', + DEPENDENCY_PARTITION_SEC = 'S', DEPENDENCY_EXTENSION = 'e', DEPENDENCY_AUTO_EXTENSION = 'x', DEPENDENCY_PIN = 'p' @@ -191,97 +136,109 @@ typedef enum ObjectClass #define PERFORM_DELETION_QUIETLY 0x0004 /* suppress notices */ #define PERFORM_DELETION_SKIP_ORIGINAL 0x0008 /* keep original obj */ #define PERFORM_DELETION_SKIP_EXTENSIONS 0x0010 /* keep extensions */ +#define PERFORM_DELETION_CONCURRENT_LOCK 0x0020 /* normal drop with + * concurrent lock mode */ /* in dependency.c */ extern void performDeletion(const ObjectAddress *object, - DropBehavior behavior, int flags); + DropBehavior behavior, int flags); extern void performMultipleDeletions(const ObjectAddresses *objects, - DropBehavior behavior, int flags); + DropBehavior behavior, int flags); extern void recordDependencyOnExpr(const ObjectAddress *depender, - Node *expr, List *rtable, - DependencyType behavior); + Node *expr, List *rtable, + DependencyType behavior); extern void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, - Node *expr, Oid relId, - DependencyType behavior, - DependencyType self_behavior, - bool ignore_self); + Node *expr, Oid relId, + DependencyType behavior, + DependencyType self_behavior, + bool reverse_self); extern ObjectClass getObjectClass(const ObjectAddress *object); extern ObjectAddresses *new_object_addresses(void); extern void add_exact_object_address(const ObjectAddress *object, - ObjectAddresses *addrs); + ObjectAddresses *addrs); extern bool object_address_present(const ObjectAddress *object, - const ObjectAddresses *addrs); + const ObjectAddresses *addrs); extern void record_object_address_dependencies(const ObjectAddress *depender, - ObjectAddresses *referenced, - DependencyType behavior); + ObjectAddresses *referenced, + DependencyType behavior); + +extern void sort_object_addresses(ObjectAddresses *addrs); extern void free_object_addresses(ObjectAddresses *addrs); /* in pg_depend.c */ extern void recordDependencyOn(const ObjectAddress *depender, - const ObjectAddress *referenced, - DependencyType behavior); + const ObjectAddress *referenced, + DependencyType behavior); extern void recordMultipleDependencies(const ObjectAddress *depender, - const ObjectAddress *referenced, - int nreferenced, - DependencyType behavior); + const ObjectAddress *referenced, + int nreferenced, + DependencyType behavior); extern void recordDependencyOnCurrentExtension(const ObjectAddress *object, - bool isReplace); + bool isReplace); extern long deleteDependencyRecordsFor(Oid classId, Oid objectId, - bool skipExtensionDeps); + bool skipExtensionDeps); extern long deleteDependencyRecordsForClass(Oid classId, Oid objectId, - Oid refclassId, char deptype); + Oid refclassId, char deptype); extern long changeDependencyFor(Oid classId, Oid objectId, - Oid refClassId, Oid oldRefObjectId, - Oid newRefObjectId); + Oid refClassId, Oid oldRefObjectId, + Oid newRefObjectId); + +extern long changeDependenciesOf(Oid classId, Oid oldObjectId, + Oid newObjectId); + +extern long changeDependenciesOn(Oid refClassId, Oid oldRefObjectId, + Oid newRefObjectId); extern Oid getExtensionOfObject(Oid classId, Oid objectId); extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId); -extern List *getOwnedSequences(Oid relid, AttrNumber attnum); -extern Oid getOwnedSequence(Oid relid, AttrNumber attnum); +extern List *getOwnedSequences(Oid relid); +extern Oid getIdentitySequence(Oid relid, AttrNumber attnum, bool missing_ok); extern Oid get_constraint_index(Oid constraintId); extern Oid get_index_constraint(Oid indexId); +extern List *get_index_ref_constraints(Oid indexId); + /* in pg_shdepend.c */ extern void recordSharedDependencyOn(ObjectAddress *depender, - ObjectAddress *referenced, - SharedDependencyType deptype); + ObjectAddress *referenced, + SharedDependencyType deptype); extern void deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, - int32 objectSubId); + int32 objectSubId); extern void recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner); extern void changeDependencyOnOwner(Oid classId, Oid objectId, - Oid newOwnerId); + Oid newOwnerId); extern void updateAclDependencies(Oid classId, Oid objectId, int32 objectSubId, - Oid ownerId, - int noldmembers, Oid *oldmembers, - int nnewmembers, Oid *newmembers); + Oid ownerId, + int noldmembers, Oid *oldmembers, + int nnewmembers, Oid *newmembers); extern bool checkSharedDependencies(Oid classId, Oid objectId, - char **detail_msg, char **detail_log_msg); + char **detail_msg, char **detail_log_msg); extern void shdepLockAndCheckObject(Oid classId, Oid objectId); diff --git a/src/include/catalog/duplicate_oids b/src/include/catalog/duplicate_oids index 8c143cf06f0..25724a4e3e0 100755 --- a/src/include/catalog/duplicate_oids +++ b/src/include/catalog/duplicate_oids @@ -1,27 +1,40 @@ #!/usr/bin/perl +#---------------------------------------------------------------------- +# +# duplicate_oids +# Identifies any manually-assigned OIDs that are used multiple times +# in the Postgres catalog data. +# +# While duplicate OIDs would only cause a failure if they appear in +# the same catalog, our project policy is that manually assigned OIDs +# should be globally unique, to avoid confusion. +# +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/include/catalog/duplicate_oids +# +#---------------------------------------------------------------------- use strict; use warnings; -BEGIN -{ - @ARGV = (glob("pg_*.h"), glob("pg_*.dat"), qw(indexing.h toasting.h)); -} +# Must run in src/include/catalog +use FindBin; +chdir $FindBin::RealBin or die "could not cd to $FindBin::RealBin: $!\n"; + +use lib "$FindBin::RealBin/../../backend/catalog/"; +use Catalog; + +my @input_files = (glob("pg_*.h"), qw(indexing.h toasting.h)); + +my $oids = Catalog::FindAllOidsFromHeaders(@input_files); my %oidcounts; -while (<>) +foreach my $oid (@{$oids}) { - next if /^CATALOG\(.*BKI_BOOTSTRAP/; - next - unless /\boid *=> *'(\d+)'/ - || /^CATALOG\([^,]*, *(\d+).*BKI_ROWTYPE_OID\((\d+),/ - || /^CATALOG\([^,]*, *(\d+)/ - || /^DECLARE_INDEX\([^,]*, *(\d+)/ - || /^DECLARE_UNIQUE_INDEX\([^,]*, *(\d+)/ - || /^DECLARE_TOAST\([^,]*, *(\d+), *(\d+)/; - $oidcounts{$1}++; - $oidcounts{$2}++ if $2; + $oidcounts{$oid}++; } my $found = 0; diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h index b1e2cbdb629..1b8e4e9e194 100644 --- a/src/include/catalog/genbki.h +++ b/src/include/catalog/genbki.h @@ -9,7 +9,7 @@ * bootstrap file from these header files.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/genbki.h @@ -25,7 +25,6 @@ /* Options that may appear after CATALOG (on the same line) */ #define BKI_BOOTSTRAP #define BKI_SHARED_RELATION -#define BKI_WITHOUT_OIDS #define BKI_ROWTYPE_OID(oid,oidmacro) #define BKI_SCHEMA_MACRO @@ -34,7 +33,12 @@ #define BKI_FORCE_NOT_NULL /* Specifies a default value for a catalog field */ #define BKI_DEFAULT(value) -/* Indicates how to perform name lookups for an OID or OID-array field */ +/* Specifies a default value for auto-generated array types */ +#define BKI_ARRAY_DEFAULT(value) +/* + * Indicates how to perform name lookups, typically for an OID or + * OID-array field + */ #define BKI_LOOKUP(catalog) /* The following are never defined; they are here only for documentation. */ diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h index 59fc0524947..eec71c29d5b 100644 --- a/src/include/catalog/heap.h +++ b/src/include/catalog/heap.h @@ -4,7 +4,7 @@ * prototypes for functions in backend/catalog/heap.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/heap.h @@ -19,11 +19,16 @@ #include "parser/parse_node.h" +/* flag bits for CheckAttributeType/CheckAttributeNamesTypes */ +#define CHKATYPE_ANYARRAY 0x01 /* allow ANYARRAY */ +#define CHKATYPE_ANYRECORD 0x02 /* allow RECORD and RECORD[] */ + typedef struct RawColumnDefault { AttrNumber attnum; /* attribute to attach default to */ Node *raw_default; /* default value (untransformed parse tree) */ bool missingMode; /* true if part of add column processing */ + char generated; /* attgenerated setting */ } RawColumnDefault; typedef struct CookedConstraint @@ -41,41 +46,41 @@ typedef struct CookedConstraint } CookedConstraint; extern Relation heap_create(const char *relname, - Oid relnamespace, - Oid reltablespace, - Oid relid, - Oid relfilenode, - TupleDesc tupDesc, - char relkind, - char relpersistence, - bool shared_relation, - bool mapped_relation, - bool allow_system_table_mods); - -extern Oid heap_create_with_catalog(const char *relname, - Oid relnamespace, - Oid reltablespace, - Oid relid, - Oid reltypeid, - Oid reloftypeid, - Oid ownerid, - TupleDesc tupdesc, - List *cooked_constraints, - char relkind, - char relpersistence, - bool shared_relation, - bool mapped_relation, - bool oidislocal, - int oidinhcount, - OnCommitAction oncommit, - Datum reloptions, - bool use_user_acl, - bool allow_system_table_mods, - bool is_internal, - Oid relrewrite, - ObjectAddress *typaddress); - -extern void heap_create_init_fork(Relation rel); + Oid relnamespace, + Oid reltablespace, + Oid relid, + Oid relfilenode, + Oid accessmtd, + TupleDesc tupDesc, + char relkind, + char relpersistence, + bool shared_relation, + bool mapped_relation, + bool allow_system_table_mods, + TransactionId *relfrozenxid, + MultiXactId *relminmxid); + +extern Oid heap_create_with_catalog(const char *relname, + Oid relnamespace, + Oid reltablespace, + Oid relid, + Oid reltypeid, + Oid reloftypeid, + Oid ownerid, + Oid accessmtd, + TupleDesc tupdesc, + List *cooked_constraints, + char relkind, + char relpersistence, + bool shared_relation, + bool mapped_relation, + OnCommitAction oncommit, + Datum reloptions, + bool use_user_acl, + bool allow_system_table_mods, + bool is_internal, + Oid relrewrite, + ObjectAddress *typaddress); extern void heap_drop_with_catalog(Oid relid); @@ -88,67 +93,68 @@ extern void heap_truncate_check_FKs(List *relations, bool tempTables); extern List *heap_truncate_find_FKs(List *relationIds); extern void InsertPgAttributeTuple(Relation pg_attribute_rel, - Form_pg_attribute new_attribute, - CatalogIndexState indstate); + Form_pg_attribute new_attribute, + CatalogIndexState indstate); extern void InsertPgClassTuple(Relation pg_class_desc, - Relation new_rel_desc, - Oid new_rel_oid, - Datum relacl, - Datum reloptions); + Relation new_rel_desc, + Oid new_rel_oid, + Datum relacl, + Datum reloptions); extern List *AddRelationNewConstraints(Relation rel, - List *newColDefaults, - List *newConstraints, - bool allow_merge, - bool is_local, - bool is_internal); + List *newColDefaults, + List *newConstraints, + bool allow_merge, + bool is_local, + bool is_internal, + const char *queryString); extern void RelationClearMissing(Relation rel); +extern void SetAttrMissing(Oid relid, char *attname, char *value); -extern Oid StoreAttrDefault(Relation rel, AttrNumber attnum, - Node *expr, bool is_internal, - bool add_column_mode); +extern Oid StoreAttrDefault(Relation rel, AttrNumber attnum, + Node *expr, bool is_internal, + bool add_column_mode); extern Node *cookDefault(ParseState *pstate, - Node *raw_default, - Oid atttypid, - int32 atttypmod, - const char *attname); + Node *raw_default, + Oid atttypid, + int32 atttypmod, + const char *attname, + char attgenerated); extern void DeleteRelationTuple(Oid relid); extern void DeleteAttributeTuples(Oid relid); extern void DeleteSystemAttributeTuples(Oid relid); extern void RemoveAttributeById(Oid relid, AttrNumber attnum); extern void RemoveAttrDefault(Oid relid, AttrNumber attnum, - DropBehavior behavior, bool complain, bool internal); + DropBehavior behavior, bool complain, bool internal); extern void RemoveAttrDefaultById(Oid attrdefId); extern void RemoveStatistics(Oid relid, AttrNumber attnum); -extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno, - bool relhasoids); +extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno); -extern Form_pg_attribute SystemAttributeByName(const char *attname, - bool relhasoids); +extern const FormData_pg_attribute *SystemAttributeByName(const char *attname); extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind, - bool allow_system_table_mods); + int flags); extern void CheckAttributeType(const char *attname, - Oid atttypid, Oid attcollation, - List *containing_rowtypes, - bool allow_system_table_mods); + Oid atttypid, Oid attcollation, + List *containing_rowtypes, + int flags); /* pg_partitioned_table catalog manipulation functions */ extern void StorePartitionKey(Relation rel, - char strategy, - int16 partnatts, - AttrNumber *partattrs, - List *partexprs, - Oid *partopclass, - Oid *partcollation); + char strategy, + int16 partnatts, + AttrNumber *partattrs, + List *partexprs, + Oid *partopclass, + Oid *partcollation); extern void RemovePartitionKeyByRelId(Oid relid); extern void StorePartitionBound(Relation rel, Relation parent, - PartitionBoundSpec *bound); + PartitionBoundSpec *bound); #endif /* HEAP_H */ diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index f20c5f789b1..1113d25b2d8 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -4,7 +4,7 @@ * prototypes for catalog/index.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/index.h @@ -20,14 +20,6 @@ #define DEFAULT_INDEX_TYPE "btree" -/* Typedef for callback function for IndexBuildHeapScan */ -typedef void (*IndexBuildCallback) (Relation index, - HeapTuple htup, - Datum *values, - bool *isnull, - bool tupleIsAlive, - void *state); - /* Action code for index_set_state_flags */ typedef enum { @@ -37,10 +29,20 @@ typedef enum INDEX_DROP_SET_DEAD } IndexStateFlagsAction; +/* state info for validate_index bulkdelete callback */ +typedef struct ValidateIndexState +{ + Tuplesortstate *tuplesort; /* for sorting the index TIDs */ + /* statistics (for debug purposes only): */ + double htups, + itups, + tups_inserted; +} ValidateIndexState; extern void index_check_primary_key(Relation heapRel, - IndexInfo *indexInfo, - bool is_alter_table); + IndexInfo *indexInfo, + bool is_alter_table, + IndexStmt *stmt); #define INDEX_CREATE_IS_PRIMARY (1 << 0) #define INDEX_CREATE_ADD_CONSTRAINT (1 << 1) @@ -50,25 +52,25 @@ extern void index_check_primary_key(Relation heapRel, #define INDEX_CREATE_PARTITIONED (1 << 5) #define INDEX_CREATE_INVALID (1 << 6) -extern Oid index_create(Relation heapRelation, - const char *indexRelationName, - Oid indexRelationId, - Oid parentIndexRelid, - Oid parentConstraintId, - Oid relFileNode, - IndexInfo *indexInfo, - List *indexColNames, - Oid accessMethodObjectId, - Oid tableSpaceId, - Oid *collationObjectId, - Oid *classObjectId, - int16 *coloptions, - Datum reloptions, - bits16 flags, - bits16 constr_flags, - bool allow_system_table_mods, - bool is_internal, - Oid *constraintId); +extern Oid index_create(Relation heapRelation, + const char *indexRelationName, + Oid indexRelationId, + Oid parentIndexRelid, + Oid parentConstraintId, + Oid relFileNode, + IndexInfo *indexInfo, + List *indexColNames, + Oid accessMethodObjectId, + Oid tableSpaceId, + Oid *collationObjectId, + Oid *classObjectId, + int16 *coloptions, + Datum reloptions, + bits16 flags, + bits16 constr_flags, + bool allow_system_table_mods, + bool is_internal, + Oid *constraintId); #define INDEX_CONSTR_CREATE_MARK_AS_PRIMARY (1 << 0) #define INDEX_CONSTR_CREATE_DEFERRABLE (1 << 1) @@ -76,64 +78,59 @@ extern Oid index_create(Relation heapRelation, #define INDEX_CONSTR_CREATE_UPDATE_INDEX (1 << 3) #define INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS (1 << 4) +extern Oid index_concurrently_create_copy(Relation heapRelation, + Oid oldIndexId, + const char *newName); + +extern void index_concurrently_build(Oid heapRelationId, + Oid indexRelationId); + +extern void index_concurrently_swap(Oid newIndexId, + Oid oldIndexId, + const char *oldName); + +extern void index_concurrently_set_dead(Oid heapId, + Oid indexId); + extern ObjectAddress index_constraint_create(Relation heapRelation, - Oid indexRelationId, - Oid parentConstraintId, - IndexInfo *indexInfo, - const char *constraintName, - char constraintType, - bits16 constr_flags, - bool allow_system_table_mods, - bool is_internal); + Oid indexRelationId, + Oid parentConstraintId, + IndexInfo *indexInfo, + const char *constraintName, + char constraintType, + bits16 constr_flags, + bool allow_system_table_mods, + bool is_internal); -extern void index_drop(Oid indexId, bool concurrent); +extern void index_drop(Oid indexId, bool concurrent, bool concurrent_lock_mode); extern IndexInfo *BuildIndexInfo(Relation index); extern bool CompareIndexInfo(IndexInfo *info1, IndexInfo *info2, - Oid *collations1, Oid *collations2, - Oid *opfamilies1, Oid *opfamilies2, - AttrNumber *attmap, int maplen); + Oid *collations1, Oid *collations2, + Oid *opfamilies1, Oid *opfamilies2, + AttrNumber *attmap, int maplen); extern void BuildSpeculativeIndexInfo(Relation index, IndexInfo *ii); extern void FormIndexDatum(IndexInfo *indexInfo, - TupleTableSlot *slot, - EState *estate, - Datum *values, - bool *isnull); + TupleTableSlot *slot, + EState *estate, + Datum *values, + bool *isnull); extern void index_build(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool isprimary, - bool isreindex, - bool parallel); - -extern double IndexBuildHeapScan(Relation heapRelation, - Relation indexRelation, - IndexInfo *indexInfo, - bool allow_sync, - IndexBuildCallback callback, - void *callback_state, - HeapScanDesc scan); -extern double IndexBuildHeapRangeScan(Relation heapRelation, Relation indexRelation, IndexInfo *indexInfo, - bool allow_sync, - bool anyvisible, - BlockNumber start_blockno, - BlockNumber end_blockno, - IndexBuildCallback callback, - void *callback_state, - HeapScanDesc scan); + bool isreindex, + bool parallel); extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot); extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action); extern void reindex_index(Oid indexId, bool skip_constraint_checks, - char relpersistence, int options); + char relpersistence, int options); /* Flag bits for reindex_relation(): */ #define REINDEX_REL_PROCESS_TOAST 0x01 @@ -154,4 +151,45 @@ extern void RestoreReindexState(void *reindexstate); extern void IndexSetParentIndex(Relation idx, Oid parentOid); + +/* + * itemptr_encode - Encode ItemPointer as int64/int8 + * + * This representation must produce values encoded as int64 that sort in the + * same order as their corresponding original TID values would (using the + * default int8 opclass to produce a result equivalent to the default TID + * opclass). + * + * As noted in validate_index(), this can be significantly faster. + */ +static inline int64 +itemptr_encode(ItemPointer itemptr) +{ + BlockNumber block = ItemPointerGetBlockNumber(itemptr); + OffsetNumber offset = ItemPointerGetOffsetNumber(itemptr); + int64 encoded; + + /* + * Use the 16 least significant bits for the offset. 32 adjacent bits are + * used for the block number. Since remaining bits are unused, there + * cannot be negative encoded values (We assume a two's complement + * representation). + */ + encoded = ((uint64) block << 16) | (uint16) offset; + + return encoded; +} + +/* + * itemptr_decode - Decode int64/int8 representation back to ItemPointer + */ +static inline void +itemptr_decode(ItemPointer itemptr, int64 encoded) +{ + BlockNumber block = (BlockNumber) (encoded >> 16); + OffsetNumber offset = (OffsetNumber) (encoded & 0xFFFF); + + ItemPointerSet(itemptr, block, offset); +} + #endif /* INDEX_H */ diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 42499e235f2..ef4445b017a 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -4,8 +4,11 @@ * This file provides some definitions to support indexing * on system catalogs * + * Caution: all #define's with numeric values in this file had better be + * object OIDs, else renumber_oids.pl might change them inappropriately. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/indexing.h @@ -30,14 +33,14 @@ typedef struct ResultRelInfo *CatalogIndexState; */ extern CatalogIndexState CatalogOpenIndexes(Relation heapRel); extern void CatalogCloseIndexes(CatalogIndexState indstate); -extern Oid CatalogTupleInsert(Relation heapRel, HeapTuple tup); -extern Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, - CatalogIndexState indstate); +extern void CatalogTupleInsert(Relation heapRel, HeapTuple tup); +extern void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, + CatalogIndexState indstate); extern void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, - HeapTuple tup); + HeapTuple tup); extern void CatalogTupleUpdateWithInfo(Relation heapRel, - ItemPointer otid, HeapTuple tup, - CatalogIndexState indstate); + ItemPointer otid, HeapTuple tup, + CatalogIndexState indstate); extern void CatalogTupleDelete(Relation heapRel, ItemPointer tid); @@ -47,7 +50,6 @@ extern void CatalogTupleDelete(Relation heapRel, ItemPointer tid); */ #define DECLARE_INDEX(name,oid,decl) extern int no_such_variable #define DECLARE_UNIQUE_INDEX(name,oid,decl) extern int no_such_variable -#define BUILD_INDICES /* @@ -122,8 +124,8 @@ DECLARE_UNIQUE_INDEX(pg_collation_oid_index, 3085, on pg_collation using btree(o DECLARE_INDEX(pg_constraint_conname_nsp_index, 2664, on pg_constraint using btree(conname name_ops, connamespace oid_ops)); #define ConstraintNameNspIndexId 2664 -DECLARE_INDEX(pg_constraint_conrelid_index, 2665, on pg_constraint using btree(conrelid oid_ops)); -#define ConstraintRelidIndexId 2665 +DECLARE_UNIQUE_INDEX(pg_constraint_conrelid_contypid_conname_index, 2665, on pg_constraint using btree(conrelid oid_ops, contypid oid_ops, conname name_ops)); +#define ConstraintRelidTypidNameIndexId 2665 DECLARE_INDEX(pg_constraint_contypid_index, 2666, on pg_constraint using btree(contypid oid_ops)); #define ConstraintTypidIndexId 2666 DECLARE_UNIQUE_INDEX(pg_constraint_oid_index, 2667, on pg_constraint using btree(oid oid_ops)); @@ -184,13 +186,6 @@ DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index, 2683, on pg_largeobject using DECLARE_UNIQUE_INDEX(pg_largeobject_metadata_oid_index, 2996, on pg_largeobject_metadata using btree(oid oid_ops)); #define LargeObjectMetadataOidIndexId 2996 -DECLARE_UNIQUE_INDEX(pg_statistic_ext_oid_index, 3380, on pg_statistic_ext using btree(oid oid_ops)); -#define StatisticExtOidIndexId 3380 -DECLARE_UNIQUE_INDEX(pg_statistic_ext_name_index, 3997, on pg_statistic_ext using btree(stxname name_ops, stxnamespace oid_ops)); -#define StatisticExtNameIndexId 3997 -DECLARE_INDEX(pg_statistic_ext_relid_index, 3379, on pg_statistic_ext using btree(stxrelid oid_ops)); -#define StatisticExtRelidIndexId 3379 - DECLARE_UNIQUE_INDEX(pg_namespace_nspname_index, 2684, on pg_namespace using btree(nspname name_ops)); #define NamespaceNameIndexId 2684 DECLARE_UNIQUE_INDEX(pg_namespace_oid_index, 2685, on pg_namespace using btree(oid oid_ops)); @@ -235,6 +230,16 @@ DECLARE_INDEX(pg_shdepend_reference_index, 1233, on pg_shdepend using btree(refc DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_inh_index, 2696, on pg_statistic using btree(starelid oid_ops, staattnum int2_ops, stainherit bool_ops)); #define StatisticRelidAttnumInhIndexId 2696 +DECLARE_UNIQUE_INDEX(pg_statistic_ext_oid_index, 3380, on pg_statistic_ext using btree(oid oid_ops)); +#define StatisticExtOidIndexId 3380 +DECLARE_UNIQUE_INDEX(pg_statistic_ext_name_index, 3997, on pg_statistic_ext using btree(stxname name_ops, stxnamespace oid_ops)); +#define StatisticExtNameIndexId 3997 +DECLARE_INDEX(pg_statistic_ext_relid_index, 3379, on pg_statistic_ext using btree(stxrelid oid_ops)); +#define StatisticExtRelidIndexId 3379 + +DECLARE_UNIQUE_INDEX(pg_statistic_ext_data_stxoid_index, 3433, on pg_statistic_ext_data using btree(stxoid oid_ops)); +#define StatisticExtDataStxoidIndexId 3433 + DECLARE_UNIQUE_INDEX(pg_tablespace_oid_index, 2697, on pg_tablespace using btree(oid oid_ops)); #define TablespaceOidIndexId 2697 DECLARE_UNIQUE_INDEX(pg_tablespace_spcname_index, 2698, on pg_tablespace using btree(spcname name_ops)); @@ -311,10 +316,10 @@ DECLARE_UNIQUE_INDEX(pg_default_acl_oid_index, 828, on pg_default_acl using btre DECLARE_UNIQUE_INDEX(pg_db_role_setting_databaseid_rol_index, 2965, on pg_db_role_setting using btree(setdatabase oid_ops, setrole oid_ops)); #define DbRoleSettingDatidRolidIndexId 2965 -DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_pattern_ops)); +DECLARE_UNIQUE_INDEX(pg_seclabel_object_index, 3597, on pg_seclabel using btree(objoid oid_ops, classoid oid_ops, objsubid int4_ops, provider text_ops)); #define SecLabelObjectIndexId 3597 -DECLARE_UNIQUE_INDEX(pg_shseclabel_object_index, 3593, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_pattern_ops)); +DECLARE_UNIQUE_INDEX(pg_shseclabel_object_index, 3593, on pg_shseclabel using btree(objoid oid_ops, classoid oid_ops, provider text_ops)); #define SharedSecLabelObjectIndexId 3593 DECLARE_UNIQUE_INDEX(pg_extension_oid_index, 3080, on pg_extension using btree(oid oid_ops)); @@ -334,7 +339,7 @@ DECLARE_UNIQUE_INDEX(pg_policy_polrelid_polname_index, 3258, on pg_policy using DECLARE_UNIQUE_INDEX(pg_replication_origin_roiident_index, 6001, on pg_replication_origin using btree(roident oid_ops)); #define ReplicationOriginIdentIndex 6001 -DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication_origin using btree(roname text_pattern_ops)); +DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication_origin using btree(roname text_ops)); #define ReplicationOriginNameIndex 6002 DECLARE_UNIQUE_INDEX(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops)); @@ -361,7 +366,4 @@ DECLARE_UNIQUE_INDEX(pg_subscription_subname_index, 6115, on pg_subscription usi DECLARE_UNIQUE_INDEX(pg_subscription_rel_srrelid_srsubid_index, 6117, on pg_subscription_rel using btree(srrelid oid_ops, srsubid oid_ops)); #define SubscriptionRelSrrelidSrsubidIndexId 6117 -/* last step of initialization script: build the indexes declared above */ -BUILD_INDICES - #endif /* INDEXING_H */ diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 7991de5e210..edb98842fcf 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -4,7 +4,7 @@ * prototypes for functions in backend/catalog/namespace.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/namespace.h @@ -64,31 +64,32 @@ typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, RangeVarGetRelidExtended(relation, lockmode, \ (missing_ok) ? RVR_MISSING_OK : 0, NULL, NULL) -extern Oid RangeVarGetRelidExtended(const RangeVar *relation, - LOCKMODE lockmode, uint32 flags, - RangeVarGetRelidCallback callback, - void *callback_arg); +extern Oid RangeVarGetRelidExtended(const RangeVar *relation, + LOCKMODE lockmode, uint32 flags, + RangeVarGetRelidCallback callback, + void *callback_arg); extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); -extern Oid RangeVarGetAndCheckCreationNamespace(RangeVar *newRelation, - LOCKMODE lockmode, - Oid *existing_relation_id); +extern Oid RangeVarGetAndCheckCreationNamespace(RangeVar *newRelation, + LOCKMODE lockmode, + Oid *existing_relation_id); extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid); extern Oid RelnameGetRelid(const char *relname); extern bool RelationIsVisible(Oid relid); extern Oid TypenameGetTypid(const char *typname); +extern Oid TypenameGetTypidExtended(const char *typname, bool temp_ok); extern bool TypeIsVisible(Oid typid); extern FuncCandidateList FuncnameGetCandidates(List *names, - int nargs, List *argnames, - bool expand_variadic, - bool expand_defaults, - bool missing_ok); + int nargs, List *argnames, + bool expand_variadic, + bool expand_defaults, + bool missing_ok); extern bool FunctionIsVisible(Oid funcid); extern Oid OpernameGetOprid(List *names, Oid oprleft, Oid oprright); extern FuncCandidateList OpernameGetCandidates(List *names, char oprkind, - bool missing_schema_ok); + bool missing_schema_ok); extern bool OperatorIsVisible(Oid oprid); extern Oid OpclassnameGetOpcid(Oid amid, const char *opcname); @@ -104,7 +105,7 @@ extern Oid ConversionGetConid(const char *conname); extern bool ConversionIsVisible(Oid conid); extern Oid get_statistics_object_oid(List *names, bool missing_ok); -extern bool StatisticsObjIsVisible(Oid stxid); +extern bool StatisticsObjIsVisible(Oid relid); extern Oid get_ts_parser_oid(List *names, bool missing_ok); extern bool TSParserIsVisible(Oid prsId); @@ -119,8 +120,8 @@ extern Oid get_ts_config_oid(List *names, bool missing_ok); extern bool TSConfigIsVisible(Oid cfgid); extern void DeconstructQualifiedName(List *names, - char **nspname_p, - char **objname_p); + char **nspname_p, + char **objname_p); extern Oid LookupNamespaceNoError(const char *nspname); extern Oid LookupExplicitNamespace(const char *nspname, bool missing_ok); extern Oid get_namespace_oid(const char *nspname, bool missing_ok); @@ -137,12 +138,13 @@ extern bool isTempToastNamespace(Oid namespaceId); extern bool isTempOrTempToastNamespace(Oid namespaceId); extern bool isAnyTempNamespace(Oid namespaceId); extern bool isOtherTempNamespace(Oid namespaceId); +extern bool isTempNamespaceInUse(Oid namespaceId); extern int GetTempNamespaceBackendId(Oid namespaceId); extern Oid GetTempToastNamespace(void); extern void GetTempNamespaceState(Oid *tempNamespaceId, - Oid *tempToastNamespaceId); + Oid *tempToastNamespaceId); extern void SetTempNamespaceState(Oid tempNamespaceId, - Oid tempToastNamespaceId); + Oid tempToastNamespaceId); extern void ResetTempTableNamespace(void); extern OverrideSearchPath *GetOverrideSearchPath(MemoryContext context); @@ -160,7 +162,7 @@ extern Oid FindDefaultConversionProc(int32 for_encoding, int32 to_encoding); extern void InitializeSearchPath(void); extern void AtEOXact_Namespace(bool isCommit, bool parallel); extern void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId parentSubid); /* stuff for search_path GUC variable */ extern char *namespace_search_path; diff --git a/src/include/catalog/objectaccess.h b/src/include/catalog/objectaccess.h index e46f5605fca..0170f1f1e41 100644 --- a/src/include/catalog/objectaccess.h +++ b/src/include/catalog/objectaccess.h @@ -3,7 +3,7 @@ * * Object access hooks. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ @@ -128,11 +128,11 @@ extern PGDLLIMPORT object_access_hook_type object_access_hook; /* Core code uses these functions to call the hook (see macros below). */ extern void RunObjectPostCreateHook(Oid classId, Oid objectId, int subId, - bool is_internal); + bool is_internal); extern void RunObjectDropHook(Oid classId, Oid objectId, int subId, - int dropflags); + int dropflags); extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId, - Oid auxiliaryId, bool is_internal); + Oid auxiliaryId, bool is_internal); extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation); extern void RunFunctionExecuteHook(Oid objectId); diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h index 6a9b1eec73f..7e61569f9fe 100644 --- a/src/include/catalog/objectaddress.h +++ b/src/include/catalog/objectaddress.h @@ -3,7 +3,7 @@ * objectaddress.h * functions for working with object addresses * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/objectaddress.h @@ -41,16 +41,16 @@ extern const ObjectAddress InvalidObjectAddress; ObjectAddressSubSet(addr, class_id, object_id, 0) extern ObjectAddress get_object_address(ObjectType objtype, Node *object, - Relation *relp, - LOCKMODE lockmode, bool missing_ok); + Relation *relp, + LOCKMODE lockmode, bool missing_ok); extern ObjectAddress get_object_address_rv(ObjectType objtype, RangeVar *rel, - List *object, Relation *relp, - LOCKMODE lockmode, bool missing_ok); + List *object, Relation *relp, + LOCKMODE lockmode, bool missing_ok); extern void check_object_ownership(Oid roleid, - ObjectType objtype, ObjectAddress address, - Node *object, Relation relation); + ObjectType objtype, ObjectAddress address, + Node *object, Relation relation); extern Oid get_object_namespace(const ObjectAddress *address); @@ -58,6 +58,7 @@ extern bool is_objectclass_supported(Oid class_id); extern Oid get_object_oid_index(Oid class_id); extern int get_object_catcache_oid(Oid class_id); extern int get_object_catcache_name(Oid class_id); +extern AttrNumber get_object_attnum_oid(Oid class_id); extern AttrNumber get_object_attnum_name(Oid class_id); extern AttrNumber get_object_attnum_namespace(Oid class_id); extern AttrNumber get_object_attnum_owner(Oid class_id); @@ -66,7 +67,7 @@ extern ObjectType get_object_type(Oid class_id, Oid object_id); extern bool get_object_namensp_unique(Oid class_id); extern HeapTuple get_catalog_object_by_oid(Relation catalog, - Oid objectId); + AttrNumber oidcol, Oid objectId); extern char *getObjectDescription(const ObjectAddress *object); extern char *getObjectDescriptionOids(Oid classid, Oid objid); @@ -75,8 +76,8 @@ extern int read_objtype_from_string(const char *objtype); extern char *getObjectTypeDescription(const ObjectAddress *object); extern char *getObjectIdentity(const ObjectAddress *address); extern char *getObjectIdentityParts(const ObjectAddress *address, - List **objname, List **objargs); -extern ArrayType *strlist_to_textarray(List *list); + List **objname, List **objargs); +extern struct ArrayType *strlist_to_textarray(List *list); extern ObjectType get_relkind_objtype(char relkind); diff --git a/src/include/catalog/opfam_internal.h b/src/include/catalog/opfam_internal.h index e9ac904c72e..9f17544ff02 100644 --- a/src/include/catalog/opfam_internal.h +++ b/src/include/catalog/opfam_internal.h @@ -2,7 +2,7 @@ * * opfam_internal.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/opfam_internal.h diff --git a/src/include/catalog/partition.h b/src/include/catalog/partition.h index b25e25bf9df..5c3565ce366 100644 --- a/src/include/catalog/partition.h +++ b/src/include/catalog/partition.h @@ -4,7 +4,7 @@ * Header file for structures and utility functions related to * partitioning * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/include/catalog/partition.h * @@ -13,64 +13,23 @@ #ifndef PARTITION_H #define PARTITION_H -#include "fmgr.h" -#include "executor/tuptable.h" -#include "nodes/execnodes.h" -#include "parser/parse_node.h" -#include "utils/rel.h" +#include "partitioning/partdefs.h" +#include "utils/relcache.h" /* Seed for the extended hash function */ #define HASH_PARTITION_SEED UINT64CONST(0x7A5B22367996DCFD) -/* - * PartitionBoundInfo encapsulates a set of partition bounds. It is usually - * associated with partitioned tables as part of its partition descriptor. - * - * The internal structure appears in partbounds.h. - */ -typedef struct PartitionBoundInfoData *PartitionBoundInfo; - -/* - * Information about partitions of a partitioned table. - */ -typedef struct PartitionDescData -{ - int nparts; /* Number of partitions */ - Oid *oids; /* OIDs of partitions */ - PartitionBoundInfo boundinfo; /* collection of partition bounds */ -} PartitionDescData; - -typedef struct PartitionDescData *PartitionDesc; - -extern void RelationBuildPartitionDesc(Relation relation); -extern bool partition_bounds_equal(int partnatts, int16 *parttyplen, - bool *parttypbyval, PartitionBoundInfo b1, - PartitionBoundInfo b2); -extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, - PartitionKey key); - -extern void check_new_partition_bound(char *relname, Relation parent, - PartitionBoundSpec *spec); extern Oid get_partition_parent(Oid relid); extern List *get_partition_ancestors(Oid relid); -extern List *get_qual_from_partbound(Relation rel, Relation parent, - PartitionBoundSpec *spec); +extern Oid index_get_partition(Relation partition, Oid indexId); extern List *map_partition_varattnos(List *expr, int fromrel_varno, - Relation to_rel, Relation from_rel, - bool *found_whole_row); -extern List *RelationGetPartitionQual(Relation rel); -extern Expr *get_partition_qual_relid(Oid relid); + Relation to_rel, Relation from_rel, + bool *found_whole_row); extern bool has_partition_attrs(Relation rel, Bitmapset *attnums, - bool *used_in_expr); + bool *used_in_expr); -extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc); extern Oid get_default_partition_oid(Oid parentId); extern void update_default_partition_oid(Oid parentId, Oid defaultPartId); -extern void check_default_allows_bound(Relation parent, Relation defaultRel, - PartitionBoundSpec *new_spec); -extern List *get_proposed_default_constraint(List *new_part_constaints); - -extern int get_partition_for_tuple(Relation relation, Datum *values, - bool *isnull); +extern List *get_proposed_default_constraint(List *new_part_constraints); #endif /* PARTITION_H */ diff --git a/src/include/catalog/pg_aggregate.dat b/src/include/catalog/pg_aggregate.dat index f8d20410efe..242d8433470 100644 --- a/src/include/catalog/pg_aggregate.dat +++ b/src/include/catalog/pg_aggregate.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_aggregate.dat -# Initial contents of the pg_aggregate system relation. +# Initial contents of the pg_aggregate system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_aggregate.dat @@ -104,9 +104,6 @@ { aggfnoid => 'max(float8)', aggtransfn => 'float8larger', aggcombinefn => 'float8larger', aggsortop => '>(float8,float8)', aggtranstype => 'float8' }, -{ aggfnoid => 'max(abstime)', aggtransfn => 'int4larger', - aggcombinefn => 'int4larger', aggsortop => '>(abstime,abstime)', - aggtranstype => 'abstime' }, { aggfnoid => 'max(date)', aggtransfn => 'date_larger', aggcombinefn => 'date_larger', aggsortop => '>(date,date)', aggtranstype => 'date' }, @@ -149,6 +146,9 @@ { aggfnoid => 'max(inet)', aggtransfn => 'network_larger', aggcombinefn => 'network_larger', aggsortop => '>(inet,inet)', aggtranstype => 'inet' }, +{ aggfnoid => 'max(pg_lsn)', aggtransfn => 'pg_lsn_larger', + aggcombinefn => 'pg_lsn_larger', aggsortop => '>(pg_lsn,pg_lsn)', + aggtranstype => 'pg_lsn' }, # min { aggfnoid => 'min(int8)', aggtransfn => 'int8smaller', @@ -169,9 +169,6 @@ { aggfnoid => 'min(float8)', aggtransfn => 'float8smaller', aggcombinefn => 'float8smaller', aggsortop => '<(float8,float8)', aggtranstype => 'float8' }, -{ aggfnoid => 'min(abstime)', aggtransfn => 'int4smaller', - aggcombinefn => 'int4smaller', aggsortop => '<(abstime,abstime)', - aggtranstype => 'abstime' }, { aggfnoid => 'min(date)', aggtransfn => 'date_smaller', aggcombinefn => 'date_smaller', aggsortop => '<(date,date)', aggtranstype => 'date' }, @@ -214,6 +211,9 @@ { aggfnoid => 'min(inet)', aggtransfn => 'network_smaller', aggcombinefn => 'network_smaller', aggsortop => '<(inet,inet)', aggtranstype => 'inet' }, +{ aggfnoid => 'min(pg_lsn)', aggtransfn => 'pg_lsn_smaller', + aggcombinefn => 'pg_lsn_smaller', aggsortop => '<(pg_lsn,pg_lsn)', + aggtranstype => 'pg_lsn' }, # count { aggfnoid => 'count(any)', aggtransfn => 'int8inc_any', diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h index 8eb5f63f56e..ff8a21daa8b 100644 --- a/src/include/catalog/pg_aggregate.h +++ b/src/include/catalog/pg_aggregate.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_aggregate.h - * definition of the system "aggregate" relation (pg_aggregate) + * definition of the "aggregate" system catalog (pg_aggregate) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_aggregate.h @@ -29,7 +29,7 @@ * cpp turns this into typedef struct FormData_pg_aggregate * ---------------------------------------------------------------- */ -CATALOG(pg_aggregate,2600,AggregateRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_aggregate,2600,AggregateRelationId) { /* pg_proc OID of the aggregate itself */ regproc aggfnoid BKI_LOOKUP(pg_proc); @@ -134,42 +134,43 @@ typedef FormData_pg_aggregate *Form_pg_aggregate; * transfn cannot be applied anymore after the first finalfn call. */ #define AGGMODIFY_READ_ONLY 'r' -#define AGGMODIFY_SHARABLE 's' +#define AGGMODIFY_SHAREABLE 's' #define AGGMODIFY_READ_WRITE 'w' #endif /* EXPOSE_TO_CLIENT_CODE */ extern ObjectAddress AggregateCreate(const char *aggName, - Oid aggNamespace, - char aggKind, - int numArgs, - int numDirectArgs, - oidvector *parameterTypes, - Datum allParameterTypes, - Datum parameterModes, - Datum parameterNames, - List *parameterDefaults, - Oid variadicArgType, - List *aggtransfnName, - List *aggfinalfnName, - List *aggcombinefnName, - List *aggserialfnName, - List *aggdeserialfnName, - List *aggmtransfnName, - List *aggminvtransfnName, - List *aggmfinalfnName, - bool finalfnExtraArgs, - bool mfinalfnExtraArgs, - char finalfnModify, - char mfinalfnModify, - List *aggsortopName, - Oid aggTransType, - int32 aggTransSpace, - Oid aggmTransType, - int32 aggmTransSpace, - const char *agginitval, - const char *aggminitval, - char proparallel); + Oid aggNamespace, + bool replace, + char aggKind, + int numArgs, + int numDirectArgs, + oidvector *parameterTypes, + Datum allParameterTypes, + Datum parameterModes, + Datum parameterNames, + List *parameterDefaults, + Oid variadicArgType, + List *aggtransfnName, + List *aggfinalfnName, + List *aggcombinefnName, + List *aggserialfnName, + List *aggdeserialfnName, + List *aggmtransfnName, + List *aggminvtransfnName, + List *aggmfinalfnName, + bool finalfnExtraArgs, + bool mfinalfnExtraArgs, + char finalfnModify, + char mfinalfnModify, + List *aggsortopName, + Oid aggTransType, + int32 aggTransSpace, + Oid aggmTransType, + int32 aggmTransSpace, + const char *agginitval, + const char *aggminitval, + char proparallel); #endif /* PG_AGGREGATE_H */ diff --git a/src/include/catalog/pg_am.dat b/src/include/catalog/pg_am.dat index 8722cacaaef..393b41dd684 100644 --- a/src/include/catalog/pg_am.dat +++ b/src/include/catalog/pg_am.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_am.dat -# Initial contents of the pg_am system relation. +# Initial contents of the pg_am system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_am.dat @@ -12,6 +12,9 @@ [ +{ oid => '2', oid_symbol => 'HEAP_TABLE_AM_OID', + descr => 'heap table access method', + amname => 'heap', amhandler => 'heap_tableam_handler', amtype => 't' }, { oid => '403', oid_symbol => 'BTREE_AM_OID', descr => 'b-tree index access method', amname => 'btree', amhandler => 'bthandler', amtype => 'i' }, diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index f821749af82..706b5e81cba 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_am.h - * definition of the system "access method" relation (pg_am) + * definition of the "access method" system catalog (pg_am) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_am.h @@ -28,6 +28,8 @@ */ CATALOG(pg_am,2601,AccessMethodRelationId) { + Oid oid; /* oid */ + /* access method name */ NameData amname; @@ -51,6 +53,7 @@ typedef FormData_pg_am *Form_pg_am; * Allowed values for amtype */ #define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_TABLE 't' /* table access method */ #endif /* EXPOSE_TO_CLIENT_CODE */ diff --git a/src/include/catalog/pg_amop.dat b/src/include/catalog/pg_amop.dat index b1cf8ec5fca..232557ee819 100644 --- a/src/include/catalog/pg_amop.dat +++ b/src/include/catalog/pg_amop.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_amop.dat -# Initial contents of the pg_amop system relation. +# Initial contents of the pg_amop system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_amop.dat @@ -299,40 +299,67 @@ amoprighttype => 'char', amopstrategy => '5', amopopr => '>(char,char)', amopmethod => 'btree' }, -# btree name_ops +# btree text_ops -{ amopfamily => 'btree/name_ops', amoplefttype => 'name', +{ amopfamily => 'btree/text_ops', amoplefttype => 'text', + amoprighttype => 'text', amopstrategy => '1', amopopr => '<(text,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'text', + amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(text,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'text', + amoprighttype => 'text', amopstrategy => '3', amopopr => '=(text,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'text', + amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(text,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'text', + amoprighttype => 'text', amopstrategy => '5', amopopr => '>(text,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', amoprighttype => 'name', amopstrategy => '1', amopopr => '<(name,name)', amopmethod => 'btree' }, -{ amopfamily => 'btree/name_ops', amoplefttype => 'name', +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', amoprighttype => 'name', amopstrategy => '2', amopopr => '<=(name,name)', amopmethod => 'btree' }, -{ amopfamily => 'btree/name_ops', amoplefttype => 'name', +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', amoprighttype => 'name', amopstrategy => '3', amopopr => '=(name,name)', amopmethod => 'btree' }, -{ amopfamily => 'btree/name_ops', amoplefttype => 'name', +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', amoprighttype => 'name', amopstrategy => '4', amopopr => '>=(name,name)', amopmethod => 'btree' }, -{ amopfamily => 'btree/name_ops', amoplefttype => 'name', +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', amoprighttype => 'name', amopstrategy => '5', amopopr => '>(name,name)', amopmethod => 'btree' }, - -# btree text_ops - +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '1', amopopr => '<(name,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(name,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '3', amopopr => '=(name,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(name,text)', + amopmethod => 'btree' }, +{ amopfamily => 'btree/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '5', amopopr => '>(name,text)', + amopmethod => 'btree' }, { amopfamily => 'btree/text_ops', amoplefttype => 'text', - amoprighttype => 'text', amopstrategy => '1', amopopr => '<(text,text)', + amoprighttype => 'name', amopstrategy => '1', amopopr => '<(text,name)', amopmethod => 'btree' }, { amopfamily => 'btree/text_ops', amoplefttype => 'text', - amoprighttype => 'text', amopstrategy => '2', amopopr => '<=(text,text)', + amoprighttype => 'name', amopstrategy => '2', amopopr => '<=(text,name)', amopmethod => 'btree' }, { amopfamily => 'btree/text_ops', amoplefttype => 'text', - amoprighttype => 'text', amopstrategy => '3', amopopr => '=(text,text)', + amoprighttype => 'name', amopstrategy => '3', amopopr => '=(text,name)', amopmethod => 'btree' }, { amopfamily => 'btree/text_ops', amoplefttype => 'text', - amoprighttype => 'text', amopstrategy => '4', amopopr => '>=(text,text)', + amoprighttype => 'name', amopstrategy => '4', amopopr => '>=(text,name)', amopmethod => 'btree' }, { amopfamily => 'btree/text_ops', amoplefttype => 'text', - amoprighttype => 'text', amopstrategy => '5', amopopr => '>(text,text)', + amoprighttype => 'name', amopstrategy => '5', amopopr => '>(text,name)', amopmethod => 'btree' }, # btree bpchar_ops @@ -371,24 +398,6 @@ amoprighttype => 'bytea', amopstrategy => '5', amopopr => '>(bytea,bytea)', amopmethod => 'btree' }, -# btree abstime_ops - -{ amopfamily => 'btree/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '1', - amopopr => '<(abstime,abstime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '2', - amopopr => '<=(abstime,abstime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '3', - amopopr => '=(abstime,abstime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '4', - amopopr => '>=(abstime,abstime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '5', - amopopr => '>(abstime,abstime)', amopmethod => 'btree' }, - # btree datetime_ops # default operators date @@ -773,42 +782,6 @@ amoprighttype => 'money', amopstrategy => '5', amopopr => '>(money,money)', amopmethod => 'btree' }, -# btree reltime_ops - -{ amopfamily => 'btree/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '1', - amopopr => '<(reltime,reltime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '2', - amopopr => '<=(reltime,reltime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '3', - amopopr => '=(reltime,reltime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '4', - amopopr => '>=(reltime,reltime)', amopmethod => 'btree' }, -{ amopfamily => 'btree/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '5', - amopopr => '>(reltime,reltime)', amopmethod => 'btree' }, - -# btree tinterval_ops - -{ amopfamily => 'btree/tinterval_ops', amoplefttype => 'tinterval', - amoprighttype => 'tinterval', amopstrategy => '1', - amopopr => '<(tinterval,tinterval)', amopmethod => 'btree' }, -{ amopfamily => 'btree/tinterval_ops', amoplefttype => 'tinterval', - amoprighttype => 'tinterval', amopstrategy => '2', - amopopr => '<=(tinterval,tinterval)', amopmethod => 'btree' }, -{ amopfamily => 'btree/tinterval_ops', amoplefttype => 'tinterval', - amoprighttype => 'tinterval', amopstrategy => '3', - amopopr => '=(tinterval,tinterval)', amopmethod => 'btree' }, -{ amopfamily => 'btree/tinterval_ops', amoplefttype => 'tinterval', - amoprighttype => 'tinterval', amopstrategy => '4', - amopopr => '>=(tinterval,tinterval)', amopmethod => 'btree' }, -{ amopfamily => 'btree/tinterval_ops', amoplefttype => 'tinterval', - amoprighttype => 'tinterval', amopstrategy => '5', - amopopr => '>(tinterval,tinterval)', amopmethod => 'btree' }, - # btree array_ops { amopfamily => 'btree/array_ops', amoplefttype => 'anyarray', @@ -979,11 +952,6 @@ amoprighttype => 'macaddr8', amopstrategy => '1', amopopr => '=(macaddr8,macaddr8)', amopmethod => 'hash' }, -# name_ops -{ amopfamily => 'hash/name_ops', amoplefttype => 'name', - amoprighttype => 'name', amopstrategy => '1', amopopr => '=(name,name)', - amopmethod => 'hash' }, - # oid_ops { amopfamily => 'hash/oid_ops', amoplefttype => 'oid', amoprighttype => 'oid', amopstrategy => '1', amopopr => '=(oid,oid)', amopmethod => 'hash' }, @@ -997,6 +965,15 @@ { amopfamily => 'hash/text_ops', amoplefttype => 'text', amoprighttype => 'text', amopstrategy => '1', amopopr => '=(text,text)', amopmethod => 'hash' }, +{ amopfamily => 'hash/text_ops', amoplefttype => 'name', + amoprighttype => 'name', amopstrategy => '1', amopopr => '=(name,name)', + amopmethod => 'hash' }, +{ amopfamily => 'hash/text_ops', amoplefttype => 'name', + amoprighttype => 'text', amopstrategy => '1', amopopr => '=(name,text)', + amopmethod => 'hash' }, +{ amopfamily => 'hash/text_ops', amoplefttype => 'text', + amoprighttype => 'name', amopstrategy => '1', amopopr => '=(text,name)', + amopmethod => 'hash' }, # time_ops { amopfamily => 'hash/time_ops', amoplefttype => 'time', @@ -1036,15 +1013,9 @@ { amopfamily => 'hash/cid_ops', amoplefttype => 'cid', amoprighttype => 'cid', amopstrategy => '1', amopopr => '=(cid,cid)', amopmethod => 'hash' }, -# abstime_ops -{ amopfamily => 'hash/abstime_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '1', - amopopr => '=(abstime,abstime)', amopmethod => 'hash' }, - -# reltime_ops -{ amopfamily => 'hash/reltime_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '1', - amopopr => '=(reltime,reltime)', amopmethod => 'hash' }, +# tid_ops +{ amopfamily => 'hash/tid_ops', amoplefttype => 'tid', amoprighttype => 'tid', + amopstrategy => '1', amopopr => '=(tid,tid)', amopmethod => 'hash' }, # text_pattern_ops { amopfamily => 'hash/text_pattern_ops', amoplefttype => 'text', @@ -1110,6 +1081,9 @@ amopstrategy => '13', amopopr => '~(box,box)', amopmethod => 'gist' }, { amopfamily => 'gist/box_ops', amoplefttype => 'box', amoprighttype => 'box', amopstrategy => '14', amopopr => '@(box,box)', amopmethod => 'gist' }, +{ amopfamily => 'gist/box_ops', amoplefttype => 'box', amoprighttype => 'point', + amopstrategy => '15', amoppurpose => 'o', amopopr => '<->(box,point)', + amopmethod => 'gist', amopsortfamily => 'btree/float_ops' }, # gist point_ops { amopfamily => 'gist/point_ops', amoplefttype => 'point', @@ -1401,6 +1375,10 @@ { amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point', amoprighttype => 'box', amopstrategy => '8', amopopr => '<@(point,box)', amopmethod => 'spgist' }, +{ amopfamily => 'spgist/quad_point_ops', amoplefttype => 'point', + amoprighttype => 'point', amopstrategy => '15', amoppurpose => 'o', + amopopr => '<->(point,point)', amopmethod => 'spgist', + amopsortfamily => 'btree/float_ops' }, # SP-GiST kd_point_ops { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point', @@ -1421,6 +1399,10 @@ { amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point', amoprighttype => 'box', amopstrategy => '8', amopopr => '<@(point,box)', amopmethod => 'spgist' }, +{ amopfamily => 'spgist/kd_point_ops', amoplefttype => 'point', + amoprighttype => 'point', amopstrategy => '15', amoppurpose => 'o', + amopopr => '<->(point,point)', amopmethod => 'spgist', + amopsortfamily => 'btree/float_ops' }, # SP-GiST text_ops { amopfamily => 'spgist/text_ops', amoplefttype => 'text', @@ -1489,11 +1471,23 @@ { amopfamily => 'gin/jsonb_ops', amoplefttype => 'jsonb', amoprighttype => '_text', amopstrategy => '11', amopopr => '?&(jsonb,_text)', amopmethod => 'gin' }, +{ amopfamily => 'gin/jsonb_ops', amoplefttype => 'jsonb', + amoprighttype => 'jsonpath', amopstrategy => '15', + amopopr => '@?(jsonb,jsonpath)', amopmethod => 'gin' }, +{ amopfamily => 'gin/jsonb_ops', amoplefttype => 'jsonb', + amoprighttype => 'jsonpath', amopstrategy => '16', + amopopr => '@@(jsonb,jsonpath)', amopmethod => 'gin' }, # GIN jsonb_path_ops { amopfamily => 'gin/jsonb_path_ops', amoplefttype => 'jsonb', amoprighttype => 'jsonb', amopstrategy => '7', amopopr => '@>(jsonb,jsonb)', amopmethod => 'gin' }, +{ amopfamily => 'gin/jsonb_path_ops', amoplefttype => 'jsonb', + amoprighttype => 'jsonpath', amopstrategy => '15', + amopopr => '@?(jsonb,jsonpath)', amopmethod => 'gin' }, +{ amopfamily => 'gin/jsonb_path_ops', amoplefttype => 'jsonb', + amoprighttype => 'jsonpath', amopstrategy => '16', + amopopr => '@@(jsonb,jsonpath)', amopmethod => 'gin' }, # SP-GiST range_ops { amopfamily => 'spgist/range_ops', amoplefttype => 'anyrange', @@ -1552,6 +1546,10 @@ amopstrategy => '11', amopopr => '|>>(box,box)', amopmethod => 'spgist' }, { amopfamily => 'spgist/box_ops', amoplefttype => 'box', amoprighttype => 'box', amopstrategy => '12', amopopr => '|&>(box,box)', amopmethod => 'spgist' }, +{ amopfamily => 'spgist/box_ops', amoplefttype => 'box', + amoprighttype => 'point', amopstrategy => '15', amoppurpose => 'o', + amopopr => '<->(box,point)', amopmethod => 'spgist', + amopsortfamily => 'btree/float_ops' }, # SP-GiST poly_ops (supports polygons) { amopfamily => 'spgist/poly_ops', amoplefttype => 'polygon', @@ -1590,6 +1588,10 @@ { amopfamily => 'spgist/poly_ops', amoplefttype => 'polygon', amoprighttype => 'polygon', amopstrategy => '12', amopopr => '|&>(polygon,polygon)', amopmethod => 'spgist' }, +{ amopfamily => 'spgist/poly_ops', amoplefttype => 'polygon', + amoprighttype => 'point', amopstrategy => '15', amoppurpose => 'o', + amopopr => '<->(polygon,point)', amopmethod => 'spgist', + amopsortfamily => 'btree/float_ops' }, # GiST inet_ops { amopfamily => 'gist/network_ops', amoplefttype => 'inet', @@ -1977,40 +1979,6 @@ amoprighttype => 'float8', amopstrategy => '5', amopopr => '>(float8,float8)', amopmethod => 'brin' }, -# minmax abstime -{ amopfamily => 'brin/abstime_minmax_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '1', - amopopr => '<(abstime,abstime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/abstime_minmax_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '2', - amopopr => '<=(abstime,abstime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/abstime_minmax_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '3', - amopopr => '=(abstime,abstime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/abstime_minmax_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '4', - amopopr => '>=(abstime,abstime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/abstime_minmax_ops', amoplefttype => 'abstime', - amoprighttype => 'abstime', amopstrategy => '5', - amopopr => '>(abstime,abstime)', amopmethod => 'brin' }, - -# minmax reltime -{ amopfamily => 'brin/reltime_minmax_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '1', - amopopr => '<(reltime,reltime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/reltime_minmax_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '2', - amopopr => '<=(reltime,reltime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/reltime_minmax_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '3', - amopopr => '=(reltime,reltime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/reltime_minmax_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '4', - amopopr => '>=(reltime,reltime)', amopmethod => 'brin' }, -{ amopfamily => 'brin/reltime_minmax_ops', amoplefttype => 'reltime', - amoprighttype => 'reltime', amopstrategy => '5', - amopopr => '>(reltime,reltime)', amopmethod => 'brin' }, - # minmax macaddr { amopfamily => 'brin/macaddr_minmax_ops', amoplefttype => 'macaddr', amoprighttype => 'macaddr', amopstrategy => '1', diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index 4be325221f0..aa2be7b643d 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_amop.h - * definition of the system "amop" relation (pg_amop) + * definition of the "access method operator" system catalog (pg_amop) * * The amop table identifies the operators associated with each index operator * family and operator class (classes are subsets of families). An associated @@ -29,7 +29,7 @@ * intentional denormalization of the catalogs to buy lookup speed. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_amop.h @@ -53,6 +53,8 @@ */ CATALOG(pg_amop,2602,AccessMethodOperatorRelationId) { + Oid oid; /* oid */ + /* the index opfamily this entry is for */ Oid amopfamily BKI_LOOKUP(pg_opfamily); diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index 6b6c807f90e..5e705019b4d 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_amproc.dat -# Initial contents of the pg_amproc system relation. +# Initial contents of the pg_amproc system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_amproc.dat @@ -15,8 +15,6 @@ # btree { amprocfamily => 'btree/array_ops', amproclefttype => 'anyarray', amprocrighttype => 'anyarray', amprocnum => '1', amproc => 'btarraycmp' }, -{ amprocfamily => 'btree/abstime_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '1', amproc => 'btabstimecmp' }, { amprocfamily => 'btree/bit_ops', amproclefttype => 'bit', amprocrighttype => 'bit', amprocnum => '1', amproc => 'bitcmp' }, { amprocfamily => 'btree/bool_ops', amproclefttype => 'bool', @@ -95,6 +93,9 @@ amproc => 'in_range(float4,float4,float8,bool,bool)' }, { amprocfamily => 'btree/network_ops', amproclefttype => 'inet', amprocrighttype => 'inet', amprocnum => '1', amproc => 'network_cmp' }, +{ amprocfamily => 'btree/network_ops', amproclefttype => 'inet', + amprocrighttype => 'inet', amprocnum => '2', + amproc => 'network_sortsupport' }, { amprocfamily => 'btree/integer_ops', amproclefttype => 'int2', amprocrighttype => 'int2', amprocnum => '1', amproc => 'btint2cmp' }, { amprocfamily => 'btree/integer_ops', amproclefttype => 'int2', @@ -150,10 +151,6 @@ { amprocfamily => 'btree/macaddr_ops', amproclefttype => 'macaddr', amprocrighttype => 'macaddr', amprocnum => '2', amproc => 'macaddr_sortsupport' }, -{ amprocfamily => 'btree/name_ops', amproclefttype => 'name', - amprocrighttype => 'name', amprocnum => '1', amproc => 'btnamecmp' }, -{ amprocfamily => 'btree/name_ops', amproclefttype => 'name', - amprocrighttype => 'name', amprocnum => '2', amproc => 'btnamesortsupport' }, { amprocfamily => 'btree/numeric_ops', amproclefttype => 'numeric', amprocrighttype => 'numeric', amprocnum => '1', amproc => 'numeric_cmp' }, { amprocfamily => 'btree/numeric_ops', amproclefttype => 'numeric', @@ -173,6 +170,14 @@ amprocrighttype => 'text', amprocnum => '1', amproc => 'bttextcmp' }, { amprocfamily => 'btree/text_ops', amproclefttype => 'text', amprocrighttype => 'text', amprocnum => '2', amproc => 'bttextsortsupport' }, +{ amprocfamily => 'btree/text_ops', amproclefttype => 'name', + amprocrighttype => 'name', amprocnum => '1', amproc => 'btnamecmp' }, +{ amprocfamily => 'btree/text_ops', amproclefttype => 'name', + amprocrighttype => 'name', amprocnum => '2', amproc => 'btnamesortsupport' }, +{ amprocfamily => 'btree/text_ops', amproclefttype => 'name', + amprocrighttype => 'text', amprocnum => '1', amproc => 'btnametextcmp' }, +{ amprocfamily => 'btree/text_ops', amproclefttype => 'text', + amprocrighttype => 'name', amprocnum => '1', amproc => 'bttextnamecmp' }, { amprocfamily => 'btree/time_ops', amproclefttype => 'time', amprocrighttype => 'time', amprocnum => '1', amproc => 'time_cmp' }, { amprocfamily => 'btree/time_ops', amproclefttype => 'time', @@ -198,11 +203,6 @@ amproc => 'btbpchar_pattern_sortsupport' }, { amprocfamily => 'btree/money_ops', amproclefttype => 'money', amprocrighttype => 'money', amprocnum => '1', amproc => 'cash_cmp' }, -{ amprocfamily => 'btree/reltime_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '1', amproc => 'btreltimecmp' }, -{ amprocfamily => 'btree/tinterval_ops', amproclefttype => 'tinterval', - amprocrighttype => 'tinterval', amprocnum => '1', - amproc => 'bttintervalcmp' }, { amprocfamily => 'btree/tid_ops', amproclefttype => 'tid', amprocrighttype => 'tid', amprocnum => '1', amproc => 'bttidcmp' }, { amprocfamily => 'btree/uuid_ops', amproclefttype => 'uuid', @@ -283,10 +283,6 @@ { amprocfamily => 'hash/macaddr_ops', amproclefttype => 'macaddr', amprocrighttype => 'macaddr', amprocnum => '2', amproc => 'hashmacaddrextended' }, -{ amprocfamily => 'hash/name_ops', amproclefttype => 'name', - amprocrighttype => 'name', amprocnum => '1', amproc => 'hashname' }, -{ amprocfamily => 'hash/name_ops', amproclefttype => 'name', - amprocrighttype => 'name', amprocnum => '2', amproc => 'hashnameextended' }, { amprocfamily => 'hash/oid_ops', amproclefttype => 'oid', amprocrighttype => 'oid', amprocnum => '1', amproc => 'hashoid' }, { amprocfamily => 'hash/oid_ops', amproclefttype => 'oid', @@ -300,6 +296,10 @@ amprocrighttype => 'text', amprocnum => '1', amproc => 'hashtext' }, { amprocfamily => 'hash/text_ops', amproclefttype => 'text', amprocrighttype => 'text', amprocnum => '2', amproc => 'hashtextextended' }, +{ amprocfamily => 'hash/text_ops', amproclefttype => 'name', + amprocrighttype => 'name', amprocnum => '1', amproc => 'hashname' }, +{ amprocfamily => 'hash/text_ops', amproclefttype => 'name', + amprocrighttype => 'name', amprocnum => '2', amproc => 'hashnameextended' }, { amprocfamily => 'hash/time_ops', amproclefttype => 'time', amprocrighttype => 'time', amprocnum => '1', amproc => 'time_hash' }, { amprocfamily => 'hash/time_ops', amproclefttype => 'time', @@ -343,16 +343,10 @@ amprocrighttype => 'cid', amprocnum => '1', amproc => 'hashint4' }, { amprocfamily => 'hash/cid_ops', amproclefttype => 'cid', amprocrighttype => 'cid', amprocnum => '2', amproc => 'hashint4extended' }, -{ amprocfamily => 'hash/abstime_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '1', amproc => 'hashint4' }, -{ amprocfamily => 'hash/abstime_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '2', - amproc => 'hashint4extended' }, -{ amprocfamily => 'hash/reltime_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '1', amproc => 'hashint4' }, -{ amprocfamily => 'hash/reltime_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '2', - amproc => 'hashint4extended' }, +{ amprocfamily => 'hash/tid_ops', amproclefttype => 'tid', + amprocrighttype => 'tid', amprocnum => '1', amproc => 'hashtid' }, +{ amprocfamily => 'hash/tid_ops', amproclefttype => 'tid', + amprocrighttype => 'tid', amprocnum => '2', amproc => 'hashtidextended' }, { amprocfamily => 'hash/text_pattern_ops', amproclefttype => 'text', amprocrighttype => 'text', amprocnum => '1', amproc => 'hashtext' }, { amprocfamily => 'hash/text_pattern_ops', amproclefttype => 'text', @@ -428,6 +422,8 @@ amprocrighttype => 'box', amprocnum => '6', amproc => 'gist_box_picksplit' }, { amprocfamily => 'gist/box_ops', amproclefttype => 'box', amprocrighttype => 'box', amprocnum => '7', amproc => 'gist_box_same' }, +{ amprocfamily => 'gist/box_ops', amproclefttype => 'box', + amprocrighttype => 'box', amprocnum => '8', amproc => 'gist_box_distance' }, { amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon', amprocrighttype => 'polygon', amprocnum => '1', amproc => 'gist_poly_consistent' }, @@ -917,34 +913,6 @@ amprocrighttype => 'float4', amprocnum => '4', amproc => 'brin_minmax_union' }, -# minmax abstime -{ amprocfamily => 'brin/abstime_minmax_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '1', - amproc => 'brin_minmax_opcinfo' }, -{ amprocfamily => 'brin/abstime_minmax_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '2', - amproc => 'brin_minmax_add_value' }, -{ amprocfamily => 'brin/abstime_minmax_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '3', - amproc => 'brin_minmax_consistent' }, -{ amprocfamily => 'brin/abstime_minmax_ops', amproclefttype => 'abstime', - amprocrighttype => 'abstime', amprocnum => '4', - amproc => 'brin_minmax_union' }, - -# minmax reltime -{ amprocfamily => 'brin/reltime_minmax_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '1', - amproc => 'brin_minmax_opcinfo' }, -{ amprocfamily => 'brin/reltime_minmax_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '2', - amproc => 'brin_minmax_add_value' }, -{ amprocfamily => 'brin/reltime_minmax_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '3', - amproc => 'brin_minmax_consistent' }, -{ amprocfamily => 'brin/reltime_minmax_ops', amproclefttype => 'reltime', - amprocrighttype => 'reltime', amprocnum => '4', - amproc => 'brin_minmax_union' }, - # minmax macaddr { amprocfamily => 'brin/macaddr_minmax_ops', amproclefttype => 'macaddr', amprocrighttype => 'macaddr', amprocnum => '1', diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index d638e0cbfe0..62ca564130b 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_amproc.h - * definition of the system "amproc" relation (pg_amproc) + * definition of the "access method procedure" system catalog (pg_amproc) * * The amproc table identifies support procedures associated with index * operator families and classes. These procedures can't be listed in pg_amop @@ -18,7 +18,7 @@ * some don't pay attention to non-default functions at all. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_amproc.h @@ -42,6 +42,8 @@ */ CATALOG(pg_amproc,2603,AccessMethodProcedureRelationId) { + Oid oid; /* oid */ + /* the index opfamily this entry is for */ Oid amprocfamily BKI_LOOKUP(pg_opfamily); diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h index 16b106d9add..4ec371bc4a4 100644 --- a/src/include/catalog/pg_attrdef.h +++ b/src/include/catalog/pg_attrdef.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_attrdef.h - * definition of the system "attribute defaults" relation (pg_attrdef) + * definition of the "attribute defaults" system catalog (pg_attrdef) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_attrdef.h @@ -28,12 +28,14 @@ */ CATALOG(pg_attrdef,2604,AttrDefaultRelationId) { + Oid oid; /* oid */ + Oid adrelid; /* OID of table containing attribute */ int16 adnum; /* attnum of attribute */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - pg_node_tree adbin; /* nodeToString representation of default */ - text adsrc; /* human-readable representation of default */ + pg_node_tree adbin BKI_FORCE_NOT_NULL; /* nodeToString representation of + * default */ #endif } FormData_pg_attrdef; diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h index 8eef7d2fedc..04004b5703e 100644 --- a/src/include/catalog/pg_attribute.h +++ b/src/include/catalog/pg_attribute.h @@ -1,14 +1,14 @@ /*------------------------------------------------------------------------- * * pg_attribute.h - * definition of the system "attribute" relation (pg_attribute) + * definition of the "attribute" system catalog (pg_attribute) * * The initial contents of pg_attribute are generated at compile time by * genbki.pl, so there is no pg_attribute.dat file. Only "bootstrapped" * relations need be included. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_attribute.h @@ -34,7 +34,7 @@ * You may need to change catalog/genbki.pl as well. * ---------------- */ -CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO +CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO { Oid attrelid; /* OID of relation containing this attribute */ NameData attname; /* name of attribute */ @@ -140,6 +140,9 @@ CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BK /* One of the ATTRIBUTE_IDENTITY_* constants below, or '\0' */ char attidentity BKI_DEFAULT('\0'); + /* One of the ATTRIBUTE_GENERATED_* constants below, or '\0' */ + char attgenerated BKI_DEFAULT('\0'); + /* Is dropped (ie, logically invisible) or not */ bool attisdropped BKI_DEFAULT(f); @@ -201,6 +204,8 @@ typedef FormData_pg_attribute *Form_pg_attribute; #define ATTRIBUTE_IDENTITY_ALWAYS 'a' #define ATTRIBUTE_IDENTITY_BY_DEFAULT 'd' +#define ATTRIBUTE_GENERATED_STORED 's' + #endif /* EXPOSE_TO_CLIENT_CODE */ #endif /* PG_ATTRIBUTE_H */ diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h index 75bc2baa14c..644a25d1e52 100644 --- a/src/include/catalog/pg_auth_members.h +++ b/src/include/catalog/pg_auth_members.h @@ -1,11 +1,11 @@ /*------------------------------------------------------------------------- * * pg_auth_members.h - * definition of the system "authorization identifier members" relation + * definition of the "authorization identifier members" system catalog * (pg_auth_members). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_auth_members.h @@ -27,7 +27,7 @@ * typedef struct FormData_pg_auth_members * ---------------- */ -CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO +CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO { Oid roleid; /* ID of a role */ Oid member; /* ID of a member of that role */ diff --git a/src/include/catalog/pg_authid.dat b/src/include/catalog/pg_authid.dat index 52f42595600..c21f97adcf2 100644 --- a/src/include/catalog/pg_authid.dat +++ b/src/include/catalog/pg_authid.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_authid.dat -# Initial contents of the pg_authid system relation. +# Initial contents of the pg_authid system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_authid.dat @@ -12,14 +12,11 @@ [ -# POSTGRES will be replaced at initdb time with a user choice that might -# contain non-word characters, so we must double-quote it. - # The C code typically refers to these roles using the #define symbols, # so make sure every entry has an oid_symbol value. { oid => '10', oid_symbol => 'BOOTSTRAP_SUPERUSERID', - rolname => '"POSTGRES"', rolsuper => 't', rolinherit => 't', + rolname => 'POSTGRES', rolsuper => 't', rolinherit => 't', rolcreaterole => 't', rolcreatedb => 't', rolcanlogin => 't', rolreplication => 't', rolbypassrls => 't', rolconnlimit => '-1', rolpassword => '_null_', rolvaliduntil => '_null_' }, diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index 863ef65ebfa..6fcf645c014 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -1,12 +1,12 @@ /*------------------------------------------------------------------------- * * pg_authid.h - * definition of the system "authorization identifier" relation (pg_authid) + * definition of the "authorization identifier" system catalog (pg_authid) * * pg_shadow and pg_group are now publicly accessible views on pg_authid. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_authid.h @@ -30,6 +30,7 @@ */ CATALOG(pg_authid,1260,AuthIdRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842,AuthIdRelation_Rowtype_Id) BKI_SCHEMA_MACRO { + Oid oid; /* oid */ NameData rolname; /* name of role */ bool rolsuper; /* read this field via superuser() only! */ bool rolinherit; /* inherit privileges from other roles? */ diff --git a/src/include/catalog/pg_cast.dat b/src/include/catalog/pg_cast.dat index c335a7686d5..aabfa7af03e 100644 --- a/src/include/catalog/pg_cast.dat +++ b/src/include/catalog/pg_cast.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_cast.dat -# Initial contents of the pg_cast system relation. +# Initial contents of the pg_cast system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_cast.dat @@ -324,17 +324,13 @@ { castsource => 'pg_dependencies', casttarget => 'text', castfunc => '0', castcontext => 'i', castmethod => 'i' }, +# pg_mcv_list can be coerced to, but not from, bytea and text +{ castsource => 'pg_mcv_list', casttarget => 'bytea', castfunc => '0', + castcontext => 'i', castmethod => 'b' }, +{ castsource => 'pg_mcv_list', casttarget => 'text', castfunc => '0', + castcontext => 'i', castmethod => 'i' }, + # Datetime category -{ castsource => 'abstime', casttarget => 'date', castfunc => 'date(abstime)', - castcontext => 'a', castmethod => 'f' }, -{ castsource => 'abstime', casttarget => 'time', castfunc => 'time(abstime)', - castcontext => 'a', castmethod => 'f' }, -{ castsource => 'abstime', casttarget => 'timestamp', - castfunc => 'timestamp(abstime)', castcontext => 'i', castmethod => 'f' }, -{ castsource => 'abstime', casttarget => 'timestamptz', - castfunc => 'timestamptz(abstime)', castcontext => 'i', castmethod => 'f' }, -{ castsource => 'reltime', casttarget => 'interval', - castfunc => 'interval(reltime)', castcontext => 'i', castmethod => 'f' }, { castsource => 'date', casttarget => 'timestamp', castfunc => 'timestamp(date)', castcontext => 'i', castmethod => 'f' }, { castsource => 'date', casttarget => 'timestamptz', @@ -343,16 +339,12 @@ castcontext => 'i', castmethod => 'f' }, { castsource => 'time', casttarget => 'timetz', castfunc => 'timetz(time)', castcontext => 'i', castmethod => 'f' }, -{ castsource => 'timestamp', casttarget => 'abstime', - castfunc => 'abstime(timestamp)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamp', casttarget => 'date', castfunc => 'date(timestamp)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamp', casttarget => 'time', castfunc => 'time(timestamp)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamp', casttarget => 'timestamptz', castfunc => 'timestamptz(timestamp)', castcontext => 'i', castmethod => 'f' }, -{ castsource => 'timestamptz', casttarget => 'abstime', - castfunc => 'abstime(timestamptz)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamptz', casttarget => 'date', castfunc => 'date(timestamptz)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamptz', casttarget => 'time', @@ -361,23 +353,11 @@ castfunc => 'timestamp(timestamptz)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timestamptz', casttarget => 'timetz', castfunc => 'timetz(timestamptz)', castcontext => 'a', castmethod => 'f' }, -{ castsource => 'interval', casttarget => 'reltime', castfunc => 'reltime', - castcontext => 'a', castmethod => 'f' }, { castsource => 'interval', casttarget => 'time', castfunc => 'time(interval)', castcontext => 'a', castmethod => 'f' }, { castsource => 'timetz', casttarget => 'time', castfunc => 'time(timetz)', castcontext => 'a', castmethod => 'f' }, -# Cross-category casts between int4 and abstime, reltime -{ castsource => 'int4', casttarget => 'abstime', castfunc => '0', - castcontext => 'e', castmethod => 'b' }, -{ castsource => 'abstime', casttarget => 'int4', castfunc => '0', - castcontext => 'e', castmethod => 'b' }, -{ castsource => 'int4', casttarget => 'reltime', castfunc => '0', - castcontext => 'e', castmethod => 'b' }, -{ castsource => 'reltime', casttarget => 'int4', castfunc => '0', - castcontext => 'e', castmethod => 'b' }, - # Geometric category { castsource => 'point', casttarget => 'box', castfunc => 'box(point)', castcontext => 'a', castmethod => 'f' }, diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index 10c796ab02e..85e31b0448e 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * pg_cast.h - * definition of the system "type casts" relation (pg_cast) + * definition of the "type casts" system catalog (pg_cast) * * As of Postgres 8.0, pg_cast describes not only type coercion functions * but also length coercion functions. * - * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_cast.h * @@ -30,6 +30,8 @@ */ CATALOG(pg_cast,2605,CastRelationId) { + Oid oid; /* oid */ + /* source datatype for cast */ Oid castsource BKI_LOOKUP(pg_type); diff --git a/src/include/catalog/pg_class.dat b/src/include/catalog/pg_class.dat index e1450e3fc7a..9bcf28676da 100644 --- a/src/include/catalog/pg_class.dat +++ b/src/include/catalog/pg_class.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_class.dat -# Initial contents of the pg_class system relation. +# Initial contents of the pg_class system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_class.dat @@ -12,7 +12,7 @@ [ -# Note: only "bootstrapped" relations, ie those marked BKI_BOOTSTRAP, need to +# Note: only bootstrap catalogs, ie those marked BKI_BOOTSTRAP, need to # have entries here. Be sure that the OIDs listed here match those given in # their CATALOG and BKI_ROWTYPE_OID macros, and that the relnatts values are # correct. @@ -21,48 +21,44 @@ # similarly, "1" in relminmxid stands for FirstMultiXactId { oid => '1247', - relname => 'pg_type', relnamespace => 'PGNSP', reltype => '71', - reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0', - reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0', + relname => 'pg_type', reltype => 'pg_type', relam => 'heap', + relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0', reltoastrelid => '0', relhasindex => 'f', relisshared => 'f', - relpersistence => 'p', relkind => 'r', relnatts => '30', relchecks => '0', - relhasoids => 't', relhasrules => 'f', relhastriggers => 'f', - relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f', - relispopulated => 't', relreplident => 'n', relispartition => 'f', - relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_', - reloptions => '_null_', relpartbound => '_null_' }, + relpersistence => 'p', relkind => 'r', relnatts => '31', relchecks => '0', + relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f', + relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't', + relreplident => 'n', relispartition => 'f', relfrozenxid => '3', + relminmxid => '1', relacl => '_null_', reloptions => '_null_', + relpartbound => '_null_' }, { oid => '1249', - relname => 'pg_attribute', relnamespace => 'PGNSP', reltype => '75', - reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0', - reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0', + relname => 'pg_attribute', reltype => 'pg_attribute', relam => 'heap', + relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0', reltoastrelid => '0', relhasindex => 'f', relisshared => 'f', - relpersistence => 'p', relkind => 'r', relnatts => '24', relchecks => '0', - relhasoids => 'f', relhasrules => 'f', relhastriggers => 'f', - relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f', - relispopulated => 't', relreplident => 'n', relispartition => 'f', - relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_', - reloptions => '_null_', relpartbound => '_null_' }, + relpersistence => 'p', relkind => 'r', relnatts => '25', relchecks => '0', + relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f', + relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't', + relreplident => 'n', relispartition => 'f', relfrozenxid => '3', + relminmxid => '1', relacl => '_null_', reloptions => '_null_', + relpartbound => '_null_' }, { oid => '1255', - relname => 'pg_proc', relnamespace => 'PGNSP', reltype => '81', - reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0', - reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0', + relname => 'pg_proc', reltype => 'pg_proc', relam => 'heap', + relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0', reltoastrelid => '0', relhasindex => 'f', relisshared => 'f', - relpersistence => 'p', relkind => 'r', relnatts => '28', relchecks => '0', - relhasoids => 't', relhasrules => 'f', relhastriggers => 'f', - relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f', - relispopulated => 't', relreplident => 'n', relispartition => 'f', - relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_', - reloptions => '_null_', relpartbound => '_null_' }, + relpersistence => 'p', relkind => 'r', relnatts => '29', relchecks => '0', + relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f', + relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't', + relreplident => 'n', relispartition => 'f', relfrozenxid => '3', + relminmxid => '1', relacl => '_null_', reloptions => '_null_', + relpartbound => '_null_' }, { oid => '1259', - relname => 'pg_class', relnamespace => 'PGNSP', reltype => '83', - reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0', - reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0', + relname => 'pg_class', reltype => 'pg_class', relam => 'heap', + relfilenode => '0', relpages => '0', reltuples => '0', relallvisible => '0', reltoastrelid => '0', relhasindex => 'f', relisshared => 'f', relpersistence => 'p', relkind => 'r', relnatts => '33', relchecks => '0', - relhasoids => 't', relhasrules => 'f', relhastriggers => 'f', - relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f', - relispopulated => 't', relreplident => 'n', relispartition => 'f', - relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_', - reloptions => '_null_', relpartbound => '_null_' }, + relhasrules => 'f', relhastriggers => 'f', relhassubclass => 'f', + relrowsecurity => 'f', relforcerowsecurity => 'f', relispopulated => 't', + relreplident => 'n', relispartition => 'f', relfrozenxid => '3', + relminmxid => '1', relacl => '_null_', reloptions => '_null_', + relpartbound => '_null_' }, ] diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index ef62c30cf95..090b6ba9078 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_class.h - * definition of the system "relation" relation (pg_class) + * definition of the "relation" system catalog (pg_class) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_class.h @@ -28,55 +28,113 @@ */ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO { - NameData relname; /* class name */ - Oid relnamespace; /* OID of namespace containing this class */ - Oid reltype; /* OID of entry in pg_type for table's - * implicit row type */ - Oid reloftype; /* OID of entry in pg_type for underlying - * composite type */ - Oid relowner; /* class owner */ - Oid relam; /* index access method; 0 if not an index */ - Oid relfilenode; /* identifier of physical storage file */ + /* oid */ + Oid oid; + /* class name */ + NameData relname; + + /* OID of namespace containing this class */ + Oid relnamespace BKI_DEFAULT(PGNSP); + + /* OID of entry in pg_type for table's implicit row type */ + Oid reltype BKI_LOOKUP(pg_type); + + /* OID of entry in pg_type for underlying composite type */ + Oid reloftype BKI_DEFAULT(0) BKI_LOOKUP(pg_type); + + /* class owner */ + Oid relowner BKI_DEFAULT(PGUID); + + /* access method; 0 if not a table / index */ + Oid relam BKI_LOOKUP(pg_am); + + /* identifier of physical storage file */ /* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */ - Oid reltablespace; /* identifier of table space for relation */ - int32 relpages; /* # of blocks (not always up-to-date) */ - float4 reltuples; /* # of tuples (not always up-to-date) */ - int32 relallvisible; /* # of all-visible blocks (not always - * up-to-date) */ - Oid reltoastrelid; /* OID of toast table; 0 if none */ - bool relhasindex; /* T if has (or has had) any indexes */ - bool relisshared; /* T if shared across databases */ - char relpersistence; /* see RELPERSISTENCE_xxx constants below */ - char relkind; /* see RELKIND_xxx constants below */ - int16 relnatts; /* number of user attributes */ + Oid relfilenode; + + /* identifier of table space for relation (0 means default for database) */ + Oid reltablespace BKI_DEFAULT(0) BKI_LOOKUP(pg_tablespace); + + /* # of blocks (not always up-to-date) */ + int32 relpages; + + /* # of tuples (not always up-to-date) */ + float4 reltuples; + + /* # of all-visible blocks (not always up-to-date) */ + int32 relallvisible; + + /* OID of toast table; 0 if none */ + Oid reltoastrelid; + + /* T if has (or has had) any indexes */ + bool relhasindex; + + /* T if shared across databases */ + bool relisshared; + + /* see RELPERSISTENCE_xxx constants below */ + char relpersistence; + + /* see RELKIND_xxx constants below */ + char relkind; + + /* number of user attributes */ + int16 relnatts; /* * Class pg_attribute must contain exactly "relnatts" user attributes * (with attnums ranging from 1 to relnatts) for this class. It may also * contain entries with negative attnums for system attributes. */ - int16 relchecks; /* # of CHECK constraints for class */ - bool relhasoids; /* T if we generate OIDs for rows of rel */ - bool relhasrules; /* has (or has had) any rules */ - bool relhastriggers; /* has (or has had) any TRIGGERs */ - bool relhassubclass; /* has (or has had) derived classes */ - bool relrowsecurity; /* row security is enabled or not */ - bool relforcerowsecurity; /* row security forced for owners or - * not */ - bool relispopulated; /* matview currently holds query results */ - char relreplident; /* see REPLICA_IDENTITY_xxx constants */ - bool relispartition; /* is relation a partition? */ - Oid relrewrite; /* heap for rewrite during DDL, link to original rel */ - TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */ - TransactionId relminmxid; /* all multixacts in this rel are >= this. - * this is really a MultiXactId */ + + /* # of CHECK constraints for class */ + int16 relchecks; + + /* has (or has had) any rules */ + bool relhasrules; + + /* has (or has had) any TRIGGERs */ + bool relhastriggers; + + /* has (or has had) child tables or indexes */ + bool relhassubclass; + + /* row security is enabled or not */ + bool relrowsecurity; + + /* row security forced for owners or not */ + bool relforcerowsecurity; + + /* matview currently holds query results */ + bool relispopulated; + + /* see REPLICA_IDENTITY_xxx constants */ + char relreplident; + + /* is relation a partition? */ + bool relispartition; + + /* heap for rewrite during DDL, link to original rel */ + Oid relrewrite BKI_DEFAULT(0); + + /* all Xids < this are frozen in this rel */ + TransactionId relfrozenxid; + + /* all multixacts in this rel are >= this; it is really a MultiXactId */ + TransactionId relminmxid; #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* NOTE: These fields are not present in a relcache entry's rd_rel field. */ - aclitem relacl[1]; /* access permissions */ - text reloptions[1]; /* access-method-specific options */ - pg_node_tree relpartbound; /* partition bound node tree */ + /* access permissions */ + aclitem relacl[1]; + + /* access-method-specific options */ + text reloptions[1]; + + /* partition bound node tree */ + pg_node_tree relpartbound; #endif } FormData_pg_class; @@ -121,6 +179,19 @@ typedef FormData_pg_class *Form_pg_class; */ #define REPLICA_IDENTITY_INDEX 'i' +/* + * Relation kinds that have physical storage. These relations normally have + * relfilenode set to non-zero, but it can also be zero if the relation is + * mapped. + */ +#define RELKIND_HAS_STORAGE(relkind) \ + ((relkind) == RELKIND_RELATION || \ + (relkind) == RELKIND_INDEX || \ + (relkind) == RELKIND_SEQUENCE || \ + (relkind) == RELKIND_TOASTVALUE || \ + (relkind) == RELKIND_MATVIEW) + + #endif /* EXPOSE_TO_CLIENT_CODE */ #endif /* PG_CLASS_H */ diff --git a/src/include/catalog/pg_collation.dat b/src/include/catalog/pg_collation.dat index e98a4fd8177..367ce3607bc 100644 --- a/src/include/catalog/pg_collation.dat +++ b/src/include/catalog/pg_collation.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_collation.dat -# Initial contents of the pg_collation system relation. +# Initial contents of the pg_collation system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_collation.dat diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h index 5c73bbf94f4..d3366f361d1 100644 --- a/src/include/catalog/pg_collation.h +++ b/src/include/catalog/pg_collation.h @@ -1,14 +1,13 @@ /*------------------------------------------------------------------------- * * pg_collation.h - * definition of the system "collation" relation (pg_collation) + * definition of the "collation" system catalog (pg_collation) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * IDENTIFICATION - * src/include/catalog/pg_collation.h + * src/include/catalog/pg_collation.h * * NOTES * The Catalog.pm module reads this file and derives schema @@ -29,10 +28,12 @@ */ CATALOG(pg_collation,3456,CollationRelationId) { + Oid oid; /* oid */ NameData collname; /* collation name */ Oid collnamespace; /* OID of namespace containing collation */ Oid collowner; /* owner of collation */ char collprovider; /* see constants below */ + bool collisdeterministic BKI_DEFAULT(t); int32 collencoding; /* encoding for this collation; -1 = "all" */ NameData collcollate; /* LC_COLLATE setting */ NameData collctype; /* LC_CTYPE setting */ @@ -58,14 +59,15 @@ typedef FormData_pg_collation *Form_pg_collation; #endif /* EXPOSE_TO_CLIENT_CODE */ -extern Oid CollationCreate(const char *collname, Oid collnamespace, - Oid collowner, - char collprovider, - int32 collencoding, - const char *collcollate, const char *collctype, - const char *collversion, - bool if_not_exists, - bool quiet); +extern Oid CollationCreate(const char *collname, Oid collnamespace, + Oid collowner, + char collprovider, + bool collisdeterministic, + int32 collencoding, + const char *collcollate, const char *collctype, + const char *collversion, + bool if_not_exists, + bool quiet); extern void RemoveCollationById(Oid collationOid); #endif /* PG_COLLATION_H */ diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h index 017e4de4aba..c1e60c7dfd2 100644 --- a/src/include/catalog/pg_constraint.h +++ b/src/include/catalog/pg_constraint.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_constraint.h - * definition of the system "constraint" relation (pg_constraint) + * definition of the "constraint" system catalog (pg_constraint) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_constraint.h @@ -31,6 +31,8 @@ */ CATALOG(pg_constraint,2606,ConstraintRelationId) { + Oid oid; /* oid */ + /* * conname + connamespace is deliberately not unique; we allow, for * example, the same name to be used for constraints of different @@ -39,6 +41,10 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) * global lock to generate a globally unique name for a nameless * constraint. We associate a namespace with constraint names only for * SQL-spec compatibility. + * + * However, we do require conname to be unique among the constraints of a + * single relation or domain. This is enforced by a unique index on + * conrelid + contypid + conname. */ NameData conname; /* name of this constraint */ Oid connamespace; /* OID of namespace containing constraint */ @@ -105,12 +111,6 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) */ int16 conkey[1]; - /* - * Columns of conrelid that the constraint does not apply to, but are - * included into the same index as the key columns - */ - int16 conincluding[1]; - /* * If a foreign key, the referenced columns of confrelid */ @@ -144,11 +144,6 @@ CATALOG(pg_constraint,2606,ConstraintRelationId) * If a check constraint, nodeToString representation of expression */ pg_node_tree conbin; - - /* - * If a check constraint, source-text representation of expression - */ - text consrc; #endif } FormData_pg_constraint; @@ -187,79 +182,67 @@ typedef enum ConstraintCategory CONSTRAINT_ASSERTION /* for future expansion */ } ConstraintCategory; -/* - * Used when cloning a foreign key constraint to a partition, so that the - * caller can optionally set up a verification pass for it. - */ -typedef struct ClonedConstraint -{ - Oid relid; - Oid refrelid; - Oid conindid; - Oid conid; - Constraint *constraint; -} ClonedConstraint; - - -extern Oid CreateConstraintEntry(const char *constraintName, - Oid constraintNamespace, - char constraintType, - bool isDeferrable, - bool isDeferred, - bool isValidated, - Oid parentConstrId, - Oid relId, - const int16 *constraintKey, - int constraintNKeys, - int constraintNTotalKeys, - Oid domainId, - Oid indexRelId, - Oid foreignRelId, - const int16 *foreignKey, - const Oid *pfEqOp, - const Oid *ppEqOp, - const Oid *ffEqOp, - int foreignNKeys, - char foreignUpdateType, - char foreignDeleteType, - char foreignMatchType, - const Oid *exclOp, - Node *conExpr, - const char *conBin, - const char *conSrc, - bool conIsLocal, - int conInhCount, - bool conNoInherit, - bool is_internal); - -extern void CloneForeignKeyConstraints(Oid parentId, Oid relationId, - List **cloned); + +extern Oid CreateConstraintEntry(const char *constraintName, + Oid constraintNamespace, + char constraintType, + bool isDeferrable, + bool isDeferred, + bool isValidated, + Oid parentConstrId, + Oid relId, + const int16 *constraintKey, + int constraintNKeys, + int constraintNTotalKeys, + Oid domainId, + Oid indexRelId, + Oid foreignRelId, + const int16 *foreignKey, + const Oid *pfEqOp, + const Oid *ppEqOp, + const Oid *ffEqOp, + int foreignNKeys, + char foreignUpdateType, + char foreignDeleteType, + char foreignMatchType, + const Oid *exclOp, + Node *conExpr, + const char *conBin, + bool conIsLocal, + int conInhCount, + bool conNoInherit, + bool is_internal); extern void RemoveConstraintById(Oid conId); extern void RenameConstraintById(Oid conId, const char *newname); extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, - Oid objNamespace, const char *conname); + const char *conname); +extern bool ConstraintNameExists(const char *conname, Oid namespaceid); extern char *ChooseConstraintName(const char *name1, const char *name2, - const char *label, Oid namespaceid, - List *others); + const char *label, Oid namespaceid, + List *others); extern void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, - Oid newNspId, bool isType, ObjectAddresses *objsMoved); + Oid newNspId, bool isType, ObjectAddresses *objsMoved); extern void ConstraintSetParentConstraint(Oid childConstrId, - Oid parentConstrId); + Oid parentConstrId, + Oid childTableId); extern Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok); extern Bitmapset *get_relation_constraint_attnos(Oid relid, const char *conname, - bool missing_ok, Oid *constraintOid); + bool missing_ok, Oid *constraintOid); extern Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok); extern Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId); extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk, - Oid *constraintOid); + Oid *constraintOid); +extern void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, + AttrNumber *conkey, AttrNumber *confkey, + Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs); extern bool check_functional_grouping(Oid relid, - Index varno, Index varlevelsup, - List *grouping_columns, - List **constraintDeps); + Index varno, Index varlevelsup, + List *grouping_columns, + List **constraintDeps); #endif /* PG_CONSTRAINT_H */ diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 773d9e6ebae..ff98d9e91a8 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -5,7 +5,7 @@ * However, we define it here so that the format is documented. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_control.h @@ -15,13 +15,14 @@ #ifndef PG_CONTROL_H #define PG_CONTROL_H +#include "access/transam.h" #include "access/xlogdefs.h" #include "pgtime.h" /* for pg_time_t */ #include "port/pg_crc32c.h" /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 1100 +#define PG_CONTROL_VERSION 1201 /* Nonce key length, see below */ #define MOCK_AUTH_NONCE_LEN 32 @@ -39,8 +40,7 @@ typedef struct CheckPoint TimeLineID PrevTimeLineID; /* previous TLI, if this record begins a new * timeline (equals ThisTimeLineID otherwise) */ bool fullPageWrites; /* current full_page_writes */ - uint32 nextXidEpoch; /* higher-order bits of nextXid */ - TransactionId nextXid; /* next free XID */ + FullTransactionId nextFullXid; /* next free full transaction ID */ Oid nextOid; /* next free OID */ MultiXactId nextMulti; /* next free MultiXactId */ MultiXactOffset nextMultiOffset; /* next free MultiXact offset */ @@ -177,6 +177,7 @@ typedef struct ControlFileData bool wal_log_hints; int MaxConnections; int max_worker_processes; + int max_wal_senders; int max_prepared_xacts; int max_locks_per_xact; bool track_commit_timestamp; diff --git a/src/include/catalog/pg_conversion.dat b/src/include/catalog/pg_conversion.dat new file mode 100644 index 00000000000..2dacc59addd --- /dev/null +++ b/src/include/catalog/pg_conversion.dat @@ -0,0 +1,405 @@ +#---------------------------------------------------------------------- +# +# pg_conversion.dat +# Initial contents of the pg_conversion system catalog. +# +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/include/catalog/pg_conversion.dat +# +#---------------------------------------------------------------------- + +# Note: conforencoding and contoencoding must match the spelling of +# the labels used in the enum pg_enc in mb/pg_wchar.h. + +[ + +{ oid => '4402', descr => 'conversion for KOI8R to MULE_INTERNAL', + conname => 'koi8_r_to_mic', conforencoding => 'PG_KOI8R', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'koi8r_to_mic' }, +{ oid => '4403', descr => 'conversion for MULE_INTERNAL to KOI8R', + conname => 'mic_to_koi8_r', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_KOI8R', conproc => 'mic_to_koi8r' }, +{ oid => '4404', descr => 'conversion for ISO-8859-5 to MULE_INTERNAL', + conname => 'iso_8859_5_to_mic', conforencoding => 'PG_ISO_8859_5', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'iso_to_mic' }, +{ oid => '4405', descr => 'conversion for MULE_INTERNAL to ISO-8859-5', + conname => 'mic_to_iso_8859_5', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_ISO_8859_5', conproc => 'mic_to_iso' }, +{ oid => '4406', descr => 'conversion for WIN1251 to MULE_INTERNAL', + conname => 'windows_1251_to_mic', conforencoding => 'PG_WIN1251', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'win1251_to_mic' }, +{ oid => '4407', descr => 'conversion for MULE_INTERNAL to WIN1251', + conname => 'mic_to_windows_1251', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_WIN1251', conproc => 'mic_to_win1251' }, +{ oid => '4408', descr => 'conversion for WIN866 to MULE_INTERNAL', + conname => 'windows_866_to_mic', conforencoding => 'PG_WIN866', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'win866_to_mic' }, +{ oid => '4409', descr => 'conversion for MULE_INTERNAL to WIN866', + conname => 'mic_to_windows_866', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_WIN866', conproc => 'mic_to_win866' }, +{ oid => '4410', descr => 'conversion for KOI8R to WIN1251', + conname => 'koi8_r_to_windows_1251', conforencoding => 'PG_KOI8R', + contoencoding => 'PG_WIN1251', conproc => 'koi8r_to_win1251' }, +{ oid => '4411', descr => 'conversion for WIN1251 to KOI8R', + conname => 'windows_1251_to_koi8_r', conforencoding => 'PG_WIN1251', + contoencoding => 'PG_KOI8R', conproc => 'win1251_to_koi8r' }, +{ oid => '4412', descr => 'conversion for KOI8R to WIN866', + conname => 'koi8_r_to_windows_866', conforencoding => 'PG_KOI8R', + contoencoding => 'PG_WIN866', conproc => 'koi8r_to_win866' }, +{ oid => '4413', descr => 'conversion for WIN866 to KOI8R', + conname => 'windows_866_to_koi8_r', conforencoding => 'PG_WIN866', + contoencoding => 'PG_KOI8R', conproc => 'win866_to_koi8r' }, +{ oid => '4414', descr => 'conversion for WIN866 to WIN1251', + conname => 'windows_866_to_windows_1251', conforencoding => 'PG_WIN866', + contoencoding => 'PG_WIN1251', conproc => 'win866_to_win1251' }, +{ oid => '4415', descr => 'conversion for WIN1251 to WIN866', + conname => 'windows_1251_to_windows_866', conforencoding => 'PG_WIN1251', + contoencoding => 'PG_WIN866', conproc => 'win1251_to_win866' }, +{ oid => '4416', descr => 'conversion for ISO-8859-5 to KOI8R', + conname => 'iso_8859_5_to_koi8_r', conforencoding => 'PG_ISO_8859_5', + contoencoding => 'PG_KOI8R', conproc => 'iso_to_koi8r' }, +{ oid => '4417', descr => 'conversion for KOI8R to ISO-8859-5', + conname => 'koi8_r_to_iso_8859_5', conforencoding => 'PG_KOI8R', + contoencoding => 'PG_ISO_8859_5', conproc => 'koi8r_to_iso' }, +{ oid => '4418', descr => 'conversion for ISO-8859-5 to WIN1251', + conname => 'iso_8859_5_to_windows_1251', conforencoding => 'PG_ISO_8859_5', + contoencoding => 'PG_WIN1251', conproc => 'iso_to_win1251' }, +{ oid => '4419', descr => 'conversion for WIN1251 to ISO-8859-5', + conname => 'windows_1251_to_iso_8859_5', conforencoding => 'PG_WIN1251', + contoencoding => 'PG_ISO_8859_5', conproc => 'win1251_to_iso' }, +{ oid => '4420', descr => 'conversion for ISO-8859-5 to WIN866', + conname => 'iso_8859_5_to_windows_866', conforencoding => 'PG_ISO_8859_5', + contoencoding => 'PG_WIN866', conproc => 'iso_to_win866' }, +{ oid => '4421', descr => 'conversion for WIN866 to ISO-8859-5', + conname => 'windows_866_to_iso_8859_5', conforencoding => 'PG_WIN866', + contoencoding => 'PG_ISO_8859_5', conproc => 'win866_to_iso' }, +{ oid => '4422', descr => 'conversion for EUC_CN to MULE_INTERNAL', + conname => 'euc_cn_to_mic', conforencoding => 'PG_EUC_CN', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'euc_cn_to_mic' }, +{ oid => '4423', descr => 'conversion for MULE_INTERNAL to EUC_CN', + conname => 'mic_to_euc_cn', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_EUC_CN', conproc => 'mic_to_euc_cn' }, +{ oid => '4424', descr => 'conversion for EUC_JP to SJIS', + conname => 'euc_jp_to_sjis', conforencoding => 'PG_EUC_JP', + contoencoding => 'PG_SJIS', conproc => 'euc_jp_to_sjis' }, +{ oid => '4425', descr => 'conversion for SJIS to EUC_JP', + conname => 'sjis_to_euc_jp', conforencoding => 'PG_SJIS', + contoencoding => 'PG_EUC_JP', conproc => 'sjis_to_euc_jp' }, +{ oid => '4426', descr => 'conversion for EUC_JP to MULE_INTERNAL', + conname => 'euc_jp_to_mic', conforencoding => 'PG_EUC_JP', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'euc_jp_to_mic' }, +{ oid => '4427', descr => 'conversion for SJIS to MULE_INTERNAL', + conname => 'sjis_to_mic', conforencoding => 'PG_SJIS', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'sjis_to_mic' }, +{ oid => '4428', descr => 'conversion for MULE_INTERNAL to EUC_JP', + conname => 'mic_to_euc_jp', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_EUC_JP', conproc => 'mic_to_euc_jp' }, +{ oid => '4429', descr => 'conversion for MULE_INTERNAL to SJIS', + conname => 'mic_to_sjis', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_SJIS', conproc => 'mic_to_sjis' }, +{ oid => '4430', descr => 'conversion for EUC_KR to MULE_INTERNAL', + conname => 'euc_kr_to_mic', conforencoding => 'PG_EUC_KR', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'euc_kr_to_mic' }, +{ oid => '4431', descr => 'conversion for MULE_INTERNAL to EUC_KR', + conname => 'mic_to_euc_kr', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_EUC_KR', conproc => 'mic_to_euc_kr' }, +{ oid => '4432', descr => 'conversion for EUC_TW to BIG5', + conname => 'euc_tw_to_big5', conforencoding => 'PG_EUC_TW', + contoencoding => 'PG_BIG5', conproc => 'euc_tw_to_big5' }, +{ oid => '4433', descr => 'conversion for BIG5 to EUC_TW', + conname => 'big5_to_euc_tw', conforencoding => 'PG_BIG5', + contoencoding => 'PG_EUC_TW', conproc => 'big5_to_euc_tw' }, +{ oid => '4434', descr => 'conversion for EUC_TW to MULE_INTERNAL', + conname => 'euc_tw_to_mic', conforencoding => 'PG_EUC_TW', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'euc_tw_to_mic' }, +{ oid => '4435', descr => 'conversion for BIG5 to MULE_INTERNAL', + conname => 'big5_to_mic', conforencoding => 'PG_BIG5', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'big5_to_mic' }, +{ oid => '4436', descr => 'conversion for MULE_INTERNAL to EUC_TW', + conname => 'mic_to_euc_tw', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_EUC_TW', conproc => 'mic_to_euc_tw' }, +{ oid => '4437', descr => 'conversion for MULE_INTERNAL to BIG5', + conname => 'mic_to_big5', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_BIG5', conproc => 'mic_to_big5' }, +{ oid => '4438', descr => 'conversion for LATIN2 to MULE_INTERNAL', + conname => 'iso_8859_2_to_mic', conforencoding => 'PG_LATIN2', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'latin2_to_mic' }, +{ oid => '4439', descr => 'conversion for MULE_INTERNAL to LATIN2', + conname => 'mic_to_iso_8859_2', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_LATIN2', conproc => 'mic_to_latin2' }, +{ oid => '4440', descr => 'conversion for WIN1250 to MULE_INTERNAL', + conname => 'windows_1250_to_mic', conforencoding => 'PG_WIN1250', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'win1250_to_mic' }, +{ oid => '4441', descr => 'conversion for MULE_INTERNAL to WIN1250', + conname => 'mic_to_windows_1250', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_WIN1250', conproc => 'mic_to_win1250' }, +{ oid => '4442', descr => 'conversion for LATIN2 to WIN1250', + conname => 'iso_8859_2_to_windows_1250', conforencoding => 'PG_LATIN2', + contoencoding => 'PG_WIN1250', conproc => 'latin2_to_win1250' }, +{ oid => '4443', descr => 'conversion for WIN1250 to LATIN2', + conname => 'windows_1250_to_iso_8859_2', conforencoding => 'PG_WIN1250', + contoencoding => 'PG_LATIN2', conproc => 'win1250_to_latin2' }, +{ oid => '4444', descr => 'conversion for LATIN1 to MULE_INTERNAL', + conname => 'iso_8859_1_to_mic', conforencoding => 'PG_LATIN1', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'latin1_to_mic' }, +{ oid => '4445', descr => 'conversion for MULE_INTERNAL to LATIN1', + conname => 'mic_to_iso_8859_1', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_LATIN1', conproc => 'mic_to_latin1' }, +{ oid => '4446', descr => 'conversion for LATIN3 to MULE_INTERNAL', + conname => 'iso_8859_3_to_mic', conforencoding => 'PG_LATIN3', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'latin3_to_mic' }, +{ oid => '4447', descr => 'conversion for MULE_INTERNAL to LATIN3', + conname => 'mic_to_iso_8859_3', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_LATIN3', conproc => 'mic_to_latin3' }, +{ oid => '4448', descr => 'conversion for LATIN4 to MULE_INTERNAL', + conname => 'iso_8859_4_to_mic', conforencoding => 'PG_LATIN4', + contoencoding => 'PG_MULE_INTERNAL', conproc => 'latin4_to_mic' }, +{ oid => '4449', descr => 'conversion for MULE_INTERNAL to LATIN4', + conname => 'mic_to_iso_8859_4', conforencoding => 'PG_MULE_INTERNAL', + contoencoding => 'PG_LATIN4', conproc => 'mic_to_latin4' }, +{ oid => '4452', descr => 'conversion for BIG5 to UTF8', + conname => 'big5_to_utf8', conforencoding => 'PG_BIG5', + contoencoding => 'PG_UTF8', conproc => 'big5_to_utf8' }, +{ oid => '4453', descr => 'conversion for UTF8 to BIG5', + conname => 'utf8_to_big5', conforencoding => 'PG_UTF8', + contoencoding => 'PG_BIG5', conproc => 'utf8_to_big5' }, +{ oid => '4454', descr => 'conversion for UTF8 to KOI8R', + conname => 'utf8_to_koi8_r', conforencoding => 'PG_UTF8', + contoencoding => 'PG_KOI8R', conproc => 'utf8_to_koi8r' }, +{ oid => '4455', descr => 'conversion for KOI8R to UTF8', + conname => 'koi8_r_to_utf8', conforencoding => 'PG_KOI8R', + contoencoding => 'PG_UTF8', conproc => 'koi8r_to_utf8' }, +{ oid => '4456', descr => 'conversion for UTF8 to KOI8U', + conname => 'utf8_to_koi8_u', conforencoding => 'PG_UTF8', + contoencoding => 'PG_KOI8U', conproc => 'utf8_to_koi8u' }, +{ oid => '4457', descr => 'conversion for KOI8U to UTF8', + conname => 'koi8_u_to_utf8', conforencoding => 'PG_KOI8U', + contoencoding => 'PG_UTF8', conproc => 'koi8u_to_utf8' }, +{ oid => '4458', descr => 'conversion for UTF8 to WIN866', + conname => 'utf8_to_windows_866', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN866', conproc => 'utf8_to_win' }, +{ oid => '4459', descr => 'conversion for WIN866 to UTF8', + conname => 'windows_866_to_utf8', conforencoding => 'PG_WIN866', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4460', descr => 'conversion for UTF8 to WIN874', + conname => 'utf8_to_windows_874', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN874', conproc => 'utf8_to_win' }, +{ oid => '4461', descr => 'conversion for WIN874 to UTF8', + conname => 'windows_874_to_utf8', conforencoding => 'PG_WIN874', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4462', descr => 'conversion for UTF8 to WIN1250', + conname => 'utf8_to_windows_1250', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1250', conproc => 'utf8_to_win' }, +{ oid => '4463', descr => 'conversion for WIN1250 to UTF8', + conname => 'windows_1250_to_utf8', conforencoding => 'PG_WIN1250', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4464', descr => 'conversion for UTF8 to WIN1251', + conname => 'utf8_to_windows_1251', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1251', conproc => 'utf8_to_win' }, +{ oid => '4465', descr => 'conversion for WIN1251 to UTF8', + conname => 'windows_1251_to_utf8', conforencoding => 'PG_WIN1251', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4466', descr => 'conversion for UTF8 to WIN1252', + conname => 'utf8_to_windows_1252', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1252', conproc => 'utf8_to_win' }, +{ oid => '4467', descr => 'conversion for WIN1252 to UTF8', + conname => 'windows_1252_to_utf8', conforencoding => 'PG_WIN1252', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4468', descr => 'conversion for UTF8 to WIN1253', + conname => 'utf8_to_windows_1253', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1253', conproc => 'utf8_to_win' }, +{ oid => '4469', descr => 'conversion for WIN1253 to UTF8', + conname => 'windows_1253_to_utf8', conforencoding => 'PG_WIN1253', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4470', descr => 'conversion for UTF8 to WIN1254', + conname => 'utf8_to_windows_1254', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1254', conproc => 'utf8_to_win' }, +{ oid => '4471', descr => 'conversion for WIN1254 to UTF8', + conname => 'windows_1254_to_utf8', conforencoding => 'PG_WIN1254', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4472', descr => 'conversion for UTF8 to WIN1255', + conname => 'utf8_to_windows_1255', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1255', conproc => 'utf8_to_win' }, +{ oid => '4473', descr => 'conversion for WIN1255 to UTF8', + conname => 'windows_1255_to_utf8', conforencoding => 'PG_WIN1255', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4474', descr => 'conversion for UTF8 to WIN1256', + conname => 'utf8_to_windows_1256', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1256', conproc => 'utf8_to_win' }, +{ oid => '4475', descr => 'conversion for WIN1256 to UTF8', + conname => 'windows_1256_to_utf8', conforencoding => 'PG_WIN1256', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4476', descr => 'conversion for UTF8 to WIN1257', + conname => 'utf8_to_windows_1257', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1257', conproc => 'utf8_to_win' }, +{ oid => '4477', descr => 'conversion for WIN1257 to UTF8', + conname => 'windows_1257_to_utf8', conforencoding => 'PG_WIN1257', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4478', descr => 'conversion for UTF8 to WIN1258', + conname => 'utf8_to_windows_1258', conforencoding => 'PG_UTF8', + contoencoding => 'PG_WIN1258', conproc => 'utf8_to_win' }, +{ oid => '4479', descr => 'conversion for WIN1258 to UTF8', + conname => 'windows_1258_to_utf8', conforencoding => 'PG_WIN1258', + contoencoding => 'PG_UTF8', conproc => 'win_to_utf8' }, +{ oid => '4480', descr => 'conversion for EUC_CN to UTF8', + conname => 'euc_cn_to_utf8', conforencoding => 'PG_EUC_CN', + contoencoding => 'PG_UTF8', conproc => 'euc_cn_to_utf8' }, +{ oid => '4481', descr => 'conversion for UTF8 to EUC_CN', + conname => 'utf8_to_euc_cn', conforencoding => 'PG_UTF8', + contoencoding => 'PG_EUC_CN', conproc => 'utf8_to_euc_cn' }, +{ oid => '4482', descr => 'conversion for EUC_JP to UTF8', + conname => 'euc_jp_to_utf8', conforencoding => 'PG_EUC_JP', + contoencoding => 'PG_UTF8', conproc => 'euc_jp_to_utf8' }, +{ oid => '4483', descr => 'conversion for UTF8 to EUC_JP', + conname => 'utf8_to_euc_jp', conforencoding => 'PG_UTF8', + contoencoding => 'PG_EUC_JP', conproc => 'utf8_to_euc_jp' }, +{ oid => '4484', descr => 'conversion for EUC_KR to UTF8', + conname => 'euc_kr_to_utf8', conforencoding => 'PG_EUC_KR', + contoencoding => 'PG_UTF8', conproc => 'euc_kr_to_utf8' }, +{ oid => '4485', descr => 'conversion for UTF8 to EUC_KR', + conname => 'utf8_to_euc_kr', conforencoding => 'PG_UTF8', + contoencoding => 'PG_EUC_KR', conproc => 'utf8_to_euc_kr' }, +{ oid => '4486', descr => 'conversion for EUC_TW to UTF8', + conname => 'euc_tw_to_utf8', conforencoding => 'PG_EUC_TW', + contoencoding => 'PG_UTF8', conproc => 'euc_tw_to_utf8' }, +{ oid => '4487', descr => 'conversion for UTF8 to EUC_TW', + conname => 'utf8_to_euc_tw', conforencoding => 'PG_UTF8', + contoencoding => 'PG_EUC_TW', conproc => 'utf8_to_euc_tw' }, +{ oid => '4488', descr => 'conversion for GB18030 to UTF8', + conname => 'gb18030_to_utf8', conforencoding => 'PG_GB18030', + contoencoding => 'PG_UTF8', conproc => 'gb18030_to_utf8' }, +{ oid => '4489', descr => 'conversion for UTF8 to GB18030', + conname => 'utf8_to_gb18030', conforencoding => 'PG_UTF8', + contoencoding => 'PG_GB18030', conproc => 'utf8_to_gb18030' }, +{ oid => '4490', descr => 'conversion for GBK to UTF8', + conname => 'gbk_to_utf8', conforencoding => 'PG_GBK', + contoencoding => 'PG_UTF8', conproc => 'gbk_to_utf8' }, +{ oid => '4491', descr => 'conversion for UTF8 to GBK', + conname => 'utf8_to_gbk', conforencoding => 'PG_UTF8', + contoencoding => 'PG_GBK', conproc => 'utf8_to_gbk' }, +{ oid => '4492', descr => 'conversion for UTF8 to LATIN2', + conname => 'utf8_to_iso_8859_2', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN2', conproc => 'utf8_to_iso8859' }, +{ oid => '4493', descr => 'conversion for LATIN2 to UTF8', + conname => 'iso_8859_2_to_utf8', conforencoding => 'PG_LATIN2', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4494', descr => 'conversion for UTF8 to LATIN3', + conname => 'utf8_to_iso_8859_3', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN3', conproc => 'utf8_to_iso8859' }, +{ oid => '4495', descr => 'conversion for LATIN3 to UTF8', + conname => 'iso_8859_3_to_utf8', conforencoding => 'PG_LATIN3', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4496', descr => 'conversion for UTF8 to LATIN4', + conname => 'utf8_to_iso_8859_4', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN4', conproc => 'utf8_to_iso8859' }, +{ oid => '4497', descr => 'conversion for LATIN4 to UTF8', + conname => 'iso_8859_4_to_utf8', conforencoding => 'PG_LATIN4', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4498', descr => 'conversion for UTF8 to LATIN5', + conname => 'utf8_to_iso_8859_9', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN5', conproc => 'utf8_to_iso8859' }, +{ oid => '4499', descr => 'conversion for LATIN5 to UTF8', + conname => 'iso_8859_9_to_utf8', conforencoding => 'PG_LATIN5', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4500', descr => 'conversion for UTF8 to LATIN6', + conname => 'utf8_to_iso_8859_10', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN6', conproc => 'utf8_to_iso8859' }, +{ oid => '4501', descr => 'conversion for LATIN6 to UTF8', + conname => 'iso_8859_10_to_utf8', conforencoding => 'PG_LATIN6', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4502', descr => 'conversion for UTF8 to LATIN7', + conname => 'utf8_to_iso_8859_13', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN7', conproc => 'utf8_to_iso8859' }, +{ oid => '4503', descr => 'conversion for LATIN7 to UTF8', + conname => 'iso_8859_13_to_utf8', conforencoding => 'PG_LATIN7', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4504', descr => 'conversion for UTF8 to LATIN8', + conname => 'utf8_to_iso_8859_14', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN8', conproc => 'utf8_to_iso8859' }, +{ oid => '4505', descr => 'conversion for LATIN8 to UTF8', + conname => 'iso_8859_14_to_utf8', conforencoding => 'PG_LATIN8', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4506', descr => 'conversion for UTF8 to LATIN9', + conname => 'utf8_to_iso_8859_15', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN9', conproc => 'utf8_to_iso8859' }, +{ oid => '4507', descr => 'conversion for LATIN9 to UTF8', + conname => 'iso_8859_15_to_utf8', conforencoding => 'PG_LATIN9', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4508', descr => 'conversion for UTF8 to LATIN10', + conname => 'utf8_to_iso_8859_16', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN10', conproc => 'utf8_to_iso8859' }, +{ oid => '4509', descr => 'conversion for LATIN10 to UTF8', + conname => 'iso_8859_16_to_utf8', conforencoding => 'PG_LATIN10', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4510', descr => 'conversion for UTF8 to ISO-8859-5', + conname => 'utf8_to_iso_8859_5', conforencoding => 'PG_UTF8', + contoencoding => 'PG_ISO_8859_5', conproc => 'utf8_to_iso8859' }, +{ oid => '4511', descr => 'conversion for ISO-8859-5 to UTF8', + conname => 'iso_8859_5_to_utf8', conforencoding => 'PG_ISO_8859_5', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4512', descr => 'conversion for UTF8 to ISO-8859-6', + conname => 'utf8_to_iso_8859_6', conforencoding => 'PG_UTF8', + contoencoding => 'PG_ISO_8859_6', conproc => 'utf8_to_iso8859' }, +{ oid => '4513', descr => 'conversion for ISO-8859-6 to UTF8', + conname => 'iso_8859_6_to_utf8', conforencoding => 'PG_ISO_8859_6', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4514', descr => 'conversion for UTF8 to ISO-8859-7', + conname => 'utf8_to_iso_8859_7', conforencoding => 'PG_UTF8', + contoencoding => 'PG_ISO_8859_7', conproc => 'utf8_to_iso8859' }, +{ oid => '4515', descr => 'conversion for ISO-8859-7 to UTF8', + conname => 'iso_8859_7_to_utf8', conforencoding => 'PG_ISO_8859_7', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4516', descr => 'conversion for UTF8 to ISO-8859-8', + conname => 'utf8_to_iso_8859_8', conforencoding => 'PG_UTF8', + contoencoding => 'PG_ISO_8859_8', conproc => 'utf8_to_iso8859' }, +{ oid => '4517', descr => 'conversion for ISO-8859-8 to UTF8', + conname => 'iso_8859_8_to_utf8', conforencoding => 'PG_ISO_8859_8', + contoencoding => 'PG_UTF8', conproc => 'iso8859_to_utf8' }, +{ oid => '4518', descr => 'conversion for LATIN1 to UTF8', + conname => 'iso_8859_1_to_utf8', conforencoding => 'PG_LATIN1', + contoencoding => 'PG_UTF8', conproc => 'iso8859_1_to_utf8' }, +{ oid => '4519', descr => 'conversion for UTF8 to LATIN1', + conname => 'utf8_to_iso_8859_1', conforencoding => 'PG_UTF8', + contoencoding => 'PG_LATIN1', conproc => 'utf8_to_iso8859_1' }, +{ oid => '4520', descr => 'conversion for JOHAB to UTF8', + conname => 'johab_to_utf8', conforencoding => 'PG_JOHAB', + contoencoding => 'PG_UTF8', conproc => 'johab_to_utf8' }, +{ oid => '4521', descr => 'conversion for UTF8 to JOHAB', + conname => 'utf8_to_johab', conforencoding => 'PG_UTF8', + contoencoding => 'PG_JOHAB', conproc => 'utf8_to_johab' }, +{ oid => '4522', descr => 'conversion for SJIS to UTF8', + conname => 'sjis_to_utf8', conforencoding => 'PG_SJIS', + contoencoding => 'PG_UTF8', conproc => 'sjis_to_utf8' }, +{ oid => '4523', descr => 'conversion for UTF8 to SJIS', + conname => 'utf8_to_sjis', conforencoding => 'PG_UTF8', + contoencoding => 'PG_SJIS', conproc => 'utf8_to_sjis' }, +{ oid => '4524', descr => 'conversion for UHC to UTF8', + conname => 'uhc_to_utf8', conforencoding => 'PG_UHC', + contoencoding => 'PG_UTF8', conproc => 'uhc_to_utf8' }, +{ oid => '4525', descr => 'conversion for UTF8 to UHC', + conname => 'utf8_to_uhc', conforencoding => 'PG_UTF8', + contoencoding => 'PG_UHC', conproc => 'utf8_to_uhc' }, +{ oid => '4526', descr => 'conversion for EUC_JIS_2004 to UTF8', + conname => 'euc_jis_2004_to_utf8', conforencoding => 'PG_EUC_JIS_2004', + contoencoding => 'PG_UTF8', conproc => 'euc_jis_2004_to_utf8' }, +{ oid => '4527', descr => 'conversion for UTF8 to EUC_JIS_2004', + conname => 'utf8_to_euc_jis_2004', conforencoding => 'PG_UTF8', + contoencoding => 'PG_EUC_JIS_2004', conproc => 'utf8_to_euc_jis_2004' }, +{ oid => '4528', descr => 'conversion for SHIFT_JIS_2004 to UTF8', + conname => 'shift_jis_2004_to_utf8', conforencoding => 'PG_SHIFT_JIS_2004', + contoencoding => 'PG_UTF8', conproc => 'shift_jis_2004_to_utf8' }, +{ oid => '4529', descr => 'conversion for UTF8 to SHIFT_JIS_2004', + conname => 'utf8_to_shift_jis_2004', conforencoding => 'PG_UTF8', + contoencoding => 'PG_SHIFT_JIS_2004', conproc => 'utf8_to_shift_jis_2004' }, +{ oid => '4530', descr => 'conversion for EUC_JIS_2004 to SHIFT_JIS_2004', + conname => 'euc_jis_2004_to_shift_jis_2004', + conforencoding => 'PG_EUC_JIS_2004', contoencoding => 'PG_SHIFT_JIS_2004', + conproc => 'euc_jis_2004_to_shift_jis_2004' }, +{ oid => '4531', descr => 'conversion for SHIFT_JIS_2004 to EUC_JIS_2004', + conname => 'shift_jis_2004_to_euc_jis_2004', + conforencoding => 'PG_SHIFT_JIS_2004', contoencoding => 'PG_EUC_JIS_2004', + conproc => 'shift_jis_2004_to_euc_jis_2004' }, + +] diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h index 7ca54e84306..49c70700ab7 100644 --- a/src/include/catalog/pg_conversion.h +++ b/src/include/catalog/pg_conversion.h @@ -1,10 +1,9 @@ /*------------------------------------------------------------------------- * * pg_conversion.h - * definition of the system "conversion" relation (pg_conversion) + * definition of the "conversion" system catalog (pg_conversion) * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_conversion.h @@ -23,29 +22,36 @@ #include "catalog/objectaddress.h" -/* ---------------------------------------------------------------- - * pg_conversion definition. - * - * cpp turns this into typedef struct FormData_pg_namespace - * - * conname name of the conversion - * connamespace name space which the conversion belongs to - * conowner owner of the conversion - * conforencoding FOR encoding id - * contoencoding TO encoding id - * conproc OID of the conversion proc - * condefault true if this is a default conversion - * ---------------------------------------------------------------- +/* ---------------- + * pg_conversion definition. cpp turns this into + * typedef struct FormData_pg_conversion + * ---------------- */ CATALOG(pg_conversion,2607,ConversionRelationId) { + /* oid */ + Oid oid; + + /* name of the conversion */ NameData conname; - Oid connamespace; - Oid conowner; - int32 conforencoding; - int32 contoencoding; - regproc conproc; - bool condefault; + + /* namespace that the conversion belongs to */ + Oid connamespace BKI_DEFAULT(PGNSP); + + /* owner of the conversion */ + Oid conowner BKI_DEFAULT(PGUID); + + /* FOR encoding id */ + int32 conforencoding BKI_LOOKUP(encoding); + + /* TO encoding id */ + int32 contoencoding BKI_LOOKUP(encoding); + + /* OID of the conversion proc */ + regproc conproc BKI_LOOKUP(pg_proc); + + /* true if this is a default conversion */ + bool condefault BKI_DEFAULT(t); } FormData_pg_conversion; /* ---------------- @@ -57,11 +63,11 @@ typedef FormData_pg_conversion *Form_pg_conversion; extern ObjectAddress ConversionCreate(const char *conname, Oid connamespace, - Oid conowner, - int32 conforencoding, int32 contoencoding, - Oid conproc, bool def); + Oid conowner, + int32 conforencoding, int32 contoencoding, + Oid conproc, bool def); extern void RemoveConversionById(Oid conversionOid); -extern Oid FindDefaultConversion(Oid connamespace, int32 for_encoding, - int32 to_encoding); +extern Oid FindDefaultConversion(Oid connamespace, int32 for_encoding, + int32 to_encoding); #endif /* PG_CONVERSION_H */ diff --git a/src/include/catalog/pg_database.dat b/src/include/catalog/pg_database.dat index 957ca8408a5..89bd75d0243 100644 --- a/src/include/catalog/pg_database.dat +++ b/src/include/catalog/pg_database.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_database.dat -# Initial contents of the pg_database system relation. +# Initial contents of the pg_database system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_database.dat @@ -12,15 +12,11 @@ [ -# LC_COLLATE and LC_CTYPE will be replaced at initdb time with user choices -# that might contain non-word characters, so we must double-quote them. - { oid => '1', oid_symbol => 'TemplateDbOid', descr => 'default template for new databases', - datname => 'template1', datdba => 'PGUID', encoding => 'ENCODING', - datcollate => '"LC_COLLATE"', datctype => '"LC_CTYPE"', datistemplate => 't', - datallowconn => 't', datconnlimit => '-1', datlastsysoid => '0', - datfrozenxid => '0', datminmxid => '1', dattablespace => '1663', - datacl => '_null_' }, + datname => 'template1', encoding => 'ENCODING', datcollate => 'LC_COLLATE', + datctype => 'LC_CTYPE', datistemplate => 't', datallowconn => 't', + datconnlimit => '-1', datlastsysoid => '0', datfrozenxid => '0', + datminmxid => '1', dattablespace => 'pg_default', datacl => '_null_' }, ] diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h index 7f03d24c1e9..06fea45f53a 100644 --- a/src/include/catalog/pg_database.h +++ b/src/include/catalog/pg_database.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_database.h - * definition of the system "database" relation (pg_database) + * definition of the "database" system catalog (pg_database) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_database.h @@ -28,21 +28,48 @@ */ CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248,DatabaseRelation_Rowtype_Id) BKI_SCHEMA_MACRO { - NameData datname; /* database name */ - Oid datdba; /* owner of database */ - int32 encoding; /* character encoding */ - NameData datcollate; /* LC_COLLATE setting */ - NameData datctype; /* LC_CTYPE setting */ - bool datistemplate; /* allowed as CREATE DATABASE template? */ - bool datallowconn; /* new connections allowed? */ - int32 datconnlimit; /* max connections allowed (-1=no limit) */ - Oid datlastsysoid; /* highest OID to consider a system OID */ - TransactionId datfrozenxid; /* all Xids < this are frozen in this DB */ - TransactionId datminmxid; /* all multixacts in the DB are >= this */ - Oid dattablespace; /* default table space for this DB */ + /* oid */ + Oid oid; + + /* database name */ + NameData datname; + + /* owner of database */ + Oid datdba BKI_DEFAULT(PGUID); + + /* character encoding */ + int32 encoding; + + /* LC_COLLATE setting */ + NameData datcollate; + + /* LC_CTYPE setting */ + NameData datctype; + + /* allowed as CREATE DATABASE template? */ + bool datistemplate; + + /* new connections allowed? */ + bool datallowconn; + + /* max connections allowed (-1=no limit) */ + int32 datconnlimit; + + /* highest OID to consider a system OID */ + Oid datlastsysoid; + + /* all Xids < this are frozen in this DB */ + TransactionId datfrozenxid; + + /* all multixacts in the DB are >= this */ + TransactionId datminmxid; + + /* default table space for this DB */ + Oid dattablespace BKI_LOOKUP(pg_tablespace); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem datacl[1]; /* access permissions */ + /* access permissions */ + aclitem datacl[1]; #endif } FormData_pg_database; diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h index f6ae9712193..078586d841d 100644 --- a/src/include/catalog/pg_db_role_setting.h +++ b/src/include/catalog/pg_db_role_setting.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_db_role_setting.h - * definition of per-database/per-user configuration settings relation + * definition of the system catalog for per-database/per-user + * configuration settings (pg_db_role_setting) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_db_role_setting.h @@ -30,7 +31,7 @@ * typedef struct FormData_pg_db_role_setting * ---------------- */ -CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION { Oid setdatabase; /* database */ Oid setrole; /* role */ @@ -48,6 +49,6 @@ typedef FormData_pg_db_role_setting * Form_pg_db_role_setting; extern void AlterSetting(Oid databaseid, Oid roleid, VariableSetStmt *setstmt); extern void DropSetting(Oid databaseid, Oid roleid); extern void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, - Relation relsetting, GucSource source); + Relation relsetting, GucSource source); #endif /* PG_DB_ROLE_SETTING_H */ diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h index d672d5b3f88..601b11e11c5 100644 --- a/src/include/catalog/pg_default_acl.h +++ b/src/include/catalog/pg_default_acl.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_default_acl.h - * definition of default ACLs for new objects. + * definition of the system catalog for default ACLs of new objects + * (pg_default_acl) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_default_acl.h @@ -28,12 +29,14 @@ */ CATALOG(pg_default_acl,826,DefaultAclRelationId) { + Oid oid; /* oid */ Oid defaclrole; /* OID of role owning this ACL */ Oid defaclnamespace; /* OID of namespace, or 0 for all */ char defaclobjtype; /* see DEFACLOBJ_xxx constants below */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem defaclacl[1]; /* permissions to add at CREATE time */ + aclitem defaclacl[1] BKI_FORCE_NOT_NULL; /* permissions to add at + * CREATE time */ #endif } FormData_pg_default_acl; diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h index bf31c1ab408..f786445fb29 100644 --- a/src/include/catalog/pg_depend.h +++ b/src/include/catalog/pg_depend.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_depend.h - * definition of the system "dependency" relation (pg_depend) + * definition of the "dependency" system catalog (pg_depend) * * pg_depend has no preloaded contents, so there is no pg_depend.dat * file; system-defined dependencies are loaded into it during a late stage @@ -16,7 +16,7 @@ * convenient to find from the contents of other catalogs. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_depend.h @@ -38,7 +38,7 @@ * typedef struct FormData_pg_depend * ---------------- */ -CATALOG(pg_depend,2608,DependRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_depend,2608,DependRelationId) { /* * Identification of the dependent (referencing) object. diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h index b95b188d289..bdf72b09d4c 100644 --- a/src/include/catalog/pg_description.h +++ b/src/include/catalog/pg_description.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_description.h - * definition of the system "description" relation (pg_description) + * definition of the "description" system catalog (pg_description) * * Because the contents of this table are taken from the *.dat files * of other catalogs, there is no pg_description.dat file. The initial @@ -23,7 +23,7 @@ * for example). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_description.h @@ -45,7 +45,7 @@ * typedef struct FormData_pg_description * ---------------- */ -CATALOG(pg_description,2609,DescriptionRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_description,2609,DescriptionRelationId) { Oid objoid; /* OID of object itself */ Oid classoid; /* OID of table containing object */ diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h index 52ec55debd1..e963cea0b28 100644 --- a/src/include/catalog/pg_enum.h +++ b/src/include/catalog/pg_enum.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_enum.h - * definition of the system "enum" relation (pg_enum) + * definition of the "enum" system catalog (pg_enum) * * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_enum.h * @@ -29,6 +30,7 @@ */ CATALOG(pg_enum,3501,EnumRelationId) { + Oid oid; /* oid */ Oid enumtypid; /* OID of owning enum type */ float4 enumsortorder; /* sort position of this enum value */ NameData enumlabel; /* text representation of enum value */ @@ -47,9 +49,14 @@ typedef FormData_pg_enum *Form_pg_enum; extern void EnumValuesCreate(Oid enumTypeOid, List *vals); extern void EnumValuesDelete(Oid enumTypeOid); extern void AddEnumLabel(Oid enumTypeOid, const char *newVal, - const char *neighbor, bool newValIsAfter, - bool skipIfExists); + const char *neighbor, bool newValIsAfter, + bool skipIfExists); extern void RenameEnumLabel(Oid enumTypeOid, - const char *oldVal, const char *newVal); + const char *oldVal, const char *newVal); +extern bool EnumBlacklisted(Oid enum_id); +extern Size EstimateEnumBlacklistSpace(void); +extern void SerializeEnumBlacklist(void *space, Size size); +extern void RestoreEnumBlacklist(void *space); +extern void AtEOXact_Enum(void); #endif /* PG_ENUM_H */ diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h index f06cbe04dc1..0c955631925 100644 --- a/src/include/catalog/pg_event_trigger.h +++ b/src/include/catalog/pg_event_trigger.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_event_trigger.h - * definition of the system "event trigger" relation (pg_event_trigger) + * definition of the "event trigger" system catalog (pg_event_trigger) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_event_trigger.h @@ -28,6 +28,7 @@ */ CATALOG(pg_event_trigger,3466,EventTriggerRelationId) { + Oid oid; /* oid */ NameData evtname; /* trigger's name */ NameData evtevent; /* trigger's event */ Oid evtowner; /* trigger's owner */ diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h index 10bbb692a5d..9bdf06da313 100644 --- a/src/include/catalog/pg_extension.h +++ b/src/include/catalog/pg_extension.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_extension.h - * definition of the system "extension" relation (pg_extension) + * definition of the "extension" system catalog (pg_extension) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_extension.h @@ -28,6 +28,7 @@ */ CATALOG(pg_extension,3079,ExtensionRelationId) { + Oid oid; /* oid */ NameData extname; /* extension name */ Oid extowner; /* extension owner */ Oid extnamespace; /* namespace of contained objects */ diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h index 67e331987cf..3f0cef33b44 100644 --- a/src/include/catalog/pg_foreign_data_wrapper.h +++ b/src/include/catalog/pg_foreign_data_wrapper.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_foreign_data_wrapper.h - * definition of the system "foreign-data wrapper" relation (pg_foreign_data_wrapper) + * definition of the "foreign-data wrapper" system catalog (pg_foreign_data_wrapper) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_data_wrapper.h @@ -28,6 +28,7 @@ */ CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId) { + Oid oid; /* oid */ NameData fdwname; /* foreign-data wrapper name */ Oid fdwowner; /* FDW owner */ Oid fdwhandler; /* handler function, or 0 if none */ @@ -40,8 +41,8 @@ CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId) } FormData_pg_foreign_data_wrapper; /* ---------------- - * Form_pg_fdw corresponds to a pointer to a tuple with - * the format of pg_fdw relation. + * Form_pg_foreign_data_wrapper corresponds to a pointer to a tuple with + * the format of pg_foreign_data_wrapper relation. * ---------------- */ typedef FormData_pg_foreign_data_wrapper *Form_pg_foreign_data_wrapper; diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h index 0d25839c3da..bc155cd2d01 100644 --- a/src/include/catalog/pg_foreign_server.h +++ b/src/include/catalog/pg_foreign_server.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * pg_foreign_server.h - * definition of the system "foreign server" relation (pg_foreign_server) + * definition of the "foreign server" system catalog (pg_foreign_server) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_server.h @@ -27,6 +27,7 @@ */ CATALOG(pg_foreign_server,1417,ForeignServerRelationId) { + Oid oid; /* oid */ NameData srvname; /* foreign server name */ Oid srvowner; /* server owner */ Oid srvfdw; /* server FDW */ diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h index 13de918880f..1b77996ef84 100644 --- a/src/include/catalog/pg_foreign_table.h +++ b/src/include/catalog/pg_foreign_table.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * pg_foreign_table.h - * definition of the system "foreign table" relation (pg_foreign_table) + * definition of the "foreign table" system catalog (pg_foreign_table) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_foreign_table.h @@ -25,7 +25,7 @@ * typedef struct FormData_pg_foreign_table * ---------------- */ -CATALOG(pg_foreign_table,3118,ForeignTableRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_foreign_table,3118,ForeignTableRelationId) { Oid ftrelid; /* OID of foreign table */ Oid ftserver; /* OID of foreign server */ diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h index 88ff40f8207..24383740786 100644 --- a/src/include/catalog/pg_index.h +++ b/src/include/catalog/pg_index.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_index.h - * definition of the system "index" relation (pg_index) + * definition of the "index" system catalog (pg_index) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_index.h @@ -26,7 +26,7 @@ * typedef struct FormData_pg_index. * ---------------- */ -CATALOG(pg_index,2610,IndexRelationId) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO +CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO { Oid indexrelid; /* OID of the index */ Oid indrelid; /* OID of the relation it indexes */ @@ -77,13 +77,4 @@ typedef FormData_pg_index *Form_pg_index; #endif /* EXPOSE_TO_CLIENT_CODE */ -/* - * Use of these macros is recommended over direct examination of the state - * flag columns where possible; this allows source code compatibility with - * the hacky representation used in 9.2. - */ -#define IndexIsValid(indexForm) ((indexForm)->indisvalid) -#define IndexIsReady(indexForm) ((indexForm)->indisready) -#define IndexIsLive(indexForm) ((indexForm)->indislive) - #endif /* PG_INDEX_H */ diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h index 3303a9c2973..a2061ef7875 100644 --- a/src/include/catalog/pg_inherits.h +++ b/src/include/catalog/pg_inherits.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_inherits.h - * definition of the system "inherits" relation (pg_inherits) + * definition of the "inherits" system catalog (pg_inherits) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_inherits.h @@ -29,7 +29,7 @@ * typedef struct FormData_pg_inherits * ---------------- */ -CATALOG(pg_inherits,2611,InheritsRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_inherits,2611,InheritsRelationId) { Oid inhrelid; Oid inhparent; @@ -46,12 +46,12 @@ typedef FormData_pg_inherits *Form_pg_inherits; extern List *find_inheritance_children(Oid parentrelId, LOCKMODE lockmode); extern List *find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, - List **parents); + List **parents); extern bool has_subclass(Oid relationId); extern bool has_superclass(Oid relationId); extern bool typeInheritsFrom(Oid subclassTypeId, Oid superclassTypeId); extern void StoreSingleInheritance(Oid relationId, Oid parentOid, - int32 seqNumber); + int32 seqNumber); extern bool DeleteInheritsTuple(Oid inhrelid, Oid inhparent); #endif /* PG_INHERITS_H */ diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h index 6ce26463507..f1c9776b033 100644 --- a/src/include/catalog/pg_init_privs.h +++ b/src/include/catalog/pg_init_privs.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_init_privs.h - * definition of the system "initial privileges" relation (pg_init_privs) + * definition of the "initial privileges" system catalog (pg_init_privs) * * NOTE: an object is identified by the OID of the row that primarily * defines the object, plus the OID of the table that that row appears in. @@ -21,7 +21,7 @@ * are loaded near the end of initdb. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_init_privs.h @@ -43,7 +43,7 @@ * typedef struct FormData_pg_init_privs * ---------------- */ -CATALOG(pg_init_privs,3394,InitPrivsRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_init_privs,3394,InitPrivsRelationId) { Oid objoid; /* OID of object itself */ Oid classoid; /* OID of table containing object */ diff --git a/src/include/catalog/pg_language.dat b/src/include/catalog/pg_language.dat index 1b50a66ea48..02dde38a1ca 100644 --- a/src/include/catalog/pg_language.dat +++ b/src/include/catalog/pg_language.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_language.dat -# Initial contents of the pg_language system relation. +# Initial contents of the pg_language system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_language.dat @@ -14,18 +14,12 @@ { oid => '12', oid_symbol => 'INTERNALlanguageId', descr => 'built-in functions', - lanname => 'internal', lanowner => 'PGUID', lanispl => 'f', - lanpltrusted => 'f', lanplcallfoid => '0', laninline => '0', - lanvalidator => '2246', lanacl => '_null_' }, + lanname => 'internal', lanvalidator => 'fmgr_internal_validator' }, { oid => '13', oid_symbol => 'ClanguageId', descr => 'dynamically-loaded C functions', - lanname => 'c', lanowner => 'PGUID', lanispl => 'f', lanpltrusted => 'f', - lanplcallfoid => '0', laninline => '0', lanvalidator => '2247', - lanacl => '_null_' }, + lanname => 'c', lanvalidator => 'fmgr_c_validator' }, { oid => '14', oid_symbol => 'SQLlanguageId', descr => 'SQL-language functions', - lanname => 'sql', lanowner => 'PGUID', lanispl => 'f', lanpltrusted => 't', - lanplcallfoid => '0', laninline => '0', lanvalidator => '2248', - lanacl => '_null_' }, + lanname => 'sql', lanpltrusted => 't', lanvalidator => 'fmgr_sql_validator' }, ] diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h index e2d8d1571b4..8aaba6ad208 100644 --- a/src/include/catalog/pg_language.h +++ b/src/include/catalog/pg_language.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_language.h - * definition of the system "language" relation (pg_language) + * definition of the "language" system catalog (pg_language) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_language.h @@ -28,16 +28,32 @@ */ CATALOG(pg_language,2612,LanguageRelationId) { - NameData lanname; /* Language name */ - Oid lanowner; /* Language's owner */ - bool lanispl; /* Is a procedural language */ - bool lanpltrusted; /* PL is trusted */ - Oid lanplcallfoid; /* Call handler for PL */ - Oid laninline; /* Optional anonymous-block handler function */ - Oid lanvalidator; /* Optional validation function */ + Oid oid; /* oid */ + + /* Language name */ + NameData lanname; + + /* Language's owner */ + Oid lanowner BKI_DEFAULT(PGUID); + + /* Is a procedural language */ + bool lanispl BKI_DEFAULT(f); + + /* PL is trusted */ + bool lanpltrusted BKI_DEFAULT(f); + + /* Call handler, if it's a PL */ + Oid lanplcallfoid BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); + + /* Optional anonymous-block handler function */ + Oid laninline BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); + + /* Optional validation function */ + Oid lanvalidator BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - aclitem lanacl[1]; /* Access privileges */ + /* Access privileges */ + aclitem lanacl[1] BKI_DEFAULT(_null_); #endif } FormData_pg_language; diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h index 481d2ff63ba..db5ca8a7650 100644 --- a/src/include/catalog/pg_largeobject.h +++ b/src/include/catalog/pg_largeobject.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_largeobject.h - * definition of the system "largeobject" relation (pg_largeobject) + * definition of the "large object" system catalog (pg_largeobject) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_largeobject.h @@ -26,7 +26,7 @@ * typedef struct FormData_pg_largeobject * ---------------- */ -CATALOG(pg_largeobject,2613,LargeObjectRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_largeobject,2613,LargeObjectRelationId) { Oid loid; /* Identifier of large object */ int32 pageno; /* Page number (starting from 0) */ diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h index a8732bc4890..b628b34cf88 100644 --- a/src/include/catalog/pg_largeobject_metadata.h +++ b/src/include/catalog/pg_largeobject_metadata.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_largeobject_metadata.h - * definition of the system "largeobject_metadata" relation (pg_largeobject_metadata) + * definition of the "large object metadata" system catalog + * (pg_largeobject_metadata) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_largeobject_metadata.h @@ -28,6 +29,8 @@ */ CATALOG(pg_largeobject_metadata,2995,LargeObjectMetadataRelationId) { + Oid oid; /* oid */ + Oid lomowner; /* OID of the largeobject owner */ #ifdef CATALOG_VARLEN /* variable-length fields start here */ diff --git a/src/include/catalog/pg_namespace.dat b/src/include/catalog/pg_namespace.dat index e3549df2735..4d596045d51 100644 --- a/src/include/catalog/pg_namespace.dat +++ b/src/include/catalog/pg_namespace.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_namespace.dat -# Initial contents of the pg_namespace system relation. +# Initial contents of the pg_namespace system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_namespace.dat diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h index 0d9cada79f7..bc349e9c730 100644 --- a/src/include/catalog/pg_namespace.h +++ b/src/include/catalog/pg_namespace.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_namespace.h - * definition of the system "namespace" relation (pg_namespace) + * definition of the "namespace" system catalog (pg_namespace) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_namespace.h @@ -33,6 +33,8 @@ */ CATALOG(pg_namespace,2615,NamespaceRelationId) { + Oid oid; /* oid */ + NameData nspname; Oid nspowner; diff --git a/src/include/catalog/pg_opclass.dat b/src/include/catalog/pg_opclass.dat index 94e3e1e5fa5..2d575102efa 100644 --- a/src/include/catalog/pg_opclass.dat +++ b/src/include/catalog/pg_opclass.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_opclass.dat -# Initial contents of the pg_opclass system relation. +# Initial contents of the pg_opclass system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_opclass.dat @@ -16,8 +16,6 @@ # referenced in the C code or in built-in catalog entries. The rest get OIDs # assigned on-the-fly during initdb. -{ opcmethod => 'btree', opcname => 'abstime_ops', - opcfamily => 'btree/abstime_ops', opcintype => 'abstime' }, { opcmethod => 'btree', opcname => 'array_ops', opcfamily => 'btree/array_ops', opcintype => 'anyarray' }, { opcmethod => 'hash', opcname => 'array_ops', opcfamily => 'hash/array_ops', @@ -95,10 +93,10 @@ # but cstring and name are the same thing except for trailing padding, # and we can safely omit that within an index entry. So we declare the # btree opclass for name as using cstring storage type. -{ opcmethod => 'btree', opcname => 'name_ops', opcfamily => 'btree/name_ops', +{ opcmethod => 'btree', opcname => 'name_ops', opcfamily => 'btree/text_ops', opcintype => 'name', opckeytype => 'cstring' }, -{ opcmethod => 'hash', opcname => 'name_ops', opcfamily => 'hash/name_ops', +{ opcmethod => 'hash', opcname => 'name_ops', opcfamily => 'hash/text_ops', opcintype => 'name' }, { oid => '3125', oid_symbol => 'NUMERIC_BTREE_OPS_OID', opcmethod => 'btree', opcname => 'numeric_ops', @@ -148,13 +146,16 @@ opcfamily => 'btree/datetime_ops', opcintype => 'timestamp' }, { opcmethod => 'hash', opcname => 'timestamp_ops', opcfamily => 'hash/timestamp_ops', opcintype => 'timestamp' }, -{ opcmethod => 'btree', opcname => 'text_pattern_ops', +{ oid => '4217', oid_symbol => 'TEXT_BTREE_PATTERN_OPS_OID', + opcmethod => 'btree', opcname => 'text_pattern_ops', opcfamily => 'btree/text_pattern_ops', opcintype => 'text', opcdefault => 'f' }, -{ opcmethod => 'btree', opcname => 'varchar_pattern_ops', +{ oid => '4218', oid_symbol => 'VARCHAR_BTREE_PATTERN_OPS_OID', + opcmethod => 'btree', opcname => 'varchar_pattern_ops', opcfamily => 'btree/text_pattern_ops', opcintype => 'text', opcdefault => 'f' }, -{ opcmethod => 'btree', opcname => 'bpchar_pattern_ops', +{ oid => '4219', oid_symbol => 'BPCHAR_BTREE_PATTERN_OPS_OID', + opcmethod => 'btree', opcname => 'bpchar_pattern_ops', opcfamily => 'btree/bpchar_pattern_ops', opcintype => 'bpchar', opcdefault => 'f' }, { opcmethod => 'btree', opcname => 'money_ops', opcfamily => 'btree/money_ops', @@ -169,10 +170,8 @@ opcintype => 'xid' }, { opcmethod => 'hash', opcname => 'cid_ops', opcfamily => 'hash/cid_ops', opcintype => 'cid' }, -{ opcmethod => 'hash', opcname => 'abstime_ops', - opcfamily => 'hash/abstime_ops', opcintype => 'abstime' }, -{ opcmethod => 'hash', opcname => 'reltime_ops', - opcfamily => 'hash/reltime_ops', opcintype => 'reltime' }, +{ opcmethod => 'hash', opcname => 'tid_ops', opcfamily => 'hash/tid_ops', + opcintype => 'tid' }, { opcmethod => 'hash', opcname => 'text_pattern_ops', opcfamily => 'hash/text_pattern_ops', opcintype => 'text', opcdefault => 'f' }, @@ -182,10 +181,6 @@ { opcmethod => 'hash', opcname => 'bpchar_pattern_ops', opcfamily => 'hash/bpchar_pattern_ops', opcintype => 'bpchar', opcdefault => 'f' }, -{ opcmethod => 'btree', opcname => 'reltime_ops', - opcfamily => 'btree/reltime_ops', opcintype => 'reltime' }, -{ opcmethod => 'btree', opcname => 'tinterval_ops', - opcfamily => 'btree/tinterval_ops', opcintype => 'tinterval' }, { opcmethod => 'hash', opcname => 'aclitem_ops', opcfamily => 'hash/aclitem_ops', opcintype => 'aclitem' }, { opcmethod => 'gist', opcname => 'box_ops', opcfamily => 'gist/box_ops', @@ -286,12 +281,6 @@ { opcmethod => 'brin', opcname => 'float8_minmax_ops', opcfamily => 'brin/float_minmax_ops', opcintype => 'float8', opckeytype => 'float8' }, -{ opcmethod => 'brin', opcname => 'abstime_minmax_ops', - opcfamily => 'brin/abstime_minmax_ops', opcintype => 'abstime', - opckeytype => 'abstime' }, -{ opcmethod => 'brin', opcname => 'reltime_minmax_ops', - opcfamily => 'brin/reltime_minmax_ops', opcintype => 'reltime', - opckeytype => 'reltime' }, { opcmethod => 'brin', opcname => 'macaddr_minmax_ops', opcfamily => 'brin/macaddr_minmax_ops', opcintype => 'macaddr', opckeytype => 'macaddr' }, diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 16c3875daa8..84853c14d35 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_opclass.h - * definition of the system "opclass" relation (pg_opclass) + * definition of the "operator class" system catalog (pg_opclass) * * The primary key for this table is --- * that is, there is a row for each valid combination of opclass name and @@ -24,7 +24,7 @@ * AMs support this. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_opclass.h @@ -48,6 +48,8 @@ */ CATALOG(pg_opclass,2616,OperatorClassRelationId) { + Oid oid; /* oid */ + /* index access method opclass is for */ Oid opcmethod BKI_LOOKUP(pg_am); diff --git a/src/include/catalog/pg_operator.dat b/src/include/catalog/pg_operator.dat index 43827384cfe..fa7dc96ece6 100644 --- a/src/include/catalog/pg_operator.dat +++ b/src/include/catalog/pg_operator.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_operator.dat -# Initial contents of the pg_operator system relation. +# Initial contents of the pg_operator system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_operator.dat @@ -107,6 +107,65 @@ oprcode => 'starts_with', oprrest => 'prefixsel', oprjoin => 'prefixjoinsel' }, +{ oid => '254', descr => 'equal', + oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'name', + oprright => 'text', oprresult => 'bool', oprcom => '=(text,name)', + oprnegate => '<>(name,text)', oprcode => 'nameeqtext', oprrest => 'eqsel', + oprjoin => 'eqjoinsel' }, +{ oid => '255', descr => 'less than', + oprname => '<', oprleft => 'name', oprright => 'text', oprresult => 'bool', + oprcom => '>(text,name)', oprnegate => '>=(name,text)', + oprcode => 'namelttext', oprrest => 'scalarltsel', + oprjoin => 'scalarltjoinsel' }, +{ oid => '256', descr => 'less than or equal', + oprname => '<=', oprleft => 'name', oprright => 'text', oprresult => 'bool', + oprcom => '>=(text,name)', oprnegate => '>(name,text)', + oprcode => 'nameletext', oprrest => 'scalarlesel', + oprjoin => 'scalarlejoinsel' }, +{ oid => '257', descr => 'greater than or equal', + oprname => '>=', oprleft => 'name', oprright => 'text', oprresult => 'bool', + oprcom => '<=(text,name)', oprnegate => '<(name,text)', + oprcode => 'namegetext', oprrest => 'scalargesel', + oprjoin => 'scalargejoinsel' }, +{ oid => '258', descr => 'greater than', + oprname => '>', oprleft => 'name', oprright => 'text', oprresult => 'bool', + oprcom => '<(text,name)', oprnegate => '<=(name,text)', + oprcode => 'namegttext', oprrest => 'scalargtsel', + oprjoin => 'scalargtjoinsel' }, +{ oid => '259', descr => 'not equal', + oprname => '<>', oprleft => 'name', oprright => 'text', oprresult => 'bool', + oprcom => '<>(text,name)', oprnegate => '=(name,text)', + oprcode => 'namenetext', oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, +{ oid => '260', descr => 'equal', + oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'text', + oprright => 'name', oprresult => 'bool', oprcom => '=(name,text)', + oprnegate => '<>(text,name)', oprcode => 'texteqname', oprrest => 'eqsel', + oprjoin => 'eqjoinsel' }, +{ oid => '261', descr => 'less than', + oprname => '<', oprleft => 'text', oprright => 'name', oprresult => 'bool', + oprcom => '>(name,text)', oprnegate => '>=(text,name)', + oprcode => 'textltname', oprrest => 'scalarltsel', + oprjoin => 'scalarltjoinsel' }, +{ oid => '262', descr => 'less than or equal', + oprname => '<=', oprleft => 'text', oprright => 'name', oprresult => 'bool', + oprcom => '>=(name,text)', oprnegate => '>(text,name)', + oprcode => 'textlename', oprrest => 'scalarlesel', + oprjoin => 'scalarlejoinsel' }, +{ oid => '263', descr => 'greater than or equal', + oprname => '>=', oprleft => 'text', oprright => 'name', oprresult => 'bool', + oprcom => '<=(name,text)', oprnegate => '<(text,name)', + oprcode => 'textgename', oprrest => 'scalargesel', + oprjoin => 'scalargejoinsel' }, +{ oid => '264', descr => 'greater than', + oprname => '>', oprleft => 'text', oprright => 'name', oprresult => 'bool', + oprcom => '<(name,text)', oprnegate => '<=(text,name)', + oprcode => 'textgtname', oprrest => 'scalargtsel', + oprjoin => 'scalargtjoinsel' }, +{ oid => '265', descr => 'not equal', + oprname => '<>', oprleft => 'text', oprright => 'name', oprresult => 'bool', + oprcom => '<>(name,text)', oprnegate => '=(text,name)', + oprcode => 'textnename', oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, + { oid => '349', descr => 'append element onto end of array', oprname => '||', oprleft => 'anyarray', oprright => 'anyelement', oprresult => 'anyarray', oprcode => 'array_append' }, @@ -145,9 +204,10 @@ oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, { oid => '387', oid_symbol => 'TIDEqualOperator', descr => 'equal', - oprname => '=', oprcanmerge => 't', oprleft => 'tid', oprright => 'tid', - oprresult => 'bool', oprcom => '=(tid,tid)', oprnegate => '<>(tid,tid)', - oprcode => 'tideq', oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, + oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'tid', + oprright => 'tid', oprresult => 'bool', oprcom => '=(tid,tid)', + oprnegate => '<>(tid,tid)', oprcode => 'tideq', oprrest => 'eqsel', + oprjoin => 'eqjoinsel' }, { oid => '402', descr => 'not equal', oprname => '<>', oprleft => 'tid', oprright => 'tid', oprresult => 'bool', oprcom => '<>(tid,tid)', oprnegate => '=(tid,tid)', oprcode => 'tidne', @@ -498,110 +558,6 @@ { oid => '559', descr => 'negate', oprname => '-', oprkind => 'l', oprleft => '0', oprright => 'int2', oprresult => 'int2', oprcode => 'int2um' }, -{ oid => '560', descr => 'equal', - oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'abstime', - oprright => 'abstime', oprresult => 'bool', oprcom => '=(abstime,abstime)', - oprnegate => '<>(abstime,abstime)', oprcode => 'abstimeeq', - oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, -{ oid => '561', descr => 'not equal', - oprname => '<>', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'bool', oprcom => '<>(abstime,abstime)', - oprnegate => '=(abstime,abstime)', oprcode => 'abstimene', - oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, -{ oid => '562', descr => 'less than', - oprname => '<', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'bool', oprcom => '>(abstime,abstime)', - oprnegate => '>=(abstime,abstime)', oprcode => 'abstimelt', - oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' }, -{ oid => '563', descr => 'greater than', - oprname => '>', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'bool', oprcom => '<(abstime,abstime)', - oprnegate => '<=(abstime,abstime)', oprcode => 'abstimegt', - oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' }, -{ oid => '564', descr => 'less than or equal', - oprname => '<=', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'bool', oprcom => '>=(abstime,abstime)', - oprnegate => '>(abstime,abstime)', oprcode => 'abstimele', - oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' }, -{ oid => '565', descr => 'greater than or equal', - oprname => '>=', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'bool', oprcom => '<=(abstime,abstime)', - oprnegate => '<(abstime,abstime)', oprcode => 'abstimege', - oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' }, -{ oid => '566', descr => 'equal', - oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'reltime', - oprright => 'reltime', oprresult => 'bool', oprcom => '=(reltime,reltime)', - oprnegate => '<>(reltime,reltime)', oprcode => 'reltimeeq', - oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, -{ oid => '567', descr => 'not equal', - oprname => '<>', oprleft => 'reltime', oprright => 'reltime', - oprresult => 'bool', oprcom => '<>(reltime,reltime)', - oprnegate => '=(reltime,reltime)', oprcode => 'reltimene', - oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, -{ oid => '568', descr => 'less than', - oprname => '<', oprleft => 'reltime', oprright => 'reltime', - oprresult => 'bool', oprcom => '>(reltime,reltime)', - oprnegate => '>=(reltime,reltime)', oprcode => 'reltimelt', - oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' }, -{ oid => '569', descr => 'greater than', - oprname => '>', oprleft => 'reltime', oprright => 'reltime', - oprresult => 'bool', oprcom => '<(reltime,reltime)', - oprnegate => '<=(reltime,reltime)', oprcode => 'reltimegt', - oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' }, -{ oid => '570', descr => 'less than or equal', - oprname => '<=', oprleft => 'reltime', oprright => 'reltime', - oprresult => 'bool', oprcom => '>=(reltime,reltime)', - oprnegate => '>(reltime,reltime)', oprcode => 'reltimele', - oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' }, -{ oid => '571', descr => 'greater than or equal', - oprname => '>=', oprleft => 'reltime', oprright => 'reltime', - oprresult => 'bool', oprcom => '<=(reltime,reltime)', - oprnegate => '<(reltime,reltime)', oprcode => 'reltimege', - oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' }, -{ oid => '572', descr => 'same as', - oprname => '~=', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '~=(tinterval,tinterval)', - oprcode => 'tintervalsame', oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, -{ oid => '573', descr => 'contains', - oprname => '<<', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcode => 'tintervalct' }, -{ oid => '574', descr => 'overlaps', - oprname => '&&', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '&&(tinterval,tinterval)', - oprcode => 'tintervalov' }, -{ oid => '575', descr => 'equal by length', - oprname => '#=', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#<>(tinterval,reltime)', - oprcode => 'tintervalleneq' }, -{ oid => '576', descr => 'not equal by length', - oprname => '#<>', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#=(tinterval,reltime)', - oprcode => 'tintervallenne' }, -{ oid => '577', descr => 'less than by length', - oprname => '#<', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#>=(tinterval,reltime)', - oprcode => 'tintervallenlt' }, -{ oid => '578', descr => 'greater than by length', - oprname => '#>', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#<=(tinterval,reltime)', - oprcode => 'tintervallengt' }, -{ oid => '579', descr => 'less than or equal by length', - oprname => '#<=', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#>(tinterval,reltime)', - oprcode => 'tintervallenle' }, -{ oid => '580', descr => 'greater than or equal by length', - oprname => '#>=', oprleft => 'tinterval', oprright => 'reltime', - oprresult => 'bool', oprnegate => '#<(tinterval,reltime)', - oprcode => 'tintervallenge' }, -{ oid => '581', descr => 'add', - oprname => '+', oprleft => 'abstime', oprright => 'reltime', - oprresult => 'abstime', oprcode => 'timepl' }, -{ oid => '582', descr => 'subtract', - oprname => '-', oprleft => 'abstime', oprright => 'reltime', - oprresult => 'abstime', oprcode => 'timemi' }, -{ oid => '583', descr => 'is contained by', - oprname => '', oprleft => 'abstime', oprright => 'tinterval', - oprresult => 'bool', oprcode => 'intinterval' }, { oid => '584', descr => 'negate', oprname => '-', oprkind => 'l', oprleft => '0', oprright => 'float4', oprresult => 'float4', oprcode => 'float4um' }, @@ -644,12 +600,6 @@ { oid => '597', descr => 'cube root', oprname => '||/', oprkind => 'l', oprleft => '0', oprright => 'float8', oprresult => 'float8', oprcode => 'dcbrt' }, -{ oid => '1284', descr => 'start of interval', - oprname => '|', oprkind => 'l', oprleft => '0', oprright => 'tinterval', - oprresult => 'abstime', oprcode => 'tintervalstart' }, -{ oid => '606', descr => 'convert to tinterval', - oprname => '<#>', oprleft => 'abstime', oprright => 'abstime', - oprresult => 'tinterval', oprcode => 'mktinterval' }, { oid => '607', descr => 'equal', oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'oid', @@ -710,22 +660,40 @@ { oid => '613', descr => 'distance between', oprname => '<->', oprleft => 'point', oprright => 'line', - oprresult => 'float8', oprcode => 'dist_pl' }, + oprresult => 'float8', oprcom => '<->(line,point)', oprcode => 'dist_pl' }, +{ oid => '760', descr => 'distance between', + oprname => '<->', oprleft => 'line', oprright => 'point', + oprresult => 'float8', oprcom => '<->(point,line)', oprcode => 'dist_lp' }, { oid => '614', descr => 'distance between', oprname => '<->', oprleft => 'point', oprright => 'lseg', - oprresult => 'float8', oprcode => 'dist_ps' }, + oprresult => 'float8', oprcom => '<->(lseg,point)', oprcode => 'dist_ps' }, +{ oid => '761', descr => 'distance between', + oprname => '<->', oprleft => 'lseg', oprright => 'point', + oprresult => 'float8', oprcom => '<->(point,lseg)', oprcode => 'dist_sp' }, { oid => '615', descr => 'distance between', oprname => '<->', oprleft => 'point', oprright => 'box', - oprresult => 'float8', oprcode => 'dist_pb' }, + oprresult => 'float8', oprcom => '<->(box,point)', oprcode => 'dist_pb' }, +{ oid => '606', descr => 'distance between', + oprname => '<->', oprleft => 'box', oprright => 'point', + oprresult => 'float8', oprcom => '<->(point,box)', oprcode => 'dist_bp' }, { oid => '616', descr => 'distance between', oprname => '<->', oprleft => 'lseg', oprright => 'line', - oprresult => 'float8', oprcode => 'dist_sl' }, + oprresult => 'float8', oprcom => '<->(line,lseg)', oprcode => 'dist_sl' }, +{ oid => '762', descr => 'distance between', + oprname => '<->', oprleft => 'line', oprright => 'lseg', + oprresult => 'float8', oprcom => '<->(lseg,line)', oprcode => 'dist_ls' }, { oid => '617', descr => 'distance between', oprname => '<->', oprleft => 'lseg', oprright => 'box', oprresult => 'float8', - oprcode => 'dist_sb' }, + oprcom => '<->(box,lseg)', oprcode => 'dist_sb' }, +{ oid => '763', descr => 'distance between', + oprname => '<->', oprleft => 'box', oprright => 'lseg', oprresult => 'float8', + oprcom => '<->(lseg,box)', oprcode => 'dist_bs' }, { oid => '618', descr => 'distance between', oprname => '<->', oprleft => 'point', oprright => 'path', - oprresult => 'float8', oprcode => 'dist_ppath' }, + oprresult => 'float8', oprcom => '<->(path,point)', oprcode => 'dist_ppath' }, +{ oid => '784', descr => 'distance between', + oprname => '<->', oprleft => 'path', oprright => 'point', + oprresult => 'float8', oprcom => '<->(point,path)', oprcode => 'dist_pathp' }, { oid => '620', descr => 'equal', oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'float4', @@ -1075,37 +1043,6 @@ oprname => '?|', oprleft => 'point', oprright => 'point', oprresult => 'bool', oprcom => '?|(point,point)', oprcode => 'point_vert' }, -{ oid => '811', descr => 'equal', - oprname => '=', oprcanmerge => 't', oprleft => 'tinterval', - oprright => 'tinterval', oprresult => 'bool', - oprcom => '=(tinterval,tinterval)', oprnegate => '<>(tinterval,tinterval)', - oprcode => 'tintervaleq', oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, -{ oid => '812', descr => 'not equal', - oprname => '<>', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '<>(tinterval,tinterval)', - oprnegate => '=(tinterval,tinterval)', oprcode => 'tintervalne', - oprrest => 'neqsel', oprjoin => 'neqjoinsel' }, -{ oid => '813', descr => 'less than', - oprname => '<', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '>(tinterval,tinterval)', - oprnegate => '>=(tinterval,tinterval)', oprcode => 'tintervallt', - oprrest => 'scalarltsel', oprjoin => 'scalarltjoinsel' }, -{ oid => '814', descr => 'greater than', - oprname => '>', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '<(tinterval,tinterval)', - oprnegate => '<=(tinterval,tinterval)', oprcode => 'tintervalgt', - oprrest => 'scalargtsel', oprjoin => 'scalargtjoinsel' }, -{ oid => '815', descr => 'less than or equal', - oprname => '<=', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '>=(tinterval,tinterval)', - oprnegate => '>(tinterval,tinterval)', oprcode => 'tintervalle', - oprrest => 'scalarlesel', oprjoin => 'scalarlejoinsel' }, -{ oid => '816', descr => 'greater than or equal', - oprname => '>=', oprleft => 'tinterval', oprright => 'tinterval', - oprresult => 'bool', oprcom => '<=(tinterval,tinterval)', - oprnegate => '<(tinterval,tinterval)', oprcode => 'tintervalge', - oprrest => 'scalargesel', oprjoin => 'scalargejoinsel' }, - { oid => '843', descr => 'multiply', oprname => '*', oprleft => 'money', oprright => 'float4', oprresult => 'money', oprcom => '*(float4,money)', @@ -1773,12 +1710,20 @@ oprcode => 'dist_polyp' }, { oid => '1523', descr => 'distance between', oprname => '<->', oprleft => 'circle', oprright => 'polygon', - oprresult => 'float8', oprcode => 'dist_cpoly' }, + oprresult => 'float8', oprcom => '<->(polygon,circle)', + oprcode => 'dist_cpoly' }, +{ oid => '1383', descr => 'distance between', + oprname => '<->', oprleft => 'polygon', oprright => 'circle', + oprresult => 'float8', oprcom => '<->(circle,polygon)', + oprcode => 'dist_polyc' }, # additional geometric operators - thomas 1997-07-09 { oid => '1524', descr => 'distance between', oprname => '<->', oprleft => 'line', oprright => 'box', oprresult => 'float8', - oprcode => 'dist_lb' }, + oprcom => '<->(box,line)', oprcode => 'dist_lb' }, +{ oid => '1382', descr => 'distance between', + oprname => '<->', oprleft => 'box', oprright => 'line', oprresult => 'float8', + oprcom => '<->(line,box)', oprcode => 'dist_bl' }, { oid => '1525', descr => 'intersect', oprname => '?#', oprleft => 'lseg', oprright => 'lseg', oprresult => 'bool', @@ -3336,5 +3281,13 @@ { oid => '3287', descr => 'delete path', oprname => '#-', oprleft => 'jsonb', oprright => '_text', oprresult => 'jsonb', oprcode => 'jsonb_delete_path' }, +{ oid => '4012', descr => 'jsonpath exists', + oprname => '@?', oprleft => 'jsonb', oprright => 'jsonpath', + oprresult => 'bool', oprcode => 'jsonb_path_exists_opr(jsonb,jsonpath)', + oprrest => 'contsel', oprjoin => 'contjoinsel' }, +{ oid => '4013', descr => 'jsonpath match', + oprname => '@@', oprleft => 'jsonb', oprright => 'jsonpath', + oprresult => 'bool', oprcode => 'jsonb_path_match_opr(jsonb,jsonpath)', + oprrest => 'contsel', oprjoin => 'contjoinsel' }, ] diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index bbf330320e7..7c4f6862a86 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_operator.h - * definition of the system "operator" relation (pg_operator) + * definition of the "operator" system catalog (pg_operator) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_operator.h @@ -31,6 +31,8 @@ */ CATALOG(pg_operator,2617,OperatorRelationId) { + Oid oid; /* oid */ + /* name of operator */ NameData oprname; @@ -83,16 +85,16 @@ typedef FormData_pg_operator *Form_pg_operator; extern ObjectAddress OperatorCreate(const char *operatorName, - Oid operatorNamespace, - Oid leftTypeId, - Oid rightTypeId, - Oid procedureId, - List *commutatorName, - List *negatorName, - Oid restrictionId, - Oid joinId, - bool canMerge, - bool canHash); + Oid operatorNamespace, + Oid leftTypeId, + Oid rightTypeId, + Oid procedureId, + List *commutatorName, + List *negatorName, + Oid restrictionId, + Oid joinId, + bool canMerge, + bool canHash); extern ObjectAddress makeOperatorDependencies(HeapTuple tuple, bool isUpdate); diff --git a/src/include/catalog/pg_opfamily.dat b/src/include/catalog/pg_opfamily.dat index 72d71ee5b2d..41e40d657ad 100644 --- a/src/include/catalog/pg_opfamily.dat +++ b/src/include/catalog/pg_opfamily.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_opfamily.dat -# Initial contents of the pg_opfamily system relation. +# Initial contents of the pg_opfamily system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_opfamily.dat @@ -12,8 +12,6 @@ [ -{ oid => '421', - opfmethod => 'btree', opfname => 'abstime_ops' }, { oid => '397', opfmethod => 'btree', opfname => 'array_ops' }, { oid => '627', @@ -64,10 +62,6 @@ opfmethod => 'btree', opfname => 'macaddr8_ops' }, { oid => '3372', opfmethod => 'hash', opfname => 'macaddr8_ops' }, -{ oid => '1986', oid_symbol => 'NAME_BTREE_FAM_OID', - opfmethod => 'btree', opfname => 'name_ops' }, -{ oid => '1987', - opfmethod => 'hash', opfname => 'name_ops' }, { oid => '1988', opfmethod => 'btree', opfname => 'numeric_ops' }, { oid => '1998', @@ -119,17 +113,11 @@ { oid => '2226', opfmethod => 'hash', opfname => 'cid_ops' }, { oid => '2227', - opfmethod => 'hash', opfname => 'abstime_ops' }, -{ oid => '2228', - opfmethod => 'hash', opfname => 'reltime_ops' }, + opfmethod => 'hash', opfname => 'tid_ops' }, { oid => '2229', opfmethod => 'hash', opfname => 'text_pattern_ops' }, { oid => '2231', opfmethod => 'hash', opfname => 'bpchar_pattern_ops' }, -{ oid => '2233', - opfmethod => 'btree', opfname => 'reltime_ops' }, -{ oid => '2234', - opfmethod => 'btree', opfname => 'tinterval_ops' }, { oid => '2235', opfmethod => 'hash', opfname => 'aclitem_ops' }, { oid => '2593', @@ -182,8 +170,6 @@ opfmethod => 'btree', opfname => 'jsonb_ops' }, { oid => '4034', opfmethod => 'hash', opfname => 'jsonb_ops' }, -{ oid => '4035', - opfmethod => 'gist', opfname => 'jsonb_ops' }, { oid => '4036', opfmethod => 'gin', opfname => 'jsonb_ops' }, { oid => '4037', @@ -210,10 +196,6 @@ opfmethod => 'brin', opfname => 'tid_minmax_ops' }, { oid => '4070', opfmethod => 'brin', opfname => 'float_minmax_ops' }, -{ oid => '4072', - opfmethod => 'brin', opfname => 'abstime_minmax_ops' }, -{ oid => '4073', - opfmethod => 'brin', opfname => 'reltime_minmax_ops' }, { oid => '4074', opfmethod => 'brin', opfname => 'macaddr_minmax_ops' }, { oid => '4109', diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index ddb0641228c..0e672d5052f 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_opfamily.h - * definition of the system "opfamily" relation (pg_opfamily) + * definition of the "operator family" system catalog (pg_opfamily) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_opfamily.h @@ -28,6 +28,8 @@ */ CATALOG(pg_opfamily,2753,OperatorFamilyRelationId) { + Oid oid; /* oid */ + /* index access method opfamily is for */ Oid opfmethod BKI_LOOKUP(pg_am); diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h index 676532ae3f1..806905489f2 100644 --- a/src/include/catalog/pg_partitioned_table.h +++ b/src/include/catalog/pg_partitioned_table.h @@ -1,10 +1,12 @@ /*------------------------------------------------------------------------- * * pg_partitioned_table.h - * definition of the system "partitioned table" relation + * definition of the "partitioned table" system catalog + * (pg_partitioned_table) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_partitioned_table.h * @@ -25,7 +27,7 @@ * typedef struct FormData_pg_partitioned_table * ---------------- */ -CATALOG(pg_partitioned_table,3350,PartitionedRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_partitioned_table,3350,PartitionedRelationId) { Oid partrelid; /* partitioned table oid */ char partstrat; /* partitioning strategy */ diff --git a/src/include/catalog/pg_pltemplate.dat b/src/include/catalog/pg_pltemplate.dat index 2d8bfabbe09..6f6d1674d61 100644 --- a/src/include/catalog/pg_pltemplate.dat +++ b/src/include/catalog/pg_pltemplate.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_pltemplate.dat -# Initial contents of the pg_pltemplate system relation. +# Initial contents of the pg_pltemplate system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_pltemplate.dat diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h index d84c86b08d2..ce890004efe 100644 --- a/src/include/catalog/pg_pltemplate.h +++ b/src/include/catalog/pg_pltemplate.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_pltemplate.h - * definition of the system "PL template" relation (pg_pltemplate) + * definition of the "PL template" system catalog (pg_pltemplate) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_pltemplate.h @@ -26,7 +26,7 @@ * typedef struct FormData_pg_pltemplate * ---------------- */ -CATALOG(pg_pltemplate,1136,PLTemplateRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +CATALOG(pg_pltemplate,1136,PLTemplateRelationId) BKI_SHARED_RELATION { NameData tmplname; /* name of PL */ bool tmpltrusted; /* PL is trusted? */ diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h index 45fdc285f79..62a78d80499 100644 --- a/src/include/catalog/pg_policy.h +++ b/src/include/catalog/pg_policy.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_policy.h - * definition of the system "policy" relation (pg_policy) + * definition of the "policy" system catalog (pg_policy) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_policy.h @@ -28,13 +28,15 @@ */ CATALOG(pg_policy,3256,PolicyRelationId) { + Oid oid; /* oid */ NameData polname; /* Policy name. */ Oid polrelid; /* Oid of the relation with policy. */ char polcmd; /* One of ACL_*_CHR, or '*' for all */ bool polpermissive; /* restrictive or permissive policy */ #ifdef CATALOG_VARLEN - Oid polroles[1]; /* Roles associated with policy, not-NULL */ + Oid polroles[1] BKI_FORCE_NOT_NULL; /* Roles associated with + * policy */ pg_node_tree polqual; /* Policy quals. */ pg_node_tree polwithcheck; /* WITH CHECK quals. */ #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3c56ef6abcc..58ea5b982b3 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_proc.dat -# Initial contents of the pg_proc system relation. +# Initial contents of the pg_proc system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_proc.dat @@ -21,7 +21,7 @@ # Try to follow the style of existing functions' comments. # Some recommended conventions: - +# # "I/O" for typinput, typoutput, typreceive, typsend functions # "I/O typmod" for typmodin, typmodout functions # "aggregate transition function" for aggtransfn functions, unless @@ -30,6 +30,9 @@ # "convert srctypename to desttypename" for cast functions # "less-equal-greater" for B-tree comparison functions +# Note: pronargs is computed when this file is read, so it does not need +# to be specified in entries here. See AddDefaultValues() in Catalog.pm. + # Once upon a time these entries were ordered by OID. Lately it's often # been the custom to insert new entries adjacent to related older entries. # Try to do one or the other though, don't just insert entries at random. @@ -186,17 +189,21 @@ prosrc => 'i4tochar' }, { oid => '79', - proname => 'nameregexeq', prorettype => 'bool', proargtypes => 'name text', - prosrc => 'nameregexeq' }, + proname => 'nameregexeq', prosupport => 'textregexeq_support', + prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameregexeq' }, { oid => '1252', proname => 'nameregexne', prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameregexne' }, { oid => '1254', - proname => 'textregexeq', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'textregexeq' }, + proname => 'textregexeq', prosupport => 'textregexeq_support', + prorettype => 'bool', proargtypes => 'text text', prosrc => 'textregexeq' }, { oid => '1256', proname => 'textregexne', prorettype => 'bool', proargtypes => 'text text', prosrc => 'textregexne' }, +{ oid => '1364', descr => 'planner support for textregexeq', + proname => 'textregexeq_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'textregexeq_support' }, + { oid => '1257', descr => 'length', proname => 'textlen', prorettype => 'int4', proargtypes => 'text', prosrc => 'textlen' }, @@ -670,115 +677,57 @@ proname => 'line_distance', prorettype => 'float8', proargtypes => 'line line', prosrc => 'line_distance' }, -{ oid => '240', descr => 'I/O', - proname => 'abstimein', provolatile => 's', prorettype => 'abstime', - proargtypes => 'cstring', prosrc => 'abstimein' }, -{ oid => '241', descr => 'I/O', - proname => 'abstimeout', provolatile => 's', prorettype => 'cstring', - proargtypes => 'abstime', prosrc => 'abstimeout' }, -{ oid => '242', descr => 'I/O', - proname => 'reltimein', provolatile => 's', prorettype => 'reltime', - proargtypes => 'cstring', prosrc => 'reltimein' }, -{ oid => '243', descr => 'I/O', - proname => 'reltimeout', provolatile => 's', prorettype => 'cstring', - proargtypes => 'reltime', prosrc => 'reltimeout' }, +{ oid => '240', + proname => 'nameeqtext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'nameeqtext' }, +{ oid => '241', + proname => 'namelttext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namelttext' }, +{ oid => '242', + proname => 'nameletext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'nameletext' }, +{ oid => '243', + proname => 'namegetext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namegetext' }, { oid => '244', - proname => 'timepl', prorettype => 'abstime', - proargtypes => 'abstime reltime', prosrc => 'timepl' }, + proname => 'namegttext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namegttext' }, { oid => '245', - proname => 'timemi', prorettype => 'abstime', - proargtypes => 'abstime reltime', prosrc => 'timemi' }, -{ oid => '246', descr => 'I/O', - proname => 'tintervalin', provolatile => 's', prorettype => 'tinterval', - proargtypes => 'cstring', prosrc => 'tintervalin' }, -{ oid => '247', descr => 'I/O', - proname => 'tintervalout', provolatile => 's', prorettype => 'cstring', - proargtypes => 'tinterval', prosrc => 'tintervalout' }, + proname => 'namenetext', proleakproof => 't', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namenetext' }, +{ oid => '246', descr => 'less-equal-greater', + proname => 'btnametextcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'name text', prosrc => 'btnametextcmp' }, +{ oid => '247', + proname => 'texteqname', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'texteqname' }, { oid => '248', - proname => 'intinterval', prorettype => 'bool', - proargtypes => 'abstime tinterval', prosrc => 'intinterval' }, -{ oid => '249', descr => 'tinterval to reltime', - proname => 'tintervalrel', prorettype => 'reltime', - proargtypes => 'tinterval', prosrc => 'tintervalrel' }, -{ oid => '250', descr => 'current date and time (abstime)', - proname => 'timenow', provolatile => 's', prorettype => 'abstime', - proargtypes => '', prosrc => 'timenow' }, + proname => 'textltname', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'textltname' }, +{ oid => '249', + proname => 'textlename', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'textlename' }, +{ oid => '250', + proname => 'textgename', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'textgename' }, { oid => '251', - proname => 'abstimeeq', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimeeq' }, + proname => 'textgtname', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'textgtname' }, { oid => '252', - proname => 'abstimene', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimene' }, -{ oid => '253', - proname => 'abstimelt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimelt' }, -{ oid => '254', - proname => 'abstimegt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimegt' }, -{ oid => '255', - proname => 'abstimele', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimele' }, -{ oid => '256', - proname => 'abstimege', proleakproof => 't', prorettype => 'bool', - proargtypes => 'abstime abstime', prosrc => 'abstimege' }, -{ oid => '257', - proname => 'reltimeeq', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimeeq' }, -{ oid => '258', - proname => 'reltimene', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimene' }, -{ oid => '259', - proname => 'reltimelt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimelt' }, -{ oid => '260', - proname => 'reltimegt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimegt' }, -{ oid => '261', - proname => 'reltimele', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimele' }, -{ oid => '262', - proname => 'reltimege', proleakproof => 't', prorettype => 'bool', - proargtypes => 'reltime reltime', prosrc => 'reltimege' }, -{ oid => '263', - proname => 'tintervalsame', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalsame' }, -{ oid => '264', - proname => 'tintervalct', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalct' }, -{ oid => '265', - proname => 'tintervalov', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalov' }, -{ oid => '266', - proname => 'tintervalleneq', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervalleneq' }, -{ oid => '267', - proname => 'tintervallenne', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervallenne' }, -{ oid => '268', - proname => 'tintervallenlt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervallenlt' }, -{ oid => '269', - proname => 'tintervallengt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervallengt' }, -{ oid => '270', - proname => 'tintervallenle', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervallenle' }, -{ oid => '271', - proname => 'tintervallenge', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval reltime', prosrc => 'tintervallenge' }, -{ oid => '272', - proname => 'tintervalstart', prorettype => 'abstime', - proargtypes => 'tinterval', prosrc => 'tintervalstart' }, -{ oid => '273', descr => 'end of interval', - proname => 'tintervalend', prorettype => 'abstime', - proargtypes => 'tinterval', prosrc => 'tintervalend' }, + proname => 'textnename', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text name', prosrc => 'textnename' }, +{ oid => '253', descr => 'less-equal-greater', + proname => 'bttextnamecmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'text name', prosrc => 'bttextnamecmp' }, + +{ oid => '266', descr => 'concatenate name and oid', + proname => 'nameconcatoid', prorettype => 'name', proargtypes => 'name oid', + prosrc => 'nameconcatoid' }, + { oid => '274', descr => 'current date and time - increments during transactions', proname => 'timeofday', provolatile => 'v', prorettype => 'text', proargtypes => '', prosrc => 'timeofday' }, -{ oid => '275', descr => 'finite abstime?', - proname => 'isfinite', prorettype => 'bool', proargtypes => 'abstime', - prosrc => 'abstime_finite' }, { oid => '277', proname => 'inter_sl', prorettype => 'bool', proargtypes => 'lseg line', @@ -918,6 +867,13 @@ proname => 'int4', prorettype => 'int4', proargtypes => 'float4', prosrc => 'ftoi4' }, +# Table access method handlers +{ oid => '3', oid_symbol => 'HEAP_TABLE_AM_HANDLER_OID', + descr => 'row-oriented heap table access method handler', + proname => 'heap_tableam_handler', provolatile => 'v', + prorettype => 'table_am_handler', proargtypes => 'internal', + prosrc => 'heap_tableam_handler' }, + # Index access method handlers { oid => '330', descr => 'btree index access method handler', proname => 'bthandler', provolatile => 'v', prorettype => 'index_am_handler', @@ -968,6 +924,9 @@ proname => 'pg_index_column_has_property', provolatile => 's', prorettype => 'bool', proargtypes => 'regclass int4 text', prosrc => 'pg_index_column_has_property' }, +{ oid => '676', descr => 'return name of given index build phase', + proname => 'pg_indexam_progress_phasename', prorettype => 'text', + proargtypes => 'oid int8', prosrc => 'pg_indexam_progress_phasename' }, { oid => '339', proname => 'poly_same', prorettype => 'bool', @@ -1001,71 +960,62 @@ prosrc => 'poly_out' }, { oid => '350', descr => 'less-equal-greater', - proname => 'btint2cmp', prorettype => 'int4', proargtypes => 'int2 int2', - prosrc => 'btint2cmp' }, + proname => 'btint2cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int2 int2', prosrc => 'btint2cmp' }, { oid => '3129', descr => 'sort support', proname => 'btint2sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btint2sortsupport' }, { oid => '351', descr => 'less-equal-greater', - proname => 'btint4cmp', prorettype => 'int4', proargtypes => 'int4 int4', - prosrc => 'btint4cmp' }, + proname => 'btint4cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int4 int4', prosrc => 'btint4cmp' }, { oid => '3130', descr => 'sort support', proname => 'btint4sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btint4sortsupport' }, { oid => '842', descr => 'less-equal-greater', - proname => 'btint8cmp', prorettype => 'int4', proargtypes => 'int8 int8', - prosrc => 'btint8cmp' }, + proname => 'btint8cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int8 int8', prosrc => 'btint8cmp' }, { oid => '3131', descr => 'sort support', proname => 'btint8sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btint8sortsupport' }, { oid => '354', descr => 'less-equal-greater', - proname => 'btfloat4cmp', prorettype => 'int4', + proname => 'btfloat4cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'float4 float4', prosrc => 'btfloat4cmp' }, { oid => '3132', descr => 'sort support', proname => 'btfloat4sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btfloat4sortsupport' }, { oid => '355', descr => 'less-equal-greater', - proname => 'btfloat8cmp', prorettype => 'int4', + proname => 'btfloat8cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'float8 float8', prosrc => 'btfloat8cmp' }, { oid => '3133', descr => 'sort support', proname => 'btfloat8sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btfloat8sortsupport' }, { oid => '356', descr => 'less-equal-greater', - proname => 'btoidcmp', prorettype => 'int4', proargtypes => 'oid oid', - prosrc => 'btoidcmp' }, + proname => 'btoidcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'oid oid', prosrc => 'btoidcmp' }, { oid => '3134', descr => 'sort support', proname => 'btoidsortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btoidsortsupport' }, { oid => '404', descr => 'less-equal-greater', - proname => 'btoidvectorcmp', prorettype => 'int4', + proname => 'btoidvectorcmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'oidvector oidvector', prosrc => 'btoidvectorcmp' }, -{ oid => '357', descr => 'less-equal-greater', - proname => 'btabstimecmp', prorettype => 'int4', - proargtypes => 'abstime abstime', prosrc => 'btabstimecmp' }, { oid => '358', descr => 'less-equal-greater', - proname => 'btcharcmp', prorettype => 'int4', proargtypes => 'char char', - prosrc => 'btcharcmp' }, + proname => 'btcharcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'char char', prosrc => 'btcharcmp' }, { oid => '359', descr => 'less-equal-greater', - proname => 'btnamecmp', prorettype => 'int4', proargtypes => 'name name', - prosrc => 'btnamecmp' }, + proname => 'btnamecmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'name name', prosrc => 'btnamecmp' }, { oid => '3135', descr => 'sort support', proname => 'btnamesortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btnamesortsupport' }, { oid => '360', descr => 'less-equal-greater', - proname => 'bttextcmp', prorettype => 'int4', proargtypes => 'text text', - prosrc => 'bttextcmp' }, + proname => 'bttextcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'text text', prosrc => 'bttextcmp' }, { oid => '3255', descr => 'sort support', proname => 'bttextsortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'bttextsortsupport' }, { oid => '377', descr => 'less-equal-greater', - proname => 'cash_cmp', prorettype => 'int4', proargtypes => 'money money', - prosrc => 'cash_cmp' }, -{ oid => '380', descr => 'less-equal-greater', - proname => 'btreltimecmp', prorettype => 'int4', - proargtypes => 'reltime reltime', prosrc => 'btreltimecmp' }, -{ oid => '381', descr => 'less-equal-greater', - proname => 'bttintervalcmp', prorettype => 'int4', - proargtypes => 'tinterval tinterval', prosrc => 'bttintervalcmp' }, + proname => 'cash_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'money money', prosrc => 'cash_cmp' }, { oid => '382', descr => 'less-equal-greater', proname => 'btarraycmp', prorettype => 'int4', proargtypes => 'anyarray anyarray', prosrc => 'btarraycmp' }, @@ -1112,12 +1062,21 @@ { oid => '363', proname => 'dist_ps', prorettype => 'float8', proargtypes => 'point lseg', prosrc => 'dist_ps' }, +{ oid => '380', + proname => 'dist_sp', prorettype => 'float8', proargtypes => 'lseg point', + prosrc => 'dist_sp' }, { oid => '364', proname => 'dist_pb', prorettype => 'float8', proargtypes => 'point box', prosrc => 'dist_pb' }, +{ oid => '357', + proname => 'dist_bp', prorettype => 'float8', proargtypes => 'box point', + prosrc => 'dist_bp' }, { oid => '365', proname => 'dist_sb', prorettype => 'float8', proargtypes => 'lseg box', prosrc => 'dist_sb' }, +{ oid => '381', + proname => 'dist_bs', prorettype => 'float8', proargtypes => 'box lseg', + prosrc => 'dist_bs' }, { oid => '366', proname => 'close_ps', prorettype => 'point', proargtypes => 'point lseg', prosrc => 'close_ps' }, @@ -1136,6 +1095,9 @@ { oid => '371', proname => 'dist_ppath', prorettype => 'float8', proargtypes => 'point path', prosrc => 'dist_ppath' }, +{ oid => '421', + proname => 'dist_pathp', prorettype => 'float8', proargtypes => 'path point', + prosrc => 'dist_pathp' }, { oid => '372', proname => 'on_sb', prorettype => 'bool', proargtypes => 'lseg box', prosrc => 'on_sb' }, @@ -1268,11 +1230,11 @@ proargmodes => '{v}', prosrc => 'pg_num_nonnulls' }, { oid => '458', descr => 'larger of two', - proname => 'text_larger', prorettype => 'text', proargtypes => 'text text', - prosrc => 'text_larger' }, + proname => 'text_larger', proleakproof => 't', prorettype => 'text', + proargtypes => 'text text', prosrc => 'text_larger' }, { oid => '459', descr => 'smaller of two', - proname => 'text_smaller', prorettype => 'text', proargtypes => 'text text', - prosrc => 'text_smaller' }, + proname => 'text_smaller', proleakproof => 't', prorettype => 'text', + proargtypes => 'text text', prosrc => 'text_smaller' }, { oid => '460', descr => 'I/O', proname => 'int8in', prorettype => 'int8', proargtypes => 'cstring', @@ -1390,35 +1352,31 @@ { oid => '668', descr => 'adjust char() to typmod length', proname => 'bpchar', prorettype => 'bpchar', proargtypes => 'bpchar int4 bool', prosrc => 'bpchar' }, -{ oid => '3097', descr => 'transform a varchar length coercion', - proname => 'varchar_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'varchar_transform' }, +{ oid => '3097', descr => 'planner support for varchar length coercion', + proname => 'varchar_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'varchar_support' }, { oid => '669', descr => 'adjust varchar() to typmod length', - proname => 'varchar', protransform => 'varchar_transform', + proname => 'varchar', prosupport => 'varchar_support', prorettype => 'varchar', proargtypes => 'varchar int4 bool', prosrc => 'varchar' }, -{ oid => '676', - proname => 'mktinterval', prorettype => 'tinterval', - proargtypes => 'abstime abstime', prosrc => 'mktinterval' }, - { oid => '619', - proname => 'oidvectorne', prorettype => 'bool', + proname => 'oidvectorne', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectorne' }, { oid => '677', - proname => 'oidvectorlt', prorettype => 'bool', + proname => 'oidvectorlt', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectorlt' }, { oid => '678', - proname => 'oidvectorle', prorettype => 'bool', + proname => 'oidvectorle', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectorle' }, { oid => '679', - proname => 'oidvectoreq', prorettype => 'bool', + proname => 'oidvectoreq', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectoreq' }, { oid => '680', - proname => 'oidvectorge', prorettype => 'bool', + proname => 'oidvectorge', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectorge' }, { oid => '681', - proname => 'oidvectorgt', prorettype => 'bool', + proname => 'oidvectorgt', proleakproof => 't', prorettype => 'bool', proargtypes => 'oidvector oidvector', prosrc => 'oidvectorgt' }, # OIDS 700 - 799 @@ -1457,15 +1415,28 @@ { oid => '725', proname => 'dist_pl', prorettype => 'float8', proargtypes => 'point line', prosrc => 'dist_pl' }, +{ oid => '702', + proname => 'dist_lp', prorettype => 'float8', proargtypes => 'line point', + prosrc => 'dist_lp' }, { oid => '726', proname => 'dist_lb', prorettype => 'float8', proargtypes => 'line box', prosrc => 'dist_lb' }, +{ oid => '703', + proname => 'dist_bl', prorettype => 'float8', proargtypes => 'box line', + prosrc => 'dist_bl' }, { oid => '727', proname => 'dist_sl', prorettype => 'float8', proargtypes => 'lseg line', prosrc => 'dist_sl' }, +{ oid => '704', + proname => 'dist_ls', prorettype => 'float8', proargtypes => 'line lseg', + prosrc => 'dist_ls' }, + { oid => '728', proname => 'dist_cpoly', prorettype => 'float8', proargtypes => 'circle polygon', prosrc => 'dist_cpoly' }, +{ oid => '785', + proname => 'dist_polyc', prorettype => 'float8', + proargtypes => 'polygon circle', prosrc => 'dist_polyc' }, { oid => '729', proname => 'poly_distance', prorettype => 'float8', proargtypes => 'polygon polygon', prosrc => 'poly_distance' }, @@ -1480,17 +1451,17 @@ proargtypes => 'circle point', prosrc => 'dist_cpoint' }, { oid => '740', - proname => 'text_lt', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'text_lt' }, + proname => 'text_lt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'text_lt' }, { oid => '741', - proname => 'text_le', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'text_le' }, + proname => 'text_le', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'text_le' }, { oid => '742', - proname => 'text_gt', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'text_gt' }, + proname => 'text_gt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'text_gt' }, { oid => '743', - proname => 'text_ge', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'text_ge' }, + proname => 'text_ge', proleakproof => 't', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'text_ge' }, { oid => '745', descr => 'current user name', proname => 'current_user', provolatile => 's', prorettype => 'name', @@ -1598,9 +1569,12 @@ proargtypes => 'anyelement _int4 _int4', prosrc => 'array_fill_with_lower_bounds' }, { oid => '2331', descr => 'expand array to set of rows', - proname => 'unnest', prorows => '100', proretset => 't', - prorettype => 'anyelement', proargtypes => 'anyarray', + proname => 'unnest', prorows => '100', prosupport => 'array_unnest_support', + proretset => 't', prorettype => 'anyelement', proargtypes => 'anyarray', prosrc => 'array_unnest' }, +{ oid => '3996', descr => 'planner support for array_unnest', + proname => 'array_unnest_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'array_unnest_support' }, { oid => '3167', descr => 'remove any occurrences of an element from an array', proname => 'array_remove', proisstrict => 'f', prorettype => 'anyarray', @@ -1646,19 +1620,6 @@ proargtypes => 'internal oid internal int2 internal', prosrc => 'arraycontjoinsel' }, -{ oid => '760', descr => 'I/O', - proname => 'smgrin', provolatile => 's', prorettype => 'smgr', - proargtypes => 'cstring', prosrc => 'smgrin' }, -{ oid => '761', descr => 'I/O', - proname => 'smgrout', provolatile => 's', prorettype => 'cstring', - proargtypes => 'smgr', prosrc => 'smgrout' }, -{ oid => '762', descr => 'storage manager', - proname => 'smgreq', prorettype => 'bool', proargtypes => 'smgr smgr', - prosrc => 'smgreq' }, -{ oid => '763', descr => 'storage manager', - proname => 'smgrne', prorettype => 'bool', proargtypes => 'smgr smgr', - prosrc => 'smgrne' }, - { oid => '764', descr => 'large object import', proname => 'lo_import', provolatile => 'v', proparallel => 'u', prorettype => 'oid', proargtypes => 'text', prosrc => 'be_lo_import' }, @@ -1686,25 +1647,6 @@ proname => 'int2smaller', prorettype => 'int2', proargtypes => 'int2 int2', prosrc => 'int2smaller' }, -{ oid => '784', - proname => 'tintervaleq', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervaleq' }, -{ oid => '785', - proname => 'tintervalne', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalne' }, -{ oid => '786', - proname => 'tintervallt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervallt' }, -{ oid => '787', - proname => 'tintervalgt', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalgt' }, -{ oid => '788', - proname => 'tintervalle', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalle' }, -{ oid => '789', - proname => 'tintervalge', proleakproof => 't', prorettype => 'bool', - proargtypes => 'tinterval tinterval', prosrc => 'tintervalge' }, - # OIDS 800 - 899 { oid => '846', @@ -1721,8 +1663,11 @@ proname => 'position', prorettype => 'int4', proargtypes => 'text text', prosrc => 'textpos' }, { oid => '850', - proname => 'textlike', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'textlike' }, + proname => 'textlike', prosupport => 'textlike_support', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'textlike' }, +{ oid => '1023', descr => 'planner support for textlike', + proname => 'textlike_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'textlike_support' }, { oid => '851', proname => 'textnlike', prorettype => 'bool', proargtypes => 'text text', prosrc => 'textnlike' }, @@ -1747,8 +1692,8 @@ proargtypes => 'int4 int8', prosrc => 'int48ge' }, { oid => '858', - proname => 'namelike', prorettype => 'bool', proargtypes => 'name text', - prosrc => 'namelike' }, + proname => 'namelike', prosupport => 'textlike_support', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namelike' }, { oid => '859', proname => 'namenlike', prorettype => 'bool', proargtypes => 'name text', prosrc => 'namenlike' }, @@ -2041,13 +1986,9 @@ # OIDS 1000 - 1999 -{ oid => '3994', descr => 'transform a time zone adjustment', - proname => 'timestamp_izone_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'timestamp_izone_transform' }, { oid => '1026', descr => 'adjust timestamp to new time zone', - proname => 'timezone', protransform => 'timestamp_izone_transform', - prorettype => 'timestamp', proargtypes => 'interval timestamptz', - prosrc => 'timestamptz_izone' }, + proname => 'timezone', prorettype => 'timestamp', + proargtypes => 'interval timestamptz', prosrc => 'timestamptz_izone' }, { oid => '1031', descr => 'I/O', proname => 'aclitemin', provolatile => 's', prorettype => 'aclitem', @@ -2070,11 +2011,12 @@ { oid => '1365', descr => 'make ACL item', proname => 'makeaclitem', prorettype => 'aclitem', proargtypes => 'oid oid text bool', prosrc => 'makeaclitem' }, -{ oid => '3943', descr => 'TODO', +{ oid => '3943', + descr => 'show hardwired default privileges, primarily for use by the information schema', proname => 'acldefault', prorettype => '_aclitem', proargtypes => 'char oid', prosrc => 'acldefault_sql' }, { oid => '1689', - descr => 'convert ACL item array to table, for use by information schema', + descr => 'convert ACL item array to table, primarily for use by information schema', proname => 'aclexplode', prorows => '10', proretset => 't', provolatile => 's', prorettype => 'record', proargtypes => '_aclitem', proallargtypes => '{_aclitem,oid,oid,text,bool}', @@ -2109,29 +2051,29 @@ proname => 'bpchareq', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpchareq' }, { oid => '1049', - proname => 'bpcharlt', prorettype => 'bool', proargtypes => 'bpchar bpchar', - prosrc => 'bpcharlt' }, + proname => 'bpcharlt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'bpchar bpchar', prosrc => 'bpcharlt' }, { oid => '1050', - proname => 'bpcharle', prorettype => 'bool', proargtypes => 'bpchar bpchar', - prosrc => 'bpcharle' }, + proname => 'bpcharle', proleakproof => 't', prorettype => 'bool', + proargtypes => 'bpchar bpchar', prosrc => 'bpcharle' }, { oid => '1051', - proname => 'bpchargt', prorettype => 'bool', proargtypes => 'bpchar bpchar', - prosrc => 'bpchargt' }, + proname => 'bpchargt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'bpchar bpchar', prosrc => 'bpchargt' }, { oid => '1052', - proname => 'bpcharge', prorettype => 'bool', proargtypes => 'bpchar bpchar', - prosrc => 'bpcharge' }, + proname => 'bpcharge', proleakproof => 't', prorettype => 'bool', + proargtypes => 'bpchar bpchar', prosrc => 'bpcharge' }, { oid => '1053', proname => 'bpcharne', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpcharne' }, { oid => '1063', descr => 'larger of two', - proname => 'bpchar_larger', prorettype => 'bpchar', + proname => 'bpchar_larger', proleakproof => 't', prorettype => 'bpchar', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_larger' }, { oid => '1064', descr => 'smaller of two', - proname => 'bpchar_smaller', prorettype => 'bpchar', + proname => 'bpchar_smaller', proleakproof => 't', prorettype => 'bpchar', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_smaller' }, { oid => '1078', descr => 'less-equal-greater', - proname => 'bpcharcmp', prorettype => 'int4', proargtypes => 'bpchar bpchar', - prosrc => 'bpcharcmp' }, + proname => 'bpcharcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'bpchar bpchar', prosrc => 'bpcharcmp' }, { oid => '3328', descr => 'sort support', proname => 'bpchar_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'bpchar_sortsupport' }, @@ -2169,8 +2111,8 @@ proname => 'date_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'date date', prosrc => 'date_ne' }, { oid => '1092', descr => 'less-equal-greater', - proname => 'date_cmp', prorettype => 'int4', proargtypes => 'date date', - prosrc => 'date_cmp' }, + proname => 'date_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'date date', prosrc => 'date_cmp' }, { oid => '3136', descr => 'sort support', proname => 'date_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'date_sortsupport' }, @@ -2197,8 +2139,8 @@ proname => 'time_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'time time', prosrc => 'time_ne' }, { oid => '1107', descr => 'less-equal-greater', - proname => 'time_cmp', prorettype => 'int4', proargtypes => 'time time', - prosrc => 'time_cmp' }, + proname => 'time_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'time time', prosrc => 'time_cmp' }, { oid => '1138', descr => 'larger of two', proname => 'date_larger', prorettype => 'date', proargtypes => 'date date', prosrc => 'date_larger' }, @@ -2276,13 +2218,9 @@ { oid => '1158', descr => 'convert UNIX epoch to timestamptz', proname => 'to_timestamp', prorettype => 'timestamptz', proargtypes => 'float8', prosrc => 'float8_timestamptz' }, -{ oid => '3995', descr => 'transform a time zone adjustment', - proname => 'timestamp_zone_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'timestamp_zone_transform' }, { oid => '1159', descr => 'adjust timestamp to new time zone', - proname => 'timezone', protransform => 'timestamp_zone_transform', - prorettype => 'timestamp', proargtypes => 'text timestamptz', - prosrc => 'timestamptz_zone' }, + proname => 'timezone', prorettype => 'timestamp', + proargtypes => 'text timestamptz', prosrc => 'timestamptz_zone' }, { oid => '1160', descr => 'I/O', proname => 'interval_in', provolatile => 's', prorettype => 'interval', @@ -2329,9 +2267,6 @@ { oid => '1172', descr => 'extract field from interval', proname => 'date_part', prorettype => 'float8', proargtypes => 'text interval', prosrc => 'interval_part' }, -{ oid => '1173', descr => 'convert abstime to timestamp with time zone', - proname => 'timestamptz', prorettype => 'timestamptz', - proargtypes => 'abstime', prosrc => 'abstime_timestamptz' }, { oid => '1174', descr => 'convert date to timestamp with time zone', proname => 'timestamptz', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'date', prosrc => 'date_timestamptz' }, @@ -2346,21 +2281,12 @@ proname => 'justify_days', prorettype => 'interval', proargtypes => 'interval', prosrc => 'interval_justify_days' }, { oid => '1176', descr => 'convert date and time to timestamp with time zone', - proname => 'timestamptz', prolang => '14', provolatile => 's', + proname => 'timestamptz', prolang => 'sql', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'date time', prosrc => 'select cast(($1 + $2) as timestamp with time zone)' }, -{ oid => '1177', descr => 'convert reltime to interval', - proname => 'interval', prorettype => 'interval', proargtypes => 'reltime', - prosrc => 'reltime_interval' }, { oid => '1178', descr => 'convert timestamp with time zone to date', proname => 'date', provolatile => 's', prorettype => 'date', proargtypes => 'timestamptz', prosrc => 'timestamptz_date' }, -{ oid => '1179', descr => 'convert abstime to date', - proname => 'date', provolatile => 's', prorettype => 'date', - proargtypes => 'abstime', prosrc => 'abstime_date' }, -{ oid => '1180', descr => 'convert timestamp with time zone to abstime', - proname => 'abstime', prorettype => 'abstime', proargtypes => 'timestamptz', - prosrc => 'timestamptz_abstime' }, { oid => '1181', descr => 'age of a transaction ID, in transactions before current transaction', proname => 'age', provolatile => 's', proparallel => 'r', @@ -2381,9 +2307,6 @@ proname => 'timestamptz_mi_interval', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'timestamptz interval', prosrc => 'timestamptz_mi_interval' }, -{ oid => '1194', descr => 'convert interval to reltime', - proname => 'reltime', prorettype => 'reltime', proargtypes => 'interval', - prosrc => 'interval_reltime' }, { oid => '1195', descr => 'smaller of two', proname => 'timestamptz_smaller', prorettype => 'timestamptz', proargtypes => 'timestamptz timestamptz', prosrc => 'timestamp_smaller' }, @@ -2402,25 +2325,25 @@ # OIDS 1200 - 1299 -{ oid => '3918', descr => 'transform an interval length coercion', - proname => 'interval_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'interval_transform' }, +{ oid => '3918', descr => 'planner support for interval length coercion', + proname => 'interval_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'interval_support' }, { oid => '1200', descr => 'adjust interval precision', - proname => 'interval', protransform => 'interval_transform', + proname => 'interval', prosupport => 'interval_support', prorettype => 'interval', proargtypes => 'interval int4', prosrc => 'interval_scale' }, { oid => '1215', descr => 'get description for object id and catalog name', - proname => 'obj_description', prolang => '14', procost => '100', + proname => 'obj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid name', prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP) and objsubid = 0' }, { oid => '1216', descr => 'get description for table column', - proname => 'col_description', prolang => '14', procost => '100', + proname => 'col_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid int4', - prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = \'\'pg_catalog.pg_class\'\'::pg_catalog.regclass and objsubid = $2' }, + prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and classoid = \'pg_catalog.pg_class\'::pg_catalog.regclass and objsubid = $2' }, { oid => '1993', descr => 'get description for object id and shared catalog name', - proname => 'shobj_description', prolang => '14', procost => '100', + proname => 'shobj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid name', prosrc => 'select description from pg_catalog.pg_shdescription where objoid = $1 and classoid = (select oid from pg_catalog.pg_class where relname = $2 and relnamespace = PGNSP)' }, @@ -2428,6 +2351,10 @@ descr => 'truncate timestamp with time zone to specified units', proname => 'date_trunc', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'text timestamptz', prosrc => 'timestamptz_trunc' }, +{ oid => '1284', + descr => 'truncate timestamp with time zone to specified units in specified time zone', + proname => 'date_trunc', provolatile => 's', prorettype => 'timestamptz', + proargtypes => 'text timestamptz text', prosrc => 'timestamptz_trunc_zone' }, { oid => '1218', descr => 'truncate interval to specified units', proname => 'date_trunc', prorettype => 'interval', proargtypes => 'text interval', prosrc => 'interval_trunc' }, @@ -2456,14 +2383,17 @@ prosrc => 'int8smaller' }, { oid => '1238', - proname => 'texticregexeq', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'texticregexeq' }, + proname => 'texticregexeq', prosupport => 'texticregexeq_support', + prorettype => 'bool', proargtypes => 'text text', prosrc => 'texticregexeq' }, +{ oid => '1024', descr => 'planner support for texticregexeq', + proname => 'texticregexeq_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'texticregexeq_support' }, { oid => '1239', proname => 'texticregexne', prorettype => 'bool', proargtypes => 'text text', prosrc => 'texticregexne' }, { oid => '1240', - proname => 'nameicregexeq', prorettype => 'bool', proargtypes => 'name text', - prosrc => 'nameicregexeq' }, + proname => 'nameicregexeq', prosupport => 'texticregexeq_support', + prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameicregexeq' }, { oid => '1241', proname => 'nameicregexne', prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameicregexne' }, @@ -2573,32 +2503,38 @@ proname => 'tidle', proleakproof => 't', prorettype => 'bool', proargtypes => 'tid tid', prosrc => 'tidle' }, { oid => '2794', descr => 'less-equal-greater', - proname => 'bttidcmp', prorettype => 'int4', proargtypes => 'tid tid', - prosrc => 'bttidcmp' }, + proname => 'bttidcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'tid tid', prosrc => 'bttidcmp' }, { oid => '2795', descr => 'larger of two', proname => 'tidlarger', prorettype => 'tid', proargtypes => 'tid tid', prosrc => 'tidlarger' }, { oid => '2796', descr => 'smaller of two', proname => 'tidsmaller', prorettype => 'tid', proargtypes => 'tid tid', prosrc => 'tidsmaller' }, +{ oid => '2233', descr => 'hash', + proname => 'hashtid', prorettype => 'int4', proargtypes => 'tid', + prosrc => 'hashtid' }, +{ oid => '2234', descr => 'hash', + proname => 'hashtidextended', prorettype => 'int8', proargtypes => 'tid int8', + prosrc => 'hashtidextended' }, { oid => '1296', - proname => 'timedate_pl', prolang => '14', prorettype => 'timestamp', + proname => 'timedate_pl', prolang => 'sql', prorettype => 'timestamp', proargtypes => 'time date', prosrc => 'select ($2 + $1)' }, { oid => '1297', proname => 'datetimetz_pl', prorettype => 'timestamptz', proargtypes => 'date timetz', prosrc => 'datetimetz_timestamptz' }, { oid => '1298', - proname => 'timetzdate_pl', prolang => '14', prorettype => 'timestamptz', + proname => 'timetzdate_pl', prolang => 'sql', prorettype => 'timestamptz', proargtypes => 'timetz date', prosrc => 'select ($2 + $1)' }, { oid => '1299', descr => 'current transaction time', - proname => 'now', provolatile => 's', proparallel => 'r', - prorettype => 'timestamptz', proargtypes => '', prosrc => 'now' }, + proname => 'now', provolatile => 's', prorettype => 'timestamptz', + proargtypes => '', prosrc => 'now' }, { oid => '2647', descr => 'current transaction time', proname => 'transaction_timestamp', provolatile => 's', prorettype => 'timestamptz', proargtypes => '', prosrc => 'now' }, { oid => '2648', descr => 'current statement time', - proname => 'statement_timestamp', provolatile => 's', proparallel => 'r', + proname => 'statement_timestamp', provolatile => 's', prorettype => 'timestamptz', proargtypes => '', prosrc => 'statement_timestamp' }, { oid => '2649', descr => 'current clock time', @@ -2631,17 +2567,17 @@ proargtypes => 'timestamptz timestamptz timestamptz timestamptz', prosrc => 'overlaps_timestamp' }, { oid => '1305', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz interval timestamptz interval', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, { oid => '1306', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz timestamptz timestamptz interval', prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, { oid => '1307', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'bool', proargtypes => 'timestamptz interval timestamptz timestamptz', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, @@ -2650,15 +2586,15 @@ proname => 'overlaps', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time time time time', prosrc => 'overlaps_time' }, { oid => '1309', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time interval time interval', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, { oid => '1310', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time time time interval', prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, { oid => '1311', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'time interval time time', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, @@ -2675,10 +2611,10 @@ proname => 'timestamptypmodout', prorettype => 'cstring', proargtypes => 'int4', prosrc => 'timestamptypmodout' }, { oid => '1314', descr => 'less-equal-greater', - proname => 'timestamptz_cmp', prorettype => 'int4', + proname => 'timestamptz_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'timestamptz timestamptz', prosrc => 'timestamp_cmp' }, { oid => '1315', descr => 'less-equal-greater', - proname => 'interval_cmp', prorettype => 'int4', + proname => 'interval_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'interval interval', prosrc => 'interval_cmp' }, { oid => '1316', descr => 'convert timestamp to time', proname => 'time', prorettype => 'time', proargtypes => 'timestamp', @@ -2708,6 +2644,9 @@ { oid => '1340', descr => 'base 10 logarithm', proname => 'log', prorettype => 'float8', proargtypes => 'float8', prosrc => 'dlog10' }, +{ oid => '1194', descr => 'base 10 logarithm', + proname => 'log10', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dlog10' }, { oid => '1341', descr => 'natural logarithm', proname => 'ln', prorettype => 'float8', proargtypes => 'float8', prosrc => 'dlog1' }, @@ -2736,7 +2675,7 @@ # This form of obj_description is now deprecated, since it will fail if # OIDs are not unique across system catalogs. Use the other form instead. { oid => '1348', descr => 'deprecated, use two-argument form instead', - proname => 'obj_description', prolang => '14', procost => '100', + proname => 'obj_description', prolang => 'sql', procost => '100', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'select description from pg_catalog.pg_description where objoid = $1 and objsubid = 0' }, @@ -2775,18 +2714,13 @@ proname => 'timetz_gt', proleakproof => 't', prorettype => 'bool', proargtypes => 'timetz timetz', prosrc => 'timetz_gt' }, { oid => '1358', descr => 'less-equal-greater', - proname => 'timetz_cmp', prorettype => 'int4', proargtypes => 'timetz timetz', - prosrc => 'timetz_cmp' }, + proname => 'timetz_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'timetz timetz', prosrc => 'timetz_cmp' }, { oid => '1359', descr => 'convert date and time with time zone to timestamp with time zone', proname => 'timestamptz', prorettype => 'timestamptz', proargtypes => 'date timetz', prosrc => 'datetimetz_timestamptz' }, -{ oid => '1364', descr => 'convert abstime to time', - proname => 'time', prolang => '14', provolatile => 's', prorettype => 'time', - proargtypes => 'abstime', - prosrc => 'select cast(cast($1 as timestamp without time zone) as pg_catalog.time)' }, - { oid => '1367', descr => 'character length', proname => 'character_length', prorettype => 'int4', proargtypes => 'bpchar', prosrc => 'bpcharlen' }, @@ -2824,16 +2758,8 @@ proname => 'char_length', prorettype => 'int4', proargtypes => 'text', prosrc => 'textlen' }, -{ oid => '1382', descr => 'extract field from abstime', - proname => 'date_part', prolang => '14', provolatile => 's', - prorettype => 'float8', proargtypes => 'text abstime', - prosrc => 'select pg_catalog.date_part($1, cast($2 as timestamp with time zone))' }, -{ oid => '1383', descr => 'extract field from reltime', - proname => 'date_part', prolang => '14', provolatile => 's', - prorettype => 'float8', proargtypes => 'text reltime', - prosrc => 'select pg_catalog.date_part($1, cast($2 as pg_catalog.interval))' }, { oid => '1384', descr => 'extract field from date', - proname => 'date_part', prolang => '14', prorettype => 'float8', + proname => 'date_part', prolang => 'sql', prorettype => 'float8', proargtypes => 'text date', prosrc => 'select pg_catalog.date_part($1, cast($2 as timestamp without time zone))' }, { oid => '1385', descr => 'extract field from time', @@ -2841,7 +2767,7 @@ prosrc => 'time_part' }, { oid => '1386', descr => 'date difference from today preserving months and years', - proname => 'age', prolang => '14', provolatile => 's', + proname => 'age', prolang => 'sql', provolatile => 's', prorettype => 'interval', proargtypes => 'timestamptz', prosrc => 'select pg_catalog.age(cast(current_date as timestamp with time zone), $1)' }, @@ -2889,11 +2815,11 @@ prosrc => 'name_text' }, { oid => '1402', descr => 'current schema name', - proname => 'current_schema', provolatile => 's', prorettype => 'name', - proargtypes => '', prosrc => 'current_schema' }, + proname => 'current_schema', provolatile => 's', proparallel => 'u', + prorettype => 'name', proargtypes => '', prosrc => 'current_schema' }, { oid => '1403', descr => 'current schema search list', - proname => 'current_schemas', provolatile => 's', prorettype => '_name', - proargtypes => 'bool', prosrc => 'current_schemas' }, + proname => 'current_schemas', provolatile => 's', proparallel => 'u', + prorettype => '_name', proargtypes => 'bool', prosrc => 'current_schemas' }, { oid => '1404', descr => 'substitute portion of string', proname => 'overlay', prorettype => 'text', @@ -2956,7 +2882,7 @@ proname => 'box_div', prorettype => 'box', proargtypes => 'box point', prosrc => 'box_div' }, { oid => '1426', - proname => 'path_contain_pt', prolang => '14', prorettype => 'bool', + proname => 'path_contain_pt', prolang => 'sql', prorettype => 'bool', proargtypes => 'path point', prosrc => 'select pg_catalog.on_ppath($2, $1)' }, { oid => '1428', proname => 'poly_contain_pt', prorettype => 'bool', @@ -3128,9 +3054,6 @@ { oid => '1480', descr => 'convert circle to box', proname => 'box', prorettype => 'box', proargtypes => 'circle', prosrc => 'circle_box' }, -{ oid => '1481', descr => 'convert to tinterval', - proname => 'tinterval', prorettype => 'tinterval', - proargtypes => 'abstime abstime', prosrc => 'mktinterval' }, { oid => '1482', proname => 'lseg_ne', proleakproof => 't', prorettype => 'bool', @@ -3219,7 +3142,7 @@ proname => 'center', prorettype => 'point', proargtypes => 'circle', prosrc => 'circle_center' }, { oid => '1544', descr => 'convert circle to 12-vertex polygon', - proname => 'polygon', prolang => '14', prorettype => 'polygon', + proname => 'polygon', prolang => 'sql', prorettype => 'polygon', proargtypes => 'circle', prosrc => 'select pg_catalog.polygon(12, $1)' }, { oid => '1545', descr => 'number of points', proname => 'npoints', prorettype => 'int4', proargtypes => 'path', @@ -3242,14 +3165,14 @@ prosrc => 'bittypmodout' }, { oid => '1569', descr => 'matches LIKE expression', - proname => 'like', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'textlike' }, + proname => 'like', prosupport => 'textlike_support', prorettype => 'bool', + proargtypes => 'text text', prosrc => 'textlike' }, { oid => '1570', descr => 'does not match LIKE expression', proname => 'notlike', prorettype => 'bool', proargtypes => 'text text', prosrc => 'textnlike' }, { oid => '1571', descr => 'matches LIKE expression', - proname => 'like', prorettype => 'bool', proargtypes => 'name text', - prosrc => 'namelike' }, + proname => 'like', prosupport => 'textlike_support', prorettype => 'bool', + proargtypes => 'name text', prosrc => 'namelike' }, { oid => '1572', descr => 'does not match LIKE expression', proname => 'notlike', prorettype => 'bool', proargtypes => 'name text', prosrc => 'namenlike' }, @@ -3282,6 +3205,11 @@ prorettype => 'int8', proargtypes => 'regclass', prosrc => 'pg_sequence_last_value' }, +{ oid => '275', descr => 'return the next oid for a system table', + proname => 'pg_nextoid', provolatile => 'v', proparallel => 'u', + prorettype => 'oid', proargtypes => 'regclass name regclass', + prosrc => 'pg_nextoid' }, + { oid => '1579', descr => 'I/O', proname => 'varbit_in', prorettype => 'varbit', proargtypes => 'cstring oid int4', prosrc => 'varbit_in' }, @@ -3314,8 +3242,8 @@ proname => 'bitlt', proleakproof => 't', prorettype => 'bool', proargtypes => 'bit bit', prosrc => 'bitlt' }, { oid => '1596', descr => 'less-equal-greater', - proname => 'bitcmp', prorettype => 'int4', proargtypes => 'bit bit', - prosrc => 'bitcmp' }, + proname => 'bitcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'bit bit', prosrc => 'bitcmp' }, { oid => '1598', descr => 'random value', proname => 'random', provolatile => 'v', proparallel => 'r', @@ -3385,6 +3313,25 @@ { oid => '1610', descr => 'PI', proname => 'pi', prorettype => 'float8', proargtypes => '', prosrc => 'dpi' }, +{ oid => '2462', descr => 'hyperbolic sine', + proname => 'sinh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dsinh' }, +{ oid => '2463', descr => 'hyperbolic cosine', + proname => 'cosh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dcosh' }, +{ oid => '2464', descr => 'hyperbolic tangent', + proname => 'tanh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dtanh' }, +{ oid => '2465', descr => 'inverse hyperbolic sine', + proname => 'asinh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dasinh' }, +{ oid => '2466', descr => 'inverse hyperbolic cosine', + proname => 'acosh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'dacosh' }, +{ oid => '2467', descr => 'inverse hyperbolic tangent', + proname => 'atanh', prorettype => 'float8', proargtypes => 'float8', + prosrc => 'datanh' }, + { oid => '1618', proname => 'interval_mul', prorettype => 'interval', proargtypes => 'interval float8', prosrc => 'interval_mul' }, @@ -3399,30 +3346,39 @@ proname => 'repeat', prorettype => 'text', proargtypes => 'text int4', prosrc => 'repeat' }, -{ oid => '1623', descr => 'convert SQL99 regexp pattern to POSIX style', +{ oid => '1623', descr => 'convert SQL regexp pattern to POSIX style', proname => 'similar_escape', proisstrict => 'f', prorettype => 'text', proargtypes => 'text text', prosrc => 'similar_escape' }, +{ oid => '1986', descr => 'convert SQL regexp pattern to POSIX style', + proname => 'similar_to_escape', prorettype => 'text', + proargtypes => 'text text', prosrc => 'similar_to_escape_2' }, +{ oid => '1987', descr => 'convert SQL regexp pattern to POSIX style', + proname => 'similar_to_escape', prorettype => 'text', proargtypes => 'text', + prosrc => 'similar_to_escape_1' }, { oid => '1624', proname => 'mul_d_interval', prorettype => 'interval', proargtypes => 'float8 interval', prosrc => 'mul_d_interval' }, { oid => '1631', - proname => 'bpcharlike', prorettype => 'bool', proargtypes => 'bpchar text', - prosrc => 'textlike' }, + proname => 'bpcharlike', prosupport => 'textlike_support', + prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'textlike' }, { oid => '1632', proname => 'bpcharnlike', prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'textnlike' }, { oid => '1633', - proname => 'texticlike', prorettype => 'bool', proargtypes => 'text text', - prosrc => 'texticlike' }, + proname => 'texticlike', prosupport => 'texticlike_support', + prorettype => 'bool', proargtypes => 'text text', prosrc => 'texticlike' }, +{ oid => '1025', descr => 'planner support for texticlike', + proname => 'texticlike_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'texticlike_support' }, { oid => '1634', proname => 'texticnlike', prorettype => 'bool', proargtypes => 'text text', prosrc => 'texticnlike' }, { oid => '1635', - proname => 'nameiclike', prorettype => 'bool', proargtypes => 'name text', - prosrc => 'nameiclike' }, + proname => 'nameiclike', prosupport => 'texticlike_support', + prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameiclike' }, { oid => '1636', proname => 'nameicnlike', prorettype => 'bool', proargtypes => 'name text', prosrc => 'nameicnlike' }, @@ -3431,20 +3387,21 @@ prosrc => 'like_escape' }, { oid => '1656', - proname => 'bpcharicregexeq', prorettype => 'bool', - proargtypes => 'bpchar text', prosrc => 'texticregexeq' }, + proname => 'bpcharicregexeq', prosupport => 'texticregexeq_support', + prorettype => 'bool', proargtypes => 'bpchar text', + prosrc => 'texticregexeq' }, { oid => '1657', proname => 'bpcharicregexne', prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'texticregexne' }, { oid => '1658', - proname => 'bpcharregexeq', prorettype => 'bool', - proargtypes => 'bpchar text', prosrc => 'textregexeq' }, + proname => 'bpcharregexeq', prosupport => 'textregexeq_support', + prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'textregexeq' }, { oid => '1659', proname => 'bpcharregexne', prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'textregexne' }, { oid => '1660', - proname => 'bpchariclike', prorettype => 'bool', proargtypes => 'bpchar text', - prosrc => 'texticlike' }, + proname => 'bpchariclike', prosupport => 'texticlike_support', + prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'texticlike' }, { oid => '1661', proname => 'bpcharicnlike', prorettype => 'bool', proargtypes => 'bpchar text', prosrc => 'texticnlike' }, @@ -3481,13 +3438,13 @@ proname => 'translate', prorettype => 'text', proargtypes => 'text text text', prosrc => 'translate' }, { oid => '879', descr => 'left-pad string to length', - proname => 'lpad', prolang => '14', prorettype => 'text', + proname => 'lpad', prolang => 'sql', prorettype => 'text', proargtypes => 'text int4', - prosrc => 'select pg_catalog.lpad($1, $2, \'\' \'\')' }, + prosrc => 'select pg_catalog.lpad($1, $2, \' \')' }, { oid => '880', descr => 'right-pad string to length', - proname => 'rpad', prolang => '14', prorettype => 'text', + proname => 'rpad', prolang => 'sql', prorettype => 'text', proargtypes => 'text int4', - prosrc => 'select pg_catalog.rpad($1, $2, \'\' \'\')' }, + prosrc => 'select pg_catalog.rpad($1, $2, \' \')' }, { oid => '881', descr => 'trim spaces from left end of string', proname => 'ltrim', prorettype => 'text', proargtypes => 'text', prosrc => 'ltrim1' }, @@ -3771,8 +3728,8 @@ proname => 'varbitlt', proleakproof => 't', prorettype => 'bool', proargtypes => 'varbit varbit', prosrc => 'bitlt' }, { oid => '1672', descr => 'less-equal-greater', - proname => 'varbitcmp', prorettype => 'int4', proargtypes => 'varbit varbit', - prosrc => 'bitcmp' }, + proname => 'varbitcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'varbit varbit', prosrc => 'bitcmp' }, # avoid the C names bitand and bitor, since they are C++ keywords { oid => '1673', @@ -3815,13 +3772,12 @@ { oid => '1685', descr => 'adjust bit() to typmod length', proname => 'bit', prorettype => 'bit', proargtypes => 'bit int4 bool', prosrc => 'bit' }, -{ oid => '3158', descr => 'transform a varbit length coercion', - proname => 'varbit_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'varbit_transform' }, +{ oid => '3158', descr => 'planner support for varbit length coercion', + proname => 'varbit_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'varbit_support' }, { oid => '1687', descr => 'adjust varbit() to typmod length', - proname => 'varbit', protransform => 'varbit_transform', - prorettype => 'varbit', proargtypes => 'varbit int4 bool', - prosrc => 'varbit' }, + proname => 'varbit', prosupport => 'varbit_support', prorettype => 'varbit', + proargtypes => 'varbit int4 bool', prosrc => 'varbit' }, { oid => '1698', descr => 'position of sub-bitstring', proname => 'position', prorettype => 'int4', proargtypes => 'bit bit', @@ -3874,7 +3830,7 @@ proname => 'macaddr_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'macaddr macaddr', prosrc => 'macaddr_ne' }, { oid => '836', descr => 'less-equal-greater', - proname => 'macaddr_cmp', prorettype => 'int4', + proname => 'macaddr_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'macaddr macaddr', prosrc => 'macaddr_cmp' }, { oid => '3144', proname => 'macaddr_not', prorettype => 'macaddr', proargtypes => 'macaddr', @@ -3920,7 +3876,7 @@ proname => 'macaddr8_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'macaddr8 macaddr8', prosrc => 'macaddr8_ne' }, { oid => '4119', descr => 'less-equal-greater', - proname => 'macaddr8_cmp', prorettype => 'int4', + proname => 'macaddr8_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'macaddr8 macaddr8', prosrc => 'macaddr8_cmp' }, { oid => '4120', proname => 'macaddr8_not', prorettype => 'macaddr8', @@ -3983,23 +3939,30 @@ proname => 'network_smaller', prorettype => 'inet', proargtypes => 'inet inet', prosrc => 'network_smaller' }, { oid => '926', descr => 'less-equal-greater', - proname => 'network_cmp', prorettype => 'int4', proargtypes => 'inet inet', - prosrc => 'network_cmp' }, + proname => 'network_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'inet inet', prosrc => 'network_cmp' }, { oid => '927', - proname => 'network_sub', prorettype => 'bool', proargtypes => 'inet inet', - prosrc => 'network_sub' }, + proname => 'network_sub', prosupport => 'network_subset_support', + prorettype => 'bool', proargtypes => 'inet inet', prosrc => 'network_sub' }, { oid => '928', - proname => 'network_subeq', prorettype => 'bool', proargtypes => 'inet inet', - prosrc => 'network_subeq' }, + proname => 'network_subeq', prosupport => 'network_subset_support', + prorettype => 'bool', proargtypes => 'inet inet', prosrc => 'network_subeq' }, { oid => '929', - proname => 'network_sup', prorettype => 'bool', proargtypes => 'inet inet', - prosrc => 'network_sup' }, + proname => 'network_sup', prosupport => 'network_subset_support', + prorettype => 'bool', proargtypes => 'inet inet', prosrc => 'network_sup' }, { oid => '930', - proname => 'network_supeq', prorettype => 'bool', proargtypes => 'inet inet', - prosrc => 'network_supeq' }, + proname => 'network_supeq', prosupport => 'network_subset_support', + prorettype => 'bool', proargtypes => 'inet inet', prosrc => 'network_supeq' }, +{ oid => '1173', descr => 'planner support for network_sub/superset', + proname => 'network_subset_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'network_subset_support' }, + { oid => '3551', proname => 'network_overlap', prorettype => 'bool', proargtypes => 'inet inet', prosrc => 'network_overlap' }, +{ oid => '8190', descr => 'sort support', + proname => 'network_sortsupport', prorettype => 'void', + proargtypes => 'internal', prosrc => 'network_sortsupport' }, # inet/cidr functions { oid => '598', descr => 'abbreviated display of inet value', @@ -4070,7 +4033,7 @@ proname => 'inetpl', prorettype => 'inet', proargtypes => 'inet int8', prosrc => 'inetpl' }, { oid => '2631', - proname => 'int8pl_inet', prolang => '14', prorettype => 'inet', + proname => 'int8pl_inet', prolang => 'sql', prorettype => 'inet', proargtypes => 'int8 inet', prosrc => 'select $2 + $1' }, { oid => '2632', proname => 'inetmi_int8', prorettype => 'inet', proargtypes => 'inet int8', @@ -4147,8 +4110,8 @@ proname => 'boolge', proleakproof => 't', prorettype => 'bool', proargtypes => 'bool bool', prosrc => 'boolge' }, { oid => '1693', descr => 'less-equal-greater', - proname => 'btboolcmp', prorettype => 'int4', proargtypes => 'bool bool', - prosrc => 'btboolcmp' }, + proname => 'btboolcmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'bool bool', prosrc => 'btboolcmp' }, { oid => '1688', descr => 'hash', proname => 'time_hash', prorettype => 'int4', proargtypes => 'time', @@ -4183,11 +4146,11 @@ { oid => '2918', descr => 'I/O typmod', proname => 'numerictypmodout', prorettype => 'cstring', proargtypes => 'int4', prosrc => 'numerictypmodout' }, -{ oid => '3157', descr => 'transform a numeric length coercion', - proname => 'numeric_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'numeric_transform' }, +{ oid => '3157', descr => 'planner support for numeric length coercion', + proname => 'numeric_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'numeric_support' }, { oid => '1703', descr => 'adjust numeric to typmod precision/scale', - proname => 'numeric', protransform => 'numeric_transform', + proname => 'numeric', prosupport => 'numeric_support', prorettype => 'numeric', proargtypes => 'numeric int4', prosrc => 'numeric' }, { oid => '1704', proname => 'numeric_abs', prorettype => 'numeric', proargtypes => 'numeric', @@ -4202,13 +4165,13 @@ proname => 'round', prorettype => 'numeric', proargtypes => 'numeric int4', prosrc => 'numeric_round' }, { oid => '1708', descr => 'value rounded to \'scale\' of zero', - proname => 'round', prolang => '14', prorettype => 'numeric', + proname => 'round', prolang => 'sql', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'select pg_catalog.round($1,0)' }, { oid => '1709', descr => 'value truncated to \'scale\'', proname => 'trunc', prorettype => 'numeric', proargtypes => 'numeric int4', prosrc => 'numeric_trunc' }, { oid => '1710', descr => 'value truncated to \'scale\' of zero', - proname => 'trunc', prolang => '14', prorettype => 'numeric', + proname => 'trunc', prolang => 'sql', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'select pg_catalog.trunc($1,0)' }, { oid => '1711', descr => 'nearest integer >= value', proname => 'ceil', prorettype => 'numeric', proargtypes => 'numeric', @@ -4295,7 +4258,10 @@ proname => 'numeric', prorettype => 'numeric', proargtypes => 'int4', prosrc => 'int4_numeric' }, { oid => '1741', descr => 'base 10 logarithm', - proname => 'log', prolang => '14', prorettype => 'numeric', + proname => 'log', prolang => 'sql', prorettype => 'numeric', + proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' }, +{ oid => '1481', descr => 'base 10 logarithm', + proname => 'log10', prolang => 'sql', prorettype => 'numeric', proargtypes => 'numeric', prosrc => 'select pg_catalog.log(10, $1)' }, { oid => '1742', descr => 'convert float4 to numeric', proname => 'numeric', prorettype => 'numeric', proargtypes => 'float4', @@ -4428,7 +4394,7 @@ proname => 'quote_literal', prorettype => 'text', proargtypes => 'text', prosrc => 'quote_literal' }, { oid => '1285', descr => 'quote a data value for usage in a querystring', - proname => 'quote_literal', prolang => '14', provolatile => 's', + proname => 'quote_literal', prolang => 'sql', provolatile => 's', prorettype => 'text', proargtypes => 'anyelement', prosrc => 'select pg_catalog.quote_literal($1::pg_catalog.text)' }, { oid => '1289', @@ -4437,7 +4403,7 @@ proargtypes => 'text', prosrc => 'quote_nullable' }, { oid => '1290', descr => 'quote a possibly-null data value for usage in a querystring', - proname => 'quote_nullable', prolang => '14', proisstrict => 'f', + proname => 'quote_nullable', prolang => 'sql', proisstrict => 'f', provolatile => 's', prorettype => 'text', proargtypes => 'anyelement', prosrc => 'select pg_catalog.quote_nullable($1::pg_catalog.text)' }, @@ -4476,13 +4442,13 @@ prorettype => 'text', proargtypes => 'text', prosrc => 'text_format_nv' }, { oid => '1810', descr => 'length in bits', - proname => 'bit_length', prolang => '14', prorettype => 'int4', + proname => 'bit_length', prolang => 'sql', prorettype => 'int4', proargtypes => 'bytea', prosrc => 'select pg_catalog.octet_length($1) * 8' }, { oid => '1811', descr => 'length in bits', - proname => 'bit_length', prolang => '14', prorettype => 'int4', + proname => 'bit_length', prolang => 'sql', prorettype => 'int4', proargtypes => 'text', prosrc => 'select pg_catalog.octet_length($1) * 8' }, { oid => '1812', descr => 'length in bits', - proname => 'bit_length', prolang => '14', prorettype => 'int4', + proname => 'bit_length', prolang => 'sql', prorettype => 'int4', proargtypes => 'bit', prosrc => 'select pg_catalog.length($1)' }, # Selectivity estimators for LIKE and related operators @@ -4801,7 +4767,7 @@ prosrc => 'to_ascii_encname' }, { oid => '1848', - proname => 'interval_pl_time', prolang => '14', prorettype => 'time', + proname => 'interval_pl_time', prolang => 'sql', prorettype => 'time', proargtypes => 'interval time', prosrc => 'select $2 + $1' }, { oid => '1850', @@ -5070,6 +5036,28 @@ proname => 'pg_dependencies_send', provolatile => 's', prorettype => 'bytea', proargtypes => 'pg_dependencies', prosrc => 'pg_dependencies_send' }, +{ oid => '5018', descr => 'I/O', + proname => 'pg_mcv_list_in', prorettype => 'pg_mcv_list', + proargtypes => 'cstring', prosrc => 'pg_mcv_list_in' }, +{ oid => '5019', descr => 'I/O', + proname => 'pg_mcv_list_out', prorettype => 'cstring', + proargtypes => 'pg_mcv_list', prosrc => 'pg_mcv_list_out' }, +{ oid => '5020', descr => 'I/O', + proname => 'pg_mcv_list_recv', provolatile => 's', + prorettype => 'pg_mcv_list', proargtypes => 'internal', + prosrc => 'pg_mcv_list_recv' }, +{ oid => '5021', descr => 'I/O', + proname => 'pg_mcv_list_send', provolatile => 's', prorettype => 'bytea', + proargtypes => 'pg_mcv_list', prosrc => 'pg_mcv_list_send' }, + +{ oid => '3427', descr => 'details about MCV list items', + proname => 'pg_mcv_list_items', prorows => '1000', proretset => 't', + provolatile => 's', prorettype => 'record', proargtypes => 'pg_mcv_list', + proallargtypes => '{pg_mcv_list,int4,_text,_bool,float8,float8}', + proargmodes => '{i,o,o,o,o,o}', + proargnames => '{mcv_list,index,values,nulls,frequency,base_frequency}', + prosrc => 'pg_stats_ext_mcvlist_items' }, + { oid => '1928', descr => 'statistics: number of scans done for table/index', proname => 'pg_stat_get_numscans', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', @@ -5160,27 +5148,27 @@ proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => 'int4', - proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,bool,text}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,sslcompression,sslclientdn}', + proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,bool,text,numeric,text,bool,text,bool}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,sslcompression,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc}', prosrc => 'pg_stat_get_activity' }, { oid => '3318', descr => 'statistics: information about progress of backends running maintenance command', proname => 'pg_stat_get_progress_info', prorows => '100', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => 'text', - proallargtypes => '{text,int4,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8}', - proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{cmdtype,pid,datid,relid,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10}', + proallargtypes => '{text,int4,oid,oid,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8,int8}', + proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{cmdtype,pid,datid,relid,param1,param2,param3,param4,param5,param6,param7,param8,param9,param10,param11,param12,param13,param14,param15,param16,param17,param18,param19,param20}', prosrc => 'pg_stat_get_progress_info' }, { oid => '3099', descr => 'statistics: information about currently active replication', proname => 'pg_stat_get_wal_senders', prorows => '10', proisstrict => 'f', proretset => 't', provolatile => 's', proparallel => 'r', prorettype => 'record', proargtypes => '', - proallargtypes => '{int4,text,pg_lsn,pg_lsn,pg_lsn,pg_lsn,interval,interval,interval,int4,text}', - proargmodes => '{o,o,o,o,o,o,o,o,o,o,o}', - proargnames => '{pid,state,sent_lsn,write_lsn,flush_lsn,replay_lsn,write_lag,flush_lag,replay_lag,sync_priority,sync_state}', + proallargtypes => '{int4,text,pg_lsn,pg_lsn,pg_lsn,pg_lsn,interval,interval,interval,int4,text,timestamptz}', + proargmodes => '{o,o,o,o,o,o,o,o,o,o,o,o}', + proargnames => '{pid,state,sent_lsn,write_lsn,flush_lsn,replay_lsn,write_lag,flush_lag,replay_lag,sync_priority,sync_state,reply_time}', prosrc => 'pg_stat_get_wal_senders' }, { oid => '3317', descr => 'statistics: information about WAL receiver', proname => 'pg_stat_get_wal_receiver', proisstrict => 'f', provolatile => 's', @@ -5323,6 +5311,16 @@ proname => 'pg_stat_get_db_deadlocks', provolatile => 's', proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', prosrc => 'pg_stat_get_db_deadlocks' }, +{ oid => '3426', + descr => 'statistics: checksum failures detected in database', + proname => 'pg_stat_get_db_checksum_failures', provolatile => 's', + proparallel => 'r', prorettype => 'int8', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_checksum_failures' }, +{ oid => '3428', + descr => 'statistics: when last checksum failure was detected in database', + proname => 'pg_stat_get_db_checksum_last_failure', provolatile => 's', + proparallel => 'r', prorettype => 'timestamptz', proargtypes => 'oid', + prosrc => 'pg_stat_get_db_checksum_last_failure' }, { oid => '3074', descr => 'statistics: last reset for a database', proname => 'pg_stat_get_db_stat_reset_time', provolatile => 's', proparallel => 'r', prorettype => 'timestamptz', proargtypes => 'oid', @@ -5544,21 +5542,21 @@ proname => 'byteane', proleakproof => 't', prorettype => 'bool', proargtypes => 'bytea bytea', prosrc => 'byteane' }, { oid => '1954', descr => 'less-equal-greater', - proname => 'byteacmp', prorettype => 'int4', proargtypes => 'bytea bytea', - prosrc => 'byteacmp' }, + proname => 'byteacmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'bytea bytea', prosrc => 'byteacmp' }, { oid => '3331', descr => 'sort support', proname => 'bytea_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'bytea_sortsupport' }, -{ oid => '3917', descr => 'transform a timestamp length coercion', - proname => 'timestamp_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'timestamp_transform' }, -{ oid => '3944', descr => 'transform a time length coercion', - proname => 'time_transform', prorettype => 'internal', - proargtypes => 'internal', prosrc => 'time_transform' }, +{ oid => '3917', descr => 'planner support for timestamp length coercion', + proname => 'timestamp_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'timestamp_support' }, +{ oid => '3944', descr => 'planner support for time length coercion', + proname => 'time_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'time_support' }, { oid => '1961', descr => 'adjust timestamp precision', - proname => 'timestamp', protransform => 'timestamp_transform', + proname => 'timestamp', prosupport => 'timestamp_support', prorettype => 'timestamp', proargtypes => 'timestamp int4', prosrc => 'timestamp_scale' }, @@ -5570,34 +5568,34 @@ prosrc => 'oidsmaller' }, { oid => '1967', descr => 'adjust timestamptz precision', - proname => 'timestamptz', protransform => 'timestamp_transform', + proname => 'timestamptz', prosupport => 'timestamp_support', prorettype => 'timestamptz', proargtypes => 'timestamptz int4', prosrc => 'timestamptz_scale' }, { oid => '1968', descr => 'adjust time precision', - proname => 'time', protransform => 'time_transform', prorettype => 'time', + proname => 'time', prosupport => 'time_support', prorettype => 'time', proargtypes => 'time int4', prosrc => 'time_scale' }, { oid => '1969', descr => 'adjust time with time zone precision', - proname => 'timetz', protransform => 'time_transform', prorettype => 'timetz', + proname => 'timetz', prosupport => 'time_support', prorettype => 'timetz', proargtypes => 'timetz int4', prosrc => 'timetz_scale' }, { oid => '2003', - proname => 'textanycat', prolang => '14', provolatile => 's', + proname => 'textanycat', prolang => 'sql', provolatile => 's', prorettype => 'text', proargtypes => 'text anynonarray', prosrc => 'select $1 || $2::pg_catalog.text' }, { oid => '2004', - proname => 'anytextcat', prolang => '14', provolatile => 's', + proname => 'anytextcat', prolang => 'sql', provolatile => 's', prorettype => 'text', proargtypes => 'anynonarray text', prosrc => 'select $1::pg_catalog.text || $2' }, { oid => '2005', - proname => 'bytealike', prorettype => 'bool', proargtypes => 'bytea bytea', - prosrc => 'bytealike' }, + proname => 'bytealike', prosupport => 'textlike_support', + prorettype => 'bool', proargtypes => 'bytea bytea', prosrc => 'bytealike' }, { oid => '2006', proname => 'byteanlike', prorettype => 'bool', proargtypes => 'bytea bytea', prosrc => 'byteanlike' }, { oid => '2007', descr => 'matches LIKE expression', - proname => 'like', prorettype => 'bool', proargtypes => 'bytea bytea', - prosrc => 'bytealike' }, + proname => 'like', prosupport => 'textlike_support', prorettype => 'bool', + proargtypes => 'bytea bytea', prosrc => 'bytealike' }, { oid => '2008', descr => 'does not match LIKE expression', proname => 'notlike', prorettype => 'bool', proargtypes => 'bytea bytea', prosrc => 'byteanlike' }, @@ -5638,9 +5636,6 @@ { oid => '2021', descr => 'extract field from timestamp', proname => 'date_part', prorettype => 'float8', proargtypes => 'text timestamp', prosrc => 'timestamp_part' }, -{ oid => '2023', descr => 'convert abstime to timestamp', - proname => 'timestamp', provolatile => 's', prorettype => 'timestamp', - proargtypes => 'abstime', prosrc => 'abstime_timestamp' }, { oid => '2024', descr => 'convert date to timestamp', proname => 'timestamp', prorettype => 'timestamp', proargtypes => 'date', prosrc => 'date_timestamp' }, @@ -5656,9 +5651,6 @@ { oid => '2029', descr => 'convert timestamp to date', proname => 'date', prorettype => 'date', proargtypes => 'timestamp', prosrc => 'timestamp_date' }, -{ oid => '2030', descr => 'convert timestamp to abstime', - proname => 'abstime', provolatile => 's', prorettype => 'abstime', - proargtypes => 'timestamp', prosrc => 'timestamp_abstime' }, { oid => '2031', proname => 'timestamp_mi', prorettype => 'interval', proargtypes => 'timestamp timestamp', prosrc => 'timestamp_mi' }, @@ -5691,19 +5683,19 @@ proargtypes => 'timestamp timestamp timestamp timestamp', prosrc => 'overlaps_timestamp' }, { oid => '2042', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp interval timestamp interval', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, ($3 + $4))' }, { oid => '2043', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp timestamp timestamp interval', prosrc => 'select ($1, $2) overlaps ($3, ($3 + $4))' }, { oid => '2044', descr => 'intervals overlap?', - proname => 'overlaps', prolang => '14', proisstrict => 'f', + proname => 'overlaps', prolang => 'sql', proisstrict => 'f', prorettype => 'bool', proargtypes => 'timestamp interval timestamp timestamp', prosrc => 'select ($1, ($1 + $2)) overlaps ($3, $4)' }, { oid => '2045', descr => 'less-equal-greater', - proname => 'timestamp_cmp', prorettype => 'int4', + proname => 'timestamp_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'timestamp timestamp', prosrc => 'timestamp_cmp' }, { oid => '3137', descr => 'sort support', proname => 'timestamp_sortsupport', prorettype => 'void', @@ -5765,18 +5757,16 @@ proargtypes => 'timestamp timestamp', prosrc => 'timestamp_age' }, { oid => '2059', descr => 'date difference from today preserving months and years', - proname => 'age', prolang => '14', provolatile => 's', + proname => 'age', prolang => 'sql', provolatile => 's', prorettype => 'interval', proargtypes => 'timestamp', prosrc => 'select pg_catalog.age(cast(current_date as timestamp without time zone), $1)' }, { oid => '2069', descr => 'adjust timestamp to new time zone', - proname => 'timezone', protransform => 'timestamp_zone_transform', - prorettype => 'timestamptz', proargtypes => 'text timestamp', - prosrc => 'timestamp_zone' }, + proname => 'timezone', prorettype => 'timestamptz', + proargtypes => 'text timestamp', prosrc => 'timestamp_zone' }, { oid => '2070', descr => 'adjust timestamp to new time zone', - proname => 'timezone', protransform => 'timestamp_izone_transform', - prorettype => 'timestamptz', proargtypes => 'interval timestamp', - prosrc => 'timestamp_izone' }, + proname => 'timezone', prorettype => 'timestamptz', + proargtypes => 'interval timestamp', prosrc => 'timestamp_izone' }, { oid => '2071', proname => 'date_pl_interval', prorettype => 'timestamp', proargtypes => 'date interval', prosrc => 'date_pl_interval' }, @@ -5787,10 +5777,10 @@ { oid => '2073', descr => 'extract text matching regular expression', proname => 'substring', prorettype => 'text', proargtypes => 'text text', prosrc => 'textregexsubstr' }, -{ oid => '2074', descr => 'extract text matching SQL99 regular expression', - proname => 'substring', prolang => '14', prorettype => 'text', +{ oid => '2074', descr => 'extract text matching SQL regular expression', + proname => 'substring', prolang => 'sql', prorettype => 'text', proargtypes => 'text text text', - prosrc => 'select pg_catalog.substring($1, pg_catalog.similar_escape($2, $3))' }, + prosrc => 'select pg_catalog.substring($1, pg_catalog.similar_to_escape($2, $3))' }, { oid => '2075', descr => 'convert int8 to bitstring', proname => 'bit', prorettype => 'bit', proargtypes => 'int8 int4', @@ -5904,7 +5894,7 @@ prorettype => 'record', proargtypes => 'text _text _text', proallargtypes => '{text,_text,_text,oid,oid,int4}', proargmodes => '{i,i,i,o,o,o}', - proargnames => '{type,name,args,classid,objid,objsubid}', + proargnames => '{type,object_names,object_args,classid,objid,objsubid}', prosrc => 'pg_get_object_address' }, { oid => '2079', descr => 'is table visible in search path?', @@ -5994,6 +5984,10 @@ proname => 'pg_backup_start_time', provolatile => 's', prorettype => 'timestamptz', proargtypes => '', prosrc => 'pg_backup_start_time' }, +{ oid => '3436', descr => 'promote standby server', + proname => 'pg_promote', provolatile => 'v', prorettype => 'bool', + proargtypes => 'bool int4', proargnames => '{wait,wait_seconds}', + prosrc => 'pg_promote' }, { oid => '2848', descr => 'switch to new wal file', proname => 'pg_switch_wal', provolatile => 'v', prorettype => 'pg_lsn', proargtypes => '', prosrc => 'pg_switch_wal' }, @@ -6123,11 +6117,11 @@ proname => 'pg_sleep', provolatile => 'v', prorettype => 'void', proargtypes => 'float8', prosrc => 'pg_sleep' }, { oid => '3935', descr => 'sleep for the specified interval', - proname => 'pg_sleep_for', prolang => '14', provolatile => 'v', + proname => 'pg_sleep_for', prolang => 'sql', provolatile => 'v', prorettype => 'void', proargtypes => 'interval', prosrc => 'select pg_catalog.pg_sleep(extract(epoch from pg_catalog.clock_timestamp() operator(pg_catalog.+) $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))' }, { oid => '3936', descr => 'sleep until the specified time', - proname => 'pg_sleep_until', prolang => '14', provolatile => 'v', + proname => 'pg_sleep_until', prolang => 'sql', provolatile => 'v', prorettype => 'void', proargtypes => 'timestamptz', prosrc => 'select pg_catalog.pg_sleep(extract(epoch from $1) operator(pg_catalog.-) extract(epoch from pg_catalog.clock_timestamp()))' }, { oid => '315', descr => 'Is JIT compilation available in this session?', @@ -6214,9 +6208,6 @@ { oid => '2120', descr => 'maximum value of all float8 input values', proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'float8', proargtypes => 'float8', prosrc => 'aggregate_dummy' }, -{ oid => '2121', descr => 'maximum value of all abstime input values', - proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'abstime', - proargtypes => 'abstime', prosrc => 'aggregate_dummy' }, { oid => '2122', descr => 'maximum value of all date input values', proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'date', proargtypes => 'date', prosrc => 'aggregate_dummy' }, @@ -6262,6 +6253,9 @@ { oid => '3564', descr => 'maximum value of all inet input values', proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'inet', proargtypes => 'inet', prosrc => 'aggregate_dummy' }, +{ oid => '4189', descr => 'maximum value of all pg_lsn input values', + proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'pg_lsn', + proargtypes => 'pg_lsn', prosrc => 'aggregate_dummy' }, { oid => '2131', descr => 'minimum value of all bigint input values', proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'int8', @@ -6281,9 +6275,6 @@ { oid => '2136', descr => 'minimum value of all float8 input values', proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'float8', proargtypes => 'float8', prosrc => 'aggregate_dummy' }, -{ oid => '2137', descr => 'minimum value of all abstime input values', - proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'abstime', - proargtypes => 'abstime', prosrc => 'aggregate_dummy' }, { oid => '2138', descr => 'minimum value of all date input values', proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'date', proargtypes => 'date', prosrc => 'aggregate_dummy' }, @@ -6329,6 +6320,9 @@ { oid => '3565', descr => 'minimum value of all inet input values', proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'inet', proargtypes => 'inet', prosrc => 'aggregate_dummy' }, +{ oid => '4190', descr => 'minimum value of all pg_lsn input values', + proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'pg_lsn', + proargtypes => 'pg_lsn', prosrc => 'aggregate_dummy' }, # count has two forms: count(any) and count(*) { oid => '2147', @@ -6547,66 +6541,66 @@ proargtypes => 'float8 float8', prosrc => 'aggregate_dummy' }, { oid => '2160', - proname => 'text_pattern_lt', prorettype => 'bool', + proname => 'text_pattern_lt', proleakproof => 't', prorettype => 'bool', proargtypes => 'text text', prosrc => 'text_pattern_lt' }, { oid => '2161', - proname => 'text_pattern_le', prorettype => 'bool', + proname => 'text_pattern_le', proleakproof => 't', prorettype => 'bool', proargtypes => 'text text', prosrc => 'text_pattern_le' }, { oid => '2163', - proname => 'text_pattern_ge', prorettype => 'bool', + proname => 'text_pattern_ge', proleakproof => 't', prorettype => 'bool', proargtypes => 'text text', prosrc => 'text_pattern_ge' }, { oid => '2164', - proname => 'text_pattern_gt', prorettype => 'bool', + proname => 'text_pattern_gt', proleakproof => 't', prorettype => 'bool', proargtypes => 'text text', prosrc => 'text_pattern_gt' }, { oid => '2166', descr => 'less-equal-greater', - proname => 'bttext_pattern_cmp', prorettype => 'int4', + proname => 'bttext_pattern_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'text text', prosrc => 'bttext_pattern_cmp' }, { oid => '3332', descr => 'sort support', proname => 'bttext_pattern_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'bttext_pattern_sortsupport' }, { oid => '2174', - proname => 'bpchar_pattern_lt', prorettype => 'bool', + proname => 'bpchar_pattern_lt', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_pattern_lt' }, { oid => '2175', - proname => 'bpchar_pattern_le', prorettype => 'bool', + proname => 'bpchar_pattern_le', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_pattern_le' }, { oid => '2177', - proname => 'bpchar_pattern_ge', prorettype => 'bool', + proname => 'bpchar_pattern_ge', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_pattern_ge' }, { oid => '2178', - proname => 'bpchar_pattern_gt', prorettype => 'bool', + proname => 'bpchar_pattern_gt', proleakproof => 't', prorettype => 'bool', proargtypes => 'bpchar bpchar', prosrc => 'bpchar_pattern_gt' }, { oid => '2180', descr => 'less-equal-greater', - proname => 'btbpchar_pattern_cmp', prorettype => 'int4', + proname => 'btbpchar_pattern_cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'bpchar bpchar', prosrc => 'btbpchar_pattern_cmp' }, { oid => '3333', descr => 'sort support', proname => 'btbpchar_pattern_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'btbpchar_pattern_sortsupport' }, { oid => '2188', descr => 'less-equal-greater', - proname => 'btint48cmp', prorettype => 'int4', proargtypes => 'int4 int8', - prosrc => 'btint48cmp' }, + proname => 'btint48cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int4 int8', prosrc => 'btint48cmp' }, { oid => '2189', descr => 'less-equal-greater', - proname => 'btint84cmp', prorettype => 'int4', proargtypes => 'int8 int4', - prosrc => 'btint84cmp' }, + proname => 'btint84cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int8 int4', prosrc => 'btint84cmp' }, { oid => '2190', descr => 'less-equal-greater', - proname => 'btint24cmp', prorettype => 'int4', proargtypes => 'int2 int4', - prosrc => 'btint24cmp' }, + proname => 'btint24cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int2 int4', prosrc => 'btint24cmp' }, { oid => '2191', descr => 'less-equal-greater', - proname => 'btint42cmp', prorettype => 'int4', proargtypes => 'int4 int2', - prosrc => 'btint42cmp' }, + proname => 'btint42cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int4 int2', prosrc => 'btint42cmp' }, { oid => '2192', descr => 'less-equal-greater', - proname => 'btint28cmp', prorettype => 'int4', proargtypes => 'int2 int8', - prosrc => 'btint28cmp' }, + proname => 'btint28cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int2 int8', prosrc => 'btint28cmp' }, { oid => '2193', descr => 'less-equal-greater', - proname => 'btint82cmp', prorettype => 'int4', proargtypes => 'int8 int2', - prosrc => 'btint82cmp' }, + proname => 'btint82cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'int8 int2', prosrc => 'btint82cmp' }, { oid => '2194', descr => 'less-equal-greater', - proname => 'btfloat48cmp', prorettype => 'int4', + proname => 'btfloat48cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'float4 float8', prosrc => 'btfloat48cmp' }, { oid => '2195', descr => 'less-equal-greater', - proname => 'btfloat84cmp', prorettype => 'int4', + proname => 'btfloat84cmp', proleakproof => 't', prorettype => 'int4', proargtypes => 'float8 float4', prosrc => 'btfloat84cmp' }, { oid => '2212', descr => 'I/O', @@ -6928,9 +6922,9 @@ proargtypes => 'name', prosrc => 'pg_database_size_name' }, { oid => '2325', descr => 'disk space usage for the main fork of the specified table or index', - proname => 'pg_relation_size', prolang => '14', provolatile => 'v', + proname => 'pg_relation_size', prolang => 'sql', provolatile => 'v', prorettype => 'int8', proargtypes => 'regclass', - prosrc => 'select pg_catalog.pg_relation_size($1, \'\'main\'\')' }, + prosrc => 'select pg_catalog.pg_relation_size($1, \'main\')' }, { oid => '2332', descr => 'disk space usage for the specified fork of a table or index', proname => 'pg_relation_size', provolatile => 'v', prorettype => 'int8', @@ -7081,6 +7075,13 @@ { oid => '3312', descr => 'I/O', proname => 'tsm_handler_out', prorettype => 'cstring', proargtypes => 'tsm_handler', prosrc => 'tsm_handler_out' }, +{ oid => '267', descr => 'I/O', + proname => 'table_am_handler_in', proisstrict => 'f', + prorettype => 'table_am_handler', proargtypes => 'cstring', + prosrc => 'table_am_handler_in' }, +{ oid => '268', descr => 'I/O', + proname => 'table_am_handler_out', prorettype => 'cstring', + proargtypes => 'table_am_handler', prosrc => 'table_am_handler_out' }, # tablesample method handlers { oid => '3313', descr => 'BERNOULLI tablesample method handler', @@ -7458,24 +7459,6 @@ { oid => '2461', descr => 'I/O', proname => 'numeric_send', prorettype => 'bytea', proargtypes => 'numeric', prosrc => 'numeric_send' }, -{ oid => '2462', descr => 'I/O', - proname => 'abstimerecv', prorettype => 'abstime', proargtypes => 'internal', - prosrc => 'abstimerecv' }, -{ oid => '2463', descr => 'I/O', - proname => 'abstimesend', prorettype => 'bytea', proargtypes => 'abstime', - prosrc => 'abstimesend' }, -{ oid => '2464', descr => 'I/O', - proname => 'reltimerecv', prorettype => 'reltime', proargtypes => 'internal', - prosrc => 'reltimerecv' }, -{ oid => '2465', descr => 'I/O', - proname => 'reltimesend', prorettype => 'bytea', proargtypes => 'reltime', - prosrc => 'reltimesend' }, -{ oid => '2466', descr => 'I/O', - proname => 'tintervalrecv', prorettype => 'tinterval', - proargtypes => 'internal', prosrc => 'tintervalrecv' }, -{ oid => '2467', descr => 'I/O', - proname => 'tintervalsend', prorettype => 'bytea', proargtypes => 'tinterval', - prosrc => 'tintervalsend' }, { oid => '2468', descr => 'I/O', proname => 'date_recv', prorettype => 'date', proargtypes => 'internal', prosrc => 'date_recv' }, @@ -7675,21 +7658,31 @@ # non-persistent series generator { oid => '1066', descr => 'non-persistent series generator', - proname => 'generate_series', prorows => '1000', proretset => 't', + proname => 'generate_series', prorows => '1000', + prosupport => 'generate_series_int4_support', proretset => 't', prorettype => 'int4', proargtypes => 'int4 int4 int4', prosrc => 'generate_series_step_int4' }, { oid => '1067', descr => 'non-persistent series generator', - proname => 'generate_series', prorows => '1000', proretset => 't', + proname => 'generate_series', prorows => '1000', + prosupport => 'generate_series_int4_support', proretset => 't', prorettype => 'int4', proargtypes => 'int4 int4', prosrc => 'generate_series_int4' }, +{ oid => '3994', descr => 'planner support for generate_series', + proname => 'generate_series_int4_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'generate_series_int4_support' }, { oid => '1068', descr => 'non-persistent series generator', - proname => 'generate_series', prorows => '1000', proretset => 't', + proname => 'generate_series', prorows => '1000', + prosupport => 'generate_series_int8_support', proretset => 't', prorettype => 'int8', proargtypes => 'int8 int8 int8', prosrc => 'generate_series_step_int8' }, { oid => '1069', descr => 'non-persistent series generator', - proname => 'generate_series', prorows => '1000', proretset => 't', + proname => 'generate_series', prorows => '1000', + prosupport => 'generate_series_int8_support', proretset => 't', prorettype => 'int8', proargtypes => 'int8 int8', prosrc => 'generate_series_int8' }, +{ oid => '3995', descr => 'planner support for generate_series', + proname => 'generate_series_int8_support', prorettype => 'internal', + proargtypes => 'internal', prosrc => 'generate_series_int8_support' }, { oid => '3259', descr => 'non-persistent series generator', proname => 'generate_series', prorows => '1000', proretset => 't', prorettype => 'numeric', proargtypes => 'numeric numeric numeric', @@ -7767,21 +7760,21 @@ # formerly-missing interval + datetime operators { oid => '2546', - proname => 'interval_pl_date', prolang => '14', prorettype => 'timestamp', + proname => 'interval_pl_date', prolang => 'sql', prorettype => 'timestamp', proargtypes => 'interval date', prosrc => 'select $2 + $1' }, { oid => '2547', - proname => 'interval_pl_timetz', prolang => '14', prorettype => 'timetz', + proname => 'interval_pl_timetz', prolang => 'sql', prorettype => 'timetz', proargtypes => 'interval timetz', prosrc => 'select $2 + $1' }, { oid => '2548', - proname => 'interval_pl_timestamp', prolang => '14', + proname => 'interval_pl_timestamp', prolang => 'sql', prorettype => 'timestamp', proargtypes => 'interval timestamp', prosrc => 'select $2 + $1' }, { oid => '2549', - proname => 'interval_pl_timestamptz', prolang => '14', provolatile => 's', + proname => 'interval_pl_timestamptz', prolang => 'sql', provolatile => 's', prorettype => 'timestamptz', proargtypes => 'interval timestamptz', prosrc => 'select $2 + $1' }, { oid => '2550', - proname => 'integer_pl_date', prolang => '14', prorettype => 'date', + proname => 'integer_pl_date', prolang => 'sql', prorettype => 'date', proargtypes => 'int4 date', prosrc => 'select $2 + $1' }, { oid => '2556', descr => 'get OIDs of databases in a tablespace', @@ -7860,6 +7853,10 @@ { oid => '2584', descr => 'GiST support', proname => 'gist_box_same', prorettype => 'internal', proargtypes => 'box box internal', prosrc => 'gist_box_same' }, +{ oid => '3998', descr => 'GiST support', + proname => 'gist_box_distance', prorettype => 'float8', + proargtypes => 'internal box int2 oid internal', + prosrc => 'gist_box_distance' }, { oid => '2585', descr => 'GiST support', proname => 'gist_poly_consistent', prorettype => 'bool', proargtypes => 'internal polygon int2 oid internal', @@ -7963,87 +7960,87 @@ # userlock replacements { oid => '2880', descr => 'obtain exclusive advisory lock', - proname => 'pg_advisory_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_lock', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int8', prosrc => 'pg_advisory_lock_int8' }, { oid => '3089', descr => 'obtain exclusive advisory lock', - proname => 'pg_advisory_xact_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_xact_lock', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int8', prosrc => 'pg_advisory_xact_lock_int8' }, { oid => '2881', descr => 'obtain shared advisory lock', - proname => 'pg_advisory_lock_shared', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_lock_shared', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int8', prosrc => 'pg_advisory_lock_shared_int8' }, { oid => '3090', descr => 'obtain shared advisory lock', proname => 'pg_advisory_xact_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'void', proargtypes => 'int8', + proparallel => 'r', prorettype => 'void', proargtypes => 'int8', prosrc => 'pg_advisory_xact_lock_shared_int8' }, { oid => '2882', descr => 'obtain exclusive advisory lock if available', - proname => 'pg_try_advisory_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_try_advisory_lock', provolatile => 'v', proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_try_advisory_lock_int8' }, { oid => '3091', descr => 'obtain exclusive advisory lock if available', proname => 'pg_try_advisory_xact_lock', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int8', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_try_advisory_xact_lock_int8' }, { oid => '2883', descr => 'obtain shared advisory lock if available', proname => 'pg_try_advisory_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int8', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_try_advisory_lock_shared_int8' }, { oid => '3092', descr => 'obtain shared advisory lock if available', proname => 'pg_try_advisory_xact_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int8', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_try_advisory_xact_lock_shared_int8' }, { oid => '2884', descr => 'release exclusive advisory lock', - proname => 'pg_advisory_unlock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_unlock', provolatile => 'v', proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_advisory_unlock_int8' }, { oid => '2885', descr => 'release shared advisory lock', proname => 'pg_advisory_unlock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int8', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int8', prosrc => 'pg_advisory_unlock_shared_int8' }, { oid => '2886', descr => 'obtain exclusive advisory lock', - proname => 'pg_advisory_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_lock', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int4 int4', prosrc => 'pg_advisory_lock_int4' }, { oid => '3093', descr => 'obtain exclusive advisory lock', - proname => 'pg_advisory_xact_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_xact_lock', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int4 int4', prosrc => 'pg_advisory_xact_lock_int4' }, { oid => '2887', descr => 'obtain shared advisory lock', - proname => 'pg_advisory_lock_shared', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_lock_shared', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'int4 int4', prosrc => 'pg_advisory_lock_shared_int4' }, { oid => '3094', descr => 'obtain shared advisory lock', proname => 'pg_advisory_xact_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'void', proargtypes => 'int4 int4', + proparallel => 'r', prorettype => 'void', proargtypes => 'int4 int4', prosrc => 'pg_advisory_xact_lock_shared_int4' }, { oid => '2888', descr => 'obtain exclusive advisory lock if available', - proname => 'pg_try_advisory_lock', provolatile => 'v', proparallel => 'u', + proname => 'pg_try_advisory_lock', provolatile => 'v', proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_try_advisory_lock_int4' }, { oid => '3095', descr => 'obtain exclusive advisory lock if available', proname => 'pg_try_advisory_xact_lock', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int4 int4', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_try_advisory_xact_lock_int4' }, { oid => '2889', descr => 'obtain shared advisory lock if available', proname => 'pg_try_advisory_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int4 int4', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_try_advisory_lock_shared_int4' }, { oid => '3096', descr => 'obtain shared advisory lock if available', proname => 'pg_try_advisory_xact_lock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int4 int4', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_try_advisory_xact_lock_shared_int4' }, { oid => '2890', descr => 'release exclusive advisory lock', - proname => 'pg_advisory_unlock', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_unlock', provolatile => 'v', proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_advisory_unlock_int4' }, { oid => '2891', descr => 'release shared advisory lock', proname => 'pg_advisory_unlock_shared', provolatile => 'v', - proparallel => 'u', prorettype => 'bool', proargtypes => 'int4 int4', + proparallel => 'r', prorettype => 'bool', proargtypes => 'int4 int4', prosrc => 'pg_advisory_unlock_shared_int4' }, { oid => '2892', descr => 'release all advisory locks', - proname => 'pg_advisory_unlock_all', provolatile => 'v', proparallel => 'u', + proname => 'pg_advisory_unlock_all', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => '', prosrc => 'pg_advisory_unlock_all' }, # XML support @@ -8166,9 +8163,9 @@ proname => 'xpath', prorettype => '_xml', proargtypes => 'text xml _text', prosrc => 'xpath' }, { oid => '2932', descr => 'evaluate XPath expression', - proname => 'xpath', prolang => '14', prorettype => '_xml', + proname => 'xpath', prolang => 'sql', prorettype => '_xml', proargtypes => 'text xml', - prosrc => 'select pg_catalog.xpath($1, $2, \'\'{}\'\'::pg_catalog.text[])' }, + prosrc => 'select pg_catalog.xpath($1, $2, \'{}\'::pg_catalog.text[])' }, { oid => '2614', descr => 'test XML value against XPath expression', proname => 'xmlexists', prorettype => 'bool', proargtypes => 'text xml', @@ -8179,9 +8176,9 @@ proname => 'xpath_exists', prorettype => 'bool', proargtypes => 'text xml _text', prosrc => 'xpath_exists' }, { oid => '3050', descr => 'test XML value against XPath expression', - proname => 'xpath_exists', prolang => '14', prorettype => 'bool', + proname => 'xpath_exists', prolang => 'sql', prorettype => 'bool', proargtypes => 'text xml', - prosrc => 'select pg_catalog.xpath_exists($1, $2, \'\'{}\'\'::pg_catalog.text[])' }, + prosrc => 'select pg_catalog.xpath_exists($1, $2, \'{}\'::pg_catalog.text[])' }, { oid => '3051', descr => 'determine if a string is well formed XML', proname => 'xml_is_well_formed', provolatile => 's', prorettype => 'bool', proargtypes => 'text', prosrc => 'xml_is_well_formed' }, @@ -8371,8 +8368,8 @@ proname => 'uuid_ne', proleakproof => 't', prorettype => 'bool', proargtypes => 'uuid uuid', prosrc => 'uuid_ne' }, { oid => '2960', descr => 'less-equal-greater', - proname => 'uuid_cmp', prorettype => 'int4', proargtypes => 'uuid uuid', - prosrc => 'uuid_cmp' }, + proname => 'uuid_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'uuid uuid', prosrc => 'uuid_cmp' }, { oid => '3300', descr => 'sort support', proname => 'uuid_sortsupport', prorettype => 'void', proargtypes => 'internal', prosrc => 'uuid_sortsupport' }, @@ -8388,6 +8385,9 @@ { oid => '3412', descr => 'hash', proname => 'uuid_hash_extended', prorettype => 'int8', proargtypes => 'uuid int8', prosrc => 'uuid_hash_extended' }, +{ oid => '3432', descr => 'generate random UUID', + proname => 'gen_random_uuid', proleakproof => 't', prorettype => 'uuid', + proargtypes => '', prosrc => 'gen_random_uuid' }, # pg_lsn { oid => '3229', descr => 'I/O', @@ -8397,23 +8397,23 @@ proname => 'pg_lsn_out', prorettype => 'cstring', proargtypes => 'pg_lsn', prosrc => 'pg_lsn_out' }, { oid => '3231', - proname => 'pg_lsn_lt', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_lt' }, + proname => 'pg_lsn_lt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_lt' }, { oid => '3232', - proname => 'pg_lsn_le', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_le' }, + proname => 'pg_lsn_le', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_le' }, { oid => '3233', - proname => 'pg_lsn_eq', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_eq' }, + proname => 'pg_lsn_eq', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_eq' }, { oid => '3234', - proname => 'pg_lsn_ge', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_ge' }, + proname => 'pg_lsn_ge', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_ge' }, { oid => '3235', - proname => 'pg_lsn_gt', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_gt' }, + proname => 'pg_lsn_gt', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_gt' }, { oid => '3236', - proname => 'pg_lsn_ne', prorettype => 'bool', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_ne' }, + proname => 'pg_lsn_ne', proleakproof => 't', prorettype => 'bool', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_ne' }, { oid => '3237', proname => 'pg_lsn_mi', prorettype => 'numeric', proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_mi' }, @@ -8424,14 +8424,20 @@ proname => 'pg_lsn_send', prorettype => 'bytea', proargtypes => 'pg_lsn', prosrc => 'pg_lsn_send' }, { oid => '3251', descr => 'less-equal-greater', - proname => 'pg_lsn_cmp', prorettype => 'int4', proargtypes => 'pg_lsn pg_lsn', - prosrc => 'pg_lsn_cmp' }, + proname => 'pg_lsn_cmp', proleakproof => 't', prorettype => 'int4', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_cmp' }, { oid => '3252', descr => 'hash', proname => 'pg_lsn_hash', prorettype => 'int4', proargtypes => 'pg_lsn', prosrc => 'pg_lsn_hash' }, { oid => '3413', descr => 'hash', proname => 'pg_lsn_hash_extended', prorettype => 'int8', proargtypes => 'pg_lsn int8', prosrc => 'pg_lsn_hash_extended' }, +{ oid => '4187', descr => 'larger of two', + proname => 'pg_lsn_larger', prorettype => 'pg_lsn', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_larger' }, +{ oid => '4188', descr => 'smaller of two', + proname => 'pg_lsn_smaller', prorettype => 'pg_lsn', + proargtypes => 'pg_lsn pg_lsn', prosrc => 'pg_lsn_smaller' }, # enum related procs { oid => '3504', descr => 'I/O', @@ -9293,6 +9299,68 @@ proname => 'jsonb_insert', prorettype => 'jsonb', proargtypes => 'jsonb _text jsonb bool', prosrc => 'jsonb_insert' }, +# jsonpath +{ oid => '4001', descr => 'I/O', + proname => 'jsonpath_in', prorettype => 'jsonpath', proargtypes => 'cstring', + prosrc => 'jsonpath_in' }, +{ oid => '4002', descr => 'I/O', + proname => 'jsonpath_recv', prorettype => 'jsonpath', + proargtypes => 'internal', prosrc => 'jsonpath_recv' }, +{ oid => '4003', descr => 'I/O', + proname => 'jsonpath_out', prorettype => 'cstring', proargtypes => 'jsonpath', + prosrc => 'jsonpath_out' }, +{ oid => '4004', descr => 'I/O', + proname => 'jsonpath_send', prorettype => 'bytea', proargtypes => 'jsonpath', + prosrc => 'jsonpath_send' }, + +{ oid => '4005', descr => 'jsonpath exists test', + proname => 'jsonb_path_exists', prorettype => 'bool', + proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_exists' }, +{ oid => '4006', descr => 'jsonpath query', + proname => 'jsonb_path_query', prorows => '1000', proretset => 't', + prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query' }, +{ oid => '4007', descr => 'jsonpath query wrapped into array', + proname => 'jsonb_path_query_array', prorettype => 'jsonb', + proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query_array' }, +{ oid => '4008', descr => 'jsonpath query first item', + proname => 'jsonb_path_query_first', prorettype => 'jsonb', + proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query_first' }, +{ oid => '4009', descr => 'jsonpath match', + proname => 'jsonb_path_match', prorettype => 'bool', + proargtypes => 'jsonb jsonpath jsonb bool', prosrc => 'jsonb_path_match' }, + +{ oid => '1177', descr => 'jsonpath exists test with timezone', + proname => 'jsonb_path_exists_tz', provolatile => 's', + prorettype => 'bool', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_exists_tz' }, +{ oid => '1179', descr => 'jsonpath query with timezone', + proname => 'jsonb_path_query_tz', provolatile => 's', + prorows => '1000', proretset => 't', + prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query_tz' }, +{ oid => '1180', descr => 'jsonpath query wrapped into array with timezone', + proname => 'jsonb_path_query_array_tz', provolatile => 's', + prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query_array_tz' }, +{ oid => '2023', descr => 'jsonpath query first item with timezone', + proname => 'jsonb_path_query_first_tz', provolatile => 's', + prorettype => 'jsonb', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_query_first_tz' }, +{ oid => '2030', descr => 'jsonpath match with timezone', + proname => 'jsonb_path_match_tz', provolatile => 's', + prorettype => 'bool', proargtypes => 'jsonb jsonpath jsonb bool', + prosrc => 'jsonb_path_match_tz' }, + +{ oid => '4010', descr => 'implementation of @? operator', + proname => 'jsonb_path_exists_opr', prorettype => 'bool', + proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_path_exists_opr' }, +{ oid => '4011', descr => 'implementation of @@ operator', + proname => 'jsonb_path_match_opr', prorettype => 'bool', + proargtypes => 'jsonb jsonpath', prosrc => 'jsonb_path_match_opr' }, + # txid { oid => '2939', descr => 'I/O', proname => 'txid_snapshot_in', prorettype => 'txid_snapshot', @@ -9784,6 +9852,20 @@ proargmodes => '{i,i,i,o,o}', proargnames => '{slot_name,immediately_reserve,temporary,slot_name,lsn}', prosrc => 'pg_create_physical_replication_slot' }, +{ oid => '4220', + descr => 'copy a physical replication slot, changing temporality', + proname => 'pg_copy_physical_replication_slot', provolatile => 'v', + proparallel => 'u', prorettype => 'record', proargtypes => 'name name bool', + proallargtypes => '{name,name,bool,name,pg_lsn}', + proargmodes => '{i,i,i,o,o}', + proargnames => '{src_slot_name,dst_slot_name,temporary,slot_name,lsn}', + prosrc => 'pg_copy_physical_replication_slot_a' }, +{ oid => '4221', descr => 'copy a physical replication slot', + proname => 'pg_copy_physical_replication_slot', provolatile => 'v', + proparallel => 'u', prorettype => 'record', proargtypes => 'name name', + proallargtypes => '{name,name,name,pg_lsn}', proargmodes => '{i,i,o,o}', + proargnames => '{src_slot_name,dst_slot_name,slot_name,lsn}', + prosrc => 'pg_copy_physical_replication_slot_b' }, { oid => '3780', descr => 'drop a replication slot', proname => 'pg_drop_replication_slot', provolatile => 'v', proparallel => 'u', prorettype => 'void', proargtypes => 'name', @@ -9800,10 +9882,33 @@ { oid => '3786', descr => 'set up a logical replication slot', proname => 'pg_create_logical_replication_slot', provolatile => 'v', proparallel => 'u', prorettype => 'record', proargtypes => 'name name bool', - proallargtypes => '{name,name,bool,text,pg_lsn}', + proallargtypes => '{name,name,bool,name,pg_lsn}', proargmodes => '{i,i,i,o,o}', proargnames => '{slot_name,plugin,temporary,slot_name,lsn}', prosrc => 'pg_create_logical_replication_slot' }, +{ oid => '4222', + descr => 'copy a logical replication slot, changing temporality and plugin', + proname => 'pg_copy_logical_replication_slot', provolatile => 'v', + proparallel => 'u', prorettype => 'record', + proargtypes => 'name name bool name', + proallargtypes => '{name,name,bool,name,name,pg_lsn}', + proargmodes => '{i,i,i,i,o,o}', + proargnames => '{src_slot_name,dst_slot_name,temporary,plugin,slot_name,lsn}', + prosrc => 'pg_copy_logical_replication_slot_a' }, +{ oid => '4223', + descr => 'copy a logical replication slot, changing temporality', + proname => 'pg_copy_logical_replication_slot', provolatile => 'v', + proparallel => 'u', prorettype => 'record', proargtypes => 'name name bool', + proallargtypes => '{name,name,bool,name,pg_lsn}', + proargmodes => '{i,i,i,o,o}', + proargnames => '{src_slot_name,dst_slot_name,temporary,slot_name,lsn}', + prosrc => 'pg_copy_logical_replication_slot_b' }, +{ oid => '4224', descr => 'copy a logical replication slot', + proname => 'pg_copy_logical_replication_slot', provolatile => 'v', + proparallel => 'u', prorettype => 'record', proargtypes => 'name name', + proallargtypes => '{name,name,name,pg_lsn}', proargmodes => '{i,i,o,o}', + proargnames => '{src_slot_name,dst_slot_name,slot_name,lsn}', + prosrc => 'pg_copy_logical_replication_slot_c' }, { oid => '3782', descr => 'get changes from replication slot', proname => 'pg_logical_slot_get_changes', procost => '1000', prorows => '1000', provariadic => 'text', proisstrict => 'f', @@ -10034,6 +10139,398 @@ proname => 'binary_upgrade_set_record_init_privs', provolatile => 'v', proparallel => 'r', prorettype => 'void', proargtypes => 'bool', prosrc => 'binary_upgrade_set_record_init_privs' }, +{ oid => '4101', descr => 'for use by pg_upgrade', + proname => 'binary_upgrade_set_missing_value', provolatile => 'v', + proparallel => 'u', prorettype => 'void', proargtypes => 'oid text text', + prosrc => 'binary_upgrade_set_missing_value' }, + +# conversion functions +{ oid => '4302', + descr => 'internal conversion function for KOI8R to MULE_INTERNAL', + proname => 'koi8r_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'koi8r_to_mic', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4303', + descr => 'internal conversion function for MULE_INTERNAL to KOI8R', + proname => 'mic_to_koi8r', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_koi8r', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4304', + descr => 'internal conversion function for ISO-8859-5 to MULE_INTERNAL', + proname => 'iso_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'iso_to_mic', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4305', + descr => 'internal conversion function for MULE_INTERNAL to ISO-8859-5', + proname => 'mic_to_iso', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_iso', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4306', + descr => 'internal conversion function for WIN1251 to MULE_INTERNAL', + proname => 'win1251_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win1251_to_mic', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4307', + descr => 'internal conversion function for MULE_INTERNAL to WIN1251', + proname => 'mic_to_win1251', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_win1251', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4308', + descr => 'internal conversion function for WIN866 to MULE_INTERNAL', + proname => 'win866_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win866_to_mic', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4309', + descr => 'internal conversion function for MULE_INTERNAL to WIN866', + proname => 'mic_to_win866', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_win866', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4310', descr => 'internal conversion function for KOI8R to WIN1251', + proname => 'koi8r_to_win1251', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'koi8r_to_win1251', probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4311', descr => 'internal conversion function for WIN1251 to KOI8R', + proname => 'win1251_to_koi8r', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'win1251_to_koi8r', probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4312', descr => 'internal conversion function for KOI8R to WIN866', + proname => 'koi8r_to_win866', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'koi8r_to_win866', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4313', descr => 'internal conversion function for WIN866 to KOI8R', + proname => 'win866_to_koi8r', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win866_to_koi8r', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4314', + descr => 'internal conversion function for WIN866 to WIN1251', + proname => 'win866_to_win1251', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'win866_to_win1251', probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4315', + descr => 'internal conversion function for WIN1251 to WIN866', + proname => 'win1251_to_win866', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'win1251_to_win866', probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4316', + descr => 'internal conversion function for ISO-8859-5 to KOI8R', + proname => 'iso_to_koi8r', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'iso_to_koi8r', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4317', + descr => 'internal conversion function for KOI8R to ISO-8859-5', + proname => 'koi8r_to_iso', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'koi8r_to_iso', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4318', + descr => 'internal conversion function for ISO-8859-5 to WIN1251', + proname => 'iso_to_win1251', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'iso_to_win1251', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4319', + descr => 'internal conversion function for WIN1251 to ISO-8859-5', + proname => 'win1251_to_iso', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win1251_to_iso', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4320', + descr => 'internal conversion function for ISO-8859-5 to WIN866', + proname => 'iso_to_win866', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'iso_to_win866', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4321', + descr => 'internal conversion function for WIN866 to ISO-8859-5', + proname => 'win866_to_iso', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win866_to_iso', + probin => '$libdir/cyrillic_and_mic' }, +{ oid => '4322', + descr => 'internal conversion function for EUC_CN to MULE_INTERNAL', + proname => 'euc_cn_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_cn_to_mic', + probin => '$libdir/euc_cn_and_mic' }, +{ oid => '4323', + descr => 'internal conversion function for MULE_INTERNAL to EUC_CN', + proname => 'mic_to_euc_cn', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_euc_cn', + probin => '$libdir/euc_cn_and_mic' }, +{ oid => '4324', descr => 'internal conversion function for EUC_JP to SJIS', + proname => 'euc_jp_to_sjis', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_jp_to_sjis', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4325', descr => 'internal conversion function for SJIS to EUC_JP', + proname => 'sjis_to_euc_jp', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'sjis_to_euc_jp', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4326', + descr => 'internal conversion function for EUC_JP to MULE_INTERNAL', + proname => 'euc_jp_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_jp_to_mic', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4327', + descr => 'internal conversion function for SJIS to MULE_INTERNAL', + proname => 'sjis_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'sjis_to_mic', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4328', + descr => 'internal conversion function for MULE_INTERNAL to EUC_JP', + proname => 'mic_to_euc_jp', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_euc_jp', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4329', + descr => 'internal conversion function for MULE_INTERNAL to SJIS', + proname => 'mic_to_sjis', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_sjis', + probin => '$libdir/euc_jp_and_sjis' }, +{ oid => '4330', + descr => 'internal conversion function for EUC_KR to MULE_INTERNAL', + proname => 'euc_kr_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_kr_to_mic', + probin => '$libdir/euc_kr_and_mic' }, +{ oid => '4331', + descr => 'internal conversion function for MULE_INTERNAL to EUC_KR', + proname => 'mic_to_euc_kr', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_euc_kr', + probin => '$libdir/euc_kr_and_mic' }, +{ oid => '4332', descr => 'internal conversion function for EUC_TW to BIG5', + proname => 'euc_tw_to_big5', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_tw_to_big5', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4333', descr => 'internal conversion function for BIG5 to EUC_TW', + proname => 'big5_to_euc_tw', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'big5_to_euc_tw', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4334', + descr => 'internal conversion function for EUC_TW to MULE_INTERNAL', + proname => 'euc_tw_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_tw_to_mic', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4335', + descr => 'internal conversion function for BIG5 to MULE_INTERNAL', + proname => 'big5_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'big5_to_mic', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4336', + descr => 'internal conversion function for MULE_INTERNAL to EUC_TW', + proname => 'mic_to_euc_tw', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_euc_tw', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4337', + descr => 'internal conversion function for MULE_INTERNAL to BIG5', + proname => 'mic_to_big5', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_big5', + probin => '$libdir/euc_tw_and_big5' }, +{ oid => '4338', + descr => 'internal conversion function for LATIN2 to MULE_INTERNAL', + proname => 'latin2_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'latin2_to_mic', + probin => '$libdir/latin2_and_win1250' }, +{ oid => '4339', + descr => 'internal conversion function for MULE_INTERNAL to LATIN2', + proname => 'mic_to_latin2', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_latin2', + probin => '$libdir/latin2_and_win1250' }, +{ oid => '4340', + descr => 'internal conversion function for WIN1250 to MULE_INTERNAL', + proname => 'win1250_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win1250_to_mic', + probin => '$libdir/latin2_and_win1250' }, +{ oid => '4341', + descr => 'internal conversion function for MULE_INTERNAL to WIN1250', + proname => 'mic_to_win1250', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_win1250', + probin => '$libdir/latin2_and_win1250' }, +{ oid => '4342', + descr => 'internal conversion function for LATIN2 to WIN1250', + proname => 'latin2_to_win1250', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'latin2_to_win1250', probin => '$libdir/latin2_and_win1250' }, +{ oid => '4343', + descr => 'internal conversion function for WIN1250 to LATIN2', + proname => 'win1250_to_latin2', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'win1250_to_latin2', probin => '$libdir/latin2_and_win1250' }, +{ oid => '4344', + descr => 'internal conversion function for LATIN1 to MULE_INTERNAL', + proname => 'latin1_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'latin1_to_mic', + probin => '$libdir/latin_and_mic' }, +{ oid => '4345', + descr => 'internal conversion function for MULE_INTERNAL to LATIN1', + proname => 'mic_to_latin1', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_latin1', + probin => '$libdir/latin_and_mic' }, +{ oid => '4346', + descr => 'internal conversion function for LATIN3 to MULE_INTERNAL', + proname => 'latin3_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'latin3_to_mic', + probin => '$libdir/latin_and_mic' }, +{ oid => '4347', + descr => 'internal conversion function for MULE_INTERNAL to LATIN3', + proname => 'mic_to_latin3', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_latin3', + probin => '$libdir/latin_and_mic' }, +{ oid => '4348', + descr => 'internal conversion function for LATIN4 to MULE_INTERNAL', + proname => 'latin4_to_mic', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'latin4_to_mic', + probin => '$libdir/latin_and_mic' }, +{ oid => '4349', + descr => 'internal conversion function for MULE_INTERNAL to LATIN4', + proname => 'mic_to_latin4', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'mic_to_latin4', + probin => '$libdir/latin_and_mic' }, +{ oid => '4352', descr => 'internal conversion function for BIG5 to UTF8', + proname => 'big5_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'big5_to_utf8', + probin => '$libdir/utf8_and_big5' }, +{ oid => '4353', descr => 'internal conversion function for UTF8 to BIG5', + proname => 'utf8_to_big5', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_big5', + probin => '$libdir/utf8_and_big5' }, +{ oid => '4354', descr => 'internal conversion function for UTF8 to KOI8R', + proname => 'utf8_to_koi8r', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_koi8r', + probin => '$libdir/utf8_and_cyrillic' }, +{ oid => '4355', descr => 'internal conversion function for KOI8R to UTF8', + proname => 'koi8r_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'koi8r_to_utf8', + probin => '$libdir/utf8_and_cyrillic' }, +{ oid => '4356', descr => 'internal conversion function for UTF8 to KOI8U', + proname => 'utf8_to_koi8u', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_koi8u', + probin => '$libdir/utf8_and_cyrillic' }, +{ oid => '4357', descr => 'internal conversion function for KOI8U to UTF8', + proname => 'koi8u_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'koi8u_to_utf8', + probin => '$libdir/utf8_and_cyrillic' }, +{ oid => '4358', descr => 'internal conversion function for UTF8 to WIN', + proname => 'utf8_to_win', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_win', + probin => '$libdir/utf8_and_win' }, +{ oid => '4359', descr => 'internal conversion function for WIN to UTF8', + proname => 'win_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'win_to_utf8', + probin => '$libdir/utf8_and_win' }, +{ oid => '4360', descr => 'internal conversion function for EUC_CN to UTF8', + proname => 'euc_cn_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_cn_to_utf8', + probin => '$libdir/utf8_and_euc_cn' }, +{ oid => '4361', descr => 'internal conversion function for UTF8 to EUC_CN', + proname => 'utf8_to_euc_cn', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_euc_cn', + probin => '$libdir/utf8_and_euc_cn' }, +{ oid => '4362', descr => 'internal conversion function for EUC_JP to UTF8', + proname => 'euc_jp_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_jp_to_utf8', + probin => '$libdir/utf8_and_euc_jp' }, +{ oid => '4363', descr => 'internal conversion function for UTF8 to EUC_JP', + proname => 'utf8_to_euc_jp', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_euc_jp', + probin => '$libdir/utf8_and_euc_jp' }, +{ oid => '4364', descr => 'internal conversion function for EUC_KR to UTF8', + proname => 'euc_kr_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_kr_to_utf8', + probin => '$libdir/utf8_and_euc_kr' }, +{ oid => '4365', descr => 'internal conversion function for UTF8 to EUC_KR', + proname => 'utf8_to_euc_kr', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_euc_kr', + probin => '$libdir/utf8_and_euc_kr' }, +{ oid => '4366', descr => 'internal conversion function for EUC_TW to UTF8', + proname => 'euc_tw_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'euc_tw_to_utf8', + probin => '$libdir/utf8_and_euc_tw' }, +{ oid => '4367', descr => 'internal conversion function for UTF8 to EUC_TW', + proname => 'utf8_to_euc_tw', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_euc_tw', + probin => '$libdir/utf8_and_euc_tw' }, +{ oid => '4368', descr => 'internal conversion function for GB18030 to UTF8', + proname => 'gb18030_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'gb18030_to_utf8', + probin => '$libdir/utf8_and_gb18030' }, +{ oid => '4369', descr => 'internal conversion function for UTF8 to GB18030', + proname => 'utf8_to_gb18030', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_gb18030', + probin => '$libdir/utf8_and_gb18030' }, +{ oid => '4370', descr => 'internal conversion function for GBK to UTF8', + proname => 'gbk_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'gbk_to_utf8', + probin => '$libdir/utf8_and_gbk' }, +{ oid => '4371', descr => 'internal conversion function for UTF8 to GBK', + proname => 'utf8_to_gbk', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_gbk', + probin => '$libdir/utf8_and_gbk' }, +{ oid => '4372', + descr => 'internal conversion function for UTF8 to ISO-8859 2-16', + proname => 'utf8_to_iso8859', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_iso8859', + probin => '$libdir/utf8_and_iso8859' }, +{ oid => '4373', + descr => 'internal conversion function for ISO-8859 2-16 to UTF8', + proname => 'iso8859_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'iso8859_to_utf8', + probin => '$libdir/utf8_and_iso8859' }, +{ oid => '4374', descr => 'internal conversion function for LATIN1 to UTF8', + proname => 'iso8859_1_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'iso8859_1_to_utf8', probin => '$libdir/utf8_and_iso8859_1' }, +{ oid => '4375', descr => 'internal conversion function for UTF8 to LATIN1', + proname => 'utf8_to_iso8859_1', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'utf8_to_iso8859_1', probin => '$libdir/utf8_and_iso8859_1' }, +{ oid => '4376', descr => 'internal conversion function for JOHAB to UTF8', + proname => 'johab_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'johab_to_utf8', + probin => '$libdir/utf8_and_johab' }, +{ oid => '4377', descr => 'internal conversion function for UTF8 to JOHAB', + proname => 'utf8_to_johab', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_johab', + probin => '$libdir/utf8_and_johab' }, +{ oid => '4378', descr => 'internal conversion function for SJIS to UTF8', + proname => 'sjis_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'sjis_to_utf8', + probin => '$libdir/utf8_and_sjis' }, +{ oid => '4379', descr => 'internal conversion function for UTF8 to SJIS', + proname => 'utf8_to_sjis', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_sjis', + probin => '$libdir/utf8_and_sjis' }, +{ oid => '4380', descr => 'internal conversion function for UHC to UTF8', + proname => 'uhc_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'uhc_to_utf8', + probin => '$libdir/utf8_and_uhc' }, +{ oid => '4381', descr => 'internal conversion function for UTF8 to UHC', + proname => 'utf8_to_uhc', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', prosrc => 'utf8_to_uhc', + probin => '$libdir/utf8_and_uhc' }, +{ oid => '4382', + descr => 'internal conversion function for EUC_JIS_2004 to UTF8', + proname => 'euc_jis_2004_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'euc_jis_2004_to_utf8', probin => '$libdir/utf8_and_euc2004' }, +{ oid => '4383', + descr => 'internal conversion function for UTF8 to EUC_JIS_2004', + proname => 'utf8_to_euc_jis_2004', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'utf8_to_euc_jis_2004', probin => '$libdir/utf8_and_euc2004' }, +{ oid => '4384', + descr => 'internal conversion function for SHIFT_JIS_2004 to UTF8', + proname => 'shift_jis_2004_to_utf8', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'shift_jis_2004_to_utf8', probin => '$libdir/utf8_and_sjis2004' }, +{ oid => '4385', + descr => 'internal conversion function for UTF8 to SHIFT_JIS_2004', + proname => 'utf8_to_shift_jis_2004', prolang => 'c', prorettype => 'void', + proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'utf8_to_shift_jis_2004', probin => '$libdir/utf8_and_sjis2004' }, +{ oid => '4386', + descr => 'internal conversion function for EUC_JIS_2004 to SHIFT_JIS_2004', + proname => 'euc_jis_2004_to_shift_jis_2004', prolang => 'c', + prorettype => 'void', proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'euc_jis_2004_to_shift_jis_2004', + probin => '$libdir/euc2004_sjis2004' }, +{ oid => '4387', + descr => 'internal conversion function for SHIFT_JIS_2004 to EUC_JIS_2004', + proname => 'shift_jis_2004_to_euc_jis_2004', prolang => 'c', + prorettype => 'void', proargtypes => 'int4 int4 cstring internal int4', + prosrc => 'shift_jis_2004_to_euc_jis_2004', + probin => '$libdir/euc2004_sjis2004' }, # replication/origin.h { oid => '6003', descr => 'create a replication origin', @@ -10085,8 +10582,7 @@ proparallel => 'r', prorettype => 'void', proargtypes => '', prosrc => 'pg_replication_origin_xact_reset' }, -{ oid => '6012', - descr => 'advance replication identifier to specific location', +{ oid => '6012', descr => 'advance replication origin to specific location', proname => 'pg_replication_origin_advance', provolatile => 'v', proparallel => 'u', prorettype => 'void', proargtypes => 'text pg_lsn', prosrc => 'pg_replication_origin_advance' }, @@ -10129,10 +10625,10 @@ # pg_config { oid => '3400', descr => 'pg_config binary as a function', - proname => 'pg_config', prorows => '23', proretset => 't', proparallel => 'r', - prorettype => 'record', proargtypes => '', proallargtypes => '{text,text}', - proargmodes => '{o,o}', proargnames => '{name,setting}', - prosrc => 'pg_config' }, + proname => 'pg_config', prorows => '23', proretset => 't', provolatile => 's', + proparallel => 'r', prorettype => 'record', proargtypes => '', + proallargtypes => '{text,text}', proargmodes => '{o,o}', + proargnames => '{name,setting}', prosrc => 'pg_config' }, # pg_controldata related functions { oid => '3441', @@ -10192,6 +10688,23 @@ provolatile => 'v', prorettype => 'record', proargtypes => '', proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}', proargnames => '{name,size,modification}', prosrc => 'pg_ls_waldir' }, +{ oid => '5031', descr => 'list of files in the archive_status directory', + proname => 'pg_ls_archive_statusdir', procost => '10', prorows => '20', + proretset => 't', provolatile => 'v', prorettype => 'record', + proargtypes => '', proallargtypes => '{text,int8,timestamptz}', + proargmodes => '{o,o,o}', proargnames => '{name,size,modification}', + prosrc => 'pg_ls_archive_statusdir' }, +{ oid => '5029', descr => 'list files in the pgsql_tmp directory', + proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't', + provolatile => 'v', prorettype => 'record', proargtypes => '', + proallargtypes => '{text,int8,timestamptz}', proargmodes => '{o,o,o}', + proargnames => '{name,size,modification}', prosrc => 'pg_ls_tmpdir_noargs' }, +{ oid => '5030', descr => 'list files in the pgsql_tmp directory', + proname => 'pg_ls_tmpdir', procost => '10', prorows => '20', proretset => 't', + provolatile => 'v', prorettype => 'record', proargtypes => 'oid', + proallargtypes => '{oid,text,int8,timestamptz}', proargmodes => '{i,o,o,o}', + proargnames => '{tablespace,name,size,modification}', + prosrc => 'pg_ls_tmpdir_1arg' }, # hash partitioning constraint function { oid => '5028', descr => 'hash partition CHECK constraint', @@ -10199,4 +10712,23 @@ proisstrict => 'f', prorettype => 'bool', proargtypes => 'oid int4 int4 any', proargmodes => '{i,i,i,v}', prosrc => 'satisfies_hash_partition' }, +# information about a partition tree +{ oid => '3423', descr => 'view partition tree tables', + proname => 'pg_partition_tree', prorows => '1000', proretset => 't', + provolatile => 'v', prorettype => 'record', proargtypes => 'regclass', + proallargtypes => '{regclass,regclass,regclass,bool,int4}', + proargmodes => '{i,o,o,o,o}', + proargnames => '{rootrelid,relid,parentrelid,isleaf,level}', + prosrc => 'pg_partition_tree' }, +{ oid => '3425', descr => 'view ancestors of the partition', + proname => 'pg_partition_ancestors', prorows => '10', proretset => 't', + provolatile => 'v', prorettype => 'regclass', proargtypes => 'regclass', + proallargtypes => '{regclass,regclass}', proargmodes => '{i,o}', + proargnames => '{partitionid,relid}', prosrc => 'pg_partition_ancestors' }, + +# function to get the top-most partition root parent +{ oid => '3424', descr => 'get top-most partition root parent', + proname => 'pg_partition_root', prorettype => 'regclass', + proargtypes => 'regclass', prosrc => 'pg_partition_root' }, + ] diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 821bc60f01f..dc29c06f628 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * pg_proc.h - * definition of the system "procedure" relation (pg_proc) + * definition of the "procedure" system catalog (pg_proc) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_proc.h @@ -30,6 +30,8 @@ */ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,ProcedureRelation_Rowtype_Id) BKI_SCHEMA_MACRO { + Oid oid; /* oid */ + /* procedure name */ NameData proname; @@ -40,7 +42,7 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce Oid proowner BKI_DEFAULT(PGUID); /* OID of pg_language entry */ - Oid prolang BKI_DEFAULT(12); + Oid prolang BKI_DEFAULT(internal) BKI_LOOKUP(pg_language); /* estimated execution cost */ float4 procost BKI_DEFAULT(1); @@ -51,8 +53,8 @@ CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,Proce /* element type of variadic array, or 0 */ Oid provariadic BKI_DEFAULT(0) BKI_LOOKUP(pg_type); - /* transforms calls to it during planning */ - regproc protransform BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); + /* planner support function for this function, or 0 if none */ + regproc prosupport BKI_DEFAULT(0) BKI_LOOKUP(pg_proc); /* see PROKIND_ categories below */ char prokind BKI_DEFAULT(f); @@ -177,30 +179,31 @@ typedef FormData_pg_proc *Form_pg_proc; extern ObjectAddress ProcedureCreate(const char *procedureName, - Oid procNamespace, - bool replace, - bool returnsSet, - Oid returnType, - Oid proowner, - Oid languageObjectId, - Oid languageValidator, - const char *prosrc, - const char *probin, - char prokind, - bool security_definer, - bool isLeakProof, - bool isStrict, - char volatility, - char parallel, - oidvector *parameterTypes, - Datum allParameterTypes, - Datum parameterModes, - Datum parameterNames, - List *parameterDefaults, - Datum trftypes, - Datum proconfig, - float4 procost, - float4 prorows); + Oid procNamespace, + bool replace, + bool returnsSet, + Oid returnType, + Oid proowner, + Oid languageObjectId, + Oid languageValidator, + const char *prosrc, + const char *probin, + char prokind, + bool security_definer, + bool isLeakProof, + bool isStrict, + char volatility, + char parallel, + oidvector *parameterTypes, + Datum allParameterTypes, + Datum parameterModes, + Datum parameterNames, + List *parameterDefaults, + Datum trftypes, + Datum proconfig, + Oid prosupport, + float4 procost, + float4 prorows); extern bool function_parse_error_transpose(const char *prosrc); diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h index e81d62dac34..20a2f0ac1bf 100644 --- a/src/include/catalog/pg_publication.h +++ b/src/include/catalog/pg_publication.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * pg_publication.h - * definition of the relation sets relation (pg_publication) + * definition of the "publication" system catalog (pg_publication) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_publication.h @@ -29,6 +29,8 @@ */ CATALOG(pg_publication,6104,PublicationRelationId) { + Oid oid; /* oid */ + NameData pubname; /* name of the publication */ Oid pubowner; /* publication owner */ @@ -85,11 +87,10 @@ extern List *GetAllTablesPublicationRelations(void); extern bool is_publishable_relation(Relation rel); extern ObjectAddress publication_add_relation(Oid pubid, Relation targetrel, - bool if_not_exists); + bool if_not_exists); extern Oid get_publication_oid(const char *pubname, bool missing_ok); -extern char *get_publication_name(Oid pubid); +extern char *get_publication_name(Oid pubid, bool missing_ok); -extern Datum pg_get_publication_tables(PG_FUNCTION_ARGS); #endif /* PG_PUBLICATION_H */ diff --git a/src/include/catalog/pg_publication_rel.h b/src/include/catalog/pg_publication_rel.h index 2208e424f4d..5f5bc92ab32 100644 --- a/src/include/catalog/pg_publication_rel.h +++ b/src/include/catalog/pg_publication_rel.h @@ -1,9 +1,10 @@ /*------------------------------------------------------------------------- * * pg_publication_rel.h - * definition of the publication to relation map (pg_publication_rel) - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * definition of the system catalog for mappings between relations and + * publications (pg_publication_rel) + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_publication_rel.h @@ -27,6 +28,7 @@ */ CATALOG(pg_publication_rel,6106,PublicationRelRelationId) { + Oid oid; /* oid */ Oid prpubid; /* Oid of the publication */ Oid prrelid; /* Oid of the relation */ } FormData_pg_publication_rel; diff --git a/src/include/catalog/pg_range.dat b/src/include/catalog/pg_range.dat index 4781ea9d36e..dd9baa2678c 100644 --- a/src/include/catalog/pg_range.dat +++ b/src/include/catalog/pg_range.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_range.dat -# Initial contents of the pg_range system relation. +# Initial contents of the pg_range system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_range.dat diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h index d8e16ccee75..b01a074d095 100644 --- a/src/include/catalog/pg_range.h +++ b/src/include/catalog/pg_range.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_range.h - * definition of the system "range" relation (pg_range) + * definition of the "range type" system catalog (pg_range) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_range.h @@ -26,7 +26,7 @@ * typedef struct FormData_pg_range * ---------------- */ -CATALOG(pg_range,3541,RangeRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_range,3541,RangeRelationId) { /* OID of owning range type */ Oid rngtypid BKI_LOOKUP(pg_type); @@ -59,8 +59,8 @@ typedef FormData_pg_range *Form_pg_range; */ extern void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, - Oid rangeSubOpclass, RegProcedure rangeCanonical, - RegProcedure rangeSubDiff); + Oid rangeSubOpclass, RegProcedure rangeCanonical, + RegProcedure rangeSubDiff); extern void RangeDelete(Oid rangeTypeOid); #endif /* PG_RANGE_H */ diff --git a/src/include/catalog/pg_replication_origin.h b/src/include/catalog/pg_replication_origin.h index eacdd39b83b..b7685847980 100644 --- a/src/include/catalog/pg_replication_origin.h +++ b/src/include/catalog/pg_replication_origin.h @@ -1,9 +1,10 @@ /*------------------------------------------------------------------------- * * pg_replication_origin.h - * Persistent replication origin registry + * definition of the "replication origin" system catalog + * (pg_replication_origin) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_replication_origin.h @@ -27,7 +28,7 @@ * typedef struct FormData_pg_replication_origin * ---------------- */ -CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELATION { /* * Locally known id that get included into WAL. diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h index 77125867b32..ceb1def6e7f 100644 --- a/src/include/catalog/pg_rewrite.h +++ b/src/include/catalog/pg_rewrite.h @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * * pg_rewrite.h - * definition of the system "rewrite-rule" relation (pg_rewrite) + * definition of the "rewrite rule" system catalog (pg_rewrite) * * As of Postgres 7.3, the primary key for this table is * --- ie, rule names are only unique among the rules of a given table. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_rewrite.h @@ -31,6 +31,7 @@ */ CATALOG(pg_rewrite,2618,RewriteRelationId) { + Oid oid; /* oid */ NameData rulename; Oid ev_class; char ev_type; @@ -38,8 +39,8 @@ CATALOG(pg_rewrite,2618,RewriteRelationId) bool is_instead; #ifdef CATALOG_VARLEN /* variable-length fields start here */ - pg_node_tree ev_qual; - pg_node_tree ev_action; + pg_node_tree ev_qual BKI_FORCE_NOT_NULL; + pg_node_tree ev_action BKI_FORCE_NOT_NULL; #endif } FormData_pg_rewrite; diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h index 48d454897cd..6e4e07eda66 100644 --- a/src/include/catalog/pg_seclabel.h +++ b/src/include/catalog/pg_seclabel.h @@ -1,11 +1,17 @@ /* ------------------------------------------------------------------------- * * pg_seclabel.h - * definition of the system "security label" relation (pg_seclabel) + * definition of the "security label" system catalog (pg_seclabel) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * src/include/catalog/pg_seclabel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * * ------------------------------------------------------------------------- */ #ifndef PG_SECLABEL_H @@ -19,7 +25,7 @@ * typedef struct FormData_pg_seclabel * ---------------- */ -CATALOG(pg_seclabel,3596,SecLabelRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_seclabel,3596,SecLabelRelationId) { Oid objoid; /* OID of the object itself */ Oid classoid; /* OID of table containing the object */ diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h index a13b05e8007..897ad141eaa 100644 --- a/src/include/catalog/pg_sequence.h +++ b/src/include/catalog/pg_sequence.h @@ -1,11 +1,17 @@ /* ------------------------------------------------------------------------- * * pg_sequence.h - * definition of the system "sequence" relation (pg_sequence) + * definition of the "sequence" system catalog (pg_sequence) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * src/include/catalog/pg_sequence.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * * ------------------------------------------------------------------------- */ #ifndef PG_SEQUENCE_H @@ -14,7 +20,7 @@ #include "catalog/genbki.h" #include "catalog/pg_sequence_d.h" -CATALOG(pg_sequence,2224,SequenceRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_sequence,2224,SequenceRelationId) { Oid seqrelid; Oid seqtypid; diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h index 0f8508cf262..915e37040d7 100644 --- a/src/include/catalog/pg_shdepend.h +++ b/src/include/catalog/pg_shdepend.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_shdepend.h - * definition of the system "shared dependency" relation (pg_shdepend) + * definition of the "shared dependency" system catalog (pg_shdepend) * * pg_shdepend has no preloaded contents, so there is no pg_shdepend.dat * file; system-defined dependencies are loaded into it during a late stage @@ -12,7 +12,7 @@ * from a relation to its database. Currently, only dependencies on roles * are explicitly stored in pg_shdepend. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_shdepend.h @@ -34,7 +34,7 @@ * typedef struct FormData_pg_shdepend * ---------------- */ -CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION { /* * Identification of the dependent (referencing) object. diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h index 00fd0e0e54f..5817815c343 100644 --- a/src/include/catalog/pg_shdescription.h +++ b/src/include/catalog/pg_shdescription.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * * pg_shdescription.h - * definition of the system "shared description" relation + * definition of the "shared description" system catalog * (pg_shdescription) * * Because the contents of this table are taken from the *.dat files @@ -16,7 +16,7 @@ * across tables. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_shdescription.h @@ -38,7 +38,7 @@ * typedef struct FormData_pg_shdescription * ---------------- */ -CATALOG(pg_shdescription,2396,SharedDescriptionRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS +CATALOG(pg_shdescription,2396,SharedDescriptionRelationId) BKI_SHARED_RELATION { Oid objoid; /* OID of object itself */ Oid classoid; /* OID of table containing object */ diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h index 22ecf981680..577081031fb 100644 --- a/src/include/catalog/pg_shseclabel.h +++ b/src/include/catalog/pg_shseclabel.h @@ -1,11 +1,17 @@ /* ------------------------------------------------------------------------- * * pg_shseclabel.h - * definition of the system "shared security label" relation (pg_shseclabel) + * definition of the "shared security label" system catalog (pg_shseclabel) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * src/include/catalog/pg_shseclabel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * * ------------------------------------------------------------------------- */ #ifndef PG_SHSECLABEL_H @@ -19,7 +25,7 @@ * typedef struct FormData_pg_shseclabel * ---------------- */ -CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO +CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_SCHEMA_MACRO { Oid objoid; /* OID of the shared object itself */ Oid classoid; /* OID of table containing the shared object */ diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h index d654d3db26e..207be54b9b9 100644 --- a/src/include/catalog/pg_statistic.h +++ b/src/include/catalog/pg_statistic.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_statistic.h - * definition of the system "statistic" relation (pg_statistic) + * definition of the "statistics" system catalog (pg_statistic) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_statistic.h @@ -26,7 +26,7 @@ * typedef struct FormData_pg_statistic * ---------------- */ -CATALOG(pg_statistic,2619,StatisticRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_statistic,2619,StatisticRelationId) { /* These fields form the unique key for the entry: */ Oid starelid; /* relation containing attribute */ @@ -74,12 +74,13 @@ CATALOG(pg_statistic,2619,StatisticRelationId) BKI_WITHOUT_OIDS * statistical data can be placed. Each slot includes: * kind integer code identifying kind of data (see below) * op OID of associated operator, if needed + * coll OID of relevant collation, or 0 if none * numbers float4 array (for statistical values) * values anyarray (for representations of data values) - * The ID and operator fields are never NULL; they are zeroes in an - * unused slot. The numbers and values fields are NULL in an unused - * slot, and might also be NULL in a used slot if the slot kind has - * no need for one or the other. + * The ID, operator, and collation fields are never NULL; they are zeroes + * in an unused slot. The numbers and values fields are NULL in an + * unused slot, and might also be NULL in a used slot if the slot kind + * has no need for one or the other. * ---------------- */ @@ -95,6 +96,12 @@ CATALOG(pg_statistic,2619,StatisticRelationId) BKI_WITHOUT_OIDS Oid staop4; Oid staop5; + Oid stacoll1; + Oid stacoll2; + Oid stacoll3; + Oid stacoll4; + Oid stacoll5; + #ifdef CATALOG_VARLEN /* variable-length fields start here */ float4 stanumbers1[1]; float4 stanumbers2[1]; @@ -159,7 +166,8 @@ typedef FormData_pg_statistic *Form_pg_statistic; /* * In a "most common values" slot, staop is the OID of the "=" operator - * used to decide whether values are the same or not. stavalues contains + * used to decide whether values are the same or not, and stacoll is the + * collation used (same as column's collation). stavalues contains * the K most common non-null values appearing in the column, and stanumbers * contains their frequencies (fractions of total row count). The values * shall be ordered in decreasing frequency. Note that since the arrays are @@ -171,9 +179,11 @@ typedef FormData_pg_statistic *Form_pg_statistic; /* * A "histogram" slot describes the distribution of scalar data. staop is - * the OID of the "<" operator that describes the sort ordering. (In theory, - * more than one histogram could appear, if a datatype has more than one - * useful sort operator.) stavalues contains M (>=2) non-null values that + * the OID of the "<" operator that describes the sort ordering, and stacoll + * is the relevant collation. (In theory more than one histogram could appear, + * if a datatype has more than one useful sort operator or we care about more + * than one collation. Currently the collation will always be that of the + * underlying column.) stavalues contains M (>=2) non-null values that * divide the non-null column data values into M-1 bins of approximately equal * population. The first stavalues item is the MIN and the last is the MAX. * stanumbers is not used and should be NULL. IMPORTANT POINT: if an MCV @@ -190,11 +200,12 @@ typedef FormData_pg_statistic *Form_pg_statistic; /* * A "correlation" slot describes the correlation between the physical order * of table tuples and the ordering of data values of this column, as seen - * by the "<" operator identified by staop. (As with the histogram, more - * than one entry could theoretically appear.) stavalues is not used and - * should be NULL. stanumbers contains a single entry, the correlation - * coefficient between the sequence of data values and the sequence of - * their actual tuple positions. The coefficient ranges from +1 to -1. + * by the "<" operator identified by staop with the collation identified by + * stacoll. (As with the histogram, more than one entry could theoretically + * appear.) stavalues is not used and should be NULL. stanumbers contains + * a single entry, the correlation coefficient between the sequence of data + * values and the sequence of their actual tuple positions. The coefficient + * ranges from +1 to -1. */ #define STATISTIC_KIND_CORRELATION 3 @@ -203,7 +214,8 @@ typedef FormData_pg_statistic *Form_pg_statistic; * except that it stores the most common non-null *elements* of the column * values. This is useful when the column datatype is an array or some other * type with identifiable elements (for instance, tsvector). staop contains - * the equality operator appropriate to the element type. stavalues contains + * the equality operator appropriate to the element type, and stacoll + * contains the collation to use with it. stavalues contains * the most common element values, and stanumbers their frequencies. Unlike * MCV slots, frequencies are measured as the fraction of non-null rows the * element value appears in, not the frequency of all rows. Also unlike @@ -226,7 +238,8 @@ typedef FormData_pg_statistic *Form_pg_statistic; * A "distinct elements count histogram" slot describes the distribution of * the number of distinct element values present in each row of an array-type * column. Only non-null rows are considered, and only non-null elements. - * staop contains the equality operator appropriate to the element type. + * staop contains the equality operator appropriate to the element type, + * and stacoll contains the collation to use with it. * stavalues is not used and should be NULL. The last member of stanumbers is * the average count of distinct element values over all non-null rows. The * preceding M (>=2) members form a histogram that divides the population of diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h index 9ccfce7c724..54a88f4ec87 100644 --- a/src/include/catalog/pg_statistic_ext.h +++ b/src/include/catalog/pg_statistic_ext.h @@ -1,10 +1,14 @@ /*------------------------------------------------------------------------- * * pg_statistic_ext.h - * definition of the system "extended statistic" relation (pg_statistic_ext) + * definition of the "extended statistics" system catalog + * (pg_statistic_ext) * + * Note that pg_statistic_ext contains the definitions of extended statistics + * objects, created by CREATE STATISTICS, but not the actual statistical data, + * created by running ANALYZE. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_statistic_ext.h @@ -28,6 +32,8 @@ */ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId) { + Oid oid; /* oid */ + Oid stxrelid; /* relation containing attributes */ /* These two fields form the unique key for the entry: */ @@ -35,6 +41,7 @@ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId) Oid stxnamespace; /* OID of statistics object's namespace */ Oid stxowner; /* statistics object's owner */ + int32 stxstattarget BKI_DEFAULT(-1); /* statistics target */ /* * variable-length fields start here, but we allow direct access to @@ -45,8 +52,6 @@ CATALOG(pg_statistic_ext,3381,StatisticExtRelationId) #ifdef CATALOG_VARLEN char stxkind[1] BKI_FORCE_NOT_NULL; /* statistics kinds requested * to build */ - pg_ndistinct stxndistinct; /* ndistinct coefficients (serialized) */ - pg_dependencies stxdependencies; /* dependencies (serialized) */ #endif } FormData_pg_statistic_ext; @@ -62,6 +67,7 @@ typedef FormData_pg_statistic_ext *Form_pg_statistic_ext; #define STATS_EXT_NDISTINCT 'd' #define STATS_EXT_DEPENDENCIES 'f' +#define STATS_EXT_MCV 'm' #endif /* EXPOSE_TO_CLIENT_CODE */ diff --git a/src/include/catalog/pg_statistic_ext_data.h b/src/include/catalog/pg_statistic_ext_data.h new file mode 100644 index 00000000000..952883e2d3e --- /dev/null +++ b/src/include/catalog/pg_statistic_ext_data.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * pg_statistic_ext_data.h + * definition of the "extended statistics data" system catalog + * (pg_statistic_ext_data) + * + * This catalog stores the statistical data for extended statistics objects. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/catalog/pg_statistic_ext_data.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * + *------------------------------------------------------------------------- + */ +#ifndef PG_STATISTIC_EXT_DATA_H +#define PG_STATISTIC_EXT_DATA_H + +#include "catalog/genbki.h" +#include "catalog/pg_statistic_ext_data_d.h" + +/* ---------------- + * pg_statistic_ext_data definition. cpp turns this into + * typedef struct FormData_pg_statistic_ext_data + * ---------------- + */ +CATALOG(pg_statistic_ext_data,3429,StatisticExtDataRelationId) +{ + Oid stxoid; /* statistics object this data is for */ + +#ifdef CATALOG_VARLEN /* variable-length fields start here */ + + pg_ndistinct stxdndistinct; /* ndistinct coefficients (serialized) */ + pg_dependencies stxddependencies; /* dependencies (serialized) */ + pg_mcv_list stxdmcv; /* MCV (serialized) */ + +#endif + +} FormData_pg_statistic_ext_data; + +/* ---------------- + * Form_pg_statistic_ext_data corresponds to a pointer to a tuple with + * the format of pg_statistic_ext_data relation. + * ---------------- + */ +typedef FormData_pg_statistic_ext_data * Form_pg_statistic_ext_data; + +#endif /* PG_STATISTIC_EXT_DATA_H */ diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h index 7fc1c29603a..3cb13d897e2 100644 --- a/src/include/catalog/pg_subscription.h +++ b/src/include/catalog/pg_subscription.h @@ -1,11 +1,17 @@ /* ------------------------------------------------------------------------- * * pg_subscription.h - * Definition of the subscription catalog (pg_subscription). + * definition of the "subscription" system catalog (pg_subscription) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * src/include/catalog/pg_subscription.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * * ------------------------------------------------------------------------- */ #ifndef PG_SUBSCRIPTION_H @@ -32,6 +38,8 @@ */ CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(6101,SubscriptionRelation_Rowtype_Id) BKI_SCHEMA_MACRO { + Oid oid; /* oid */ + Oid subdbid; /* Database the subscription is in. */ NameData subname; /* Name of the subscription */ @@ -74,7 +82,7 @@ typedef struct Subscription extern Subscription *GetSubscription(Oid subid, bool missing_ok); extern void FreeSubscription(Subscription *sub); extern Oid get_subscription_oid(const char *subname, bool missing_ok); -extern char *get_subscription_name(Oid subid); +extern char *get_subscription_name(Oid subid, bool missing_ok); extern int CountDBSubscriptions(Oid dbid); diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h index 8971b679cdd..f7df814a181 100644 --- a/src/include/catalog/pg_subscription_rel.h +++ b/src/include/catalog/pg_subscription_rel.h @@ -1,12 +1,18 @@ /* ------------------------------------------------------------------------- * * pg_subscription_rel.h - * Local info about tables that come from the publisher of a - * subscription (pg_subscription_rel). + * definition of the system catalog containing the state for each + * replicated table in each subscription (pg_subscription_rel) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * + * src/include/catalog/pg_subscription_rel.h + * + * NOTES + * The Catalog.pm module reads this file and derives schema + * information. + * * ------------------------------------------------------------------------- */ #ifndef PG_SUBSCRIPTION_REL_H @@ -23,7 +29,7 @@ * typedef struct FormData_pg_subscription_rel * ---------------- */ -CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId) { Oid srsubid; /* Oid of subscription */ Oid srrelid; /* Oid of relation */ @@ -61,12 +67,12 @@ typedef struct SubscriptionRelState char state; } SubscriptionRelState; -extern Oid AddSubscriptionRelState(Oid subid, Oid relid, char state, - XLogRecPtr sublsn); -extern Oid UpdateSubscriptionRelState(Oid subid, Oid relid, char state, - XLogRecPtr sublsn); +extern void AddSubscriptionRelState(Oid subid, Oid relid, char state, + XLogRecPtr sublsn); +extern void UpdateSubscriptionRelState(Oid subid, Oid relid, char state, + XLogRecPtr sublsn); extern char GetSubscriptionRelState(Oid subid, Oid relid, - XLogRecPtr *sublsn, bool missing_ok); + XLogRecPtr *sublsn, bool missing_ok); extern void RemoveSubscriptionRel(Oid subid, Oid relid); extern List *GetSubscriptionRelations(Oid subid); diff --git a/src/include/catalog/pg_tablespace.dat b/src/include/catalog/pg_tablespace.dat index b623a2d39c4..f45ef9a2dd4 100644 --- a/src/include/catalog/pg_tablespace.dat +++ b/src/include/catalog/pg_tablespace.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_tablespace.dat -# Initial contents of the pg_tablespace system relation. +# Initial contents of the pg_tablespace system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_tablespace.dat diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h index 4782e78e6b3..594a81cd9a2 100644 --- a/src/include/catalog/pg_tablespace.h +++ b/src/include/catalog/pg_tablespace.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_tablespace.h - * definition of the system "tablespace" relation (pg_tablespace) + * definition of the "tablespace" system catalog (pg_tablespace) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_tablespace.h @@ -28,6 +28,7 @@ */ CATALOG(pg_tablespace,1213,TableSpaceRelationId) BKI_SHARED_RELATION { + Oid oid; /* oid */ NameData spcname; /* tablespace name */ Oid spcowner; /* owner of tablespace */ diff --git a/src/include/catalog/pg_transform.h b/src/include/catalog/pg_transform.h index 6059b897c66..1a255cc8eae 100644 --- a/src/include/catalog/pg_transform.h +++ b/src/include/catalog/pg_transform.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_transform.h - * definition of the system "transform" relation (pg_transform) + * definition of the "transform" system catalog (pg_transform) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_transform.h @@ -28,6 +28,7 @@ */ CATALOG(pg_transform,3576,TransformRelationId) { + Oid oid; /* oid */ Oid trftype; Oid trflang; regproc trffromsql; diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h index 9955e62d3a0..362be3a6ab0 100644 --- a/src/include/catalog/pg_trigger.h +++ b/src/include/catalog/pg_trigger.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_trigger.h - * definition of the system "trigger" relation (pg_trigger) + * definition of the "trigger" system catalog (pg_trigger) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_trigger.h @@ -33,6 +33,7 @@ */ CATALOG(pg_trigger,2620,TriggerRelationId) { + Oid oid; /* oid */ Oid tgrelid; /* relation trigger is attached to */ NameData tgname; /* trigger's name */ Oid tgfoid; /* OID of function to be called */ diff --git a/src/include/catalog/pg_ts_config.dat b/src/include/catalog/pg_ts_config.dat index b57db6787dc..bddaa8192fb 100644 --- a/src/include/catalog/pg_ts_config.dat +++ b/src/include/catalog/pg_ts_config.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_ts_config.dat -# Initial contents of the pg_ts_config system relation. +# Initial contents of the pg_ts_config system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_ts_config.dat @@ -13,7 +13,6 @@ [ { oid => '3748', descr => 'simple configuration', - cfgname => 'simple', cfgnamespace => 'PGNSP', cfgowner => 'PGUID', - cfgparser => '3722' }, + cfgname => 'simple', cfgparser => 'default' }, ] diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h index d344bb76de8..7ab97a8aa36 100644 --- a/src/include/catalog/pg_ts_config.h +++ b/src/include/catalog/pg_ts_config.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_ts_config.h - * definition of configuration of tsearch + * definition of the "text search configuration" system catalog + * (pg_ts_config) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_config.h @@ -28,10 +29,20 @@ */ CATALOG(pg_ts_config,3602,TSConfigRelationId) { - NameData cfgname; /* name of configuration */ - Oid cfgnamespace; /* name space */ - Oid cfgowner; /* owner */ - Oid cfgparser; /* OID of parser (in pg_ts_parser) */ + /* oid */ + Oid oid; + + /* name of configuration */ + NameData cfgname; + + /* name space */ + Oid cfgnamespace BKI_DEFAULT(PGNSP); + + /* owner */ + Oid cfgowner BKI_DEFAULT(PGUID); + + /* OID of parser */ + Oid cfgparser BKI_LOOKUP(pg_ts_parser); } FormData_pg_ts_config; typedef FormData_pg_ts_config *Form_pg_ts_config; diff --git a/src/include/catalog/pg_ts_config_map.dat b/src/include/catalog/pg_ts_config_map.dat index 090a1ca1e91..43a8bd4cdcd 100644 --- a/src/include/catalog/pg_ts_config_map.dat +++ b/src/include/catalog/pg_ts_config_map.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_ts_config_map.dat -# Initial contents of the pg_ts_config_map system relation. +# Initial contents of the pg_ts_config_map system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_ts_config_map.dat @@ -12,24 +12,43 @@ [ -{ mapcfg => '3748', maptokentype => '1', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '2', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '3', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '4', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '5', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '6', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '7', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '8', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '9', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '10', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '11', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '15', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '16', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '17', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '18', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '19', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '20', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '21', mapseqno => '1', mapdict => '3765' }, -{ mapcfg => '3748', maptokentype => '22', mapseqno => '1', mapdict => '3765' }, +{ mapcfg => 'simple', maptokentype => '1', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '2', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '3', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '4', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '5', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '6', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '7', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '8', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '9', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '10', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '11', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '15', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '16', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '17', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '18', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '19', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '20', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '21', mapseqno => '1', + mapdict => 'simple' }, +{ mapcfg => 'simple', maptokentype => '22', mapseqno => '1', + mapdict => 'simple' }, ] diff --git a/src/include/catalog/pg_ts_config_map.h b/src/include/catalog/pg_ts_config_map.h index 21200215c45..7892e17d71c 100644 --- a/src/include/catalog/pg_ts_config_map.h +++ b/src/include/catalog/pg_ts_config_map.h @@ -1,10 +1,11 @@ /*------------------------------------------------------------------------- * * pg_ts_config_map.h - * definition of token mappings for configurations of tsearch + * definition of the system catalog for text search token mappings + * (pg_ts_config_map) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_config_map.h @@ -26,12 +27,19 @@ * typedef struct FormData_pg_ts_config_map * ---------------- */ -CATALOG(pg_ts_config_map,3603,TSConfigMapRelationId) BKI_WITHOUT_OIDS +CATALOG(pg_ts_config_map,3603,TSConfigMapRelationId) { - Oid mapcfg; /* OID of configuration owning this entry */ - int32 maptokentype; /* token type from parser */ - int32 mapseqno; /* order in which to consult dictionaries */ - Oid mapdict; /* dictionary to consult */ + /* OID of configuration owning this entry */ + Oid mapcfg BKI_LOOKUP(pg_ts_config); + + /* token type from parser */ + int32 maptokentype; + + /* order in which to consult dictionaries */ + int32 mapseqno; + + /* dictionary to consult */ + Oid mapdict BKI_LOOKUP(pg_ts_dict); } FormData_pg_ts_config_map; typedef FormData_pg_ts_config_map *Form_pg_ts_config_map; diff --git a/src/include/catalog/pg_ts_dict.dat b/src/include/catalog/pg_ts_dict.dat index 6852303604c..f9d50da1c97 100644 --- a/src/include/catalog/pg_ts_dict.dat +++ b/src/include/catalog/pg_ts_dict.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_ts_dict.dat -# Initial contents of the pg_ts_dict system relation. +# Initial contents of the pg_ts_dict system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_ts_dict.dat @@ -14,7 +14,6 @@ { oid => '3765', descr => 'simple dictionary: just lower case and check for stopword', - dictname => 'simple', dictnamespace => 'PGNSP', dictowner => 'PGUID', - dicttemplate => '3727', dictinitoption => '_null_' }, + dictname => 'simple', dicttemplate => 'simple', dictinitoption => '_null_' }, ] diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h index 1e285adcec9..be7f016c116 100644 --- a/src/include/catalog/pg_ts_dict.h +++ b/src/include/catalog/pg_ts_dict.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_ts_dict.h - * definition of dictionaries for tsearch + * definition of the "text search dictionary" system catalog (pg_ts_dict) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_dict.h @@ -28,13 +28,24 @@ */ CATALOG(pg_ts_dict,3600,TSDictionaryRelationId) { - NameData dictname; /* dictionary name */ - Oid dictnamespace; /* name space */ - Oid dictowner; /* owner */ - Oid dicttemplate; /* dictionary's template */ + /* oid */ + Oid oid; + + /* dictionary name */ + NameData dictname; + + /* name space */ + Oid dictnamespace BKI_DEFAULT(PGNSP); + + /* owner */ + Oid dictowner BKI_DEFAULT(PGUID); + + /* dictionary's template */ + Oid dicttemplate BKI_LOOKUP(pg_ts_template); #ifdef CATALOG_VARLEN /* variable-length fields start here */ - text dictinitoption; /* options passed to dict_init() */ + /* options passed to dict_init() */ + text dictinitoption; #endif } FormData_pg_ts_dict; diff --git a/src/include/catalog/pg_ts_parser.dat b/src/include/catalog/pg_ts_parser.dat index 8c507705962..aca4773c13b 100644 --- a/src/include/catalog/pg_ts_parser.dat +++ b/src/include/catalog/pg_ts_parser.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_ts_parser.dat -# Initial contents of the pg_ts_parser system relation. +# Initial contents of the pg_ts_parser system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_ts_parser.dat diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h index ccaf40bbb41..88ef79d3ab0 100644 --- a/src/include/catalog/pg_ts_parser.h +++ b/src/include/catalog/pg_ts_parser.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_ts_parser.h - * definition of parsers for tsearch + * definition of the "text search parser" system catalog (pg_ts_parser) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_parser.h @@ -28,6 +28,8 @@ */ CATALOG(pg_ts_parser,3601,TSParserRelationId) { + Oid oid; /* oid */ + /* parser's name */ NameData prsname; diff --git a/src/include/catalog/pg_ts_template.dat b/src/include/catalog/pg_ts_template.dat index 1322c390226..d55dc25d14a 100644 --- a/src/include/catalog/pg_ts_template.dat +++ b/src/include/catalog/pg_ts_template.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_ts_template.dat -# Initial contents of the pg_ts_template system relation. +# Initial contents of the pg_ts_template system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_ts_template.dat diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h index 5e66e02beff..afaff027d39 100644 --- a/src/include/catalog/pg_ts_template.h +++ b/src/include/catalog/pg_ts_template.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_ts_template.h - * definition of dictionary templates for tsearch + * definition of the "text search template" system catalog (pg_ts_template) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_ts_template.h @@ -28,6 +28,8 @@ */ CATALOG(pg_ts_template,3764,TSTemplateRelationId) { + Oid oid; /* oid */ + /* template name */ NameData tmplname; diff --git a/src/include/catalog/pg_type.dat b/src/include/catalog/pg_type.dat index ae7e89b3222..be49e001144 100644 --- a/src/include/catalog/pg_type.dat +++ b/src/include/catalog/pg_type.dat @@ -1,9 +1,9 @@ #---------------------------------------------------------------------- # # pg_type.dat -# Initial contents of the pg_type system relation. +# Initial contents of the pg_type system catalog. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/pg_type.dat @@ -24,147 +24,153 @@ # The only oid_symbol entries in this file are for names that don't match # this rule, and are grandfathered in. +# To autogenerate an array type, add 'array_type_oid => 'nnnn' to the element +# type, which will instruct genbki.pl to generate a BKI entry for it. +# In a few cases, the array type's properties don't match the normal pattern +# so it can't be autogenerated; in such cases do not write array_type_oid. + # Once upon a time these entries were ordered by OID. Lately it's often # been the custom to insert new entries adjacent to related older entries. # Try to do one or the other though, don't just insert entries at random. # OIDS 1 - 99 -{ oid => '16', descr => 'boolean, \'true\'/\'false\'', +{ oid => '16', array_type_oid => '1000', + descr => 'boolean, \'true\'/\'false\'', typname => 'bool', typlen => '1', typbyval => 't', typcategory => 'B', - typispreferred => 't', typarray => '_bool', typinput => 'boolin', - typoutput => 'boolout', typreceive => 'boolrecv', typsend => 'boolsend', - typalign => 'c' }, -{ oid => '17', descr => 'variable-length string, binary values escaped', + typispreferred => 't', typinput => 'boolin', typoutput => 'boolout', + typreceive => 'boolrecv', typsend => 'boolsend', typalign => 'c' }, +{ oid => '17', array_type_oid => '1001', + descr => 'variable-length string, binary values escaped', typname => 'bytea', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_bytea', typinput => 'byteain', typoutput => 'byteaout', - typreceive => 'bytearecv', typsend => 'byteasend', typalign => 'i', - typstorage => 'x' }, -{ oid => '18', descr => 'single character', + typinput => 'byteain', typoutput => 'byteaout', typreceive => 'bytearecv', + typsend => 'byteasend', typalign => 'i', typstorage => 'x' }, +{ oid => '18', array_type_oid => '1002', descr => 'single character', typname => 'char', typlen => '1', typbyval => 't', typcategory => 'S', - typarray => '_char', typinput => 'charin', typoutput => 'charout', - typreceive => 'charrecv', typsend => 'charsend', typalign => 'c' }, -{ oid => '19', descr => '63-byte type for storing system identifiers', + typinput => 'charin', typoutput => 'charout', typreceive => 'charrecv', + typsend => 'charsend', typalign => 'c' }, +{ oid => '19', array_type_oid => '1003', + descr => '63-byte type for storing system identifiers', typname => 'name', typlen => 'NAMEDATALEN', typbyval => 'f', - typcategory => 'S', typelem => 'char', typarray => '_name', - typinput => 'namein', typoutput => 'nameout', typreceive => 'namerecv', - typsend => 'namesend', typalign => 'c' }, -{ oid => '20', descr => '~18 digit integer, 8-byte storage', + typcategory => 'S', typelem => 'char', typinput => 'namein', + typoutput => 'nameout', typreceive => 'namerecv', typsend => 'namesend', + typalign => 'c', typcollation => 'C' }, +{ oid => '20', array_type_oid => '1016', + descr => '~18 digit integer, 8-byte storage', typname => 'int8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'N', typarray => '_int8', typinput => 'int8in', - typoutput => 'int8out', typreceive => 'int8recv', typsend => 'int8send', - typalign => 'd' }, -{ oid => '21', descr => '-32 thousand to 32 thousand, 2-byte storage', + typcategory => 'N', typinput => 'int8in', typoutput => 'int8out', + typreceive => 'int8recv', typsend => 'int8send', typalign => 'd' }, +{ oid => '21', array_type_oid => '1005', + descr => '-32 thousand to 32 thousand, 2-byte storage', typname => 'int2', typlen => '2', typbyval => 't', typcategory => 'N', - typarray => '_int2', typinput => 'int2in', typoutput => 'int2out', - typreceive => 'int2recv', typsend => 'int2send', typalign => 's' }, -{ oid => '22', descr => 'array of int2, used in system tables', + typinput => 'int2in', typoutput => 'int2out', typreceive => 'int2recv', + typsend => 'int2send', typalign => 's' }, +{ oid => '22', array_type_oid => '1006', + descr => 'array of int2, used in system tables', typname => 'int2vector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int2', typarray => '_int2vector', typinput => 'int2vectorin', - typoutput => 'int2vectorout', typreceive => 'int2vectorrecv', - typsend => 'int2vectorsend', typalign => 'i' }, -{ oid => '23', descr => '-2 billion to 2 billion integer, 4-byte storage', + typelem => 'int2', typinput => 'int2vectorin', typoutput => 'int2vectorout', + typreceive => 'int2vectorrecv', typsend => 'int2vectorsend', + typalign => 'i' }, +{ oid => '23', array_type_oid => '1007', + descr => '-2 billion to 2 billion integer, 4-byte storage', typname => 'int4', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_int4', typinput => 'int4in', typoutput => 'int4out', - typreceive => 'int4recv', typsend => 'int4send', typalign => 'i' }, -{ oid => '24', descr => 'registered procedure', + typinput => 'int4in', typoutput => 'int4out', typreceive => 'int4recv', + typsend => 'int4send', typalign => 'i' }, +{ oid => '24', array_type_oid => '1008', descr => 'registered procedure', typname => 'regproc', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regproc', typinput => 'regprocin', typoutput => 'regprocout', + typinput => 'regprocin', typoutput => 'regprocout', typreceive => 'regprocrecv', typsend => 'regprocsend', typalign => 'i' }, -{ oid => '25', descr => 'variable-length string, no limit specified', +{ oid => '25', array_type_oid => '1009', + descr => 'variable-length string, no limit specified', typname => 'text', typlen => '-1', typbyval => 'f', typcategory => 'S', - typispreferred => 't', typarray => '_text', typinput => 'textin', - typoutput => 'textout', typreceive => 'textrecv', typsend => 'textsend', - typalign => 'i', typstorage => 'x', typcollation => '100' }, -{ oid => '26', descr => 'object identifier(oid), maximum 4 billion', + typispreferred => 't', typinput => 'textin', typoutput => 'textout', + typreceive => 'textrecv', typsend => 'textsend', typalign => 'i', + typstorage => 'x', typcollation => 'default' }, +{ oid => '26', array_type_oid => '1028', + descr => 'object identifier(oid), maximum 4 billion', typname => 'oid', typlen => '4', typbyval => 't', typcategory => 'N', - typispreferred => 't', typarray => '_oid', typinput => 'oidin', - typoutput => 'oidout', typreceive => 'oidrecv', typsend => 'oidsend', - typalign => 'i' }, -{ oid => '27', descr => '(block, offset), physical location of tuple', + typispreferred => 't', typinput => 'oidin', typoutput => 'oidout', + typreceive => 'oidrecv', typsend => 'oidsend', typalign => 'i' }, +{ oid => '27', array_type_oid => '1010', + descr => '(block, offset), physical location of tuple', typname => 'tid', typlen => '6', typbyval => 'f', typcategory => 'U', - typarray => '_tid', typinput => 'tidin', typoutput => 'tidout', - typreceive => 'tidrecv', typsend => 'tidsend', typalign => 's' }, -{ oid => '28', descr => 'transaction id', + typinput => 'tidin', typoutput => 'tidout', typreceive => 'tidrecv', + typsend => 'tidsend', typalign => 's' }, +{ oid => '28', array_type_oid => '1011', descr => 'transaction id', typname => 'xid', typlen => '4', typbyval => 't', typcategory => 'U', - typarray => '_xid', typinput => 'xidin', typoutput => 'xidout', - typreceive => 'xidrecv', typsend => 'xidsend', typalign => 'i' }, -{ oid => '29', descr => 'command identifier type, sequence in transaction id', + typinput => 'xidin', typoutput => 'xidout', typreceive => 'xidrecv', + typsend => 'xidsend', typalign => 'i' }, +{ oid => '29', array_type_oid => '1012', + descr => 'command identifier type, sequence in transaction id', typname => 'cid', typlen => '4', typbyval => 't', typcategory => 'U', - typarray => '_cid', typinput => 'cidin', typoutput => 'cidout', - typreceive => 'cidrecv', typsend => 'cidsend', typalign => 'i' }, -{ oid => '30', descr => 'array of oids, used in system tables', + typinput => 'cidin', typoutput => 'cidout', typreceive => 'cidrecv', + typsend => 'cidsend', typalign => 'i' }, +{ oid => '30', array_type_oid => '1013', + descr => 'array of oids, used in system tables', typname => 'oidvector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'oid', typarray => '_oidvector', typinput => 'oidvectorin', - typoutput => 'oidvectorout', typreceive => 'oidvectorrecv', - typsend => 'oidvectorsend', typalign => 'i' }, + typelem => 'oid', typinput => 'oidvectorin', typoutput => 'oidvectorout', + typreceive => 'oidvectorrecv', typsend => 'oidvectorsend', typalign => 'i' }, # hand-built rowtype entries for bootstrapped catalogs # NB: OIDs assigned here must match the BKI_ROWTYPE_OID declarations { oid => '71', typname => 'pg_type', typlen => '-1', typbyval => 'f', typtype => 'c', - typcategory => 'C', typrelid => '1247', typinput => 'record_in', + typcategory => 'C', typrelid => 'pg_type', typinput => 'record_in', typoutput => 'record_out', typreceive => 'record_recv', typsend => 'record_send', typalign => 'd', typstorage => 'x' }, { oid => '75', typname => 'pg_attribute', typlen => '-1', typbyval => 'f', typtype => 'c', - typcategory => 'C', typrelid => '1249', typinput => 'record_in', + typcategory => 'C', typrelid => 'pg_attribute', typinput => 'record_in', typoutput => 'record_out', typreceive => 'record_recv', typsend => 'record_send', typalign => 'd', typstorage => 'x' }, { oid => '81', typname => 'pg_proc', typlen => '-1', typbyval => 'f', typtype => 'c', - typcategory => 'C', typrelid => '1255', typinput => 'record_in', + typcategory => 'C', typrelid => 'pg_proc', typinput => 'record_in', typoutput => 'record_out', typreceive => 'record_recv', typsend => 'record_send', typalign => 'd', typstorage => 'x' }, { oid => '83', typname => 'pg_class', typlen => '-1', typbyval => 'f', typtype => 'c', - typcategory => 'C', typrelid => '1259', typinput => 'record_in', + typcategory => 'C', typrelid => 'pg_class', typinput => 'record_in', typoutput => 'record_out', typreceive => 'record_recv', typsend => 'record_send', typalign => 'd', typstorage => 'x' }, # OIDS 100 - 199 -{ oid => '114', +{ oid => '114', array_type_oid => '199', descr => 'JSON stored as text', typname => 'json', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_json', typinput => 'json_in', typoutput => 'json_out', - typreceive => 'json_recv', typsend => 'json_send', typalign => 'i', - typstorage => 'x' }, -{ oid => '142', descr => 'XML content', + typinput => 'json_in', typoutput => 'json_out', typreceive => 'json_recv', + typsend => 'json_send', typalign => 'i', typstorage => 'x' }, +{ oid => '142', array_type_oid => '143', descr => 'XML content', typname => 'xml', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_xml', typinput => 'xml_in', typoutput => 'xml_out', - typreceive => 'xml_recv', typsend => 'xml_send', typalign => 'i', - typstorage => 'x' }, -{ oid => '143', - typname => '_xml', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'xml', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '199', - typname => '_json', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'json', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, + typinput => 'xml_in', typoutput => 'xml_out', typreceive => 'xml_recv', + typsend => 'xml_send', typalign => 'i', typstorage => 'x' }, { oid => '194', oid_symbol => 'PGNODETREEOID', descr => 'string representing an internal node tree', typname => 'pg_node_tree', typlen => '-1', typbyval => 'f', typcategory => 'S', typinput => 'pg_node_tree_in', typoutput => 'pg_node_tree_out', typreceive => 'pg_node_tree_recv', typsend => 'pg_node_tree_send', typalign => 'i', typstorage => 'x', - typcollation => '100' }, + typcollation => 'default' }, { oid => '3361', oid_symbol => 'PGNDISTINCTOID', descr => 'multivariate ndistinct coefficients', typname => 'pg_ndistinct', typlen => '-1', typbyval => 'f', typcategory => 'S', typinput => 'pg_ndistinct_in', typoutput => 'pg_ndistinct_out', typreceive => 'pg_ndistinct_recv', typsend => 'pg_ndistinct_send', typalign => 'i', typstorage => 'x', - typcollation => '100' }, + typcollation => 'default' }, { oid => '3402', oid_symbol => 'PGDEPENDENCIESOID', descr => 'multivariate dependencies', typname => 'pg_dependencies', typlen => '-1', typbyval => 'f', typcategory => 'S', typinput => 'pg_dependencies_in', typoutput => 'pg_dependencies_out', typreceive => 'pg_dependencies_recv', typsend => 'pg_dependencies_send', typalign => 'i', typstorage => 'x', - typcollation => '100' }, + typcollation => 'default' }, +{ oid => '5017', oid_symbol => 'PGMCVLISTOID', + descr => 'multivariate MCV list', + typname => 'pg_mcv_list', typlen => '-1', typbyval => 'f', typcategory => 'S', + typinput => 'pg_mcv_list_in', typoutput => 'pg_mcv_list_out', + typreceive => 'pg_mcv_list_recv', typsend => 'pg_mcv_list_send', + typalign => 'i', typstorage => 'x', typcollation => 'default' }, { oid => '32', oid_symbol => 'PGDDLCOMMANDOID', descr => 'internal type for passing CollectedCommand', typname => 'pg_ddl_command', typlen => 'SIZEOF_POINTER', typbyval => 't', @@ -172,678 +178,313 @@ typoutput => 'pg_ddl_command_out', typreceive => 'pg_ddl_command_recv', typsend => 'pg_ddl_command_send', typalign => 'ALIGNOF_POINTER' }, -# OIDS 200 - 299 - -{ oid => '210', descr => 'storage manager', - typname => 'smgr', typlen => '2', typbyval => 't', typcategory => 'U', - typinput => 'smgrin', typoutput => 'smgrout', typreceive => '-', - typsend => '-', typalign => 's' }, - # OIDS 600 - 699 -{ oid => '600', descr => 'geometric point \'(x, y)\'', +{ oid => '600', array_type_oid => '1017', + descr => 'geometric point \'(x, y)\'', typname => 'point', typlen => '16', typbyval => 'f', typcategory => 'G', - typelem => 'float8', typarray => '_point', typinput => 'point_in', - typoutput => 'point_out', typreceive => 'point_recv', typsend => 'point_send', - typalign => 'd' }, -{ oid => '601', descr => 'geometric line segment \'(pt1,pt2)\'', + typelem => 'float8', typinput => 'point_in', typoutput => 'point_out', + typreceive => 'point_recv', typsend => 'point_send', typalign => 'd' }, +{ oid => '601', array_type_oid => '1018', + descr => 'geometric line segment \'(pt1,pt2)\'', typname => 'lseg', typlen => '32', typbyval => 'f', typcategory => 'G', - typelem => 'point', typarray => '_lseg', typinput => 'lseg_in', - typoutput => 'lseg_out', typreceive => 'lseg_recv', typsend => 'lseg_send', - typalign => 'd' }, -{ oid => '602', descr => 'geometric path \'(pt1,...)\'', + typelem => 'point', typinput => 'lseg_in', typoutput => 'lseg_out', + typreceive => 'lseg_recv', typsend => 'lseg_send', typalign => 'd' }, +{ oid => '602', array_type_oid => '1019', + descr => 'geometric path \'(pt1,...)\'', typname => 'path', typlen => '-1', typbyval => 'f', typcategory => 'G', - typarray => '_path', typinput => 'path_in', typoutput => 'path_out', - typreceive => 'path_recv', typsend => 'path_send', typalign => 'd', - typstorage => 'x' }, -{ oid => '603', descr => 'geometric box \'(lower left,upper right)\'', + typinput => 'path_in', typoutput => 'path_out', typreceive => 'path_recv', + typsend => 'path_send', typalign => 'd', typstorage => 'x' }, +{ oid => '603', array_type_oid => '1020', + descr => 'geometric box \'(lower left,upper right)\'', typname => 'box', typlen => '32', typbyval => 'f', typcategory => 'G', - typdelim => ';', typelem => 'point', typarray => '_box', typinput => 'box_in', + typdelim => ';', typelem => 'point', typinput => 'box_in', typoutput => 'box_out', typreceive => 'box_recv', typsend => 'box_send', typalign => 'd' }, -{ oid => '604', descr => 'geometric polygon \'(pt1,...)\'', +{ oid => '604', array_type_oid => '1027', + descr => 'geometric polygon \'(pt1,...)\'', typname => 'polygon', typlen => '-1', typbyval => 'f', typcategory => 'G', - typarray => '_polygon', typinput => 'poly_in', typoutput => 'poly_out', - typreceive => 'poly_recv', typsend => 'poly_send', typalign => 'd', - typstorage => 'x' }, -{ oid => '628', descr => 'geometric line', + typinput => 'poly_in', typoutput => 'poly_out', typreceive => 'poly_recv', + typsend => 'poly_send', typalign => 'd', typstorage => 'x' }, +{ oid => '628', array_type_oid => '629', descr => 'geometric line', typname => 'line', typlen => '24', typbyval => 'f', typcategory => 'G', - typelem => 'float8', typarray => '_line', typinput => 'line_in', - typoutput => 'line_out', typreceive => 'line_recv', typsend => 'line_send', - typalign => 'd' }, -{ oid => '629', - typname => '_line', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'line', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, + typelem => 'float8', typinput => 'line_in', typoutput => 'line_out', + typreceive => 'line_recv', typsend => 'line_send', typalign => 'd' }, # OIDS 700 - 799 -{ oid => '700', +{ oid => '700', array_type_oid => '1021', descr => 'single-precision floating point number, 4-byte storage', typname => 'float4', typlen => '4', typbyval => 'FLOAT4PASSBYVAL', - typcategory => 'N', typarray => '_float4', typinput => 'float4in', - typoutput => 'float4out', typreceive => 'float4recv', typsend => 'float4send', - typalign => 'i' }, -{ oid => '701', + typcategory => 'N', typinput => 'float4in', typoutput => 'float4out', + typreceive => 'float4recv', typsend => 'float4send', typalign => 'i' }, +{ oid => '701', array_type_oid => '1022', descr => 'double-precision floating point number, 8-byte storage', typname => 'float8', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'N', typispreferred => 't', typarray => '_float8', - typinput => 'float8in', typoutput => 'float8out', typreceive => 'float8recv', - typsend => 'float8send', typalign => 'd' }, -{ oid => '702', - descr => 'absolute, limited-range date and time (Unix system time)', - typname => 'abstime', typlen => '4', typbyval => 't', typcategory => 'D', - typarray => '_abstime', typinput => 'abstimein', typoutput => 'abstimeout', - typreceive => 'abstimerecv', typsend => 'abstimesend', typalign => 'i' }, -{ oid => '703', - descr => 'relative, limited-range time interval (Unix delta time)', - typname => 'reltime', typlen => '4', typbyval => 't', typcategory => 'T', - typarray => '_reltime', typinput => 'reltimein', typoutput => 'reltimeout', - typreceive => 'reltimerecv', typsend => 'reltimesend', typalign => 'i' }, -{ oid => '704', descr => '(abstime,abstime), time interval', - typname => 'tinterval', typlen => '12', typbyval => 'f', typcategory => 'T', - typarray => '_tinterval', typinput => 'tintervalin', - typoutput => 'tintervalout', typreceive => 'tintervalrecv', - typsend => 'tintervalsend', typalign => 'i' }, -{ oid => '705', + typcategory => 'N', typispreferred => 't', typinput => 'float8in', + typoutput => 'float8out', typreceive => 'float8recv', typsend => 'float8send', + typalign => 'd' }, +{ oid => '705', descr => 'pseudo-type representing an undetermined type', typname => 'unknown', typlen => '-2', typbyval => 'f', typtype => 'p', typcategory => 'X', typinput => 'unknownin', typoutput => 'unknownout', typreceive => 'unknownrecv', typsend => 'unknownsend', typalign => 'c' }, -{ oid => '718', descr => 'geometric circle \'(center,radius)\'', +{ oid => '718', array_type_oid => '719', + descr => 'geometric circle \'(center,radius)\'', typname => 'circle', typlen => '24', typbyval => 'f', typcategory => 'G', - typarray => '_circle', typinput => 'circle_in', typoutput => 'circle_out', + typinput => 'circle_in', typoutput => 'circle_out', typreceive => 'circle_recv', typsend => 'circle_send', typalign => 'd' }, -{ oid => '719', - typname => '_circle', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'circle', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '790', oid_symbol => 'CASHOID', +{ oid => '790', oid_symbol => 'CASHOID', array_type_oid => '791', descr => 'monetary amounts, $d,ddd.cc', typname => 'money', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'N', typarray => '_money', typinput => 'cash_in', - typoutput => 'cash_out', typreceive => 'cash_recv', typsend => 'cash_send', - typalign => 'd' }, -{ oid => '791', - typname => '_money', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'money', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, + typcategory => 'N', typinput => 'cash_in', typoutput => 'cash_out', + typreceive => 'cash_recv', typsend => 'cash_send', typalign => 'd' }, # OIDS 800 - 899 -{ oid => '829', descr => 'XX:XX:XX:XX:XX:XX, MAC address', +{ oid => '829', array_type_oid => '1040', + descr => 'XX:XX:XX:XX:XX:XX, MAC address', typname => 'macaddr', typlen => '6', typbyval => 'f', typcategory => 'U', - typarray => '_macaddr', typinput => 'macaddr_in', typoutput => 'macaddr_out', + typinput => 'macaddr_in', typoutput => 'macaddr_out', typreceive => 'macaddr_recv', typsend => 'macaddr_send', typalign => 'i' }, -{ oid => '869', descr => 'IP address/netmask, host address, netmask optional', +{ oid => '869', array_type_oid => '1041', + descr => 'IP address/netmask, host address, netmask optional', typname => 'inet', typlen => '-1', typbyval => 'f', typcategory => 'I', - typispreferred => 't', typarray => '_inet', typinput => 'inet_in', - typoutput => 'inet_out', typreceive => 'inet_recv', typsend => 'inet_send', - typalign => 'i', typstorage => 'm' }, -{ oid => '650', descr => 'network IP address/netmask, network address', - typname => 'cidr', typlen => '-1', typbyval => 'f', typcategory => 'I', - typarray => '_cidr', typinput => 'cidr_in', typoutput => 'cidr_out', - typreceive => 'cidr_recv', typsend => 'cidr_send', typalign => 'i', + typispreferred => 't', typinput => 'inet_in', typoutput => 'inet_out', + typreceive => 'inet_recv', typsend => 'inet_send', typalign => 'i', typstorage => 'm' }, -{ oid => '774', descr => 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address', +{ oid => '650', array_type_oid => '651', + descr => 'network IP address/netmask, network address', + typname => 'cidr', typlen => '-1', typbyval => 'f', typcategory => 'I', + typinput => 'cidr_in', typoutput => 'cidr_out', typreceive => 'cidr_recv', + typsend => 'cidr_send', typalign => 'i', typstorage => 'm' }, +{ oid => '774', array_type_oid => '775', + descr => 'XX:XX:XX:XX:XX:XX:XX:XX, MAC address', typname => 'macaddr8', typlen => '8', typbyval => 'f', typcategory => 'U', - typarray => '_macaddr8', typinput => 'macaddr8_in', - typoutput => 'macaddr8_out', typreceive => 'macaddr8_recv', - typsend => 'macaddr8_send', typalign => 'i' }, + typinput => 'macaddr8_in', typoutput => 'macaddr8_out', + typreceive => 'macaddr8_recv', typsend => 'macaddr8_send', typalign => 'i' }, # OIDS 1000 - 1099 -{ oid => '1000', - typname => '_bool', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'bool', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1001', - typname => '_bytea', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'bytea', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1002', - typname => '_char', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'char', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1003', - typname => '_name', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'name', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1005', - typname => '_int2', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int2', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1006', - typname => '_int2vector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int2vector', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1007', - typname => '_int4', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int4', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1008', - typname => '_regproc', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regproc', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1009', - typname => '_text', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'text', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x', - typcollation => '100' }, -{ oid => '1028', - typname => '_oid', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'oid', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1010', - typname => '_tid', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tid', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1011', - typname => '_xid', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'xid', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1012', - typname => '_cid', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'cid', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1013', - typname => '_oidvector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'oidvector', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1014', - typname => '_bpchar', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'bpchar', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'bpchartypmodin', typmodout => 'bpchartypmodout', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x', - typcollation => '100' }, -{ oid => '1015', - typname => '_varchar', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'varchar', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'varchartypmodin', typmodout => 'varchartypmodout', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x', - typcollation => '100' }, -{ oid => '1016', - typname => '_int8', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int8', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1017', - typname => '_point', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'point', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1018', - typname => '_lseg', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'lseg', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1019', - typname => '_path', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'path', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1020', - typname => '_box', typlen => '-1', typbyval => 'f', typcategory => 'A', - typdelim => ';', typelem => 'box', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1021', - typname => '_float4', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'float4', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1022', - typname => '_float8', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'float8', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1023', - typname => '_abstime', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'abstime', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1024', - typname => '_reltime', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'reltime', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1025', - typname => '_tinterval', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tinterval', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1027', - typname => '_polygon', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'polygon', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1033', descr => 'access control list', +{ oid => '1033', array_type_oid => '1034', descr => 'access control list', typname => 'aclitem', typlen => '12', typbyval => 'f', typcategory => 'U', - typarray => '_aclitem', typinput => 'aclitemin', typoutput => 'aclitemout', - typreceive => '-', typsend => '-', typalign => 'i' }, -{ oid => '1034', - typname => '_aclitem', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'aclitem', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1040', - typname => '_macaddr', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'macaddr', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '775', - typname => '_macaddr8', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'macaddr8', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1041', - typname => '_inet', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'inet', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '651', - typname => '_cidr', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'cidr', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1263', - typname => '_cstring', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'cstring', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1042', + typinput => 'aclitemin', typoutput => 'aclitemout', typreceive => '-', + typsend => '-', typalign => 'i' }, +{ oid => '1042', array_type_oid => '1014', descr => 'char(length), blank-padded string, fixed storage length', typname => 'bpchar', typlen => '-1', typbyval => 'f', typcategory => 'S', - typarray => '_bpchar', typinput => 'bpcharin', typoutput => 'bpcharout', - typreceive => 'bpcharrecv', typsend => 'bpcharsend', - typmodin => 'bpchartypmodin', typmodout => 'bpchartypmodout', typalign => 'i', - typstorage => 'x', typcollation => '100' }, -{ oid => '1043', + typinput => 'bpcharin', typoutput => 'bpcharout', typreceive => 'bpcharrecv', + typsend => 'bpcharsend', typmodin => 'bpchartypmodin', + typmodout => 'bpchartypmodout', typalign => 'i', typstorage => 'x', + typcollation => 'default' }, +{ oid => '1043', array_type_oid => '1015', descr => 'varchar(length), non-blank-padded string, variable storage length', typname => 'varchar', typlen => '-1', typbyval => 'f', typcategory => 'S', - typarray => '_varchar', typinput => 'varcharin', typoutput => 'varcharout', + typinput => 'varcharin', typoutput => 'varcharout', typreceive => 'varcharrecv', typsend => 'varcharsend', typmodin => 'varchartypmodin', typmodout => 'varchartypmodout', - typalign => 'i', typstorage => 'x', typcollation => '100' }, -{ oid => '1082', descr => 'date', + typalign => 'i', typstorage => 'x', typcollation => 'default' }, +{ oid => '1082', array_type_oid => '1182', descr => 'date', typname => 'date', typlen => '4', typbyval => 't', typcategory => 'D', - typarray => '_date', typinput => 'date_in', typoutput => 'date_out', - typreceive => 'date_recv', typsend => 'date_send', typalign => 'i' }, -{ oid => '1083', descr => 'time of day', + typinput => 'date_in', typoutput => 'date_out', typreceive => 'date_recv', + typsend => 'date_send', typalign => 'i' }, +{ oid => '1083', array_type_oid => '1183', descr => 'time of day', typname => 'time', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'D', typarray => '_time', typinput => 'time_in', - typoutput => 'time_out', typreceive => 'time_recv', typsend => 'time_send', - typmodin => 'timetypmodin', typmodout => 'timetypmodout', typalign => 'd' }, + typcategory => 'D', typinput => 'time_in', typoutput => 'time_out', + typreceive => 'time_recv', typsend => 'time_send', typmodin => 'timetypmodin', + typmodout => 'timetypmodout', typalign => 'd' }, # OIDS 1100 - 1199 -{ oid => '1114', descr => 'date and time', +{ oid => '1114', array_type_oid => '1115', descr => 'date and time', typname => 'timestamp', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'D', typarray => '_timestamp', typinput => 'timestamp_in', - typoutput => 'timestamp_out', typreceive => 'timestamp_recv', - typsend => 'timestamp_send', typmodin => 'timestamptypmodin', - typmodout => 'timestamptypmodout', typalign => 'd' }, -{ oid => '1115', - typname => '_timestamp', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'timestamp', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', + typcategory => 'D', typinput => 'timestamp_in', typoutput => 'timestamp_out', + typreceive => 'timestamp_recv', typsend => 'timestamp_send', typmodin => 'timestamptypmodin', typmodout => 'timestamptypmodout', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1182', - typname => '_date', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'date', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1183', - typname => '_time', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'time', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'timetypmodin', typmodout => 'timetypmodout', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1184', descr => 'date and time with time zone', - typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'D', typispreferred => 't', typarray => '_timestamptz', - typinput => 'timestamptz_in', typoutput => 'timestamptz_out', - typreceive => 'timestamptz_recv', typsend => 'timestamptz_send', - typmodin => 'timestamptztypmodin', typmodout => 'timestamptztypmodout', typalign => 'd' }, -{ oid => '1185', - typname => '_timestamptz', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'timestamptz', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'timestamptztypmodin', typmodout => 'timestamptztypmodout', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '1186', descr => '@ , time interval', +{ oid => '1184', array_type_oid => '1185', + descr => 'date and time with time zone', + typname => 'timestamptz', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', + typcategory => 'D', typispreferred => 't', typinput => 'timestamptz_in', + typoutput => 'timestamptz_out', typreceive => 'timestamptz_recv', + typsend => 'timestamptz_send', typmodin => 'timestamptztypmodin', + typmodout => 'timestamptztypmodout', typalign => 'd' }, +{ oid => '1186', array_type_oid => '1187', + descr => '@ , time interval', typname => 'interval', typlen => '16', typbyval => 'f', typcategory => 'T', - typispreferred => 't', typarray => '_interval', typinput => 'interval_in', - typoutput => 'interval_out', typreceive => 'interval_recv', - typsend => 'interval_send', typmodin => 'intervaltypmodin', - typmodout => 'intervaltypmodout', typalign => 'd' }, -{ oid => '1187', - typname => '_interval', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'interval', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', + typispreferred => 't', typinput => 'interval_in', typoutput => 'interval_out', + typreceive => 'interval_recv', typsend => 'interval_send', typmodin => 'intervaltypmodin', typmodout => 'intervaltypmodout', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, + typalign => 'd' }, # OIDS 1200 - 1299 -{ oid => '1231', - typname => '_numeric', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'numeric', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'numerictypmodin', typmodout => 'numerictypmodout', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1266', descr => 'time of day with time zone', +{ oid => '1266', array_type_oid => '1270', + descr => 'time of day with time zone', typname => 'timetz', typlen => '12', typbyval => 'f', typcategory => 'D', - typarray => '_timetz', typinput => 'timetz_in', typoutput => 'timetz_out', + typinput => 'timetz_in', typoutput => 'timetz_out', typreceive => 'timetz_recv', typsend => 'timetz_send', typmodin => 'timetztypmodin', typmodout => 'timetztypmodout', typalign => 'd' }, -{ oid => '1270', - typname => '_timetz', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'timetz', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'timetztypmodin', typmodout => 'timetztypmodout', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, # OIDS 1500 - 1599 -{ oid => '1560', descr => 'fixed-length bit string', +{ oid => '1560', array_type_oid => '1561', descr => 'fixed-length bit string', typname => 'bit', typlen => '-1', typbyval => 'f', typcategory => 'V', - typarray => '_bit', typinput => 'bit_in', typoutput => 'bit_out', - typreceive => 'bit_recv', typsend => 'bit_send', typmodin => 'bittypmodin', - typmodout => 'bittypmodout', typalign => 'i', typstorage => 'x' }, -{ oid => '1561', - typname => '_bit', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'bit', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'bittypmodin', typmodout => 'bittypmodout', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '1562', descr => 'variable-length bit string', + typinput => 'bit_in', typoutput => 'bit_out', typreceive => 'bit_recv', + typsend => 'bit_send', typmodin => 'bittypmodin', typmodout => 'bittypmodout', + typalign => 'i', typstorage => 'x' }, +{ oid => '1562', array_type_oid => '1563', + descr => 'variable-length bit string', typname => 'varbit', typlen => '-1', typbyval => 'f', typcategory => 'V', - typispreferred => 't', typarray => '_varbit', typinput => 'varbit_in', - typoutput => 'varbit_out', typreceive => 'varbit_recv', - typsend => 'varbit_send', typmodin => 'varbittypmodin', - typmodout => 'varbittypmodout', typalign => 'i', typstorage => 'x' }, -{ oid => '1563', - typname => '_varbit', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'varbit', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typmodin => 'varbittypmodin', typmodout => 'varbittypmodout', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, + typispreferred => 't', typinput => 'varbit_in', typoutput => 'varbit_out', + typreceive => 'varbit_recv', typsend => 'varbit_send', + typmodin => 'varbittypmodin', typmodout => 'varbittypmodout', typalign => 'i', + typstorage => 'x' }, # OIDS 1700 - 1799 -{ oid => '1700', +{ oid => '1700', array_type_oid => '1231', descr => 'numeric(precision, decimal), arbitrary precision number', typname => 'numeric', typlen => '-1', typbyval => 'f', typcategory => 'N', - typarray => '_numeric', typinput => 'numeric_in', typoutput => 'numeric_out', + typinput => 'numeric_in', typoutput => 'numeric_out', typreceive => 'numeric_recv', typsend => 'numeric_send', typmodin => 'numerictypmodin', typmodout => 'numerictypmodout', typalign => 'i', typstorage => 'm' }, -{ oid => '1790', descr => 'reference to cursor (portal name)', +{ oid => '1790', array_type_oid => '2201', + descr => 'reference to cursor (portal name)', typname => 'refcursor', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_refcursor', typinput => 'textin', typoutput => 'textout', - typreceive => 'textrecv', typsend => 'textsend', typalign => 'i', - typstorage => 'x' }, + typinput => 'textin', typoutput => 'textout', typreceive => 'textrecv', + typsend => 'textsend', typalign => 'i', typstorage => 'x' }, # OIDS 2200 - 2299 -{ oid => '2201', - typname => '_refcursor', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'refcursor', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, - -{ oid => '2202', descr => 'registered procedure (with args)', +{ oid => '2202', array_type_oid => '2207', + descr => 'registered procedure (with args)', typname => 'regprocedure', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regprocedure', typinput => 'regprocedurein', - typoutput => 'regprocedureout', typreceive => 'regprocedurerecv', - typsend => 'regproceduresend', typalign => 'i' }, -{ oid => '2203', descr => 'registered operator', + typinput => 'regprocedurein', typoutput => 'regprocedureout', + typreceive => 'regprocedurerecv', typsend => 'regproceduresend', + typalign => 'i' }, +{ oid => '2203', array_type_oid => '2208', descr => 'registered operator', typname => 'regoper', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regoper', typinput => 'regoperin', typoutput => 'regoperout', + typinput => 'regoperin', typoutput => 'regoperout', typreceive => 'regoperrecv', typsend => 'regopersend', typalign => 'i' }, -{ oid => '2204', descr => 'registered operator (with args)', +{ oid => '2204', array_type_oid => '2209', + descr => 'registered operator (with args)', typname => 'regoperator', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regoperator', typinput => 'regoperatorin', - typoutput => 'regoperatorout', typreceive => 'regoperatorrecv', - typsend => 'regoperatorsend', typalign => 'i' }, -{ oid => '2205', descr => 'registered class', + typinput => 'regoperatorin', typoutput => 'regoperatorout', + typreceive => 'regoperatorrecv', typsend => 'regoperatorsend', + typalign => 'i' }, +{ oid => '2205', array_type_oid => '2210', descr => 'registered class', typname => 'regclass', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regclass', typinput => 'regclassin', typoutput => 'regclassout', + typinput => 'regclassin', typoutput => 'regclassout', typreceive => 'regclassrecv', typsend => 'regclasssend', typalign => 'i' }, -{ oid => '2206', descr => 'registered type', +{ oid => '2206', array_type_oid => '2211', descr => 'registered type', typname => 'regtype', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regtype', typinput => 'regtypein', typoutput => 'regtypeout', + typinput => 'regtypein', typoutput => 'regtypeout', typreceive => 'regtyperecv', typsend => 'regtypesend', typalign => 'i' }, -{ oid => '4096', descr => 'registered role', +{ oid => '4096', array_type_oid => '4097', descr => 'registered role', typname => 'regrole', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regrole', typinput => 'regrolein', typoutput => 'regroleout', + typinput => 'regrolein', typoutput => 'regroleout', typreceive => 'regrolerecv', typsend => 'regrolesend', typalign => 'i' }, -{ oid => '4089', descr => 'registered namespace', +{ oid => '4089', array_type_oid => '4090', descr => 'registered namespace', typname => 'regnamespace', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regnamespace', typinput => 'regnamespacein', - typoutput => 'regnamespaceout', typreceive => 'regnamespacerecv', - typsend => 'regnamespacesend', typalign => 'i' }, -{ oid => '2207', - typname => '_regprocedure', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'regprocedure', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '2208', - typname => '_regoper', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regoper', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '2209', - typname => '_regoperator', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'regoperator', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '2210', - typname => '_regclass', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regclass', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '2211', - typname => '_regtype', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regtype', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '4097', - typname => '_regrole', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regrole', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '4090', - typname => '_regnamespace', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'regnamespace', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, + typinput => 'regnamespacein', typoutput => 'regnamespaceout', + typreceive => 'regnamespacerecv', typsend => 'regnamespacesend', + typalign => 'i' }, # uuid -{ oid => '2950', descr => 'UUID datatype', +{ oid => '2950', array_type_oid => '2951', descr => 'UUID datatype', typname => 'uuid', typlen => '16', typbyval => 'f', typcategory => 'U', - typarray => '_uuid', typinput => 'uuid_in', typoutput => 'uuid_out', - typreceive => 'uuid_recv', typsend => 'uuid_send', typalign => 'c' }, -{ oid => '2951', - typname => '_uuid', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'uuid', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, + typinput => 'uuid_in', typoutput => 'uuid_out', typreceive => 'uuid_recv', + typsend => 'uuid_send', typalign => 'c' }, # pg_lsn -{ oid => '3220', oid_symbol => 'LSNOID', descr => 'PostgreSQL LSN datatype', +{ oid => '3220', oid_symbol => 'LSNOID', array_type_oid => '3221', + descr => 'PostgreSQL LSN datatype', typname => 'pg_lsn', typlen => '8', typbyval => 'FLOAT8PASSBYVAL', - typcategory => 'U', typarray => '_pg_lsn', typinput => 'pg_lsn_in', - typoutput => 'pg_lsn_out', typreceive => 'pg_lsn_recv', - typsend => 'pg_lsn_send', typalign => 'd' }, -{ oid => '3221', - typname => '_pg_lsn', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'pg_lsn', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, + typcategory => 'U', typinput => 'pg_lsn_in', typoutput => 'pg_lsn_out', + typreceive => 'pg_lsn_recv', typsend => 'pg_lsn_send', typalign => 'd' }, # text search -{ oid => '3614', descr => 'text representation for text search', +{ oid => '3614', array_type_oid => '3643', + descr => 'text representation for text search', typname => 'tsvector', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_tsvector', typinput => 'tsvectorin', typoutput => 'tsvectorout', + typinput => 'tsvectorin', typoutput => 'tsvectorout', typreceive => 'tsvectorrecv', typsend => 'tsvectorsend', typanalyze => 'ts_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3642', +{ oid => '3642', array_type_oid => '3644', descr => 'GiST index internal text representation for text search', typname => 'gtsvector', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_gtsvector', typinput => 'gtsvectorin', - typoutput => 'gtsvectorout', typreceive => '-', typsend => '-', - typalign => 'i' }, -{ oid => '3615', descr => 'query representation for text search', + typinput => 'gtsvectorin', typoutput => 'gtsvectorout', typreceive => '-', + typsend => '-', typalign => 'i' }, +{ oid => '3615', array_type_oid => '3645', + descr => 'query representation for text search', typname => 'tsquery', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_tsquery', typinput => 'tsqueryin', typoutput => 'tsqueryout', + typinput => 'tsqueryin', typoutput => 'tsqueryout', typreceive => 'tsqueryrecv', typsend => 'tsquerysend', typalign => 'i' }, -{ oid => '3734', descr => 'registered text search configuration', +{ oid => '3734', array_type_oid => '3735', + descr => 'registered text search configuration', typname => 'regconfig', typlen => '4', typbyval => 't', typcategory => 'N', - typarray => '_regconfig', typinput => 'regconfigin', - typoutput => 'regconfigout', typreceive => 'regconfigrecv', - typsend => 'regconfigsend', typalign => 'i' }, -{ oid => '3769', descr => 'registered text search dictionary', + typinput => 'regconfigin', typoutput => 'regconfigout', + typreceive => 'regconfigrecv', typsend => 'regconfigsend', typalign => 'i' }, +{ oid => '3769', array_type_oid => '3770', + descr => 'registered text search dictionary', typname => 'regdictionary', typlen => '4', typbyval => 't', - typcategory => 'N', typarray => '_regdictionary', - typinput => 'regdictionaryin', typoutput => 'regdictionaryout', - typreceive => 'regdictionaryrecv', typsend => 'regdictionarysend', - typalign => 'i' }, - -{ oid => '3643', - typname => '_tsvector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tsvector', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3644', - typname => '_gtsvector', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'gtsvector', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3645', - typname => '_tsquery', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tsquery', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3735', - typname => '_regconfig', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'regconfig', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3770', - typname => '_regdictionary', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'regdictionary', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, + typcategory => 'N', typinput => 'regdictionaryin', + typoutput => 'regdictionaryout', typreceive => 'regdictionaryrecv', + typsend => 'regdictionarysend', typalign => 'i' }, # jsonb -{ oid => '3802', descr => 'Binary JSON', +{ oid => '3802', array_type_oid => '3807', descr => 'Binary JSON', typname => 'jsonb', typlen => '-1', typbyval => 'f', typcategory => 'U', - typarray => '_jsonb', typinput => 'jsonb_in', typoutput => 'jsonb_out', - typreceive => 'jsonb_recv', typsend => 'jsonb_send', typalign => 'i', + typinput => 'jsonb_in', typoutput => 'jsonb_out', typreceive => 'jsonb_recv', + typsend => 'jsonb_send', typalign => 'i', typstorage => 'x' }, +{ oid => '4072', array_type_oid => '4073', descr => 'JSON path', + typname => 'jsonpath', typlen => '-1', typbyval => 'f', typcategory => 'U', + typinput => 'jsonpath_in', typoutput => 'jsonpath_out', + typreceive => 'jsonpath_recv', typsend => 'jsonpath_send', typalign => 'i', typstorage => 'x' }, -{ oid => '3807', - typname => '_jsonb', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'jsonb', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '2970', descr => 'txid snapshot', +{ oid => '2970', array_type_oid => '2949', descr => 'txid snapshot', typname => 'txid_snapshot', typlen => '-1', typbyval => 'f', - typcategory => 'U', typarray => '_txid_snapshot', - typinput => 'txid_snapshot_in', typoutput => 'txid_snapshot_out', - typreceive => 'txid_snapshot_recv', typsend => 'txid_snapshot_send', - typalign => 'd', typstorage => 'x' }, -{ oid => '2949', - typname => '_txid_snapshot', typlen => '-1', typbyval => 'f', - typcategory => 'A', typelem => 'txid_snapshot', typinput => 'array_in', - typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, + typcategory => 'U', typinput => 'txid_snapshot_in', + typoutput => 'txid_snapshot_out', typreceive => 'txid_snapshot_recv', + typsend => 'txid_snapshot_send', typalign => 'd', typstorage => 'x' }, # range types -{ oid => '3904', descr => 'range of integers', +{ oid => '3904', array_type_oid => '3905', descr => 'range of integers', typname => 'int4range', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_int4range', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3905', - typname => '_int4range', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int4range', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3906', descr => 'range of numerics', +{ oid => '3906', array_type_oid => '3907', descr => 'range of numerics', typname => 'numrange', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_numrange', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3907', - typname => '_numrange', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'numrange', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3908', descr => 'range of timestamps without time zone', +{ oid => '3908', array_type_oid => '3909', + descr => 'range of timestamps without time zone', typname => 'tsrange', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_tsrange', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '3909', - typname => '_tsrange', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tsrange', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '3910', descr => 'range of timestamps with time zone', +{ oid => '3910', array_type_oid => '3911', + descr => 'range of timestamps with time zone', typname => 'tstzrange', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_tstzrange', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '3911', - typname => '_tstzrange', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'tstzrange', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '3912', descr => 'range of dates', +{ oid => '3912', array_type_oid => '3913', descr => 'range of dates', typname => 'daterange', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_daterange', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3913', - typname => '_daterange', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'daterange', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'i', typstorage => 'x' }, -{ oid => '3926', descr => 'range of bigints', +{ oid => '3926', array_type_oid => '3927', descr => 'range of bigints', typname => 'int8range', typlen => '-1', typbyval => 'f', typtype => 'r', - typcategory => 'R', typarray => '_int8range', typinput => 'range_in', - typoutput => 'range_out', typreceive => 'range_recv', typsend => 'range_send', + typcategory => 'R', typinput => 'range_in', typoutput => 'range_out', + typreceive => 'range_recv', typsend => 'range_send', typanalyze => 'range_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '3927', - typname => '_int8range', typlen => '-1', typbyval => 'f', typcategory => 'A', - typelem => 'int8range', typinput => 'array_in', typoutput => 'array_out', - typreceive => 'array_recv', typsend => 'array_send', - typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, # pseudo-types # types with typtype='p' represent various special cases in the type system. @@ -854,87 +495,102 @@ # but there is now support for it in records and arrays. Perhaps we should # just treat it as a regular base type? -{ oid => '2249', +{ oid => '2249', descr => 'pseudo-type representing any composite type', typname => 'record', typlen => '-1', typbyval => 'f', typtype => 'p', typcategory => 'P', typarray => '_record', typinput => 'record_in', typoutput => 'record_out', typreceive => 'record_recv', typsend => 'record_send', typalign => 'd', typstorage => 'x' }, +# Arrays of records have typcategory P, so they can't be autogenerated. { oid => '2287', typname => '_record', typlen => '-1', typbyval => 'f', typtype => 'p', typcategory => 'P', typelem => 'record', typinput => 'array_in', typoutput => 'array_out', typreceive => 'array_recv', typsend => 'array_send', typanalyze => 'array_typanalyze', typalign => 'd', typstorage => 'x' }, -{ oid => '2275', +{ oid => '2275', array_type_oid => '1263', descr => 'C-style string', typname => 'cstring', typlen => '-2', typbyval => 'f', typtype => 'p', - typcategory => 'P', typarray => '_cstring', typinput => 'cstring_in', - typoutput => 'cstring_out', typreceive => 'cstring_recv', - typsend => 'cstring_send', typalign => 'c' }, -{ oid => '2276', + typcategory => 'P', typinput => 'cstring_in', typoutput => 'cstring_out', + typreceive => 'cstring_recv', typsend => 'cstring_send', typalign => 'c' }, +{ oid => '2276', descr => 'pseudo-type representing any type', typname => 'any', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'any_in', typoutput => 'any_out', typreceive => '-', typsend => '-', typalign => 'i' }, -{ oid => '2277', +{ oid => '2277', descr => 'pseudo-type representing a polymorphic array type', typname => 'anyarray', typlen => '-1', typbyval => 'f', typtype => 'p', typcategory => 'P', typinput => 'anyarray_in', typoutput => 'anyarray_out', typreceive => 'anyarray_recv', typsend => 'anyarray_send', typalign => 'd', typstorage => 'x' }, { oid => '2278', + descr => 'pseudo-type for the result of a function with no real result', typname => 'void', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'void_in', typoutput => 'void_out', typreceive => 'void_recv', typsend => 'void_send', typalign => 'i' }, -{ oid => '2279', +{ oid => '2279', descr => 'pseudo-type for the result of a trigger function', typname => 'trigger', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'trigger_in', typoutput => 'trigger_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '3838', oid_symbol => 'EVTTRIGGEROID', + descr => 'pseudo-type for the result of an event trigger function', typname => 'event_trigger', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'event_trigger_in', typoutput => 'event_trigger_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '2280', + descr => 'pseudo-type for the result of a language handler function', typname => 'language_handler', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'language_handler_in', typoutput => 'language_handler_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '2281', + descr => 'pseudo-type representing an internal data structure', typname => 'internal', typlen => 'SIZEOF_POINTER', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'internal_in', typoutput => 'internal_out', typreceive => '-', typsend => '-', typalign => 'ALIGNOF_POINTER' }, -{ oid => '2282', +{ oid => '2282', descr => 'obsolete, deprecated pseudo-type', typname => 'opaque', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'opaque_in', typoutput => 'opaque_out', typreceive => '-', typsend => '-', typalign => 'i' }, -{ oid => '2283', +{ oid => '2283', descr => 'pseudo-type representing a polymorphic base type', typname => 'anyelement', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'anyelement_in', typoutput => 'anyelement_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '2776', + descr => 'pseudo-type representing a polymorphic base type that is not an array', typname => 'anynonarray', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'anynonarray_in', typoutput => 'anynonarray_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '3500', + descr => 'pseudo-type representing a polymorphic base type that is an enum', typname => 'anyenum', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'anyenum_in', typoutput => 'anyenum_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '3115', + descr => 'pseudo-type for the result of an FDW handler function', typname => 'fdw_handler', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'fdw_handler_in', typoutput => 'fdw_handler_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '325', + descr => 'pseudo-type for the result of an index AM handler function', typname => 'index_am_handler', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'index_am_handler_in', typoutput => 'index_am_handler_out', typreceive => '-', typsend => '-', typalign => 'i' }, { oid => '3310', + descr => 'pseudo-type for the result of a tablesample method function', typname => 'tsm_handler', typlen => '4', typbyval => 't', typtype => 'p', typcategory => 'P', typinput => 'tsm_handler_in', typoutput => 'tsm_handler_out', typreceive => '-', typsend => '-', typalign => 'i' }, +{ oid => '269', + typname => 'table_am_handler', typlen => '4', typbyval => 't', typtype => 'p', + typcategory => 'P', typinput => 'table_am_handler_in', + typoutput => 'table_am_handler_out', typreceive => '-', typsend => '-', + typalign => 'i' }, { oid => '3831', + descr => 'pseudo-type representing a polymorphic base type that is a range', typname => 'anyrange', typlen => '-1', typbyval => 'f', typtype => 'p', typcategory => 'P', typinput => 'anyrange_in', typoutput => 'anyrange_out', typreceive => '-', typsend => '-', typalign => 'd', typstorage => 'x' }, diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 8f301db91c5..2a584b4b130 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * pg_type.h - * definition of the system "type" relation (pg_type) + * definition of the "type" system catalog (pg_type) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_type.h @@ -36,6 +36,8 @@ */ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelation_Rowtype_Id) BKI_SCHEMA_MACRO { + Oid oid; /* oid */ + /* type name */ NameData typname; @@ -52,17 +54,17 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * "varlena" type (one that has a length word), -2 to indicate a * null-terminated C string. */ - int16 typlen; + int16 typlen BKI_ARRAY_DEFAULT(-1); /* * typbyval determines whether internal Postgres routines pass a value of * this type by value or by reference. typbyval had better be false if * the length is not 1, 2, or 4 (or 8 on 8-byte-Datum machines). * Variable-length types are always passed by reference. Note that - * typbyval can be false even if the length would allow pass-by-value; - * this is currently true for type float4, for example. + * typbyval can be false even if the length would allow pass-by-value; for + * example, type macaddr8 is pass-by-ref even when Datum is 8 bytes. */ - bool typbyval; + bool typbyval BKI_ARRAY_DEFAULT(f); /* * typtype is 'b' for a base type, 'c' for a composite type (e.g., a @@ -71,7 +73,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * * If typtype is 'c', typrelid is the OID of the class' entry in pg_class. */ - char typtype BKI_DEFAULT(b); + char typtype BKI_DEFAULT(b) BKI_ARRAY_DEFAULT(b); /* * typcategory and typispreferred help the parser distinguish preferred @@ -81,14 +83,15 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati */ /* arbitrary type classification */ - char typcategory; + char typcategory BKI_ARRAY_DEFAULT(A); /* is type "preferred" within its category? */ - bool typispreferred BKI_DEFAULT(f); + bool typispreferred BKI_DEFAULT(f) BKI_ARRAY_DEFAULT(f); /* * If typisdefined is false, the entry is only a placeholder (forward - * reference). We know the type name, but not yet anything else about it. + * reference). We know the type's name and owner, but not yet anything + * else about it. */ bool typisdefined BKI_DEFAULT(t); @@ -96,7 +99,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati char typdelim BKI_DEFAULT(','); /* associated pg_class OID if a composite type, else 0 */ - Oid typrelid BKI_DEFAULT(0); + Oid typrelid BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP(pg_class); /* * If typelem is not 0 then it identifies another row in pg_type. The @@ -115,19 +118,19 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * If there is a "true" array type having this type as element type, * typarray links to it. Zero if no associated "true" array type. */ - Oid typarray BKI_DEFAULT(0) BKI_LOOKUP(pg_type); + Oid typarray BKI_DEFAULT(0) BKI_ARRAY_DEFAULT(0) BKI_LOOKUP(pg_type); /* * I/O conversion procedures for the datatype. */ /* text format (required) */ - regproc typinput BKI_LOOKUP(pg_proc); - regproc typoutput BKI_LOOKUP(pg_proc); + regproc typinput BKI_ARRAY_DEFAULT(array_in) BKI_LOOKUP(pg_proc); + regproc typoutput BKI_ARRAY_DEFAULT(array_out) BKI_LOOKUP(pg_proc); /* binary format (optional) */ - regproc typreceive BKI_LOOKUP(pg_proc); - regproc typsend BKI_LOOKUP(pg_proc); + regproc typreceive BKI_ARRAY_DEFAULT(array_recv) BKI_LOOKUP(pg_proc); + regproc typsend BKI_ARRAY_DEFAULT(array_send) BKI_LOOKUP(pg_proc); /* * I/O functions for optional type modifiers. @@ -138,7 +141,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati /* * Custom ANALYZE procedure for the datatype (0 selects the default). */ - regproc typanalyze BKI_DEFAULT(-) BKI_LOOKUP(pg_proc); + regproc typanalyze BKI_DEFAULT(-) BKI_ARRAY_DEFAULT(array_typanalyze) BKI_LOOKUP(pg_proc); /* ---------------- * typalign is the alignment required when storing a value of this @@ -176,7 +179,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * 'm' MAIN like 'x' but try to keep in main tuple * ---------------- */ - char typstorage BKI_DEFAULT(p); + char typstorage BKI_DEFAULT(p) BKI_ARRAY_DEFAULT(x); /* * This flag represents a "NOT NULL" constraint against this datatype. @@ -208,10 +211,11 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati int32 typndims BKI_DEFAULT(0); /* - * Collation: 0 if type cannot use collations, DEFAULT_COLLATION_OID for - * collatable base types, possibly other OID for domains + * Collation: 0 if type cannot use collations, nonzero (typically + * DEFAULT_COLLATION_OID) for collatable base types, possibly some other + * OID for domains over collatable types */ - Oid typcollation BKI_DEFAULT(0); + Oid typcollation BKI_DEFAULT(0) BKI_LOOKUP(pg_collation); #ifdef CATALOG_VARLEN /* variable-length fields start here */ @@ -220,7 +224,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * a default expression for the type. Currently this is only used for * domains. */ - pg_node_tree typdefaultbin BKI_DEFAULT(_null_); + pg_node_tree typdefaultbin BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_); /* * typdefault is NULL if the type has no associated default value. If @@ -230,7 +234,7 @@ CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelati * external representation of the type's default value, which may be fed * to the type's input converter to produce a constant. */ - text typdefault BKI_DEFAULT(_null_); + text typdefault BKI_DEFAULT(_null_) BKI_ARRAY_DEFAULT(_null_); /* * Access permissions @@ -287,66 +291,57 @@ typedef FormData_pg_type *Form_pg_type; extern ObjectAddress TypeShellMake(const char *typeName, - Oid typeNamespace, - Oid ownerId); + Oid typeNamespace, + Oid ownerId); extern ObjectAddress TypeCreate(Oid newTypeOid, - const char *typeName, - Oid typeNamespace, - Oid relationOid, - char relationKind, - Oid ownerId, - int16 internalSize, - char typeType, - char typeCategory, - bool typePreferred, - char typDelim, - Oid inputProcedure, - Oid outputProcedure, - Oid receiveProcedure, - Oid sendProcedure, - Oid typmodinProcedure, - Oid typmodoutProcedure, - Oid analyzeProcedure, - Oid elementType, - bool isImplicitArray, - Oid arrayType, - Oid baseType, - const char *defaultTypeValue, - char *defaultTypeBin, - bool passedByValue, - char alignment, - char storage, - int32 typeMod, - int32 typNDims, - bool typeNotNull, - Oid typeCollation); - -extern void GenerateTypeDependencies(Oid typeNamespace, - Oid typeObjectId, - Oid relationOid, - char relationKind, - Oid owner, - Oid inputProcedure, - Oid outputProcedure, - Oid receiveProcedure, - Oid sendProcedure, - Oid typmodinProcedure, - Oid typmodoutProcedure, - Oid analyzeProcedure, - Oid elementType, - bool isImplicitArray, - Oid baseType, - Oid typeCollation, - Node *defaultExpr, - bool rebuild); + const char *typeName, + Oid typeNamespace, + Oid relationOid, + char relationKind, + Oid ownerId, + int16 internalSize, + char typeType, + char typeCategory, + bool typePreferred, + char typDelim, + Oid inputProcedure, + Oid outputProcedure, + Oid receiveProcedure, + Oid sendProcedure, + Oid typmodinProcedure, + Oid typmodoutProcedure, + Oid analyzeProcedure, + Oid elementType, + bool isImplicitArray, + Oid arrayType, + Oid baseType, + const char *defaultTypeValue, + char *defaultTypeBin, + bool passedByValue, + char alignment, + char storage, + int32 typeMod, + int32 typNDims, + bool typeNotNull, + Oid typeCollation); + +extern void GenerateTypeDependencies(Oid typeObjectId, + Form_pg_type typeForm, + Node *defaultExpr, + void *typacl, + char relationKind, /* only for relation + * rowtypes */ + bool isImplicitArray, + bool isDependentType, + bool rebuild); extern void RenameTypeInternal(Oid typeOid, const char *newTypeName, - Oid typeNamespace); + Oid typeNamespace); extern char *makeArrayTypeName(const char *typeName, Oid typeNamespace); extern bool moveArrayTypeName(Oid typeOid, const char *typeName, - Oid typeNamespace); + Oid typeNamespace); #endif /* PG_TYPE_H */ diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h index 6efbed0a9d4..e496828dca5 100644 --- a/src/include/catalog/pg_user_mapping.h +++ b/src/include/catalog/pg_user_mapping.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * pg_user_mapping.h - * definition of the system "user mapping" relation (pg_user_mapping) + * definition of the "user mapping" system catalog (pg_user_mapping) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/catalog/pg_user_mapping.h @@ -27,6 +27,8 @@ */ CATALOG(pg_user_mapping,1418,UserMappingRelationId) { + Oid oid; /* oid */ + Oid umuser; /* Id of the user, InvalidOid if PUBLIC is * wanted */ Oid umserver; /* server of this mapping */ diff --git a/src/include/catalog/reformat_dat_file.pl b/src/include/catalog/reformat_dat_file.pl old mode 100644 new mode 100755 index 038ba7bb05e..fd4dbad67ef --- a/src/include/catalog/reformat_dat_file.pl +++ b/src/include/catalog/reformat_dat_file.pl @@ -1,55 +1,51 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl #---------------------------------------------------------------------- # # reformat_dat_file.pl -# Perl script that reads in a catalog data file and writes out -# a functionally equivalent file in a standard format. +# Perl script that reads in catalog data file(s) and writes out +# functionally equivalent file(s) in a standard format. # -# Metadata entries (if any) come first, with normal attributes -# starting on the following line, in the same order they would be in -# the corresponding table. Comments and blank lines are preserved. +# In each entry of a reformatted file, metadata fields (if present) +# come first, with normal attributes starting on the following line, +# in the same order as the columns of the corresponding catalog. +# Comments and blank lines are preserved. # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/include/catalog/reformat_dat_file.pl # #---------------------------------------------------------------------- -use Catalog; - use strict; use warnings; -my @input_files; +use FindBin; +use Getopt::Long; + +# If you copy this script to somewhere other than src/include/catalog, +# you'll need to modify this "use lib" or provide a suitable -I switch. +use lib "$FindBin::RealBin/../../backend/catalog/"; +use Catalog; + +# Names of the metadata fields of a catalog entry. +# Note: oid is a normal column from a storage perspective, but it's more +# important than the rest, so it's listed first among the metadata fields. +# Note: line_number is also a metadata field, but we never write it out, +# so it's not listed here. +my @METADATA = + ('oid', 'oid_symbol', 'array_type_oid', 'descr', 'autogenerated'); + +# Process command line switches. my $output_path = ''; my $full_tuples = 0; -# Process command line switches. -while (@ARGV) -{ - my $arg = shift @ARGV; - if ($arg !~ /^-/) - { - push @input_files, $arg; - } - elsif ($arg =~ /^-o/) - { - $output_path = length($arg) > 2 ? substr($arg, 2) : shift @ARGV; - } - elsif ($arg eq '--full-tuples') - { - $full_tuples = 1; - } - else - { - usage(); - } -} +GetOptions( + 'output=s' => \$output_path, + 'full-tuples' => \$full_tuples) || usage(); # Sanity check arguments. -die "No input files.\n" - if !@input_files; +die "No input files.\n" unless @ARGV; # Make sure output_path ends in a slash. if ($output_path ne '' && substr($output_path, -1) ne '/') @@ -57,23 +53,20 @@ $output_path .= '/'; } -# Metadata of a catalog entry -my @METADATA = ('oid', 'oid_symbol', 'descr'); - # Read all the input files into internal data structures. # We pass data file names as arguments and then look for matching # headers to parse the schema from. my %catalogs; my %catalog_data; my @catnames; -foreach my $datfile (@input_files) +foreach my $datfile (@ARGV) { $datfile =~ /(.+)\.dat$/ or die "Input files need to be data (.dat) files.\n"; my $header = "$1.h"; die "There in no header file corresponding to $datfile" - if ! -e $header; + if !-e $header; my $catalog = Catalog::ParseHeader($header); my $catname = $catalog->{catname}; @@ -112,15 +105,19 @@ foreach my $column (@$schema) { my $attname = $column->{name}; - push @attnames, $attname; + + # We may have ordinary columns at the storage level that we still + # want to format as a special value. Exclude these from the column + # list so they are not written twice. + push @attnames, $attname + if !(grep { $_ eq $attname } @METADATA); } - # Overwrite .dat files in place, since they are under version control. + # Write output files to specified directory. my $datfile = "$output_path$catname.dat"; open my $dat, '>', $datfile or die "can't open $datfile: $!"; - # Write the data. foreach my $data (@{ $catalog_data{$catname} }) { @@ -138,6 +135,9 @@ if (!$full_tuples) { + # If it's an autogenerated entry, drop it completely. + next if $values{autogenerated}; + # Else, just drop any default/computed fields. strip_default_values(\%values, $schema, $catname); } @@ -158,10 +158,6 @@ print $dat " },\n"; } - # Strings -- handle accordingly or ignore. It was necessary to - # ignore bare commas during the initial data conversion. This - # should be a no-op now, but we may as well keep that behavior. - # Preserve blank lines. elsif ($data =~ /^\s*$/) { @@ -177,31 +173,44 @@ close $dat; } -# Leave values out if there is a matching default. +# Remove column values for which there is a matching default, +# or if the value can be computed from other columns. sub strip_default_values { my ($row, $schema, $catname) = @_; + # Delete values that match defaults. foreach my $column (@$schema) { my $attname = $column->{name}; + + # It's okay if we have no oid value, since it will be assigned + # automatically before bootstrap. die "strip_default_values: $catname.$attname undefined\n" - if ! defined $row->{$attname}; + if !defined $row->{$attname} and $attname ne 'oid'; - # Delete values that match defaults. if (defined $column->{default} and ($row->{$attname} eq $column->{default})) { delete $row->{$attname}; } + } - # Also delete pg_proc.pronargs, since that can be recomputed. - if ($catname eq 'pg_proc' && $attname eq 'pronargs' && - defined($row->{proargtypes})) - { - delete $row->{$attname}; - } + # Delete computed values. See AddDefaultValues() in Catalog.pm. + # Note: This must be done after deleting values matching defaults. + if ($catname eq 'pg_proc') + { + delete $row->{pronargs} if defined $row->{proargtypes}; + } + + # If a pg_type entry has an auto-generated array type, then its + # typarray field is a computed value too (see GenerateArrayTypes). + if ($catname eq 'pg_type') + { + delete $row->{typarray} if defined $row->{array_type_oid}; } + + return; } # Format the individual elements of a Perl hash into a valid string @@ -210,7 +219,7 @@ sub strip_default_values # data files. sub format_hash { - my $data = shift; + my $data = shift; my @orig_attnames = @_; # Copy attname to new array if it has a value, so we can determine @@ -228,7 +237,7 @@ sub format_hash my $char_count = 1; my $threshold; - my $hash_str = ''; + my $hash_str = ''; my $element_count = 0; foreach my $attname (@attnames) @@ -262,7 +271,7 @@ sub format_hash # Include a leading space in the key-value pair, since this will # always go after either a comma or an additional padding space on # the next line. - my $element = " $attname => '$value'"; + my $element = " $attname => '$value'"; my $element_length = length($element); # If adding the element to the current line would expand the line @@ -292,13 +301,12 @@ sub usage Usage: reformat_dat_file.pl [options] datafile... Options: - -o output path + --output PATH output directory (default '.') --full-tuples write out full tuples, including default values -Expects a list of .dat files as arguments. - -Make sure location of Catalog.pm is passed to the perl interpreter: -perl -I /path/to/Catalog.pm/ ... +Non-option arguments are the names of input .dat files. +Updated files are written to the output directory, +possibly overwriting the input files. EOM } diff --git a/src/include/catalog/renumber_oids.pl b/src/include/catalog/renumber_oids.pl new file mode 100755 index 00000000000..8a07340ba14 --- /dev/null +++ b/src/include/catalog/renumber_oids.pl @@ -0,0 +1,291 @@ +#!/usr/bin/perl +#---------------------------------------------------------------------- +# +# renumber_oids.pl +# Perl script that shifts a range of OIDs in the Postgres catalog data +# to a different range, skipping any OIDs that are already in use. +# +# Note: This does not reformat the .dat files, so you may want +# to run reformat_dat_file.pl afterwards. +# +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/include/catalog/renumber_oids.pl +# +#---------------------------------------------------------------------- + +use strict; +use warnings; + +use FindBin; +use Getopt::Long; + +# Must run in src/include/catalog +chdir $FindBin::RealBin or die "could not cd to $FindBin::RealBin: $!\n"; + +use lib "$FindBin::RealBin/../../backend/catalog/"; +use Catalog; + +# We'll need this number. +my $FirstGenbkiObjectId = + Catalog::FindDefinedSymbol('access/transam.h', '..', 'FirstGenbkiObjectId'); + +# Process command line switches. +my $output_path = ''; +my $first_mapped_oid = 0; +my $last_mapped_oid = $FirstGenbkiObjectId - 1; +my $target_oid = 0; + +GetOptions( + 'output=s' => \$output_path, + 'first-mapped-oid=i' => \$first_mapped_oid, + 'last-mapped-oid=i' => \$last_mapped_oid, + 'target-oid=i' => \$target_oid) || usage(); + +# Sanity check arguments. +die "Unexpected non-switch arguments.\n" if @ARGV; +die "--first-mapped-oid must be specified.\n" + if $first_mapped_oid <= 0; +die "Empty mapped OID range.\n" + if $last_mapped_oid < $first_mapped_oid; +die "--target-oid must be specified.\n" + if $target_oid <= 0; +die "--target-oid must not be within mapped OID range.\n" + if $target_oid >= $first_mapped_oid && $target_oid <= $last_mapped_oid; + +# Make sure output_path ends in a slash. +if ($output_path ne '' && substr($output_path, -1) ne '/') +{ + $output_path .= '/'; +} + +# Collect all the existing assigned OIDs (including those to be remapped). +my @header_files = (glob("pg_*.h"), qw(indexing.h toasting.h)); +my $oids = Catalog::FindAllOidsFromHeaders(@header_files); + +# Hash-ify the existing OIDs for convenient lookup. +my %oidhash; +@oidhash{@$oids} = undef; + +# Select new OIDs for existing OIDs in the mapped range. +# We do this first so that we preserve the ordering of the mapped OIDs +# (for reproducibility's sake), and so that if we fail due to running out +# of OID room, that happens before we've overwritten any files. +my %maphash; +my $next_oid = $target_oid; + +for ( + my $mapped_oid = $first_mapped_oid; + $mapped_oid <= $last_mapped_oid; + $mapped_oid++) +{ + next if !exists $oidhash{$mapped_oid}; + $next_oid++ + while ( + exists $oidhash{$next_oid} + || ( $next_oid >= $first_mapped_oid + && $next_oid <= $last_mapped_oid)); + die "Reached FirstGenbkiObjectId before assigning all OIDs.\n" + if $next_oid >= $FirstGenbkiObjectId; + $maphash{$mapped_oid} = $next_oid; + $next_oid++; +} + +die "There are no OIDs in the mapped range.\n" if $next_oid == $target_oid; + +# Read each .h file and write out modified data. +foreach my $input_file (@header_files) +{ + $input_file =~ /(\w+)\.h$/ + or die "Input file $input_file needs to be a .h file.\n"; + my $catname = $1; + + # Ignore generated *_d.h files. + next if $catname =~ /_d$/; + + open(my $ifd, '<', $input_file) || die "$input_file: $!"; + + # Write output files to specified directory. + # Use a .tmp suffix, then rename into place, in case we're overwriting. + my $output_file = "$output_path$catname.h"; + my $tmp_output_file = "$output_file.tmp"; + open my $ofd, '>', $tmp_output_file + or die "can't open $tmp_output_file: $!"; + my $changed = 0; + + # Scan the input file. + while (<$ifd>) + { + my $line = $_; + + # Check for OID-defining macros that Catalog::ParseHeader knows about, + # and update OIDs as needed. + if ($line =~ m/^(DECLARE_TOAST\(\s*\w+,\s*)(\d+)(,\s*)(\d+)\)/) + { + my $oid2 = $2; + my $oid4 = $4; + if (exists $maphash{$oid2}) + { + $oid2 = $maphash{$oid2}; + my $repl = $1 . $oid2 . $3 . $oid4 . ")"; + $line =~ s/^DECLARE_TOAST\(\s*\w+,\s*\d+,\s*\d+\)/$repl/; + $changed = 1; + } + if (exists $maphash{$oid4}) + { + $oid4 = $maphash{$oid4}; + my $repl = $1 . $oid2 . $3 . $oid4 . ")"; + $line =~ s/^DECLARE_TOAST\(\s*\w+,\s*\d+,\s*\d+\)/$repl/; + $changed = 1; + } + } + elsif ( + $line =~ m/^(DECLARE_(UNIQUE_)?INDEX\(\s*\w+,\s*)(\d+)(,\s*.+)\)/) + { + if (exists $maphash{$3}) + { + my $repl = $1 . $maphash{$3} . $4 . ")"; + $line =~ + s/^DECLARE_(UNIQUE_)?INDEX\(\s*\w+,\s*\d+,\s*.+\)/$repl/; + $changed = 1; + } + } + elsif ($line =~ m/^CATALOG\((\w+),(\d+),(\w+)\)/) + { + if (exists $maphash{$2}) + { + my $repl = + "CATALOG(" . $1 . "," . $maphash{$2} . "," . $3 . ")"; + $line =~ s/^CATALOG\(\w+,\d+,\w+\)/$repl/; + $changed = 1; + } + + if ($line =~ m/BKI_ROWTYPE_OID\((\d+),(\w+)\)/) + { + if (exists $maphash{$1}) + { + my $repl = + "BKI_ROWTYPE_OID(" . $maphash{$1} . "," . $2 . ")"; + $line =~ s/BKI_ROWTYPE_OID\(\d+,\w+\)/$repl/; + $changed = 1; + } + } + } + + # In indexing.h and toasting.h only, check for #define SYM nnnn, + # and replace if within mapped range. + elsif ($line =~ m/^(\s*#\s*define\s+\w+\s+)(\d+)\b/) + { + if (($catname eq 'indexing' || $catname eq 'toasting') + && exists $maphash{$2}) + { + my $repl = $1 . $maphash{$2}; + $line =~ s/^\s*#\s*define\s+\w+\s+\d+\b/$repl/; + $changed = 1; + } + } + + print $ofd $line; + } + + close $ifd; + close $ofd; + + # Avoid updating files if we didn't change them. + if ($changed || $output_path ne '') + { + rename $tmp_output_file, $output_file + or die "can't rename $tmp_output_file to $output_file: $!"; + } + else + { + unlink $tmp_output_file + or die "can't unlink $tmp_output_file: $!"; + } +} + +# Likewise, read each .dat file and write out modified data. +foreach my $input_file (glob("pg_*.dat")) +{ + $input_file =~ /(\w+)\.dat$/ + or die "Input file $input_file needs to be a .dat file.\n"; + my $catname = $1; + + open(my $ifd, '<', $input_file) || die "$input_file: $!"; + + # Write output files to specified directory. + # Use a .tmp suffix, then rename into place, in case we're overwriting. + my $output_file = "$output_path$catname.dat"; + my $tmp_output_file = "$output_file.tmp"; + open my $ofd, '>', $tmp_output_file + or die "can't open $tmp_output_file: $!"; + my $changed = 0; + + # Scan the input file. + while (<$ifd>) + { + my $line = $_; + + # Check for oid => 'nnnn', and replace if within mapped range. + if ($line =~ m/\b(oid\s*=>\s*)'(\d+)'/) + { + if (exists $maphash{$2}) + { + my $repl = $1 . "'" . $maphash{$2} . "'"; + $line =~ s/\boid\s*=>\s*'\d+'/$repl/; + $changed = 1; + } + } + + # Likewise for array_type_oid. + if ($line =~ m/\b(array_type_oid\s*=>\s*)'(\d+)'/) + { + if (exists $maphash{$2}) + { + my $repl = $1 . "'" . $maphash{$2} . "'"; + $line =~ s/\barray_type_oid\s*=>\s*'\d+'/$repl/; + $changed = 1; + } + } + + print $ofd $line; + } + + close $ifd; + close $ofd; + + # Avoid updating files if we didn't change them. + if ($changed || $output_path ne '') + { + rename $tmp_output_file, $output_file + or die "can't rename $tmp_output_file to $output_file: $!"; + } + else + { + unlink $tmp_output_file + or die "can't unlink $tmp_output_file: $!"; + } +} + +sub usage +{ + my $last = $FirstGenbkiObjectId - 1; + die < *'\''\([0-9][0-9]*\)'\''.*$/\1/p' \ - -e 's/^CATALOG([^,]*, *\([0-9][0-9]*\).*BKI_ROWTYPE_OID(\([0-9][0-9]*\),.*$/\1,\2/p' \ - -e 's/^CATALOG([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_INDEX([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_UNIQUE_INDEX([^,]*, *\([0-9][0-9]*\).*$/\1/p' \ - -e 's/^DECLARE_TOAST([^,]*, *\([0-9][0-9]*\), *\([0-9][0-9]*\).*$/\1,\2/p' | \ -tr ',' '\n' | \ -sort -n | \ -uniq | \ -$AWK ' -BEGIN { - last = 0; -} -/^[0-9]/ { - if ($1 > last + 1) { - if ($1 > last + 2) { - print last + 1, "-", $1 - 1; - } else { - print last + 1; +# Must run in src/include/catalog +use FindBin; +chdir $FindBin::RealBin or die "could not cd to $FindBin::RealBin: $!\n"; + +use lib "$FindBin::RealBin/../../backend/catalog/"; +use Catalog; + +my @input_files = (glob("pg_*.h"), qw(indexing.h toasting.h)); + +my $oids = Catalog::FindAllOidsFromHeaders(@input_files); + +# Also push FirstGenbkiObjectId to serve as a terminator for the last gap. +my $FirstGenbkiObjectId = + Catalog::FindDefinedSymbol('access/transam.h', '..', 'FirstGenbkiObjectId'); +push @{$oids}, $FirstGenbkiObjectId; + +my $prev_oid = 0; +my @sortedoids = sort { $a <=> $b } @{$oids}; +foreach my $oid (@sortedoids) +{ + if ($oid > $prev_oid + 1) + { + if ($oid > $prev_oid + 2) + { + printf "%d - %d\n", $prev_oid + 1, $oid - 1; + } + else + { + printf "%d\n", $prev_oid + 1; } } - last = $1; + $prev_oid = $oid; } -END { - print last + 1, "-", ENVIRON["FIRSTOBJECTID"]-1; -}' + +my $suggestion; +do +{ + $suggestion = int(8000 + rand(2000)); +} while (grep(/^$suggestion$/, @{$oids})); + +my $navailable = 0; +foreach my $oid (@sortedoids) +{ + if ($oid > $suggestion) + { + $navailable = $oid - $suggestion; + last; + } +} + +printf "Patches should use a more-or-less consecutive range of OIDs.\n"; +printf + "Best practice is to start with a random choice in the range 8000-9999.\n"; +printf + "Suggested random unused OID: $suggestion ($navailable consecutive OID(s) available starting here)\n"; diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h index 402a4b2d582..5c1a13d8d7b 100644 --- a/src/include/commands/alter.h +++ b/src/include/commands/alter.h @@ -4,7 +4,7 @@ * prototypes for commands/alter.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/alter.h @@ -22,14 +22,14 @@ extern ObjectAddress ExecRenameStmt(RenameStmt *stmt); extern ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, - ObjectAddress *refAddress); + ObjectAddress *refAddress); extern ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, - ObjectAddress *oldSchemaAddr); -extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, - ObjectAddresses *objsMoved); + ObjectAddress *oldSchemaAddr); +extern Oid AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid, + ObjectAddresses *objsMoved); extern ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt); extern void AlterObjectOwner_internal(Relation catalog, Oid objectId, - Oid new_ownerId); + Oid new_ownerId); #endif /* ALTER_H */ diff --git a/src/include/commands/async.h b/src/include/commands/async.h index d5868c42a02..c295dc67c64 100644 --- a/src/include/commands/async.h +++ b/src/include/commands/async.h @@ -3,7 +3,7 @@ * async.h * Asynchronous notification: NOTIFY, LISTEN, UNLISTEN * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/async.h @@ -15,8 +15,6 @@ #include -#include "fmgr.h" - /* * The number of SLRU page buffers we use for the notification queue. */ @@ -29,8 +27,8 @@ extern Size AsyncShmemSize(void); extern void AsyncShmemInit(void); extern void NotifyMyFrontEnd(const char *channel, - const char *payload, - int32 srcPid); + const char *payload, + int32 srcPid); /* notify-related SQL statements */ extern void Async_Notify(const char *channel, const char *payload); diff --git a/src/include/commands/cluster.h b/src/include/commands/cluster.h index b338cb10988..11b7cdf4ee7 100644 --- a/src/include/commands/cluster.h +++ b/src/include/commands/cluster.h @@ -3,7 +3,7 @@ * cluster.h * header file for postgres cluster command stuff * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/commands/cluster.h @@ -19,21 +19,20 @@ extern void cluster(ClusterStmt *stmt, bool isTopLevel); -extern void cluster_rel(Oid tableOid, Oid indexOid, bool recheck, - bool verbose); +extern void cluster_rel(Oid tableOid, Oid indexOid, int options); extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid, - bool recheck, LOCKMODE lockmode); + bool recheck, LOCKMODE lockmode); extern void mark_index_clustered(Relation rel, Oid indexOid, bool is_internal); -extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, - LOCKMODE lockmode); +extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence, + LOCKMODE lockmode); extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap, - bool is_system_catalog, - bool swap_toast_by_content, - bool check_constraints, - bool is_internal, - TransactionId frozenXid, - MultiXactId minMulti, - char newrelpersistence); + bool is_system_catalog, + bool swap_toast_by_content, + bool check_constraints, + bool is_internal, + TransactionId frozenXid, + MultiXactId minMulti, + char newrelpersistence); #endif /* CLUSTER_H */ diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h index 9b0f00a997e..e25f5d50b32 100644 --- a/src/include/commands/collationcmds.h +++ b/src/include/commands/collationcmds.h @@ -4,7 +4,7 @@ * prototypes for collationcmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/collationcmds.h diff --git a/src/include/commands/comment.h b/src/include/commands/comment.h index 411433f862c..d349159f05c 100644 --- a/src/include/commands/comment.h +++ b/src/include/commands/comment.h @@ -7,7 +7,7 @@ * * Prototypes for functions in commands/comment.c * - * Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Copyright (c) 1999-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 9fd40cb6f04..c38cab8076e 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -4,7 +4,7 @@ * prototypes for conversioncmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/conversioncmds.h diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h index f393e7e73d7..bbe0105d77b 100644 --- a/src/include/commands/copy.h +++ b/src/include/commands/copy.h @@ -4,7 +4,7 @@ * Definitions for using the POSTGRES copy command. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/copy.h @@ -24,17 +24,17 @@ typedef struct CopyStateData *CopyState; typedef int (*copy_data_source_cb) (void *outbuf, int minread, int maxread); extern void DoCopy(ParseState *state, const CopyStmt *stmt, - int stmt_location, int stmt_len, - uint64 *processed); + int stmt_location, int stmt_len, + uint64 *processed); extern void ProcessCopyOptions(ParseState *pstate, CopyState cstate, bool is_from, List *options); extern CopyState BeginCopyFrom(ParseState *pstate, Relation rel, const char *filename, - bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options); + bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options); extern void EndCopyFrom(CopyState cstate); extern bool NextCopyFrom(CopyState cstate, ExprContext *econtext, - Datum *values, bool *nulls, Oid *tupleOid); + Datum *values, bool *nulls); extern bool NextCopyFromRawFields(CopyState cstate, - char ***fields, int *nfields); + char ***fields, int *nfields); extern void CopyFromErrorCallback(void *arg); extern uint64 CopyFrom(CopyState cstate); diff --git a/src/include/commands/createas.h b/src/include/commands/createas.h index 03ba21ded83..abd0525290d 100644 --- a/src/include/commands/createas.h +++ b/src/include/commands/createas.h @@ -4,7 +4,7 @@ * prototypes for createas.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/createas.h @@ -22,7 +22,7 @@ extern ObjectAddress ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString, - ParamListInfo params, QueryEnvironment *queryEnv, char *completionTag); + ParamListInfo params, QueryEnvironment *queryEnv, char *completionTag); extern int GetIntoRelEFlags(IntoClause *intoClause); diff --git a/src/include/commands/dbcommands.h b/src/include/commands/dbcommands.h index 677c7fc5fcb..154c8157ee2 100644 --- a/src/include/commands/dbcommands.h +++ b/src/include/commands/dbcommands.h @@ -4,7 +4,7 @@ * Database management commands (create/drop database). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/dbcommands.h @@ -26,7 +26,7 @@ extern Oid AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTop extern Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt); extern ObjectAddress AlterDatabaseOwner(const char *dbname, Oid newOwnerId); -extern Oid get_database_oid(const char *dbname, bool missingok); +extern Oid get_database_oid(const char *dbname, bool missing_ok); extern char *get_database_name(Oid dbid); extern void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype); diff --git a/src/include/commands/dbcommands_xlog.h b/src/include/commands/dbcommands_xlog.h index 83048d6c5bc..46be8a615ac 100644 --- a/src/include/commands/dbcommands_xlog.h +++ b/src/include/commands/dbcommands_xlog.h @@ -4,7 +4,7 @@ * Database resource manager XLOG definitions (create/drop database). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/dbcommands_xlog.h diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 8fc9e424cfc..1dc6dc2ca04 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -4,7 +4,7 @@ * POSTGRES define and remove utility definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/defrem.h @@ -25,30 +25,31 @@ extern void RemoveObjects(DropStmt *stmt); /* commands/indexcmds.c */ extern ObjectAddress DefineIndex(Oid relationId, - IndexStmt *stmt, - Oid indexRelationId, - Oid parentIndexId, - Oid parentConstraintId, - bool is_alter_table, - bool check_rights, - bool check_not_in_use, - bool skip_build, - bool quiet); -extern void ReindexIndex(RangeVar *indexRelation, int options); -extern Oid ReindexTable(RangeVar *relation, int options); + IndexStmt *stmt, + Oid indexRelationId, + Oid parentIndexId, + Oid parentConstraintId, + bool is_alter_table, + bool check_rights, + bool check_not_in_use, + bool skip_build, + bool quiet); +extern void ReindexIndex(RangeVar *indexRelation, int options, bool concurrent); +extern Oid ReindexTable(RangeVar *relation, int options, bool concurrent); extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, - int options); + int options, bool concurrent); extern char *makeObjectName(const char *name1, const char *name2, - const char *label); + const char *label); extern char *ChooseRelationName(const char *name1, const char *name2, - const char *label, Oid namespaceid); + const char *label, Oid namespaceid, + bool isconstraint); extern bool CheckIndexCompatible(Oid oldId, - const char *accessMethodName, - List *attributeList, - List *exclusionOpNames); + const char *accessMethodName, + List *attributeList, + List *exclusionOpNames); extern Oid GetDefaultOpClass(Oid type_id, Oid am_id); -extern Oid ResolveOpClass(List *opclass, Oid attrType, - const char *accessMethodName, Oid accessMethodId); +extern Oid ResolveOpClass(List *opclass, Oid attrType, + const char *accessMethodName, Oid accessMethodId); /* commands/functioncmds.c */ extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt); @@ -61,22 +62,23 @@ extern void DropCastById(Oid castOid); extern ObjectAddress CreateTransform(CreateTransformStmt *stmt); extern void DropTransformById(Oid transformOid); extern void IsThereFunctionInNamespace(const char *proname, int pronargs, - oidvector *proargtypes, Oid nspOid); + oidvector *proargtypes, Oid nspOid); extern void ExecuteDoStmt(DoStmt *stmt, bool atomic); extern void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest); +extern TupleDesc CallStmtResultDesc(CallStmt *stmt); extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); extern Oid get_transform_oid(Oid type_id, Oid lang_id, bool missing_ok); extern void interpret_function_parameter_list(ParseState *pstate, - List *parameters, - Oid languageOid, - ObjectType objtype, - oidvector **parameterTypes, - ArrayType **allParameterTypes, - ArrayType **parameterModes, - ArrayType **parameterNames, - List **parameterDefaults, - Oid *variadicArgType, - Oid *requiredResultType); + List *parameters, + Oid languageOid, + ObjectType objtype, + oidvector **parameterTypes, + ArrayType **allParameterTypes, + ArrayType **parameterModes, + ArrayType **parameterNames, + List **parameterDefaults, + Oid *variadicArgType, + Oid *requiredResultType); /* commands/operatorcmds.c */ extern ObjectAddress DefineOperator(List *names, List *parameters); @@ -85,14 +87,15 @@ extern ObjectAddress AlterOperator(AlterOperatorStmt *stmt); /* commands/statscmds.c */ extern ObjectAddress CreateStatistics(CreateStatsStmt *stmt); +extern ObjectAddress AlterStatistics(AlterStatsStmt *stmt); extern void RemoveStatisticsById(Oid statsOid); extern void UpdateStatisticsForTypeChange(Oid statsOid, - Oid relationOid, int attnum, - Oid oldColumnType, Oid newColumnType); + Oid relationOid, int attnum, + Oid oldColumnType, Oid newColumnType); /* commands/aggregatecmds.c */ extern ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, - List *parameters); + List *parameters, bool replace); /* commands/opclasscmds.c */ extern ObjectAddress DefineOpClass(CreateOpClassStmt *stmt); @@ -103,9 +106,9 @@ extern void RemoveOpFamilyById(Oid opfamilyOid); extern void RemoveAmOpEntryById(Oid entryOid); extern void RemoveAmProcEntryById(Oid entryOid); extern void IsThereOpClassInNamespace(const char *opcname, Oid opcmethod, - Oid opcnamespace); + Oid opcnamespace); extern void IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod, - Oid opfnamespace); + Oid opfnamespace); extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); @@ -121,7 +124,7 @@ extern ObjectAddress DefineTSTemplate(List *names, List *parameters); extern void RemoveTSTemplateById(Oid tmplId); extern ObjectAddress DefineTSConfiguration(List *names, List *parameters, - ObjectAddress *copied); + ObjectAddress *copied); extern void RemoveTSConfigurationById(Oid cfgId); extern ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt); @@ -146,14 +149,15 @@ extern void RemoveUserMappingById(Oid umId); extern void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid); extern void ImportForeignSchema(ImportForeignSchemaStmt *stmt); extern Datum transformGenericOptions(Oid catalogId, - Datum oldOptions, - List *options, - Oid fdwvalidator); + Datum oldOptions, + List *options, + Oid fdwvalidator); /* commands/amcmds.c */ extern ObjectAddress CreateAccessMethod(CreateAmStmt *stmt); extern void RemoveAccessMethodById(Oid amOid); extern Oid get_index_am_oid(const char *amname, bool missing_ok); +extern Oid get_table_am_oid(const char *amname, bool missing_ok); extern Oid get_am_oid(const char *amname, bool missing_ok); extern char *get_am_name(Oid amOid); diff --git a/src/include/commands/discard.h b/src/include/commands/discard.h index bbec7ef6efb..dbd27bf202f 100644 --- a/src/include/commands/discard.h +++ b/src/include/commands/discard.h @@ -4,7 +4,7 @@ * prototypes for discard.c. * * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/commands/discard.h * diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h index 0e1959462eb..575e9243e51 100644 --- a/src/include/commands/event_trigger.h +++ b/src/include/commands/event_trigger.h @@ -3,7 +3,7 @@ * event_trigger.h * Declarations for command trigger handling. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/event_trigger.h @@ -31,7 +31,6 @@ typedef struct EventTriggerData #define AT_REWRITE_ALTER_PERSISTENCE 0x01 #define AT_REWRITE_DEFAULT_VAL 0x02 #define AT_REWRITE_COLUMN_REWRITE 0x04 -#define AT_REWRITE_ALTER_OID 0x08 /* * EventTriggerData is the node type that is passed as fmgr "context" info @@ -41,7 +40,7 @@ typedef struct EventTriggerData ((fcinfo)->context != NULL && IsA((fcinfo)->context, EventTriggerData)) extern Oid CreateEventTrigger(CreateEventTrigStmt *stmt); -extern void RemoveEventTriggerById(Oid ctrigOid); +extern void RemoveEventTriggerById(Oid trigOid); extern Oid get_event_trigger_oid(const char *trigname, bool missing_ok); extern Oid AlterEventTrigger(AlterEventTrigStmt *stmt); @@ -59,30 +58,30 @@ extern bool EventTriggerBeginCompleteQuery(void); extern void EventTriggerEndCompleteQuery(void); extern bool trackDroppedObjectsNeeded(void); extern void EventTriggerSQLDropAddObject(const ObjectAddress *object, - bool original, bool normal); + bool original, bool normal); extern void EventTriggerInhibitCommandCollection(void); extern void EventTriggerUndoInhibitCommandCollection(void); extern void EventTriggerCollectSimpleCommand(ObjectAddress address, - ObjectAddress secondaryObject, - Node *parsetree); + ObjectAddress secondaryObject, + Node *parsetree); extern void EventTriggerAlterTableStart(Node *parsetree); extern void EventTriggerAlterTableRelid(Oid objectId); extern void EventTriggerCollectAlterTableSubcmd(Node *subcmd, - ObjectAddress address); + ObjectAddress address); extern void EventTriggerAlterTableEnd(void); extern void EventTriggerCollectGrant(InternalGrant *istmt); extern void EventTriggerCollectAlterOpFam(AlterOpFamilyStmt *stmt, - Oid opfamoid, List *operators, - List *procedures); + Oid opfamoid, List *operators, + List *procedures); extern void EventTriggerCollectCreateOpClass(CreateOpClassStmt *stmt, - Oid opcoid, List *operators, - List *procedures); + Oid opcoid, List *operators, + List *procedures); extern void EventTriggerCollectAlterTSConfig(AlterTSConfigurationStmt *stmt, - Oid cfgId, Oid *dictIds, int ndicts); + Oid cfgId, Oid *dictIds, int ndicts); extern void EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt); #endif /* EVENT_TRIGGER_H */ diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h index 9b75baae6e6..8639891c164 100644 --- a/src/include/commands/explain.h +++ b/src/include/commands/explain.h @@ -3,7 +3,7 @@ * explain.h * prototypes for explain.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994-5, Regents of the University of California * * src/include/commands/explain.h @@ -35,6 +35,7 @@ typedef struct ExplainState bool buffers; /* print buffer usage */ bool timing; /* print detailed node timing */ bool summary; /* print total planning and execution timing */ + bool settings; /* print modified settings */ ExplainFormat format; /* output format */ /* state for output formatting --- not reset for each new plan tree */ int indent; /* current indentation level */ @@ -63,25 +64,27 @@ extern PGDLLIMPORT explain_get_index_name_hook_type explain_get_index_name_hook; extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, - ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest); + ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest); extern ExplainState *NewExplainState(void); extern TupleDesc ExplainResultDesc(ExplainStmt *stmt); extern void ExplainOneUtility(Node *utilityStmt, IntoClause *into, - ExplainState *es, const char *queryString, - ParamListInfo params, QueryEnvironment *queryEnv); + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv); extern void ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, - ExplainState *es, const char *queryString, - ParamListInfo params, QueryEnvironment *queryEnv, - const instr_time *planduration); + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv, + const instr_time *planduration); extern void ExplainPrintPlan(ExplainState *es, QueryDesc *queryDesc); extern void ExplainPrintTriggers(ExplainState *es, QueryDesc *queryDesc); -extern void ExplainPrintJIT(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainPrintJITSummary(ExplainState *es, QueryDesc *queryDesc); +extern void ExplainPrintJIT(ExplainState *es, int jit_flags, + struct JitInstrumentation *jit_instr, int worker_num); extern void ExplainQueryText(ExplainState *es, QueryDesc *queryDesc); @@ -90,21 +93,21 @@ extern void ExplainEndOutput(ExplainState *es); extern void ExplainSeparatePlans(ExplainState *es); extern void ExplainPropertyList(const char *qlabel, List *data, - ExplainState *es); + ExplainState *es); extern void ExplainPropertyListNested(const char *qlabel, List *data, - ExplainState *es); + ExplainState *es); extern void ExplainPropertyText(const char *qlabel, const char *value, - ExplainState *es); + ExplainState *es); extern void ExplainPropertyInteger(const char *qlabel, const char *unit, - int64 value, ExplainState *es); + int64 value, ExplainState *es); extern void ExplainPropertyFloat(const char *qlabel, const char *unit, - double value, int ndigits, ExplainState *es); + double value, int ndigits, ExplainState *es); extern void ExplainPropertyBool(const char *qlabel, bool value, - ExplainState *es); + ExplainState *es); extern void ExplainOpenGroup(const char *objtype, const char *labelname, - bool labeled, ExplainState *es); + bool labeled, ExplainState *es); extern void ExplainCloseGroup(const char *objtype, const char *labelname, - bool labeled, ExplainState *es); + bool labeled, ExplainState *es); #endif /* EXPLAIN_H */ diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h index 068a3754aac..02fc17d7c09 100644 --- a/src/include/commands/extension.h +++ b/src/include/commands/extension.h @@ -4,7 +4,7 @@ * Extension management commands (create/drop extension). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/extension.h @@ -36,21 +36,19 @@ extern ObjectAddress CreateExtension(ParseState *pstate, CreateExtensionStmt *st extern void RemoveExtensionById(Oid extId); extern ObjectAddress InsertExtensionTuple(const char *extName, Oid extOwner, - Oid schemaOid, bool relocatable, const char *extVersion, - Datum extConfig, Datum extCondition, - List *requiredExtensions); + Oid schemaOid, bool relocatable, const char *extVersion, + Datum extConfig, Datum extCondition, + List *requiredExtensions); extern ObjectAddress ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt); extern ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, - ObjectAddress *objAddress); + ObjectAddress *objAddr); extern Oid get_extension_oid(const char *extname, bool missing_ok); extern char *get_extension_name(Oid ext_oid); extern ObjectAddress AlterExtensionNamespace(const char *extensionName, const char *newschema, - Oid *oldschema); - -extern void AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId); + Oid *oldschema); #endif /* EXTENSION_H */ diff --git a/src/include/commands/lockcmds.h b/src/include/commands/lockcmds.h index 6420e13e752..8d2a9a24c50 100644 --- a/src/include/commands/lockcmds.h +++ b/src/include/commands/lockcmds.h @@ -4,7 +4,7 @@ * prototypes for lockcmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/lockcmds.h diff --git a/src/include/commands/matview.h b/src/include/commands/matview.h index 3b30ad76b2c..edf04bf415a 100644 --- a/src/include/commands/matview.h +++ b/src/include/commands/matview.h @@ -4,7 +4,7 @@ * prototypes for matview.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/matview.h @@ -24,7 +24,7 @@ extern void SetMatViewPopulatedState(Relation relation, bool newstate); extern ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, - ParamListInfo params, char *completionTag); + ParamListInfo params, char *completionTag); extern DestReceiver *CreateTransientRelDestReceiver(Oid oid); diff --git a/src/include/commands/policy.h b/src/include/commands/policy.h index acf621a8ecd..8650c1a639b 100644 --- a/src/include/commands/policy.h +++ b/src/include/commands/policy.h @@ -4,7 +4,7 @@ * prototypes for policy.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/policy.h @@ -28,8 +28,8 @@ extern bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid objid); extern ObjectAddress CreatePolicy(CreatePolicyStmt *stmt); extern ObjectAddress AlterPolicy(AlterPolicyStmt *stmt); -extern Oid get_relation_policy_oid(Oid relid, const char *policy_name, - bool missing_ok); +extern Oid get_relation_policy_oid(Oid relid, const char *policy_name, + bool missing_ok); extern ObjectAddress rename_policy(RenameStmt *stmt); diff --git a/src/include/commands/portalcmds.h b/src/include/commands/portalcmds.h index 99dd04594fd..73220981eec 100644 --- a/src/include/commands/portalcmds.h +++ b/src/include/commands/portalcmds.h @@ -4,7 +4,7 @@ * prototypes for portalcmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/portalcmds.h @@ -19,10 +19,10 @@ extern void PerformCursorOpen(DeclareCursorStmt *cstmt, ParamListInfo params, - const char *queryString, bool isTopLevel); + const char *queryString, bool isTopLevel); extern void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, - char *completionTag); + char *completionTag); extern void PerformPortalClose(const char *name); diff --git a/src/include/commands/prepare.h b/src/include/commands/prepare.h index ffec029df40..2ce832419ff 100644 --- a/src/include/commands/prepare.h +++ b/src/include/commands/prepare.h @@ -4,7 +4,7 @@ * PREPARE, EXECUTE and DEALLOCATE commands, and prepared-stmt storage * * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * src/include/commands/prepare.h * @@ -36,21 +36,21 @@ typedef struct /* Utility statements PREPARE, EXECUTE, DEALLOCATE, EXPLAIN EXECUTE */ extern void PrepareQuery(PrepareStmt *stmt, const char *queryString, - int stmt_location, int stmt_len); + int stmt_location, int stmt_len); extern void ExecuteQuery(ExecuteStmt *stmt, IntoClause *intoClause, - const char *queryString, ParamListInfo params, - DestReceiver *dest, char *completionTag); + const char *queryString, ParamListInfo params, + DestReceiver *dest, char *completionTag); extern void DeallocateQuery(DeallocateStmt *stmt); extern void ExplainExecuteQuery(ExecuteStmt *execstmt, IntoClause *into, - ExplainState *es, const char *queryString, - ParamListInfo params, QueryEnvironment *queryEnv); + ExplainState *es, const char *queryString, + ParamListInfo params, QueryEnvironment *queryEnv); /* Low-level access to stored prepared statements */ extern void StorePreparedStatement(const char *stmt_name, - CachedPlanSource *plansource, - bool from_sql); + CachedPlanSource *plansource, + bool from_sql); extern PreparedStatement *FetchPreparedStatement(const char *stmt_name, - bool throwError); + bool throwError); extern void DropPreparedStatement(const char *stmt_name, bool showError); extern TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt); extern List *FetchPreparedStatementTargetList(PreparedStatement *stmt); diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 6a6b467fee4..acd1313cb3d 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -7,7 +7,7 @@ * constants, you probably also need to update the views based on them * in system_views.sql. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/progress.h @@ -34,4 +34,72 @@ #define PROGRESS_VACUUM_PHASE_TRUNCATE 5 #define PROGRESS_VACUUM_PHASE_FINAL_CLEANUP 6 +/* Progress parameters for cluster */ +#define PROGRESS_CLUSTER_COMMAND 0 +#define PROGRESS_CLUSTER_PHASE 1 +#define PROGRESS_CLUSTER_INDEX_RELID 2 +#define PROGRESS_CLUSTER_HEAP_TUPLES_SCANNED 3 +#define PROGRESS_CLUSTER_HEAP_TUPLES_WRITTEN 4 +#define PROGRESS_CLUSTER_TOTAL_HEAP_BLKS 5 +#define PROGRESS_CLUSTER_HEAP_BLKS_SCANNED 6 +#define PROGRESS_CLUSTER_INDEX_REBUILD_COUNT 7 + +/* Phases of cluster (as advertised via PROGRESS_CLUSTER_PHASE) */ +#define PROGRESS_CLUSTER_PHASE_SEQ_SCAN_HEAP 1 +#define PROGRESS_CLUSTER_PHASE_INDEX_SCAN_HEAP 2 +#define PROGRESS_CLUSTER_PHASE_SORT_TUPLES 3 +#define PROGRESS_CLUSTER_PHASE_WRITE_NEW_HEAP 4 +#define PROGRESS_CLUSTER_PHASE_SWAP_REL_FILES 5 +#define PROGRESS_CLUSTER_PHASE_REBUILD_INDEX 6 +#define PROGRESS_CLUSTER_PHASE_FINAL_CLEANUP 7 + +/* Commands of PROGRESS_CLUSTER */ +#define PROGRESS_CLUSTER_COMMAND_CLUSTER 1 +#define PROGRESS_CLUSTER_COMMAND_VACUUM_FULL 2 + +/* Progress parameters for CREATE INDEX */ +/* 3, 4 and 5 reserved for "waitfor" metrics */ +#define PROGRESS_CREATEIDX_COMMAND 0 +#define PROGRESS_CREATEIDX_INDEX_OID 6 +#define PROGRESS_CREATEIDX_ACCESS_METHOD_OID 8 +#define PROGRESS_CREATEIDX_PHASE 9 /* AM-agnostic phase # */ +#define PROGRESS_CREATEIDX_SUBPHASE 10 /* phase # filled by AM */ +#define PROGRESS_CREATEIDX_TUPLES_TOTAL 11 +#define PROGRESS_CREATEIDX_TUPLES_DONE 12 +#define PROGRESS_CREATEIDX_PARTITIONS_TOTAL 13 +#define PROGRESS_CREATEIDX_PARTITIONS_DONE 14 +/* 15 and 16 reserved for "block number" metrics */ + +/* Phases of CREATE INDEX (as advertised via PROGRESS_CREATEIDX_PHASE) */ +#define PROGRESS_CREATEIDX_PHASE_WAIT_1 1 +#define PROGRESS_CREATEIDX_PHASE_BUILD 2 +#define PROGRESS_CREATEIDX_PHASE_WAIT_2 3 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN 4 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_SORT 5 +#define PROGRESS_CREATEIDX_PHASE_VALIDATE_TABLESCAN 6 +#define PROGRESS_CREATEIDX_PHASE_WAIT_3 7 +#define PROGRESS_CREATEIDX_PHASE_WAIT_4 8 +#define PROGRESS_CREATEIDX_PHASE_WAIT_5 9 + +/* + * Subphases of CREATE INDEX, for index_build. + */ +#define PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE 1 +/* Additional phases are defined by each AM */ + +/* Commands of PROGRESS_CREATEIDX */ +#define PROGRESS_CREATEIDX_COMMAND_CREATE 1 +#define PROGRESS_CREATEIDX_COMMAND_CREATE_CONCURRENTLY 2 +#define PROGRESS_CREATEIDX_COMMAND_REINDEX 3 +#define PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY 4 + +/* Lock holder wait counts */ +#define PROGRESS_WAITFOR_TOTAL 3 +#define PROGRESS_WAITFOR_DONE 4 +#define PROGRESS_WAITFOR_CURRENT_PID 5 + +/* Block numbers in a generic relation scan */ +#define PROGRESS_SCAN_BLOCKS_TOTAL 15 +#define PROGRESS_SCAN_BLOCKS_DONE 16 + #endif diff --git a/src/include/commands/publicationcmds.h b/src/include/commands/publicationcmds.h index 0c0d7795cf1..c536b648f82 100644 --- a/src/include/commands/publicationcmds.h +++ b/src/include/commands/publicationcmds.h @@ -4,7 +4,7 @@ * prototypes for publicationcmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/publicationcmds.h diff --git a/src/include/commands/schemacmds.h b/src/include/commands/schemacmds.h index bf00754245b..fed86118ea8 100644 --- a/src/include/commands/schemacmds.h +++ b/src/include/commands/schemacmds.h @@ -4,7 +4,7 @@ * prototypes for schemacmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/schemacmds.h @@ -18,9 +18,9 @@ #include "catalog/objectaddress.h" #include "nodes/parsenodes.h" -extern Oid CreateSchemaCommand(CreateSchemaStmt *parsetree, - const char *queryString, - int stmt_location, int stmt_len); +extern Oid CreateSchemaCommand(CreateSchemaStmt *parsetree, + const char *queryString, + int stmt_location, int stmt_len); extern void RemoveSchemaById(Oid schemaOid); diff --git a/src/include/commands/seclabel.h b/src/include/commands/seclabel.h index 85f2cf67aaf..4605996a1ff 100644 --- a/src/include/commands/seclabel.h +++ b/src/include/commands/seclabel.h @@ -3,7 +3,7 @@ * * Prototypes for functions in commands/seclabel.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ #ifndef SECLABEL_H @@ -15,9 +15,9 @@ * Internal APIs */ extern char *GetSecurityLabel(const ObjectAddress *object, - const char *provider); + const char *provider); extern void SetSecurityLabel(const ObjectAddress *object, - const char *provider, const char *label); + const char *provider, const char *label); extern void DeleteSecurityLabel(const ObjectAddress *object); extern void DeleteSharedSecurityLabel(Oid objectId, Oid classId); @@ -29,6 +29,6 @@ extern ObjectAddress ExecSecLabelStmt(SecLabelStmt *stmt); typedef void (*check_object_relabel_type) (const ObjectAddress *object, const char *seclabel); extern void register_label_provider(const char *provider, - check_object_relabel_type hook); + check_object_relabel_type hook); #endif /* SECLABEL_H */ diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index 3f58bae31a0..ee26ab47d0e 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -3,7 +3,7 @@ * sequence.h * prototypes for sequence.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/sequence.h diff --git a/src/include/commands/subscriptioncmds.h b/src/include/commands/subscriptioncmds.h index 6d70ad71b17..b339b074dca 100644 --- a/src/include/commands/subscriptioncmds.h +++ b/src/include/commands/subscriptioncmds.h @@ -4,7 +4,7 @@ * prototypes for subscriptioncmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/subscriptioncmds.h @@ -19,7 +19,7 @@ #include "nodes/parsenodes.h" extern ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt, - bool isTopLevel); + bool isTopLevel); extern ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt); extern void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel); diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index 70ee3da76b8..9c25a805f29 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -4,7 +4,7 @@ * prototypes for tablecmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/tablecmds.h @@ -18,13 +18,12 @@ #include "catalog/dependency.h" #include "catalog/objectaddress.h" #include "nodes/parsenodes.h" -#include "catalog/partition.h" #include "storage/lock.h" #include "utils/relcache.h" extern ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, - ObjectAddress *typaddress, const char *queryString); + ObjectAddress *typaddress, const char *queryString); extern void RemoveRelations(DropStmt *drop); @@ -41,15 +40,15 @@ extern void AlterTableInternal(Oid relid, List *cmds, bool recurse); extern Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt); extern ObjectAddress AlterTableNamespace(AlterObjectSchemaStmt *stmt, - Oid *oldschema); + Oid *oldschema); extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, - Oid nspOid, ObjectAddresses *objsMoved); + Oid nspOid, ObjectAddresses *objsMoved); extern void AlterRelationNamespaceInternal(Relation classRel, Oid relOid, - Oid oldNspOid, Oid newNspOid, - bool hasDependEntry, - ObjectAddresses *objsMoved); + Oid oldNspOid, Oid newNspOid, + bool hasDependEntry, + ObjectAddresses *objsMoved); extern void CheckTableNotInUse(Relation rel, const char *stmt); @@ -61,40 +60,35 @@ extern void SetRelationHasSubclass(Oid relationId, bool relhassubclass); extern ObjectAddress renameatt(RenameStmt *stmt); -extern ObjectAddress renameatt_type(RenameStmt *stmt); - extern ObjectAddress RenameConstraint(RenameStmt *stmt); extern ObjectAddress RenameRelation(RenameStmt *stmt); extern void RenameRelationInternal(Oid myrelid, - const char *newrelname, bool is_internal); + const char *newrelname, bool is_internal, + bool is_index); extern void find_composite_type_dependencies(Oid typeOid, - Relation origRelation, - const char *origTypeName); + Relation origRelation, + const char *origTypeName); extern void check_of_type(HeapTuple typetuple); -extern void createForeignKeyTriggers(Relation rel, Oid refRelOid, - Constraint *fkconstraint, Oid constraintOid, - Oid indexOid, bool create_action); - extern void register_on_commit_action(Oid relid, OnCommitAction action); extern void remove_on_commit_action(Oid relid); extern void PreCommit_on_commit_actions(void); extern void AtEOXact_on_commit_actions(bool isCommit); extern void AtEOSubXact_on_commit_actions(bool isCommit, - SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId mySubid, + SubTransactionId parentSubid); extern void RangeVarCallbackOwnsTable(const RangeVar *relation, - Oid relId, Oid oldRelId, void *arg); + Oid relId, Oid oldRelId, void *arg); extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, - Oid relId, Oid oldRelId, void *noCatalogs); + Oid relId, Oid oldRelId, void *arg); extern bool PartConstraintImpliedByRelConstraint(Relation scanrel, - List *partConstraint); + List *partConstraint); #endif /* TABLECMDS_H */ diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index d52b73d57ab..273e31ccdfb 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -4,7 +4,7 @@ * Tablespace management commands (create/drop tablespace). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/tablespace.h @@ -49,7 +49,7 @@ extern Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); -extern Oid GetDefaultTablespace(char relpersistence); +extern Oid GetDefaultTablespace(char relpersistence, bool partitioned); extern void PrepareTempTablespaces(void); diff --git a/src/include/commands/trigger.h b/src/include/commands/trigger.h index 1b79a803103..a46feeedb0b 100644 --- a/src/include/commands/trigger.h +++ b/src/include/commands/trigger.h @@ -3,7 +3,7 @@ * trigger.h * Declarations for trigger handling. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/trigger.h @@ -35,8 +35,8 @@ typedef struct TriggerData HeapTuple tg_trigtuple; HeapTuple tg_newtuple; Trigger *tg_trigger; - Buffer tg_trigtuplebuf; - Buffer tg_newtuplebuf; + TupleTableSlot *tg_trigslot; + TupleTableSlot *tg_newslot; Tuplestorestate *tg_oldtable; Tuplestorestate *tg_newtable; } TriggerData; @@ -77,9 +77,9 @@ typedef struct TransitionCaptureState * format to parent format after they have already been converted in the * opposite direction during routing. In that case we bypass conversion * and allow the inserting code (copy.c and nodeModifyTable.c) to provide - * the original tuple directly. + * a slot containing the original tuple directly. */ - HeapTuple tcs_original_insert_tuple; + TupleTableSlot *tcs_original_insert_tuple; /* * Private data including the tuplestore(s) into which to insert tuples. @@ -158,9 +158,9 @@ extern PGDLLIMPORT int SessionReplicationRole; #define TRIGGER_DISABLED 'D' extern ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, - Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, - Oid funcoid, Oid parentTriggerOid, Node *whenClause, - bool isInternal, bool in_partition); + Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, + Oid funcoid, Oid parentTriggerOid, Node *whenClause, + bool isInternal, bool in_partition); extern void RemoveTriggerById(Oid trigOid); extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); @@ -168,7 +168,7 @@ extern Oid get_trigger_oid(Oid relid, const char *name, bool missing_ok); extern ObjectAddress renametrig(RenameStmt *stmt); extern void EnableDisableTrigger(Relation rel, const char *tgname, - char fires_when, bool skip_system, LOCKMODE lockmode); + char fires_when, bool skip_system, LOCKMODE lockmode); extern void RelationBuildTriggers(Relation relation); @@ -177,72 +177,71 @@ extern TriggerDesc *CopyTriggerDesc(TriggerDesc *trigdesc); extern const char *FindTriggerIncompatibleWithInheritance(TriggerDesc *trigdesc); extern TransitionCaptureState *MakeTransitionCaptureState(TriggerDesc *trigdesc, - Oid relid, CmdType cmdType); + Oid relid, CmdType cmdType); extern void FreeTriggerDesc(TriggerDesc *trigdesc); extern void ExecBSInsertTriggers(EState *estate, - ResultRelInfo *relinfo); + ResultRelInfo *relinfo); extern void ExecASInsertTriggers(EState *estate, - ResultRelInfo *relinfo, - TransitionCaptureState *transition_capture); -extern TupleTableSlot *ExecBRInsertTriggers(EState *estate, - ResultRelInfo *relinfo, - TupleTableSlot *slot); + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); +extern bool ExecBRInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TupleTableSlot *slot); extern void ExecARInsertTriggers(EState *estate, - ResultRelInfo *relinfo, - HeapTuple trigtuple, - List *recheckIndexes, - TransitionCaptureState *transition_capture); -extern TupleTableSlot *ExecIRInsertTriggers(EState *estate, - ResultRelInfo *relinfo, - TupleTableSlot *slot); + ResultRelInfo *relinfo, + TupleTableSlot *slot, + List *recheckIndexes, + TransitionCaptureState *transition_capture); +extern bool ExecIRInsertTriggers(EState *estate, + ResultRelInfo *relinfo, + TupleTableSlot *slot); extern void ExecBSDeleteTriggers(EState *estate, - ResultRelInfo *relinfo); + ResultRelInfo *relinfo); extern void ExecASDeleteTriggers(EState *estate, - ResultRelInfo *relinfo, - TransitionCaptureState *transition_capture); + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); extern bool ExecBRDeleteTriggers(EState *estate, - EPQState *epqstate, - ResultRelInfo *relinfo, - ItemPointer tupleid, - HeapTuple fdw_trigtuple, - HeapUpdateFailureData *hufdp); + EPQState *epqstate, + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot **epqslot); extern void ExecARDeleteTriggers(EState *estate, - ResultRelInfo *relinfo, - ItemPointer tupleid, - HeapTuple fdw_trigtuple, - TransitionCaptureState *transition_capture); + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TransitionCaptureState *transition_capture); extern bool ExecIRDeleteTriggers(EState *estate, - ResultRelInfo *relinfo, - HeapTuple trigtuple); + ResultRelInfo *relinfo, + HeapTuple trigtuple); extern void ExecBSUpdateTriggers(EState *estate, - ResultRelInfo *relinfo); + ResultRelInfo *relinfo); extern void ExecASUpdateTriggers(EState *estate, - ResultRelInfo *relinfo, - TransitionCaptureState *transition_capture); -extern TupleTableSlot *ExecBRUpdateTriggers(EState *estate, - EPQState *epqstate, - ResultRelInfo *relinfo, - ItemPointer tupleid, - HeapTuple fdw_trigtuple, - TupleTableSlot *slot, - HeapUpdateFailureData *hufdp); + ResultRelInfo *relinfo, + TransitionCaptureState *transition_capture); +extern bool ExecBRUpdateTriggers(EState *estate, + EPQState *epqstate, + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot *slot); extern void ExecARUpdateTriggers(EState *estate, - ResultRelInfo *relinfo, - ItemPointer tupleid, - HeapTuple fdw_trigtuple, - HeapTuple newtuple, - List *recheckIndexes, - TransitionCaptureState *transition_capture); -extern TupleTableSlot *ExecIRUpdateTriggers(EState *estate, - ResultRelInfo *relinfo, - HeapTuple trigtuple, - TupleTableSlot *slot); + ResultRelInfo *relinfo, + ItemPointer tupleid, + HeapTuple fdw_trigtuple, + TupleTableSlot *slot, + List *recheckIndexes, + TransitionCaptureState *transition_capture); +extern bool ExecIRUpdateTriggers(EState *estate, + ResultRelInfo *relinfo, + HeapTuple trigtuple, + TupleTableSlot *slot); extern void ExecBSTruncateTriggers(EState *estate, - ResultRelInfo *relinfo); + ResultRelInfo *relinfo); extern void ExecASTruncateTriggers(EState *estate, - ResultRelInfo *relinfo); + ResultRelInfo *relinfo); extern void AfterTriggerBeginXact(void); extern void AfterTriggerBeginQuery(void); @@ -259,11 +258,13 @@ extern bool AfterTriggerPendingOnRel(Oid relid); * in utils/adt/ri_triggers.c */ extern bool RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, - HeapTuple old_row, HeapTuple new_row); + TupleTableSlot *old_slot, TupleTableSlot *new_slot); extern bool RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, - HeapTuple old_row, HeapTuple new_row); + TupleTableSlot *old_slot, TupleTableSlot *new_slot); extern bool RI_Initial_Check(Trigger *trigger, - Relation fk_rel, Relation pk_rel); + Relation fk_rel, Relation pk_rel); +extern void RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, + Relation pk_rel); /* result values for RI_FKey_trigger_type: */ #define RI_TRIGGER_PK 1 /* is a trigger on the PK relation */ diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index a04f3405de1..8af0665f296 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -4,7 +4,7 @@ * prototypes for typecmds.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/typecmds.h @@ -26,17 +26,17 @@ extern void RemoveTypeById(Oid typeOid); extern ObjectAddress DefineDomain(CreateDomainStmt *stmt); extern ObjectAddress DefineEnum(CreateEnumStmt *stmt); extern ObjectAddress DefineRange(CreateRangeStmt *stmt); -extern ObjectAddress AlterEnum(AlterEnumStmt *stmt, bool isTopLevel); +extern ObjectAddress AlterEnum(AlterEnumStmt *stmt); extern ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist); extern Oid AssignTypeArrayOid(void); extern ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw); extern ObjectAddress AlterDomainNotNull(List *names, bool notNull); extern ObjectAddress AlterDomainAddConstraint(List *names, Node *constr, - ObjectAddress *constrAddr); + ObjectAddress *constrAddr); extern ObjectAddress AlterDomainValidateConstraint(List *names, const char *constrName); extern ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, - DropBehavior behavior, bool missing_ok); + DropBehavior behavior, bool missing_ok); extern void checkDomainOwner(HeapTuple tup); @@ -47,11 +47,11 @@ extern void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry) extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId); extern ObjectAddress AlterTypeNamespace(List *names, const char *newschema, - ObjectType objecttype, Oid *oldschema); + ObjectType objecttype, Oid *oldschema); extern Oid AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved); -extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, - bool isImplicitArray, - bool errorOnTableType, - ObjectAddresses *objsMoved); +extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid, + bool isImplicitArray, + bool errorOnTableType, + ObjectAddresses *objsMoved); #endif /* TYPECMDS_H */ diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h index 85d472f0a54..128f7ae65da 100644 --- a/src/include/commands/vacuum.h +++ b/src/include/commands/vacuum.h @@ -4,7 +4,7 @@ * header file for postgres vacuum cleaner and statistics analyzer * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/vacuum.h @@ -15,6 +15,7 @@ #define VACUUM_H #include "access/htup.h" +#include "catalog/pg_class.h" #include "catalog/pg_statistic.h" #include "catalog/pg_type.h" #include "nodes/parsenodes.h" @@ -51,9 +52,11 @@ * careful to allocate any pointed-to data in anl_context, which will NOT * be CurrentMemoryContext when compute_stats is called. * - * Note: for the moment, all comparisons done for statistical purposes - * should use the database's default collation (DEFAULT_COLLATION_OID). - * This might change in some future release. + * Note: all comparisons done for statistical purposes should use the + * underlying column's collation (attcollation), except in situations + * where a noncollatable container type contains a collatable type; + * in that case use the type's default collation. Be sure to record + * the appropriate collation in stacoll. *---------- */ typedef struct VacAttrStats *VacAttrStatsP; @@ -77,11 +80,13 @@ typedef struct VacAttrStats * because some index opclasses store a different type than the underlying * column/expression. Instead use attrtypid, attrtypmod, and attrtype for * information about the datatype being fed to the typanalyze function. + * Likewise, use attrcollid not attr->attcollation. */ Form_pg_attribute attr; /* copy of pg_attribute row for column */ Oid attrtypid; /* type of data being analyzed */ int32 attrtypmod; /* typmod of data being analyzed */ Form_pg_type attrtype; /* copy of pg_type row for attrtypid */ + Oid attrcollid; /* collation of data being analyzed */ MemoryContext anl_context; /* where to save long-lived data */ /* @@ -102,6 +107,7 @@ typedef struct VacAttrStats float4 stadistinct; /* # distinct values */ int16 stakind[STATISTIC_NUM_SLOTS]; Oid staop[STATISTIC_NUM_SLOTS]; + Oid stacoll[STATISTIC_NUM_SLOTS]; int numnumbers[STATISTIC_NUM_SLOTS]; float4 *stanumbers[STATISTIC_NUM_SLOTS]; int numvalues[STATISTIC_NUM_SLOTS]; @@ -130,11 +136,40 @@ typedef struct VacAttrStats int rowstride; } VacAttrStats; +typedef enum VacuumOption +{ + VACOPT_VACUUM = 1 << 0, /* do VACUUM */ + VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */ + VACOPT_VERBOSE = 1 << 2, /* print progress info */ + VACOPT_FREEZE = 1 << 3, /* FREEZE option */ + VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ + VACOPT_SKIP_LOCKED = 1 << 5, /* skip if cannot get lock */ + VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ + VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ +} VacuumOption; + +/* + * A ternary value used by vacuum parameters. + * + * DEFAULT value is used to determine the value based on other + * configurations, e.g. reloptions. + */ +typedef enum VacOptTernaryValue +{ + VACOPT_TERNARY_DEFAULT = 0, + VACOPT_TERNARY_DISABLED, + VACOPT_TERNARY_ENABLED, +} VacOptTernaryValue; + /* * Parameters customizing behavior of VACUUM and ANALYZE. + * + * Note that at least one of VACOPT_VACUUM and VACOPT_ANALYZE must be set + * in options. */ typedef struct VacuumParams { + int options; /* bitmask of VacuumOption */ int freeze_min_age; /* min freeze age, -1 to use default */ int freeze_table_age; /* age at which to scan whole table */ int multixact_freeze_min_age; /* min multixact freeze age, -1 to @@ -145,6 +180,10 @@ typedef struct VacuumParams int log_min_duration; /* minimum execution threshold in ms at * which verbose logs are activated, -1 * to use default */ + VacOptTernaryValue index_cleanup; /* Do index vacuum and cleanup, + * default value depends on reloptions */ + VacOptTernaryValue truncate; /* Truncate empty pages at the end, + * default value depends on reloptions */ } VacuumParams; /* GUC parameters */ @@ -156,44 +195,44 @@ extern int vacuum_multixact_freeze_table_age; /* in commands/vacuum.c */ -extern void ExecVacuum(VacuumStmt *vacstmt, bool isTopLevel); -extern void vacuum(int options, List *relations, VacuumParams *params, - BufferAccessStrategy bstrategy, bool isTopLevel); +extern void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel); +extern void vacuum(List *relations, VacuumParams *params, + BufferAccessStrategy bstrategy, bool isTopLevel); extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, - int *nindexes, Relation **Irel); + int *nindexes, Relation **Irel); extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); extern double vac_estimate_reltuples(Relation relation, - BlockNumber total_pages, - BlockNumber scanned_pages, - double scanned_tuples); + BlockNumber total_pages, + BlockNumber scanned_pages, + double scanned_tuples); extern void vac_update_relstats(Relation relation, - BlockNumber num_pages, - double num_tuples, - BlockNumber num_all_visible_pages, - bool hasindex, - TransactionId frozenxid, - MultiXactId minmulti, - bool in_outer_xact); + BlockNumber num_pages, + double num_tuples, + BlockNumber num_all_visible_pages, + bool hasindex, + TransactionId frozenxid, + MultiXactId minmulti, + bool in_outer_xact); extern void vacuum_set_xid_limits(Relation rel, - int freeze_min_age, int freeze_table_age, - int multixact_freeze_min_age, - int multixact_freeze_table_age, - TransactionId *oldestXmin, - TransactionId *freezeLimit, - TransactionId *xidFullScanLimit, - MultiXactId *multiXactCutoff, - MultiXactId *mxactFullScanLimit); + int freeze_min_age, int freeze_table_age, + int multixact_freeze_min_age, + int multixact_freeze_table_age, + TransactionId *oldestXmin, + TransactionId *freezeLimit, + TransactionId *xidFullScanLimit, + MultiXactId *multiXactCutoff, + MultiXactId *mxactFullScanLimit); extern void vac_update_datfrozenxid(void); extern void vacuum_delay_point(void); - -/* in commands/vacuumlazy.c */ -extern void lazy_vacuum_rel(Relation onerel, int options, - VacuumParams *params, BufferAccessStrategy bstrategy); +extern bool vacuum_is_relation_owner(Oid relid, Form_pg_class reltuple, + int options); +extern Relation vacuum_open_relation(Oid relid, RangeVar *relation, + int options, bool verbose, LOCKMODE lmode); /* in commands/analyze.c */ -extern void analyze_rel(Oid relid, RangeVar *relation, int options, - VacuumParams *params, List *va_cols, bool in_outer_xact, - BufferAccessStrategy bstrategy); +extern void analyze_rel(Oid relid, RangeVar *relation, + VacuumParams *params, List *va_cols, bool in_outer_xact, + BufferAccessStrategy bstrategy); extern bool std_typanalyze(VacAttrStats *stats); /* in utils/misc/sampling.c --- duplicate of declarations in utils/sampling.h */ diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h index 4ea3b0209b1..5f43414425c 100644 --- a/src/include/commands/variable.h +++ b/src/include/commands/variable.h @@ -2,7 +2,7 @@ * variable.h * Routines for handling specialized SET variables. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/variable.h @@ -22,9 +22,7 @@ extern bool check_log_timezone(char **newval, void **extra, GucSource source); extern void assign_log_timezone(const char *newval, void *extra); extern const char *show_log_timezone(void); extern bool check_transaction_read_only(bool *newval, void **extra, GucSource source); -extern bool check_XactIsoLevel(char **newval, void **extra, GucSource source); -extern void assign_XactIsoLevel(const char *newval, void *extra); -extern const char *show_XactIsoLevel(void); +extern bool check_XactIsoLevel(int *newval, void **extra, GucSource source); extern bool check_transaction_deferrable(bool *newval, void **extra, GucSource source); extern bool check_random_seed(double *newval, void **extra, GucSource source); extern void assign_random_seed(double newval, void *extra); diff --git a/src/include/commands/view.h b/src/include/commands/view.h index 4703922ff69..663e096a7af 100644 --- a/src/include/commands/view.h +++ b/src/include/commands/view.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/commands/view.h @@ -17,10 +17,8 @@ #include "catalog/objectaddress.h" #include "nodes/parsenodes.h" -extern void validateWithCheckOption(const char *value); - extern ObjectAddress DefineView(ViewStmt *stmt, const char *queryString, - int stmt_location, int stmt_len); + int stmt_location, int stmt_len); extern void StoreViewQuery(Oid viewOid, Query *viewParse, bool replace); diff --git a/src/include/common/base64.h b/src/include/common/base64.h index 32cec4b2104..c30b1734833 100644 --- a/src/include/common/base64.h +++ b/src/include/common/base64.h @@ -3,7 +3,7 @@ * Encoding and decoding routines for base64 without whitespace * support. * - * Portions Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/include/common/base64.h */ @@ -11,8 +11,8 @@ #define BASE64_H /* base 64 */ -extern int pg_b64_encode(const char *src, int len, char *dst); -extern int pg_b64_decode(const char *src, int len, char *dst); +extern int pg_b64_encode(const char *src, int len, char *dst, int dstlen); +extern int pg_b64_decode(const char *src, int len, char *dst, int dstlen); extern int pg_b64_enc_len(int srclen); extern int pg_b64_dec_len(int srclen); diff --git a/src/include/common/config_info.h b/src/include/common/config_info.h index 72014a915a9..b1b93f3e086 100644 --- a/src/include/common/config_info.h +++ b/src/include/common/config_info.h @@ -2,7 +2,7 @@ * config_info.h * Common code for pg_config output * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/common/config_info.h */ @@ -16,6 +16,6 @@ typedef struct ConfigData } ConfigData; extern ConfigData *get_configdata(const char *my_exec_path, - size_t *configdata_len); + size_t *configdata_len); #endif /* COMMON_CONFIG_INFO_H */ diff --git a/src/include/common/controldata_utils.h b/src/include/common/controldata_utils.h index d8fd3163968..6263afafbbe 100644 --- a/src/include/common/controldata_utils.h +++ b/src/include/common/controldata_utils.h @@ -2,7 +2,7 @@ * controldata_utils.h * Common code for pg_controldata output * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/controldata_utils.h @@ -12,6 +12,8 @@ #include "catalog/pg_control.h" -extern ControlFileData *get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p); +extern ControlFileData *get_controlfile(const char *DataDir, bool *crc_ok_p); +extern void update_controlfile(const char *DataDir, + ControlFileData *ControlFile, bool do_sync); #endif /* COMMON_CONTROLDATA_UTILS_H */ diff --git a/src/include/common/fe_memutils.h b/src/include/common/fe_memutils.h index 458743dd401..a1e5940d312 100644 --- a/src/include/common/fe_memutils.h +++ b/src/include/common/fe_memutils.h @@ -2,7 +2,7 @@ * fe_memutils.h * memory management support for frontend code * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/common/fe_memutils.h */ diff --git a/src/include/common/file_perm.h b/src/include/common/file_perm.h index 3090f789317..d512e622dbb 100644 --- a/src/include/common/file_perm.h +++ b/src/include/common/file_perm.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * - * File and directory permission constants + * File and directory permission definitions * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/file_perm.h @@ -13,6 +13,8 @@ #ifndef FILE_PERM_H #define FILE_PERM_H +#include + /* * Mode mask for data directory permissions that only allows the owner to * read/write directories and files. diff --git a/src/include/common/file_utils.h b/src/include/common/file_utils.h index 71f638562e2..3aefc38b10f 100644 --- a/src/include/common/file_utils.h +++ b/src/include/common/file_utils.h @@ -5,7 +5,7 @@ * Assorted utility functions to work on files. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/file_utils.h @@ -15,13 +15,10 @@ #ifndef FILE_UTILS_H #define FILE_UTILS_H -extern int fsync_fname(const char *fname, bool isdir, - const char *progname); -extern void fsync_pgdata(const char *pg_data, const char *progname, - int serverVersion); -extern void fsync_dir_recurse(const char *dir, const char *progname); -extern int durable_rename(const char *oldfile, const char *newfile, - const char *progname); -extern int fsync_parent_path(const char *fname, const char *progname); +extern int fsync_fname(const char *fname, bool isdir); +extern void fsync_pgdata(const char *pg_data, int serverVersion); +extern void fsync_dir_recurse(const char *dir); +extern int durable_rename(const char *oldfile, const char *newfile); +extern int fsync_parent_path(const char *fname); #endif /* FILE_UTILS_H */ diff --git a/src/include/common/int.h b/src/include/common/int.h index 82e38d4b7bd..8f262bc8b7f 100644 --- a/src/include/common/int.h +++ b/src/include/common/int.h @@ -11,7 +11,7 @@ * the 64 bit cases can be considerably faster with intrinsics. In case no * intrinsics are available 128 bit math is used where available. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/common/int.h * @@ -20,10 +20,28 @@ #ifndef COMMON_INT_H #define COMMON_INT_H -/* - * If a + b overflows, return true, otherwise store the result of a + b into - * *result. The content of *result is implementation defined in case of + +/*--------- + * The following guidelines apply to all the routines: + * - If a + b overflows, return true, otherwise store the result of a + b + * into *result. The content of *result is implementation defined in case of + * overflow. + * - If a - b overflows, return true, otherwise store the result of a - b + * into *result. The content of *result is implementation defined in case of * overflow. + * - If a * b overflows, return true, otherwise store the result of a * b + * into *result. The content of *result is implementation defined in case of + * overflow. + *--------- + */ + +/*------------------------------------------------------------------------ + * Overflow routines for signed integers + *------------------------------------------------------------------------ + */ + +/* + * INT16 */ static inline bool pg_add_s16_overflow(int16 a, int16 b, int16 *result) @@ -35,7 +53,7 @@ pg_add_s16_overflow(int16 a, int16 b, int16 *result) if (res > PG_INT16_MAX || res < PG_INT16_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int16) res; @@ -43,11 +61,6 @@ pg_add_s16_overflow(int16 a, int16 b, int16 *result) #endif } -/* - * If a - b overflows, return true, otherwise store the result of a - b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_sub_s16_overflow(int16 a, int16 b, int16 *result) { @@ -58,7 +71,7 @@ pg_sub_s16_overflow(int16 a, int16 b, int16 *result) if (res > PG_INT16_MAX || res < PG_INT16_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int16) res; @@ -66,11 +79,6 @@ pg_sub_s16_overflow(int16 a, int16 b, int16 *result) #endif } -/* - * If a * b overflows, return true, otherwise store the result of a * b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_mul_s16_overflow(int16 a, int16 b, int16 *result) { @@ -81,7 +89,7 @@ pg_mul_s16_overflow(int16 a, int16 b, int16 *result) if (res > PG_INT16_MAX || res < PG_INT16_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int16) res; @@ -90,9 +98,7 @@ pg_mul_s16_overflow(int16 a, int16 b, int16 *result) } /* - * If a + b overflows, return true, otherwise store the result of a + b into - * *result. The content of *result is implementation defined in case of - * overflow. + * INT32 */ static inline bool pg_add_s32_overflow(int32 a, int32 b, int32 *result) @@ -104,7 +110,7 @@ pg_add_s32_overflow(int32 a, int32 b, int32 *result) if (res > PG_INT32_MAX || res < PG_INT32_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int32) res; @@ -112,11 +118,6 @@ pg_add_s32_overflow(int32 a, int32 b, int32 *result) #endif } -/* - * If a - b overflows, return true, otherwise store the result of a - b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_sub_s32_overflow(int32 a, int32 b, int32 *result) { @@ -127,7 +128,7 @@ pg_sub_s32_overflow(int32 a, int32 b, int32 *result) if (res > PG_INT32_MAX || res < PG_INT32_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int32) res; @@ -135,11 +136,6 @@ pg_sub_s32_overflow(int32 a, int32 b, int32 *result) #endif } -/* - * If a * b overflows, return true, otherwise store the result of a * b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_mul_s32_overflow(int32 a, int32 b, int32 *result) { @@ -150,7 +146,7 @@ pg_mul_s32_overflow(int32 a, int32 b, int32 *result) if (res > PG_INT32_MAX || res < PG_INT32_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int32) res; @@ -159,9 +155,7 @@ pg_mul_s32_overflow(int32 a, int32 b, int32 *result) } /* - * If a + b overflows, return true, otherwise store the result of a + b into - * *result. The content of *result is implementation defined in case of - * overflow. + * INT64 */ static inline bool pg_add_s64_overflow(int64 a, int64 b, int64 *result) @@ -173,7 +167,7 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result) if (res > PG_INT64_MAX || res < PG_INT64_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int64) res; @@ -182,7 +176,7 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result) if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) || (a < 0 && b < 0 && a < PG_INT64_MIN - b)) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = a + b; @@ -190,11 +184,6 @@ pg_add_s64_overflow(int64 a, int64 b, int64 *result) #endif } -/* - * If a - b overflows, return true, otherwise store the result of a - b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result) { @@ -205,7 +194,7 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result) if (res > PG_INT64_MAX || res < PG_INT64_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int64) res; @@ -214,7 +203,7 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result) if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) || (a > 0 && b < 0 && a > PG_INT64_MAX + b)) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = a - b; @@ -222,11 +211,6 @@ pg_sub_s64_overflow(int64 a, int64 b, int64 *result) #endif } -/* - * If a * b overflows, return true, otherwise store the result of a * b into - * *result. The content of *result is implementation defined in case of - * overflow. - */ static inline bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result) { @@ -237,7 +221,7 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result) if (res > PG_INT64_MAX || res < PG_INT64_MIN) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = (int64) res; @@ -262,7 +246,7 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result) (a < 0 && b > 0 && a < PG_INT64_MIN / b) || (a < 0 && b < 0 && a < PG_INT64_MAX / b))) { - *result = 0x5EED; /* to avoid spurious warnings */ + *result = 0x5EED; /* to avoid spurious warnings */ return true; } *result = a * b; @@ -270,4 +254,184 @@ pg_mul_s64_overflow(int64 a, int64 b, int64 *result) #endif } +/*------------------------------------------------------------------------ + * Overflow routines for unsigned integers + *------------------------------------------------------------------------ + */ + +/* + * UINT16 + */ +static inline bool +pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint16 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + uint32 res = (uint32) a * (uint32) b; + + if (res > PG_UINT16_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint16) res; + return false; +#endif +} + +/* + * INT32 + */ +static inline bool +pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint32 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#else + uint64 res = (uint64) a * (uint64) b; + + if (res > PG_UINT32_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint32) res; + return false; +#endif +} + +/* + * UINT64 + */ +static inline bool +pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_add_overflow(a, b, result); +#else + uint64 res = a + b; + + if (res < a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + +static inline bool +pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_sub_overflow(a, b, result); +#else + if (b > a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = a - b; + return false; +#endif +} + +static inline bool +pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result) +{ +#if defined(HAVE__BUILTIN_OP_OVERFLOW) + return __builtin_mul_overflow(a, b, result); +#elif defined(HAVE_INT128) + uint128 res = (uint128) a * (uint128) b; + + if (res > PG_UINT64_MAX) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = (uint64) res; + return false; +#else + uint64 res = a * b; + + if (a != 0 && b != res / a) + { + *result = 0x5EED; /* to avoid spurious warnings */ + return true; + } + *result = res; + return false; +#endif +} + #endif /* COMMON_INT_H */ diff --git a/src/include/common/int128.h b/src/include/common/int128.h index 2654f18f85f..1a833cd93e7 100644 --- a/src/include/common/int128.h +++ b/src/include/common/int128.h @@ -8,7 +8,7 @@ * * See src/tools/testint128.c for a simple test harness for this file. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/common/int128.h * diff --git a/src/include/common/ip.h b/src/include/common/ip.h index 33147891d1d..ad7208673dd 100644 --- a/src/include/common/ip.h +++ b/src/include/common/ip.h @@ -5,7 +5,7 @@ * * These definitions are used by both frontend and backend code. * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/common/ip.h * @@ -24,14 +24,14 @@ #define IS_AF_UNIX(fam) (0) #endif -extern int pg_getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo *hintp, - struct addrinfo **result); +extern int pg_getaddrinfo_all(const char *hostname, const char *servname, + const struct addrinfo *hintp, + struct addrinfo **result); extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); -extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); +extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, + char *node, int nodelen, + char *service, int servicelen, + int flags); #endif /* IP_H */ diff --git a/src/include/common/keywords.h b/src/include/common/keywords.h index 0b31505b665..fb18858a53e 100644 --- a/src/include/common/keywords.h +++ b/src/include/common/keywords.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * keywords.h - * lexical token lookup for key words in PostgreSQL + * PostgreSQL's list of SQL keywords * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/keywords.h @@ -14,31 +14,20 @@ #ifndef KEYWORDS_H #define KEYWORDS_H +#include "common/kwlookup.h" + /* Keyword categories --- should match lists in gram.y */ #define UNRESERVED_KEYWORD 0 #define COL_NAME_KEYWORD 1 #define TYPE_FUNC_NAME_KEYWORD 2 #define RESERVED_KEYWORD 3 - -typedef struct ScanKeyword -{ - const char *name; /* in lower case */ - int16 value; /* grammar's token code */ - int16 category; /* see codes above */ -} ScanKeyword; - #ifndef FRONTEND -extern PGDLLIMPORT const ScanKeyword ScanKeywords[]; -extern PGDLLIMPORT const int NumScanKeywords; +extern PGDLLIMPORT const ScanKeywordList ScanKeywords; +extern PGDLLIMPORT const uint8 ScanKeywordCategories[]; #else -extern const ScanKeyword ScanKeywords[]; -extern const int NumScanKeywords; +extern const ScanKeywordList ScanKeywords; +extern const uint8 ScanKeywordCategories[]; #endif - -extern const ScanKeyword *ScanKeywordLookup(const char *text, - const ScanKeyword *keywords, - int num_keywords); - #endif /* KEYWORDS_H */ diff --git a/src/include/common/kwlookup.h b/src/include/common/kwlookup.h new file mode 100644 index 00000000000..dbff36713d6 --- /dev/null +++ b/src/include/common/kwlookup.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * kwlookup.h + * Key word lookup for PostgreSQL + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/common/kwlookup.h + * + *------------------------------------------------------------------------- + */ +#ifndef KWLOOKUP_H +#define KWLOOKUP_H + +/* Hash function used by ScanKeywordLookup */ +typedef int (*ScanKeywordHashFunc) (const void *key, size_t keylen); + +/* + * This struct contains the data needed by ScanKeywordLookup to perform a + * search within a set of keywords. The contents are typically generated by + * src/tools/gen_keywordlist.pl from a header containing PG_KEYWORD macros. + */ +typedef struct ScanKeywordList +{ + const char *kw_string; /* all keywords in order, separated by \0 */ + const uint16 *kw_offsets; /* offsets to the start of each keyword */ + ScanKeywordHashFunc hash; /* perfect hash function for keywords */ + int num_keywords; /* number of keywords */ + int max_kw_len; /* length of longest keyword */ +} ScanKeywordList; + + +extern int ScanKeywordLookup(const char *text, const ScanKeywordList *keywords); + +/* Code that wants to retrieve the text of the N'th keyword should use this. */ +static inline const char * +GetScanKeyword(int n, const ScanKeywordList *keywords) +{ + return keywords->kw_string + keywords->kw_offsets[n]; +} + +#endif /* KWLOOKUP_H */ diff --git a/src/include/common/link-canary.h b/src/include/common/link-canary.h new file mode 100644 index 00000000000..1845e66e31d --- /dev/null +++ b/src/include/common/link-canary.h @@ -0,0 +1,17 @@ +/*------------------------------------------------------------------------- + * + * link-canary.h + * Detect whether src/common functions came from frontend or backend. + * + * Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * src/include/common/link-canary.h + * + *------------------------------------------------------------------------- + */ +#ifndef LINK_CANARY_H +#define LINK_CANARY_H + +extern bool pg_link_canary_is_frontend(void); + +#endif /* LINK_CANARY_H */ diff --git a/src/include/common/logging.h b/src/include/common/logging.h new file mode 100644 index 00000000000..4a28e9a3a84 --- /dev/null +++ b/src/include/common/logging.h @@ -0,0 +1,95 @@ +/*------------------------------------------------------------------------- + * Logging framework for frontend programs + * + * Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * src/include/common/logging.h + * + *------------------------------------------------------------------------- + */ +#ifndef COMMON_LOGGING_H +#define COMMON_LOGGING_H + +/* + * Log levels are informational only. They do not affect program flow. + */ +enum pg_log_level +{ + /* + * Not initialized yet + */ + PG_LOG_NOTSET = 0, + + /* + * Low level messages that are normally off by default. + */ + PG_LOG_DEBUG, + + /* + * Any program messages that go to stderr, shown by default. (The + * program's normal output should go to stdout and not use the logging + * system.) + */ + PG_LOG_INFO, + + /* + * Warnings and "almost" errors, depends on the program + */ + PG_LOG_WARNING, + + /* + * Errors + */ + PG_LOG_ERROR, + + /* + * Severe errors that cause program termination. (One-shot programs may + * chose to label even fatal errors as merely "errors". The distinction + * is up to the program.) + */ + PG_LOG_FATAL, + + /* + * Turn all logging off. + */ + PG_LOG_OFF, +}; + +extern enum pg_log_level __pg_log_level; + +/* + * Kind of a hack to be able to produce the psql output exactly as required by + * the regression tests. + */ +#define PG_LOG_FLAG_TERSE 1 + +void pg_logging_init(const char *argv0); +void pg_logging_config(int new_flags); +void pg_logging_set_level(enum pg_log_level new_level); +void pg_logging_set_pre_callback(void (*cb) (void)); +void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)); + +void pg_log_generic(enum pg_log_level level, const char *pg_restrict fmt,...) pg_attribute_printf(2, 3); +void pg_log_generic_v(enum pg_log_level level, const char *pg_restrict fmt, va_list ap) pg_attribute_printf(2, 0); + +#define pg_log_fatal(...) do { \ + if (likely(__pg_log_level <= PG_LOG_FATAL)) pg_log_generic(PG_LOG_FATAL, __VA_ARGS__); \ + } while(0) + +#define pg_log_error(...) do { \ + if (likely(__pg_log_level <= PG_LOG_ERROR)) pg_log_generic(PG_LOG_ERROR, __VA_ARGS__); \ + } while(0) + +#define pg_log_warning(...) do { \ + if (likely(__pg_log_level <= PG_LOG_WARNING)) pg_log_generic(PG_LOG_WARNING, __VA_ARGS__); \ + } while(0) + +#define pg_log_info(...) do { \ + if (likely(__pg_log_level <= PG_LOG_INFO)) pg_log_generic(PG_LOG_INFO, __VA_ARGS__); \ + } while(0) + +#define pg_log_debug(...) do { \ + if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) pg_log_generic(PG_LOG_DEBUG, __VA_ARGS__); \ + } while(0) + +#endif /* COMMON_LOGGING_H */ diff --git a/src/include/common/md5.h b/src/include/common/md5.h index 905d3aa2197..aa7cd3f27b5 100644 --- a/src/include/common/md5.h +++ b/src/include/common/md5.h @@ -6,7 +6,7 @@ * These definitions are needed by both frontend and backend code to work * with MD5-encrypted passwords. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/md5.h @@ -16,11 +16,12 @@ #ifndef PG_MD5_H #define PG_MD5_H +#define MD5_PASSWD_CHARSET "0123456789abcdef" #define MD5_PASSWD_LEN 35 extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum); extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf); extern bool pg_md5_encrypt(const char *passwd, const char *salt, - size_t salt_len, char *buf); + size_t salt_len, char *buf); #endif diff --git a/src/include/common/pg_lzcompress.h b/src/include/common/pg_lzcompress.h index d4b2e8a53c6..3e53fbe97bd 100644 --- a/src/include/common/pg_lzcompress.h +++ b/src/include/common/pg_lzcompress.h @@ -84,8 +84,10 @@ extern const PGLZ_Strategy *const PGLZ_strategy_always; * ---------- */ extern int32 pglz_compress(const char *source, int32 slen, char *dest, - const PGLZ_Strategy *strategy); + const PGLZ_Strategy *strategy); extern int32 pglz_decompress(const char *source, int32 slen, char *dest, - int32 rawsize); + int32 rawsize, bool check_complete); +extern int32 pglz_maximum_compressed_size(int32 rawsize, + int32 total_compressed_size); #endif /* _PG_LZCOMPRESS_H_ */ diff --git a/src/include/common/relpath.h b/src/include/common/relpath.h index 82d817a53c7..8ac3929bbf4 100644 --- a/src/include/common/relpath.h +++ b/src/include/common/relpath.h @@ -3,7 +3,7 @@ * relpath.h * Declarations for GetRelationPath() and friends * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/relpath.h @@ -67,7 +67,7 @@ extern int forkname_chars(const char *str, ForkNumber *fork); extern char *GetDatabasePath(Oid dbNode, Oid spcNode); extern char *GetRelationPath(Oid dbNode, Oid spcNode, Oid relNode, - int backendId, ForkNumber forkNumber); + int backendId, ForkNumber forkNumber); /* * Wrapper macros for GetRelationPath. Beware of multiple diff --git a/src/include/common/restricted_token.h b/src/include/common/restricted_token.h index a4a263fdee0..078385c6a3f 100644 --- a/src/include/common/restricted_token.h +++ b/src/include/common/restricted_token.h @@ -2,7 +2,7 @@ * restricted_token.h * helper routine to ensure restricted token on Windows * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/restricted_token.h @@ -14,11 +14,11 @@ * On Windows make sure that we are running with a restricted token, * On other platforms do nothing. */ -void get_restricted_token(const char *progname); +void get_restricted_token(void); #ifdef WIN32 /* Create a restricted token and execute the specified process with it. */ -HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo, const char *progname); +HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo); #endif #endif /* COMMON_RESTRICTED_TOKEN_H */ diff --git a/src/include/common/saslprep.h b/src/include/common/saslprep.h index dc1af15030c..09f33650d90 100644 --- a/src/include/common/saslprep.h +++ b/src/include/common/saslprep.h @@ -5,7 +5,7 @@ * * These definitions are used by both frontend and backend code. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/common/saslprep.h * diff --git a/src/include/common/scram-common.h b/src/include/common/scram-common.h index 17373cce3ae..d52df67ec8b 100644 --- a/src/include/common/scram-common.h +++ b/src/include/common/scram-common.h @@ -3,7 +3,7 @@ * scram-common.h * Declarations for helper functions used for SCRAM authentication * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/scram-common.h @@ -17,11 +17,7 @@ /* Name of SCRAM mechanisms per IANA */ #define SCRAM_SHA_256_NAME "SCRAM-SHA-256" -#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */ - -/* Channel binding types */ -#define SCRAM_CHANNEL_BINDING_TLS_UNIQUE "tls-unique" -#define SCRAM_CHANNEL_BINDING_TLS_END_POINT "tls-server-end-point" +#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */ /* Length of SCRAM keys (client and server) */ #define SCRAM_KEY_LEN PG_SHA256_DIGEST_LENGTH @@ -63,12 +59,12 @@ extern void scram_HMAC_update(scram_HMAC_ctx *ctx, const char *str, int slen); extern void scram_HMAC_final(uint8 *result, scram_HMAC_ctx *ctx); extern void scram_SaltedPassword(const char *password, const char *salt, - int saltlen, int iterations, uint8 *result); + int saltlen, int iterations, uint8 *result); extern void scram_H(const uint8 *str, int len, uint8 *result); extern void scram_ClientKey(const uint8 *salted_password, uint8 *result); extern void scram_ServerKey(const uint8 *salted_password, uint8 *result); extern char *scram_build_verifier(const char *salt, int saltlen, int iterations, - const char *password); + const char *password); #endif /* SCRAM_COMMON_H */ diff --git a/src/include/common/sha2.h b/src/include/common/sha2.h index f3fd0d0d28a..cd3da8eccdc 100644 --- a/src/include/common/sha2.h +++ b/src/include/common/sha2.h @@ -3,7 +3,7 @@ * sha2.h * Generic headers for SHA224, 256, 384 AND 512 functions of PostgreSQL. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/common/sha2.h @@ -50,7 +50,7 @@ #ifndef _PG_SHA2_H_ #define _PG_SHA2_H_ -#ifdef USE_SSL +#ifdef USE_OPENSSL #include #endif @@ -69,7 +69,7 @@ #define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1) /* Context Structures for SHA-1/224/256/384/512 */ -#ifdef USE_SSL +#ifdef USE_OPENSSL typedef SHA256_CTX pg_sha256_ctx; typedef SHA512_CTX pg_sha512_ctx; typedef SHA256_CTX pg_sha224_ctx; @@ -89,27 +89,27 @@ typedef struct pg_sha512_ctx } pg_sha512_ctx; typedef struct pg_sha256_ctx pg_sha224_ctx; typedef struct pg_sha512_ctx pg_sha384_ctx; -#endif /* USE_SSL */ +#endif /* USE_OPENSSL */ /* Interface routines for SHA224/256/384/512 */ extern void pg_sha224_init(pg_sha224_ctx *ctx); extern void pg_sha224_update(pg_sha224_ctx *ctx, const uint8 *input0, - size_t len); + size_t len); extern void pg_sha224_final(pg_sha224_ctx *ctx, uint8 *dest); extern void pg_sha256_init(pg_sha256_ctx *ctx); extern void pg_sha256_update(pg_sha256_ctx *ctx, const uint8 *input0, - size_t len); + size_t len); extern void pg_sha256_final(pg_sha256_ctx *ctx, uint8 *dest); extern void pg_sha384_init(pg_sha384_ctx *ctx); extern void pg_sha384_update(pg_sha384_ctx *ctx, - const uint8 *, size_t len); + const uint8 *, size_t len); extern void pg_sha384_final(pg_sha384_ctx *ctx, uint8 *dest); extern void pg_sha512_init(pg_sha512_ctx *ctx); extern void pg_sha512_update(pg_sha512_ctx *ctx, const uint8 *input0, - size_t len); + size_t len); extern void pg_sha512_final(pg_sha512_ctx *ctx, uint8 *dest); #endif /* _PG_SHA2_H_ */ diff --git a/src/include/common/shortest_dec.h b/src/include/common/shortest_dec.h new file mode 100644 index 00000000000..4c3dcd37cff --- /dev/null +++ b/src/include/common/shortest_dec.h @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------- + * + * Ryu floating-point output. + * + * Portions Copyright (c) 2018-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/common/shortest_dec.h + * + * This is a modification of code taken from github.com/ulfjack/ryu under the + * terms of the Boost license (not the Apache license). The original copyright + * notice follows: + * + * Copyright 2018 Ulf Adams + * + * The contents of this file may be used under the terms of the Apache + * License, Version 2.0. + * + * (See accompanying file LICENSE-Apache or copy at + * http://www.apache.org/licenses/LICENSE-2.0) + * + * Alternatively, the contents of this file may be used under the terms of the + * Boost Software License, Version 1.0. + * + * (See accompanying file LICENSE-Boost or copy at + * https://www.boost.org/LICENSE_1_0.txt) + * + * Unless required by applicable law or agreed to in writing, this software is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. + * + *--------------------------------------------------------------------------- + */ +#ifndef SHORTEST_DEC_H +#define SHORTEST_DEC_H + +/*---- + * The length of 25 comes from: + * + * Case 1: -9.9999999999999999e-299 = 24 bytes, plus 1 for null + * + * Case 2: -0.00099999999999999999 = 23 bytes, plus 1 for null + */ +#define DOUBLE_SHORTEST_DECIMAL_LEN 25 + +int double_to_shortest_decimal_bufn(double f, char *result); +int double_to_shortest_decimal_buf(double f, char *result); +char *double_to_shortest_decimal(double f); + +/* + * The length of 16 comes from: + * + * Case 1: -9.99999999e+29 = 15 bytes, plus 1 for null + * + * Case 2: -0.000999999999 = 15 bytes, plus 1 for null + */ +#define FLOAT_SHORTEST_DECIMAL_LEN 16 + +int float_to_shortest_decimal_bufn(float f, char *result); +int float_to_shortest_decimal_buf(float f, char *result); +char *float_to_shortest_decimal(float f); + +#endif /* SHORTEST_DEC_H */ diff --git a/src/include/common/string.h b/src/include/common/string.h index 63c3e81a644..94f653fdd75 100644 --- a/src/include/common/string.h +++ b/src/include/common/string.h @@ -2,7 +2,7 @@ * string.h * string handling helpers * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/string.h @@ -11,7 +11,9 @@ #define COMMON_STRING_H extern bool pg_str_endswith(const char *str, const char *end); -extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, - int base); +extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, + int base); +extern void pg_clean_ascii(char *str); +extern int pg_strip_crlf(char *str); #endif /* COMMON_STRING_H */ diff --git a/src/include/common/unicode_norm.h b/src/include/common/unicode_norm.h index 34ca2622ec5..99167d29525 100644 --- a/src/include/common/unicode_norm.h +++ b/src/include/common/unicode_norm.h @@ -5,7 +5,7 @@ * * These definitions are used by both frontend and backend code. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/common/unicode_norm.h * diff --git a/src/include/common/unicode_norm_table.h b/src/include/common/unicode_norm_table.h index 3444bc8d802..8b1335ffc9d 100644 --- a/src/include/common/unicode_norm_table.h +++ b/src/include/common/unicode_norm_table.h @@ -3,7 +3,7 @@ * unicode_norm_table.h * Composition table used for Unicode normalization * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/common/unicode_norm_table.h @@ -34,7 +34,7 @@ typedef struct #define DECOMPOSITION_IS_INLINE(x) (((x)->dec_size_flags & DECOMP_INLINE) != 0) /* Table of Unicode codepoints and their decompositions */ -static const pg_unicode_decomposition UnicodeDecompMain[6532] = +static const pg_unicode_decomposition UnicodeDecompMain[6582] = { {0x00A0, 0, 1 | DECOMP_INLINE, 0x0020}, {0x00A8, 0, 2 | DECOMP_NO_COMPOSE, 0}, /* compatibility mapping */ @@ -700,6 +700,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x07F1, 230, 0, 0}, {0x07F2, 220, 0, 0}, {0x07F3, 230, 0, 0}, + {0x07FD, 220, 0, 0}, {0x0816, 230, 0, 0}, {0x0817, 230, 0, 0}, {0x0818, 230, 0, 0}, @@ -724,6 +725,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x0859, 220, 0, 0}, {0x085A, 220, 0, 0}, {0x085B, 220, 0, 0}, + {0x08D3, 220, 0, 0}, {0x08D4, 230, 0, 0}, {0x08D5, 230, 0, 0}, {0x08D6, 230, 0, 0}, @@ -791,6 +793,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x09DC, 0, 2 | DECOMP_NO_COMPOSE, 775}, /* in exclusion list */ {0x09DD, 0, 2 | DECOMP_NO_COMPOSE, 777}, /* in exclusion list */ {0x09DF, 0, 2 | DECOMP_NO_COMPOSE, 779}, /* in exclusion list */ + {0x09FE, 230, 0, 0}, {0x0A33, 0, 2 | DECOMP_NO_COMPOSE, 781}, /* in exclusion list */ {0x0A36, 0, 2 | DECOMP_NO_COMPOSE, 783}, /* in exclusion list */ {0x0A3C, 7, 0, 0}, @@ -824,6 +827,8 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x0CCA, 0, 2, 819}, {0x0CCB, 0, 2, 821}, {0x0CCD, 9, 0, 0}, + {0x0D3B, 9, 0, 0}, + {0x0D3C, 9, 0, 0}, {0x0D4A, 0, 2, 823}, {0x0D4B, 0, 2, 825}, {0x0D4C, 0, 2, 827}, @@ -844,6 +849,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x0EB3, 0, 2 | DECOMP_NO_COMPOSE, 839}, /* compatibility mapping */ {0x0EB8, 118, 0, 0}, {0x0EB9, 118, 0, 0}, + {0x0EBA, 9, 0, 0}, {0x0EC8, 122, 0, 0}, {0x0EC9, 122, 0, 0}, {0x0ECA, 122, 0, 0}, @@ -1139,6 +1145,10 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1DF3, 230, 0, 0}, {0x1DF4, 230, 0, 0}, {0x1DF5, 230, 0, 0}, + {0x1DF6, 232, 0, 0}, + {0x1DF7, 228, 0, 0}, + {0x1DF8, 228, 0, 0}, + {0x1DF9, 220, 0, 0}, {0x1DFB, 230, 0, 0}, {0x1DFC, 233, 0, 0}, {0x1DFD, 220, 0, 0}, @@ -2702,262 +2712,263 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x32FC, 0, 1 | DECOMP_INLINE, 0x30F0}, {0x32FD, 0, 1 | DECOMP_INLINE, 0x30F1}, {0x32FE, 0, 1 | DECOMP_INLINE, 0x30F2}, - {0x3300, 0, 4, 2803}, - {0x3301, 0, 4, 2807}, - {0x3302, 0, 4, 2811}, - {0x3303, 0, 3, 2815}, - {0x3304, 0, 4, 2818}, - {0x3305, 0, 3, 2822}, - {0x3306, 0, 3, 2825}, - {0x3307, 0, 5, 2828}, - {0x3308, 0, 4, 2833}, - {0x3309, 0, 3, 2837}, - {0x330A, 0, 3, 2840}, - {0x330B, 0, 3, 2843}, - {0x330C, 0, 4, 2846}, - {0x330D, 0, 4, 2850}, - {0x330E, 0, 3, 2854}, - {0x330F, 0, 3, 2857}, - {0x3310, 0, 2 | DECOMP_NO_COMPOSE, 2860}, /* compatibility mapping */ - {0x3311, 0, 3, 2862}, - {0x3312, 0, 4, 2865}, - {0x3313, 0, 4, 2869}, - {0x3314, 0, 2 | DECOMP_NO_COMPOSE, 2873}, /* compatibility mapping */ - {0x3315, 0, 5, 2875}, - {0x3316, 0, 6, 2880}, - {0x3317, 0, 5, 2886}, - {0x3318, 0, 3, 2891}, - {0x3319, 0, 5, 2894}, - {0x331A, 0, 5, 2899}, - {0x331B, 0, 4, 2904}, - {0x331C, 0, 3, 2908}, - {0x331D, 0, 3, 2911}, - {0x331E, 0, 3, 2914}, - {0x331F, 0, 4, 2917}, - {0x3320, 0, 5, 2921}, - {0x3321, 0, 4, 2926}, - {0x3322, 0, 3, 2930}, - {0x3323, 0, 3, 2933}, - {0x3324, 0, 3, 2936}, - {0x3325, 0, 2 | DECOMP_NO_COMPOSE, 2939}, /* compatibility mapping */ - {0x3326, 0, 2 | DECOMP_NO_COMPOSE, 2941}, /* compatibility mapping */ - {0x3327, 0, 2 | DECOMP_NO_COMPOSE, 2943}, /* compatibility mapping */ - {0x3328, 0, 2 | DECOMP_NO_COMPOSE, 2945}, /* compatibility mapping */ - {0x3329, 0, 3, 2947}, - {0x332A, 0, 3, 2950}, - {0x332B, 0, 5, 2953}, - {0x332C, 0, 3, 2958}, - {0x332D, 0, 4, 2961}, - {0x332E, 0, 5, 2965}, - {0x332F, 0, 3, 2970}, - {0x3330, 0, 2 | DECOMP_NO_COMPOSE, 2973}, /* compatibility mapping */ - {0x3331, 0, 2 | DECOMP_NO_COMPOSE, 2975}, /* compatibility mapping */ - {0x3332, 0, 5, 2977}, - {0x3333, 0, 4, 2982}, - {0x3334, 0, 5, 2986}, - {0x3335, 0, 3, 2991}, - {0x3336, 0, 5, 2994}, - {0x3337, 0, 2 | DECOMP_NO_COMPOSE, 2999}, /* compatibility mapping */ - {0x3338, 0, 3, 3001}, - {0x3339, 0, 3, 3004}, - {0x333A, 0, 3, 3007}, - {0x333B, 0, 3, 3010}, - {0x333C, 0, 3, 3013}, - {0x333D, 0, 4, 3016}, - {0x333E, 0, 3, 3020}, - {0x333F, 0, 2 | DECOMP_NO_COMPOSE, 3023}, /* compatibility mapping */ - {0x3340, 0, 3, 3025}, - {0x3341, 0, 3, 3028}, - {0x3342, 0, 3, 3031}, - {0x3343, 0, 4, 3034}, - {0x3344, 0, 3, 3038}, - {0x3345, 0, 3, 3041}, - {0x3346, 0, 3, 3044}, - {0x3347, 0, 5, 3047}, - {0x3348, 0, 4, 3052}, - {0x3349, 0, 2 | DECOMP_NO_COMPOSE, 3056}, /* compatibility mapping */ - {0x334A, 0, 5, 3058}, - {0x334B, 0, 2 | DECOMP_NO_COMPOSE, 3063}, /* compatibility mapping */ - {0x334C, 0, 4, 3065}, - {0x334D, 0, 4, 3069}, - {0x334E, 0, 3, 3073}, - {0x334F, 0, 3, 3076}, - {0x3350, 0, 3, 3079}, - {0x3351, 0, 4, 3082}, - {0x3352, 0, 2 | DECOMP_NO_COMPOSE, 3086}, /* compatibility mapping */ - {0x3353, 0, 3, 3088}, - {0x3354, 0, 4, 3091}, - {0x3355, 0, 2 | DECOMP_NO_COMPOSE, 3095}, /* compatibility mapping */ - {0x3356, 0, 5, 3097}, - {0x3357, 0, 3, 3102}, - {0x3358, 0, 2 | DECOMP_NO_COMPOSE, 3105}, /* compatibility mapping */ - {0x3359, 0, 2 | DECOMP_NO_COMPOSE, 3107}, /* compatibility mapping */ - {0x335A, 0, 2 | DECOMP_NO_COMPOSE, 3109}, /* compatibility mapping */ - {0x335B, 0, 2 | DECOMP_NO_COMPOSE, 3111}, /* compatibility mapping */ - {0x335C, 0, 2 | DECOMP_NO_COMPOSE, 3113}, /* compatibility mapping */ - {0x335D, 0, 2 | DECOMP_NO_COMPOSE, 3115}, /* compatibility mapping */ - {0x335E, 0, 2 | DECOMP_NO_COMPOSE, 3117}, /* compatibility mapping */ - {0x335F, 0, 2 | DECOMP_NO_COMPOSE, 3119}, /* compatibility mapping */ - {0x3360, 0, 2 | DECOMP_NO_COMPOSE, 3121}, /* compatibility mapping */ - {0x3361, 0, 2 | DECOMP_NO_COMPOSE, 3123}, /* compatibility mapping */ - {0x3362, 0, 3, 3125}, - {0x3363, 0, 3, 3128}, - {0x3364, 0, 3, 3131}, - {0x3365, 0, 3, 3134}, - {0x3366, 0, 3, 3137}, - {0x3367, 0, 3, 3140}, - {0x3368, 0, 3, 3143}, - {0x3369, 0, 3, 3146}, - {0x336A, 0, 3, 3149}, - {0x336B, 0, 3, 3152}, - {0x336C, 0, 3, 3155}, - {0x336D, 0, 3, 3158}, - {0x336E, 0, 3, 3161}, - {0x336F, 0, 3, 3164}, - {0x3370, 0, 3, 3167}, - {0x3371, 0, 3, 3170}, - {0x3372, 0, 2 | DECOMP_NO_COMPOSE, 3173}, /* compatibility mapping */ - {0x3373, 0, 2 | DECOMP_NO_COMPOSE, 3175}, /* compatibility mapping */ - {0x3374, 0, 3, 3177}, - {0x3375, 0, 2 | DECOMP_NO_COMPOSE, 3180}, /* compatibility mapping */ - {0x3376, 0, 2 | DECOMP_NO_COMPOSE, 3182}, /* compatibility mapping */ - {0x3377, 0, 2 | DECOMP_NO_COMPOSE, 3184}, /* compatibility mapping */ - {0x3378, 0, 3, 3186}, - {0x3379, 0, 3, 3189}, - {0x337A, 0, 2 | DECOMP_NO_COMPOSE, 3192}, /* compatibility mapping */ - {0x337B, 0, 2 | DECOMP_NO_COMPOSE, 3194}, /* compatibility mapping */ - {0x337C, 0, 2 | DECOMP_NO_COMPOSE, 3196}, /* compatibility mapping */ - {0x337D, 0, 2 | DECOMP_NO_COMPOSE, 3198}, /* compatibility mapping */ - {0x337E, 0, 2 | DECOMP_NO_COMPOSE, 3200}, /* compatibility mapping */ - {0x337F, 0, 4, 3202}, - {0x3380, 0, 2 | DECOMP_NO_COMPOSE, 3206}, /* compatibility mapping */ - {0x3381, 0, 2 | DECOMP_NO_COMPOSE, 3208}, /* compatibility mapping */ - {0x3382, 0, 2 | DECOMP_NO_COMPOSE, 3210}, /* compatibility mapping */ - {0x3383, 0, 2 | DECOMP_NO_COMPOSE, 3212}, /* compatibility mapping */ - {0x3384, 0, 2 | DECOMP_NO_COMPOSE, 3214}, /* compatibility mapping */ - {0x3385, 0, 2 | DECOMP_NO_COMPOSE, 3216}, /* compatibility mapping */ - {0x3386, 0, 2 | DECOMP_NO_COMPOSE, 3218}, /* compatibility mapping */ - {0x3387, 0, 2 | DECOMP_NO_COMPOSE, 3220}, /* compatibility mapping */ - {0x3388, 0, 3, 3222}, - {0x3389, 0, 4, 3225}, - {0x338A, 0, 2 | DECOMP_NO_COMPOSE, 3229}, /* compatibility mapping */ - {0x338B, 0, 2 | DECOMP_NO_COMPOSE, 3231}, /* compatibility mapping */ - {0x338C, 0, 2 | DECOMP_NO_COMPOSE, 3233}, /* compatibility mapping */ - {0x338D, 0, 2 | DECOMP_NO_COMPOSE, 3235}, /* compatibility mapping */ - {0x338E, 0, 2 | DECOMP_NO_COMPOSE, 3237}, /* compatibility mapping */ - {0x338F, 0, 2 | DECOMP_NO_COMPOSE, 3239}, /* compatibility mapping */ - {0x3390, 0, 2 | DECOMP_NO_COMPOSE, 3241}, /* compatibility mapping */ - {0x3391, 0, 3, 3243}, - {0x3392, 0, 3, 3246}, - {0x3393, 0, 3, 3249}, - {0x3394, 0, 3, 3252}, - {0x3395, 0, 2 | DECOMP_NO_COMPOSE, 3255}, /* compatibility mapping */ - {0x3396, 0, 2 | DECOMP_NO_COMPOSE, 3257}, /* compatibility mapping */ - {0x3397, 0, 2 | DECOMP_NO_COMPOSE, 3259}, /* compatibility mapping */ - {0x3398, 0, 2 | DECOMP_NO_COMPOSE, 3261}, /* compatibility mapping */ - {0x3399, 0, 2 | DECOMP_NO_COMPOSE, 3263}, /* compatibility mapping */ - {0x339A, 0, 2 | DECOMP_NO_COMPOSE, 3265}, /* compatibility mapping */ - {0x339B, 0, 2 | DECOMP_NO_COMPOSE, 3267}, /* compatibility mapping */ - {0x339C, 0, 2 | DECOMP_NO_COMPOSE, 3269}, /* compatibility mapping */ - {0x339D, 0, 2 | DECOMP_NO_COMPOSE, 3271}, /* compatibility mapping */ - {0x339E, 0, 2 | DECOMP_NO_COMPOSE, 3273}, /* compatibility mapping */ - {0x339F, 0, 3, 3275}, - {0x33A0, 0, 3, 3278}, - {0x33A1, 0, 2 | DECOMP_NO_COMPOSE, 3281}, /* compatibility mapping */ - {0x33A2, 0, 3, 3283}, - {0x33A3, 0, 3, 3286}, - {0x33A4, 0, 3, 3289}, - {0x33A5, 0, 2 | DECOMP_NO_COMPOSE, 3292}, /* compatibility mapping */ - {0x33A6, 0, 3, 3294}, - {0x33A7, 0, 3, 3297}, - {0x33A8, 0, 4, 3300}, - {0x33A9, 0, 2 | DECOMP_NO_COMPOSE, 3304}, /* compatibility mapping */ - {0x33AA, 0, 3, 3306}, - {0x33AB, 0, 3, 3309}, - {0x33AC, 0, 3, 3312}, - {0x33AD, 0, 3, 3315}, - {0x33AE, 0, 5, 3318}, - {0x33AF, 0, 6, 3323}, - {0x33B0, 0, 2 | DECOMP_NO_COMPOSE, 3329}, /* compatibility mapping */ - {0x33B1, 0, 2 | DECOMP_NO_COMPOSE, 3331}, /* compatibility mapping */ - {0x33B2, 0, 2 | DECOMP_NO_COMPOSE, 3333}, /* compatibility mapping */ - {0x33B3, 0, 2 | DECOMP_NO_COMPOSE, 3335}, /* compatibility mapping */ - {0x33B4, 0, 2 | DECOMP_NO_COMPOSE, 3337}, /* compatibility mapping */ - {0x33B5, 0, 2 | DECOMP_NO_COMPOSE, 3339}, /* compatibility mapping */ - {0x33B6, 0, 2 | DECOMP_NO_COMPOSE, 3341}, /* compatibility mapping */ - {0x33B7, 0, 2 | DECOMP_NO_COMPOSE, 3343}, /* compatibility mapping */ - {0x33B8, 0, 2 | DECOMP_NO_COMPOSE, 3345}, /* compatibility mapping */ - {0x33B9, 0, 2 | DECOMP_NO_COMPOSE, 3347}, /* compatibility mapping */ - {0x33BA, 0, 2 | DECOMP_NO_COMPOSE, 3349}, /* compatibility mapping */ - {0x33BB, 0, 2 | DECOMP_NO_COMPOSE, 3351}, /* compatibility mapping */ - {0x33BC, 0, 2 | DECOMP_NO_COMPOSE, 3353}, /* compatibility mapping */ - {0x33BD, 0, 2 | DECOMP_NO_COMPOSE, 3355}, /* compatibility mapping */ - {0x33BE, 0, 2 | DECOMP_NO_COMPOSE, 3357}, /* compatibility mapping */ - {0x33BF, 0, 2 | DECOMP_NO_COMPOSE, 3359}, /* compatibility mapping */ - {0x33C0, 0, 2 | DECOMP_NO_COMPOSE, 3361}, /* compatibility mapping */ - {0x33C1, 0, 2 | DECOMP_NO_COMPOSE, 3363}, /* compatibility mapping */ - {0x33C2, 0, 4, 3365}, - {0x33C3, 0, 2 | DECOMP_NO_COMPOSE, 3369}, /* compatibility mapping */ - {0x33C4, 0, 2 | DECOMP_NO_COMPOSE, 3371}, /* compatibility mapping */ - {0x33C5, 0, 2 | DECOMP_NO_COMPOSE, 3373}, /* compatibility mapping */ - {0x33C6, 0, 4, 3375}, - {0x33C7, 0, 3, 3379}, - {0x33C8, 0, 2 | DECOMP_NO_COMPOSE, 3382}, /* compatibility mapping */ - {0x33C9, 0, 2 | DECOMP_NO_COMPOSE, 3384}, /* compatibility mapping */ - {0x33CA, 0, 2 | DECOMP_NO_COMPOSE, 3386}, /* compatibility mapping */ - {0x33CB, 0, 2 | DECOMP_NO_COMPOSE, 3388}, /* compatibility mapping */ - {0x33CC, 0, 2 | DECOMP_NO_COMPOSE, 3390}, /* compatibility mapping */ - {0x33CD, 0, 2 | DECOMP_NO_COMPOSE, 3392}, /* compatibility mapping */ - {0x33CE, 0, 2 | DECOMP_NO_COMPOSE, 3394}, /* compatibility mapping */ - {0x33CF, 0, 2 | DECOMP_NO_COMPOSE, 3396}, /* compatibility mapping */ - {0x33D0, 0, 2 | DECOMP_NO_COMPOSE, 3398}, /* compatibility mapping */ - {0x33D1, 0, 2 | DECOMP_NO_COMPOSE, 3400}, /* compatibility mapping */ - {0x33D2, 0, 3, 3402}, - {0x33D3, 0, 2 | DECOMP_NO_COMPOSE, 3405}, /* compatibility mapping */ - {0x33D4, 0, 2 | DECOMP_NO_COMPOSE, 3407}, /* compatibility mapping */ - {0x33D5, 0, 3, 3409}, - {0x33D6, 0, 3, 3412}, - {0x33D7, 0, 2 | DECOMP_NO_COMPOSE, 3415}, /* compatibility mapping */ - {0x33D8, 0, 4, 3417}, - {0x33D9, 0, 3, 3421}, - {0x33DA, 0, 2 | DECOMP_NO_COMPOSE, 3424}, /* compatibility mapping */ - {0x33DB, 0, 2 | DECOMP_NO_COMPOSE, 3426}, /* compatibility mapping */ - {0x33DC, 0, 2 | DECOMP_NO_COMPOSE, 3428}, /* compatibility mapping */ - {0x33DD, 0, 2 | DECOMP_NO_COMPOSE, 3430}, /* compatibility mapping */ - {0x33DE, 0, 3, 3432}, - {0x33DF, 0, 3, 3435}, - {0x33E0, 0, 2 | DECOMP_NO_COMPOSE, 3438}, /* compatibility mapping */ - {0x33E1, 0, 2 | DECOMP_NO_COMPOSE, 3440}, /* compatibility mapping */ - {0x33E2, 0, 2 | DECOMP_NO_COMPOSE, 3442}, /* compatibility mapping */ - {0x33E3, 0, 2 | DECOMP_NO_COMPOSE, 3444}, /* compatibility mapping */ - {0x33E4, 0, 2 | DECOMP_NO_COMPOSE, 3446}, /* compatibility mapping */ - {0x33E5, 0, 2 | DECOMP_NO_COMPOSE, 3448}, /* compatibility mapping */ - {0x33E6, 0, 2 | DECOMP_NO_COMPOSE, 3450}, /* compatibility mapping */ - {0x33E7, 0, 2 | DECOMP_NO_COMPOSE, 3452}, /* compatibility mapping */ - {0x33E8, 0, 2 | DECOMP_NO_COMPOSE, 3454}, /* compatibility mapping */ - {0x33E9, 0, 3, 3456}, - {0x33EA, 0, 3, 3459}, - {0x33EB, 0, 3, 3462}, - {0x33EC, 0, 3, 3465}, - {0x33ED, 0, 3, 3468}, - {0x33EE, 0, 3, 3471}, - {0x33EF, 0, 3, 3474}, - {0x33F0, 0, 3, 3477}, - {0x33F1, 0, 3, 3480}, - {0x33F2, 0, 3, 3483}, - {0x33F3, 0, 3, 3486}, - {0x33F4, 0, 3, 3489}, - {0x33F5, 0, 3, 3492}, - {0x33F6, 0, 3, 3495}, - {0x33F7, 0, 3, 3498}, - {0x33F8, 0, 3, 3501}, - {0x33F9, 0, 3, 3504}, - {0x33FA, 0, 3, 3507}, - {0x33FB, 0, 3, 3510}, - {0x33FC, 0, 3, 3513}, - {0x33FD, 0, 3, 3516}, - {0x33FE, 0, 3, 3519}, - {0x33FF, 0, 3, 3522}, + {0x32FF, 0, 2 | DECOMP_NO_COMPOSE, 2803}, /* compatibility mapping */ + {0x3300, 0, 4, 2805}, + {0x3301, 0, 4, 2809}, + {0x3302, 0, 4, 2813}, + {0x3303, 0, 3, 2817}, + {0x3304, 0, 4, 2820}, + {0x3305, 0, 3, 2824}, + {0x3306, 0, 3, 2827}, + {0x3307, 0, 5, 2830}, + {0x3308, 0, 4, 2835}, + {0x3309, 0, 3, 2839}, + {0x330A, 0, 3, 2842}, + {0x330B, 0, 3, 2845}, + {0x330C, 0, 4, 2848}, + {0x330D, 0, 4, 2852}, + {0x330E, 0, 3, 2856}, + {0x330F, 0, 3, 2859}, + {0x3310, 0, 2 | DECOMP_NO_COMPOSE, 2862}, /* compatibility mapping */ + {0x3311, 0, 3, 2864}, + {0x3312, 0, 4, 2867}, + {0x3313, 0, 4, 2871}, + {0x3314, 0, 2 | DECOMP_NO_COMPOSE, 2875}, /* compatibility mapping */ + {0x3315, 0, 5, 2877}, + {0x3316, 0, 6, 2882}, + {0x3317, 0, 5, 2888}, + {0x3318, 0, 3, 2893}, + {0x3319, 0, 5, 2896}, + {0x331A, 0, 5, 2901}, + {0x331B, 0, 4, 2906}, + {0x331C, 0, 3, 2910}, + {0x331D, 0, 3, 2913}, + {0x331E, 0, 3, 2916}, + {0x331F, 0, 4, 2919}, + {0x3320, 0, 5, 2923}, + {0x3321, 0, 4, 2928}, + {0x3322, 0, 3, 2932}, + {0x3323, 0, 3, 2935}, + {0x3324, 0, 3, 2938}, + {0x3325, 0, 2 | DECOMP_NO_COMPOSE, 2941}, /* compatibility mapping */ + {0x3326, 0, 2 | DECOMP_NO_COMPOSE, 2943}, /* compatibility mapping */ + {0x3327, 0, 2 | DECOMP_NO_COMPOSE, 2945}, /* compatibility mapping */ + {0x3328, 0, 2 | DECOMP_NO_COMPOSE, 2947}, /* compatibility mapping */ + {0x3329, 0, 3, 2949}, + {0x332A, 0, 3, 2952}, + {0x332B, 0, 5, 2955}, + {0x332C, 0, 3, 2960}, + {0x332D, 0, 4, 2963}, + {0x332E, 0, 5, 2967}, + {0x332F, 0, 3, 2972}, + {0x3330, 0, 2 | DECOMP_NO_COMPOSE, 2975}, /* compatibility mapping */ + {0x3331, 0, 2 | DECOMP_NO_COMPOSE, 2977}, /* compatibility mapping */ + {0x3332, 0, 5, 2979}, + {0x3333, 0, 4, 2984}, + {0x3334, 0, 5, 2988}, + {0x3335, 0, 3, 2993}, + {0x3336, 0, 5, 2996}, + {0x3337, 0, 2 | DECOMP_NO_COMPOSE, 3001}, /* compatibility mapping */ + {0x3338, 0, 3, 3003}, + {0x3339, 0, 3, 3006}, + {0x333A, 0, 3, 3009}, + {0x333B, 0, 3, 3012}, + {0x333C, 0, 3, 3015}, + {0x333D, 0, 4, 3018}, + {0x333E, 0, 3, 3022}, + {0x333F, 0, 2 | DECOMP_NO_COMPOSE, 3025}, /* compatibility mapping */ + {0x3340, 0, 3, 3027}, + {0x3341, 0, 3, 3030}, + {0x3342, 0, 3, 3033}, + {0x3343, 0, 4, 3036}, + {0x3344, 0, 3, 3040}, + {0x3345, 0, 3, 3043}, + {0x3346, 0, 3, 3046}, + {0x3347, 0, 5, 3049}, + {0x3348, 0, 4, 3054}, + {0x3349, 0, 2 | DECOMP_NO_COMPOSE, 3058}, /* compatibility mapping */ + {0x334A, 0, 5, 3060}, + {0x334B, 0, 2 | DECOMP_NO_COMPOSE, 3065}, /* compatibility mapping */ + {0x334C, 0, 4, 3067}, + {0x334D, 0, 4, 3071}, + {0x334E, 0, 3, 3075}, + {0x334F, 0, 3, 3078}, + {0x3350, 0, 3, 3081}, + {0x3351, 0, 4, 3084}, + {0x3352, 0, 2 | DECOMP_NO_COMPOSE, 3088}, /* compatibility mapping */ + {0x3353, 0, 3, 3090}, + {0x3354, 0, 4, 3093}, + {0x3355, 0, 2 | DECOMP_NO_COMPOSE, 3097}, /* compatibility mapping */ + {0x3356, 0, 5, 3099}, + {0x3357, 0, 3, 3104}, + {0x3358, 0, 2 | DECOMP_NO_COMPOSE, 3107}, /* compatibility mapping */ + {0x3359, 0, 2 | DECOMP_NO_COMPOSE, 3109}, /* compatibility mapping */ + {0x335A, 0, 2 | DECOMP_NO_COMPOSE, 3111}, /* compatibility mapping */ + {0x335B, 0, 2 | DECOMP_NO_COMPOSE, 3113}, /* compatibility mapping */ + {0x335C, 0, 2 | DECOMP_NO_COMPOSE, 3115}, /* compatibility mapping */ + {0x335D, 0, 2 | DECOMP_NO_COMPOSE, 3117}, /* compatibility mapping */ + {0x335E, 0, 2 | DECOMP_NO_COMPOSE, 3119}, /* compatibility mapping */ + {0x335F, 0, 2 | DECOMP_NO_COMPOSE, 3121}, /* compatibility mapping */ + {0x3360, 0, 2 | DECOMP_NO_COMPOSE, 3123}, /* compatibility mapping */ + {0x3361, 0, 2 | DECOMP_NO_COMPOSE, 3125}, /* compatibility mapping */ + {0x3362, 0, 3, 3127}, + {0x3363, 0, 3, 3130}, + {0x3364, 0, 3, 3133}, + {0x3365, 0, 3, 3136}, + {0x3366, 0, 3, 3139}, + {0x3367, 0, 3, 3142}, + {0x3368, 0, 3, 3145}, + {0x3369, 0, 3, 3148}, + {0x336A, 0, 3, 3151}, + {0x336B, 0, 3, 3154}, + {0x336C, 0, 3, 3157}, + {0x336D, 0, 3, 3160}, + {0x336E, 0, 3, 3163}, + {0x336F, 0, 3, 3166}, + {0x3370, 0, 3, 3169}, + {0x3371, 0, 3, 3172}, + {0x3372, 0, 2 | DECOMP_NO_COMPOSE, 3175}, /* compatibility mapping */ + {0x3373, 0, 2 | DECOMP_NO_COMPOSE, 3177}, /* compatibility mapping */ + {0x3374, 0, 3, 3179}, + {0x3375, 0, 2 | DECOMP_NO_COMPOSE, 3182}, /* compatibility mapping */ + {0x3376, 0, 2 | DECOMP_NO_COMPOSE, 3184}, /* compatibility mapping */ + {0x3377, 0, 2 | DECOMP_NO_COMPOSE, 3186}, /* compatibility mapping */ + {0x3378, 0, 3, 3188}, + {0x3379, 0, 3, 3191}, + {0x337A, 0, 2 | DECOMP_NO_COMPOSE, 3194}, /* compatibility mapping */ + {0x337B, 0, 2 | DECOMP_NO_COMPOSE, 3196}, /* compatibility mapping */ + {0x337C, 0, 2 | DECOMP_NO_COMPOSE, 3198}, /* compatibility mapping */ + {0x337D, 0, 2 | DECOMP_NO_COMPOSE, 3200}, /* compatibility mapping */ + {0x337E, 0, 2 | DECOMP_NO_COMPOSE, 3202}, /* compatibility mapping */ + {0x337F, 0, 4, 3204}, + {0x3380, 0, 2 | DECOMP_NO_COMPOSE, 3208}, /* compatibility mapping */ + {0x3381, 0, 2 | DECOMP_NO_COMPOSE, 3210}, /* compatibility mapping */ + {0x3382, 0, 2 | DECOMP_NO_COMPOSE, 3212}, /* compatibility mapping */ + {0x3383, 0, 2 | DECOMP_NO_COMPOSE, 3214}, /* compatibility mapping */ + {0x3384, 0, 2 | DECOMP_NO_COMPOSE, 3216}, /* compatibility mapping */ + {0x3385, 0, 2 | DECOMP_NO_COMPOSE, 3218}, /* compatibility mapping */ + {0x3386, 0, 2 | DECOMP_NO_COMPOSE, 3220}, /* compatibility mapping */ + {0x3387, 0, 2 | DECOMP_NO_COMPOSE, 3222}, /* compatibility mapping */ + {0x3388, 0, 3, 3224}, + {0x3389, 0, 4, 3227}, + {0x338A, 0, 2 | DECOMP_NO_COMPOSE, 3231}, /* compatibility mapping */ + {0x338B, 0, 2 | DECOMP_NO_COMPOSE, 3233}, /* compatibility mapping */ + {0x338C, 0, 2 | DECOMP_NO_COMPOSE, 3235}, /* compatibility mapping */ + {0x338D, 0, 2 | DECOMP_NO_COMPOSE, 3237}, /* compatibility mapping */ + {0x338E, 0, 2 | DECOMP_NO_COMPOSE, 3239}, /* compatibility mapping */ + {0x338F, 0, 2 | DECOMP_NO_COMPOSE, 3241}, /* compatibility mapping */ + {0x3390, 0, 2 | DECOMP_NO_COMPOSE, 3243}, /* compatibility mapping */ + {0x3391, 0, 3, 3245}, + {0x3392, 0, 3, 3248}, + {0x3393, 0, 3, 3251}, + {0x3394, 0, 3, 3254}, + {0x3395, 0, 2 | DECOMP_NO_COMPOSE, 3257}, /* compatibility mapping */ + {0x3396, 0, 2 | DECOMP_NO_COMPOSE, 3259}, /* compatibility mapping */ + {0x3397, 0, 2 | DECOMP_NO_COMPOSE, 3261}, /* compatibility mapping */ + {0x3398, 0, 2 | DECOMP_NO_COMPOSE, 3263}, /* compatibility mapping */ + {0x3399, 0, 2 | DECOMP_NO_COMPOSE, 3265}, /* compatibility mapping */ + {0x339A, 0, 2 | DECOMP_NO_COMPOSE, 3267}, /* compatibility mapping */ + {0x339B, 0, 2 | DECOMP_NO_COMPOSE, 3269}, /* compatibility mapping */ + {0x339C, 0, 2 | DECOMP_NO_COMPOSE, 3271}, /* compatibility mapping */ + {0x339D, 0, 2 | DECOMP_NO_COMPOSE, 3273}, /* compatibility mapping */ + {0x339E, 0, 2 | DECOMP_NO_COMPOSE, 3275}, /* compatibility mapping */ + {0x339F, 0, 3, 3277}, + {0x33A0, 0, 3, 3280}, + {0x33A1, 0, 2 | DECOMP_NO_COMPOSE, 3283}, /* compatibility mapping */ + {0x33A2, 0, 3, 3285}, + {0x33A3, 0, 3, 3288}, + {0x33A4, 0, 3, 3291}, + {0x33A5, 0, 2 | DECOMP_NO_COMPOSE, 3294}, /* compatibility mapping */ + {0x33A6, 0, 3, 3296}, + {0x33A7, 0, 3, 3299}, + {0x33A8, 0, 4, 3302}, + {0x33A9, 0, 2 | DECOMP_NO_COMPOSE, 3306}, /* compatibility mapping */ + {0x33AA, 0, 3, 3308}, + {0x33AB, 0, 3, 3311}, + {0x33AC, 0, 3, 3314}, + {0x33AD, 0, 3, 3317}, + {0x33AE, 0, 5, 3320}, + {0x33AF, 0, 6, 3325}, + {0x33B0, 0, 2 | DECOMP_NO_COMPOSE, 3331}, /* compatibility mapping */ + {0x33B1, 0, 2 | DECOMP_NO_COMPOSE, 3333}, /* compatibility mapping */ + {0x33B2, 0, 2 | DECOMP_NO_COMPOSE, 3335}, /* compatibility mapping */ + {0x33B3, 0, 2 | DECOMP_NO_COMPOSE, 3337}, /* compatibility mapping */ + {0x33B4, 0, 2 | DECOMP_NO_COMPOSE, 3339}, /* compatibility mapping */ + {0x33B5, 0, 2 | DECOMP_NO_COMPOSE, 3341}, /* compatibility mapping */ + {0x33B6, 0, 2 | DECOMP_NO_COMPOSE, 3343}, /* compatibility mapping */ + {0x33B7, 0, 2 | DECOMP_NO_COMPOSE, 3345}, /* compatibility mapping */ + {0x33B8, 0, 2 | DECOMP_NO_COMPOSE, 3347}, /* compatibility mapping */ + {0x33B9, 0, 2 | DECOMP_NO_COMPOSE, 3349}, /* compatibility mapping */ + {0x33BA, 0, 2 | DECOMP_NO_COMPOSE, 3351}, /* compatibility mapping */ + {0x33BB, 0, 2 | DECOMP_NO_COMPOSE, 3353}, /* compatibility mapping */ + {0x33BC, 0, 2 | DECOMP_NO_COMPOSE, 3355}, /* compatibility mapping */ + {0x33BD, 0, 2 | DECOMP_NO_COMPOSE, 3357}, /* compatibility mapping */ + {0x33BE, 0, 2 | DECOMP_NO_COMPOSE, 3359}, /* compatibility mapping */ + {0x33BF, 0, 2 | DECOMP_NO_COMPOSE, 3361}, /* compatibility mapping */ + {0x33C0, 0, 2 | DECOMP_NO_COMPOSE, 3363}, /* compatibility mapping */ + {0x33C1, 0, 2 | DECOMP_NO_COMPOSE, 3365}, /* compatibility mapping */ + {0x33C2, 0, 4, 3367}, + {0x33C3, 0, 2 | DECOMP_NO_COMPOSE, 3371}, /* compatibility mapping */ + {0x33C4, 0, 2 | DECOMP_NO_COMPOSE, 3373}, /* compatibility mapping */ + {0x33C5, 0, 2 | DECOMP_NO_COMPOSE, 3375}, /* compatibility mapping */ + {0x33C6, 0, 4, 3377}, + {0x33C7, 0, 3, 3381}, + {0x33C8, 0, 2 | DECOMP_NO_COMPOSE, 3384}, /* compatibility mapping */ + {0x33C9, 0, 2 | DECOMP_NO_COMPOSE, 3386}, /* compatibility mapping */ + {0x33CA, 0, 2 | DECOMP_NO_COMPOSE, 3388}, /* compatibility mapping */ + {0x33CB, 0, 2 | DECOMP_NO_COMPOSE, 3390}, /* compatibility mapping */ + {0x33CC, 0, 2 | DECOMP_NO_COMPOSE, 3392}, /* compatibility mapping */ + {0x33CD, 0, 2 | DECOMP_NO_COMPOSE, 3394}, /* compatibility mapping */ + {0x33CE, 0, 2 | DECOMP_NO_COMPOSE, 3396}, /* compatibility mapping */ + {0x33CF, 0, 2 | DECOMP_NO_COMPOSE, 3398}, /* compatibility mapping */ + {0x33D0, 0, 2 | DECOMP_NO_COMPOSE, 3400}, /* compatibility mapping */ + {0x33D1, 0, 2 | DECOMP_NO_COMPOSE, 3402}, /* compatibility mapping */ + {0x33D2, 0, 3, 3404}, + {0x33D3, 0, 2 | DECOMP_NO_COMPOSE, 3407}, /* compatibility mapping */ + {0x33D4, 0, 2 | DECOMP_NO_COMPOSE, 3409}, /* compatibility mapping */ + {0x33D5, 0, 3, 3411}, + {0x33D6, 0, 3, 3414}, + {0x33D7, 0, 2 | DECOMP_NO_COMPOSE, 3417}, /* compatibility mapping */ + {0x33D8, 0, 4, 3419}, + {0x33D9, 0, 3, 3423}, + {0x33DA, 0, 2 | DECOMP_NO_COMPOSE, 3426}, /* compatibility mapping */ + {0x33DB, 0, 2 | DECOMP_NO_COMPOSE, 3428}, /* compatibility mapping */ + {0x33DC, 0, 2 | DECOMP_NO_COMPOSE, 3430}, /* compatibility mapping */ + {0x33DD, 0, 2 | DECOMP_NO_COMPOSE, 3432}, /* compatibility mapping */ + {0x33DE, 0, 3, 3434}, + {0x33DF, 0, 3, 3437}, + {0x33E0, 0, 2 | DECOMP_NO_COMPOSE, 3440}, /* compatibility mapping */ + {0x33E1, 0, 2 | DECOMP_NO_COMPOSE, 3442}, /* compatibility mapping */ + {0x33E2, 0, 2 | DECOMP_NO_COMPOSE, 3444}, /* compatibility mapping */ + {0x33E3, 0, 2 | DECOMP_NO_COMPOSE, 3446}, /* compatibility mapping */ + {0x33E4, 0, 2 | DECOMP_NO_COMPOSE, 3448}, /* compatibility mapping */ + {0x33E5, 0, 2 | DECOMP_NO_COMPOSE, 3450}, /* compatibility mapping */ + {0x33E6, 0, 2 | DECOMP_NO_COMPOSE, 3452}, /* compatibility mapping */ + {0x33E7, 0, 2 | DECOMP_NO_COMPOSE, 3454}, /* compatibility mapping */ + {0x33E8, 0, 2 | DECOMP_NO_COMPOSE, 3456}, /* compatibility mapping */ + {0x33E9, 0, 3, 3458}, + {0x33EA, 0, 3, 3461}, + {0x33EB, 0, 3, 3464}, + {0x33EC, 0, 3, 3467}, + {0x33ED, 0, 3, 3470}, + {0x33EE, 0, 3, 3473}, + {0x33EF, 0, 3, 3476}, + {0x33F0, 0, 3, 3479}, + {0x33F1, 0, 3, 3482}, + {0x33F2, 0, 3, 3485}, + {0x33F3, 0, 3, 3488}, + {0x33F4, 0, 3, 3491}, + {0x33F5, 0, 3, 3494}, + {0x33F6, 0, 3, 3497}, + {0x33F7, 0, 3, 3500}, + {0x33F8, 0, 3, 3503}, + {0x33F9, 0, 3, 3506}, + {0x33FA, 0, 3, 3509}, + {0x33FB, 0, 3, 3512}, + {0x33FC, 0, 3, 3515}, + {0x33FD, 0, 3, 3518}, + {0x33FE, 0, 3, 3521}, + {0x33FF, 0, 3, 3524}, {0xA66F, 230, 0, 0}, {0xA674, 230, 0, 0}, {0xA675, 230, 0, 0}, @@ -3371,7 +3382,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFA69, 0, 1 | DECOMP_INLINE, 0x97FF}, {0xFA6A, 0, 1 | DECOMP_INLINE, 0x983B}, {0xFA6B, 0, 1 | DECOMP_INLINE, 0x6075}, - {0xFA6C, 0, 1, 3525}, + {0xFA6C, 0, 1, 3527}, {0xFA6D, 0, 1 | DECOMP_INLINE, 0x8218}, {0xFA70, 0, 1 | DECOMP_INLINE, 0x4E26}, {0xFA71, 0, 1 | DECOMP_INLINE, 0x51B5}, @@ -3468,32 +3479,32 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFACC, 0, 1 | DECOMP_INLINE, 0x983B}, {0xFACD, 0, 1 | DECOMP_INLINE, 0x9B12}, {0xFACE, 0, 1 | DECOMP_INLINE, 0x9F9C}, - {0xFACF, 0, 1, 3526}, - {0xFAD0, 0, 1, 3527}, - {0xFAD1, 0, 1, 3528}, + {0xFACF, 0, 1, 3528}, + {0xFAD0, 0, 1, 3529}, + {0xFAD1, 0, 1, 3530}, {0xFAD2, 0, 1 | DECOMP_INLINE, 0x3B9D}, {0xFAD3, 0, 1 | DECOMP_INLINE, 0x4018}, {0xFAD4, 0, 1 | DECOMP_INLINE, 0x4039}, - {0xFAD5, 0, 1, 3529}, - {0xFAD6, 0, 1, 3530}, - {0xFAD7, 0, 1, 3531}, + {0xFAD5, 0, 1, 3531}, + {0xFAD6, 0, 1, 3532}, + {0xFAD7, 0, 1, 3533}, {0xFAD8, 0, 1 | DECOMP_INLINE, 0x9F43}, {0xFAD9, 0, 1 | DECOMP_INLINE, 0x9F8E}, - {0xFB00, 0, 2 | DECOMP_NO_COMPOSE, 3532}, /* compatibility mapping */ - {0xFB01, 0, 2 | DECOMP_NO_COMPOSE, 3534}, /* compatibility mapping */ - {0xFB02, 0, 2 | DECOMP_NO_COMPOSE, 3536}, /* compatibility mapping */ - {0xFB03, 0, 3, 3538}, - {0xFB04, 0, 3, 3541}, - {0xFB05, 0, 2 | DECOMP_NO_COMPOSE, 3544}, /* compatibility mapping */ - {0xFB06, 0, 2 | DECOMP_NO_COMPOSE, 3546}, /* compatibility mapping */ - {0xFB13, 0, 2 | DECOMP_NO_COMPOSE, 3548}, /* compatibility mapping */ - {0xFB14, 0, 2 | DECOMP_NO_COMPOSE, 3550}, /* compatibility mapping */ - {0xFB15, 0, 2 | DECOMP_NO_COMPOSE, 3552}, /* compatibility mapping */ - {0xFB16, 0, 2 | DECOMP_NO_COMPOSE, 3554}, /* compatibility mapping */ - {0xFB17, 0, 2 | DECOMP_NO_COMPOSE, 3556}, /* compatibility mapping */ - {0xFB1D, 0, 2 | DECOMP_NO_COMPOSE, 3558}, /* in exclusion list */ + {0xFB00, 0, 2 | DECOMP_NO_COMPOSE, 3534}, /* compatibility mapping */ + {0xFB01, 0, 2 | DECOMP_NO_COMPOSE, 3536}, /* compatibility mapping */ + {0xFB02, 0, 2 | DECOMP_NO_COMPOSE, 3538}, /* compatibility mapping */ + {0xFB03, 0, 3, 3540}, + {0xFB04, 0, 3, 3543}, + {0xFB05, 0, 2 | DECOMP_NO_COMPOSE, 3546}, /* compatibility mapping */ + {0xFB06, 0, 2 | DECOMP_NO_COMPOSE, 3548}, /* compatibility mapping */ + {0xFB13, 0, 2 | DECOMP_NO_COMPOSE, 3550}, /* compatibility mapping */ + {0xFB14, 0, 2 | DECOMP_NO_COMPOSE, 3552}, /* compatibility mapping */ + {0xFB15, 0, 2 | DECOMP_NO_COMPOSE, 3554}, /* compatibility mapping */ + {0xFB16, 0, 2 | DECOMP_NO_COMPOSE, 3556}, /* compatibility mapping */ + {0xFB17, 0, 2 | DECOMP_NO_COMPOSE, 3558}, /* compatibility mapping */ + {0xFB1D, 0, 2 | DECOMP_NO_COMPOSE, 3560}, /* in exclusion list */ {0xFB1E, 26, 0, 0}, - {0xFB1F, 0, 2 | DECOMP_NO_COMPOSE, 3560}, /* in exclusion list */ + {0xFB1F, 0, 2 | DECOMP_NO_COMPOSE, 3562}, /* in exclusion list */ {0xFB20, 0, 1 | DECOMP_INLINE, 0x05E2}, {0xFB21, 0, 1 | DECOMP_INLINE, 0x05D0}, {0xFB22, 0, 1 | DECOMP_INLINE, 0x05D3}, @@ -3504,39 +3515,39 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFB27, 0, 1 | DECOMP_INLINE, 0x05E8}, {0xFB28, 0, 1 | DECOMP_INLINE, 0x05EA}, {0xFB29, 0, 1 | DECOMP_INLINE, 0x002B}, - {0xFB2A, 0, 2 | DECOMP_NO_COMPOSE, 3562}, /* in exclusion list */ - {0xFB2B, 0, 2 | DECOMP_NO_COMPOSE, 3564}, /* in exclusion list */ - {0xFB2C, 0, 2 | DECOMP_NO_COMPOSE, 3566}, /* in exclusion list */ - {0xFB2D, 0, 2 | DECOMP_NO_COMPOSE, 3568}, /* in exclusion list */ - {0xFB2E, 0, 2 | DECOMP_NO_COMPOSE, 3570}, /* in exclusion list */ - {0xFB2F, 0, 2 | DECOMP_NO_COMPOSE, 3572}, /* in exclusion list */ - {0xFB30, 0, 2 | DECOMP_NO_COMPOSE, 3574}, /* in exclusion list */ - {0xFB31, 0, 2 | DECOMP_NO_COMPOSE, 3576}, /* in exclusion list */ - {0xFB32, 0, 2 | DECOMP_NO_COMPOSE, 3578}, /* in exclusion list */ - {0xFB33, 0, 2 | DECOMP_NO_COMPOSE, 3580}, /* in exclusion list */ - {0xFB34, 0, 2 | DECOMP_NO_COMPOSE, 3582}, /* in exclusion list */ - {0xFB35, 0, 2 | DECOMP_NO_COMPOSE, 3584}, /* in exclusion list */ - {0xFB36, 0, 2 | DECOMP_NO_COMPOSE, 3586}, /* in exclusion list */ - {0xFB38, 0, 2 | DECOMP_NO_COMPOSE, 3588}, /* in exclusion list */ - {0xFB39, 0, 2 | DECOMP_NO_COMPOSE, 3590}, /* in exclusion list */ - {0xFB3A, 0, 2 | DECOMP_NO_COMPOSE, 3592}, /* in exclusion list */ - {0xFB3B, 0, 2 | DECOMP_NO_COMPOSE, 3594}, /* in exclusion list */ - {0xFB3C, 0, 2 | DECOMP_NO_COMPOSE, 3596}, /* in exclusion list */ - {0xFB3E, 0, 2 | DECOMP_NO_COMPOSE, 3598}, /* in exclusion list */ - {0xFB40, 0, 2 | DECOMP_NO_COMPOSE, 3600}, /* in exclusion list */ - {0xFB41, 0, 2 | DECOMP_NO_COMPOSE, 3602}, /* in exclusion list */ - {0xFB43, 0, 2 | DECOMP_NO_COMPOSE, 3604}, /* in exclusion list */ - {0xFB44, 0, 2 | DECOMP_NO_COMPOSE, 3606}, /* in exclusion list */ - {0xFB46, 0, 2 | DECOMP_NO_COMPOSE, 3608}, /* in exclusion list */ - {0xFB47, 0, 2 | DECOMP_NO_COMPOSE, 3610}, /* in exclusion list */ - {0xFB48, 0, 2 | DECOMP_NO_COMPOSE, 3612}, /* in exclusion list */ - {0xFB49, 0, 2 | DECOMP_NO_COMPOSE, 3614}, /* in exclusion list */ - {0xFB4A, 0, 2 | DECOMP_NO_COMPOSE, 3616}, /* in exclusion list */ - {0xFB4B, 0, 2 | DECOMP_NO_COMPOSE, 3618}, /* in exclusion list */ - {0xFB4C, 0, 2 | DECOMP_NO_COMPOSE, 3620}, /* in exclusion list */ - {0xFB4D, 0, 2 | DECOMP_NO_COMPOSE, 3622}, /* in exclusion list */ - {0xFB4E, 0, 2 | DECOMP_NO_COMPOSE, 3624}, /* in exclusion list */ - {0xFB4F, 0, 2 | DECOMP_NO_COMPOSE, 3626}, /* compatibility mapping */ + {0xFB2A, 0, 2 | DECOMP_NO_COMPOSE, 3564}, /* in exclusion list */ + {0xFB2B, 0, 2 | DECOMP_NO_COMPOSE, 3566}, /* in exclusion list */ + {0xFB2C, 0, 2 | DECOMP_NO_COMPOSE, 3568}, /* in exclusion list */ + {0xFB2D, 0, 2 | DECOMP_NO_COMPOSE, 3570}, /* in exclusion list */ + {0xFB2E, 0, 2 | DECOMP_NO_COMPOSE, 3572}, /* in exclusion list */ + {0xFB2F, 0, 2 | DECOMP_NO_COMPOSE, 3574}, /* in exclusion list */ + {0xFB30, 0, 2 | DECOMP_NO_COMPOSE, 3576}, /* in exclusion list */ + {0xFB31, 0, 2 | DECOMP_NO_COMPOSE, 3578}, /* in exclusion list */ + {0xFB32, 0, 2 | DECOMP_NO_COMPOSE, 3580}, /* in exclusion list */ + {0xFB33, 0, 2 | DECOMP_NO_COMPOSE, 3582}, /* in exclusion list */ + {0xFB34, 0, 2 | DECOMP_NO_COMPOSE, 3584}, /* in exclusion list */ + {0xFB35, 0, 2 | DECOMP_NO_COMPOSE, 3586}, /* in exclusion list */ + {0xFB36, 0, 2 | DECOMP_NO_COMPOSE, 3588}, /* in exclusion list */ + {0xFB38, 0, 2 | DECOMP_NO_COMPOSE, 3590}, /* in exclusion list */ + {0xFB39, 0, 2 | DECOMP_NO_COMPOSE, 3592}, /* in exclusion list */ + {0xFB3A, 0, 2 | DECOMP_NO_COMPOSE, 3594}, /* in exclusion list */ + {0xFB3B, 0, 2 | DECOMP_NO_COMPOSE, 3596}, /* in exclusion list */ + {0xFB3C, 0, 2 | DECOMP_NO_COMPOSE, 3598}, /* in exclusion list */ + {0xFB3E, 0, 2 | DECOMP_NO_COMPOSE, 3600}, /* in exclusion list */ + {0xFB40, 0, 2 | DECOMP_NO_COMPOSE, 3602}, /* in exclusion list */ + {0xFB41, 0, 2 | DECOMP_NO_COMPOSE, 3604}, /* in exclusion list */ + {0xFB43, 0, 2 | DECOMP_NO_COMPOSE, 3606}, /* in exclusion list */ + {0xFB44, 0, 2 | DECOMP_NO_COMPOSE, 3608}, /* in exclusion list */ + {0xFB46, 0, 2 | DECOMP_NO_COMPOSE, 3610}, /* in exclusion list */ + {0xFB47, 0, 2 | DECOMP_NO_COMPOSE, 3612}, /* in exclusion list */ + {0xFB48, 0, 2 | DECOMP_NO_COMPOSE, 3614}, /* in exclusion list */ + {0xFB49, 0, 2 | DECOMP_NO_COMPOSE, 3616}, /* in exclusion list */ + {0xFB4A, 0, 2 | DECOMP_NO_COMPOSE, 3618}, /* in exclusion list */ + {0xFB4B, 0, 2 | DECOMP_NO_COMPOSE, 3620}, /* in exclusion list */ + {0xFB4C, 0, 2 | DECOMP_NO_COMPOSE, 3622}, /* in exclusion list */ + {0xFB4D, 0, 2 | DECOMP_NO_COMPOSE, 3624}, /* in exclusion list */ + {0xFB4E, 0, 2 | DECOMP_NO_COMPOSE, 3626}, /* in exclusion list */ + {0xFB4F, 0, 2 | DECOMP_NO_COMPOSE, 3628}, /* compatibility mapping */ {0xFB50, 0, 1 | DECOMP_INLINE, 0x0671}, {0xFB51, 0, 1 | DECOMP_INLINE, 0x0671}, {0xFB52, 0, 1 | DECOMP_INLINE, 0x067B}, @@ -3658,477 +3669,477 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFBE7, 0, 1 | DECOMP_INLINE, 0x06D0}, {0xFBE8, 0, 1 | DECOMP_INLINE, 0x0649}, {0xFBE9, 0, 1 | DECOMP_INLINE, 0x0649}, - {0xFBEA, 0, 2 | DECOMP_NO_COMPOSE, 3628}, /* compatibility mapping */ - {0xFBEB, 0, 2 | DECOMP_NO_COMPOSE, 3630}, /* compatibility mapping */ - {0xFBEC, 0, 2 | DECOMP_NO_COMPOSE, 3632}, /* compatibility mapping */ - {0xFBED, 0, 2 | DECOMP_NO_COMPOSE, 3634}, /* compatibility mapping */ - {0xFBEE, 0, 2 | DECOMP_NO_COMPOSE, 3636}, /* compatibility mapping */ - {0xFBEF, 0, 2 | DECOMP_NO_COMPOSE, 3638}, /* compatibility mapping */ - {0xFBF0, 0, 2 | DECOMP_NO_COMPOSE, 3640}, /* compatibility mapping */ - {0xFBF1, 0, 2 | DECOMP_NO_COMPOSE, 3642}, /* compatibility mapping */ - {0xFBF2, 0, 2 | DECOMP_NO_COMPOSE, 3644}, /* compatibility mapping */ - {0xFBF3, 0, 2 | DECOMP_NO_COMPOSE, 3646}, /* compatibility mapping */ - {0xFBF4, 0, 2 | DECOMP_NO_COMPOSE, 3648}, /* compatibility mapping */ - {0xFBF5, 0, 2 | DECOMP_NO_COMPOSE, 3650}, /* compatibility mapping */ - {0xFBF6, 0, 2 | DECOMP_NO_COMPOSE, 3652}, /* compatibility mapping */ - {0xFBF7, 0, 2 | DECOMP_NO_COMPOSE, 3654}, /* compatibility mapping */ - {0xFBF8, 0, 2 | DECOMP_NO_COMPOSE, 3656}, /* compatibility mapping */ - {0xFBF9, 0, 2 | DECOMP_NO_COMPOSE, 3658}, /* compatibility mapping */ - {0xFBFA, 0, 2 | DECOMP_NO_COMPOSE, 3660}, /* compatibility mapping */ - {0xFBFB, 0, 2 | DECOMP_NO_COMPOSE, 3662}, /* compatibility mapping */ + {0xFBEA, 0, 2 | DECOMP_NO_COMPOSE, 3630}, /* compatibility mapping */ + {0xFBEB, 0, 2 | DECOMP_NO_COMPOSE, 3632}, /* compatibility mapping */ + {0xFBEC, 0, 2 | DECOMP_NO_COMPOSE, 3634}, /* compatibility mapping */ + {0xFBED, 0, 2 | DECOMP_NO_COMPOSE, 3636}, /* compatibility mapping */ + {0xFBEE, 0, 2 | DECOMP_NO_COMPOSE, 3638}, /* compatibility mapping */ + {0xFBEF, 0, 2 | DECOMP_NO_COMPOSE, 3640}, /* compatibility mapping */ + {0xFBF0, 0, 2 | DECOMP_NO_COMPOSE, 3642}, /* compatibility mapping */ + {0xFBF1, 0, 2 | DECOMP_NO_COMPOSE, 3644}, /* compatibility mapping */ + {0xFBF2, 0, 2 | DECOMP_NO_COMPOSE, 3646}, /* compatibility mapping */ + {0xFBF3, 0, 2 | DECOMP_NO_COMPOSE, 3648}, /* compatibility mapping */ + {0xFBF4, 0, 2 | DECOMP_NO_COMPOSE, 3650}, /* compatibility mapping */ + {0xFBF5, 0, 2 | DECOMP_NO_COMPOSE, 3652}, /* compatibility mapping */ + {0xFBF6, 0, 2 | DECOMP_NO_COMPOSE, 3654}, /* compatibility mapping */ + {0xFBF7, 0, 2 | DECOMP_NO_COMPOSE, 3656}, /* compatibility mapping */ + {0xFBF8, 0, 2 | DECOMP_NO_COMPOSE, 3658}, /* compatibility mapping */ + {0xFBF9, 0, 2 | DECOMP_NO_COMPOSE, 3660}, /* compatibility mapping */ + {0xFBFA, 0, 2 | DECOMP_NO_COMPOSE, 3662}, /* compatibility mapping */ + {0xFBFB, 0, 2 | DECOMP_NO_COMPOSE, 3664}, /* compatibility mapping */ {0xFBFC, 0, 1 | DECOMP_INLINE, 0x06CC}, {0xFBFD, 0, 1 | DECOMP_INLINE, 0x06CC}, {0xFBFE, 0, 1 | DECOMP_INLINE, 0x06CC}, {0xFBFF, 0, 1 | DECOMP_INLINE, 0x06CC}, - {0xFC00, 0, 2 | DECOMP_NO_COMPOSE, 3664}, /* compatibility mapping */ - {0xFC01, 0, 2 | DECOMP_NO_COMPOSE, 3666}, /* compatibility mapping */ - {0xFC02, 0, 2 | DECOMP_NO_COMPOSE, 3668}, /* compatibility mapping */ - {0xFC03, 0, 2 | DECOMP_NO_COMPOSE, 3670}, /* compatibility mapping */ - {0xFC04, 0, 2 | DECOMP_NO_COMPOSE, 3672}, /* compatibility mapping */ - {0xFC05, 0, 2 | DECOMP_NO_COMPOSE, 3674}, /* compatibility mapping */ - {0xFC06, 0, 2 | DECOMP_NO_COMPOSE, 3676}, /* compatibility mapping */ - {0xFC07, 0, 2 | DECOMP_NO_COMPOSE, 3678}, /* compatibility mapping */ - {0xFC08, 0, 2 | DECOMP_NO_COMPOSE, 3680}, /* compatibility mapping */ - {0xFC09, 0, 2 | DECOMP_NO_COMPOSE, 3682}, /* compatibility mapping */ - {0xFC0A, 0, 2 | DECOMP_NO_COMPOSE, 3684}, /* compatibility mapping */ - {0xFC0B, 0, 2 | DECOMP_NO_COMPOSE, 3686}, /* compatibility mapping */ - {0xFC0C, 0, 2 | DECOMP_NO_COMPOSE, 3688}, /* compatibility mapping */ - {0xFC0D, 0, 2 | DECOMP_NO_COMPOSE, 3690}, /* compatibility mapping */ - {0xFC0E, 0, 2 | DECOMP_NO_COMPOSE, 3692}, /* compatibility mapping */ - {0xFC0F, 0, 2 | DECOMP_NO_COMPOSE, 3694}, /* compatibility mapping */ - {0xFC10, 0, 2 | DECOMP_NO_COMPOSE, 3696}, /* compatibility mapping */ - {0xFC11, 0, 2 | DECOMP_NO_COMPOSE, 3698}, /* compatibility mapping */ - {0xFC12, 0, 2 | DECOMP_NO_COMPOSE, 3700}, /* compatibility mapping */ - {0xFC13, 0, 2 | DECOMP_NO_COMPOSE, 3702}, /* compatibility mapping */ - {0xFC14, 0, 2 | DECOMP_NO_COMPOSE, 3704}, /* compatibility mapping */ - {0xFC15, 0, 2 | DECOMP_NO_COMPOSE, 3706}, /* compatibility mapping */ - {0xFC16, 0, 2 | DECOMP_NO_COMPOSE, 3708}, /* compatibility mapping */ - {0xFC17, 0, 2 | DECOMP_NO_COMPOSE, 3710}, /* compatibility mapping */ - {0xFC18, 0, 2 | DECOMP_NO_COMPOSE, 3712}, /* compatibility mapping */ - {0xFC19, 0, 2 | DECOMP_NO_COMPOSE, 3714}, /* compatibility mapping */ - {0xFC1A, 0, 2 | DECOMP_NO_COMPOSE, 3716}, /* compatibility mapping */ - {0xFC1B, 0, 2 | DECOMP_NO_COMPOSE, 3718}, /* compatibility mapping */ - {0xFC1C, 0, 2 | DECOMP_NO_COMPOSE, 3720}, /* compatibility mapping */ - {0xFC1D, 0, 2 | DECOMP_NO_COMPOSE, 3722}, /* compatibility mapping */ - {0xFC1E, 0, 2 | DECOMP_NO_COMPOSE, 3724}, /* compatibility mapping */ - {0xFC1F, 0, 2 | DECOMP_NO_COMPOSE, 3726}, /* compatibility mapping */ - {0xFC20, 0, 2 | DECOMP_NO_COMPOSE, 3728}, /* compatibility mapping */ - {0xFC21, 0, 2 | DECOMP_NO_COMPOSE, 3730}, /* compatibility mapping */ - {0xFC22, 0, 2 | DECOMP_NO_COMPOSE, 3732}, /* compatibility mapping */ - {0xFC23, 0, 2 | DECOMP_NO_COMPOSE, 3734}, /* compatibility mapping */ - {0xFC24, 0, 2 | DECOMP_NO_COMPOSE, 3736}, /* compatibility mapping */ - {0xFC25, 0, 2 | DECOMP_NO_COMPOSE, 3738}, /* compatibility mapping */ - {0xFC26, 0, 2 | DECOMP_NO_COMPOSE, 3740}, /* compatibility mapping */ - {0xFC27, 0, 2 | DECOMP_NO_COMPOSE, 3742}, /* compatibility mapping */ - {0xFC28, 0, 2 | DECOMP_NO_COMPOSE, 3744}, /* compatibility mapping */ - {0xFC29, 0, 2 | DECOMP_NO_COMPOSE, 3746}, /* compatibility mapping */ - {0xFC2A, 0, 2 | DECOMP_NO_COMPOSE, 3748}, /* compatibility mapping */ - {0xFC2B, 0, 2 | DECOMP_NO_COMPOSE, 3750}, /* compatibility mapping */ - {0xFC2C, 0, 2 | DECOMP_NO_COMPOSE, 3752}, /* compatibility mapping */ - {0xFC2D, 0, 2 | DECOMP_NO_COMPOSE, 3754}, /* compatibility mapping */ - {0xFC2E, 0, 2 | DECOMP_NO_COMPOSE, 3756}, /* compatibility mapping */ - {0xFC2F, 0, 2 | DECOMP_NO_COMPOSE, 3758}, /* compatibility mapping */ - {0xFC30, 0, 2 | DECOMP_NO_COMPOSE, 3760}, /* compatibility mapping */ - {0xFC31, 0, 2 | DECOMP_NO_COMPOSE, 3762}, /* compatibility mapping */ - {0xFC32, 0, 2 | DECOMP_NO_COMPOSE, 3764}, /* compatibility mapping */ - {0xFC33, 0, 2 | DECOMP_NO_COMPOSE, 3766}, /* compatibility mapping */ - {0xFC34, 0, 2 | DECOMP_NO_COMPOSE, 3768}, /* compatibility mapping */ - {0xFC35, 0, 2 | DECOMP_NO_COMPOSE, 3770}, /* compatibility mapping */ - {0xFC36, 0, 2 | DECOMP_NO_COMPOSE, 3772}, /* compatibility mapping */ - {0xFC37, 0, 2 | DECOMP_NO_COMPOSE, 3774}, /* compatibility mapping */ - {0xFC38, 0, 2 | DECOMP_NO_COMPOSE, 3776}, /* compatibility mapping */ - {0xFC39, 0, 2 | DECOMP_NO_COMPOSE, 3778}, /* compatibility mapping */ - {0xFC3A, 0, 2 | DECOMP_NO_COMPOSE, 3780}, /* compatibility mapping */ - {0xFC3B, 0, 2 | DECOMP_NO_COMPOSE, 3782}, /* compatibility mapping */ - {0xFC3C, 0, 2 | DECOMP_NO_COMPOSE, 3784}, /* compatibility mapping */ - {0xFC3D, 0, 2 | DECOMP_NO_COMPOSE, 3786}, /* compatibility mapping */ - {0xFC3E, 0, 2 | DECOMP_NO_COMPOSE, 3788}, /* compatibility mapping */ - {0xFC3F, 0, 2 | DECOMP_NO_COMPOSE, 3790}, /* compatibility mapping */ - {0xFC40, 0, 2 | DECOMP_NO_COMPOSE, 3792}, /* compatibility mapping */ - {0xFC41, 0, 2 | DECOMP_NO_COMPOSE, 3794}, /* compatibility mapping */ - {0xFC42, 0, 2 | DECOMP_NO_COMPOSE, 3796}, /* compatibility mapping */ - {0xFC43, 0, 2 | DECOMP_NO_COMPOSE, 3798}, /* compatibility mapping */ - {0xFC44, 0, 2 | DECOMP_NO_COMPOSE, 3800}, /* compatibility mapping */ - {0xFC45, 0, 2 | DECOMP_NO_COMPOSE, 3802}, /* compatibility mapping */ - {0xFC46, 0, 2 | DECOMP_NO_COMPOSE, 3804}, /* compatibility mapping */ - {0xFC47, 0, 2 | DECOMP_NO_COMPOSE, 3806}, /* compatibility mapping */ - {0xFC48, 0, 2 | DECOMP_NO_COMPOSE, 3808}, /* compatibility mapping */ - {0xFC49, 0, 2 | DECOMP_NO_COMPOSE, 3810}, /* compatibility mapping */ - {0xFC4A, 0, 2 | DECOMP_NO_COMPOSE, 3812}, /* compatibility mapping */ - {0xFC4B, 0, 2 | DECOMP_NO_COMPOSE, 3814}, /* compatibility mapping */ - {0xFC4C, 0, 2 | DECOMP_NO_COMPOSE, 3816}, /* compatibility mapping */ - {0xFC4D, 0, 2 | DECOMP_NO_COMPOSE, 3818}, /* compatibility mapping */ - {0xFC4E, 0, 2 | DECOMP_NO_COMPOSE, 3820}, /* compatibility mapping */ - {0xFC4F, 0, 2 | DECOMP_NO_COMPOSE, 3822}, /* compatibility mapping */ - {0xFC50, 0, 2 | DECOMP_NO_COMPOSE, 3824}, /* compatibility mapping */ - {0xFC51, 0, 2 | DECOMP_NO_COMPOSE, 3826}, /* compatibility mapping */ - {0xFC52, 0, 2 | DECOMP_NO_COMPOSE, 3828}, /* compatibility mapping */ - {0xFC53, 0, 2 | DECOMP_NO_COMPOSE, 3830}, /* compatibility mapping */ - {0xFC54, 0, 2 | DECOMP_NO_COMPOSE, 3832}, /* compatibility mapping */ - {0xFC55, 0, 2 | DECOMP_NO_COMPOSE, 3834}, /* compatibility mapping */ - {0xFC56, 0, 2 | DECOMP_NO_COMPOSE, 3836}, /* compatibility mapping */ - {0xFC57, 0, 2 | DECOMP_NO_COMPOSE, 3838}, /* compatibility mapping */ - {0xFC58, 0, 2 | DECOMP_NO_COMPOSE, 3840}, /* compatibility mapping */ - {0xFC59, 0, 2 | DECOMP_NO_COMPOSE, 3842}, /* compatibility mapping */ - {0xFC5A, 0, 2 | DECOMP_NO_COMPOSE, 3844}, /* compatibility mapping */ - {0xFC5B, 0, 2 | DECOMP_NO_COMPOSE, 3846}, /* compatibility mapping */ - {0xFC5C, 0, 2 | DECOMP_NO_COMPOSE, 3848}, /* compatibility mapping */ - {0xFC5D, 0, 2 | DECOMP_NO_COMPOSE, 3850}, /* compatibility mapping */ - {0xFC5E, 0, 3, 3852}, - {0xFC5F, 0, 3, 3855}, - {0xFC60, 0, 3, 3858}, - {0xFC61, 0, 3, 3861}, - {0xFC62, 0, 3, 3864}, - {0xFC63, 0, 3, 3867}, - {0xFC64, 0, 2 | DECOMP_NO_COMPOSE, 3870}, /* compatibility mapping */ - {0xFC65, 0, 2 | DECOMP_NO_COMPOSE, 3872}, /* compatibility mapping */ - {0xFC66, 0, 2 | DECOMP_NO_COMPOSE, 3874}, /* compatibility mapping */ - {0xFC67, 0, 2 | DECOMP_NO_COMPOSE, 3876}, /* compatibility mapping */ - {0xFC68, 0, 2 | DECOMP_NO_COMPOSE, 3878}, /* compatibility mapping */ - {0xFC69, 0, 2 | DECOMP_NO_COMPOSE, 3880}, /* compatibility mapping */ - {0xFC6A, 0, 2 | DECOMP_NO_COMPOSE, 3882}, /* compatibility mapping */ - {0xFC6B, 0, 2 | DECOMP_NO_COMPOSE, 3884}, /* compatibility mapping */ - {0xFC6C, 0, 2 | DECOMP_NO_COMPOSE, 3886}, /* compatibility mapping */ - {0xFC6D, 0, 2 | DECOMP_NO_COMPOSE, 3888}, /* compatibility mapping */ - {0xFC6E, 0, 2 | DECOMP_NO_COMPOSE, 3890}, /* compatibility mapping */ - {0xFC6F, 0, 2 | DECOMP_NO_COMPOSE, 3892}, /* compatibility mapping */ - {0xFC70, 0, 2 | DECOMP_NO_COMPOSE, 3894}, /* compatibility mapping */ - {0xFC71, 0, 2 | DECOMP_NO_COMPOSE, 3896}, /* compatibility mapping */ - {0xFC72, 0, 2 | DECOMP_NO_COMPOSE, 3898}, /* compatibility mapping */ - {0xFC73, 0, 2 | DECOMP_NO_COMPOSE, 3900}, /* compatibility mapping */ - {0xFC74, 0, 2 | DECOMP_NO_COMPOSE, 3902}, /* compatibility mapping */ - {0xFC75, 0, 2 | DECOMP_NO_COMPOSE, 3904}, /* compatibility mapping */ - {0xFC76, 0, 2 | DECOMP_NO_COMPOSE, 3906}, /* compatibility mapping */ - {0xFC77, 0, 2 | DECOMP_NO_COMPOSE, 3908}, /* compatibility mapping */ - {0xFC78, 0, 2 | DECOMP_NO_COMPOSE, 3910}, /* compatibility mapping */ - {0xFC79, 0, 2 | DECOMP_NO_COMPOSE, 3912}, /* compatibility mapping */ - {0xFC7A, 0, 2 | DECOMP_NO_COMPOSE, 3914}, /* compatibility mapping */ - {0xFC7B, 0, 2 | DECOMP_NO_COMPOSE, 3916}, /* compatibility mapping */ - {0xFC7C, 0, 2 | DECOMP_NO_COMPOSE, 3918}, /* compatibility mapping */ - {0xFC7D, 0, 2 | DECOMP_NO_COMPOSE, 3920}, /* compatibility mapping */ - {0xFC7E, 0, 2 | DECOMP_NO_COMPOSE, 3922}, /* compatibility mapping */ - {0xFC7F, 0, 2 | DECOMP_NO_COMPOSE, 3924}, /* compatibility mapping */ - {0xFC80, 0, 2 | DECOMP_NO_COMPOSE, 3926}, /* compatibility mapping */ - {0xFC81, 0, 2 | DECOMP_NO_COMPOSE, 3928}, /* compatibility mapping */ - {0xFC82, 0, 2 | DECOMP_NO_COMPOSE, 3930}, /* compatibility mapping */ - {0xFC83, 0, 2 | DECOMP_NO_COMPOSE, 3932}, /* compatibility mapping */ - {0xFC84, 0, 2 | DECOMP_NO_COMPOSE, 3934}, /* compatibility mapping */ - {0xFC85, 0, 2 | DECOMP_NO_COMPOSE, 3936}, /* compatibility mapping */ - {0xFC86, 0, 2 | DECOMP_NO_COMPOSE, 3938}, /* compatibility mapping */ - {0xFC87, 0, 2 | DECOMP_NO_COMPOSE, 3940}, /* compatibility mapping */ - {0xFC88, 0, 2 | DECOMP_NO_COMPOSE, 3942}, /* compatibility mapping */ - {0xFC89, 0, 2 | DECOMP_NO_COMPOSE, 3944}, /* compatibility mapping */ - {0xFC8A, 0, 2 | DECOMP_NO_COMPOSE, 3946}, /* compatibility mapping */ - {0xFC8B, 0, 2 | DECOMP_NO_COMPOSE, 3948}, /* compatibility mapping */ - {0xFC8C, 0, 2 | DECOMP_NO_COMPOSE, 3950}, /* compatibility mapping */ - {0xFC8D, 0, 2 | DECOMP_NO_COMPOSE, 3952}, /* compatibility mapping */ - {0xFC8E, 0, 2 | DECOMP_NO_COMPOSE, 3954}, /* compatibility mapping */ - {0xFC8F, 0, 2 | DECOMP_NO_COMPOSE, 3956}, /* compatibility mapping */ - {0xFC90, 0, 2 | DECOMP_NO_COMPOSE, 3958}, /* compatibility mapping */ - {0xFC91, 0, 2 | DECOMP_NO_COMPOSE, 3960}, /* compatibility mapping */ - {0xFC92, 0, 2 | DECOMP_NO_COMPOSE, 3962}, /* compatibility mapping */ - {0xFC93, 0, 2 | DECOMP_NO_COMPOSE, 3964}, /* compatibility mapping */ - {0xFC94, 0, 2 | DECOMP_NO_COMPOSE, 3966}, /* compatibility mapping */ - {0xFC95, 0, 2 | DECOMP_NO_COMPOSE, 3968}, /* compatibility mapping */ - {0xFC96, 0, 2 | DECOMP_NO_COMPOSE, 3970}, /* compatibility mapping */ - {0xFC97, 0, 2 | DECOMP_NO_COMPOSE, 3972}, /* compatibility mapping */ - {0xFC98, 0, 2 | DECOMP_NO_COMPOSE, 3974}, /* compatibility mapping */ - {0xFC99, 0, 2 | DECOMP_NO_COMPOSE, 3976}, /* compatibility mapping */ - {0xFC9A, 0, 2 | DECOMP_NO_COMPOSE, 3978}, /* compatibility mapping */ - {0xFC9B, 0, 2 | DECOMP_NO_COMPOSE, 3980}, /* compatibility mapping */ - {0xFC9C, 0, 2 | DECOMP_NO_COMPOSE, 3982}, /* compatibility mapping */ - {0xFC9D, 0, 2 | DECOMP_NO_COMPOSE, 3984}, /* compatibility mapping */ - {0xFC9E, 0, 2 | DECOMP_NO_COMPOSE, 3986}, /* compatibility mapping */ - {0xFC9F, 0, 2 | DECOMP_NO_COMPOSE, 3988}, /* compatibility mapping */ - {0xFCA0, 0, 2 | DECOMP_NO_COMPOSE, 3990}, /* compatibility mapping */ - {0xFCA1, 0, 2 | DECOMP_NO_COMPOSE, 3992}, /* compatibility mapping */ - {0xFCA2, 0, 2 | DECOMP_NO_COMPOSE, 3994}, /* compatibility mapping */ - {0xFCA3, 0, 2 | DECOMP_NO_COMPOSE, 3996}, /* compatibility mapping */ - {0xFCA4, 0, 2 | DECOMP_NO_COMPOSE, 3998}, /* compatibility mapping */ - {0xFCA5, 0, 2 | DECOMP_NO_COMPOSE, 4000}, /* compatibility mapping */ - {0xFCA6, 0, 2 | DECOMP_NO_COMPOSE, 4002}, /* compatibility mapping */ - {0xFCA7, 0, 2 | DECOMP_NO_COMPOSE, 4004}, /* compatibility mapping */ - {0xFCA8, 0, 2 | DECOMP_NO_COMPOSE, 4006}, /* compatibility mapping */ - {0xFCA9, 0, 2 | DECOMP_NO_COMPOSE, 4008}, /* compatibility mapping */ - {0xFCAA, 0, 2 | DECOMP_NO_COMPOSE, 4010}, /* compatibility mapping */ - {0xFCAB, 0, 2 | DECOMP_NO_COMPOSE, 4012}, /* compatibility mapping */ - {0xFCAC, 0, 2 | DECOMP_NO_COMPOSE, 4014}, /* compatibility mapping */ - {0xFCAD, 0, 2 | DECOMP_NO_COMPOSE, 4016}, /* compatibility mapping */ - {0xFCAE, 0, 2 | DECOMP_NO_COMPOSE, 4018}, /* compatibility mapping */ - {0xFCAF, 0, 2 | DECOMP_NO_COMPOSE, 4020}, /* compatibility mapping */ - {0xFCB0, 0, 2 | DECOMP_NO_COMPOSE, 4022}, /* compatibility mapping */ - {0xFCB1, 0, 2 | DECOMP_NO_COMPOSE, 4024}, /* compatibility mapping */ - {0xFCB2, 0, 2 | DECOMP_NO_COMPOSE, 4026}, /* compatibility mapping */ - {0xFCB3, 0, 2 | DECOMP_NO_COMPOSE, 4028}, /* compatibility mapping */ - {0xFCB4, 0, 2 | DECOMP_NO_COMPOSE, 4030}, /* compatibility mapping */ - {0xFCB5, 0, 2 | DECOMP_NO_COMPOSE, 4032}, /* compatibility mapping */ - {0xFCB6, 0, 2 | DECOMP_NO_COMPOSE, 4034}, /* compatibility mapping */ - {0xFCB7, 0, 2 | DECOMP_NO_COMPOSE, 4036}, /* compatibility mapping */ - {0xFCB8, 0, 2 | DECOMP_NO_COMPOSE, 4038}, /* compatibility mapping */ - {0xFCB9, 0, 2 | DECOMP_NO_COMPOSE, 4040}, /* compatibility mapping */ - {0xFCBA, 0, 2 | DECOMP_NO_COMPOSE, 4042}, /* compatibility mapping */ - {0xFCBB, 0, 2 | DECOMP_NO_COMPOSE, 4044}, /* compatibility mapping */ - {0xFCBC, 0, 2 | DECOMP_NO_COMPOSE, 4046}, /* compatibility mapping */ - {0xFCBD, 0, 2 | DECOMP_NO_COMPOSE, 4048}, /* compatibility mapping */ - {0xFCBE, 0, 2 | DECOMP_NO_COMPOSE, 4050}, /* compatibility mapping */ - {0xFCBF, 0, 2 | DECOMP_NO_COMPOSE, 4052}, /* compatibility mapping */ - {0xFCC0, 0, 2 | DECOMP_NO_COMPOSE, 4054}, /* compatibility mapping */ - {0xFCC1, 0, 2 | DECOMP_NO_COMPOSE, 4056}, /* compatibility mapping */ - {0xFCC2, 0, 2 | DECOMP_NO_COMPOSE, 4058}, /* compatibility mapping */ - {0xFCC3, 0, 2 | DECOMP_NO_COMPOSE, 4060}, /* compatibility mapping */ - {0xFCC4, 0, 2 | DECOMP_NO_COMPOSE, 4062}, /* compatibility mapping */ - {0xFCC5, 0, 2 | DECOMP_NO_COMPOSE, 4064}, /* compatibility mapping */ - {0xFCC6, 0, 2 | DECOMP_NO_COMPOSE, 4066}, /* compatibility mapping */ - {0xFCC7, 0, 2 | DECOMP_NO_COMPOSE, 4068}, /* compatibility mapping */ - {0xFCC8, 0, 2 | DECOMP_NO_COMPOSE, 4070}, /* compatibility mapping */ - {0xFCC9, 0, 2 | DECOMP_NO_COMPOSE, 4072}, /* compatibility mapping */ - {0xFCCA, 0, 2 | DECOMP_NO_COMPOSE, 4074}, /* compatibility mapping */ - {0xFCCB, 0, 2 | DECOMP_NO_COMPOSE, 4076}, /* compatibility mapping */ - {0xFCCC, 0, 2 | DECOMP_NO_COMPOSE, 4078}, /* compatibility mapping */ - {0xFCCD, 0, 2 | DECOMP_NO_COMPOSE, 4080}, /* compatibility mapping */ - {0xFCCE, 0, 2 | DECOMP_NO_COMPOSE, 4082}, /* compatibility mapping */ - {0xFCCF, 0, 2 | DECOMP_NO_COMPOSE, 4084}, /* compatibility mapping */ - {0xFCD0, 0, 2 | DECOMP_NO_COMPOSE, 4086}, /* compatibility mapping */ - {0xFCD1, 0, 2 | DECOMP_NO_COMPOSE, 4088}, /* compatibility mapping */ - {0xFCD2, 0, 2 | DECOMP_NO_COMPOSE, 4090}, /* compatibility mapping */ - {0xFCD3, 0, 2 | DECOMP_NO_COMPOSE, 4092}, /* compatibility mapping */ - {0xFCD4, 0, 2 | DECOMP_NO_COMPOSE, 4094}, /* compatibility mapping */ - {0xFCD5, 0, 2 | DECOMP_NO_COMPOSE, 4096}, /* compatibility mapping */ - {0xFCD6, 0, 2 | DECOMP_NO_COMPOSE, 4098}, /* compatibility mapping */ - {0xFCD7, 0, 2 | DECOMP_NO_COMPOSE, 4100}, /* compatibility mapping */ - {0xFCD8, 0, 2 | DECOMP_NO_COMPOSE, 4102}, /* compatibility mapping */ - {0xFCD9, 0, 2 | DECOMP_NO_COMPOSE, 4104}, /* compatibility mapping */ - {0xFCDA, 0, 2 | DECOMP_NO_COMPOSE, 4106}, /* compatibility mapping */ - {0xFCDB, 0, 2 | DECOMP_NO_COMPOSE, 4108}, /* compatibility mapping */ - {0xFCDC, 0, 2 | DECOMP_NO_COMPOSE, 4110}, /* compatibility mapping */ - {0xFCDD, 0, 2 | DECOMP_NO_COMPOSE, 4112}, /* compatibility mapping */ - {0xFCDE, 0, 2 | DECOMP_NO_COMPOSE, 4114}, /* compatibility mapping */ - {0xFCDF, 0, 2 | DECOMP_NO_COMPOSE, 4116}, /* compatibility mapping */ - {0xFCE0, 0, 2 | DECOMP_NO_COMPOSE, 4118}, /* compatibility mapping */ - {0xFCE1, 0, 2 | DECOMP_NO_COMPOSE, 4120}, /* compatibility mapping */ - {0xFCE2, 0, 2 | DECOMP_NO_COMPOSE, 4122}, /* compatibility mapping */ - {0xFCE3, 0, 2 | DECOMP_NO_COMPOSE, 4124}, /* compatibility mapping */ - {0xFCE4, 0, 2 | DECOMP_NO_COMPOSE, 4126}, /* compatibility mapping */ - {0xFCE5, 0, 2 | DECOMP_NO_COMPOSE, 4128}, /* compatibility mapping */ - {0xFCE6, 0, 2 | DECOMP_NO_COMPOSE, 4130}, /* compatibility mapping */ - {0xFCE7, 0, 2 | DECOMP_NO_COMPOSE, 4132}, /* compatibility mapping */ - {0xFCE8, 0, 2 | DECOMP_NO_COMPOSE, 4134}, /* compatibility mapping */ - {0xFCE9, 0, 2 | DECOMP_NO_COMPOSE, 4136}, /* compatibility mapping */ - {0xFCEA, 0, 2 | DECOMP_NO_COMPOSE, 4138}, /* compatibility mapping */ - {0xFCEB, 0, 2 | DECOMP_NO_COMPOSE, 4140}, /* compatibility mapping */ - {0xFCEC, 0, 2 | DECOMP_NO_COMPOSE, 4142}, /* compatibility mapping */ - {0xFCED, 0, 2 | DECOMP_NO_COMPOSE, 4144}, /* compatibility mapping */ - {0xFCEE, 0, 2 | DECOMP_NO_COMPOSE, 4146}, /* compatibility mapping */ - {0xFCEF, 0, 2 | DECOMP_NO_COMPOSE, 4148}, /* compatibility mapping */ - {0xFCF0, 0, 2 | DECOMP_NO_COMPOSE, 4150}, /* compatibility mapping */ - {0xFCF1, 0, 2 | DECOMP_NO_COMPOSE, 4152}, /* compatibility mapping */ - {0xFCF2, 0, 3, 4154}, - {0xFCF3, 0, 3, 4157}, - {0xFCF4, 0, 3, 4160}, - {0xFCF5, 0, 2 | DECOMP_NO_COMPOSE, 4163}, /* compatibility mapping */ - {0xFCF6, 0, 2 | DECOMP_NO_COMPOSE, 4165}, /* compatibility mapping */ - {0xFCF7, 0, 2 | DECOMP_NO_COMPOSE, 4167}, /* compatibility mapping */ - {0xFCF8, 0, 2 | DECOMP_NO_COMPOSE, 4169}, /* compatibility mapping */ - {0xFCF9, 0, 2 | DECOMP_NO_COMPOSE, 4171}, /* compatibility mapping */ - {0xFCFA, 0, 2 | DECOMP_NO_COMPOSE, 4173}, /* compatibility mapping */ - {0xFCFB, 0, 2 | DECOMP_NO_COMPOSE, 4175}, /* compatibility mapping */ - {0xFCFC, 0, 2 | DECOMP_NO_COMPOSE, 4177}, /* compatibility mapping */ - {0xFCFD, 0, 2 | DECOMP_NO_COMPOSE, 4179}, /* compatibility mapping */ - {0xFCFE, 0, 2 | DECOMP_NO_COMPOSE, 4181}, /* compatibility mapping */ - {0xFCFF, 0, 2 | DECOMP_NO_COMPOSE, 4183}, /* compatibility mapping */ - {0xFD00, 0, 2 | DECOMP_NO_COMPOSE, 4185}, /* compatibility mapping */ - {0xFD01, 0, 2 | DECOMP_NO_COMPOSE, 4187}, /* compatibility mapping */ - {0xFD02, 0, 2 | DECOMP_NO_COMPOSE, 4189}, /* compatibility mapping */ - {0xFD03, 0, 2 | DECOMP_NO_COMPOSE, 4191}, /* compatibility mapping */ - {0xFD04, 0, 2 | DECOMP_NO_COMPOSE, 4193}, /* compatibility mapping */ - {0xFD05, 0, 2 | DECOMP_NO_COMPOSE, 4195}, /* compatibility mapping */ - {0xFD06, 0, 2 | DECOMP_NO_COMPOSE, 4197}, /* compatibility mapping */ - {0xFD07, 0, 2 | DECOMP_NO_COMPOSE, 4199}, /* compatibility mapping */ - {0xFD08, 0, 2 | DECOMP_NO_COMPOSE, 4201}, /* compatibility mapping */ - {0xFD09, 0, 2 | DECOMP_NO_COMPOSE, 4203}, /* compatibility mapping */ - {0xFD0A, 0, 2 | DECOMP_NO_COMPOSE, 4205}, /* compatibility mapping */ - {0xFD0B, 0, 2 | DECOMP_NO_COMPOSE, 4207}, /* compatibility mapping */ - {0xFD0C, 0, 2 | DECOMP_NO_COMPOSE, 4209}, /* compatibility mapping */ - {0xFD0D, 0, 2 | DECOMP_NO_COMPOSE, 4211}, /* compatibility mapping */ - {0xFD0E, 0, 2 | DECOMP_NO_COMPOSE, 4213}, /* compatibility mapping */ - {0xFD0F, 0, 2 | DECOMP_NO_COMPOSE, 4215}, /* compatibility mapping */ - {0xFD10, 0, 2 | DECOMP_NO_COMPOSE, 4217}, /* compatibility mapping */ - {0xFD11, 0, 2 | DECOMP_NO_COMPOSE, 4219}, /* compatibility mapping */ - {0xFD12, 0, 2 | DECOMP_NO_COMPOSE, 4221}, /* compatibility mapping */ - {0xFD13, 0, 2 | DECOMP_NO_COMPOSE, 4223}, /* compatibility mapping */ - {0xFD14, 0, 2 | DECOMP_NO_COMPOSE, 4225}, /* compatibility mapping */ - {0xFD15, 0, 2 | DECOMP_NO_COMPOSE, 4227}, /* compatibility mapping */ - {0xFD16, 0, 2 | DECOMP_NO_COMPOSE, 4229}, /* compatibility mapping */ - {0xFD17, 0, 2 | DECOMP_NO_COMPOSE, 4231}, /* compatibility mapping */ - {0xFD18, 0, 2 | DECOMP_NO_COMPOSE, 4233}, /* compatibility mapping */ - {0xFD19, 0, 2 | DECOMP_NO_COMPOSE, 4235}, /* compatibility mapping */ - {0xFD1A, 0, 2 | DECOMP_NO_COMPOSE, 4237}, /* compatibility mapping */ - {0xFD1B, 0, 2 | DECOMP_NO_COMPOSE, 4239}, /* compatibility mapping */ - {0xFD1C, 0, 2 | DECOMP_NO_COMPOSE, 4241}, /* compatibility mapping */ - {0xFD1D, 0, 2 | DECOMP_NO_COMPOSE, 4243}, /* compatibility mapping */ - {0xFD1E, 0, 2 | DECOMP_NO_COMPOSE, 4245}, /* compatibility mapping */ - {0xFD1F, 0, 2 | DECOMP_NO_COMPOSE, 4247}, /* compatibility mapping */ - {0xFD20, 0, 2 | DECOMP_NO_COMPOSE, 4249}, /* compatibility mapping */ - {0xFD21, 0, 2 | DECOMP_NO_COMPOSE, 4251}, /* compatibility mapping */ - {0xFD22, 0, 2 | DECOMP_NO_COMPOSE, 4253}, /* compatibility mapping */ - {0xFD23, 0, 2 | DECOMP_NO_COMPOSE, 4255}, /* compatibility mapping */ - {0xFD24, 0, 2 | DECOMP_NO_COMPOSE, 4257}, /* compatibility mapping */ - {0xFD25, 0, 2 | DECOMP_NO_COMPOSE, 4259}, /* compatibility mapping */ - {0xFD26, 0, 2 | DECOMP_NO_COMPOSE, 4261}, /* compatibility mapping */ - {0xFD27, 0, 2 | DECOMP_NO_COMPOSE, 4263}, /* compatibility mapping */ - {0xFD28, 0, 2 | DECOMP_NO_COMPOSE, 4265}, /* compatibility mapping */ - {0xFD29, 0, 2 | DECOMP_NO_COMPOSE, 4267}, /* compatibility mapping */ - {0xFD2A, 0, 2 | DECOMP_NO_COMPOSE, 4269}, /* compatibility mapping */ - {0xFD2B, 0, 2 | DECOMP_NO_COMPOSE, 4271}, /* compatibility mapping */ - {0xFD2C, 0, 2 | DECOMP_NO_COMPOSE, 4273}, /* compatibility mapping */ - {0xFD2D, 0, 2 | DECOMP_NO_COMPOSE, 4275}, /* compatibility mapping */ - {0xFD2E, 0, 2 | DECOMP_NO_COMPOSE, 4277}, /* compatibility mapping */ - {0xFD2F, 0, 2 | DECOMP_NO_COMPOSE, 4279}, /* compatibility mapping */ - {0xFD30, 0, 2 | DECOMP_NO_COMPOSE, 4281}, /* compatibility mapping */ - {0xFD31, 0, 2 | DECOMP_NO_COMPOSE, 4283}, /* compatibility mapping */ - {0xFD32, 0, 2 | DECOMP_NO_COMPOSE, 4285}, /* compatibility mapping */ - {0xFD33, 0, 2 | DECOMP_NO_COMPOSE, 4287}, /* compatibility mapping */ - {0xFD34, 0, 2 | DECOMP_NO_COMPOSE, 4289}, /* compatibility mapping */ - {0xFD35, 0, 2 | DECOMP_NO_COMPOSE, 4291}, /* compatibility mapping */ - {0xFD36, 0, 2 | DECOMP_NO_COMPOSE, 4293}, /* compatibility mapping */ - {0xFD37, 0, 2 | DECOMP_NO_COMPOSE, 4295}, /* compatibility mapping */ - {0xFD38, 0, 2 | DECOMP_NO_COMPOSE, 4297}, /* compatibility mapping */ - {0xFD39, 0, 2 | DECOMP_NO_COMPOSE, 4299}, /* compatibility mapping */ - {0xFD3A, 0, 2 | DECOMP_NO_COMPOSE, 4301}, /* compatibility mapping */ - {0xFD3B, 0, 2 | DECOMP_NO_COMPOSE, 4303}, /* compatibility mapping */ - {0xFD3C, 0, 2 | DECOMP_NO_COMPOSE, 4305}, /* compatibility mapping */ - {0xFD3D, 0, 2 | DECOMP_NO_COMPOSE, 4307}, /* compatibility mapping */ - {0xFD50, 0, 3, 4309}, - {0xFD51, 0, 3, 4312}, - {0xFD52, 0, 3, 4315}, - {0xFD53, 0, 3, 4318}, - {0xFD54, 0, 3, 4321}, - {0xFD55, 0, 3, 4324}, - {0xFD56, 0, 3, 4327}, - {0xFD57, 0, 3, 4330}, - {0xFD58, 0, 3, 4333}, - {0xFD59, 0, 3, 4336}, - {0xFD5A, 0, 3, 4339}, - {0xFD5B, 0, 3, 4342}, - {0xFD5C, 0, 3, 4345}, - {0xFD5D, 0, 3, 4348}, - {0xFD5E, 0, 3, 4351}, - {0xFD5F, 0, 3, 4354}, - {0xFD60, 0, 3, 4357}, - {0xFD61, 0, 3, 4360}, - {0xFD62, 0, 3, 4363}, - {0xFD63, 0, 3, 4366}, - {0xFD64, 0, 3, 4369}, - {0xFD65, 0, 3, 4372}, - {0xFD66, 0, 3, 4375}, - {0xFD67, 0, 3, 4378}, - {0xFD68, 0, 3, 4381}, - {0xFD69, 0, 3, 4384}, - {0xFD6A, 0, 3, 4387}, - {0xFD6B, 0, 3, 4390}, - {0xFD6C, 0, 3, 4393}, - {0xFD6D, 0, 3, 4396}, - {0xFD6E, 0, 3, 4399}, - {0xFD6F, 0, 3, 4402}, - {0xFD70, 0, 3, 4405}, - {0xFD71, 0, 3, 4408}, - {0xFD72, 0, 3, 4411}, - {0xFD73, 0, 3, 4414}, - {0xFD74, 0, 3, 4417}, - {0xFD75, 0, 3, 4420}, - {0xFD76, 0, 3, 4423}, - {0xFD77, 0, 3, 4426}, - {0xFD78, 0, 3, 4429}, - {0xFD79, 0, 3, 4432}, - {0xFD7A, 0, 3, 4435}, - {0xFD7B, 0, 3, 4438}, - {0xFD7C, 0, 3, 4441}, - {0xFD7D, 0, 3, 4444}, - {0xFD7E, 0, 3, 4447}, - {0xFD7F, 0, 3, 4450}, - {0xFD80, 0, 3, 4453}, - {0xFD81, 0, 3, 4456}, - {0xFD82, 0, 3, 4459}, - {0xFD83, 0, 3, 4462}, - {0xFD84, 0, 3, 4465}, - {0xFD85, 0, 3, 4468}, - {0xFD86, 0, 3, 4471}, - {0xFD87, 0, 3, 4474}, - {0xFD88, 0, 3, 4477}, - {0xFD89, 0, 3, 4480}, - {0xFD8A, 0, 3, 4483}, - {0xFD8B, 0, 3, 4486}, - {0xFD8C, 0, 3, 4489}, - {0xFD8D, 0, 3, 4492}, - {0xFD8E, 0, 3, 4495}, - {0xFD8F, 0, 3, 4498}, - {0xFD92, 0, 3, 4501}, - {0xFD93, 0, 3, 4504}, - {0xFD94, 0, 3, 4507}, - {0xFD95, 0, 3, 4510}, - {0xFD96, 0, 3, 4513}, - {0xFD97, 0, 3, 4516}, - {0xFD98, 0, 3, 4519}, - {0xFD99, 0, 3, 4522}, - {0xFD9A, 0, 3, 4525}, - {0xFD9B, 0, 3, 4528}, - {0xFD9C, 0, 3, 4531}, - {0xFD9D, 0, 3, 4534}, - {0xFD9E, 0, 3, 4537}, - {0xFD9F, 0, 3, 4540}, - {0xFDA0, 0, 3, 4543}, - {0xFDA1, 0, 3, 4546}, - {0xFDA2, 0, 3, 4549}, - {0xFDA3, 0, 3, 4552}, - {0xFDA4, 0, 3, 4555}, - {0xFDA5, 0, 3, 4558}, - {0xFDA6, 0, 3, 4561}, - {0xFDA7, 0, 3, 4564}, - {0xFDA8, 0, 3, 4567}, - {0xFDA9, 0, 3, 4570}, - {0xFDAA, 0, 3, 4573}, - {0xFDAB, 0, 3, 4576}, - {0xFDAC, 0, 3, 4579}, - {0xFDAD, 0, 3, 4582}, - {0xFDAE, 0, 3, 4585}, - {0xFDAF, 0, 3, 4588}, - {0xFDB0, 0, 3, 4591}, - {0xFDB1, 0, 3, 4594}, - {0xFDB2, 0, 3, 4597}, - {0xFDB3, 0, 3, 4600}, - {0xFDB4, 0, 3, 4603}, - {0xFDB5, 0, 3, 4606}, - {0xFDB6, 0, 3, 4609}, - {0xFDB7, 0, 3, 4612}, - {0xFDB8, 0, 3, 4615}, - {0xFDB9, 0, 3, 4618}, - {0xFDBA, 0, 3, 4621}, - {0xFDBB, 0, 3, 4624}, - {0xFDBC, 0, 3, 4627}, - {0xFDBD, 0, 3, 4630}, - {0xFDBE, 0, 3, 4633}, - {0xFDBF, 0, 3, 4636}, - {0xFDC0, 0, 3, 4639}, - {0xFDC1, 0, 3, 4642}, - {0xFDC2, 0, 3, 4645}, - {0xFDC3, 0, 3, 4648}, - {0xFDC4, 0, 3, 4651}, - {0xFDC5, 0, 3, 4654}, - {0xFDC6, 0, 3, 4657}, - {0xFDC7, 0, 3, 4660}, - {0xFDF0, 0, 3, 4663}, - {0xFDF1, 0, 3, 4666}, - {0xFDF2, 0, 4, 4669}, - {0xFDF3, 0, 4, 4673}, - {0xFDF4, 0, 4, 4677}, - {0xFDF5, 0, 4, 4681}, - {0xFDF6, 0, 4, 4685}, - {0xFDF7, 0, 4, 4689}, - {0xFDF8, 0, 4, 4693}, - {0xFDF9, 0, 3, 4697}, - {0xFDFA, 0, 18, 4700}, - {0xFDFB, 0, 8, 4718}, - {0xFDFC, 0, 4, 4726}, + {0xFC00, 0, 2 | DECOMP_NO_COMPOSE, 3666}, /* compatibility mapping */ + {0xFC01, 0, 2 | DECOMP_NO_COMPOSE, 3668}, /* compatibility mapping */ + {0xFC02, 0, 2 | DECOMP_NO_COMPOSE, 3670}, /* compatibility mapping */ + {0xFC03, 0, 2 | DECOMP_NO_COMPOSE, 3672}, /* compatibility mapping */ + {0xFC04, 0, 2 | DECOMP_NO_COMPOSE, 3674}, /* compatibility mapping */ + {0xFC05, 0, 2 | DECOMP_NO_COMPOSE, 3676}, /* compatibility mapping */ + {0xFC06, 0, 2 | DECOMP_NO_COMPOSE, 3678}, /* compatibility mapping */ + {0xFC07, 0, 2 | DECOMP_NO_COMPOSE, 3680}, /* compatibility mapping */ + {0xFC08, 0, 2 | DECOMP_NO_COMPOSE, 3682}, /* compatibility mapping */ + {0xFC09, 0, 2 | DECOMP_NO_COMPOSE, 3684}, /* compatibility mapping */ + {0xFC0A, 0, 2 | DECOMP_NO_COMPOSE, 3686}, /* compatibility mapping */ + {0xFC0B, 0, 2 | DECOMP_NO_COMPOSE, 3688}, /* compatibility mapping */ + {0xFC0C, 0, 2 | DECOMP_NO_COMPOSE, 3690}, /* compatibility mapping */ + {0xFC0D, 0, 2 | DECOMP_NO_COMPOSE, 3692}, /* compatibility mapping */ + {0xFC0E, 0, 2 | DECOMP_NO_COMPOSE, 3694}, /* compatibility mapping */ + {0xFC0F, 0, 2 | DECOMP_NO_COMPOSE, 3696}, /* compatibility mapping */ + {0xFC10, 0, 2 | DECOMP_NO_COMPOSE, 3698}, /* compatibility mapping */ + {0xFC11, 0, 2 | DECOMP_NO_COMPOSE, 3700}, /* compatibility mapping */ + {0xFC12, 0, 2 | DECOMP_NO_COMPOSE, 3702}, /* compatibility mapping */ + {0xFC13, 0, 2 | DECOMP_NO_COMPOSE, 3704}, /* compatibility mapping */ + {0xFC14, 0, 2 | DECOMP_NO_COMPOSE, 3706}, /* compatibility mapping */ + {0xFC15, 0, 2 | DECOMP_NO_COMPOSE, 3708}, /* compatibility mapping */ + {0xFC16, 0, 2 | DECOMP_NO_COMPOSE, 3710}, /* compatibility mapping */ + {0xFC17, 0, 2 | DECOMP_NO_COMPOSE, 3712}, /* compatibility mapping */ + {0xFC18, 0, 2 | DECOMP_NO_COMPOSE, 3714}, /* compatibility mapping */ + {0xFC19, 0, 2 | DECOMP_NO_COMPOSE, 3716}, /* compatibility mapping */ + {0xFC1A, 0, 2 | DECOMP_NO_COMPOSE, 3718}, /* compatibility mapping */ + {0xFC1B, 0, 2 | DECOMP_NO_COMPOSE, 3720}, /* compatibility mapping */ + {0xFC1C, 0, 2 | DECOMP_NO_COMPOSE, 3722}, /* compatibility mapping */ + {0xFC1D, 0, 2 | DECOMP_NO_COMPOSE, 3724}, /* compatibility mapping */ + {0xFC1E, 0, 2 | DECOMP_NO_COMPOSE, 3726}, /* compatibility mapping */ + {0xFC1F, 0, 2 | DECOMP_NO_COMPOSE, 3728}, /* compatibility mapping */ + {0xFC20, 0, 2 | DECOMP_NO_COMPOSE, 3730}, /* compatibility mapping */ + {0xFC21, 0, 2 | DECOMP_NO_COMPOSE, 3732}, /* compatibility mapping */ + {0xFC22, 0, 2 | DECOMP_NO_COMPOSE, 3734}, /* compatibility mapping */ + {0xFC23, 0, 2 | DECOMP_NO_COMPOSE, 3736}, /* compatibility mapping */ + {0xFC24, 0, 2 | DECOMP_NO_COMPOSE, 3738}, /* compatibility mapping */ + {0xFC25, 0, 2 | DECOMP_NO_COMPOSE, 3740}, /* compatibility mapping */ + {0xFC26, 0, 2 | DECOMP_NO_COMPOSE, 3742}, /* compatibility mapping */ + {0xFC27, 0, 2 | DECOMP_NO_COMPOSE, 3744}, /* compatibility mapping */ + {0xFC28, 0, 2 | DECOMP_NO_COMPOSE, 3746}, /* compatibility mapping */ + {0xFC29, 0, 2 | DECOMP_NO_COMPOSE, 3748}, /* compatibility mapping */ + {0xFC2A, 0, 2 | DECOMP_NO_COMPOSE, 3750}, /* compatibility mapping */ + {0xFC2B, 0, 2 | DECOMP_NO_COMPOSE, 3752}, /* compatibility mapping */ + {0xFC2C, 0, 2 | DECOMP_NO_COMPOSE, 3754}, /* compatibility mapping */ + {0xFC2D, 0, 2 | DECOMP_NO_COMPOSE, 3756}, /* compatibility mapping */ + {0xFC2E, 0, 2 | DECOMP_NO_COMPOSE, 3758}, /* compatibility mapping */ + {0xFC2F, 0, 2 | DECOMP_NO_COMPOSE, 3760}, /* compatibility mapping */ + {0xFC30, 0, 2 | DECOMP_NO_COMPOSE, 3762}, /* compatibility mapping */ + {0xFC31, 0, 2 | DECOMP_NO_COMPOSE, 3764}, /* compatibility mapping */ + {0xFC32, 0, 2 | DECOMP_NO_COMPOSE, 3766}, /* compatibility mapping */ + {0xFC33, 0, 2 | DECOMP_NO_COMPOSE, 3768}, /* compatibility mapping */ + {0xFC34, 0, 2 | DECOMP_NO_COMPOSE, 3770}, /* compatibility mapping */ + {0xFC35, 0, 2 | DECOMP_NO_COMPOSE, 3772}, /* compatibility mapping */ + {0xFC36, 0, 2 | DECOMP_NO_COMPOSE, 3774}, /* compatibility mapping */ + {0xFC37, 0, 2 | DECOMP_NO_COMPOSE, 3776}, /* compatibility mapping */ + {0xFC38, 0, 2 | DECOMP_NO_COMPOSE, 3778}, /* compatibility mapping */ + {0xFC39, 0, 2 | DECOMP_NO_COMPOSE, 3780}, /* compatibility mapping */ + {0xFC3A, 0, 2 | DECOMP_NO_COMPOSE, 3782}, /* compatibility mapping */ + {0xFC3B, 0, 2 | DECOMP_NO_COMPOSE, 3784}, /* compatibility mapping */ + {0xFC3C, 0, 2 | DECOMP_NO_COMPOSE, 3786}, /* compatibility mapping */ + {0xFC3D, 0, 2 | DECOMP_NO_COMPOSE, 3788}, /* compatibility mapping */ + {0xFC3E, 0, 2 | DECOMP_NO_COMPOSE, 3790}, /* compatibility mapping */ + {0xFC3F, 0, 2 | DECOMP_NO_COMPOSE, 3792}, /* compatibility mapping */ + {0xFC40, 0, 2 | DECOMP_NO_COMPOSE, 3794}, /* compatibility mapping */ + {0xFC41, 0, 2 | DECOMP_NO_COMPOSE, 3796}, /* compatibility mapping */ + {0xFC42, 0, 2 | DECOMP_NO_COMPOSE, 3798}, /* compatibility mapping */ + {0xFC43, 0, 2 | DECOMP_NO_COMPOSE, 3800}, /* compatibility mapping */ + {0xFC44, 0, 2 | DECOMP_NO_COMPOSE, 3802}, /* compatibility mapping */ + {0xFC45, 0, 2 | DECOMP_NO_COMPOSE, 3804}, /* compatibility mapping */ + {0xFC46, 0, 2 | DECOMP_NO_COMPOSE, 3806}, /* compatibility mapping */ + {0xFC47, 0, 2 | DECOMP_NO_COMPOSE, 3808}, /* compatibility mapping */ + {0xFC48, 0, 2 | DECOMP_NO_COMPOSE, 3810}, /* compatibility mapping */ + {0xFC49, 0, 2 | DECOMP_NO_COMPOSE, 3812}, /* compatibility mapping */ + {0xFC4A, 0, 2 | DECOMP_NO_COMPOSE, 3814}, /* compatibility mapping */ + {0xFC4B, 0, 2 | DECOMP_NO_COMPOSE, 3816}, /* compatibility mapping */ + {0xFC4C, 0, 2 | DECOMP_NO_COMPOSE, 3818}, /* compatibility mapping */ + {0xFC4D, 0, 2 | DECOMP_NO_COMPOSE, 3820}, /* compatibility mapping */ + {0xFC4E, 0, 2 | DECOMP_NO_COMPOSE, 3822}, /* compatibility mapping */ + {0xFC4F, 0, 2 | DECOMP_NO_COMPOSE, 3824}, /* compatibility mapping */ + {0xFC50, 0, 2 | DECOMP_NO_COMPOSE, 3826}, /* compatibility mapping */ + {0xFC51, 0, 2 | DECOMP_NO_COMPOSE, 3828}, /* compatibility mapping */ + {0xFC52, 0, 2 | DECOMP_NO_COMPOSE, 3830}, /* compatibility mapping */ + {0xFC53, 0, 2 | DECOMP_NO_COMPOSE, 3832}, /* compatibility mapping */ + {0xFC54, 0, 2 | DECOMP_NO_COMPOSE, 3834}, /* compatibility mapping */ + {0xFC55, 0, 2 | DECOMP_NO_COMPOSE, 3836}, /* compatibility mapping */ + {0xFC56, 0, 2 | DECOMP_NO_COMPOSE, 3838}, /* compatibility mapping */ + {0xFC57, 0, 2 | DECOMP_NO_COMPOSE, 3840}, /* compatibility mapping */ + {0xFC58, 0, 2 | DECOMP_NO_COMPOSE, 3842}, /* compatibility mapping */ + {0xFC59, 0, 2 | DECOMP_NO_COMPOSE, 3844}, /* compatibility mapping */ + {0xFC5A, 0, 2 | DECOMP_NO_COMPOSE, 3846}, /* compatibility mapping */ + {0xFC5B, 0, 2 | DECOMP_NO_COMPOSE, 3848}, /* compatibility mapping */ + {0xFC5C, 0, 2 | DECOMP_NO_COMPOSE, 3850}, /* compatibility mapping */ + {0xFC5D, 0, 2 | DECOMP_NO_COMPOSE, 3852}, /* compatibility mapping */ + {0xFC5E, 0, 3, 3854}, + {0xFC5F, 0, 3, 3857}, + {0xFC60, 0, 3, 3860}, + {0xFC61, 0, 3, 3863}, + {0xFC62, 0, 3, 3866}, + {0xFC63, 0, 3, 3869}, + {0xFC64, 0, 2 | DECOMP_NO_COMPOSE, 3872}, /* compatibility mapping */ + {0xFC65, 0, 2 | DECOMP_NO_COMPOSE, 3874}, /* compatibility mapping */ + {0xFC66, 0, 2 | DECOMP_NO_COMPOSE, 3876}, /* compatibility mapping */ + {0xFC67, 0, 2 | DECOMP_NO_COMPOSE, 3878}, /* compatibility mapping */ + {0xFC68, 0, 2 | DECOMP_NO_COMPOSE, 3880}, /* compatibility mapping */ + {0xFC69, 0, 2 | DECOMP_NO_COMPOSE, 3882}, /* compatibility mapping */ + {0xFC6A, 0, 2 | DECOMP_NO_COMPOSE, 3884}, /* compatibility mapping */ + {0xFC6B, 0, 2 | DECOMP_NO_COMPOSE, 3886}, /* compatibility mapping */ + {0xFC6C, 0, 2 | DECOMP_NO_COMPOSE, 3888}, /* compatibility mapping */ + {0xFC6D, 0, 2 | DECOMP_NO_COMPOSE, 3890}, /* compatibility mapping */ + {0xFC6E, 0, 2 | DECOMP_NO_COMPOSE, 3892}, /* compatibility mapping */ + {0xFC6F, 0, 2 | DECOMP_NO_COMPOSE, 3894}, /* compatibility mapping */ + {0xFC70, 0, 2 | DECOMP_NO_COMPOSE, 3896}, /* compatibility mapping */ + {0xFC71, 0, 2 | DECOMP_NO_COMPOSE, 3898}, /* compatibility mapping */ + {0xFC72, 0, 2 | DECOMP_NO_COMPOSE, 3900}, /* compatibility mapping */ + {0xFC73, 0, 2 | DECOMP_NO_COMPOSE, 3902}, /* compatibility mapping */ + {0xFC74, 0, 2 | DECOMP_NO_COMPOSE, 3904}, /* compatibility mapping */ + {0xFC75, 0, 2 | DECOMP_NO_COMPOSE, 3906}, /* compatibility mapping */ + {0xFC76, 0, 2 | DECOMP_NO_COMPOSE, 3908}, /* compatibility mapping */ + {0xFC77, 0, 2 | DECOMP_NO_COMPOSE, 3910}, /* compatibility mapping */ + {0xFC78, 0, 2 | DECOMP_NO_COMPOSE, 3912}, /* compatibility mapping */ + {0xFC79, 0, 2 | DECOMP_NO_COMPOSE, 3914}, /* compatibility mapping */ + {0xFC7A, 0, 2 | DECOMP_NO_COMPOSE, 3916}, /* compatibility mapping */ + {0xFC7B, 0, 2 | DECOMP_NO_COMPOSE, 3918}, /* compatibility mapping */ + {0xFC7C, 0, 2 | DECOMP_NO_COMPOSE, 3920}, /* compatibility mapping */ + {0xFC7D, 0, 2 | DECOMP_NO_COMPOSE, 3922}, /* compatibility mapping */ + {0xFC7E, 0, 2 | DECOMP_NO_COMPOSE, 3924}, /* compatibility mapping */ + {0xFC7F, 0, 2 | DECOMP_NO_COMPOSE, 3926}, /* compatibility mapping */ + {0xFC80, 0, 2 | DECOMP_NO_COMPOSE, 3928}, /* compatibility mapping */ + {0xFC81, 0, 2 | DECOMP_NO_COMPOSE, 3930}, /* compatibility mapping */ + {0xFC82, 0, 2 | DECOMP_NO_COMPOSE, 3932}, /* compatibility mapping */ + {0xFC83, 0, 2 | DECOMP_NO_COMPOSE, 3934}, /* compatibility mapping */ + {0xFC84, 0, 2 | DECOMP_NO_COMPOSE, 3936}, /* compatibility mapping */ + {0xFC85, 0, 2 | DECOMP_NO_COMPOSE, 3938}, /* compatibility mapping */ + {0xFC86, 0, 2 | DECOMP_NO_COMPOSE, 3940}, /* compatibility mapping */ + {0xFC87, 0, 2 | DECOMP_NO_COMPOSE, 3942}, /* compatibility mapping */ + {0xFC88, 0, 2 | DECOMP_NO_COMPOSE, 3944}, /* compatibility mapping */ + {0xFC89, 0, 2 | DECOMP_NO_COMPOSE, 3946}, /* compatibility mapping */ + {0xFC8A, 0, 2 | DECOMP_NO_COMPOSE, 3948}, /* compatibility mapping */ + {0xFC8B, 0, 2 | DECOMP_NO_COMPOSE, 3950}, /* compatibility mapping */ + {0xFC8C, 0, 2 | DECOMP_NO_COMPOSE, 3952}, /* compatibility mapping */ + {0xFC8D, 0, 2 | DECOMP_NO_COMPOSE, 3954}, /* compatibility mapping */ + {0xFC8E, 0, 2 | DECOMP_NO_COMPOSE, 3956}, /* compatibility mapping */ + {0xFC8F, 0, 2 | DECOMP_NO_COMPOSE, 3958}, /* compatibility mapping */ + {0xFC90, 0, 2 | DECOMP_NO_COMPOSE, 3960}, /* compatibility mapping */ + {0xFC91, 0, 2 | DECOMP_NO_COMPOSE, 3962}, /* compatibility mapping */ + {0xFC92, 0, 2 | DECOMP_NO_COMPOSE, 3964}, /* compatibility mapping */ + {0xFC93, 0, 2 | DECOMP_NO_COMPOSE, 3966}, /* compatibility mapping */ + {0xFC94, 0, 2 | DECOMP_NO_COMPOSE, 3968}, /* compatibility mapping */ + {0xFC95, 0, 2 | DECOMP_NO_COMPOSE, 3970}, /* compatibility mapping */ + {0xFC96, 0, 2 | DECOMP_NO_COMPOSE, 3972}, /* compatibility mapping */ + {0xFC97, 0, 2 | DECOMP_NO_COMPOSE, 3974}, /* compatibility mapping */ + {0xFC98, 0, 2 | DECOMP_NO_COMPOSE, 3976}, /* compatibility mapping */ + {0xFC99, 0, 2 | DECOMP_NO_COMPOSE, 3978}, /* compatibility mapping */ + {0xFC9A, 0, 2 | DECOMP_NO_COMPOSE, 3980}, /* compatibility mapping */ + {0xFC9B, 0, 2 | DECOMP_NO_COMPOSE, 3982}, /* compatibility mapping */ + {0xFC9C, 0, 2 | DECOMP_NO_COMPOSE, 3984}, /* compatibility mapping */ + {0xFC9D, 0, 2 | DECOMP_NO_COMPOSE, 3986}, /* compatibility mapping */ + {0xFC9E, 0, 2 | DECOMP_NO_COMPOSE, 3988}, /* compatibility mapping */ + {0xFC9F, 0, 2 | DECOMP_NO_COMPOSE, 3990}, /* compatibility mapping */ + {0xFCA0, 0, 2 | DECOMP_NO_COMPOSE, 3992}, /* compatibility mapping */ + {0xFCA1, 0, 2 | DECOMP_NO_COMPOSE, 3994}, /* compatibility mapping */ + {0xFCA2, 0, 2 | DECOMP_NO_COMPOSE, 3996}, /* compatibility mapping */ + {0xFCA3, 0, 2 | DECOMP_NO_COMPOSE, 3998}, /* compatibility mapping */ + {0xFCA4, 0, 2 | DECOMP_NO_COMPOSE, 4000}, /* compatibility mapping */ + {0xFCA5, 0, 2 | DECOMP_NO_COMPOSE, 4002}, /* compatibility mapping */ + {0xFCA6, 0, 2 | DECOMP_NO_COMPOSE, 4004}, /* compatibility mapping */ + {0xFCA7, 0, 2 | DECOMP_NO_COMPOSE, 4006}, /* compatibility mapping */ + {0xFCA8, 0, 2 | DECOMP_NO_COMPOSE, 4008}, /* compatibility mapping */ + {0xFCA9, 0, 2 | DECOMP_NO_COMPOSE, 4010}, /* compatibility mapping */ + {0xFCAA, 0, 2 | DECOMP_NO_COMPOSE, 4012}, /* compatibility mapping */ + {0xFCAB, 0, 2 | DECOMP_NO_COMPOSE, 4014}, /* compatibility mapping */ + {0xFCAC, 0, 2 | DECOMP_NO_COMPOSE, 4016}, /* compatibility mapping */ + {0xFCAD, 0, 2 | DECOMP_NO_COMPOSE, 4018}, /* compatibility mapping */ + {0xFCAE, 0, 2 | DECOMP_NO_COMPOSE, 4020}, /* compatibility mapping */ + {0xFCAF, 0, 2 | DECOMP_NO_COMPOSE, 4022}, /* compatibility mapping */ + {0xFCB0, 0, 2 | DECOMP_NO_COMPOSE, 4024}, /* compatibility mapping */ + {0xFCB1, 0, 2 | DECOMP_NO_COMPOSE, 4026}, /* compatibility mapping */ + {0xFCB2, 0, 2 | DECOMP_NO_COMPOSE, 4028}, /* compatibility mapping */ + {0xFCB3, 0, 2 | DECOMP_NO_COMPOSE, 4030}, /* compatibility mapping */ + {0xFCB4, 0, 2 | DECOMP_NO_COMPOSE, 4032}, /* compatibility mapping */ + {0xFCB5, 0, 2 | DECOMP_NO_COMPOSE, 4034}, /* compatibility mapping */ + {0xFCB6, 0, 2 | DECOMP_NO_COMPOSE, 4036}, /* compatibility mapping */ + {0xFCB7, 0, 2 | DECOMP_NO_COMPOSE, 4038}, /* compatibility mapping */ + {0xFCB8, 0, 2 | DECOMP_NO_COMPOSE, 4040}, /* compatibility mapping */ + {0xFCB9, 0, 2 | DECOMP_NO_COMPOSE, 4042}, /* compatibility mapping */ + {0xFCBA, 0, 2 | DECOMP_NO_COMPOSE, 4044}, /* compatibility mapping */ + {0xFCBB, 0, 2 | DECOMP_NO_COMPOSE, 4046}, /* compatibility mapping */ + {0xFCBC, 0, 2 | DECOMP_NO_COMPOSE, 4048}, /* compatibility mapping */ + {0xFCBD, 0, 2 | DECOMP_NO_COMPOSE, 4050}, /* compatibility mapping */ + {0xFCBE, 0, 2 | DECOMP_NO_COMPOSE, 4052}, /* compatibility mapping */ + {0xFCBF, 0, 2 | DECOMP_NO_COMPOSE, 4054}, /* compatibility mapping */ + {0xFCC0, 0, 2 | DECOMP_NO_COMPOSE, 4056}, /* compatibility mapping */ + {0xFCC1, 0, 2 | DECOMP_NO_COMPOSE, 4058}, /* compatibility mapping */ + {0xFCC2, 0, 2 | DECOMP_NO_COMPOSE, 4060}, /* compatibility mapping */ + {0xFCC3, 0, 2 | DECOMP_NO_COMPOSE, 4062}, /* compatibility mapping */ + {0xFCC4, 0, 2 | DECOMP_NO_COMPOSE, 4064}, /* compatibility mapping */ + {0xFCC5, 0, 2 | DECOMP_NO_COMPOSE, 4066}, /* compatibility mapping */ + {0xFCC6, 0, 2 | DECOMP_NO_COMPOSE, 4068}, /* compatibility mapping */ + {0xFCC7, 0, 2 | DECOMP_NO_COMPOSE, 4070}, /* compatibility mapping */ + {0xFCC8, 0, 2 | DECOMP_NO_COMPOSE, 4072}, /* compatibility mapping */ + {0xFCC9, 0, 2 | DECOMP_NO_COMPOSE, 4074}, /* compatibility mapping */ + {0xFCCA, 0, 2 | DECOMP_NO_COMPOSE, 4076}, /* compatibility mapping */ + {0xFCCB, 0, 2 | DECOMP_NO_COMPOSE, 4078}, /* compatibility mapping */ + {0xFCCC, 0, 2 | DECOMP_NO_COMPOSE, 4080}, /* compatibility mapping */ + {0xFCCD, 0, 2 | DECOMP_NO_COMPOSE, 4082}, /* compatibility mapping */ + {0xFCCE, 0, 2 | DECOMP_NO_COMPOSE, 4084}, /* compatibility mapping */ + {0xFCCF, 0, 2 | DECOMP_NO_COMPOSE, 4086}, /* compatibility mapping */ + {0xFCD0, 0, 2 | DECOMP_NO_COMPOSE, 4088}, /* compatibility mapping */ + {0xFCD1, 0, 2 | DECOMP_NO_COMPOSE, 4090}, /* compatibility mapping */ + {0xFCD2, 0, 2 | DECOMP_NO_COMPOSE, 4092}, /* compatibility mapping */ + {0xFCD3, 0, 2 | DECOMP_NO_COMPOSE, 4094}, /* compatibility mapping */ + {0xFCD4, 0, 2 | DECOMP_NO_COMPOSE, 4096}, /* compatibility mapping */ + {0xFCD5, 0, 2 | DECOMP_NO_COMPOSE, 4098}, /* compatibility mapping */ + {0xFCD6, 0, 2 | DECOMP_NO_COMPOSE, 4100}, /* compatibility mapping */ + {0xFCD7, 0, 2 | DECOMP_NO_COMPOSE, 4102}, /* compatibility mapping */ + {0xFCD8, 0, 2 | DECOMP_NO_COMPOSE, 4104}, /* compatibility mapping */ + {0xFCD9, 0, 2 | DECOMP_NO_COMPOSE, 4106}, /* compatibility mapping */ + {0xFCDA, 0, 2 | DECOMP_NO_COMPOSE, 4108}, /* compatibility mapping */ + {0xFCDB, 0, 2 | DECOMP_NO_COMPOSE, 4110}, /* compatibility mapping */ + {0xFCDC, 0, 2 | DECOMP_NO_COMPOSE, 4112}, /* compatibility mapping */ + {0xFCDD, 0, 2 | DECOMP_NO_COMPOSE, 4114}, /* compatibility mapping */ + {0xFCDE, 0, 2 | DECOMP_NO_COMPOSE, 4116}, /* compatibility mapping */ + {0xFCDF, 0, 2 | DECOMP_NO_COMPOSE, 4118}, /* compatibility mapping */ + {0xFCE0, 0, 2 | DECOMP_NO_COMPOSE, 4120}, /* compatibility mapping */ + {0xFCE1, 0, 2 | DECOMP_NO_COMPOSE, 4122}, /* compatibility mapping */ + {0xFCE2, 0, 2 | DECOMP_NO_COMPOSE, 4124}, /* compatibility mapping */ + {0xFCE3, 0, 2 | DECOMP_NO_COMPOSE, 4126}, /* compatibility mapping */ + {0xFCE4, 0, 2 | DECOMP_NO_COMPOSE, 4128}, /* compatibility mapping */ + {0xFCE5, 0, 2 | DECOMP_NO_COMPOSE, 4130}, /* compatibility mapping */ + {0xFCE6, 0, 2 | DECOMP_NO_COMPOSE, 4132}, /* compatibility mapping */ + {0xFCE7, 0, 2 | DECOMP_NO_COMPOSE, 4134}, /* compatibility mapping */ + {0xFCE8, 0, 2 | DECOMP_NO_COMPOSE, 4136}, /* compatibility mapping */ + {0xFCE9, 0, 2 | DECOMP_NO_COMPOSE, 4138}, /* compatibility mapping */ + {0xFCEA, 0, 2 | DECOMP_NO_COMPOSE, 4140}, /* compatibility mapping */ + {0xFCEB, 0, 2 | DECOMP_NO_COMPOSE, 4142}, /* compatibility mapping */ + {0xFCEC, 0, 2 | DECOMP_NO_COMPOSE, 4144}, /* compatibility mapping */ + {0xFCED, 0, 2 | DECOMP_NO_COMPOSE, 4146}, /* compatibility mapping */ + {0xFCEE, 0, 2 | DECOMP_NO_COMPOSE, 4148}, /* compatibility mapping */ + {0xFCEF, 0, 2 | DECOMP_NO_COMPOSE, 4150}, /* compatibility mapping */ + {0xFCF0, 0, 2 | DECOMP_NO_COMPOSE, 4152}, /* compatibility mapping */ + {0xFCF1, 0, 2 | DECOMP_NO_COMPOSE, 4154}, /* compatibility mapping */ + {0xFCF2, 0, 3, 4156}, + {0xFCF3, 0, 3, 4159}, + {0xFCF4, 0, 3, 4162}, + {0xFCF5, 0, 2 | DECOMP_NO_COMPOSE, 4165}, /* compatibility mapping */ + {0xFCF6, 0, 2 | DECOMP_NO_COMPOSE, 4167}, /* compatibility mapping */ + {0xFCF7, 0, 2 | DECOMP_NO_COMPOSE, 4169}, /* compatibility mapping */ + {0xFCF8, 0, 2 | DECOMP_NO_COMPOSE, 4171}, /* compatibility mapping */ + {0xFCF9, 0, 2 | DECOMP_NO_COMPOSE, 4173}, /* compatibility mapping */ + {0xFCFA, 0, 2 | DECOMP_NO_COMPOSE, 4175}, /* compatibility mapping */ + {0xFCFB, 0, 2 | DECOMP_NO_COMPOSE, 4177}, /* compatibility mapping */ + {0xFCFC, 0, 2 | DECOMP_NO_COMPOSE, 4179}, /* compatibility mapping */ + {0xFCFD, 0, 2 | DECOMP_NO_COMPOSE, 4181}, /* compatibility mapping */ + {0xFCFE, 0, 2 | DECOMP_NO_COMPOSE, 4183}, /* compatibility mapping */ + {0xFCFF, 0, 2 | DECOMP_NO_COMPOSE, 4185}, /* compatibility mapping */ + {0xFD00, 0, 2 | DECOMP_NO_COMPOSE, 4187}, /* compatibility mapping */ + {0xFD01, 0, 2 | DECOMP_NO_COMPOSE, 4189}, /* compatibility mapping */ + {0xFD02, 0, 2 | DECOMP_NO_COMPOSE, 4191}, /* compatibility mapping */ + {0xFD03, 0, 2 | DECOMP_NO_COMPOSE, 4193}, /* compatibility mapping */ + {0xFD04, 0, 2 | DECOMP_NO_COMPOSE, 4195}, /* compatibility mapping */ + {0xFD05, 0, 2 | DECOMP_NO_COMPOSE, 4197}, /* compatibility mapping */ + {0xFD06, 0, 2 | DECOMP_NO_COMPOSE, 4199}, /* compatibility mapping */ + {0xFD07, 0, 2 | DECOMP_NO_COMPOSE, 4201}, /* compatibility mapping */ + {0xFD08, 0, 2 | DECOMP_NO_COMPOSE, 4203}, /* compatibility mapping */ + {0xFD09, 0, 2 | DECOMP_NO_COMPOSE, 4205}, /* compatibility mapping */ + {0xFD0A, 0, 2 | DECOMP_NO_COMPOSE, 4207}, /* compatibility mapping */ + {0xFD0B, 0, 2 | DECOMP_NO_COMPOSE, 4209}, /* compatibility mapping */ + {0xFD0C, 0, 2 | DECOMP_NO_COMPOSE, 4211}, /* compatibility mapping */ + {0xFD0D, 0, 2 | DECOMP_NO_COMPOSE, 4213}, /* compatibility mapping */ + {0xFD0E, 0, 2 | DECOMP_NO_COMPOSE, 4215}, /* compatibility mapping */ + {0xFD0F, 0, 2 | DECOMP_NO_COMPOSE, 4217}, /* compatibility mapping */ + {0xFD10, 0, 2 | DECOMP_NO_COMPOSE, 4219}, /* compatibility mapping */ + {0xFD11, 0, 2 | DECOMP_NO_COMPOSE, 4221}, /* compatibility mapping */ + {0xFD12, 0, 2 | DECOMP_NO_COMPOSE, 4223}, /* compatibility mapping */ + {0xFD13, 0, 2 | DECOMP_NO_COMPOSE, 4225}, /* compatibility mapping */ + {0xFD14, 0, 2 | DECOMP_NO_COMPOSE, 4227}, /* compatibility mapping */ + {0xFD15, 0, 2 | DECOMP_NO_COMPOSE, 4229}, /* compatibility mapping */ + {0xFD16, 0, 2 | DECOMP_NO_COMPOSE, 4231}, /* compatibility mapping */ + {0xFD17, 0, 2 | DECOMP_NO_COMPOSE, 4233}, /* compatibility mapping */ + {0xFD18, 0, 2 | DECOMP_NO_COMPOSE, 4235}, /* compatibility mapping */ + {0xFD19, 0, 2 | DECOMP_NO_COMPOSE, 4237}, /* compatibility mapping */ + {0xFD1A, 0, 2 | DECOMP_NO_COMPOSE, 4239}, /* compatibility mapping */ + {0xFD1B, 0, 2 | DECOMP_NO_COMPOSE, 4241}, /* compatibility mapping */ + {0xFD1C, 0, 2 | DECOMP_NO_COMPOSE, 4243}, /* compatibility mapping */ + {0xFD1D, 0, 2 | DECOMP_NO_COMPOSE, 4245}, /* compatibility mapping */ + {0xFD1E, 0, 2 | DECOMP_NO_COMPOSE, 4247}, /* compatibility mapping */ + {0xFD1F, 0, 2 | DECOMP_NO_COMPOSE, 4249}, /* compatibility mapping */ + {0xFD20, 0, 2 | DECOMP_NO_COMPOSE, 4251}, /* compatibility mapping */ + {0xFD21, 0, 2 | DECOMP_NO_COMPOSE, 4253}, /* compatibility mapping */ + {0xFD22, 0, 2 | DECOMP_NO_COMPOSE, 4255}, /* compatibility mapping */ + {0xFD23, 0, 2 | DECOMP_NO_COMPOSE, 4257}, /* compatibility mapping */ + {0xFD24, 0, 2 | DECOMP_NO_COMPOSE, 4259}, /* compatibility mapping */ + {0xFD25, 0, 2 | DECOMP_NO_COMPOSE, 4261}, /* compatibility mapping */ + {0xFD26, 0, 2 | DECOMP_NO_COMPOSE, 4263}, /* compatibility mapping */ + {0xFD27, 0, 2 | DECOMP_NO_COMPOSE, 4265}, /* compatibility mapping */ + {0xFD28, 0, 2 | DECOMP_NO_COMPOSE, 4267}, /* compatibility mapping */ + {0xFD29, 0, 2 | DECOMP_NO_COMPOSE, 4269}, /* compatibility mapping */ + {0xFD2A, 0, 2 | DECOMP_NO_COMPOSE, 4271}, /* compatibility mapping */ + {0xFD2B, 0, 2 | DECOMP_NO_COMPOSE, 4273}, /* compatibility mapping */ + {0xFD2C, 0, 2 | DECOMP_NO_COMPOSE, 4275}, /* compatibility mapping */ + {0xFD2D, 0, 2 | DECOMP_NO_COMPOSE, 4277}, /* compatibility mapping */ + {0xFD2E, 0, 2 | DECOMP_NO_COMPOSE, 4279}, /* compatibility mapping */ + {0xFD2F, 0, 2 | DECOMP_NO_COMPOSE, 4281}, /* compatibility mapping */ + {0xFD30, 0, 2 | DECOMP_NO_COMPOSE, 4283}, /* compatibility mapping */ + {0xFD31, 0, 2 | DECOMP_NO_COMPOSE, 4285}, /* compatibility mapping */ + {0xFD32, 0, 2 | DECOMP_NO_COMPOSE, 4287}, /* compatibility mapping */ + {0xFD33, 0, 2 | DECOMP_NO_COMPOSE, 4289}, /* compatibility mapping */ + {0xFD34, 0, 2 | DECOMP_NO_COMPOSE, 4291}, /* compatibility mapping */ + {0xFD35, 0, 2 | DECOMP_NO_COMPOSE, 4293}, /* compatibility mapping */ + {0xFD36, 0, 2 | DECOMP_NO_COMPOSE, 4295}, /* compatibility mapping */ + {0xFD37, 0, 2 | DECOMP_NO_COMPOSE, 4297}, /* compatibility mapping */ + {0xFD38, 0, 2 | DECOMP_NO_COMPOSE, 4299}, /* compatibility mapping */ + {0xFD39, 0, 2 | DECOMP_NO_COMPOSE, 4301}, /* compatibility mapping */ + {0xFD3A, 0, 2 | DECOMP_NO_COMPOSE, 4303}, /* compatibility mapping */ + {0xFD3B, 0, 2 | DECOMP_NO_COMPOSE, 4305}, /* compatibility mapping */ + {0xFD3C, 0, 2 | DECOMP_NO_COMPOSE, 4307}, /* compatibility mapping */ + {0xFD3D, 0, 2 | DECOMP_NO_COMPOSE, 4309}, /* compatibility mapping */ + {0xFD50, 0, 3, 4311}, + {0xFD51, 0, 3, 4314}, + {0xFD52, 0, 3, 4317}, + {0xFD53, 0, 3, 4320}, + {0xFD54, 0, 3, 4323}, + {0xFD55, 0, 3, 4326}, + {0xFD56, 0, 3, 4329}, + {0xFD57, 0, 3, 4332}, + {0xFD58, 0, 3, 4335}, + {0xFD59, 0, 3, 4338}, + {0xFD5A, 0, 3, 4341}, + {0xFD5B, 0, 3, 4344}, + {0xFD5C, 0, 3, 4347}, + {0xFD5D, 0, 3, 4350}, + {0xFD5E, 0, 3, 4353}, + {0xFD5F, 0, 3, 4356}, + {0xFD60, 0, 3, 4359}, + {0xFD61, 0, 3, 4362}, + {0xFD62, 0, 3, 4365}, + {0xFD63, 0, 3, 4368}, + {0xFD64, 0, 3, 4371}, + {0xFD65, 0, 3, 4374}, + {0xFD66, 0, 3, 4377}, + {0xFD67, 0, 3, 4380}, + {0xFD68, 0, 3, 4383}, + {0xFD69, 0, 3, 4386}, + {0xFD6A, 0, 3, 4389}, + {0xFD6B, 0, 3, 4392}, + {0xFD6C, 0, 3, 4395}, + {0xFD6D, 0, 3, 4398}, + {0xFD6E, 0, 3, 4401}, + {0xFD6F, 0, 3, 4404}, + {0xFD70, 0, 3, 4407}, + {0xFD71, 0, 3, 4410}, + {0xFD72, 0, 3, 4413}, + {0xFD73, 0, 3, 4416}, + {0xFD74, 0, 3, 4419}, + {0xFD75, 0, 3, 4422}, + {0xFD76, 0, 3, 4425}, + {0xFD77, 0, 3, 4428}, + {0xFD78, 0, 3, 4431}, + {0xFD79, 0, 3, 4434}, + {0xFD7A, 0, 3, 4437}, + {0xFD7B, 0, 3, 4440}, + {0xFD7C, 0, 3, 4443}, + {0xFD7D, 0, 3, 4446}, + {0xFD7E, 0, 3, 4449}, + {0xFD7F, 0, 3, 4452}, + {0xFD80, 0, 3, 4455}, + {0xFD81, 0, 3, 4458}, + {0xFD82, 0, 3, 4461}, + {0xFD83, 0, 3, 4464}, + {0xFD84, 0, 3, 4467}, + {0xFD85, 0, 3, 4470}, + {0xFD86, 0, 3, 4473}, + {0xFD87, 0, 3, 4476}, + {0xFD88, 0, 3, 4479}, + {0xFD89, 0, 3, 4482}, + {0xFD8A, 0, 3, 4485}, + {0xFD8B, 0, 3, 4488}, + {0xFD8C, 0, 3, 4491}, + {0xFD8D, 0, 3, 4494}, + {0xFD8E, 0, 3, 4497}, + {0xFD8F, 0, 3, 4500}, + {0xFD92, 0, 3, 4503}, + {0xFD93, 0, 3, 4506}, + {0xFD94, 0, 3, 4509}, + {0xFD95, 0, 3, 4512}, + {0xFD96, 0, 3, 4515}, + {0xFD97, 0, 3, 4518}, + {0xFD98, 0, 3, 4521}, + {0xFD99, 0, 3, 4524}, + {0xFD9A, 0, 3, 4527}, + {0xFD9B, 0, 3, 4530}, + {0xFD9C, 0, 3, 4533}, + {0xFD9D, 0, 3, 4536}, + {0xFD9E, 0, 3, 4539}, + {0xFD9F, 0, 3, 4542}, + {0xFDA0, 0, 3, 4545}, + {0xFDA1, 0, 3, 4548}, + {0xFDA2, 0, 3, 4551}, + {0xFDA3, 0, 3, 4554}, + {0xFDA4, 0, 3, 4557}, + {0xFDA5, 0, 3, 4560}, + {0xFDA6, 0, 3, 4563}, + {0xFDA7, 0, 3, 4566}, + {0xFDA8, 0, 3, 4569}, + {0xFDA9, 0, 3, 4572}, + {0xFDAA, 0, 3, 4575}, + {0xFDAB, 0, 3, 4578}, + {0xFDAC, 0, 3, 4581}, + {0xFDAD, 0, 3, 4584}, + {0xFDAE, 0, 3, 4587}, + {0xFDAF, 0, 3, 4590}, + {0xFDB0, 0, 3, 4593}, + {0xFDB1, 0, 3, 4596}, + {0xFDB2, 0, 3, 4599}, + {0xFDB3, 0, 3, 4602}, + {0xFDB4, 0, 3, 4605}, + {0xFDB5, 0, 3, 4608}, + {0xFDB6, 0, 3, 4611}, + {0xFDB7, 0, 3, 4614}, + {0xFDB8, 0, 3, 4617}, + {0xFDB9, 0, 3, 4620}, + {0xFDBA, 0, 3, 4623}, + {0xFDBB, 0, 3, 4626}, + {0xFDBC, 0, 3, 4629}, + {0xFDBD, 0, 3, 4632}, + {0xFDBE, 0, 3, 4635}, + {0xFDBF, 0, 3, 4638}, + {0xFDC0, 0, 3, 4641}, + {0xFDC1, 0, 3, 4644}, + {0xFDC2, 0, 3, 4647}, + {0xFDC3, 0, 3, 4650}, + {0xFDC4, 0, 3, 4653}, + {0xFDC5, 0, 3, 4656}, + {0xFDC6, 0, 3, 4659}, + {0xFDC7, 0, 3, 4662}, + {0xFDF0, 0, 3, 4665}, + {0xFDF1, 0, 3, 4668}, + {0xFDF2, 0, 4, 4671}, + {0xFDF3, 0, 4, 4675}, + {0xFDF4, 0, 4, 4679}, + {0xFDF5, 0, 4, 4683}, + {0xFDF6, 0, 4, 4687}, + {0xFDF7, 0, 4, 4691}, + {0xFDF8, 0, 4, 4695}, + {0xFDF9, 0, 3, 4699}, + {0xFDFA, 0, 18, 4702}, + {0xFDFB, 0, 8, 4720}, + {0xFDFC, 0, 4, 4728}, {0xFE10, 0, 1 | DECOMP_INLINE, 0x002C}, {0xFE11, 0, 1 | DECOMP_INLINE, 0x3001}, {0xFE12, 0, 1 | DECOMP_INLINE, 0x3002}, @@ -4211,20 +4222,20 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFE69, 0, 1 | DECOMP_INLINE, 0x0024}, {0xFE6A, 0, 1 | DECOMP_INLINE, 0x0025}, {0xFE6B, 0, 1 | DECOMP_INLINE, 0x0040}, - {0xFE70, 0, 2 | DECOMP_NO_COMPOSE, 4730}, /* compatibility mapping */ - {0xFE71, 0, 2 | DECOMP_NO_COMPOSE, 4732}, /* compatibility mapping */ - {0xFE72, 0, 2 | DECOMP_NO_COMPOSE, 4734}, /* compatibility mapping */ - {0xFE74, 0, 2 | DECOMP_NO_COMPOSE, 4736}, /* compatibility mapping */ - {0xFE76, 0, 2 | DECOMP_NO_COMPOSE, 4738}, /* compatibility mapping */ - {0xFE77, 0, 2 | DECOMP_NO_COMPOSE, 4740}, /* compatibility mapping */ - {0xFE78, 0, 2 | DECOMP_NO_COMPOSE, 4742}, /* compatibility mapping */ - {0xFE79, 0, 2 | DECOMP_NO_COMPOSE, 4744}, /* compatibility mapping */ - {0xFE7A, 0, 2 | DECOMP_NO_COMPOSE, 4746}, /* compatibility mapping */ - {0xFE7B, 0, 2 | DECOMP_NO_COMPOSE, 4748}, /* compatibility mapping */ - {0xFE7C, 0, 2 | DECOMP_NO_COMPOSE, 4750}, /* compatibility mapping */ - {0xFE7D, 0, 2 | DECOMP_NO_COMPOSE, 4752}, /* compatibility mapping */ - {0xFE7E, 0, 2 | DECOMP_NO_COMPOSE, 4754}, /* compatibility mapping */ - {0xFE7F, 0, 2 | DECOMP_NO_COMPOSE, 4756}, /* compatibility mapping */ + {0xFE70, 0, 2 | DECOMP_NO_COMPOSE, 4732}, /* compatibility mapping */ + {0xFE71, 0, 2 | DECOMP_NO_COMPOSE, 4734}, /* compatibility mapping */ + {0xFE72, 0, 2 | DECOMP_NO_COMPOSE, 4736}, /* compatibility mapping */ + {0xFE74, 0, 2 | DECOMP_NO_COMPOSE, 4738}, /* compatibility mapping */ + {0xFE76, 0, 2 | DECOMP_NO_COMPOSE, 4740}, /* compatibility mapping */ + {0xFE77, 0, 2 | DECOMP_NO_COMPOSE, 4742}, /* compatibility mapping */ + {0xFE78, 0, 2 | DECOMP_NO_COMPOSE, 4744}, /* compatibility mapping */ + {0xFE79, 0, 2 | DECOMP_NO_COMPOSE, 4746}, /* compatibility mapping */ + {0xFE7A, 0, 2 | DECOMP_NO_COMPOSE, 4748}, /* compatibility mapping */ + {0xFE7B, 0, 2 | DECOMP_NO_COMPOSE, 4750}, /* compatibility mapping */ + {0xFE7C, 0, 2 | DECOMP_NO_COMPOSE, 4752}, /* compatibility mapping */ + {0xFE7D, 0, 2 | DECOMP_NO_COMPOSE, 4754}, /* compatibility mapping */ + {0xFE7E, 0, 2 | DECOMP_NO_COMPOSE, 4756}, /* compatibility mapping */ + {0xFE7F, 0, 2 | DECOMP_NO_COMPOSE, 4758}, /* compatibility mapping */ {0xFE80, 0, 1 | DECOMP_INLINE, 0x0621}, {0xFE81, 0, 1 | DECOMP_INLINE, 0x0622}, {0xFE82, 0, 1 | DECOMP_INLINE, 0x0622}, @@ -4342,14 +4353,14 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0xFEF2, 0, 1 | DECOMP_INLINE, 0x064A}, {0xFEF3, 0, 1 | DECOMP_INLINE, 0x064A}, {0xFEF4, 0, 1 | DECOMP_INLINE, 0x064A}, - {0xFEF5, 0, 2 | DECOMP_NO_COMPOSE, 4758}, /* compatibility mapping */ - {0xFEF6, 0, 2 | DECOMP_NO_COMPOSE, 4760}, /* compatibility mapping */ - {0xFEF7, 0, 2 | DECOMP_NO_COMPOSE, 4762}, /* compatibility mapping */ - {0xFEF8, 0, 2 | DECOMP_NO_COMPOSE, 4764}, /* compatibility mapping */ - {0xFEF9, 0, 2 | DECOMP_NO_COMPOSE, 4766}, /* compatibility mapping */ - {0xFEFA, 0, 2 | DECOMP_NO_COMPOSE, 4768}, /* compatibility mapping */ - {0xFEFB, 0, 2 | DECOMP_NO_COMPOSE, 4770}, /* compatibility mapping */ - {0xFEFC, 0, 2 | DECOMP_NO_COMPOSE, 4772}, /* compatibility mapping */ + {0xFEF5, 0, 2 | DECOMP_NO_COMPOSE, 4760}, /* compatibility mapping */ + {0xFEF6, 0, 2 | DECOMP_NO_COMPOSE, 4762}, /* compatibility mapping */ + {0xFEF7, 0, 2 | DECOMP_NO_COMPOSE, 4764}, /* compatibility mapping */ + {0xFEF8, 0, 2 | DECOMP_NO_COMPOSE, 4766}, /* compatibility mapping */ + {0xFEF9, 0, 2 | DECOMP_NO_COMPOSE, 4768}, /* compatibility mapping */ + {0xFEFA, 0, 2 | DECOMP_NO_COMPOSE, 4770}, /* compatibility mapping */ + {0xFEFB, 0, 2 | DECOMP_NO_COMPOSE, 4772}, /* compatibility mapping */ + {0xFEFC, 0, 2 | DECOMP_NO_COMPOSE, 4774}, /* compatibility mapping */ {0xFF01, 0, 1 | DECOMP_INLINE, 0x0021}, {0xFF02, 0, 1 | DECOMP_INLINE, 0x0022}, {0xFF03, 0, 1 | DECOMP_INLINE, 0x0023}, @@ -4590,18 +4601,33 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x10A3F, 9, 0, 0}, {0x10AE5, 230, 0, 0}, {0x10AE6, 220, 0, 0}, + {0x10D24, 230, 0, 0}, + {0x10D25, 230, 0, 0}, + {0x10D26, 230, 0, 0}, + {0x10D27, 230, 0, 0}, + {0x10F46, 220, 0, 0}, + {0x10F47, 220, 0, 0}, + {0x10F48, 230, 0, 0}, + {0x10F49, 230, 0, 0}, + {0x10F4A, 230, 0, 0}, + {0x10F4B, 220, 0, 0}, + {0x10F4C, 230, 0, 0}, + {0x10F4D, 220, 0, 0}, + {0x10F4E, 220, 0, 0}, + {0x10F4F, 220, 0, 0}, + {0x10F50, 220, 0, 0}, {0x11046, 9, 0, 0}, {0x1107F, 9, 0, 0}, - {0x1109A, 0, 2, 4774}, - {0x1109C, 0, 2, 4776}, - {0x110AB, 0, 2, 4778}, + {0x1109A, 0, 2, 4776}, + {0x1109C, 0, 2, 4778}, + {0x110AB, 0, 2, 4780}, {0x110B9, 9, 0, 0}, {0x110BA, 7, 0, 0}, {0x11100, 230, 0, 0}, {0x11101, 230, 0, 0}, {0x11102, 230, 0, 0}, - {0x1112E, 0, 2, 4780}, - {0x1112F, 0, 2, 4782}, + {0x1112E, 0, 2, 4782}, + {0x1112F, 0, 2, 4784}, {0x11133, 9, 0, 0}, {0x11134, 9, 0, 0}, {0x11173, 7, 0, 0}, @@ -4611,9 +4637,10 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x11236, 7, 0, 0}, {0x112E9, 7, 0, 0}, {0x112EA, 9, 0, 0}, + {0x1133B, 7, 0, 0}, {0x1133C, 7, 0, 0}, - {0x1134B, 0, 2, 4784}, - {0x1134C, 0, 2, 4786}, + {0x1134B, 0, 2, 4786}, + {0x1134C, 0, 2, 4788}, {0x1134D, 9, 0, 0}, {0x11366, 230, 0, 0}, {0x11367, 230, 0, 0}, @@ -4629,20 +4656,31 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x11374, 230, 0, 0}, {0x11442, 9, 0, 0}, {0x11446, 7, 0, 0}, - {0x114BB, 0, 2, 4788}, - {0x114BC, 0, 2, 4790}, - {0x114BE, 0, 2, 4792}, + {0x1145E, 230, 0, 0}, + {0x114BB, 0, 2, 4790}, + {0x114BC, 0, 2, 4792}, + {0x114BE, 0, 2, 4794}, {0x114C2, 9, 0, 0}, {0x114C3, 7, 0, 0}, - {0x115BA, 0, 2, 4794}, - {0x115BB, 0, 2, 4796}, + {0x115BA, 0, 2, 4796}, + {0x115BB, 0, 2, 4798}, {0x115BF, 9, 0, 0}, {0x115C0, 7, 0, 0}, {0x1163F, 9, 0, 0}, {0x116B6, 9, 0, 0}, {0x116B7, 7, 0, 0}, {0x1172B, 9, 0, 0}, + {0x11839, 9, 0, 0}, + {0x1183A, 7, 0, 0}, + {0x119E0, 9, 0, 0}, + {0x11A34, 9, 0, 0}, + {0x11A47, 9, 0, 0}, + {0x11A99, 9, 0, 0}, {0x11C3F, 9, 0, 0}, + {0x11D42, 7, 0, 0}, + {0x11D44, 9, 0, 0}, + {0x11D45, 9, 0, 0}, + {0x11D97, 9, 0, 0}, {0x16AF0, 1, 0, 0}, {0x16AF1, 1, 0, 0}, {0x16AF2, 1, 0, 0}, @@ -4656,13 +4694,13 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x16B35, 230, 0, 0}, {0x16B36, 230, 0, 0}, {0x1BC9E, 1, 0, 0}, - {0x1D15E, 0, 2 | DECOMP_NO_COMPOSE, 4798}, /* in exclusion list */ - {0x1D15F, 0, 2 | DECOMP_NO_COMPOSE, 4800}, /* in exclusion list */ - {0x1D160, 0, 2 | DECOMP_NO_COMPOSE, 4802}, /* in exclusion list */ - {0x1D161, 0, 2 | DECOMP_NO_COMPOSE, 4804}, /* in exclusion list */ - {0x1D162, 0, 2 | DECOMP_NO_COMPOSE, 4806}, /* in exclusion list */ - {0x1D163, 0, 2 | DECOMP_NO_COMPOSE, 4808}, /* in exclusion list */ - {0x1D164, 0, 2 | DECOMP_NO_COMPOSE, 4810}, /* in exclusion list */ + {0x1D15E, 0, 2 | DECOMP_NO_COMPOSE, 4800}, /* in exclusion list */ + {0x1D15F, 0, 2 | DECOMP_NO_COMPOSE, 4802}, /* in exclusion list */ + {0x1D160, 0, 2 | DECOMP_NO_COMPOSE, 4804}, /* in exclusion list */ + {0x1D161, 0, 2 | DECOMP_NO_COMPOSE, 4806}, /* in exclusion list */ + {0x1D162, 0, 2 | DECOMP_NO_COMPOSE, 4808}, /* in exclusion list */ + {0x1D163, 0, 2 | DECOMP_NO_COMPOSE, 4810}, /* in exclusion list */ + {0x1D164, 0, 2 | DECOMP_NO_COMPOSE, 4812}, /* in exclusion list */ {0x1D165, 216, 0, 0}, {0x1D166, 216, 0, 0}, {0x1D167, 1, 0, 0}, @@ -4693,12 +4731,12 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1D1AB, 230, 0, 0}, {0x1D1AC, 230, 0, 0}, {0x1D1AD, 230, 0, 0}, - {0x1D1BB, 0, 2 | DECOMP_NO_COMPOSE, 4812}, /* in exclusion list */ - {0x1D1BC, 0, 2 | DECOMP_NO_COMPOSE, 4814}, /* in exclusion list */ - {0x1D1BD, 0, 2 | DECOMP_NO_COMPOSE, 4816}, /* in exclusion list */ - {0x1D1BE, 0, 2 | DECOMP_NO_COMPOSE, 4818}, /* in exclusion list */ - {0x1D1BF, 0, 2 | DECOMP_NO_COMPOSE, 4820}, /* in exclusion list */ - {0x1D1C0, 0, 2 | DECOMP_NO_COMPOSE, 4822}, /* in exclusion list */ + {0x1D1BB, 0, 2 | DECOMP_NO_COMPOSE, 4814}, /* in exclusion list */ + {0x1D1BC, 0, 2 | DECOMP_NO_COMPOSE, 4816}, /* in exclusion list */ + {0x1D1BD, 0, 2 | DECOMP_NO_COMPOSE, 4818}, /* in exclusion list */ + {0x1D1BE, 0, 2 | DECOMP_NO_COMPOSE, 4820}, /* in exclusion list */ + {0x1D1BF, 0, 2 | DECOMP_NO_COMPOSE, 4822}, /* in exclusion list */ + {0x1D1C0, 0, 2 | DECOMP_NO_COMPOSE, 4824}, /* in exclusion list */ {0x1D242, 230, 0, 0}, {0x1D243, 230, 0, 0}, {0x1D244, 230, 0, 0}, @@ -5736,6 +5774,17 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1E028, 230, 0, 0}, {0x1E029, 230, 0, 0}, {0x1E02A, 230, 0, 0}, + {0x1E130, 230, 0, 0}, + {0x1E131, 230, 0, 0}, + {0x1E132, 230, 0, 0}, + {0x1E133, 230, 0, 0}, + {0x1E134, 230, 0, 0}, + {0x1E135, 230, 0, 0}, + {0x1E136, 230, 0, 0}, + {0x1E2EC, 230, 0, 0}, + {0x1E2ED, 230, 0, 0}, + {0x1E2EE, 230, 0, 0}, + {0x1E2EF, 230, 0, 0}, {0x1E8D0, 220, 0, 0}, {0x1E8D1, 220, 0, 0}, {0x1E8D2, 220, 0, 0}, @@ -5891,48 +5940,48 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1EEB9, 0, 1 | DECOMP_INLINE, 0x0636}, {0x1EEBA, 0, 1 | DECOMP_INLINE, 0x0638}, {0x1EEBB, 0, 1 | DECOMP_INLINE, 0x063A}, - {0x1F100, 0, 2 | DECOMP_NO_COMPOSE, 4824}, /* compatibility mapping */ - {0x1F101, 0, 2 | DECOMP_NO_COMPOSE, 4826}, /* compatibility mapping */ - {0x1F102, 0, 2 | DECOMP_NO_COMPOSE, 4828}, /* compatibility mapping */ - {0x1F103, 0, 2 | DECOMP_NO_COMPOSE, 4830}, /* compatibility mapping */ - {0x1F104, 0, 2 | DECOMP_NO_COMPOSE, 4832}, /* compatibility mapping */ - {0x1F105, 0, 2 | DECOMP_NO_COMPOSE, 4834}, /* compatibility mapping */ - {0x1F106, 0, 2 | DECOMP_NO_COMPOSE, 4836}, /* compatibility mapping */ - {0x1F107, 0, 2 | DECOMP_NO_COMPOSE, 4838}, /* compatibility mapping */ - {0x1F108, 0, 2 | DECOMP_NO_COMPOSE, 4840}, /* compatibility mapping */ - {0x1F109, 0, 2 | DECOMP_NO_COMPOSE, 4842}, /* compatibility mapping */ - {0x1F10A, 0, 2 | DECOMP_NO_COMPOSE, 4844}, /* compatibility mapping */ - {0x1F110, 0, 3, 4846}, - {0x1F111, 0, 3, 4849}, - {0x1F112, 0, 3, 4852}, - {0x1F113, 0, 3, 4855}, - {0x1F114, 0, 3, 4858}, - {0x1F115, 0, 3, 4861}, - {0x1F116, 0, 3, 4864}, - {0x1F117, 0, 3, 4867}, - {0x1F118, 0, 3, 4870}, - {0x1F119, 0, 3, 4873}, - {0x1F11A, 0, 3, 4876}, - {0x1F11B, 0, 3, 4879}, - {0x1F11C, 0, 3, 4882}, - {0x1F11D, 0, 3, 4885}, - {0x1F11E, 0, 3, 4888}, - {0x1F11F, 0, 3, 4891}, - {0x1F120, 0, 3, 4894}, - {0x1F121, 0, 3, 4897}, - {0x1F122, 0, 3, 4900}, - {0x1F123, 0, 3, 4903}, - {0x1F124, 0, 3, 4906}, - {0x1F125, 0, 3, 4909}, - {0x1F126, 0, 3, 4912}, - {0x1F127, 0, 3, 4915}, - {0x1F128, 0, 3, 4918}, - {0x1F129, 0, 3, 4921}, - {0x1F12A, 0, 3, 4924}, + {0x1F100, 0, 2 | DECOMP_NO_COMPOSE, 4826}, /* compatibility mapping */ + {0x1F101, 0, 2 | DECOMP_NO_COMPOSE, 4828}, /* compatibility mapping */ + {0x1F102, 0, 2 | DECOMP_NO_COMPOSE, 4830}, /* compatibility mapping */ + {0x1F103, 0, 2 | DECOMP_NO_COMPOSE, 4832}, /* compatibility mapping */ + {0x1F104, 0, 2 | DECOMP_NO_COMPOSE, 4834}, /* compatibility mapping */ + {0x1F105, 0, 2 | DECOMP_NO_COMPOSE, 4836}, /* compatibility mapping */ + {0x1F106, 0, 2 | DECOMP_NO_COMPOSE, 4838}, /* compatibility mapping */ + {0x1F107, 0, 2 | DECOMP_NO_COMPOSE, 4840}, /* compatibility mapping */ + {0x1F108, 0, 2 | DECOMP_NO_COMPOSE, 4842}, /* compatibility mapping */ + {0x1F109, 0, 2 | DECOMP_NO_COMPOSE, 4844}, /* compatibility mapping */ + {0x1F10A, 0, 2 | DECOMP_NO_COMPOSE, 4846}, /* compatibility mapping */ + {0x1F110, 0, 3, 4848}, + {0x1F111, 0, 3, 4851}, + {0x1F112, 0, 3, 4854}, + {0x1F113, 0, 3, 4857}, + {0x1F114, 0, 3, 4860}, + {0x1F115, 0, 3, 4863}, + {0x1F116, 0, 3, 4866}, + {0x1F117, 0, 3, 4869}, + {0x1F118, 0, 3, 4872}, + {0x1F119, 0, 3, 4875}, + {0x1F11A, 0, 3, 4878}, + {0x1F11B, 0, 3, 4881}, + {0x1F11C, 0, 3, 4884}, + {0x1F11D, 0, 3, 4887}, + {0x1F11E, 0, 3, 4890}, + {0x1F11F, 0, 3, 4893}, + {0x1F120, 0, 3, 4896}, + {0x1F121, 0, 3, 4899}, + {0x1F122, 0, 3, 4902}, + {0x1F123, 0, 3, 4905}, + {0x1F124, 0, 3, 4908}, + {0x1F125, 0, 3, 4911}, + {0x1F126, 0, 3, 4914}, + {0x1F127, 0, 3, 4917}, + {0x1F128, 0, 3, 4920}, + {0x1F129, 0, 3, 4923}, + {0x1F12A, 0, 3, 4926}, {0x1F12B, 0, 1 | DECOMP_INLINE, 0x0043}, {0x1F12C, 0, 1 | DECOMP_INLINE, 0x0052}, - {0x1F12D, 0, 2 | DECOMP_NO_COMPOSE, 4927}, /* compatibility mapping */ - {0x1F12E, 0, 2 | DECOMP_NO_COMPOSE, 4929}, /* compatibility mapping */ + {0x1F12D, 0, 2 | DECOMP_NO_COMPOSE, 4929}, /* compatibility mapping */ + {0x1F12E, 0, 2 | DECOMP_NO_COMPOSE, 4931}, /* compatibility mapping */ {0x1F130, 0, 1 | DECOMP_INLINE, 0x0041}, {0x1F131, 0, 1 | DECOMP_INLINE, 0x0042}, {0x1F132, 0, 1 | DECOMP_INLINE, 0x0043}, @@ -5959,17 +6008,18 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1F147, 0, 1 | DECOMP_INLINE, 0x0058}, {0x1F148, 0, 1 | DECOMP_INLINE, 0x0059}, {0x1F149, 0, 1 | DECOMP_INLINE, 0x005A}, - {0x1F14A, 0, 2 | DECOMP_NO_COMPOSE, 4931}, /* compatibility mapping */ - {0x1F14B, 0, 2 | DECOMP_NO_COMPOSE, 4933}, /* compatibility mapping */ - {0x1F14C, 0, 2 | DECOMP_NO_COMPOSE, 4935}, /* compatibility mapping */ - {0x1F14D, 0, 2 | DECOMP_NO_COMPOSE, 4937}, /* compatibility mapping */ - {0x1F14E, 0, 3, 4939}, - {0x1F14F, 0, 2 | DECOMP_NO_COMPOSE, 4942}, /* compatibility mapping */ - {0x1F16A, 0, 2 | DECOMP_NO_COMPOSE, 4944}, /* compatibility mapping */ - {0x1F16B, 0, 2 | DECOMP_NO_COMPOSE, 4946}, /* compatibility mapping */ - {0x1F190, 0, 2 | DECOMP_NO_COMPOSE, 4948}, /* compatibility mapping */ - {0x1F200, 0, 2 | DECOMP_NO_COMPOSE, 4950}, /* compatibility mapping */ - {0x1F201, 0, 2 | DECOMP_NO_COMPOSE, 4952}, /* compatibility mapping */ + {0x1F14A, 0, 2 | DECOMP_NO_COMPOSE, 4933}, /* compatibility mapping */ + {0x1F14B, 0, 2 | DECOMP_NO_COMPOSE, 4935}, /* compatibility mapping */ + {0x1F14C, 0, 2 | DECOMP_NO_COMPOSE, 4937}, /* compatibility mapping */ + {0x1F14D, 0, 2 | DECOMP_NO_COMPOSE, 4939}, /* compatibility mapping */ + {0x1F14E, 0, 3, 4941}, + {0x1F14F, 0, 2 | DECOMP_NO_COMPOSE, 4944}, /* compatibility mapping */ + {0x1F16A, 0, 2 | DECOMP_NO_COMPOSE, 4946}, /* compatibility mapping */ + {0x1F16B, 0, 2 | DECOMP_NO_COMPOSE, 4948}, /* compatibility mapping */ + {0x1F16C, 0, 2 | DECOMP_NO_COMPOSE, 4950}, /* compatibility mapping */ + {0x1F190, 0, 2 | DECOMP_NO_COMPOSE, 4952}, /* compatibility mapping */ + {0x1F200, 0, 2 | DECOMP_NO_COMPOSE, 4954}, /* compatibility mapping */ + {0x1F201, 0, 2 | DECOMP_NO_COMPOSE, 4956}, /* compatibility mapping */ {0x1F202, 0, 1 | DECOMP_INLINE, 0x30B5}, {0x1F210, 0, 1 | DECOMP_INLINE, 0x624B}, {0x1F211, 0, 1 | DECOMP_INLINE, 0x5B57}, @@ -6015,21 +6065,21 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x1F239, 0, 1 | DECOMP_INLINE, 0x5272}, {0x1F23A, 0, 1 | DECOMP_INLINE, 0x55B6}, {0x1F23B, 0, 1 | DECOMP_INLINE, 0x914D}, - {0x1F240, 0, 3, 4954}, - {0x1F241, 0, 3, 4957}, - {0x1F242, 0, 3, 4960}, - {0x1F243, 0, 3, 4963}, - {0x1F244, 0, 3, 4966}, - {0x1F245, 0, 3, 4969}, - {0x1F246, 0, 3, 4972}, - {0x1F247, 0, 3, 4975}, - {0x1F248, 0, 3, 4978}, + {0x1F240, 0, 3, 4958}, + {0x1F241, 0, 3, 4961}, + {0x1F242, 0, 3, 4964}, + {0x1F243, 0, 3, 4967}, + {0x1F244, 0, 3, 4970}, + {0x1F245, 0, 3, 4973}, + {0x1F246, 0, 3, 4976}, + {0x1F247, 0, 3, 4979}, + {0x1F248, 0, 3, 4982}, {0x1F250, 0, 1 | DECOMP_INLINE, 0x5F97}, {0x1F251, 0, 1 | DECOMP_INLINE, 0x53EF}, {0x2F800, 0, 1 | DECOMP_INLINE, 0x4E3D}, {0x2F801, 0, 1 | DECOMP_INLINE, 0x4E38}, {0x2F802, 0, 1 | DECOMP_INLINE, 0x4E41}, - {0x2F803, 0, 1, 4981}, + {0x2F803, 0, 1, 4985}, {0x2F804, 0, 1 | DECOMP_INLINE, 0x4F60}, {0x2F805, 0, 1 | DECOMP_INLINE, 0x4FAE}, {0x2F806, 0, 1 | DECOMP_INLINE, 0x4FBB}, @@ -6039,22 +6089,22 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F80A, 0, 1 | DECOMP_INLINE, 0x50E7}, {0x2F80B, 0, 1 | DECOMP_INLINE, 0x50CF}, {0x2F80C, 0, 1 | DECOMP_INLINE, 0x349E}, - {0x2F80D, 0, 1, 4982}, + {0x2F80D, 0, 1, 4986}, {0x2F80E, 0, 1 | DECOMP_INLINE, 0x514D}, {0x2F80F, 0, 1 | DECOMP_INLINE, 0x5154}, {0x2F810, 0, 1 | DECOMP_INLINE, 0x5164}, {0x2F811, 0, 1 | DECOMP_INLINE, 0x5177}, - {0x2F812, 0, 1, 4983}, + {0x2F812, 0, 1, 4987}, {0x2F813, 0, 1 | DECOMP_INLINE, 0x34B9}, {0x2F814, 0, 1 | DECOMP_INLINE, 0x5167}, {0x2F815, 0, 1 | DECOMP_INLINE, 0x518D}, - {0x2F816, 0, 1, 4984}, + {0x2F816, 0, 1, 4988}, {0x2F817, 0, 1 | DECOMP_INLINE, 0x5197}, {0x2F818, 0, 1 | DECOMP_INLINE, 0x51A4}, {0x2F819, 0, 1 | DECOMP_INLINE, 0x4ECC}, {0x2F81A, 0, 1 | DECOMP_INLINE, 0x51AC}, {0x2F81B, 0, 1 | DECOMP_INLINE, 0x51B5}, - {0x2F81C, 0, 1, 4985}, + {0x2F81C, 0, 1, 4989}, {0x2F81D, 0, 1 | DECOMP_INLINE, 0x51F5}, {0x2F81E, 0, 1 | DECOMP_INLINE, 0x5203}, {0x2F81F, 0, 1 | DECOMP_INLINE, 0x34DF}, @@ -6078,11 +6128,11 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F831, 0, 1 | DECOMP_INLINE, 0x537F}, {0x2F832, 0, 1 | DECOMP_INLINE, 0x537F}, {0x2F833, 0, 1 | DECOMP_INLINE, 0x537F}, - {0x2F834, 0, 1, 4986}, + {0x2F834, 0, 1, 4990}, {0x2F835, 0, 1 | DECOMP_INLINE, 0x7070}, {0x2F836, 0, 1 | DECOMP_INLINE, 0x53CA}, {0x2F837, 0, 1 | DECOMP_INLINE, 0x53DF}, - {0x2F838, 0, 1, 4987}, + {0x2F838, 0, 1, 4991}, {0x2F839, 0, 1 | DECOMP_INLINE, 0x53EB}, {0x2F83A, 0, 1 | DECOMP_INLINE, 0x53F1}, {0x2F83B, 0, 1 | DECOMP_INLINE, 0x5406}, @@ -6115,15 +6165,15 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F856, 0, 1 | DECOMP_INLINE, 0x5832}, {0x2F857, 0, 1 | DECOMP_INLINE, 0x5831}, {0x2F858, 0, 1 | DECOMP_INLINE, 0x58AC}, - {0x2F859, 0, 1, 4988}, + {0x2F859, 0, 1, 4992}, {0x2F85A, 0, 1 | DECOMP_INLINE, 0x58F2}, {0x2F85B, 0, 1 | DECOMP_INLINE, 0x58F7}, {0x2F85C, 0, 1 | DECOMP_INLINE, 0x5906}, {0x2F85D, 0, 1 | DECOMP_INLINE, 0x591A}, {0x2F85E, 0, 1 | DECOMP_INLINE, 0x5922}, {0x2F85F, 0, 1 | DECOMP_INLINE, 0x5962}, - {0x2F860, 0, 1, 4989}, - {0x2F861, 0, 1, 4990}, + {0x2F860, 0, 1, 4993}, + {0x2F861, 0, 1, 4994}, {0x2F862, 0, 1 | DECOMP_INLINE, 0x59EC}, {0x2F863, 0, 1 | DECOMP_INLINE, 0x5A1B}, {0x2F864, 0, 1 | DECOMP_INLINE, 0x5A27}, @@ -6134,12 +6184,12 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F869, 0, 1 | DECOMP_INLINE, 0x5B08}, {0x2F86A, 0, 1 | DECOMP_INLINE, 0x5B3E}, {0x2F86B, 0, 1 | DECOMP_INLINE, 0x5B3E}, - {0x2F86C, 0, 1, 4991}, + {0x2F86C, 0, 1, 4995}, {0x2F86D, 0, 1 | DECOMP_INLINE, 0x5BC3}, {0x2F86E, 0, 1 | DECOMP_INLINE, 0x5BD8}, {0x2F86F, 0, 1 | DECOMP_INLINE, 0x5BE7}, {0x2F870, 0, 1 | DECOMP_INLINE, 0x5BF3}, - {0x2F871, 0, 1, 4992}, + {0x2F871, 0, 1, 4996}, {0x2F872, 0, 1 | DECOMP_INLINE, 0x5BFF}, {0x2F873, 0, 1 | DECOMP_INLINE, 0x5C06}, {0x2F874, 0, 1 | DECOMP_INLINE, 0x5F53}, @@ -6149,9 +6199,9 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F878, 0, 1 | DECOMP_INLINE, 0x5C6E}, {0x2F879, 0, 1 | DECOMP_INLINE, 0x5CC0}, {0x2F87A, 0, 1 | DECOMP_INLINE, 0x5C8D}, - {0x2F87B, 0, 1, 4993}, + {0x2F87B, 0, 1, 4997}, {0x2F87C, 0, 1 | DECOMP_INLINE, 0x5D43}, - {0x2F87D, 0, 1, 4994}, + {0x2F87D, 0, 1, 4998}, {0x2F87E, 0, 1 | DECOMP_INLINE, 0x5D6E}, {0x2F87F, 0, 1 | DECOMP_INLINE, 0x5D6B}, {0x2F880, 0, 1 | DECOMP_INLINE, 0x5D7C}, @@ -6163,22 +6213,22 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F886, 0, 1 | DECOMP_INLINE, 0x5E3D}, {0x2F887, 0, 1 | DECOMP_INLINE, 0x5E69}, {0x2F888, 0, 1 | DECOMP_INLINE, 0x3862}, - {0x2F889, 0, 1, 4995}, + {0x2F889, 0, 1, 4999}, {0x2F88A, 0, 1 | DECOMP_INLINE, 0x387C}, {0x2F88B, 0, 1 | DECOMP_INLINE, 0x5EB0}, {0x2F88C, 0, 1 | DECOMP_INLINE, 0x5EB3}, {0x2F88D, 0, 1 | DECOMP_INLINE, 0x5EB6}, {0x2F88E, 0, 1 | DECOMP_INLINE, 0x5ECA}, - {0x2F88F, 0, 1, 4996}, + {0x2F88F, 0, 1, 5000}, {0x2F890, 0, 1 | DECOMP_INLINE, 0x5EFE}, - {0x2F891, 0, 1, 4997}, - {0x2F892, 0, 1, 4998}, + {0x2F891, 0, 1, 5001}, + {0x2F892, 0, 1, 5002}, {0x2F893, 0, 1 | DECOMP_INLINE, 0x8201}, {0x2F894, 0, 1 | DECOMP_INLINE, 0x5F22}, {0x2F895, 0, 1 | DECOMP_INLINE, 0x5F22}, {0x2F896, 0, 1 | DECOMP_INLINE, 0x38C7}, - {0x2F897, 0, 1, 4999}, - {0x2F898, 0, 1, 5000}, + {0x2F897, 0, 1, 5003}, + {0x2F898, 0, 1, 5004}, {0x2F899, 0, 1 | DECOMP_INLINE, 0x5F62}, {0x2F89A, 0, 1 | DECOMP_INLINE, 0x5F6B}, {0x2F89B, 0, 1 | DECOMP_INLINE, 0x38E3}, @@ -6190,7 +6240,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F8A1, 0, 1 | DECOMP_INLINE, 0x393A}, {0x2F8A2, 0, 1 | DECOMP_INLINE, 0x391C}, {0x2F8A3, 0, 1 | DECOMP_INLINE, 0x6094}, - {0x2F8A4, 0, 1, 5001}, + {0x2F8A4, 0, 1, 5005}, {0x2F8A5, 0, 1 | DECOMP_INLINE, 0x60C7}, {0x2F8A6, 0, 1 | DECOMP_INLINE, 0x6148}, {0x2F8A7, 0, 1 | DECOMP_INLINE, 0x614C}, @@ -6210,13 +6260,13 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F8B5, 0, 1 | DECOMP_INLINE, 0x62B1}, {0x2F8B6, 0, 1 | DECOMP_INLINE, 0x62D4}, {0x2F8B7, 0, 1 | DECOMP_INLINE, 0x6350}, - {0x2F8B8, 0, 1, 5002}, + {0x2F8B8, 0, 1, 5006}, {0x2F8B9, 0, 1 | DECOMP_INLINE, 0x633D}, {0x2F8BA, 0, 1 | DECOMP_INLINE, 0x62FC}, {0x2F8BB, 0, 1 | DECOMP_INLINE, 0x6368}, {0x2F8BC, 0, 1 | DECOMP_INLINE, 0x6383}, {0x2F8BD, 0, 1 | DECOMP_INLINE, 0x63E4}, - {0x2F8BE, 0, 1, 5003}, + {0x2F8BE, 0, 1, 5007}, {0x2F8BF, 0, 1 | DECOMP_INLINE, 0x6422}, {0x2F8C0, 0, 1 | DECOMP_INLINE, 0x63C5}, {0x2F8C1, 0, 1 | DECOMP_INLINE, 0x63A9}, @@ -6228,7 +6278,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F8C7, 0, 1 | DECOMP_INLINE, 0x3A6C}, {0x2F8C8, 0, 1 | DECOMP_INLINE, 0x654F}, {0x2F8C9, 0, 1 | DECOMP_INLINE, 0x656C}, - {0x2F8CA, 0, 1, 5004}, + {0x2F8CA, 0, 1, 5008}, {0x2F8CB, 0, 1 | DECOMP_INLINE, 0x65E3}, {0x2F8CC, 0, 1 | DECOMP_INLINE, 0x66F8}, {0x2F8CD, 0, 1 | DECOMP_INLINE, 0x6649}, @@ -6247,13 +6297,13 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F8DA, 0, 1 | DECOMP_INLINE, 0x6721}, {0x2F8DB, 0, 1 | DECOMP_INLINE, 0x675E}, {0x2F8DC, 0, 1 | DECOMP_INLINE, 0x6753}, - {0x2F8DD, 0, 1, 5005}, + {0x2F8DD, 0, 1, 5009}, {0x2F8DE, 0, 1 | DECOMP_INLINE, 0x3B49}, {0x2F8DF, 0, 1 | DECOMP_INLINE, 0x67FA}, {0x2F8E0, 0, 1 | DECOMP_INLINE, 0x6785}, {0x2F8E1, 0, 1 | DECOMP_INLINE, 0x6852}, {0x2F8E2, 0, 1 | DECOMP_INLINE, 0x6885}, - {0x2F8E3, 0, 1, 5006}, + {0x2F8E3, 0, 1, 5010}, {0x2F8E4, 0, 1 | DECOMP_INLINE, 0x688E}, {0x2F8E5, 0, 1 | DECOMP_INLINE, 0x681F}, {0x2F8E6, 0, 1 | DECOMP_INLINE, 0x6914}, @@ -6262,22 +6312,22 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F8E9, 0, 1 | DECOMP_INLINE, 0x69A3}, {0x2F8EA, 0, 1 | DECOMP_INLINE, 0x69EA}, {0x2F8EB, 0, 1 | DECOMP_INLINE, 0x6AA8}, - {0x2F8EC, 0, 1, 5007}, + {0x2F8EC, 0, 1, 5011}, {0x2F8ED, 0, 1 | DECOMP_INLINE, 0x6ADB}, {0x2F8EE, 0, 1 | DECOMP_INLINE, 0x3C18}, {0x2F8EF, 0, 1 | DECOMP_INLINE, 0x6B21}, - {0x2F8F0, 0, 1, 5008}, + {0x2F8F0, 0, 1, 5012}, {0x2F8F1, 0, 1 | DECOMP_INLINE, 0x6B54}, {0x2F8F2, 0, 1 | DECOMP_INLINE, 0x3C4E}, {0x2F8F3, 0, 1 | DECOMP_INLINE, 0x6B72}, {0x2F8F4, 0, 1 | DECOMP_INLINE, 0x6B9F}, {0x2F8F5, 0, 1 | DECOMP_INLINE, 0x6BBA}, {0x2F8F6, 0, 1 | DECOMP_INLINE, 0x6BBB}, - {0x2F8F7, 0, 1, 5009}, - {0x2F8F8, 0, 1, 5010}, - {0x2F8F9, 0, 1, 5011}, + {0x2F8F7, 0, 1, 5013}, + {0x2F8F8, 0, 1, 5014}, + {0x2F8F9, 0, 1, 5015}, {0x2F8FA, 0, 1 | DECOMP_INLINE, 0x6C4E}, - {0x2F8FB, 0, 1, 5012}, + {0x2F8FB, 0, 1, 5016}, {0x2F8FC, 0, 1 | DECOMP_INLINE, 0x6CBF}, {0x2F8FD, 0, 1 | DECOMP_INLINE, 0x6CCD}, {0x2F8FE, 0, 1 | DECOMP_INLINE, 0x6C67}, @@ -6288,18 +6338,18 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F903, 0, 1 | DECOMP_INLINE, 0x6D69}, {0x2F904, 0, 1 | DECOMP_INLINE, 0x6D78}, {0x2F905, 0, 1 | DECOMP_INLINE, 0x6D85}, - {0x2F906, 0, 1, 5013}, + {0x2F906, 0, 1, 5017}, {0x2F907, 0, 1 | DECOMP_INLINE, 0x6D34}, {0x2F908, 0, 1 | DECOMP_INLINE, 0x6E2F}, {0x2F909, 0, 1 | DECOMP_INLINE, 0x6E6E}, {0x2F90A, 0, 1 | DECOMP_INLINE, 0x3D33}, {0x2F90B, 0, 1 | DECOMP_INLINE, 0x6ECB}, {0x2F90C, 0, 1 | DECOMP_INLINE, 0x6EC7}, - {0x2F90D, 0, 1, 5014}, + {0x2F90D, 0, 1, 5018}, {0x2F90E, 0, 1 | DECOMP_INLINE, 0x6DF9}, {0x2F90F, 0, 1 | DECOMP_INLINE, 0x6F6E}, - {0x2F910, 0, 1, 5015}, - {0x2F911, 0, 1, 5016}, + {0x2F910, 0, 1, 5019}, + {0x2F911, 0, 1, 5020}, {0x2F912, 0, 1 | DECOMP_INLINE, 0x6FC6}, {0x2F913, 0, 1 | DECOMP_INLINE, 0x7039}, {0x2F914, 0, 1 | DECOMP_INLINE, 0x701E}, @@ -6309,19 +6359,19 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F918, 0, 1 | DECOMP_INLINE, 0x707D}, {0x2F919, 0, 1 | DECOMP_INLINE, 0x7077}, {0x2F91A, 0, 1 | DECOMP_INLINE, 0x70AD}, - {0x2F91B, 0, 1, 5017}, + {0x2F91B, 0, 1, 5021}, {0x2F91C, 0, 1 | DECOMP_INLINE, 0x7145}, - {0x2F91D, 0, 1, 5018}, + {0x2F91D, 0, 1, 5022}, {0x2F91E, 0, 1 | DECOMP_INLINE, 0x719C}, - {0x2F91F, 0, 1, 5019}, + {0x2F91F, 0, 1, 5023}, {0x2F920, 0, 1 | DECOMP_INLINE, 0x7228}, {0x2F921, 0, 1 | DECOMP_INLINE, 0x7235}, {0x2F922, 0, 1 | DECOMP_INLINE, 0x7250}, - {0x2F923, 0, 1, 5020}, + {0x2F923, 0, 1, 5024}, {0x2F924, 0, 1 | DECOMP_INLINE, 0x7280}, {0x2F925, 0, 1 | DECOMP_INLINE, 0x7295}, - {0x2F926, 0, 1, 5021}, - {0x2F927, 0, 1, 5022}, + {0x2F926, 0, 1, 5025}, + {0x2F927, 0, 1, 5026}, {0x2F928, 0, 1 | DECOMP_INLINE, 0x737A}, {0x2F929, 0, 1 | DECOMP_INLINE, 0x738B}, {0x2F92A, 0, 1 | DECOMP_INLINE, 0x3EAC}, @@ -6335,22 +6385,22 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F932, 0, 1 | DECOMP_INLINE, 0x74CA}, {0x2F933, 0, 1 | DECOMP_INLINE, 0x3F1B}, {0x2F934, 0, 1 | DECOMP_INLINE, 0x7524}, - {0x2F935, 0, 1, 5023}, + {0x2F935, 0, 1, 5027}, {0x2F936, 0, 1 | DECOMP_INLINE, 0x753E}, - {0x2F937, 0, 1, 5024}, + {0x2F937, 0, 1, 5028}, {0x2F938, 0, 1 | DECOMP_INLINE, 0x7570}, - {0x2F939, 0, 1, 5025}, + {0x2F939, 0, 1, 5029}, {0x2F93A, 0, 1 | DECOMP_INLINE, 0x7610}, - {0x2F93B, 0, 1, 5026}, - {0x2F93C, 0, 1, 5027}, - {0x2F93D, 0, 1, 5028}, + {0x2F93B, 0, 1, 5030}, + {0x2F93C, 0, 1, 5031}, + {0x2F93D, 0, 1, 5032}, {0x2F93E, 0, 1 | DECOMP_INLINE, 0x3FFC}, {0x2F93F, 0, 1 | DECOMP_INLINE, 0x4008}, {0x2F940, 0, 1 | DECOMP_INLINE, 0x76F4}, - {0x2F941, 0, 1, 5029}, - {0x2F942, 0, 1, 5030}, - {0x2F943, 0, 1, 5031}, - {0x2F944, 0, 1, 5032}, + {0x2F941, 0, 1, 5033}, + {0x2F942, 0, 1, 5034}, + {0x2F943, 0, 1, 5035}, + {0x2F944, 0, 1, 5036}, {0x2F945, 0, 1 | DECOMP_INLINE, 0x771E}, {0x2F946, 0, 1 | DECOMP_INLINE, 0x771F}, {0x2F947, 0, 1 | DECOMP_INLINE, 0x771F}, @@ -6359,68 +6409,68 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F94A, 0, 1 | DECOMP_INLINE, 0x778B}, {0x2F94B, 0, 1 | DECOMP_INLINE, 0x4046}, {0x2F94C, 0, 1 | DECOMP_INLINE, 0x4096}, - {0x2F94D, 0, 1, 5033}, + {0x2F94D, 0, 1, 5037}, {0x2F94E, 0, 1 | DECOMP_INLINE, 0x784E}, {0x2F94F, 0, 1 | DECOMP_INLINE, 0x788C}, {0x2F950, 0, 1 | DECOMP_INLINE, 0x78CC}, {0x2F951, 0, 1 | DECOMP_INLINE, 0x40E3}, - {0x2F952, 0, 1, 5034}, + {0x2F952, 0, 1, 5038}, {0x2F953, 0, 1 | DECOMP_INLINE, 0x7956}, - {0x2F954, 0, 1, 5035}, - {0x2F955, 0, 1, 5036}, + {0x2F954, 0, 1, 5039}, + {0x2F955, 0, 1, 5040}, {0x2F956, 0, 1 | DECOMP_INLINE, 0x798F}, {0x2F957, 0, 1 | DECOMP_INLINE, 0x79EB}, {0x2F958, 0, 1 | DECOMP_INLINE, 0x412F}, {0x2F959, 0, 1 | DECOMP_INLINE, 0x7A40}, {0x2F95A, 0, 1 | DECOMP_INLINE, 0x7A4A}, {0x2F95B, 0, 1 | DECOMP_INLINE, 0x7A4F}, - {0x2F95C, 0, 1, 5037}, - {0x2F95D, 0, 1, 5038}, - {0x2F95E, 0, 1, 5039}, + {0x2F95C, 0, 1, 5041}, + {0x2F95D, 0, 1, 5042}, + {0x2F95E, 0, 1, 5043}, {0x2F95F, 0, 1 | DECOMP_INLINE, 0x7AEE}, {0x2F960, 0, 1 | DECOMP_INLINE, 0x4202}, - {0x2F961, 0, 1, 5040}, + {0x2F961, 0, 1, 5044}, {0x2F962, 0, 1 | DECOMP_INLINE, 0x7BC6}, {0x2F963, 0, 1 | DECOMP_INLINE, 0x7BC9}, {0x2F964, 0, 1 | DECOMP_INLINE, 0x4227}, - {0x2F965, 0, 1, 5041}, + {0x2F965, 0, 1, 5045}, {0x2F966, 0, 1 | DECOMP_INLINE, 0x7CD2}, {0x2F967, 0, 1 | DECOMP_INLINE, 0x42A0}, {0x2F968, 0, 1 | DECOMP_INLINE, 0x7CE8}, {0x2F969, 0, 1 | DECOMP_INLINE, 0x7CE3}, {0x2F96A, 0, 1 | DECOMP_INLINE, 0x7D00}, - {0x2F96B, 0, 1, 5042}, + {0x2F96B, 0, 1, 5046}, {0x2F96C, 0, 1 | DECOMP_INLINE, 0x7D63}, {0x2F96D, 0, 1 | DECOMP_INLINE, 0x4301}, {0x2F96E, 0, 1 | DECOMP_INLINE, 0x7DC7}, {0x2F96F, 0, 1 | DECOMP_INLINE, 0x7E02}, {0x2F970, 0, 1 | DECOMP_INLINE, 0x7E45}, {0x2F971, 0, 1 | DECOMP_INLINE, 0x4334}, - {0x2F972, 0, 1, 5043}, - {0x2F973, 0, 1, 5044}, + {0x2F972, 0, 1, 5047}, + {0x2F973, 0, 1, 5048}, {0x2F974, 0, 1 | DECOMP_INLINE, 0x4359}, - {0x2F975, 0, 1, 5045}, + {0x2F975, 0, 1, 5049}, {0x2F976, 0, 1 | DECOMP_INLINE, 0x7F7A}, - {0x2F977, 0, 1, 5046}, + {0x2F977, 0, 1, 5050}, {0x2F978, 0, 1 | DECOMP_INLINE, 0x7F95}, {0x2F979, 0, 1 | DECOMP_INLINE, 0x7FFA}, {0x2F97A, 0, 1 | DECOMP_INLINE, 0x8005}, - {0x2F97B, 0, 1, 5047}, - {0x2F97C, 0, 1, 5048}, + {0x2F97B, 0, 1, 5051}, + {0x2F97C, 0, 1, 5052}, {0x2F97D, 0, 1 | DECOMP_INLINE, 0x8060}, - {0x2F97E, 0, 1, 5049}, + {0x2F97E, 0, 1, 5053}, {0x2F97F, 0, 1 | DECOMP_INLINE, 0x8070}, - {0x2F980, 0, 1, 5050}, + {0x2F980, 0, 1, 5054}, {0x2F981, 0, 1 | DECOMP_INLINE, 0x43D5}, {0x2F982, 0, 1 | DECOMP_INLINE, 0x80B2}, {0x2F983, 0, 1 | DECOMP_INLINE, 0x8103}, {0x2F984, 0, 1 | DECOMP_INLINE, 0x440B}, {0x2F985, 0, 1 | DECOMP_INLINE, 0x813E}, {0x2F986, 0, 1 | DECOMP_INLINE, 0x5AB5}, - {0x2F987, 0, 1, 5051}, - {0x2F988, 0, 1, 5052}, - {0x2F989, 0, 1, 5053}, - {0x2F98A, 0, 1, 5054}, + {0x2F987, 0, 1, 5055}, + {0x2F988, 0, 1, 5056}, + {0x2F989, 0, 1, 5057}, + {0x2F98A, 0, 1, 5058}, {0x2F98B, 0, 1 | DECOMP_INLINE, 0x8201}, {0x2F98C, 0, 1 | DECOMP_INLINE, 0x8204}, {0x2F98D, 0, 1 | DECOMP_INLINE, 0x8F9E}, @@ -6433,7 +6483,7 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F994, 0, 1 | DECOMP_INLINE, 0x82B3}, {0x2F995, 0, 1 | DECOMP_INLINE, 0x82BD}, {0x2F996, 0, 1 | DECOMP_INLINE, 0x82E6}, - {0x2F997, 0, 1, 5055}, + {0x2F997, 0, 1, 5059}, {0x2F998, 0, 1 | DECOMP_INLINE, 0x82E5}, {0x2F999, 0, 1 | DECOMP_INLINE, 0x831D}, {0x2F99A, 0, 1 | DECOMP_INLINE, 0x8363}, @@ -6446,20 +6496,20 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F9A1, 0, 1 | DECOMP_INLINE, 0x83CA}, {0x2F9A2, 0, 1 | DECOMP_INLINE, 0x83CC}, {0x2F9A3, 0, 1 | DECOMP_INLINE, 0x83DC}, - {0x2F9A4, 0, 1, 5056}, - {0x2F9A5, 0, 1, 5057}, - {0x2F9A6, 0, 1, 5058}, + {0x2F9A4, 0, 1, 5060}, + {0x2F9A5, 0, 1, 5061}, + {0x2F9A6, 0, 1, 5062}, {0x2F9A7, 0, 1 | DECOMP_INLINE, 0x452B}, {0x2F9A8, 0, 1 | DECOMP_INLINE, 0x84F1}, {0x2F9A9, 0, 1 | DECOMP_INLINE, 0x84F3}, {0x2F9AA, 0, 1 | DECOMP_INLINE, 0x8516}, - {0x2F9AB, 0, 1, 5059}, + {0x2F9AB, 0, 1, 5063}, {0x2F9AC, 0, 1 | DECOMP_INLINE, 0x8564}, - {0x2F9AD, 0, 1, 5060}, + {0x2F9AD, 0, 1, 5064}, {0x2F9AE, 0, 1 | DECOMP_INLINE, 0x455D}, {0x2F9AF, 0, 1 | DECOMP_INLINE, 0x4561}, - {0x2F9B0, 0, 1, 5061}, - {0x2F9B1, 0, 1, 5062}, + {0x2F9B0, 0, 1, 5065}, + {0x2F9B1, 0, 1, 5066}, {0x2F9B2, 0, 1 | DECOMP_INLINE, 0x456B}, {0x2F9B3, 0, 1 | DECOMP_INLINE, 0x8650}, {0x2F9B4, 0, 1 | DECOMP_INLINE, 0x865C}, @@ -6479,39 +6529,39 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F9C2, 0, 1 | DECOMP_INLINE, 0x45F9}, {0x2F9C3, 0, 1 | DECOMP_INLINE, 0x8860}, {0x2F9C4, 0, 1 | DECOMP_INLINE, 0x8863}, - {0x2F9C5, 0, 1, 5063}, + {0x2F9C5, 0, 1, 5067}, {0x2F9C6, 0, 1 | DECOMP_INLINE, 0x88D7}, {0x2F9C7, 0, 1 | DECOMP_INLINE, 0x88DE}, {0x2F9C8, 0, 1 | DECOMP_INLINE, 0x4635}, {0x2F9C9, 0, 1 | DECOMP_INLINE, 0x88FA}, {0x2F9CA, 0, 1 | DECOMP_INLINE, 0x34BB}, - {0x2F9CB, 0, 1, 5064}, - {0x2F9CC, 0, 1, 5065}, + {0x2F9CB, 0, 1, 5068}, + {0x2F9CC, 0, 1, 5069}, {0x2F9CD, 0, 1 | DECOMP_INLINE, 0x46BE}, {0x2F9CE, 0, 1 | DECOMP_INLINE, 0x46C7}, {0x2F9CF, 0, 1 | DECOMP_INLINE, 0x8AA0}, {0x2F9D0, 0, 1 | DECOMP_INLINE, 0x8AED}, {0x2F9D1, 0, 1 | DECOMP_INLINE, 0x8B8A}, {0x2F9D2, 0, 1 | DECOMP_INLINE, 0x8C55}, - {0x2F9D3, 0, 1, 5066}, + {0x2F9D3, 0, 1, 5070}, {0x2F9D4, 0, 1 | DECOMP_INLINE, 0x8CAB}, {0x2F9D5, 0, 1 | DECOMP_INLINE, 0x8CC1}, {0x2F9D6, 0, 1 | DECOMP_INLINE, 0x8D1B}, {0x2F9D7, 0, 1 | DECOMP_INLINE, 0x8D77}, - {0x2F9D8, 0, 1, 5067}, - {0x2F9D9, 0, 1, 5068}, + {0x2F9D8, 0, 1, 5071}, + {0x2F9D9, 0, 1, 5072}, {0x2F9DA, 0, 1 | DECOMP_INLINE, 0x8DCB}, {0x2F9DB, 0, 1 | DECOMP_INLINE, 0x8DBC}, {0x2F9DC, 0, 1 | DECOMP_INLINE, 0x8DF0}, - {0x2F9DD, 0, 1, 5069}, + {0x2F9DD, 0, 1, 5073}, {0x2F9DE, 0, 1 | DECOMP_INLINE, 0x8ED4}, {0x2F9DF, 0, 1 | DECOMP_INLINE, 0x8F38}, - {0x2F9E0, 0, 1, 5070}, - {0x2F9E1, 0, 1, 5071}, + {0x2F9E0, 0, 1, 5074}, + {0x2F9E1, 0, 1, 5075}, {0x2F9E2, 0, 1 | DECOMP_INLINE, 0x9094}, {0x2F9E3, 0, 1 | DECOMP_INLINE, 0x90F1}, {0x2F9E4, 0, 1 | DECOMP_INLINE, 0x9111}, - {0x2F9E5, 0, 1, 5072}, + {0x2F9E5, 0, 1, 5076}, {0x2F9E6, 0, 1 | DECOMP_INLINE, 0x911B}, {0x2F9E7, 0, 1 | DECOMP_INLINE, 0x9238}, {0x2F9E8, 0, 1 | DECOMP_INLINE, 0x92D7}, @@ -6519,27 +6569,27 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2F9EA, 0, 1 | DECOMP_INLINE, 0x927C}, {0x2F9EB, 0, 1 | DECOMP_INLINE, 0x93F9}, {0x2F9EC, 0, 1 | DECOMP_INLINE, 0x9415}, - {0x2F9ED, 0, 1, 5073}, + {0x2F9ED, 0, 1, 5077}, {0x2F9EE, 0, 1 | DECOMP_INLINE, 0x958B}, {0x2F9EF, 0, 1 | DECOMP_INLINE, 0x4995}, {0x2F9F0, 0, 1 | DECOMP_INLINE, 0x95B7}, - {0x2F9F1, 0, 1, 5074}, + {0x2F9F1, 0, 1, 5078}, {0x2F9F2, 0, 1 | DECOMP_INLINE, 0x49E6}, {0x2F9F3, 0, 1 | DECOMP_INLINE, 0x96C3}, {0x2F9F4, 0, 1 | DECOMP_INLINE, 0x5DB2}, {0x2F9F5, 0, 1 | DECOMP_INLINE, 0x9723}, - {0x2F9F6, 0, 1, 5075}, - {0x2F9F7, 0, 1, 5076}, + {0x2F9F6, 0, 1, 5079}, + {0x2F9F7, 0, 1, 5080}, {0x2F9F8, 0, 1 | DECOMP_INLINE, 0x4A6E}, {0x2F9F9, 0, 1 | DECOMP_INLINE, 0x4A76}, {0x2F9FA, 0, 1 | DECOMP_INLINE, 0x97E0}, - {0x2F9FB, 0, 1, 5077}, + {0x2F9FB, 0, 1, 5081}, {0x2F9FC, 0, 1 | DECOMP_INLINE, 0x4AB2}, - {0x2F9FD, 0, 1, 5078}, + {0x2F9FD, 0, 1, 5082}, {0x2F9FE, 0, 1 | DECOMP_INLINE, 0x980B}, {0x2F9FF, 0, 1 | DECOMP_INLINE, 0x980B}, {0x2FA00, 0, 1 | DECOMP_INLINE, 0x9829}, - {0x2FA01, 0, 1, 5079}, + {0x2FA01, 0, 1, 5083}, {0x2FA02, 0, 1 | DECOMP_INLINE, 0x98E2}, {0x2FA03, 0, 1 | DECOMP_INLINE, 0x4B33}, {0x2FA04, 0, 1 | DECOMP_INLINE, 0x9929}, @@ -6547,18 +6597,18 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2FA06, 0, 1 | DECOMP_INLINE, 0x99C2}, {0x2FA07, 0, 1 | DECOMP_INLINE, 0x99FE}, {0x2FA08, 0, 1 | DECOMP_INLINE, 0x4BCE}, - {0x2FA09, 0, 1, 5080}, + {0x2FA09, 0, 1, 5084}, {0x2FA0A, 0, 1 | DECOMP_INLINE, 0x9B12}, {0x2FA0B, 0, 1 | DECOMP_INLINE, 0x9C40}, {0x2FA0C, 0, 1 | DECOMP_INLINE, 0x9CFD}, {0x2FA0D, 0, 1 | DECOMP_INLINE, 0x4CCE}, {0x2FA0E, 0, 1 | DECOMP_INLINE, 0x4CED}, {0x2FA0F, 0, 1 | DECOMP_INLINE, 0x9D67}, - {0x2FA10, 0, 1, 5081}, + {0x2FA10, 0, 1, 5085}, {0x2FA11, 0, 1 | DECOMP_INLINE, 0x4CF8}, - {0x2FA12, 0, 1, 5082}, - {0x2FA13, 0, 1, 5083}, - {0x2FA14, 0, 1, 5084}, + {0x2FA12, 0, 1, 5086}, + {0x2FA13, 0, 1, 5087}, + {0x2FA14, 0, 1, 5088}, {0x2FA15, 0, 1 | DECOMP_INLINE, 0x9EBB}, {0x2FA16, 0, 1 | DECOMP_INLINE, 0x4D56}, {0x2FA17, 0, 1 | DECOMP_INLINE, 0x9EF9}, @@ -6567,12 +6617,12 @@ static const pg_unicode_decomposition UnicodeDecompMain[6532] = {0x2FA1A, 0, 1 | DECOMP_INLINE, 0x9F0F}, {0x2FA1B, 0, 1 | DECOMP_INLINE, 0x9F16}, {0x2FA1C, 0, 1 | DECOMP_INLINE, 0x9F3B}, - {0x2FA1D, 0, 1, 5085} + {0x2FA1D, 0, 1, 5089} }; /* codepoints array */ -static const uint32 UnicodeDecomp_codepoints[5086] = +static const uint32 UnicodeDecomp_codepoints[5090] = { /* 0 */ 0x0020, 0x0308, /* 2 */ 0x0020, 0x0304, @@ -7868,993 +7918,995 @@ static const uint32 UnicodeDecomp_codepoints[5086] = /* 2795 */ 0x0065, 0x0072, 0x0067, /* 2798 */ 0x0065, 0x0056, /* 2800 */ 0x004C, 0x0054, 0x0044, - /* 2803 */ 0x30A2, 0x30D1, 0x30FC, 0x30C8, - /* 2807 */ 0x30A2, 0x30EB, 0x30D5, 0x30A1, - /* 2811 */ 0x30A2, 0x30F3, 0x30DA, 0x30A2, - /* 2815 */ 0x30A2, 0x30FC, 0x30EB, - /* 2818 */ 0x30A4, 0x30CB, 0x30F3, 0x30B0, - /* 2822 */ 0x30A4, 0x30F3, 0x30C1, - /* 2825 */ 0x30A6, 0x30A9, 0x30F3, - /* 2828 */ 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, - /* 2833 */ 0x30A8, 0x30FC, 0x30AB, 0x30FC, - /* 2837 */ 0x30AA, 0x30F3, 0x30B9, - /* 2840 */ 0x30AA, 0x30FC, 0x30E0, - /* 2843 */ 0x30AB, 0x30A4, 0x30EA, - /* 2846 */ 0x30AB, 0x30E9, 0x30C3, 0x30C8, - /* 2850 */ 0x30AB, 0x30ED, 0x30EA, 0x30FC, - /* 2854 */ 0x30AC, 0x30ED, 0x30F3, - /* 2857 */ 0x30AC, 0x30F3, 0x30DE, - /* 2860 */ 0x30AE, 0x30AC, - /* 2862 */ 0x30AE, 0x30CB, 0x30FC, - /* 2865 */ 0x30AD, 0x30E5, 0x30EA, 0x30FC, - /* 2869 */ 0x30AE, 0x30EB, 0x30C0, 0x30FC, - /* 2873 */ 0x30AD, 0x30ED, - /* 2875 */ 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, - /* 2880 */ 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, - /* 2886 */ 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, - /* 2891 */ 0x30B0, 0x30E9, 0x30E0, - /* 2894 */ 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, - /* 2899 */ 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, - /* 2904 */ 0x30AF, 0x30ED, 0x30FC, 0x30CD, - /* 2908 */ 0x30B1, 0x30FC, 0x30B9, - /* 2911 */ 0x30B3, 0x30EB, 0x30CA, - /* 2914 */ 0x30B3, 0x30FC, 0x30DD, - /* 2917 */ 0x30B5, 0x30A4, 0x30AF, 0x30EB, - /* 2921 */ 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, - /* 2926 */ 0x30B7, 0x30EA, 0x30F3, 0x30B0, - /* 2930 */ 0x30BB, 0x30F3, 0x30C1, - /* 2933 */ 0x30BB, 0x30F3, 0x30C8, - /* 2936 */ 0x30C0, 0x30FC, 0x30B9, - /* 2939 */ 0x30C7, 0x30B7, - /* 2941 */ 0x30C9, 0x30EB, - /* 2943 */ 0x30C8, 0x30F3, - /* 2945 */ 0x30CA, 0x30CE, - /* 2947 */ 0x30CE, 0x30C3, 0x30C8, - /* 2950 */ 0x30CF, 0x30A4, 0x30C4, - /* 2953 */ 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, - /* 2958 */ 0x30D1, 0x30FC, 0x30C4, - /* 2961 */ 0x30D0, 0x30FC, 0x30EC, 0x30EB, - /* 2965 */ 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, - /* 2970 */ 0x30D4, 0x30AF, 0x30EB, - /* 2973 */ 0x30D4, 0x30B3, - /* 2975 */ 0x30D3, 0x30EB, - /* 2977 */ 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, - /* 2982 */ 0x30D5, 0x30A3, 0x30FC, 0x30C8, - /* 2986 */ 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, - /* 2991 */ 0x30D5, 0x30E9, 0x30F3, - /* 2994 */ 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, - /* 2999 */ 0x30DA, 0x30BD, - /* 3001 */ 0x30DA, 0x30CB, 0x30D2, - /* 3004 */ 0x30D8, 0x30EB, 0x30C4, - /* 3007 */ 0x30DA, 0x30F3, 0x30B9, - /* 3010 */ 0x30DA, 0x30FC, 0x30B8, - /* 3013 */ 0x30D9, 0x30FC, 0x30BF, - /* 3016 */ 0x30DD, 0x30A4, 0x30F3, 0x30C8, - /* 3020 */ 0x30DC, 0x30EB, 0x30C8, - /* 3023 */ 0x30DB, 0x30F3, - /* 3025 */ 0x30DD, 0x30F3, 0x30C9, - /* 3028 */ 0x30DB, 0x30FC, 0x30EB, - /* 3031 */ 0x30DB, 0x30FC, 0x30F3, - /* 3034 */ 0x30DE, 0x30A4, 0x30AF, 0x30ED, - /* 3038 */ 0x30DE, 0x30A4, 0x30EB, - /* 3041 */ 0x30DE, 0x30C3, 0x30CF, - /* 3044 */ 0x30DE, 0x30EB, 0x30AF, - /* 3047 */ 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, - /* 3052 */ 0x30DF, 0x30AF, 0x30ED, 0x30F3, - /* 3056 */ 0x30DF, 0x30EA, - /* 3058 */ 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, - /* 3063 */ 0x30E1, 0x30AC, - /* 3065 */ 0x30E1, 0x30AC, 0x30C8, 0x30F3, - /* 3069 */ 0x30E1, 0x30FC, 0x30C8, 0x30EB, - /* 3073 */ 0x30E4, 0x30FC, 0x30C9, - /* 3076 */ 0x30E4, 0x30FC, 0x30EB, - /* 3079 */ 0x30E6, 0x30A2, 0x30F3, - /* 3082 */ 0x30EA, 0x30C3, 0x30C8, 0x30EB, - /* 3086 */ 0x30EA, 0x30E9, - /* 3088 */ 0x30EB, 0x30D4, 0x30FC, - /* 3091 */ 0x30EB, 0x30FC, 0x30D6, 0x30EB, - /* 3095 */ 0x30EC, 0x30E0, - /* 3097 */ 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, - /* 3102 */ 0x30EF, 0x30C3, 0x30C8, - /* 3105 */ 0x0030, 0x70B9, - /* 3107 */ 0x0031, 0x70B9, - /* 3109 */ 0x0032, 0x70B9, - /* 3111 */ 0x0033, 0x70B9, - /* 3113 */ 0x0034, 0x70B9, - /* 3115 */ 0x0035, 0x70B9, - /* 3117 */ 0x0036, 0x70B9, - /* 3119 */ 0x0037, 0x70B9, - /* 3121 */ 0x0038, 0x70B9, - /* 3123 */ 0x0039, 0x70B9, - /* 3125 */ 0x0031, 0x0030, 0x70B9, - /* 3128 */ 0x0031, 0x0031, 0x70B9, - /* 3131 */ 0x0031, 0x0032, 0x70B9, - /* 3134 */ 0x0031, 0x0033, 0x70B9, - /* 3137 */ 0x0031, 0x0034, 0x70B9, - /* 3140 */ 0x0031, 0x0035, 0x70B9, - /* 3143 */ 0x0031, 0x0036, 0x70B9, - /* 3146 */ 0x0031, 0x0037, 0x70B9, - /* 3149 */ 0x0031, 0x0038, 0x70B9, - /* 3152 */ 0x0031, 0x0039, 0x70B9, - /* 3155 */ 0x0032, 0x0030, 0x70B9, - /* 3158 */ 0x0032, 0x0031, 0x70B9, - /* 3161 */ 0x0032, 0x0032, 0x70B9, - /* 3164 */ 0x0032, 0x0033, 0x70B9, - /* 3167 */ 0x0032, 0x0034, 0x70B9, - /* 3170 */ 0x0068, 0x0050, 0x0061, - /* 3173 */ 0x0064, 0x0061, - /* 3175 */ 0x0041, 0x0055, - /* 3177 */ 0x0062, 0x0061, 0x0072, - /* 3180 */ 0x006F, 0x0056, - /* 3182 */ 0x0070, 0x0063, - /* 3184 */ 0x0064, 0x006D, - /* 3186 */ 0x0064, 0x006D, 0x00B2, - /* 3189 */ 0x0064, 0x006D, 0x00B3, - /* 3192 */ 0x0049, 0x0055, - /* 3194 */ 0x5E73, 0x6210, - /* 3196 */ 0x662D, 0x548C, - /* 3198 */ 0x5927, 0x6B63, - /* 3200 */ 0x660E, 0x6CBB, - /* 3202 */ 0x682A, 0x5F0F, 0x4F1A, 0x793E, - /* 3206 */ 0x0070, 0x0041, - /* 3208 */ 0x006E, 0x0041, - /* 3210 */ 0x03BC, 0x0041, - /* 3212 */ 0x006D, 0x0041, - /* 3214 */ 0x006B, 0x0041, - /* 3216 */ 0x004B, 0x0042, - /* 3218 */ 0x004D, 0x0042, - /* 3220 */ 0x0047, 0x0042, - /* 3222 */ 0x0063, 0x0061, 0x006C, - /* 3225 */ 0x006B, 0x0063, 0x0061, 0x006C, - /* 3229 */ 0x0070, 0x0046, - /* 3231 */ 0x006E, 0x0046, - /* 3233 */ 0x03BC, 0x0046, - /* 3235 */ 0x03BC, 0x0067, - /* 3237 */ 0x006D, 0x0067, - /* 3239 */ 0x006B, 0x0067, - /* 3241 */ 0x0048, 0x007A, - /* 3243 */ 0x006B, 0x0048, 0x007A, - /* 3246 */ 0x004D, 0x0048, 0x007A, - /* 3249 */ 0x0047, 0x0048, 0x007A, - /* 3252 */ 0x0054, 0x0048, 0x007A, - /* 3255 */ 0x03BC, 0x2113, - /* 3257 */ 0x006D, 0x2113, - /* 3259 */ 0x0064, 0x2113, - /* 3261 */ 0x006B, 0x2113, - /* 3263 */ 0x0066, 0x006D, - /* 3265 */ 0x006E, 0x006D, - /* 3267 */ 0x03BC, 0x006D, - /* 3269 */ 0x006D, 0x006D, - /* 3271 */ 0x0063, 0x006D, - /* 3273 */ 0x006B, 0x006D, - /* 3275 */ 0x006D, 0x006D, 0x00B2, - /* 3278 */ 0x0063, 0x006D, 0x00B2, - /* 3281 */ 0x006D, 0x00B2, - /* 3283 */ 0x006B, 0x006D, 0x00B2, - /* 3286 */ 0x006D, 0x006D, 0x00B3, - /* 3289 */ 0x0063, 0x006D, 0x00B3, - /* 3292 */ 0x006D, 0x00B3, - /* 3294 */ 0x006B, 0x006D, 0x00B3, - /* 3297 */ 0x006D, 0x2215, 0x0073, - /* 3300 */ 0x006D, 0x2215, 0x0073, 0x00B2, - /* 3304 */ 0x0050, 0x0061, - /* 3306 */ 0x006B, 0x0050, 0x0061, - /* 3309 */ 0x004D, 0x0050, 0x0061, - /* 3312 */ 0x0047, 0x0050, 0x0061, - /* 3315 */ 0x0072, 0x0061, 0x0064, - /* 3318 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, - /* 3323 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, - /* 3329 */ 0x0070, 0x0073, - /* 3331 */ 0x006E, 0x0073, - /* 3333 */ 0x03BC, 0x0073, - /* 3335 */ 0x006D, 0x0073, - /* 3337 */ 0x0070, 0x0056, - /* 3339 */ 0x006E, 0x0056, - /* 3341 */ 0x03BC, 0x0056, - /* 3343 */ 0x006D, 0x0056, - /* 3345 */ 0x006B, 0x0056, - /* 3347 */ 0x004D, 0x0056, - /* 3349 */ 0x0070, 0x0057, - /* 3351 */ 0x006E, 0x0057, - /* 3353 */ 0x03BC, 0x0057, - /* 3355 */ 0x006D, 0x0057, - /* 3357 */ 0x006B, 0x0057, - /* 3359 */ 0x004D, 0x0057, - /* 3361 */ 0x006B, 0x03A9, - /* 3363 */ 0x004D, 0x03A9, - /* 3365 */ 0x0061, 0x002E, 0x006D, 0x002E, - /* 3369 */ 0x0042, 0x0071, - /* 3371 */ 0x0063, 0x0063, - /* 3373 */ 0x0063, 0x0064, - /* 3375 */ 0x0043, 0x2215, 0x006B, 0x0067, - /* 3379 */ 0x0043, 0x006F, 0x002E, - /* 3382 */ 0x0064, 0x0042, - /* 3384 */ 0x0047, 0x0079, - /* 3386 */ 0x0068, 0x0061, - /* 3388 */ 0x0048, 0x0050, - /* 3390 */ 0x0069, 0x006E, - /* 3392 */ 0x004B, 0x004B, - /* 3394 */ 0x004B, 0x004D, - /* 3396 */ 0x006B, 0x0074, - /* 3398 */ 0x006C, 0x006D, - /* 3400 */ 0x006C, 0x006E, - /* 3402 */ 0x006C, 0x006F, 0x0067, - /* 3405 */ 0x006C, 0x0078, - /* 3407 */ 0x006D, 0x0062, - /* 3409 */ 0x006D, 0x0069, 0x006C, - /* 3412 */ 0x006D, 0x006F, 0x006C, - /* 3415 */ 0x0050, 0x0048, - /* 3417 */ 0x0070, 0x002E, 0x006D, 0x002E, - /* 3421 */ 0x0050, 0x0050, 0x004D, - /* 3424 */ 0x0050, 0x0052, - /* 3426 */ 0x0073, 0x0072, - /* 3428 */ 0x0053, 0x0076, - /* 3430 */ 0x0057, 0x0062, - /* 3432 */ 0x0056, 0x2215, 0x006D, - /* 3435 */ 0x0041, 0x2215, 0x006D, - /* 3438 */ 0x0031, 0x65E5, - /* 3440 */ 0x0032, 0x65E5, - /* 3442 */ 0x0033, 0x65E5, - /* 3444 */ 0x0034, 0x65E5, - /* 3446 */ 0x0035, 0x65E5, - /* 3448 */ 0x0036, 0x65E5, - /* 3450 */ 0x0037, 0x65E5, - /* 3452 */ 0x0038, 0x65E5, - /* 3454 */ 0x0039, 0x65E5, - /* 3456 */ 0x0031, 0x0030, 0x65E5, - /* 3459 */ 0x0031, 0x0031, 0x65E5, - /* 3462 */ 0x0031, 0x0032, 0x65E5, - /* 3465 */ 0x0031, 0x0033, 0x65E5, - /* 3468 */ 0x0031, 0x0034, 0x65E5, - /* 3471 */ 0x0031, 0x0035, 0x65E5, - /* 3474 */ 0x0031, 0x0036, 0x65E5, - /* 3477 */ 0x0031, 0x0037, 0x65E5, - /* 3480 */ 0x0031, 0x0038, 0x65E5, - /* 3483 */ 0x0031, 0x0039, 0x65E5, - /* 3486 */ 0x0032, 0x0030, 0x65E5, - /* 3489 */ 0x0032, 0x0031, 0x65E5, - /* 3492 */ 0x0032, 0x0032, 0x65E5, - /* 3495 */ 0x0032, 0x0033, 0x65E5, - /* 3498 */ 0x0032, 0x0034, 0x65E5, - /* 3501 */ 0x0032, 0x0035, 0x65E5, - /* 3504 */ 0x0032, 0x0036, 0x65E5, - /* 3507 */ 0x0032, 0x0037, 0x65E5, - /* 3510 */ 0x0032, 0x0038, 0x65E5, - /* 3513 */ 0x0032, 0x0039, 0x65E5, - /* 3516 */ 0x0033, 0x0030, 0x65E5, - /* 3519 */ 0x0033, 0x0031, 0x65E5, - /* 3522 */ 0x0067, 0x0061, 0x006C, - /* 3525 */ 0x242EE, - /* 3526 */ 0x2284A, - /* 3527 */ 0x22844, - /* 3528 */ 0x233D5, - /* 3529 */ 0x25249, - /* 3530 */ 0x25CD0, - /* 3531 */ 0x27ED3, - /* 3532 */ 0x0066, 0x0066, - /* 3534 */ 0x0066, 0x0069, - /* 3536 */ 0x0066, 0x006C, - /* 3538 */ 0x0066, 0x0066, 0x0069, - /* 3541 */ 0x0066, 0x0066, 0x006C, - /* 3544 */ 0x017F, 0x0074, - /* 3546 */ 0x0073, 0x0074, - /* 3548 */ 0x0574, 0x0576, - /* 3550 */ 0x0574, 0x0565, - /* 3552 */ 0x0574, 0x056B, - /* 3554 */ 0x057E, 0x0576, - /* 3556 */ 0x0574, 0x056D, - /* 3558 */ 0x05D9, 0x05B4, - /* 3560 */ 0x05F2, 0x05B7, - /* 3562 */ 0x05E9, 0x05C1, - /* 3564 */ 0x05E9, 0x05C2, - /* 3566 */ 0xFB49, 0x05C1, - /* 3568 */ 0xFB49, 0x05C2, - /* 3570 */ 0x05D0, 0x05B7, - /* 3572 */ 0x05D0, 0x05B8, - /* 3574 */ 0x05D0, 0x05BC, - /* 3576 */ 0x05D1, 0x05BC, - /* 3578 */ 0x05D2, 0x05BC, - /* 3580 */ 0x05D3, 0x05BC, - /* 3582 */ 0x05D4, 0x05BC, - /* 3584 */ 0x05D5, 0x05BC, - /* 3586 */ 0x05D6, 0x05BC, - /* 3588 */ 0x05D8, 0x05BC, - /* 3590 */ 0x05D9, 0x05BC, - /* 3592 */ 0x05DA, 0x05BC, - /* 3594 */ 0x05DB, 0x05BC, - /* 3596 */ 0x05DC, 0x05BC, - /* 3598 */ 0x05DE, 0x05BC, - /* 3600 */ 0x05E0, 0x05BC, - /* 3602 */ 0x05E1, 0x05BC, - /* 3604 */ 0x05E3, 0x05BC, - /* 3606 */ 0x05E4, 0x05BC, - /* 3608 */ 0x05E6, 0x05BC, - /* 3610 */ 0x05E7, 0x05BC, - /* 3612 */ 0x05E8, 0x05BC, - /* 3614 */ 0x05E9, 0x05BC, - /* 3616 */ 0x05EA, 0x05BC, - /* 3618 */ 0x05D5, 0x05B9, - /* 3620 */ 0x05D1, 0x05BF, - /* 3622 */ 0x05DB, 0x05BF, - /* 3624 */ 0x05E4, 0x05BF, - /* 3626 */ 0x05D0, 0x05DC, - /* 3628 */ 0x0626, 0x0627, + /* 2803 */ 0x4EE4, 0x548C, + /* 2805 */ 0x30A2, 0x30D1, 0x30FC, 0x30C8, + /* 2809 */ 0x30A2, 0x30EB, 0x30D5, 0x30A1, + /* 2813 */ 0x30A2, 0x30F3, 0x30DA, 0x30A2, + /* 2817 */ 0x30A2, 0x30FC, 0x30EB, + /* 2820 */ 0x30A4, 0x30CB, 0x30F3, 0x30B0, + /* 2824 */ 0x30A4, 0x30F3, 0x30C1, + /* 2827 */ 0x30A6, 0x30A9, 0x30F3, + /* 2830 */ 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, + /* 2835 */ 0x30A8, 0x30FC, 0x30AB, 0x30FC, + /* 2839 */ 0x30AA, 0x30F3, 0x30B9, + /* 2842 */ 0x30AA, 0x30FC, 0x30E0, + /* 2845 */ 0x30AB, 0x30A4, 0x30EA, + /* 2848 */ 0x30AB, 0x30E9, 0x30C3, 0x30C8, + /* 2852 */ 0x30AB, 0x30ED, 0x30EA, 0x30FC, + /* 2856 */ 0x30AC, 0x30ED, 0x30F3, + /* 2859 */ 0x30AC, 0x30F3, 0x30DE, + /* 2862 */ 0x30AE, 0x30AC, + /* 2864 */ 0x30AE, 0x30CB, 0x30FC, + /* 2867 */ 0x30AD, 0x30E5, 0x30EA, 0x30FC, + /* 2871 */ 0x30AE, 0x30EB, 0x30C0, 0x30FC, + /* 2875 */ 0x30AD, 0x30ED, + /* 2877 */ 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, + /* 2882 */ 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, + /* 2888 */ 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, + /* 2893 */ 0x30B0, 0x30E9, 0x30E0, + /* 2896 */ 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, + /* 2901 */ 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, + /* 2906 */ 0x30AF, 0x30ED, 0x30FC, 0x30CD, + /* 2910 */ 0x30B1, 0x30FC, 0x30B9, + /* 2913 */ 0x30B3, 0x30EB, 0x30CA, + /* 2916 */ 0x30B3, 0x30FC, 0x30DD, + /* 2919 */ 0x30B5, 0x30A4, 0x30AF, 0x30EB, + /* 2923 */ 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, + /* 2928 */ 0x30B7, 0x30EA, 0x30F3, 0x30B0, + /* 2932 */ 0x30BB, 0x30F3, 0x30C1, + /* 2935 */ 0x30BB, 0x30F3, 0x30C8, + /* 2938 */ 0x30C0, 0x30FC, 0x30B9, + /* 2941 */ 0x30C7, 0x30B7, + /* 2943 */ 0x30C9, 0x30EB, + /* 2945 */ 0x30C8, 0x30F3, + /* 2947 */ 0x30CA, 0x30CE, + /* 2949 */ 0x30CE, 0x30C3, 0x30C8, + /* 2952 */ 0x30CF, 0x30A4, 0x30C4, + /* 2955 */ 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, + /* 2960 */ 0x30D1, 0x30FC, 0x30C4, + /* 2963 */ 0x30D0, 0x30FC, 0x30EC, 0x30EB, + /* 2967 */ 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, + /* 2972 */ 0x30D4, 0x30AF, 0x30EB, + /* 2975 */ 0x30D4, 0x30B3, + /* 2977 */ 0x30D3, 0x30EB, + /* 2979 */ 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, + /* 2984 */ 0x30D5, 0x30A3, 0x30FC, 0x30C8, + /* 2988 */ 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, + /* 2993 */ 0x30D5, 0x30E9, 0x30F3, + /* 2996 */ 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, + /* 3001 */ 0x30DA, 0x30BD, + /* 3003 */ 0x30DA, 0x30CB, 0x30D2, + /* 3006 */ 0x30D8, 0x30EB, 0x30C4, + /* 3009 */ 0x30DA, 0x30F3, 0x30B9, + /* 3012 */ 0x30DA, 0x30FC, 0x30B8, + /* 3015 */ 0x30D9, 0x30FC, 0x30BF, + /* 3018 */ 0x30DD, 0x30A4, 0x30F3, 0x30C8, + /* 3022 */ 0x30DC, 0x30EB, 0x30C8, + /* 3025 */ 0x30DB, 0x30F3, + /* 3027 */ 0x30DD, 0x30F3, 0x30C9, + /* 3030 */ 0x30DB, 0x30FC, 0x30EB, + /* 3033 */ 0x30DB, 0x30FC, 0x30F3, + /* 3036 */ 0x30DE, 0x30A4, 0x30AF, 0x30ED, + /* 3040 */ 0x30DE, 0x30A4, 0x30EB, + /* 3043 */ 0x30DE, 0x30C3, 0x30CF, + /* 3046 */ 0x30DE, 0x30EB, 0x30AF, + /* 3049 */ 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, + /* 3054 */ 0x30DF, 0x30AF, 0x30ED, 0x30F3, + /* 3058 */ 0x30DF, 0x30EA, + /* 3060 */ 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, + /* 3065 */ 0x30E1, 0x30AC, + /* 3067 */ 0x30E1, 0x30AC, 0x30C8, 0x30F3, + /* 3071 */ 0x30E1, 0x30FC, 0x30C8, 0x30EB, + /* 3075 */ 0x30E4, 0x30FC, 0x30C9, + /* 3078 */ 0x30E4, 0x30FC, 0x30EB, + /* 3081 */ 0x30E6, 0x30A2, 0x30F3, + /* 3084 */ 0x30EA, 0x30C3, 0x30C8, 0x30EB, + /* 3088 */ 0x30EA, 0x30E9, + /* 3090 */ 0x30EB, 0x30D4, 0x30FC, + /* 3093 */ 0x30EB, 0x30FC, 0x30D6, 0x30EB, + /* 3097 */ 0x30EC, 0x30E0, + /* 3099 */ 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, + /* 3104 */ 0x30EF, 0x30C3, 0x30C8, + /* 3107 */ 0x0030, 0x70B9, + /* 3109 */ 0x0031, 0x70B9, + /* 3111 */ 0x0032, 0x70B9, + /* 3113 */ 0x0033, 0x70B9, + /* 3115 */ 0x0034, 0x70B9, + /* 3117 */ 0x0035, 0x70B9, + /* 3119 */ 0x0036, 0x70B9, + /* 3121 */ 0x0037, 0x70B9, + /* 3123 */ 0x0038, 0x70B9, + /* 3125 */ 0x0039, 0x70B9, + /* 3127 */ 0x0031, 0x0030, 0x70B9, + /* 3130 */ 0x0031, 0x0031, 0x70B9, + /* 3133 */ 0x0031, 0x0032, 0x70B9, + /* 3136 */ 0x0031, 0x0033, 0x70B9, + /* 3139 */ 0x0031, 0x0034, 0x70B9, + /* 3142 */ 0x0031, 0x0035, 0x70B9, + /* 3145 */ 0x0031, 0x0036, 0x70B9, + /* 3148 */ 0x0031, 0x0037, 0x70B9, + /* 3151 */ 0x0031, 0x0038, 0x70B9, + /* 3154 */ 0x0031, 0x0039, 0x70B9, + /* 3157 */ 0x0032, 0x0030, 0x70B9, + /* 3160 */ 0x0032, 0x0031, 0x70B9, + /* 3163 */ 0x0032, 0x0032, 0x70B9, + /* 3166 */ 0x0032, 0x0033, 0x70B9, + /* 3169 */ 0x0032, 0x0034, 0x70B9, + /* 3172 */ 0x0068, 0x0050, 0x0061, + /* 3175 */ 0x0064, 0x0061, + /* 3177 */ 0x0041, 0x0055, + /* 3179 */ 0x0062, 0x0061, 0x0072, + /* 3182 */ 0x006F, 0x0056, + /* 3184 */ 0x0070, 0x0063, + /* 3186 */ 0x0064, 0x006D, + /* 3188 */ 0x0064, 0x006D, 0x00B2, + /* 3191 */ 0x0064, 0x006D, 0x00B3, + /* 3194 */ 0x0049, 0x0055, + /* 3196 */ 0x5E73, 0x6210, + /* 3198 */ 0x662D, 0x548C, + /* 3200 */ 0x5927, 0x6B63, + /* 3202 */ 0x660E, 0x6CBB, + /* 3204 */ 0x682A, 0x5F0F, 0x4F1A, 0x793E, + /* 3208 */ 0x0070, 0x0041, + /* 3210 */ 0x006E, 0x0041, + /* 3212 */ 0x03BC, 0x0041, + /* 3214 */ 0x006D, 0x0041, + /* 3216 */ 0x006B, 0x0041, + /* 3218 */ 0x004B, 0x0042, + /* 3220 */ 0x004D, 0x0042, + /* 3222 */ 0x0047, 0x0042, + /* 3224 */ 0x0063, 0x0061, 0x006C, + /* 3227 */ 0x006B, 0x0063, 0x0061, 0x006C, + /* 3231 */ 0x0070, 0x0046, + /* 3233 */ 0x006E, 0x0046, + /* 3235 */ 0x03BC, 0x0046, + /* 3237 */ 0x03BC, 0x0067, + /* 3239 */ 0x006D, 0x0067, + /* 3241 */ 0x006B, 0x0067, + /* 3243 */ 0x0048, 0x007A, + /* 3245 */ 0x006B, 0x0048, 0x007A, + /* 3248 */ 0x004D, 0x0048, 0x007A, + /* 3251 */ 0x0047, 0x0048, 0x007A, + /* 3254 */ 0x0054, 0x0048, 0x007A, + /* 3257 */ 0x03BC, 0x2113, + /* 3259 */ 0x006D, 0x2113, + /* 3261 */ 0x0064, 0x2113, + /* 3263 */ 0x006B, 0x2113, + /* 3265 */ 0x0066, 0x006D, + /* 3267 */ 0x006E, 0x006D, + /* 3269 */ 0x03BC, 0x006D, + /* 3271 */ 0x006D, 0x006D, + /* 3273 */ 0x0063, 0x006D, + /* 3275 */ 0x006B, 0x006D, + /* 3277 */ 0x006D, 0x006D, 0x00B2, + /* 3280 */ 0x0063, 0x006D, 0x00B2, + /* 3283 */ 0x006D, 0x00B2, + /* 3285 */ 0x006B, 0x006D, 0x00B2, + /* 3288 */ 0x006D, 0x006D, 0x00B3, + /* 3291 */ 0x0063, 0x006D, 0x00B3, + /* 3294 */ 0x006D, 0x00B3, + /* 3296 */ 0x006B, 0x006D, 0x00B3, + /* 3299 */ 0x006D, 0x2215, 0x0073, + /* 3302 */ 0x006D, 0x2215, 0x0073, 0x00B2, + /* 3306 */ 0x0050, 0x0061, + /* 3308 */ 0x006B, 0x0050, 0x0061, + /* 3311 */ 0x004D, 0x0050, 0x0061, + /* 3314 */ 0x0047, 0x0050, 0x0061, + /* 3317 */ 0x0072, 0x0061, 0x0064, + /* 3320 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, + /* 3325 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, + /* 3331 */ 0x0070, 0x0073, + /* 3333 */ 0x006E, 0x0073, + /* 3335 */ 0x03BC, 0x0073, + /* 3337 */ 0x006D, 0x0073, + /* 3339 */ 0x0070, 0x0056, + /* 3341 */ 0x006E, 0x0056, + /* 3343 */ 0x03BC, 0x0056, + /* 3345 */ 0x006D, 0x0056, + /* 3347 */ 0x006B, 0x0056, + /* 3349 */ 0x004D, 0x0056, + /* 3351 */ 0x0070, 0x0057, + /* 3353 */ 0x006E, 0x0057, + /* 3355 */ 0x03BC, 0x0057, + /* 3357 */ 0x006D, 0x0057, + /* 3359 */ 0x006B, 0x0057, + /* 3361 */ 0x004D, 0x0057, + /* 3363 */ 0x006B, 0x03A9, + /* 3365 */ 0x004D, 0x03A9, + /* 3367 */ 0x0061, 0x002E, 0x006D, 0x002E, + /* 3371 */ 0x0042, 0x0071, + /* 3373 */ 0x0063, 0x0063, + /* 3375 */ 0x0063, 0x0064, + /* 3377 */ 0x0043, 0x2215, 0x006B, 0x0067, + /* 3381 */ 0x0043, 0x006F, 0x002E, + /* 3384 */ 0x0064, 0x0042, + /* 3386 */ 0x0047, 0x0079, + /* 3388 */ 0x0068, 0x0061, + /* 3390 */ 0x0048, 0x0050, + /* 3392 */ 0x0069, 0x006E, + /* 3394 */ 0x004B, 0x004B, + /* 3396 */ 0x004B, 0x004D, + /* 3398 */ 0x006B, 0x0074, + /* 3400 */ 0x006C, 0x006D, + /* 3402 */ 0x006C, 0x006E, + /* 3404 */ 0x006C, 0x006F, 0x0067, + /* 3407 */ 0x006C, 0x0078, + /* 3409 */ 0x006D, 0x0062, + /* 3411 */ 0x006D, 0x0069, 0x006C, + /* 3414 */ 0x006D, 0x006F, 0x006C, + /* 3417 */ 0x0050, 0x0048, + /* 3419 */ 0x0070, 0x002E, 0x006D, 0x002E, + /* 3423 */ 0x0050, 0x0050, 0x004D, + /* 3426 */ 0x0050, 0x0052, + /* 3428 */ 0x0073, 0x0072, + /* 3430 */ 0x0053, 0x0076, + /* 3432 */ 0x0057, 0x0062, + /* 3434 */ 0x0056, 0x2215, 0x006D, + /* 3437 */ 0x0041, 0x2215, 0x006D, + /* 3440 */ 0x0031, 0x65E5, + /* 3442 */ 0x0032, 0x65E5, + /* 3444 */ 0x0033, 0x65E5, + /* 3446 */ 0x0034, 0x65E5, + /* 3448 */ 0x0035, 0x65E5, + /* 3450 */ 0x0036, 0x65E5, + /* 3452 */ 0x0037, 0x65E5, + /* 3454 */ 0x0038, 0x65E5, + /* 3456 */ 0x0039, 0x65E5, + /* 3458 */ 0x0031, 0x0030, 0x65E5, + /* 3461 */ 0x0031, 0x0031, 0x65E5, + /* 3464 */ 0x0031, 0x0032, 0x65E5, + /* 3467 */ 0x0031, 0x0033, 0x65E5, + /* 3470 */ 0x0031, 0x0034, 0x65E5, + /* 3473 */ 0x0031, 0x0035, 0x65E5, + /* 3476 */ 0x0031, 0x0036, 0x65E5, + /* 3479 */ 0x0031, 0x0037, 0x65E5, + /* 3482 */ 0x0031, 0x0038, 0x65E5, + /* 3485 */ 0x0031, 0x0039, 0x65E5, + /* 3488 */ 0x0032, 0x0030, 0x65E5, + /* 3491 */ 0x0032, 0x0031, 0x65E5, + /* 3494 */ 0x0032, 0x0032, 0x65E5, + /* 3497 */ 0x0032, 0x0033, 0x65E5, + /* 3500 */ 0x0032, 0x0034, 0x65E5, + /* 3503 */ 0x0032, 0x0035, 0x65E5, + /* 3506 */ 0x0032, 0x0036, 0x65E5, + /* 3509 */ 0x0032, 0x0037, 0x65E5, + /* 3512 */ 0x0032, 0x0038, 0x65E5, + /* 3515 */ 0x0032, 0x0039, 0x65E5, + /* 3518 */ 0x0033, 0x0030, 0x65E5, + /* 3521 */ 0x0033, 0x0031, 0x65E5, + /* 3524 */ 0x0067, 0x0061, 0x006C, + /* 3527 */ 0x242EE, + /* 3528 */ 0x2284A, + /* 3529 */ 0x22844, + /* 3530 */ 0x233D5, + /* 3531 */ 0x25249, + /* 3532 */ 0x25CD0, + /* 3533 */ 0x27ED3, + /* 3534 */ 0x0066, 0x0066, + /* 3536 */ 0x0066, 0x0069, + /* 3538 */ 0x0066, 0x006C, + /* 3540 */ 0x0066, 0x0066, 0x0069, + /* 3543 */ 0x0066, 0x0066, 0x006C, + /* 3546 */ 0x017F, 0x0074, + /* 3548 */ 0x0073, 0x0074, + /* 3550 */ 0x0574, 0x0576, + /* 3552 */ 0x0574, 0x0565, + /* 3554 */ 0x0574, 0x056B, + /* 3556 */ 0x057E, 0x0576, + /* 3558 */ 0x0574, 0x056D, + /* 3560 */ 0x05D9, 0x05B4, + /* 3562 */ 0x05F2, 0x05B7, + /* 3564 */ 0x05E9, 0x05C1, + /* 3566 */ 0x05E9, 0x05C2, + /* 3568 */ 0xFB49, 0x05C1, + /* 3570 */ 0xFB49, 0x05C2, + /* 3572 */ 0x05D0, 0x05B7, + /* 3574 */ 0x05D0, 0x05B8, + /* 3576 */ 0x05D0, 0x05BC, + /* 3578 */ 0x05D1, 0x05BC, + /* 3580 */ 0x05D2, 0x05BC, + /* 3582 */ 0x05D3, 0x05BC, + /* 3584 */ 0x05D4, 0x05BC, + /* 3586 */ 0x05D5, 0x05BC, + /* 3588 */ 0x05D6, 0x05BC, + /* 3590 */ 0x05D8, 0x05BC, + /* 3592 */ 0x05D9, 0x05BC, + /* 3594 */ 0x05DA, 0x05BC, + /* 3596 */ 0x05DB, 0x05BC, + /* 3598 */ 0x05DC, 0x05BC, + /* 3600 */ 0x05DE, 0x05BC, + /* 3602 */ 0x05E0, 0x05BC, + /* 3604 */ 0x05E1, 0x05BC, + /* 3606 */ 0x05E3, 0x05BC, + /* 3608 */ 0x05E4, 0x05BC, + /* 3610 */ 0x05E6, 0x05BC, + /* 3612 */ 0x05E7, 0x05BC, + /* 3614 */ 0x05E8, 0x05BC, + /* 3616 */ 0x05E9, 0x05BC, + /* 3618 */ 0x05EA, 0x05BC, + /* 3620 */ 0x05D5, 0x05B9, + /* 3622 */ 0x05D1, 0x05BF, + /* 3624 */ 0x05DB, 0x05BF, + /* 3626 */ 0x05E4, 0x05BF, + /* 3628 */ 0x05D0, 0x05DC, /* 3630 */ 0x0626, 0x0627, - /* 3632 */ 0x0626, 0x06D5, + /* 3632 */ 0x0626, 0x0627, /* 3634 */ 0x0626, 0x06D5, - /* 3636 */ 0x0626, 0x0648, + /* 3636 */ 0x0626, 0x06D5, /* 3638 */ 0x0626, 0x0648, - /* 3640 */ 0x0626, 0x06C7, + /* 3640 */ 0x0626, 0x0648, /* 3642 */ 0x0626, 0x06C7, - /* 3644 */ 0x0626, 0x06C6, + /* 3644 */ 0x0626, 0x06C7, /* 3646 */ 0x0626, 0x06C6, - /* 3648 */ 0x0626, 0x06C8, + /* 3648 */ 0x0626, 0x06C6, /* 3650 */ 0x0626, 0x06C8, - /* 3652 */ 0x0626, 0x06D0, + /* 3652 */ 0x0626, 0x06C8, /* 3654 */ 0x0626, 0x06D0, /* 3656 */ 0x0626, 0x06D0, - /* 3658 */ 0x0626, 0x0649, + /* 3658 */ 0x0626, 0x06D0, /* 3660 */ 0x0626, 0x0649, /* 3662 */ 0x0626, 0x0649, - /* 3664 */ 0x0626, 0x062C, - /* 3666 */ 0x0626, 0x062D, - /* 3668 */ 0x0626, 0x0645, - /* 3670 */ 0x0626, 0x0649, - /* 3672 */ 0x0626, 0x064A, - /* 3674 */ 0x0628, 0x062C, - /* 3676 */ 0x0628, 0x062D, - /* 3678 */ 0x0628, 0x062E, - /* 3680 */ 0x0628, 0x0645, - /* 3682 */ 0x0628, 0x0649, - /* 3684 */ 0x0628, 0x064A, - /* 3686 */ 0x062A, 0x062C, - /* 3688 */ 0x062A, 0x062D, - /* 3690 */ 0x062A, 0x062E, - /* 3692 */ 0x062A, 0x0645, - /* 3694 */ 0x062A, 0x0649, - /* 3696 */ 0x062A, 0x064A, - /* 3698 */ 0x062B, 0x062C, - /* 3700 */ 0x062B, 0x0645, - /* 3702 */ 0x062B, 0x0649, - /* 3704 */ 0x062B, 0x064A, - /* 3706 */ 0x062C, 0x062D, - /* 3708 */ 0x062C, 0x0645, - /* 3710 */ 0x062D, 0x062C, - /* 3712 */ 0x062D, 0x0645, - /* 3714 */ 0x062E, 0x062C, - /* 3716 */ 0x062E, 0x062D, - /* 3718 */ 0x062E, 0x0645, - /* 3720 */ 0x0633, 0x062C, - /* 3722 */ 0x0633, 0x062D, - /* 3724 */ 0x0633, 0x062E, - /* 3726 */ 0x0633, 0x0645, - /* 3728 */ 0x0635, 0x062D, - /* 3730 */ 0x0635, 0x0645, - /* 3732 */ 0x0636, 0x062C, - /* 3734 */ 0x0636, 0x062D, - /* 3736 */ 0x0636, 0x062E, - /* 3738 */ 0x0636, 0x0645, - /* 3740 */ 0x0637, 0x062D, - /* 3742 */ 0x0637, 0x0645, - /* 3744 */ 0x0638, 0x0645, - /* 3746 */ 0x0639, 0x062C, - /* 3748 */ 0x0639, 0x0645, - /* 3750 */ 0x063A, 0x062C, - /* 3752 */ 0x063A, 0x0645, - /* 3754 */ 0x0641, 0x062C, - /* 3756 */ 0x0641, 0x062D, - /* 3758 */ 0x0641, 0x062E, - /* 3760 */ 0x0641, 0x0645, - /* 3762 */ 0x0641, 0x0649, - /* 3764 */ 0x0641, 0x064A, - /* 3766 */ 0x0642, 0x062D, - /* 3768 */ 0x0642, 0x0645, - /* 3770 */ 0x0642, 0x0649, - /* 3772 */ 0x0642, 0x064A, - /* 3774 */ 0x0643, 0x0627, - /* 3776 */ 0x0643, 0x062C, - /* 3778 */ 0x0643, 0x062D, - /* 3780 */ 0x0643, 0x062E, - /* 3782 */ 0x0643, 0x0644, - /* 3784 */ 0x0643, 0x0645, - /* 3786 */ 0x0643, 0x0649, - /* 3788 */ 0x0643, 0x064A, - /* 3790 */ 0x0644, 0x062C, - /* 3792 */ 0x0644, 0x062D, - /* 3794 */ 0x0644, 0x062E, - /* 3796 */ 0x0644, 0x0645, - /* 3798 */ 0x0644, 0x0649, - /* 3800 */ 0x0644, 0x064A, - /* 3802 */ 0x0645, 0x062C, - /* 3804 */ 0x0645, 0x062D, - /* 3806 */ 0x0645, 0x062E, - /* 3808 */ 0x0645, 0x0645, - /* 3810 */ 0x0645, 0x0649, - /* 3812 */ 0x0645, 0x064A, - /* 3814 */ 0x0646, 0x062C, - /* 3816 */ 0x0646, 0x062D, - /* 3818 */ 0x0646, 0x062E, - /* 3820 */ 0x0646, 0x0645, - /* 3822 */ 0x0646, 0x0649, - /* 3824 */ 0x0646, 0x064A, - /* 3826 */ 0x0647, 0x062C, - /* 3828 */ 0x0647, 0x0645, - /* 3830 */ 0x0647, 0x0649, - /* 3832 */ 0x0647, 0x064A, - /* 3834 */ 0x064A, 0x062C, - /* 3836 */ 0x064A, 0x062D, - /* 3838 */ 0x064A, 0x062E, - /* 3840 */ 0x064A, 0x0645, - /* 3842 */ 0x064A, 0x0649, - /* 3844 */ 0x064A, 0x064A, - /* 3846 */ 0x0630, 0x0670, - /* 3848 */ 0x0631, 0x0670, - /* 3850 */ 0x0649, 0x0670, - /* 3852 */ 0x0020, 0x064C, 0x0651, - /* 3855 */ 0x0020, 0x064D, 0x0651, - /* 3858 */ 0x0020, 0x064E, 0x0651, - /* 3861 */ 0x0020, 0x064F, 0x0651, - /* 3864 */ 0x0020, 0x0650, 0x0651, - /* 3867 */ 0x0020, 0x0651, 0x0670, - /* 3870 */ 0x0626, 0x0631, - /* 3872 */ 0x0626, 0x0632, - /* 3874 */ 0x0626, 0x0645, - /* 3876 */ 0x0626, 0x0646, - /* 3878 */ 0x0626, 0x0649, - /* 3880 */ 0x0626, 0x064A, - /* 3882 */ 0x0628, 0x0631, - /* 3884 */ 0x0628, 0x0632, - /* 3886 */ 0x0628, 0x0645, - /* 3888 */ 0x0628, 0x0646, - /* 3890 */ 0x0628, 0x0649, - /* 3892 */ 0x0628, 0x064A, - /* 3894 */ 0x062A, 0x0631, - /* 3896 */ 0x062A, 0x0632, - /* 3898 */ 0x062A, 0x0645, - /* 3900 */ 0x062A, 0x0646, - /* 3902 */ 0x062A, 0x0649, - /* 3904 */ 0x062A, 0x064A, - /* 3906 */ 0x062B, 0x0631, - /* 3908 */ 0x062B, 0x0632, - /* 3910 */ 0x062B, 0x0645, - /* 3912 */ 0x062B, 0x0646, - /* 3914 */ 0x062B, 0x0649, - /* 3916 */ 0x062B, 0x064A, - /* 3918 */ 0x0641, 0x0649, - /* 3920 */ 0x0641, 0x064A, - /* 3922 */ 0x0642, 0x0649, - /* 3924 */ 0x0642, 0x064A, - /* 3926 */ 0x0643, 0x0627, - /* 3928 */ 0x0643, 0x0644, - /* 3930 */ 0x0643, 0x0645, - /* 3932 */ 0x0643, 0x0649, - /* 3934 */ 0x0643, 0x064A, - /* 3936 */ 0x0644, 0x0645, - /* 3938 */ 0x0644, 0x0649, - /* 3940 */ 0x0644, 0x064A, - /* 3942 */ 0x0645, 0x0627, - /* 3944 */ 0x0645, 0x0645, - /* 3946 */ 0x0646, 0x0631, - /* 3948 */ 0x0646, 0x0632, - /* 3950 */ 0x0646, 0x0645, - /* 3952 */ 0x0646, 0x0646, - /* 3954 */ 0x0646, 0x0649, - /* 3956 */ 0x0646, 0x064A, - /* 3958 */ 0x0649, 0x0670, - /* 3960 */ 0x064A, 0x0631, - /* 3962 */ 0x064A, 0x0632, - /* 3964 */ 0x064A, 0x0645, - /* 3966 */ 0x064A, 0x0646, - /* 3968 */ 0x064A, 0x0649, - /* 3970 */ 0x064A, 0x064A, - /* 3972 */ 0x0626, 0x062C, - /* 3974 */ 0x0626, 0x062D, - /* 3976 */ 0x0626, 0x062E, - /* 3978 */ 0x0626, 0x0645, - /* 3980 */ 0x0626, 0x0647, - /* 3982 */ 0x0628, 0x062C, - /* 3984 */ 0x0628, 0x062D, - /* 3986 */ 0x0628, 0x062E, - /* 3988 */ 0x0628, 0x0645, - /* 3990 */ 0x0628, 0x0647, - /* 3992 */ 0x062A, 0x062C, - /* 3994 */ 0x062A, 0x062D, - /* 3996 */ 0x062A, 0x062E, - /* 3998 */ 0x062A, 0x0645, - /* 4000 */ 0x062A, 0x0647, - /* 4002 */ 0x062B, 0x0645, - /* 4004 */ 0x062C, 0x062D, - /* 4006 */ 0x062C, 0x0645, - /* 4008 */ 0x062D, 0x062C, - /* 4010 */ 0x062D, 0x0645, - /* 4012 */ 0x062E, 0x062C, - /* 4014 */ 0x062E, 0x0645, - /* 4016 */ 0x0633, 0x062C, - /* 4018 */ 0x0633, 0x062D, - /* 4020 */ 0x0633, 0x062E, - /* 4022 */ 0x0633, 0x0645, - /* 4024 */ 0x0635, 0x062D, - /* 4026 */ 0x0635, 0x062E, - /* 4028 */ 0x0635, 0x0645, - /* 4030 */ 0x0636, 0x062C, - /* 4032 */ 0x0636, 0x062D, - /* 4034 */ 0x0636, 0x062E, - /* 4036 */ 0x0636, 0x0645, - /* 4038 */ 0x0637, 0x062D, - /* 4040 */ 0x0638, 0x0645, - /* 4042 */ 0x0639, 0x062C, - /* 4044 */ 0x0639, 0x0645, - /* 4046 */ 0x063A, 0x062C, - /* 4048 */ 0x063A, 0x0645, - /* 4050 */ 0x0641, 0x062C, - /* 4052 */ 0x0641, 0x062D, - /* 4054 */ 0x0641, 0x062E, - /* 4056 */ 0x0641, 0x0645, - /* 4058 */ 0x0642, 0x062D, - /* 4060 */ 0x0642, 0x0645, - /* 4062 */ 0x0643, 0x062C, - /* 4064 */ 0x0643, 0x062D, - /* 4066 */ 0x0643, 0x062E, - /* 4068 */ 0x0643, 0x0644, - /* 4070 */ 0x0643, 0x0645, - /* 4072 */ 0x0644, 0x062C, - /* 4074 */ 0x0644, 0x062D, - /* 4076 */ 0x0644, 0x062E, - /* 4078 */ 0x0644, 0x0645, - /* 4080 */ 0x0644, 0x0647, - /* 4082 */ 0x0645, 0x062C, - /* 4084 */ 0x0645, 0x062D, - /* 4086 */ 0x0645, 0x062E, - /* 4088 */ 0x0645, 0x0645, - /* 4090 */ 0x0646, 0x062C, - /* 4092 */ 0x0646, 0x062D, - /* 4094 */ 0x0646, 0x062E, - /* 4096 */ 0x0646, 0x0645, - /* 4098 */ 0x0646, 0x0647, - /* 4100 */ 0x0647, 0x062C, - /* 4102 */ 0x0647, 0x0645, - /* 4104 */ 0x0647, 0x0670, - /* 4106 */ 0x064A, 0x062C, - /* 4108 */ 0x064A, 0x062D, - /* 4110 */ 0x064A, 0x062E, - /* 4112 */ 0x064A, 0x0645, - /* 4114 */ 0x064A, 0x0647, - /* 4116 */ 0x0626, 0x0645, - /* 4118 */ 0x0626, 0x0647, - /* 4120 */ 0x0628, 0x0645, - /* 4122 */ 0x0628, 0x0647, - /* 4124 */ 0x062A, 0x0645, - /* 4126 */ 0x062A, 0x0647, - /* 4128 */ 0x062B, 0x0645, - /* 4130 */ 0x062B, 0x0647, - /* 4132 */ 0x0633, 0x0645, - /* 4134 */ 0x0633, 0x0647, - /* 4136 */ 0x0634, 0x0645, - /* 4138 */ 0x0634, 0x0647, - /* 4140 */ 0x0643, 0x0644, - /* 4142 */ 0x0643, 0x0645, - /* 4144 */ 0x0644, 0x0645, - /* 4146 */ 0x0646, 0x0645, - /* 4148 */ 0x0646, 0x0647, - /* 4150 */ 0x064A, 0x0645, - /* 4152 */ 0x064A, 0x0647, - /* 4154 */ 0x0640, 0x064E, 0x0651, - /* 4157 */ 0x0640, 0x064F, 0x0651, - /* 4160 */ 0x0640, 0x0650, 0x0651, - /* 4163 */ 0x0637, 0x0649, - /* 4165 */ 0x0637, 0x064A, - /* 4167 */ 0x0639, 0x0649, - /* 4169 */ 0x0639, 0x064A, - /* 4171 */ 0x063A, 0x0649, - /* 4173 */ 0x063A, 0x064A, - /* 4175 */ 0x0633, 0x0649, - /* 4177 */ 0x0633, 0x064A, - /* 4179 */ 0x0634, 0x0649, - /* 4181 */ 0x0634, 0x064A, - /* 4183 */ 0x062D, 0x0649, - /* 4185 */ 0x062D, 0x064A, - /* 4187 */ 0x062C, 0x0649, - /* 4189 */ 0x062C, 0x064A, - /* 4191 */ 0x062E, 0x0649, - /* 4193 */ 0x062E, 0x064A, - /* 4195 */ 0x0635, 0x0649, - /* 4197 */ 0x0635, 0x064A, - /* 4199 */ 0x0636, 0x0649, - /* 4201 */ 0x0636, 0x064A, - /* 4203 */ 0x0634, 0x062C, - /* 4205 */ 0x0634, 0x062D, - /* 4207 */ 0x0634, 0x062E, - /* 4209 */ 0x0634, 0x0645, - /* 4211 */ 0x0634, 0x0631, - /* 4213 */ 0x0633, 0x0631, - /* 4215 */ 0x0635, 0x0631, - /* 4217 */ 0x0636, 0x0631, - /* 4219 */ 0x0637, 0x0649, - /* 4221 */ 0x0637, 0x064A, - /* 4223 */ 0x0639, 0x0649, - /* 4225 */ 0x0639, 0x064A, - /* 4227 */ 0x063A, 0x0649, - /* 4229 */ 0x063A, 0x064A, - /* 4231 */ 0x0633, 0x0649, - /* 4233 */ 0x0633, 0x064A, - /* 4235 */ 0x0634, 0x0649, - /* 4237 */ 0x0634, 0x064A, - /* 4239 */ 0x062D, 0x0649, - /* 4241 */ 0x062D, 0x064A, - /* 4243 */ 0x062C, 0x0649, - /* 4245 */ 0x062C, 0x064A, - /* 4247 */ 0x062E, 0x0649, - /* 4249 */ 0x062E, 0x064A, - /* 4251 */ 0x0635, 0x0649, - /* 4253 */ 0x0635, 0x064A, - /* 4255 */ 0x0636, 0x0649, - /* 4257 */ 0x0636, 0x064A, - /* 4259 */ 0x0634, 0x062C, - /* 4261 */ 0x0634, 0x062D, - /* 4263 */ 0x0634, 0x062E, - /* 4265 */ 0x0634, 0x0645, - /* 4267 */ 0x0634, 0x0631, - /* 4269 */ 0x0633, 0x0631, - /* 4271 */ 0x0635, 0x0631, - /* 4273 */ 0x0636, 0x0631, - /* 4275 */ 0x0634, 0x062C, - /* 4277 */ 0x0634, 0x062D, - /* 4279 */ 0x0634, 0x062E, - /* 4281 */ 0x0634, 0x0645, - /* 4283 */ 0x0633, 0x0647, - /* 4285 */ 0x0634, 0x0647, - /* 4287 */ 0x0637, 0x0645, - /* 4289 */ 0x0633, 0x062C, - /* 4291 */ 0x0633, 0x062D, - /* 4293 */ 0x0633, 0x062E, - /* 4295 */ 0x0634, 0x062C, - /* 4297 */ 0x0634, 0x062D, - /* 4299 */ 0x0634, 0x062E, - /* 4301 */ 0x0637, 0x0645, - /* 4303 */ 0x0638, 0x0645, - /* 4305 */ 0x0627, 0x064B, + /* 3664 */ 0x0626, 0x0649, + /* 3666 */ 0x0626, 0x062C, + /* 3668 */ 0x0626, 0x062D, + /* 3670 */ 0x0626, 0x0645, + /* 3672 */ 0x0626, 0x0649, + /* 3674 */ 0x0626, 0x064A, + /* 3676 */ 0x0628, 0x062C, + /* 3678 */ 0x0628, 0x062D, + /* 3680 */ 0x0628, 0x062E, + /* 3682 */ 0x0628, 0x0645, + /* 3684 */ 0x0628, 0x0649, + /* 3686 */ 0x0628, 0x064A, + /* 3688 */ 0x062A, 0x062C, + /* 3690 */ 0x062A, 0x062D, + /* 3692 */ 0x062A, 0x062E, + /* 3694 */ 0x062A, 0x0645, + /* 3696 */ 0x062A, 0x0649, + /* 3698 */ 0x062A, 0x064A, + /* 3700 */ 0x062B, 0x062C, + /* 3702 */ 0x062B, 0x0645, + /* 3704 */ 0x062B, 0x0649, + /* 3706 */ 0x062B, 0x064A, + /* 3708 */ 0x062C, 0x062D, + /* 3710 */ 0x062C, 0x0645, + /* 3712 */ 0x062D, 0x062C, + /* 3714 */ 0x062D, 0x0645, + /* 3716 */ 0x062E, 0x062C, + /* 3718 */ 0x062E, 0x062D, + /* 3720 */ 0x062E, 0x0645, + /* 3722 */ 0x0633, 0x062C, + /* 3724 */ 0x0633, 0x062D, + /* 3726 */ 0x0633, 0x062E, + /* 3728 */ 0x0633, 0x0645, + /* 3730 */ 0x0635, 0x062D, + /* 3732 */ 0x0635, 0x0645, + /* 3734 */ 0x0636, 0x062C, + /* 3736 */ 0x0636, 0x062D, + /* 3738 */ 0x0636, 0x062E, + /* 3740 */ 0x0636, 0x0645, + /* 3742 */ 0x0637, 0x062D, + /* 3744 */ 0x0637, 0x0645, + /* 3746 */ 0x0638, 0x0645, + /* 3748 */ 0x0639, 0x062C, + /* 3750 */ 0x0639, 0x0645, + /* 3752 */ 0x063A, 0x062C, + /* 3754 */ 0x063A, 0x0645, + /* 3756 */ 0x0641, 0x062C, + /* 3758 */ 0x0641, 0x062D, + /* 3760 */ 0x0641, 0x062E, + /* 3762 */ 0x0641, 0x0645, + /* 3764 */ 0x0641, 0x0649, + /* 3766 */ 0x0641, 0x064A, + /* 3768 */ 0x0642, 0x062D, + /* 3770 */ 0x0642, 0x0645, + /* 3772 */ 0x0642, 0x0649, + /* 3774 */ 0x0642, 0x064A, + /* 3776 */ 0x0643, 0x0627, + /* 3778 */ 0x0643, 0x062C, + /* 3780 */ 0x0643, 0x062D, + /* 3782 */ 0x0643, 0x062E, + /* 3784 */ 0x0643, 0x0644, + /* 3786 */ 0x0643, 0x0645, + /* 3788 */ 0x0643, 0x0649, + /* 3790 */ 0x0643, 0x064A, + /* 3792 */ 0x0644, 0x062C, + /* 3794 */ 0x0644, 0x062D, + /* 3796 */ 0x0644, 0x062E, + /* 3798 */ 0x0644, 0x0645, + /* 3800 */ 0x0644, 0x0649, + /* 3802 */ 0x0644, 0x064A, + /* 3804 */ 0x0645, 0x062C, + /* 3806 */ 0x0645, 0x062D, + /* 3808 */ 0x0645, 0x062E, + /* 3810 */ 0x0645, 0x0645, + /* 3812 */ 0x0645, 0x0649, + /* 3814 */ 0x0645, 0x064A, + /* 3816 */ 0x0646, 0x062C, + /* 3818 */ 0x0646, 0x062D, + /* 3820 */ 0x0646, 0x062E, + /* 3822 */ 0x0646, 0x0645, + /* 3824 */ 0x0646, 0x0649, + /* 3826 */ 0x0646, 0x064A, + /* 3828 */ 0x0647, 0x062C, + /* 3830 */ 0x0647, 0x0645, + /* 3832 */ 0x0647, 0x0649, + /* 3834 */ 0x0647, 0x064A, + /* 3836 */ 0x064A, 0x062C, + /* 3838 */ 0x064A, 0x062D, + /* 3840 */ 0x064A, 0x062E, + /* 3842 */ 0x064A, 0x0645, + /* 3844 */ 0x064A, 0x0649, + /* 3846 */ 0x064A, 0x064A, + /* 3848 */ 0x0630, 0x0670, + /* 3850 */ 0x0631, 0x0670, + /* 3852 */ 0x0649, 0x0670, + /* 3854 */ 0x0020, 0x064C, 0x0651, + /* 3857 */ 0x0020, 0x064D, 0x0651, + /* 3860 */ 0x0020, 0x064E, 0x0651, + /* 3863 */ 0x0020, 0x064F, 0x0651, + /* 3866 */ 0x0020, 0x0650, 0x0651, + /* 3869 */ 0x0020, 0x0651, 0x0670, + /* 3872 */ 0x0626, 0x0631, + /* 3874 */ 0x0626, 0x0632, + /* 3876 */ 0x0626, 0x0645, + /* 3878 */ 0x0626, 0x0646, + /* 3880 */ 0x0626, 0x0649, + /* 3882 */ 0x0626, 0x064A, + /* 3884 */ 0x0628, 0x0631, + /* 3886 */ 0x0628, 0x0632, + /* 3888 */ 0x0628, 0x0645, + /* 3890 */ 0x0628, 0x0646, + /* 3892 */ 0x0628, 0x0649, + /* 3894 */ 0x0628, 0x064A, + /* 3896 */ 0x062A, 0x0631, + /* 3898 */ 0x062A, 0x0632, + /* 3900 */ 0x062A, 0x0645, + /* 3902 */ 0x062A, 0x0646, + /* 3904 */ 0x062A, 0x0649, + /* 3906 */ 0x062A, 0x064A, + /* 3908 */ 0x062B, 0x0631, + /* 3910 */ 0x062B, 0x0632, + /* 3912 */ 0x062B, 0x0645, + /* 3914 */ 0x062B, 0x0646, + /* 3916 */ 0x062B, 0x0649, + /* 3918 */ 0x062B, 0x064A, + /* 3920 */ 0x0641, 0x0649, + /* 3922 */ 0x0641, 0x064A, + /* 3924 */ 0x0642, 0x0649, + /* 3926 */ 0x0642, 0x064A, + /* 3928 */ 0x0643, 0x0627, + /* 3930 */ 0x0643, 0x0644, + /* 3932 */ 0x0643, 0x0645, + /* 3934 */ 0x0643, 0x0649, + /* 3936 */ 0x0643, 0x064A, + /* 3938 */ 0x0644, 0x0645, + /* 3940 */ 0x0644, 0x0649, + /* 3942 */ 0x0644, 0x064A, + /* 3944 */ 0x0645, 0x0627, + /* 3946 */ 0x0645, 0x0645, + /* 3948 */ 0x0646, 0x0631, + /* 3950 */ 0x0646, 0x0632, + /* 3952 */ 0x0646, 0x0645, + /* 3954 */ 0x0646, 0x0646, + /* 3956 */ 0x0646, 0x0649, + /* 3958 */ 0x0646, 0x064A, + /* 3960 */ 0x0649, 0x0670, + /* 3962 */ 0x064A, 0x0631, + /* 3964 */ 0x064A, 0x0632, + /* 3966 */ 0x064A, 0x0645, + /* 3968 */ 0x064A, 0x0646, + /* 3970 */ 0x064A, 0x0649, + /* 3972 */ 0x064A, 0x064A, + /* 3974 */ 0x0626, 0x062C, + /* 3976 */ 0x0626, 0x062D, + /* 3978 */ 0x0626, 0x062E, + /* 3980 */ 0x0626, 0x0645, + /* 3982 */ 0x0626, 0x0647, + /* 3984 */ 0x0628, 0x062C, + /* 3986 */ 0x0628, 0x062D, + /* 3988 */ 0x0628, 0x062E, + /* 3990 */ 0x0628, 0x0645, + /* 3992 */ 0x0628, 0x0647, + /* 3994 */ 0x062A, 0x062C, + /* 3996 */ 0x062A, 0x062D, + /* 3998 */ 0x062A, 0x062E, + /* 4000 */ 0x062A, 0x0645, + /* 4002 */ 0x062A, 0x0647, + /* 4004 */ 0x062B, 0x0645, + /* 4006 */ 0x062C, 0x062D, + /* 4008 */ 0x062C, 0x0645, + /* 4010 */ 0x062D, 0x062C, + /* 4012 */ 0x062D, 0x0645, + /* 4014 */ 0x062E, 0x062C, + /* 4016 */ 0x062E, 0x0645, + /* 4018 */ 0x0633, 0x062C, + /* 4020 */ 0x0633, 0x062D, + /* 4022 */ 0x0633, 0x062E, + /* 4024 */ 0x0633, 0x0645, + /* 4026 */ 0x0635, 0x062D, + /* 4028 */ 0x0635, 0x062E, + /* 4030 */ 0x0635, 0x0645, + /* 4032 */ 0x0636, 0x062C, + /* 4034 */ 0x0636, 0x062D, + /* 4036 */ 0x0636, 0x062E, + /* 4038 */ 0x0636, 0x0645, + /* 4040 */ 0x0637, 0x062D, + /* 4042 */ 0x0638, 0x0645, + /* 4044 */ 0x0639, 0x062C, + /* 4046 */ 0x0639, 0x0645, + /* 4048 */ 0x063A, 0x062C, + /* 4050 */ 0x063A, 0x0645, + /* 4052 */ 0x0641, 0x062C, + /* 4054 */ 0x0641, 0x062D, + /* 4056 */ 0x0641, 0x062E, + /* 4058 */ 0x0641, 0x0645, + /* 4060 */ 0x0642, 0x062D, + /* 4062 */ 0x0642, 0x0645, + /* 4064 */ 0x0643, 0x062C, + /* 4066 */ 0x0643, 0x062D, + /* 4068 */ 0x0643, 0x062E, + /* 4070 */ 0x0643, 0x0644, + /* 4072 */ 0x0643, 0x0645, + /* 4074 */ 0x0644, 0x062C, + /* 4076 */ 0x0644, 0x062D, + /* 4078 */ 0x0644, 0x062E, + /* 4080 */ 0x0644, 0x0645, + /* 4082 */ 0x0644, 0x0647, + /* 4084 */ 0x0645, 0x062C, + /* 4086 */ 0x0645, 0x062D, + /* 4088 */ 0x0645, 0x062E, + /* 4090 */ 0x0645, 0x0645, + /* 4092 */ 0x0646, 0x062C, + /* 4094 */ 0x0646, 0x062D, + /* 4096 */ 0x0646, 0x062E, + /* 4098 */ 0x0646, 0x0645, + /* 4100 */ 0x0646, 0x0647, + /* 4102 */ 0x0647, 0x062C, + /* 4104 */ 0x0647, 0x0645, + /* 4106 */ 0x0647, 0x0670, + /* 4108 */ 0x064A, 0x062C, + /* 4110 */ 0x064A, 0x062D, + /* 4112 */ 0x064A, 0x062E, + /* 4114 */ 0x064A, 0x0645, + /* 4116 */ 0x064A, 0x0647, + /* 4118 */ 0x0626, 0x0645, + /* 4120 */ 0x0626, 0x0647, + /* 4122 */ 0x0628, 0x0645, + /* 4124 */ 0x0628, 0x0647, + /* 4126 */ 0x062A, 0x0645, + /* 4128 */ 0x062A, 0x0647, + /* 4130 */ 0x062B, 0x0645, + /* 4132 */ 0x062B, 0x0647, + /* 4134 */ 0x0633, 0x0645, + /* 4136 */ 0x0633, 0x0647, + /* 4138 */ 0x0634, 0x0645, + /* 4140 */ 0x0634, 0x0647, + /* 4142 */ 0x0643, 0x0644, + /* 4144 */ 0x0643, 0x0645, + /* 4146 */ 0x0644, 0x0645, + /* 4148 */ 0x0646, 0x0645, + /* 4150 */ 0x0646, 0x0647, + /* 4152 */ 0x064A, 0x0645, + /* 4154 */ 0x064A, 0x0647, + /* 4156 */ 0x0640, 0x064E, 0x0651, + /* 4159 */ 0x0640, 0x064F, 0x0651, + /* 4162 */ 0x0640, 0x0650, 0x0651, + /* 4165 */ 0x0637, 0x0649, + /* 4167 */ 0x0637, 0x064A, + /* 4169 */ 0x0639, 0x0649, + /* 4171 */ 0x0639, 0x064A, + /* 4173 */ 0x063A, 0x0649, + /* 4175 */ 0x063A, 0x064A, + /* 4177 */ 0x0633, 0x0649, + /* 4179 */ 0x0633, 0x064A, + /* 4181 */ 0x0634, 0x0649, + /* 4183 */ 0x0634, 0x064A, + /* 4185 */ 0x062D, 0x0649, + /* 4187 */ 0x062D, 0x064A, + /* 4189 */ 0x062C, 0x0649, + /* 4191 */ 0x062C, 0x064A, + /* 4193 */ 0x062E, 0x0649, + /* 4195 */ 0x062E, 0x064A, + /* 4197 */ 0x0635, 0x0649, + /* 4199 */ 0x0635, 0x064A, + /* 4201 */ 0x0636, 0x0649, + /* 4203 */ 0x0636, 0x064A, + /* 4205 */ 0x0634, 0x062C, + /* 4207 */ 0x0634, 0x062D, + /* 4209 */ 0x0634, 0x062E, + /* 4211 */ 0x0634, 0x0645, + /* 4213 */ 0x0634, 0x0631, + /* 4215 */ 0x0633, 0x0631, + /* 4217 */ 0x0635, 0x0631, + /* 4219 */ 0x0636, 0x0631, + /* 4221 */ 0x0637, 0x0649, + /* 4223 */ 0x0637, 0x064A, + /* 4225 */ 0x0639, 0x0649, + /* 4227 */ 0x0639, 0x064A, + /* 4229 */ 0x063A, 0x0649, + /* 4231 */ 0x063A, 0x064A, + /* 4233 */ 0x0633, 0x0649, + /* 4235 */ 0x0633, 0x064A, + /* 4237 */ 0x0634, 0x0649, + /* 4239 */ 0x0634, 0x064A, + /* 4241 */ 0x062D, 0x0649, + /* 4243 */ 0x062D, 0x064A, + /* 4245 */ 0x062C, 0x0649, + /* 4247 */ 0x062C, 0x064A, + /* 4249 */ 0x062E, 0x0649, + /* 4251 */ 0x062E, 0x064A, + /* 4253 */ 0x0635, 0x0649, + /* 4255 */ 0x0635, 0x064A, + /* 4257 */ 0x0636, 0x0649, + /* 4259 */ 0x0636, 0x064A, + /* 4261 */ 0x0634, 0x062C, + /* 4263 */ 0x0634, 0x062D, + /* 4265 */ 0x0634, 0x062E, + /* 4267 */ 0x0634, 0x0645, + /* 4269 */ 0x0634, 0x0631, + /* 4271 */ 0x0633, 0x0631, + /* 4273 */ 0x0635, 0x0631, + /* 4275 */ 0x0636, 0x0631, + /* 4277 */ 0x0634, 0x062C, + /* 4279 */ 0x0634, 0x062D, + /* 4281 */ 0x0634, 0x062E, + /* 4283 */ 0x0634, 0x0645, + /* 4285 */ 0x0633, 0x0647, + /* 4287 */ 0x0634, 0x0647, + /* 4289 */ 0x0637, 0x0645, + /* 4291 */ 0x0633, 0x062C, + /* 4293 */ 0x0633, 0x062D, + /* 4295 */ 0x0633, 0x062E, + /* 4297 */ 0x0634, 0x062C, + /* 4299 */ 0x0634, 0x062D, + /* 4301 */ 0x0634, 0x062E, + /* 4303 */ 0x0637, 0x0645, + /* 4305 */ 0x0638, 0x0645, /* 4307 */ 0x0627, 0x064B, - /* 4309 */ 0x062A, 0x062C, 0x0645, - /* 4312 */ 0x062A, 0x062D, 0x062C, - /* 4315 */ 0x062A, 0x062D, 0x062C, - /* 4318 */ 0x062A, 0x062D, 0x0645, - /* 4321 */ 0x062A, 0x062E, 0x0645, - /* 4324 */ 0x062A, 0x0645, 0x062C, - /* 4327 */ 0x062A, 0x0645, 0x062D, - /* 4330 */ 0x062A, 0x0645, 0x062E, - /* 4333 */ 0x062C, 0x0645, 0x062D, - /* 4336 */ 0x062C, 0x0645, 0x062D, - /* 4339 */ 0x062D, 0x0645, 0x064A, - /* 4342 */ 0x062D, 0x0645, 0x0649, - /* 4345 */ 0x0633, 0x062D, 0x062C, - /* 4348 */ 0x0633, 0x062C, 0x062D, - /* 4351 */ 0x0633, 0x062C, 0x0649, - /* 4354 */ 0x0633, 0x0645, 0x062D, - /* 4357 */ 0x0633, 0x0645, 0x062D, - /* 4360 */ 0x0633, 0x0645, 0x062C, - /* 4363 */ 0x0633, 0x0645, 0x0645, - /* 4366 */ 0x0633, 0x0645, 0x0645, - /* 4369 */ 0x0635, 0x062D, 0x062D, - /* 4372 */ 0x0635, 0x062D, 0x062D, - /* 4375 */ 0x0635, 0x0645, 0x0645, - /* 4378 */ 0x0634, 0x062D, 0x0645, - /* 4381 */ 0x0634, 0x062D, 0x0645, - /* 4384 */ 0x0634, 0x062C, 0x064A, - /* 4387 */ 0x0634, 0x0645, 0x062E, - /* 4390 */ 0x0634, 0x0645, 0x062E, - /* 4393 */ 0x0634, 0x0645, 0x0645, - /* 4396 */ 0x0634, 0x0645, 0x0645, - /* 4399 */ 0x0636, 0x062D, 0x0649, - /* 4402 */ 0x0636, 0x062E, 0x0645, - /* 4405 */ 0x0636, 0x062E, 0x0645, - /* 4408 */ 0x0637, 0x0645, 0x062D, - /* 4411 */ 0x0637, 0x0645, 0x062D, - /* 4414 */ 0x0637, 0x0645, 0x0645, - /* 4417 */ 0x0637, 0x0645, 0x064A, - /* 4420 */ 0x0639, 0x062C, 0x0645, - /* 4423 */ 0x0639, 0x0645, 0x0645, - /* 4426 */ 0x0639, 0x0645, 0x0645, - /* 4429 */ 0x0639, 0x0645, 0x0649, - /* 4432 */ 0x063A, 0x0645, 0x0645, - /* 4435 */ 0x063A, 0x0645, 0x064A, - /* 4438 */ 0x063A, 0x0645, 0x0649, - /* 4441 */ 0x0641, 0x062E, 0x0645, - /* 4444 */ 0x0641, 0x062E, 0x0645, - /* 4447 */ 0x0642, 0x0645, 0x062D, - /* 4450 */ 0x0642, 0x0645, 0x0645, - /* 4453 */ 0x0644, 0x062D, 0x0645, - /* 4456 */ 0x0644, 0x062D, 0x064A, - /* 4459 */ 0x0644, 0x062D, 0x0649, - /* 4462 */ 0x0644, 0x062C, 0x062C, - /* 4465 */ 0x0644, 0x062C, 0x062C, - /* 4468 */ 0x0644, 0x062E, 0x0645, - /* 4471 */ 0x0644, 0x062E, 0x0645, - /* 4474 */ 0x0644, 0x0645, 0x062D, - /* 4477 */ 0x0644, 0x0645, 0x062D, - /* 4480 */ 0x0645, 0x062D, 0x062C, - /* 4483 */ 0x0645, 0x062D, 0x0645, - /* 4486 */ 0x0645, 0x062D, 0x064A, - /* 4489 */ 0x0645, 0x062C, 0x062D, - /* 4492 */ 0x0645, 0x062C, 0x0645, - /* 4495 */ 0x0645, 0x062E, 0x062C, - /* 4498 */ 0x0645, 0x062E, 0x0645, - /* 4501 */ 0x0645, 0x062C, 0x062E, - /* 4504 */ 0x0647, 0x0645, 0x062C, - /* 4507 */ 0x0647, 0x0645, 0x0645, - /* 4510 */ 0x0646, 0x062D, 0x0645, - /* 4513 */ 0x0646, 0x062D, 0x0649, - /* 4516 */ 0x0646, 0x062C, 0x0645, - /* 4519 */ 0x0646, 0x062C, 0x0645, - /* 4522 */ 0x0646, 0x062C, 0x0649, - /* 4525 */ 0x0646, 0x0645, 0x064A, - /* 4528 */ 0x0646, 0x0645, 0x0649, - /* 4531 */ 0x064A, 0x0645, 0x0645, - /* 4534 */ 0x064A, 0x0645, 0x0645, - /* 4537 */ 0x0628, 0x062E, 0x064A, - /* 4540 */ 0x062A, 0x062C, 0x064A, - /* 4543 */ 0x062A, 0x062C, 0x0649, - /* 4546 */ 0x062A, 0x062E, 0x064A, - /* 4549 */ 0x062A, 0x062E, 0x0649, - /* 4552 */ 0x062A, 0x0645, 0x064A, - /* 4555 */ 0x062A, 0x0645, 0x0649, - /* 4558 */ 0x062C, 0x0645, 0x064A, - /* 4561 */ 0x062C, 0x062D, 0x0649, - /* 4564 */ 0x062C, 0x0645, 0x0649, - /* 4567 */ 0x0633, 0x062E, 0x0649, - /* 4570 */ 0x0635, 0x062D, 0x064A, - /* 4573 */ 0x0634, 0x062D, 0x064A, - /* 4576 */ 0x0636, 0x062D, 0x064A, - /* 4579 */ 0x0644, 0x062C, 0x064A, - /* 4582 */ 0x0644, 0x0645, 0x064A, - /* 4585 */ 0x064A, 0x062D, 0x064A, - /* 4588 */ 0x064A, 0x062C, 0x064A, - /* 4591 */ 0x064A, 0x0645, 0x064A, - /* 4594 */ 0x0645, 0x0645, 0x064A, - /* 4597 */ 0x0642, 0x0645, 0x064A, - /* 4600 */ 0x0646, 0x062D, 0x064A, - /* 4603 */ 0x0642, 0x0645, 0x062D, - /* 4606 */ 0x0644, 0x062D, 0x0645, - /* 4609 */ 0x0639, 0x0645, 0x064A, - /* 4612 */ 0x0643, 0x0645, 0x064A, - /* 4615 */ 0x0646, 0x062C, 0x062D, - /* 4618 */ 0x0645, 0x062E, 0x064A, - /* 4621 */ 0x0644, 0x062C, 0x0645, - /* 4624 */ 0x0643, 0x0645, 0x0645, - /* 4627 */ 0x0644, 0x062C, 0x0645, - /* 4630 */ 0x0646, 0x062C, 0x062D, - /* 4633 */ 0x062C, 0x062D, 0x064A, - /* 4636 */ 0x062D, 0x062C, 0x064A, - /* 4639 */ 0x0645, 0x062C, 0x064A, - /* 4642 */ 0x0641, 0x0645, 0x064A, - /* 4645 */ 0x0628, 0x062D, 0x064A, - /* 4648 */ 0x0643, 0x0645, 0x0645, - /* 4651 */ 0x0639, 0x062C, 0x0645, - /* 4654 */ 0x0635, 0x0645, 0x0645, - /* 4657 */ 0x0633, 0x062E, 0x064A, - /* 4660 */ 0x0646, 0x062C, 0x064A, - /* 4663 */ 0x0635, 0x0644, 0x06D2, - /* 4666 */ 0x0642, 0x0644, 0x06D2, - /* 4669 */ 0x0627, 0x0644, 0x0644, 0x0647, - /* 4673 */ 0x0627, 0x0643, 0x0628, 0x0631, - /* 4677 */ 0x0645, 0x062D, 0x0645, 0x062F, - /* 4681 */ 0x0635, 0x0644, 0x0639, 0x0645, - /* 4685 */ 0x0631, 0x0633, 0x0648, 0x0644, - /* 4689 */ 0x0639, 0x0644, 0x064A, 0x0647, - /* 4693 */ 0x0648, 0x0633, 0x0644, 0x0645, - /* 4697 */ 0x0635, 0x0644, 0x0649, - /* 4700 */ 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, - /* 4718 */ 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, - /* 4726 */ 0x0631, 0x06CC, 0x0627, 0x0644, - /* 4730 */ 0x0020, 0x064B, - /* 4732 */ 0x0640, 0x064B, - /* 4734 */ 0x0020, 0x064C, - /* 4736 */ 0x0020, 0x064D, - /* 4738 */ 0x0020, 0x064E, - /* 4740 */ 0x0640, 0x064E, - /* 4742 */ 0x0020, 0x064F, - /* 4744 */ 0x0640, 0x064F, - /* 4746 */ 0x0020, 0x0650, - /* 4748 */ 0x0640, 0x0650, - /* 4750 */ 0x0020, 0x0651, - /* 4752 */ 0x0640, 0x0651, - /* 4754 */ 0x0020, 0x0652, - /* 4756 */ 0x0640, 0x0652, - /* 4758 */ 0x0644, 0x0622, + /* 4309 */ 0x0627, 0x064B, + /* 4311 */ 0x062A, 0x062C, 0x0645, + /* 4314 */ 0x062A, 0x062D, 0x062C, + /* 4317 */ 0x062A, 0x062D, 0x062C, + /* 4320 */ 0x062A, 0x062D, 0x0645, + /* 4323 */ 0x062A, 0x062E, 0x0645, + /* 4326 */ 0x062A, 0x0645, 0x062C, + /* 4329 */ 0x062A, 0x0645, 0x062D, + /* 4332 */ 0x062A, 0x0645, 0x062E, + /* 4335 */ 0x062C, 0x0645, 0x062D, + /* 4338 */ 0x062C, 0x0645, 0x062D, + /* 4341 */ 0x062D, 0x0645, 0x064A, + /* 4344 */ 0x062D, 0x0645, 0x0649, + /* 4347 */ 0x0633, 0x062D, 0x062C, + /* 4350 */ 0x0633, 0x062C, 0x062D, + /* 4353 */ 0x0633, 0x062C, 0x0649, + /* 4356 */ 0x0633, 0x0645, 0x062D, + /* 4359 */ 0x0633, 0x0645, 0x062D, + /* 4362 */ 0x0633, 0x0645, 0x062C, + /* 4365 */ 0x0633, 0x0645, 0x0645, + /* 4368 */ 0x0633, 0x0645, 0x0645, + /* 4371 */ 0x0635, 0x062D, 0x062D, + /* 4374 */ 0x0635, 0x062D, 0x062D, + /* 4377 */ 0x0635, 0x0645, 0x0645, + /* 4380 */ 0x0634, 0x062D, 0x0645, + /* 4383 */ 0x0634, 0x062D, 0x0645, + /* 4386 */ 0x0634, 0x062C, 0x064A, + /* 4389 */ 0x0634, 0x0645, 0x062E, + /* 4392 */ 0x0634, 0x0645, 0x062E, + /* 4395 */ 0x0634, 0x0645, 0x0645, + /* 4398 */ 0x0634, 0x0645, 0x0645, + /* 4401 */ 0x0636, 0x062D, 0x0649, + /* 4404 */ 0x0636, 0x062E, 0x0645, + /* 4407 */ 0x0636, 0x062E, 0x0645, + /* 4410 */ 0x0637, 0x0645, 0x062D, + /* 4413 */ 0x0637, 0x0645, 0x062D, + /* 4416 */ 0x0637, 0x0645, 0x0645, + /* 4419 */ 0x0637, 0x0645, 0x064A, + /* 4422 */ 0x0639, 0x062C, 0x0645, + /* 4425 */ 0x0639, 0x0645, 0x0645, + /* 4428 */ 0x0639, 0x0645, 0x0645, + /* 4431 */ 0x0639, 0x0645, 0x0649, + /* 4434 */ 0x063A, 0x0645, 0x0645, + /* 4437 */ 0x063A, 0x0645, 0x064A, + /* 4440 */ 0x063A, 0x0645, 0x0649, + /* 4443 */ 0x0641, 0x062E, 0x0645, + /* 4446 */ 0x0641, 0x062E, 0x0645, + /* 4449 */ 0x0642, 0x0645, 0x062D, + /* 4452 */ 0x0642, 0x0645, 0x0645, + /* 4455 */ 0x0644, 0x062D, 0x0645, + /* 4458 */ 0x0644, 0x062D, 0x064A, + /* 4461 */ 0x0644, 0x062D, 0x0649, + /* 4464 */ 0x0644, 0x062C, 0x062C, + /* 4467 */ 0x0644, 0x062C, 0x062C, + /* 4470 */ 0x0644, 0x062E, 0x0645, + /* 4473 */ 0x0644, 0x062E, 0x0645, + /* 4476 */ 0x0644, 0x0645, 0x062D, + /* 4479 */ 0x0644, 0x0645, 0x062D, + /* 4482 */ 0x0645, 0x062D, 0x062C, + /* 4485 */ 0x0645, 0x062D, 0x0645, + /* 4488 */ 0x0645, 0x062D, 0x064A, + /* 4491 */ 0x0645, 0x062C, 0x062D, + /* 4494 */ 0x0645, 0x062C, 0x0645, + /* 4497 */ 0x0645, 0x062E, 0x062C, + /* 4500 */ 0x0645, 0x062E, 0x0645, + /* 4503 */ 0x0645, 0x062C, 0x062E, + /* 4506 */ 0x0647, 0x0645, 0x062C, + /* 4509 */ 0x0647, 0x0645, 0x0645, + /* 4512 */ 0x0646, 0x062D, 0x0645, + /* 4515 */ 0x0646, 0x062D, 0x0649, + /* 4518 */ 0x0646, 0x062C, 0x0645, + /* 4521 */ 0x0646, 0x062C, 0x0645, + /* 4524 */ 0x0646, 0x062C, 0x0649, + /* 4527 */ 0x0646, 0x0645, 0x064A, + /* 4530 */ 0x0646, 0x0645, 0x0649, + /* 4533 */ 0x064A, 0x0645, 0x0645, + /* 4536 */ 0x064A, 0x0645, 0x0645, + /* 4539 */ 0x0628, 0x062E, 0x064A, + /* 4542 */ 0x062A, 0x062C, 0x064A, + /* 4545 */ 0x062A, 0x062C, 0x0649, + /* 4548 */ 0x062A, 0x062E, 0x064A, + /* 4551 */ 0x062A, 0x062E, 0x0649, + /* 4554 */ 0x062A, 0x0645, 0x064A, + /* 4557 */ 0x062A, 0x0645, 0x0649, + /* 4560 */ 0x062C, 0x0645, 0x064A, + /* 4563 */ 0x062C, 0x062D, 0x0649, + /* 4566 */ 0x062C, 0x0645, 0x0649, + /* 4569 */ 0x0633, 0x062E, 0x0649, + /* 4572 */ 0x0635, 0x062D, 0x064A, + /* 4575 */ 0x0634, 0x062D, 0x064A, + /* 4578 */ 0x0636, 0x062D, 0x064A, + /* 4581 */ 0x0644, 0x062C, 0x064A, + /* 4584 */ 0x0644, 0x0645, 0x064A, + /* 4587 */ 0x064A, 0x062D, 0x064A, + /* 4590 */ 0x064A, 0x062C, 0x064A, + /* 4593 */ 0x064A, 0x0645, 0x064A, + /* 4596 */ 0x0645, 0x0645, 0x064A, + /* 4599 */ 0x0642, 0x0645, 0x064A, + /* 4602 */ 0x0646, 0x062D, 0x064A, + /* 4605 */ 0x0642, 0x0645, 0x062D, + /* 4608 */ 0x0644, 0x062D, 0x0645, + /* 4611 */ 0x0639, 0x0645, 0x064A, + /* 4614 */ 0x0643, 0x0645, 0x064A, + /* 4617 */ 0x0646, 0x062C, 0x062D, + /* 4620 */ 0x0645, 0x062E, 0x064A, + /* 4623 */ 0x0644, 0x062C, 0x0645, + /* 4626 */ 0x0643, 0x0645, 0x0645, + /* 4629 */ 0x0644, 0x062C, 0x0645, + /* 4632 */ 0x0646, 0x062C, 0x062D, + /* 4635 */ 0x062C, 0x062D, 0x064A, + /* 4638 */ 0x062D, 0x062C, 0x064A, + /* 4641 */ 0x0645, 0x062C, 0x064A, + /* 4644 */ 0x0641, 0x0645, 0x064A, + /* 4647 */ 0x0628, 0x062D, 0x064A, + /* 4650 */ 0x0643, 0x0645, 0x0645, + /* 4653 */ 0x0639, 0x062C, 0x0645, + /* 4656 */ 0x0635, 0x0645, 0x0645, + /* 4659 */ 0x0633, 0x062E, 0x064A, + /* 4662 */ 0x0646, 0x062C, 0x064A, + /* 4665 */ 0x0635, 0x0644, 0x06D2, + /* 4668 */ 0x0642, 0x0644, 0x06D2, + /* 4671 */ 0x0627, 0x0644, 0x0644, 0x0647, + /* 4675 */ 0x0627, 0x0643, 0x0628, 0x0631, + /* 4679 */ 0x0645, 0x062D, 0x0645, 0x062F, + /* 4683 */ 0x0635, 0x0644, 0x0639, 0x0645, + /* 4687 */ 0x0631, 0x0633, 0x0648, 0x0644, + /* 4691 */ 0x0639, 0x0644, 0x064A, 0x0647, + /* 4695 */ 0x0648, 0x0633, 0x0644, 0x0645, + /* 4699 */ 0x0635, 0x0644, 0x0649, + /* 4702 */ 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, + /* 4720 */ 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, + /* 4728 */ 0x0631, 0x06CC, 0x0627, 0x0644, + /* 4732 */ 0x0020, 0x064B, + /* 4734 */ 0x0640, 0x064B, + /* 4736 */ 0x0020, 0x064C, + /* 4738 */ 0x0020, 0x064D, + /* 4740 */ 0x0020, 0x064E, + /* 4742 */ 0x0640, 0x064E, + /* 4744 */ 0x0020, 0x064F, + /* 4746 */ 0x0640, 0x064F, + /* 4748 */ 0x0020, 0x0650, + /* 4750 */ 0x0640, 0x0650, + /* 4752 */ 0x0020, 0x0651, + /* 4754 */ 0x0640, 0x0651, + /* 4756 */ 0x0020, 0x0652, + /* 4758 */ 0x0640, 0x0652, /* 4760 */ 0x0644, 0x0622, - /* 4762 */ 0x0644, 0x0623, + /* 4762 */ 0x0644, 0x0622, /* 4764 */ 0x0644, 0x0623, - /* 4766 */ 0x0644, 0x0625, + /* 4766 */ 0x0644, 0x0623, /* 4768 */ 0x0644, 0x0625, - /* 4770 */ 0x0644, 0x0627, + /* 4770 */ 0x0644, 0x0625, /* 4772 */ 0x0644, 0x0627, - /* 4774 */ 0x11099, 0x110BA, - /* 4776 */ 0x1109B, 0x110BA, - /* 4778 */ 0x110A5, 0x110BA, - /* 4780 */ 0x11131, 0x11127, - /* 4782 */ 0x11132, 0x11127, - /* 4784 */ 0x11347, 0x1133E, - /* 4786 */ 0x11347, 0x11357, - /* 4788 */ 0x114B9, 0x114BA, - /* 4790 */ 0x114B9, 0x114B0, - /* 4792 */ 0x114B9, 0x114BD, - /* 4794 */ 0x115B8, 0x115AF, - /* 4796 */ 0x115B9, 0x115AF, - /* 4798 */ 0x1D157, 0x1D165, - /* 4800 */ 0x1D158, 0x1D165, - /* 4802 */ 0x1D15F, 0x1D16E, - /* 4804 */ 0x1D15F, 0x1D16F, - /* 4806 */ 0x1D15F, 0x1D170, - /* 4808 */ 0x1D15F, 0x1D171, - /* 4810 */ 0x1D15F, 0x1D172, - /* 4812 */ 0x1D1B9, 0x1D165, - /* 4814 */ 0x1D1BA, 0x1D165, - /* 4816 */ 0x1D1BB, 0x1D16E, - /* 4818 */ 0x1D1BC, 0x1D16E, - /* 4820 */ 0x1D1BB, 0x1D16F, - /* 4822 */ 0x1D1BC, 0x1D16F, - /* 4824 */ 0x0030, 0x002E, - /* 4826 */ 0x0030, 0x002C, - /* 4828 */ 0x0031, 0x002C, - /* 4830 */ 0x0032, 0x002C, - /* 4832 */ 0x0033, 0x002C, - /* 4834 */ 0x0034, 0x002C, - /* 4836 */ 0x0035, 0x002C, - /* 4838 */ 0x0036, 0x002C, - /* 4840 */ 0x0037, 0x002C, - /* 4842 */ 0x0038, 0x002C, - /* 4844 */ 0x0039, 0x002C, - /* 4846 */ 0x0028, 0x0041, 0x0029, - /* 4849 */ 0x0028, 0x0042, 0x0029, - /* 4852 */ 0x0028, 0x0043, 0x0029, - /* 4855 */ 0x0028, 0x0044, 0x0029, - /* 4858 */ 0x0028, 0x0045, 0x0029, - /* 4861 */ 0x0028, 0x0046, 0x0029, - /* 4864 */ 0x0028, 0x0047, 0x0029, - /* 4867 */ 0x0028, 0x0048, 0x0029, - /* 4870 */ 0x0028, 0x0049, 0x0029, - /* 4873 */ 0x0028, 0x004A, 0x0029, - /* 4876 */ 0x0028, 0x004B, 0x0029, - /* 4879 */ 0x0028, 0x004C, 0x0029, - /* 4882 */ 0x0028, 0x004D, 0x0029, - /* 4885 */ 0x0028, 0x004E, 0x0029, - /* 4888 */ 0x0028, 0x004F, 0x0029, - /* 4891 */ 0x0028, 0x0050, 0x0029, - /* 4894 */ 0x0028, 0x0051, 0x0029, - /* 4897 */ 0x0028, 0x0052, 0x0029, - /* 4900 */ 0x0028, 0x0053, 0x0029, - /* 4903 */ 0x0028, 0x0054, 0x0029, - /* 4906 */ 0x0028, 0x0055, 0x0029, - /* 4909 */ 0x0028, 0x0056, 0x0029, - /* 4912 */ 0x0028, 0x0057, 0x0029, - /* 4915 */ 0x0028, 0x0058, 0x0029, - /* 4918 */ 0x0028, 0x0059, 0x0029, - /* 4921 */ 0x0028, 0x005A, 0x0029, - /* 4924 */ 0x3014, 0x0053, 0x3015, - /* 4927 */ 0x0043, 0x0044, - /* 4929 */ 0x0057, 0x005A, - /* 4931 */ 0x0048, 0x0056, - /* 4933 */ 0x004D, 0x0056, - /* 4935 */ 0x0053, 0x0044, - /* 4937 */ 0x0053, 0x0053, - /* 4939 */ 0x0050, 0x0050, 0x0056, - /* 4942 */ 0x0057, 0x0043, - /* 4944 */ 0x004D, 0x0043, - /* 4946 */ 0x004D, 0x0044, - /* 4948 */ 0x0044, 0x004A, - /* 4950 */ 0x307B, 0x304B, - /* 4952 */ 0x30B3, 0x30B3, - /* 4954 */ 0x3014, 0x672C, 0x3015, - /* 4957 */ 0x3014, 0x4E09, 0x3015, - /* 4960 */ 0x3014, 0x4E8C, 0x3015, - /* 4963 */ 0x3014, 0x5B89, 0x3015, - /* 4966 */ 0x3014, 0x70B9, 0x3015, - /* 4969 */ 0x3014, 0x6253, 0x3015, - /* 4972 */ 0x3014, 0x76D7, 0x3015, - /* 4975 */ 0x3014, 0x52DD, 0x3015, - /* 4978 */ 0x3014, 0x6557, 0x3015, - /* 4981 */ 0x20122, - /* 4982 */ 0x2063A, - /* 4983 */ 0x2051C, - /* 4984 */ 0x2054B, - /* 4985 */ 0x291DF, - /* 4986 */ 0x20A2C, - /* 4987 */ 0x20B63, - /* 4988 */ 0x214E4, - /* 4989 */ 0x216A8, - /* 4990 */ 0x216EA, - /* 4991 */ 0x219C8, - /* 4992 */ 0x21B18, - /* 4993 */ 0x21DE4, - /* 4994 */ 0x21DE6, - /* 4995 */ 0x22183, - /* 4996 */ 0x2A392, - /* 4997 */ 0x22331, - /* 4998 */ 0x22331, - /* 4999 */ 0x232B8, - /* 5000 */ 0x261DA, - /* 5001 */ 0x226D4, - /* 5002 */ 0x22B0C, - /* 5003 */ 0x22BF1, - /* 5004 */ 0x2300A, - /* 5005 */ 0x233C3, - /* 5006 */ 0x2346D, - /* 5007 */ 0x236A3, - /* 5008 */ 0x238A7, - /* 5009 */ 0x23A8D, - /* 5010 */ 0x21D0B, - /* 5011 */ 0x23AFA, - /* 5012 */ 0x23CBC, - /* 5013 */ 0x23D1E, - /* 5014 */ 0x23ED1, - /* 5015 */ 0x23F5E, - /* 5016 */ 0x23F8E, - /* 5017 */ 0x20525, - /* 5018 */ 0x24263, - /* 5019 */ 0x243AB, - /* 5020 */ 0x24608, - /* 5021 */ 0x24735, - /* 5022 */ 0x24814, - /* 5023 */ 0x24C36, - /* 5024 */ 0x24C92, - /* 5025 */ 0x2219F, - /* 5026 */ 0x24FA1, - /* 5027 */ 0x24FB8, - /* 5028 */ 0x25044, - /* 5029 */ 0x250F3, - /* 5030 */ 0x250F2, - /* 5031 */ 0x25119, - /* 5032 */ 0x25133, - /* 5033 */ 0x2541D, - /* 5034 */ 0x25626, - /* 5035 */ 0x2569A, - /* 5036 */ 0x256C5, - /* 5037 */ 0x2597C, - /* 5038 */ 0x25AA7, - /* 5039 */ 0x25AA7, - /* 5040 */ 0x25BAB, - /* 5041 */ 0x25C80, - /* 5042 */ 0x25F86, - /* 5043 */ 0x26228, - /* 5044 */ 0x26247, - /* 5045 */ 0x262D9, - /* 5046 */ 0x2633E, - /* 5047 */ 0x264DA, - /* 5048 */ 0x26523, - /* 5049 */ 0x265A8, - /* 5050 */ 0x2335F, - /* 5051 */ 0x267A7, - /* 5052 */ 0x267B5, - /* 5053 */ 0x23393, - /* 5054 */ 0x2339C, - /* 5055 */ 0x26B3C, - /* 5056 */ 0x26C36, - /* 5057 */ 0x26D6B, - /* 5058 */ 0x26CD5, - /* 5059 */ 0x273CA, - /* 5060 */ 0x26F2C, - /* 5061 */ 0x26FB1, - /* 5062 */ 0x270D2, - /* 5063 */ 0x27667, - /* 5064 */ 0x278AE, - /* 5065 */ 0x27966, - /* 5066 */ 0x27CA8, - /* 5067 */ 0x27F2F, - /* 5068 */ 0x20804, - /* 5069 */ 0x208DE, - /* 5070 */ 0x285D2, - /* 5071 */ 0x285ED, - /* 5072 */ 0x2872E, - /* 5073 */ 0x28BFA, - /* 5074 */ 0x28D77, - /* 5075 */ 0x29145, - /* 5076 */ 0x2921A, - /* 5077 */ 0x2940A, - /* 5078 */ 0x29496, - /* 5079 */ 0x295B6, - /* 5080 */ 0x29B30, - /* 5081 */ 0x2A0CE, - /* 5082 */ 0x2A105, - /* 5083 */ 0x2A20E, - /* 5084 */ 0x2A291, - /* 5085 */ 0x2A600 + /* 4774 */ 0x0644, 0x0627, + /* 4776 */ 0x11099, 0x110BA, + /* 4778 */ 0x1109B, 0x110BA, + /* 4780 */ 0x110A5, 0x110BA, + /* 4782 */ 0x11131, 0x11127, + /* 4784 */ 0x11132, 0x11127, + /* 4786 */ 0x11347, 0x1133E, + /* 4788 */ 0x11347, 0x11357, + /* 4790 */ 0x114B9, 0x114BA, + /* 4792 */ 0x114B9, 0x114B0, + /* 4794 */ 0x114B9, 0x114BD, + /* 4796 */ 0x115B8, 0x115AF, + /* 4798 */ 0x115B9, 0x115AF, + /* 4800 */ 0x1D157, 0x1D165, + /* 4802 */ 0x1D158, 0x1D165, + /* 4804 */ 0x1D15F, 0x1D16E, + /* 4806 */ 0x1D15F, 0x1D16F, + /* 4808 */ 0x1D15F, 0x1D170, + /* 4810 */ 0x1D15F, 0x1D171, + /* 4812 */ 0x1D15F, 0x1D172, + /* 4814 */ 0x1D1B9, 0x1D165, + /* 4816 */ 0x1D1BA, 0x1D165, + /* 4818 */ 0x1D1BB, 0x1D16E, + /* 4820 */ 0x1D1BC, 0x1D16E, + /* 4822 */ 0x1D1BB, 0x1D16F, + /* 4824 */ 0x1D1BC, 0x1D16F, + /* 4826 */ 0x0030, 0x002E, + /* 4828 */ 0x0030, 0x002C, + /* 4830 */ 0x0031, 0x002C, + /* 4832 */ 0x0032, 0x002C, + /* 4834 */ 0x0033, 0x002C, + /* 4836 */ 0x0034, 0x002C, + /* 4838 */ 0x0035, 0x002C, + /* 4840 */ 0x0036, 0x002C, + /* 4842 */ 0x0037, 0x002C, + /* 4844 */ 0x0038, 0x002C, + /* 4846 */ 0x0039, 0x002C, + /* 4848 */ 0x0028, 0x0041, 0x0029, + /* 4851 */ 0x0028, 0x0042, 0x0029, + /* 4854 */ 0x0028, 0x0043, 0x0029, + /* 4857 */ 0x0028, 0x0044, 0x0029, + /* 4860 */ 0x0028, 0x0045, 0x0029, + /* 4863 */ 0x0028, 0x0046, 0x0029, + /* 4866 */ 0x0028, 0x0047, 0x0029, + /* 4869 */ 0x0028, 0x0048, 0x0029, + /* 4872 */ 0x0028, 0x0049, 0x0029, + /* 4875 */ 0x0028, 0x004A, 0x0029, + /* 4878 */ 0x0028, 0x004B, 0x0029, + /* 4881 */ 0x0028, 0x004C, 0x0029, + /* 4884 */ 0x0028, 0x004D, 0x0029, + /* 4887 */ 0x0028, 0x004E, 0x0029, + /* 4890 */ 0x0028, 0x004F, 0x0029, + /* 4893 */ 0x0028, 0x0050, 0x0029, + /* 4896 */ 0x0028, 0x0051, 0x0029, + /* 4899 */ 0x0028, 0x0052, 0x0029, + /* 4902 */ 0x0028, 0x0053, 0x0029, + /* 4905 */ 0x0028, 0x0054, 0x0029, + /* 4908 */ 0x0028, 0x0055, 0x0029, + /* 4911 */ 0x0028, 0x0056, 0x0029, + /* 4914 */ 0x0028, 0x0057, 0x0029, + /* 4917 */ 0x0028, 0x0058, 0x0029, + /* 4920 */ 0x0028, 0x0059, 0x0029, + /* 4923 */ 0x0028, 0x005A, 0x0029, + /* 4926 */ 0x3014, 0x0053, 0x3015, + /* 4929 */ 0x0043, 0x0044, + /* 4931 */ 0x0057, 0x005A, + /* 4933 */ 0x0048, 0x0056, + /* 4935 */ 0x004D, 0x0056, + /* 4937 */ 0x0053, 0x0044, + /* 4939 */ 0x0053, 0x0053, + /* 4941 */ 0x0050, 0x0050, 0x0056, + /* 4944 */ 0x0057, 0x0043, + /* 4946 */ 0x004D, 0x0043, + /* 4948 */ 0x004D, 0x0044, + /* 4950 */ 0x004D, 0x0052, + /* 4952 */ 0x0044, 0x004A, + /* 4954 */ 0x307B, 0x304B, + /* 4956 */ 0x30B3, 0x30B3, + /* 4958 */ 0x3014, 0x672C, 0x3015, + /* 4961 */ 0x3014, 0x4E09, 0x3015, + /* 4964 */ 0x3014, 0x4E8C, 0x3015, + /* 4967 */ 0x3014, 0x5B89, 0x3015, + /* 4970 */ 0x3014, 0x70B9, 0x3015, + /* 4973 */ 0x3014, 0x6253, 0x3015, + /* 4976 */ 0x3014, 0x76D7, 0x3015, + /* 4979 */ 0x3014, 0x52DD, 0x3015, + /* 4982 */ 0x3014, 0x6557, 0x3015, + /* 4985 */ 0x20122, + /* 4986 */ 0x2063A, + /* 4987 */ 0x2051C, + /* 4988 */ 0x2054B, + /* 4989 */ 0x291DF, + /* 4990 */ 0x20A2C, + /* 4991 */ 0x20B63, + /* 4992 */ 0x214E4, + /* 4993 */ 0x216A8, + /* 4994 */ 0x216EA, + /* 4995 */ 0x219C8, + /* 4996 */ 0x21B18, + /* 4997 */ 0x21DE4, + /* 4998 */ 0x21DE6, + /* 4999 */ 0x22183, + /* 5000 */ 0x2A392, + /* 5001 */ 0x22331, + /* 5002 */ 0x22331, + /* 5003 */ 0x232B8, + /* 5004 */ 0x261DA, + /* 5005 */ 0x226D4, + /* 5006 */ 0x22B0C, + /* 5007 */ 0x22BF1, + /* 5008 */ 0x2300A, + /* 5009 */ 0x233C3, + /* 5010 */ 0x2346D, + /* 5011 */ 0x236A3, + /* 5012 */ 0x238A7, + /* 5013 */ 0x23A8D, + /* 5014 */ 0x21D0B, + /* 5015 */ 0x23AFA, + /* 5016 */ 0x23CBC, + /* 5017 */ 0x23D1E, + /* 5018 */ 0x23ED1, + /* 5019 */ 0x23F5E, + /* 5020 */ 0x23F8E, + /* 5021 */ 0x20525, + /* 5022 */ 0x24263, + /* 5023 */ 0x243AB, + /* 5024 */ 0x24608, + /* 5025 */ 0x24735, + /* 5026 */ 0x24814, + /* 5027 */ 0x24C36, + /* 5028 */ 0x24C92, + /* 5029 */ 0x2219F, + /* 5030 */ 0x24FA1, + /* 5031 */ 0x24FB8, + /* 5032 */ 0x25044, + /* 5033 */ 0x250F3, + /* 5034 */ 0x250F2, + /* 5035 */ 0x25119, + /* 5036 */ 0x25133, + /* 5037 */ 0x2541D, + /* 5038 */ 0x25626, + /* 5039 */ 0x2569A, + /* 5040 */ 0x256C5, + /* 5041 */ 0x2597C, + /* 5042 */ 0x25AA7, + /* 5043 */ 0x25AA7, + /* 5044 */ 0x25BAB, + /* 5045 */ 0x25C80, + /* 5046 */ 0x25F86, + /* 5047 */ 0x26228, + /* 5048 */ 0x26247, + /* 5049 */ 0x262D9, + /* 5050 */ 0x2633E, + /* 5051 */ 0x264DA, + /* 5052 */ 0x26523, + /* 5053 */ 0x265A8, + /* 5054 */ 0x2335F, + /* 5055 */ 0x267A7, + /* 5056 */ 0x267B5, + /* 5057 */ 0x23393, + /* 5058 */ 0x2339C, + /* 5059 */ 0x26B3C, + /* 5060 */ 0x26C36, + /* 5061 */ 0x26D6B, + /* 5062 */ 0x26CD5, + /* 5063 */ 0x273CA, + /* 5064 */ 0x26F2C, + /* 5065 */ 0x26FB1, + /* 5066 */ 0x270D2, + /* 5067 */ 0x27667, + /* 5068 */ 0x278AE, + /* 5069 */ 0x27966, + /* 5070 */ 0x27CA8, + /* 5071 */ 0x27F2F, + /* 5072 */ 0x20804, + /* 5073 */ 0x208DE, + /* 5074 */ 0x285D2, + /* 5075 */ 0x285ED, + /* 5076 */ 0x2872E, + /* 5077 */ 0x28BFA, + /* 5078 */ 0x28D77, + /* 5079 */ 0x29145, + /* 5080 */ 0x2921A, + /* 5081 */ 0x2940A, + /* 5082 */ 0x29496, + /* 5083 */ 0x295B6, + /* 5084 */ 0x29B30, + /* 5085 */ 0x2A0CE, + /* 5086 */ 0x2A105, + /* 5087 */ 0x2A20E, + /* 5088 */ 0x2A291, + /* 5089 */ 0x2A600 }; diff --git a/src/include/common/username.h b/src/include/common/username.h index 1bb3496f9e3..ecc5ad4207b 100644 --- a/src/include/common/username.h +++ b/src/include/common/username.h @@ -2,7 +2,7 @@ * username.h * lookup effective username * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/common/username.h */ diff --git a/src/include/datatype/timestamp.h b/src/include/datatype/timestamp.h index f5b6026ef5b..2b506827cb2 100644 --- a/src/include/datatype/timestamp.h +++ b/src/include/datatype/timestamp.h @@ -5,7 +5,7 @@ * * Note: this file must be includable in both frontend and backend contexts. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/datatype/timestamp.h diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h index f4617a28fa2..d21dbead0a2 100644 --- a/src/include/executor/execExpr.h +++ b/src/include/executor/execExpr.h @@ -4,7 +4,7 @@ * Low level infrastructure related to expression evaluation * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/execExpr.h @@ -19,7 +19,7 @@ /* forward references to avoid circularity */ struct ExprEvalStep; -struct ArrayRefState; +struct SubscriptingRefState; /* Bits in ExprState->flags (see also execnodes.h for public flag bits): */ /* expression's interpreter has been initialized */ @@ -185,21 +185,21 @@ typedef enum ExprEvalOp */ EEOP_FIELDSTORE_FORM, - /* Process an array subscript; short-circuit expression to NULL if NULL */ - EEOP_ARRAYREF_SUBSCRIPT, + /* Process a container subscript; short-circuit expression to NULL if NULL */ + EEOP_SBSREF_SUBSCRIPT, /* - * Compute old array element/slice when an ArrayRef assignment expression - * contains ArrayRef/FieldStore subexpressions. Value is accessed using - * the CaseTest mechanism. + * Compute old container element/slice when a SubscriptingRef assignment + * expression contains SubscriptingRef/FieldStore subexpressions. Value is + * accessed using the CaseTest mechanism. */ - EEOP_ARRAYREF_OLD, + EEOP_SBSREF_OLD, - /* compute new value for ArrayRef assignment expression */ - EEOP_ARRAYREF_ASSIGN, + /* compute new value for SubscriptingRef assignment expression */ + EEOP_SBSREF_ASSIGN, - /* compute element/slice for ArrayRef fetch expression */ - EEOP_ARRAYREF_FETCH, + /* compute element/slice for SubscriptingRef fetch expression */ + EEOP_SBSREF_FETCH, /* evaluate value for CoerceToDomainValue */ EEOP_DOMAIN_TESTVAL, @@ -223,7 +223,8 @@ typedef enum ExprEvalOp /* aggregation related nodes */ EEOP_AGG_STRICT_DESERIALIZE, EEOP_AGG_DESERIALIZE, - EEOP_AGG_STRICT_INPUT_CHECK, + EEOP_AGG_STRICT_INPUT_CHECK_ARGS, + EEOP_AGG_STRICT_INPUT_CHECK_NULLS, EEOP_AGG_INIT_TRANS, EEOP_AGG_STRICT_TRANS_CHECK, EEOP_AGG_PLAIN_TRANS_BYVAL, @@ -262,7 +263,12 @@ typedef struct ExprEvalStep { /* attribute number up to which to fetch (inclusive) */ int last_var; + /* will the type of slot be the same for every invocation */ + bool fixed; + /* tuple descriptor, if known */ TupleDesc known_desc; + /* type of slot, can only be relied upon if fixed is set */ + const TupleTableSlotOps *kind; } fetch; /* for EEOP_INNER/OUTER/SCAN_[SYS]VAR[_FIRST] */ @@ -486,22 +492,22 @@ typedef struct ExprEvalStep int ncolumns; } fieldstore; - /* for EEOP_ARRAYREF_SUBSCRIPT */ + /* for EEOP_SBSREF_SUBSCRIPT */ struct { /* too big to have inline */ - struct ArrayRefState *state; + struct SubscriptingRefState *state; int off; /* 0-based index of this subscript */ bool isupper; /* is it upper or lower subscript? */ int jumpdone; /* jump here on null */ - } arrayref_subscript; + } sbsref_subscript; - /* for EEOP_ARRAYREF_OLD / ASSIGN / FETCH */ + /* for EEOP_SBSREF_OLD / ASSIGN / FETCH */ struct { /* too big to have inline */ - struct ArrayRefState *state; - } arrayref; + struct SubscriptingRefState *state; + } sbsref; /* for EEOP_DOMAIN_NOTNULL / DOMAIN_CHECK */ struct @@ -570,7 +576,7 @@ typedef struct ExprEvalStep /* for EEOP_WINDOW_FUNC */ struct { - /* out-of-line state, modified by nodeWindowFunc.c */ + /* out-of-line state, modified by nodeWindowAgg.c */ WindowFuncExprState *wfstate; } window_func; @@ -596,9 +602,21 @@ typedef struct ExprEvalStep int jumpnull; } agg_deserialize; - /* for EEOP_AGG_STRICT_INPUT_CHECK */ - struct - { + /* for EEOP_AGG_STRICT_INPUT_CHECK_NULLS / STRICT_INPUT_CHECK_ARGS */ + struct + { + /* + * For EEOP_AGG_STRICT_INPUT_CHECK_ARGS args contains pointers to + * the NullableDatums that need to be checked for NULLs. + * + * For EEOP_AGG_STRICT_INPUT_CHECK_NULLS nulls contains pointers + * to booleans that need to be checked for NULLs. + * + * Both cases currently need to exist because sometimes the + * to-be-checked nulls are in TupleTableSlot.isnull array, and + * sometimes in FunctionCallInfoBaseData.args[i].isnull. + */ + NullableDatum *args; bool *nulls; int nargs; int jumpnull; @@ -640,14 +658,14 @@ typedef struct ExprEvalStep } ExprEvalStep; -/* Non-inline data for array operations */ -typedef struct ArrayRefState +/* Non-inline data for container operations */ +typedef struct SubscriptingRefState { bool isassignment; /* is it assignment, or just fetch? */ - Oid refelemtype; /* OID of the array element type */ - int16 refattrlength; /* typlen of array type */ - int16 refelemlength; /* typlen of the array element type */ + Oid refelemtype; /* OID of the container element type */ + int16 refattrlength; /* typlen of container type */ + int16 refelemlength; /* typlen of the container element type */ bool refelembyval; /* is the element type pass-by-value? */ char refelemalign; /* typalign of the element type */ @@ -670,10 +688,10 @@ typedef struct ArrayRefState Datum replacevalue; bool replacenull; - /* if we have a nested assignment, ARRAYREF_OLD puts old value here */ + /* if we have a nested assignment, SBSREF_OLD puts old value here */ Datum prevvalue; bool prevnull; -} ArrayRefState; +} SubscriptingRefState; /* functions in execExpr.c */ @@ -692,57 +710,58 @@ extern void CheckExprStillValid(ExprState *state, ExprContext *econtext); * expression evaluation, reducing code duplication. */ extern void ExecEvalFuncExprFusage(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalFuncExprStrictFusage(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalParamExec(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); -extern void ExecEvalParamExecParams(Bitmapset *params, EState *estate); + ExprContext *econtext); extern void ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op); extern void ExecEvalCurrentOfExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalNextValueExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalRowNull(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalRowNotNull(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalArrayCoerce(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalRow(ExprState *state, ExprEvalStep *op); extern void ExecEvalMinMax(ExprState *state, ExprEvalStep *op); extern void ExecEvalFieldSelect(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalFieldStoreDeForm(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalFieldStoreForm(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); -extern bool ExecEvalArrayRefSubscript(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefFetch(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefOld(ExprState *state, ExprEvalStep *op); -extern void ExecEvalArrayRefAssign(ExprState *state, ExprEvalStep *op); + ExprContext *econtext); +extern bool ExecEvalSubscriptingRef(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefFetch(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefOld(ExprState *state, ExprEvalStep *op); +extern void ExecEvalSubscriptingRefAssign(ExprState *state, ExprEvalStep *op); extern void ExecEvalConvertRowtype(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalScalarArrayOp(ExprState *state, ExprEvalStep *op); extern void ExecEvalConstraintNotNull(ExprState *state, ExprEvalStep *op); extern void ExecEvalConstraintCheck(ExprState *state, ExprEvalStep *op); extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op); extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op); extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); +extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op, + ExprContext *econtext, TupleTableSlot *slot); extern void ExecAggInitGroup(AggState *aggstate, AggStatePerTrans pertrans, AggStatePerGroup pergroup); extern Datum ExecAggTransReparent(AggState *aggstate, AggStatePerTrans pertrans, - Datum newValue, bool newValueIsNull, - Datum oldValue, bool oldValueIsNull); + Datum newValue, bool newValueIsNull, + Datum oldValue, bool oldValueIsNull); extern void ExecEvalAggOrderedTransDatum(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); extern void ExecEvalAggOrderedTransTuple(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); #endif /* EXEC_EXPR_H */ diff --git a/src/include/executor/execMerge.h b/src/include/executor/execMerge.h deleted file mode 100644 index 5ea8c4e50a8..00000000000 --- a/src/include/executor/execMerge.h +++ /dev/null @@ -1,31 +0,0 @@ -/*------------------------------------------------------------------------- - * - * execMerge.h - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/executor/execMerge.h - * - *------------------------------------------------------------------------- - */ -#ifndef EXECMERGE_H -#define EXECMERGE_H - -#include "nodes/execnodes.h" - -/* flags for mt_merge_subcommands */ -#define MERGE_INSERT 0x01 -#define MERGE_UPDATE 0x02 -#define MERGE_DELETE 0x04 - -extern void ExecMerge(ModifyTableState *mtstate, EState *estate, - TupleTableSlot *slot, JunkFilter *junkfilter, - ResultRelInfo *resultRelInfo); - -extern void ExecInitMerge(ModifyTableState *mtstate, - EState *estate, - ResultRelInfo *resultRelInfo); - -#endif /* NODEMERGE_H */ diff --git a/src/include/executor/execParallel.h b/src/include/executor/execParallel.h index 626a66c27a0..46fcf899927 100644 --- a/src/include/executor/execParallel.h +++ b/src/include/executor/execParallel.h @@ -2,7 +2,7 @@ * execParallel.h * POSTGRES parallel execution interface * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -27,6 +27,7 @@ typedef struct ParallelExecutorInfo ParallelContext *pcxt; /* parallel context we're using */ BufferUsage *buffer_usage; /* points to bufusage area in DSM */ SharedExecutorInstrumentation *instrumentation; /* optional */ + struct SharedJitInstrumentation *jit_instrumentation; /* optional */ dsa_area *area; /* points to DSA area in DSM */ dsa_pointer param_exec; /* serialized PARAM_EXEC parameters */ bool finished; /* set true by ExecParallelFinish */ @@ -36,13 +37,13 @@ typedef struct ParallelExecutorInfo } ParallelExecutorInfo; extern ParallelExecutorInfo *ExecInitParallelPlan(PlanState *planstate, - EState *estate, Bitmapset *sendParam, int nworkers, - int64 tuples_needed); + EState *estate, Bitmapset *sendParam, int nworkers, + int64 tuples_needed); extern void ExecParallelCreateReaders(ParallelExecutorInfo *pei); extern void ExecParallelFinish(ParallelExecutorInfo *pei); extern void ExecParallelCleanup(ParallelExecutorInfo *pei); extern void ExecParallelReinitialize(PlanState *planstate, - ParallelExecutorInfo *pei, Bitmapset *sendParam); + ParallelExecutorInfo *pei, Bitmapset *sendParam); extern void ParallelQueryMain(dsm_segment *seg, shm_toc *toc); diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h index b2daf24c41d..580734e9c96 100644 --- a/src/include/executor/execPartition.h +++ b/src/include/executor/execPartition.h @@ -2,7 +2,7 @@ * execPartition.h * POSTGRES partitioning executor interface * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -13,202 +13,144 @@ #ifndef EXECPARTITION_H #define EXECPARTITION_H -#include "catalog/partition.h" #include "nodes/execnodes.h" #include "nodes/parsenodes.h" #include "nodes/plannodes.h" #include "partitioning/partprune.h" -/*----------------------- - * PartitionDispatch - information about one partitioned table in a partition - * hierarchy required to route a tuple to one of its partitions +/* See execPartition.c for the definitions. */ +typedef struct PartitionDispatchData *PartitionDispatch; +typedef struct PartitionTupleRouting PartitionTupleRouting; + +/* + * PartitionRoutingInfo * - * reldesc Relation descriptor of the table - * key Partition key information of the table - * keystate Execution state required for expressions in the partition key - * partdesc Partition descriptor of the table - * tupslot A standalone TupleTableSlot initialized with this table's tuple - * descriptor - * tupmap TupleConversionMap to convert from the parent's rowtype to - * this table's rowtype (when extracting the partition key of a - * tuple just before routing it through this table) - * indexes Array with partdesc->nparts members (for details on what - * individual members represent, see how they are set in - * get_partition_dispatch_recurse()) - *----------------------- + * Additional result relation information specific to routing tuples to a + * table partition. */ -typedef struct PartitionDispatchData +typedef struct PartitionRoutingInfo { - Relation reldesc; - PartitionKey key; - List *keystate; /* list of ExprState */ - PartitionDesc partdesc; - TupleTableSlot *tupslot; - TupleConversionMap *tupmap; - int *indexes; -} PartitionDispatchData; + /* + * Map for converting tuples in root partitioned table format into + * partition format, or NULL if no conversion is required. + */ + TupleConversionMap *pi_RootToPartitionMap; -typedef struct PartitionDispatchData *PartitionDispatch; + /* + * Map for converting tuples in partition format into the root partitioned + * table format, or NULL if no conversion is required. + */ + TupleConversionMap *pi_PartitionToRootMap; + + /* + * Slot to store tuples in partition format, or NULL when no translation + * is required between root and partition. + */ + TupleTableSlot *pi_PartitionTupleSlot; +} PartitionRoutingInfo; -/*----------------------- - * PartitionTupleRouting - Encapsulates all information required to execute - * tuple-routing between partitions. +/* + * PartitionedRelPruningData - Per-partitioned-table data for run-time pruning + * of partitions. For a multilevel partitioned table, we have one of these + * for the topmost partition plus one for each non-leaf child partition. * - * partition_dispatch_info Array of PartitionDispatch objects with one - * entry for every partitioned table in the - * partition tree. - * num_dispatch number of partitioned tables in the partition - * tree (= length of partition_dispatch_info[]) - * partition_oids Array of leaf partitions OIDs with one entry - * for every leaf partition in the partition tree, - * initialized in full by - * ExecSetupPartitionTupleRouting. - * partitions Array of ResultRelInfo* objects with one entry - * for every leaf partition in the partition tree, - * initialized lazily by ExecInitPartitionInfo. - * num_partitions Number of leaf partitions in the partition tree - * (= 'partitions_oid'/'partitions' array length) - * parent_child_tupconv_maps Array of TupleConversionMap objects with one - * entry for every leaf partition (required to - * convert tuple from the root table's rowtype to - * a leaf partition's rowtype after tuple routing - * is done) - * child_parent_tupconv_maps Array of TupleConversionMap objects with one - * entry for every leaf partition (required to - * convert an updated tuple from the leaf - * partition's rowtype to the root table's rowtype - * so that tuple routing can be done) - * child_parent_map_not_required Array of bool. True value means that a map is - * determined to be not required for the given - * partition. False means either we haven't yet - * checked if a map is required, or it was - * determined to be required. - * subplan_partition_offsets Integer array ordered by UPDATE subplans. Each - * element of this array has the index into the - * corresponding partition in partitions array. - * num_subplan_partition_offsets Length of 'subplan_partition_offsets' array - * partition_tuple_slot TupleTableSlot to be used to manipulate any - * given leaf partition's rowtype after that - * partition is chosen for insertion by - * tuple-routing. - *----------------------- + * subplan_map[] and subpart_map[] have the same definitions as in + * PartitionedRelPruneInfo (see plannodes.h); though note that here, + * subpart_map contains indexes into PartitionPruningData.partrelprunedata[]. + * + * nparts Length of subplan_map[] and subpart_map[]. + * subplan_map Subplan index by partition index, or -1. + * subpart_map Subpart index by partition index, or -1. + * present_parts A Bitmapset of the partition indexes that we + * have subplans or subparts for. + * initial_pruning_steps List of PartitionPruneSteps used to + * perform executor startup pruning. + * exec_pruning_steps List of PartitionPruneSteps used to + * perform per-scan pruning. + * initial_context If initial_pruning_steps isn't NIL, contains + * the details needed to execute those steps. + * exec_context If exec_pruning_steps isn't NIL, contains + * the details needed to execute those steps. */ -typedef struct PartitionTupleRouting +typedef struct PartitionedRelPruningData { - PartitionDispatch *partition_dispatch_info; - int num_dispatch; - Oid *partition_oids; - ResultRelInfo **partitions; - int num_partitions; - TupleConversionMap **parent_child_tupconv_maps; - TupleConversionMap **child_parent_tupconv_maps; - bool *child_parent_map_not_required; - int *subplan_partition_offsets; - int num_subplan_partition_offsets; - TupleTableSlot *partition_tuple_slot; - TupleTableSlot *root_tuple_slot; -} PartitionTupleRouting; + int nparts; + int *subplan_map; + int *subpart_map; + Bitmapset *present_parts; + List *initial_pruning_steps; + List *exec_pruning_steps; + PartitionPruneContext initial_context; + PartitionPruneContext exec_context; +} PartitionedRelPruningData; -/*----------------------- - * PartitionPruningData - Encapsulates all information required to support - * elimination of partitions in node types which support arbitrary Lists of - * subplans. Information stored here allows the planner's partition pruning - * functions to be called and the return value of partition indexes translated - * into the subpath indexes of node types such as Append, thus allowing us to - * bypass certain subnodes when we have proofs that indicate that no tuple - * matching the 'pruning_steps' will be found within. - * - * subnode_map An array containing the subnode index which - * matches this partition index, or -1 if the - * subnode has been pruned already. - * subpart_map An array containing the offset into the - * 'partprunedata' array in PartitionPruning, or - * -1 if there is no such element in that array. - * present_parts A Bitmapset of the partition index that we have - * subnodes mapped for. - * context Contains the context details required to call - * the partition pruning code. - * pruning_steps Contains a list of PartitionPruneStep used to - * perform the actual pruning. - * extparams Contains paramids of external params found - * matching partition keys in 'pruning_steps'. - * allparams As 'extparams' but also including exec params. - *----------------------- +/* + * PartitionPruningData - Holds all the run-time pruning information for + * a single partitioning hierarchy containing one or more partitions. + * partrelprunedata[] is an array ordered such that parents appear before + * their children; in particular, the first entry is the topmost partition, + * which was actually named in the SQL query. */ typedef struct PartitionPruningData { - int *subnode_map; - int *subpart_map; - Bitmapset *present_parts; - PartitionPruneContext context; - List *pruning_steps; - Bitmapset *extparams; - Bitmapset *allparams; + int num_partrelprunedata; /* number of array entries */ + PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER]; } PartitionPruningData; -/*----------------------- - * PartitionPruneState - State object required for executor nodes to perform - * partition pruning elimination of their subnodes. This encapsulates a - * flattened hierarchy of PartitionPruningData structs and also stores all - * paramids which were found to match the partition keys of each partition. - * This struct can be attached to node types which support arbitrary Lists of - * subnodes containing partitions to allow subnodes to be eliminated due to - * the clauses being unable to match to any tuple that the subnode could +/* + * PartitionPruneState - State object required for plan nodes to perform + * run-time partition pruning. + * + * This struct can be attached to plan types which support arbitrary Lists of + * subplans containing partitions, to allow subplans to be eliminated due to + * the clauses being unable to match to any tuple that the subplan could * possibly produce. * - * partprunedata Array of PartitionPruningData for the node's target - * partitioned relation. First element contains the - * details for the target partitioned table. - * num_partprunedata Number of items in 'partprunedata' array. - * prune_context A memory context which can be used to call the query - * planner's partition prune functions. - * extparams All PARAM_EXTERN paramids which were found to match a - * partition key in each of the contained - * PartitionPruningData structs. - * execparams As above but for PARAM_EXEC. - * allparams Union of 'extparams' and 'execparams', saved to avoid - * recalculation. - *----------------------- + * execparamids Contains paramids of PARAM_EXEC Params found within + * any of the partprunedata structs. Pruning must be + * done again each time the value of one of these + * parameters changes. + * other_subplans Contains indexes of subplans that don't belong to any + * "partprunedata", e.g UNION ALL children that are not + * partitioned tables, or a partitioned table that the + * planner deemed run-time pruning to be useless for. + * These must not be pruned. + * prune_context A short-lived memory context in which to execute the + * partition pruning functions. + * do_initial_prune true if pruning should be performed during executor + * startup (at any hierarchy level). + * do_exec_prune true if pruning should be performed during + * executor run (at any hierarchy level). + * num_partprunedata Number of items in "partprunedata" array. + * partprunedata Array of PartitionPruningData pointers for the plan's + * partitioned relation(s), one for each partitioning + * hierarchy that requires run-time pruning. */ typedef struct PartitionPruneState { - PartitionPruningData *partprunedata; - int num_partprunedata; + Bitmapset *execparamids; + Bitmapset *other_subplans; MemoryContext prune_context; - Bitmapset *extparams; - Bitmapset *execparams; - Bitmapset *allparams; + bool do_initial_prune; + bool do_exec_prune; + int num_partprunedata; + PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER]; } PartitionPruneState; -extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(ModifyTableState *mtstate, - Relation rel); -extern int ExecFindPartition(ResultRelInfo *resultRelInfo, - PartitionDispatch *pd, - TupleTableSlot *slot, - EState *estate); -extern int ExecFindPartitionByOid(PartitionTupleRouting *proute, Oid partoid); -extern ResultRelInfo *ExecInitPartitionInfo(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo, - PartitionTupleRouting *proute, - EState *estate, int partidx); -extern void ExecInitRoutingInfo(ModifyTableState *mtstate, - EState *estate, - PartitionTupleRouting *proute, - ResultRelInfo *partRelInfo, - int partidx); -extern void ExecSetupChildParentMapForLeaf(PartitionTupleRouting *proute); -extern TupleConversionMap *TupConvMapForLeaf(PartitionTupleRouting *proute, - ResultRelInfo *rootRelInfo, int leaf_index); -extern HeapTuple ConvertPartitionTupleSlot(TupleConversionMap *map, - HeapTuple tuple, - TupleTableSlot *new_slot, - TupleTableSlot **p_my_slot); +extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(EState *estate, + ModifyTableState *mtstate, + Relation rel); +extern ResultRelInfo *ExecFindPartition(ModifyTableState *mtstate, + ResultRelInfo *rootResultRelInfo, + PartitionTupleRouting *proute, + TupleTableSlot *slot, + EState *estate); extern void ExecCleanupTupleRouting(ModifyTableState *mtstate, - PartitionTupleRouting *proute); -extern PartitionPruneState *ExecSetupPartitionPruneState(PlanState *planstate, - List *partitionpruneinfo); + PartitionTupleRouting *proute); +extern PartitionPruneState *ExecCreatePartitionPruneState(PlanState *planstate, + PartitionPruneInfo *partitionpruneinfo); extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate); extern Bitmapset *ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, - int nsubnodes); + int nsubplans); #endif /* EXECPARTITION_H */ diff --git a/src/include/executor/execdebug.h b/src/include/executor/execdebug.h index 236b2cc4fdf..c119fdf4fa0 100644 --- a/src/include/executor/execdebug.h +++ b/src/include/executor/execdebug.h @@ -7,7 +7,7 @@ * for debug printouts, because that's more flexible than printf(). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/execdebug.h diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h index 10e9ded246b..b88fa02d3b7 100644 --- a/src/include/executor/execdesc.h +++ b/src/include/executor/execdesc.h @@ -5,7 +5,7 @@ * and related modules. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/execdesc.h @@ -57,13 +57,13 @@ typedef struct QueryDesc /* in pquery.c */ extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt, - const char *sourceText, - Snapshot snapshot, - Snapshot crosscheck_snapshot, - DestReceiver *dest, - ParamListInfo params, - QueryEnvironment *queryEnv, - int instrument_options); + const char *sourceText, + Snapshot snapshot, + Snapshot crosscheck_snapshot, + DestReceiver *dest, + ParamListInfo params, + QueryEnvironment *queryEnv, + int instrument_options); extern void FreeQueryDesc(QueryDesc *qdesc); diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 45a077a949c..6298c7c8cad 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -4,7 +4,7 @@ * support for the POSTGRES executor module * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/executor.h @@ -14,8 +14,9 @@ #ifndef EXECUTOR_H #define EXECUTOR_H -#include "catalog/partition.h" #include "executor/execdesc.h" +#include "fmgr.h" +#include "nodes/lockoptions.h" #include "nodes/parsenodes.h" #include "utils/memutils.h" @@ -51,19 +52,13 @@ * AfterTriggerBeginQuery/AfterTriggerEndQuery. This does not necessarily * mean that the plan can't queue any AFTER triggers; just that the caller * is responsible for there being a trigger context for them to be queued in. - * - * WITH/WITHOUT_OIDS tell the executor to emit tuples with or without space - * for OIDs, respectively. These are currently used only for CREATE TABLE AS. - * If neither is set, the plan may or may not produce tuples including OIDs. */ #define EXEC_FLAG_EXPLAIN_ONLY 0x0001 /* EXPLAIN, no ANALYZE */ #define EXEC_FLAG_REWIND 0x0002 /* need efficient rescan */ #define EXEC_FLAG_BACKWARD 0x0004 /* need backward scan */ #define EXEC_FLAG_MARK 0x0008 /* need mark/restore */ #define EXEC_FLAG_SKIP_TRIGGERS 0x0010 /* skip AfterTrigger calls */ -#define EXEC_FLAG_WITH_OIDS 0x0020 /* force OIDs in returned tuples */ -#define EXEC_FLAG_WITHOUT_OIDS 0x0040 /* force no OIDs in returned tuples */ -#define EXEC_FLAG_WITH_NO_DATA 0x0080 /* rel scannability doesn't matter */ +#define EXEC_FLAG_WITH_NO_DATA 0x0020 /* rel scannability doesn't matter */ /* Hook for plugins to get control in ExecutorStart() */ @@ -93,7 +88,7 @@ extern PGDLLIMPORT ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook; /* * prototypes from functions in execAmi.c */ -struct Path; /* avoid including relation.h here */ +struct Path; /* avoid including pathnodes.h here */ extern void ExecReScan(PlanState *node); extern void ExecMarkPos(PlanState *node); @@ -106,54 +101,67 @@ extern bool ExecMaterializesOutput(NodeTag plantype); * prototypes from functions in execCurrent.c */ extern bool execCurrentOf(CurrentOfExpr *cexpr, - ExprContext *econtext, - Oid table_oid, - ItemPointer current_tid); + ExprContext *econtext, + Oid table_oid, + ItemPointer current_tid); /* * prototypes from functions in execGrouping.c */ extern ExprState *execTuplesMatchPrepare(TupleDesc desc, - int numCols, - AttrNumber *keyColIdx, - Oid *eqOperators, - PlanState *parent); + int numCols, + const AttrNumber *keyColIdx, + const Oid *eqOperators, + const Oid *collations, + PlanState *parent); extern void execTuplesHashPrepare(int numCols, - Oid *eqOperators, - Oid **eqFuncOids, - FmgrInfo **hashFunctions); + const Oid *eqOperators, + Oid **eqFuncOids, + FmgrInfo **hashFunctions); extern TupleHashTable BuildTupleHashTable(PlanState *parent, - TupleDesc inputDesc, - int numCols, AttrNumber *keyColIdx, - Oid *eqfuncoids, - FmgrInfo *hashfunctions, - long nbuckets, Size additionalsize, - MemoryContext tablecxt, - MemoryContext tempcxt, bool use_variable_hash_iv); + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext tablecxt, + MemoryContext tempcxt, bool use_variable_hash_iv); +extern TupleHashTable BuildTupleHashTableExt(PlanState *parent, + TupleDesc inputDesc, + int numCols, AttrNumber *keyColIdx, + const Oid *eqfuncoids, + FmgrInfo *hashfunctions, + Oid *collations, + long nbuckets, Size additionalsize, + MemoryContext metacxt, + MemoryContext tablecxt, + MemoryContext tempcxt, bool use_variable_hash_iv); extern TupleHashEntry LookupTupleHashEntry(TupleHashTable hashtable, - TupleTableSlot *slot, - bool *isnew); + TupleTableSlot *slot, + bool *isnew); extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable, - TupleTableSlot *slot, - ExprState *eqcomp, - FmgrInfo *hashfunctions); + TupleTableSlot *slot, + ExprState *eqcomp, + FmgrInfo *hashfunctions); +extern void ResetTupleHashTable(TupleHashTable hashtable); /* * prototypes from functions in execJunk.c */ -extern JunkFilter *ExecInitJunkFilter(List *targetList, bool hasoid, - TupleTableSlot *slot); +extern JunkFilter *ExecInitJunkFilter(List *targetList, + TupleTableSlot *slot); extern JunkFilter *ExecInitJunkFilterConversion(List *targetList, - TupleDesc cleanTupType, - TupleTableSlot *slot); + TupleDesc cleanTupType, + TupleTableSlot *slot); extern AttrNumber ExecFindJunkAttribute(JunkFilter *junkfilter, - const char *attrName); + const char *attrName); extern AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, - const char *attrName); + const char *attrName); extern Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, - bool *isNull); + bool *isNull); extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter, - TupleTableSlot *slot); + TupleTableSlot *slot); /* @@ -162,9 +170,9 @@ extern TupleTableSlot *ExecFilterJunk(JunkFilter *junkfilter, extern void ExecutorStart(QueryDesc *queryDesc, int eflags); extern void standard_ExecutorStart(QueryDesc *queryDesc, int eflags); extern void ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, uint64 count, bool execute_once); + ScanDirection direction, uint64 count, bool execute_once); extern void standard_ExecutorRun(QueryDesc *queryDesc, - ScanDirection direction, uint64 count, bool execute_once); + ScanDirection direction, uint64 count, bool execute_once); extern void ExecutorFinish(QueryDesc *queryDesc); extern void standard_ExecutorFinish(QueryDesc *queryDesc); extern void ExecutorEnd(QueryDesc *queryDesc); @@ -173,43 +181,36 @@ extern void ExecutorRewind(QueryDesc *queryDesc); extern bool ExecCheckRTPerms(List *rangeTable, bool ereport_on_violation); extern void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation); extern void InitResultRelInfo(ResultRelInfo *resultRelInfo, - Relation resultRelationDesc, - Index resultRelationIndex, - Relation partition_root, - int instrument_options); + Relation resultRelationDesc, + Index resultRelationIndex, + Relation partition_root, + int instrument_options); extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid); extern void ExecCleanUpTriggerState(EState *estate); -extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids); extern void ExecConstraints(ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, EState *estate, - bool check_partition_constraint); + TupleTableSlot *slot, EState *estate); extern bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, EState *estate); + TupleTableSlot *slot, EState *estate, bool emitError); extern void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, EState *estate); + TupleTableSlot *slot, EState *estate); extern void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, EState *estate); + TupleTableSlot *slot, EState *estate); extern LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo); extern ExecRowMark *ExecFindRowMark(EState *estate, Index rti, bool missing_ok); extern ExecAuxRowMark *ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist); -extern TupleTableSlot *EvalPlanQual(EState *estate, EPQState *epqstate, - Relation relation, Index rti, int lockmode, - ItemPointer tid, TransactionId priorXmax); -extern HeapTuple EvalPlanQualFetch(EState *estate, Relation relation, - int lockmode, LockWaitPolicy wait_policy, ItemPointer tid, - TransactionId priorXmax); -extern void EvalPlanQualInit(EPQState *epqstate, EState *estate, - Plan *subplan, List *auxrowmarks, int epqParam); +extern TupleTableSlot *EvalPlanQual(EPQState *epqstate, Relation relation, + Index rti, TupleTableSlot *testslot); +extern void EvalPlanQualInit(EPQState *epqstate, EState *parentestate, + Plan *subplan, List *auxrowmarks, int epqParam); extern void EvalPlanQualSetPlan(EPQState *epqstate, - Plan *subplan, List *auxrowmarks); -extern void EvalPlanQualSetTuple(EPQState *epqstate, Index rti, - HeapTuple tuple); -extern HeapTuple EvalPlanQualGetTuple(EPQState *epqstate, Index rti); + Plan *subplan, List *auxrowmarks); +extern TupleTableSlot *EvalPlanQualSlot(EPQState *epqstate, + Relation relation, Index rti); #define EvalPlanQualSetSlot(epqstate, slot) ((epqstate)->origslot = (slot)) -extern void EvalPlanQualFetchRowMarks(EPQState *epqstate); +extern bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot); extern TupleTableSlot *EvalPlanQualNext(EPQState *epqstate); -extern void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate); +extern void EvalPlanQualBegin(EPQState *epqstate); extern void EvalPlanQualEnd(EPQState *epqstate); /* @@ -249,17 +250,19 @@ extern ExprState *ExecInitQual(List *qual, PlanState *parent); extern ExprState *ExecInitCheck(List *qual, PlanState *parent); extern List *ExecInitExprList(List *nodes, PlanState *parent); extern ExprState *ExecBuildAggTrans(AggState *aggstate, struct AggStatePerPhaseData *phase, - bool doSort, bool doHash); + bool doSort, bool doHash); extern ExprState *ExecBuildGroupingEqual(TupleDesc ldesc, TupleDesc rdesc, - int numCols, - AttrNumber *keyColIdx, - Oid *eqfunctions, - PlanState *parent); + const TupleTableSlotOps *lops, const TupleTableSlotOps *rops, + int numCols, + const AttrNumber *keyColIdx, + const Oid *eqfunctions, + const Oid *collations, + PlanState *parent); extern ProjectionInfo *ExecBuildProjectionInfo(List *targetList, - ExprContext *econtext, - TupleTableSlot *slot, - PlanState *parent, - TupleDesc inputDesc); + ExprContext *econtext, + TupleTableSlot *slot, + PlanState *parent, + TupleDesc inputDesc); extern ExprState *ExecPrepareExpr(Expr *node, EState *estate); extern ExprState *ExecPrepareQual(List *qual, EState *estate); extern ExprState *ExecPrepareCheck(List *qual, EState *estate); @@ -312,7 +315,7 @@ ExecEvalExprSwitchContext(ExprState *state, * ExecProject * * Projects a tuple based on projection info and stores it in the slot passed - * to ExecBuildProjectInfo(). + * to ExecBuildProjectionInfo(). * * Note: the result is always a virtual tuple; therefore it may reference * the contents of the exprContext's scan tuples and/or temporary results @@ -342,7 +345,7 @@ ExecProject(ProjectionInfo *projInfo) * Successfully formed a result row. Mark the result slot as containing a * valid virtual tuple (inlined version of ExecStoreVirtualTuple()). */ - slot->tts_isempty = false; + slot->tts_flags &= ~TTS_FLAG_EMPTY; slot->tts_nvalid = slot->tts_tupleDescriptor->natts; return slot; @@ -402,19 +405,19 @@ extern bool ExecCheck(ExprState *state, ExprContext *context); * prototypes from functions in execSRF.c */ extern SetExprState *ExecInitTableFunctionResult(Expr *expr, - ExprContext *econtext, PlanState *parent); + ExprContext *econtext, PlanState *parent); extern Tuplestorestate *ExecMakeTableFunctionResult(SetExprState *setexpr, - ExprContext *econtext, - MemoryContext argContext, - TupleDesc expectedDesc, - bool randomAccess); + ExprContext *econtext, + MemoryContext argContext, + TupleDesc expectedDesc, + bool randomAccess); extern SetExprState *ExecInitFunctionResultSet(Expr *expr, - ExprContext *econtext, PlanState *parent); + ExprContext *econtext, PlanState *parent); extern Datum ExecMakeFunctionResultSet(SetExprState *fcache, - ExprContext *econtext, - MemoryContext argContext, - bool *isNull, - ExprDoneCond *isDone); + ExprContext *econtext, + MemoryContext argContext, + bool *isNull, + ExprDoneCond *isDone); /* * prototypes from functions in execScan.c @@ -423,7 +426,7 @@ typedef TupleTableSlot *(*ExecScanAccessMtd) (ScanState *node); typedef bool (*ExecScanRecheckMtd) (ScanState *node, TupleTableSlot *slot); extern TupleTableSlot *ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, - ExecScanRecheckMtd recheckMtd); + ExecScanRecheckMtd recheckMtd); extern void ExecAssignScanProjectionInfo(ScanState *node); extern void ExecAssignScanProjectionInfoWithVarno(ScanState *node, Index varno); extern void ExecScanReScan(ScanState *node); @@ -431,14 +434,21 @@ extern void ExecScanReScan(ScanState *node); /* * prototypes from functions in execTuples.c */ -extern void ExecInitResultTupleSlotTL(EState *estate, PlanState *planstate); -extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupleDesc); +extern void ExecInitResultTypeTL(PlanState *planstate); +extern void ExecInitResultSlot(PlanState *planstate, + const TupleTableSlotOps *tts_ops); +extern void ExecInitResultTupleSlotTL(PlanState *planstate, + const TupleTableSlotOps *tts_ops); +extern void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, + TupleDesc tupleDesc, + const TupleTableSlotOps *tts_ops); extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate, - TupleDesc tupleDesc); -extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, - TupleDesc tupType); -extern TupleDesc ExecTypeFromTL(List *targetList, bool hasoid); -extern TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid); + TupleDesc tupledesc, + const TupleTableSlotOps *tts_ops); +extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, + const TupleTableSlotOps *tts_ops); +extern TupleDesc ExecTypeFromTL(List *targetList); +extern TupleDesc ExecCleanTypeFromTL(List *targetList); extern TupleDesc ExecTypeFromExprList(List *exprList); extern void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList); extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg); @@ -450,7 +460,8 @@ typedef struct TupOutputState } TupOutputState; extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest, - TupleDesc tupdesc); + TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops); extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull); extern void do_text_output_multiline(TupOutputState *tstate, const char *txt); extern void end_tup_output(TupOutputState *tstate); @@ -504,72 +515,86 @@ extern ExprContext *MakePerTupleExprContext(EState *estate); extern void ExecAssignExprContext(EState *estate, PlanState *planstate); extern TupleDesc ExecGetResultType(PlanState *planstate); +extern const TupleTableSlotOps *ExecGetResultSlotOps(PlanState *planstate, + bool *isfixed); extern void ExecAssignProjectionInfo(PlanState *planstate, - TupleDesc inputDesc); + TupleDesc inputDesc); extern void ExecConditionalAssignProjectionInfo(PlanState *planstate, - TupleDesc inputDesc, Index varno); + TupleDesc inputDesc, Index varno); extern void ExecFreeExprContext(PlanState *planstate); extern void ExecAssignScanType(ScanState *scanstate, TupleDesc tupDesc); -extern void ExecCreateScanSlotFromOuterPlan(EState *estate, ScanState *scanstate); +extern void ExecCreateScanSlotFromOuterPlan(EState *estate, + ScanState *scanstate, + const TupleTableSlotOps *tts_ops); extern bool ExecRelationIsTargetRelation(EState *estate, Index scanrelid); extern Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags); -extern void ExecCloseScanRelation(Relation scanrel); + +extern void ExecInitRangeTable(EState *estate, List *rangeTable); + +static inline RangeTblEntry * +exec_rt_fetch(Index rti, EState *estate) +{ + return (RangeTblEntry *) list_nth(estate->es_range_table, rti - 1); +} + +extern Relation ExecGetRangeTableRelation(EState *estate, Index rti); extern int executor_errposition(EState *estate, int location); extern void RegisterExprContextCallback(ExprContext *econtext, - ExprContextCallbackFunction function, - Datum arg); + ExprContextCallbackFunction function, + Datum arg); extern void UnregisterExprContextCallback(ExprContext *econtext, - ExprContextCallbackFunction function, - Datum arg); - -extern void ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate); + ExprContextCallbackFunction function, + Datum arg); extern Datum GetAttributeByName(HeapTupleHeader tuple, const char *attname, - bool *isNull); + bool *isNull); extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, - bool *isNull); + bool *isNull); extern int ExecTargetListLength(List *targetlist); extern int ExecCleanTargetListLength(List *targetlist); +extern TupleTableSlot *ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relInfo); +extern TupleTableSlot *ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo); +extern TupleTableSlot *ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo); + /* * prototypes from functions in execIndexing.c */ extern void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative); extern void ExecCloseIndices(ResultRelInfo *resultRelInfo); -extern List *ExecInsertIndexTuples(TupleTableSlot *slot, ItemPointer tupleid, - EState *estate, bool noDupErr, bool *specConflict, - List *arbiterIndexes); +extern List *ExecInsertIndexTuples(TupleTableSlot *slot, EState *estate, bool noDupErr, + bool *specConflict, List *arbiterIndexes); extern bool ExecCheckIndexConstraints(TupleTableSlot *slot, EState *estate, - ItemPointer conflictTid, List *arbiterIndexes); + ItemPointer conflictTid, List *arbiterIndexes); extern void check_exclusion_constraint(Relation heap, Relation index, - IndexInfo *indexInfo, - ItemPointer tupleid, - Datum *values, bool *isnull, - EState *estate, bool newIndex); + IndexInfo *indexInfo, + ItemPointer tupleid, + Datum *values, bool *isnull, + EState *estate, bool newIndex); /* * prototypes from functions in execReplication.c */ extern bool RelationFindReplTupleByIndex(Relation rel, Oid idxoid, - LockTupleMode lockmode, - TupleTableSlot *searchslot, - TupleTableSlot *outslot); + LockTupleMode lockmode, + TupleTableSlot *searchslot, + TupleTableSlot *outslot); extern bool RelationFindReplTupleSeq(Relation rel, LockTupleMode lockmode, - TupleTableSlot *searchslot, TupleTableSlot *outslot); + TupleTableSlot *searchslot, TupleTableSlot *outslot); extern void ExecSimpleRelationInsert(EState *estate, TupleTableSlot *slot); extern void ExecSimpleRelationUpdate(EState *estate, EPQState *epqstate, - TupleTableSlot *searchslot, TupleTableSlot *slot); + TupleTableSlot *searchslot, TupleTableSlot *slot); extern void ExecSimpleRelationDelete(EState *estate, EPQState *epqstate, - TupleTableSlot *searchslot); + TupleTableSlot *searchslot); extern void CheckCmdReplicaIdentity(Relation rel, CmdType cmd); extern void CheckSubscriptionRelkind(char relkind, const char *nspname, - const char *relname); + const char *relname); #endif /* EXECUTOR_H */ diff --git a/src/include/executor/functions.h b/src/include/executor/functions.h index a309809ba84..99131bfadb4 100644 --- a/src/include/executor/functions.h +++ b/src/include/executor/functions.h @@ -4,7 +4,7 @@ * Declarations for execution of SQL-language functions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/functions.h @@ -23,18 +23,18 @@ typedef struct SQLFunctionParseInfo *SQLFunctionParseInfoPtr; extern Datum fmgr_sql(PG_FUNCTION_ARGS); extern SQLFunctionParseInfoPtr prepare_sql_fn_parse_info(HeapTuple procedureTuple, - Node *call_expr, - Oid inputCollation); + Node *call_expr, + Oid inputCollation); extern void sql_fn_parser_setup(struct ParseState *pstate, - SQLFunctionParseInfoPtr pinfo); + SQLFunctionParseInfoPtr pinfo); extern void check_sql_fn_statements(List *queryTreeList); extern bool check_sql_fn_retval(Oid func_id, Oid rettype, - List *queryTreeList, - bool *modifyTargetList, - JunkFilter **junkFilter); + List *queryTreeList, + bool *modifyTargetList, + JunkFilter **junkFilter); extern DestReceiver *CreateSQLFunctionDestReceiver(void); diff --git a/src/include/executor/hashjoin.h b/src/include/executor/hashjoin.h index a9f9872a78c..2c94b926d37 100644 --- a/src/include/executor/hashjoin.h +++ b/src/include/executor/hashjoin.h @@ -4,7 +4,7 @@ * internal structures for hash joins * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/hashjoin.h @@ -337,6 +337,7 @@ typedef struct HashJoinTableData FmgrInfo *outer_hashfunctions; /* lookup data for hash functions */ FmgrInfo *inner_hashfunctions; /* lookup data for hash functions */ bool *hashStrict; /* is each hash join operator strict? */ + Oid *collations; Size spaceUsed; /* memory space currently used by tuples */ Size spaceAllowed; /* upper limit for space used */ diff --git a/src/include/executor/instrument.h b/src/include/executor/instrument.h index 28eb0093d47..70d8632305e 100644 --- a/src/include/executor/instrument.h +++ b/src/include/executor/instrument.h @@ -4,7 +4,7 @@ * definitions for run-time statistics collection * * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/include/executor/instrument.h * @@ -57,12 +57,10 @@ typedef struct Instrumentation double startup; /* Total startup time (in seconds) */ double total; /* Total total time (in seconds) */ double ntuples; /* Total tuples produced */ + double ntuples2; /* Secondary node-specific tuple counter */ double nloops; /* # of run cycles for this node */ - double nfiltered1; /* # tuples removed by scanqual or joinqual OR - * # tuples inserted by MERGE */ - double nfiltered2; /* # tuples removed by "other" quals OR - * # tuples updated by MERGE */ - double nfiltered3; /* # tuples deleted by MERGE */ + double nfiltered1; /* # tuples removed by scanqual or joinqual */ + double nfiltered2; /* # tuples removed by "other" quals */ BufferUsage bufusage; /* Total buffer usage */ } Instrumentation; diff --git a/src/include/executor/nodeAgg.h b/src/include/executor/nodeAgg.h index ab55be8f113..68c9e5f5400 100644 --- a/src/include/executor/nodeAgg.h +++ b/src/include/executor/nodeAgg.h @@ -4,7 +4,7 @@ * prototypes for nodeAgg.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeAgg.h @@ -158,12 +158,12 @@ typedef struct AggStatePerTransData * re-initializing the unchanging fields; which isn't much, but it seems * worth the extra space consumption. */ - FunctionCallInfoData transfn_fcinfo; + FunctionCallInfo transfn_fcinfo; /* Likewise for serialization and deserialization functions */ - FunctionCallInfoData serialfn_fcinfo; + FunctionCallInfo serialfn_fcinfo; - FunctionCallInfoData deserialfn_fcinfo; + FunctionCallInfo deserialfn_fcinfo; } AggStatePerTransData; /* @@ -216,10 +216,10 @@ typedef struct AggStatePerAggData bool resulttypeByVal; /* - * "sharable" is false if this agg cannot share state values with other + * "shareable" is false if this agg cannot share state values with other * aggregates because the final function is read-write. */ - bool sharable; + bool shareable; } AggStatePerAggData; /* @@ -300,7 +300,7 @@ typedef struct AggStatePerHashData int numhashGrpCols; /* number of columns in hash table */ int largestGrpColIdx; /* largest col required for hashing */ AttrNumber *hashGrpColIdxInput; /* hash col indices in input slot */ - AttrNumber *hashGrpColIdxHash; /* indices in hashtbl tuples */ + AttrNumber *hashGrpColIdxHash; /* indices in hash table tuples */ Agg *aggnode; /* original Agg node, for numGroups etc. */ } AggStatePerHashData; @@ -311,6 +311,4 @@ extern void ExecReScanAgg(AggState *node); extern Size hash_agg_entry_size(int numAggs); -extern Datum aggregate_dummy(PG_FUNCTION_ARGS); - #endif /* NODEAGG_H */ diff --git a/src/include/executor/nodeAppend.h b/src/include/executor/nodeAppend.h index 4e31a9fcd83..80e02b7fac8 100644 --- a/src/include/executor/nodeAppend.h +++ b/src/include/executor/nodeAppend.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeAppend.h diff --git a/src/include/executor/nodeBitmapAnd.h b/src/include/executor/nodeBitmapAnd.h index 029e5b600d7..addf70f969c 100644 --- a/src/include/executor/nodeBitmapAnd.h +++ b/src/include/executor/nodeBitmapAnd.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapAnd.h diff --git a/src/include/executor/nodeBitmapHeapscan.h b/src/include/executor/nodeBitmapHeapscan.h index e86d3e10d4a..112def153cb 100644 --- a/src/include/executor/nodeBitmapHeapscan.h +++ b/src/include/executor/nodeBitmapHeapscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapHeapscan.h @@ -21,12 +21,12 @@ extern BitmapHeapScanState *ExecInitBitmapHeapScan(BitmapHeapScan *node, EState extern void ExecEndBitmapHeapScan(BitmapHeapScanState *node); extern void ExecReScanBitmapHeapScan(BitmapHeapScanState *node); extern void ExecBitmapHeapEstimate(BitmapHeapScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecBitmapHeapInitializeDSM(BitmapHeapScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecBitmapHeapReInitializeDSM(BitmapHeapScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecBitmapHeapInitializeWorker(BitmapHeapScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); #endif /* NODEBITMAPHEAPSCAN_H */ diff --git a/src/include/executor/nodeBitmapIndexscan.h b/src/include/executor/nodeBitmapIndexscan.h index 8b93baabea4..3903c876f86 100644 --- a/src/include/executor/nodeBitmapIndexscan.h +++ b/src/include/executor/nodeBitmapIndexscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapIndexscan.h diff --git a/src/include/executor/nodeBitmapOr.h b/src/include/executor/nodeBitmapOr.h index 96f84d22ede..27ce62c806d 100644 --- a/src/include/executor/nodeBitmapOr.h +++ b/src/include/executor/nodeBitmapOr.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeBitmapOr.h diff --git a/src/include/executor/nodeCtescan.h b/src/include/executor/nodeCtescan.h index 21f4f191cd1..564d807e845 100644 --- a/src/include/executor/nodeCtescan.h +++ b/src/include/executor/nodeCtescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeCtescan.h diff --git a/src/include/executor/nodeCustom.h b/src/include/executor/nodeCustom.h index 454a684a409..2829be5d010 100644 --- a/src/include/executor/nodeCustom.h +++ b/src/include/executor/nodeCustom.h @@ -4,7 +4,7 @@ * * prototypes for CustomScan nodes * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------ @@ -14,13 +14,12 @@ #include "access/parallel.h" #include "nodes/execnodes.h" -#include "nodes/extensible.h" /* * General executor code */ -extern CustomScanState *ExecInitCustomScan(CustomScan *custom_scan, - EState *estate, int eflags); +extern CustomScanState *ExecInitCustomScan(CustomScan *cscan, + EState *estate, int eflags); extern void ExecEndCustomScan(CustomScanState *node); extern void ExecReScanCustomScan(CustomScanState *node); @@ -31,13 +30,13 @@ extern void ExecCustomRestrPos(CustomScanState *node); * Parallel execution support */ extern void ExecCustomScanEstimate(CustomScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecCustomScanInitializeDSM(CustomScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecCustomScanReInitializeDSM(CustomScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecCustomScanInitializeWorker(CustomScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); extern void ExecShutdownCustomScan(CustomScanState *node); #endif /* NODECUSTOM_H */ diff --git a/src/include/executor/nodeForeignscan.h b/src/include/executor/nodeForeignscan.h index ccb66be733d..ca7723c8997 100644 --- a/src/include/executor/nodeForeignscan.h +++ b/src/include/executor/nodeForeignscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeForeignscan.h @@ -22,13 +22,13 @@ extern void ExecEndForeignScan(ForeignScanState *node); extern void ExecReScanForeignScan(ForeignScanState *node); extern void ExecForeignScanEstimate(ForeignScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecForeignScanInitializeDSM(ForeignScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecForeignScanReInitializeDSM(ForeignScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecForeignScanInitializeWorker(ForeignScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); extern void ExecShutdownForeignScan(ForeignScanState *node); #endif /* NODEFOREIGNSCAN_H */ diff --git a/src/include/executor/nodeFunctionscan.h b/src/include/executor/nodeFunctionscan.h index 5de8d15a5ff..4f7d60dcc3d 100644 --- a/src/include/executor/nodeFunctionscan.h +++ b/src/include/executor/nodeFunctionscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeFunctionscan.h diff --git a/src/include/executor/nodeGather.h b/src/include/executor/nodeGather.h index 4477b855c45..73a69a4c4bb 100644 --- a/src/include/executor/nodeGather.h +++ b/src/include/executor/nodeGather.h @@ -4,7 +4,7 @@ * prototypes for nodeGather.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeGather.h diff --git a/src/include/executor/nodeGatherMerge.h b/src/include/executor/nodeGatherMerge.h index 1e514ff0900..d818576f1c8 100644 --- a/src/include/executor/nodeGatherMerge.h +++ b/src/include/executor/nodeGatherMerge.h @@ -4,7 +4,7 @@ * prototypes for nodeGatherMerge.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeGatherMerge.h @@ -17,8 +17,8 @@ #include "nodes/execnodes.h" extern GatherMergeState *ExecInitGatherMerge(GatherMerge *node, - EState *estate, - int eflags); + EState *estate, + int eflags); extern void ExecEndGatherMerge(GatherMergeState *node); extern void ExecReScanGatherMerge(GatherMergeState *node); extern void ExecShutdownGatherMerge(GatherMergeState *node); diff --git a/src/include/executor/nodeGroup.h b/src/include/executor/nodeGroup.h index 483390db8ce..1e673b0dafc 100644 --- a/src/include/executor/nodeGroup.h +++ b/src/include/executor/nodeGroup.h @@ -4,7 +4,7 @@ * prototypes for nodeGroup.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeGroup.h diff --git a/src/include/executor/nodeHash.h b/src/include/executor/nodeHash.h index 8d700c06c55..fc80f03aa8d 100644 --- a/src/include/executor/nodeHash.h +++ b/src/include/executor/nodeHash.h @@ -4,7 +4,7 @@ * prototypes for nodeHash.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeHash.h @@ -24,49 +24,49 @@ extern Node *MultiExecHash(HashState *node); extern void ExecEndHash(HashState *node); extern void ExecReScanHash(HashState *node); -extern HashJoinTable ExecHashTableCreate(HashState *state, List *hashOperators, - bool keepNulls); +extern HashJoinTable ExecHashTableCreate(HashState *state, List *hashOperators, List *hashCollations, + bool keepNulls); extern void ExecParallelHashTableAlloc(HashJoinTable hashtable, - int batchno); + int batchno); extern void ExecHashTableDestroy(HashJoinTable hashtable); extern void ExecHashTableDetach(HashJoinTable hashtable); extern void ExecHashTableDetachBatch(HashJoinTable hashtable); extern void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable, - int batchno); + int batchno); extern void ExecHashTableInsert(HashJoinTable hashtable, - TupleTableSlot *slot, - uint32 hashvalue); + TupleTableSlot *slot, + uint32 hashvalue); extern void ExecParallelHashTableInsert(HashJoinTable hashtable, - TupleTableSlot *slot, - uint32 hashvalue); -extern void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, TupleTableSlot *slot, uint32 hashvalue); +extern void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable, + TupleTableSlot *slot, + uint32 hashvalue); extern bool ExecHashGetHashValue(HashJoinTable hashtable, - ExprContext *econtext, - List *hashkeys, - bool outer_tuple, - bool keep_nulls, - uint32 *hashvalue); + ExprContext *econtext, + List *hashkeys, + bool outer_tuple, + bool keep_nulls, + uint32 *hashvalue); extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable, - uint32 hashvalue, - int *bucketno, - int *batchno); + uint32 hashvalue, + int *bucketno, + int *batchno); extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext); extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext); extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate); extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate, - ExprContext *econtext); + ExprContext *econtext); extern void ExecHashTableReset(HashJoinTable hashtable); extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable); extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew, - bool try_combined_work_mem, - int parallel_workers, - size_t *space_allowed, - int *numbuckets, - int *numbatches, - int *num_skew_mcvs); + bool try_combined_work_mem, + int parallel_workers, + size_t *space_allowed, + int *numbuckets, + int *numbatches, + int *num_skew_mcvs); extern int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue); extern void ExecHashEstimate(HashState *node, ParallelContext *pcxt); extern void ExecHashInitializeDSM(HashState *node, ParallelContext *pcxt); @@ -74,6 +74,6 @@ extern void ExecHashInitializeWorker(HashState *node, ParallelWorkerContext *pwc extern void ExecHashRetrieveInstrumentation(HashState *node); extern void ExecShutdownHash(HashState *node); extern void ExecHashGetInstrumentation(HashInstrumentation *instrument, - HashJoinTable hashtable); + HashJoinTable hashtable); #endif /* NODEHASH_H */ diff --git a/src/include/executor/nodeHashjoin.h b/src/include/executor/nodeHashjoin.h index 4086dd53821..1752b3b208d 100644 --- a/src/include/executor/nodeHashjoin.h +++ b/src/include/executor/nodeHashjoin.h @@ -4,7 +4,7 @@ * prototypes for nodeHashjoin.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeHashjoin.h @@ -26,9 +26,9 @@ extern void ExecHashJoinEstimate(HashJoinState *state, ParallelContext *pcxt); extern void ExecHashJoinInitializeDSM(HashJoinState *state, ParallelContext *pcxt); extern void ExecHashJoinReInitializeDSM(HashJoinState *state, ParallelContext *pcxt); extern void ExecHashJoinInitializeWorker(HashJoinState *state, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); extern void ExecHashJoinSaveTuple(MinimalTuple tuple, uint32 hashvalue, - BufFile **fileptr); + BufFile **fileptr); #endif /* NODEHASHJOIN_H */ diff --git a/src/include/executor/nodeIndexonlyscan.h b/src/include/executor/nodeIndexonlyscan.h index 8f6c5a8d09d..644166b5bcb 100644 --- a/src/include/executor/nodeIndexonlyscan.h +++ b/src/include/executor/nodeIndexonlyscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeIndexonlyscan.h @@ -25,12 +25,12 @@ extern void ExecReScanIndexOnlyScan(IndexOnlyScanState *node); /* Support functions for parallel index-only scans */ extern void ExecIndexOnlyScanEstimate(IndexOnlyScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecIndexOnlyScanReInitializeDSM(IndexOnlyScanState *node, - ParallelContext *pcxt); + ParallelContext *pcxt); extern void ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); #endif /* NODEINDEXONLYSCAN_H */ diff --git a/src/include/executor/nodeIndexscan.h b/src/include/executor/nodeIndexscan.h index 822a9c9fade..e895ec5b7b3 100644 --- a/src/include/executor/nodeIndexscan.h +++ b/src/include/executor/nodeIndexscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeIndexscan.h @@ -14,6 +14,7 @@ #ifndef NODEINDEXSCAN_H #define NODEINDEXSCAN_H +#include "access/genam.h" #include "access/parallel.h" #include "nodes/execnodes.h" @@ -26,21 +27,21 @@ extern void ExecIndexScanEstimate(IndexScanState *node, ParallelContext *pcxt); extern void ExecIndexScanInitializeDSM(IndexScanState *node, ParallelContext *pcxt); extern void ExecIndexScanReInitializeDSM(IndexScanState *node, ParallelContext *pcxt); extern void ExecIndexScanInitializeWorker(IndexScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); /* * These routines are exported to share code with nodeIndexonlyscan.c and * nodeBitmapIndexscan.c */ extern void ExecIndexBuildScanKeys(PlanState *planstate, Relation index, - List *quals, bool isorderby, - ScanKey *scanKeys, int *numScanKeys, - IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, - IndexArrayKeyInfo **arrayKeys, int *numArrayKeys); + List *quals, bool isorderby, + ScanKey *scanKeys, int *numScanKeys, + IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, + IndexArrayKeyInfo **arrayKeys, int *numArrayKeys); extern void ExecIndexEvalRuntimeKeys(ExprContext *econtext, - IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys); + IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys); extern bool ExecIndexEvalArrayKeys(ExprContext *econtext, - IndexArrayKeyInfo *arrayKeys, int numArrayKeys); + IndexArrayKeyInfo *arrayKeys, int numArrayKeys); extern bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys); #endif /* NODEINDEXSCAN_H */ diff --git a/src/include/executor/nodeLimit.h b/src/include/executor/nodeLimit.h index 160ae5b0263..c12ff92bb57 100644 --- a/src/include/executor/nodeLimit.h +++ b/src/include/executor/nodeLimit.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeLimit.h diff --git a/src/include/executor/nodeLockRows.h b/src/include/executor/nodeLockRows.h index e3d77dff560..0623607d166 100644 --- a/src/include/executor/nodeLockRows.h +++ b/src/include/executor/nodeLockRows.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeLockRows.h diff --git a/src/include/executor/nodeMaterial.h b/src/include/executor/nodeMaterial.h index 84004efd5e9..e558c34cc00 100644 --- a/src/include/executor/nodeMaterial.h +++ b/src/include/executor/nodeMaterial.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMaterial.h diff --git a/src/include/executor/nodeMergeAppend.h b/src/include/executor/nodeMergeAppend.h index e3bb7d91ff9..feeddd4a6f6 100644 --- a/src/include/executor/nodeMergeAppend.h +++ b/src/include/executor/nodeMergeAppend.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMergeAppend.h diff --git a/src/include/executor/nodeMergejoin.h b/src/include/executor/nodeMergejoin.h index 456a39d9147..996ae4d02c8 100644 --- a/src/include/executor/nodeMergejoin.h +++ b/src/include/executor/nodeMergejoin.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeMergejoin.h diff --git a/src/include/executor/nodeModifyTable.h b/src/include/executor/nodeModifyTable.h index 7e9ab3cb6b4..891b119608b 100644 --- a/src/include/executor/nodeModifyTable.h +++ b/src/include/executor/nodeModifyTable.h @@ -3,7 +3,7 @@ * nodeModifyTable.h * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeModifyTable.h @@ -15,31 +15,10 @@ #include "nodes/execnodes.h" +extern void ExecComputeStoredGenerated(EState *estate, TupleTableSlot *slot); + extern ModifyTableState *ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags); extern void ExecEndModifyTable(ModifyTableState *node); extern void ExecReScanModifyTable(ModifyTableState *node); -extern TupleTableSlot *ExecPrepareTupleRouting(ModifyTableState *mtstate, - EState *estate, - struct PartitionTupleRouting *proute, - ResultRelInfo *targetRelInfo, - TupleTableSlot *slot); -extern TupleTableSlot *ExecDelete(ModifyTableState *mtstate, - ItemPointer tupleid, HeapTuple oldtuple, TupleTableSlot *planSlot, - EPQState *epqstate, EState *estate, bool *tupleDeleted, - bool processReturning, HeapUpdateFailureData *hufdp, - MergeActionState *actionState, bool canSetTag, - bool changingPart); -extern TupleTableSlot *ExecUpdate(ModifyTableState *mtstate, - ItemPointer tupleid, HeapTuple oldtuple, TupleTableSlot *slot, - TupleTableSlot *planSlot, EPQState *epqstate, EState *estate, - bool *tuple_updated, HeapUpdateFailureData *hufdp, - MergeActionState *actionState, bool canSetTag); -extern TupleTableSlot *ExecInsert(ModifyTableState *mtstate, - TupleTableSlot *slot, - TupleTableSlot *planSlot, - EState *estate, - MergeActionState *actionState, - bool canSetTag); -extern void ExecCheckPlanOutput(Relation resultRel, List *targetList); #endif /* NODEMODIFYTABLE_H */ diff --git a/src/include/executor/nodeNamedtuplestorescan.h b/src/include/executor/nodeNamedtuplestorescan.h index 6c7300bcb86..89e441fd3b7 100644 --- a/src/include/executor/nodeNamedtuplestorescan.h +++ b/src/include/executor/nodeNamedtuplestorescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeNamedtuplestorescan.h diff --git a/src/include/executor/nodeNestloop.h b/src/include/executor/nodeNestloop.h index 06b90d150eb..d1f94d3c126 100644 --- a/src/include/executor/nodeNestloop.h +++ b/src/include/executor/nodeNestloop.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeNestloop.h diff --git a/src/include/executor/nodeProjectSet.h b/src/include/executor/nodeProjectSet.h index c365589754d..15902a96e96 100644 --- a/src/include/executor/nodeProjectSet.h +++ b/src/include/executor/nodeProjectSet.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeProjectSet.h diff --git a/src/include/executor/nodeRecursiveunion.h b/src/include/executor/nodeRecursiveunion.h index 09f211c5000..76befffe09b 100644 --- a/src/include/executor/nodeRecursiveunion.h +++ b/src/include/executor/nodeRecursiveunion.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeRecursiveunion.h diff --git a/src/include/executor/nodeResult.h b/src/include/executor/nodeResult.h index 422a2ffd478..af5fb60a678 100644 --- a/src/include/executor/nodeResult.h +++ b/src/include/executor/nodeResult.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeResult.h diff --git a/src/include/executor/nodeSamplescan.h b/src/include/executor/nodeSamplescan.h index 0d489496cd4..c0976508c4f 100644 --- a/src/include/executor/nodeSamplescan.h +++ b/src/include/executor/nodeSamplescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSamplescan.h diff --git a/src/include/executor/nodeSeqscan.h b/src/include/executor/nodeSeqscan.h index 020b40c6b70..f0595b2a35b 100644 --- a/src/include/executor/nodeSeqscan.h +++ b/src/include/executor/nodeSeqscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSeqscan.h @@ -26,6 +26,6 @@ extern void ExecSeqScanEstimate(SeqScanState *node, ParallelContext *pcxt); extern void ExecSeqScanInitializeDSM(SeqScanState *node, ParallelContext *pcxt); extern void ExecSeqScanReInitializeDSM(SeqScanState *node, ParallelContext *pcxt); extern void ExecSeqScanInitializeWorker(SeqScanState *node, - ParallelWorkerContext *pwcxt); + ParallelWorkerContext *pwcxt); #endif /* NODESEQSCAN_H */ diff --git a/src/include/executor/nodeSetOp.h b/src/include/executor/nodeSetOp.h index d41fcbdc6e6..408022c6ca6 100644 --- a/src/include/executor/nodeSetOp.h +++ b/src/include/executor/nodeSetOp.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSetOp.h diff --git a/src/include/executor/nodeSort.h b/src/include/executor/nodeSort.h index 22f69ee1eab..d1caceddfd1 100644 --- a/src/include/executor/nodeSort.h +++ b/src/include/executor/nodeSort.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSort.h diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h index d9784a2b71f..2d90964275b 100644 --- a/src/include/executor/nodeSubplan.h +++ b/src/include/executor/nodeSubplan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSubplan.h @@ -28,4 +28,6 @@ extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent); extern void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext); +extern void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext); + #endif /* NODESUBPLAN_H */ diff --git a/src/include/executor/nodeSubqueryscan.h b/src/include/executor/nodeSubqueryscan.h index 4bd292159c1..cb61217fa3b 100644 --- a/src/include/executor/nodeSubqueryscan.h +++ b/src/include/executor/nodeSubqueryscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeSubqueryscan.h diff --git a/src/include/executor/nodeTableFuncscan.h b/src/include/executor/nodeTableFuncscan.h index 06ebbf31eb5..f7806247522 100644 --- a/src/include/executor/nodeTableFuncscan.h +++ b/src/include/executor/nodeTableFuncscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeTableFuncscan.h diff --git a/src/include/executor/nodeTidscan.h b/src/include/executor/nodeTidscan.h index 30d21ff2296..9065995408b 100644 --- a/src/include/executor/nodeTidscan.h +++ b/src/include/executor/nodeTidscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeTidscan.h diff --git a/src/include/executor/nodeUnique.h b/src/include/executor/nodeUnique.h index b8a44b73c10..adacc703664 100644 --- a/src/include/executor/nodeUnique.h +++ b/src/include/executor/nodeUnique.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeUnique.h diff --git a/src/include/executor/nodeValuesscan.h b/src/include/executor/nodeValuesscan.h index b4f384b111a..25bec5086e4 100644 --- a/src/include/executor/nodeValuesscan.h +++ b/src/include/executor/nodeValuesscan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeValuesscan.h diff --git a/src/include/executor/nodeWindowAgg.h b/src/include/executor/nodeWindowAgg.h index 677e2d8d07e..741036dd982 100644 --- a/src/include/executor/nodeWindowAgg.h +++ b/src/include/executor/nodeWindowAgg.h @@ -4,7 +4,7 @@ * prototypes for nodeWindowAgg.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeWindowAgg.h diff --git a/src/include/executor/nodeWorktablescan.h b/src/include/executor/nodeWorktablescan.h index 7daee1e40a6..d100cf203cc 100644 --- a/src/include/executor/nodeWorktablescan.h +++ b/src/include/executor/nodeWorktablescan.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/nodeWorktablescan.h diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 78410b9f772..ad69a5ce433 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -3,7 +3,7 @@ * spi.h * Server Programming Interface public declarations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/spi.h @@ -21,11 +21,14 @@ typedef struct SPITupleTable { - MemoryContext tuptabcxt; /* memory context of result table */ - uint64 alloced; /* # of alloced vals */ - uint64 free; /* # of free vals */ + /* Public members */ TupleDesc tupdesc; /* tuple descriptor */ - HeapTuple *vals; /* tuples */ + HeapTuple *vals; /* array of tuples */ + uint64 numvals; /* number of valid tuples */ + + /* Private members, not intended for external callers */ + uint64 alloced; /* allocated length of vals array */ + MemoryContext tuptabcxt; /* memory context of result table */ slist_node next; /* link for internal bookkeeping */ SubTransactionId subid; /* subxact in which tuptable was created */ } SPITupleTable; @@ -64,7 +67,6 @@ typedef struct _SPI_plan *SPIPlanPtr; #define SPI_OK_REL_REGISTER 15 #define SPI_OK_REL_UNREGISTER 16 #define SPI_OK_TD_REGISTER 17 -#define SPI_OK_MERGE 18 #define SPI_OPT_NONATOMIC (1 << 0) @@ -76,7 +78,6 @@ typedef struct _SPI_plan *SPIPlanPtr; #define SPI_restore_connection() ((void) 0) extern PGDLLIMPORT uint64 SPI_processed; -extern PGDLLIMPORT Oid SPI_lastoid; extern PGDLLIMPORT SPITupleTable *SPI_tuptable; extern PGDLLIMPORT int SPI_result; @@ -84,30 +85,30 @@ extern int SPI_connect(void); extern int SPI_connect_ext(int options); extern int SPI_finish(void); extern int SPI_execute(const char *src, bool read_only, long tcount); -extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, - bool read_only, long tcount); -extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, - ParamListInfo params, - bool read_only, long tcount); +extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, + bool read_only, long tcount); +extern int SPI_execute_plan_with_paramlist(SPIPlanPtr plan, + ParamListInfo params, + bool read_only, long tcount); extern int SPI_exec(const char *src, long tcount); -extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, - long tcount); -extern int SPI_execute_snapshot(SPIPlanPtr plan, - Datum *Values, const char *Nulls, - Snapshot snapshot, - Snapshot crosscheck_snapshot, - bool read_only, bool fire_triggers, long tcount); -extern int SPI_execute_with_args(const char *src, - int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, - bool read_only, long tcount); +extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls, + long tcount); +extern int SPI_execute_snapshot(SPIPlanPtr plan, + Datum *Values, const char *Nulls, + Snapshot snapshot, + Snapshot crosscheck_snapshot, + bool read_only, bool fire_triggers, long tcount); +extern int SPI_execute_with_args(const char *src, + int nargs, Oid *argtypes, + Datum *Values, const char *Nulls, + bool read_only, long tcount); extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes); extern SPIPlanPtr SPI_prepare_cursor(const char *src, int nargs, Oid *argtypes, - int cursorOptions); + int cursorOptions); extern SPIPlanPtr SPI_prepare_params(const char *src, - ParserSetupHook parserSetup, - void *parserSetupArg, - int cursorOptions); + ParserSetupHook parserSetup, + void *parserSetupArg, + int cursorOptions); extern int SPI_keepplan(SPIPlanPtr plan); extern SPIPlanPtr SPI_saveplan(SPIPlanPtr plan); extern int SPI_freeplan(SPIPlanPtr plan); @@ -124,7 +125,7 @@ extern CachedPlan *SPI_plan_get_cached_plan(SPIPlanPtr plan); extern HeapTuple SPI_copytuple(HeapTuple tuple); extern HeapTupleHeader SPI_returntuple(HeapTuple tuple, TupleDesc tupdesc); extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, - int *attnum, Datum *Values, const char *Nulls); + int *attnum, Datum *Values, const char *Nulls); extern int SPI_fnumber(TupleDesc tupdesc, const char *fname); extern char *SPI_fname(TupleDesc tupdesc, int fnumber); extern char *SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber); @@ -141,14 +142,14 @@ extern void SPI_freetuple(HeapTuple pointer); extern void SPI_freetuptable(SPITupleTable *tuptable); extern Portal SPI_cursor_open(const char *name, SPIPlanPtr plan, - Datum *Values, const char *Nulls, bool read_only); + Datum *Values, const char *Nulls, bool read_only); extern Portal SPI_cursor_open_with_args(const char *name, - const char *src, - int nargs, Oid *argtypes, - Datum *Values, const char *Nulls, - bool read_only, int cursorOptions); + const char *src, + int nargs, Oid *argtypes, + Datum *Values, const char *Nulls, + bool read_only, int cursorOptions); extern Portal SPI_cursor_open_with_paramlist(const char *name, SPIPlanPtr plan, - ParamListInfo params, bool read_only); + ParamListInfo params, bool read_only); extern Portal SPI_cursor_find(const char *name); extern void SPI_cursor_fetch(Portal portal, bool forward, long count); extern void SPI_cursor_move(Portal portal, bool forward, long count); @@ -162,9 +163,13 @@ extern int SPI_register_trigger_data(TriggerData *tdata); extern void SPI_start_transaction(void); extern void SPI_commit(void); +extern void SPI_commit_and_chain(void); extern void SPI_rollback(void); +extern void SPI_rollback_and_chain(void); +extern void SPICleanup(void); extern void AtEOXact_SPI(bool isCommit); extern void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid); +extern bool SPI_inside_nonatomic_context(void); #endif /* SPI_H */ diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h index 376fae0bbc4..bfcb4663144 100644 --- a/src/include/executor/spi_priv.h +++ b/src/include/executor/spi_priv.h @@ -3,7 +3,7 @@ * spi_priv.h * Server Programming Interface private declarations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/spi_priv.h @@ -23,7 +23,6 @@ typedef struct { /* current results */ uint64 processed; /* by Executor */ - Oid lastoid; SPITupleTable *tuptable; /* tuptable currently being built */ /* subtransaction in which current Executor call was started */ @@ -38,8 +37,15 @@ typedef struct QueryEnvironment *queryEnv; /* query environment setup for SPI level */ /* transaction management support */ - bool atomic; /* atomic execution context, does not allow transactions */ - bool internal_xact; /* SPI-managed transaction boundary, skip cleanup */ + bool atomic; /* atomic execution context, does not allow + * transactions */ + bool internal_xact; /* SPI-managed transaction boundary, skip + * cleanup */ + + /* saved values of API global variables for previous nesting level */ + uint64 outer_processed; + SPITupleTable *outer_tuptable; + int outer_result; } _SPI_connection; /* diff --git a/src/include/executor/tablefunc.h b/src/include/executor/tablefunc.h index 52424ae2ffd..838c2c2ca29 100644 --- a/src/include/executor/tablefunc.h +++ b/src/include/executor/tablefunc.h @@ -3,7 +3,7 @@ * tablefunc.h * interface for TableFunc executor node * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tablefunc.h @@ -20,11 +20,11 @@ struct TableFuncScanState; * TableFuncRoutine holds function pointers used for generating content of * table-producer functions, such as XMLTABLE. * - * InitBuilder initialize table builder private objects. The output tuple + * InitOpaque initializes table builder private objects. The output tuple * descriptor, input functions for the columns, and typioparams are passed * from executor state. * - * SetDoc is called to define the input document. The table builder may + * SetDocument is called to define the input document. The table builder may * apply additional transformations not exposed outside the table builder * context. * @@ -45,7 +45,7 @@ struct TableFuncScanState; * builder context such that each subsequent GetValue call returns the values * for the indicated column for the row being processed. * - * DestroyBuilder shall release all resources associated with a table builder + * DestroyOpaque shall release all resources associated with a table builder * context. It may be called either because all rows have been consumed, or * because an error occurred while processing the table expression. */ diff --git a/src/include/executor/tqueue.h b/src/include/executor/tqueue.h index 0fe36392525..e6958c60903 100644 --- a/src/include/executor/tqueue.h +++ b/src/include/executor/tqueue.h @@ -3,7 +3,7 @@ * tqueue.h * Use shm_mq to send & receive tuples between parallel backends * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tqueue.h @@ -27,6 +27,6 @@ extern DestReceiver *CreateTupleQueueDestReceiver(shm_mq_handle *handle); extern TupleQueueReader *CreateTupleQueueReader(shm_mq_handle *handle); extern void DestroyTupleQueueReader(TupleQueueReader *reader); extern HeapTuple TupleQueueReaderNext(TupleQueueReader *reader, - bool nowait, bool *done); + bool nowait, bool *done); #endif /* TQUEUE_H */ diff --git a/src/include/executor/tstoreReceiver.h b/src/include/executor/tstoreReceiver.h index 5e2f83123c4..6522b7c6df1 100644 --- a/src/include/executor/tstoreReceiver.h +++ b/src/include/executor/tstoreReceiver.h @@ -4,7 +4,7 @@ * prototypes for tstoreReceiver.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tstoreReceiver.h @@ -22,8 +22,8 @@ extern DestReceiver *CreateTuplestoreDestReceiver(void); extern void SetTuplestoreDestReceiverParams(DestReceiver *self, - Tuplestorestate *tStore, - MemoryContext tContext, - bool detoast); + Tuplestorestate *tStore, + MemoryContext tContext, + bool detoast); #endif /* TSTORE_RECEIVER_H */ diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h index b71ec8e0698..203b1ab7dca 100644 --- a/src/include/executor/tuptable.h +++ b/src/include/executor/tuptable.h @@ -4,7 +4,7 @@ * tuple table support stuff * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/executor/tuptable.h @@ -15,16 +15,27 @@ #define TUPTABLE_H #include "access/htup.h" +#include "access/sysattr.h" #include "access/tupdesc.h" +#include "access/htup_details.h" #include "storage/buf.h" /*---------- * The executor stores tuples in a "tuple table" which is a List of - * independent TupleTableSlots. There are several cases we need to handle: - * 1. physical tuple in a disk buffer page - * 2. physical tuple constructed in palloc'ed memory - * 3. "minimal" physical tuple constructed in palloc'ed memory - * 4. "virtual" tuple consisting of Datum/isnull arrays + * independent TupleTableSlots. + * + * There's various different types of tuple table slots, each being able to + * store different types of tuples. Additional types of slots can be added + * without modifying core code. The type of a slot is determined by the + * TupleTableSlotOps* passed to the slot creation routine. The builtin types + * of slots are + * + * 1. physical tuple in a disk buffer page (TTSOpsBufferHeapTuple) + * 2. physical tuple constructed in palloc'ed memory (TTSOpsHeapTuple) + * 3. "minimal" physical tuple constructed in palloc'ed memory + * (TTSOpsMinimalTuple) + * 4. "virtual" tuple consisting of Datum/isnull arrays (TTSOpsVirtual) + * * * The first two cases are similar in that they both deal with "materialized" * tuples, but resource management is different. For a tuple in a disk page @@ -37,39 +48,28 @@ * parallel to case 1. Note that a minimal tuple has no "system columns". * (Actually, it could have an OID, but we have no need to access the OID.) * - * A "virtual" tuple is an optimization used to minimize physical data - * copying in a nest of plan nodes. Any pass-by-reference Datums in the - * tuple point to storage that is not directly associated with the - * TupleTableSlot; generally they will point to part of a tuple stored in - * a lower plan node's output TupleTableSlot, or to a function result + * A "virtual" tuple is an optimization used to minimize physical data copying + * in a nest of plan nodes. Until materialized pass-by-reference Datums in + * the slot point to storage that is not directly associated with the + * TupleTableSlot; generally they will point to part of a tuple stored in a + * lower plan node's output TupleTableSlot, or to a function result * constructed in a plan node's per-tuple econtext. It is the responsibility - * of the generating plan node to be sure these resources are not released - * for as long as the virtual tuple needs to be valid. We only use virtual - * tuples in the result slots of plan nodes --- tuples to be copied anywhere - * else need to be "materialized" into physical tuples. Note also that a - * virtual tuple does not have any "system columns". - * - * It is also possible for a TupleTableSlot to hold both physical and minimal - * copies of a tuple. This is done when the slot is requested to provide - * the format other than the one it currently holds. (Originally we attempted - * to handle such requests by replacing one format with the other, but that - * had the fatal defect of invalidating any pass-by-reference Datums pointing - * into the existing slot contents.) Both copies must contain identical data - * payloads when this is the case. - * - * The Datum/isnull arrays of a TupleTableSlot serve double duty. When the - * slot contains a virtual tuple, they are the authoritative data. When the - * slot contains a physical tuple, the arrays contain data extracted from - * the tuple. (In this state, any pass-by-reference Datums point into - * the physical tuple.) The extracted information is built "lazily", - * ie, only as needed. This serves to avoid repeated extraction of data - * from the physical tuple. - * - * A TupleTableSlot can also be "empty", holding no valid data. This is - * the only valid state for a freshly-created slot that has not yet had a - * tuple descriptor assigned to it. In this state, tts_isempty must be - * true, tts_shouldFree false, tts_tuple NULL, tts_buffer InvalidBuffer, - * and tts_nvalid zero. + * of the generating plan node to be sure these resources are not released for + * as long as the virtual tuple needs to be valid or is materialized. Note + * also that a virtual tuple does not have any "system columns". + * + * The Datum/isnull arrays of a TupleTableSlot serve double duty. For virtual + * slots they are the authoritative data. For the other builtin slots, + * the arrays contain data extracted from the tuple. (In this state, any + * pass-by-reference Datums point into the physical tuple.) The extracted + * information is built "lazily", ie, only as needed. This serves to avoid + * repeated extraction of data from the physical tuple. + * + * A TupleTableSlot can also be "empty", indicated by flag TTS_FLAG_EMPTY set + * in tts_flags, holding no valid data. This is the only valid state for a + * freshly-created slot that has not yet had a tuple descriptor assigned to + * it. In this state, TTS_SHOULDFREE should not be set in tts_flags, tts_tuple + * must be NULL and tts_nvalid zero. * * The tupleDescriptor is simply referenced, not copied, by the TupleTableSlot * code. The caller of ExecSetSlotDescriptor() is responsible for providing @@ -79,106 +79,409 @@ * mechanism to do more. However, the slot will increment the tupdesc * reference count if a reference-counted tupdesc is supplied.) * - * When tts_shouldFree is true, the physical tuple is "owned" by the slot - * and should be freed when the slot's reference to the tuple is dropped. - * - * If tts_buffer is not InvalidBuffer, then the slot is holding a pin - * on the indicated buffer page; drop the pin when we release the - * slot's reference to that buffer. (tts_shouldFree should always be - * false in such a case, since presumably tts_tuple is pointing at the - * buffer page.) - * - * tts_nvalid indicates the number of valid columns in the tts_values/isnull - * arrays. When the slot is holding a "virtual" tuple this must be equal - * to the descriptor's natts. When the slot is holding a physical tuple - * this is equal to the number of columns we have extracted (we always - * extract columns from left to right, so there are no holes). - * - * tts_values/tts_isnull are allocated when a descriptor is assigned to the - * slot; they are of length equal to the descriptor's natts. - * - * tts_mintuple must always be NULL if the slot does not hold a "minimal" - * tuple. When it does, tts_mintuple points to the actual MinimalTupleData - * object (the thing to be pfree'd if tts_shouldFreeMin is true). If the slot - * has only a minimal and not also a regular physical tuple, then tts_tuple - * points at tts_minhdr and the fields of that struct are set correctly - * for access to the minimal tuple; in particular, tts_minhdr.t_data points - * MINIMAL_TUPLE_OFFSET bytes before tts_mintuple. This allows column - * extraction to treat the case identically to regular physical tuples. - * - * tts_slow/tts_off are saved state for slot_deform_tuple, and should not - * be touched by any other code. + * When TTS_SHOULDFREE is set in tts_flags, the physical tuple is "owned" by + * the slot and should be freed when the slot's reference to the tuple is + * dropped. + * + * tts_values/tts_isnull are allocated either when the slot is created (when + * the descriptor is provided), or when a descriptor is assigned to the slot; + * they are of length equal to the descriptor's natts. + * + * The TTS_FLAG_SLOW flag is saved state for + * slot_deform_heap_tuple, and should not be touched by any other code. *---------- */ + +/* true = slot is empty */ +#define TTS_FLAG_EMPTY (1 << 1) +#define TTS_EMPTY(slot) (((slot)->tts_flags & TTS_FLAG_EMPTY) != 0) + +/* should pfree tuple "owned" by the slot? */ +#define TTS_FLAG_SHOULDFREE (1 << 2) +#define TTS_SHOULDFREE(slot) (((slot)->tts_flags & TTS_FLAG_SHOULDFREE) != 0) + +/* saved state for slot_deform_heap_tuple */ +#define TTS_FLAG_SLOW (1 << 3) +#define TTS_SLOW(slot) (((slot)->tts_flags & TTS_FLAG_SLOW) != 0) + +/* fixed tuple descriptor */ +#define TTS_FLAG_FIXED (1 << 4) +#define TTS_FIXED(slot) (((slot)->tts_flags & TTS_FLAG_FIXED) != 0) + +struct TupleTableSlotOps; +typedef struct TupleTableSlotOps TupleTableSlotOps; + +/* base tuple table slot type */ typedef struct TupleTableSlot { NodeTag type; - bool tts_isempty; /* true = slot is empty */ - bool tts_shouldFree; /* should pfree tts_tuple? */ - bool tts_shouldFreeMin; /* should pfree tts_mintuple? */ -#define FIELDNO_TUPLETABLESLOT_SLOW 4 - bool tts_slow; /* saved state for slot_deform_tuple */ -#define FIELDNO_TUPLETABLESLOT_TUPLE 5 - HeapTuple tts_tuple; /* physical tuple, or NULL if virtual */ -#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 6 +#define FIELDNO_TUPLETABLESLOT_FLAGS 1 + uint16 tts_flags; /* Boolean states */ +#define FIELDNO_TUPLETABLESLOT_NVALID 2 + AttrNumber tts_nvalid; /* # of valid values in tts_values */ + const TupleTableSlotOps *const tts_ops; /* implementation of slot */ +#define FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR 4 TupleDesc tts_tupleDescriptor; /* slot's tuple descriptor */ - MemoryContext tts_mcxt; /* slot itself is in this context */ - Buffer tts_buffer; /* tuple's buffer, or InvalidBuffer */ -#define FIELDNO_TUPLETABLESLOT_NVALID 9 - int tts_nvalid; /* # of valid values in tts_values */ -#define FIELDNO_TUPLETABLESLOT_VALUES 10 +#define FIELDNO_TUPLETABLESLOT_VALUES 5 Datum *tts_values; /* current per-attribute values */ -#define FIELDNO_TUPLETABLESLOT_ISNULL 11 +#define FIELDNO_TUPLETABLESLOT_ISNULL 6 bool *tts_isnull; /* current per-attribute isnull flags */ - MinimalTuple tts_mintuple; /* minimal tuple, or NULL if none */ - HeapTupleData tts_minhdr; /* workspace for minimal-tuple-only case */ -#define FIELDNO_TUPLETABLESLOT_OFF 14 - uint32 tts_off; /* saved state for slot_deform_tuple */ - bool tts_fixedTupleDescriptor; /* descriptor can't be changed */ + MemoryContext tts_mcxt; /* slot itself is in this context */ + ItemPointerData tts_tid; /* stored tuple's tid */ + Oid tts_tableOid; /* table oid of tuple */ } TupleTableSlot; -#define TTS_HAS_PHYSICAL_TUPLE(slot) \ - ((slot)->tts_tuple != NULL && (slot)->tts_tuple != &((slot)->tts_minhdr)) +/* routines for a TupleTableSlot implementation */ +struct TupleTableSlotOps +{ + /* Minimum size of the slot */ + size_t base_slot_size; + + /* Initialization. */ + void (*init) (TupleTableSlot *slot); + + /* Destruction. */ + void (*release) (TupleTableSlot *slot); + + /* + * Clear the contents of the slot. Only the contents are expected to be + * cleared and not the tuple descriptor. Typically an implementation of + * this callback should free the memory allocated for the tuple contained + * in the slot. + */ + void (*clear) (TupleTableSlot *slot); + + /* + * Fill up first natts entries of tts_values and tts_isnull arrays with + * values from the tuple contained in the slot. The function may be called + * with natts more than the number of attributes available in the tuple, + * in which case it should set tts_nvalid to the number of returned + * columns. + */ + void (*getsomeattrs) (TupleTableSlot *slot, int natts); + + /* + * Returns value of the given system attribute as a datum and sets isnull + * to false, if it's not NULL. Throws an error if the slot type does not + * support system attributes. + */ + Datum (*getsysattr) (TupleTableSlot *slot, int attnum, bool *isnull); + + /* + * Make the contents of the slot solely depend on the slot, and not on + * underlying resources (like another memory context, buffers, etc). + */ + void (*materialize) (TupleTableSlot *slot); + + /* + * Copy the contents of the source slot into the destination slot's own + * context. Invoked using callback of the destination slot. + */ + void (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot); + + /* + * Return a heap tuple "owned" by the slot. It is slot's responsibility to + * free the memory consumed by the heap tuple. If the slot can not "own" a + * heap tuple, it should not implement this callback and should set it as + * NULL. + */ + HeapTuple (*get_heap_tuple) (TupleTableSlot *slot); + + /* + * Return a minimal tuple "owned" by the slot. It is slot's responsibility + * to free the memory consumed by the minimal tuple. If the slot can not + * "own" a minimal tuple, it should not implement this callback and should + * set it as NULL. + */ + MinimalTuple (*get_minimal_tuple) (TupleTableSlot *slot); + + /* + * Return a copy of heap tuple representing the contents of the slot. The + * copy needs to be palloc'd in the current memory context. The slot + * itself is expected to remain unaffected. It is *not* expected to have + * meaningful "system columns" in the copy. The copy is not be "owned" by + * the slot i.e. the caller has to take responsibility to free memory + * consumed by the slot. + */ + HeapTuple (*copy_heap_tuple) (TupleTableSlot *slot); + + /* + * Return a copy of minimal tuple representing the contents of the slot. + * The copy needs to be palloc'd in the current memory context. The slot + * itself is expected to remain unaffected. It is *not* expected to have + * meaningful "system columns" in the copy. The copy is not be "owned" by + * the slot i.e. the caller has to take responsibility to free memory + * consumed by the slot. + */ + MinimalTuple (*copy_minimal_tuple) (TupleTableSlot *slot); +}; + +/* + * Predefined TupleTableSlotOps for various types of TupleTableSlotOps. The + * same are used to identify the type of a given slot. + */ +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsVirtual; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsHeapTuple; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsMinimalTuple; +extern PGDLLIMPORT const TupleTableSlotOps TTSOpsBufferHeapTuple; + +#define TTS_IS_VIRTUAL(slot) ((slot)->tts_ops == &TTSOpsVirtual) +#define TTS_IS_HEAPTUPLE(slot) ((slot)->tts_ops == &TTSOpsHeapTuple) +#define TTS_IS_MINIMALTUPLE(slot) ((slot)->tts_ops == &TTSOpsMinimalTuple) +#define TTS_IS_BUFFERTUPLE(slot) ((slot)->tts_ops == &TTSOpsBufferHeapTuple) + + +/* + * Tuple table slot implementations. + */ + +typedef struct VirtualTupleTableSlot +{ + TupleTableSlot base; + + char *data; /* data for materialized slots */ +} VirtualTupleTableSlot; + +typedef struct HeapTupleTableSlot +{ + TupleTableSlot base; + +#define FIELDNO_HEAPTUPLETABLESLOT_TUPLE 1 + HeapTuple tuple; /* physical tuple */ +#define FIELDNO_HEAPTUPLETABLESLOT_OFF 2 + uint32 off; /* saved state for slot_deform_heap_tuple */ + HeapTupleData tupdata; /* optional workspace for storing tuple */ +} HeapTupleTableSlot; + +/* heap tuple residing in a buffer */ +typedef struct BufferHeapTupleTableSlot +{ + HeapTupleTableSlot base; + + /* + * If buffer is not InvalidBuffer, then the slot is holding a pin on the + * indicated buffer page; drop the pin when we release the slot's + * reference to that buffer. (TTS_FLAG_SHOULDFREE should not be set be + * false in such a case, since presumably tts_tuple is pointing at the + * buffer page.) + */ + Buffer buffer; /* tuple's buffer, or InvalidBuffer */ +} BufferHeapTupleTableSlot; + +typedef struct MinimalTupleTableSlot +{ + TupleTableSlot base; + + /* + * In a minimal slot tuple points at minhdr and the fields of that struct + * are set correctly for access to the minimal tuple; in particular, + * minhdr.t_data points MINIMAL_TUPLE_OFFSET bytes before mintuple. This + * allows column extraction to treat the case identically to regular + * physical tuples. + */ +#define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE 1 + HeapTuple tuple; /* tuple wrapper */ + MinimalTuple mintuple; /* minimal tuple, or NULL if none */ + HeapTupleData minhdr; /* workspace for minimal-tuple-only case */ +#define FIELDNO_MINIMALTUPLETABLESLOT_OFF 4 + uint32 off; /* saved state for slot_deform_heap_tuple */ +} MinimalTupleTableSlot; /* * TupIsNull -- is a TupleTableSlot empty? */ #define TupIsNull(slot) \ - ((slot) == NULL || (slot)->tts_isempty) + ((slot) == NULL || TTS_EMPTY(slot)) /* in executor/execTuples.c */ -extern TupleTableSlot *MakeTupleTableSlot(TupleDesc desc); -extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc); +extern TupleTableSlot *MakeTupleTableSlot(TupleDesc tupleDesc, + const TupleTableSlotOps *tts_ops); +extern TupleTableSlot *ExecAllocTableSlot(List **tupleTable, TupleDesc desc, + const TupleTableSlotOps *tts_ops); extern void ExecResetTupleTable(List *tupleTable, bool shouldFree); -extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc); +extern TupleTableSlot *MakeSingleTupleTableSlot(TupleDesc tupdesc, + const TupleTableSlotOps *tts_ops); extern void ExecDropSingleTupleTableSlot(TupleTableSlot *slot); extern void ExecSetSlotDescriptor(TupleTableSlot *slot, TupleDesc tupdesc); -extern TupleTableSlot *ExecStoreTuple(HeapTuple tuple, - TupleTableSlot *slot, - Buffer buffer, - bool shouldFree); +extern TupleTableSlot *ExecStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree); +extern void ExecForceStoreHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + bool shouldFree); +extern TupleTableSlot *ExecStoreBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer); +extern TupleTableSlot *ExecStorePinnedBufferHeapTuple(HeapTuple tuple, + TupleTableSlot *slot, + Buffer buffer); extern TupleTableSlot *ExecStoreMinimalTuple(MinimalTuple mtup, - TupleTableSlot *slot, - bool shouldFree); -extern TupleTableSlot *ExecClearTuple(TupleTableSlot *slot); + TupleTableSlot *slot, + bool shouldFree); +extern void ExecForceStoreMinimalTuple(MinimalTuple mtup, TupleTableSlot *slot, + bool shouldFree); extern TupleTableSlot *ExecStoreVirtualTuple(TupleTableSlot *slot); extern TupleTableSlot *ExecStoreAllNullTuple(TupleTableSlot *slot); -extern HeapTuple ExecCopySlotTuple(TupleTableSlot *slot); -extern MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot *slot); -extern HeapTuple ExecFetchSlotTuple(TupleTableSlot *slot); -extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot); -extern Datum ExecFetchSlotTupleDatum(TupleTableSlot *slot); -extern HeapTuple ExecMaterializeSlot(TupleTableSlot *slot); -extern TupleTableSlot *ExecCopySlot(TupleTableSlot *dstslot, - TupleTableSlot *srcslot); - -/* in access/common/heaptuple.c */ -extern Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull); -extern void slot_getallattrs(TupleTableSlot *slot); -extern void slot_getsomeattrs(TupleTableSlot *slot, int attnum); -extern bool slot_attisnull(TupleTableSlot *slot, int attnum); -extern bool slot_getsysattr(TupleTableSlot *slot, int attnum, - Datum *value, bool *isnull); -extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, int lastAttNum); +extern void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot); +extern HeapTuple ExecFetchSlotHeapTuple(TupleTableSlot *slot, bool materialize, bool *shouldFree); +extern MinimalTuple ExecFetchSlotMinimalTuple(TupleTableSlot *slot, + bool *shouldFree); +extern Datum ExecFetchSlotHeapTupleDatum(TupleTableSlot *slot); +extern void slot_getmissingattrs(TupleTableSlot *slot, int startAttNum, + int lastAttNum); +extern void slot_getsomeattrs_int(TupleTableSlot *slot, int attnum); + + +#ifndef FRONTEND + +/* + * This function forces the entries of the slot's Datum/isnull arrays to be + * valid at least up through the attnum'th entry. + */ +static inline void +slot_getsomeattrs(TupleTableSlot *slot, int attnum) +{ + if (slot->tts_nvalid < attnum) + slot_getsomeattrs_int(slot, attnum); +} + +/* + * slot_getallattrs + * This function forces all the entries of the slot's Datum/isnull + * arrays to be valid. The caller may then extract data directly + * from those arrays instead of using slot_getattr. + */ +static inline void +slot_getallattrs(TupleTableSlot *slot) +{ + slot_getsomeattrs(slot, slot->tts_tupleDescriptor->natts); +} + + +/* + * slot_attisnull + * + * Detect whether an attribute of the slot is null, without actually fetching + * it. + */ +static inline bool +slot_attisnull(TupleTableSlot *slot, int attnum) +{ + AssertArg(attnum > 0); + + if (attnum > slot->tts_nvalid) + slot_getsomeattrs(slot, attnum); + + return slot->tts_isnull[attnum - 1]; +} + +/* + * slot_getattr - fetch one attribute of the slot's contents. + */ +static inline Datum +slot_getattr(TupleTableSlot *slot, int attnum, + bool *isnull) +{ + AssertArg(attnum > 0); + + if (attnum > slot->tts_nvalid) + slot_getsomeattrs(slot, attnum); + + *isnull = slot->tts_isnull[attnum - 1]; + + return slot->tts_values[attnum - 1]; +} + +/* + * slot_getsysattr - fetch a system attribute of the slot's current tuple. + * + * If the slot type does not contain system attributes, this will throw an + * error. Hence before calling this function, callers should make sure that + * the slot type is the one that supports system attributes. + */ +static inline Datum +slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull) +{ + AssertArg(attnum < 0); /* caller error */ + + if (attnum == TableOidAttributeNumber) + { + *isnull = false; + return ObjectIdGetDatum(slot->tts_tableOid); + } + else if (attnum == SelfItemPointerAttributeNumber) + { + *isnull = false; + return PointerGetDatum(&slot->tts_tid); + } + + /* Fetch the system attribute from the underlying tuple. */ + return slot->tts_ops->getsysattr(slot, attnum, isnull); +} + +/* + * ExecClearTuple - clear the slot's contents + */ +static inline TupleTableSlot * +ExecClearTuple(TupleTableSlot *slot) +{ + slot->tts_ops->clear(slot); + + return slot; +} + +/* ExecMaterializeSlot - force a slot into the "materialized" state. + * + * This causes the slot's tuple to be a local copy not dependent on any + * external storage (i.e. pointing into a Buffer, or having allocations in + * another memory context). + * + * A typical use for this operation is to prepare a computed tuple for being + * stored on disk. The original data may or may not be virtual, but in any + * case we need a private copy for heap_insert to scribble on. + */ +static inline void +ExecMaterializeSlot(TupleTableSlot *slot) +{ + slot->tts_ops->materialize(slot); +} + +/* + * ExecCopySlotHeapTuple - return HeapTuple allocated in caller's context + */ +static inline HeapTuple +ExecCopySlotHeapTuple(TupleTableSlot *slot) +{ + Assert(!TTS_EMPTY(slot)); + + return slot->tts_ops->copy_heap_tuple(slot); +} + +/* + * ExecCopySlotMinimalTuple - return MinimalTuple allocated in caller's context + */ +static inline MinimalTuple +ExecCopySlotMinimalTuple(TupleTableSlot *slot) +{ + return slot->tts_ops->copy_minimal_tuple(slot); +} + +/* + * ExecCopySlot - copy one slot's contents into another. + * + * If a source's system attributes are supposed to be accessed in the target + * slot, the target slot and source slot types need to match. + */ +static inline TupleTableSlot * +ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot) +{ + Assert(!TTS_EMPTY(srcslot)); + + dstslot->tts_ops->copyslot(dstslot, srcslot); + + return dstslot; +} + +#endif /* FRONTEND */ #endif /* TUPTABLE_H */ diff --git a/src/include/fe_utils/conditional.h b/src/include/fe_utils/conditional.h index 15162071976..7faa74e7be9 100644 --- a/src/include/fe_utils/conditional.h +++ b/src/include/fe_utils/conditional.h @@ -5,8 +5,8 @@ * allow a manage nested conditionals. * * It is used by: - * - "psql" interpretor for handling \if ... \endif - * - "pgbench" interpretor for handling \if ... \endif + * - "psql" interpreter for handling \if ... \endif + * - "pgbench" interpreter for handling \if ... \endif * - "pgbench" syntax checker to test for proper nesting * * The stack holds the state of enclosing conditionals (are we in @@ -14,7 +14,7 @@ * a true branch?) so that the interpreter knows whether to execute * code and whether to evaluate conditions. * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/include/fe_utils/conditional.h * @@ -75,7 +75,7 @@ extern ConditionalStack conditional_stack_create(void); extern void conditional_stack_destroy(ConditionalStack cstack); -extern int conditional_stack_depth(ConditionalStack cstack); +extern int conditional_stack_depth(ConditionalStack cstack); extern void conditional_stack_push(ConditionalStack cstack, ifState new_state); diff --git a/src/include/fe_utils/connect.h b/src/include/fe_utils/connect.h index fa293d2458d..c1c8c04ab02 100644 --- a/src/include/fe_utils/connect.h +++ b/src/include/fe_utils/connect.h @@ -3,7 +3,7 @@ * Interfaces in support of FE/BE connections. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/connect.h @@ -23,6 +23,6 @@ * might work with the old server, skip this. */ #define ALWAYS_SECURE_SEARCH_PATH_SQL \ - "SELECT pg_catalog.set_config('search_path', '', false)" + "SELECT pg_catalog.set_config('search_path', '', false);" #endif /* CONNECT_H */ diff --git a/src/include/fe_utils/mbprint.h b/src/include/fe_utils/mbprint.h index 7d8019c203d..97f0a590e8d 100644 --- a/src/include/fe_utils/mbprint.h +++ b/src/include/fe_utils/mbprint.h @@ -3,7 +3,7 @@ * Multibyte character printing support for frontend code * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/mbprint.h @@ -22,8 +22,8 @@ struct lineptr extern unsigned char *mbvalidate(unsigned char *pwcs, int encoding); extern int pg_wcswidth(const char *pwcs, size_t len, int encoding); extern void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, - struct lineptr *lines, int count); + struct lineptr *lines, int count); extern void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, - int *width, int *height, int *format_size); + int *width, int *height, int *format_size); #endif /* MBPRINT_H */ diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h index 83320d06bdd..f138d963d3f 100644 --- a/src/include/fe_utils/print.h +++ b/src/include/fe_utils/print.h @@ -3,7 +3,7 @@ * Query-result printing support for frontend code * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/print.h @@ -26,14 +26,15 @@ enum printFormat { PRINT_NOTHING = 0, /* to make sure someone initializes this */ - PRINT_UNALIGNED, PRINT_ALIGNED, - PRINT_WRAPPED, - PRINT_HTML, PRINT_ASCIIDOC, + PRINT_CSV, + PRINT_HTML, PRINT_LATEX, PRINT_LATEX_LONGTABLE, - PRINT_TROFF_MS + PRINT_TROFF_MS, + PRINT_UNALIGNED, + PRINT_WRAPPED /* add your favourite output format here ... */ }; @@ -112,6 +113,7 @@ typedef struct printTableOpt const printTextFormat *line_style; /* line style (NULL for default) */ struct separator fieldSep; /* field separator for unaligned text mode */ struct separator recordSep; /* record separator for unaligned text mode */ + char csvFieldSep[2]; /* field separator for csv format */ bool numericLocale; /* locale-aware numeric units separator and * decimal marker */ char *tableAttr; /* attributes for HTML
*/ @@ -190,21 +192,21 @@ extern void ClosePager(FILE *pagerpipe); extern void html_escaped_print(const char *in, FILE *fout); extern void printTableInit(printTableContent *const content, - const printTableOpt *opt, const char *title, - const int ncolumns, const int nrows); + const printTableOpt *opt, const char *title, + const int ncolumns, const int nrows); extern void printTableAddHeader(printTableContent *const content, - char *header, const bool translate, const char align); + char *header, const bool translate, const char align); extern void printTableAddCell(printTableContent *const content, - char *cell, const bool translate, const bool mustfree); + char *cell, const bool translate, const bool mustfree); extern void printTableAddFooter(printTableContent *const content, - const char *footer); + const char *footer); extern void printTableSetFooter(printTableContent *const content, - const char *footer); + const char *footer); extern void printTableCleanup(printTableContent *const content); extern void printTable(const printTableContent *cont, - FILE *fout, bool is_pager, FILE *flog); + FILE *fout, bool is_pager, FILE *flog); extern void printQuery(const PGresult *result, const printQueryOpt *opt, - FILE *fout, bool is_pager, FILE *flog); + FILE *fout, bool is_pager, FILE *flog); extern char column_type_alignment(Oid); diff --git a/src/include/fe_utils/psqlscan.h b/src/include/fe_utils/psqlscan.h index 2d58c071f37..dd2ebcb01d9 100644 --- a/src/include/fe_utils/psqlscan.h +++ b/src/include/fe_utils/psqlscan.h @@ -10,7 +10,7 @@ * backslash commands. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/psqlscan.h @@ -64,13 +64,6 @@ typedef struct PsqlScanCallbacks /* This pointer can be NULL if no variable substitution is wanted */ char *(*get_variable) (const char *varname, PsqlScanQuoteType quote, void *passthrough); - /* Print an error message someplace appropriate */ - /* (very old gcc versions don't support attributes on function pointers) */ -#if defined(__GNUC__) && __GNUC__ < 4 - void (*write_error) (const char *fmt,...); -#else - void (*write_error) (const char *fmt,...) pg_attribute_printf(1, 2); -#endif } PsqlScanCallbacks; @@ -80,13 +73,13 @@ extern void psql_scan_destroy(PsqlScanState state); extern void psql_scan_set_passthrough(PsqlScanState state, void *passthrough); extern void psql_scan_setup(PsqlScanState state, - const char *line, int line_len, - int encoding, bool std_strings); + const char *line, int line_len, + int encoding, bool std_strings); extern void psql_scan_finish(PsqlScanState state); extern PsqlScanResult psql_scan(PsqlScanState state, - PQExpBuffer query_buf, - promptStatus_t *prompt); + PQExpBuffer query_buf, + promptStatus_t *prompt); extern void psql_scan_reset(PsqlScanState state); diff --git a/src/include/fe_utils/psqlscan_int.h b/src/include/fe_utils/psqlscan_int.h index 0be0db69ab7..c538ece1975 100644 --- a/src/include/fe_utils/psqlscan_int.h +++ b/src/include/fe_utils/psqlscan_int.h @@ -27,14 +27,14 @@ * is the start state number, which is easy enough to manage --- usually, * in fact, we just need to set it to INITIAL when changing lexers. But to * make that work at all, we must use re-entrant lexers, so that all the - * relevant state is in the yyscanner_t attached to the PsqlScanState; + * relevant state is in the yyscan_t attached to the PsqlScanState; * if we were using lexers with separate static state we would soon end up * with dangling buffer pointers in one or the other. Also note that this * is unlikely to work very nicely if the lexers aren't all built with the * same flex version, or if they don't use the same flex options. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/psqlscan_int.h @@ -128,21 +128,21 @@ typedef struct PsqlScanStateData * compatible lexers. */ extern void psqlscan_push_new_buffer(PsqlScanState state, - const char *newstr, const char *varname); + const char *newstr, const char *varname); extern void psqlscan_pop_buffer_stack(PsqlScanState state); extern void psqlscan_select_top_buffer(PsqlScanState state); extern bool psqlscan_var_is_current_source(PsqlScanState state, - const char *varname); + const char *varname); extern YY_BUFFER_STATE psqlscan_prepare_buffer(PsqlScanState state, - const char *txt, int len, - char **txtcopy); + const char *txt, int len, + char **txtcopy); extern void psqlscan_emit(PsqlScanState state, const char *txt, int len); extern char *psqlscan_extract_substring(PsqlScanState state, - const char *txt, int len); + const char *txt, int len); extern void psqlscan_escape_variable(PsqlScanState state, - const char *txt, int len, - PsqlScanQuoteType quote); + const char *txt, int len, + PsqlScanQuoteType quote); extern void psqlscan_test_variable(PsqlScanState state, - const char *txt, int len); + const char *txt, int len); #endif /* PSQLSCAN_INT_H */ diff --git a/src/include/fe_utils/recovery_gen.h b/src/include/fe_utils/recovery_gen.h new file mode 100644 index 00000000000..8b15307dfb8 --- /dev/null +++ b/src/include/fe_utils/recovery_gen.h @@ -0,0 +1,28 @@ +/*------------------------------------------------------------------------- + * + * Generator for recovery configuration + * + * Portions Copyright (c) 2011-2019, PostgreSQL Global Development Group + * + * src/include/fe_utils/recovery_gen.h + * + *------------------------------------------------------------------------- + */ +#ifndef RECOVERY_GEN_H +#define RECOVERY_GEN_H + +#include "libpq-fe.h" +#include "pqexpbuffer.h" + +/* + * recovery configuration is part of postgresql.conf in version 12 and up, and + * in recovery.conf before that. + */ +#define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000 + +extern PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, + char *pg_replication_slot); +extern void WriteRecoveryConfig(PGconn *pgconn, char *target_dir, + PQExpBuffer contents); + +#endif /* RECOVERY_GEN_H */ diff --git a/src/include/fe_utils/simple_list.h b/src/include/fe_utils/simple_list.h index 9785489128c..75738becf42 100644 --- a/src/include/fe_utils/simple_list.h +++ b/src/include/fe_utils/simple_list.h @@ -7,7 +7,7 @@ * it's all we need in, eg, pg_dump. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/simple_list.h @@ -46,9 +46,11 @@ typedef struct SimpleStringList extern void simple_oid_list_append(SimpleOidList *list, Oid val); extern bool simple_oid_list_member(SimpleOidList *list, Oid val); +extern void simple_oid_list_destroy(SimpleOidList *list); extern void simple_string_list_append(SimpleStringList *list, const char *val); extern bool simple_string_list_member(SimpleStringList *list, const char *val); +extern void simple_string_list_destroy(SimpleStringList *list); extern const char *simple_string_list_not_touched(SimpleStringList *list); diff --git a/src/include/fe_utils/string_utils.h b/src/include/fe_utils/string_utils.h index 9a311e0f0fa..8c13cc0a66d 100644 --- a/src/include/fe_utils/string_utils.h +++ b/src/include/fe_utils/string_utils.h @@ -6,7 +6,7 @@ * assorted contexts. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fe_utils/string_utils.h @@ -25,21 +25,20 @@ extern PQExpBuffer (*getLocalPQExpBuffer) (void); /* Functions */ extern const char *fmtId(const char *identifier); -extern const char *fmtQualifiedId(int remoteVersion, - const char *schema, const char *id); +extern const char *fmtQualifiedId(const char *schema, const char *id); extern char *formatPGVersionNumber(int version_number, bool include_minor, - char *buf, size_t buflen); + char *buf, size_t buflen); extern void appendStringLiteral(PQExpBuffer buf, const char *str, - int encoding, bool std_strings); + int encoding, bool std_strings); extern void appendStringLiteralConn(PQExpBuffer buf, const char *str, - PGconn *conn); + PGconn *conn); extern void appendStringLiteralDQ(PQExpBuffer buf, const char *str, - const char *dqprefix); + const char *dqprefix); extern void appendByteaLiteral(PQExpBuffer buf, - const unsigned char *str, size_t length, - bool std_strings); + const unsigned char *str, size_t length, + bool std_strings); extern void appendShellString(PQExpBuffer buf, const char *str); extern bool appendShellStringNoError(PQExpBuffer buf, const char *str); @@ -49,12 +48,12 @@ extern void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname); extern bool parsePGArray(const char *atext, char ***itemarray, int *nitems); extern bool appendReloptionsArray(PQExpBuffer buffer, const char *reloptions, - const char *prefix, int encoding, bool std_strings); + const char *prefix, int encoding, bool std_strings); extern bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, - const char *pattern, - bool have_where, bool force_escape, - const char *schemavar, const char *namevar, - const char *altnamevar, const char *visibilityrule); + const char *pattern, + bool have_where, bool force_escape, + const char *schemavar, const char *namevar, + const char *altnamevar, const char *visibilityrule); #endif /* STRING_UTILS_H */ diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 101f513ba67..29ae4674cc7 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -8,7 +8,7 @@ * or call fmgr-callable functions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fmgr.h @@ -35,7 +35,7 @@ typedef struct StringInfoData *fmStringInfo; * signature.) */ -typedef struct FunctionCallInfoData *FunctionCallInfo; +typedef struct FunctionCallInfoBaseData *FunctionCallInfo; typedef Datum (*PGFunction) (FunctionCallInfo fcinfo); @@ -46,8 +46,8 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo); * info struct saved for re-use. * * Note that fn_expr really is parse-time-determined information about the - * arguments, rather than about the function itself. But it's convenient - * to store it here rather than in FunctionCallInfoData, where it might more + * arguments, rather than about the function itself. But it's convenient to + * store it here rather than in FunctionCallInfoBaseData, where it might more * logically belong. * * fn_extra is available for use by the called function; all other fields @@ -73,8 +73,16 @@ typedef struct FmgrInfo * 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.) + * + * Note that enough space for arguments needs to be provided, either by using + * SizeForFunctionCallInfo() in dynamic allocations, or by using + * LOCAL_FCINFO() for on-stack allocations. + * + * This struct is named *BaseData, rather than *Data, to break pre v12 code + * that allocated FunctionCallInfoData itself, as it'd often silently break + * old code due to no space for arguments being provided. */ -typedef struct FunctionCallInfoData +typedef struct FunctionCallInfoBaseData { FmgrInfo *flinfo; /* ptr to lookup info used for this call */ fmNodePtr context; /* pass info about context of call */ @@ -83,11 +91,31 @@ typedef struct FunctionCallInfoData #define FIELDNO_FUNCTIONCALLINFODATA_ISNULL 4 bool isnull; /* function must set true if result is NULL */ short nargs; /* # arguments actually passed */ -#define FIELDNO_FUNCTIONCALLINFODATA_ARG 6 - Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */ -#define FIELDNO_FUNCTIONCALLINFODATA_ARGNULL 7 - bool argnull[FUNC_MAX_ARGS]; /* T if arg[i] is actually NULL */ -} FunctionCallInfoData; +#define FIELDNO_FUNCTIONCALLINFODATA_ARGS 6 + NullableDatum args[FLEXIBLE_ARRAY_MEMBER]; +} FunctionCallInfoBaseData; + +/* + * Space needed for a FunctionCallInfoBaseData struct with sufficient space + * for `nargs` arguments. + */ +#define SizeForFunctionCallInfo(nargs) \ + (offsetof(FunctionCallInfoBaseData, args) + \ + sizeof(NullableDatum) * (nargs)) + +/* + * This macro ensures that `name` points to a stack-allocated + * FunctionCallInfoBaseData struct with sufficient space for `nargs` arguments. + */ +#define LOCAL_FCINFO(name, nargs) \ + /* use union with FunctionCallInfoBaseData to guarantee alignment */ \ + union \ + { \ + FunctionCallInfoBaseData fcinfo; \ + /* ensure enough space for nargs args is available */ \ + char fcinfo_data[SizeForFunctionCallInfo(nargs)]; \ + } name##data; \ + FunctionCallInfo name = &name##data.fcinfo /* * This routine fills a FmgrInfo struct, given the OID @@ -101,7 +129,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo); * and used to hold all subsidiary data of finfo. */ extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, - MemoryContext mcxt); + MemoryContext mcxt); /* Convenience macro for setting the fn_expr field */ #define fmgr_info_set_expr(expr, finfo) \ @@ -111,16 +139,13 @@ extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, * Copy an FmgrInfo struct */ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, - MemoryContext destcxt); + MemoryContext destcxt); extern void fmgr_symbol(Oid functionId, char **mod, char **fn); /* - * This macro initializes all the fields of a FunctionCallInfoData except - * for the arg[] and argnull[] arrays. Performance testing has shown that - * the fastest way to set up argnull[] for small numbers of arguments is to - * explicitly set each required element to false, so we don't try to zero - * out the argnull[] array in the macro. + * This macro initializes all the fields of a FunctionCallInfoBaseData except + * for the args[] array. */ #define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo) \ do { \ @@ -133,7 +158,7 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn); } while (0) /* - * This macro invokes a function given a filled-in FunctionCallInfoData + * This macro invokes a function given a filled-in FunctionCallInfoBaseData * struct. The macro result is the returned Datum --- but note that * caller must still check fcinfo->isnull! Also, if function is strict, * it is caller's responsibility to verify that no null arguments are present @@ -176,7 +201,7 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn); * If function is not marked "proisstrict" in pg_proc, it must check for * null arguments using this macro. Do not try to GETARG a null argument! */ -#define PG_ARGISNULL(n) (fcinfo->argnull[n]) +#define PG_ARGISNULL(n) (fcinfo->args[n].isnull) /* * Support for fetching detoasted copies of toastable datatypes (all of @@ -204,7 +229,7 @@ extern void fmgr_symbol(Oid functionId, char **mod, char **fn); extern struct varlena *pg_detoast_datum(struct varlena *datum); extern struct varlena *pg_detoast_datum_copy(struct varlena *datum); extern struct varlena *pg_detoast_datum_slice(struct varlena *datum, - int32 first, int32 count); + int32 first, int32 count); extern struct varlena *pg_detoast_datum_packed(struct varlena *datum); #define PG_DETOAST_DATUM(datum) \ @@ -235,7 +260,7 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena *datum); /* Macros for fetching arguments of standard types */ -#define PG_GETARG_DATUM(n) (fcinfo->arg[n]) +#define PG_GETARG_DATUM(n) (fcinfo->args[n].value) #define PG_GETARG_INT32(n) DatumGetInt32(PG_GETARG_DATUM(n)) #define PG_GETARG_UINT32(n) DatumGetUInt32(PG_GETARG_DATUM(n)) #define PG_GETARG_INT16(n) DatumGetInt16(PG_GETARG_DATUM(n)) @@ -464,38 +489,39 @@ extern int no_such_variable /* These are for invocation of a specifically named function with a * directly-computed parameter list. Note that neither arguments nor result - * are allowed to be NULL. + * are allowed to be NULL. Also, the function cannot be one that needs to + * look at FmgrInfo, since there won't be any. */ extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation, - Datum arg1); + Datum arg1); extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2); + Datum arg1, Datum arg2); extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); + Datum arg1, Datum arg2, + Datum arg3); extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); /* * These functions work like the DirectFunctionCall functions except that @@ -506,44 +532,45 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, * 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); + Oid collation, Datum arg1); extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, - Oid collation, Datum arg1, Datum arg2); + 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. */ +extern Datum FunctionCall0Coll(FmgrInfo *flinfo, Oid collation); extern Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1); + Datum arg1); extern Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2); + Datum arg1, Datum arg2); extern Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); + Datum arg1, Datum arg2, + Datum arg3); extern Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); extern Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); extern Datum FunctionCall6Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); extern Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); extern Datum FunctionCall8Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); /* These are for invocation of a function identified by OID with a * directly-computed parameter list. Note that neither arguments nor result @@ -553,35 +580,35 @@ extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation, */ extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation); extern Datum OidFunctionCall1Coll(Oid functionId, Oid collation, - Datum arg1); + Datum arg1); extern Datum OidFunctionCall2Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2); + Datum arg1, Datum arg2); extern Datum OidFunctionCall3Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3); + Datum arg1, Datum arg2, + Datum arg3); extern Datum OidFunctionCall4Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4); extern Datum OidFunctionCall5Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5); extern Datum OidFunctionCall6Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6); extern Datum OidFunctionCall7Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7); extern Datum OidFunctionCall8Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8); extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation, - Datum arg1, Datum arg2, - Datum arg3, Datum arg4, Datum arg5, - Datum arg6, Datum arg7, Datum arg8, - Datum arg9); + Datum arg1, Datum arg2, + Datum arg3, Datum arg4, Datum arg5, + Datum arg6, Datum arg7, Datum arg8, + Datum arg9); /* These macros allow the collation argument to be omitted (with a default of * InvalidOid, ie, no collation). They exist mostly for backwards @@ -647,15 +674,15 @@ extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation, /* Special cases for convenient invocation of datatype I/O functions. */ extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str, - Oid typioparam, int32 typmod); + Oid typioparam, int32 typmod); extern Datum OidInputFunctionCall(Oid functionId, char *str, - Oid typioparam, int32 typmod); + Oid typioparam, int32 typmod); extern char *OutputFunctionCall(FmgrInfo *flinfo, Datum val); extern char *OidOutputFunctionCall(Oid functionId, Datum val); extern Datum ReceiveFunctionCall(FmgrInfo *flinfo, fmStringInfo buf, - Oid typioparam, int32 typmod); + Oid typioparam, int32 typmod); extern Datum OidReceiveFunctionCall(Oid functionId, fmStringInfo buf, - Oid typioparam, int32 typmod); + Oid typioparam, int32 typmod); extern bytea *SendFunctionCall(FmgrInfo *flinfo, Datum val); extern bytea *OidSendFunctionCall(Oid functionId, Datum val); @@ -680,7 +707,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid); extern char *Dynamic_library_path; extern PGFunction load_external_function(const char *filename, const char *funcname, - bool signalNotFound, void **filehandle); + bool signalNotFound, void **filehandle); 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); @@ -699,14 +726,14 @@ extern void RestoreLibraryState(char *start_address); #define AGG_CONTEXT_AGGREGATE 1 /* regular aggregate */ #define AGG_CONTEXT_WINDOW 2 /* window function */ -extern int AggCheckCallContext(FunctionCallInfo fcinfo, - MemoryContext *aggcontext); +extern int AggCheckCallContext(FunctionCallInfo fcinfo, + MemoryContext *aggcontext); extern fmAggrefPtr AggGetAggref(FunctionCallInfo fcinfo); extern MemoryContext AggGetTempMemoryContext(FunctionCallInfo fcinfo); extern bool AggStateIsShared(FunctionCallInfo fcinfo); extern void AggRegisterCallback(FunctionCallInfo fcinfo, - fmExprContextCallbackFunction func, - Datum arg); + fmExprContextCallbackFunction func, + Datum arg); /* * We allow plugin modules to hook function entry/exit. This is intended diff --git a/src/include/foreign/fdwapi.h b/src/include/foreign/fdwapi.h index c14eb546c64..822686033e4 100644 --- a/src/include/foreign/fdwapi.h +++ b/src/include/foreign/fdwapi.h @@ -3,7 +3,7 @@ * fdwapi.h * API for foreign-data wrappers * - * Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Copyright (c) 2010-2019, PostgreSQL Global Development Group * * src/include/foreign/fdwapi.h * @@ -14,7 +14,7 @@ #include "access/parallel.h" #include "nodes/execnodes.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" /* To avoid including explain.h here, reference ExplainState thus: */ struct ExplainState; @@ -121,10 +121,11 @@ typedef void (*EndDirectModify_function) (ForeignScanState *node); typedef RowMarkType (*GetForeignRowMarkType_function) (RangeTblEntry *rte, LockClauseStrength strength); -typedef HeapTuple (*RefetchForeignRow_function) (EState *estate, - ExecRowMark *erm, - Datum rowid, - bool *updated); +typedef void (*RefetchForeignRow_function) (EState *estate, + ExecRowMark *erm, + Datum rowid, + TupleTableSlot *slot, + bool *updated); typedef void (*ExplainForeignScan_function) (ForeignScanState *node, struct ExplainState *es); @@ -255,7 +256,7 @@ extern FdwRoutine *GetFdwRoutineByServerId(Oid serverid); extern FdwRoutine *GetFdwRoutineByRelId(Oid relid); extern FdwRoutine *GetFdwRoutineForRelation(Relation relation, bool makecopy); extern bool IsImportableForeignTable(const char *tablename, - ImportForeignSchemaStmt *stmt); + ImportForeignSchemaStmt *stmt); extern Path *GetExistingLocalJoinPath(RelOptInfo *joinrel); #endif /* FDWAPI_H */ diff --git a/src/include/foreign/foreign.h b/src/include/foreign/foreign.h index 3ca12e64d27..4de157c19cb 100644 --- a/src/include/foreign/foreign.h +++ b/src/include/foreign/foreign.h @@ -4,7 +4,7 @@ * support for foreign-data wrappers, servers and user mappings. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/foreign/foreign.h * @@ -21,17 +21,6 @@ (OidIsValid(userid) ? GetUserNameFromId(userid, false) : "public") -/* - * Generic option types for validation. - * NB! These are treated as flags, so use only powers of two here. - */ -typedef enum -{ - ServerOpt = 1, /* options applicable to SERVER */ - UserMappingOpt = 2, /* options for USER MAPPING */ - FdwOpt = 4 /* options for FOREIGN DATA WRAPPER */ -} GenericOptionFlags; - typedef struct ForeignDataWrapper { Oid fdwid; /* FDW Oid */ @@ -68,13 +57,23 @@ typedef struct ForeignTable List *options; /* ftoptions as DefElem list */ } ForeignTable; +/* Flags for GetForeignServerExtended */ +#define FSV_MISSING_OK 0x01 + +/* Flags for GetForeignDataWrapperExtended */ +#define FDW_MISSING_OK 0x01 + extern ForeignServer *GetForeignServer(Oid serverid); +extern ForeignServer *GetForeignServerExtended(Oid serverid, + bits16 flags); extern ForeignServer *GetForeignServerByName(const char *name, bool missing_ok); extern UserMapping *GetUserMapping(Oid userid, Oid serverid); extern ForeignDataWrapper *GetForeignDataWrapper(Oid fdwid); +extern ForeignDataWrapper *GetForeignDataWrapperExtended(Oid fdwid, + bits16 flags); extern ForeignDataWrapper *GetForeignDataWrapperByName(const char *name, - bool missing_ok); + bool missing_ok); extern ForeignTable *GetForeignTable(Oid relid); extern List *GetForeignColumnOptions(Oid relid, AttrNumber attnum); diff --git a/src/include/funcapi.h b/src/include/funcapi.h index 01aa208c5ee..1a88b520877 100644 --- a/src/include/funcapi.h +++ b/src/include/funcapi.h @@ -8,7 +8,7 @@ * or call FUNCAPI-callable functions or macros. * * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * src/include/funcapi.h * @@ -74,14 +74,6 @@ typedef struct FuncCallContext */ uint64 max_calls; - /* - * OPTIONAL pointer to result slot - * - * This is obsolete and only present for backwards compatibility, viz, - * user-defined SRFs that use the deprecated TupleDescGetSlot(). - */ - TupleTableSlot *slot; - /* * OPTIONAL pointer to miscellaneous user-provided context information * @@ -162,35 +154,35 @@ typedef enum TypeFuncClass } TypeFuncClass; extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, - Oid *resultTypeId, - TupleDesc *resultTupleDesc); + Oid *resultTypeId, + TupleDesc *resultTupleDesc); extern TypeFuncClass get_expr_result_type(Node *expr, - Oid *resultTypeId, - TupleDesc *resultTupleDesc); + Oid *resultTypeId, + TupleDesc *resultTupleDesc); extern TypeFuncClass get_func_result_type(Oid functionId, - Oid *resultTypeId, - TupleDesc *resultTupleDesc); + Oid *resultTypeId, + TupleDesc *resultTupleDesc); extern TupleDesc get_expr_result_tupdesc(Node *expr, bool noError); extern bool resolve_polymorphic_argtypes(int numargs, Oid *argtypes, - char *argmodes, - Node *call_expr); + char *argmodes, + Node *call_expr); -extern int get_func_arg_info(HeapTuple procTup, - Oid **p_argtypes, char ***p_argnames, - char **p_argmodes); +extern int get_func_arg_info(HeapTuple procTup, + Oid **p_argtypes, char ***p_argnames, + char **p_argmodes); -extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes, - char ***arg_names); +extern int get_func_input_arg_names(Datum proargnames, Datum proargmodes, + char ***arg_names); extern int get_func_trftypes(HeapTuple procTup, Oid **p_trftypes); extern char *get_func_result_name(Oid functionId); extern TupleDesc build_function_result_tupdesc_d(char prokind, - Datum proallargtypes, - Datum proargmodes, - Datum proargnames); + Datum proallargtypes, + Datum proargmodes, + Datum proargnames); extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); @@ -221,8 +213,6 @@ extern TupleDesc build_function_result_tupdesc_t(HeapTuple procTuple); * TupleDesc based on a named relation. * TupleDesc TypeGetTupleDesc(Oid typeoid, List *colaliases) - Use to get a * TupleDesc based on a type OID. - * TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc) - Builds a - * TupleTableSlot, which is not needed anymore. * TupleGetDatum(TupleTableSlot *slot, HeapTuple tuple) - get a Datum * given a tuple and a slot. *---------- @@ -240,7 +230,6 @@ extern TupleDesc BlessTupleDesc(TupleDesc tupdesc); extern AttInMetadata *TupleDescGetAttInMetadata(TupleDesc tupdesc); extern HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values); extern Datum HeapTupleHeaderGetDatum(HeapTupleHeader tuple); -extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc); /*---------- @@ -263,7 +252,7 @@ extern TupleTableSlot *TupleDescGetSlot(TupleDesc tupdesc); * oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); * * - * + * * * * // return to original context when allocating transient memory @@ -342,8 +331,8 @@ extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext *funcctx); * The return result is the number of elements stored, or -1 in the case of * "VARIADIC NULL". */ -extern int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, - bool convert_unknown, Datum **values, - Oid **types, bool **nulls); +extern int extract_variadic_args(FunctionCallInfo fcinfo, int variadic_start, + bool convert_unknown, Datum **values, + Oid **types, bool **nulls); #endif /* FUNCAPI_H */ diff --git a/src/include/getaddrinfo.h b/src/include/getaddrinfo.h index 1b460a3e5f2..34c728d98a6 100644 --- a/src/include/getaddrinfo.h +++ b/src/include/getaddrinfo.h @@ -13,7 +13,7 @@ * This code will also work on platforms where struct addrinfo is defined * in the system headers but no getaddrinfo() can be located. * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/getaddrinfo.h * @@ -150,13 +150,13 @@ struct addrinfo #endif #define getnameinfo pg_getnameinfo -extern int getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res); +extern int getaddrinfo(const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res); extern void freeaddrinfo(struct addrinfo *res); extern const char *gai_strerror(int errcode); -extern int getnameinfo(const struct sockaddr *sa, int salen, - char *node, int nodelen, - char *service, int servicelen, int flags); +extern int getnameinfo(const struct sockaddr *sa, int salen, + char *node, int nodelen, + char *service, int servicelen, int flags); #endif /* HAVE_GETADDRINFO */ #endif /* GETADDRINFO_H */ diff --git a/src/include/getopt_long.h b/src/include/getopt_long.h index a9013b40f79..02dc54783a5 100644 --- a/src/include/getopt_long.h +++ b/src/include/getopt_long.h @@ -2,7 +2,7 @@ * Portions Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * - * Portions Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/getopt_long.h */ @@ -28,9 +28,9 @@ struct option #ifndef HAVE_GETOPT_LONG -extern int getopt_long(int argc, char *const argv[], - const char *optstring, - const struct option *longopts, int *longindex); +extern int getopt_long(int argc, char *const argv[], + const char *optstring, + const struct option *longopts, int *longindex); #endif #endif /* GETOPT_LONG_H */ diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h index ddeffae2731..d879cef20f3 100644 --- a/src/include/jit/jit.h +++ b/src/include/jit/jit.h @@ -2,7 +2,7 @@ * jit.h * Provider independent JIT infrastructure. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/jit/jit.h * @@ -17,20 +17,15 @@ /* Flags determining what kind of JIT operations to perform */ #define PGJIT_NONE 0 -#define PGJIT_PERFORM 1 << 0 -#define PGJIT_OPT3 1 << 1 -#define PGJIT_INLINE 1 << 2 -#define PGJIT_EXPR 1 << 3 -#define PGJIT_DEFORM 1 << 4 +#define PGJIT_PERFORM (1 << 0) +#define PGJIT_OPT3 (1 << 1) +#define PGJIT_INLINE (1 << 2) +#define PGJIT_EXPR (1 << 3) +#define PGJIT_DEFORM (1 << 4) -typedef struct JitContext +typedef struct JitInstrumentation { - /* see PGJIT_* above */ - int flags; - - ResourceOwner resowner; - /* number of emitted functions */ size_t created_functions; @@ -45,6 +40,25 @@ typedef struct JitContext /* accumulated time for code emission */ instr_time emission_counter; +} JitInstrumentation; + +/* + * DSM structure for accumulating jit instrumentation of all workers. + */ +typedef struct SharedJitInstrumentation +{ + int num_workers; + JitInstrumentation jit_instr[FLEXIBLE_ARRAY_MEMBER]; +} SharedJitInstrumentation; + +typedef struct JitContext +{ + /* see PGJIT_* above */ + int flags; + + ResourceOwner resowner; + + JitInstrumentation instr; } JitContext; typedef struct JitProviderCallbacks JitProviderCallbacks; @@ -85,6 +99,7 @@ extern void jit_release_context(JitContext *context); * not be able to perform JIT (i.e. return false). */ extern bool jit_compile_expr(struct ExprState *state); +extern void InstrJitAgg(JitInstrumentation *dst, JitInstrumentation *add); #endif /* JIT_H */ diff --git a/src/include/jit/llvmjit.h b/src/include/jit/llvmjit.h index b0093db49d7..6178864b2e6 100644 --- a/src/include/jit/llvmjit.h +++ b/src/include/jit/llvmjit.h @@ -2,7 +2,7 @@ * llvmjit.h * LLVM JIT provider. * - * Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/jit/llvmjit.h * @@ -11,9 +11,11 @@ #ifndef LLVMJIT_H #define LLVMJIT_H -#ifndef USE_LLVM -#error "llvmjit.h should only be included by code dealing with llvm" -#endif +/* + * To avoid breaking cpluspluscheck, allow including the file even when LLVM + * is not available. + */ +#ifdef USE_LLVM #include @@ -62,9 +64,12 @@ extern LLVMTypeRef TypePGFunction; extern LLVMTypeRef TypeSizeT; extern LLVMTypeRef TypeStorageBool; -extern LLVMTypeRef StructtupleDesc; +extern LLVMTypeRef StructNullableDatum; +extern LLVMTypeRef StructTupleDescData; extern LLVMTypeRef StructHeapTupleData; extern LLVMTypeRef StructTupleTableSlot; +extern LLVMTypeRef StructHeapTupleTableSlot; +extern LLVMTypeRef StructMinimalTupleTableSlot; extern LLVMTypeRef StructMemoryContextData; extern LLVMTypeRef StructFunctionCallInfoData; extern LLVMTypeRef StructExprContext; @@ -77,11 +82,11 @@ extern LLVMTypeRef StructAggStatePerGroupData; extern LLVMValueRef AttributeTemplate; extern LLVMValueRef FuncStrlen; extern LLVMValueRef FuncVarsizeAny; -extern LLVMValueRef FuncSlotGetsomeattrs; extern LLVMValueRef FuncSlotGetmissingattrs; -extern LLVMValueRef FuncHeapGetsysattr; +extern LLVMValueRef FuncSlotGetsomeattrsInt; extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal; -extern LLVMValueRef FuncExecEvalArrayRefSubscript; +extern LLVMValueRef FuncExecEvalSubscriptingRef; +extern LLVMValueRef FuncExecEvalSysVar; extern LLVMValueRef FuncExecAggTransReparent; extern LLVMValueRef FuncExecAggInitGroup; @@ -111,7 +116,9 @@ extern void llvm_inline(LLVMModuleRef mod); **************************************************************************** */ extern bool llvm_compile_expr(struct ExprState *state); -extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDesc desc, int natts); +struct TupleTableSlotOps; +extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDesc desc, + const struct TupleTableSlotOps *ops, int natts); /* **************************************************************************** @@ -125,12 +132,15 @@ extern LLVMValueRef slot_compile_deform(struct LLVMJitContext *context, TupleDes extern char *LLVMGetHostCPUName(void); #endif +#if defined(HAVE_DECL_LLVMGETHOSTCPUFEATURES) && !HAVE_DECL_LLVMGETHOSTCPUFEATURES /** Get the host CPU features as a string. The result needs to be disposed with LLVMDisposeMessage. */ extern char *LLVMGetHostCPUFeatures(void); +#endif #ifdef __cplusplus } /* extern "C" */ #endif +#endif /* USE_LLVM */ #endif /* LLVMJIT_H */ diff --git a/src/include/jit/llvmjit_emit.h b/src/include/jit/llvmjit_emit.h index 0d1b246f42a..cdfa0dc7214 100644 --- a/src/include/jit/llvmjit_emit.h +++ b/src/include/jit/llvmjit_emit.h @@ -2,16 +2,23 @@ * llvmjit_emit.h * Helpers to make emitting LLVM IR a it more concise and pgindent proof. * - * Copyright (c) 2018, PostgreSQL Global Development Group + * Copyright (c) 2018-2019, PostgreSQL Global Development Group * * src/include/lib/llvmjit_emit.h */ #ifndef LLVMJIT_EMIT_H #define LLVMJIT_EMIT_H +/* + * To avoid breaking cpluspluscheck, allow including the file even when LLVM + * is not available. + */ +#ifdef USE_LLVM #include +#include "jit/llvmjit.h" + /* * Emit a non-LLVM pointer as an LLVM constant. @@ -208,4 +215,60 @@ l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc) return ret; } + +/* + * Return pointer to the argno'th argument nullness. + */ +static inline LLVMValueRef +l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + LLVMValueRef v_args; + LLVMValueRef v_argn; + + v_args = LLVMBuildStructGEP(b, + v_fcinfo, + FIELDNO_FUNCTIONCALLINFODATA_ARGS, + ""); + v_argn = LLVMBuildStructGEP(b, v_args, argno, ""); + + return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_ISNULL, ""); +} + +/* + * Return pointer to the argno'th argument datum. + */ +static inline LLVMValueRef +l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + LLVMValueRef v_args; + LLVMValueRef v_argn; + + v_args = LLVMBuildStructGEP(b, + v_fcinfo, + FIELDNO_FUNCTIONCALLINFODATA_ARGS, + ""); + v_argn = LLVMBuildStructGEP(b, v_args, argno, ""); + + return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_DATUM, ""); +} + +/* + * Return argno'th argument nullness. + */ +static inline LLVMValueRef +l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + return LLVMBuildLoad(b, l_funcnullp(b, v_fcinfo, argno), ""); +} + +/* + * Return argno'th argument datum. + */ +static inline LLVMValueRef +l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) +{ + return LLVMBuildLoad(b, l_funcvaluep(b, v_fcinfo, argno), ""); +} + +#endif /* USE_LLVM */ #endif diff --git a/src/include/lib/binaryheap.h b/src/include/lib/binaryheap.h index 9399e0d60b0..21f96b9ca6a 100644 --- a/src/include/lib/binaryheap.h +++ b/src/include/lib/binaryheap.h @@ -3,7 +3,7 @@ * * A simple binary heap implementation * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * src/include/lib/binaryheap.h */ @@ -38,8 +38,8 @@ typedef struct binaryheap } binaryheap; extern binaryheap *binaryheap_allocate(int capacity, - binaryheap_comparator compare, - void *arg); + binaryheap_comparator compare, + void *arg); extern void binaryheap_reset(binaryheap *heap); extern void binaryheap_free(binaryheap *heap); extern void binaryheap_add_unordered(binaryheap *heap, Datum d); diff --git a/src/include/lib/bipartite_match.h b/src/include/lib/bipartite_match.h index c184c0d38e1..7997a5d5a68 100644 --- a/src/include/lib/bipartite_match.h +++ b/src/include/lib/bipartite_match.h @@ -1,7 +1,7 @@ /* * bipartite_match.h * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * src/include/lib/bipartite_match.h */ diff --git a/src/include/lib/bloomfilter.h b/src/include/lib/bloomfilter.h index 6cbdd9bfd99..3b952fbed91 100644 --- a/src/include/lib/bloomfilter.h +++ b/src/include/lib/bloomfilter.h @@ -3,7 +3,7 @@ * bloomfilter.h * Space-efficient set membership testing * - * Copyright (c) 2018, PostgreSQL Global Development Group + * Copyright (c) 2018-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/lib/bloomfilter.h @@ -16,12 +16,12 @@ typedef struct bloom_filter bloom_filter; extern bloom_filter *bloom_create(int64 total_elems, int bloom_work_mem, - uint64 seed); + uint64 seed); extern void bloom_free(bloom_filter *filter); extern void bloom_add_element(bloom_filter *filter, unsigned char *elem, - size_t len); + size_t len); extern bool bloom_lacks_element(bloom_filter *filter, unsigned char *elem, - size_t len); + size_t len); extern double bloom_prop_bits_set(bloom_filter *filter); #endif /* BLOOMFILTER_H */ diff --git a/src/include/lib/dshash.h b/src/include/lib/dshash.h index 8c733bfe256..fa2e28ff3e3 100644 --- a/src/include/lib/dshash.h +++ b/src/include/lib/dshash.h @@ -3,7 +3,7 @@ * dshash.h * Concurrent hash tables backed by dynamic shared memory areas. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -61,21 +61,21 @@ typedef struct dshash_table_item dshash_table_item; /* Creating, sharing and destroying from hash tables. */ extern dshash_table *dshash_create(dsa_area *area, - const dshash_parameters *params, - void *arg); + const dshash_parameters *params, + void *arg); extern dshash_table *dshash_attach(dsa_area *area, - const dshash_parameters *params, - dshash_table_handle handle, - void *arg); + const dshash_parameters *params, + dshash_table_handle handle, + void *arg); extern void dshash_detach(dshash_table *hash_table); extern dshash_table_handle dshash_get_hash_table_handle(dshash_table *hash_table); extern void dshash_destroy(dshash_table *hash_table); /* Finding, creating, deleting entries. */ extern void *dshash_find(dshash_table *hash_table, - const void *key, bool exclusive); + const void *key, bool exclusive); extern void *dshash_find_or_insert(dshash_table *hash_table, - const void *key, bool *found); + const void *key, bool *found); extern bool dshash_delete_key(dshash_table *hash_table, const void *key); extern void dshash_delete_entry(dshash_table *hash_table, void *entry); extern void dshash_release_lock(dshash_table *hash_table, void *entry); diff --git a/src/include/lib/hyperloglog.h b/src/include/lib/hyperloglog.h index f735111f916..508a3cf7066 100644 --- a/src/include/lib/hyperloglog.h +++ b/src/include/lib/hyperloglog.h @@ -3,7 +3,7 @@ * * A simple HyperLogLog cardinality estimator implementation * - * Portions Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2014-2019, PostgreSQL Global Development Group * * Based on Hideaki Ohno's C++ implementation. The copyright terms of Ohno's * original version (the MIT license) follow. diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h index fc9d6b3ee4c..b1a5974ee40 100644 --- a/src/include/lib/ilist.h +++ b/src/include/lib/ilist.h @@ -96,7 +96,7 @@ * } * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/include/lib/integerset.h b/src/include/lib/integerset.h new file mode 100644 index 00000000000..a7882c1a268 --- /dev/null +++ b/src/include/lib/integerset.h @@ -0,0 +1,24 @@ +/* + * integerset.h + * In-memory data structure to hold a large set of integers efficiently + * + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group + * + * src/include/lib/integerset.h + */ +#ifndef INTEGERSET_H +#define INTEGERSET_H + +typedef struct IntegerSet IntegerSet; + +extern IntegerSet *intset_create(void); +extern void intset_add_member(IntegerSet *intset, uint64 x); +extern bool intset_is_member(IntegerSet *intset, uint64 x); + +extern uint64 intset_num_entries(IntegerSet *intset); +extern uint64 intset_memory_usage(IntegerSet *intset); + +extern void intset_begin_iterate(IntegerSet *intset); +extern bool intset_iterate_next(IntegerSet *intset, uint64 *next); + +#endif /* INTEGERSET_H */ diff --git a/src/include/lib/knapsack.h b/src/include/lib/knapsack.h index 9f17004d48e..14fb75ca8b3 100644 --- a/src/include/lib/knapsack.h +++ b/src/include/lib/knapsack.h @@ -1,7 +1,7 @@ /* * knapsack.h * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * src/include/lib/knapsack.h */ @@ -11,6 +11,6 @@ #include "nodes/bitmapset.h" extern Bitmapset *DiscreteKnapsack(int max_weight, int num_items, - int *item_weights, double *item_values); + int *item_weights, double *item_values); #endif /* KNAPSACK_H */ diff --git a/src/include/lib/pairingheap.h b/src/include/lib/pairingheap.h index 9d3de79601f..4fbed1d9c59 100644 --- a/src/include/lib/pairingheap.h +++ b/src/include/lib/pairingheap.h @@ -3,7 +3,7 @@ * * A Pairing Heap implementation * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * src/include/lib/pairingheap.h */ @@ -76,7 +76,7 @@ typedef struct pairingheap } pairingheap; extern pairingheap *pairingheap_allocate(pairingheap_comparator compare, - void *arg); + void *arg); extern void pairingheap_free(pairingheap *heap); extern void pairingheap_add(pairingheap *heap, pairingheap_node *node); extern pairingheap_node *pairingheap_first(pairingheap *heap); @@ -85,8 +85,8 @@ extern void pairingheap_remove(pairingheap *heap, pairingheap_node *node); #ifdef PAIRINGHEAP_DEBUG extern char *pairingheap_dump(pairingheap *heap, - void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque), - void *opaque); + void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque), + void *opaque); #endif /* Resets the heap to be empty. */ diff --git a/src/include/lib/rbtree.h b/src/include/lib/rbtree.h index c46db47a750..6d79a240153 100644 --- a/src/include/lib/rbtree.h +++ b/src/include/lib/rbtree.h @@ -3,7 +3,7 @@ * rbtree.h * interface for PostgreSQL generic Red-Black binary tree package * - * Copyright (c) 2009-2018, PostgreSQL Global Development Group + * Copyright (c) 2009-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/lib/rbtree.h @@ -14,29 +14,29 @@ #define RBTREE_H /* - * RBNode is intended to be used as the first field of a larger struct, + * RBTNode is intended to be used as the first field of a larger struct, * whose additional fields carry whatever payload data the caller needs * for a tree entry. (The total size of that larger struct is passed to - * rb_create.) RBNode is declared here to support this usage, but + * rbt_create.) RBTNode is declared here to support this usage, but * callers must treat it as an opaque struct. */ -typedef struct RBNode +typedef struct RBTNode { char color; /* node's current color, red or black */ - struct RBNode *left; /* left child, or RBNIL if none */ - struct RBNode *right; /* right child, or RBNIL if none */ - struct RBNode *parent; /* parent, or NULL (not RBNIL!) if none */ -} RBNode; + struct RBTNode *left; /* left child, or RBTNIL if none */ + struct RBTNode *right; /* right child, or RBTNIL if none */ + struct RBTNode *parent; /* parent, or NULL (not RBTNIL!) if none */ +} RBTNode; /* Opaque struct representing a whole tree */ typedef struct RBTree RBTree; /* Available tree iteration orderings */ -typedef enum RBOrderControl +typedef enum RBTOrderControl { LeftRightWalk, /* inorder: left child, node, right child */ RightLeftWalk /* reverse inorder: right, node, left */ -} RBOrderControl; +} RBTOrderControl; /* * RBTreeIterator holds state while traversing a tree. This is declared @@ -47,33 +47,33 @@ typedef struct RBTreeIterator RBTreeIterator; struct RBTreeIterator { - RBTree *rb; - RBNode *(*iterate) (RBTreeIterator *iter); - RBNode *last_visited; + RBTree *rbt; + RBTNode *(*iterate) (RBTreeIterator *iter); + RBTNode *last_visited; bool is_over; }; /* Support functions to be provided by caller */ -typedef int (*rb_comparator) (const RBNode *a, const RBNode *b, void *arg); -typedef void (*rb_combiner) (RBNode *existing, const RBNode *newdata, void *arg); -typedef RBNode *(*rb_allocfunc) (void *arg); -typedef void (*rb_freefunc) (RBNode *x, void *arg); +typedef int (*rbt_comparator) (const RBTNode *a, const RBTNode *b, void *arg); +typedef void (*rbt_combiner) (RBTNode *existing, const RBTNode *newdata, void *arg); +typedef RBTNode *(*rbt_allocfunc) (void *arg); +typedef void (*rbt_freefunc) (RBTNode *x, void *arg); -extern RBTree *rb_create(Size node_size, - rb_comparator comparator, - rb_combiner combiner, - rb_allocfunc allocfunc, - rb_freefunc freefunc, - void *arg); +extern RBTree *rbt_create(Size node_size, + rbt_comparator comparator, + rbt_combiner combiner, + rbt_allocfunc allocfunc, + rbt_freefunc freefunc, + void *arg); -extern RBNode *rb_find(RBTree *rb, const RBNode *data); -extern RBNode *rb_leftmost(RBTree *rb); +extern RBTNode *rbt_find(RBTree *rbt, const RBTNode *data); +extern RBTNode *rbt_leftmost(RBTree *rbt); -extern RBNode *rb_insert(RBTree *rb, const RBNode *data, bool *isNew); -extern void rb_delete(RBTree *rb, RBNode *node); +extern RBTNode *rbt_insert(RBTree *rbt, const RBTNode *data, bool *isNew); +extern void rbt_delete(RBTree *rbt, RBTNode *node); -extern void rb_begin_iterate(RBTree *rb, RBOrderControl ctrl, - RBTreeIterator *iter); -extern RBNode *rb_iterate(RBTreeIterator *iter); +extern void rbt_begin_iterate(RBTree *rbt, RBTOrderControl ctrl, + RBTreeIterator *iter); +extern RBTNode *rbt_iterate(RBTreeIterator *iter); #endif /* RBTREE_H */ diff --git a/src/include/lib/simplehash.h b/src/include/lib/simplehash.h index 5273d494600..d827270a6ac 100644 --- a/src/include/lib/simplehash.h +++ b/src/include/lib/simplehash.h @@ -32,7 +32,7 @@ * - SH_STORE_HASH - if defined the hash is stored in the elements * - SH_GET_HASH(tb, a) - return the field to store the hash in * - * For examples of usage look at simplehash.c (file local definition) and + * For examples of usage look at tidbitmap.c (file local definition) and * execnodes.h/execGrouping.c (exposed declaration, file local * implementation). * @@ -65,16 +65,19 @@ /* type declarations */ #define SH_TYPE SH_MAKE_NAME(hash) #define SH_STATUS SH_MAKE_NAME(status) -#define SH_STATUS_EMPTY SH_MAKE_NAME(EMPTY) -#define SH_STATUS_IN_USE SH_MAKE_NAME(IN_USE) +#define SH_STATUS_EMPTY SH_MAKE_NAME(SH_EMPTY) +#define SH_STATUS_IN_USE SH_MAKE_NAME(SH_IN_USE) #define SH_ITERATOR SH_MAKE_NAME(iterator) /* function declarations */ #define SH_CREATE SH_MAKE_NAME(create) #define SH_DESTROY SH_MAKE_NAME(destroy) +#define SH_RESET SH_MAKE_NAME(reset) #define SH_INSERT SH_MAKE_NAME(insert) +#define SH_INSERT_HASH SH_MAKE_NAME(insert_hash) #define SH_DELETE SH_MAKE_NAME(delete) #define SH_LOOKUP SH_MAKE_NAME(lookup) +#define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash) #define SH_GROW SH_MAKE_NAME(grow) #define SH_START_ITERATE SH_MAKE_NAME(start_iterate) #define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at) @@ -90,6 +93,8 @@ #define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance) #define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket) #define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash) +#define SH_INSERT_HASH_INTERNAL SH_MAKE_NAME(insert_hash_internal) +#define SH_LOOKUP_HASH_INTERNAL SH_MAKE_NAME(lookup_hash_internal) /* generate forward declarations necessary to use the hash table */ #ifdef SH_DECLARE @@ -138,11 +143,16 @@ typedef struct SH_ITERATOR /* externally visible function prototypes */ SH_SCOPE SH_TYPE *SH_CREATE(MemoryContext ctx, uint32 nelements, - void *private_data); + void *private_data); SH_SCOPE void SH_DESTROY(SH_TYPE * tb); +SH_SCOPE void SH_RESET(SH_TYPE * tb); SH_SCOPE void SH_GROW(SH_TYPE * tb, uint32 newsize); SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found); +SH_SCOPE SH_ELEMENT_TYPE *SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, + uint32 hash, bool *found); SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key); +SH_SCOPE SH_ELEMENT_TYPE *SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, + uint32 hash); SH_SCOPE bool SH_DELETE(SH_TYPE * tb, SH_KEY_TYPE key); SH_SCOPE void SH_START_ITERATE(SH_TYPE * tb, SH_ITERATOR * iter); SH_SCOPE void SH_START_ITERATE_AT(SH_TYPE * tb, SH_ITERATOR * iter, uint32 at); @@ -185,6 +195,16 @@ SH_SCOPE void SH_STAT(SH_TYPE * tb); #define SH_COMPARE_KEYS(tb, ahash, akey, b) (SH_EQUAL(tb, b->SH_KEY, akey)) #endif +/* + * Wrap the following definitions in include guards, to avoid multiple + * definition errors if this header is included more than once. The rest of + * the file deliberately has no include guards, because it can be included + * with different parameters to define functions and types with non-colliding + * names. + */ +#ifndef SIMPLEHASH_H +#define SIMPLEHASH_H + /* FIXME: can we move these to a central location? */ /* calculate ceil(log base 2) of num */ @@ -206,6 +226,8 @@ sh_pow2(uint64 num) return ((uint64) 1) << sh_log2(num); } +#endif + /* * Compute sizing parameters for hashtable. Called when creating and growing * the hashtable. @@ -356,6 +378,14 @@ SH_DESTROY(SH_TYPE * tb) pfree(tb); } +/* reset the contents of a previously created hash table */ +SH_SCOPE void +SH_RESET(SH_TYPE * tb) +{ + memset(tb->data, 0, sizeof(SH_ELEMENT_TYPE) * tb->size); + tb->members = 0; +} + /* * Grow a hash table to at least `newsize` buckets. * @@ -470,14 +500,12 @@ SH_GROW(SH_TYPE * tb, uint32 newsize) } /* - * Insert the key key into the hash-table, set *found to true if the key - * already exists, false otherwise. Returns the hash-table entry in either - * case. + * This is a separate static inline function, so it can be reliably be inlined + * into its wrapper functions even if SH_SCOPE is extern. */ -SH_SCOPE SH_ELEMENT_TYPE * -SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found) +static inline SH_ELEMENT_TYPE * +SH_INSERT_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) { - uint32 hash = SH_HASH_KEY(tb, key); uint32 startelem; uint32 curelem; SH_ELEMENT_TYPE *data; @@ -642,12 +670,36 @@ SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found) } /* - * Lookup up entry in hash table. Returns NULL if key not present. + * Insert the key key into the hash-table, set *found to true if the key + * already exists, false otherwise. Returns the hash-table entry in either + * case. */ SH_SCOPE SH_ELEMENT_TYPE * -SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key) +SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found) +{ + uint32 hash = SH_HASH_KEY(tb, key); + + return SH_INSERT_HASH_INTERNAL(tb, key, hash, found); +} + +/* + * Insert the key key into the hash-table using an already-calculated + * hash. Set *found to true if the key already exists, false + * otherwise. Returns the hash-table entry in either case. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_INSERT_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash, bool *found) +{ + return SH_INSERT_HASH_INTERNAL(tb, key, hash, found); +} + +/* + * This is a separate static inline function, so it can be reliably be inlined + * into its wrapper functions even if SH_SCOPE is extern. + */ +static inline SH_ELEMENT_TYPE * +SH_LOOKUP_HASH_INTERNAL(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash) { - uint32 hash = SH_HASH_KEY(tb, key); const uint32 startelem = SH_INITIAL_BUCKET(tb, hash); uint32 curelem = startelem; @@ -676,6 +728,28 @@ SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key) } } +/* + * Lookup up entry in hash table. Returns NULL if key not present. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key) +{ + uint32 hash = SH_HASH_KEY(tb, key); + + return SH_LOOKUP_HASH_INTERNAL(tb, key, hash); +} + +/* + * Lookup up entry in hash table using an already-calculated hash. + * + * Returns NULL if key not present. + */ +SH_SCOPE SH_ELEMENT_TYPE * +SH_LOOKUP_HASH(SH_TYPE * tb, SH_KEY_TYPE key, uint32 hash) +{ + return SH_LOOKUP_HASH_INTERNAL(tb, key, hash); +} + /* * Delete entry from hash table. Returns whether to-be-deleted key was * present. @@ -924,6 +998,7 @@ SH_STAT(SH_TYPE * tb) #undef SH_GET_HASH #undef SH_STORE_HASH #undef SH_USE_NONDEFAULT_ALLOCATOR +#undef SH_EQUAL /* undefine locally declared macros */ #undef SH_MAKE_PREFIX @@ -946,9 +1021,12 @@ SH_STAT(SH_TYPE * tb) /* external function names */ #undef SH_CREATE #undef SH_DESTROY +#undef SH_RESET #undef SH_INSERT +#undef SH_INSERT_HASH #undef SH_DELETE #undef SH_LOOKUP +#undef SH_LOOKUP_HASH #undef SH_GROW #undef SH_START_ITERATE #undef SH_START_ITERATE_AT @@ -965,3 +1043,5 @@ SH_STAT(SH_TYPE * tb) #undef SH_PREV #undef SH_DISTANCE_FROM_OPTIMAL #undef SH_ENTRY_HASH +#undef SH_INSERT_HASH_INTERNAL +#undef SH_LOOKUP_HASH_INTERNAL diff --git a/src/include/lib/stringinfo.h b/src/include/lib/stringinfo.h index 8551237fc6b..c4842778c51 100644 --- a/src/include/lib/stringinfo.h +++ b/src/include/lib/stringinfo.h @@ -7,7 +7,7 @@ * It can be used to buffer either ordinary C strings (null-terminated text) * or arbitrary binary data. All storage is allocated with palloc(). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/lib/stringinfo.h @@ -141,7 +141,7 @@ extern void appendStringInfoSpaces(StringInfo str, int count); * if necessary. */ extern void appendBinaryStringInfo(StringInfo str, - const char *data, int datalen); + const char *data, int datalen); /*------------------------ * appendBinaryStringInfoNT @@ -149,7 +149,7 @@ extern void appendBinaryStringInfo(StringInfo str, * if necessary. Does not ensure a trailing null-byte exists. */ extern void appendBinaryStringInfoNT(StringInfo str, - const char *data, int datalen); + const char *data, int datalen); /*------------------------ * enlargeStringInfo diff --git a/src/include/libpq/auth.h b/src/include/libpq/auth.h index e8a1dc14ffc..405fd43487b 100644 --- a/src/include/libpq/auth.h +++ b/src/include/libpq/auth.h @@ -4,7 +4,7 @@ * Definitions for network authentication routines * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/auth.h diff --git a/src/include/libpq/be-fsstubs.h b/src/include/libpq/be-fsstubs.h index ed31e54323d..a753ed1a33e 100644 --- a/src/include/libpq/be-fsstubs.h +++ b/src/include/libpq/be-fsstubs.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/be-fsstubs.h @@ -27,6 +27,6 @@ extern int lo_write(int fd, const char *buf, int len); */ extern void AtEOXact_LargeObject(bool isCommit); extern void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId parentSubid); #endif /* BE_FSSTUBS_H */ diff --git a/src/include/libpq/be-gssapi-common.h b/src/include/libpq/be-gssapi-common.h new file mode 100644 index 00000000000..acb30b94944 --- /dev/null +++ b/src/include/libpq/be-gssapi-common.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * be-gssapi-common.h + * Definitions for GSSAPI authentication and encryption handling + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/libpq/be-gssapi-common.h + * + *------------------------------------------------------------------------- + */ + +#ifndef BE_GSSAPI_COMMON_H +#define BE_GSSAPI_COMMON_H + +#if defined(HAVE_GSSAPI_H) +#include +#else +#include +#endif + +void pg_GSS_error(int severity, const char *errmsg, + OM_uint32 maj_stat, OM_uint32 min_stat); + +#endif /* BE_GSSAPI_COMMON_H */ diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h index 4279a4a9ed3..e6b50a72888 100644 --- a/src/include/libpq/crypt.h +++ b/src/include/libpq/crypt.h @@ -3,7 +3,7 @@ * crypt.h * Interface to libpq/crypt.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/crypt.h @@ -33,14 +33,14 @@ typedef enum PasswordType extern PasswordType get_password_type(const char *shadow_pass); extern char *encrypt_password(PasswordType target_type, const char *role, - const char *password); + const char *password); extern char *get_role_password(const char *role, char **logdetail); -extern int md5_crypt_verify(const char *role, const char *shadow_pass, - const char *client_pass, const char *md5_salt, - int md5_salt_len, char **logdetail); -extern int plain_crypt_verify(const char *role, const char *shadow_pass, - const char *client_pass, char **logdetail); +extern int md5_crypt_verify(const char *role, const char *shadow_pass, + const char *client_pass, const char *md5_salt, + int md5_salt_len, char **logdetail); +extern int plain_crypt_verify(const char *role, const char *shadow_pass, + const char *client_pass, char **logdetail); #endif diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 5f68f4c6661..d638479d884 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -55,9 +55,18 @@ typedef enum ConnType ctLocal, ctHost, ctHostSSL, - ctHostNoSSL + ctHostNoSSL, + ctHostGSS, + ctHostNoGSS, } ConnType; +typedef enum ClientCertMode +{ + clientCertOff, + clientCertCA, + clientCertFull +} ClientCertMode; + typedef struct HbaLine { int linenumber; @@ -86,7 +95,7 @@ typedef struct HbaLine int ldapscope; char *ldapprefix; char *ldapsuffix; - bool clientcert; + ClientCertMode clientcert; char *krb_realm; bool include_realm; bool compat_realm; @@ -117,9 +126,9 @@ typedef struct Port hbaPort; extern bool load_hba(void); extern bool load_ident(void); extern void hba_getauthmethod(hbaPort *port); -extern int check_usermap(const char *usermap_name, - const char *pg_role, const char *auth_user, - bool case_sensitive); +extern int check_usermap(const char *usermap_name, + const char *pg_role, const char *auth_user, + bool case_sensitive); extern bool pg_isblank(const char c); #endif /* HBA_H */ diff --git a/src/include/libpq/ifaddr.h b/src/include/libpq/ifaddr.h index 1d35597a7f4..e68ff04a65e 100644 --- a/src/include/libpq/ifaddr.h +++ b/src/include/libpq/ifaddr.h @@ -3,7 +3,7 @@ * ifaddr.h * IP netmask calculations, and enumerating network interfaces. * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/libpq/ifaddr.h * @@ -18,12 +18,12 @@ typedef void (*PgIfAddrCallback) (struct sockaddr *addr, struct sockaddr *netmask, void *cb_data); -extern int pg_range_sockaddr(const struct sockaddr_storage *addr, - const struct sockaddr_storage *netaddr, - const struct sockaddr_storage *netmask); +extern int pg_range_sockaddr(const struct sockaddr_storage *addr, + const struct sockaddr_storage *netaddr, + const struct sockaddr_storage *netmask); -extern int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, - char *numbits, int family); +extern int pg_sockaddr_cidr_mask(struct sockaddr_storage *mask, + char *numbits, int family); extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data); diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h index 7698cd1f88a..541f970f99e 100644 --- a/src/include/libpq/libpq-be.h +++ b/src/include/libpq/libpq-be.h @@ -8,7 +8,7 @@ * Structs that need to be client-visible are in pqcomm.h. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq-be.h @@ -86,6 +86,10 @@ typedef struct gss_cred_id_t cred; /* GSSAPI connection cred's */ gss_ctx_id_t ctx; /* GSSAPI connection context */ gss_name_t name; /* GSSAPI client name */ + char *princ; /* GSSAPI Principal used for auth, NULL if + * GSSAPI auth was not used */ + bool auth; /* GSSAPI Authentication used */ + bool enc; /* GSSAPI encryption in use */ #endif } pg_gssinfo; #endif @@ -139,19 +143,19 @@ typedef struct Port List *guc_options; /* - * Information that needs to be held during the authentication cycle. + * The startup packet application name, only used here for the "connection + * authorized" log message. We shouldn't use this post-startup, instead + * the GUC should be used as application can change it afterward. */ - HbaLine *hba; + char *application_name; /* - * Information that really has no business at all being in struct Port, - * but since it gets used by elog.c in the same way as database_name and - * other members of this struct, we may as well keep it here. + * Information that needs to be held during the authentication cycle. */ - TimestampTz SessionStartTime; /* backend start time */ + HbaLine *hba; /* - * TCP keepalive settings. + * TCP keepalive and user timeout settings. * * default values are 0 if AF_UNIX or not yet known; current values are 0 * if AF_UNIX or using the default. Also, -1 in a default value means we @@ -160,10 +164,15 @@ typedef struct Port int default_keepalives_idle; int default_keepalives_interval; int default_keepalives_count; + int default_tcp_user_timeout; int keepalives_idle; int keepalives_interval; int keepalives_count; + int tcp_user_timeout; + /* + * GSSAPI structures. + */ #if defined(ENABLE_GSS) || defined(ENABLE_SSPI) /* @@ -197,19 +206,20 @@ typedef struct Port * Hardcoded DH parameters, used in ephemeral DH keying. (See also * README.SSL for more details on EDH.) * - * If you want to create your own hardcoded DH parameters - * for fun and profit, review "Assigned Number for SKIP - * Protocols" (http://www.skip-vpn.org/spec/numbers.html) - * for suggestions. + * This is the 2048-bit DH parameter from RFC 3526. The generation of the + * prime is specified in RFC 2412 Appendix E, which also discusses the + * design choice of the generator. Note that when loaded with OpenSSL + * this causes DH_check() to fail on DH_NOT_SUITABLE_GENERATOR, where + * leaking a bit is preferred. */ #define FILE_DH2048 \ "-----BEGIN DH PARAMETERS-----\n\ -MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\ -89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\ -T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\ -zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\ -Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\ -CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\ +MIIBCAKCAQEA///////////JD9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxOb\n\ +IlFKCHmONATd75UZs806QxswKwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjft\n\ +awv/XLb0Brft7jhr+1qJn6WunyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXT\n\ +mmkWP6j9JM9fg2VdI9yjrZYcYvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhgh\n\ +fDKQXkYuNs474553LBgOhgObJ4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq\n\ +5RXSJhiY+gUQFXKOWoqsqmj//////////wIBAg==\n\ -----END DH PARAMETERS-----\n" /* @@ -258,15 +268,9 @@ extern int be_tls_get_cipher_bits(Port *port); extern bool be_tls_get_compression(Port *port); extern const char *be_tls_get_version(Port *port); extern const char *be_tls_get_cipher(Port *port); -extern void be_tls_get_peerdn_name(Port *port, char *ptr, size_t len); - -/* - * Get the expected TLS Finished message information from the client, useful - * for authorization when doing channel binding. - * - * Result is a palloc'd copy of the TLS Finished message with its size. - */ -extern char *be_tls_get_peer_finished(Port *port, size_t *len); +extern void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len); +extern void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len); +extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len); /* * Get the server certificate hash for SCRAM channel binding type @@ -274,10 +278,30 @@ extern char *be_tls_get_peer_finished(Port *port, size_t *len); * * The result is a palloc'd hash of the server certificate with its * size, and NULL if there is no certificate available. + * + * This is not supported with old versions of OpenSSL that don't have + * the X509_get_signature_nid() function. */ +#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID) +#define HAVE_BE_TLS_GET_CERTIFICATE_HASH extern char *be_tls_get_certificate_hash(Port *port, size_t *len); #endif +#endif /* USE_SSL */ + +#ifdef ENABLE_GSS +/* + * Return information about the GSSAPI authenticated connection + */ +extern bool be_gssapi_get_auth(Port *port); +extern bool be_gssapi_get_enc(Port *port); +extern const char *be_gssapi_get_princ(Port *port); + +/* Read and write to a GSSAPI-encrypted connection. */ +extern ssize_t be_gssapi_read(Port *port, void *ptr, size_t len); +extern ssize_t be_gssapi_write(Port *port, void *ptr, size_t len); +#endif /* ENABLE_GSS */ + extern ProtocolVersion FrontendProtocol; /* TCP keepalives configuration. These are no-ops on an AF_UNIX socket. */ @@ -285,9 +309,11 @@ extern ProtocolVersion FrontendProtocol; extern int pq_getkeepalivesidle(Port *port); extern int pq_getkeepalivesinterval(Port *port); extern int pq_getkeepalivescount(Port *port); +extern int pq_gettcpusertimeout(Port *port); extern int pq_setkeepalivesidle(int idle, Port *port); extern int pq_setkeepalivesinterval(int interval, Port *port); extern int pq_setkeepalivescount(int count, Port *port); +extern int pq_settcpusertimeout(int timeout, Port *port); #endif /* LIBPQ_BE_H */ diff --git a/src/include/libpq/libpq-fs.h b/src/include/libpq/libpq-fs.h index e63d11ef194..f29883a83c2 100644 --- a/src/include/libpq/libpq-fs.h +++ b/src/include/libpq/libpq-fs.h @@ -4,7 +4,7 @@ * definitions for using Inversion file system routines (ie, large objects) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq-fs.h diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index a74ad521b5a..08a257616dc 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -4,7 +4,7 @@ * POSTGRES LIBPQ buffer structure definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/libpq.h @@ -33,7 +33,7 @@ typedef struct void (*endcopyout) (bool errorAbort); } PQcommMethods; -extern PGDLLIMPORT PQcommMethods *PqCommMethods; +extern const PGDLLIMPORT PQcommMethods *PqCommMethods; #define pq_comm_reset() (PqCommMethods->comm_reset()) #define pq_flush() (PqCommMethods->flush()) @@ -53,9 +53,11 @@ extern PGDLLIMPORT PQcommMethods *PqCommMethods; /* * prototypes for functions in pqcomm.c */ -extern int StreamServerPort(int family, char *hostName, - unsigned short portNumber, char *unixSocketDir, - pgsocket ListenSocket[], int MaxListen); +extern WaitEventSet *FeBeWaitSet; + +extern int StreamServerPort(int family, char *hostName, + unsigned short portNumber, char *unixSocketDir, + pgsocket ListenSocket[], int MaxListen); extern int StreamConnection(pgsocket server_fd, Port *port); extern void StreamClose(pgsocket sock); extern void TouchSocketFiles(void); @@ -75,6 +77,7 @@ extern int pq_putbytes(const char *s, size_t len); /* * prototypes for functions in be-secure.c */ +extern char *ssl_library; extern char *ssl_cert_file; extern char *ssl_key_file; extern char *ssl_ca_file; @@ -82,6 +85,9 @@ extern char *ssl_crl_file; extern char *ssl_dh_params_file; extern char *ssl_passphrase_command; extern bool ssl_passphrase_command_supports_reload; +#ifdef USE_SSL +extern bool ssl_loaded_verify_locations; +#endif extern int secure_initialize(bool isServerStart); extern bool secure_loaded_verify_locations(void); @@ -93,20 +99,34 @@ extern ssize_t secure_write(Port *port, void *ptr, size_t len); extern ssize_t secure_raw_read(Port *port, void *ptr, size_t len); extern ssize_t secure_raw_write(Port *port, const void *ptr, size_t len); -extern bool ssl_loaded_verify_locations; - -extern WaitEventSet *FeBeWaitSet; +/* + * prototypes for functions in be-secure-gssapi.c + */ +#ifdef ENABLE_GSS +extern ssize_t secure_open_gssapi(Port *port); +#endif /* GUCs */ extern char *SSLCipherSuites; extern char *SSLECDHCurve; extern bool SSLPreferServerCiphers; +extern int ssl_min_protocol_version; +extern int ssl_max_protocol_version; + +enum ssl_protocol_versions +{ + PG_TLS_ANY = 0, + PG_TLS1_VERSION, + PG_TLS1_1_VERSION, + PG_TLS1_2_VERSION, + PG_TLS1_3_VERSION, +}; /* * prototypes for functions in be-secure-common.c */ -extern int run_ssl_passphrase_command(const char *prompt, bool is_server_start, - char *buf, int size); +extern int run_ssl_passphrase_command(const char *prompt, bool is_server_start, + char *buf, int size); extern bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart); diff --git a/src/include/libpq/pqcomm.h b/src/include/libpq/pqcomm.h index cc0e0b32c78..baf6a4b6c02 100644 --- a/src/include/libpq/pqcomm.h +++ b/src/include/libpq/pqcomm.h @@ -6,7 +6,7 @@ * NOTE: for historical reasons, this does not correspond to pqcomm.c. * pqcomm.c's routines are declared in libpq.h. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqcomm.h @@ -199,9 +199,10 @@ typedef struct CancelRequestPacket /* - * A client can also start by sending a SSL negotiation request, to get a - * secure channel. + * A client can also start by sending a SSL or GSSAPI negotiation request to + * get a secure channel. */ #define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) +#define NEGOTIATE_GSS_CODE PG_PROTOCOL(1234,5680) #endif /* PQCOMM_H */ diff --git a/src/include/libpq/pqformat.h b/src/include/libpq/pqformat.h index 57bde691e89..04dcb3ee1ee 100644 --- a/src/include/libpq/pqformat.h +++ b/src/include/libpq/pqformat.h @@ -3,7 +3,7 @@ * pqformat.h * Definitions for formatting and parsing frontend/backend messages * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqformat.h @@ -24,18 +24,15 @@ extern void pq_endmessage_reuse(StringInfo buf); extern void pq_sendbytes(StringInfo buf, const char *data, int datalen); extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen, - bool countincludesself); + bool countincludesself); extern void pq_sendtext(StringInfo buf, const char *str, int slen); extern void pq_sendstring(StringInfo buf, const char *str); extern void pq_send_ascii_string(StringInfo buf, const char *str); extern void pq_sendfloat4(StringInfo buf, float4 f); extern void pq_sendfloat8(StringInfo buf, float8 f); -extern void pq_sendfloat4(StringInfo buf, float4 f); -extern void pq_sendfloat8(StringInfo buf, float8 f); - /* - * Append an int8 to a StringInfo buffer, which already has enough space + * Append a [u]int8 to a StringInfo buffer, which already has enough space * preallocated. * * The use of pg_restrict allows the compiler to optimize the code based on @@ -47,55 +44,55 @@ extern void pq_sendfloat8(StringInfo buf, float8 f); * overly picky and demanding a * before a restrict. */ static inline void -pq_writeint8(StringInfoData *pg_restrict buf, int8 i) +pq_writeint8(StringInfoData *pg_restrict buf, uint8 i) { - int8 ni = i; + uint8 ni = i; - Assert(buf->len + (int) sizeof(int8) <= buf->maxlen); - memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(int8)); - buf->len += sizeof(int8); + Assert(buf->len + (int) sizeof(uint8) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint8)); + buf->len += sizeof(uint8); } /* - * Append an int16 to a StringInfo buffer, which already has enough space + * Append a [u]int16 to a StringInfo buffer, which already has enough space * preallocated. */ static inline void -pq_writeint16(StringInfoData *pg_restrict buf, int16 i) +pq_writeint16(StringInfoData *pg_restrict buf, uint16 i) { - int16 ni = pg_hton16(i); + uint16 ni = pg_hton16(i); - Assert(buf->len + (int) sizeof(int16) <= buf->maxlen); - memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(int16)); - buf->len += sizeof(int16); + Assert(buf->len + (int) sizeof(uint16) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint16)); + buf->len += sizeof(uint16); } /* - * Append an int32 to a StringInfo buffer, which already has enough space + * Append a [u]int32 to a StringInfo buffer, which already has enough space * preallocated. */ static inline void -pq_writeint32(StringInfoData *pg_restrict buf, int32 i) +pq_writeint32(StringInfoData *pg_restrict buf, uint32 i) { - int32 ni = pg_hton32(i); + uint32 ni = pg_hton32(i); - Assert(buf->len + (int) sizeof(int32) <= buf->maxlen); - memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(int32)); - buf->len += sizeof(int32); + Assert(buf->len + (int) sizeof(uint32) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint32)); + buf->len += sizeof(uint32); } /* - * Append an int64 to a StringInfo buffer, which already has enough space + * Append a [u]int64 to a StringInfo buffer, which already has enough space * preallocated. */ static inline void -pq_writeint64(StringInfoData *pg_restrict buf, int64 i) +pq_writeint64(StringInfoData *pg_restrict buf, uint64 i) { - int64 ni = pg_hton64(i); + uint64 ni = pg_hton64(i); - Assert(buf->len + (int) sizeof(int64) <= buf->maxlen); - memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(int64)); - buf->len += sizeof(int64); + Assert(buf->len + (int) sizeof(uint64) <= buf->maxlen); + memcpy((char *pg_restrict) (buf->data + buf->len), &ni, sizeof(uint64)); + buf->len += sizeof(uint64); } /* @@ -127,41 +124,41 @@ pq_writestring(StringInfoData *pg_restrict buf, const char *pg_restrict str) pfree(p); } -/* append a binary int8 to a StringInfo buffer */ +/* append a binary [u]int8 to a StringInfo buffer */ static inline void -pq_sendint8(StringInfo buf, int8 i) +pq_sendint8(StringInfo buf, uint8 i) { - enlargeStringInfo(buf, sizeof(int8)); + enlargeStringInfo(buf, sizeof(uint8)); pq_writeint8(buf, i); } -/* append a binary int16 to a StringInfo buffer */ +/* append a binary [u]int16 to a StringInfo buffer */ static inline void -pq_sendint16(StringInfo buf, int16 i) +pq_sendint16(StringInfo buf, uint16 i) { - enlargeStringInfo(buf, sizeof(int16)); + enlargeStringInfo(buf, sizeof(uint16)); pq_writeint16(buf, i); } -/* append a binary int32 to a StringInfo buffer */ +/* append a binary [u]int32 to a StringInfo buffer */ static inline void -pq_sendint32(StringInfo buf, int32 i) +pq_sendint32(StringInfo buf, uint32 i) { - enlargeStringInfo(buf, sizeof(int32)); + enlargeStringInfo(buf, sizeof(uint32)); pq_writeint32(buf, i); } -/* append a binary int64 to a StringInfo buffer */ +/* append a binary [u]int64 to a StringInfo buffer */ static inline void -pq_sendint64(StringInfo buf, int64 i) +pq_sendint64(StringInfo buf, uint64 i) { - enlargeStringInfo(buf, sizeof(int64)); + enlargeStringInfo(buf, sizeof(uint64)); pq_writeint64(buf, i); } /* append a binary byte to a StringInfo buffer */ static inline void -pq_sendbyte(StringInfo buf, int8 byt) +pq_sendbyte(StringInfo buf, uint8 byt) { pq_sendint8(buf, byt); } @@ -172,18 +169,18 @@ pq_sendbyte(StringInfo buf, int8 byt) * This function is deprecated; prefer use of the functions above. */ static inline void -pq_sendint(StringInfo buf, int i, int b) +pq_sendint(StringInfo buf, uint32 i, int b) { switch (b) { case 1: - pq_sendint8(buf, (int8) i); + pq_sendint8(buf, (uint8) i); break; case 2: - pq_sendint16(buf, (int16) i); + pq_sendint16(buf, (uint16) i); break; case 4: - pq_sendint32(buf, (int32) i); + pq_sendint32(buf, (uint32) i); break; default: elog(ERROR, "unsupported integer size %d", b); diff --git a/src/include/libpq/pqmq.h b/src/include/libpq/pqmq.h index e273656fde4..81efe0d56ee 100644 --- a/src/include/libpq/pqmq.h +++ b/src/include/libpq/pqmq.h @@ -3,7 +3,7 @@ * pqmq.h * Use the frontend/backend protocol for communication over a shm_mq * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqmq.h diff --git a/src/include/libpq/pqsignal.h b/src/include/libpq/pqsignal.h index f292591dfc6..d0e3b9e479e 100644 --- a/src/include/libpq/pqsignal.h +++ b/src/include/libpq/pqsignal.h @@ -3,7 +3,7 @@ * pqsignal.h * Backend signal(2) support (see also src/port/pqsignal.c) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/pqsignal.h diff --git a/src/include/libpq/scram.h b/src/include/libpq/scram.h index 91872fcd088..87e2d56301c 100644 --- a/src/include/libpq/scram.h +++ b/src/include/libpq/scram.h @@ -3,7 +3,7 @@ * scram.h * Interface to libpq/scram.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/libpq/scram.h @@ -13,6 +13,7 @@ #ifndef PG_SCRAM_H #define PG_SCRAM_H +#include "lib/stringinfo.h" #include "libpq/libpq-be.h" /* Status codes for message exchange */ @@ -21,13 +22,16 @@ #define SASL_EXCHANGE_FAILURE 2 /* Routines dedicated to authentication */ -extern void *pg_be_scram_init(Port *port, const char *shadow_pass); -extern int pg_be_scram_exchange(void *opaq, char *input, int inputlen, - char **output, int *outputlen, char **logdetail); +extern void pg_be_scram_get_mechanisms(Port *port, StringInfo buf); +extern void *pg_be_scram_init(Port *port, const char *selected_mech, const char *shadow_pass); +extern int pg_be_scram_exchange(void *opaq, const char *input, int inputlen, + char **output, int *outputlen, char **logdetail); /* Routines to handle and check SCRAM-SHA-256 verifier */ extern char *pg_be_scram_build_verifier(const char *password); +extern bool parse_scram_verifier(const char *verifier, int *iterations, char **salt, + uint8 *stored_key, uint8 *server_key); extern bool scram_verify_plain_password(const char *username, - const char *password, const char *verifier); + const char *password, const char *verifier); #endif /* PG_SCRAM_H */ diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h index 748db5ba5fe..3e3e6c470e9 100644 --- a/src/include/mb/pg_wchar.h +++ b/src/include/mb/pg_wchar.h @@ -3,7 +3,7 @@ * pg_wchar.h * multibyte-character support * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/mb/pg_wchar.h @@ -289,7 +289,7 @@ typedef enum pg_enc #define PG_ENCODING_BE_LAST PG_KOI8U /* - * Please use these tests before access to pg_encconv_tbl[] + * Please use these tests before access to pg_enc2name_tbl[] * or to other places... */ #define PG_VALID_BE_ENCODING(_enc) \ @@ -522,12 +522,12 @@ extern int pg_valid_server_encoding_id(int encoding); */ extern int pg_mb2wchar(const char *from, pg_wchar *to); extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len); -extern int pg_encoding_mb2wchar_with_len(int encoding, - const char *from, pg_wchar *to, int len); +extern int pg_encoding_mb2wchar_with_len(int encoding, + const char *from, pg_wchar *to, int len); extern int pg_wchar2mb(const pg_wchar *from, char *to); extern int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len); -extern int pg_encoding_wchar2mb_with_len(int encoding, - const pg_wchar *from, char *to, int len); +extern int pg_encoding_wchar2mb_with_len(int encoding, + const pg_wchar *from, char *to, int len); extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2); extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n); extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n); @@ -542,9 +542,9 @@ extern int pg_mic_mblen(const unsigned char *mbstr); extern int pg_mbstrlen(const char *mbstr); extern int pg_mbstrlen_with_len(const char *mbstr, int len); extern int pg_mbcliplen(const char *mbstr, int len, int limit); -extern int pg_encoding_mbcliplen(int encoding, const char *mbstr, - int len, int limit); -extern int pg_mbcharcliplen(const char *mbstr, int len, int imit); +extern int pg_encoding_mbcliplen(int encoding, const char *mbstr, + int len, int limit); +extern int pg_mbcharcliplen(const char *mbstr, int len, int limit); extern int pg_encoding_max_length(int encoding); extern int pg_database_encoding_max_length(void); extern mbcharacter_incrementer pg_database_encoding_character_incrementer(void); @@ -572,8 +572,8 @@ extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); extern pg_wchar utf8_to_unicode(const unsigned char *c); extern int pg_utf_mblen(const unsigned char *); extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len, - int src_encoding, - int dest_encoding); + int src_encoding, + int dest_encoding); extern char *pg_client_to_server(const char *s, int len); extern char *pg_server_to_client(const char *s, int len); @@ -584,48 +584,46 @@ extern unsigned short BIG5toCNS(unsigned short big5, unsigned char *lc); extern unsigned short CNStoBIG5(unsigned short cns, unsigned char lc); extern void UtfToLocal(const unsigned char *utf, int len, - unsigned char *iso, - const pg_mb_radix_tree *map, - const pg_utf_to_local_combined *cmap, int cmapsize, - utf_local_conversion_func conv_func, - int encoding); + unsigned char *iso, + const pg_mb_radix_tree *map, + const pg_utf_to_local_combined *cmap, int cmapsize, + utf_local_conversion_func conv_func, + int encoding); extern void LocalToUtf(const unsigned char *iso, int len, - unsigned char *utf, - const pg_mb_radix_tree *map, - const pg_local_to_utf_combined *cmap, int cmapsize, - utf_local_conversion_func conv_func, - int encoding); + unsigned char *utf, + const pg_mb_radix_tree *map, + const pg_local_to_utf_combined *cmap, int cmapsize, + utf_local_conversion_func conv_func, + int encoding); extern bool pg_verifymbstr(const char *mbstr, int len, bool noError); extern bool pg_verify_mbstr(int encoding, const char *mbstr, int len, - bool noError); -extern int pg_verify_mbstr_len(int encoding, const char *mbstr, int len, - bool noError); + bool noError); +extern int pg_verify_mbstr_len(int encoding, const char *mbstr, int len, + bool noError); extern void check_encoding_conversion_args(int src_encoding, - int dest_encoding, - int len, - int expected_src_encoding, - int expected_dest_encoding); + int dest_encoding, + int len, + int expected_src_encoding, + int expected_dest_encoding); extern void report_invalid_encoding(int encoding, const char *mbstr, int len) pg_attribute_noreturn(); extern void report_untranslatable_char(int src_encoding, int dest_encoding, - const char *mbstr, int len) pg_attribute_noreturn(); + const char *mbstr, int len) pg_attribute_noreturn(); extern void local2local(const unsigned char *l, unsigned char *p, int len, - int src_encoding, int dest_encoding, const unsigned char *tab); -extern void pg_ascii2mic(const unsigned char *l, unsigned char *p, int len); -extern void pg_mic2ascii(const unsigned char *mic, unsigned char *p, int len); + int src_encoding, int dest_encoding, const unsigned char *tab); extern void latin2mic(const unsigned char *l, unsigned char *p, int len, - int lc, int encoding); + int lc, int encoding); extern void mic2latin(const unsigned char *mic, unsigned char *p, int len, - int lc, int encoding); + int lc, int encoding); extern void latin2mic_with_table(const unsigned char *l, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab); + int len, int lc, int encoding, + const unsigned char *tab); extern void mic2latin_with_table(const unsigned char *mic, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab); + int len, int lc, int encoding, + const unsigned char *tab); extern bool pg_utf8_islegal(const unsigned char *source, int length); diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index e167ee8fcbe..6a9ac02e2af 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -10,7 +10,7 @@ * Over time, this has also become the preferred place for widely known * resource-limitation stuff, such as work_mem and check_stack_depth(). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/miscadmin.h @@ -25,6 +25,7 @@ #include +#include "datatype/timestamp.h" /* for TimestampTz */ #include "pgtime.h" /* for pg_time_t */ @@ -77,13 +78,13 @@ /* in globals.c */ /* these are marked volatile because they are set by signal handlers: */ -extern PGDLLIMPORT volatile bool InterruptPending; -extern PGDLLIMPORT volatile bool QueryCancelPending; -extern PGDLLIMPORT volatile bool ProcDiePending; -extern PGDLLIMPORT volatile bool IdleInTransactionSessionTimeoutPending; +extern PGDLLIMPORT volatile sig_atomic_t InterruptPending; +extern PGDLLIMPORT volatile sig_atomic_t QueryCancelPending; +extern PGDLLIMPORT volatile sig_atomic_t ProcDiePending; +extern PGDLLIMPORT volatile sig_atomic_t IdleInTransactionSessionTimeoutPending; extern PGDLLIMPORT volatile sig_atomic_t ConfigReloadPending; -extern volatile bool ClientConnectionLost; +extern PGDLLIMPORT volatile sig_atomic_t ClientConnectionLost; /* these are marked volatile because they are examined by signal handlers: */ extern PGDLLIMPORT volatile uint32 InterruptHoldoffCount; @@ -149,6 +150,7 @@ extern PGDLLIMPORT bool IsPostmasterEnvironment; extern PGDLLIMPORT bool IsUnderPostmaster; extern PGDLLIMPORT bool IsBackgroundWorker; extern PGDLLIMPORT bool IsBinaryUpgrade; +extern PGDLLIMPORT bool IsOnlineUpgrade; extern PGDLLIMPORT bool ExitOnAnyError; @@ -163,6 +165,7 @@ extern PGDLLIMPORT int max_parallel_workers; extern PGDLLIMPORT int MyProcPid; extern PGDLLIMPORT pg_time_t MyStartTime; +extern PGDLLIMPORT TimestampTz MyStartTimestamp; extern PGDLLIMPORT struct Port *MyProcPort; extern PGDLLIMPORT struct Latch *MyLatch; extern int32 MyCancelKey; @@ -248,7 +251,7 @@ extern int VacuumCostPageHit; extern int VacuumCostPageMiss; extern int VacuumCostPageDirty; extern int VacuumCostLimit; -extern int VacuumCostDelay; +extern double VacuumCostDelay; extern int VacuumPageHit; extern int VacuumPageMiss; @@ -423,7 +426,7 @@ extern AuxProcType MyAuxProcType; extern void pg_split_opts(char **argv, int *argcp, const char *optstr); extern void InitializeMaxBackends(void); extern void InitPostgres(const char *in_dbname, Oid dboid, const char *username, - Oid useroid, char *out_dbname, bool override_allow_connections); + Oid useroid, char *out_dbname, bool override_allow_connections); extern void BaseInit(void); /* in utils/init/miscinit.c */ @@ -435,7 +438,7 @@ extern char *local_preload_libraries_string; extern void CreateDataDirLockFile(bool amPostmaster); extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster, - const char *socketDir); + const char *socketDir); extern void TouchSocketLockFiles(void); extern void AddToDataDirLockFile(int target_line, const char *str); extern bool RecheckDataDirLockFile(void); @@ -448,5 +451,6 @@ extern bool has_rolreplication(Oid roleid); /* in access/transam/xlog.c */ extern bool BackupInProgress(void); extern void CancelBackup(void); +extern void RegisterUnlinkLockFileCallback(void); #endif /* MISCADMIN_H */ diff --git a/src/include/nodes/bitmapset.h b/src/include/nodes/bitmapset.h index b6f1a9e6e54..0c645628e55 100644 --- a/src/include/nodes/bitmapset.h +++ b/src/include/nodes/bitmapset.h @@ -11,7 +11,7 @@ * bms_is_empty() in preference to testing for NULL.) * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/nodes/bitmapset.h * @@ -27,13 +27,25 @@ struct List; /* * Data representation + * + * Larger bitmap word sizes generally give better performance, so long as + * they're not wider than the processor can handle efficiently. We use + * 64-bit words if pointers are that large, else 32-bit words. */ +#if SIZEOF_VOID_P >= 8 + +#define BITS_PER_BITMAPWORD 64 +typedef uint64 bitmapword; /* must be an unsigned type */ +typedef int64 signedbitmapword; /* must be the matching signed type */ + +#else -/* The unit size can be adjusted by changing these three declarations: */ #define BITS_PER_BITMAPWORD 32 typedef uint32 bitmapword; /* must be an unsigned type */ typedef int32 signedbitmapword; /* must be the matching signed type */ +#endif + typedef struct Bitmapset { int nwords; /* number of words in array */ @@ -75,6 +87,7 @@ extern Bitmapset *bms_difference(const Bitmapset *a, const Bitmapset *b); extern bool bms_is_subset(const Bitmapset *a, const Bitmapset *b); extern BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset *b); extern bool bms_is_member(int x, const Bitmapset *a); +extern int bms_member_index(Bitmapset *a, int x); extern bool bms_overlap(const Bitmapset *a, const Bitmapset *b); extern bool bms_overlap_list(const Bitmapset *a, const struct List *b); extern bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b); diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 06456f07cc7..44f76082e99 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -4,7 +4,7 @@ * definitions for executor state nodes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/execnodes.h @@ -14,17 +14,18 @@ #ifndef EXECNODES_H #define EXECNODES_H -#include "access/genam.h" -#include "access/heapam.h" #include "access/tupconvert.h" #include "executor/instrument.h" +#include "fmgr.h" #include "lib/pairingheap.h" #include "nodes/params.h" #include "nodes/plannodes.h" +#include "partitioning/partdefs.h" #include "utils/hsearch.h" #include "utils/queryenvironment.h" #include "utils/reltrigger.h" #include "utils/sharedtuplestore.h" +#include "utils/snapshot.h" #include "utils/sortsupport.h" #include "utils/tuplestore.h" #include "utils/tuplesort.h" @@ -33,10 +34,14 @@ struct PlanState; /* forward references in this file */ +struct PartitionRoutingInfo; struct ParallelHashJoinState; +struct ExecRowMark; struct ExprState; struct ExprContext; +struct RangeTblEntry; /* avoid including parsenodes.h here */ struct ExprEvalStep; /* avoid including execExpr.h everywhere */ +struct CopyMultiInsertBuffer; /* ---------------- @@ -56,7 +61,7 @@ typedef Datum (*ExprStateEvalFunc) (struct ExprState *expression, typedef struct ExprState { - Node tag; + NodeTag tag; uint8 flags; /* bitmask of EEO_FLAG_* bits, see above */ @@ -120,7 +125,7 @@ typedef struct ExprState * * NumIndexAttrs total number of columns in this index * NumIndexKeyAttrs number of key columns in index - * KeyAttrNumbers underlying-rel attribute numbers used as keys + * IndexAttrNumbers underlying-rel attribute numbers used as keys * (zeroes indicate expressions). It also contains * info about included columns. * Expressions expr trees for expression entries, or NIL if none @@ -130,7 +135,7 @@ typedef struct ExprState * ExclusionOps Per-column exclusion operators, or NULL if none * ExclusionProcs Underlying function OIDs for ExclusionOps * ExclusionStrats Opclass strategy numbers for ExclusionOps - * UniqueOps Theses are like Exclusion*, but for unique indexes + * UniqueOps These are like Exclusion*, but for unique indexes * UniqueProcs * UniqueStrats * Unique is it a unique index? @@ -138,6 +143,7 @@ typedef struct ExprState * Concurrent are we doing a concurrent index build? * BrokenHotChain did we detect any broken HOT chains? * ParallelWorkers # of workers requested (excludes leader) + * Am Oid of index AM * AmCache private cache area for index AM * Context memory context holding this IndexInfo * @@ -150,7 +156,7 @@ typedef struct IndexInfo NodeTag type; int ii_NumIndexAttrs; /* total number of columns in index */ int ii_NumIndexKeyAttrs; /* number of key columns in index */ - AttrNumber ii_KeyAttrNumbers[INDEX_MAX_KEYS]; + AttrNumber ii_IndexAttrNumbers[INDEX_MAX_KEYS]; List *ii_Expressions; /* list of Expr */ List *ii_ExpressionsState; /* list of ExprState */ List *ii_Predicate; /* list of Expr */ @@ -363,17 +369,8 @@ typedef struct JunkFilter AttrNumber *jf_cleanMap; TupleTableSlot *jf_resultSlot; AttrNumber jf_junkAttNo; - AttrNumber jf_otherJunkAttNo; } JunkFilter; -typedef struct MergeState -{ - /* List of MERGE MATCHED action states */ - List *matchedActionStates; - /* List of MERGE NOT MATCHED action states */ - List *notMatchedActionStates; -} MergeState; - /* * OnConflictSetState * @@ -383,8 +380,9 @@ typedef struct OnConflictSetState { NodeTag type; + TupleTableSlot *oc_Existing; /* slot to store existing target tuple in */ + TupleTableSlot *oc_ProjSlot; /* CONFLICT ... SET ... projection target */ ProjectionInfo *oc_ProjInfo; /* for ON CONFLICT DO UPDATE SET */ - TupleDesc oc_ProjTupdesc; /* TupleDesc for the above projection */ ExprState *oc_WhereClause; /* state for the WHERE clause */ } OnConflictSetState; @@ -394,12 +392,19 @@ typedef struct OnConflictSetState * Whenever we update an existing relation, we have to update indexes on the * relation, and perhaps also fire triggers. ResultRelInfo holds all the * information needed about a result relation, including indexes. + * + * Normally, a ResultRelInfo refers to a table that is in the query's + * range table; then ri_RangeTableIndex is the RT index and ri_RelationDesc + * is just a copy of the relevant es_relations[] entry. But sometimes, + * in ResultRelInfos used only for triggers, ri_RangeTableIndex is zero + * and ri_RelationDesc is a separately-opened relcache pointer that needs + * to be separately closed. See ExecGetTriggerResultRel. */ typedef struct ResultRelInfo { NodeTag type; - /* result relation's range table index */ + /* result relation's range table index, or 0 if not in range table */ Index ri_RangeTableIndex; /* relation descriptor for result relation */ @@ -426,6 +431,11 @@ typedef struct ResultRelInfo /* optional runtime measurements for triggers */ Instrumentation *ri_TrigInstrument; + /* On-demand created slots for triggers / returning processing */ + TupleTableSlot *ri_ReturningSlot; /* for trigger output tuples */ + TupleTableSlot *ri_TrigOldSlot; /* for a trigger's old tuple */ + TupleTableSlot *ri_TrigNewSlot; /* for a trigger's new tuple */ + /* FDW callback functions, if foreign table */ struct FdwRoutine *ri_FdwRoutine; @@ -444,6 +454,9 @@ typedef struct ResultRelInfo /* array of constraint-checking expr states */ ExprState **ri_ConstraintExprs; + /* array of stored generated columns expr states */ + ExprState **ri_GeneratedExprs; + /* for removing junk attributes from tuples */ JunkFilter *ri_junkFilter; @@ -468,40 +481,13 @@ typedef struct ResultRelInfo /* relation descriptor for root partitioned table */ Relation ri_PartitionRoot; - /* true if ready for tuple routing */ - bool ri_PartitionReadyForRouting; - - int ri_PartitionLeafIndex; - /* for running MERGE on this result relation */ - MergeState *ri_mergeState; + /* Additional information specific to partition tuple routing */ + struct PartitionRoutingInfo *ri_PartitionInfo; - /* - * While executing MERGE, the target relation is processed twice; once - * as a target relation and once to run a join between the target and the - * source. We generate two different RTEs for these two purposes, one with - * rte->inh set to false and other with rte->inh set to true. - * - * Since the plan re-evaluated by EvalPlanQual uses the join RTE, we must - * install the updated tuple in the scan corresponding to that RTE. The - * following member tracks the index of the second RTE for EvalPlanQual - * purposes. ri_mergeTargetRTI is non-zero only when MERGE is in-progress. - * We use ri_mergeTargetRTI to run EvalPlanQual for MERGE and - * ri_RangeTableIndex elsewhere. - */ - Index ri_mergeTargetRTI; + /* For use by copy.c when performing multi-inserts */ + struct CopyMultiInsertBuffer *ri_CopyMultiInsertBuffer; } ResultRelInfo; -/* - * Get the Range table index for EvalPlanQual. - * - * We use the ri_mergeTargetRTI if set, otherwise use ri_RangeTableIndex. - * ri_mergeTargetRTI should really be ever set iff we're running MERGE. - */ -#define GetEPQRangeTableIndex(r) \ - (((r)->ri_mergeTargetRTI > 0) \ - ? (r)->ri_mergeTargetRTI \ - : (r)->ri_RangeTableIndex) - /* ---------------- * EState information * @@ -517,6 +503,11 @@ typedef struct EState Snapshot es_snapshot; /* time qual to use */ Snapshot es_crosscheck_snapshot; /* crosscheck time qual for RI */ List *es_range_table; /* List of RangeTblEntry */ + Index es_range_table_size; /* size of the range table arrays */ + Relation *es_relations; /* Array of per-range-table-entry Relation + * pointers, or NULL if not yet opened */ + struct ExecRowMark **es_rowmarks; /* Array of per-range-table-entry + * ExecRowMarks, or NULL if none */ PlannedStmt *es_plannedstmt; /* link to top of plan tree */ const char *es_sourceText; /* Source text from QueryDesc */ @@ -531,26 +522,23 @@ typedef struct EState ResultRelInfo *es_result_relation_info; /* currently active array elt */ /* - * Info about the target partitioned target table root(s) for - * update/delete queries. They required only to fire any per-statement - * triggers defined on the table. It exists separately from - * es_result_relations, because partitioned tables don't appear in the - * plan tree for the update/delete cases. + * Info about the partition root table(s) for insert/update/delete queries + * targeting partitioned tables. Only leaf partitions are mentioned in + * es_result_relations, but we need access to the roots for firing + * triggers and for runtime tuple routing. */ ResultRelInfo *es_root_result_relations; /* array of ResultRelInfos */ int es_num_root_result_relations; /* length of the array */ + PartitionDirectory es_partition_directory; /* for PartitionDesc lookup */ /* - * The following list contains ResultRelInfos created by the tuple - * routing code for partitions that don't already have one. + * The following list contains ResultRelInfos created by the tuple routing + * code for partitions that don't already have one. */ List *es_tuple_routing_result_relations; /* Stuff used for firing triggers: */ List *es_trig_target_relations; /* trigger-only ResultRelInfos */ - TupleTableSlot *es_trig_tuple_slot; /* for trigger output tuples */ - TupleTableSlot *es_trig_oldtup_slot; /* for TriggerEnabled */ - TupleTableSlot *es_trig_newtup_slot; /* for TriggerEnabled */ /* Parameter info: */ ParamListInfo es_param_list_info; /* values of external params */ @@ -563,10 +551,7 @@ typedef struct EState List *es_tupleTable; /* List of TupleTableSlots */ - List *es_rowMarks; /* List of ExecRowMarks */ - uint64 es_processed; /* # of tuples processed */ - Oid es_lastoid; /* last oid processed (by INSERT) */ int es_top_eflags; /* eflags passed to ExecutorStart */ int es_instrument; /* OR of InstrumentOption flags */ @@ -586,17 +571,12 @@ typedef struct EState ExprContext *es_per_tuple_exprcontext; /* - * These fields are for re-evaluating plan quals when an updated tuple is - * substituted in READ COMMITTED mode. es_epqTuple[] contains tuples that - * scan plan nodes should return instead of whatever they'd normally - * return, or NULL if nothing to return; es_epqTupleSet[] is true if a - * particular array entry is valid; and es_epqScanDone[] is state to - * remember if the tuple has been returned already. Arrays are of size - * list_length(es_range_table) and are indexed by scan node scanrelid - 1. + * If not NULL, this is an EPQState's EState. This is a field in EState + * both to allow EvalPlanQual aware executor nodes to detect that they + * need to perform EPQ related work, and to provide necessary information + * to do so. */ - HeapTuple *es_epqTuple; /* array of EPQ substitute tuples */ - bool *es_epqTupleSet; /* true if EPQ tuple is provided */ - bool *es_epqScanDone; /* true if EPQ tuple has been fetched */ + struct EPQState *es_epq_active; bool es_use_parallel_mode; /* can we use parallel workers? */ @@ -607,9 +587,14 @@ typedef struct EState * JIT information. es_jit_flags indicates whether JIT should be performed * and with which options. es_jit is created on-demand when JITing is * performed. + * + * es_jit_worker_instr is the combined, on demand allocated, + * instrumentation from all workers. The leader's instrumentation is kept + * separate, and is combined on demand by ExplainPrintJITSummary(). */ int es_jit_flags; struct JitContext *es_jit; + struct JitInstrumentation *es_jit_worker_instr; } EState; @@ -628,7 +613,9 @@ typedef struct EState * node that sources the relation (e.g., for a foreign table the FDW can use * ermExtra to hold information). * - * EState->es_rowMarks is a list of these structs. + * EState->es_rowmarks is an array of these structs, indexed by RT index, + * with NULLs for irrelevant RT indexes. es_rowmarks itself is NULL if + * there are no rowmarks. */ typedef struct ExecRowMark { @@ -650,7 +637,7 @@ typedef struct ExecRowMark * additional runtime representation of FOR [KEY] UPDATE/SHARE clauses * * Each LockRows and ModifyTable node keeps a list of the rowmarks it needs to - * deal with. In addition to a pointer to the related entry in es_rowMarks, + * deal with. In addition to a pointer to the related entry in es_rowmarks, * this struct carries the column number(s) of the resjunk columns associated * with the rowmark (see comments for PlanRowMark for more detail). In the * case of ModifyTable, there has to be a separate ExecAuxRowMark list for @@ -659,7 +646,7 @@ typedef struct ExecRowMark */ typedef struct ExecAuxRowMark { - ExecRowMark *rowmark; /* related entry in es_rowMarks */ + ExecRowMark *rowmark; /* related entry in es_rowmarks */ AttrNumber ctidAttNo; /* resno of ctid junk attribute, if any */ AttrNumber toidAttNo; /* resno of tableoid junk attribute, if any */ AttrNumber wholeAttNo; /* resno of whole-row junk attribute, if any */ @@ -708,6 +695,7 @@ typedef struct TupleHashTableData AttrNumber *keyColIdx; /* attr numbers of key columns */ FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ ExprState *tab_eq_func; /* comparator for table datatype(s) */ + Oid *tab_collations; /* collations for hash and comparison */ MemoryContext tablecxt; /* memory context containing table */ MemoryContext tempcxt; /* context for function evaluations */ Size entrysize; /* actual size to make each hash entry */ @@ -715,7 +703,7 @@ typedef struct TupleHashTableData /* The following fields are set transiently for each table search: */ TupleTableSlot *inputslot; /* current input tuple's slot */ FmgrInfo *in_hash_funcs; /* hash functions for input datatype(s) */ - ExprState *cur_eq_func; /* comparator for for input vs. table */ + ExprState *cur_eq_func; /* comparator for input vs. table */ uint32 hash_iv; /* hash-function IV */ ExprContext *exprcontext; /* expression context */ } TupleHashTableData; @@ -846,7 +834,7 @@ typedef struct SetExprState * (by InitFunctionCallInfoData) if func.fn_oid is valid. It also saves * argument values between calls, when setArgsValid is true. */ - FunctionCallInfoData fcinfo_data; + FunctionCallInfo fcinfo; } SetExprState; /* ---------------- @@ -875,7 +863,9 @@ typedef struct SubPlanState MemoryContext hashtempcxt; /* temp memory context for hash tables */ ExprContext *innerecontext; /* econtext for computing inner tuples */ AttrNumber *keyColIdx; /* control data for hash tables */ - Oid *tab_eq_funcoids;/* equality func oids for table datatype(s) */ + Oid *tab_eq_funcoids; /* equality func oids for table + * datatype(s) */ + Oid *tab_collations; /* collations for hash and comparison */ FmgrInfo *tab_hash_funcs; /* hash functions for table datatype(s) */ FmgrInfo *tab_eq_funcs; /* equality functions for table datatype(s) */ FmgrInfo *lhs_hash_funcs; /* hash functions for lefthand datatype(s) */ @@ -960,6 +950,9 @@ typedef struct PlanState Instrumentation *instrument; /* Optional runtime stats for this node */ WorkerInstrumentation *worker_instrument; /* per-worker instrumentation */ + /* Per-worker JIT instrumentation */ + struct SharedJitInstrumentation *worker_jit_instrument; + /* * Common structural data for all Plan types. These links to subsidiary * state trees parallel links in the associated plan tree (except for the @@ -981,6 +974,7 @@ typedef struct PlanState /* * Other run-time state needed by most if not all node types. */ + TupleDesc ps_ResultTupleDesc; /* node's return type */ TupleTableSlot *ps_ResultTupleSlot; /* slot for my result tuples */ ExprContext *ps_ExprContext; /* node's expression-evaluation context */ ProjectionInfo *ps_ProjInfo; /* info for doing tuple projection */ @@ -991,6 +985,42 @@ typedef struct PlanState * descriptor, without encoding knowledge about all executor nodes. */ TupleDesc scandesc; + + /* + * Define the slot types for inner, outer and scanslots for expression + * contexts with this state as a parent. If *opsset is set, then + * *opsfixed indicates whether *ops is guaranteed to be the type of slot + * used. That means that every slot in the corresponding + * ExprContext.ecxt_*tuple will point to a slot of that type, while + * evaluating the expression. If *opsfixed is false, but *ops is set, + * that indicates the most likely type of slot. + * + * The scan* fields are set by ExecInitScanTupleSlot(). If that's not + * called, nodes can initialize the fields themselves. + * + * If outer/inneropsset is false, the information is inferred on-demand + * using ExecGetResultSlotOps() on ->righttree/lefttree, using the + * corresponding node's resultops* fields. + * + * The result* fields are automatically set when ExecInitResultSlot is + * used (be it directly or when the slot is created by + * ExecAssignScanProjectionInfo() / + * ExecConditionalAssignProjectionInfo()). If no projection is necessary + * ExecConditionalAssignProjectionInfo() defaults those fields to the scan + * operations. + */ + const TupleTableSlotOps *scanops; + const TupleTableSlotOps *outerops; + const TupleTableSlotOps *innerops; + const TupleTableSlotOps *resultops; + bool scanopsfixed; + bool outeropsfixed; + bool inneropsfixed; + bool resultopsfixed; + bool scanopsset; + bool outeropsset; + bool inneropsset; + bool resultopsset; } PlanState; /* ---------------- @@ -1004,6 +1034,11 @@ typedef struct PlanState #define outerPlanState(node) (((PlanState *)(node))->lefttree) /* Macros for inline access to certain instrumentation counters */ +#define InstrCountTuples2(node, delta) \ + do { \ + if (((PlanState *)(node))->instrument) \ + ((PlanState *)(node))->instrument->ntuples2 += (delta); \ + } while (0) #define InstrCountFiltered1(node, delta) \ do { \ if (((PlanState *)(node))->instrument) \ @@ -1014,25 +1049,76 @@ typedef struct PlanState if (((PlanState *)(node))->instrument) \ ((PlanState *)(node))->instrument->nfiltered2 += (delta); \ } while(0) -#define InstrCountFiltered3(node, delta) \ - do { \ - if (((PlanState *)(node))->instrument) \ - ((PlanState *)(node))->instrument->nfiltered3 += (delta); \ - } while(0) /* * EPQState is state for executing an EvalPlanQual recheck on a candidate - * tuple in ModifyTable or LockRows. The estate and planstate fields are - * NULL if inactive. + * tuples e.g. in ModifyTable or LockRows. + * + * To execute EPQ a separate EState is created (stored in ->recheckestate), + * which shares some resources, like the rangetable, with the main query's + * EState (stored in ->parentestate). The (sub-)tree of the plan that needs to + * be rechecked (in ->plan), is separately initialized (into + * ->recheckplanstate), but shares plan nodes with the corresponding nodes in + * the main query. The scan nodes in that separate executor tree are changed + * to return only the current tuple of interest for the respective + * table. Those tuples are either provided by the caller (using + * EvalPlanQualSlot), and/or found using the rowmark mechanism (non-locking + * rowmarks by the EPQ machinery itself, locking ones by the caller). + * + * While the plan to be checked may be changed using EvalPlanQualSetPlan() - + * e.g. so all source plans for a ModifyTable node can be processed - all such + * plans need to share the same EState. */ typedef struct EPQState { - EState *estate; /* subsidiary EState */ - PlanState *planstate; /* plan state tree ready to be executed */ - TupleTableSlot *origslot; /* original output tuple to be rechecked */ + /* Initialized at EvalPlanQualInit() time: */ + + EState *parentestate; /* main query's EState */ + int epqParam; /* ID of Param to force scan node re-eval */ + + /* + * Tuples to be substituted by scan nodes. They need to set up, before + * calling EvalPlanQual()/EvalPlanQualNext(), into the slot returned by + * EvalPlanQualSlot(scanrelid). The array is indexed by scanrelid - 1. + */ + List *tuple_table; /* tuple table for relsubs_slot */ + TupleTableSlot **relsubs_slot; + + /* + * Initialized by EvalPlanQualInit(), may be changed later with + * EvalPlanQualSetPlan(): + */ + Plan *plan; /* plan tree to be executed */ List *arowMarks; /* ExecAuxRowMarks (non-locking only) */ - int epqParam; /* ID of Param to force scan node re-eval */ + + + /* + * The original output tuple to be rechecked. Set by + * EvalPlanQualSetSlot(), before EvalPlanQualNext() or EvalPlanQual() may + * be called. + */ + TupleTableSlot *origslot; + + + /* Initialized or reset by EvalPlanQualBegin(): */ + + EState *recheckestate; /* EState for EPQ execution, see above */ + + /* + * Rowmarks that can be fetched on-demand using + * EvalPlanQualFetchRowMark(), indexed by scanrelid - 1. Only non-locking + * rowmarks. + */ + ExecAuxRowMark **relsubs_rowmark; + + /* + * True if a relation's EPQ tuple has been fetched for relation, indexed + * by scanrelid - 1. + */ + bool *relsubs_done; + + PlanState *recheckplanstate; /* EPQ specific exec nodes, for ->plan */ } EPQState; @@ -1065,20 +1151,6 @@ typedef struct ProjectSetState MemoryContext argcontext; /* context for SRF arguments */ } ProjectSetState; -/* ---------------- - * MergeActionState information - * ---------------- - */ -typedef struct MergeActionState -{ - NodeTag type; - bool matched; /* true=MATCHED, false=NOT MATCHED */ - ExprState *whenqual; /* WHEN AND conditions */ - CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ - ProjectionInfo *proj; /* tuple projection info */ - TupleDesc tupDesc; /* tuple descriptor for projection */ -} MergeActionState; - /* ---------------- * ModifyTableState information * ---------------- @@ -1086,23 +1158,27 @@ typedef struct MergeActionState typedef struct ModifyTableState { PlanState ps; /* its first field is NodeTag */ - CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */ + CmdType operation; /* INSERT, UPDATE, or DELETE */ bool canSetTag; /* do we set the command tag/es_processed? */ bool mt_done; /* are we done? */ PlanState **mt_plans; /* subplans (one per target rel) */ int mt_nplans; /* number of plans in the array */ int mt_whichplan; /* which one is being executed (0..n-1) */ + TupleTableSlot **mt_scans; /* input tuple corresponding to underlying + * plans */ ResultRelInfo *resultRelInfo; /* per-subplan target relations */ ResultRelInfo *rootResultRelInfo; /* root target relation (partitioned * table root) */ List **mt_arowmarks; /* per-subplan ExecAuxRowMark lists */ EPQState mt_epqstate; /* for evaluating EvalPlanQual rechecks */ bool fireBSTriggers; /* do we need to fire stmt triggers? */ - TupleTableSlot *mt_existing; /* slot to store existing target tuple in */ List *mt_excludedtlist; /* the excluded pseudo relation's tlist */ - TupleTableSlot *mt_conflproj; /* CONFLICT ... SET ... projection target */ - TupleTableSlot *mt_mergeproj; /* MERGE action projection target */ + /* + * Slot for storing tuples in the root partitioned table's rowtype during + * an UPDATE of a partitioned table. + */ + TupleTableSlot *mt_root_tuple_slot; /* Tuple-routing support info */ struct PartitionTupleRouting *mt_partition_tuple_routing; @@ -1115,9 +1191,6 @@ typedef struct ModifyTableState /* Per plan map for tuple conversion from child to root */ TupleConversionMap **mt_per_subplan_tupconv_maps; - - /* Flags showing which subcommands are present INS/UPD/DEL/DO NOTHING */ - int mt_merge_subcommands; } ModifyTableState; /* ---------------- @@ -1126,7 +1199,7 @@ typedef struct ModifyTableState * nplans how many plans are in the array * whichplan which plan is being executed (0 .. n-1), or a * special negative value. See nodeAppend.c. - * pruningstate details required to allow partitions to be + * prune_state details required to allow partitions to be * eliminated from the scan, or NULL if not possible. * valid_subplans for runtime pruning, valid appendplans indexes to * scan. @@ -1145,6 +1218,8 @@ struct AppendState PlanState **appendplans; /* array of PlanStates for my inputs */ int as_nplans; int as_whichplan; + int as_first_partial_plan; /* Index of 'appendplans' containing + * the first partial plan */ ParallelAppendState *as_pstate; /* parallel coordination info */ Size pstate_len; /* size of parallel coordination info */ struct PartitionPruneState *as_prune_state; @@ -1161,6 +1236,12 @@ struct AppendState * slots current output tuple of each subplan * heap heap of active tuples * initialized true if we have fetched first tuple from each subplan + * noopscan true if partition pruning proved that none of the + * mergeplans can contain a record to satisfy this query. + * prune_state details required to allow partitions to be + * eliminated from the scan, or NULL if not possible. + * valid_subplans for runtime pruning, valid mergeplans indexes to + * scan. * ---------------- */ typedef struct MergeAppendState @@ -1173,6 +1254,9 @@ typedef struct MergeAppendState TupleTableSlot **ms_slots; /* array of length ms_nplans */ struct binaryheap *ms_heap; /* binary heap of slot indices */ bool ms_initialized; /* are subplans started? */ + bool ms_noopscan; + struct PartitionPruneState *ms_prune_state; + Bitmapset *ms_valid_subplans; } MergeAppendState; /* ---------------- @@ -1246,7 +1330,7 @@ typedef struct ScanState { PlanState ps; /* its first field is NodeTag */ Relation ss_currentRelation; - HeapScanDesc ss_currentScanDesc; + struct TableScanDescData *ss_currentScanDesc; TupleTableSlot *ss_ScanTupleSlot; } ScanState; @@ -1276,6 +1360,9 @@ typedef struct SampleScanState bool use_pagemode; /* use page-at-a-time visibility checking? */ bool begun; /* false means need to call BeginSampleScan */ uint32 seed; /* random seed */ + int64 donetuples; /* number of tuples already returned */ + bool haveblock; /* has a block for sampling been determined */ + bool done; /* exhausted all tuples? */ } SampleScanState; /* @@ -1285,14 +1372,14 @@ typedef struct SampleScanState */ typedef struct { - ScanKey scan_key; /* scankey to put value into */ + struct ScanKeyData *scan_key; /* scankey to put value into */ ExprState *key_expr; /* expr to evaluate to get value */ bool key_toastable; /* is expr's result a toastable datatype? */ } IndexRuntimeKeyInfo; typedef struct { - ScanKey scan_key; /* scankey to put value into */ + struct ScanKeyData *scan_key; /* scankey to put value into */ ExprState *array_expr; /* expr to evaluate to get array value */ int next_elem; /* next array element to use */ int num_elems; /* number of elems in current array value */ @@ -1323,7 +1410,7 @@ typedef struct * SortSupport for reordering ORDER BY exprs * OrderByTypByVals is the datatype of order by expression pass-by-value? * OrderByTypLens typlens of the datatypes of order by expressions - * pscan_len size of parallel index scan descriptor + * PscanLen size of parallel index scan descriptor * ---------------- */ typedef struct IndexScanState @@ -1331,16 +1418,16 @@ typedef struct IndexScanState ScanState ss; /* its first field is NodeTag */ ExprState *indexqualorig; List *indexorderbyorig; - ScanKey iss_ScanKeys; + struct ScanKeyData *iss_ScanKeys; int iss_NumScanKeys; - ScanKey iss_OrderByKeys; + struct ScanKeyData *iss_OrderByKeys; int iss_NumOrderByKeys; IndexRuntimeKeyInfo *iss_RuntimeKeys; int iss_NumRuntimeKeys; bool iss_RuntimeKeysReady; ExprContext *iss_RuntimeContext; Relation iss_RelationDesc; - IndexScanDesc iss_ScanDesc; + struct IndexScanDescData *iss_ScanDesc; /* These are needed for re-checking ORDER BY expr ordering */ pairingheap *iss_ReorderQueue; @@ -1367,27 +1454,27 @@ typedef struct IndexScanState * RuntimeContext expr context for evaling runtime Skeys * RelationDesc index relation descriptor * ScanDesc index scan descriptor + * TableSlot slot for holding tuples fetched from the table * VMBuffer buffer in use for visibility map testing, if any - * HeapFetches number of tuples we were forced to fetch from heap - * ioss_PscanLen Size of parallel index-only scan descriptor + * PscanLen size of parallel index-only scan descriptor * ---------------- */ typedef struct IndexOnlyScanState { ScanState ss; /* its first field is NodeTag */ ExprState *indexqual; - ScanKey ioss_ScanKeys; + struct ScanKeyData *ioss_ScanKeys; int ioss_NumScanKeys; - ScanKey ioss_OrderByKeys; + struct ScanKeyData *ioss_OrderByKeys; int ioss_NumOrderByKeys; IndexRuntimeKeyInfo *ioss_RuntimeKeys; int ioss_NumRuntimeKeys; bool ioss_RuntimeKeysReady; ExprContext *ioss_RuntimeContext; Relation ioss_RelationDesc; - IndexScanDesc ioss_ScanDesc; + struct IndexScanDescData *ioss_ScanDesc; + TupleTableSlot *ioss_TableSlot; Buffer ioss_VMBuffer; - long ioss_HeapFetches; Size ioss_PscanLen; } IndexOnlyScanState; @@ -1411,7 +1498,7 @@ typedef struct BitmapIndexScanState { ScanState ss; /* its first field is NodeTag */ TIDBitmap *biss_result; - ScanKey biss_ScanKeys; + struct ScanKeyData *biss_ScanKeys; int biss_NumScanKeys; IndexRuntimeKeyInfo *biss_RuntimeKeys; int biss_NumRuntimeKeys; @@ -1420,7 +1507,7 @@ typedef struct BitmapIndexScanState bool biss_RuntimeKeysReady; ExprContext *biss_RuntimeContext; Relation biss_RelationDesc; - IndexScanDesc biss_ScanDesc; + struct IndexScanDescData *biss_ScanDesc; } BitmapIndexScanState; /* ---------------- @@ -1476,7 +1563,7 @@ typedef struct ParallelBitmapHeapState * tbmiterator iterator for scanning current pages * tbmres current-page data * can_skip_fetch can we potentially skip tuple fetches in this scan? - * skip_fetch are we skipping tuple fetches on this page? + * return_empty_tuples number of empty tuples to return * vmbuffer buffer for visibility-map lookups * pvmbuffer ditto, for prefetched pages * exact_pages total number of exact pages retrieved @@ -1500,7 +1587,7 @@ typedef struct BitmapHeapScanState TBMIterator *tbmiterator; TBMIterateResult *tbmres; bool can_skip_fetch; - bool skip_fetch; + int return_empty_tuples; Buffer vmbuffer; Buffer pvmbuffer; long exact_pages; @@ -1620,15 +1707,15 @@ typedef struct TableFuncScanState ExprState *rowexpr; /* state for row-generating expression */ List *colexprs; /* state for column-generating expression */ List *coldefexprs; /* state for column default expressions */ - List *ns_names; /* list of str nodes with namespace names */ - List *ns_uris; /* list of states of namespace uri exprs */ + List *ns_names; /* same as TableFunc.ns_names */ + List *ns_uris; /* list of states of namespace URI exprs */ Bitmapset *notnulls; /* nullability flag for each output column */ void *opaque; /* table builder private space */ const struct TableFuncRoutine *routine; /* table builder methods */ FmgrInfo *in_functions; /* input function for each column */ Oid *typioparams; /* typioparam for each column */ int64 ordinal; /* row number to be output next */ - MemoryContext perValueCxt; /* short life context for value evaluation */ + MemoryContext perTableCxt; /* per-table context */ Tuplestorestate *tupstore; /* output tuple store */ } TableFuncScanState; @@ -1816,7 +1903,6 @@ typedef struct MergeJoinState * * hashclauses original form of the hashjoin condition * hj_OuterHashKeys the outer hash keys in the hashjoin condition - * hj_InnerHashKeys the inner hash keys in the hashjoin condition * hj_HashOperators the join operators in the hashjoin condition * hj_HashTable hash table for the hashjoin * (NULL if table not built yet) @@ -1847,8 +1933,8 @@ typedef struct HashJoinState JoinState js; /* its first field is NodeTag */ ExprState *hashclauses; List *hj_OuterHashKeys; /* list of ExprState nodes */ - List *hj_InnerHashKeys; /* list of ExprState nodes */ List *hj_HashOperators; /* list of operator OIDs */ + List *hj_Collations; HashJoinTable hj_HashTable; uint32 hj_CurHashValue; int hj_CurBucketNo; @@ -2016,8 +2102,8 @@ typedef struct WindowAggState WindowStatePerFunc perfunc; /* per-window-function information */ WindowStatePerAgg peragg; /* per-plain-aggregate information */ - ExprState *partEqfunction; /* equality funcs for partition columns */ - ExprState *ordEqfunction; /* equality funcs for ordering columns */ + ExprState *partEqfunction; /* equality funcs for partition columns */ + ExprState *ordEqfunction; /* equality funcs for ordering columns */ Tuplestorestate *buffer; /* stores rows of current partition */ int current_ptr; /* read pointer # for current row */ int framehead_ptr; /* read pointer # for frame head, if used */ @@ -2095,7 +2181,7 @@ typedef struct WindowAggState typedef struct UniqueState { PlanState ps; /* its first field is NodeTag */ - ExprState *eqfunction; /* tuple equality qual */ + ExprState *eqfunction; /* tuple equality qual */ } UniqueState; /* ---------------- @@ -2185,7 +2271,6 @@ typedef struct HashState PlanState ps; /* its first field is NodeTag */ HashJoinTable hashtable; /* hash table for the hashjoin */ List *hashkeys; /* list of ExprState nodes */ - /* hashkeys is same as parent's hj_InnerHashKeys */ SharedHashInfo *shared_info; /* one entry per worker */ HashInstrumentation *hinstrument; /* this worker's entry */ @@ -2235,8 +2320,6 @@ typedef struct LockRowsState PlanState ps; /* its first field is NodeTag */ List *lr_arowMarks; /* List of ExecAuxRowMarks */ EPQState lr_epqstate; /* for evaluating EvalPlanQual rechecks */ - HeapTuple *lr_curtuples; /* locked tuples (one entry per RT entry) */ - int lr_ntables; /* length of lr_curtuples[] array */ } LockRowsState; /* ---------------- diff --git a/src/include/nodes/extensible.h b/src/include/nodes/extensible.h index 3f909fb4595..402cdf13a37 100644 --- a/src/include/nodes/extensible.h +++ b/src/include/nodes/extensible.h @@ -4,7 +4,7 @@ * Definitions for extensible nodes and custom scans * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/extensible.h @@ -17,8 +17,8 @@ #include "access/parallel.h" #include "commands/explain.h" #include "nodes/execnodes.h" +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" /* maximum length of an extensible node identifier */ #define EXTNODENAME_MAX_LEN 64 @@ -72,7 +72,7 @@ typedef struct ExtensibleNodeMethods extern void RegisterExtensibleNodeMethods(const ExtensibleNodeMethods *method); extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *name, - bool missing_ok); + bool missing_ok); /* * Flags for custom paths, indicating what capabilities the resulting scan @@ -155,6 +155,6 @@ typedef struct CustomExecMethods extern void RegisterCustomScanMethods(const CustomScanMethods *methods); extern const CustomScanMethods *GetCustomScanMethods(const char *CustomName, - bool missing_ok); + bool missing_ok); #endif /* EXTENSIBLE_H */ diff --git a/src/include/nodes/lockoptions.h b/src/include/nodes/lockoptions.h index 24afd6efd41..8e8ccff43ca 100644 --- a/src/include/nodes/lockoptions.h +++ b/src/include/nodes/lockoptions.h @@ -4,7 +4,7 @@ * Common header for some locking-related declarations. * * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * src/include/nodes/lockoptions.h * @@ -43,4 +43,19 @@ typedef enum LockWaitPolicy LockWaitError } LockWaitPolicy; +/* + * Possible lock modes for a tuple. + */ +typedef enum LockTupleMode +{ + /* SELECT FOR KEY SHARE */ + LockTupleKeyShare, + /* SELECT FOR SHARE */ + LockTupleShare, + /* SELECT FOR NO KEY UPDATE, and UPDATEs that don't modify key columns */ + LockTupleNoKeyExclusive, + /* SELECT FOR UPDATE, UPDATEs that modify key columns, and DELETE */ + LockTupleExclusive +} LockTupleMode; + #endif /* LOCKOPTIONS_H */ diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h index 57bd52ff244..8032bb7aa2a 100644 --- a/src/include/nodes/makefuncs.h +++ b/src/include/nodes/makefuncs.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * makefuncs.h - * prototypes for the creator functions (for primitive nodes) + * prototypes for the creator functions of various nodes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/makefuncs.h @@ -14,46 +14,47 @@ #ifndef MAKEFUNC_H #define MAKEFUNC_H +#include "nodes/execnodes.h" #include "nodes/parsenodes.h" extern A_Expr *makeA_Expr(A_Expr_Kind kind, List *name, - Node *lexpr, Node *rexpr, int location); + Node *lexpr, Node *rexpr, int location); extern A_Expr *makeSimpleA_Expr(A_Expr_Kind kind, char *name, - Node *lexpr, Node *rexpr, int location); + Node *lexpr, Node *rexpr, int location); extern Var *makeVar(Index varno, - AttrNumber varattno, - Oid vartype, - int32 vartypmod, - Oid varcollid, - Index varlevelsup); + AttrNumber varattno, + Oid vartype, + int32 vartypmod, + Oid varcollid, + Index varlevelsup); extern Var *makeVarFromTargetEntry(Index varno, - TargetEntry *tle); + TargetEntry *tle); extern Var *makeWholeRowVar(RangeTblEntry *rte, - Index varno, - Index varlevelsup, - bool allowScalar); + Index varno, + Index varlevelsup, + bool allowScalar); extern TargetEntry *makeTargetEntry(Expr *expr, - AttrNumber resno, - char *resname, - bool resjunk); + AttrNumber resno, + char *resname, + bool resjunk); extern TargetEntry *flatCopyTargetEntry(TargetEntry *src_tle); extern FromExpr *makeFromExpr(List *fromlist, Node *quals); extern Const *makeConst(Oid consttype, - int32 consttypmod, - Oid constcollid, - int constlen, - Datum constvalue, - bool constisnull, - bool constbyval); + int32 consttypmod, + Oid constcollid, + int constlen, + Datum constvalue, + bool constisnull, + bool constbyval); extern Const *makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid); @@ -64,7 +65,7 @@ extern Expr *makeBoolExpr(BoolExprType boolop, List *args, int location); extern Alias *makeAlias(const char *aliasname, List *colnames); extern RelabelType *makeRelabelType(Expr *arg, Oid rtype, int32 rtypmod, - Oid rcollid, CoercionForm rformat); + Oid rcollid, CoercionForm rformat); extern RangeVar *makeRangeVar(char *schemaname, char *relname, int location); @@ -73,16 +74,32 @@ extern TypeName *makeTypeNameFromNameList(List *names); extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod); extern ColumnDef *makeColumnDef(const char *colname, - Oid typeOid, int32 typmod, Oid collOid); + Oid typeOid, int32 typmod, Oid collOid); extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args, - Oid funccollid, Oid inputcollid, CoercionForm fformat); + Oid funccollid, Oid inputcollid, CoercionForm fformat); extern FuncCall *makeFuncCall(List *name, List *args, int location); +extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset, + Expr *leftop, Expr *rightop, + Oid opcollid, Oid inputcollid); + +extern Expr *make_andclause(List *andclauses); +extern Expr *make_orclause(List *orclauses); +extern Expr *make_notclause(Expr *notclause); + +extern Node *make_and_qual(Node *qual1, Node *qual2); +extern Expr *make_ands_explicit(List *andclauses); +extern List *make_ands_implicit(Expr *clause); + +extern IndexInfo *makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, + List *expressions, List *predicates, + bool unique, bool isready, bool concurrent); + extern DefElem *makeDefElem(char *name, Node *arg, int location); extern DefElem *makeDefElemExtended(char *nameSpace, char *name, Node *arg, - DefElemAction defaction, int location); + DefElemAction defaction, int location); extern GroupingSet *makeGroupingSet(GroupingSetKind kind, List *content, int location); diff --git a/src/include/nodes/memnodes.h b/src/include/nodes/memnodes.h index 2a8d83f3d08..df0ae3625cb 100644 --- a/src/include/nodes/memnodes.h +++ b/src/include/nodes/memnodes.h @@ -4,7 +4,7 @@ * POSTGRES memory context node definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/memnodes.h @@ -79,6 +79,7 @@ typedef struct MemoryContextData /* these two fields are placed here to minimize alignment wastage: */ bool isReset; /* T = no space alloced since last reset */ bool allowInCritSection; /* allow palloc in critical section */ + int64 mem_allocated; /* track memory allocated for this context */ const MemoryContextMethods *methods; /* virtual function table */ MemoryContext parent; /* NULL if no parent (toplevel context) */ MemoryContext firstchild; /* head of linked list of children */ diff --git a/src/include/nodes/nodeFuncs.h b/src/include/nodes/nodeFuncs.h index 849f34d2a8e..0cb931c82c7 100644 --- a/src/include/nodes/nodeFuncs.h +++ b/src/include/nodes/nodeFuncs.h @@ -3,7 +3,7 @@ * nodeFuncs.h * Various general-purpose manipulations of Node trees * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/nodeFuncs.h @@ -22,8 +22,11 @@ #define QTW_IGNORE_RC_SUBQUERIES 0x03 /* both of above */ #define QTW_IGNORE_JOINALIASES 0x04 /* JOIN alias var lists */ #define QTW_IGNORE_RANGE_TABLE 0x08 /* skip rangetable entirely */ -#define QTW_EXAMINE_RTES 0x10 /* examine RTEs */ -#define QTW_DONT_COPY_QUERY 0x20 /* do not copy top Query */ +#define QTW_EXAMINE_RTES_BEFORE 0x10 /* examine RTE nodes before their + * contents */ +#define QTW_EXAMINE_RTES_AFTER 0x20 /* examine RTE nodes after their + * contents */ +#define QTW_DONT_COPY_QUERY 0x40 /* do not copy top Query */ /* callback function for check_functions_in_node */ typedef bool (*check_function_callback) (Oid func_id, void *context); @@ -47,8 +50,80 @@ extern void fix_opfuncids(Node *node); extern void set_opfuncid(OpExpr *opexpr); extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); +/* Is clause a FuncExpr clause? */ +static inline bool +is_funcclause(const void *clause) +{ + return clause != NULL && IsA(clause, FuncExpr); +} + +/* Is clause an OpExpr clause? */ +static inline bool +is_opclause(const void *clause) +{ + return clause != NULL && IsA(clause, OpExpr); +} + +/* Extract left arg of a binary opclause, or only arg of a unary opclause */ +static inline Node * +get_leftop(const void *clause) +{ + const OpExpr *expr = (const OpExpr *) clause; + + if (expr->args != NIL) + return (Node *) linitial(expr->args); + else + return NULL; +} + +/* Extract right arg of a binary opclause (NULL if it's a unary opclause) */ +static inline Node * +get_rightop(const void *clause) +{ + const OpExpr *expr = (const OpExpr *) clause; + + if (list_length(expr->args) >= 2) + return (Node *) lsecond(expr->args); + else + return NULL; +} + +/* Is clause an AND clause? */ +static inline bool +is_andclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == AND_EXPR); +} + +/* Is clause an OR clause? */ +static inline bool +is_orclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == OR_EXPR); +} + +/* Is clause a NOT clause? */ +static inline bool +is_notclause(const void *clause) +{ + return (clause != NULL && + IsA(clause, BoolExpr) && + ((const BoolExpr *) clause)->boolop == NOT_EXPR); +} + +/* Extract argument from a clause known to be a NOT clause */ +static inline Expr * +get_notclausearg(const void *notclause) +{ + return (Expr *) linitial(((const BoolExpr *) notclause)->args); +} + extern bool check_functions_in_node(Node *node, check_function_callback checker, - void *context); + void *context); extern bool expression_tree_walker(Node *node, bool (*walker) (), void *context); diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index defdbae5070..bce2d59b0db 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -4,7 +4,7 @@ * Definitions for tagged nodes. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/nodes.h @@ -87,6 +87,10 @@ typedef enum NodeTag /* these aren't subclasses of Plan: */ T_NestLoopParam, T_PlanRowMark, + T_PartitionPruneInfo, + T_PartitionedRelPruneInfo, + T_PartitionPruneStepOp, + T_PartitionPruneStepCombine, T_PlanInvalItem, /* @@ -97,7 +101,6 @@ typedef enum NodeTag T_PlanState, T_ResultState, T_ProjectSetState, - T_MergeActionState, T_ModifyTableState, T_AppendState, T_MergeAppendState, @@ -151,7 +154,7 @@ typedef enum NodeTag T_Aggref, T_GroupingFunc, T_WindowFunc, - T_ArrayRef, + T_SubscriptingRef, T_FuncExpr, T_NamedArgExpr, T_OpExpr, @@ -193,10 +196,6 @@ typedef enum NodeTag T_FromExpr, T_OnConflictExpr, T_IntoClause, - T_PartitionPruneStep, - T_PartitionPruneStepOp, - T_PartitionPruneStepCombine, - T_PartitionPruneInfo, /* * TAGS FOR EXPRESSION STATE NODES (execnodes.h) @@ -216,7 +215,7 @@ typedef enum NodeTag T_DomainConstraintState, /* - * TAGS FOR PLANNER NODES (relation.h) + * TAGS FOR PLANNER NODES (pathnodes.h) */ T_PlannerInfo, T_PlannerGlobal, @@ -238,7 +237,7 @@ typedef enum NodeTag T_HashPath, T_AppendPath, T_MergeAppendPath, - T_ResultPath, + T_GroupResultPath, T_MaterialPath, T_UniquePath, T_GatherPath, @@ -263,6 +262,7 @@ typedef enum NodeTag T_PathKey, T_PathTarget, T_RestrictInfo, + T_IndexClause, T_PlaceHolderVar, T_SpecialJoinInfo, T_AppendRelInfo, @@ -272,7 +272,6 @@ typedef enum NodeTag T_RollupData, T_GroupingSetData, T_StatisticExtInfo, - T_MergeAction, /* * TAGS FOR MEMORY NODES (memnodes.h) @@ -313,7 +312,6 @@ typedef enum NodeTag T_InsertStmt, T_DeleteStmt, T_UpdateStmt, - T_MergeStmt, T_SelectStmt, T_AlterTableStmt, T_AlterTableCmd, @@ -422,6 +420,7 @@ typedef enum NodeTag T_CreateStatsStmt, T_AlterCollationStmt, T_CallStmt, + T_AlterStatsStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) @@ -478,7 +477,6 @@ typedef enum NodeTag T_PartitionRangeDatum, T_PartitionCmd, T_VacuumRelation, - T_MergeWhenClause, /* * TAGS FOR REPLICATION GRAMMAR PARSE NODES (replnodes.h) @@ -507,9 +505,15 @@ typedef enum NodeTag T_InlineCodeBlock, /* in nodes/parsenodes.h */ T_FdwRoutine, /* in foreign/fdwapi.h */ T_IndexAmRoutine, /* in access/amapi.h */ + T_TableAmRoutine, /* in access/tableam.h */ T_TsmRoutine, /* in access/tsmapi.h */ T_ForeignKeyCacheInfo, /* in utils/rel.h */ - T_CallContext /* in nodes/parsenodes.h */ + T_CallContext, /* in nodes/parsenodes.h */ + T_SupportRequestSimplify, /* in nodes/supportnodes.h */ + T_SupportRequestSelectivity, /* in nodes/supportnodes.h */ + T_SupportRequestCost, /* in nodes/supportnodes.h */ + T_SupportRequestRows, /* in nodes/supportnodes.h */ + T_SupportRequestIndexCondition /* in nodes/supportnodes.h */ } NodeTag; /* @@ -605,16 +609,19 @@ struct StringInfoData; /* not to include stringinfo.h here */ extern void outNode(struct StringInfoData *str, const void *obj); extern void outToken(struct StringInfoData *str, const char *s); extern void outBitmapset(struct StringInfoData *str, - const struct Bitmapset *bms); + const struct Bitmapset *bms); extern void outDatum(struct StringInfoData *str, uintptr_t value, - int typlen, bool typbyval); + int typlen, bool typbyval); extern char *nodeToString(const void *obj); extern char *bmsToString(const struct Bitmapset *bms); /* * nodes/{readfuncs.c,read.c} */ -extern void *stringToNode(char *str); +extern void *stringToNode(const char *str); +#ifdef WRITE_READ_PARSE_PLAN_TREES +extern void *stringToNodeWithLocations(const char *str); +#endif extern struct Bitmapset *readBitmapset(void); extern uintptr_t readDatum(bool typbyval); extern bool *readBoolCols(int numCols); @@ -664,8 +671,7 @@ typedef enum CmdType CMD_SELECT, /* select stmt */ CMD_UPDATE, /* update stmt */ CMD_INSERT, /* insert stmt */ - CMD_DELETE, /* delete stmt */ - CMD_MERGE, /* merge stmt */ + CMD_DELETE, CMD_UTILITY, /* cmds like create, destroy, copy, vacuum, * etc. */ CMD_NOTHING /* dummy command for instead nothing rules @@ -743,7 +749,7 @@ typedef enum JoinType * AggStrategy - * overall execution strategies for Agg plan nodes * - * This is needed in both plannodes.h and relation.h, so put it here... + * This is needed in both pathnodes.h and plannodes.h, so put it here... */ typedef enum AggStrategy { @@ -757,14 +763,14 @@ typedef enum AggStrategy * AggSplit - * splitting (partial aggregation) modes for Agg plan nodes * - * This is needed in both plannodes.h and relation.h, so put it here... + * This is needed in both pathnodes.h and plannodes.h, so put it here... */ /* Primitive options supported by nodeAgg.c: */ #define AGGSPLITOP_COMBINE 0x01 /* substitute combinefn for transfn */ #define AGGSPLITOP_SKIPFINAL 0x02 /* skip finalfn, return state as-is */ -#define AGGSPLITOP_SERIALIZE 0x04 /* apply serializefn to output */ -#define AGGSPLITOP_DESERIALIZE 0x08 /* apply deserializefn to input */ +#define AGGSPLITOP_SERIALIZE 0x04 /* apply serialfn to output */ +#define AGGSPLITOP_DESERIALIZE 0x08 /* apply deserialfn to input */ /* Supported operating modes (i.e., useful combinations of these options): */ typedef enum AggSplit @@ -787,7 +793,7 @@ typedef enum AggSplit * SetOpCmd and SetOpStrategy - * overall semantics and execution strategies for SetOp plan nodes * - * This is needed in both plannodes.h and relation.h, so put it here... + * This is needed in both pathnodes.h and plannodes.h, so put it here... */ typedef enum SetOpCmd { diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h index 04b03c7303e..fd9046619cc 100644 --- a/src/include/nodes/params.h +++ b/src/include/nodes/params.h @@ -4,7 +4,7 @@ * Support for finding the values associated with Param nodes. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/params.h @@ -151,6 +151,7 @@ typedef struct ParamExecData /* Functions found in src/backend/nodes/params.c */ +extern ParamListInfo makeParamList(int numParams); extern ParamListInfo copyParamList(ParamListInfo from); extern Size EstimateParamListSpace(ParamListInfo paramLI); extern void SerializeParamList(ParamListInfo paramLI, char **start_address); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index c8405386cf9..d93a79a5547 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -12,7 +12,7 @@ * identifying statement boundaries in multi-statement source strings. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/parsenodes.h @@ -26,6 +26,8 @@ #include "nodes/lockoptions.h" #include "nodes/primnodes.h" #include "nodes/value.h" +#include "partitioning/partdefs.h" + typedef enum OverridingKind { @@ -38,7 +40,7 @@ typedef enum OverridingKind typedef enum QuerySource { QSRC_ORIGINAL, /* original parsetree (explicit query) */ - QSRC_PARSER, /* added by parse analysis in MERGE */ + QSRC_PARSER, /* added by parse analysis (now unused) */ QSRC_INSTEAD_RULE, /* added by unconditional INSTEAD rule */ QSRC_QUAL_INSTEAD_RULE, /* added by conditional INSTEAD rule */ QSRC_NON_INSTEAD_RULE /* added by non-INSTEAD rule */ @@ -107,7 +109,7 @@ typedef struct Query { NodeTag type; - CmdType commandType; /* select|insert|update|delete|merge|utility */ + CmdType commandType; /* select|insert|update|delete|utility */ QuerySource querySource; /* where did I come from? */ @@ -118,7 +120,7 @@ typedef struct Query Node *utilityStmt; /* non-null if commandType == CMD_UTILITY */ int resultRelation; /* rtable index of target relation for - * INSERT/UPDATE/DELETE/MERGE; 0 for SELECT */ + * INSERT/UPDATE/DELETE; 0 for SELECT */ bool hasAggs; /* has aggregates in tlist or havingQual */ bool hasWindowFuncs; /* has window functions in tlist */ @@ -166,12 +168,8 @@ typedef struct Query List *constraintDeps; /* a list of pg_constraint OIDs that the query * depends on to be semantically valid */ - List *withCheckOptions; /* a list of WithCheckOption's, which are - * only added during rewrite and therefore - * are not written out as part of Query. */ - int mergeTarget_relation; - List *mergeSourceTargetList; - List *mergeActionList; /* list of actions for MERGE (only) */ + List *withCheckOptions; /* a list of WithCheckOption's (added + * during rewrite) */ /* * The following two fields identify the portion of the source text string @@ -226,7 +224,7 @@ typedef struct TypeName * Currently, A_Star must appear only as the last list element --- the grammar * is responsible for enforcing this! * - * Note: any array subscripting or selection of fields from composite columns + * Note: any container subscripting or selection of fields from composite columns * is represented by an A_Indirection node above the ColumnRef. However, * for simplicity in the normal case, initial field selection from a table * name is represented within ColumnRef and not by adding A_Indirection. @@ -651,13 +649,13 @@ typedef struct ColumnDef bool is_local; /* column has local (non-inherited) def'n */ bool is_not_null; /* NOT NULL constraint specified? */ bool is_from_type; /* column definition came from table type */ - bool is_from_parent; /* column def came from partition parent */ char storage; /* attstorage setting, or 0 for default */ Node *raw_default; /* default value (untransformed parse tree) */ Node *cooked_default; /* default value (transformed expr tree) */ char identity; /* attidentity setting */ - RangeVar *identitySequence; /* to store identity sequence name for ALTER - * TABLE ... ADD COLUMN */ + RangeVar *identitySequence; /* to store identity sequence name for + * ALTER TABLE ... ADD COLUMN */ + char generated; /* attgenerated setting */ CollateClause *collClause; /* untransformed COLLATE spec, if any */ Oid collOid; /* collation OID (InvalidOid if not set) */ List *constraints; /* other constraints on column */ @@ -680,10 +678,11 @@ typedef enum TableLikeOption CREATE_TABLE_LIKE_COMMENTS = 1 << 0, CREATE_TABLE_LIKE_CONSTRAINTS = 1 << 1, CREATE_TABLE_LIKE_DEFAULTS = 1 << 2, - CREATE_TABLE_LIKE_IDENTITY = 1 << 3, - CREATE_TABLE_LIKE_INDEXES = 1 << 4, - CREATE_TABLE_LIKE_STATISTICS = 1 << 5, - CREATE_TABLE_LIKE_STORAGE = 1 << 6, + CREATE_TABLE_LIKE_GENERATED = 1 << 3, + CREATE_TABLE_LIKE_IDENTITY = 1 << 4, + CREATE_TABLE_LIKE_INDEXES = 1 << 5, + CREATE_TABLE_LIKE_STATISTICS = 1 << 6, + CREATE_TABLE_LIKE_STORAGE = 1 << 7, CREATE_TABLE_LIKE_ALL = PG_INT32_MAX } TableLikeOption; @@ -806,7 +805,7 @@ typedef struct PartitionSpec * This represents the portion of the partition key space assigned to a * particular partition. These are stored on disk in pg_class.relpartbound. */ -typedef struct PartitionBoundSpec +struct PartitionBoundSpec { NodeTag type; @@ -825,7 +824,7 @@ typedef struct PartitionBoundSpec List *upperdatums; /* List of PartitionRangeDatums */ int location; /* token location, or -1 if unknown */ -} PartitionBoundSpec; +}; /* * PartitionRangeDatum - one of the values in a range partition bound @@ -936,6 +935,15 @@ typedef struct PartitionCmd * them in these fields. A whole-row Var reference is represented by * setting the bit for InvalidAttrNumber. * + * updatedCols is also used in some other places, for example, to determine + * which triggers to fire and in FDWs to know which changed columns they + * need to ship off. Generated columns that are caused to be updated by an + * update to a base column are collected in extraUpdatedCols. This is not + * considered for permission checking, but it is useful in those places + * that want to know the full set of columns being updated as opposed to + * only the ones the user explicitly mentioned in the query. (There is + * currently no need for an extraInsertedCols, but it could exist.) + * * securityQuals is a list of security barrier quals (boolean expressions), * to be tested in the listed order before returning a row from the * relation. It is always NIL in parser output. Entries are added by the @@ -953,7 +961,10 @@ typedef enum RTEKind RTE_TABLEFUNC, /* TableFunc(.., column list) */ RTE_VALUES, /* VALUES (), (), ... */ RTE_CTE, /* common table expr (WITH list element) */ - RTE_NAMEDTUPLESTORE /* tuplestore, e.g. for AFTER triggers */ + RTE_NAMEDTUPLESTORE, /* tuplestore, e.g. for AFTER triggers */ + RTE_RESULT /* RTE represents an empty FROM clause; such + * RTEs are added by the planner, they're not + * present during parsing or rewriting */ } RTEKind; typedef struct RangeTblEntry @@ -975,9 +986,21 @@ typedef struct RangeTblEntry * that the tuple format of the tuplestore is the same as the referenced * relation. This allows plans referencing AFTER trigger transition * tables to be invalidated if the underlying table is altered. + * + * rellockmode is really LOCKMODE, but it's declared int to avoid having + * to include lock-related headers here. It must be RowExclusiveLock if + * the RTE is an INSERT/UPDATE/DELETE target, else RowShareLock if the RTE + * is a SELECT FOR UPDATE/FOR SHARE target, else AccessShareLock. + * + * Note: in some cases, rule expansion may result in RTEs that are marked + * with RowExclusiveLock even though they are not the target of the + * current query; this happens if a DO ALSO rule simply scans the original + * target table. We leave such RTEs with their original lockmode so as to + * avoid getting an additional, lesser lock. */ Oid relid; /* OID of the relation */ char relkind; /* relation kind (see pg_class.relkind) */ + int rellockmode; /* lock level that query requires on the rel */ struct TableSampleClause *tablesample; /* sampling info, or NULL */ /* @@ -1035,7 +1058,7 @@ typedef struct RangeTblEntry bool self_reference; /* is this a recursive self-reference? */ /* - * Fields valid for table functions, values, CTE and ENR RTEs (else NIL): + * Fields valid for CTE, VALUES, ENR, and TableFunc RTEs (else NIL): * * We need these for CTE RTEs so that the types of self-referential * columns are well-defined. For VALUES RTEs, storing these explicitly @@ -1043,7 +1066,9 @@ typedef struct RangeTblEntry * ENRs, we store the types explicitly here (we could get the information * from the catalogs if 'relid' was supplied, but we'd still need these * for TupleDesc-based ENRs, so we might as well always store the type - * info here). + * info here). For TableFuncs, these fields are redundant with data in + * the TableFunc node, but keeping them here allows some code sharing with + * the other cases. * * For ENRs only, we have to consider the possibility of dropped columns. * A dropped column is included in these lists, but it will have zeroes in @@ -1073,6 +1098,7 @@ typedef struct RangeTblEntry Bitmapset *selectedCols; /* columns needing SELECT permission */ Bitmapset *insertedCols; /* columns needing INSERT permission */ Bitmapset *updatedCols; /* columns needing UPDATE permission */ + Bitmapset *extraUpdatedCols; /* generated columns being updated */ List *securityQuals; /* security barrier quals to apply, if any */ } RangeTblEntry; @@ -1131,9 +1157,7 @@ typedef enum WCOKind WCO_VIEW_CHECK, /* WCO on an auto-updatable view */ WCO_RLS_INSERT_CHECK, /* RLS INSERT WITH CHECK policy */ WCO_RLS_UPDATE_CHECK, /* RLS UPDATE WITH CHECK policy */ - WCO_RLS_CONFLICT_CHECK, /* RLS ON CONFLICT DO UPDATE USING policy */ - WCO_RLS_MERGE_UPDATE_CHECK, /* RLS MERGE UPDATE USING policy */ - WCO_RLS_MERGE_DELETE_CHECK /* RLS MERGE DELETE USING policy */ + WCO_RLS_CONFLICT_CHECK /* RLS ON CONFLICT DO UPDATE USING policy */ } WCOKind; typedef struct WithCheckOption @@ -1390,11 +1414,19 @@ typedef struct OnConflictClause * * We don't currently support the SEARCH or CYCLE clause. */ +typedef enum CTEMaterialize +{ + CTEMaterializeDefault, /* no option specified */ + CTEMaterializeAlways, /* MATERIALIZED */ + CTEMaterializeNever /* NOT MATERIALIZED */ +} CTEMaterialize; + typedef struct CommonTableExpr { NodeTag type; char *ctename; /* query name (never qualified) */ List *aliascolnames; /* optional list of column names */ + CTEMaterialize ctematerialized; /* is this an optimization fence? */ /* SelectStmt/InsertStmt/etc before parse analysis, Query afterwards: */ Node *ctequery; /* the CTE's subquery */ int location; /* token location, or -1 if unknown */ @@ -1508,46 +1540,6 @@ typedef struct UpdateStmt WithClause *withClause; /* WITH clause */ } UpdateStmt; -/* ---------------------- - * Merge Statement - * ---------------------- - */ -typedef struct MergeStmt -{ - NodeTag type; - RangeVar *relation; /* target relation to merge into */ - Node *source_relation; /* source relation */ - Node *join_condition; /* join condition between source and target */ - List *mergeWhenClauses; /* list of MergeWhenClause(es) */ - WithClause *withClause; /* WITH clause */ -} MergeStmt; - -typedef struct MergeWhenClause -{ - NodeTag type; - bool matched; /* true=MATCHED, false=NOT MATCHED */ - CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ - Node *condition; /* WHEN AND conditions (raw parser) */ - List *targetList; /* INSERT/UPDATE targetlist */ - /* the following members are only useful for INSERT action */ - List *cols; /* optional: names of the target columns */ - List *values; /* VALUES to INSERT, or NULL */ - OverridingKind override; /* OVERRIDING clause */ -} MergeWhenClause; - -/* - * WHEN [NOT] MATCHED THEN action info - */ -typedef struct MergeAction -{ - NodeTag type; - bool matched; /* true=MATCHED, false=NOT MATCHED */ - OverridingKind override; /* OVERRIDING clause */ - Node *qual; /* transformed WHEN AND conditions */ - CmdType commandType; /* INSERT/UPDATE/DELETE/DO NOTHING */ - List *targetList; /* the target list (of ResTarget) */ -} MergeAction; - /* ---------------------- * Select Statement * @@ -1772,6 +1764,7 @@ typedef enum AlterTableType AT_ColumnDefault, /* alter column default */ AT_DropNotNull, /* alter column drop not null */ AT_SetNotNull, /* alter column set not null */ + AT_CheckNotNull, /* check column is already marked not null */ AT_SetStatistics, /* alter column set statistics */ AT_SetOptions, /* alter column set ( options ) */ AT_ResetOptions, /* alter column reset ( options ) */ @@ -1800,8 +1793,6 @@ typedef enum AlterTableType AT_DropCluster, /* SET WITHOUT CLUSTER */ AT_SetLogged, /* SET LOGGED */ AT_SetUnLogged, /* SET UNLOGGED */ - AT_AddOids, /* SET WITH OIDS */ - AT_AddOidsRecurse, /* internal to commands/tablecmds.c */ AT_DropOids, /* SET WITHOUT OIDS */ AT_SetTableSpace, /* SET TABLESPACE */ AT_SetRelOptions, /* SET (...) -- AM specific parameters */ @@ -2002,6 +1993,7 @@ typedef struct CopyStmt bool is_program; /* is 'filename' a program to popen? */ char *filename; /* filename, or NULL for STDIN/STDOUT */ List *options; /* List of DefElem nodes */ + Node *whereClause; /* WHERE condition (or NULL) */ } CopyStmt; /* ---------------------- @@ -2065,6 +2057,7 @@ typedef struct CreateStmt List *options; /* options from WITH clause */ OnCommitAction oncommit; /* what do we do at COMMIT? */ char *tablespacename; /* table space to use, or NULL */ + char *accessMethod; /* table access method */ bool if_not_exists; /* just do nothing if it already exists? */ } CreateStmt; @@ -2106,6 +2099,7 @@ typedef enum ConstrType /* types of constraints */ CONSTR_NOTNULL, CONSTR_DEFAULT, CONSTR_IDENTITY, + CONSTR_GENERATED, CONSTR_CHECK, CONSTR_PRIMARY, CONSTR_UNIQUE, @@ -2144,7 +2138,7 @@ typedef struct Constraint bool is_no_inherit; /* is constraint non-inheritable? */ Node *raw_expr; /* expr, as untransformed parse tree */ char *cooked_expr; /* expr, as nodeToString representation */ - char generated_when; + char generated_when; /* ALWAYS or BY DEFAULT */ /* Fields used for unique constraints (UNIQUE and PRIMARY KEY): */ List *keys; /* String nodes naming referenced key @@ -2159,6 +2153,8 @@ typedef struct Constraint List *options; /* options from WITH clause */ char *indexname; /* existing index to use; otherwise NULL */ char *indexspace; /* index tablespace; NULL for default */ + bool reset_default_tblspc; /* reset default_tablespace prior to + * creating the index */ /* These could be, but currently are not, used for UNIQUE/PKEY: */ char *access_method; /* index access method; NULL for default */ Node *where_clause; /* partial index predicate */ @@ -2454,8 +2450,7 @@ typedef struct AlterEventTrigStmt } AlterEventTrigStmt; /* ---------------------- - * Create/Drop PROCEDURAL LANGUAGE Statements - * Create PROCEDURAL LANGUAGE Statements + * Create LANGUAGE Statements * ---------------------- */ typedef struct CreatePLangStmt @@ -2553,6 +2548,7 @@ typedef struct DefineStmt List *args; /* a list of TypeName (if needed) */ List *definition; /* a list of DefElem */ bool if_not_exists; /* just do nothing if it already exists? */ + bool replace; /* replace if already exists? */ } DefineStmt; /* ---------------------- @@ -2748,10 +2744,6 @@ typedef struct FetchStmt * index, just a UNIQUE/PKEY constraint using an existing index. isconstraint * must always be true in this case, and the fields describing the index * properties are empty. - * - * The relation to build the index on can be represented either by name - * (in which case the RangeVar indicates whether to recurse or not) or by OID - * (in which case the command is always recursive). * ---------------------- */ typedef struct IndexStmt @@ -2759,7 +2751,6 @@ typedef struct IndexStmt NodeTag type; char *idxname; /* name of new index, or NULL for default */ RangeVar *relation; /* relation to build index on */ - Oid relationId; /* OID of relation to build index on */ char *accessMethod; /* name of access method (eg. btree) */ char *tableSpace; /* tablespace, or NULL for default */ List *indexParams; /* columns to index: a list of IndexElem */ @@ -2779,6 +2770,8 @@ typedef struct IndexStmt bool transformed; /* true when transformIndexStmt is finished */ bool concurrent; /* should this be a concurrent index build? */ bool if_not_exists; /* just do nothing if index already exists? */ + bool reset_default_tblspc; /* reset default_tablespace prior to + * executing */ } IndexStmt; /* ---------------------- @@ -2796,6 +2789,18 @@ typedef struct CreateStatsStmt bool if_not_exists; /* do nothing if stats name already exists */ } CreateStatsStmt; +/* ---------------------- + * Alter Statistics Statement + * ---------------------- + */ +typedef struct AlterStatsStmt +{ + NodeTag type; + List *defnames; /* qualified name (list of Value strings) */ + int stxstattarget; /* statistics target */ + bool missing_ok; /* skip error if statistics object is missing */ +} AlterStatsStmt; + /* ---------------------- * Create Function Statement * ---------------------- @@ -3017,8 +3022,9 @@ typedef struct TransactionStmt NodeTag type; TransactionStmtKind kind; /* see above */ List *options; /* for BEGIN/START commands */ - char *savepoint_name; /* for savepoint commands */ + char *savepoint_name; /* for savepoint commands */ char *gid; /* for two-phase-commit related commands */ + bool chain; /* AND CHAIN option */ } TransactionStmt; /* ---------------------- @@ -3155,33 +3161,34 @@ typedef struct AlterSystemStmt * Cluster Statement (support pbrown's cluster index implementation) * ---------------------- */ +typedef enum ClusterOption +{ + CLUOPT_RECHECK = 1 << 0, /* recheck relation state */ + CLUOPT_VERBOSE = 1 << 1 /* print progress info */ +} ClusterOption; + typedef struct ClusterStmt { NodeTag type; RangeVar *relation; /* relation being indexed, or NULL if all */ char *indexname; /* original index defined */ - bool verbose; /* print progress info */ + int options; /* OR of ClusterOption flags */ } ClusterStmt; /* ---------------------- * Vacuum and Analyze Statements * * Even though these are nominally two statements, it's convenient to use - * just one node type for both. Note that at least one of VACOPT_VACUUM - * and VACOPT_ANALYZE must be set in options. + * just one node type for both. * ---------------------- */ -typedef enum VacuumOption +typedef struct VacuumStmt { - VACOPT_VACUUM = 1 << 0, /* do VACUUM */ - VACOPT_ANALYZE = 1 << 1, /* do ANALYZE */ - VACOPT_VERBOSE = 1 << 2, /* print progress info */ - VACOPT_FREEZE = 1 << 3, /* FREEZE option */ - VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ - VACOPT_NOWAIT = 1 << 5, /* don't wait to get lock (autovacuum only) */ - VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ - VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ -} VacuumOption; + NodeTag type; + List *options; /* list of DefElem nodes */ + List *rels; /* list of VacuumRelation, or NIL for all */ + bool is_vacuumcmd; /* true for VACUUM, false for ANALYZE */ +} VacuumStmt; /* * Info about a single target table of VACUUM/ANALYZE. @@ -3198,13 +3205,6 @@ typedef struct VacuumRelation List *va_cols; /* list of column names, or NIL for all */ } VacuumRelation; -typedef struct VacuumStmt -{ - NodeTag type; - int options; /* OR of VacuumOption flags */ - List *rels; /* list of VacuumRelation, or NIL for all */ -} VacuumStmt; - /* ---------------------- * Explain Statement * @@ -3312,7 +3312,8 @@ typedef struct ConstraintsSetStmt */ /* Reindex options */ -#define REINDEXOPT_VERBOSE 1 << 0 /* print progress info */ +#define REINDEXOPT_VERBOSE (1 << 0) /* print progress info */ +#define REINDEXOPT_REPORT_PROGRESS (1 << 1) /* report pgstat progress */ typedef enum ReindexObjectType { @@ -3331,6 +3332,7 @@ typedef struct ReindexStmt RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ int options; /* Reindex options flags */ + bool concurrent; /* reindex concurrently? */ } ReindexStmt; /* ---------------------- @@ -3475,7 +3477,7 @@ typedef struct AlterTSConfigurationStmt typedef struct CreatePublicationStmt { NodeTag type; - char *pubname; /* Name of of the publication */ + char *pubname; /* Name of the publication */ List *options; /* List of DefElem nodes */ List *tables; /* Optional list of tables to add */ bool for_all_tables; /* Special publication for all tables in db */ @@ -3484,7 +3486,7 @@ typedef struct CreatePublicationStmt typedef struct AlterPublicationStmt { NodeTag type; - char *pubname; /* Name of of the publication */ + char *pubname; /* Name of the publication */ /* parameters used for ALTER PUBLICATION ... WITH */ List *options; /* List of DefElem nodes */ @@ -3498,7 +3500,7 @@ typedef struct AlterPublicationStmt typedef struct CreateSubscriptionStmt { NodeTag type; - char *subname; /* Name of of the subscription */ + char *subname; /* Name of the subscription */ char *conninfo; /* Connection string to publisher */ List *publication; /* One or more publication to subscribe to */ List *options; /* List of DefElem nodes */ @@ -3517,7 +3519,7 @@ typedef struct AlterSubscriptionStmt { NodeTag type; AlterSubscriptionType kind; /* ALTER_SUBSCRIPTION_OPTIONS, etc */ - char *subname; /* Name of of the subscription */ + char *subname; /* Name of the subscription */ char *conninfo; /* Connection string to publisher */ List *publication; /* One or more publication to subscribe to */ List *options; /* List of DefElem nodes */ @@ -3526,7 +3528,7 @@ typedef struct AlterSubscriptionStmt typedef struct DropSubscriptionStmt { NodeTag type; - char *subname; /* Name of of the subscription */ + char *subname; /* Name of the subscription */ bool missing_ok; /* Skip error if missing? */ DropBehavior behavior; /* RESTRICT or CASCADE behavior */ } DropSubscriptionStmt; diff --git a/src/include/nodes/relation.h b/src/include/nodes/pathnodes.h similarity index 91% rename from src/include/nodes/relation.h rename to src/include/nodes/pathnodes.h index 73a41c5475a..23a06d718e3 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/pathnodes.h @@ -1,21 +1,20 @@ /*------------------------------------------------------------------------- * - * relation.h - * Definitions for planner's internal data structures. + * pathnodes.h + * Definitions for planner's internal data structures, especially Paths. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/include/nodes/relation.h + * src/include/nodes/pathnodes.h * *------------------------------------------------------------------------- */ -#ifndef RELATION_H -#define RELATION_H +#ifndef PATHNODES_H +#define PATHNODES_H #include "access/sdir.h" -#include "fmgr.h" #include "lib/stringinfo.h" #include "nodes/params.h" #include "nodes/parsenodes.h" @@ -61,7 +60,7 @@ typedef struct AggClauseCosts bool hasNonPartial; /* does any agg not support partial mode? */ bool hasNonSerial; /* is any partial agg non-serializable? */ QualCost transCost; /* total per-input-row execution costs */ - Cost finalCost; /* total per-aggregated-row costs */ + QualCost finalCost; /* total per-aggregated-row costs */ Size transitionSpace; /* space for pass-by-ref transition data */ } AggClauseCosts; @@ -82,6 +81,17 @@ typedef enum UpperRelationKind /* NB: UPPERREL_FINAL must be last enum entry; it's used to size arrays */ } UpperRelationKind; +/* + * This enum identifies which type of relation is being planned through the + * inheritance planner. INHKIND_NONE indicates the inheritance planner + * was not used. + */ +typedef enum InheritanceKind +{ + INHKIND_NONE, + INHKIND_INHERITED, + INHKIND_PARTITIONED +} InheritanceKind; /*---------- * PlannerGlobal @@ -110,7 +120,6 @@ typedef struct PlannerGlobal List *resultRelations; /* "flat" list of integer RT indexes */ - List *nonleafResultRelations; /* "flat" list of integer RT indexes */ List *rootResultRelations; /* "flat" list of integer RT indexes */ List *relationOids; /* OIDs of relations the plan depends on */ @@ -134,6 +143,8 @@ typedef struct PlannerGlobal bool parallelModeNeeded; /* parallel mode actually required? */ char maxParallelHazard; /* worst PROPARALLEL hazard level */ + + PartitionDirectory partition_directory; /* partition descriptors */ } PlannerGlobal; /* macro for fetching the Plan associated with a SubPlan node */ @@ -149,9 +160,17 @@ typedef struct PlannerGlobal * It holds links to all of the planner's working state, in addition to the * original Query. Note that at present the planner extensively modifies * the passed-in Query data structure; someday that should stop. + * + * For reasons explained in optimizer/optimizer.h, we define the typedef + * either here or in that header, whichever is read first. *---------- */ -typedef struct PlannerInfo +#ifndef HAVE_PLANNERINFO_TYPEDEF +typedef struct PlannerInfo PlannerInfo; +#define HAVE_PLANNERINFO_TYPEDEF 1 +#endif + +struct PlannerInfo { NodeTag type; @@ -161,7 +180,7 @@ typedef struct PlannerInfo Index query_level; /* 1 at the outermost Query */ - struct PlannerInfo *parent_root; /* NULL at outermost Query */ + PlannerInfo *parent_root; /* NULL at outermost Query */ /* * plan_params contains the expressions that this query level needs to @@ -184,12 +203,19 @@ typedef struct PlannerInfo /* * simple_rte_array is the same length as simple_rel_array and holds - * pointers to the associated rangetable entries. This lets us avoid - * rt_fetch(), which can be a bit slow once large inheritance sets have - * been expanded. + * pointers to the associated rangetable entries. Using this is a shade + * faster than using rt_fetch(), mostly due to fewer indirections. */ RangeTblEntry **simple_rte_array; /* rangetable as an array */ + /* + * append_rel_array is the same length as the above arrays, and holds + * pointers to the corresponding AppendRelInfo entry indexed by + * child_relid, or NULL if the rel is not an appendrel child. The array + * itself is not allocated if append_rel_list is empty. + */ + struct AppendRelInfo **append_rel_array; + /* * all_baserels is a Relids set of all base relids (but not "other" * relids) in the query; that is, the Relids identifier of the final join @@ -237,6 +263,8 @@ typedef struct PlannerInfo List *eq_classes; /* list of active EquivalenceClasses */ + bool ec_merging_done; /* set true once ECs are canonical */ + List *canon_pathkeys; /* list of "canonical" PathKeys */ List *left_join_clauses; /* list of RestrictInfos for mergejoinable @@ -252,6 +280,11 @@ typedef struct PlannerInfo List *join_info_list; /* list of SpecialJoinInfos */ + /* + * Note: for AppendRelInfos describing partitions of a partitioned table, + * we guarantee that partitions that come earlier in the partitioned + * table's PartitionDesc will appear earlier in append_rel_list. + */ List *append_rel_list; /* list of AppendRelInfos */ List *rowMarks; /* list of PlanRowMarks */ @@ -279,8 +312,13 @@ typedef struct PlannerInfo struct PathTarget *upper_targets[UPPERREL_FINAL + 1]; /* - * grouping_planner passes back its final processed targetlist here, for - * use in relabeling the topmost tlist of the finished Plan. + * The fully-processed targetlist is kept here. It differs from + * parse->targetList in that (for INSERT and UPDATE) it's been reordered + * to match the target table, and defaults have been filled in. Also, + * additional resjunk targets may be present. preprocess_targetlist() + * does most of this work, but note that more resjunk targets can get + * added during appendrel expansion. (Hence, upper_targets mustn't get + * set up till after that.) */ List *processed_tlist; @@ -290,7 +328,8 @@ typedef struct PlannerInfo MemoryContext planner_cxt; /* context holding PlannerInfo */ - double total_table_pages; /* # of pages in all tables of query */ + double total_table_pages; /* # of pages in all non-dummy tables of + * query */ double tuple_fraction; /* tuple_fraction passed to query_planner */ double limit_tuples; /* limit_tuples passed to query_planner */ @@ -298,11 +337,11 @@ typedef struct PlannerInfo Index qual_security_level; /* minimum security_level for quals */ /* Note: qual_security_level is zero if there are no securityQuals */ - bool hasInheritedTarget; /* true if parse->resultRelation is an - * inheritance child rel */ + InheritanceKind inhTargetKind; /* indicates if the target relation is an + * inheritance child or partition or a + * partitioned table */ bool hasJoinRTEs; /* true if any RTEs are RTE_JOIN kind */ bool hasLateralRTEs; /* true if any RTEs are marked LATERAL */ - bool hasDeletedRTEs; /* true if any RTE was deleted from jointree */ bool hasHavingQual; /* true if havingQual was non-null */ bool hasPseudoConstantQuals; /* true if any RestrictInfo has * pseudoconstant = true */ @@ -321,7 +360,7 @@ typedef struct PlannerInfo /* Does this query modify any partition key columns? */ bool partColsUpdated; -} PlannerInfo; +}; /* @@ -360,7 +399,7 @@ typedef struct PartitionSchemeData bool *parttypbyval; /* Cached information about partition comparison functions. */ - FmgrInfo *partsupfunc; + struct FmgrInfo *partsupfunc; } PartitionSchemeData; typedef struct PartitionSchemeData *PartitionScheme; @@ -466,6 +505,8 @@ typedef struct PartitionSchemeData *PartitionScheme; * pages - number of disk pages in relation (zero if not a table) * tuples - number of tuples in relation (not considering restrictions) * allvisfrac - fraction of disk pages that are marked all-visible + * eclass_indexes - EquivalenceClasses that mention this rel (filled + * only after EC merging is complete) * subroot - PlannerInfo for subquery (NULL if it's not a subquery) * subplan_params - list of PlannerParamItems to be passed to subquery * @@ -540,8 +581,8 @@ typedef struct PartitionSchemeData *PartitionScheme; * part_rels - RelOptInfos for each partition * partexprs, nullable_partexprs - Partition key expressions * partitioned_child_rels - RT indexes of unpruned partitions of - * relation that are partitioned tables - * themselves + * this relation that are partitioned tables + * themselves, in hierarchical order * * Note: A base relation always has only one set of partition keys, but a join * relation may have as many sets of partition keys as the number of relations @@ -639,6 +680,8 @@ typedef struct RelOptInfo BlockNumber pages; /* size estimates derived from pg_class */ double tuples; double allvisfrac; + Bitmapset *eclass_indexes; /* Indexes in PlannerInfo's eq_classes list of + * ECs that mention this rel */ PlannerInfo *subroot; /* if subquery */ List *subplan_params; /* if subquery */ int rel_parallel_workers; /* wanted number of parallel workers */ @@ -665,8 +708,11 @@ typedef struct RelOptInfo * involving this rel */ bool has_eclass_joins; /* T means joininfo is incomplete */ - /* used by "other" relations */ - Relids top_parent_relids; /* Relids of topmost parents */ + /* used by partitionwise joins: */ + bool consider_partitionwise_join; /* consider partitionwise join + * paths? (if partitioned rel) */ + Relids top_parent_relids; /* Relids of topmost parents (if "other" + * rel) */ /* used for partitioned relations */ PartitionScheme part_scheme; /* Partitioning scheme. */ @@ -685,15 +731,12 @@ typedef struct RelOptInfo * * It's not enough to test whether rel->part_scheme is set, because it might * be that the basic partitioning properties of the input relations matched - * but the partition bounds did not. - * - * We treat dummy relations as unpartitioned. We could alternatively - * treat them as partitioned, but it's not clear whether that's a useful thing - * to do. + * but the partition bounds did not. Also, if we are able to prove a rel + * dummy (empty), we should henceforth treat it as unpartitioned. */ #define IS_PARTITIONED_REL(rel) \ ((rel)->part_scheme && (rel)->boundinfo && (rel)->nparts > 0 && \ - (rel)->part_rels && !(IS_DUMMY_REL(rel))) + (rel)->part_rels && !IS_DUMMY_REL(rel)) /* * Convenience macro to make sure that a partitioned relation has all the @@ -734,7 +777,12 @@ typedef struct RelOptInfo * (by plancat.c), indrestrictinfo and predOK are set later, in * check_index_predicates(). */ -typedef struct IndexOptInfo +#ifndef HAVE_INDEXOPTINFO_TYPEDEF +typedef struct IndexOptInfo IndexOptInfo; +#define HAVE_INDEXOPTINFO_TYPEDEF 1 +#endif + +struct IndexOptInfo { NodeTag type; @@ -788,7 +836,7 @@ typedef struct IndexOptInfo bool amcanparallel; /* does AM support parallel scan? */ /* Rather than include amapi.h here, we declare amcostestimate like this */ void (*amcostestimate) (); /* AM's cost estimator */ -} IndexOptInfo; +}; /* * ForeignKeyOptInfo @@ -1093,30 +1141,16 @@ typedef struct Path * * 'indexinfo' is the index to be scanned. * - * 'indexclauses' is a list of index qualification clauses, with implicit - * AND semantics across the list. Each clause is a RestrictInfo node from - * the query's WHERE or JOIN conditions. An empty list implies a full - * index scan. - * - * 'indexquals' has the same structure as 'indexclauses', but it contains - * the actual index qual conditions that can be used with the index. - * In simple cases this is identical to 'indexclauses', but when special - * indexable operators appear in 'indexclauses', they are replaced by the - * derived indexscannable conditions in 'indexquals'. - * - * 'indexqualcols' is an integer list of index column numbers (zero-based) - * of the same length as 'indexquals', showing which index column each qual - * is meant to be used with. 'indexquals' is required to be ordered by - * index column, so 'indexqualcols' must form a nondecreasing sequence. - * (The order of multiple quals for the same index column is unspecified.) + * 'indexclauses' is a list of IndexClause nodes, each representing one + * index-checkable restriction, with implicit AND semantics across the list. + * An empty list implies a full index scan. * * 'indexorderbys', if not NIL, is a list of ORDER BY expressions that have * been found to be usable as ordering operators for an amcanorderbyop index. * The list must match the path's pathkeys, ie, one expression per pathkey * in the same order. These are not RestrictInfos, just bare expressions, - * since they generally won't yield booleans. Also, unlike the case for - * quals, it's guaranteed that each expression has the index key on the left - * side of the operator. + * since they generally won't yield booleans. It's guaranteed that each + * expression has the index key on the left side of the operator. * * 'indexorderbycols' is an integer list of index column numbers (zero-based) * of the same length as 'indexorderbys', showing which index column each @@ -1142,8 +1176,6 @@ typedef struct IndexPath Path path; IndexOptInfo *indexinfo; List *indexclauses; - List *indexquals; - List *indexqualcols; List *indexorderbys; List *indexorderbycols; ScanDirection indexscandir; @@ -1151,6 +1183,50 @@ typedef struct IndexPath Selectivity indexselectivity; } IndexPath; +/* + * Each IndexClause references a RestrictInfo node from the query's WHERE + * or JOIN conditions, and shows how that restriction can be applied to + * the particular index. We support both indexclauses that are directly + * usable by the index machinery, which are typically of the form + * "indexcol OP pseudoconstant", and those from which an indexable qual + * can be derived. The simplest such transformation is that a clause + * of the form "pseudoconstant OP indexcol" can be commuted to produce an + * indexable qual (the index machinery expects the indexcol to be on the + * left always). Another example is that we might be able to extract an + * indexable range condition from a LIKE condition, as in "x LIKE 'foo%bar'" + * giving rise to "x >= 'foo' AND x < 'fop'". Derivation of such lossy + * conditions is done by a planner support function attached to the + * indexclause's top-level function or operator. + * + * indexquals is a list of RestrictInfos for the directly-usable index + * conditions associated with this IndexClause. In the simplest case + * it's a one-element list whose member is iclause->rinfo. Otherwise, + * it contains one or more directly-usable indexqual conditions extracted + * from the given clause. The 'lossy' flag indicates whether the + * indexquals are semantically equivalent to the original clause, or + * represent a weaker condition. + * + * Normally, indexcol is the index of the single index column the clause + * works on, and indexcols is NIL. But if the clause is a RowCompareExpr, + * indexcol is the index of the leading column, and indexcols is a list of + * all the affected columns. (Note that indexcols matches up with the + * columns of the actual indexable RowCompareExpr in indexquals, which + * might be different from the original in rinfo.) + * + * An IndexPath's IndexClause list is required to be ordered by index + * column, i.e. the indexcol values must form a nondecreasing sequence. + * (The order of multiple clauses for the same index column is unspecified.) + */ +typedef struct IndexClause +{ + NodeTag type; + struct RestrictInfo *rinfo; /* original restriction or join clause */ + List *indexquals; /* indexqual(s) derived from it */ + bool lossy; /* are indexquals a lossy version of clause? */ + AttrNumber indexcol; /* index column the clause uses (zero-based) */ + List *indexcols; /* multiple index columns, if RowCompare */ +} IndexClause; + /* * BitmapHeapPath represents one or more indexscans that generate TID bitmaps * instead of directly accessing the heap, followed by AND/OR combinations @@ -1204,8 +1280,8 @@ typedef struct BitmapOrPath * TidPath represents a scan by TID * * tidquals is an implicitly OR'ed list of qual expressions of the form - * "CTID = pseudoconstant" or "CTID = ANY(pseudoconstant_array)". - * Note they are bare expressions, not RestrictInfos. + * "CTID = pseudoconstant", or "CTID = ANY(pseudoconstant_array)", + * or a CurrentOfExpr for the relation. */ typedef struct TidPath { @@ -1286,6 +1362,9 @@ typedef struct CustomPath * elements. These cases are optimized during create_append_plan. * In particular, an AppendPath with no subpaths is a "dummy" path that * is created to represent the case that a relation is provably empty. + * (This is a convenient representation because it means that when we build + * an appendrel and find that all its children have been excluded, no extra + * action is needed to recognize the relation as dummy.) */ typedef struct AppendPath { @@ -1293,18 +1372,21 @@ typedef struct AppendPath /* RT indexes of non-leaf tables in a partition tree */ List *partitioned_rels; List *subpaths; /* list of component Paths */ - - /* Index of first partial path in subpaths */ + /* Index of first partial path in subpaths; list_length(subpaths) if none */ int first_partial_path; + double limit_tuples; /* hard limit on output tuples, or -1 */ } AppendPath; -#define IS_DUMMY_PATH(p) \ +#define IS_DUMMY_APPEND(p) \ (IsA((p), AppendPath) && ((AppendPath *) (p))->subpaths == NIL) -/* A relation that's been proven empty will have one path that is dummy */ -#define IS_DUMMY_REL(r) \ - ((r)->cheapest_total_path != NULL && \ - IS_DUMMY_PATH((r)->cheapest_total_path)) +/* + * A relation that's been proven empty will have one path that is dummy + * (but might have projection paths on top). For historical reasons, + * this is provided as a macro that wraps is_dummy_rel(). + */ +#define IS_DUMMY_REL(r) is_dummy_rel(r) +extern bool is_dummy_rel(RelOptInfo *rel); /* * MergeAppendPath represents a MergeAppend plan, ie, the merging of sorted @@ -1320,17 +1402,17 @@ typedef struct MergeAppendPath } MergeAppendPath; /* - * ResultPath represents use of a Result plan node to compute a variable-free - * targetlist with no underlying tables (a "SELECT expressions" query). - * The query could have a WHERE clause, too, represented by "quals". + * GroupResultPath represents use of a Result plan node to compute the + * output of a degenerate GROUP BY case, wherein we know we should produce + * exactly one row, which might then be filtered by a HAVING qual. * * Note that quals is a list of bare clauses, not RestrictInfos. */ -typedef struct ResultPath +typedef struct GroupResultPath { Path path; List *quals; -} ResultPath; +} GroupResultPath; /* * MaterialPath represents use of a Material plan node, i.e., caching of @@ -1387,8 +1469,7 @@ typedef struct GatherPath /* * GatherMergePath runs several copies of a plan in parallel and collects - * the results, preserving their common sort order. For gather merge, the - * parallel leader always executes the plan too, so we don't need single_copy. + * the results, preserving their common sort order. */ typedef struct GatherMergePath { @@ -1631,17 +1712,12 @@ typedef struct MinMaxAggPath /* * WindowAggPath represents generic computation of window functions - * - * Note: winpathkeys is separate from path.pathkeys because the actual sort - * order might be an extension of winpathkeys; but createplan.c needs to - * know exactly how many pathkeys match the window clause. */ typedef struct WindowAggPath { Path path; Path *subpath; /* path representing input source */ WindowClause *winclause; /* WindowClause we'll be using */ - List *winpathkeys; /* PathKeys for PARTITION keys + ORDER keys */ } WindowAggPath; /* @@ -1684,7 +1760,7 @@ typedef struct LockRowsPath } LockRowsPath; /* - * ModifyTablePath represents performing INSERT/UPDATE/DELETE/MERGE + * ModifyTablePath represents performing INSERT/UPDATE/DELETE modifications * * We represent most things that will be in the ModifyTable plan node * literally, except we have child Path(s) not Plan(s). But analysis of the @@ -1693,14 +1769,12 @@ typedef struct LockRowsPath typedef struct ModifyTablePath { Path path; - CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */ + CmdType operation; /* INSERT, UPDATE, or DELETE */ bool canSetTag; /* do we set the command tag/es_processed? */ Index nominalRelation; /* Parent RT index for use of EXPLAIN */ - /* RT indexes of non-leaf tables in a partition tree */ - List *partitioned_rels; + Index rootRelation; /* Root RT index, if target is partitioned */ bool partColsUpdated; /* some part key in hierarchy updated */ List *resultRelations; /* integer list of RT indexes */ - Index mergeTargetRelation; /* RT index of merge target relation */ List *subpaths; /* Path(s) producing source data */ List *subroots; /* per-target-table PlannerInfos */ List *withCheckOptionLists; /* per-target-table WCO lists */ @@ -1708,8 +1782,6 @@ typedef struct ModifyTablePath List *rowMarks; /* PlanRowMarks (non-locking only) */ OnConflictExpr *onconflict; /* ON CONFLICT clause, or NULL */ int epqParam; /* ID of Param for EvalPlanQual re-eval */ - List *mergeSourceTargetList; - List *mergeActionList; /* actions for MERGE */ } ModifyTablePath; /* @@ -1792,7 +1864,8 @@ typedef struct LimitPath * if we decide that it can be pushed down into the nullable side of the join. * In that case it acts as a plain filter qual for wherever it gets evaluated. * (In short, is_pushed_down is only false for non-degenerate outer join - * conditions. Possibly we should rename it to reflect that meaning?) + * conditions. Possibly we should rename it to reflect that meaning? But + * see also the comments for RINFO_IS_PUSHED_DOWN, below.) * * RestrictInfo nodes also contain an outerjoin_delayed flag, which is true * if the clause's applicability must be delayed due to any outer joins @@ -1934,6 +2007,20 @@ typedef struct RestrictInfo Selectivity right_mcvfreq; /* right side's most common val's freq */ } RestrictInfo; +/* + * This macro embodies the correct way to test whether a RestrictInfo is + * "pushed down" to a given outer join, that is, should be treated as a filter + * clause rather than a join clause at that outer join. This is certainly so + * if is_pushed_down is true; but examining that is not sufficient anymore, + * because outer-join clauses will get pushed down to lower outer joins when + * we generate a path for the lower outer join that is parameterized by the + * LHS of the upper one. We can detect such a clause by noting that its + * required_relids exceed the scope of the join. + */ +#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids) \ + ((rinfo)->is_pushed_down || \ + !bms_is_subset((rinfo)->required_relids, joinrelids)) + /* * Since mergejoinscansel() is a relatively expensive function, and would * otherwise be invoked many times while planning a large join tree, @@ -2035,8 +2122,12 @@ typedef struct PlaceHolderVar * plain innerjoin semantics. Note that lhs_strict, delay_upper_joins, and * of course the semi_xxx fields are not set meaningfully within such structs. */ +#ifndef HAVE_SPECIALJOININFO_TYPEDEF +typedef struct SpecialJoinInfo SpecialJoinInfo; +#define HAVE_SPECIALJOININFO_TYPEDEF 1 +#endif -typedef struct SpecialJoinInfo +struct SpecialJoinInfo { NodeTag type; Relids min_lefthand; /* base relids in minimum LHS for join */ @@ -2051,7 +2142,7 @@ typedef struct SpecialJoinInfo bool semi_can_hash; /* true if semi_operators are all hash */ List *semi_operators; /* OIDs of equality join operators */ List *semi_rhs_exprs; /* righthand-side expressions of these ops */ -} SpecialJoinInfo; +}; /* * Append-relation info. @@ -2356,6 +2447,24 @@ typedef struct PartitionwiseAggregateType patype; } GroupPathExtraData; +/* + * Struct for extra information passed to subroutines of grouping_planner + * + * limit_needed is true if we actually need a Limit plan node. + * limit_tuples is an estimated bound on the number of output tuples, + * or -1 if no LIMIT or couldn't estimate. + * count_est and offset_est are the estimated values of the LIMIT and OFFSET + * expressions computed by preprocess_limit() (see comments for + * preprocess_limit() for more information). + */ +typedef struct +{ + bool limit_needed; + double limit_tuples; + int64 count_est; + int64 offset_est; +} FinalPathExtraData; + /* * For speed reasons, cost estimation for join paths is performed in two * phases: the first phase tries to quickly derive a lower bound for the @@ -2393,4 +2502,4 @@ typedef struct JoinCostWorkspace double inner_rows_total; } JoinCostWorkspace; -#endif /* RELATION_H */ +#endif /* PATHNODES_H */ diff --git a/src/include/nodes/pg_list.h b/src/include/nodes/pg_list.h index e6cd2cdfba4..409d840e793 100644 --- a/src/include/nodes/pg_list.h +++ b/src/include/nodes/pg_list.h @@ -1,19 +1,19 @@ /*------------------------------------------------------------------------- * * pg_list.h - * interface for PostgreSQL generic linked list package + * interface for PostgreSQL generic list package * - * This package implements singly-linked homogeneous lists. + * Once upon a time, parts of Postgres were written in Lisp and used real + * cons-cell lists for major data structures. When that code was rewritten + * in C, we initially had a faithful emulation of cons-cell lists, which + * unsurprisingly was a performance bottleneck. A couple of major rewrites + * later, these data structures are actually simple expansible arrays; + * but the "List" name and a lot of the notation survives. * - * It is important to have constant-time length, append, and prepend - * operations. To achieve this, we deal with two distinct data - * structures: - * - * 1. A set of "list cells": each cell contains a data field and - * a link to the next cell in the list or NULL. - * 2. A single structure containing metadata about the list: the - * type of the list, pointers to the head and tail cells, and - * the length of the list. + * One important concession to the original implementation is that an empty + * list is always represented by a null pointer (preferentially written NIL). + * Non-empty lists have a header, which will not be relocated as long as the + * list remains non-empty, and an expansible data array. * * We support three types of lists: * @@ -27,7 +27,7 @@ * always be so; try to be careful to maintain the distinction.) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/pg_list.h @@ -40,51 +40,131 @@ #include "nodes/nodes.h" -typedef struct ListCell ListCell; +typedef union ListCell +{ + void *ptr_value; + int int_value; + Oid oid_value; +} ListCell; typedef struct List { NodeTag type; /* T_List, T_IntList, or T_OidList */ - int length; - ListCell *head; - ListCell *tail; + int length; /* number of elements currently present */ + int max_length; /* allocated length of elements[] */ + ListCell *elements; /* re-allocatable array of cells */ + /* We may allocate some cells along with the List header: */ + ListCell initial_elements[FLEXIBLE_ARRAY_MEMBER]; + /* If elements == initial_elements, it's not a separate allocation */ } List; -struct ListCell -{ - union - { - void *ptr_value; - int int_value; - Oid oid_value; - } data; - ListCell *next; -}; - /* * The *only* valid representation of an empty list is NIL; in other - * words, a non-NIL list is guaranteed to have length >= 1 and - * head/tail != NULL + * words, a non-NIL list is guaranteed to have length >= 1. */ #define NIL ((List *) NULL) /* - * These routines are used frequently. However, we can't implement - * them as macros, since we want to avoid double-evaluation of macro - * arguments. + * State structs for various looping macros below. + */ +typedef struct ForEachState +{ + const List *l; /* list we're looping through */ + int i; /* current element index */ +} ForEachState; + +typedef struct ForBothState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + int i; /* common element index */ +} ForBothState; + +typedef struct ForBothCellState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + int i1; /* current element indexes */ + int i2; +} ForBothCellState; + +typedef struct ForThreeState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + int i; /* common element index */ +} ForThreeState; + +typedef struct ForFourState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + const List *l4; + int i; /* common element index */ +} ForFourState; + +typedef struct ForFiveState +{ + const List *l1; /* lists we're looping through */ + const List *l2; + const List *l3; + const List *l4; + const List *l5; + int i; /* common element index */ +} ForFiveState; + +/* + * These routines are small enough, and used often enough, to justify being + * inline. */ + +/* Fetch address of list's first cell; NULL if empty list */ static inline ListCell * list_head(const List *l) { - return l ? l->head : NULL; + return l ? &l->elements[0] : NULL; +} + +/* Fetch address of list's last cell; NULL if empty list */ +static inline ListCell * +list_tail(const List *l) +{ + return l ? &l->elements[l->length - 1] : NULL; +} + +/* Fetch address of list's second cell, if it has one, else NULL */ +static inline ListCell * +list_second_cell(const List *l) +{ + if (l && l->length >= 2) + return &l->elements[1]; + else + return NULL; +} + +/* Fetch address of list's third cell, if it has one, else NULL */ +static inline ListCell * +list_third_cell(const List *l) +{ + if (l && l->length >= 3) + return &l->elements[2]; + else + return NULL; } +/* Fetch address of list's fourth cell, if it has one, else NULL */ static inline ListCell * -list_tail(List *l) +list_fourth_cell(const List *l) { - return l ? l->tail : NULL; + if (l && l->length >= 4) + return &l->elements[3]; + else + return NULL; } +/* Fetch list's length */ static inline int list_length(const List *l) { @@ -92,6 +172,11 @@ list_length(const List *l) } /* + * Macros to access the data values within List cells. + * + * Note that with the exception of the "xxx_node" macros, these are + * lvalues and can be assigned to. + * * NB: There is an unfortunate legacy from a previous incarnation of * the List API: the macro lfirst() was used to mean "the data in this * cons cell". To avoid changing every usage of lfirst(), that meaning @@ -99,13 +184,12 @@ list_length(const List *l) * the data it contains; to get the data in the first cell of a * List, use linitial(). Worse, lsecond() is more closely related to * linitial() than lfirst(): given a List, lsecond() returns the data - * in the second cons cell. + * in the second list cell. */ -#define lnext(lc) ((lc)->next) -#define lfirst(lc) ((lc)->data.ptr_value) -#define lfirst_int(lc) ((lc)->data.int_value) -#define lfirst_oid(lc) ((lc)->data.oid_value) +#define lfirst(lc) ((lc)->ptr_value) +#define lfirst_int(lc) ((lc)->int_value) +#define lfirst_oid(lc) ((lc)->oid_value) #define lfirst_node(type,lc) castNode(type, lfirst(lc)) #define linitial(l) lfirst(list_head(l)) @@ -113,19 +197,19 @@ list_length(const List *l) #define linitial_oid(l) lfirst_oid(list_head(l)) #define linitial_node(type,l) castNode(type, linitial(l)) -#define lsecond(l) lfirst(lnext(list_head(l))) -#define lsecond_int(l) lfirst_int(lnext(list_head(l))) -#define lsecond_oid(l) lfirst_oid(lnext(list_head(l))) +#define lsecond(l) lfirst(list_second_cell(l)) +#define lsecond_int(l) lfirst_int(list_second_cell(l)) +#define lsecond_oid(l) lfirst_oid(list_second_cell(l)) #define lsecond_node(type,l) castNode(type, lsecond(l)) -#define lthird(l) lfirst(lnext(lnext(list_head(l)))) -#define lthird_int(l) lfirst_int(lnext(lnext(list_head(l)))) -#define lthird_oid(l) lfirst_oid(lnext(lnext(list_head(l)))) +#define lthird(l) lfirst(list_third_cell(l)) +#define lthird_int(l) lfirst_int(list_third_cell(l)) +#define lthird_oid(l) lfirst_oid(list_third_cell(l)) #define lthird_node(type,l) castNode(type, lthird(l)) -#define lfourth(l) lfirst(lnext(lnext(lnext(list_head(l))))) -#define lfourth_int(l) lfirst_int(lnext(lnext(lnext(list_head(l))))) -#define lfourth_oid(l) lfirst_oid(lnext(lnext(lnext(list_head(l))))) +#define lfourth(l) lfirst(list_fourth_cell(l)) +#define lfourth_int(l) lfirst_int(list_fourth_cell(l)) +#define lfourth_oid(l) lfirst_oid(list_fourth_cell(l)) #define lfourth_node(type,l) castNode(type, lfourth(l)) #define llast(l) lfirst(list_tail(l)) @@ -136,38 +220,189 @@ list_length(const List *l) /* * Convenience macros for building fixed-length lists */ -#define list_make1(x1) lcons(x1, NIL) -#define list_make2(x1,x2) lcons(x1, list_make1(x2)) -#define list_make3(x1,x2,x3) lcons(x1, list_make2(x2, x3)) -#define list_make4(x1,x2,x3,x4) lcons(x1, list_make3(x2, x3, x4)) -#define list_make5(x1,x2,x3,x4,x5) lcons(x1, list_make4(x2, x3, x4, x5)) - -#define list_make1_int(x1) lcons_int(x1, NIL) -#define list_make2_int(x1,x2) lcons_int(x1, list_make1_int(x2)) -#define list_make3_int(x1,x2,x3) lcons_int(x1, list_make2_int(x2, x3)) -#define list_make4_int(x1,x2,x3,x4) lcons_int(x1, list_make3_int(x2, x3, x4)) -#define list_make5_int(x1,x2,x3,x4,x5) lcons_int(x1, list_make4_int(x2, x3, x4, x5)) - -#define list_make1_oid(x1) lcons_oid(x1, NIL) -#define list_make2_oid(x1,x2) lcons_oid(x1, list_make1_oid(x2)) -#define list_make3_oid(x1,x2,x3) lcons_oid(x1, list_make2_oid(x2, x3)) -#define list_make4_oid(x1,x2,x3,x4) lcons_oid(x1, list_make3_oid(x2, x3, x4)) -#define list_make5_oid(x1,x2,x3,x4,x5) lcons_oid(x1, list_make4_oid(x2, x3, x4, x5)) +#define list_make_ptr_cell(v) ((ListCell) {.ptr_value = (v)}) +#define list_make_int_cell(v) ((ListCell) {.int_value = (v)}) +#define list_make_oid_cell(v) ((ListCell) {.oid_value = (v)}) + +#define list_make1(x1) \ + list_make1_impl(T_List, list_make_ptr_cell(x1)) +#define list_make2(x1,x2) \ + list_make2_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2)) +#define list_make3(x1,x2,x3) \ + list_make3_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3)) +#define list_make4(x1,x2,x3,x4) \ + list_make4_impl(T_List, list_make_ptr_cell(x1), list_make_ptr_cell(x2), \ + list_make_ptr_cell(x3), list_make_ptr_cell(x4)) + +#define list_make1_int(x1) \ + list_make1_impl(T_IntList, list_make_int_cell(x1)) +#define list_make2_int(x1,x2) \ + list_make2_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2)) +#define list_make3_int(x1,x2,x3) \ + list_make3_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3)) +#define list_make4_int(x1,x2,x3,x4) \ + list_make4_impl(T_IntList, list_make_int_cell(x1), list_make_int_cell(x2), \ + list_make_int_cell(x3), list_make_int_cell(x4)) + +#define list_make1_oid(x1) \ + list_make1_impl(T_OidList, list_make_oid_cell(x1)) +#define list_make2_oid(x1,x2) \ + list_make2_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2)) +#define list_make3_oid(x1,x2,x3) \ + list_make3_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3)) +#define list_make4_oid(x1,x2,x3,x4) \ + list_make4_impl(T_OidList, list_make_oid_cell(x1), list_make_oid_cell(x2), \ + list_make_oid_cell(x3), list_make_oid_cell(x4)) + +/* + * Locate the n'th cell (counting from 0) of the list. + * It is an assertion failure if there is no such cell. + */ +static inline ListCell * +list_nth_cell(const List *list, int n) +{ + Assert(list != NIL); + Assert(n >= 0 && n < list->length); + return &list->elements[n]; +} + +/* + * Return the pointer value contained in the n'th element of the + * specified list. (List elements begin at 0.) + */ +static inline void * +list_nth(const List *list, int n) +{ + Assert(IsA(list, List)); + return lfirst(list_nth_cell(list, n)); +} + +/* + * Return the integer value contained in the n'th element of the + * specified list. + */ +static inline int +list_nth_int(const List *list, int n) +{ + Assert(IsA(list, IntList)); + return lfirst_int(list_nth_cell(list, n)); +} + +/* + * Return the OID value contained in the n'th element of the specified + * list. + */ +static inline Oid +list_nth_oid(const List *list, int n) +{ + Assert(IsA(list, OidList)); + return lfirst_oid(list_nth_cell(list, n)); +} + +#define list_nth_node(type,list,n) castNode(type, list_nth(list, n)) + +/* + * Get the given ListCell's index (from 0) in the given List. + */ +static inline int +list_cell_number(const List *l, const ListCell *c) +{ + Assert(c >= &l->elements[0] && c < &l->elements[l->length]); + return c - l->elements; +} + +/* + * Get the address of the next cell after "c" within list "l", or NULL if none. + */ +static inline ListCell * +lnext(const List *l, const ListCell *c) +{ + Assert(c >= &l->elements[0] && c < &l->elements[l->length]); + c++; + if (c < &l->elements[l->length]) + return (ListCell *) c; + else + return NULL; +} /* * foreach - - * a convenience macro which loops through the list + * a convenience macro for looping through a list + * + * "cell" must be the name of a "ListCell *" variable; it's made to point + * to each List element in turn. "cell" will be NULL after normal exit from + * the loop, but an early "break" will leave it pointing at the current + * List element. + * + * Beware of changing the List object while the loop is iterating. + * The current semantics are that we examine successive list indices in + * each iteration, so that insertion or deletion of list elements could + * cause elements to be re-visited or skipped unexpectedly. Previous + * implementations of foreach() behaved differently. However, it's safe + * to append elements to the List (or in general, insert them after the + * current element); such new elements are guaranteed to be visited. + * Also, the current element of the List can be deleted, if you use + * foreach_delete_current() to do so. BUT: either of these actions will + * invalidate the "cell" pointer for the remainder of the current iteration. + */ +#define foreach(cell, lst) \ + for (ForEachState cell##__state = {(lst), 0}; \ + (cell##__state.l != NIL && \ + cell##__state.i < cell##__state.l->length) ? \ + (cell = &cell##__state.l->elements[cell##__state.i], true) : \ + (cell = NULL, false); \ + cell##__state.i++) + +/* + * foreach_delete_current - + * delete the current list element from the List associated with a + * surrounding foreach() loop, returning the new List pointer. + * + * This is equivalent to list_delete_cell(), but it also adjusts the foreach + * loop's state so that no list elements will be missed. Do not delete + * elements from an active foreach loop's list in any other way! + */ +#define foreach_delete_current(lst, cell) \ + (cell##__state.i--, \ + (List *) (cell##__state.l = list_delete_cell(lst, cell))) + +/* + * foreach_current_index - + * get the zero-based list index of a surrounding foreach() loop's + * current element; pass the name of the "ListCell *" iterator variable. + * + * Beware of using this after foreach_delete_current(); the value will be + * out of sync for the rest of the current loop iteration. Anyway, since + * you just deleted the current element, the value is pretty meaningless. */ -#define foreach(cell, l) \ - for ((cell) = list_head(l); (cell) != NULL; (cell) = lnext(cell)) +#define foreach_current_index(cell) (cell##__state.i) /* * for_each_cell - * a convenience macro which loops through a list starting from a * specified cell + * + * The caveats for foreach() apply equally here. */ -#define for_each_cell(cell, initcell) \ - for ((cell) = (initcell); (cell) != NULL; (cell) = lnext(cell)) +#define for_each_cell(cell, lst, initcell) \ + for (ForEachState cell##__state = for_each_cell_setup(lst, initcell); \ + (cell##__state.l != NIL && \ + cell##__state.i < cell##__state.l->length) ? \ + (cell = &cell##__state.l->elements[cell##__state.i], true) : \ + (cell = NULL, false); \ + cell##__state.i++) + +static inline ForEachState +for_each_cell_setup(List *lst, ListCell *initcell) +{ + ForEachState r = {lst, + initcell ? list_cell_number(lst, initcell) : list_length(lst)}; + + return r; +} /* * forboth - @@ -175,12 +410,22 @@ list_length(const List *l) * simultaneously. This macro loops through both lists at the same * time, stopping when either list runs out of elements. Depending * on the requirements of the call site, it may also be wise to - * assert that the lengths of the two lists are equal. + * assert that the lengths of the two lists are equal. (But, if they + * are not, some callers rely on the ending cell values being separately + * NULL or non-NULL as defined here; don't try to optimize that.) + * + * The caveats for foreach() apply equally here. */ #define forboth(cell1, list1, cell2, list2) \ - for ((cell1) = list_head(list1), (cell2) = list_head(list2); \ - (cell1) != NULL && (cell2) != NULL; \ - (cell1) = lnext(cell1), (cell2) = lnext(cell2)) + for (ForBothState cell1##__state = {(list1), (list2), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + (cell1 != NULL && cell2 != NULL); \ + cell1##__state.i++) + +#define multi_for_advance_cell(cell, state, l, i) \ + (cell = (state.l != NIL && state.i < state.l->length) ? \ + &state.l->elements[state.i] : NULL) /* * for_both_cell - @@ -190,41 +435,93 @@ list_length(const List *l) * requirements of the call site, it may also be wise to assert that the * lengths of the two lists are equal, and initcell1 and initcell2 are at * the same position in the respective lists. + * + * The caveats for foreach() apply equally here. */ -#define for_both_cell(cell1, initcell1, cell2, initcell2) \ - for ((cell1) = (initcell1), (cell2) = (initcell2); \ - (cell1) != NULL && (cell2) != NULL; \ - (cell1) = lnext(cell1), (cell2) = lnext(cell2)) +#define for_both_cell(cell1, list1, initcell1, cell2, list2, initcell2) \ + for (ForBothCellState cell1##__state = \ + for_both_cell_setup(list1, initcell1, list2, initcell2); \ + multi_for_advance_cell(cell1, cell1##__state, l1, i1), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i2), \ + (cell1 != NULL && cell2 != NULL); \ + cell1##__state.i1++, cell1##__state.i2++) + +static inline ForBothCellState +for_both_cell_setup(List *list1, ListCell *initcell1, + List *list2, ListCell *initcell2) +{ + ForBothCellState r = {list1, list2, + initcell1 ? list_cell_number(list1, initcell1) : list_length(list1), + initcell2 ? list_cell_number(list2, initcell2) : list_length(list2)}; + + return r; +} /* * forthree - * the same for three lists */ -#define forthree(cell1, list1, cell2, list2, cell3, list3) \ - for ((cell1) = list_head(list1), (cell2) = list_head(list2), (cell3) = list_head(list3); \ - (cell1) != NULL && (cell2) != NULL && (cell3) != NULL; \ - (cell1) = lnext(cell1), (cell2) = lnext(cell2), (cell3) = lnext(cell3)) +#define forthree(cell1, list1, cell2, list2, cell3, list3) \ + for (ForThreeState cell1##__state = {(list1), (list2), (list3), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL); \ + cell1##__state.i++) + +/* + * forfour - + * the same for four lists + */ +#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4) \ + for (ForFourState cell1##__state = {(list1), (list2), (list3), (list4), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + multi_for_advance_cell(cell4, cell1##__state, l4, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL && cell4 != NULL); \ + cell1##__state.i++) + +/* + * forfive - + * the same for five lists + */ +#define forfive(cell1, list1, cell2, list2, cell3, list3, cell4, list4, cell5, list5) \ + for (ForFiveState cell1##__state = {(list1), (list2), (list3), (list4), (list5), 0}; \ + multi_for_advance_cell(cell1, cell1##__state, l1, i), \ + multi_for_advance_cell(cell2, cell1##__state, l2, i), \ + multi_for_advance_cell(cell3, cell1##__state, l3, i), \ + multi_for_advance_cell(cell4, cell1##__state, l4, i), \ + multi_for_advance_cell(cell5, cell1##__state, l5, i), \ + (cell1 != NULL && cell2 != NULL && cell3 != NULL && \ + cell4 != NULL && cell5 != NULL); \ + cell1##__state.i++) + +/* Functions in src/backend/nodes/list.c */ + +extern List *list_make1_impl(NodeTag t, ListCell datum1); +extern List *list_make2_impl(NodeTag t, ListCell datum1, ListCell datum2); +extern List *list_make3_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3); +extern List *list_make4_impl(NodeTag t, ListCell datum1, ListCell datum2, + ListCell datum3, ListCell datum4); extern List *lappend(List *list, void *datum); extern List *lappend_int(List *list, int datum); extern List *lappend_oid(List *list, Oid datum); -extern ListCell *lappend_cell(List *list, ListCell *prev, void *datum); -extern ListCell *lappend_cell_int(List *list, ListCell *prev, int datum); -extern ListCell *lappend_cell_oid(List *list, ListCell *prev, Oid datum); +extern List *list_insert_nth(List *list, int pos, void *datum); +extern List *list_insert_nth_int(List *list, int pos, int datum); +extern List *list_insert_nth_oid(List *list, int pos, Oid datum); extern List *lcons(void *datum, List *list); extern List *lcons_int(int datum, List *list); extern List *lcons_oid(Oid datum, List *list); -extern List *list_concat(List *list1, List *list2); -extern List *list_truncate(List *list, int new_size); +extern List *list_concat(List *list1, const List *list2); +extern List *list_concat_copy(const List *list1, const List *list2); -extern ListCell *list_nth_cell(const List *list, int n); -extern void *list_nth(const List *list, int n); -extern int list_nth_int(const List *list, int n); -extern Oid list_nth_oid(const List *list, int n); -#define list_nth_node(type,list,n) castNode(type, list_nth(list, n)) +extern List *list_truncate(List *list, int new_size); extern bool list_member(const List *list, const void *datum); extern bool list_member_ptr(const List *list, const void *datum); @@ -236,7 +533,9 @@ extern List *list_delete_ptr(List *list, void *datum); extern List *list_delete_int(List *list, int datum); extern List *list_delete_oid(List *list, Oid datum); extern List *list_delete_first(List *list); -extern List *list_delete_cell(List *list, ListCell *cell, ListCell *prev); +extern List *list_delete_last(List *list); +extern List *list_delete_nth_cell(List *list, int n); +extern List *list_delete_cell(List *list, ListCell *cell); extern List *list_union(const List *list1, const List *list2); extern List *list_union_ptr(const List *list1, const List *list2); @@ -258,87 +557,23 @@ extern List *list_append_unique_ptr(List *list, void *datum); extern List *list_append_unique_int(List *list, int datum); extern List *list_append_unique_oid(List *list, Oid datum); -extern List *list_concat_unique(List *list1, List *list2); -extern List *list_concat_unique_ptr(List *list1, List *list2); -extern List *list_concat_unique_int(List *list1, List *list2); -extern List *list_concat_unique_oid(List *list1, List *list2); +extern List *list_concat_unique(List *list1, const List *list2); +extern List *list_concat_unique_ptr(List *list1, const List *list2); +extern List *list_concat_unique_int(List *list1, const List *list2); +extern List *list_concat_unique_oid(List *list1, const List *list2); + +extern void list_deduplicate_oid(List *list); extern void list_free(List *list); extern void list_free_deep(List *list); extern List *list_copy(const List *list); extern List *list_copy_tail(const List *list, int nskip); +extern List *list_copy_deep(const List *oldlist); -typedef int (*list_qsort_comparator) (const void *a, const void *b); -extern List *list_qsort(const List *list, list_qsort_comparator cmp); - -/* - * To ease migration to the new list API, a set of compatibility - * macros are provided that reduce the impact of the list API changes - * as far as possible. Until client code has been rewritten to use the - * new list API, the ENABLE_LIST_COMPAT symbol can be defined before - * including pg_list.h - */ -#ifdef ENABLE_LIST_COMPAT - -#define lfirsti(lc) lfirst_int(lc) -#define lfirsto(lc) lfirst_oid(lc) - -#define makeList1(x1) list_make1(x1) -#define makeList2(x1, x2) list_make2(x1, x2) -#define makeList3(x1, x2, x3) list_make3(x1, x2, x3) -#define makeList4(x1, x2, x3, x4) list_make4(x1, x2, x3, x4) - -#define makeListi1(x1) list_make1_int(x1) -#define makeListi2(x1, x2) list_make2_int(x1, x2) - -#define makeListo1(x1) list_make1_oid(x1) -#define makeListo2(x1, x2) list_make2_oid(x1, x2) - -#define lconsi(datum, list) lcons_int(datum, list) -#define lconso(datum, list) lcons_oid(datum, list) - -#define lappendi(list, datum) lappend_int(list, datum) -#define lappendo(list, datum) lappend_oid(list, datum) - -#define nconc(l1, l2) list_concat(l1, l2) - -#define nth(n, list) list_nth(list, n) - -#define member(datum, list) list_member(list, datum) -#define ptrMember(datum, list) list_member_ptr(list, datum) -#define intMember(datum, list) list_member_int(list, datum) -#define oidMember(datum, list) list_member_oid(list, datum) - -/* - * Note that the old lremove() determined equality via pointer - * comparison, whereas the new list_delete() uses equal(); in order to - * keep the same behavior, we therefore need to map lremove() calls to - * list_delete_ptr() rather than list_delete() - */ -#define lremove(elem, list) list_delete_ptr(list, elem) -#define LispRemove(elem, list) list_delete(list, elem) -#define lremovei(elem, list) list_delete_int(list, elem) -#define lremoveo(elem, list) list_delete_oid(list, elem) - -#define ltruncate(n, list) list_truncate(list, n) - -#define set_union(l1, l2) list_union(l1, l2) -#define set_uniono(l1, l2) list_union_oid(l1, l2) -#define set_ptrUnion(l1, l2) list_union_ptr(l1, l2) - -#define set_difference(l1, l2) list_difference(l1, l2) -#define set_differenceo(l1, l2) list_difference_oid(l1, l2) -#define set_ptrDifference(l1, l2) list_difference_ptr(l1, l2) - -#define equali(l1, l2) equal(l1, l2) -#define equalo(l1, l2) equal(l1, l2) - -#define freeList(list) list_free(list) - -#define listCopy(list) list_copy(list) +typedef int (*list_sort_comparator) (const ListCell *a, const ListCell *b); +extern void list_sort(List *list, list_sort_comparator cmp); -extern int length(List *list); -#endif /* ENABLE_LIST_COMPAT */ +extern int list_oid_cmp(const ListCell *p1, const ListCell *p2); #endif /* PG_LIST_H */ diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index c5c33cd3360..8e6594e3551 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -4,7 +4,7 @@ * definitions for query plan nodes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/plannodes.h @@ -15,10 +15,10 @@ #define PLANNODES_H #include "access/sdir.h" +#include "access/stratnum.h" #include "lib/stringinfo.h" #include "nodes/bitmapset.h" #include "nodes/lockoptions.h" -#include "nodes/parsenodes.h" #include "nodes/primnodes.h" @@ -43,7 +43,7 @@ typedef struct PlannedStmt { NodeTag type; - CmdType commandType; /* select|insert|update|delete|merge|utility */ + CmdType commandType; /* select|insert|update|delete|utility */ uint64 queryId; /* query identifier (copied from Query) */ @@ -69,15 +69,8 @@ typedef struct PlannedStmt List *resultRelations; /* integer list of RT indexes, or NIL */ /* - * rtable indexes of non-leaf target relations for UPDATE/DELETE on all - * the partitioned tables mentioned in the query. - */ - List *nonleafResultRelations; - - /* - * rtable indexes of root target relations for UPDATE/DELETE; this list - * maintains a subset of the RT indexes in nonleafResultRelations, - * indicating the roots of the respective partition hierarchies. + * rtable indexes of partitioned table roots that are UPDATE/DELETE + * targets; needed for trigger firing. */ List *rootResultRelations; @@ -210,6 +203,12 @@ typedef struct ProjectSet * Apply rows produced by subplan(s) to result table(s), * by inserting, updating, or deleting. * + * If the originally named target table is a partitioned table, both + * nominalRelation and rootRelation contain the RT index of the partition + * root, which is not otherwise mentioned in the plan. Otherwise rootRelation + * is zero. However, nominalRelation will always be set, as it's the rel that + * EXPLAIN should claim is the INSERT/UPDATE/DELETE target. + * * Note that rowMarks and epqParam are presumed to be valid for all the * subplan(s); they can't contain any info that varies across subplans. * ---------------- @@ -217,14 +216,12 @@ typedef struct ProjectSet typedef struct ModifyTable { Plan plan; - CmdType operation; /* INSERT, UPDATE, DELETE or MERGE */ + CmdType operation; /* INSERT, UPDATE, or DELETE */ bool canSetTag; /* do we set the command tag/es_processed? */ Index nominalRelation; /* Parent RT index for use of EXPLAIN */ - /* RT indexes of non-leaf tables in a partition tree */ - List *partitioned_rels; + Index rootRelation; /* Root RT index, if target is partitioned */ bool partColsUpdated; /* some part key in hierarchy updated */ List *resultRelations; /* integer list of RT indexes */ - Index mergeTargetRelation; /* RT index of the merge target */ int resultRelIndex; /* index of first resultRel in plan's list */ int rootResultRelIndex; /* index of the partitioned table root */ List *plans; /* plan(s) producing source data */ @@ -240,10 +237,10 @@ typedef struct ModifyTable Node *onConflictWhere; /* WHERE for ON CONFLICT UPDATE */ Index exclRelRTI; /* RTI of the EXCLUDED pseudo relation */ List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ - List *mergeSourceTargetList; - List *mergeActionList; /* actions for MERGE */ } ModifyTable; +struct PartitionPruneInfo; /* forward reference to struct below */ + /* ---------------- * Append node - * Generate the concatenation of the results of sub-plans. @@ -252,8 +249,6 @@ typedef struct ModifyTable typedef struct Append { Plan plan; - /* RT indexes of non-leaf tables in a partition tree */ - List *partitioned_rels; List *appendplans; /* @@ -262,10 +257,8 @@ typedef struct Append */ int first_partial_plan; - /* - * Mapping details for run-time subplan pruning, one per partitioned_rels - */ - List *part_prune_infos; + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; } Append; /* ---------------- @@ -276,15 +269,15 @@ typedef struct Append typedef struct MergeAppend { Plan plan; - /* RT indexes of non-leaf tables in a partition tree */ - List *partitioned_rels; List *mergeplans; - /* remaining fields are just like the sort-key info in struct Sort */ + /* these fields are just like the sort-key info in struct Sort: */ int numCols; /* number of sort-key columns */ AttrNumber *sortColIdx; /* their indexes in the target list */ Oid *sortOperators; /* OIDs of operators to sort them by */ Oid *collations; /* OIDs of collations */ bool *nullsFirst; /* NULLS FIRST/LAST directions */ + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; } MergeAppend; /* ---------------- @@ -304,6 +297,7 @@ typedef struct RecursiveUnion * duplicate-ness */ AttrNumber *dupColIdx; /* their indexes in the target list */ Oid *dupOperators; /* equality operators to compare with */ + Oid *dupCollations; long numGroups; /* estimated number of groups in input */ } RecursiveUnion; @@ -485,7 +479,8 @@ typedef struct BitmapHeapScan * tid scan node * * tidquals is an implicitly OR'ed list of qual expressions of the form - * "CTID = pseudoconstant" or "CTID = ANY(pseudoconstant_array)". + * "CTID = pseudoconstant", or "CTID = ANY(pseudoconstant_array)", + * or a CurrentOfExpr for the relation. * ---------------- */ typedef struct TidScan @@ -742,6 +737,14 @@ typedef struct HashJoin { Join join; List *hashclauses; + List *hashoperators; + List *hashcollations; + + /* + * List of expressions to be hashed for tuples from the outer plan, to + * perform lookups in the hashtable over the inner plan. + */ + List *hashkeys; } HashJoin; /* ---------------- @@ -779,6 +782,7 @@ typedef struct Group int numCols; /* number of grouping columns */ AttrNumber *grpColIdx; /* their indexes in the target list */ Oid *grpOperators; /* equality operators to compare with */ + Oid *grpCollations; } Group; /* --------------- @@ -803,6 +807,7 @@ typedef struct Agg int numCols; /* number of grouping columns */ AttrNumber *grpColIdx; /* their indexes in the target list */ Oid *grpOperators; /* equality operators to compare with */ + Oid *grpCollations; long numGroups; /* estimated number of groups in input */ Bitmapset *aggParams; /* IDs of Params used in Aggref inputs */ /* Note: planner provides numGroups & aggParams only in HASHED/MIXED case */ @@ -821,9 +826,11 @@ typedef struct WindowAgg int partNumCols; /* number of columns in partition clause */ AttrNumber *partColIdx; /* their indexes in the target list */ Oid *partOperators; /* equality operators for partition columns */ + Oid *partCollations; /* collations for partition columns */ int ordNumCols; /* number of columns in ordering clause */ AttrNumber *ordColIdx; /* their indexes in the target list */ Oid *ordOperators; /* equality operators for ordering columns */ + Oid *ordCollations; /* collations for ordering columns */ int frameOptions; /* frame_clause options, see WindowDef */ Node *startOffset; /* expression for starting bound, if any */ Node *endOffset; /* expression for ending bound, if any */ @@ -845,6 +852,7 @@ typedef struct Unique int numCols; /* number of columns to check for uniqueness */ AttrNumber *uniqColIdx; /* their indexes in the target list */ Oid *uniqOperators; /* equality operators to compare with */ + Oid *uniqCollations; /* collations for equality comparisons */ } Unique; /* ------------ @@ -899,6 +907,12 @@ typedef struct GatherMerge typedef struct Hash { Plan plan; + + /* + * List of expressions to be hashed for tuples from Hash's outer plan, + * needed to put them into the hashtable. + */ + List *hashkeys; /* hash keys for the hashjoin condition */ Oid skewTable; /* outer join key's table OID, or InvalidOid */ AttrNumber skewColumn; /* outer join key's column #, or zero */ bool skewInherit; /* is outer join rel an inheritance tree? */ @@ -919,6 +933,7 @@ typedef struct SetOp * duplicate-ness */ AttrNumber *dupColIdx; /* their indexes in the target list */ Oid *dupOperators; /* equality operators to compare with */ + Oid *dupCollations; AttrNumber flagColIdx; /* where is the flag column, if any */ int firstFlag; /* flag value for first input relation */ long numGroups; /* estimated number of groups in input */ @@ -1050,6 +1065,153 @@ typedef struct PlanRowMark } PlanRowMark; +/* + * Node types to represent partition pruning information. + */ + +/* + * PartitionPruneInfo - Details required to allow the executor to prune + * partitions. + * + * Here we store mapping details to allow translation of a partitioned table's + * index as returned by the partition pruning code into subplan indexes for + * plan types which support arbitrary numbers of subplans, such as Append. + * We also store various details to tell the executor when it should be + * performing partition pruning. + * + * Each PartitionedRelPruneInfo describes the partitioning rules for a single + * partitioned table (a/k/a level of partitioning). Since a partitioning + * hierarchy could contain multiple levels, we represent it by a List of + * PartitionedRelPruneInfos, where the first entry represents the topmost + * partitioned table and additional entries represent non-leaf child + * partitions, ordered such that parents appear before their children. + * Then, since an Append-type node could have multiple partitioning + * hierarchies among its children, we have an unordered List of those Lists. + * + * prune_infos List of Lists containing PartitionedRelPruneInfo nodes, + * one sublist per run-time-prunable partition hierarchy + * appearing in the parent plan node's subplans. + * other_subplans Indexes of any subplans that are not accounted for + * by any of the PartitionedRelPruneInfo nodes in + * "prune_infos". These subplans must not be pruned. + */ +typedef struct PartitionPruneInfo +{ + NodeTag type; + List *prune_infos; + Bitmapset *other_subplans; +} PartitionPruneInfo; + +/* + * PartitionedRelPruneInfo - Details required to allow the executor to prune + * partitions for a single partitioned table. + * + * subplan_map[] and subpart_map[] are indexed by partition index of the + * partitioned table referenced by 'rtindex', the partition index being the + * order that the partitions are defined in the table's PartitionDesc. For a + * leaf partition p, subplan_map[p] contains the zero-based index of the + * partition's subplan in the parent plan's subplan list; it is -1 if the + * partition is non-leaf or has been pruned. For a non-leaf partition p, + * subpart_map[p] contains the zero-based index of that sub-partition's + * PartitionedRelPruneInfo in the hierarchy's PartitionedRelPruneInfo list; + * it is -1 if the partition is a leaf or has been pruned. Note that subplan + * indexes, as stored in 'subplan_map', are global across the parent plan + * node, but partition indexes are valid only within a particular hierarchy. + * relid_map[p] contains the partition's OID, or 0 if the partition was pruned. + */ +typedef struct PartitionedRelPruneInfo +{ + NodeTag type; + Index rtindex; /* RT index of partition rel for this level */ + Bitmapset *present_parts; /* Indexes of all partitions which subplans or + * subparts are present for */ + int nparts; /* Length of the following arrays: */ + int *subplan_map; /* subplan index by partition index, or -1 */ + int *subpart_map; /* subpart index by partition index, or -1 */ + Oid *relid_map; /* relation OID by partition index, or 0 */ + + /* + * initial_pruning_steps shows how to prune during executor startup (i.e., + * without use of any PARAM_EXEC Params); it is NIL if no startup pruning + * is required. exec_pruning_steps shows how to prune with PARAM_EXEC + * Params; it is NIL if no per-scan pruning is required. + */ + List *initial_pruning_steps; /* List of PartitionPruneStep */ + List *exec_pruning_steps; /* List of PartitionPruneStep */ + Bitmapset *execparamids; /* All PARAM_EXEC Param IDs in + * exec_pruning_steps */ +} PartitionedRelPruneInfo; + +/* + * Abstract Node type for partition pruning steps (there are no concrete + * Nodes of this type). + * + * step_id is the global identifier of the step within its pruning context. + */ +typedef struct PartitionPruneStep +{ + NodeTag type; + int step_id; +} PartitionPruneStep; + +/* + * PartitionPruneStepOp - Information to prune using a set of mutually AND'd + * OpExpr clauses + * + * This contains information extracted from up to partnatts OpExpr clauses, + * where partnatts is the number of partition key columns. 'opstrategy' is the + * strategy of the operator in the clause matched to the last partition key. + * 'exprs' contains expressions which comprise the lookup key to be passed to + * the partition bound search function. 'cmpfns' contains the OIDs of + * comparison functions used to compare aforementioned expressions with + * partition bounds. Both 'exprs' and 'cmpfns' contain the same number of + * items, up to partnatts items. + * + * Once we find the offset of a partition bound using the lookup key, we + * determine which partitions to include in the result based on the value of + * 'opstrategy'. For example, if it were equality, we'd return just the + * partition that would contain that key or a set of partitions if the key + * didn't consist of all partitioning columns. For non-equality strategies, + * we'd need to include other partitions as appropriate. + * + * 'nullkeys' is the set containing the offset of the partition keys (0 to + * partnatts - 1) that were matched to an IS NULL clause. This is only + * considered for hash partitioning as we need to pass which keys are null + * to the hash partition bound search function. It is never possible to + * have an expression be present in 'exprs' for a given partition key and + * the corresponding bit set in 'nullkeys'. + */ +typedef struct PartitionPruneStepOp +{ + PartitionPruneStep step; + + StrategyNumber opstrategy; + List *exprs; + List *cmpfns; + Bitmapset *nullkeys; +} PartitionPruneStepOp; + +/* + * PartitionPruneStepCombine - Information to prune using a BoolExpr clause + * + * For BoolExpr clauses, we combine the set of partitions determined for each + * of the argument clauses. + */ +typedef enum PartitionPruneCombineOp +{ + PARTPRUNE_COMBINE_UNION, + PARTPRUNE_COMBINE_INTERSECT +} PartitionPruneCombineOp; + +typedef struct PartitionPruneStepCombine +{ + PartitionPruneStep step; + + PartitionPruneCombineOp combineOp; + List *source_stepids; +} PartitionPruneStepCombine; + + /* * Plan invalidation info * diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index f90aa7b2a19..860a84de7c0 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -7,7 +7,7 @@ * and join trees. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/primnodes.h @@ -18,7 +18,6 @@ #define PRIMNODES_H #include "access/attnum.h" -#include "access/stratnum.h" #include "nodes/bitmapset.h" #include "nodes/pg_list.h" @@ -76,12 +75,15 @@ typedef struct RangeVar /* * TableFunc - node for a table function, such as XMLTABLE. + * + * Entries in the ns_names list are either string Value nodes containing + * literal namespace names, or NULL pointers to represent DEFAULT. */ typedef struct TableFunc { NodeTag type; - List *ns_uris; /* list of namespace uri */ - List *ns_names; /* list of namespace names */ + List *ns_uris; /* list of namespace URI expressions */ + List *ns_names; /* list of namespace names or NULL */ Node *docexpr; /* input document expression */ Node *rowexpr; /* row filter expression */ List *colnames; /* column names (list of String) */ @@ -109,6 +111,7 @@ typedef struct IntoClause RangeVar *rel; /* target relation name */ List *colNames; /* column names to assign, or NIL */ + char *accessMethod; /* table access method */ List *options; /* options from WITH clause */ OnCommitAction onCommit; /* what do we do at COMMIT? */ char *tableSpaceName; /* table space to use, or NULL */ @@ -366,18 +369,19 @@ typedef struct WindowFunc } WindowFunc; /* ---------------- - * ArrayRef: describes an array subscripting operation - * - * An ArrayRef can describe fetching a single element from an array, - * fetching a subarray (array slice), storing a single element into - * an array, or storing a slice. The "store" cases work with an - * initial array value and a source value that is inserted into the - * appropriate part of the array; the result of the operation is an - * entire new modified array value. - * - * If reflowerindexpr = NIL, then we are fetching or storing a single array - * element at the subscripts given by refupperindexpr. Otherwise we are - * fetching or storing an array slice, that is a rectangular subarray + * SubscriptingRef: describes a subscripting operation over a container + * (array, etc). + * + * A SubscriptingRef can describe fetching a single element from a container, + * fetching a part of container (e.g. array slice), storing a single element into + * a container, or storing a slice. The "store" cases work with an + * initial container value and a source value that is inserted into the + * appropriate part of the container; the result of the operation is an + * entire new modified container value. + * + * If reflowerindexpr = NIL, then we are fetching or storing a single container + * element at the subscripts given by refupperindexpr. Otherwise we are + * fetching or storing a container slice, that is a rectangular subcontainer * with lower and upper bounds given by the index expressions. * reflowerindexpr must be the same length as refupperindexpr when it * is not NIL. @@ -389,28 +393,29 @@ typedef struct WindowFunc * element; but it is the array type when doing subarray fetch or either * type of store. * - * Note: for the cases where an array is returned, if refexpr yields a R/W - * expanded array, then the implementation is allowed to modify that object + * Note: for the cases where a container is returned, if refexpr yields a R/W + * expanded container, then the implementation is allowed to modify that object * in-place and return the same object.) * ---------------- */ -typedef struct ArrayRef +typedef struct SubscriptingRef { Expr xpr; - Oid refarraytype; /* type of the array proper */ - Oid refelemtype; /* type of the array elements */ - int32 reftypmod; /* typmod of the array (and elements too) */ + Oid refcontainertype; /* type of the container proper */ + Oid refelemtype; /* type of the container elements */ + int32 reftypmod; /* typmod of the container (and elements too) */ Oid refcollid; /* OID of collation, or InvalidOid if none */ List *refupperindexpr; /* expressions that evaluate to upper - * array indexes */ + * container indexes */ List *reflowerindexpr; /* expressions that evaluate to lower - * array indexes, or NIL for single array - * element */ - Expr *refexpr; /* the expression that evaluates to an array - * value */ + * container indexes, or NIL for single + * container element */ + Expr *refexpr; /* the expression that evaluates to a + * container value */ + Expr *refassgnexpr; /* expression for the source value, or NULL if * fetch */ -} ArrayRef; +} SubscriptingRef; /* * CoercionContext - distinguishes the allowed set of type casts @@ -753,7 +758,7 @@ typedef struct FieldSelect * * FieldStore represents the operation of modifying one field in a tuple * value, yielding a new tuple value (the input is not touched!). Like - * the assign case of ArrayRef, this is used to implement UPDATE of a + * the assign case of SubscriptingRef, this is used to implement UPDATE of a * portion of a column. * * resulttype is always a named composite type (not a domain). To update @@ -932,8 +937,20 @@ typedef struct CaseWhen * This is effectively like a Param, but can be implemented more simply * since we need only one replacement value at a time. * - * We also use this in nested UPDATE expressions. - * See transformAssignmentIndirection(). + * We also abuse this node type for some other purposes, including: + * * Placeholder for the current array element value in ArrayCoerceExpr; + * see build_coercion_expression(). + * * Nested FieldStore/SubscriptingRef assignment expressions in INSERT/UPDATE; + * see transformAssignmentIndirection(). + * + * The uses in CaseExpr and ArrayCoerceExpr are safe only to the extent that + * there is not any other CaseExpr or ArrayCoerceExpr between the value source + * node and its child CaseTestExpr(s). This is true in the parse analysis + * output, but the planner's function-inlining logic has to be careful not to + * break it. + * + * The nested-assignment-expression case is safe because the only node types + * that can be above such CaseTestExprs are FieldStore and SubscriptingRef. */ typedef struct CaseTestExpr { @@ -1507,101 +1524,4 @@ typedef struct OnConflictExpr List *exclRelTlist; /* tlist of the EXCLUDED pseudo relation */ } OnConflictExpr; - -/* - * Node types to represent a partition pruning step. - */ - -/* - * The base Node type. step_id is the global identifier of a given step - * within a given pruning context. - */ -typedef struct PartitionPruneStep -{ - NodeTag type; - int step_id; -} PartitionPruneStep; - -/*---------- - * PartitionPruneStepOp - Information to prune using a set of mutually AND'd - * OpExpr clauses - * - * This contains information extracted from up to partnatts OpExpr clauses, - * where partnatts is the number of partition key columns. 'opstrategy' is the - * strategy of the operator in the clause matched to the last partition key. - * 'exprs' contains expressions which comprise the lookup key to be passed to - * the partition bound search function. 'cmpfns' contains the OIDs of - * comparison function used to compare aforementioned expressions with - * partition bounds. Both 'exprs' and 'cmpfns' contain the same number of - * items up to partnatts items. - * - * Once we find the offset of a partition bound using the lookup key, we - * determine which partitions to include in the result based on the value of - * 'opstrategy'. For example, if it were equality, we'd return just the - * partition that would contain that key or a set of partitions if the key - * didn't consist of all partitioning columns. For non-equality strategies, - * we'd need to include other partitions as appropriate. - * - * 'nullkeys' is the set containing the offset of the partition keys (0 to - * partnatts - 1) that were matched to an IS NULL clause. This is only - * considered for hash partitioning as we need to pass which keys are null - * to the hash partition bound search function. It is never possible to - * have an expression be present in 'exprs' for a given partition key and - * the corresponding bit set in 'nullkeys'. - *---------- - */ -typedef struct PartitionPruneStepOp -{ - PartitionPruneStep step; - - StrategyNumber opstrategy; - List *exprs; - List *cmpfns; - Bitmapset *nullkeys; -} PartitionPruneStepOp; - -/*---------- - * PartitionPruneStepCombine - Information to prune using a BoolExpr clause - * - * For BoolExpr clauses, we combine the set of partitions determined for each - * of its argument clauses. - *---------- - */ -typedef enum PartitionPruneCombineOp -{ - PARTPRUNE_COMBINE_UNION, - PARTPRUNE_COMBINE_INTERSECT -} PartitionPruneCombineOp; - -typedef struct PartitionPruneStepCombine -{ - PartitionPruneStep step; - - PartitionPruneCombineOp combineOp; - List *source_stepids; -} PartitionPruneStepCombine; - -/*---------- - * PartitionPruneInfo - Details required to allow the executor to prune - * partitions. - * - * Here we store mapping details to allow translation of a partitioned table's - * index into subnode indexes for node types which support arbitrary numbers - * of sub nodes, such as Append. - *---------- - */ -typedef struct PartitionPruneInfo -{ - NodeTag type; - Oid reloid; /* Oid of partition rel */ - List *pruning_steps; /* List of PartitionPruneStep */ - Bitmapset *present_parts; /* Indexes of all partitions which subnodes - * are present for. */ - int nparts; /* The length of the following two arrays */ - int *subnode_map; /* subnode index by partition id, or -1 */ - int *subpart_map; /* subpart index by partition id, or -1 */ - Bitmapset *extparams; /* All external paramids seen in prunesteps */ - Bitmapset *execparams; /* All exec paramids seen in prunesteps */ -} PartitionPruneInfo; - #endif /* PRIMNODES_H */ diff --git a/src/include/nodes/print.h b/src/include/nodes/print.h index fba87c6c13f..cbff56a7242 100644 --- a/src/include/nodes/print.h +++ b/src/include/nodes/print.h @@ -4,7 +4,7 @@ * definitions for nodes/print.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/print.h @@ -22,7 +22,7 @@ extern void print(const void *obj); extern void pprint(const void *obj); extern void elog_node_display(int lev, const char *title, - const void *obj, bool pretty); + const void *obj, bool pretty); extern char *format_node_dump(const char *dump); extern char *pretty_format_node_dump(const char *dump); extern void print_rt(const List *rtable); diff --git a/src/include/nodes/readfuncs.h b/src/include/nodes/readfuncs.h index 491e61c459f..aa967ea2dea 100644 --- a/src/include/nodes/readfuncs.h +++ b/src/include/nodes/readfuncs.h @@ -4,7 +4,7 @@ * header file for read.c and readfuncs.c. These functions are internal * to the stringToNode interface and should not be used by anyone else. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/readfuncs.h @@ -16,12 +16,19 @@ #include "nodes/nodes.h" +/* + * variable in read.c that needs to be accessible to readfuncs.c + */ +#ifdef WRITE_READ_PARSE_PLAN_TREES +extern bool restore_location_fields; +#endif + /* * prototypes for functions in read.c (the lisp token parser) */ -extern char *pg_strtok(int *length); -extern char *debackslash(char *token, int length); -extern void *nodeRead(char *token, int tok_len); +extern const char *pg_strtok(int *length); +extern char *debackslash(const char *token, int length); +extern void *nodeRead(const char *token, int tok_len); /* * prototypes for functions in readfuncs.c diff --git a/src/include/nodes/replnodes.h b/src/include/nodes/replnodes.h index 66c948d85ec..1e3ed4e19fb 100644 --- a/src/include/nodes/replnodes.h +++ b/src/include/nodes/replnodes.h @@ -4,7 +4,7 @@ * definitions for replication grammar parse nodes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/nodes/replnodes.h diff --git a/src/include/nodes/supportnodes.h b/src/include/nodes/supportnodes.h new file mode 100644 index 00000000000..460d75bd2dd --- /dev/null +++ b/src/include/nodes/supportnodes.h @@ -0,0 +1,242 @@ +/*------------------------------------------------------------------------- + * + * supportnodes.h + * Definitions for planner support functions. + * + * This file defines the API for "planner support functions", which + * are SQL functions (normally written in C) that can be attached to + * another "target" function to give the system additional knowledge + * about the target function. All the current capabilities have to do + * with planning queries that use the target function, though it is + * possible that future extensions will add functionality to be invoked + * by the parser or executor. + * + * A support function must have the SQL signature + * supportfn(internal) returns internal + * The argument is a pointer to one of the Node types defined in this file. + * The result is usually also a Node pointer, though its type depends on + * which capability is being invoked. In all cases, a NULL pointer result + * (that's PG_RETURN_POINTER(NULL), not PG_RETURN_NULL()) indicates that + * the support function cannot do anything useful for the given request. + * Support functions must return a NULL pointer, not fail, if they do not + * recognize the request node type or cannot handle the given case; this + * allows for future extensions of the set of request cases. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/nodes/supportnodes.h + * + *------------------------------------------------------------------------- + */ +#ifndef SUPPORTNODES_H +#define SUPPORTNODES_H + +#include "nodes/primnodes.h" + +struct PlannerInfo; /* avoid including pathnodes.h here */ +struct IndexOptInfo; +struct SpecialJoinInfo; + + +/* + * The Simplify request allows the support function to perform plan-time + * simplification of a call to its target function. For example, a varchar + * length coercion that does not decrease the allowed length of its argument + * could be replaced by a RelabelType node, or "x + 0" could be replaced by + * "x". This is invoked during the planner's constant-folding pass, so the + * function's arguments can be presumed already simplified. + * + * The planner's PlannerInfo "root" is typically not needed, but can be + * consulted if it's necessary to obtain info about Vars present in + * the given node tree. Beware that root could be NULL in some usages. + * + * "fcall" will be a FuncExpr invoking the support function's target + * function. (This is true even if the original parsetree node was an + * operator call; a FuncExpr is synthesized for this purpose.) + * + * The result should be a semantically-equivalent transformed node tree, + * or NULL if no simplification could be performed. Do *not* return or + * modify *fcall, as it isn't really a separately allocated Node. But + * it's okay to use fcall->args, or parts of it, in the result tree. + */ +typedef struct SupportRequestSimplify +{ + NodeTag type; + + struct PlannerInfo *root; /* Planner's infrastructure */ + FuncExpr *fcall; /* Function call to be simplified */ +} SupportRequestSimplify; + +/* + * The Selectivity request allows the support function to provide a + * selectivity estimate for a function appearing at top level of a WHERE + * clause (so it applies only to functions returning boolean). + * + * The input arguments are the same as are supplied to operator restriction + * and join estimators, except that we unify those two APIs into just one + * request type. See clause_selectivity() for the details. + * + * If an estimate can be made, store it into the "selectivity" field and + * return the address of the SupportRequestSelectivity node; the estimate + * must be between 0 and 1 inclusive. Return NULL if no estimate can be + * made (in which case the planner will fall back to a default estimate, + * traditionally 1/3). + * + * If the target function is being used as the implementation of an operator, + * the support function will not be used for this purpose; the operator's + * restriction or join estimator is consulted instead. + */ +typedef struct SupportRequestSelectivity +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure */ + Oid funcid; /* function we are inquiring about */ + List *args; /* pre-simplified arguments to function */ + Oid inputcollid; /* function's input collation */ + bool is_join; /* is this a join or restriction case? */ + int varRelid; /* if restriction, RTI of target relation */ + JoinType jointype; /* if join, outer join type */ + struct SpecialJoinInfo *sjinfo; /* if outer join, info about join */ + + /* Output fields: */ + Selectivity selectivity; /* returned selectivity estimate */ +} SupportRequestSelectivity; + +/* + * The Cost request allows the support function to provide an execution + * cost estimate for its target function. The cost estimate can include + * both a one-time (query startup) component and a per-execution component. + * The estimate should *not* include the costs of evaluating the target + * function's arguments, only the target function itself. + * + * The "node" argument is normally the parse node that is invoking the + * target function. This is a FuncExpr in the simplest case, but it could + * also be an OpExpr, DistinctExpr, NullIfExpr, or WindowFunc, or possibly + * other cases in future. NULL is passed if the function cannot presume + * its arguments to be equivalent to what the calling node presents as + * arguments; that happens for, e.g., aggregate support functions and + * per-column comparison operators used by RowExprs. + * + * If an estimate can be made, store it into the cost fields and return the + * address of the SupportRequestCost node. Return NULL if no estimate can be + * made, in which case the planner will rely on the target function's procost + * field. (Note: while procost is automatically scaled by cpu_operator_cost, + * this is not the case for the outputs of the Cost request; the support + * function must scale its results appropriately on its own.) + */ +typedef struct SupportRequestCost +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure (could be NULL) */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function, or NULL */ + + /* Output fields: */ + Cost startup; /* one-time cost */ + Cost per_tuple; /* per-evaluation cost */ +} SupportRequestCost; + +/* + * The Rows request allows the support function to provide an output rowcount + * estimate for its target function (so it applies only to set-returning + * functions). + * + * The "node" argument is the parse node that is invoking the target function; + * currently this will always be a FuncExpr or OpExpr. + * + * If an estimate can be made, store it into the rows field and return the + * address of the SupportRequestRows node. Return NULL if no estimate can be + * made, in which case the planner will rely on the target function's prorows + * field. + */ +typedef struct SupportRequestRows +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure (could be NULL) */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function */ + + /* Output fields: */ + double rows; /* number of rows expected to be returned */ +} SupportRequestRows; + +/* + * The IndexCondition request allows the support function to generate + * a directly-indexable condition based on a target function call that is + * not itself indexable. The target function call must appear at the top + * level of WHERE or JOIN/ON, so this applies only to functions returning + * boolean. + * + * The "node" argument is the parse node that is invoking the target function; + * currently this will always be a FuncExpr or OpExpr. The call is made + * only if at least one function argument matches an index column's variable + * or expression. "indexarg" identifies the matching argument (it's the + * argument's zero-based index in the node's args list). + * + * If the transformation is possible, return a List of directly-indexable + * condition expressions, else return NULL. (A List is used because it's + * sometimes useful to generate more than one indexable condition, such as + * when a LIKE with constant prefix gives rise to both >= and < conditions.) + * + * "Directly indexable" means that the condition must be directly executable + * by the index machinery. Typically this means that it is a binary OpExpr + * with the index column value on the left, a pseudo-constant on the right, + * and an operator that is in the index column's operator family. Other + * possibilities include RowCompareExpr, ScalarArrayOpExpr, and NullTest, + * depending on the index type; but those seem less likely to be useful for + * derived index conditions. "Pseudo-constant" means that the right-hand + * expression must not contain any volatile functions, nor any Vars of the + * table the index is for; use is_pseudo_constant_for_index() to check this. + * (Note: if the passed "node" is an OpExpr, the core planner already verified + * that the non-indexkey operand is pseudo-constant; but when the "node" + * is a FuncExpr, it does not check, since it doesn't know which of the + * function's arguments you might need to use in an index comparison value.) + * + * In many cases, an index condition can be generated but it is weaker than + * the function condition itself; for example, a LIKE with a constant prefix + * can produce an index range check based on the prefix, but we still need + * to execute the LIKE operator to verify the rest of the pattern. We say + * that such an index condition is "lossy". When returning an index condition, + * you should set the "lossy" request field to true if the condition is lossy, + * or false if it is an exact equivalent of the function's result. The core + * code will initialize that field to true, which is the common case. + * + * It is important to verify that the index operator family is the correct + * one for the condition you want to generate. Core support functions tend + * to use the known OID of a built-in opfamily for this, but extensions need + * to work harder, since their OIDs aren't fixed. A possibly workable + * answer for an index on an extension datatype is to verify the index AM's + * OID instead, and then assume that there's only one relevant opclass for + * your datatype so the opfamily must be the right one. Generating OpExpr + * nodes may also require knowing extension datatype OIDs (often you can + * find these out by applying exprType() to a function argument) and + * operator OIDs (which you can look up using get_opfamily_member). + */ +typedef struct SupportRequestIndexCondition +{ + NodeTag type; + + /* Input fields: */ + struct PlannerInfo *root; /* Planner's infrastructure */ + Oid funcid; /* function we are inquiring about */ + Node *node; /* parse node invoking function */ + int indexarg; /* index of function arg matching indexcol */ + struct IndexOptInfo *index; /* planner's info about target index */ + int indexcol; /* index of target index column (0-based) */ + Oid opfamily; /* index column's operator family */ + Oid indexcollation; /* index column's collation */ + + /* Output fields: */ + bool lossy; /* set to false if index condition is an exact + * equivalent of the function call */ +} SupportRequestIndexCondition; + +#endif /* SUPPORTNODES_H */ diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h index 31532e97690..26973ac7a58 100644 --- a/src/include/nodes/tidbitmap.h +++ b/src/include/nodes/tidbitmap.h @@ -13,7 +13,7 @@ * fact that a particular page needs to be visited. * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/nodes/tidbitmap.h * @@ -37,7 +37,7 @@ typedef struct TBMIterator TBMIterator; typedef struct TBMSharedIterator TBMSharedIterator; /* Result structure for tbm_iterate */ -typedef struct +typedef struct TBMIterateResult { BlockNumber blockno; /* page number containing tuples */ int ntuples; /* -1 indicates lossy result */ @@ -53,8 +53,8 @@ extern void tbm_free(TIDBitmap *tbm); extern void tbm_free_shared_area(dsa_area *dsa, dsa_pointer dp); extern void tbm_add_tuples(TIDBitmap *tbm, - const ItemPointer tids, int ntids, - bool recheck); + const ItemPointer tids, int ntids, + bool recheck); extern void tbm_add_page(TIDBitmap *tbm, BlockNumber pageno); extern void tbm_union(TIDBitmap *a, const TIDBitmap *b); @@ -69,7 +69,7 @@ extern TBMIterateResult *tbm_shared_iterate(TBMSharedIterator *iterator); extern void tbm_end_iterate(TBMIterator *iterator); extern void tbm_end_shared_iterate(TBMSharedIterator *iterator); extern TBMSharedIterator *tbm_attach_shared_iterate(dsa_area *dsa, - dsa_pointer dp); + dsa_pointer dp); extern long tbm_calculate_entries(double maxbytes); #endif /* TIDBITMAP_H */ diff --git a/src/include/nodes/value.h b/src/include/nodes/value.h index 16657145153..871ffa8fa9f 100644 --- a/src/include/nodes/value.h +++ b/src/include/nodes/value.h @@ -4,7 +4,7 @@ * interface for Value nodes * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/nodes/value.h * diff --git a/src/include/optimizer/appendinfo.h b/src/include/optimizer/appendinfo.h new file mode 100644 index 00000000000..9fdb6a6036c --- /dev/null +++ b/src/include/optimizer/appendinfo.h @@ -0,0 +1,35 @@ +/*------------------------------------------------------------------------- + * + * appendinfo.h + * Routines for mapping expressions between append rel parent(s) and + * children + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/appendinfo.h + * + *------------------------------------------------------------------------- + */ +#ifndef APPENDINFO_H +#define APPENDINFO_H + +#include "nodes/pathnodes.h" +#include "utils/relcache.h" + +extern AppendRelInfo *make_append_rel_info(Relation parentrel, + Relation childrel, + Index parentRTindex, Index childRTindex); +extern Node *adjust_appendrel_attrs(PlannerInfo *root, Node *node, + int nappinfos, AppendRelInfo **appinfos); +extern Node *adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, + Relids child_relids, + Relids top_parent_relids); +extern Relids adjust_child_relids(Relids relids, int nappinfos, + AppendRelInfo **appinfos); +extern Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, + Relids child_relids, Relids top_parent_relids); +extern AppendRelInfo **find_appinfos_by_relids(PlannerInfo *root, + Relids relids, int *nappinfos); + +#endif /* APPENDINFO_H */ diff --git a/src/include/optimizer/clauses.h b/src/include/optimizer/clauses.h index ba4fa4b68b3..2f9aeec4a77 100644 --- a/src/include/optimizer/clauses.h +++ b/src/include/optimizer/clauses.h @@ -4,7 +4,7 @@ * prototypes for clauses.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/clauses.h @@ -14,11 +14,8 @@ #ifndef CLAUSES_H #define CLAUSES_H -#include "nodes/relation.h" - - -#define is_opclause(clause) ((clause) != NULL && IsA(clause, OpExpr)) -#define is_funcclause(clause) ((clause) != NULL && IsA(clause, FuncExpr)) +#include "access/htup.h" +#include "nodes/pathnodes.h" typedef struct { @@ -27,39 +24,17 @@ typedef struct List **windowFuncs; /* lists of WindowFuncs for each winref */ } WindowFuncLists; -extern Expr *make_opclause(Oid opno, Oid opresulttype, bool opretset, - Expr *leftop, Expr *rightop, - Oid opcollid, Oid inputcollid); -extern Node *get_leftop(const Expr *clause); -extern Node *get_rightop(const Expr *clause); - -extern bool not_clause(Node *clause); -extern Expr *make_notclause(Expr *notclause); -extern Expr *get_notclausearg(Expr *notclause); - -extern bool or_clause(Node *clause); -extern Expr *make_orclause(List *orclauses); - -extern bool and_clause(Node *clause); -extern Expr *make_andclause(List *andclauses); -extern Node *make_and_qual(Node *qual1, Node *qual2); -extern Expr *make_ands_explicit(List *andclauses); -extern List *make_ands_implicit(Expr *clause); - extern bool contain_agg_clause(Node *clause); extern void get_agg_clause_costs(PlannerInfo *root, Node *clause, - AggSplit aggsplit, AggClauseCosts *costs); + AggSplit aggsplit, AggClauseCosts *costs); extern bool contain_window_function(Node *clause); extern WindowFuncLists *find_window_functions(Node *clause, Index maxWinRef); -extern double expression_returns_set_rows(Node *clause); +extern double expression_returns_set_rows(PlannerInfo *root, Node *clause); extern bool contain_subplans(Node *clause); -extern bool contain_mutable_functions(Node *clause); -extern bool contain_volatile_functions(Node *clause); -extern bool contain_volatile_functions_not_nextval(Node *clause); extern char max_parallel_hazard(Query *parse); extern bool is_parallel_safe(PlannerInfo *root, Node *node); extern bool contain_nonstrict_functions(Node *clause); @@ -76,13 +51,8 @@ extern bool is_pseudo_constant_clause_relids(Node *clause, Relids relids); extern int NumRelids(Node *clause); extern void CommuteOpExpr(OpExpr *clause); -extern void CommuteRowCompareExpr(RowCompareExpr *clause); - -extern Node *eval_const_expressions(PlannerInfo *root, Node *node); - -extern Node *estimate_expression_value(PlannerInfo *root, Node *node); extern Query *inline_set_returning_function(PlannerInfo *root, - RangeTblEntry *rte); + RangeTblEntry *rte); #endif /* CLAUSES_H */ diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h index d3269eae71c..b3d0b4f6fbc 100644 --- a/src/include/optimizer/cost.h +++ b/src/include/optimizer/cost.h @@ -4,7 +4,7 @@ * prototypes for costsize.c and clausesel.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/cost.h @@ -14,8 +14,8 @@ #ifndef COST_H #define COST_H +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" /* defaults for costsize.c's Cost parameters */ @@ -44,17 +44,9 @@ typedef enum * routines to compute costs and sizes */ -/* parameter variables and flags */ -extern PGDLLIMPORT double seq_page_cost; -extern PGDLLIMPORT double random_page_cost; -extern PGDLLIMPORT double cpu_tuple_cost; -extern PGDLLIMPORT double cpu_index_tuple_cost; -extern PGDLLIMPORT double cpu_operator_cost; -extern PGDLLIMPORT double parallel_tuple_cost; -extern PGDLLIMPORT double parallel_setup_cost; -extern PGDLLIMPORT int effective_cache_size; +/* parameter variables and flags (see also optimizer.h) */ extern PGDLLIMPORT Cost disable_cost; -extern PGDLLIMPORT int max_parallel_workers_per_gather; +extern PGDLLIMPORT int max_parallel_workers_per_gather; extern PGDLLIMPORT bool enable_seqscan; extern PGDLLIMPORT bool enable_indexscan; extern PGDLLIMPORT bool enable_indexonlyscan; @@ -71,151 +63,138 @@ extern PGDLLIMPORT bool enable_partitionwise_join; extern PGDLLIMPORT bool enable_partitionwise_aggregate; extern PGDLLIMPORT bool enable_parallel_append; extern PGDLLIMPORT bool enable_parallel_hash; -extern PGDLLIMPORT int constraint_exclusion; +extern PGDLLIMPORT bool enable_partition_pruning; +extern PGDLLIMPORT int constraint_exclusion; -extern double clamp_row_est(double nrows); extern double index_pages_fetched(double tuples_fetched, BlockNumber pages, - double index_pages, PlannerInfo *root); + double index_pages, PlannerInfo *root); extern void cost_seqscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, - ParamPathInfo *param_info); + ParamPathInfo *param_info); extern void cost_samplescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, - ParamPathInfo *param_info); + ParamPathInfo *param_info); extern void cost_index(IndexPath *path, PlannerInfo *root, - double loop_count, bool partial_path); + double loop_count, bool partial_path); extern void cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, - ParamPathInfo *param_info, - Path *bitmapqual, double loop_count); + ParamPathInfo *param_info, + Path *bitmapqual, double loop_count); extern void cost_bitmap_and_node(BitmapAndPath *path, PlannerInfo *root); extern void cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root); extern void cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec); extern void cost_tidscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info); + RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info); extern void cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_functionscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); -extern void cost_tableexprscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_valuesscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_tablefuncscan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_ctescan(Path *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info); -extern void cost_namedtuplestorescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_namedtuplestorescan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); +extern void cost_resultscan(Path *path, PlannerInfo *root, + RelOptInfo *baserel, ParamPathInfo *param_info); extern void cost_recursive_union(Path *runion, Path *nrterm, Path *rterm); extern void cost_sort(Path *path, PlannerInfo *root, - List *pathkeys, Cost input_cost, double tuples, int width, - Cost comparison_cost, int sort_mem, - double limit_tuples); + List *pathkeys, Cost input_cost, double tuples, int width, + Cost comparison_cost, int sort_mem, + double limit_tuples); extern void cost_append(AppendPath *path); extern void cost_merge_append(Path *path, PlannerInfo *root, - List *pathkeys, int n_streams, - Cost input_startup_cost, Cost input_total_cost, - double tuples); + List *pathkeys, int n_streams, + Cost input_startup_cost, Cost input_total_cost, + double tuples); extern void cost_material(Path *path, - Cost input_startup_cost, Cost input_total_cost, - double tuples, int width); + Cost input_startup_cost, Cost input_total_cost, + double tuples, int width); extern void cost_agg(Path *path, PlannerInfo *root, - AggStrategy aggstrategy, const AggClauseCosts *aggcosts, - int numGroupCols, double numGroups, - List *quals, - Cost input_startup_cost, Cost input_total_cost, - double input_tuples); + AggStrategy aggstrategy, const AggClauseCosts *aggcosts, + int numGroupCols, double numGroups, + List *quals, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples); extern void cost_windowagg(Path *path, PlannerInfo *root, - List *windowFuncs, int numPartCols, int numOrderCols, - Cost input_startup_cost, Cost input_total_cost, - double input_tuples); + List *windowFuncs, int numPartCols, int numOrderCols, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples); extern void cost_group(Path *path, PlannerInfo *root, - int numGroupCols, double numGroups, - List *quals, - Cost input_startup_cost, Cost input_total_cost, - double input_tuples); + int numGroupCols, double numGroups, + List *quals, + Cost input_startup_cost, Cost input_total_cost, + double input_tuples); extern void initial_cost_nestloop(PlannerInfo *root, - JoinCostWorkspace *workspace, - JoinType jointype, - Path *outer_path, Path *inner_path, - JoinPathExtraData *extra); + JoinCostWorkspace *workspace, + JoinType jointype, + Path *outer_path, Path *inner_path, + JoinPathExtraData *extra); extern void final_cost_nestloop(PlannerInfo *root, NestPath *path, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra); + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); extern void initial_cost_mergejoin(PlannerInfo *root, - JoinCostWorkspace *workspace, - JoinType jointype, - List *mergeclauses, - Path *outer_path, Path *inner_path, - List *outersortkeys, List *innersortkeys, - JoinPathExtraData *extra); + JoinCostWorkspace *workspace, + JoinType jointype, + List *mergeclauses, + Path *outer_path, Path *inner_path, + List *outersortkeys, List *innersortkeys, + JoinPathExtraData *extra); extern void final_cost_mergejoin(PlannerInfo *root, MergePath *path, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra); + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); extern void initial_cost_hashjoin(PlannerInfo *root, - JoinCostWorkspace *workspace, - JoinType jointype, - List *hashclauses, - Path *outer_path, Path *inner_path, - JoinPathExtraData *extra, - bool parallel_hash); + JoinCostWorkspace *workspace, + JoinType jointype, + List *hashclauses, + Path *outer_path, Path *inner_path, + JoinPathExtraData *extra, + bool parallel_hash); extern void final_cost_hashjoin(PlannerInfo *root, HashPath *path, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra); + JoinCostWorkspace *workspace, + JoinPathExtraData *extra); extern void cost_gather(GatherPath *path, PlannerInfo *root, - RelOptInfo *baserel, ParamPathInfo *param_info, double *rows); + RelOptInfo *baserel, ParamPathInfo *param_info, double *rows); +extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root, + RelOptInfo *rel, ParamPathInfo *param_info, + Cost input_startup_cost, Cost input_total_cost, + double *rows); extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan); extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root); extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root); extern void compute_semi_anti_join_factors(PlannerInfo *root, - RelOptInfo *outerrel, - RelOptInfo *innerrel, - JoinType jointype, - SpecialJoinInfo *sjinfo, - List *restrictlist, - SemiAntiJoinFactors *semifactors); + RelOptInfo *joinrel, + RelOptInfo *outerrel, + RelOptInfo *innerrel, + JoinType jointype, + SpecialJoinInfo *sjinfo, + List *restrictlist, + SemiAntiJoinFactors *semifactors); extern void set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern double get_parameterized_baserel_size(PlannerInfo *root, - RelOptInfo *rel, - List *param_clauses); + RelOptInfo *rel, + List *param_clauses); extern double get_parameterized_joinrel_size(PlannerInfo *root, - RelOptInfo *rel, - Path *outer_path, - Path *inner_path, - SpecialJoinInfo *sjinfo, - List *restrict_clauses); + RelOptInfo *rel, + Path *outer_path, + Path *inner_path, + SpecialJoinInfo *sjinfo, + List *restrict_clauses); extern void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel, - SpecialJoinInfo *sjinfo, - List *restrictlist); + RelOptInfo *outer_rel, + RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo, + List *restrictlist); extern void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern void set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel, - double cte_rows); + double cte_rows); extern void set_tablefunc_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern void set_namedtuplestore_size_estimates(PlannerInfo *root, RelOptInfo *rel); +extern void set_result_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel); extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target); extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, - Path *bitmapqual, int loop_count, Cost *cost, double *tuple); - -/* - * prototypes for clausesel.c - * routines to compute clause selectivities - */ -extern Selectivity clauselist_selectivity(PlannerInfo *root, - List *clauses, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo); -extern Selectivity clause_selectivity(PlannerInfo *root, - Node *clause, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo); -extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root, - RelOptInfo *rel, ParamPathInfo *param_info, - Cost input_startup_cost, Cost input_total_cost, - double *rows); + Path *bitmapqual, int loop_count, Cost *cost, double *tuple); #endif /* COST_H */ diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h index 4ae4b6374a6..484b360f1fd 100644 --- a/src/include/optimizer/geqo.h +++ b/src/include/optimizer/geqo.h @@ -3,7 +3,7 @@ * geqo.h * prototypes for various files in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo.h @@ -22,7 +22,7 @@ #ifndef GEQO_H #define GEQO_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "optimizer/geqo_gene.h" @@ -79,7 +79,7 @@ typedef struct /* routines in geqo_main.c */ extern RelOptInfo *geqo(PlannerInfo *root, - int number_of_rels, List *initial_rels); + int number_of_rels, List *initial_rels); /* routines in geqo_eval.c */ extern Cost geqo_eval(PlannerInfo *root, Gene *tour, int num_gene); diff --git a/src/include/optimizer/geqo_copy.h b/src/include/optimizer/geqo_copy.h index f70786bef40..0654b06d5d0 100644 --- a/src/include/optimizer/geqo_copy.h +++ b/src/include/optimizer/geqo_copy.h @@ -3,7 +3,7 @@ * geqo_copy.h * prototypes for copy functions in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_copy.h diff --git a/src/include/optimizer/geqo_gene.h b/src/include/optimizer/geqo_gene.h index 3ddd268449e..ff4c024bb60 100644 --- a/src/include/optimizer/geqo_gene.h +++ b/src/include/optimizer/geqo_gene.h @@ -3,7 +3,7 @@ * geqo_gene.h * genome representation in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_gene.h diff --git a/src/include/optimizer/geqo_misc.h b/src/include/optimizer/geqo_misc.h index 26a36690064..9b15b7455e1 100644 --- a/src/include/optimizer/geqo_misc.h +++ b/src/include/optimizer/geqo_misc.h @@ -3,7 +3,7 @@ * geqo_misc.h * prototypes for printout routines in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_misc.h diff --git a/src/include/optimizer/geqo_mutation.h b/src/include/optimizer/geqo_mutation.h index c9a00255235..4ffed687ff3 100644 --- a/src/include/optimizer/geqo_mutation.h +++ b/src/include/optimizer/geqo_mutation.h @@ -3,7 +3,7 @@ * geqo_mutation.h * prototypes for mutation functions in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_mutation.h diff --git a/src/include/optimizer/geqo_pool.h b/src/include/optimizer/geqo_pool.h index eb343412f81..7a135ad72b0 100644 --- a/src/include/optimizer/geqo_pool.h +++ b/src/include/optimizer/geqo_pool.h @@ -3,7 +3,7 @@ * geqo_pool.h * pool representation in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_pool.h diff --git a/src/include/optimizer/geqo_random.h b/src/include/optimizer/geqo_random.h index 03bd0ae8ebf..398455e2e92 100644 --- a/src/include/optimizer/geqo_random.h +++ b/src/include/optimizer/geqo_random.h @@ -3,7 +3,7 @@ * geqo_random.h * random number generator * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_random.h diff --git a/src/include/optimizer/geqo_recombination.h b/src/include/optimizer/geqo_recombination.h index 3ca89d80911..8dfda79cdf9 100644 --- a/src/include/optimizer/geqo_recombination.h +++ b/src/include/optimizer/geqo_recombination.h @@ -3,7 +3,7 @@ * geqo_recombination.h * prototypes for recombination in the genetic query optimizer * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_recombination.h @@ -43,10 +43,10 @@ extern Edge *alloc_edge_table(PlannerInfo *root, int num_gene); extern void free_edge_table(PlannerInfo *root, Edge *edge_table); extern float gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2, - int num_gene, Edge *edge_table); + int num_gene, Edge *edge_table); -extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, - int num_gene); +extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, + int num_gene); /* partially matched crossover [PMX] */ @@ -55,8 +55,8 @@ extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, #define MOM 0 /* indicator for gene from mom */ extern void pmx(PlannerInfo *root, - Gene *tour1, Gene *tour2, - Gene *offspring, int num_gene); + Gene *tour1, Gene *tour2, + Gene *offspring, int num_gene); typedef struct City @@ -71,19 +71,19 @@ extern City * alloc_city_table(PlannerInfo *root, int num_gene); extern void free_city_table(PlannerInfo *root, City * city_table); /* cycle crossover [CX] */ -extern int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, - Gene *offspring, int num_gene, City * city_table); +extern int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, + Gene *offspring, int num_gene, City * city_table); /* position crossover [PX] */ extern void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, - int num_gene, City * city_table); + int num_gene, City * city_table); /* order crossover [OX1] according to Davis */ extern void ox1(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, - int num_gene, City * city_table); + int num_gene, City * city_table); /* order crossover [OX2] according to Syswerda */ extern void ox2(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, - int num_gene, City * city_table); + int num_gene, City * city_table); #endif /* GEQO_RECOMBINATION_H */ diff --git a/src/include/optimizer/geqo_selection.h b/src/include/optimizer/geqo_selection.h index d6bea3c2bd7..85c0d215104 100644 --- a/src/include/optimizer/geqo_selection.h +++ b/src/include/optimizer/geqo_selection.h @@ -3,7 +3,7 @@ * geqo_selection.h * prototypes for selection routines in optimizer/geqo * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/geqo_selection.h @@ -27,7 +27,7 @@ extern void geqo_selection(PlannerInfo *root, - Chromosome *momma, Chromosome *daddy, - Pool *pool, double bias); + Chromosome *momma, Chromosome *daddy, + Pool *pool, double bias); #endif /* GEQO_SELECTION_H */ diff --git a/src/include/optimizer/inherit.h b/src/include/optimizer/inherit.h new file mode 100644 index 00000000000..f465a526c70 --- /dev/null +++ b/src/include/optimizer/inherit.h @@ -0,0 +1,27 @@ +/*------------------------------------------------------------------------- + * + * inherit.h + * prototypes for inherit.c. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/inherit.h + * + *------------------------------------------------------------------------- + */ +#ifndef INHERIT_H +#define INHERIT_H + +#include "nodes/pathnodes.h" + + +extern void expand_inherited_rtentry(PlannerInfo *root, RelOptInfo *rel, + RangeTblEntry *rte, Index rti); + +extern bool apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, + RelOptInfo *childrel, RangeTblEntry *childRTE, + AppendRelInfo *appinfo); + +#endif /* INHERIT_H */ diff --git a/src/include/optimizer/joininfo.h b/src/include/optimizer/joininfo.h index 48f6d625e2e..0807d1901f3 100644 --- a/src/include/optimizer/joininfo.h +++ b/src/include/optimizer/joininfo.h @@ -4,7 +4,7 @@ * prototypes for joininfo.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/joininfo.h @@ -14,17 +14,17 @@ #ifndef JOININFO_H #define JOININFO_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" extern bool have_relevant_joinclause(PlannerInfo *root, - RelOptInfo *rel1, RelOptInfo *rel2); + RelOptInfo *rel1, RelOptInfo *rel2); extern void add_join_clause_to_rels(PlannerInfo *root, - RestrictInfo *restrictinfo, - Relids join_relids); + RestrictInfo *restrictinfo, + Relids join_relids); extern void remove_join_clause_from_rels(PlannerInfo *root, - RestrictInfo *restrictinfo, - Relids join_relids); + RestrictInfo *restrictinfo, + Relids join_relids); #endif /* JOININFO_H */ diff --git a/src/include/optimizer/optimizer.h b/src/include/optimizer/optimizer.h new file mode 100644 index 00000000000..6b8fd3f285e --- /dev/null +++ b/src/include/optimizer/optimizer.h @@ -0,0 +1,189 @@ +/*------------------------------------------------------------------------- + * + * optimizer.h + * External API for the Postgres planner. + * + * This header is meant to define everything that the core planner + * exposes for use by non-planner modules. + * + * Note that there are files outside src/backend/optimizer/ that are + * considered planner modules, because they're too much in bed with + * planner operations to be treated otherwise. FDW planning code is an + * example. For the most part, however, code outside the core planner + * should not need to include any optimizer/ header except this one. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/optimizer.h + * + *------------------------------------------------------------------------- + */ +#ifndef OPTIMIZER_H +#define OPTIMIZER_H + +#include "nodes/parsenodes.h" + +/* + * We don't want to include nodes/pathnodes.h here, because non-planner + * code should generally treat PlannerInfo as an opaque typedef. + * But we'd like such code to use that typedef name, so define the + * typedef either here or in pathnodes.h, whichever is read first. + */ +#ifndef HAVE_PLANNERINFO_TYPEDEF +typedef struct PlannerInfo PlannerInfo; +#define HAVE_PLANNERINFO_TYPEDEF 1 +#endif + +/* Likewise for IndexOptInfo and SpecialJoinInfo. */ +#ifndef HAVE_INDEXOPTINFO_TYPEDEF +typedef struct IndexOptInfo IndexOptInfo; +#define HAVE_INDEXOPTINFO_TYPEDEF 1 +#endif +#ifndef HAVE_SPECIALJOININFO_TYPEDEF +typedef struct SpecialJoinInfo SpecialJoinInfo; +#define HAVE_SPECIALJOININFO_TYPEDEF 1 +#endif + +/* It also seems best not to include plannodes.h, params.h, or htup.h here */ +struct PlannedStmt; +struct ParamListInfoData; +struct HeapTupleData; + + +/* in path/clausesel.c: */ + +extern Selectivity clause_selectivity(PlannerInfo *root, + Node *clause, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); +extern Selectivity clauselist_selectivity_simple(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + Bitmapset *estimatedclauses); +extern Selectivity clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); + +/* in path/costsize.c: */ + +/* widely used cost parameters */ +extern PGDLLIMPORT double seq_page_cost; +extern PGDLLIMPORT double random_page_cost; +extern PGDLLIMPORT double cpu_tuple_cost; +extern PGDLLIMPORT double cpu_index_tuple_cost; +extern PGDLLIMPORT double cpu_operator_cost; +extern PGDLLIMPORT double parallel_tuple_cost; +extern PGDLLIMPORT double parallel_setup_cost; +extern PGDLLIMPORT int effective_cache_size; + +extern double clamp_row_est(double nrows); + +/* in path/indxpath.c: */ + +extern bool is_pseudo_constant_for_index(Node *expr, IndexOptInfo *index); + +/* in plan/planner.c: */ + +/* possible values for force_parallel_mode */ +typedef enum +{ + FORCE_PARALLEL_OFF, + FORCE_PARALLEL_ON, + FORCE_PARALLEL_REGRESS +} ForceParallelMode; + +/* GUC parameters */ +extern int force_parallel_mode; +extern bool parallel_leader_participation; + +extern struct PlannedStmt *planner(Query *parse, int cursorOptions, + struct ParamListInfoData *boundParams); + +extern Expr *expression_planner(Expr *expr); +extern Expr *expression_planner_with_deps(Expr *expr, + List **relationOids, + List **invalItems); + +extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid); +extern int plan_create_index_workers(Oid tableOid, Oid indexOid); + +/* in plan/setrefs.c: */ + +extern void extract_query_dependencies(Node *query, + List **relationOids, + List **invalItems, + bool *hasRowSecurity); + +/* in prep/prepqual.c: */ + +extern Node *negate_clause(Node *node); +extern Expr *canonicalize_qual(Expr *qual, bool is_check); + +/* in util/clauses.c: */ + +extern bool contain_mutable_functions(Node *clause); +extern bool contain_volatile_functions(Node *clause); +extern bool contain_volatile_functions_not_nextval(Node *clause); + +extern Node *eval_const_expressions(PlannerInfo *root, Node *node); + +extern Node *estimate_expression_value(PlannerInfo *root, Node *node); + +extern Expr *evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod, + Oid result_collation); + +extern List *expand_function_arguments(List *args, Oid result_type, + struct HeapTupleData *func_tuple); + +/* in util/predtest.c: */ + +extern bool predicate_implied_by(List *predicate_list, List *clause_list, + bool weak); +extern bool predicate_refuted_by(List *predicate_list, List *clause_list, + bool weak); + +/* in util/tlist.c: */ + +extern int count_nonjunk_tlist_entries(List *tlist); +extern TargetEntry *get_sortgroupref_tle(Index sortref, + List *targetList); +extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause, + List *targetList); +extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause, + List *targetList); +extern List *get_sortgrouplist_exprs(List *sgClauses, + List *targetList); +extern SortGroupClause *get_sortgroupref_clause(Index sortref, + List *clauses); +extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref, + List *clauses); + +/* in util/var.c: */ + +/* Bits that can be OR'd into the flags argument of pull_var_clause() */ +#define PVC_INCLUDE_AGGREGATES 0x0001 /* include Aggrefs in output list */ +#define PVC_RECURSE_AGGREGATES 0x0002 /* recurse into Aggref arguments */ +#define PVC_INCLUDE_WINDOWFUNCS 0x0004 /* include WindowFuncs in output list */ +#define PVC_RECURSE_WINDOWFUNCS 0x0008 /* recurse into WindowFunc arguments */ +#define PVC_INCLUDE_PLACEHOLDERS 0x0010 /* include PlaceHolderVars in + * output list */ +#define PVC_RECURSE_PLACEHOLDERS 0x0020 /* recurse into PlaceHolderVar + * arguments */ + +extern Bitmapset *pull_varnos(Node *node); +extern Bitmapset *pull_varnos_of_level(Node *node, int levelsup); +extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos); +extern List *pull_vars_of_level(Node *node, int levelsup); +extern bool contain_var_clause(Node *node); +extern bool contain_vars_of_level(Node *node, int levelsup); +extern int locate_var_of_level(Node *node, int levelsup); +extern List *pull_var_clause(Node *node, int flags); +extern Node *flatten_join_alias_vars(Query *query, Node *node); + +#endif /* OPTIMIZER_H */ diff --git a/src/include/optimizer/orclauses.h b/src/include/optimizer/orclauses.h index 2154e66746a..b5279001896 100644 --- a/src/include/optimizer/orclauses.h +++ b/src/include/optimizer/orclauses.h @@ -4,7 +4,7 @@ * prototypes for orclauses.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/orclauses.h @@ -14,7 +14,7 @@ #ifndef ORCLAUSES_H #define ORCLAUSES_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" extern void extract_restriction_or_clauses(PlannerInfo *root); diff --git a/src/include/optimizer/paramassign.h b/src/include/optimizer/paramassign.h new file mode 100644 index 00000000000..edf3ed86281 --- /dev/null +++ b/src/include/optimizer/paramassign.h @@ -0,0 +1,34 @@ +/*------------------------------------------------------------------------- + * + * paramassign.h + * Functions for assigning PARAM_EXEC slots during planning. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/optimizer/paramassign.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARAMASSIGN_H +#define PARAMASSIGN_H + +#include "nodes/pathnodes.h" + +extern Param *replace_outer_var(PlannerInfo *root, Var *var); +extern Param *replace_outer_placeholdervar(PlannerInfo *root, + PlaceHolderVar *phv); +extern Param *replace_outer_agg(PlannerInfo *root, Aggref *agg); +extern Param *replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp); +extern Param *replace_nestloop_param_var(PlannerInfo *root, Var *var); +extern Param *replace_nestloop_param_placeholdervar(PlannerInfo *root, + PlaceHolderVar *phv); +extern void process_subquery_nestloop_params(PlannerInfo *root, + List *subplan_params); +extern List *identify_current_nestloop_params(PlannerInfo *root, + Relids leftrelids); +extern Param *generate_new_exec_param(PlannerInfo *root, Oid paramtype, + int32 paramtypmod, Oid paramcollation); +extern int assign_special_exec_param(PlannerInfo *root); + +#endif /* PARAMASSIGN_H */ diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index 4f65686d9be..a12af54971b 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -4,7 +4,7 @@ * prototypes for pathnode.c, relnode.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/pathnode.h @@ -15,292 +15,303 @@ #define PATHNODE_H #include "nodes/bitmapset.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" /* * prototypes for pathnode.c */ -extern int compare_path_costs(Path *path1, Path *path2, - CostSelector criterion); -extern int compare_fractional_path_costs(Path *path1, Path *path2, - double fraction); +extern int compare_path_costs(Path *path1, Path *path2, + CostSelector criterion); +extern int compare_fractional_path_costs(Path *path1, Path *path2, + double fraction); extern void set_cheapest(RelOptInfo *parent_rel); extern void add_path(RelOptInfo *parent_rel, Path *new_path); extern bool add_path_precheck(RelOptInfo *parent_rel, - Cost startup_cost, Cost total_cost, - List *pathkeys, Relids required_outer); + Cost startup_cost, Cost total_cost, + List *pathkeys, Relids required_outer); extern void add_partial_path(RelOptInfo *parent_rel, Path *new_path); extern bool add_partial_path_precheck(RelOptInfo *parent_rel, - Cost total_cost, List *pathkeys); + Cost total_cost, List *pathkeys); extern Path *create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer, int parallel_workers); + Relids required_outer, int parallel_workers); extern Path *create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern IndexPath *create_index_path(PlannerInfo *root, - IndexOptInfo *index, - List *indexclauses, - List *indexclausecols, - List *indexorderbys, - List *indexorderbycols, - List *pathkeys, - ScanDirection indexscandir, - bool indexonly, - Relids required_outer, - double loop_count, - bool partial_path); + IndexOptInfo *index, + List *indexclauses, + List *indexorderbys, + List *indexorderbycols, + List *pathkeys, + ScanDirection indexscandir, + bool indexonly, + Relids required_outer, + double loop_count, + bool partial_path); extern BitmapHeapPath *create_bitmap_heap_path(PlannerInfo *root, - RelOptInfo *rel, - Path *bitmapqual, - Relids required_outer, - double loop_count, - int parallel_degree); + RelOptInfo *rel, + Path *bitmapqual, + Relids required_outer, + double loop_count, + int parallel_degree); extern BitmapAndPath *create_bitmap_and_path(PlannerInfo *root, - RelOptInfo *rel, - List *bitmapquals); + RelOptInfo *rel, + List *bitmapquals); extern BitmapOrPath *create_bitmap_or_path(PlannerInfo *root, - RelOptInfo *rel, - List *bitmapquals); + RelOptInfo *rel, + List *bitmapquals); extern TidPath *create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, - List *tidquals, Relids required_outer); + List *tidquals, Relids required_outer); extern AppendPath *create_append_path(PlannerInfo *root, RelOptInfo *rel, - List *subpaths, List *partial_subpaths, - Relids required_outer, - int parallel_workers, bool parallel_aware, - List *partitioned_rels, double rows); + List *subpaths, List *partial_subpaths, + List *pathkeys, Relids required_outer, + int parallel_workers, bool parallel_aware, + List *partitioned_rels, double rows); extern MergeAppendPath *create_merge_append_path(PlannerInfo *root, - RelOptInfo *rel, - List *subpaths, - List *pathkeys, - Relids required_outer, - List *partitioned_rels); -extern ResultPath *create_result_path(PlannerInfo *root, RelOptInfo *rel, - PathTarget *target, List *resconstantqual); + RelOptInfo *rel, + List *subpaths, + List *pathkeys, + Relids required_outer, + List *partitioned_rels); +extern GroupResultPath *create_group_result_path(PlannerInfo *root, + RelOptInfo *rel, + PathTarget *target, + List *havingqual); extern MaterialPath *create_material_path(RelOptInfo *rel, Path *subpath); extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel, - Path *subpath, SpecialJoinInfo *sjinfo); + Path *subpath, SpecialJoinInfo *sjinfo); extern GatherPath *create_gather_path(PlannerInfo *root, - RelOptInfo *rel, Path *subpath, PathTarget *target, - Relids required_outer, double *rows); + RelOptInfo *rel, Path *subpath, PathTarget *target, + Relids required_outer, double *rows); extern GatherMergePath *create_gather_merge_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - PathTarget *target, - List *pathkeys, - Relids required_outer, - double *rows); + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + List *pathkeys, + Relids required_outer, + double *rows); extern SubqueryScanPath *create_subqueryscan_path(PlannerInfo *root, - RelOptInfo *rel, Path *subpath, - List *pathkeys, Relids required_outer); + RelOptInfo *rel, Path *subpath, + List *pathkeys, Relids required_outer); extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, - List *pathkeys, Relids required_outer); -extern Path *create_tablexprscan_path(PlannerInfo *root, RelOptInfo *rel, - List *pathkeys, Relids required_outer); + List *pathkeys, Relids required_outer); extern Path *create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern Path *create_tablefuncscan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern Path *create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern Path *create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); +extern Path *create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, + Relids required_outer); extern Path *create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern ForeignPath *create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, - PathTarget *target, - double rows, Cost startup_cost, Cost total_cost, - List *pathkeys, - Relids required_outer, - Path *fdw_outerpath, - List *fdw_private); + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Relids required_outer, + Path *fdw_outerpath, + List *fdw_private); +extern ForeignPath *create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Relids required_outer, + Path *fdw_outerpath, + List *fdw_private); +extern ForeignPath *create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, + PathTarget *target, + double rows, Cost startup_cost, Cost total_cost, + List *pathkeys, + Path *fdw_outerpath, + List *fdw_private); extern Relids calc_nestloop_required_outer(Relids outerrelids, - Relids outer_paramrels, - Relids innerrelids, - Relids inner_paramrels); + Relids outer_paramrels, + Relids innerrelids, + Relids inner_paramrels); extern Relids calc_non_nestloop_required_outer(Path *outer_path, Path *inner_path); extern NestPath *create_nestloop_path(PlannerInfo *root, - RelOptInfo *joinrel, - JoinType jointype, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra, - Path *outer_path, - Path *inner_path, - List *restrict_clauses, - List *pathkeys, - Relids required_outer); + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + List *restrict_clauses, + List *pathkeys, + Relids required_outer); extern MergePath *create_mergejoin_path(PlannerInfo *root, - RelOptInfo *joinrel, - JoinType jointype, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra, - Path *outer_path, - Path *inner_path, - List *restrict_clauses, - List *pathkeys, - Relids required_outer, - List *mergeclauses, - List *outersortkeys, - List *innersortkeys); + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + List *restrict_clauses, + List *pathkeys, + Relids required_outer, + List *mergeclauses, + List *outersortkeys, + List *innersortkeys); extern HashPath *create_hashjoin_path(PlannerInfo *root, - RelOptInfo *joinrel, - JoinType jointype, - JoinCostWorkspace *workspace, - JoinPathExtraData *extra, - Path *outer_path, - Path *inner_path, - bool parallel_hash, - List *restrict_clauses, - Relids required_outer, - List *hashclauses); + RelOptInfo *joinrel, + JoinType jointype, + JoinCostWorkspace *workspace, + JoinPathExtraData *extra, + Path *outer_path, + Path *inner_path, + bool parallel_hash, + List *restrict_clauses, + Relids required_outer, + List *hashclauses); extern ProjectionPath *create_projection_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - PathTarget *target); + RelOptInfo *rel, + Path *subpath, + PathTarget *target); extern Path *apply_projection_to_path(PlannerInfo *root, - RelOptInfo *rel, - Path *path, - PathTarget *target); + RelOptInfo *rel, + Path *path, + PathTarget *target); extern ProjectSetPath *create_set_projection_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - PathTarget *target); + RelOptInfo *rel, + Path *subpath, + PathTarget *target); extern SortPath *create_sort_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - List *pathkeys, - double limit_tuples); + RelOptInfo *rel, + Path *subpath, + List *pathkeys, + double limit_tuples); extern GroupPath *create_group_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - List *groupClause, - List *qual, - double numGroups); + RelOptInfo *rel, + Path *subpath, + List *groupClause, + List *qual, + double numGroups); extern UpperUniquePath *create_upper_unique_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - int numCols, - double numGroups); + RelOptInfo *rel, + Path *subpath, + int numCols, + double numGroups); extern AggPath *create_agg_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - PathTarget *target, - AggStrategy aggstrategy, - AggSplit aggsplit, - List *groupClause, - List *qual, - const AggClauseCosts *aggcosts, - double numGroups); + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + AggStrategy aggstrategy, + AggSplit aggsplit, + List *groupClause, + List *qual, + const AggClauseCosts *aggcosts, + double numGroups); extern GroupingSetsPath *create_groupingsets_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - List *having_qual, - AggStrategy aggstrategy, - List *rollups, - const AggClauseCosts *agg_costs, - double numGroups); + RelOptInfo *rel, + Path *subpath, + List *having_qual, + AggStrategy aggstrategy, + List *rollups, + const AggClauseCosts *agg_costs, + double numGroups); extern MinMaxAggPath *create_minmaxagg_path(PlannerInfo *root, - RelOptInfo *rel, - PathTarget *target, - List *mmaggregates, - List *quals); + RelOptInfo *rel, + PathTarget *target, + List *mmaggregates, + List *quals); extern WindowAggPath *create_windowagg_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - PathTarget *target, - List *windowFuncs, - WindowClause *winclause, - List *winpathkeys); + RelOptInfo *rel, + Path *subpath, + PathTarget *target, + List *windowFuncs, + WindowClause *winclause); extern SetOpPath *create_setop_path(PlannerInfo *root, - RelOptInfo *rel, - Path *subpath, - SetOpCmd cmd, - SetOpStrategy strategy, - List *distinctList, - AttrNumber flagColIdx, - int firstFlag, - double numGroups, - double outputRows); + RelOptInfo *rel, + Path *subpath, + SetOpCmd cmd, + SetOpStrategy strategy, + List *distinctList, + AttrNumber flagColIdx, + int firstFlag, + double numGroups, + double outputRows); extern RecursiveUnionPath *create_recursiveunion_path(PlannerInfo *root, - RelOptInfo *rel, - Path *leftpath, - Path *rightpath, - PathTarget *target, - List *distinctList, - int wtParam, - double numGroups); + RelOptInfo *rel, + Path *leftpath, + Path *rightpath, + PathTarget *target, + List *distinctList, + int wtParam, + double numGroups); extern LockRowsPath *create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, - Path *subpath, List *rowMarks, int epqParam); + Path *subpath, List *rowMarks, int epqParam); extern ModifyTablePath *create_modifytable_path(PlannerInfo *root, - RelOptInfo *rel, - CmdType operation, bool canSetTag, - Index nominalRelation, List *partitioned_rels, - bool partColsUpdated, - List *resultRelations, - Index mergeTargetRelation, - List *subpaths, - List *subroots, - List *withCheckOptionLists, List *returningLists, - List *rowMarks, OnConflictExpr *onconflict, - List *mergeSourceTargetList, - List *mergeActionList, int epqParam); + RelOptInfo *rel, + CmdType operation, bool canSetTag, + Index nominalRelation, Index rootRelation, + bool partColsUpdated, + List *resultRelations, List *subpaths, + List *subroots, + List *withCheckOptionLists, List *returningLists, + List *rowMarks, OnConflictExpr *onconflict, + int epqParam); extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel, - Path *subpath, - Node *limitOffset, Node *limitCount, - int64 offset_est, int64 count_est); + Path *subpath, + Node *limitOffset, Node *limitCount, + int64 offset_est, int64 count_est); +extern void adjust_limit_rows_costs(double *rows, + Cost *startup_cost, Cost *total_cost, + int64 offset_est, int64 count_est); extern Path *reparameterize_path(PlannerInfo *root, Path *path, - Relids required_outer, - double loop_count); + Relids required_outer, + double loop_count); extern Path *reparameterize_path_by_child(PlannerInfo *root, Path *path, - RelOptInfo *child_rel); + RelOptInfo *child_rel); /* * prototypes for relnode.c */ extern void setup_simple_rel_arrays(PlannerInfo *root); +extern void expand_planner_arrays(PlannerInfo *root, int add_size); extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, - RelOptInfo *parent); + RelOptInfo *parent); extern RelOptInfo *find_base_rel(PlannerInfo *root, int relid); extern RelOptInfo *find_join_rel(PlannerInfo *root, Relids relids); extern RelOptInfo *build_join_rel(PlannerInfo *root, - Relids joinrelids, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel, - SpecialJoinInfo *sjinfo, - List **restrictlist_ptr); + Relids joinrelids, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel, + SpecialJoinInfo *sjinfo, + List **restrictlist_ptr); extern Relids min_join_parameterization(PlannerInfo *root, - Relids joinrelids, - RelOptInfo *outer_rel, - RelOptInfo *inner_rel); -extern RelOptInfo *build_empty_join_rel(PlannerInfo *root); + Relids joinrelids, + RelOptInfo *outer_rel, + RelOptInfo *inner_rel); extern RelOptInfo *fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, - Relids relids); -extern AppendRelInfo *find_childrel_appendrelinfo(PlannerInfo *root, - RelOptInfo *rel); + Relids relids); extern Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel); extern ParamPathInfo *get_baserel_parampathinfo(PlannerInfo *root, - RelOptInfo *baserel, - Relids required_outer); + RelOptInfo *baserel, + Relids required_outer); extern ParamPathInfo *get_joinrel_parampathinfo(PlannerInfo *root, - RelOptInfo *joinrel, - Path *outer_path, - Path *inner_path, - SpecialJoinInfo *sjinfo, - Relids required_outer, - List **restrict_clauses); + RelOptInfo *joinrel, + Path *outer_path, + Path *inner_path, + SpecialJoinInfo *sjinfo, + Relids required_outer, + List **restrict_clauses); extern ParamPathInfo *get_appendrel_parampathinfo(RelOptInfo *appendrel, - Relids required_outer); + Relids required_outer); extern ParamPathInfo *find_param_path_info(RelOptInfo *rel, - Relids required_outer); + Relids required_outer); extern RelOptInfo *build_child_join_rel(PlannerInfo *root, - RelOptInfo *outer_rel, RelOptInfo *inner_rel, - RelOptInfo *parent_joinrel, List *restrictlist, - SpecialJoinInfo *sjinfo, JoinType jointype); + RelOptInfo *outer_rel, RelOptInfo *inner_rel, + RelOptInfo *parent_joinrel, List *restrictlist, + SpecialJoinInfo *sjinfo, JoinType jointype); #endif /* PATHNODE_H */ diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h index 50e180c5543..7345137d1da 100644 --- a/src/include/optimizer/paths.h +++ b/src/include/optimizer/paths.h @@ -4,7 +4,7 @@ * prototypes for various files in optimizer/path * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/paths.h @@ -14,16 +14,16 @@ #ifndef PATHS_H #define PATHS_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" /* * allpaths.c */ extern PGDLLIMPORT bool enable_geqo; -extern PGDLLIMPORT int geqo_threshold; -extern PGDLLIMPORT int min_parallel_table_scan_size; -extern PGDLLIMPORT int min_parallel_index_scan_size; +extern PGDLLIMPORT int geqo_threshold; +extern PGDLLIMPORT int min_parallel_table_scan_size; +extern PGDLLIMPORT int min_parallel_index_scan_size; /* Hook for plugins to get control in set_rel_pathlist() */ typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, @@ -49,18 +49,17 @@ extern PGDLLIMPORT join_search_hook_type join_search_hook; extern RelOptInfo *make_one_rel(PlannerInfo *root, List *joinlist); -extern void set_dummy_rel_pathlist(RelOptInfo *rel); extern RelOptInfo *standard_join_search(PlannerInfo *root, int levels_needed, - List *initial_rels); + List *initial_rels); extern void generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, - bool override_rows); -extern int compute_parallel_worker(RelOptInfo *rel, double heap_pages, - double index_pages, int max_workers); + bool override_rows); +extern int compute_parallel_worker(RelOptInfo *rel, double heap_pages, + double index_pages, int max_workers); extern void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel, - Path *bitmapqual); + Path *bitmapqual); extern void generate_partitionwise_join_paths(PlannerInfo *root, - RelOptInfo *rel); + RelOptInfo *rel); #ifdef OPTIMIZER_DEBUG extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel); @@ -72,21 +71,13 @@ extern void debug_print_rel(PlannerInfo *root, RelOptInfo *rel); */ extern void create_index_paths(PlannerInfo *root, RelOptInfo *rel); extern bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, - List *restrictlist, - List *exprlist, List *oprlist); + List *restrictlist, + List *exprlist, List *oprlist); extern bool indexcol_is_bool_constant_for_query(IndexOptInfo *index, - int indexcol); + int indexcol); extern bool match_index_to_operand(Node *operand, int indexcol, - IndexOptInfo *index); -extern void expand_indexqual_conditions(IndexOptInfo *index, - List *indexclauses, List *indexclausecols, - List **indexquals_p, List **indexqualcols_p); + IndexOptInfo *index); extern void check_index_predicates(PlannerInfo *root, RelOptInfo *rel); -extern Expr *adjust_rowcompare_for_index(RowCompareExpr *clause, - IndexOptInfo *index, - int indexcol, - List **indexcolnos, - bool *var_on_left_p); /* * tidpath.h @@ -99,9 +90,9 @@ extern void create_tidscan_paths(PlannerInfo *root, RelOptInfo *rel); * routines to create join paths */ extern void add_paths_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *outerrel, RelOptInfo *innerrel, - JoinType jointype, SpecialJoinInfo *sjinfo, - List *restrictlist); + RelOptInfo *outerrel, RelOptInfo *innerrel, + JoinType jointype, SpecialJoinInfo *sjinfo, + List *restrictlist); /* * joinrels.c @@ -109,14 +100,15 @@ extern void add_paths_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, */ extern void join_search_one_level(PlannerInfo *root, int level); extern RelOptInfo *make_join_rel(PlannerInfo *root, - RelOptInfo *rel1, RelOptInfo *rel2); + RelOptInfo *rel1, RelOptInfo *rel2); extern bool have_join_order_restriction(PlannerInfo *root, - RelOptInfo *rel1, RelOptInfo *rel2); + RelOptInfo *rel1, RelOptInfo *rel2); extern bool have_dangerous_phv(PlannerInfo *root, - Relids outer_relids, Relids inner_params); + Relids outer_relids, Relids inner_params); extern void mark_dummy_rel(RelOptInfo *rel); -extern bool have_partkey_equi_join(RelOptInfo *rel1, RelOptInfo *rel2, - JoinType jointype, List *restrictlist); +extern bool have_partkey_equi_join(RelOptInfo *joinrel, + RelOptInfo *rel1, RelOptInfo *rel2, + JoinType jointype, List *restrictlist); /* * equivclass.c @@ -129,51 +121,53 @@ typedef bool (*ec_matches_callback_type) (PlannerInfo *root, void *arg); extern bool process_equivalence(PlannerInfo *root, - RestrictInfo **p_restrictinfo, - bool below_outer_join); + RestrictInfo **p_restrictinfo, + bool below_outer_join); extern Expr *canonicalize_ec_expression(Expr *expr, - Oid req_type, Oid req_collation); + Oid req_type, Oid req_collation); extern void reconsider_outer_join_clauses(PlannerInfo *root); extern EquivalenceClass *get_eclass_for_sort_expr(PlannerInfo *root, - Expr *expr, - Relids nullable_relids, - List *opfamilies, - Oid opcintype, - Oid collation, - Index sortref, - Relids rel, - bool create_it); + Expr *expr, + Relids nullable_relids, + List *opfamilies, + Oid opcintype, + Oid collation, + Index sortref, + Relids rel, + bool create_it); extern void generate_base_implied_equalities(PlannerInfo *root); extern List *generate_join_implied_equalities(PlannerInfo *root, - Relids join_relids, - Relids outer_relids, - RelOptInfo *inner_rel); + Relids join_relids, + Relids outer_relids, + RelOptInfo *inner_rel); extern List *generate_join_implied_equalities_for_ecs(PlannerInfo *root, - List *eclasses, - Relids join_relids, - Relids outer_relids, - RelOptInfo *inner_rel); + List *eclasses, + Relids join_relids, + Relids outer_relids, + RelOptInfo *inner_rel); extern bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2); extern EquivalenceClass *match_eclasses_to_foreign_key_col(PlannerInfo *root, - ForeignKeyOptInfo *fkinfo, - int colno); + ForeignKeyOptInfo *fkinfo, + int colno); extern void add_child_rel_equivalences(PlannerInfo *root, - AppendRelInfo *appinfo, - RelOptInfo *parent_rel, - RelOptInfo *child_rel); + AppendRelInfo *appinfo, + RelOptInfo *parent_rel, + RelOptInfo *child_rel); extern List *generate_implied_equalities_for_column(PlannerInfo *root, - RelOptInfo *rel, - ec_matches_callback_type callback, - void *callback_arg, - Relids prohibited_rels); + RelOptInfo *rel, + ec_matches_callback_type callback, + void *callback_arg, + Relids prohibited_rels); extern bool have_relevant_eclass_joinclause(PlannerInfo *root, - RelOptInfo *rel1, RelOptInfo *rel2); + RelOptInfo *rel1, RelOptInfo *rel2); extern bool has_relevant_eclass_joinclause(PlannerInfo *root, - RelOptInfo *rel1); + RelOptInfo *rel1); extern bool eclass_useful_for_merging(PlannerInfo *root, - EquivalenceClass *eclass, - RelOptInfo *rel); + EquivalenceClass *eclass, + RelOptInfo *rel); extern bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist); +extern bool is_redundant_with_indexclauses(RestrictInfo *rinfo, + List *indexclauses); /* * pathkeys.c @@ -190,53 +184,55 @@ typedef enum extern PathKeysComparison compare_pathkeys(List *keys1, List *keys2); extern bool pathkeys_contained_in(List *keys1, List *keys2); extern Path *get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, - Relids required_outer, - CostSelector cost_criterion, - bool require_parallel_safe); + Relids required_outer, + CostSelector cost_criterion, + bool require_parallel_safe); extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths, - List *pathkeys, - Relids required_outer, - double fraction); + List *pathkeys, + Relids required_outer, + double fraction); extern Path *get_cheapest_parallel_safe_total_inner(List *paths); extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index, - ScanDirection scandir); + ScanDirection scandir); +extern List *build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel, + ScanDirection scandir, bool *partialkeys); extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr, - Relids nullable_relids, Oid opno, - Relids rel, bool create_it); + Relids nullable_relids, Oid opno, + Relids rel, bool create_it); extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, - List *subquery_pathkeys, - List *subquery_tlist); + List *subquery_pathkeys, + List *subquery_tlist); extern List *build_join_pathkeys(PlannerInfo *root, - RelOptInfo *joinrel, - JoinType jointype, - List *outer_pathkeys); + RelOptInfo *joinrel, + JoinType jointype, + List *outer_pathkeys); extern List *make_pathkeys_for_sortclauses(PlannerInfo *root, - List *sortclauses, - List *tlist); + List *sortclauses, + List *tlist); extern void initialize_mergeclause_eclasses(PlannerInfo *root, - RestrictInfo *restrictinfo); + RestrictInfo *restrictinfo); extern void update_mergeclause_eclasses(PlannerInfo *root, - RestrictInfo *restrictinfo); + RestrictInfo *restrictinfo); extern List *find_mergeclauses_for_outer_pathkeys(PlannerInfo *root, - List *pathkeys, - List *restrictinfos); + List *pathkeys, + List *restrictinfos); extern List *select_outer_pathkeys_for_merge(PlannerInfo *root, - List *mergeclauses, - RelOptInfo *joinrel); + List *mergeclauses, + RelOptInfo *joinrel); extern List *make_inner_pathkeys_for_merge(PlannerInfo *root, - List *mergeclauses, - List *outer_pathkeys); + List *mergeclauses, + List *outer_pathkeys); extern List *trim_mergeclauses_for_inner_pathkeys(PlannerInfo *root, - List *mergeclauses, - List *pathkeys); + List *mergeclauses, + List *pathkeys); extern List *truncate_useless_pathkeys(PlannerInfo *root, - RelOptInfo *rel, - List *pathkeys); + RelOptInfo *rel, + List *pathkeys); extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel); extern PathKey *make_canonical_pathkey(PlannerInfo *root, - EquivalenceClass *eclass, Oid opfamily, - int strategy, bool nulls_first); + EquivalenceClass *eclass, Oid opfamily, + int strategy, bool nulls_first); extern void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, - List *live_childrels); + List *live_childrels); #endif /* PATHS_H */ diff --git a/src/include/optimizer/placeholder.h b/src/include/optimizer/placeholder.h index 91ebdb90fc6..08f71879235 100644 --- a/src/include/optimizer/placeholder.h +++ b/src/include/optimizer/placeholder.h @@ -4,7 +4,7 @@ * prototypes for optimizer/util/placeholder.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/placeholder.h @@ -14,21 +14,19 @@ #ifndef PLACEHOLDER_H #define PLACEHOLDER_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" extern PlaceHolderVar *make_placeholder_expr(PlannerInfo *root, Expr *expr, - Relids phrels); + Relids phrels); extern PlaceHolderInfo *find_placeholder_info(PlannerInfo *root, - PlaceHolderVar *phv, bool create_new_ph); + PlaceHolderVar *phv, bool create_new_ph); extern void find_placeholders_in_jointree(PlannerInfo *root); extern void update_placeholder_eval_levels(PlannerInfo *root, - SpecialJoinInfo *new_sjinfo); + SpecialJoinInfo *new_sjinfo); extern void fix_placeholder_input_needed_levels(PlannerInfo *root); extern void add_placeholders_to_base_rels(PlannerInfo *root); extern void add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, - RelOptInfo *outer_rel, RelOptInfo *inner_rel); -extern void add_placeholders_to_child_joinrel(PlannerInfo *root, - RelOptInfo *childrel, RelOptInfo *parentrel); + RelOptInfo *outer_rel, RelOptInfo *inner_rel); #endif /* PLACEHOLDER_H */ diff --git a/src/include/optimizer/plancat.h b/src/include/optimizer/plancat.h index 7d53cbbb872..bbb27f87798 100644 --- a/src/include/optimizer/plancat.h +++ b/src/include/optimizer/plancat.h @@ -4,7 +4,7 @@ * prototypes for plancat.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/plancat.h @@ -14,7 +14,7 @@ #ifndef PLANCAT_H #define PLANCAT_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #include "utils/relcache.h" /* Hook for plugins to get control in get_relation_info() */ @@ -26,35 +26,52 @@ extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook; extern void get_relation_info(PlannerInfo *root, Oid relationObjectId, - bool inhparent, RelOptInfo *rel); + bool inhparent, RelOptInfo *rel); extern List *infer_arbiter_indexes(PlannerInfo *root); extern void estimate_rel_size(Relation rel, int32 *attr_widths, - BlockNumber *pages, double *tuples, double *allvisfrac); + BlockNumber *pages, double *tuples, double *allvisfrac); +extern int32 get_rel_data_width(Relation rel, int32 *attr_widths); extern int32 get_relation_data_width(Oid relid, int32 *attr_widths); extern bool relation_excluded_by_constraints(PlannerInfo *root, - RelOptInfo *rel, RangeTblEntry *rte); + RelOptInfo *rel, RangeTblEntry *rte); extern List *build_physical_tlist(PlannerInfo *root, RelOptInfo *rel); extern bool has_unique_index(RelOptInfo *rel, AttrNumber attno); extern Selectivity restriction_selectivity(PlannerInfo *root, - Oid operatorid, - List *args, - Oid inputcollid, - int varRelid); + Oid operatorid, + List *args, + Oid inputcollid, + int varRelid); extern Selectivity join_selectivity(PlannerInfo *root, - Oid operatorid, - List *args, - Oid inputcollid, - JoinType jointype, - SpecialJoinInfo *sjinfo); + Oid operatorid, + List *args, + Oid inputcollid, + JoinType jointype, + SpecialJoinInfo *sjinfo); + +extern Selectivity function_selectivity(PlannerInfo *root, + Oid funcid, + List *args, + Oid inputcollid, + bool is_join, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo); + +extern void add_function_cost(PlannerInfo *root, Oid funcid, Node *node, + QualCost *cost); + +extern double get_function_rows(PlannerInfo *root, Oid funcid, Node *node); extern bool has_row_triggers(PlannerInfo *root, Index rti, CmdType event); +extern bool has_stored_generated_columns(PlannerInfo *root, Index rti); + #endif /* PLANCAT_H */ diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 7132c88242b..e7aaddd50d6 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -4,7 +4,7 @@ * prototypes for various files in optimizer/plan * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/planmain.h @@ -14,22 +14,12 @@ #ifndef PLANMAIN_H #define PLANMAIN_H +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" - -/* possible values for force_parallel_mode */ -typedef enum -{ - FORCE_PARALLEL_OFF, - FORCE_PARALLEL_ON, - FORCE_PARALLEL_REGRESS -} ForceParallelMode; /* GUC parameters */ #define DEFAULT_CURSOR_TUPLE_FRACTION 0.1 extern double cursor_tuple_fraction; -extern int force_parallel_mode; -extern bool parallel_leader_participation; /* query_planner callback to compute query_pathkeys */ typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra); @@ -37,22 +27,24 @@ typedef void (*query_pathkeys_callback) (PlannerInfo *root, void *extra); /* * prototypes for plan/planmain.c */ -extern RelOptInfo *query_planner(PlannerInfo *root, List *tlist, - query_pathkeys_callback qp_callback, void *qp_extra); +extern RelOptInfo *query_planner(PlannerInfo *root, + query_pathkeys_callback qp_callback, void *qp_extra); /* * prototypes for plan/planagg.c */ -extern void preprocess_minmax_aggregates(PlannerInfo *root, List *tlist); +extern void preprocess_minmax_aggregates(PlannerInfo *root); /* * prototypes for plan/createplan.c */ extern Plan *create_plan(PlannerInfo *root, Path *best_path); extern ForeignScan *make_foreignscan(List *qptlist, List *qpqual, - Index scanrelid, List *fdw_exprs, List *fdw_private, - List *fdw_scan_tlist, List *fdw_recheck_quals, - Plan *outer_plan); + Index scanrelid, List *fdw_exprs, List *fdw_private, + List *fdw_scan_tlist, List *fdw_recheck_quals, + Plan *outer_plan); +extern Plan *change_plan_targetlist(Plan *subplan, List *tlist, + bool tlist_parallel_safe); extern Plan *materialize_finished_plan(Plan *subplan); extern bool is_projection_capable_path(Path *path); extern bool is_projection_capable_plan(Plan *plan); @@ -60,10 +52,10 @@ extern bool is_projection_capable_plan(Plan *plan); /* External use of these functions is deprecated: */ extern Sort *make_sort_from_sortclauses(List *sortcls, Plan *lefttree); extern Agg *make_agg(List *tlist, List *qual, - AggStrategy aggstrategy, AggSplit aggsplit, - int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, - List *groupingSets, List *chain, - double dNumGroups, Plan *lefttree); + AggStrategy aggstrategy, AggSplit aggsplit, + int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, + List *groupingSets, List *chain, + double dNumGroups, Plan *lefttree); extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount); /* @@ -73,31 +65,32 @@ extern int from_collapse_limit; extern int join_collapse_limit; extern void add_base_rels_to_query(PlannerInfo *root, Node *jtnode); +extern void add_other_rels_to_query(PlannerInfo *root); extern void build_base_rel_tlists(PlannerInfo *root, List *final_tlist); extern void add_vars_to_targetlist(PlannerInfo *root, List *vars, - Relids where_needed, bool create_new_ph); + Relids where_needed, bool create_new_ph); extern void find_lateral_references(PlannerInfo *root); extern void create_lateral_join_info(PlannerInfo *root); extern List *deconstruct_jointree(PlannerInfo *root); extern void distribute_restrictinfo_to_rels(PlannerInfo *root, - RestrictInfo *restrictinfo); + RestrictInfo *restrictinfo); extern void process_implied_equality(PlannerInfo *root, - Oid opno, - Oid collation, - Expr *item1, - Expr *item2, - Relids qualscope, - Relids nullable_relids, - Index security_level, - bool below_outer_join, - bool both_const); + Oid opno, + Oid collation, + Expr *item1, + Expr *item2, + Relids qualscope, + Relids nullable_relids, + Index security_level, + bool below_outer_join, + bool both_const); extern RestrictInfo *build_implied_join_equality(Oid opno, - Oid collation, - Expr *item1, - Expr *item2, - Relids qualscope, - Relids nullable_relids, - Index security_level); + Oid collation, + Expr *item1, + Expr *item2, + Relids qualscope, + Relids nullable_relids, + Index security_level); extern void match_foreign_keys_to_quals(PlannerInfo *root); /* @@ -108,17 +101,15 @@ extern void reduce_unique_semijoins(PlannerInfo *root); extern bool query_supports_distinctness(Query *query); extern bool query_is_distinct_for(Query *query, List *colnos, List *opids); extern bool innerrel_is_unique(PlannerInfo *root, - Relids outerrelids, RelOptInfo *innerrel, - JoinType jointype, List *restrictlist, bool force_cache); + Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, + JoinType jointype, List *restrictlist, bool force_cache); /* * prototypes for plan/setrefs.c */ extern Plan *set_plan_references(PlannerInfo *root, Plan *plan); extern void record_plan_function_dependency(PlannerInfo *root, Oid funcid); -extern void extract_query_dependencies(Node *query, - List **relationOids, - List **invalItems, - bool *hasRowSecurity); +extern void record_plan_type_dependency(PlannerInfo *root, Oid typid); +extern bool extract_query_dependencies_walker(Node *node, PlannerInfo *root); #endif /* PLANMAIN_H */ diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index c090396e139..8d30b942150 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -3,8 +3,12 @@ * planner.h * prototypes for planner.c. * + * Note that the primary entry points for planner.c are declared in + * optimizer/optimizer.h, because they're intended to be called from + * non-planner code. Declarations here are meant for use by other + * planner modules. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/planner.h @@ -14,8 +18,8 @@ #ifndef PLANNER_H #define PLANNER_H +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" /* Hook for plugins to get control in planner() */ @@ -33,30 +37,23 @@ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; -extern PlannedStmt *planner(Query *parse, int cursorOptions, - ParamListInfo boundParams); extern PlannedStmt *standard_planner(Query *parse, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams); extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse, - PlannerInfo *parent_root, - bool hasRecursion, double tuple_fraction); - -extern bool is_dummy_plan(Plan *plan); + PlannerInfo *parent_root, + bool hasRecursion, double tuple_fraction); extern RowMarkType select_rowmark_type(RangeTblEntry *rte, - LockClauseStrength strength); + LockClauseStrength strength); + +extern bool limit_needed(Query *parse); extern void mark_partial_aggref(Aggref *agg, AggSplit aggsplit); extern Path *get_cheapest_fractional_path(RelOptInfo *rel, - double tuple_fraction); - -extern Expr *expression_planner(Expr *expr); + double tuple_fraction); extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr); -extern bool plan_cluster_use_sort(Oid tableOid, Oid indexOid); -extern int plan_create_index_workers(Oid tableOid, Oid indexOid); - #endif /* PLANNER_H */ diff --git a/src/include/optimizer/predtest.h b/src/include/optimizer/predtest.h deleted file mode 100644 index 69d87ea5c57..00000000000 --- a/src/include/optimizer/predtest.h +++ /dev/null @@ -1,25 +0,0 @@ -/*------------------------------------------------------------------------- - * - * predtest.h - * prototypes for predtest.c - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/optimizer/predtest.h - * - *------------------------------------------------------------------------- - */ -#ifndef PREDTEST_H -#define PREDTEST_H - -#include "nodes/primnodes.h" - - -extern bool predicate_implied_by(List *predicate_list, List *clause_list, - bool weak); -extern bool predicate_refuted_by(List *predicate_list, List *clause_list, - bool weak); - -#endif /* PREDTEST_H */ diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h index 38608770a20..9018160d80b 100644 --- a/src/include/optimizer/prep.h +++ b/src/include/optimizer/prep.h @@ -4,7 +4,7 @@ * prototypes for files in optimizer/prep/ * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/prep.h @@ -14,26 +14,22 @@ #ifndef PREP_H #define PREP_H +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" /* * prototypes for prepjointree.c */ +extern void replace_empty_jointree(Query *parse); extern void pull_up_sublinks(PlannerInfo *root); -extern void inline_set_returning_functions(PlannerInfo *root); +extern void preprocess_function_rtes(PlannerInfo *root); extern void pull_up_subqueries(PlannerInfo *root); extern void flatten_simple_union_all(PlannerInfo *root); extern void reduce_outer_joins(PlannerInfo *root); +extern void remove_useless_result_rtes(PlannerInfo *root); extern Relids get_relids_in_jointree(Node *jtnode, bool include_joins); -extern Relids get_relids_for_join(PlannerInfo *root, int joinrelid); - -/* - * prototypes for prepqual.c - */ -extern Node *negate_clause(Node *node); -extern Expr *canonicalize_qual(Expr *qual, bool is_check); +extern Relids get_relids_for_join(Query *query, int joinrelid); /* * prototypes for preptlist.c @@ -47,22 +43,4 @@ extern PlanRowMark *get_plan_rowmark(List *rowmarks, Index rtindex); */ extern RelOptInfo *plan_set_operations(PlannerInfo *root); -extern void expand_inherited_tables(PlannerInfo *root); - -extern Node *adjust_appendrel_attrs(PlannerInfo *root, Node *node, - int nappinfos, AppendRelInfo **appinfos); - -extern Node *adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, - Relids child_relids, - Relids top_parent_relids); - -extern AppendRelInfo **find_appinfos_by_relids(PlannerInfo *root, - Relids relids, int *nappinfos); - -extern SpecialJoinInfo *build_child_join_sjinfo(PlannerInfo *root, - SpecialJoinInfo *parent_sjinfo, - Relids left_relids, Relids right_relids); -extern Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, - Relids child_relids, Relids top_parent_relids); - #endif /* PREP_H */ diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h index 9cd874d07ed..0fe92ad4282 100644 --- a/src/include/optimizer/restrictinfo.h +++ b/src/include/optimizer/restrictinfo.h @@ -4,7 +4,7 @@ * prototypes for restrictinfo.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/restrictinfo.h @@ -14,7 +14,7 @@ #ifndef RESTRICTINFO_H #define RESTRICTINFO_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" /* Convenience macro for the common case of a valid-everywhere qual */ @@ -22,25 +22,27 @@ make_restrictinfo(clause, true, false, false, 0, NULL, NULL, NULL) extern RestrictInfo *make_restrictinfo(Expr *clause, - bool is_pushed_down, - bool outerjoin_delayed, - bool pseudoconstant, - Index security_level, - Relids required_relids, - Relids outer_relids, - Relids nullable_relids); + bool is_pushed_down, + bool outerjoin_delayed, + bool pseudoconstant, + Index security_level, + Relids required_relids, + Relids outer_relids, + Relids nullable_relids); +extern RestrictInfo *commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op); extern bool restriction_is_or_clause(RestrictInfo *restrictinfo); extern bool restriction_is_securely_promotable(RestrictInfo *restrictinfo, - RelOptInfo *rel); + RelOptInfo *rel); extern List *get_actual_clauses(List *restrictinfo_list); extern List *extract_actual_clauses(List *restrictinfo_list, - bool pseudoconstant); + bool pseudoconstant); extern void extract_actual_join_clauses(List *restrictinfo_list, - List **joinquals, - List **otherquals); + Relids joinrelids, + List **joinquals, + List **otherquals); extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel); extern bool join_clause_is_movable_into(RestrictInfo *rinfo, - Relids currentrelids, - Relids current_and_outer); + Relids currentrelids, + Relids current_and_outer); #endif /* RESTRICTINFO_H */ diff --git a/src/include/optimizer/subselect.h b/src/include/optimizer/subselect.h index d28c993b3a0..71a22eeb647 100644 --- a/src/include/optimizer/subselect.h +++ b/src/include/optimizer/subselect.h @@ -1,8 +1,9 @@ /*------------------------------------------------------------------------- * * subselect.h + * Planning routines for subselects. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/subselect.h @@ -12,17 +13,17 @@ #ifndef SUBSELECT_H #define SUBSELECT_H +#include "nodes/pathnodes.h" #include "nodes/plannodes.h" -#include "nodes/relation.h" extern void SS_process_ctes(PlannerInfo *root); extern JoinExpr *convert_ANY_sublink_to_join(PlannerInfo *root, - SubLink *sublink, - Relids available_rels); + SubLink *sublink, + Relids available_rels); extern JoinExpr *convert_EXISTS_sublink_to_join(PlannerInfo *root, - SubLink *sublink, - bool under_not, - Relids available_rels); + SubLink *sublink, + bool under_not, + Relids available_rels); extern Node *SS_replace_correlation_vars(PlannerInfo *root, Node *expr); extern Node *SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual); extern void SS_identify_outer_params(PlannerInfo *root); @@ -30,14 +31,10 @@ extern void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel); extern void SS_attach_initplans(PlannerInfo *root, Plan *plan); extern void SS_finalize_plan(PlannerInfo *root, Plan *plan); extern Param *SS_make_initplan_output_param(PlannerInfo *root, - Oid resulttype, int32 resulttypmod, - Oid resultcollation); + Oid resulttype, int32 resulttypmod, + Oid resultcollation); extern void SS_make_initplan_from_plan(PlannerInfo *root, - PlannerInfo *subroot, Plan *plan, - Param *prm); -extern Param *assign_nestloop_param_var(PlannerInfo *root, Var *var); -extern Param *assign_nestloop_param_placeholdervar(PlannerInfo *root, - PlaceHolderVar *phv); -extern int SS_assign_special_param(PlannerInfo *root); + PlannerInfo *subroot, Plan *plan, + Param *prm); #endif /* SUBSELECT_H */ diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h index 9fa52e1278f..8a2378f968d 100644 --- a/src/include/optimizer/tlist.h +++ b/src/include/optimizer/tlist.h @@ -4,7 +4,7 @@ * prototypes for tlist.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/optimizer/tlist.h @@ -14,7 +14,7 @@ #ifndef TLIST_H #define TLIST_H -#include "nodes/relation.h" +#include "nodes/pathnodes.h" extern TargetEntry *tlist_member(Expr *node, List *targetlist); @@ -24,8 +24,6 @@ extern List *add_to_flat_tlist(List *tlist, List *exprs); extern List *get_tlist_exprs(List *tlist, bool includeJunk); -extern int count_nonjunk_tlist_entries(List *tlist); - extern bool tlist_same_exprs(List *tlist1, List *tlist2); extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK); @@ -33,21 +31,8 @@ extern bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK) extern void apply_tlist_labeling(List *dest_tlist, List *src_tlist); -extern TargetEntry *get_sortgroupref_tle(Index sortref, - List *targetList); -extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause, - List *targetList); -extern Node *get_sortgroupclause_expr(SortGroupClause *sgClause, - List *targetList); -extern List *get_sortgrouplist_exprs(List *sgClauses, - List *targetList); - -extern SortGroupClause *get_sortgroupref_clause(Index sortref, - List *clauses); -extern SortGroupClause *get_sortgroupref_clause_noerr(Index sortref, - List *clauses); - extern Oid *extract_grouping_ops(List *groupClause); +extern Oid *extract_grouping_collations(List *groupClause, List *tlist); extern AttrNumber *extract_grouping_cols(List *groupClause, List *tlist); extern bool grouping_is_sortable(List *groupClause); extern bool grouping_is_hashable(List *groupClause); @@ -57,13 +42,13 @@ extern List *make_tlist_from_pathtarget(PathTarget *target); extern PathTarget *copy_pathtarget(PathTarget *src); extern PathTarget *create_empty_pathtarget(void); extern void add_column_to_pathtarget(PathTarget *target, - Expr *expr, Index sortgroupref); + Expr *expr, Index sortgroupref); extern void add_new_column_to_pathtarget(PathTarget *target, Expr *expr); extern void add_new_columns_to_pathtarget(PathTarget *target, List *exprs); extern void apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target); extern void split_pathtarget_at_srfs(PlannerInfo *root, - PathTarget *target, PathTarget *input_target, - List **targets, List **targets_contain_srfs); + PathTarget *target, PathTarget *input_target, + List **targets, List **targets_contain_srfs); /* Convenience macro to get a PathTarget with valid cost/width fields */ #define create_pathtarget(root, tlist) \ diff --git a/src/include/optimizer/var.h b/src/include/optimizer/var.h deleted file mode 100644 index 43c53b53445..00000000000 --- a/src/include/optimizer/var.h +++ /dev/null @@ -1,40 +0,0 @@ -/*------------------------------------------------------------------------- - * - * var.h - * prototypes for optimizer/util/var.c. - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/optimizer/var.h - * - *------------------------------------------------------------------------- - */ -#ifndef VAR_H -#define VAR_H - -#include "nodes/relation.h" - -/* Bits that can be OR'd into the flags argument of pull_var_clause() */ -#define PVC_INCLUDE_AGGREGATES 0x0001 /* include Aggrefs in output list */ -#define PVC_RECURSE_AGGREGATES 0x0002 /* recurse into Aggref arguments */ -#define PVC_INCLUDE_WINDOWFUNCS 0x0004 /* include WindowFuncs in output list */ -#define PVC_RECURSE_WINDOWFUNCS 0x0008 /* recurse into WindowFunc arguments */ -#define PVC_INCLUDE_PLACEHOLDERS 0x0010 /* include PlaceHolderVars in - * output list */ -#define PVC_RECURSE_PLACEHOLDERS 0x0020 /* recurse into PlaceHolderVar - * arguments */ - - -extern Relids pull_varnos(Node *node); -extern Relids pull_varnos_of_level(Node *node, int levelsup); -extern void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos); -extern List *pull_vars_of_level(Node *node, int levelsup); -extern bool contain_var_clause(Node *node); -extern bool contain_vars_of_level(Node *node, int levelsup); -extern int locate_var_of_level(Node *node, int levelsup); -extern List *pull_var_clause(Node *node, int flags); -extern Node *flatten_join_alias_vars(PlannerInfo *root, Node *node); - -#endif /* VAR_H */ diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h index 41fb10666e5..cb1d96bc35d 100644 --- a/src/include/parser/analyze.h +++ b/src/include/parser/analyze.h @@ -4,7 +4,7 @@ * parse analysis for optimizable statements * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/analyze.h @@ -23,20 +23,15 @@ extern PGDLLIMPORT post_parse_analyze_hook_type post_parse_analyze_hook; extern Query *parse_analyze(RawStmt *parseTree, const char *sourceText, - Oid *paramTypes, int numParams, QueryEnvironment *queryEnv); + Oid *paramTypes, int numParams, QueryEnvironment *queryEnv); extern Query *parse_analyze_varparams(RawStmt *parseTree, const char *sourceText, - Oid **paramTypes, int *numParams); + Oid **paramTypes, int *numParams); extern Query *parse_sub_analyze(Node *parseTree, ParseState *parentParseState, - CommonTableExpr *parentCTE, - bool locked_from_parent, - bool resolve_unknowns); - -extern List *transformInsertRow(ParseState *pstate, List *exprlist, - List *stmtcols, List *icolumns, List *attrnos, - bool strip_indirection); -extern List *transformUpdateTargetList(ParseState *pstate, - List *targetList); + CommonTableExpr *parentCTE, + bool locked_from_parent, + bool resolve_unknowns); + extern Query *transformTopLevelStmt(ParseState *pstate, RawStmt *parseTree); extern Query *transformStmt(ParseState *pstate, Node *parseTree); @@ -45,7 +40,10 @@ extern bool analyze_requires_snapshot(RawStmt *parseTree); extern const char *LCS_asString(LockClauseStrength strength); extern void CheckSelectLocking(Query *qry, LockClauseStrength strength); extern void applyLockingClause(Query *qry, Index rtindex, - LockClauseStrength strength, - LockWaitPolicy waitPolicy, bool pushedDown); + LockClauseStrength strength, + LockWaitPolicy waitPolicy, bool pushedDown); + +extern List *BuildOnConflictExcludedTargetlist(Relation targetrel, + Index exclRelIndex); #endif /* ANALYZE_H */ diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h index 42e7edee6d3..add64bc170f 100644 --- a/src/include/parser/gramparse.h +++ b/src/include/parser/gramparse.h @@ -8,7 +8,7 @@ * Definitions that are needed outside the core parser should be in parser.h. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/gramparse.h @@ -65,8 +65,8 @@ typedef struct base_yy_extra_type /* from parser.c */ -extern int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, - core_yyscan_t yyscanner); +extern int base_yylex(YYSTYPE *lvalp, YYLTYPE *llocp, + core_yyscan_t yyscanner); /* from gram.y */ extern void parser_init(base_yy_extra_type *yyext); diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 81f758afbf0..00ace8425e2 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -2,12 +2,12 @@ * * kwlist.h * - * The keyword list is kept in its own source file for possible use by + * The keyword lists are kept in their own source files for use by * automatic tools. The exact representation of a keyword is determined * by the PG_KEYWORD macro, which is not defined in this file; it can * be defined by the caller for special purposes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -21,8 +21,7 @@ /* * List of keyword (name, token-value, category) entries. * - * !!WARNING!!: This list must be sorted by ASCII name, because binary - * search is used to locate entries. + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. */ /* name, value, category */ @@ -245,10 +244,8 @@ PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD) PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD) PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD) PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD) -PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD) PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD) PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD) -PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD) PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD) PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD) PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD) @@ -386,10 +383,12 @@ PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD) PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD) PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD) PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD) +PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD) PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD) PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD) PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD) PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD) +PG_KEYWORD("support", SUPPORT, UNRESERVED_KEYWORD) PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD) PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD) PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD) diff --git a/src/include/parser/parse_agg.h b/src/include/parser/parse_agg.h index 0e6adffe57f..102f266d6c9 100644 --- a/src/include/parser/parse_agg.h +++ b/src/include/parser/parse_agg.h @@ -3,7 +3,7 @@ * parse_agg.h * handle aggregates and window functions in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_agg.h @@ -16,13 +16,13 @@ #include "parser/parse_node.h" extern void transformAggregateCall(ParseState *pstate, Aggref *agg, - List *args, List *aggorder, - bool agg_distinct); + List *args, List *aggorder, + bool agg_distinct); extern Node *transformGroupingFunc(ParseState *pstate, GroupingFunc *g); extern void transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc, - WindowDef *windef); + WindowDef *windef); extern void parseCheckAggregates(ParseState *pstate, Query *qry); @@ -30,39 +30,39 @@ extern List *expand_grouping_sets(List *groupingSets, int limit); extern int get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes); -extern Oid resolve_aggregate_transtype(Oid aggfuncid, - Oid aggtranstype, - Oid *inputTypes, - int numArguments); +extern Oid resolve_aggregate_transtype(Oid aggfuncid, + Oid aggtranstype, + Oid *inputTypes, + int numArguments); extern void build_aggregate_transfn_expr(Oid *agg_input_types, - int agg_num_inputs, - int agg_num_direct_inputs, - bool agg_variadic, - Oid agg_state_type, - Oid agg_input_collation, - Oid transfn_oid, - Oid invtransfn_oid, - Expr **transfnexpr, - Expr **invtransfnexpr); + int agg_num_inputs, + int agg_num_direct_inputs, + bool agg_variadic, + Oid agg_state_type, + Oid agg_input_collation, + Oid transfn_oid, + Oid invtransfn_oid, + Expr **transfnexpr, + Expr **invtransfnexpr); extern void build_aggregate_combinefn_expr(Oid agg_state_type, - Oid agg_input_collation, - Oid combinefn_oid, - Expr **combinefnexpr); + Oid agg_input_collation, + Oid combinefn_oid, + Expr **combinefnexpr); extern void build_aggregate_serialfn_expr(Oid serialfn_oid, - Expr **serialfnexpr); + Expr **serialfnexpr); extern void build_aggregate_deserialfn_expr(Oid deserialfn_oid, - Expr **deserialfnexpr); + Expr **deserialfnexpr); extern void build_aggregate_finalfn_expr(Oid *agg_input_types, - int num_finalfn_inputs, - Oid agg_state_type, - Oid agg_result_type, - Oid agg_input_collation, - Oid finalfn_oid, - Expr **finalfnexpr); + int num_finalfn_inputs, + Oid agg_state_type, + Oid agg_result_type, + Oid agg_input_collation, + Oid finalfn_oid, + Expr **finalfnexpr); #endif /* PARSE_AGG_H */ diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index 4420e720708..42adc63d1fc 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -4,7 +4,7 @@ * handle clauses in parser * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_clause.h @@ -17,40 +17,36 @@ #include "parser/parse_node.h" extern void transformFromClause(ParseState *pstate, List *frmList); -extern int setTargetTable(ParseState *pstate, RangeVar *relation, - bool inh, bool alsoSource, AclMode requiredPerms); -extern bool interpretOidsOption(List *defList, bool allowOids); -extern Node *transformFromClauseItem(ParseState *pstate, Node *n, - RangeTblEntry **top_rte, int *top_rti, - RangeTblEntry **right_rte, int *right_rti, - List **fnamespace); +extern int setTargetTable(ParseState *pstate, RangeVar *relation, + bool inh, bool alsoSource, AclMode requiredPerms); + extern Node *transformWhereClause(ParseState *pstate, Node *clause, - ParseExprKind exprKind, const char *constructName); + ParseExprKind exprKind, const char *constructName); extern Node *transformLimitClause(ParseState *pstate, Node *clause, - ParseExprKind exprKind, const char *constructName); + ParseExprKind exprKind, const char *constructName); extern List *transformGroupClause(ParseState *pstate, List *grouplist, - List **groupingSets, - List **targetlist, List *sortClause, - ParseExprKind exprKind, bool useSQL99); + List **groupingSets, + List **targetlist, List *sortClause, + ParseExprKind exprKind, bool useSQL99); extern List *transformSortClause(ParseState *pstate, List *orderlist, - List **targetlist, ParseExprKind exprKind, - bool useSQL99); + List **targetlist, ParseExprKind exprKind, + bool useSQL99); extern List *transformWindowDefinitions(ParseState *pstate, - List *windowdefs, - List **targetlist); + List *windowdefs, + List **targetlist); extern List *transformDistinctClause(ParseState *pstate, - List **targetlist, List *sortClause, bool is_agg); + List **targetlist, List *sortClause, bool is_agg); extern List *transformDistinctOnClause(ParseState *pstate, List *distinctlist, - List **targetlist, List *sortClause); + List **targetlist, List *sortClause); extern void transformOnConflictArbiter(ParseState *pstate, - OnConflictClause *onConflictClause, - List **arbiterExpr, Node **arbiterWhere, - Oid *constraint); + OnConflictClause *onConflictClause, + List **arbiterExpr, Node **arbiterWhere, + Oid *constraint); extern List *addTargetToSortList(ParseState *pstate, TargetEntry *tle, - List *sortlist, List *targetlist, SortBy *sortby); + List *sortlist, List *targetlist, SortBy *sortby); extern Index assignSortGroupRef(TargetEntry *tle, List *tlist); extern bool targetIsInSortList(TargetEntry *tle, Oid sortop, List *sortList); diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index af12c136efa..37d73ae2cc6 100644 --- a/src/include/parser/parse_coerce.h +++ b/src/include/parser/parse_coerce.h @@ -4,7 +4,7 @@ * Routines for type coercion. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_coerce.h @@ -36,58 +36,58 @@ extern bool IsPreferredType(TYPCATEGORY category, Oid type); extern TYPCATEGORY TypeCategory(Oid type); extern Node *coerce_to_target_type(ParseState *pstate, - Node *expr, Oid exprtype, - Oid targettype, int32 targettypmod, - CoercionContext ccontext, - CoercionForm cformat, - int location); -extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids, - CoercionContext ccontext); + Node *expr, Oid exprtype, + Oid targettype, int32 targettypmod, + CoercionContext ccontext, + CoercionForm cformat, + int location); +extern bool can_coerce_type(int nargs, const Oid *input_typeids, const Oid *target_typeids, + CoercionContext ccontext); extern Node *coerce_type(ParseState *pstate, Node *node, - Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, - CoercionContext ccontext, CoercionForm cformat, int location); + Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod, + CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, - Oid typeId, - CoercionContext ccontext, CoercionForm cformat, int location, - bool hideInputCoercion); + Oid typeId, + CoercionContext ccontext, CoercionForm cformat, int location, + bool hideInputCoercion); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, - const char *constructName); + const char *constructName); extern Node *coerce_to_specific_type(ParseState *pstate, Node *node, - Oid targetTypeId, - const char *constructName); + Oid targetTypeId, + const char *constructName); extern Node *coerce_to_specific_type_typmod(ParseState *pstate, Node *node, - Oid targetTypeId, int32 targetTypmod, - const char *constructName); + Oid targetTypeId, int32 targetTypmod, + const char *constructName); -extern int parser_coercion_errposition(ParseState *pstate, - int coerce_location, - Node *input_expr); +extern int parser_coercion_errposition(ParseState *pstate, + int coerce_location, + Node *input_expr); -extern Oid select_common_type(ParseState *pstate, List *exprs, - const char *context, Node **which_expr); +extern Oid select_common_type(ParseState *pstate, List *exprs, + const char *context, Node **which_expr); extern Node *coerce_to_common_type(ParseState *pstate, Node *node, - Oid targetTypeId, - const char *context); + Oid targetTypeId, + const char *context); -extern bool check_generic_type_consistency(Oid *actual_arg_types, - Oid *declared_arg_types, - int nargs); -extern Oid enforce_generic_type_consistency(Oid *actual_arg_types, - Oid *declared_arg_types, - int nargs, - Oid rettype, - bool allow_poly); -extern Oid resolve_generic_type(Oid declared_type, - Oid context_actual_type, - Oid context_declared_type); +extern bool check_generic_type_consistency(const Oid *actual_arg_types, + const Oid *declared_arg_types, + int nargs); +extern Oid enforce_generic_type_consistency(const Oid *actual_arg_types, + Oid *declared_arg_types, + int nargs, + Oid rettype, + bool allow_poly); +extern Oid resolve_generic_type(Oid declared_type, + Oid context_actual_type, + Oid context_declared_type); extern CoercionPathType find_coercion_pathway(Oid targetTypeId, - Oid sourceTypeId, - CoercionContext ccontext, - Oid *funcid); + Oid sourceTypeId, + CoercionContext ccontext, + Oid *funcid); extern CoercionPathType find_typmod_coercion_function(Oid typeId, - Oid *funcid); + Oid *funcid); #endif /* PARSE_COERCE_H */ diff --git a/src/include/parser/parse_collate.h b/src/include/parser/parse_collate.h index aea297ce38c..180d96b9b2f 100644 --- a/src/include/parser/parse_collate.h +++ b/src/include/parser/parse_collate.h @@ -4,7 +4,7 @@ * Routines for assigning collation information. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_collate.h diff --git a/src/include/parser/parse_cte.h b/src/include/parser/parse_cte.h index 7e862d19065..0d4ce3608dc 100644 --- a/src/include/parser/parse_cte.h +++ b/src/include/parser/parse_cte.h @@ -4,7 +4,7 @@ * handle CTEs (common table expressions) in parser * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_cte.h @@ -19,6 +19,6 @@ extern List *transformWithClause(ParseState *pstate, WithClause *withClause); extern void analyzeCTETargetList(ParseState *pstate, CommonTableExpr *cte, - List *tlist); + List *tlist); #endif /* PARSE_CTE_H */ diff --git a/src/include/parser/parse_enr.h b/src/include/parser/parse_enr.h index e8af457e02e..b8eff5c0d4b 100644 --- a/src/include/parser/parse_enr.h +++ b/src/include/parser/parse_enr.h @@ -4,7 +4,7 @@ * Internal definitions for parser * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_enr.h diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index e5aff61b8f3..bb1f8770d8d 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -3,7 +3,7 @@ * parse_expr.h * handle expressions in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_expr.h diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h index 2e3810fc32f..5a3b287eaf0 100644 --- a/src/include/parser/parse_func.h +++ b/src/include/parser/parse_func.h @@ -4,15 +4,15 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_func.h * *------------------------------------------------------------------------- */ -#ifndef PARSER_FUNC_H -#define PARSER_FUNC_H +#ifndef PARSE_FUNC_H +#define PARSE_FUNC_H #include "catalog/namespace.h" #include "parser/parse_node.h" @@ -36,38 +36,38 @@ extern Node *ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, int location); extern FuncDetailCode func_get_detail(List *funcname, - List *fargs, List *fargnames, - int nargs, Oid *argtypes, - bool expand_variadic, bool expand_defaults, - Oid *funcid, Oid *rettype, - bool *retset, int *nvargs, Oid *vatype, - Oid **true_typeids, List **argdefaults); + List *fargs, List *fargnames, + int nargs, Oid *argtypes, + bool expand_variadic, bool expand_defaults, + Oid *funcid, Oid *rettype, + bool *retset, int *nvargs, Oid *vatype, + Oid **true_typeids, List **argdefaults); -extern int func_match_argtypes(int nargs, - Oid *input_typeids, - FuncCandidateList raw_candidates, - FuncCandidateList *candidates); +extern int func_match_argtypes(int nargs, + Oid *input_typeids, + FuncCandidateList raw_candidates, + FuncCandidateList *candidates); extern FuncCandidateList func_select_candidate(int nargs, - Oid *input_typeids, - FuncCandidateList candidates); + Oid *input_typeids, + FuncCandidateList candidates); extern void make_fn_arguments(ParseState *pstate, - List *fargs, - Oid *actual_arg_types, - Oid *declared_arg_types); + List *fargs, + Oid *actual_arg_types, + Oid *declared_arg_types); extern const char *funcname_signature_string(const char *funcname, int nargs, - List *argnames, const Oid *argtypes); + List *argnames, const Oid *argtypes); extern const char *func_signature_string(List *funcname, int nargs, - List *argnames, const Oid *argtypes); + List *argnames, const Oid *argtypes); -extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, - bool noError); -extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, - bool noError); +extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes, + bool missing_ok); +extern Oid LookupFuncWithArgs(ObjectType objtype, ObjectWithArgs *func, + bool missing_ok); extern void check_srf_call_placement(ParseState *pstate, Node *last_srf, - int location); + int location); #endif /* PARSE_FUNC_H */ diff --git a/src/include/parser/parse_merge.h b/src/include/parser/parse_merge.h deleted file mode 100644 index 0151809e09b..00000000000 --- a/src/include/parser/parse_merge.h +++ /dev/null @@ -1,19 +0,0 @@ -/*------------------------------------------------------------------------- - * - * parse_merge.h - * handle merge-stmt in parser - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/parser/parse_merge.h - * - *------------------------------------------------------------------------- - */ -#ifndef PARSE_MERGE_H -#define PARSE_MERGE_H - -#include "parser/parse_node.h" -extern Query *transformMergeStmt(ParseState *pstate, MergeStmt *stmt); -#endif diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index 3fd2151ccbe..7c099e70845 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -4,7 +4,7 @@ * Internal definitions for parser * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_node.h @@ -50,7 +50,6 @@ typedef enum ParseExprKind EXPR_KIND_INSERT_TARGET, /* INSERT target list item */ EXPR_KIND_UPDATE_SOURCE, /* UPDATE assignment source item */ EXPR_KIND_UPDATE_TARGET, /* UPDATE assignment target item */ - EXPR_KIND_MERGE_WHEN_AND, /* MERGE WHEN ... AND condition */ EXPR_KIND_GROUP_BY, /* GROUP BY */ EXPR_KIND_ORDER_BY, /* ORDER BY */ EXPR_KIND_DISTINCT_ON, /* DISTINCT ON */ @@ -69,8 +68,11 @@ typedef enum ParseExprKind EXPR_KIND_EXECUTE_PARAMETER, /* parameter value in EXECUTE */ EXPR_KIND_TRIGGER_WHEN, /* WHEN condition in CREATE TRIGGER */ EXPR_KIND_POLICY, /* USING or WITH CHECK expr in policy */ + EXPR_KIND_PARTITION_BOUND, /* partition bound expression */ EXPR_KIND_PARTITION_EXPRESSION, /* PARTITION BY expression */ - EXPR_KIND_CALL_ARGUMENT /* procedure argument in CALL */ + EXPR_KIND_CALL_ARGUMENT, /* procedure argument in CALL */ + EXPR_KIND_COPY_WHERE, /* WHERE condition in COPY FROM */ + EXPR_KIND_GENERATED_COLUMN, /* generation expression for a column */ } ParseExprKind; @@ -128,7 +130,7 @@ typedef Node *(*CoerceParamHook) (ParseState *pstate, Param *param, * p_parent_cte: CommonTableExpr that immediately contains the current query, * if any. * - * p_target_relation: target relation, if query is INSERT/UPDATE/DELETE/MERGE + * p_target_relation: target relation, if query is INSERT, UPDATE, or DELETE. * * p_target_rangetblentry: target relation's entry in the rtable list. * @@ -182,7 +184,7 @@ struct ParseState List *p_ctenamespace; /* current namespace for common table exprs */ List *p_future_ctes; /* common table exprs not yet in namespace */ CommonTableExpr *p_parent_cte; /* this query's containing CTE */ - Relation p_target_relation; /* INSERT/UPDATE/DELETE/MERGE target rel */ + Relation p_target_relation; /* INSERT/UPDATE/DELETE target rel */ RangeTblEntry *p_target_rangetblentry; /* target rel's RTE */ bool p_is_insert; /* process assignment like INSERT not UPDATE */ List *p_windowdefs; /* raw representations of window clauses */ @@ -267,19 +269,20 @@ extern void free_parsestate(ParseState *pstate); extern int parser_errposition(ParseState *pstate, int location); extern void setup_parser_errposition_callback(ParseCallbackState *pcbstate, - ParseState *pstate, int location); + ParseState *pstate, int location); extern void cancel_parser_errposition_callback(ParseCallbackState *pcbstate); extern Var *make_var(ParseState *pstate, RangeTblEntry *rte, int attrno, - int location); -extern Oid transformArrayType(Oid *arrayType, int32 *arrayTypmod); -extern ArrayRef *transformArraySubscripts(ParseState *pstate, - Node *arrayBase, - Oid arrayType, - Oid elementType, - int32 arrayTypMod, - List *indirection, - Node *assignFrom); + int location); +extern Oid transformContainerType(Oid *containerType, int32 *containerTypmod); + +extern SubscriptingRef *transformContainerSubscripts(ParseState *pstate, + Node *containerBase, + Oid containerType, + Oid elementType, + int32 containerTypMod, + List *indirection, + Node *assignFrom); extern Const *make_const(ParseState *pstate, Value *value, int location); #endif /* PARSE_NODE_H */ diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h index da9cd3877c4..2265c25e4d3 100644 --- a/src/include/parser/parse_oper.h +++ b/src/include/parser/parse_oper.h @@ -4,7 +4,7 @@ * handle operator things for parser * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_oper.h @@ -22,33 +22,33 @@ typedef HeapTuple Operator; /* Routines to look up an operator given name and exact input type(s) */ -extern Oid LookupOperName(ParseState *pstate, List *opername, - Oid oprleft, Oid oprright, - bool noError, int location); +extern Oid LookupOperName(ParseState *pstate, List *opername, + Oid oprleft, Oid oprright, + bool noError, int location); extern Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError); /* Routines to find operators matching a name and given input types */ /* NB: the selected operator may require coercion of the input types! */ extern Operator oper(ParseState *pstate, List *op, Oid arg1, Oid arg2, - bool noError, int location); + bool noError, int location); extern Operator right_oper(ParseState *pstate, List *op, Oid arg, - bool noError, int location); + bool noError, int location); extern Operator left_oper(ParseState *pstate, List *op, Oid arg, - bool noError, int location); + bool noError, int location); /* Routines to find operators that DO NOT require coercion --- ie, their */ /* input types are either exactly as given, or binary-compatible */ extern Operator compatible_oper(ParseState *pstate, List *op, - Oid arg1, Oid arg2, - bool noError, int location); + Oid arg1, Oid arg2, + bool noError, int location); /* currently no need for compatible_left_oper/compatible_right_oper */ /* Routines for identifying "<", "=", ">" operators for a type */ extern void get_sort_group_operators(Oid argtype, - bool needLT, bool needEQ, bool needGT, - Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, - bool *isHashable); + bool needLT, bool needEQ, bool needGT, + Oid *ltOpr, Oid *eqOpr, Oid *gtOpr, + bool *isHashable); /* Convenience routines for common calls on the above */ extern Oid compatible_oper_opid(List *op, Oid arg1, Oid arg2, bool noError); @@ -59,9 +59,9 @@ extern Oid oprfuncid(Operator op); /* Build expression tree for an operator invocation */ extern Expr *make_op(ParseState *pstate, List *opname, - Node *ltree, Node *rtree, Node *last_srf, int location); + Node *ltree, Node *rtree, Node *last_srf, int location); extern Expr *make_scalar_array_op(ParseState *pstate, List *opname, - bool useOr, - Node *ltree, Node *rtree, int location); + bool useOr, + Node *ltree, Node *rtree, int location); #endif /* PARSE_OPER_H */ diff --git a/src/include/parser/parse_param.h b/src/include/parser/parse_param.h index fd6c695ebf9..acd9e50be38 100644 --- a/src/include/parser/parse_param.h +++ b/src/include/parser/parse_param.h @@ -3,7 +3,7 @@ * parse_param.h * handle parameters in parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_param.h @@ -16,9 +16,9 @@ #include "parser/parse_node.h" extern void parse_fixed_parameters(ParseState *pstate, - Oid *paramTypes, int numParams); + Oid *paramTypes, int numParams); extern void parse_variable_parameters(ParseState *pstate, - Oid **paramTypes, int *numParams); + Oid **paramTypes, int *numParams); extern void check_variable_parameters(ParseState *pstate, Query *query); extern bool query_contains_extern_params(Query *query); diff --git a/src/include/parser/parse_relation.h b/src/include/parser/parse_relation.h index b9792acdaea..f7e078172de 100644 --- a/src/include/parser/parse_relation.h +++ b/src/include/parser/parse_relation.h @@ -4,7 +4,7 @@ * prototypes for parse_relation.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_relation.h @@ -35,96 +35,97 @@ typedef struct extern RangeTblEntry *refnameRangeTblEntry(ParseState *pstate, - const char *schemaname, - const char *refname, - int location, - int *sublevels_up); + const char *schemaname, + const char *refname, + int location, + int *sublevels_up); extern CommonTableExpr *scanNameSpaceForCTE(ParseState *pstate, - const char *refname, - Index *ctelevelsup); + const char *refname, + Index *ctelevelsup); extern bool scanNameSpaceForENR(ParseState *pstate, const char *refname); extern void checkNameSpaceConflicts(ParseState *pstate, List *namespace1, - List *namespace2); -extern int RTERangeTablePosn(ParseState *pstate, - RangeTblEntry *rte, - int *sublevels_up); + List *namespace2); +extern int RTERangeTablePosn(ParseState *pstate, + RangeTblEntry *rte, + int *sublevels_up); extern RangeTblEntry *GetRTEByRangeTablePosn(ParseState *pstate, - int varno, - int sublevels_up); + int varno, + int sublevels_up); extern CommonTableExpr *GetCTEForRTE(ParseState *pstate, RangeTblEntry *rte, - int rtelevelsup); + int rtelevelsup); extern Node *scanRTEForColumn(ParseState *pstate, RangeTblEntry *rte, - const char *colname, int location, - int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate); + const char *colname, int location, + int fuzzy_rte_penalty, FuzzyAttrMatchState *fuzzystate); extern Node *colNameToVar(ParseState *pstate, const char *colname, bool localonly, - int location); + int location); extern void markVarForSelectPriv(ParseState *pstate, Var *var, - RangeTblEntry *rte); + RangeTblEntry *rte); extern Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, - int lockmode); + int lockmode); extern RangeTblEntry *addRangeTableEntry(ParseState *pstate, - RangeVar *relation, - Alias *alias, - bool inh, - bool inFromCl); + RangeVar *relation, + Alias *alias, + bool inh, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForRelation(ParseState *pstate, - Relation rel, - Alias *alias, - bool inh, - bool inFromCl); + Relation rel, + int lockmode, + Alias *alias, + bool inh, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForSubquery(ParseState *pstate, - Query *subquery, - Alias *alias, - bool lateral, - bool inFromCl); + Query *subquery, + Alias *alias, + bool lateral, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForFunction(ParseState *pstate, - List *funcnames, - List *funcexprs, - List *coldeflists, - RangeFunction *rangefunc, - bool lateral, - bool inFromCl); + List *funcnames, + List *funcexprs, + List *coldeflists, + RangeFunction *rangefunc, + bool lateral, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForValues(ParseState *pstate, - List *exprs, - List *coltypes, - List *coltypmods, - List *colcollations, - Alias *alias, - bool lateral, - bool inFromCl); + List *exprs, + List *coltypes, + List *coltypmods, + List *colcollations, + Alias *alias, + bool lateral, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForTableFunc(ParseState *pstate, - TableFunc *tf, - Alias *alias, - bool lateral, - bool inFromCl); + TableFunc *tf, + Alias *alias, + bool lateral, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForJoin(ParseState *pstate, - List *colnames, - JoinType jointype, - List *aliasvars, - Alias *alias, - bool inFromCl); + List *colnames, + JoinType jointype, + List *aliasvars, + Alias *alias, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForCTE(ParseState *pstate, - CommonTableExpr *cte, - Index levelsup, - RangeVar *rv, - bool inFromCl); + CommonTableExpr *cte, + Index levelsup, + RangeVar *rv, + bool inFromCl); extern RangeTblEntry *addRangeTableEntryForENR(ParseState *pstate, - RangeVar *rv, - bool inFromCl); + RangeVar *rv, + bool inFromCl); extern bool isLockedRefname(ParseState *pstate, const char *refname); extern void addRTEtoQuery(ParseState *pstate, RangeTblEntry *rte, - bool addToJoinList, - bool addToRelNameSpace, bool addToVarNameSpace); + bool addToJoinList, + bool addToRelNameSpace, bool addToVarNameSpace); extern void errorMissingRTE(ParseState *pstate, RangeVar *relation) pg_attribute_noreturn(); extern void errorMissingColumn(ParseState *pstate, - const char *relname, const char *colname, int location) pg_attribute_noreturn(); + const char *relname, const char *colname, int location) pg_attribute_noreturn(); extern void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, - int location, bool include_dropped, - List **colnames, List **colvars); + int location, bool include_dropped, + List **colnames, List **colvars); extern List *expandRelAttrs(ParseState *pstate, RangeTblEntry *rte, - int rtindex, int sublevels_up, int location); + int rtindex, int sublevels_up, int location); extern int attnameAttNum(Relation rd, const char *attname, bool sysColOK); -extern Name attnumAttName(Relation rd, int attid); +extern const NameData *attnumAttName(Relation rd, int attid); extern Oid attnumTypeId(Relation rd, int attid); extern Oid attnumCollationId(Relation rd, int attid); extern bool isQueryUsingTempRelation(Query *query); diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h index ec6e0c102ff..2052254cdd2 100644 --- a/src/include/parser/parse_target.h +++ b/src/include/parser/parse_target.h @@ -4,7 +4,7 @@ * handle target lists * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_target.h @@ -18,28 +18,28 @@ extern List *transformTargetList(ParseState *pstate, List *targetlist, - ParseExprKind exprKind); + ParseExprKind exprKind); extern List *transformExpressionList(ParseState *pstate, List *exprlist, - ParseExprKind exprKind, bool allowDefault); + ParseExprKind exprKind, bool allowDefault); extern void resolveTargetListUnknowns(ParseState *pstate, List *targetlist); extern void markTargetListOrigins(ParseState *pstate, List *targetlist); extern TargetEntry *transformTargetEntry(ParseState *pstate, - Node *node, Node *expr, ParseExprKind exprKind, - char *colname, bool resjunk); + Node *node, Node *expr, ParseExprKind exprKind, + char *colname, bool resjunk); extern Expr *transformAssignedExpr(ParseState *pstate, Expr *expr, - ParseExprKind exprKind, - const char *colname, - int attrno, - List *indirection, - int location); + ParseExprKind exprKind, + const char *colname, + int attrno, + List *indirection, + int location); extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle, - char *colname, int attrno, - List *indirection, - int location); + char *colname, int attrno, + List *indirection, + int location); extern List *checkInsertTargets(ParseState *pstate, List *cols, - List **attrnos); + List **attrnos); extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var, - int levelsup); + int levelsup); extern char *FigureColname(Node *node); extern char *FigureIndexColname(Node *node); diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index ab16737d570..b243c64383d 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -3,7 +3,7 @@ * parse_type.h * handle type operations for parser * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_type.h @@ -20,14 +20,17 @@ typedef HeapTuple Type; extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p, bool missing_ok); -extern Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, - bool missing_ok); + int32 *typmod_p, bool missing_ok); +extern Type LookupTypeNameExtended(ParseState *pstate, + const TypeName *typeName, int32 *typmod_p, + bool temp_ok, bool missing_ok); +extern Oid LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, + bool missing_ok); extern Type typenameType(ParseState *pstate, const TypeName *typeName, - int32 *typmod_p); + int32 *typmod_p); extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName); extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName, - Oid *typeid_p, int32 *typmod_p); + Oid *typeid_p, int32 *typmod_p); extern char *TypeNameToString(const TypeName *typeName); extern char *TypeNameListToString(List *typenames); diff --git a/src/include/parser/parse_utilcmd.h b/src/include/parser/parse_utilcmd.h index 35ac97940ad..1348064ad07 100644 --- a/src/include/parser/parse_utilcmd.h +++ b/src/include/parser/parse_utilcmd.h @@ -4,7 +4,7 @@ * parse analysis for utility commands * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parse_utilcmd.h @@ -19,17 +19,17 @@ extern List *transformCreateStmt(CreateStmt *stmt, const char *queryString); extern List *transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, - const char *queryString); + const char *queryString); extern IndexStmt *transformIndexStmt(Oid relid, IndexStmt *stmt, - const char *queryString); + const char *queryString); extern void transformRuleStmt(RuleStmt *stmt, const char *queryString, - List **actions, Node **whereClause); + List **actions, Node **whereClause); extern List *transformCreateSchemaStmt(CreateSchemaStmt *stmt); extern PartitionBoundSpec *transformPartitionBound(ParseState *pstate, Relation parent, - PartitionBoundSpec *spec); -extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel, Oid heapOid, - Relation source_idx, - const AttrNumber *attmap, int attmap_length, - Oid *constraintOid); + PartitionBoundSpec *spec); +extern IndexStmt *generateClonedIndexStmt(RangeVar *heapRel, + Relation source_idx, + const AttrNumber *attmap, int attmap_length, + Oid *constraintOid); #endif /* PARSE_UTILCMD_H */ diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index f26f6e22e12..6057dc16de9 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -5,7 +5,7 @@ * * This is the external API for the raw lexing/parsing functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parser.h diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h index dd9ae658ac7..cf47e107b9a 100644 --- a/src/include/parser/parsetree.h +++ b/src/include/parser/parsetree.h @@ -5,7 +5,7 @@ * parse trees. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/parsetree.h @@ -31,16 +31,6 @@ #define rt_fetch(rangetable_index, rangetable) \ ((RangeTblEntry *) list_nth(rangetable, (rangetable_index)-1)) -/* - * getrelid - * - * Given the range index of a relation, return the corresponding - * relation OID. Note that InvalidOid will be returned if the - * RTE is for a non-relation-type RTE. - */ -#define getrelid(rangeindex,rangetable) \ - (rt_fetch(rangeindex, rangetable)->relid) - /* * Given an RTE and an attribute number, return the appropriate * variable name or alias for that attribute of that RTE. @@ -52,14 +42,14 @@ extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); * type and typemod info for that attribute of that RTE. */ extern void get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum, - Oid *vartype, int32 *vartypmod, Oid *varcollid); + Oid *vartype, int32 *vartypmod, Oid *varcollid); /* * Check whether an attribute of an RTE has been dropped (note that * get_rte_attribute_type will fail on such an attr) */ extern bool get_rte_attribute_is_dropped(RangeTblEntry *rte, - AttrNumber attnum); + AttrNumber attnum); /* ---------------- diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h index 20bf1e66724..731a2bd264a 100644 --- a/src/include/parser/scanner.h +++ b/src/include/parser/scanner.h @@ -8,7 +8,7 @@ * higher-level API provided by parser.h. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scanner.h @@ -73,10 +73,10 @@ typedef struct core_yy_extra_type Size scanbuflen; /* - * The keyword list to use. + * The keyword list to use, and the associated grammar token codes. */ - const ScanKeyword *keywords; - int num_keywords; + const ScanKeywordList *keywordlist; + const uint16 *keyword_tokens; /* * Scanner settings to use. These are initialized from the corresponding @@ -116,14 +116,17 @@ typedef struct core_yy_extra_type typedef void *core_yyscan_t; +/* Constant data exported from parser/scan.l */ +extern PGDLLIMPORT const uint16 ScanKeywordTokens[]; + /* Entry points in parser/scan.l */ extern core_yyscan_t scanner_init(const char *str, - core_yy_extra_type *yyext, - const ScanKeyword *keywords, - int num_keywords); + core_yy_extra_type *yyext, + const ScanKeywordList *keywordlist, + const uint16 *keyword_tokens); extern void scanner_finish(core_yyscan_t yyscanner); -extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp, - core_yyscan_t yyscanner); +extern int core_yylex(core_YYSTYPE *lvalp, YYLTYPE *llocp, + core_yyscan_t yyscanner); extern int scanner_errposition(int location, core_yyscan_t yyscanner); extern void scanner_yyerror(const char *message, core_yyscan_t yyscanner) pg_attribute_noreturn(); diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h index 766b3f908a9..fb2980bd178 100644 --- a/src/include/parser/scansup.h +++ b/src/include/parser/scansup.h @@ -4,7 +4,7 @@ * scanner support routines. used by both the bootstrap lexer * as well as the normal lexer * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/parser/scansup.h @@ -18,10 +18,10 @@ extern char *scanstr(const char *s); extern char *downcase_truncate_identifier(const char *ident, int len, - bool warn); + bool warn); extern char *downcase_identifier(const char *ident, int len, - bool warn, bool truncate); + bool warn, bool truncate); extern void truncate_identifier(char *ident, int len, bool warn); diff --git a/src/include/partitioning/partbounds.h b/src/include/partitioning/partbounds.h index c76014d4a83..0d0fd42b181 100644 --- a/src/include/partitioning/partbounds.h +++ b/src/include/partitioning/partbounds.h @@ -2,7 +2,7 @@ * * partbounds.h * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/include/partitioning/partbounds.h * @@ -11,7 +11,11 @@ #ifndef PARTBOUNDS_H #define PARTBOUNDS_H -#include "catalog/partition.h" +#include "fmgr.h" +#include "nodes/parsenodes.h" +#include "nodes/pg_list.h" +#include "partitioning/partdefs.h" +#include "utils/relcache.h" /* @@ -52,7 +56,6 @@ * pointed by remainder produced when hash value of the datum-tuple is divided * by the greatest modulus. */ - typedef struct PartitionBoundInfoData { char strategy; /* hash, list or range? */ @@ -71,54 +74,39 @@ typedef struct PartitionBoundInfoData #define partition_bound_accepts_nulls(bi) ((bi)->null_index != -1) #define partition_bound_has_default(bi) ((bi)->default_index != -1) -/* - * When qsort'ing partition bounds after reading from the catalog, each bound - * is represented with one of the following structs. - */ - -/* One bound of a hash partition */ -typedef struct PartitionHashBound -{ - int modulus; - int remainder; - int index; -} PartitionHashBound; - -/* One value coming from some (index'th) list partition */ -typedef struct PartitionListValue -{ - int index; - Datum value; -} PartitionListValue; - -/* One bound of a range partition */ -typedef struct PartitionRangeBound -{ - int index; - Datum *datums; /* range bound datums */ - PartitionRangeDatumKind *kind; /* the kind of each datum */ - bool lower; /* this is the lower (vs upper) bound */ -} PartitionRangeBound; - extern int get_hash_partition_greatest_modulus(PartitionBoundInfo b); -extern int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, - PartitionBoundInfo boundinfo, - Datum value, bool *is_equal); -extern int partition_range_bsearch(int partnatts, FmgrInfo *partsupfunc, - Oid *partcollation, - PartitionBoundInfo boundinfo, - PartitionRangeBound *probe, bool *is_equal); -extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc, - Oid *partcollation, - PartitionBoundInfo boundinfo, - int nvalues, Datum *values, bool *is_equal); -extern int partition_hash_bsearch(PartitionBoundInfo boundinfo, - int modulus, int remainder); -extern uint64 compute_hash_value(int partnatts, FmgrInfo *partsupfunc, - Datum *values, bool *isnull); +extern uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, + Oid *partcollation, + Datum *values, bool *isnull); +extern List *get_qual_from_partbound(Relation rel, Relation parent, + PartitionBoundSpec *spec); +extern PartitionBoundInfo partition_bounds_create(PartitionBoundSpec **boundspecs, + int nparts, PartitionKey key, int **mapping); +extern bool partition_bounds_equal(int partnatts, int16 *parttyplen, + bool *parttypbyval, PartitionBoundInfo b1, + PartitionBoundInfo b2); +extern PartitionBoundInfo partition_bounds_copy(PartitionBoundInfo src, + PartitionKey key); +extern bool partitions_are_ordered(PartitionBoundInfo boundinfo, int nparts); +extern void check_new_partition_bound(char *relname, Relation parent, + PartitionBoundSpec *spec); +extern void check_default_partition_contents(Relation parent, + Relation defaultRel, + PartitionBoundSpec *new_spec); + extern int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, - Oid *partcollation, - Datum *rb_datums, PartitionRangeDatumKind *rb_kind, - Datum *tuple_datums, int n_tuple_datums); + Oid *partcollation, + Datum *rb_datums, PartitionRangeDatumKind *rb_kind, + Datum *tuple_datums, int n_tuple_datums); +extern int partition_list_bsearch(FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + Datum value, bool *is_equal); +extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc, + Oid *partcollation, + PartitionBoundInfo boundinfo, + int nvalues, Datum *values, bool *is_equal); +extern int partition_hash_bsearch(PartitionBoundInfo boundinfo, + int modulus, int remainder); #endif /* PARTBOUNDS_H */ diff --git a/src/include/partitioning/partdefs.h b/src/include/partitioning/partdefs.h new file mode 100644 index 00000000000..aec3b3fe63e --- /dev/null +++ b/src/include/partitioning/partdefs.h @@ -0,0 +1,26 @@ +/*------------------------------------------------------------------------- + * + * partdefs.h + * Base definitions for partitioned table handling + * + * Copyright (c) 2007-2019, PostgreSQL Global Development Group + * + * src/include/partitioning/partdefs.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTDEFS_H +#define PARTDEFS_H + + +typedef struct PartitionBoundInfoData *PartitionBoundInfo; + +typedef struct PartitionKeyData *PartitionKey; + +typedef struct PartitionBoundSpec PartitionBoundSpec; + +typedef struct PartitionDescData *PartitionDesc; + +typedef struct PartitionDirectoryData *PartitionDirectory; + +#endif /* PARTDEFS_H */ diff --git a/src/include/partitioning/partdesc.h b/src/include/partitioning/partdesc.h new file mode 100644 index 00000000000..38712c15501 --- /dev/null +++ b/src/include/partitioning/partdesc.h @@ -0,0 +1,43 @@ +/*------------------------------------------------------------------------- + * + * partdesc.h + * + * Copyright (c) 1996-2019, PostgreSQL Global Development Group + * + * src/include/utils/partdesc.h + * + *------------------------------------------------------------------------- + */ + +#ifndef PARTDESC_H +#define PARTDESC_H + +#include "partitioning/partdefs.h" +#include "utils/relcache.h" + +/* + * Information about partitions of a partitioned table. + */ +typedef struct PartitionDescData +{ + int nparts; /* Number of partitions */ + Oid *oids; /* Array of 'nparts' elements containing + * partition OIDs in order of the their bounds */ + bool *is_leaf; /* Array of 'nparts' elements storing whether + * the corresponding 'oids' element belongs to + * a leaf partition or not */ + PartitionBoundInfo boundinfo; /* collection of partition bounds */ +} PartitionDescData; + +extern void RelationBuildPartitionDesc(Relation rel); + +extern PartitionDirectory CreatePartitionDirectory(MemoryContext mcxt); +extern PartitionDesc PartitionDirectoryLookup(PartitionDirectory, Relation); +extern void DestroyPartitionDirectory(PartitionDirectory pdir); + +extern Oid get_default_oid_from_partdesc(PartitionDesc partdesc); + +extern bool equalPartitionDescs(PartitionKey key, PartitionDesc partdesc1, + PartitionDesc partdesc2); + +#endif /* PARTCACHE_H */ diff --git a/src/include/partitioning/partprune.h b/src/include/partitioning/partprune.h index 2ae2fd16ede..b3e926865ae 100644 --- a/src/include/partitioning/partprune.h +++ b/src/include/partitioning/partprune.h @@ -4,7 +4,7 @@ * prototypes for partprune.c * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/partitioning/partprune.h @@ -14,50 +14,67 @@ #ifndef PARTPRUNE_H #define PARTPRUNE_H -#include "catalog/partition.h" -#include "nodes/relation.h" +#include "nodes/execnodes.h" +#include "partitioning/partdefs.h" + +struct PlannerInfo; /* avoid including pathnodes.h here */ +struct RelOptInfo; + /* * PartitionPruneContext + * Stores information needed at runtime for pruning computations + * related to a single partitioned table. * - * Information about a partitioned table needed to perform partition pruning. + * strategy Partition strategy, e.g. LIST, RANGE, HASH. + * partnatts Number of columns in the partition key. + * nparts Number of partitions in this partitioned table. + * boundinfo Partition boundary info for the partitioned table. + * partcollation Array of partnatts elements, storing the collations of the + * partition key columns. + * partsupfunc Array of FmgrInfos for the comparison or hashing functions + * associated with the partition keys (partnatts elements). + * (This points into the partrel's partition key, typically.) + * stepcmpfuncs Array of FmgrInfos for the comparison or hashing function + * for each pruning step and partition key. + * ppccontext Memory context holding this PartitionPruneContext's + * subsidiary data, such as the FmgrInfos. + * planstate Points to the parent plan node's PlanState when called + * during execution; NULL when called from the planner. + * exprstates Array of ExprStates, indexed as per PruneCxtStateIdx; one + * for each partition key in each pruning step. Allocated if + * planstate is non-NULL, otherwise NULL. */ typedef struct PartitionPruneContext { - /* Partition key information */ char strategy; int partnatts; - Oid *partopfamily; - Oid *partopcintype; - Oid *partcollation; - FmgrInfo *partsupfunc; - - /* Number of partitions */ int nparts; - - /* Partition boundary info */ PartitionBoundInfo boundinfo; - - /* - * Can be set when the context is used from the executor to allow params - * found matching the partition key to be evaluated. - */ + Oid *partcollation; + FmgrInfo *partsupfunc; + FmgrInfo *stepcmpfuncs; + MemoryContext ppccontext; PlanState *planstate; - - /* - * Parameters that are safe to be used for partition pruning. execparams - * are not safe to use until the executor is running. - */ - Bitmapset *safeparams; + ExprState **exprstates; } PartitionPruneContext; +/* + * PruneCxtStateIdx() computes the correct index into the stepcmpfuncs[] + * and exprstates[] arrays for step step_id and partition key column keyno. + * (Note: there is code that assumes the entries for a given step are + * sequential, so this is not chosen freely.) + */ +#define PruneCxtStateIdx(partnatts, step_id, keyno) \ + ((partnatts) * (step_id) + (keyno)) -extern List *make_partition_pruneinfo(PlannerInfo *root, List *partition_rels, - List *subpaths, List *prunequal); -extern Relids prune_append_rel_partitions(RelOptInfo *rel); +extern PartitionPruneInfo *make_partition_pruneinfo(struct PlannerInfo *root, + struct RelOptInfo *parentrel, + List *subpaths, + List *partitioned_rels, + List *prunequal); +extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel); extern Bitmapset *get_matching_partitions(PartitionPruneContext *context, - List *pruning_steps); -extern List *gen_partprune_steps(RelOptInfo *rel, List *clauses, - bool *contradictory); + List *pruning_steps); #endif /* PARTPRUNE_H */ diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index f3620231a71..c6014e83fa8 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -114,18 +114,18 @@ /* Define to 1 if your compiler handles computed gotos. */ #undef HAVE_COMPUTED_GOTO +/* Define to 1 if you have the `copyfile' function. */ +#undef HAVE_COPYFILE + +/* Define to 1 if you have the header file. */ +#undef HAVE_COPYFILE_H + /* Define to 1 if you have the header file. */ #undef HAVE_CRTDEFS_H -/* Define to 1 if you have the `crypt' function. */ -#undef HAVE_CRYPT - /* Define to 1 if you have the `CRYPTO_lock' function. */ #undef HAVE_CRYPTO_LOCK -/* Define to 1 if you have the header file. */ -#undef HAVE_CRYPT_H - /* Define to 1 if you have the declaration of `fdatasync', and to 0 if you don't. */ #undef HAVE_DECL_FDATASYNC @@ -134,6 +134,18 @@ don't. */ #undef HAVE_DECL_F_FULLFSYNC +/* Define to 1 if you have the declaration of + `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */ +#undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER + +/* Define to 1 if you have the declaration of + `LLVMCreatePerfJITEventListener', and to 0 if you don't. */ +#undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER + +/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to + 0 if you don't. */ +#undef HAVE_DECL_LLVMGETHOSTCPUFEATURES + /* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0 if you don't. */ #undef HAVE_DECL_LLVMGETHOSTCPUNAME @@ -142,21 +154,17 @@ to 0 if you don't. */ #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN -/* Define to 1 if you have the declaration of `LLVMOrcRegisterGDB', and to 0 - if you don't. */ -#undef HAVE_DECL_LLVMORCREGISTERGDB - -/* Define to 1 if you have the declaration of `LLVMOrcRegisterPerf', and to 0 - if you don't. */ -#undef HAVE_DECL_LLVMORCREGISTERPERF - /* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you don't. */ #undef HAVE_DECL_POSIX_FADVISE -/* Define to 1 if you have the declaration of `snprintf', and to 0 if you +/* Define to 1 if you have the declaration of `RTLD_GLOBAL', and to 0 if you + don't. */ +#undef HAVE_DECL_RTLD_GLOBAL + +/* Define to 1 if you have the declaration of `RTLD_NOW', and to 0 if you don't. */ -#undef HAVE_DECL_SNPRINTF +#undef HAVE_DECL_RTLD_NOW /* Define to 1 if you have the declaration of `strlcat', and to 0 if you don't. */ @@ -170,16 +178,13 @@ don't. */ #undef HAVE_DECL_STRNLEN -/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you +/* Define to 1 if you have the declaration of `strtoll', and to 0 if you don't. */ -#undef HAVE_DECL_SYS_SIGLIST +#undef HAVE_DECL_STRTOLL -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you +/* Define to 1 if you have the declaration of `strtoull', and to 0 if you don't. */ -#undef HAVE_DECL_VSNPRINTF - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLD_H +#undef HAVE_DECL_STRTOULL /* Define to 1 if you have the `dlopen' function. */ #undef HAVE_DLOPEN @@ -190,6 +195,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_READLINE_H +/* Define to 1 if you have the `explicit_bzero' function. */ +#undef HAVE_EXPLICIT_BZERO + /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC @@ -220,28 +228,26 @@ /* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */ #undef HAVE_GCC__ATOMIC_INT32_CAS -/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int *, int64). - */ +/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, + int64). */ #undef HAVE_GCC__ATOMIC_INT64_CAS /* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */ #undef HAVE_GCC__SYNC_CHAR_TAS -/* Define to 1 if you have __sync_compare_and_swap(int *, int, int). */ +/* Define to 1 if you have __sync_val_compare_and_swap(int *, int, int). */ #undef HAVE_GCC__SYNC_INT32_CAS /* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */ #undef HAVE_GCC__SYNC_INT32_TAS -/* Define to 1 if you have __sync_compare_and_swap(int64 *, int64, int64). */ +/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64). + */ #undef HAVE_GCC__SYNC_INT64_CAS /* Define to 1 if you have the `getaddrinfo' function. */ #undef HAVE_GETADDRINFO -/* Define to 1 if you have the `getauxval' function. */ -#undef HAVE_GETAUXVAL - /* Define to 1 if you have the `gethostbyname_r' function. */ #undef HAVE_GETHOSTBYNAME_R @@ -392,6 +398,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `memset_s' function. */ +#undef HAVE_MEMSET_S + /* Define to 1 if the system has the type `MINIDUMP_TYPE'. */ #undef HAVE_MINIDUMP_TYPE @@ -428,6 +437,12 @@ /* Define to 1 if the assembler supports PPC's LWARX mutex hint bit. */ #undef HAVE_PPC_LWARX_MUTEX_HINT +/* Define to 1 if you have the `ppoll' function. */ +#undef HAVE_PPOLL + +/* Define to 1 if you have the `pread' function. */ +#undef HAVE_PREAD + /* Define to 1 if you have the `pstat' function. */ #undef HAVE_PSTAT @@ -443,12 +458,12 @@ /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT +/* Define to 1 if you have the `pwrite' function. */ +#undef HAVE_PWRITE + /* Define to 1 if you have the `random' function. */ #undef HAVE_RANDOM -/* Define to 1 if you have the `RAND_OpenSSL' function. */ -#undef HAVE_RAND_OPENSSL - /* Define to 1 if you have the header file. */ #undef HAVE_READLINE_H @@ -483,15 +498,15 @@ /* Define to 1 if you have the `setproctitle' function. */ #undef HAVE_SETPROCTITLE +/* Define to 1 if you have the `setproctitle_fast' function. */ +#undef HAVE_SETPROCTITLE_FAST + /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the `shm_open' function. */ #undef HAVE_SHM_OPEN -/* Define to 1 if you have the `snprintf' function. */ -#undef HAVE_SNPRINTF - /* Define to 1 if you have spinlocks. */ #undef HAVE_SPINLOCKS @@ -513,8 +528,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR +/* Define to 1 if you have the `strchrnul' function. */ +#undef HAVE_STRCHRNUL /* Define to 1 if you have the `strerror_r' function. */ #undef HAVE_STRERROR_R @@ -534,8 +549,11 @@ /* Define to 1 if you have the `strnlen' function. */ #undef HAVE_STRNLEN -/* Define to use have a strong random number source */ -#undef HAVE_STRONG_RANDOM +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if you have the `strtof' function. */ +#undef HAVE_STRTOF /* Define to 1 if you have the `strtoll' function. */ #undef HAVE_STRTOLL @@ -594,6 +612,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IPC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PRCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCCTL_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H @@ -667,6 +691,9 @@ /* Define to 1 if the system has the type `unsigned long long int'. */ #undef HAVE_UNSIGNED_LONG_LONG_INT +/* Define to 1 if you have the `uselocale' function. */ +#undef HAVE_USELOCALE + /* Define to 1 if you have the `utime' function. */ #undef HAVE_UTIME @@ -691,9 +718,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UUID_UUID_H -/* Define to 1 if you have the `vsnprintf' function. */ -#undef HAVE_VSNPRINTF - /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H @@ -709,6 +733,9 @@ /* Define to 1 if you have the `X509_get_signature_nid' function. */ #undef HAVE_X509_GET_SIGNATURE_NID +/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ +#undef HAVE_X86_64_POPCNTQ + /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL @@ -721,18 +748,30 @@ /* Define to 1 if your compiler understands __builtin_bswap64. */ #undef HAVE__BUILTIN_BSWAP64 +/* Define to 1 if your compiler understands __builtin_clz. */ +#undef HAVE__BUILTIN_CLZ + /* Define to 1 if your compiler understands __builtin_constant_p. */ #undef HAVE__BUILTIN_CONSTANT_P +/* Define to 1 if your compiler understands __builtin_ctz. */ +#undef HAVE__BUILTIN_CTZ + /* Define to 1 if your compiler understands __builtin_$op_overflow. */ #undef HAVE__BUILTIN_OP_OVERFLOW +/* Define to 1 if your compiler understands __builtin_popcount. */ +#undef HAVE__BUILTIN_POPCOUNT + /* Define to 1 if your compiler understands __builtin_types_compatible_p. */ #undef HAVE__BUILTIN_TYPES_COMPATIBLE_P /* Define to 1 if your compiler understands __builtin_unreachable. */ #undef HAVE__BUILTIN_UNREACHABLE +/* Define to 1 if you have the `_configthreadlocale' function. */ +#undef HAVE__CONFIGTHREADLOCALE + /* Define to 1 if you have __cpuid. */ #undef HAVE__CPUID @@ -742,10 +781,13 @@ /* Define to 1 if your compiler understands _Static_assert. */ #undef HAVE__STATIC_ASSERT -/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */ -#undef HAVE__VA_ARGS +/* Define to 1 if you have the `__strtoll' function. */ +#undef HAVE___STRTOLL -/* Define to the appropriate snprintf length modifier for 64-bit ints. */ +/* Define to 1 if you have the `__strtoull' function. */ +#undef HAVE___STRTOULL + +/* Define to the appropriate printf length modifier for 64-bit ints. */ #undef INT64_MODIFIER /* Define to 1 if `locale_t' requires . */ @@ -788,7 +830,7 @@ /* PostgreSQL major version as a string */ #undef PG_MAJORVERSION -/* Define to gnu_printf if compiler supports it, else printf. */ +/* Define to best printf format archetype, usually gnu_printf if available. */ #undef PG_PRINTF_ATTRIBUTE /* PostgreSQL version as a string */ @@ -839,7 +881,7 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Define to 1 if strerror_r() returns a int. */ +/* Define to 1 if strerror_r() returns int. */ #undef STRERROR_R_INT /* Define to 1 if your declares `struct tm'. */ @@ -899,9 +941,6 @@ /* Define to 1 to build with PAM support. (--with-pam) */ #undef USE_PAM -/* Use replacement snprintf() functions. */ -#undef USE_REPL_SNPRINTF - /* Define to 1 to use software CRC-32C implementation (slicing-by-8). */ #undef USE_SLICING_BY_8_CRC32C diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index bc437b08f0c..5bbf476990f 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -72,6 +72,15 @@ # define gettimeofday(a,b) gettimeofday(a) #endif +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +/* #undef HAVE_ASN1_STRING_GET0_DATA */ + +/* Define to 1 if you have the `BIO_get_data' function. */ +/* #undef HAVE_BIO_GET_DATA */ + +/* Define to 1 if you have the `BIO_meth_new' function. */ +/* #undef HAVE_BIO_METH_NEW */ + /* Define to 1 if you have the `cbrt' function. */ //#define HAVE_CBRT 1 @@ -84,12 +93,6 @@ /* Define to 1 if your compiler handles computed gotos. */ /* #undef HAVE_COMPUTED_GOTO */ -/* Define to 1 if you have the `crypt' function. */ -/* #undef HAVE_CRYPT */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_CRYPT_H */ - /* Define to 1 if you have the declaration of `fdatasync', and to 0 if you don't. */ #define HAVE_DECL_FDATASYNC 0 @@ -98,36 +101,48 @@ don't. */ #define HAVE_DECL_F_FULLFSYNC 0 +/* Define to 1 if you have the declaration of + `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */ +#undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER + +/* Define to 1 if you have the declaration of + `LLVMCreatePerfJITEventListener', and to 0 if you don't. */ +#undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER + /* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0 if you don't. */ #define HAVE_DECL_LLVMGETHOSTCPUNAME 0 +/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to 0 + if you don't. */ +#define HAVE_DECL_LLVMGETHOSTCPUFEATURES 0 + /* Define to 1 if you have the declaration of `LLVMOrcGetSymbolAddressIn', and to 0 if you don't. */ #define HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN 0 -/* Define to 1 if you have the declaration of `LLVMOrcRegisterGDB', and to 0 - if you don't. */ -#define HAVE_DECL_LLVMORCREGISTERGDB 0 - -/* Define to 1 if you have the declaration of `LLVMOrcRegisterPerf', and to 0 - if you don't. */ -#define HAVE_DECL_LLVMORCREGISTERPERF 0 +/* Define to 1 if you have the declaration of `RTLD_GLOBAL', and to 0 if you + don't. */ +#define HAVE_DECL_RTLD_GLOBAL 0 -/* Define to 1 if you have the declaration of `snprintf', and to 0 if you +/* Define to 1 if you have the declaration of `RTLD_NOW', and to 0 if you don't. */ -#define HAVE_DECL_SNPRINTF 1 +#define HAVE_DECL_RTLD_NOW 0 /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #define HAVE_DECL_STRNLEN 1 -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you +/* Define to 1 if you have the `strtof' function. */ +#define HAVE_STRTOF 1 + +/* Define to 1 if you have the declaration of `strtoll', and to 0 if you don't. */ -#define HAVE_DECL_VSNPRINTF 1 +#define HAVE_DECL_STRTOLL 1 -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLD_H */ +/* Define to 1 if you have the declaration of `strtoull', and to 0 if you + don't. */ +#define HAVE_DECL_STRTOULL 1 /* Define to 1 if you have the `dlopen' function. */ /* #undef HAVE_DLOPEN */ @@ -138,15 +153,12 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_EDITLINE_READLINE_H */ -/* Define to 1 if you have the `fcvt' function. */ -#define HAVE_FCVT 1 +/* Define to 1 if you have the `explicit_bzero' function. */ +/* #undef HAVE_EXPLICIT_BZERO */ /* Define to 1 if you have the `fdatasync' function. */ /* #undef HAVE_FDATASYNC */ -/* Define to 1 if you have finite(). */ -#define HAVE_FINITE 1 - /* Define to 1 if you have the `fpclass' function. */ /* #undef HAVE_FPCLASS */ @@ -225,6 +237,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_LDAP_H */ +/* Define to 1 if you have the `ldap_initialize' function. */ +/* #undef HAVE_LDAP_INITIALIZE */ + /* Define to 1 if you have the `crypto' library (-lcrypto). */ /* #undef HAVE_LIBCRYPTO */ @@ -271,6 +286,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 +/* Define to 1 if you have the `memset_s' function. */ +/* #undef HAVE_MEMSET_S */ + /* Define to 1 if the system has the type `MINIDUMP_TYPE'. */ #define HAVE_MINIDUMP_TYPE 1 @@ -280,6 +298,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_NETINET_TCP_H */ +/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +/* #undef HAVE_OPENSSL_INIT_SSL */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_PAM_PAM_APPL_H */ @@ -295,12 +316,21 @@ /* Define to 1 if you have the `posix_fallocate' function. */ /* #undef HAVE_POSIX_FALLOCATE */ +/* Define to 1 if you have the `ppoll' function. */ +/* #undef HAVE_PPOLL */ + +/* Define to 1 if you have the `pread' function. */ +/* #undef HAVE_PREAD */ + /* Define to 1 if you have the `pstat' function. */ /* #undef HAVE_PSTAT */ /* Define to 1 if the PS_STRINGS thing exists. */ /* #undef HAVE_PS_STRINGS */ +/* Define to 1 if you have the `pwrite' function. */ +/* #undef HAVE_PWRITE */ + /* Define to 1 if you have the `random' function. */ /* #undef HAVE_RANDOM */ @@ -341,9 +371,6 @@ /* Define to 1 if you have the `setsid' function. */ /* #undef HAVE_SETSID */ -/* Define to 1 if you have the `snprintf' function. */ -/* #undef HAVE_SNPRINTF */ - /* Define to 1 if you have spinlocks. */ #define HAVE_SPINLOCKS 1 @@ -353,11 +380,16 @@ /* Define to 1 if you have the `srandom' function. */ /* #undef HAVE_SRANDOM */ +/* Define to 1 if you have the `SSL_clear_options' function. */ +#define HAVE_SSL_CLEAR_OPTIONS 1 + /* Define to 1 if you have the `SSL_get_current_compression' function. */ #define HAVE_SSL_GET_CURRENT_COMPRESSION 1 /* Define to 1 if stdbool.h conforms to C99. */ -/* #undef HAVE_STDBOOL_H */ +#if (_MSC_VER >= 1800) +#define HAVE_STDBOOL_H 1 +#endif /* Define to 1 if you have the header file. */ /* #undef HAVE_STDINT_H */ @@ -365,10 +397,8 @@ /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 -/* Define to 1 if you have the `strerror' function. */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif +/* Define to 1 if you have the `strchrnul' function. */ +/* #undef HAVE_STRCHRNUL */ /* Define to 1 if you have the `strerror_r' function. */ /* #undef HAVE_STRERROR_R */ @@ -379,20 +409,26 @@ /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 -/* Define to use have a strong random number source */ -#define HAVE_STRONG_RANDOM 1 +/* Define to 1 if you have the `strsignal' function. */ +/* #undef HAVE_STRSIGNAL */ /* Define to 1 if you have the `strtoll' function. */ -//#define HAVE_STRTOLL 1 - -/* Define to 1 if you have the `strtoq' function. */ -/* #undef HAVE_STRTOQ */ +#ifdef HAVE_LONG_LONG_INT_64 +#define HAVE_STRTOLL 1 +/* Before VS2013, use Microsoft's nonstandard equivalent function */ +#if (_MSC_VER < 1800) +#define strtoll _strtoi64 +#endif +#endif /* Define to 1 if you have the `strtoull' function. */ -//#define HAVE_STRTOULL 1 - -/* Define to 1 if you have the `strtouq' function. */ -/* #undef HAVE_STRTOUQ */ +#ifdef HAVE_LONG_LONG_INT_64 +#define HAVE_STRTOULL 1 +/* Before VS2013, use Microsoft's nonstandard equivalent function */ +#if (_MSC_VER < 1800) +#define strtoull _strtoui64 +#endif +#endif /* Define to 1 if the system has the type `struct addrinfo'. */ #if (_MSC_VER > 1200) @@ -427,9 +463,6 @@ /* Define to 1 if `__ss_len' is member of `struct sockaddr_storage'. */ /* #undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */ -/* Define to 1 if the system has the type `struct sockaddr_un'. */ -/* #undef HAVE_STRUCT_SOCKADDR_UN */ - /* Define to 1 if `tm_zone' is member of `struct tm'. */ /* #undef HAVE_STRUCT_TM_TM_ZONE */ @@ -439,15 +472,15 @@ /* Define to 1 if you have the `sync_file_range' function. */ /* #undef HAVE_SYNC_FILE_RANGE */ -/* Define to 1 if you have the `sysconf' function. */ -/* #undef HAVE_SYSCONF */ - /* Define to 1 if you have the syslog interface. */ /* #undef HAVE_SYSLOG */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_IPC_H */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRCTL_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PSTAT_H */ @@ -503,6 +536,9 @@ /* Define to 1 if you have the `unsetenv' function. */ /* #undef HAVE_UNSETENV */ +/* Define to 1 if you have the `uselocale' function. */ +/* #undef HAVE_USELOCALE */ + /* Define to 1 if you have the `utime' function. */ #define HAVE_UTIME 1 @@ -512,9 +548,6 @@ /* Define to 1 if you have the header file. */ #define HAVE_UTIME_H 1 -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - /* Define to 1 if you have the header file. */ #define HAVE_WCHAR_H 1 @@ -527,6 +560,12 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_WINLDAP_H */ +/* Define to 1 if you have the `X509_get_signature_nid' function. */ +#define HAVE_X509_GET_SIGNATURE_NID 1 + +/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ +/* #undef HAVE_X86_64_POPCNTQ */ + /* Define to 1 if the system has the type `_Bool'. */ /* #undef HAVE__BOOL */ @@ -539,18 +578,30 @@ /* Define to 1 if your compiler understands __builtin_bswap64. */ /* #undef HAVE__BUILTIN_BSWAP64 */ +/* Define to 1 if your compiler understands __builtin_clz. */ +/* #undef HAVE__BUILTIN_CLZ */ + /* Define to 1 if your compiler understands __builtin_constant_p. */ /* #undef HAVE__BUILTIN_CONSTANT_P */ +/* Define to 1 if your compiler understands __builtin_ctz. */ +/* #undef HAVE__BUILTIN_CTZ */ + /* Define to 1 if your compiler understands __builtin_$op_overflow. */ /* #undef HAVE__BUILTIN_OP_OVERFLOW */ +/* Define to 1 if your compiler understands __builtin_popcount. */ +/* #undef HAVE__BUILTIN_POPCOUNT */ + /* Define to 1 if your compiler understands __builtin_types_compatible_p. */ /* #undef HAVE__BUILTIN_TYPES_COMPATIBLE_P */ /* Define to 1 if your compiler understands __builtin_unreachable. */ /* #undef HAVE__BUILTIN_UNREACHABLE */ +/* Define to 1 if you have the `_configthreadlocale' function. */ +#define HAVE__CONFIGTHREADLOCALE 1 + /* Define to 1 if you have __cpuid. */ #define HAVE__CPUID 1 @@ -560,10 +611,7 @@ /* Define to 1 if your compiler understands _Static_assert. */ /* #undef HAVE__STATIC_ASSERT */ -/* Define to 1 if your compiler understands __VA_ARGS__ in macros. */ -#define HAVE__VA_ARGS 1 - -/* Define to the appropriate snprintf length modifier for 64-bit ints. */ +/* Define to the appropriate printf length modifier for 64-bit ints. */ #define INT64_MODIFIER "ll" /* Define to 1 if `locale_t' requires . */ @@ -579,16 +627,16 @@ #define MEMSET_LOOP_LIMIT 1024 /* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "pgsql-bugs@postgresql.org" +#define PACKAGE_BUGREPORT "pgsql-bugs@lists.postgresql.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "PostgreSQL" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PostgreSQL 11devel" +#define PACKAGE_STRING "PostgreSQL 13devel" /* Define to the version of this package. */ -#define PACKAGE_VERSION "11devel" +#define PACKAGE_VERSION "13devel" /* Define to the name of a signed 128-bit integer type. */ #undef PG_INT128_TYPE @@ -597,10 +645,10 @@ #define PG_INT64_TYPE long long int /* PostgreSQL version as a string */ -#define PG_VERSION "11devel" +#define PG_VERSION "13devel" /* PostgreSQL version as a number */ -#define PG_VERSION_NUM 110000 +#define PG_VERSION_NUM 130000 /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "postgresql" @@ -613,7 +661,7 @@ #define PG_VERSION_STR "Uninitialized version string (win32)" /* The size of `bool', as computed by sizeof. */ -#define SIZEOF_BOOL 0 +#define SIZEOF_BOOL 1 /* The size of `long', as computed by sizeof. */ #define SIZEOF_LONG 4 @@ -635,7 +683,7 @@ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 -/* Define to 1 if strerror_r() returns a int. */ +/* Define to 1 if strerror_r() returns int. */ /* #undef STRERROR_R_INT */ /* Define to 1 if your declares `struct tm'. */ @@ -671,9 +719,6 @@ /* Define to 1 to build with PAM support. (--with-pam) */ /* #undef USE_PAM */ -/* Use replacement snprintf() functions. */ -#define USE_REPL_SNPRINTF 1 - /* Define to 1 to use software CRC-32C implementation (slicing-by-8). */ #if (_MSC_VER < 1500) #define USE_SLICING_BY_8_CRC32C 1 diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index b309395f11c..743401cb969 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -6,7 +6,7 @@ * for developers. If you edit any of these, be sure to do a *full* * rebuild (and an initdb if noted). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/pg_config_manual.h @@ -14,8 +14,8 @@ */ /* - * This is default value for wal_segment_size to be used at initdb when run - * without --walsegsize option. Must be a valid segment size. + * This is the default value for wal_segment_size to be used when initdb is run + * without the --wal-segsize option. It must be a valid segment size. */ #define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) @@ -136,7 +136,9 @@ /* * USE_PREFETCH code should be compiled only if we have a way to implement * prefetching. (This is decoupled from USE_POSIX_FADVISE because there - * might in future be support for alternative low-level prefetch APIs.) + * might in future be support for alternative low-level prefetch APIs. + * If you change this, you probably need to adjust the error message in + * check_effective_io_concurrency.) */ #ifdef USE_POSIX_FADVISE #define USE_PREFETCH @@ -286,6 +288,13 @@ */ /* #define COPY_PARSE_PLAN_TREES */ +/* + * Define this to force all parse and plan trees to be passed through + * outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in + * those modules. + */ +/* #define WRITE_READ_PARSE_PLAN_TREES */ + /* * Define this to force all raw parse trees for DML statements to be scanned * by raw_expression_tree_walker(), to facilitate catching errors and diff --git a/src/include/pg_getopt.h b/src/include/pg_getopt.h index c050f2025f9..639a1613c13 100644 --- a/src/include/pg_getopt.h +++ b/src/include/pg_getopt.h @@ -1,8 +1,17 @@ /* + * Postgres files that use getopt(3) always include this file. + * We must cope with three different scenarios: + * 1. We're using the platform's getopt(), and we should just import the + * appropriate declarations. + * 2. The platform lacks getopt(), and we must declare everything. + * 3. The platform has getopt(), but we're not using it because we don't + * like its behavior. The declarations we make here must be compatible + * with both the platform's getopt() and our src/port/getopt.c. + * * Portions Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. * - * Portions Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2003-2019, PostgreSQL Global Development Group * * src/include/pg_getopt.h */ @@ -39,6 +48,7 @@ extern int optopt; extern int optreset; #endif +/* Provide getopt() declaration if the platform doesn't have it */ #ifndef HAVE_GETOPT extern int getopt(int nargc, char *const *nargv, const char *ostr); #endif diff --git a/src/include/pg_trace.h b/src/include/pg_trace.h index e00e39da4e9..6f25db64663 100644 --- a/src/include/pg_trace.h +++ b/src/include/pg_trace.h @@ -3,7 +3,7 @@ * * Definitions for the PostgreSQL tracing framework * - * Copyright (c) 2006-2018, PostgreSQL Global Development Group + * Copyright (c) 2006-2019, PostgreSQL Global Development Group * * src/include/pg_trace.h * ---------- diff --git a/src/include/pgstat.h b/src/include/pgstat.h index be2f59239bf..fe076d823db 100644 --- a/src/include/pgstat.h +++ b/src/include/pgstat.h @@ -3,7 +3,7 @@ * * Definitions for the PostgreSQL statistics collector daemon. * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/include/pgstat.h * ---------- @@ -12,7 +12,6 @@ #define PGSTAT_H #include "datatype/timestamp.h" -#include "fmgr.h" #include "libpq/pqcomm.h" #include "port/atomics.h" #include "portability/instr_time.h" @@ -64,7 +63,8 @@ typedef enum StatMsgType PGSTAT_MTYPE_FUNCPURGE, PGSTAT_MTYPE_RECOVERYCONFLICT, PGSTAT_MTYPE_TEMPFILE, - PGSTAT_MTYPE_DEADLOCK + PGSTAT_MTYPE_DEADLOCK, + PGSTAT_MTYPE_CHECKSUMFAILURE } StatMsgType; /* ---------- @@ -530,6 +530,19 @@ typedef struct PgStat_MsgDeadlock Oid m_databaseid; } PgStat_MsgDeadlock; +/* ---------- + * PgStat_MsgChecksumFailure Sent by the backend to tell the collector + * about checksum failures noticed. + * ---------- + */ +typedef struct PgStat_MsgChecksumFailure +{ + PgStat_MsgHdr m_hdr; + Oid m_databaseid; + int m_failurecount; + TimestampTz m_failure_time; +} PgStat_MsgChecksumFailure; + /* ---------- * PgStat_Msg Union over all possible messages. @@ -546,7 +559,7 @@ typedef union PgStat_Msg PgStat_MsgResetcounter msg_resetcounter; PgStat_MsgResetsharedcounter msg_resetsharedcounter; PgStat_MsgResetsinglecounter msg_resetsinglecounter; - PgStat_MsgAutovacStart msg_autovacuum; + PgStat_MsgAutovacStart msg_autovacuum_start; PgStat_MsgVacuum msg_vacuum; PgStat_MsgAnalyze msg_analyze; PgStat_MsgArchiver msg_archiver; @@ -555,6 +568,8 @@ typedef union PgStat_Msg PgStat_MsgFuncpurge msg_funcpurge; PgStat_MsgRecoveryConflict msg_recoveryconflict; PgStat_MsgDeadlock msg_deadlock; + PgStat_MsgTempFile msg_tempfile; + PgStat_MsgChecksumFailure msg_checksumfailure; } PgStat_Msg; @@ -593,6 +608,8 @@ typedef struct PgStat_StatDBEntry PgStat_Counter n_temp_files; PgStat_Counter n_temp_bytes; PgStat_Counter n_deadlocks; + PgStat_Counter n_checksum_failures; + TimestampTz last_checksum_failure; PgStat_Counter n_block_read_time; /* times in microseconds */ PgStat_Counter n_block_write_time; @@ -759,8 +776,8 @@ typedef enum WAIT_EVENT_BGWRITER_HIBERNATE, WAIT_EVENT_BGWRITER_MAIN, WAIT_EVENT_CHECKPOINTER_MAIN, - WAIT_EVENT_LOGICAL_LAUNCHER_MAIN, WAIT_EVENT_LOGICAL_APPLY_MAIN, + WAIT_EVENT_LOGICAL_LAUNCHER_MAIN, WAIT_EVENT_PGSTAT_MAIN, WAIT_EVENT_RECOVERY_WAL_ALL, WAIT_EVENT_RECOVERY_WAL_STREAM, @@ -787,7 +804,8 @@ typedef enum WAIT_EVENT_SSL_OPEN_SERVER, WAIT_EVENT_WAL_RECEIVER_WAIT_START, WAIT_EVENT_WAL_SENDER_WAIT_WAL, - WAIT_EVENT_WAL_SENDER_WRITE_DATA + WAIT_EVENT_WAL_SENDER_WRITE_DATA, + WAIT_EVENT_GSS_OPEN_SERVER, } WaitEventClient; /* ---------- @@ -802,6 +820,9 @@ typedef enum WAIT_EVENT_BGWORKER_SHUTDOWN = PG_WAIT_IPC, WAIT_EVENT_BGWORKER_STARTUP, WAIT_EVENT_BTREE_PAGE, + WAIT_EVENT_CLOG_GROUP_UPDATE, + WAIT_EVENT_CHECKPOINT_DONE, + WAIT_EVENT_CHECKPOINT_START, WAIT_EVENT_EXECUTE_GATHER, WAIT_EVENT_HASH_BATCH_ALLOCATING, WAIT_EVENT_HASH_BATCH_ELECTING, @@ -810,25 +831,25 @@ typedef enum WAIT_EVENT_HASH_BUILD_ELECTING, WAIT_EVENT_HASH_BUILD_HASHING_INNER, WAIT_EVENT_HASH_BUILD_HASHING_OUTER, + WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATING, + WAIT_EVENT_HASH_GROW_BATCHES_DECIDING, WAIT_EVENT_HASH_GROW_BATCHES_ELECTING, WAIT_EVENT_HASH_GROW_BATCHES_FINISHING, WAIT_EVENT_HASH_GROW_BATCHES_REPARTITIONING, - WAIT_EVENT_HASH_GROW_BATCHES_ALLOCATING, - WAIT_EVENT_HASH_GROW_BATCHES_DECIDING, + WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATING, WAIT_EVENT_HASH_GROW_BUCKETS_ELECTING, WAIT_EVENT_HASH_GROW_BUCKETS_REINSERTING, - WAIT_EVENT_HASH_GROW_BUCKETS_ALLOCATING, WAIT_EVENT_LOGICAL_SYNC_DATA, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE, WAIT_EVENT_MQ_INTERNAL, WAIT_EVENT_MQ_PUT_MESSAGE, WAIT_EVENT_MQ_RECEIVE, WAIT_EVENT_MQ_SEND, - WAIT_EVENT_PARALLEL_FINISH, WAIT_EVENT_PARALLEL_BITMAP_SCAN, WAIT_EVENT_PARALLEL_CREATE_INDEX_SCAN, + WAIT_EVENT_PARALLEL_FINISH, WAIT_EVENT_PROCARRAY_GROUP_UPDATE, - WAIT_EVENT_CLOG_GROUP_UPDATE, + WAIT_EVENT_PROMOTE, WAIT_EVENT_REPLICATION_ORIGIN_DROP, WAIT_EVENT_REPLICATION_SLOT_DROP, WAIT_EVENT_SAFE_SNAPSHOT, @@ -921,6 +942,7 @@ typedef enum WAIT_EVENT_WAL_INIT_SYNC, WAIT_EVENT_WAL_INIT_WRITE, WAIT_EVENT_WAL_READ, + WAIT_EVENT_WAL_SYNC, WAIT_EVENT_WAL_SYNC_METHOD_ASSIGN, WAIT_EVENT_WAL_WRITE } WaitEventIO; @@ -932,10 +954,12 @@ typedef enum typedef enum ProgressCommandType { PROGRESS_COMMAND_INVALID, - PROGRESS_COMMAND_VACUUM + PROGRESS_COMMAND_VACUUM, + PROGRESS_COMMAND_CLUSTER, + PROGRESS_COMMAND_CREATE_INDEX } ProgressCommandType; -#define PGSTAT_NUM_PROGRESS_PARAM 10 +#define PGSTAT_NUM_PROGRESS_PARAM 20 /* ---------- * Shared-memory data structures @@ -948,17 +972,44 @@ typedef enum ProgressCommandType * * For each backend, we keep the SSL status in a separate struct, that * is only filled in if SSL is enabled. + * + * All char arrays must be null-terminated. */ typedef struct PgBackendSSLStatus { /* Information about SSL connection */ int ssl_bits; bool ssl_compression; - char ssl_version[NAMEDATALEN]; /* MUST be null-terminated */ - char ssl_cipher[NAMEDATALEN]; /* MUST be null-terminated */ - char ssl_clientdn[NAMEDATALEN]; /* MUST be null-terminated */ + char ssl_version[NAMEDATALEN]; + char ssl_cipher[NAMEDATALEN]; + char ssl_client_dn[NAMEDATALEN]; + + /* + * serial number is max "20 octets" per RFC 5280, so this size should be + * fine + */ + char ssl_client_serial[NAMEDATALEN]; + + char ssl_issuer_dn[NAMEDATALEN]; } PgBackendSSLStatus; +/* + * PgBackendGSSStatus + * + * For each backend, we keep the GSS status in a separate struct, that + * is only filled in if GSS is enabled. + * + * All char arrays must be null-terminated. + */ +typedef struct PgBackendGSSStatus +{ + /* Information about GSSAPI connection */ + char gss_princ[NAMEDATALEN]; /* GSSAPI Principal used to auth */ + bool gss_auth; /* If GSSAPI authentication was used */ + bool gss_enc; /* If encryption is being used */ + +} PgBackendGSSStatus; + /* ---------- * PgBackendStatus @@ -983,11 +1034,12 @@ typedef struct PgBackendStatus * the copy is valid; otherwise start over. This makes updates cheap * while reads are potentially expensive, but that's the tradeoff we want. * - * The above protocol needs the memory barriers to ensure that the - * apparent order of execution is as it desires. Otherwise, for example, - * the CPU might rearrange the code so that st_changecount is incremented - * twice before the modification on a machine with weak memory ordering. - * This surprising result can lead to bugs. + * The above protocol needs memory barriers to ensure that the apparent + * order of execution is as it desires. Otherwise, for example, the CPU + * might rearrange the code so that st_changecount is incremented twice + * before the modification on a machine with weak memory ordering. Hence, + * use the macros defined below for manipulating st_changecount, rather + * than touching it directly. */ int st_changecount; @@ -1013,6 +1065,10 @@ typedef struct PgBackendStatus bool st_ssl; PgBackendSSLStatus *st_sslstatus; + /* Information about GSSAPI connection */ + bool st_gss; + PgBackendGSSStatus *st_gssstatus; + /* current state */ BackendState st_state; @@ -1043,42 +1099,66 @@ typedef struct PgBackendStatus } PgBackendStatus; /* - * Macros to load and store st_changecount with the memory barriers. + * Macros to load and store st_changecount with appropriate memory barriers. + * + * Use PGSTAT_BEGIN_WRITE_ACTIVITY() before, and PGSTAT_END_WRITE_ACTIVITY() + * after, modifying the current process's PgBackendStatus data. Note that, + * since there is no mechanism for cleaning up st_changecount after an error, + * THESE MACROS FORM A CRITICAL SECTION. Any error between them will be + * promoted to PANIC, causing a database restart to clean up shared memory! + * Hence, keep the critical section as short and straight-line as possible. + * Aside from being safer, that minimizes the window in which readers will + * have to loop. * - * pgstat_increment_changecount_before() and - * pgstat_increment_changecount_after() need to be called before and after - * PgBackendStatus entries are modified, respectively. This makes sure that - * st_changecount is incremented around the modification. + * Reader logic should follow this sketch: * - * Also pgstat_save_changecount_before() and pgstat_save_changecount_after() - * need to be called before and after PgBackendStatus entries are copied into - * private memory, respectively. + * for (;;) + * { + * int before_ct, after_ct; + * + * pgstat_begin_read_activity(beentry, before_ct); + * ... copy beentry data to local memory ... + * pgstat_end_read_activity(beentry, after_ct); + * if (pgstat_read_activity_complete(before_ct, after_ct)) + * break; + * CHECK_FOR_INTERRUPTS(); + * } + * + * For extra safety, we generally use volatile beentry pointers, although + * the memory barriers should theoretically be sufficient. */ -#define pgstat_increment_changecount_before(beentry) \ - do { \ - beentry->st_changecount++; \ +#define PGSTAT_BEGIN_WRITE_ACTIVITY(beentry) \ + do { \ + START_CRIT_SECTION(); \ + (beentry)->st_changecount++; \ pg_write_barrier(); \ } while (0) -#define pgstat_increment_changecount_after(beentry) \ - do { \ +#define PGSTAT_END_WRITE_ACTIVITY(beentry) \ + do { \ pg_write_barrier(); \ - beentry->st_changecount++; \ - Assert((beentry->st_changecount & 1) == 0); \ + (beentry)->st_changecount++; \ + Assert(((beentry)->st_changecount & 1) == 0); \ + END_CRIT_SECTION(); \ } while (0) -#define pgstat_save_changecount_before(beentry, save_changecount) \ - do { \ - save_changecount = beentry->st_changecount; \ - pg_read_barrier(); \ +#define pgstat_begin_read_activity(beentry, before_changecount) \ + do { \ + (before_changecount) = (beentry)->st_changecount; \ + pg_read_barrier(); \ } while (0) -#define pgstat_save_changecount_after(beentry, save_changecount) \ - do { \ - pg_read_barrier(); \ - save_changecount = beentry->st_changecount; \ +#define pgstat_end_read_activity(beentry, after_changecount) \ + do { \ + pg_read_barrier(); \ + (after_changecount) = (beentry)->st_changecount; \ } while (0) +#define pgstat_read_activity_complete(before_changecount, after_changecount) \ + ((before_changecount) == (after_changecount) && \ + ((before_changecount) & 1) == 0) + + /* ---------- * LocalPgBackendStatus * @@ -1181,13 +1261,15 @@ extern void pgstat_reset_single_counter(Oid objectid, PgStat_Single_Reset_Type t extern void pgstat_report_autovac(Oid dboid); extern void pgstat_report_vacuum(Oid tableoid, bool shared, - PgStat_Counter livetuples, PgStat_Counter deadtuples); + PgStat_Counter livetuples, PgStat_Counter deadtuples); extern void pgstat_report_analyze(Relation rel, - PgStat_Counter livetuples, PgStat_Counter deadtuples, - bool resetcounter); + PgStat_Counter livetuples, PgStat_Counter deadtuples, + bool resetcounter); extern void pgstat_report_recovery_conflict(int reason); extern void pgstat_report_deadlock(void); +extern void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount); +extern void pgstat_report_checksum_failure(void); extern void pgstat_initialize(void); extern void pgstat_bestart(void); @@ -1200,14 +1282,14 @@ extern const char *pgstat_get_wait_event(uint32 wait_event_info); extern const char *pgstat_get_wait_event_type(uint32 wait_event_info); extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser); extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer, - int buflen); + int buflen); extern const char *pgstat_get_backend_desc(BackendType backendType); extern void pgstat_progress_start_command(ProgressCommandType cmdtype, - Oid relid); + Oid relid); extern void pgstat_progress_update_param(int index, int64 val); extern void pgstat_progress_update_multi_param(int nparam, const int *index, - const int64 *val); + const int64 *val); extern void pgstat_progress_end_command(void); extern PgStat_TableStatus *find_tabstat_entry(Oid rel_id); @@ -1319,21 +1401,22 @@ extern void pgstat_count_heap_delete(Relation rel); extern void pgstat_count_truncate(Relation rel); extern void pgstat_update_heap_dead_tuples(Relation rel, int delta); -extern void pgstat_init_function_usage(FunctionCallInfoData *fcinfo, - PgStat_FunctionCallUsage *fcu); +struct FunctionCallInfoBaseData; +extern void pgstat_init_function_usage(struct FunctionCallInfoBaseData *fcinfo, + PgStat_FunctionCallUsage *fcu); extern void pgstat_end_function_usage(PgStat_FunctionCallUsage *fcu, - bool finalize); + bool finalize); -extern void AtEOXact_PgStat(bool isCommit); +extern void AtEOXact_PgStat(bool isCommit, bool parallel); extern void AtEOSubXact_PgStat(bool isCommit, int nestDepth); extern void AtPrepare_PgStat(void); extern void PostPrepare_PgStat(void); extern void pgstat_twophase_postcommit(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void pgstat_twophase_postabort(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void pgstat_send_archiver(const char *xlog, bool failed); extern void pgstat_send_bgwriter(void); diff --git a/src/include/pgtar.h b/src/include/pgtar.h index 9eaa8bf15de..e69d87d8837 100644 --- a/src/include/pgtar.h +++ b/src/include/pgtar.h @@ -4,7 +4,7 @@ * Functions for manipulating tarfile datastructures (src/port/tar.c) * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/pgtar.h @@ -20,7 +20,7 @@ enum tarError }; extern enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, - pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime); + pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime); extern uint64 read_tar_number(const char *s, int len); extern void print_tar_number(char *s, int len, uint64 val); extern int tarChecksum(char *header); diff --git a/src/include/pgtime.h b/src/include/pgtime.h index 5f18b04b20a..ff0e72a3a99 100644 --- a/src/include/pgtime.h +++ b/src/include/pgtime.h @@ -3,7 +3,7 @@ * pgtime.h * PostgreSQL internal timezone library * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/pgtime.h @@ -47,18 +47,18 @@ typedef struct pg_tzenum pg_tzenum; extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz); extern struct pg_tm *pg_gmtime(const pg_time_t *timep); -extern int pg_next_dst_boundary(const pg_time_t *timep, - long int *before_gmtoff, - int *before_isdst, - pg_time_t *boundary, - long int *after_gmtoff, - int *after_isdst, - const pg_tz *tz); +extern int pg_next_dst_boundary(const pg_time_t *timep, + long int *before_gmtoff, + int *before_isdst, + pg_time_t *boundary, + long int *after_gmtoff, + int *after_isdst, + const pg_tz *tz); extern bool pg_interpret_timezone_abbrev(const char *abbrev, - const pg_time_t *timep, - long int *gmtoff, - int *isdst, - const pg_tz *tz); + const pg_time_t *timep, + long int *gmtoff, + int *isdst, + const pg_tz *tz); extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff); extern const char *pg_get_timezone_name(pg_tz *tz); extern bool pg_tz_acceptable(pg_tz *tz); @@ -66,7 +66,7 @@ extern bool pg_tz_acceptable(pg_tz *tz); /* these functions are in strftime.c */ extern size_t pg_strftime(char *s, size_t max, const char *format, - const struct pg_tm *tm); + const struct pg_tm *tm); /* these functions and variables are in pgtz.c */ diff --git a/src/include/port.h b/src/include/port.h index 74a9dc4d4d5..30b6378ae56 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -3,7 +3,7 @@ * port.h * Header for src/port/ compatibility functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port.h @@ -48,7 +48,7 @@ extern char *first_dir_separator(const char *filename); extern char *last_dir_separator(const char *filename); extern char *first_path_var_separator(const char *pathlist); extern void join_path_components(char *ret_path, - const char *head, const char *tail); + const char *head, const char *tail); extern void canonicalize_path(char *path); extern void make_native_path(char *path); extern void cleanup_path(char *path); @@ -104,8 +104,8 @@ extern void set_pglocale_pgservice(const char *argv0, const char *app); /* Portable way to find binaries (in exec.c) */ extern int find_my_exec(const char *argv0, char *retpath); -extern int find_other_exec(const char *argv0, const char *target, - const char *versionstr, char *retpath); +extern int find_other_exec(const char *argv0, const char *target, + const char *versionstr, char *retpath); /* Doesn't belong here, but this is used with find_other_exec(), so... */ #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" @@ -134,7 +134,12 @@ extern unsigned char pg_tolower(unsigned char ch); extern unsigned char pg_ascii_toupper(unsigned char ch); extern unsigned char pg_ascii_tolower(unsigned char ch); -#ifdef USE_REPL_SNPRINTF +/* + * Beginning in v12, we always replace snprintf() and friends with our own + * implementation. This symbol is no longer consulted by the core code, + * but keep it defined anyway in case any extensions are looking at it. + */ +#define USE_REPL_SNPRINTF 1 /* * Versions of libintl >= 0.13 try to replace printf() and friends with @@ -147,6 +152,9 @@ extern unsigned char pg_ascii_tolower(unsigned char ch); #ifdef snprintf #undef snprintf #endif +#ifdef vsprintf +#undef vsprintf +#endif #ifdef sprintf #undef sprintf #endif @@ -156,42 +164,57 @@ extern unsigned char pg_ascii_tolower(unsigned char ch); #ifdef fprintf #undef fprintf #endif +#ifdef vprintf +#undef vprintf +#endif #ifdef printf #undef printf #endif extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); +extern int pg_vsprintf(char *str, const char *fmt, va_list args); extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args); extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); +extern int pg_vprintf(const char *fmt, va_list args); extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); /* - * The GCC-specific code below prevents the pg_attribute_printf above from - * being replaced, and this is required because gcc doesn't know anything - * about pg_printf. + * We use __VA_ARGS__ for printf to prevent replacing references to + * the "printf" format archetype in format() attribute declarations. + * That unfortunately means that taking a function pointer to printf + * will not do what we'd wish. (If you need to do that, you must name + * pg_printf explicitly.) For printf's sibling functions, use + * parameterless macros so that function pointers will work unsurprisingly. */ -#ifdef __GNUC__ -#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) -#define snprintf(...) pg_snprintf(__VA_ARGS__) -#define sprintf(...) pg_sprintf(__VA_ARGS__) -#define vfprintf(...) pg_vfprintf(__VA_ARGS__) -#define fprintf(...) pg_fprintf(__VA_ARGS__) -#define printf(...) pg_printf(__VA_ARGS__) -#else #define vsnprintf pg_vsnprintf #define snprintf pg_snprintf +#define vsprintf pg_vsprintf #define sprintf pg_sprintf #define vfprintf pg_vfprintf #define fprintf pg_fprintf -#define printf pg_printf -#endif -#endif /* USE_REPL_SNPRINTF */ +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +/* This is also provided by snprintf.c */ +extern int pg_strfromd(char *str, size_t count, int precision, double value); + +/* Replace strerror() with our own, somewhat more robust wrapper */ +extern char *pg_strerror(int errnum); +#define strerror pg_strerror + +/* Likewise for strerror_r(); note we prefer the GNU API for that */ +extern char *pg_strerror_r(int errnum, char *buf, size_t buflen); +#define strerror_r pg_strerror_r +#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */ + +/* Wrap strsignal(), or provide our own version if necessary */ +extern const char *pg_strsignal(int signum); /* Portable prompt handling */ extern void simple_prompt(const char *prompt, char *destination, size_t destlen, - bool echo); + bool echo); extern int pclose_check(FILE *stream); @@ -249,11 +272,8 @@ extern bool rmtree(const char *path, bool rmtopdir); #define O_DIRECT 0x80000000 extern int pgwin32_open(const char *, int,...); extern FILE *pgwin32_fopen(const char *, const char *); - -#ifndef FRONTEND #define open(a,b,c) pgwin32_open(a,b,c) #define fopen(a,b) pgwin32_fopen(a,b) -#endif /* * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want @@ -310,9 +330,6 @@ extern int gettimeofday(struct timeval *tp, struct timezone *tzp); * Default "extern" declarations or macro substitutes for library routines. * When necessary, these routines are provided by files in src/port/. */ -#ifndef HAVE_CRYPT -extern char *crypt(const char *key, const char *setting); -#endif /* WIN32 handled in port/win32_port.h */ #ifndef WIN32 @@ -347,17 +364,33 @@ extern int isinf(double x); /* * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version * newer than the gcc compatibility clang claims to have. This would cause a - * *lot* of superfluous function calls, therefore revert when using clang. + * *lot* of superfluous function calls, therefore revert when using clang. In + * C++ there's issues with libc++ (not libstdc++), so disable as well. */ -#ifdef __clang__ +#if defined(__clang__) && !defined(__cplusplus) /* needs to be separate to not confuse other compilers */ #if __has_builtin(__builtin_isinf) +/* need to include before, to avoid getting overwritten */ +#include #undef isinf #define isinf __builtin_isinf #endif /* __has_builtin(isinf) */ -#endif /* __clang__ */ +#endif /* __clang__ && !__cplusplus */ #endif /* !HAVE_ISINF */ +#ifndef HAVE_EXPLICIT_BZERO +extern void explicit_bzero(void *buf, size_t len); +#endif + +#ifndef HAVE_STRTOF +extern float strtof(const char *nptr, char **endptr); +#endif + +#ifdef HAVE_BUGGY_STRTOF +extern float pg_strtof(const char *nptr, char **endptr); +#define strtof(a,b) (pg_strtof((a),(b))) +#endif + #ifndef HAVE_MKDTEMP extern char *mkdtemp(char *path); #endif @@ -372,6 +405,23 @@ extern double rint(double x); extern int inet_aton(const char *cp, struct in_addr *addr); #endif +/* + * Windows and older Unix don't have pread(2) and pwrite(2). We have + * replacement functions, but they have slightly different semantics so we'll + * use a name with a pg_ prefix to avoid confusion. + */ +#ifdef HAVE_PREAD +#define pg_pread pread +#else +extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset); +#endif + +#ifdef HAVE_PWRITE +#define pg_pwrite pwrite +#else +extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset); +#endif + #if !HAVE_DECL_STRLCAT extern size_t strlcat(char *dst, const char *src, size_t siz); #endif @@ -400,22 +450,43 @@ extern void srandom(unsigned int seed); #define SSL_get_current_compression(x) 0 #endif -/* thread.h */ -extern char *pqStrerror(int errnum, char *strerrbuf, size_t buflen); +#ifndef HAVE_DLOPEN +extern void *dlopen(const char *file, int mode); +extern void *dlsym(void *handle, const char *symbol); +extern int dlclose(void *handle); +extern char *dlerror(void); +#endif + +/* + * In some older systems, the RTLD_NOW flag isn't defined and the mode + * argument to dlopen must always be 1. + */ +#if !HAVE_DECL_RTLD_NOW +#define RTLD_NOW 1 +#endif + +/* + * The RTLD_GLOBAL flag is wanted if available, but it doesn't exist + * everywhere. If it doesn't exist, set it to 0 so it has no effect. + */ +#if !HAVE_DECL_RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif +/* thread.h */ #ifndef WIN32 -extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, - size_t buflen, struct passwd **result); +extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, + size_t buflen, struct passwd **result); #endif -extern int pqGethostbyname(const char *name, - struct hostent *resultbuf, - char *buffer, size_t buflen, - struct hostent **result, - int *herrno); +extern int pqGethostbyname(const char *name, + struct hostent *resultbuf, + char *buffer, size_t buflen, + struct hostent **result, + int *herrno); extern void pg_qsort(void *base, size_t nel, size_t elsize, - int (*cmp) (const void *, const void *)); + int (*cmp) (const void *, const void *)); extern int pg_qsort_strcmp(const void *a, const void *b); #define qsort(a,b,c,d) pg_qsort(a,b,c,d) @@ -423,7 +494,7 @@ extern int pg_qsort_strcmp(const void *a, const void *b); typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); extern void qsort_arg(void *base, size_t nel, size_t elsize, - qsort_arg_comparator cmp, void *arg); + qsort_arg_comparator cmp, void *arg); /* port/chklocale.c */ extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); @@ -433,13 +504,17 @@ extern int pg_codepage_to_encoding(UINT cp); #endif /* port/inet_net_ntop.c */ -extern char *inet_net_ntop(int af, const void *src, int bits, - char *dst, size_t size); +extern char *pg_inet_net_ntop(int af, const void *src, int bits, + char *dst, size_t size); /* port/pg_strong_random.c */ -#ifdef HAVE_STRONG_RANDOM extern bool pg_strong_random(void *buf, size_t len); -#endif + +/* + * pg_backend_random used to be a wrapper for pg_strong_random before + * Postgres 12 for the backend code. + */ +#define pg_backend_random pg_strong_random /* port/pgcheckdir.c */ extern int pg_check_dir(const char *dir); @@ -459,7 +534,9 @@ extern pqsigfunc pqsignal_no_restart(int signo, pqsigfunc func); /* port/quotes.c */ extern char *escape_single_quotes_ascii(const char *src); -/* port/wait_error.c */ +/* common/wait_error.c */ extern char *wait_result_to_str(int exit_status); +extern bool wait_result_is_signal(int exit_status, int signum); +extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found); #endif /* PG_PORT_H */ diff --git a/src/include/port/atomics.h b/src/include/port/atomics.h index 04703916755..fab66f8e987 100644 --- a/src/include/port/atomics.h +++ b/src/include/port/atomics.h @@ -28,7 +28,7 @@ * For an introduction to using memory barriers within the PostgreSQL backend, * see src/backend/storage/lmgr/README.barrier * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port/atomics.h @@ -178,7 +178,7 @@ pg_atomic_init_flag(volatile pg_atomic_flag *ptr) } /* - * pg_atomic_test_and_set_flag - TAS() + * pg_atomic_test_set_flag - TAS() * * Returns true if the flag has successfully been set, false otherwise. * diff --git a/src/include/port/atomics/arch-arm.h b/src/include/port/atomics/arch-arm.h index 99fe3bbfd24..ca78eb699d0 100644 --- a/src/include/port/atomics/arch-arm.h +++ b/src/include/port/atomics/arch-arm.h @@ -3,7 +3,7 @@ * arch-arm.h * Atomic operations considerations specific to ARM * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * NOTES: * diff --git a/src/include/port/atomics/arch-hppa.h b/src/include/port/atomics/arch-hppa.h index 818a3e0c872..43c2e56bfa0 100644 --- a/src/include/port/atomics/arch-hppa.h +++ b/src/include/port/atomics/arch-hppa.h @@ -3,7 +3,7 @@ * arch-hppa.h * Atomic operations considerations specific to HPPA * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/arch-ia64.h b/src/include/port/atomics/arch-ia64.h index 571a79ee670..e1cf56f954b 100644 --- a/src/include/port/atomics/arch-ia64.h +++ b/src/include/port/atomics/arch-ia64.h @@ -3,7 +3,7 @@ * arch-ia64.h * Atomic operations considerations specific to intel itanium * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/arch-ppc.h b/src/include/port/atomics/arch-ppc.h index faeb7a5d155..344b39449bd 100644 --- a/src/include/port/atomics/arch-ppc.h +++ b/src/include/port/atomics/arch-ppc.h @@ -3,7 +3,7 @@ * arch-ppc.h * Atomic operations considerations specific to PowerPC * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/arch-x86.h b/src/include/port/atomics/arch-x86.h index 5a3d95e056c..79f79a16034 100644 --- a/src/include/port/atomics/arch-x86.h +++ b/src/include/port/atomics/arch-x86.h @@ -7,7 +7,7 @@ * support for xadd and cmpxchg. Given that the 386 isn't supported anywhere * anymore that's not much of a restriction luckily. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/fallback.h b/src/include/port/atomics/fallback.h index 88a967ad5b9..b69465cbcba 100644 --- a/src/include/port/atomics/fallback.h +++ b/src/include/port/atomics/fallback.h @@ -4,7 +4,7 @@ * Fallback for platforms without spinlock and/or atomics support. Slower * than native atomics support, but not unusably slow. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port/atomics/fallback.h diff --git a/src/include/port/atomics/generic-acc.h b/src/include/port/atomics/generic-acc.h index bd6caaf8174..a64c841f4f1 100644 --- a/src/include/port/atomics/generic-acc.h +++ b/src/include/port/atomics/generic-acc.h @@ -3,7 +3,7 @@ * generic-acc.h * Atomic operations support when using HPs acc on HPUX * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: @@ -68,7 +68,7 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, _Asm_mf(); /* * Notes: - * DOWN_MEM_FENCE | _UP_MEM_FENCE prevents reordering by the compiler + * _DOWN_MEM_FENCE | _UP_MEM_FENCE prevents reordering by the compiler */ current = _Asm_cmpxchg(_SZ_W, /* word */ _SEM_REL, diff --git a/src/include/port/atomics/generic-gcc.h b/src/include/port/atomics/generic-gcc.h index 3a1dc883778..ba3a5f5f666 100644 --- a/src/include/port/atomics/generic-gcc.h +++ b/src/include/port/atomics/generic-gcc.h @@ -3,7 +3,7 @@ * generic-gcc.h * Atomic operations, implemented using gcc (or compatible) intrinsics. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/generic-msvc.h b/src/include/port/atomics/generic-msvc.h index 59211c22035..b53f0eec418 100644 --- a/src/include/port/atomics/generic-msvc.h +++ b/src/include/port/atomics/generic-msvc.h @@ -3,7 +3,7 @@ * generic-msvc.h * Atomic operations support when using MSVC * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * NOTES: diff --git a/src/include/port/atomics/generic-sunpro.h b/src/include/port/atomics/generic-sunpro.h index e903243b687..4b03c66ad3c 100644 --- a/src/include/port/atomics/generic-sunpro.h +++ b/src/include/port/atomics/generic-sunpro.h @@ -3,7 +3,7 @@ * generic-sunpro.h * Atomic operations for solaris' CC * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * NOTES: * diff --git a/src/include/port/atomics/generic-xlc.h b/src/include/port/atomics/generic-xlc.h index f18207568cf..8b5c7329706 100644 --- a/src/include/port/atomics/generic-xlc.h +++ b/src/include/port/atomics/generic-xlc.h @@ -3,7 +3,7 @@ * generic-xlc.h * Atomic operations for IBM's CC * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * * NOTES: * @@ -73,11 +73,27 @@ pg_atomic_compare_exchange_u32_impl(volatile pg_atomic_uint32 *ptr, static inline uint32 pg_atomic_fetch_add_u32_impl(volatile pg_atomic_uint32 *ptr, int32 add_) { + uint32 _t; + uint32 res; + /* - * __fetch_and_add() emits a leading "sync" and trailing "isync", thereby - * providing sequential consistency. This is undocumented. + * xlc has a no-longer-documented __fetch_and_add() intrinsic. In xlc + * 12.01.0000.0000, it emits a leading "sync" and trailing "isync". In + * xlc 13.01.0003.0004, it emits neither. Hence, using the intrinsic + * would add redundant syncs on xlc 12. */ - return __fetch_and_add((volatile int *)&ptr->value, add_); + __asm__ __volatile__( + " sync \n" + " lwarx %1,0,%4 \n" + " add %0,%1,%3 \n" + " stwcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to lwarx */ + " isync \n" +: "=&r"(_t), "=&r"(res), "+m"(ptr->value) +: "r"(add_), "r"(&ptr->value) +: "memory", "cc"); + + return res; } #ifdef PG_HAVE_ATOMIC_U64_SUPPORT @@ -103,7 +119,22 @@ pg_atomic_compare_exchange_u64_impl(volatile pg_atomic_uint64 *ptr, static inline uint64 pg_atomic_fetch_add_u64_impl(volatile pg_atomic_uint64 *ptr, int64 add_) { - return __fetch_and_addlp((volatile long *)&ptr->value, add_); + uint64 _t; + uint64 res; + + /* Like u32, but s/lwarx/ldarx/; s/stwcx/stdcx/ */ + __asm__ __volatile__( + " sync \n" + " ldarx %1,0,%4 \n" + " add %0,%1,%3 \n" + " stdcx. %0,0,%4 \n" + " bne $-12 \n" /* branch to ldarx */ + " isync \n" +: "=&r"(_t), "=&r"(res), "+m"(ptr->value) +: "r"(add_), "r"(&ptr->value) +: "memory", "cc"); + + return res; } #endif /* PG_HAVE_ATOMIC_U64_SUPPORT */ diff --git a/src/include/port/atomics/generic.h b/src/include/port/atomics/generic.h index ea11698a358..ffe4530ddd0 100644 --- a/src/include/port/atomics/generic.h +++ b/src/include/port/atomics/generic.h @@ -4,7 +4,7 @@ * Implement higher level operations based on some lower level atomic * operations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port/atomics/generic.h diff --git a/src/include/port/cygwin.h b/src/include/port/cygwin.h index 5c149470c68..f1fc1a93d76 100644 --- a/src/include/port/cygwin.h +++ b/src/include/port/cygwin.h @@ -16,3 +16,11 @@ #endif #define PGDLLEXPORT + +/* + * Cygwin has a strtof() which is literally just (float)strtod(), which means + * we get misrounding _and_ silent over/underflow. Using our wrapper doesn't + * fix the misrounding but does fix the error checks, which cuts down on the + * number of test variant files needed. + */ +#define HAVE_BUGGY_STRTOF 1 diff --git a/src/include/port/pg_bitutils.h b/src/include/port/pg_bitutils.h new file mode 100644 index 00000000000..5197926696f --- /dev/null +++ b/src/include/port/pg_bitutils.h @@ -0,0 +1,139 @@ +/*------------------------------------------------------------------------- + * + * pg_bitutils.h + * Miscellaneous functions for bit-wise operations. + * + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * src/include/port/pg_bitutils.h + * + *------------------------------------------------------------------------- + */ +#ifndef PG_BITUTILS_H +#define PG_BITUTILS_H + +extern PGDLLIMPORT const uint8 pg_leftmost_one_pos[256]; +extern PGDLLIMPORT const uint8 pg_rightmost_one_pos[256]; +extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; + +/* + * pg_leftmost_one_pos32 + * Returns the position of the most significant set bit in "word", + * measured from the least significant bit. word must not be 0. + */ +static inline int +pg_leftmost_one_pos32(uint32 word) +{ +#ifdef HAVE__BUILTIN_CLZ + Assert(word != 0); + + return 31 - __builtin_clz(word); +#else + int shift = 32 - 8; + + Assert(word != 0); + + while ((word >> shift) == 0) + shift -= 8; + + return shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif /* HAVE__BUILTIN_CLZ */ +} + +/* + * pg_leftmost_one_pos64 + * As above, but for a 64-bit word. + */ +static inline int +pg_leftmost_one_pos64(uint64 word) +{ +#ifdef HAVE__BUILTIN_CLZ + Assert(word != 0); + +#if defined(HAVE_LONG_INT_64) + return 63 - __builtin_clzl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + return 63 - __builtin_clzll(word); +#else +#error must have a working 64-bit integer datatype +#endif +#else /* !HAVE__BUILTIN_CLZ */ + int shift = 64 - 8; + + Assert(word != 0); + + while ((word >> shift) == 0) + shift -= 8; + + return shift + pg_leftmost_one_pos[(word >> shift) & 255]; +#endif /* HAVE__BUILTIN_CLZ */ +} + +/* + * pg_rightmost_one_pos32 + * Returns the position of the least significant set bit in "word", + * measured from the least significant bit. word must not be 0. + */ +static inline int +pg_rightmost_one_pos32(uint32 word) +{ +#ifdef HAVE__BUILTIN_CTZ + Assert(word != 0); + + return __builtin_ctz(word); +#else + int result = 0; + + Assert(word != 0); + + while ((word & 255) == 0) + { + word >>= 8; + result += 8; + } + result += pg_rightmost_one_pos[word & 255]; + return result; +#endif /* HAVE__BUILTIN_CTZ */ +} + +/* + * pg_rightmost_one_pos64 + * As above, but for a 64-bit word. + */ +static inline int +pg_rightmost_one_pos64(uint64 word) +{ +#ifdef HAVE__BUILTIN_CTZ + Assert(word != 0); + +#if defined(HAVE_LONG_INT_64) + return __builtin_ctzl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + return __builtin_ctzll(word); +#else +#error must have a working 64-bit integer datatype +#endif +#else /* !HAVE__BUILTIN_CTZ */ + int result = 0; + + Assert(word != 0); + + while ((word & 255) == 0) + { + word >>= 8; + result += 8; + } + result += pg_rightmost_one_pos[word & 255]; + return result; +#endif /* HAVE__BUILTIN_CTZ */ +} + +/* Count the number of one-bits in a uint32 or uint64 */ +extern int (*pg_popcount32) (uint32 word); +extern int (*pg_popcount64) (uint64 word); + +/* Count the number of one-bits in a byte array */ +extern uint64 pg_popcount(const char *buf, int bytes); + +#endif /* PG_BITUTILS_H */ diff --git a/src/include/port/pg_bswap.h b/src/include/port/pg_bswap.h index 0f09c05d6f9..dbf9df61559 100644 --- a/src/include/port/pg_bswap.h +++ b/src/include/port/pg_bswap.h @@ -11,7 +11,7 @@ * return the same. Use caution when using these wrapper macros with signed * integers. * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * src/include/port/pg_bswap.h * @@ -102,7 +102,7 @@ pg_bswap64(uint64 x) /* - * Portable and fast equivalents for for ntohs, ntohl, htons, htonl, + * Portable and fast equivalents for ntohs, ntohl, htons, htonl, * additionally extended to 64 bits. */ #ifdef WORDS_BIGENDIAN diff --git a/src/include/port/pg_crc32c.h b/src/include/port/pg_crc32c.h index 9a26295c8e8..fbd079d2439 100644 --- a/src/include/port/pg_crc32c.h +++ b/src/include/port/pg_crc32c.h @@ -23,7 +23,7 @@ * EQ_CRC32C(c1, c2) * Check for equality of two CRCs. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port/pg_crc32c.h diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h index d31c28f7d44..1cf166a570d 100644 --- a/src/include/port/win32_port.h +++ b/src/include/port/win32_port.h @@ -6,7 +6,7 @@ * Note this is read in MinGW as well as native Windows builds, * but not in Cygwin builds. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/port/win32_port.h @@ -171,8 +171,6 @@ #define SIGTSTP 18 #define SIGCONT 19 #define SIGCHLD 20 -#define SIGTTIN 21 -#define SIGTTOU 22 /* Same as SIGABRT -- no problem, I hope */ #define SIGWINCH 28 #define SIGUSR1 30 #define SIGUSR2 31 @@ -322,8 +320,8 @@ extern int pgwin32_safestat(const char *path, struct stat *buf); * Supplement to . * * We redefine network-related Berkeley error symbols as the corresponding WSA - * constants. This allows elog.c to recognize them as being in the Winsock - * error code range and pass them off to pgwin32_socket_strerror(), since + * constants. This allows strerror.c to recognize them as being in the Winsock + * error code range and pass them off to win32_socket_strerror(), since * Windows' version of plain strerror() won't cope. Note that this will break * if these names are used for anything else besides Windows Sockets errors. * See TranslateSocketError() when changing this list. @@ -453,11 +451,9 @@ int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen); int pgwin32_listen(SOCKET s, int backlog); SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen); int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen); -int pgwin32_select(int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout); +int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout); int pgwin32_recv(SOCKET s, char *buf, int len, int flags); int pgwin32_send(SOCKET s, const void *buf, int len, int flags); - -const char *pgwin32_socket_strerror(int err); int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout); extern int pgwin32_noblock; @@ -502,7 +498,14 @@ typedef unsigned short mode_t; #define W_OK 2 #define R_OK 4 +/* + * isinf() and isnan() should per spec be in , but MSVC older than + * 2013 does not have them there. It does have _fpclass() and _isnan(), but + * they're in , so include that here even though it means float.h + * percolates to our whole tree. Recent versions don't require any of this. + */ #if (_MSC_VER < 1800) +#include #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) || (_fpclass(x) == _FPCLASS_NINF)) #define isnan(x) _isnan(x) #endif @@ -512,4 +515,23 @@ typedef unsigned short mode_t; #endif /* _MSC_VER */ +#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || \ + defined(__MINGW32__) || defined(__MINGW64__) +/* + * VS2013 has a strtof() that seems to give correct answers for valid input, + * even on the rounding edge cases, but which doesn't handle out-of-range + * input correctly. Work around that. + * + * Mingw claims to have a strtof, and my reading of its source code suggests + * that it ought to work (and not need this hack), but the regression test + * results disagree with me; whether this is a version issue or not is not + * clear. However, using our wrapper (and the misrounded-input variant file, + * already required for supporting ancient systems) can't make things any + * worse, except for a tiny performance loss when reading zeros. + * + * See also cygwin.h for another instance of this. + */ +#define HAVE_BUGGY_STRTOF 1 +#endif + #endif /* PG_WIN32_PORT_H */ diff --git a/src/include/portability/instr_time.h b/src/include/portability/instr_time.h index f968444671c..0f5c16136a9 100644 --- a/src/include/portability/instr_time.h +++ b/src/include/portability/instr_time.h @@ -20,6 +20,9 @@ * * INSTR_TIME_SET_CURRENT(t) set t to current time * + * INSTR_TIME_SET_CURRENT_LAZY(t) set t to current time if t is zero, + * evaluates to whether t changed + * * INSTR_TIME_ADD(x, y) x += y * * INSTR_TIME_SUBTRACT(x, y) x -= y @@ -43,7 +46,7 @@ * Beware of multiple evaluations of the macro arguments. * * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/include/portability/instr_time.h * @@ -245,4 +248,9 @@ GetTimerFrequency(void) #endif /* WIN32 */ +/* same macro on all platforms */ + +#define INSTR_TIME_SET_CURRENT_LAZY(t) \ + (INSTR_TIME_IS_ZERO(t) ? INSTR_TIME_SET_CURRENT(t), true : false) + #endif /* INSTR_TIME_H */ diff --git a/src/include/portability/mem.h b/src/include/portability/mem.h index ba183f53682..a085c6f242e 100644 --- a/src/include/portability/mem.h +++ b/src/include/portability/mem.h @@ -3,7 +3,7 @@ * mem.h * portability definitions for various memory operations * - * Copyright (c) 2001-2018, PostgreSQL Global Development Group + * Copyright (c) 2001-2019, PostgreSQL Global Development Group * * src/include/portability/mem.h * diff --git a/src/include/postgres.h b/src/include/postgres.h index bbcb50e41fc..057a3413acd 100644 --- a/src/include/postgres.h +++ b/src/include/postgres.h @@ -7,7 +7,7 @@ * Client-side code should include postgres_fe.h instead. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * * src/include/postgres.h @@ -321,6 +321,8 @@ typedef struct (VARATT_IS_EXTERNAL(PTR) && VARTAG_EXTERNAL(PTR) == VARTAG_EXPANDED_RW) #define VARATT_IS_EXTERNAL_EXPANDED(PTR) \ (VARATT_IS_EXTERNAL(PTR) && VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR))) +#define VARATT_IS_EXTERNAL_NON_EXPANDED(PTR) \ + (VARATT_IS_EXTERNAL(PTR) && !VARTAG_IS_EXPANDED(VARTAG_EXTERNAL(PTR))) #define VARATT_IS_SHORT(PTR) VARATT_IS_1B(PTR) #define VARATT_IS_EXTENDED(PTR) (!VARATT_IS_4B_U(PTR)) @@ -364,6 +366,21 @@ typedef struct typedef uintptr_t Datum; +/* + * A NullableDatum is used in places where both a Datum and its nullness needs + * to be stored. This can be more efficient than storing datums and nullness + * in separate arrays, due to better spatial locality, even if more space may + * be wasted due to padding. + */ +typedef struct NullableDatum +{ +#define FIELDNO_NULLABLE_DATUM_DATUM 0 + Datum value; +#define FIELDNO_NULLABLE_DATUM_ISNULL 1 + bool isnull; + /* due to alignment padding this could be used for flags for free */ +} NullableDatum; + #define SIZEOF_DATUM SIZEOF_VOID_P /* diff --git a/src/include/postgres_fe.h b/src/include/postgres_fe.h index 14567953f24..f55cebd7b41 100644 --- a/src/include/postgres_fe.h +++ b/src/include/postgres_fe.h @@ -8,7 +8,7 @@ * postgres.h. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * * src/include/postgres_fe.h diff --git a/src/include/postmaster/autovacuum.h b/src/include/postmaster/autovacuum.h index 96752caed8d..8451e5d9e27 100644 --- a/src/include/postmaster/autovacuum.h +++ b/src/include/postmaster/autovacuum.h @@ -4,7 +4,7 @@ * header file for integrated autovacuum daemon * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/postmaster/autovacuum.h @@ -37,7 +37,7 @@ extern int autovacuum_anl_thresh; extern double autovacuum_anl_scale; extern int autovacuum_freeze_max_age; extern int autovacuum_multixact_freeze_max_age; -extern int autovacuum_vac_cost_delay; +extern double autovacuum_vac_cost_delay; extern int autovacuum_vac_cost_limit; /* autovacuum launcher PID, only valid when worker is shutting down */ @@ -72,7 +72,7 @@ extern void AutovacuumLauncherIAm(void); #endif extern bool AutoVacuumRequestWork(AutoVacuumWorkItemType type, - Oid relationId, BlockNumber blkno); + Oid relationId, BlockNumber blkno); /* shared memory stuff */ extern Size AutoVacuumShmemSize(void); diff --git a/src/include/postmaster/bgworker.h b/src/include/postmaster/bgworker.h index 9c49bb7f4b0..8786a2a351e 100644 --- a/src/include/postmaster/bgworker.h +++ b/src/include/postmaster/bgworker.h @@ -31,7 +31,7 @@ * different) code. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -115,11 +115,11 @@ extern void RegisterBackgroundWorker(BackgroundWorker *worker); /* Register a new bgworker from a regular backend */ extern bool RegisterDynamicBackgroundWorker(BackgroundWorker *worker, - BackgroundWorkerHandle **handle); + BackgroundWorkerHandle **handle); /* Query the status of a bgworker */ extern BgwHandleStatus GetBackgroundWorkerPid(BackgroundWorkerHandle *handle, - pid_t *pidp); + pid_t *pidp); extern BgwHandleStatus WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pid); extern BgwHandleStatus WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *); @@ -145,11 +145,18 @@ extern void BackgroundWorkerInitializeConnection(const char *dbname, const char /* Just like the above, but specifying database and user by OID. */ extern void BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid, uint32 flags); -/* Flags to BackgroundWorkerInitializeConnection et al */ +/* + * Flags to BackgroundWorkerInitializeConnection et al + * + * + * Allow bypassing datallowconn restrictions when connecting to database + */ #define BGWORKER_BYPASS_ALLOWCONN 1 + /* Block/unblock signals in a background worker process */ extern void BackgroundWorkerBlockSignals(void); extern void BackgroundWorkerUnblockSignals(void); +extern void BackgroundWorkerShmemAttach(void); #endif /* BGWORKER_H */ diff --git a/src/include/postmaster/bgworker_internals.h b/src/include/postmaster/bgworker_internals.h index 548dc1c1466..e98fc4a0860 100644 --- a/src/include/postmaster/bgworker_internals.h +++ b/src/include/postmaster/bgworker_internals.h @@ -2,7 +2,7 @@ * bgworker_internals.h * POSTGRES pluggable background workers internals * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -56,8 +56,8 @@ extern void ResetBackgroundWorkerCrashTimes(void); /* Function to start a background worker, called from postmaster.c */ extern void StartBackgroundWorker(void) pg_attribute_noreturn(); -#ifdef EXEC_BACKEND extern BackgroundWorker *BackgroundWorkerEntry(int slotno); -#endif +extern void SetBackgroundWorkerEntries(void* entries); +extern void* GetBackgroundWorkerEntries(void); #endif /* BGWORKER_INTERNALS_H */ diff --git a/src/include/postmaster/bgwriter.h b/src/include/postmaster/bgwriter.h index 941c6aba7d1..630366f49ef 100644 --- a/src/include/postmaster/bgwriter.h +++ b/src/include/postmaster/bgwriter.h @@ -6,7 +6,7 @@ * The bgwriter process used to handle checkpointing duties too. Now * there is a separate process, but we did not bother to split this header. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/postmaster/bgwriter.h * @@ -17,6 +17,8 @@ #include "storage/block.h" #include "storage/relfilenode.h" +#include "storage/smgr.h" +#include "storage/sync.h" /* GUC options */ @@ -31,9 +33,9 @@ extern void CheckpointerMain(void) pg_attribute_noreturn(); extern void RequestCheckpoint(int flags); extern void CheckpointWriteDelay(int flags, double progress); -extern bool ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, - BlockNumber segno); -extern void AbsorbFsyncRequests(void); +extern bool ForwardSyncRequest(const FileTag *ftag, SyncRequestType type); + +extern void AbsorbSyncRequests(void); extern Size CheckpointerShmemSize(void); extern void CheckpointerShmemInit(void); diff --git a/src/include/postmaster/fork_process.h b/src/include/postmaster/fork_process.h index d552e0297c9..eb3c8ec9748 100644 --- a/src/include/postmaster/fork_process.h +++ b/src/include/postmaster/fork_process.h @@ -3,7 +3,7 @@ * fork_process.h * Exports from postmaster/fork_process.c. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/postmaster/fork_process.h * diff --git a/src/include/postmaster/pgarch.h b/src/include/postmaster/pgarch.h index 292e63a26a5..2474eac26a5 100644 --- a/src/include/postmaster/pgarch.h +++ b/src/include/postmaster/pgarch.h @@ -3,7 +3,7 @@ * pgarch.h * Exports from postmaster/pgarch.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/postmaster/pgarch.h diff --git a/src/include/postmaster/postmaster.h b/src/include/postmaster/postmaster.h index 1877eef2391..4aea0a36422 100644 --- a/src/include/postmaster/postmaster.h +++ b/src/include/postmaster/postmaster.h @@ -3,7 +3,7 @@ * postmaster.h * Exports from postmaster/postmaster.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/postmaster/postmaster.h @@ -29,6 +29,7 @@ extern bool log_hostname; extern bool enable_bonjour; extern char *bonjour_name; extern bool restart_after_crash; +extern char* OnlineUpgradePath; #ifdef WIN32 extern HANDLE PostmasterHandle; @@ -48,10 +49,10 @@ extern PGDLLIMPORT const char *progname; extern void PostmasterMain(int argc, char *argv[]) pg_attribute_noreturn(); extern void ClosePostmasterPorts(bool am_syslogger); +extern void InitProcessGlobals(void); extern int MaxLivePostmasterChildren(void); -extern int GetNumShmemAttachedBgworkers(void); extern bool PostmasterMarkPIDForWorkerNotify(int); #ifdef EXEC_BACKEND diff --git a/src/include/postmaster/startup.h b/src/include/postmaster/startup.h index 1bef7239b2e..7b3a089932e 100644 --- a/src/include/postmaster/startup.h +++ b/src/include/postmaster/startup.h @@ -3,7 +3,7 @@ * startup.h * Exports from postmaster/startup.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/postmaster/startup.h * diff --git a/src/include/postmaster/syslogger.h b/src/include/postmaster/syslogger.h index b35fadc1bd0..3a611045736 100644 --- a/src/include/postmaster/syslogger.h +++ b/src/include/postmaster/syslogger.h @@ -3,7 +3,7 @@ * syslogger.h * Exports from postmaster/syslogger.c. * - * Copyright (c) 2004-2018, PostgreSQL Global Development Group + * Copyright (c) 2004-2019, PostgreSQL Global Development Group * * src/include/postmaster/syslogger.h * @@ -87,6 +87,9 @@ extern void write_syslogger_file(const char *buffer, int count, int dest); extern void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn(); #endif +extern bool CheckLogrotateSignal(void); +extern void RemoveLogrotateSignalFiles(void); + /* * Name of files saving meta-data information about the log * files currently in use by the syslogger diff --git a/src/include/postmaster/walwriter.h b/src/include/postmaster/walwriter.h index 26ec256b967..ae267d2411e 100644 --- a/src/include/postmaster/walwriter.h +++ b/src/include/postmaster/walwriter.h @@ -3,7 +3,7 @@ * walwriter.h * Exports from postmaster/walwriter.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/postmaster/walwriter.h * diff --git a/src/include/regex/regex.h b/src/include/regex/regex.h index 27fdc090409..dc31899aa4d 100644 --- a/src/include/regex/regex.h +++ b/src/include/regex/regex.h @@ -167,10 +167,18 @@ typedef struct /* * the prototypes for exported functions */ + +/* regcomp.c */ extern int pg_regcomp(regex_t *, const pg_wchar *, size_t, int, Oid); extern int pg_regexec(regex_t *, const pg_wchar *, size_t, size_t, rm_detail_t *, size_t, regmatch_t[], int); extern int pg_regprefix(regex_t *, pg_wchar **, size_t *); extern void pg_regfree(regex_t *); extern size_t pg_regerror(int, const regex_t *, char *, size_t); +/* regexp.c */ +extern regex_t *RE_compile_and_cache(text *text_re, int cflags, Oid collation); +extern bool RE_compile_and_execute(text *text_re, char *dat, int dat_len, + int cflags, Oid collation, + int nmatch, regmatch_t *pmatch); + #endif /* _REGEX_H_ */ diff --git a/src/include/regex/regexport.h b/src/include/regex/regexport.h index ff6ff3d7913..972fb604a97 100644 --- a/src/include/regex/regexport.h +++ b/src/include/regex/regexport.h @@ -17,7 +17,7 @@ * line and start/end of string. Colors are numbered 0..C-1, but note that * color 0 is "white" (all unused characters) and can generally be ignored. * - * Portions Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2013-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1998, 1999 Henry Spencer * * IDENTIFICATION @@ -44,7 +44,7 @@ extern int pg_reg_getinitialstate(const regex_t *regex); extern int pg_reg_getfinalstate(const regex_t *regex); extern int pg_reg_getnumoutarcs(const regex_t *regex, int st); extern void pg_reg_getoutarcs(const regex_t *regex, int st, - regex_arc_t *arcs, int arcs_len); + regex_arc_t *arcs, int arcs_len); /* Functions for gathering information about colors */ extern int pg_reg_getnumcolors(const regex_t *regex); @@ -52,6 +52,6 @@ extern int pg_reg_colorisbegin(const regex_t *regex, int co); extern int pg_reg_colorisend(const regex_t *regex, int co); extern int pg_reg_getnumcharacters(const regex_t *regex, int co); extern void pg_reg_getcharacters(const regex_t *regex, int co, - pg_wchar *chars, int chars_len); + pg_wchar *chars, int chars_len); #endif /* _REGEXPORT_H_ */ diff --git a/src/include/replication/basebackup.h b/src/include/replication/basebackup.h index 941d07b99f1..503a5b9f0b1 100644 --- a/src/include/replication/basebackup.h +++ b/src/include/replication/basebackup.h @@ -3,7 +3,7 @@ * basebackup.h * Exports from replication/basebackup.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * src/include/replication/basebackup.h * diff --git a/src/include/replication/decode.h b/src/include/replication/decode.h index 0e63c0b296f..89689a010b2 100644 --- a/src/include/replication/decode.h +++ b/src/include/replication/decode.h @@ -2,7 +2,7 @@ * decode.h * PostgreSQL WAL to logical transformation * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -14,7 +14,7 @@ #include "replication/reorderbuffer.h" #include "replication/logical.h" -void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, - XLogReaderState *record); +void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, + XLogReaderState *record); #endif diff --git a/src/include/replication/logical.h b/src/include/replication/logical.h index 619c5f4d73e..31c796b7651 100644 --- a/src/include/replication/logical.h +++ b/src/include/replication/logical.h @@ -2,7 +2,7 @@ * logical.h * PostgreSQL logical decoding coordination * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -17,8 +17,7 @@ struct LogicalDecodingContext; -typedef void (*LogicalOutputPluginWriterWrite) ( - struct LogicalDecodingContext *lr, +typedef void (*LogicalOutputPluginWriterWrite) (struct LogicalDecodingContext *lr, XLogRecPtr Ptr, TransactionId xid, bool last_write @@ -26,8 +25,7 @@ typedef void (*LogicalOutputPluginWriterWrite) ( typedef LogicalOutputPluginWriterWrite LogicalOutputPluginWriterPrepareWrite; -typedef void (*LogicalOutputPluginWriterUpdateProgress) ( - struct LogicalDecodingContext *lr, +typedef void (*LogicalOutputPluginWriterUpdateProgress) (struct LogicalDecodingContext *lr, XLogRecPtr Ptr, TransactionId xid ); @@ -46,11 +44,11 @@ typedef struct LogicalDecodingContext struct SnapBuild *snapshot_builder; /* - * Marks the logical decoding context as fast forward decoding one. - * Such a context does not have plugin loaded so most of the the following - * properties are unused. + * Marks the logical decoding context as fast forward decoding one. Such a + * context does not have plugin loaded so most of the following properties + * are unused. */ - bool fast_forward; + bool fast_forward; OutputPluginCallbacks callbacks; OutputPluginOptions options; @@ -95,27 +93,27 @@ typedef struct LogicalDecodingContext extern void CheckLogicalDecodingRequirements(void); extern LogicalDecodingContext *CreateInitDecodingContext(char *plugin, - List *output_plugin_options, - bool need_full_snapshot, - XLogPageReadCB read_page, - LogicalOutputPluginWriterPrepareWrite prepare_write, - LogicalOutputPluginWriterWrite do_write, - LogicalOutputPluginWriterUpdateProgress update_progress); -extern LogicalDecodingContext *CreateDecodingContext( - XLogRecPtr start_lsn, - List *output_plugin_options, - bool fast_forward, - XLogPageReadCB read_page, - LogicalOutputPluginWriterPrepareWrite prepare_write, - LogicalOutputPluginWriterWrite do_write, - LogicalOutputPluginWriterUpdateProgress update_progress); + List *output_plugin_options, + bool need_full_snapshot, + XLogRecPtr restart_lsn, + XLogPageReadCB read_page, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write, + LogicalOutputPluginWriterUpdateProgress update_progress); +extern LogicalDecodingContext *CreateDecodingContext(XLogRecPtr start_lsn, + List *output_plugin_options, + bool fast_forward, + XLogPageReadCB read_page, + LogicalOutputPluginWriterPrepareWrite prepare_write, + LogicalOutputPluginWriterWrite do_write, + LogicalOutputPluginWriterUpdateProgress update_progress); extern void DecodingContextFindStartpoint(LogicalDecodingContext *ctx); extern bool DecodingContextReady(LogicalDecodingContext *ctx); extern void FreeDecodingContext(LogicalDecodingContext *ctx); extern void LogicalIncreaseXminForSlot(XLogRecPtr lsn, TransactionId xmin); extern void LogicalIncreaseRestartDecodingForSlot(XLogRecPtr current_lsn, - XLogRecPtr restart_lsn); + XLogRecPtr restart_lsn); extern void LogicalConfirmReceivedLocation(XLogRecPtr lsn); extern bool filter_by_origin_cb_wrapper(LogicalDecodingContext *ctx, RepOriginId origin_id); diff --git a/src/include/replication/logicalfuncs.h b/src/include/replication/logicalfuncs.h index 4236b40bc67..012096f183d 100644 --- a/src/include/replication/logicalfuncs.h +++ b/src/include/replication/logicalfuncs.h @@ -2,7 +2,7 @@ * logicalfuncs.h * PostgreSQL WAL to logical transformation support functions * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ @@ -11,9 +11,9 @@ #include "replication/logical.h" -extern int logical_read_local_xlog_page(XLogReaderState *state, - XLogRecPtr targetPagePtr, - int reqLen, XLogRecPtr targetRecPtr, - char *cur_page, TimeLineID *pageTLI); +extern int logical_read_local_xlog_page(XLogReaderState *state, + XLogRecPtr targetPagePtr, + int reqLen, XLogRecPtr targetRecPtr, + char *cur_page); #endif diff --git a/src/include/replication/logicallauncher.h b/src/include/replication/logicallauncher.h index ef02512412e..f8759241d7f 100644 --- a/src/include/replication/logicallauncher.h +++ b/src/include/replication/logicallauncher.h @@ -3,7 +3,7 @@ * logicallauncher.h * Exports for logical replication launcher. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/replication/logicallauncher.h * @@ -24,6 +24,7 @@ extern void ApplyLauncherShmemInit(void); extern void ApplyLauncherWakeupAtCommit(void); extern bool XactManipulatesLogicalReplicationWorkers(void); extern void AtEOXact_ApplyLauncher(bool isCommit); +extern void AtEOSubXact_ApplyLauncher(bool isCommit, int nestDepth); extern bool IsLogicalLauncher(void); diff --git a/src/include/replication/logicalproto.h b/src/include/replication/logicalproto.h index 92e88d31279..3fc430af013 100644 --- a/src/include/replication/logicalproto.h +++ b/src/include/replication/logicalproto.h @@ -3,7 +3,7 @@ * logicalproto.h * logical replication protocol * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/replication/logicalproto.h @@ -19,8 +19,8 @@ /* * Protocol capabilities * - * LOGICAL_PROTO_VERSION_NUM is our native protocol and the greatest version - * we can support. PGLOGICAL_PROTO_MIN_VERSION_NUM is the oldest version we + * LOGICALREP_PROTO_VERSION_NUM is our native protocol and the greatest version + * we can support. LOGICALREP_PROTO_MIN_VERSION_NUM is the oldest version we * have backwards compatibility for. The client requests protocol version at * connect time. */ @@ -77,33 +77,33 @@ typedef struct LogicalRepCommitData extern void logicalrep_write_begin(StringInfo out, ReorderBufferTXN *txn); extern void logicalrep_read_begin(StringInfo in, - LogicalRepBeginData *begin_data); + LogicalRepBeginData *begin_data); extern void logicalrep_write_commit(StringInfo out, ReorderBufferTXN *txn, - XLogRecPtr commit_lsn); + XLogRecPtr commit_lsn); extern void logicalrep_read_commit(StringInfo in, - LogicalRepCommitData *commit_data); + LogicalRepCommitData *commit_data); extern void logicalrep_write_origin(StringInfo out, const char *origin, - XLogRecPtr origin_lsn); + XLogRecPtr origin_lsn); extern char *logicalrep_read_origin(StringInfo in, XLogRecPtr *origin_lsn); extern void logicalrep_write_insert(StringInfo out, Relation rel, - HeapTuple newtuple); + HeapTuple newtuple); extern LogicalRepRelId logicalrep_read_insert(StringInfo in, LogicalRepTupleData *newtup); extern void logicalrep_write_update(StringInfo out, Relation rel, HeapTuple oldtuple, - HeapTuple newtuple); + HeapTuple newtuple); extern LogicalRepRelId logicalrep_read_update(StringInfo in, - bool *has_oldtuple, LogicalRepTupleData *oldtup, - LogicalRepTupleData *newtup); + bool *has_oldtuple, LogicalRepTupleData *oldtup, + LogicalRepTupleData *newtup); extern void logicalrep_write_delete(StringInfo out, Relation rel, - HeapTuple oldtuple); + HeapTuple oldtuple); extern LogicalRepRelId logicalrep_read_delete(StringInfo in, - LogicalRepTupleData *oldtup); + LogicalRepTupleData *oldtup); extern void logicalrep_write_truncate(StringInfo out, int nrelids, Oid relids[], - bool cascade, bool restart_seqs); + bool cascade, bool restart_seqs); extern List *logicalrep_read_truncate(StringInfo in, - bool *cascade, bool *restart_seqs); + bool *cascade, bool *restart_seqs); extern void logicalrep_write_rel(StringInfo out, Relation rel); extern LogicalRepRelation *logicalrep_read_rel(StringInfo in); extern void logicalrep_write_typ(StringInfo out, Oid typoid); extern void logicalrep_read_typ(StringInfo out, LogicalRepTyp *ltyp); -#endif /* LOGICALREP_PROTO_H */ +#endif /* LOGICAL_PROTO_H */ diff --git a/src/include/replication/logicalrelation.h b/src/include/replication/logicalrelation.h index 73e48058270..2642a3f94ec 100644 --- a/src/include/replication/logicalrelation.h +++ b/src/include/replication/logicalrelation.h @@ -3,7 +3,7 @@ * logicalrelation.h * Relation definitions for logical replication relation mapping. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/replication/logicalrelation.h * @@ -32,9 +32,9 @@ typedef struct LogicalRepRelMapEntry extern void logicalrep_relmap_update(LogicalRepRelation *remoterel); extern LogicalRepRelMapEntry *logicalrep_rel_open(LogicalRepRelId remoteid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void logicalrep_rel_close(LogicalRepRelMapEntry *rel, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void logicalrep_typmap_update(LogicalRepTyp *remotetyp); extern char *logicalrep_typmap_gettypname(Oid remoteid); diff --git a/src/include/replication/logicalworker.h b/src/include/replication/logicalworker.h index 6379aae7ceb..e9524aefd9f 100644 --- a/src/include/replication/logicalworker.h +++ b/src/include/replication/logicalworker.h @@ -3,7 +3,7 @@ * logicalworker.h * Exports for logical replication workers. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/replication/logicalworker.h * diff --git a/src/include/replication/message.h b/src/include/replication/message.h index 37e1bd32d6a..a2e3f6c8026 100644 --- a/src/include/replication/message.h +++ b/src/include/replication/message.h @@ -2,7 +2,7 @@ * message.h * Exports from replication/logical/message.c * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * src/include/replication/message.h *------------------------------------------------------------------------- @@ -31,7 +31,7 @@ typedef struct xl_logical_message #define SizeOfLogicalMessage (offsetof(xl_logical_message, message)) extern XLogRecPtr LogLogicalMessage(const char *prefix, const char *message, - size_t size, bool transactional); + size_t size, bool transactional); /* RMGR API*/ #define XLOG_LOGICAL_MESSAGE 0x00 diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h index 34fc01207d5..dccf48418ff 100644 --- a/src/include/replication/origin.h +++ b/src/include/replication/origin.h @@ -2,7 +2,7 @@ * origin.h * Exports from replication/logical/origin.c * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * src/include/replication/origin.h *------------------------------------------------------------------------- @@ -10,7 +10,6 @@ #ifndef PG_ORIGIN_H #define PG_ORIGIN_H -#include "fmgr.h" #include "access/xlog.h" #include "access/xlogdefs.h" #include "access/xlogreader.h" @@ -43,17 +42,17 @@ extern RepOriginId replorigin_by_name(char *name, bool missing_ok); extern RepOriginId replorigin_create(char *name); extern void replorigin_drop(RepOriginId roident, bool nowait); extern bool replorigin_by_oid(RepOriginId roident, bool missing_ok, - char **roname); + char **roname); /* API for querying & manipulating replication progress tracking */ extern void replorigin_advance(RepOriginId node, - XLogRecPtr remote_commit, - XLogRecPtr local_commit, - bool go_backward, bool wal_log); + XLogRecPtr remote_commit, + XLogRecPtr local_commit, + bool go_backward, bool wal_log); extern XLogRecPtr replorigin_get_progress(RepOriginId node, bool flush); extern void replorigin_session_advance(XLogRecPtr remote_commit, - XLogRecPtr local_commit); + XLogRecPtr local_commit); extern void replorigin_session_setup(RepOriginId node); extern void replorigin_session_reset(void); extern XLogRecPtr replorigin_session_get_progress(bool flush); diff --git a/src/include/replication/output_plugin.h b/src/include/replication/output_plugin.h index 1ee0a56f034..d4ce54f26d7 100644 --- a/src/include/replication/output_plugin.h +++ b/src/include/replication/output_plugin.h @@ -2,7 +2,7 @@ * output_plugin.h * PostgreSQL Logical Decode Plugin Interface * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ diff --git a/src/include/replication/pgoutput.h b/src/include/replication/pgoutput.h index 29178da1d17..8870721bcd8 100644 --- a/src/include/replication/pgoutput.h +++ b/src/include/replication/pgoutput.h @@ -3,7 +3,7 @@ * pgoutput.h * Logical Replication output plugin * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * pgoutput.h diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 3867ce89505..4c06a78c11f 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -2,7 +2,7 @@ * reorderbuffer.h * PostgreSQL logical replay/reorder buffer management. * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * src/include/replication/reorderbuffer.h */ @@ -101,8 +101,8 @@ typedef struct ReorderBufferChange } tp; /* - * Truncate data for REORDER_BUFFER_CHANGE_TRUNCATE representing - * one set of relations to be truncated. + * Truncate data for REORDER_BUFFER_CHANGE_TRUNCATE representing one + * set of relations to be truncated. */ struct { @@ -110,7 +110,7 @@ typedef struct ReorderBufferChange bool cascade; bool restart_seqs; Oid *relids; - } truncate; + } truncate; /* Message with arbitrary data. */ struct @@ -160,10 +160,9 @@ typedef struct ReorderBufferTXN /* did the TX have catalog changes */ bool has_catalog_changes; - /* - * Do we know this is a subxact? - */ + /* Do we know this is a subxact? Xid of top-level txn if so */ bool is_known_as_subxact; + TransactionId toplevel_xid; /* * LSN of the first data carrying, WAL record with knowledge about this @@ -209,10 +208,13 @@ typedef struct ReorderBufferTXN TimestampTz commit_time; /* - * Base snapshot or NULL. + * The base snapshot is used to decode all changes until either this + * transaction modifies the catalog, or another catalog-modifying + * transaction commits. */ Snapshot base_snapshot; XLogRecPtr base_snapshot_lsn; + dlist_node base_snapshot_node; /* link in txns_by_base_snapshot_lsn */ /* * How many ReorderBufferChange's do we have in this txn. @@ -279,7 +281,7 @@ typedef struct ReorderBufferTXN * Position in one of three lists: * * list of subtransactions if we are *known* to be subxact * * list of toplevel xacts (can be an as-yet unknown subxact) - * * list of preallocated ReorderBufferTXNs + * * list of preallocated ReorderBufferTXNs (if unused) * --- */ dlist_node node; @@ -290,34 +292,29 @@ typedef struct ReorderBufferTXN typedef struct ReorderBuffer ReorderBuffer; /* change callback signature */ -typedef void (*ReorderBufferApplyChangeCB) ( - ReorderBuffer *rb, +typedef void (*ReorderBufferApplyChangeCB) (ReorderBuffer *rb, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change); /* truncate callback signature */ -typedef void (*ReorderBufferApplyTruncateCB) ( - ReorderBuffer *rb, +typedef void (*ReorderBufferApplyTruncateCB) (ReorderBuffer *rb, ReorderBufferTXN *txn, int nrelations, Relation relations[], ReorderBufferChange *change); /* begin callback signature */ -typedef void (*ReorderBufferBeginCB) ( - ReorderBuffer *rb, +typedef void (*ReorderBufferBeginCB) (ReorderBuffer *rb, ReorderBufferTXN *txn); /* commit callback signature */ -typedef void (*ReorderBufferCommitCB) ( - ReorderBuffer *rb, +typedef void (*ReorderBufferCommitCB) (ReorderBuffer *rb, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); /* message callback signature */ -typedef void (*ReorderBufferMessageCB) ( - ReorderBuffer *rb, +typedef void (*ReorderBufferMessageCB) (ReorderBuffer *rb, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, @@ -337,6 +334,15 @@ struct ReorderBuffer */ dlist_head toplevel_by_lsn; + /* + * Transactions and subtransactions that have a base snapshot, ordered by + * LSN of the record which caused us to first obtain the base snapshot. + * This is not the same as toplevel_by_lsn, because we only set the base + * snapshot on the first logical-decoding-relevant record (eg. heap + * writes), whereas the initial LSN could be set by other operations. + */ + dlist_head txns_by_base_snapshot_lsn; + /* * one-entry sized cache for by_txn. Very frequently the same txn gets * looked up over and over again. @@ -391,37 +397,41 @@ void ReorderBufferReturnTupleBuf(ReorderBuffer *, ReorderBufferTupleBuf *tuple) ReorderBufferChange *ReorderBufferGetChange(ReorderBuffer *); void ReorderBufferReturnChange(ReorderBuffer *, ReorderBufferChange *); +Oid *ReorderBufferGetRelids(ReorderBuffer *, int nrelids); +void ReorderBufferReturnRelids(ReorderBuffer *, Oid *relids); + void ReorderBufferQueueChange(ReorderBuffer *, TransactionId, XLogRecPtr lsn, ReorderBufferChange *); -void ReorderBufferQueueMessage(ReorderBuffer *, TransactionId, Snapshot snapshot, XLogRecPtr lsn, - bool transactional, const char *prefix, - Size message_size, const char *message); -void ReorderBufferCommit(ReorderBuffer *, TransactionId, - XLogRecPtr commit_lsn, XLogRecPtr end_lsn, - TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn); +void ReorderBufferQueueMessage(ReorderBuffer *, TransactionId, Snapshot snapshot, XLogRecPtr lsn, + bool transactional, const char *prefix, + Size message_size, const char *message); +void ReorderBufferCommit(ReorderBuffer *, TransactionId, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn, + TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn); void ReorderBufferAssignChild(ReorderBuffer *, TransactionId, TransactionId, XLogRecPtr commit_lsn); -void ReorderBufferCommitChild(ReorderBuffer *, TransactionId, TransactionId, - XLogRecPtr commit_lsn, XLogRecPtr end_lsn); +void ReorderBufferCommitChild(ReorderBuffer *, TransactionId, TransactionId, + XLogRecPtr commit_lsn, XLogRecPtr end_lsn); void ReorderBufferAbort(ReorderBuffer *, TransactionId, XLogRecPtr lsn); void ReorderBufferAbortOld(ReorderBuffer *, TransactionId xid); void ReorderBufferForget(ReorderBuffer *, TransactionId, XLogRecPtr lsn); void ReorderBufferSetBaseSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap); void ReorderBufferAddSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap); -void ReorderBufferAddNewCommandId(ReorderBuffer *, TransactionId, XLogRecPtr lsn, - CommandId cid); -void ReorderBufferAddNewTupleCids(ReorderBuffer *, TransactionId, XLogRecPtr lsn, - RelFileNode node, ItemPointerData pt, - CommandId cmin, CommandId cmax, CommandId combocid); -void ReorderBufferAddInvalidations(ReorderBuffer *, TransactionId, XLogRecPtr lsn, - Size nmsgs, SharedInvalidationMessage *msgs); -void ReorderBufferImmediateInvalidation(ReorderBuffer *, uint32 ninvalidations, - SharedInvalidationMessage *invalidations); +void ReorderBufferAddNewCommandId(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + CommandId cid); +void ReorderBufferAddNewTupleCids(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + RelFileNode node, ItemPointerData pt, + CommandId cmin, CommandId cmax, CommandId combocid); +void ReorderBufferAddInvalidations(ReorderBuffer *, TransactionId, XLogRecPtr lsn, + Size nmsgs, SharedInvalidationMessage *msgs); +void ReorderBufferImmediateInvalidation(ReorderBuffer *, uint32 ninvalidations, + SharedInvalidationMessage *invalidations); void ReorderBufferProcessXid(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn); void ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn); bool ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid); bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid); ReorderBufferTXN *ReorderBufferGetOldestTXN(ReorderBuffer *); +TransactionId ReorderBufferGetOldestXmin(ReorderBuffer *rb); void ReorderBufferSetRestartPoint(ReorderBuffer *, XLogRecPtr ptr); diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h index 76a88c6de78..3a5763fb07a 100644 --- a/src/include/replication/slot.h +++ b/src/include/replication/slot.h @@ -2,14 +2,13 @@ * slot.h * Replication slot management. * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * *------------------------------------------------------------------------- */ #ifndef SLOT_H #define SLOT_H -#include "fmgr.h" #include "access/xlog.h" #include "access/xlogreader.h" #include "storage/condition_variable.h" @@ -86,6 +85,19 @@ typedef struct ReplicationSlotPersistentData /* * Shared memory state of a single replication slot. + * + * The in-memory data of replication slots follows a locking model based + * on two linked concepts: + * - A replication slot's in_use flag is switched when added or discarded using + * the LWLock ReplicationSlotControlLock, which needs to be hold in exclusive + * mode when updating the flag by the backend owning the slot and doing the + * operation, while readers (concurrent backends not owning the slot) need + * to hold it in shared mode when looking at replication slot data. + * - Individual fields are protected by mutex where only the backend owning + * the slot is authorized to update the fields from its own slot. The + * backend owning the slot does not need to take this lock when reading its + * own fields, while concurrent backends not owning this slot should take the + * lock when reading this slot's data. */ typedef struct ReplicationSlot { @@ -156,7 +168,7 @@ typedef struct ReplicationSlotCtlData /* * Pointers to shared memory */ -extern ReplicationSlotCtlData *ReplicationSlotCtl; +extern PGDLLIMPORT ReplicationSlotCtlData *ReplicationSlotCtl; extern PGDLLIMPORT ReplicationSlot *MyReplicationSlot; /* GUCs */ @@ -168,7 +180,7 @@ extern void ReplicationSlotsShmemInit(void); /* management of individual slots */ extern void ReplicationSlotCreate(const char *name, bool db_specific, - ReplicationSlotPersistency p); + ReplicationSlotPersistency p); extern void ReplicationSlotPersist(void); extern void ReplicationSlotDrop(const char *name, bool nowait); diff --git a/src/include/replication/snapbuild.h b/src/include/replication/snapbuild.h index 56257430aea..392fe1609ba 100644 --- a/src/include/replication/snapbuild.h +++ b/src/include/replication/snapbuild.h @@ -3,7 +3,7 @@ * snapbuild.h * Exports from replication/logical/snapbuild.c. * - * Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Copyright (c) 2012-2019, PostgreSQL Global Development Group * * src/include/replication/snapbuild.h * @@ -60,8 +60,8 @@ struct xl_running_xacts; extern void CheckPointSnapBuild(void); extern SnapBuild *AllocateSnapshotBuilder(struct ReorderBuffer *cache, - TransactionId xmin_horizon, XLogRecPtr start_lsn, - bool need_full_snapshot); + TransactionId xmin_horizon, XLogRecPtr start_lsn, + bool need_full_snapshot); extern void FreeSnapshotBuilder(SnapBuild *cache); extern void SnapBuildSnapDecRefcount(Snapshot snap); @@ -72,19 +72,19 @@ extern void SnapBuildClearExportedSnapshot(void); extern SnapBuildState SnapBuildCurrentState(SnapBuild *snapstate); extern Snapshot SnapBuildGetOrBuildSnapshot(SnapBuild *builder, - TransactionId xid); + TransactionId xid); extern bool SnapBuildXactNeedsSkip(SnapBuild *snapstate, XLogRecPtr ptr); extern void SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn, - TransactionId xid, int nsubxacts, - TransactionId *subxacts); + TransactionId xid, int nsubxacts, + TransactionId *subxacts); extern bool SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, - XLogRecPtr lsn); + XLogRecPtr lsn); extern void SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid, - XLogRecPtr lsn, struct xl_heap_new_cid *cid); + XLogRecPtr lsn, struct xl_heap_new_cid *cid); extern void SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn, - struct xl_running_xacts *running); + struct xl_running_xacts *running); extern void SnapBuildSerializationPoint(SnapBuild *builder, XLogRecPtr lsn); #endif /* SNAPBUILD_H */ diff --git a/src/include/replication/syncrep.h b/src/include/replication/syncrep.h index bc43b4e1090..913a8b08ce9 100644 --- a/src/include/replication/syncrep.h +++ b/src/include/replication/syncrep.h @@ -3,7 +3,7 @@ * syncrep.h * Exports from replication/syncrep.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/replication/syncrep.h diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h index 76268ceb23f..e12a9349660 100644 --- a/src/include/replication/walreceiver.h +++ b/src/include/replication/walreceiver.h @@ -3,7 +3,7 @@ * walreceiver.h * Exports from replication/walreceiverfuncs.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * src/include/replication/walreceiver.h * @@ -14,7 +14,6 @@ #include "access/xlog.h" #include "access/xlogdefs.h" -#include "fmgr.h" #include "getaddrinfo.h" /* for NI_MAXHOST */ #include "replication/logicalproto.h" #include "replication/walsender.h" @@ -110,8 +109,8 @@ typedef struct char conninfo[MAXCONNINFO]; /* - * Host name (this can be a host name, an IP address, or a directory - * path) and port number of the active replication connection. + * Host name (this can be a host name, an IP address, or a directory path) + * and port number of the active replication connection. */ char sender_host[NI_MAXHOST]; int sender_port; @@ -188,7 +187,7 @@ typedef enum } WalRcvExecStatus; /* - * Return value for walrcv_query, returns the status of the execution and + * Return value for walrcv_exec, returns the status of the execution and * tuples if any. */ typedef struct WalRcvExecResult @@ -206,11 +205,11 @@ typedef WalReceiverConn *(*walrcv_connect_fn) (const char *conninfo, bool logica typedef void (*walrcv_check_conninfo_fn) (const char *conninfo); typedef char *(*walrcv_get_conninfo_fn) (WalReceiverConn *conn); typedef void (*walrcv_get_senderinfo_fn) (WalReceiverConn *conn, - char **sender_host, - int *sender_port); + char **sender_host, + int *sender_port); typedef char *(*walrcv_identify_system_fn) (WalReceiverConn *conn, - TimeLineID *primary_tli, - int *server_version); + TimeLineID *primary_tli); +typedef int (*walrcv_server_version_fn) (WalReceiverConn *conn); typedef void (*walrcv_readtimelinehistoryfile_fn) (WalReceiverConn *conn, TimeLineID tli, char **filename, @@ -240,6 +239,7 @@ typedef struct WalReceiverFunctionsType walrcv_get_conninfo_fn walrcv_get_conninfo; walrcv_get_senderinfo_fn walrcv_get_senderinfo; walrcv_identify_system_fn walrcv_identify_system; + walrcv_server_version_fn walrcv_server_version; walrcv_readtimelinehistoryfile_fn walrcv_readtimelinehistoryfile; walrcv_startstreaming_fn walrcv_startstreaming; walrcv_endstreaming_fn walrcv_endstreaming; @@ -260,8 +260,10 @@ extern PGDLLIMPORT WalReceiverFunctionsType *WalReceiverFunctions; WalReceiverFunctions->walrcv_get_conninfo(conn) #define walrcv_get_senderinfo(conn, sender_host, sender_port) \ WalReceiverFunctions->walrcv_get_senderinfo(conn, sender_host, sender_port) -#define walrcv_identify_system(conn, primary_tli, server_version) \ - WalReceiverFunctions->walrcv_identify_system(conn, primary_tli, server_version) +#define walrcv_identify_system(conn, primary_tli) \ + WalReceiverFunctions->walrcv_identify_system(conn, primary_tli) +#define walrcv_server_version(conn) \ + WalReceiverFunctions->walrcv_server_version(conn) #define walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) \ WalReceiverFunctions->walrcv_readtimelinehistoryfile(conn, tli, filename, content, size) #define walrcv_startstreaming(conn, options) \ @@ -299,6 +301,7 @@ walrcv_clear_result(WalRcvExecResult *walres) /* prototypes for functions in walreceiver.c */ extern void WalReceiverMain(void) pg_attribute_noreturn(); +extern void ProcessWalRcvInterrupts(void); /* prototypes for functions in walreceiverfuncs.c */ extern Size WalRcvShmemSize(void); @@ -307,7 +310,7 @@ extern void ShutdownWalRcv(void); extern bool WalRcvStreaming(void); extern bool WalRcvRunning(void); extern void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, - const char *conninfo, const char *slotname); + const char *conninfo, const char *slotname); extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI); extern int GetReplicationApplyDelay(void); extern int GetReplicationTransferLatency(void); diff --git a/src/include/replication/walsender.h b/src/include/replication/walsender.h index 45b72a76dbd..61223aecbc1 100644 --- a/src/include/replication/walsender.h +++ b/src/include/replication/walsender.h @@ -3,7 +3,7 @@ * walsender.h * Exports from replication/walsender.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * src/include/replication/walsender.h * @@ -14,8 +14,6 @@ #include -#include "fmgr.h" - /* * What to do with a snapshot in create replication slot command. */ diff --git a/src/include/replication/walsender_private.h b/src/include/replication/walsender_private.h index 4b904779361..0dd6d1cf808 100644 --- a/src/include/replication/walsender_private.h +++ b/src/include/replication/walsender_private.h @@ -3,7 +3,7 @@ * walsender_private.h * Private definitions from replication/walsender.c. * - * Portions Copyright (c) 2010-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2010-2019, PostgreSQL Global Development Group * * src/include/replication/walsender_private.h * @@ -75,6 +75,11 @@ typedef struct WalSnd * SyncRepLock. */ int sync_standby_priority; + + /* + * Timestamp of the last message received from standby. + */ + TimestampTz replyTime; } WalSnd; extern WalSnd *MyWalSnd; diff --git a/src/include/replication/worker_internal.h b/src/include/replication/worker_internal.h index 1ce3b6b0587..05f4936419a 100644 --- a/src/include/replication/worker_internal.h +++ b/src/include/replication/worker_internal.h @@ -3,7 +3,7 @@ * worker_internal.h * Internal headers shared by logical replication workers. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * src/include/replication/worker_internal.h * @@ -27,7 +27,7 @@ typedef struct LogicalRepWorker /* Indicates if this slot is used or free. */ bool in_use; - /* Increased everytime the slot is taken by new worker. */ + /* Increased every time the slot is taken by new worker. */ uint16 generation; /* Pointer to proc array. NULL if not running. */ @@ -70,10 +70,10 @@ extern bool in_remote_transaction; extern void logicalrep_worker_attach(int slot); extern LogicalRepWorker *logicalrep_worker_find(Oid subid, Oid relid, - bool only_running); + bool only_running); extern List *logicalrep_workers_find(Oid subid, bool only_running); extern void logicalrep_worker_launch(Oid dbid, Oid subid, const char *subname, - Oid userid, Oid relid); + Oid userid, Oid relid); extern void logicalrep_worker_stop(Oid subid, Oid relid); extern void logicalrep_worker_stop_at_commit(Oid subid, Oid relid); extern void logicalrep_worker_wakeup(Oid subid, Oid relid); @@ -83,8 +83,8 @@ extern int logicalrep_sync_worker_count(Oid subid); extern char *LogicalRepSyncTableStart(XLogRecPtr *origin_startpos); void process_syncing_tables(XLogRecPtr current_lsn); -void invalidate_syncing_table_states(Datum arg, int cacheid, - uint32 hashvalue); +void invalidate_syncing_table_states(Datum arg, int cacheid, + uint32 hashvalue); static inline bool am_tablesync_worker(void) diff --git a/src/include/rewrite/prs2lock.h b/src/include/rewrite/prs2lock.h index 9e7c87a8c14..07ca649359f 100644 --- a/src/include/rewrite/prs2lock.h +++ b/src/include/rewrite/prs2lock.h @@ -3,7 +3,7 @@ * prs2lock.h * data structures for POSTGRES Rule System II (rewrite rules only) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/prs2lock.h @@ -43,4 +43,4 @@ typedef struct RuleLock RewriteRule **rules; } RuleLock; -#endif /* REWRITE_H */ +#endif /* PRS2LOCK_H */ diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h index 4ceaaffee77..1b45985ea40 100644 --- a/src/include/rewrite/rewriteDefine.h +++ b/src/include/rewrite/rewriteDefine.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteDefine.h @@ -26,19 +26,19 @@ extern ObjectAddress DefineRule(RuleStmt *stmt, const char *queryString); extern ObjectAddress DefineQueryRewrite(const char *rulename, - Oid event_relid, - Node *event_qual, - CmdType event_type, - bool is_instead, - bool replace, - List *action); + Oid event_relid, + Node *event_qual, + CmdType event_type, + bool is_instead, + bool replace, + List *action); extern ObjectAddress RenameRewriteRule(RangeVar *relation, const char *oldName, - const char *newName); + const char *newName); extern void setRuleCheckAsUser(Node *node, Oid userid); extern void EnableDisableRule(Relation rel, const char *rulename, - char fires_when); + char fires_when); #endif /* REWRITEDEFINE_H */ diff --git a/src/include/rewrite/rewriteHandler.h b/src/include/rewrite/rewriteHandler.h index 1ab5de39422..c55fe81a0a3 100644 --- a/src/include/rewrite/rewriteHandler.h +++ b/src/include/rewrite/rewriteHandler.h @@ -4,7 +4,7 @@ * External interface to query rewriter. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteHandler.h @@ -19,19 +19,18 @@ extern List *QueryRewrite(Query *parsetree); extern void AcquireRewriteLocks(Query *parsetree, - bool forExecute, - bool forUpdatePushedDown); + bool forExecute, + bool forUpdatePushedDown); extern Node *build_column_default(Relation rel, int attrno); extern void rewriteTargetListUD(Query *parsetree, RangeTblEntry *target_rte, - Relation target_relation); -extern void rewriteTargetListMerge(Query *parsetree, Relation target_relation); + Relation target_relation); extern Query *get_view_query(Relation view); extern const char *view_query_is_auto_updatable(Query *viewquery, - bool check_cols); -extern int relation_is_updatable(Oid reloid, - bool include_triggers, - Bitmapset *include_cols); + bool check_cols); +extern int relation_is_updatable(Oid reloid, + bool include_triggers, + Bitmapset *include_cols); #endif /* REWRITEHANDLER_H */ diff --git a/src/include/rewrite/rewriteManip.h b/src/include/rewrite/rewriteManip.h index f0299bc703d..8d8fd17e41c 100644 --- a/src/include/rewrite/rewriteManip.h +++ b/src/include/rewrite/rewriteManip.h @@ -4,7 +4,7 @@ * Querytree manipulation subroutines for query rewriter. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteManip.h @@ -41,14 +41,14 @@ typedef enum ReplaceVarsNoMatchOption extern void OffsetVarNodes(Node *node, int offset, int sublevels_up); extern void ChangeVarNodes(Node *node, int old_varno, int new_varno, - int sublevels_up); + int sublevels_up); extern void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, - int min_sublevels_up); + int min_sublevels_up); extern void IncrementVarSublevelsUp_rtable(List *rtable, - int delta_sublevels_up, int min_sublevels_up); + int delta_sublevels_up, int min_sublevels_up); extern bool rangeTableEntry_used(Node *node, int rt_index, - int sublevels_up); + int sublevels_up); extern Query *getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr); @@ -62,24 +62,24 @@ extern int locate_windowfunc(Node *node); extern bool checkExprHasSubLink(Node *node); extern Node *replace_rte_variables(Node *node, - int target_varno, int sublevels_up, - replace_rte_variables_callback callback, - void *callback_arg, - bool *outer_hasSubLinks); + int target_varno, int sublevels_up, + replace_rte_variables_callback callback, + void *callback_arg, + bool *outer_hasSubLinks); extern Node *replace_rte_variables_mutator(Node *node, - replace_rte_variables_context *context); + replace_rte_variables_context *context); extern Node *map_variable_attnos(Node *node, - int target_varno, int sublevels_up, - const AttrNumber *attno_map, int map_length, - Oid to_rowtype, bool *found_whole_row); + int target_varno, int sublevels_up, + const AttrNumber *attno_map, int map_length, + Oid to_rowtype, bool *found_whole_row); extern Node *ReplaceVarsFromTargetList(Node *node, - int target_varno, int sublevels_up, - RangeTblEntry *target_rte, - List *targetlist, - ReplaceVarsNoMatchOption nomatch_option, - int nomatch_varno, - bool *outer_hasSubLinks); + int target_varno, int sublevels_up, + RangeTblEntry *target_rte, + List *targetlist, + ReplaceVarsNoMatchOption nomatch_option, + int nomatch_varno, + bool *outer_hasSubLinks); #endif /* REWRITEMANIP_H */ diff --git a/src/include/rewrite/rewriteRemove.h b/src/include/rewrite/rewriteRemove.h index 351e26c307a..54cfecad5be 100644 --- a/src/include/rewrite/rewriteRemove.h +++ b/src/include/rewrite/rewriteRemove.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteRemove.h diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h index f34bfda05f0..ce84d62bd2e 100644 --- a/src/include/rewrite/rewriteSupport.h +++ b/src/include/rewrite/rewriteSupport.h @@ -4,7 +4,7 @@ * * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rewrite/rewriteSupport.h diff --git a/src/include/rewrite/rowsecurity.h b/src/include/rewrite/rowsecurity.h index f2f5251c713..214d556e506 100644 --- a/src/include/rewrite/rowsecurity.h +++ b/src/include/rewrite/rowsecurity.h @@ -5,7 +5,7 @@ * prototypes for rewrite/rowsecurity.c and the structures for managing * the row security policies for relations in relcache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * ------------------------------------------------------------------------- @@ -42,8 +42,8 @@ extern PGDLLIMPORT row_security_policy_hook_type row_security_policy_hook_permis extern PGDLLIMPORT row_security_policy_hook_type row_security_policy_hook_restrictive; extern void get_row_security_policies(Query *root, - RangeTblEntry *rte, int rt_index, - List **securityQuals, List **withCheckOptions, - bool *hasRowSecurity, bool *hasSubLinks); + RangeTblEntry *rte, int rt_index, + List **securityQuals, List **withCheckOptions, + bool *hasRowSecurity, bool *hasSubLinks); #endif /* ROWSECURITY_H */ diff --git a/src/include/rusagestub.h b/src/include/rusagestub.h index 1423e2699ed..53ad66a9d57 100644 --- a/src/include/rusagestub.h +++ b/src/include/rusagestub.h @@ -4,7 +4,7 @@ * Stubs for getrusage(3). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/rusagestub.h diff --git a/src/include/snowball/header.h b/src/include/snowball/header.h index c0450ae4ebf..5e5ab5a9f08 100644 --- a/src/include/snowball/header.h +++ b/src/include/snowball/header.h @@ -13,7 +13,7 @@ * * NOTE: this file should not be included into any non-snowball sources! * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/snowball/header.h * diff --git a/src/include/snowball/libstemmer/api.h b/src/include/snowball/libstemmer/api.h index 8b997f0c298..7ed7995f9e1 100644 --- a/src/include/snowball/libstemmer/api.h +++ b/src/include/snowball/libstemmer/api.h @@ -19,8 +19,15 @@ struct SN_env { unsigned char * B; }; +#ifdef __cplusplus +extern "C" { +#endif + extern struct SN_env * SN_create_env(int S_size, int I_size, int B_size); extern void SN_close_env(struct SN_env * z, int S_size); extern int SN_set_current(struct SN_env * z, int size, const symbol * s); +#ifdef __cplusplus +} +#endif diff --git a/src/include/snowball/libstemmer/header.h b/src/include/snowball/libstemmer/header.h index 4d3078f50f4..6bccf0f2c78 100644 --- a/src/include/snowball/libstemmer/header.h +++ b/src/include/snowball/libstemmer/header.h @@ -54,5 +54,7 @@ extern int insert_v(struct SN_env * z, int bra, int ket, const symbol * p); extern symbol * slice_to(struct SN_env * z, symbol * p); extern symbol * assign_to(struct SN_env * z, symbol * p); +extern int len_utf8(const symbol * p); + extern void debug(struct SN_env * z, int number, int line_count); diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h index 49c5559cdfc..57f16f8960d 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_danish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h index e67d11152cd..5423842969f 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_dutch.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h index e685dcf7ef0..d5a56a98f0b 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_english.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h index c67b67b944f..ba197d8a705 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_finnish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h index 21244d61621..29321023a2c 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_french.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h index 85253892278..0887ac81646 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_german.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h deleted file mode 100644 index c3177e5019c..00000000000 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_hungarian.h +++ /dev/null @@ -1,16 +0,0 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern struct SN_env * hungarian_ISO_8859_1_create_env(void); -extern void hungarian_ISO_8859_1_close_env(struct SN_env * z); - -extern int hungarian_ISO_8859_1_stem(struct SN_env * z); - -#ifdef __cplusplus -} -#endif - diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_indonesian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_indonesian.h new file mode 100644 index 00000000000..aac192cacea --- /dev/null +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_indonesian.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * indonesian_ISO_8859_1_create_env(void); +extern void indonesian_ISO_8859_1_close_env(struct SN_env * z); + +extern int indonesian_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_irish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_irish.h new file mode 100644 index 00000000000..0e146373aee --- /dev/null +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_irish.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * irish_ISO_8859_1_create_env(void); +extern void irish_ISO_8859_1_close_env(struct SN_env * z); + +extern int irish_ISO_8859_1_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h index dccbfd5e971..9e3fcf7f789 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_italian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h index e09e34e52f3..424c8cd4683 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_norwegian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h index 5c8fd01db17..99bc54ff0d1 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_porter.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h index 0279bc94da6..e9abc0de5fb 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_portuguese.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h index 83f1498403f..1e661aacfe4 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_spanish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h b/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h index 4184e5ca39e..5e6f6ac8afa 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_1_swedish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_2_hungarian.h b/src/include/snowball/libstemmer/stem_ISO_8859_2_hungarian.h new file mode 100644 index 00000000000..c019a7d4569 --- /dev/null +++ b/src/include/snowball/libstemmer/stem_ISO_8859_2_hungarian.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * hungarian_ISO_8859_2_create_env(void); +extern void hungarian_ISO_8859_2_close_env(struct SN_env * z); + +extern int hungarian_ISO_8859_2_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h b/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h index 931f269ceb2..ef9bd3f3a42 100644 --- a/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h +++ b/src/include/snowball/libstemmer/stem_ISO_8859_2_romanian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_KOI8_R_russian.h b/src/include/snowball/libstemmer/stem_KOI8_R_russian.h index de2179d29f0..cc58324c66c 100644 --- a/src/include/snowball/libstemmer/stem_KOI8_R_russian.h +++ b/src/include/snowball/libstemmer/stem_KOI8_R_russian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_arabic.h b/src/include/snowball/libstemmer/stem_UTF_8_arabic.h new file mode 100644 index 00000000000..5ef61a1031f --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_arabic.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * arabic_UTF_8_create_env(void); +extern void arabic_UTF_8_close_env(struct SN_env * z); + +extern int arabic_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_danish.h b/src/include/snowball/libstemmer/stem_UTF_8_danish.h index ed744d454f0..71f93155edb 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_danish.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_danish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_dutch.h b/src/include/snowball/libstemmer/stem_UTF_8_dutch.h index a99646452b0..6af7d0adf3d 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_dutch.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_dutch.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_english.h b/src/include/snowball/libstemmer/stem_UTF_8_english.h index 619a8bc72ae..d0ea10ef9f0 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_english.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_english.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_finnish.h b/src/include/snowball/libstemmer/stem_UTF_8_finnish.h index d2f2fd96383..7d07fbaf4a0 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_finnish.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_finnish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_french.h b/src/include/snowball/libstemmer/stem_UTF_8_french.h index 08e341846df..b19139e538b 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_french.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_french.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_german.h b/src/include/snowball/libstemmer/stem_UTF_8_german.h index 5bd84d431f0..2a95132e9f5 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_german.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_german.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_greek.h b/src/include/snowball/libstemmer/stem_UTF_8_greek.h new file mode 100644 index 00000000000..bf1cc6ca01f --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_greek.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * greek_UTF_8_create_env(void); +extern void greek_UTF_8_close_env(struct SN_env * z); + +extern int greek_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h b/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h index d81bd23469a..d662a836355 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_hungarian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_indonesian.h b/src/include/snowball/libstemmer/stem_UTF_8_indonesian.h new file mode 100644 index 00000000000..7e07e73c343 --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_indonesian.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * indonesian_UTF_8_create_env(void); +extern void indonesian_UTF_8_close_env(struct SN_env * z); + +extern int indonesian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_irish.h b/src/include/snowball/libstemmer/stem_UTF_8_irish.h new file mode 100644 index 00000000000..ea8b81860e1 --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_irish.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * irish_UTF_8_create_env(void); +extern void irish_UTF_8_close_env(struct SN_env * z); + +extern int irish_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_italian.h b/src/include/snowball/libstemmer/stem_UTF_8_italian.h index 3bee080d52c..4177c3ebf89 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_italian.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_italian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_lithuanian.h b/src/include/snowball/libstemmer/stem_UTF_8_lithuanian.h new file mode 100644 index 00000000000..8a9b1241a8a --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_lithuanian.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * lithuanian_UTF_8_create_env(void); +extern void lithuanian_UTF_8_close_env(struct SN_env * z); + +extern int lithuanian_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_nepali.h b/src/include/snowball/libstemmer/stem_UTF_8_nepali.h new file mode 100644 index 00000000000..20b2b919ac2 --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_nepali.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * nepali_UTF_8_create_env(void); +extern void nepali_UTF_8_close_env(struct SN_env * z); + +extern int nepali_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h b/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h index c75444bcd95..b155ebb7189 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_norwegian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_porter.h b/src/include/snowball/libstemmer/stem_UTF_8_porter.h index 82d469ac459..54efb6f130d 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_porter.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_porter.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h b/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h index 9fe7f9aa811..68dc2554c35 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_portuguese.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_romanian.h b/src/include/snowball/libstemmer/stem_UTF_8_romanian.h index d01e8132e20..2cc1ad011dc 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_romanian.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_romanian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_russian.h b/src/include/snowball/libstemmer/stem_UTF_8_russian.h index 4ef774ddccb..2bc621bff9e 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_russian.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_russian.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_spanish.h b/src/include/snowball/libstemmer/stem_UTF_8_spanish.h index 10572ecc370..075ba876ed8 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_spanish.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_spanish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_swedish.h b/src/include/snowball/libstemmer/stem_UTF_8_swedish.h index 1444ebb49a6..095623db804 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_swedish.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_swedish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/snowball/libstemmer/stem_UTF_8_tamil.h b/src/include/snowball/libstemmer/stem_UTF_8_tamil.h new file mode 100644 index 00000000000..65505dc028b --- /dev/null +++ b/src/include/snowball/libstemmer/stem_UTF_8_tamil.h @@ -0,0 +1,16 @@ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern struct SN_env * tamil_UTF_8_create_env(void); +extern void tamil_UTF_8_close_env(struct SN_env * z); + +extern int tamil_UTF_8_stem(struct SN_env * z); + +#ifdef __cplusplus +} +#endif + diff --git a/src/include/snowball/libstemmer/stem_UTF_8_turkish.h b/src/include/snowball/libstemmer/stem_UTF_8_turkish.h index 8173a174867..7d94a2f9efb 100644 --- a/src/include/snowball/libstemmer/stem_UTF_8_turkish.h +++ b/src/include/snowball/libstemmer/stem_UTF_8_turkish.h @@ -1,5 +1,5 @@ - -/* This file was generated automatically by the Snowball to ANSI C compiler */ +/* This file was generated automatically by the Snowball to ISO C compiler */ +/* http://snowballstem.org/ */ #ifdef __cplusplus extern "C" { diff --git a/src/include/statistics/extended_stats_internal.h b/src/include/statistics/extended_stats_internal.h index b3ca0c1229f..fcf4e8ae0b3 100644 --- a/src/include/statistics/extended_stats_internal.h +++ b/src/include/statistics/extended_stats_internal.h @@ -3,7 +3,7 @@ * extended_stats_internal.h * POSTGRES extended statistics internal declarations * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -31,11 +31,22 @@ typedef struct int tupno; /* position index for tuple it came from */ } ScalarItem; +/* (de)serialization info */ +typedef struct DimensionInfo +{ + int nvalues; /* number of deduplicated values */ + int nbytes; /* number of bytes (serialized) */ + int nbytes_aligned; /* size of deserialized data with alignment */ + int typlen; /* pg_type.typlen */ + bool typbyval; /* pg_type.typbyval */ +} DimensionInfo; + /* multi-sort */ typedef struct MultiSortSupportData { - int ndims; /* number of dimensions supported by the */ - SortSupportData ssup[1]; /* sort support data for each dimension */ + int ndims; /* number of dimensions */ + /* sort support data for each dimension: */ + SortSupportData ssup[FLEXIBLE_ARRAY_MEMBER]; } MultiSortSupportData; typedef MultiSortSupportData *MultiSortSupport; @@ -44,26 +55,59 @@ typedef struct SortItem { Datum *values; bool *isnull; + int count; } SortItem; extern MVNDistinct *statext_ndistinct_build(double totalrows, - int numrows, HeapTuple *rows, - Bitmapset *attrs, VacAttrStats **stats); + int numrows, HeapTuple *rows, + Bitmapset *attrs, VacAttrStats **stats); extern bytea *statext_ndistinct_serialize(MVNDistinct *ndistinct); extern MVNDistinct *statext_ndistinct_deserialize(bytea *data); extern MVDependencies *statext_dependencies_build(int numrows, HeapTuple *rows, - Bitmapset *attrs, VacAttrStats **stats); + Bitmapset *attrs, VacAttrStats **stats); extern bytea *statext_dependencies_serialize(MVDependencies *dependencies); extern MVDependencies *statext_dependencies_deserialize(bytea *data); +extern MCVList *statext_mcv_build(int numrows, HeapTuple *rows, + Bitmapset *attrs, VacAttrStats **stats, + double totalrows, int stattarget); +extern bytea *statext_mcv_serialize(MCVList *mcv, VacAttrStats **stats); +extern MCVList *statext_mcv_deserialize(bytea *data); + extern MultiSortSupport multi_sort_init(int ndims); extern void multi_sort_add_dimension(MultiSortSupport mss, int sortdim, - Oid oper); + Oid oper, Oid collation); extern int multi_sort_compare(const void *a, const void *b, void *arg); -extern int multi_sort_compare_dim(int dim, const SortItem *a, - const SortItem *b, MultiSortSupport mss); -extern int multi_sort_compare_dims(int start, int end, const SortItem *a, - const SortItem *b, MultiSortSupport mss); +extern int multi_sort_compare_dim(int dim, const SortItem *a, + const SortItem *b, MultiSortSupport mss); +extern int multi_sort_compare_dims(int start, int end, const SortItem *a, + const SortItem *b, MultiSortSupport mss); +extern int compare_scalars_simple(const void *a, const void *b, void *arg); +extern int compare_datums_simple(Datum a, Datum b, SortSupport ssup); + +extern void *bsearch_arg(const void *key, const void *base, + size_t nmemb, size_t size, + int (*compar) (const void *, const void *, void *), + void *arg); + +extern AttrNumber *build_attnums_array(Bitmapset *attrs, int *numattrs); + +extern SortItem *build_sorted_items(int numrows, int *nitems, HeapTuple *rows, + TupleDesc tdesc, MultiSortSupport mss, + int numattrs, AttrNumber *attnums); + +extern bool examine_opclause_expression(OpExpr *expr, Var **varp, + Const **cstp, bool *varonleftp); + +extern Selectivity mcv_clauselist_selectivity(PlannerInfo *root, + StatisticExtInfo *stat, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Selectivity *basesel, + Selectivity *totalsel); #endif /* EXTENDED_STATS_INTERNAL_H */ diff --git a/src/include/statistics/statistics.h b/src/include/statistics/statistics.h index 8009fee3223..588b6738b2a 100644 --- a/src/include/statistics/statistics.h +++ b/src/include/statistics/statistics.h @@ -3,7 +3,7 @@ * statistics.h * Extended statistics and selectivity estimation functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/statistics/statistics.h @@ -14,7 +14,7 @@ #define STATISTICS_H #include "commands/vacuum.h" -#include "nodes/relation.h" +#include "nodes/pathnodes.h" #define STATS_MAX_DIMENSIONS 8 /* max number of attributes */ @@ -22,17 +22,13 @@ #define STATS_NDISTINCT_MAGIC 0xA352BFA4 /* struct identifier */ #define STATS_NDISTINCT_TYPE_BASIC 1 /* struct version */ -/* MVDistinctItem represents a single combination of columns */ +/* MVNDistinctItem represents a single combination of columns */ typedef struct MVNDistinctItem { double ndistinct; /* ndistinct value for this combination */ Bitmapset *attrs; /* attr numbers of items */ } MVNDistinctItem; -/* size of the struct, excluding attribute list */ -#define SizeOfMVNDistinctItem \ - (offsetof(MVNDistinctItem, ndistinct) + sizeof(double)) - /* A MVNDistinct object, comprising all possible combinations of columns */ typedef struct MVNDistinct { @@ -42,13 +38,7 @@ typedef struct MVNDistinct MVNDistinctItem items[FLEXIBLE_ARRAY_MEMBER]; } MVNDistinct; -/* size of the struct excluding the items array */ -#define SizeOfMVNDistinct (offsetof(MVNDistinct, nitems) + sizeof(uint32)) - - -/* size of the struct excluding the items array */ -#define SizeOfMVNDistinct (offsetof(MVNDistinct, nitems) + sizeof(uint32)) - +/* Multivariate functional dependencies */ #define STATS_DEPS_MAGIC 0xB4549A2C /* marks serialized bytea */ #define STATS_DEPS_TYPE_BASIC 1 /* basic dependencies type */ @@ -63,10 +53,6 @@ typedef struct MVDependency AttrNumber attributes[FLEXIBLE_ARRAY_MEMBER]; /* attribute numbers */ } MVDependency; -/* size of the struct excluding the deps array */ -#define SizeOfDependency \ - (offsetof(MVDependency, nattributes) + sizeof(AttrNumber)) - typedef struct MVDependencies { uint32 magic; /* magic constant marker */ @@ -75,25 +61,64 @@ typedef struct MVDependencies MVDependency *deps[FLEXIBLE_ARRAY_MEMBER]; /* dependencies */ } MVDependencies; -/* size of the struct excluding the deps array */ -#define SizeOfDependencies (offsetof(MVDependencies, ndeps) + sizeof(uint32)) +/* used to flag stats serialized to bytea */ +#define STATS_MCV_MAGIC 0xE1A651C2 /* marks serialized bytea */ +#define STATS_MCV_TYPE_BASIC 1 /* basic MCV list type */ + +/* max items in MCV list (should be equal to max default_statistics_target) */ +#define STATS_MCVLIST_MAX_ITEMS 10000 + +/* + * Multivariate MCV (most-common value) lists + * + * A straightforward extension of MCV items - i.e. a list (array) of + * combinations of attribute values, together with a frequency and null flags. + */ +typedef struct MCVItem +{ + double frequency; /* frequency of this combination */ + double base_frequency; /* frequency if independent */ + bool *isnull; /* NULL flags */ + Datum *values; /* item values */ +} MCVItem; + +/* multivariate MCV list - essentially an array of MCV items */ +typedef struct MCVList +{ + uint32 magic; /* magic constant marker */ + uint32 type; /* type of MCV list (BASIC) */ + uint32 nitems; /* number of MCV items in the array */ + AttrNumber ndimensions; /* number of dimensions */ + Oid types[STATS_MAX_DIMENSIONS]; /* OIDs of data types */ + MCVItem items[FLEXIBLE_ARRAY_MEMBER]; /* array of MCV items */ +} MCVList; extern MVNDistinct *statext_ndistinct_load(Oid mvoid); extern MVDependencies *statext_dependencies_load(Oid mvoid); +extern MCVList *statext_mcv_load(Oid mvoid); extern void BuildRelationExtStatistics(Relation onerel, double totalrows, - int numrows, HeapTuple *rows, - int natts, VacAttrStats **vacattrstats); + int numrows, HeapTuple *rows, + int natts, VacAttrStats **vacattrstats); +extern int ComputeExtStatisticsRows(Relation onerel, + int natts, VacAttrStats **stats); extern bool statext_is_kind_built(HeapTuple htup, char kind); extern Selectivity dependencies_clauselist_selectivity(PlannerInfo *root, - List *clauses, - int varRelid, - JoinType jointype, - SpecialJoinInfo *sjinfo, - RelOptInfo *rel, - Bitmapset **estimatedclauses); + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Bitmapset **estimatedclauses); +extern Selectivity statext_clauselist_selectivity(PlannerInfo *root, + List *clauses, + int varRelid, + JoinType jointype, + SpecialJoinInfo *sjinfo, + RelOptInfo *rel, + Bitmapset **estimatedclauses); extern bool has_stats_of_kind(List *stats, char requiredkind); extern StatisticExtInfo *choose_best_statistics(List *stats, - Bitmapset *attnums, char requiredkind); + Bitmapset *attnums, char requiredkind); #endif /* STATISTICS_H */ diff --git a/src/include/storage/backendid.h b/src/include/storage/backendid.h index e000bb848c0..70ef8eb7ac6 100644 --- a/src/include/storage/backendid.h +++ b/src/include/storage/backendid.h @@ -4,7 +4,7 @@ * POSTGRES backend id communication definitions * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/backendid.h diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h index 8b5a3751eab..1903897eef0 100644 --- a/src/include/storage/barrier.h +++ b/src/include/storage/barrier.h @@ -3,7 +3,7 @@ * barrier.h * Barriers for synchronizing cooperating processes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/barrier.h diff --git a/src/include/storage/block.h b/src/include/storage/block.h index e2bfa11e370..04ab4c6d710 100644 --- a/src/include/storage/block.h +++ b/src/include/storage/block.h @@ -4,7 +4,7 @@ * POSTGRES disk block definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/block.h @@ -22,7 +22,7 @@ * contains exactly one disk block). the blocks are numbered * sequentially, 0 to 0xFFFFFFFE. * - * InvalidBlockNumber is the same thing as P_NEW in buf.h. + * InvalidBlockNumber is the same thing as P_NEW in bufmgr.h. * * the access methods, the buffer manager and the storage manager are * more or less the only pieces of code that should be accessing disk diff --git a/src/include/storage/buf.h b/src/include/storage/buf.h index 3b89983b427..f438801f2c6 100644 --- a/src/include/storage/buf.h +++ b/src/include/storage/buf.h @@ -4,7 +4,7 @@ * Basic buffer manager data types. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buf.h diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 5370035f0c6..6ffe184476d 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -5,7 +5,7 @@ * strategy. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buf_internals.h @@ -52,7 +52,7 @@ /* * Flags for buffer descriptors * - * Note: TAG_VALID essentially means that there is a buffer hashtable + * Note: BM_TAG_VALID essentially means that there is a buffer hashtable * entry associated with the buffer's tag. */ #define BM_LOCKED (1U << 22) /* buffer header is locked */ @@ -307,10 +307,10 @@ extern void ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag * /* freelist.c */ extern BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy, - uint32 *buf_state); + uint32 *buf_state); extern void StrategyFreeBuffer(BufferDesc *buf); extern bool StrategyRejectBuffer(BufferAccessStrategy strategy, - BufferDesc *buf); + BufferDesc *buf); extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc); extern void StrategyNotifyBgWriter(int bgwprocno); @@ -329,12 +329,12 @@ extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode); /* localbuf.c */ extern void LocalPrefetchBuffer(SMgrRelation smgr, ForkNumber forkNum, - BlockNumber blockNum); + BlockNumber blockNum); extern BufferDesc *LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, - BlockNumber blockNum, bool *foundPtr); + BlockNumber blockNum, bool *foundPtr); extern void MarkLocalBufferDirty(Buffer buffer); extern void DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum, - BlockNumber firstDelBlock); + BlockNumber firstDelBlock); extern void DropRelFileNodeAllLocalBuffers(RelFileNode rnode); extern void AtEOXact_LocalBuffers(bool isCommit); diff --git a/src/include/storage/buffile.h b/src/include/storage/buffile.h index a6cdeb451c1..1fba404fe2e 100644 --- a/src/include/storage/buffile.h +++ b/src/include/storage/buffile.h @@ -15,7 +15,7 @@ * but currently we have no need for oversize temp files without buffered * access. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/buffile.h @@ -43,7 +43,7 @@ extern size_t BufFileWrite(BufFile *file, void *ptr, size_t size); extern int BufFileSeek(BufFile *file, int fileno, off_t offset, int whence); extern void BufFileTell(BufFile *file, int *fileno, off_t *offset); extern int BufFileSeekBlock(BufFile *file, long blknum); -extern off_t BufFileSize(BufFile *file); +extern int64 BufFileSize(BufFile *file); extern long BufFileAppend(BufFile *target, BufFile *source); extern BufFile *BufFileCreateShared(SharedFileSet *fileset, const char *name); diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 3cce3906a0e..17b97f7e38f 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -4,7 +4,7 @@ * POSTGRES buffer manager definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/bufmgr.h @@ -20,7 +20,6 @@ #include "storage/relfilenode.h" #include "utils/relcache.h" #include "utils/snapmgr.h" -#include "utils/tqual.h" typedef void *Block; @@ -164,20 +163,20 @@ extern PGDLLIMPORT int32 *LocalRefCount; */ extern bool ComputeIoConcurrency(int io_concurrency, double *target); extern void PrefetchBuffer(Relation reln, ForkNumber forkNum, - BlockNumber blockNum); + BlockNumber blockNum); extern Buffer ReadBuffer(Relation reln, BlockNumber blockNum); extern Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, - BlockNumber blockNum, ReadBufferMode mode, - BufferAccessStrategy strategy); + BlockNumber blockNum, ReadBufferMode mode, + BufferAccessStrategy strategy); extern Buffer ReadBufferWithoutRelcache(RelFileNode rnode, - ForkNumber forkNum, BlockNumber blockNum, - ReadBufferMode mode, BufferAccessStrategy strategy); + ForkNumber forkNum, BlockNumber blockNum, + ReadBufferMode mode, BufferAccessStrategy strategy); extern void ReleaseBuffer(Buffer buffer); extern void UnlockReleaseBuffer(Buffer buffer); extern void MarkBufferDirty(Buffer buffer); extern void IncrBufferRefCount(Buffer buffer); extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, - BlockNumber blockNum); + BlockNumber blockNum); extern void InitBufferPool(void); extern void InitBufferPoolAccess(void); @@ -187,12 +186,12 @@ extern void PrintBufferLeakWarning(Buffer buffer); extern void CheckPointBuffers(int flags); extern BlockNumber BufferGetBlockNumber(Buffer buffer); extern BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, - ForkNumber forkNum); + ForkNumber forkNum); extern void FlushOneBuffer(Buffer buffer); extern void FlushRelationBuffers(Relation rel); extern void FlushDatabaseBuffers(Oid dbid); -extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, - ForkNumber forkNum, BlockNumber firstDelBlock); +extern void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber *forkNum, + int nforks, BlockNumber *firstDelBlock); extern void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes); extern void DropDatabaseBuffers(Oid dbid); @@ -207,7 +206,7 @@ extern void PrintPinnedBufs(void); #endif extern Size BufferShmemSize(void); extern void BufferGetTag(Buffer buffer, RelFileNode *rnode, - ForkNumber *forknum, BlockNumber *blknum); + ForkNumber *forknum, BlockNumber *blknum); extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std); @@ -268,8 +267,8 @@ TestForOldSnapshot(Snapshot snapshot, Relation relation, Page page) if (old_snapshot_threshold >= 0 && (snapshot) != NULL - && ((snapshot)->satisfies == HeapTupleSatisfiesMVCC - || (snapshot)->satisfies == HeapTupleSatisfiesToast) + && ((snapshot)->snapshot_type == SNAPSHOT_MVCC + || (snapshot)->snapshot_type == SNAPSHOT_TOAST) && !XLogRecPtrIsInvalid((snapshot)->lsn) && PageGetLSN(page) > (snapshot)->lsn) TestForOldSnapshot_impl(snapshot, relation); diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index 85dd10c45a3..4ef6d8ddd4a 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -4,7 +4,7 @@ * Standard POSTGRES buffer page definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/bufpage.h @@ -53,14 +53,18 @@ * * NOTES: * - * linp1..N form an ItemId array. ItemPointers point into this array - * rather than pointing directly to a tuple. Note that OffsetNumbers + * linp1..N form an ItemId (line pointer) array. ItemPointers point + * to a physical block number and a logical offset (line pointer + * number) within that block/page. Note that OffsetNumbers * conventionally start at 1, not 0. * - * tuple1..N are added "backwards" on the page. because a tuple's - * ItemPointer points to its ItemId entry rather than its actual + * tuple1..N are added "backwards" on the page. Since an ItemPointer + * offset is used to access an ItemId entry rather than an actual * byte-offset position, tuples can be physically shuffled on a page - * whenever the need arises. + * whenever the need arises. This indirection also keeps crash recovery + * relatively simple, because the low-level details of page space + * management can be controlled by standard buffer page code during + * logging, and during recovery. * * AM-generic per-page information is kept in PageHeaderData. * @@ -233,7 +237,7 @@ typedef PageHeaderData *PageHeader; /* * PageGetContents - * To be used in case the page does not contain item pointers. + * To be used in cases where the page does not contain line pointers. * * Note: prior to 8.3 this was not guaranteed to yield a MAXALIGN'd result. * Now it is. Beware of old code that might think the offset to the contents @@ -302,7 +306,7 @@ typedef PageHeaderData *PageHeader; * This is intended to catch use of the pointer before page initialization. * It is implemented as a function due to the limitations of the MSVC * compiler, which choked on doing all these tests within another macro. We - * return true so that MacroAssert() can be used while still getting the + * return true so that AssertMacro() can be used while still getting the * specifics from the macro failure within this function. */ static inline bool @@ -417,7 +421,7 @@ do { \ extern void PageInit(Page page, Size pageSize, Size specialSize); extern bool PageIsVerified(Page page, BlockNumber blkno); extern OffsetNumber PageAddItemExtended(Page page, Item item, Size size, - OffsetNumber offsetNumber, int flags); + OffsetNumber offsetNumber, int flags); extern Page PageGetTempPage(Page page); extern Page PageGetTempPageCopy(Page page); extern Page PageGetTempPageCopySpecial(Page page); @@ -431,7 +435,7 @@ extern void PageIndexTupleDelete(Page page, OffsetNumber offset); extern void PageIndexMultiDelete(Page page, OffsetNumber *itemnos, int nitems); extern void PageIndexTupleDeleteNoCompact(Page page, OffsetNumber offset); extern bool PageIndexTupleOverwrite(Page page, OffsetNumber offnum, - Item newtup, Size newsize); + Item newtup, Size newsize); extern char *PageSetChecksumCopy(Page page, BlockNumber blkno); extern void PageSetChecksumInplace(Page page, BlockNumber blkno); diff --git a/src/include/storage/checksum.h b/src/include/storage/checksum.h index 433755e279f..7ef32a3baa3 100644 --- a/src/include/storage/checksum.h +++ b/src/include/storage/checksum.h @@ -3,7 +3,7 @@ * checksum.h * Checksum implementation for data pages. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/checksum.h diff --git a/src/include/storage/checksum_impl.h b/src/include/storage/checksum_impl.h index 64d76229add..4b87610796a 100644 --- a/src/include/storage/checksum_impl.h +++ b/src/include/storage/checksum_impl.h @@ -8,7 +8,7 @@ * referenced by storage/checksum.h. (Note: you may need to redefine * Assert() as empty to compile this successfully externally.) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/checksum_impl.h @@ -107,6 +107,13 @@ /* prime multiplier of FNV-1a hash */ #define FNV_PRIME 16777619 +/* Use a union so that this code is valid under strict aliasing */ +typedef union +{ + PageHeaderData phdr; + uint32 data[BLCKSZ / (sizeof(uint32) * N_SUMS)][N_SUMS]; +} PGChecksummablePage; + /* * Base offsets to initialize each of the parallel FNV hashes into a * different initial state. @@ -132,28 +139,27 @@ do { \ } while (0) /* - * Block checksum algorithm. The data argument must be aligned on a 4-byte - * boundary. + * Block checksum algorithm. The page must be adequately aligned + * (at least on 4-byte boundary). */ static uint32 -pg_checksum_block(char *data, uint32 size) +pg_checksum_block(const PGChecksummablePage *page) { uint32 sums[N_SUMS]; - uint32 (*dataArr)[N_SUMS] = (uint32 (*)[N_SUMS]) data; uint32 result = 0; uint32 i, j; /* ensure that the size is compatible with the algorithm */ - Assert((size % (sizeof(uint32) * N_SUMS)) == 0); + Assert(sizeof(PGChecksummablePage) == BLCKSZ); /* initialize partial checksums to their corresponding offsets */ memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets)); /* main checksum calculation */ - for (i = 0; i < size / sizeof(uint32) / N_SUMS; i++) + for (i = 0; i < (uint32) (BLCKSZ / (sizeof(uint32) * N_SUMS)); i++) for (j = 0; j < N_SUMS; j++) - CHECKSUM_COMP(sums[j], dataArr[i][j]); + CHECKSUM_COMP(sums[j], page->data[i][j]); /* finally add in two rounds of zeroes for additional mixing */ for (i = 0; i < 2; i++) @@ -168,8 +174,10 @@ pg_checksum_block(char *data, uint32 size) } /* - * Compute the checksum for a Postgres page. The page must be aligned on a - * 4-byte boundary. + * Compute the checksum for a Postgres page. + * + * The page must be adequately aligned (at least on a 4-byte boundary). + * Beware also that the checksum field of the page is transiently zeroed. * * The checksum includes the block number (to detect the case where a page is * somehow moved to a different location), the page header (excluding the @@ -178,12 +186,12 @@ pg_checksum_block(char *data, uint32 size) uint16 pg_checksum_page(char *page, BlockNumber blkno) { - PageHeader phdr = (PageHeader) page; + PGChecksummablePage *cpage = (PGChecksummablePage *) page; uint16 save_checksum; uint32 checksum; /* We only calculate the checksum for properly-initialized pages */ - Assert(!PageIsNew(page)); + Assert(!PageIsNew(&cpage->phdr)); /* * Save pd_checksum and temporarily set it to zero, so that the checksum @@ -191,10 +199,10 @@ pg_checksum_page(char *page, BlockNumber blkno) * Restore it after, because actually updating the checksum is NOT part of * the API of this function. */ - save_checksum = phdr->pd_checksum; - phdr->pd_checksum = 0; - checksum = pg_checksum_block(page, BLCKSZ); - phdr->pd_checksum = save_checksum; + save_checksum = cpage->phdr.pd_checksum; + cpage->phdr.pd_checksum = 0; + checksum = pg_checksum_block(cpage); + cpage->phdr.pd_checksum = save_checksum; /* Mix in the block number to detect transposed pages */ checksum ^= blkno; diff --git a/src/include/storage/condition_variable.h b/src/include/storage/condition_variable.h index 32e645c02a1..ee06e051ce1 100644 --- a/src/include/storage/condition_variable.h +++ b/src/include/storage/condition_variable.h @@ -12,7 +12,7 @@ * can be cancelled prior to the fulfillment of the condition) and do not * use pointers internally (so that they are safe to use within DSMs). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/condition_variable.h @@ -43,6 +43,8 @@ extern void ConditionVariableInit(ConditionVariable *cv); * the condition variable. */ extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info); +extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, + uint32 wait_event_info); extern void ConditionVariableCancelSleep(void); /* diff --git a/src/include/storage/copydir.h b/src/include/storage/copydir.h index 4fef3e21072..525cc6203e1 100644 --- a/src/include/storage/copydir.h +++ b/src/include/storage/copydir.h @@ -3,7 +3,7 @@ * copydir.h * Copy a directory. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/copydir.h diff --git a/src/include/storage/dsm.h b/src/include/storage/dsm.h index 169de946f7b..e6896754723 100644 --- a/src/include/storage/dsm.h +++ b/src/include/storage/dsm.h @@ -3,7 +3,7 @@ * dsm.h * manage dynamic shared memory segments * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/dsm.h @@ -29,15 +29,11 @@ extern void dsm_postmaster_startup(struct PGShmemHeader *); extern void dsm_backend_shutdown(void); extern void dsm_detach_all(void); -#ifdef EXEC_BACKEND extern void dsm_set_control_handle(dsm_handle h); -#endif -/* Functions that create, update, or remove mappings. */ +/* Functions that create or remove mappings. */ extern dsm_segment *dsm_create(Size size, int flags); extern dsm_segment *dsm_attach(dsm_handle h); -extern void *dsm_resize(dsm_segment *seg, Size size); -extern void *dsm_remap(dsm_segment *seg); extern void dsm_detach(dsm_segment *seg); /* Resource management functions. */ @@ -55,9 +51,9 @@ extern dsm_handle dsm_segment_handle(dsm_segment *seg); /* Cleanup hooks. */ typedef void (*on_dsm_detach_callback) (dsm_segment *, Datum arg); extern void on_dsm_detach(dsm_segment *seg, - on_dsm_detach_callback function, Datum arg); + on_dsm_detach_callback function, Datum arg); extern void cancel_on_dsm_detach(dsm_segment *seg, - on_dsm_detach_callback function, Datum arg); + on_dsm_detach_callback function, Datum arg); extern void reset_on_dsm_detach(void); #endif /* DSM_H */ diff --git a/src/include/storage/dsm_impl.h b/src/include/storage/dsm_impl.h index 0e5730f7c5b..1dc557b791a 100644 --- a/src/include/storage/dsm_impl.h +++ b/src/include/storage/dsm_impl.h @@ -3,7 +3,7 @@ * dsm_impl.h * low-level dynamic shared memory primitives * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/dsm_impl.h @@ -14,7 +14,6 @@ #define DSM_IMPL_H /* Dynamic shared memory implementations. */ -#define DSM_IMPL_NONE 0 #define DSM_IMPL_POSIX 1 #define DSM_IMPL_SYSV 2 #define DSM_IMPL_WINDOWS 3 @@ -60,21 +59,17 @@ typedef enum DSM_OP_CREATE, DSM_OP_ATTACH, DSM_OP_DETACH, - DSM_OP_RESIZE, DSM_OP_DESTROY } dsm_op; /* Create, attach to, detach from, resize, or destroy a segment. */ extern bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, - void **impl_private, void **mapped_address, Size *mapped_size, - int elevel); - -/* Some implementations cannot resize segments. Can this one? */ -extern bool dsm_impl_can_resize(void); + void **impl_private, void **mapped_address, Size *mapped_size, + int elevel); /* Implementation-dependent actions required to keep segment until shutdown. */ extern void dsm_impl_pin_segment(dsm_handle handle, void *impl_private, - void **impl_private_pm_handle); + void **impl_private_pm_handle); extern void dsm_impl_unpin_segment(dsm_handle handle, void **impl_private); #endif /* DSM_IMPL_H */ diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index 484339b7690..625fbc386a4 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -4,7 +4,7 @@ * Virtual file descriptor definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/fd.h @@ -15,7 +15,7 @@ /* * calls: * - * File {Close, Read, Write, Seek, Tell, Sync} + * File {Close, Read, Write, Size, Sync} * {Path Name Open, Allocate, Free} File * * These are NOT JUST RENAMINGS OF THE UNIX ROUTINES. @@ -33,7 +33,7 @@ * no way for them to share kernel file descriptors with other files. * * Likewise, use AllocateDir/FreeDir, not opendir/closedir, to allocate - * open directories (DIR*), and OpenTransientFile/CloseTransient File for an + * open directories (DIR*), and OpenTransientFile/CloseTransientFile for an * unbuffered file descriptor. */ #ifndef FD_H @@ -42,21 +42,30 @@ #include -/* - * FileSeek uses the standard UNIX lseek(2) flags. - */ - typedef int File; /* GUC parameter */ extern PGDLLIMPORT int max_files_per_process; +extern PGDLLIMPORT bool data_sync_retry; /* * This is private to fd.c, but exported for save/restore_backend_variables() */ extern int max_safe_fds; +/* + * On Windows, we have to interpret EACCES as possibly meaning the same as + * ENOENT, because if a file is unlinked-but-not-yet-gone on that platform, + * that's what you get. Ugh. This code is designed so that we don't + * actually believe these cases are okay without further evidence (namely, + * a pending fsync request getting canceled ... see ProcessSyncRequests). + */ +#ifndef WIN32 +#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT) +#else +#define FILE_POSSIBLY_DELETED(err) ((err) == ENOENT || (err) == EACCES) +#endif /* * prototypes for functions in fd.c @@ -68,17 +77,16 @@ extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fil extern File OpenTemporaryFile(bool interXact); extern void FileClose(File file); extern int FilePrefetch(File file, off_t offset, int amount, uint32 wait_event_info); -extern int FileRead(File file, char *buffer, int amount, uint32 wait_event_info); -extern int FileWrite(File file, char *buffer, int amount, uint32 wait_event_info); +extern int FileRead(File file, char *buffer, int amount, off_t offset, uint32 wait_event_info); +extern int FileWrite(File file, char *buffer, int amount, off_t offset, uint32 wait_event_info); extern int FileSync(File file, uint32 wait_event_info); -extern off_t FileSeek(File file, off_t offset, int whence); +extern off_t FileSize(File file); extern int FileTruncate(File file, off_t offset, uint32 wait_event_info); extern void FileWriteback(File file, off_t offset, off_t nbytes, uint32 wait_event_info); extern char *FilePathName(File file); extern int FileGetRawDesc(File file); extern int FileGetRawFlags(File file); extern mode_t FileGetRawMode(File file); -extern off_t FileGetSize(File file); /* Operations used for sharing named temporary files */ extern File PathNameCreateTemporaryFile(const char *name, bool error_on_failure); @@ -100,7 +108,7 @@ extern int ClosePipeStream(FILE *file); extern DIR *AllocateDir(const char *dirname); extern struct dirent *ReadDir(DIR *dir, const char *dirname); extern struct dirent *ReadDirExtended(DIR *dir, const char *dirname, - int elevel); + int elevel); extern int FreeDir(DIR *dir); /* Operations to allow use of a plain kernel FD, with automatic cleanup */ @@ -123,10 +131,12 @@ extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces); extern bool TempTablespacesAreSet(void); extern int GetTempTablespaces(Oid *tableSpaces, int numSpaces); extern Oid GetNextTempTableSpace(void); -extern void AtEOXact_Files(void); +extern void AtEOXact_Files(bool isCommit); extern void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId parentSubid); extern void RemovePgTempFiles(void); +extern void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok, + bool unlink_all); extern bool looks_like_temp_rel_name(const char *name); extern int pg_fsync(int fd); @@ -139,6 +149,7 @@ extern int durable_rename(const char *oldfile, const char *newfile, int loglevel extern int durable_unlink(const char *fname, int loglevel); extern int durable_link_or_rename(const char *oldfile, const char *newfile, int loglevel); extern void SyncDataDirectory(void); +extern int data_sync_elevel(int elevel); /* Filename components */ #define PG_TEMP_FILES_DIR "pgsql_tmp" diff --git a/src/include/storage/freespace.h b/src/include/storage/freespace.h index 726eb30fb80..b75f6fe9468 100644 --- a/src/include/storage/freespace.h +++ b/src/include/storage/freespace.h @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding free space in relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/freespace.h @@ -22,17 +22,18 @@ extern Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk); extern BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded); extern BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, - BlockNumber oldPage, - Size oldSpaceAvail, - Size spaceNeeded); + BlockNumber oldPage, + Size oldSpaceAvail, + Size spaceNeeded); extern void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, - Size spaceAvail); + Size spaceAvail); extern void XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk, - Size spaceAvail); + Size spaceAvail); -extern void FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks); +extern BlockNumber FreeSpaceMapPrepareTruncateRel(Relation rel, + BlockNumber nblocks); extern void FreeSpaceMapVacuum(Relation rel); extern void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, - BlockNumber end); + BlockNumber end); #endif /* FREESPACE_H_ */ diff --git a/src/include/storage/fsm_internals.h b/src/include/storage/fsm_internals.h index d6b81878614..0ec5a7966f6 100644 --- a/src/include/storage/fsm_internals.h +++ b/src/include/storage/fsm_internals.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * - * fsm_internal.h + * fsm_internals.h * internal functions for free space map * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/fsm_internals.h @@ -61,8 +61,8 @@ typedef FSMPageData *FSMPage; #define SlotsPerFSMPage LeafNodesPerPage /* Prototypes for functions in fsmpage.c */ -extern int fsm_search_avail(Buffer buf, uint8 min_cat, bool advancenext, - bool exclusive_lock_held); +extern int fsm_search_avail(Buffer buf, uint8 min_cat, bool advancenext, + bool exclusive_lock_held); extern uint8 fsm_get_avail(Page page, int slot); extern uint8 fsm_get_max_avail(Page page); extern bool fsm_set_avail(Page page, int slot, uint8 value); diff --git a/src/include/storage/indexfsm.h b/src/include/storage/indexfsm.h index 07cbef41067..bc5b303cb7c 100644 --- a/src/include/storage/indexfsm.h +++ b/src/include/storage/indexfsm.h @@ -4,7 +4,7 @@ * POSTGRES free space map for quickly finding an unused page in index * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/indexfsm.h diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 6a05a89349c..d113813df32 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -8,7 +8,7 @@ * exit-time cleanup for either a postmaster or a backend. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/ipc.h @@ -76,6 +76,6 @@ extern void on_exit_reset(void); /* ipci.c */ extern PGDLLIMPORT shmem_startup_hook_type shmem_startup_hook; -extern void CreateSharedMemoryAndSemaphores(bool makePrivate, int port); +extern void CreateSharedMemoryAndSemaphores(void); #endif /* IPC_H */ diff --git a/src/include/storage/item.h b/src/include/storage/item.h index 44a52fbdfbc..95913f81772 100644 --- a/src/include/storage/item.h +++ b/src/include/storage/item.h @@ -4,7 +4,7 @@ * POSTGRES disk item definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/item.h diff --git a/src/include/storage/itemid.h b/src/include/storage/itemid.h index 60570cc53d1..ad232fb706f 100644 --- a/src/include/storage/itemid.h +++ b/src/include/storage/itemid.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * * itemid.h - * Standard POSTGRES buffer page item identifier definitions. + * Standard POSTGRES buffer page item identifier/line pointer definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/itemid.h @@ -15,16 +15,17 @@ #define ITEMID_H /* - * An item pointer (also called line pointer) on a buffer page + * A line pointer on a buffer page. See buffer page definitions and comments + * for an explanation of how line pointers are used. * - * In some cases an item pointer is "in use" but does not have any associated - * storage on the page. By convention, lp_len == 0 in every item pointer + * In some cases a line pointer is "in use" but does not have any associated + * storage on the page. By convention, lp_len == 0 in every line pointer * that does not have storage, independently of its lp_flags state. */ typedef struct ItemIdData { unsigned lp_off:15, /* offset to tuple (from start of page) */ - lp_flags:2, /* state of item pointer, see below */ + lp_flags:2, /* state of line pointer, see below */ lp_len:15; /* byte length of tuple */ } ItemIdData; @@ -72,7 +73,7 @@ typedef uint16 ItemLength; /* * ItemIdGetRedirect - * In a REDIRECT pointer, lp_off holds the link to the next item pointer + * In a REDIRECT pointer, lp_off holds offset number for next line pointer */ #define ItemIdGetRedirect(itemId) \ ((itemId)->lp_off) diff --git a/src/include/storage/itemptr.h b/src/include/storage/itemptr.h index 626c98f9691..d73eed585e6 100644 --- a/src/include/storage/itemptr.h +++ b/src/include/storage/itemptr.h @@ -4,7 +4,7 @@ * POSTGRES disk item pointer definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/itemptr.h @@ -22,8 +22,8 @@ * * This is a pointer to an item within a disk page of a known file * (for example, a cross-link from an index to its parent table). - * blkid tells us which block, posid tells us which entry in the linp - * (ItemIdData) array we want. + * ip_blkid tells us which block, ip_posid tells us which entry in + * the linp (ItemIdData) array we want. * * Note: because there is an item pointer in each tuple header and index * tuple header on disk, it's very important not to waste space with @@ -41,13 +41,35 @@ typedef struct ItemPointerData /* If compiler understands packed and aligned pragmas, use those */ #if defined(pg_attribute_packed) && defined(pg_attribute_aligned) -pg_attribute_packed() -pg_attribute_aligned(2) + pg_attribute_packed() + pg_attribute_aligned(2) #endif ItemPointerData; typedef ItemPointerData *ItemPointer; +/* ---------------- + * special values used in heap tuples (t_ctid) + * ---------------- + */ + +/* + * If a heap tuple holds a speculative insertion token rather than a real + * TID, ip_posid is set to SpecTokenOffsetNumber, and the token is stored in + * ip_blkid. SpecTokenOffsetNumber must be higher than MaxOffsetNumber, so + * that it can be distinguished from a valid offset number in a regular item + * pointer. + */ +#define SpecTokenOffsetNumber 0xfffe + +/* + * When a tuple is moved to a different partition by UPDATE, the t_ctid of + * the old tuple version is set to this magic value. + */ +#define MovedPartitionsOffsetNumber 0xfffd +#define MovedPartitionsBlockNumber InvalidBlockNumber + + /* ---------------- * support macros * ---------------- @@ -160,7 +182,10 @@ typedef ItemPointerData *ItemPointer; * partition. */ #define ItemPointerIndicatesMovedPartitions(pointer) \ - !BlockNumberIsValid(ItemPointerGetBlockNumberNoCheck(pointer)) +( \ + ItemPointerGetOffsetNumber(pointer) == MovedPartitionsOffsetNumber && \ + ItemPointerGetBlockNumberNoCheck(pointer) == MovedPartitionsBlockNumber \ +) /* * ItemPointerSetMovedPartitions @@ -168,7 +193,7 @@ typedef ItemPointerData *ItemPointer; * different partition. */ #define ItemPointerSetMovedPartitions(pointer) \ - ItemPointerSetBlockNumber((pointer), InvalidBlockNumber) + ItemPointerSet((pointer), MovedPartitionsBlockNumber, MovedPartitionsOffsetNumber) /* ---------------- * externs diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h index a234d5cf8e1..36c950d721f 100644 --- a/src/include/storage/large_object.h +++ b/src/include/storage/large_object.h @@ -5,7 +5,7 @@ * zillions of large objects (internal, external, jaquith, inversion). * Now we only support inversion. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/large_object.h diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index a4bcb48874a..bd7af11a8ad 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -90,7 +90,7 @@ * efficient than using WaitLatch or WaitLatchOrSocket. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/latch.h @@ -126,10 +126,11 @@ typedef struct Latch #define WL_SOCKET_WRITEABLE (1 << 2) #define WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */ #define WL_POSTMASTER_DEATH (1 << 4) +#define WL_EXIT_ON_PM_DEATH (1 << 5) #ifdef WIN32 -#define WL_SOCKET_CONNECTED (1 << 5) +#define WL_SOCKET_CONNECTED (1 << 6) #else -/* avoid having to to deal with case on platforms not requiring it */ +/* avoid having to deal with case on platforms not requiring it */ #define WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE #endif @@ -155,26 +156,26 @@ typedef struct WaitEventSet WaitEventSet; * prototypes for functions in latch.c */ extern void InitializeLatchSupport(void); -extern void InitLatch(volatile Latch *latch); -extern void InitSharedLatch(volatile Latch *latch); -extern void OwnLatch(volatile Latch *latch); -extern void DisownLatch(volatile Latch *latch); -extern void SetLatch(volatile Latch *latch); -extern void ResetLatch(volatile Latch *latch); +extern void InitLatch(Latch *latch); +extern void InitSharedLatch(Latch *latch); +extern void OwnLatch(Latch *latch); +extern void DisownLatch(Latch *latch); +extern void SetLatch(Latch *latch); +extern void ResetLatch(Latch *latch); extern WaitEventSet *CreateWaitEventSet(MemoryContext context, int nevents); extern void FreeWaitEventSet(WaitEventSet *set); -extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, - Latch *latch, void *user_data); +extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, + Latch *latch, void *user_data); extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch); -extern int WaitEventSetWait(WaitEventSet *set, long timeout, - WaitEvent *occurred_events, int nevents, - uint32 wait_event_info); -extern int WaitLatch(volatile Latch *latch, int wakeEvents, long timeout, - uint32 wait_event_info); -extern int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, - pgsocket sock, long timeout, uint32 wait_event_info); +extern int WaitEventSetWait(WaitEventSet *set, long timeout, + WaitEvent *occurred_events, int nevents, + uint32 wait_event_info); +extern int WaitLatch(Latch *latch, int wakeEvents, long timeout, + uint32 wait_event_info); +extern int WaitLatchOrSocket(Latch *latch, int wakeEvents, + pgsocket sock, long timeout, uint32 wait_event_info); /* * Unix implementation uses SIGUSR1 for inter-process signaling. diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h index a217de97166..099e18f2b75 100644 --- a/src/include/storage/lmgr.h +++ b/src/include/storage/lmgr.h @@ -4,7 +4,7 @@ * POSTGRES lock manager definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lmgr.h @@ -45,6 +45,8 @@ extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode); extern void LockRelation(Relation relation, LOCKMODE lockmode); extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode); extern void UnlockRelation(Relation relation, LOCKMODE lockmode); +extern bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode, + bool orstronger); extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode); extern void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); @@ -54,7 +56,7 @@ extern void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode); extern void LockRelationForExtension(Relation relation, LOCKMODE lockmode); extern void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode); extern bool ConditionalLockRelationForExtension(Relation relation, - LOCKMODE lockmode); + LOCKMODE lockmode); extern int RelationExtensionLockWaiterCount(Relation relation); /* Lock a page (currently only used within indexes) */ @@ -65,19 +67,19 @@ extern void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode); /* Lock a tuple (see heap_lock_tuple before assuming you understand this) */ extern void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode); extern bool ConditionalLockTuple(Relation relation, ItemPointer tid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode); /* Lock an XID (used to wait for a transaction to finish) */ extern void XactLockTableInsert(TransactionId xid); extern void XactLockTableDelete(TransactionId xid); extern void XactLockTableWait(TransactionId xid, Relation rel, - ItemPointer ctid, XLTW_Oper oper); + ItemPointer ctid, XLTW_Oper oper); extern bool ConditionalXactLockTableWait(TransactionId xid); /* Lock VXIDs, specified by conflicting locktags */ -extern void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode); -extern void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode); +extern void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress); +extern void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress); /* Lock an XID for tuple insertion (used to wait for an insertion to finish) */ extern uint32 SpeculativeInsertionLockAcquire(TransactionId xid); @@ -86,20 +88,20 @@ extern void SpeculativeInsertionWait(TransactionId xid, uint32 token); /* Lock a general object (other than a relation) of the current database */ extern void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); /* Lock a shared-across-databases object (other than a relation) */ extern void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); extern void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid, - LOCKMODE lockmode); + LOCKMODE lockmode); /* Describe a locktag for error messages */ extern void DescribeLockTag(StringInfo buf, const LOCKTAG *tag); diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 777da716790..6efb7a96481 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -4,7 +4,7 @@ * POSTGRES low-level lock mechanism * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lock.h @@ -138,27 +138,13 @@ typedef uint16 LOCKMETHODID; typedef enum LockTagType { LOCKTAG_RELATION, /* whole relation */ - /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */ LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */ - /* same ID info as RELATION */ LOCKTAG_PAGE, /* one page of a relation */ - /* ID info for a page is RELATION info + BlockNumber */ LOCKTAG_TUPLE, /* one physical tuple */ - /* ID info for a tuple is PAGE info + OffsetNumber */ LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */ - /* ID info for a transaction is its TransactionId */ LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */ - /* ID info for a virtual transaction is its VirtualTransactionId */ LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */ - /* ID info for a transaction is its TransactionId */ LOCKTAG_OBJECT, /* non-relation database object */ - /* ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID */ - - /* - * Note: object ID has same representation as in pg_depend and - * pg_description, but notice that we are constraining SUBID to 16 bits. - * Also, we use DB OID = 0 for shared objects such as tablespaces. - */ LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */ LOCKTAG_ADVISORY /* advisory user locks */ } LockTagType; @@ -190,6 +176,8 @@ typedef struct LOCKTAG * the physical fields of LOCKTAG. Use these to set up LOCKTAG values, * rather than accessing the fields directly. Note multiple eval of target! */ + +/* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */ #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ @@ -198,6 +186,7 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_RELATION, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* same ID info as RELATION */ #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ @@ -206,6 +195,7 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* ID info for a page is RELATION info + BlockNumber */ #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ @@ -214,6 +204,7 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_PAGE, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* ID info for a tuple is PAGE info + OffsetNumber */ #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (reloid), \ @@ -222,6 +213,7 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_TUPLE, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* ID info for a transaction is its TransactionId */ #define SET_LOCKTAG_TRANSACTION(locktag,xid) \ ((locktag).locktag_field1 = (xid), \ (locktag).locktag_field2 = 0, \ @@ -230,6 +222,7 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_TRANSACTION, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* ID info for a virtual transaction is its VirtualTransactionId */ #define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \ ((locktag).locktag_field1 = (vxid).backendId, \ (locktag).locktag_field2 = (vxid).localTransactionId, \ @@ -238,6 +231,10 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* + * ID info for a speculative insert is TRANSACTION info + + * its speculative insert counter. + */ #define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \ ((locktag).locktag_field1 = (xid), \ (locktag).locktag_field2 = (token), \ @@ -246,6 +243,13 @@ typedef struct LOCKTAG (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD) +/* + * ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID + * + * Note: object ID has same representation as in pg_depend and + * pg_description, but notice that we are constraining SUBID to 16 bits. + * Also, we use DB OID = 0 for shared objects such as tablespaces. + */ #define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \ ((locktag).locktag_field1 = (dboid), \ (locktag).locktag_field2 = (classoid), \ @@ -404,14 +408,15 @@ typedef struct LOCALLOCK LOCALLOCKTAG tag; /* unique identifier of locallock entry */ /* data */ + uint32 hashcode; /* copy of LOCKTAG's hash value */ LOCK *lock; /* associated LOCK object, if any */ PROCLOCK *proclock; /* associated PROCLOCK object, if any */ - uint32 hashcode; /* copy of LOCKTAG's hash value */ int64 nLocks; /* total number of times lock is held */ int numLockOwners; /* # of relevant ResourceOwners */ int maxLockOwners; /* allocated size of array */ - bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */ + bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */ + bool lockCleared; /* we read all sinval msgs for lock */ } LOCALLOCK; #define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid) @@ -472,7 +477,8 @@ typedef enum { LOCKACQUIRE_NOT_AVAIL, /* lock not available, and dontWait=true */ LOCKACQUIRE_OK, /* lock successfully acquired */ - LOCKACQUIRE_ALREADY_HELD /* incremented count for lock already held */ + LOCKACQUIRE_ALREADY_HELD, /* incremented count for lock already held */ + LOCKACQUIRE_ALREADY_CLEAR /* incremented count for lock already clear */ } LockAcquireResult; /* Deadlock states identified by DeadLockCheck() */ @@ -521,30 +527,33 @@ extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag); extern uint32 LockTagHashCode(const LOCKTAG *locktag); extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2); extern LockAcquireResult LockAcquire(const LOCKTAG *locktag, - LOCKMODE lockmode, - bool sessionLock, - bool dontWait); + LOCKMODE lockmode, + bool sessionLock, + bool dontWait); extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, - LOCKMODE lockmode, - bool sessionLock, - bool dontWait, - bool report_memory_error); + LOCKMODE lockmode, + bool sessionLock, + bool dontWait, + bool reportMemoryError, + LOCALLOCK **locallockp); extern void AbortStrongLockAcquire(void); +extern void MarkLockClear(LOCALLOCK *locallock); extern bool LockRelease(const LOCKTAG *locktag, - LOCKMODE lockmode, bool sessionLock); + LOCKMODE lockmode, bool sessionLock); extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks); extern void LockReleaseSession(LOCKMETHODID lockmethodid); extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks); extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks); +extern bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode); extern bool LockHasWaiters(const LOCKTAG *locktag, - LOCKMODE lockmode, bool sessionLock); + LOCKMODE lockmode, bool sessionLock); extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag, - LOCKMODE lockmode); + LOCKMODE lockmode, int *countp); extern void AtPrepare_Locks(void); extern void PostPrepare_Locks(TransactionId xid); -extern int LockCheckConflicts(LockMethod lockMethodTable, - LOCKMODE lockmode, - LOCK *lock, PROCLOCK *proclock); +extern int LockCheckConflicts(LockMethod lockMethodTable, + LOCKMODE lockmode, + LOCK *lock, PROCLOCK *proclock); extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode); extern void GrantAwaitedLock(void); extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode); @@ -556,21 +565,21 @@ extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks); extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode); extern void lock_twophase_recover(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void lock_twophase_postcommit(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void lock_twophase_postabort(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern void lock_twophase_standby_recover(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); extern DeadLockState DeadLockCheck(PGPROC *proc); extern PGPROC *GetBlockingAutoVacuumPgproc(void); extern void DeadLockReport(void) pg_attribute_noreturn(); extern void RememberSimpleDeadLock(PGPROC *proc1, - LOCKMODE lockmode, - LOCK *lock, - PGPROC *proc2); + LOCKMODE lockmode, + LOCK *lock, + PGPROC *proc2); extern void InitDeadLockChecking(void); extern int LockWaiterCount(const LOCKTAG *locktag); @@ -585,4 +594,4 @@ extern void VirtualXactLockTableInsert(VirtualTransactionId vxid); extern void VirtualXactLockTableCleanup(void); extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait); -#endif /* LOCK_H */ +#endif /* LOCK_H_ */ diff --git a/src/include/storage/lockdefs.h b/src/include/storage/lockdefs.h index 72eca39f17f..bda08edcfdb 100644 --- a/src/include/storage/lockdefs.h +++ b/src/include/storage/lockdefs.h @@ -7,7 +7,7 @@ * contains definition that have to (indirectly) be available when included by * FRONTEND code. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lockdefs.h @@ -45,11 +45,15 @@ typedef int LOCKMODE; #define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM FULL, * and unqualified LOCK TABLE */ +#define MaxLockMode 8 + + +/* WAL representation of an AccessExclusiveLock on a table */ typedef struct xl_standby_lock { TransactionId xid; /* xid of holder of AccessExclusiveLock */ - Oid dbOid; - Oid relOid; + Oid dbOid; /* DB containing table */ + Oid relOid; /* OID of table */ } xl_standby_lock; -#endif /* LOCKDEF_H_ */ +#endif /* LOCKDEFS_H_ */ diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index c21bfe2f666..f627dfedc5c 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -4,7 +4,7 @@ * Lightweight lock manager * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/lwlock.h @@ -88,7 +88,7 @@ typedef union LWLockMinimallyPadded } LWLockMinimallyPadded; extern PGDLLIMPORT LWLockPadded *MainLWLockArray; -extern char *MainLWLockNames[]; +extern const char *const MainLWLockNames[]; /* struct for storing named tranche information */ typedef struct NamedLWLockTranche @@ -133,7 +133,7 @@ typedef enum LWLockMode { LW_EXCLUSIVE, LW_SHARED, - LW_WAIT_UNTIL_FREE /* A special mode used in PGPROC->lwlockMode, + LW_WAIT_UNTIL_FREE /* A special mode used in PGPROC->lwWaitMode, * when waiting for lock to become free. Not * to be used as LWLockAcquire argument */ } LWLockMode; @@ -219,6 +219,7 @@ typedef enum BuiltinTrancheIds LWTRANCHE_SHARED_TUPLESTORE, LWTRANCHE_TBM, LWTRANCHE_PARALLEL_APPEND, + LWTRANCHE_SXACT, LWTRANCHE_FIRST_USER_DEFINED } BuiltinTrancheIds; diff --git a/src/include/storage/md.h b/src/include/storage/md.h new file mode 100644 index 00000000000..c0f05e23ff9 --- /dev/null +++ b/src/include/storage/md.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * md.h + * magnetic disk storage manager public interface declarations. + * + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/md.h + * + *------------------------------------------------------------------------- + */ +#ifndef MD_H +#define MD_H + +#include "storage/block.h" +#include "storage/relfilenode.h" +#include "storage/smgr.h" +#include "storage/sync.h" + +/* md storage manager functionality */ +extern void mdinit(void); +extern void mdopen(SMgrRelation reln); +extern void mdclose(SMgrRelation reln, ForkNumber forknum); +extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); +extern bool mdexists(SMgrRelation reln, ForkNumber forknum); +extern void mdunlink(RelFileNodeBackend rnode, ForkNumber forknum, bool isRedo); +extern void mdextend(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, char *buffer, bool skipFsync); +extern void mdprefetch(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum); +extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, + char *buffer); +extern void mdwrite(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, char *buffer, bool skipFsync); +extern void mdwriteback(SMgrRelation reln, ForkNumber forknum, + BlockNumber blocknum, BlockNumber nblocks); +extern BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum); +extern void mdtruncate(SMgrRelation reln, ForkNumber forknum, + BlockNumber nblocks); +extern void mdimmedsync(SMgrRelation reln, ForkNumber forknum); + +extern void ForgetDatabaseSyncRequests(Oid dbid); +extern void DropRelationFiles(RelFileNode *delrels, int ndelrels, bool isRedo); + +/* md sync callbacks */ +extern int mdsyncfiletag(const FileTag *ftag, char *path); +extern int mdunlinkfiletag(const FileTag *ftag, char *path); +extern bool mdfiletagmatches(const FileTag *ftag, const FileTag *candidate); + +#endif /* MD_H */ diff --git a/src/include/storage/off.h b/src/include/storage/off.h index 6179f2f8540..02e663f6ed7 100644 --- a/src/include/storage/off.h +++ b/src/include/storage/off.h @@ -4,7 +4,7 @@ * POSTGRES disk "offset" definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/off.h @@ -26,7 +26,6 @@ typedef uint16 OffsetNumber; #define InvalidOffsetNumber ((OffsetNumber) 0) #define FirstOffsetNumber ((OffsetNumber) 1) #define MaxOffsetNumber ((OffsetNumber) (BLCKSZ / sizeof(ItemIdData))) -#define OffsetNumberMask (0xffff) /* valid uint16 bits */ /* ---------------- * support macros diff --git a/src/include/storage/pg_sema.h b/src/include/storage/pg_sema.h index 2072cf0e8f7..1ac4f9a830f 100644 --- a/src/include/storage/pg_sema.h +++ b/src/include/storage/pg_sema.h @@ -10,7 +10,7 @@ * be provided by each port. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pg_sema.h @@ -41,7 +41,7 @@ typedef HANDLE PGSemaphore; extern Size PGSemaphoreShmemSize(int maxSemas); /* Module initialization (called during postmaster start or shmem reinit) */ -extern void PGReserveSemaphores(int maxSemas, int port); +extern void PGReserveSemaphores(int maxSemas); /* Allocate a PGSemaphore structure with initial count 1 */ extern PGSemaphore PGSemaphoreCreate(void); diff --git a/src/include/storage/pg_shmem.h b/src/include/storage/pg_shmem.h index 6b1e0402514..435ce33ddbe 100644 --- a/src/include/storage/pg_shmem.h +++ b/src/include/storage/pg_shmem.h @@ -14,7 +14,7 @@ * only one ID number. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pg_shmem.h @@ -30,7 +30,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ { int32 magic; /* magic # to identify Postgres segments */ #define PGShmemMagic 679834894 - pid_t creatorPID; /* PID of creating process */ + pid_t creatorPID; /* PID of creating process (set but unread) */ Size totalsize; /* total size of segment */ Size freeoffset; /* offset to first free space */ dsm_handle dsm_control; /* ID of dynamic shared memory control seg */ @@ -41,7 +41,8 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ #endif } PGShmemHeader; -/* GUC variable */ +/* GUC variables */ +extern int shared_memory_type; extern int huge_pages; /* Possible values for huge_pages */ @@ -52,20 +53,38 @@ typedef enum HUGE_PAGES_TRY } HugePagesType; +/* Possible values for shared_memory_type */ +typedef enum +{ + SHMEM_TYPE_WINDOWS, + SHMEM_TYPE_SYSV, + SHMEM_TYPE_MMAP, + SHMEM_TYPE_POSIX +} PGShmemType; + #ifndef WIN32 extern unsigned long UsedShmemSegID; #else extern HANDLE UsedShmemSegID; +extern void *ShmemProtectiveRegion; #endif extern void *UsedShmemSegAddr; +extern void *AnonymousShmem; +extern int AnonymousShmemFile; + +#if !defined(WIN32) && !defined(EXEC_BACKEND) +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_MMAP +#elif !defined(WIN32) +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_SYSV +#else +#define DEFAULT_SHARED_MEMORY_TYPE SHMEM_TYPE_WINDOWS +#endif -#ifdef EXEC_BACKEND extern void PGSharedMemoryReAttach(void); extern void PGSharedMemoryNoReAttach(void); -#endif -extern PGShmemHeader *PGSharedMemoryCreate(Size size, bool makePrivate, - int port, PGShmemHeader **shim); +extern PGShmemHeader *PGSharedMemoryCreate(Size size, + PGShmemHeader **shim); extern bool PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2); extern void PGSharedMemoryDetach(void); diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h index bec162cc16d..7a79fb99138 100644 --- a/src/include/storage/pmsignal.h +++ b/src/include/storage/pmsignal.h @@ -4,7 +4,7 @@ * routines for signaling the postmaster from its child processes * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/pmsignal.h @@ -14,6 +14,16 @@ #ifndef PMSIGNAL_H #define PMSIGNAL_H +#include + +#ifdef HAVE_SYS_PRCTL_H +#include "sys/prctl.h" +#endif + +#ifdef HAVE_SYS_PROCCTL_H +#include "sys/procctl.h" +#endif + /* * Reasons for signaling the postmaster. We can cope with simultaneous * signals for different reasons. If the same reason is signaled multiple @@ -51,6 +61,34 @@ extern bool IsPostmasterChildWalSender(int slot); extern void MarkPostmasterChildActive(void); extern void MarkPostmasterChildInactive(void); extern void MarkPostmasterChildWalSender(void); -extern bool PostmasterIsAlive(void); +extern bool PostmasterIsAliveInternal(void); +extern void PostmasterDeathSignalInit(void); + + +/* + * Do we have a way to ask for a signal on parent death? + * + * If we do, pmsignal.c will set up a signal handler, that sets a flag when + * the parent dies. Checking the flag first makes PostmasterIsAlive() a lot + * cheaper in usual case that the postmaster is alive. + */ +#if (defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_PDEATHSIG)) || \ + (defined(HAVE_SYS_PROCCTL_H) && defined(PROC_PDEATHSIG_CTL)) +#define USE_POSTMASTER_DEATH_SIGNAL +#endif + +#ifdef USE_POSTMASTER_DEATH_SIGNAL +extern volatile sig_atomic_t postmaster_possibly_dead; + +static inline bool +PostmasterIsAlive(void) +{ + if (likely(!postmaster_possibly_dead)) + return true; + return PostmasterIsAliveInternal(); +} +#else +#define PostmasterIsAlive() PostmasterIsAliveInternal() +#endif #endif /* PMSIGNAL_H */ diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h index 6a3464daa1e..376245ecd70 100644 --- a/src/include/storage/predicate.h +++ b/src/include/storage/predicate.h @@ -4,7 +4,7 @@ * POSTGRES public predicate locking definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/predicate.h @@ -30,6 +30,11 @@ extern int max_predicate_locks_per_page; /* Number of SLRU buffers to use for predicate locking */ #define NUM_OLDSERXID_BUFFERS 16 +/* + * A handle used for sharing SERIALIZABLEXACT objects between the participants + * in a parallel query. + */ +typedef void *SerializableXactHandle; /* * function prototypes @@ -47,8 +52,8 @@ extern bool PageIsPredicateLocked(Relation relation, BlockNumber blkno); /* predicate lock maintenance */ extern Snapshot GetSerializableTransactionSnapshot(Snapshot snapshot); extern void SetSerializableTransactionSnapshot(Snapshot snapshot, - VirtualTransactionId *sourcevxid, - int sourcepid); + VirtualTransactionId *sourcevxid, + int sourcepid); extern void RegisterPredicateLockingXid(TransactionId xid); extern void PredicateLockRelation(Relation relation, Snapshot snapshot); extern void PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot); @@ -56,11 +61,11 @@ extern void PredicateLockTuple(Relation relation, HeapTuple tuple, Snapshot snap extern void PredicateLockPageSplit(Relation relation, BlockNumber oldblkno, BlockNumber newblkno); extern void PredicateLockPageCombine(Relation relation, BlockNumber oldblkno, BlockNumber newblkno); extern void TransferPredicateLocksToHeapRelation(Relation relation); -extern void ReleasePredicateLocks(bool isCommit); +extern void ReleasePredicateLocks(bool isCommit, bool isReadOnlySafe); /* conflict detection (may also trigger rollback) */ extern void CheckForSerializableConflictOut(bool valid, Relation relation, HeapTuple tuple, - Buffer buffer, Snapshot snapshot); + Buffer buffer, Snapshot snapshot); extern void CheckForSerializableConflictIn(Relation relation, HeapTuple tuple, Buffer buffer); extern void CheckTableForSerializableConflictIn(Relation relation); @@ -72,6 +77,10 @@ extern void AtPrepare_PredicateLocks(void); extern void PostPrepare_PredicateLocks(TransactionId xid); extern void PredicateLockTwoPhaseFinish(TransactionId xid, bool isCommit); extern void predicatelock_twophase_recover(TransactionId xid, uint16 info, - void *recdata, uint32 len); + void *recdata, uint32 len); + +/* parallel query support */ +extern SerializableXactHandle ShareSerializableXact(void); +extern void AttachSerializableXact(SerializableXactHandle handle); #endif /* PREDICATE_H */ diff --git a/src/include/storage/predicate_internals.h b/src/include/storage/predicate_internals.h index 0f736d37dff..a1b981302d9 100644 --- a/src/include/storage/predicate_internals.h +++ b/src/include/storage/predicate_internals.h @@ -4,7 +4,7 @@ * POSTGRES internal predicate locking definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/predicate_internals.h @@ -15,6 +15,7 @@ #define PREDICATE_INTERNALS_H #include "storage/lock.h" +#include "storage/lwlock.h" /* * Commit number. @@ -51,7 +52,7 @@ typedef uint64 SerCommitSeqNo; * * Eligibility for cleanup of committed transactions is generally determined * by comparing the transaction's finishedBefore field to - * SerializableGlobalXmin. + * SxactGlobalXmin. */ typedef struct SERIALIZABLEXACT { @@ -91,6 +92,9 @@ typedef struct SERIALIZABLEXACT SHM_QUEUE finishedLink; /* list link in * FinishedSerializableTransactions */ + LWLock predicateLockListLock; /* protects predicateLocks in parallel + * mode */ + /* * for r/o transactions: list of concurrent r/w transactions that we could * potentially have conflicts with, and vice versa for r/w transactions @@ -123,6 +127,12 @@ typedef struct SERIALIZABLEXACT #define SXACT_FLAG_RO_UNSAFE 0x00000100 #define SXACT_FLAG_SUMMARY_CONFLICT_IN 0x00000200 #define SXACT_FLAG_SUMMARY_CONFLICT_OUT 0x00000400 +/* + * The following flag means the transaction has been partially released + * already, but is being preserved because parallel workers might have a + * reference to it. It'll be recycled by the leader at end-of-transaction. + */ +#define SXACT_FLAG_PARTIALLY_RELEASED 0x00000800 /* * The following types are used to provide an ad hoc list for holding @@ -473,7 +483,7 @@ typedef struct TwoPhasePredicateRecord * locking internals. */ extern PredicateLockData *GetPredicateLockStatusData(void); -extern int GetSafeSnapshotBlockingPids(int blocked_pid, - int *output, int output_size); +extern int GetSafeSnapshotBlockingPids(int blocked_pid, + int *output, int output_size); #endif /* PREDICATE_INTERNALS_H */ diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 5c19a61dcf8..281e1db7259 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -4,7 +4,7 @@ * per-process shared memory data structures * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/proc.h @@ -63,7 +63,7 @@ struct XidCache (PROC_IN_VACUUM | PROC_IN_ANALYZE | PROC_VACUUM_FOR_WRAPAROUND) /* - * We allow a small number of "weak" relation locks (AccesShareLock, + * We allow a small number of "weak" relation locks (AccessShareLock, * RowShareLock, RowExclusiveLock) to be recorded in the PGPROC structure * rather than the main lock table. This eases contention on the lock * manager LWLocks. See storage/lmgr/README for additional details. @@ -114,6 +114,9 @@ struct PGPROC Oid databaseId; /* OID of database this backend is using */ Oid roleId; /* OID of role using this backend */ + Oid tempNamespaceId; /* OID of temp schema this backend is + * using */ + bool isBackgroundWorker; /* true if background worker. */ /* @@ -252,6 +255,8 @@ typedef struct PROC_HDR PGPROC *autovacFreeProcs; /* Head of list of bgworker free PGPROC structures */ PGPROC *bgworkerFreeProcs; + /* Head of list of walsender free PGPROC structures */ + PGPROC *walsenderFreeProcs; /* First pgproc waiting for group XID clear */ pg_atomic_uint32 procArrayGroupFirst; /* First pgproc waiting for group transaction status update */ @@ -327,4 +332,4 @@ extern PGPROC *AuxiliaryPidGetProc(int pid); extern void BecomeLockGroupLeader(void); extern bool BecomeLockGroupMember(PGPROC *leader, int pid); -#endif /* PROC_H */ +#endif /* _PROC_H_ */ diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index 75bab2985ff..da8b672096f 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -4,7 +4,7 @@ * POSTGRES process array definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/procarray.h @@ -66,12 +66,12 @@ extern void ProcArrayClearTransaction(PGPROC *proc); extern void ProcArrayInitRecovery(TransactionId initializedUptoXID); extern void ProcArrayApplyRecoveryInfo(RunningTransactions running); extern void ProcArrayApplyXidAssignment(TransactionId topxid, - int nsubxids, TransactionId *subxids); + int nsubxids, TransactionId *subxids); extern void RecordKnownAssignedTransactionIds(TransactionId xid); extern void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, - int nsubxids, TransactionId *subxids, - TransactionId max_xid); + int nsubxids, TransactionId *subxids, + TransactionId max_xid); extern void ExpireAllKnownAssignedTransactionIds(void); extern void ExpireOldKnownAssignedTransactionIds(TransactionId xid); @@ -81,7 +81,7 @@ extern int GetMaxSnapshotSubxidCount(void); extern Snapshot GetSnapshotData(Snapshot snapshot); extern bool ProcArrayInstallImportedXmin(TransactionId xmin, - VirtualTransactionId *sourcevxid); + VirtualTransactionId *sourcevxid); extern bool ProcArrayInstallRestoredXmin(TransactionId xmin, PGPROC *proc); extern RunningTransactions GetRunningTransactionData(void); @@ -101,8 +101,8 @@ extern int BackendXidGetPid(TransactionId xid); extern bool IsBackendPid(int pid); extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin, - bool excludeXmin0, bool allDbs, int excludeVacuum, - int *nvxids); + bool excludeXmin0, bool allDbs, int excludeVacuum, + int *nvxids); extern VirtualTransactionId *GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid); extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode); @@ -112,16 +112,16 @@ extern int CountDBConnections(Oid databaseid); extern void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending); extern int CountUserBackends(Oid roleid); extern bool CountOtherDBBackends(Oid databaseId, - int *nbackends, int *nprepared); + int *nbackends, int *nprepared); extern void XidCacheRemoveRunningXids(TransactionId xid, - int nxids, const TransactionId *xids, - TransactionId latestXid); + int nxids, const TransactionId *xids, + TransactionId latestXid); extern void ProcArraySetReplicationSlotXmin(TransactionId xmin, - TransactionId catalog_xmin, bool already_locked); + TransactionId catalog_xmin, bool already_locked); extern void ProcArrayGetReplicationSlotXmin(TransactionId *xmin, - TransactionId *catalog_xmin); + TransactionId *catalog_xmin); #endif /* PROCARRAY_H */ diff --git a/src/include/storage/proclist.h b/src/include/storage/proclist.h index 59a478e1f63..d7f6ae31417 100644 --- a/src/include/storage/proclist.h +++ b/src/include/storage/proclist.h @@ -10,7 +10,7 @@ * See proclist_types.h for the structs that these functions operate on. They * are separated to break a header dependency cycle with proc.h. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/storage/proclist.h diff --git a/src/include/storage/proclist_types.h b/src/include/storage/proclist_types.h index f4dac10fb64..a1fd93ddcc1 100644 --- a/src/include/storage/proclist_types.h +++ b/src/include/storage/proclist_types.h @@ -5,7 +5,7 @@ * * See proclist.h for functions that operate on these types. * - * Portions Copyright (c) 2016-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/include/storage/proclist_types.h diff --git a/src/include/storage/procsignal.h b/src/include/storage/procsignal.h index 6db0d69b71f..05b186a05c2 100644 --- a/src/include/storage/procsignal.h +++ b/src/include/storage/procsignal.h @@ -4,7 +4,7 @@ * Routines for interprocess signalling * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/procsignal.h @@ -52,8 +52,8 @@ extern Size ProcSignalShmemSize(void); extern void ProcSignalShmemInit(void); extern void ProcSignalInit(int pss_idx); -extern int SendProcSignal(pid_t pid, ProcSignalReason reason, - BackendId backendId); +extern int SendProcSignal(pid_t pid, ProcSignalReason reason, + BackendId backendId); extern void procsignal_sigusr1_handler(SIGNAL_ARGS); diff --git a/src/include/storage/reinit.h b/src/include/storage/reinit.h index 9a1c5bdc4e9..63d0b56d48e 100644 --- a/src/include/storage/reinit.h +++ b/src/include/storage/reinit.h @@ -4,7 +4,7 @@ * Reinitialization of unlogged relations * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/reinit.h @@ -19,8 +19,8 @@ extern void ResetUnloggedRelations(int op); -extern bool parse_filename_for_nontemp_relation( - const char *name, int *oidchars, ForkNumber *fork); +extern bool parse_filename_for_nontemp_relation(const char *name, + int *oidchars, ForkNumber *fork); #define UNLOGGED_RELATION_CLEANUP 0x0001 #define UNLOGGED_RELATION_INIT 0x0002 diff --git a/src/include/storage/relfilenode.h b/src/include/storage/relfilenode.h index abffd84a1cf..586500a6c56 100644 --- a/src/include/storage/relfilenode.h +++ b/src/include/storage/relfilenode.h @@ -4,7 +4,7 @@ * Physical access information for relations. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/relfilenode.h diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 04175dbaaa4..d0ab247623c 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -86,7 +86,7 @@ * when using the SysV semaphore code. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/s_lock.h @@ -383,7 +383,7 @@ tas(volatile slock_t *lock) register slock_t _res; /* - * See comment in /pg/backend/port/tas/solaris_sparc.s for why this + * See comment in src/backend/port/tas/sunstudio_sparc.s for why this * uses "ldstub", and that file uses "cas". gcc currently generates * sparcv7-targeted binaries, so "cas" use isn't possible. */ @@ -598,14 +598,31 @@ tas(volatile slock_t *lock) #if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */ -/* Note: on SGI we use the OS' mutex ABI, see below */ -/* Note: R10000 processors require a separate SYNC */ #define HAS_TEST_AND_SET typedef unsigned int slock_t; #define TAS(lock) tas(lock) +/* + * Original MIPS-I processors lacked the LL/SC instructions, but if we are + * so unfortunate as to be running on one of those, we expect that the kernel + * will handle the illegal-instruction traps and emulate them for us. On + * anything newer (and really, MIPS-I is extinct) LL/SC is the only sane + * choice because any other synchronization method must involve a kernel + * call. Unfortunately, many toolchains still default to MIPS-I as the + * codegen target; if the symbol __mips shows that that's the case, we + * have to force the assembler to accept LL/SC. + * + * R10000 and up processors require a separate SYNC, which has the same + * issues as LL/SC. + */ +#if __mips < 2 +#define MIPS_SET_MIPS2 " .set mips2 \n" +#else +#define MIPS_SET_MIPS2 +#endif + static __inline__ int tas(volatile slock_t *lock) { @@ -615,7 +632,7 @@ tas(volatile slock_t *lock) __asm__ __volatile__( " .set push \n" - " .set mips2 \n" + MIPS_SET_MIPS2 " .set noreorder \n" " .set nomacro \n" " ll %0, %2 \n" @@ -637,7 +654,7 @@ do \ { \ __asm__ __volatile__( \ " .set push \n" \ - " .set mips2 \n" \ + MIPS_SET_MIPS2 \ " .set noreorder \n" \ " .set nomacro \n" \ " sync \n" \ @@ -897,7 +914,7 @@ spin_delay(void) /* Blow up if we didn't have any way to do spinlocks */ #ifndef HAS_TEST_AND_SET -#error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. +#error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@lists.postgresql.org. #endif diff --git a/src/include/storage/sharedfileset.h b/src/include/storage/sharedfileset.h index d74c488e590..2d3667435b8 100644 --- a/src/include/storage/sharedfileset.h +++ b/src/include/storage/sharedfileset.h @@ -4,10 +4,10 @@ * Shared temporary file management. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * src/include/storage/sharedfilespace.h + * src/include/storage/sharedfileset.h * *------------------------------------------------------------------------- */ @@ -39,7 +39,7 @@ extern void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg); extern File SharedFileSetCreate(SharedFileSet *fileset, const char *name); extern File SharedFileSetOpen(SharedFileSet *fileset, const char *name); extern bool SharedFileSetDelete(SharedFileSet *fileset, const char *name, - bool error_on_failure); + bool error_on_failure); extern void SharedFileSetDeleteAll(SharedFileSet *fileset); #endif diff --git a/src/include/storage/shm_mq.h b/src/include/storage/shm_mq.h index f85f2eb7d17..02d8055d8ab 100644 --- a/src/include/storage/shm_mq.h +++ b/src/include/storage/shm_mq.h @@ -3,7 +3,7 @@ * shm_mq.h * single-reader, single-writer shared memory message queue * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/shm_mq.h @@ -57,7 +57,7 @@ extern PGPROC *shm_mq_get_sender(shm_mq *); /* Set up backend-local queue state. */ extern shm_mq_handle *shm_mq_attach(shm_mq *mq, dsm_segment *seg, - BackgroundWorkerHandle *handle); + BackgroundWorkerHandle *handle); /* Associate worker handle with shm_mq. */ extern void shm_mq_set_handle(shm_mq_handle *, BackgroundWorkerHandle *); @@ -70,11 +70,11 @@ extern shm_mq *shm_mq_get_queue(shm_mq_handle *mqh); /* Send or receive messages. */ extern shm_mq_result shm_mq_send(shm_mq_handle *mqh, - Size nbytes, const void *data, bool nowait); + Size nbytes, const void *data, bool nowait); extern shm_mq_result shm_mq_sendv(shm_mq_handle *mqh, - shm_mq_iovec *iov, int iovcnt, bool nowait); + shm_mq_iovec *iov, int iovcnt, bool nowait); extern shm_mq_result shm_mq_receive(shm_mq_handle *mqh, - Size *nbytesp, void **datap, bool nowait); + Size *nbytesp, void **datap, bool nowait); /* Wait for our counterparty to attach to the queue. */ extern shm_mq_result shm_mq_wait_for_attach(shm_mq_handle *mqh); diff --git a/src/include/storage/shm_toc.h b/src/include/storage/shm_toc.h index 4efe1723b4c..96b59bf43e0 100644 --- a/src/include/storage/shm_toc.h +++ b/src/include/storage/shm_toc.h @@ -12,7 +12,7 @@ * other data structure within the segment and only put the pointer to * the data structure itself in the table of contents. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/shm_toc.h diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h index b84d1043478..876e9086113 100644 --- a/src/include/storage/shmem.h +++ b/src/include/storage/shmem.h @@ -11,7 +11,7 @@ * at the same address. This means shared memory pointers can be passed * around directly between different processes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/shmem.h @@ -40,7 +40,7 @@ extern void *ShmemAllocUnlocked(Size size); extern bool ShmemAddrIsValid(const void *addr); extern void InitShmemIndex(void); extern HTAB *ShmemInitHash(const char *name, long init_size, long max_size, - HASHCTL *infoP, int hash_flags); + HASHCTL *infoP, int hash_flags); extern void *ShmemInitStruct(const char *name, Size size, bool *foundPtr); extern Size add_size(Size s1, Size s2); extern Size mul_size(Size s1, Size s2); @@ -71,9 +71,9 @@ extern void SHMQueueDelete(SHM_QUEUE *queue); extern void SHMQueueInsertBefore(SHM_QUEUE *queue, SHM_QUEUE *elem); extern void SHMQueueInsertAfter(SHM_QUEUE *queue, SHM_QUEUE *elem); extern Pointer SHMQueueNext(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, - Size linkOffset); + Size linkOffset); extern Pointer SHMQueuePrev(const SHM_QUEUE *queue, const SHM_QUEUE *curElem, - Size linkOffset); + Size linkOffset); extern bool SHMQueueEmpty(const SHM_QUEUE *queue); extern bool SHMQueueIsDetached(const SHM_QUEUE *queue); diff --git a/src/include/storage/sinval.h b/src/include/storage/sinval.h index 71567802154..a9cccfc6c44 100644 --- a/src/include/storage/sinval.h +++ b/src/include/storage/sinval.h @@ -4,7 +4,7 @@ * POSTGRES shared cache invalidation communication definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/sinval.h @@ -128,10 +128,9 @@ extern uint64 SharedInvalidMessageCounter; extern volatile sig_atomic_t catchupInterruptPending; extern void SendSharedInvalidMessages(const SharedInvalidationMessage *msgs, - int n); -extern void ReceiveSharedInvalidMessages( - void (*invalFunction) (SharedInvalidationMessage *msg), - void (*resetFunction) (void)); + int n); +extern void ReceiveSharedInvalidMessages(void (*invalFunction) (SharedInvalidationMessage *msg), + void (*resetFunction) (void)); /* signal handler for catchup events (PROCSIG_CATCHUP_INTERRUPT) */ extern void HandleCatchupInterrupt(void); @@ -143,11 +142,11 @@ extern void HandleCatchupInterrupt(void); */ extern void ProcessCatchupInterrupt(void); -extern int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, - bool *RelcacheInitFileInval); +extern int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, + bool *RelcacheInitFileInval); extern void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, - int nmsgs, bool RelcacheInitFileInval, - Oid dbid, Oid tsid); + int nmsgs, bool RelcacheInitFileInval, + Oid dbid, Oid tsid); extern void LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg); diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h index 2652b87b600..d2b67b18dac 100644 --- a/src/include/storage/sinvaladt.h +++ b/src/include/storage/sinvaladt.h @@ -12,7 +12,7 @@ * The struct type SharedInvalidationMessage, defining the contents of * a single message, is defined in sinval.h. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/sinvaladt.h diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h index 558e4d8518b..1543d8d870d 100644 --- a/src/include/storage/smgr.h +++ b/src/include/storage/smgr.h @@ -4,7 +4,7 @@ * storage manager switch public interface declarations. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/smgr.h @@ -14,11 +14,10 @@ #ifndef SMGR_H #define SMGR_H -#include "fmgr.h" +#include "lib/ilist.h" #include "storage/block.h" #include "storage/relfilenode.h" - /* * smgr.c maintains a table of SMgrRelation objects, which are essentially * cached file handles. An SMgrRelation is created (if not already present) @@ -72,7 +71,7 @@ typedef struct SMgrRelationData struct _MdfdVec *md_seg_fds[MAX_FORKNUM + 1]; /* if unowned, list link in list of all unowned SMgrRelations */ - struct SMgrRelationData *next_unowned_reln; + dlist_node node; } SMgrRelationData; typedef SMgrRelationData *SMgrRelation; @@ -91,57 +90,20 @@ extern void smgrclosenode(RelFileNodeBackend rnode); extern void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern void smgrdounlink(SMgrRelation reln, bool isRedo); extern void smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo); -extern void smgrdounlinkfork(SMgrRelation reln, ForkNumber forknum, bool isRedo); extern void smgrextend(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, char *buffer, bool skipFsync); + BlockNumber blocknum, char *buffer, bool skipFsync); extern void smgrprefetch(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum); + BlockNumber blocknum); extern void smgrread(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, char *buffer); + BlockNumber blocknum, char *buffer); extern void smgrwrite(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, char *buffer, bool skipFsync); + BlockNumber blocknum, char *buffer, bool skipFsync); extern void smgrwriteback(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, BlockNumber nblocks); + BlockNumber blocknum, BlockNumber nblocks); extern BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum); -extern void smgrtruncate(SMgrRelation reln, ForkNumber forknum, - BlockNumber nblocks); +extern void smgrtruncate(SMgrRelation reln, ForkNumber *forknum, + int nforks, BlockNumber *nblocks); extern void smgrimmedsync(SMgrRelation reln, ForkNumber forknum); -extern void smgrpreckpt(void); -extern void smgrsync(void); -extern void smgrpostckpt(void); extern void AtEOXact_SMgr(void); - -/* internals: move me elsewhere -- ay 7/94 */ - -/* in md.c */ -extern void mdinit(void); -extern void mdclose(SMgrRelation reln, ForkNumber forknum); -extern void mdcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); -extern bool mdexists(SMgrRelation reln, ForkNumber forknum); -extern void mdunlink(RelFileNodeBackend rnode, ForkNumber forknum, bool isRedo); -extern void mdextend(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, char *buffer, bool skipFsync); -extern void mdprefetch(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum); -extern void mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, - char *buffer); -extern void mdwrite(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, char *buffer, bool skipFsync); -extern void mdwriteback(SMgrRelation reln, ForkNumber forknum, - BlockNumber blocknum, BlockNumber nblocks); -extern BlockNumber mdnblocks(SMgrRelation reln, ForkNumber forknum); -extern void mdtruncate(SMgrRelation reln, ForkNumber forknum, - BlockNumber nblocks); -extern void mdimmedsync(SMgrRelation reln, ForkNumber forknum); -extern void mdpreckpt(void); -extern void mdsync(void); -extern void mdpostckpt(void); - -extern void SetForwardFsyncRequests(void); -extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum, - BlockNumber segno); -extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum); -extern void ForgetDatabaseFsyncRequests(Oid dbid); - #endif /* SMGR_H */ diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h index b49fc10aa47..0f61d45eb71 100644 --- a/src/include/storage/spin.h +++ b/src/include/storage/spin.h @@ -41,7 +41,7 @@ * be again. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/spin.h diff --git a/src/include/storage/standby.h b/src/include/storage/standby.h index 28bf8f2f398..a3f8f82ff32 100644 --- a/src/include/storage/standby.h +++ b/src/include/storage/standby.h @@ -4,7 +4,7 @@ * Definitions for hot standby mode. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/standby.h @@ -28,7 +28,7 @@ extern void InitRecoveryTransactionEnvironment(void); extern void ShutdownRecoveryTransactionEnvironment(void); extern void ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, - RelFileNode node); + RelFileNode node); extern void ResolveRecoveryConflictWithTablespace(Oid tsid); extern void ResolveRecoveryConflictWithDatabase(Oid dbid); @@ -48,9 +48,9 @@ extern void StandbyLockTimeoutHandler(void); */ extern void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid); extern void StandbyReleaseLockTree(TransactionId xid, - int nsubxids, TransactionId *subxids); + int nsubxids, TransactionId *subxids); extern void StandbyReleaseAllLocks(void); -extern void StandbyReleaseOldLocks(int nxids, TransactionId *xids); +extern void StandbyReleaseOldLocks(TransactionId oldxid); #define MinSizeOfXactRunningXacts offsetof(xl_running_xacts, xids) @@ -72,7 +72,7 @@ typedef struct RunningTransactionsData int xcnt; /* # of xact ids in xids[] */ int subxcnt; /* # of subxact ids in xids[] */ bool subxid_overflow; /* snapshot overflowed, subxids missing */ - TransactionId nextXid; /* copy of ShmemVariableCache->nextXid */ + TransactionId nextXid; /* xid from ShmemVariableCache->nextFullXid */ TransactionId oldestRunningXid; /* *not* oldestXmin */ TransactionId latestCompletedXid; /* so we can set xmax */ @@ -86,6 +86,6 @@ extern void LogAccessExclusiveLockPrepare(void); extern XLogRecPtr LogStandbySnapshot(void); extern void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, - bool relcacheInitFileInval); + bool relcacheInitFileInval); #endif /* STANDBY_H */ diff --git a/src/include/storage/standbydefs.h b/src/include/storage/standbydefs.h index bb6144805a7..9a612a5834b 100644 --- a/src/include/storage/standbydefs.h +++ b/src/include/storage/standbydefs.h @@ -1,10 +1,10 @@ /*------------------------------------------------------------------------- * - * standbydef.h + * standbydefs.h * Frontend exposed definitions for hot standby mode. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/storage/standbydefs.h @@ -24,9 +24,9 @@ extern void standby_redo(XLogReaderState *record); extern void standby_desc(StringInfo buf, XLogReaderState *record); extern const char *standby_identify(uint8 info); extern void standby_desc_invalidations(StringInfo buf, - int nmsgs, SharedInvalidationMessage *msgs, - Oid dbId, Oid tsId, - bool relcacheInitFileInval); + int nmsgs, SharedInvalidationMessage *msgs, + Oid dbId, Oid tsId, + bool relcacheInitFileInval); /* * XLOG message types @@ -49,7 +49,7 @@ typedef struct xl_running_xacts int xcnt; /* # of xact ids in xids[] */ int subxcnt; /* # of subxact ids in xids[] */ bool subxid_overflow; /* snapshot overflowed, subxids missing */ - TransactionId nextXid; /* copy of ShmemVariableCache->nextXid */ + TransactionId nextXid; /* xid from ShmemVariableCache->nextFullXid */ TransactionId oldestRunningXid; /* *not* oldestXmin */ TransactionId latestCompletedXid; /* so we can set xmax */ @@ -64,7 +64,7 @@ typedef struct xl_invalidations { Oid dbId; /* MyDatabaseId */ Oid tsId; /* MyDatabaseTableSpace */ - bool relcacheInitFileInval; /* invalidate relcache init file */ + bool relcacheInitFileInval; /* invalidate relcache init files */ int nmsgs; /* number of shared inval msgs */ SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]; } xl_invalidations; diff --git a/src/include/storage/sync.h b/src/include/storage/sync.h new file mode 100644 index 00000000000..16428c5f5fb --- /dev/null +++ b/src/include/storage/sync.h @@ -0,0 +1,62 @@ +/*------------------------------------------------------------------------- + * + * sync.h + * File synchronization management code. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/storage/sync.h + * + *------------------------------------------------------------------------- + */ +#ifndef SYNC_H +#define SYNC_H + +#include "storage/relfilenode.h" + +/* + * Type of sync request. These are used to manage the set of pending + * requests to call a sync handler's sync or unlink functions at the next + * checkpoint. + */ +typedef enum SyncRequestType +{ + SYNC_REQUEST, /* schedule a call of sync function */ + SYNC_UNLINK_REQUEST, /* schedule a call of unlink function */ + SYNC_FORGET_REQUEST, /* forget all calls for a tag */ + SYNC_FILTER_REQUEST /* forget all calls satisfying match fn */ +} SyncRequestType; + +/* + * Which set of functions to use to handle a given request. The values of + * the enumerators must match the indexes of the function table in sync.c. + */ +typedef enum SyncRequestHandler +{ + SYNC_HANDLER_MD = 0 /* md smgr */ +} SyncRequestHandler; + +/* + * A tag identifying a file. Currently it has the members required for md.c's + * usage, but sync.c has no knowledge of the internal structure, and it is + * liable to change as required by future handlers. + */ +typedef struct FileTag +{ + int16 handler; /* SyncRequestHandler value, saving space */ + int16 forknum; /* ForkNumber, saving space */ + RelFileNode rnode; + uint32 segno; +} FileTag; + +extern void InitSync(void); +extern void SyncPreCheckpoint(void); +extern void SyncPostCheckpoint(void); +extern void ProcessSyncRequests(void); +extern void RememberSyncRequest(const FileTag *ftag, SyncRequestType type); +extern void EnableSyncRequestForwarding(void); +extern bool RegisterSyncRequest(const FileTag *ftag, SyncRequestType type, + bool retryOnError); + +#endif /* SYNC_H */ diff --git a/src/include/tcop/deparse_utility.h b/src/include/tcop/deparse_utility.h index 8459463391a..7884e046477 100644 --- a/src/include/tcop/deparse_utility.h +++ b/src/include/tcop/deparse_utility.h @@ -2,7 +2,7 @@ * * deparse_utility.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/deparse_utility.h @@ -44,6 +44,7 @@ typedef struct CollectedATSubcmd typedef struct CollectedCommand { CollectedCommandType type; + bool in_extension; Node *parsetree; @@ -100,6 +101,8 @@ typedef struct CollectedCommand ObjectType objtype; } defprivs; } d; + + struct CollectedCommand *parent; /* when nested */ } CollectedCommand; #endif /* DEPARSE_UTILITY_H */ diff --git a/src/include/tcop/dest.h b/src/include/tcop/dest.h index 82f0f2e741c..3fc96198846 100644 --- a/src/include/tcop/dest.h +++ b/src/include/tcop/dest.h @@ -57,7 +57,7 @@ * calls in portal and cursor manipulations. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/dest.h diff --git a/src/include/tcop/fastpath.h b/src/include/tcop/fastpath.h index 6e1608a4fa9..6113733bf21 100644 --- a/src/include/tcop/fastpath.h +++ b/src/include/tcop/fastpath.h @@ -3,7 +3,7 @@ * fastpath.h * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/fastpath.h diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h index 507d89cf69b..9e24cfa6610 100644 --- a/src/include/tcop/pquery.h +++ b/src/include/tcop/pquery.h @@ -4,7 +4,7 @@ * prototypes for pquery.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/pquery.h @@ -28,18 +28,18 @@ extern List *FetchPortalTargetList(Portal portal); extern List *FetchStatementTargetList(Node *stmt); extern void PortalStart(Portal portal, ParamListInfo params, - int eflags, Snapshot snapshot); + int eflags, Snapshot snapshot); extern void PortalSetResultFormat(Portal portal, int nFormats, - int16 *formats); + int16 *formats); extern bool PortalRun(Portal portal, long count, bool isTopLevel, - bool run_once, DestReceiver *dest, DestReceiver *altdest, - char *completionTag); + bool run_once, DestReceiver *dest, DestReceiver *altdest, + char *completionTag); extern uint64 PortalRunFetch(Portal portal, - FetchDirection fdirection, - long count, - DestReceiver *dest); + FetchDirection fdirection, + long count, + DestReceiver *dest); #endif /* PQUERY_H */ diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 63b4e4864d0..ec21f7e45c5 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -4,16 +4,11 @@ * prototypes for postgres.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/tcopprot.h * - * OLD COMMENTS - * This file was created so that other c files could get the two - * function prototypes without having to include tcop.h which single - * handedly includes the whole f*cking tree -- mer 5 Nov. 1991 - * *------------------------------------------------------------------------- */ #ifndef TCOPPROT_H @@ -49,18 +44,18 @@ extern PGDLLIMPORT int log_statement; extern List *pg_parse_query(const char *query_string); extern List *pg_analyze_and_rewrite(RawStmt *parsetree, - const char *query_string, - Oid *paramTypes, int numParams, - QueryEnvironment *queryEnv); + const char *query_string, + Oid *paramTypes, int numParams, + QueryEnvironment *queryEnv); extern List *pg_analyze_and_rewrite_params(RawStmt *parsetree, - const char *query_string, - ParserSetupHook parserSetup, - void *parserSetupArg, - QueryEnvironment *queryEnv); + const char *query_string, + ParserSetupHook parserSetup, + void *parserSetupArg, + QueryEnvironment *queryEnv); extern PlannedStmt *pg_plan_query(Query *querytree, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams); extern List *pg_plan_queries(List *querytrees, int cursorOptions, - ParamListInfo boundParams); + ParamListInfo boundParams); extern bool check_max_stack_depth(int *newval, void **extra, GucSource source); extern void assign_max_stack_depth(int newval, void *extra); @@ -75,18 +70,18 @@ extern void ProcessClientReadInterrupt(bool blocked); extern void ProcessClientWriteInterrupt(bool blocked); extern void process_postgres_switches(int argc, char *argv[], - GucContext ctx, const char **dbname); + GucContext ctx, const char **dbname); extern void PostgresMain(int argc, char *argv[], - const char *dbname, - const char *username) pg_attribute_noreturn(); + const char *dbname, + const char *username) pg_attribute_noreturn(); extern long get_stack_depth_rlimit(void); extern void ResetUsage(void); extern void ShowUsage(const char *title); extern int check_log_duration(char *msec_str, bool was_logged); extern void set_debug_options(int debug_flag, - GucContext context, GucSource source); + GucContext context, GucSource source); extern bool set_plan_disabling_options(const char *arg, - GucContext context, GucSource source); + GucContext context, GucSource source); extern const char *get_stats_option_name(const char *arg); #endif /* TCOPPROT_H */ diff --git a/src/include/tcop/utility.h b/src/include/tcop/utility.h index 880d19311a6..5abcacf6a0c 100644 --- a/src/include/tcop/utility.h +++ b/src/include/tcop/utility.h @@ -4,7 +4,7 @@ * prototypes for utility.c. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tcop/utility.h @@ -20,7 +20,8 @@ typedef enum { PROCESS_UTILITY_TOPLEVEL, /* toplevel interactive command */ PROCESS_UTILITY_QUERY, /* a complete query, but not toplevel */ - PROCESS_UTILITY_QUERY_NONATOMIC, /* a complete query, nonatomic execution context */ + PROCESS_UTILITY_QUERY_NONATOMIC, /* a complete query, nonatomic + * execution context */ PROCESS_UTILITY_SUBCOMMAND /* a portion of a query */ } ProcessUtilityContext; @@ -33,13 +34,13 @@ typedef void (*ProcessUtility_hook_type) (PlannedStmt *pstmt, extern PGDLLIMPORT ProcessUtility_hook_type ProcessUtility_hook; extern void ProcessUtility(PlannedStmt *pstmt, const char *queryString, - ProcessUtilityContext context, ParamListInfo params, - QueryEnvironment *queryEnv, - DestReceiver *dest, char *completionTag); + ProcessUtilityContext context, ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, char *completionTag); extern void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, - ProcessUtilityContext context, ParamListInfo params, - QueryEnvironment *queryEnv, - DestReceiver *dest, char *completionTag); + ProcessUtilityContext context, ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, char *completionTag); extern bool UtilityReturnsTuples(Node *parsetree); diff --git a/src/include/tsearch/dicts/regis.h b/src/include/tsearch/dicts/regis.h index 15dba3a5059..f3b37f27d67 100644 --- a/src/include/tsearch/dicts/regis.h +++ b/src/include/tsearch/dicts/regis.h @@ -4,7 +4,7 @@ * * Declarations for fast regex subset, used by ISpell * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/tsearch/dicts/regis.h * diff --git a/src/include/tsearch/dicts/spell.h b/src/include/tsearch/dicts/spell.h index 210f97dda90..4cba5784368 100644 --- a/src/include/tsearch/dicts/spell.h +++ b/src/include/tsearch/dicts/spell.h @@ -4,7 +4,7 @@ * * Declarations for ISpell dictionary * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/tsearch/dicts/spell.h * diff --git a/src/include/tsearch/ts_cache.h b/src/include/tsearch/ts_cache.h index 410f1d54afb..77e325d1015 100644 --- a/src/include/tsearch/ts_cache.h +++ b/src/include/tsearch/ts_cache.h @@ -3,7 +3,7 @@ * ts_cache.h * Tsearch related object caches. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/tsearch/ts_cache.h diff --git a/src/include/tsearch/ts_locale.h b/src/include/tsearch/ts_locale.h index 02809539dd1..9e8cd77245b 100644 --- a/src/include/tsearch/ts_locale.h +++ b/src/include/tsearch/ts_locale.h @@ -3,7 +3,7 @@ * ts_locale.h * locale compatibility layer for tsearch * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * src/include/tsearch/ts_locale.h * @@ -55,7 +55,7 @@ extern char *lowerstr(const char *str); extern char *lowerstr_with_len(const char *str, int len); extern bool tsearch_readline_begin(tsearch_readline_state *stp, - const char *filename); + const char *filename); extern char *tsearch_readline(tsearch_readline_state *stp); extern void tsearch_readline_end(tsearch_readline_state *stp); diff --git a/src/include/tsearch/ts_public.h b/src/include/tsearch/ts_public.h index 0b7a5aa68ed..465a3616a6e 100644 --- a/src/include/tsearch/ts_public.h +++ b/src/include/tsearch/ts_public.h @@ -4,7 +4,7 @@ * Public interface to various tsearch modules, such as * parsers and dictionaries. * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * src/include/tsearch/ts_public.h * @@ -65,7 +65,7 @@ typedef struct * Common useful things for tsearch subsystem */ extern char *get_tsearch_config_filename(const char *basename, - const char *extension); + const char *extension); /* * Often useful stopword list management @@ -77,7 +77,7 @@ typedef struct } StopList; extern void readstoplist(const char *fname, StopList *s, - char *(*wordop) (const char *)); + char *(*wordop) (const char *)); extern bool searchstoplist(StopList *s, char *key); /* diff --git a/src/include/tsearch/ts_type.h b/src/include/tsearch/ts_type.h index ccf5701aa36..559cf84cbc1 100644 --- a/src/include/tsearch/ts_type.h +++ b/src/include/tsearch/ts_type.h @@ -3,7 +3,7 @@ * ts_type.h * Definitions for the tsvector and tsquery types * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * src/include/tsearch/ts_type.h * diff --git a/src/include/tsearch/ts_utils.h b/src/include/tsearch/ts_utils.h index 73e969fe9ce..ee60a2a629c 100644 --- a/src/include/tsearch/ts_utils.h +++ b/src/include/tsearch/ts_utils.h @@ -3,7 +3,7 @@ * ts_utils.h * helper utilities for tsearch * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * src/include/tsearch/ts_utils.h * @@ -32,9 +32,9 @@ typedef struct TSVectorParseStateData *TSVectorParseState; extern TSVectorParseState init_tsvector_parser(char *input, int flags); extern void reset_tsvector_parser(TSVectorParseState state, char *input); extern bool gettoken_tsvector(TSVectorParseState state, - char **token, int *len, - WordEntryPos **pos, int *poslen, - char **endptr); + char **token, int *len, + WordEntryPos **pos, int *poslen, + char **endptr); extern void close_tsvector_parser(TSVectorParseState state); /* phrase operator begins with '<' */ @@ -68,7 +68,7 @@ extern TSQuery parse_tsquery(char *buf, /* Functions for use by PushFunction implementations */ extern void pushValue(TSQueryParserState state, - char *strval, int lenval, int16 weight, bool prefix); + char *strval, int lenval, int16 weight, bool prefix); extern void pushStop(TSQueryParserState state); extern void pushOperator(TSQueryParserState state, int8 oper, int16 distance); @@ -113,7 +113,7 @@ extern void parsetext(Oid cfgId, ParsedText *prs, char *buf, int32 buflen); */ extern void hlparsetext(Oid cfgId, HeadlineParsedText *prs, TSQuery query, - char *buf, int32 buflen); + char *buf, int32 buflen); extern text *generateHeadline(HeadlineParsedText *prs); /* @@ -190,7 +190,7 @@ typedef bool (*TSExecuteCallback) (void *arg, QueryOperand *val, #define TS_EXEC_PHRASE_NO_POS (0x02) extern bool TS_execute(QueryItem *curitem, void *arg, uint32 flags, - TSExecuteCallback chkcond); + TSExecuteCallback chkcond); extern bool tsquery_requires_match(QueryItem *curitem); /* @@ -250,6 +250,6 @@ extern void QTNClearFlags(QTNode *in, uint32 flags); extern bool QTNEq(QTNode *a, QTNode *b); extern TSQuerySign makeTSQuerySign(TSQuery a); extern QTNode *findsubquery(QTNode *root, QTNode *ex, QTNode *subs, - bool *isfind); + bool *isfind); #endif /* _PG_TS_UTILS_H_ */ diff --git a/src/include/utils/.gitignore b/src/include/utils/.gitignore index 25db658da51..05cfa7a8d6c 100644 --- a/src/include/utils/.gitignore +++ b/src/include/utils/.gitignore @@ -2,3 +2,4 @@ /fmgrprotos.h /probes.h /errcodes.h +/header-stamp diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index f4d4be8d0d3..b99da737283 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -4,7 +4,7 @@ * Definition of (and support for) access control list data structures. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/acl.h @@ -35,7 +35,6 @@ #include "access/htup.h" #include "nodes/parsenodes.h" #include "parser/parse_node.h" -#include "utils/array.h" #include "utils/snapshot.h" @@ -104,7 +103,7 @@ typedef struct AclItem /* * Acl a one-dimensional array of AclItem */ -typedef ArrayType Acl; +typedef struct ArrayType Acl; #define ACL_NUM(ACL) (ARR_DIMS(ACL)[0]) #define ACL_DAT(ACL) ((AclItem *) ARR_DATA_PTR(ACL)) @@ -188,10 +187,12 @@ typedef enum */ extern Acl *acldefault(ObjectType objtype, Oid ownerId); extern Acl *get_user_default_acl(ObjectType objtype, Oid ownerId, - Oid nsp_oid); + Oid nsp_oid); +extern void recordDependencyOnNewAcl(Oid classId, Oid objectId, int32 objsubId, + Oid ownerId, Acl *acl); extern Acl *aclupdate(const Acl *old_acl, const AclItem *mod_aip, - int modechg, Oid ownerId, DropBehavior behavior); + int modechg, Oid ownerId, DropBehavior behavior); extern Acl *aclnewowner(const Acl *old_acl, Oid oldOwnerId, Oid newOwnerId); extern Acl *make_empty_acl(void); extern Acl *aclcopy(const Acl *orig_acl); @@ -201,7 +202,7 @@ extern void aclitemsort(Acl *acl); extern bool aclequal(const Acl *left_acl, const Acl *right_acl); extern AclMode aclmask(const Acl *acl, Oid roleid, Oid ownerId, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern int aclmembers(const Acl *acl, Oid **roleids); extern bool has_privs_of_role(Oid member, Oid role); @@ -217,8 +218,8 @@ extern HeapTuple get_rolespec_tuple(const RoleSpec *role); extern char *get_rolespec_name(const RoleSpec *role); extern void select_best_grantor(Oid roleId, AclMode privileges, - const Acl *acl, Oid ownerId, - Oid *grantorId, AclMode *grantOptions); + const Acl *acl, Oid ownerId, + Oid *grantorId, AclMode *grantOptions); extern void initialize_acl(void); @@ -232,38 +233,38 @@ extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid); extern void RemoveDefaultACLById(Oid defaclOid); extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, - Oid roleid, AclMode mask, AclMaskHow how); + Oid roleid, AclMode mask, AclMaskHow how); extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_language_aclmask(Oid lang_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid, - AclMode mask, AclMaskHow how, Snapshot snapshot); + AclMode mask, AclMaskHow how, Snapshot snapshot); extern AclMode pg_namespace_aclmask(Oid nsp_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_tablespace_aclmask(Oid spc_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_foreign_data_wrapper_aclmask(Oid fdw_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_foreign_server_aclmask(Oid srv_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid, - AclMode mask, AclMaskHow how); + AclMode mask, AclMaskHow how); extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, - Oid roleid, AclMode mode); + Oid roleid, AclMode mode); extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, - AclMode mode, AclMaskHow how); + AclMode mode, AclMaskHow how); extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode); extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode); extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode); extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode); extern AclResult pg_largeobject_aclcheck_snapshot(Oid lang_oid, Oid roleid, - AclMode mode, Snapshot snapshot); + AclMode mode, Snapshot snapshot); extern AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode); extern AclResult pg_tablespace_aclcheck(Oid spc_oid, Oid roleid, AclMode mode); extern AclResult pg_foreign_data_wrapper_aclcheck(Oid fdw_oid, Oid roleid, AclMode mode); @@ -271,10 +272,10 @@ extern AclResult pg_foreign_server_aclcheck(Oid srv_oid, Oid roleid, AclMode mod extern AclResult pg_type_aclcheck(Oid type_oid, Oid roleid, AclMode mode); extern void aclcheck_error(AclResult aclerr, ObjectType objtype, - const char *objectname); + const char *objectname); extern void aclcheck_error_col(AclResult aclerr, ObjectType objtype, - const char *objectname, const char *colname); + const char *objectname, const char *colname); extern void aclcheck_error_type(AclResult aclerr, Oid typeOid); diff --git a/src/include/utils/aclchk_internal.h b/src/include/utils/aclchk_internal.h index f7c44fcd4ba..890d71556ff 100644 --- a/src/include/utils/aclchk_internal.h +++ b/src/include/utils/aclchk_internal.h @@ -2,7 +2,7 @@ * * aclchk_internal.h * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/aclchk_internal.h diff --git a/src/include/utils/array.h b/src/include/utils/array.h index afbb532e9c2..5cfafe00457 100644 --- a/src/include/utils/array.h +++ b/src/include/utils/array.h @@ -51,7 +51,7 @@ * arrays holding the elements. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/array.h @@ -77,7 +77,7 @@ struct ExprContext; * CAUTION: if you change the header for ordinary arrays you will also * need to change the headers for oidvector and int2vector! */ -typedef struct +typedef struct ArrayType { int32 vl_len_; /* varlena header (do not touch directly!) */ int ndim; /* # of dimensions */ @@ -157,7 +157,10 @@ typedef struct ExpandedArrayHeader /* * Functions that can handle either a "flat" varlena array or an expanded - * array use this union to work with their input. + * array use this union to work with their input. Don't refer to "flt"; + * instead, cast to ArrayType. This struct nominally requires 8-byte + * alignment on 64-bit, but it's often used for an ArrayType having 4-byte + * alignment. UBSan complains about referencing "flt" in such cases. */ typedef union AnyArrayType { @@ -311,17 +314,21 @@ typedef struct ArrayIteratorData *ArrayIterator; * Macros for working with AnyArrayType inputs. Beware multiple references! */ #define AARR_NDIM(a) \ - (VARATT_IS_EXPANDED_HEADER(a) ? (a)->xpn.ndims : ARR_NDIM(&(a)->flt)) + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.ndims : ARR_NDIM((ArrayType *) (a))) #define AARR_HASNULL(a) \ (VARATT_IS_EXPANDED_HEADER(a) ? \ ((a)->xpn.dvalues != NULL ? (a)->xpn.dnulls != NULL : ARR_HASNULL((a)->xpn.fvalue)) : \ - ARR_HASNULL(&(a)->flt)) + ARR_HASNULL((ArrayType *) (a))) #define AARR_ELEMTYPE(a) \ - (VARATT_IS_EXPANDED_HEADER(a) ? (a)->xpn.element_type : ARR_ELEMTYPE(&(a)->flt)) + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.element_type : ARR_ELEMTYPE((ArrayType *) (a))) #define AARR_DIMS(a) \ - (VARATT_IS_EXPANDED_HEADER(a) ? (a)->xpn.dims : ARR_DIMS(&(a)->flt)) + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.dims : ARR_DIMS((ArrayType *) (a))) #define AARR_LBOUND(a) \ - (VARATT_IS_EXPANDED_HEADER(a) ? (a)->xpn.lbound : ARR_LBOUND(&(a)->flt)) + (VARATT_IS_EXPANDED_HEADER(a) ? \ + (a)->xpn.lbound : ARR_LBOUND((ArrayType *) (a))) /* @@ -333,92 +340,92 @@ extern bool Array_nulls; * prototypes for functions defined in arrayfuncs.c */ extern void CopyArrayEls(ArrayType *array, - Datum *values, - bool *nulls, - int nitems, - int typlen, - bool typbyval, - char typalign, - bool freedata); + Datum *values, + bool *nulls, + int nitems, + int typlen, + bool typbyval, + char typalign, + bool freedata); extern Datum array_get_element(Datum arraydatum, int nSubscripts, int *indx, - int arraytyplen, int elmlen, bool elmbyval, char elmalign, - bool *isNull); + int arraytyplen, int elmlen, bool elmbyval, char elmalign, + bool *isNull); extern Datum array_set_element(Datum arraydatum, int nSubscripts, int *indx, - Datum dataValue, bool isNull, - int arraytyplen, int elmlen, bool elmbyval, char elmalign); + Datum dataValue, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); extern Datum array_get_slice(Datum arraydatum, int nSubscripts, - int *upperIndx, int *lowerIndx, - bool *upperProvided, bool *lowerProvided, - int arraytyplen, int elmlen, bool elmbyval, char elmalign); + int *upperIndx, int *lowerIndx, + bool *upperProvided, bool *lowerProvided, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); extern Datum array_set_slice(Datum arraydatum, int nSubscripts, - int *upperIndx, int *lowerIndx, - bool *upperProvided, bool *lowerProvided, - Datum srcArrayDatum, bool isNull, - int arraytyplen, int elmlen, bool elmbyval, char elmalign); + int *upperIndx, int *lowerIndx, + bool *upperProvided, bool *lowerProvided, + Datum srcArrayDatum, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx, - int arraytyplen, int elmlen, bool elmbyval, char elmalign, - bool *isNull); + int arraytyplen, int elmlen, bool elmbyval, char elmalign, + bool *isNull); extern ArrayType *array_set(ArrayType *array, int nSubscripts, int *indx, - Datum dataValue, bool isNull, - int arraytyplen, int elmlen, bool elmbyval, char elmalign); + Datum dataValue, bool isNull, + int arraytyplen, int elmlen, bool elmbyval, char elmalign); extern Datum array_map(Datum arrayd, - struct ExprState *exprstate, struct ExprContext *econtext, - Oid retType, ArrayMapState *amstate); + struct ExprState *exprstate, struct ExprContext *econtext, + Oid retType, ArrayMapState *amstate); extern void array_bitmap_copy(bits8 *destbitmap, int destoffset, - const bits8 *srcbitmap, int srcoffset, - int nitems); + const bits8 *srcbitmap, int srcoffset, + int nitems); extern ArrayType *construct_array(Datum *elems, int nelems, - Oid elmtype, - int elmlen, bool elmbyval, char elmalign); + Oid elmtype, + int elmlen, bool elmbyval, char elmalign); extern ArrayType *construct_md_array(Datum *elems, - bool *nulls, - int ndims, - int *dims, - int *lbs, - Oid elmtype, int elmlen, bool elmbyval, char elmalign); + bool *nulls, + int ndims, + int *dims, + int *lbs, + Oid elmtype, int elmlen, bool elmbyval, char elmalign); extern ArrayType *construct_empty_array(Oid elmtype); extern ExpandedArrayHeader *construct_empty_expanded_array(Oid element_type, - MemoryContext parentcontext, - ArrayMetaState *metacache); + MemoryContext parentcontext, + ArrayMetaState *metacache); extern void deconstruct_array(ArrayType *array, - Oid elmtype, - int elmlen, bool elmbyval, char elmalign, - Datum **elemsp, bool **nullsp, int *nelemsp); + Oid elmtype, + int elmlen, bool elmbyval, char elmalign, + Datum **elemsp, bool **nullsp, int *nelemsp); extern bool array_contains_nulls(ArrayType *array); extern ArrayBuildState *initArrayResult(Oid element_type, - MemoryContext rcontext, bool subcontext); + MemoryContext rcontext, bool subcontext); extern ArrayBuildState *accumArrayResult(ArrayBuildState *astate, - Datum dvalue, bool disnull, - Oid element_type, - MemoryContext rcontext); + Datum dvalue, bool disnull, + Oid element_type, + MemoryContext rcontext); extern Datum makeArrayResult(ArrayBuildState *astate, - MemoryContext rcontext); + MemoryContext rcontext); extern Datum makeMdArrayResult(ArrayBuildState *astate, int ndims, - int *dims, int *lbs, MemoryContext rcontext, bool release); + int *dims, int *lbs, MemoryContext rcontext, bool release); extern ArrayBuildStateArr *initArrayResultArr(Oid array_type, Oid element_type, - MemoryContext rcontext, bool subcontext); + MemoryContext rcontext, bool subcontext); extern ArrayBuildStateArr *accumArrayResultArr(ArrayBuildStateArr *astate, - Datum dvalue, bool disnull, - Oid array_type, - MemoryContext rcontext); + Datum dvalue, bool disnull, + Oid array_type, + MemoryContext rcontext); extern Datum makeArrayResultArr(ArrayBuildStateArr *astate, - MemoryContext rcontext, bool release); + MemoryContext rcontext, bool release); extern ArrayBuildStateAny *initArrayResultAny(Oid input_type, - MemoryContext rcontext, bool subcontext); + MemoryContext rcontext, bool subcontext); extern ArrayBuildStateAny *accumArrayResultAny(ArrayBuildStateAny *astate, - Datum dvalue, bool disnull, - Oid input_type, - MemoryContext rcontext); + Datum dvalue, bool disnull, + Oid input_type, + MemoryContext rcontext); extern Datum makeArrayResultAny(ArrayBuildStateAny *astate, - MemoryContext rcontext, bool release); + MemoryContext rcontext, bool release); extern ArrayIterator array_create_iterator(ArrayType *arr, int slice_ndim, ArrayMetaState *mstate); extern bool array_iterate(ArrayIterator iterator, Datum *value, bool *isnull); @@ -441,10 +448,10 @@ extern int32 *ArrayGetIntegerTypmods(ArrayType *arr, int *n); * prototypes for functions defined in array_expanded.c */ extern Datum expand_array(Datum arraydatum, MemoryContext parentcontext, - ArrayMetaState *metacache); + ArrayMetaState *metacache); extern ExpandedArrayHeader *DatumGetExpandedArray(Datum d); extern ExpandedArrayHeader *DatumGetExpandedArrayX(Datum d, - ArrayMetaState *metacache); + ArrayMetaState *metacache); extern AnyArrayType *DatumGetAnyArrayP(Datum d); extern void deconstruct_expanded_array(ExpandedArrayHeader *eah); diff --git a/src/include/utils/arrayaccess.h b/src/include/utils/arrayaccess.h index f04752213e9..47e74260d8c 100644 --- a/src/include/utils/arrayaccess.h +++ b/src/include/utils/arrayaccess.h @@ -4,7 +4,7 @@ * Declarations for element-by-element access to Postgres arrays. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/arrayaccess.h @@ -71,8 +71,8 @@ array_iter_setup(array_iter *it, AnyArrayType *a) { it->datumptr = NULL; it->isnullptr = NULL; - it->dataptr = ARR_DATA_PTR(&a->flt); - it->bitmapptr = ARR_NULLBITMAP(&a->flt); + it->dataptr = ARR_DATA_PTR((ArrayType *) a); + it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a); } it->bitmask = 1; } diff --git a/src/include/utils/ascii.h b/src/include/utils/ascii.h index 9ecf164047a..72542494df7 100644 --- a/src/include/utils/ascii.h +++ b/src/include/utils/ascii.h @@ -1,7 +1,7 @@ /*----------------------------------------------------------------------- * ascii.h * - * Portions Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2019, PostgreSQL Global Development Group * * src/include/utils/ascii.h * diff --git a/src/include/utils/attoptcache.h b/src/include/utils/attoptcache.h index f36ce279ac4..3dfb0fe578b 100644 --- a/src/include/utils/attoptcache.h +++ b/src/include/utils/attoptcache.h @@ -3,7 +3,7 @@ * attoptcache.h * Attribute options cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/attoptcache.h diff --git a/src/include/utils/backend_random.h b/src/include/utils/backend_random.h deleted file mode 100644 index 99ea2cb9fb5..00000000000 --- a/src/include/utils/backend_random.h +++ /dev/null @@ -1,19 +0,0 @@ -/*------------------------------------------------------------------------- - * - * backend_random.h - * Declarations for backend random number generation - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * - * src/include/utils/backend_random.h - * - *------------------------------------------------------------------------- - */ -#ifndef BACKEND_RANDOM_H -#define BACKEND_RANDOM_H - -extern Size BackendRandomShmemSize(void); -extern void BackendRandomShmemInit(void); -extern bool pg_backend_random(char *dst, int len); - -#endif /* BACKEND_RANDOM_H */ diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index d0416e90fcc..937ddb7ef08 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -4,7 +4,7 @@ * Declarations for operations on built-in types. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/builtins.h @@ -25,7 +25,7 @@ extern bool parse_bool_with_len(const char *value, size_t len, bool *result); /* domains.c */ extern void domain_check(Datum value, bool isnull, Oid domainType, - void **extra, MemoryContext mcxt); + void **extra, MemoryContext mcxt); extern int errdatatype(Oid datatypeOid); extern int errdomainconstraint(Oid datatypeOid, const char *conname); @@ -37,12 +37,14 @@ extern unsigned hex_decode(const char *src, unsigned len, char *dst); extern int2vector *buildint2vector(const int16 *int2s, int n); /* name.c */ -extern int namecpy(Name n1, Name n2); +extern int namecpy(Name n1, const NameData *n2); extern int namestrcpy(Name name, const char *str); extern int namestrcmp(Name name, const char *str); /* numutils.c */ extern int32 pg_atoi(const char *s, int size, int c); +extern int16 pg_strtoint16(const char *s); +extern int32 pg_strtoint32(const char *s); extern void pg_itoa(int16 i, char *a); extern void pg_ltoa(int32 l, char *a); extern void pg_lltoa(int64 ll, char *a); @@ -50,20 +52,6 @@ extern char *pg_ltostr_zeropad(char *str, int32 value, int32 minwidth); extern char *pg_ltostr(char *str, int32 value); extern uint64 pg_strtouint64(const char *str, char **endptr, int base); -/* float.c */ -extern PGDLLIMPORT int extra_float_digits; - -extern double get_float8_infinity(void); -extern float get_float4_infinity(void); -extern double get_float8_nan(void); -extern float get_float4_nan(void); -extern int is_infinite(double val); -extern double float8in_internal(char *num, char **endptr_p, - const char *type_name, const char *orig_string); -extern char *float8out_internal(double num); -extern int float4_cmp_internal(float4 a, float4 b); -extern int float8_cmp_internal(float8 a, float8 b); - /* oid.c */ extern oidvector *buildoidvector(const Oid *oids, int n); extern Oid oidparse(Node *node); @@ -71,17 +59,17 @@ extern int oid_cmp(const void *p1, const void *p2); /* regexp.c */ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive, - Oid collation, bool *exact); + Oid collation, bool *exact); /* ruleutils.c */ extern bool quote_all_identifiers; extern const char *quote_identifier(const char *ident); extern char *quote_qualified_identifier(const char *qualifier, - const char *ident); + const char *ident); extern void generate_operator_clause(fmStringInfo buf, - const char *leftop, Oid leftoptype, - Oid opoid, - const char *rightop, Oid rightoptype); + const char *leftop, Oid leftoptype, + Oid opoid, + const char *rightop, Oid rightoptype); /* varchar.c */ extern int bpchartruelen(char *s, int len); @@ -99,12 +87,12 @@ extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len); extern int xidComparator(const void *arg1, const void *arg2); /* inet_cidr_ntop.c */ -extern char *inet_cidr_ntop(int af, const void *src, int bits, - char *dst, size_t size); +extern char *pg_inet_cidr_ntop(int af, const void *src, int bits, + char *dst, size_t size); /* inet_net_pton.c */ -extern int inet_net_pton(int af, const char *src, - void *dst, size_t size); +extern int pg_inet_net_pton(int af, const char *src, + void *dst, size_t size); /* network.c */ extern double convert_network_to_scalar(Datum value, Oid typid, bool *failure); diff --git a/src/include/utils/bytea.h b/src/include/utils/bytea.h index a959dde7914..72224ca95f3 100644 --- a/src/include/utils/bytea.h +++ b/src/include/utils/bytea.h @@ -4,7 +4,7 @@ * Declarations for BYTEA data type support. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/bytea.h @@ -14,7 +14,6 @@ #ifndef BYTEA_H #define BYTEA_H -#include "fmgr.h" typedef enum diff --git a/src/include/utils/catcache.h b/src/include/utils/catcache.h index 7b22f9c7bc5..ff1fabaca14 100644 --- a/src/include/utils/catcache.h +++ b/src/include/utils/catcache.h @@ -10,7 +10,7 @@ * guarantee that there can only be one matching row for a key combination. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/catcache.h @@ -192,38 +192,38 @@ extern PGDLLIMPORT MemoryContext CacheMemoryContext; extern void CreateCacheMemoryContext(void); extern CatCache *InitCatCache(int id, Oid reloid, Oid indexoid, - int nkeys, const int *key, - int nbuckets); + int nkeys, const int *key, + int nbuckets); extern void InitCatCachePhase2(CatCache *cache, bool touch_index); extern HeapTuple SearchCatCache(CatCache *cache, - Datum v1, Datum v2, Datum v3, Datum v4); + Datum v1, Datum v2, Datum v3, Datum v4); extern HeapTuple SearchCatCache1(CatCache *cache, - Datum v1); + Datum v1); extern HeapTuple SearchCatCache2(CatCache *cache, - Datum v1, Datum v2); + Datum v1, Datum v2); extern HeapTuple SearchCatCache3(CatCache *cache, - Datum v1, Datum v2, Datum v3); + Datum v1, Datum v2, Datum v3); extern HeapTuple SearchCatCache4(CatCache *cache, - Datum v1, Datum v2, Datum v3, Datum v4); + Datum v1, Datum v2, Datum v3, Datum v4); extern void ReleaseCatCache(HeapTuple tuple); extern uint32 GetCatCacheHashValue(CatCache *cache, - Datum v1, Datum v2, - Datum v3, Datum v4); + Datum v1, Datum v2, + Datum v3, Datum v4); extern CatCList *SearchCatCacheList(CatCache *cache, int nkeys, - Datum v1, Datum v2, - Datum v3); + Datum v1, Datum v2, + Datum v3); extern void ReleaseCatCacheList(CatCList *list); extern void ResetCatalogCaches(void); extern void CatalogCacheFlushCatalog(Oid catId); extern void CatCacheInvalidate(CatCache *cache, uint32 hashValue); extern void PrepareToInvalidateCacheTuple(Relation relation, - HeapTuple tuple, - HeapTuple newtuple, - void (*function) (int, uint32, Oid)); + HeapTuple tuple, + HeapTuple newtuple, + void (*function) (int, uint32, Oid)); extern void PrintCatCacheLeakWarning(HeapTuple tuple); extern void PrintCatCacheListLeakWarning(CatCList *list); diff --git a/src/include/utils/combocid.h b/src/include/utils/combocid.h index 094a9cf98b4..69bff2a6a04 100644 --- a/src/include/utils/combocid.h +++ b/src/include/utils/combocid.h @@ -4,7 +4,7 @@ * Combo command ID support routines * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/combocid.h diff --git a/src/include/utils/date.h b/src/include/utils/date.h index eb6d2a16fec..c29f13aaf04 100644 --- a/src/include/utils/date.h +++ b/src/include/utils/date.h @@ -4,7 +4,7 @@ * Definitions for the SQL "date" and "time" types. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/date.h @@ -70,11 +70,16 @@ typedef struct /* date.c */ extern int32 anytime_typmod_check(bool istz, int32 typmod); extern double date2timestamp_no_overflow(DateADT dateVal); +extern Timestamp date2timestamp_opt_error(DateADT dateVal, bool *have_error); +extern TimestampTz date2timestamptz_opt_error(DateADT dateVal, bool *have_error); extern void EncodeSpecialDate(DateADT dt, char *str); extern DateADT GetSQLCurrentDate(void); extern TimeTzADT *GetSQLCurrentTime(int32 typmod); extern TimeADT GetSQLLocalTime(int32 typmod); extern int time2tm(TimeADT time, struct pg_tm *tm, fsec_t *fsec); extern int timetz2tm(TimeTzADT *time, struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int tm2time(struct pg_tm *tm, fsec_t fsec, TimeADT *result); +extern int tm2timetz(struct pg_tm *tm, fsec_t fsec, int tz, TimeTzADT *result); +extern void AdjustTimeForTypmod(TimeADT *time, int32 typmod); #endif /* DATE_H */ diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index d66582b7a2b..5ebf336071b 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -3,10 +3,10 @@ * datetime.h * Definitions for date/time support code. * The support code is shared with other date data types, - * including abstime, reltime, date, and time. + * including date, and time. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/datetime.h @@ -148,8 +148,6 @@ struct tzEntry; #define DTK_AGO 5 #define DTK_SPECIAL 6 -#define DTK_INVALID 7 -#define DTK_CURRENT 8 #define DTK_EARLY 9 #define DTK_LATE 10 #define DTK_EPOCH 11 @@ -291,28 +289,28 @@ extern void GetCurrentTimeUsec(struct pg_tm *tm, fsec_t *fsec, int *tzp); extern void j2date(int jd, int *year, int *month, int *day); extern int date2j(int year, int month, int day); -extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, - char **field, int *ftype, - int maxfields, int *numfields); -extern int DecodeDateTime(char **field, int *ftype, - int nf, int *dtype, - struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int ParseDateTime(const char *timestr, char *workbuf, size_t buflen, + char **field, int *ftype, + int maxfields, int *numfields); +extern int DecodeDateTime(char **field, int *ftype, + int nf, int *dtype, + struct pg_tm *tm, fsec_t *fsec, int *tzp); extern int DecodeTimezone(char *str, int *tzp); -extern int DecodeTimeOnly(char **field, int *ftype, - int nf, int *dtype, - struct pg_tm *tm, fsec_t *fsec, int *tzp); -extern int DecodeInterval(char **field, int *ftype, int nf, int range, - int *dtype, struct pg_tm *tm, fsec_t *fsec); -extern int DecodeISO8601Interval(char *str, - int *dtype, struct pg_tm *tm, fsec_t *fsec); +extern int DecodeTimeOnly(char **field, int *ftype, + int nf, int *dtype, + struct pg_tm *tm, fsec_t *fsec, int *tzp); +extern int DecodeInterval(char **field, int *ftype, int nf, int range, + int *dtype, struct pg_tm *tm, fsec_t *fsec); +extern int DecodeISO8601Interval(char *str, + int *dtype, struct pg_tm *tm, fsec_t *fsec); extern void DateTimeParseError(int dterr, const char *str, - const char *datatype) pg_attribute_noreturn(); + const char *datatype) pg_attribute_noreturn(); extern int DetermineTimeZoneOffset(struct pg_tm *tm, pg_tz *tzp); extern int DetermineTimeZoneAbbrevOffset(struct pg_tm *tm, const char *abbr, pg_tz *tzp); -extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, - pg_tz *tzp, int *isdst); +extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, + pg_tz *tzp, int *isdst); extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str); extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str); @@ -320,22 +318,26 @@ extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, extern void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str); extern void EncodeSpecialTimestamp(Timestamp dt, char *str); -extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, - struct pg_tm *tm); +extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, + struct pg_tm *tm); -extern int DecodeTimezoneAbbrev(int field, char *lowtoken, - int *offset, pg_tz **tz); +extern int DecodeTimezoneAbbrev(int field, char *lowtoken, + int *offset, pg_tz **tz); extern int DecodeSpecial(int field, char *lowtoken, int *val); extern int DecodeUnits(int field, char *lowtoken, int *val); extern int j2day(int jd); -extern Node *TemporalTransform(int32 max_precis, Node *node); +extern Node *TemporalSimplify(int32 max_precis, Node *node); extern bool CheckDateTokenTables(void); extern TimeZoneAbbrevTable *ConvertTimeZoneAbbrevs(struct tzEntry *abbrevs, - int n); + int n); extern void InstallTimeZoneAbbrevs(TimeZoneAbbrevTable *tbl); +extern void AdjustTimestampForTypmod(Timestamp *time, int32 typmod); +extern bool AdjustTimestampForTypmodError(Timestamp *time, int32 typmod, + bool *error); + #endif /* DATETIME_H */ diff --git a/src/include/utils/datum.h b/src/include/utils/datum.h index 90ab5381aa2..4b068f81036 100644 --- a/src/include/utils/datum.h +++ b/src/include/utils/datum.h @@ -8,7 +8,7 @@ * of the Datum. (We do it this way because in most situations the caller * can look up the info just once and use it for many per-datum operations.) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/datum.h @@ -44,16 +44,25 @@ extern Datum datumTransfer(Datum value, bool typByVal, int typLen); * XXX : See comments in the code for restrictions! */ extern bool datumIsEqual(Datum value1, Datum value2, - bool typByVal, int typLen); + bool typByVal, int typLen); + +/* + * datum_image_eq + * + * Compares two datums for identical contents, based on byte images. Return + * true if the two datums are equal, false otherwise. + */ +extern bool datum_image_eq(Datum value1, Datum value2, + bool typByVal, int typLen); /* * Serialize and restore datums so that we can transfer them to parallel * workers. */ extern Size datumEstimateSpace(Datum value, bool isnull, bool typByVal, - int typLen); + int typLen); extern void datumSerialize(Datum value, bool isnull, bool typByVal, - int typLen, char **start_address); + int typLen, char **start_address); extern Datum datumRestore(char **start_address, bool *isnull); #endif /* DATUM_H */ diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h index 5be6aab2926..991b62d28c4 100644 --- a/src/include/utils/dsa.h +++ b/src/include/utils/dsa.h @@ -3,7 +3,7 @@ * dsa.h * Dynamic shared memory areas. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -22,7 +22,7 @@ struct dsa_area; typedef struct dsa_area dsa_area; /* - * If this system only uses a 32-bit value for Size, then use the 32-bit + * If this system only uses a 32-bit value for size_t, then use the 32-bit * implementation of DSA. This limits the amount of DSA that can be created * to something significantly less than the entire 4GB address space because * the DSA pointer must encode both a segment identifier and an offset, but @@ -99,11 +99,9 @@ typedef pg_atomic_uint64 dsa_pointer_atomic; */ typedef dsm_handle dsa_handle; -extern void dsa_startup(void); - extern dsa_area *dsa_create(int tranche_id); -extern dsa_area *dsa_create_in_place(void *place, Size size, - int tranche_id, dsm_segment *segment); +extern dsa_area *dsa_create_in_place(void *place, size_t size, + int tranche_id, dsm_segment *segment); extern dsa_area *dsa_attach(dsa_handle handle); extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment); extern void dsa_release_in_place(void *place); @@ -113,10 +111,10 @@ extern void dsa_pin_mapping(dsa_area *area); extern void dsa_detach(dsa_area *area); extern void dsa_pin(dsa_area *area); extern void dsa_unpin(dsa_area *area); -extern void dsa_set_size_limit(dsa_area *area, Size limit); -extern Size dsa_minimum_size(void); +extern void dsa_set_size_limit(dsa_area *area, size_t limit); +extern size_t dsa_minimum_size(void); extern dsa_handle dsa_get_handle(dsa_area *area); -extern dsa_pointer dsa_allocate_extended(dsa_area *area, Size size, int flags); +extern dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags); extern void dsa_free(dsa_area *area, dsa_pointer dp); extern void *dsa_get_address(dsa_area *area, dsa_pointer dp); extern void dsa_trim(dsa_area *area); diff --git a/src/include/utils/dynahash.h b/src/include/utils/dynahash.h index 4365e1b439b..3d0e1f0c821 100644 --- a/src/include/utils/dynahash.h +++ b/src/include/utils/dynahash.h @@ -4,7 +4,7 @@ * POSTGRES dynahash.h file definitions * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/dynahash.h diff --git a/src/include/utils/dynamic_loader.h b/src/include/utils/dynamic_loader.h deleted file mode 100644 index e2455b52ca7..00000000000 --- a/src/include/utils/dynamic_loader.h +++ /dev/null @@ -1,25 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dynamic_loader.h - * - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/dynamic_loader.h - * - *------------------------------------------------------------------------- - */ -#ifndef DYNAMIC_LOADER_H -#define DYNAMIC_LOADER_H - -#include "fmgr.h" - - -extern void *pg_dlopen(const char *filename); -extern PGFunction pg_dlsym(void *handle, const char *funcname); -extern void pg_dlclose(void *handle); -extern char *pg_dlerror(void); - -#endif /* DYNAMIC_LOADER_H */ diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 7a9ba7f2fff..ba0b7f6f79c 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -4,7 +4,7 @@ * POSTGRES error reporting/logging definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/elog.h @@ -63,13 +63,30 @@ (PGSIXBIT(ch1) + (PGSIXBIT(ch2) << 6) + (PGSIXBIT(ch3) << 12) + \ (PGSIXBIT(ch4) << 18) + (PGSIXBIT(ch5) << 24)) -/* These macros depend on the fact that '0' becomes a zero in SIXBIT */ +/* These macros depend on the fact that '0' becomes a zero in PGSIXBIT */ #define ERRCODE_TO_CATEGORY(ec) ((ec) & ((1 << 12) - 1)) #define ERRCODE_IS_CATEGORY(ec) (((ec) & ~((1 << 12) - 1)) == 0) /* SQLSTATE codes for errors are defined in a separate file */ #include "utils/errcodes.h" +/* + * Provide a way to prevent "errno" from being accidentally used inside an + * elog() or ereport() invocation. Since we know that some operating systems + * define errno as something involving a function call, we'll put a local + * variable of the same name as that function in the local scope to force a + * compile error. On platforms that don't define errno in that way, nothing + * happens, so we get no warning ... but we can live with that as long as it + * happens on some popular platforms. + */ +#if defined(errno) && defined(__linux__) +#define pg_prevent_errno_in_scope() int __errno_location pg_attribute_unused() +#elif defined(errno) && (defined(__darwin__) || defined(__freebsd__)) +#define pg_prevent_errno_in_scope() int __error pg_attribute_unused() +#else +#define pg_prevent_errno_in_scope() +#endif + /*---------- * New-style error reporting API: to be used in this way: @@ -103,6 +120,7 @@ #ifdef HAVE__BUILTIN_CONSTANT_P #define ereport_domain(elevel, domain, rest) \ do { \ + pg_prevent_errno_in_scope(); \ if (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ errfinish rest; \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ @@ -112,6 +130,7 @@ #define ereport_domain(elevel, domain, rest) \ do { \ const int elevel_ = (elevel); \ + pg_prevent_errno_in_scope(); \ if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \ errfinish rest; \ if (elevel_ >= ERROR) \ @@ -125,7 +144,7 @@ #define TEXTDOMAIN NULL extern bool errstart(int elevel, const char *filename, int lineno, - const char *funcname, const char *domain); + const char *funcname, const char *domain); extern void errfinish(int dummy,...); extern int errcode(int sqlerrcode); @@ -136,20 +155,20 @@ extern int errcode_for_socket_access(void); extern int errmsg(const char *fmt,...) pg_attribute_printf(1, 2); extern int errmsg_internal(const char *fmt,...) pg_attribute_printf(1, 2); -extern int errmsg_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); +extern int errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); extern int errdetail(const char *fmt,...) pg_attribute_printf(1, 2); extern int errdetail_internal(const char *fmt,...) pg_attribute_printf(1, 2); extern int errdetail_log(const char *fmt,...) pg_attribute_printf(1, 2); -extern int errdetail_log_plural(const char *fmt_singular, - const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); +extern int errdetail_log_plural(const char *fmt_singular, + const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); -extern int errdetail_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); +extern int errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); extern int errhint(const char *fmt,...) pg_attribute_printf(1, 2); @@ -188,9 +207,8 @@ extern int getinternalerrposition(void); * elog(ERROR, "portal \"%s\" not found", stmt->portalname); *---------- */ -#ifdef HAVE__VA_ARGS /* - * If we have variadic macros, we can give the compiler a hint about the + * Using variadic macros, we can give the compiler a hint about the * call not returning when elevel >= ERROR. See comments for ereport(). * Note that historically elog() has called elog_start (which saves errno) * before evaluating "elevel", so we preserve that behavior here. @@ -198,6 +216,7 @@ extern int getinternalerrposition(void); #ifdef HAVE__BUILTIN_CONSTANT_P #define elog(elevel, ...) \ do { \ + pg_prevent_errno_in_scope(); \ elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ elog_finish(elevel, __VA_ARGS__); \ if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ @@ -206,6 +225,7 @@ extern int getinternalerrposition(void); #else /* !HAVE__BUILTIN_CONSTANT_P */ #define elog(elevel, ...) \ do { \ + pg_prevent_errno_in_scope(); \ elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO); \ { \ const int elevel_ = (elevel); \ @@ -215,11 +235,6 @@ extern int getinternalerrposition(void); } \ } while(0) #endif /* HAVE__BUILTIN_CONSTANT_P */ -#else /* !HAVE__VA_ARGS */ -#define elog \ - elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), \ - elog_finish -#endif /* HAVE__VA_ARGS */ extern void elog_start(const char *filename, int lineno, const char *funcname); extern void elog_finish(int elevel, const char *fmt,...) pg_attribute_printf(2, 3); @@ -257,8 +272,10 @@ extern PGDLLIMPORT ErrorContextCallback *error_context_stack; * PG_END_TRY(); * * (The braces are not actually necessary, but are recommended so that - * pgindent will indent the construct nicely.) The error recovery code - * can optionally do PG_RE_THROW() to propagate the same error outwards. + * pgindent will indent the construct nicely.) The error recovery code + * can either do PG_RE_THROW to propagate the error outwards, or do a + * (sub)transaction abort. Failure to do so may leave the system in an + * inconsistent state for further processing. * * Note: while the system will correctly propagate any new ereport(ERROR) * occurring in the recovery section, there is a small limit on the number diff --git a/src/include/utils/evtcache.h b/src/include/utils/evtcache.h index 727b6ba5887..f606c99267b 100644 --- a/src/include/utils/evtcache.h +++ b/src/include/utils/evtcache.h @@ -1,13 +1,13 @@ /*------------------------------------------------------------------------- * - * evtcache.c + * evtcache.h * Special-purpose cache for event trigger data. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * src/backend/utils/cache/evtcache.c + * src/include/utils/evtcache.h * *------------------------------------------------------------------------- */ diff --git a/src/include/utils/expandeddatum.h b/src/include/utils/expandeddatum.h index 3361bb25ade..bc6e1df0254 100644 --- a/src/include/utils/expandeddatum.h +++ b/src/include/utils/expandeddatum.h @@ -34,7 +34,7 @@ * value if they fail partway through. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/expandeddatum.h @@ -126,7 +126,7 @@ struct ExpandedObjectHeader */ #define EOH_HEADER_MAGIC (-1) #define VARATT_IS_EXPANDED_HEADER(PTR) \ - (((ExpandedObjectHeader *) (PTR))->vl_len_ == EOH_HEADER_MAGIC) + (((varattrib_4b *) (PTR))->va_4byte.va_header == (uint32) EOH_HEADER_MAGIC) /* * Generic support functions for expanded objects. @@ -147,11 +147,11 @@ struct ExpandedObjectHeader extern ExpandedObjectHeader *DatumGetEOHP(Datum d); extern void EOH_init_header(ExpandedObjectHeader *eohptr, - const ExpandedObjectMethods *methods, - MemoryContext obj_context); + const ExpandedObjectMethods *methods, + MemoryContext obj_context); extern Size EOH_get_flat_size(ExpandedObjectHeader *eohptr); extern void EOH_flatten_into(ExpandedObjectHeader *eohptr, - void *result, Size allocated_size); + void *result, Size allocated_size); extern Datum MakeExpandedObjectReadOnlyInternal(Datum d); extern Datum TransferExpandedObject(Datum d, MemoryContext new_parent); extern void DeleteExpandedObject(Datum d); diff --git a/src/include/utils/expandedrecord.h b/src/include/utils/expandedrecord.h index a95c9cce22e..84e6aae23fe 100644 --- a/src/include/utils/expandedrecord.h +++ b/src/include/utils/expandedrecord.h @@ -3,7 +3,7 @@ * expandedrecord.h * Declarations for composite expanded objects. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/expandedrecord.h @@ -127,8 +127,10 @@ typedef struct ExpandedRecordHeader char *fstartptr; /* start of its data area */ char *fendptr; /* end+1 of its data area */ + /* Some operations on the expanded record need a short-lived context */ + MemoryContext er_short_term_cxt; /* short-term memory context */ + /* Working state for domain checking, used if ER_FLAG_IS_DOMAIN is set */ - MemoryContext er_domain_check_cxt; /* short-term memory context */ struct ExpandedRecordHeader *er_dummy_header; /* dummy record header */ void *er_domaininfo; /* cache space for domain_check() */ @@ -165,34 +167,36 @@ typedef struct ExpandedRecordFieldInfo * prototypes for functions defined in expandedrecord.c */ extern ExpandedRecordHeader *make_expanded_record_from_typeid(Oid type_id, int32 typmod, - MemoryContext parentcontext); + MemoryContext parentcontext); extern ExpandedRecordHeader *make_expanded_record_from_tupdesc(TupleDesc tupdesc, - MemoryContext parentcontext); + MemoryContext parentcontext); extern ExpandedRecordHeader *make_expanded_record_from_exprecord(ExpandedRecordHeader *olderh, - MemoryContext parentcontext); + MemoryContext parentcontext); extern void expanded_record_set_tuple(ExpandedRecordHeader *erh, - HeapTuple tuple, bool copy); + HeapTuple tuple, bool copy, bool expand_external); extern Datum make_expanded_record_from_datum(Datum recorddatum, - MemoryContext parentcontext); + MemoryContext parentcontext); extern TupleDesc expanded_record_fetch_tupdesc(ExpandedRecordHeader *erh); extern HeapTuple expanded_record_get_tuple(ExpandedRecordHeader *erh); extern ExpandedRecordHeader *DatumGetExpandedRecord(Datum d); extern void deconstruct_expanded_record(ExpandedRecordHeader *erh); extern bool expanded_record_lookup_field(ExpandedRecordHeader *erh, - const char *fieldname, - ExpandedRecordFieldInfo *finfo); + const char *fieldname, + ExpandedRecordFieldInfo *finfo); extern Datum expanded_record_fetch_field(ExpandedRecordHeader *erh, int fnumber, - bool *isnull); + bool *isnull); extern void expanded_record_set_field_internal(ExpandedRecordHeader *erh, - int fnumber, - Datum newValue, bool isnull, - bool check_constraints); + int fnumber, + Datum newValue, bool isnull, + bool expand_external, + bool check_constraints); extern void expanded_record_set_fields(ExpandedRecordHeader *erh, - const Datum *newValues, const bool *isnulls); + const Datum *newValues, const bool *isnulls, + bool expand_external); /* outside code should never call expanded_record_set_field_internal as such */ -#define expanded_record_set_field(erh, fnumber, newValue, isnull) \ - expanded_record_set_field_internal(erh, fnumber, newValue, isnull, true) +#define expanded_record_set_field(erh, fnumber, newValue, isnull, expand_external) \ + expanded_record_set_field_internal(erh, fnumber, newValue, isnull, expand_external, true) /* * Inline-able fast cases. The expanded_record_fetch_xxx functions above diff --git a/src/include/utils/float.h b/src/include/utils/float.h new file mode 100644 index 00000000000..543d00e5910 --- /dev/null +++ b/src/include/utils/float.h @@ -0,0 +1,379 @@ +/*------------------------------------------------------------------------- + * + * float.h + * Definitions for the built-in floating-point types + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/include/utils/float.h + * + *------------------------------------------------------------------------- + */ +#ifndef FLOAT_H +#define FLOAT_H + +#include + +#ifndef M_PI +/* From my RH5.2 gcc math.h file - thomas 2000-04-03 */ +#define M_PI 3.14159265358979323846 +#endif + +/* Radians per degree, a.k.a. PI / 180 */ +#define RADIANS_PER_DEGREE 0.0174532925199432957692 + +/* Visual C++ etc lacks NAN, and won't accept 0.0/0.0. */ +#if defined(WIN32) && !defined(NAN) +static const uint32 nan[2] = {0xffffffff, 0x7fffffff}; + +#define NAN (*(const float8 *) nan) +#endif + +extern PGDLLIMPORT int extra_float_digits; + +/* + * Utility functions in float.c + */ +extern int is_infinite(float8 val); +extern float8 float8in_internal(char *num, char **endptr_p, + const char *type_name, const char *orig_string); +extern float8 float8in_internal_opt_error(char *num, char **endptr_p, + const char *type_name, const char *orig_string, + bool *have_error); +extern char *float8out_internal(float8 num); +extern int float4_cmp_internal(float4 a, float4 b); +extern int float8_cmp_internal(float8 a, float8 b); + +/* + * Routines to provide reasonably platform-independent handling of + * infinity and NaN + * + * We assume that isinf() and isnan() are available and work per spec. + * (On some platforms, we have to supply our own; see src/port.) However, + * generating an Infinity or NaN in the first place is less well standardized; + * pre-C99 systems tend not to have C99's INFINITY and NaN macros. We + * centralize our workarounds for this here. + */ + +/* + * The funny placements of the two #pragmas is necessary because of a + * long lived bug in the Microsoft compilers. + * See http://support.microsoft.com/kb/120968/en-us for details + */ +#if (_MSC_VER >= 1800) +#pragma warning(disable:4756) +#endif +static inline float4 +get_float4_infinity(void) +{ +#ifdef INFINITY + /* C99 standard way */ + return (float4) INFINITY; +#else +#if (_MSC_VER >= 1800) +#pragma warning(default:4756) +#endif + + /* + * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the + * largest normal float8. We assume forcing an overflow will get us a + * true infinity. + */ + return (float4) (HUGE_VAL * HUGE_VAL); +#endif +} + +static inline float8 +get_float8_infinity(void) +{ +#ifdef INFINITY + /* C99 standard way */ + return (float8) INFINITY; +#else + + /* + * On some platforms, HUGE_VAL is an infinity, elsewhere it's just the + * largest normal float8. We assume forcing an overflow will get us a + * true infinity. + */ + return (float8) (HUGE_VAL * HUGE_VAL); +#endif +} + +static inline float4 +get_float4_nan(void) +{ +#ifdef NAN + /* C99 standard way */ + return (float4) NAN; +#else + /* Assume we can get a NAN via zero divide */ + return (float4) (0.0 / 0.0); +#endif +} + +static inline float8 +get_float8_nan(void) +{ + /* (float8) NAN doesn't work on some NetBSD/MIPS releases */ +#if defined(NAN) && !(defined(__NetBSD__) && defined(__mips__)) + /* C99 standard way */ + return (float8) NAN; +#else + /* Assume we can get a NaN via zero divide */ + return (float8) (0.0 / 0.0); +#endif +} + +/* + * Checks to see if a float4/8 val has underflowed or overflowed + */ + +static inline void +check_float4_val(const float4 val, const bool inf_is_valid, + const bool zero_is_valid) +{ + if (!inf_is_valid && unlikely(isinf(val))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); + + if (!zero_is_valid && unlikely(val == 0.0)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); +} + +static inline void +check_float8_val(const float8 val, const bool inf_is_valid, + const bool zero_is_valid) +{ + if (!inf_is_valid && unlikely(isinf(val))) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow"))); + + if (!zero_is_valid && unlikely(val == 0.0)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow"))); +} + +/* + * Routines for operations with the checks above + * + * There isn't any way to check for underflow of addition/subtraction + * because numbers near the underflow value have already been rounded to + * the point where we can't detect that the two values were originally + * different, e.g. on x86, '1e-45'::float4 == '2e-45'::float4 == + * 1.4013e-45. + */ + +static inline float4 +float4_pl(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 + val2; + check_float4_val(result, isinf(val1) || isinf(val2), true); + + return result; +} + +static inline float8 +float8_pl(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 + val2; + check_float8_val(result, isinf(val1) || isinf(val2), true); + + return result; +} + +static inline float4 +float4_mi(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 - val2; + check_float4_val(result, isinf(val1) || isinf(val2), true); + + return result; +} + +static inline float8 +float8_mi(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 - val2; + check_float8_val(result, isinf(val1) || isinf(val2), true); + + return result; +} + +static inline float4 +float4_mul(const float4 val1, const float4 val2) +{ + float4 result; + + result = val1 * val2; + check_float4_val(result, isinf(val1) || isinf(val2), + val1 == 0.0f || val2 == 0.0f); + + return result; +} + +static inline float8 +float8_mul(const float8 val1, const float8 val2) +{ + float8 result; + + result = val1 * val2; + check_float8_val(result, isinf(val1) || isinf(val2), + val1 == 0.0 || val2 == 0.0); + + return result; +} + +static inline float4 +float4_div(const float4 val1, const float4 val2) +{ + float4 result; + + if (val2 == 0.0f) + ereport(ERROR, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); + + result = val1 / val2; + check_float4_val(result, isinf(val1) || isinf(val2), val1 == 0.0f); + + return result; +} + +static inline float8 +float8_div(const float8 val1, const float8 val2) +{ + float8 result; + + if (val2 == 0.0) + ereport(ERROR, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); + + result = val1 / val2; + check_float8_val(result, isinf(val1) || isinf(val2), val1 == 0.0); + + return result; +} + +/* + * Routines for NaN-aware comparisons + * + * We consider all NaNs to be equal and larger than any non-NaN. This is + * somewhat arbitrary; the important thing is to have a consistent sort + * order. + */ + +static inline bool +float4_eq(const float4 val1, const float4 val2) +{ + return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2; +} + +static inline bool +float8_eq(const float8 val1, const float8 val2) +{ + return isnan(val1) ? isnan(val2) : !isnan(val2) && val1 == val2; +} + +static inline bool +float4_ne(const float4 val1, const float4 val2) +{ + return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2; +} + +static inline bool +float8_ne(const float8 val1, const float8 val2) +{ + return isnan(val1) ? !isnan(val2) : isnan(val2) || val1 != val2; +} + +static inline bool +float4_lt(const float4 val1, const float4 val2) +{ + return !isnan(val1) && (isnan(val2) || val1 < val2); +} + +static inline bool +float8_lt(const float8 val1, const float8 val2) +{ + return !isnan(val1) && (isnan(val2) || val1 < val2); +} + +static inline bool +float4_le(const float4 val1, const float4 val2) +{ + return isnan(val2) || (!isnan(val1) && val1 <= val2); +} + +static inline bool +float8_le(const float8 val1, const float8 val2) +{ + return isnan(val2) || (!isnan(val1) && val1 <= val2); +} + +static inline bool +float4_gt(const float4 val1, const float4 val2) +{ + return !isnan(val2) && (isnan(val1) || val1 > val2); +} + +static inline bool +float8_gt(const float8 val1, const float8 val2) +{ + return !isnan(val2) && (isnan(val1) || val1 > val2); +} + +static inline bool +float4_ge(const float4 val1, const float4 val2) +{ + return isnan(val1) || (!isnan(val2) && val1 >= val2); +} + +static inline bool +float8_ge(const float8 val1, const float8 val2) +{ + return isnan(val1) || (!isnan(val2) && val1 >= val2); +} + +static inline float4 +float4_min(const float4 val1, const float4 val2) +{ + return float4_lt(val1, val2) ? val1 : val2; +} + +static inline float8 +float8_min(const float8 val1, const float8 val2) +{ + return float8_lt(val1, val2) ? val1 : val2; +} + +static inline float4 +float4_max(const float4 val1, const float4 val2) +{ + return float4_gt(val1, val2) ? val1 : val2; +} + +static inline float8 +float8_max(const float8 val1, const float8 val2) +{ + return float8_gt(val1, val2) ? val1 : val2; +} + +#endif /* FLOAT_H */ diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h index d8317eb3eac..e981f349347 100644 --- a/src/include/utils/fmgrtab.h +++ b/src/include/utils/fmgrtab.h @@ -3,7 +3,7 @@ * fmgrtab.h * The function manager's table of internal functions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/fmgrtab.h @@ -25,10 +25,10 @@ typedef struct { Oid foid; /* OID of the function */ - const char *funcName; /* C name of the function */ short nargs; /* 0..FUNC_MAX_ARGS, or -1 if variable count */ bool strict; /* T if function is "strict" */ bool retset; /* T if function returns a set */ + const char *funcName; /* C name of the function */ PGFunction func; /* pointer to compiled function */ } FmgrBuiltin; @@ -36,11 +36,13 @@ extern const FmgrBuiltin fmgr_builtins[]; extern const int fmgr_nbuiltins; /* number of entries in table */ +extern const Oid fmgr_last_builtin_oid; /* highest function OID in table */ + /* - * Mapping from a builtin function's oid to the index in the fmgr_builtins - * array. + * Mapping from a builtin function's OID to its index in the fmgr_builtins + * array. This is indexed from 0 through fmgr_last_builtin_oid. */ #define InvalidOidBuiltinMapping PG_UINT16_MAX -extern const uint16 fmgr_builtin_oid_index[FirstBootstrapObjectId]; +extern const uint16 fmgr_builtin_oid_index[]; #endif /* FMGRTAB_H */ diff --git a/src/include/utils/formatting.h b/src/include/utils/formatting.h index a9f5548b46c..165ca78ba5c 100644 --- a/src/include/utils/formatting.h +++ b/src/include/utils/formatting.h @@ -4,10 +4,10 @@ * src/include/utils/formatting.h * * - * Portions Copyright (c) 1999-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1999-2019, PostgreSQL Global Development Group * * The PostgreSQL routines for a DateTime/int/float/numeric formatting, - * inspire with Oracle TO_CHAR() / TO_DATE() / TO_NUMBER() routines. + * inspired by the Oracle TO_CHAR() / TO_DATE() / TO_NUMBER() routines. * * Karel Zak * @@ -17,8 +17,6 @@ #ifndef _FORMATTING_H_ #define _FORMATTING_H_ -#include "fmgr.h" - extern char *str_tolower(const char *buff, size_t nbytes, Oid collid); extern char *str_toupper(const char *buff, size_t nbytes, Oid collid); @@ -28,4 +26,8 @@ extern char *asc_tolower(const char *buff, size_t nbytes); extern char *asc_toupper(const char *buff, size_t nbytes); extern char *asc_initcap(const char *buff, size_t nbytes); +extern Datum parse_datetime(text *date_txt, text *fmt, bool std, + Oid *typid, int32 *typmod, int *tz, + bool *have_error); + #endif diff --git a/src/include/utils/freepage.h b/src/include/utils/freepage.h index cbbf267fb3e..adce535e3ad 100644 --- a/src/include/utils/freepage.h +++ b/src/include/utils/freepage.h @@ -3,7 +3,7 @@ * freepage.h * Management of page-organized free memory. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/freepage.h @@ -91,9 +91,9 @@ struct FreePageManager /* Functions to manipulate the free page map. */ extern void FreePageManagerInitialize(FreePageManager *fpm, char *base); extern bool FreePageManagerGet(FreePageManager *fpm, Size npages, - Size *first_page); + Size *first_page); extern void FreePageManagerPut(FreePageManager *fpm, Size first_page, - Size npages); + Size npages); extern char *FreePageManagerDump(FreePageManager *fpm); #endif /* FREEPAGE_H */ diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index a589e4239ff..4b0353cf0f2 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -3,14 +3,11 @@ * geo_decls.h - Declarations for various 2D constructs. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/geo_decls.h * - * NOTE - * These routines do *not* use the float types from adt/. - * * XXX These routines were not written by a numerical analyst. * * XXX I have made some attempt to flesh out the operators @@ -21,14 +18,14 @@ #ifndef GEO_DECLS_H #define GEO_DECLS_H -#include - #include "fmgr.h" /*-------------------------------------------------------------------- * Useful floating point utilities and constants. - *-------------------------------------------------------------------*/ - + *------------------------------------------------------------------- + * + * XXX: They are not NaN-aware. + */ #define EPSILON 1.0E-06 @@ -57,7 +54,7 @@ *-------------------------------------------------------------------*/ typedef struct { - double x, + float8 x, y; } Point; @@ -89,7 +86,7 @@ typedef struct *-------------------------------------------------------------------*/ typedef struct { - double A, + float8 A, B, C; } LINE; @@ -124,7 +121,7 @@ typedef struct typedef struct { Point center; - double radius; + float8 radius; } CIRCLE; /* @@ -178,10 +175,6 @@ typedef struct * in geo_ops.c */ -/* private routines */ -extern double point_dt(Point *pt1, Point *pt2); -extern double point_sl(Point *pt1, Point *pt2); -extern double pg_hypot(double x, double y); -extern BOX *box_copy(BOX *box); +extern float8 pg_hypot(float8 x, float8 y); #endif /* GEO_DECLS_H */ diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 3d13a33b94e..6791e0cbc20 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -4,7 +4,7 @@ * External declarations pertaining to backend/utils/misc/guc.c and * backend/utils/misc/guc-file.l * - * Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Copyright (c) 2000-2019, PostgreSQL Global Development Group * Written by Peter Eisentraut . * * src/include/utils/guc.h @@ -143,17 +143,17 @@ typedef struct ConfigVariable } ConfigVariable; extern bool ParseConfigFile(const char *config_file, bool strict, - const char *calling_file, int calling_lineno, - int depth, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p); + const char *calling_file, int calling_lineno, + int depth, int elevel, + ConfigVariable **head_p, ConfigVariable **tail_p); extern bool ParseConfigFp(FILE *fp, const char *config_file, - int depth, int elevel, - ConfigVariable **head_p, ConfigVariable **tail_p); + int depth, int elevel, + ConfigVariable **head_p, ConfigVariable **tail_p); extern bool ParseConfigDirectory(const char *includedir, - const char *calling_file, int calling_lineno, - int depth, int elevel, - ConfigVariable **head_p, - ConfigVariable **tail_p); + const char *calling_file, int calling_lineno, + int depth, int elevel, + ConfigVariable **head_p, + ConfigVariable **tail_p); extern void FreeConfigVariables(ConfigVariable *list); /* @@ -227,6 +227,8 @@ typedef enum #define GUC_UNIT_MIN 0x30000 /* value is in minutes */ #define GUC_UNIT_TIME 0xF0000 /* mask for time-related units */ +#define GUC_EXPLAIN 0x100000 /* include in explain */ + #define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME) @@ -244,7 +246,6 @@ extern bool log_statement_stats; extern bool log_btree_build_stats; extern PGDLLIMPORT bool check_function_bodies; -extern bool default_with_oids; extern bool session_auth_is_superuser; extern int log_min_error_statement; @@ -252,6 +253,7 @@ extern PGDLLIMPORT int log_min_messages; extern PGDLLIMPORT int client_min_messages; extern int log_min_duration_statement; extern int log_temp_files; +extern double log_xact_sample_rate; extern int temp_file_limit; @@ -268,6 +270,7 @@ extern PGDLLIMPORT char *application_name; extern int tcp_keepalives_idle; extern int tcp_keepalives_interval; extern int tcp_keepalives_count; +extern int tcp_user_timeout; #ifdef TRACE_SORT extern bool trace_sort; @@ -277,77 +280,72 @@ extern bool trace_sort; * Functions exported by guc.c */ extern void SetConfigOption(const char *name, const char *value, - GucContext context, GucSource source); - -extern void DefineCustomBoolVariable( - const char *name, - const char *short_desc, - const char *long_desc, - bool *valueAddr, - bool bootValue, - GucContext context, - int flags, - GucBoolCheckHook check_hook, - GucBoolAssignHook assign_hook, - GucShowHook show_hook); - -extern void DefineCustomIntVariable( - const char *name, - const char *short_desc, - const char *long_desc, - int *valueAddr, - int bootValue, - int minValue, - int maxValue, - GucContext context, - int flags, - GucIntCheckHook check_hook, - GucIntAssignHook assign_hook, - GucShowHook show_hook); - -extern void DefineCustomRealVariable( - const char *name, - const char *short_desc, - const char *long_desc, - double *valueAddr, - double bootValue, - double minValue, - double maxValue, - GucContext context, - int flags, - GucRealCheckHook check_hook, - GucRealAssignHook assign_hook, - GucShowHook show_hook); - -extern void DefineCustomStringVariable( - const char *name, - const char *short_desc, - const char *long_desc, - char **valueAddr, - const char *bootValue, - GucContext context, - int flags, - GucStringCheckHook check_hook, - GucStringAssignHook assign_hook, - GucShowHook show_hook); - -extern void DefineCustomEnumVariable( - const char *name, - const char *short_desc, - const char *long_desc, - int *valueAddr, - int bootValue, - const struct config_enum_entry *options, - GucContext context, - int flags, - GucEnumCheckHook check_hook, - GucEnumAssignHook assign_hook, - GucShowHook show_hook); + GucContext context, GucSource source); + +extern void DefineCustomBoolVariable(const char *name, + const char *short_desc, + const char *long_desc, + bool *valueAddr, + bool bootValue, + GucContext context, + int flags, + GucBoolCheckHook check_hook, + GucBoolAssignHook assign_hook, + GucShowHook show_hook); + +extern void DefineCustomIntVariable(const char *name, + const char *short_desc, + const char *long_desc, + int *valueAddr, + int bootValue, + int minValue, + int maxValue, + GucContext context, + int flags, + GucIntCheckHook check_hook, + GucIntAssignHook assign_hook, + GucShowHook show_hook); + +extern void DefineCustomRealVariable(const char *name, + const char *short_desc, + const char *long_desc, + double *valueAddr, + double bootValue, + double minValue, + double maxValue, + GucContext context, + int flags, + GucRealCheckHook check_hook, + GucRealAssignHook assign_hook, + GucShowHook show_hook); + +extern void DefineCustomStringVariable(const char *name, + const char *short_desc, + const char *long_desc, + char **valueAddr, + const char *bootValue, + GucContext context, + int flags, + GucStringCheckHook check_hook, + GucStringAssignHook assign_hook, + GucShowHook show_hook); + +extern void DefineCustomEnumVariable(const char *name, + const char *short_desc, + const char *long_desc, + int *valueAddr, + int bootValue, + const struct config_enum_entry *options, + GucContext context, + int flags, + GucEnumCheckHook check_hook, + GucEnumAssignHook assign_hook, + GucShowHook show_hook); extern void EmitWarningsOnPlaceholders(const char *className); extern const char *GetConfigOption(const char *name, bool missing_ok, - bool restrict_superuser); + bool restrict_privileged); extern const char *GetConfigOptionResetString(const char *name); extern int GetConfigOptionFlags(const char *name, bool missing_ok); extern void ProcessConfigFile(GucContext context); @@ -360,15 +358,16 @@ extern void AtEOXact_GUC(bool isCommit, int nestLevel); extern void BeginReportingGUCOptions(void); extern void ParseLongOption(const char *string, char **name, char **value); extern bool parse_int(const char *value, int *result, int flags, - const char **hintmsg); -extern bool parse_real(const char *value, double *result); -extern int set_config_option(const char *name, const char *value, - GucContext context, GucSource source, - GucAction action, bool changeVal, int elevel, - bool is_reload); -extern void AlterSystemSetConfigFile(AlterSystemStmt *setstmt); + const char **hintmsg); +extern bool parse_real(const char *value, double *result, int flags, + const char **hintmsg); +extern int set_config_option(const char *name, const char *value, + GucContext context, GucSource source, + GucAction action, bool changeVal, int elevel, + bool is_reload); +extern void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt); extern char *GetConfigOptionByName(const char *name, const char **varname, - bool missing_ok); + bool missing_ok); extern void GetConfigOptionByNum(int varnum, const char **values, bool *noshow); extern int GetNumConfigOptions(void); @@ -380,7 +379,7 @@ extern void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel); extern char *ExtractSetVariableArgs(VariableSetStmt *stmt); extern void ProcessGUCArray(ArrayType *array, - GucContext context, GucSource source, GucAction action); + GucContext context, GucSource source, GucAction action); extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *value); extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name); extern ArrayType *GUCArrayReset(ArrayType *array); diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h index 668d9efd357..d68976fafa9 100644 --- a/src/include/utils/guc_tables.h +++ b/src/include/utils/guc_tables.h @@ -5,7 +5,7 @@ * * See src/backend/utils/misc/README for design notes. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/utils/guc_tables.h * @@ -69,6 +69,8 @@ enum config_group WAL_SETTINGS, WAL_CHECKPOINTS, WAL_ARCHIVING, + WAL_ARCHIVE_RECOVERY, + WAL_RECOVERY_TARGET, REPLICATION, REPLICATION_SENDING, REPLICATION_MASTER, @@ -264,6 +266,7 @@ extern void build_guc_variables(void); /* search in enum options */ extern const char *config_enum_lookup_by_value(struct config_enum *record, int val); extern bool config_enum_lookup_by_name(struct config_enum *record, - const char *value, int *retval); + const char *value, int *retval); +extern struct config_generic **get_explain_guc_options(int *num); #endif /* GUC_TABLES_H */ diff --git a/src/include/utils/hashutils.h b/src/include/utils/hashutils.h index 5e9fe65012f..db8b7d31917 100644 --- a/src/include/utils/hashutils.h +++ b/src/include/utils/hashutils.h @@ -1,12 +1,31 @@ /* * Utilities for working with hash values. * - * Portions Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2017-2019, PostgreSQL Global Development Group */ #ifndef HASHUTILS_H #define HASHUTILS_H + +/* + * Rotate the high 32 bits and the low 32 bits separately. The standard + * hash function sometimes rotates the low 32 bits by one bit when + * combining elements. We want extended hash functions to be compatible with + * that algorithm when the seed is 0, so we can't just do a normal rotation. + * This works, though. + */ +#define ROTATE_HIGH_AND_LOW_32BITS(v) \ + ((((v) << 1) & UINT64CONST(0xfffffffefffffffe)) | \ + (((v) >> 31) & UINT64CONST(0x100000001))) + + +extern Datum hash_any(const unsigned char *k, int keylen); +extern Datum hash_any_extended(const unsigned char *k, + int keylen, uint64 seed); +extern Datum hash_uint32(uint32 k); +extern Datum hash_uint32_extended(uint32 k, uint64 seed); + /* * Combine two 32-bit hash values, resulting in another hash value, with * decent bit mixing. diff --git a/src/include/utils/help_config.h b/src/include/utils/help_config.h index f35d4da8a87..f0eace59f50 100644 --- a/src/include/utils/help_config.h +++ b/src/include/utils/help_config.h @@ -3,7 +3,7 @@ * help_config.h * Interface to the --help-config option of main.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/utils/help_config.h * diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h index 8357faac5a8..fe5ab9c8681 100644 --- a/src/include/utils/hsearch.h +++ b/src/include/utils/hsearch.h @@ -4,7 +4,7 @@ * exported definitions for utils/hash/dynahash.c; see notes therein * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/hsearch.h @@ -120,17 +120,17 @@ typedef struct * prototypes for functions in dynahash.c */ extern HTAB *hash_create(const char *tabname, long nelem, - HASHCTL *info, int flags); + HASHCTL *info, int flags); extern void hash_destroy(HTAB *hashp); extern void hash_stats(const char *where, HTAB *hashp); extern void *hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, - bool *foundPtr); + bool *foundPtr); extern uint32 get_hash_value(HTAB *hashp, const void *keyPtr); extern void *hash_search_with_hash_value(HTAB *hashp, const void *keyPtr, - uint32 hashvalue, HASHACTION action, - bool *foundPtr); + uint32 hashvalue, HASHACTION action, + bool *foundPtr); extern bool hash_update_hash_key(HTAB *hashp, void *existingEntry, - const void *newKeyPtr); + const void *newKeyPtr); extern long hash_get_num_entries(HTAB *hashp); extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp); extern void *hash_seq_search(HASH_SEQ_STATUS *status); diff --git a/src/include/utils/index_selfuncs.h b/src/include/utils/index_selfuncs.h index ae2b96943d7..b81556d7a1e 100644 --- a/src/include/utils/index_selfuncs.h +++ b/src/include/utils/index_selfuncs.h @@ -9,7 +9,7 @@ * If you make it depend on anything besides access/amapi.h, that's likely * a mistake. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/index_selfuncs.h @@ -23,52 +23,52 @@ /* Functions in selfuncs.c */ extern void brincostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); extern void btcostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); extern void hashcostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); extern void gistcostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); extern void spgcostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); extern void gincostestimate(struct PlannerInfo *root, - struct IndexPath *path, - double loop_count, - Cost *indexStartupCost, - Cost *indexTotalCost, - Selectivity *indexSelectivity, - double *indexCorrelation, - double *indexPages); + struct IndexPath *path, + double loop_count, + Cost *indexStartupCost, + Cost *indexTotalCost, + Selectivity *indexSelectivity, + double *indexCorrelation, + double *indexPages); #endif /* INDEX_SELFUNCS_H */ diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h index e3bec398b1d..998593e956f 100644 --- a/src/include/utils/inet.h +++ b/src/include/utils/inet.h @@ -4,7 +4,7 @@ * Declarations for operations on INET datatypes. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/inet.h diff --git a/src/include/utils/int8.h b/src/include/utils/int8.h index 91171ee4cc9..4836095d931 100644 --- a/src/include/utils/int8.h +++ b/src/include/utils/int8.h @@ -4,7 +4,7 @@ * Declarations for operations on 64-bit integers. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/int8.h diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h index 7a66d466f70..940d53f9006 100644 --- a/src/include/utils/inval.h +++ b/src/include/utils/inval.h @@ -4,7 +4,7 @@ * POSTGRES cache invalidation dispatcher definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/inval.h @@ -29,15 +29,13 @@ extern void AtEOXact_Inval(bool isCommit); extern void AtEOSubXact_Inval(bool isCommit); -extern void AtPrepare_Inval(void); - extern void PostPrepare_Inval(void); extern void CommandEndInvalidationMessages(void); extern void CacheInvalidateHeapTuple(Relation relation, - HeapTuple tuple, - HeapTuple newtuple); + HeapTuple tuple, + HeapTuple newtuple); extern void CacheInvalidateCatalog(Oid catalogId); @@ -54,11 +52,11 @@ extern void CacheInvalidateSmgr(RelFileNodeBackend rnode); extern void CacheInvalidateRelmap(Oid databaseId); extern void CacheRegisterSyscacheCallback(int cacheid, - SyscacheCallbackFunction func, - Datum arg); + SyscacheCallbackFunction func, + Datum arg); extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func, - Datum arg); + Datum arg); extern void CallSyscacheCallbacks(int cacheid, uint32 hashvalue); diff --git a/src/include/utils/json.h b/src/include/utils/json.h index 549bd4d2877..a3275439afa 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -3,7 +3,7 @@ * json.h * Declarations for JSON data type support. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/json.h diff --git a/src/include/utils/jsonapi.h b/src/include/utils/jsonapi.h index b28201c2bc6..e1dab24d5dd 100644 --- a/src/include/utils/jsonapi.h +++ b/src/include/utils/jsonapi.h @@ -3,7 +3,7 @@ * jsonapi.h * Declarations for JSON API support. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/jsonapi.h @@ -94,7 +94,7 @@ typedef struct JsonSemAction } JsonSemAction; /* - * parse_json will parse the string in the lex calling the + * pg_parse_json will parse the string in the lex calling the * action functions in sem at the appropriate points. It is * up to them to keep what state they need in semstate. If they * need access to the state of the lexer, then its pointer @@ -122,8 +122,8 @@ extern int json_count_array_elements(JsonLexContext *lex); */ extern JsonLexContext *makeJsonLexContext(text *json, bool need_escapes); extern JsonLexContext *makeJsonLexContextCstringLen(char *json, - int len, - bool need_escapes); + int len, + bool need_escapes); /* * Utility function to check if a string is a valid JSON number. @@ -136,15 +136,16 @@ extern bool IsValidJsonNumber(const char *str, int len); * Flag types for iterate_json(b)_values to specify what elements from a * json(b) document we want to iterate. */ -typedef enum JsonToIndex { - jtiKey = 0x01, - jtiString = 0x02, - jtiNumeric = 0x04, - jtiBool = 0x08, - jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool +typedef enum JsonToIndex +{ + jtiKey = 0x01, + jtiString = 0x02, + jtiNumeric = 0x04, + jtiBool = 0x08, + jtiAll = jtiKey | jtiString | jtiNumeric | jtiBool } JsonToIndex; -/* an action that will be applied to each value in iterate_json(b)_vaues functions */ +/* an action that will be applied to each value in iterate_json(b)_values functions */ typedef void (*JsonIterateStringValuesAction) (void *state, char *elem_value, int elem_len); /* an action that will be applied to each value in transform_json(b)_values functions */ @@ -152,14 +153,15 @@ typedef text *(*JsonTransformStringValuesAction) (void *state, char *elem_value, extern uint32 parse_jsonb_index_flags(Jsonb *jb); extern void iterate_jsonb_values(Jsonb *jb, uint32 flags, void *state, - JsonIterateStringValuesAction action); + JsonIterateStringValuesAction action); extern void iterate_json_values(text *json, uint32 flags, void *action_state, - JsonIterateStringValuesAction action); + JsonIterateStringValuesAction action); extern Jsonb *transform_jsonb_string_values(Jsonb *jsonb, void *action_state, - JsonTransformStringValuesAction transform_action); + JsonTransformStringValuesAction transform_action); extern text *transform_json_string_values(text *json, void *action_state, - JsonTransformStringValuesAction transform_action); + JsonTransformStringValuesAction transform_action); -extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid); +extern char *JsonEncodeDateTime(char *buf, Datum value, Oid typid, + const int *tzp); #endif /* JSONAPI_H */ diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h index 27873d4d107..5e8179665e2 100644 --- a/src/include/utils/jsonb.h +++ b/src/include/utils/jsonb.h @@ -3,7 +3,7 @@ * jsonb.h * Declarations for jsonb data type support. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/include/utils/jsonb.h * @@ -34,6 +34,9 @@ typedef enum #define JsonbExistsStrategyNumber 9 #define JsonbExistsAnyStrategyNumber 10 #define JsonbExistsAllStrategyNumber 11 +#define JsonbJsonpathExistsStrategyNumber 15 +#define JsonbJsonpathPredicateStrategyNumber 16 + /* * In the standard jsonb_ops GIN opclass for jsonb, we choose to index both @@ -66,8 +69,10 @@ typedef enum /* Convenience macros */ #define DatumGetJsonbP(d) ((Jsonb *) PG_DETOAST_DATUM(d)) +#define DatumGetJsonbPCopy(d) ((Jsonb *) PG_DETOAST_DATUM_COPY(d)) #define JsonbPGetDatum(p) PointerGetDatum(p) #define PG_GETARG_JSONB_P(x) DatumGetJsonbP(PG_GETARG_DATUM(x)) +#define PG_GETARG_JSONB_P_COPY(x) DatumGetJsonbPCopy(PG_GETARG_DATUM(x)) #define PG_RETURN_JSONB_P(x) PG_RETURN_POINTER(x) typedef struct JsonbPair JsonbPair; @@ -236,7 +241,15 @@ enum jbvType jbvArray = 0x10, jbvObject, /* Binary (i.e. struct Jsonb) jbvArray/jbvObject */ - jbvBinary + jbvBinary, + + /* + * Virtual types. + * + * These types are used only for in-memory JSON processing and serialized + * into JSON strings when outputted to json/jsonb. + */ + jbvDatetime = 0x20, }; /* @@ -277,11 +290,21 @@ struct JsonbValue int len; JsonbContainer *data; } binary; /* Array or object, in on-disk format */ + + struct + { + Datum value; + Oid typid; + int32 typmod; + int tz; /* Numeric time zone, in seconds, for + * TimestampTz data type */ + } datetime; } val; }; -#define IsAJsonbScalar(jsonbval) ((jsonbval)->type >= jbvNull && \ - (jsonbval)->type <= jbvBool) +#define IsAJsonbScalar(jsonbval) (((jsonbval)->type >= jbvNull && \ + (jsonbval)->type <= jbvBool) || \ + (jsonbval)->type == jbvDatetime) /* * Key/value pair within an Object. @@ -357,27 +380,32 @@ extern uint32 getJsonbOffset(const JsonbContainer *jc, int index); extern uint32 getJsonbLength(const JsonbContainer *jc, int index); extern int compareJsonbContainers(JsonbContainer *a, JsonbContainer *b); extern JsonbValue *findJsonbValueFromContainer(JsonbContainer *sheader, - uint32 flags, - JsonbValue *key); + uint32 flags, + JsonbValue *key); +extern JsonbValue *getKeyJsonValueFromContainer(JsonbContainer *container, + const char *keyVal, int keyLen, + JsonbValue *res); extern JsonbValue *getIthJsonbValueFromContainer(JsonbContainer *sheader, - uint32 i); + uint32 i); extern JsonbValue *pushJsonbValue(JsonbParseState **pstate, - JsonbIteratorToken seq, JsonbValue *jbVal); + JsonbIteratorToken seq, JsonbValue *jbval); extern JsonbIterator *JsonbIteratorInit(JsonbContainer *container); extern JsonbIteratorToken JsonbIteratorNext(JsonbIterator **it, JsonbValue *val, - bool skipNested); + bool skipNested); extern Jsonb *JsonbValueToJsonb(JsonbValue *val); extern bool JsonbDeepContains(JsonbIterator **val, - JsonbIterator **mContained); + JsonbIterator **mContained); extern void JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash); extern void JsonbHashScalarValueExtended(const JsonbValue *scalarVal, - uint64 *hash, uint64 seed); + uint64 *hash, uint64 seed); /* jsonb.c support functions */ extern char *JsonbToCString(StringInfo out, JsonbContainer *in, - int estimated_len); + int estimated_len); extern char *JsonbToCStringIndent(StringInfo out, JsonbContainer *in, - int estimated_len); + int estimated_len); +extern bool JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res); +extern const char *JsonbTypeName(JsonbValue *jb); #endif /* __JSONB_H__ */ diff --git a/src/include/utils/jsonpath.h b/src/include/utils/jsonpath.h new file mode 100644 index 00000000000..0f2b08efe6e --- /dev/null +++ b/src/include/utils/jsonpath.h @@ -0,0 +1,251 @@ +/*------------------------------------------------------------------------- + * + * jsonpath.h + * Definitions for jsonpath datatype + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/include/utils/jsonpath.h + * + *------------------------------------------------------------------------- + */ + +#ifndef JSONPATH_H +#define JSONPATH_H + +#include "fmgr.h" +#include "utils/jsonb.h" +#include "nodes/pg_list.h" + +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + uint32 header; /* version and flags (see below) */ + char data[FLEXIBLE_ARRAY_MEMBER]; +} JsonPath; + +#define JSONPATH_VERSION (0x01) +#define JSONPATH_LAX (0x80000000) +#define JSONPATH_HDRSZ (offsetof(JsonPath, data)) + +#define DatumGetJsonPathP(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM(d))) +#define DatumGetJsonPathPCopy(d) ((JsonPath *) DatumGetPointer(PG_DETOAST_DATUM_COPY(d))) +#define PG_GETARG_JSONPATH_P(x) DatumGetJsonPathP(PG_GETARG_DATUM(x)) +#define PG_GETARG_JSONPATH_P_COPY(x) DatumGetJsonPathPCopy(PG_GETARG_DATUM(x)) +#define PG_RETURN_JSONPATH_P(p) PG_RETURN_POINTER(p) + +#define jspIsScalar(type) ((type) >= jpiNull && (type) <= jpiBool) + +/* + * All node's type of jsonpath expression + */ +typedef enum JsonPathItemType +{ + jpiNull = jbvNull, /* NULL literal */ + jpiString = jbvString, /* string literal */ + jpiNumeric = jbvNumeric, /* numeric literal */ + jpiBool = jbvBool, /* boolean literal: TRUE or FALSE */ + jpiAnd, /* predicate && predicate */ + jpiOr, /* predicate || predicate */ + jpiNot, /* ! predicate */ + jpiIsUnknown, /* (predicate) IS UNKNOWN */ + jpiEqual, /* expr == expr */ + jpiNotEqual, /* expr != expr */ + jpiLess, /* expr < expr */ + jpiGreater, /* expr > expr */ + jpiLessOrEqual, /* expr <= expr */ + jpiGreaterOrEqual, /* expr >= expr */ + jpiAdd, /* expr + expr */ + jpiSub, /* expr - expr */ + jpiMul, /* expr * expr */ + jpiDiv, /* expr / expr */ + jpiMod, /* expr % expr */ + jpiPlus, /* + expr */ + jpiMinus, /* - expr */ + jpiAnyArray, /* [*] */ + jpiAnyKey, /* .* */ + jpiIndexArray, /* [subscript, ...] */ + jpiAny, /* .** */ + jpiKey, /* .key */ + jpiCurrent, /* @ */ + jpiRoot, /* $ */ + jpiVariable, /* $variable */ + jpiFilter, /* ? (predicate) */ + jpiExists, /* EXISTS (expr) predicate */ + jpiType, /* .type() item method */ + jpiSize, /* .size() item method */ + jpiAbs, /* .abs() item method */ + jpiFloor, /* .floor() item method */ + jpiCeiling, /* .ceiling() item method */ + jpiDouble, /* .double() item method */ + jpiDatetime, /* .datetime() item method */ + jpiKeyValue, /* .keyvalue() item method */ + jpiSubscript, /* array subscript: 'expr' or 'expr TO expr' */ + jpiLast, /* LAST array subscript */ + jpiStartsWith, /* STARTS WITH predicate */ + jpiLikeRegex, /* LIKE_REGEX predicate */ +} JsonPathItemType; + +/* XQuery regex mode flags for LIKE_REGEX predicate */ +#define JSP_REGEX_ICASE 0x01 /* i flag, case insensitive */ +#define JSP_REGEX_DOTALL 0x02 /* s flag, dot matches newline */ +#define JSP_REGEX_MLINE 0x04 /* m flag, ^/$ match at newlines */ +#define JSP_REGEX_WSPACE 0x08 /* x flag, ignore whitespace in pattern */ +#define JSP_REGEX_QUOTE 0x10 /* q flag, no special characters */ + +/* + * Support functions to parse/construct binary value. + * Unlike many other representation of expression the first/main + * node is not an operation but left operand of expression. That + * allows to implement cheap follow-path descending in jsonb + * structure and then execute operator with right operand + */ + +typedef struct JsonPathItem +{ + JsonPathItemType type; + + /* position form base to next node */ + int32 nextPos; + + /* + * pointer into JsonPath value to current node, all positions of current + * are relative to this base + */ + char *base; + + union + { + /* classic operator with two operands: and, or etc */ + struct + { + int32 left; + int32 right; + } args; + + /* any unary operation */ + int32 arg; + + /* storage for jpiIndexArray: indexes of array */ + struct + { + int32 nelems; + struct + { + int32 from; + int32 to; + } *elems; + } array; + + /* jpiAny: levels */ + struct + { + uint32 first; + uint32 last; + } anybounds; + + struct + { + char *data; /* for bool, numeric and string/key */ + int32 datalen; /* filled only for string/key */ + } value; + + struct + { + int32 expr; + char *pattern; + int32 patternlen; + uint32 flags; + } like_regex; + } content; +} JsonPathItem; + +#define jspHasNext(jsp) ((jsp)->nextPos > 0) + +extern void jspInit(JsonPathItem *v, JsonPath *js); +extern void jspInitByBuffer(JsonPathItem *v, char *base, int32 pos); +extern bool jspGetNext(JsonPathItem *v, JsonPathItem *a); +extern void jspGetArg(JsonPathItem *v, JsonPathItem *a); +extern void jspGetLeftArg(JsonPathItem *v, JsonPathItem *a); +extern void jspGetRightArg(JsonPathItem *v, JsonPathItem *a); +extern Numeric jspGetNumeric(JsonPathItem *v); +extern bool jspGetBool(JsonPathItem *v); +extern char *jspGetString(JsonPathItem *v, int32 *len); +extern bool jspGetArraySubscript(JsonPathItem *v, JsonPathItem *from, + JsonPathItem *to, int i); + +extern const char *jspOperationName(JsonPathItemType type); + +/* + * Parsing support data structures. + */ + +typedef struct JsonPathParseItem JsonPathParseItem; + +struct JsonPathParseItem +{ + JsonPathItemType type; + JsonPathParseItem *next; /* next in path */ + + union + { + + /* classic operator with two operands: and, or etc */ + struct + { + JsonPathParseItem *left; + JsonPathParseItem *right; + } args; + + /* any unary operation */ + JsonPathParseItem *arg; + + /* storage for jpiIndexArray: indexes of array */ + struct + { + int nelems; + struct + { + JsonPathParseItem *from; + JsonPathParseItem *to; + } *elems; + } array; + + /* jpiAny: levels */ + struct + { + uint32 first; + uint32 last; + } anybounds; + + struct + { + JsonPathParseItem *expr; + char *pattern; /* could not be not null-terminated */ + uint32 patternlen; + uint32 flags; + } like_regex; + + /* scalars */ + Numeric numeric; + bool boolean; + struct + { + uint32 len; + char *val; /* could not be not null-terminated */ + } string; + } value; +}; + +typedef struct JsonPathParseResult +{ + JsonPathParseItem *expr; + bool lax; +} JsonPathParseResult; + +extern JsonPathParseResult *parsejsonpath(const char *str, int len); + +extern int jspConvertRegexFlags(uint32 xflags); + +#endif diff --git a/src/include/utils/logtape.h b/src/include/utils/logtape.h index 9bf1d801424..081b03880a0 100644 --- a/src/include/utils/logtape.h +++ b/src/include/utils/logtape.h @@ -5,7 +5,7 @@ * * See logtape.c for explanations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/logtape.h @@ -44,13 +44,10 @@ typedef struct LogicalTapeSet LogicalTapeSet; typedef struct TapeShare { /* - * firstblocknumber is first block that should be read from materialized - * tape. - * - * buffilesize is the size of associated BufFile following freezing. + * Currently, all the leader process needs is the location of the + * materialized tape's first block. */ long firstblocknumber; - off_t buffilesize; } TapeShare; /* @@ -58,24 +55,24 @@ typedef struct TapeShare */ extern LogicalTapeSet *LogicalTapeSetCreate(int ntapes, TapeShare *shared, - SharedFileSet *fileset, int worker); + SharedFileSet *fileset, int worker); extern void LogicalTapeSetClose(LogicalTapeSet *lts); extern void LogicalTapeSetForgetFreeSpace(LogicalTapeSet *lts); extern size_t LogicalTapeRead(LogicalTapeSet *lts, int tapenum, - void *ptr, size_t size); + void *ptr, size_t size); extern void LogicalTapeWrite(LogicalTapeSet *lts, int tapenum, - void *ptr, size_t size); + void *ptr, size_t size); extern void LogicalTapeRewindForRead(LogicalTapeSet *lts, int tapenum, - size_t buffer_size); + size_t buffer_size); extern void LogicalTapeRewindForWrite(LogicalTapeSet *lts, int tapenum); extern void LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, - TapeShare *share); + TapeShare *share); extern size_t LogicalTapeBackspace(LogicalTapeSet *lts, int tapenum, - size_t size); + size_t size); extern void LogicalTapeSeek(LogicalTapeSet *lts, int tapenum, - long blocknum, int offset); + long blocknum, int offset); extern void LogicalTapeTell(LogicalTapeSet *lts, int tapenum, - long *blocknum, int *offset); + long *blocknum, int *offset); extern long LogicalTapeSetBlocks(LogicalTapeSet *lts); #endif /* LOGTAPE_H */ diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index e55ea4035b8..c8df5bff9f9 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -3,7 +3,7 @@ * lsyscache.h * Convenience routines for common queries in the system catalog cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/lsyscache.h @@ -44,6 +44,7 @@ typedef struct AttStatsSlot { /* Always filled: */ Oid staop; /* Actual staop for the found slot */ + Oid stacoll; /* Actual collation for the found slot */ /* Filled if ATTSTATSSLOT_VALUES is specified: */ Oid valuetype; /* Actual datatype of the values */ Datum *values; /* slot's "values" array, or NULL if none */ @@ -65,36 +66,38 @@ extern bool op_in_opfamily(Oid opno, Oid opfamily); extern int get_op_opfamily_strategy(Oid opno, Oid opfamily); extern Oid get_op_opfamily_sortfamily(Oid opno, Oid opfamily); extern void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, - int *strategy, - Oid *lefttype, - Oid *righttype); -extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, - int16 strategy); + int *strategy, + Oid *lefttype, + Oid *righttype); +extern Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, + int16 strategy); extern bool get_ordering_op_properties(Oid opno, - Oid *opfamily, Oid *opcintype, int16 *strategy); + Oid *opfamily, Oid *opcintype, int16 *strategy); extern Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse); extern Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type); extern List *get_mergejoin_opfamilies(Oid opno); extern bool get_compatible_hash_operators(Oid opno, - Oid *lhs_opno, Oid *rhs_opno); + Oid *lhs_opno, Oid *rhs_opno); extern bool get_op_hash_functions(Oid opno, - RegProcedure *lhs_procno, RegProcedure *rhs_procno); + RegProcedure *lhs_procno, RegProcedure *rhs_procno); extern List *get_op_btree_interpretation(Oid opno); extern bool equality_ops_are_compatible(Oid opno1, Oid opno2); -extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, - int16 procnum); +extern Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, + int16 procnum); extern char *get_attname(Oid relid, AttrNumber attnum, bool missing_ok); extern AttrNumber get_attnum(Oid relid, const char *attname); -extern char get_attidentity(Oid relid, AttrNumber attnum); +extern char get_attgenerated(Oid relid, AttrNumber attnum); extern Oid get_atttype(Oid relid, AttrNumber attnum); -extern int32 get_atttypmod(Oid relid, AttrNumber attnum); extern void get_atttypetypmodcoll(Oid relid, AttrNumber attnum, - Oid *typid, int32 *typmod, Oid *collid); + Oid *typid, int32 *typmod, Oid *collid); extern char *get_collation_name(Oid colloid); +extern bool get_collation_isdeterministic(Oid colloid); extern char *get_constraint_name(Oid conoid); extern char *get_language_name(Oid langoid, bool missing_ok); extern Oid get_opclass_family(Oid opclass); extern Oid get_opclass_input_type(Oid opclass); +extern bool get_opclass_opfamily_and_input_type(Oid opclass, + Oid *opfamily, Oid *opcintype); extern RegProcedure get_opcode(Oid opno); extern char *get_opname(Oid opno); extern Oid get_op_rettype(Oid opno); @@ -119,13 +122,13 @@ extern char func_volatile(Oid funcid); extern char func_parallel(Oid funcid); extern char get_func_prokind(Oid funcid); extern bool get_func_leakproof(Oid funcid); -extern float4 get_func_cost(Oid funcid); -extern float4 get_func_rows(Oid funcid); +extern RegProcedure get_func_support(Oid funcid); extern Oid get_relname_relid(const char *relname, Oid relnamespace); extern char *get_rel_name(Oid relid); extern Oid get_rel_namespace(Oid relid); extern Oid get_rel_type_id(Oid relid); extern char get_rel_relkind(Oid relid); +extern bool get_rel_relispartition(Oid relid); extern Oid get_rel_tablespace(Oid relid); extern char get_rel_persistence(Oid relid); extern Oid get_transform_fromsql(Oid typid, Oid langid, List *trftypes); @@ -135,16 +138,16 @@ extern int16 get_typlen(Oid typid); extern bool get_typbyval(Oid typid); extern void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval); extern void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, - char *typalign); + char *typalign); extern Oid getTypeIOParam(HeapTuple typeTuple); extern void get_type_io_data(Oid typid, - IOFuncSelector which_func, - int16 *typlen, - bool *typbyval, - char *typalign, - char *typdelim, - Oid *typioparam, - Oid *func); + IOFuncSelector which_func, + int16 *typlen, + bool *typbyval, + char *typalign, + char *typdelim, + Oid *typioparam, + Oid *func); extern char get_typstorage(Oid typid); extern Node *get_typdefault(Oid typid); extern char get_typtype(Oid typid); @@ -152,8 +155,8 @@ extern bool type_is_rowtype(Oid typid); extern bool type_is_enum(Oid typid); extern bool type_is_range(Oid typid); extern void get_type_category_preferred(Oid typid, - char *typcategory, - bool *typispreferred); + char *typcategory, + bool *typispreferred); extern Oid get_typ_typrelid(Oid typid); extern Oid get_element_type(Oid typid); extern Oid get_array_type(Oid typid); @@ -171,11 +174,12 @@ extern Oid getBaseTypeAndTypmod(Oid typid, int32 *typmod); extern int32 get_typavgwidth(Oid typid, int32 typmod); extern int32 get_attavgwidth(Oid relid, AttrNumber attnum); extern bool get_attstatsslot(AttStatsSlot *sslot, HeapTuple statstuple, - int reqkind, Oid reqop, int flags); + int reqkind, Oid reqop, int flags); extern void free_attstatsslot(AttStatsSlot *sslot); extern char *get_namespace_name(Oid nspid); extern char *get_namespace_name_or_temp(Oid nspid); extern Oid get_range_subtype(Oid rangeOid); +extern Oid get_index_column_opclass(Oid index_oid, int attno); #define type_is_array(typid) (get_element_type(typid) != InvalidOid) /* type_is_array_domain accepts both plain arrays and domains over arrays */ diff --git a/src/include/utils/memdebug.h b/src/include/utils/memdebug.h index c2c58b9cdd7..de235f67ae9 100644 --- a/src/include/utils/memdebug.h +++ b/src/include/utils/memdebug.h @@ -7,7 +7,7 @@ * empty definitions for Valgrind client request macros we use. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/memdebug.h diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index bc5757681ba..6a837bc9902 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -7,7 +7,7 @@ * of the API of the memory management subsystem. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/memutils.h @@ -78,14 +78,15 @@ extern void MemoryContextResetChildren(MemoryContext context); extern void MemoryContextDeleteChildren(MemoryContext context); extern void MemoryContextSetIdentifier(MemoryContext context, const char *id); extern void MemoryContextSetParent(MemoryContext context, - MemoryContext new_parent); + MemoryContext new_parent); extern Size GetMemoryChunkSpace(void *pointer); extern MemoryContext MemoryContextGetParent(MemoryContext context); extern bool MemoryContextIsEmpty(MemoryContext context); +extern int64 MemoryContextMemAllocated(MemoryContext context, bool recurse); extern void MemoryContextStats(MemoryContext context); extern void MemoryContextStatsDetail(MemoryContext context, int max_children); extern void MemoryContextAllowInCriticalSection(MemoryContext context, - bool allow); + bool allow); #ifdef MEMORY_CONTEXT_CHECKING extern void MemoryContextCheck(MemoryContext context); @@ -138,10 +139,10 @@ GetMemoryChunkContext(void *pointer) * specific creation routines, and noplace else. */ extern void MemoryContextCreate(MemoryContext node, - NodeTag tag, - const MemoryContextMethods *methods, - MemoryContext parent, - const char *name); + NodeTag tag, + const MemoryContextMethods *methods, + MemoryContext parent, + const char *name); /* @@ -149,38 +150,37 @@ extern void MemoryContextCreate(MemoryContext node, */ /* aset.c */ -extern MemoryContext AllocSetContextCreateExtended(MemoryContext parent, - const char *name, - Size minContextSize, - Size initBlockSize, - Size maxBlockSize); +extern MemoryContext AllocSetContextCreateInternal(MemoryContext parent, + const char *name, + Size minContextSize, + Size initBlockSize, + Size maxBlockSize); /* * This wrapper macro exists to check for non-constant strings used as context * names; that's no longer supported. (Use MemoryContextSetIdentifier if you - * want to provide a variable identifier.) Note you must specify block sizes - * with one of the abstraction macros below. + * want to provide a variable identifier.) */ #ifdef HAVE__BUILTIN_CONSTANT_P -#define AllocSetContextCreate(parent, name, allocparams) \ +#define AllocSetContextCreate(parent, name, ...) \ (StaticAssertExpr(__builtin_constant_p(name), \ "memory context names must be constant strings"), \ - AllocSetContextCreateExtended(parent, name, allocparams)) + AllocSetContextCreateInternal(parent, name, __VA_ARGS__)) #else -#define AllocSetContextCreate(parent, name, allocparams) \ - AllocSetContextCreateExtended(parent, name, allocparams) +#define AllocSetContextCreate \ + AllocSetContextCreateInternal #endif /* slab.c */ extern MemoryContext SlabContextCreate(MemoryContext parent, - const char *name, - Size blockSize, - Size chunkSize); + const char *name, + Size blockSize, + Size chunkSize); /* generation.c */ extern MemoryContext GenerationContextCreate(MemoryContext parent, - const char *name, - Size blockSize); + const char *name, + Size blockSize); /* * Recommended default alloc parameters, suitable for "ordinary" contexts diff --git a/src/include/utils/nabstime.h b/src/include/utils/nabstime.h deleted file mode 100644 index 293a49f022e..00000000000 --- a/src/include/utils/nabstime.h +++ /dev/null @@ -1,103 +0,0 @@ -/*------------------------------------------------------------------------- - * - * nabstime.h - * Definitions for the "new" abstime code. - * - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/nabstime.h - * - *------------------------------------------------------------------------- - */ -#ifndef NABSTIME_H -#define NABSTIME_H - -#include - -#include "fmgr.h" -#include "pgtime.h" - - -/* ---------------------------------------------------------------- - * - * time types + support macros - * - * ---------------------------------------------------------------- - */ - -/* - * Although time_t generally is a long int on 64 bit systems, these two - * types must be 4 bytes, because that's what pg_type.h assumes. They - * should be yanked (long) before 2038 and be replaced by timestamp and - * interval. - */ -typedef int32 AbsoluteTime; -typedef int32 RelativeTime; - -typedef struct -{ - int32 status; - AbsoluteTime data[2]; -} TimeIntervalData; - -typedef TimeIntervalData *TimeInterval; - -/* - * Macros for fmgr-callable functions. - */ -#define DatumGetAbsoluteTime(X) ((AbsoluteTime) DatumGetInt32(X)) -#define DatumGetRelativeTime(X) ((RelativeTime) DatumGetInt32(X)) -#define DatumGetTimeInterval(X) ((TimeInterval) DatumGetPointer(X)) - -#define AbsoluteTimeGetDatum(X) Int32GetDatum(X) -#define RelativeTimeGetDatum(X) Int32GetDatum(X) -#define TimeIntervalGetDatum(X) PointerGetDatum(X) - -#define PG_GETARG_ABSOLUTETIME(n) DatumGetAbsoluteTime(PG_GETARG_DATUM(n)) -#define PG_GETARG_RELATIVETIME(n) DatumGetRelativeTime(PG_GETARG_DATUM(n)) -#define PG_GETARG_TIMEINTERVAL(n) DatumGetTimeInterval(PG_GETARG_DATUM(n)) - -#define PG_RETURN_ABSOLUTETIME(x) return AbsoluteTimeGetDatum(x) -#define PG_RETURN_RELATIVETIME(x) return RelativeTimeGetDatum(x) -#define PG_RETURN_TIMEINTERVAL(x) return TimeIntervalGetDatum(x) - -/* - * Reserved values - * Epoch is Unix system time zero, but needs to be kept as a reserved - * value rather than converting to time since timezone calculations - * might move it away from 1970-01-01 00:00:00Z - tgl 97/02/20 - * - * Pre-v6.1 code had large decimal numbers for reserved values. - * These were chosen as special 32-bit bit patterns, - * so redefine them explicitly using these bit patterns. - tgl 97/02/24 - */ -#define INVALID_ABSTIME ((AbsoluteTime) 0x7FFFFFFE) /* 2147483647 (2^31 - 1) */ -#define NOEND_ABSTIME ((AbsoluteTime) 0x7FFFFFFC) /* 2147483645 (2^31 - 3) */ -#define NOSTART_ABSTIME ((AbsoluteTime) INT_MIN) /* -2147483648 */ - -#define INVALID_RELTIME ((RelativeTime) 0x7FFFFFFE) /* 2147483647 (2^31 - 1) */ - -#define AbsoluteTimeIsValid(time) \ - ((bool) ((time) != INVALID_ABSTIME)) - -/* - * Because NOSTART_ABSTIME is defined as INT_MIN, there can't be any - * AbsoluteTime values less than it. Therefore, we can code the test - * "time > NOSTART_ABSTIME" as "time != NOSTART_ABSTIME", which avoids - * compiler bugs on some platforms. --- tgl & az, 11/2000 - */ -#define AbsoluteTimeIsReal(time) \ - ((bool) (((AbsoluteTime) (time)) < NOEND_ABSTIME && \ - ((AbsoluteTime) (time)) != NOSTART_ABSTIME)) - -#define RelativeTimeIsValid(time) \ - ((bool) (((RelativeTime) (time)) != INVALID_RELTIME)) - - -/* non-fmgr-callable support routines */ -extern AbsoluteTime GetCurrentAbsoluteTime(void); -extern void abstime2tm(AbsoluteTime time, int *tzp, struct pg_tm *tm, char **tzn); - -#endif /* NABSTIME_H */ diff --git a/src/include/utils/numeric.h b/src/include/utils/numeric.h index cd8da8bdc25..7cc597d7b09 100644 --- a/src/include/utils/numeric.h +++ b/src/include/utils/numeric.h @@ -5,7 +5,7 @@ * * Original coding 1998, Jan Wieck. Heavily revised 2003, Tom Lane. * - * Copyright (c) 1998-2018, PostgreSQL Global Development Group + * Copyright (c) 1998-2019, PostgreSQL Global Development Group * * src/include/utils/numeric.h * @@ -61,4 +61,16 @@ int32 numeric_maximum_size(int32 typmod); extern char *numeric_out_sci(Numeric num, int scale); extern char *numeric_normalize(Numeric num); +extern Numeric numeric_add_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_sub_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_mul_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_div_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern Numeric numeric_mod_opt_error(Numeric num1, Numeric num2, + bool *have_error); +extern int32 numeric_int4_opt_error(Numeric num, bool *error); + #endif /* _PG_NUMERIC_H_ */ diff --git a/src/include/utils/palloc.h b/src/include/utils/palloc.h index 781e948f692..a5f435ee068 100644 --- a/src/include/utils/palloc.h +++ b/src/include/utils/palloc.h @@ -18,7 +18,7 @@ * everything that should be freed. See utils/mmgr/README for more info. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/palloc.h @@ -72,7 +72,7 @@ extern void *MemoryContextAlloc(MemoryContext context, Size size); extern void *MemoryContextAllocZero(MemoryContext context, Size size); extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); extern void *MemoryContextAllocExtended(MemoryContext context, - Size size, int flags); + Size size, int flags); extern void *palloc(Size size); extern void *palloc0(Size size); @@ -117,7 +117,7 @@ MemoryContextSwitchTo(MemoryContext context) /* Registration of memory context reset/delete callbacks */ extern void MemoryContextRegisterResetCallback(MemoryContext context, - MemoryContextCallback *cb); + MemoryContextCallback *cb); /* * These are like standard strdup() except the copied string is diff --git a/src/include/utils/partcache.h b/src/include/utils/partcache.h new file mode 100644 index 00000000000..823ad2eeb65 --- /dev/null +++ b/src/include/utils/partcache.h @@ -0,0 +1,101 @@ +/*------------------------------------------------------------------------- + * + * partcache.h + * + * Copyright (c) 1996-2019, PostgreSQL Global Development Group + * + * src/include/utils/partcache.h + * + *------------------------------------------------------------------------- + */ +#ifndef PARTCACHE_H +#define PARTCACHE_H + +#include "access/attnum.h" +#include "fmgr.h" +#include "nodes/pg_list.h" +#include "nodes/primnodes.h" +#include "partitioning/partdefs.h" +#include "utils/relcache.h" + +/* + * Information about the partition key of a relation + */ +typedef struct PartitionKeyData +{ + char strategy; /* partitioning strategy */ + int16 partnatts; /* number of columns in the partition key */ + AttrNumber *partattrs; /* attribute numbers of columns in the + * partition key or 0 if it's an expr */ + List *partexprs; /* list of expressions in the partitioning + * key, one for each zero-valued partattrs */ + + Oid *partopfamily; /* OIDs of operator families */ + Oid *partopcintype; /* OIDs of opclass declared input data types */ + FmgrInfo *partsupfunc; /* lookup info for support funcs */ + + /* Partitioning collation per attribute */ + Oid *partcollation; + + /* Type information per attribute */ + Oid *parttypid; + int32 *parttypmod; + int16 *parttyplen; + bool *parttypbyval; + char *parttypalign; + Oid *parttypcoll; +} PartitionKeyData; + +extern void RelationBuildPartitionKey(Relation relation); +extern List *RelationGetPartitionQual(Relation rel); +extern Expr *get_partition_qual_relid(Oid relid); + +/* + * PartitionKey inquiry functions + */ +static inline int +get_partition_strategy(PartitionKey key) +{ + return key->strategy; +} + +static inline int +get_partition_natts(PartitionKey key) +{ + return key->partnatts; +} + +static inline List * +get_partition_exprs(PartitionKey key) +{ + return key->partexprs; +} + +/* + * PartitionKey inquiry functions - one column + */ +static inline int16 +get_partition_col_attnum(PartitionKey key, int col) +{ + return key->partattrs[col]; +} + +static inline Oid +get_partition_col_typid(PartitionKey key, int col) +{ + return key->parttypid[col]; +} + +static inline int32 +get_partition_col_typmod(PartitionKey key, int col) +{ + return key->parttypmod[col]; +} + +static inline Oid +get_partition_col_collation(PartitionKey key, int col) +{ + return key->partcollation[col]; +} + +#endif /* PARTCACHE_H */ diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h index 48bca045c2d..4d5c99d1a70 100644 --- a/src/include/utils/pg_crc.h +++ b/src/include/utils/pg_crc.h @@ -26,7 +26,7 @@ * * The CRC-32C variant is in port/pg_crc32c.h. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_crc.h diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index 88a3134862f..b4b3aa5843e 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -4,7 +4,7 @@ * * src/include/utils/pg_locale.h * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * *----------------------------------------------------------------------- */ @@ -82,6 +82,7 @@ extern void cache_locale_time(void); struct pg_locale_struct { char provider; + bool deterministic; union { #ifdef HAVE_LOCALE_T @@ -111,8 +112,8 @@ extern int32_t icu_from_uchar(char **result, const UChar *buff_uchar, int32_t le /* 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); + pg_locale_t locale); 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, pg_locale_t locale); #endif /* _PG_LOCALE_ */ diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h index 0db478a259a..70d8640ef3e 100644 --- a/src/include/utils/pg_lsn.h +++ b/src/include/utils/pg_lsn.h @@ -5,7 +5,7 @@ * PostgreSQL. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_lsn.h @@ -24,4 +24,6 @@ #define PG_GETARG_LSN(n) DatumGetLSN(PG_GETARG_DATUM(n)) #define PG_RETURN_LSN(x) return LSNGetDatum(x) +extern XLogRecPtr pg_lsn_in_internal(const char *str, bool *have_error); + #endif /* PG_LSN_H */ diff --git a/src/include/utils/pg_rusage.h b/src/include/utils/pg_rusage.h index 5768caab818..95f4f87b2ac 100644 --- a/src/include/utils/pg_rusage.h +++ b/src/include/utils/pg_rusage.h @@ -4,7 +4,7 @@ * header file for resource usage measurement support routines * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pg_rusage.h diff --git a/src/include/utils/pidfile.h b/src/include/utils/pidfile.h index d3c47aea42e..21e7ccf92fb 100644 --- a/src/include/utils/pidfile.h +++ b/src/include/utils/pidfile.h @@ -3,7 +3,7 @@ * pidfile.h * Declarations describing the data directory lock file (postmaster.pid) * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/pidfile.h @@ -28,7 +28,8 @@ * * Lines 6 and up are added via AddToDataDirLockFile() after initial file * creation; also, line 5 is initially empty and is changed after the first - * Unix socket is opened. + * Unix socket is opened. Onlookers should not assume that lines 4 and up + * are filled in any particular order. * * Socket lock file(s), if used, have the same contents as lines 1-5, with * line 5 being their own directory. diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index ab20aa04b0a..de2555ec2d3 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -5,7 +5,7 @@ * * See plancache.c for comments. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/plancache.h @@ -16,14 +16,27 @@ #define PLANCACHE_H #include "access/tupdesc.h" +#include "lib/ilist.h" #include "nodes/params.h" #include "utils/queryenvironment.h" /* Forward declaration, to avoid including parsenodes.h here */ struct RawStmt; +/* possible values for plan_cache_mode */ +typedef enum +{ + PLAN_CACHE_MODE_AUTO, + PLAN_CACHE_MODE_FORCE_GENERIC_PLAN, + PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN +} PlanCacheMode; + +/* GUC parameter */ +extern int plan_cache_mode; + #define CACHEDPLANSOURCE_MAGIC 195726186 #define CACHEDPLAN_MAGIC 953717834 +#define CACHEDEXPR_MAGIC 838275847 /* * CachedPlanSource (which might better have been called CachedQuery) @@ -110,7 +123,7 @@ typedef struct CachedPlanSource bool is_valid; /* is the query_list currently valid? */ int generation; /* increments each time we create a plan */ /* If CachedPlanSource has been saved, it is a member of a global list */ - struct CachedPlanSource *next_saved; /* list link, if so */ + dlist_node node; /* list link, if is_saved */ /* State kept to help decide whether to use custom or generic plans: */ double generic_cost; /* cost of generic plan, or -1 if not known */ double total_custom_cost; /* total cost of custom plans so far */ @@ -143,43 +156,70 @@ typedef struct CachedPlan MemoryContext context; /* context containing this CachedPlan */ } CachedPlan; +/* + * CachedExpression is a low-overhead mechanism for caching the planned form + * of standalone scalar expressions. While such expressions are not usually + * subject to cache invalidation events, that can happen, for example because + * of replacement of a SQL function that was inlined into the expression. + * The plancache takes care of storing the expression tree and marking it + * invalid if a cache invalidation occurs, but the caller must notice the + * !is_valid status and discard the obsolete expression without reusing it. + * We do not store the original parse tree, only the planned expression; + * this is an optimization based on the assumption that we usually will not + * need to replan for the life of the session. + */ +typedef struct CachedExpression +{ + int magic; /* should equal CACHEDEXPR_MAGIC */ + Node *expr; /* planned form of expression */ + bool is_valid; /* is the expression still valid? */ + /* remaining fields should be treated as private to plancache.c: */ + List *relationOids; /* OIDs of relations the expr depends on */ + List *invalItems; /* other dependencies, as PlanInvalItems */ + MemoryContext context; /* context containing this CachedExpression */ + dlist_node node; /* link in global list of CachedExpressions */ +} CachedExpression; + extern void InitPlanCache(void); extern void ResetPlanCache(void); extern CachedPlanSource *CreateCachedPlan(struct RawStmt *raw_parse_tree, - const char *query_string, - const char *commandTag); + const char *query_string, + const char *commandTag); extern CachedPlanSource *CreateOneShotCachedPlan(struct RawStmt *raw_parse_tree, - const char *query_string, - const char *commandTag); + const char *query_string, + const char *commandTag); extern void CompleteCachedPlan(CachedPlanSource *plansource, - List *querytree_list, - MemoryContext querytree_context, - Oid *param_types, - int num_params, - ParserSetupHook parserSetup, - void *parserSetupArg, - int cursor_options, - bool fixed_result); + List *querytree_list, + MemoryContext querytree_context, + Oid *param_types, + int num_params, + ParserSetupHook parserSetup, + void *parserSetupArg, + int cursor_options, + bool fixed_result); extern void SaveCachedPlan(CachedPlanSource *plansource); extern void DropCachedPlan(CachedPlanSource *plansource); extern void CachedPlanSetParentContext(CachedPlanSource *plansource, - MemoryContext newcontext); + MemoryContext newcontext); extern CachedPlanSource *CopyCachedPlan(CachedPlanSource *plansource); extern bool CachedPlanIsValid(CachedPlanSource *plansource); extern List *CachedPlanGetTargetList(CachedPlanSource *plansource, - QueryEnvironment *queryEnv); + QueryEnvironment *queryEnv); extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource, - ParamListInfo boundParams, - bool useResOwner, - QueryEnvironment *queryEnv); + ParamListInfo boundParams, + bool useResOwner, + QueryEnvironment *queryEnv); extern void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner); +extern CachedExpression *GetCachedExpression(Node *expr); +extern void FreeCachedExpression(CachedExpression *cexpr); + #endif /* PLANCACHE_H */ diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h index b4a259dcf8f..098c837e0a1 100644 --- a/src/include/utils/portal.h +++ b/src/include/utils/portal.h @@ -36,7 +36,7 @@ * to look like NO SCROLL cursors. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/portal.h @@ -116,7 +116,7 @@ typedef struct PortalData /* Bookkeeping data */ const char *name; /* portal's name */ const char *prepStmtName; /* source prepared statement (NULL if none) */ - MemoryContext portalContext;/* subsidiary memory for portal */ + MemoryContext portalContext; /* subsidiary memory for portal */ ResourceOwner resowner; /* resources owned by portal */ void (*cleanup) (Portal portal); /* cleanup hook */ @@ -208,12 +208,12 @@ extern void AtAbort_Portals(void); extern void AtCleanup_Portals(void); extern void PortalErrorCleanup(void); extern void AtSubCommit_Portals(SubTransactionId mySubid, - SubTransactionId parentSubid, - ResourceOwner parentXactOwner); + SubTransactionId parentSubid, + ResourceOwner parentXactOwner); extern void AtSubAbort_Portals(SubTransactionId mySubid, - SubTransactionId parentSubid, - ResourceOwner myXactOwner, - ResourceOwner parentXactOwner); + SubTransactionId parentSubid, + ResourceOwner myXactOwner, + ResourceOwner parentXactOwner); extern void AtSubCleanup_Portals(SubTransactionId mySubid); extern Portal CreatePortal(const char *name, bool allowDup, bool dupSilent); extern Portal CreateNewPortal(void); @@ -225,11 +225,11 @@ extern void MarkPortalFailed(Portal portal); extern void PortalDrop(Portal portal, bool isTopCommit); extern Portal GetPortalByName(const char *name); extern void PortalDefineQuery(Portal portal, - const char *prepStmtName, - const char *sourceText, - const char *commandTag, - List *stmts, - CachedPlan *cplan); + const char *prepStmtName, + const char *sourceText, + const char *commandTag, + List *stmts, + CachedPlan *cplan); extern PlannedStmt *PortalGetPrimaryStmt(Portal portal); extern void PortalCreateHoldStore(Portal portal); extern void PortalHashTableDeleteAll(void); diff --git a/src/include/utils/ps_status.h b/src/include/utils/ps_status.h index 2ba5a0ea2ea..23f1e59ffcd 100644 --- a/src/include/utils/ps_status.h +++ b/src/include/utils/ps_status.h @@ -17,7 +17,7 @@ extern bool update_process_title; extern char **save_ps_display_args(int argc, char **argv); extern void init_ps_display(const char *username, const char *dbname, - const char *host_info, const char *initial_str); + const char *host_info, const char *initial_str); extern void set_ps_display(const char *activity, bool force); diff --git a/src/include/utils/queryenvironment.h b/src/include/utils/queryenvironment.h index 34fde6401f5..6d5086fa16a 100644 --- a/src/include/utils/queryenvironment.h +++ b/src/include/utils/queryenvironment.h @@ -4,7 +4,7 @@ * Access to functions to mutate the query environment and retrieve the * actual data related to entries (if any). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/queryenvironment.h diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h index 83e94e005b4..580e4765017 100644 --- a/src/include/utils/rangetypes.h +++ b/src/include/utils/rangetypes.h @@ -4,7 +4,7 @@ * Declarations for Postgres range types. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/rangetypes.h @@ -96,44 +96,44 @@ extern bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, /* internal versions of the above */ extern bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); extern bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, - RangeType *r2); + RangeType *r2); /* assorted support functions */ extern TypeCacheEntry *range_get_typcache(FunctionCallInfo fcinfo, - Oid rngtypid); + Oid rngtypid); extern RangeType *range_serialize(TypeCacheEntry *typcache, RangeBound *lower, - RangeBound *upper, bool empty); + RangeBound *upper, bool empty); extern void range_deserialize(TypeCacheEntry *typcache, RangeType *range, - RangeBound *lower, RangeBound *upper, - bool *empty); + RangeBound *lower, RangeBound *upper, + bool *empty); extern char range_get_flags(RangeType *range); extern void range_set_contain_empty(RangeType *range); extern RangeType *make_range(TypeCacheEntry *typcache, RangeBound *lower, - RangeBound *upper, bool empty); -extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, - RangeBound *b2); -extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, - RangeBound *b2); + RangeBound *upper, bool empty); +extern int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, + RangeBound *b2); +extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, + RangeBound *b2); extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1, - RangeBound bound2); + RangeBound bound2); extern RangeType *make_empty_range(TypeCacheEntry *typcache); #endif /* RANGETYPES_H */ diff --git a/src/include/utils/regproc.h b/src/include/utils/regproc.h index 5b9a8cbee86..494f36121b1 100644 --- a/src/include/utils/regproc.h +++ b/src/include/utils/regproc.h @@ -3,7 +3,7 @@ * regproc.h * Functions for the built-in types regproc, regclass, regtype, etc. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/regproc.h @@ -19,10 +19,10 @@ extern List *stringToQualifiedNameList(const char *string); extern char *format_procedure(Oid procedure_oid); extern char *format_procedure_qualified(Oid procedure_oid); extern void format_procedure_parts(Oid operator_oid, List **objnames, - List **objargs); + List **objargs); extern char *format_operator(Oid operator_oid); extern char *format_operator_qualified(Oid operator_oid); extern void format_operator_parts(Oid operator_oid, List **objnames, - List **objargs); + List **objargs); #endif diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index ffffde01da9..a5cf804f9fc 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -4,7 +4,7 @@ * POSTGRES relation descriptor (a/k/a relcache entry) definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/rel.h @@ -19,7 +19,6 @@ #include "catalog/pg_class.h" #include "catalog/pg_index.h" #include "catalog/pg_publication.h" -#include "fmgr.h" #include "nodes/bitmapset.h" #include "rewrite/prs2lock.h" #include "storage/block.h" @@ -46,36 +45,6 @@ typedef struct LockInfoData typedef LockInfoData *LockInfo; -/* - * Information about the partition key of a relation - */ -typedef struct PartitionKeyData -{ - char strategy; /* partitioning strategy */ - int16 partnatts; /* number of columns in the partition key */ - AttrNumber *partattrs; /* attribute numbers of columns in the - * partition key */ - List *partexprs; /* list of expressions in the partitioning - * key, or NIL */ - - Oid *partopfamily; /* OIDs of operator families */ - Oid *partopcintype; /* OIDs of opclass declared input data types */ - FmgrInfo *partsupfunc; /* lookup info for support funcs */ - - /* Partitioning collation per attribute */ - Oid *partcollation; - - /* Type information per attribute */ - Oid *parttypid; - int32 *parttypmod; - int16 *parttyplen; - bool *parttypbyval; - char *parttypalign; - Oid *parttypcoll; -} PartitionKeyData; - -typedef struct PartitionKeyData *PartitionKey; - /* * Here are the contents of a relation cache entry. */ @@ -90,8 +59,8 @@ typedef struct RelationData bool rd_islocaltemp; /* rel is a temp rel of this session */ bool rd_isnailed; /* rel is nailed in cache */ bool rd_isvalid; /* relcache entry is valid */ - char rd_indexvalid; /* state of rd_indexlist: 0 = not valid, 1 = - * valid, 2 = temporarily forced */ + bool rd_indexvalid; /* is rd_indexlist valid? (also rd_pkindex and + * rd_replidindex) */ bool rd_statvalid; /* is rd_statlist valid? */ /* @@ -105,7 +74,7 @@ typedef struct RelationData * when a relation has multiple new relfilenodes within a single * transaction, with one of them occurring in a subsequently aborted * subtransaction, e.g. BEGIN; TRUNCATE t; SAVEPOINT save; TRUNCATE t; - * ROLLBACK TO save; -- rd_newRelfilenode is now forgotten + * ROLLBACK TO save; -- rd_newRelfilenodeSubid is now forgotten */ SubTransactionId rd_createSubid; /* rel was created in current xact */ SubTransactionId rd_newRelfilenodeSubid; /* new relfilenode assigned in @@ -125,15 +94,16 @@ typedef struct RelationData List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */ bool rd_fkeyvalid; /* true if list has been computed */ - MemoryContext rd_partkeycxt; /* private memory cxt for the below */ struct PartitionKeyData *rd_partkey; /* partition key, or NULL */ - MemoryContext rd_pdcxt; /* private context for partdesc */ + MemoryContext rd_partkeycxt; /* private context for rd_partkey, if any */ struct PartitionDescData *rd_partdesc; /* partitions, or NULL */ + MemoryContext rd_pdcxt; /* private context for rd_partdesc, if any */ List *rd_partcheck; /* partition CHECK quals */ + bool rd_partcheckvalid; /* true if list has been computed */ + MemoryContext rd_partcheckcxt; /* private cxt for rd_partcheck, if any */ /* data managed by RelationGetIndexList: */ List *rd_indexlist; /* list of OIDs of indexes on relation */ - Oid rd_oidindex; /* OID of unique index on OID, if any */ Oid rd_pkindex; /* OID of primary key, if any */ Oid rd_replidindex; /* OID of replica identity index, if any */ @@ -141,12 +111,10 @@ typedef struct RelationData List *rd_statlist; /* list of OIDs of extended stats */ /* data managed by RelationGetIndexAttrBitmap: */ - Bitmapset *rd_indexattr; /* columns used in non-projection indexes */ - Bitmapset *rd_projindexattr; /* columns used in projection indexes */ + Bitmapset *rd_indexattr; /* identifies columns used in indexes */ Bitmapset *rd_keyattr; /* cols that can be ref'd by foreign keys */ Bitmapset *rd_pkattr; /* cols included in primary key */ Bitmapset *rd_idattr; /* included in replica identity index */ - Bitmapset *rd_projidx; /* Oids of projection indexes */ PublicationActions *rd_pubactions; /* publication actions */ @@ -157,6 +125,20 @@ typedef struct RelationData */ bytea *rd_options; /* parsed pg_class.reloptions */ + /* + * Oid of the handler for this relation. For an index this is a function + * returning IndexAmRoutine, for table like relations a function returning + * TableAmRoutine. This is stored separately from rd_indam, rd_tableam as + * its lookup requires syscache access, but during relcache bootstrap we + * need to be able to initialize rd_tableam without syscache lookups. + */ + Oid rd_amhandler; /* OID of index AM's handler function */ + + /* + * Table access method. + */ + const struct TableAmRoutine *rd_tableam; + /* These are non-NULL only for an index relation: */ Form_pg_index rd_index; /* pg_index tuple describing this index */ /* use "struct" here to avoid needing to include htup.h: */ @@ -169,31 +151,33 @@ typedef struct RelationData * those with lefttype and righttype equal to the opclass's opcintype. The * arrays are indexed by support function number, which is a sufficient * identifier given that restriction. - * - * Note: rd_amcache is available for index AMs to cache private data about - * an index. This must be just a cache since it may get reset at any time - * (in particular, it will get reset by a relcache inval message for the - * index). If used, it must point to a single memory chunk palloc'd in - * rd_indexcxt. A relcache reset will include freeing that chunk and - * setting rd_amcache = NULL. */ - Oid rd_amhandler; /* OID of index AM's handler function */ MemoryContext rd_indexcxt; /* private memory cxt for this stuff */ /* use "struct" here to avoid needing to include amapi.h: */ - struct IndexAmRoutine *rd_amroutine; /* index AM's API struct */ + struct IndexAmRoutine *rd_indam; /* index AM's API struct */ Oid *rd_opfamily; /* OIDs of op families for each index col */ Oid *rd_opcintype; /* OIDs of opclass declared input data types */ RegProcedure *rd_support; /* OIDs of support procedures */ - FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ + struct FmgrInfo *rd_supportinfo; /* lookup info for support procedures */ int16 *rd_indoption; /* per-column AM-specific flags */ List *rd_indexprs; /* index expression trees, if any */ List *rd_indpred; /* index predicate tree, if any */ Oid *rd_exclops; /* OIDs of exclusion operators, if any */ Oid *rd_exclprocs; /* OIDs of exclusion ops' procs, if any */ uint16 *rd_exclstrats; /* exclusion ops' strategy numbers, if any */ - void *rd_amcache; /* available for use by index AM */ Oid *rd_indcollation; /* OIDs of index collations */ + /* + * rd_amcache is available for index and table AMs to cache private data + * about the relation. This must be just a cache since it may get reset + * at any time (in particular, it will get reset by a relcache inval + * message for the relation). If used, it must point to a single memory + * chunk palloc'd in CacheMemoryContext, or in rd_indexcxt for an index + * relation. A relcache reset will include freeing that chunk and setting + * rd_amcache = NULL. + */ + void *rd_amcache; /* available for use by index/table AM */ + /* * foreign-table support * @@ -232,12 +216,13 @@ typedef struct RelationData * The per-FK-column arrays can be fixed-size because we allow at most * INDEX_MAX_KEYS columns in a foreign key constraint. * - * Currently, we only cache fields of interest to the planner, but the - * set of fields could be expanded in future. + * Currently, we mostly cache fields of interest to the planner, but the set + * of fields has already grown the constraint OID for other uses. */ typedef struct ForeignKeyCacheInfo { NodeTag type; + Oid conoid; /* oid of the constraint itself */ Oid conrelid; /* relation constrained by the foreign key */ Oid confrelid; /* relation referenced by the foreign key */ int nkeys; /* number of columns in the foreign key */ @@ -247,14 +232,6 @@ typedef struct ForeignKeyCacheInfo Oid conpfeqop[INDEX_MAX_KEYS]; /* PK = FK operator OIDs */ } ForeignKeyCacheInfo; -/* - * Options common for all all indexes - */ -typedef struct GenericIndexOpts -{ - int32 vl_len_; - bool recheck_on_update; -} GenericIndexOpts; /* * StdRdOptions @@ -270,7 +247,6 @@ typedef struct AutoVacOpts bool enabled; int vacuum_threshold; int analyze_threshold; - int vacuum_cost_delay; int vacuum_cost_limit; int freeze_min_age; int freeze_max_age; @@ -279,6 +255,7 @@ typedef struct AutoVacOpts int multixact_freeze_max_age; int multixact_freeze_table_age; int log_min_duration; + float8 vacuum_cost_delay; float8 vacuum_scale_factor; float8 analyze_scale_factor; } AutoVacOpts; @@ -293,6 +270,8 @@ typedef struct StdRdOptions AutoVacOpts autovacuum; /* autovacuum-related options */ bool user_catalog_table; /* use as an additional catalog relation */ int parallel_workers; /* max number of parallel workers */ + bool vacuum_index_cleanup; /* enables index vacuuming and cleanup */ + bool vacuum_truncate; /* enables vacuum to truncate a relation */ } StdRdOptions; #define HEAP_MIN_FILLFACTOR 10 @@ -348,6 +327,13 @@ typedef struct StdRdOptions ((relation)->rd_options ? \ ((StdRdOptions *) (relation)->rd_options)->parallel_workers : (defaultpw)) +/* ViewOptions->check_option values */ +typedef enum ViewOptCheckOption +{ + VIEW_OPTION_CHECK_OPTION_NOT_SET, + VIEW_OPTION_CHECK_OPTION_LOCAL, + VIEW_OPTION_CHECK_OPTION_CASCADED +} ViewOptCheckOption; /* * ViewOptions @@ -357,7 +343,7 @@ typedef struct ViewOptions { int32 vl_len_; /* varlena header (do not touch directly!) */ bool security_barrier; - int check_option_offset; + ViewOptCheckOption check_option; } ViewOptions; /* @@ -376,7 +362,8 @@ typedef struct ViewOptions */ #define RelationHasCheckOption(relation) \ ((relation)->rd_options && \ - ((ViewOptions *) (relation)->rd_options)->check_option_offset != 0) + ((ViewOptions *) (relation)->rd_options)->check_option != \ + VIEW_OPTION_CHECK_OPTION_NOT_SET) /* * RelationHasLocalCheckOption @@ -385,10 +372,8 @@ typedef struct ViewOptions */ #define RelationHasLocalCheckOption(relation) \ ((relation)->rd_options && \ - ((ViewOptions *) (relation)->rd_options)->check_option_offset != 0 ? \ - strcmp((char *) (relation)->rd_options + \ - ((ViewOptions *) (relation)->rd_options)->check_option_offset, \ - "local") == 0 : false) + ((ViewOptions *) (relation)->rd_options)->check_option == \ + VIEW_OPTION_CHECK_OPTION_LOCAL) /* * RelationHasCascadedCheckOption @@ -397,11 +382,8 @@ typedef struct ViewOptions */ #define RelationHasCascadedCheckOption(relation) \ ((relation)->rd_options && \ - ((ViewOptions *) (relation)->rd_options)->check_option_offset != 0 ? \ - strcmp((char *) (relation)->rd_options + \ - ((ViewOptions *) (relation)->rd_options)->check_option_offset, \ - "cascaded") == 0 : false) - + ((ViewOptions *) (relation)->rd_options)->check_option == \ + VIEW_OPTION_CHECK_OPTION_CASCADED) /* * RelationIsValid @@ -480,13 +462,12 @@ typedef struct ViewOptions /* * RelationIsMapped - * True if the relation uses the relfilenode map. - * - * NB: this is only meaningful for relkinds that have storage, else it - * will misleadingly say "true". + * True if the relation uses the relfilenode map. Note multiple eval + * of argument! */ #define RelationIsMapped(relation) \ - ((relation)->rd_rel->relfilenode == InvalidOid) + (RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \ + ((relation)->rd_rel->relfilenode == InvalidOid)) /* * RelationOpenSmgr @@ -618,48 +599,6 @@ typedef struct ViewOptions */ #define RelationGetPartitionKey(relation) ((relation)->rd_partkey) -/* - * PartitionKey inquiry functions - */ -static inline int -get_partition_strategy(PartitionKey key) -{ - return key->strategy; -} - -static inline int -get_partition_natts(PartitionKey key) -{ - return key->partnatts; -} - -static inline List * -get_partition_exprs(PartitionKey key) -{ - return key->partexprs; -} - -/* - * PartitionKey inquiry functions - one column - */ -static inline int16 -get_partition_col_attnum(PartitionKey key, int col) -{ - return key->partattrs[col]; -} - -static inline Oid -get_partition_col_typid(PartitionKey key, int col) -{ - return key->parttypid[col]; -} - -static inline int32 -get_partition_col_typmod(PartitionKey key, int col) -{ - return key->parttypmod[col]; -} - /* * RelationGetPartitionDesc * Returns partition descriptor for a relation. @@ -669,7 +608,5 @@ get_partition_col_typmod(PartitionKey key, int col) /* routines in utils/cache/relcache.c */ extern void RelationIncrementReferenceCount(Relation rel); extern void RelationDecrementReferenceCount(Relation rel); -extern bool RelationHasUnloggedIndex(Relation rel); -extern List *RelationGetRepsetList(Relation rel); #endif /* REL_H */ diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index dbbf41b0c16..2f2ace35b05 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -4,7 +4,7 @@ * Relation descriptor cache definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relcache.h @@ -45,7 +45,6 @@ extern void RelationClose(Relation relation); extern List *RelationGetFKeyList(Relation relation); extern List *RelationGetIndexList(Relation relation); extern List *RelationGetStatExtList(Relation relation); -extern Oid RelationGetOidIndex(Relation relation); extern Oid RelationGetPrimaryKeyIndex(Relation relation); extern Oid RelationGetReplicaIndex(Relation relation); extern List *RelationGetIndexExpressions(Relation relation); @@ -53,23 +52,19 @@ extern List *RelationGetIndexPredicate(Relation relation); typedef enum IndexAttrBitmapKind { - INDEX_ATTR_BITMAP_HOT, - INDEX_ATTR_BITMAP_PROJ, + INDEX_ATTR_BITMAP_ALL, INDEX_ATTR_BITMAP_KEY, INDEX_ATTR_BITMAP_PRIMARY_KEY, INDEX_ATTR_BITMAP_IDENTITY_KEY } IndexAttrBitmapKind; extern Bitmapset *RelationGetIndexAttrBitmap(Relation relation, - IndexAttrBitmapKind keyAttrs); + IndexAttrBitmapKind attrKind); extern void RelationGetExclusionInfo(Relation indexRelation, - Oid **operators, - Oid **procs, - uint16 **strategies); - -extern void RelationSetIndexList(Relation relation, - List *indexIds, Oid oidIndex); + Oid **operators, + Oid **procs, + uint16 **strategies); extern void RelationInitIndexAccessInfo(Relation relation); @@ -77,6 +72,8 @@ extern void RelationInitIndexAccessInfo(Relation relation); struct PublicationActions; extern struct PublicationActions *GetRelationPublicationActions(Relation relation); +extern void RelationInitTableAccessMethod(Relation relation); + /* * Routines to support ereport() reports of relation-related errors */ @@ -96,21 +93,21 @@ extern void RelationCacheInitializePhase3(void); * Routine to create a relcache entry for an about-to-be-created relation */ extern Relation RelationBuildLocalRelation(const char *relname, - Oid relnamespace, - TupleDesc tupDesc, - Oid relid, - Oid relfilenode, - Oid reltablespace, - bool shared_relation, - bool mapped_relation, - char relpersistence, - char relkind); + Oid relnamespace, + TupleDesc tupDesc, + Oid relid, + Oid accessmtd, + Oid relfilenode, + Oid reltablespace, + bool shared_relation, + bool mapped_relation, + char relpersistence, + char relkind); /* * Routine to manage assignment of new relfilenode to a relation */ -extern void RelationSetNewRelfilenode(Relation relation, char persistence, - TransactionId freezeXid, MultiXactId minmulti); +extern void RelationSetNewRelfilenode(Relation relation, char persistence); /* * Routines for flushing/rebuilding relcache entries in various scenarios @@ -125,7 +122,7 @@ extern void RelationCloseSmgrByOid(Oid relationId); extern void AtEOXact_RelationCache(bool isCommit); extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, - SubTransactionId parentSubid); + SubTransactionId parentSubid); /* * Routines to help manage rebuilding of relcache init files diff --git a/src/include/utils/relfilenodemap.h b/src/include/utils/relfilenodemap.h index e79115d34f0..9f24530162d 100644 --- a/src/include/utils/relfilenodemap.h +++ b/src/include/utils/relfilenodemap.h @@ -3,7 +3,7 @@ * relfilenodemap.h * relfilenode to oid mapping cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relfilenodemap.h diff --git a/src/include/utils/relmapper.h b/src/include/utils/relmapper.h index f69b1006bf2..2a0a5e2e10a 100644 --- a/src/include/utils/relmapper.h +++ b/src/include/utils/relmapper.h @@ -4,7 +4,7 @@ * Catalog-to-filenode mapping * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relmapper.h @@ -40,7 +40,7 @@ extern Oid RelationMapOidToFilenode(Oid relationId, bool shared); extern Oid RelationMapFilenodeToOid(Oid relationId, bool shared); extern void RelationMapUpdateMap(Oid relationId, Oid fileNode, bool shared, - bool immediate); + bool immediate); extern void RelationMapRemoveMapping(Oid relationId); @@ -48,7 +48,7 @@ extern void RelationMapInvalidate(bool shared); extern void RelationMapInvalidateAll(void); extern void AtCCI_RelationMap(void); -extern void AtEOXact_RelationMap(bool isCommit); +extern void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker); extern void AtPrepare_RelationMap(void); extern void CheckPointRelationMap(void); @@ -59,6 +59,10 @@ extern void RelationMapInitialize(void); extern void RelationMapInitializePhase2(void); extern void RelationMapInitializePhase3(void); +extern Size EstimateRelationMapSpace(void); +extern void SerializeRelationMap(Size maxSize, char *startAddress); +extern void RestoreRelationMap(char *startAddress); + extern void relmap_redo(XLogReaderState *record); extern void relmap_desc(StringInfo buf, XLogReaderState *record); extern const char *relmap_identify(uint8 info); diff --git a/src/include/utils/relptr.h b/src/include/utils/relptr.h index 4b74571e91d..9ebcca5295e 100644 --- a/src/include/utils/relptr.h +++ b/src/include/utils/relptr.h @@ -3,7 +3,7 @@ * relptr.h * This file contains basic declarations for relative pointers. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/relptr.h diff --git a/src/include/utils/reltrigger.h b/src/include/utils/reltrigger.h index 9b4dc7f8109..f1f8c37caab 100644 --- a/src/include/utils/reltrigger.h +++ b/src/include/utils/reltrigger.h @@ -4,7 +4,7 @@ * POSTGRES relation trigger definitions. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/reltrigger.h diff --git a/src/include/utils/resowner.h b/src/include/utils/resowner.h index fe7f49119ba..d1670daf791 100644 --- a/src/include/utils/resowner.h +++ b/src/include/utils/resowner.h @@ -9,7 +9,7 @@ * See utils/resowner/README for more info. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/resowner.h @@ -33,6 +33,7 @@ typedef struct ResourceOwnerData *ResourceOwner; extern PGDLLIMPORT ResourceOwner CurrentResourceOwner; extern PGDLLIMPORT ResourceOwner CurTransactionResourceOwner; extern PGDLLIMPORT ResourceOwner TopTransactionResourceOwner; +extern PGDLLIMPORT ResourceOwner AuxProcessResourceOwner; /* * Resource releasing is done in three phases: pre-locks, locks, and @@ -65,18 +66,20 @@ typedef void (*ResourceReleaseCallback) (ResourceReleasePhase phase, /* generic routines */ extern ResourceOwner ResourceOwnerCreate(ResourceOwner parent, - const char *name); + const char *name); extern void ResourceOwnerRelease(ResourceOwner owner, - ResourceReleasePhase phase, - bool isCommit, - bool isTopLevel); + ResourceReleasePhase phase, + bool isCommit, + bool isTopLevel); extern void ResourceOwnerDelete(ResourceOwner owner); extern ResourceOwner ResourceOwnerGetParent(ResourceOwner owner); extern void ResourceOwnerNewParent(ResourceOwner owner, - ResourceOwner newparent); + ResourceOwner newparent); extern void RegisterResourceReleaseCallback(ResourceReleaseCallback callback, - void *arg); + void *arg); extern void UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, - void *arg); + void *arg); +extern void CreateAuxProcessResourceOwner(void); +extern void ReleaseAuxProcessResources(bool isCommit); #endif /* RESOWNER_H */ diff --git a/src/include/utils/resowner_private.h b/src/include/utils/resowner_private.h index 44dc99eb267..b8261ad8665 100644 --- a/src/include/utils/resowner_private.h +++ b/src/include/utils/resowner_private.h @@ -6,7 +6,7 @@ * See utils/resowner/README for more info. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/resowner_private.h @@ -37,56 +37,56 @@ extern void ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock); /* support for catcache refcount management */ extern void ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner); extern void ResourceOwnerRememberCatCacheRef(ResourceOwner owner, - HeapTuple tuple); + HeapTuple tuple); extern void ResourceOwnerForgetCatCacheRef(ResourceOwner owner, - HeapTuple tuple); + HeapTuple tuple); extern void ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner); extern void ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, - CatCList *list); + CatCList *list); extern void ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, - CatCList *list); + CatCList *list); /* support for relcache refcount management */ extern void ResourceOwnerEnlargeRelationRefs(ResourceOwner owner); extern void ResourceOwnerRememberRelationRef(ResourceOwner owner, - Relation rel); + Relation rel); extern void ResourceOwnerForgetRelationRef(ResourceOwner owner, - Relation rel); + Relation rel); /* support for plancache refcount management */ extern void ResourceOwnerEnlargePlanCacheRefs(ResourceOwner owner); extern void ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, - CachedPlan *plan); + CachedPlan *plan); extern void ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, - CachedPlan *plan); + CachedPlan *plan); /* support for tupledesc refcount management */ extern void ResourceOwnerEnlargeTupleDescs(ResourceOwner owner); extern void ResourceOwnerRememberTupleDesc(ResourceOwner owner, - TupleDesc tupdesc); + TupleDesc tupdesc); extern void ResourceOwnerForgetTupleDesc(ResourceOwner owner, - TupleDesc tupdesc); + TupleDesc tupdesc); /* support for snapshot refcount management */ extern void ResourceOwnerEnlargeSnapshots(ResourceOwner owner); extern void ResourceOwnerRememberSnapshot(ResourceOwner owner, - Snapshot snapshot); + Snapshot snapshot); extern void ResourceOwnerForgetSnapshot(ResourceOwner owner, - Snapshot snapshot); + Snapshot snapshot); /* support for temporary file management */ extern void ResourceOwnerEnlargeFiles(ResourceOwner owner); extern void ResourceOwnerRememberFile(ResourceOwner owner, - File file); + File file); extern void ResourceOwnerForgetFile(ResourceOwner owner, - File file); + File file); /* support for dynamic shared memory management */ extern void ResourceOwnerEnlargeDSMs(ResourceOwner owner); extern void ResourceOwnerRememberDSM(ResourceOwner owner, - dsm_segment *); + dsm_segment *); extern void ResourceOwnerForgetDSM(ResourceOwner owner, - dsm_segment *); + dsm_segment *); /* support for JITContext management */ extern void ResourceOwnerEnlargeJIT(ResourceOwner owner); diff --git a/src/include/utils/rls.h b/src/include/utils/rls.h index f3b48583335..201d94f32b2 100644 --- a/src/include/utils/rls.h +++ b/src/include/utils/rls.h @@ -4,7 +4,7 @@ * Header file for Row Level Security (RLS) utility commands to be used * with the rowsecurity feature. * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/include/utils/rls.h * diff --git a/src/include/utils/ruleutils.h b/src/include/utils/ruleutils.h index 9f9b029ab88..d34cad2f4b8 100644 --- a/src/include/utils/ruleutils.h +++ b/src/include/utils/ruleutils.h @@ -3,7 +3,7 @@ * ruleutils.h * Declarations for ruleutils.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/ruleutils.h @@ -22,16 +22,17 @@ extern char *pg_get_indexdef_string(Oid indexrelid); extern char *pg_get_indexdef_columns(Oid indexrelid, bool pretty); extern char *pg_get_partkeydef_columns(Oid relid, bool pretty); +extern char *pg_get_partconstrdef_string(Oid partitionId, char *aliasname); extern char *pg_get_constraintdef_command(Oid constraintId); extern char *deparse_expression(Node *expr, List *dpcontext, - bool forceprefix, bool showimplicit); + bool forceprefix, bool showimplicit); extern List *deparse_context_for(const char *aliasname, Oid relid); extern List *deparse_context_for_plan_rtable(List *rtable, List *rtable_names); extern List *set_deparse_context_planstate(List *dpcontext, - Node *planstate, List *ancestors); + Node *planstate, List *ancestors); extern List *select_rtable_names_for_explain(List *rtable, - Bitmapset *rels_used); + Bitmapset *rels_used); extern char *generate_collation_name(Oid collid); extern char *get_range_partbound_string(List *bound_datums); diff --git a/src/include/utils/sampling.h b/src/include/utils/sampling.h index c82148515dc..541b507fb50 100644 --- a/src/include/utils/sampling.h +++ b/src/include/utils/sampling.h @@ -3,7 +3,7 @@ * sampling.h * definitions for sampling functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/sampling.h @@ -20,7 +20,7 @@ typedef unsigned short SamplerRandomState[3]; extern void sampler_random_init_state(long seed, - SamplerRandomState randstate); + SamplerRandomState randstate); extern double sampler_random_fract(SamplerRandomState randstate); /* Block sampling methods */ @@ -38,7 +38,7 @@ typedef struct typedef BlockSamplerData *BlockSampler; extern void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks, - int samplesize, long randseed); + int samplesize, long randseed); extern bool BlockSampler_HasMore(BlockSampler bs); extern BlockNumber BlockSampler_Next(BlockSampler bs); diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h index 95e44280c4c..353d38a3ff8 100644 --- a/src/include/utils/selfuncs.h +++ b/src/include/utils/selfuncs.h @@ -5,7 +5,7 @@ * infrastructure for selectivity and cost estimation. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/selfuncs.h @@ -15,9 +15,9 @@ #ifndef SELFUNCS_H #define SELFUNCS_H -#include "fmgr.h" #include "access/htup.h" -#include "nodes/relation.h" +#include "fmgr.h" +#include "nodes/pathnodes.h" /* @@ -85,34 +85,6 @@ typedef struct VariableStatData } while(0) -typedef enum -{ - Pattern_Type_Like, - Pattern_Type_Like_IC, - Pattern_Type_Regex, - Pattern_Type_Regex_IC, - Pattern_Type_Prefix -} Pattern_Type; - -typedef enum -{ - Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Prefix_Exact -} Pattern_Prefix_Status; - -/* - * deconstruct_indexquals is a simple function to examine the indexquals - * attached to a proposed IndexPath. It returns a list of IndexQualInfo - * structs, one per qual expression. - */ -typedef struct -{ - RestrictInfo *rinfo; /* the indexqual itself */ - int indexcol; /* zero-based index column number */ - bool varonleft; /* true if index column is on left of qual */ - Oid clause_op; /* qual's operator OID, if relevant */ - Node *other_operand; /* non-index operand of qual's operator */ -} IndexQualInfo; - /* * genericcostestimate is a general-purpose estimator that can be used for * most index types. In some cases we use genericcostestimate as the base @@ -138,7 +110,7 @@ typedef struct double numIndexPages; /* number of leaf pages visited */ double numIndexTuples; /* number of leaf tuples visited */ double spc_random_page_cost; /* relevant random_page_cost value */ - double num_sa_scans; /* # indexscans from ScalarArrayOps */ + double num_sa_scans; /* # indexscans from ScalarArrayOpExprs */ } GenericCosts; /* Hooks for plugins to get control when we ask for stats */ @@ -156,75 +128,83 @@ extern PGDLLIMPORT get_index_stats_hook_type get_index_stats_hook; /* Functions in selfuncs.c */ extern void examine_variable(PlannerInfo *root, Node *node, int varRelid, - VariableStatData *vardata); + VariableStatData *vardata); extern bool statistic_proc_security_check(VariableStatData *vardata, Oid func_oid); extern bool get_restriction_variable(PlannerInfo *root, List *args, - int varRelid, - VariableStatData *vardata, Node **other, - bool *varonleft); + int varRelid, + VariableStatData *vardata, Node **other, + bool *varonleft); extern void get_join_variables(PlannerInfo *root, List *args, - SpecialJoinInfo *sjinfo, - VariableStatData *vardata1, - VariableStatData *vardata2, - bool *join_is_reversed); + SpecialJoinInfo *sjinfo, + VariableStatData *vardata1, + VariableStatData *vardata2, + bool *join_is_reversed); extern double get_variable_numdistinct(VariableStatData *vardata, - bool *isdefault); + bool *isdefault); extern double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, - Datum constval, bool varonleft, - double *sumcommonp); + Datum constval, bool varonleft, + double *sumcommonp); extern double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, - Datum constval, bool varonleft, - int min_hist_size, int n_skip, - int *hist_size); - -extern Pattern_Prefix_Status pattern_fixed_prefix(Const *patt, - Pattern_Type ptype, - Oid collation, - Const **prefix, - Selectivity *rest_selec); -extern Const *make_greater_string(const Const *str_const, FmgrInfo *ltproc, - Oid collation); + Datum constval, bool varonleft, + int min_hist_size, int n_skip, + int *hist_size); +extern double ineq_histogram_selectivity(PlannerInfo *root, + VariableStatData *vardata, + FmgrInfo *opproc, bool isgt, bool iseq, + Datum constval, Oid consttype); +extern double var_eq_const(VariableStatData *vardata, Oid oproid, + Datum constval, bool constisnull, + bool varonleft, bool negate); +extern double var_eq_non_const(VariableStatData *vardata, Oid oproid, + Node *other, + bool varonleft, bool negate); extern Selectivity boolvarsel(PlannerInfo *root, Node *arg, int varRelid); extern Selectivity booltestsel(PlannerInfo *root, BoolTestType booltesttype, - Node *arg, int varRelid, - JoinType jointype, SpecialJoinInfo *sjinfo); + Node *arg, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo); extern Selectivity nulltestsel(PlannerInfo *root, NullTestType nulltesttype, - Node *arg, int varRelid, - JoinType jointype, SpecialJoinInfo *sjinfo); + Node *arg, int varRelid, + JoinType jointype, SpecialJoinInfo *sjinfo); extern Selectivity scalararraysel(PlannerInfo *root, - ScalarArrayOpExpr *clause, - bool is_join_clause, - int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); + ScalarArrayOpExpr *clause, + bool is_join_clause, + int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); extern int estimate_array_length(Node *arrayexpr); extern Selectivity rowcomparesel(PlannerInfo *root, - RowCompareExpr *clause, - int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); + RowCompareExpr *clause, + int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo); extern void mergejoinscansel(PlannerInfo *root, Node *clause, - Oid opfamily, int strategy, bool nulls_first, - Selectivity *leftstart, Selectivity *leftend, - Selectivity *rightstart, Selectivity *rightend); + Oid opfamily, int strategy, bool nulls_first, + Selectivity *leftstart, Selectivity *leftend, + Selectivity *rightstart, Selectivity *rightend); extern double estimate_num_groups(PlannerInfo *root, List *groupExprs, - double input_rows, List **pgset); + double input_rows, List **pgset); extern void estimate_hash_bucket_stats(PlannerInfo *root, - Node *hashkey, double nbuckets, - Selectivity *mcv_freq, - Selectivity *bucketsize_frac); - -extern List *deconstruct_indexquals(IndexPath *path); + Node *hashkey, double nbuckets, + Selectivity *mcv_freq, + Selectivity *bucketsize_frac); +extern double estimate_hashagg_tablesize(Path *path, + const AggClauseCosts *agg_costs, + double dNumGroups); + +extern List *get_quals_from_indexclauses(List *indexclauses); +extern Cost index_other_operands_eval_cost(PlannerInfo *root, + List *indexquals); +extern List *add_predicate_to_index_quals(IndexOptInfo *index, + List *indexQuals); extern void genericcostestimate(PlannerInfo *root, IndexPath *path, - double loop_count, - List *qinfos, - GenericCosts *costs); + double loop_count, + GenericCosts *costs); /* Functions in array_selfuncs.c */ extern Selectivity scalararraysel_containment(PlannerInfo *root, - Node *leftop, Node *rightop, - Oid elemtype, bool isEquality, bool useOr, - int varRelid); + Node *leftop, Node *rightop, + Oid elemtype, bool isEquality, bool useOr, + int varRelid); #endif /* SELFUNCS_H */ diff --git a/src/include/utils/sharedtuplestore.h b/src/include/utils/sharedtuplestore.h index 834773511d1..9dea626e84f 100644 --- a/src/include/utils/sharedtuplestore.h +++ b/src/include/utils/sharedtuplestore.h @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * * sharedtuplestore.h - * Simple mechinism for sharing tuples between backends. + * Simple mechanism for sharing tuples between backends. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/sharedtuplestore.h @@ -32,16 +32,16 @@ typedef struct SharedTuplestoreAccessor SharedTuplestoreAccessor; extern size_t sts_estimate(int participants); extern SharedTuplestoreAccessor *sts_initialize(SharedTuplestore *sts, - int participants, - int my_participant_number, - size_t meta_data_size, - int flags, - SharedFileSet *fileset, - const char *name); + int participants, + int my_participant_number, + size_t meta_data_size, + int flags, + SharedFileSet *fileset, + const char *name); extern SharedTuplestoreAccessor *sts_attach(SharedTuplestore *sts, - int my_participant_number, - SharedFileSet *fileset); + int my_participant_number, + SharedFileSet *fileset); extern void sts_end_write(SharedTuplestoreAccessor *accessor); @@ -52,10 +52,10 @@ extern void sts_begin_parallel_scan(SharedTuplestoreAccessor *accessor); extern void sts_end_parallel_scan(SharedTuplestoreAccessor *accessor); extern void sts_puttuple(SharedTuplestoreAccessor *accessor, - void *meta_data, - MinimalTuple tuple); + void *meta_data, + MinimalTuple tuple); extern MinimalTuple sts_parallel_scan_next(SharedTuplestoreAccessor *accessor, - void *meta_data); + void *meta_data); #endif /* SHAREDTUPLESTORE_H */ diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h index 83806f30406..67b07df48cb 100644 --- a/src/include/utils/snapmgr.h +++ b/src/include/utils/snapmgr.h @@ -3,7 +3,7 @@ * snapmgr.h * POSTGRES snapshot manager * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/snapmgr.h @@ -13,7 +13,7 @@ #ifndef SNAPMGR_H #define SNAPMGR_H -#include "fmgr.h" +#include "access/transam.h" #include "utils/relcache.h" #include "utils/resowner.h" #include "utils/snapshot.h" @@ -40,7 +40,6 @@ RelationNeedsWAL(rel) \ && !IsCatalogRelation(rel) \ && !RelationIsAccessibleInLogicalDecoding(rel) \ - && !RelationHasUnloggedIndex(rel) \ ) #define EarlyPruningEnabled(rel) (old_snapshot_threshold >= 0 && RelationAllowsEarlyPruning(rel)) @@ -61,6 +60,45 @@ extern PGDLLIMPORT TransactionId RecentXmin; extern PGDLLIMPORT TransactionId RecentGlobalXmin; extern PGDLLIMPORT TransactionId RecentGlobalDataXmin; +/* Variables representing various special snapshot semantics */ +extern PGDLLIMPORT SnapshotData SnapshotSelfData; +extern PGDLLIMPORT SnapshotData SnapshotAnyData; +extern PGDLLIMPORT SnapshotData CatalogSnapshotData; + +#define SnapshotSelf (&SnapshotSelfData) +#define SnapshotAny (&SnapshotAnyData) + +/* + * We don't provide a static SnapshotDirty variable because it would be + * non-reentrant. Instead, users of that snapshot type should declare a + * local variable of type SnapshotData, and initialize it with this macro. + */ +#define InitDirtySnapshot(snapshotdata) \ + ((snapshotdata).snapshot_type = SNAPSHOT_DIRTY) + +/* + * Similarly, some initialization is required for a NonVacuumable snapshot. + * The caller must supply the xmin horizon to use (e.g., RecentGlobalXmin). + */ +#define InitNonVacuumableSnapshot(snapshotdata, xmin_horizon) \ + ((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \ + (snapshotdata).xmin = (xmin_horizon)) + +/* + * Similarly, some initialization is required for SnapshotToast. We need + * to set lsn and whenTaken correctly to support snapshot_too_old. + */ +#define InitToastSnapshot(snapshotdata, l, w) \ + ((snapshotdata).snapshot_type = SNAPSHOT_TOAST, \ + (snapshotdata).lsn = (l), \ + (snapshotdata).whenTaken = (w)) + +/* This macro encodes the knowledge of which snapshots are MVCC-safe */ +#define IsMVCCSnapshot(snapshot) \ + ((snapshot)->snapshot_type == SNAPSHOT_MVCC || \ + (snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC) + + extern Snapshot GetTransactionSnapshot(void); extern Snapshot GetLatestSnapshot(void); extern void SnapshotSetCommandId(CommandId curcid); @@ -83,6 +121,8 @@ extern void UnregisterSnapshot(Snapshot snapshot); extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner); extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner); +extern FullTransactionId GetFullRecentGlobalXmin(void); + extern void AtSubCommit_Snapshot(int level); extern void AtSubAbort_Snapshot(int level); extern void AtEOXact_Snapshot(bool isCommit, bool resetXmin); @@ -92,12 +132,17 @@ extern bool XactHasExportedSnapshots(void); extern void DeleteAllExportedSnapshotFiles(void); extern bool ThereAreNoPriorRegisteredSnapshots(void); extern TransactionId TransactionIdLimitedForOldSnapshots(TransactionId recentXmin, - Relation relation); + Relation relation); extern void MaintainOldSnapshotTimeMapping(TimestampTz whenTaken, - TransactionId xmin); + TransactionId xmin); extern char *ExportSnapshot(Snapshot snapshot); +/* + * Utility functions for implementing visibility routines in table AMs. + */ +extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); + /* Support for catalog timetravel for logical decoding */ struct HTAB; extern struct HTAB *HistoricSnapshotGetTupleCids(void); diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h index a8a5a8f4c07..c00f1fe9085 100644 --- a/src/include/utils/snapshot.h +++ b/src/include/utils/snapshot.h @@ -3,7 +3,7 @@ * snapshot.h * POSTGRES snapshot definition * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/snapshot.h @@ -20,19 +20,108 @@ #include "storage/buf.h" +/* + * The different snapshot types. We use SnapshotData structures to represent + * both "regular" (MVCC) snapshots and "special" snapshots that have non-MVCC + * semantics. The specific semantics of a snapshot are encoded by its type. + * + * The behaviour of each type of snapshot should be documented alongside its + * enum value, best in terms that are not specific to an individual table AM. + * + * The reason the snapshot type rather than a callback as it used to be is + * that that allows to use the same snapshot for different table AMs without + * having one callback per AM. + */ +typedef enum SnapshotType +{ + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid for the given MVCC snapshot. + * + * Here, we consider the effects of: + * - all transactions committed as of the time of the given snapshot + * - previous commands of this transaction + * + * Does _not_ include: + * - transactions shown as in-progress by the snapshot + * - transactions started after the snapshot was taken + * - changes made by the current command + * ------------------------------------------------------------------------- + */ + SNAPSHOT_MVCC = 0, + + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid "for itself". + * + * Here, we consider the effects of: + * - all committed transactions (as of the current instant) + * - previous commands of this transaction + * - changes made by the current command + * + * Does _not_ include: + * - in-progress transactions (as of the current instant) + * ------------------------------------------------------------------------- + */ + SNAPSHOT_SELF, + + /* + * Any tuple is visible. + */ + SNAPSHOT_ANY, + + /* + * A tuple is visible iff the tuple is valid as a TOAST row. + */ + SNAPSHOT_TOAST, + + /*------------------------------------------------------------------------- + * A tuple is visible iff the tuple is valid including effects of open + * transactions. + * + * Here, we consider the effects of: + * - all committed and in-progress transactions (as of the current instant) + * - previous commands of this transaction + * - changes made by the current command + * + * This is essentially like SNAPSHOT_SELF as far as effects of the current + * transaction and committed/aborted xacts are concerned. However, it + * also includes the effects of other xacts still in progress. + * + * A special hack is that when a snapshot of this type is used to + * determine tuple visibility, the passed-in snapshot struct is used as an + * output argument to return the xids of concurrent xacts that affected + * the tuple. snapshot->xmin is set to the tuple's xmin if that is + * another transaction that's still in progress; or to + * InvalidTransactionId if the tuple's xmin is committed good, committed + * dead, or my own xact. Similarly for snapshot->xmax and the tuple's + * xmax. If the tuple was inserted speculatively, meaning that the + * inserter might still back down on the insertion without aborting the + * whole transaction, the associated token is also returned in + * snapshot->speculativeToken. See also InitDirtySnapshot(). + * ------------------------------------------------------------------------- + */ + SNAPSHOT_DIRTY, + + /* + * A tuple is visible iff it follows the rules of SNAPSHOT_MVCC, but + * supports being called in timetravel context (for decoding catalog + * contents in the context of logical decoding). + */ + SNAPSHOT_HISTORIC_MVCC, + + /* + * A tuple is visible iff the tuple might be visible to some transaction; + * false if it's surely dead to everyone, i.e., vacuumable. + * + * For visibility checks snapshot->min must have been set up with the xmin + * horizon to use. + */ + SNAPSHOT_NON_VACUUMABLE +} SnapshotType; + typedef struct SnapshotData *Snapshot; #define InvalidSnapshot ((Snapshot) NULL) -/* - * We use SnapshotData structures to represent both "regular" (MVCC) - * snapshots and "special" snapshots that have non-MVCC semantics. - * The specific semantics of a snapshot are encoded by the "satisfies" - * function. - */ -typedef bool (*SnapshotSatisfiesFunc) (HeapTuple htup, - Snapshot snapshot, Buffer buffer); - /* * Struct representing all kind of possible snapshots. * @@ -52,7 +141,7 @@ typedef bool (*SnapshotSatisfiesFunc) (HeapTuple htup, */ typedef struct SnapshotData { - SnapshotSatisfiesFunc satisfies; /* tuple test function */ + SnapshotType snapshot_type; /* type of snapshot */ /* * The remaining fields are used only for MVCC snapshots, and are normally @@ -114,18 +203,4 @@ typedef struct SnapshotData XLogRecPtr lsn; /* position in the WAL stream when taken */ } SnapshotData; -/* - * Result codes for HeapTupleSatisfiesUpdate. This should really be in - * tqual.h, but we want to avoid including that file elsewhere. - */ -typedef enum -{ - HeapTupleMayBeUpdated, - HeapTupleInvisible, - HeapTupleSelfUpdated, - HeapTupleUpdated, - HeapTupleBeingUpdated, - HeapTupleWouldBlock /* can be returned by heap_tuple_lock */ -} HTSU_Result; - #endif /* SNAPSHOT_H */ diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h index 53b692e9a29..997b7900a7e 100644 --- a/src/include/utils/sortsupport.h +++ b/src/include/utils/sortsupport.h @@ -42,7 +42,7 @@ * function for such cases, but probably not any other acceleration method. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/sortsupport.h @@ -96,8 +96,7 @@ typedef struct SortSupportData * Comparator function has the same API as the traditional btree * comparison function, ie, return <0, 0, or >0 according as x is less * than, equal to, or greater than y. Note that x and y are guaranteed - * not null, and there is no way to return null either. Do not return - * INT_MIN, as callers are allowed to negate the result before using it. + * not null, and there is no way to return null either. * * This may be either the authoritative comparator, or the abbreviated * comparator. Core code may switch this over the initial preference of @@ -185,8 +184,8 @@ typedef struct SortSupportData /* * Full, authoritative comparator for key that an abbreviated * representation was generated for, used when an abbreviated comparison - * was inconclusive (by calling ApplySortComparatorFull()), or used to - * replace "comparator" when core system ultimately decides against + * was inconclusive (by calling ApplySortAbbrevFullComparator()), or used + * to replace "comparator" when core system ultimately decides against * abbreviation. */ int (*abbrev_full_comparator) (Datum x, Datum y, SortSupport ssup); @@ -224,7 +223,7 @@ ApplySortComparator(Datum datum1, bool isNull1, { compare = ssup->comparator(datum1, datum2, ssup); if (ssup->ssup_reverse) - compare = -compare; + INVERT_COMPARE_RESULT(compare); } return compare; @@ -262,7 +261,7 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, { compare = ssup->abbrev_full_comparator(datum1, datum2, ssup); if (ssup->ssup_reverse) - compare = -compare; + INVERT_COMPARE_RESULT(compare); } return compare; @@ -272,6 +271,6 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup); extern void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup); extern void PrepareSortSupportFromIndexRel(Relation indexRel, int16 strategy, - SortSupport ssup); + SortSupport ssup); #endif /* SORTSUPPORT_H */ diff --git a/src/include/utils/spccache.h b/src/include/utils/spccache.h index 2f30c982b25..5f7aa6b9011 100644 --- a/src/include/utils/spccache.h +++ b/src/include/utils/spccache.h @@ -3,7 +3,7 @@ * spccache.h * Tablespace cache. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/spccache.h @@ -13,8 +13,8 @@ #ifndef SPCCACHE_H #define SPCCACHE_H -void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost, - float8 *spc_seq_page_cost); +void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost, + float8 *spc_seq_page_cost); int get_tablespace_io_concurrency(Oid spcid); #endif /* SPCCACHE_H */ diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h index 4f333586ee9..918765cc993 100644 --- a/src/include/utils/syscache.h +++ b/src/include/utils/syscache.h @@ -6,7 +6,7 @@ * See also lsyscache.h, which provides convenience routines for * common cache-lookup operations. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/syscache.h @@ -86,6 +86,7 @@ enum SysCacheIdentifier REPLORIGNAME, RULERELNAME, SEQRELID, + STATEXTDATASTXOID, STATEXTNAMENSP, STATEXTOID, STATRELATTINH, @@ -116,30 +117,30 @@ extern void InitCatalogCache(void); extern void InitCatalogCachePhase2(void); extern HeapTuple SearchSysCache(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); + Datum key1, Datum key2, Datum key3, Datum key4); /* * The use of argument specific numbers is encouraged. They're faster, and * insulates the caller from changes in the maximum number of keys. */ extern HeapTuple SearchSysCache1(int cacheId, - Datum key1); + Datum key1); extern HeapTuple SearchSysCache2(int cacheId, - Datum key1, Datum key2); + Datum key1, Datum key2); extern HeapTuple SearchSysCache3(int cacheId, - Datum key1, Datum key2, Datum key3); + Datum key1, Datum key2, Datum key3); extern HeapTuple SearchSysCache4(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); + Datum key1, Datum key2, Datum key3, Datum key4); extern void ReleaseSysCache(HeapTuple tuple); /* convenience routines */ extern HeapTuple SearchSysCacheCopy(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); + Datum key1, Datum key2, Datum key3, Datum key4); extern bool SearchSysCacheExists(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); -extern Oid GetSysCacheOid(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); + Datum key1, Datum key2, Datum key3, Datum key4); +extern Oid GetSysCacheOid(int cacheId, AttrNumber oidcol, + Datum key1, Datum key2, Datum key3, Datum key4); extern HeapTuple SearchSysCacheAttName(Oid relid, const char *attname); extern HeapTuple SearchSysCacheCopyAttName(Oid relid, const char *attname); @@ -149,15 +150,15 @@ extern HeapTuple SearchSysCacheAttNum(Oid relid, int16 attnum); extern HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum); extern Datum SysCacheGetAttr(int cacheId, HeapTuple tup, - AttrNumber attributeNumber, bool *isNull); + AttrNumber attributeNumber, bool *isNull); extern uint32 GetSysCacheHashValue(int cacheId, - Datum key1, Datum key2, Datum key3, Datum key4); + Datum key1, Datum key2, Datum key3, Datum key4); /* list-search interface. Users of this must import catcache.h too */ struct catclist; extern struct catclist *SearchSysCacheList(int cacheId, int nkeys, - Datum key1, Datum key2, Datum key3); + Datum key1, Datum key2, Datum key3); extern void SysCacheInvalidate(int cacheId, uint32 hashValue); @@ -188,14 +189,14 @@ extern bool RelationSupportsSysCache(Oid relid); #define SearchSysCacheExists4(cacheId, key1, key2, key3, key4) \ SearchSysCacheExists(cacheId, key1, key2, key3, key4) -#define GetSysCacheOid1(cacheId, key1) \ - GetSysCacheOid(cacheId, key1, 0, 0, 0) -#define GetSysCacheOid2(cacheId, key1, key2) \ - GetSysCacheOid(cacheId, key1, key2, 0, 0) -#define GetSysCacheOid3(cacheId, key1, key2, key3) \ - GetSysCacheOid(cacheId, key1, key2, key3, 0) -#define GetSysCacheOid4(cacheId, key1, key2, key3, key4) \ - GetSysCacheOid(cacheId, key1, key2, key3, key4) +#define GetSysCacheOid1(cacheId, oidcol, key1) \ + GetSysCacheOid(cacheId, oidcol, key1, 0, 0, 0) +#define GetSysCacheOid2(cacheId, oidcol, key1, key2) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, 0, 0) +#define GetSysCacheOid3(cacheId, oidcol, key1, key2, key3) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, key3, 0) +#define GetSysCacheOid4(cacheId, oidcol, key1, key2, key3, key4) \ + GetSysCacheOid(cacheId, oidcol, key1, key2, key3, key4) #define GetSysCacheHashValue1(cacheId, key1) \ GetSysCacheHashValue(cacheId, key1, 0, 0, 0) diff --git a/src/include/utils/timeout.h b/src/include/utils/timeout.h index dcc7307c169..9244a2a7b75 100644 --- a/src/include/utils/timeout.h +++ b/src/include/utils/timeout.h @@ -4,7 +4,7 @@ * Routines to multiplex SIGALRM interrupts for multiple timeout reasons. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/timeout.h diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 2b3b35703e0..e884d4405f5 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -3,7 +3,7 @@ * timestamp.h * Definitions for the SQL "timestamp" and "interval" types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/timestamp.h @@ -71,10 +71,10 @@ extern TimestampTz GetCurrentTimestamp(void); extern TimestampTz GetSQLCurrentTimestamp(int32 typmod); extern Timestamp GetSQLLocalTimestamp(int32 typmod); extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, - long *secs, int *microsecs); + long *secs, int *microsecs); extern bool TimestampDifferenceExceeds(TimestampTz start_time, - TimestampTz stop_time, - int msec); + TimestampTz stop_time, + int msec); extern TimestampTz time_t_to_timestamptz(pg_time_t tm); extern pg_time_t timestamptz_to_time_t(TimestampTz t); @@ -82,8 +82,8 @@ extern pg_time_t timestamptz_to_time_t(TimestampTz t); extern const char *timestamptz_to_str(TimestampTz t); extern int tm2timestamp(struct pg_tm *tm, fsec_t fsec, int *tzp, Timestamp *dt); -extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, - fsec_t *fsec, const char **tzn, pg_tz *attimezone); +extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, + fsec_t *fsec, const char **tzn, pg_tz *attimezone); extern void dt2time(Timestamp dt, int *hour, int *min, int *sec, fsec_t *fsec); extern int interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec); @@ -97,6 +97,9 @@ extern int timestamp_cmp_internal(Timestamp dt1, Timestamp dt2); /* timestamp comparison works for timestamptz also */ #define timestamptz_cmp_internal(dt1,dt2) timestamp_cmp_internal(dt1, dt2) +extern TimestampTz timestamp2timestamptz_opt_error(Timestamp timestamp, + bool *have_error); + extern int isoweek2j(int year, int week); extern void isoweek2date(int woy, int *year, int *mon, int *mday); extern void isoweekdate2date(int isoweek, int wday, int *year, int *mon, int *mday); @@ -104,4 +107,6 @@ extern int date2isoweek(int year, int mon, int mday); extern int date2isoyear(int year, int mon, int mday); extern int date2isoyearday(int year, int mon, int mday); +extern bool TimestampTimestampTzRequiresRewrite(void); + #endif /* TIMESTAMP_H */ diff --git a/src/include/utils/tqual.h b/src/include/utils/tqual.h deleted file mode 100644 index d3b6e99bb4f..00000000000 --- a/src/include/utils/tqual.h +++ /dev/null @@ -1,123 +0,0 @@ -/*------------------------------------------------------------------------- - * - * tqual.h - * POSTGRES "time qualification" definitions, ie, tuple visibility rules. - * - * Should be moved/renamed... - vadim 07/28/98 - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/tqual.h - * - *------------------------------------------------------------------------- - */ -#ifndef TQUAL_H -#define TQUAL_H - -#include "utils/snapshot.h" -#include "access/xlogdefs.h" - - -/* Static variables representing various special snapshot semantics */ -extern PGDLLIMPORT SnapshotData SnapshotSelfData; -extern PGDLLIMPORT SnapshotData SnapshotAnyData; -extern PGDLLIMPORT SnapshotData CatalogSnapshotData; - -#define SnapshotSelf (&SnapshotSelfData) -#define SnapshotAny (&SnapshotAnyData) - -/* This macro encodes the knowledge of which snapshots are MVCC-safe */ -#define IsMVCCSnapshot(snapshot) \ - ((snapshot)->satisfies == HeapTupleSatisfiesMVCC || \ - (snapshot)->satisfies == HeapTupleSatisfiesHistoricMVCC) - -/* - * HeapTupleSatisfiesVisibility - * True iff heap tuple satisfies a time qual. - * - * Notes: - * Assumes heap tuple is valid. - * Beware of multiple evaluations of snapshot argument. - * Hint bits in the HeapTuple's t_infomask may be updated as a side effect; - * if so, the indicated buffer is marked dirty. - */ -#define HeapTupleSatisfiesVisibility(tuple, snapshot, buffer) \ - ((*(snapshot)->satisfies) (tuple, snapshot, buffer)) - -/* Result codes for HeapTupleSatisfiesVacuum */ -typedef enum -{ - HEAPTUPLE_DEAD, /* tuple is dead and deletable */ - HEAPTUPLE_LIVE, /* tuple is live (committed, no deleter) */ - HEAPTUPLE_RECENTLY_DEAD, /* tuple is dead, but not deletable yet */ - HEAPTUPLE_INSERT_IN_PROGRESS, /* inserting xact is still in progress */ - HEAPTUPLE_DELETE_IN_PROGRESS /* deleting xact is still in progress */ -} HTSV_Result; - -/* These are the "satisfies" test routines for the various snapshot types */ -extern bool HeapTupleSatisfiesMVCC(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesSelf(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesAny(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesToast(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesDirty(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesNonVacuumable(HeapTuple htup, - Snapshot snapshot, Buffer buffer); -extern bool HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, - Snapshot snapshot, Buffer buffer); - -/* Special "satisfies" routines with different APIs */ -extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTuple htup, - CommandId curcid, Buffer buffer); -extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTuple htup, - TransactionId OldestXmin, Buffer buffer); -extern bool HeapTupleIsSurelyDead(HeapTuple htup, - TransactionId OldestXmin); -extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); - -extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer, - uint16 infomask, TransactionId xid); -extern bool HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple); - -/* - * To avoid leaking too much knowledge about reorderbuffer implementation - * details this is implemented in reorderbuffer.c not tqual.c. - */ -struct HTAB; -extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data, - Snapshot snapshot, - HeapTuple htup, - Buffer buffer, - CommandId *cmin, CommandId *cmax); - -/* - * We don't provide a static SnapshotDirty variable because it would be - * non-reentrant. Instead, users of that snapshot type should declare a - * local variable of type SnapshotData, and initialize it with this macro. - */ -#define InitDirtySnapshot(snapshotdata) \ - ((snapshotdata).satisfies = HeapTupleSatisfiesDirty) - -/* - * Similarly, some initialization is required for a NonVacuumable snapshot. - * The caller must supply the xmin horizon to use (e.g., RecentGlobalXmin). - */ -#define InitNonVacuumableSnapshot(snapshotdata, xmin_horizon) \ - ((snapshotdata).satisfies = HeapTupleSatisfiesNonVacuumable, \ - (snapshotdata).xmin = (xmin_horizon)) - -/* - * Similarly, some initialization is required for SnapshotToast. We need - * to set lsn and whenTaken correctly to support snapshot_too_old. - */ -#define InitToastSnapshot(snapshotdata, l, w) \ - ((snapshotdata).satisfies = HeapTupleSatisfiesToast, \ - (snapshotdata).lsn = (l), \ - (snapshotdata).whenTaken = (w)) - -#endif /* TQUAL_H */ diff --git a/src/include/utils/tuplesort.h b/src/include/utils/tuplesort.h index d2e6754f043..d774bc1152f 100644 --- a/src/include/utils/tuplesort.h +++ b/src/include/utils/tuplesort.h @@ -11,7 +11,7 @@ * algorithm. Parallel sorts use a variant of this external sort * algorithm, and are typically only used for large amounts of data. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tuplesort.h @@ -23,7 +23,6 @@ #include "access/itup.h" #include "executor/tuptable.h" -#include "fmgr.h" #include "storage/dsm.h" #include "utils/relcache.h" @@ -54,7 +53,7 @@ typedef struct SortCoordinateData /* Private opaque state (points to shared memory) */ Sharedsort *sharedsort; -} SortCoordinateData; +} SortCoordinateData; typedef struct SortCoordinateData *SortCoordinate; @@ -189,59 +188,59 @@ typedef struct TuplesortInstrumentation */ extern Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc, - int nkeys, AttrNumber *attNums, - Oid *sortOperators, Oid *sortCollations, - bool *nullsFirstFlags, - int workMem, SortCoordinate coordinate, - bool randomAccess); + int nkeys, AttrNumber *attNums, + Oid *sortOperators, Oid *sortCollations, + bool *nullsFirstFlags, + int workMem, SortCoordinate coordinate, + bool randomAccess); extern Tuplesortstate *tuplesort_begin_cluster(TupleDesc tupDesc, - Relation indexRel, int workMem, - SortCoordinate coordinate, bool randomAccess); + Relation indexRel, int workMem, + SortCoordinate coordinate, bool randomAccess); extern Tuplesortstate *tuplesort_begin_index_btree(Relation heapRel, - Relation indexRel, - bool enforceUnique, - int workMem, SortCoordinate coordinate, - bool randomAccess); + Relation indexRel, + bool enforceUnique, + int workMem, SortCoordinate coordinate, + bool randomAccess); extern Tuplesortstate *tuplesort_begin_index_hash(Relation heapRel, - Relation indexRel, - uint32 high_mask, - uint32 low_mask, - uint32 max_buckets, - int workMem, SortCoordinate coordinate, - bool randomAccess); + Relation indexRel, + uint32 high_mask, + uint32 low_mask, + uint32 max_buckets, + int workMem, SortCoordinate coordinate, + bool randomAccess); extern Tuplesortstate *tuplesort_begin_datum(Oid datumType, - Oid sortOperator, Oid sortCollation, - bool nullsFirstFlag, - int workMem, SortCoordinate coordinate, - bool randomAccess); + Oid sortOperator, Oid sortCollation, + bool nullsFirstFlag, + int workMem, SortCoordinate coordinate, + bool randomAccess); extern void tuplesort_set_bound(Tuplesortstate *state, int64 bound); extern void tuplesort_puttupleslot(Tuplesortstate *state, - TupleTableSlot *slot); + TupleTableSlot *slot); extern void tuplesort_putheaptuple(Tuplesortstate *state, HeapTuple tup); extern void tuplesort_putindextuplevalues(Tuplesortstate *state, - Relation rel, ItemPointer self, - Datum *values, bool *isnull); + Relation rel, ItemPointer self, + Datum *values, bool *isnull); extern void tuplesort_putdatum(Tuplesortstate *state, Datum val, - bool isNull); + bool isNull); extern void tuplesort_performsort(Tuplesortstate *state); extern bool tuplesort_gettupleslot(Tuplesortstate *state, bool forward, - bool copy, TupleTableSlot *slot, Datum *abbrev); + bool copy, TupleTableSlot *slot, Datum *abbrev); extern HeapTuple tuplesort_getheaptuple(Tuplesortstate *state, bool forward); extern IndexTuple tuplesort_getindextuple(Tuplesortstate *state, bool forward); extern bool tuplesort_getdatum(Tuplesortstate *state, bool forward, - Datum *val, bool *isNull, Datum *abbrev); + Datum *val, bool *isNull, Datum *abbrev); extern bool tuplesort_skiptuples(Tuplesortstate *state, int64 ntuples, - bool forward); + bool forward); extern void tuplesort_end(Tuplesortstate *state); extern void tuplesort_get_stats(Tuplesortstate *state, - TuplesortInstrumentation *stats); + TuplesortInstrumentation *stats); extern const char *tuplesort_method_name(TuplesortMethod m); extern const char *tuplesort_space_type_name(TuplesortSpaceType t); @@ -249,7 +248,7 @@ extern int tuplesort_merge_order(int64 allowedMem); extern Size tuplesort_estimate_shared(int nworkers); extern void tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, - dsm_segment *seg); + dsm_segment *seg); extern void tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg); /* diff --git a/src/include/utils/tuplestore.h b/src/include/utils/tuplestore.h index 2c0c3f82194..f9b6fcec29e 100644 --- a/src/include/utils/tuplestore.h +++ b/src/include/utils/tuplestore.h @@ -21,7 +21,7 @@ * Also, we have changed the API to return tuples in TupleTableSlots, * so that there is a check to prevent attempted access to system columns. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tuplestore.h @@ -45,16 +45,16 @@ typedef struct Tuplestorestate Tuplestorestate; */ extern Tuplestorestate *tuplestore_begin_heap(bool randomAccess, - bool interXact, - int maxKBytes); + bool interXact, + int maxKBytes); extern void tuplestore_set_eflags(Tuplestorestate *state, int eflags); extern void tuplestore_puttupleslot(Tuplestorestate *state, - TupleTableSlot *slot); + TupleTableSlot *slot); extern void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple); extern void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, - Datum *values, bool *isnull); + Datum *values, bool *isnull); /* tuplestore_donestoring() used to be required, but is no longer used */ #define tuplestore_donestoring(state) ((void) 0) @@ -64,19 +64,19 @@ extern int tuplestore_alloc_read_pointer(Tuplestorestate *state, int eflags); extern void tuplestore_select_read_pointer(Tuplestorestate *state, int ptr); extern void tuplestore_copy_read_pointer(Tuplestorestate *state, - int srcptr, int destptr); + int srcptr, int destptr); extern void tuplestore_trim(Tuplestorestate *state); extern bool tuplestore_in_memory(Tuplestorestate *state); extern bool tuplestore_gettupleslot(Tuplestorestate *state, bool forward, - bool copy, TupleTableSlot *slot); + bool copy, TupleTableSlot *slot); extern bool tuplestore_advance(Tuplestorestate *state, bool forward); extern bool tuplestore_skiptuples(Tuplestorestate *state, - int64 ntuples, bool forward); + int64 ntuples, bool forward); extern int64 tuplestore_tuple_count(Tuplestorestate *state); diff --git a/src/include/utils/typcache.h b/src/include/utils/typcache.h index 217d064da52..04bf28180df 100644 --- a/src/include/utils/typcache.h +++ b/src/include/utils/typcache.h @@ -6,7 +6,7 @@ * The type cache exists to speed lookup of certain information about data * types that is not directly available from a type's pg_type row. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/typcache.h @@ -41,6 +41,7 @@ typedef struct TypeCacheEntry char typtype; Oid typrelid; Oid typelem; + Oid typcollation; /* * Information obtained from opfamily entries @@ -167,7 +168,7 @@ typedef struct SharedRecordTypmodRegistry SharedRecordTypmodRegistry; extern TypeCacheEntry *lookup_type_cache(Oid type_id, int flags); extern void InitDomainConstraintRef(Oid type_id, DomainConstraintRef *ref, - MemoryContext refctx, bool need_exprstate); + MemoryContext refctx, bool need_exprstate); extern void UpdateDomainConstraintRef(DomainConstraintRef *ref); @@ -176,12 +177,12 @@ extern bool DomainHasConstraints(Oid type_id); extern TupleDesc lookup_rowtype_tupdesc(Oid type_id, int32 typmod); extern TupleDesc lookup_rowtype_tupdesc_noerror(Oid type_id, int32 typmod, - bool noError); + bool noError); extern TupleDesc lookup_rowtype_tupdesc_copy(Oid type_id, int32 typmod); extern TupleDesc lookup_rowtype_tupdesc_domain(Oid type_id, int32 typmod, - bool noError); + bool noError); extern void assign_record_type_typmod(TupleDesc tupDesc); @@ -192,7 +193,7 @@ extern int compare_values_of_enum(TypeCacheEntry *tcache, Oid arg1, Oid arg2); extern size_t SharedRecordTypmodRegistryEstimate(void); extern void SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *, - dsm_segment *segment, dsa_area *area); + dsm_segment *segment, dsa_area *area); extern void SharedRecordTypmodRegistryAttach(SharedRecordTypmodRegistry *); diff --git a/src/include/utils/tzparser.h b/src/include/utils/tzparser.h index 5a16d121035..3de618498f9 100644 --- a/src/include/utils/tzparser.h +++ b/src/include/utils/tzparser.h @@ -3,7 +3,7 @@ * tzparser.h * Timezone offset file parsing definitions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/tzparser.h diff --git a/src/include/utils/uuid.h b/src/include/utils/uuid.h index 312c8c48c64..5b33ea280d7 100644 --- a/src/include/utils/uuid.h +++ b/src/include/utils/uuid.h @@ -5,7 +5,7 @@ * to avoid conflicts with any uuid_t type that might be defined by * the system headers. * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * src/include/utils/uuid.h * diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h index 3278cb5461b..e947de55be4 100644 --- a/src/include/utils/varbit.h +++ b/src/include/utils/varbit.h @@ -5,7 +5,7 @@ * * Code originally contributed by Adriaan Joubert. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/varbit.h @@ -21,6 +21,11 @@ /* * Modeled on struct varlena from postgres.h, but data type is bits8. + * + * Caution: if bit_len is not a multiple of BITS_PER_BYTE, the low-order + * bits of the last byte of bit_dat[] are unused and MUST be zeroes. + * (This allows bit_cmp() to not bother masking the last byte.) + * Also, there should not be any excess bytes counted in the header length. */ typedef struct { diff --git a/src/include/utils/varlena.h b/src/include/utils/varlena.h index 90e131a3a04..2bad1dfc821 100644 --- a/src/include/utils/varlena.h +++ b/src/include/utils/varlena.h @@ -3,7 +3,7 @@ * varlena.h * Functions for the variable-length built-in types. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/varlena.h @@ -17,21 +17,23 @@ #include "utils/sortsupport.h" extern int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid); -extern void varstr_sortsupport(SortSupport ssup, Oid collid, bool bpchar); -extern int varstr_levenshtein(const char *source, int slen, - const char *target, int tlen, - int ins_c, int del_c, int sub_c, - bool trusted); -extern int varstr_levenshtein_less_equal(const char *source, int slen, - const char *target, int tlen, - int ins_c, int del_c, int sub_c, - int max_d, bool trusted); +extern void varstr_sortsupport(SortSupport ssup, Oid typid, Oid collid); +extern int varstr_levenshtein(const char *source, int slen, + const char *target, int tlen, + int ins_c, int del_c, int sub_c, + bool trusted); +extern int varstr_levenshtein_less_equal(const char *source, int slen, + const char *target, int tlen, + int ins_c, int del_c, int sub_c, + int max_d, bool trusted); extern List *textToQualifiedNameList(text *textval); extern bool SplitIdentifierString(char *rawstring, char separator, - List **namelist); + List **namelist); extern bool SplitDirectoriesString(char *rawstring, char separator, - List **namelist); + List **namelist); +extern bool SplitGUCList(char *rawstring, char separator, + List **namelist); extern text *replace_text_regexp(text *src_text, void *regexp, - text *replace_text, bool glob); + text *replace_text, bool glob); #endif diff --git a/src/include/utils/xml.h b/src/include/utils/xml.h index fe488da42ec..90d08b1fcf2 100644 --- a/src/include/utils/xml.h +++ b/src/include/utils/xml.h @@ -4,7 +4,7 @@ * Declarations for XML data type support. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/utils/xml.h @@ -58,12 +58,12 @@ extern PgXmlErrorContext *pg_xml_init(PgXmlStrictness strictness); extern void pg_xml_done(PgXmlErrorContext *errcxt, bool isError); extern bool pg_xml_error_occurred(PgXmlErrorContext *errcxt); extern void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, - const char *msg); + const char *msg); extern xmltype *xmlconcat(List *args); extern xmltype *xmlelement(XmlExpr *xexpr, - Datum *named_argvalue, bool *named_argnull, - Datum *argvalue, bool *argnull); + Datum *named_argvalue, bool *named_argnull, + Datum *argvalue, bool *argnull); extern xmltype *xmlparse(text *data, XmlOptionType xmloption, bool preserve_whitespace); extern xmltype *xmlpi(const char *target, text *arg, bool arg_is_null, bool *result_is_null); extern xmltype *xmlroot(xmltype *data, text *version, int standalone); diff --git a/src/include/windowapi.h b/src/include/windowapi.h index f6f18e5159b..b86730043c4 100644 --- a/src/include/windowapi.h +++ b/src/include/windowapi.h @@ -19,7 +19,7 @@ * function in nodeWindowAgg.c for details. * * - * Portions Copyright (c) 2000-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2000-2019, PostgreSQL Global Development Group * * src/include/windowapi.h * @@ -51,14 +51,14 @@ extern void WinSetMarkPosition(WindowObject winobj, int64 markpos); extern bool WinRowsArePeers(WindowObject winobj, int64 pos1, int64 pos2); extern Datum WinGetFuncArgInPartition(WindowObject winobj, int argno, - int relpos, int seektype, bool set_mark, - bool *isnull, bool *isout); + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout); extern Datum WinGetFuncArgInFrame(WindowObject winobj, int argno, - int relpos, int seektype, bool set_mark, - bool *isnull, bool *isout); + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout); extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno, - bool *isnull); + bool *isnull); #endif /* WINDOWAPI_H */ diff --git a/src/interfaces/ecpg/compatlib/.gitignore b/src/interfaces/ecpg/compatlib/.gitignore index ad5ba1354ca..926385c6b97 100644 --- a/src/interfaces/ecpg/compatlib/.gitignore +++ b/src/interfaces/ecpg/compatlib/.gitignore @@ -1,5 +1,3 @@ /compatlib.def /blibecpg_compatdll.def /exports.list -/snprintf.c -/strnlen.c diff --git a/src/interfaces/ecpg/compatlib/Makefile b/src/interfaces/ecpg/compatlib/Makefile index ebfd89544aa..cd9879ba75a 100644 --- a/src/interfaces/ecpg/compatlib/Makefile +++ b/src/interfaces/ecpg/compatlib/Makefile @@ -2,7 +2,7 @@ # # Makefile for ecpg compatibility library # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/interfaces/ecpg/compatlib/Makefile @@ -22,16 +22,13 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ -I$(libpq_srcdir) -DFRONTEND $(CPPFLAGS) override CFLAGS += $(PTHREAD_CFLAGS) -SHLIB_LINK_INTERNAL = -L../ecpglib -lecpg -L../pgtypeslib -lpgtypes $(libpq) +SHLIB_LINK_INTERNAL = -L../ecpglib -lecpg -L../pgtypeslib -lpgtypes $(libpq_pgport_shlib) SHLIB_LINK = $(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS) SHLIB_PREREQS = submake-ecpglib submake-pgtypeslib SHLIB_EXPORTS = exports.txt -# Need to recompile any libpgport object files -LIBS := $(filter-out -lpgport, $(LIBS)) - -OBJS= informix.o $(filter snprintf.o strnlen.o, $(LIBOBJS)) $(WIN32RES) +OBJS= informix.o $(WIN32RES) PKG_CONFIG_REQUIRES_PRIVATE = libecpg libpgtypes @@ -48,9 +45,6 @@ submake-pgtypeslib: # Shared library stuff include $(top_srcdir)/src/Makefile.shlib -snprintf.c strnlen.c: % : $(top_srcdir)/src/port/% - rm -f $@ && $(LN_S) $< . - install: all installdirs install-lib installdirs: installdirs-lib @@ -58,6 +52,6 @@ installdirs: installdirs-lib uninstall: uninstall-lib clean distclean: clean-lib - rm -f $(OBJS) snprintf.c strnlen.c + rm -f $(OBJS) maintainer-clean: distclean maintainer-clean-lib diff --git a/src/interfaces/ecpg/compatlib/exports.txt b/src/interfaces/ecpg/compatlib/exports.txt index e0cfd7a22d0..86e9ca16404 100644 --- a/src/interfaces/ecpg/compatlib/exports.txt +++ b/src/interfaces/ecpg/compatlib/exports.txt @@ -1,5 +1,5 @@ # src/interfaces/ecpg/compatlib/exports.txt -# Functions to be exported by ecpg_compatlib DLL +# Functions to be exported by libecpg_compat DLL ECPG_informix_get_var 1 ECPG_informix_set_var 2 decadd 3 diff --git a/src/interfaces/ecpg/compatlib/informix.c b/src/interfaces/ecpg/compatlib/informix.c index 13058cf7bf7..6ef1fadb7fc 100644 --- a/src/interfaces/ecpg/compatlib/informix.c +++ b/src/interfaces/ecpg/compatlib/informix.c @@ -679,11 +679,6 @@ intoasc(interval * i, char *str) return 0; } -/* - * rfmt.c - description - * by Carsten Wolff , Wed Apr 2 2003 - */ - static struct { long val; @@ -745,7 +740,7 @@ initValue(long lng_val) return 0; } -/* return the position oft the right-most dot in some string */ +/* return the position of the right-most dot in some string */ static int getRightMostDot(const char *str) { @@ -811,7 +806,7 @@ rfmtlong(long lng_val, const char *fmt, char *outbuf) /* and fill the temp-string wit '0's up to there. */ dotpos = getRightMostDot(fmt); - /* start to parse the formatstring */ + /* start to parse the format-string */ temp[0] = '\0'; k = value.digits - 1; /* position in the value_string */ for (i = fmt_len - 1, j = 0; i >= 0; i--, j++) diff --git a/src/interfaces/ecpg/ecpglib/.gitignore b/src/interfaces/ecpg/ecpglib/.gitignore index 1619e970c29..f2bf3e7a4a5 100644 --- a/src/interfaces/ecpg/ecpglib/.gitignore +++ b/src/interfaces/ecpg/ecpglib/.gitignore @@ -1,11 +1,3 @@ /ecpglib.def /blibecpgdll.def /exports.list -/path.c -/pgstrcasecmp.c -/snprintf.c -/strlcpy.c -/strnlen.c -/thread.c -/win32setlocale.c -/isinf.c diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile index d25d248616d..8827a17fecb 100644 --- a/src/interfaces/ecpg/ecpglib/Makefile +++ b/src/interfaces/ecpg/ecpglib/Makefile @@ -2,7 +2,7 @@ # # Makefile for ecpg library # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/interfaces/ecpg/ecpglib/Makefile @@ -22,20 +22,10 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ -I$(libpq_srcdir) -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) override CFLAGS += $(PTHREAD_CFLAGS) -# Need to recompile any libpgport object files -LIBS := $(filter-out -lpgport, $(LIBS)) +OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o \ + memory.o connect.o misc.o $(WIN32RES) -OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \ - connect.o misc.o path.o pgstrcasecmp.o \ - $(filter snprintf.o strlcpy.o strnlen.o win32setlocale.o isinf.o, $(LIBOBJS)) \ - $(WIN32RES) - -# thread.c is needed only for non-WIN32 implementation of path.c -ifneq ($(PORTNAME), win32) -OBJS += thread.o -endif - -SHLIB_LINK_INTERNAL = -L../pgtypeslib -lpgtypes $(libpq) +SHLIB_LINK_INTERNAL = -L../pgtypeslib -lpgtypes $(libpq_pgport_shlib) SHLIB_LINK = $(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS) SHLIB_PREREQS = submake-libpq submake-pgtypeslib @@ -52,16 +42,8 @@ submake-pgtypeslib: # Shared library stuff include $(top_srcdir)/src/Makefile.shlib -# We use some port modules verbatim, but since we need to -# compile with appropriate options to build a shared lib, we can't -# necessarily use the same object files as the backend uses. Instead, -# symlink the source files in here and build our own object file. - -path.c pgstrcasecmp.c snprintf.c strlcpy.c strnlen.c thread.c win32setlocale.c isinf.c: % : $(top_srcdir)/src/port/% - rm -f $@ && $(LN_S) $< . - +# Make dependency on pg_config_paths.h visible. misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h -path.o: path.c $(top_builddir)/src/port/pg_config_paths.h $(top_builddir)/src/port/pg_config_paths.h: $(MAKE) -C $(top_builddir)/src/port pg_config_paths.h @@ -74,6 +56,5 @@ uninstall: uninstall-lib clean distclean: clean-lib rm -f $(OBJS) - rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c strnlen.c thread.c win32setlocale.c isinf.c maintainer-clean: distclean maintainer-clean-lib diff --git a/src/interfaces/ecpg/ecpglib/connect.c b/src/interfaces/ecpg/ecpglib/connect.c index 71fa2753638..b4f6089c282 100644 --- a/src/interfaces/ecpg/ecpglib/connect.c +++ b/src/interfaces/ecpg/ecpglib/connect.c @@ -7,7 +7,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #ifdef ENABLE_THREAD_SAFETY @@ -514,9 +514,9 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p options ? "with options " : "", options ? options : "", (user && strlen(user) > 0) ? "for user " : "", user ? user : ""); + /* count options (this may produce an overestimate, it's ok) */ if (options) for (i = 0; options[i]; i++) - /* count options */ if (options[i] == '=') connect_params++; @@ -583,8 +583,12 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p { char *str; - /* options look like this "option1 = value1 option2 = value2 ... */ - /* we have to break up the string into single options */ + /* + * The options string contains "keyword=value" pairs separated by + * '&'s. We must break this up into keywords and values to pass to + * libpq (it's okay to scribble on the options string). We ignore + * spaces just before each keyword or value. + */ for (str = options; *str;) { int e, @@ -592,13 +596,21 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p char *token1, *token2; - for (token1 = str; *token1 && *token1 == ' '; token1++); - for (e = 0; token1[e] && token1[e] != '='; e++); + /* Skip spaces before keyword */ + for (token1 = str; *token1 == ' '; token1++) + /* skip */ ; + /* Find end of keyword */ + for (e = 0; token1[e] && token1[e] != '='; e++) + /* skip */ ; if (token1[e]) /* found "=" */ { token1[e] = '\0'; - for (token2 = token1 + e + 1; *token2 && *token2 == ' '; token2++); - for (a = 0; token2[a] && token2[a] != '&'; a++); + /* Skip spaces before value */ + for (token2 = token1 + e + 1; *token2 == ' '; token2++) + /* skip */ ; + /* Find end of value */ + for (a = 0; token2[a] && token2[a] != '&'; a++) + /* skip */ ; if (token2[a]) /* found "&" => another option follows */ { token2[a] = '\0'; @@ -612,11 +624,14 @@ ECPGconnect(int lineno, int c, const char *name, const char *user, const char *p i++; } else - /* the parser should not be able to create this invalid option */ + { + /* Bogus options syntax ... ignore trailing garbage */ str = token1 + e; + } } - } + + Assert(i <= connect_params); conn_keywords[i] = NULL; /* terminator */ this->connection = PQconnectdbParams(conn_keywords, conn_values, 0); diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index b43b36260ac..81f94cc12b8 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -3,13 +3,12 @@ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" -#include #include #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #include "pgtypes_numeric.h" #include "pgtypes_date.h" @@ -123,6 +122,86 @@ check_special_value(char *ptr, double *retval, char **endptr) return false; } +/* imported from src/backend/utils/adt/encode.c */ + +unsigned +ecpg_hex_enc_len(unsigned srclen) +{ + return srclen << 1; +} + +unsigned +ecpg_hex_dec_len(unsigned srclen) +{ + return srclen >> 1; +} + +static inline char +get_hex(char c) +{ + static const int8 hexlookup[128] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + int res = -1; + + if (c > 0 && c < 127) + res = hexlookup[(unsigned char) c]; + + return (char) res; +} + +static unsigned +hex_decode(const char *src, unsigned len, char *dst) +{ + const char *s, + *srcend; + char v1, + v2, + *p; + + srcend = src + len; + s = src; + p = dst; + while (s < srcend) + { + if (*s == ' ' || *s == '\n' || *s == '\t' || *s == '\r') + { + s++; + continue; + } + v1 = get_hex(*s++) << 4; + if (s >= srcend) + return -1; + + v2 = get_hex(*s++); + *p++ = v1 | v2; + } + + return p - dst; +} + +unsigned +ecpg_hex_encode(const char *src, unsigned len, char *dst) +{ + static const char hextbl[] = "0123456789abcdef"; + const char *end = src + len; + + while (src < end) + { + *dst++ = hextbl[(*src >> 4) & 0xF]; + *dst++ = hextbl[*src & 0xF]; + src++; + } + return len * 2; +} + bool ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, enum ECPGttype type, enum ECPGttype ind_type, @@ -448,6 +527,55 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, return false; break; + case ECPGt_bytea: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var + offset * act_tuple); + long dst_size, + src_size, + dec_size; + + dst_size = ecpg_hex_enc_len(varcharsize); + src_size = size - 2; /* exclude backslash + 'x' */ + dec_size = src_size < dst_size ? src_size : dst_size; + variable->len = hex_decode(pval + 2, dec_size, variable->arr); + + if (dst_size < src_size) + { + long rcv_size = ecpg_hex_dec_len(size - 2); + + /* truncation */ + switch (ind_type) + { + case ECPGt_short: + case ECPGt_unsigned_short: + *((short *) (ind + ind_offset * act_tuple)) = rcv_size; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *((int *) (ind + ind_offset * act_tuple)) = rcv_size; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *((long *) (ind + ind_offset * act_tuple)) = rcv_size; + break; +#ifdef HAVE_LONG_LONG_INT + case ECPGt_long_long: + case ECPGt_unsigned_long_long: + *((long long int *) (ind + ind_offset * act_tuple)) = rcv_size; + break; +#endif /* HAVE_LONG_LONG_INT */ + default: + break; + } + sqlca->sqlwarn[0] = sqlca->sqlwarn[1] = 'W'; + } + + pval += size; + + } + break; + case ECPGt_char: case ECPGt_unsigned_char: case ECPGt_string: @@ -464,15 +592,22 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, if (varcharsize == 0 || varcharsize > size) { - /* compatibility mode, blank pad and null terminate char array */ + /* + * compatibility mode, blank pad and null + * terminate char array + */ if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char)) { memset(str, ' ', varcharsize); memcpy(str, pval, size); - str[varcharsize-1] = '\0'; + str[varcharsize - 1] = '\0'; - /* compatibility mode empty string gets -1 indicator but no warning */ - if (size == 0) { + /* + * compatibility mode empty string gets -1 + * indicator but no warning + */ + if (size == 0) + { /* truncation */ switch (ind_type) { @@ -488,12 +623,12 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, case ECPGt_unsigned_long: *((long *) (ind + ind_offset * act_tuple)) = -1; break; - #ifdef HAVE_LONG_LONG_INT +#ifdef HAVE_LONG_LONG_INT case ECPGt_long_long: case ECPGt_unsigned_long_long: *((long long int *) (ind + ind_offset * act_tuple)) = -1; break; - #endif /* HAVE_LONG_LONG_INT */ +#endif /* HAVE_LONG_LONG_INT */ default: break; } @@ -523,7 +658,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, if (ORACLE_MODE(compat) && (varcharsize - 1) < size) { if (type == ECPGt_char || type == ECPGt_unsigned_char) - str[varcharsize-1] = '\0'; + str[varcharsize - 1] = '\0'; } if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size)) diff --git a/src/interfaces/ecpg/ecpglib/descriptor.c b/src/interfaces/ecpg/ecpglib/descriptor.c index f38bf343f0b..ef500a915d6 100644 --- a/src/interfaces/ecpg/ecpglib/descriptor.c +++ b/src/interfaces/ecpg/ecpglib/descriptor.c @@ -12,7 +12,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #include "sqlda.h" #include "sql3types.h" @@ -218,7 +218,7 @@ get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int va (struct ECPGgeneric_varchar *) var; if (varcharsize == 0) - strncpy(variable->arr, value, strlen(value)); + memcpy(variable->arr, value, strlen(value)); else strncpy(variable->arr, value, varcharsize); @@ -483,22 +483,45 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...) if (data_var.type != ECPGt_EORT) { struct statement stmt; - char *oldlocale; + + memset(&stmt, 0, sizeof stmt); + stmt.lineno = lineno; /* Make sure we do NOT honor the locale for numeric input */ /* since the database gives the standard decimal point */ - oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); + /* (see comments in execute.c) */ +#ifdef HAVE_USELOCALE + stmt.clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0); + if (stmt.clocale != (locale_t) 0) + stmt.oldlocale = uselocale(stmt.clocale); +#else +#ifdef HAVE__CONFIGTHREADLOCALE + stmt.oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); +#endif + stmt.oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); setlocale(LC_NUMERIC, "C"); - - memset(&stmt, 0, sizeof stmt); - stmt.lineno = lineno; +#endif /* desperate try to guess something sensible */ stmt.connection = ecpg_get_connection(NULL); ecpg_store_result(ECPGresult, index, &stmt, &data_var); - setlocale(LC_NUMERIC, oldlocale); - ecpg_free(oldlocale); +#ifdef HAVE_USELOCALE + if (stmt.oldlocale != (locale_t) 0) + uselocale(stmt.oldlocale); + if (stmt.clocale) + freelocale(stmt.clocale); +#else + if (stmt.oldlocale) + { + setlocale(LC_NUMERIC, stmt.oldlocale); + ecpg_free(stmt.oldlocale); + } +#ifdef HAVE__CONFIGTHREADLOCALE + if (stmt.oldthreadlocale != -1) + (void) _configthreadlocale(stmt.oldthreadlocale); +#endif +#endif } else if (data_var.ind_type != ECPGt_NO_INDICATOR && data_var.ind_pointer != NULL) @@ -564,6 +587,27 @@ ECPGset_desc_header(int lineno, const char *desc_name, int count) return true; } +static void +set_desc_attr(struct descriptor_item *desc_item, struct variable *var, + char *tobeinserted) +{ + if (var->type != ECPGt_bytea) + desc_item->is_binary = false; + + else + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); + + desc_item->is_binary = true; + desc_item->data_len = variable->len; + } + + ecpg_free(desc_item->data); /* free() takes care of a potential NULL value */ + desc_item->data = (char *) tobeinserted; +} + + bool ECPGset_desc(int lineno, const char *desc_name, int index,...) { @@ -643,9 +687,7 @@ ECPGset_desc(int lineno, const char *desc_name, int index,...) return false; } - ecpg_free(desc_item->data); /* free() takes care of a - * potential NULL value */ - desc_item->data = (char *) tobeinserted; + set_desc_attr(desc_item, var, tobeinserted); tobeinserted = NULL; break; } diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h similarity index 80% rename from src/interfaces/ecpg/ecpglib/extern.h rename to src/interfaces/ecpg/ecpglib/ecpglib_extern.h index a88f34106cc..f788bfd1eac 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/ecpglib_extern.h @@ -1,17 +1,21 @@ -/* src/interfaces/ecpg/ecpglib/extern.h */ +/* src/interfaces/ecpg/ecpglib/ecpglib_extern.h */ -#ifndef _ECPG_LIB_EXTERN_H -#define _ECPG_LIB_EXTERN_H +#ifndef _ECPG_ECPGLIB_EXTERN_H +#define _ECPG_ECPGLIB_EXTERN_H #include "libpq-fe.h" #include "sqlca.h" #include "sqlda-native.h" #include "sqlda-compat.h" #include "ecpg_config.h" +#include "ecpgtype.h" #ifndef CHAR_BIT #include #endif +#ifdef LOCALE_T_IN_XLOCALE +#include +#endif enum COMPAT_MODE { @@ -37,6 +41,13 @@ struct ECPGgeneric_varchar char arr[FLEXIBLE_ARRAY_MEMBER]; }; +/* A generic bytea type. */ +struct ECPGgeneric_bytea +{ + int len; + char arr[FLEXIBLE_ARRAY_MEMBER]; +}; + /* * type information cache */ @@ -61,9 +72,19 @@ struct statement bool questionmarks; struct variable *inlist; struct variable *outlist; +#ifdef HAVE_USELOCALE + locale_t clocale; + locale_t oldlocale; +#else char *oldlocale; +#ifdef HAVE__CONFIGTHREADLOCALE + int oldthreadlocale; +#endif +#endif int nparams; char **paramvalues; + int *paramlengths; + int *paramformats; PGresult *results; }; @@ -106,6 +127,8 @@ struct descriptor_item int precision; int scale; int type; + bool is_binary; + int data_len; struct descriptor_item *next; }; @@ -139,9 +162,9 @@ extern struct var_list *ivlist; bool ecpg_add_mem(void *ptr, int lineno); -bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type, - enum ECPGttype, char *, char *, long, long, long, - enum ARRAY_TYPE, enum COMPAT_MODE, bool); +bool ecpg_get_data(const PGresult *, int, int, int, enum ECPGttype type, + enum ECPGttype, char *, char *, long, long, long, + enum ARRAY_TYPE, enum COMPAT_MODE, bool); #ifdef ENABLE_THREAD_SAFETY void ecpg_pthreads_init(void); @@ -156,30 +179,27 @@ char *ecpg_strdup(const char *, int); const char *ecpg_type_name(enum ECPGttype); int ecpg_dynamic_type(Oid); int sqlda_dynamic_type(Oid, enum COMPAT_MODE); -void ecpg_free_auto_mem(void); void ecpg_clear_auto_mem(void); -struct descriptor *ecpggetdescp(int, char *); - struct descriptor *ecpg_find_desc(int line, const char *name); struct prepared_statement *ecpg_find_prepared_statement(const char *, - struct connection *, struct prepared_statement **); + struct connection *, struct prepared_statement **); -bool ecpg_store_result(const PGresult *results, int act_field, - const struct statement *stmt, struct variable *var); +bool ecpg_store_result(const PGresult *results, int act_field, + const struct statement *stmt, struct variable *var); bool ecpg_store_input(const int, const bool, const struct variable *, char **, bool); void ecpg_free_params(struct statement *stmt, bool print); -bool ecpg_do_prologue(int, const int, const int, const char *, const bool, - enum ECPG_statement_type, const char *, va_list, - struct statement **); +bool ecpg_do_prologue(int, const int, const int, const char *, const bool, + enum ECPG_statement_type, const char *, va_list, + struct statement **); bool ecpg_build_params(struct statement *); bool ecpg_autostart_transaction(struct statement *stmt); bool ecpg_execute(struct statement *stmt); bool ecpg_process_output(struct statement *, bool); void ecpg_do_epilogue(struct statement *); -bool ecpg_do(const int, const int, const int, const char *, const bool, - const int, const char *, va_list); +bool ecpg_do(const int, const int, const int, const char *, const bool, + const int, const char *, va_list); bool ecpg_check_PQresult(PGresult *, int, PGconn *, enum COMPAT_MODE); void ecpg_raise(int line, int code, const char *sqlstate, const char *str); @@ -188,12 +208,16 @@ char *ecpg_prepared(const char *, struct connection *); bool ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *conn); void ecpg_log(const char *format,...) pg_attribute_printf(1, 2); bool ecpg_auto_prepare(int, const char *, const int, char **, const char *); +bool ecpg_register_prepared_stmt(struct statement *); void ecpg_init_sqlca(struct sqlca_t *sqlca); struct sqlda_compat *ecpg_build_compat_sqlda(int, PGresult *, int, enum COMPAT_MODE); void ecpg_set_compat_sqlda(int, struct sqlda_compat **, const PGresult *, int, enum COMPAT_MODE); struct sqlda_struct *ecpg_build_native_sqlda(int, PGresult *, int, enum COMPAT_MODE); void ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int, enum COMPAT_MODE); +unsigned ecpg_hex_dec_len(unsigned srclen); +unsigned ecpg_hex_enc_len(unsigned srclen); +unsigned ecpg_hex_encode(const char *src, unsigned len, char *dst); /* SQLSTATE values generated or processed by ecpglib (intentionally * not exported -- users should refer to the codes directly) */ @@ -221,4 +245,4 @@ void ecpg_set_native_sqlda(int, struct sqlda_struct **, const PGresult *, int, #define ECPG_SQLSTATE_ECPG_INTERNAL_ERROR "YE000" #define ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY "YE001" -#endif /* _ECPG_LIB_EXTERN_H */ +#endif /* _ECPG_ECPGLIB_EXTERN_H */ diff --git a/src/interfaces/ecpg/ecpglib/error.c b/src/interfaces/ecpg/ecpglib/error.c index f34ae4afb83..9c56991a1e8 100644 --- a/src/interfaces/ecpg/ecpglib/error.c +++ b/src/interfaces/ecpg/ecpglib/error.c @@ -6,7 +6,7 @@ #include "ecpgerrno.h" #include "ecpgtype.h" #include "ecpglib.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" void diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index c1b44d36f2b..7c9cb760a99 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -16,7 +16,6 @@ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" -#include #include #include "catalog/pg_type_d.h" @@ -24,7 +23,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #include "sqlda-native.h" #include "sqlda-compat.h" @@ -103,7 +102,12 @@ free_statement(struct statement *stmt) free_variable(stmt->outlist); ecpg_free(stmt->command); ecpg_free(stmt->name); +#ifdef HAVE_USELOCALE + if (stmt->clocale) + freelocale(stmt->clocale); +#else ecpg_free(stmt->oldlocale); +#endif ecpg_free(stmt); } @@ -223,12 +227,6 @@ ecpg_is_type_an_array(int type, const struct statement *stmt, const struct varia return ECPG_ARRAY_ERROR; if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), FLOAT8OID, ECPG_ARRAY_NONE, stmt->lineno)) return ECPG_ARRAY_ERROR; - if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), ABSTIMEOID, ECPG_ARRAY_NONE, stmt->lineno)) - return ECPG_ARRAY_ERROR; - if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), RELTIMEOID, ECPG_ARRAY_NONE, stmt->lineno)) - return ECPG_ARRAY_ERROR; - if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), TINTERVALOID, ECPG_ARRAY_NONE, stmt->lineno)) - return ECPG_ARRAY_ERROR; if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), UNKNOWNOID, ECPG_ARRAY_NONE, stmt->lineno)) return ECPG_ARRAY_ERROR; if (!ecpg_type_infocache_push(&(stmt->connection->cache_head), CIRCLEOID, ECPG_ARRAY_NONE, stmt->lineno)) @@ -490,6 +488,24 @@ sprintf_float_value(char *ptr, float value, const char *delim) sprintf(ptr, "%.15g%s", value, delim); } +static char * +convert_bytea_to_string(char *from_data, int from_len, int lineno) +{ + char *to_data; + int to_len = ecpg_hex_enc_len(from_len) + 4 + 1; /* backslash + 'x' + + * quote + quote */ + + to_data = ecpg_alloc(to_len, lineno); + if (!to_data) + return NULL; + + strcpy(to_data, "'\\x"); + ecpg_hex_encode(from_data, from_len, to_data + 3); + strcpy(to_data + 3 + ecpg_hex_enc_len(from_len), "\'"); + + return to_data; +} + bool ecpg_store_input(const int lineno, const bool force_indicator, const struct variable *var, char **tobeinserted_p, bool quote) @@ -806,6 +822,20 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari *tobeinserted_p = mallocedval; } break; + + case ECPGt_bytea: + { + struct ECPGgeneric_varchar *variable = + (struct ECPGgeneric_varchar *) (var->value); + + if (!(mallocedval = (char *) ecpg_alloc(variable->len, lineno))) + return false; + + memcpy(mallocedval, variable->arr, variable->len); + *tobeinserted_p = mallocedval; + } + break; + case ECPGt_varchar: { struct ECPGgeneric_varchar *variable = @@ -1048,6 +1078,36 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari return true; } +static void +print_param_value(char *value, int len, int is_binary, int lineno, int nth) +{ + char *value_s; + bool malloced = false; + + if (value == NULL) + value_s = "null"; + else if (!is_binary) + value_s = value; + else + { + value_s = ecpg_alloc(ecpg_hex_enc_len(len) + 1, lineno); + if (value_s != NULL) + { + ecpg_hex_encode(value, len, value_s); + value_s[ecpg_hex_enc_len(len)] = '\0'; + malloced = true; + } + else + value_s = "no memory for logging of parameter"; + } + + ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", + lineno, nth, value_s); + + if (malloced) + ecpg_free(value_s); +} + void ecpg_free_params(struct statement *stmt, bool print) { @@ -1056,11 +1116,16 @@ ecpg_free_params(struct statement *stmt, bool print) for (n = 0; n < stmt->nparams; n++) { if (print) - ecpg_log("ecpg_free_params on line %d: parameter %d = %s\n", stmt->lineno, n + 1, stmt->paramvalues[n] ? stmt->paramvalues[n] : "null"); + print_param_value(stmt->paramvalues[n], stmt->paramlengths[n], + stmt->paramformats[n], stmt->lineno, n + 1); ecpg_free(stmt->paramvalues[n]); } ecpg_free(stmt->paramvalues); + ecpg_free(stmt->paramlengths); + ecpg_free(stmt->paramformats); stmt->paramvalues = NULL; + stmt->paramlengths = NULL; + stmt->paramformats = NULL; stmt->nparams = 0; } @@ -1092,7 +1157,54 @@ insert_tobeinserted(int position, int ph_len, struct statement *stmt, char *tobe ecpg_free(stmt->command); stmt->command = newcopy; - ecpg_free((char *) tobeinserted); + ecpg_free(tobeinserted); + return true; +} + +static bool +store_input_from_desc(struct statement *stmt, struct descriptor_item *desc_item, + char **tobeinserted) +{ + struct variable var; + + /* + * In case of binary data, only allocate memory and memcpy because binary + * data have been already stored into desc_item->data with + * ecpg_store_input() at ECPGset_desc(). + */ + if (desc_item->is_binary) + { + if (!(*tobeinserted = ecpg_alloc(desc_item->data_len, stmt->lineno))) + return false; + memcpy(*tobeinserted, desc_item->data, desc_item->data_len); + return true; + } + + var.type = ECPGt_char; + var.varcharsize = strlen(desc_item->data); + var.value = desc_item->data; + var.pointer = &(desc_item->data); + var.arrsize = 1; + var.offset = 0; + + if (!desc_item->indicator) + { + var.ind_type = ECPGt_NO_INDICATOR; + var.ind_value = var.ind_pointer = NULL; + var.ind_varcharsize = var.ind_arrsize = var.ind_offset = 0; + } + else + { + var.ind_type = ECPGt_int; + var.ind_value = &(desc_item->indicator); + var.ind_pointer = &(var.ind_value); + var.ind_varcharsize = var.ind_arrsize = 1; + var.ind_offset = 0; + } + + if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &var, tobeinserted, false)) + return false; + return true; } @@ -1127,8 +1239,13 @@ ecpg_build_params(struct statement *stmt) { char *tobeinserted; int counter = 1; + bool binary_format; + int binary_length; + tobeinserted = NULL; + binary_length = 0; + binary_format = false; /* * A descriptor is a special case since it contains many variables but @@ -1140,7 +1257,6 @@ ecpg_build_params(struct statement *stmt) * We create an additional variable list here, so the same logic * applies. */ - struct variable desc_inlist; struct descriptor *desc; struct descriptor_item *desc_item; @@ -1151,33 +1267,18 @@ ecpg_build_params(struct statement *stmt) desc_counter++; for (desc_item = desc->items; desc_item; desc_item = desc_item->next) { - if (desc_item->num == desc_counter) - { - desc_inlist.type = ECPGt_char; - desc_inlist.value = desc_item->data; - desc_inlist.pointer = &(desc_item->data); - desc_inlist.varcharsize = strlen(desc_item->data); - desc_inlist.arrsize = 1; - desc_inlist.offset = 0; - if (!desc_item->indicator) - { - desc_inlist.ind_type = ECPGt_NO_INDICATOR; - desc_inlist.ind_value = desc_inlist.ind_pointer = NULL; - desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0; - } - else - { - desc_inlist.ind_type = ECPGt_int; - desc_inlist.ind_value = &(desc_item->indicator); - desc_inlist.ind_pointer = &(desc_inlist.ind_value); - desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1; - desc_inlist.ind_offset = 0; - } - if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false)) - return false; + if (desc_item->num != desc_counter) + continue; - break; + if (!store_input_from_desc(stmt, desc_item, &tobeinserted)) + return false; + + if (desc_item->is_binary) + { + binary_length = desc_item->data_len; + binary_format = true; } + break; } if (desc->count == desc_counter) desc_counter = 0; @@ -1300,6 +1401,12 @@ ecpg_build_params(struct statement *stmt) { if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false)) return false; + + if (var->type == ECPGt_bytea) + { + binary_length = ((struct ECPGgeneric_varchar *) (var->value))->len; + binary_format = true; + } } /* @@ -1309,13 +1416,14 @@ ecpg_build_params(struct statement *stmt) if ((position = next_insert(stmt->command, position, stmt->questionmarks, std_strings) + 1) == 0) { /* - * We have an argument but we dont have the matched up placeholder - * in the string + * We have an argument but we don't have the matched up + * placeholder in the string */ ecpg_raise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL); ecpg_free_params(stmt, false); + ecpg_free(tobeinserted); return false; } @@ -1343,6 +1451,48 @@ ecpg_build_params(struct statement *stmt) */ else if (stmt->command[position] == '0') { + if (stmt->statement_type == ECPGst_prepare || + stmt->statement_type == ECPGst_exec_with_exprlist) + { + /* Need to double-quote the inserted statement name. */ + char *str = ecpg_alloc(strlen(tobeinserted) + 2 + 1, + stmt->lineno); + + if (!str) + { + ecpg_free(tobeinserted); + ecpg_free_params(stmt, false); + return false; + } + sprintf(str, "\"%s\"", tobeinserted); + ecpg_free(tobeinserted); + tobeinserted = str; + } + + if (!insert_tobeinserted(position, 2, stmt, tobeinserted)) + { + ecpg_free_params(stmt, false); + return false; + } + tobeinserted = NULL; + } + else if (stmt->statement_type == ECPGst_exec_with_exprlist) + { + if (binary_format) + { + char *p = convert_bytea_to_string(tobeinserted, + binary_length, + stmt->lineno); + + ecpg_free(tobeinserted); + if (!p) + { + ecpg_free_params(stmt, false); + return false; + } + tobeinserted = p; + } + if (!insert_tobeinserted(position, 2, stmt, tobeinserted)) { ecpg_free_params(stmt, false); @@ -1352,17 +1502,28 @@ ecpg_build_params(struct statement *stmt) } else { - char **paramvalues; + if (!(stmt->paramvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno))) + { + ecpg_free_params(stmt, false); + ecpg_free(tobeinserted); + return false; + } + stmt->paramvalues[stmt->nparams] = tobeinserted; - if (!(paramvalues = (char **) ecpg_realloc(stmt->paramvalues, sizeof(char *) * (stmt->nparams + 1), stmt->lineno))) + if (!(stmt->paramlengths = (int *) ecpg_realloc(stmt->paramlengths, sizeof(int) * (stmt->nparams + 1), stmt->lineno))) { ecpg_free_params(stmt, false); return false; } + stmt->paramlengths[stmt->nparams] = binary_length; + if (!(stmt->paramformats = (int *) ecpg_realloc(stmt->paramformats, sizeof(int) * (stmt->nparams + 1), stmt->lineno))) + { + ecpg_free_params(stmt, false); + return false; + } + stmt->paramformats[stmt->nparams] = (binary_format ? 1 : 0); stmt->nparams++; - stmt->paramvalues = paramvalues; - stmt->paramvalues[stmt->nparams - 1] = tobeinserted; /* let's see if this was an old style placeholder */ if (stmt->command[position] == '?') @@ -1392,8 +1553,12 @@ ecpg_build_params(struct statement *stmt) var = var->next; } - /* Check if there are unmatched things left. */ - if (next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0) + /* + * Check if there are unmatched things left. PREPARE AS has no parameter. + * Check other statement. + */ + if (stmt->statement_type != ECPGst_prepare && + next_insert(stmt->command, position, stmt->questionmarks, std_strings) >= 0) { ecpg_raise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL); @@ -1435,7 +1600,13 @@ ecpg_execute(struct statement *stmt) ecpg_log("ecpg_execute on line %d: query: %s; with %d parameter(s) on connection %s\n", stmt->lineno, stmt->command, stmt->nparams, stmt->connection->name); if (stmt->statement_type == ECPGst_execute) { - stmt->results = PQexecPrepared(stmt->connection->connection, stmt->name, stmt->nparams, (const char *const *) stmt->paramvalues, NULL, NULL, 0); + stmt->results = PQexecPrepared(stmt->connection->connection, + stmt->name, + stmt->nparams, + (const char *const *) stmt->paramvalues, + (const int *) stmt->paramlengths, + (const int *) stmt->paramformats, + 0); ecpg_log("ecpg_execute on line %d: using PQexecPrepared for \"%s\"\n", stmt->lineno, stmt->command); } else @@ -1447,9 +1618,24 @@ ecpg_execute(struct statement *stmt) } else { - stmt->results = PQexecParams(stmt->connection->connection, stmt->command, stmt->nparams, NULL, (const char *const *) stmt->paramvalues, NULL, NULL, 0); + stmt->results = PQexecParams(stmt->connection->connection, + stmt->command, stmt->nparams, NULL, + (const char *const *) stmt->paramvalues, + (const int *) stmt->paramlengths, + (const int *) stmt->paramformats, + 0); + ecpg_log("ecpg_execute on line %d: using PQexecParams\n", stmt->lineno); } + + if (stmt->statement_type == ECPGst_prepare) + { + if (!ecpg_register_prepared_stmt(stmt)) + { + ecpg_free_params(stmt, true); + return false; + } + } } ecpg_free_params(stmt, true); @@ -1713,7 +1899,7 @@ ecpg_process_output(struct statement *stmt, bool clear_result) /* * execution should never reach this code because it is already - * handled in ECPGcheck_PQresult() + * handled in ecpg_check_PQresult() */ ecpg_log("ecpg_process_output on line %d: unknown execution status type\n", stmt->lineno); @@ -1729,12 +1915,13 @@ ecpg_process_output(struct statement *stmt, bool clear_result) } /* check for asynchronous returns */ - notify = PQnotifies(stmt->connection->connection); - if (notify) + PQconsumeInput(stmt->connection->connection); + while ((notify = PQnotifies(stmt->connection->connection)) != NULL) { ecpg_log("ecpg_process_output on line %d: asynchronous notification of \"%s\" from backend PID %d received\n", stmt->lineno, notify->relname, notify->be_pid); PQfreemem(notify); + PQconsumeInput(stmt->connection->connection); } return status; @@ -1756,11 +1943,12 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, enum ECPG_statement_type statement_type, const char *query, va_list args, struct statement **stmt_out) { - struct statement *stmt; + struct statement *stmt = NULL; struct connection *con; enum ECPGttype type; struct variable **list; char *prepname; + bool is_prepared_name_set; *stmt_out = NULL; @@ -1777,8 +1965,29 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, /* * Make sure we do NOT honor the locale for numeric input/output since the - * database wants the standard decimal point + * database wants the standard decimal point. If available, use + * uselocale() for this because it's thread-safe. Windows doesn't have + * that, but it usually does have _configthreadlocale(). In some versions + * of MinGW, _configthreadlocale() exists but always returns -1 --- so + * treat that situation as if the function doesn't exist. */ +#ifdef HAVE_USELOCALE + stmt->clocale = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0); + if (stmt->clocale == (locale_t) 0) + { + ecpg_do_epilogue(stmt); + return false; + } + stmt->oldlocale = uselocale(stmt->clocale); + if (stmt->oldlocale == (locale_t) 0) + { + ecpg_do_epilogue(stmt); + return false; + } +#else +#ifdef HAVE__CONFIGTHREADLOCALE + stmt->oldthreadlocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE); +#endif stmt->oldlocale = ecpg_strdup(setlocale(LC_NUMERIC, NULL), lineno); if (stmt->oldlocale == NULL) { @@ -1786,6 +1995,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, return false; } setlocale(LC_NUMERIC, "C"); +#endif #ifdef ENABLE_THREAD_SAFETY ecpg_pthreads_init(); @@ -1840,6 +2050,7 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, return false; } } + /* name of PREPARE AS will be set in loop of inlist */ stmt->connection = con; stmt->lineno = lineno; @@ -1851,8 +2062,9 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, /*------ * create a list of variables * - * The variables are listed with input variables preceding outputvariables - * The end of each group is marked by an end marker. per variable we list: + * The variables are listed with input variables preceding output + * variables. The end of each group is marked by an end marker. + * Per variable we list: * * type - as defined in ecpgtype.h * value - where to store the data @@ -1862,13 +2074,15 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, * offset - offset between ith and (i+1)th entry in an array, normally * that means sizeof(type) * ind_type - type of indicator variable - * ind_value - pointer to indicator variable + * ind_pointer - pointer to indicator variable * ind_varcharsize - empty - * ind_arraysize - arraysize of indicator array + * ind_arrsize - arraysize of indicator array * ind_offset - indicator offset *------ */ + is_prepared_name_set = false; + list = &(stmt->inlist); type = va_arg(args, enum ECPGttype); @@ -1957,6 +2171,12 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, *list = var; else ptr->next = var; + + if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare) + { + stmt->name = ecpg_strdup(var->value, lineno); + is_prepared_name_set = true; + } } type = va_arg(args, enum ECPGttype); @@ -1970,6 +2190,13 @@ ecpg_do_prologue(int lineno, const int compat, const int force_indicator, return false; } + if (!is_prepared_name_set && stmt->statement_type == ECPGst_prepare) + { + ecpg_raise(lineno, ECPG_TOO_FEW_ARGUMENTS, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, (con) ? con->name : ecpg_gettext("")); + ecpg_do_epilogue(stmt); + return false; + } + /* initialize auto_mem struct */ ecpg_clear_auto_mem(); @@ -1988,8 +2215,23 @@ ecpg_do_epilogue(struct statement *stmt) if (stmt == NULL) return; +#ifdef HAVE_USELOCALE + if (stmt->oldlocale != (locale_t) 0) + uselocale(stmt->oldlocale); +#else if (stmt->oldlocale) setlocale(LC_NUMERIC, stmt->oldlocale); +#ifdef HAVE__CONFIGTHREADLOCALE + + /* + * This is a bit trickier than it looks: if we failed partway through + * statement initialization, oldthreadlocale could still be 0. But that's + * okay because a call with 0 is defined to be a no-op. + */ + if (stmt->oldthreadlocale != -1) + (void) _configthreadlocale(stmt->oldthreadlocale); +#endif +#endif free_statement(stmt); } diff --git a/src/interfaces/ecpg/ecpglib/memory.c b/src/interfaces/ecpg/ecpglib/memory.c index dc548a4cdab..52ca1c5c687 100644 --- a/src/interfaces/ecpg/ecpglib/memory.c +++ b/src/interfaces/ecpg/ecpglib/memory.c @@ -7,7 +7,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" void ecpg_free(void *ptr) diff --git a/src/interfaces/ecpg/ecpglib/misc.c b/src/interfaces/ecpg/ecpglib/misc.c index be9cac6e7b4..2eec54a2d99 100644 --- a/src/interfaces/ecpg/ecpglib/misc.c +++ b/src/interfaces/ecpg/ecpglib/misc.c @@ -9,7 +9,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #include "pgtypes_numeric.h" #include "pgtypes_date.h" @@ -355,6 +355,9 @@ ECPGset_noind_null(enum ECPGttype type, void *ptr) *(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00; ((struct ECPGgeneric_varchar *) ptr)->len = 0; break; + case ECPGt_bytea: + ((struct ECPGgeneric_bytea *) ptr)->len = 0; + break; case ECPGt_decimal: memset((char *) ptr, 0, sizeof(decimal)); ((decimal *) ptr)->sign = NUMERIC_NULL; @@ -428,6 +431,10 @@ ECPGis_noind_null(enum ECPGttype type, const void *ptr) if (*(((const struct ECPGgeneric_varchar *) ptr)->arr) == 0x00) return true; break; + case ECPGt_bytea: + if (((const struct ECPGgeneric_bytea *) ptr)->len == 0) + return true; + break; case ECPGt_decimal: if (((const decimal *) ptr)->sign == NUMERIC_NULL) return true; @@ -525,6 +532,17 @@ ECPGset_var(int number, void *pointer, int lineno) { struct var_list *ptr; + struct sqlca_t *sqlca = ECPGget_sqlca(); + + if (sqlca == NULL) + { + ecpg_raise(lineno, ECPG_OUT_OF_MEMORY, + ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL); + return; + } + + ecpg_init_sqlca(sqlca); + for (ptr = ivlist; ptr != NULL; ptr = ptr->next) { if (ptr->number == number) diff --git a/src/interfaces/ecpg/ecpglib/nls.mk b/src/interfaces/ecpg/ecpglib/nls.mk index 3057a00b329..5ce97ead8e3 100644 --- a/src/interfaces/ecpg/ecpglib/nls.mk +++ b/src/interfaces/ecpg/ecpglib/nls.mk @@ -1,6 +1,6 @@ # src/interfaces/ecpg/ecpglib/nls.mk CATALOG_NAME = ecpglib -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru tr zh_CN +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr vi zh_CN GETTEXT_FILES = connect.c descriptor.c error.c execute.c misc.c GETTEXT_TRIGGERS = ecpg_gettext GETTEXT_FLAGS = ecpg_gettext:1:pass-c-format diff --git a/src/interfaces/ecpg/ecpglib/po/cs.po b/src/interfaces/ecpg/ecpglib/po/cs.po index 38911088079..bc09566ec70 100644 --- a/src/interfaces/ecpg/ecpglib/po/cs.po +++ b/src/interfaces/ecpg/ecpglib/po/cs.po @@ -3,171 +3,197 @@ # This file is distributed under the same license as the PostgreSQL package. # # Tomáš Vondra , 2012, 2013. - msgid "" msgstr "" "Project-Id-Version: ecpglib-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-09-18 16:40+0000\n" -"PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2018-07-13 19:38+0000\n" +"PO-Revision-Date: 2018-07-13 23:44+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.7\n" -#: connect.c:231 +#: connect.c:237 msgid "empty message text" msgstr "prázdný text zprávy" -#: connect.c:384 connect.c:413 connect.c:618 +#: connect.c:401 connect.c:430 connect.c:638 msgid "" msgstr "" -#: descriptor.c:807 misc.c:113 +#: descriptor.c:834 misc.c:120 msgid "NULL" msgstr "NULL" -#: error.c:29 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 #, c-format msgid "no data found on line %d" msgstr "na řádce %d nenalezena žádná data" -#: error.c:39 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 #, c-format msgid "out of memory on line %d" msgstr "nedostatek pamÄ›ti na řádce %d" -#: error.c:49 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 #, c-format msgid "unsupported type \"%s\" on line %d" msgstr "nepodporovaný typ \"%s\" na řádce %d" -#: error.c:59 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 #, c-format msgid "too many arguments on line %d" msgstr "příliÅ¡ mnoho argumentů na řádce %d" -#: error.c:69 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 #, c-format msgid "too few arguments on line %d" msgstr "příliÅ¡ málo argumentů na řádce %d" -#: error.c:79 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 #, c-format msgid "invalid input syntax for type int: \"%s\", on line %d" msgstr "chybná vstupní syntaxe pro typ int: \"%s\", na řádce %d" -#: error.c:89 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 #, c-format msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" msgstr "chybná vstupní syntaxe pro typ unsigned int: \"%s\", na řádce %d" -#: error.c:99 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 #, c-format msgid "invalid input syntax for floating-point type: \"%s\", on line %d" msgstr "chybná vstupní syntaxe pro typ floating-point: \"%s\", na řádce %d" -#: error.c:110 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 #, c-format msgid "invalid syntax for type boolean: \"%s\", on line %d" msgstr "chybná vstupní syntaxe pro typ boolean: \"%s\", na řádce %d" -#: error.c:118 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 #, c-format msgid "could not convert boolean value: size mismatch, on line %d" msgstr "nelze zkonvertovat boolean hodnotu: nesprávná velikost, na řádce %d" -#: error.c:128 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 #, c-format msgid "empty query on line %d" msgstr "prázdný dotaz na řádce %d" -#: error.c:138 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 #, c-format msgid "null value without indicator on line %d" msgstr "null hodnota bez indikátoru na řádce %d" -#: error.c:148 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 #, c-format msgid "variable does not have an array type on line %d" msgstr "promÄ›nná nemá datový typ pole na řádce %d" -#: error.c:158 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 #, c-format msgid "data read from server is not an array on line %d" msgstr "data naÄtená ze serveru nejsou pole na řádce %d" -#: error.c:168 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 #, c-format msgid "inserting an array of variables is not supported on line %d" msgstr "vkládání pole promÄ›nných není podporováno na řádce %d" -#: error.c:178 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 #, c-format msgid "connection \"%s\" does not exist on line %d" msgstr "spojení \"%s\" neexistuje na řádce %d" -#: error.c:188 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 #, c-format msgid "not connected to connection \"%s\" on line %d" msgstr "neotevÅ™ené spojení \"%s\" na řádce %d" -#: error.c:198 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 #, c-format msgid "invalid statement name \"%s\" on line %d" msgstr "neplatný název příkazu \"%s\" na řádce %d" -#: error.c:208 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 #, c-format msgid "descriptor \"%s\" not found on line %d" msgstr "deskriptor \"%s\" nenalezen na řádce %d" -#: error.c:218 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 #, c-format msgid "descriptor index out of range on line %d" msgstr "index deskriptoru mimo rozsah na řádce %d" -#: error.c:228 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 #, c-format msgid "unrecognized descriptor item \"%s\" on line %d" msgstr "nerozpoznaná položka deskriptoru \"%s\" na řádce %d" -#: error.c:238 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 #, c-format msgid "variable does not have a numeric type on line %d" msgstr "promÄ›nná nemá Äíselný datový typ na řádce %d" -#: error.c:248 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 #, c-format msgid "variable does not have a character type on line %d" msgstr "promÄ›nná nemá znakový datový typ na řádce %d" -#: error.c:258 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 #, c-format msgid "error in transaction processing on line %d" msgstr "chyba v transakÄním zpracování na řádce %d" -#: error.c:268 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 #, c-format msgid "could not connect to database \"%s\" on line %d" msgstr "nelze se spojit s databází \"%s\" na řádce %d" -#: error.c:278 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 #, c-format msgid "SQL error %d on line %d" msgstr "SQL chyba %d na řádce %d" -#: error.c:318 +#: error.c:254 msgid "the connection to the server was lost" msgstr "spojení se serverem bylo ztraceno" -#: error.c:405 +#: error.c:347 #, c-format msgid "SQL error: %s\n" msgstr "SQL chyba: %s\n" -#: execute.c:1921 +#: execute.c:1968 msgid "" msgstr "" diff --git a/src/interfaces/ecpg/ecpglib/po/es.po b/src/interfaces/ecpg/ecpglib/po/es.po index 4c493fc6533..b0e1f6be980 100644 --- a/src/interfaces/ecpg/ecpglib/po/es.po +++ b/src/interfaces/ecpg/ecpglib/po/es.po @@ -1,18 +1,18 @@ # Spanish message translation file for ecpglib # -# Copyright (C) 2009-2012 PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Emanuel Calvo Franco , 2009. # msgid "" msgstr "" -"Project-Id-Version: ecpglib (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:38+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: ecpglib (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:20-0400\n" "Last-Translator: Emanuel Calvo Franco \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -22,11 +22,11 @@ msgstr "" msgid "empty message text" msgstr "mensaje de texto vacío" -#: connect.c:401 connect.c:430 connect.c:638 +#: connect.c:403 connect.c:432 connect.c:640 msgid "" msgstr "" -#: descriptor.c:833 misc.c:120 +#: descriptor.c:887 misc.c:120 msgid "NULL" msgstr "NULL" @@ -183,18 +183,24 @@ msgstr "no se pudo conectar a la base de datos «%s» en línea %d" #. translator: this string will be truncated at 149 characters expanded. #: error.c:207 #, c-format +msgid "The cursor is invalid on line %d" +msgstr "el cursor no es válido en línea %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:214 +#, c-format msgid "SQL error %d on line %d" msgstr "error SQL %d en línea %d" -#: error.c:254 +#: error.c:261 msgid "the connection to the server was lost" msgstr "se ha perdido la conexión al servidor" -#: error.c:347 +#: error.c:354 #, c-format msgid "SQL error: %s\n" msgstr "error SQL: %s\n" -#: execute.c:1961 +#: execute.c:2187 execute.c:2194 msgid "" msgstr "" diff --git a/src/interfaces/ecpg/ecpglib/po/fr.po b/src/interfaces/ecpg/ecpglib/po/fr.po index b897ec9d998..57ebed62638 100644 --- a/src/interfaces/ecpg/ecpglib/po/fr.po +++ b/src/interfaces/ecpg/ecpglib/po/fr.po @@ -8,172 +8,202 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2010-03-06 17:22+0000\n" -"PO-Revision-Date: 2013-09-04 20:31-0400\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:08+0000\n" +"PO-Revision-Date: 2019-05-17 14:44+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.2.1\n" -#: connect.c:226 +#: connect.c:237 msgid "empty message text" msgstr "texte du message vide" -#: connect.c:381 -#: connect.c:407 -#: connect.c:520 +#: connect.c:403 connect.c:432 connect.c:640 msgid "" msgstr "" -#: error.c:29 +#: descriptor.c:888 misc.c:120 +msgid "NULL" +msgstr "NULL" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 #, c-format msgid "no data found on line %d" msgstr "aucune donnée trouvée sur la ligne %d" -#: error.c:39 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 #, c-format msgid "out of memory on line %d" msgstr "mémoire épuisée à la ligne %d" -#: error.c:49 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 #, c-format msgid "unsupported type \"%s\" on line %d" msgstr "type « %s » non supporté sur la ligne %d" -#: error.c:59 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 #, c-format msgid "too many arguments on line %d" msgstr "trop d'arguments sur la ligne %d" -#: error.c:69 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 #, c-format msgid "too few arguments on line %d" msgstr "trop peu d'arguments sur la ligne %d" -#: error.c:79 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 #, c-format msgid "invalid input syntax for type int: \"%s\", on line %d" msgstr "syntaxe invalide en entrée pour le type int : « %s » sur la ligne %d" -#: error.c:89 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 #, c-format msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" msgstr "syntaxe invalide en entrée pour le type unisgned int : « %s » sur la ligne %d" -#: error.c:99 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 #, c-format msgid "invalid input syntax for floating-point type: \"%s\", on line %d" msgstr "syntaxe invalide en entrée pour le type float : « %s » sur la ligne %d" -#: error.c:110 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 #, c-format msgid "invalid syntax for type boolean: \"%s\", on line %d" msgstr "syntaxe invalide en entrée pour le type booléen : « %s » sur la ligne %d" -#: error.c:118 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 #, c-format msgid "could not convert boolean value: size mismatch, on line %d" msgstr "" "n'a pas pu convertir la valeur booléenne : différence de taille sur la\n" "ligne %d" -#: error.c:128 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 #, c-format msgid "empty query on line %d" msgstr "requête vide sur la ligne %d" -#: error.c:138 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 #, c-format msgid "null value without indicator on line %d" msgstr "valeur NULL sans indicateur sur la ligne %d" -#: error.c:148 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 #, c-format msgid "variable does not have an array type on line %d" msgstr "la valeur n'a pas de type tableau sur la ligne %d" -#: error.c:158 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 #, c-format msgid "data read from server is not an array on line %d" msgstr "la donnée lue du serveur n'est pas un tableau sur la ligne %d" -#: error.c:168 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 #, c-format msgid "inserting an array of variables is not supported on line %d" msgstr "l'insertion d'un tableau de variables n'est pas supportée, sur la ligne %d" -#: error.c:178 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 #, c-format msgid "connection \"%s\" does not exist on line %d" msgstr "la connexion « %s » n'existe pas en ligne %d" -#: error.c:188 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 #, c-format msgid "not connected to connection \"%s\" on line %d" msgstr "non connecté à la connexion « %s » en ligne %d" -#: error.c:198 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 #, c-format msgid "invalid statement name \"%s\" on line %d" msgstr "nom d'instruction « %s » invalide sur la ligne %d" -#: error.c:208 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 #, c-format msgid "descriptor \"%s\" not found on line %d" msgstr "descripteur « %s » introuvable sur la ligne %d" -#: error.c:218 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 #, c-format msgid "descriptor index out of range on line %d" msgstr "index de descripteur hors d'échelle sur la ligne %d" -#: error.c:228 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 #, c-format msgid "unrecognized descriptor item \"%s\" on line %d" msgstr "élément descripteur « %s » non reconnu sur la ligne %d" -#: error.c:238 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 #, c-format msgid "variable does not have a numeric type on line %d" msgstr "la variable n'est pas de type numeric sur la ligne %d" -#: error.c:248 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 #, c-format msgid "variable does not have a character type on line %d" msgstr "la variable n'est pas de type caractère sur la ligne %d" -#: error.c:258 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 #, c-format msgid "error in transaction processing on line %d" msgstr "erreur dans le traitement de la transaction en ligne %d" -#: error.c:268 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 #, c-format msgid "could not connect to database \"%s\" on line %d" msgstr "n'a pas pu se connecter à la base de données « %s » en ligne %d" -#: error.c:278 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 +#, c-format +msgid "The cursor is invalid on line %d" +msgstr "Le curseur est invalide sur la ligne %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:214 #, c-format msgid "SQL error %d on line %d" msgstr "erreur SQL %d en ligne %d" -#: error.c:316 +#: error.c:261 msgid "the connection to the server was lost" msgstr "la connexion au serveur a été perdue" -#: error.c:402 +#: error.c:354 #, c-format msgid "SQL error: %s\n" msgstr "erreur SQL : %s\n" -#: execute.c:1912 +#: execute.c:2103 msgid "" msgstr "" - -#: misc.c:113 -msgid "NULL" -msgstr "NULL" - diff --git a/src/interfaces/ecpg/ecpglib/po/it.po b/src/interfaces/ecpg/ecpglib/po/it.po index 20f4494c8d0..24d7435f2fa 100644 --- a/src/interfaces/ecpg/ecpglib/po/it.po +++ b/src/interfaces/ecpg/ecpglib/po/it.po @@ -1,27 +1,26 @@ # -# Translation of ecpglib to Italian -# PostgreSQL Project +# ecpglib.po +# Italian message translation file for ecpglib # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Maurizio Totti +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Gabriele Bartolini +# Daniele Varrazzo , 2012-2017 +# Maurizio Totti , 2010 # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: ecpglib (PostgreSQL) 9.3\n" +"Project-Id-Version: ecpglib (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-03-15 22:10+0000\n" +"POT-Creation-Date: 2016-04-17 00:07+0000\n" "PO-Revision-Date: 2012-10-30 13:08+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -30,163 +29,189 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Poedit 1.5.4\n" -#: connect.c:231 +#: connect.c:237 msgid "empty message text" msgstr "messaggio di testo vuoto" -#: connect.c:384 connect.c:413 connect.c:618 +#: connect.c:401 connect.c:430 connect.c:638 msgid "" msgstr "" -#: descriptor.c:807 misc.c:113 +#: descriptor.c:833 misc.c:120 msgid "NULL" msgstr "NULL" -#: error.c:29 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 #, c-format msgid "no data found on line %d" msgstr "non ci sono dati alla riga %d" # Utilizzerei 'memoria esaurita' al posto di 'errore di memoria' (GB) -#: error.c:39 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 #, c-format msgid "out of memory on line %d" msgstr "memoria esaurita alla riga %d" -#: error.c:49 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 #, c-format msgid "unsupported type \"%s\" on line %d" msgstr "tipo \"%s\" non supportato alla riga %d" -#: error.c:59 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 #, c-format msgid "too many arguments on line %d" msgstr "troppi argomenti alla riga %d" -#: error.c:69 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 #, c-format msgid "too few arguments on line %d" msgstr "numero di argomenti non sufficiente alla riga %d" -#: error.c:79 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 #, c-format msgid "invalid input syntax for type int: \"%s\", on line %d" msgstr "sintassi in input non valida per il tipo int: \"%s\", alla riga %d" -#: error.c:89 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 #, c-format msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" msgstr "sintassi in input non valida per il tipo unsigned int: \"%s\", alla riga %d" -#: error.c:99 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 #, c-format msgid "invalid input syntax for floating-point type: \"%s\", on line %d" msgstr "sintassi in input non valida per il tipo floating-point: \"%s\", alla riga %d" -#: error.c:110 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 #, c-format msgid "invalid syntax for type boolean: \"%s\", on line %d" msgstr "sintassi in input non valida per il tipo boolean: \"%s\", alla riga %d" # Originariamente da MT: non si può convertire il valore booleano: la dimensione è sbagliata (disallineata), alla riga %d -#: error.c:118 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 #, c-format msgid "could not convert boolean value: size mismatch, on line %d" msgstr "conversione fallita per il valore booleano: dimensione incompatibile, alla riga %d" -#: error.c:128 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 #, c-format msgid "empty query on line %d" msgstr "query vuota alla riga %d" -#: error.c:138 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 #, c-format msgid "null value without indicator on line %d" msgstr "valore nullo senza variabile 'indicatore' alla riga %d" # è difficile da tradurre diversamente (GB) -#: error.c:148 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 #, c-format msgid "variable does not have an array type on line %d" msgstr "la variabile non è di tipo array alla riga %d" -#: error.c:158 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 #, c-format msgid "data read from server is not an array on line %d" msgstr "i dati letti dal server non sono di tipo array alla riga %d" -#: error.c:168 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 #, c-format msgid "inserting an array of variables is not supported on line %d" msgstr "inserire un array di variabili non è supportato alla riga %d" -#: error.c:178 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 #, c-format msgid "connection \"%s\" does not exist on line %d" msgstr "la connessione \"%s\" non esiste alla riga %d" # Inizialmente (MT): non si è connessi alla connessione \"%s\" alla riga %d -#: error.c:188 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 #, c-format msgid "not connected to connection \"%s\" on line %d" msgstr "connessione \"%s\" non attiva alla riga %d" -#: error.c:198 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 #, c-format msgid "invalid statement name \"%s\" on line %d" msgstr "nome di istruzione non valido \"%s\" alla riga %d" -#: error.c:208 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 #, c-format msgid "descriptor \"%s\" not found on line %d" msgstr "il descrittore \"%s\" non esiste alla riga %d" # userei intervallo al posto di range (GB) -#: error.c:218 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 #, c-format msgid "descriptor index out of range on line %d" msgstr "l'indice del descrittore è fuori intervallo alla riga %d" -#: error.c:228 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 #, c-format msgid "unrecognized descriptor item \"%s\" on line %d" msgstr "elemento del descrittore \"%s\" sconosciuto alla riga %d" -#: error.c:238 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 #, c-format msgid "variable does not have a numeric type on line %d" msgstr "la variabile non è di tipo numerico alla riga %d" -#: error.c:248 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 #, c-format msgid "variable does not have a character type on line %d" msgstr "la variabile non è di tipo carattere alla riga %d" -#: error.c:258 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 #, c-format msgid "error in transaction processing on line %d" msgstr "errore nel processare la transazione alla riga %d" # Inizialmente (MT): non posso connettermi al database \"%s\" alla riga %d -#: error.c:268 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 #, c-format msgid "could not connect to database \"%s\" on line %d" msgstr "connessione fallita al database \"%s\" alla riga %d" -#: error.c:278 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 #, c-format msgid "SQL error %d on line %d" msgstr "errore SQL %d alla riga %d" -#: error.c:318 +#: error.c:254 msgid "the connection to the server was lost" msgstr "la connessione con il server è andata persa" -#: error.c:405 +#: error.c:347 #, c-format msgid "SQL error: %s\n" msgstr "errore SQL: %s\n" -#: execute.c:1921 +#: execute.c:1962 msgid "" msgstr "" diff --git a/src/interfaces/ecpg/ecpglib/po/ko.po b/src/interfaces/ecpg/ecpglib/po/ko.po index 69bffb8e17e..a059c47757a 100644 --- a/src/interfaces/ecpg/ecpglib/po/ko.po +++ b/src/interfaces/ecpg/ecpglib/po/ko.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: ecpglib (PostgreSQL) 9.6\n" +"Project-Id-Version: ecpglib (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" "POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 15:37+0900\n" +"PO-Revision-Date: 2017-08-17 13:20+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" diff --git a/src/interfaces/ecpg/ecpglib/po/ru.po b/src/interfaces/ecpg/ecpglib/po/ru.po index 1fc65d93ad4..d88e9f84ec0 100644 --- a/src/interfaces/ecpg/ecpglib/po/ru.po +++ b/src/interfaces/ecpg/ecpglib/po/ru.po @@ -2,12 +2,11 @@ # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: ecpglib (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:38+0000\n" +"POT-Creation-Date: 2019-02-08 11:42+0300\n" "PO-Revision-Date: 2016-09-20 12:00+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" @@ -26,7 +25,7 @@ msgstr "пуÑтое Ñообщение" msgid "" msgstr "<ПО_УМОЛЧÐÐИЮ>" -#: descriptor.c:833 misc.c:120 +#: descriptor.c:857 misc.c:120 msgid "NULL" msgstr "NULL" @@ -197,6 +196,6 @@ msgstr "подключение к Ñерверу потерÑно" msgid "SQL error: %s\n" msgstr "ошибка SQL: %s\n" -#: execute.c:1961 +#: execute.c:1996 msgid "" msgstr "<>" diff --git a/src/interfaces/ecpg/ecpglib/po/sv.po b/src/interfaces/ecpg/ecpglib/po/sv.po new file mode 100644 index 00000000000..1a889519c07 --- /dev/null +++ b/src/interfaces/ecpg/ecpglib/po/sv.po @@ -0,0 +1,204 @@ +# SWEDISH message translation file for ecpglib +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Dennis Björklund , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: ecpglib (PostgreSQL) 10\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-27 01:38+0000\n" +"PO-Revision-Date: 2019-04-27 14:15+0200\n" +"Last-Translator: Dennis Björklund , 2017\n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: connect.c:237 +msgid "empty message text" +msgstr "tom meddelandetext" + +#: connect.c:403 connect.c:432 connect.c:640 +msgid "" +msgstr "" + +#: descriptor.c:888 misc.c:120 +msgid "NULL" +msgstr "NULL" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 +#, c-format +msgid "no data found on line %d" +msgstr "ingen data hittad pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 +#, c-format +msgid "out of memory on line %d" +msgstr "slut pÃ¥ minne pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 +#, c-format +msgid "unsupported type \"%s\" on line %d" +msgstr "ej stöd för typ \"%s\" pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 +#, c-format +msgid "too many arguments on line %d" +msgstr "för mÃ¥nga argument pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 +#, c-format +msgid "too few arguments on line %d" +msgstr "för fÃ¥ argument pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 +#, c-format +msgid "invalid input syntax for type int: \"%s\", on line %d" +msgstr "ogiltig inputsyntax för typ int: \"%s\", pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 +#, c-format +msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" +msgstr "ogiltig inputsyntax för typ unsigned int: \"%s\", pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 +#, c-format +msgid "invalid input syntax for floating-point type: \"%s\", on line %d" +msgstr "ogiltig inputsyntaxc för flyttalstyp: \"%s\", pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 +#, c-format +msgid "invalid syntax for type boolean: \"%s\", on line %d" +msgstr "ogiltig syntax för typ boolean: \"%s\", pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 +#, c-format +msgid "could not convert boolean value: size mismatch, on line %d" +msgstr "kunde inte konvertera booleanskt värde: storlekarna matchar inte, pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 +#, c-format +msgid "empty query on line %d" +msgstr "tom frÃ¥ga pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 +#, c-format +msgid "null value without indicator on line %d" +msgstr "null-värde utan indikator pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 +#, c-format +msgid "variable does not have an array type on line %d" +msgstr "variabel har inte array-typ pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 +#, c-format +msgid "data read from server is not an array on line %d" +msgstr "data inläst frÃ¥n servern är inte en array pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 +#, c-format +msgid "inserting an array of variables is not supported on line %d" +msgstr "sätta in en array med variabler stöds inte pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 +#, c-format +msgid "connection \"%s\" does not exist on line %d" +msgstr "anslutning \"%s\" funns inte pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 +#, c-format +msgid "not connected to connection \"%s\" on line %d" +msgstr "ej ansluten till anslutning \"%s\" pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 +#, c-format +msgid "invalid statement name \"%s\" on line %d" +msgstr "ogiltigt satsnamn \"%s\" pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 +#, c-format +msgid "descriptor \"%s\" not found on line %d" +msgstr "deskriptor \"%s\" hittades inte pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 +#, c-format +msgid "descriptor index out of range on line %d" +msgstr "deskriptor-index utanför sitt intervall pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 +#, c-format +msgid "unrecognized descriptor item \"%s\" on line %d" +msgstr "okänd deskriptor-post \"%s\" pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 +#, c-format +msgid "variable does not have a numeric type on line %d" +msgstr "variabel har ej numerisk typ pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 +#, c-format +msgid "variable does not have a character type on line %d" +msgstr "variabel har ej character-typ pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 +#, c-format +msgid "error in transaction processing on line %d" +msgstr "fel i transaktionsprocessande pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 +#, c-format +msgid "could not connect to database \"%s\" on line %d" +msgstr "kunde inte ansluta till databas \"%s\" pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 +#, c-format +msgid "The cursor is invalid on line %d" +msgstr "Markören är ogiltig pÃ¥ rad %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:214 +#, c-format +msgid "SQL error %d on line %d" +msgstr "SQL-fel %d pÃ¥ rad %d" + +#: error.c:261 +msgid "the connection to the server was lost" +msgstr "anslutningen till servern tappades" + +#: error.c:354 +#, c-format +msgid "SQL error: %s\n" +msgstr "SQL-fel: %s\n" + +#: execute.c:2103 +msgid "" +msgstr "" diff --git a/src/interfaces/ecpg/ecpglib/po/tr.po b/src/interfaces/ecpg/ecpglib/po/tr.po index 1df67a5d596..38ac9897f0b 100644 --- a/src/interfaces/ecpg/ecpglib/po/tr.po +++ b/src/interfaces/ecpg/ecpglib/po/tr.po @@ -6,170 +6,200 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 8.4\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2010-08-31 20:08+0000\n" -"PO-Revision-Date: 2013-09-04 20:47-0400\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:38+0000\n" +"PO-Revision-Date: 2019-06-14 10:40+0300\n" "Last-Translator: Devrim GÜNDÜZ \n" "Language-Team: TR \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" -#: connect.c:226 +#: connect.c:237 msgid "empty message text" -msgstr "BoÅŸ mesaj metni" +msgstr "boÅŸ mesaj metni" -#: connect.c:381 -#: connect.c:407 -#: connect.c:520 +#: connect.c:403 connect.c:432 connect.c:640 msgid "" msgstr "<ÖNTANIMLI>" -#: error.c:29 +#: descriptor.c:888 misc.c:120 +msgid "NULL" +msgstr "NULL" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 #, c-format msgid "no data found on line %d" msgstr "%d. satırda veri bulunamadı" -#: error.c:39 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 #, c-format msgid "out of memory on line %d" msgstr "%d. satırda yetersiz bellek" -#: error.c:49 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 #, c-format msgid "unsupported type \"%s\" on line %d" -msgstr "\"%s\" veri tipi (%d. satırda) desteklenmiyor" +msgstr "%2$d. satırda desteklenmeyen veri tipi \"%1$s\"" -#: error.c:59 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 #, c-format msgid "too many arguments on line %d" msgstr "%d. satırda çok fazla argüman var" -#: error.c:69 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 #, c-format msgid "too few arguments on line %d" msgstr "%d. satırda yetersiz argüman sayısı" -#: error.c:79 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 #, c-format msgid "invalid input syntax for type int: \"%s\", on line %d" -msgstr "int veri tipi için geçersiz girdi sözdizimi: \"%s\", %d. satırda" +msgstr "%2$d. satırda int veri tipi için geçersiz girdi sözdizimi: \"%1$s\"" -#: error.c:89 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 #, c-format msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" -msgstr "iÅŸaretsiz tamsayı veri tipi için geçersiz girdi sözdizimi: \"%s\", %d. satırda" +msgstr "%2$d. satırda iÅŸaretsiz tamsayı tipi için geçersiz girdi sözdizimi: \"%1$s\"" -#: error.c:99 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 #, c-format msgid "invalid input syntax for floating-point type: \"%s\", on line %d" -msgstr "kayan noktalı veri tipi için geçersiz girdi sözdizimi: \"%s\", %d. satırda" +msgstr "%2$d. satırda kayan noktalı veri tipi için geçersiz girdi sözdizimi: \"%1$s\"" -#: error.c:110 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 #, c-format msgid "invalid syntax for type boolean: \"%s\", on line %d" -msgstr "boolean veri tipi için geçersiz girdi sözdizimi: \"%s\", %d. satırda" +msgstr "%2$d. satırda boolean veri tipi için geçersiz girdi sözdizimi: \"%1$s\"" -#: error.c:118 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 #, c-format msgid "could not convert boolean value: size mismatch, on line %d" msgstr "boolean deÄŸer dönüştürülemedi: boyut uyuÅŸmazlığı, %d. satırda" -#: error.c:128 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 #, c-format msgid "empty query on line %d" msgstr "%d. satırda boÅŸ sorgu" -#: error.c:138 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 #, c-format msgid "null value without indicator on line %d" msgstr "%d. satırda belirteç olmadan null deÄŸer var" -#: error.c:148 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 #, c-format msgid "variable does not have an array type on line %d" -msgstr "%d. satırda deÄŸiÅŸkenin bir dizi veri tipi yok" +msgstr "%d. satırda deÄŸiÅŸkenin veri tipi dizi deÄŸil" -#: error.c:158 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 #, c-format msgid "data read from server is not an array on line %d" msgstr "%d. satırda sunucudan okunan veri bir dizi deÄŸil" -#: error.c:168 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 #, c-format msgid "inserting an array of variables is not supported on line %d" -msgstr "%d. satırda deÄŸiÅŸkenlerden oluÅŸan dizinin girilmesi desteklenmiyor" +msgstr "%d. satırda deÄŸiÅŸkenlerden oluÅŸan dizinin eklenmesi (insert) desteklenmiyor" -#: error.c:178 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 #, c-format msgid "connection \"%s\" does not exist on line %d" -msgstr "\"%s\" baÄŸlantısı %d numaralı satırda yok" +msgstr "%2$d numaralı satırda \"%1$s\" baÄŸlantısı yok" -#: error.c:188 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 #, c-format msgid "not connected to connection \"%s\" on line %d" -msgstr "\"%s\" baÄŸlantısına %d. satırda baÄŸlanılmıyor" +msgstr "%2$d. satırda\"%1$s\" baÄŸlantısına baÄŸlanılmıyor" -#: error.c:198 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 #, c-format msgid "invalid statement name \"%s\" on line %d" -msgstr "\"%s\" ifade adı geçersiz (%d. satırda)" +msgstr "%2$d. satırda geçersiz ifade adı \"%1$s\"" -#: error.c:208 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 #, c-format msgid "descriptor \"%s\" not found on line %d" -msgstr "\"%s\" açıklayıcısı %d. satırda bulunamadı" +msgstr "%2$d. satırda tanımlayıcı \"%1$s\" bulunamadı" -#: error.c:218 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 #, c-format msgid "descriptor index out of range on line %d" -msgstr "%d. satırdaki açıklayıcı indexi sınırların dışında" +msgstr "%d. satırdaki açıklayıcı indeks sınırların dışında" -#: error.c:228 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 #, c-format msgid "unrecognized descriptor item \"%s\" on line %d" -msgstr "\"%s\" tanımsız açıklayıcı nesnesi %d. satırda tanımlanamıyor" +msgstr "%2$d. satırda bilinmeyen tanımlayıcı öğe \"%1$s\"" -#: error.c:238 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 #, c-format msgid "variable does not have a numeric type on line %d" -msgstr "%d. satırdaki deÄŸiÅŸkenin sayısal tipi yok" +msgstr "%d. satırdaki deÄŸiÅŸken sayısal tipte deÄŸil" -#: error.c:248 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 #, c-format msgid "variable does not have a character type on line %d" msgstr "%d. satırdaki deÄŸiÅŸkenin karakter tipi yok" -#: error.c:258 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 #, c-format msgid "error in transaction processing on line %d" msgstr "%d. satırda tranaction'ı iÅŸlerken hata oluÅŸtu" -#: error.c:268 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 #, c-format msgid "could not connect to database \"%s\" on line %d" -msgstr " \"%s\" veritabanına baÄŸlanılamadı (satır no: %d)" +msgstr "%2$d. satırda \"%1$s\" veritabanına baÄŸlanılamadı" -#: error.c:278 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 +#, c-format +msgid "The cursor is invalid on line %d" +msgstr "%d. satırda geçersiz imleç (cursor)" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:214 #, c-format msgid "SQL error %d on line %d" -msgstr "%d SQL hatası (%d. satırda)" +msgstr "%2$d. satırda SQL hatası %1$d" -#: error.c:318 +#: error.c:261 msgid "the connection to the server was lost" msgstr "sunucuya baÄŸlantı kesildi" -#: error.c:405 +#: error.c:354 #, c-format msgid "SQL error: %s\n" msgstr "SQL hatası: %s\n" -#: execute.c:1912 +#: execute.c:2103 msgid "" msgstr "" - -#: misc.c:113 -msgid "NULL" -msgstr "NULL" - diff --git a/src/interfaces/ecpg/ecpglib/po/vi.po b/src/interfaces/ecpg/ecpglib/po/vi.po new file mode 100644 index 00000000000..850b54f26ce --- /dev/null +++ b/src/interfaces/ecpg/ecpglib/po/vi.po @@ -0,0 +1,200 @@ +# LANGUAGE message translation file for ecpglib +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the ecpglib (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: ecpglib (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:08+0000\n" +"PO-Revision-Date: 2018-04-23 21:34+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: connect.c:237 +msgid "empty message text" +msgstr "văn bản tin nhắn trống" + +#: connect.c:401 connect.c:430 connect.c:638 +msgid "" +msgstr "" + +#: descriptor.c:834 misc.c:120 +msgid "NULL" +msgstr "NULL" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 +#, c-format +msgid "no data found on line %d" +msgstr "không tìm thấy dữ liệu trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 +#, c-format +msgid "out of memory on line %d" +msgstr "hết bá»™ nhá»› trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 +#, c-format +msgid "unsupported type \"%s\" on line %d" +msgstr "không há»— trợ kiểu \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 +#, c-format +msgid "too many arguments on line %d" +msgstr "quá nhiá»u đối số trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 +#, c-format +msgid "too few arguments on line %d" +msgstr "quá ít đối số trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 +#, c-format +msgid "invalid input syntax for type int: \"%s\", on line %d" +msgstr "cú pháp nhập không hợp lệ cho kiểu int: \"%s\", trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 +#, c-format +msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" +msgstr "cú pháp nhập không hợp lệ cho kiểu unsigned int: \"%s\", trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 +#, c-format +msgid "invalid input syntax for floating-point type: \"%s\", on line %d" +msgstr "cú pháp nhập không hợp lệ cho kiểu dấu phẩy động: \"%s\", trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 +#, c-format +msgid "invalid syntax for type boolean: \"%s\", on line %d" +msgstr "cú pháp không hợp lệ cho kiểu boolean: \"%s\", trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 +#, c-format +msgid "could not convert boolean value: size mismatch, on line %d" +msgstr "không thể chuyển đổi giá trị boolean: kích thước không khá»›p, trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 +#, c-format +msgid "empty query on line %d" +msgstr "truy vấn trống trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 +#, c-format +msgid "null value without indicator on line %d" +msgstr "giá trị null không có chỉ báo (indicator) trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 +#, c-format +msgid "variable does not have an array type on line %d" +msgstr "biến không có kiểu mảng trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 +#, c-format +msgid "data read from server is not an array on line %d" +msgstr "dữ liệu Ä‘á»c từ server không phải là má»™t mảng trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 +#, c-format +msgid "inserting an array of variables is not supported on line %d" +msgstr "chèn má»™t mảng các biến không được há»— trợ trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 +#, c-format +msgid "connection \"%s\" does not exist on line %d" +msgstr "kết nối \"%s\" không tồn tại trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 +#, c-format +msgid "not connected to connection \"%s\" on line %d" +msgstr "chưa kết nối tá»›i kết nối \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 +#, c-format +msgid "invalid statement name \"%s\" on line %d" +msgstr "tên statement không hợp lệ \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 +#, c-format +msgid "descriptor \"%s\" not found on line %d" +msgstr "không tìm thấy descriptor \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 +#, c-format +msgid "descriptor index out of range on line %d" +msgstr "chỉ mục cá»§a descriptor nằm ngoài phạm vi trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 +#, c-format +msgid "unrecognized descriptor item \"%s\" on line %d" +msgstr "không nhận ra descriptor item \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 +#, c-format +msgid "variable does not have a numeric type on line %d" +msgstr "biến số không có kiểu numeric trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 +#, c-format +msgid "variable does not have a character type on line %d" +msgstr "biến số không có kiểu ký tá»± trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 +#, c-format +msgid "error in transaction processing on line %d" +msgstr "lá»—i trong xá»­ lý giao dịch trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 +#, c-format +msgid "could not connect to database \"%s\" on line %d" +msgstr "không thể kết nối vá»›i cÆ¡ sở dữ liệu \"%s\" trên dòng %d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 +#, c-format +msgid "SQL error %d on line %d" +msgstr "lá»—i SQL %d trên dòng %d" + +#: error.c:254 +msgid "the connection to the server was lost" +msgstr "kết nối vá»›i server bị mất" + +#: error.c:347 +#, c-format +msgid "SQL error: %s\n" +msgstr "lá»—i SQL: %s\n" + +#: execute.c:1968 +msgid "" +msgstr "" diff --git a/src/interfaces/ecpg/ecpglib/po/zh_CN.po b/src/interfaces/ecpg/ecpglib/po/zh_CN.po index 73f698b45cb..403b3e65895 100644 --- a/src/interfaces/ecpg/ecpglib/po/zh_CN.po +++ b/src/interfaces/ecpg/ecpglib/po/zh_CN.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: ecpglib (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-01-29 13:40+0000\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:08+0000\n" "PO-Revision-Date: 2013-09-03 23:28-0400\n" "Last-Translator: Weibin \n" "Language-Team: Chinese (Simplified)\n" @@ -16,158 +16,191 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: connect.c:231 +#: connect.c:237 msgid "empty message text" msgstr "æ¶ˆæ¯æ–‡æœ¬ä¸ºç©º" -#: connect.c:384 connect.c:413 connect.c:618 +#: connect.c:403 connect.c:432 connect.c:640 msgid "" msgstr "" -#: descriptor.c:807 misc.c:113 +#: descriptor.c:887 misc.c:120 msgid "NULL" msgstr "NULL" -#: error.c:29 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:33 #, c-format msgid "no data found on line %d" msgstr "在第%d行上没有找到数æ®" -#: error.c:39 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:40 #, c-format msgid "out of memory on line %d" msgstr "在第%d行上内存用尽" -#: error.c:49 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:47 #, c-format msgid "unsupported type \"%s\" on line %d" msgstr "在第%2$dä¸Šå‡ºçŽ°ä¸æ”¯æŒçš„类型\"%1$s\"" -#: error.c:59 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:54 #, c-format msgid "too many arguments on line %d" msgstr "在第%dè¡Œä¸Šçš„å‚æ•°å¤šäºŽæŒ‡å®šçš„æ•°é‡" -#: error.c:69 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:61 #, c-format msgid "too few arguments on line %d" msgstr "在第%dè¡Œä¸Šçš„å‚æ•°å°‘于指定的数é‡" -#: error.c:79 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:68 #, c-format msgid "invalid input syntax for type int: \"%s\", on line %d" msgstr "对于整数类型的输入语法无效: \"%s\" ,在第%d行" -#: error.c:89 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:75 #, c-format msgid "invalid input syntax for type unsigned int: \"%s\", on line %d" msgstr "å¯¹äºŽæ— ç¬¦å·æ•´æ•°ç±»åž‹çš„输入语法无效: \"%s\" 在第%d行" -#: error.c:99 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:82 #, c-format msgid "invalid input syntax for floating-point type: \"%s\", on line %d" msgstr "对于浮点类型的输入语法无效: \"%s\",在第%d行" -#: error.c:110 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:90 #, c-format msgid "invalid syntax for type boolean: \"%s\", on line %d" msgstr "对于布尔类型语法无效: \"%s\",在第%d行上" -#: error.c:118 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:95 #, c-format msgid "could not convert boolean value: size mismatch, on line %d" msgstr "在第%d行上无法转æ¢å¸ƒå°”类型值: 大å°ä¸åŒ¹é…" -#: error.c:128 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:102 #, c-format msgid "empty query on line %d" msgstr "在第%d行上查询是空的" -#: error.c:138 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:109 #, c-format msgid "null value without indicator on line %d" msgstr "在第%d行上的空值没有标志" -#: error.c:148 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:116 #, c-format msgid "variable does not have an array type on line %d" msgstr "在第%d行上的å˜é‡æ²¡æœ‰æ•°ç»„类型" -#: error.c:158 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:123 #, c-format msgid "data read from server is not an array on line %d" msgstr "在第%d行上从æœåŠ¡å™¨è¯»å–的数æ®ä¸æ˜¯æ•°ç»„" -#: error.c:168 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:130 #, c-format msgid "inserting an array of variables is not supported on line %d" msgstr "在第%dè¡Œä¸Šä¸æ”¯æŒæ­£åœ¨æ’入一个的å˜é‡æ•°ç»„" -#: error.c:178 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:137 #, c-format msgid "connection \"%s\" does not exist on line %d" msgstr "在第%2$d行上连接\"%1$s\"ä¸å­˜åœ¨" -#: error.c:188 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:144 #, c-format msgid "not connected to connection \"%s\" on line %d" msgstr "在第%2$d行上没有连接到\"%1$s\"连接" -#: error.c:198 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:151 #, c-format msgid "invalid statement name \"%s\" on line %d" msgstr "在第%2$d行上的语å¥åç§°\"%1$s\"无效" -#: error.c:208 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:158 #, c-format msgid "descriptor \"%s\" not found on line %d" msgstr "在第%2$d行上没有找到æè¿°ç¬¦\"%1$s\"" -#: error.c:218 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:165 #, c-format msgid "descriptor index out of range on line %d" msgstr "在第%d行上的æè¿°ç¬¦ç´¢å¼•超出范围" -#: error.c:228 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:172 #, c-format msgid "unrecognized descriptor item \"%s\" on line %d" msgstr "在第%2$d行上出现无法识别的æè¿°ç¬¦æˆå‘˜\"%1$s\"" -#: error.c:238 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:179 #, c-format msgid "variable does not have a numeric type on line %d" msgstr "在第%d上的å˜é‡æ²¡æœ‰æ•°å€¼ç±»åž‹" -#: error.c:248 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:186 #, c-format msgid "variable does not have a character type on line %d" msgstr "在第%d行上的å˜é‡æ²¡æœ‰å­—符类型" -#: error.c:258 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:193 #, c-format msgid "error in transaction processing on line %d" msgstr "在第%d行上的事务处ç†ä¸­å‘生错误" -#: error.c:268 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:200 #, c-format msgid "could not connect to database \"%s\" on line %d" msgstr "在第%2$d行上无法连接数æ®åº“\"%1$s\"" -#: error.c:278 +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:207 +#, fuzzy, c-format +#| msgid "SQL error %d on line %d" +msgid "The cursor is invalid on line %d" +msgstr "在第%2$d行上的SQL命令å‘生错误 代ç %1$d" + +#. translator: this string will be truncated at 149 characters expanded. +#: error.c:214 #, c-format msgid "SQL error %d on line %d" msgstr "在第%2$d行上的SQL命令å‘生错误 代ç %1$d" # common.c:298 -#: error.c:318 +#: error.c:261 msgid "the connection to the server was lost" msgstr "与æœåŠ¡å™¨çš„è¿žæŽ¥ä¸¢å¤±" -#: error.c:405 +#: error.c:354 #, c-format msgid "SQL error: %s\n" msgstr "SQL语å¥é”™è¯¯: %s\n" -#: execute.c:1921 +#: execute.c:2187 execute.c:2194 msgid "" msgstr "<空>" diff --git a/src/interfaces/ecpg/ecpglib/prepare.c b/src/interfaces/ecpg/ecpglib/prepare.c index e76b645024e..6e7adb94f26 100644 --- a/src/interfaces/ecpg/ecpglib/prepare.c +++ b/src/interfaces/ecpg/ecpglib/prepare.c @@ -8,27 +8,37 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #define STMTID_SIZE 32 +/* + * The statement cache contains stmtCacheNBuckets hash buckets, each + * having stmtCacheEntPerBucket entries, which we recycle as needed, + * giving up the least-executed entry in the bucket. + * stmtCacheEntries[0] is never used, so that zero can be a "not found" + * indicator. + */ +#define stmtCacheNBuckets 2039 /* should be a prime number */ +#define stmtCacheEntPerBucket 8 + +#define stmtCacheArraySize (stmtCacheNBuckets * stmtCacheEntPerBucket + 1) + typedef struct { int lineno; char stmtID[STMTID_SIZE]; char *ecpgQuery; - long execs; /* # of executions */ - const char *connection; /* connection for the statement */ + long execs; /* # of executions */ + const char *connection; /* connection for the statement */ } stmtCacheEntry; static int nextStmtID = 1; -static const int stmtCacheNBuckets = 2039; /* # buckets - a prime # */ -static const int stmtCacheEntPerBucket = 8; /* # entries/bucket */ -static stmtCacheEntry stmtCacheEntries[16384] = {{0, {0}, 0, 0, 0}}; +static stmtCacheEntry *stmtCacheEntries = NULL; static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, - struct prepared_statement *prev, struct prepared_statement *this); + struct prepared_statement *prev, struct prepared_statement *this); static bool isvarchar(unsigned char c) @@ -45,6 +55,51 @@ isvarchar(unsigned char c) return false; } +bool +ecpg_register_prepared_stmt(struct statement *stmt) +{ + struct statement *prep_stmt; + struct prepared_statement *this; + struct connection *con = stmt->connection; + struct prepared_statement *prev = NULL; + int lineno = stmt->lineno; + + /* check if we already have prepared this statement */ + this = ecpg_find_prepared_statement(stmt->name, con, &prev); + if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this)) + return false; + + /* allocate new statement */ + this = (struct prepared_statement *) ecpg_alloc(sizeof(struct prepared_statement), lineno); + if (!this) + return false; + + prep_stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno); + if (!prep_stmt) + { + ecpg_free(this); + return false; + } + memset(prep_stmt, 0, sizeof(struct statement)); + + /* create statement */ + prep_stmt->lineno = lineno; + prep_stmt->connection = con; + prep_stmt->command = ecpg_strdup(stmt->command, lineno); + prep_stmt->inlist = prep_stmt->outlist = NULL; + this->name = ecpg_strdup(stmt->name, lineno); + this->stmt = prep_stmt; + this->prepared = true; + + if (con->prep_stmts == NULL) + this->next = NULL; + else + this->next = con->prep_stmts; + + con->prep_stmts = this; + return true; +} + static bool replace_variables(char **text, int lineno) { @@ -64,9 +119,9 @@ replace_variables(char **text, int lineno) ptr += 2; /* skip '::' */ else { + /* a rough guess of the size we need: */ + int buffersize = sizeof(int) * CHAR_BIT * 10 / 3; int len; - int buffersize = sizeof(int) * CHAR_BIT * 10 / 3; /* a rough guess of the - * size we need */ char *buffer, *newcopy; @@ -75,7 +130,8 @@ replace_variables(char **text, int lineno) snprintf(buffer, buffersize, "$%d", counter++); - for (len = 1; (*text)[ptr + len] && isvarchar((*text)[ptr + len]); len++); + for (len = 1; (*text)[ptr + len] && isvarchar((*text)[ptr + len]); len++) + /* skip */ ; if (!(newcopy = (char *) ecpg_alloc(strlen(*text) -len + strlen(buffer) + 1, lineno))) { ecpg_free(buffer); @@ -158,15 +214,16 @@ prepare_common(int lineno, struct connection *con, const char *name, const char /* handle the EXEC SQL PREPARE statement */ /* questionmarks is not needed but remains in there for the time being to not change the API */ bool -ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, const char *name, const char *variable) +ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, + const char *name, const char *variable) { struct connection *con; struct prepared_statement *this, *prev; (void) questionmarks; /* quiet the compiler */ - con = ecpg_get_connection(connection_name); + con = ecpg_get_connection(connection_name); if (!ecpg_init(con, connection_name, lineno)) return false; @@ -185,7 +242,9 @@ ecpg_find_prepared_statement(const char *name, struct prepared_statement *this, *prev; - for (this = con->prep_stmts, prev = NULL; this != NULL; prev = this, this = this->next) + for (this = con->prep_stmts, prev = NULL; + this != NULL; + prev = this, this = this->next) { if (strcmp(this->name, name) == 0) { @@ -198,7 +257,8 @@ ecpg_find_prepared_statement(const char *name, } static bool -deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct prepared_statement *prev, struct prepared_statement *this) +deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, + struct prepared_statement *prev, struct prepared_statement *this) { bool r = false; @@ -217,7 +277,9 @@ deallocate_one(int lineno, enum COMPAT_MODE c, struct connection *con, struct pr sprintf(text, "deallocate \"%s\"", this->name); query = PQexec(this->stmt->connection->connection, text); ecpg_free(text); - if (ecpg_check_PQresult(query, lineno, this->stmt->connection->connection, this->stmt->compat)) + if (ecpg_check_PQresult(query, lineno, + this->stmt->connection->connection, + this->stmt->compat)) { PQclear(query); r = true; @@ -257,7 +319,6 @@ ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name) *prev; con = ecpg_get_connection(connection_name); - if (!ecpg_init(con, connection_name, lineno)) return false; @@ -288,7 +349,8 @@ ecpg_deallocate_all_conn(int lineno, enum COMPAT_MODE c, struct connection *con) bool ECPGdeallocate_all(int lineno, int compat, const char *connection_name) { - return ecpg_deallocate_all_conn(lineno, compat, ecpg_get_connection(connection_name)); + return ecpg_deallocate_all_conn(lineno, compat, + ecpg_get_connection(connection_name)); } char * @@ -306,6 +368,7 @@ char * ECPGprepared_statement(const char *connection_name, const char *name, int lineno) { (void) lineno; /* keep the compiler quiet */ + return ecpg_prepared(name, ecpg_get_connection(connection_name)); } @@ -319,27 +382,28 @@ HashStmt(const char *ecpgQuery) bucketNo, hashLeng, stmtLeng; - long long hashVal, + uint64 hashVal, rotVal; stmtLeng = strlen(ecpgQuery); - hashLeng = 50; /* use 1st 50 characters of statement */ - if (hashLeng > stmtLeng) /* if the statement isn't that long */ - hashLeng = stmtLeng; /* use its actual length */ + hashLeng = 50; /* use 1st 50 characters of statement */ + if (hashLeng > stmtLeng) /* if the statement isn't that long */ + hashLeng = stmtLeng; /* use its actual length */ hashVal = 0; for (stmtIx = 0; stmtIx < hashLeng; ++stmtIx) { - hashVal = hashVal + (int) ecpgQuery[stmtIx]; + hashVal = hashVal + (unsigned char) ecpgQuery[stmtIx]; + /* rotate 32-bit hash value left 13 bits */ hashVal = hashVal << 13; - rotVal = (hashVal & 0x1fff00000000LL) >> 32; - hashVal = (hashVal & 0xffffffffLL) | rotVal; + rotVal = (hashVal & UINT64CONST(0x1fff00000000)) >> 32; + hashVal = (hashVal & UINT64CONST(0xffffffff)) | rotVal; } bucketNo = hashVal % stmtCacheNBuckets; - bucketNo += 1; /* don't use bucket # 0 */ - return (bucketNo * stmtCacheEntPerBucket); + /* Add 1 so that array entry 0 is never used */ + return bucketNo * stmtCacheEntPerBucket + 1; } /* @@ -353,21 +417,25 @@ SearchStmtCache(const char *ecpgQuery) int entNo, entIx; -/* hash the statement */ + /* quick failure if cache not set up */ + if (stmtCacheEntries == NULL) + return 0; + + /* hash the statement */ entNo = HashStmt(ecpgQuery); -/* search the cache */ + /* search the cache */ for (entIx = 0; entIx < stmtCacheEntPerBucket; ++entIx) { - if (stmtCacheEntries[entNo].stmtID[0]) /* check if entry is in use */ + if (stmtCacheEntries[entNo].stmtID[0]) /* check if entry is in use */ { if (strcmp(ecpgQuery, stmtCacheEntries[entNo].ecpgQuery) == 0) - break; /* found it */ + break; /* found it */ } - ++entNo; /* incr entry # */ + ++entNo; /* incr entry # */ } -/* if entry wasn't found - set entry # to zero */ + /* if entry wasn't found - set entry # to zero */ if (entIx >= stmtCacheEntPerBucket) entNo = 0; @@ -380,27 +448,32 @@ SearchStmtCache(const char *ecpgQuery) * OR negative error code */ static int -ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo) /* entry # to free */ +ecpg_freeStmtCacheEntry(int lineno, int compat, + int entNo) /* entry # to free */ { stmtCacheEntry *entry; struct connection *con; struct prepared_statement *this, *prev; + /* fail if cache isn't set up */ + if (stmtCacheEntries == NULL) + return -1; + entry = &stmtCacheEntries[entNo]; - if (!entry->stmtID[0]) /* return if the entry isn't in use */ + if (!entry->stmtID[0]) /* return if the entry isn't in use */ return 0; con = ecpg_get_connection(entry->connection); - /* free the 'prepared_statement' list entry */ + /* free the 'prepared_statement' list entry */ this = ecpg_find_prepared_statement(entry->stmtID, con, &prev); if (this && !deallocate_one(lineno, compat, con, prev, this)) return -1; entry->stmtID[0] = '\0'; - /* free the memory used by the cache entry */ + /* free the memory used by the cache entry */ if (entry->ecpgQuery) { ecpg_free(entry->ecpgQuery); @@ -415,11 +488,11 @@ ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo) /* entry # to free */ * returns entry # in cache used OR negative error code */ static int -AddStmtToCache(int lineno, /* line # of statement */ - const char *stmtID, /* statement ID */ - const char *connection, /* connection */ +AddStmtToCache(int lineno, /* line # of statement */ + const char *stmtID, /* statement ID */ + const char *connection, /* connection */ int compat, /* compatibility level */ - const char *ecpgQuery) /* query */ + const char *ecpgQuery) /* query */ { int ix, initEntNo, @@ -427,32 +500,44 @@ AddStmtToCache(int lineno, /* line # of statement */ entNo; stmtCacheEntry *entry; -/* hash the statement */ + /* allocate and zero cache array if we haven't already */ + if (stmtCacheEntries == NULL) + { + stmtCacheEntries = (stmtCacheEntry *) + ecpg_alloc(sizeof(stmtCacheEntry) * stmtCacheArraySize, lineno); + if (stmtCacheEntries == NULL) + return -1; + } + + /* hash the statement */ initEntNo = HashStmt(ecpgQuery); -/* search for an unused entry */ + /* search for an unused entry */ entNo = initEntNo; /* start with the initial entry # for the - * bucket */ - luEntNo = initEntNo; /* use it as the initial 'least used' entry */ + * bucket */ + luEntNo = initEntNo; /* use it as the initial 'least used' entry */ for (ix = 0; ix < stmtCacheEntPerBucket; ++ix) { entry = &stmtCacheEntries[entNo]; - if (!entry->stmtID[0]) /* unused entry - use it */ + if (!entry->stmtID[0]) /* unused entry - use it */ break; if (entry->execs < stmtCacheEntries[luEntNo].execs) - luEntNo = entNo; /* save new 'least used' entry */ - ++entNo; /* increment entry # */ + luEntNo = entNo; /* save new 'least used' entry */ + ++entNo; /* increment entry # */ } -/* if no unused entries were found - use the 'least used' entry found in the bucket */ - if (ix >= stmtCacheEntPerBucket) /* if no unused entries were found */ - entNo = luEntNo; /* re-use the 'least used' entry */ + /* + * if no unused entries were found, re-use the 'least used' entry found in + * the bucket + */ + if (ix >= stmtCacheEntPerBucket) + entNo = luEntNo; -/* 'entNo' is the entry to use - make sure its free */ + /* 'entNo' is the entry to use - make sure its free */ if (ecpg_freeStmtCacheEntry(lineno, compat, entNo) < 0) return -1; -/* add the query to the entry */ + /* add the query to the entry */ entry = &stmtCacheEntries[entNo]; entry->lineno = lineno; entry->ecpgQuery = ecpg_strdup(ecpgQuery, lineno); @@ -469,10 +554,10 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha { int entNo; - /* search the statement cache for this statement */ + /* search the statement cache for this statement */ entNo = SearchStmtCache(query); - /* if not found - add the statement to the cache */ + /* if not found - add the statement to the cache */ if (entNo) { char *stmtID; @@ -502,7 +587,9 @@ ecpg_auto_prepare(int lineno, const char *connection_name, const int compat, cha if (!ECPGprepare(lineno, connection_name, 0, stmtID, query)) return false; - if (AddStmtToCache(lineno, stmtID, connection_name, compat, query) < 0) + + entNo = AddStmtToCache(lineno, stmtID, connection_name, compat, query); + if (entNo < 0) return false; *name = ecpg_strdup(stmtID, lineno); diff --git a/src/interfaces/ecpg/ecpglib/sqlda.c b/src/interfaces/ecpg/ecpglib/sqlda.c index 317d22fa4ed..3fb0d829d37 100644 --- a/src/interfaces/ecpg/ecpglib/sqlda.c +++ b/src/interfaces/ecpg/ecpglib/sqlda.c @@ -16,7 +16,7 @@ #include "ecpgtype.h" #include "ecpglib.h" #include "ecpgerrno.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqlca.h" #include "sqlda-native.h" #include "sqlda-compat.h" @@ -107,9 +107,12 @@ sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, l case ECPGt_numeric: /* - * Let's align both the numeric struct and the digits array to - * int Unfortunately we need to do double work here to compute - * the size of the space needed for the numeric structure. + * We align the numeric struct to allow it to store a pointer, + * while the digits array is aligned to int (which seems like + * overkill, but let's keep compatibility here). + * + * Unfortunately we need to deconstruct the value twice to + * find out the digits array's size and then later fill it. */ ecpg_sqlda_align_add_size(offset, sizeof(NumericDigit *), sizeof(numeric), &offset, &next_offset); if (!PQgetisnull(res, row, i)) @@ -120,8 +123,8 @@ sqlda_common_total_size(const PGresult *res, int row, enum COMPAT_MODE compat, l num = PGTYPESnumeric_from_asc(val, NULL); if (!num) break; - if (num->ndigits) - ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset); + if (num->buf) + ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset); PGTYPESnumeric_free(num); } break; @@ -345,10 +348,10 @@ ecpg_set_compat_sqlda(int lineno, struct sqlda_compat **_sqlda, const PGresult * memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric)); - if (num->ndigits) + if (num->buf) { - ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset); - memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1); + ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset); + memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits); ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset; ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf); @@ -534,10 +537,10 @@ ecpg_set_native_sqlda(int lineno, struct sqlda_struct **_sqlda, const PGresult * memcpy(sqlda->sqlvar[i].sqldata, num, sizeof(numeric)); - if (num->ndigits) + if (num->buf) { - ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, &offset, &next_offset); - memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1); + ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->digits - num->buf + num->ndigits, &offset, &next_offset); + memcpy((char *) sqlda + offset, num->buf, num->digits - num->buf + num->ndigits); ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + offset; ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda + offset + (num->digits - num->buf); diff --git a/src/interfaces/ecpg/ecpglib/typename.c b/src/interfaces/ecpg/ecpglib/typename.c index 9da1cdf4c23..9251450f9e6 100644 --- a/src/interfaces/ecpg/ecpglib/typename.c +++ b/src/interfaces/ecpg/ecpglib/typename.c @@ -7,7 +7,7 @@ #include "ecpgtype.h" #include "ecpglib.h" -#include "extern.h" +#include "ecpglib_extern.h" #include "sqltypes.h" #include "sql3types.h" @@ -48,6 +48,8 @@ ecpg_type_name(enum ECPGttype typ) return "bool"; case ECPGt_varchar: return "varchar"; + case ECPGt_bytea: + return "bytea"; case ECPGt_char_variable: return "char"; case ECPGt_decimal: diff --git a/src/interfaces/ecpg/include/Makefile b/src/interfaces/ecpg/include/Makefile index e92e56f26f3..9c68bf3c477 100644 --- a/src/interfaces/ecpg/include/Makefile +++ b/src/interfaces/ecpg/include/Makefile @@ -14,7 +14,7 @@ install: all installdirs install-headers .PHONY: install-headers ecpg_headers = ecpgerrno.h ecpglib.h ecpgtype.h sqlca.h sql3types.h ecpg_informix.h \ - pgtypes_error.h pgtypes_numeric.h pgtypes_timestamp.h pgtypes_date.h pgtypes_interval.h \ + pgtypes_error.h pgtypes_numeric.h pgtypes_timestamp.h pgtypes_date.h pgtypes_interval.h pgtypes.h \ sqlda.h sqlda-compat.h sqlda-native.h informix_headers = datetime.h decimal.h sqltypes.h diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index 8a601996d2d..a9bc584cd8d 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -59,8 +59,6 @@ char *ECPGprepared_statement(const char *, const char *, int); PGconn *ECPGget_PGconn(const char *); PGTransactionStatusType ECPGtransactionStatus(const char *); -char *ECPGerrmsg(void); - /* print an error message */ void sqlprint(void); diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 38fb3b6eaf5..3a575081e4f 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -63,7 +63,8 @@ enum ECPGttype ECPGt_EORT, /* End of result types. */ ECPGt_NO_INDICATOR, /* no indicator */ ECPGt_string, /* trimmed (char *) type */ - ECPGt_sqlda /* C struct descriptor */ + ECPGt_sqlda, /* C struct descriptor */ + ECPGt_bytea }; /* descriptor items */ @@ -88,7 +89,7 @@ enum ECPGdtype ECPGd_cardinality }; -#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string)) +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string) || ((type) == ECPGt_bytea)) /* we also have to handle different statement types */ enum ECPG_statement_type @@ -96,7 +97,9 @@ enum ECPG_statement_type ECPGst_normal, ECPGst_execute, ECPGst_exec_immediate, - ECPGst_prepnormal + ECPGst_prepnormal, + ECPGst_prepare, + ECPGst_exec_with_exprlist }; #ifdef __cplusplus diff --git a/src/interfaces/ecpg/include/pgtypes.h b/src/interfaces/ecpg/include/pgtypes.h new file mode 100644 index 00000000000..dbf759b45f5 --- /dev/null +++ b/src/interfaces/ecpg/include/pgtypes.h @@ -0,0 +1,17 @@ +/* src/interfaces/ecpg/include/pgtypes.h */ + +#ifndef PGTYPES_H +#define PGTYPES_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void PGTYPESchar_free(char *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* PGTYPES_H */ diff --git a/src/interfaces/ecpg/include/pgtypes_date.h b/src/interfaces/ecpg/include/pgtypes_date.h index caf8a33d125..c668097466e 100644 --- a/src/interfaces/ecpg/include/pgtypes_date.h +++ b/src/interfaces/ecpg/include/pgtypes_date.h @@ -3,6 +3,7 @@ #ifndef PGTYPES_DATETIME #define PGTYPES_DATETIME +#include #include typedef long date; diff --git a/src/interfaces/ecpg/include/pgtypes_interval.h b/src/interfaces/ecpg/include/pgtypes_interval.h index 5747736fe16..3b17cd1d115 100644 --- a/src/interfaces/ecpg/include/pgtypes_interval.h +++ b/src/interfaces/ecpg/include/pgtypes_interval.h @@ -4,6 +4,7 @@ #define PGTYPES_INTERVAL #include +#include #ifndef C_H diff --git a/src/interfaces/ecpg/include/pgtypes_numeric.h b/src/interfaces/ecpg/include/pgtypes_numeric.h index 56c46ea2729..5c763a9eb61 100644 --- a/src/interfaces/ecpg/include/pgtypes_numeric.h +++ b/src/interfaces/ecpg/include/pgtypes_numeric.h @@ -1,6 +1,8 @@ #ifndef PGTYPES_NUMERIC #define PGTYPES_NUMERIC +#include + #define NUMERIC_POS 0x0000 #define NUMERIC_NEG 0x4000 #define NUMERIC_NAN 0xC000 diff --git a/src/interfaces/ecpg/include/pgtypes_timestamp.h b/src/interfaces/ecpg/include/pgtypes_timestamp.h index 1545be4ee9b..3e298378912 100644 --- a/src/interfaces/ecpg/include/pgtypes_timestamp.h +++ b/src/interfaces/ecpg/include/pgtypes_timestamp.h @@ -3,6 +3,7 @@ #ifndef PGTYPES_TIMESTAMP #define PGTYPES_TIMESTAMP +#include /* pgtypes_interval.h includes ecpg_config.h */ #include diff --git a/src/interfaces/ecpg/include/sqlda-compat.h b/src/interfaces/ecpg/include/sqlda-compat.h index 7393182aa95..7b0ac45c42f 100644 --- a/src/interfaces/ecpg/include/sqlda-compat.h +++ b/src/interfaces/ecpg/include/sqlda-compat.h @@ -1,5 +1,5 @@ /* - * pgsql/src/interfaces/ecpg/include/sqlda-infx-compat.h + * src/interfaces/ecpg/include/sqlda-compat.h */ #ifndef ECPG_SQLDA_COMPAT_H diff --git a/src/interfaces/ecpg/pgtypeslib/.gitignore b/src/interfaces/ecpg/pgtypeslib/.gitignore index d5f0fae445a..91402ad88b3 100644 --- a/src/interfaces/ecpg/pgtypeslib/.gitignore +++ b/src/interfaces/ecpg/pgtypeslib/.gitignore @@ -1,8 +1,3 @@ /pgtypeslib.def /blibpgtypesdll.def /exports.list -/pgstrcasecmp.c -/rint.c -/snprintf.c -/string.c -/strnlen.c diff --git a/src/interfaces/ecpg/pgtypeslib/Makefile b/src/interfaces/ecpg/pgtypeslib/Makefile index 29264ce7b7b..fcc18c193cd 100644 --- a/src/interfaces/ecpg/pgtypeslib/Makefile +++ b/src/interfaces/ecpg/pgtypeslib/Makefile @@ -2,7 +2,7 @@ # # Makefile for ecpg pgtypes library # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/interfaces/ecpg/pgtypeslib/Makefile @@ -22,17 +22,12 @@ override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ -DFRONTEND $(CPPFLAGS) override CFLAGS += $(PTHREAD_CFLAGS) -# Need to recompile any libpgport object files -LIBS := $(filter-out -lpgport, $(LIBS)) - -SHLIB_LINK += $(filter -lm, $(LIBS)) +SHLIB_LINK_INTERNAL = -lpgcommon_shlib -lpgport_shlib +SHLIB_LINK += $(filter -lintl -lm, $(LIBS)) SHLIB_EXPORTS = exports.txt OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o \ - pgstrcasecmp.o \ - $(filter rint.o snprintf.o strnlen.o, $(LIBOBJS)) \ - string.o \ $(WIN32RES) all: all-lib @@ -40,17 +35,6 @@ all: all-lib # Shared library stuff include $(top_srcdir)/src/Makefile.shlib -# We use some port modules verbatim, but since we need to -# compile with appropriate options to build a shared lib, we can't -# necessarily use the same object files as the backend uses. Instead, -# symlink the source files in here and build our own object file. - -pgstrcasecmp.c rint.c snprintf.c strnlen.c: % : $(top_srcdir)/src/port/% - rm -f $@ && $(LN_S) $< . - -string.c: % : $(top_srcdir)/src/common/% - rm -f $@ && $(LN_S) $< . - install: all installdirs install-lib installdirs: installdirs-lib @@ -58,6 +42,6 @@ installdirs: installdirs-lib uninstall: uninstall-lib clean distclean: clean-lib - rm -f $(OBJS) pgstrcasecmp.c rint.c snprintf.c strnlen.c string.c + rm -f $(OBJS) maintainer-clean: distclean maintainer-clean-lib diff --git a/src/interfaces/ecpg/pgtypeslib/common.c b/src/interfaces/ecpg/pgtypeslib/common.c index ae29b6c4ab8..abcf7f5dbef 100644 --- a/src/interfaces/ecpg/pgtypeslib/common.c +++ b/src/interfaces/ecpg/pgtypeslib/common.c @@ -2,7 +2,8 @@ #include "postgres_fe.h" -#include "extern.h" +#include "pgtypeslib_extern.h" +#include "pgtypes.h" /* Return value is zero-filled. */ char * @@ -42,10 +43,8 @@ pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **outp i = strlen(replace_val.str_val); if (i + 1 <= *pstr_len) { - /* - * copy over i + 1 bytes, that includes the tailing terminator - */ - strncpy(*output, replace_val.str_val, i + 1); + /* include trailing terminator in what we copy */ + memcpy(*output, replace_val.str_val, i + 1); *pstr_len -= i; *output += i; if (replace_type == PGTYPES_TYPE_STRING_MALLOCED) @@ -111,7 +110,7 @@ pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **outp break; } - if (i < 0) + if (i < 0 || i >= PGTYPES_FMT_NUM_MAX_DIGITS) { free(t); return -1; @@ -138,3 +137,12 @@ pgtypes_fmt_replace(union un_fmt_comb replace_val, int replace_type, char **outp } return 0; } + +/* Functions declared in pgtypes.h. */ + +/* Just frees memory (mostly needed for Windows) */ +void +PGTYPESchar_free(char *ptr) +{ + free(ptr); +} diff --git a/src/interfaces/ecpg/pgtypeslib/datetime.c b/src/interfaces/ecpg/pgtypeslib/datetime.c index 1e692a5f9ef..9ee460b9a1f 100644 --- a/src/interfaces/ecpg/pgtypeslib/datetime.c +++ b/src/interfaces/ecpg/pgtypeslib/datetime.c @@ -4,10 +4,9 @@ #include #include -#include #include -#include "extern.h" +#include "pgtypeslib_extern.h" #include "dt.h" #include "pgtypes_error.h" #include "pgtypes_date.h" @@ -624,7 +623,7 @@ PGTYPESdate_defmt_asc(date * d, const char *fmt, const char *str) /* * evil[tm] hack: if we read the pgtypes_date_months and haven't - * found a match, reset list to point to pgtypes_date_months_short + * found a match, reset list to point to months (abbreviations) * and reset the counter variable i */ if (list == pgtypes_date_months) diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h index 8cf03bfedfb..893c9b6194e 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt.h +++ b/src/interfaces/ecpg/pgtypeslib/dt.h @@ -5,6 +5,8 @@ #include +#include + #define MAXTZLEN 10 typedef int32 fsec_t; @@ -143,8 +145,6 @@ typedef int32 fsec_t; #define DTK_AGO 5 #define DTK_SPECIAL 6 -#define DTK_INVALID 7 -#define DTK_CURRENT 8 #define DTK_EARLY 9 #define DTK_LATE 10 #define DTK_EPOCH 11 @@ -327,15 +327,15 @@ void GetCurrentDateTime(struct tm *); int date2j(int, int, int); void TrimTrailingZeros(char *); void dt2time(double, int *, int *, int *, fsec_t *); -int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d, - int *year, int *month, int *day, - int *hour, int *minute, int *second, - int *tz); +int PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d, + int *year, int *month, int *day, + int *hour, int *minute, int *second, + int *tz); extern char *pgtypes_date_weekdays_short[]; extern char *pgtypes_date_months[]; extern char *months[]; extern char *days[]; -extern int day_tab[2][13]; +extern const int day_tab[2][13]; #endif /* DT_H */ diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c index 994389f4a16..e71defaa66a 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt_common.c +++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c @@ -6,17 +6,18 @@ #include #include -#include "extern.h" +#include "common/string.h" +#include "pgtypeslib_extern.h" #include "dt.h" #include "pgtypes_timestamp.h" -int day_tab[2][13] = { +const int day_tab[2][13] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0}}; typedef long AbsoluteTime; -static datetkn datetktbl[] = { +static const datetkn datetktbl[] = { /* text, token, lexval */ {EARLY, RESERV, DTK_EARLY}, /* "-infinity" reserved for "early time" */ {"acsst", DTZ, 37800}, /* Cent. Australia */ @@ -111,7 +112,6 @@ static datetkn datetktbl[] = { #endif {"cot", TZ, -18000}, /* Columbia Time */ {"cst", TZ, -21600}, /* Central Standard Time */ - {DCURRENT, RESERV, DTK_CURRENT}, /* "current" is always now */ #if 0 cvst #endif @@ -172,7 +172,7 @@ static datetkn datetktbl[] = { ghst #endif {"gilt", TZ, 43200}, /* Gilbert Islands Time */ - {"gmt", TZ, 0}, /* Greenwish Mean Time */ + {"gmt", TZ, 0}, /* Greenwich Mean Time */ {"gst", TZ, 36000}, /* Guam Std Time, USSR Zone 9 */ {"gyt", TZ, -14400}, /* Guyana Time */ {"h", UNITS, DTK_HOUR}, /* "hour" */ @@ -201,7 +201,6 @@ static datetkn datetktbl[] = { idt /* Israeli, Iran, Indian Daylight Time */ #endif {LATE, RESERV, DTK_LATE}, /* "infinity" reserved for "late time" */ - {INVALID, RESERV, DTK_INVALID}, /* "invalid" reserved for bad time */ {"iot", TZ, 18000}, /* Indian Chagos Time */ {"irkst", DTZ, 32400}, /* Irkutsk Summer Time */ {"irkt", TZ, 28800}, /* Irkutsk Time */ @@ -372,7 +371,6 @@ static datetkn datetktbl[] = { #endif {"ulast", DTZ, 32400}, /* Ulan Bator Summer Time */ {"ulat", TZ, 28800}, /* Ulan Bator Time */ - {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ {"ut", TZ, 0}, {"utc", TZ, 0}, {"uyst", DTZ, -7200}, /* Uruguay Summer Time */ @@ -420,7 +418,7 @@ static datetkn datetktbl[] = { {ZULU, TZ, 0}, /* UTC */ }; -static datetkn deltatktbl[] = { +static const datetkn deltatktbl[] = { /* text, token, lexval */ {"@", IGNORE_DTF, 0}, /* postgres relative prefix */ {DAGO, AGO, 0}, /* "ago" indicates negative time offset */ @@ -440,7 +438,6 @@ static datetkn deltatktbl[] = { {"hours", UNITS, DTK_HOUR}, /* "hours" relative */ {"hr", UNITS, DTK_HOUR}, /* "hour" relative */ {"hrs", UNITS, DTK_HOUR}, /* "hours" relative */ - {INVALID, RESERV, DTK_INVALID}, /* reserved for invalid time */ {"m", UNITS, DTK_MINUTE}, /* "minute" relative */ {"microsecon", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {"mil", UNITS, DTK_MILLENNIUM}, /* "millennium" relative */ @@ -471,7 +468,6 @@ static datetkn deltatktbl[] = { {DTIMEZONE, UNITS, DTK_TZ}, /* "timezone" time offset */ {"timezone_h", UNITS, DTK_TZ_HOUR}, /* timezone hour units */ {"timezone_m", UNITS, DTK_TZ_MINUTE}, /* timezone minutes units */ - {"undefined", RESERV, DTK_INVALID}, /* pre-v6.1 invalid time */ {"us", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {"usec", UNITS, DTK_MICROSEC}, /* "microsecond" relative */ {DMICROSEC, UNITS, DTK_MICROSEC}, /* "microsecond" relative */ @@ -490,9 +486,9 @@ static datetkn deltatktbl[] = { static const unsigned int szdatetktbl = lengthof(datetktbl); static const unsigned int szdeltatktbl = lengthof(deltatktbl); -static datetkn *datecache[MAXDATEFIELDS] = {NULL}; +static const datetkn *datecache[MAXDATEFIELDS] = {NULL}; -static datetkn *deltacache[MAXDATEFIELDS] = {NULL}; +static const datetkn *deltacache[MAXDATEFIELDS] = {NULL}; char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL}; @@ -502,12 +498,12 @@ char *pgtypes_date_weekdays_short[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fr char *pgtypes_date_months[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", NULL}; -static datetkn * -datebsearch(char *key, datetkn *base, unsigned int nel) +static const datetkn * +datebsearch(const char *key, const datetkn *base, unsigned int nel) { if (nel > 0) { - datetkn *last = base + nel - 1, + const datetkn *last = base + nel - 1, *position; int result; @@ -540,7 +536,7 @@ int DecodeUnits(int field, char *lowtoken, int *val) { int type; - datetkn *tp; + const datetkn *tp; /* use strncmp so that we match truncated tokens */ if (deltacache[field] != NULL && @@ -641,7 +637,7 @@ static int DecodeSpecial(int field, char *lowtoken, int *val) { int type; - datetkn *tp; + const datetkn *tp; /* use strncmp so that we match truncated tokens */ if (datecache[field] != NULL && @@ -833,7 +829,7 @@ EncodeDateTime(struct tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tz /* * Note: the uses of %.*s in this function would be risky if the * timezone names ever contain non-ASCII characters. However, all - * TZ abbreviations in the Olson database are plain ASCII. + * TZ abbreviations in the IANA database are plain ASCII. */ if (print_tz) @@ -1115,7 +1111,7 @@ DecodeNumberField(int len, char *str, int fmask, for (i = 0; i < 6; i++) fstr[i] = *cp != '\0' ? *cp++ : '0'; fstr[i] = '\0'; - *fsec = strtol(fstr, NULL, 10); + *fsec = strtoint(fstr, NULL, 10); *cp = '\0'; len = strlen(str); } @@ -1206,7 +1202,7 @@ DecodeNumber(int flen, char *str, int fmask, *tmask = 0; - val = strtol(str, &cp, 10); + val = strtoint(str, &cp, 10); if (cp == str) return -1; @@ -1442,11 +1438,11 @@ DecodeTime(char *str, int *tmask, struct tm *tm, fsec_t *fsec) *tmask = DTK_TIME_M; - tm->tm_hour = strtol(str, &cp, 10); + tm->tm_hour = strtoint(str, &cp, 10); if (*cp != ':') return -1; str = cp + 1; - tm->tm_min = strtol(str, &cp, 10); + tm->tm_min = strtoint(str, &cp, 10); if (*cp == '\0') { tm->tm_sec = 0; @@ -1457,7 +1453,7 @@ DecodeTime(char *str, int *tmask, struct tm *tm, fsec_t *fsec) else { str = cp + 1; - tm->tm_sec = strtol(str, &cp, 10); + tm->tm_sec = strtoint(str, &cp, 10); if (*cp == '\0') *fsec = 0; else if (*cp == '.') @@ -1478,7 +1474,7 @@ DecodeTime(char *str, int *tmask, struct tm *tm, fsec_t *fsec) for (i = 0; i < 6; i++) fstr[i] = *cp != '\0' ? *cp++ : '0'; fstr[i] = '\0'; - *fsec = strtol(fstr, &cp, 10); + *fsec = strtoint(fstr, &cp, 10); if (*cp != '\0') return -1; } @@ -1510,20 +1506,20 @@ DecodeTimezone(char *str, int *tzp) int len; /* assume leading character is "+" or "-" */ - hr = strtol(str + 1, &cp, 10); + hr = strtoint(str + 1, &cp, 10); /* explicit delimiter? */ if (*cp == ':') - min = strtol(cp + 1, &cp, 10); + min = strtoint(cp + 1, &cp, 10); /* otherwise, might have run things together... */ else if (*cp == '\0' && (len = strlen(str)) > 3) { - min = strtol(str + len - 2, &cp, 10); + min = strtoint(str + len - 2, &cp, 10); if (min < 0 || min >= 60) return -1; *(str + len - 2) = '\0'; - hr = strtol(str + 1, &cp, 10); + hr = strtoint(str + 1, &cp, 10); if (hr < 0 || hr > 13) return -1; } @@ -1830,7 +1826,7 @@ DecodeDateTime(char **field, int *ftype, int nf, if (tzp == NULL) return -1; - val = strtol(field[i], &cp, 10); + val = strtoint(field[i], &cp, 10); if (*cp != '-') return -1; @@ -1965,7 +1961,7 @@ DecodeDateTime(char **field, int *ftype, int nf, char *cp; int val; - val = strtol(field[i], &cp, 10); + val = strtoint(field[i], &cp, 10); /* * only a few kinds are allowed to have an embedded diff --git a/src/interfaces/ecpg/pgtypeslib/exports.txt b/src/interfaces/ecpg/pgtypeslib/exports.txt index 70ef01a8a7d..2d5ec17656a 100644 --- a/src/interfaces/ecpg/pgtypeslib/exports.txt +++ b/src/interfaces/ecpg/pgtypeslib/exports.txt @@ -45,3 +45,4 @@ PGTYPEStimestamp_from_asc 42 PGTYPEStimestamp_sub 43 PGTYPEStimestamp_sub_interval 44 PGTYPEStimestamp_to_asc 45 +PGTYPESchar_free 46 diff --git a/src/interfaces/ecpg/pgtypeslib/interval.c b/src/interfaces/ecpg/pgtypeslib/interval.c index 0510f5289c8..3ff8a1025a3 100644 --- a/src/interfaces/ecpg/pgtypeslib/interval.c +++ b/src/interfaces/ecpg/pgtypeslib/interval.c @@ -11,7 +11,7 @@ #include "common/string.h" -#include "extern.h" +#include "pgtypeslib_extern.h" #include "dt.h" #include "pgtypes_error.h" #include "pgtypes_interval.h" @@ -184,6 +184,7 @@ DecodeISO8601Interval(char *str, continue; } /* Else fall through to extended alternative format */ + /* FALLTHROUGH */ case '-': /* ISO 8601 4.4.3.3 Alternative Format, * Extended */ if (havefield) @@ -262,6 +263,7 @@ DecodeISO8601Interval(char *str, return 0; } /* Else fall through to extended alternative format */ + /* FALLTHROUGH */ case ':': /* ISO 8601 4.4.3.3 Alternative Format, * Extended */ if (havefield) diff --git a/src/interfaces/ecpg/pgtypeslib/numeric.c b/src/interfaces/ecpg/pgtypeslib/numeric.c index 6643242ab19..22088bae8e4 100644 --- a/src/interfaces/ecpg/pgtypeslib/numeric.c +++ b/src/interfaces/ecpg/pgtypeslib/numeric.c @@ -5,7 +5,7 @@ #include #include -#include "extern.h" +#include "pgtypeslib_extern.h" #include "pgtypes_error.h" #define Max(x, y) ((x) > (y) ? (x) : (y)) diff --git a/src/interfaces/ecpg/pgtypeslib/extern.h b/src/interfaces/ecpg/pgtypeslib/pgtypeslib_extern.h similarity index 87% rename from src/interfaces/ecpg/pgtypeslib/extern.h rename to src/interfaces/ecpg/pgtypeslib/pgtypeslib_extern.h index 9df800ea1d5..7e7626a3cc1 100644 --- a/src/interfaces/ecpg/pgtypeslib/extern.h +++ b/src/interfaces/ecpg/pgtypeslib/pgtypeslib_extern.h @@ -1,7 +1,7 @@ -/* src/interfaces/ecpg/pgtypeslib/extern.h */ +/* src/interfaces/ecpg/pgtypeslib/pgtypeslib_extern.h */ -#ifndef __PGTYPES_COMMON_H__ -#define __PGTYPES_COMMON_H__ +#ifndef _ECPG_PGTYPESLIB_EXTERN_H +#define _ECPG_PGTYPESLIB_EXTERN_H #include "pgtypes_error.h" @@ -50,4 +50,4 @@ char *pgtypes_strdup(const char *); #define TRUE 1 #endif /* TRUE */ -#endif /* __PGTYPES_COMMON_H__ */ +#endif /* _ECPG_PGTYPESLIB_EXTERN_H */ diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c index abccc268dcc..e830ee737e7 100644 --- a/src/interfaces/ecpg/pgtypeslib/timestamp.c +++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c @@ -4,7 +4,6 @@ #include "postgres_fe.h" #include -#include #include #include @@ -12,7 +11,7 @@ #error -ffast-math is known to break this code #endif -#include "extern.h" +#include "pgtypeslib_extern.h" #include "dt.h" #include "pgtypes_timestamp.h" #include "pgtypes_date.h" @@ -254,10 +253,6 @@ PGTYPEStimestamp_from_asc(char *str, char **endptr) TIMESTAMP_NOBEGIN(result); break; - case DTK_INVALID: - errno = PGTYPES_TS_BAD_TIMESTAMP; - return noresult; - default: errno = PGTYPES_TS_BAD_TIMESTAMP; return noresult; @@ -280,8 +275,8 @@ PGTYPEStimestamp_to_asc(timestamp tstamp) *tm = &tt; char buf[MAXDATELEN + 1]; fsec_t fsec; - int DateStyle = 1; /* this defaults to ISO_DATES, shall we make - * it an option? */ + int DateStyle = 1; /* this defaults to USE_ISO_DATES, shall we + * make it an option? */ if (TIMESTAMP_NOT_FINITE(tstamp)) EncodeSpecialTimestamp(tstamp, buf); diff --git a/src/interfaces/ecpg/preproc/.gitignore b/src/interfaces/ecpg/preproc/.gitignore index aacfb844bda..958a826f9e8 100644 --- a/src/interfaces/ecpg/preproc/.gitignore +++ b/src/interfaces/ecpg/preproc/.gitignore @@ -2,5 +2,7 @@ /preproc.c /preproc.h /pgc.c - +/c_kwlist_d.h +/ecpg_kwlist_d.h +/typename.c /ecpg diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile index b0c404e41ed..2ec10236263 100644 --- a/src/interfaces/ecpg/preproc/Makefile +++ b/src/interfaces/ecpg/preproc/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/interfaces/ecpg/preproc # -# Copyright (c) 1998-2018, PostgreSQL Global Development Group +# Copyright (c) 1998-2019, PostgreSQL Global Development Group # # src/interfaces/ecpg/preproc/Makefile # @@ -16,15 +16,22 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I../include -I$(top_srcdir)/src/interfaces/ecpg/include \ - -I. -I$(srcdir) -DECPG_COMPILE \ - $(CPPFLAGS) + -I. -I$(srcdir) \ + -I$(top_srcdir)/src/interfaces/ecpg/ecpglib \ + -I$(libpq_srcdir) \ + $(CPPFLAGS) override CFLAGS += $(PTHREAD_CFLAGS) OBJS= preproc.o pgc.o type.o ecpg.o output.o parser.o \ - keywords.o c_keywords.o ecpg_keywords.o ../ecpglib/typename.o descriptor.o variable.o \ + keywords.o c_keywords.o ecpg_keywords.o typename.o descriptor.o variable.o \ $(WIN32RES) +# where to find gen_keywordlist.pl and subsidiary files +TOOLSDIR = $(top_srcdir)/src/tools +GEN_KEYWORDLIST = $(PERL) -I $(TOOLSDIR) $(TOOLSDIR)/gen_keywordlist.pl +GEN_KEYWORDLIST_DEPS = $(TOOLSDIR)/gen_keywordlist.pl $(TOOLSDIR)/PerfectHash.pm + # Suppress parallel build to avoid a bug in GNU make 3.82 # (see comments in ../Makefile) ifeq ($(MAKE_VERSION),3.82) @@ -34,10 +41,11 @@ endif all: ecpg ecpg: $(OBJS) | submake-libpgport - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $^ $(LIBS) $(PTHREAD_LIBS) -o $@$(X) + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) $(PTHREAD_LIBS) -o $@$(X) -../ecpglib/typename.o: ../ecpglib/typename.c - $(MAKE) -C $(dir $@) $(notdir $@) +# We symlink typename.c from ecpglib and recompile it here +typename.c: % : $(top_srcdir)/src/interfaces/ecpg/ecpglib/% + rm -f $@ && $(LN_S) $< . # See notes in src/backend/parser/Makefile about the following two rules preproc.h: preproc.c @@ -49,9 +57,20 @@ preproc.y: ../../../backend/parser/gram.y parse.pl ecpg.addons ecpg.header ecpg. $(PERL) $(srcdir)/parse.pl $(srcdir) < $< > $@ $(PERL) $(srcdir)/check_rules.pl $(srcdir) $< +# generate keyword headers +c_kwlist_d.h: c_kwlist.h $(GEN_KEYWORDLIST_DEPS) + $(GEN_KEYWORDLIST) --varname ScanCKeywords --no-case-fold $< + +ecpg_kwlist_d.h: ecpg_kwlist.h $(GEN_KEYWORDLIST_DEPS) + $(GEN_KEYWORDLIST) --varname ScanECPGKeywords $< + +# Force these dependencies to be known even without dependency info built: ecpg_keywords.o c_keywords.o keywords.o preproc.o pgc.o parser.o: preproc.h +ecpg_keywords.o: ecpg_kwlist_d.h +c_keywords.o: c_kwlist_d.h +keywords.o: $(top_srcdir)/src/include/parser/kwlist.h -distprep: preproc.y preproc.c preproc.h pgc.c +distprep: preproc.y preproc.c preproc.h pgc.c c_kwlist_d.h ecpg_kwlist_d.h install: all installdirs $(INSTALL_PROGRAM) ecpg$(X) '$(DESTDIR)$(bindir)' @@ -62,13 +81,11 @@ installdirs: uninstall: rm -f '$(DESTDIR)$(bindir)/ecpg$(X)' +# preproc.y, preproc.c, preproc.h, pgc.c, c_kwlist_d.h, and ecpg_kwlist_d.h +# are in the distribution tarball, so they are not cleaned here. clean distclean: rm -f *.o ecpg$(X) -# garbage from development - @rm -f core a.out + rm -f typename.c -# `make distclean' must not remove preproc.y, preproc.c, preproc.h, or pgc.c -# since we want to ship those files in the distribution for people with -# inadequate tools. Instead, `make maintainer-clean' will remove them. maintainer-clean: distclean - rm -f preproc.y preproc.c preproc.h pgc.c + rm -f preproc.y preproc.c preproc.h pgc.c c_kwlist_d.h ecpg_kwlist_d.h diff --git a/src/interfaces/ecpg/preproc/c_keywords.c b/src/interfaces/ecpg/preproc/c_keywords.c index 06bf0390994..80aa7d5339c 100644 --- a/src/interfaces/ecpg/preproc/c_keywords.c +++ b/src/interfaces/ecpg/preproc/c_keywords.c @@ -9,77 +9,59 @@ */ #include "postgres_fe.h" -#include - -#include "extern.h" +#include "preproc_extern.h" #include "preproc.h" -/* - * List of (keyword-name, keyword-token-value) pairs. - * - * !!WARNING!!: This list must be sorted, because binary - * search is used to locate entries. - */ -static const ScanKeyword ScanCKeywords[] = { - /* name, value, category */ +/* ScanKeywordList lookup data for C keywords */ +#include "c_kwlist_d.h" - /* - * category is not needed in ecpg, it is only here so we can share the - * data structure with the backend - */ - {"VARCHAR", VARCHAR, 0}, - {"auto", S_AUTO, 0}, - {"bool", SQL_BOOL, 0}, - {"char", CHAR_P, 0}, - {"const", S_CONST, 0}, - {"enum", ENUM_P, 0}, - {"extern", S_EXTERN, 0}, - {"float", FLOAT_P, 0}, - {"hour", HOUR_P, 0}, - {"int", INT_P, 0}, - {"long", SQL_LONG, 0}, - {"minute", MINUTE_P, 0}, - {"month", MONTH_P, 0}, - {"register", S_REGISTER, 0}, - {"second", SECOND_P, 0}, - {"short", SQL_SHORT, 0}, - {"signed", SQL_SIGNED, 0}, - {"static", S_STATIC, 0}, - {"struct", SQL_STRUCT, 0}, - {"to", TO, 0}, - {"typedef", S_TYPEDEF, 0}, - {"union", UNION, 0}, - {"unsigned", SQL_UNSIGNED, 0}, - {"varchar", VARCHAR, 0}, - {"volatile", S_VOLATILE, 0}, - {"year", YEAR_P, 0}, +/* Token codes for C keywords */ +#define PG_KEYWORD(kwname, value) value, + +static const uint16 ScanCKeywordTokens[] = { +#include "c_kwlist.h" }; +#undef PG_KEYWORD + /* - * Do a binary search using plain strcmp() comparison. This is much like + * ScanCKeywordLookup - see if a given word is a keyword + * + * Returns the token value of the keyword, or -1 if no match. + * + * Do a hash search using plain strcmp() comparison. This is much like * ScanKeywordLookup(), except we want case-sensitive matching. */ -const ScanKeyword * -ScanCKeywordLookup(const char *text) +int +ScanCKeywordLookup(const char *str) { - const ScanKeyword *low = &ScanCKeywords[0]; - const ScanKeyword *high = &ScanCKeywords[lengthof(ScanCKeywords) - 1]; + size_t len; + int h; + const char *kw; + + /* + * Reject immediately if too long to be any keyword. This saves useless + * hashing work on long strings. + */ + len = strlen(str); + if (len > ScanCKeywords.max_kw_len) + return -1; + + /* + * Compute the hash function. Since it's a perfect hash, we need only + * match to the specific keyword it identifies. + */ + h = ScanCKeywords_hash_func(str, len); + + /* An out-of-range result implies no match */ + if (h < 0 || h >= ScanCKeywords.num_keywords) + return -1; - while (low <= high) - { - const ScanKeyword *middle; - int difference; + kw = GetScanKeyword(h, &ScanCKeywords); - middle = low + (high - low) / 2; - difference = strcmp(middle->name, text); - if (difference == 0) - return middle; - else if (difference < 0) - low = middle + 1; - else - high = middle - 1; - } + if (strcmp(kw, str) == 0) + return ScanCKeywordTokens[h]; - return NULL; + return -1; } diff --git a/src/interfaces/ecpg/preproc/c_kwlist.h b/src/interfaces/ecpg/preproc/c_kwlist.h new file mode 100644 index 00000000000..610a4b1e053 --- /dev/null +++ b/src/interfaces/ecpg/preproc/c_kwlist.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * c_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/ecpg/preproc/c_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef C_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("VARCHAR", VARCHAR) +PG_KEYWORD("auto", S_AUTO) +PG_KEYWORD("bool", SQL_BOOL) +PG_KEYWORD("char", CHAR_P) +PG_KEYWORD("const", S_CONST) +PG_KEYWORD("enum", ENUM_P) +PG_KEYWORD("extern", S_EXTERN) +PG_KEYWORD("float", FLOAT_P) +PG_KEYWORD("hour", HOUR_P) +PG_KEYWORD("int", INT_P) +PG_KEYWORD("long", SQL_LONG) +PG_KEYWORD("minute", MINUTE_P) +PG_KEYWORD("month", MONTH_P) +PG_KEYWORD("register", S_REGISTER) +PG_KEYWORD("second", SECOND_P) +PG_KEYWORD("short", SQL_SHORT) +PG_KEYWORD("signed", SQL_SIGNED) +PG_KEYWORD("static", S_STATIC) +PG_KEYWORD("struct", SQL_STRUCT) +PG_KEYWORD("to", TO) +PG_KEYWORD("typedef", S_TYPEDEF) +PG_KEYWORD("union", UNION) +PG_KEYWORD("unsigned", SQL_UNSIGNED) +PG_KEYWORD("varchar", VARCHAR) +PG_KEYWORD("volatile", S_VOLATILE) +PG_KEYWORD("year", YEAR_P) diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl index 4c2151c1b68..a03474fcff1 100644 --- a/src/interfaces/ecpg/preproc/check_rules.pl +++ b/src/interfaces/ecpg/preproc/check_rules.pl @@ -1,9 +1,9 @@ #!/usr/bin/perl # src/interfaces/ecpg/preproc/check_rules.pl -# test parser generater for ecpg -# call with backend parser as stdin +# test parser generator for ecpg +# call with backend grammar as stdin # -# Copyright (c) 2009-2018, PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group # # Written by Michael Meskes # Andy Colson @@ -39,14 +39,18 @@ 'ExecuteStmtEXECUTEnameexecute_param_clause' => 'EXECUTE prepared_name execute_param_clause execute_rest', -'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause' - => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause', + 'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' + => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest', + + 'ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' + => 'CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest', 'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' => 'PREPARE prepared_name prep_type_clause AS PreparableStmt'); my $block = ''; my $yaccmode = 0; +my $in_rule = 0; my $brace_indent = 0; my (@arr, %found); my $comment = 0; @@ -131,10 +135,14 @@ $found{$block} = 1; $cc++; $block = ''; + $in_rule = 0 if $arr[$fieldIndexer] eq ';'; } elsif (($arr[$fieldIndexer] =~ '[A-Za-z0-9]+:') || $arr[ $fieldIndexer + 1 ] eq ':') { + die "unterminated rule at grammar line $.\n" + if $in_rule; + $in_rule = 1; $non_term_id = $arr[$fieldIndexer]; $non_term_id =~ tr/://d; } @@ -145,6 +153,9 @@ } } +die "unterminated rule at end of grammar\n" + if $in_rule; + close $parser_fh; if ($verbose) { diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index 729f063f62e..a29f5303273 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -9,7 +9,7 @@ #include "postgres_fe.h" -#include "extern.h" +#include "preproc_extern.h" /* * assignment handling function (descriptor) diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons index ca3efadc481..300381eaad5 100644 --- a/src/interfaces/ecpg/preproc/ecpg.addons +++ b/src/interfaces/ecpg/preproc/ecpg.addons @@ -22,7 +22,7 @@ ECPG: stmtDeallocateStmt block output_deallocate_prepare_statement($1); } ECPG: stmtDeclareCursorStmt block - { output_simple_statement($1); } + { output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); } ECPG: stmtDiscardStmt block ECPG: stmtFetchStmt block { output_statement($1, 1, ECPGst_normal); } @@ -32,13 +32,54 @@ ECPG: stmtSelectStmt block ECPG: stmtUpdateStmt block { output_statement($1, 1, ECPGst_prepnormal); } ECPG: stmtExecuteStmt block - { output_statement($1, 1, ECPGst_execute); } -ECPG: stmtPrepareStmt block { if ($1.type == NULL || strlen($1.type) == 0) + output_statement($1.name, 1, ECPGst_execute); + else + { + if ($1.name[0] != '"') + /* case of char_variable */ + add_variable_to_tail(&argsinsert, find_variable($1.name), &no_indicator); + else + { + /* case of ecpg_ident or CSTRING */ + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *str = mm_strdup($1.name + 1); + + /* It must be cut off double quotation because new_variable() double-quotes. */ + str[strlen(str) - 1] = '\0'; + sprintf(length, "%zu", strlen(str)); + add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); + } + output_statement(cat_str(3, mm_strdup("execute"), mm_strdup("$0"), $1.type), 0, ECPGst_exec_with_exprlist); + } + } +ECPG: stmtPrepareStmt block + { + if ($1.type == NULL) output_prepare_statement($1.name, $1.stmt); + else if (strlen($1.type) == 0) + { + char *stmt = cat_str(3, mm_strdup("\""), $1.stmt, mm_strdup("\"")); + output_prepare_statement($1.name, stmt); + } else - output_statement(cat_str(5, mm_strdup("prepare"), $1.name, $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_normal); + { + if ($1.name[0] != '"') + /* case of char_variable */ + add_variable_to_tail(&argsinsert, find_variable($1.name), &no_indicator); + else + { + char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); + char *str = mm_strdup($1.name + 1); + + /* It must be cut off double quotation because new_variable() double-quotes. */ + str[strlen(str) - 1] = '\0'; + sprintf(length, "%zu", strlen(str)); + add_variable_to_tail(&argsinsert, new_variable(str, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); + } + output_statement(cat_str(5, mm_strdup("prepare"), mm_strdup("$0"), $1.type, mm_strdup("as"), $1.stmt), 0, ECPGst_prepare); + } } ECPG: stmtTransactionStmt block { @@ -65,7 +106,7 @@ ECPG: stmtViewStmt rule } | ECPGCursorStmt { - output_simple_statement($1); + output_simple_statement($1, (strncmp($1, "ECPGset_var", strlen("ECPGset_var")) == 0) ? 4 : 0); } | ECPGDeallocateDescr { @@ -75,7 +116,7 @@ ECPG: stmtViewStmt rule } | ECPGDeclare { - output_simple_statement($1); + output_simple_statement($1, 0); } | ECPGDescribe { @@ -178,21 +219,21 @@ ECPG: stmtViewStmt rule if (connection) mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in VAR statement"); - output_simple_statement($1); + output_simple_statement($1, 0); } | ECPGWhenever { if (connection) mmerror(PARSE_ERROR, ET_ERROR, "AT option not allowed in WHENEVER statement"); - output_simple_statement($1); + output_simple_statement($1, 0); } ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block { char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4; $$ = cat_str(2,mm_strdup("where current of"), cursor_marker); } -ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_options addon +ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listcopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_optionswhere_clause addon if (strcmp($6, "from") == 0 && (strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0)) mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented"); @@ -271,11 +312,15 @@ ECPG: cursor_namename rule $1 = curname; $$ = $1; } +ECPG: ExplainableStmtExecuteStmt block + { + $$ = $1.name; + } ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block { $$.name = $2; $$.type = $3; - $$.stmt = cat_str(3, mm_strdup("\""), $5, mm_strdup("\"")); + $$.stmt = $5; } | PREPARE prepared_name FROM execstring { @@ -284,7 +329,18 @@ ECPG: PrepareStmtPREPAREprepared_nameprep_type_clauseASPreparableStmt block $$.stmt = $4; } ECPG: ExecuteStmtEXECUTEprepared_nameexecute_param_clauseexecute_rest block - { $$ = $2; } + { + $$.name = $2; + $$.type = $3; + } +ECPG: ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block + { + $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table"),$4,mm_strdup("as execute"),$7,$8,$9); + } +ECPG: ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEprepared_nameexecute_param_clauseopt_with_dataexecute_rest block + { + $$.name = cat_str(8,mm_strdup("create"),$2,mm_strdup("table if not exists"),$7,mm_strdup("as execute"),$10,$11,$12); + } ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectStmt block { struct cursor *ptr, *this; @@ -327,12 +383,7 @@ ECPG: DeclareCursorStmtDECLAREcursor_namecursor_optionsCURSORopt_holdFORSelectSt } comment = cat_str(3, mm_strdup("/*"), c1, mm_strdup("*/")); - if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */ - $$ = cat_str(3, adjust_outofscope_cursor_vars(this), - mm_strdup("ECPG_informix_reset_sqlca();"), - comment); - else - $$ = cat2_str(adjust_outofscope_cursor_vars(this), comment); + $$ = cat2_str(adjust_outofscope_cursor_vars(this), comment); } ECPG: ClosePortalStmtCLOSEcursor_name block { diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c index 8fb731fcfb1..ee6e634e456 100644 --- a/src/interfaces/ecpg/preproc/ecpg.c +++ b/src/interfaces/ecpg/preproc/ecpg.c @@ -1,7 +1,7 @@ /* src/interfaces/ecpg/preproc/ecpg.c */ /* Main for ecpg, the PostgreSQL embedded SQL precompiler. */ -/* Copyright (c) 1996-2018, PostgreSQL Global Development Group */ +/* Copyright (c) 1996-2019, PostgreSQL Global Development Group */ #include "postgres_fe.h" @@ -9,7 +9,7 @@ #include "getopt_long.h" -#include "extern.h" +#include "preproc_extern.h" int ret_value = 0; bool autocommit = false, @@ -58,7 +58,7 @@ help(const char *progname) printf(_(" -?, --help show this help, then exit\n")); printf(_("\nIf no output file is specified, the name is formed by adding .c to the\n" "input file name, after stripping off .pgc if present.\n")); - printf(_("\nReport bugs to .\n")); + printf(_("\nReport bugs to .\n")); } static void @@ -98,13 +98,13 @@ add_preprocessor_define(char *define) /* symbol has a value */ for (tmp = ptr - 1; *tmp == ' '; tmp--); tmp[1] = '\0'; - defines->old = define_copy; - defines->new = ptr + 1; + defines->olddef = define_copy; + defines->newdef = ptr + 1; } else { - defines->old = define_copy; - defines->new = mm_strdup("1"); + defines->olddef = define_copy; + defines->newdef = mm_strdup("1"); } defines->pertinent = true; defines->used = NULL; @@ -149,7 +149,7 @@ main(int argc, char *const argv[]) } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { - printf("ecpg %s\n", PG_VERSION); + printf("ecpg (PostgreSQL) %s\n", PG_VERSION); exit(0); } } @@ -189,8 +189,8 @@ main(int argc, char *const argv[]) break; case 'h': header_mode = true; - /* this must include "-c" to make sense */ - /* so do not place a "break;" here */ + /* this must include "-c" to make sense, so fall through */ + /* FALLTHROUGH */ case 'c': auto_create_c = true; break; @@ -208,7 +208,7 @@ main(int argc, char *const argv[]) snprintf(informix_path, MAXPGPATH, "%s/informix/esql", pkginclude_path); add_include_path(informix_path); } - else if (strncmp(optarg, "ORACLE", strlen("ORACLE")) == 0) + else if (pg_strcasecmp(optarg, "ORACLE") == 0) { compat = ECPG_COMPAT_ORACLE; } @@ -219,11 +219,11 @@ main(int argc, char *const argv[]) } break; case 'r': - if (strcmp(optarg, "no_indicator") == 0) + if (pg_strcasecmp(optarg, "no_indicator") == 0) force_indicator = false; - else if (strcmp(optarg, "prepare") == 0) + else if (pg_strcasecmp(optarg, "prepare") == 0) auto_prepare = true; - else if (strcmp(optarg, "questionmarks") == 0) + else if (pg_strcasecmp(optarg, "questionmarks") == 0) questionmarks = true; else { @@ -378,8 +378,8 @@ main(int argc, char *const argv[]) defptr = defines; defines = defines->next; - free(defptr->new); - free(defptr->old); + free(defptr->newdef); + free(defptr->olddef); free(defptr); } @@ -391,8 +391,8 @@ main(int argc, char *const argv[]) { defptr->next = this->next; - free(this->new); - free(this->old); + free(this->newdef); + free(this->olddef); free(this); } } @@ -479,7 +479,8 @@ main(int argc, char *const argv[]) } } - if (output_filename && out_option == 0) { + if (output_filename && out_option == 0) + { free(output_filename); output_filename = NULL; } diff --git a/src/interfaces/ecpg/preproc/ecpg.header b/src/interfaces/ecpg/preproc/ecpg.header index 8921bcbeaec..4091ffd28b5 100644 --- a/src/interfaces/ecpg/preproc/ecpg.header +++ b/src/interfaces/ecpg/preproc/ecpg.header @@ -4,7 +4,7 @@ %{ #include "postgres_fe.h" -#include "extern.h" +#include "preproc_extern.h" #include "ecpg_config.h" #include @@ -46,6 +46,7 @@ static char pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess static struct this_type actual_type[STRUCT_DEPTH]; static char *actual_startline[STRUCT_DEPTH]; static int varchar_counter = 1; +static int bytea_counter = 1; /* temporarily store struct members while creating the data structure */ struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL }; @@ -562,6 +563,7 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum, ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL; if (type_enum != ECPGt_varchar && + type_enum != ECPGt_bytea && type_enum != ECPGt_char && type_enum != ECPGt_unsigned_char && type_enum != ECPGt_string && @@ -590,4 +592,5 @@ add_typedef(char *name, char *dimension, char *length, enum ECPGttype type_enum, struct fetch_desc descriptor; struct su_symbol struct_union; struct prep prep; + struct exec exec; } diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 19dc7818859..1122f56a14d 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -34,7 +34,14 @@ CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectSt if (FoundInto == 1) mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); - $$ = cat_str(6, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as"), $7); + $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as"), $7, $8); + } + | CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data + { + if (FoundInto == 1) + mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO"); + + $$ = cat_str(7, mm_strdup("create"), $2, mm_strdup("table if not exists"), $7, mm_strdup("as"), $10, $11); } ; @@ -339,12 +346,8 @@ ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared comment = cat_str(3, mm_strdup("/*"), mm_strdup(this->command), mm_strdup("*/")); - if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */ - $$ = cat_str(3, adjust_outofscope_cursor_vars(this), - mm_strdup("ECPG_informix_reset_sqlca();"), + $$ = cat_str(2, adjust_outofscope_cursor_vars(this), comment); - else - $$ = cat2_str(adjust_outofscope_cursor_vars(this), comment); } ; @@ -550,6 +553,14 @@ var_type: simple_type $$.type_index = mm_strdup("-1"); $$.type_sizeof = NULL; } + else if (strcmp($1, "bytea") == 0) + { + $$.type_enum = ECPGt_bytea; + $$.type_str = EMPTY; + $$.type_dimension = mm_strdup("-1"); + $$.type_index = mm_strdup("-1"); + $$.type_sizeof = NULL; + } else if (strcmp($1, "float") == 0) { $$.type_enum = ECPGt_float; @@ -627,7 +638,7 @@ var_type: simple_type /* this is for typedef'ed types */ struct typedefs *this = get_typedef($1); - $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name); + $$.type_str = (this->type->type_enum == ECPGt_varchar || this->type->type_enum == ECPGt_bytea) ? EMPTY : mm_strdup(this->name); $$.type_enum = this->type->type_enum; $$.type_dimension = this->type->type_dimension; $$.type_index = this->type->type_index; @@ -838,7 +849,7 @@ variable_list: variable { $$ = $1; } | variable_list ',' variable { - if (actual_type[struct_level].type_enum == ECPGt_varchar) + if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea) $$ = cat_str(3, $1, mm_strdup(";"), $3); else $$ = cat_str(3, $1, mm_strdup(","), $3); @@ -852,9 +863,10 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize char *length = $3.index2; /* length of string */ char *dim_str; char *vcn; + int *varlen_type_counter; + char *struct_name; adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false); - switch (actual_type[struct_level].type_enum) { case ECPGt_struct: @@ -868,10 +880,21 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize break; case ECPGt_varchar: + case ECPGt_bytea: + if (actual_type[struct_level].type_enum == ECPGt_varchar) + { + varlen_type_counter = &varchar_counter; + struct_name = " struct varchar_"; + } + else + { + varlen_type_counter = &bytea_counter; + struct_name = " struct bytea_"; + } if (atoi(dimension) < 0) - type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter); + type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter); else - type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter), dimension); + type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, *varlen_type_counter), dimension); if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1) dim_str=mm_strdup(""); @@ -883,12 +906,12 @@ variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initialize /* make sure varchar struct name is unique by adding a unique counter to its definition */ vcn = (char *) mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(vcn, "%d", varchar_counter); + sprintf(vcn, "%d", *varlen_type_counter); if (strcmp(dimension, "0") == 0) - $$ = cat_str(7, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); + $$ = cat_str(7, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5); else - $$ = cat_str(8, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); - varchar_counter++; + $$ = cat_str(8, make2_str(mm_strdup(struct_name), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5); + (*varlen_type_counter)++; break; case ECPGt_char: @@ -1042,7 +1065,7 @@ UsingValue: UsingConst { char *length = mm_alloc(32); - sprintf(length, "%d", (int) strlen($1)); + sprintf(length, "%zu", strlen($1)); add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator); } | civar { $$ = EMPTY; } @@ -1169,7 +1192,7 @@ IntConstVar: Iconst { char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(length, "%d", (int) strlen($1)); + sprintf(length, "%zu", strlen($1)); new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); $$ = $1; } @@ -1215,7 +1238,7 @@ AllConstVar: ecpg_fconst { char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); - sprintf(length, "%d", (int) strlen($1)); + sprintf(length, "%zu", strlen($1)); new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0); $$ = $1; } @@ -1230,7 +1253,7 @@ AllConstVar: ecpg_fconst char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); char *var = cat2_str(mm_strdup("-"), $2); - sprintf(length, "%d", (int) strlen(var)); + sprintf(length, "%zu", strlen(var)); new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); $$ = var; } @@ -1240,7 +1263,7 @@ AllConstVar: ecpg_fconst char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3); char *var = cat2_str(mm_strdup("-"), $2); - sprintf(length, "%d", (int) strlen(var)); + sprintf(length, "%zu", strlen(var)); new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); $$ = var; } @@ -1251,7 +1274,7 @@ AllConstVar: ecpg_fconst char *var = $1 + 1; var[strlen(var) - 1] = '\0'; - sprintf(length, "%d", (int) strlen(var)); + sprintf(length, "%zu", strlen(var)); new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0); $$ = var; } @@ -1354,6 +1377,7 @@ ECPGVar: SQL_VAR break; case ECPGt_varchar: + case ECPGt_bytea: if (atoi(dimension) == -1) type = ECPGmake_simple_type($5.type_enum, length, 0); else diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c index 848b2d48493..4839c37bbca 100644 --- a/src/interfaces/ecpg/preproc/ecpg_keywords.c +++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c @@ -13,85 +13,43 @@ #include -#include "extern.h" +#include "preproc_extern.h" #include "preproc.h" -/* - * List of (keyword-name, keyword-token-value) pairs. - * - * !!WARNING!!: This list must be sorted, because binary - * search is used to locate entries. - */ -static const ScanKeyword ECPGScanKeywords[] = { - /* name, value, category */ +/* ScanKeywordList lookup data for ECPG keywords */ +#include "ecpg_kwlist_d.h" + +/* Token codes for ECPG keywords */ +#define PG_KEYWORD(kwname, value) value, - /* - * category is not needed in ecpg, it is only here so we can share the - * data structure with the backend - */ - {"allocate", SQL_ALLOCATE, 0}, - {"autocommit", SQL_AUTOCOMMIT, 0}, - {"bool", SQL_BOOL, 0}, - {"break", SQL_BREAK, 0}, - {"cardinality", SQL_CARDINALITY, 0}, - {"connect", SQL_CONNECT, 0}, - {"count", SQL_COUNT, 0}, - {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE, 0}, - {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION, 0}, - {"describe", SQL_DESCRIBE, 0}, - {"descriptor", SQL_DESCRIPTOR, 0}, - {"disconnect", SQL_DISCONNECT, 0}, - {"found", SQL_FOUND, 0}, - {"free", SQL_FREE, 0}, - {"get", SQL_GET, 0}, - {"go", SQL_GO, 0}, - {"goto", SQL_GOTO, 0}, - {"identified", SQL_IDENTIFIED, 0}, - {"indicator", SQL_INDICATOR, 0}, - {"key_member", SQL_KEY_MEMBER, 0}, - {"length", SQL_LENGTH, 0}, - {"long", SQL_LONG, 0}, - {"nullable", SQL_NULLABLE, 0}, - {"octet_length", SQL_OCTET_LENGTH, 0}, - {"open", SQL_OPEN, 0}, - {"output", SQL_OUTPUT, 0}, - {"reference", SQL_REFERENCE, 0}, - {"returned_length", SQL_RETURNED_LENGTH, 0}, - {"returned_octet_length", SQL_RETURNED_OCTET_LENGTH, 0}, - {"scale", SQL_SCALE, 0}, - {"section", SQL_SECTION, 0}, - {"short", SQL_SHORT, 0}, - {"signed", SQL_SIGNED, 0}, - {"sqlerror", SQL_SQLERROR, 0}, - {"sqlprint", SQL_SQLPRINT, 0}, - {"sqlwarning", SQL_SQLWARNING, 0}, - {"stop", SQL_STOP, 0}, - {"struct", SQL_STRUCT, 0}, - {"unsigned", SQL_UNSIGNED, 0}, - {"var", SQL_VAR, 0}, - {"whenever", SQL_WHENEVER, 0}, +static const uint16 ECPGScanKeywordTokens[] = { +#include "ecpg_kwlist.h" }; +#undef PG_KEYWORD + + /* * ScanECPGKeywordLookup - see if a given word is a keyword * - * Returns a pointer to the ScanKeyword table entry, or NULL if no match. + * Returns the token value of the keyword, or -1 if no match. + * * Keywords are matched using the same case-folding rules as in the backend. */ -const ScanKeyword * +int ScanECPGKeywordLookup(const char *text) { - const ScanKeyword *res; + int kwnum; /* First check SQL symbols defined by the backend. */ - res = ScanKeywordLookup(text, SQLScanKeywords, NumSQLScanKeywords); - if (res) - return res; + kwnum = ScanKeywordLookup(text, &ScanKeywords); + if (kwnum >= 0) + return SQLScanKeywordTokens[kwnum]; /* Try ECPG-specific keywords. */ - res = ScanKeywordLookup(text, ECPGScanKeywords, lengthof(ECPGScanKeywords)); - if (res) - return res; + kwnum = ScanKeywordLookup(text, &ScanECPGKeywords); + if (kwnum >= 0) + return ECPGScanKeywordTokens[kwnum]; - return NULL; + return -1; } diff --git a/src/interfaces/ecpg/preproc/ecpg_kwlist.h b/src/interfaces/ecpg/preproc/ecpg_kwlist.h new file mode 100644 index 00000000000..bdd98549254 --- /dev/null +++ b/src/interfaces/ecpg/preproc/ecpg_kwlist.h @@ -0,0 +1,67 @@ +/*------------------------------------------------------------------------- + * + * ecpg_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/interfaces/ecpg/preproc/ecpg_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef ECPG_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("allocate", SQL_ALLOCATE) +PG_KEYWORD("autocommit", SQL_AUTOCOMMIT) +PG_KEYWORD("bool", SQL_BOOL) +PG_KEYWORD("break", SQL_BREAK) +PG_KEYWORD("cardinality", SQL_CARDINALITY) +PG_KEYWORD("connect", SQL_CONNECT) +PG_KEYWORD("count", SQL_COUNT) +PG_KEYWORD("datetime_interval_code", SQL_DATETIME_INTERVAL_CODE) +PG_KEYWORD("datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION) +PG_KEYWORD("describe", SQL_DESCRIBE) +PG_KEYWORD("descriptor", SQL_DESCRIPTOR) +PG_KEYWORD("disconnect", SQL_DISCONNECT) +PG_KEYWORD("found", SQL_FOUND) +PG_KEYWORD("free", SQL_FREE) +PG_KEYWORD("get", SQL_GET) +PG_KEYWORD("go", SQL_GO) +PG_KEYWORD("goto", SQL_GOTO) +PG_KEYWORD("identified", SQL_IDENTIFIED) +PG_KEYWORD("indicator", SQL_INDICATOR) +PG_KEYWORD("key_member", SQL_KEY_MEMBER) +PG_KEYWORD("length", SQL_LENGTH) +PG_KEYWORD("long", SQL_LONG) +PG_KEYWORD("nullable", SQL_NULLABLE) +PG_KEYWORD("octet_length", SQL_OCTET_LENGTH) +PG_KEYWORD("open", SQL_OPEN) +PG_KEYWORD("output", SQL_OUTPUT) +PG_KEYWORD("reference", SQL_REFERENCE) +PG_KEYWORD("returned_length", SQL_RETURNED_LENGTH) +PG_KEYWORD("returned_octet_length", SQL_RETURNED_OCTET_LENGTH) +PG_KEYWORD("scale", SQL_SCALE) +PG_KEYWORD("section", SQL_SECTION) +PG_KEYWORD("short", SQL_SHORT) +PG_KEYWORD("signed", SQL_SIGNED) +PG_KEYWORD("sqlerror", SQL_SQLERROR) +PG_KEYWORD("sqlprint", SQL_SQLPRINT) +PG_KEYWORD("sqlwarning", SQL_SQLWARNING) +PG_KEYWORD("stop", SQL_STOP) +PG_KEYWORD("struct", SQL_STRUCT) +PG_KEYWORD("unsigned", SQL_UNSIGNED) +PG_KEYWORD("var", SQL_VAR) +PG_KEYWORD("whenever", SQL_WHENEVER) diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c index 21e1f928fd6..03804099d12 100644 --- a/src/interfaces/ecpg/preproc/keywords.c +++ b/src/interfaces/ecpg/preproc/keywords.c @@ -4,7 +4,7 @@ * lexical token lookup for key words in PostgreSQL * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,24 +17,22 @@ /* * This is much trickier than it looks. We are #include'ing kwlist.h - * but the "value" numbers that go into the table are from preproc.h - * not the backend's gram.h. Therefore this table will recognize all - * keywords known to the backend, but will supply the token numbers used + * but the token numbers that go into the table are from preproc.h + * not the backend's gram.h. Therefore this token table will match + * the ScanKeywords table supplied from common/keywords.c, including all + * keywords known to the backend, but it will supply the token numbers used * by ecpg's grammar, which is what we need. The ecpg grammar must * define all the same token names the backend does, else we'll get * undefined-symbol failures in this compile. */ -#include "common/keywords.h" - -#include "extern.h" +#include "preproc_extern.h" #include "preproc.h" +#define PG_KEYWORD(kwname, value, category) value, -#define PG_KEYWORD(a,b,c) {a,b,c}, - -const ScanKeyword SQLScanKeywords[] = { +const uint16 SQLScanKeywordTokens[] = { #include "parser/kwlist.h" }; -const int NumSQLScanKeywords = lengthof(SQLScanKeywords); +#undef PG_KEYWORD diff --git a/src/interfaces/ecpg/preproc/nls.mk b/src/interfaces/ecpg/preproc/nls.mk index 91297a2323b..06f6d3192dc 100644 --- a/src/interfaces/ecpg/preproc/nls.mk +++ b/src/interfaces/ecpg/preproc/nls.mk @@ -1,6 +1,6 @@ # src/interfaces/ecpg/preproc/nls.mk CATALOG_NAME = ecpg -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru tr zh_CN zh_TW +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr vi zh_CN zh_TW GETTEXT_FILES = descriptor.c ecpg.c pgc.c preproc.c type.c variable.c GETTEXT_TRIGGERS = mmerror:3 mmfatal:2 GETTEXT_FLAGS = mmerror:3:c-format mmfatal:2:c-format diff --git a/src/interfaces/ecpg/preproc/output.c b/src/interfaces/ecpg/preproc/output.c index 0465857eb6e..65d06d5794b 100644 --- a/src/interfaces/ecpg/preproc/output.c +++ b/src/interfaces/ecpg/preproc/output.c @@ -2,7 +2,7 @@ #include "postgres_fe.h" -#include "extern.h" +#include "preproc_extern.h" static void output_escaped_str(char *cmd, bool quoted); @@ -16,9 +16,11 @@ output_line_number(void) } void -output_simple_statement(char *stmt) +output_simple_statement(char *stmt, int whenever_mode) { output_escaped_str(stmt, false); + if (whenever_mode) + whenever_action(whenever_mode); output_line_number(); free(stmt); } @@ -125,24 +127,30 @@ static char *ecpg_statement_type_name[] = { "ECPGst_normal", "ECPGst_execute", "ECPGst_exec_immediate", - "ECPGst_prepnormal" + "ECPGst_prepnormal", + "ECPGst_prepare", + "ECPGst_exec_with_exprlist" }; void output_statement(char *stmt, int whenever_mode, enum ECPG_statement_type st) { fprintf(base_yyout, "{ ECPGdo(__LINE__, %d, %d, %s, %d, ", compat, force_indicator, connection ? connection : "NULL", questionmarks); + + if (st == ECPGst_prepnormal && !auto_prepare) + st = ECPGst_normal; + + /* + * In following cases, stmt is CSTRING or char_variable. They must be + * output directly. - prepared_name of EXECUTE without exprlist - + * execstring of EXECUTE IMMEDIATE + */ + fprintf(base_yyout, "%s, ", ecpg_statement_type_name[st]); if (st == ECPGst_execute || st == ECPGst_exec_immediate) - { - fprintf(base_yyout, "%s, %s, ", ecpg_statement_type_name[st], stmt); - } + fprintf(base_yyout, "%s, ", stmt); else { - if (st == ECPGst_prepnormal && auto_prepare) - fputs("ECPGst_prepnormal, \"", base_yyout); - else - fputs("ECPGst_normal, \"", base_yyout); - + fputs("\"", base_yyout); output_escaped_str(stmt, false); fputs("\", ", base_yyout); } diff --git a/src/interfaces/ecpg/preproc/parse.pl b/src/interfaces/ecpg/preproc/parse.pl index e68cc26f525..3619706cdc8 100644 --- a/src/interfaces/ecpg/preproc/parse.pl +++ b/src/interfaces/ecpg/preproc/parse.pl @@ -1,9 +1,9 @@ #!/usr/bin/perl # src/interfaces/ecpg/preproc/parse.pl -# parser generater for ecpg version 2 +# parser generator for ecpg version 2 # call with backend parser as stdin # -# Copyright (c) 2007-2018, PostgreSQL Global Development Group +# Copyright (c) 2007-2019, PostgreSQL Global Development Group # # Written by Mike Aubury # Michael Meskes @@ -22,6 +22,7 @@ my $copymode = 0; my $brace_indent = 0; my $yaccmode = 0; +my $in_rule = 0; my $header_included = 0; my $feature_not_supported = 0; my $tokenmode = 0; @@ -57,6 +58,7 @@ # ECPG-only replace_types are defined in ecpg-replace_types my %replace_types = ( 'PrepareStmt' => '', + 'ExecuteStmt' => '', 'opt_array_bounds' => '', # "ignore" means: do not create type and rules for this non-term-id @@ -101,11 +103,13 @@ 'RETURNING target_list opt_ecpg_into', 'ExecuteStmtEXECUTEnameexecute_param_clause' => 'EXECUTE prepared_name execute_param_clause execute_rest', -'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause' - => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause', + 'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' + => 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest', + 'ExecuteStmtCREATEOptTempTABLEIF_PNOTEXISTScreate_as_targetASEXECUTEnameexecute_param_clauseopt_with_data' + => 'CREATE OptTemp TABLE IF_P NOT EXISTS create_as_target AS EXECUTE prepared_name execute_param_clause opt_with_data execute_rest', 'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' => 'PREPARE prepared_name prep_type_clause AS PreparableStmt', - 'var_nameColId' => 'ECPGColId',); + 'var_nameColId' => 'ECPGColId'); preload_addons(); @@ -134,20 +138,20 @@ sub main chomp; - # comment out the line below to make the result file match (blank line wise) - # the prior version. - #next if ($_ eq ''); - - # Dump the action for a rule - - # stmt_mode indicates if we are processing the 'stmt:' - # rule (mode==0 means normal, mode==1 means stmt:) - # flds are the fields to use. These may start with a '$' - in - # which case they are the result of a previous non-terminal - # - # if they dont start with a '$' then they are token name - # - # len is the number of fields in flds... - # leadin is the padding to apply at the beginning (just use for formatting) + # comment out the line below to make the result file match (blank line wise) + # the prior version. + #next if ($_ eq ''); + + # Dump the action for a rule - + # stmt_mode indicates if we are processing the 'stmt:' + # rule (mode==0 means normal, mode==1 means stmt:) + # flds are the fields to use. These may start with a '$' - in + # which case they are the result of a previous non-terminal + # + # if they don't start with a '$' then they are token name + # + # len is the number of fields in flds... + # leadin is the padding to apply at the beginning (just use for formatting) if (/^%%/) { @@ -223,7 +227,7 @@ sub main next line; } - # Dont worry about anything if we're not in the right section of gram.y + # Don't worry about anything if we're not in the right section of gram.y if ($yaccmode != 1) { next line; @@ -288,6 +292,7 @@ sub main @fields = (); $infield = 0; $line = ''; + $in_rule = 0; next; } @@ -365,6 +370,9 @@ sub main $line = ''; @fields = (); $infield = 1; + die "unterminated rule at grammar line $.\n" + if $in_rule; + $in_rule = 1; next; } elsif ($copymode) @@ -415,6 +423,9 @@ sub main } } } + die "unterminated rule at end of grammar\n" + if $in_rule; + return; } @@ -431,6 +442,7 @@ sub include_file add_to_buffer($buffer, $_); } close($fh); + return; } sub include_addon @@ -472,6 +484,7 @@ sub include_addon sub add_to_buffer { push(@{ $buff{ $_[0] } }, "$_[1]\n"); + return; } sub dump_buffer @@ -480,6 +493,7 @@ sub dump_buffer print '/* ', $buffer, ' */', "\n"; my $ref = $buff{$buffer}; print @$ref; + return; } sub dump_fields @@ -501,7 +515,7 @@ sub dump_fields if ($flds->[0] ne 'create' || $flds->[2] ne 'table') { add_to_buffer('rules', -'mmerror(PARSE_ERROR, ET_WARNING, "unsupported feature will be passed to server");' + 'mmerror(PARSE_ERROR, ET_WARNING, "unsupported feature will be passed to server");' ); } $feature_not_supported = 0; @@ -582,6 +596,7 @@ sub dump_fields add_to_buffer('rules', ' { $$ = NULL; }'); } } + return; } @@ -632,8 +647,8 @@ sub preload_addons my $filename = $path . "/ecpg.addons"; open(my $fh, '<', $filename) or die; - # there may be multiple lines starting ECPG: and then multiple lines of code. - # the code need to be add to all prior ECPG records. + # there may be multiple lines starting ECPG: and then multiple lines of code. + # the code need to be add to all prior ECPG records. my (@needsRules, @code, $record); # there may be comments before the first ECPG line, skip them @@ -673,4 +688,5 @@ sub preload_addons push(@{ $x->{lines} }, @code); } } + return; } diff --git a/src/interfaces/ecpg/preproc/parser.c b/src/interfaces/ecpg/preproc/parser.c index e5a8f9d170e..abae89d51b4 100644 --- a/src/interfaces/ecpg/preproc/parser.c +++ b/src/interfaces/ecpg/preproc/parser.c @@ -7,7 +7,7 @@ * need to bother with re-entrant interfaces. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,7 +18,7 @@ #include "postgres_fe.h" -#include "extern.h" +#include "preproc_extern.h" #include "preproc.h" diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 405dee73b03..488c89b7f42 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -7,10 +7,9 @@ * This is a modified version of src/backend/parser/scan.l * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * * IDENTIFICATION * src/interfaces/ecpg/preproc/pgc.l * @@ -23,17 +22,18 @@ #include "common/string.h" -#include "extern.h" +#include "preproc_extern.h" #include "preproc.h" } %{ + +/* LCOV_EXCL_START */ + extern YYSTYPE base_yylval; static int xcdepth = 0; /* depth of nesting in slash-star comments */ static char *dolqstart = NULL; /* current $foo$ quote start string */ -static YY_BUFFER_STATE scanbufhandle; -static char *scanbuf; /* * literalbuf is used to accumulate literal values when multiple rules @@ -53,8 +53,9 @@ static bool include_next; #define startlit() (literalbuf[0] = '\0', literallen = 0) static void addlit(char *ytext, int yleng); -static void addlitchar (unsigned char); -static void parse_include (void); +static void addlitchar(unsigned char); +static int process_integer_literal(const char *token, YYSTYPE *lval); +static void parse_include(void); static bool ecpg_isspace(char ch); static bool isdefine(void); static bool isinformixdefine(void); @@ -81,8 +82,6 @@ static struct _if_value short else_branch; } stacked_if_value[MAX_NESTED_IF]; -/* LCOV_EXCL_START */ - %} %option 8bit @@ -91,11 +90,8 @@ static struct _if_value %option noinput %option noyywrap %option warn -%option prefix="base_yy" - %option yylineno - -%x C SQL incl def def_ident undef +%option prefix="base_yy" /* * OK, here is a short description of lex/flex rules behavior. @@ -108,18 +104,24 @@ static struct _if_value * We use exclusive states for quoted strings, extended comments, * and to eliminate parsing troubles for numeric strings. * Exclusive states: - * bit string literal - * extended C-style comments in C - * extended C-style comments in SQL - * delimited identifiers (double-quoted identifiers) - thomas 1997-10-27 - * hexadecimal numeric string - thomas 1997-11-16 - * standard quoted strings - thomas 1997-07-30 - * standard quoted strings in C - michael - * extended quoted strings (support backslash escape sequences) - * national character quoted strings + * bit string literal + * extended C-style comments in C + * extended C-style comments in SQL + * delimited identifiers (double-quoted identifiers) + * double-quoted strings in C + * hexadecimal numeric string + * national character quoted strings + * standard quoted strings + * extended quoted strings (support backslash escape sequences) + * single-quoted strings in C * $foo$ quoted strings * quoted identifier with Unicode escapes * quoted string with Unicode escapes + * condition of an EXEC SQL IFDEF construct + * skipping the inactive part of an EXEC SQL IFDEF construct + * + * Remember to add an <> case whenever you add a new exclusive state! + * The default one is probably not the right thing. */ %x xb @@ -128,15 +130,60 @@ static struct _if_value %x xd %x xdc %x xh -%x xe %x xn %x xq +%x xe %x xqc %x xdolq -%x xcond -%x xskip %x xui %x xus +%x xcond +%x xskip + +/* Additional exclusive states that are specific to ECPG */ +%x C SQL incl def def_ident undef + +/* + * In order to make the world safe for Windows and Mac clients as well as + * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n + * sequence will be seen as two successive newlines, but that doesn't cause + * any problems. SQL-style comments, which start with -- and extend to the + * next newline, are treated as equivalent to a single whitespace character. + * + * NOTE a fine point: if there is no newline following --, we will absorb + * everything to the end of the input as a comment. This is correct. Older + * versions of Postgres failed to recognize -- as a comment if the input + * did not end with a newline. + * + * XXX perhaps \f (formfeed) should be treated as a newline as well? + * + * XXX if you change the set of whitespace characters, fix ecpg_isspace() + * to agree. + */ + +space [ \t\n\r\f] +horiz_space [ \t\f] +newline [\n\r] +non_newline [^\n\r] + +comment ("--"{non_newline}*) + +whitespace ({space}+|{comment}) + +/* + * SQL requires at least one newline in the whitespace separating + * string literals that are to be concatenated. Silly, but who are we + * to argue? Note that {whitespace_with_newline} should not have * after + * it, whereas {whitespace} should generally have a * after it... + */ + +horiz_whitespace ({horiz_space}|{comment}) +whitespace_with_newline ({horiz_whitespace}*{newline}{whitespace}*) + +quote ' +quotestop {quote}{whitespace}* +quotecontinue {quote}{whitespace_with_newline}{quote} +quotefail {quote}{whitespace}*"-" /* Bit string */ @@ -158,9 +205,6 @@ xeoctesc [\\][0-7]{1,3} xehexesc [\\]x[0-9A-Fa-f]{1,2} xeunicode [\\](u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8}) -/* C version of hex number */ -xch 0[xX][0-9A-Fa-f]* - /* Extended quote * xqdouble implements embedded quote, '''' */ @@ -194,7 +238,9 @@ xddouble {dquote}{dquote} xdinside [^"]+ /* Unicode escapes */ -/* (The ecpg scanner is not backup-free, so the fail rules in scan.l are not needed here, but could be added if desired.) */ +/* (The ecpg scanner is not backup-free, so the fail rules in scan.l are + * not needed here, but could be added if desired.) + */ uescape [uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']{quote} /* Quoted identifier with Unicode escapes */ @@ -211,22 +257,23 @@ xdcqdq \\\" xdcother [^"] xdcinside ({xdcqq}|{xdcqdq}|{xdcother}) + /* C-style comments * * The "extended comment" syntax closely resembles allowable operator syntax. * The tricky part here is to get lex to recognize a string starting with * slash-star as a comment, when interpreting it as an operator would produce - * a longer match --- remember lex will prefer a longer match! Also, if we + * a longer match --- remember lex will prefer a longer match! Also, if we * have something like plus-slash-star, lex will think this is a 3-character * operator whereas we want to see it as a + operator and a comment start. * The solution is two-fold: * 1. append {op_chars}* to xcstart so that it matches as much text as - * {operator} would. Then the tie-breaker (first matching rule of same - * length) ensures xcstart wins. We put back the extra stuff with yyless() - * in case it contains a star-slash that should terminate the comment. + * {operator} would. Then the tie-breaker (first matching rule of same + * length) ensures xcstart wins. We put back the extra stuff with yyless() + * in case it contains a star-slash that should terminate the comment. * 2. In the operator rule, check for slash-star within the operator, and - * if found throw it back with yyless(). This handles the plus-slash-star - * problem. + * if found throw it back with yyless(). This handles the plus-slash-star + * problem. * Dash-dash comments have similar interactions with the operator rule. */ xcstart \/\*{op_chars}* @@ -245,6 +292,15 @@ array ({ident_cont}|{whitespace}|[\[\]\+\-\*\%\/\(\)\>\.])* typecast "::" dot_dot \.\. colon_equals ":=" + +/* + * These operator-like tokens (unlike the above ones) also match the {operator} + * rule, which means that they might be overridden by a longer match if they + * are followed by a comment start or a + or - character. Accordingly, if you + * add to this list, you must also add corresponding code to the {operator} + * block to return the correct token in such cases. (This is not needed in + * psqlscan.l since the token value is ignored there.) + */ equals_greater "=>" less_equals "<=" greater_equals ">=" @@ -253,7 +309,7 @@ not_equals "!=" /* * "self" is the set of chars that should be returned as single-character - * tokens. "op_chars" is the set of chars that can make up "Op" tokens, + * tokens. "op_chars" is the set of chars that can make up "Op" tokens, * which can be one or more characters long (but if a single-char token * appears in the "self" set, it is not to be returned as an Op). Note * that the sets overlap, but each has some chars that are not in the other. @@ -269,68 +325,40 @@ operator {op_chars}+ * instead we pass it separately to parser. there it gets * coerced via doNegate() -- Leon aug 20 1999 * + * {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10. + * * {realfail1} and {realfail2} are added to prevent the need for scanner * backup when the {real} rule fails to match completely. */ integer {digit}+ decimal (({digit}*\.{digit}+)|({digit}+\.{digit}*)) +decimalfail {digit}+\.\. real ({integer}|{decimal})[Ee][-+]?{digit}+ realfail1 ({integer}|{decimal})[Ee] realfail2 ({integer}|{decimal})[Ee][-+] param \${integer} -/* - * In order to make the world safe for Windows and Mac clients as well as - * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n - * sequence will be seen as two successive newlines, but that doesn't cause - * any problems. SQL-style comments, which start with -- and extend to the - * next newline, are treated as equivalent to a single whitespace character. - * - * NOTE a fine point: if there is no newline following --, we will absorb - * everything to the end of the input as a comment. This is correct. Older - * versions of Postgres failed to recognize -- as a comment if the input - * did not end with a newline. - * - * XXX perhaps \f (formfeed) should be treated as a newline as well? - * - * XXX if you change the set of whitespace characters, fix ecpg_isspace() - * to agree. - */ - -ccomment "//".*\n - -space [ \t\n\r\f] -horiz_space [ \t\f] -newline [\n\r] -non_newline [^\n\r] - -comment ("--"{non_newline}*) - -whitespace ({space}+|{comment}) - -/* - * SQL requires at least one newline in the whitespace separating - * string literals that are to be concatenated. Silly, but who are we - * to argue? Note that {whitespace_with_newline} should not have * after - * it, whereas {whitespace} should generally have a * after it... - */ - -horiz_whitespace ({horiz_space}|{comment}) -whitespace_with_newline ({horiz_whitespace}*{newline}{whitespace}*) - -quote ' -quotestop {quote}{whitespace}* -quotecontinue {quote}{whitespace_with_newline}{quote} -quotefail {quote}{whitespace}*"-" - /* special characters for other dbms */ /* we have to react differently in compat mode */ informix_special [\$] other . +/* + * Dollar quoted strings are totally opaque, and no escaping is done on them. + * Other quoted strings must allow some special characters such as single-quote + * and newline. + * Embedded single-quotes are implemented both in the SQL standard + * style of two adjacent single quotes "''" and in the Postgres/Java style + * of escaped-quote "\'". + * Other embedded escaped characters are matched explicitly and the leading + * backslash is dropped from the string. + * Note that xcstart must appear before operator, as explained above! + * Also whitespace (comment) must appear before operator. + */ + /* some stuff needed for ecpg */ exec [eE][xX][eE][cC] sql [sS][qQ][lL] @@ -340,6 +368,11 @@ include_next [iI][nN][cC][lL][uU][dD][eE]_[nN][eE][xX][tT] import [iI][mM][pP][oO][rR][tT] undef [uU][nN][dD][eE][fF] +/* C version of hex number */ +xch 0[xX][0-9A-Fa-f]* + +ccomment "//".*\n + if [iI][fF] ifdef [iI][fF][dD][eE][fF] ifndef [iI][fF][nN][dD][eE][fF] @@ -357,24 +390,12 @@ ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit} cppinclude {space}*#{include}{space}* cppinclude_next {space}*#{include_next}{space}* -/* take care of cpp lines, they may also be continuated */ +/* take care of cpp lines, they may also be continued */ /* first a general line for all commands not starting with "i" */ /* and then the other commands starting with "i", we have to add these - * separately because the cppline production would match on "include" too */ -cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+\/)|.|\\{space}*{newline})*{newline} - -/* - * Dollar quoted strings are totally opaque, and no escaping is done on them. - * Other quoted strings must allow some special characters such as single-quote - * and newline. - * Embedded single-quotes are implemented both in the SQL standard - * style of two adjacent single quotes "''" and in the Postgres/Java style - * of escaped-quote "\'". - * Other embedded escaped characters are matched explicitly and the leading - * backslash is dropped from the string. - thomas 1997-09-24 - * Note that xcstart must appear before operator, as explained above! - * Also whitespace (comment) must appear before operator. + * separately because the cppline production would match on "include" too */ +cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+\/)|.|\\{space}*{newline})*{newline} %% @@ -383,22 +404,27 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ token_start = NULL; %} -{whitespace} { /* ignore */ } +{ +{whitespace} { + /* ignore */ + } -{xcstart} { +{xcstart} { token_start = yytext; state_before = YYSTATE; xcdepth = 0; - BEGIN(xcc); + BEGIN(xcsql); /* Put back any characters past slash-star; see above */ yyless(2); fputs("/*", yyout); } -{xcstart} { +} /* */ + +{xcstart} { token_start = yytext; state_before = YYSTATE; xcdepth = 0; - BEGIN(xcsql); + BEGIN(xcc); /* Put back any characters past slash-star; see above */ yyless(2); fputs("/*", yyout); @@ -428,20 +454,36 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ BEGIN(state_before); token_start = NULL; } -{xcinside} { ECHO; } -{op_chars} { ECHO; } -\*+ { ECHO; } -<> { mmfatal(PARSE_ERROR, "unterminated /* comment"); } +{ +{xcinside} { + ECHO; + } + +{op_chars} { + ECHO; + } + +\*+ { + ECHO; + } -{xbstart} { +<> { + mmfatal(PARSE_ERROR, "unterminated /* comment"); + } +} /* */ + +{ +{xbstart} { token_start = yytext; BEGIN(xb); startlit(); addlitchar('b'); } -{quotestop} | -{quotefail} { +} /* */ + +{quotestop} | +{quotefail} { yyless(1); BEGIN(SQL); if (literalbuf[strspn(literalbuf, "01") + 1] != '\0') @@ -449,11 +491,14 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ base_yylval.str = mm_strdup(literalbuf); return BCONST; } - {xhinside} | -{xbinside} { addlit(yytext, yyleng); } +{xbinside} { + addlit(yytext, yyleng); + } {quotecontinue} | -{quotecontinue} { /* ignore */ } +{quotecontinue} { + /* ignore */ + } <> { mmfatal(PARSE_ERROR, "unterminated bit string literal"); } {xhstart} { @@ -463,186 +508,251 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ addlitchar('x'); } {quotestop} | -{quotefail} { - yyless(1); - BEGIN(SQL); - base_yylval.str = mm_strdup(literalbuf); - return XCONST; - } +{quotefail} { + yyless(1); + BEGIN(SQL); + base_yylval.str = mm_strdup(literalbuf); + return XCONST; + } <> { mmfatal(PARSE_ERROR, "unterminated hexadecimal string literal"); } -{xnstart} { - /* National character. - * Transfer it as-is to the backend. - */ - token_start = yytext; - state_before = YYSTATE; - BEGIN(xn); - startlit(); - } + {xqstart} { - token_start = yytext; - state_before = YYSTATE; - BEGIN(xqc); - startlit(); - } -{xqstart} { - token_start = yytext; - state_before = YYSTATE; - BEGIN(xq); - startlit(); - } -{xestart} { - token_start = yytext; - state_before = YYSTATE; - BEGIN(xe); - startlit(); - } -{xusstart} { - token_start = yytext; - state_before = YYSTATE; - BEGIN(xus); - startlit(); - addlit(yytext, yyleng); - } + token_start = yytext; + state_before = YYSTATE; + BEGIN(xqc); + startlit(); + } + +{ +{xnstart} { + /* National character. + * Transfer it as-is to the backend. + */ + token_start = yytext; + state_before = YYSTATE; + BEGIN(xn); + startlit(); + } + +{xqstart} { + token_start = yytext; + state_before = YYSTATE; + BEGIN(xq); + startlit(); + } +{xestart} { + token_start = yytext; + state_before = YYSTATE; + BEGIN(xe); + startlit(); + } +{xusstart} { + token_start = yytext; + state_before = YYSTATE; + BEGIN(xus); + startlit(); + addlit(yytext, yyleng); + } +} /* */ + {quotestop} | {quotefail} { - yyless(1); - BEGIN(state_before); - base_yylval.str = mm_strdup(literalbuf); - return SCONST; - } + yyless(1); + BEGIN(state_before); + base_yylval.str = mm_strdup(literalbuf); + return SCONST; + } {quotestop} | {quotefail} { - yyless(1); - BEGIN(state_before); - base_yylval.str = mm_strdup(literalbuf); - return ECONST; - } + yyless(1); + BEGIN(state_before); + base_yylval.str = mm_strdup(literalbuf); + return ECONST; + } {quotestop} | {quotefail} { - yyless(1); - BEGIN(state_before); - base_yylval.str = mm_strdup(literalbuf); - return NCONST; - } + yyless(1); + BEGIN(state_before); + base_yylval.str = mm_strdup(literalbuf); + return NCONST; + } {xusstop} { - addlit(yytext, yyleng); - BEGIN(state_before); - base_yylval.str = mm_strdup(literalbuf); - return UCONST; - } + addlit(yytext, yyleng); + BEGIN(state_before); + base_yylval.str = mm_strdup(literalbuf); + return UCONST; + } {xqdouble} { addlitchar('\''); } -{xqcquote} { - addlitchar('\\'); - addlitchar('\''); - } +{xqcquote} { + addlitchar('\\'); + addlitchar('\''); + } {xqinside} { addlit(yytext, yyleng); } -{xeinside} { addlit(yytext, yyleng); } -{xeunicode} { addlit(yytext, yyleng); } -{xeescape} { addlit(yytext, yyleng); } -{xeoctesc} { addlit(yytext, yyleng); } -{xehexesc} { addlit(yytext, yyleng); } -{quotecontinue} { /* ignore */ } -. { - /* This is only needed for \ just before EOF */ - addlitchar(yytext[0]); - } +{xeinside} { + addlit(yytext, yyleng); + } +{xeunicode} { + addlit(yytext, yyleng); + } +{xeescape} { + addlit(yytext, yyleng); + } +{xeoctesc} { + addlit(yytext, yyleng); + } +{xehexesc} { + addlit(yytext, yyleng); + } +{quotecontinue} { + /* ignore */ + } +. { + /* This is only needed for \ just before EOF */ + addlitchar(yytext[0]); + } <> { mmfatal(PARSE_ERROR, "unterminated quoted string"); } -{dolqfailed} { - /* throw back all but the initial "$" */ - yyless(1); - /* and treat it as {other} */ - return yytext[0]; - } -{dolqdelim} { - token_start = yytext; - if (dolqstart) - free(dolqstart); - dolqstart = mm_strdup(yytext); - BEGIN(xdolq); - startlit(); - addlit(yytext, yyleng); - } -{dolqdelim} { - if (strcmp(yytext, dolqstart) == 0) - { + +{ +{dolqdelim} { + token_start = yytext; + if (dolqstart) + free(dolqstart); + dolqstart = mm_strdup(yytext); + BEGIN(xdolq); + startlit(); addlit(yytext, yyleng); - free(dolqstart); - dolqstart = NULL; - BEGIN(SQL); - base_yylval.str = mm_strdup(literalbuf); - return DOLCONST; } - else - { - /* - * When we fail to match $...$ to dolqstart, transfer - * the $... part to the output, but put back the final - * $ for rescanning. Consider $delim$...$junk$delim$ - */ - addlit(yytext, yyleng-1); - yyless(yyleng-1); +{dolqfailed} { + /* throw back all but the initial "$" */ + yyless(1); + /* and treat it as {other} */ + return yytext[0]; } - } -{dolqinside} { addlit(yytext, yyleng); } -{dolqfailed} { addlit(yytext, yyleng); } -{other} { - /* single quote or dollar sign */ - addlitchar(yytext[0]); - } -<> { base_yyerror("unterminated dollar-quoted string"); } -{xdstart} { - state_before = YYSTATE; - BEGIN(xd); - startlit(); - } -{xuistart} { - state_before = YYSTATE; - BEGIN(xui); - startlit(); - addlit(yytext, yyleng); - } -{xdstop} { - BEGIN(state_before); - if (literallen == 0) - mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); - /* The backend will truncate the identifier here. We do not as it does not change the result. */ - base_yylval.str = mm_strdup(literalbuf); - return CSTRING; - } -{xdstop} { - BEGIN(state_before); - base_yylval.str = mm_strdup(literalbuf); - return CSTRING; - } -{xuistop} { - BEGIN(state_before); - if (literallen == 2) /* "U&" */ - mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); - /* The backend will truncate the identifier here. We do not as it does not change the result. */ +} /* */ + +{dolqdelim} { + if (strcmp(yytext, dolqstart) == 0) + { addlit(yytext, yyleng); + free(dolqstart); + dolqstart = NULL; + BEGIN(SQL); base_yylval.str = mm_strdup(literalbuf); - return UIDENT; + return DOLCONST; } -{xddouble} { addlitchar('"'); } -{xdinside} { addlit(yytext, yyleng); } -<> { mmfatal(PARSE_ERROR, "unterminated quoted identifier"); } -{xdstart} { - state_before = YYSTATE; - BEGIN(xdc); - startlit(); + else + { + /* + * When we fail to match $...$ to dolqstart, transfer + * the $... part to the output, but put back the final + * $ for rescanning. Consider $delim$...$junk$delim$ + */ + addlit(yytext, yyleng - 1); + yyless(yyleng - 1); } -{xdcinside} { addlit(yytext, yyleng); } -{typecast} { return TYPECAST; } -{dot_dot} { return DOT_DOT; } -{colon_equals} { return COLON_EQUALS; } -{equals_greater} { return EQUALS_GREATER; } -{less_equals} { return LESS_EQUALS; } -{greater_equals} { return GREATER_EQUALS; } -{less_greater} { return NOT_EQUALS; } -{not_equals} { return NOT_EQUALS; } -{informix_special} { + } +{dolqinside} { + addlit(yytext, yyleng); + } +{dolqfailed} { + addlit(yytext, yyleng); + } +. { + /* single quote or dollar sign */ + addlitchar(yytext[0]); + } +<> { mmfatal(PARSE_ERROR, "unterminated dollar-quoted string"); } + +{ +{xdstart} { + state_before = YYSTATE; + BEGIN(xd); + startlit(); + } +{xuistart} { + state_before = YYSTATE; + BEGIN(xui); + startlit(); + addlit(yytext, yyleng); + } +} /* */ + +{xdstop} { + BEGIN(state_before); + if (literallen == 0) + mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); + /* The backend will truncate the identifier here. We do not as it does not change the result. */ + base_yylval.str = mm_strdup(literalbuf); + return CSTRING; + } +{xdstop} { + BEGIN(state_before); + base_yylval.str = mm_strdup(literalbuf); + return CSTRING; + } +{xuistop} { + BEGIN(state_before); + if (literallen == 2) /* "U&" */ + mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier"); + /* The backend will truncate the identifier here. We do not as it does not change the result. */ + addlit(yytext, yyleng); + base_yylval.str = mm_strdup(literalbuf); + return UIDENT; + } +{xddouble} { + addlitchar('"'); + } +{xdinside} { + addlit(yytext, yyleng); + } +<> { mmfatal(PARSE_ERROR, "unterminated quoted identifier"); } +{xdstart} { + state_before = YYSTATE; + BEGIN(xdc); + startlit(); + } +{xdcinside} { + addlit(yytext, yyleng); + } +<> { mmfatal(PARSE_ERROR, "unterminated quoted string"); } + +{ +{typecast} { + return TYPECAST; + } + +{dot_dot} { + return DOT_DOT; + } + +{colon_equals} { + return COLON_EQUALS; + } + +{equals_greater} { + return EQUALS_GREATER; + } + +{less_equals} { + return LESS_EQUALS; + } + +{greater_equals} { + return GREATER_EQUALS; + } + +{less_greater} { + /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ + return NOT_EQUALS; + } + +{not_equals} { + /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ + return NOT_EQUALS; + } + +{informix_special} { /* are we simulating Informix? */ if (INFORMIX_MODE) { @@ -651,152 +761,201 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ else return yytext[0]; } -{self} { /* - * We may find a ';' inside a structure - * definition in a TYPE or VAR statement. - * This is not an EOL marker. - */ - if (yytext[0] == ';' && struct_level == 0) - BEGIN(C); - return yytext[0]; - } -{operator} { - /* - * Check for embedded slash-star or dash-dash; those - * are comment starts, so operator must stop there. - * Note that slash-star or dash-dash at the first - * character will match a prior rule, not this one. - */ - int nchars = yyleng; - char *slashstar = strstr(yytext, "/*"); - char *dashdash = strstr(yytext, "--"); - if (slashstar && dashdash) - { - /* if both appear, take the first one */ - if (slashstar > dashdash) - slashstar = dashdash; - } - else if (!slashstar) +{self} { + /* + * We may find a ';' inside a structure + * definition in a TYPE or VAR statement. + * This is not an EOL marker. + */ + if (yytext[0] == ';' && struct_level == 0) + BEGIN(C); + return yytext[0]; + } + +{operator} { + /* + * Check for embedded slash-star or dash-dash; those + * are comment starts, so operator must stop there. + * Note that slash-star or dash-dash at the first + * character will match a prior rule, not this one. + */ + int nchars = yyleng; + char *slashstar = strstr(yytext, "/*"); + char *dashdash = strstr(yytext, "--"); + + if (slashstar && dashdash) + { + /* if both appear, take the first one */ + if (slashstar > dashdash) slashstar = dashdash; - if (slashstar) - nchars = slashstar - yytext; + } + else if (!slashstar) + slashstar = dashdash; + if (slashstar) + nchars = slashstar - yytext; - /* - * For SQL compatibility, '+' and '-' cannot be the - * last char of a multi-char operator unless the operator - * contains chars that are not in SQL operators. - * The idea is to lex '=-' as two operators, but not - * to forbid operator names like '?-' that could not be - * sequences of SQL operators. - */ - while (nchars > 1 && - (yytext[nchars-1] == '+' || - yytext[nchars-1] == '-')) - { - int ic; + /* + * For SQL compatibility, '+' and '-' cannot be the + * last char of a multi-char operator unless the operator + * contains chars that are not in SQL operators. + * The idea is to lex '=-' as two operators, but not + * to forbid operator names like '?-' that could not be + * sequences of SQL operators. + */ + if (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')) + { + int ic; - for (ic = nchars-2; ic >= 0; ic--) - { - if (strchr("~!@#^&|`?%", yytext[ic])) - break; - } - if (ic >= 0) - break; /* found a char that makes it OK */ - nchars--; /* else remove the +/-, and check again */ + for (ic = nchars - 2; ic >= 0; ic--) + { + char c = yytext[ic]; + if (c == '~' || c == '!' || c == '@' || + c == '#' || c == '^' || c == '&' || + c == '|' || c == '`' || c == '?' || + c == '%') + break; } - - if (nchars < yyleng) + if (ic < 0) { - /* Strip the unwanted chars from the token */ - yyless(nchars); /* - * If what we have left is only one char, and it's - * one of the characters matching "self", then - * return it as a character token the same way - * that the "self" rule would have. + * didn't find a qualifying character, so remove + * all trailing [+-] */ - if (nchars == 1 && - strchr(",()[].;:+-*/%^<>=", yytext[0])) - return yytext[0]; + do { + nchars--; + } while (nchars > 1 && + (yytext[nchars - 1] == '+' || + yytext[nchars - 1] == '-')); } - - base_yylval.str = mm_strdup(yytext); - return Op; - } -{param} { - base_yylval.ival = atol(yytext+1); - return PARAM; } -{integer} { - int val; - char* endptr; - errno = 0; - val = strtoint(yytext, &endptr, 10); - if (*endptr != '\0' || errno == ERANGE) + if (nchars < yyleng) + { + /* Strip the unwanted chars from the token */ + yyless(nchars); + /* + * If what we have left is only one char, and it's + * one of the characters matching "self", then + * return it as a character token the same way + * that the "self" rule would have. + */ + if (nchars == 1 && + strchr(",()[].;:+-*/%^<>=", yytext[0])) + return yytext[0]; + /* + * Likewise, if what we have left is two chars, and + * those match the tokens ">=", "<=", "=>", "<>" or + * "!=", then we must return the appropriate token + * rather than the generic Op. + */ + if (nchars == 2) { - errno = 0; - base_yylval.str = mm_strdup(yytext); - return FCONST; + if (yytext[0] == '=' && yytext[1] == '>') + return EQUALS_GREATER; + if (yytext[0] == '>' && yytext[1] == '=') + return GREATER_EQUALS; + if (yytext[0] == '<' && yytext[1] == '=') + return LESS_EQUALS; + if (yytext[0] == '<' && yytext[1] == '>') + return NOT_EQUALS; + if (yytext[0] == '!' && yytext[1] == '=') + return NOT_EQUALS; } - base_yylval.ival = val; - return ICONST; } -{ip} { - base_yylval.str = mm_strdup(yytext); - return IP; + + base_yylval.str = mm_strdup(yytext); + return Op; } -{decimal} { - base_yylval.str = mm_strdup(yytext); - return FCONST; - } -{real} { - base_yylval.str = mm_strdup(yytext); - return FCONST; - } -{realfail1} { - yyless(yyleng-1); - base_yylval.str = mm_strdup(yytext); - return FCONST; - } -{realfail2} { - yyless(yyleng-2); + +{param} { + base_yylval.ival = atol(yytext+1); + return PARAM; + } + +{ip} { + base_yylval.str = mm_strdup(yytext); + return IP; + } +} /* */ + +{ +{integer} { + return process_integer_literal(yytext, &base_yylval); + } +{decimal} { + base_yylval.str = mm_strdup(yytext); + return FCONST; + } +{decimalfail} { + /* throw back the .., and treat as integer */ + yyless(yyleng - 2); + return process_integer_literal(yytext, &base_yylval); + } +{real} { + base_yylval.str = mm_strdup(yytext); + return FCONST; + } +{realfail1} { + /* + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. + */ + yyless(yyleng - 1); + return process_integer_literal(yytext, &base_yylval); + } +{realfail2} { + /* throw back the [Ee][+-], and proceed as above */ + yyless(yyleng - 2); + return process_integer_literal(yytext, &base_yylval); + } +} /* */ + +{ +:{identifier}((("->"|\.){identifier})|(\[{array}\]))* { + base_yylval.str = mm_strdup(yytext+1); + return CVARIABLE; + } + +{identifier} { + if (!isdefine()) + { + int kwvalue; + + /* Is it an SQL/ECPG keyword? */ + kwvalue = ScanECPGKeywordLookup(yytext); + if (kwvalue >= 0) + return kwvalue; + + /* Is it a C keyword? */ + kwvalue = ScanCKeywordLookup(yytext); + if (kwvalue >= 0) + return kwvalue; + + /* + * None of the above. Return it as an identifier. + * + * The backend will attempt to truncate and case-fold + * the identifier, but I see no good reason for ecpg + * to do so; that's just another way that ecpg could get + * out of step with the backend. + */ base_yylval.str = mm_strdup(yytext); - return FCONST; + return IDENT; } -:{identifier}((("->"|\.){identifier})|(\[{array}\]))* { - base_yylval.str = mm_strdup(yytext+1); - return CVARIABLE; - } -{identifier} { - const ScanKeyword *keyword; + } - if (!isdefine()) - { - /* Is it an SQL/ECPG keyword? */ - keyword = ScanECPGKeywordLookup(yytext); - if (keyword != NULL) - return keyword->value; +{other} { + return yytext[0]; + } +} /* */ - /* Is it a C keyword? */ - keyword = ScanCKeywordLookup(yytext); - if (keyword != NULL) - return keyword->value; + /* + * Begin ECPG-specific rules + */ - /* - * None of the above. Return it as an identifier. - * - * The backend will attempt to truncate and case-fold - * the identifier, but I see no good reason for ecpg - * to do so; that's just another way that ecpg could get - * out of step with the backend. - */ - base_yylval.str = mm_strdup(yytext); - return IDENT; - } - } -{other} { return yytext[0]; } {exec_sql} { BEGIN(SQL); return SQL_START; } {informix_special} { /* are we simulating Informix? */ @@ -851,12 +1010,11 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ return CPP_LINE; } {identifier} { - const ScanKeyword *keyword; - /* * Try to detect a function name: * look for identifiers at the global scope - * keep the last identifier before the first '(' and '{' */ + * keep the last identifier before the first '(' and '{' + */ if (braces_open == 0 && parenths_open == 0) { if (current_function) @@ -867,9 +1025,11 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ /* however, some defines have to be taken care of for compatibility */ if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine()) { - keyword = ScanCKeywordLookup(yytext); - if (keyword != NULL) - return keyword->value; + int kwvalue; + + kwvalue = ScanCKeywordLookup(yytext); + if (kwvalue >= 0) + return kwvalue; else { base_yylval.str = mm_strdup(yytext); @@ -954,14 +1114,14 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ for (ptr = defines; ptr != NULL; ptr2 = ptr, ptr = ptr->next) { - if (strcmp(yytext, ptr->old) == 0) + if (strcmp(yytext, ptr->olddef) == 0) { if (ptr2 == NULL) defines = ptr->next; else ptr2->next = ptr->next; - free(ptr->new); - free(ptr->old); + free(ptr->newdef); + free(ptr->olddef); free(ptr); break; } @@ -1140,8 +1300,10 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ yytext[i+1] = '\0'; for (defptr = defines; - defptr != NULL && strcmp(yytext, defptr->old) != 0; - defptr = defptr->next); + defptr != NULL && + strcmp(yytext, defptr->olddef) != 0; + defptr = defptr->next) + /* skip */ ; preproc_tos++; stacked_if_value[preproc_tos].else_branch = false; @@ -1173,10 +1335,10 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ for (ptr = defines; ptr != NULL; ptr = ptr->next) { - if (strcmp(old, ptr->old) == 0) + if (strcmp(old, ptr->olddef) == 0) { - free(ptr->new); - ptr->new = mm_strdup(literalbuf); + free(ptr->newdef); + ptr->newdef = mm_strdup(literalbuf); } } if (ptr == NULL) @@ -1184,8 +1346,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ this = (struct _defines *) mm_alloc(sizeof(struct _defines)); /* initial definition */ - this->old = old; - this->new = mm_strdup(literalbuf); + this->olddef = old; + this->newdef = mm_strdup(literalbuf); this->next = defines; this->used = NULL; defines = this; @@ -1247,7 +1409,8 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } } -{other}|\n { mmfatal(PARSE_ERROR, "internal error: unreachable state; please report this to "); } + +{other}|\n { mmfatal(PARSE_ERROR, "internal error: unreachable state; please report this to "); } %% @@ -1270,7 +1433,7 @@ lex_init(void) if (literalbuf == NULL) { literalalloc = 1024; - literalbuf = (char *) malloc(literalalloc); + literalbuf = (char *) mm_alloc(literalalloc); } startlit(); @@ -1309,6 +1472,28 @@ addlitchar(unsigned char ychar) literalbuf[literallen] = '\0'; } +/* + * Process {integer}. Note this will also do the right thing with {decimal}, + * ie digits and a decimal point. + */ +static int +process_integer_literal(const char *token, YYSTYPE *lval) +{ + int val; + char *endptr; + + errno = 0; + val = strtoint(token, &endptr, 10); + if (*endptr != '\0' || errno == ERANGE) + { + /* integer too large (or contains decimal pt), treat it as a float */ + lval->str = mm_strdup(token); + return FCONST; + } + lval->ival = val; + return ICONST; +} + static void parse_include(void) { @@ -1355,7 +1540,7 @@ parse_include(void) yyin = fopen(inc_file, "r"); if (!yyin) { - if (strcmp(inc_file + strlen(inc_file) - 2, ".h") != 0) + if (strlen(inc_file) <= 2 || strcmp(inc_file + strlen(inc_file) - 2, ".h") != 0) { strcat(inc_file, ".h"); yyin = fopen(inc_file, "r"); @@ -1373,7 +1558,7 @@ parse_include(void) for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next) { - if (strlen(ip->path) + strlen(yytext) + 3 > MAXPGPATH) + if (strlen(ip->path) + strlen(yytext) + 4 > MAXPGPATH) { fprintf(stderr, _("Error: include path \"%s/%s\" is too long on line %d, skipping\n"), ip->path, yytext, yylineno); continue; @@ -1430,7 +1615,7 @@ static bool isdefine(void) /* is it a define? */ for (ptr = defines; ptr; ptr = ptr->next) { - if (strcmp(yytext, ptr->old) == 0 && ptr->used == NULL) + if (strcmp(yytext, ptr->olddef) == 0 && ptr->used == NULL) { struct _yy_buffer *yb; @@ -1443,7 +1628,7 @@ static bool isdefine(void) ptr->used = yy_buffer = yb; - yy_scan_string(ptr->new); + yy_scan_string(ptr->newdef); return true; } } @@ -1480,44 +1665,3 @@ static bool isinformixdefine(void) return false; } - -/* - * Called before any actual parsing is done - */ -void -scanner_init(const char *str) -{ - Size slen = strlen(str); - - /* - * Might be left over after ereport() - */ - if (YY_CURRENT_BUFFER) - yy_delete_buffer(YY_CURRENT_BUFFER); - - /* - * Make a scan buffer with special termination needed by flex. - */ - scanbuf = mm_alloc(slen + 2); - memcpy(scanbuf, str, slen); - scanbuf[slen] = scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR; - scanbufhandle = yy_scan_buffer(scanbuf, slen + 2); - - /* initialize literal buffer to a reasonable but expansible size */ - literalalloc = 128; - literalbuf = (char *) mm_alloc(literalalloc); - startlit(); - - BEGIN(INITIAL); -} - - -/* - * Called after parsing is done to clean up after scanner_init() - */ -void -scanner_finish(void) -{ - yy_delete_buffer(scanbufhandle); - free(scanbuf); -} diff --git a/src/interfaces/ecpg/preproc/po/cs.po b/src/interfaces/ecpg/preproc/po/cs.po index e145037fd12..a8e1036e833 100644 --- a/src/interfaces/ecpg/preproc/po/cs.po +++ b/src/interfaces/ecpg/preproc/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: ecpg-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-09-18 16:40+0000\n" -"PO-Revision-Date: 2012-09-19 01:01+0200\n" +"POT-Creation-Date: 2018-07-13 19:38+0000\n" +"PO-Revision-Date: 2018-07-13 23:43+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.4\n" +"X-Generator: Poedit 2.0.7\n" #: descriptor.c:64 #, c-format @@ -28,27 +28,27 @@ msgstr "promÄ›nná \"%s\" musí mít Äíselný typ" msgid "descriptor \"%s\" does not exist" msgstr "descriptor \"%s\" neexistuje" -#: descriptor.c:161 descriptor.c:210 +#: descriptor.c:161 descriptor.c:213 #, c-format msgid "descriptor header item \"%d\" does not exist" msgstr "descriptor header item \"%d\" neexistuje" -#: descriptor.c:182 +#: descriptor.c:183 #, c-format msgid "nullable is always 1" msgstr "nullable je vždy 1" -#: descriptor.c:185 +#: descriptor.c:186 #, c-format msgid "key_member is always 0" msgstr "key_member je vždy 0" -#: descriptor.c:277 +#: descriptor.c:280 #, c-format msgid "descriptor item \"%s\" is not implemented" msgstr "descriptor item \"%s\" není implementován" -#: descriptor.c:287 +#: descriptor.c:290 #, c-format msgid "descriptor item \"%s\" cannot be set" msgstr "descriptor item \"%s\" nelze nastavit" @@ -91,10 +91,10 @@ msgstr "" #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" " -C MÓD nastaví mód kompatibility; MÓD může být jedno z \n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" #: ecpg.c:46 #, c-format @@ -150,12 +150,11 @@ msgstr " -t zapne autocommit transakcí\n" #: ecpg.c:57 #, c-format -msgid " --version output version information, then exit\n" -msgstr " --version vypíše informaci o verzi, poté skonÄí\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version vypíše informaci o verzi, poté skonÄí\n" #: ecpg.c:58 #, c-format -#| msgid " --help show this help, then exit\n" msgid " -?, --help show this help, then exit\n" msgstr " -?, --help zobrazí tuto nápovÄ›du; poté skonÄí\n" @@ -180,132 +179,142 @@ msgstr "" "\n" "Chyby hlaste na adresu .\n" -#: ecpg.c:182 ecpg.c:333 ecpg.c:343 +#: ecpg.c:139 +#, c-format +msgid "%s: could not locate my own executable path\n" +msgstr "%s: nelze nalézt cestu k vlastnímu spustitelnému souboru\n" + +#: ecpg.c:174 ecpg.c:331 ecpg.c:342 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: nelze otevřít soubor \"%s\": %s\n" -#: ecpg.c:221 ecpg.c:234 ecpg.c:250 ecpg.c:275 +#: ecpg.c:217 ecpg.c:230 ecpg.c:246 ecpg.c:272 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Zkuste \"%s --help\" pro více informací.\n" -#: ecpg.c:245 +#: ecpg.c:241 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: podpora pro ladicí informace parseru (-d) není dostupná\n" -#: ecpg.c:263 +#: ecpg.c:260 #, c-format -msgid "%s, the PostgreSQL embedded C preprocessor, version %d.%d.%d\n" -msgstr "%s, PostgreSQL embedded C preprocessor, verze %d.%d.%d\n" +msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" +msgstr "%s, PostgreSQL embedded C preprocessor, verze %s\n" -#: ecpg.c:265 +#: ecpg.c:262 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... hledání zaÄíná zde:\n" -#: ecpg.c:268 +#: ecpg.c:265 #, c-format msgid "end of search list\n" msgstr "konec vyhledávacího seznamu\n" -#: ecpg.c:274 +#: ecpg.c:271 #, c-format msgid "%s: no input files specified\n" msgstr "%s: nebyl zadán žádný vstupní soubor\n" -#: ecpg.c:466 +#: ecpg.c:465 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "kurzor \"%s\" byl deklarován ale nebyl otevÅ™en" -#: ecpg.c:479 preproc.y:109 +#: ecpg.c:478 preproc.y:127 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "nelze odstranit výstupní soubor \"%s\"\n" -#: pgc.l:403 +#: pgc.l:435 #, c-format msgid "unterminated /* comment" msgstr "neukonÄený /* komentář" -#: pgc.l:416 +#: pgc.l:448 #, c-format msgid "invalid bit string literal" msgstr "neplatný bit string literál" -#: pgc.l:425 +#: pgc.l:457 #, c-format msgid "unterminated bit string literal" msgstr "neukonÄený literál - bitový Å™etÄ›zec" -#: pgc.l:441 +#: pgc.l:473 #, c-format msgid "unterminated hexadecimal string literal" msgstr "neukonÄený literál - hexadecimální Å™etÄ›zec" -#: pgc.l:519 +#: pgc.l:551 #, c-format msgid "unterminated quoted string" msgstr "neukonÄený Å™etÄ›zec v uvozovkách" -#: pgc.l:574 pgc.l:587 +#: pgc.l:609 pgc.l:622 #, c-format msgid "zero-length delimited identifier" msgstr "ohraniÄený (delimited) identifikátor s nulovou délkou" -#: pgc.l:595 +#: pgc.l:630 #, c-format msgid "unterminated quoted identifier" msgstr "neukonÄený identifikátor v uvozovkách" -#: pgc.l:941 +#: pgc.l:880 +#, c-format +msgid "nested /* ... */ comments" +msgstr "vnoÅ™ené /* ... */ komentáře" + +#: pgc.l:973 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "chybÄ›jící identifikátor v příkazu EXEC SQL UNDEF" -#: pgc.l:987 pgc.l:1001 +#: pgc.l:1019 pgc.l:1033 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "chybÄ›jící odpovídající \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" -#: pgc.l:990 pgc.l:1003 pgc.l:1179 +#: pgc.l:1022 pgc.l:1035 pgc.l:1211 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "chybÄ›jící \"EXEC SQL ENDIF;\"" -#: pgc.l:1019 pgc.l:1038 +#: pgc.l:1051 pgc.l:1070 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "více než jedna vÄ›tev EXEC SQL ELSE" -#: pgc.l:1060 pgc.l:1074 +#: pgc.l:1092 pgc.l:1106 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "neodpovídající EXEC SQL ENDIF" -#: pgc.l:1094 +#: pgc.l:1126 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "příliÅ¡ mnoho zanoÅ™ených EXEC SQL IFDEF podmínek" -#: pgc.l:1127 +#: pgc.l:1159 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "chybÄ›jící identifikátor v příkazu EXEC SQL IFDEF" -#: pgc.l:1136 +#: pgc.l:1168 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "chybÄ›jící identifikátor v příkazu EXEC SQL DEFINE" -#: pgc.l:1169 +#: pgc.l:1201 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "syntaktická chyba v příkazu EXEC SQL INCLUDE" -#: pgc.l:1218 +#: pgc.l:1250 #, c-format msgid "" "internal error: unreachable state; please report this to " -#: pgc.l:1343 +#: pgc.l:1379 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "" "Chyba: include path \"%s/%s\" na řádku %d je příliÅ¡ dlouhá, pÅ™eskakuji\n" -#: pgc.l:1365 +#: pgc.l:1402 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "nelze otevřít soubor \"%s\" na řádku %d" @@ -334,128 +343,119 @@ msgstr "syntaktická chyba" msgid "WARNING: " msgstr "VAROVÃNÃ: " -#: preproc.y:85 +#: preproc.y:84 #, c-format msgid "ERROR: " msgstr "CHYBA: " -#: preproc.y:491 +#: preproc.y:508 #, c-format msgid "cursor \"%s\" does not exist" msgstr "kurzor \"%s\" neexistuje" -#: preproc.y:520 +#: preproc.y:537 #, c-format msgid "initializer not allowed in type definition" msgstr "inicializátor (initializer) není v definici typu povolen" -#: preproc.y:522 +#: preproc.y:539 #, c-format msgid "type name \"string\" is reserved in Informix mode" msgstr "název typu \"string\" je vyhrazen pro mód Informix" -#: preproc.y:529 preproc.y:13277 +#: preproc.y:546 preproc.y:15731 #, c-format msgid "type \"%s\" is already defined" msgstr "typ \"%s\" je již definován" -#: preproc.y:553 preproc.y:13930 preproc.y:14251 variable.c:610 +#: preproc.y:570 preproc.y:16389 preproc.y:16714 variable.c:620 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "vícerozmÄ›rná pole pro jednoduché datové typy nejsou podporována" -#: preproc.y:1526 +#: preproc.y:1693 #, c-format msgid "AT option not allowed in CLOSE DATABASE statement" msgstr "AT volba není v příkazu CLOSE DATABASE povolena" -#: preproc.y:1723 +#: preproc.y:1902 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "AT volba není v příkazu CONNECT povolena" -#: preproc.y:1757 +#: preproc.y:1936 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "AT volba není v příkazu DISCONNECT povolena" -#: preproc.y:1812 +#: preproc.y:1991 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "AT volba není v příkazu SET CONNECTION povolena" -#: preproc.y:1834 +#: preproc.y:2013 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "AT volba není v příkazu TYPE povolena" -#: preproc.y:1843 +#: preproc.y:2022 #, c-format msgid "AT option not allowed in VAR statement" msgstr "AT volba není v příkazu VAR povolena" -#: preproc.y:1850 +#: preproc.y:2029 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "AT volba není v příkazu WHENEVER povolena" -#: preproc.y:2204 preproc.y:3489 preproc.y:4658 preproc.y:4667 preproc.y:4952 -#: preproc.y:7343 preproc.y:7348 preproc.y:7353 preproc.y:9695 preproc.y:10242 +#: preproc.y:2106 preproc.y:2278 preproc.y:2283 preproc.y:2399 preproc.y:4044 +#: preproc.y:5602 preproc.y:5611 preproc.y:5911 preproc.y:7510 preproc.y:9003 +#: preproc.y:9008 preproc.y:11799 #, c-format msgid "unsupported feature will be passed to server" msgstr "nepodporovaná vlastnost bude pÅ™edána serveru" -#: preproc.y:2446 +#: preproc.y:2657 #, c-format msgid "SHOW ALL is not implemented" msgstr "příkaz SHOW ALL není implementován" -#: preproc.y:2889 preproc.y:2900 -#, c-format -msgid "COPY TO STDIN is not possible" -msgstr "příkaz COPY TO STDIN nelze použít" - -#: preproc.y:2891 -#, c-format -msgid "COPY FROM STDOUT is not possible" -msgstr "příkaz COPY FROM STDOUT nelze použít" - -#: preproc.y:2893 +#: preproc.y:3385 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "příkaz COPY FROM STDIN není implementován" -#: preproc.y:8157 preproc.y:12866 +#: preproc.y:9956 preproc.y:15320 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "použití promÄ›nné \"%s\" v dalších deklaracích není podporováno" -#: preproc.y:8159 preproc.y:12868 +#: preproc.y:9958 preproc.y:15322 #, c-format msgid "cursor \"%s\" is already defined" msgstr "kurzor \"%s\" je již definován" -#: preproc.y:8577 +#: preproc.y:10388 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "již neopdporovaná syntaxe LIMIT #,# pÅ™edána serveru" -#: preproc.y:8812 +#: preproc.y:10713 preproc.y:10720 #, c-format msgid "subquery in FROM must have an alias" msgstr "poddotaz ve FROM musí mít alias" -#: preproc.y:12596 +#: preproc.y:15050 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE AS nemůže specifikovat INTO" -#: preproc.y:12632 +#: preproc.y:15086 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "oÄekáváno \"@\", nalezeno \"%s\"" -#: preproc.y:12644 +#: preproc.y:15098 #, c-format msgid "" "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are " @@ -464,83 +464,88 @@ msgstr "" "podporovány jsou pouze protokoly \"tcp\" a \"unix\" a typ databáze " "\"postgresql\"" -#: preproc.y:12647 +#: preproc.y:15101 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "oÄekáváno \"://\", nalezeno \"%s\"" -#: preproc.y:12652 +#: preproc.y:15106 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" msgstr "Unixové sockety fungují pouze na \"localhost\" ale ne na \"%s\"" -#: preproc.y:12678 +#: preproc.y:15132 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "oÄekáváno \"postgresql\", nalezeno \"%s\"" -#: preproc.y:12681 +#: preproc.y:15135 #, c-format msgid "invalid connection type: %s" msgstr "chybný typ spojení: %s" -#: preproc.y:12690 +#: preproc.y:15144 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "oÄekáváno \"@\" nebo \"://\", nalezeno \"%s\"" -#: preproc.y:12765 preproc.y:12783 +#: preproc.y:15219 preproc.y:15237 #, c-format msgid "invalid data type" msgstr "chybný datový typ" -#: preproc.y:12794 preproc.y:12811 +#: preproc.y:15248 preproc.y:15265 #, c-format msgid "incomplete statement" msgstr "neúplný příkaz" -#: preproc.y:12797 preproc.y:12814 +#: preproc.y:15251 preproc.y:15268 #, c-format msgid "unrecognized token \"%s\"" msgstr "nerozpoznaný token \"%s\"" -#: preproc.y:13088 +#: preproc.y:15542 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "pouze datové typy numeric a decimal mají argumenty pÅ™esnost/velikost" -#: preproc.y:13100 +#: preproc.y:15554 #, c-format msgid "interval specification not allowed here" msgstr "specifikace intervalu zde není povolena" -#: preproc.y:13252 preproc.y:13304 +#: preproc.y:15706 preproc.y:15758 #, c-format msgid "too many levels in nested structure/union definition" msgstr "příliÅ¡ mnoho úrovní v definici vnoÅ™ené struktury/union" -#: preproc.y:13438 +#: preproc.y:15897 #, c-format msgid "pointers to varchar are not implemented" msgstr "ukazatele na varchar nejsou implementovány" -#: preproc.y:13625 preproc.y:13650 +#: preproc.y:16084 preproc.y:16109 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "použití nepodporovaného příkazu DESCRIBE" -#: preproc.y:13897 +#: preproc.y:16356 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "inicializátor není v příkazu EXEC SQL VAR podporován" -#: preproc.y:14209 +#: preproc.y:16672 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "pole identifikátorů nejsou na vstupu povolena" +#: preproc.y:16893 +#, c-format +msgid "operator not allowed in variable definition" +msgstr "operátor není povolen v definici promÄ›nné" + #. translator: %s is typically the translation of "syntax error" -#: preproc.y:14463 +#: preproc.y:16934 #, c-format msgid "%s at or near \"%s\"" msgstr "%s na nebo blízko \"%s\"" @@ -550,7 +555,7 @@ msgstr "%s na nebo blízko \"%s\"" msgid "out of memory" msgstr "paměť vyÄerpána" -#: type.c:212 type.c:590 +#: type.c:212 type.c:676 #, c-format msgid "unrecognized variable type code %d" msgstr "nerozpoznaný kód typu promÄ›nné %d" @@ -587,67 +592,77 @@ msgstr "indicator variable pro pole/ukaztel musí být pole/ukazatel" msgid "nested arrays are not supported (except strings)" msgstr "vnoÅ™ená pole nejsou podporována (kromÄ› Å™etÄ›zců)" -#: type.c:322 +#: type.c:331 #, c-format msgid "indicator for struct has to be a struct" msgstr "indikátor pro strukturu musí být struktura" -#: type.c:331 type.c:339 type.c:347 +#: type.c:351 type.c:372 type.c:392 #, c-format msgid "indicator for simple data type has to be simple" msgstr "indikátor pro jednoduché datové typy musí být jednoduchý" -#: type.c:649 +#: type.c:616 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "indikátor pro strukturu \"%s\" má příliÅ¡ málo položek" + +#: type.c:624 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "indikátor pro strukturu \"%s\" má příliÅ¡ mnoho položek" + +#: type.c:735 #, c-format msgid "unrecognized descriptor item code %d" msgstr "nerozpoznaný kód deskriptoru položky %d" -#: variable.c:89 variable.c:112 +#: variable.c:89 variable.c:116 #, c-format msgid "incorrectly formed variable \"%s\"" msgstr "nesprávnÄ› vytvoÅ™ený název promÄ›nné \"%s\"" -#: variable.c:135 +#: variable.c:139 #, c-format msgid "variable \"%s\" is not a pointer" msgstr "promÄ›nná \"%s\" není ukazatel" -#: variable.c:138 variable.c:163 +#: variable.c:142 variable.c:167 #, c-format msgid "variable \"%s\" is not a pointer to a structure or a union" msgstr "promÄ›nná \"%s\" není ukazatel na strukturu nebo sjednocení" -#: variable.c:150 +#: variable.c:154 #, c-format msgid "variable \"%s\" is neither a structure nor a union" msgstr "promÄ›nná \"%s\" není ani struktura ani sjednocení" -#: variable.c:160 +#: variable.c:164 #, c-format msgid "variable \"%s\" is not an array" msgstr "promÄ›nná \"%s\" není pole" -#: variable.c:229 variable.c:251 +#: variable.c:233 variable.c:255 #, c-format msgid "variable \"%s\" is not declared" msgstr "promÄ›nná \"%s\" není deklarována" -#: variable.c:484 +#: variable.c:494 #, c-format msgid "indicator variable must have an integer type" msgstr "indicator variable musí mít celoÄíselný typ" -#: variable.c:496 +#: variable.c:506 #, c-format msgid "unrecognized data type name \"%s\"" msgstr "nerozpoznaný název datového typu \"%s\"" -#: variable.c:507 variable.c:515 variable.c:532 variable.c:535 +#: variable.c:517 variable.c:525 variable.c:542 variable.c:545 #, c-format msgid "multidimensional arrays are not supported" msgstr "vícerozmÄ›rná pole nejsou podporována" -#: variable.c:524 +#: variable.c:534 #, c-format msgid "" "multilevel pointers (more than 2 levels) are not supported; found %d level" @@ -663,13 +678,18 @@ msgstr[2] "" "víceúrovňové ukazatele (více než 2 úrovnÄ›) nejsou podporovány; nalezeny %d " "úrovnÄ›" -#: variable.c:529 +#: variable.c:539 #, c-format msgid "pointer to pointer is not supported for this data type" msgstr "ukazatel na ukazatel není pro tento datový typ podporován" -#: variable.c:549 +#: variable.c:559 #, c-format msgid "multidimensional arrays for structures are not supported" msgstr "vícerozmÄ›rná pole pro struktury nejsou podporována" +#~ msgid "COPY TO STDIN is not possible" +#~ msgstr "příkaz COPY TO STDIN nelze použít" + +#~ msgid "COPY FROM STDOUT is not possible" +#~ msgstr "příkaz COPY FROM STDOUT nelze použít" diff --git a/src/interfaces/ecpg/preproc/po/de.po b/src/interfaces/ecpg/preproc/po/de.po index 8cd9678b1dd..c729ea5c995 100644 --- a/src/interfaces/ecpg/preproc/po/de.po +++ b/src/interfaces/ecpg/preproc/po/de.po @@ -1,16 +1,16 @@ # German message translation file for ecpg -# Copyright (C) 2009-2017 PostgreSQL Global Development Group +# Copyright (C) 2009-2018 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2009-2017. +# Peter Eisentraut , 2009-2018. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" +"Project-Id-Version: PostgreSQL 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-02-10 21:38+0000\n" -"PO-Revision-Date: 2017-02-10 18:33-0500\n" +"POT-Creation-Date: 2018-05-07 00:38+0000\n" +"PO-Revision-Date: 2018-05-06 21:09-0400\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -92,10 +92,10 @@ msgstr "" #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" " -C MODUS Kompatibilitätsmodus setzen; MODUS kann sein:\n" -" »INFORMIX« oder »INFORMIX_SE«\n" +" »INFORMIX«, »INFORMIX_SE«, »ORACLE«\n" #: ecpg.c:46 #, c-format @@ -181,147 +181,147 @@ msgstr "" msgid "%s: could not locate my own executable path\n" msgstr "%s: konnte Pfad des eigenen Programs nicht finden\n" -#: ecpg.c:174 ecpg.c:327 ecpg.c:337 +#: ecpg.c:174 ecpg.c:331 ecpg.c:342 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: konnte Datei »%s« nicht öffnen: %s\n" -#: ecpg.c:213 ecpg.c:226 ecpg.c:242 ecpg.c:268 +#: ecpg.c:217 ecpg.c:230 ecpg.c:246 ecpg.c:272 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n" -#: ecpg.c:237 +#: ecpg.c:241 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: Unterstützung für Parserdebugging (-d) nicht verfügbar\n" -#: ecpg.c:256 +#: ecpg.c:260 #, c-format msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" msgstr "%s, der PostgreSQL-Embedded-C-Präprozessor, Version %s\n" -#: ecpg.c:258 +#: ecpg.c:262 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... Suche beginnt hier:\n" -#: ecpg.c:261 +#: ecpg.c:265 #, c-format msgid "end of search list\n" msgstr "Ende der Suchliste\n" -#: ecpg.c:267 +#: ecpg.c:271 #, c-format msgid "%s: no input files specified\n" msgstr "%s: keine Eingabedateien angegeben\n" -#: ecpg.c:460 +#: ecpg.c:465 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "Cursor »%s« wurde deklariert aber nicht geöffnet" -#: ecpg.c:473 preproc.y:127 +#: ecpg.c:478 preproc.y:127 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "konnte Ausgabedatei »%s« nicht entfernen\n" -#: pgc.l:432 +#: pgc.l:435 #, c-format msgid "unterminated /* comment" msgstr "/*-Kommentar nicht abgeschlossen" -#: pgc.l:445 +#: pgc.l:448 #, c-format msgid "invalid bit string literal" msgstr "ungültige Bitkettenkonstante" -#: pgc.l:454 +#: pgc.l:457 #, c-format msgid "unterminated bit string literal" msgstr "Bitkettenkonstante nicht abgeschlossen" -#: pgc.l:470 +#: pgc.l:473 #, c-format msgid "unterminated hexadecimal string literal" msgstr "hexadezimale Zeichenkette nicht abgeschlossen" -#: pgc.l:548 +#: pgc.l:551 #, c-format msgid "unterminated quoted string" msgstr "Zeichenkette in Anführungszeichen nicht abgeschlossen" -#: pgc.l:605 pgc.l:618 +#: pgc.l:609 pgc.l:622 #, c-format msgid "zero-length delimited identifier" msgstr "Bezeichner in Anführungszeichen hat Länge null" -#: pgc.l:626 +#: pgc.l:630 #, c-format msgid "unterminated quoted identifier" msgstr "Bezeichner in Anführungszeichen nicht abgeschlossen" -#: pgc.l:881 +#: pgc.l:880 #, c-format msgid "nested /* ... */ comments" msgstr "geschachtelte /* ... */-Kommentare" -#: pgc.l:974 +#: pgc.l:973 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "fehlender Bezeichner im Befehl EXEC SQL UNDEF" -#: pgc.l:1020 pgc.l:1034 +#: pgc.l:1019 pgc.l:1033 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "passendes »EXEC SQL IFDEF« / »EXEC SQL IFNDEF« fehlt" -#: pgc.l:1023 pgc.l:1036 pgc.l:1212 +#: pgc.l:1022 pgc.l:1035 pgc.l:1211 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "»EXEC SQL ENDIF;« fehlt" -#: pgc.l:1052 pgc.l:1071 +#: pgc.l:1051 pgc.l:1070 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "mehr als ein EXEC SQL ENDIF" -#: pgc.l:1093 pgc.l:1107 +#: pgc.l:1092 pgc.l:1106 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "unzusammenhängendes EXEC SQL ENDIF" -#: pgc.l:1127 +#: pgc.l:1126 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "zu viele verschachtelte EXEC SQL IFDEF-Bedingungen" -#: pgc.l:1160 +#: pgc.l:1159 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "fehlender Bezeichner im Befehl EXEC SQL IFDEF" -#: pgc.l:1169 +#: pgc.l:1168 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "fehlender Bezeichner im Befehl EXEC SQL DEFINE" -#: pgc.l:1202 +#: pgc.l:1201 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "Syntaxfehler im Befehl EXEC SQL INCLUDE" -#: pgc.l:1251 +#: pgc.l:1250 #, c-format msgid "internal error: unreachable state; please report this to " msgstr "interner Fehler: unerreichbarer Zustand; bitte an berichten" -#: pgc.l:1375 +#: pgc.l:1379 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "Fehler: Include-Pfad »%s/%s« ist zu lang auf Zeile %d, wird übersprungen\n" -#: pgc.l:1398 +#: pgc.l:1402 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "konnte Include-Datei »%s« nicht öffnen auf Zeile %d" @@ -355,185 +355,185 @@ msgstr "Initialisierungswert nicht erlaubt in Typdefinition" msgid "type name \"string\" is reserved in Informix mode" msgstr "Typname »string« ist im Informix-Modus reserviert" -#: preproc.y:546 preproc.y:15083 +#: preproc.y:546 preproc.y:15722 #, c-format msgid "type \"%s\" is already defined" msgstr "Typ »%s« ist bereits definiert" -#: preproc.y:570 preproc.y:15741 preproc.y:16061 variable.c:620 +#: preproc.y:570 preproc.y:16380 preproc.y:16705 variable.c:620 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "mehrdimensionale Arrays für einfache Datentypen werden nicht unterstützt" -#: preproc.y:1667 +#: preproc.y:1693 #, c-format msgid "AT option not allowed in CLOSE DATABASE statement" msgstr "AT-Option ist nicht erlaubt im Befehl CLOSE DATABASE" -#: preproc.y:1888 +#: preproc.y:1902 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "AT-Option ist nicht erlaubt im Befehl CONNECT" -#: preproc.y:1922 +#: preproc.y:1936 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "AT-Option ist nicht erlaubt im Befehl DISCONNECT" -#: preproc.y:1977 +#: preproc.y:1991 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "AT-Option ist nicht erlaubt im Befehl SET CONNECTION" -#: preproc.y:1999 +#: preproc.y:2013 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "AT-Option ist nicht erlaubt im TYPE-Befehl" -#: preproc.y:2008 +#: preproc.y:2022 #, c-format msgid "AT option not allowed in VAR statement" msgstr "AT-Option ist nicht erlaubt im VAR-Befehl" -#: preproc.y:2015 +#: preproc.y:2029 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "AT-Option ist nicht erlaubt im WHENEVER-Befehl" -#: preproc.y:2267 preproc.y:2272 preproc.y:2388 preproc.y:3925 preproc.y:5484 -#: preproc.y:5493 preproc.y:5793 preproc.y:7233 preproc.y:8613 preproc.y:8618 -#: preproc.y:11229 preproc.y:11850 +#: preproc.y:2106 preproc.y:2278 preproc.y:2283 preproc.y:2399 preproc.y:4044 +#: preproc.y:5602 preproc.y:5611 preproc.y:5911 preproc.y:7510 preproc.y:9003 +#: preproc.y:9008 preproc.y:11790 #, c-format msgid "unsupported feature will be passed to server" msgstr "nicht mehr unterstütztes Feature wird an Server weitergereicht werden" -#: preproc.y:2646 +#: preproc.y:2657 #, c-format msgid "SHOW ALL is not implemented" msgstr "SHOW ALL ist nicht implementiert" -#: preproc.y:3270 +#: preproc.y:3385 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "COPY FROM STDIN ist nicht implementiert" -#: preproc.y:9488 preproc.y:14672 +#: preproc.y:9956 preproc.y:15311 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "Verwendung der Variable »%s« in verschiedenen DECLARE-Anweisungen wird nicht unterstützt" -#: preproc.y:9490 preproc.y:14674 +#: preproc.y:9958 preproc.y:15313 #, c-format msgid "cursor \"%s\" is already defined" msgstr "Cursor »%s« ist bereits definiert" -#: preproc.y:9920 +#: preproc.y:10388 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "nicht mehr unterstützte Syntax LIMIT x,y wird an Server weitergereicht" -#: preproc.y:10228 preproc.y:10235 +#: preproc.y:10704 preproc.y:10711 #, c-format msgid "subquery in FROM must have an alias" msgstr "Unteranfrage in FROM muss Aliasnamen erhalten" -#: preproc.y:14402 +#: preproc.y:15041 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE AS kann INTO nicht verwenden" -#: preproc.y:14438 +#: preproc.y:15077 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "»@« erwartet, »%s« gefunden" -#: preproc.y:14450 +#: preproc.y:15089 #, c-format msgid "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported" msgstr "er werden nur die Protokolle »tcp« und »unix« und der Datenbanktyp »postgresql« unterstützt" -#: preproc.y:14453 +#: preproc.y:15092 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "»://« erwartet, »%s« gefunden" -#: preproc.y:14458 +#: preproc.y:15097 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" msgstr "Unix-Domain-Sockets funktionieren nur mit »localhost«, aber nicht mit »%s«" -#: preproc.y:14484 +#: preproc.y:15123 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "»postgresql« erwartet, »%s« gefunden" -#: preproc.y:14487 +#: preproc.y:15126 #, c-format msgid "invalid connection type: %s" msgstr "ungültiger Verbindungstyp: %s" -#: preproc.y:14496 +#: preproc.y:15135 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "»@« oder »://« erwartet, »%s« gefunden" -#: preproc.y:14571 preproc.y:14589 +#: preproc.y:15210 preproc.y:15228 #, c-format msgid "invalid data type" msgstr "ungültiger Datentyp" -#: preproc.y:14600 preproc.y:14617 +#: preproc.y:15239 preproc.y:15256 #, c-format msgid "incomplete statement" msgstr "unvollständige Anweisung" -#: preproc.y:14603 preproc.y:14620 +#: preproc.y:15242 preproc.y:15259 #, c-format msgid "unrecognized token \"%s\"" msgstr "nicht erkanntes Token »%s«" -#: preproc.y:14894 +#: preproc.y:15533 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "nur die Datentypen NUMERIC und DECIMAL haben Argumente für Präzision und Skala" -#: preproc.y:14906 +#: preproc.y:15545 #, c-format msgid "interval specification not allowed here" msgstr "Intervallangabe hier nicht erlaubt" -#: preproc.y:15058 preproc.y:15110 +#: preproc.y:15697 preproc.y:15749 #, c-format msgid "too many levels in nested structure/union definition" msgstr "zu viele Ebenen in verschachtelter Definition von Struktur/Union" -#: preproc.y:15249 +#: preproc.y:15888 #, c-format msgid "pointers to varchar are not implemented" msgstr "Zeiger auf varchar sind nicht implementiert" -#: preproc.y:15436 preproc.y:15461 +#: preproc.y:16075 preproc.y:16100 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "nicht unterstützter DESCRIBE-Befehl wird verwendet" -#: preproc.y:15708 +#: preproc.y:16347 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "Initialisierungswert nicht erlaubt in Befehl EXEC SQL VAR" -#: preproc.y:16019 +#: preproc.y:16663 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "Array aus Indikatoren bei der Eingabe nicht erlaubt" -#: preproc.y:16240 +#: preproc.y:16884 #, c-format msgid "operator not allowed in variable definition" msgstr "Operator nicht erlaubt in Variablendefinition" #. translator: %s is typically the translation of "syntax error" -#: preproc.y:16278 +#: preproc.y:16925 #, c-format msgid "%s at or near \"%s\"" msgstr "%s bei »%s«" @@ -543,7 +543,7 @@ msgstr "%s bei »%s«" msgid "out of memory" msgstr "Speicher aufgebraucht" -#: type.c:212 type.c:664 +#: type.c:212 type.c:676 #, c-format msgid "unrecognized variable type code %d" msgstr "unbekannter Variablentypcode %d" @@ -588,7 +588,17 @@ msgstr "Indikator für struct muss ein struct sein" msgid "indicator for simple data type has to be simple" msgstr "Indikator für einfachen Typ muss einfachen Typ haben" -#: type.c:723 +#: type.c:616 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "Indikator-Struct »%s« hat zu wenige Mitglieder" + +#: type.c:624 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "Indikator-Struct »%s« hat zu viele Mitglieder" + +#: type.c:735 #, c-format msgid "unrecognized descriptor item code %d" msgstr "unbekannter Deskriptorelementcode %d" diff --git a/src/interfaces/ecpg/preproc/po/es.po b/src/interfaces/ecpg/preproc/po/es.po index b0f7dcfa7f2..de6f35f71d7 100644 --- a/src/interfaces/ecpg/preproc/po/es.po +++ b/src/interfaces/ecpg/preproc/po/es.po @@ -1,26 +1,27 @@ # Spanish translation file for ecpg # -# Copyright (C) 2009-2012 PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Emanuel Calvo Franco , 2009. # Alvaro Herrera , 2009-2012 # Franco Catena, , 2009 +# Carlos Chapi , 2018 # msgid "" msgstr "" -"Project-Id-Version: ecpg (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:38+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Project-Id-Version: ecpg (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:20-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" #: descriptor.c:64 #, c-format @@ -57,7 +58,7 @@ msgstr "elemento del descriptor «%s» no está implementado" msgid "descriptor item \"%s\" cannot be set" msgstr "no se puede establecer el elemento del descriptor «%s»" -#: ecpg.c:35 +#: ecpg.c:36 #, c-format msgid "" "%s is the PostgreSQL embedded SQL preprocessor for C programs.\n" @@ -66,7 +67,7 @@ msgstr "" "%s es el preprocesador de SQL incrustado para programas en C de PostgreSQL.\n" "\n" -#: ecpg.c:37 +#: ecpg.c:38 #, c-format msgid "" "Usage:\n" @@ -77,12 +78,12 @@ msgstr "" " %s [OPCIÓN]... ARCHIVO...\n" "\n" -#: ecpg.c:40 +#: ecpg.c:41 #, c-format msgid "Options:\n" msgstr "Opciones:\n" -#: ecpg.c:41 +#: ecpg.c:42 #, c-format msgid "" " -c automatically generate C code from embedded SQL code;\n" @@ -91,46 +92,46 @@ msgstr "" " -c genera automáticamente código en C desde código SQL\n" " incrustado; esto afecta EXEC SQL TYPE\n" -#: ecpg.c:43 +#: ecpg.c:44 #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" " -C MODO establece el modo de compatibilidad;\n" -" MODO puede ser \"INFORMIX\", \"INFORMIX_SE\"\n" +" MODO puede ser \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" -#: ecpg.c:46 +#: ecpg.c:47 #, c-format msgid " -d generate parser debug output\n" msgstr " -d genera salida depurada del analizador\n" -#: ecpg.c:48 +#: ecpg.c:49 #, c-format msgid " -D SYMBOL define SYMBOL\n" msgstr " -D SYMBOL define SYMBOL\n" -#: ecpg.c:49 +#: ecpg.c:50 #, c-format msgid " -h parse a header file, this option includes option \"-c\"\n" msgstr " -h analiza un archivo de cabecera; esto incluye «-c»\n" -#: ecpg.c:50 +#: ecpg.c:51 #, c-format msgid " -i parse system include files as well\n" msgstr " -i analiza además los archivos de inclusión de sistema\n" -#: ecpg.c:51 +#: ecpg.c:52 #, c-format msgid " -I DIRECTORY search DIRECTORY for include files\n" msgstr " -I DIRECTORIO busca los archivos de inclusión en DIRECTORIO\n" -#: ecpg.c:52 +#: ecpg.c:53 #, c-format msgid " -o OUTFILE write result to OUTFILE\n" msgstr " -o ARCHIVO escribe la salida en ARCHIVO\n" -#: ecpg.c:53 +#: ecpg.c:54 #, c-format msgid "" " -r OPTION specify run-time behavior; OPTION can be:\n" @@ -140,27 +141,27 @@ msgstr "" " OPCIÓN puede ser: «no_indicator», «prepare»,\n" " «questionmarks»\n" -#: ecpg.c:55 +#: ecpg.c:56 #, c-format msgid " --regression run in regression testing mode\n" msgstr " --regression ejecuta en modo de prueba de regresión\n" -#: ecpg.c:56 +#: ecpg.c:57 #, c-format msgid " -t turn on autocommit of transactions\n" msgstr " -t activa el compromiso (commit) automático de transacciones\n" -#: ecpg.c:57 +#: ecpg.c:58 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version muestra información de la versión, luego sale\n" -#: ecpg.c:58 +#: ecpg.c:59 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help muestra esta ayuda, luego sale\n" -#: ecpg.c:59 +#: ecpg.c:60 #, c-format msgid "" "\n" @@ -171,161 +172,166 @@ msgstr "" "Si no se especifica un archivo de salida, el nombre se forma agregando .c al\n" "archivo de entrada, luego de quitar .pgc si está presente.\n" -#: ecpg.c:61 +#: ecpg.c:62 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Reporte errores a .\n" +"Reporte errores a .\n" -#: ecpg.c:139 +#: ecpg.c:182 #, c-format msgid "%s: could not locate my own executable path\n" msgstr "%s: no se pudo localizar la ruta de mi propio ejecutable\n" -#: ecpg.c:174 ecpg.c:327 ecpg.c:337 +#: ecpg.c:217 ecpg.c:374 ecpg.c:385 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: no se pudo abrir el archivo «%s»: %s\n" -#: ecpg.c:213 ecpg.c:226 ecpg.c:242 ecpg.c:268 +#: ecpg.c:260 ecpg.c:273 ecpg.c:289 ecpg.c:315 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Utilice «%s --help» para obtener mayor información.\n" -#: ecpg.c:237 +#: ecpg.c:284 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: la depuración del analizador (parser, -d) no está disponible)\n" -#: ecpg.c:256 +#: ecpg.c:303 #, c-format msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" msgstr "%s, el preprocesador de C incrustado de PostgreSQL, versión %s\n" -#: ecpg.c:258 +#: ecpg.c:305 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... la búsqueda comienza aquí:\n" -#: ecpg.c:261 +#: ecpg.c:308 #, c-format msgid "end of search list\n" msgstr "fin de la lista de búsqueda\n" -#: ecpg.c:267 +#: ecpg.c:314 #, c-format msgid "%s: no input files specified\n" msgstr "%s: no se especificaron archivos de entrada\n" -#: ecpg.c:460 +#: ecpg.c:497 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "el cursor «%s» fue declarado pero no abierto" -#: ecpg.c:473 preproc.y:127 +#: ecpg.c:510 preproc.y:129 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "no se pudo eliminar el archivo de salida «%s»\n" -#: pgc.l:431 +#: pgc.l:472 #, c-format msgid "unterminated /* comment" msgstr "comentario /* no cerrado" -#: pgc.l:444 +#: pgc.l:490 #, c-format msgid "invalid bit string literal" msgstr "cadena de bits no válida" -#: pgc.l:453 +#: pgc.l:502 #, c-format msgid "unterminated bit string literal" msgstr "una cadena de bits está inconclusa" -#: pgc.l:469 +#: pgc.l:518 #, c-format msgid "unterminated hexadecimal string literal" msgstr "una cadena hexadecimal está inconclusa" -#: pgc.l:547 +#: pgc.l:614 pgc.l:718 #, c-format msgid "unterminated quoted string" msgstr "una cadena en comillas está inconclusa" -#: pgc.l:605 pgc.l:618 +#: pgc.l:665 +#, c-format +msgid "unterminated dollar-quoted string" +msgstr "una cadena separada por $ está inconclusa" + +#: pgc.l:684 pgc.l:697 #, c-format msgid "zero-length delimited identifier" msgstr "identificador delimitado de longitud cero" -#: pgc.l:626 +#: pgc.l:709 #, c-format msgid "unterminated quoted identifier" msgstr "un identificador en comillas está inconcluso" -#: pgc.l:881 +#: pgc.l:1040 #, c-format msgid "nested /* ... */ comments" msgstr "comentarios /* ... */ anidados" -#: pgc.l:974 +#: pgc.l:1133 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "falta un identificador en la orden EXEC SQL UNDEF" -#: pgc.l:1020 pgc.l:1034 +#: pgc.l:1179 pgc.l:1193 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "falta el «EXEC SQL IFDEF» / «EXEC SQL IFNDEF»" -#: pgc.l:1023 pgc.l:1036 pgc.l:1212 +#: pgc.l:1182 pgc.l:1195 pgc.l:1373 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "falta el «EXEC SQL ENDIF;»" -#: pgc.l:1052 pgc.l:1071 +#: pgc.l:1211 pgc.l:1230 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "hay más de un EXEC SQL ELSE" -#: pgc.l:1093 pgc.l:1107 +#: pgc.l:1252 pgc.l:1266 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "EXEC SQL ENDIF sin coincidencia" -#: pgc.l:1127 +#: pgc.l:1286 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "demasiadas condiciones EXEC SQL IFDEF anidadas" -#: pgc.l:1160 +#: pgc.l:1321 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "identificador faltante en la orden EXEC SQL IFDEF" -#: pgc.l:1169 +#: pgc.l:1330 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "identificador faltante en la orden EXEC SQL DEFINE" -#: pgc.l:1202 +#: pgc.l:1363 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "error de sintaxis en orden EXEC SQL INCLUDE" -#: pgc.l:1251 +#: pgc.l:1413 #, c-format -msgid "internal error: unreachable state; please report this to " -msgstr "Error Interno: estado no esperado; por favor reporte a " +msgid "internal error: unreachable state; please report this to " +msgstr "error interno: estado no esperado; por favor reporte a " -#: pgc.l:1375 +#: pgc.l:1564 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "Error: ruta de inclusión «%s/%s» es demasiada larga en la línea %d, omitiendo\n" -#: pgc.l:1398 +#: pgc.l:1587 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "no se pudo abrir el archivo a incluir «%s» en la línea %d" @@ -334,210 +340,215 @@ msgstr "no se pudo abrir el archivo a incluir «%s» en la línea %d" msgid "syntax error" msgstr "error de sintaxis" -#: preproc.y:81 +#: preproc.y:83 #, c-format msgid "WARNING: " msgstr "ATENCIÓN: " -#: preproc.y:84 +#: preproc.y:86 #, c-format msgid "ERROR: " msgstr "ERROR: " -#: preproc.y:508 +#: preproc.y:510 #, c-format msgid "cursor \"%s\" does not exist" msgstr "no existe el cursor «%s»" -#: preproc.y:537 +#: preproc.y:539 #, c-format msgid "initializer not allowed in type definition" msgstr "inicializador no permitido en definición de tipo" -#: preproc.y:539 +#: preproc.y:541 #, c-format msgid "type name \"string\" is reserved in Informix mode" msgstr "el nombre de tipo «string» está reservado en modo Informix" -#: preproc.y:546 preproc.y:15408 +#: preproc.y:548 preproc.y:15877 #, c-format msgid "type \"%s\" is already defined" msgstr "el tipo «%s» ya está definido" -#: preproc.y:570 preproc.y:16066 preproc.y:16386 variable.c:620 +#: preproc.y:573 preproc.y:16548 preproc.y:16873 variable.c:621 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "los arrays multidimensionales para tipos de datos simples no están soportados" -#: preproc.y:1681 -#, c-format -msgid "AT option not allowed in CLOSE DATABASE statement" -msgstr "la opción AT no está permitida en la sentencia CLOSE DATABASE" - -#: preproc.y:1894 +#: preproc.y:1938 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "la opción AT no está permitida en la sentencia CONNECT" -#: preproc.y:1928 +#: preproc.y:1976 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "la opción AT no está permitida en la sentencia DISCONNECT" -#: preproc.y:1983 +#: preproc.y:2038 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "la opción AT no está permitida en la sentencia SET CONNECTION" -#: preproc.y:2005 +#: preproc.y:2060 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "la opción AT no está permitida en la sentencia TYPE" -#: preproc.y:2014 +#: preproc.y:2069 #, c-format msgid "AT option not allowed in VAR statement" msgstr "la opción AT no está permitida en la sentencia VAR" -#: preproc.y:2021 +#: preproc.y:2076 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "la opción AT no está permitida en la sentencia WHENEVER" -#: preproc.y:2090 preproc.y:2274 preproc.y:2279 preproc.y:2395 preproc.y:3969 -#: preproc.y:5511 preproc.y:5520 preproc.y:5820 preproc.y:7356 preproc.y:8797 -#: preproc.y:8802 preproc.y:11534 preproc.y:12155 +#: preproc.y:2153 preproc.y:2325 preproc.y:2330 preproc.y:2453 preproc.y:4046 +#: preproc.y:5635 preproc.y:5935 preproc.y:7563 preproc.y:9075 preproc.y:9080 +#: preproc.y:11880 #, c-format msgid "unsupported feature will be passed to server" msgstr "característica no soportada será pasada al servidor" -#: preproc.y:2653 +#: preproc.y:2711 #, c-format msgid "SHOW ALL is not implemented" msgstr "SHOW ALL no está implementado" -#: preproc.y:3325 +#: preproc.y:3369 +#, c-format +msgid "AT option not allowed in CLOSE DATABASE statement" +msgstr "la opción AT no está permitida en la sentencia CLOSE DATABASE" + +#: preproc.y:3394 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "COPY FROM STDIN no está implementado" -#: preproc.y:9700 preproc.y:14997 +#: preproc.y:10026 preproc.y:15460 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "el uso de la variable «%s» en diferentes sentencias declare no está soportado" -#: preproc.y:9702 preproc.y:14999 +#: preproc.y:10028 preproc.y:15462 #, c-format msgid "cursor \"%s\" is already defined" msgstr "el cursor «%s» ya está definido" -#: preproc.y:10132 +#: preproc.y:10469 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "la sintaxis LIMIT #,# que ya no está soportada ha sido pasada al servidor" -#: preproc.y:10448 preproc.y:10455 +#: preproc.y:10794 preproc.y:10801 #, c-format msgid "subquery in FROM must have an alias" msgstr "las subconsultas en FROM deben tener un alias" -#: preproc.y:14727 +#: preproc.y:15151 preproc.y:15158 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE AS no puede especificar INTO" -#: preproc.y:14763 +#: preproc.y:15194 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "se esperaba «@», se encontró «%s»" -#: preproc.y:14775 +#: preproc.y:15206 #, c-format msgid "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported" msgstr "sólo los protocolos «tcp» y «unix» y tipo de bases de datos «postgresql» están soportados" -#: preproc.y:14778 +#: preproc.y:15209 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "se esperaba «://», se encontró «%s»" -#: preproc.y:14783 +#: preproc.y:15214 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" msgstr "los sockets de dominio unix sólo trabajan en «localhost» pero no en «%s»" -#: preproc.y:14809 +#: preproc.y:15240 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "se esperaba «postgresql», se encontró «%s»" -#: preproc.y:14812 +#: preproc.y:15243 #, c-format msgid "invalid connection type: %s" msgstr "tipo de conexión no válido: %s" -#: preproc.y:14821 +#: preproc.y:15252 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "se esperaba «@» o «://», se encontró «%s»" -#: preproc.y:14896 preproc.y:14914 +#: preproc.y:15327 preproc.y:15345 #, c-format msgid "invalid data type" msgstr "tipo de dato no válido" -#: preproc.y:14925 preproc.y:14942 +#: preproc.y:15356 preproc.y:15373 #, c-format msgid "incomplete statement" msgstr "sentencia incompleta" -#: preproc.y:14928 preproc.y:14945 +#: preproc.y:15359 preproc.y:15376 #, c-format msgid "unrecognized token \"%s\"" msgstr "elemento «%s» no reconocido" -#: preproc.y:15219 +#: preproc.y:15422 +#, c-format +msgid "declared name %s is already defined" +msgstr "el cursor «%s» ya está definido" + +#: preproc.y:15680 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "sólo los tipos de dato numeric y decimal tienen argumento de precisión/escala" -#: preproc.y:15231 +#: preproc.y:15692 #, c-format msgid "interval specification not allowed here" msgstr "la especificación de intervalo no está permitida aquí" -#: preproc.y:15383 preproc.y:15435 +#: preproc.y:15852 preproc.y:15904 #, c-format msgid "too many levels in nested structure/union definition" msgstr "demasiados niveles en la definición anidada de estructura/unión" -#: preproc.y:15574 +#: preproc.y:16055 #, c-format msgid "pointers to varchar are not implemented" msgstr "los punteros a varchar no están implementados" -#: preproc.y:15761 preproc.y:15786 +#: preproc.y:16242 preproc.y:16267 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "utilizando sentencia DESCRIBE no soportada" -#: preproc.y:16033 +#: preproc.y:16514 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "inicializador no permitido en la orden EXEC SQL VAR" -#: preproc.y:16344 +#: preproc.y:16831 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "no se permiten los arrays de indicadores en la entrada" -#: preproc.y:16565 +#: preproc.y:17052 #, c-format msgid "operator not allowed in variable definition" msgstr "operador no permitido en definición de variable" #. translator: %s is typically the translation of "syntax error" -#: preproc.y:16603 +#: preproc.y:17093 #, c-format msgid "%s at or near \"%s\"" msgstr "%s en o cerca de «%s»" @@ -547,52 +558,62 @@ msgstr "%s en o cerca de «%s»" msgid "out of memory" msgstr "memoria agotada" -#: type.c:212 type.c:664 +#: type.c:214 type.c:685 #, c-format msgid "unrecognized variable type code %d" msgstr "código de tipo de variable %d no reconocido" -#: type.c:261 +#: type.c:263 #, c-format msgid "variable \"%s\" is hidden by a local variable of a different type" msgstr "la variable «%s» está escondida por una variable local de tipo diferente" -#: type.c:263 +#: type.c:265 #, c-format msgid "variable \"%s\" is hidden by a local variable" msgstr "la variable «%s» está escondida por una variable local" -#: type.c:275 +#: type.c:277 #, c-format msgid "indicator variable \"%s\" is hidden by a local variable of a different type" msgstr "la variable de indicador «%s» está escondida por una variable local de tipo diferente" -#: type.c:277 +#: type.c:279 #, c-format msgid "indicator variable \"%s\" is hidden by a local variable" msgstr "variable de indicador «%s» está escondida por una variable local" -#: type.c:285 +#: type.c:287 #, c-format msgid "indicator for array/pointer has to be array/pointer" msgstr "indicador para array/puntero debe ser array/puntero" -#: type.c:289 +#: type.c:291 #, c-format msgid "nested arrays are not supported (except strings)" msgstr "no se permiten arrays anidados (excepto cadenas de caracteres)" -#: type.c:331 +#: type.c:333 #, c-format msgid "indicator for struct has to be a struct" msgstr "el indicador para struct debe ser struct" -#: type.c:351 type.c:372 type.c:392 +#: type.c:353 type.c:374 type.c:394 #, c-format msgid "indicator for simple data type has to be simple" msgstr "el indicador para tipo dato simple debe ser simple" -#: type.c:723 +#: type.c:625 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "struct para indicador «%s» no tiene suficientes miembros" + +#: type.c:633 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "struct para indicador «%s» tiene demasiados miembros" + +#: type.c:744 #, c-format msgid "unrecognized descriptor item code %d" msgstr "código de descriptor de elemento %d no reconocido" @@ -658,6 +679,3 @@ msgstr "los punteros a puntero no están soportados para este tipo de dato" #, c-format msgid "multidimensional arrays for structures are not supported" msgstr "los arrays multidimensionales para estructuras no están soportados" - -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version muestra información de la versión, luego sale\n" diff --git a/src/interfaces/ecpg/preproc/po/fr.po b/src/interfaces/ecpg/preproc/po/fr.po index d408bd36a93..b6dbad2e031 100644 --- a/src/interfaces/ecpg/preproc/po/fr.po +++ b/src/interfaces/ecpg/preproc/po/fr.po @@ -8,9 +8,9 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-02 04:38+0000\n" -"PO-Revision-Date: 2017-07-02 17:45+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:08+0000\n" +"PO-Revision-Date: 2019-05-17 14:44+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" #: descriptor.c:64 #, c-format @@ -55,7 +55,7 @@ msgstr "l'élément du descripteur « %s » n'est pas implanté" msgid "descriptor item \"%s\" cannot be set" msgstr "l'élément du descripteur « %s » ne peut pas être initialisé" -#: ecpg.c:35 +#: ecpg.c:36 #, c-format msgid "" "%s is the PostgreSQL embedded SQL preprocessor for C programs.\n" @@ -64,7 +64,7 @@ msgstr "" "%s est le préprocesseur SQL embarqué de PostgreSQL pour les programmes C.\n" "\n" -#: ecpg.c:37 +#: ecpg.c:38 #, c-format msgid "" "Usage:\n" @@ -75,89 +75,94 @@ msgstr "" " %s [OPTION]... FICHIER...\n" "\n" -#: ecpg.c:40 +#: ecpg.c:41 #, c-format msgid "Options:\n" msgstr "Options:\n" -#: ecpg.c:41 +#: ecpg.c:42 #, c-format msgid "" " -c automatically generate C code from embedded SQL code;\n" " this affects EXEC SQL TYPE\n" msgstr "" -" -c produit automatiquement le code C à partir du code SQL embarqué ;\n" +" -c produit automatiquement le code C à partir du code SQL " +"embarqué ;\n" " ceci affecte EXEC SQL TYPE\n" -#: ecpg.c:43 +#: ecpg.c:44 #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" " -C MODE configure le mode de compatibilité ; MODE peut être\n" -" « INFORMIX » ou « INFORMIX_SE »\n" +" « INFORMIX », « INFORMIX_SE » ou « ORACLE »\n" -#: ecpg.c:46 +#: ecpg.c:47 #, c-format msgid " -d generate parser debug output\n" msgstr " -d produit la sortie de débogage de l'analyseur\n" -#: ecpg.c:48 +#: ecpg.c:49 #, c-format msgid " -D SYMBOL define SYMBOL\n" msgstr " -D SYMBOLE définit SYMBOLE\n" -#: ecpg.c:49 +#: ecpg.c:50 #, c-format -msgid " -h parse a header file, this option includes option \"-c\"\n" -msgstr " -h analyse un fichier d'en-tête, cette option inclut l'option « -c »\n" +msgid "" +" -h parse a header file, this option includes option \"-c\"\n" +msgstr "" +" -h analyse un fichier d'en-tête, cette option inclut l'option " +"« -c »\n" -#: ecpg.c:50 +#: ecpg.c:51 #, c-format msgid " -i parse system include files as well\n" msgstr " -i analyse en plus les fichiers d'en-tête systèmes\n" -#: ecpg.c:51 +#: ecpg.c:52 #, c-format msgid " -I DIRECTORY search DIRECTORY for include files\n" msgstr " -I RÉPERTOIRE recherche les fichiers d'en-têtes dans RÉPERTOIRE\n" -#: ecpg.c:52 +#: ecpg.c:53 #, c-format msgid " -o OUTFILE write result to OUTFILE\n" msgstr " -o FICHIER écrit le résultat dans FICHIER\n" -#: ecpg.c:53 +#: ecpg.c:54 #, c-format msgid "" " -r OPTION specify run-time behavior; OPTION can be:\n" " \"no_indicator\", \"prepare\", \"questionmarks\"\n" msgstr "" -" -r OPTION indique le comportement à l'exécution ; OPTION peut valoir :\n" +" -r OPTION indique le comportement à l'exécution ; OPTION peut " +"valoir :\n" " « no_indicator », « prepare », « questionmarks »\n" -#: ecpg.c:55 +#: ecpg.c:56 #, c-format msgid " --regression run in regression testing mode\n" msgstr " --regression s'exécute en mode de tests des régressions\n" -#: ecpg.c:56 +#: ecpg.c:57 #, c-format msgid " -t turn on autocommit of transactions\n" msgstr " -t active la validation automatique des transactions\n" -#: ecpg.c:57 +#: ecpg.c:58 #, c-format msgid " -V, --version output version information, then exit\n" msgstr " -V, --version affiche la version et quitte\n" -#: ecpg.c:58 +#: ecpg.c:59 #, c-format msgid " -?, --help show this help, then exit\n" msgstr " -?, --help affiche cette aide et quitte\n" -#: ecpg.c:59 +#: ecpg.c:60 #, c-format msgid "" "\n" @@ -169,165 +174,172 @@ msgstr "" "ajoutant le suffixe .c au nom du fichier en entrée après avoir supprimé le\n" "suffixe .pgc s'il est présent\n" -#: ecpg.c:61 +#: ecpg.c:62 #, c-format msgid "" "\n" -"Report bugs to .\n" +"Report bugs to .\n" msgstr "" "\n" -"Rapporter les bogues à .\n" +"Rapporter les bogues à .\n" -#: ecpg.c:139 +#: ecpg.c:182 #, c-format msgid "%s: could not locate my own executable path\n" msgstr "%s : n'a pas pu localiser mon propre exécutable\n" -#: ecpg.c:174 ecpg.c:327 ecpg.c:337 +#: ecpg.c:217 ecpg.c:374 ecpg.c:385 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n" -#: ecpg.c:213 ecpg.c:226 ecpg.c:242 ecpg.c:268 +#: ecpg.c:260 ecpg.c:273 ecpg.c:289 ecpg.c:315 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Essayer « %s --help » pour plus d'informations.\n" -#: ecpg.c:237 +#: ecpg.c:284 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s : support de débogage de l'analyseur (-d) non disponible\n" -#: ecpg.c:256 +#: ecpg.c:303 #, c-format msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" msgstr "%s, le préprocesseur C embarqué de PostgreSQL, version %s\n" -#: ecpg.c:258 +#: ecpg.c:305 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "la recherche EXEC SQL INCLUDE ... commence ici :\n" -#: ecpg.c:261 +#: ecpg.c:308 #, c-format msgid "end of search list\n" msgstr "fin de la liste de recherche\n" -#: ecpg.c:267 +#: ecpg.c:314 #, c-format msgid "%s: no input files specified\n" msgstr "%s : aucun fichier précisé en entrée\n" -#: ecpg.c:460 +#: ecpg.c:497 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "le curseur « %s » est déclaré mais non ouvert" -#: ecpg.c:473 preproc.y:127 +#: ecpg.c:510 preproc.y:129 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "n'a pas pu supprimer le fichier « %s » en sortie\n" -#: pgc.l:431 +#: pgc.l:472 #, c-format msgid "unterminated /* comment" msgstr "commentaire /* non terminé" -#: pgc.l:444 +#: pgc.l:490 #, c-format msgid "invalid bit string literal" msgstr "chaîne bit litéral invalide" -#: pgc.l:453 +#: pgc.l:502 #, c-format msgid "unterminated bit string literal" msgstr "chaîne bit litéral non terminée" -#: pgc.l:469 +#: pgc.l:518 #, c-format msgid "unterminated hexadecimal string literal" msgstr "chaîne hexadécimale litéralle non terminée" -#: pgc.l:547 +#: pgc.l:614 pgc.l:718 #, c-format msgid "unterminated quoted string" msgstr "chaîne entre guillemets non terminée" -#: pgc.l:605 pgc.l:618 +#: pgc.l:665 +#, c-format +msgid "unterminated dollar-quoted string" +msgstr "chaîne entre guillemets dollars non terminée" + +#: pgc.l:684 pgc.l:697 #, c-format msgid "zero-length delimited identifier" msgstr "identifiant délimité de taille zéro" -#: pgc.l:626 +#: pgc.l:709 #, c-format msgid "unterminated quoted identifier" msgstr "identifiant entre guillemet non terminé" -#: pgc.l:881 +#: pgc.l:1040 #, c-format msgid "nested /* ... */ comments" msgstr "commentaires /* ... */ imbriqués" -#: pgc.l:974 +#: pgc.l:1133 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "identifiant manquant dans la commande EXEC SQL UNDEF" -#: pgc.l:1020 pgc.l:1034 +#: pgc.l:1179 pgc.l:1193 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "correspondance manquante « EXEC SQL IFDEF » / « EXEC SQL IFNDEF »" -#: pgc.l:1023 pgc.l:1036 pgc.l:1212 +#: pgc.l:1182 pgc.l:1195 pgc.l:1371 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "« EXEC SQL ENDIF; » manquant" -#: pgc.l:1052 pgc.l:1071 +#: pgc.l:1211 pgc.l:1230 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "plusieurs EXEC SQL ELSE" -#: pgc.l:1093 pgc.l:1107 +#: pgc.l:1252 pgc.l:1266 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "EXEC SQL ENDIF différent" -#: pgc.l:1127 +#: pgc.l:1286 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "trop de conditions EXEC SQL IFDEF imbriquées" -#: pgc.l:1160 +#: pgc.l:1319 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "identifiant manquant dans la commande EXEC SQL IFDEF" -#: pgc.l:1169 +#: pgc.l:1328 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "identifiant manquant dans la commande EXEC SQL DEFINE" -#: pgc.l:1202 +#: pgc.l:1361 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "erreur de syntaxe dans la commande EXEC SQL INCLUDE" -#: pgc.l:1251 +#: pgc.l:1411 #, c-format -msgid "internal error: unreachable state; please report this to " +msgid "" +"internal error: unreachable state; please report this to " msgstr "" "erreur interne : l'état ne peut être atteint ; merci de rapporter ceci à\n" -"" +"" -#: pgc.l:1375 +#: pgc.l:1562 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "" "Erreur : le chemin d'en-tête « %s/%s » est trop long sur la ligne %d,\n" "ignoré\n" -#: pgc.l:1398 +#: pgc.l:1585 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "n'a pas pu ouvrir le fichier d'en-tête « %s » sur la ligne %d" @@ -336,218 +348,229 @@ msgstr "n'a pas pu ouvrir le fichier d'en-tête « %s » sur la ligne %d" msgid "syntax error" msgstr "erreur de syntaxe" -#: preproc.y:81 +#: preproc.y:83 #, c-format msgid "WARNING: " msgstr "ATTENTION : " -#: preproc.y:84 +#: preproc.y:86 #, c-format msgid "ERROR: " msgstr "ERREUR : " -#: preproc.y:508 +#: preproc.y:510 #, c-format msgid "cursor \"%s\" does not exist" msgstr "le curseur « %s » n'existe pas" -#: preproc.y:537 +#: preproc.y:539 #, c-format msgid "initializer not allowed in type definition" msgstr "initialiseur non autorisé dans la définition du type" -#: preproc.y:539 +#: preproc.y:541 #, c-format msgid "type name \"string\" is reserved in Informix mode" msgstr "le nom du type « string » est réservé dans le mode Informix" -#: preproc.y:546 preproc.y:15412 +#: preproc.y:548 preproc.y:15828 #, c-format msgid "type \"%s\" is already defined" msgstr "le type « %s » est déjà défini" -#: preproc.y:570 preproc.y:16070 preproc.y:16390 variable.c:620 +#: preproc.y:573 preproc.y:16499 preproc.y:16824 variable.c:621 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "" "les tableaux multi-dimensionnels pour les types de données simples ne sont\n" "pas supportés" -#: preproc.y:1681 -#, c-format -msgid "AT option not allowed in CLOSE DATABASE statement" -msgstr "option AT non autorisée dans une instruction CLOSE DATABASE" - -#: preproc.y:1894 +#: preproc.y:1896 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "option AT non autorisée dans une instruction CONNECT" -#: preproc.y:1928 +#: preproc.y:1934 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "option AT non autorisée dans une instruction DISCONNECT" -#: preproc.y:1983 +#: preproc.y:1996 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "option AT non autorisée dans une instruction SET CONNECTION" -#: preproc.y:2005 +#: preproc.y:2018 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "option AT non autorisée dans une instruction TYPE" -#: preproc.y:2014 +#: preproc.y:2027 #, c-format msgid "AT option not allowed in VAR statement" msgstr "option AT non autorisée dans une instruction VAR" -#: preproc.y:2021 +#: preproc.y:2034 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "option AT non autorisée dans une instruction WHENEVER" -#: preproc.y:2090 preproc.y:2274 preproc.y:2279 preproc.y:2395 preproc.y:3969 preproc.y:5519 -#: preproc.y:5528 preproc.y:5828 preproc.y:7364 preproc.y:8801 preproc.y:8806 preproc.y:11538 -#: preproc.y:12159 +#: preproc.y:2111 preproc.y:2283 preproc.y:2288 preproc.y:2411 preproc.y:4004 +#: preproc.y:5593 preproc.y:5893 preproc.y:7521 preproc.y:9033 preproc.y:9038 +#: preproc.y:11831 #, c-format msgid "unsupported feature will be passed to server" msgstr "la fonctionnalité non supportée sera passée au serveur" -#: preproc.y:2653 +#: preproc.y:2669 #, c-format msgid "SHOW ALL is not implemented" msgstr "SHOW ALL n'est pas implanté" -#: preproc.y:3325 +#: preproc.y:3327 +#, c-format +msgid "AT option not allowed in CLOSE DATABASE statement" +msgstr "option AT non autorisée dans une instruction CLOSE DATABASE" + +#: preproc.y:3352 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "COPY FROM STDIN n'est pas implanté" -#: preproc.y:9704 preproc.y:15001 +#: preproc.y:9977 preproc.y:15411 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "" -"l'utilisation de la variable « %s » dans différentes instructions de déclaration\n" +"l'utilisation de la variable « %s » dans différentes instructions de " +"déclaration\n" "n'est pas supportée" -#: preproc.y:9706 preproc.y:15003 +#: preproc.y:9979 preproc.y:15413 #, c-format msgid "cursor \"%s\" is already defined" msgstr "le curseur « %s » est déjà défini" -#: preproc.y:10136 +#: preproc.y:10420 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "la syntaxe obsolète LIMIT #,# a été passée au serveur" -#: preproc.y:10452 preproc.y:10459 +#: preproc.y:10745 preproc.y:10752 #, c-format msgid "subquery in FROM must have an alias" msgstr "la sous-requête du FROM doit avoir un alias" -#: preproc.y:14731 +#: preproc.y:15102 preproc.y:15109 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE AS ne peut pas indiquer INTO" -#: preproc.y:14767 +#: preproc.y:15145 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "« @ » attendu, « %s » trouvé" -#: preproc.y:14779 +#: preproc.y:15157 #, c-format -msgid "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported" +msgid "" +"only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are " +"supported" msgstr "" "seuls les protocoles « tcp » et « unix » et les types de base de données\n" "« postgresql » sont supportés" -#: preproc.y:14782 +#: preproc.y:15160 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "« :// » attendu, « %s » trouvé" -#: preproc.y:14787 +#: preproc.y:15165 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" -msgstr "les sockets de domaine Unix fonctionnent seulement sur « localhost », mais pas sur « %s »" +msgstr "" +"les sockets de domaine Unix fonctionnent seulement sur « localhost », mais " +"pas sur « %s »" -#: preproc.y:14813 +#: preproc.y:15191 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "« postgresql » attendu, « %s » trouvé" -#: preproc.y:14816 +#: preproc.y:15194 #, c-format msgid "invalid connection type: %s" msgstr "type de connexion invalide : %s" -#: preproc.y:14825 +#: preproc.y:15203 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "« @ » ou « :// » attendu, « %s » trouvé" -#: preproc.y:14900 preproc.y:14918 +#: preproc.y:15278 preproc.y:15296 #, c-format msgid "invalid data type" msgstr "type de données invalide" -#: preproc.y:14929 preproc.y:14946 +#: preproc.y:15307 preproc.y:15324 #, c-format msgid "incomplete statement" msgstr "instruction incomplète" -#: preproc.y:14932 preproc.y:14949 +#: preproc.y:15310 preproc.y:15327 #, c-format msgid "unrecognized token \"%s\"" msgstr "jeton « %s » non reconnu" -#: preproc.y:15223 +#: preproc.y:15373 +#, c-format +msgid "declared name %s is already defined" +msgstr "le nom déclaré %s est déjà défini" + +#: preproc.y:15631 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "" "seuls les types de données numeric et decimal ont des arguments de\n" "précision et d'échelle" -#: preproc.y:15235 +#: preproc.y:15643 #, c-format msgid "interval specification not allowed here" msgstr "interval de spécification non autorisé ici" -#: preproc.y:15387 preproc.y:15439 +#: preproc.y:15803 preproc.y:15855 #, c-format msgid "too many levels in nested structure/union definition" msgstr "trop de niveaux dans la définition de structure/union imbriquée" -#: preproc.y:15578 +#: preproc.y:16006 #, c-format msgid "pointers to varchar are not implemented" -msgstr "les pointeurs sur des chaînes de caractères (varchar) ne sont pas implantés" +msgstr "" +"les pointeurs sur des chaînes de caractères (varchar) ne sont pas implantés" -#: preproc.y:15765 preproc.y:15790 +#: preproc.y:16193 preproc.y:16218 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "utilisation de l'instruction DESCRIBE non supporté" -#: preproc.y:16037 +#: preproc.y:16465 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "initialiseur non autorisé dans la commande EXEC SQL VAR" -#: preproc.y:16348 +#: preproc.y:16782 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "les tableaux d'indicateurs ne sont pas autorisés en entrée" -#: preproc.y:16569 +#: preproc.y:17003 #, c-format msgid "operator not allowed in variable definition" msgstr "opérateur non autorisé dans la définition de la variable" #. translator: %s is typically the translation of "syntax error" -#: preproc.y:16607 +#: preproc.y:17044 #, c-format msgid "%s at or near \"%s\"" msgstr "%s sur ou près de « %s »" @@ -557,56 +580,68 @@ msgstr "%s sur ou près de « %s »" msgid "out of memory" msgstr "mémoire épuisée" -#: type.c:212 type.c:664 +#: type.c:214 type.c:685 #, c-format msgid "unrecognized variable type code %d" msgstr "code %d du type de variable non reconnu" -#: type.c:261 +#: type.c:263 #, c-format msgid "variable \"%s\" is hidden by a local variable of a different type" -msgstr "la variable « %s » est cachée par une variable locale d'un type différent" +msgstr "" +"la variable « %s » est cachée par une variable locale d'un type différent" -#: type.c:263 +#: type.c:265 #, c-format msgid "variable \"%s\" is hidden by a local variable" msgstr "la variable « %s » est cachée par une variable locale" -#: type.c:275 +#: type.c:277 #, c-format -msgid "indicator variable \"%s\" is hidden by a local variable of a different type" +msgid "" +"indicator variable \"%s\" is hidden by a local variable of a different type" msgstr "" "la variable indicateur « %s » est caché par une variable locale d'un type\n" "différent" -#: type.c:277 +#: type.c:279 #, c-format msgid "indicator variable \"%s\" is hidden by a local variable" msgstr "la variable indicateur « %s » est cachée par une variable locale" -#: type.c:285 +#: type.c:287 #, c-format msgid "indicator for array/pointer has to be array/pointer" msgstr "l'indicateur pour le tableau/pointeur doit être tableau/pointeur" -#: type.c:289 +#: type.c:291 #, c-format msgid "nested arrays are not supported (except strings)" msgstr "" "les tableaux imbriqués ne sont pas supportés (sauf les chaînes de\n" "caractères)" -#: type.c:331 +#: type.c:333 #, c-format msgid "indicator for struct has to be a struct" msgstr "l'indicateur d'un struct doit être un struct" -#: type.c:351 type.c:372 type.c:392 +#: type.c:353 type.c:374 type.c:394 #, c-format msgid "indicator for simple data type has to be simple" msgstr "l'indicateur d'un type de données simple doit être simple" -#: type.c:723 +#: type.c:625 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "le struct indicateur « %s » a trop peu de membres" + +#: type.c:633 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "le struct indicateur « %s » a trop de membres" + +#: type.c:744 #, c-format msgid "unrecognized descriptor item code %d" msgstr "code %d de l'élément du descripteur non reconnu" @@ -624,7 +659,8 @@ msgstr "la variable « %s » n'est pas un pointeur" #: variable.c:142 variable.c:167 #, c-format msgid "variable \"%s\" is not a pointer to a structure or a union" -msgstr "la variable « %s » n'est pas un pointeur vers une structure ou une union" +msgstr "" +"la variable « %s » n'est pas un pointeur vers une structure ou une union" #: variable.c:154 #, c-format @@ -658,8 +694,10 @@ msgstr "les tableaux multidimensionnels ne sont pas supportés" #: variable.c:534 #, c-format -msgid "multilevel pointers (more than 2 levels) are not supported; found %d level" -msgid_plural "multilevel pointers (more than 2 levels) are not supported; found %d levels" +msgid "" +"multilevel pointers (more than 2 levels) are not supported; found %d level" +msgid_plural "" +"multilevel pointers (more than 2 levels) are not supported; found %d levels" msgstr[0] "" "les pointeurs multi-niveaux (plus de deux) ne sont pas supportés :\n" "%d niveau trouvé" @@ -675,25 +713,26 @@ msgstr "ce type de données ne supporte pas les pointeurs de pointeur" #: variable.c:559 #, c-format msgid "multidimensional arrays for structures are not supported" -msgstr "les tableaux multidimensionnels ne sont pas supportés pour les structures" +msgstr "" +"les tableaux multidimensionnels ne sont pas supportés pour les structures" -#~ msgid " --version output version information, then exit\n" -#~ msgstr " --version affiche la version et quitte\n" +#~ msgid "COPY TO STDIN is not possible" +#~ msgstr "COPY TO STDIN n'est pas possible" -#~ msgid "AT option not allowed in DEALLOCATE statement" -#~ msgstr "option AT non autorisée dans une instruction DEALLOCATE" +#~ msgid "COPY FROM STDOUT is not possible" +#~ msgstr "COPY FROM STDOUT n'est pas possible" -#~ msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" -#~ msgstr "une contrainte déclarée INITIALLY DEFERRED doit être DEFERRABLE" +#~ msgid "NEW used in query that is not in a rule" +#~ msgstr "NEW utilisé dans une requête qui n'est pas dans une règle" #~ msgid "OLD used in query that is not in a rule" #~ msgstr "OLD utilisé dans une requête qui n'est pas dans une règle" -#~ msgid "NEW used in query that is not in a rule" -#~ msgstr "NEW utilisé dans une requête qui n'est pas dans une règle" +#~ msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" +#~ msgstr "une contrainte déclarée INITIALLY DEFERRED doit être DEFERRABLE" -#~ msgid "COPY FROM STDOUT is not possible" -#~ msgstr "COPY FROM STDOUT n'est pas possible" +#~ msgid "AT option not allowed in DEALLOCATE statement" +#~ msgstr "option AT non autorisée dans une instruction DEALLOCATE" -#~ msgid "COPY TO STDIN is not possible" -#~ msgstr "COPY TO STDIN n'est pas possible" +#~ msgid " --version output version information, then exit\n" +#~ msgstr " --version affiche la version et quitte\n" diff --git a/src/interfaces/ecpg/preproc/po/it.po b/src/interfaces/ecpg/preproc/po/it.po index 19c77755ea8..bfdd9ea0953 100644 --- a/src/interfaces/ecpg/preproc/po/it.po +++ b/src/interfaces/ecpg/preproc/po/it.po @@ -1,36 +1,33 @@ # -# Translation of ecpg to Italian -# PostgreSQL Project +# ecpg.po +# Italian message translation file for ecpg # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Maurizio Totti +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Emanuele Zamprogno +# Daniele Varrazzo , 2012-2017. +# Maurizio Totti , 2010. # -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: ecpg (PostgreSQL) 10\n" +"Project-Id-Version: ecpg (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-22 22:38+0000\n" -"PO-Revision-Date: 2017-04-23 04:44+0100\n" +"POT-Creation-Date: 2018-10-08 14:08+0000\n" +"PO-Revision-Date: 2018-10-08 21:54+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" #: descriptor.c:64 #, c-format @@ -105,10 +102,10 @@ msgstr "" #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" " -C MODO imposta la modalità di compatibilità; MODO può essere uno\n" -" tra \"INFORMIX\", \"INFORMIX_SE\"\n" +" tra \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" #: ecpg.c:46 #, c-format @@ -194,149 +191,149 @@ msgstr "" msgid "%s: could not locate my own executable path\n" msgstr "%s: percorso del proprio eseguibile non trovato\n" -#: ecpg.c:174 ecpg.c:327 ecpg.c:337 +#: ecpg.c:174 ecpg.c:331 ecpg.c:342 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: apertura del file \"%s\" fallita: %s\n" -#: ecpg.c:213 ecpg.c:226 ecpg.c:242 ecpg.c:268 +#: ecpg.c:217 ecpg.c:230 ecpg.c:246 ecpg.c:272 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "Prova \"%s --help\" per maggiori informazioni.\n" -#: ecpg.c:237 +#: ecpg.c:241 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: il supporto al debug del parser (-d) non è disponibile\n" -#: ecpg.c:256 +#: ecpg.c:260 #, c-format msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" msgstr "%s, il preprocessore di PostgreSQL per programmi in C, versione %s\n" -#: ecpg.c:258 +#: ecpg.c:262 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... la ricerca inizia da qui:\n" -#: ecpg.c:261 +#: ecpg.c:265 #, c-format msgid "end of search list\n" msgstr "fine della lista di ricerca\n" -#: ecpg.c:267 +#: ecpg.c:271 #, c-format msgid "%s: no input files specified\n" msgstr "%s: non è stato specificato nessun file di input\n" -#: ecpg.c:460 +#: ecpg.c:465 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "il cursore \"%s\" è stato dichiarato, ma non aperto" -#: ecpg.c:473 preproc.y:127 +#: ecpg.c:478 preproc.y:127 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "rimozione del file di output \"%s\" fallita\n" -#: pgc.l:431 +#: pgc.l:444 #, c-format msgid "unterminated /* comment" msgstr "commento /* non terminato" # string literal sarebbe intraducubile infatti è come la stringa viene rappresentata nel linguaggio di programmazione, ma come si fa a tradurlo?.... # Secondo me "stringa letterale" -- Daniele -#: pgc.l:444 +#: pgc.l:457 #, c-format msgid "invalid bit string literal" msgstr "bit nella stringa letterale non valido" -#: pgc.l:453 +#: pgc.l:466 #, c-format msgid "unterminated bit string literal" msgstr "letterale di stringa di bit non terminato" -#: pgc.l:469 +#: pgc.l:482 #, c-format msgid "unterminated hexadecimal string literal" msgstr "letterale di stringa esadecimale non terminato" -#: pgc.l:547 +#: pgc.l:560 #, c-format msgid "unterminated quoted string" msgstr "stringa tra virgolette non terminata" -#: pgc.l:605 pgc.l:618 +#: pgc.l:618 pgc.l:631 #, c-format msgid "zero-length delimited identifier" msgstr "identificativo delimitato di lunghezza zero" -#: pgc.l:626 +#: pgc.l:639 #, c-format msgid "unterminated quoted identifier" msgstr "identificativo tra virgolette non terminato" -#: pgc.l:881 +#: pgc.l:921 #, c-format msgid "nested /* ... */ comments" msgstr "commenti /* ... */ annidati" -#: pgc.l:974 +#: pgc.l:1014 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "identificativo mancante nel comando EXEC SQL UNDEF" -#: pgc.l:1020 pgc.l:1034 +#: pgc.l:1060 pgc.l:1074 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "mancata corrispondenza fra \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" -#: pgc.l:1023 pgc.l:1036 pgc.l:1212 +#: pgc.l:1063 pgc.l:1076 pgc.l:1252 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "manca \"EXEC SQL ENDIF;\"" -#: pgc.l:1052 pgc.l:1071 +#: pgc.l:1092 pgc.l:1111 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "più di un EXEC SQL ELSE" -#: pgc.l:1093 pgc.l:1107 +#: pgc.l:1133 pgc.l:1147 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "EXEC SQL ENDIF non corrispondente" -#: pgc.l:1127 +#: pgc.l:1167 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "troppe condizioni EXEC SQL IFDEF annidate" -#: pgc.l:1160 +#: pgc.l:1200 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "identificativo mancante nel comando EXEC SQL IFDEF" -#: pgc.l:1169 +#: pgc.l:1209 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "identificativo mancante nel comando EXEC SQL DEFINE" -#: pgc.l:1202 +#: pgc.l:1242 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "errore di sintassi nel comando EXEC SQL INCLUDE" -#: pgc.l:1251 +#: pgc.l:1291 #, c-format msgid "internal error: unreachable state; please report this to " msgstr "errore interno: stato non raggiungibile, si prega di segnalarlo a " -#: pgc.l:1375 +#: pgc.l:1420 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "Errore: il percorso delle inclusioni \"%s/%s\" è troppo lungo alla riga %d, perciò viene saltato\n" -#: pgc.l:1398 +#: pgc.l:1443 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "apertura del file di include \"%s\" alla riga %d fallita" @@ -370,185 +367,185 @@ msgstr "l'inizializzatore non è permesso nella definizione del tipo di dato" msgid "type name \"string\" is reserved in Informix mode" msgstr "il nome di tipo \"string\" è riservato alla modalità Informix" -#: preproc.y:546 preproc.y:15453 +#: preproc.y:546 preproc.y:15744 #, c-format msgid "type \"%s\" is already defined" msgstr "il tipo \"%s\" è già definito" -#: preproc.y:570 preproc.y:16111 preproc.y:16431 variable.c:620 +#: preproc.y:570 preproc.y:16402 preproc.y:16727 variable.c:620 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "gli array multidimensionali per tipi dato semplici non sono supportati" -#: preproc.y:1685 +#: preproc.y:1694 #, c-format msgid "AT option not allowed in CLOSE DATABASE statement" msgstr "l'opzione AT non è permessa nell'istruzione CLOSE DATABASE" -#: preproc.y:1898 +#: preproc.y:1903 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "l'opzione AT non è permessa nell'istruzione CONNECT" -#: preproc.y:1932 +#: preproc.y:1937 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "l'opzione AT non è permessa nell'istruzione DISCONNECT" -#: preproc.y:1987 +#: preproc.y:1992 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "l'opzione AT non è permessa nell'istruzione SET CONNECTION" -#: preproc.y:2009 +#: preproc.y:2014 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "l'opzione AT non è permessa nell'istruzione TYPE" -#: preproc.y:2018 +#: preproc.y:2023 #, c-format msgid "AT option not allowed in VAR statement" msgstr "l'opzione AT non è permessa nell'istruzione VAR" -#: preproc.y:2025 +#: preproc.y:2030 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "l'opzione AT non è permessa nell'istruzione WHENEVER" -#: preproc.y:2277 preproc.y:2282 preproc.y:2398 preproc.y:4003 preproc.y:5549 -#: preproc.y:5558 preproc.y:5866 preproc.y:7402 preproc.y:8834 preproc.y:8839 -#: preproc.y:11571 preproc.y:12192 +#: preproc.y:2107 preproc.y:2279 preproc.y:2284 preproc.y:2400 preproc.y:4045 +#: preproc.y:5615 preproc.y:5624 preproc.y:5924 preproc.y:7523 preproc.y:9016 +#: preproc.y:9021 preproc.y:11812 #, c-format msgid "unsupported feature will be passed to server" msgstr "al server è stata richiesta una funzionalità non supportata" -#: preproc.y:2656 +#: preproc.y:2658 #, c-format msgid "SHOW ALL is not implemented" msgstr "SHOW ALL non è implementato" -#: preproc.y:3328 +#: preproc.y:3386 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "COPY FROM STDIN non è implementato" -#: preproc.y:9737 preproc.y:15042 +#: preproc.y:9969 preproc.y:15333 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "usare la variabile \"%s\" in una diversa istruzione declare non è supportato" -#: preproc.y:9739 preproc.y:15044 +#: preproc.y:9971 preproc.y:15335 #, c-format msgid "cursor \"%s\" is already defined" msgstr "il cursore \"%s\" è già definito" -#: preproc.y:10169 +#: preproc.y:10401 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "la sintassi LIMIT #,# passata al server non è più supportata" -#: preproc.y:10485 preproc.y:10492 +#: preproc.y:10726 preproc.y:10733 #, c-format msgid "subquery in FROM must have an alias" msgstr "la sottoquery in FROM deve avere un alias" -#: preproc.y:14772 +#: preproc.y:15063 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE AS non può specificare INTO" -#: preproc.y:14808 +#: preproc.y:15099 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "atteso \"@\", trovato \"%s\"" -#: preproc.y:14820 +#: preproc.y:15111 #, c-format msgid "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported" msgstr "soltanto i protocolli \"tcp\" e \"unix\" ed il tipo database \"postgresql\" sono supportati" -#: preproc.y:14823 +#: preproc.y:15114 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "atteso \"://\", trovato \"%s\"" -#: preproc.y:14828 +#: preproc.y:15119 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" msgstr "i socket di dominio Unix funzionano solo con \"localhost\" ma non con \"%s\"" -#: preproc.y:14854 +#: preproc.y:15145 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "atteso \"postgresql\", trovato \"%s\"" -#: preproc.y:14857 +#: preproc.y:15148 #, c-format msgid "invalid connection type: %s" msgstr "tipo di connessione non valido: %s" -#: preproc.y:14866 +#: preproc.y:15157 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "atteso \"@\" oppure \"://\", trovato \"%s\"" -#: preproc.y:14941 preproc.y:14959 +#: preproc.y:15232 preproc.y:15250 #, c-format msgid "invalid data type" msgstr "tipo dato non valido" -#: preproc.y:14970 preproc.y:14987 +#: preproc.y:15261 preproc.y:15278 #, c-format msgid "incomplete statement" msgstr "istruzione incompleta" -#: preproc.y:14973 preproc.y:14990 +#: preproc.y:15264 preproc.y:15281 #, c-format msgid "unrecognized token \"%s\"" msgstr "token \"%s\" sconosciuto" -#: preproc.y:15264 +#: preproc.y:15555 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "solo i dati di tipo numeric e decimal hanno argomento precisione/scala" -#: preproc.y:15276 +#: preproc.y:15567 #, c-format msgid "interval specification not allowed here" msgstr "specificazione di intervallo non permessa qui" -#: preproc.y:15428 preproc.y:15480 +#: preproc.y:15719 preproc.y:15771 #, c-format msgid "too many levels in nested structure/union definition" msgstr "troppi livelli nidificati nella definizione della struttura/unione" -#: preproc.y:15619 +#: preproc.y:15910 #, c-format msgid "pointers to varchar are not implemented" msgstr "i puntatori a varchar non sono implementati" -#: preproc.y:15806 preproc.y:15831 +#: preproc.y:16097 preproc.y:16122 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "si sta utilizzando una istruzione DESCRIBE non supportata" -#: preproc.y:16078 +#: preproc.y:16369 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" msgstr "initializer non è permesso nel comando EXEC SQL VAR" -#: preproc.y:16389 +#: preproc.y:16685 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "array di indicatori non sono permessi" -#: preproc.y:16610 +#: preproc.y:16906 #, c-format msgid "operator not allowed in variable definition" msgstr "operatore non permesso nella definizione di variabile" #. translator: %s is typically the translation of "syntax error" -#: preproc.y:16648 +#: preproc.y:16947 #, c-format msgid "%s at or near \"%s\"" msgstr "%s a o presso \"%s\"" @@ -558,7 +555,7 @@ msgstr "%s a o presso \"%s\"" msgid "out of memory" msgstr "memoria esaurita" -#: type.c:212 type.c:664 +#: type.c:212 type.c:676 #, c-format msgid "unrecognized variable type code %d" msgstr "tipo di variabile sconosciuto codice %d" @@ -604,7 +601,17 @@ msgstr "un indicatore per una struttura deve essere una struttura" msgid "indicator for simple data type has to be simple" msgstr "un indicatore per un tipo di dato semplice deve essere semplice" -#: type.c:723 +#: type.c:616 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "l'indicatore struttura \"%s\" non ha abbastanza membri" + +#: type.c:624 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "l'indicatore struttura \"%s\" ha troppi membri" + +#: type.c:735 #, c-format msgid "unrecognized descriptor item code %d" msgstr "descrittore di codice %d sconosciuto" diff --git a/src/interfaces/ecpg/preproc/po/ja.po b/src/interfaces/ecpg/preproc/po/ja.po index 68aa91caa49..33cbd9ea0b5 100644 --- a/src/interfaces/ecpg/preproc/po/ja.po +++ b/src/interfaces/ecpg/preproc/po/ja.po @@ -5,17 +5,18 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0 beta 3\n" +"Project-Id-Version: PostgreSQL 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 09:56+0900\n" -"PO-Revision-Date: 2010-07-21 18:37+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-08-31 16:21+0900\n" +"PO-Revision-Date: 2018-08-21 20:52+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.5.4\n" #: descriptor.c:64 #, c-format @@ -27,27 +28,27 @@ msgstr "変数\"%s\"ã¯æ•°å€¤åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" msgid "descriptor \"%s\" does not exist" msgstr "%s記述å­ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: descriptor.c:161 descriptor.c:210 +#: descriptor.c:161 descriptor.c:213 #, c-format msgid "descriptor header item \"%d\" does not exist" msgstr "記述å­ãƒ˜ãƒƒãƒ€é …ç›®%dã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: descriptor.c:182 +#: descriptor.c:183 #, c-format msgid "nullable is always 1" msgstr "nullableã¯å¸¸ã«1ã§ã™" -#: descriptor.c:185 +#: descriptor.c:186 #, c-format msgid "key_member is always 0" msgstr "key_memberã¯å¸¸ã«0ã§ã™" -#: descriptor.c:277 +#: descriptor.c:280 #, c-format msgid "descriptor item \"%s\" is not implemented" msgstr "記述å­é …ç›®%sã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: descriptor.c:287 +#: descriptor.c:290 #, c-format msgid "descriptor item \"%s\" cannot be set" msgstr "記述å­é …ç›®%sã¯è¨­å®šã§ãã¾ã›ã‚“" @@ -90,10 +91,10 @@ msgstr "" #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" -" -C モード 互æ›ãƒ¢ãƒ¼ãƒ‰ã‚’設定ã—ã¾ã™ã€‚モードã¯\"INFORMIX\", \"INFORMIX_SE\"\n" -" ã®ã„ãšã‚Œã‹ã‚’設定ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™\n" +" -C MODE 互æ›ãƒ¢ãƒ¼ãƒ‰ã‚’設定; MODEã¯\"INFORMIX\"〠\"INFORMIX_SE\"ã€\n" +" \"ORACLE\"ã®ã„ãšã‚Œã‹ã§ã™\n" #: ecpg.c:46 #, c-format @@ -103,27 +104,29 @@ msgstr " -d パーサã®ãƒ‡ãƒãƒƒã‚°å‡ºåŠ›ã‚’æœ‰åŠ¹ã«ã—ã¾ã™\n" #: ecpg.c:48 #, c-format msgid " -D SYMBOL define SYMBOL\n" -msgstr " -D シンボル シンボルを定義ã—ã¾ã™\n" +msgstr " -D SYMBOL シンボル SYMBOL を定義ã—ã¾ã™\n" #: ecpg.c:49 #, c-format msgid " -h parse a header file, this option includes option \"-c\"\n" -msgstr " -h ヘッダファイルを解æžã—ã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã«ã¯\"-c\"オプションãŒå«ã¾ã‚Œã¾ã™\n" +msgstr "" +" -h ヘッダファイルをパースã—ã¾ã™ã€‚ã“ã®ã‚ªãƒ—ションã«ã¯\"-c\"オプション\n" +" ãŒå«ã¾ã‚Œã¾ã™\n" #: ecpg.c:50 #, c-format msgid " -i parse system include files as well\n" -msgstr " -i ã‚·ã‚¹ãƒ†ãƒ ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ•ã‚¡ã‚¤ãƒ«ã‚‚åŒæ™‚ã«è§£æžã—ã¾ã™\n" +msgstr " -i システムインクルードファイルもパースã—ã¾ã™\n" #: ecpg.c:51 #, c-format msgid " -I DIRECTORY search DIRECTORY for include files\n" -msgstr " -I ディレクトリ ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ•ã‚¡ã‚¤ãƒ«ã®æ¤œç´¢ã«ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’使用ã—ã¾ã™\n" +msgstr " -I DIRECTORY DIRECTORYã‹ã‚‰ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ•ァイルを検索ã—ã¾ã™\n" #: ecpg.c:52 #, c-format msgid " -o OUTFILE write result to OUTFILE\n" -msgstr " -o 出力ファイル çµæžœã‚’å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã«æ›¸ã出ã—ã¾ã™\n" +msgstr " -o OUTFILE çµæžœã‚’OUTFILEã«å‡ºåŠ›ã—ã¾ã™\n" #: ecpg.c:53 #, c-format @@ -131,7 +134,7 @@ msgid "" " -r OPTION specify run-time behavior; OPTION can be:\n" " \"no_indicator\", \"prepare\", \"questionmarks\"\n" msgstr "" -" -r OPTION 実行時ã®å‹•作を指定ã—ã¾ã™ã€‚ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã¯æ¬¡ã®ã„ãšã‚Œã‹ã‚’å–ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚\n" +" -r OPTION 実行時ã®å‹•作を指定ã—ã¾ã™ã€‚ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã¯æ¬¡ã®ã„ãšã‚Œã‹ã§ã™\n" " \"no_indicator\"ã€\"prepare\"ã€\"questionmarks\"\n" #: ecpg.c:55 @@ -146,13 +149,13 @@ msgstr " -t トランザクションã®è‡ªå‹•コミットを有効 #: ecpg.c:57 #, c-format -msgid " --version output version information, then exit\n" -msgstr " --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を出力ã—ã€çµ‚了ã—ã¾ã™\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version ãƒãƒ¼ã‚¸ãƒ§ãƒ³æƒ…報を出力ã—ã¦ã€çµ‚了ã—ã¾ã™\n" #: ecpg.c:58 #, c-format msgid " -?, --help show this help, then exit\n" -msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" +msgstr " -?, --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã¦ã€çµ‚了ã—ã¾ã™\n" #: ecpg.c:59 #, c-format @@ -162,7 +165,7 @@ msgid "" "input file name, after stripping off .pgc if present.\n" msgstr "" "\n" -"å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãŒæŒ‡å®šã•れã¦ã„ãªã„å ´åˆã€å…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®åå‰ã«.cを付ã‘ãŸåå‰ã«ãªã‚Šã¾ã™ã€‚\n" +"å‡ºåŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®æŒ‡å®šãŒãªã„å ´åˆã¯ã€å…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ã®åå‰ã«.cを付ã‘ãŸåå‰ã«ãªã‚Šã¾ã™ã€‚\n" "ãŸã ã—ã€ã‚‚ã—.pgcãŒã‚ã‚‹å ´åˆã¯ã“れをå–り除ã„ã¦ã‹ã‚‰.cãŒä»˜ã‘られã¾ã™ã€‚\n" #: ecpg.c:61 @@ -174,142 +177,152 @@ msgstr "" "\n" "ä¸å…·åˆã¯ã«å ±å‘Šã—ã¦ãã ã•ã„。\n" -#: ecpg.c:182 ecpg.c:333 ecpg.c:343 +#: ecpg.c:139 +#, c-format +msgid "%s: could not locate my own executable path\n" +msgstr "%s: 自身ã®å®Ÿè¡Œãƒ•ァイルã®å ´æ‰€ãŒã‚ã‹ã‚Šã¾ã›ã‚“\n" + +#: ecpg.c:174 ecpg.c:331 ecpg.c:342 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: ecpg.c:221 ecpg.c:234 ecpg.c:250 ecpg.c:275 +#: ecpg.c:217 ecpg.c:230 ecpg.c:246 ecpg.c:272 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "詳細ã¯\"%s --help\"を実行ã—ã¦ãã ã•ã„。\n" -#: ecpg.c:245 +#: ecpg.c:241 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: パーサデãƒãƒƒã‚°ã®ã‚µãƒãƒ¼ãƒˆ(-d)を利用ã§ãã¾ã›ã‚“\n" -#: ecpg.c:263 +#: ecpg.c:260 #, c-format -msgid "%s, the PostgreSQL embedded C preprocessor, version %d.%d.%d\n" -msgstr "%s PostgreSQL埋込ã¿C言語プリプロセッサ ãƒãƒ¼ã‚¸ãƒ§ãƒ³%d.%d.%d\n" +msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" +msgstr "%s, PostgreSQL埋込ã¿C言語プリプロセッサ, ãƒãƒ¼ã‚¸ãƒ§ãƒ³%s\n" -#: ecpg.c:265 +#: ecpg.c:262 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... 検索ãŒå§‹ã¾ã‚Šã¾ã™\n" -#: ecpg.c:268 +#: ecpg.c:265 #, c-format msgid "end of search list\n" msgstr "検索リストã®çµ‚端ã§ã™\n" -#: ecpg.c:274 +#: ecpg.c:271 #, c-format msgid "%s: no input files specified\n" msgstr "%s: å…¥åŠ›ãƒ•ã‚¡ã‚¤ãƒ«ãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“\n" -#: ecpg.c:466 +#: ecpg.c:465 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "カーソル%sã¯å®£è¨€ã•れã¾ã—ãŸãŒã€ã‚ªãƒ¼ãƒ—ンã•れã¦ã„ã¾ã›ã‚“" -#: ecpg.c:479 preproc.y:109 +#: ecpg.c:478 preproc.y:127 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "出力ファイル\"%s\"を削除ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: pgc.l:403 +#: pgc.l:444 #, c-format msgid "unterminated /* comment" msgstr "/*コメントãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: pgc.l:416 +#: pgc.l:457 #, c-format msgid "invalid bit string literal" msgstr "無効ãªãƒ“ット列リテラルã§ã™" -#: pgc.l:425 +#: pgc.l:466 #, c-format msgid "unterminated bit string literal" msgstr "ビット文字列リテラルã®çµ‚端ãŒã‚りã¾ã›ã‚“" -#: pgc.l:441 +#: pgc.l:482 #, c-format msgid "unterminated hexadecimal string literal" msgstr "16進数文字列リテラルã®çµ‚端ãŒã‚りã¾ã›ã‚“" -#: pgc.l:519 +#: pgc.l:560 #, c-format msgid "unterminated quoted string" msgstr "文字列ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: pgc.l:574 pgc.l:587 +#: pgc.l:618 pgc.l:631 #, c-format msgid "zero-length delimited identifier" msgstr "区切りã¤ã識別å­ã®é•·ã•ãŒã‚¼ãƒ­ã§ã™" -#: pgc.l:595 +#: pgc.l:639 #, c-format msgid "unterminated quoted identifier" msgstr "識別å­ã®å¼•用符ãŒé–‰ã˜ã¦ã„ã¾ã›ã‚“" -#: pgc.l:941 +#: pgc.l:921 +#, c-format +msgid "nested /* ... */ comments" +msgstr "入れå­çŠ¶ã® /* ... */ コメント" + +#: pgc.l:1014 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "EXEC SQL UNDEFコマンドã«ãŠã„ã¦è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“" -#: pgc.l:987 pgc.l:1001 +#: pgc.l:1060 pgc.l:1074 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "対応ã™ã‚‹\"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"ãŒã‚りã¾ã›ã‚“" -#: pgc.l:990 pgc.l:1003 pgc.l:1179 +#: pgc.l:1063 pgc.l:1076 pgc.l:1252 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "\"EXEC SQL ENDIF;\"ãŒã‚りã¾ã›ã‚“" -#: pgc.l:1019 pgc.l:1038 +#: pgc.l:1092 pgc.l:1111 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "1ã¤ä»¥ä¸Šã®EXEC SQL ELSE\"ãŒå­˜åœ¨ã—ã¾ã™" -#: pgc.l:1060 pgc.l:1074 +#: pgc.l:1133 pgc.l:1147 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "EXEC SQL ENDIFã«å¯¾å¿œã™ã‚‹ã‚‚ã®ãŒã‚りã¾ã›ã‚“" -#: pgc.l:1094 +#: pgc.l:1167 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "入れå­çжã®EXEC SQL IFDEFæ¡ä»¶ãŒå¤šã™ãŽã¾ã™" -#: pgc.l:1127 +#: pgc.l:1200 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "EXEC SQL IFDEFコマンドã«ãŠã„ã¦è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“" -#: pgc.l:1136 +#: pgc.l:1209 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "EXEC SQL DEFINEコマンドã«ãŠã„ã¦è­˜åˆ¥å­ãŒã‚りã¾ã›ã‚“" -#: pgc.l:1169 +#: pgc.l:1242 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "EXEC SQL INCLUDEコマンドã«ãŠã„ã¦æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™" -#: pgc.l:1218 +#: pgc.l:1291 #, c-format msgid "internal error: unreachable state; please report this to " msgstr "内部エラー: 到é”ã—ãªã„ã¯ãšã®çŠ¶æ…‹ã§ã™ã€‚ã¾ã§å ±å‘Šã—ã¦ãã ã•ã„" -#: pgc.l:1343 +#: pgc.l:1420 #, c-format msgid "Error: include path \"%s/%s\" is too long on line %d, skipping\n" msgstr "エラー:行番å·%3$dã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ‘ス\"%1$s/%2$s\"ãŒé•·ã™ãŽã¾ã™ã€‚無視ã—ã¾ã—ãŸã€‚\n" -#: pgc.l:1365 +#: pgc.l:1443 #, c-format msgid "could not open include file \"%s\" on line %d" msgstr "行番å·%2$dã®ã‚¤ãƒ³ã‚¯ãƒ«ãƒ¼ãƒ‰ãƒ•ァイル\"%1$s\"をオープンã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" @@ -323,200 +336,205 @@ msgstr "構文エラー" msgid "WARNING: " msgstr "警告: " -#: preproc.y:85 +#: preproc.y:84 #, c-format msgid "ERROR: " msgstr "エラー: " -#: preproc.y:491 +#: preproc.y:508 #, c-format msgid "cursor \"%s\" does not exist" msgstr "カーソル\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: preproc.y:520 +#: preproc.y:537 #, c-format msgid "initializer not allowed in type definition" -msgstr "型定義ã§ã¯ã‚¤ãƒ‹ã‚·ãƒ£ãƒ©ã‚¤ã‚¶ã¯è¨±ã•れã¾ã›ã‚“" +msgstr "型定義ã§ã¯åˆæœŸåŒ–å­ã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:522 +#: preproc.y:539 #, c-format msgid "type name \"string\" is reserved in Informix mode" msgstr "åž‹å\"string\"ã¯Informixモードã§ã™ã§ã«äºˆç´„ã•れã¦ã„ã¾ã™" -#: preproc.y:529 preproc.y:13638 +#: preproc.y:546 preproc.y:15744 #, c-format msgid "type \"%s\" is already defined" msgstr "\"%s\"åž‹ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" -#: preproc.y:553 preproc.y:14291 preproc.y:14612 variable.c:614 +#: preproc.y:570 preproc.y:16402 preproc.y:16727 variable.c:620 #, c-format msgid "multidimensional arrays for simple data types are not supported" msgstr "å˜ç´”ãªãƒ‡ãƒ¼ã‚¿åž‹ã®å¤šæ¬¡å…ƒé…列ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:1544 +#: preproc.y:1694 #, c-format msgid "AT option not allowed in CLOSE DATABASE statement" msgstr "CLOSE DATABASEæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1747 +#: preproc.y:1903 #, c-format msgid "AT option not allowed in CONNECT statement" msgstr "CONNECTæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1781 +#: preproc.y:1937 #, c-format msgid "AT option not allowed in DISCONNECT statement" msgstr "DISCONNECTæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1836 +#: preproc.y:1992 #, c-format msgid "AT option not allowed in SET CONNECTION statement" msgstr "SET CONNECTIONæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1858 +#: preproc.y:2014 #, c-format msgid "AT option not allowed in TYPE statement" msgstr "TYPEæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1867 +#: preproc.y:2023 #, c-format msgid "AT option not allowed in VAR statement" msgstr "VARæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:1874 +#: preproc.y:2030 #, c-format msgid "AT option not allowed in WHENEVER statement" msgstr "WHENEVERæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:2122 preproc.y:2127 preproc.y:2242 preproc.y:3548 preproc.y:4800 -#: preproc.y:4809 preproc.y:5105 preproc.y:7552 preproc.y:7557 preproc.y:9965 -#: preproc.y:10555 +#: preproc.y:2107 preproc.y:2279 preproc.y:2284 preproc.y:2400 preproc.y:4045 +#: preproc.y:5615 preproc.y:5624 preproc.y:5924 preproc.y:7523 preproc.y:9016 +#: preproc.y:9021 preproc.y:11812 #, c-format msgid "unsupported feature will be passed to server" msgstr "サーãƒã«æœªã‚µãƒãƒ¼ãƒˆæ©Ÿèƒ½ãŒæ¸¡ã•れã¾ã™" -#: preproc.y:2484 +#: preproc.y:2658 #, c-format msgid "SHOW ALL is not implemented" msgstr "SHOW ALLã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:2940 +#: preproc.y:3386 #, c-format msgid "COPY FROM STDIN is not implemented" msgstr "COPY FROM STDINã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:8381 preproc.y:13227 +#: preproc.y:9969 preproc.y:15333 #, c-format msgid "using variable \"%s\" in different declare statements is not supported" msgstr "ç•°ãªã£ãŸdeclareステートメントã«ãŠã‘る変数\"%s\"ã®ä½¿ç”¨ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:8383 preproc.y:13229 +#: preproc.y:9971 preproc.y:15335 #, c-format msgid "cursor \"%s\" is already defined" msgstr "カーソル\"%s\"ã¯ã™ã§ã«å®šç¾©ã•れã¦ã„ã¾ã™" -#: preproc.y:8801 +#: preproc.y:10401 #, c-format msgid "no longer supported LIMIT #,# syntax passed to server" msgstr "サーãƒã«æ¸¡ã•れるLIMIT #,#æ§‹æ–‡ã¯ã‚‚ã¯ã‚„サãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:9045 preproc.y:9052 +#: preproc.y:10726 preproc.y:10733 #, c-format msgid "subquery in FROM must have an alias" msgstr "FROMå¥ã®å‰¯å•ã„åˆã‚ã›ã¯åˆ¥åã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: preproc.y:12957 +#: preproc.y:15063 #, c-format msgid "CREATE TABLE AS cannot specify INTO" msgstr "CREATE TABLE ASã¯INTOを指定ã§ãã¾ã›ã‚“" -#: preproc.y:12993 +#: preproc.y:15099 #, c-format msgid "expected \"@\", found \"%s\"" msgstr "想定ã§ã¯\"@\"ã€çµæžœã§ã¯\"%s\"" -#: preproc.y:13005 +#: preproc.y:15111 #, c-format msgid "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported" msgstr "プロトコルã§ã¯\"tcp\"ãŠã‚ˆã³\"unix\"ã®ã¿ã€ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã®ç¨®é¡žã§ã¯\"postgresql\"ã®ã¿ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" -#: preproc.y:13008 +#: preproc.y:15114 #, c-format msgid "expected \"://\", found \"%s\"" msgstr "想定ã§ã¯\"://\"ã€çµæžœã§ã¯\"%s\"" -#: preproc.y:13013 +#: preproc.y:15119 #, c-format msgid "Unix-domain sockets only work on \"localhost\" but not on \"%s\"" msgstr "Unixドメインソケットã¯\"localhost\"ã§ã®ã¿ã§å‹•作ã—ã€\"%s\"ã§ã¯å‹•作ã—ã¾ã›ã‚“" -#: preproc.y:13039 +#: preproc.y:15145 #, c-format msgid "expected \"postgresql\", found \"%s\"" msgstr "想定ã§ã¯\"postgresql\"ã€çµæžœã§ã¯\"%s\"" -#: preproc.y:13042 +#: preproc.y:15148 #, c-format msgid "invalid connection type: %s" msgstr "ç„¡åŠ¹ãªæŽ¥ç¶šç¨®é¡ž: %s" -#: preproc.y:13051 +#: preproc.y:15157 #, c-format msgid "expected \"@\" or \"://\", found \"%s\"" msgstr "想定ã§ã¯\"@ã¾ãŸã¯\"\"://\"ã€çµæžœã§ã¯\"%s\"" -#: preproc.y:13126 preproc.y:13144 +#: preproc.y:15232 preproc.y:15250 #, c-format msgid "invalid data type" msgstr "無効ãªãƒ‡ãƒ¼ã‚¿åž‹" -#: preproc.y:13155 preproc.y:13172 +#: preproc.y:15261 preproc.y:15278 #, c-format msgid "incomplete statement" msgstr "ä¸å®Œå…¨ãªæ–‡" -#: preproc.y:13158 preproc.y:13175 +#: preproc.y:15264 preproc.y:15281 #, c-format msgid "unrecognized token \"%s\"" msgstr "èªè­˜ã§ããªã„トークン\"%s\"" -#: preproc.y:13449 +#: preproc.y:15555 #, c-format msgid "only data types numeric and decimal have precision/scale argument" msgstr "数値データ型ã¾ãŸã¯10進数データ型ã®ã¿ãŒç²¾åº¦/ä½å–り引数ã¨å–ã‚‹ã“ã¨ãŒã§ãã¾ã™" -#: preproc.y:13461 +#: preproc.y:15567 #, c-format msgid "interval specification not allowed here" msgstr "æ™‚é–“é–“éš”ã®æŒ‡å®šã¯ã“ã“ã§ã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:13613 preproc.y:13665 +#: preproc.y:15719 preproc.y:15771 #, c-format msgid "too many levels in nested structure/union definition" msgstr "構造体/ユニオンã®å®šç¾©ã®å…¥ã‚Œå­ãƒ¬ãƒ™ãƒ«ãŒæ·±ã™ãŽã¾ã™" -#: preproc.y:13799 +#: preproc.y:15910 #, c-format msgid "pointers to varchar are not implemented" msgstr "varcharを指ã—示ã™ãƒã‚¤ãƒ³ã‚¿ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: preproc.y:13986 preproc.y:14011 +#: preproc.y:16097 preproc.y:16122 #, c-format msgid "using unsupported DESCRIBE statement" msgstr "未サãƒãƒ¼ãƒˆã®DESCRIBEæ–‡ã®ä½¿ç”¨" -#: preproc.y:14258 +#: preproc.y:16369 #, c-format msgid "initializer not allowed in EXEC SQL VAR command" -msgstr "EXEC SQL VARコマンドã§ã¯ã‚¤ãƒ‹ã‚·ãƒ£ãƒ©ã‚¤ã‚¶ã¯è¨±ã•れã¾ã›ã‚“" +msgstr "EXEC SQL VARコマンドã§ã¯åˆæœŸåŒ–å­ã¯è¨±ã•れã¾ã›ã‚“" -#: preproc.y:14570 +#: preproc.y:16685 #, c-format msgid "arrays of indicators are not allowed on input" msgstr "指示å­é…列ã¯å…¥åŠ›ã¨ã—ã¦è¨±ã•れã¾ã›ã‚“" +#: preproc.y:16906 +#, c-format +msgid "operator not allowed in variable definition" +msgstr "変数定義ã§ã¯æ¼”ç®—å­ã¯è¨±ã•れã¾ã›ã‚“" + #. translator: %s is typically the translation of "syntax error" -#: preproc.y:14824 +#: preproc.y:16947 #, c-format msgid "%s at or near \"%s\"" msgstr "\"%2$s\"ã¾ãŸã¯ãã®è¿‘辺ã§%1$s" @@ -526,7 +544,7 @@ msgstr "\"%2$s\"ã¾ãŸã¯ãã®è¿‘辺ã§%1$s" msgid "out of memory" msgstr "メモリä¸è¶³ã§ã™" -#: type.c:212 type.c:593 +#: type.c:212 type.c:676 #, c-format msgid "unrecognized variable type code %d" msgstr "èªè­˜ã§ããªã„変数型コード%d" @@ -534,22 +552,22 @@ msgstr "èªè­˜ã§ããªã„変数型コード%d" #: type.c:261 #, c-format msgid "variable \"%s\" is hidden by a local variable of a different type" -msgstr "変数\"%s\"ã¯ã€ç•°ãªã£ãŸåž‹ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šä¸å¯è¦–ã«ãªã£ã¦ã„ã¾ã™" +msgstr "変数\"%s\"ã¯ã€ç•°ãªã£ãŸåž‹ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šéš è”½ã•れã¦ã„ã¾ã™" #: type.c:263 #, c-format msgid "variable \"%s\" is hidden by a local variable" -msgstr "変数\"%s\"ã¯ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šä¸å¯è¦–ã«ãªã£ã¦ã„ã¾ã™" +msgstr "変数\"%s\"ã¯ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šéš è”½ã•れã¦ã„ã¾ã™" #: type.c:275 #, c-format msgid "indicator variable \"%s\" is hidden by a local variable of a different type" -msgstr "指示å­å¤‰æ•°\"%s\"ã¯ã€ç•°ãªã£ãŸåž‹ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šä¸å¯è¦–ã«ãªã£ã¦ã„ã¾ã™" +msgstr "指示å­å¤‰æ•°\"%s\"ã¯ã€ç•°ãªã£ãŸåž‹ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šéš è”½ã•れã¦ã„ã¾ã™" #: type.c:277 #, c-format msgid "indicator variable \"%s\" is hidden by a local variable" -msgstr "指示å­å¤‰æ•°\"%s\"ã¯ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šä¸å¯è¦–ã«ãªã£ã¦ã„ã¾ã™" +msgstr "指示å­å¤‰æ•°\"%s\"ã¯ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«ã‚ˆã‚Šéš è”½ã•れã¦ã„ã¾ã™" #: type.c:285 #, c-format @@ -559,19 +577,29 @@ msgstr "é…列/ãƒã‚¤ãƒ³ã‚¿ç”¨ã®æŒ‡ç¤ºå­ã¯é…列/ãƒã‚¤ãƒ³ã‚¿ã§ãªã‘れ㰠#: type.c:289 #, c-format msgid "nested arrays are not supported (except strings)" -msgstr "入れå­çжã®é…列ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“(文字列ã¯é™¤ãã¾ã™ï¼‰" +msgstr "入れå­çжã®é…列ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“ (文字列ã¯é™¤ãã¾ã™)" -#: type.c:322 +#: type.c:331 #, c-format msgid "indicator for struct has to be a struct" msgstr "æ§‹é€ ä½“ç”¨ã®æŒ‡ç¤ºå­ã¯æ§‹é€ ä½“ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: type.c:331 type.c:339 type.c:347 +#: type.c:351 type.c:372 type.c:392 #, c-format msgid "indicator for simple data type has to be simple" -msgstr "å˜ç´”ãªãƒ‡ãƒ¼ã‚¿åž‹ç”¨ã®æŒ‡ç¤ºå­ã¯å˜ç´”ãªã‚‚ã®ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "å˜ç´”ãªãƒ‡ãƒ¼ã‚¿åž‹ç”¨ã®æŒ‡ç¤ºå­ã¯å˜ç´”åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: type.c:616 +#, c-format +msgid "indicator struct \"%s\" has too few members" +msgstr "æŒ‡ç¤ºå­æ§‹é€ ä½“\"%s\"ã®ãƒ¡ãƒ³ãƒãŒè¶³ã‚Šã¾ã›ã‚“" + +#: type.c:624 +#, c-format +msgid "indicator struct \"%s\" has too many members" +msgstr "æŒ‡ç¤ºå­æ§‹é€ ä½“\"%s\"ã®ãƒ¡ãƒ³ãƒãŒå¤šã™ãŽã¾ã™" -#: type.c:652 +#: type.c:735 #, c-format msgid "unrecognized descriptor item code %d" msgstr "èªè­˜ã§ããªã„記述å­é …目コード%dã§ã™" @@ -606,49 +634,34 @@ msgstr "変数\"%s\"ã¯é…列ã§ã¯ã‚りã¾ã›ã‚“" msgid "variable \"%s\" is not declared" msgstr "変数\"%s\"ã¯å®£è¨€ã•れã¦ã„ã¾ã›ã‚“" -#: variable.c:488 +#: variable.c:494 #, c-format msgid "indicator variable must have an integer type" msgstr "指示å­å¤‰æ•°ã¯æ•´æ•°åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: variable.c:500 +#: variable.c:506 #, c-format msgid "unrecognized data type name \"%s\"" msgstr "データ型å\"%s\"ã¯èªè­˜ã§ãã¾ã›ã‚“" -#: variable.c:511 variable.c:519 variable.c:536 variable.c:539 +#: variable.c:517 variable.c:525 variable.c:542 variable.c:545 #, c-format msgid "multidimensional arrays are not supported" msgstr "多次元é…列ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" -#: variable.c:528 +#: variable.c:534 #, c-format msgid "multilevel pointers (more than 2 levels) are not supported; found %d level" msgid_plural "multilevel pointers (more than 2 levels) are not supported; found %d levels" msgstr[0] "複数レベルã®ãƒã‚¤ãƒ³ã‚¿ï¼ˆ2レベル以上)ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“。%dレベルã‚りã¾ã™" msgstr[1] "複数レベルã®ãƒã‚¤ãƒ³ã‚¿ï¼ˆ2レベル以上)ã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“。%dレベルã‚りã¾ã™" -#: variable.c:533 +#: variable.c:539 #, c-format msgid "pointer to pointer is not supported for this data type" msgstr "ã“ã®ãƒ‡ãƒ¼ã‚¿åž‹ã§ã¯ã€ãƒã‚¤ãƒ³ã‚¿ã‚’指ã—示ã™ãƒã‚¤ãƒ³ã‚¿ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: variable.c:553 +#: variable.c:559 #, c-format msgid "multidimensional arrays for structures are not supported" msgstr "構造体ã®å¤šæ¬¡å…ƒé…列ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" - -#~ msgid "AT option not allowed in DEALLOCATE statement" -#~ msgstr "DEALLOCATEæ–‡ã§ã¯ATオプションã¯è¨±ã•れã¾ã›ã‚“" - -#~ msgid "COPY TO STDIN is not possible" -#~ msgstr "COPY TO STDINã¯ã§ãã¾ã›ã‚“" - -#~ msgid "COPY FROM STDOUT is not possible" -#~ msgstr "COPY FROM STDOUTã¯ã§ãã¾ã›ã‚“" - -#~ msgid "constraint declared INITIALLY DEFERRED must be DEFERRABLE" -#~ msgstr "INITIALLY DEFERREDã¨å®£è¨€ã•れãŸåˆ¶ç´„ã¯DEFERRABLEã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" - -#~ msgid " --help show this help, then exit\n" -#~ msgstr " --help ã“ã®ãƒ˜ãƒ«ãƒ—を表示ã—ã€çµ‚了ã—ã¾ã™\n" diff --git a/src/interfaces/ecpg/preproc/po/ko.po b/src/interfaces/ecpg/preproc/po/ko.po index 124482f963c..566b858ac05 100644 --- a/src/interfaces/ecpg/preproc/po/ko.po +++ b/src/interfaces/ecpg/preproc/po/ko.po @@ -1,9 +1,14 @@ +# LANGUAGE message translation file for ecpg +# Copyright (C) 2017 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# Ioseph Kim , 2017. +# msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" +"Project-Id-Version: ecpg (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 15:33+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 16:26+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" "Language: ko\n" @@ -22,7 +27,7 @@ msgstr "\"%s\" 변수는 ìˆ«ìž í˜•ì‹ì´ì–´ì•¼ 함" msgid "descriptor \"%s\" does not exist" msgstr "\"%s\" 설명ìžê°€ ì—†ìŒ" -#: descriptor.c:161 descriptor.c:212 +#: descriptor.c:161 descriptor.c:213 #, c-format msgid "descriptor header item \"%d\" does not exist" msgstr "ì„¤ëª…ìž í—¤ë” í•­ëª© \"%d\"ì´(ê°€) ì—†ìŒ" @@ -37,12 +42,12 @@ msgstr "null 허용 여부는 í•­ìƒ 1" msgid "key_member is always 0" msgstr "key_member는 í•­ìƒ 0" -#: descriptor.c:279 +#: descriptor.c:280 #, c-format msgid "descriptor item \"%s\" is not implemented" msgstr "ì„¤ëª…ìž í•­ëª© \"%s\"ì´(ê°€) 구현ë˜ì§€ 않ìŒ" -#: descriptor.c:289 +#: descriptor.c:290 #, c-format msgid "descriptor item \"%s\" cannot be set" msgstr "ì„¤ëª…ìž í•­ëª© \"%s\"ì„(를) 설정할 수 ì—†ìŒ" @@ -85,11 +90,10 @@ msgstr "" #, c-format msgid "" " -C MODE set compatibility mode; MODE can be one of\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" msgstr "" -" -C MODE 호환성 모드를 설정합니다. MODE는 ë‹¤ìŒ ì¤‘ í•˜ë‚˜ì¼ ìˆ˜ 있습니" -"다.\n" -" \"INFORMIX\", \"INFORMIX_SE\"\n" +" -C MODE 호환성 모드를 설정합니다. MODE는 ë‹¤ìŒ ì¤‘ í•˜ë‚˜ì¼ ìˆ˜ 있습니다.\n" +" \"INFORMIX\", \"INFORMIX_SE\", \"ORACLE\"\n" #: ecpg.c:46 #, c-format @@ -103,8 +107,7 @@ msgstr " -D SYMBOL SYMBOL ì •ì˜\n" #: ecpg.c:49 #, c-format -msgid "" -" -h parse a header file, this option includes option \"-c\"\n" +msgid " -h parse a header file, this option includes option \"-c\"\n" msgstr " -h í—¤ë” íŒŒì¼ êµ¬ë¬¸ ë¶„ì„. ì´ ì˜µì…˜ì€ \"-c\" 옵션 í¬í•¨\n" #: ecpg.c:50 @@ -128,8 +131,7 @@ msgid "" " -r OPTION specify run-time behavior; OPTION can be:\n" " \"no_indicator\", \"prepare\", \"questionmarks\"\n" msgstr "" -" -r OPTION 런타임 ë™ìž‘ì„ ì§€ì •í•©ë‹ˆë‹¤. 사용 가능한 OPTIONì€ ë‹¤ìŒê³¼ 같습니" -"다.\n" +" -r OPTION 런타임 ë™ìž‘ì„ ì§€ì •í•©ë‹ˆë‹¤. 사용 가능한 OPTIONì€ ë‹¤ìŒê³¼ 같습니다.\n" " \"no_indicator\", \"prepare\", \"questionmarks\"\n" #: ecpg.c:55 @@ -144,8 +146,8 @@ msgstr " -t 트랜잭션 ìžë™ 커밋 설정\n" #: ecpg.c:57 #, c-format -msgid " --version output version information, then exit\n" -msgstr " --version 버전 정보를 출력하고 종료\n" +msgid " -V, --version output version information, then exit\n" +msgstr " -V, --version 버전 ì •ë³´ 보여주고 마침\n" #: ecpg.c:58 #, c-format @@ -172,156 +174,152 @@ msgstr "" "\n" "오류보고: .\n" -#: ecpg.c:143 +#: ecpg.c:139 #, c-format msgid "%s: could not locate my own executable path\n" msgstr "%s: 실행 가능한 경로를 지정할 수 없습니다\n" -#: ecpg.c:186 ecpg.c:337 ecpg.c:347 +#: ecpg.c:174 ecpg.c:331 ecpg.c:342 #, c-format msgid "%s: could not open file \"%s\": %s\n" msgstr "%s: \"%s\" íŒŒì¼ ì—´ 수 ì—†ìŒ: %s\n" -#: ecpg.c:225 ecpg.c:238 ecpg.c:254 ecpg.c:279 +#: ecpg.c:217 ecpg.c:230 ecpg.c:246 ecpg.c:272 #, c-format msgid "Try \"%s --help\" for more information.\n" msgstr "ìžì œí•œ ì‚¬í•­ì€ \"%s --help\" 명령으로 살펴보십시오.\n" -#: ecpg.c:249 +#: ecpg.c:241 #, c-format msgid "%s: parser debug support (-d) not available\n" msgstr "%s: 파서 디버그 ì§€ì›(-d)ì„ ì‚¬ìš©í•  수 ì—†ìŒ\n" -#: ecpg.c:267 +#: ecpg.c:260 #, c-format -msgid "%s, the PostgreSQL embedded C preprocessor, version %d.%d.%d\n" -msgstr "PostgreSQL í¬í•¨ C 전처리기 %sì˜ ë²„ì „ %d.%d.%d\n" +msgid "%s, the PostgreSQL embedded C preprocessor, version %s\n" +msgstr "%s, PostgreSQL í¬í•¨ C 전처리기, 버전 %s\n" -#: ecpg.c:269 +#: ecpg.c:262 #, c-format msgid "EXEC SQL INCLUDE ... search starts here:\n" msgstr "EXEC SQL INCLUDE ... 여기서 검색 시작:\n" -#: ecpg.c:272 +#: ecpg.c:265 #, c-format msgid "end of search list\n" msgstr "검색 목ë¡ì˜ ë\n" -#: ecpg.c:278 +#: ecpg.c:271 #, c-format msgid "%s: no input files specified\n" msgstr "%s: ì§€ì •ëœ ìž…ë ¥ íŒŒì¼ ì—†ìŒ\n" -#: ecpg.c:470 +#: ecpg.c:465 #, c-format msgid "cursor \"%s\" has been declared but not opened" msgstr "\"%s\" 커서가 ì„ ì–¸ë˜ì—ˆì§€ë§Œ 열리지 않ìŒ" -#: ecpg.c:483 preproc.y:127 +#: ecpg.c:478 preproc.y:127 #, c-format msgid "could not remove output file \"%s\"\n" msgstr "출력 íŒŒì¼ \"%s\"ì„(를) 제거할 수 ì—†ìŒ\n" -#: pgc.l:440 +#: pgc.l:444 #, c-format msgid "unterminated /* comment" msgstr "마무리 ì•ˆëœ /* 주ì„" -#: pgc.l:453 +#: pgc.l:457 #, c-format msgid "invalid bit string literal" msgstr "ìž˜ëª»ëœ ë¹„íŠ¸ 문ìžì—´ 리터럴" -#: pgc.l:462 +#: pgc.l:466 #, c-format msgid "unterminated bit string literal" msgstr "마무리 ì•ˆëœ ë¹„íŠ¸ 문ìžì—´ 문ìž" -#: pgc.l:478 +#: pgc.l:482 #, c-format msgid "unterminated hexadecimal string literal" msgstr "마무리 ì•ˆëœ 16진수 문ìžì—´ 문ìž" -#: pgc.l:556 +#: pgc.l:560 #, c-format msgid "unterminated quoted string" msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ë¬¸ìžì—´" -#: pgc.l:613 pgc.l:626 +#: pgc.l:618 pgc.l:631 #, c-format msgid "zero-length delimited identifier" msgstr "길ì´ê°€ 0ì¸ êµ¬ë¶„ ì‹ë³„ìž" -#: pgc.l:634 +#: pgc.l:639 #, c-format msgid "unterminated quoted identifier" msgstr "마무리 ì•ˆëœ ë”°ì˜´í‘œ ì•ˆì˜ ì‹ë³„ìž" -#: pgc.l:889 +#: pgc.l:921 #, c-format msgid "nested /* ... */ comments" msgstr "ì¤‘ì²©ëœ /* ... */ 주ì„" -#: pgc.l:982 +#: pgc.l:1014 #, c-format msgid "missing identifier in EXEC SQL UNDEF command" msgstr "EXEC SQL UNDEF ëª…ë ¹ì— ì‹ë³„ìž ëˆ„ë½" -#: pgc.l:1028 pgc.l:1042 +#: pgc.l:1060 pgc.l:1074 #, c-format msgid "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"" msgstr "ì¼ì¹˜í•˜ëŠ” \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\" 누ë½" -#: pgc.l:1031 pgc.l:1044 pgc.l:1220 +#: pgc.l:1063 pgc.l:1076 pgc.l:1252 #, c-format msgid "missing \"EXEC SQL ENDIF;\"" msgstr "\"EXEC SQL ENDIF;\" 누ë½" -#: pgc.l:1060 pgc.l:1079 +#: pgc.l:1092 pgc.l:1111 #, c-format msgid "more than one EXEC SQL ELSE" msgstr "ë‘ ê°œ ì´ìƒì˜ EXEC SQL ELSE" -#: pgc.l:1101 pgc.l:1115 +#: pgc.l:1133 pgc.l:1147 #, c-format msgid "unmatched EXEC SQL ENDIF" msgstr "ì¼ì¹˜í•˜ì§€ 않는 EXEC SQL ENDIF" -#: pgc.l:1135 +#: pgc.l:1167 #, c-format msgid "too many nested EXEC SQL IFDEF conditions" msgstr "ì¤‘ì²©ëœ EXEC SQL IFDEF ì¡°ê±´ì´ ë„ˆë¬´ ë§ŽìŒ" -#: pgc.l:1168 +#: pgc.l:1200 #, c-format msgid "missing identifier in EXEC SQL IFDEF command" msgstr "EXEC SQL IFDEF ëª…ë ¹ì— ì‹ë³„ìž ëˆ„ë½" -#: pgc.l:1177 +#: pgc.l:1209 #, c-format msgid "missing identifier in EXEC SQL DEFINE command" msgstr "EXEC SQL DEFINE ëª…ë ¹ì— ì‹ë³„ìž ëˆ„ë½" -#: pgc.l:1210 +#: pgc.l:1242 #, c-format msgid "syntax error in EXEC SQL INCLUDE command" msgstr "EXEC SQL INCLUDE ëª…ë ¹ì— êµ¬ë¬¸ 오류 ë°œìƒ" -#: pgc.l:1259 +#: pgc.l:1291 #, c-format -msgid "" -"internal error: unreachable state; please report this to " -msgstr "" -"ë‚´ë¶€ 오류: ì—°ê²°í•  수 없습니다. ì´ ë¬¸ì œë¥¼ " +msgstr "ë‚´ë¶€ 오류: ì—°ê²°í•  수 없습니다. ì´ ë¬¸ì œë¥¼
\n", fout); free(fieldMax); free(fieldNotNum); free((void *) fieldNames); @@ -323,8 +325,6 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po) #endif /* ENABLE_THREAD_SAFETY */ #endif /* WIN32 */ } - if (po->html3 && !po->expanded) - fputs("\n", fout); } } diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c index 7dcef808dd7..0e36974fc4a 100644 --- a/src/interfaces/libpq/fe-protocol2.c +++ b/src/interfaces/libpq/fe-protocol2.c @@ -3,7 +3,7 @@ * fe-protocol2.c * functions that are specific to frontend/backend protocol version 2 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -966,6 +966,14 @@ pqGetErrorNotice2(PGconn *conn, bool isError) char *startp; char *splitp; + /* + * If this is an error message, pre-emptively clear any incomplete query + * result we may have. We'd just throw it away below anyway, and + * releasing it before collecting the error might avoid out-of-memory. + */ + if (isError) + pqClearAsyncResult(conn); + /* * Since the message might be pretty long, we create a temporary * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended @@ -1038,7 +1046,7 @@ pqGetErrorNotice2(PGconn *conn, bool isError) */ if (isError) { - pqClearAsyncResult(conn); + pqClearAsyncResult(conn); /* redundant, but be safe */ conn->result = res; resetPQExpBuffer(&conn->errorMessage); if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg) @@ -1442,42 +1450,30 @@ pqFunctionCall2(PGconn *conn, Oid fnid, pqPutInt(fnid, 4, conn) != 0 || /* function id */ pqPutInt(nargs, 4, conn) != 0) /* # of args */ { - pqHandleSendFailure(conn); + /* error message should be set up already */ return NULL; } for (i = 0; i < nargs; ++i) { /* len.int4 + contents */ if (pqPutInt(args[i].len, 4, conn)) - { - pqHandleSendFailure(conn); return NULL; - } if (args[i].isint) { if (pqPutInt(args[i].u.integer, 4, conn)) - { - pqHandleSendFailure(conn); return NULL; - } } else { if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn)) - { - pqHandleSendFailure(conn); return NULL; - } } } if (pqPutMsgEnd(conn) < 0 || pqFlush(conn)) - { - pqHandleSendFailure(conn); return NULL; - } for (;;) { diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c index d3ca5d25f6f..b04f7ec123b 100644 --- a/src/interfaces/libpq/fe-protocol3.c +++ b/src/interfaces/libpq/fe-protocol3.c @@ -3,7 +3,7 @@ * fe-protocol3.c * functions that are specific to frontend/backend protocol version 3 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -51,9 +51,9 @@ static int getNotify(PGconn *conn); static int getCopyStart(PGconn *conn, ExecStatusType copytype); static int getReadyForQuery(PGconn *conn); static void reportErrorPosition(PQExpBuffer msg, const char *query, - int loc, int encoding); -static int build_startup_packet(const PGconn *conn, char *packet, - const PQEnvironmentOption *options); + int loc, int encoding); +static int build_startup_packet(const PGconn *conn, char *packet, + const PQEnvironmentOption *options); /* @@ -317,8 +317,8 @@ pqParseInput3(PGconn *conn) * * If we're doing a Describe, we have to pass something * back to the client, so set up a COMMAND_OK result, - * instead of TUPLES_OK. Otherwise we can just ignore - * this message. + * instead of PGRES_TUPLES_OK. Otherwise we can just + * ignore this message. */ if (conn->queryclass == PGQUERY_DESCRIBE) { @@ -879,6 +879,14 @@ pqGetErrorNotice3(PGconn *conn, bool isError) PQExpBufferData workBuf; char id; + /* + * If this is an error message, pre-emptively clear any incomplete query + * result we may have. We'd just throw it away below anyway, and + * releasing it before collecting the error might avoid out-of-memory. + */ + if (isError) + pqClearAsyncResult(conn); + /* * Since the fields might be pretty long, we create a temporary * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended @@ -943,7 +951,7 @@ pqGetErrorNotice3(PGconn *conn, bool isError) { if (res) res->errMsg = pqResultStrdup(res, workBuf.data); - pqClearAsyncResult(conn); + pqClearAsyncResult(conn); /* redundant, but be safe */ conn->result = res; if (PQExpBufferDataBroken(workBuf)) printfPQExpBuffer(&conn->errorMessage, @@ -988,7 +996,7 @@ pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, /* If we couldn't allocate a PGresult, just say "out of memory" */ if (res == NULL) { - appendPQExpBuffer(msg, libpq_gettext("out of memory\n")); + appendPQExpBufferStr(msg, libpq_gettext("out of memory\n")); return; } @@ -1001,7 +1009,7 @@ pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, if (res->errMsg && res->errMsg[0]) appendPQExpBufferStr(msg, res->errMsg); else - appendPQExpBuffer(msg, libpq_gettext("no error message available\n")); + appendPQExpBufferStr(msg, libpq_gettext("no error message available\n")); return; } @@ -1009,6 +1017,24 @@ pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, val = PQresultErrorField(res, PG_DIAG_SEVERITY); if (val) appendPQExpBuffer(msg, "%s: ", val); + + if (verbosity == PQERRORS_SQLSTATE) + { + /* + * If we have a SQLSTATE, print that and nothing else. If not (which + * shouldn't happen for server-generated errors, but might possibly + * happen for libpq-generated ones), fall back to TERSE format, as + * that seems better than printing nothing at all. + */ + val = PQresultErrorField(res, PG_DIAG_SQLSTATE); + if (val) + { + appendPQExpBuffer(msg, "%s\n", val); + return; + } + verbosity = PQERRORS_TERSE; + } + if (verbosity == PQERRORS_VERBOSE) { val = PQresultErrorField(res, PG_DIAG_SQLSTATE); @@ -1918,50 +1944,35 @@ pqFunctionCall3(PGconn *conn, Oid fnid, pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */ pqPutInt(nargs, 2, conn) < 0) /* # of args */ { - pqHandleSendFailure(conn); + /* error message should be set up already */ return NULL; } for (i = 0; i < nargs; ++i) { /* len.int4 + contents */ if (pqPutInt(args[i].len, 4, conn)) - { - pqHandleSendFailure(conn); return NULL; - } if (args[i].len == -1) continue; /* it's NULL */ if (args[i].isint) { if (pqPutInt(args[i].u.integer, args[i].len, conn)) - { - pqHandleSendFailure(conn); return NULL; - } } else { if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn)) - { - pqHandleSendFailure(conn); return NULL; - } } } if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */ - { - pqHandleSendFailure(conn); return NULL; - } if (pqPutMsgEnd(conn) < 0 || pqFlush(conn)) - { - pqHandleSendFailure(conn); return NULL; - } for (;;) { diff --git a/src/interfaces/libpq/fe-secure-common.c b/src/interfaces/libpq/fe-secure-common.c index 40203f3b642..2e83a79e1bd 100644 --- a/src/interfaces/libpq/fe-secure-common.c +++ b/src/interfaces/libpq/fe-secure-common.c @@ -8,7 +8,7 @@ * file contains support routines that are used by the library-specific * implementations such as fe-secure-openssl.c. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -88,10 +88,17 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn, { char *name; int result; - char *host = PQhost(conn); + char *host = conn->connhost[conn->whichhost].host; *store_name = NULL; + if (!(host && host[0] != '\0')) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("host name must be specified\n")); + return -1; + } + /* * There is no guarantee the string returned from the certificate is * NULL-terminated, so make a copy that is. @@ -145,7 +152,7 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn, bool pq_verify_peer_name_matches_certificate(PGconn *conn) { - char *host = PQhost(conn); + char *host = conn->connhost[conn->whichhost].host; int rc; int names_examined = 0; char *first_name = NULL; diff --git a/src/interfaces/libpq/fe-secure-common.h b/src/interfaces/libpq/fe-secure-common.h index 980a58af255..87020a00faa 100644 --- a/src/interfaces/libpq/fe-secure-common.h +++ b/src/interfaces/libpq/fe-secure-common.h @@ -4,7 +4,7 @@ * * common implementation-independent SSL support code * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -18,9 +18,9 @@ #include "libpq-fe.h" -extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn, - const char *namedata, size_t namelen, - char **store_name); +extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn, + const char *namedata, size_t namelen, + char **store_name); extern bool pq_verify_peer_name_matches_certificate(PGconn *conn); #endif /* FE_SECURE_COMMON_H */ diff --git a/src/interfaces/libpq/fe-secure-gssapi.c b/src/interfaces/libpq/fe-secure-gssapi.c new file mode 100644 index 00000000000..095750db1fa --- /dev/null +++ b/src/interfaces/libpq/fe-secure-gssapi.c @@ -0,0 +1,623 @@ +/*------------------------------------------------------------------------- + * + * fe-secure-gssapi.c + * The front-end (client) encryption support for GSSAPI + * + * Portions Copyright (c) 2016-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/interfaces/libpq/fe-secure-gssapi.c + * + *------------------------------------------------------------------------- + */ + +#include "postgres_fe.h" + +#include "libpq-fe.h" +#include "libpq-int.h" +#include "fe-gssapi-common.h" +#include "port/pg_bswap.h" + +/* + * Require encryption support, as well as mutual authentication and + * tamperproofing measures. + */ +#define GSS_REQUIRED_FLAGS GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | \ + GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG + +/* + * We use fixed-size buffers for handling the encryption/decryption + * which are larger than PQComm's buffer will typically be to minimize + * the times where we have to make multiple packets and therefore sets + * of recv/send calls for a single read/write call to us. + * + * NOTE: The client and server have to agree on the max packet size, + * because we have to pass an entire packet to GSSAPI at a time and we + * don't want the other side to send arbitrairly huge packets as we + * would have to allocate memory for them to then pass them to GSSAPI. + */ +#define PQ_GSS_SEND_BUFFER_SIZE 16384 +#define PQ_GSS_RECV_BUFFER_SIZE 16384 + +/* PqGSSSendBuffer is for *encrypted* data */ +static char PqGSSSendBuffer[PQ_GSS_SEND_BUFFER_SIZE]; +static int PqGSSSendPointer; /* Next index to store a byte in + * PqGSSSendBuffer */ +static int PqGSSSendStart; /* Next index to send a byte in + * PqGSSSendBuffer */ + +/* PqGSSRecvBuffer is for *encrypted* data */ +static char PqGSSRecvBuffer[PQ_GSS_RECV_BUFFER_SIZE]; +static int PqGSSRecvPointer; /* Next index to read a byte from + * PqGSSRecvBuffer */ +static int PqGSSRecvLength; /* End of data available in PqGSSRecvBuffer */ + +/* PqGSSResultBuffer is for *unencrypted* data */ +static char PqGSSResultBuffer[PQ_GSS_RECV_BUFFER_SIZE]; +static int PqGSSResultPointer; /* Next index to read a byte from + * PqGSSResultBuffer */ +static int PqGSSResultLength; /* End of data available in PqGSSResultBuffer */ + +uint32 max_packet_size; /* Maximum size we can encrypt and fit the + * results into our output buffer */ + +/* + * Write len bytes of data from ptr along a GSSAPI-encrypted connection. Note + * that the connection must be already set up for GSSAPI encryption (i.e., + * GSSAPI transport negotiation is complete). Returns len when all data has + * been written; retry when errno is EWOULDBLOCK or similar with the same + * values of ptr and len. On non-socket failures, will log an error message. + */ +ssize_t +pg_GSS_write(PGconn *conn, const void *ptr, size_t len) +{ + gss_buffer_desc input, + output = GSS_C_EMPTY_BUFFER; + OM_uint32 major, + minor; + ssize_t ret = -1; + size_t bytes_to_encrypt = len; + size_t bytes_encrypted = 0; + + /* + * Loop through encrypting data and sending it out until + * pqsecure_raw_write() complains (which would likely mean that the socket + * is non-blocking and the requested send() would block, or there was some + * kind of actual error) and then return. + */ + while (bytes_to_encrypt || PqGSSSendPointer) + { + int conf_state = 0; + uint32 netlen; + + /* + * Check if we have data in the encrypted output buffer that needs to + * be sent, and if so, try to send it. If we aren't able to, return + * that back up to the caller. + */ + if (PqGSSSendPointer) + { + ssize_t ret; + ssize_t amount = PqGSSSendPointer - PqGSSSendStart; + + ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendStart, amount); + if (ret < 0) + { + /* + * If we encrypted some data and it's in our output buffer, + * but send() is saying that we would block, then tell the + * client how far we got with encrypting the data so that they + * can call us again with whatever is left, at which point we + * will try to send the remaining encrypted data first and + * then move on to encrypting the rest of the data. + */ + if (bytes_encrypted != 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) + return bytes_encrypted; + else + return ret; + } + + /* + * Partial write, move forward that far in our buffer and try + * again + */ + if (ret != amount) + { + PqGSSSendStart += ret; + continue; + } + + /* All encrypted data was sent, our buffer is empty now. */ + PqGSSSendPointer = PqGSSSendStart = 0; + } + + /* + * Check if there are any bytes left to encrypt. If not, we're done. + */ + if (!bytes_to_encrypt) + return bytes_encrypted; + + /* + * Check how much we are being asked to send, if it's too much, then + * we will have to loop and possibly be called multiple times to get + * through all the data. + */ + if (bytes_to_encrypt > max_packet_size) + input.length = max_packet_size; + else + input.length = bytes_to_encrypt; + + input.value = (char *) ptr + bytes_encrypted; + + output.value = NULL; + output.length = 0; + + /* Create the next encrypted packet */ + major = gss_wrap(&minor, conn->gctx, 1, GSS_C_QOP_DEFAULT, + &input, &conf_state, &output); + if (major != GSS_S_COMPLETE) + { + pg_GSS_error(libpq_gettext("GSSAPI wrap error"), conn, major, minor); + goto cleanup; + } + else if (conf_state == 0) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("outgoing GSSAPI message would not use confidentiality\n")); + goto cleanup; + } + + if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("client tried to send oversize GSSAPI packet (%zu > %zu)\n"), + (size_t) output.length, + PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)); + goto cleanup; + } + + bytes_encrypted += input.length; + bytes_to_encrypt -= input.length; + + /* 4 network-order bytes of length, then payload */ + netlen = htonl(output.length); + memcpy(PqGSSSendBuffer + PqGSSSendPointer, &netlen, sizeof(uint32)); + PqGSSSendPointer += sizeof(uint32); + + memcpy(PqGSSSendBuffer + PqGSSSendPointer, output.value, output.length); + PqGSSSendPointer += output.length; + } + + ret = bytes_encrypted; + +cleanup: + if (output.value != NULL) + gss_release_buffer(&minor, &output); + return ret; +} + +/* + * Read up to len bytes of data into ptr from a GSSAPI-encrypted connection. + * Note that GSSAPI transport must already have been negotiated. Returns the + * number of bytes read into ptr; otherwise, returns -1. Retry with the same + * ptr and len when errno is EWOULDBLOCK or similar. + */ +ssize_t +pg_GSS_read(PGconn *conn, void *ptr, size_t len) +{ + OM_uint32 major, + minor; + gss_buffer_desc input = GSS_C_EMPTY_BUFFER, + output = GSS_C_EMPTY_BUFFER; + ssize_t ret = 0; + size_t bytes_to_return = len; + size_t bytes_returned = 0; + + /* + * The goal here is to read an incoming encrypted packet, one at a time, + * decrypt it into our out buffer, returning to the caller what they asked + * for, and then saving anything else for the next call. + * + * We get a read request, we look if we have cleartext bytes available + * and, if so, copy those to the result, and then we try to decrypt the + * next packet. + * + * We should not try to decrypt the next packet until the read buffer is + * completely empty. + * + * If the caller asks for more bytes than one decrypted packet, then we + * should try to return all bytes asked for. + */ + while (bytes_to_return) + { + int conf_state = 0; + + /* Check if we have data in our buffer that we can return immediately */ + if (PqGSSResultPointer < PqGSSResultLength) + { + int bytes_in_buffer = PqGSSResultLength - PqGSSResultPointer; + int bytes_to_copy = bytes_in_buffer < len - bytes_returned ? bytes_in_buffer : len - bytes_returned; + + /* + * Copy the data from our output buffer into the caller's buffer, + * at the point where we last left off filling their buffer + */ + memcpy((char *) ptr + bytes_returned, PqGSSResultBuffer + PqGSSResultPointer, bytes_to_copy); + PqGSSResultPointer += bytes_to_copy; + bytes_to_return -= bytes_to_copy; + bytes_returned += bytes_to_copy; + + /* Check if our result buffer is now empty and, if so, reset */ + if (PqGSSResultPointer == PqGSSResultLength) + PqGSSResultPointer = PqGSSResultLength = 0; + + continue; + } + + /* + * At this point, our output buffer should be empty with more bytes + * being requested to be read. We are now ready to load the next + * packet and decrypt it (entirely) into our buffer. + * + * If we get a partial read back while trying to read a packet off the + * wire then we return back what bytes we were able to return and wait + * to be called again, until we get a full packet to decrypt. + */ + + /* Check if we got a partial read just trying to get the length */ + if (PqGSSRecvLength < sizeof(uint32)) + { + /* Try to get whatever of the length we still need */ + ret = pqsecure_raw_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, + sizeof(uint32) - PqGSSRecvLength); + if (ret < 0) + return bytes_returned ? bytes_returned : ret; + + PqGSSRecvLength += ret; + if (PqGSSRecvLength < sizeof(uint32)) + return bytes_returned; + } + + /* + * We should have the whole length at this point, so pull it out and + * then read whatever we have left of the packet + */ + input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + + /* Check for over-length packet */ + if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("oversize GSSAPI packet sent by the server (%zu > %zu)\n"), + (size_t) input.length, + PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)); + ret = -1; + goto cleanup; + } + + /* + * Read as much of the packet as we are able to on this call into + * wherever we left off from the last time we were called. + */ + ret = pqsecure_raw_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, + input.length - (PqGSSRecvLength - sizeof(uint32))); + if (ret < 0) + return bytes_returned ? bytes_returned : ret; + + /* + * If we got less than the rest of the packet then we need to return + * and be called again. + */ + PqGSSRecvLength += ret; + if (PqGSSRecvLength - sizeof(uint32) < input.length) + return bytes_returned ? bytes_returned : -1; + + /* + * We now have the full packet and we can perform the decryption and + * refill our output buffer, then loop back up to pass that back to + * the user. + */ + output.value = NULL; + output.length = 0; + input.value = PqGSSRecvBuffer + sizeof(uint32); + + major = gss_unwrap(&minor, conn->gctx, &input, &output, &conf_state, NULL); + if (major != GSS_S_COMPLETE) + { + pg_GSS_error(libpq_gettext("GSSAPI unwrap error"), conn, + major, minor); + ret = -1; + goto cleanup; + } + else if (conf_state == 0) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("incoming GSSAPI message did not use confidentiality\n")); + ret = -1; + goto cleanup; + } + + memcpy(PqGSSResultBuffer, output.value, output.length); + PqGSSResultLength = output.length; + + /* Our buffer is now empty, reset it */ + PqGSSRecvPointer = PqGSSRecvLength = 0; + + gss_release_buffer(&minor, &output); + } + + ret = bytes_returned; + +cleanup: + if (output.value != NULL) + gss_release_buffer(&minor, &output); + return ret; +} + +/* + * Simple wrapper for reading from pqsecure_raw_read. + * + * This takes the same arguments as pqsecure_raw_read, plus an output parameter + * to return the number of bytes read. This handles if blocking would occur and + * if we detect EOF on the connection. + */ +static PostgresPollingStatusType +gss_read(PGconn *conn, void *recv_buffer, size_t length, ssize_t *ret) +{ + *ret = pqsecure_raw_read(conn, recv_buffer, length); + if (*ret < 0 && errno == EWOULDBLOCK) + return PGRES_POLLING_READING; + else if (*ret < 0) + return PGRES_POLLING_FAILED; + + /* Check for EOF */ + if (*ret == 0) + { + int result = pqReadReady(conn); + + if (result < 0) + return PGRES_POLLING_FAILED; + + if (!result) + return PGRES_POLLING_READING; + + *ret = pqsecure_raw_read(conn, recv_buffer, length); + if (*ret == 0) + return PGRES_POLLING_FAILED; + } + + return PGRES_POLLING_OK; +} + +/* + * Negotiate GSSAPI transport for a connection. When complete, returns + * PGRES_POLLING_OK. Will return PGRES_POLLING_READING or + * PGRES_POLLING_WRITING as appropriate whenever it would block, and + * PGRES_POLLING_FAILED if transport could not be negotiated. + */ +PostgresPollingStatusType +pqsecure_open_gss(PGconn *conn) +{ + static int first = 1; + ssize_t ret; + OM_uint32 major, + minor; + uint32 netlen; + PostgresPollingStatusType result; + gss_buffer_desc input = GSS_C_EMPTY_BUFFER, + output = GSS_C_EMPTY_BUFFER; + + /* Check for data that needs to be written */ + if (first) + { + PqGSSSendPointer = PqGSSSendStart = PqGSSRecvPointer = PqGSSRecvLength = PqGSSResultPointer = PqGSSResultLength = 0; + first = 0; + } + + /* + * Check if we have anything to send from a prior call and if so, send it. + */ + if (PqGSSSendPointer) + { + ssize_t amount = PqGSSSendPointer - PqGSSSendStart; + + ret = pqsecure_raw_write(conn, PqGSSSendBuffer + PqGSSSendStart, amount); + if (ret < 0 && errno == EWOULDBLOCK) + return PGRES_POLLING_WRITING; + + if (ret != amount) + { + PqGSSSendStart += amount; + return PGRES_POLLING_WRITING; + } + + PqGSSSendPointer = PqGSSSendStart = 0; + } + + /* + * Client sends first, and sending creates a context, therefore this will + * be false the first time through, and then when we get called again we + * will check for incoming data. + */ + if (conn->gctx) + { + /* Process any incoming data we might have */ + + /* See if we are still trying to get the length */ + if (PqGSSRecvLength < sizeof(uint32)) + { + /* Attempt to get the length first */ + result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, sizeof(uint32) - PqGSSRecvLength, &ret); + if (result != PGRES_POLLING_OK) + return result; + + PqGSSRecvLength += ret; + + if (PqGSSRecvLength < sizeof(uint32)) + return PGRES_POLLING_READING; + } + + /* + * Check if we got an error packet + * + * This is safe to do because we shouldn't ever get a packet over 8192 + * and therefore the actual length bytes, being that they are in + * network byte order, for any real packet will start with two zero + * bytes. + */ + if (PqGSSRecvBuffer[0] == 'E') + { + /* + * For an error packet during startup, we don't get a length, so + * simply read as much as we can fit into our buffer (as a string, + * so leave a spot at the end for a NULL byte too) and report that + * back to the caller. + */ + result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, PQ_GSS_RECV_BUFFER_SIZE - PqGSSRecvLength - 1, &ret); + if (result != PGRES_POLLING_OK) + return result; + + PqGSSRecvLength += ret; + + printfPQExpBuffer(&conn->errorMessage, "%s\n", PqGSSRecvBuffer + 1); + + return PGRES_POLLING_FAILED; + } + + /* + * We should have the whole length at this point, so pull it out and + * then read whatever we have left of the packet + */ + + /* Get the length and check for over-length packet */ + input.length = ntohl(*(uint32 *) PqGSSRecvBuffer); + if (input.length > PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("oversize GSSAPI packet sent by the server (%zu > %zu)\n"), + (size_t) input.length, + PQ_GSS_RECV_BUFFER_SIZE - sizeof(uint32)); + return PGRES_POLLING_FAILED; + } + + /* + * Read as much of the packet as we are able to on this call into + * wherever we left off from the last time we were called. + */ + result = gss_read(conn, PqGSSRecvBuffer + PqGSSRecvLength, + input.length - (PqGSSRecvLength - sizeof(uint32)), &ret); + if (result != PGRES_POLLING_OK) + return result; + + PqGSSRecvLength += ret; + + /* + * If we got less than the rest of the packet then we need to return + * and be called again. + */ + if (PqGSSRecvLength - sizeof(uint32) < input.length) + return PGRES_POLLING_READING; + + input.value = PqGSSRecvBuffer + sizeof(uint32); + } + + /* Load the service name (no-op if already done */ + ret = pg_GSS_load_servicename(conn); + if (ret != STATUS_OK) + return PGRES_POLLING_FAILED; + + /* + * Call GSS init context, either with an empty input, or with a complete + * packet from the server. + */ + major = gss_init_sec_context(&minor, conn->gcred, &conn->gctx, + conn->gtarg_nam, GSS_C_NO_OID, + GSS_REQUIRED_FLAGS, 0, 0, &input, NULL, + &output, NULL, NULL); + + /* GSS Init Sec Context uses the whole packet, so clear it */ + PqGSSRecvPointer = PqGSSRecvLength = 0; + + if (GSS_ERROR(major)) + { + pg_GSS_error(libpq_gettext("could not initiate GSSAPI security context"), + conn, major, minor); + return PGRES_POLLING_FAILED; + } + else if (output.length == 0) + { + /* + * We're done - hooray! Kind of gross, but we need to disable SSL + * here so that we don't accidentally tunnel one over the other. + */ +#ifdef USE_SSL + conn->allow_ssl_try = false; +#endif + gss_release_cred(&minor, &conn->gcred); + conn->gcred = GSS_C_NO_CREDENTIAL; + conn->gssenc = true; + + /* + * Determine the max packet size which will fit in our buffer, after + * accounting for the length + */ + major = gss_wrap_size_limit(&minor, conn->gctx, 1, GSS_C_QOP_DEFAULT, + PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32), &max_packet_size); + + if (GSS_ERROR(major)) + pg_GSS_error(libpq_gettext("GSSAPI size check error"), conn, + major, minor); + + return PGRES_POLLING_OK; + } + + /* Must have output.length > 0 */ + if (output.length > PQ_GSS_SEND_BUFFER_SIZE - sizeof(uint32)) + { + pg_GSS_error(libpq_gettext("GSSAPI context establishment error"), + conn, major, minor); + return PGRES_POLLING_FAILED; + } + + /* Queue the token for writing */ + netlen = htonl(output.length); + + memcpy(PqGSSSendBuffer, (char *) &netlen, sizeof(uint32)); + PqGSSSendPointer += sizeof(uint32); + + memcpy(PqGSSSendBuffer + PqGSSSendPointer, output.value, output.length); + PqGSSSendPointer += output.length; + + gss_release_buffer(&minor, &output); + + /* Asked to be called again to write data */ + return PGRES_POLLING_WRITING; +} + +/* + * GSSAPI Information functions. + */ + +/* + * Return the GSSAPI Context itself. + */ +void * +PQgetgssctx(PGconn *conn) +{ + if (!conn) + return NULL; + + return conn->gctx; +} + +/* + * Return true if GSSAPI encryption is in use. + */ +int +PQgssEncInUse(PGconn *conn) +{ + if (!conn || !conn->gctx) + return 0; + + return conn->gssenc; +} diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 2e2f1074fcb..c8dddfb5fdb 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -4,7 +4,7 @@ * OpenSSL support * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -62,9 +62,9 @@ #include static int verify_cb(int ok, X509_STORE_CTX *ctx); -static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, - ASN1_STRING *name, - char **store_name); +static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, + ASN1_STRING *name, + char **store_name); static void destroy_ssl_system(void); static int initialize_SSL(PGconn *conn); static PostgresPollingStatusType open_client_SSL(PGconn *); @@ -142,7 +142,7 @@ pgtls_read(PGconn *conn, void *ptr, size_t len) { ssize_t n; int result_errno = 0; - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; int err; unsigned long ecode; @@ -264,7 +264,7 @@ pgtls_read(PGconn *conn, void *ptr, size_t len) bool pgtls_read_pending(PGconn *conn) { - return SSL_pending(conn->ssl); + return SSL_pending(conn->ssl) > 0; } ssize_t @@ -272,7 +272,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len) { ssize_t n; int result_errno = 0; - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; int err; unsigned long ecode; @@ -369,30 +369,10 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len) return n; } -char * -pgtls_get_finished(PGconn *conn, size_t *len) -{ - char dummy[1]; - char *result; - - /* - * OpenSSL does not offer an API to get directly the length of the TLS - * Finished message sent, so first do a dummy call to grab this - * information and then do an allocation with the correct size. - */ - *len = SSL_get_finished(conn->ssl, dummy, sizeof(dummy)); - result = malloc(*len); - if (result == NULL) - return NULL; - (void) SSL_get_finished(conn->ssl, result, *len); - - return result; -} - +#ifdef HAVE_X509_GET_SIGNATURE_NID char * pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len) { -#ifdef HAVE_X509_GET_SIGNATURE_NID X509 *peer_cert; const EVP_MD *algo_type; unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */ @@ -462,12 +442,8 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len) *len = hash_size; return cert_hash; -#else - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("channel binding type \"tls-server-end-point\" is not supported by this build\n")); - return NULL; -#endif } +#endif /* HAVE_X509_GET_SIGNATURE_NID */ /* ------------------------------------------------------------ */ /* OpenSSL specific code */ @@ -560,8 +536,8 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, (*names_examined)++; rc = openssl_verify_peer_name_matches_certificate_name(conn, - name->d.dNSName, - &alt_name); + name->d.dNSName, + &alt_name); if (alt_name) { @@ -599,10 +575,10 @@ pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, { (*names_examined)++; rc = openssl_verify_peer_name_matches_certificate_name( - conn, - X509_NAME_ENTRY_get_data( - X509_NAME_get_entry(subject_name, cn_index)), - first_name); + conn, + X509_NAME_ENTRY_get_data( + X509_NAME_get_entry(subject_name, cn_index)), + first_name); } } } @@ -760,7 +736,7 @@ static void destroy_ssl_system(void) { #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) - /* Mutex is created in initialize_ssl_system() */ + /* Mutex is created in pgtls_init() */ if (pthread_mutex_lock(&ssl_config_mutex)) return; @@ -804,7 +780,7 @@ initialize_SSL(PGconn *conn) struct stat buf; char homedir[MAXPGPATH]; char fnbuf[MAXPGPATH]; - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; bool have_homedir; bool have_cert; bool have_rootcert; @@ -893,20 +869,8 @@ initialize_SSL(PGconn *conn) if (fnbuf[0] != '\0' && X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1) { - /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */ -#ifdef X509_V_FLAG_CRL_CHECK X509_STORE_set_flags(cvstore, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); -#else - char *err = SSLerrmessage(ERR_get_error()); - - printfPQExpBuffer(&conn->errorMessage, - libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"), - fnbuf); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; -#endif } /* if not found, silently ignore; we do not require CRL */ ERR_clear_error(); @@ -965,7 +929,7 @@ initialize_SSL(PGconn *conn) { printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not open certificate file \"%s\": %s\n"), - fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf))); + fnbuf, strerror_r(errno, sebuf, sizeof(sebuf))); SSL_CTX_free(SSL_context); return -1; } @@ -1194,6 +1158,7 @@ initialize_SSL(PGconn *conn) #ifdef SSL_OP_NO_COMPRESSION if (conn->sslcompression && conn->sslcompression[0] == '0') SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION); + /* * Mainline OpenSSL introduced SSL_clear_options() before * SSL_OP_NO_COMPRESSION, so this following #ifdef should not be @@ -1235,7 +1200,7 @@ open_client_SSL(PGconn *conn) case SSL_ERROR_SYSCALL: { - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; if (r == -1) printfPQExpBuffer(&conn->errorMessage, @@ -1587,7 +1552,7 @@ my_BIO_s_socket(void) return my_bio_methods; } -/* This should exactly match openssl's SSL_set_fd except for using my BIO */ +/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */ static int my_SSL_set_fd(PGconn *conn, int fd) { diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c index cfb77f6d85f..b8191b4c8f8 100644 --- a/src/interfaces/libpq/fe-secure.c +++ b/src/interfaces/libpq/fe-secure.c @@ -6,7 +6,7 @@ * message integrity and endpoint authentication. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -220,6 +220,13 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len) n = pgtls_read(conn, ptr, len); } else +#endif +#ifdef ENABLE_GSS + if (conn->gssenc) + { + n = pg_GSS_read(conn, ptr, len); + } + else #endif { n = pqsecure_raw_read(conn, ptr, len); @@ -233,7 +240,7 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) { ssize_t n; int result_errno = 0; - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; n = recv(conn->sock, ptr, len, 0); @@ -297,6 +304,13 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len) n = pgtls_write(conn, ptr, len); } else +#endif +#ifdef ENABLE_GSS + if (conn->gssenc) + { + n = pg_GSS_write(conn, ptr, len); + } + else #endif { n = pqsecure_raw_write(conn, ptr, len); @@ -311,7 +325,7 @@ pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len) ssize_t n; int flags = 0; int result_errno = 0; - char sebuf[256]; + char sebuf[PG_STRERROR_R_BUFLEN]; DECLARE_SIGPIPE_INFO(spinfo); @@ -360,9 +374,10 @@ pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len) case EPIPE: /* Set flag for EPIPE */ REMEMBER_EPIPE(spinfo, true); - /* FALL THRU */ #ifdef ECONNRESET + /* FALL THRU */ + case ECONNRESET: #endif printfPQExpBuffer(&conn->errorMessage, @@ -419,6 +434,23 @@ PQsslAttributeNames(PGconn *conn) } #endif /* USE_SSL */ +/* Dummy version of GSSAPI information functions, when built without GSS support */ +#ifndef ENABLE_GSS + +void * +PQgetgssctx(PGconn *conn) +{ + return NULL; +} + +int +PQgssEncInUse(PGconn *conn) +{ + return 0; +} + +#endif /* ENABLE_GSS */ + #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) diff --git a/src/interfaces/libpq/libpq-events.c b/src/interfaces/libpq/libpq-events.c index 09f9c7f9bb8..3a17af10e54 100644 --- a/src/interfaces/libpq/libpq-events.c +++ b/src/interfaces/libpq/libpq-events.c @@ -3,7 +3,7 @@ * libpq-events.c * functions for supporting the libpq "events" API * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/interfaces/libpq/libpq-events.h b/src/interfaces/libpq/libpq-events.h index 7d0726a8399..449aea54c77 100644 --- a/src/interfaces/libpq/libpq-events.h +++ b/src/interfaces/libpq/libpq-events.h @@ -5,7 +5,7 @@ * that invoke the libpq "events" API, but are not interesting to * ordinary users of libpq. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/libpq/libpq-events.h @@ -69,8 +69,8 @@ typedef struct typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); /* Registers an event proc with the given PGconn. */ -extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, - const char *name, void *passThrough); +extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, + const char *name, void *passThrough); /* Sets the PGconn instance data for the provided proc to data. */ extern int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index ed9c8068614..5f65db30e4f 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -4,7 +4,7 @@ * This file contains definitions for structures and * externs for functions used by frontend postgres applications. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/libpq/libpq-fe.h @@ -65,8 +65,10 @@ typedef enum CONNECTION_NEEDED, /* Internal state: connect() needed */ CONNECTION_CHECK_WRITABLE, /* Check if we could make a writable * connection. */ - CONNECTION_CONSUME /* Wait for any pending message and consume + CONNECTION_CONSUME, /* Wait for any pending message and consume * them. */ + CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */ + CONNECTION_CHECK_TARGET /* Check if we have a proper target connection */ } ConnStatusType; typedef enum @@ -111,7 +113,8 @@ typedef enum { PQERRORS_TERSE, /* single-line error messages */ PQERRORS_DEFAULT, /* recommended style */ - PQERRORS_VERBOSE /* all the facts, ma'am */ + PQERRORS_VERBOSE, /* all the facts, ma'am */ + PQERRORS_SQLSTATE /* only error severity and SQLSTATE code */ } PGVerbosity; typedef enum @@ -254,17 +257,17 @@ typedef struct pgresAttDesc /* Asynchronous (non-blocking) */ extern PGconn *PQconnectStart(const char *conninfo); extern PGconn *PQconnectStartParams(const char *const *keywords, - const char *const *values, int expand_dbname); + const char *const *values, int expand_dbname); extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); /* Synchronous (blocking) */ extern PGconn *PQconnectdb(const char *conninfo); extern PGconn *PQconnectdbParams(const char *const *keywords, - const char *const *values, int expand_dbname); + const char *const *values, int expand_dbname); extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, - const char *pgoptions, const char *pgtty, - const char *dbName, - const char *login, const char *pwd); + const char *pgoptions, const char *pgtty, + const char *dbName, + const char *login, const char *pwd); #define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) @@ -285,7 +288,7 @@ extern PQconninfoOption *PQconninfo(PGconn *conn); extern void PQconninfoFree(PQconninfoOption *connOptions); /* - * close the current connection and restablish a new one with the same + * close the current connection and reestablish a new one with the same * parameters */ /* Asynchronous (non-blocking) */ @@ -312,13 +315,14 @@ extern char *PQdb(const PGconn *conn); extern char *PQuser(const PGconn *conn); extern char *PQpass(const PGconn *conn); extern char *PQhost(const PGconn *conn); +extern char *PQhostaddr(const PGconn *conn); extern char *PQport(const PGconn *conn); extern char *PQtty(const PGconn *conn); extern char *PQoptions(const PGconn *conn); extern ConnStatusType PQstatus(const PGconn *conn); extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); extern const char *PQparameterStatus(const PGconn *conn, - const char *paramName); + const char *paramName); extern int PQprotocolVersion(const PGconn *conn); extern int PQserverVersion(const PGconn *conn); extern char *PQerrorMessage(const PGconn *conn); @@ -345,12 +349,18 @@ extern void PQinitSSL(int do_init); /* More detailed way to tell libpq whether it needs to initialize OpenSSL */ extern void PQinitOpenSSL(int do_ssl, int do_crypto); +/* Return true if GSSAPI encryption is in use */ +extern int PQgssEncInUse(PGconn *conn); + +/* Returns GSSAPI context if GSSAPI is in use */ +extern void *PQgetgssctx(PGconn *conn); + /* Set verbosity for PQerrorMessage and PQresultErrorMessage */ extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); /* Set CONTEXT visibility for PQerrorMessage and PQresultErrorMessage */ extern PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, - PGContextVisibility show_context); + PGContextVisibility show_context); /* Enable/disable tracing */ extern void PQtrace(PGconn *conn, FILE *debug_port); @@ -358,11 +368,11 @@ extern void PQuntrace(PGconn *conn); /* Override default notice handling routines */ extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, - PQnoticeReceiver proc, - void *arg); + PQnoticeReceiver proc, + void *arg); extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, - PQnoticeProcessor proc, - void *arg); + PQnoticeProcessor proc, + void *arg); /* * Used to set callback that prevents concurrent access to @@ -380,44 +390,44 @@ extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); /* Simple synchronous query */ extern PGresult *PQexec(PGconn *conn, const char *query); extern PGresult *PQexecParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); + const char *command, + int nParams, + const Oid *paramTypes, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); extern PGresult *PQprepare(PGconn *conn, const char *stmtName, - const char *query, int nParams, - const Oid *paramTypes); + const char *query, int nParams, + const Oid *paramTypes); extern PGresult *PQexecPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); + const char *stmtName, + int nParams, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); /* Interface for multiple-result or asynchronous queries */ extern int PQsendQuery(PGconn *conn, const char *query); -extern int PQsendQueryParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); -extern int PQsendPrepare(PGconn *conn, const char *stmtName, - const char *query, int nParams, - const Oid *paramTypes); -extern int PQsendQueryPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); +extern int PQsendQueryParams(PGconn *conn, + const char *command, + int nParams, + const Oid *paramTypes, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); +extern int PQsendPrepare(PGconn *conn, const char *stmtName, + const char *query, int nParams, + const Oid *paramTypes); +extern int PQsendQueryPrepared(PGconn *conn, + const char *stmtName, + int nParams, + const char *const *paramValues, + const int *paramLengths, + const int *paramFormats, + int resultFormat); extern int PQsetSingleRowMode(PGconn *conn); extern PGresult *PQgetResult(PGconn *conn); @@ -446,7 +456,7 @@ extern int PQisnonblocking(const PGconn *conn); extern int PQisthreadsafe(void); extern PGPing PQping(const char *conninfo); extern PGPing PQpingParams(const char *const *keywords, - const char *const *values, int expand_dbname); + const char *const *values, int expand_dbname); /* Force the write buffer to be written (or at least try) */ extern int PQflush(PGconn *conn); @@ -456,20 +466,20 @@ extern int PQflush(PGconn *conn); * use */ extern PGresult *PQfn(PGconn *conn, - int fnid, - int *result_buf, - int *result_len, - int result_is_int, - const PQArgBlock *args, - int nargs); + int fnid, + int *result_buf, + int *result_len, + int result_is_int, + const PQArgBlock *args, + int nargs); /* Accessor functions for PGresult objects */ extern ExecStatusType PQresultStatus(const PGresult *res); extern char *PQresStatus(ExecStatusType status); extern char *PQresultErrorMessage(const PGresult *res); extern char *PQresultVerboseErrorMessage(const PGresult *res, - PGVerbosity verbosity, - PGContextVisibility show_context); + PGVerbosity verbosity, + PGContextVisibility show_context); extern char *PQresultErrorField(const PGresult *res, int fieldcode); extern int PQntuples(const PGresult *res); extern int PQnfields(const PGresult *res); @@ -516,48 +526,50 @@ extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); extern PGresult *PQcopyResult(const PGresult *src, int flags); extern int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); extern void *PQresultAlloc(PGresult *res, size_t nBytes); +extern size_t PQresultMemorySize(const PGresult *res); extern int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); /* Quoting strings before inclusion in queries. */ extern size_t PQescapeStringConn(PGconn *conn, - char *to, const char *from, size_t length, - int *error); + char *to, const char *from, size_t length, + int *error); extern char *PQescapeLiteral(PGconn *conn, const char *str, size_t len); extern char *PQescapeIdentifier(PGconn *conn, const char *str, size_t len); extern unsigned char *PQescapeByteaConn(PGconn *conn, - const unsigned char *from, size_t from_length, - size_t *to_length); + const unsigned char *from, size_t from_length, + size_t *to_length); extern unsigned char *PQunescapeBytea(const unsigned char *strtext, - size_t *retbuflen); + size_t *retbuflen); /* These forms are deprecated! */ extern size_t PQescapeString(char *to, const char *from, size_t length); extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, - size_t *to_length); + size_t *to_length); /* === in fe-print.c === */ -extern void PQprint(FILE *fout, /* output stream */ - const PGresult *res, - const PQprintOpt *ps); /* option structure */ +extern void PQprint(FILE *fout, /* output stream */ + const PGresult *res, + const PQprintOpt *ps); /* option structure */ /* * really old printing routines */ extern void PQdisplayTuples(const PGresult *res, - FILE *fp, /* where to send the output */ - int fillAlign, /* pad the fields with spaces */ - const char *fieldSep, /* field separator */ - int printHeader, /* display headers? */ - int quiet); + FILE *fp, /* where to send the output */ + int fillAlign, /* pad the fields with spaces */ + const char *fieldSep, /* field separator */ + int printHeader, /* display headers? */ + int quiet); extern void PQprintTuples(const PGresult *res, - FILE *fout, /* output stream */ - int printAttName, /* print attribute names */ - int terseOutput, /* delimiter bars */ - int width); /* width of column, if 0, use variable width */ + FILE *fout, /* output stream */ + int PrintAttNames, /* print attribute names */ + int TerseOutput, /* delimiter bars */ + int colWidth); /* width of column, if 0, use + * variable width */ /* === in fe-lobj.c === */ diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index eba23dcecc8..64468ab4dab 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -9,7 +9,7 @@ * more likely to break across PostgreSQL releases than code that uses * only the official API. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/libpq/libpq-int.h @@ -169,7 +169,7 @@ struct pg_result int ntups; int numAttributes; PGresAttDesc *attDescs; - PGresAttValue **tuples; /* each PGresTuple is an array of + PGresAttValue **tuples; /* each PGresult tuple is an array of * PGresAttValue's */ int tupArrSize; /* allocated size of tuples array */ int numParameters; @@ -208,6 +208,8 @@ struct pg_result PGresult_data *curBlock; /* most recently allocated block */ int curOffset; /* start offset of free space in block */ int spaceLeft; /* number of free bytes remaining in block */ + + size_t memorySize; /* total space allocated for this PGresult */ }; /* PGAsyncStatusType defines the state of the query-execution state machine */ @@ -230,7 +232,8 @@ typedef enum PGQUERY_DESCRIBE /* Describe Statement or Portal */ } PGQueryClass; -/* PGSetenvStatusType defines the state of the PQSetenv state machine */ +/* PGSetenvStatusType defines the state of the pqSetenv state machine */ + /* (this is used only for 2.0-protocol connections) */ typedef enum { @@ -290,6 +293,7 @@ typedef struct pgDataValue const char *value; /* data value, without zero-termination */ } PGdataValue; +/* Host address type enum for struct pg_conn_host */ typedef enum pg_conn_host_type { CHT_HOST_NAME, @@ -298,21 +302,19 @@ typedef enum pg_conn_host_type } pg_conn_host_type; /* - * pg_conn_host stores all information about one of possibly several hosts - * mentioned in the connection string. Derived by splitting the pghost - * on the comma character and then parsing each segment. + * pg_conn_host stores all information about each of possibly several hosts + * mentioned in the connection string. Most fields are derived by splitting + * the relevant connection parameter (e.g., pghost) at commas. */ typedef struct pg_conn_host { - pg_conn_host_type type; /* type of host */ + pg_conn_host_type type; /* type of host address */ char *host; /* host name or socket path */ - char *hostaddr; /* host address */ - char *port; /* port number for this host; if not NULL, - * overrides the PGConn's pgport */ + char *hostaddr; /* host numeric IP address */ + char *port; /* port number (always provided) */ char *password; /* password for this host, read from the - * password file. only set if the PGconn's - * pgpass field is NULL. */ - struct addrinfo *addrlist; /* list of possible backend addresses */ + * password file; NULL if not sought or not + * found in password file. */ } pg_conn_host; /* @@ -325,15 +327,17 @@ struct pg_conn char *pghost; /* the machine on which the server is running, * or a path to a UNIX-domain socket, or a * comma-separated list of machines and/or - * paths, optionally with port suffixes; if - * NULL, use DEFAULT_PGSOCKET_DIR */ + * paths; if NULL, use DEFAULT_PGSOCKET_DIR */ char *pghostaddr; /* the numeric IP address of the machine on - * which the server is running. Takes - * precedence over above. */ - char *pgport; /* the server's communication port number */ + * which the server is running, or a + * comma-separated list of same. Takes + * precedence over pghost. */ + char *pgport; /* the server's communication port number, or + * a comma-separated list of ports */ char *pgtty; /* tty on which the backend messages is * displayed (OBSOLETE, NOT USED) */ char *connect_timeout; /* connection timeout (numeric string) */ + char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */ char *client_encoding_initial; /* encoding to use */ char *pgoptions; /* options to start the backend with */ char *appname; /* application name */ @@ -343,13 +347,14 @@ struct pg_conn char *pguser; /* Postgres username and password, if any */ char *pgpass; char *pgpassfile; /* path to a file containing password(s) */ + char *channel_binding; /* channel binding mode + * (require,prefer,disable) */ char *keepalives; /* use TCP keepalives? */ char *keepalives_idle; /* time between TCP keepalives */ char *keepalives_interval; /* time between TCP keepalive * retransmits */ char *keepalives_count; /* maximum number of TCP keepalive * retransmits */ - char *scram_channel_binding; /* SCRAM channel binding type */ char *sslmode; /* SSL mode (require,prefer,allow,disable) */ char *sslcompression; /* SSL compression (0 or 1) */ char *sslkey; /* client key filename */ @@ -393,9 +398,10 @@ struct pg_conn PGnotify *notifyTail; /* newest unreported Notify msg */ /* Support for multiple hosts in connection string */ - int nconnhost; /* # of possible hosts */ - int whichhost; /* host we're currently considering */ - pg_conn_host *connhost; /* details about each possible host */ + int nconnhost; /* # of hosts named in conn string */ + int whichhost; /* host we're currently trying/connected to */ + pg_conn_host *connhost; /* details about each named host */ + char *connip; /* IP address for current network connection */ /* Connection data */ pgsocket sock; /* FD for socket, PGINVALID_SOCKET if @@ -406,12 +412,17 @@ struct pg_conn int sversion; /* server version, e.g. 70401 for 7.4.1 */ bool auth_req_received; /* true if any type of auth req received */ bool password_needed; /* true if server demanded a password */ - bool pgpassfile_used; /* true if password is from pgpassfile */ bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */ bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */ + bool write_failed; /* have we had a write failure on sock? */ + char *write_err_msg; /* write error message, or NULL if OOM */ /* Transient state needed while establishing connection */ - struct addrinfo *addr_cur; /* backend address currently being tried */ + bool try_next_addr; /* time to advance to next address/host? */ + bool try_next_host; /* time to advance to next connhost[]? */ + struct addrinfo *addrlist; /* list of addresses for current connhost */ + struct addrinfo *addr_cur; /* the one currently being tried */ + int addrlist_family; /* needed to know how to free addrlist */ PGSetenvStatusType setenv_state; /* for 2.0 protocol only */ const PQEnvironmentOption *next_eo; bool send_appname; /* okay to send application_name? */ @@ -473,9 +484,15 @@ struct pg_conn #endif /* USE_OPENSSL */ #endif /* USE_SSL */ + char *gssencmode; /* GSS mode (require,prefer,disable) */ #ifdef ENABLE_GSS gss_ctx_id_t gctx; /* GSS context */ gss_name_t gtarg_nam; /* GSS target name */ + + /* The following are encryption-only */ + bool try_gss; /* GSS attempting permitted */ + bool gssenc; /* GSS encryption is usable */ + gss_cred_id_t gcred; /* GSS credential temp storage. */ #endif #ifdef ENABLE_SSPI @@ -544,8 +561,8 @@ extern char *const pgresStatus[]; /* === in fe-connect.c === */ extern void pqDropConnection(PGconn *conn, bool flushInput); -extern int pqPacketSend(PGconn *conn, char pack_type, - const void *buf, size_t buf_len); +extern int pqPacketSend(PGconn *conn, char pack_type, + const void *buf, size_t buf_len); extern bool pqGetHomeDirectory(char *buf, int bufsize); #ifdef ENABLE_THREAD_SAFETY @@ -576,44 +593,43 @@ extern void pqSaveErrorResult(PGconn *conn); extern PGresult *pqPrepareAsyncResult(PGconn *conn); extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3); extern void pqSaveMessageField(PGresult *res, char code, - const char *value); + const char *value); extern void pqSaveParameterStatus(PGconn *conn, const char *name, - const char *value); + const char *value); extern int pqRowProcessor(PGconn *conn, const char **errmsgp); -extern void pqHandleSendFailure(PGconn *conn); /* === in fe-protocol2.c === */ extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn); extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen, - const PQEnvironmentOption *options); + const PQEnvironmentOption *options); extern void pqParseInput2(PGconn *conn); extern int pqGetCopyData2(PGconn *conn, char **buffer, int async); extern int pqGetline2(PGconn *conn, char *s, int maxlen); extern int pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize); extern int pqEndcopy2(PGconn *conn); extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid, - int *result_buf, int *actual_result_len, - int result_is_int, - const PQArgBlock *args, int nargs); + int *result_buf, int *actual_result_len, + int result_is_int, + const PQArgBlock *args, int nargs); /* === in fe-protocol3.c === */ extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, - const PQEnvironmentOption *options); + const PQEnvironmentOption *options); extern void pqParseInput3(PGconn *conn); extern int pqGetErrorNotice3(PGconn *conn, bool isError); extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, - PGVerbosity verbosity, PGContextVisibility show_context); + PGVerbosity verbosity, PGContextVisibility show_context); extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); extern int pqGetline3(PGconn *conn, char *s, int maxlen); extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize); extern int pqEndcopy3(PGconn *conn); extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, - int *result_buf, int *actual_result_len, - int result_is_int, - const PQArgBlock *args, int nargs); + int *result_buf, int *actual_result_len, + int result_is_int, + const PQArgBlock *args, int nargs); /* === in fe-misc.c === */ @@ -639,15 +655,14 @@ extern int pqPutMsgEnd(PGconn *conn); extern int pqReadData(PGconn *conn); extern int pqFlush(PGconn *conn); extern int pqWait(int forRead, int forWrite, PGconn *conn); -extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, - time_t finish_time); +extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, + time_t finish_time); extern int pqReadReady(PGconn *conn); extern int pqWriteReady(PGconn *conn); /* === in fe-secure.c === */ extern int pqsecure_initialize(PGconn *); -extern void pqsecure_destroy(void); extern PostgresPollingStatusType pqsecure_open_client(PGconn *); extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); @@ -658,7 +673,7 @@ extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, - bool got_epipe); + bool got_epipe); #endif /* === SSL === */ @@ -715,22 +730,20 @@ extern bool pgtls_read_pending(PGconn *conn); */ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len); -/* - * Get the TLS finish message sent during last handshake. - * - * This information is useful for callers doing channel binding during - * authentication. - */ -extern char *pgtls_get_finished(PGconn *conn, size_t *len); - /* * Get the hash of the server certificate, for SCRAM channel binding type * tls-server-end-point. * * NULL is sent back to the caller in the event of an error, with an * error message for the caller to consume. + * + * This is not supported with old versions of OpenSSL that don't have + * the X509_get_signature_nid() function. */ +#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID) +#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); +#endif /* * Verify that the server certificate matches the host name we connected to. @@ -741,9 +754,26 @@ extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); * -1, and sets the libpq error message. * */ -extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, - int *names_examined, - char **first_name); +extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, + int *names_examined, + char **first_name); + +/* === GSSAPI === */ + +#ifdef ENABLE_GSS + +/* + * Establish a GSSAPI-encrypted connection. + */ +extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); + +/* + * Read and write functions for GSSAPI-encrypted connections, with internal + * buffering to handle nonblocking sockets. + */ +extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); +extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); +#endif /* === miscellaneous macros === */ @@ -771,7 +801,7 @@ extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigne #define SOCK_ERRNO_SET(e) WSASetLastError(e) #else #define SOCK_ERRNO errno -#define SOCK_STRERROR pqStrerror +#define SOCK_STRERROR strerror_r #define SOCK_ERRNO_SET(e) (errno = (e)) #endif diff --git a/src/interfaces/libpq/libpq.rc.in b/src/interfaces/libpq/libpq.rc.in index bc89cd2a433..896651a4115 100644 --- a/src/interfaces/libpq/libpq.rc.in +++ b/src/interfaces/libpq/libpq.rc.in @@ -1,8 +1,8 @@ #include VS_VERSION_INFO VERSIONINFO - FILEVERSION 11,0,0,0 - PRODUCTVERSION 11,0,0,0 + FILEVERSION 13,0,0,0 + PRODUCTVERSION 13,0,0,0 FILEFLAGSMASK 0x3fL FILEFLAGS 0 FILEOS VOS__WINDOWS32 @@ -15,13 +15,13 @@ BEGIN BEGIN VALUE "CompanyName", "\0" VALUE "FileDescription", "PostgreSQL Access Library\0" - VALUE "FileVersion", "11.0\0" + VALUE "FileVersion", "13.0\0" VALUE "InternalName", "libpq\0" - VALUE "LegalCopyright", "Copyright (C) 2018\0" + VALUE "LegalCopyright", "Copyright (C) 2019\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libpq.dll\0" VALUE "ProductName", "PostgreSQL\0" - VALUE "ProductVersion", "11.0\0" + VALUE "ProductVersion", "13.0\0" END END BLOCK "VarFileInfo" diff --git a/src/interfaces/libpq/nls.mk b/src/interfaces/libpq/nls.mk index 4196870b496..28f3941ab92 100644 --- a/src/interfaces/libpq/nls.mk +++ b/src/interfaces/libpq/nls.mk @@ -1,6 +1,6 @@ # src/interfaces/libpq/nls.mk CATALOG_NAME = libpq AVAIL_LANGUAGES = cs de es fr he it ja ko pl pt_BR ru sv tr zh_CN zh_TW -GETTEXT_FILES = fe-auth.c fe-auth-scram.c fe-connect.c fe-exec.c fe-lobj.c fe-misc.c fe-protocol2.c fe-protocol3.c fe-secure.c fe-secure-common.c fe-secure-openssl.c win32.c +GETTEXT_FILES = fe-auth.c fe-auth-scram.c fe-connect.c fe-exec.c fe-gssapi-common.c fe-lobj.c fe-misc.c fe-protocol2.c fe-protocol3.c fe-secure.c fe-secure-common.c fe-secure-gssapi.c fe-secure-openssl.c win32.c GETTEXT_TRIGGERS = libpq_gettext pqInternalNotice:2 GETTEXT_FLAGS = libpq_gettext:1:pass-c-format pqInternalNotice:2:c-format diff --git a/src/interfaces/libpq/po/cs.po b/src/interfaces/libpq/po/cs.po index 7a54ba6b705..2c826a6a1a9 100644 --- a/src/interfaces/libpq/po/cs.po +++ b/src/interfaces/libpq/po/cs.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: libpq-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-09-23 20:12+0000\n" -"PO-Revision-Date: 2013-09-24 20:31+0200\n" +"POT-Creation-Date: 2018-07-13 19:38+0000\n" +"PO-Revision-Date: 2018-08-06 20:03+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -18,103 +18,238 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" -#: fe-auth.c:210 fe-auth.c:429 fe-auth.c:656 -msgid "host name must be specified\n" -msgstr "host musí být specifikován\n" +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (empty message)\n" +msgstr "poÅ¡kozená SCRAM zpráva (prázdná zpráva)\n" -#: fe-auth.c:240 +#: fe-auth-scram.c:195 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "poÅ¡kozená SCRAM zpráva (délka neodpovídá)\n" + +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "chybná signatura serveru\n" + +#: fe-auth-scram.c:253 +msgid "invalid SCRAM exchange state\n" +msgstr "chybný stav SCRAM výmÄ›ny\n" + +#: fe-auth-scram.c:276 #, c-format -msgid "could not set socket to blocking mode: %s\n" -msgstr "nelze nastavit soket do blokujícího módu: %s\n" +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "poÅ¡kozená SCRAM zpráva (oÄekáván atribut \"%c\")\n" -#: fe-auth.c:258 fe-auth.c:262 +#: fe-auth-scram.c:285 #, c-format -msgid "Kerberos 5 authentication rejected: %*s\n" -msgstr "Kerberos 5 autentizace odmítnuta: %*s\n" +msgid "" +"malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "poÅ¡kozená SCRAM zpráva (oÄekáván znak \"=\" pro atribut \"%c\")\n" + +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" +msgstr "nelze vygenerovat nonce\n" + +#: fe-auth-scram.c:334 fe-auth-scram.c:408 fe-auth-scram.c:554 +#: fe-auth-scram.c:574 fe-auth-scram.c:600 fe-auth-scram.c:614 +#: fe-auth-scram.c:656 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:628 fe-auth.c:787 fe-auth.c:1099 fe-auth.c:1247 fe-connect.c:782 +#: fe-connect.c:1209 fe-connect.c:1385 fe-connect.c:1953 fe-connect.c:2482 +#: fe-connect.c:4070 fe-connect.c:4322 fe-connect.c:4441 fe-connect.c:4691 +#: fe-connect.c:4771 fe-connect.c:4870 fe-connect.c:5126 fe-connect.c:5155 +#: fe-connect.c:5227 fe-connect.c:5251 fe-connect.c:5269 fe-connect.c:5370 +#: fe-connect.c:5379 fe-connect.c:5735 fe-connect.c:5885 fe-exec.c:2702 +#: fe-exec.c:3449 fe-exec.c:3614 fe-lobj.c:895 fe-protocol2.c:1213 +#: fe-protocol3.c:999 fe-protocol3.c:1685 fe-secure-common.c:103 +#: fe-secure-openssl.c:458 fe-secure-openssl.c:1049 +msgid "out of memory\n" +msgstr "nedostatek pamÄ›ti\n" + +#: fe-auth-scram.c:469 +msgid "invalid channel binding type\n" +msgstr "neplatný channel binding typ\n" -#: fe-auth.c:288 +#: fe-auth-scram.c:480 #, c-format -#| msgid "could not restore non-blocking mode on socket: %s\n" -msgid "could not restore nonblocking mode on socket: %s\n" -msgstr "nelze obnovit neblokující mód soketu: %s\n" +msgid "empty channel binding data for channel binding type \"%s\"\n" +msgstr "" +"prázdná \"channel binding data\" pro channel binding typu \"%s\"\n" +"\n" + +#: fe-auth-scram.c:592 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "chybná SCRAM odpovÄ›Ä (nonce neodpovídá)\n" + +#: fe-auth-scram.c:631 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "poÅ¡kozená SCRAM zpráva (chybný poÄet iterací)\n" -#: fe-auth.c:400 +#: fe-auth-scram.c:637 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "poÅ¡kozená SCRAM zpráva (smetí na konci server-first-message)\n" + +#: fe-auth-scram.c:667 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "server zaslal chybu v rámci SCRAM výmÄ›ny: %s\n" + +#: fe-auth-scram.c:683 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "poÅ¡kozená SCRAM zpráva (smetí na konci server-final-message)\n" + +#: fe-auth-scram.c:691 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "poÅ¡kozená SCRAM zpráva (chybná signatura serveru)\n" + +#: fe-auth.c:122 +#, c-format +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "pÅ™i alokaci GSSAPI bufferu doÅ¡la paměť (%d)\n" + +#: fe-auth.c:177 msgid "GSSAPI continuation error" msgstr "PÅ™etrvávající chyba GSSAPI" -#: fe-auth.c:436 +#: fe-auth.c:207 fe-auth.c:461 +msgid "host name must be specified\n" +msgstr "host musí být specifikován\n" + +#: fe-auth.c:214 msgid "duplicate GSS authentication request\n" msgstr "duplikátní GSS autentizaÄní požadavek\n" -#: fe-auth.c:456 +#: fe-auth.c:240 msgid "GSSAPI name import error" -msgstr "chyba importu jména GSSAPI" +msgstr "chyba importu GSSAPI jména" + +#: fe-auth.c:303 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "pÅ™i alokaci SSPI bufferu doÅ¡la paměť (%d)\n" -#: fe-auth.c:542 +#: fe-auth.c:351 msgid "SSPI continuation error" msgstr "PÅ™etrvávající chyba SSPI" -#: fe-auth.c:553 fe-auth.c:627 fe-auth.c:662 fe-auth.c:758 fe-connect.c:2005 -#: fe-connect.c:3393 fe-connect.c:3611 fe-connect.c:4023 fe-connect.c:4118 -#: fe-connect.c:4383 fe-connect.c:4452 fe-connect.c:4469 fe-connect.c:4560 -#: fe-connect.c:4910 fe-connect.c:5060 fe-exec.c:3296 fe-exec.c:3461 -#: fe-lobj.c:896 fe-protocol2.c:1181 fe-protocol3.c:1544 fe-secure.c:791 -#: fe-secure.c:1191 -msgid "out of memory\n" -msgstr "nedostatek pamÄ›ti\n" +#: fe-auth.c:422 +msgid "duplicate SSPI authentication request\n" +msgstr "duplicitní SSPI autentizaÄní požadavek\n" -#: fe-auth.c:642 +#: fe-auth.c:447 msgid "could not acquire SSPI credentials" -msgstr "nelze získat SSL credentials." +msgstr "nelze získat SSPI credentials" + +#: fe-auth.c:501 +msgid "duplicate SASL authentication request\n" +msgstr "duplicitní SASL autentizaÄní požadavek\n" + +#: fe-auth.c:546 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "žádný ze SASL authentizaÄních mechanismů serveru není podporován\n" + +#: fe-auth.c:652 +#, c-format +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "pÅ™i alokaci SASL bufferu doÅ¡la paměť (%d)\n" -#: fe-auth.c:733 +#: fe-auth.c:677 +msgid "" +"AuthenticationSASLFinal received from server, but SASL authentication was " +"not completed\n" +msgstr "" +"AuthenticationSASLFinal obdržena od serveru, ale SASL authentizace nebyla " +"dokonÄena\n" + +#: fe-auth.c:754 msgid "SCM_CRED authentication method not supported\n" msgstr "SCM_CRED metoda autentizace není podporována\n" -#: fe-auth.c:809 +#: fe-auth.c:845 msgid "Kerberos 4 authentication not supported\n" msgstr "Kerberos 4 autentizace není podporována\n" -#: fe-auth.c:825 +#: fe-auth.c:850 msgid "Kerberos 5 authentication not supported\n" msgstr "Kerberos 5 autentizace není podporována\n" -#: fe-auth.c:897 +#: fe-auth.c:921 msgid "GSSAPI authentication not supported\n" msgstr "GSSAPI autentizace není podporována\n" -#: fe-auth.c:929 +#: fe-auth.c:953 msgid "SSPI authentication not supported\n" msgstr "SSPI autentizace není podporována\n" -#: fe-auth.c:937 +#: fe-auth.c:961 msgid "Crypt authentication not supported\n" msgstr "Crypt autentizace není podporována\n" -#: fe-auth.c:964 +#: fe-auth.c:1027 #, c-format msgid "authentication method %u not supported\n" msgstr "autentizaÄní metoda %u není podporována\n" -#: fe-connect.c:798 +#: fe-auth.c:1074 +#, c-format +msgid "user name lookup failure: error code %lu\n" +msgstr "vyhledání uživatele selhalo: chybový kód %lu\n" + +#: fe-auth.c:1084 fe-connect.c:2409 +#, c-format +msgid "could not look up local user ID %d: %s\n" +msgstr "nelze vyhledat lokálního uživatele ID %d: %s\n" + +#: fe-auth.c:1089 fe-connect.c:2414 +#, c-format +msgid "local user with ID %d does not exist\n" +msgstr "lokální uživatel s ID %d neexistuje\n" + +#: fe-auth.c:1191 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "neoÄekávaná podoba výsledku pro SHOW\n" + +#: fe-auth.c:1200 +msgid "password_encryption value too long\n" +msgstr "hodnota password_encryption je příliÅ¡ dlouhá\n" + +#: fe-auth.c:1240 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "neznámý algoritmus pro Å¡ifrování hesla \"%s\"\n" + +#: fe-connect.c:975 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "nelze napárovat %d jmen hostů na %d hostaddr hodnot\n" + +#: fe-connect.c:1032 +#, c-format +msgid "could not match %d port numbers to %d hosts\n" +msgstr "nelze napárovat %d Äísel portů na %d hostů\n" + +#: fe-connect.c:1135 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "neplatná hodnota sslmode: \"%s\"\n" -#: fe-connect.c:819 +#: fe-connect.c:1156 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "" "hodnota sslmode \"%s\" je neplatná pokud není zakompilována podpora SSL\n" -#: fe-connect.c:1023 +#: fe-connect.c:1191 +#, c-format +msgid "invalid target_session_attrs value: \"%s\"\n" +msgstr "neplatná hodnota target_session_attrs: \"%s\"\n" + +#: fe-connect.c:1409 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "nelze nastavit \"no delay\" mód TCP soketu: %s\n" -#: fe-connect.c:1053 +#: fe-connect.c:1439 #, c-format msgid "" "could not connect to server: %s\n" @@ -125,7 +260,7 @@ msgstr "" "\tJe spuÅ¡tÄ›n server lokálnÄ› a akceptuje\n" "\tspojení pomocí Unix soketu \"%s\"?\n" -#: fe-connect.c:1108 +#: fe-connect.c:1497 #, c-format msgid "" "could not connect to server: %s\n" @@ -136,7 +271,7 @@ msgstr "" "\tJe server na \"%s\" (%s) spuÅ¡tÄ›n a akceptuje\n" "\tTCP/IP spojení na portu %s?\n" -#: fe-connect.c:1117 +#: fe-connect.c:1506 #, c-format msgid "" "could not connect to server: %s\n" @@ -147,247 +282,235 @@ msgstr "" "\tJe server na \"%s\" spuÅ¡tÄ›n a akceptuje\n" "\tTCP/IP spojení na portu %s?\n" -#: fe-connect.c:1168 -#, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPIDLE) selhalo: %s\n" - -#: fe-connect.c:1181 -#, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPALIVE) selhalo: %s\n" - -#: fe-connect.c:1213 +#: fe-connect.c:1557 fe-connect.c:1589 fe-connect.c:1622 fe-connect.c:2181 #, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "setsockopt(TCP_KEEPINTVL) selhalo: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "setsockopt(%s) selhalo: %s\n" -#: fe-connect.c:1245 -#, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "setsockopt(TCP_KEEPCNT) selhalo: %s\n" - -#: fe-connect.c:1293 +#: fe-connect.c:1671 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) selhalo: %ui\n" -#: fe-connect.c:1345 +#: fe-connect.c:1728 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "neplatné Äíslo portu: \"%s\"\n" -#: fe-connect.c:1378 -#, c-format -msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" -msgstr "Cesta k unixovému \"%s\" je příliÅ¡ dlouhá (maximum %d bytů)\n" - -#: fe-connect.c:1397 +#: fe-connect.c:1744 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "nemohu pÅ™eložit jméno hostitele \"%s\" na adresu: %s\n" -#: fe-connect.c:1401 +#: fe-connect.c:1753 +#, c-format +msgid "could not parse network address \"%s\": %s\n" +msgstr "nelze naparsovat síťovou adresu \"%s\": %s\n" + +#: fe-connect.c:1764 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" +msgstr "Cesta k unixovému \"%s\" je příliÅ¡ dlouhá (maximum %d bytů)\n" + +#: fe-connect.c:1778 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "nemohu pÅ™eložit cestu Unix-domain soketu \"%s\" na adresu: %s\n" -#: fe-connect.c:1606 +#: fe-connect.c:2059 msgid "invalid connection state, probably indicative of memory corruption\n" msgstr "neplatný stav spojení, pravdÄ›podobnÄ› způsobený poÅ¡kozením pamÄ›ti\n" -#: fe-connect.c:1647 +#: fe-connect.c:2116 #, c-format msgid "could not create socket: %s\n" msgstr "nelze vytvoÅ™it soket: %s\n" -#: fe-connect.c:1669 +#: fe-connect.c:2138 #, c-format -#| msgid "could not set socket to non-blocking mode: %s\n" msgid "could not set socket to nonblocking mode: %s\n" msgstr "soket nelze nastavit do neblokujícího módu: %s\n" -#: fe-connect.c:1680 +#: fe-connect.c:2149 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "nelze nastavit soket do close-on-exec módu: %s\n" -#: fe-connect.c:1699 +#: fe-connect.c:2168 msgid "keepalives parameter must be an integer\n" msgstr "parametr keepalives musí být celé Äíslo\n" -#: fe-connect.c:1712 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(SO_KEEPALIVE) selhalo: %s\n" - -#: fe-connect.c:1849 +#: fe-connect.c:2319 #, c-format msgid "could not get socket error status: %s\n" msgstr "nelze obdržet chybový status soketu: %s\n" -#: fe-connect.c:1883 +#: fe-connect.c:2354 #, c-format msgid "could not get client address from socket: %s\n" msgstr "nelze získat adresu klienta ze soketu: %s\n" -#: fe-connect.c:1924 +#: fe-connect.c:2396 msgid "requirepeer parameter is not supported on this platform\n" msgstr "parametr requirepeer není na této platformÄ› podporován\n" -#: fe-connect.c:1927 +#: fe-connect.c:2399 #, c-format msgid "could not get peer credentials: %s\n" msgstr "nelze získat informace (credentials) protistrany: %s\n" -#: fe-connect.c:1937 -#, c-format -msgid "local user with ID %d does not exist\n" -msgstr "lokální uživatel s ID %d neexistuje\n" - -#: fe-connect.c:1945 +#: fe-connect.c:2422 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeer obsahuje \"%s\", ale skuteÄné jméno peera je \"%s\"\n" -#: fe-connect.c:1979 +#: fe-connect.c:2456 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "nelze poslat SSL \"negotiation paket\": %s\n" -#: fe-connect.c:2018 +#: fe-connect.c:2495 #, c-format msgid "could not send startup packet: %s\n" msgstr "nelze poslat poÄáteÄní paket: %s\n" -#: fe-connect.c:2088 +#: fe-connect.c:2565 msgid "server does not support SSL, but SSL was required\n" msgstr "server nepodporuje SSL, leÄ SSL je vyžadováno\n" -#: fe-connect.c:2114 +#: fe-connect.c:2591 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "pÅ™ijata neplatná odpovÄ›Ä na SSL negotiation: %c\n" -#: fe-connect.c:2189 fe-connect.c:2222 +#: fe-connect.c:2667 fe-connect.c:2700 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "oÄekáván byl autentizaÄní dotaz ze serveru, ale pÅ™ijat byl %c\n" -#: fe-connect.c:2389 -#, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "pÅ™i alokace GSSAPI bufferu doÅ¡la paměť (%d)" - -#: fe-connect.c:2474 +#: fe-connect.c:2929 msgid "unexpected message from server during startup\n" msgstr "neoÄekávaná zpráva ze serveru bÄ›hem startu\n" -#: fe-connect.c:2568 +#: fe-connect.c:3147 +#, c-format +msgid "could not make a writable connection to server \"%s:%s\"\n" +msgstr "nelze otevřít zapisovatelné spojení na server \"%s:%s\"\n" + +#: fe-connect.c:3196 +#, c-format +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "test \"SHOW transaction_read_only\" selhal na serveru \"%s:%s\"\n" + +#: fe-connect.c:3217 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "neplatný stav spojení %d, pravdÄ›podobnÄ› způsobený poÅ¡kozením pamÄ›ti\n" -#: fe-connect.c:3001 fe-connect.c:3061 +#: fe-connect.c:3676 fe-connect.c:3736 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc \"%s\" selhalo bÄ›hem události PGEVT_CONNRESET\n" -#: fe-connect.c:3406 +#: fe-connect.c:4083 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "naplatné LDAP URL \"%s\": schéma musí být ldap://\n" -#: fe-connect.c:3421 +#: fe-connect.c:4098 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "neplatné LDAP URL \"%s\": chybí rozliÅ¡ující jméno\n" -#: fe-connect.c:3432 fe-connect.c:3485 +#: fe-connect.c:4109 fe-connect.c:4162 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "neplatné LDAP URL \"%s\": musí mít právÄ› jeden atribut\n" -#: fe-connect.c:3442 fe-connect.c:3499 +#: fe-connect.c:4119 fe-connect.c:4176 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "naplatné LDAP URL \"%s\": musí mít vyhledávací rozsah (base/one/sub)\n" -#: fe-connect.c:3453 +#: fe-connect.c:4130 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "naplatné LDAP URL \"%s\": není filter\n" -#: fe-connect.c:3474 +#: fe-connect.c:4151 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "naplatné LDAP URL \"%s\": neplatný Äíslo portu\n" -#: fe-connect.c:3508 +#: fe-connect.c:4185 msgid "could not create LDAP structure\n" msgstr "nelze vytvoÅ™it LDAP strukturu\n" -#: fe-connect.c:3550 +#: fe-connect.c:4261 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "vyhledávání na LDAP serveru selhalo: %s\n" -#: fe-connect.c:3561 +#: fe-connect.c:4272 msgid "more than one entry found on LDAP lookup\n" msgstr "nalezen více jak jeden záznam pÅ™i LDAP vyhledávání\n" -#: fe-connect.c:3562 fe-connect.c:3574 +#: fe-connect.c:4273 fe-connect.c:4285 msgid "no entry found on LDAP lookup\n" msgstr "nebyl nalezen žádný záznam pÅ™i LDAP vyhledávání\n" -#: fe-connect.c:3585 fe-connect.c:3598 +#: fe-connect.c:4296 fe-connect.c:4309 msgid "attribute has no values on LDAP lookup\n" msgstr "atribut nemá žádnou hodnotu pÅ™i LDAP vyhledávání\n" -#: fe-connect.c:3650 fe-connect.c:3669 fe-connect.c:4157 +#: fe-connect.c:4361 fe-connect.c:4380 fe-connect.c:4909 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "chybné \"=\" po \"%s\" v informaÄním Å™etÄ›zci spojení\n" -#: fe-connect.c:3733 fe-connect.c:4337 fe-connect.c:5042 +#: fe-connect.c:4453 fe-connect.c:5094 fe-connect.c:5868 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "neplatný parametr spojení \"%s\"\n" -#: fe-connect.c:3749 fe-connect.c:4206 +#: fe-connect.c:4469 fe-connect.c:4958 msgid "unterminated quoted string in connection info string\n" msgstr "neukonÄený Å™etÄ›zec v uvozovkách v informaÄním Å™etÄ›zci spojení\n" -#: fe-connect.c:3788 -msgid "could not get home directory to locate service definition file" -msgstr "nelze získat domovský adresář pro nalezení koÅ™enového certifikátu" - -#: fe-connect.c:3821 +#: fe-connect.c:4552 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "definice služby \"%s\" nenalezena\n" -#: fe-connect.c:3844 +#: fe-connect.c:4575 #, c-format msgid "service file \"%s\" not found\n" msgstr "soubor se seznamem služeb \"%s\" nebyl nalezen\n" -#: fe-connect.c:3857 +#: fe-connect.c:4588 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "řádek %d v souboru se seznamem služeb \"%s\" je příliÅ¡ dlouhý\n" -#: fe-connect.c:3928 fe-connect.c:3955 +#: fe-connect.c:4659 fe-connect.c:4703 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "syntaktická chyba v souboru se seznamu služeb \"%s\", řádek %d\n" -#: fe-connect.c:4570 +#: fe-connect.c:4670 +#, c-format +msgid "" +"nested service specifications not supported in service file \"%s\", line %d\n" +msgstr "" +"vnoÅ™ené specifikace služeb nejsou podporovány v service souboru \"%s\", " +"řádek %d\n" + +#: fe-connect.c:5390 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "neplatné URI propagované do interní procedury parseru: \"%s\"\n" -#: fe-connect.c:4640 +#: fe-connect.c:5467 #, c-format msgid "" "end of string reached when looking for matching \"]\" in IPv6 host address " @@ -396,12 +519,12 @@ msgstr "" "pÅ™i hledání odpovídajícího znaku \"]\" v IPv6 adrese hostitele byl dosažen " "konec Å™etÄ›zce URI: \"%s\"\n" -#: fe-connect.c:4647 +#: fe-connect.c:5474 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "IPv6 adresa hostitele v URI nesmí být prázdná: \"%s\"\n" -#: fe-connect.c:4662 +#: fe-connect.c:5489 #, c-format msgid "" "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): " @@ -410,43 +533,43 @@ msgstr "" "neoÄekávaný znak \"%c\" na pozici %d v URI (oÄekáváno \":\" nebo \"/\"): \"%s" "\"\n" -#: fe-connect.c:4776 +#: fe-connect.c:5618 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "" "pÅ™ebyteÄný oddÄ›lovaÄ klíÄe/hodnoty \"=\" v URI parametru dotazu: \"%s\"\n" -#: fe-connect.c:4796 +#: fe-connect.c:5638 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "" "chybÄ›jící oddÄ›lovaÄ klíÄe/hodnoty \"=\" v URI parametru dotazu: \"%s\"\n" -#: fe-connect.c:4867 +#: fe-connect.c:5689 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "neplatný parametr v URI dotazu: \"%s\"\n" -#: fe-connect.c:4937 +#: fe-connect.c:5763 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "neplatný procenty-kódovaný token \"%s\"\n" -#: fe-connect.c:4947 +#: fe-connect.c:5773 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "zakázaná hodnota %%00 v procenty-k´odované hodnotÄ›: \"%s\"\n" -#: fe-connect.c:5270 +#: fe-connect.c:6119 msgid "connection pointer is NULL\n" msgstr "pointer spojení je NULL\n" -#: fe-connect.c:5547 +#: fe-connect.c:6417 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "VAROVÃNÃ: soubor s hesly \"%s\" není prostý (plain) soubor\n" -#: fe-connect.c:5556 +#: fe-connect.c:6426 #, c-format msgid "" "WARNING: password file \"%s\" has group or world access; permissions should " @@ -455,205 +578,228 @@ msgstr "" "UPOZORNÄšNÃ: Soubor s hesly \"%s\" má přístupová práva pro Ätení pro skupinu " "nebo vÅ¡echny uživatele; práva by mÄ›la být u=rw (0600)\n" -#: fe-connect.c:5656 +#: fe-connect.c:6518 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "heslo naÄteno ze souboru \"%s\"\n" -#: fe-exec.c:824 +#: fe-exec.c:437 fe-exec.c:2776 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "Äíslo řádky %d je mimo rozsah 0..%d" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "nedostatek pamÄ›ti" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "POZNÃMKA" -#: fe-exec.c:1120 fe-exec.c:1178 fe-exec.c:1224 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult nemůže podporovat více než INT_MAX řádek" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "size_t pÅ™eteÄení" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "Å™etÄ›zec příkazu je prázdný ukazatel\n" -#: fe-exec.c:1184 fe-exec.c:1230 fe-exec.c:1325 +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "poÄet parametrů musí být mezi 0 a 65535\n" -#: fe-exec.c:1218 fe-exec.c:1319 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "název výrazu je prázdný ukazatel\n" -#: fe-exec.c:1238 fe-exec.c:1402 fe-exec.c:2096 fe-exec.c:2295 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2390 msgid "function requires at least protocol version 3.0\n" msgstr "funkce vyžaduje protokol alespoň 3.0 a vyšší\n" -#: fe-exec.c:1356 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "není spojení se serverem\n" -#: fe-exec.c:1363 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "zpracovává se již jiný příkaz\n" -#: fe-exec.c:1478 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "délka musí být specifikována pro binarní parametr\n" -#: fe-exec.c:1756 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "neoÄekávaný asyncStatus: %d\n" -#: fe-exec.c:1776 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc \"%s\" selhala bÄ›hem události PGEVT_RESULTCREATE\n" -#: fe-exec.c:1906 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "COPY bylo ukonÄeno novým PQexec" -#: fe-exec.c:1914 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "COPY IN status musí být nejdříve ukonÄen\n" -#: fe-exec.c:1934 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "COPY OUT status musí být nejdříve ukonÄen\n" -#: fe-exec.c:1942 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec není povoleno bÄ›hem COPY BOTH\n" -#: fe-exec.c:2185 fe-exec.c:2252 fe-exec.c:2342 fe-protocol2.c:1327 -#: fe-protocol3.c:1683 +#: fe-exec.c:2280 fe-exec.c:2347 fe-exec.c:2437 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "COPY se neprovádí\n" -#: fe-exec.c:2534 +#: fe-exec.c:2627 msgid "connection in wrong state\n" msgstr "spojení je ve Å¡patném stavu\n" -#: fe-exec.c:2565 +#: fe-exec.c:2658 msgid "invalid ExecStatusType code" msgstr "neplatný ExecStatusType kód" -#: fe-exec.c:2629 fe-exec.c:2652 +#: fe-exec.c:2685 +msgid "PGresult is not an error result\n" +msgstr "PGresult není chybový výsledek\n" + +#: fe-exec.c:2760 fe-exec.c:2783 #, c-format msgid "column number %d is out of range 0..%d" msgstr "Äíslo sloupce %d je mimo rozsah 0..%d" -#: fe-exec.c:2645 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "Äíslo řádky %d je mimo rozsah 0..%d" - -#: fe-exec.c:2667 +#: fe-exec.c:2798 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "Äíslo parametru %d je mimo rozsah 0..%d" -#: fe-exec.c:2955 +#: fe-exec.c:3108 #, c-format msgid "could not interpret result from server: %s" msgstr "nelze interpretovat výsledek ze serveru: %s" -#: fe-exec.c:3194 fe-exec.c:3278 +#: fe-exec.c:3347 fe-exec.c:3431 msgid "incomplete multibyte character\n" msgstr "nekompletní multibyte znak\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "nelze urÄit OID funkce lo_truncare\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "argument pro lo_truncate pÅ™esahuje rozsah typu integer\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "nelze urÄit OID funkce lo_truncare64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "agrument pro lo_read pÅ™esahuje rozsah typu integer\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "agrument pro lo_write pÅ™esahuje rozsah typu integer\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "nelze urÄit OID funkce lo_lseek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "nelze urÄit OID funkce lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "nelze urÄit OID funkce lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "nelze otevřít soubor \"%s\": %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "nelze Äíst ze souboru \"%s\": %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "nelze zapsat do souboru \"%s\": %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "dotaz inicializující \"large object\" funkce nevrátil data\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "nelze urÄit OID funkce lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "nelze urÄit OID funkce lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "nelze urÄit OID funkce lo_create\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "nelze urÄit OID funkce lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "nelze urÄit OID funkce lo_lseek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "nelze urÄit OID funkce lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "nelze urÄit OID funkce loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "nelze urÄit OID funkce lowrite\n" -#: fe-misc.c:295 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "pqGetInt nepodporuje integer velikosti %lu" -#: fe-misc.c:331 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "pqPutInt nepodporuje integer velikosti %lu" -#: fe-misc.c:610 fe-misc.c:806 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "spojení není otevÅ™eno\n" -#: fe-misc.c:736 fe-secure.c:387 fe-secure.c:467 fe-secure.c:548 -#: fe-secure.c:657 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -663,41 +809,41 @@ msgstr "" "\tToto pravdÄ›podobnÄ› znamená, že byl ukonÄen nestandardnÄ›\n" "\tpÅ™ed nebo bÄ›hem vykonávání požadavku.\n" -#: fe-misc.c:970 +#: fe-misc.c:1009 msgid "timeout expired\n" msgstr "Äasový limit (timeout) ubÄ›hl\n" -#: fe-misc.c:1015 -msgid "socket not open\n" -msgstr "soket není otevÅ™en\n" +#: fe-misc.c:1054 +msgid "invalid socket\n" +msgstr "chybný socket\n" -#: fe-misc.c:1038 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "select() selhal: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "" "neplatný status spojení %c, pravdÄ›podobnÄ› způsobený poÅ¡kozením pamÄ›ti\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "neplatný status %c, pravdÄ›podobnÄ› způsobený poÅ¡kozením pamÄ›ti\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "zpráva typu 0x%02x pÅ™iÅ¡la ze serveru bÄ›hem neÄinnosti" -#: fe-protocol2.c:522 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "neoÄekávaný znak %c následuje prázdnou odezvu dotazu(\"I\" zpráva)" -#: fe-protocol2.c:580 +#: fe-protocol2.c:594 #, c-format msgid "" "server sent data (\"D\" message) without prior row description (\"T\" " @@ -706,7 +852,7 @@ msgstr "" "server odeslal data (\"D\" zpráva) bez pÅ™edcházejícího popisu řádky (\"T\" " "zpráva)" -#: fe-protocol2.c:598 +#: fe-protocol2.c:612 #, c-format msgid "" "server sent binary data (\"B\" message) without prior row description (\"T\" " @@ -715,31 +861,26 @@ msgstr "" "server odeslal binární data (\"B\" zpráva) bez pÅ™edchozího popisu řádky (\"T" "\" zpráva)" -#: fe-protocol2.c:618 fe-protocol3.c:385 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "neoÄekávaná odpovÄ›Ä serveru; pÅ™edchozí znak byl \"%c\"\n" -#: fe-protocol2.c:747 fe-protocol2.c:922 fe-protocol3.c:600 fe-protocol3.c:782 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "nedostatek pamÄ›ti pro výsledek dotazu" -#: fe-protocol2.c:1370 fe-protocol3.c:1752 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1382 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "ztráta synchronizace se serverem, resetuji spojení" -#: fe-protocol2.c:1516 fe-protocol2.c:1548 fe-protocol3.c:1955 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "chyba protokolu: id=0x%x\n" -#: fe-protocol3.c:341 +#: fe-protocol3.c:367 msgid "" "server sent data (\"D\" message) without prior row description (\"T\" " "message)\n" @@ -747,214 +888,262 @@ msgstr "" "server odeslal data (\"D\" zpráva) bez pÅ™edchozího popisu řádky (\"T\" " "zpráva)\n" -#: fe-protocol3.c:406 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "obsah zprávy nesouhlasí s délkou v typu zprávy \"%c\"\n" -#: fe-protocol3.c:427 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "" "ztracena synchronizace se serverem: obdržena zpráva typu \"%c\", délky %d\n" -#: fe-protocol3.c:478 fe-protocol3.c:518 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "nedostatek dat v \"T\" zprávÄ›" -#: fe-protocol3.c:551 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "pÅ™ebyteÄná data v \"T\" zprávÄ›" -#: fe-protocol3.c:690 fe-protocol3.c:722 fe-protocol3.c:740 +#: fe-protocol3.c:690 +msgid "extraneous data in \"t\" message" +msgstr "pÅ™ebyteÄná data v \"t\" zprávÄ›" + +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "nedostatek dat v \"D\" zprávÄ›" -#: fe-protocol3.c:696 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "neoÄekávaný poÄet položek v \"D\" zprávÄ›" -#: fe-protocol3.c:749 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "pÅ™ebyteÄná data v \"D\" zprávÄ›" +#: fe-protocol3.c:1012 +msgid "no error message available\n" +msgstr "chybová zpráva není k dispozici\n" + #. translator: %s represents a digit string -#: fe-protocol3.c:878 fe-protocol3.c:897 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" -msgstr "na znaku %s" +msgstr " na znaku %s" -#: fe-protocol3.c:910 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "DETAIL: %s\n" -#: fe-protocol3.c:913 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "DOPORUÄŒENÃ: %s\n" -#: fe-protocol3.c:916 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "DOTAZ: %s\n" -#: fe-protocol3.c:919 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "KONTEXT: %s\n" -#: fe-protocol3.c:926 +#: fe-protocol3.c:1096 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "NÃZEV SCHÉMATU: %s\n" -#: fe-protocol3.c:930 +#: fe-protocol3.c:1100 #, c-format msgid "TABLE NAME: %s\n" msgstr "NÃZEV TABULKY: %s\n" -#: fe-protocol3.c:934 +#: fe-protocol3.c:1104 #, c-format msgid "COLUMN NAME: %s\n" msgstr "NÃZEV SLOUPCE: %s\n" -#: fe-protocol3.c:938 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "NÃZEV DATOVÉHO TYPU: %s\n" -#: fe-protocol3.c:942 +#: fe-protocol3.c:1112 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "NÃZEV OMEZENÃ: %s\n" -#: fe-protocol3.c:954 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "UMÃSTÄšNÃ: " -#: fe-protocol3.c:956 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:958 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1182 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "ŘÃDKA %d: " -#: fe-protocol3.c:1577 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: not doing text COPY OUT\n" -#: fe-secure.c:270 fe-secure.c:1128 fe-secure.c:1348 -#, c-format -#| msgid "could not create SSL context: %s\n" -msgid "could not acquire mutex: %s\n" -msgstr "nelze získat mutex: %s\n" +#: fe-secure-common.c:117 +msgid "SSL certificate's name contains embedded null\n" +msgstr "jméno SSL certifikátu obsahuje vloženou null hodnotu\n" + +#: fe-secure-common.c:164 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "host musí být specifikován pro ověřené SSL spojení\n" -#: fe-secure.c:282 +#: fe-secure-common.c:189 #, c-format -msgid "could not establish SSL connection: %s\n" -msgstr "nelze vytvoÅ™it SSL spojení: %s\n" +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "" +"serverový certifikát pro \"%s\" nesouhlasí s jménem serveru (host name) \"%s" +"\"\n" -#: fe-secure.c:392 fe-secure.c:553 fe-secure.c:1477 +#: fe-secure-common.c:195 +msgid "could not get server's host name from server certificate\n" +msgstr "ze serverového certifikátu nelze získat host name serveru\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1243 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALL chyba: %s\n" -#: fe-secure.c:399 fe-secure.c:560 fe-secure.c:1481 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1247 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALL chyba: detekován EOF\n" -#: fe-secure.c:410 fe-secure.c:571 fe-secure.c:1490 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1256 #, c-format msgid "SSL error: %s\n" msgstr "SSL chyba: %s\n" -#: fe-secure.c:425 fe-secure.c:586 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL spojení bylo neoÄekávanÄ› ukonÄeno\n" -#: fe-secure.c:431 fe-secure.c:592 fe-secure.c:1499 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1265 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "neznámý chybový kód SSL: %d\n" -#: fe-secure.c:475 -#, c-format -msgid "could not receive data from server: %s\n" -msgstr "nelze pÅ™ijmout data ze serveru: %s\n" +#: fe-secure-openssl.c:418 +msgid "could not determine server certificate signature algorithm\n" +msgstr "nelze urÄit podepisovací algoritmus serverového certifikátu\n" -#: fe-secure.c:664 +#: fe-secure-openssl.c:439 #, c-format -msgid "could not send data to server: %s\n" -msgstr "nelze poslat data na server: %s\n" +msgid "could not find digest for NID %s\n" +msgstr "nelze nalézt digest pro NID %s\n" -#: fe-secure.c:784 fe-secure.c:801 -msgid "could not get server common name from server certificate\n" -msgstr "ze serverového certifikátu nelze získat common name serveru\n" +#: fe-secure-openssl.c:449 +msgid "could not generate peer certificate hash\n" +msgstr "nelze vygenerovat hash peer cerfitikátu\n" -#: fe-secure.c:814 -msgid "SSL certificate's common name contains embedded null\n" -msgstr "VeÅ™ejné jméno SSL certifikátu obsahuje vloženou null hodnotu\n" +#: fe-secure-openssl.c:467 +msgid "" +"channel binding type \"tls-server-end-point\" is not supported by this " +"build\n" +msgstr "" +"channel binding typu \"tls-server-end-point\" není tímto buildem podporován\n" -#: fe-secure.c:826 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "host musí být specifikován pro ověřené SSL spojení\n" +#: fe-secure-openssl.c:510 +msgid "SSL certificate's name entry is missing\n" +msgstr "SSL certifikátu chybí položka name\n" -#: fe-secure.c:840 +#: fe-secure-openssl.c:839 #, c-format -msgid "server common name \"%s\" does not match host name \"%s\"\n" +msgid "could not create SSL context: %s\n" +msgstr "nelze vytvoÅ™it SSL kontext: %s\n" + +#: fe-secure-openssl.c:876 +#, c-format +msgid "could not read root certificate file \"%s\": %s\n" +msgstr "nelze Äíst soubor s koÅ™enovým certifikátem \"%s\": %s\n" + +#: fe-secure-openssl.c:904 +#, c-format +msgid "SSL library does not support CRL certificates (file \"%s\")\n" +msgstr "knihovna SSL nepodporuje CRL certifikáty (soubor \"%s\")\n" + +#: fe-secure-openssl.c:932 +msgid "" +"could not get home directory to locate root certificate file\n" +"Either provide the file or change sslmode to disable server certificate " +"verification.\n" msgstr "" -"veÅ™ejné jméno serveru \"%s\" nesouhlasí s jménem serveru (host name) \"%s\"\n" +"nelze urÄit domácí adresář pro nalezení souboru s koÅ™enovým certifikátem\n" +"BuÄ poskytnÄ›te soubor nebo změňte ssl mód tak, aby neověřoval certifkát " +"serveru.\n" -#: fe-secure.c:975 +#: fe-secure-openssl.c:936 #, c-format -msgid "could not create SSL context: %s\n" -msgstr "nelze vytvoÅ™it SSL kontext: %s\n" +msgid "" +"root certificate file \"%s\" does not exist\n" +"Either provide the file or change sslmode to disable server certificate " +"verification.\n" +msgstr "" +"soubor s koÅ™enovým certifikátem \"%s\" neexistuje\n" +"poskytnÄ›nte soubor nebo zmÄ›ntÄ› ssl mód tak, aby neověřoval certifkát " +"serveru.\n" -#: fe-secure.c:1098 +#: fe-secure-openssl.c:967 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "nelze otevřít soubor s certifikátem \"%s\": %s\n" -#: fe-secure.c:1137 fe-secure.c:1152 +#: fe-secure-openssl.c:986 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "nelze Äíst soubor s certifikátem \"%s\": %s\n" -#: fe-secure.c:1207 +#: fe-secure-openssl.c:1011 +#, c-format +msgid "could not establish SSL connection: %s\n" +msgstr "nelze vytvoÅ™it SSL spojení: %s\n" + +#: fe-secure-openssl.c:1065 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "nelze nahrát SSL engine \"%s\": %s\n" -#: fe-secure.c:1219 +#: fe-secure-openssl.c:1077 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "nelze inicializovat SSL engine \"%s\": %s\n" -#: fe-secure.c:1235 +#: fe-secure-openssl.c:1093 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "nelze Äíst soubor privátního klíÄe \"%s\" z enginu \"%s\": %s\n" -#: fe-secure.c:1249 +#: fe-secure-openssl.c:1107 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "nelze naÄíst soubor privátního klíÄe \"%s\" z enginu \"%s\": %s\n" -#: fe-secure.c:1286 +#: fe-secure-openssl.c:1144 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "certifikát je přítomen, ale soubor privátního klíÄe ne \"%s\"\n" -#: fe-secure.c:1294 +#: fe-secure-openssl.c:1152 #, c-format msgid "" "private key file \"%s\" has group or world access; permissions should be " @@ -963,67 +1152,70 @@ msgstr "" "soubor s privátním klíÄem \"%s\" má povolená přístupová práva pro skupinu " "nebo vÅ¡echny uživatele; práva by mÄ›la být u=rw (0600) nebo přísnÄ›jší\n" -#: fe-secure.c:1305 +#: fe-secure-openssl.c:1163 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "nelze naÄíst soubor privátního klíÄe \"%s\": %s\n" -#: fe-secure.c:1319 +#: fe-secure-openssl.c:1177 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "certifikát nesouhlasí se souborem privátního klíÄe \"%s\": %s\n" -#: fe-secure.c:1357 -#, c-format -msgid "could not read root certificate file \"%s\": %s\n" -msgstr "nelze Äíst soubor s koÅ™enovým certifikátem \"%s\": %s\n" - -#: fe-secure.c:1387 -#, c-format -msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "knihovna SSL nepodporuje CRL certifikáty (file \"%s\")\n" - -#: fe-secure.c:1420 -msgid "" -"could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"nelze urÄit domácí adresář pro nalezení souboru s koÅ™enovým certifikátem\n" -"BuÄ poskytnÄ›te soubor nebo změňte ssl mód tak, aby neověřoval certifkát " -"serveru.\n" - -#: fe-secure.c:1424 -#, c-format -msgid "" -"root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"soubor s koÅ™enovým certifikátem \"%s\" neexistuje\n" -"poskytnÄ›nte soubor nebo zmÄ›ntÄ› ssl mód tak, aby neověřoval certifkát " -"serveru.\n" - -#: fe-secure.c:1518 +#: fe-secure-openssl.c:1286 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "certifikát nelze získat: %s\n" -#: fe-secure.c:1614 +#: fe-secure-openssl.c:1375 #, c-format msgid "no SSL error reported" msgstr "žádný chybový kód SSL nebyl hlášený" -#: fe-secure.c:1623 +#: fe-secure-openssl.c:1384 #, c-format msgid "SSL error code %lu" msgstr "SSL chybový kód %lu" -#: win32.c:322 +#: fe-secure.c:269 +#, c-format +msgid "could not receive data from server: %s\n" +msgstr "nelze pÅ™ijmout data ze serveru: %s\n" + +#: fe-secure.c:378 +#, c-format +msgid "could not send data to server: %s\n" +msgstr "nelze poslat data na server: %s\n" + +#: win32.c:317 #, c-format msgid "unrecognized socket error: 0x%08X/%d" msgstr "neznámá chyba socketu: 0x%08X/%d" +#~ msgid "could not set socket to blocking mode: %s\n" +#~ msgstr "nelze nastavit soket do blokujícího módu: %s\n" + +#~ msgid "Kerberos 5 authentication rejected: %*s\n" +#~ msgstr "Kerberos 5 autentizace odmítnuta: %*s\n" + +#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPIDLE) selhalo: %s\n" + +#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPALIVE) selhalo: %s\n" + +#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPINTVL) selhalo: %s\n" + +#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(SO_KEEPALIVE) selhalo: %s\n" + +#~ msgid "could not get home directory to locate service definition file" +#~ msgstr "nelze získat domovský adresář pro nalezení koÅ™enového certifikátu" + +#~ msgid "socket not open\n" +#~ msgstr "soket není otevÅ™en\n" + #~ msgid "unrecognized return value from row processor" #~ msgstr "nerozpoznaná návratová hodnota z processoru řádek" diff --git a/src/interfaces/libpq/po/de.po b/src/interfaces/libpq/po/de.po index 738a88f0eed..b5beaef87e8 100644 --- a/src/interfaces/libpq/po/de.po +++ b/src/interfaces/libpq/po/de.po @@ -1,14 +1,14 @@ # German message translation file for libpq -# Peter Eisentraut , 2001 - 2017. +# Peter Eisentraut , 2001 - 2018. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" +"Project-Id-Version: PostgreSQL 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 16:38+0000\n" -"PO-Revision-Date: 2017-08-04 17:31-0400\n" +"POT-Creation-Date: 2018-08-30 06:38+0000\n" +"PO-Revision-Date: 2018-08-30 09:11+0200\n" "Last-Translator: Peter Eisentraut \n" "Language-Team: German \n" "Language: de\n" @@ -16,73 +16,73 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: fe-auth-scram.c:176 +#: fe-auth-scram.c:189 msgid "malformed SCRAM message (empty message)\n" msgstr "fehlerhafte SCRAM-Nachricht (leere Nachricht)\n" -#: fe-auth-scram.c:182 +#: fe-auth-scram.c:195 msgid "malformed SCRAM message (length mismatch)\n" msgstr "fehlerhafte SCRAM-Nachricht (Länge stimmt nicht überein)\n" -#: fe-auth-scram.c:231 -msgid "invalid server signature\n" -msgstr "ungültige Serversignatur\n" +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "falsche Serversignatur\n" -#: fe-auth-scram.c:240 +#: fe-auth-scram.c:253 msgid "invalid SCRAM exchange state\n" msgstr "ungültiger Zustand des SCRAM-Austauschs\n" -#: fe-auth-scram.c:263 +#: fe-auth-scram.c:276 #, c-format -msgid "malformed SCRAM message (%c expected)\n" -msgstr "" +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "fehlerhafte SCRAM-Nachricht (Attribut »%c« erwartet)\n" -#: fe-auth-scram.c:272 +#: fe-auth-scram.c:285 #, c-format -msgid "malformed SCRAM message (expected = in attr '%c')\n" -msgstr "" +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "fehlerhafte SCRAM-Nachricht (Zeichen »=« für Attribut »%c« erwartet)\n" -#: fe-auth-scram.c:311 -msgid "failed to generate nonce\n" +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" msgstr "konnte Nonce nicht erzeugen\n" -#: fe-auth-scram.c:319 fe-auth-scram.c:336 fe-auth-scram.c:346 -#: fe-auth-scram.c:400 fe-auth-scram.c:420 fe-auth-scram.c:445 -#: fe-auth-scram.c:459 fe-auth-scram.c:501 fe-auth.c:227 fe-auth.c:362 -#: fe-auth.c:432 fe-auth.c:467 fe-auth.c:609 fe-auth.c:768 fe-auth.c:1080 -#: fe-auth.c:1228 fe-connect.c:775 fe-connect.c:1203 fe-connect.c:1379 -#: fe-connect.c:1947 fe-connect.c:2476 fe-connect.c:4062 fe-connect.c:4314 -#: fe-connect.c:4433 fe-connect.c:4673 fe-connect.c:4753 fe-connect.c:4852 -#: fe-connect.c:5108 fe-connect.c:5137 fe-connect.c:5209 fe-connect.c:5233 -#: fe-connect.c:5251 fe-connect.c:5352 fe-connect.c:5361 fe-connect.c:5717 -#: fe-connect.c:5867 fe-exec.c:2651 fe-exec.c:3398 fe-exec.c:3563 -#: fe-lobj.c:896 fe-protocol2.c:1206 fe-protocol3.c:992 fe-protocol3.c:1678 -#: fe-secure-openssl.c:514 fe-secure-openssl.c:1138 +#: fe-auth-scram.c:334 fe-auth-scram.c:401 fe-auth-scram.c:523 +#: fe-auth-scram.c:543 fe-auth-scram.c:569 fe-auth-scram.c:583 +#: fe-auth-scram.c:625 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:643 fe-auth.c:802 fe-auth.c:1114 fe-auth.c:1262 fe-connect.c:835 +#: fe-connect.c:1264 fe-connect.c:1440 fe-connect.c:1922 fe-connect.c:1945 +#: fe-connect.c:2606 fe-connect.c:4152 fe-connect.c:4404 fe-connect.c:4523 +#: fe-connect.c:4773 fe-connect.c:4853 fe-connect.c:4952 fe-connect.c:5208 +#: fe-connect.c:5237 fe-connect.c:5309 fe-connect.c:5333 fe-connect.c:5351 +#: fe-connect.c:5452 fe-connect.c:5461 fe-connect.c:5817 fe-connect.c:5967 +#: fe-exec.c:2702 fe-exec.c:3449 fe-exec.c:3614 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1685 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 msgid "out of memory\n" msgstr "Speicher aufgebraucht\n" -#: fe-auth-scram.c:437 +#: fe-auth-scram.c:561 msgid "invalid SCRAM response (nonce mismatch)\n" msgstr "ungültige SCRAM-Antwort (Nonce stimmt nicht überein)\n" -#: fe-auth-scram.c:476 +#: fe-auth-scram.c:600 msgid "malformed SCRAM message (invalid iteration count)\n" -msgstr "" +msgstr "fehlerhafte SCRAM-Nachricht (ungültige Iterationszahl)\n" -#: fe-auth-scram.c:482 +#: fe-auth-scram.c:606 msgid "malformed SCRAM message (garbage at end of server-first-message)\n" -msgstr "" +msgstr "fehlerhafte SCRAM-Nachricht (Müll am Ende der »server-first-message«)\n" -#: fe-auth-scram.c:511 +#: fe-auth-scram.c:636 #, c-format -msgid "error received from server in SASL exchange: %s\n" -msgstr "Fehler vom Server empfangen im SASL-Austausch: %s\n" +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "Fehler vom Server empfangen im SCRAM-Austausch: %s\n" -#: fe-auth-scram.c:526 +#: fe-auth-scram.c:652 msgid "malformed SCRAM message (garbage at end of server-final-message)\n" -msgstr "" +msgstr "fehlerhafte SCRAM-Nachricht (Müll am Ende der »server-final-message«)\n" -#: fe-auth-scram.c:534 +#: fe-auth-scram.c:660 msgid "malformed SCRAM message (invalid server signature)\n" msgstr "fehlerhafte SCRAM-Nachricht (ungültige Serversignatur)\n" @@ -95,7 +95,7 @@ msgstr "Speicher aufgebraucht beim Anlegen des GSSAPI-Puffers (%d)\n" msgid "GSSAPI continuation error" msgstr "GSSAPI-Fortsetzungsfehler" -#: fe-auth.c:207 fe-auth.c:461 +#: fe-auth.c:207 fe-auth.c:461 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "Hostname muss angegeben werden\n" @@ -124,115 +124,115 @@ msgstr "doppelte SSPI-Authentifizierungsanfrage\n" msgid "could not acquire SSPI credentials" msgstr "konnte SSPI-Credentials nicht erhalten" -#: fe-auth.c:500 +#: fe-auth.c:501 msgid "duplicate SASL authentication request\n" msgstr "doppelte SASL-Authentifizierungsanfrage\n" -#: fe-auth.c:560 +#: fe-auth.c:549 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "Server hat Authentifizierung mit SCRAM-SHA-256-PLUS über eine Verbindung ohne SSL angeboten\n" + +#: fe-auth.c:561 msgid "none of the server's SASL authentication mechanisms are supported\n" msgstr "keine der SASL-Authentifizierungsmechanismen des Servers werden unterstützt\n" -#: fe-auth.c:633 +#: fe-auth.c:667 #, c-format msgid "out of memory allocating SASL buffer (%d)\n" msgstr "Speicher aufgebraucht beim Anlegen des SASL-Puffers (%d)\n" -#: fe-auth.c:658 +#: fe-auth.c:692 msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" msgstr "AuthenticationSASLFinal vom Server empfangen, aber SASL-Authentifizierung war noch nicht abgeschlossen\n" -#: fe-auth.c:735 +#: fe-auth.c:769 msgid "SCM_CRED authentication method not supported\n" msgstr "SCM_CRED-Authentifizierungsmethode nicht unterstützt\n" -#: fe-auth.c:826 +#: fe-auth.c:860 msgid "Kerberos 4 authentication not supported\n" msgstr "Authentifizierung mit Kerberos 4 nicht unterstützt\n" -#: fe-auth.c:831 +#: fe-auth.c:865 msgid "Kerberos 5 authentication not supported\n" msgstr "Authentifizierung mit Kerberos 5 nicht unterstützt\n" -#: fe-auth.c:902 +#: fe-auth.c:936 msgid "GSSAPI authentication not supported\n" msgstr "Authentifizierung mit GSSAPI nicht unterstützt\n" -#: fe-auth.c:934 +#: fe-auth.c:968 msgid "SSPI authentication not supported\n" msgstr "Authentifizierung mit SSPI nicht unterstützt\n" -#: fe-auth.c:942 +#: fe-auth.c:976 msgid "Crypt authentication not supported\n" msgstr "Authentifizierung mit Crypt nicht unterstützt\n" -#: fe-auth.c:1008 +#: fe-auth.c:1042 #, c-format msgid "authentication method %u not supported\n" msgstr "Authentifizierungsmethode %u nicht unterstützt\n" -#: fe-auth.c:1055 +#: fe-auth.c:1089 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "Fehler beim Nachschlagen des Benutzernamens: Fehlercode %lu\n" -#: fe-auth.c:1065 fe-connect.c:2403 +#: fe-auth.c:1099 fe-connect.c:2533 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "konnte lokale Benutzer-ID %d nicht nachschlagen: %s\n" -#: fe-auth.c:1070 fe-connect.c:2408 +#: fe-auth.c:1104 fe-connect.c:2538 #, c-format msgid "local user with ID %d does not exist\n" msgstr "lokaler Benutzer mit ID %d existiert nicht\n" -#: fe-auth.c:1172 +#: fe-auth.c:1206 msgid "unexpected shape of result set returned for SHOW\n" msgstr "unerwartete Form der Ergebnismenge von SHOW\n" -#: fe-auth.c:1181 +#: fe-auth.c:1215 msgid "password_encryption value too long\n" msgstr "Wert von password_encryption ist zu lang\n" -#: fe-auth.c:1221 +#: fe-auth.c:1255 #, c-format msgid "unrecognized password encryption algorithm \"%s\"\n" msgstr "unbekannter Passwortverschlüsselungsalgorithmus »%s«\n" -#: fe-connect.c:968 +#: fe-connect.c:1018 #, c-format -msgid "could not match %d host names to %d hostaddrs\n" +msgid "could not match %d host names to %d hostaddr values\n" msgstr "fehlerhafte Angabe: %d Hostnamen und %d hostaddr-Angaben\n" -#: fe-connect.c:1025 +#: fe-connect.c:1094 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "fehlerhafte Angabe: %d Portnummern und %d Hosts\n" -#: fe-connect.c:1077 -msgid "could not get home directory to locate password file\n" -msgstr "konnte Home-Verzeichnis nicht ermitteln, um Passwortdatei zu finden\n" - -#: fe-connect.c:1129 +#: fe-connect.c:1190 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "ungültiger sslmode-Wert: »%s«\n" -#: fe-connect.c:1150 +#: fe-connect.c:1211 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "sslmode-Wert »%s« ist ungültig, wenn SSL-Unterstützung nicht einkompiliert worden ist\n" -#: fe-connect.c:1185 +#: fe-connect.c:1246 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "ungültiger target_session_attrs-Wert: »%s«\n" -#: fe-connect.c:1403 +#: fe-connect.c:1464 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "konnte Socket nicht auf TCP »No Delay«-Modus umstellen: %s\n" -#: fe-connect.c:1433 +#: fe-connect.c:1494 #, c-format msgid "" "could not connect to server: %s\n" @@ -243,7 +243,7 @@ msgstr "" "\tLäuft der Server lokal und akzeptiert er Verbindungen\n" "\tauf dem Unix-Domain-Socket »%s«?\n" -#: fe-connect.c:1491 +#: fe-connect.c:1552 #, c-format msgid "" "could not connect to server: %s\n" @@ -254,7 +254,7 @@ msgstr "" "\tLäuft der Server auf dem Host »%s« (%s) und akzeptiert er\n" "\tTCP/IP-Verbindungen auf Port %s?\n" -#: fe-connect.c:1500 +#: fe-connect.c:1561 #, c-format msgid "" "could not connect to server: %s\n" @@ -265,492 +265,507 @@ msgstr "" "\tLäuft der Server auf dem Host »%s« und akzeptiert er\n" "\tTCP/IP-Verbindungen auf Port %s?\n" -#: fe-connect.c:1551 fe-connect.c:1583 fe-connect.c:1616 fe-connect.c:2175 +#: fe-connect.c:1612 fe-connect.c:1644 fe-connect.c:1677 fe-connect.c:2325 #, c-format msgid "setsockopt(%s) failed: %s\n" msgstr "setsockopt(%s) fehlgeschlagen: %s\n" -#: fe-connect.c:1665 +#: fe-connect.c:1726 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) fehlgeschlagen: %ui\n" -#: fe-connect.c:1722 +#: fe-connect.c:2035 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "ungültiger Verbindungszustand, möglicherweise ein Speicherproblem\n" + +#: fe-connect.c:2101 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "ungültige Portnummer: »%s«\n" -#: fe-connect.c:1738 +#: fe-connect.c:2117 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "konnte Hostnamen »%s« nicht in Adresse übersetzen: %s\n" -#: fe-connect.c:1747 +#: fe-connect.c:2130 #, c-format msgid "could not parse network address \"%s\": %s\n" msgstr "konnte Netzwerkadresse »%s« nicht interpretieren: %s\n" -#: fe-connect.c:1758 +#: fe-connect.c:2143 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "Unix-Domain-Socket-Pfad »%s« ist zu lang (maximal %d Bytes)\n" -#: fe-connect.c:1772 +#: fe-connect.c:2158 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "konnte Unix-Domain-Socket-Pfad »%s« nicht in Adresse übersetzen: %s\n" -#: fe-connect.c:2053 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "ungültiger Verbindungszustand, möglicherweise ein Speicherproblem\n" - -#: fe-connect.c:2110 +#: fe-connect.c:2262 #, c-format msgid "could not create socket: %s\n" msgstr "konnte Socket nicht erzeugen: %s\n" -#: fe-connect.c:2132 +#: fe-connect.c:2284 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "konnte Socket nicht auf nicht-blockierenden Modus umstellen: %s\n" -#: fe-connect.c:2143 +#: fe-connect.c:2294 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "konnte Socket nicht auf »Close on exec«-Modus umstellen: %s\n" -#: fe-connect.c:2162 +#: fe-connect.c:2312 msgid "keepalives parameter must be an integer\n" msgstr "Parameter »keepalives« muss eine ganze Zahl sein\n" -#: fe-connect.c:2313 +#: fe-connect.c:2450 #, c-format msgid "could not get socket error status: %s\n" msgstr "konnte Socket-Fehlerstatus nicht ermitteln: %s\n" -#: fe-connect.c:2348 +#: fe-connect.c:2478 #, c-format msgid "could not get client address from socket: %s\n" msgstr "konnte Client-Adresse vom Socket nicht ermitteln: %s\n" -#: fe-connect.c:2390 +#: fe-connect.c:2520 msgid "requirepeer parameter is not supported on this platform\n" msgstr "Parameter »requirepeer« wird auf dieser Plattform nicht unterstützt\n" -#: fe-connect.c:2393 +#: fe-connect.c:2523 #, c-format msgid "could not get peer credentials: %s\n" msgstr "konnte Credentials von Gegenstelle nicht ermitteln: %s\n" -#: fe-connect.c:2416 +#: fe-connect.c:2546 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeer gibt »%s« an, aber tatsächlicher Benutzername der Gegenstelle ist »%s«\n" -#: fe-connect.c:2450 +#: fe-connect.c:2580 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "konnte Paket zur SSL-Verhandlung nicht senden: %s\n" -#: fe-connect.c:2489 +#: fe-connect.c:2619 #, c-format msgid "could not send startup packet: %s\n" msgstr "konnte Startpaket nicht senden: %s\n" -#: fe-connect.c:2559 +#: fe-connect.c:2689 msgid "server does not support SSL, but SSL was required\n" msgstr "Server unterstützt kein SSL, aber SSL wurde verlangt\n" -#: fe-connect.c:2585 +#: fe-connect.c:2715 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "ungültige Antwort auf SSL-Verhandlungspaket empfangen: %c\n" -#: fe-connect.c:2661 fe-connect.c:2694 +#: fe-connect.c:2792 fe-connect.c:2825 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "Authentifizierungsanfrage wurde vom Server erwartet, aber %c wurde empfangen\n" -#: fe-connect.c:2923 +#: fe-connect.c:3052 msgid "unexpected message from server during startup\n" msgstr "unerwartete Nachricht vom Server beim Start\n" -#: fe-connect.c:3141 +#: fe-connect.c:3282 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "konnte keine schreibbare Verbindung zum Server »%s:%s« aufbauen\n" -#: fe-connect.c:3190 +#: fe-connect.c:3328 #, c-format msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" msgstr "Test »SHOW transaction_read_only« fehlgeschlagen auf Server »%s:%s«\n" -#: fe-connect.c:3211 +#: fe-connect.c:3343 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "ungültiger Verbindungszustand %d, möglicherweise ein Speicherproblem\n" -#: fe-connect.c:3668 fe-connect.c:3728 +#: fe-connect.c:3758 fe-connect.c:3818 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc »%s« während PGEVT_CONNRESET-Ereignis fehlgeschlagen\n" -#: fe-connect.c:4075 +#: fe-connect.c:4165 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "ungültige LDAP-URL »%s«: Schema muss ldap:// sein\n" -#: fe-connect.c:4090 +#: fe-connect.c:4180 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "ungültige LDAP-URL »%s«: Distinguished Name fehlt\n" -#: fe-connect.c:4101 fe-connect.c:4154 +#: fe-connect.c:4191 fe-connect.c:4244 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "ungültige LDAP-URL »%s«: muss genau ein Attribut haben\n" -#: fe-connect.c:4111 fe-connect.c:4168 +#: fe-connect.c:4201 fe-connect.c:4258 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "ungültige LDAP-URL »%s«: Suchbereich fehlt (base/one/sub)\n" -#: fe-connect.c:4122 +#: fe-connect.c:4212 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "ungültige LDAP-URL »%s«: kein Filter\n" -#: fe-connect.c:4143 +#: fe-connect.c:4233 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "ungültige LDAP-URL »%s«: ungültige Portnummer\n" -#: fe-connect.c:4177 +#: fe-connect.c:4267 msgid "could not create LDAP structure\n" msgstr "konnte LDAP-Struktur nicht erzeugen\n" -#: fe-connect.c:4253 +#: fe-connect.c:4343 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "Suche auf LDAP-Server fehlgeschlagen: %s\n" -#: fe-connect.c:4264 +#: fe-connect.c:4354 msgid "more than one entry found on LDAP lookup\n" msgstr "LDAP-Suche ergab mehr als einen Eintrag\n" -#: fe-connect.c:4265 fe-connect.c:4277 +#: fe-connect.c:4355 fe-connect.c:4367 msgid "no entry found on LDAP lookup\n" msgstr "kein Eintrag gefunden bei LDAP-Suche\n" -#: fe-connect.c:4288 fe-connect.c:4301 +#: fe-connect.c:4378 fe-connect.c:4391 msgid "attribute has no values on LDAP lookup\n" msgstr "Attribut hat keine Werte bei LDAP-Suche\n" -#: fe-connect.c:4353 fe-connect.c:4372 fe-connect.c:4891 +#: fe-connect.c:4443 fe-connect.c:4462 fe-connect.c:4991 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "fehlendes »=« nach »%s« in der Zeichenkette der Verbindungsdaten\n" -#: fe-connect.c:4445 fe-connect.c:5076 fe-connect.c:5850 +#: fe-connect.c:4535 fe-connect.c:5176 fe-connect.c:5950 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "ungültige Verbindungsoption »%s«\n" -#: fe-connect.c:4461 fe-connect.c:4940 +#: fe-connect.c:4551 fe-connect.c:5040 msgid "unterminated quoted string in connection info string\n" msgstr "fehlendes schließendes Anführungszeichen (\") in der Zeichenkette der Verbindungsdaten\n" -#: fe-connect.c:4501 -msgid "could not get home directory to locate service definition file" -msgstr "konnte Home-Verzeichnis nicht ermitteln, um Servicedefinitionsdatei zu finden" - -#: fe-connect.c:4534 +#: fe-connect.c:4634 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "Definition von Service »%s« nicht gefunden\n" -#: fe-connect.c:4557 +#: fe-connect.c:4657 #, c-format msgid "service file \"%s\" not found\n" msgstr "Servicedatei »%s« nicht gefunden\n" -#: fe-connect.c:4570 +#: fe-connect.c:4670 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "Zeile %d zu lang in Servicedatei »%s«\n" -#: fe-connect.c:4641 fe-connect.c:4685 +#: fe-connect.c:4741 fe-connect.c:4785 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "Syntaxfehler in Servicedatei »%s«, Zeile %d\n" -#: fe-connect.c:4652 +#: fe-connect.c:4752 #, c-format msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "geschachtelte »service«-Definitionen werden nicht unterstützt in Servicedatei »%s«, Zeile %d\n" -#: fe-connect.c:5372 +#: fe-connect.c:5472 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "ungültige URI an interne Parserroutine weitergeleitet: »%s«\n" -#: fe-connect.c:5449 +#: fe-connect.c:5549 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "Ende der Eingabezeichenkette gefunden beim Suchen nach passendem »]« in IPv6-Hostadresse in URI: »%s«\n" -#: fe-connect.c:5456 +#: fe-connect.c:5556 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "IPv6-Hostadresse darf nicht leer sein in URI: »%s«\n" -#: fe-connect.c:5471 +#: fe-connect.c:5571 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" msgstr "unerwartetes Zeichen »%c« an Position %d in URI (»:« oder »/« erwartet): »%s«\n" -#: fe-connect.c:5600 +#: fe-connect.c:5700 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "zusätzliches Schlüssel/Wert-Trennzeichen »=« in URI-Query-Parameter: »%s«\n" -#: fe-connect.c:5620 +#: fe-connect.c:5720 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "fehlendes Schlüssel/Wert-Trennzeichen »=« in URI-Query-Parameter: »%s«\n" -#: fe-connect.c:5671 +#: fe-connect.c:5771 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "ungültiger URI-Query-Parameter: »%s«\n" -#: fe-connect.c:5745 +#: fe-connect.c:5845 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "ungültiges Prozent-kodiertes Token: »%s«\n" -#: fe-connect.c:5755 +#: fe-connect.c:5855 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "verbotener Wert %%00 in Prozent-kodiertem Wert: »%s«\n" -#: fe-connect.c:6100 +#: fe-connect.c:6201 msgid "connection pointer is NULL\n" msgstr "Verbindung ist ein NULL-Zeiger\n" -#: fe-connect.c:6398 +#: fe-connect.c:6499 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "WARNUNG: Passwortdatei »%s« ist keine normale Datei\n" -#: fe-connect.c:6407 +#: fe-connect.c:6508 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "WARNUNG: Passwortdatei »%s« erlaubt Lesezugriff für Gruppe oder Andere; Rechte sollten u=rw (0600) oder weniger sein\n" -#: fe-connect.c:6499 +#: fe-connect.c:6602 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "Passwort wurde aus Datei »%s« gelesen\n" -#: fe-exec.c:826 +#: fe-exec.c:437 fe-exec.c:2776 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "Zeilennummer %d ist außerhalb des zulässigen Bereichs 0..%d" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "Speicher aufgebraucht" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "HINWEIS" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult kann nicht mehr als INT_MAX Tupel enthalten" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "Überlauf von size_t" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "Befehlszeichenkette ist ein NULL-Zeiger\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "Anzahl der Parameter muss zwischen 0 und 65535 sein\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "Anweisungsname ist ein NULL-Zeiger\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2390 msgid "function requires at least protocol version 3.0\n" msgstr "Funktion erfordert mindestens Protokollversion 3.0\n" -#: fe-exec.c:1377 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "keine Verbindung mit dem Server\n" -#: fe-exec.c:1384 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "ein anderer Befehl ist bereits in Ausführung\n" -#: fe-exec.c:1498 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "für binäre Parameter muss eine Länge angegeben werden\n" -#: fe-exec.c:1770 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "unerwarteter asyncStatus: %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc »%s« während PGEVT_RESULTCREATE-Ereignis fehlgeschlagen\n" -#: fe-exec.c:1950 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "COPY von neuem PQexec beendet" -#: fe-exec.c:1958 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "COPY-IN-Zustand muss erst beendet werden\n" -#: fe-exec.c:1978 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "COPY-OUT-Zustand muss erst beendet werden\n" -#: fe-exec.c:1986 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec ist während COPY BOTH nicht erlaubt\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2280 fe-exec.c:2347 fe-exec.c:2437 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "keine COPY in Ausführung\n" -#: fe-exec.c:2576 +#: fe-exec.c:2627 msgid "connection in wrong state\n" msgstr "Verbindung im falschen Zustand\n" -#: fe-exec.c:2607 +#: fe-exec.c:2658 msgid "invalid ExecStatusType code" msgstr "ungültiger ExecStatusType-Kode" -#: fe-exec.c:2634 +#: fe-exec.c:2685 msgid "PGresult is not an error result\n" msgstr "PGresult ist kein Fehlerresultat\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2760 fe-exec.c:2783 #, c-format msgid "column number %d is out of range 0..%d" msgstr "Spaltennummer %d ist außerhalb des zulässigen Bereichs 0..%d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "Zeilennummer %d ist außerhalb des zulässigen Bereichs 0..%d" - -#: fe-exec.c:2747 +#: fe-exec.c:2798 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "Parameternummer %d ist außerhalb des zulässigen Bereichs 0..%d" -#: fe-exec.c:3057 +#: fe-exec.c:3108 #, c-format msgid "could not interpret result from server: %s" msgstr "konnte Ergebnis vom Server nicht interpretieren: %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3347 fe-exec.c:3431 msgid "incomplete multibyte character\n" msgstr "unvollständiges Mehrbyte-Zeichen\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "kann OID der Funktion lo_truncate nicht ermitteln\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "Argument von lo_truncate überschreitet Bereich für ganze Zahlen\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "kann OID der Funktion lo_truncate64 nicht ermitteln\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "Argument von lo_read überschreitet Bereich für ganze Zahlen\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "Argument von lo_write überschreitet Bereich für ganze Zahlen\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "kann OID der Funktion lo_lseek64 nicht ermitteln\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "kann OID der Funktion lo_create nicht ermitteln\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "kann OID der Funktion lo_tell64 nicht ermitteln\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "konnte Datei »%s« nicht öffnen: %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" -msgstr "konnte nicht aus Datei »%s« nicht lesen: %s\n" +msgstr "konnte nicht aus Datei »%s« lesen: %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "konnte nicht in Datei »%s« schreiben: %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "Abfrage zur Initialisierung der Large-Object-Funktionen ergab keine Daten\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "kann OID der Funktion lo_open nicht ermitteln\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "kann OID der Funktion lo_close nicht ermitteln\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "kann OID der Funktion lo_creat nicht ermitteln\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "kann OID der Funktion lo_unlink nicht ermitteln\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "kann OID der Funktion lo_lseek nicht ermitteln\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "kann OID der Funktion lo_tell nicht ermitteln\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "kann OID der Funktion loread nicht ermitteln\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "kann OID der Funktion lowrite nicht ermitteln\n" -#: fe-misc.c:292 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "Integer der Größe %lu wird von pqGetInt nicht unterstützt" -#: fe-misc.c:328 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "Integer der Größe %lu wird von pqPutInt nicht unterstützt" -#: fe-misc.c:639 fe-misc.c:840 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "Verbindung nicht offen\n" -#: fe-misc.c:809 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -760,255 +775,257 @@ msgstr "" "\tDas heißt wahrscheinlich, dass der Server abnormal beendete\n" "\tbevor oder während die Anweisung bearbeitet wurde.\n" -#: fe-misc.c:1011 +#: fe-misc.c:1009 msgid "timeout expired\n" msgstr "Timeout abgelaufen\n" -#: fe-misc.c:1056 +#: fe-misc.c:1054 msgid "invalid socket\n" msgstr "ungültiges Socket\n" -#: fe-misc.c:1079 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "select() fehlgeschlagen: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "ungültiger Setenv-Zustand %c, möglicherweise ein Speicherproblem\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "ungültiger Zustand %c, möglicherweise ein Speicherproblem\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "Nachricht vom Typ 0x%02x kam vom Server im Ruhezustand" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 -#: fe-protocol3.c:209 fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 -#: fe-protocol3.c:728 fe-protocol3.c:951 -msgid "out of memory" -msgstr "Speicher aufgebraucht" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "unerwartetes Zeichen %c kam nach Antwort auf leere Anfrage (»I«-Nachricht)" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "Server sendete Daten (»D«-Nachricht) ohne vorherige Zeilenbeschreibung (»T«-Nachricht)" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" msgstr "Server sendete binäre Daten (»B«-Nachricht) ohne vorherige Zeilenbeschreibung (»T«-Nachricht)" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "unerwartete Antwort vom Server; erstes empfangenes Zeichen war »%c«\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "Speicher für Anfrageergebnis aufgebraucht" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "Synchronisation mit Server verloren, Verbindung wird zurückgesetzt" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "Protokollfehler: id=0x%x\n" -#: fe-protocol3.c:368 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" msgstr "Server sendete Daten (»D«-Nachricht) ohne vorherige Zeilenbeschreibung (»T«-Nachricht)\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "Nachrichteninhalt stimmt nicht mit Länge in Nachrichtentyp »%c« überein\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "Synchronisation mit Server verloren: Nachrichtentyp »%c« empfangen, Länge %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "nicht genug Daten in »T«-Nachricht" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "zu viele Daten in »T«-Nachricht" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "zu viele Daten in »t«-Nachricht" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "nicht genug Daten in »D«-Nachricht" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "unerwartete Feldzahl in »D«-Nachricht" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "zu viele Daten in »D«-Nachricht" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "keine Fehlermeldung verfügbar\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" msgstr " bei Zeichen %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "DETAIL: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "TIP: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "ANFRAGE: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "KONTEXT: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1096 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "SCHEMANAME: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1100 #, c-format msgid "TABLE NAME: %s\n" msgstr "TABELLENNAME: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1104 #, c-format msgid "COLUMN NAME: %s\n" msgstr "SPALTENNAME: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "DATENTYPNAME: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1112 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "CONSTRAINT-NAME: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "ORT: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "ZEILE %d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: Text COPY OUT nicht ausgeführt\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1323 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "Name im SSL-Zertifikat enthält Null-Byte\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "Hostname muss angegeben werden für eine verifizierte SSL-Verbindung\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "Server-Zertifikat für »%s« stimmt nicht mit dem Hostnamen »%s« überein\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "konnte Hostnamen des Servers nicht aus dem Serverzertifikat ermitteln\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL-SYSCALL-Fehler: %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1327 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL-SYSCALL-Fehler: Dateiende entdeckt\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1336 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSL-Fehler: %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL-Verbindung wurde unerwartet geschlossen\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1345 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "unbekannter SSL-Fehlercode: %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "Namenseintrag fehlt im SSL-Zertifikat\n" - -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "Name im SSL-Zertifikat enthält Null-Byte\n" - -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "Hostname muss angegeben werden für eine verifizierte SSL-Verbindung\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "konnte Signaturalgorithmus des Serverzertifikats nicht ermitteln\n" -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "Server-Zertifikat für »%s« stimmt nicht mit dem Hostnamen »%s« überein\n" +msgid "could not find digest for NID %s\n" +msgstr "konnte Digest für NID %s nicht finden\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "konnte Hostnamen des Servers nicht aus dem Serverzertifikat ermitteln\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "konnte Hash des Zertifikats der Gegenstelle nicht erzeugen\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "Namenseintrag fehlt im SSL-Zertifikat\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "konnte SSL-Kontext nicht erzeugen: %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "konnte Root-Zertifikat-Datei »%s« nicht lesen: %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" msgstr "SSL-Bibliothek unterstützt keine CRL-Zertifikate (Datei »%s«)\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate verification.\n" @@ -1016,7 +1033,7 @@ msgstr "" "konnte Home-Verzeichnis nicht ermitteln, um Root-Zertifikat-Datei zu finden\n" "Legen Sie entweder die Datei an oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1025,82 +1042,82 @@ msgstr "" "Root-Zertifikat-Datei »%s« existiert nicht\n" "Legen Sie entweder die Datei an oder ändern Sie sslmode, um die Überprüfung der Serverzertifikate abzuschalten.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "konnte Zertifikatdatei »%s« nicht öffnen: %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "konnte Zertifikatdatei »%s« nicht lesen: %s\n" -#: fe-secure-openssl.c:1100 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "konnte SSL-Verbindung nicht aufbauen: %s\n" -#: fe-secure-openssl.c:1154 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "konnte SSL-Engine »%s« nicht laden: %s\n" -#: fe-secure-openssl.c:1166 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "konnte SSL-Engine »%s« nicht initialisieren: %s\n" -#: fe-secure-openssl.c:1182 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« lesen: %s\n" -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "konnte privaten SSL-Schlüssel »%s« nicht von Engine »%s« laden: %s\n" -#: fe-secure-openssl.c:1233 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "Zertifikat vorhanden, aber keine private Schlüsseldatei »%s«\n" -#: fe-secure-openssl.c:1241 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "WARNUNG: private Schlüsseldatei »%s« erlaubt Lesezugriff für Gruppe oder Andere; Rechte sollten u=rw (0600) oder weniger sein\n" -#: fe-secure-openssl.c:1252 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "konnte private Schlüsseldatei »%s« nicht laden: %s\n" -#: fe-secure-openssl.c:1266 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "Zertifikat passt nicht zur privaten Schlüsseldatei »%s«: %s\n" -#: fe-secure-openssl.c:1366 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "Zertifikat konnte nicht ermittelt werden: %s\n" -#: fe-secure-openssl.c:1458 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "kein SSL-Fehler berichtet" -#: fe-secure-openssl.c:1467 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSL-Fehlercode %lu" -#: fe-secure.c:261 +#: fe-secure.c:269 #, c-format msgid "could not receive data from server: %s\n" msgstr "konnte keine Daten vom Server empfangen: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:378 #, c-format msgid "could not send data to server: %s\n" msgstr "konnte keine Daten an den Server senden: %s\n" diff --git a/src/interfaces/libpq/po/es.po b/src/interfaces/libpq/po/es.po index 7e335da1f29..9c07468fa4e 100644 --- a/src/interfaces/libpq/po/es.po +++ b/src/interfaces/libpq/po/es.po @@ -1,186 +1,249 @@ # Spanish message translation file for libpq 2013-08-30 12:42-0400\n" # -# Copyright (C) 2002-2013 PostgreSQL Global Development Group +# Copyright (c) 2002-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Karim , 2002. # Alvaro Herrera , 2003-2013 # Mario González , 2005 +# Carlos Chapi , 2017, 2018 # msgid "" msgstr "" -"Project-Id-Version: libpq (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-10 20:38+0000\n" -"PO-Revision-Date: 2017-07-11 11:22-0500\n" -"Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Project-Id-Version: libpq (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:09+0000\n" +"PO-Revision-Date: 2019-06-06 17:21-0400\n" +"Last-Translator: Carlos Chapi \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: BlackCAT 1.0\n" + +#: fe-auth-scram.c:183 +msgid "malformed SCRAM message (empty message)\n" +msgstr "mensaje SCRAM no es válido (mensaje vacío)\n" + +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "mensaje SCRAM no es válido (longitud no coincide)\n" + +#: fe-auth-scram.c:238 +msgid "incorrect server signature\n" +msgstr "signatura de servidor incorrecta\n" + +#: fe-auth-scram.c:247 +msgid "invalid SCRAM exchange state\n" +msgstr "estado de intercambio SCRAM no es válido\n" + +#: fe-auth-scram.c:270 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "mensaje SCRAM no es válido (se esperaba atributo «%c»)\n" + +#: fe-auth-scram.c:279 +#, c-format +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "mensaje SCRAM no es válido (se esperaba el carácter «=» para el atributo «%c»)\n" + +#: fe-auth-scram.c:320 +msgid "could not generate nonce\n" +msgstr "no se pude generar nonce\n" + +#: fe-auth-scram.c:328 fe-auth-scram.c:395 fe-auth-scram.c:517 +#: fe-auth-scram.c:537 fe-auth-scram.c:563 fe-auth-scram.c:577 +#: fe-auth-scram.c:619 fe-auth.c:290 fe-auth.c:360 fe-auth.c:395 fe-auth.c:581 +#: fe-auth.c:740 fe-auth.c:1052 fe-auth.c:1200 fe-connect.c:858 +#: fe-connect.c:1320 fe-connect.c:1496 fe-connect.c:2085 fe-connect.c:2108 +#: fe-connect.c:2831 fe-connect.c:4513 fe-connect.c:4765 fe-connect.c:4884 +#: fe-connect.c:5134 fe-connect.c:5214 fe-connect.c:5313 fe-connect.c:5569 +#: fe-connect.c:5598 fe-connect.c:5670 fe-connect.c:5694 fe-connect.c:5712 +#: fe-connect.c:5813 fe-connect.c:5822 fe-connect.c:6178 fe-connect.c:6328 +#: fe-exec.c:2748 fe-exec.c:3495 fe-exec.c:3660 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1703 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "memoria agotada\n" + +#: fe-auth-scram.c:555 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "respuesta SCRAM no es válida (nonce no coincide)\n" + +#: fe-auth-scram.c:594 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "mensaje SCRAM no es válido (el conteo de iteración no es válido)\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "mensaje SCRAM no es válido (se encontró basura al final de server-first-message)\n" + +#: fe-auth-scram.c:630 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "se recibió un error desde el servidor durante el intercambio SCRAM: %s\n" + +#: fe-auth-scram.c:646 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "mensaje SCRAM no válido (se encontró basura al final de server-final-message)\n" + +#: fe-auth-scram.c:654 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "mensaje SCRAM no es válido (la signatura del servidor no es válida)\n" -#: fe-auth.c:122 +#: fe-auth.c:77 #, c-format msgid "out of memory allocating GSSAPI buffer (%d)\n" msgstr "memoria agotada creando el búfer GSSAPI (%d)\n" -#: fe-auth.c:177 +#: fe-auth.c:132 msgid "GSSAPI continuation error" msgstr "error en continuación de GSSAPI" -#: fe-auth.c:207 fe-auth.c:461 +#: fe-auth.c:159 fe-auth.c:389 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "el nombre de servidor debe ser especificado\n" -#: fe-auth.c:214 +#: fe-auth.c:166 msgid "duplicate GSS authentication request\n" msgstr "petición de autentificación GSS duplicada\n" -#: fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 fe-auth.c:609 -#: fe-auth.c:768 fe-auth.c:1080 fe-auth.c:1228 fe-connect.c:775 -#: fe-connect.c:1203 fe-connect.c:1379 fe-connect.c:1947 fe-connect.c:2476 -#: fe-connect.c:4062 fe-connect.c:4314 fe-connect.c:4433 fe-connect.c:4673 -#: fe-connect.c:4753 fe-connect.c:4852 fe-connect.c:5108 fe-connect.c:5137 -#: fe-connect.c:5209 fe-connect.c:5233 fe-connect.c:5251 fe-connect.c:5352 -#: fe-connect.c:5361 fe-connect.c:5717 fe-connect.c:5867 fe-exec.c:2651 -#: fe-exec.c:3398 fe-exec.c:3563 fe-lobj.c:896 fe-protocol2.c:1206 -#: fe-protocol3.c:992 fe-protocol3.c:1678 fe-secure-openssl.c:514 -#: fe-secure-openssl.c:1138 -msgid "out of memory\n" -msgstr "memoria agotada\n" - -#: fe-auth.c:240 -msgid "GSSAPI name import error" -msgstr "error en conversión de nombre GSSAPI" - -#: fe-auth.c:303 +#: fe-auth.c:231 #, c-format msgid "out of memory allocating SSPI buffer (%d)\n" msgstr "memoria agotada creando el búfer SSPI (%d)\n" -#: fe-auth.c:351 +#: fe-auth.c:279 msgid "SSPI continuation error" msgstr "error en continuación de SSPI" -#: fe-auth.c:422 +#: fe-auth.c:350 msgid "duplicate SSPI authentication request\n" msgstr "petición de autentificación SSPI duplicada\n" -#: fe-auth.c:447 +#: fe-auth.c:375 msgid "could not acquire SSPI credentials" msgstr "no se pudo obtener las credenciales SSPI" -#: fe-auth.c:500 +#: fe-auth.c:429 msgid "duplicate SASL authentication request\n" msgstr "petición de autentificación SASL duplicada\n" -#: fe-auth.c:560 +#: fe-auth.c:487 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "el servidor ofreció autenticación SCRAM-SHA-256-PLUS sobre una conexión no-SSL\n" + +#: fe-auth.c:499 msgid "none of the server's SASL authentication mechanisms are supported\n" msgstr "ningún método de autentificación SASL del servidor está soportado\n" -#: fe-auth.c:633 +#: fe-auth.c:605 #, c-format msgid "out of memory allocating SASL buffer (%d)\n" msgstr "memoria agotada creando el búfer SASL (%d)\n" -#: fe-auth.c:658 +#: fe-auth.c:630 msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" msgstr "Se recibió AuthenticationSASLFinal desde el servidor, pero la autentificación SASL no se completó\n" -#: fe-auth.c:735 +#: fe-auth.c:707 msgid "SCM_CRED authentication method not supported\n" msgstr "el método de autentificación SCM_CRED no está soportado\n" -#: fe-auth.c:826 +#: fe-auth.c:798 msgid "Kerberos 4 authentication not supported\n" msgstr "el método de autentificación Kerberos 4 no está soportado\n" -#: fe-auth.c:831 +#: fe-auth.c:803 msgid "Kerberos 5 authentication not supported\n" msgstr "el método de autentificación Kerberos 5 no está soportado\n" -#: fe-auth.c:902 +#: fe-auth.c:874 msgid "GSSAPI authentication not supported\n" msgstr "el método de autentificación GSSAPI no está soportado\n" -#: fe-auth.c:934 +#: fe-auth.c:906 msgid "SSPI authentication not supported\n" msgstr "el método de autentificación SSPI no está soportado\n" -#: fe-auth.c:942 +#: fe-auth.c:914 msgid "Crypt authentication not supported\n" msgstr "el método de autentificación Crypt no está soportado\n" -#: fe-auth.c:1008 +#: fe-auth.c:980 #, c-format msgid "authentication method %u not supported\n" msgstr "el método de autentificación %u no está soportado\n" -#: fe-auth.c:1055 +#: fe-auth.c:1027 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "fallo en la búsqueda del nombre de usuario: código de error %lu\n" -#: fe-auth.c:1065 fe-connect.c:2403 +#: fe-auth.c:1037 fe-connect.c:2718 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "no se pudo buscar el usuario local de ID %d: %s\n" -#: fe-auth.c:1070 fe-connect.c:2408 +#: fe-auth.c:1042 fe-connect.c:2723 #, c-format msgid "local user with ID %d does not exist\n" msgstr "no existe un usuario local con ID %d\n" -#: fe-auth.c:1172 +#: fe-auth.c:1144 msgid "unexpected shape of result set returned for SHOW\n" msgstr "SHOW retornó un conjunto de resultados con estructura inesperada\n" -#: fe-auth.c:1181 +#: fe-auth.c:1153 msgid "password_encryption value too long\n" msgstr "el valor para password_encryption es demasiado largo\n" -#: fe-auth.c:1221 +#: fe-auth.c:1193 #, c-format msgid "unrecognized password encryption algorithm \"%s\"\n" msgstr "algoritmo para cifrado de contraseña «%s» desconocido\n" -#: fe-connect.c:968 +#: fe-connect.c:1041 #, c-format -msgid "could not match %d host names to %d hostaddrs\n" +msgid "could not match %d host names to %d hostaddr values\n" msgstr "no se pudo emparejar %d nombres de host a %d direcciones de host\n" -#: fe-connect.c:1025 +#: fe-connect.c:1117 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "no se pudo emparejar %d números de puertos a %d hosts\n" -#: fe-connect.c:1077 -msgid "could not get home directory to locate password file\n" -msgstr "no se pudo obtener el directorio home para localizar el archivo de contraseña\n" - -#: fe-connect.c:1129 +#: fe-connect.c:1213 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "valor sslmode no válido: «%s»\n" -#: fe-connect.c:1150 +#: fe-connect.c:1234 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "el valor sslmode «%s» no es válido cuando no se ha compilado con soporte SSL\n" -#: fe-connect.c:1185 +#: fe-connect.c:1258 +#, c-format +msgid "invalid gssencmode value: \"%s\"\n" +msgstr "valor gssencmode no válido: «%s»\n" + +#: fe-connect.c:1268 +msgid "no GSSAPI support; cannot require GSSAPI\n" +msgstr "no hay soporte GSSAPI; no se puede requerir GSSAPI\n" + +#: fe-connect.c:1302 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "valor para target_session_attrs no válido: «%s»\n" -#: fe-connect.c:1403 +#: fe-connect.c:1520 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "no se pudo establecer el socket en modo TCP sin retardo: %s\n" -#: fe-connect.c:1433 +#: fe-connect.c:1583 #, c-format msgid "" "could not connect to server: %s\n" @@ -191,7 +254,7 @@ msgstr "" "\t¿Está el servidor en ejecución localmente y aceptando\n" "\tconexiones en el socket de dominio Unix «%s»?\n" -#: fe-connect.c:1491 +#: fe-connect.c:1620 #, c-format msgid "" "could not connect to server: %s\n" @@ -202,7 +265,7 @@ msgstr "" "\t¿Está el servidor en ejecución en el servidor «%s» (%s) y aceptando\n" "\tconexiones TCP/IP en el puerto %s?\n" -#: fe-connect.c:1500 +#: fe-connect.c:1628 #, c-format msgid "" "could not connect to server: %s\n" @@ -213,492 +276,535 @@ msgstr "" "\t¿Está el servidor en ejecución en el servidor «%s» y aceptando\n" "\tconexiones TCP/IP en el puerto %s?\n" -#: fe-connect.c:1551 fe-connect.c:1583 fe-connect.c:1616 fe-connect.c:2175 +#: fe-connect.c:1679 +#, c-format +msgid "invalid integer value \"%s\" for keyword \"%s\"\n" +msgstr "valor entero «%s» no válido para palabra clave «%s»\n" + +#: fe-connect.c:1709 fe-connect.c:1743 fe-connect.c:1778 fe-connect.c:1865 +#: fe-connect.c:2508 #, c-format msgid "setsockopt(%s) failed: %s\n" msgstr "setsockopt(%s) falló: %s\n" -#: fe-connect.c:1665 +#: fe-connect.c:1831 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" -#: fe-connect.c:1722 +#: fe-connect.c:2199 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "el estado de conexión no es válido, probablemente por corrupción de memoria\n" + +#: fe-connect.c:2267 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "número de puerto no válido: «%s»\n" -#: fe-connect.c:1738 +#: fe-connect.c:2283 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "no se pudo traducir el nombre «%s» a una dirección: %s\n" -#: fe-connect.c:1747 +#: fe-connect.c:2296 #, c-format msgid "could not parse network address \"%s\": %s\n" msgstr "no se pudo interpretar la dirección de red «%s»: %s\n" -#: fe-connect.c:1758 +#: fe-connect.c:2309 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "la ruta del socket de dominio Unix «%s» es demasiado larga (máximo %d bytes)\n" -#: fe-connect.c:1772 +#: fe-connect.c:2324 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "no se pudo traducir la ruta del socket Unix «%s» a una dirección: %s\n" -#: fe-connect.c:2053 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "el estado de conexión no es válido, probablemente por corrupción de memoria\n" - -#: fe-connect.c:2110 +#: fe-connect.c:2445 #, c-format msgid "could not create socket: %s\n" msgstr "no se pudo crear el socket: %s\n" -#: fe-connect.c:2132 +#: fe-connect.c:2467 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "no se pudo establecer el socket en modo no bloqueante: %s\n" -#: fe-connect.c:2143 +#: fe-connect.c:2477 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "no se pudo poner el socket en modo close-on-exec: %s\n" -#: fe-connect.c:2162 +#: fe-connect.c:2495 msgid "keepalives parameter must be an integer\n" msgstr "el parámetro de keepalives debe ser un entero\n" -#: fe-connect.c:2313 +#: fe-connect.c:2635 #, c-format msgid "could not get socket error status: %s\n" msgstr "no se pudo determinar el estado de error del socket: %s\n" -#: fe-connect.c:2348 +#: fe-connect.c:2663 #, c-format msgid "could not get client address from socket: %s\n" msgstr "no se pudo obtener la dirección del cliente desde el socket: %s\n" -#: fe-connect.c:2390 +#: fe-connect.c:2705 msgid "requirepeer parameter is not supported on this platform\n" msgstr "el parámetro requirepeer no está soportado en esta plataforma\n" -#: fe-connect.c:2393 +#: fe-connect.c:2708 #, c-format msgid "could not get peer credentials: %s\n" msgstr "no se pudo obtener credenciales de la contraparte: %s\n" -#: fe-connect.c:2416 +#: fe-connect.c:2731 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeer especifica «%s», pero el nombre de usuario de la contraparte es «%s»\n" -#: fe-connect.c:2450 +#: fe-connect.c:2766 +#, c-format +msgid "could not send GSSAPI negotiation packet: %s\n" +msgstr "no se pudo enviar el paquete de negociación GSSAPI: %s\n" + +#: fe-connect.c:2778 +msgid "GSSAPI encryption required, but was impossible (possibly no ccache, no server support, or using a local socket)\n" +msgstr "cifrado GSSAPI requerido, pero fue imposible (posiblemente no hay ccache, no hay soporte de servidor, o se está usando un socket local)\n" + +#: fe-connect.c:2805 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "no se pudo enviar el paquete de negociación SSL: %s\n" -#: fe-connect.c:2489 +#: fe-connect.c:2844 #, c-format msgid "could not send startup packet: %s\n" msgstr "no se pudo enviar el paquete de inicio: %s\n" -#: fe-connect.c:2559 +#: fe-connect.c:2914 msgid "server does not support SSL, but SSL was required\n" msgstr "el servidor no soporta SSL, pero SSL es requerida\n" -#: fe-connect.c:2585 +#: fe-connect.c:2940 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "se ha recibido una respuesta no válida en la negociación SSL: %c\n" -#: fe-connect.c:2661 fe-connect.c:2694 +#: fe-connect.c:3030 +msgid "server doesn't support GSSAPI encryption, but it was required\n" +msgstr "el servidor no soporta cifrado GSSAPI, pero es requerida\n" + +#: fe-connect.c:3041 +#, c-format +msgid "received invalid response to GSSAPI negotiation: %c\n" +msgstr "se ha recibido una respuesta no válida en la negociación GSSAPI: %c\n" + +#: fe-connect.c:3109 fe-connect.c:3142 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "se esperaba una petición de autentificación desde el servidor, pero se ha recibido %c\n" -#: fe-connect.c:2923 +#: fe-connect.c:3389 msgid "unexpected message from server during startup\n" msgstr "se ha recibido un mensaje inesperado del servidor durante el inicio\n" -#: fe-connect.c:3141 +#: fe-connect.c:3616 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "no se pudo establecer una conexión de escritura al servidor: «%s:%s»\n" -#: fe-connect.c:3190 +#: fe-connect.c:3662 #, c-format msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" msgstr "la prueba «SHOW transaction_read_only» falló en el servidor «%s:%s»\n" -#: fe-connect.c:3211 +#: fe-connect.c:3677 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "estado de conexión no válido %d, probablemente por corrupción de memoria\n" -#: fe-connect.c:3668 fe-connect.c:3728 +#: fe-connect.c:4119 fe-connect.c:4179 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc «%s» falló durante el evento PGEVT_CONNRESET\n" -#: fe-connect.c:4075 +#: fe-connect.c:4526 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "URL LDAP no válida «%s»: el esquema debe ser ldap://\n" -#: fe-connect.c:4090 +#: fe-connect.c:4541 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "URL LDAP no válida «%s»: distinguished name faltante\n" -#: fe-connect.c:4101 fe-connect.c:4154 +#: fe-connect.c:4552 fe-connect.c:4605 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "URL LDAP no válida «%s»: debe tener exactamente un atributo\n" -#: fe-connect.c:4111 fe-connect.c:4168 +#: fe-connect.c:4562 fe-connect.c:4619 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "URL LDAP no válida «%s»: debe tener ámbito de búsqueda (base/one/sub)\n" -#: fe-connect.c:4122 +#: fe-connect.c:4573 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "URL LDAP no válida «%s»: no tiene filtro\n" -#: fe-connect.c:4143 +#: fe-connect.c:4594 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "URL LDAP no válida «%s»: número de puerto no válido\n" -#: fe-connect.c:4177 +#: fe-connect.c:4628 msgid "could not create LDAP structure\n" msgstr "no se pudo crear estructura LDAP\n" -#: fe-connect.c:4253 +#: fe-connect.c:4704 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "búsqueda en servidor LDAP falló: %s\n" -#: fe-connect.c:4264 +#: fe-connect.c:4715 msgid "more than one entry found on LDAP lookup\n" msgstr "se encontro más de una entrada en búsqueda LDAP\n" -#: fe-connect.c:4265 fe-connect.c:4277 +#: fe-connect.c:4716 fe-connect.c:4728 msgid "no entry found on LDAP lookup\n" msgstr "no se encontró ninguna entrada en búsqueda LDAP\n" -#: fe-connect.c:4288 fe-connect.c:4301 +#: fe-connect.c:4739 fe-connect.c:4752 msgid "attribute has no values on LDAP lookup\n" msgstr "la búsqueda LDAP entregó atributo sin valores\n" -#: fe-connect.c:4353 fe-connect.c:4372 fe-connect.c:4891 +#: fe-connect.c:4804 fe-connect.c:4823 fe-connect.c:5352 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "falta «=» después de «%s» en la cadena de información de la conexión\n" -#: fe-connect.c:4445 fe-connect.c:5076 fe-connect.c:5850 +#: fe-connect.c:4896 fe-connect.c:5537 fe-connect.c:6311 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "opción de conexión no válida «%s»\n" -#: fe-connect.c:4461 fe-connect.c:4940 +#: fe-connect.c:4912 fe-connect.c:5401 msgid "unterminated quoted string in connection info string\n" msgstr "cadena de caracteres entre comillas sin terminar en la cadena de información de conexión\n" -#: fe-connect.c:4501 -msgid "could not get home directory to locate service definition file" -msgstr "no se pudo obtener el directorio home para localizar el archivo de definición de servicio" - -#: fe-connect.c:4534 +#: fe-connect.c:4995 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "la definición de servicio «%s» no fue encontrada\n" -#: fe-connect.c:4557 +#: fe-connect.c:5018 #, c-format msgid "service file \"%s\" not found\n" msgstr "el archivo de servicio «%s» no fue encontrado\n" -#: fe-connect.c:4570 +#: fe-connect.c:5031 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "la línea %d es demasiado larga en archivo de servicio «%s»\n" -#: fe-connect.c:4641 fe-connect.c:4685 +#: fe-connect.c:5102 fe-connect.c:5146 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "error de sintaxis en archivo de servicio «%s», línea %d\n" -#: fe-connect.c:4652 +#: fe-connect.c:5113 #, c-format msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "especificaciones de servicio anidadas no soportadas en archivo de servicio «%s», línea %d\n" -#: fe-connect.c:5372 +#: fe-connect.c:5833 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "URI no válida propagada a rutina interna de procesamiento: «%s»\n" -#: fe-connect.c:5449 +#: fe-connect.c:5910 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "se encontró el fin de la cadena mientras se buscaba el «]» correspondiente en dirección IPv6 en URI: «%s»\n" -#: fe-connect.c:5456 +#: fe-connect.c:5917 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "la dirección IPv6 no puede ser vacía en la URI: «%s»\n" -#: fe-connect.c:5471 +#: fe-connect.c:5932 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" msgstr "carácter «%c» inesperado en la posición %d en URI (se esperaba «:» o «/»): «%s»\n" -#: fe-connect.c:5600 +#: fe-connect.c:6061 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "separador llave/valor «=» extra en parámetro de la URI: «%s»\n" -#: fe-connect.c:5620 +#: fe-connect.c:6081 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "separador llave/valor «=» faltante en parámetro de la URI: «%s»\n" -#: fe-connect.c:5671 +#: fe-connect.c:6132 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "parámetro de URI no válido: «%s»\n" -#: fe-connect.c:5745 +#: fe-connect.c:6206 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "elemento escapado con %% no válido: «%s»\n" -#: fe-connect.c:5755 +#: fe-connect.c:6216 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "valor no permitido %%00 en valor escapado con %%: «%s»\n" -#: fe-connect.c:6100 +#: fe-connect.c:6581 msgid "connection pointer is NULL\n" msgstr "el puntero de conexión es NULL\n" -#: fe-connect.c:6398 +#: fe-connect.c:6879 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "ADVERTENCIA: El archivo de claves «%s» no es un archivo plano\n" -#: fe-connect.c:6407 +#: fe-connect.c:6888 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "ADVERTENCIA: El archivo de claves «%s» tiene permiso de lectura para el grupo u otros; los permisos deberían ser u=rw (0600) o menos\n" -#: fe-connect.c:6499 +#: fe-connect.c:6982 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "contraseña obtenida desde el archivo «%s»\n" -#: fe-exec.c:826 +#: fe-exec.c:445 fe-exec.c:2822 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "el número de fila %d está fuera del rango 0..%d" + +#: fe-exec.c:506 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "memoria agotada" + +#: fe-exec.c:507 fe-protocol2.c:1402 fe-protocol3.c:1911 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:816 +msgid "write to server failed\n" +msgstr "falló escritura al servidor\n" + +#: fe-exec.c:897 msgid "NOTICE" msgstr "AVISO" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:955 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult no puede soportar un número de tuplas mayor que INT_MAX" + +#: fe-exec.c:967 +msgid "size_t overflow" +msgstr "desbordamiento de size_t" + +#: fe-exec.c:1244 fe-exec.c:1302 fe-exec.c:1348 msgid "command string is a null pointer\n" msgstr "la cadena de orden es un puntero nulo\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1308 fe-exec.c:1354 fe-exec.c:1449 msgid "number of parameters must be between 0 and 65535\n" msgstr "el número de parámetros debe estar entre 0 y 65535\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1342 fe-exec.c:1443 msgid "statement name is a null pointer\n" msgstr "el nombre de sentencia es un puntero nulo\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1362 fe-exec.c:1525 fe-exec.c:2234 fe-exec.c:2436 msgid "function requires at least protocol version 3.0\n" msgstr "la función requiere protocolo 3.0 o superior\n" -#: fe-exec.c:1377 +#: fe-exec.c:1480 msgid "no connection to the server\n" msgstr "no hay conexión con el servidor\n" -#: fe-exec.c:1384 +#: fe-exec.c:1487 msgid "another command is already in progress\n" msgstr "hay otra orden en ejecución\n" -#: fe-exec.c:1498 +#: fe-exec.c:1601 msgid "length must be given for binary parameter\n" msgstr "el largo debe ser especificado para un parámetro binario\n" -#: fe-exec.c:1770 +#: fe-exec.c:1864 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "asyncStatus no esperado: %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1884 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc «%s» falló durante el evento PGEVT_RESULTCREATE\n" -#: fe-exec.c:1950 +#: fe-exec.c:2044 msgid "COPY terminated by new PQexec" msgstr "COPY terminado por un nuevo PQexec" -#: fe-exec.c:1958 +#: fe-exec.c:2052 msgid "COPY IN state must be terminated first\n" msgstr "el estado COPY IN debe ser terminado primero\n" -#: fe-exec.c:1978 +#: fe-exec.c:2072 msgid "COPY OUT state must be terminated first\n" msgstr "el estado COPY OUT debe ser terminado primero\n" -#: fe-exec.c:1986 +#: fe-exec.c:2080 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec no está permitido durante COPY BOTH\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2326 fe-exec.c:2393 fe-exec.c:2483 fe-protocol2.c:1359 +#: fe-protocol3.c:1842 msgid "no COPY in progress\n" msgstr "no hay COPY alguno en ejecución\n" -#: fe-exec.c:2576 +#: fe-exec.c:2673 msgid "connection in wrong state\n" msgstr "la conexión está en un estado incorrecto\n" -#: fe-exec.c:2607 +#: fe-exec.c:2704 msgid "invalid ExecStatusType code" msgstr "el código de ExecStatusType no es válido" -#: fe-exec.c:2634 +#: fe-exec.c:2731 msgid "PGresult is not an error result\n" msgstr "PGresult no es un resultado de error\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2806 fe-exec.c:2829 #, c-format msgid "column number %d is out of range 0..%d" msgstr "el número de columna %d está fuera del rango 0..%d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "el número de fila %d está fuera del rango 0..%d" - -#: fe-exec.c:2747 +#: fe-exec.c:2844 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "el número de parámetro %d está fuera del rango 0..%d" -#: fe-exec.c:3057 +#: fe-exec.c:3154 #, c-format msgid "could not interpret result from server: %s" msgstr "no se pudo interpretar el resultado del servidor: %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3393 fe-exec.c:3477 msgid "incomplete multibyte character\n" msgstr "carácter multibyte incompleto\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "no se puede determinar el OID de la función lo_truncate\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "el argumento de lo_truncate excede el rango de enteros\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "no se puede determinar el OID de la función lo_truncate64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "el argumento de lo_read excede el rango de enteros\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "el argumento de lo_write excede el rango de enteros\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "no se puede determinar el OID de la función lo_lseek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "no se puede determinar el OID de la función lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "no se puede determinar el OID de la función lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "no se pudo abrir el archivo «%s»: %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "no se pudo leer el archivo «%s»: %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "no se pudo escribir a archivo «%s»: %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "la consulta para inicializar las funciones de objetos grandes no devuelve datos\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "no se puede determinar el OID de la función lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "no se puede determinar el OID de la función lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "no se puede determinar el OID de la función lo_creat\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "no se puede determinar el OID de la función lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "no se puede determinar el OID de la función lo_lseek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "no se puede determinar el OID de la función lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "no se puede determinar el OID de la función loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "no se puede determinar el OID de la función lowrite\n" -#: fe-misc.c:292 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "el entero de tamaño %lu no está soportado por pqGetInt" -#: fe-misc.c:328 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "el entero de tamaño %lu no está soportado por pqPutInt" -#: fe-misc.c:639 fe-misc.c:840 +#: fe-misc.c:637 fe-misc.c:859 msgid "connection not open\n" msgstr "la conexión no está abierta\n" -#: fe-misc.c:809 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:268 fe-secure.c:385 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -708,255 +814,257 @@ msgstr "" "\tProbablemente se debe a que el servidor terminó de manera anormal\n" "\tantes o durante el procesamiento de la petición.\n" -#: fe-misc.c:1011 +#: fe-misc.c:1046 msgid "timeout expired\n" msgstr "tiempo de espera agotado\n" -#: fe-misc.c:1056 +#: fe-misc.c:1091 msgid "invalid socket\n" msgstr "socket no válido\n" -#: fe-misc.c:1079 +#: fe-misc.c:1114 #, c-format msgid "select() failed: %s\n" msgstr "select() fallida: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "el estado de setenv %c no es válido, probablemente por corrupción de memoria\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "el estado %c no es válido, probablemente por corrupción de memoria\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "un mensaje de tipo 0x%02x llegó del servidor estando inactivo" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 fe-protocol3.c:209 -#: fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 fe-protocol3.c:728 -#: fe-protocol3.c:951 -msgid "out of memory" -msgstr "memoria agotada" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "carácter %c no esperado, siguiendo una respuesta de consulta vacía (mensaje «I»)" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "el servidor envió datos (mensaje «D») sin precederlos con una descripción de fila (mensaje «T»)" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" msgstr "el servidor envió datos binarios (mensaje «B») sin precederlos con una description de fila (mensaje «T»)" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "se ha recibido una respuesta inesperada del servidor; el primer carácter recibido fue «%c»\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "no hay suficiente memoria para el resultado de la consulta" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "se perdió la sincronía con el servidor, reseteando la conexión" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1536 fe-protocol2.c:1568 fe-protocol3.c:2099 #, c-format msgid "protocol error: id=0x%x\n" msgstr "error de protocolo: id=0x%x\n" -#: fe-protocol3.c:368 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" msgstr "el servidor envió datos (mensaje «D») sin precederlos con una descripción de fila (mensaje «T»)\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "el contenido del mensaje no concuerda con el largo, en el mensaje tipo «%c»\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "se perdió la sincronía con el servidor: se recibió un mensaje de tipo «%c», largo %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "datos insuficientes en el mensaje «T»" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "datos ininteligibles en mensaje «T»" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "datos ininteligibles en mensaje «t»" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "datos insuficientes en el mensaje «D»" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "cantidad de campos inesperada en mensaje «D»" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "datos ininteligibles en mensaje «D»" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "no hay mensaje de error disponible\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1060 fe-protocol3.c:1079 #, c-format msgid " at character %s" msgstr " en el carácter %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1092 #, c-format msgid "DETAIL: %s\n" msgstr "DETALLE: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1095 #, c-format msgid "HINT: %s\n" msgstr "SUGERENCIA: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1098 #, c-format msgid "QUERY: %s\n" msgstr "CONSULTA: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1105 #, c-format msgid "CONTEXT: %s\n" msgstr "CONTEXTO: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1114 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "NOMBRE DE ESQUEMA: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1118 #, c-format msgid "TABLE NAME: %s\n" msgstr "NOMBRE DE TABLA: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1122 #, c-format msgid "COLUMN NAME: %s\n" msgstr "NOMBRE DE COLUMNA: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1126 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "NOMBRE TIPO DE DATO: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1130 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "NOMBRE DE RESTRICCIÓN: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1142 msgid "LOCATION: " msgstr "UBICACIÓN: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1144 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1146 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1341 #, c-format msgid "LINE %d: " msgstr "LÃNEA %d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1736 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: no se está haciendo COPY OUT de texto\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1323 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "el elemento de nombre en el certificado SSL contiene un carácter null\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "el nombre de servidor debe ser especificado para una conexión SSL verificada\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "el certificado de servidor para «%s» no coincide con el nombre de servidor «%s»\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "no se pudo obtener el nombre de servidor desde el certificado del servidor\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "ERROR en llamada SSL: %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1327 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "ERROR en llamada SSL: detectado fin de archivo\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1336 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "error de SSL: %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "la conexión SSL se ha cerrado inesperadamente\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1345 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "código de error SSL no reconocido: %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "falta el elemento de nombre en el certificado SSL\n" - -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "el elemento de nombre en el certificado SSL contiene un carácter null\n" - -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "el nombre de servidor debe ser especificado para una conexión SSL verificada\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "no se pudo determinar el algoritmo de firma del certificado del servidor\n" -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "el certificado de servidor para «%s» no coincide con el nombre de servidor «%s»\n" +msgid "could not find digest for NID %s\n" +msgstr "no se pudo encontrar «digest» para el NID %s\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "no se pudo obtener el nombre de servidor desde el certificado del servidor\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "no se pudo generar hash de certificado de la contraparte\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "falta el elemento de nombre en el certificado SSL\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "no se pudo crear un contexto SSL: %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "no se pudo leer la lista de certificado raíz «%s»: %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" msgstr "la biblioteca SSL no soporta certificados CRL (archivo «%s»)\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate verification.\n" @@ -964,7 +1072,7 @@ msgstr "" "no se pudo obtener el directorio «home» para ubicar el archivo del certificado raíz\n" "Debe ya sea entregar este archivo, o bien cambiar sslmode para deshabilitar la verificación de certificados del servidor.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -973,82 +1081,82 @@ msgstr "" "el archivo de certificado raíz «%s» no existe\n" "Debe ya sea entregar este archivo, o bien cambiar sslmode para deshabilitar la verificación de certificados del servidor.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "no se pudo abrir el archivo de certificado «%s»: %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "no se pudo leer el archivo de certificado «%s»: %s\n" -#: fe-secure-openssl.c:1100 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "no se pudo establecer conexión SSL: %s\n" -#: fe-secure-openssl.c:1154 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "no se pudo cargar el motor SSL «%s»: %s\n" -#: fe-secure-openssl.c:1166 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "no se pudo inicializar el motor SSL «%s»: %s\n" -#: fe-secure-openssl.c:1182 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "no se pudo leer el archivo de la llave privada SSL «%s» desde el motor «%s»: %s\n" -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "no se pudo leer la llave privada SSL «%s» desde el motor «%s»: %s\n" -#: fe-secure-openssl.c:1233 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "el certificado está presente, pero no la llave privada «%s»\n" -#: fe-secure-openssl.c:1241 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "el archivo de la llave privada «%s» tiene permiso de lectura para el grupo u otros; los permisos deberían ser u=rw (0600) o menos\n" -#: fe-secure-openssl.c:1252 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "no se pudo cargar el archivo de la llave privada «%s»: %s\n" -#: fe-secure-openssl.c:1266 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "el certificado no coincide con la llave privada «%s»: %s\n" -#: fe-secure-openssl.c:1366 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "el certificado no pudo ser obtenido: %s\n" -#: fe-secure-openssl.c:1458 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "código de error SSL no reportado" -#: fe-secure-openssl.c:1467 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "código de error SSL %lu" -#: fe-secure.c:261 +#: fe-secure.c:276 #, c-format msgid "could not receive data from server: %s\n" msgstr "no se pudo recibir datos del servidor: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:392 #, c-format msgid "could not send data to server: %s\n" msgstr "no se pudo enviar datos al servidor: %s\n" @@ -1057,21 +1165,3 @@ msgstr "no se pudo enviar datos al servidor: %s\n" #, c-format msgid "unrecognized socket error: 0x%08X/%d" msgstr "código de error de socket no reconocido: 0x%08X/%d" - -#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPIDLE) falló: %s\n" - -#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPALIVE) falló: %s\n" - -#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPINTVL) falló: %s\n" - -#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -#~ msgstr "setsockopt(SO_KEEPALIVE) falló: %s\n" - -#~ msgid "socket not open\n" -#~ msgstr "el socket no está abierto\n" - -#~ msgid "could not acquire mutex: %s\n" -#~ msgstr "no se pudo adquirir el mutex: %s\n" diff --git a/src/interfaces/libpq/po/fr.po b/src/interfaces/libpq/po/fr.po index 755f0e982a2..178e23c00ff 100644 --- a/src/interfaces/libpq/po/fr.po +++ b/src/interfaces/libpq/po/fr.po @@ -7,239 +7,254 @@ # Stéphane Schildknecht , 2009. msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 02:38+0000\n" -"PO-Revision-Date: 2017-08-04 19:53+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:08+0000\n" +"PO-Revision-Date: 2019-05-17 14:53+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: PostgreSQLfr \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.0.2\n" +"X-Generator: Poedit 2.2.1\n" -#: fe-auth-scram.c:176 +#: fe-auth-scram.c:183 msgid "malformed SCRAM message (empty message)\n" msgstr "message SCRAM malformé (message vide)\n" -#: fe-auth-scram.c:182 +#: fe-auth-scram.c:189 msgid "malformed SCRAM message (length mismatch)\n" msgstr "message SCRAM malformé (pas de correspondance sur la longueur)\n" -#: fe-auth-scram.c:231 -msgid "invalid server signature\n" +#: fe-auth-scram.c:238 +msgid "incorrect server signature\n" msgstr "signature invalide du serveur\n" -#: fe-auth-scram.c:240 +#: fe-auth-scram.c:247 msgid "invalid SCRAM exchange state\n" msgstr "état d'échange SCRAM invalide\n" -#: fe-auth-scram.c:263 +#: fe-auth-scram.c:270 #, c-format -msgid "malformed SCRAM message (%c expected)\n" -msgstr "message SCRAM malformé (%c attendu)\n" +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "message SCRAM malformé (attribut « %c » attendu)\n" -#: fe-auth-scram.c:272 +#: fe-auth-scram.c:279 #, c-format -msgid "malformed SCRAM message (expected = in attr '%c')\n" -msgstr "message SCRAM malformé (= attendu dans l'attribut '%c')\n" - -#: fe-auth-scram.c:311 -msgid "failed to generate nonce\n" -msgstr "échec pour la génération de nonce\n" - -#: fe-auth-scram.c:319 fe-auth-scram.c:336 fe-auth-scram.c:346 -#: fe-auth-scram.c:400 fe-auth-scram.c:420 fe-auth-scram.c:445 -#: fe-auth-scram.c:459 fe-auth-scram.c:501 fe-auth.c:227 fe-auth.c:362 -#: fe-auth.c:432 fe-auth.c:467 fe-auth.c:609 fe-auth.c:768 fe-auth.c:1080 -#: fe-auth.c:1228 fe-connect.c:775 fe-connect.c:1203 fe-connect.c:1379 -#: fe-connect.c:1947 fe-connect.c:2476 fe-connect.c:4062 fe-connect.c:4314 -#: fe-connect.c:4433 fe-connect.c:4673 fe-connect.c:4753 fe-connect.c:4852 -#: fe-connect.c:5108 fe-connect.c:5137 fe-connect.c:5209 fe-connect.c:5233 -#: fe-connect.c:5251 fe-connect.c:5352 fe-connect.c:5361 fe-connect.c:5717 -#: fe-connect.c:5867 fe-exec.c:2651 fe-exec.c:3398 fe-exec.c:3563 fe-lobj.c:896 -#: fe-protocol2.c:1206 fe-protocol3.c:992 fe-protocol3.c:1678 -#: fe-secure-openssl.c:514 fe-secure-openssl.c:1138 +msgid "" +"malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "" +"message SCRAM malformé (caractère « = » attendu pour l'attribut « %c »)\n" + +#: fe-auth-scram.c:320 +msgid "could not generate nonce\n" +msgstr "n'a pas pu générer le nonce\n" + +#: fe-auth-scram.c:328 fe-auth-scram.c:395 fe-auth-scram.c:517 +#: fe-auth-scram.c:537 fe-auth-scram.c:563 fe-auth-scram.c:577 +#: fe-auth-scram.c:619 fe-auth.c:290 fe-auth.c:360 fe-auth.c:395 fe-auth.c:581 +#: fe-auth.c:740 fe-auth.c:1052 fe-auth.c:1200 fe-connect.c:858 +#: fe-connect.c:1320 fe-connect.c:1496 fe-connect.c:2085 fe-connect.c:2108 +#: fe-connect.c:2830 fe-connect.c:4512 fe-connect.c:4764 fe-connect.c:4883 +#: fe-connect.c:5133 fe-connect.c:5213 fe-connect.c:5312 fe-connect.c:5568 +#: fe-connect.c:5597 fe-connect.c:5669 fe-connect.c:5693 fe-connect.c:5711 +#: fe-connect.c:5812 fe-connect.c:5821 fe-connect.c:6177 fe-connect.c:6327 +#: fe-exec.c:2748 fe-exec.c:3495 fe-exec.c:3660 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1703 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 msgid "out of memory\n" msgstr "mémoire épuisée\n" -#: fe-auth-scram.c:437 +#: fe-auth-scram.c:555 msgid "invalid SCRAM response (nonce mismatch)\n" msgstr "réponse SCRAM invalide (pas de correspondance sur nonce)\n" -#: fe-auth-scram.c:476 +#: fe-auth-scram.c:594 msgid "malformed SCRAM message (invalid iteration count)\n" msgstr "message SCRAM malformé (décompte d'itération invalide)\n" -#: fe-auth-scram.c:482 +#: fe-auth-scram.c:600 msgid "malformed SCRAM message (garbage at end of server-first-message)\n" msgstr "message SCRAM malformé (problème à la fin du server-first-message)\n" -#: fe-auth-scram.c:511 +#: fe-auth-scram.c:630 #, c-format -msgid "error received from server in SASL exchange: %s\n" -msgstr "réception d'une erreur du serveur dans l'échange SASL : %s\n" +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "réception d'une erreur du serveur dans l'échange SCRAM : %s\n" -#: fe-auth-scram.c:526 +#: fe-auth-scram.c:646 msgid "malformed SCRAM message (garbage at end of server-final-message)\n" msgstr "message SCRAM malformé (problème à la fin du server-final-message)\n" -#: fe-auth-scram.c:534 +#: fe-auth-scram.c:654 msgid "malformed SCRAM message (invalid server signature)\n" msgstr "message SCRAM malformé (signature serveur invalide)\n" -#: fe-auth.c:122 +#: fe-auth.c:77 #, c-format msgid "out of memory allocating GSSAPI buffer (%d)\n" msgstr "mémoire épuisée lors de l'allocation du tampon GSSAPI (%d)\n" -#: fe-auth.c:177 +#: fe-auth.c:132 msgid "GSSAPI continuation error" msgstr "erreur de suite GSSAPI" -#: fe-auth.c:207 fe-auth.c:461 +#: fe-auth.c:159 fe-auth.c:389 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "le nom d'hôte doit être précisé\n" -#: fe-auth.c:214 +#: fe-auth.c:166 msgid "duplicate GSS authentication request\n" msgstr "requête d'authentification GSS dupliquée\n" -#: fe-auth.c:240 -msgid "GSSAPI name import error" -msgstr "erreur d'import du nom GSSAPI" - -#: fe-auth.c:303 +#: fe-auth.c:231 #, c-format msgid "out of memory allocating SSPI buffer (%d)\n" msgstr "mémoire épuisée lors de l'allocation du tampon SSPI (%d)\n" -#: fe-auth.c:351 +#: fe-auth.c:279 msgid "SSPI continuation error" msgstr "erreur de suite SSPI" -#: fe-auth.c:422 +#: fe-auth.c:350 msgid "duplicate SSPI authentication request\n" msgstr "requête d'authentification SSPI dupliquée\n" -#: fe-auth.c:447 +#: fe-auth.c:375 msgid "could not acquire SSPI credentials" msgstr "n'a pas pu récupérer les pièces d'identité SSPI" -#: fe-auth.c:500 +#: fe-auth.c:429 msgid "duplicate SASL authentication request\n" msgstr "requête d'authentification SASL dupliquée\n" -#: fe-auth.c:560 +#: fe-auth.c:487 +msgid "" +"server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "" +"le serveur a proposé une authentification SCRAM-SHA-256-PLUS sur une " +"connexion non SSL\n" + +#: fe-auth.c:499 msgid "none of the server's SASL authentication mechanisms are supported\n" msgstr "" "authentification Kerberos 4 non supportée\n" "aucun des mécanismes d'authentification SASL du serveur n'est supporté\n" -#: fe-auth.c:633 +#: fe-auth.c:605 #, c-format msgid "out of memory allocating SASL buffer (%d)\n" msgstr "mémoire épuisée lors de l'allocation du tampon SASL (%d)\n" -#: fe-auth.c:658 -msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" -msgstr "AuthenticationSASLFinal reçu du serveur mais l'authentification SASL n'a pas été terminée\n" +#: fe-auth.c:630 +msgid "" +"AuthenticationSASLFinal received from server, but SASL authentication was " +"not completed\n" +msgstr "" +"AuthenticationSASLFinal reçu du serveur mais l'authentification SASL n'a pas " +"été terminée\n" -#: fe-auth.c:735 +#: fe-auth.c:707 msgid "SCM_CRED authentication method not supported\n" msgstr "authentification SCM_CRED non supportée\n" -#: fe-auth.c:826 +#: fe-auth.c:798 msgid "Kerberos 4 authentication not supported\n" msgstr "authentification Kerberos 4 non supportée\n" -#: fe-auth.c:831 +#: fe-auth.c:803 msgid "Kerberos 5 authentication not supported\n" msgstr "authentification Kerberos 5 non supportée\n" -#: fe-auth.c:902 +#: fe-auth.c:874 msgid "GSSAPI authentication not supported\n" msgstr "authentification GSSAPI non supportée\n" -#: fe-auth.c:934 +#: fe-auth.c:906 msgid "SSPI authentication not supported\n" msgstr "authentification SSPI non supportée\n" -#: fe-auth.c:942 +#: fe-auth.c:914 msgid "Crypt authentication not supported\n" msgstr "authentification crypt non supportée\n" -#: fe-auth.c:1008 +#: fe-auth.c:980 #, c-format msgid "authentication method %u not supported\n" msgstr "méthode d'authentification %u non supportée\n" -#: fe-auth.c:1055 +#: fe-auth.c:1027 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "échec de la recherche du nom d'utilisateur : code erreur %lu\n" -#: fe-auth.c:1065 fe-connect.c:2403 +#: fe-auth.c:1037 fe-connect.c:2717 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "n'a pas pu rechercher l'identifiant de l'utilisateur local %d : %s\n" -#: fe-auth.c:1070 fe-connect.c:2408 +#: fe-auth.c:1042 fe-connect.c:2722 #, c-format msgid "local user with ID %d does not exist\n" msgstr "l'utilisateur local dont l'identifiant est %d n'existe pas\n" -#: fe-auth.c:1172 +#: fe-auth.c:1144 msgid "unexpected shape of result set returned for SHOW\n" msgstr "forme du résultat inattendu pour SHOW\n" -#: fe-auth.c:1181 +#: fe-auth.c:1153 msgid "password_encryption value too long\n" msgstr "la valeur de password_encryption est trop longue\n" -#: fe-auth.c:1221 +#: fe-auth.c:1193 #, c-format msgid "unrecognized password encryption algorithm \"%s\"\n" msgstr "algorithme de chiffrement du mot de passe « %s » non reconnu\n" -#: fe-connect.c:968 +#: fe-connect.c:1041 #, c-format -msgid "could not match %d host names to %d hostaddrs\n" -msgstr "n'a pas pu faire correspondre les %d noms d'hôte aux %d adresses\n" +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "" +"n'a pas pu faire correspondre les %d noms d'hôte aux %d valeurs hostaddr\n" -#: fe-connect.c:1025 +#: fe-connect.c:1117 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "n'a pas pu faire correspondre les %d numéros de port aux %d hôtes\n" -#: fe-connect.c:1077 -msgid "could not get home directory to locate password file\n" -msgstr "" -"n'a pas pu obtenir le répertoire personnel pour trouver le fichier de\n" -"mot de passe\n" - -#: fe-connect.c:1129 +#: fe-connect.c:1213 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "valeur sslmode invalide : « %s »\n" -#: fe-connect.c:1150 +#: fe-connect.c:1234 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" -msgstr "valeur sslmode « %s » invalide si le support SSL n'est pas compilé initialement\n" +msgstr "" +"valeur sslmode « %s » invalide si le support SSL n'est pas compilé " +"initialement\n" -#: fe-connect.c:1185 +#: fe-connect.c:1258 +#, c-format +msgid "invalid gssencmode value: \"%s\"\n" +msgstr "valeur gssencmode invalide : « %s »\n" + +#: fe-connect.c:1268 +msgid "no GSSAPI support; cannot require GSSAPI\n" +msgstr "pas de support de GSSAPI : ne peut pas nécessiter GSSAPI\n" + +#: fe-connect.c:1302 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "valeur target_session_attrs invalide : « %s »\n" -#: fe-connect.c:1403 +#: fe-connect.c:1520 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "n'a pas pu activer le mode TCP sans délai pour la socket : %s\n" -#: fe-connect.c:1433 +#: fe-connect.c:1583 #, c-format msgid "" "could not connect to server: %s\n" @@ -250,7 +265,7 @@ msgstr "" "\tLe serveur est-il actif localement et accepte-t-il les connexions sur la\n" " \tsocket Unix « %s » ?\n" -#: fe-connect.c:1491 +#: fe-connect.c:1620 #, c-format msgid "" "could not connect to server: %s\n" @@ -261,7 +276,7 @@ msgstr "" "\tLe serveur est-il actif sur l'hôte « %s » (%s)\n" "\tet accepte-t-il les connexionsTCP/IP sur le port %s ?\n" -#: fe-connect.c:1500 +#: fe-connect.c:1628 #, c-format msgid "" "could not connect to server: %s\n" @@ -272,509 +287,578 @@ msgstr "" "\tLe serveur est-il actif sur l'hôte « %s » et accepte-t-il les connexions\n" "\tTCP/IP sur le port %s ?\n" -#: fe-connect.c:1551 fe-connect.c:1583 fe-connect.c:1616 fe-connect.c:2175 +#: fe-connect.c:1679 +#, c-format +msgid "invalid integer value \"%s\" for keyword \"%s\"\n" +msgstr "valeur entière « %s » invalide pour le mot clé « %s »\n" + +#: fe-connect.c:1709 fe-connect.c:1743 fe-connect.c:1778 fe-connect.c:1865 +#: fe-connect.c:2507 #, c-format msgid "setsockopt(%s) failed: %s\n" msgstr "setsockopt(%s) a échoué : %s\n" -#: fe-connect.c:1665 +#: fe-connect.c:1831 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) a échoué : %ui\n" -#: fe-connect.c:1722 +#: fe-connect.c:2199 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "" +"état de connexion invalide, indique probablement une corruption de mémoire\n" + +#: fe-connect.c:2267 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "numéro de port invalide : « %s »\n" -#: fe-connect.c:1738 +#: fe-connect.c:2283 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "n'a pas pu traduire le nom d'hôte « %s » en adresse : %s\n" -#: fe-connect.c:1747 +#: fe-connect.c:2296 #, c-format msgid "could not parse network address \"%s\": %s\n" msgstr "n'a pas pu analyser l'adresse réseau « %s » : %s\n" -#: fe-connect.c:1758 +#: fe-connect.c:2309 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" -msgstr "Le chemin du socket de domaine Unix, « %s », est trop (maximum %d octets)\n" +msgstr "" +"Le chemin du socket de domaine Unix, « %s », est trop (maximum %d octets)\n" -#: fe-connect.c:1772 +#: fe-connect.c:2324 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "" -"n'a pas pu traduire le chemin de la socket du domaine Unix « %s » en adresse :\n" +"n'a pas pu traduire le chemin de la socket du domaine Unix « %s » en " +"adresse :\n" "%s\n" -#: fe-connect.c:2053 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "état de connexion invalide, indique probablement une corruption de mémoire\n" - -#: fe-connect.c:2110 +#: fe-connect.c:2444 #, c-format msgid "could not create socket: %s\n" msgstr "n'a pas pu créer la socket : %s\n" -#: fe-connect.c:2132 +#: fe-connect.c:2466 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "n'a pas pu activer le mode non-bloquant pour la socket : %s\n" -#: fe-connect.c:2143 +#: fe-connect.c:2476 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "n'a pas pu paramétrer la socket en mode close-on-exec : %s\n" -#: fe-connect.c:2162 +#: fe-connect.c:2494 msgid "keepalives parameter must be an integer\n" msgstr "le paramètre keepalives doit être un entier\n" -#: fe-connect.c:2313 +#: fe-connect.c:2634 #, c-format msgid "could not get socket error status: %s\n" msgstr "n'a pas pu déterminer le statut d'erreur de la socket : %s\n" -#: fe-connect.c:2348 +#: fe-connect.c:2662 #, c-format msgid "could not get client address from socket: %s\n" msgstr "n'a pas pu obtenir l'adresse du client depuis la socket : %s\n" -#: fe-connect.c:2390 +#: fe-connect.c:2704 msgid "requirepeer parameter is not supported on this platform\n" msgstr "le paramètre requirepeer n'est pas supporté sur cette plateforme\n" -#: fe-connect.c:2393 +#: fe-connect.c:2707 #, c-format msgid "could not get peer credentials: %s\n" msgstr "n'a pas pu obtenir l'authentification de l'autre : %s\n" -#: fe-connect.c:2416 +#: fe-connect.c:2730 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" -msgstr "requirepeer indique « %s » mais le nom de l'utilisateur réel est « %s »\n" +msgstr "" +"requirepeer indique « %s » mais le nom de l'utilisateur réel est « %s »\n" + +#: fe-connect.c:2765 +#, c-format +msgid "could not send GSSAPI negotiation packet: %s\n" +msgstr "n'a pas pu transmettre le paquet de négociation GSSAPI : %s\n" + +#: fe-connect.c:2777 +msgid "" +"GSSAPI encryption required, but was impossible (possibly no ccache, no " +"server support, or using a local socket)\n" +msgstr "" +"chiffrage nécessaire avec GSSAPI, mais impossible (potentiellement pas de " +"cache, de support serveur ou de socket local)\n" -#: fe-connect.c:2450 +#: fe-connect.c:2804 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "n'a pas pu transmettre le paquet de négociation SSL : %s\n" -#: fe-connect.c:2489 +#: fe-connect.c:2843 #, c-format msgid "could not send startup packet: %s\n" msgstr "n'a pas pu transmettre le paquet de démarrage : %s\n" -#: fe-connect.c:2559 +#: fe-connect.c:2913 msgid "server does not support SSL, but SSL was required\n" msgstr "le serveur ne supporte pas SSL alors que SSL était réclamé\n" -#: fe-connect.c:2585 +#: fe-connect.c:2939 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "a reçu une réponse invalide à la négociation SSL : %c\n" -#: fe-connect.c:2661 fe-connect.c:2694 +#: fe-connect.c:3029 +msgid "server doesn't support GSSAPI encryption, but it was required\n" +msgstr "" +"le serveur ne supporte pas le chiffrage GSSAPI alors qu'il était réclamé\n" + +#: fe-connect.c:3040 +#, c-format +msgid "received invalid response to GSSAPI negotiation: %c\n" +msgstr "a reçu une réponse invalide à la négociation GSSAPI : %c\n" + +#: fe-connect.c:3108 fe-connect.c:3141 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "" "attendait une requête d'authentification en provenance du serveur, mais a\n" " reçu %c\n" -#: fe-connect.c:2923 +#: fe-connect.c:3388 msgid "unexpected message from server during startup\n" msgstr "message inattendu du serveur lors du démarrage\n" -#: fe-connect.c:3141 +#: fe-connect.c:3615 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "n'a pas pu réaliser une connexion en écriture au serveur « %s » : %s\n" -#: fe-connect.c:3190 +#: fe-connect.c:3661 #, c-format msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" -msgstr "le test \"SHOW transaction_read_only\" a échoué sur le serveur \"%s:%s\"\n" +msgstr "" +"le test \"SHOW transaction_read_only\" a échoué sur le serveur \"%s:%s\"\n" -#: fe-connect.c:3211 +#: fe-connect.c:3676 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "" "état de connexion invalide (%d), indiquant probablement une corruption de\n" " mémoire\n" -#: fe-connect.c:3668 fe-connect.c:3728 +#: fe-connect.c:4118 fe-connect.c:4178 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "échec de PGEventProc « %s » lors de l'événement PGEVT_CONNRESET\n" -#: fe-connect.c:4075 +#: fe-connect.c:4525 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "URL LDAP « %s » invalide : le schéma doit être ldap://\n" -#: fe-connect.c:4090 +#: fe-connect.c:4540 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "URL LDAP « %s » invalide : le « distinguished name » manque\n" -#: fe-connect.c:4101 fe-connect.c:4154 +#: fe-connect.c:4551 fe-connect.c:4604 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "URL LDAP « %s » invalide : doit avoir exactement un attribut\n" -#: fe-connect.c:4111 fe-connect.c:4168 +#: fe-connect.c:4561 fe-connect.c:4618 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" -msgstr "URL LDAP « %s » invalide : doit avoir une échelle de recherche (base/un/sous)\n" +msgstr "" +"URL LDAP « %s » invalide : doit avoir une échelle de recherche (base/un/" +"sous)\n" -#: fe-connect.c:4122 +#: fe-connect.c:4572 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "URL LDAP « %s » invalide : aucun filtre\n" -#: fe-connect.c:4143 +#: fe-connect.c:4593 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "URL LDAP « %s » invalide : numéro de port invalide\n" -#: fe-connect.c:4177 +#: fe-connect.c:4627 msgid "could not create LDAP structure\n" msgstr "n'a pas pu créer la structure LDAP\n" -#: fe-connect.c:4253 +#: fe-connect.c:4703 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "échec de la recherche sur le serveur LDAP : %s\n" -#: fe-connect.c:4264 +#: fe-connect.c:4714 msgid "more than one entry found on LDAP lookup\n" msgstr "plusieurs entrées trouvées pendant la recherche LDAP\n" -#: fe-connect.c:4265 fe-connect.c:4277 +#: fe-connect.c:4715 fe-connect.c:4727 msgid "no entry found on LDAP lookup\n" msgstr "aucune entrée trouvée pendant la recherche LDAP\n" -#: fe-connect.c:4288 fe-connect.c:4301 +#: fe-connect.c:4738 fe-connect.c:4751 msgid "attribute has no values on LDAP lookup\n" msgstr "l'attribut n'a pas de valeur après la recherche LDAP\n" -#: fe-connect.c:4353 fe-connect.c:4372 fe-connect.c:4891 +#: fe-connect.c:4803 fe-connect.c:4822 fe-connect.c:5351 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" -msgstr "« = » manquant après « %s » dans la chaîne des paramètres de connexion\n" +msgstr "" +"« = » manquant après « %s » dans la chaîne des paramètres de connexion\n" -#: fe-connect.c:4445 fe-connect.c:5076 fe-connect.c:5850 +#: fe-connect.c:4895 fe-connect.c:5536 fe-connect.c:6310 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "option de connexion « %s » invalide\n" -#: fe-connect.c:4461 fe-connect.c:4940 +#: fe-connect.c:4911 fe-connect.c:5400 msgid "unterminated quoted string in connection info string\n" msgstr "guillemets non refermés dans la chaîne des paramètres de connexion\n" -#: fe-connect.c:4501 -msgid "could not get home directory to locate service definition file" -msgstr "" -"n'a pas pu obtenir le répertoire personnel pour trouver le certificat de\n" -"définition du service" - -#: fe-connect.c:4534 +#: fe-connect.c:4994 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "définition du service « %s » introuvable\n" -#: fe-connect.c:4557 +#: fe-connect.c:5017 #, c-format msgid "service file \"%s\" not found\n" msgstr "fichier de service « %s » introuvable\n" -#: fe-connect.c:4570 +#: fe-connect.c:5030 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "ligne %d trop longue dans le fichier service « %s »\n" -#: fe-connect.c:4641 fe-connect.c:4685 +#: fe-connect.c:5101 fe-connect.c:5145 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "erreur de syntaxe dans le fichier service « %s », ligne %d\n" -#: fe-connect.c:4652 +#: fe-connect.c:5112 #, c-format -msgid "nested service specifications not supported in service file \"%s\", line %d\n" -msgstr "spécifications imbriquées de service non supportées dans le fichier service « %s », ligne %d\n" +msgid "" +"nested service specifications not supported in service file \"%s\", line %d\n" +msgstr "" +"spécifications imbriquées de service non supportées dans le fichier service " +"« %s », ligne %d\n" -#: fe-connect.c:5372 +#: fe-connect.c:5832 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "URI invalide propagée à la routine d'analyse interne : « %s »\n" -#: fe-connect.c:5449 +#: fe-connect.c:5909 #, c-format -msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" +msgid "" +"end of string reached when looking for matching \"]\" in IPv6 host address " +"in URI: \"%s\"\n" msgstr "" "fin de chaîne atteinte lors de la recherche du « ] » correspondant dans\n" "l'adresse IPv6 de l'hôte indiquée dans l'URI : « %s »\n" -#: fe-connect.c:5456 +#: fe-connect.c:5916 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "l'adresse IPv6 de l'hôte ne peut pas être vide dans l'URI : « %s »\n" -#: fe-connect.c:5471 +#: fe-connect.c:5931 #, c-format -msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" +msgid "" +"unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): " +"\"%s\"\n" msgstr "" "caractère « %c » inattendu à la position %d de l'URI (caractère « : » ou\n" "« / » attendu) : « %s »\n" -#: fe-connect.c:5600 +#: fe-connect.c:6060 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" -msgstr "séparateur « = » de clé/valeur en trop dans le paramètre de requête URI : « %s »\n" +msgstr "" +"séparateur « = » de clé/valeur en trop dans le paramètre de requête URI : « " +"%s »\n" -#: fe-connect.c:5620 +#: fe-connect.c:6080 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" -msgstr "séparateur « = » de clé/valeur manquant dans le paramètre de requête URI : « %s »\n" +msgstr "" +"séparateur « = » de clé/valeur manquant dans le paramètre de requête URI : « " +"%s »\n" -#: fe-connect.c:5671 +#: fe-connect.c:6131 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "paramètre de la requête URI invalide : « %s »\n" -#: fe-connect.c:5745 +#: fe-connect.c:6205 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "jeton encodé en pourcentage invalide : « %s »\n" -#: fe-connect.c:5755 +#: fe-connect.c:6215 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "valeur %%00 interdite dans la valeur codée en pourcentage : « %s »\n" -#: fe-connect.c:6100 +#: fe-connect.c:6580 msgid "connection pointer is NULL\n" msgstr "le pointeur de connexion est NULL\n" -#: fe-connect.c:6398 +#: fe-connect.c:6878 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" -msgstr "ATTENTION : le fichier de mots de passe « %s » n'est pas un fichier texte\n" +msgstr "" +"ATTENTION : le fichier de mots de passe « %s » n'est pas un fichier texte\n" -#: fe-connect.c:6407 +#: fe-connect.c:6887 #, c-format -msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" +msgid "" +"WARNING: password file \"%s\" has group or world access; permissions should " +"be u=rw (0600) or less\n" msgstr "" "ATTENTION : le fichier de mots de passe « %s » a des droits d'accès en\n" "lecture pour le groupe ou universel ; les droits devraient être u=rw (0600)\n" "ou inférieur\n" -#: fe-connect.c:6499 +#: fe-connect.c:6981 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "mot de passe récupéré dans le fichier fichier « %s »\n" -#: fe-exec.c:826 +#: fe-exec.c:445 fe-exec.c:2822 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "le numéro de ligne %d est en dehors des limites 0..%d" + +#: fe-exec.c:506 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "mémoire épuisée" + +#: fe-exec.c:507 fe-protocol2.c:1402 fe-protocol3.c:1911 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:816 +msgid "write to server failed\n" +msgstr "échec en écriture vers le serveur\n" + +#: fe-exec.c:897 msgid "NOTICE" msgstr "NOTICE" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:955 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult ne supporte pas plus de INT_MAX lignes" + +#: fe-exec.c:967 +msgid "size_t overflow" +msgstr "saturation de size_t" + +#: fe-exec.c:1244 fe-exec.c:1302 fe-exec.c:1348 msgid "command string is a null pointer\n" msgstr "la chaîne de commande est un pointeur nul\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1308 fe-exec.c:1354 fe-exec.c:1449 msgid "number of parameters must be between 0 and 65535\n" msgstr "le nombre de paramètres doit être compris entre 0 et 65535\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1342 fe-exec.c:1443 msgid "statement name is a null pointer\n" msgstr "le nom de l'instruction est un pointeur nul\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1362 fe-exec.c:1525 fe-exec.c:2234 fe-exec.c:2436 msgid "function requires at least protocol version 3.0\n" msgstr "la fonction nécessite au minimum le protocole 3.0\n" -#: fe-exec.c:1377 +#: fe-exec.c:1480 msgid "no connection to the server\n" msgstr "aucune connexion au serveur\n" -#: fe-exec.c:1384 +#: fe-exec.c:1487 msgid "another command is already in progress\n" msgstr "une autre commande est déjà en cours\n" -#: fe-exec.c:1498 +#: fe-exec.c:1601 msgid "length must be given for binary parameter\n" msgstr "la longueur doit être indiquée pour les paramètres binaires\n" -#: fe-exec.c:1770 +#: fe-exec.c:1864 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "asyncStatus inattendu : %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1884 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "échec de PGEventProc « %s » lors de l'événement PGEVT_RESULTCREATE\n" -#: fe-exec.c:1950 +#: fe-exec.c:2044 msgid "COPY terminated by new PQexec" msgstr "COPY terminé par un nouveau PQexec" -#: fe-exec.c:1958 +#: fe-exec.c:2052 msgid "COPY IN state must be terminated first\n" msgstr "l'état COPY IN doit d'abord être terminé\n" -#: fe-exec.c:1978 +#: fe-exec.c:2072 msgid "COPY OUT state must be terminated first\n" msgstr "l'état COPY OUT doit d'abord être terminé\n" -#: fe-exec.c:1986 +#: fe-exec.c:2080 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec non autorisé pendant COPY BOTH\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2326 fe-exec.c:2393 fe-exec.c:2483 fe-protocol2.c:1359 +#: fe-protocol3.c:1842 msgid "no COPY in progress\n" msgstr "aucun COPY en cours\n" -#: fe-exec.c:2576 +#: fe-exec.c:2673 msgid "connection in wrong state\n" msgstr "connexion dans un état erroné\n" -#: fe-exec.c:2607 +#: fe-exec.c:2704 msgid "invalid ExecStatusType code" msgstr "code ExecStatusType invalide" -#: fe-exec.c:2634 +#: fe-exec.c:2731 msgid "PGresult is not an error result\n" msgstr "PGresult n'est pas un résultat d'erreur\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2806 fe-exec.c:2829 #, c-format msgid "column number %d is out of range 0..%d" msgstr "le numéro de colonne %d est en dehors des limites 0..%d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "le numéro de ligne %d est en dehors des limites 0..%d" - -#: fe-exec.c:2747 +#: fe-exec.c:2844 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "le numéro de paramètre %d est en dehors des limites 0..%d" -#: fe-exec.c:3057 +#: fe-exec.c:3154 #, c-format msgid "could not interpret result from server: %s" msgstr "n'a pas pu interpréter la réponse du serveur : %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3393 fe-exec.c:3477 msgid "incomplete multibyte character\n" msgstr "caractère multi-octet incomplet\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_truncate\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "l'argument de lo_truncate dépasse l'échelle des entiers\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_truncate64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "l'argument de lo_read dépasse l'échelle des entiers\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "l'argument de lo_write dépasse l'échelle des entiers\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_lseek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le fichier « %s » : %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "n'a pas pu lire le fichier « %s » : %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "n'a pas pu écrire dans le fichier « %s » : %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "" -"la requête d'initialisation des fonctions pour « Larges Objects » ne renvoie\n" +"la requête d'initialisation des fonctions pour « Larges Objects » ne " +"renvoie\n" "pas de données\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_creat\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_lseek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "ne peut pas déterminer l'OID de la fonction lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "ne peut pas déterminer l'OID de la fonction loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "ne peut pas déterminer l'OID de la fonction lowrite\n" -#: fe-misc.c:292 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "entier de taille %lu non supporté par pqGetInt" -#: fe-misc.c:328 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "entier de taille %lu non supporté par pqPutInt" -#: fe-misc.c:639 fe-misc.c:840 +#: fe-misc.c:637 fe-misc.c:859 msgid "connection not open\n" msgstr "la connexion n'est pas active\n" -#: fe-misc.c:809 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:268 fe-secure.c:385 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -784,364 +868,392 @@ msgstr "" "\tLe serveur s'est peut-être arrêté anormalement avant ou durant le\n" "\ttraitement de la requête.\n" -#: fe-misc.c:1011 +#: fe-misc.c:1046 msgid "timeout expired\n" msgstr "le délai est dépassé\n" -#: fe-misc.c:1056 +#: fe-misc.c:1091 msgid "invalid socket\n" msgstr "socket invalide\n" -#: fe-misc.c:1079 +#: fe-misc.c:1114 #, c-format msgid "select() failed: %s\n" msgstr "échec de select() : %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" -msgstr "état setenv %c invalide, indiquant probablement une corruption de la mémoire\n" +msgstr "" +"état setenv %c invalide, indiquant probablement une corruption de la " +"mémoire\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" -msgstr "état %c invalide, indiquant probablement une corruption de la mémoire\n" +msgstr "" +"état %c invalide, indiquant probablement une corruption de la mémoire\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" -msgstr "le message de type 0x%02x est arrivé alors que le serveur était en attente" - -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 fe-protocol3.c:209 -#: fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 fe-protocol3.c:728 -#: fe-protocol3.c:951 -msgid "out of memory" -msgstr "mémoire épuisée" +msgstr "" +"le message de type 0x%02x est arrivé alors que le serveur était en attente" -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "" "caractère %c inattendu à la suite d'une réponse de requête vide (message\n" "« I »)" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format -msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" +msgid "" +"server sent data (\"D\" message) without prior row description (\"T\" " +"message)" msgstr "" "le serveur a envoyé des données (message « D ») sans description préalable\n" "de la ligne (message « T »)" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format -msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" +msgid "" +"server sent binary data (\"B\" message) without prior row description (\"T\" " +"message)" msgstr "" "le serveur a envoyé des données binaires (message « B ») sans description\n" "préalable de la ligne (message « T »)" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" -msgstr "réponse inattendue du serveur, le premier caractère reçu étant « %c »\n" +msgstr "" +"réponse inattendue du serveur, le premier caractère reçu étant « %c »\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "mémoire épuisée pour le résultat de la requête" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" -msgstr "synchronisation perdue avec le serveur, réinitialisation de la connexion" +msgstr "" +"synchronisation perdue avec le serveur, réinitialisation de la connexion" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1536 fe-protocol2.c:1568 fe-protocol3.c:2099 #, c-format msgid "protocol error: id=0x%x\n" msgstr "erreur de protocole : id=0x%x\n" -#: fe-protocol3.c:368 -msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" +#: fe-protocol3.c:367 +msgid "" +"server sent data (\"D\" message) without prior row description (\"T\" " +"message)\n" msgstr "" "le serveur a envoyé des données (message « D ») sans description préalable\n" "de la ligne (message « T »)\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "" "le contenu du message ne correspond pas avec la longueur du type de message\n" "« %c »\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "" "synchronisation perdue avec le serveur : a reçu le type de message « %c »,\n" "longueur %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "données insuffisantes dans le message « T »" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "données supplémentaires dans le message « T »" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "données supplémentaires dans le message « t »" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "données insuffisantes dans le message « D »" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "nombre de champs inattendu dans le message « D »" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "données supplémentaires dans le message « D »" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "aucun message d'erreur disponible\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1060 fe-protocol3.c:1079 #, c-format msgid " at character %s" msgstr " au caractère %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1092 #, c-format msgid "DETAIL: %s\n" msgstr "DÉTAIL : %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1095 #, c-format msgid "HINT: %s\n" msgstr "ASTUCE : %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1098 #, c-format msgid "QUERY: %s\n" msgstr "REQUÊTE : %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1105 #, c-format msgid "CONTEXT: %s\n" msgstr "CONTEXTE : %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1114 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "NOM DE SCHÉMA : %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1118 #, c-format msgid "TABLE NAME: %s\n" msgstr "NOM DE TABLE : %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1122 #, c-format msgid "COLUMN NAME: %s\n" msgstr "NOM DE COLONNE : %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1126 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "NOM DU TYPE DE DONNÉES : %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1130 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "NOM DE CONTRAINTE : %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1142 msgid "LOCATION: " msgstr "EMPLACEMENT : " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1144 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1146 #, c-format msgid "%s:%s" msgstr "%s : %s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1341 #, c-format msgid "LINE %d: " msgstr "LIGNE %d : " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1736 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline : ne va pas réaliser un COPY OUT au format texte\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1323 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "le nom du certificat SSL contient des NULL\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "le nom d'hôte doit être précisé pour une connexion SSL vérifiée\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "" +"le certificat serveur pour « %s » ne correspond pas au nom d'hôte « %s »\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "" +"n'a pas pu récupérer le nom d'hôte du serveur à partir du certificat " +"serveur\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "erreur SYSCALL SSL : %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1327 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "erreur SYSCALL SSL : EOF détecté\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1336 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "erreur SSL : %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "la connexion SSL a été fermée de façon inattendu\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1345 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "code d'erreur SSL inconnu : %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "l'entrée du nom du certificat SSL est manquante\n" - -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "le nom du certificat SSL contient des NULL\n" - -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "le nom d'hôte doit être précisé pour une connexion SSL vérifiée\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "" +"n'a pas pu déterminer l'algorithme de signature du certificat serveur\n" -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "le certificat serveur pour « %s » ne correspond pas au nom d'hôte « %s »\n" +msgid "could not find digest for NID %s\n" +msgstr "n'a pas pu trouver l'entrée pour le NID %s\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "n'a pas pu récupérer le nom d'hôte du serveur à partir du certificat serveur\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "n'a pas pu générer le hachage du certificat peer\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "l'entrée du nom du certificat SSL est manquante\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "n'a pas pu créer le contexte SSL : %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "n'a pas pu lire le certificat racine « %s » : %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "la bibliothèque SSL ne supporte pas les certificats CRL (fichier « %s »)\n" +msgstr "" +"la bibliothèque SSL ne supporte pas les certificats CRL (fichier « %s »)\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" +"Either provide the file or change sslmode to disable server certificate " +"verification.\n" msgstr "" -"n'a pas pu obtenir le répertoire personnel pour situer le fichier de certificat racine.\n" -"Fournissez le fichier ou modifiez sslmode pour désactiver la vérification du\n" +"n'a pas pu obtenir le répertoire personnel pour situer le fichier de " +"certificat racine.\n" +"Fournissez le fichier ou modifiez sslmode pour désactiver la vérification " +"du\n" "certificat par le serveur.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" +"Either provide the file or change sslmode to disable server certificate " +"verification.\n" msgstr "" "le fichier de certificat racine « %s » n'existe pas.\n" -"Fournissez le fichier ou modifiez sslmode pour désactiver la vérification du\n" +"Fournissez le fichier ou modifiez sslmode pour désactiver la vérification " +"du\n" "certificat par le serveur.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "n'a pas pu ouvrir le certificat « %s » : %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "n'a pas pu lire le certificat « %s » : %s\n" -#: fe-secure-openssl.c:1100 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "n'a pas pu établir la connexion SSL : %s\n" -#: fe-secure-openssl.c:1154 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "n'a pas pu charger le moteur SSL « %s » : %s\n" -#: fe-secure-openssl.c:1166 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "n'a pas pu initialiser le moteur SSL « %s » : %s\n" -#: fe-secure-openssl.c:1182 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" -msgstr "n'a pas pu lire la clé privée SSL « %s » à partir du moteur « %s » : %s\n" +msgstr "" +"n'a pas pu lire la clé privée SSL « %s » à partir du moteur « %s » : %s\n" -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" -msgstr "n'a pas pu charger la clé privée SSL « %s » à partir du moteur « %s » : %s\n" +msgstr "" +"n'a pas pu charger la clé privée SSL « %s » à partir du moteur « %s » : %s\n" -#: fe-secure-openssl.c:1233 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "le certificat est présent, mais la clé privée « %s » est absente\n" -#: fe-secure-openssl.c:1241 +#: fe-secure-openssl.c:1128 #, c-format -msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" +msgid "" +"private key file \"%s\" has group or world access; permissions should be " +"u=rw (0600) or less\n" msgstr "" "le fichier de la clé privée « %s » a des droits d'accès en lecture\n" "pour le groupe ou universel ; les droits devraient être u=rw (0600)\n" "ou inférieur\n" -#: fe-secure-openssl.c:1252 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "n'a pas pu charger le fichier de clé privée « %s » : %s\n" -#: fe-secure-openssl.c:1266 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "le certificat ne correspond pas à la clé privée « %s » : %s\n" -#: fe-secure-openssl.c:1366 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "le certificat n'a pas pu être obtenu : %s\n" -#: fe-secure-openssl.c:1458 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "aucune erreur SSL reportée" -#: fe-secure-openssl.c:1467 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "erreur SSL %lu" -#: fe-secure.c:261 +#: fe-secure.c:276 #, c-format msgid "could not receive data from server: %s\n" msgstr "n'a pas pu recevoir des données depuis le serveur : %s\n" -#: fe-secure.c:369 +#: fe-secure.c:392 #, c-format msgid "could not send data to server: %s\n" msgstr "n'a pas pu transmettre les données au serveur : %s\n" @@ -1151,6 +1263,9 @@ msgstr "n'a pas pu transmettre les données au serveur : %s\n" msgid "unrecognized socket error: 0x%08X/%d" msgstr "erreur de socket non reconnue : 0x%08X/%d" +#~ msgid "failed to generate nonce\n" +#~ msgstr "échec pour la génération de nonce\n" + #~ msgid "socket not open\n" #~ msgstr "socket non ouvert\n" @@ -1165,10 +1280,13 @@ msgstr "erreur de socket non reconnue : 0x%08X/%d" #~ msgid "could not get home directory to locate client certificate files\n" #~ msgstr "" -#~ "n'a pas pu récupérer le répertoire personnel pour trouver les certificats\n" +#~ "n'a pas pu récupérer le répertoire personnel pour trouver les " +#~ "certificats\n" #~ "du client\n" -#~ msgid "verified SSL connections are only supported when connecting to a host name\n" +#~ msgid "" +#~ "verified SSL connections are only supported when connecting to a host " +#~ "name\n" #~ msgstr "" #~ "les connexions SSL vérifiées ne sont supportées que lors de la connexion\n" #~ "à un alias hôte\n" @@ -1183,7 +1301,9 @@ msgstr "erreur de socket non reconnue : 0x%08X/%d" #~ msgstr "n'a pas pu lire la clé privée « %s » : %s\n" #~ msgid "invalid appname state %d, probably indicative of memory corruption\n" -#~ msgstr "état appname %d invalide, indiquant probablement une corruption de la mémoire\n" +#~ msgstr "" +#~ "état appname %d invalide, indiquant probablement une corruption de la " +#~ "mémoire\n" #~ msgid "invalid sslverify value: \"%s\"\n" #~ msgstr "valeur sslverify invalide : « %s »\n" @@ -1205,3 +1325,16 @@ msgstr "erreur de socket non reconnue : 0x%08X/%d" #~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" #~ msgstr "setsockopt(TCP_KEEPIDLE) a échoué : %s\n" + +#~ msgid "could not get home directory to locate service definition file" +#~ msgstr "" +#~ "n'a pas pu obtenir le répertoire personnel pour trouver le certificat de\n" +#~ "définition du service" + +#~ msgid "could not get home directory to locate password file\n" +#~ msgstr "" +#~ "n'a pas pu obtenir le répertoire personnel pour trouver le fichier de\n" +#~ "mot de passe\n" + +#~ msgid "GSSAPI name import error" +#~ msgstr "erreur d'import du nom GSSAPI" diff --git a/src/interfaces/libpq/po/he.po b/src/interfaces/libpq/po/he.po index 63472c1d61d..2b26f6058e8 100644 --- a/src/interfaces/libpq/po/he.po +++ b/src/interfaces/libpq/po/he.po @@ -116,12 +116,12 @@ msgstr "שיטת ×”×ימות %u ××™× ×” נתמכת\n" #: fe-auth.c:1045 #, c-format msgid "user name lookup failure: error code %lu\n" -msgstr "כישלון בדיקה עבור ×©× ×”×ž×©×ª×ž×©: קוד שגי××” % lu\n" +msgstr "כישלון בדיקה עבור ×©× ×”×ž×©×ª×ž×©: קוד שגי××” %lu\n" #: fe-auth.c:1055 fe-connect.c:2258 #, c-format msgid "could not look up local user ID %d: %s\n" -msgstr "×œ× ×™×›×•×œ לחפש משתמש מקומי ×¢× ×ž×–×”×” % d: %s\n" +msgstr "×œ× ×™×›×•×œ לחפש משתמש מקומי ×¢× ×ž×–×”×” %d: %s\n" #: fe-auth.c:1060 fe-connect.c:2263 #, c-format @@ -225,7 +225,7 @@ msgstr "נכשל setsockopt(TCP_KEEPCNT): %s\n" #: fe-connect.c:1561 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" -msgstr "נכשל WSAIoctl(SIO_KEEPALIVE_VALS): % ui\n" +msgstr "נכשל WSAIoctl(SIO_KEEPALIVE_VALS): %ui\n" #: fe-connect.c:1619 #, c-format @@ -701,12 +701,12 @@ msgstr "×ין ×פשרות לקבוע ×ת OID של פונקציה lowrite\n" #: fe-misc.c:292 #, c-format msgid "integer of size %lu not supported by pqGetInt" -msgstr "מספר ×©×œ× ×‘×’×•×“×œ % lu ×ינו נתמך על ידי pqGetInt" +msgstr "מספר ×©×œ× ×‘×’×•×“×œ %lu ×ינו נתמך על ידי pqGetInt" #: fe-misc.c:328 #, c-format msgid "integer of size %lu not supported by pqPutInt" -msgstr "מספר ×©×œ× ×‘×’×•×“×œ % lu ×ינו נתמך על ידי pqPutInt" +msgstr "מספר ×©×œ× ×‘×’×•×“×œ %lu ×ינו נתמך על ידי pqPutInt" #: fe-misc.c:639 fe-misc.c:840 msgid "connection not open\n" @@ -760,7 +760,7 @@ msgstr "×ין זיכרון פנוי" #: fe-protocol2.c:529 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" -msgstr "תו ×œ× ×¦×¤×•×™% c בעקבות תגובת ש×ילתה ריקה (הודעת \"I\")" +msgstr "תו ×œ× ×¦×¤×•×™ %c בעקבות תגובת ש×ילתה ריקה (הודעת \"I\")" #: fe-protocol2.c:595 #, c-format @@ -913,7 +913,7 @@ msgstr "%s:%s" #: fe-protocol3.c:1316 #, c-format msgid "LINE %d: " -msgstr "השורה % d: " +msgstr "השורה %d: " #: fe-protocol3.c:1711 msgid "PQgetline: not doing text COPY OUT\n" @@ -1069,7 +1069,7 @@ msgstr "×ין דיווח על שגי×ת SSL" #: fe-secure-openssl.c:1465 #, c-format msgid "SSL error code %lu" -msgstr "קוד שגי×ת SSL % lu" +msgstr "קוד שגי×ת SSL %lu" #: fe-secure.c:261 #, c-format diff --git a/src/interfaces/libpq/po/it.po b/src/interfaces/libpq/po/it.po index 87c35628934..737f35bd78d 100644 --- a/src/interfaces/libpq/po/it.po +++ b/src/interfaces/libpq/po/it.po @@ -1,56 +1,105 @@ # -# Translation of libpq to Italian -# PostgreSQL Project +# libpq.po +# Italian message translation file for libpq # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Daniele Varrazzo -# * Maurizio Totti +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Emanuele Zamprogno -# -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project -# -# Translation of libpq to Italian -# PostgreSQL Project -# -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org -# -# Traduttori: -# * Maurizio Totti -# -# Revisori: -# * Emanuele Zamprogno -# -# Copyright (c) 2009, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project -# -# Italian translation file for libpq. +# Daniele Varrazzo , 2012-2017 +# Maurizio Totti , 2010 # Fabrizio Mazzoni , 2003. +# Gaetano Mendola , 2003. # -# Versione 1.00 del 12 Ottobre 2003 -# Revisione 1.01 del 14 Ottobre 2003 a cura di Gaetano Mendola +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: libpq (PostgreSQL) 10\n" +"Project-Id-Version: libpq (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:38+0000\n" -"PO-Revision-Date: 2017-05-23 01:18+0100\n" +"POT-Creation-Date: 2018-10-08 14:08+0000\n" +"PO-Revision-Date: 2018-10-08 21:59+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-SourceCharset: UTF-8\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" + +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (empty message)\n" +msgstr "messaggio SCRAM malformato (messaggio vuoto)\n" + +#: fe-auth-scram.c:195 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "messaggio SCRAM malformato (lunghezza errata)\n" + +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "firma del server non corretta\n" + +#: fe-auth-scram.c:253 +msgid "invalid SCRAM exchange state\n" +msgstr "stato di scambio SCRAM non valido\n" + +#: fe-auth-scram.c:276 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "messaggio SCRAM malformato (atteso attributo \"%c\")\n" + +#: fe-auth-scram.c:285 +#, c-format +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "messaggio SCRAM malformato (atteso carattere \"=\" per l'attributo \"%c\")\n" + +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" +msgstr "generazione del nonce fallita\n" + +#: fe-auth-scram.c:334 fe-auth-scram.c:401 fe-auth-scram.c:523 +#: fe-auth-scram.c:543 fe-auth-scram.c:569 fe-auth-scram.c:583 +#: fe-auth-scram.c:625 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:643 fe-auth.c:802 fe-auth.c:1114 fe-auth.c:1262 fe-connect.c:835 +#: fe-connect.c:1264 fe-connect.c:1440 fe-connect.c:1922 fe-connect.c:1945 +#: fe-connect.c:2606 fe-connect.c:4152 fe-connect.c:4404 fe-connect.c:4523 +#: fe-connect.c:4773 fe-connect.c:4853 fe-connect.c:4952 fe-connect.c:5208 +#: fe-connect.c:5237 fe-connect.c:5309 fe-connect.c:5333 fe-connect.c:5351 +#: fe-connect.c:5452 fe-connect.c:5461 fe-connect.c:5817 fe-connect.c:5967 +#: fe-exec.c:2702 fe-exec.c:3449 fe-exec.c:3614 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1685 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "memoria esaurita\n" + +#: fe-auth-scram.c:561 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "risposta SCRAM non valida (il nonce non combacia)\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "messaggio SCRAM malformato (numero di iterazione non valido)\n" + +#: fe-auth-scram.c:606 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "messaggio SCRAM malformato (dati non riconosciuti dopo il primo messaggio del server)\n" + +#: fe-auth-scram.c:636 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "errore ricevuto dal server durante lo scambio SCRAM: %s\n" + +#: fe-auth-scram.c:652 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "messaggio SCRAM malformato (dati non riconosciuti dopo il messaggio finale del server)\n" + +#: fe-auth-scram.c:660 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "messaggio SCRAM malformato (firma del server non valida)\n" #: fe-auth.c:122 #, c-format @@ -58,152 +107,149 @@ msgid "out of memory allocating GSSAPI buffer (%d)\n" msgstr "memoria esaurita nell'allocazione del buffer GSSAPI (%d)\n" # DV: non ne sono convinto -#: fe-auth.c:172 +#: fe-auth.c:177 msgid "GSSAPI continuation error" msgstr "GSSAPI errore di continuazione" -#: fe-auth.c:202 fe-auth.c:451 +#: fe-auth.c:207 fe-auth.c:461 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "il nome dell'host deve essere specificato\n" -#: fe-auth.c:209 +#: fe-auth.c:214 msgid "duplicate GSS authentication request\n" msgstr "richiesta di autenticazione GSS duplicata\n" -#: fe-auth.c:222 fe-auth.c:357 fe-auth.c:422 fe-auth.c:457 fe-auth.c:599 -#: fe-auth.c:758 fe-auth.c:1070 fe-auth.c:1217 fe-connect.c:712 -#: fe-connect.c:1091 fe-connect.c:1267 fe-connect.c:1824 fe-connect.c:2352 -#: fe-connect.c:3953 fe-connect.c:4205 fe-connect.c:4324 fe-connect.c:4564 -#: fe-connect.c:4644 fe-connect.c:4743 fe-connect.c:4999 fe-connect.c:5028 -#: fe-connect.c:5100 fe-connect.c:5124 fe-connect.c:5142 fe-connect.c:5243 -#: fe-connect.c:5252 fe-connect.c:5608 fe-connect.c:5758 fe-exec.c:2651 -#: fe-exec.c:3398 fe-exec.c:3563 fe-lobj.c:896 fe-protocol2.c:1206 -#: fe-protocol3.c:992 fe-protocol3.c:1678 fe-secure-openssl.c:514 -#: fe-secure-openssl.c:1138 -msgid "out of memory\n" -msgstr "memoria esaurita\n" - # non è che mi torni tanto così -#: fe-auth.c:235 +#: fe-auth.c:240 msgid "GSSAPI name import error" msgstr "errore di importazione del nome GSSAPI" -#: fe-auth.c:298 +#: fe-auth.c:303 #, c-format msgid "out of memory allocating SSPI buffer (%d)\n" msgstr "memoria esaurita nell'allocazione del buffer SSPI (%d)\n" -#: fe-auth.c:346 +#: fe-auth.c:351 msgid "SSPI continuation error" msgstr "SSPI errore di continuazione" -#: fe-auth.c:437 +#: fe-auth.c:422 +msgid "duplicate SSPI authentication request\n" +msgstr "richiesta di autenticazione SSPI duplicata\n" + +#: fe-auth.c:447 msgid "could not acquire SSPI credentials" msgstr "non è stato possibile ottenere le credenziali SSPI" -#: fe-auth.c:490 +#: fe-auth.c:501 msgid "duplicate SASL authentication request\n" msgstr "doppia richiesta di autenticazione SASL\n" -#: fe-auth.c:550 +#: fe-auth.c:549 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "il server ha offerto autenticazione SCRAM-SHA-256-PLUS su una connessione non SSL\n" + +#: fe-auth.c:561 msgid "none of the server's SASL authentication mechanisms are supported\n" msgstr "nessuno dei meccanismi di autenticazione SASL del server è supportato\n" -#: fe-auth.c:623 +#: fe-auth.c:667 #, c-format msgid "out of memory allocating SASL buffer (%d)\n" msgstr "memoria esaurita nell'allocazione del buffer SASL (%d)\n" -#: fe-auth.c:648 +#: fe-auth.c:692 msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" msgstr "ricevuto AuthenticationSASLFinal dal server, ma l'autenticazione SASL non è stata completata\n" -#: fe-auth.c:725 +#: fe-auth.c:769 msgid "SCM_CRED authentication method not supported\n" msgstr "il metodo di autenticazione SCM_CRED non è supportato\n" -#: fe-auth.c:816 +#: fe-auth.c:860 msgid "Kerberos 4 authentication not supported\n" msgstr "l'autenticazione Kerberos 4 non è supportata\n" -#: fe-auth.c:821 +#: fe-auth.c:865 msgid "Kerberos 5 authentication not supported\n" msgstr "l'autenticazione Kerberos 5 non è supportata\n" -#: fe-auth.c:892 +#: fe-auth.c:936 msgid "GSSAPI authentication not supported\n" msgstr "l'autenticazione GSSAPI non è supportata\n" -#: fe-auth.c:924 +#: fe-auth.c:968 msgid "SSPI authentication not supported\n" msgstr "l'autenticazione SSPI non è supportata\n" -#: fe-auth.c:932 +#: fe-auth.c:976 msgid "Crypt authentication not supported\n" msgstr "l'autenticazione Crypt non è supportata\n" -#: fe-auth.c:998 +#: fe-auth.c:1042 #, c-format msgid "authentication method %u not supported\n" msgstr "l'autenticazione %u non è supportata\n" -#: fe-auth.c:1045 +#: fe-auth.c:1089 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "ricerca del nome utente fallita: codice di errore %lu\n" -#: fe-auth.c:1055 fe-connect.c:2279 +#: fe-auth.c:1099 fe-connect.c:2533 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "ricerca dell'ID utente locale %d non riuscita: %s\n" -#: fe-auth.c:1060 fe-connect.c:2284 +#: fe-auth.c:1104 fe-connect.c:2538 #, c-format msgid "local user with ID %d does not exist\n" msgstr "l'utente locale con ID %d non esiste\n" -#: fe-auth.c:1162 +#: fe-auth.c:1206 msgid "unexpected shape of result set returned for SHOW\n" msgstr "il risultato restituito da SHOW ha una forma imprevista\n" -#: fe-auth.c:1171 +#: fe-auth.c:1215 msgid "password_encryption value too long\n" msgstr "valore di password_encryption troppo lungo\n" -#: fe-auth.c:1211 -msgid "unknown password encryption algorithm\n" -msgstr "algoritmo di criptaggio della password sconosciuto\n" +#: fe-auth.c:1255 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "algoritmo di criptaggio della password \"%s\" sconosciuto\n" + +#: fe-connect.c:1018 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "non è possibile far combaciare %d nomi host con %d valori hostaddr\n" -#: fe-connect.c:913 +#: fe-connect.c:1094 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "non è possibile far combaciare %d numeri di porta con %d host\n" -#: fe-connect.c:965 -msgid "could not get home directory to locate password file\n" -msgstr "errore nel raggiungere la directory home per trovare il file delle password\n" - -#: fe-connect.c:1017 +#: fe-connect.c:1190 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "valore sslmode errato: \"%s\"\n" -#: fe-connect.c:1038 +#: fe-connect.c:1211 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "valore sslmode \"%s\" non valido quando il supporto SSL non è compilato\n" -#: fe-connect.c:1073 +#: fe-connect.c:1246 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "valore per target_session_attrs non valido: \"%s\"\n" -#: fe-connect.c:1291 +#: fe-connect.c:1464 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "impostazione del socket in modalità TCP no delay fallita: %s\n" -#: fe-connect.c:1321 +#: fe-connect.c:1494 #, c-format msgid "" "could not connect to server: %s\n" @@ -214,7 +260,7 @@ msgstr "" "\tVerifica che il server locale sia in funzione e che\n" "\taccetti connessioni sul socket di dominio Unix \"%s\"\n" -#: fe-connect.c:1376 +#: fe-connect.c:1552 #, c-format msgid "" "could not connect to server: %s\n" @@ -225,7 +271,7 @@ msgstr "" "\tVerifica che il server all'indirizzo \"%s\" (%s) sia in funzione\n" "\te che accetti connessioni TCP/IP sulla porta %s\n" -#: fe-connect.c:1385 +#: fe-connect.c:1561 #, c-format msgid "" "could not connect to server: %s\n" @@ -236,510 +282,510 @@ msgstr "" "\tVerifica che il server all'indirizzo \"%s\" sia in funzione\n" "\te che accetti connessioni TCP/IP sulla porta %s\n" -#: fe-connect.c:1436 +#: fe-connect.c:1612 fe-connect.c:1644 fe-connect.c:1677 fe-connect.c:2325 #, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "chiamata setsockopt(TCP_KEEPIDLE) fallita: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "setsockopt(%s) fallita: %s\n" -#: fe-connect.c:1449 +#: fe-connect.c:1726 #, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "chiamata setsockopt(TCP_KEEPALIVE) fallita: %s\n" +msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" +msgstr "chiamata WSAIoctl(SIO_KEEPALIVE_VALS) fallito: %ui\n" -#: fe-connect.c:1481 -#, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "chiamata setsockopt(TCP_KEEPINTVL) fallita: %s\n" +#: fe-connect.c:2035 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "stato della connessione non valido, probabilmente indica una corruzione della memoria\n" -#: fe-connect.c:1513 +#: fe-connect.c:2101 #, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "chiamata setsockopt(TCP_KEEPCNT) fallita: %s\n" +msgid "invalid port number: \"%s\"\n" +msgstr "numero di porta non valido: \"%s\"\n" -#: fe-connect.c:1561 +#: fe-connect.c:2117 #, c-format -msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" -msgstr "chiamata WSAIoctl(SIO_KEEPALIVE_VALS) fallito: %ui\n" +msgid "could not translate host name \"%s\" to address: %s\n" +msgstr "conversione del nome host \"%s\" in indirizzo fallita: %s\n" -#: fe-connect.c:1619 +#: fe-connect.c:2130 #, c-format -msgid "invalid port number: \"%s\"\n" -msgstr "numero di porta non valido: \"%s\"\n" +msgid "could not parse network address \"%s\": %s\n" +msgstr "interpretazione dell'indirizzo di rete \"%s\" fallita: %s\n" -#: fe-connect.c:1643 +#: fe-connect.c:2143 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "Il percorso del socket di dominio unix \"%s\" è troppo lungo (massimo %d byte)\n" -#: fe-connect.c:1661 -#, c-format -msgid "could not translate host name \"%s\" to address: %s\n" -msgstr "conversione del nome host \"%s\" in indirizzo fallita: %s\n" - -#: fe-connect.c:1665 +#: fe-connect.c:2158 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "conversione del percorso del socket di dominio Unix \"%s\" in indirizzo fallita: %s\n" -#: fe-connect.c:1930 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "stato della connessione non valido, probabilmente indica una corruzione della memoria\n" - -#: fe-connect.c:1987 +#: fe-connect.c:2262 #, c-format msgid "could not create socket: %s\n" msgstr "creazione del socket fallita: %s\n" -#: fe-connect.c:2009 +#: fe-connect.c:2284 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "impostazione del socket in modalità non bloccante fallita: %s\n" -#: fe-connect.c:2020 +#: fe-connect.c:2294 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "impostazione del socket in modalità close-on-exec fallita: %s\n" -#: fe-connect.c:2039 +#: fe-connect.c:2312 msgid "keepalives parameter must be an integer\n" msgstr "il parametro keepalives dev'essere un intero\n" -#: fe-connect.c:2052 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "chiamata setsockopt(SO_KEEPALIVE) fallita: %s\n" - -#: fe-connect.c:2189 +#: fe-connect.c:2450 #, c-format msgid "could not get socket error status: %s\n" msgstr "lettura dello stato di errore del socket fallita: %s\n" -#: fe-connect.c:2224 +#: fe-connect.c:2478 #, c-format msgid "could not get client address from socket: %s\n" msgstr "non è stato possibile ottenere l'indirizzo del client dal socket: %s\n" -#: fe-connect.c:2266 +#: fe-connect.c:2520 msgid "requirepeer parameter is not supported on this platform\n" msgstr "il parametro requirepeer non è supportato su questa piattaforma\n" -#: fe-connect.c:2269 +#: fe-connect.c:2523 #, c-format msgid "could not get peer credentials: %s\n" msgstr "non è stato possibile ottenere le credenziali del peer: %s\n" -#: fe-connect.c:2292 +#: fe-connect.c:2546 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeer specifica \"%s\", ma il vero nome utente del peer è \"%s\"\n" -#: fe-connect.c:2326 +#: fe-connect.c:2580 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "invio del pacchetto di negoziazione SSL fallito: %s\n" -#: fe-connect.c:2365 +#: fe-connect.c:2619 #, c-format msgid "could not send startup packet: %s\n" msgstr "invio del pacchetto di avvio fallito: %s\n" -#: fe-connect.c:2435 +#: fe-connect.c:2689 msgid "server does not support SSL, but SSL was required\n" msgstr "il server non supporta SSL, ma SSL è stato richiesto\n" -#: fe-connect.c:2461 +#: fe-connect.c:2715 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "ricevuta risposta errata alla negoziazione SSL: %c\n" -#: fe-connect.c:2537 fe-connect.c:2570 +#: fe-connect.c:2792 fe-connect.c:2825 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "prevista richiesta di autenticazione dal server, ma è stato ricevuto %c\n" -#: fe-connect.c:2799 +#: fe-connect.c:3052 msgid "unexpected message from server during startup\n" msgstr "messaggio imprevisto dal server durante l'avvio\n" -#: fe-connect.c:3003 +#: fe-connect.c:3282 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "errore nello stabilire una connessione scrivibile col server \"%s:%s\"\n" -#: fe-connect.c:3045 +#: fe-connect.c:3328 #, c-format -msgid "test \"SHOW transaction_read_only\" failed on \"%s:%s\"\n" -msgstr "test \"SHOW transaction_read_only\" fallito su \"%s:%s\"\n" +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "test \"SHOW transaction_read_only\" fallito sul server \"%s:%s\"\n" -#: fe-connect.c:3067 +#: fe-connect.c:3343 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "stato connessione errato %d, probabilmente indica una corruzione di memoria\n" -#: fe-connect.c:3559 fe-connect.c:3619 +#: fe-connect.c:3758 fe-connect.c:3818 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc \"%s\" fallito durante l'evento PGEVT_CONNRESET\n" -#: fe-connect.c:3966 +#: fe-connect.c:4165 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "URL LDAP \"%s\" non corretta: lo schema deve essere ldap://\n" -#: fe-connect.c:3981 +#: fe-connect.c:4180 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "URL LDAP \"%s\" non corretta: distinguished name non trovato\n" -#: fe-connect.c:3992 fe-connect.c:4045 +#: fe-connect.c:4191 fe-connect.c:4244 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "URL LDAP \"%s\" non corretta: deve avere esattamente un attributo\n" -#: fe-connect.c:4002 fe-connect.c:4059 +#: fe-connect.c:4201 fe-connect.c:4258 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "URL LDAP \"%s\" non corretta: deve essere specificato la portata della ricerca (base/one/sub)\n" -#: fe-connect.c:4013 +#: fe-connect.c:4212 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "URL LDAP \"%s\" non corretta: filtro non specificato\n" -#: fe-connect.c:4034 +#: fe-connect.c:4233 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "URL LDAP \"%s\" non corretta: numero di porta non valido\n" -#: fe-connect.c:4068 +#: fe-connect.c:4267 msgid "could not create LDAP structure\n" msgstr "creazione della struttura dati LDAP fallita\n" -#: fe-connect.c:4144 +#: fe-connect.c:4343 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "ricerca del server LDAP fallita: %s\n" -#: fe-connect.c:4155 +#: fe-connect.c:4354 msgid "more than one entry found on LDAP lookup\n" msgstr "trovata più di una voce nella ricerca LDAP\n" -#: fe-connect.c:4156 fe-connect.c:4168 +#: fe-connect.c:4355 fe-connect.c:4367 msgid "no entry found on LDAP lookup\n" msgstr "nessun elemento trovato per la ricerca LDAP\n" -#: fe-connect.c:4179 fe-connect.c:4192 +#: fe-connect.c:4378 fe-connect.c:4391 msgid "attribute has no values on LDAP lookup\n" msgstr "l'attributo non ha valori nella ricerca LDAP\n" -#: fe-connect.c:4244 fe-connect.c:4263 fe-connect.c:4782 +#: fe-connect.c:4443 fe-connect.c:4462 fe-connect.c:4991 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "manca \"=\" dopo \"%s\" nella stringa di connessione\n" -#: fe-connect.c:4336 fe-connect.c:4967 fe-connect.c:5741 +#: fe-connect.c:4535 fe-connect.c:5176 fe-connect.c:5950 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "opzione di connessione errata \"%s\"\n" -#: fe-connect.c:4352 fe-connect.c:4831 +#: fe-connect.c:4551 fe-connect.c:5040 msgid "unterminated quoted string in connection info string\n" msgstr "stringa tra virgolette non terminata nella stringa di connessione\n" -#: fe-connect.c:4392 -msgid "could not get home directory to locate service definition file" -msgstr "directory home non trovata per la localizzazione del file di definizione di servizio" - -#: fe-connect.c:4425 +#: fe-connect.c:4634 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "il file di definizione di servizio \"%s\" non è stato trovato\n" -#: fe-connect.c:4448 +#: fe-connect.c:4657 #, c-format msgid "service file \"%s\" not found\n" msgstr "il file di servizio \"%s\" non è stato trovato\n" -#: fe-connect.c:4461 +#: fe-connect.c:4670 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "la riga %d nel file di servizio \"%s\" è troppo lunga\n" -#: fe-connect.c:4532 fe-connect.c:4576 +#: fe-connect.c:4741 fe-connect.c:4785 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "errore di sintassi del file di servizio \"%s\", alla riga %d\n" -#: fe-connect.c:4543 +#: fe-connect.c:4752 #, c-format msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "specifiche di servizio annidate non supportate nel file di servizio \"%s\", linea %d\n" -#: fe-connect.c:5263 +#: fe-connect.c:5472 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "URI invalida propagata alla routine di parsing interna: \"%s\"\n" -#: fe-connect.c:5340 +#: fe-connect.c:5549 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "fine stringa raggiunta cercando un \"]\" corrispondente nell'indirizzo host IPv6 nella URI: \"%s\"\n" -#: fe-connect.c:5347 +#: fe-connect.c:5556 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "l'indirizzo host IPv6 non dev'essere assente nella URI: \"%s\"\n" -#: fe-connect.c:5362 +#: fe-connect.c:5571 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" msgstr "carattere inatteso \"%c\" in posizione %d nella uri URI (atteso \":\" oppure \"/\"): \"%s\"\n" -#: fe-connect.c:5491 +#: fe-connect.c:5700 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "separatore chiave/valore \"=\" in eccesso nei parametri della URI: \"%s\"\n" -#: fe-connect.c:5511 +#: fe-connect.c:5720 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "separatore chiave/valore \"=\" mancante nei parametri della URI: \"%s\"\n" -#: fe-connect.c:5562 +#: fe-connect.c:5771 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "parametro URI non valido: \"%s\"\n" -#: fe-connect.c:5636 +#: fe-connect.c:5845 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "simbolo percent-encoded non valido \"%s\"\n" -#: fe-connect.c:5646 +#: fe-connect.c:5855 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "valore non ammesso %%00 nel valore percent-encoded: \"%s\"\n" -#: fe-connect.c:5991 +#: fe-connect.c:6201 msgid "connection pointer is NULL\n" msgstr "il puntatore della connessione è NULL\n" -#: fe-connect.c:6289 +#: fe-connect.c:6499 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "ATTENZIONE: il file delle password \"%s\" non è un file regolare\n" -#: fe-connect.c:6298 +#: fe-connect.c:6508 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "" "ATTENZIONE: Il file delle password %s ha privilegi di accesso in lettura e scrittura per tutti;\n" "i permessi dovrebbero essere u=rw (0600) o inferiori\n" -#: fe-connect.c:6390 +#: fe-connect.c:6602 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "password ottenuta dal file \"%s\"\n" -#: fe-exec.c:826 +#: fe-exec.c:437 fe-exec.c:2776 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "la riga numero %d non è compreso tra 0 e %d" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "memoria esaurita" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "NOTIFICA" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult non può supportare più di INT_MAX tuple" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "overflow size_t" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "il testo del comando è un puntatore nullo\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "il numero di parametri deve essere tra 0 e 65535\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "il nome dell'istruzione è un puntatore nullo\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2390 msgid "function requires at least protocol version 3.0\n" msgstr "la funzione richiede almeno il protocollo versione 3.0\n" -#: fe-exec.c:1377 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "nessuna connessione al server\n" -#: fe-exec.c:1384 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "un altro comando è in esecuzione\n" -#: fe-exec.c:1498 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "la lunghezza deve essere fornita per i parametri binari\n" -#: fe-exec.c:1770 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "asyncStatus imprevisto: %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc \"%s\" fallito durante l'evento PGEVT_RESULTCREATE\n" -#: fe-exec.c:1950 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "COPY terminato da una nuova PQexec" -#: fe-exec.c:1958 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "lo stato COPY IN deve prima essere terminato\n" -#: fe-exec.c:1978 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "lo stato COPY OUT deve prima essere terminato\n" # NON SONO ASSOLUTAMENTE CONVINTO! -#: fe-exec.c:1986 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec not consentito durante COPY BOTH\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2280 fe-exec.c:2347 fe-exec.c:2437 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "nessun comando COPY in corso\n" -#: fe-exec.c:2576 +#: fe-exec.c:2627 msgid "connection in wrong state\n" msgstr "la connessione è in uno stato errato\n" -#: fe-exec.c:2607 +#: fe-exec.c:2658 msgid "invalid ExecStatusType code" msgstr "codice ExecStatusType errato" -#: fe-exec.c:2634 +#: fe-exec.c:2685 msgid "PGresult is not an error result\n" msgstr "PGresult non è un risultato di errore\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2760 fe-exec.c:2783 #, c-format msgid "column number %d is out of range 0..%d" msgstr "la colonna numero %d non è compreso tra 0 e %d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "la riga numero %d non è compreso tra 0 e %d" - -#: fe-exec.c:2747 +#: fe-exec.c:2798 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "il parametro numero %d non è compreso tra 0 e %d" -#: fe-exec.c:3057 +#: fe-exec.c:3108 #, c-format msgid "could not interpret result from server: %s" msgstr "errore nell'interpretazione del risultato dal server: %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3347 fe-exec.c:3431 msgid "incomplete multibyte character\n" msgstr "carattere multibyte incompleto\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "non è possibile determinare l'OID della funzione lo_truncate\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "l'argomento di lo_truncate supera l'intervallo degli interi\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "non è possibile determinare l'OID della funzione lo_truncate64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "l'argomento di lo_read supera l'intervallo degli interi\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "l'argomento di lo_write supera l'intervallo degli interi\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "non è possibile determinare l'OID della funzione lo_seek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "non è possibile determinare l'OID della funzione lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "non è possibile determinare l'OID della funzione lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "apertura del file \"%s\" fallita: %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "lettura dal file \"%s\" fallita: %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "scrittura nel file \"%s\" fallita: %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "la query per inizializzare le funzioni large object non hanno restituito dati\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "non è possibile determinare l'OID della funzione lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "non è possibile determinare l'OID della funzione lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "non è possibile determinare l'OID della funzione lo_create\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "non è possibile determinare l'OID della funzione lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "non è possibile determinare l'OID della funzione lo_seek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "non è possibile determinare l'OID della funzione lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "non è possibile determinare l'OID della funzione loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "non è possibile determinare l'OID della funzione lowrite\n" -#: fe-misc.c:292 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "intero di dimensione %lu non supportato da pqGetInt" -#: fe-misc.c:328 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "intero di dimensione %lu non supportato da pqPutInt" -#: fe-misc.c:639 fe-misc.c:840 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "connessione non aperta\n" -#: fe-misc.c:809 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -749,255 +795,257 @@ msgstr "" "\tQuesto probabilmente indica che il server ha terminato in modo anormale\n" "\tprima o durante l'elaborazione della richiesta.\n" -#: fe-misc.c:1011 +#: fe-misc.c:1009 msgid "timeout expired\n" msgstr "timeout scaduto\n" -#: fe-misc.c:1056 +#: fe-misc.c:1054 msgid "invalid socket\n" msgstr "socket non valido\n" -#: fe-misc.c:1079 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "select() fallita: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "stato %c di setenv non valido, probabilmente indica una corruzione di memoria\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "stato %c non valido, probabilmente indica una corruzione di memoria\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "messaggio tipo 0x%02x arrivato dal server mentre era inattivo" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 fe-protocol3.c:209 -#: fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 fe-protocol3.c:728 -#: fe-protocol3.c:951 -msgid "out of memory" -msgstr "memoria esaurita" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "carattere %c non previsto a seguito di una risposta vuota ad una query (messaggio \"I\")" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "il server ha spedito dati (messaggio di tipo \"D\") senza prima il descrittore di riga (messaggio di tipo \"T\")" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" msgstr "il server ha spedito dati binari (messaggio di tipo \"B\") senza prima il descrittore di riga (messaggio di tipo \"T\")" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "risposta inattesa dal server; il primo carattere ricevuto era \"%c\"\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "memoria esaurita per il risultato della query" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "persa la sincronizzazione con il server, sto resettando la connessione" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "errore di protocollo: id=0x%x\n" -#: fe-protocol3.c:368 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" msgstr "il server ha spedito dati (messaggio di tipo \"D\") senza prima il descrittore di riga (messaggio di tipo \"T\")\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "i contenuti del messaggio non sono in accordo con la lunghezza del tipo di messaggio \"%c\"\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "persa la sincronizzazione con il server: ricevuto il tipo di messaggio \"%c\" di lunghezza %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "dati insufficienti nel messaggio di tipo \"T\"" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "dati estranei nel messaggio di tipo \"T\"" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "dati estranei nel messaggio di tipo \"t\"" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "dati insufficienti nel messaggio di tipo \"D\"" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "numero dei campi non previsto nel messaggio di tipo \"D\"" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "dati estranei nel messaggio di tipo \"D\"" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "nessun messaggio di errore disponibile\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" msgstr " al carattere %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "DETTAGLI: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "NOTA: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "QUERY: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "CONTESTO: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1096 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "NOME SCHEMA: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1100 #, c-format msgid "TABLE NAME: %s\n" msgstr "NOME TABELLA: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1104 #, c-format msgid "COLUMN NAME: %s\n" msgstr "NOME COLONNA: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "NOME TIPO DATI: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1112 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "NOME VINCOLO: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "POSIZIONE: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "RIGA %d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: COPY OUT testuale ignorato\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1323 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "Il nome del certificato SSL contiene null\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "il nome dell'host dev'essere specificato per una connessione SSL verificata\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "il certificato per il server \"%s\" non combacia col nome host \"%s\"\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "impossibile ottenere il nome dell'host del server dal certificato del server\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "errore SSL SYSCALL: %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1327 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "errore SSL SYSCALL: rilevato EOF\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1336 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "errore SSL: %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "la connessione SSL è stata chiusa inaspettatamente\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1345 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "codice di errore SSL sconosciuto: %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "manca il nome del certificato SSL\n" - -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "Il nome del certificato SSL contiene null\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "impossibile determinare l'algoritmo di firma del certificato del server\n" -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "il nome dell'host dev'essere specificato per una connessione SSL verificata\n" - -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "il certificato per il server \"%s\" non combacia col nome host \"%s\"\n" +msgid "could not find digest for NID %s\n" +msgstr "impossibile trovare il digest per il NID %s\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "impossibile ottenere il nome dell'host del server dal certificato del server\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "impossibile generare l'hash del certificato del peer\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "manca il nome del certificato SSL\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "creazione del contesto SSL fallita: %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "lettura del file di certificato radice \"%s\" fallita: %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" msgstr "la libreria SSL non supporta i certificati di tipo CRL (file \"%s\")\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate verification.\n" @@ -1005,7 +1053,7 @@ msgstr "" "directory utente non trovata per la locazione del file di certificato radice\n" "Per favore fornisci il file oppure cambia sslmode per disabilitare la verifica del certificato del server.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1014,82 +1062,82 @@ msgstr "" "il file \"%s\" del certificato radice non esiste\n" "Per favore fornisci il file oppure cambia sslmode per disabilitare la verifica del certificato del server.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "apertura del file di certificato \"%s\" fallita: %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "lettura del file di certificato \"%s\" fallita: %s\n" -#: fe-secure-openssl.c:1100 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "non è stato possibile stabilire una connessione SSL: %s\n" -#: fe-secure-openssl.c:1154 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "caricamento del motore SSL \"%s\" fallito: %s\n" -#: fe-secure-openssl.c:1166 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "inizializzazione del motore SSL \"%s\" fallita: %s\n" -#: fe-secure-openssl.c:1182 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "lettura del file della chiave privata SSL \"%s\" dal motore \"%s\" fallita: %s\n" -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "caricamento della chiave privata SSL \"%s\" dal motore \"%s\" fallito: %s\n" -#: fe-secure-openssl.c:1233 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "certificato trovato, ma non la chiave privata \"%s\"\n" -#: fe-secure-openssl.c:1241 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "Il file della chiave privata \"%s\" ha privilegi di accesso in lettura e scrittura per tutti; i permessi dovrebbero essere u=rw (0600) o inferiori\n" -#: fe-secure-openssl.c:1252 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "caricamento del file della chiave privata \"%s\" fallito: %s\n" -#: fe-secure-openssl.c:1266 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "il certificato non corrisponde con il file della chiave privata \"%s\": %s\n" -#: fe-secure-openssl.c:1366 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "non è stato possibile possibile ottenere il certificato: %s\n" -#: fe-secure-openssl.c:1458 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "nessun errore SSL riportato" -#: fe-secure-openssl.c:1467 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "codice di errore SSL: %lu" -#: fe-secure.c:261 +#: fe-secure.c:269 #, c-format msgid "could not receive data from server: %s\n" msgstr "ricezione dati dal server fallita: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:378 #, c-format msgid "could not send data to server: %s\n" msgstr "invio dati al server fallito: %s\n" diff --git a/src/interfaces/libpq/po/ja.po b/src/interfaces/libpq/po/ja.po index b7335b639b7..a63edf628c1 100644 --- a/src/interfaces/libpq/po/ja.po +++ b/src/interfaces/libpq/po/ja.po @@ -3,112 +3,236 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.1 beta 2\n" +"Project-Id-Version: PostgreSQL 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 12:53+0900\n" -"PO-Revision-Date: 2014-08-16 16:38+0900\n" -"Last-Translator: HOTTA Michihide \n" +"POT-Creation-Date: 2018-08-31 16:21+0900\n" +"PO-Revision-Date: 2018-08-21 21:01+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" + +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (empty message)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (空ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸)\n" + +#: fe-auth-scram.c:195 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (é•·ã•ã®ä¸æ•´åˆ)\n" + +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "æ­£ã—ããªã„サーãƒç½²å\n" + +#: fe-auth-scram.c:253 +msgid "invalid SCRAM exchange state\n" +msgstr "䏿­£ãªSCRAM交æ›çŠ¶æ…‹\n" + +#: fe-auth-scram.c:276 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (属性 \"%c\" ãŒå¿…è¦)\n" + +#: fe-auth-scram.c:285 +#, c-format +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (属性 \"%c\" ã«æ–‡å­— \"=\" ãŒå¿…è¦)\n" + +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" +msgstr "nonce を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: fe-auth-scram.c:334 fe-auth-scram.c:401 fe-auth-scram.c:523 +#: fe-auth-scram.c:543 fe-auth-scram.c:569 fe-auth-scram.c:583 +#: fe-auth-scram.c:625 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:643 fe-auth.c:802 fe-auth.c:1114 fe-auth.c:1262 fe-connect.c:835 +#: fe-connect.c:1264 fe-connect.c:1440 fe-connect.c:1922 fe-connect.c:1945 +#: fe-connect.c:2606 fe-connect.c:4152 fe-connect.c:4404 fe-connect.c:4523 +#: fe-connect.c:4773 fe-connect.c:4853 fe-connect.c:4952 fe-connect.c:5208 +#: fe-connect.c:5237 fe-connect.c:5309 fe-connect.c:5333 fe-connect.c:5351 +#: fe-connect.c:5452 fe-connect.c:5461 fe-connect.c:5817 fe-connect.c:5967 +#: fe-exec.c:2702 fe-exec.c:3449 fe-exec.c:3614 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1685 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "メモリä¸è¶³\n" -#: fe-auth.c:210 fe-auth.c:429 fe-auth.c:656 -msgid "host name must be specified\n" -msgstr "ホストåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +#: fe-auth-scram.c:561 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "䏿­£ãªSCRAM応答 (nonce ã®ä¸ä¸€è‡´)\n" -#: fe-auth.c:240 -#, c-format -msgid "could not set socket to blocking mode: %s\n" -msgstr "ソケットをブロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (䏿­£ãªç¹°ã‚Šè¿”ã—回数)\n" + +#: fe-auth-scram.c:606 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (server-first-message 終端ã®ä½™åˆ†ãªãƒ‡ãƒ¼ã‚¿)\n" -#: fe-auth.c:258 fe-auth.c:262 +#: fe-auth-scram.c:636 #, c-format -msgid "Kerberos 5 authentication rejected: %*s\n" -msgstr "Kerberos 5èªè¨¼ãŒæ‹’çµ¶ã•れã¾ã—ãŸ: %*s\n" +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "SCRAM交æ›ä¸­ã«ã‚µãƒ¼ãƒã‹ã‚‰ã®ã‚¨ãƒ©ãƒ¼ã‚’å—ä¿¡ã—ã¾ã—ãŸ: %s\n" -#: fe-auth.c:288 +#: fe-auth-scram.c:652 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (server-final-message 終端ã®ä½™åˆ†ãªãƒ‡ãƒ¼ã‚¿)\n" + +#: fe-auth-scram.c:660 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "SCRAMメッセージã®ãƒ•ォーマット異常 (䏿­£ãªã‚µãƒ¼ãƒç½²å)\n" + +#: fe-auth.c:122 #, c-format -#| msgid "could not restore non-blocking mode on socket: %s\n" -msgid "could not restore nonblocking mode on socket: %s\n" -msgstr "ソケットをéžãƒ–ãƒ­ãƒƒã‚­ãƒ³ã‚°ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "GSSAPIãƒãƒƒãƒ•ã‚¡ã®å‰²ã‚Šå½“ã¦ã®éš›ã®ãƒ¡ãƒ¢ãƒªä¸è¶³(%d)\n" -#: fe-auth.c:400 +#: fe-auth.c:177 msgid "GSSAPI continuation error" msgstr "GSSAI続行エラー" -#: fe-auth.c:436 +#: fe-auth.c:207 fe-auth.c:461 fe-secure-common.c:98 +msgid "host name must be specified\n" +msgstr "ホストåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: fe-auth.c:214 msgid "duplicate GSS authentication request\n" msgstr "é‡è¤‡ã™ã‚‹GSSèªè¨¼è¦æ±‚\n" -#: fe-auth.c:456 +#: fe-auth.c:240 msgid "GSSAPI name import error" msgstr "GSSAPIåã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚¨ãƒ©ãƒ¼" -#: fe-auth.c:542 +#: fe-auth.c:303 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "SSPIãƒãƒƒãƒ•ã‚¡ã®å‰²ã‚Šå½“ã¦ã®éš›ã®ãƒ¡ãƒ¢ãƒªä¸è¶³(%d)\n" + +#: fe-auth.c:351 msgid "SSPI continuation error" msgstr "SSPI続行エラー" -#: fe-auth.c:553 fe-auth.c:627 fe-auth.c:662 fe-auth.c:758 fe-connect.c:2005 -#: fe-connect.c:3393 fe-connect.c:3611 fe-connect.c:4023 fe-connect.c:4118 -#: fe-connect.c:4383 fe-connect.c:4452 fe-connect.c:4469 fe-connect.c:4560 -#: fe-connect.c:4910 fe-connect.c:5060 fe-exec.c:3296 fe-exec.c:3461 -#: fe-lobj.c:896 fe-protocol2.c:1181 fe-protocol3.c:1544 fe-secure.c:786 -#: fe-secure.c:1184 -msgid "out of memory\n" -msgstr "メモリä¸è¶³ã§ã™\n" +#: fe-auth.c:422 +msgid "duplicate SSPI authentication request\n" +msgstr "é‡è¤‡ã™ã‚‹SSPIèªè¨¼è¦æ±‚\n" -#: fe-auth.c:642 +#: fe-auth.c:447 msgid "could not acquire SSPI credentials" msgstr "SSPI資格を入手ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: fe-auth.c:733 +#: fe-auth.c:501 +msgid "duplicate SASL authentication request\n" +msgstr "é‡è¤‡ã™ã‚‹SASLèªè¨¼è¦æ±‚\n" + +#: fe-auth.c:549 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "サーãƒãŒéžSSL接続上㧠SCRAM-SHA-256-PLUS èªè¨¼ã‚’æç¤ºã—ã¦ãã¾ã—ãŸ\n" + +#: fe-auth.c:561 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "サーãƒå´ã®ã„ãšã‚Œã®SASLèªè¨¼æ©Ÿæ§‹ã‚‚サãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" + +#: fe-auth.c:667 +#, c-format +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "SASLãƒãƒƒãƒ•ã‚¡ã®å‰²ã‚Šå½“ã¦ã®éš›ã®ãƒ¡ãƒ¢ãƒªä¸è¶³(%d)\n" + +#: fe-auth.c:692 +msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" +msgstr "サーãƒã‹ã‚‰AuthenticationSASLFinalã‚’å—ä¿¡ã—ã¾ã—ãŸã€ã—ã‹ã—SASLèªè¨¼ã¯å®Œäº†ã—ã¦ã„ã¾ã›ã‚“\n" + +#: fe-auth.c:769 msgid "SCM_CRED authentication method not supported\n" msgstr "SCM_CREDèªè¨¼æ–¹å¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:809 +#: fe-auth.c:860 msgid "Kerberos 4 authentication not supported\n" msgstr "Kerberos 4èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:825 +#: fe-auth.c:865 msgid "Kerberos 5 authentication not supported\n" msgstr "Kerberos 5èªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:897 +#: fe-auth.c:936 msgid "GSSAPI authentication not supported\n" msgstr "GSSAPIèªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:929 +#: fe-auth.c:968 msgid "SSPI authentication not supported\n" msgstr "SSPIèªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:937 +#: fe-auth.c:976 msgid "Crypt authentication not supported\n" msgstr "Cryptèªè¨¼ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-auth.c:964 +#: fe-auth.c:1042 #, c-format msgid "authentication method %u not supported\n" msgstr "èªè¨¼æ–¹å¼%uã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-connect.c:798 +#: fe-auth.c:1089 +#, c-format +msgid "user name lookup failure: error code %lu\n" +msgstr "ユーザーåã®æ¤œç´¢ã«å¤±æ•—: エラー コード %lu\n" + +#: fe-auth.c:1099 fe-connect.c:2533 +#, c-format +msgid "could not look up local user ID %d: %s\n" +msgstr "ローカルユーザID%dãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: fe-auth.c:1104 fe-connect.c:2538 +#, c-format +msgid "local user with ID %d does not exist\n" +msgstr "ID %d ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ã¯å­˜åœ¨ã—ã¾ã›ã‚“\n" + +#: fe-auth.c:1206 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "SHOW ã«å¯¾ã™ã‚‹äºˆæœŸã—ãªã„å½¢ã®ãƒªã‚¶ãƒ«ãƒˆã‚»ãƒƒãƒˆ\n" + +#: fe-auth.c:1215 +msgid "password_encryption value too long\n" +msgstr "password_encryptionã®å€¤ãŒé•·ã™ãŽã¾ã™\n" + +#: fe-auth.c:1255 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "èªè­˜ã§ããªã„パスワード暗å·åŒ–アルゴリズム \"%s\"\n" + +#: fe-connect.c:1018 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "%d個ã®ãƒ›ã‚¹ãƒˆåã¨%d個ã®hostaddrã®å€¤ã¨ã®çªãåˆã›ã¯ã§ãã¾ã›ã‚“\n" + +#: fe-connect.c:1094 +#, c-format +msgid "could not match %d port numbers to %d hosts\n" +msgstr "%d個ã®ãƒãƒ¼ãƒˆç•ªå·ã¨%d個ã®ãƒ›ã‚¹ãƒˆã¨ã®çªãåˆã›ã¯ã§ãã¾ã›ã‚“\n" + +#: fe-connect.c:1190 #, c-format msgid "invalid sslmode value: \"%s\"\n" -msgstr "sslmodeã®å€¤ãŒç„¡åйã§ã™: \"%s\"\n" +msgstr "sslmodeã®å€¤ãŒä¸æ­£ã§ã™: \"%s\"\n" -#: fe-connect.c:819 +#: fe-connect.c:1211 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" -msgstr "SSLサãƒãƒ¼ãƒˆãŒçµ„ã¿è¾¼ã¾ã‚Œã¦ã„ãªã„å ´åˆsslmodeã®å€¤\"%s\"ã¯ç„¡åйã§ã™\n" +msgstr "SSLサãƒãƒ¼ãƒˆãŒçµ„ã¿è¾¼ã¾ã‚Œã¦ã„ãªã„å ´åˆsslmodeã®å€¤\"%s\"ã¯ä¸æ­£ã§ã™\n" -#: fe-connect.c:1023 +#: fe-connect.c:1246 +#, c-format +msgid "invalid target_session_attrs value: \"%s\"\n" +msgstr "target_session_attrsã®å€¤ãŒä¸æ­£ã§ã™: \"%s\"\n" + +#: fe-connect.c:1464 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "TCPソケットをéžé…延モードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1053 +#: fe-connect.c:1494 #, c-format msgid "" "could not connect to server: %s\n" @@ -119,7 +243,7 @@ msgstr "" " ローカルã«ã‚µãƒ¼ãƒãŒç¨¼å‹•ã—ã¦ã„ã¾ã™ã‹?\n" " Unixドメインソケット\"%s\"ã§é€šä¿¡ã‚’å—ã‘付ã‘ã¦ã„ã¾ã™ã‹?\n" -#: fe-connect.c:1108 +#: fe-connect.c:1552 #, c-format msgid "" "could not connect to server: %s\n" @@ -130,7 +254,7 @@ msgstr "" "\tサーãƒã¯ãƒ›ã‚¹ãƒˆ \"%s\" (%s) ã§ç¨¼å‹•ã—ã¦ãŠã‚Šã€\n" "\tã¾ãŸã€ãƒãƒ¼ãƒˆ %s ã§ TCP/IP 接続をå—ã‘付ã‘ã¦ã„ã¾ã™ã‹?\n" -#: fe-connect.c:1117 +#: fe-connect.c:1561 #, c-format msgid "" "could not connect to server: %s\n" @@ -141,507 +265,507 @@ msgstr "" "\tサーãƒã¯ãƒ›ã‚¹ãƒˆ\"%s\"ã§ç¨¼å‹•ã—ã¦ã„ã¾ã™ã‹?\n" "\tã¾ãŸã€ãƒãƒ¼ãƒˆ%sã§TCP/IP接続をå—ã‘付ã‘ã¦ã„ã¾ã™ã‹?\n" -#: fe-connect.c:1168 +#: fe-connect.c:1612 fe-connect.c:1644 fe-connect.c:1677 fe-connect.c:2325 #, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPIDLE)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "setsockopt(%s)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: fe-connect.c:1181 +#: fe-connect.c:1726 #, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPALIVE)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" +msgstr "WSAIoctl(SIO_KEEPALIVE_VALS)ã«å¤±æ•—ã—ã¾ã—ãŸ:%ui\n" -#: fe-connect.c:1213 -#, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "setsockopt(TCP_KEEPINTVL)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" +#: fe-connect.c:2035 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "接続状態ãŒä¸æ­£ã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" -#: fe-connect.c:1245 +#: fe-connect.c:2101 #, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "setsockopt(TCP_KEEPCNT)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" +msgid "invalid port number: \"%s\"\n" +msgstr "䏿­£ãªãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"\n" -#: fe-connect.c:1293 +#: fe-connect.c:2117 #, c-format -msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" -msgstr "WSAIoctl(SIO_KEEPALIVE_VALS)ã«å¤±æ•—ã—ã¾ã—ãŸ:%ui\n" +msgid "could not translate host name \"%s\" to address: %s\n" +msgstr "ホストå\"%s\"をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1345 +#: fe-connect.c:2130 #, c-format -msgid "invalid port number: \"%s\"\n" -msgstr "無効ãªãƒãƒ¼ãƒˆç•ªå·ã§ã™: \"%s\"\n" +msgid "could not parse network address \"%s\": %s\n" +msgstr "ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯ã‚¢ãƒ‰ãƒ¬ã‚¹\"%s\"をパースã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1378 +#: fe-connect.c:2143 #, c-format -#| msgid "backup label too long (max %d bytes)" msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "Unixドメインソケットã®ãƒ‘ス\"%s\"ãŒé•·ã™ãŽã¾ã™(最大 %d ãƒã‚¤ãƒˆ)\n" -#: fe-connect.c:1397 -#, c-format -msgid "could not translate host name \"%s\" to address: %s\n" -msgstr "ホストå\"%s\"をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" - -#: fe-connect.c:1401 +#: fe-connect.c:2158 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "Unixドメインソケットã®ãƒ‘ス\"%s\"をアドレスã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1606 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "接続状態ãŒç„¡åйã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" - -#: fe-connect.c:1647 +#: fe-connect.c:2262 #, c-format msgid "could not create socket: %s\n" msgstr "ソケットを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1669 +#: fe-connect.c:2284 #, c-format -#| msgid "could not set socket to non-blocking mode: %s\n" msgid "could not set socket to nonblocking mode: %s\n" msgstr "ソケットをéžãƒ–ロッキングモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1680 +#: fe-connect.c:2294 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "ソケットをclose-on-execモードã«è¨­å®šã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1699 +#: fe-connect.c:2312 msgid "keepalives parameter must be an integer\n" msgstr "keepaliveã®ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã¯æ•´æ•°ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:1712 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(SO_KEEPALIVE)ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" - -#: fe-connect.c:1849 +#: fe-connect.c:2450 #, c-format msgid "could not get socket error status: %s\n" msgstr "ソケットã®ã‚¨ãƒ©ãƒ¼çŠ¶æ…‹ã‚’å…¥æ‰‹ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1883 +#: fe-connect.c:2478 #, c-format msgid "could not get client address from socket: %s\n" msgstr "ソケットã‹ã‚‰ã‚¯ãƒ©ã‚¤ã‚¢ãƒ³ãƒˆã‚¢ãƒ‰ãƒ¬ã‚¹ã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1924 +#: fe-connect.c:2520 msgid "requirepeer parameter is not supported on this platform\n" msgstr "ã“ã®ãƒ—ラットフォームã§ã¯ requirepeer パラメータã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-connect.c:1927 +#: fe-connect.c:2523 #, c-format msgid "could not get peer credentials: %s\n" msgstr "ピアã®è³‡æ ¼è¨¼æ˜Žã‚’入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:1937 -#, c-format -msgid "local user with ID %d does not exist\n" -msgstr "ID %d ã‚’æŒã¤ãƒ­ãƒ¼ã‚«ãƒ«ãƒ¦ãƒ¼ã‚¶ã¯å­˜åœ¨ã—ã¾ã›ã‚“\n" - -#: fe-connect.c:1945 +#: fe-connect.c:2546 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeerã¯\"%s\"を指定ã—ã¦ã„ã¾ã™ãŒã€å®Ÿéš›ã®ãƒ”ã‚¢åã¯\"%s\"ã§ã™\n" -#: fe-connect.c:1979 +#: fe-connect.c:2580 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "SSL調åœãƒ‘ケットをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:2018 +#: fe-connect.c:2619 #, c-format msgid "could not send startup packet: %s\n" msgstr "開始パケットをé€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-connect.c:2088 +#: fe-connect.c:2689 msgid "server does not support SSL, but SSL was required\n" msgstr "サーãƒã¯SSLをサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“ãŒã€SSLãŒè¦æ±‚ã•れã¾ã—ãŸ\n" -#: fe-connect.c:2114 +#: fe-connect.c:2715 #, c-format msgid "received invalid response to SSL negotiation: %c\n" -msgstr "SSL調åœã«å¯¾ã—ã¦ç„¡åйãªå¿œç­”ã‚’å—ä¿¡ã—ã¾ã—ãŸ: %c\n" +msgstr "SSL調åœã«å¯¾ã—ã¦ä¸æ­£ãªå¿œç­”ã‚’å—ä¿¡ã—ã¾ã—ãŸ: %c\n" -#: fe-connect.c:2189 fe-connect.c:2222 +#: fe-connect.c:2792 fe-connect.c:2825 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "サーãƒã‹ã‚‰ã®èªè¨¼è¦æ±‚を想定ã—ã¦ã„ã¾ã—ãŸãŒã€%cã‚’å—ä¿¡ã—ã¾ã—ãŸ\n" -#: fe-connect.c:2389 -#, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "GSSAPIãƒãƒƒãƒ•ã‚¡ã®å‰²ã‚Šå½“ã¦æ™‚ã®ãƒ¡ãƒ¢ãƒªä¸è¶³(%d)" - -#: fe-connect.c:2474 +#: fe-connect.c:3052 msgid "unexpected message from server during startup\n" msgstr "起動時ã«ã‚µãƒ¼ãƒã‹ã‚‰æƒ³å®šå¤–ã®ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãŒã‚りã¾ã—ãŸ\n" -#: fe-connect.c:2568 +#: fe-connect.c:3282 +#, c-format +msgid "could not make a writable connection to server \"%s:%s\"\n" +msgstr "サーãƒ\"%s:%s\"ã¸ã®æ›¸ãè¾¼ã¿å¯èƒ½ãªæŽ¥ç¶šã‚’確立ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" + +#: fe-connect.c:3328 +#, c-format +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "サーãƒ\"%s:%s\"ã§\"SHOW transaction_read_only\"ã®ãƒ†ã‚¹ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ\n" + +#: fe-connect.c:3343 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" -msgstr "接続状態%dãŒç„¡åйã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" +msgstr "接続状態%dãŒä¸æ­£ã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" -#: fe-connect.c:3001 fe-connect.c:3061 +#: fe-connect.c:3758 fe-connect.c:3818 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEVT_CONNRESETイベント中ã«PGEventProc \"%s\"ã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: fe-connect.c:3406 +#: fe-connect.c:4165 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" -msgstr "無効ãªLDAP URL\"%s\":スキーマã¯ldap://ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgstr "䏿­£ãªLDAP URL\"%s\":スキーマã¯ldap://ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:3421 +#: fe-connect.c:4180 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" -msgstr "無効ãªLDAP URL \"%s\": 区別åãŒã‚りã¾ã›ã‚“\n" +msgstr "䏿­£ãªLDAP URL \"%s\": 区別åãŒã‚りã¾ã›ã‚“\n" -#: fe-connect.c:3432 fe-connect.c:3485 +#: fe-connect.c:4191 fe-connect.c:4244 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" -msgstr "無効ãªLDAP URL \"%s\": 正確ã«1ã¤ã®å±žæ€§ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgstr "䏿­£ãªLDAP URL \"%s\": 正確ã«1ã¤ã®å±žæ€§ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:3442 fe-connect.c:3499 +#: fe-connect.c:4201 fe-connect.c:4258 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" -msgstr "無効ãªLDAP URL \"%s\": 検索スコープ(base/one/sub)ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +msgstr "䏿­£ãªLDAP URL \"%s\": 検索スコープ(base/one/sub)ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:3453 +#: fe-connect.c:4212 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" -msgstr "無効ãªLDAP URL \"%s\": フィルタãŒã‚りã¾ã›ã‚“\n" +msgstr "䏿­£ãªLDAP URL \"%s\": フィルタãŒã‚りã¾ã›ã‚“\n" -#: fe-connect.c:3474 +#: fe-connect.c:4233 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" -msgstr "無効ãªLDAP URL \"%s\": ãƒãƒ¼ãƒˆç•ªå·ãŒç„¡åйã§ã™\n" +msgstr "䏿­£ãªLDAP URL \"%s\": ãƒãƒ¼ãƒˆç•ªå·ãŒä¸æ­£ã§ã™\n" -#: fe-connect.c:3508 +#: fe-connect.c:4267 msgid "could not create LDAP structure\n" msgstr "LDAP構造体を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-connect.c:3550 +#: fe-connect.c:4343 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "LDAPサーãƒã§æ¤œç´¢ã«å¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: fe-connect.c:3561 +#: fe-connect.c:4354 msgid "more than one entry found on LDAP lookup\n" msgstr "LDAPæ¤œç´¢çµæžœãŒè¤‡æ•°ã‚りã¾ã—ãŸ\n" -#: fe-connect.c:3562 fe-connect.c:3574 +#: fe-connect.c:4355 fe-connect.c:4367 msgid "no entry found on LDAP lookup\n" msgstr "LDAPæ¤œç´¢çµæžœãŒç©ºã§ã—ãŸ\n" -#: fe-connect.c:3585 fe-connect.c:3598 +#: fe-connect.c:4378 fe-connect.c:4391 msgid "attribute has no values on LDAP lookup\n" msgstr "LDAP検索ã§å±žæ€§ã«å€¤ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-connect.c:3650 fe-connect.c:3669 fe-connect.c:4157 +#: fe-connect.c:4443 fe-connect.c:4462 fe-connect.c:4991 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "接続情報文字列ã«ãŠã„ã¦\"%s\"ã®å¾Œã«\"=\"ãŒã‚りã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-connect.c:3733 fe-connect.c:4337 fe-connect.c:5042 +#: fe-connect.c:4535 fe-connect.c:5176 fe-connect.c:5950 #, c-format msgid "invalid connection option \"%s\"\n" -msgstr "接続オプション\"%s\"ã¯ç„¡åйã§ã™\n" +msgstr "接続オプション\"%s\"ã¯ä¸æ­£ã§ã™\n" -#: fe-connect.c:3749 fe-connect.c:4206 +#: fe-connect.c:4551 fe-connect.c:5040 msgid "unterminated quoted string in connection info string\n" msgstr "接続情報文字列ã«ãŠã„ã¦é–‰ã˜ã¦ã„ãªã„引用符ãŒã‚りã¾ã—ãŸ\n" -#: fe-connect.c:3788 -msgid "could not get home directory to locate service definition file" -msgstr "サーãƒè¨­å®šãƒ•ァイルã®å ´æ‰€ã‚’特定ã—よã†ã¨ã—ã¾ã—ãŸãŒã€ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’å–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚" - -#: fe-connect.c:3821 +#: fe-connect.c:4634 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "サービス定義\"%s\"ãŒã¿ã¤ã‹ã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:3844 +#: fe-connect.c:4657 #, c-format msgid "service file \"%s\" not found\n" msgstr "サービスファイル\"%s\"ãŒã¿ã¤ã‹ã‚Šã¾ã›ã‚“\n" -#: fe-connect.c:3857 +#: fe-connect.c:4670 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "サービスファイル\"%2$s\"ã®è¡Œ%1$dãŒé•·ã™ãŽã¾ã™ã€‚\n" -#: fe-connect.c:3928 fe-connect.c:3955 +#: fe-connect.c:4741 fe-connect.c:4785 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "サービスファイル\"%s\"ã®è¡Œ%dã«æ§‹æ–‡ã‚¨ãƒ©ãƒ¼ãŒã‚りã¾ã™\n" -#: fe-connect.c:4570 +#: fe-connect.c:4752 +#, c-format +msgid "nested service specifications not supported in service file \"%s\", line %d\n" +msgstr "サービスファイル\"%s\"ã§ã¯ãƒã‚¹ãƒˆã—ãŸã‚µãƒ¼ãƒ“ス指定ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“ã€è¡Œ%d\n" + +#: fe-connect.c:5472 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" -msgstr "内部パーサ処ç†ã¸ä¼ã‚ã£ãŸç„¡åйãªURI: \"%s\"\n" +msgstr "内部パーサ処ç†ã¸ä¼ã‚ã£ãŸä¸æ­£ãªURI: \"%s\"\n" -#: fe-connect.c:4640 +#: fe-connect.c:5549 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "URI \"%s\"内ã®IPv6ホストアドレスã«ãŠã„ã¦å¯¾å¿œã™ã‚‹\"]\"を探ã—ã¦ã„ã‚‹é–“ã«æ–‡å­—列ãŒçµ‚ã‚りã¾ã—ãŸ\n" -#: fe-connect.c:4647 +#: fe-connect.c:5556 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "URI \"%s\"内ã®IPv6ホストアドレスãŒç©ºã§ã‚ã‚‹å¯èƒ½æ€§ãŒã‚りã¾ã™\n" -#: fe-connect.c:4662 +#: fe-connect.c:5571 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" msgstr "URI(\":\"ã¨\"/\"を除ã)内ã®ä½ç½®%2$dã«æƒ³å®šå¤–ã®\"%1$c\"文字ãŒã‚りã¾ã™: \"%3$s\"\n" -#: fe-connect.c:4776 +#: fe-connect.c:5700 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "URIå•ã„åˆã‚ã›ãƒ‘ラメータ内ã«ä½™åˆ†ãªã‚­ãƒ¼ã¨å€¤ã‚’分ã‘ã‚‹\"=\"ãŒã‚りã¾ã™: \"%s\"\n" -#: fe-connect.c:4796 +#: fe-connect.c:5720 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "URIå•ã„åˆã‚ã›ãƒ‘ラメータ内ã«ã‚­ãƒ¼ã¨å€¤ã‚’分ã‘ã‚‹\\\"=\\\"ãŒã‚りã¾ã¾ã›ã‚“: \"%s\"\n" -#: fe-connect.c:4867 +#: fe-connect.c:5771 #, c-format msgid "invalid URI query parameter: \"%s\"\n" -msgstr "無効ãªURIå•ã„åˆã‚ã›ãƒ‘ラメータ:\"%s\"\n" +msgstr "䏿­£ãªURIå•ã„åˆã‚ã›ãƒ‘ラメータ:\"%s\"\n" -#: fe-connect.c:4937 +#: fe-connect.c:5845 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" -msgstr "無効ãªãƒ‘ーセント符å·åŒ–トークン: \"%s\"\n" +msgstr "䏿­£ãªãƒ‘ーセント符å·åŒ–トークン: \"%s\"\n" -#: fe-connect.c:4947 +#: fe-connect.c:5855 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "パーセント符å·åŒ–ã•れãŸå€¤ã§ã¯%%00値ã¯è¨±ã•れã¾ã›ã‚“: \"%s\"\n" -#: fe-connect.c:5270 +#: fe-connect.c:6201 msgid "connection pointer is NULL\n" msgstr "接続ãƒã‚¤ãƒ³ã‚¿ã¯NULLã§ã™\n" -#: fe-connect.c:5547 +#: fe-connect.c:6499 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "WARNING: パスワードファイル\"%s\"ãŒãƒ†ã‚­ã‚¹ãƒˆãƒ•ァイルã§ã¯ã‚りã¾ã›ã‚“\n" -#: fe-connect.c:5556 +#: fe-connect.c:6508 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "警告: パスワードファイル \"%s\" ãŒã‚°ãƒ«ãƒ¼ãƒ—メンãƒã‚‚ã—ãã¯ä»–ã®ãƒ¦ãƒ¼ã‚¶ã‹ã‚‰èª­ã‚る状態ã«ãªã£ã¦ã„ã¾ã™ã€‚ã“ã®æ¨©é™ã¯u=rw (0600)以下ã«ã™ã¹ãã§ã™\n" -#: fe-connect.c:5656 +#: fe-connect.c:6602 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "ファイル\"%s\"ã‹ã‚‰ãƒ‘スワードを読ã¿è¾¼ã¿ã¾ã—ãŸ\n" -#: fe-exec.c:824 +#: fe-exec.c:437 fe-exec.c:2776 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "行番å·%dã¯0..%dã®ç¯„囲を超ãˆã¦ã„ã¾ã™" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "メモリä¸è¶³ã§ã™" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "注æ„" -#: fe-exec.c:1120 fe-exec.c:1178 fe-exec.c:1224 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresultã¯INT_MAX個以上ã®ã‚¿ãƒ—ルを扱ãˆã¾ã›ã‚“" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "size_t オーãƒãƒ¼ãƒ•ロー" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "コマンド文字列ãŒãƒŒãƒ«ãƒã‚¤ãƒ³ã‚¿ã§ã™\n" -#: fe-exec.c:1184 fe-exec.c:1230 fe-exec.c:1325 -#| msgid "interval(%d) precision must be between %d and %d" +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "パラメータ数ã¯0ã‹ã‚‰65535ã¾ã§ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-exec.c:1218 fe-exec.c:1319 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "æ–‡ã®åå‰ãŒãƒŒãƒ«ãƒã‚¤ãƒ³ã‚¿ã§ã™\n" -#: fe-exec.c:1238 fe-exec.c:1402 fe-exec.c:2096 fe-exec.c:2295 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2390 msgid "function requires at least protocol version 3.0\n" msgstr "関数ã¯å°‘ãªãã¨ã‚‚プロトコルãƒãƒ¼ã‚¸ãƒ§ãƒ³3.0ãŒå¿…è¦ã§ã™\n" -#: fe-exec.c:1356 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "サーãƒã¸ã®æŽ¥ç¶šãŒã‚りã¾ã›ã‚“\n" -#: fe-exec.c:1363 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "ä»–ã®ã‚³ãƒžãƒ³ãƒ‰ã‚’処ç†ã—ã¦ã„ã¾ã™\n" -#: fe-exec.c:1478 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "ãƒã‚¤ãƒŠãƒªãƒ‘ラメータã«ã¯é•·ã•を指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-exec.c:1756 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "想定外ã®asyncStatus: %d\n" -#: fe-exec.c:1776 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEVT_RESULTCREATEイベント中ã«PGEventProc \"%s\"ã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: fe-exec.c:1906 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "æ–°ãŸãªPQexec\"ã«ã‚ˆã‚ŠCOPYãŒçµ‚了ã—ã¾ã—ãŸ" -#: fe-exec.c:1914 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "ã¾ãšCOPY IN状態を終了ã•ã›ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-exec.c:1934 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "ã¾ãšCOPY OUT状態を終了ã•ã›ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" -#: fe-exec.c:1942 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "COPY BOTH 実行中㮠PQexec ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-exec.c:2185 fe-exec.c:2252 fe-exec.c:2342 fe-protocol2.c:1327 -#: fe-protocol3.c:1683 +#: fe-exec.c:2280 fe-exec.c:2347 fe-exec.c:2437 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "実行中ã®COPYã¯ã‚りã¾ã›ã‚“\n" -#: fe-exec.c:2534 +#: fe-exec.c:2627 msgid "connection in wrong state\n" msgstr "接続状態ãŒç•°å¸¸ã§ã™\n" -#: fe-exec.c:2565 +#: fe-exec.c:2658 msgid "invalid ExecStatusType code" -msgstr "ExecStatusTypeコードãŒç„¡åйã§ã™" +msgstr "ExecStatusTypeコードãŒä¸æ­£ã§ã™" + +#: fe-exec.c:2685 +msgid "PGresult is not an error result\n" +msgstr "PGresutãŒã‚¨ãƒ©ãƒ¼çµæžœã§ã¯ã‚りã¾ã›ã‚“\n" -#: fe-exec.c:2629 fe-exec.c:2652 +#: fe-exec.c:2760 fe-exec.c:2783 #, c-format msgid "column number %d is out of range 0..%d" msgstr "列番å·%dã¯0..%dã®ç¯„囲を超ãˆã¦ã„ã¾ã™" -#: fe-exec.c:2645 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "行番å·%dã¯0..%dã®ç¯„囲を超ãˆã¦ã„ã¾ã™" - -#: fe-exec.c:2667 +#: fe-exec.c:2798 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "パラメータ%dã¯0..%dã®ç¯„囲を超ãˆã¦ã„ã¾ã™" -#: fe-exec.c:2955 +#: fe-exec.c:3108 #, c-format msgid "could not interpret result from server: %s" msgstr "サーãƒã‹ã‚‰ã®çµæžœã‚’解釈ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: fe-exec.c:3194 fe-exec.c:3278 +#: fe-exec.c:3347 fe-exec.c:3431 msgid "incomplete multibyte character\n" msgstr "ä¸å®Œå…¨ãªãƒžãƒ«ãƒãƒã‚¤ãƒˆæ–‡å­—\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "lo_truncate関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:171 -#| msgid "Value exceeds integer range." +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "lo_truncateã¸ã®å¼•æ•°ãŒæ•´æ•°ç¯„囲を超ãˆã¦ã„ã¾ã™ã€‚\n" -#: fe-lobj.c:222 -#| msgid "cannot determine OID of function lo_truncate\n" +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "lo_truncate64関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:280 -#| msgid "Value exceeds integer range." +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "lo_readã¸ã®å¼•æ•°ãŒæ•´æ•°ç¯„囲を超ãˆã¦ã„ã¾ã™ã€‚\n" -#: fe-lobj.c:335 -#| msgid "Value exceeds integer range." +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "lo_writeã¸ã®å¼•æ•°ãŒæ•´æ•°ç¯„囲を超ãˆã¦ã„ã¾ã™ã€‚\n" -#: fe-lobj.c:426 -#| msgid "cannot determine OID of function lo_lseek\n" +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "lo_lseek64関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "lo_create関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:601 -#| msgid "cannot determine OID of function lo_tell\n" +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "lo_tell64関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "ファイル\"%s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "ファイル\"%s\"ã«æ›¸ãè¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "ãƒ©ãƒ¼ã‚¸ã‚ªãƒ–ã‚¸ã‚§ã‚¯ãƒˆæ©Ÿèƒ½ã‚’åˆæœŸåŒ–ã™ã‚‹å•ã„åˆã‚ã›ãŒãƒ‡ãƒ¼ã‚¿ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "lo_open関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "lo_close関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "lo_creat関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "lo_unlink関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "lo_lseek関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "lo_tell関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "loread関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "lowrite関数ã®OIDを決定ã§ãã¾ã›ã‚“\n" -#: fe-misc.c:295 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "サイズ%luã®æ•´æ•°ã¯pqGetIntã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: fe-misc.c:331 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "サイズ%luã®æ•´æ•°ã¯pqPutIntã§ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: fe-misc.c:610 fe-misc.c:806 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "接続ã¯ã‚ªãƒ¼ãƒ—ンã•れã¦ã„ã¾ã›ã‚“\n" -#: fe-misc.c:736 fe-secure.c:382 fe-secure.c:462 fe-secure.c:543 -#: fe-secure.c:652 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -651,345 +775,354 @@ msgstr "" " ãŠãらãè¦æ±‚ã®å‡¦ç†å‰ã¾ãŸã¯å‡¦ç†ä¸­ã«ã‚µãƒ¼ãƒãŒç•°å¸¸çµ‚了\n" " ã—ãŸã“ã¨ã‚’æ„味ã—ã¦ã„ã¾ã™ã€‚\n" -#: fe-misc.c:970 +#: fe-misc.c:1009 msgid "timeout expired\n" msgstr "タイムアウト期間ãŒéŽãŽã¾ã—ãŸ\n" -#: fe-misc.c:1015 -msgid "socket not open\n" -msgstr "ソケットãŒã‚ªãƒ¼ãƒ—ンã•れã¦ã„ã¾ã›ã‚“\n" +#: fe-misc.c:1054 +msgid "invalid socket\n" +msgstr "䏿­£ãªã‚½ã‚±ãƒƒãƒˆã§ã™\n" -#: fe-misc.c:1038 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "select()ãŒå¤±æ•—ã—ã¾ã—ãŸ: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" -msgstr "setenv状態%cã¯ç„¡åйã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" +msgstr "setenv状態%cã¯ä¸æ­£ã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" -msgstr "状態%cã¯ç„¡åйã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" +msgstr "状態%cã¯ä¸æ­£ã§ã™ã€‚メモリ障害ã®å¯èƒ½æ€§ãŒã‚りã¾ã™\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "待機中ã«ã‚µãƒ¼ãƒã‹ã‚‰ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡ž0x%02xãŒå±Šãã¾ã—ãŸ" -#: fe-protocol2.c:522 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "空ã®å•ã„åˆã‚ã›å¿œç­”(\"I\"メッセージ)ã®å¾Œã«æƒ³å®šå¤–ã®æ–‡å­—%cãŒã‚りã¾ã—ãŸ" -#: fe-protocol2.c:580 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "サーãƒãŒäº‹å‰ã®è¡Œè¨˜è¿°(\"T\"メッセージ)ãªã—ã«ãƒ‡ãƒ¼ã‚¿(\"D\"メッセージ)ã‚’é€ä¿¡ã—ã¾ã—ãŸ" -#: fe-protocol2.c:598 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" msgstr "サーãƒãŒäº‹å‰ã®è¡Œè¨˜è¿°(\"T\"メッセージ)ãªã—ã«ãƒã‚¤ãƒŠãƒªãƒ‡ãƒ¼ã‚¿(\"B\"メッセージ)ã‚’é€ä¿¡ã—ã¾ã—ãŸ" -#: fe-protocol2.c:618 fe-protocol3.c:385 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "サーãƒã‹ã‚‰æƒ³å®šå¤–ã®å¿œç­”ãŒã‚りã¾ã—ãŸã€‚å—ã‘付ã‘ãŸå…ˆé ­æ–‡å­—ã¯\"%c\"ã§ã™\n" -#: fe-protocol2.c:747 fe-protocol2.c:922 fe-protocol3.c:600 fe-protocol3.c:782 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "å•ã„åˆã‚ã›çµæžœç”¨ã®ãƒ¡ãƒ¢ãƒªãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: fe-protocol2.c:1370 fe-protocol3.c:1752 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1382 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "サーãƒã¨ã®å‹•機ãŒå¤±ã‚れã¾ã—ãŸã€‚接続をリセットã—ã¦ã„ã¾ã™" -#: fe-protocol2.c:1516 fe-protocol2.c:1548 fe-protocol3.c:1955 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "プロトコルエラー: id=0x%x\n" -#: fe-protocol3.c:341 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" msgstr "サーãƒãŒäº‹å‰ã®è¡Œè¨˜è¿°(\"T\"メッセージ)ãªã—ã«ãƒ‡ãƒ¼ã‚¿(\"D\"メッセージ)ã‚’é€ä¿¡ã—ã¾ã—ãŸ\"\n" -#: fe-protocol3.c:406 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "メッセージã®å†…容ãŒãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡ž\"%c\"ã®é•·ã•ã«åˆã„ã¾ã›ã‚“\n" -#: fe-protocol3.c:427 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "サーãƒã¨ã®åŒæœŸãŒå¤±ã‚れã¾ã—ãŸã€‚å—ä¿¡ã—ãŸãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ç¨®é¡žã¯\"%c\"ã€é•·ã•ã¯%d\n" -#: fe-protocol3.c:478 fe-protocol3.c:518 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "\"T\"メッセージ内ã®ãƒ‡ãƒ¼ã‚¿ãŒä¸å分ã§ã™" -#: fe-protocol3.c:551 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" -msgstr "\"T\"メッセージ内ã®ãƒ‡ãƒ¼ã‚¿ãŒç„¡é–¢ä¿‚ã§ã™" +msgstr "\"T\"メッセージ内ã«ç„¡é–¢ä¿‚ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" + +#: fe-protocol3.c:690 +msgid "extraneous data in \"t\" message" +msgstr "\"t\"メッセージ内ã«ç„¡é–¢ä¿‚ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" -#: fe-protocol3.c:690 fe-protocol3.c:722 fe-protocol3.c:740 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "\"D\"\"メッセージ内ã®ãƒ‡ãƒ¼ã‚¿ãŒä¸å分ã§ã™" -#: fe-protocol3.c:696 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "\"D\"メッセージ内ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰æ•°ãŒæƒ³å®šå¤–ã§ã™ã€‚" -#: fe-protocol3.c:749 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" -msgstr "â€D\"メッセージ内ã®ãƒ‡ãƒ¼ã‚¿ãŒç„¡é–¢ä¿‚ã§ã™" +msgstr "â€D\"メッセージ内ã«ç„¡é–¢ä¿‚ãªãƒ‡ãƒ¼ã‚¿ãŒã‚りã¾ã™" + +#: fe-protocol3.c:1012 +msgid "no error message available\n" +msgstr "エラーメッセージãŒã‚りã¾ã›ã‚“\n" #. translator: %s represents a digit string -#: fe-protocol3.c:878 fe-protocol3.c:897 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" msgstr "(文字ä½ç½®: %s)" -#: fe-protocol3.c:910 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "DETAIL: %s\n" -#: fe-protocol3.c:913 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "HINT: %s\n" -#: fe-protocol3.c:916 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "QUERY: %s\n" -#: fe-protocol3.c:919 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "CONTEXT: %s\n" -#: fe-protocol3.c:926 +#: fe-protocol3.c:1096 #, c-format -#| msgid "CONTEXT: %s\n" msgid "SCHEMA NAME: %s\n" msgstr "SCHEMA NAME: %s\n" -#: fe-protocol3.c:930 +#: fe-protocol3.c:1100 #, c-format -#| msgid "DETAIL: %s\n" msgid "TABLE NAME: %s\n" msgstr "TABLE NAME: %s\n" -#: fe-protocol3.c:934 +#: fe-protocol3.c:1104 #, c-format -#| msgid "CONTEXT: %s\n" msgid "COLUMN NAME: %s\n" msgstr "COLUMN NAME: %s\n" -#: fe-protocol3.c:938 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "DATATYPE NAME: %s\n" -#: fe-protocol3.c:942 +#: fe-protocol3.c:1112 #, c-format -#| msgid "CONTEXT: %s\n" msgid "CONSTRAINT NAME: %s\n" msgstr "CONSTRAINT NAME: %s\n" -#: fe-protocol3.c:954 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "LOCATION: " -#: fe-protocol3.c:956 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:958 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1182 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "行 %d: " -#: fe-protocol3.c:1577 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: テキストã®COPY OUTを行ã£ã¦ã„ã¾ã›ã‚“\n" -#: fe-secure.c:266 fe-secure.c:1121 fe-secure.c:1339 -msgid "unable to acquire mutex\n" -msgstr "ミューテックスをç²å¾—ã§ãã¾ã›ã‚“\n" +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "SSL証明書ã®åå‰ã®é€”中ã«nullãŒå«ã¾ã‚Œã¦ã„ã¾ã™\n" -#: fe-secure.c:278 +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "SSL 接続を検証ã™ã‚‹ãŸã‚ã«ãƒ›ã‚¹ãƒˆåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" + +#: fe-secure-common.c:196 #, c-format -msgid "could not establish SSL connection: %s\n" -msgstr "SSL接続を確立ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "\"%s\"ã®ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ãŒãƒ›ã‚¹ãƒˆå\"%s\"ã¨ãƒžãƒƒãƒã—ã¾ã›ã‚“\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "サーãƒè¨¼æ˜Žæ›¸ã‹ã‚‰ã‚µãƒ¼ãƒã®ãƒ›ã‚¹ãƒˆåã‚’å–り出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" -#: fe-secure.c:387 fe-secure.c:548 fe-secure.c:1468 +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALLエラー: %s\n" -#: fe-secure.c:394 fe-secure.c:555 fe-secure.c:1472 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALLエラー: EOFを検知\n" -#: fe-secure.c:405 fe-secure.c:566 fe-secure.c:1481 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSLエラー: %s\n" -#: fe-secure.c:420 fe-secure.c:581 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSLæŽ¥ç¶šãŒæ„図ã›ãšã«ã‚¯ãƒ­ãƒ¼ã‚ºã•れã¾ã—ãŸ\n" -#: fe-secure.c:426 fe-secure.c:587 fe-secure.c:1490 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "䏿˜Žã®SSLエラーコード: %d\n" -#: fe-secure.c:470 -#, c-format -msgid "could not receive data from server: %s\n" -msgstr "サーãƒã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "サーãƒè¨¼æ˜Žæ›¸ã®ç½²åアルゴリズムを決定ã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-secure.c:659 +#: fe-secure-openssl.c:419 #, c-format -msgid "could not send data to server: %s\n" -msgstr "サーãƒã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "could not find digest for NID %s\n" +msgstr "NID %sã®ãƒ€ã‚¤ã‚¸ã‚§ã‚¹ãƒˆãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-secure.c:779 fe-secure.c:796 -msgid "could not get server common name from server certificate\n" -msgstr "サーãƒè¨¼æ˜Žæ›¸ã‹ã‚‰ã‚µãƒ¼ãƒã®ã‚³ãƒ¢ãƒ³ãƒãƒ¼ãƒ ã‚’å–り出ã™ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "ピアã®è¨¼æ˜Žæ›¸ãƒãƒƒã‚·ãƒ¥ã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸ\n" -#: fe-secure.c:809 -msgid "SSL certificate's common name contains embedded null\n" -msgstr "SSL 証明書ã®ã‚³ãƒ¢ãƒ³ãƒãƒ¼ãƒ ã« null ãŒå«ã¾ã‚Œã¦ã„ã¾ã™\n" +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "SSL証明書ã«åå‰ã®é …ç›®ãŒã‚りã¾ã›ã‚“\n" -#: fe-secure.c:821 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "SSL 接続を検証ã™ã‚‹ãŸã‚ã«ãƒ›ã‚¹ãƒˆåを指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“\n" +#: fe-secure-openssl.c:815 +#, c-format +msgid "could not create SSL context: %s\n" +msgstr "SSLコンテキストを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:835 +#: fe-secure-openssl.c:852 #, c-format -msgid "server common name \"%s\" does not match host name \"%s\"\n" -msgstr "サーãƒã®æ­£å¼å(common name)\"%s\"ãŒãƒ›ã‚¹ãƒˆå\"%s\"ã¨ä¸€è‡´ã—ã¾ã›ã‚“\n" +msgid "could not read root certificate file \"%s\": %s\n" +msgstr "ルート証明書\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:970 +#: fe-secure-openssl.c:880 #, c-format -msgid "could not create SSL context: %s\n" -msgstr "SSLコンテキストを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" +msgid "SSL library does not support CRL certificates (file \"%s\")\n" +msgstr "SSLライブラリãŒCRL証明書(\"%s\")をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-secure.c:1093 +#: fe-secure-openssl.c:908 +msgid "" +"could not get home directory to locate root certificate file\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"ルート証明書ファイルを置ããŸã‚ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå­˜åœ¨ã—ã¾ã›ã‚“。\n" +"ファイルを用æ„ã™ã‚‹ã‹ã€ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ã®æ¤œè¨¼ã‚’無効ã«ã™ã‚‹ã‚ˆã†ã« sslmode を変更ã—ã¦ãã ã•ã„\n" + +#: fe-secure-openssl.c:912 +#, c-format +msgid "" +"root certificate file \"%s\" does not exist\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"ルート証明書ファイル\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“。\n" +"ファイルを用æ„ã™ã‚‹ã‹ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ã®æ¤œè¨¼ã‚’無効ã«ã™ã‚‹ã‚ˆã†ã«sslmodeを変更ã—ã¦ãã ã•ã„\n" + +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "証明書ファイル\"%s\"をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1130 fe-secure.c:1145 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "証明書ファイル\"%s\"を読ã¿è¾¼ã‚ã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1200 +#: fe-secure-openssl.c:987 +#, c-format +msgid "could not establish SSL connection: %s\n" +msgstr "SSL接続を確立ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "SSLエンジン\"%s\"を読ã¿è¾¼ã¿ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1212 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "SSLエンジン\"%s\"ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1228 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "SSL秘密キーファイル\"%s\"をエンジン\"%s\"ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1242 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "SSL秘密キー\"%s\"をエンジン\"%s\"ã‹ã‚‰èª­ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1279 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "証明書ã¯ã‚りã¾ã—ãŸãŒã€ç§˜å¯†ã‚­ãƒ¼ãƒ•ァイル\"%s\"ã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ\n" -#: fe-secure.c:1287 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "警告:秘密キーファイル \"%s\" ãŒã‚°ãƒ«ãƒ¼ãƒ—メンãƒã‚„第三者ã‹ã‚‰èª­ã‚る状態ã«ãªã£ã¦ã„ã¾ã™ã€‚ã“ã®æ¨©é™ã¯u=rw (0600)ã¾ãŸã¯ãれ以下ã¨ã™ã¹ãã§ã™\n" -#: fe-secure.c:1298 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "秘密キーファイル\"%s\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1312 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "証明書ã¨ç§˜å¯†ã‚­ãƒ¼ãƒ•ァイル\"%s\"ãŒä¸€è‡´ã—ã¾ã›ã‚“: %s\n" -#: fe-secure.c:1348 -#, c-format -msgid "could not read root certificate file \"%s\": %s\n" -msgstr "ルート証明書\"%s\"を読ã¿å–れã¾ã›ã‚“ã§ã—ãŸ: %s\n" - -#: fe-secure.c:1378 -#, c-format -msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "SSLライブラリãŒCRL証明書(\"%s\")をオープンã§ãã¾ã›ã‚“ã§ã—ãŸ\n" - -#: fe-secure.c:1411 -msgid "" -"could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" -msgstr "" -"ルート証明書ファイルを置ããŸã‚ã®ãƒ›ãƒ¼ãƒ ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªãŒå­˜åœ¨ã—ã¾ã›ã‚“。\n" -"ファイルを用æ„ã™ã‚‹ã‹ã€ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ã®æ¤œè¨¼ã‚’無効ã«ã™ã‚‹ã‚ˆã†ã« sslmode を変更ã—ã¦ãã ã•ã„\n" - -#: fe-secure.c:1415 -#, c-format -msgid "" -"root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" -msgstr "" -"ルート証明書ファイル\"%s\"ãŒå­˜åœ¨ã—ã¾ã›ã‚“。\n" -"ファイルを用æ„ã™ã‚‹ã‹ã‚µãƒ¼ãƒè¨¼æ˜Žæ›¸ã®æ¤œè¨¼ã‚’無効ã«ã™ã‚‹ã‚ˆã†ã«sslmodeを変更ã—ã¦ãã ã•ã„\n" - -#: fe-secure.c:1509 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "証明書を入手ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" -#: fe-secure.c:1586 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "SSLエラーã¯ã‚りã¾ã›ã‚“ã§ã—ãŸ" -#: fe-secure.c:1595 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSLエラーコード: %lu" -#: win32.c:322 +#: fe-secure.c:269 +#, c-format +msgid "could not receive data from server: %s\n" +msgstr "サーãƒã‹ã‚‰ãƒ‡ãƒ¼ã‚¿ã‚’å—ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: fe-secure.c:378 +#, c-format +msgid "could not send data to server: %s\n" +msgstr "サーãƒã«ãƒ‡ãƒ¼ã‚¿ã‚’é€ä¿¡ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s\n" + +#: win32.c:317 #, c-format msgid "unrecognized socket error: 0x%08X/%d" msgstr "䏿˜Žãªã‚½ã‚±ãƒƒãƒˆã‚¨ãƒ©ãƒ¼ 0x%08X/%d" - -#~ msgid "verified SSL connections are only supported when connecting to a host name\n" -#~ msgstr "検証ã•れãŸSSL接続ã¯ãƒ›ã‚¹ãƒˆåã¸ã®æŽ¥ç¶šæ™‚ã®ã¿ã‚µãƒãƒ¼ãƒˆã•れã¾ã™\n" diff --git a/src/interfaces/libpq/po/ko.po b/src/interfaces/libpq/po/ko.po index 43c53cca769..0b94ec45c6a 100644 --- a/src/interfaces/libpq/po/ko.po +++ b/src/interfaces/libpq/po/ko.po @@ -3,10 +3,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6 libpq\n" +"Project-Id-Version: libpq (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 16:37+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-10 09:24+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -15,103 +15,223 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: fe-auth.c:148 +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (empty message)\n" +msgstr "SCRAM 메시지가 형ì‹ì— ì•ˆë§žìŒ (메시지 비었ìŒ)\n" + +#: fe-auth-scram.c:195 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "SCRAM 메시지가 형ì‹ì— ì•ˆë§žìŒ (ê¸¸ì´ ë¶ˆì¼ì¹˜)\n" + +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "ìž˜ëª»ëœ ì„œë²„ 서명\n" + +#: fe-auth-scram.c:253 +msgid "invalid SCRAM exchange state\n" +msgstr "SCRAM êµí™” ìƒíƒœê°€ 바르지 않ìŒ\n" + +#: fe-auth-scram.c:276 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "SCRAM 메시지가 형ì‹ì— ì•ˆë§žìŒ (\"%c\" ì†ì„±ì´ 예ìƒë¨)\n" + +#: fe-auth-scram.c:285 +#, c-format +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "SCRAM 메시지가 형ì‹ì— ì•ˆë§žìŒ (\"%c\" ì†ì„± 예ìƒê°’ì€ \"=\")\n" + +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" +msgstr "암호화 토í°(nonce)ì„ ë§Œë“¤ 수 ì—†ìŒ\n" + +#: fe-auth-scram.c:334 fe-auth-scram.c:401 fe-auth-scram.c:523 +#: fe-auth-scram.c:543 fe-auth-scram.c:569 fe-auth-scram.c:583 +#: fe-auth-scram.c:625 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:643 fe-auth.c:802 fe-auth.c:1114 fe-auth.c:1262 fe-connect.c:835 +#: fe-connect.c:1264 fe-connect.c:1440 fe-connect.c:1922 fe-connect.c:1945 +#: fe-connect.c:2606 fe-connect.c:4152 fe-connect.c:4404 fe-connect.c:4523 +#: fe-connect.c:4773 fe-connect.c:4853 fe-connect.c:4952 fe-connect.c:5208 +#: fe-connect.c:5237 fe-connect.c:5309 fe-connect.c:5333 fe-connect.c:5351 +#: fe-connect.c:5452 fe-connect.c:5461 fe-connect.c:5817 fe-connect.c:5967 +#: fe-exec.c:2702 fe-exec.c:3449 fe-exec.c:3614 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1685 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "메모리 부족\n" + +#: fe-auth-scram.c:561 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "ìž˜ëª»ëœ SCRAM ì‘답 (í† í° ë¶ˆì¼ì¹˜)\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "형ì‹ì— ë§žì§€ ì•Šì€ SCRAM 메시지 (나열 숫ìžê°€ ì´ìƒí•¨)\n" + +#: fe-auth-scram.c:606 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "형ì‹ì— ë§žì§€ ì•Šì€ SCRAM 메시지 (서버 첫 메시지 ëì— ì“¸ëª¨ 없는 ê°’ì´ ìžˆìŒ)\n" + +#: fe-auth-scram.c:636 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "SCRAM êµí™˜ìž‘ì—…ì—서 서버로부터 ë°ì´í„°ë¥¼ 받지 못했ìŒ: %s\n" + +#: fe-auth-scram.c:652 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "형ì‹ì— ë§žì§€ ì•Šì€ SCRAM 메시지 (서버 ë 메시지 ë’¤ì— ì“¸ëª¨ 없는 ê°’ì´ ìžˆìŒ)\n" + +#: fe-auth-scram.c:660 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "형ì‹ì— ë§žì§€ ì•Šì€ SCRAM 메시지 (서버 사ì¸ì´ ì´ìƒí•¨)\n" + +#: fe-auth.c:122 +#, c-format +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "GSSAPI 버í¼(%d)ì— í• ë‹¹í•  메모리 부족\n" + +#: fe-auth.c:177 msgid "GSSAPI continuation error" msgstr "GSSAPI ì—°ì† ì˜¤ë¥˜" -#: fe-auth.c:177 fe-auth.c:412 +#: fe-auth.c:207 fe-auth.c:461 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "호스트 ì´ë¦„ì„ ì§€ì •í•´ì•¼ 함\n" -#: fe-auth.c:184 +#: fe-auth.c:214 msgid "duplicate GSS authentication request\n" msgstr "ì¤‘ë³µëœ GSS ì¸ì¦ 요청\n" -#: fe-auth.c:197 fe-auth.c:309 fe-auth.c:383 fe-auth.c:418 fe-auth.c:514 -#: fe-auth.c:780 fe-connect.c:707 fe-connect.c:904 fe-connect.c:1080 -#: fe-connect.c:2091 fe-connect.c:3484 fe-connect.c:3736 fe-connect.c:3855 -#: fe-connect.c:4095 fe-connect.c:4175 fe-connect.c:4274 fe-connect.c:4530 -#: fe-connect.c:4559 fe-connect.c:4631 fe-connect.c:4649 fe-connect.c:4745 -#: fe-connect.c:5079 fe-connect.c:5229 fe-exec.c:2652 fe-exec.c:3399 -#: fe-exec.c:3564 fe-lobj.c:896 fe-protocol2.c:1206 fe-protocol3.c:992 -#: fe-protocol3.c:1678 fe-secure-openssl.c:552 fe-secure-openssl.c:1094 -msgid "out of memory\n" -msgstr "메모리 부족\n" - -#: fe-auth.c:210 +#: fe-auth.c:240 msgid "GSSAPI name import error" msgstr "GSSAPI ì´ë¦„ 가져오기 오류" -#: fe-auth.c:298 +#: fe-auth.c:303 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "SSPI 버í¼(%d)ì— í• ë‹¹í•  메모리 부족\n" + +#: fe-auth.c:351 msgid "SSPI continuation error" msgstr "SSPI ì—°ì† ì˜¤ë¥˜" -#: fe-auth.c:398 +#: fe-auth.c:422 +msgid "duplicate SSPI authentication request\n" +msgstr "ì¤‘ë³µëœ SSPI ì¸ì¦ 요청\n" + +#: fe-auth.c:447 msgid "could not acquire SSPI credentials" msgstr "SSPI ìžê²© ì¦ëª…ì„ ê°€ì ¸ì˜¬ 수 ì—†ìŒ" -#: fe-auth.c:489 +#: fe-auth.c:501 +msgid "duplicate SASL authentication request\n" +msgstr "ì¤‘ë³µëœ SASL ì¸ì¦ 요청\n" + +#: fe-auth.c:549 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "서버는 non-SSL ì ‘ì†ìœ¼ë¡œ SCRAM-SHA-256-PLUS ì¸ì¦ì„ 제공함\n" + +#: fe-auth.c:561 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "SASL ì¸ì¦ ë©”ì»¤ë‹ˆì¦˜ì„ ì§€ì›í•˜ëŠ” 서버가 없습니다.\n" + +#: fe-auth.c:667 +#, c-format +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "SASL 버í¼(%d)ì— í• ë‹¹í•  메모리 부족\n" + +#: fe-auth.c:692 +msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" +msgstr "서버ì—서 AuthenticationSASLFinal ì‘ë‹µì„ ë°›ì•˜ì§€ë§Œ, SASL ì¸ì¦ì´ ë나지 않았ìŒ\n" + +#: fe-auth.c:769 msgid "SCM_CRED authentication method not supported\n" msgstr "SCM_CRED ì¸ì¦ ë°©ë²•ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:565 +#: fe-auth.c:860 msgid "Kerberos 4 authentication not supported\n" msgstr "Kerberos 4 ì¸ì¦ ë°©ë²•ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:570 +#: fe-auth.c:865 msgid "Kerberos 5 authentication not supported\n" msgstr "Kerberos 5 ì¸ì¦ ë°©ë²•ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:641 +#: fe-auth.c:936 msgid "GSSAPI authentication not supported\n" msgstr "GSSAPI ì¸ì¦ì€ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:673 +#: fe-auth.c:968 msgid "SSPI authentication not supported\n" msgstr "SSPI ì¸ì¦ì€ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:681 +#: fe-auth.c:976 msgid "Crypt authentication not supported\n" msgstr "암호화 ì¸ì¦ì€ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:708 +#: fe-auth.c:1042 #, c-format msgid "authentication method %u not supported\n" msgstr "%u ì¸ì¦ ë°©ë²•ì´ ì§€ì›ë˜ì§€ 않ìŒ\n" -#: fe-auth.c:755 +#: fe-auth.c:1089 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "ì‚¬ìš©ìž ì´ë¦„ 찾기 실패: 오류 코드 %lu\n" -#: fe-auth.c:765 fe-connect.c:2018 +#: fe-auth.c:1099 fe-connect.c:2533 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "UID %d 해당하는 사용ìžë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: fe-auth.c:770 fe-connect.c:2023 +#: fe-auth.c:1104 fe-connect.c:2538 #, c-format msgid "local user with ID %d does not exist\n" msgstr "ID %d 로컬 ì‚¬ìš©ìž ì—†ìŒ\n" -#: fe-connect.c:846 +#: fe-auth.c:1206 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "SHOW ëª…ë ¹ì˜ ê²°ê³¼ ìžë£Œê°€ 비정ìƒìž„\n" + +#: fe-auth.c:1215 +msgid "password_encryption value too long\n" +msgstr "password_encryption 너무 긺\n" + +#: fe-auth.c:1255 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "알 수 없는 비밀번호 암호화 알고리즘: \"%s\"\n" + +#: fe-connect.c:1018 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "호스트 ì´ë¦„ì€ %dê°œì¸ë°, 호스트 주소는 %d개임\n" + +#: fe-connect.c:1094 +#, c-format +msgid "could not match %d port numbers to %d hosts\n" +msgstr "í¬íЏ 번호는 %dê°œì¸ë°, 호스트는 %d개입니다.\n" + +#: fe-connect.c:1190 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "ìž˜ëª»ëœ sslmode ê°’: \"%s\"\n" -#: fe-connect.c:867 +#: fe-connect.c:1211 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" -msgstr "" -"SSL ì—°ê²° ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않고 ì»´íŒŒì¼ ëœ ê²½ìš°ëŠ” sslmode 값으로 \"%s\" ê°’ì€ íƒ€" -"당치 않습니다\n" +msgstr "SSL ì—°ê²° ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않고 ì»´íŒŒì¼ ëœ ê²½ìš°ëŠ” sslmode 값으로 \"%s\" ê°’ì€ íƒ€ë‹¹ì¹˜ 않습니다\n" -#: fe-connect.c:1104 +#: fe-connect.c:1246 +#, c-format +msgid "invalid target_session_attrs value: \"%s\"\n" +msgstr "ìž˜ëª»ëœ target_session_attrs ê°’: \"%s\"\n" + +#: fe-connect.c:1464 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "ì†Œì¼“ì„ TCPì— no delay 모드로 지정할 수 ì—†ìŒ: %s\n" -#: fe-connect.c:1134 +#: fe-connect.c:1494 #, c-format msgid "" "could not connect to server: %s\n" @@ -122,7 +242,7 @@ msgstr "" "\të¡œì»¬í˜¸ìŠ¤íŠ¸ì— ì„œë²„ê°€ ê°€ë™ ì¤‘ì¸ì§€,\n" "\t\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ ì ‘ê·¼ì´ ê°€ëŠ¥í•œì§€ 살펴보십시오.\n" -#: fe-connect.c:1189 +#: fe-connect.c:1552 #, c-format msgid "" "could not connect to server: %s\n" @@ -133,7 +253,7 @@ msgstr "" "\t\"%s\" (%s) í˜¸ìŠ¤íŠ¸ì— ì„œë²„ê°€ ê°€ë™ ì¤‘ì¸ì§€,\n" "\t%s í¬íŠ¸ë¡œ TCP/IP ì—°ê²°ì´ ê°€ëŠ¥í•œì§€ 살펴보십시오.\n" -#: fe-connect.c:1198 +#: fe-connect.c:1561 #, c-format msgid "" "could not connect to server: %s\n" @@ -144,514 +264,507 @@ msgstr "" "\t\"%s\" í˜¸ìŠ¤íŠ¸ì— ì„œë²„ê°€ ê°€ë™ ì¤‘ì¸ì§€,\n" "\t%s í¬íŠ¸ë¡œ TCP/IP ì—°ê²°ì´ ê°€ëŠ¥í•œì§€ 살펴보십시오.\n" -#: fe-connect.c:1249 +#: fe-connect.c:1612 fe-connect.c:1644 fe-connect.c:1677 fe-connect.c:2325 #, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPIDLE) 실패: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "setsockopt(%s) 실패: %s\n" -#: fe-connect.c:1262 +#: fe-connect.c:1726 #, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPALIVE) 실패: %s\n" +msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" +msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) 실패: %ui\n" -#: fe-connect.c:1294 -#, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "setsockopt(TCP_KEEPINTVL) 실패: %s\n" +#: fe-connect.c:2035 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "ìž˜ëª»ëœ ì—°ê²° ìƒíƒœ, 메모리 ì†ìƒì¼ ê°€ëŠ¥ì„±ì´ í¼\n" -#: fe-connect.c:1326 +#: fe-connect.c:2101 #, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "setsockopt(TCP_KEEPCNT) 실패: %s\n" +msgid "invalid port number: \"%s\"\n" +msgstr "ìž˜ëª»ëœ í¬íЏ 번호: \"%s\"\n" -#: fe-connect.c:1374 +#: fe-connect.c:2117 #, c-format -msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" -msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) 실패: %ui\n" +msgid "could not translate host name \"%s\" to address: %s\n" +msgstr "\"%s\" 호스트 ì´ë¦„ì„ ì „ì†¡í•  수 없습니다: ëŒ€ìƒ ì£¼ì†Œ: %s\n" -#: fe-connect.c:1426 +#: fe-connect.c:2130 #, c-format -msgid "invalid port number: \"%s\"\n" -msgstr "ìž˜ëª»ëœ í¬íЏ 번호: \"%s\"\n" +msgid "could not parse network address \"%s\": %s\n" +msgstr "\"%s\" ë„¤íŠ¸ì›Œí¬ ì£¼ì†Œë¥¼ í•´ì„í•  수 ì—†ìŒ: %s\n" -#: fe-connect.c:1459 +#: fe-connect.c:2143 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ 경로가 너무 ê¹ë‹ˆë‹¤ (최대 %d ë°”ì´íЏ)\n" -#: fe-connect.c:1478 -#, c-format -msgid "could not translate host name \"%s\" to address: %s\n" -msgstr "\"%s\" 호스트 ì´ë¦„ì„ ì „ì†¡í•  수 없습니다: ëŒ€ìƒ ì£¼ì†Œ: %s\n" - -#: fe-connect.c:1482 +#: fe-connect.c:2158 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "\"%s\" 유닉스 ë„ë©”ì¸ ì†Œì¼“ 경로를 전송할 수 없습니다: ëŒ€ìƒ ì£¼ì†Œ: %s\n" -#: fe-connect.c:1687 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "ìž˜ëª»ëœ ì—°ê²° ìƒíƒœ, 메모리 ì†ìƒì¼ ê°€ëŠ¥ì„±ì´ í¼\n" - -#: fe-connect.c:1727 +#: fe-connect.c:2262 #, c-format msgid "could not create socket: %s\n" msgstr "ì†Œì¼“ì„ ë§Œë“¤ 수 ì—†ìŒ: %s\n" -#: fe-connect.c:1749 +#: fe-connect.c:2284 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "ì†Œì¼“ì„ nonblocking 모드로 지정할 수 ì—†ìŒ: %s\n" -#: fe-connect.c:1760 +#: fe-connect.c:2294 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "ì†Œì¼“ì„ close-on-exec 모드로 지정할 수 ì—†ìŒ: %s\n" -#: fe-connect.c:1779 +#: fe-connect.c:2312 msgid "keepalives parameter must be an integer\n" msgstr "keepalives ë§¤ê°œë³€ìˆ˜ê°’ì€ ì •ìˆ˜ì—¬ì•¼ 합니다.\n" -#: fe-connect.c:1792 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(SO_KEEPALIVE) 실패: %s\n" - -#: fe-connect.c:1929 +#: fe-connect.c:2450 #, c-format msgid "could not get socket error status: %s\n" msgstr "소켓 오류 ìƒíƒœë¥¼ 구할 수 ì—†ìŒ: %s\n" -#: fe-connect.c:1963 +#: fe-connect.c:2478 #, c-format msgid "could not get client address from socket: %s\n" msgstr "소켓ì—서 í´ë¼ì´ì–¸íЏ 주소를 구할 수 ì—†ìŒ: %s\n" -#: fe-connect.c:2005 +#: fe-connect.c:2520 msgid "requirepeer parameter is not supported on this platform\n" msgstr "requirepeer 매개변수는 ì´ ìš´ì˜ì²´ì œì—서 ì§€ì›í•˜ì§€ 않ìŒ\n" -#: fe-connect.c:2008 +#: fe-connect.c:2523 #, c-format msgid "could not get peer credentials: %s\n" msgstr "신뢰성 피어를 ì–»ì„ ìˆ˜ 없습니다: %s\n" -#: fe-connect.c:2031 +#: fe-connect.c:2546 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "\"%s\" ì´ë¦„으로 requirepeer를 지정했지만, 실재 ì‚¬ìš©ìž ì´ë¦„ì€ \"%s\" 입니다\n" -#: fe-connect.c:2065 +#: fe-connect.c:2580 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "SSL êµì„­ íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s\n" -#: fe-connect.c:2104 +#: fe-connect.c:2619 #, c-format msgid "could not send startup packet: %s\n" msgstr "시작 íŒ¨í‚·ì„ ë³´ë‚¼ 수 ì—†ìŒ: %s\n" -#: fe-connect.c:2174 +#: fe-connect.c:2689 msgid "server does not support SSL, but SSL was required\n" msgstr "서버가 SSL ê¸°ëŠ¥ì„ ì§€ì›í•˜ì§€ 않는ë°, SSL ê¸°ëŠ¥ì„ ìš”êµ¬í–ˆìŒ\n" -#: fe-connect.c:2200 +#: fe-connect.c:2715 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "SSL êµì„­ì— 대한 ìž˜ëª»ëœ ì‘ë‹µì„ ê°ì§€í–ˆìŒ: %c\n" -#: fe-connect.c:2275 fe-connect.c:2308 +#: fe-connect.c:2792 fe-connect.c:2825 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "서버가 ì¸ì¦ì„ 요구했지만, %c 받았ìŒ\n" -#: fe-connect.c:2475 -#, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "GSSAPI 버í¼(%d)ì— í• ë‹¹í•  메모리 부족" - -#: fe-connect.c:2560 +#: fe-connect.c:3052 msgid "unexpected message from server during startup\n" msgstr "시작하는 ë™ì•ˆ 서버로부터 기대ë˜ì§€ 않는 메시지\n" -#: fe-connect.c:2654 +#: fe-connect.c:3282 +#, c-format +msgid "could not make a writable connection to server \"%s:%s\"\n" +msgstr "\"%s:%s\" ì„œë²„ì— ì“°ê¸° 가능한 ì—°ê²°ì„ ë§ºì„ ìˆ˜ ì—†ìŒ\n" + +#: fe-connect.c:3328 +#, c-format +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "\"%s:%s\" 서버ì—서 \"SHOW transaction_read_only\" 검사가 실패함\n" + +#: fe-connect.c:3343 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "ìž˜ëª»ëœ ì—°ê²° ìƒíƒœ %d, 메모리 ì†ìƒì¼ ê°€ëŠ¥ì„±ì´ í¼\n" -#: fe-connect.c:3090 fe-connect.c:3150 +#: fe-connect.c:3758 fe-connect.c:3818 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEVT_CONNRESET ì´ë²¤íЏ ë™ì•ˆ PGEventProc \"%s\"ì´(ê°€) 실패함\n" -#: fe-connect.c:3497 +#: fe-connect.c:4165 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": 스키마는 ldap:// 여야함\n" -#: fe-connect.c:3512 +#: fe-connect.c:4180 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": ì‹ë³„ìž ì´ë¦„ì´ ë¹ ì¡ŒìŒ\n" -#: fe-connect.c:3523 fe-connect.c:3576 +#: fe-connect.c:4191 fe-connect.c:4244 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": 단 í•˜ë‚˜ì˜ ì†ì„±ë§Œ 가져야함\n" -#: fe-connect.c:3533 fe-connect.c:3590 +#: fe-connect.c:4201 fe-connect.c:4258 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": 검색범위(base/one/sub)를 지정해야함\n" -#: fe-connect.c:3544 +#: fe-connect.c:4212 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": í•„í„° ì—†ìŒ\n" -#: fe-connect.c:3565 +#: fe-connect.c:4233 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "ìž˜ëª»ëœ LDAP URL \"%s\": í¬íŠ¸ë²ˆí˜¸ê°€ 잘못ë¨\n" -#: fe-connect.c:3599 +#: fe-connect.c:4267 msgid "could not create LDAP structure\n" msgstr "LDAP 구조를 만들 수 ì—†ìŒ\n" -#: fe-connect.c:3675 +#: fe-connect.c:4343 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "LDAP 서버를 ì°¾ì„ ìˆ˜ ì—†ìŒ: %s\n" -#: fe-connect.c:3686 +#: fe-connect.c:4354 msgid "more than one entry found on LDAP lookup\n" msgstr "LDAP 검색ì—서 하나 ì´ìƒì˜ 엔트리가 발견ë˜ì—ˆìŒ\n" -#: fe-connect.c:3687 fe-connect.c:3699 +#: fe-connect.c:4355 fe-connect.c:4367 msgid "no entry found on LDAP lookup\n" msgstr "LDAP 검색ì—서 해당 항목 ì—†ìŒ\n" -#: fe-connect.c:3710 fe-connect.c:3723 +#: fe-connect.c:4378 fe-connect.c:4391 msgid "attribute has no values on LDAP lookup\n" msgstr "LDAP 검색ì—서 ì†ì„±ì˜ ê°’ì´ ì—†ìŒ\n" -#: fe-connect.c:3775 fe-connect.c:3794 fe-connect.c:4313 +#: fe-connect.c:4443 fe-connect.c:4462 fe-connect.c:4991 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "연결문ìžì—´ì—서 \"%s\" 다ìŒì— \"=\" ë¬¸ìž ë¹ ì¡ŒìŒ\n" -#: fe-connect.c:3867 fe-connect.c:4498 fe-connect.c:5212 +#: fe-connect.c:4535 fe-connect.c:5176 fe-connect.c:5950 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "ìž˜ëª»ëœ ì—°ê²° 옵션 \"%s\"\n" -#: fe-connect.c:3883 fe-connect.c:4362 +#: fe-connect.c:4551 fe-connect.c:5040 msgid "unterminated quoted string in connection info string\n" msgstr "연결문ìžì—´ì—서 완성ë˜ì§€ 못한 따옴표문ìžì—´ì´ 있ìŒ\n" -#: fe-connect.c:3923 -msgid "could not get home directory to locate service definition file" -msgstr "서비스 ì •ì˜ íŒŒì¼ì´ 있는 홈 디렉토리를 ì°¾ì„ ìˆ˜ ì—†ìŒ" - -#: fe-connect.c:3956 +#: fe-connect.c:4634 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "\"%s\" 서비스 ì •ì˜ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: fe-connect.c:3979 +#: fe-connect.c:4657 #, c-format msgid "service file \"%s\" not found\n" msgstr "\"%s\" 서비스 파ì¼ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: fe-connect.c:3992 +#: fe-connect.c:4670 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "%d번째 ì¤„ì´ \"%s\" 서비스 파ì¼ì—서 너무 ê¹ë‹ˆë‹¤\n" -#: fe-connect.c:4063 fe-connect.c:4107 +#: fe-connect.c:4741 fe-connect.c:4785 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "\"%s\" 서비스 파ì¼ì˜ %d번째 ì¤„ì— êµ¬ë¬¸ 오류 있ìŒ\n" -#: fe-connect.c:4074 +#: fe-connect.c:4752 #, c-format -msgid "" -"nested service specifications not supported in service file \"%s\", line %d\n" +msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "\"%s\" 서비스 파ì¼ì˜ %d번째 ì¤„ì— ì„¤ì •ì„ ì§€ì›í•˜ì§€ 않ìŒ\n" -#: fe-connect.c:4756 +#: fe-connect.c:5472 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "URI 구문 ë¶„ì„ì„ í•  수 ì—†ìŒ: \"%s\"\n" -#: fe-connect.c:4826 +#: fe-connect.c:5549 #, c-format -msgid "" -"end of string reached when looking for matching \"]\" in IPv6 host address " -"in URI: \"%s\"\n" -msgstr "" -"URIì˜ IPv6 호스트 주소ì—서 \"]\" 매칭 ê²€ìƒ‰ì„ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤, 해당 URI: \"%s\"\n" +msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" +msgstr "URIì˜ IPv6 호스트 주소ì—서 \"]\" 매칭 ê²€ìƒ‰ì„ ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤, 해당 URI: \"%s\"\n" -#: fe-connect.c:4833 +#: fe-connect.c:5556 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "IPv6 호스트 주소가 없습니다, 해당 URI: \"%s\"\n" -#: fe-connect.c:4848 +#: fe-connect.c:5571 #, c-format -msgid "" -"unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): " -"\"%s\"\n" -msgstr "" -"ìž˜ëª»ëœ \"%c\" 문ìžê°€ URI 문ìžì—´ ê°€ìš´ë° %d 번째 있습니다(\":\" ë˜ëŠ” \"/\" 문ìžê°€ 있어야 함): " -"\"%s\"\n" +msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" +msgstr "ìž˜ëª»ëœ \"%c\" 문ìžê°€ URI 문ìžì—´ ê°€ìš´ë° %d 번째 있습니다(\":\" ë˜ëŠ” \"/\" 문ìžê°€ 있어야 함): \"%s\"\n" -#: fe-connect.c:4962 +#: fe-connect.c:5700 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "키/밸류 êµ¬ë¶„ìž \"=\" 문ìžê°€ 필요함, 해당 URI 쿼리 매개변수: \"%s\"\n" -#: fe-connect.c:4982 +#: fe-connect.c:5720 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "키/밸류 êµ¬ë¶„ìž \"=\" 문ìžê°€ 필요함, 해당 URI 쿼리 매개변수: \"%s\"\n" -#: fe-connect.c:5033 +#: fe-connect.c:5771 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "ìž˜ëª»ëœ URL 쿼리 매개변수값: \"%s\"\n" -#: fe-connect.c:5107 +#: fe-connect.c:5845 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "ìž˜ëª»ëœ í¼ì„¼íЏ ì¸ì½”드 토í°: \"%s\"\n" -#: fe-connect.c:5117 +#: fe-connect.c:5855 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "í¼ì„¼íЏ ì¸ì½”드 ê°’ì— %%00 숨김 ê°’ì´ ìžˆìŒ: \"%s\"\n" -#: fe-connect.c:5451 +#: fe-connect.c:6201 msgid "connection pointer is NULL\n" msgstr "ì—°ê²° í¬ì¸í„°ê°€ NULL\n" -#: fe-connect.c:5749 +#: fe-connect.c:6499 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "경고: \"%s\" 패스워드 파ì¼ì´ plain 파ì¼ì´ 아님\n" -#: fe-connect.c:5758 +#: fe-connect.c:6508 #, c-format -msgid "" -"WARNING: password file \"%s\" has group or world access; permissions should " -"be u=rw (0600) or less\n" -msgstr "" -"경고: 패스워드 íŒŒì¼ \"%s\"ì— ê·¸ë£¹ ë˜ëŠ” 범용 액세스 ê¶Œí•œì´ ìžˆìŠµë‹ˆë‹¤. ê¶Œí•œì€ " -"u=rw(0600) ì´í•˜ì—¬ì•¼ 합니다.\n" +msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" +msgstr "경고: 패스워드 íŒŒì¼ \"%s\"ì— ê·¸ë£¹ ë˜ëŠ” 범용 액세스 ê¶Œí•œì´ ìžˆìŠµë‹ˆë‹¤. ê¶Œí•œì€ u=rw(0600) ì´í•˜ì—¬ì•¼ 합니다.\n" -#: fe-connect.c:5864 +#: fe-connect.c:6602 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "\"%s\" 파ì¼ì—서 암호를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: fe-exec.c:826 +#: fe-exec.c:437 fe-exec.c:2776 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "%d 번째 í–‰(row)ì€ 0..%d 범위를 벗어났ìŒ" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "메모리 부족" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "알림" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult 함수는 INT_MAX 튜플보다 ë§Žì€ ê²½ìš°ë¥¼ ì§€ì›í•˜ì§€ 않ìŒ" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "size_t 초과" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "명령 문ìžì—´ì´ null í¬ì¸í„°\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "매개변수값으로 숫ìžëŠ” 0ì—서 65535까지만 쓸 수 있ìŒ\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "실행 구문 ì´ë¦„ì´ null í¬ì¸íЏ(ê°’ì´ ì—†ìŒ)입니다\n" -#: fe-exec.c:1259 fe-exec.c:1423 fe-exec.c:2141 fe-exec.c:2340 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2390 msgid "function requires at least protocol version 3.0\n" msgstr "함수는 ì ì–´ë„ 버전 3ì˜ í”„ë¡œí† ì½œì„ ìš”êµ¬í•˜ê³  있습니다\n" -#: fe-exec.c:1377 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "ì„œë²„ì— ëŒ€í•œ ì—°ê²°ì´ ì—†ìŒ\n" -#: fe-exec.c:1384 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "처리 ì¤‘ì— ì´ë¯¸ 다른 ëª…ë ¹ì´ ì¡´ìž¬í•¨\n" -#: fe-exec.c:1499 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "ë°”ì´ë„ˆë¦¬ ìžë£Œ 매개 변수를 사용할 때는 ê·¸ 길ì´ë¥¼ 지정해야 함\n" -#: fe-exec.c:1771 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "기대ë˜ì§€ ì•Šì€ ë™ê¸°í™”ìƒíƒœ: %d\n" -#: fe-exec.c:1791 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEVT_RESULTCREATE ì´ë²¤íЏ ë™ì•ˆ PGEventProc \"%s\" 실패함\n" -#: fe-exec.c:1951 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "새 PQexec 호출로 COPY ìž‘ì—…ì´ ì¤‘ì§€ ë˜ì—ˆìŠµë‹ˆë‹¤" -#: fe-exec.c:1959 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "COPY IN ìƒíƒœê°€ 먼저 ë나야함\n" -#: fe-exec.c:1979 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "COPY OUT ìƒíƒœê°€ 먼저 ë나야함\n" -#: fe-exec.c:1987 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "COPY BOTH 작업 중ì—는 PQexec 사용할 수 ì—†ìŒ\n" -#: fe-exec.c:2230 fe-exec.c:2297 fe-exec.c:2387 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2280 fe-exec.c:2347 fe-exec.c:2437 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "처리 ê°€ìš´ë° COPYê°€ ì—†ìŒ\n" -#: fe-exec.c:2577 +#: fe-exec.c:2627 msgid "connection in wrong state\n" msgstr "ìž˜ëª»ëœ ìƒíƒœì˜ ì—°ê²°\n" -#: fe-exec.c:2608 +#: fe-exec.c:2658 msgid "invalid ExecStatusType code" msgstr "ìž˜ëª»ëœ ExecStatusType 코드" -#: fe-exec.c:2635 +#: fe-exec.c:2685 msgid "PGresult is not an error result\n" msgstr "PGresultê°€ 오류 결과가 아님\n" -#: fe-exec.c:2710 fe-exec.c:2733 +#: fe-exec.c:2760 fe-exec.c:2783 #, c-format msgid "column number %d is out of range 0..%d" msgstr "%d 번째 ì—´ì€ 0..%d 범위를 벗어났ìŒ" -#: fe-exec.c:2726 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "%d 번째 í–‰(row)ì€ 0..%d 범위를 벗어났ìŒ" - -#: fe-exec.c:2748 +#: fe-exec.c:2798 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "%dê°œì˜ ë§¤ê°œ 변수는 0..%d 범위를 벗어났ìŒ" -#: fe-exec.c:3058 +#: fe-exec.c:3108 #, c-format msgid "could not interpret result from server: %s" msgstr "서버로부터 결과처리를 중지 시킬 수 ì—†ìŒ: %s" -#: fe-exec.c:3297 fe-exec.c:3381 +#: fe-exec.c:3347 fe-exec.c:3431 msgid "incomplete multibyte character\n" msgstr "완성ë˜ì§€ ì•Šì€ ë©€í‹°ë°”ì´íЏ 문ìž\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "lo_truncate í•¨ìˆ˜ì˜ OID를 ê²°ì •í•  수 ì—†ìŒ\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "lo_truncate í•¨ìˆ˜ì˜ ì¸ìžê°’ì´ ì •ìˆ˜ 범위가 아님\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "lo_truncate64 í•¨ìˆ˜ì˜ OID를 알 수 ì—†ìŒ\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "lo_read í•¨ìˆ˜ì˜ ì¸ìžê°’ì´ ì •ìˆ˜ 범위가 아님\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "lo_write í•¨ìˆ˜ì˜ ì¸ìžê°’ì´ ì •ìˆ˜ 범위가 아님\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "lo_lseek64 í•¨ìˆ˜ì˜ OID를 알 수 ì—†ìŒ\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "lo_create í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "lo_tell64 í•¨ìˆ˜ì˜ OID를 알 수 ì—†ìŒ\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ ì—´ 수 ì—†ìŒ: %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "\"%s\" 파ì¼ì„ 쓸 수 ì—†ìŒ: %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "large object functionì„ ì´ˆê¸°í™” 하는 쿼리가 ë°ì´í„°ë¥¼ 리턴하지 않았ìŒ\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "lo_open í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "lo_close í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "lo_create í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "lo_unlink í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "lo_lseek í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "lo_tell í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "loread í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "lowrite í•¨ìˆ˜ì˜ OID 조사를 í•  수 ì—†ìŒ\n" -#: fe-misc.c:295 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "%lu 정수형 í¬ê¸°ëŠ” pqGetInt 함수ì—서 ì§€ì›í•˜ì§€ 않ìŒ" -#: fe-misc.c:331 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "%lu 정수형 í¬ê¸°ëŠ” pqPutInt 함수ì—서 ì§€ì›í•˜ì§€ 않ìŒ" -#: fe-misc.c:642 fe-misc.c:843 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "ì—°ê²° 열기 실패\n" -#: fe-misc.c:812 fe-secure-openssl.c:271 fe-secure-openssl.c:380 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -661,371 +774,349 @@ msgstr "" "\tì´ëŸ° 처리는 í´ë¼ì´ì–¸íŠ¸ì˜ ìš”êµ¬ë¥¼ 처리하는 ë™ì•ˆì´ë‚˜\n" "\t처리하기 ì „ì— ì„œë²„ê°€ ê°‘ìžê¸° 종료ë˜ì—ˆìŒì„ ì˜ë¯¸í•¨\n" -#: fe-misc.c:1016 +#: fe-misc.c:1009 msgid "timeout expired\n" msgstr "시간 초과\n" -#: fe-misc.c:1061 +#: fe-misc.c:1054 msgid "invalid socket\n" msgstr "ìž˜ëª»ëœ ì†Œì¼“\n" -#: fe-misc.c:1084 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "select() 실패: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "ìž˜ëª»ëœ í™˜ê²½ë³€ìˆ˜ ìƒíƒœ %c, 메모리 ì†ìƒì¼ ê°€ëŠ¥ì„±ì´ í¼\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "ìž˜ëª»ëœ ìƒíƒœ %c, 메모리 ì†ìƒì¼ ê°€ëŠ¥ì„±ì´ í¼\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "휴지(idle)ë™ì•ˆ 서버로 부터 0x%02x 형태 메시지를 받았ìŒ" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 -#: fe-protocol3.c:209 fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 -#: fe-protocol3.c:728 fe-protocol3.c:951 -msgid "out of memory" -msgstr "메모리 부족" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "비어있는 쿼리 ì‘답(\"I\" 메시지)ì— ë’¤ì´ì–´ %cì˜ ìž˜ëª»ëœ ë¬¸ìžê°€ 있ìŒ" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format -msgid "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)" -msgstr "" -"서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ìžë£Œ(\"D\" 메시지)를 보냈ìŒ" +msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" +msgstr "서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ìžë£Œ(\"D\" 메시지)를 보냈ìŒ" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format -msgid "" -"server sent binary data (\"B\" message) without prior row description (\"T\" " -"message)" -msgstr "" -"서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ë°”ì´ë„ˆë¦¬ ìžë£Œ(\"B\" 메시지)를 " -"보냈ìŒ" +msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" +msgstr "서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ë°”ì´ë„ˆë¦¬ ìžë£Œ(\"B\" 메시지)를 보냈ìŒ" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "서버로부터 예ìƒì¹˜ 못한 ì‘ë‹µì„ ë°›ì•˜ìŒ; \"%c\" 문ìžë¥¼ 첫문ìžë¡œ 받았ìŒ\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "쿼리 ê²°ê³¼ 처리를 위한 메모리 부족" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "ì„œë²„ì™€ì˜ ë™ê¸°í™”ê°€ ëŠê¹€, ì—°ê²°ì„ ìž¬ 시ë„함" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "프로토콜 오류: id=0x%x\n" -#: fe-protocol3.c:368 -msgid "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)\n" -msgstr "" -"서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ìžë£Œ(\"D\" 메시지)를 보냈ìŒ\n" +#: fe-protocol3.c:367 +msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" +msgstr "서버ì—서 먼저 í–‰(row) 설명(\"T\" 메시지) ì—†ì´ ìžë£Œ(\"D\" 메시지)를 보냈ìŒ\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "메시지 ë‚´ìš©ì´ \"%c\" 메시지 í˜•íƒœì˜ ê¸¸ì´ë¥¼ í—ˆë½í•˜ì§€ 않ìŒ\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "ì„œë²„ì™€ì˜ ë™ê¸°í™”ê°€ ëŠê¹€: \"%c\" 형태 ê¸¸ì´ %d 메시지 ë°›ìŒ\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "\"T\" 메시지 ì•ˆì— ë¶€ì¡±ìž ë°ì´í„°" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "\"T\" 메시지 ì•ˆì— ìž˜ëª»ëœ ë°ì´í„°" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "\"t\" 메시지 ì•ˆì— ìž˜ëª»ëœ ë°ì´í„°" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "\"D\" 메시지 ì•ˆì— ë¶ˆì¶©ë¶„í•œ ë°ì´í„°" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "\"D\" 메시지 ì•ˆì— ì˜ˆìƒì¹˜ 못한 필드 수" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "\"D\" 메시지 ì•ˆì— ìž˜ëª»ëœ ë°ì´í„°" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "보여줄 오류 메시지가 ì—†ìŒ\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" msgstr " 위치: %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "ìƒì„¸ì •ë³´: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "힌트: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "쿼리: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "구문: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1096 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "스키마 ì´ë¦„: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1100 #, c-format msgid "TABLE NAME: %s\n" msgstr "í…Œì´ë¸” ì´ë¦„: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1104 #, c-format msgid "COLUMN NAME: %s\n" msgstr "칼럼 ì´ë¦„: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "ìžë£Œí˜• ì´ë¦„: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1112 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "제약조건 ì´ë¦„: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "위치: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "줄 %d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: text COPY OUT ìž‘ì—…ì„ í•  수 ì—†ìŒ\n" -#: fe-secure-openssl.c:146 fe-secure-openssl.c:1031 fe-secure-openssl.c:1251 -#, c-format -msgid "could not acquire mutex: %s\n" -msgstr "mutex ì·¨ë“ ì‹¤íŒ¨: %s\n" +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "SSL ì¸ì¦ì„œì˜ ì´ë¦„ì— null 문ìžê°€ 있ìŒ\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "ì¸ì¦ëœ SSL ì ‘ì†ì„ 위해서는 호스트 ì´ë¦„ì„ ì§€ì •í•´ì•¼ 함\n" -#: fe-secure-openssl.c:158 +#: fe-secure-common.c:196 #, c-format -msgid "could not establish SSL connection: %s\n" -msgstr "SSL ì—°ê²°ì„ í™•ë¦½í•  수 ì—†ìŒ: %s\n" +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "서버 ì¸ì¦ì„œì˜ ì´ë¦„ \"%s\"ì´(ê°€) 호스트 ì´ë¦„ \"%s\"ê³¼(와) ì¼ì¹˜í•˜ì§€ 않ìŒ\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "서버 ì¸ì¦ì„œì—서 서버 호스트 ì´ë¦„ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -#: fe-secure-openssl.c:276 fe-secure-openssl.c:385 fe-secure-openssl.c:1377 +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALL 오류: %s\n" -#: fe-secure-openssl.c:283 fe-secure-openssl.c:392 fe-secure-openssl.c:1381 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALL 오류: EOF ê°ì§€ë¨\n" -#: fe-secure-openssl.c:294 fe-secure-openssl.c:403 fe-secure-openssl.c:1390 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSL 오류: %s\n" -#: fe-secure-openssl.c:309 fe-secure-openssl.c:418 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL ì—°ê²°ì´ ì˜ˆìƒì¹˜ 못하게 ëŠê¹€\n" -#: fe-secure-openssl.c:315 fe-secure-openssl.c:424 fe-secure-openssl.c:1399 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "알 수 없는 SSL 오류 코드: %d\n" -#: fe-secure-openssl.c:536 +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "서버 ì¸ì¦ì„œ 서명 ì•Œê³ ë¦¬ì¦˜ì„ ì•Œ 수 ì—†ìŒ\n" + +#: fe-secure-openssl.c:419 +#, c-format +msgid "could not find digest for NID %s\n" +msgstr "%s NIDìš© 다ì´ì œìŠ¤íŠ¸ë¥¼ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" + +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "피어 ì¸ì¦ 해시 ê°’ì„ ë§Œë“¤ 수 ì—†ìŒ\n" + +#: fe-secure-openssl.c:486 msgid "SSL certificate's name entry is missing\n" msgstr "SSL ì¸ì¦ì„œì˜ ì´ë¦„ í•­ëª©ì´ ìž˜ëª»ë¨\n" -#: fe-secure-openssl.c:566 -msgid "SSL certificate's name contains embedded null\n" -msgstr "SSL ì¸ì¦ì„œì˜ ì´ë¦„ì— null 문ìžê°€ 있ìŒ\n" +#: fe-secure-openssl.c:815 +#, c-format +msgid "could not create SSL context: %s\n" +msgstr "SSL context를 만들 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:617 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "ì¸ì¦ëœ SSL ì ‘ì†ì„ 위해서는 호스트 ì´ë¦„ì„ ì§€ì •í•´ì•¼ 함\n" +#: fe-secure-openssl.c:852 +#, c-format +msgid "could not read root certificate file \"%s\": %s\n" +msgstr "\"%s\" 루트 ì¸ì¦ì„œ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:717 +#: fe-secure-openssl.c:880 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "" -"서버 ì¸ì¦ì„œì˜ ì´ë¦„ \"%s\"ì´(ê°€) 호스트 ì´ë¦„ \"%s\"ê³¼(와) ì¼ì¹˜í•˜ì§€ 않ìŒ\n" +msgid "SSL library does not support CRL certificates (file \"%s\")\n" +msgstr "SSL ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ CRL ì¸ì¦ì„œ (\"%s\" 파ì¼)를 ì§€ì›í•˜ì§€ 않ìŒ\n" -#: fe-secure-openssl.c:723 -msgid "could not get server's host name from server certificate\n" -msgstr "서버 ì¸ì¦ì„œì—서 서버 호스트 ì´ë¦„ì„ ì°¾ì„ ìˆ˜ ì—†ìŒ\n" +#: fe-secure-openssl.c:908 +msgid "" +"could not get home directory to locate root certificate file\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"루트 ì¸ì¦ì„œ 파ì¼ì´ 있는 홈 디렉터리를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" +"해당 파ì¼ì„ 제공하거나 서버 ì¸ì¦ì„œ 확ì¸ì„ 사용하지 않ë„ë¡ sslmode를 변경하십시오.\n" -#: fe-secure-openssl.c:870 +#: fe-secure-openssl.c:912 #, c-format -msgid "could not create SSL context: %s\n" -msgstr "SSL context를 만들 수 ì—†ìŒ: %s\n" +msgid "" +"root certificate file \"%s\" does not exist\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"루트 ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì´(ê°€) 없습니다.\n" +"해당 파ì¼ì„ 제공하거나 서버 ì¸ì¦ì„œ 확ì¸ì„ 사용하지 않ë„ë¡ sslmode를 변경하십시오.\n" -#: fe-secure-openssl.c:1001 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "\"%s\" ì¸ì¦ì„œ 파ì¼ì„ 열수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1040 fe-secure-openssl.c:1055 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "\"%s\" ì¸ì¦ì„œ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1110 +#: fe-secure-openssl.c:987 +#, c-format +msgid "could not establish SSL connection: %s\n" +msgstr "SSL ì—°ê²°ì„ í™•ë¦½í•  수 ì—†ìŒ: %s\n" + +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "SSL 엔진 \"%s\"ì„(를) 로드할 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1122 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "SSL 엔진 \"%s\"ì„(를) 초기화할 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1138 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "ê°œì¸ SSL 키 \"%s\"ì„(를) \"%s\" 엔진ì—서 ì½ì„ 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1152 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "ê°œì¸ SSL 키 \"%s\"ì„(를) \"%s\" 엔진ì—서 ì½ì„ 수 ì—†ìŒ: %s\n" -#: fe-secure-openssl.c:1189 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "ì¸ì¦ì„œê°€ 있지만, \"%s\" ê°œì¸í‚¤ê°€ 아닙니다.\n" -#: fe-secure-openssl.c:1197 +#: fe-secure-openssl.c:1128 #, c-format -msgid "" -"private key file \"%s\" has group or world access; permissions should be " -"u=rw (0600) or less\n" -msgstr "" -"ê°œì¸ í‚¤ íŒŒì¼ \"%s\"ì— ê·¸ë£¹ ë˜ëŠ” 범용 액세스 ê¶Œí•œì´ ìžˆìŠµë‹ˆë‹¤. ê¶Œí•œì€ " -"u=rw(0600) ì´í•˜ì—¬ì•¼ 합니다.\n" +msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" +msgstr "ê°œì¸ í‚¤ íŒŒì¼ \"%s\"ì— ê·¸ë£¹ ë˜ëŠ” 범용 액세스 ê¶Œí•œì´ ìžˆìŠµë‹ˆë‹¤. ê¶Œí•œì€ u=rw(0600) ì´í•˜ì—¬ì•¼ 합니다.\n" -#: fe-secure-openssl.c:1208 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "\"%s\" ê°œì¸í‚¤ 파ì¼ì„ ë¶ˆëŸ¬ë“¤ì¼ ìˆ˜ 없습니다: %s\n" -#: fe-secure-openssl.c:1222 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "ì¸ì¦ì„œê°€ \"%s\" ê°œì¸í‚¤ 파ì¼ê³¼ ë§žì§€ 않습니다: %s\n" -#: fe-secure-openssl.c:1260 -#, c-format -msgid "could not read root certificate file \"%s\": %s\n" -msgstr "\"%s\" 루트 ì¸ì¦ì„œ 파ì¼ì„ ì½ì„ 수 ì—†ìŒ: %s\n" - -#: fe-secure-openssl.c:1290 -#, c-format -msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "SSL ë¼ì´ë¸ŒëŸ¬ë¦¬ê°€ CRL ì¸ì¦ì„œ (\"%s\" 파ì¼)를 ì§€ì›í•˜ì§€ 않ìŒ\n" - -#: fe-secure-openssl.c:1323 -msgid "" -"could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"루트 ì¸ì¦ì„œ 파ì¼ì´ 있는 홈 디렉터리를 ì°¾ì„ ìˆ˜ ì—†ìŒ\n" -"해당 파ì¼ì„ 제공하거나 서버 ì¸ì¦ì„œ 확ì¸ì„ 사용하지 않ë„ë¡ sslmode를 변경하십" -"시오.\n" - -#: fe-secure-openssl.c:1327 -#, c-format -msgid "" -"root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"루트 ì¸ì¦ì„œ íŒŒì¼ \"%s\"ì´(ê°€) 없습니다.\n" -"해당 파ì¼ì„ 제공하거나 서버 ì¸ì¦ì„œ 확ì¸ì„ 사용하지 않ë„ë¡ sslmode를 변경하십" -"시오.\n" - -#: fe-secure-openssl.c:1420 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "ì¸ì¦ì„œë¥¼ 구하질 못했습니다: %s\n" -#: fe-secure-openssl.c:1512 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "SSL 오류 ì—†ìŒì´ ë³´ê³ ë¨" -#: fe-secure-openssl.c:1521 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSL 오류 번호 %lu" -#: fe-secure.c:261 +#: fe-secure.c:269 #, c-format msgid "could not receive data from server: %s\n" msgstr "서버로부터 ë°ì´í„°ë¥¼ 받지 못했ìŒ: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:378 #, c-format msgid "could not send data to server: %s\n" msgstr "ì„œë²„ì— ë°ì´í„°ë¥¼ 보낼 수 ì—†ìŒ: %s\n" diff --git a/src/interfaces/libpq/po/ru.po b/src/interfaces/libpq/po/ru.po index de6e91fc72d..2d7e138a6e1 100644 --- a/src/interfaces/libpq/po/ru.po +++ b/src/interfaces/libpq/po/ru.po @@ -4,14 +4,14 @@ # Serguei A. Mokhov , 2001-2004. # Oleg Bartunov , 2005. # Andrey Sudnik , 2010. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: libpq (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:38+0000\n" -"PO-Revision-Date: 2017-03-29 06:55+0300\n" +"POT-Creation-Date: 2019-04-30 07:03+0300\n" +"PO-Revision-Date: 2018-10-03 13:55+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -19,123 +19,236 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" -#: fe-auth.c:149 +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (empty message)\n" +msgstr "неправильное Ñообщение SCRAM (пуÑтое Ñодержимое)\n" + +#: fe-auth-scram.c:195 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "неправильное Ñообщение SCRAM (Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð°)\n" + +#: fe-auth-scram.c:244 +msgid "incorrect server signature\n" +msgstr "Ð½ÐµÐºÐ¾Ñ€Ñ€ÐµÐºÑ‚Ð½Ð°Ñ Ñигнатура Ñервера\n" + +#: fe-auth-scram.c:253 +msgid "invalid SCRAM exchange state\n" +msgstr "ошибочное ÑоÑтоÑние обмена SCRAM\n" + +#: fe-auth-scram.c:276 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "неправильное Ñообщение SCRAM (ожидалÑÑ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚ \"%c\")\n" + +#: fe-auth-scram.c:285 +#, c-format +msgid "" +"malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "" +"неправильное Ñообщение SCRAM (Ð´Ð»Ñ Ð°Ñ‚Ñ€Ð¸Ð±ÑƒÑ‚Ð° \"%c\" ожидалÑÑ Ñимвол \"=\")\n" + +#: fe-auth-scram.c:326 +msgid "could not generate nonce\n" +msgstr "не удалоÑÑŒ Ñгенерировать разовый код\n" + +#: fe-auth-scram.c:334 fe-auth-scram.c:401 fe-auth-scram.c:523 +#: fe-auth-scram.c:543 fe-auth-scram.c:569 fe-auth-scram.c:583 +#: fe-auth-scram.c:625 fe-auth.c:227 fe-auth.c:362 fe-auth.c:432 fe-auth.c:467 +#: fe-auth.c:653 fe-auth.c:812 fe-auth.c:1124 fe-auth.c:1272 fe-connect.c:835 +#: fe-connect.c:1264 fe-connect.c:1440 fe-connect.c:1922 fe-connect.c:1945 +#: fe-connect.c:2606 fe-connect.c:4152 fe-connect.c:4404 fe-connect.c:4523 +#: fe-connect.c:4773 fe-connect.c:4853 fe-connect.c:4952 fe-connect.c:5208 +#: fe-connect.c:5237 fe-connect.c:5309 fe-connect.c:5333 fe-connect.c:5351 +#: fe-connect.c:5452 fe-connect.c:5461 fe-connect.c:5817 fe-connect.c:5967 +#: fe-exec.c:2705 fe-exec.c:3452 fe-exec.c:3617 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1685 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "нехватка памÑти\n" + +#: fe-auth-scram.c:561 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "неверный ответ SCRAM (неÑовпадение проверочного кода)\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "неправильное Ñообщение SCRAM (некорректное чиÑло итераций)\n" + +#: fe-auth-scram.c:606 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "" +"неправильное Ñообщение SCRAM (муÑор в конце первого ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñервера)\n" + +#: fe-auth-scram.c:636 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "в ходе обмена SCRAM от Ñервера получена ошибка: %s\n" + +#: fe-auth-scram.c:652 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "" +"неправильное Ñообщение SCRAM (муÑор в конце поÑледнего ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ñервера)\n" + +#: fe-auth-scram.c:660 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "неправильное Ñообщение SCRAM (Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ñигнатура Ñервера)\n" + +#: fe-auth.c:122 +#, c-format +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° GSSAPI (%d)\n" + +#: fe-auth.c:177 msgid "GSSAPI continuation error" msgstr "ошибка Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ð² GSSAPI" -#: fe-auth.c:179 fe-auth.c:415 +#: fe-auth.c:207 fe-auth.c:461 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "требуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð¸Ð¼Ñ Ñервера\n" -#: fe-auth.c:186 +#: fe-auth.c:214 msgid "duplicate GSS authentication request\n" msgstr "повторный Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ GSS\n" -#: fe-auth.c:199 fe-auth.c:311 fe-auth.c:386 fe-auth.c:421 fe-auth.c:465 -#: fe-auth.c:599 fe-auth.c:902 fe-connect.c:716 fe-connect.c:1086 -#: fe-connect.c:1262 fe-connect.c:1798 fe-connect.c:2326 fe-connect.c:4000 -#: fe-connect.c:4252 fe-connect.c:4371 fe-connect.c:4611 fe-connect.c:4691 -#: fe-connect.c:4790 fe-connect.c:5046 fe-connect.c:5075 fe-connect.c:5147 -#: fe-connect.c:5165 fe-connect.c:5266 fe-connect.c:5275 fe-connect.c:5631 -#: fe-connect.c:5781 fe-exec.c:2651 fe-exec.c:3398 fe-exec.c:3563 fe-lobj.c:896 -#: fe-protocol2.c:1206 fe-protocol3.c:992 fe-protocol3.c:1678 -#: fe-secure-openssl.c:514 fe-secure-openssl.c:1137 -msgid "out of memory\n" -msgstr "нехватка памÑти\n" - -#: fe-auth.c:212 +#: fe-auth.c:240 msgid "GSSAPI name import error" msgstr "ошибка импорта имени в GSSAPI" -#: fe-auth.c:300 +#: fe-auth.c:303 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° SSPI (%d)\n" + +#: fe-auth.c:351 msgid "SSPI continuation error" msgstr "ошибка Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶ÐµÐ½Ð¸Ñ Ð² SSPI" -#: fe-auth.c:401 +#: fe-auth.c:422 +msgid "duplicate SSPI authentication request\n" +msgstr "повторный Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ SSPI\n" + +#: fe-auth.c:447 msgid "could not acquire SSPI credentials" msgstr "не удалоÑÑŒ получить удоÑтоверение SSPI" -#: fe-auth.c:474 +#: fe-auth.c:501 +msgid "duplicate SASL authentication request\n" +msgstr "повторный Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ SASL\n" + +#: fe-auth.c:559 +msgid "" +"server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "" +"Ñервер предложил аутентификацию SCRAM-SHA-256-PLUS Ð´Ð»Ñ ÑоединениÑ, не " +"защищённого SSL\n" + +#: fe-auth.c:571 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "" +"ни один из Ñерверных механизмов аутентификации SASL не поддерживаетÑÑ\n" + +#: fe-auth.c:677 #, c-format -msgid "SASL authentication mechanism %s not supported\n" -msgstr "механизм аутентификации SASL %s не поддерживаетÑÑ\n" +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° SASL (%d)\n" -#: fe-auth.c:574 +#: fe-auth.c:702 +msgid "" +"AuthenticationSASLFinal received from server, but SASL authentication was " +"not completed\n" +msgstr "" +"c Ñервера получено Ñообщение AuthenticationSASLFinal, но Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ SASL " +"ещё не завершена\n" + +#: fe-auth.c:779 msgid "SCM_CRED authentication method not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ SCM_CRED не поддерживаетÑÑ\n" -#: fe-auth.c:650 +#: fe-auth.c:870 msgid "Kerberos 4 authentication not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Kerberos 4 не поддерживаетÑÑ\n" -#: fe-auth.c:655 +#: fe-auth.c:875 msgid "Kerberos 5 authentication not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Kerberos 5 не поддерживаетÑÑ\n" -#: fe-auth.c:726 +#: fe-auth.c:946 msgid "GSSAPI authentication not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· GSSAPI не поддерживаетÑÑ\n" -#: fe-auth.c:758 +#: fe-auth.c:978 msgid "SSPI authentication not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· SSPI не поддерживаетÑÑ\n" -#: fe-auth.c:766 +#: fe-auth.c:986 msgid "Crypt authentication not supported\n" msgstr "Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Crypt не поддерживаетÑÑ\n" -#: fe-auth.c:830 +#: fe-auth.c:1052 #, c-format msgid "authentication method %u not supported\n" msgstr "метод аутентификации %u не поддерживаетÑÑ\n" -#: fe-auth.c:877 +#: fe-auth.c:1099 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "раÑпознать Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð½Ðµ удалоÑÑŒ (код ошибки: %lu)\n" -#: fe-auth.c:887 fe-connect.c:2253 +#: fe-auth.c:1109 fe-connect.c:2533 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "найти локального Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð¿Ð¾ идентификатору (%d) не удалоÑÑŒ: %s\n" -#: fe-auth.c:892 fe-connect.c:2258 +#: fe-auth.c:1114 fe-connect.c:2538 #, c-format msgid "local user with ID %d does not exist\n" msgstr "локальный пользователь Ñ ID %d не ÑущеÑтвует\n" -#: fe-connect.c:918 +#: fe-auth.c:1216 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "Ð½ÐµÐ¾Ð¶Ð¸Ð´Ð°Ð½Ð½Ð°Ñ Ñ„Ð¾Ñ€Ð¼Ð° набора результатов, возвращённого Ð´Ð»Ñ SHOW\n" + +#: fe-auth.c:1225 +msgid "password_encryption value too long\n" +msgstr "Ñлишком длинное значение password_encryption\n" + +#: fe-auth.c:1265 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "нераÑпознанный алгоритм ÑˆÐ¸Ñ„Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ \"%s\"\n" + +#: fe-connect.c:1018 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "не удалоÑÑŒ ÑопоÑтавить имена узлов (%d) Ñо значениÑми hostaddr (%d)\n" + +#: fe-connect.c:1094 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "не удалоÑÑŒ ÑопоÑтавить номера портов (%d) Ñ ÑƒÐ·Ð»Ð°Ð¼Ð¸ (%d)\n" -#: fe-connect.c:970 -msgid "could not get home directory to locate password file\n" -msgstr "не удалоÑÑŒ получить домашний каталог Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файла паролей\n" - -#: fe-connect.c:1012 +#: fe-connect.c:1190 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "неверное значение sslmode: \"%s\"\n" -#: fe-connect.c:1033 +#: fe-connect.c:1211 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "значение sslmode \"%s\" недопуÑтимо Ð´Ð»Ñ Ñборки без поддержки SSL\n" -#: fe-connect.c:1068 +#: fe-connect.c:1246 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "неверное значение target_session_attrs: \"%s\"\n" -#: fe-connect.c:1286 +#: fe-connect.c:1464 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "не удалоÑÑŒ перевеÑти Ñокет в режим TCP-передачи без задержки: %s\n" -#: fe-connect.c:1316 +#: fe-connect.c:1494 #, c-format msgid "" "could not connect to server: %s\n" @@ -144,9 +257,9 @@ msgid "" msgstr "" "не удалоÑÑŒ подключитьÑÑ Ðº Ñерверу: %s\n" "\tОн дейÑтвительно работает локально и принимает\n" -"\tÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· доменный Ñокет \"%s\"?\n" +"\tÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ‡ÐµÑ€ÐµÐ· Unix-Ñокет \"%s\"?\n" -#: fe-connect.c:1371 +#: fe-connect.c:1552 #, c-format msgid "" "could not connect to server: %s\n" @@ -157,7 +270,7 @@ msgstr "" "\tОн дейÑтвительно работает по адреÑу \"%s\" (%s)\n" "\t и принимает TCP-ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (порт %s)?\n" -#: fe-connect.c:1380 +#: fe-connect.c:1561 #, c-format msgid "" "could not connect to server: %s\n" @@ -168,259 +281,229 @@ msgstr "" "\tОн дейÑтвительно работает по адреÑу \"%s\"\n" "\t и принимает TCP-ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ (порт %s)?\n" -#: fe-connect.c:1431 +#: fe-connect.c:1612 fe-connect.c:1644 fe-connect.c:1677 fe-connect.c:2325 #, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "ошибка в setsockopt(TCP_KEEPIDLE): %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "ошибка в setsockopt(%s): %s\n" -#: fe-connect.c:1444 -#, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "ошибка в setsockopt(TCP_KEEPALIVE): %s\n" - -#: fe-connect.c:1476 -#, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "ошибка в setsockopt(TCP_KEEPINTVL): %s\n" - -#: fe-connect.c:1508 -#, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "ошибка в setsockopt(TCP_KEEPCNT): %s\n" - -#: fe-connect.c:1556 +#: fe-connect.c:1726 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "ошибка в WSAIoctl(SIO_KEEPALIVE_VALS): %ui\n" -#: fe-connect.c:1614 +#: fe-connect.c:2035 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "неверное ÑоÑтоÑние ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ - возможно разрушение памÑти\n" + +#: fe-connect.c:2101 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "неверный номер порта: \"%s\"\n" -#: fe-connect.c:1638 -#, c-format -msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" -msgstr "длина пути доменного Ñокета \"%s\" превышает предел (%d байт)\n" - -#: fe-connect.c:1656 +#: fe-connect.c:2117 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "преобразовать Ð¸Ð¼Ñ \"%s\" в Ð°Ð´Ñ€ÐµÑ Ð½Ðµ удалоÑÑŒ: %s\n" -#: fe-connect.c:1660 +#: fe-connect.c:2130 #, c-format -msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" -msgstr "" -"преобразовать путь к доменному Ñокету UNIX \"%s\" в Ð°Ð´Ñ€ÐµÑ Ð½Ðµ удалоÑÑŒ: %s\n" +msgid "could not parse network address \"%s\": %s\n" +msgstr "не удалоÑÑŒ разобрать Ñетевой Ð°Ð´Ñ€ÐµÑ \"%s\": %s\n" -#: fe-connect.c:1904 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "неверное ÑоÑтоÑние ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ - возможно разрушение памÑти\n" +#: fe-connect.c:2143 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" +msgstr "длина пути Unix-Ñокета \"%s\" превышает предел (%d байт)\n" + +#: fe-connect.c:2158 +#, c-format +msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" +msgstr "преобразовать путь Unix-Ñокета \"%s\" в Ð°Ð´Ñ€ÐµÑ Ð½Ðµ удалоÑÑŒ: %s\n" -#: fe-connect.c:1961 +#: fe-connect.c:2262 #, c-format msgid "could not create socket: %s\n" msgstr "не удалоÑÑŒ Ñоздать Ñокет: %s\n" -#: fe-connect.c:1983 +#: fe-connect.c:2284 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "не удалоÑÑŒ перевеÑти Ñокет в неблокирующий режим: %s\n" -#: fe-connect.c:1994 +#: fe-connect.c:2294 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "" "не удалоÑÑŒ перевеÑти Ñокет в режим Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ð¿Ñ€Ð¸ выполнении (close-on-exec): " "%s\n" -#: fe-connect.c:2013 +#: fe-connect.c:2312 msgid "keepalives parameter must be an integer\n" msgstr "параметр keepalives должен быть целым чиÑлом\n" -#: fe-connect.c:2026 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "ошибка в setsockopt(SO_KEEPALIVE): %s\n" - -#: fe-connect.c:2163 +#: fe-connect.c:2450 #, c-format msgid "could not get socket error status: %s\n" msgstr "не удалоÑÑŒ получить ÑÑ‚Ð°Ñ‚ÑƒÑ Ð¾ÑˆÐ¸Ð±ÐºÐ¸ Ñокета: %s\n" -#: fe-connect.c:2198 +#: fe-connect.c:2478 #, c-format msgid "could not get client address from socket: %s\n" msgstr "не удалоÑÑŒ получить Ð°Ð´Ñ€ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð° из Ñокета: %s\n" -#: fe-connect.c:2240 +#: fe-connect.c:2520 msgid "requirepeer parameter is not supported on this platform\n" msgstr "параметр requirepeer не поддерживаетÑÑ Ð² Ñтой ОС\n" -#: fe-connect.c:2243 +#: fe-connect.c:2523 #, c-format msgid "could not get peer credentials: %s\n" msgstr "не удалоÑÑŒ получить учётные данные Ñервера: %s\n" -#: fe-connect.c:2266 +#: fe-connect.c:2546 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "" "requirepeer допуÑкает подключение только к \"%s\", но Ñервер работает под " "именем \"%s\"\n" -#: fe-connect.c:2300 +#: fe-connect.c:2580 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "не удалоÑÑŒ отправить пакет ÑоглаÑÐ¾Ð²Ð°Ð½Ð¸Ñ SSL: %s\n" -#: fe-connect.c:2339 +#: fe-connect.c:2619 #, c-format msgid "could not send startup packet: %s\n" msgstr "не удалоÑÑŒ отправить Ñтартовый пакет: %s\n" -#: fe-connect.c:2409 +#: fe-connect.c:2689 msgid "server does not support SSL, but SSL was required\n" msgstr "затребовано подключение через SSL, но Ñервер не поддерживает SSL\n" -#: fe-connect.c:2435 +#: fe-connect.c:2715 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "получен неверный ответ на ÑоглаÑование SSL: %c\n" -#: fe-connect.c:2510 fe-connect.c:2543 +#: fe-connect.c:2792 fe-connect.c:2825 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "ожидалÑÑ Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸ от Ñервера, но получено: %c\n" -#: fe-connect.c:2710 -#, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° GSSAPI (%d)" - -#: fe-connect.c:2748 -#, c-format -msgid "out of memory allocating SASL buffer (%d)" -msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ð±ÑƒÑ„ÐµÑ€Ð° SASL (%d)" - -#: fe-connect.c:2838 +#: fe-connect.c:3052 msgid "unexpected message from server during startup\n" msgstr "неожиданное Ñообщение от Ñервера в начале работы\n" -#: fe-connect.c:3042 +#: fe-connect.c:3282 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "" "не удалоÑÑŒ уÑтановить подключение Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ/запиÑи к Ñерверу \"%s:%s\"\n" -#: fe-connect.c:3084 +#: fe-connect.c:3328 #, c-format -msgid "test \"show transaction_read_only\" failed on \"%s:%s\" \n" -msgstr "проверка \"show transaction_read_only\" не пройдена на \"%s:%s\" \n" +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "" +"проверка \"SHOW transaction_read_only\" не пройдена на Ñервере \"%s:%s\"\n" -#: fe-connect.c:3106 +#: fe-connect.c:3343 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "неверное ÑоÑтоÑние ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ %d - возможно разрушение памÑти\n" -#: fe-connect.c:3606 fe-connect.c:3666 +#: fe-connect.c:3758 fe-connect.c:3818 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "ошибка в PGEventProc \"%s\" при обработке ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ PGEVT_CONNRESET\n" -#: fe-connect.c:4013 +#: fe-connect.c:4165 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": Ñхема должна быть ldap://\n" -#: fe-connect.c:4028 +#: fe-connect.c:4180 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": отÑутÑтвует уникальное имÑ\n" -#: fe-connect.c:4039 fe-connect.c:4092 +#: fe-connect.c:4191 fe-connect.c:4244 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": должен быть только один атрибут\n" -#: fe-connect.c:4049 fe-connect.c:4106 +#: fe-connect.c:4201 fe-connect.c:4258 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "" "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": не указана облаÑть поиÑка (base/one/sub)\n" -#: fe-connect.c:4060 +#: fe-connect.c:4212 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": нет фильтра\n" -#: fe-connect.c:4081 +#: fe-connect.c:4233 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "некорректный Ð°Ð´Ñ€ÐµÑ LDAP \"%s\": неверный номер порта\n" -#: fe-connect.c:4115 +#: fe-connect.c:4267 msgid "could not create LDAP structure\n" msgstr "не удалоÑÑŒ Ñоздать Ñтруктуру LDAP\n" -#: fe-connect.c:4191 +#: fe-connect.c:4343 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "ошибка поиÑка на Ñервере LDAP: %s\n" -#: fe-connect.c:4202 +#: fe-connect.c:4354 msgid "more than one entry found on LDAP lookup\n" msgstr "при поиÑке LDAP найдено более одного вхождениÑ\n" -#: fe-connect.c:4203 fe-connect.c:4215 +#: fe-connect.c:4355 fe-connect.c:4367 msgid "no entry found on LDAP lookup\n" msgstr "при поиÑке LDAP ничего не найдено\n" -#: fe-connect.c:4226 fe-connect.c:4239 +#: fe-connect.c:4378 fe-connect.c:4391 msgid "attribute has no values on LDAP lookup\n" msgstr "атрибут не Ñодержит значений при поиÑке LDAP\n" -#: fe-connect.c:4291 fe-connect.c:4310 fe-connect.c:4829 +#: fe-connect.c:4443 fe-connect.c:4462 fe-connect.c:4991 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "в Ñтроке ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½ÐµÑ‚ \"=\" поÑле \"%s\"\n" -#: fe-connect.c:4383 fe-connect.c:5014 fe-connect.c:5764 +#: fe-connect.c:4535 fe-connect.c:5176 fe-connect.c:5950 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "неверный параметр ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ \"%s\"\n" -#: fe-connect.c:4399 fe-connect.c:4878 +#: fe-connect.c:4551 fe-connect.c:5040 msgid "unterminated quoted string in connection info string\n" msgstr "в Ñтроке ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð½Ðµ хватает закрывающей кавычки\n" -#: fe-connect.c:4439 -msgid "could not get home directory to locate service definition file" -msgstr "" -"не удалоÑÑŒ получить домашний каталог Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файла определений Ñлужб" - -#: fe-connect.c:4472 +#: fe-connect.c:4634 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "определение Ñлужбы \"%s\" не найдено\n" -#: fe-connect.c:4495 +#: fe-connect.c:4657 #, c-format msgid "service file \"%s\" not found\n" msgstr "файл определений Ñлужб \"%s\" не найден\n" -#: fe-connect.c:4508 +#: fe-connect.c:4670 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "Ñлишком Ð´Ð»Ð¸Ð½Ð½Ð°Ñ Ñтрока (%d) в файле определений Ñлужб \"%s\"\n" -#: fe-connect.c:4579 fe-connect.c:4623 +#: fe-connect.c:4741 fe-connect.c:4785 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "ÑинтакÑичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° в файле Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñлужб \"%s\" (Ñтрока %d)\n" -#: fe-connect.c:4590 +#: fe-connect.c:4752 #, c-format msgid "" "nested service specifications not supported in service file \"%s\", line %d\n" @@ -428,24 +511,24 @@ msgstr "" "рекурÑивные Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñлужб не поддерживаютÑÑ (файл Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñлужб \"%s" "\", Ñтрока %d)\n" -#: fe-connect.c:5286 +#: fe-connect.c:5472 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "во внутреннюю процедуру разбора Ñтроки передан ошибочный URI: \"%s\"\n" -#: fe-connect.c:5363 +#: fe-connect.c:5549 #, c-format msgid "" "end of string reached when looking for matching \"]\" in IPv6 host address " "in URI: \"%s\"\n" msgstr "URI не Ñодержит Ñимвол \"]\" поÑле адреÑа IPv6: \"%s\"\n" -#: fe-connect.c:5370 +#: fe-connect.c:5556 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "IPv6, ÑодержащийÑÑ Ð² URI, не может быть пуÑтым: \"%s\"\n" -#: fe-connect.c:5385 +#: fe-connect.c:5571 #, c-format msgid "" "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): " @@ -454,41 +537,41 @@ msgstr "" "неожиданный Ñимвол \"%c\" в позиции %d в URI (ожидалоÑÑŒ \":\" или \"/\"): " "\"%s\"\n" -#: fe-connect.c:5514 +#: fe-connect.c:5700 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "лишний разделитель ключа/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"=\" в параметрах URI: \"%s\"\n" -#: fe-connect.c:5534 +#: fe-connect.c:5720 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "в параметрах URI не хватает Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ ÐºÐ»ÑŽÑ‡Ð°/Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ \"=\": \"%s\"\n" -#: fe-connect.c:5585 +#: fe-connect.c:5771 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "неверный параметр в URI: \"%s\"\n" -#: fe-connect.c:5659 +#: fe-connect.c:5845 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "неверный Ñимвол, закодированный Ñ %%: \"%s\"\n" -#: fe-connect.c:5669 +#: fe-connect.c:5855 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "недопуÑтимое значение %%00 Ð´Ð»Ñ Ñимвола, закодированного Ñ %%: \"%s\"\n" -#: fe-connect.c:6014 +#: fe-connect.c:6201 msgid "connection pointer is NULL\n" msgstr "нулевой указатель ÑоединениÑ\n" -#: fe-connect.c:6312 +#: fe-connect.c:6499 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "ПРЕДУПРЕЖДЕÐИЕ: файл паролей \"%s\" - не обычный файл\n" -#: fe-connect.c:6321 +#: fe-connect.c:6508 #, c-format msgid "" "WARNING: password file \"%s\" has group or world access; permissions should " @@ -497,209 +580,228 @@ msgstr "" "ПРЕДУПРЕЖДЕÐИЕ: к файлу паролей \"%s\" имеют доÑтуп вÑе или группа; права " "должны быть u=rw (0600) или более ограниченные\n" -#: fe-connect.c:6413 +#: fe-connect.c:6602 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "пароль получен из файла \"%s\"\n" -#: fe-exec.c:826 +#: fe-exec.c:437 fe-exec.c:2779 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "номер запиÑи %d вне диапазона 0..%d" + +#: fe-exec.c:498 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "нехватка памÑти" + +#: fe-exec.c:499 fe-protocol2.c:1402 fe-protocol3.c:1893 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:847 msgid "NOTICE" msgstr "ЗÐМЕЧÐÐИЕ" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:905 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult не может вмеÑтить больше чем INT_MAX кортежей" + +#: fe-exec.c:917 +msgid "size_t overflow" +msgstr "переполнение size_t" + +#: fe-exec.c:1192 fe-exec.c:1250 fe-exec.c:1296 msgid "command string is a null pointer\n" msgstr "указатель на командную Ñтроку нулевой\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1256 fe-exec.c:1302 fe-exec.c:1397 msgid "number of parameters must be between 0 and 65535\n" msgstr "чиÑло параметров должно быть от 0 до 65535\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1290 fe-exec.c:1391 msgid "statement name is a null pointer\n" msgstr "указатель на Ð¸Ð¼Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ‚Ð¾Ñ€Ð° нулевой\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1310 fe-exec.c:1473 fe-exec.c:2191 fe-exec.c:2393 msgid "function requires at least protocol version 3.0\n" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ протокол минимум верÑии 3.0\n" -#: fe-exec.c:1377 +#: fe-exec.c:1428 msgid "no connection to the server\n" msgstr "нет ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ñервером\n" -#: fe-exec.c:1384 +#: fe-exec.c:1435 msgid "another command is already in progress\n" msgstr "уже выполнÑетÑÑ Ð´Ñ€ÑƒÐ³Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°\n" -#: fe-exec.c:1498 +#: fe-exec.c:1549 msgid "length must be given for binary parameter\n" msgstr "Ð´Ð»Ñ Ð´Ð²Ð¾Ð¸Ñ‡Ð½Ð¾Ð³Ð¾ параметра должна быть указана длина\n" -#: fe-exec.c:1770 +#: fe-exec.c:1821 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "неожиданный asyncStatus: %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1841 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "ошибка в PGEventProc \"%s\" при обработке ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ PGEVT_RESULTCREATE\n" -#: fe-exec.c:1950 +#: fe-exec.c:2001 msgid "COPY terminated by new PQexec" msgstr "Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ COPY прервана вызовом PQexec" -#: fe-exec.c:1958 +#: fe-exec.c:2009 msgid "COPY IN state must be terminated first\n" msgstr "Ñначала должно завершитьÑÑ ÑоÑтоÑние COPY IN\n" -#: fe-exec.c:1978 +#: fe-exec.c:2029 msgid "COPY OUT state must be terminated first\n" msgstr "Ñначала должно завершитьÑÑ ÑоÑтоÑние COPY OUT\n" -#: fe-exec.c:1986 +#: fe-exec.c:2037 msgid "PQexec not allowed during COPY BOTH\n" msgstr "вызов PQexec не допуÑкаетÑÑ Ð² процеÑÑе COPY BOTH\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2283 fe-exec.c:2350 fe-exec.c:2440 fe-protocol2.c:1359 +#: fe-protocol3.c:1824 msgid "no COPY in progress\n" msgstr "Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ COPY не выполнÑетÑÑ\n" -#: fe-exec.c:2576 +#: fe-exec.c:2630 msgid "connection in wrong state\n" msgstr "Ñоединение в неправильном ÑоÑтоÑнии\n" -#: fe-exec.c:2607 +#: fe-exec.c:2661 msgid "invalid ExecStatusType code" msgstr "неверный код ExecStatusType" -#: fe-exec.c:2634 +#: fe-exec.c:2688 msgid "PGresult is not an error result\n" msgstr "Ð’ PGresult не передан результат ошибки\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2763 fe-exec.c:2786 #, c-format msgid "column number %d is out of range 0..%d" msgstr "номер Ñтолбца %d вне диапазона 0..%d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "номер запиÑи %d вне диапазона 0..%d" - -#: fe-exec.c:2747 +#: fe-exec.c:2801 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "номер параметра %d вне диапазона 0..%d" -#: fe-exec.c:3057 +#: fe-exec.c:3111 #, c-format msgid "could not interpret result from server: %s" msgstr "не удалоÑÑŒ интерпретировать ответ Ñервера: %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3350 fe-exec.c:3434 msgid "incomplete multibyte character\n" msgstr "неполный многобайтный Ñимвол\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "не удалоÑÑŒ определить OID функции lo_truncate\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "аргумент lo_truncate не умещаетÑÑ Ð² обычном целом\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "не удалоÑÑŒ определить OID функции lo_truncate64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "аргумент lo_read не умещаетÑÑ Ð² обычном целом\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "аргумент lo_write не умещаетÑÑ Ð² обычном целом\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "не удалоÑÑŒ определить OID функции lo_lseek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "не удалоÑÑŒ определить OID функции lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "не удалоÑÑŒ определить OID функции lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть файл \"%s\": %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "не удалоÑÑŒ прочитать файл \"%s\": %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "не удалоÑÑŒ запиÑать файл \"%s\": %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ функций Ð´Ð»Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ñ… объектов не вернул данные\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "не удалоÑÑŒ определить OID функции lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "не удалоÑÑŒ определить OID функции lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "не удалоÑÑŒ определить OID функции lo_creat\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "не удалоÑÑŒ определить OID функции lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "не удалоÑÑŒ определить OID функции lo_lseek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "не удалоÑÑŒ определить OID функции lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "не удалоÑÑŒ определить OID функции loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "не удалоÑÑŒ определить OID функции lowrite\n" -#: fe-misc.c:295 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ pqGetInt не поддерживает integer размером %lu байт" -#: fe-misc.c:331 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ pqPutInt не поддерживает integer размером %lu байт" -#: fe-misc.c:642 fe-misc.c:843 +#: fe-misc.c:637 fe-misc.c:838 msgid "connection not open\n" msgstr "Ñоединение не открыто\n" -#: fe-misc.c:812 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:261 fe-secure.c:371 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -709,46 +811,40 @@ msgstr "" "\tСкорее вÑего Ñервер прекратил работу из-за ÑбоÑ\n" "\tдо или в процеÑÑе Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа.\n" -#: fe-misc.c:1016 +#: fe-misc.c:1009 msgid "timeout expired\n" -msgstr "таймаут\n" +msgstr "тайм-аут\n" -#: fe-misc.c:1061 +#: fe-misc.c:1054 msgid "invalid socket\n" msgstr "неверный Ñокет\n" -#: fe-misc.c:1084 +#: fe-misc.c:1077 #, c-format msgid "select() failed: %s\n" msgstr "ошибка в select(): %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "неверное ÑоÑтоÑние setenv %c - возможно разрушение памÑти\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "неверное ÑоÑтоÑние %c - возможно разрушение памÑти\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "от Ñервера во Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€Ð¾ÑÑ‚Ð¾Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¾ Ñообщение типа 0x%02x" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 fe-protocol3.c:209 -#: fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 fe-protocol3.c:728 -#: fe-protocol3.c:951 -msgid "out of memory" -msgstr "нехватка памÑти" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "неожиданный Ñимвол %c вÑлед за пуÑтым ответом (Ñообщение \"I\")" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format msgid "" "server sent data (\"D\" message) without prior row description (\"T\" " @@ -757,7 +853,7 @@ msgstr "" "Ñервер отправил данные (Ñообщение \"D\") без предварительного опиÑÐ°Ð½Ð¸Ñ " "Ñтроки (Ñообщение \"T\")" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format msgid "" "server sent binary data (\"B\" message) without prior row description (\"T\" " @@ -766,31 +862,26 @@ msgstr "" "Ñервер отправил двоичные данные (Ñообщение \"B\") без предварительного " "опиÑÐ°Ð½Ð¸Ñ Ñтроки (Ñообщение \"T\")" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "неожиданный ответ Ñервера; первый полученный Ñимвол: \"%c\"\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "недоÑтаточно памÑти Ð´Ð»Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð° запроÑа" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "потерÑна ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ñервером; попытка воÑÑтановить Ñоединение" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1548 fe-protocol2.c:1580 fe-protocol3.c:2096 #, c-format msgid "protocol error: id=0x%x\n" msgstr "ошибка протокола: id=0x%x\n" -#: fe-protocol3.c:368 +#: fe-protocol3.c:367 msgid "" "server sent data (\"D\" message) without prior row description (\"T\" " "message)\n" @@ -798,180 +889,193 @@ msgstr "" "Ñервер отправил данные (Ñообщение \"D\") без предварительного опиÑÐ°Ð½Ð¸Ñ " "Ñтроки (Ñообщение \"T\")\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "Ñодержимое не ÑоответÑтвует длине в Ñообщении типа \"%c\"\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "" "потерÑна ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ Ñервером: получено Ñообщение типа \"%c\", длина %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "недоÑтаточно данных в Ñообщении \"T\"" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "лишние данные в Ñообщении \"T\"" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "лишние данные в Ñообщении \"t\"" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "недоÑтаточно данных в Ñообщении \"D\"" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "неверное чиÑло полей в Ñообщении \"D\"" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "лишние данные в Ñообщении \"D\"" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "нет ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибке\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1042 fe-protocol3.c:1061 #, c-format msgid " at character %s" msgstr " Ñимвол %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1074 #, c-format msgid "DETAIL: %s\n" msgstr "ПОДРОБÐОСТИ: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1077 #, c-format msgid "HINT: %s\n" msgstr "ПОДСКÐЗКÐ: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1080 #, c-format msgid "QUERY: %s\n" msgstr "ЗÐПРОС: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1087 #, c-format msgid "CONTEXT: %s\n" msgstr "КОÐТЕКСТ: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1096 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "СХЕМÐ: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1100 #, c-format msgid "TABLE NAME: %s\n" msgstr "ТÐБЛИЦÐ: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1104 #, c-format msgid "COLUMN NAME: %s\n" msgstr "СТОЛБЕЦ: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1108 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "ТИП ДÐÐÐЫХ: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1112 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "ОГРÐÐИЧЕÐИЕ: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1124 msgid "LOCATION: " msgstr "ПОЛОЖЕÐИЕ: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1126 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1128 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1323 #, c-format msgid "LINE %d: " msgstr "СТРОКР%d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1718 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline можно вызывать только во Ð²Ñ€ÐµÐ¼Ñ COPY OUT Ñ Ñ‚ÐµÐºÑтом\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1321 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "Ð¸Ð¼Ñ Ð² SSL-Ñертификате включает нулевой байт\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð³Ð¾ SSL-ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð°\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "" +"Ñерверный Ñертификат Ð´Ð»Ñ \"%s\" не ÑоответÑтвует имени Ñервера \"%s\"\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "не удалоÑÑŒ получить Ð¸Ð¼Ñ Ñервера из Ñертификата\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "ошибка SSL SYSCALL: %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1325 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "ошибка SSL SYSCALL: конец файла (EOF)\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1334 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "ошибка SSL: %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL-Ñоединение было неожиданно закрыто\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1343 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "нераÑпознанный код ошибки SSL: %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "запиÑÑŒ имени в SSL-Ñертификате отÑутÑтвует\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "не удалоÑÑŒ определить алгоритм подпиÑи Ñертификата Ñервера\n" -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "Ð¸Ð¼Ñ Ð² SSL-Ñертификате включает нулевой байт\n" - -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐµÐ½Ð½Ð¾Ð³Ð¾ SSL-ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ‚Ñ€ÐµÐ±ÑƒÐµÑ‚ÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ Ð¸Ð¼Ñ ÑƒÐ·Ð»Ð°\n" - -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "" -"Ñерверный Ñертификат Ð´Ð»Ñ \"%s\" не ÑоответÑтвует имени Ñервера \"%s\"\n" +msgid "could not find digest for NID %s\n" +msgstr "не удалоÑÑŒ найти алгоритм Ñ…ÐµÑˆÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ NID %s\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "не удалоÑÑŒ получить Ð¸Ð¼Ñ Ñервера из Ñертификата\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "не удалоÑÑŒ Ñгенерировать хеш Ñертификата Ñервера\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "запиÑÑŒ имени в SSL-Ñертификате отÑутÑтвует\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "не удалоÑÑŒ Ñоздать контекÑÑ‚ SSL: %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "не удалоÑÑŒ прочитать файл корневых Ñертификатов \"%s\": %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" msgstr "Библиотека SSL не поддерживает проверку CRL (файл \"%s\")\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate " @@ -981,7 +1085,7 @@ msgstr "" "Укажите полный путь к файлу или отключите проверку Ñертификата Ñервера, " "изменив sslmode.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -992,47 +1096,47 @@ msgstr "" "Укажите полный путь к файлу или отключите проверку Ñертификата Ñервера, " "изменив sslmode.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "не удалоÑÑŒ открыть файл Ñертификата \"%s\": %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "не удалоÑÑŒ прочитать файл Ñертификата \"%s\": %s\n" -#: fe-secure-openssl.c:1099 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "не удалоÑÑŒ уÑтановить SSL-Ñоединение: %s\n" -#: fe-secure-openssl.c:1153 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "не удалоÑÑŒ загрузить модуль SSL ENGINE \"%s\": %s\n" -#: fe-secure-openssl.c:1165 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "не удалоÑÑŒ инициализировать модуль SSL ENGINE \"%s\": %s\n" -#: fe-secure-openssl.c:1181 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "не удалоÑÑŒ прочитать закрытый ключ SSL \"%s\" из Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\": %s\n" -#: fe-secure-openssl.c:1195 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "не удалоÑÑŒ загрузить закрытый ключ SSL \"%s\" из Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\": %s\n" -#: fe-secure-openssl.c:1232 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "Ñертификат приÑутÑтвует, но файла закрытого ключа \"%s\" нет\n" -#: fe-secure-openssl.c:1240 +#: fe-secure-openssl.c:1128 #, c-format msgid "" "private key file \"%s\" has group or world access; permissions should be " @@ -1041,37 +1145,37 @@ msgstr "" "к файлу закрытого ключа \"%s\" имеют доÑтуп вÑе или группа; права должны " "быть u=rw (0600) или более ограниченные\n" -#: fe-secure-openssl.c:1251 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "не удалоÑÑŒ загрузить файл закрытого ключа \"%s\": %s\n" -#: fe-secure-openssl.c:1265 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "Ñертификат не ÑоответÑтвует файлу закрытого ключа \"%s\": %s\n" -#: fe-secure-openssl.c:1364 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "не удалоÑÑŒ получить Ñертификат: %s\n" -#: fe-secure-openssl.c:1456 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "нет ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ Ð¾Ð± ошибке SSL" -#: fe-secure-openssl.c:1465 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "код ошибки SSL: %lu" -#: fe-secure.c:261 +#: fe-secure.c:269 #, c-format msgid "could not receive data from server: %s\n" msgstr "не удалоÑÑŒ получить данные Ñ Ñервера: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:378 #, c-format msgid "could not send data to server: %s\n" msgstr "не удалоÑÑŒ передать данные Ñерверу: %s\n" @@ -1081,6 +1185,25 @@ msgstr "не удалоÑÑŒ передать данные Ñерверу: %s\n" msgid "unrecognized socket error: 0x%08X/%d" msgstr "нераÑÐ¿Ð¾Ð·Ð½Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñокета: 0x%08X/%d" +#~ msgid "could not get home directory to locate password file\n" +#~ msgstr "не удалоÑÑŒ получить домашний каталог Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файла паролей\n" + +#~ msgid "could not get home directory to locate service definition file" +#~ msgstr "" +#~ "не удалоÑÑŒ получить домашний каталог Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ файла определений Ñлужб" + +#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" +#~ msgstr "ошибка в setsockopt(TCP_KEEPIDLE): %s\n" + +#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" +#~ msgstr "ошибка в setsockopt(TCP_KEEPALIVE): %s\n" + +#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" +#~ msgstr "ошибка в setsockopt(TCP_KEEPINTVL): %s\n" + +#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" +#~ msgstr "ошибка в setsockopt(SO_KEEPALIVE): %s\n" + #~ msgid "could not acquire mutex: %s\n" #~ msgstr "не удалоÑÑŒ заблокировать Ñемафор: %s\n" diff --git a/src/interfaces/libpq/po/sv.po b/src/interfaces/libpq/po/sv.po index 0c76f0f546f..23818be3107 100644 --- a/src/interfaces/libpq/po/sv.po +++ b/src/interfaces/libpq/po/sv.po @@ -1,15 +1,15 @@ # Swedish message translation file for libpq # Peter Eisentraut , 2001, 2010. -# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017. +# Dennis Björklund , 2002, 2003, 2004, 2005, 2006, 2017, 2018, 2019. # # Use these quotes: "%s" # msgid "" msgstr "" "Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-05 02:08+0000\n" -"PO-Revision-Date: 2017-08-05 07:54+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 07:08+0000\n" +"PO-Revision-Date: 2019-04-29 13:26+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,223 +17,228 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: fe-auth-scram.c:176 +#: fe-auth-scram.c:183 msgid "malformed SCRAM message (empty message)\n" msgstr "felaktigt SCRAM-meddelande (tomt meddelande)\n" -#: fe-auth-scram.c:182 +#: fe-auth-scram.c:189 msgid "malformed SCRAM message (length mismatch)\n" msgstr "felaktigt SCRAM-meddelande (längden stämmer inte)\n" -#: fe-auth-scram.c:231 -msgid "invalid server signature\n" -msgstr "ogiltig serversignatur\n" +#: fe-auth-scram.c:238 +msgid "incorrect server signature\n" +msgstr "felaktig serversignatur\n" -#: fe-auth-scram.c:240 +#: fe-auth-scram.c:247 msgid "invalid SCRAM exchange state\n" msgstr "ogiltig SCRAM-utbytesstatus\n" -#: fe-auth-scram.c:263 +#: fe-auth-scram.c:270 #, c-format -msgid "malformed SCRAM message (%c expected)\n" -msgstr "felaktigt SCRAM-meddelande (förväntade %c)\n" +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "felaktigt SCRAM-meddelande (förväntade attribut %c)\n" -#: fe-auth-scram.c:272 +#: fe-auth-scram.c:279 #, c-format -msgid "malformed SCRAM message (expected = in attr '%c')\n" -msgstr "felaktigt SCRAM-meddelande (förväntade = i attr '%c')\n" +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "felaktigt SCRAM-meddelande (förväntade tecken \"=\" för attribut '%c')\n" -#: fe-auth-scram.c:311 +#: fe-auth-scram.c:320 msgid "could not generate nonce\n" msgstr "kunde inte skapa engÃ¥ngsnummer\n" -#: fe-auth-scram.c:319 fe-auth-scram.c:336 fe-auth-scram.c:346 -#: fe-auth-scram.c:400 fe-auth-scram.c:420 fe-auth-scram.c:445 -#: fe-auth-scram.c:459 fe-auth-scram.c:501 fe-auth.c:227 fe-auth.c:362 -#: fe-auth.c:432 fe-auth.c:467 fe-auth.c:609 fe-auth.c:768 fe-auth.c:1080 -#: fe-auth.c:1228 fe-connect.c:775 fe-connect.c:1203 fe-connect.c:1379 -#: fe-connect.c:1947 fe-connect.c:2476 fe-connect.c:4062 fe-connect.c:4314 -#: fe-connect.c:4433 fe-connect.c:4673 fe-connect.c:4753 fe-connect.c:4852 -#: fe-connect.c:5108 fe-connect.c:5137 fe-connect.c:5209 fe-connect.c:5233 -#: fe-connect.c:5251 fe-connect.c:5352 fe-connect.c:5361 fe-connect.c:5717 -#: fe-connect.c:5867 fe-exec.c:2651 fe-exec.c:3398 fe-exec.c:3563 -#: fe-lobj.c:896 fe-protocol2.c:1206 fe-protocol3.c:992 fe-protocol3.c:1678 -#: fe-secure-openssl.c:514 fe-secure-openssl.c:1138 +#: fe-auth-scram.c:328 fe-auth-scram.c:395 fe-auth-scram.c:517 +#: fe-auth-scram.c:537 fe-auth-scram.c:563 fe-auth-scram.c:577 +#: fe-auth-scram.c:619 fe-auth.c:290 fe-auth.c:360 fe-auth.c:395 fe-auth.c:581 +#: fe-auth.c:740 fe-auth.c:1052 fe-auth.c:1200 fe-connect.c:858 +#: fe-connect.c:1320 fe-connect.c:1496 fe-connect.c:2085 fe-connect.c:2108 +#: fe-connect.c:2830 fe-connect.c:4512 fe-connect.c:4764 fe-connect.c:4883 +#: fe-connect.c:5133 fe-connect.c:5213 fe-connect.c:5312 fe-connect.c:5568 +#: fe-connect.c:5597 fe-connect.c:5669 fe-connect.c:5693 fe-connect.c:5711 +#: fe-connect.c:5812 fe-connect.c:5821 fe-connect.c:6177 fe-connect.c:6327 +#: fe-exec.c:2748 fe-exec.c:3495 fe-exec.c:3660 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1703 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 msgid "out of memory\n" msgstr "slut pÃ¥ minne\n" -#: fe-auth-scram.c:437 +#: fe-auth-scram.c:555 msgid "invalid SCRAM response (nonce mismatch)\n" msgstr "ogiltigt SCRAM-svar (engÃ¥ngsnummer matchar inte)\n" -#: fe-auth-scram.c:476 +#: fe-auth-scram.c:594 msgid "malformed SCRAM message (invalid iteration count)\n" msgstr "felaktigt SCRAM meddelande (ogiltig iterationsräknare)\n" -#: fe-auth-scram.c:482 +#: fe-auth-scram.c:600 msgid "malformed SCRAM message (garbage at end of server-first-message)\n" msgstr "felaktigt SCRAM-meddelande (skräp i slutet pÃ¥ server-first-message)\n" -#: fe-auth-scram.c:511 +#: fe-auth-scram.c:630 #, c-format -msgid "error received from server in SASL exchange: %s\n" -msgstr "fel mottaget frÃ¥n server i SASL-utbyte: %s\n" +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "fel mottaget frÃ¥n server i SCRAM-utbyte: %s\n" -#: fe-auth-scram.c:526 +#: fe-auth-scram.c:646 msgid "malformed SCRAM message (garbage at end of server-final-message)\n" msgstr "felaktigt SCRAM-meddelande (skräp i slutet av server-final-message)\n" -#: fe-auth-scram.c:534 +#: fe-auth-scram.c:654 msgid "malformed SCRAM message (invalid server signature)\n" msgstr "felaktigt SCRAM-meddelande (ogiltigt serversignatur)\n" -#: fe-auth.c:122 +#: fe-auth.c:77 #, c-format msgid "out of memory allocating GSSAPI buffer (%d)\n" msgstr "slut pÃ¥ minne vid allokering av buffer till GSSAPI (%d)\n" -#: fe-auth.c:177 +#: fe-auth.c:132 msgid "GSSAPI continuation error" msgstr "GSSAPI fortsättningsfel" -#: fe-auth.c:207 fe-auth.c:461 +#: fe-auth.c:159 fe-auth.c:389 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "värdnamn mÃ¥ste anges\n" -#: fe-auth.c:214 +#: fe-auth.c:166 msgid "duplicate GSS authentication request\n" msgstr "duplicerad autentiseringsbegäran frÃ¥n GSS\n" -#: fe-auth.c:240 -msgid "GSSAPI name import error" -msgstr "GSSAPI-fel vid import av namn" - -#: fe-auth.c:303 +#: fe-auth.c:231 #, c-format msgid "out of memory allocating SSPI buffer (%d)\n" msgstr "slut pÃ¥ minne vid allokering av buffer till GSSAPI (%d)\n" -#: fe-auth.c:351 +#: fe-auth.c:279 msgid "SSPI continuation error" msgstr "SSPI fortsättningsfel" -#: fe-auth.c:422 +#: fe-auth.c:350 msgid "duplicate SSPI authentication request\n" msgstr "duplicerad autentiseringsbegäran frÃ¥n SSPI\n" -#: fe-auth.c:447 +#: fe-auth.c:375 msgid "could not acquire SSPI credentials" msgstr "kunde inte hämta SSPI-referenser" -#: fe-auth.c:500 +#: fe-auth.c:429 msgid "duplicate SASL authentication request\n" msgstr "duplicerad autentiseringsbegäran frÃ¥n SASL\n" -#: fe-auth.c:560 +#: fe-auth.c:487 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "servern erbjöd SCRAM-SHA-256-PLUS-autentisering över en icke-SSL-anslutning\n" + +#: fe-auth.c:499 msgid "none of the server's SASL authentication mechanisms are supported\n" msgstr "ingen av serverns SASL-autentiseringsmekanismer stöds\n" -#: fe-auth.c:633 +#: fe-auth.c:605 #, c-format msgid "out of memory allocating SASL buffer (%d)\n" msgstr "slut pÃ¥ minne vid allokering av buffer till SASL (%d)\n" -#: fe-auth.c:658 +#: fe-auth.c:630 msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" msgstr "mottog AuthenticationSASLFinal frÃ¥n server, men SASL-autentisering slutfördes ej\n" -#: fe-auth.c:735 +#: fe-auth.c:707 msgid "SCM_CRED authentication method not supported\n" msgstr "autentiseringsmetoden SCM_CRED stöds ej\n" -#: fe-auth.c:826 +#: fe-auth.c:798 msgid "Kerberos 4 authentication not supported\n" msgstr "Kerberos-4-autentisering stöds ej\n" -#: fe-auth.c:831 +#: fe-auth.c:803 msgid "Kerberos 5 authentication not supported\n" msgstr "Kerberos-5-autentisering stöds ej\n" -#: fe-auth.c:902 +#: fe-auth.c:874 msgid "GSSAPI authentication not supported\n" msgstr "GSSAPI-autentisering stöds ej\n" -#: fe-auth.c:934 +#: fe-auth.c:906 msgid "SSPI authentication not supported\n" msgstr "SSPI-autentisering stöds ej\n" -#: fe-auth.c:942 +#: fe-auth.c:914 msgid "Crypt authentication not supported\n" msgstr "Crypt-autentisering stöds ej\n" -#: fe-auth.c:1008 +#: fe-auth.c:980 #, c-format msgid "authentication method %u not supported\n" msgstr "autentiseringsmetod %u stöds ej\n" -#: fe-auth.c:1055 +#: fe-auth.c:1027 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "misslyckad sökning efter användarnamn: felkod %lu\n" -#: fe-auth.c:1065 fe-connect.c:2403 +#: fe-auth.c:1037 fe-connect.c:2717 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "kunde inte slÃ¥ upp lokalt användar-id %d: %s\n" -#: fe-auth.c:1070 fe-connect.c:2408 +#: fe-auth.c:1042 fe-connect.c:2722 #, c-format msgid "local user with ID %d does not exist\n" msgstr "lokal användare med ID %d existerar inte\n" -#: fe-auth.c:1172 +#: fe-auth.c:1144 msgid "unexpected shape of result set returned for SHOW\n" msgstr "oväntad form pÃ¥ resultatmängden som returnerades för SHOW\n" -#: fe-auth.c:1181 +#: fe-auth.c:1153 msgid "password_encryption value too long\n" msgstr "password_encryption-värdet är för lÃ¥ngt\n" -#: fe-auth.c:1221 +#: fe-auth.c:1193 #, c-format msgid "unrecognized password encryption algorithm \"%s\"\n" msgstr "okänd lösenordskrypteringsalgoritm \"%s\"\n" -#: fe-connect.c:968 +#: fe-connect.c:1041 #, c-format -msgid "could not match %d host names to %d hostaddrs\n" +msgid "could not match %d host names to %d hostaddr values\n" msgstr "kunde inte matcha %d värdnamn till %d värdadresser\n" -#: fe-connect.c:1025 +#: fe-connect.c:1117 #, c-format msgid "could not match %d port numbers to %d hosts\n" msgstr "kunde inte matcha %d portnummer med %d värdar\n" -#: fe-connect.c:1077 -msgid "could not get home directory to locate password file\n" -msgstr "kunde inte hämta hemkatalogen för att lokalisera lösenordsfilen\n" - -#: fe-connect.c:1129 +#: fe-connect.c:1213 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "ogiltigt värde för ssl-läge: \"%s\"\n" -#: fe-connect.c:1150 +#: fe-connect.c:1234 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "värde för ssl-läge, \"%s\", är ogiltigt när SSL-stöd inte kompilerats in\n" -#: fe-connect.c:1185 +#: fe-connect.c:1258 +#, c-format +msgid "invalid gssencmode value: \"%s\"\n" +msgstr "ogiltigt värde för gssencmode: \"%s\"\n" + +#: fe-connect.c:1268 +msgid "no GSSAPI support; cannot require GSSAPI\n" +msgstr "inget stöd för GSSAPI; kan inte kräva GSSAPI\n" + +#: fe-connect.c:1302 #, c-format msgid "invalid target_session_attrs value: \"%s\"\n" msgstr "ogiltigt target_session_attrs-värde: \"%s\"\n" -#: fe-connect.c:1403 +#: fe-connect.c:1520 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "kunde inte sätta uttag (socket) till läget TCP-ingen-fördröjning: %s\n" -#: fe-connect.c:1433 +#: fe-connect.c:1583 #, c-format msgid "" "could not connect to server: %s\n" @@ -244,7 +249,7 @@ msgstr "" "\tKör servern pÃ¥ lokalt och accepterar den\n" "\tanslutningar pÃ¥ Unix-uttaget \"%s\"?\n" -#: fe-connect.c:1491 +#: fe-connect.c:1620 #, c-format msgid "" "could not connect to server: %s\n" @@ -255,7 +260,7 @@ msgstr "" "\tKör servern pÃ¥ värden \"%s\" (%s) och accepterar\n" "\tden TCP/IP-uppkopplingar pÃ¥ port %s?\n" -#: fe-connect.c:1500 +#: fe-connect.c:1628 #, c-format msgid "" "could not connect to server: %s\n" @@ -266,492 +271,535 @@ msgstr "" "\tKör servern pÃ¥ värden \"%s\" och accepterar\n" "\tden TCP/IP-uppkopplingar pÃ¥ porten %s?\n" -#: fe-connect.c:1551 fe-connect.c:1583 fe-connect.c:1616 fe-connect.c:2175 +#: fe-connect.c:1679 +#, c-format +msgid "invalid integer value \"%s\" for keyword \"%s\"\n" +msgstr "ogiltigt heltalsvärde \"%s\" för nyckelord \"%s\"\n" + +#: fe-connect.c:1709 fe-connect.c:1743 fe-connect.c:1778 fe-connect.c:1865 +#: fe-connect.c:2507 #, c-format msgid "setsockopt(%s) failed: %s\n" msgstr "setsockopt(%s) misslyckades: %s\n" -#: fe-connect.c:1665 +#: fe-connect.c:1831 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) misslyckades: %ui\n" -#: fe-connect.c:1722 +#: fe-connect.c:2199 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "ogiltigt förbindelsetillstÃ¥nd, antagligen korrupt minne\n" + +#: fe-connect.c:2267 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "ogiltigt portnummer \"%s\"\n" -#: fe-connect.c:1738 +#: fe-connect.c:2283 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "kunde inte översätta värdnamn \"%s\" till adress: %s\n" -#: fe-connect.c:1747 +#: fe-connect.c:2296 #, c-format msgid "could not parse network address \"%s\": %s\n" msgstr "kunde inte parsa nätverksadress \"%s\": %s\n" -#: fe-connect.c:1758 +#: fe-connect.c:2309 #, c-format msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" msgstr "Sökväg till unixdomänuttag \"%s\" är för lÃ¥ng (maximalt %d byte)\n" -#: fe-connect.c:1772 +#: fe-connect.c:2324 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "kunde inte översätta sökväg till unix-uttag (socket) \"%s\" till adress: %s\n" -#: fe-connect.c:2053 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "ogiltigt förbindelsetillstÃ¥nd, antagligen korrupt minne\n" - -#: fe-connect.c:2110 +#: fe-connect.c:2444 #, c-format msgid "could not create socket: %s\n" msgstr "kan inte skapa uttag: %s\n" -#: fe-connect.c:2132 +#: fe-connect.c:2466 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "kunde inte sätta uttag (socket) till ickeblockerande läge: %s\n" -#: fe-connect.c:2143 +#: fe-connect.c:2476 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "kunde inte ställa in uttag (socket) i \"close-on-exec\"-läge: %s\n" -#: fe-connect.c:2162 +#: fe-connect.c:2494 msgid "keepalives parameter must be an integer\n" msgstr "keepalives-parameter mÃ¥ste vara ett heltal\n" -#: fe-connect.c:2313 +#: fe-connect.c:2634 #, c-format msgid "could not get socket error status: %s\n" msgstr "kunde inte hämta felstatus för uttag (socket): %s\n" -#: fe-connect.c:2348 +#: fe-connect.c:2662 #, c-format msgid "could not get client address from socket: %s\n" msgstr "kunde inte fÃ¥ tag pÃ¥ klientadressen frÃ¥n uttag (socket): %s\n" -#: fe-connect.c:2390 +#: fe-connect.c:2704 msgid "requirepeer parameter is not supported on this platform\n" msgstr "requirepeer-parameter stöds inte pÃ¥ denna plattform\n" -#: fe-connect.c:2393 +#: fe-connect.c:2707 #, c-format msgid "could not get peer credentials: %s\n" msgstr "kunde inte hämta andra sidans referenser: %s\n" -#: fe-connect.c:2416 +#: fe-connect.c:2730 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "requirepeer anger \"%s\", men andra sidans användarnamn är \"%s\"\n" -#: fe-connect.c:2450 +#: fe-connect.c:2765 +#, c-format +msgid "could not send GSSAPI negotiation packet: %s\n" +msgstr "kunde inte skicka GSSAPI-paket för uppkopplingsförhandling: %s\n" + +#: fe-connect.c:2777 +msgid "GSSAPI encryption required, but was impossible (possibly no ccache, no server support, or using a local socket)\n" +msgstr "GSSAPI-kryptering krävdes men var omöjligt (kanske ingen ccache, inget serverstöd eller använder ett lokalt uttag)\n" + +#: fe-connect.c:2804 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "kunde inte skicka SSL-paket för uppkopplingsförhandling: %s\n" -#: fe-connect.c:2489 +#: fe-connect.c:2843 #, c-format msgid "could not send startup packet: %s\n" msgstr "kan inte skicka startpaketet: %s\n" -#: fe-connect.c:2559 +#: fe-connect.c:2913 msgid "server does not support SSL, but SSL was required\n" msgstr "SSL stöds inte av servern, men SSL krävdes\n" -#: fe-connect.c:2585 +#: fe-connect.c:2939 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "tog emot ogiltigt svar till SSL-uppkopplingsförhandling: %c\n" -#: fe-connect.c:2661 fe-connect.c:2694 +#: fe-connect.c:3029 +msgid "server doesn't support GSSAPI encryption, but it was required\n" +msgstr "GSSAPI stöds inte av servern, men det krävdes\n" + +#: fe-connect.c:3040 +#, c-format +msgid "received invalid response to GSSAPI negotiation: %c\n" +msgstr "tog emot ogiltigt svar till GSSAPI-uppkopplingsförhandling: %c\n" + +#: fe-connect.c:3108 fe-connect.c:3141 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "förväntade autentiseringsförfrÃ¥gan frÃ¥n servern, men fick %c\n" -#: fe-connect.c:2923 +#: fe-connect.c:3388 msgid "unexpected message from server during startup\n" msgstr "oväntat meddelande frÃ¥n servern under starten\n" -#: fe-connect.c:3141 +#: fe-connect.c:3615 #, c-format msgid "could not make a writable connection to server \"%s:%s\"\n" msgstr "kunde inte upprätta en skrivbar anslutning till server \"%s:%s\"\n" -#: fe-connect.c:3190 +#: fe-connect.c:3661 #, c-format msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" msgstr "test \"SHOW transaction_read_only\" misslyckades pÃ¥ server \"%s:%s\"\n" -#: fe-connect.c:3211 +#: fe-connect.c:3676 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "ogiltigt förbindelsetillstÃ¥nd %d, antagligen korrupt minne\n" -#: fe-connect.c:3668 fe-connect.c:3728 +#: fe-connect.c:4118 fe-connect.c:4178 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc \"%s\" misslyckades under PGEVT_CONNRESET-händelse\n" -#: fe-connect.c:4075 +#: fe-connect.c:4525 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "ogiltig LDAP URL \"%s\": schemat mÃ¥ste vara ldap://\n" -#: fe-connect.c:4090 +#: fe-connect.c:4540 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "ogiltig LDAP URL \"%s\": saknar urskiljbart namn\n" -#: fe-connect.c:4101 fe-connect.c:4154 +#: fe-connect.c:4551 fe-connect.c:4604 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "ogiltig LDAP URL \"%s\": mÃ¥ste finnas exakt ett attribut\n" -#: fe-connect.c:4111 fe-connect.c:4168 +#: fe-connect.c:4561 fe-connect.c:4618 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "ogiltig LDAP URL \"%s\": mÃ¥ste ha sök-scope (base/one/sub)\n" -#: fe-connect.c:4122 +#: fe-connect.c:4572 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "ogiltigt LDAP URL \"%s\": inget filter\n" -#: fe-connect.c:4143 +#: fe-connect.c:4593 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "ogiltig LDAP URL \"%s\": ogiltigt portnummer\n" -#: fe-connect.c:4177 +#: fe-connect.c:4627 msgid "could not create LDAP structure\n" msgstr "kunde inte skapa LDAP-struktur\n" -#: fe-connect.c:4253 +#: fe-connect.c:4703 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "uppslagning av LDAP-server misslyckades: %s\n" -#: fe-connect.c:4264 +#: fe-connect.c:4714 msgid "more than one entry found on LDAP lookup\n" msgstr "mer än en post hittad i LDAP-uppslagning\n" -#: fe-connect.c:4265 fe-connect.c:4277 +#: fe-connect.c:4715 fe-connect.c:4727 msgid "no entry found on LDAP lookup\n" msgstr "ingen post hittad i LDAP-uppslagning\n" -#: fe-connect.c:4288 fe-connect.c:4301 +#: fe-connect.c:4738 fe-connect.c:4751 msgid "attribute has no values on LDAP lookup\n" msgstr "attributet har inga värden i LDAP-uppslagning\n" -#: fe-connect.c:4353 fe-connect.c:4372 fe-connect.c:4891 +#: fe-connect.c:4803 fe-connect.c:4822 fe-connect.c:5351 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "\"=\" efter \"%s\" saknas i förbindelseinfosträng\n" -#: fe-connect.c:4445 fe-connect.c:5076 fe-connect.c:5850 +#: fe-connect.c:4895 fe-connect.c:5536 fe-connect.c:6310 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "ogiltig förbindelseparameter \"%s\"\n" -#: fe-connect.c:4461 fe-connect.c:4940 +#: fe-connect.c:4911 fe-connect.c:5400 msgid "unterminated quoted string in connection info string\n" msgstr "icke terminerad sträng i uppkopplingsinformationen\n" -#: fe-connect.c:4501 -msgid "could not get home directory to locate service definition file" -msgstr "kunde inte hämta hemkatalogen för att lokalisera servicedefinitionsfilen" - -#: fe-connect.c:4534 +#: fe-connect.c:4994 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "definition av service \"%s\" hittades inte\n" -#: fe-connect.c:4557 +#: fe-connect.c:5017 #, c-format msgid "service file \"%s\" not found\n" msgstr "servicefil \"%s\" hittades inte\n" -#: fe-connect.c:4570 +#: fe-connect.c:5030 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "rad %d för lÃ¥ng i servicefil \"%s\"\n" -#: fe-connect.c:4641 fe-connect.c:4685 +#: fe-connect.c:5101 fe-connect.c:5145 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "syntaxfel i servicefel \"%s\", rad %d\n" -#: fe-connect.c:4652 +#: fe-connect.c:5112 #, c-format msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "nästlade servicespecifikationer stöds inte i servicefil \"%s\", rad %d\n" -#: fe-connect.c:5372 +#: fe-connect.c:5832 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "ogiltig URI propagerad till intern parsningsrutin: \"%s\"\n" -#: fe-connect.c:5449 +#: fe-connect.c:5909 #, c-format msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "nÃ¥dde slutet pÃ¥ strängen när vi letade efter matchande \"]\" i IPv6-värdadress i URI: \"%s\"\n" -#: fe-connect.c:5456 +#: fe-connect.c:5916 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "IPv6-värdadress fÃ¥r ej vara tom i URI: \"%s\"\n" -#: fe-connect.c:5471 +#: fe-connect.c:5931 #, c-format msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" msgstr "oväntat tecken \"%c\" vid position %d i URI (förväntade \":\" eller \"/\"): \"%s\"\n" -#: fe-connect.c:5600 +#: fe-connect.c:6060 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "extra nyckel/värde-separator \"=\" i URI-frÃ¥geparameter: \"%s\"\n" -#: fe-connect.c:5620 +#: fe-connect.c:6080 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "saknar nyckel/värde-separator \"=\" i URI-frÃ¥geparameter: \"%s\"\n" -#: fe-connect.c:5671 +#: fe-connect.c:6131 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "ogiltig URI-frÃ¥geparameter: \"%s\"\n" -#: fe-connect.c:5745 +#: fe-connect.c:6205 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "ogiltigt procent-kodad symbol: \"%s\"\n" -#: fe-connect.c:5755 +#: fe-connect.c:6215 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "förbjudet värde %%00 i procentkodat värde: \"%s\"\n" -#: fe-connect.c:6100 +#: fe-connect.c:6580 msgid "connection pointer is NULL\n" msgstr "anslutningspekare är NULL\n" -#: fe-connect.c:6398 +#: fe-connect.c:6878 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "FEL: lösenordsfil \"%s\" är inte en vanlig fil\n" -#: fe-connect.c:6407 +#: fe-connect.c:6887 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "VARNING: lösenordsfilen \"%s\" har läsrättigheter för gruppen eller världen; rättigheten skall vara u=rw (0600) eller mindre\n" -#: fe-connect.c:6499 +#: fe-connect.c:6981 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "lösenord hämtat frÃ¥n fil \"%s\"\n" -#: fe-exec.c:826 +#: fe-exec.c:445 fe-exec.c:2822 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "radnummer %d är utanför giltigt intervall 0..%d" + +#: fe-exec.c:506 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "slut pÃ¥ minne" + +#: fe-exec.c:507 fe-protocol2.c:1402 fe-protocol3.c:1911 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:816 +msgid "write to server failed\n" +msgstr "skrivning till servern misslyckades\n" + +#: fe-exec.c:897 msgid "NOTICE" msgstr "NOTIS" -#: fe-exec.c:1141 fe-exec.c:1199 fe-exec.c:1245 +#: fe-exec.c:955 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult stöder inte mer än INT_MAX tupler" + +#: fe-exec.c:967 +msgid "size_t overflow" +msgstr "size_t-överspill" + +#: fe-exec.c:1244 fe-exec.c:1302 fe-exec.c:1348 msgid "command string is a null pointer\n" msgstr "kommandosträngen är en null-pekare\n" -#: fe-exec.c:1205 fe-exec.c:1251 fe-exec.c:1346 +#: fe-exec.c:1308 fe-exec.c:1354 fe-exec.c:1449 msgid "number of parameters must be between 0 and 65535\n" msgstr "antal parametrar mÃ¥ste bara mellan 0 och 65535\n" -#: fe-exec.c:1239 fe-exec.c:1340 +#: fe-exec.c:1342 fe-exec.c:1443 msgid "statement name is a null pointer\n" msgstr "satsens namn är en null-pekare\n" -#: fe-exec.c:1259 fe-exec.c:1422 fe-exec.c:2140 fe-exec.c:2339 +#: fe-exec.c:1362 fe-exec.c:1525 fe-exec.c:2234 fe-exec.c:2436 msgid "function requires at least protocol version 3.0\n" msgstr "funktionen kräver minst protokollversion 3.0\n" -#: fe-exec.c:1377 +#: fe-exec.c:1480 msgid "no connection to the server\n" msgstr "inte förbunden till servern\n" -#: fe-exec.c:1384 +#: fe-exec.c:1487 msgid "another command is already in progress\n" msgstr "ett annat kommando pÃ¥gÃ¥r redan\n" -#: fe-exec.c:1498 +#: fe-exec.c:1601 msgid "length must be given for binary parameter\n" msgstr "längden mÃ¥ste anges för en binär parameter\n" -#: fe-exec.c:1770 +#: fe-exec.c:1864 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "oväntad asyncStatus: %d\n" -#: fe-exec.c:1790 +#: fe-exec.c:1884 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc \"%s\" misslyckades under PGEVT_RESULTCREATE-händelse\n" -#: fe-exec.c:1950 +#: fe-exec.c:2044 msgid "COPY terminated by new PQexec" msgstr "COPY terminerad av ny PQexec" -#: fe-exec.c:1958 +#: fe-exec.c:2052 msgid "COPY IN state must be terminated first\n" msgstr "COPY IN-läge mÃ¥ste avslutas först\n" -#: fe-exec.c:1978 +#: fe-exec.c:2072 msgid "COPY OUT state must be terminated first\n" msgstr "COPY OUT-läge mÃ¥ste avslutas först\n" -#: fe-exec.c:1986 +#: fe-exec.c:2080 msgid "PQexec not allowed during COPY BOTH\n" msgstr "PQexec tillÃ¥ts inte under COPY BOTH\n" -#: fe-exec.c:2229 fe-exec.c:2296 fe-exec.c:2386 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2326 fe-exec.c:2393 fe-exec.c:2483 fe-protocol2.c:1359 +#: fe-protocol3.c:1842 msgid "no COPY in progress\n" msgstr "ingen COPY pÃ¥gÃ¥r\n" -#: fe-exec.c:2576 +#: fe-exec.c:2673 msgid "connection in wrong state\n" msgstr "förbindelse i felaktigt tillstÃ¥nd\n" -#: fe-exec.c:2607 +#: fe-exec.c:2704 msgid "invalid ExecStatusType code" msgstr "ogiltig ExecStatusType-kod" -#: fe-exec.c:2634 +#: fe-exec.c:2731 msgid "PGresult is not an error result\n" msgstr "PGresult är inte ett felresultat\n" -#: fe-exec.c:2709 fe-exec.c:2732 +#: fe-exec.c:2806 fe-exec.c:2829 #, c-format msgid "column number %d is out of range 0..%d" msgstr "kolumnnummer %d är utanför giltigt intervall 0..%d" -#: fe-exec.c:2725 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "radnummer %d är utanför giltigt intervall 0..%d" - -#: fe-exec.c:2747 +#: fe-exec.c:2844 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "parameter nummer %d är utanför giltigt intervall 0..%d" -#: fe-exec.c:3057 +#: fe-exec.c:3154 #, c-format msgid "could not interpret result from server: %s" msgstr "kunde inte tolka svaret frÃ¥n servern: %s" -#: fe-exec.c:3296 fe-exec.c:3380 +#: fe-exec.c:3393 fe-exec.c:3477 msgid "incomplete multibyte character\n" msgstr "ofullständigt multibyte-tecken\n" -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_truncate\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "argumentet till lo_truncate överskrider heltalsintervallet\n" -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_truncate64\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "ett argument till lo_read överskriver heltalsintervallet\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "ett argument till lo_write överskriver heltalsintervallet\n" -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_lseek64\n" -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_create\n" -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_tell64\n" -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "kan inte öppna fil \"%s\": %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "kunde inte läsa frÃ¥n fil \"%s\": %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "kan inte skriva till fil \"%s\": %s\n" -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "frÃ¥ga för att initiera stort objekt-funktion returnerade ingen data\n" -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_open\n" -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_close\n" -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_create\n" -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_unlink\n" -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_lseek\n" -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lo_tell\n" -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen loread\n" -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "kan inte ta reda pÃ¥ OID för funktionen lowrite\n" -#: fe-misc.c:292 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "heltal med storlek %lu stöds inte av pqGetInt" -#: fe-misc.c:328 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "heltal med storlek %lu stöds inte av pqPutInt" -#: fe-misc.c:639 fe-misc.c:840 +#: fe-misc.c:637 fe-misc.c:859 msgid "connection not open\n" msgstr "förbindelse inte öppen\n" -#: fe-misc.c:809 fe-secure-openssl.c:229 fe-secure-openssl.c:338 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:268 fe-secure.c:385 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -761,255 +809,257 @@ msgstr "" "\tTroligen sÃ¥ terminerade servern pga nÃ¥got fel antingen\n" "\tinnan eller under tiden den bearbetade en förfrÃ¥gan.\n" -#: fe-misc.c:1011 +#: fe-misc.c:1046 msgid "timeout expired\n" msgstr "timeout utgÃ¥ngen\n" -#: fe-misc.c:1056 +#: fe-misc.c:1091 msgid "invalid socket\n" msgstr "ogiltigt uttag\n" -#: fe-misc.c:1079 +#: fe-misc.c:1114 #, c-format msgid "select() failed: %s\n" msgstr "select() misslyckades: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "ogiltigt setenv-tillstÃ¥nd %c, indikerar troligen ett minnesfel\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "ogiltigt tillstÃ¥nd %c, indikerar troligen ett minnesfel\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "meddelandetyp 0x%02x kom frÃ¥n server under viloperiod" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 -#: fe-protocol3.c:209 fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 -#: fe-protocol3.c:728 fe-protocol3.c:951 -msgid "out of memory" -msgstr "slut pÃ¥ minne" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "oväntat tecken %c följer pÃ¥ ett tomt frÃ¥gesvar (meddelande \"I\")" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" msgstr "servern skickade data (meddelande \"D\") utan föregÃ¥ende radbeskrivning (meddelande \"T\")" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" msgstr "servern skickade binärdata (meddelande \"B\") utan föregÃ¥ende radbeskrivning (meddelande \"T\")" -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "oväntat svar för servern; första mottagna tecknet var \"%c\"\n" -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "slut pÃ¥ minnet för frÃ¥geresultat" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "tappade synkronisering med servern, startar o, uppkopplingen" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1536 fe-protocol2.c:1568 fe-protocol3.c:2099 #, c-format msgid "protocol error: id=0x%x\n" msgstr "protokollfel: id=0x%x\n" -#: fe-protocol3.c:368 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" msgstr "servern skickade data (meddelande \"D\") utan att först skicka en radbeskrivning (meddelande \"T\")\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "meddelandeinnehÃ¥ll stämmer inte med längden för meddelandetyp \"%c\"\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "tappade synkronisering med servern: fick meddelandetyp \"%c\", längd %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "otillräckligt med data i \"T\"-meddelande" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "extra data i \"T\"-meddelande" -#: fe-protocol3.c:691 +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "extra data i \"t\"-meddelande" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "otillräckligt med data i \"D\"-meddelande" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "oväntat fältantal i \"D\"-meddelande" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "extra data i \"D\"-meddelande" -#: fe-protocol3.c:1005 +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "inget felmeddelande finns tillgängligt\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1060 fe-protocol3.c:1079 #, c-format msgid " at character %s" msgstr " vid tecken %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1092 #, c-format msgid "DETAIL: %s\n" msgstr "DETALJ: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1095 #, c-format msgid "HINT: %s\n" msgstr "TIPS: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1098 #, c-format msgid "QUERY: %s\n" msgstr "FRÃ…GA: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1105 #, c-format msgid "CONTEXT: %s\n" msgstr "KONTEXT: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1114 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "SCHEMANAMN: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1118 #, c-format msgid "TABLE NAME: %s\n" msgstr "TABELLNAMN: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1122 #, c-format msgid "COLUMN NAME: %s\n" msgstr "KOLUMNNAMN: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1126 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "DATATYPNAMN: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1130 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "VILLKORSNAMN: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1142 msgid "LOCATION: " msgstr "PLATS: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1144 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1146 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1341 #, c-format msgid "LINE %d: " msgstr "RAD %d: " -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1736 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: utför inte text-COPY OUT\n" -#: fe-secure-openssl.c:234 fe-secure-openssl.c:343 fe-secure-openssl.c:1323 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "SSL-certifikatets namn innehÃ¥ller null-värden\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "värdnamn mÃ¥ste anges för en verifierad SSL-anslutning\n" + +#: fe-secure-common.c:196 +#, c-format +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "servercertifikat för \"%s\" matchar inte värdnamn \"%s\"\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "kan inte hämta ut serverns värdnamn frÃ¥n servercertifikatet\n" + +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALL fel: %s\n" -#: fe-secure-openssl.c:241 fe-secure-openssl.c:350 fe-secure-openssl.c:1327 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALL-fel: EOF upptäckt\n" -#: fe-secure-openssl.c:252 fe-secure-openssl.c:361 fe-secure-openssl.c:1336 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSL-fel: %s\n" -#: fe-secure-openssl.c:267 fe-secure-openssl.c:376 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL-anslutning har oväntat stängts\n" -#: fe-secure-openssl.c:273 fe-secure-openssl.c:382 fe-secure-openssl.c:1345 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "okänd SSL-felkod: %d\n" -#: fe-secure-openssl.c:494 -msgid "SSL certificate's name entry is missing\n" -msgstr "SSL-certifikatets namn saknas\n" - -#: fe-secure-openssl.c:528 -msgid "SSL certificate's name contains embedded null\n" -msgstr "SSL-certifikatets namn innehÃ¥ller null-värden\n" - -#: fe-secure-openssl.c:580 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "värdnamn mÃ¥ste anges för en verifierad SSL-anslutning\n" +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "kunde inte lista ut serverns algoritm för certifikatsignering\n" -#: fe-secure-openssl.c:680 +#: fe-secure-openssl.c:419 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "servercertifikat för \"%s\" matchar inte värdnamn \"%s\"\n" +msgid "could not find digest for NID %s\n" +msgstr "kunde inte hitta kontrollsumma för NID %s\n" -#: fe-secure-openssl.c:686 -msgid "could not get server's host name from server certificate\n" -msgstr "kan inte hämta ut serverns värdnamn frÃ¥n servercertifikatet\n" +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "kunde inte generera peer-certifikathash\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "SSL-certifikatets namn saknas\n" -#: fe-secure-openssl.c:928 +#: fe-secure-openssl.c:815 #, c-format msgid "could not create SSL context: %s\n" msgstr "kan inte skapa SSL-omgivning: %s\n" -#: fe-secure-openssl.c:965 +#: fe-secure-openssl.c:852 #, c-format msgid "could not read root certificate file \"%s\": %s\n" msgstr "kunde inte läsa root-certifikatfilen \"%s\": %s\n" -#: fe-secure-openssl.c:993 +#: fe-secure-openssl.c:880 #, c-format msgid "SSL library does not support CRL certificates (file \"%s\")\n" msgstr "SSL-bibliotek stöder inte CRL-certifikat (fil \"%s\")\n" -#: fe-secure-openssl.c:1021 +#: fe-secure-openssl.c:908 msgid "" "could not get home directory to locate root certificate file\n" "Either provide the file or change sslmode to disable server certificate verification.\n" @@ -1017,7 +1067,7 @@ msgstr "" "kunde inte hämta hemkatalogen för att lokalisera root-certifikatfilen\n" "Antingen tillhandahÃ¥ll filen eller ändra sslmode för att stänga av serverns certifikatverifiering.\n" -#: fe-secure-openssl.c:1025 +#: fe-secure-openssl.c:912 #, c-format msgid "" "root certificate file \"%s\" does not exist\n" @@ -1026,82 +1076,82 @@ msgstr "" "root-certifikatfilen \"%s\" finns inte\n" "Antingen tillhandahÃ¥ll filen eller ändra sslmode för att stänga av serverns certifikatverifiering.\n" -#: fe-secure-openssl.c:1056 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "kunde inte öppna certifikatfil \"%s\": %s\n" -#: fe-secure-openssl.c:1075 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "kunde inte läsa certifikatfil \"%s\": %s\n" -#: fe-secure-openssl.c:1100 +#: fe-secure-openssl.c:987 #, c-format msgid "could not establish SSL connection: %s\n" msgstr "kan inte skapa SSL-förbindelse: %s\n" -#: fe-secure-openssl.c:1154 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "kunde inte ladda SSL-motor \"%s\": %s\n" -#: fe-secure-openssl.c:1166 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "kunde inte initiera SSL-motor \"%s\": %s\n" -#: fe-secure-openssl.c:1182 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "kunde inte läsa privat SSL-nyckel \"%s\" frÃ¥n motor \"%s\": %s\n" -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "kunde inte ladda privat SSL-nyckel \"%s\" frÃ¥n motor \"%s\": %s\n" -#: fe-secure-openssl.c:1233 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "certifikat tillgängligt, men inte den privata nyckelfilen \"%s\"\n" -#: fe-secure-openssl.c:1241 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "privata nyckelfilen \"%s\" har läsrättigheter för gruppen eller världen; rättigheten skall vara u=rw (0600) eller mindre\n" -#: fe-secure-openssl.c:1252 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "kunde inte ladda privata nyckelfilen \"%s\": %s\n" -#: fe-secure-openssl.c:1266 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "certifikatet matchar inte den privata nyckelfilen \"%s\": %s\n" -#: fe-secure-openssl.c:1366 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "certifikatet kunde inte hämtas: %s\n" -#: fe-secure-openssl.c:1458 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "inget SSL-fel rapporterat" -#: fe-secure-openssl.c:1467 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSL-felkod %lu" -#: fe-secure.c:261 +#: fe-secure.c:276 #, c-format msgid "could not receive data from server: %s\n" msgstr "kan inte ta emot data frÃ¥n servern: %s\n" -#: fe-secure.c:369 +#: fe-secure.c:392 #, c-format msgid "could not send data to server: %s\n" msgstr "kan inte skicka data till servern: %s\n" @@ -1111,63 +1161,81 @@ msgstr "kan inte skicka data till servern: %s\n" msgid "unrecognized socket error: 0x%08X/%d" msgstr "okänt uttagsfel: 0x%08X/%d" -#~ msgid "could not set socket to blocking mode: %s\n" -#~ msgstr "kunde inte ställa in uttag (socket) i blockerande läge: %s\n" +#~ msgid "invalid channel binding type\n" +#~ msgstr "ogiltig kanalbindningstyp\n" -#~ msgid "Kerberos 5 authentication rejected: %*s\n" -#~ msgstr "Kerberos-5-autentisering vägras: %*s\n" +#~ msgid "empty channel binding data for channel binding type \"%s\"\n" +#~ msgstr "tom kanalbindningsdata för kanalbindningstyp \"%s\"\n" -#~ msgid "could not restore non-blocking mode on socket: %s\n" -#~ msgstr "kunde inte Ã¥terställa ickeblockerande läge för uttag (socket): %s\n" +#~ msgid "channel binding type \"tls-server-end-point\" is not supported by this build\n" +#~ msgstr "kanalbindningstyp \"tls-server-end-point\" stöds inte av detta bygge\n" -#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPIDLE) misslyckades: %s\n" +#~ msgid "could not get home directory to locate password file\n" +#~ msgstr "kunde inte hämta hemkatalogen för att lokalisera lösenordsfilen\n" -#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPALIVE) misslyckades: %s\n" +#~ msgid "could not get home directory to locate service definition file" +#~ msgstr "kunde inte hämta hemkatalogen för att lokalisera servicedefinitionsfilen" -#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -#~ msgstr "setsockopt(TCP_KEEPINTVL) misslyckades: %s\n" +#~ msgid "certificate could not be validated: %s\n" +#~ msgstr "certifikatet kunde inte valideras: %s\n" -#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -#~ msgstr "setsockopt(SO_KEEPALIVE) misslyckades: %s\n" +#~ msgid "could not read private key file \"%s\": %s\n" +#~ msgstr "kunde inte läsa privat nyckelfil \"%s\": %s\n" -#~ msgid "socket not open\n" -#~ msgstr "uttag (socket) ej öppen\n" +#~ msgid "private key file \"%s\" changed during execution\n" +#~ msgstr "privata nyckelfilen \"%s\" har ändrats under körning\n" -#, fuzzy -#~ msgid "could not get home directory to locate client certificate files\n" -#~ msgstr "kunde inte hämta hemkatalogen: %s\n" +#~ msgid "could not open private key file \"%s\": %s\n" +#~ msgstr "kan inte öppna privat nyckelfil \"%s\": %s\n" -#~ msgid "error querying socket: %s\n" -#~ msgstr "fel vid förfrÃ¥gan till uttag (socket): %s\n" +#~ msgid "private key file \"%s\" has wrong permissions\n" +#~ msgstr "privata nyckelfilen \"%s\" har fel rättigheter\n" -#~ msgid "could not get information about host \"%s\": %s\n" -#~ msgstr "kunde inte fÃ¥ information om värd \"%s\": %s\n" +#~ msgid "invalid value of PGSSLKEY environment variable\n" +#~ msgstr "felaktigt värde pÃ¥ miljövariabeln PGSSLKEY\n" -#~ msgid "unsupported protocol\n" -#~ msgstr "protokoll stöds inte\n" +#~ msgid "could not get user information\n" +#~ msgstr "kunde inte hämta användarinformation\n" #~ msgid "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n" #~ msgstr "värdens namn \"%s\" är inte %ld.%ld.%ld.%ld efter uppslagning\n" -#~ msgid "could not get user information\n" -#~ msgstr "kunde inte hämta användarinformation\n" +#~ msgid "unsupported protocol\n" +#~ msgstr "protokoll stöds inte\n" -#~ msgid "invalid value of PGSSLKEY environment variable\n" -#~ msgstr "felaktigt värde pÃ¥ miljövariabeln PGSSLKEY\n" +#~ msgid "could not get information about host \"%s\": %s\n" +#~ msgstr "kunde inte fÃ¥ information om värd \"%s\": %s\n" -#~ msgid "private key file \"%s\" has wrong permissions\n" -#~ msgstr "privata nyckelfilen \"%s\" har fel rättigheter\n" +#~ msgid "error querying socket: %s\n" +#~ msgstr "fel vid förfrÃ¥gan till uttag (socket): %s\n" -#~ msgid "could not open private key file \"%s\": %s\n" -#~ msgstr "kan inte öppna privat nyckelfil \"%s\": %s\n" +#, fuzzy +#~ msgid "could not get home directory to locate client certificate files\n" +#~ msgstr "kunde inte hämta hemkatalogen: %s\n" -#~ msgid "private key file \"%s\" changed during execution\n" -#~ msgstr "privata nyckelfilen \"%s\" har ändrats under körning\n" +#~ msgid "socket not open\n" +#~ msgstr "uttag (socket) ej öppen\n" -#~ msgid "could not read private key file \"%s\": %s\n" -#~ msgstr "kunde inte läsa privat nyckelfil \"%s\": %s\n" +#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(SO_KEEPALIVE) misslyckades: %s\n" -#~ msgid "certificate could not be validated: %s\n" -#~ msgstr "certifikatet kunde inte valideras: %s\n" +#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPINTVL) misslyckades: %s\n" + +#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPALIVE) misslyckades: %s\n" + +#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPIDLE) misslyckades: %s\n" + +#~ msgid "could not restore non-blocking mode on socket: %s\n" +#~ msgstr "kunde inte Ã¥terställa ickeblockerande läge för uttag (socket): %s\n" + +#~ msgid "Kerberos 5 authentication rejected: %*s\n" +#~ msgstr "Kerberos-5-autentisering vägras: %*s\n" + +#~ msgid "could not set socket to blocking mode: %s\n" +#~ msgstr "kunde inte ställa in uttag (socket) i blockerande läge: %s\n" + +#~ msgid "GSSAPI name import error" +#~ msgstr "GSSAPI-fel vid import av namn" diff --git a/src/interfaces/libpq/po/tr.po b/src/interfaces/libpq/po/tr.po index bed25920922..855dad74b77 100644 --- a/src/interfaces/libpq/po/tr.po +++ b/src/interfaces/libpq/po/tr.po @@ -1,133 +1,248 @@ # translation of libpq.po to Turkish # Devrim GUNDUZ 2004, 2005, 2006, 2007. # Nicolai TUFAR 2004, 2005, 2006, 2007. +# Abdullah GÜLNER 2017, 2018. +# msgid "" msgstr "" "Project-Id-Version: libpq-tr\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2011-08-30 22:43+0000\n" -"PO-Revision-Date: 2011-08-31 13:21+0200\n" -"Last-Translator: Devrim GÜNDÜZ \n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-05 21:38+0000\n" +"PO-Revision-Date: 2019-06-14 10:49+0300\n" +"Last-Translator: Abdullah GÜLNER\n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: KBabel 1.9.1\n" +"X-Generator: Poedit 1.8.7.1\n" "X-Poedit-Basepath: /home/ntufar/pg/pgsql/src/interfaces/libpq\n" "X-Poedit-SearchPath-0: /home/ntufar/pg/pgsql/src/interfaces/libpq\n" -#: fe-auth.c:210 -#: fe-auth.c:429 -#: fe-auth.c:656 -msgid "host name must be specified\n" -msgstr "sunucu adı belirtilmelidir\n" +#: fe-auth-scram.c:183 +msgid "malformed SCRAM message (empty message)\n" +msgstr "hatalı SCRAM mesajı (boÅŸ mesaj)\n" + +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "hatalı SCRAM mesajı (uzunluk uyuÅŸmazlığı)\n" + +#: fe-auth-scram.c:238 +msgid "incorrect server signature\n" +msgstr "sunucu imzası yanlış\n" -#: fe-auth.c:240 +#: fe-auth-scram.c:247 +msgid "invalid SCRAM exchange state\n" +msgstr "geçersiz SCRAM deÄŸiÅŸim durumu\n" + +#: fe-auth-scram.c:270 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "hatalı SCRAM mesajı (\"%c\" niteliÄŸi bekleniyor)\n" + +#: fe-auth-scram.c:279 #, c-format -msgid "could not set socket to blocking mode: %s\n" -msgstr "soket engelleme moduna ayarlanamadı: %s\n" +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "hatalı SCRAM mesajı (\"%c\" niteliÄŸi için \"=\" karakteri bekleniyor)\n" + +#: fe-auth-scram.c:320 +msgid "could not generate nonce\n" +msgstr "nonce oluÅŸturulamadı\n" -#: fe-auth.c:258 -#: fe-auth.c:262 +#: fe-auth-scram.c:328 fe-auth-scram.c:395 fe-auth-scram.c:517 +#: fe-auth-scram.c:537 fe-auth-scram.c:563 fe-auth-scram.c:577 +#: fe-auth-scram.c:619 fe-auth.c:290 fe-auth.c:360 fe-auth.c:395 fe-auth.c:581 +#: fe-auth.c:740 fe-auth.c:1052 fe-auth.c:1200 fe-connect.c:858 +#: fe-connect.c:1320 fe-connect.c:1496 fe-connect.c:2085 fe-connect.c:2108 +#: fe-connect.c:2830 fe-connect.c:4512 fe-connect.c:4764 fe-connect.c:4883 +#: fe-connect.c:5133 fe-connect.c:5213 fe-connect.c:5312 fe-connect.c:5568 +#: fe-connect.c:5597 fe-connect.c:5669 fe-connect.c:5693 fe-connect.c:5711 +#: fe-connect.c:5812 fe-connect.c:5821 fe-connect.c:6177 fe-connect.c:6327 +#: fe-exec.c:2748 fe-exec.c:3495 fe-exec.c:3660 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1703 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "yetersiz bellek\n" + +#: fe-auth-scram.c:555 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "geçersiz SCRAM cevabı (nonce uyuÅŸmazlığı)\n" + +#: fe-auth-scram.c:594 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "hatalı SCRAM mesajı (geçersiz iterasyon sayısı)\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "hatalı SCRAM mesajı (sunucu-ilk-mesajı sonunda anlamsız deÄŸer)\n" + +#: fe-auth-scram.c:630 #, c-format -msgid "Kerberos 5 authentication rejected: %*s\n" -msgstr "Kerberos 5 yetkilendirmesi kabul edilmedi: %*s\n" +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "SCRAM deÄŸiÅŸimi iÅŸleminde sunucudan hata alındı: %s\n" + +#: fe-auth-scram.c:646 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "hatalı SCRAM mesajı (sunucu-son-mesajı sonunda anlamsız deÄŸer)\n" -#: fe-auth.c:288 +#: fe-auth-scram.c:654 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "hatalı SCRAM mesajı (geçersiz sunucu imzası)\n" + +#: fe-auth.c:77 #, c-format -msgid "could not restore non-blocking mode on socket: %s\n" -msgstr "could not restore non-blocking mode on socket: %s\n" +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "GSSAPI tamponu ayrılırken yetersiz bellek hatası (%d)\n" -#: fe-auth.c:400 +#: fe-auth.c:132 msgid "GSSAPI continuation error" msgstr "GSSAPI devam hatası" -#: fe-auth.c:436 +#: fe-auth.c:159 fe-auth.c:389 fe-secure-common.c:98 +msgid "host name must be specified\n" +msgstr "sunucu adı belirtilmelidir\n" + +#: fe-auth.c:166 msgid "duplicate GSS authentication request\n" msgstr "çift GSS yetkilendirme isteÄŸi\n" -#: fe-auth.c:456 -msgid "GSSAPI name import error" -msgstr "GSSAPI ad aktarma hatası" +#: fe-auth.c:231 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "GSSAPI tamponu ayrılırken yetersiz bellek hatası (%d)\n" -#: fe-auth.c:542 +#: fe-auth.c:279 msgid "SSPI continuation error" msgstr "SSPI devam hatası" -#: fe-auth.c:553 -#: fe-auth.c:627 -#: fe-auth.c:662 -#: fe-auth.c:757 -#: fe-connect.c:1961 -#: fe-connect.c:3368 -#: fe-connect.c:3586 -#: fe-connect.c:4007 -#: fe-connect.c:4016 -#: fe-connect.c:4153 -#: fe-connect.c:4199 -#: fe-connect.c:4217 -#: fe-connect.c:4296 -#: fe-connect.c:4366 -#: fe-connect.c:4412 -#: fe-connect.c:4430 -#: fe-exec.c:3121 -#: fe-exec.c:3286 -#: fe-lobj.c:696 -#: fe-protocol2.c:1092 -#: fe-protocol3.c:1433 -msgid "out of memory\n" -msgstr "yetersiz bellek\n" +#: fe-auth.c:350 +msgid "duplicate SSPI authentication request\n" +msgstr "çift SSPI yetkilendirme isteÄŸi\n" -#: fe-auth.c:642 +#: fe-auth.c:375 msgid "could not acquire SSPI credentials" -msgstr "SSPI kimlik bilgileri alınamadı: %m" +msgstr "SSPI kimlik bilgileri alınamadı" + +#: fe-auth.c:429 +msgid "duplicate SASL authentication request\n" +msgstr "çift SASL yetkilendirme isteÄŸi\n" + +#: fe-auth.c:487 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "" +"sunucu SSL'li olmayan bir baÄŸlantı üzerinde SCRAM-SHA-256-PLUS kimlik doÄŸrulaması önerdi\n" +" \n" -#: fe-auth.c:733 +#: fe-auth.c:499 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "sunucunun SASL yetkilendirme mekanizmalarından hiçbiri desteklenmiyor\n" + +#: fe-auth.c:605 +#, c-format +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "SASL tamponu ayrılırken yetersiz bellek hatası (%d)\n" + +#: fe-auth.c:630 +msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" +msgstr "sunucudan AuthenticationSASLFinal alındı, fakat SASL yetkilendirmesi tamamlanmadı\n" + +#: fe-auth.c:707 msgid "SCM_CRED authentication method not supported\n" msgstr "SCM_CRED yetkilendirme yöntemi desteklenmiyor.\n" -#: fe-auth.c:807 +#: fe-auth.c:798 msgid "Kerberos 4 authentication not supported\n" msgstr "Kerberos 4 yetkilendirmesi desteklenmiyor\n" -#: fe-auth.c:823 +#: fe-auth.c:803 msgid "Kerberos 5 authentication not supported\n" msgstr "Kerberos 5 yetkilendirmesi desteklenmiyor\n" -#: fe-auth.c:895 +#: fe-auth.c:874 msgid "GSSAPI authentication not supported\n" msgstr "GSSAPI yetkilendirmesi desteklenmiyor\n" -#: fe-auth.c:927 +#: fe-auth.c:906 msgid "SSPI authentication not supported\n" msgstr "SSPI yetkilendirmesi desteklenmiyor\n" -#: fe-auth.c:935 +#: fe-auth.c:914 msgid "Crypt authentication not supported\n" msgstr "Crypt yetkilendirmesi desteklenmiyor\n" -#: fe-auth.c:962 +#: fe-auth.c:980 #, c-format msgid "authentication method %u not supported\n" msgstr "%u yetkilendirme sistemi desteklenmiyor\n" -#: fe-connect.c:758 +#: fe-auth.c:1027 +#, c-format +msgid "user name lookup failure: error code %lu\n" +msgstr "kullanıcı adı arama baÅŸarısız: hata kodu %lu\n" + +#: fe-auth.c:1037 fe-connect.c:2717 +#, c-format +msgid "could not look up local user ID %d: %s\n" +msgstr "yerel kullanıcı ID %d bulunamadı: %s\n" + +#: fe-auth.c:1042 fe-connect.c:2722 +#, c-format +msgid "local user with ID %d does not exist\n" +msgstr "yerel kullanıcı ID %d mevcut deÄŸildir\n" + +#: fe-auth.c:1144 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "SHOW için döndürülen sonuç kümesi beklenmeyen ÅŸekilde \n" + +#: fe-auth.c:1153 +msgid "password_encryption value too long\n" +msgstr "parola ÅŸifreleme (password_encryption) deÄŸeri çok uzun\n" + +#: fe-auth.c:1193 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "bilinmeyen parola ÅŸifreleme algoritması \"%s\"\n" + +#: fe-connect.c:1041 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "%d sunucu adları %d sunucu adresleriyle eÅŸleÅŸtirilemedi\n" + +#: fe-connect.c:1117 +#, c-format +msgid "could not match %d port numbers to %d hosts\n" +msgstr "%d kapı (port) numaraları %d sunucuları ile eÅŸleÅŸtirilemedi\n" + +#: fe-connect.c:1213 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "geçersiz sslmode deÄŸeri: \"%s\"\n" -#: fe-connect.c:779 +#: fe-connect.c:1234 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" -msgstr "\"%s\" ssl modu, SSL desteÄŸi derlenmeyince geçersizdir.\n" +msgstr "\"%s\" sslmode deÄŸeri, SSL desteÄŸi derlenmeyince geçersizdir\n" + +#: fe-connect.c:1258 +#, c-format +msgid "invalid gssencmode value: \"%s\"\n" +msgstr "geçersiz gssencmode deÄŸeri: \"%s\"\n" + +#: fe-connect.c:1268 +msgid "no GSSAPI support; cannot require GSSAPI\n" +msgstr "GSSAPI desteÄŸi yok; GSSAPI gerektiremez\n" + +#: fe-connect.c:1302 +#, c-format +msgid "invalid target_session_attrs value: \"%s\"\n" +msgstr "geçersiz target_session_attrs deÄŸeri: \"%s\"\n" -#: fe-connect.c:972 +#: fe-connect.c:1520 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" -msgstr "could not set socket to TCP no delay mode: %s\n" +msgstr "soket TCP no delay moduna ayarlanamadı: %s\n" -#: fe-connect.c:1002 +#: fe-connect.c:1583 #, c-format msgid "" "could not connect to server: %s\n" @@ -135,10 +250,10 @@ msgid "" "\tconnections on Unix domain socket \"%s\"?\n" msgstr "" "sunucuya baÄŸlanılamadı: %s\n" -"\tSunucu yerelde çalışıyor ve Unix domain\n" -"\tsoketleri üzerinden baÄŸlantılara izin veriyor mu? \"%s\"?\n" +"\tSunucu yerelde çalışıyor ve \"%s\" Unix domain\n" +"\tsoketi üzerinden baÄŸlantılara izin veriyor mu?\n" -#: fe-connect.c:1057 +#: fe-connect.c:1620 #, c-format msgid "" "could not connect to server: %s\n" @@ -146,10 +261,10 @@ msgid "" "\tTCP/IP connections on port %s?\n" msgstr "" "sunucuya baÄŸlanılamadı: %s\n" -"\tSunucu \"%s\" (%s) sunucusunda çalışıyor ve\n" +"\tSunucu \"%s\" (%s) makinasında çalışıyor ve\n" "\t %s portundan TCP/IP baÄŸlantılarına izin veriyor mu?\n" -#: fe-connect.c:1066 +#: fe-connect.c:1628 #, c-format msgid "" "could not connect to server: %s\n" @@ -157,805 +272,976 @@ msgid "" "\tTCP/IP connections on port %s?\n" msgstr "" "sunucuya baÄŸlanılamadı: %s\n" -"\tls Sunucu \"%s\" sunucunda çalışıyor ve\n" -"\t %s portundan baÄŸlantılara izin veriyor mu?\n" - -#: fe-connect.c:1117 -#, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "setsockopt(TCP_KEEPIDLE) baÅŸarısız oldu: %s\n" - -#: fe-connect.c:1130 -#, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(SO_REUSEADDR) baÅŸarısız oldu: %s\n" +"\tSunucu \"%s\" makiansında çalışıyor ve\n" +"\t %s portundan TCP/IP baÄŸlantılarına izin veriyor mu?\n" -#: fe-connect.c:1162 +#: fe-connect.c:1679 #, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "setsockopt(TCP_KEEPINTVL) baÅŸarısız oldu: %s\n" +msgid "invalid integer value \"%s\" for keyword \"%s\"\n" +msgstr "\"%2$s\" anahtar kelimesi için geçersiz tamsayı deÄŸeri \"%1$s\"\n" -#: fe-connect.c:1194 +#: fe-connect.c:1709 fe-connect.c:1743 fe-connect.c:1778 fe-connect.c:1865 +#: fe-connect.c:2507 #, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "setsockopt(TCP_KEEPCNT) baÅŸarısız oldu: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "setsockopt(%s) baÅŸarısız oldu: %s\n" -#: fe-connect.c:1242 +#: fe-connect.c:1831 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "WSAIoctl(SIO_KEEPALIVE_VALS) baÅŸarısız oldu: %ui\n" -#: fe-connect.c:1294 +#: fe-connect.c:2199 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "geçersiz baÄŸlantı durumu, hafızanın zarar görmüş olmasının iÅŸareti olabilir\n" + +#: fe-connect.c:2267 #, c-format msgid "invalid port number: \"%s\"\n" -msgstr "Geçersiz port numarası: \"%s\"\n" +msgstr "geçersiz port numarası: \"%s\"\n" -#: fe-connect.c:1337 +#: fe-connect.c:2283 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "\"%s\" makine adı bir adrese çevirilemedi: %s\n" -#: fe-connect.c:1341 +#: fe-connect.c:2296 +#, c-format +msgid "could not parse network address \"%s\": %s\n" +msgstr "aÄŸ adresi \"%s\" ayrıştırılamadı: %s\n" + +#: fe-connect.c:2309 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" +msgstr "Unix-domain soket yolu \"%s\" çok uzun (azami %d bayt)\n" + +#: fe-connect.c:2324 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "\"%s\" Unix domain soket yolu adrese çevirilemedi: %s\n" -#: fe-connect.c:1551 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "Geçersiz baÄŸlantı durumu, hafızanın zarar görmüş olmasının iÅŸareti olabilir\n" - -#: fe-connect.c:1592 +#: fe-connect.c:2444 #, c-format msgid "could not create socket: %s\n" -msgstr "soket yaratılamadı: %s\n" +msgstr "soket oluÅŸturulamadı: %s\n" -#: fe-connect.c:1615 +#: fe-connect.c:2466 #, c-format -msgid "could not set socket to non-blocking mode: %s\n" -msgstr "could not set socket to non-blocking mode: %s\n" +msgid "could not set socket to nonblocking mode: %s\n" +msgstr "soket bloklamasız ( non-blocking ) moda ayarlanamadı: %s\n" -#: fe-connect.c:1627 +#: fe-connect.c:2476 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "soket close-on-exec moduna ayarlanamadı: %s\n" -#: fe-connect.c:1647 +#: fe-connect.c:2494 msgid "keepalives parameter must be an integer\n" msgstr "keepalives parametresi tamsayı olmalıdır\n" -#: fe-connect.c:1660 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "setsockopt(SO_KEEPALIVE) baÅŸarısız oldu: %s\n" - -#: fe-connect.c:1801 +#: fe-connect.c:2634 #, c-format msgid "could not get socket error status: %s\n" msgstr "soket hata durumu alınamadı: %s\n" -#: fe-connect.c:1839 +#: fe-connect.c:2662 #, c-format msgid "could not get client address from socket: %s\n" msgstr "soketten istemci adresi alınamadı: %s\n" -#: fe-connect.c:1880 +#: fe-connect.c:2704 msgid "requirepeer parameter is not supported on this platform\n" msgstr "bu platformda requirepeer parametresi desteklenmiyor \n" -#: fe-connect.c:1883 +#: fe-connect.c:2707 #, c-format msgid "could not get peer credentials: %s\n" msgstr "karşı tarafın kimlik bilgileri alınamadı: %s \n" -#: fe-connect.c:1893 +#: fe-connect.c:2730 #, c-format -msgid "local user with ID %d does not exist\n" -msgstr "yerel kullanıcı ID %d mevcut deÄŸildir\n" +msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" +msgstr "requirepeer \"%s\" belirtiyor, ancak gerçek karşı taraf (peer) kullanıcı adı \"%s\"\n" -#: fe-connect.c:1901 +#: fe-connect.c:2765 #, c-format -msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" -msgstr "requirepeer \"%s\" belirtiyor, ancak gerçek peer kullanıcı aıd \"%s\"\n" +msgid "could not send GSSAPI negotiation packet: %s\n" +msgstr "GSSAPI anlaÅŸma (negotiation) paketi gönderilemedi: %s\n" -#: fe-connect.c:1935 +#: fe-connect.c:2777 +msgid "GSSAPI encryption required, but was impossible (possibly no ccache, no server support, or using a local socket)\n" +msgstr "GSSAPI ÅŸifrelemesi gerekli, fakat mümkün deÄŸil (muhtemelen ccache yok, sunucu desteÄŸi yok ya da yerel soket kullanılıyor)\n" + +#: fe-connect.c:2804 #, c-format msgid "could not send SSL negotiation packet: %s\n" -msgstr "could not send SSL negotiation packet: %s\n" +msgstr "SSL anlaÅŸma (negotiation) paketi gönderilemedi: %s\n" -#: fe-connect.c:1974 +#: fe-connect.c:2843 #, c-format msgid "could not send startup packet: %s\n" msgstr "baÅŸlangıç paketi gönderilemedi: %s\n" -#: fe-connect.c:2044 +#: fe-connect.c:2913 msgid "server does not support SSL, but SSL was required\n" msgstr "sunucu SSL desteklemiyor, ama SSL gerekli idi\n" -#: fe-connect.c:2070 +#: fe-connect.c:2939 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "ssl görüşmesine geçersiz yanıt alındı: %c\n" -#: fe-connect.c:2149 -#: fe-connect.c:2182 +#: fe-connect.c:3029 +msgid "server doesn't support GSSAPI encryption, but it was required\n" +msgstr "sunucu GSSAPI ÅŸifrelemesi desteklemiyor, ama gerekli idi\n" + +#: fe-connect.c:3040 #, c-format -msgid "expected authentication request from server, but received %c\n" -msgstr "sunucudan yetkilendirme isteÄŸi beklendi ancak %c alındı\n" +msgid "received invalid response to GSSAPI negotiation: %c\n" +msgstr "GSSAPI görüşmesine geçersiz yanıt alındı: %c\n" -#: fe-connect.c:2363 +#: fe-connect.c:3108 fe-connect.c:3141 #, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "GSSAPI tamponu ayrılırken yetersiz bellek hatası (%d)" +msgid "expected authentication request from server, but received %c\n" +msgstr "sunucudan yetkilendirme isteÄŸi beklendi ancak %c alındı\n" -#: fe-connect.c:2448 +#: fe-connect.c:3388 msgid "unexpected message from server during startup\n" msgstr "baÅŸlangıç sırasında sunucudan beklenmeyen bir mesaj alındı\n" -#: fe-connect.c:2547 +#: fe-connect.c:3615 +#, c-format +msgid "could not make a writable connection to server \"%s:%s\"\n" +msgstr "sunucuya yazılabilir (writable) baÄŸlantı saÄŸlanamadı \"%s:%s\"\n" + +#: fe-connect.c:3661 +#, c-format +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "\"SHOW transaction_read_only\" testi sunucuda baÅŸarısız oldu \"%s:%s\"\n" + +#: fe-connect.c:3676 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "%d - geçersiz baÄŸlantı durumu, bellekteki veri zarar görmüş olabilir\n" -#: fe-connect.c:2976 -#: fe-connect.c:3036 +#: fe-connect.c:4118 fe-connect.c:4178 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "PGEventProc \"%s\" iÅŸlemi PGEVT_CONNRESET iÅŸlemi sırasında baÅŸarısız oldu\n" -#: fe-connect.c:3381 +#: fe-connect.c:4525 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "geçersiz LDAP URL \"%s\": ÅŸema, ldap:// ile baÅŸlamalıdir\n" -#: fe-connect.c:3396 +#: fe-connect.c:4540 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" -msgstr "geçersiz LDAP URL \"%s\": distinguished name eksik\n" +msgstr "geçersiz LDAP URL \"%s\": distinguished isim eksik\n" -#: fe-connect.c:3407 -#: fe-connect.c:3460 +#: fe-connect.c:4551 fe-connect.c:4604 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" -msgstr "geçersiz LDAP URL \"%s\": tam bir attribute içermelidir\n" +msgstr "geçersiz LDAP URL \"%s\": tam olarak bir nitelik (attribute) içermelidir\n" -#: fe-connect.c:3417 -#: fe-connect.c:3474 +#: fe-connect.c:4561 fe-connect.c:4618 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "geçersiz LDAP URL \"%s\": arama kapsamı içermelidir (base/one/sub)\n" -#: fe-connect.c:3428 +#: fe-connect.c:4572 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" -msgstr "geçersiz LDAP URL \"%s\": filtere eksik\n" +msgstr "geçersiz LDAP URL \"%s\": filtre eksik\n" -#: fe-connect.c:3449 +#: fe-connect.c:4593 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "geçersiz LDAP URL \"%s\": geçersiz port numarası\n" -#: fe-connect.c:3483 +#: fe-connect.c:4627 msgid "could not create LDAP structure\n" msgstr "LDAP yapısı oluÅŸturma hatası\n" -#: fe-connect.c:3525 +#: fe-connect.c:4703 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "LDAP sonucunda sorgulama hatası: %s\n" -#: fe-connect.c:3536 +#: fe-connect.c:4714 msgid "more than one entry found on LDAP lookup\n" msgstr "LDAP sorgusu sonucunda birden fazla giriÅŸ bulundu\n" -#: fe-connect.c:3537 -#: fe-connect.c:3549 +#: fe-connect.c:4715 fe-connect.c:4727 msgid "no entry found on LDAP lookup\n" msgstr "LDAP sorgusu sonucunda hiçbir giriÅŸ bulunamadı\n" -#: fe-connect.c:3560 -#: fe-connect.c:3573 +#: fe-connect.c:4738 fe-connect.c:4751 msgid "attribute has no values on LDAP lookup\n" msgstr "LDAP sorgusu sonucunda bulunan attribute, hiçbir deÄŸer içermiyor\n" -#: fe-connect.c:3625 -#: fe-connect.c:3644 -#: fe-connect.c:4055 +#: fe-connect.c:4803 fe-connect.c:4822 fe-connect.c:5351 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "baÄŸlantı bilgi katarında \"%s\" bilgisinden sonra \"=\" iÅŸareti eksik\n" -#: fe-connect.c:3708 -#: fe-connect.c:4137 -#: fe-connect.c:4321 +#: fe-connect.c:4895 fe-connect.c:5536 fe-connect.c:6310 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "geçersiz baÄŸlantı seçeneÄŸi \"%s\"\n" -#: fe-connect.c:3724 -#: fe-connect.c:4104 +#: fe-connect.c:4911 fe-connect.c:5400 msgid "unterminated quoted string in connection info string\n" msgstr "baÄŸlantı bilgi katarında sonlandırılmamış tırnaklı katar\n" -#: fe-connect.c:3763 -msgid "could not get home directory to locate service definition file" -msgstr "servis dosyasının olduÄŸu ev dizini bulunamadı" - -#: fe-connect.c:3796 +#: fe-connect.c:4994 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "\"%s\" servisinin tanımı bulunamadı\n" -#: fe-connect.c:3819 +#: fe-connect.c:5017 #, c-format msgid "service file \"%s\" not found\n" msgstr "\"%s\" servis dosyası bulunamadı\n" -#: fe-connect.c:3832 +#: fe-connect.c:5030 #, c-format msgid "line %d too long in service file \"%s\"\n" -msgstr " \"%2$s\" servis dosyasında %1$d no'lu satır çok uzun \n" +msgstr "\"%2$s\" servis dosyasında %1$d no'lu satır çok uzun \n" -#: fe-connect.c:3903 -#: fe-connect.c:3930 +#: fe-connect.c:5101 fe-connect.c:5145 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "\"%s\" servis dosyasında yazım hatası, satır no %d\n" -#: fe-connect.c:4597 +#: fe-connect.c:5112 +#, c-format +msgid "nested service specifications not supported in service file \"%s\", line %d\n" +msgstr "\"%s\" servis dosyası satır no %d , desteklenmeyen içiçe servis tanımlamaları\n" + +#: fe-connect.c:5832 +#, c-format +msgid "invalid URI propagated to internal parser routine: \"%s\"\n" +msgstr "dahili çözümleyici yordamına aktarılan geçersiz URI: \"%s\"\n" + +#: fe-connect.c:5909 +#, c-format +msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" +msgstr "URI içinde IPv6 sunucu adresinde eÅŸleÅŸen \"]\" aranırken dize sonuna ulaşıldı: \"%s\"\n" + +#: fe-connect.c:5916 +#, c-format +msgid "IPv6 host address may not be empty in URI: \"%s\"\n" +msgstr "URI içinde IPv6 sunuu adresi boÅŸ olamaz: \"%s\"\n" + +#: fe-connect.c:5931 +#, c-format +msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" +msgstr "URI içinde %2$d pozisyonunda beklenmeyen karakter \"%1$c\" (\":\" veya \"/\" bekleniyordu): \"%3$s\"\n" + +#: fe-connect.c:6060 +#, c-format +msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" +msgstr "URI sorgu parametresinde fazla anahtar/deÄŸer ayıracı \"=\": \"%s\"\n" + +#: fe-connect.c:6080 +#, c-format +msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" +msgstr "URI sorgu parametresinde eksik anahtar/deÄŸer ayıracı \"=\": \"%s\"\n" + +#: fe-connect.c:6131 +#, c-format +msgid "invalid URI query parameter: \"%s\"\n" +msgstr "geçersiz URI sorgu parametresi: \"%s\"\n" + +#: fe-connect.c:6205 +#, c-format +msgid "invalid percent-encoded token: \"%s\"\n" +msgstr "geçersiz percent-encoded andacı (token)\"%s\"\n" + +#: fe-connect.c:6215 +#, c-format +msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" +msgstr "percent-encoded deÄŸeri içinde yasak deÄŸer %%00: \"%s\"\n" + +#: fe-connect.c:6580 msgid "connection pointer is NULL\n" msgstr "baÄŸlantı belirteci NULL'dur\n" -#: fe-connect.c:4874 +#: fe-connect.c:6878 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "UYARI: \"%s\" password dosyası düz metin dosyası deÄŸildir\n" -#: fe-connect.c:4883 +#: fe-connect.c:6887 #, c-format msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "UYARI: \"%s\" ÅŸifre dosyası herkes ya da grup tarafından eriÅŸilebilir durumda; dosyanın izinleri u=rw (0600) ya da daha az olmalı\n" -#: fe-connect.c:4971 +#: fe-connect.c:6981 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "\"%s\" dosyasından parola okundu\n" -#: fe-exec.c:810 +#: fe-exec.c:445 fe-exec.c:2822 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "%d satır numarası, 0..%d sınırının dışında" + +#: fe-exec.c:506 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "yetersiz bellek" + +#: fe-exec.c:507 fe-protocol2.c:1402 fe-protocol3.c:1911 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:816 +msgid "write to server failed\n" +msgstr "sunucuya yazma baÅŸarısız oldu\n" + +#: fe-exec.c:897 msgid "NOTICE" msgstr "BİLGİ" -#: fe-exec.c:997 -#: fe-exec.c:1054 -#: fe-exec.c:1094 +#: fe-exec.c:955 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresult INT_MAX deÄŸerinden daha fazla satır (Tuple) destekleyemez" + +#: fe-exec.c:967 +msgid "size_t overflow" +msgstr "size_t taÅŸması" + +#: fe-exec.c:1244 fe-exec.c:1302 fe-exec.c:1348 msgid "command string is a null pointer\n" msgstr "komut katarı null belirteçtir\n" -#: fe-exec.c:1087 -#: fe-exec.c:1182 +#: fe-exec.c:1308 fe-exec.c:1354 fe-exec.c:1449 +msgid "number of parameters must be between 0 and 65535\n" +msgstr "parametrelerin sayısı 0 ve 65535 arasında olmalı\n" + +#: fe-exec.c:1342 fe-exec.c:1443 msgid "statement name is a null pointer\n" msgstr "durum adı null belirteçtir\n" -#: fe-exec.c:1102 -#: fe-exec.c:1256 -#: fe-exec.c:1925 -#: fe-exec.c:2123 +#: fe-exec.c:1362 fe-exec.c:1525 fe-exec.c:2234 fe-exec.c:2436 msgid "function requires at least protocol version 3.0\n" msgstr "fonksiyon en az 3.0 prokolüne gereksinim duyuyor.\n" -#: fe-exec.c:1213 +#: fe-exec.c:1480 msgid "no connection to the server\n" msgstr "sunucuya baÄŸlantı yok\n" -#: fe-exec.c:1220 +#: fe-exec.c:1487 msgid "another command is already in progress\n" msgstr "ÅŸu anda iÅŸlenen baÅŸka bir komut var\n" -#: fe-exec.c:1332 +#: fe-exec.c:1601 msgid "length must be given for binary parameter\n" msgstr "binary parametresinin uzunluÄŸu belirtilmelidir\n" -#: fe-exec.c:1585 +#: fe-exec.c:1864 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "beklenmeyen asyncStatus: %d\n" -#: fe-exec.c:1605 +#: fe-exec.c:1884 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "PGEventProc \"%s\" iÅŸlemi PGEVT_RESULTCREATE iÅŸlemi sırasında baÅŸarısız oldu\n" -#: fe-exec.c:1735 +#: fe-exec.c:2044 msgid "COPY terminated by new PQexec" msgstr "COPY, yeni PQexec tarafından sonlandırıldı" -#: fe-exec.c:1743 +#: fe-exec.c:2052 msgid "COPY IN state must be terminated first\n" msgstr "Öncelikle COPY IN durumu sonlandırılmalıdır\n" -#: fe-exec.c:1763 +#: fe-exec.c:2072 msgid "COPY OUT state must be terminated first\n" msgstr "Öncelikle COPY OUT durumu sonlandırılmalıdır\n" -#: fe-exec.c:1771 +#: fe-exec.c:2080 msgid "PQexec not allowed during COPY BOTH\n" -msgstr "PQexec COPY BOTH sırasında izin verilmiyor\n" +msgstr "PQexec için COPY BOTH sırasında izin verilmiyor\n" -#: fe-exec.c:2014 -#: fe-exec.c:2080 -#: fe-exec.c:2167 -#: fe-protocol2.c:1237 -#: fe-protocol3.c:1569 +#: fe-exec.c:2326 fe-exec.c:2393 fe-exec.c:2483 fe-protocol2.c:1359 +#: fe-protocol3.c:1842 msgid "no COPY in progress\n" msgstr "çalışan COPY süreci yok\n" -#: fe-exec.c:2359 +#: fe-exec.c:2673 msgid "connection in wrong state\n" msgstr "baÄŸlantı yanlış durumda\n" -#: fe-exec.c:2390 +#: fe-exec.c:2704 msgid "invalid ExecStatusType code" msgstr "geçersiz ExecStatusType kodu" -#: fe-exec.c:2454 -#: fe-exec.c:2477 -#, c-format -msgid "column number %d is out of range 0..%d" -msgstr "%d kolon numarası, 0..%d sınırının dışında" +#: fe-exec.c:2731 +msgid "PGresult is not an error result\n" +msgstr "PGresult bir hata sonucu deÄŸildir\n" -#: fe-exec.c:2470 +#: fe-exec.c:2806 fe-exec.c:2829 #, c-format -msgid "row number %d is out of range 0..%d" -msgstr "%d satır numarası, 0..%d sınırının dışında" +msgid "column number %d is out of range 0..%d" +msgstr "%d kolon numarası, 0..%d aralığının dışında" -#: fe-exec.c:2492 +#: fe-exec.c:2844 #, c-format msgid "parameter number %d is out of range 0..%d" -msgstr "%d parametre sıra dışı: 0..%d" +msgstr "%d sayılı parametre aralık dışında: 0..%d" -#: fe-exec.c:2780 +#: fe-exec.c:3154 #, c-format msgid "could not interpret result from server: %s" msgstr "sunucudan gelen yanıt yorumlanamadı: %s" -#: fe-exec.c:3019 -#: fe-exec.c:3103 +#: fe-exec.c:3393 fe-exec.c:3477 msgid "incomplete multibyte character\n" msgstr "tamamlanmamış çoklu bayt karakteri\n" -#: fe-lobj.c:152 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "lo_truncate fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:380 +#: fe-lobj.c:170 +msgid "argument of lo_truncate exceeds integer range\n" +msgstr "lo_truncate argümanı tamsayı aralığını aşıyor\n" + +#: fe-lobj.c:221 +msgid "cannot determine OID of function lo_truncate64\n" +msgstr "lo_truncate64 fonksiyonunun OID'i belirlenemiyor\n" + +#: fe-lobj.c:279 +msgid "argument of lo_read exceeds integer range\n" +msgstr "lo_read argümanı tamsayı aralığını aşıyor\n" + +#: fe-lobj.c:334 +msgid "argument of lo_write exceeds integer range\n" +msgstr "lo_write argümanı tamsayı aralığını aşıyor\n" + +#: fe-lobj.c:425 +msgid "cannot determine OID of function lo_lseek64\n" +msgstr "lo_lseek64 fonksiyonunun OID'i belirlenemiyor\n" + +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "lo_create fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:525 -#: fe-lobj.c:624 +#: fe-lobj.c:600 +msgid "cannot determine OID of function lo_tell64\n" +msgstr "lo_tell64 fonksiyonunun OID'i belirlenemiyor\n" + +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "\"%s\" dosyası açılamadı: %s\n" -#: fe-lobj.c:575 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "\"%s\" dosyasından okuma hatası: %s\n" -#: fe-lobj.c:639 -#: fe-lobj.c:663 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "\"%s\" dosyasına yazılamadı: %s\n" -#: fe-lobj.c:744 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "large object fonksiyonlarını ilklendirecek sorgu veri döndürmedi\n" -#: fe-lobj.c:785 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "lo_open fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:792 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "lo_close fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:799 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "lo_create fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:806 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "lo_unlink fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:813 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "lo_lseek fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:820 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "lo_tell fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:827 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "loread fonksiyonunun OID'i belirlenemiyor\n" -#: fe-lobj.c:834 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "lowrite fonksiyonunun OID'i belirlenemiyor\n" -#: fe-misc.c:270 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" -msgstr "%lu büyüklüğündeki tamsayılar pqGetInt tarafından desteklenmez." +msgstr "%lu büyüklüğündeki tamsayılar pqGetInt tarafından desteklenmez" -#: fe-misc.c:306 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" -msgstr "%lu büyüklüğündeki tamsayılar pqPutInt tarafından desteklenmez." +msgstr "%lu büyüklüğündeki tamsayılar pqPutInt tarafından desteklenmez" -#: fe-misc.c:585 -#: fe-misc.c:784 +#: fe-misc.c:637 fe-misc.c:859 msgid "connection not open\n" msgstr "baÄŸlantı açık deÄŸil\n" -#: fe-misc.c:711 -#: fe-secure.c:364 -#: fe-secure.c:443 -#: fe-secure.c:524 -#: fe-secure.c:632 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:268 fe-secure.c:385 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" "\tbefore or while processing the request.\n" msgstr "" "sunucu baÄŸlantıyı beklenmedik ÅŸekilde kapattı\n" -"\tBu ileti sunucunun isteÄŸi iÅŸlemeden hemen önce ya da \n" -"\tisteÄŸi iÅŸlerken kapatıldığı anlamına gelir.\n" +"\tBu muhtemelen sunucunun isteÄŸi iÅŸlemeden önce ya da \n" +"\tisteÄŸi iÅŸlerken anormal olarak kapandığı anlamına gelir.\n" -#: fe-misc.c:948 +#: fe-misc.c:1046 msgid "timeout expired\n" msgstr "zamanaşımı süresi sona derdi\n" -#: fe-misc.c:993 -msgid "socket not open\n" -msgstr "soket açık deÄŸil\n" +#: fe-misc.c:1091 +msgid "invalid socket\n" +msgstr "geçersiz soket\n" -#: fe-misc.c:1016 +#: fe-misc.c:1114 #, c-format msgid "select() failed: %s\n" msgstr "select() baÅŸarısız oldu: %s\n" -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" -msgstr "Geçersiz setenv durumu %c, belleÄŸin zarar görmesinin bir iÅŸareti olabilir\n" +msgstr "geçersiz setenv durumu %c, belleÄŸin zarar görmesinin bir iÅŸareti olabilir\n" -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" -msgstr "Geçersiz %c durumu, belleÄŸin zarar görmesinin bir iÅŸareti olabilir\n" +msgstr "geçersiz %c durumu, belleÄŸin zarar görmesinin bir iÅŸareti olabilir\n" -#: fe-protocol2.c:479 -#: fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" -msgstr "Sunucu boÅŸ durumdayken sunucudan 0x%02x ileti tipi geldi" +msgstr "sunucu boÅŸ durumdayken sunucudan 0x%02x ileti tipi geldi" -#: fe-protocol2.c:522 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" -msgstr "BoÅŸ sorgu yanıtını takip eden geçersiz karakter:%c (\"I\" ileti)" +msgstr "boÅŸ sorgu yanıtını takip eden geçersiz karakter:%c (\"I\" mesajı)" -#: fe-protocol2.c:576 +#: fe-protocol2.c:594 #, c-format msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" -msgstr "Sunucu öncelikli satır tanımı olmadan veri (\"D\" ileti) gönderdi (\"T\" ileti)" +msgstr "sunucu önceki satır tanımı (\"T\" mesajı) olmadan veri (\"D\" mesajı) gönderdi" -#: fe-protocol2.c:592 +#: fe-protocol2.c:612 #, c-format msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" -msgstr "Sunucu öncelikli satır tanımı olmadan ikili veri (\"D\" ileti) gönderdi (\"T\" ileti)" +msgstr "sunucu önceki satır tanımı (\"T\" mesajı) olmadan ikili veri (\"B\" mesajı) gönderdi" -#: fe-protocol2.c:612 -#: fe-protocol3.c:388 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "sunucudan beklenmeyen bir yanıt alındı; alınan ilk karakter\"%c\" idi\n" -#: fe-protocol2.c:833 -#: fe-protocol3.c:707 -msgid "out of memory for query result\n" -msgstr "Sorgu sonucu için yetersiz bellek\n" - -#: fe-protocol2.c:1280 -#: fe-protocol3.c:1637 -#, c-format -msgid "%s" -msgstr "%s" +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 +msgid "out of memory for query result" +msgstr "sorgu sonucu için yetersiz bellek" -#: fe-protocol2.c:1292 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "sunucu ile eÅŸzamanlama kayboldu, baÄŸlantı yeniden açılıyor" -#: fe-protocol2.c:1426 -#: fe-protocol2.c:1458 -#: fe-protocol3.c:1840 +#: fe-protocol2.c:1536 fe-protocol2.c:1568 fe-protocol3.c:2099 #, c-format msgid "protocol error: id=0x%x\n" msgstr "protokol hatası: id=0x%x\n" -#: fe-protocol3.c:344 +#: fe-protocol3.c:367 msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" -msgstr "Sunucu öncelikli satır tanımı olmadan veri (\"D\" ileti) gönderdi (\"T\" ileti)\n" +msgstr "" +"sunucu, önceki satır tanımı (\"T\" mesajı) olmadan veri (\"D\" mesajı) gönderdi\n" +"\n" -#: fe-protocol3.c:409 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" -msgstr "İleti içeriÄŸi,\"%c\" ileti tipinin içindeki uzunlukla aynı deÄŸil\n" +msgstr "ileti içeriÄŸi,\"%c\" ileti tipinin içindeki uzunlukla aynı deÄŸil\n" -#: fe-protocol3.c:430 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "sunucu ile eÅŸzamanlılık kayboldu: \"%c\" ileti tipi alındı, uzunluÄŸu %d\n" -#: fe-protocol3.c:652 -msgid "unexpected field count in \"D\" message\n" -msgstr "\"D\" iletisinde beklenmeyen alan sayısı\n" +#: fe-protocol3.c:504 fe-protocol3.c:544 +msgid "insufficient data in \"T\" message" +msgstr "\"T\" mesajında yetersiz veri" + +#: fe-protocol3.c:577 +msgid "extraneous data in \"T\" message" +msgstr "\"T\" mesajında ilgisiz veri" + +#: fe-protocol3.c:690 +msgid "extraneous data in \"t\" message" +msgstr "\"t\" mesajında ilgisiz veri" + +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 +msgid "insufficient data in \"D\" message" +msgstr "\"D\" mesajında yetersiz veri" + +#: fe-protocol3.c:767 +msgid "unexpected field count in \"D\" message" +msgstr "\"D\" mesajında beklenmeyen alan sayısı" + +#: fe-protocol3.c:820 +msgid "extraneous data in \"D\" message" +msgstr "\"D\" mesajında ilgisiz veri" + +#: fe-protocol3.c:1012 +msgid "no error message available\n" +msgstr "hata mesajı bulunmuyor\n" #. translator: %s represents a digit string -#: fe-protocol3.c:798 -#: fe-protocol3.c:817 +#: fe-protocol3.c:1060 fe-protocol3.c:1079 #, c-format msgid " at character %s" -msgstr "%s. karakterde" +msgstr " %s. karakterde" -#: fe-protocol3.c:830 +#: fe-protocol3.c:1092 #, c-format msgid "DETAIL: %s\n" msgstr "AYRINTI: %s\n" -#: fe-protocol3.c:833 +#: fe-protocol3.c:1095 #, c-format msgid "HINT: %s\n" msgstr "İPUCU: %s\n" -#: fe-protocol3.c:836 +#: fe-protocol3.c:1098 #, c-format msgid "QUERY: %s\n" msgstr "SORGU: %s\n" -#: fe-protocol3.c:839 +#: fe-protocol3.c:1105 #, c-format msgid "CONTEXT: %s\n" msgstr "BAÄžLAM: %s\n" -#: fe-protocol3.c:851 +#: fe-protocol3.c:1114 +#, c-format +msgid "SCHEMA NAME: %s\n" +msgstr "ÅžEMA ADI: %s\n" + +#: fe-protocol3.c:1118 +#, c-format +msgid "TABLE NAME: %s\n" +msgstr "TABLO ADI: %s\n" + +#: fe-protocol3.c:1122 +#, c-format +msgid "COLUMN NAME: %s\n" +msgstr "SÜTUN ADI: %s\n" + +#: fe-protocol3.c:1126 +#, c-format +msgid "DATATYPE NAME: %s\n" +msgstr "VERİ TİPİ ADI: %s\n" + +#: fe-protocol3.c:1130 +#, c-format +msgid "CONSTRAINT NAME: %s\n" +msgstr "KISITLAMA ADI: %s\n" + +#: fe-protocol3.c:1142 msgid "LOCATION: " msgstr "YER: " -#: fe-protocol3.c:853 +#: fe-protocol3.c:1144 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:855 +#: fe-protocol3.c:1146 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1079 +#: fe-protocol3.c:1341 #, c-format msgid "LINE %d: " msgstr "SATIR %d: " -#: fe-protocol3.c:1465 +#: fe-protocol3.c:1736 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: COPY OUT metnini yapmıyor\n" -#: fe-secure.c:265 +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "SSL sertifikasının ismi gömülü olarak null içeriyor\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "doÄŸrulanmış bir SSL baÄŸlantısı için makina adı belirtilmelidir\n" + +#: fe-secure-common.c:196 #, c-format -msgid "could not establish SSL connection: %s\n" -msgstr "SSL baÄŸlantısı saÄŸlanamadı: %s\n" +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "\"%s\" için olan sunucu sertifikası \"%s\" olan makina adı ile eÅŸleÅŸmiyor\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "sunucunun makina adı sunucu sertifikasından alınamadı\n" -#: fe-secure.c:369 -#: fe-secure.c:529 -#: fe-secure.c:1331 +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALL hatası: %s\n" -#: fe-secure.c:376 -#: fe-secure.c:536 -#: fe-secure.c:1335 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALL hatası: EOF bulundu\n" -#: fe-secure.c:387 -#: fe-secure.c:547 -#: fe-secure.c:1344 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSL hatası: %s\n" -#: fe-secure.c:401 -#: fe-secure.c:561 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL baÄŸlantısı beklenmeyen ÅŸekilde sonlandırıldı\n" -#: fe-secure.c:407 -#: fe-secure.c:567 -#: fe-secure.c:1353 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "tanımlanamayan SSL hata kodu: %d\n" -#: fe-secure.c:451 +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "" +"sunucu sertifika imza algoritması belirlenemedi\n" +"\n" + +#: fe-secure-openssl.c:419 #, c-format -msgid "could not receive data from server: %s\n" -msgstr "Sunucudan veri alınamadı: %s\n" +msgid "could not find digest for NID %s\n" +msgstr "NID %s için özet (digest) bulunamadı\n" -#: fe-secure.c:639 +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "karşı tarafın sertifika hash'i oluÅŸturulamadı\n" + +#: fe-secure-openssl.c:486 +msgid "SSL certificate's name entry is missing\n" +msgstr "" +"SSL sertifikasının isim giriÅŸi eksik\n" +"\n" + +#: fe-secure-openssl.c:815 #, c-format -msgid "could not send data to server: %s\n" -msgstr "Sunucuya veri gönderilemedi: %s\n" +msgid "could not create SSL context: %s\n" +msgstr "SSL baÄŸlamı oluÅŸturulamadı: %s\n" -#: fe-secure.c:746 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "onaylı SSL baÄŸlantısı için sunucu adı belirtilmelidir\n" +#: fe-secure-openssl.c:852 +#, c-format +msgid "could not read root certificate file \"%s\": %s\n" +msgstr "\"%s\"kök sertifika dosyası okunamadı: %s\n" -#: fe-secure.c:765 +#: fe-secure-openssl.c:880 #, c-format -msgid "server common name \"%s\" does not match host name \"%s\"\n" -msgstr "Sunucu ortak adı olan \"%s\", \"%s\" olan host adı ile eÅŸleÅŸmiyor\n" +msgid "SSL library does not support CRL certificates (file \"%s\")\n" +msgstr "kurulu SSL kütüphanesi CRL sertifikalarını desteklemiyor (dosya adı \"%s\")\n" -#: fe-secure.c:897 +#: fe-secure-openssl.c:908 +msgid "" +"could not get home directory to locate root certificate file\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"kök sertifika dosyasının ev dizini bulunamadı\n" +"Ya bir dosya adı belirtin, ya da sunucu sertifika doÄŸrulamasını kapatmak için sslmode ayarını deÄŸiÅŸtirin.\n" + +#: fe-secure-openssl.c:912 #, c-format -msgid "could not create SSL context: %s\n" -msgstr "SSL içeriÄŸi yaratılamadı: %s\n" +msgid "" +"root certificate file \"%s\" does not exist\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"\"%s\" kök sertifika dosyası mevcut deÄŸil\n" +"Ya bu dosyayı oluÅŸturun ya da sslmode ayarını sunucu sertifika doÄŸrulamasını kapatmak için deÄŸiÅŸtirin.\n" -#: fe-secure.c:1019 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "\"%s\" sertifikası açılamadı: %s\n" -#: fe-secure.c:1044 -#: fe-secure.c:1054 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "\"%s\" sertifikası okunamadı: %s\n" -#: fe-secure.c:1091 +#: fe-secure-openssl.c:987 +#, c-format +msgid "could not establish SSL connection: %s\n" +msgstr "SSL baÄŸlantısı saÄŸlanamadı: %s\n" + +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "\"%s\" SSL motoru yüklenemedi: %s\n" -#: fe-secure.c:1103 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "\"%s\" SSL motoru ilklendirilemedi: %s\n" -#: fe-secure.c:1119 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" -msgstr "\"%2$s\" motorundan \"%1$s\" SSL özel anahtarı okunamadı: %3$s\n" +msgstr "\"%2$s\" motorundan \"%1$s\" özel SSL anahtarı okunamadı: %3$s\n" -#: fe-secure.c:1133 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" -msgstr "\"%2$s\" motorundan \"%1$s\" SSL özel anahtarı yüklenemedi: %3$s\n" +msgstr "\"%2$s\" motorundan \"%1$s\" özel SSL anahtarı yüklenemedi: %3$s\n" -#: fe-secure.c:1170 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" -msgstr "Sertifika mevcut ancak özel anahtar mevcut deÄŸil \"%s\"\n" +msgstr "sertifika mevcut ancak özel anahtar (private key) mevcut deÄŸil \"%s\"\n" -#: fe-secure.c:1178 +#: fe-secure-openssl.c:1128 #, c-format msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" -msgstr "\"%s\" özel anahtar dosyası herkes ya da grup tarafından eriÅŸilebilir durumda; dosyanın izinleri u=rw (0600) ya da daha az olmalı\n" +msgstr "\"%s\" özel anahtar (private key) dosyası herkes ya da grup tarafından eriÅŸilebilir durumda; dosyanın izinleri u=rw (0600) ya da daha az olmalı\n" -#: fe-secure.c:1189 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" -msgstr "private key dosyası \"%s\" okunamıyor: %s\n" +msgstr "özel anahtar (private key) dosyası \"%s\" okunamıyor: %s\n" -#: fe-secure.c:1203 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" -msgstr "Sertifika, \"%s\" özel anahtar dosyası ile uyuÅŸmuyor: %s\n" - -#: fe-secure.c:1231 -#, c-format -msgid "could not read root certificate file \"%s\": %s\n" -msgstr "\"%s\"kök sertifika dosyası okunamadı: %s\n" - -#: fe-secure.c:1258 -#, c-format -msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "Kurulu SSL kütüphanesi CRL sertifikalarını desteklemiyor (dosya adı \"%s\")\n" - -#: fe-secure.c:1285 -msgid "" -"could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" -msgstr "" -"kök sertifika dosyasının ev dizini bulunamadı\n" -"Ya bir dosya adı belirtin, ya da sunucu sertifika onaylamasını kapatmak için sslmode'u kapatın.\n" - -#: fe-secure.c:1289 -#, c-format -msgid "" -"root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate verification.\n" -msgstr "" -"\"%s\" kök sertifika dosyası mevcut deÄŸil\n" -"Ya bu dosyayı oluÅŸturun ya da sslmode ayarını sunucu sertifika onaylamasını kapatmak için deÄŸiÅŸtirin.\n" +msgstr "sertifika, \"%s\" özel anahtar (private key) dosyası ile uyuÅŸmuyor: %s\n" -#: fe-secure.c:1372 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "sertifika elde edilemedi: %s\n" -#: fe-secure.c:1400 -msgid "SSL certificate's common name contains embedded null\n" -msgstr "SSL sertifikasının ortak adı (common name) gömülü olarak null içeriyor\n" - -#: fe-secure.c:1476 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "SSL hatası raporlanmadı" -#: fe-secure.c:1485 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSL hata kodu: %lu" -#~ msgid "could not get home directory to locate client certificate files\n" -#~ msgstr "İstemci sertifika dosyalarının olduÄŸu ev dizini bulunamadı\n" +#: fe-secure.c:276 +#, c-format +msgid "could not receive data from server: %s\n" +msgstr "sunucudan veri alınamadı: %s\n" -#~ msgid "" -#~ "verified SSL connections are only supported when connecting to a host name" -#~ msgstr "" -#~ "Onaylanmış SSL baÄŸlantıları sadece bir sunucu adına baÄŸlanıldığı zaman " -#~ "geçerlidir" +#: fe-secure.c:392 +#, c-format +msgid "could not send data to server: %s\n" +msgstr "sunucuya veri gönderilemedi: %s\n" -#~ msgid "could not open private key file \"%s\": %s\n" -#~ msgstr "\"%s\" özel anahtar dosyası açılamadı: %s\n" +#: win32.c:317 +#, c-format +msgid "unrecognized socket error: 0x%08X/%d" +msgstr "bilinmeyen soket hatası: 0x%08X/%d" -#~ msgid "private key file \"%s\" changed during execution\n" -#~ msgstr "\"%s\" özel anahtar dosyası çalışma anında açılamadı\n" +#~ msgid "certificate could not be validated: %s\n" +#~ msgstr "sertifika doÄŸrulanamadı: %s\n" -#~ msgid "could not read private key file \"%s\": %s\n" -#~ msgstr "\"%s\" özel anahtar dosyası okunamadı: %s\n" +#~ msgid "private key file \"%s\" has wrong permissions\n" +#~ msgstr "\"%s\" özel anahtarı yanlış izinlere sahip\n" -#~ msgid "invalid sslverify value: \"%s\"\n" -#~ msgstr "geçersiz sslverify deÄŸeri: \"%s\"\n" +#~ msgid "invalid value of PGSSLKEY environment variable\n" +#~ msgstr "PGSSLKEY ortam deÄŸiÅŸkeni için geçersiz deÄŸer\n" -#~ msgid "root certificate file \"%s\" does not exist" -#~ msgstr "kök sertifika dosyası \"%s\" mevcut deÄŸildir" +#~ msgid "could not get user information\n" +#~ msgstr "kullanıcı bilgisi alınamadı\n" -#~ msgid "error querying socket: %s\n" -#~ msgstr "soketi sorgularken hata oluÅŸtu: %s\n" +#~ msgid "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n" +#~ msgstr "Sunucu ortak adı olan \"%s\" %ld.%ld.%ld.%ld adresine çözülemiyor\n" + +#~ msgid "unsupported protocol\n" +#~ msgstr "desteklenmeyen protokol\n" #~ msgid "could not get information about host \"%s\": %s\n" #~ msgstr "\"%s\" sunucusu hakkında bilgi alınamadı: %s\n" -#~ msgid "unsupported protocol\n" -#~ msgstr "desteklenmeyen protokol\n" +#~ msgid "error querying socket: %s\n" +#~ msgstr "soketi sorgularken hata oluÅŸtu: %s\n" -#~ msgid "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n" -#~ msgstr "" -#~ "Sunucu ortak adı olan \"%s\" %ld.%ld.%ld.%ld adresine çözülemiyor\n" +#~ msgid "root certificate file \"%s\" does not exist" +#~ msgstr "kök sertifika dosyası \"%s\" mevcut deÄŸildir" -#~ msgid "could not get user information\n" -#~ msgstr "kullanıcı bilgisi alınamadı\n" +#~ msgid "invalid sslverify value: \"%s\"\n" +#~ msgstr "geçersiz sslverify deÄŸeri: \"%s\"\n" -#~ msgid "invalid value of PGSSLKEY environment variable\n" -#~ msgstr "PGSSLKEY ortam deÄŸiÅŸkeni için geçersiz deÄŸer\n" +#~ msgid "could not read private key file \"%s\": %s\n" +#~ msgstr "\"%s\" özel anahtar dosyası okunamadı: %s\n" -#~ msgid "private key file \"%s\" has wrong permissions\n" -#~ msgstr "\"%s\" özel anahtarı yanlış izinlere sahip\n" +#~ msgid "private key file \"%s\" changed during execution\n" +#~ msgstr "\"%s\" özel anahtar dosyası çalışma anında açılamadı\n" -#~ msgid "certificate could not be validated: %s\n" -#~ msgstr "sertifika doÄŸrulanamadı: %s\n" +#~ msgid "could not open private key file \"%s\": %s\n" +#~ msgstr "\"%s\" özel anahtar dosyası açılamadı: %s\n" + +#~ msgid "verified SSL connections are only supported when connecting to a host name" +#~ msgstr "Onaylanmış SSL baÄŸlantıları sadece bir sunucu adına baÄŸlanıldığı zaman geçerlidir" + +#~ msgid "could not get home directory to locate client certificate files\n" +#~ msgstr "İstemci sertifika dosyalarının olduÄŸu ev dizini bulunamadı\n" + +#~ msgid "socket not open\n" +#~ msgstr "soket açık deÄŸil\n" + +#~ msgid "could not get home directory to locate service definition file" +#~ msgstr "servis dosyasının olduÄŸu ev dizini bulunamadı" + +#~ msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(SO_KEEPALIVE) baÅŸarısız oldu: %s\n" + +#~ msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPINTVL) baÅŸarısız oldu: %s\n" + +#~ msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" +#~ msgstr "setsockopt(SO_REUSEADDR) baÅŸarısız oldu: %s\n" + +#~ msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" +#~ msgstr "setsockopt(TCP_KEEPIDLE) baÅŸarısız oldu: %s\n" + +#~ msgid "could not restore non-blocking mode on socket: %s\n" +#~ msgstr "could not restore non-blocking mode on socket: %s\n" + +#~ msgid "Kerberos 5 authentication rejected: %*s\n" +#~ msgstr "Kerberos 5 yetkilendirmesi kabul edilmedi: %*s\n" + +#~ msgid "could not set socket to blocking mode: %s\n" +#~ msgstr "soket engelleme moduna ayarlanamadı: %s\n" + +#~ msgid "GSSAPI name import error" +#~ msgstr "GSSAPI ad aktarma hatası" diff --git a/src/interfaces/libpq/po/zh_CN.po b/src/interfaces/libpq/po/zh_CN.po index 189c3106ca7..7a99b35c8e4 100644 --- a/src/interfaces/libpq/po/zh_CN.po +++ b/src/interfaces/libpq/po/zh_CN.po @@ -3,124 +3,256 @@ # msgid "" msgstr "" -"Project-Id-Version: libpq (PostgreSQL 9.0)\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:38+0000\n" -"PO-Revision-Date: 2016-09-26 10:11-0400\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Chinese (Simplified) \n" +"Project-Id-Version: libpq (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:08+0000\n" +"PO-Revision-Date: 2019-05-17 17:10+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.7\n" -#: fe-auth.c:148 +#: fe-auth-scram.c:183 +msgid "malformed SCRAM message (empty message)\n" +msgstr "错误的SCRAM消æ¯ï¼ˆç©ºæ¶ˆæ¯ï¼‰\n" + +#: fe-auth-scram.c:189 +msgid "malformed SCRAM message (length mismatch)\n" +msgstr "错误的SCRAM消æ¯ï¼ˆé•¿åº¦ä¸åŒ¹é…)\n" + +#: fe-auth-scram.c:238 +msgid "incorrect server signature\n" +msgstr "æœåŠ¡å™¨ç­¾å䏿­£ç¡®\n" + +#: fe-auth-scram.c:247 +msgid "invalid SCRAM exchange state\n" +msgstr "SCRAM交æ¢çŠ¶æ€æ— æ•ˆ\n" + +#: fe-auth-scram.c:270 +#, c-format +msgid "malformed SCRAM message (attribute \"%c\" expected)\n" +msgstr "错误的SCRAM消æ¯ï¼ˆåº”为属性\"%c\")\n" + +#: fe-auth-scram.c:279 +#, c-format +msgid "malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n" +msgstr "错误的SCRAM消æ¯ï¼ˆå±žæ€§\"%c\"需è¦å­—符\"=\")\n" + +#: fe-auth-scram.c:320 +msgid "could not generate nonce\n" +msgstr "无法生æˆnonce\n" + +# fe-connect.c:2427 fe-connect.c:2436 fe-connect.c:2933 fe-exec.c:1284 +# fe-lobj.c:536 +#: fe-auth-scram.c:328 fe-auth-scram.c:395 fe-auth-scram.c:517 +#: fe-auth-scram.c:537 fe-auth-scram.c:563 fe-auth-scram.c:577 +#: fe-auth-scram.c:619 fe-auth.c:290 fe-auth.c:360 fe-auth.c:395 fe-auth.c:581 +#: fe-auth.c:740 fe-auth.c:1052 fe-auth.c:1200 fe-connect.c:858 +#: fe-connect.c:1320 fe-connect.c:1496 fe-connect.c:2085 fe-connect.c:2108 +#: fe-connect.c:2831 fe-connect.c:4513 fe-connect.c:4765 fe-connect.c:4884 +#: fe-connect.c:5134 fe-connect.c:5214 fe-connect.c:5313 fe-connect.c:5569 +#: fe-connect.c:5598 fe-connect.c:5670 fe-connect.c:5694 fe-connect.c:5712 +#: fe-connect.c:5813 fe-connect.c:5822 fe-connect.c:6178 fe-connect.c:6328 +#: fe-exec.c:2748 fe-exec.c:3495 fe-exec.c:3660 fe-lobj.c:895 +#: fe-protocol2.c:1213 fe-protocol3.c:999 fe-protocol3.c:1703 +#: fe-secure-common.c:110 fe-secure-openssl.c:438 fe-secure-openssl.c:1025 +msgid "out of memory\n" +msgstr "内存用尽\n" + +#: fe-auth-scram.c:555 +msgid "invalid SCRAM response (nonce mismatch)\n" +msgstr "SCRAMå“应无效(éžåŒ¹é…)\n" + +#: fe-auth-scram.c:594 +msgid "malformed SCRAM message (invalid iteration count)\n" +msgstr "错误的SCRAM消æ¯ï¼ˆè¿­ä»£è®¡æ•°æ— æ•ˆï¼‰\n" + +#: fe-auth-scram.c:600 +msgid "malformed SCRAM message (garbage at end of server-first-message)\n" +msgstr "错误的SCRAMæ¶ˆæ¯ (æœåŠ¡å™¨ç¬¬ä¸€æ¡æ¶ˆæ¯ç»“æŸæ—¶ä¸ºåžƒåœ¾æ¶ˆæ¯)\n" + +# fe-misc.c:515 fe-misc.c:595 +#: fe-auth-scram.c:630 +#, c-format +msgid "error received from server in SCRAM exchange: %s\n" +msgstr "在SCRAM交æ¢ä¸­ä»ŽæœåŠ¡å™¨æŽ¥æ”¶åˆ°é”™è¯¯: %s\n" + +#: fe-auth-scram.c:646 +msgid "malformed SCRAM message (garbage at end of server-final-message)\n" +msgstr "错误的SCRAMæ¶ˆæ¯ (æœåŠ¡å™¨æœ€åŽä¸€æ¡æ¶ˆæ¯ç»“æŸæ—¶ä¸ºåžƒåœ¾æ¶ˆæ¯)\n" + +#: fe-auth-scram.c:654 +msgid "malformed SCRAM message (invalid server signature)\n" +msgstr "错误的SCRAMæ¶ˆæ¯ (æœåŠ¡å™¨ç­¾åæ— æ•ˆ)\n" + +#: fe-auth.c:77 +#, c-format +msgid "out of memory allocating GSSAPI buffer (%d)\n" +msgstr "在分é…GSSAPI缓冲区(%d)时内存用尽\n" + +#: fe-auth.c:132 msgid "GSSAPI continuation error" msgstr "GSSAPI连续出现错误" -#: fe-auth.c:177 fe-auth.c:412 +#: fe-auth.c:159 fe-auth.c:389 fe-secure-common.c:98 msgid "host name must be specified\n" msgstr "必须指定主机å\n" -#: fe-auth.c:184 +#: fe-auth.c:166 msgid "duplicate GSS authentication request\n" msgstr "é‡å¤çš„GSS认è¯è¯·æ±‚\n" -# fe-connect.c:2427 fe-connect.c:2436 fe-connect.c:2933 fe-exec.c:1284 -# fe-lobj.c:536 -#: fe-auth.c:197 fe-auth.c:309 fe-auth.c:383 fe-auth.c:418 fe-auth.c:514 -#: fe-auth.c:780 fe-connect.c:707 fe-connect.c:904 fe-connect.c:1080 -#: fe-connect.c:2091 fe-connect.c:3484 fe-connect.c:3736 fe-connect.c:3855 -#: fe-connect.c:4095 fe-connect.c:4175 fe-connect.c:4274 fe-connect.c:4526 -#: fe-connect.c:4555 fe-connect.c:4627 fe-connect.c:4645 fe-connect.c:4741 -#: fe-connect.c:5075 fe-connect.c:5225 fe-exec.c:2634 fe-exec.c:3381 -#: fe-exec.c:3546 fe-lobj.c:896 fe-protocol2.c:1206 fe-protocol3.c:992 -#: fe-protocol3.c:1678 fe-secure-openssl.c:551 fe-secure-openssl.c:1093 -msgid "out of memory\n" -msgstr "内存用尽\n" - -#: fe-auth.c:210 -msgid "GSSAPI name import error" -msgstr "GSSAPIå称导入错误" +#: fe-auth.c:231 +#, c-format +msgid "out of memory allocating SSPI buffer (%d)\n" +msgstr "在分é…SSPI缓冲区(%d)时内存用尽\n" -#: fe-auth.c:298 +#: fe-auth.c:279 msgid "SSPI continuation error" msgstr "SSPI连续出现错误" -#: fe-auth.c:398 +#: fe-auth.c:350 +msgid "duplicate SSPI authentication request\n" +msgstr "é‡å¤çš„SSPI认è¯è¯·æ±‚\n" + +#: fe-auth.c:375 msgid "could not acquire SSPI credentials" msgstr "无法获得SSPIè¯ä¹¦" +#: fe-auth.c:429 +msgid "duplicate SASL authentication request\n" +msgstr "é‡å¤çš„SASL认è¯è¯·æ±‚\n" + +#: fe-auth.c:487 +msgid "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n" +msgstr "æœåŠ¡å™¨é€šè¿‡éžSSL连接æä¾›äº†SCRAM-SHA-256-PLUS身份验è¯\n" + +# fe-auth.c:595 +#: fe-auth.c:499 +msgid "none of the server's SASL authentication mechanisms are supported\n" +msgstr "䏿”¯æŒæœåŠ¡å™¨çš„SASLèº«ä»½éªŒè¯æœºåˆ¶\n" + +#: fe-auth.c:605 +#, c-format +msgid "out of memory allocating SASL buffer (%d)\n" +msgstr "在分é…SASL缓冲区(%d)时内存用尽\n" + +#: fe-auth.c:630 +msgid "AuthenticationSASLFinal received from server, but SASL authentication was not completed\n" +msgstr "从æœåŠ¡å™¨æŽ¥æ”¶åˆ°AuthenticationSASLFinal,但未完æˆSASL身份验è¯\n" + # fe-auth.c:503 -#: fe-auth.c:489 +#: fe-auth.c:707 msgid "SCM_CRED authentication method not supported\n" msgstr "䏿”¯æŒ SCM_CRED è®¤è¯æ–¹å¼\n" # fe-auth.c:595 -#: fe-auth.c:565 +#: fe-auth.c:798 msgid "Kerberos 4 authentication not supported\n" msgstr "䏿”¯æŒ Kerberos 4 认è¯\n" # fe-auth.c:612 -#: fe-auth.c:570 +#: fe-auth.c:803 msgid "Kerberos 5 authentication not supported\n" msgstr "䏿”¯æŒ Kerberos 5 认è¯\n" # fe-auth.c:595 -#: fe-auth.c:641 +#: fe-auth.c:874 msgid "GSSAPI authentication not supported\n" msgstr "䏿”¯æŒGSSAPI认è¯\n" # fe-auth.c:595 -#: fe-auth.c:673 +#: fe-auth.c:906 msgid "SSPI authentication not supported\n" msgstr "䏿”¯æŒSSPI认è¯\n" # fe-auth.c:595 -#: fe-auth.c:681 +#: fe-auth.c:914 msgid "Crypt authentication not supported\n" msgstr "䏿”¯æŒCrypt认è¯\n" # fe-auth.c:640 -#: fe-auth.c:708 +#: fe-auth.c:980 #, c-format msgid "authentication method %u not supported\n" msgstr "䏿”¯æŒ %u è®¤è¯æ–¹å¼\n" -#: fe-auth.c:755 +#: fe-auth.c:1027 #, c-format msgid "user name lookup failure: error code %lu\n" msgstr "ç”¨æˆ·åæŸ¥æ‰¾å¤±è´¥ï¼šé”™è¯¯ä»£ç %lu\n" -#: fe-auth.c:765 fe-connect.c:2018 +#: fe-auth.c:1037 fe-connect.c:2718 #, c-format msgid "could not look up local user ID %d: %s\n" msgstr "无法查找本地用户ID %d: %s\n" -#: fe-auth.c:770 fe-connect.c:2023 +#: fe-auth.c:1042 fe-connect.c:2723 #, c-format msgid "local user with ID %d does not exist\n" msgstr "ID 为 %d 的本地用户ä¸å­˜åœ¨\n" -#: fe-connect.c:846 +# fe-exec.c:1371 +#: fe-auth.c:1144 +msgid "unexpected shape of result set returned for SHOW\n" +msgstr "SHOW出现æ„外的结果状æ€\n" + +#: fe-auth.c:1153 +msgid "password_encryption value too long\n" +msgstr "密ç _加密值太长\n" + +#: fe-auth.c:1193 +#, c-format +msgid "unrecognized password encryption algorithm \"%s\"\n" +msgstr "无法识别的密ç åŠ å¯†ç®—æ³• \"%s\"\n" + +# fe-misc.c:702 +#: fe-connect.c:1041 +#, c-format +msgid "could not match %d host names to %d hostaddr values\n" +msgstr "无法将主机å %d ä¸Žä¸»æœºåœ°å€ %d匹é…\n" + +#: fe-connect.c:1117 +#, c-format +msgid "could not match %d port numbers to %d hosts\n" +msgstr "无法将端å£å· %d与主机%d匹é…\n" + +#: fe-connect.c:1213 #, c-format msgid "invalid sslmode value: \"%s\"\n" msgstr "无效的 sslmode 值: \"%s\"\n" -#: fe-connect.c:867 +#: fe-connect.c:1234 #, c-format msgid "sslmode value \"%s\" invalid when SSL support is not compiled in\n" msgstr "无效的 sslmode 值 \"%s\" 当没有把 SSL 支æŒç¼–è¯‘è¿›æ¥æ—¶\n" +#: fe-connect.c:1258 +#, fuzzy, c-format +#| msgid "invalid sslmode value: \"%s\"\n" +msgid "invalid gssencmode value: \"%s\"\n" +msgstr "无效的 sslmode 值: \"%s\"\n" + +#: fe-connect.c:1268 +msgid "no GSSAPI support; cannot require GSSAPI\n" +msgstr "" + +#: fe-connect.c:1302 +#, c-format +msgid "invalid target_session_attrs value: \"%s\"\n" +msgstr "无效的 target_session_attrs 值: \"%s\"\n" + # fe-connect.c:732 -#: fe-connect.c:1104 +#: fe-connect.c:1520 #, c-format msgid "could not set socket to TCP no delay mode: %s\n" msgstr "无法将套接字设置为 TCP 无延迟模å¼: %s\n" # fe-connect.c:752 -#: fe-connect.c:1134 +#: fe-connect.c:1583 #, c-format msgid "" "could not connect to server: %s\n" @@ -132,7 +264,7 @@ msgstr "" "\t\"%s\"上准备接å—è”æŽ¥?\n" # fe-connect.c:761 -#: fe-connect.c:1189 +#: fe-connect.c:1620 #, c-format msgid "" "could not connect to server: %s\n" @@ -144,7 +276,7 @@ msgstr "" "%s 上的 TCP/IP è”æŽ¥?\n" # fe-connect.c:761 -#: fe-connect.c:1198 +#: fe-connect.c:1628 #, c-format msgid "" "could not connect to server: %s\n" @@ -155,565 +287,598 @@ msgstr "" "\tæœåŠ¡å™¨æ˜¯å¦åœ¨ä¸»æœº \"%s\" 上è¿è¡Œå¹¶ä¸”准备接å—在端å£\n" "%s 上的 TCP/IP è”æŽ¥?\n" -#: fe-connect.c:1249 +#: fe-connect.c:1679 #, c-format -msgid "setsockopt(TCP_KEEPIDLE) failed: %s\n" -msgstr "执行setsockopt(TCP_KEEPIDLE)失败: %s\n" - -#: fe-connect.c:1262 -#, c-format -msgid "setsockopt(TCP_KEEPALIVE) failed: %s\n" -msgstr "执行setsockopt(TCP_KEEPALIVE)失败: %s\n" - -#: fe-connect.c:1294 -#, c-format -msgid "setsockopt(TCP_KEEPINTVL) failed: %s\n" -msgstr "执行setsockopt(TCP_KEEPINTVL)失败: %s\n" +msgid "invalid integer value \"%s\" for keyword \"%s\"\n" +msgstr "" -#: fe-connect.c:1326 +#: fe-connect.c:1709 fe-connect.c:1743 fe-connect.c:1778 fe-connect.c:1865 +#: fe-connect.c:2508 #, c-format -msgid "setsockopt(TCP_KEEPCNT) failed: %s\n" -msgstr "执行setsockopt(TCP_KEEPCNT) 失败: %s\n" +msgid "setsockopt(%s) failed: %s\n" +msgstr "执行setsockopt(%s) 失败: %s\n" -#: fe-connect.c:1374 +#: fe-connect.c:1831 #, c-format msgid "WSAIoctl(SIO_KEEPALIVE_VALS) failed: %ui\n" msgstr "执行WSAIoctl(SIO_KEEPALIVE_VALS)失败:%u\n" -#: fe-connect.c:1426 +# fe-connect.c:1232 +#: fe-connect.c:2199 +msgid "invalid connection state, probably indicative of memory corruption\n" +msgstr "æ— æ•ˆçš„è”æŽ¥çŠ¶æ€, å¯èƒ½æ˜¯å­˜å‚¨å™¨æ•°æ®è¢«ç ´å的标志\n" + +#: fe-connect.c:2267 #, c-format msgid "invalid port number: \"%s\"\n" msgstr "无效端å£å·: \"%s\"\n" -#: fe-connect.c:1459 -#, c-format -msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" -msgstr "Unix域的套接字路径\"%s\"è¶…é•¿(最大为%d字节)\n" - # fe-misc.c:702 -#: fe-connect.c:1478 +#: fe-connect.c:2283 #, c-format msgid "could not translate host name \"%s\" to address: %s\n" msgstr "无法解释主机å \"%s\" 到地å€: %s\n" +#: fe-connect.c:2296 +#, c-format +msgid "could not parse network address \"%s\": %s\n" +msgstr "无法分æžç½‘络地å€\"%s\": %s\n" + +#: fe-connect.c:2309 +#, c-format +msgid "Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n" +msgstr "Unix域的套接字路径\"%s\"è¶…é•¿(最大为%d字节)\n" + # fe-misc.c:702 -#: fe-connect.c:1482 +#: fe-connect.c:2324 #, c-format msgid "could not translate Unix-domain socket path \"%s\" to address: %s\n" msgstr "无法解释 Unix-domian 套接字路径 \"%s\" 到地å€: %s\n" -# fe-connect.c:1232 -#: fe-connect.c:1687 -msgid "invalid connection state, probably indicative of memory corruption\n" -msgstr "æ— æ•ˆçš„è”æŽ¥çŠ¶æ€, å¯èƒ½æ˜¯å­˜å‚¨å™¨æ•°æ®è¢«ç ´å的标志\n" - # fe-connect.c:891 -#: fe-connect.c:1727 +#: fe-connect.c:2445 #, c-format msgid "could not create socket: %s\n" msgstr "无法创建套接字: %s\n" # fe-connect.c:708 -#: fe-connect.c:1749 +#: fe-connect.c:2467 #, c-format msgid "could not set socket to nonblocking mode: %s\n" msgstr "无法设置套接字为éžé˜»å¡žæ¨¡å¼: %s\n" # fe-auth.c:395 -#: fe-connect.c:1760 +#: fe-connect.c:2477 #, c-format msgid "could not set socket to close-on-exec mode: %s\n" msgstr "无法将套接字设置为执行时关闭 (close-on-exec) 模å¼: %s\n" -#: fe-connect.c:1779 +#: fe-connect.c:2495 msgid "keepalives parameter must be an integer\n" msgstr "傿•°keepalives必须是一个整数\n" -#: fe-connect.c:1792 -#, c-format -msgid "setsockopt(SO_KEEPALIVE) failed: %s\n" -msgstr "执行setsockopt(SO_KEEPALIVE) 失败: %s\n" - # fe-connect.c:1263 -#: fe-connect.c:1929 +#: fe-connect.c:2635 #, c-format msgid "could not get socket error status: %s\n" msgstr "无法获å–套接字错误状æ€: %s\n" # fe-connect.c:1283 -#: fe-connect.c:1963 +#: fe-connect.c:2663 #, c-format msgid "could not get client address from socket: %s\n" msgstr "无法从套接字获å–客户端地å€: %s\n" -#: fe-connect.c:2005 +#: fe-connect.c:2705 msgid "requirepeer parameter is not supported on this platform\n" msgstr "在此平å°ä¸Šä¸æ”¯æŒrequirepeer傿•°\n" -#: fe-connect.c:2008 +#: fe-connect.c:2708 #, c-format msgid "could not get peer credentials: %s\n" msgstr "无法获得对等(peer)è¯ä¹¦:%s\n" -#: fe-connect.c:2031 +#: fe-connect.c:2731 #, c-format msgid "requirepeer specifies \"%s\", but actual peer user name is \"%s\"\n" msgstr "期望对方用户指定值为 \"%s\", 但实际的对方用户å为 \"%s\"\n" # fe-connect.c:959 -#: fe-connect.c:2065 +#: fe-connect.c:2766 +#, fuzzy, c-format +#| msgid "could not send SSL negotiation packet: %s\n" +msgid "could not send GSSAPI negotiation packet: %s\n" +msgstr "无法å‘é€ SSL æ¡æ‰‹åŒ…: %s\n" + +#: fe-connect.c:2778 +msgid "GSSAPI encryption required, but was impossible (possibly no ccache, no server support, or using a local socket)\n" +msgstr "" + +# fe-connect.c:959 +#: fe-connect.c:2805 #, c-format msgid "could not send SSL negotiation packet: %s\n" msgstr "无法å‘é€ SSL æ¡æ‰‹åŒ…: %s\n" # fe-connect.c:1322 -#: fe-connect.c:2104 +#: fe-connect.c:2844 #, c-format msgid "could not send startup packet: %s\n" msgstr "无法å‘é€å¯åŠ¨åŒ…: %s\n" # fe-connect.c:1010 -#: fe-connect.c:2174 +#: fe-connect.c:2914 msgid "server does not support SSL, but SSL was required\n" msgstr "æœåС噍䏿”¯æŒ SSL, ä½†æ˜¯è¦æ±‚使用 SSL\n" # fe-connect.c:1001 -#: fe-connect.c:2200 +#: fe-connect.c:2940 #, c-format msgid "received invalid response to SSL negotiation: %c\n" msgstr "收到对 SSL æ¡æ‰‹çš„æ— æ•ˆå“应: %c\n" +# fe-connect.c:1010 +#: fe-connect.c:3030 +#, fuzzy +#| msgid "server does not support SSL, but SSL was required\n" +msgid "server doesn't support GSSAPI encryption, but it was required\n" +msgstr "æœåС噍䏿”¯æŒ SSL, ä½†æ˜¯è¦æ±‚使用 SSL\n" + +# fe-connect.c:1001 +#: fe-connect.c:3041 +#, fuzzy, c-format +#| msgid "received invalid response to SSL negotiation: %c\n" +msgid "received invalid response to GSSAPI negotiation: %c\n" +msgstr "收到对 SSL æ¡æ‰‹çš„æ— æ•ˆå“应: %c\n" + # fe-connect.c:1378 -#: fe-connect.c:2275 fe-connect.c:2308 +#: fe-connect.c:3109 fe-connect.c:3142 #, c-format msgid "expected authentication request from server, but received %c\n" msgstr "期待æ¥è‡ªæœåŠ¡å™¨çš„è®¤è¯è¯·æ±‚, å´æ”¶åˆ° %c\n" -#: fe-connect.c:2475 -#, c-format -msgid "out of memory allocating GSSAPI buffer (%d)" -msgstr "在分é…GSSAPI缓冲区(%d)时内存用尽" - # fe-connect.c:1490 -#: fe-connect.c:2560 +#: fe-connect.c:3389 msgid "unexpected message from server during startup\n" msgstr "å¯åŠ¨è¿‡ç¨‹ä¸­æ”¶åˆ°æ¥è‡ªæœåŠ¡å™¨çš„éžé¢„期信æ¯\n" +#: fe-connect.c:3616 +#, c-format +msgid "could not make a writable connection to server \"%s:%s\"\n" +msgstr "无法与æœåŠ¡å™¨å»ºç«‹å¯å†™è¿žæŽ¥\"%s:%s\"\n" + +#: fe-connect.c:3662 +#, c-format +msgid "test \"SHOW transaction_read_only\" failed on server \"%s:%s\"\n" +msgstr "在æœåС噍\"%s:%s\"上测试\"SHOW transaction_read_only\"失败\n" + # fe-connect.c:1549 -#: fe-connect.c:2654 +#: fe-connect.c:3677 #, c-format msgid "invalid connection state %d, probably indicative of memory corruption\n" msgstr "æ— æ•ˆçš„è¿žæŽ¥çŠ¶æ€ %d, è¿™å¯èƒ½è¡¨ç¤ºå†…存出现问题\n" -#: fe-connect.c:3090 fe-connect.c:3150 +#: fe-connect.c:4119 fe-connect.c:4179 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n" msgstr "在PGEVT_CONNRESETäº‹ä»¶è§¦å‘æœŸé—´æ‰§è¡ŒPGEventProc \"%s\"错误\n" -#: fe-connect.c:3497 +#: fe-connect.c:4526 #, c-format msgid "invalid LDAP URL \"%s\": scheme must be ldap://\n" msgstr "无效LDAP URL\"%s\": 模å¼å¿…须是ldap://\n" -#: fe-connect.c:3512 +#: fe-connect.c:4541 #, c-format msgid "invalid LDAP URL \"%s\": missing distinguished name\n" msgstr "无效LDAP URL \"%s\": 丢失å¯åŒºåˆ†çš„åç§°\n" -#: fe-connect.c:3523 fe-connect.c:3576 +#: fe-connect.c:4552 fe-connect.c:4605 #, c-format msgid "invalid LDAP URL \"%s\": must have exactly one attribute\n" msgstr "无效LDAP URL \"%s\": åªèƒ½æœ‰ä¸€ä¸ªå±žæ€§\n" -#: fe-connect.c:3533 fe-connect.c:3590 +#: fe-connect.c:4562 fe-connect.c:4619 #, c-format msgid "invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n" msgstr "无效LDAP URL \"%s\": 必须有æœç´¢èŒƒå›´(base/one/sub)\n" -#: fe-connect.c:3544 +#: fe-connect.c:4573 #, c-format msgid "invalid LDAP URL \"%s\": no filter\n" msgstr "无效的 LDAP URL \"%s\": 没有过滤器\n" -#: fe-connect.c:3565 +#: fe-connect.c:4594 #, c-format msgid "invalid LDAP URL \"%s\": invalid port number\n" msgstr "无效LDAP URL \"%s\": 无效端å£å·\n" -#: fe-connect.c:3599 +#: fe-connect.c:4628 msgid "could not create LDAP structure\n" msgstr "无法创建LDAP结构\n" -#: fe-connect.c:3675 +#: fe-connect.c:4704 #, c-format msgid "lookup on LDAP server failed: %s\n" msgstr "在LDAPæœåŠ¡å™¨ä¸Šçš„æŸ¥æ‰¾å¤±è´¥: %s\n" -#: fe-connect.c:3686 +#: fe-connect.c:4715 msgid "more than one entry found on LDAP lookup\n" msgstr "在LDAPæœç´¢ä¸Šæ‰¾åˆ°å¤šä¸ªå…¥å£\n" -#: fe-connect.c:3687 fe-connect.c:3699 +#: fe-connect.c:4716 fe-connect.c:4728 msgid "no entry found on LDAP lookup\n" msgstr "在LDAP查找上没有å‘现入å£\n" -#: fe-connect.c:3710 fe-connect.c:3723 +#: fe-connect.c:4739 fe-connect.c:4752 msgid "attribute has no values on LDAP lookup\n" msgstr "在LDAP查找上的属性没有值\n" # fe-connect.c:2475 -#: fe-connect.c:3775 fe-connect.c:3794 fe-connect.c:4313 +#: fe-connect.c:4804 fe-connect.c:4823 fe-connect.c:5352 #, c-format msgid "missing \"=\" after \"%s\" in connection info string\n" msgstr "åœ¨è”æŽ¥ä¿¡æ¯å­—串里的 \"%s\" åŽé¢ç¼ºå°‘ \"=\"\n" # fe-connect.c:2558 -#: fe-connect.c:3867 fe-connect.c:4494 fe-connect.c:5208 +#: fe-connect.c:4896 fe-connect.c:5537 fe-connect.c:6311 #, c-format msgid "invalid connection option \"%s\"\n" msgstr "éžæ³•è”æŽ¥é€‰é¡¹ \"%s\"\n" # fe-connect.c:2524 -#: fe-connect.c:3883 fe-connect.c:4362 +#: fe-connect.c:4912 fe-connect.c:5401 msgid "unterminated quoted string in connection info string\n" msgstr "è”æŽ¥ä¿¡æ¯å­—串中未结æŸçš„引å·å­—串\n" -#: fe-connect.c:3923 -msgid "could not get home directory to locate service definition file" -msgstr "无法进入home目录æ¥å®šä½æœåŠ¡å®šä¹‰æ–‡ä»¶" - -#: fe-connect.c:3956 +#: fe-connect.c:4995 #, c-format msgid "definition of service \"%s\" not found\n" msgstr "错误:没有找到æœåŠ¡\"%s\"的定义\n" -#: fe-connect.c:3979 +#: fe-connect.c:5018 #, c-format msgid "service file \"%s\" not found\n" msgstr "错误:没有找到æœåŠ¡æ–‡ä»¶\"%s\"\n" -#: fe-connect.c:3992 +#: fe-connect.c:5031 #, c-format msgid "line %d too long in service file \"%s\"\n" msgstr "在æœåŠ¡æ–‡ä»¶\"%2$s\"中的第%1$d行的长度太长\n" -#: fe-connect.c:4063 fe-connect.c:4107 +#: fe-connect.c:5102 fe-connect.c:5146 #, c-format msgid "syntax error in service file \"%s\", line %d\n" msgstr "在æœåŠ¡æ–‡ä»¶\"%s\"的第%d行出现语法错误\n" -#: fe-connect.c:4074 +#: fe-connect.c:5113 #, c-format -msgid "" -"nested service specifications not supported in service file \"%s\", line %d\n" +msgid "nested service specifications not supported in service file \"%s\", line %d\n" msgstr "在æœåŠ¡æ–‡ä»¶\"%s\"的第%dè¡Œå‡ºçŽ°ä¸æ”¯æŒçš„嵌套æœåŠ¡è¯´æ˜Ž\n" -#: fe-connect.c:4752 +#: fe-connect.c:5833 #, c-format msgid "invalid URI propagated to internal parser routine: \"%s\"\n" msgstr "无效的URI传入内部解æžå™¨å¤„ç†ç¨‹åº: \"%s\"\n" -#: fe-connect.c:4822 +#: fe-connect.c:5910 #, c-format -msgid "" -"end of string reached when looking for matching \"]\" in IPv6 host address " -"in URI: \"%s\"\n" +msgid "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n" msgstr "在 URI: \"%s\"中的IPv6主机地å€é‡ŒæŸ¥æ‰¾åŒ¹é…符\"]\"æ—¶é‡åˆ°äº†å­—符串结æŸç¬¦\n" -#: fe-connect.c:4829 +#: fe-connect.c:5917 #, c-format msgid "IPv6 host address may not be empty in URI: \"%s\"\n" msgstr "URI:\"%s\"中的IPv6主机地å€å¯èƒ½ä¸ä¸ºç©º\n" -#: fe-connect.c:4844 +#: fe-connect.c:5932 #, c-format -msgid "" -"unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): " -"\"%s\"\n" -msgstr "" -"éžé¢„期的字符\"%c\"出现在在ä½ç½®%d, URI (expected \":\" or \"/\"):\"%s\"\n" +msgid "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n" +msgstr "éžé¢„期的字符\"%c\"出现在在ä½ç½®%d, URI (expected \":\" or \"/\"):\"%s\"\n" -#: fe-connect.c:4958 +#: fe-connect.c:6061 #, c-format msgid "extra key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "é‡åˆ°å¤šä½™çš„é”®/值分隔符\"=\"在URIæŸ¥è¯¢å‚æ•°é‡Œ: \"%s\"\n" -#: fe-connect.c:4978 +#: fe-connect.c:6081 #, c-format msgid "missing key/value separator \"=\" in URI query parameter: \"%s\"\n" msgstr "缺少相应的键/值分隔符\"=\"在URIæŸ¥è¯¢å‚æ•°é‡Œ: \"%s\"\n" -#: fe-connect.c:5029 +#: fe-connect.c:6132 #, c-format msgid "invalid URI query parameter: \"%s\"\n" msgstr "无效的URIæŸ¥è¯¢å‚æ•°: \"%s\"\n" # fe-connect.c:2558 -#: fe-connect.c:5103 +#: fe-connect.c:6206 #, c-format msgid "invalid percent-encoded token: \"%s\"\n" msgstr "无效的百分å·ç¼–ç ä»¤ç‰Œ: \"%s\"\n" -#: fe-connect.c:5113 +#: fe-connect.c:6216 #, c-format msgid "forbidden value %%00 in percent-encoded value: \"%s\"\n" msgstr "在百分值编ç çš„值: \"%s\"é‡Œç¦æ­¢ä½¿ç”¨ %%00\n" # fe-connect.c:2744 -#: fe-connect.c:5447 +#: fe-connect.c:6581 msgid "connection pointer is NULL\n" msgstr "è”æŽ¥æŒ‡é’ˆæ˜¯ NULL\n" -#: fe-connect.c:5745 +#: fe-connect.c:6879 #, c-format msgid "WARNING: password file \"%s\" is not a plain file\n" msgstr "警告: å£ä»¤æ–‡ä»¶\"%s\"䏿˜¯æ™®é€šæ–‡æœ¬æ–‡ä»¶\n" # fe-connect.c:2953 -#: fe-connect.c:5754 +#: fe-connect.c:6888 #, c-format -msgid "" -"WARNING: password file \"%s\" has group or world access; permissions should " -"be u=rw (0600) or less\n" +msgid "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "警告: å£ä»¤æ–‡ä»¶\"%s\"的访问æƒé™è¿‡å¤§; æƒé™åº”设置 为 u=rw (0600)或更少\n" -#: fe-connect.c:5860 +#: fe-connect.c:6982 #, c-format msgid "password retrieved from file \"%s\"\n" msgstr "从文件\"%s\"中获å–å£ä»¤\n" -#: fe-exec.c:826 +# fe-exec.c:2130 +#: fe-exec.c:445 fe-exec.c:2822 +#, c-format +msgid "row number %d is out of range 0..%d" +msgstr "行å·ç  %d 超出了范围 0..%d" + +#: fe-exec.c:506 fe-protocol2.c:502 fe-protocol2.c:537 fe-protocol2.c:1056 +#: fe-protocol3.c:208 fe-protocol3.c:235 fe-protocol3.c:252 fe-protocol3.c:332 +#: fe-protocol3.c:727 fe-protocol3.c:958 +msgid "out of memory" +msgstr "内存用尽" + +#: fe-exec.c:507 fe-protocol2.c:1402 fe-protocol3.c:1911 +#, c-format +msgid "%s" +msgstr "%s" + +#: fe-exec.c:816 +#, fuzzy +#| msgid "lookup on LDAP server failed: %s\n" +msgid "write to server failed\n" +msgstr "在LDAPæœåŠ¡å™¨ä¸Šçš„æŸ¥æ‰¾å¤±è´¥: %s\n" + +#: fe-exec.c:897 msgid "NOTICE" msgstr "注æ„" +#: fe-exec.c:955 +msgid "PGresult cannot support more than INT_MAX tuples" +msgstr "PGresultä¸èƒ½æ”¯æŒè¶…过INT_MAX元组" + +#: fe-exec.c:967 +msgid "size_t overflow" +msgstr "size_t溢出" + # fe-exec.c:737 -#: fe-exec.c:1123 fe-exec.c:1181 fe-exec.c:1227 +#: fe-exec.c:1244 fe-exec.c:1302 fe-exec.c:1348 msgid "command string is a null pointer\n" msgstr "命令字串是一个空指针\n" -#: fe-exec.c:1187 fe-exec.c:1233 fe-exec.c:1328 +#: fe-exec.c:1308 fe-exec.c:1354 fe-exec.c:1449 msgid "number of parameters must be between 0 and 65535\n" msgstr "傿•°çš„个数必须介于0到65535之间\n" # fe-exec.c:737 -#: fe-exec.c:1221 fe-exec.c:1322 +#: fe-exec.c:1342 fe-exec.c:1443 msgid "statement name is a null pointer\n" msgstr "声明å字是一个空指针\n" -#: fe-exec.c:1241 fe-exec.c:1405 fe-exec.c:2123 fe-exec.c:2322 +#: fe-exec.c:1362 fe-exec.c:1525 fe-exec.c:2234 fe-exec.c:2436 msgid "function requires at least protocol version 3.0\n" msgstr "å‡½æ•°è‡³å°‘éœ€è¦ 3.0 版本的åè®®\n" # fe-exec.c:745 -#: fe-exec.c:1359 +#: fe-exec.c:1480 msgid "no connection to the server\n" msgstr "没有到æœåŠ¡å™¨çš„è”æŽ¥\n" # fe-exec.c:752 -#: fe-exec.c:1366 +#: fe-exec.c:1487 msgid "another command is already in progress\n" msgstr "å·²ç»æœ‰å¦å¤–一æ¡å‘½ä»¤åœ¨å¤„ç†\n" -#: fe-exec.c:1481 +#: fe-exec.c:1601 msgid "length must be given for binary parameter\n" msgstr "对于2è¿›åˆ¶å‚æ•°å¿…须指定长度\n" # fe-exec.c:1371 -#: fe-exec.c:1753 +#: fe-exec.c:1864 #, c-format msgid "unexpected asyncStatus: %d\n" msgstr "æ„外的 asyncStatus(异步状æ€): %d\n" -#: fe-exec.c:1773 +#: fe-exec.c:1884 #, c-format msgid "PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n" msgstr "在PGEVT_CONNRESETäº‹ä»¶è§¦å‘æœŸé—´æ‰§è¡ŒPGEventProc \"%s\"错误\n" -#: fe-exec.c:1933 +#: fe-exec.c:2044 msgid "COPY terminated by new PQexec" msgstr "COPY 被一个新的 PQexec 终止" # fe-exec.c:1421 -#: fe-exec.c:1941 +#: fe-exec.c:2052 msgid "COPY IN state must be terminated first\n" msgstr "COPY IN 状æ€å¿…须先结æŸ\n" # fe-exec.c:1421 -#: fe-exec.c:1961 +#: fe-exec.c:2072 msgid "COPY OUT state must be terminated first\n" msgstr "COPY OUT 状æ€å¿…须先结æŸ\n" -#: fe-exec.c:1969 +#: fe-exec.c:2080 msgid "PQexec not allowed during COPY BOTH\n" msgstr "在 COPY BOTHæ—¶ä¸å…许调用PQexec\n" # fe-exec.c:1780 -#: fe-exec.c:2212 fe-exec.c:2279 fe-exec.c:2369 fe-protocol2.c:1352 -#: fe-protocol3.c:1817 +#: fe-exec.c:2326 fe-exec.c:2393 fe-exec.c:2483 fe-protocol2.c:1359 +#: fe-protocol3.c:1842 msgid "no COPY in progress\n" msgstr "没有正在处ç†çš„ COPY\n" # fe-exec.c:1884 -#: fe-exec.c:2559 +#: fe-exec.c:2673 msgid "connection in wrong state\n" msgstr "è”æŽ¥å¤„äºŽé”™è¯¯çŠ¶æ€\n" # fe-exec.c:2055 -#: fe-exec.c:2590 +#: fe-exec.c:2704 msgid "invalid ExecStatusType code" msgstr "éžæ³• ExecStatusType 代ç " -#: fe-exec.c:2617 -#| msgid "result is out of range" +#: fe-exec.c:2731 msgid "PGresult is not an error result\n" msgstr "PGresult䏿˜¯é”™è¯¯çš„结果\n" # fe-exec.c:2108 fe-exec.c:2141 -#: fe-exec.c:2692 fe-exec.c:2715 +#: fe-exec.c:2806 fe-exec.c:2829 #, c-format msgid "column number %d is out of range 0..%d" msgstr "列å·ç  %d 超出了范围 0..%d" # fe-exec.c:2130 -#: fe-exec.c:2708 -#, c-format -msgid "row number %d is out of range 0..%d" -msgstr "行å·ç  %d 超出了范围 0..%d" - -# fe-exec.c:2130 -#: fe-exec.c:2730 +#: fe-exec.c:2844 #, c-format msgid "parameter number %d is out of range 0..%d" msgstr "傿•°å·%d超出了范围 0..%d" # fe-exec.c:2325 -#: fe-exec.c:3040 +#: fe-exec.c:3154 #, c-format msgid "could not interpret result from server: %s" msgstr "无法解释æ¥è‡ªæœåŠ¡å™¨çš„ç»“æžœ: %s" -#: fe-exec.c:3279 fe-exec.c:3363 +#: fe-exec.c:3393 fe-exec.c:3477 msgid "incomplete multibyte character\n" msgstr "无效的多字节字符\n" # fe-lobj.c:616 -#: fe-lobj.c:155 +#: fe-lobj.c:154 msgid "cannot determine OID of function lo_truncate\n" msgstr "无法确定函数 lo_creat çš„ OID\n" -#: fe-lobj.c:171 +#: fe-lobj.c:170 msgid "argument of lo_truncate exceeds integer range\n" msgstr "lo_truncateçš„å‚æ•°è¶…出整数范围\n" # fe-lobj.c:616 -#: fe-lobj.c:222 +#: fe-lobj.c:221 msgid "cannot determine OID of function lo_truncate64\n" msgstr "无法确定函数lo_truncate64çš„OID值\n" -#: fe-lobj.c:280 +#: fe-lobj.c:279 msgid "argument of lo_read exceeds integer range\n" msgstr "lo_readçš„å‚æ•°å€¼å·²è¶…出整数范围\n" -#: fe-lobj.c:335 +#: fe-lobj.c:334 msgid "argument of lo_write exceeds integer range\n" msgstr "lo_writeçš„å‚æ•°å€¼å·²è¶…出整数范围\n" # fe-lobj.c:630 -#: fe-lobj.c:426 +#: fe-lobj.c:425 msgid "cannot determine OID of function lo_lseek64\n" msgstr "无法确定函数lo_lseek64çš„OID值\n" # fe-lobj.c:616 -#: fe-lobj.c:522 +#: fe-lobj.c:521 msgid "cannot determine OID of function lo_create\n" msgstr "无法确定函数 lo_creat çš„ OID\n" # fe-lobj.c:637 -#: fe-lobj.c:601 +#: fe-lobj.c:600 msgid "cannot determine OID of function lo_tell64\n" msgstr "无法确定函数lo_tell64çš„OID值\n" # fe-lobj.c:400 fe-lobj.c:483 -#: fe-lobj.c:707 fe-lobj.c:816 +#: fe-lobj.c:706 fe-lobj.c:815 #, c-format msgid "could not open file \"%s\": %s\n" msgstr "无法打开文件 \"%s\": %s\n" -#: fe-lobj.c:762 +#: fe-lobj.c:761 #, c-format msgid "could not read from file \"%s\": %s\n" msgstr "æ— æ³•è¯»å–æ–‡ä»¶ \"%s\": %s\n" -#: fe-lobj.c:836 fe-lobj.c:860 +#: fe-lobj.c:835 fe-lobj.c:859 #, c-format msgid "could not write to file \"%s\": %s\n" msgstr "无法写入文件 \"%s\": %s\n" # fe-lobj.c:564 -#: fe-lobj.c:947 +#: fe-lobj.c:946 msgid "query to initialize large object functions did not return data\n" msgstr "åˆå§‹åŒ–大对象函数的查询没有返回数æ®\n" # fe-lobj.c:602 -#: fe-lobj.c:996 +#: fe-lobj.c:995 msgid "cannot determine OID of function lo_open\n" msgstr "无法判断函数 lo_open çš„ OID\n" # fe-lobj.c:609 -#: fe-lobj.c:1003 +#: fe-lobj.c:1002 msgid "cannot determine OID of function lo_close\n" msgstr "无法判断函数 lo_close çš„ OID\n" # fe-lobj.c:616 -#: fe-lobj.c:1010 +#: fe-lobj.c:1009 msgid "cannot determine OID of function lo_creat\n" msgstr "无法判断函数 lo_creat çš„ OID\n" # fe-lobj.c:623 -#: fe-lobj.c:1017 +#: fe-lobj.c:1016 msgid "cannot determine OID of function lo_unlink\n" msgstr "无法判断函数 lo_unlink çš„ OID\n" # fe-lobj.c:630 -#: fe-lobj.c:1024 +#: fe-lobj.c:1023 msgid "cannot determine OID of function lo_lseek\n" msgstr "无法判断函数 lo_lseek çš„ OID\n" # fe-lobj.c:637 -#: fe-lobj.c:1031 +#: fe-lobj.c:1030 msgid "cannot determine OID of function lo_tell\n" msgstr "无法判断函数 lo_tell çš„ OID\n" # fe-lobj.c:644 -#: fe-lobj.c:1038 +#: fe-lobj.c:1037 msgid "cannot determine OID of function loread\n" msgstr "无法判断函数 loread çš„ OID\n" # fe-lobj.c:651 -#: fe-lobj.c:1045 +#: fe-lobj.c:1044 msgid "cannot determine OID of function lowrite\n" msgstr "无法判断函数 lowrite çš„ OID\n" # fe-misc.c:303 -#: fe-misc.c:295 +#: fe-misc.c:290 #, c-format msgid "integer of size %lu not supported by pqGetInt" msgstr "pqGetInt 䏿”¯æŒå¤§å°ä¸º %lu 的整数" # fe-misc.c:341 -#: fe-misc.c:331 +#: fe-misc.c:326 #, c-format msgid "integer of size %lu not supported by pqPutInt" msgstr "pqPutInt 䏿”¯æŒå¤§å°ä¸º %lu 的整数" # fe-misc.c:450 fe-misc.c:642 fe-misc.c:798 -#: fe-misc.c:642 fe-misc.c:843 +#: fe-misc.c:637 fe-misc.c:859 msgid "connection not open\n" msgstr "è”æŽ¥æœªæ‰“å¼€\n" # fe-misc.c:612 fe-misc.c:686 -#: fe-misc.c:812 fe-secure-openssl.c:270 fe-secure-openssl.c:379 -#: fe-secure.c:253 fe-secure.c:362 +#: fe-misc.c:807 fe-secure-openssl.c:206 fe-secure-openssl.c:314 +#: fe-secure.c:268 fe-secure.c:385 msgid "" "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" @@ -723,389 +888,367 @@ msgstr "" "\tè¿™ç§çŽ°è±¡é€šå¸¸æ„å‘³ç€æœåŠ¡å™¨åœ¨å¤„ç†è¯·æ±‚之å‰\n" "或者正在处ç†è¯·æ±‚的时候æ„外中止\n" -#: fe-misc.c:1016 +#: fe-misc.c:1046 msgid "timeout expired\n" msgstr "超时满\n" -#: fe-misc.c:1061 -#| msgid "invalid symbol" +#: fe-misc.c:1091 msgid "invalid socket\n" msgstr "无效套接字\n" # fe-misc.c:389 fe-misc.c:423 fe-misc.c:838 -#: fe-misc.c:1084 +#: fe-misc.c:1114 #, c-format msgid "select() failed: %s\n" msgstr "select() 失败: %s\n" # fe-connect.c:1549 -#: fe-protocol2.c:91 +#: fe-protocol2.c:90 #, c-format msgid "invalid setenv state %c, probably indicative of memory corruption\n" msgstr "无效的 setenv çŠ¶æ€ %c, å¯èƒ½æ˜¯å†…存被破å\n" # fe-connect.c:1549 -#: fe-protocol2.c:390 +#: fe-protocol2.c:389 #, c-format msgid "invalid state %c, probably indicative of memory corruption\n" msgstr "æ— æ•ˆçŠ¶æ€ %c, å¯èƒ½æ˜¯å†…存被破å\n" -#: fe-protocol2.c:479 fe-protocol3.c:186 +#: fe-protocol2.c:478 fe-protocol3.c:185 #, c-format msgid "message type 0x%02x arrived from server while idle" msgstr "当空闲时收到æœåŠ¡èµ·å‘é€è¿‡æ¥çš„æ¶ˆæ¯ç±»åž‹ 0x%02x" -#: fe-protocol2.c:503 fe-protocol2.c:538 fe-protocol2.c:1049 -#: fe-protocol3.c:209 fe-protocol3.c:236 fe-protocol3.c:253 fe-protocol3.c:333 -#: fe-protocol3.c:728 fe-protocol3.c:951 -msgid "out of memory" -msgstr "内存用尽" - -#: fe-protocol2.c:529 +#: fe-protocol2.c:528 #, c-format msgid "unexpected character %c following empty query response (\"I\" message)" msgstr "unexpected character %c following empty query response (\"I\" message)" -#: fe-protocol2.c:595 +#: fe-protocol2.c:594 #, c-format -msgid "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)" -msgstr "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)" +msgid "server sent data (\"D\" message) without prior row description (\"T\" message)" +msgstr "server sent data (\"D\" message) without prior row description (\"T\" message)" -#: fe-protocol2.c:613 +#: fe-protocol2.c:612 #, c-format -msgid "" -"server sent binary data (\"B\" message) without prior row description (\"T\" " -"message)" -msgstr "" -"server sent binary data (\"B\" message) without prior row description (\"T\" " -"message)" +msgid "server sent binary data (\"B\" message) without prior row description (\"T\" message)" +msgstr "server sent binary data (\"B\" message) without prior row description (\"T\" message)" # fe-connect.c:1378 -#: fe-protocol2.c:633 fe-protocol3.c:412 +#: fe-protocol2.c:632 fe-protocol3.c:411 #, c-format msgid "unexpected response from server; first received character was \"%c\"\n" msgstr "æ¥è‡ªæœåС噍æ„外的回执, 第一个收到的字符是 \"%c\"\n" # fe-connect.c:2427 fe-connect.c:2436 fe-connect.c:2933 fe-exec.c:1284 # fe-lobj.c:536 -#: fe-protocol2.c:762 fe-protocol2.c:937 fe-protocol3.c:627 fe-protocol3.c:854 +#: fe-protocol2.c:761 fe-protocol2.c:936 fe-protocol3.c:626 fe-protocol3.c:853 msgid "out of memory for query result" msgstr "查询结果时内存耗尽" -#: fe-protocol2.c:1395 fe-protocol3.c:1886 -#, c-format -msgid "%s" -msgstr "%s" - -#: fe-protocol2.c:1407 +#: fe-protocol2.c:1414 #, c-format msgid "lost synchronization with server, resetting connection" msgstr "失去与æœåŠ¡å™¨åŒæ­¥, é‡ç½®è¿žæŽ¥" -#: fe-protocol2.c:1541 fe-protocol2.c:1573 fe-protocol3.c:2089 +#: fe-protocol2.c:1536 fe-protocol2.c:1568 fe-protocol3.c:2099 #, c-format msgid "protocol error: id=0x%x\n" msgstr "å议错误: id=0x%x\n" -#: fe-protocol3.c:368 -msgid "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)\n" -msgstr "" -"server sent data (\"D\" message) without prior row description (\"T\" " -"message)\n" +#: fe-protocol3.c:367 +msgid "server sent data (\"D\" message) without prior row description (\"T\" message)\n" +msgstr "server sent data (\"D\" message) without prior row description (\"T\" message)\n" -#: fe-protocol3.c:433 +#: fe-protocol3.c:432 #, c-format msgid "message contents do not agree with length in message type \"%c\"\n" msgstr "在消æ¯ç±»åž‹ \"%c\" 中, 消æ¯å†…容与长度ä¸åŒ¹é…\n" -#: fe-protocol3.c:454 +#: fe-protocol3.c:453 #, c-format msgid "lost synchronization with server: got message type \"%c\", length %d\n" msgstr "失去与æœåŠ¡å™¨åŒæ­¥: 获å–到消æ¯ç±»åž‹ \"%c\", 长度 %d\n" -#: fe-protocol3.c:505 fe-protocol3.c:545 +#: fe-protocol3.c:504 fe-protocol3.c:544 msgid "insufficient data in \"T\" message" msgstr "\"T\"消æ¯ä¸­å‰©ä¸‹çš„æ•°æ®ä¸å¤Ÿ" -#: fe-protocol3.c:578 +#: fe-protocol3.c:577 msgid "extraneous data in \"T\" message" msgstr "\"T\"消æ¯ä¸­æœ‰æ— å…³çš„æ•°æ®" -#: fe-protocol3.c:691 -#| msgid "extraneous data in \"T\" message" +#: fe-protocol3.c:690 msgid "extraneous data in \"t\" message" msgstr "\"t\"消æ¯ä¸­æœ‰æ— å…³çš„æ•°æ®" -#: fe-protocol3.c:762 fe-protocol3.c:794 fe-protocol3.c:812 +#: fe-protocol3.c:761 fe-protocol3.c:793 fe-protocol3.c:811 msgid "insufficient data in \"D\" message" msgstr "\"D\"消æ¯ä¸­å‰©ä¸‹çš„æ•°æ®ä¸å¤Ÿ" -#: fe-protocol3.c:768 +#: fe-protocol3.c:767 msgid "unexpected field count in \"D\" message" msgstr "在 \"D\" 消æ¯ä¸­, æ„外的字段个数" -#: fe-protocol3.c:821 +#: fe-protocol3.c:820 msgid "extraneous data in \"D\" message" msgstr "\"D\"消æ¯ä¸­å·²ç»æ²¡æœ‰æ•°æ®äº†" # startup.c:502 -#: fe-protocol3.c:1005 -#| msgid "\\%s: error while setting variable\n" +#: fe-protocol3.c:1012 msgid "no error message available\n" msgstr "没有å¯ç”¨çš„错误消æ¯\n" #. translator: %s represents a digit string -#: fe-protocol3.c:1035 fe-protocol3.c:1054 +#: fe-protocol3.c:1060 fe-protocol3.c:1079 #, c-format msgid " at character %s" msgstr " 在字符 %s" -#: fe-protocol3.c:1067 +#: fe-protocol3.c:1092 #, c-format msgid "DETAIL: %s\n" msgstr "æè¿°: %s\n" -#: fe-protocol3.c:1070 +#: fe-protocol3.c:1095 #, c-format msgid "HINT: %s\n" msgstr "æç¤º: %s\n" -#: fe-protocol3.c:1073 +#: fe-protocol3.c:1098 #, c-format msgid "QUERY: %s\n" msgstr "查询: %s\n" -#: fe-protocol3.c:1080 +#: fe-protocol3.c:1105 #, c-format msgid "CONTEXT: %s\n" msgstr "背景: %s\n" -#: fe-protocol3.c:1089 +#: fe-protocol3.c:1114 #, c-format msgid "SCHEMA NAME: %s\n" msgstr "方案å: %s\n" -#: fe-protocol3.c:1093 +#: fe-protocol3.c:1118 #, c-format msgid "TABLE NAME: %s\n" msgstr "表å: %s\n" -#: fe-protocol3.c:1097 +#: fe-protocol3.c:1122 #, c-format msgid "COLUMN NAME: %s\n" msgstr "列å: %s\n" -#: fe-protocol3.c:1101 +#: fe-protocol3.c:1126 #, c-format msgid "DATATYPE NAME: %s\n" msgstr "æ•°æ®ç±»åž‹å: %s\n" -#: fe-protocol3.c:1105 +#: fe-protocol3.c:1130 #, c-format msgid "CONSTRAINT NAME: %s\n" msgstr "约æŸå: %s\n" -#: fe-protocol3.c:1117 +#: fe-protocol3.c:1142 msgid "LOCATION: " msgstr "ä½ç½®: " -#: fe-protocol3.c:1119 +#: fe-protocol3.c:1144 #, c-format msgid "%s, " msgstr "%s, " -#: fe-protocol3.c:1121 +#: fe-protocol3.c:1146 #, c-format msgid "%s:%s" msgstr "%s:%s" -#: fe-protocol3.c:1316 +#: fe-protocol3.c:1341 #, c-format msgid "LINE %d: " msgstr "第%d行" -#: fe-protocol3.c:1711 +#: fe-protocol3.c:1736 msgid "PQgetline: not doing text COPY OUT\n" msgstr "PQgetline: not doing text COPY OUT\n" -#: fe-secure-openssl.c:146 fe-secure-openssl.c:1030 fe-secure-openssl.c:1250 -#, c-format -msgid "could not acquire mutex: %s\n" -msgstr "无法获å–互斥é”(mutex): %s\n" +#: fe-secure-common.c:124 +msgid "SSL certificate's name contains embedded null\n" +msgstr "SSLè¯ä¹¦çš„å称包å«åµŒå…¥çš„空值\n" + +#: fe-secure-common.c:171 +msgid "host name must be specified for a verified SSL connection\n" +msgstr "必须为一个已验è¯çš„SSL连接指定主机å\n" -#: fe-secure-openssl.c:158 +#: fe-secure-common.c:196 #, c-format -msgid "could not establish SSL connection: %s\n" -msgstr "无法建立 SSL è”æŽ¥: %s\n" +msgid "server certificate for \"%s\" does not match host name \"%s\"\n" +msgstr "\"%s\"çš„æœåС噍è¯ä¹¦ä¸Žä¸»æœºåä¸åŒ¹é…\"%s\"\n" + +#: fe-secure-common.c:202 +msgid "could not get server's host name from server certificate\n" +msgstr "无法从æœåС噍è¯ä¹¦å¾—到æœåŠ¡å™¨çš„ä¸»æœºå\n" -#: fe-secure-openssl.c:275 fe-secure-openssl.c:384 fe-secure-openssl.c:1376 +#: fe-secure-openssl.c:211 fe-secure-openssl.c:319 fe-secure-openssl.c:1219 #, c-format msgid "SSL SYSCALL error: %s\n" msgstr "SSL SYSCALL 错误: %s\n" -#: fe-secure-openssl.c:282 fe-secure-openssl.c:391 fe-secure-openssl.c:1380 +#: fe-secure-openssl.c:218 fe-secure-openssl.c:326 fe-secure-openssl.c:1223 msgid "SSL SYSCALL error: EOF detected\n" msgstr "SSL SYSCALL 错误: å‘现结æŸç¬¦\n" # fe-auth.c:232 -#: fe-secure-openssl.c:293 fe-secure-openssl.c:402 fe-secure-openssl.c:1389 +#: fe-secure-openssl.c:229 fe-secure-openssl.c:337 fe-secure-openssl.c:1232 #, c-format msgid "SSL error: %s\n" msgstr "SSL 错误: %s\n" -#: fe-secure-openssl.c:308 fe-secure-openssl.c:417 +#: fe-secure-openssl.c:244 fe-secure-openssl.c:352 msgid "SSL connection has been closed unexpectedly\n" msgstr "SSL连接异常关闭\n" -#: fe-secure-openssl.c:314 fe-secure-openssl.c:423 fe-secure-openssl.c:1398 +#: fe-secure-openssl.c:250 fe-secure-openssl.c:358 fe-secure-openssl.c:1241 #, c-format msgid "unrecognized SSL error code: %d\n" msgstr "未知的 SSL 错误ç : %d\n" -#: fe-secure-openssl.c:535 +#: fe-secure-openssl.c:398 +msgid "could not determine server certificate signature algorithm\n" +msgstr "无法确定æœåС噍è¯ä¹¦ç­¾å算法\n" + +#: fe-secure-openssl.c:419 +#, c-format +msgid "could not find digest for NID %s\n" +msgstr "找ä¸åˆ°NID %s的摘è¦\n" + +#: fe-secure-openssl.c:429 +msgid "could not generate peer certificate hash\n" +msgstr "无法生æˆå¯¹ç­‰è¯ä¹¦å“ˆå¸Œ\n" + +#: fe-secure-openssl.c:486 msgid "SSL certificate's name entry is missing\n" msgstr "SSLè¯ä¹¦çš„å称项缺失\n" -#: fe-secure-openssl.c:565 -msgid "SSL certificate's name contains embedded null\n" -msgstr "SSLè¯ä¹¦çš„å称包å«åµŒå…¥çš„空值\n" +#: fe-secure-openssl.c:815 +#, c-format +msgid "could not create SSL context: %s\n" +msgstr "无法创建 SSL 环境: %s\n" -#: fe-secure-openssl.c:616 -msgid "host name must be specified for a verified SSL connection\n" -msgstr "必须为一个已验è¯çš„SSL连接指定主机å\n" +# fe-connect.c:891 +#: fe-secure-openssl.c:852 +#, c-format +msgid "could not read root certificate file \"%s\": %s\n" +msgstr "æ— æ³•è¯»å–æ ¹è¯ä¹¦æ–‡ä»¶ \"%s\": %s\n" -#: fe-secure-openssl.c:716 +# fe-lobj.c:400 fe-lobj.c:483 +#: fe-secure-openssl.c:880 #, c-format -msgid "server certificate for \"%s\" does not match host name \"%s\"\n" -msgstr "\"%s\"çš„æœåС噍è¯ä¹¦ä¸Žä¸»æœºåä¸åŒ¹é…\"%s\"\n" +msgid "SSL library does not support CRL certificates (file \"%s\")\n" +msgstr "SSLåº“ä¸æ”¯æŒCRL认è¯(文件 \"%s\")\n" -#: fe-secure-openssl.c:722 -msgid "could not get server's host name from server certificate\n" -msgstr "无法从æœåС噍è¯ä¹¦å¾—到æœåŠ¡å™¨çš„ä¸»æœºå\n" +#: fe-secure-openssl.c:908 +msgid "" +"could not get home directory to locate root certificate file\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"无法获å–homeç›®å½•ä»¥å®šä½æ ¹è®¤è¯æ–‡ä»¶\n" +"å¯ä»¥æä¾›è¯¥æ–‡ä»¶æˆ–者将sslmode改为ç¦ç”¨æœåС噍è¯ä¹¦è®¤è¯.\n" -#: fe-secure-openssl.c:869 +#: fe-secure-openssl.c:912 #, c-format -msgid "could not create SSL context: %s\n" -msgstr "无法创建 SSL 环境: %s\n" +msgid "" +"root certificate file \"%s\" does not exist\n" +"Either provide the file or change sslmode to disable server certificate verification.\n" +msgstr "" +"æ ¹è®¤è¯æ–‡ä»¶\"%s\"ä¸å­˜åœ¨\n" +"å¯ä»¥æä¾›è¿™ä¸ªæ–‡ä»¶æˆ–者将sslmode改为ç¦ç”¨æœåŠ¡å™¨è®¤è¯æ£€éªŒ.\n" # fe-lobj.c:400 fe-lobj.c:483 -#: fe-secure-openssl.c:1000 +#: fe-secure-openssl.c:943 #, c-format msgid "could not open certificate file \"%s\": %s\n" msgstr "无法打开è¯ä¹¦æ–‡ä»¶ \"%s\": %s\n" # fe-lobj.c:400 fe-lobj.c:483 -#: fe-secure-openssl.c:1039 fe-secure-openssl.c:1054 +#: fe-secure-openssl.c:962 #, c-format msgid "could not read certificate file \"%s\": %s\n" msgstr "无法读å–è¯ä¹¦æ–‡ä»¶ \"%s\": %s\n" +#: fe-secure-openssl.c:987 +#, c-format +msgid "could not establish SSL connection: %s\n" +msgstr "无法建立 SSL è”æŽ¥: %s\n" + # fe-lobj.c:400 fe-lobj.c:483 -#: fe-secure-openssl.c:1109 +#: fe-secure-openssl.c:1041 #, c-format msgid "could not load SSL engine \"%s\": %s\n" msgstr "无法加载SSL引擎 \"%s\": %s\n" -#: fe-secure-openssl.c:1121 +#: fe-secure-openssl.c:1053 #, c-format msgid "could not initialize SSL engine \"%s\": %s\n" msgstr "无法åˆå§‹åŒ–SSL引擎\"%s\": %s\n" # fe-connect.c:891 -#: fe-secure-openssl.c:1137 +#: fe-secure-openssl.c:1069 #, c-format msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "无法从引擎\"%2$s\"读å–ç§æœ‰SSLé’¥\"%1$s\": %3$s\n" # fe-connect.c:891 -#: fe-secure-openssl.c:1151 +#: fe-secure-openssl.c:1083 #, c-format msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n" msgstr "无法从引擎\"%2$s\"读å–ç§æœ‰SSLé’¥\"%1$s\": %3$s\n" -#: fe-secure-openssl.c:1188 +#: fe-secure-openssl.c:1120 #, c-format msgid "certificate present, but not private key file \"%s\"\n" msgstr "有è¯ä¹¦, 但䏿˜¯ç§é’¥æ–‡ä»¶ \"%s\"\n" # fe-connect.c:2953 -#: fe-secure-openssl.c:1196 +#: fe-secure-openssl.c:1128 #, c-format -msgid "" -"private key file \"%s\" has group or world access; permissions should be " -"u=rw (0600) or less\n" +msgid "private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n" msgstr "警告: ç§é’¥æ–‡ä»¶ \"%s\"的访问æƒé™è¿‡å¤§; æƒé™åº”设置 为 u=rw (0600)或更å°\n" -#: fe-secure-openssl.c:1207 +#: fe-secure-openssl.c:1139 #, c-format msgid "could not load private key file \"%s\": %s\n" msgstr "无法装载ç§é’¥æ–‡ä»¶ \"%s\": %s\n" -#: fe-secure-openssl.c:1221 +#: fe-secure-openssl.c:1153 #, c-format msgid "certificate does not match private key file \"%s\": %s\n" msgstr "è¯ä¹¦ä¸åŒ¹é…ç§é’¥æ–‡ä»¶ \"%s\": %s\n" -# fe-connect.c:891 -#: fe-secure-openssl.c:1259 -#, c-format -msgid "could not read root certificate file \"%s\": %s\n" -msgstr "æ— æ³•è¯»å–æ ¹è¯ä¹¦æ–‡ä»¶ \"%s\": %s\n" - -# fe-lobj.c:400 fe-lobj.c:483 -#: fe-secure-openssl.c:1289 -#, c-format -msgid "SSL library does not support CRL certificates (file \"%s\")\n" -msgstr "SSLåº“ä¸æ”¯æŒCRL认è¯(文件 \"%s\")\n" - -#: fe-secure-openssl.c:1322 -msgid "" -"could not get home directory to locate root certificate file\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"无法获å–homeç›®å½•ä»¥å®šä½æ ¹è®¤è¯æ–‡ä»¶\n" -"å¯ä»¥æä¾›è¯¥æ–‡ä»¶æˆ–者将sslmode改为ç¦ç”¨æœåС噍è¯ä¹¦è®¤è¯.\n" - -#: fe-secure-openssl.c:1326 -#, c-format -msgid "" -"root certificate file \"%s\" does not exist\n" -"Either provide the file or change sslmode to disable server certificate " -"verification.\n" -msgstr "" -"æ ¹è®¤è¯æ–‡ä»¶\"%s\"ä¸å­˜åœ¨\n" -"å¯ä»¥æä¾›è¿™ä¸ªæ–‡ä»¶æˆ–者将sslmode改为ç¦ç”¨æœåŠ¡å™¨è®¤è¯æ£€éªŒ.\n" - -#: fe-secure-openssl.c:1419 +#: fe-secure-openssl.c:1262 #, c-format msgid "certificate could not be obtained: %s\n" msgstr "无法获得è¯ä¹¦: %s\n" -#: fe-secure-openssl.c:1511 +#: fe-secure-openssl.c:1351 #, c-format msgid "no SSL error reported" msgstr "没有报告SSL错误" -#: fe-secure-openssl.c:1520 +#: fe-secure-openssl.c:1360 #, c-format msgid "SSL error code %lu" msgstr "SSL é”™è¯¯ä»£ç  %lu" # fe-misc.c:515 fe-misc.c:595 -#: fe-secure.c:261 +#: fe-secure.c:276 #, c-format msgid "could not receive data from server: %s\n" msgstr "无法从æœåŠ¡å™¨æŽ¥æ”¶æ•°æ®: %s\n" # fe-misc.c:702 -#: fe-secure.c:369 +#: fe-secure.c:392 #, c-format msgid "could not send data to server: %s\n" msgstr "æ— æ³•å‘æœåС噍å‘逿•°æ®: %s\n" @@ -1114,7 +1257,3 @@ msgstr "æ— æ³•å‘æœåС噍å‘逿•°æ®: %s\n" #, c-format msgid "unrecognized socket error: 0x%08X/%d" msgstr "ä¸å¯è¯†åˆ«çš„套接字错误: 0x%08X/%d" - -#~ msgid "" -#~ "verified SSL connections are only supported when connecting to a host name" -#~ msgstr "åªæœ‰å½“æ­£åœ¨è¿žæŽ¥ä¸€ä¸ªä¸»æœºæ—¶æ‰æ”¯æŒæ£€æŸ¥çš„SSL连接" diff --git a/src/interfaces/libpq/pqexpbuffer.c b/src/interfaces/libpq/pqexpbuffer.c index 86b16e60fb2..a9af6f8d837 100644 --- a/src/interfaces/libpq/pqexpbuffer.c +++ b/src/interfaces/libpq/pqexpbuffer.c @@ -15,7 +15,7 @@ * a usable vsnprintf(), then a copy of our own implementation of it will * be linked into libpq. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/libpq/pqexpbuffer.c @@ -37,6 +37,9 @@ /* All "broken" PQExpBuffers point to this string. */ static const char oom_buffer[1] = ""; +/* Need a char * for unconstify() compatibility */ +static const char *oom_buffer_ptr = oom_buffer; + static bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0); @@ -57,7 +60,7 @@ markPQExpBufferBroken(PQExpBuffer str) * to put oom_buffer in read-only storage, so that anyone who tries to * scribble on a broken PQExpBuffer will get a failure. */ - str->data = (char *) oom_buffer; + str->data = unconstify(char *, oom_buffer_ptr); str->len = 0; str->maxlen = 0; } @@ -91,7 +94,7 @@ initPQExpBuffer(PQExpBuffer str) str->data = (char *) malloc(INITIAL_EXPBUFFER_SIZE); if (str->data == NULL) { - str->data = (char *) oom_buffer; /* see comment above */ + str->data = unconstify(char *, oom_buffer_ptr); /* see comment above */ str->maxlen = 0; str->len = 0; } @@ -130,7 +133,7 @@ termPQExpBuffer(PQExpBuffer str) if (str->data != oom_buffer) free(str->data); /* just for luck, make the buffer validly empty. */ - str->data = (char *) oom_buffer; /* see comment above */ + str->data = unconstify(char *, oom_buffer_ptr); /* see comment above */ str->maxlen = 0; str->len = 0; } @@ -233,6 +236,7 @@ enlargePQExpBuffer(PQExpBuffer str, size_t needed) void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) { + int save_errno = errno; va_list args; bool done; @@ -244,6 +248,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) /* Loop in case we have to retry after enlarging the buffer. */ do { + errno = save_errno; va_start(args, fmt); done = appendPQExpBufferVA(str, fmt, args); va_end(args); @@ -261,6 +266,7 @@ printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) { + int save_errno = errno; va_list args; bool done; @@ -270,6 +276,7 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) /* Loop in case we have to retry after enlarging the buffer. */ do { + errno = save_errno; va_start(args, fmt); done = appendPQExpBufferVA(str, fmt, args); va_end(args); @@ -281,6 +288,9 @@ appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) * Shared guts of printfPQExpBuffer/appendPQExpBuffer. * Attempt to format data and append it to str. Returns true if done * (either successful or hard failure), false if need to retry. + * + * Caution: callers must be sure to preserve their entry-time errno + * when looping, in case the fmt contains "%m". */ static bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) @@ -295,76 +305,50 @@ appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) */ if (str->maxlen > str->len + 16) { - /* - * Note: we intentionally leave one byte unused, as a guard against - * old broken versions of vsnprintf. - */ - avail = str->maxlen - str->len - 1; - - errno = 0; + avail = str->maxlen - str->len; nprinted = vsnprintf(str->data + str->len, avail, fmt, args); /* - * If vsnprintf reports an error other than ENOMEM, fail. + * If vsnprintf reports an error, fail (we assume this means there's + * something wrong with the format string). */ - if (nprinted < 0 && errno != 0 && errno != ENOMEM) + if (unlikely(nprinted < 0)) { markPQExpBufferBroken(str); return true; } - /* - * Note: some versions of vsnprintf return the number of chars - * actually stored, not the total space needed as C99 specifies. And - * at least one returns -1 on failure. Be conservative about - * believing whether the print worked. - */ - if (nprinted >= 0 && (size_t) nprinted < avail - 1) + if ((size_t) nprinted < avail) { /* Success. Note nprinted does not include trailing null. */ str->len += nprinted; return true; } - if (nprinted >= 0 && (size_t) nprinted > avail) - { - /* - * This appears to be a C99-compliant vsnprintf, so believe its - * estimate of the required space. (If it's wrong, the logic will - * still work, but we may loop multiple times.) Note that the - * space needed should be only nprinted+1 bytes, but we'd better - * allocate one more than that so that the test above will succeed - * next time. - * - * In the corner case where the required space just barely - * overflows, fail. - */ - if (nprinted > INT_MAX - 2) - { - markPQExpBufferBroken(str); - return true; - } - needed = nprinted + 2; - } - else + /* + * We assume a C99-compliant vsnprintf, so believe its estimate of the + * required space, and add one for the trailing null. (If it's wrong, + * the logic will still work, but we may loop multiple times.) + * + * Choke if the required space would exceed INT_MAX, since str->maxlen + * can't represent more than that. + */ + if (unlikely(nprinted > INT_MAX - 1)) { - /* - * Buffer overrun, and we don't know how much space is needed. - * Estimate twice the previous buffer size, but not more than - * INT_MAX. - */ - if (avail >= INT_MAX / 2) - needed = INT_MAX; - else - needed = avail * 2; + markPQExpBufferBroken(str); + return true; } + needed = nprinted + 1; } else { /* * We have to guess at how much to enlarge, since we're skipping the - * formatting work. + * formatting work. Fortunately, because of enlargePQExpBuffer's + * preference for power-of-2 sizes, this number isn't very sensitive; + * the net effect is that we'll double the buffer size before trying + * to run vsnprintf, which seems sensible. */ needed = 32; } diff --git a/src/interfaces/libpq/pqexpbuffer.h b/src/interfaces/libpq/pqexpbuffer.h index 771602af09f..8a412e99833 100644 --- a/src/interfaces/libpq/pqexpbuffer.h +++ b/src/interfaces/libpq/pqexpbuffer.h @@ -15,7 +15,7 @@ * a usable vsnprintf(), then a copy of our own implementation of it will * be linked into libpq. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/interfaces/libpq/pqexpbuffer.h @@ -177,6 +177,6 @@ extern void appendPQExpBufferChar(PQExpBuffer str, char ch); * if necessary. */ extern void appendBinaryPQExpBuffer(PQExpBuffer str, - const char *data, size_t datalen); + const char *data, size_t datalen); #endif /* PQEXPBUFFER_H */ diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c index f6d675d5c4f..21e4142398e 100644 --- a/src/interfaces/libpq/pthread-win32.c +++ b/src/interfaces/libpq/pthread-win32.c @@ -3,7 +3,7 @@ * pthread-win32.c * partial pthread implementation for win32 * -* Copyright (c) 2004-2018, PostgreSQL Global Development Group +* Copyright (c) 2004-2019, PostgreSQL Global Development Group * IDENTIFICATION * src/interfaces/libpq/pthread-win32.c * diff --git a/src/interfaces/libpq/test/uri-regress.c b/src/interfaces/libpq/test/uri-regress.c index 4590f370085..c9b91a89280 100644 --- a/src/interfaces/libpq/test/uri-regress.c +++ b/src/interfaces/libpq/test/uri-regress.c @@ -7,7 +7,7 @@ * prints out the values from the parsed PQconninfoOption struct that differ * from the defaults (obtained from PQconndefaults). * - * Portions Copyright (c) 2012-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 2012-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/interfaces/libpq/test/uri-regress.c diff --git a/src/interfaces/libpq/win32.c b/src/interfaces/libpq/win32.c index 79768e4e0b8..8b9fb942b00 100644 --- a/src/interfaces/libpq/win32.c +++ b/src/interfaces/libpq/win32.c @@ -15,7 +15,7 @@ * The error constants are taken from the Frambak Bakfram LGSOCKET * library guys who in turn took them from the Winsock FAQ. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * */ diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix index e5ad89d1470..ba3695dd570 100644 --- a/src/makefiles/Makefile.aix +++ b/src/makefiles/Makefile.aix @@ -23,6 +23,9 @@ else LDFLAGS_SL += -Wl,-bnoentry -Wl,-H512 -Wl,-bM:SRE endif +# env var name to use in place of LD_LIBRARY_PATH +ld_library_path_var = LIBPATH + POSTGRES_IMP= postgres.imp @@ -40,4 +43,4 @@ MKLDEXPORT=$(top_srcdir)/$(MKLDEXPORT_DIR)/mkldexport.sh # Rule for building a shared library from a single .o file %$(DLSUFFIX): %.o %.exp - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -o $@ $*.o -Wl,-bE:$*.exp $(BE_DLLLIBS) + $(CC) $(CFLAGS) $*.o $(LDFLAGS) $(LDFLAGS_SL) -o $@ -Wl,-bE:$*.exp $(BE_DLLLIBS) diff --git a/src/makefiles/Makefile.cygwin b/src/makefiles/Makefile.cygwin index 3aaa8a9f04b..f274d802b1e 100644 --- a/src/makefiles/Makefile.cygwin +++ b/src/makefiles/Makefile.cygwin @@ -14,6 +14,8 @@ AROPT = crs DLSUFFIX = .dll CFLAGS_SL = +override CPPFLAGS += -DWIN32_STACK_RLIMIT=$(WIN32_STACK_RLIMIT) + ifneq (,$(findstring backend,$(subdir))) ifeq (,$(findstring conversion_procs,$(subdir))) ifeq (,$(findstring libpqwalreceiver,$(subdir))) diff --git a/src/makefiles/Makefile.darwin b/src/makefiles/Makefile.darwin index 7a8ba3e5274..b17598f0586 100644 --- a/src/makefiles/Makefile.darwin +++ b/src/makefiles/Makefile.darwin @@ -2,6 +2,9 @@ AROPT = crs DLSUFFIX = .so +# env var name to use in place of LD_LIBRARY_PATH +ld_library_path_var = DYLD_LIBRARY_PATH + ifdef PGXS BE_DLLLIBS = -bundle_loader $(bindir)/postgres else @@ -10,4 +13,4 @@ endif # Rule for building a shared library from a single .o file %.so: %.o - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -bundle $(BE_DLLLIBS) -o $@ $< + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -bundle $(BE_DLLLIBS) -o $@ diff --git a/src/makefiles/Makefile.freebsd b/src/makefiles/Makefile.freebsd index 5a98e5a2b0b..c462e2fd584 100644 --- a/src/makefiles/Makefile.freebsd +++ b/src/makefiles/Makefile.freebsd @@ -1,25 +1,21 @@ AROPT = cr -ifdef ELF_SYSTEM export_dynamic = -Wl,-export-dynamic rpath = -Wl,-R'$(rpathdir)' -endif DLSUFFIX = .so CFLAGS_SL = -fPIC -DPIC +# extra stuff for $(with_temp_install) +# we need this to get LD_LIBRARY_PATH searched ahead of the compiled-in +# rpath, if no DT_RUNPATH is present in the executable. The conditions +# under which DT_RUNPATH are added seem unpredictable, so be safe. + +define with_temp_install_extra +LD_LIBRARY_PATH_RPATH=1 +endef # Rule for building a shared library from a single .o file %.so: %.o -ifdef ELF_SYSTEM - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< -else - $(LD) $(LDREL) $(LDOUT) $<.obj -x $< - @echo building shared object $@ - @rm -f $@.pic - @${AR} cq $@.pic $<.obj - ${RANLIB} $@.pic - @rm -f $@ - $(LD) -x -Bshareable -Bforcearchive -o $@ $@.pic -endif + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/makefiles/Makefile.hpux b/src/makefiles/Makefile.hpux index 97bd0ba6d9e..c871fb0c7ef 100644 --- a/src/makefiles/Makefile.hpux +++ b/src/makefiles/Makefile.hpux @@ -36,17 +36,20 @@ else CFLAGS_SL = +Z endif +# env var name to use in place of LD_LIBRARY_PATH +ld_library_path_var = SHLIB_PATH + # Rule for building a shared library from a single .o file %$(DLSUFFIX): %.o ifeq ($(GCC), yes) ifeq ($(with_gnu_ld), yes) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< `$(CC) $(LDFLAGS) -print-libgcc-file-name` + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ `$(CC) $(LDFLAGS) -print-libgcc-file-name` else $(LD) -b -o $@ $< `$(CC) $(LDFLAGS) -print-libgcc-file-name` endif else ifeq ($(with_gnu_ld), yes) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ else $(LD) -b -o $@ $< endif diff --git a/src/makefiles/Makefile.linux b/src/makefiles/Makefile.linux index f4f091caef5..ac58fe45de0 100644 --- a/src/makefiles/Makefile.linux +++ b/src/makefiles/Makefile.linux @@ -12,4 +12,4 @@ CFLAGS_SL = -fPIC # Rule for building a shared library from a single .o file %.so: %.o - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/makefiles/Makefile.netbsd b/src/makefiles/Makefile.netbsd index 43841c15973..15695fb65c7 100644 --- a/src/makefiles/Makefile.netbsd +++ b/src/makefiles/Makefile.netbsd @@ -1,11 +1,7 @@ AROPT = cr -ifdef ELF_SYSTEM export_dynamic = -Wl,-E rpath = -Wl,-R'$(rpathdir)' -else -rpath = -Wl,-R'$(rpathdir)' -endif DLSUFFIX = .so @@ -14,14 +10,4 @@ CFLAGS_SL = -fPIC -DPIC # Rule for building a shared library from a single .o file %.so: %.o -ifdef ELF_SYSTEM - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< -else - $(LD) $(LDREL) $(LDOUT) $<.obj -x $< - @echo building shared object $@ - @rm -f $@.pic - @${AR} cq $@.pic $<.obj - ${RANLIB} $@.pic - @rm -f $@ - $(LD) -x -Bshareable -Bforcearchive -o $@ $@.pic -endif + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/makefiles/Makefile.openbsd b/src/makefiles/Makefile.openbsd index d8fde49d5c8..15695fb65c7 100644 --- a/src/makefiles/Makefile.openbsd +++ b/src/makefiles/Makefile.openbsd @@ -1,9 +1,7 @@ AROPT = cr -ifdef ELF_SYSTEM export_dynamic = -Wl,-E rpath = -Wl,-R'$(rpathdir)' -endif DLSUFFIX = .so @@ -12,14 +10,4 @@ CFLAGS_SL = -fPIC -DPIC # Rule for building a shared library from a single .o file %.so: %.o -ifdef ELF_SYSTEM - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< -else - $(LD) $(LDREL) $(LDOUT) $<.obj -x $< - @echo building shared object $@ - @rm -f $@.pic - @${AR} cq $@.pic $<.obj - ${RANLIB} $@.pic - @rm -f $@ - $(LD) -x -Bshareable -Bforcearchive -o $@ $@.pic -endif + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ diff --git a/src/makefiles/Makefile.solaris b/src/makefiles/Makefile.solaris index e459de30cf4..a7f5652f0ca 100644 --- a/src/makefiles/Makefile.solaris +++ b/src/makefiles/Makefile.solaris @@ -19,9 +19,9 @@ endif # Rule for building a shared library from a single .o file %.so: %.o ifeq ($(GCC), yes) - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ $< + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@ else - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SL) -G -o $@ $< + $(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -G -o $@ endif sqlmansect = 5sql diff --git a/src/makefiles/Makefile.win32 b/src/makefiles/Makefile.win32 index 7abbd01971a..3dea11e5c28 100644 --- a/src/makefiles/Makefile.win32 +++ b/src/makefiles/Makefile.win32 @@ -8,6 +8,8 @@ BE_DLLLIBS= -L$(top_builddir)/src/backend -lpostgres override CPPFLAGS+="-I$(top_srcdir)/src/include/port/win32" endif +override CPPFLAGS += -DWIN32_STACK_RLIMIT=$(WIN32_STACK_RLIMIT) + AROPT = crs DLSUFFIX = .dll CFLAGS_SL = diff --git a/src/makefiles/pgxs.mk b/src/makefiles/pgxs.mk index c038836e73d..271e7eaba82 100644 --- a/src/makefiles/pgxs.mk +++ b/src/makefiles/pgxs.mk @@ -38,12 +38,24 @@ # SCRIPTS -- script files (not binaries) to install into $PREFIX/bin # SCRIPTS_built -- script files (not binaries) to install into $PREFIX/bin, # which need to be built first +# HEADERS -- files to install into $(includedir_server)/$MODULEDIR/$MODULE_big +# HEADERS_built -- as above but built first (but NOT cleaned) +# HEADERS_$(MODULE) -- files to install into +# $(includedir_server)/$MODULEDIR/$MODULE; the value of $MODULE must be +# listed in MODULES or MODULE_big +# HEADERS_built_$(MODULE) -- as above but built first (also NOT cleaned) # REGRESS -- list of regression test cases (without suffix) # REGRESS_OPTS -- additional switches to pass to pg_regress +# TAP_TESTS -- switch to enable TAP tests +# ISOLATION -- list of isolation test cases +# ISOLATION_OPTS -- additional switches to pass to pg_isolation_regress # NO_INSTALLCHECK -- don't define an installcheck target, useful e.g. if # tests require special configuration, or don't use pg_regress # EXTRA_CLEAN -- extra files to remove in 'make clean' -# PG_CPPFLAGS -- will be added to CPPFLAGS +# PG_CPPFLAGS -- will be prepended to CPPFLAGS +# PG_CFLAGS -- will be appended to CFLAGS +# PG_CXXFLAGS -- will be appended to CXXFLAGS +# PG_LDFLAGS -- will be prepended to LDFLAGS # PG_LIBS -- will be added to PROGRAM link line # PG_LIBS_INTERNAL -- same, for references to libraries within build tree # SHLIB_LINK -- will be added to MODULE_big link line @@ -62,6 +74,12 @@ endif ifdef PGXS + +# External extensions must assume generated headers are available +NO_GENERATED_HEADERS=yes +# The temp-install rule won't work, either +NO_TEMP_INSTALL=yes + # We assume that we are in src/makefiles/, so top is ... top_builddir := $(dir $(PGXS))../.. include $(top_builddir)/src/Makefile.global @@ -75,7 +93,8 @@ endif ifeq ($(FLEX),) FLEX = flex endif -endif + +endif # PGXS override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) @@ -87,21 +106,112 @@ endif ifdef MODULEDIR datamoduledir := $(MODULEDIR) docmoduledir := $(MODULEDIR) +incmoduledir := $(MODULEDIR) else ifdef EXTENSION datamoduledir := extension docmoduledir := extension +incmoduledir := extension else datamoduledir := contrib docmoduledir := contrib +incmoduledir := contrib endif endif ifdef PG_CPPFLAGS override CPPFLAGS := $(PG_CPPFLAGS) $(CPPFLAGS) endif +ifdef PG_CFLAGS +override CFLAGS := $(CFLAGS) $(PG_CFLAGS) +endif +ifdef PG_CXXFLAGS +override CXXFLAGS := $(CXXFLAGS) $(PG_CXXFLAGS) +endif +ifdef PG_LDFLAGS +override LDFLAGS := $(PG_LDFLAGS) $(LDFLAGS) +endif + +# logic for HEADERS_* stuff + +# get list of all names used with or without built_ prefix +# note that use of HEADERS_built_foo will get both "foo" and "built_foo", +# we cope with that later when filtering this list against MODULES. +# If someone wants to name a module "built_foo", they can do that and it +# works, but if they have MODULES = foo built_foo then they will need to +# force building of all headers and use HEADERS_built_foo and +# HEADERS_built_built_foo. +HEADER_alldirs := $(patsubst HEADERS_%,%,$(filter HEADERS_%, $(.VARIABLES))) +HEADER_alldirs += $(patsubst HEADERS_built_%,%,$(filter HEADERS_built_%, $(.VARIABLES))) + +# collect all names of built headers to use as a dependency +HEADER_allbuilt := + +ifdef MODULE_big + +# we can unconditionally add $(MODULE_big) here, because we will strip it +# back out below if it turns out not to actually define any headers. +HEADER_dirs := $(MODULE_big) +HEADER_unbuilt_$(MODULE_big) = $(HEADERS) +HEADER_built_$(MODULE_big) = $(HEADERS_built) +HEADER_allbuilt += $(HEADERS_built) +# treat "built" as an exclusion below as well as "built_foo" +HEADER_xdirs := built built_$(MODULE_big) + +else # not MODULE_big, so check MODULES + +# HEADERS is an error in the absence of MODULE_big to provide a dir name +ifdef HEADERS +$(error HEADERS requires MODULE_big to be set) +endif +# make list of modules that have either HEADERS_foo or HEADERS_built_foo +HEADER_dirs := $(foreach m,$(MODULES),$(if $(filter $(m) built_$(m),$(HEADER_alldirs)),$(m))) +# make list of conflicting names to exclude +HEADER_xdirs := $(addprefix built_,$(HEADER_dirs)) + +endif # MODULE_big or MODULES + +# HEADERS_foo requires that "foo" is in MODULES as a sanity check +ifneq (,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) +$(error $(patsubst %,HEADERS_%,$(filter-out $(HEADER_dirs) $(HEADER_xdirs),$(HEADER_alldirs))) defined with no module) +endif + +# assign HEADER_unbuilt_foo and HEADER_built_foo, but make sure +# that "built" takes precedence in the case of conflict, by removing +# conflicting module names when matching the unbuilt name +$(foreach m,$(filter-out $(HEADER_xdirs),$(HEADER_dirs)),$(eval HEADER_unbuilt_$(m) += $$(HEADERS_$(m)))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_built_$(m) += $$(HEADERS_built_$(m)))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_allbuilt += $$(HEADERS_built_$(m)))) + +# expand out the list of headers for each dir, attaching source prefixes +header_file_list = $(HEADER_built_$(1)) $(addprefix $(srcdir)/,$(HEADER_unbuilt_$(1))) +$(foreach m,$(HEADER_dirs),$(eval HEADER_files_$(m) := $$(call header_file_list,$$(m)))) + +# note that the caller's HEADERS* vars have all been expanded now, and +# later changes will have no effect. -all: $(PROGRAM) $(DATA_built) $(SCRIPTS_built) $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .control, $(EXTENSION)) +# remove entries in HEADER_dirs that produced an empty list of files, +# to ensure we don't try and install them +HEADER_dirs := $(foreach m,$(HEADER_dirs),$(if $(strip $(HEADER_files_$(m))),$(m))) + +# Functions for generating install/uninstall commands; the blank lines +# before the "endef" are required, don't lose them +# $(call install_headers,dir,headers) +define install_headers +$(MKDIR_P) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' +$(INSTALL_DATA) $(2) '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)/' + +endef +# $(call uninstall_headers,dir,headers) +define uninstall_headers +rm -f $(addprefix '$(DESTDIR)$(includedir_server)/$(incmoduledir)/$(1)'/, $(notdir $(2))) + +endef + +# end of HEADERS_* stuff + + +all: $(PROGRAM) $(DATA_built) $(HEADER_allbuilt) $(SCRIPTS_built) $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .control, $(EXTENSION)) ifeq ($(with_llvm), yes) all: $(addsuffix .bc, $(MODULES)) $(patsubst %.o,%.bc, $(OBJS)) @@ -147,6 +257,9 @@ endif # SCRIPTS ifdef SCRIPTS_built $(INSTALL_SCRIPT) $(SCRIPTS_built) '$(DESTDIR)$(bindir)/' endif # SCRIPTS_built +ifneq (,$(strip $(HEADER_dirs))) + $(foreach dir,$(HEADER_dirs),$(call install_headers,$(dir),$(HEADER_files_$(dir)))) +endif # HEADERS ifdef MODULE_big ifeq ($(with_llvm), yes) $(call install_llvm_module,$(MODULE_big),$(OBJS)) @@ -211,6 +324,9 @@ endif ifdef SCRIPTS_built rm -f $(addprefix '$(DESTDIR)$(bindir)'/, $(SCRIPTS_built)) endif +ifneq (,$(strip $(HEADER_dirs))) + $(foreach dir,$(HEADER_dirs),$(call uninstall_headers,$(dir),$(HEADER_files_$(dir)))) +endif # HEADERS ifdef MODULE_big ifeq ($(with_llvm), yes) @@ -248,6 +364,12 @@ ifeq ($(PORTNAME), win) rm -f regress.def endif endif # REGRESS +ifdef TAP_TESTS + rm -rf tmp_check/ +endif +ifdef ISOLATION + rm -rf output_iso/ tmp_check_iso/ +endif ifdef MODULE_big clean: clean-lib @@ -258,12 +380,7 @@ distclean maintainer-clean: clean ifdef REGRESS -# Select database to use for running the tests -ifneq ($(USE_MODULE_DB),) - REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB_MODULE) -else - REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB) -endif +REGRESS_OPTS += --dbname=$(CONTRIB_TESTDB) # When doing a VPATH build, must copy over the data files so that the # driver script can find them. We have to use an absolute path for @@ -282,30 +399,55 @@ $(test_files_build): $(abs_builddir)/%: $(srcdir)/% $(MKDIR_P) $(dir $@) ln -s $< $@ endif # VPATH +endif # REGRESS .PHONY: submake submake: ifndef PGXS $(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X) + $(MAKE) -C $(top_builddir)/src/test/isolation all endif -# against installed postmaster +ifdef ISOLATION +ISOLATION_OPTS += --dbname=$(ISOLATION_TESTDB) +endif + +# Standard rules to run regression tests including multiple test suites. +# Runs against an installed postmaster. ifndef NO_INSTALLCHECK installcheck: submake $(REGRESS_PREP) +ifdef REGRESS $(pg_regress_installcheck) $(REGRESS_OPTS) $(REGRESS) endif +ifdef ISOLATION + $(pg_isolation_regress_installcheck) $(ISOLATION_OPTS) $(ISOLATION) +endif +ifdef TAP_TESTS + $(prove_installcheck) +endif +endif # NO_INSTALLCHECK +# Runs independently of any installation ifdef PGXS check: @echo '"$(MAKE) check" is not supported.' @echo 'Do "$(MAKE) install", then "$(MAKE) installcheck" instead.' else check: submake $(REGRESS_PREP) +ifdef REGRESS $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS) +endif +ifdef ISOLATION + $(pg_isolation_regress_check) $(ISOLATION_OPTS) $(ISOLATION) +endif +ifdef TAP_TESTS + $(prove_check) +endif +endif # PGXS -temp-install: EXTRA_INSTALL+=$(subdir) +ifndef NO_TEMP_INSTALL +checkprep: EXTRA_INSTALL+=$(subdir) endif -endif # REGRESS # STANDARD RULES diff --git a/src/nls-global.mk b/src/nls-global.mk index 4fc99379916..30b40ffe2ab 100644 --- a/src/nls-global.mk +++ b/src/nls-global.mk @@ -40,7 +40,7 @@ ALL_PO_FILES = $(addprefix po/, $(addsuffix .po, $(AVAIL_LANGUAGES))) MO_FILES = $(addprefix po/, $(addsuffix .mo, $(LANGUAGES))) ifdef XGETTEXT -XGETTEXT += -ctranslator --copyright-holder='PostgreSQL Global Development Group' --msgid-bugs-address=pgsql-bugs@postgresql.org --no-wrap --sort-by-file --package-name='$(CATALOG_NAME) (PostgreSQL)' --package-version='$(MAJORVERSION)' +XGETTEXT += -ctranslator --copyright-holder='PostgreSQL Global Development Group' --msgid-bugs-address=pgsql-bugs@lists.postgresql.org --no-wrap --sort-by-file --package-name='$(CATALOG_NAME) (PostgreSQL)' --package-version='$(MAJORVERSION)' endif ifdef MSGMERGE @@ -54,6 +54,7 @@ GETTEXT_FLAGS += _:1:pass-c-format # common settings that apply to backend and all backend modules BACKEND_COMMON_GETTEXT_TRIGGERS = \ + $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \ errmsg errmsg_plural:1,2 \ errdetail errdetail_log errdetail_plural:1,2 \ errhint \ @@ -62,11 +63,20 @@ BACKEND_COMMON_GETTEXT_TRIGGERS = \ MultiXactIdWait:6 \ ConditionalMultiXactIdWait:6 BACKEND_COMMON_GETTEXT_FLAGS = \ + $(FRONTEND_COMMON_GETTEXT_FLAGS) \ errmsg:1:c-format errmsg_plural:1:c-format errmsg_plural:2:c-format \ errdetail:1:c-format errdetail_log:1:c-format errdetail_plural:1:c-format errdetail_plural:2:c-format \ errhint:1:c-format \ errcontext:1:c-format +FRONTEND_COMMON_GETTEXT_FILES = $(top_srcdir)/src/common/logging.c + +FRONTEND_COMMON_GETTEXT_TRIGGERS = \ + pg_log_fatal pg_log_error pg_log_warning pg_log_info pg_log_generic:2 pg_log_generic_v:2 + +FRONTEND_COMMON_GETTEXT_FLAGS = \ + pg_log_fatal:1:c-format pg_log_error:1:c-format pg_log_warning:1:c-format pg_log_info:1:c-format pg_log_generic:2:c-format pg_log_generic_v:2:c-format + all-po: $(MO_FILES) diff --git a/src/pl/plperl/GNUmakefile b/src/pl/plperl/GNUmakefile index 933abb47c49..9b1c5141014 100644 --- a/src/pl/plperl/GNUmakefile +++ b/src/pl/plperl/GNUmakefile @@ -12,12 +12,13 @@ override CPPFLAGS += -DPLPERL_HAVE_UID_GID override CPPFLAGS += -Wno-comment endif -# Note: we need to make sure that the CORE directory is included last, +# Note: we need to include the perl_includespec directory last, # probably because it sometimes contains some header files with names # that clash with some of ours, or with some that we include, notably on # Windows. -override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) $(perl_embed_ccflags) -I$(perl_archlibexp)/CORE +override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) $(perl_embed_ccflags) $(perl_includespec) +# this is often, but not always, the same directory named by perl_includespec rpathdir = $(perl_archlibexp)/CORE PGFILEDESC = "PL/Perl - procedural language" @@ -100,7 +101,7 @@ uninstall: uninstall-lib uninstall-data install-data: installdirs $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/' - $(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/ppport.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) $(srcdir)/plperl.h $(srcdir)/ppport.h $(srcdir)/plperl_helpers.h '$(DESTDIR)$(includedir_server)' uninstall-data: rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA))) diff --git a/src/pl/plperl/SPI.xs b/src/pl/plperl/SPI.xs index b98c547e8be..b2db3bd6949 100644 --- a/src/pl/plperl/SPI.xs +++ b/src/pl/plperl/SPI.xs @@ -10,9 +10,6 @@ /* this must be first: */ #include "postgres.h" -/* Defined by Perl */ -#undef _ - /* perl stuff */ #define PG_NEED_PERL_XSUB_H #include "plperl.h" diff --git a/src/pl/plperl/Util.xs b/src/pl/plperl/Util.xs index 686513d2e8d..47eba594155 100644 --- a/src/pl/plperl/Util.xs +++ b/src/pl/plperl/Util.xs @@ -12,13 +12,11 @@ /* this must be first: */ #include "postgres.h" + #include "fmgr.h" #include "utils/builtins.h" #include "utils/bytea.h" /* for byteain & byteaout */ -/* Defined by Perl */ -#undef _ - /* perl stuff */ #define PG_NEED_PERL_XSUB_H #include "plperl.h" diff --git a/src/pl/plperl/expected/plperl.out b/src/pl/plperl/expected/plperl.out index ebfba3eb8d0..d8a1ff5dd8d 100644 --- a/src/pl/plperl/expected/plperl.out +++ b/src/pl/plperl/expected/plperl.out @@ -763,14 +763,17 @@ $$ LANGUAGE plperl; SELECT text_obj(); ERROR: cannot convert Perl hash to non-composite type text CONTEXT: PL/Perl function "text_obj" ------ make sure we can't return a scalar ref +-- test looking through a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str; $$ LANGUAGE plperl; SELECT text_scalarref(); -ERROR: PL/Perl function must return reference to hash or array -CONTEXT: PL/Perl function "text_scalarref" + text_scalarref +---------------- + str +(1 row) + -- check safe behavior when a function body is replaced during execution CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS $$ spi_exec_query('CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS \'return $_[0] * 3;\' LANGUAGE plperl;'); diff --git a/src/pl/plperl/expected/plperl_trigger.out b/src/pl/plperl/expected/plperl_trigger.out index 28011cd9f64..d4879e2f03b 100644 --- a/src/pl/plperl/expected/plperl_trigger.out +++ b/src/pl/plperl/expected/plperl_trigger.out @@ -6,6 +6,10 @@ CREATE TABLE trigger_test ( v varchar, foo rowcompnest ); +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plperl AS $$ # make sure keys are sorted for consistent results - perl no longer @@ -98,6 +102,79 @@ NOTICE: $_TD->{table_name} = 'trigger_test' NOTICE: $_TD->{table_schema} = 'public' NOTICE: $_TD->{when} = 'BEFORE' DROP TRIGGER show_trigger_data_trig on trigger_test; +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +insert into trigger_test_generated (i) values (1); +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'INSERT' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_before' +NOTICE: $_TD->{new} = {'i' => '1'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'BEFORE' +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'INSERT' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_after' +NOTICE: $_TD->{new} = {'i' => '1', 'j' => '2'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'AFTER' +update trigger_test_generated set i = 11 where i = 1; +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'UPDATE' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_before' +NOTICE: $_TD->{new} = {'i' => '11'} +NOTICE: $_TD->{old} = {'i' => '1', 'j' => '2'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'BEFORE' +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'UPDATE' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_after' +NOTICE: $_TD->{new} = {'i' => '11', 'j' => '22'} +NOTICE: $_TD->{old} = {'i' => '1', 'j' => '2'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'AFTER' +delete from trigger_test_generated; +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'DELETE' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_before' +NOTICE: $_TD->{old} = {'i' => '11', 'j' => '22'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'BEFORE' +NOTICE: $_TD->{argc} = '0' +NOTICE: $_TD->{event} = 'DELETE' +NOTICE: $_TD->{level} = 'ROW' +NOTICE: $_TD->{name} = 'show_trigger_data_trig_after' +NOTICE: $_TD->{old} = {'i' => '11', 'j' => '22'} +NOTICE: $_TD->{relid} = 'bogus:12345' +NOTICE: $_TD->{relname} = 'trigger_test_generated' +NOTICE: $_TD->{table_name} = 'trigger_test_generated' +NOTICE: $_TD->{table_schema} = 'public' +NOTICE: $_TD->{when} = 'AFTER' +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; insert into trigger_test values(1,'insert', '("(1)")'); CREATE VIEW trigger_test_view AS SELECT * FROM trigger_test; CREATE TRIGGER show_trigger_data_trig @@ -295,3 +372,21 @@ NOTICE: perlsnitch: ddl_command_start DROP TABLE NOTICE: perlsnitch: ddl_command_end DROP TABLE drop event trigger perl_a_snitch; drop event trigger perl_b_snitch; +-- dealing with generated columns +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE plperl +AS $$ +$_TD->{new}{j} = 5; # not allowed +return 'MODIFY'; +$$; +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +ERROR: cannot set generated column "j" +CONTEXT: PL/Perl function "generated_test_func1" +SELECT * FROM trigger_test_generated; + i | j +---+--- +(0 rows) + diff --git a/src/pl/plperl/nls.mk b/src/pl/plperl/nls.mk index 9b4b4292701..f33e325c76e 100644 --- a/src/pl/plperl/nls.mk +++ b/src/pl/plperl/nls.mk @@ -1,6 +1,6 @@ # src/pl/plperl/nls.mk CATALOG_NAME = plperl -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv tr zh_CN zh_TW +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv tr vi zh_CN zh_TW GETTEXT_FILES = plperl.c SPI.c GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(BACKEND_COMMON_GETTEXT_FLAGS) diff --git a/src/pl/plperl/plc_perlboot.pl b/src/pl/plperl/plc_perlboot.pl index ff059648696..f41aa80e80b 100644 --- a/src/pl/plperl/plc_perlboot.pl +++ b/src/pl/plperl/plc_perlboot.pl @@ -51,9 +51,9 @@ sub ::encode_array_constructor } { - - package PostgreSQL::InServer - ; ## no critic (RequireFilenameMatchesPackage); +#<<< protect next line from perltidy so perlcritic annotation works + package PostgreSQL::InServer; ## no critic (RequireFilenameMatchesPackage) +#>>> use strict; use warnings; @@ -62,6 +62,7 @@ sub ::encode_array_constructor (my $msg = shift) =~ s/\(eval \d+\) //g; chomp $msg; &::elog(&::WARNING, $msg); + return; } $SIG{__WARN__} = \&plperl_warn; diff --git a/src/pl/plperl/plc_trusted.pl b/src/pl/plperl/plc_trusted.pl index 7b11a3f52b0..dea3727682c 100644 --- a/src/pl/plperl/plc_trusted.pl +++ b/src/pl/plperl/plc_trusted.pl @@ -1,7 +1,8 @@ # src/pl/plperl/plc_trusted.pl -package PostgreSQL::InServer::safe - ; ## no critic (RequireFilenameMatchesPackage); +#<<< protect next line from perltidy so perlcritic annotation works +package PostgreSQL::InServer::safe; ## no critic (RequireFilenameMatchesPackage) +#>>> # Load widely useful pragmas into plperl to make them available. # diff --git a/src/pl/plperl/plperl--1.0.sql b/src/pl/plperl/plperl--1.0.sql index 801900f023d..f716ba1c563 100644 --- a/src/pl/plperl/plperl--1.0.sql +++ b/src/pl/plperl/plperl--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plperl; +CREATE LANGUAGE plperl; -COMMENT ON PROCEDURAL LANGUAGE plperl IS 'PL/Perl procedural language'; +COMMENT ON LANGUAGE plperl IS 'PL/Perl procedural language'; diff --git a/src/pl/plperl/plperl--unpackaged--1.0.sql b/src/pl/plperl/plperl--unpackaged--1.0.sql index b062bd5d9b3..5e097c443db 100644 --- a/src/pl/plperl/plperl--unpackaged--1.0.sql +++ b/src/pl/plperl/plperl--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plperl/plperl--unpackaged--1.0.sql */ -ALTER EXTENSION plperl ADD PROCEDURAL LANGUAGE plperl; +ALTER EXTENSION plperl ADD LANGUAGE plperl; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plperl ADD FUNCTION plperl_call_handler(); ALTER EXTENSION plperl ADD FUNCTION plperl_inline_handler(internal); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 4342c02b272..c480999c51d 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -7,9 +7,6 @@ #include "postgres.h" -/* Defined by Perl */ -#undef _ - /* system stuff */ #include #include @@ -263,25 +260,25 @@ static void plperl_event_trigger_handler(PG_FUNCTION_ARGS); static void free_plperl_function(plperl_proc_desc *prodesc); static plperl_proc_desc *compile_plperl_function(Oid fn_oid, - bool is_trigger, - bool is_event_trigger); + bool is_trigger, + bool is_event_trigger); -static SV *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc); +static SV *plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated); static SV *plperl_hash_from_datum(Datum attr); static SV *plperl_ref_from_pg_array(Datum arg, Oid typid); static SV *split_array(plperl_array_info *info, int first, int last, int nest); static SV *make_array_ref(plperl_array_info *info, int first, int last); static SV *get_perl_array_ref(SV *sv); static Datum plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, - FunctionCallInfo fcinfo, - FmgrInfo *finfo, Oid typioparam, - bool *isnull); + FunctionCallInfo fcinfo, + FmgrInfo *finfo, Oid typioparam, + bool *isnull); static void _sv_to_datum_finfo(Oid typid, FmgrInfo *finfo, Oid *typioparam); static Datum plperl_array_to_datum(SV *src, Oid typid, int32 typmod); static void array_to_datum_internal(AV *av, ArrayBuildState *astate, - int *ndims, int *dims, int cur_depth, - Oid arraytypid, Oid elemtypid, int32 typmod, - FmgrInfo *finfo, Oid typioparam); + int *ndims, int *dims, int cur_depth, + Oid arraytypid, Oid elemtypid, int32 typmod, + FmgrInfo *finfo, Oid typioparam); static Datum plperl_hash_to_datum(SV *src, TupleDesc td); static void plperl_init_shared_libs(pTHX); @@ -294,7 +291,7 @@ static SV **hv_store_string(HV *hv, const char *key, SV *val); static SV **hv_fetch_string(HV *hv, const char *key); static void plperl_create_sub(plperl_proc_desc *desc, const char *s, Oid fn_oid); static SV *plperl_call_perl_func(plperl_proc_desc *desc, - FunctionCallInfo fcinfo); + FunctionCallInfo fcinfo); static void plperl_compile_callback(void *arg); static void plperl_exec_callback(void *arg); static void plperl_inline_callback(void *arg); @@ -1402,11 +1399,13 @@ plperl_sv_to_datum(SV *sv, Oid typid, int32 typmod, return ret; } - /* Reference, but not reference to hash or array ... */ - ereport(ERROR, - (errcode(ERRCODE_DATATYPE_MISMATCH), - errmsg("PL/Perl function must return reference to hash or array"))); - return (Datum) 0; /* shut up compiler */ + /* + * If it's a reference to something else, such as a scalar, just + * recursively look through the reference. + */ + return plperl_sv_to_datum(SvRV(sv), typid, typmod, + fcinfo, finfo, typioparam, + isnull); } else { @@ -1642,13 +1641,19 @@ plperl_trigger_build_args(FunctionCallInfo fcinfo) hv_store_string(hv, "name", cstr2sv(tdata->tg_trigger->tgname)); hv_store_string(hv, "relid", cstr2sv(relid)); + /* + * Note: In BEFORE trigger, stored generated columns are not computed yet, + * so don't make them accessible in NEW row. + */ + if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) { event = "INSERT"; if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) hv_store_string(hv, "new", plperl_hash_from_tuple(tdata->tg_trigtuple, - tupdesc)); + tupdesc, + !TRIGGER_FIRED_BEFORE(tdata->tg_event))); } else if (TRIGGER_FIRED_BY_DELETE(tdata->tg_event)) { @@ -1656,7 +1661,8 @@ plperl_trigger_build_args(FunctionCallInfo fcinfo) if (TRIGGER_FIRED_FOR_ROW(tdata->tg_event)) hv_store_string(hv, "old", plperl_hash_from_tuple(tdata->tg_trigtuple, - tupdesc)); + tupdesc, + true)); } else if (TRIGGER_FIRED_BY_UPDATE(tdata->tg_event)) { @@ -1665,10 +1671,12 @@ plperl_trigger_build_args(FunctionCallInfo fcinfo) { hv_store_string(hv, "old", plperl_hash_from_tuple(tdata->tg_trigtuple, - tupdesc)); + tupdesc, + true)); hv_store_string(hv, "new", plperl_hash_from_tuple(tdata->tg_newtuple, - tupdesc)); + tupdesc, + !TRIGGER_FIRED_BEFORE(tdata->tg_event))); } } else if (TRIGGER_FIRED_BY_TRUNCATE(tdata->tg_event)) @@ -1789,6 +1797,11 @@ plperl_modify_tuple(HV *hvTD, TriggerData *tdata, HeapTuple otup) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot set system attribute \"%s\"", key))); + if (attr->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), + errmsg("cannot set generated column \"%s\"", + key))); modvalues[attn - 1] = plperl_sv_to_datum(val, attr->atttypid, @@ -1874,8 +1887,8 @@ PG_FUNCTION_INFO_V1(plperl_inline_handler); Datum plperl_inline_handler(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(fake_fcinfo, 0); InlineCodeBlock *codeblock = (InlineCodeBlock *) PG_GETARG_POINTER(0); - FunctionCallInfoData fake_fcinfo; FmgrInfo flinfo; plperl_proc_desc desc; plperl_call_data *volatile save_call_data = current_call_data; @@ -1897,10 +1910,10 @@ plperl_inline_handler(PG_FUNCTION_ARGS) * plperl_call_perl_func(). In particular note that this sets things up * with no arguments passed, and a result type of VOID. */ - MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); + MemSet(fake_fcinfo, 0, SizeForFunctionCallInfo(0)); MemSet(&flinfo, 0, sizeof(flinfo)); MemSet(&desc, 0, sizeof(desc)); - fake_fcinfo.flinfo = &flinfo; + fake_fcinfo->flinfo = &flinfo; flinfo.fn_oid = InvalidOid; flinfo.fn_mcxt = CurrentMemoryContext; @@ -1918,7 +1931,7 @@ plperl_inline_handler(PG_FUNCTION_ARGS) desc.nargs = 0; desc.reference = NULL; - this_call_data.fcinfo = &fake_fcinfo; + this_call_data.fcinfo = fake_fcinfo; this_call_data.prodesc = &desc; /* we do not bother with refcounting the fake prodesc */ @@ -1938,7 +1951,7 @@ plperl_inline_handler(PG_FUNCTION_ARGS) if (!desc.reference) /* can this happen? */ elog(ERROR, "could not create internal procedure for anonymous code block"); - perlret = plperl_call_perl_func(&desc, &fake_fcinfo); + perlret = plperl_call_perl_func(&desc, fake_fcinfo); SvREFCNT_dec_current(perlret); @@ -2078,7 +2091,7 @@ plperlu_validator(PG_FUNCTION_ARGS) /* - * Uses mksafefunc/mkunsafefunc to create a subroutine whose text is + * Uses mkfunc to create a subroutine whose text is * supplied in s, and returns a reference to it */ static void @@ -2192,11 +2205,11 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo) for (i = 0; i < desc->nargs; i++) { - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) PUSHs(&PL_sv_undef); else if (desc->arg_is_rowtype[i]) { - SV *sv = plperl_hash_from_datum(fcinfo->arg[i]); + SV *sv = plperl_hash_from_datum(fcinfo->args[i].value); PUSHs(sv_2mortal(sv)); } @@ -2206,15 +2219,15 @@ plperl_call_perl_func(plperl_proc_desc *desc, FunctionCallInfo fcinfo) Oid funcid; if (OidIsValid(desc->arg_arraytype[i])) - sv = plperl_ref_from_pg_array(fcinfo->arg[i], desc->arg_arraytype[i]); + sv = plperl_ref_from_pg_array(fcinfo->args[i].value, desc->arg_arraytype[i]); else if ((funcid = get_transform_fromsql(argtypes[i], current_call_data->prodesc->lang_oid, current_call_data->prodesc->trftypes))) - sv = (SV *) DatumGetPointer(OidFunctionCall1(funcid, fcinfo->arg[i])); + sv = (SV *) DatumGetPointer(OidFunctionCall1(funcid, fcinfo->args[i].value)); else { char *tmp; tmp = OutputFunctionCall(&(desc->arg_out_func[i]), - fcinfo->arg[i]); + fcinfo->args[i].value); sv = cstr2sv(tmp); pfree(tmp); } @@ -2823,7 +2836,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger) elog(ERROR, "cache lookup failed for language %u", procStruct->prolang); langStruct = (Form_pg_language) GETSTRUCT(langTup); - prodesc->lang_oid = HeapTupleGetOid(langTup); + prodesc->lang_oid = langStruct->oid; prodesc->lanpltrusted = langStruct->lanpltrusted; ReleaseSysCache(langTup); @@ -3010,7 +3023,7 @@ plperl_hash_from_datum(Datum attr) tmptup.t_len = HeapTupleHeaderGetDatumLength(td); tmptup.t_data = td; - sv = plperl_hash_from_tuple(&tmptup, tupdesc); + sv = plperl_hash_from_tuple(&tmptup, tupdesc, true); ReleaseTupleDesc(tupdesc); return sv; @@ -3018,7 +3031,7 @@ plperl_hash_from_datum(Datum attr) /* Build a hash from all attributes of a given tuple. */ static SV * -plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) +plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc, bool include_generated) { dTHX; HV *hv; @@ -3042,6 +3055,13 @@ plperl_hash_from_tuple(HeapTuple tuple, TupleDesc tupdesc) if (att->attisdropped) continue; + if (att->attgenerated) + { + /* don't include unless requested */ + if (!include_generated) + continue; + } + attname = NameStr(att->attname); attr = heap_getattr(tuple, i + 1, tupdesc, &isnull); @@ -3196,7 +3216,7 @@ plperl_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 processed, av_extend(rows, processed); for (i = 0; i < processed; i++) { - row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc); + row = plperl_hash_from_tuple(tuptable->vals[i], tuptable->tupdesc, true); av_push(rows, row); } hv_store_string(result, "rows", @@ -3482,7 +3502,8 @@ plperl_spi_fetchrow(char *cursor) else { row = plperl_hash_from_tuple(SPI_tuptable->vals[0], - SPI_tuptable->tupdesc); + SPI_tuptable->tupdesc, + true); } SPI_freetuptable(SPI_tuptable); } @@ -3964,8 +3985,6 @@ plperl_spi_commit(void) PG_TRY(); { - HoldPinnedPortals(); - SPI_commit(); SPI_start_transaction(); } @@ -3991,8 +4010,6 @@ plperl_spi_rollback(void) PG_TRY(); { - HoldPinnedPortals(); - SPI_rollback(); SPI_start_transaction(); } diff --git a/src/pl/plperl/plperl.h b/src/pl/plperl/plperl.h index 843331e9dd3..3748158a86d 100644 --- a/src/pl/plperl/plperl.h +++ b/src/pl/plperl/plperl.h @@ -5,7 +5,7 @@ * * This should be included _AFTER_ postgres.h and system include files * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1995, Regents of the University of California * * src/pl/plperl/plperl.h @@ -17,13 +17,6 @@ /* stop perl headers from hijacking stdio and other stuff on Windows */ #ifdef WIN32 #define WIN32IO_IS_STDIO -/* - * isnan is defined in both the perl and mingw headers. We don't use it, - * so this just clears up the compile warning. - */ -#ifdef isnan -#undef isnan -#endif #endif /* WIN32 */ /* @@ -36,18 +29,31 @@ * Sometimes perl carefully scribbles on our *printf macros. * So we undefine them here and redefine them after it's done its dirty deed. */ - -#ifdef USE_REPL_SNPRINTF -#undef snprintf #undef vsnprintf -#endif +#undef snprintf +#undef vsprintf +#undef sprintf +#undef vfprintf +#undef fprintf +#undef vprintf +#undef printf + +/* + * Perl scribbles on the "_" macro too. + */ +#undef _ /* * ActivePerl 5.18 and later are MinGW-built, and their headers use GCC's - * __inline__. Translate to something MSVC recognizes. + * __inline__. Translate to something MSVC recognizes. Also, perl.h sometimes + * defines isnan, so undefine it here and put back the definition later if + * perl.h doesn't. */ #ifdef _MSC_VER #define __inline__ inline +#ifdef isnan +#undef isnan +#endif #endif /* @@ -77,25 +83,84 @@ * before ppport.h, so use a #define flag to control inclusion here. */ #ifdef PG_NEED_PERL_XSUB_H +/* + * On Windows, win32_port.h defines macros for a lot of these same functions. + * To avoid compiler warnings when XSUB.h redefines them, #undef our versions. + */ +#ifdef WIN32 +#undef accept +#undef bind +#undef connect +#undef fopen +#undef kill +#undef listen +#undef lstat +#undef mkdir +#undef open +#undef putenv +#undef recv +#undef rename +#undef select +#undef send +#undef socket +#undef stat +#undef unlink +#endif + #include "XSUB.h" #endif -/* put back our snprintf and vsnprintf */ -#ifdef USE_REPL_SNPRINTF +/* put back our *printf macros ... this must match src/include/port.h */ +#ifdef vsnprintf +#undef vsnprintf +#endif #ifdef snprintf #undef snprintf #endif -#ifdef vsnprintf -#undef vsnprintf +#ifdef vsprintf +#undef vsprintf #endif -#ifdef __GNUC__ -#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) -#define snprintf(...) pg_snprintf(__VA_ARGS__) -#else +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + #define vsnprintf pg_vsnprintf #define snprintf pg_snprintf -#endif /* __GNUC__ */ -#endif /* USE_REPL_SNPRINTF */ +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) + +/* + * Put back "_" too; but rather than making it just gettext() as the core + * code does, make it dgettext() so that the right things will happen in + * loadable modules (if they've set up TEXTDOMAIN correctly). Note that + * we can't just set TEXTDOMAIN here, because this file is used by more + * extensions than just PL/Perl itself. + */ +#undef _ +#define _(x) dgettext(TEXTDOMAIN, x) + +/* put back the definition of isnan if needed */ +#ifdef _MSC_VER +#ifndef isnan +#define isnan(x) _isnan(x) +#endif +#endif /* perl version and platform portability */ #define NEED_eval_pv diff --git a/src/pl/plperl/plperl_helpers.h b/src/pl/plperl/plperl_helpers.h index 65b85a27aed..1e318b6dc83 100644 --- a/src/pl/plperl/plperl_helpers.h +++ b/src/pl/plperl/plperl_helpers.h @@ -3,6 +3,9 @@ #include "mb/pg_wchar.h" +#include "plperl.h" + + /* * convert from utf8 to database encoding * diff --git a/src/pl/plperl/plperl_opmask.pl b/src/pl/plperl/plperl_opmask.pl index 61e5cac1485..e4e64b843f2 100644 --- a/src/pl/plperl/plperl_opmask.pl +++ b/src/pl/plperl/plperl_opmask.pl @@ -38,11 +38,11 @@ # (included in :default) but aren't considered sufficiently safe qw[!dbmopen !setpgrp !setpriority], - # custom is not deemed a likely security risk as it can't be generated from - # perl so would only be seen if the DBA had chosen to load a module that - # used it. Even then it's unlikely to be seen because it's typically - # generated by compiler plugins that operate after PL_op_mask checks. - # But we err on the side of caution and disable it + # custom is not deemed a likely security risk as it can't be generated from + # perl so would only be seen if the DBA had chosen to load a module that + # used it. Even then it's unlikely to be seen because it's typically + # generated by compiler plugins that operate after PL_op_mask checks. + # But we err on the side of caution and disable it qw[!custom],); printf $fh " /* ALLOWED: @allowed_ops */ \\\n"; diff --git a/src/pl/plperl/plperlu--1.0.sql b/src/pl/plperl/plperlu--1.0.sql index d1d213dd5f8..7efb4fbc5bf 100644 --- a/src/pl/plperl/plperlu--1.0.sql +++ b/src/pl/plperl/plperlu--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plperlu; +CREATE LANGUAGE plperlu; -COMMENT ON PROCEDURAL LANGUAGE plperlu IS 'PL/PerlU untrusted procedural language'; +COMMENT ON LANGUAGE plperlu IS 'PL/PerlU untrusted procedural language'; diff --git a/src/pl/plperl/plperlu--unpackaged--1.0.sql b/src/pl/plperl/plperlu--unpackaged--1.0.sql index bc62d36a3d8..36de1ddf49e 100644 --- a/src/pl/plperl/plperlu--unpackaged--1.0.sql +++ b/src/pl/plperl/plperlu--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plperl/plperlu--unpackaged--1.0.sql */ -ALTER EXTENSION plperlu ADD PROCEDURAL LANGUAGE plperlu; +ALTER EXTENSION plperlu ADD LANGUAGE plperlu; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plperlu ADD FUNCTION plperlu_call_handler(); ALTER EXTENSION plperlu ADD FUNCTION plperlu_inline_handler(internal); diff --git a/src/pl/plperl/po/cs.po b/src/pl/plperl/po/cs.po index a130437bc23..5f0980b722f 100644 --- a/src/pl/plperl/po/cs.po +++ b/src/pl/plperl/po/cs.po @@ -3,108 +3,119 @@ # This file is distributed under the same license as the PostgreSQL package. # # Tomáš Vondra , 2012, 2013. - msgid "" msgstr "" "Project-Id-Version: plperl-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-09-18 16:39+0000\n" -"PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2018-07-13 19:38+0000\n" +"PO-Revision-Date: 2018-07-13 23:52+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.7\n" -#: plperl.c:386 +#: plperl.c:409 msgid "" "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "" "Pokud je true, trusted a untrusted Perl kód bude zkompilován ve striktním " "módu." -#: plperl.c:400 +#: plperl.c:423 msgid "" "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Perl inicializaÄní kód spouÅ¡tÄ›ný pÅ™i inicializaci Perl interpreteru." -#: plperl.c:422 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "Perl inicializaÄní kód spouÅ¡tÄ›ný pÅ™i prvním použití jazyka plperl." -#: plperl.c:430 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "Perl inicializaÄní kód spouÅ¡tÄ›ný pÅ™i prvním použití jazyka plperlu." -#: plperl.c:647 plperl.c:821 plperl.c:826 plperl.c:930 plperl.c:941 -#: plperl.c:982 plperl.c:1003 plperl.c:1992 plperl.c:2087 plperl.c:2149 +#: plperl.c:650 +#, c-format +msgid "cannot allocate multiple Perl interpreters on this platform" +msgstr "na této platformÄ› nelze alokovat více Perl interpreterů" + +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2143 plperl.c:2253 plperl.c:2321 +#: plperl.c:2384 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:648 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "bÄ›hem spouÅ¡tÄ›ní PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:822 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "bÄ›hem parsování Perl inicializace" -#: plperl.c:827 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "bÄ›hem bÄ›hu Perl inicializace" -#: plperl.c:931 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "bÄ›hem spouÅ¡tÄ›ní PLC_TRUSTED" -#: plperl.c:942 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "bÄ›hem spouÅ¡tÄ›ní utf8fix" -#: plperl.c:983 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "bÄ›hem spouÅ¡tÄ›ní plperl.on_plperl_init" -#: plperl.c:1004 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "bÄ›hem spouÅ¡tÄ›ní plperl.on_plperlu_init" -#: plperl.c:1048 plperl.c:1648 +#: plperl.c:1105 plperl.c:1787 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl hash obsahuje neexistující sloupec \"%s\"" -#: plperl.c:1133 +#: plperl.c:1110 plperl.c:1792 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "nelze nastavit systémový atribut \"%s\"" + +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "poÄet rozmÄ›rů pole (%d) pÅ™ekraÄuje povolené maximum (%d)" -#: plperl.c:1145 plperl.c:1162 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "" "multidimensional arrays must have array expressions with matching dimensions" msgstr "vícerozmÄ›rná pole musí mít výrazy s odpovídajícími rozmÄ›ry" -#: plperl.c:1199 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "Perlové pole nelze pÅ™evést na typ %s který není pole" -#: plperl.c:1295 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "Perlový hash nelze pÅ™evést na nekompozitní typ %s" -#: plperl.c:1306 +#: plperl.c:1388 plperl.c:3288 #, c-format msgid "" "function returning record called in context that cannot accept type record" @@ -112,44 +123,59 @@ msgstr "" "funkce vracející záznam byla zavolána z kontextu, který neumožňuje pÅ™ijetí " "záznamu" -#: plperl.c:1321 +#: plperl.c:1447 #, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "PL/Perl funkce musí vracet odkaz na hash nebo pole" +msgid "lookup failed for type %s" +msgstr "vyhledávání selhalo pro typ %s" -#: plperl.c:1625 +#: plperl.c:1762 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} neexistuje" -#: plperl.c:1629 +#: plperl.c:1766 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} není odkaz na hash" -#: plperl.c:1869 plperl.c:2568 +#: plperl.c:2018 plperl.c:2860 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "PL/Perl funkce nemohou vracet datový typ %s" -#: plperl.c:1882 plperl.c:2613 +#: plperl.c:2031 plperl.c:2901 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "PL/Perl funkce nemohou pÅ™ijímat datový typ %s" -#: plperl.c:1996 +#: plperl.c:2148 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "z kompilované funkce se nepodaÅ™ilo získat CODE referenci \"%s\"" -#: plperl.c:2194 +#: plperl.c:2241 +#, c-format +msgid "didn't get a return item from function" +msgstr "z funkce nebyla získána návratová hodnota" + +#: plperl.c:2285 plperl.c:2352 +#, c-format +msgid "couldn't fetch $_TD" +msgstr "nelze naÄíst $_TD" + +#: plperl.c:2309 plperl.c:2372 +#, c-format +msgid "didn't get a return item from trigger function" +msgstr "z triggeru nebyla získána návratová hodnota" + +#: plperl.c:2433 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "funkce vracející tabulku (set-valued) byla zavolána z kontextu, který " "neumožňuje pÅ™ijetí tabulky" -#: plperl.c:2238 +#: plperl.c:2478 #, c-format msgid "" "set-returning PL/Perl function must return reference to array or use " @@ -158,36 +184,36 @@ msgstr "" "PL/Perl funkce vracející tabulku (set-returned) musí vracet odkaz na pole " "nebo používat return_next." -#: plperl.c:2352 +#: plperl.c:2599 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "ignoruje modifikovaný řádek v DELETE triggeru" -#: plperl.c:2360 +#: plperl.c:2607 #, c-format msgid "" "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "" "výsledek PL/Perl trigger funkce musí být undef, \"SKIP\", nebo \"MODIFY\"" -#: plperl.c:2498 plperl.c:2508 -#, c-format -msgid "out of memory" -msgstr "paměť vyÄerpána" - -#: plperl.c:2560 +#: plperl.c:2855 #, c-format msgid "trigger functions can only be called as triggers" msgstr "" "funkce pro obsluhu triggerů mohou být volané pouze prostÅ™ednictvím triggerů" -#: plperl.c:2933 +#: plperl.c:3195 +#, c-format +msgid "query result has too many rows to fit in a Perl array" +msgstr "výsledek dotazu má příliÅ¡ mnoho řádek pro uložení do pole v Perlu" + +#: plperl.c:3265 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "" "return_next nelze použít v non-SETOF funkci (funkci nevracející tabulku)" -#: plperl.c:2989 +#: plperl.c:3339 #, c-format msgid "" "SETOF-composite-returning PL/Perl function must call return_next with " @@ -196,17 +222,23 @@ msgstr "" "PL/Perl funkce vracející tabulku složených typů (SETOF-composite-returning) " "musí volat return_next s odkazem na hash" -#: plperl.c:3700 +#: plperl.c:4117 #, c-format msgid "PL/Perl function \"%s\"" msgstr "PL/Perl funkce \"%s\"" -#: plperl.c:3712 +#: plperl.c:4129 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "kompilace PL/Perl funkce \"%s\"" -#: plperl.c:3721 +#: plperl.c:4138 #, c-format msgid "PL/Perl anonymous code block" msgstr "PL/Perl anonymní blok kódu" + +#~ msgid "PL/Perl function must return reference to hash or array" +#~ msgstr "PL/Perl funkce musí vracet odkaz na hash nebo pole" + +#~ msgid "out of memory" +#~ msgstr "paměť vyÄerpána" diff --git a/src/pl/plperl/po/de.po b/src/pl/plperl/po/de.po index ff818fd6f32..ba33d41ce15 100644 --- a/src/pl/plperl/po/de.po +++ b/src/pl/plperl/po/de.po @@ -1,222 +1,222 @@ # German message translation file for plperl -# Copyright (C) 2017 PostgreSQL Global Development Group +# Copyright (C) 2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2009 - 2017. +# Peter Eisentraut , 2009 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-09 17:37+0000\n" -"PO-Revision-Date: 2017-03-09 13:35-0500\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-08 08:08+0000\n" +"PO-Revision-Date: 2019-05-08 10:45+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: plperl.c:390 +#: plperl.c:409 msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "Wenn wahr, dann wird vertrauenswürdiger und nicht vertrauenswürdiger Perl-Code im »strict«-Modus kompiliert." -#: plperl.c:404 +#: plperl.c:423 msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Perl-Initialisierungscode, der ausgeführt wird, wenn der Perl-Interpreter initialisiert wird." -#: plperl.c:426 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "Perl-Initialisierungscode, der ausgeführt wird, wenn plperl zum ersten Mal benutzt wird." -#: plperl.c:434 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "Perl-Initialisierungscode, der ausgeführt wird, wenn plperlu zum ersten Mal benutzt wird." -#: plperl.c:631 +#: plperl.c:650 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "auf dieser Plattform können nicht mehrere Perl-Interpreter angelegt werden" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2157 plperl.c:2267 plperl.c:2335 +#: plperl.c:2398 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "beim Ausführen von PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "beim Parsen der Perl-Initialisierung" -#: plperl.c:833 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "beim Ausführen der Perl-Initialisierung" -#: plperl.c:947 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "beim Ausführen von PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "beim Ausführen von utf8fix" -#: plperl.c:1002 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "beim Ausführen von plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "beim Ausführen von plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1105 plperl.c:1796 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl-Hash enthält nicht existierende Spalte »%s«" -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1110 plperl.c:1801 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "Systemattribut »%s« kann nicht gesetzt werden" -#: plperl.c:1157 +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" -#: plperl.c:1221 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "kann Perl-Array nicht in Nicht-Array-Typ %s umwandeln" -#: plperl.c:1323 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "kann Perl-Hash nicht in nicht zusammengesetzten Typ %s umwandeln" -#: plperl.c:1334 +#: plperl.c:1388 plperl.c:3309 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "PL/Perl-Funktion muss eine Referenz auf ein Hash oder ein Array zurückgeben" - -#: plperl.c:1386 +#: plperl.c:1447 #, c-format msgid "lookup failed for type %s" msgstr "Nachschlagen nach Typ %s fehlgeschlagen" -#: plperl.c:1695 +#: plperl.c:1771 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} existiert nicht" -#: plperl.c:1699 +#: plperl.c:1775 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} ist keine Hash-Referenz" -#: plperl.c:1950 plperl.c:2778 +#: plperl.c:1806 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "kann generierte Spalte »%s« nicht setzen" + +#: plperl.c:2032 plperl.c:2874 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "PL/Perl-Funktionen können keinen Rückgabetyp %s haben" -#: plperl.c:1963 plperl.c:2820 +#: plperl.c:2045 plperl.c:2915 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "PL/Perl-Funktionen können Typ %s nicht annehmen" -#: plperl.c:2079 +#: plperl.c:2162 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "keine CODE-Referenz erhalten beim Kompilieren von Funktion »%s«" -#: plperl.c:2171 +#: plperl.c:2255 #, c-format msgid "didn't get a return item from function" msgstr "keinen Rückgabewert aus Funktion erhalten" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2299 plperl.c:2366 #, c-format msgid "couldn't fetch $_TD" msgstr "konnte $_TD nicht auslesen" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2323 plperl.c:2386 #, c-format msgid "didn't get a return item from trigger function" msgstr "keinen Rückgabewert aus Triggerfunktion erhalten" -#: plperl.c:2357 +#: plperl.c:2447 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "Funktion mit Mengenergebnis in einem Zusammenhang aufgerufen, der keine Mengenergebnisse verarbeiten kann" -#: plperl.c:2401 +#: plperl.c:2492 #, c-format msgid "set-returning PL/Perl function must return reference to array or use return_next" msgstr "PL/Perl-Funktionen mit Mengenergebnis müssen eine Referenz auf ein Array zurückgeben oder return_next verwenden" -#: plperl.c:2515 +#: plperl.c:2613 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "geänderte Zeile im DELETE-Trigger wird ignoriert" -#: plperl.c:2523 +#: plperl.c:2621 #, c-format msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "Ergebnis einer PL/Perl-Triggerfunktion muss undef, »SKIP« oder »MODIFY« sein" -#: plperl.c:2773 +#: plperl.c:2869 #, c-format msgid "trigger functions can only be called as triggers" msgstr "Triggerfunktionen können nur als Trigger aufgerufen werden" -#: plperl.c:3113 +#: plperl.c:3216 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "Anfrageergebnis hat zu viele Zeilen, um in ein Perl-Array zu passen" -#: plperl.c:3158 +#: plperl.c:3286 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "return_next kann nur in einer Funktion mit SETOF-Rückgabetyp verwendet werden" -#: plperl.c:3212 +#: plperl.c:3360 #, c-format msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "PL/Perl-Funktion, die SETOF eines zusammengesetzten Typs zurückgibt, muss return_next mit einer Referenz auf ein Hash aufrufen" -#: plperl.c:3875 +#: plperl.c:4135 #, c-format msgid "PL/Perl function \"%s\"" msgstr "PL/Perl-Funktion »%s«" -#: plperl.c:3887 +#: plperl.c:4147 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "Kompilierung der PL/Perl-Funktion »%s«" -#: plperl.c:3896 +#: plperl.c:4156 #, c-format msgid "PL/Perl anonymous code block" msgstr "anonymer PL/Perl-Codeblock" diff --git a/src/pl/plperl/po/es.po b/src/pl/plperl/po/es.po index 3027478b091..799fe5ba530 100644 --- a/src/pl/plperl/po/es.po +++ b/src/pl/plperl/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for plperl # -# Copyright (C) 2008-2012 PostgreSQL Global Development Group +# Copyright (c) 2008-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Emanuel Calvo Franco , 2008. @@ -8,220 +8,217 @@ # msgid "" msgstr "" -"Project-Id-Version: plperl (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:37+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: plperl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:25-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7\n" -#: plperl.c:390 +#: plperl.c:406 msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "Si es verdadero, se compilará código Perl confiable y no confiable en modo «strict»." -#: plperl.c:404 +#: plperl.c:420 msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Código Perl de inicialización a ejecutar cuando un intérprete Perl es inicializado." -#: plperl.c:426 +#: plperl.c:442 msgid "Perl initialization code to execute once when plperl is first used." msgstr "Código Perl de inicialización a ejecutar cuando plperl se usa por primera vez." -#: plperl.c:434 +#: plperl.c:450 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "Código Perl de inicialización a ejecutar cuando plperlu se usa por primera vez." -#: plperl.c:631 +#: plperl.c:647 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "no se pueden instanciar múltiples intérpretes Perl en esta plataforma" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:670 plperl.c:854 plperl.c:860 plperl.c:977 plperl.c:989 +#: plperl.c:1032 plperl.c:1055 plperl.c:2154 plperl.c:2264 plperl.c:2332 +#: plperl.c:2395 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:671 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "mientras se ejecutaba PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:855 #, c-format msgid "while parsing Perl initialization" msgstr "mientras se interpretaba la inicialización de Perl" -#: plperl.c:833 +#: plperl.c:861 #, c-format msgid "while running Perl initialization" msgstr "mientras se ejecutaba la inicialización de Perl" -#: plperl.c:947 +#: plperl.c:978 #, c-format msgid "while executing PLC_TRUSTED" msgstr "mientras se ejecutaba PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:990 #, c-format msgid "while executing utf8fix" msgstr "mientras se ejecutaba utf8fix" -#: plperl.c:1002 +#: plperl.c:1033 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "mientras se ejecutaba plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1056 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "mientras se ejecutaba plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1102 plperl.c:1793 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "el hash de Perl contiene el columna inexistente «%s»" -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1107 plperl.c:1798 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "no se puede definir el atributo de sistema «%s»" -#: plperl.c:1157 +#: plperl.c:1195 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "el número de dimensiones del array (%d) excede el máximo permitido (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1207 plperl.c:1224 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "los arrays multidimensionales deben tener expresiones de arrays con dimensiones coincidentes" -#: plperl.c:1221 +#: plperl.c:1260 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "no se puede convertir un array de Perl al tipo no-array %s" -#: plperl.c:1323 +#: plperl.c:1363 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "no se puede convertir un hash de Perl al tipo no compuesto %s" -#: plperl.c:1334 +#: plperl.c:1385 plperl.c:3306 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "una función Perl debe retornar una referencia a un hash o array" - -#: plperl.c:1386 +#: plperl.c:1444 #, c-format msgid "lookup failed for type %s" msgstr "búsqueda del tipo %s falló" -#: plperl.c:1695 +#: plperl.c:1768 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} no existe" -#: plperl.c:1699 +#: plperl.c:1772 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} no es una referencia a un hash" -#: plperl.c:1950 plperl.c:2785 +#: plperl.c:1803 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "no se puede definir la columna generada «%s»" + +#: plperl.c:2029 plperl.c:2871 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "las funciones en PL/Perl no pueden retornar el tipo %s" -#: plperl.c:1963 plperl.c:2827 +#: plperl.c:2042 plperl.c:2912 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "funciones de PL/Perl no pueden aceptar el tipo %s" -#: plperl.c:2079 +#: plperl.c:2159 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "no se obtuvo una referencia CODE en la compilación de la función «%s»" -#: plperl.c:2171 +#: plperl.c:2252 #, c-format msgid "didn't get a return item from function" msgstr "no se obtuvo un elemento de retorno desde la función" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2296 plperl.c:2363 #, c-format msgid "couldn't fetch $_TD" msgstr "no se pudo obtener $_TD" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2320 plperl.c:2383 #, c-format msgid "didn't get a return item from trigger function" msgstr "no se obtuvo un elemento de retorno desde la función de disparador" -#: plperl.c:2357 +#: plperl.c:2444 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "se llamó a una función que retorna un conjunto en un contexto que no puede aceptarlo" -#: plperl.c:2401 +#: plperl.c:2489 #, c-format msgid "set-returning PL/Perl function must return reference to array or use return_next" msgstr "una función PL/Perl que retorna un conjunto debe retornar una referencia a un array o usar return_next" -#: plperl.c:2522 +#: plperl.c:2610 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "ignorando la tupla modificada en el disparador DELETE" -#: plperl.c:2530 +#: plperl.c:2618 #, c-format msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "el resultado de la función disparadora en PL/Perl debe ser undef, «SKIP» o «MODIFY»" -#: plperl.c:2780 +#: plperl.c:2866 #, c-format msgid "trigger functions can only be called as triggers" msgstr "las funciones disparadoras sólo pueden ser llamadas como disparadores" -#: plperl.c:3120 +#: plperl.c:3213 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "el resultado de la consulta tiene demasiados registros y no entran en un array de Perl" -#: plperl.c:3165 +#: plperl.c:3283 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "no se puede utilizar return_next en una función sin SETOF" -#: plperl.c:3219 +#: plperl.c:3357 #, c-format msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "una función Perl que retorna SETOF de un tipo compuesto debe invocar return_next con una referencia a un hash" -#: plperl.c:3882 +#: plperl.c:4132 #, c-format msgid "PL/Perl function \"%s\"" msgstr "función PL/Perl «%s»" -#: plperl.c:3894 +#: plperl.c:4144 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "compilación de la función PL/Perl «%s»" -#: plperl.c:3903 +#: plperl.c:4153 #, c-format msgid "PL/Perl anonymous code block" msgstr "bloque de código anónimo de PL/Perl" - -#~ msgid "out of memory" -#~ msgstr "memoria agotada" diff --git a/src/pl/plperl/po/fr.po b/src/pl/plperl/po/fr.po index f20a97addc5..d34cac6ae3b 100644 --- a/src/pl/plperl/po/fr.po +++ b/src/pl/plperl/po/fr.po @@ -6,254 +6,274 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-06 14:37+0000\n" -"PO-Revision-Date: 2017-07-06 18:04+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:08+0000\n" +"PO-Revision-Date: 2019-05-17 15:02+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: plperl.c:390 -msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." +#: plperl.c:409 +msgid "" +"If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "" "Si true, le code Perl de confiance et sans confiance sera compilé en mode\n" "strict." -#: plperl.c:404 -msgid "Perl initialization code to execute when a Perl interpreter is initialized." +#: plperl.c:423 +msgid "" +"Perl initialization code to execute when a Perl interpreter is initialized." msgstr "" "Code d'initialisation Perl à exécuter lorsque un interpréteur Perl est\n" "initialisé." -#: plperl.c:426 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "" "Code d'initialisation Perl à exécuter lorsque plperl est utilisé pour la\n" "première fois" -#: plperl.c:434 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "" "Code d'initialisation Perl à exécuter lorsque plperlu est utilisé pour la\n" "première fois" -#: plperl.c:631 +#: plperl.c:650 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "ne peut pas allouer plusieurs interpréteurs Perl sur cette plateforme" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2157 plperl.c:2267 plperl.c:2335 +#: plperl.c:2398 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "lors de l'exécution de PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "lors de l'analyse de l'initialisation de perl" -#: plperl.c:833 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "lors de l'exécution de l'initialisation de perl" -#: plperl.c:947 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "lors de l'exécution de PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "lors de l'exécution de utf8fix" -#: plperl.c:1002 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "lors de l'exécution de plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "lors de l'exécution de plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1105 plperl.c:1796 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Le hachage Perl contient la colonne « %s » inexistante" -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1110 plperl.c:1801 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "ne peut pas initialiser l'attribut système « %s »" -#: plperl.c:1157 +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "le nombre de dimensions du tableau (%d) dépasse la maximum autorisé (%d)" +msgstr "" +"le nombre de dimensions du tableau (%d) dépasse la maximum autorisé (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1210 plperl.c:1227 #, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions" +msgid "" +"multidimensional arrays must have array expressions with matching dimensions" msgstr "" "les tableaux multidimensionnels doivent avoir des expressions de tableaux\n" "avec les dimensions correspondantes" -#: plperl.c:1221 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" -msgstr "ne peut pas convertir le tableau Perl en un type %s qui n'est pas un tableau" +msgstr "" +"ne peut pas convertir le tableau Perl en un type %s qui n'est pas un tableau" -#: plperl.c:1323 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "ne peut pas convertir le hachage Perl en un type %s non composite" -#: plperl.c:1334 +#: plperl.c:1388 plperl.c:3309 #, c-format -msgid "function returning record called in context that cannot accept type record" +msgid "" +"function returning record called in context that cannot accept type record" msgstr "" "fonction renvoyant le type record appelée dans un contexte qui ne peut pas\n" "accepter le type record" -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "la fonction PL/perl doit renvoyer la référence à un hachage ou à un tableau" - -#: plperl.c:1386 +#: plperl.c:1447 #, c-format msgid "lookup failed for type %s" msgstr "recherche échouée pour le type %s" -#: plperl.c:1695 +#: plperl.c:1771 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} n'existe pas" -#: plperl.c:1699 +#: plperl.c:1775 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} n'est pas une référence de hachage" -#: plperl.c:1950 plperl.c:2785 +#: plperl.c:1806 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "ne peut pas initialiser la colonne générée « %s »" + +#: plperl.c:2032 plperl.c:2874 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "Les fonctions PL/perl ne peuvent pas renvoyer le type %s" -#: plperl.c:1963 plperl.c:2827 +#: plperl.c:2045 plperl.c:2915 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "Les fonctions PL/perl ne peuvent pas accepter le type %s" -#: plperl.c:2079 +#: plperl.c:2162 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" -msgstr "n'a pas obtenu une référence CODE lors de la compilation de la fonction « %s »" +msgstr "" +"n'a pas obtenu une référence CODE lors de la compilation de la fonction « %s " +"»" -#: plperl.c:2171 +#: plperl.c:2255 #, c-format msgid "didn't get a return item from function" msgstr "n'a pas obtenu un élément en retour de la fonction" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2299 plperl.c:2366 #, c-format msgid "couldn't fetch $_TD" msgstr "n'a pas pu récupérer $_TD" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2323 plperl.c:2386 #, c-format msgid "didn't get a return item from trigger function" msgstr "n'a pas obtenu un élément en retour de la fonction trigger" -#: plperl.c:2357 +#: plperl.c:2447 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "fonction renvoyant un ensemble appelée dans un contexte qui ne peut pas\n" "accepter un ensemble" -#: plperl.c:2401 +#: plperl.c:2492 #, c-format -msgid "set-returning PL/Perl function must return reference to array or use return_next" +msgid "" +"set-returning PL/Perl function must return reference to array or use " +"return_next" msgstr "" "la fonction PL/perl renvoyant des ensembles doit renvoyer la référence à\n" "un tableau ou utiliser return_next" -#: plperl.c:2522 +#: plperl.c:2613 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "ignore la ligne modifiée dans le trigger DELETE" -#: plperl.c:2530 +#: plperl.c:2621 #, c-format -msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" +msgid "" +"result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "" "le résultat de la fonction trigger PL/perl doit être undef, « SKIP » ou\n" "« MODIFY »" -#: plperl.c:2780 +#: plperl.c:2869 #, c-format msgid "trigger functions can only be called as triggers" msgstr "les fonctions trigger peuvent seulement être appelées par des triggers" -#: plperl.c:3120 +#: plperl.c:3216 #, c-format msgid "query result has too many rows to fit in a Perl array" -msgstr "le résultat de la requête contient trop de lignes pour être intégré dans un tableau Perl" +msgstr "" +"le résultat de la requête contient trop de lignes pour être intégré dans un " +"tableau Perl" -#: plperl.c:3165 +#: plperl.c:3286 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "ne peut pas utiliser return_next dans une fonction non SETOF" -#: plperl.c:3219 +#: plperl.c:3360 #, c-format -msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" +msgid "" +"SETOF-composite-returning PL/Perl function must call return_next with " +"reference to hash" msgstr "" "une fonction PL/perl renvoyant des lignes composites doit appeler\n" "return_next avec la référence à un hachage" -#: plperl.c:3882 +#: plperl.c:4135 #, c-format msgid "PL/Perl function \"%s\"" msgstr "fonction PL/Perl « %s »" -#: plperl.c:3894 +#: plperl.c:4147 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "compilation de la fonction PL/Perl « %s »" -#: plperl.c:3903 +#: plperl.c:4156 #, c-format msgid "PL/Perl anonymous code block" msgstr "bloc de code PL/Perl anonyme" -#~ msgid "error from Perl function \"%s\": %s" -#~ msgstr "échec dans la fonction Perl « %s » : %s" - -#~ msgid "creation of Perl function \"%s\" failed: %s" -#~ msgstr "échec de la création de la fonction Perl « %s » : %s" - -#~ msgid "while executing PLC_SAFE_OK" -#~ msgstr "lors de l'exécution de PLC_SAFE_OK" +#~ msgid "out of memory" +#~ msgstr "mémoire épuisée" #~ msgid "composite-returning PL/Perl function must return reference to hash" #~ msgstr "" #~ "la fonction PL/perl renvoyant des valeurs composites doit renvoyer la\n" #~ "référence à un hachage" -#~ msgid "out of memory" -#~ msgstr "mémoire épuisée" +#~ msgid "while executing PLC_SAFE_OK" +#~ msgstr "lors de l'exécution de PLC_SAFE_OK" + +#~ msgid "creation of Perl function \"%s\" failed: %s" +#~ msgstr "échec de la création de la fonction Perl « %s » : %s" + +#~ msgid "error from Perl function \"%s\": %s" +#~ msgstr "échec dans la fonction Perl « %s » : %s" + +#~ msgid "PL/Perl function must return reference to hash or array" +#~ msgstr "" +#~ "la fonction PL/perl doit renvoyer la référence à un hachage ou à un " +#~ "tableau" diff --git a/src/pl/plperl/po/it.po b/src/pl/plperl/po/it.po index 134dc445845..359817ddd98 100644 --- a/src/pl/plperl/po/it.po +++ b/src/pl/plperl/po/it.po @@ -1,28 +1,26 @@ # -# Translation of plperl to Italian -# PostgreSQL Project +# plperl.po +# Italian message translation file for plperl # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Emanuele Zamprogno -# * Daniele Varrazzo +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Gabriele Bartolini +# Daniele Varrazzo , 2012-2017. +# Emanuele Zamprogno # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: plperl (PostgreSQL) 10\n" +"Project-Id-Version: plperl (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-22 22:37+0000\n" +"POT-Creation-Date: 2018-10-08 14:08+0000\n" "PO-Revision-Date: 2017-04-23 04:42+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -31,205 +29,200 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Poedit 1.8.7.1\n" -#: plperl.c:390 +#: plperl.c:409 msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "Se vero, il codice Perl affidabile e non affidabile sarà compilato in modalità strict." -#: plperl.c:404 +#: plperl.c:423 msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "codice Perl di inizializzazione da eseguire quando l'interprete Perl è inizializzato." -#: plperl.c:426 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "codice Perl di inizializzazione da eseguire una sola volta quando plperl è usato per la prima volta." -#: plperl.c:434 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "codice Perl di inizializzazione da eseguire una sola volta quando plperlu è usato per la prima volta." -#: plperl.c:631 +#: plperl.c:650 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "non è possibile allocare piû interpreti Perl su questa piattaforma" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2143 plperl.c:2253 plperl.c:2321 +#: plperl.c:2384 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "nell'esecuzione di PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "durante il parsing dell'inizializzazione Perl" -#: plperl.c:833 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "durante l'esecuzione dell'inizializzazione Perl" -#: plperl.c:947 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "nell'esecuzione di PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "durante l'esecuzione di utf8fix" -#: plperl.c:1002 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "nell'esecuzione di plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "nell'esecuzione di plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1105 plperl.c:1787 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "La struttura hash in Perl contiene la colonna inesistente \"%s\"" -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1110 plperl.c:1792 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "l'attributo di sistema \"%s\" non si può impostare" -#: plperl.c:1157 +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "il numero di dimensioni dell'array (%d) eccede il massimo consentito (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "gli array multidimensionali devono avere espressioni array di dimensioni corrispondenti" -#: plperl.c:1221 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "non è possibile convertire un array Perl nel tipo non-array %s" -#: plperl.c:1323 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "non è possibile convertire un hash Perl nel tipo non composito %s" -#: plperl.c:1334 +#: plperl.c:1388 plperl.c:3288 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "la funzione che restituisce un record è chiamata in un contesto che non può accettare il tipo record" -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "la funzione PL/Perl deve restituire un riferimento a hash o array" - -#: plperl.c:1386 +#: plperl.c:1447 #, c-format msgid "lookup failed for type %s" msgstr "ricerca del tipo %s fallita" -#: plperl.c:1695 +#: plperl.c:1762 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} non esiste" -#: plperl.c:1699 +#: plperl.c:1766 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} non è un riferimento ad un hash" -#: plperl.c:1950 plperl.c:2785 +#: plperl.c:2018 plperl.c:2860 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "la funzione PL/Perl non può restituire il tipo %s" -#: plperl.c:1963 plperl.c:2827 +#: plperl.c:2031 plperl.c:2901 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "la funzione PL/Perl non può accettare il tipo %s" -#: plperl.c:2079 +#: plperl.c:2148 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "non ho ricevuto un riferimento CODE dal compilare la funzione \"%s\"" -#: plperl.c:2171 +#: plperl.c:2241 #, c-format msgid "didn't get a return item from function" msgstr "la funzione non ha restituito un elemento" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2285 plperl.c:2352 #, c-format msgid "couldn't fetch $_TD" msgstr "lettura di $_TD fallita" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2309 plperl.c:2372 #, c-format msgid "didn't get a return item from trigger function" msgstr "la funzione trigger non ha restituito un elemento" -#: plperl.c:2357 +#: plperl.c:2433 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "la funzione che restituisce insiemi è chiamata in un contesto che non può accettare un insieme" -#: plperl.c:2401 +#: plperl.c:2478 #, c-format msgid "set-returning PL/Perl function must return reference to array or use return_next" msgstr "la funzione PL/Perl che restituisce un insieme deve restituire un riferimento ad un array o usare return_next" -#: plperl.c:2522 +#: plperl.c:2599 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "modifiche alla riga ignorate nel trigger DELETE" -#: plperl.c:2530 +#: plperl.c:2607 #, c-format msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "il risultato della funzione trigger PL/Perl deve essere undef, \"SKIP\" oppure \"MODIFY\"" -#: plperl.c:2780 +#: plperl.c:2855 #, c-format msgid "trigger functions can only be called as triggers" msgstr "le funzioni trigger possono essere chiamate esclusivamente da trigger" -#: plperl.c:3120 +#: plperl.c:3195 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "il risultato della query ha troppe righe per un array Perl" -#: plperl.c:3165 +#: plperl.c:3265 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "non si può usare return_next in una funzione non-SETOF" -#: plperl.c:3219 +#: plperl.c:3339 #, c-format msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "una funzione PL/Perl che restituisce SETOF di un tipo composito deve chiamare return_next con riferimento ad un hash" -#: plperl.c:3882 +#: plperl.c:4117 #, c-format msgid "PL/Perl function \"%s\"" msgstr "funzione PL/Perl \"%s\"" -#: plperl.c:3894 +#: plperl.c:4129 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "compilazione della funzione Perl \"%s\"" -#: plperl.c:3903 +#: plperl.c:4138 #, c-format msgid "PL/Perl anonymous code block" msgstr "blocco di codice anonimo PL/Perl" diff --git a/src/pl/plperl/po/ja.po b/src/pl/plperl/po/ja.po index cab0253534c..517eadce9ce 100644 --- a/src/pl/plperl/po/ja.po +++ b/src/pl/plperl/po/ja.po @@ -1,193 +1,242 @@ # LANGUAGE message translation file for plperl # Copyright (C) 2009 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# FIRST AUTHOR , 2009. +# Honda Shigehiro , 2012. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.1 beta 2\n" +"Project-Id-Version: plperl (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-08-11 17:49+0900\n" -"PO-Revision-Date: 2012-08-11 17:51+0900\n" -"Last-Translator: Honda Shigehiro\n" +"POT-Creation-Date: 2018-01-29 10:46+0900\n" +"PO-Revision-Date: 2018-02-13 11:13+0900\n" +"Last-Translator: Michihide Hotta \n" "Language-Team: jpug-doc \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" -#: plperl.c:365 -msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." -msgstr "真ãªã‚‰ã°ä¿¡é ¼ã—ã€ä¿¡é ¼ã•れãªã„Perlã®ã‚³ãƒ¼ãƒ‰ã¯strictモードã§ã‚³ãƒ³ãƒ‘イルã•れã¾ã™ã€‚" +#: plperl.c:407 +msgid "" +"If true, trusted and untrusted Perl code will be compiled in strict mode." +msgstr "" +"true ã®å ´åˆã€trusted ãŠã‚ˆã³ untrusted 㪠Perl ã®ã‚³ãƒ¼ãƒ‰ã¯ã„ãšã‚Œã‚‚ strict モー" +"ドã§ã‚³ãƒ³ãƒ‘イルã•れã¾ã™ã€‚" -#: plperl.c:379 -msgid "Perl initialization code to execute when a Perl interpreter is initialized." -msgstr "Perl ã®ã‚¤ãƒ³ã‚¿ãƒ—リタãŒåˆæœŸåŒ–ã•れる際ã«å®Ÿè¡Œã•れるã¹ã Perl åˆæœŸåŒ–コード" +#: plperl.c:421 +msgid "" +"Perl initialization code to execute when a Perl interpreter is initialized." +msgstr "" +"Perl ã®ã‚¤ãƒ³ã‚¿ãƒ—リタãŒåˆæœŸåŒ–ã•れる際ã«å®Ÿè¡Œã•れるã¹ã Perl ã®åˆæœŸåŒ–コード。" -#: plperl.c:401 +#: plperl.c:443 msgid "Perl initialization code to execute once when plperl is first used." -msgstr "plperl ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦å®Ÿè¡Œã•れるã¹ã Perl åˆæœŸåŒ–コード" +msgstr "plperl ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦ã ã‘実行ã•れる Perl ã®åˆæœŸåŒ–コード。" -#: plperl.c:409 +#: plperl.c:451 msgid "Perl initialization code to execute once when plperlu is first used." -msgstr "plperlu ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦å®Ÿè¡Œã•れるã¹ã Perl åˆæœŸåŒ–コード" +msgstr "plperlu ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦ã ã‘実行ã•れる Perl ã®åˆæœŸåŒ–コード。" -#: plperl.c:626 plperl.c:788 plperl.c:793 plperl.c:897 plperl.c:908 -#: plperl.c:949 plperl.c:970 plperl.c:1943 plperl.c:2038 plperl.c:2100 +#: plperl.c:648 +#, c-format +msgid "cannot allocate multiple Perl interpreters on this platform" +msgstr "ã“ã®ãƒ—ラットフォームã§ã¯è¤‡æ•°ã® Perl インタプリタを設定ã§ãã¾ã›ã‚“" + +#: plperl.c:671 plperl.c:855 plperl.c:861 plperl.c:978 plperl.c:990 +#: plperl.c:1033 plperl.c:1056 plperl.c:2120 plperl.c:2230 plperl.c:2298 +#: plperl.c:2361 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:627 +#: plperl.c:672 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" -msgstr "PostgreSQL::InServer::SPI::bootstrap ã®å®Ÿè¡Œä¸­ã«" +msgstr "PostgreSQL::InServer::SPI::bootstrap ã®å®Ÿè¡Œä¸­" -#: plperl.c:789 +#: plperl.c:856 #, c-format msgid "while parsing Perl initialization" -msgstr "Perl åˆæœŸåŒ–処ç†ã®ãƒ‘ース中ã«" +msgstr "Perl åˆæœŸåŒ–処ç†ã®ãƒ‘ース中" -#: plperl.c:794 +#: plperl.c:862 #, c-format msgid "while running Perl initialization" -msgstr "Perl åˆæœŸåŒ–処ç†ã®å®Ÿè¡Œä¸­ã«" +msgstr "Perl åˆæœŸåŒ–処ç†ã®å®Ÿè¡Œä¸­" -#: plperl.c:898 +#: plperl.c:979 #, c-format msgid "while executing PLC_TRUSTED" -msgstr "PLC_TRUSTED ã®å®Ÿè¡Œä¸­ã«" +msgstr "PLC_TRUSTED ã®å®Ÿè¡Œä¸­" -#: plperl.c:909 +#: plperl.c:991 #, c-format msgid "while executing utf8fix" -msgstr "utf8fix ã®å®Ÿè¡Œä¸­ã«" +msgstr "utf8fix ã®å®Ÿè¡Œä¸­" -#: plperl.c:950 +#: plperl.c:1034 #, c-format msgid "while executing plperl.on_plperl_init" -msgstr "plperl.on_plperl_init ã®å®Ÿè¡Œä¸­ã«" +msgstr "plperl.on_plperl_init ã®å®Ÿè¡Œä¸­" -#: plperl.c:971 +#: plperl.c:1057 #, c-format msgid "while executing plperl.on_plperlu_init" -msgstr "plperl.on_plperlu_init ã®å®Ÿè¡Œä¸­ã«" +msgstr "plperl.on_plperlu_init ã®å®Ÿè¡Œä¸­" -#: plperl.c:1015 plperl.c:1615 +#: plperl.c:1102 plperl.c:1764 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" -msgstr "Perlãƒãƒƒã‚·ãƒ¥ã«å­˜åœ¨ã—ãªã„列\"%s\"ãŒå«ã¾ã‚Œã¾ã™" +msgstr "Perl ãƒãƒƒã‚·ãƒ¥ã«å­˜åœ¨ã—ãªã„列 \"%s\" ãŒã‚りã¾ã™" + +#: plperl.c:1107 plperl.c:1769 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "システム属性 \"%s\" をセットã§ãã¾ã›ã‚“" -#: plperl.c:1100 +#: plperl.c:1195 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "é…åˆ—ã®æ¬¡æ•°(%d)ãŒä¸Šé™(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" +msgstr "é…åˆ—ã®æ¬¡å…ƒæ•°(%d)ãŒåˆ¶é™å€¤(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: plperl.c:1112 plperl.c:1129 +#: plperl.c:1207 plperl.c:1224 #, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions" -msgstr "多次元é…åˆ—ã¯æ¬¡æ•°ã«åˆã£ãŸé…列å¼ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "" +"multidimensional arrays must have array expressions with matching dimensions" +msgstr "多次元é…åˆ—ã¯æ¬¡å…ƒæ•°ã«åˆã£ãŸé…列å¼ã‚’æŒãŸãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: plperl.c:1166 +#: plperl.c:1260 #, c-format msgid "cannot convert Perl array to non-array type %s" -msgstr "Perlé…列をéžé…列型%sã«å¤‰æ›ã§ãã¾ã›ã‚“" +msgstr "Perl é…列をéžé…列型 %s ã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: plperl.c:1262 +#: plperl.c:1362 #, c-format msgid "cannot convert Perl hash to non-composite type %s" -msgstr "Perlãƒãƒƒã‚·ãƒ¥ã‚’éžè¤‡åˆåž‹%sã«å¤‰æ›ã§ãã¾ã›ã‚“" +msgstr "Perl ãƒãƒƒã‚·ãƒ¥ã‚’éžè¤‡åˆåž‹ %s ã«å¤‰æ›ã§ãã¾ã›ã‚“" -#: plperl.c:1273 +#: plperl.c:1373 #, c-format -msgid "function returning record called in context that cannot accept type record" -msgstr "レコード型をå—ã‘付ã‘られãªã„コンテキストã§ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã³å‡ºã•れã¾ã—ãŸ" +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"レコード型をå—ã‘付ã‘られãªã„コンテキストã§ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã³å‡ºã•れã¾ã—" +"ãŸ" -#: plperl.c:1288 +#: plperl.c:1388 #, c-format msgid "PL/Perl function must return reference to hash or array" -msgstr "PL/Perl関数ã¯ãƒãƒƒã‚·ãƒ¥ã¾ãŸã¯é…列ã¸ã®å‚ç…§ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" +msgstr "PL/Perl 関数ã¯ãƒãƒƒã‚·ãƒ¥ã¾ãŸã¯é…列ã¸ã®å‚ç…§ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" -#: plperl.c:1592 +#: plperl.c:1425 +#, c-format +msgid "lookup failed for type %s" +msgstr "åž‹ %s ã®æ¤œç´¢ã«å¤±æ•—ã—ã¾ã—ãŸ" + +#: plperl.c:1740 #, c-format msgid "$_TD->{new} does not exist" -msgstr "$_TD->{new}ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "$_TD->{new} ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: plperl.c:1596 +#: plperl.c:1744 #, c-format msgid "$_TD->{new} is not a hash reference" -msgstr "$_TD->{new}ã¯ãƒãƒƒã‚·ãƒ¥ã¸ã®å‚ç…§ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "$_TD->{new} ã¯ãƒãƒƒã‚·ãƒ¥ã¸ã®å‚ç…§ã§ã¯ã‚りã¾ã›ã‚“" -#: plperl.c:1820 plperl.c:2518 +#: plperl.c:1995 plperl.c:2833 #, c-format msgid "PL/Perl functions cannot return type %s" -msgstr "PL/Perl関数ã¯%s型を返ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "PL/Perl 関数㯠%s 型を返ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: plperl.c:1833 plperl.c:2565 +#: plperl.c:2008 plperl.c:2875 #, c-format msgid "PL/Perl functions cannot accept type %s" -msgstr "PL/Perl関数ã¯%s型をå—ã‘付ã‘られã¾ã›ã‚“" +msgstr "PL/Perl 関数㯠%s 型をå—ã‘付ã‘られã¾ã›ã‚“" -#: plperl.c:1947 +#: plperl.c:2125 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "関数 \"%s\" ã®ã‚³ãƒ³ãƒ‘イルã‹ã‚‰ã¯ã‚³ãƒ¼ãƒ‰å‚ç…§ã‚’å–å¾—ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plperl.c:2151 +#: plperl.c:2218 #, c-format -msgid "set-valued function called in context that cannot accept a set" -msgstr "ã“ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§é›†åˆå€¤ã®é–¢æ•°ã¯é›†åˆã‚’å—ã‘付ã‘られã¾ã›ã‚“" +msgid "didn't get a return item from function" +msgstr "関数ã‹ã‚‰ã¯æˆ»ã‚Šé …目をå–å¾—ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plperl.c:2195 +#: plperl.c:2262 plperl.c:2329 #, c-format -msgid "set-returning PL/Perl function must return reference to array or use return_next" -msgstr "集åˆã‚’è¿”ã™PL/Perl関数ã¯é…列ã¸ã®å‚ç…§ã‚’è¿”ã™ã€ã¾ãŸã¯ã€return_nextを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™" +msgid "couldn't fetch $_TD" +msgstr "$_TD ã‚’å–り出ã›ã¾ã›ã‚“ã§ã—ãŸ" -#: plperl.c:2315 +#: plperl.c:2286 plperl.c:2349 #, c-format -msgid "ignoring modified row in DELETE trigger" -msgstr "DELETEトリガã«ã¦å¤‰æ›´ã•れãŸè¡Œã‚’無視ã—ã¾ã™" +msgid "didn't get a return item from trigger function" +msgstr "トリガー関数ã‹ã‚‰é …目をå–å¾—ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plperl.c:2323 +#: plperl.c:2406 #, c-format -msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" -msgstr "PL/Perlトリガ関数ã®çµæžœã¯\"SKIP\"ã¾ãŸã¯\"MODIFY\"ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "set-valued function called in context that cannot accept a set" +msgstr "集åˆã‚’å—ã‘付ã‘られãªã„コンテキストã§é›†åˆå€¤é–¢æ•°ãŒå‘¼ã°ã‚Œã¾ã—ãŸ" + +#: plperl.c:2451 +#, c-format +msgid "" +"set-returning PL/Perl function must return reference to array or use " +"return_next" +msgstr "" +"集åˆã‚’返㙠PL/Perl 関数ã¯ã€é…列ã¸ã®å‚ç…§ã‚’è¿”ã™ã‹ã¾ãŸã¯ return_next を使ã†å¿…è¦" +"ãŒã‚りã¾ã™" -#: plperl.c:2449 plperl.c:2455 +#: plperl.c:2572 #, c-format -msgid "out of memory" -msgstr "メモリä¸è¶³ã§ã™" +msgid "ignoring modified row in DELETE trigger" +msgstr "DELETE トリガーã§å¤‰æ›´ã•れãŸè¡Œã‚’無視ã—ã¦ã„ã¾ã™" -#: plperl.c:2509 +#: plperl.c:2580 +#, c-format +msgid "" +"result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" +msgstr "" +"PL/Perl ã®ãƒˆãƒªã‚¬ãƒ¼é–¢æ•°ã®çµæžœã¯ undefã€\"SKIP\"ã€\"MODIFY\" ã®ã„ãšã‚Œã‹ã§ãªã‘" +"れã°ãªã‚Šã¾ã›ã‚“" + +#: plperl.c:2828 #, c-format msgid "trigger functions can only be called as triggers" msgstr "トリガー関数ã¯ãƒˆãƒªã‚¬ãƒ¼ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" -#: plperl.c:2885 +#: plperl.c:3170 +#, c-format +msgid "query result has too many rows to fit in a Perl array" +msgstr "å•ã„åˆã‚ã›ã®çµæžœã«å«ã¾ã‚Œã‚‹è¡Œæ•°ãŒ Perl ã®é…列ã«å¯¾ã—ã¦å¤šã™ãŽã¾ã™" + +#: plperl.c:3240 #, c-format msgid "cannot use return_next in a non-SETOF function" -msgstr "SETOF関数以外ã§ã¯return_nextを使用ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" +msgstr "集åˆã‚’è¿”ã™é–¢æ•°ä»¥å¤–ã§ return_next を使ã†ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: plperl.c:2941 +#: plperl.c:3300 #, c-format -msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" -msgstr "複åˆåž‹ã®SETOFã‚’è¿”ã™PL/Perl関数ã¯ãƒãƒƒã‚·ãƒ¥ã¸ã®å‚ç…§ã‚’æŒã¤return_nextを呼ã³å‡ºã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "" +"SETOF-composite-returning PL/Perl function must call return_next with " +"reference to hash" +msgstr "" +"複åˆåž‹ã®é›†åˆã‚’返㙠PL/Perl 関数ã¯ã€ãƒãƒƒã‚·ãƒ¥ã¸ã®å‚ç…§ã‚’æŒã¤ return_next を呼ã³" +"出ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: plperl.c:3652 +#: plperl.c:4009 #, c-format msgid "PL/Perl function \"%s\"" msgstr "PL/Perl 関数 \"%s\"" -#: plperl.c:3664 +#: plperl.c:4021 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "PL/Perl 関数 \"%s\" ã®ã‚³ãƒ³ãƒ‘イル" -#: plperl.c:3673 +#: plperl.c:4030 #, c-format msgid "PL/Perl anonymous code block" msgstr "PL/Perl ã®ç„¡åコードブロック" - -#~ msgid "composite-returning PL/Perl function must return reference to hash" -#~ msgstr "複åˆåž‹ã‚’è¿”ã™PL/Perl関数ã¯ãƒãƒƒã‚·ãƒ¥ã¸ã®å‚ç…§ã‚’è¿”ã™å¿…è¦ãŒã‚りã¾ã™" diff --git a/src/pl/plperl/po/ko.po b/src/pl/plperl/po/ko.po index 2f32d9fcbf9..75c4202b4cb 100644 --- a/src/pl/plperl/po/ko.po +++ b/src/pl/plperl/po/ko.po @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: plperl (PostgreSQL) 9.6\n" +"Project-Id-Version: plperl (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 18:54+0900\n" +"POT-Creation-Date: 2017-08-16 10:59+0900\n" +"PO-Revision-Date: 2017-08-16 17:47+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" "Language: ko\n" @@ -16,200 +16,200 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: plperl.c:405 +#: plperl.c:407 msgid "" "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "true로 지정하면, Perl 코드가 엄격한 구문 검사로 ì»´íŒŒì¼ ë¨" -#: plperl.c:419 +#: plperl.c:421 msgid "" "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Perl ì¸í„°í”„리터가 초기화 ë  ë•Œ 실행할 Perl 초기화 코드" -#: plperl.c:441 +#: plperl.c:443 msgid "Perl initialization code to execute once when plperl is first used." msgstr "plperl ëª¨ë“ˆì´ ì²˜ìŒ ì‚¬ìš©ë  ë•Œ 실행할 Perl 초기화 코드" -#: plperl.c:449 +#: plperl.c:451 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "plperlu ëª¨ë“ˆì´ ì²˜ìŒ ì‚¬ìš©ë  ë•Œ 실행할 Perl 초기화 코드" -#: plperl.c:646 +#: plperl.c:648 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "ì´ í”Œëž«í¼ì— 여러 Perl ì¸í„°í”„리터를 사용할 수 ì—†ìŒ" -#: plperl.c:666 plperl.c:841 plperl.c:847 plperl.c:961 plperl.c:973 -#: plperl.c:1016 plperl.c:1037 plperl.c:2080 plperl.c:2189 plperl.c:2256 -#: plperl.c:2318 +#: plperl.c:671 plperl.c:855 plperl.c:861 plperl.c:978 plperl.c:990 +#: plperl.c:1033 plperl.c:1056 plperl.c:2120 plperl.c:2230 plperl.c:2298 +#: plperl.c:2361 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:667 +#: plperl.c:672 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "PostgreSQL::InServer::SPI::bootstrap 실행 중" -#: plperl.c:842 +#: plperl.c:856 #, c-format msgid "while parsing Perl initialization" msgstr "Perl 초기화 구문 ë¶„ì„ ì¤‘" -#: plperl.c:848 +#: plperl.c:862 #, c-format msgid "while running Perl initialization" msgstr "Perl 초기화 실행 중" -#: plperl.c:962 +#: plperl.c:979 #, c-format msgid "while executing PLC_TRUSTED" msgstr "PLC_TRUSTED 실행 중" -#: plperl.c:974 +#: plperl.c:991 #, c-format msgid "while executing utf8fix" msgstr "utf8fix 실행 중" -#: plperl.c:1017 +#: plperl.c:1034 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "plperl.on_plperl_init 실행 중" -#: plperl.c:1038 +#: plperl.c:1057 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "plperl.on_plperlu_init 실행 중" -#: plperl.c:1082 plperl.c:1722 +#: plperl.c:1102 plperl.c:1764 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl í•´ì‹œì— ì¡´ìž¬í•˜ì§€ 않는 \"%s\" ì¹¼ëŸ¼ì´ í¬í•¨ë˜ì—ˆìŠµë‹ˆë‹¤" -#: plperl.c:1167 +#: plperl.c:1107 plperl.c:1769 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" 시스템 ì†ì„±ì„ 지정할 수 ì—†ìŒ" + +#: plperl.c:1195 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "지정한 ë°°ì—´ í¬ê¸°(%d)ê°€ 최대치(%d)를 초과했습니다" -#: plperl.c:1179 plperl.c:1196 +#: plperl.c:1207 plperl.c:1224 #, c-format msgid "" "multidimensional arrays must have array expressions with matching dimensions" msgstr "ë‹¤ì°¨ì› ë°°ì—´ì—는 ì¼ì¹˜í•˜ëŠ” ì°¨ì›ì´ í¬í•¨ëœ ë°°ì—´ ì‹ì´ 있어야 함" -#: plperl.c:1231 +#: plperl.c:1260 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "Perl ë°°ì—´í˜•ì„ ë¹„ë°°ì—´í˜• %s ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" -#: plperl.c:1333 +#: plperl.c:1362 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "Perl 해시 ìžë£Œí˜•ì„ ë¹„ë³µí•© %s ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" -#: plperl.c:1344 +#: plperl.c:1373 #, c-format msgid "" "function returning record called in context that cannot accept type record" msgstr "반환 ìžë£Œí˜•ì´ recordì¸ë° 함수가 ê·¸ ìžë£Œí˜•으로 반환하지 않ìŒ" -#: plperl.c:1359 +#: plperl.c:1388 #, c-format msgid "PL/Perl function must return reference to hash or array" msgstr "PL/Perl 함수는 해시나 ë°°ì—´ ìžë£Œí˜•ì„ ì°¸ì¡°í•˜ê²Œ 반환해야 함" -#: plperl.c:1396 +#: plperl.c:1425 #, c-format msgid "lookup failed for type %s" msgstr "%s ìžë£Œí˜• 찾기 실패" -#: plperl.c:1699 +#: plperl.c:1740 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} ì—†ìŒ" -#: plperl.c:1703 +#: plperl.c:1744 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} ìžë£Œí˜•ì´ í•´ì‹œ 참조가 아님" -#: plperl.c:1956 plperl.c:2790 +#: plperl.c:1995 plperl.c:2833 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "PL/Perl 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•  수 ì—†ìŒ" -#: plperl.c:1969 plperl.c:2835 +#: plperl.c:2008 plperl.c:2875 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "PL/Perl 함수는 %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: plperl.c:2085 +#: plperl.c:2125 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "\"%s\" 함수를 ì»´íŒŒì¼ í•˜ë©´ì„œ 코드 참조를 구할 수 ì—†ìŒ" -#: plperl.c:2177 +#: plperl.c:2218 #, c-format msgid "didn't get a return item from function" msgstr "함수ì—서 반환할 í•­ëª©ì„ ëª» ì°¾ìŒ" -#: plperl.c:2220 plperl.c:2286 +#: plperl.c:2262 plperl.c:2329 #, c-format msgid "couldn't fetch $_TD" msgstr "$_TD 못 구함" -#: plperl.c:2244 plperl.c:2306 +#: plperl.c:2286 plperl.c:2349 #, c-format msgid "didn't get a return item from trigger function" msgstr "트리거 함수ì—서 반환할 í•­ëª©ì„ ëª» ì°¾ìŒ" -#: plperl.c:2363 +#: plperl.c:2406 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "set-values 함수(í…Œì´ë¸” 리턴 함수)ê°€ set ì •ì˜ ì—†ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤ (í…Œì´ë¸”ê³¼ í•´" "당 ì—´ alias 지정하세요)" -#: plperl.c:2407 +#: plperl.c:2451 #, c-format msgid "" "set-returning PL/Perl function must return reference to array or use " "return_next" msgstr "ì§‘í•© 반환 PL/Perl 함수는 ë°°ì—´ ë˜ëŠ” return_next 를 사용해서 반환해야 함" -#: plperl.c:2521 +#: plperl.c:2572 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "DELETE 트리거ì—서는 ë³€ê²½ëœ ë¡œìš°ëŠ” 무시 함" -#: plperl.c:2529 +#: plperl.c:2580 #, c-format msgid "" "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "" "PL/Perl 트리거 í•¨ìˆ˜ì˜ ê²°ê³¼ëŠ” undef, \"SKIP\", \"MODIFY\" 중 하나여야 함" -#: plperl.c:2708 plperl.c:2718 -#, c-format -msgid "out of memory" -msgstr "메모리 부족" - -#: plperl.c:2782 +#: plperl.c:2828 #, c-format msgid "trigger functions can only be called as triggers" msgstr "트리거 함수는 트리거로만 í˜¸ì¶œë  ìˆ˜ 있ìŒ" -#: plperl.c:3121 +#: plperl.c:3170 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "쿼리 결과가 Perl ë°°ì—´ì— ë‹´ê¸°ì—는 너무 많습니다" -#: plperl.c:3166 +#: plperl.c:3240 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "SETOF 함수가 아닌 경우ì—는 return_next êµ¬ë¬¸ì„ ì“¸ 수 ì—†ìŒ" -#: plperl.c:3220 +#: plperl.c:3300 #, c-format msgid "" "SETOF-composite-returning PL/Perl function must call return_next with " @@ -218,17 +218,17 @@ msgstr "" "SETOF-composite-returning PL/Perl 함수는 return_next ì—서 해시 ìžë£Œí˜•ì„ ì°¸ì¡°" "해야 함" -#: plperl.c:3948 +#: plperl.c:4009 #, c-format msgid "PL/Perl function \"%s\"" msgstr "\"%s\" PL/Perl 함수" -#: plperl.c:3960 +#: plperl.c:4021 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "\"%s\" PL/Perl 함수 ì»´í•„ë ˆì´ì…˜" -#: plperl.c:3969 +#: plperl.c:4030 #, c-format msgid "PL/Perl anonymous code block" msgstr "PL/Perl ìµëª… 코드 블럭" diff --git a/src/pl/plperl/po/ru.po b/src/pl/plperl/po/ru.po index ba7e6b7a7db..efc6747177a 100644 --- a/src/pl/plperl/po/ru.po +++ b/src/pl/plperl/po/ru.po @@ -2,13 +2,13 @@ # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: plperl (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:37+0000\n" +"POT-Creation-Date: 2019-04-30 07:03+0300\n" "PO-Revision-Date: 2017-03-29 13:41+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,97 +16,96 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" -#: plperl.c:390 +#: plperl.c:409 msgid "" "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "" "ЕÑли Ñтот параметр равен true, доверенный и недоверенный код Perl будет " "компилироватьÑÑ Ð² Ñтрогом режиме." -#: plperl.c:404 +#: plperl.c:423 msgid "" "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "" "Код инициализации Perl, который выполнÑетÑÑ Ð¿Ñ€Ð¸ инициализации интерпретатора " "Perl." -#: plperl.c:426 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "" "Код инициализации Perl, который выполнÑетÑÑ Ð¾Ð´Ð¸Ð½ раз, при первом " "иÑпользовании plperl." -#: plperl.c:434 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "" "Код инициализации Perl, который выполнÑетÑÑ Ð¾Ð´Ð¸Ð½ раз, при первом " "иÑпользовании plperlu." -#: plperl.c:631 +#: plperl.c:650 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "на Ñтой платформе Ð½ÐµÐ»ÑŒÐ·Ñ Ð·Ð°Ð¿ÑƒÑтить множеÑтво интерпретаторов Perl" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2143 plperl.c:2253 plperl.c:2321 +#: plperl.c:2384 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "при выполнении PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "при разборе параметров инициализации Perl" -#: plperl.c:833 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "при выполнении инициализации Perl" -#: plperl.c:947 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "при выполнении PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "при выполнении utf8fix" -#: plperl.c:1002 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "при выполнении plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "при выполнении plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1105 plperl.c:1787 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl-хеш Ñодержит неÑущеÑтвующий Ñтолбец \"%s\"" -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1110 plperl.c:1792 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "уÑтановить ÑиÑтемный атрибут \"%s\" нельзÑ" -#: plperl.c:1157 +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "чиÑло размерноÑтей маÑÑива (%d) превышает предел (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "" "multidimensional arrays must have array expressions with matching dimensions" @@ -114,80 +113,75 @@ msgstr "" "Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ñ… маÑÑивов должны задаватьÑÑ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÑоответÑтвующими " "размерноÑÑ‚Ñми" -#: plperl.c:1221 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "Perl-маÑÑив Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ в тип не маÑÑива %s" -#: plperl.c:1323 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "Perl-хеш Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ñ‚ÑŒ в не ÑоÑтавной тип %s" -#: plperl.c:1334 +#: plperl.c:1388 plperl.c:3288 #, c-format msgid "" "function returning record called in context that cannot accept type record" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ, вызвана в контекÑте, не допуÑкающем Ñтот тип" -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Perl должна возвращать ÑÑылку на хеш или маÑÑив" - -#: plperl.c:1386 +#: plperl.c:1447 #, c-format msgid "lookup failed for type %s" msgstr "найти тип %s не удалоÑÑŒ" -#: plperl.c:1695 +#: plperl.c:1762 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} не ÑущеÑтвует" -#: plperl.c:1699 +#: plperl.c:1766 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} - не ÑÑылка на хеш" -#: plperl.c:1950 plperl.c:2778 +#: plperl.c:2018 plperl.c:2860 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "функции PL/Perl не могут возвращать тип %s" -#: plperl.c:1963 plperl.c:2820 +#: plperl.c:2031 plperl.c:2901 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "функции PL/Perl не могут принимать тип %s" -#: plperl.c:2079 +#: plperl.c:2148 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "не удалоÑÑŒ получить ÑÑылку на код поÑле компилÑции функции \"%s\"" -#: plperl.c:2171 +#: plperl.c:2241 #, c-format msgid "didn't get a return item from function" msgstr "не удалоÑÑŒ получить возвращаемый Ñлемент от функции" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2285 plperl.c:2352 #, c-format msgid "couldn't fetch $_TD" msgstr "не удалоÑÑŒ получить $_TD" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2309 plperl.c:2372 #, c-format msgid "didn't get a return item from trigger function" msgstr "не удалоÑÑŒ получить возвращаемый Ñлемент от триггерной функции" -#: plperl.c:2357 +#: plperl.c:2433 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво, вызвана в контекÑте, где ему нет меÑта" -#: plperl.c:2401 +#: plperl.c:2478 #, c-format msgid "" "set-returning PL/Perl function must return reference to array or use " @@ -196,12 +190,12 @@ msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Perl, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво, должна возвращать ÑÑылку на маÑÑив " "или вызывать return_next" -#: plperl.c:2515 +#: plperl.c:2599 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "в триггере DELETE Ð¸Ð·Ð¼ÐµÐ½Ñ‘Ð½Ð½Ð°Ñ Ñтрока игнорируетÑÑ" -#: plperl.c:2523 +#: plperl.c:2607 #, c-format msgid "" "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" @@ -209,24 +203,24 @@ msgstr "" "результатом триггерной функции PL/Perl должен быть undef, \"SKIP\" или " "\"MODIFY\"" -#: plperl.c:2773 +#: plperl.c:2855 #, c-format msgid "trigger functions can only be called as triggers" msgstr "триггерные функции могут вызыватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в триггерах" -#: plperl.c:3113 +#: plperl.c:3195 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "" "результат запроÑа Ñодержит Ñлишком много Ñтрок Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ в маÑÑиве Perl" -#: plperl.c:3158 +#: plperl.c:3265 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "" "return_next можно иÑпользовать только в функциÑÑ…, возвращающих множеÑтва" -#: plperl.c:3212 +#: plperl.c:3339 #, c-format msgid "" "SETOF-composite-returning PL/Perl function must call return_next with " @@ -235,20 +229,23 @@ msgstr "" "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Perl, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ ÑоÑтавное множеÑтво, должна вызывать " "return_next Ñо ÑÑылкой на хеш" -#: plperl.c:3875 +#: plperl.c:4113 #, c-format msgid "PL/Perl function \"%s\"" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Perl \"%s\"" -#: plperl.c:3887 +#: plperl.c:4125 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "компилÑÑ†Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ PL/Perl \"%s\"" -#: plperl.c:3896 +#: plperl.c:4134 #, c-format msgid "PL/Perl anonymous code block" msgstr "анонимный блок кода PL/Perl" +#~ msgid "PL/Perl function must return reference to hash or array" +#~ msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Perl должна возвращать ÑÑылку на хеш или маÑÑив" + #~ msgid "out of memory" #~ msgstr "нехватка памÑти" diff --git a/src/pl/plperl/po/sv.po b/src/pl/plperl/po/sv.po index f1ea160533d..7de9a157457 100644 --- a/src/pl/plperl/po/sv.po +++ b/src/pl/plperl/po/sv.po @@ -2,14 +2,14 @@ # Copyright (C) 2014 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Mats Erik Andersson , 2014. -# Dennis Björklund 2017. +# Dennis Björklund 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: plperl (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-20 20:37+0000\n" -"PO-Revision-Date: 2017-08-05 08:26+0200\n" +"Project-Id-Version: plperl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 07:08+0000\n" +"PO-Revision-Date: 2019-04-29 14:25+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,208 +17,211 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: plperl.c:390 +#: plperl.c:409 msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "Om sant, tillförlitlig och otillförlitlig Perl-kod kommer kompileras i strikt läge." -#: plperl.c:404 +#: plperl.c:423 msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Perl-kod för initialisering, utföres när perl-tolken förbereds." -#: plperl.c:426 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "Perl-kod för engÃ¥ngs-initialisering dÃ¥ plperl används första gÃ¥ngen." -#: plperl.c:434 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "Perl-kod för engÃ¥ngs-initialisering dÃ¥ plperlu används första gÃ¥ngen." -#: plperl.c:631 +#: plperl.c:650 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "kan inte utnyttja flera Perl-interpretorer pÃ¥ denna plattform" -#: plperl.c:651 plperl.c:826 plperl.c:832 plperl.c:946 plperl.c:958 -#: plperl.c:1001 plperl.c:1022 plperl.c:2074 plperl.c:2183 plperl.c:2250 -#: plperl.c:2312 +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2157 plperl.c:2267 plperl.c:2335 +#: plperl.c:2398 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:652 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "vid utförande av PostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:827 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "vid tolkning av perls initieringssteg" -#: plperl.c:833 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "vid utförande av perls initieringssteg" -#: plperl.c:947 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr "vid utförande av PLC_TRUSTED" -#: plperl.c:959 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "vid utförande av utf8fix" -#: plperl.c:1002 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "vid utförande av plperl.on_plperl_init" -#: plperl.c:1023 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "vid utförande av plperl.on_plperlu_init" -#: plperl.c:1067 plperl.c:1719 +#: plperl.c:1105 plperl.c:1796 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perlhash innehÃ¥ller en okänd kolumn \"%s\"." -#: plperl.c:1072 plperl.c:1724 +#: plperl.c:1110 plperl.c:1801 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "kan inte sätta systemattribut \"%s\"" -#: plperl.c:1157 +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "antalet array-dimensioner (%d) överskrider det maximalt tillÃ¥tna (%d)" -#: plperl.c:1169 plperl.c:1186 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "flerdimensionella vektorer mÃ¥ste ha array-uttryck av passande dimensioner" -#: plperl.c:1221 +#: plperl.c:1263 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "kan inte omvandla perlvektor till icke-array av typ \"%s\"." -#: plperl.c:1323 +#: plperl.c:1366 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "kan inte omvandla en perlhash till icke-composite-typ \"%s\"." -#: plperl.c:1334 +#: plperl.c:1388 plperl.c:3309 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "en funktion med post som värde anropades i sammanhang där poster inte kan godtagas." -#: plperl.c:1349 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "Funktioner i PL/Perl mÃ¥ste svara med referens till hash eller array." - -#: plperl.c:1386 +#: plperl.c:1447 #, c-format msgid "lookup failed for type %s" msgstr "uppslag misslyckades för typen \"%s\"" -#: plperl.c:1695 +#: plperl.c:1771 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} finns inte." -#: plperl.c:1699 +#: plperl.c:1775 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} är inte en hash-referens." -#: plperl.c:1950 plperl.c:2785 +#: plperl.c:1806 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "kan inte sätta genererad kolumn \"%s\"" + +#: plperl.c:2032 plperl.c:2874 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "Funktioner i PL/Perl kan inte svara med typ \"%s\"." -#: plperl.c:1963 plperl.c:2827 +#: plperl.c:2045 plperl.c:2915 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "Funktioner i PL/Perl kan inte hantera typ \"%s\"." -#: plperl.c:2079 +#: plperl.c:2162 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "fick inte en CODE-referens vid kompilering av funktionen \"%s\"." -#: plperl.c:2171 +#: plperl.c:2255 #, c-format msgid "didn't get a return item from function" msgstr "fick inget returnvärde frÃ¥n funktion" -#: plperl.c:2214 plperl.c:2280 +#: plperl.c:2299 plperl.c:2366 #, c-format msgid "couldn't fetch $_TD" msgstr "kunde inte hämta $_TD" -#: plperl.c:2238 plperl.c:2300 +#: plperl.c:2323 plperl.c:2386 #, c-format msgid "didn't get a return item from trigger function" msgstr "fick inget returvärde frÃ¥n utlösarfunktion" -#: plperl.c:2357 +#: plperl.c:2447 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "en funktion som returnerar en mängd anropades i kontext som inte godtar en mängd" -#: plperl.c:2401 +#: plperl.c:2492 #, c-format msgid "set-returning PL/Perl function must return reference to array or use return_next" msgstr "En mängd-returnerande funktion i PL/Perl mÃ¥ste göra det som referens eller med return_next." -#: plperl.c:2522 +#: plperl.c:2613 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "Lämnar ändrad rad orörd i en DELETE-triggning" -#: plperl.c:2530 +#: plperl.c:2621 #, c-format msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "resultat av en triggningsfunktion i PL/Perl mÃ¥ste vara undef, \"SKIP\" eller \"MODIFY\"." -#: plperl.c:2780 +#: plperl.c:2869 #, c-format msgid "trigger functions can only be called as triggers" msgstr "Triggningsfunktioner kan bara anropas vid triggning." -#: plperl.c:3120 +#: plperl.c:3216 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "frÃ¥geresultatet har för mÃ¥nga rader för att fÃ¥ plats i en Perl-array" -#: plperl.c:3165 +#: plperl.c:3286 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "fÃ¥r inte nyttja return_next i funktion som ej är SETOF" -#: plperl.c:3219 +#: plperl.c:3360 #, c-format msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "En funktion i PL/Perl med värderetur som SETOF mÃ¥ste anropa return_next med en hashreferens" -#: plperl.c:3882 +#: plperl.c:4135 #, c-format msgid "PL/Perl function \"%s\"" msgstr "PL/Perl-funktion \"%s\"." -#: plperl.c:3894 +#: plperl.c:4147 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "kompilering av PL/Perl-funktion \"%s\"" -#: plperl.c:3903 +#: plperl.c:4156 #, c-format msgid "PL/Perl anonymous code block" msgstr "Anonymt kodblock i PL/Perl." #~ msgid "out of memory" #~ msgstr "slut pÃ¥ minne" + +#~ msgid "PL/Perl function must return reference to hash or array" +#~ msgstr "Funktioner i PL/Perl mÃ¥ste svara med referens till hash eller array." diff --git a/src/pl/plperl/po/tr.po b/src/pl/plperl/po/tr.po index 8c46740be9e..a8708e42ea5 100644 --- a/src/pl/plperl/po/tr.po +++ b/src/pl/plperl/po/tr.po @@ -6,199 +6,231 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 8.4\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2011-08-29 20:38+0000\n" -"PO-Revision-Date: 2011-08-30 01:44+0200\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:38+0000\n" +"PO-Revision-Date: 2019-06-13 17:04+0300\n" "Last-Translator: Devrim GÜNDÜZ \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Turkish\n" -"X-Poedit-Country: Turkey\n" +"X-Generator: Poedit 1.8.7.1\n" -#: plperl.c:362 +#: plperl.c:409 msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "DoÄŸru ise, trusted ve untrusted Perl kodları strict modda derlenecektir" -#: plperl.c:376 +#: plperl.c:423 msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "Perl yorumlayıcısı ilklendirildiÄŸinde çalışacak Perl ilklendirme kodu." -#: plperl.c:398 +#: plperl.c:445 msgid "Perl initialization code to execute once when plperl is first used." msgstr "plperl ilk kez kullanıldığında çalışacak Perl ilklendirme kodu" -#: plperl.c:406 +#: plperl.c:453 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "plperlu ilk kez kullanıldığında çalışacak Perl ilklendirme kodu" -#: plperl.c:623 -#: plperl.c:785 -#: plperl.c:790 -#: plperl.c:894 -#: plperl.c:905 -#: plperl.c:946 -#: plperl.c:967 -#: plperl.c:1868 -#: plperl.c:1963 -#: plperl.c:2025 +#: plperl.c:650 +#, c-format +msgid "cannot allocate multiple Perl interpreters on this platform" +msgstr "bu platformda birden fazla Perl interpreter ayrılamıyor" + +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2157 plperl.c:2267 plperl.c:2335 +#: plperl.c:2398 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:624 +#: plperl.c:674 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "PostgreSQL::InServer::SPI::bootstrap çalıştırılırken" -#: plperl.c:786 +#: plperl.c:858 #, c-format msgid "while parsing Perl initialization" msgstr "Perl ilklendirmesi ayrıştırılırken" -#: plperl.c:791 +#: plperl.c:864 #, c-format msgid "while running Perl initialization" msgstr "Perl ilklendirmesi sırasında" -#: plperl.c:895 +#: plperl.c:981 #, c-format msgid "while executing PLC_TRUSTED" msgstr " PLC_TRUSTED çalıştırılırken" -#: plperl.c:906 +#: plperl.c:993 #, c-format msgid "while executing utf8fix" msgstr "utf8fix çalıştırılırken" -#: plperl.c:947 +#: plperl.c:1036 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "plperl.on_plperl_init çalıştırılırken" -#: plperl.c:968 +#: plperl.c:1059 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "plperl.on_plperlu_init çalıştırılırken" -#: plperl.c:1014 -#: plperl.c:1541 +#: plperl.c:1105 plperl.c:1796 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl hashi olmayan kolonu içeriyor: \"%s\"" -#: plperl.c:1097 +#: plperl.c:1110 plperl.c:1801 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" sistem niteliÄŸi ayarlanamıyor" + +#: plperl.c:1198 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "dizin boyut sayısı (%d), izin verilern en yüksek deÄŸerini (%d) aÅŸmaktadır" -#: plperl.c:1111 +#: plperl.c:1210 plperl.c:1227 #, c-format msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "çok boyutlu dizinler boyut sayısı kadar dizin ifade sayısına sahip olmalıdırlar" -#: plperl.c:1219 +#: plperl.c:1263 #, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "PL/Perl fonksiyonu hash ya da dizine referans dönmelidir" +msgid "cannot convert Perl array to non-array type %s" +msgstr "Perl dizisi (array) dizi olmayan %s tipine dönüştürülemiyor" -#: plperl.c:1518 +#: plperl.c:1366 +#, c-format +msgid "cannot convert Perl hash to non-composite type %s" +msgstr "Perl hash'i kompozit olmayan %s tipine dönüştürülemez" + +#: plperl.c:1388 plperl.c:3309 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "tip kaydı içermeyen alanda çağırılan ve kayıt döndüren fonksiyon" + +#: plperl.c:1447 +#, c-format +msgid "lookup failed for type %s" +msgstr "%s tipi için arama (lookup) baÅŸarısız oldu" + +#: plperl.c:1771 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new} mevcut deÄŸil" -#: plperl.c:1522 +#: plperl.c:1775 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new} hash referansı deÄŸil" -#: plperl.c:1745 -#: plperl.c:2476 +#: plperl.c:1806 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "oluÅŸturulan \"%s\" sütunu ayarlanamıyor" + +#: plperl.c:2032 plperl.c:2874 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "PL/Perl fonksiyonları %s veri tipini döndüremezler" -#: plperl.c:1758 -#: plperl.c:2523 +#: plperl.c:2045 plperl.c:2915 #, c-format msgid "PL/Perl functions cannot accept type %s" msgstr "PL/Perl fonksiyonları %s tipini kabul etmez" -#: plperl.c:1872 +#: plperl.c:2162 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "\"%s\" fonksiyonu derlenirken CODE referansı alınamadı" -#: plperl.c:2077 +#: plperl.c:2255 #, c-format -msgid "set-valued function called in context that cannot accept a set" -msgstr "set deÄŸerini kabul etmediÄŸi ortamda set deÄŸeri alan fonksiyon çağırılmış" +msgid "didn't get a return item from function" +msgstr "fonksiyonden dönüş (return) deÄŸeri alınamadı" -#: plperl.c:2121 +#: plperl.c:2299 plperl.c:2366 #, c-format -msgid "set-returning PL/Perl function must return reference to array or use return_next" -msgstr "se dönen PL/Perl fonksiyonu return_next kullanmalı ya da bir diziye referans dönmelidir" +msgid "couldn't fetch $_TD" +msgstr "$_TD getirilemedi" -#: plperl.c:2150 +#: plperl.c:2323 plperl.c:2386 #, c-format -msgid "composite-returning PL/Perl function must return reference to hash" -msgstr "composite döndüren PL/Perl fonksiyonu hash'e referans dönmelidir" +msgid "didn't get a return item from trigger function" +msgstr "trigger fonksiyonundan dönüş (return) deÄŸeri alınamadı" -#: plperl.c:2159 +#: plperl.c:2447 #, c-format -msgid "function returning record called in context that cannot accept type record" -msgstr "tip kaydı içermeyen alanda çağırılan ve kayıt döndüren fonksiyon" +msgid "set-valued function called in context that cannot accept a set" +msgstr "set deÄŸerini kabul etmediÄŸi ortamda set deÄŸeri alan fonksiyon çağırılmış" + +#: plperl.c:2492 +#, c-format +msgid "set-returning PL/Perl function must return reference to array or use return_next" +msgstr "se dönen PL/Perl fonksiyonu return_next kullanmalı ya da bir diziye referans dönmelidir" -#: plperl.c:2273 +#: plperl.c:2613 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "DELETE triggerındaki deÄŸiÅŸtirilmiÅŸ satır gözardı ediliyor" -#: plperl.c:2281 +#: plperl.c:2621 #, c-format msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "PL/Perl trigger fonksiyonun sonucu undef, \"SKIP\" ya da \"MODIFY\" olmalıdır" -#: plperl.c:2407 -#: plperl.c:2413 -#, c-format -msgid "out of memory" -msgstr "yetersiz bellek" - -#: plperl.c:2467 +#: plperl.c:2869 #, c-format msgid "trigger functions can only be called as triggers" msgstr "trigger fonksiyonları sadece trigger olarak çağırılabilirler" -#: plperl.c:2843 +#: plperl.c:3216 +#, c-format +msgid "query result has too many rows to fit in a Perl array" +msgstr "sorgu sonucunda bir Perl dizisine (array) sığabilecekten çok fazla satır var" + +#: plperl.c:3286 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "SETOF olmayan bir fonksiyonda return_next kullanılamaz" -#: plperl.c:2849 +#: plperl.c:3360 #, c-format msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "SETOF-composite döndüren PL/Perl fonksiyonları return_next'i hash'e referans olarak çağırmalıdır" -#: plperl.c:3615 +#: plperl.c:4135 #, c-format msgid "PL/Perl function \"%s\"" msgstr "\"%s\" PL/Perl fonksiyonu" -#: plperl.c:3627 +#: plperl.c:4147 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "\"%s\" PL/Perl fonksiyonunun derlenmesi" -#: plperl.c:3636 +#: plperl.c:4156 #, c-format msgid "PL/Perl anonymous code block" msgstr "PL/Perl anonim kod bloÄŸu" +#~ msgid "composite-returning PL/Perl function must return reference to hash" +#~ msgstr "composite döndüren PL/Perl fonksiyonu hash'e referans dönmelidir" + +#~ msgid "out of memory" +#~ msgstr "yetersiz bellek" + #~ msgid "creation of Perl function \"%s\" failed: %s" #~ msgstr " \"%s\" Perl fonksiyonunun yaratılması baÅŸarısız oldu: %s" #~ msgid "error from Perl function \"%s\": %s" #~ msgstr "Perl fonksiyonunda hata: \"%s\": %s" + +#~ msgid "PL/Perl function must return reference to hash or array" +#~ msgstr "PL/Perl fonksiyonu hash ya da dizine referans dönmelidir" diff --git a/src/pl/plperl/po/vi.po b/src/pl/plperl/po/vi.po new file mode 100644 index 00000000000..15ba87477c1 --- /dev/null +++ b/src/pl/plperl/po/vi.po @@ -0,0 +1,242 @@ +# LANGUAGE message translation file for plperl +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the plperl (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: plperl (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:08+0000\n" +"PO-Revision-Date: 2018-04-29 23:57+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: plperl.c:409 +msgid "" +"If true, trusted and untrusted Perl code will be compiled in strict mode." +msgstr "" +"Nếu đúng, mã perl đáng tin cậy(PL/Perl ) và không đáng tin cậy(PL/PerlU) sẽ " +"được biên dịch trong chế độ strict." + +#: plperl.c:423 +msgid "" +"Perl initialization code to execute when a Perl interpreter is initialized." +msgstr "Mã Perl được thá»±c thi khi trình thông dịch Perl được khởi tạo." + +#: plperl.c:445 +msgid "Perl initialization code to execute once when plperl is first used." +msgstr "Mã Perl được thá»±c thi khi plperl được sá»­ dụng lần đầu tiên." + +#: plperl.c:453 +msgid "Perl initialization code to execute once when plperlu is first used." +msgstr "Mã Perl được thá»±c thi khi plperlu được sá»­ dụng lần đầu tiên." + +#: plperl.c:650 +#, c-format +msgid "cannot allocate multiple Perl interpreters on this platform" +msgstr "không thể cấp phát nhiá»u trình thông dịch Perl trên hệ Ä‘iá»u hành này" + +#: plperl.c:673 plperl.c:857 plperl.c:863 plperl.c:980 plperl.c:992 +#: plperl.c:1035 plperl.c:1058 plperl.c:2141 plperl.c:2251 plperl.c:2319 +#: plperl.c:2382 +#, c-format +msgid "%s" +msgstr "%s" + +#: plperl.c:674 +#, c-format +msgid "while executing PostgreSQL::InServer::SPI::bootstrap" +msgstr "trong khi thá»±c thi PostgreSQL::InServer::SPI::bootstrap" + +#: plperl.c:858 +#, c-format +msgid "while parsing Perl initialization" +msgstr "trong khi phân tích cú pháp khởi tạo Perl" + +#: plperl.c:864 +#, c-format +msgid "while running Perl initialization" +msgstr "trong khi chạy cú pháp khởi tạo Perl" + +#: plperl.c:981 +#, c-format +msgid "while executing PLC_TRUSTED" +msgstr "trong khi chạy PLC_TRUSTED" + +#: plperl.c:993 +#, c-format +msgid "while executing utf8fix" +msgstr "trong khi thá»±c thi utf8fix" + +#: plperl.c:1036 +#, c-format +msgid "while executing plperl.on_plperl_init" +msgstr "trong khi thá»±c thi plperl.on_plperl_init" + +#: plperl.c:1059 +#, c-format +msgid "while executing plperl.on_plperlu_init" +msgstr "trong khi thá»±c thi plperl.plperlu_init" + +#: plperl.c:1105 plperl.c:1785 +#, c-format +msgid "Perl hash contains nonexistent column \"%s\"" +msgstr "Giá trị băm Perl chứa cá»™t không tồn tại \"%s\"" + +#: plperl.c:1110 plperl.c:1790 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "không thể thiết lập attribute hệ thống \"%s\"" + +#: plperl.c:1198 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "số lượng chiá»u cá»§a mảng (%d) vượt quá số lượng tối Ä‘a cho phép (%d)" + +#: plperl.c:1210 plperl.c:1227 +#, c-format +msgid "" +"multidimensional arrays must have array expressions with matching dimensions" +msgstr "mảng Ä‘a chiá»u phải có biểu thức mảng tương ứng vá»›i các chiá»u" + +#: plperl.c:1263 +#, c-format +msgid "cannot convert Perl array to non-array type %s" +msgstr "không thể chuyển đổi mảng Perl thành kiểu không phải mảng %s" + +#: plperl.c:1366 +#, c-format +msgid "cannot convert Perl hash to non-composite type %s" +msgstr "" +"không thể chuyển đổi giá trị băm Perl thành kiểu không phải-composite %s" + +#: plperl.c:1388 plperl.c:3286 +#, c-format +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"hàm trả vá» bản ghi được gá»i trong ngữ cảnh không thể chấp nhận kiểu bản ghi" + +#: plperl.c:1408 +#, c-format +msgid "PL/Perl function must return reference to hash or array" +msgstr "Hàm PL/Perl phải trả vá» tham thiếu tá»›i giá trị băm hoặc mảng" + +#: plperl.c:1445 +#, c-format +msgid "lookup failed for type %s" +msgstr "không tìm thấy kiểu dữ liệu %s" + +#: plperl.c:1760 +#, c-format +msgid "$_TD->{new} does not exist" +msgstr "$_TD->{new} không tồn tại" + +#: plperl.c:1764 +#, c-format +msgid "$_TD->{new} is not a hash reference" +msgstr "$_TD->{new} không phải là má»™t tham chiếu giá trị băm" + +#: plperl.c:2016 plperl.c:2858 +#, c-format +msgid "PL/Perl functions cannot return type %s" +msgstr "Hàm PL/Perl không thể trả vá» kiểu %s" + +#: plperl.c:2029 plperl.c:2899 +#, c-format +msgid "PL/Perl functions cannot accept type %s" +msgstr "Hàm PL/Perl không thể chấp nhận kiểu %s" + +#: plperl.c:2146 +#, c-format +msgid "didn't get a CODE reference from compiling function \"%s\"" +msgstr "không nhận được tham chiếu CODE từ hàm biên dịch \"%s\"" + +#: plperl.c:2239 +#, c-format +msgid "didn't get a return item from function" +msgstr "không nhận được má»™t mục trả vá» từ hàm" + +#: plperl.c:2283 plperl.c:2350 +#, c-format +msgid "couldn't fetch $_TD" +msgstr "không thể fetch $_TD" + +#: plperl.c:2307 plperl.c:2370 +#, c-format +msgid "didn't get a return item from trigger function" +msgstr "không nhận được má»™t mục trả vá» từ hàm trigger" + +#: plperl.c:2431 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "" +"hàm thiết lập giá trị được gá»i trong ngữ cảnh không thể chấp nhận má»™t tập " +"hợp" + +#: plperl.c:2476 +#, c-format +msgid "" +"set-returning PL/Perl function must return reference to array or use " +"return_next" +msgstr "" +"hàm thiết lập-trả vá» PL/Perl phải trả vá» tham chiếu tá»›i mảng hay sá»­ dụng " +"return_next" + +#: plperl.c:2597 +#, c-format +msgid "ignoring modified row in DELETE trigger" +msgstr "bá» qua hàng đã sá»­a đổi trong trigger DELETE" + +#: plperl.c:2605 +#, c-format +msgid "" +"result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" +msgstr "" +"kết quả cá»§a hàm trigger PL/Perl phải là undef, \"SKIP\" hoặc \"MODIFY\"" + +#: plperl.c:2853 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "các hàm trigger chỉ có thể được gá»i như những trigger" + +#: plperl.c:3193 +#, c-format +msgid "query result has too many rows to fit in a Perl array" +msgstr "kết quả truy vấn có quá nhiá»u hàng có thể vừa vá»›i má»™t mảng Perl" + +#: plperl.c:3263 +#, c-format +msgid "cannot use return_next in a non-SETOF function" +msgstr "không thể sá»­ dụng return_next trong hàm không phải-SETOF" + +#: plperl.c:3337 +#, c-format +msgid "" +"SETOF-composite-returning PL/Perl function must call return_next with " +"reference to hash" +msgstr "" +"Hàm PL/Perl trả vá» SETOF-composite phải gá»i return_next vá»›i tham chiếu tá»›i " +"giá trị băm" + +#: plperl.c:4115 +#, c-format +msgid "PL/Perl function \"%s\"" +msgstr "Hàm PL/Perl \"%s\"" + +#: plperl.c:4127 +#, c-format +msgid "compilation of PL/Perl function \"%s\"" +msgstr "biên dịch hàm PL/Perl \"%s\"" + +#: plperl.c:4136 +#, c-format +msgid "PL/Perl anonymous code block" +msgstr "Khối mã ẩn danh PL/Perl" diff --git a/src/pl/plperl/po/zh_CN.po b/src/pl/plperl/po/zh_CN.po index 56886dd5c1e..a375433d09b 100644 --- a/src/pl/plperl/po/zh_CN.po +++ b/src/pl/plperl/po/zh_CN.po @@ -5,226 +5,218 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:37+0000\n" -"PO-Revision-Date: 2016-05-19 20:43+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Weibin \n" +"Project-Id-Version: plperl (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:08+0000\n" +"PO-Revision-Date: 2019-05-17 18:35+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.7\n" -#: plperl.c:405 -msgid "" -"If true, trusted and untrusted Perl code will be compiled in strict mode." +#: plperl.c:406 +msgid "If true, trusted and untrusted Perl code will be compiled in strict mode." msgstr "如果为真的è¯ï¼Œé‚£ä¹ˆä¿¡ä»»å’Œéžä¿¡ä»»çš„Perl代ç å°†ä»¥é™åˆ¶æ¨¡å¼ç¼–译." -#: plperl.c:419 -msgid "" -"Perl initialization code to execute when a Perl interpreter is initialized." +#: plperl.c:420 +msgid "Perl initialization code to execute when a Perl interpreter is initialized." msgstr "当åˆå§‹åŒ–一个Perl解释器时候执行Perlåˆå§‹åŒ–代ç " -#: plperl.c:441 +#: plperl.c:442 msgid "Perl initialization code to execute once when plperl is first used." msgstr "在第一次使用plperl的时候执行一次Perlåˆå§‹åŒ–代ç " -#: plperl.c:449 +#: plperl.c:450 msgid "Perl initialization code to execute once when plperlu is first used." msgstr "在plperlu第一次使用的时候执行一次Perlåˆå§‹åŒ–代ç " -#: plperl.c:646 +#: plperl.c:647 #, c-format msgid "cannot allocate multiple Perl interpreters on this platform" msgstr "在这个平å°ä¸Šæ— æ³•分é…多个Perl解释器" -#: plperl.c:666 plperl.c:841 plperl.c:847 plperl.c:961 plperl.c:973 -#: plperl.c:1016 plperl.c:1037 plperl.c:2080 plperl.c:2189 plperl.c:2256 -#: plperl.c:2318 +#: plperl.c:670 plperl.c:854 plperl.c:860 plperl.c:977 plperl.c:989 +#: plperl.c:1032 plperl.c:1055 plperl.c:2154 plperl.c:2264 plperl.c:2332 +#: plperl.c:2395 #, c-format msgid "%s" msgstr "%s" -#: plperl.c:667 +#: plperl.c:671 #, c-format msgid "while executing PostgreSQL::InServer::SPI::bootstrap" msgstr "åŒæ—¶åœ¨æ‰§è¡ŒPostgreSQL::InServer::SPI::bootstrap" -#: plperl.c:842 +#: plperl.c:855 #, c-format msgid "while parsing Perl initialization" msgstr "åŒæ—¶åœ¨è§£æžPerlåˆå§‹åŒ–" -#: plperl.c:848 +#: plperl.c:861 #, c-format msgid "while running Perl initialization" msgstr "åŒæ—¶åœ¨è¿è¡ŒPerlåˆå§‹åŒ–" -#: plperl.c:962 +#: plperl.c:978 #, c-format msgid "while executing PLC_TRUSTED" msgstr "åŒæ—¶åœ¨æ‰§è¡ŒPLC_TRUSTED" -#: plperl.c:974 +#: plperl.c:990 #, c-format msgid "while executing utf8fix" msgstr "åŒæ—¶åœ¨æ‰§è¡Œutf8fix" -#: plperl.c:1017 +#: plperl.c:1033 #, c-format msgid "while executing plperl.on_plperl_init" msgstr "åŒæ—¶åœ¨æ‰§è¡Œplperl.on_plperl_init" -#: plperl.c:1038 +#: plperl.c:1056 #, c-format msgid "while executing plperl.on_plperlu_init" msgstr "åŒæ—¶åœ¨æ‰§è¡Œplperl.on_plperlu_init" -#: plperl.c:1082 plperl.c:1722 +#: plperl.c:1102 plperl.c:1793 #, c-format msgid "Perl hash contains nonexistent column \"%s\"" msgstr "Perl的哈希功能包å«ä¸å­˜åœ¨çš„列\"%s\"" -#: plperl.c:1167 +#: plperl.c:1107 plperl.c:1798 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" + +#: plperl.c:1195 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "数组的维数(%d)超过最大å…许值(%d)" -#: plperl.c:1179 plperl.c:1196 +#: plperl.c:1207 plperl.c:1224 #, c-format -msgid "" -"multidimensional arrays must have array expressions with matching dimensions" +msgid "multidimensional arrays must have array expressions with matching dimensions" msgstr "多维数组必须有符åˆç»´åº¦çš„æ•°ç»„表达å¼" -#: plperl.c:1231 +#: plperl.c:1260 #, c-format msgid "cannot convert Perl array to non-array type %s" msgstr "无法将Perlæ•°ç»„è½¬æ¢æˆéžæ•°ç»„类型 %s" -#: plperl.c:1333 +#: plperl.c:1363 #, c-format msgid "cannot convert Perl hash to non-composite type %s" msgstr "无法将Perlå“ˆå¸Œç±»åž‹è½¬æ¢æˆéžç»„åˆç±»åž‹ %s" -#: plperl.c:1344 +#: plperl.c:1385 plperl.c:3306 #, c-format -msgid "" -"function returning record called in context that cannot accept type record" +msgid "function returning record called in context that cannot accept type record" msgstr "è¿”å›žå€¼ç±»åž‹æ˜¯è®°å½•çš„å‡½æ•°åœ¨ä¸æŽ¥å—使用记录类型的环境中调用" -#: plperl.c:1359 -#, c-format -msgid "PL/Perl function must return reference to hash or array" -msgstr "PL/Perl 函数必须返回对哈希或数组的引用" - -#: plperl.c:1396 +#: plperl.c:1444 #, c-format msgid "lookup failed for type %s" msgstr "类型%s查找失败" -#: plperl.c:1699 +#: plperl.c:1768 #, c-format msgid "$_TD->{new} does not exist" msgstr "$_TD->{new}ä¸å­˜åœ¨" -#: plperl.c:1703 +#: plperl.c:1772 #, c-format msgid "$_TD->{new} is not a hash reference" msgstr "$_TD->{new}䏿˜¯ä¸€ä¸ªå“ˆå¸Œå¼•用" -#: plperl.c:1956 plperl.c:2790 +#: plperl.c:1803 +#, fuzzy, c-format +#| msgid "cannot set system attribute \"%s\"" +msgid "cannot set generated column \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" + +#: plperl.c:2029 plperl.c:2871 #, c-format msgid "PL/Perl functions cannot return type %s" msgstr "PL/Perl函数无法返回类型%s" -#: plperl.c:1969 plperl.c:2835 +#: plperl.c:2042 plperl.c:2912 #, c-format msgid "PL/Perl functions cannot accept type %s" -msgstr "PL/Perl functions无法使用类型%s" +msgstr "PL/Perl 函数无法使用类型%s" -#: plperl.c:2085 +#: plperl.c:2159 #, c-format msgid "didn't get a CODE reference from compiling function \"%s\"" msgstr "没有从正在编译的函数 \"%s\"得到CODEå‚考" -#: plperl.c:2177 +#: plperl.c:2252 #, c-format msgid "didn't get a return item from function" msgstr "没有从函数得到一个返回项" -#: plperl.c:2220 plperl.c:2286 +#: plperl.c:2296 plperl.c:2363 #, c-format msgid "couldn't fetch $_TD" msgstr "无法å–å¾— $_TD" -#: plperl.c:2244 plperl.c:2306 +#: plperl.c:2320 plperl.c:2383 #, c-format msgid "didn't get a return item from trigger function" msgstr "没有从触å‘器函数得到一个返回项" -#: plperl.c:2363 +#: plperl.c:2444 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "集值函数在ä¸èƒ½ä½¿ç”¨é›†åˆçš„环境中调用" -#: plperl.c:2407 +#: plperl.c:2489 #, c-format -msgid "" -"set-returning PL/Perl function must return reference to array or use " -"return_next" +msgid "set-returning PL/Perl function must return reference to array or use return_next" msgstr "返回集åˆçš„PL/Perl函数必须返回对数组的引用或者使用return_next" -#: plperl.c:2521 +#: plperl.c:2610 #, c-format msgid "ignoring modified row in DELETE trigger" msgstr "在DELETE触å‘器中忽略已修改的记录" -#: plperl.c:2529 +#: plperl.c:2618 #, c-format -msgid "" -"result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" +msgid "result of PL/Perl trigger function must be undef, \"SKIP\", or \"MODIFY\"" msgstr "PL/Perl 触å‘器函数的结果必须是undef, \"SKIP\", 或 \"MODIFY\"" -#: plperl.c:2708 plperl.c:2718 -#, c-format -msgid "out of memory" -msgstr "内存用尽" - -#: plperl.c:2782 +#: plperl.c:2866 #, c-format msgid "trigger functions can only be called as triggers" msgstr "触å‘器函数åªèƒ½ä»¥è§¦å‘器的形å¼è°ƒç”¨" -#: plperl.c:3121 +#: plperl.c:3213 #, c-format msgid "query result has too many rows to fit in a Perl array" msgstr "查询结果中的行太多,无法放在一个Perl数组中" -#: plperl.c:3166 +#: plperl.c:3283 #, c-format msgid "cannot use return_next in a non-SETOF function" msgstr "ä¸èƒ½åœ¨éžSETOF函数中使用return_next" -#: plperl.c:3222 +#: plperl.c:3357 #, c-format -msgid "" -"SETOF-composite-returning PL/Perl function must call return_next with " -"reference to hash" +msgid "SETOF-composite-returning PL/Perl function must call return_next with reference to hash" msgstr "返回SETOF-组åˆç±»åž‹å€¼çš„PL/Perl函数必须调用带有对哈希引用的return_next" -#: plperl.c:3954 +#: plperl.c:4132 #, c-format msgid "PL/Perl function \"%s\"" msgstr "PL/Perl函数\"%s\"" -#: plperl.c:3966 +#: plperl.c:4144 #, c-format msgid "compilation of PL/Perl function \"%s\"" msgstr "编译PL/Perl函数\"%s\"" -#: plperl.c:3975 +#: plperl.c:4153 #, c-format msgid "PL/Perl anonymous code block" msgstr "PL/Perl匿å代ç å—" diff --git a/src/pl/plperl/sql/plperl.sql b/src/pl/plperl/sql/plperl.sql index c36da0ff043..b0d950b2304 100644 --- a/src/pl/plperl/sql/plperl.sql +++ b/src/pl/plperl/sql/plperl.sql @@ -504,7 +504,7 @@ $$ LANGUAGE plperl; SELECT text_obj(); ------ make sure we can't return a scalar ref +-- test looking through a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str; diff --git a/src/pl/plperl/sql/plperl_trigger.sql b/src/pl/plperl/sql/plperl_trigger.sql index 624193b9d08..4adddeb80ac 100644 --- a/src/pl/plperl/sql/plperl_trigger.sql +++ b/src/pl/plperl/sql/plperl_trigger.sql @@ -8,6 +8,11 @@ CREATE TABLE trigger_test ( foo rowcompnest ); +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); + CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plperl AS $$ # make sure keys are sorted for consistent results - perl no longer @@ -70,6 +75,21 @@ delete from trigger_test; DROP TRIGGER show_trigger_data_trig on trigger_test; +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); + +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); + +insert into trigger_test_generated (i) values (1); +update trigger_test_generated set i = 11 where i = 1; +delete from trigger_test_generated; + +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; + insert into trigger_test values(1,'insert', '("(1)")'); CREATE VIEW trigger_test_view AS SELECT * FROM trigger_test; @@ -221,3 +241,19 @@ drop table foo; drop event trigger perl_a_snitch; drop event trigger perl_b_snitch; + +-- dealing with generated columns + +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE plperl +AS $$ +$_TD->{new}{j} = 5; # not allowed +return 'MODIFY'; +$$; + +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); + +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +SELECT * FROM trigger_test_generated; diff --git a/src/pl/plperl/text2macro.pl b/src/pl/plperl/text2macro.pl index 27c6ef7e427..52fcbe1be1c 100644 --- a/src/pl/plperl/text2macro.pl +++ b/src/pl/plperl/text2macro.pl @@ -99,4 +99,5 @@ sub selftest warn "Test string: $string\n"; warn "Result : $result"; die "Failed!" if $result ne "$string\n"; + return; } diff --git a/src/pl/plpgsql/src/.gitignore b/src/pl/plpgsql/src/.gitignore index ff6ac965fdd..3ab9a2243cc 100644 --- a/src/pl/plpgsql/src/.gitignore +++ b/src/pl/plpgsql/src/.gitignore @@ -1,5 +1,7 @@ /pl_gram.c /pl_gram.h +/pl_reserved_kwlist_d.h +/pl_unreserved_kwlist_d.h /plerrcodes.h /log/ /results/ diff --git a/src/pl/plpgsql/src/Makefile b/src/pl/plpgsql/src/Makefile index dd17092fd5d..af9f6fb209b 100644 --- a/src/pl/plpgsql/src/Makefile +++ b/src/pl/plpgsql/src/Makefile @@ -27,7 +27,13 @@ DATA = plpgsql.control plpgsql--1.0.sql plpgsql--unpackaged--1.0.sql REGRESS_OPTS = --dbname=$(PL_TESTDB) REGRESS = plpgsql_call plpgsql_control plpgsql_domain plpgsql_record \ - plpgsql_transaction plpgsql_varprops + plpgsql_cache plpgsql_transaction plpgsql_trap \ + plpgsql_trigger plpgsql_varprops + +# where to find gen_keywordlist.pl and subsidiary files +TOOLSDIR = $(top_srcdir)/src/tools +GEN_KEYWORDLIST = $(PERL) -I $(TOOLSDIR) $(TOOLSDIR)/gen_keywordlist.pl +GEN_KEYWORDLIST_DEPS = $(TOOLSDIR)/gen_keywordlist.pl $(TOOLSDIR)/PerfectHash.pm all: all-lib @@ -61,6 +67,7 @@ uninstall-headers: # Force these dependencies to be known even without dependency info built: pl_gram.o pl_handler.o pl_comp.o pl_exec.o pl_funcs.o pl_scanner.o: plpgsql.h pl_gram.h plerrcodes.h +pl_scanner.o: pl_reserved_kwlist_d.h pl_unreserved_kwlist_d.h # See notes in src/backend/parser/Makefile about the following two rules pl_gram.h: pl_gram.c @@ -72,6 +79,13 @@ pl_gram.c: BISONFLAGS += -d plerrcodes.h: $(top_srcdir)/src/backend/utils/errcodes.txt generate-plerrcodes.pl $(PERL) $(srcdir)/generate-plerrcodes.pl $< > $@ +# generate keyword headers for the scanner +pl_reserved_kwlist_d.h: pl_reserved_kwlist.h $(GEN_KEYWORDLIST_DEPS) + $(GEN_KEYWORDLIST) --varname ReservedPLKeywords $< + +pl_unreserved_kwlist_d.h: pl_unreserved_kwlist.h $(GEN_KEYWORDLIST_DEPS) + $(GEN_KEYWORDLIST) --varname UnreservedPLKeywords $< + check: submake $(pg_regress_check) $(REGRESS_OPTS) $(REGRESS) @@ -84,13 +98,14 @@ submake: $(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X) -distprep: pl_gram.h pl_gram.c plerrcodes.h +distprep: pl_gram.h pl_gram.c plerrcodes.h pl_reserved_kwlist_d.h pl_unreserved_kwlist_d.h -# pl_gram.c, pl_gram.h and plerrcodes.h are in the distribution tarball, -# so they are not cleaned here. +# pl_gram.c, pl_gram.h, plerrcodes.h, pl_reserved_kwlist_d.h, and +# pl_unreserved_kwlist_d.h are in the distribution tarball, so they +# are not cleaned here. clean distclean: clean-lib rm -f $(OBJS) rm -rf $(pg_regress_clean_files) maintainer-clean: distclean - rm -f pl_gram.c pl_gram.h plerrcodes.h + rm -f pl_gram.c pl_gram.h plerrcodes.h pl_reserved_kwlist_d.h pl_unreserved_kwlist_d.h diff --git a/src/pl/plpgsql/src/expected/plpgsql_cache.out b/src/pl/plpgsql/src/expected/plpgsql_cache.out new file mode 100644 index 00000000000..c2cf0136050 --- /dev/null +++ b/src/pl/plpgsql/src/expected/plpgsql_cache.out @@ -0,0 +1,67 @@ +-- +-- Cache-behavior-dependent test cases +-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- between regular and CLOBBER_CACHE_ALWAYS builds, so we must have two +-- expected-output files to cover both cases. To minimize the maintenance +-- effort resulting from that, this file should contain only tests that +-- do have different results under CLOBBER_CACHE_ALWAYS. +-- +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text); +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$; +select c_sillyaddone(42); + c_sillyaddone +--------------- + 43 +(1 row) + +alter table c_mutable drop column f1; +alter table c_mutable add column f1 float8; +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select c_sillyaddone(42); +ERROR: type of parameter 4 (double precision) does not match that when preparing the plan (integer) +CONTEXT: PL/pgSQL function c_sillyaddone(integer) line 1 at RETURN +-- but it's OK if we force plan rebuilding +discard plans; +select c_sillyaddone(42); + c_sillyaddone +--------------- + 43 +(1 row) + +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$; +select show_result_type('select 1 as a'); + show_result_type +---------------------- + type integer value 1 +(1 row) + +-- currently this fails due to cached plan for pg_typeof expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select show_result_type('select 2.0 as a'); +ERROR: type of parameter 5 (numeric) does not match that when preparing the plan (integer) +CONTEXT: SQL statement "select pg_typeof(r.a)" +PL/pgSQL function show_result_type(text) line 7 at SQL statement +-- but it's OK if we force plan rebuilding +discard plans; +select show_result_type('select 2.0 as a'); + show_result_type +------------------------ + type numeric value 2.0 +(1 row) + diff --git a/src/pl/plpgsql/src/expected/plpgsql_cache_1.out b/src/pl/plpgsql/src/expected/plpgsql_cache_1.out new file mode 100644 index 00000000000..0ac2c64a15c --- /dev/null +++ b/src/pl/plpgsql/src/expected/plpgsql_cache_1.out @@ -0,0 +1,72 @@ +-- +-- Cache-behavior-dependent test cases +-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- between regular and CLOBBER_CACHE_ALWAYS builds, so we must have two +-- expected-output files to cover both cases. To minimize the maintenance +-- effort resulting from that, this file should contain only tests that +-- do have different results under CLOBBER_CACHE_ALWAYS. +-- +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text); +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$; +select c_sillyaddone(42); + c_sillyaddone +--------------- + 43 +(1 row) + +alter table c_mutable drop column f1; +alter table c_mutable add column f1 float8; +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select c_sillyaddone(42); + c_sillyaddone +--------------- + 43 +(1 row) + +-- but it's OK if we force plan rebuilding +discard plans; +select c_sillyaddone(42); + c_sillyaddone +--------------- + 43 +(1 row) + +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$; +select show_result_type('select 1 as a'); + show_result_type +---------------------- + type integer value 1 +(1 row) + +-- currently this fails due to cached plan for pg_typeof expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select show_result_type('select 2.0 as a'); + show_result_type +------------------------ + type numeric value 2.0 +(1 row) + +-- but it's OK if we force plan rebuilding +discard plans; +select show_result_type('select 2.0 as a'); + show_result_type +------------------------ + type numeric value 2.0 +(1 row) + diff --git a/src/pl/plpgsql/src/expected/plpgsql_call.out b/src/pl/plpgsql/src/expected/plpgsql_call.out index ab9d3bbc701..d9c88e85c8d 100644 --- a/src/pl/plpgsql/src/expected/plpgsql_call.out +++ b/src/pl/plpgsql/src/expected/plpgsql_call.out @@ -114,7 +114,7 @@ BEGIN RAISE INFO 'x = %, y = %', x, y; END; $$; -ERROR: argument 2 is an output argument but is not writable +ERROR: procedure parameter "b" is an output parameter but corresponding argument is not writable CONTEXT: PL/pgSQL function inline_code_block line 6 at CALL DO LANGUAGE plpgsql @@ -152,6 +152,118 @@ CALL test_proc7(100, -1, -1); 0 | 1 (1 row) +-- named parameters and defaults +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$; +CALL test_proc8a(10, 20); +NOTICE: a: 10, b: 20 + a | b +-----+---- + 100 | 30 +(1 row) + +CALL test_proc8a(b => 20, a => 10); +NOTICE: a: 10, b: 20 + a | b +-----+---- + 100 | 30 +(1 row) + +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$; +NOTICE: a: 10, b: 30 +NOTICE: _a: 100, _b: 40 +NOTICE: a: 100, b: 40 +NOTICE: _a: 1000, _b: 50 +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$; +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; +NOTICE: a: 10, b: 30, c: 50 +NOTICE: _a: 100, _b: 40, _c: -500 +NOTICE: a: 100, b: 40, c: -500 +NOTICE: _a: 1000, _b: 50, _c: 5000 +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$; +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; +NOTICE: a: 10, b: 30, c: 50 +NOTICE: _a: 100, _b: 40, _c: -500 +NOTICE: a: 10, b: 30, c: 50 +NOTICE: _a: 100, _b: 40, _c: -500 +NOTICE: a: 10, b: 30, c: 50 +NOTICE: _a: 100, _b: 40, _c: -500 +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; +ERROR: procedure parameter "c" is an output parameter but corresponding argument is not writable +CONTEXT: PL/pgSQL function inline_code_block line 5 at CALL +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; +ERROR: procedure parameter "c" is an output parameter but corresponding argument is not writable +CONTEXT: PL/pgSQL function inline_code_block line 5 at CALL -- transition variable assignment TRUNCATE test1; CREATE FUNCTION triggerfunc1() RETURNS trigger @@ -179,3 +291,50 @@ DROP PROCEDURE test_proc1; DROP PROCEDURE test_proc3; DROP PROCEDURE test_proc4; DROP TABLE test1; +-- more checks for named-parameter handling +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql; +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$; +ERROR: procedure parameter "v_text" is an output parameter but corresponding argument is not writable +CONTEXT: PL/pgSQL function inline_code_block line 6 at CALL +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$; +NOTICE: v_cnt = 42 +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$; +NOTICE: v_cnt = 10 +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$; +NOTICE: diff --git a/src/pl/plpgsql/src/expected/plpgsql_record.out b/src/pl/plpgsql/src/expected/plpgsql_record.out index 29e42fda6c1..403c6358b93 100644 --- a/src/pl/plpgsql/src/expected/plpgsql_record.out +++ b/src/pl/plpgsql/src/expected/plpgsql_record.out @@ -421,18 +421,8 @@ select sillyaddone(42); 43 (1 row) -alter table mutable drop column f1; -alter table mutable add column f1 float8; --- currently, this fails due to cached plan for "r.f1 + 1" expression --- select sillyaddone(42); -\c - --- but it's OK after a reconnect -select sillyaddone(42); - sillyaddone -------------- - 43 -(1 row) - +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test alter table mutable drop column f1; select sillyaddone(42); -- fail ERROR: record "r" has no field "f1" @@ -457,6 +447,35 @@ alter table mutable drop column f3; select getf3(null::mutable); -- fails again ERROR: record "x" has no field "f3" \set SHOW_CONTEXT errors +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off; -- else reference to nonexistent type fails +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$; +reset check_function_bodies; +select sillyaddtwo(42); -- fail +ERROR: type "mutable2" does not exist +LINE 1: declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end + ^ +QUERY: declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end +CONTEXT: compilation of PL/pgSQL function "sillyaddtwo" near line 1 +create table mutable2(f1 int, f2 text); +select sillyaddtwo(42); + sillyaddtwo +------------- + 44 +(1 row) + +drop table mutable2; +select sillyaddtwo(42); -- fail +ERROR: type "mutable2" does not exist +CONTEXT: PL/pgSQL function sillyaddtwo(integer) line 1 at assignment +create table mutable2(f0 text, f1 int, f2 text); +select sillyaddtwo(42); + sillyaddtwo +------------- + 44 +(1 row) + -- check access to system columns in a record variable create function sillytrig() returns trigger language plpgsql as $$begin @@ -664,3 +683,16 @@ NOTICE: processing row 2 NOTICE: processing row 3 ERROR: value for domain ordered_texts violates check constraint "ordered_texts_check" CONTEXT: PL/pgSQL function inline_code_block line 8 at assignment +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$; +create table two_int8s_tab (f1 two_int8s); +insert into two_int8s_tab values (compresult(42)); +-- reconnect so we lose any local knowledge of anonymous record types +\c - +table two_int8s_tab; + f1 +--------- + (42,42) +(1 row) + diff --git a/src/pl/plpgsql/src/expected/plpgsql_transaction.out b/src/pl/plpgsql/src/expected/plpgsql_transaction.out index 2d0e3fa85ed..5f576231c3c 100644 --- a/src/pl/plpgsql/src/expected/plpgsql_transaction.out +++ b/src/pl/plpgsql/src/expected/plpgsql_transaction.out @@ -130,6 +130,18 @@ $$; CALL transaction_test5(); ERROR: invalid transaction termination CONTEXT: PL/pgSQL function transaction_test5() line 3 at COMMIT +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$; +CALL transaction_test5b(); +ERROR: invalid transaction termination +CONTEXT: PL/pgSQL function transaction_test5b() line 3 at COMMIT TRUNCATE test1; -- nested procedure calls CREATE PROCEDURE transaction_test6(c text) @@ -389,6 +401,50 @@ SELECT * FROM test3; 1 (1 row) +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$; +TRUNCATE test1; +CALL cursor_fail_during_commit(); +ERROR: division by zero +CONTEXT: PL/pgSQL function cursor_fail_during_commit() line 6 at COMMIT +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1; + count +------- + 0 +(1 row) + +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$; +TRUNCATE test1; +CALL cursor_fail_during_rollback(); +ERROR: division by zero +CONTEXT: PL/pgSQL function cursor_fail_during_rollback() line 6 at ROLLBACK +SELECT count(*) FROM test1; + count +------- + 0 +(1 row) + -- SET TRANSACTION DO LANGUAGE plpgsql $$ BEGIN @@ -409,7 +465,7 @@ $$; INFO: read committed INFO: repeatable read INFO: read committed --- error case +-- error cases DO LANGUAGE plpgsql $$ BEGIN SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; @@ -418,6 +474,127 @@ $$; ERROR: SET TRANSACTION ISOLATION LEVEL must be called before any query CONTEXT: SQL statement "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ" PL/pgSQL function inline_code_block line 3 at SET +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$; +ERROR: unsupported transaction command in PL/pgSQL +CONTEXT: PL/pgSQL function inline_code_block line 3 at SQL statement +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$; +ERROR: EXECUTE of transaction commands is not implemented +CONTEXT: PL/pgSQL function inline_code_block line 3 at EXECUTE +-- snapshot handling test +TRUNCATE test2; +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$; +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$; +SELECT * FROM test2; + x +---- + 42 +(1 row) + +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$; +CALL transaction_test10a(10); + x +---- + 11 +(1 row) + +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$; +CALL transaction_test10b(10); + x +--- + 9 +(1 row) + +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$; +CALL transaction_test11(); +-- transaction chain +TRUNCATE test1; +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$; +INFO: transaction_isolation = repeatable read +INFO: transaction_isolation = repeatable read +INFO: transaction_isolation = repeatable read +INFO: transaction_isolation = repeatable read +SELECT * FROM test1; + a | b +---+--- + 0 | + 2 | +(2 rows) + DROP TABLE test1; DROP TABLE test2; DROP TABLE test3; diff --git a/src/pl/plpgsql/src/expected/plpgsql_trap.out b/src/pl/plpgsql/src/expected/plpgsql_trap.out new file mode 100644 index 00000000000..90cf6c28956 --- /dev/null +++ b/src/pl/plpgsql/src/expected/plpgsql_trap.out @@ -0,0 +1,255 @@ +-- +-- Test error trapping +-- +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql; +select trap_zero_divide(50); +NOTICE: should see this +NOTICE: should see this only if 50 <> 0 +NOTICE: should see this only if 50 fits in smallint + trap_zero_divide +------------------ + 2 +(1 row) + +select trap_zero_divide(0); +NOTICE: should see this +NOTICE: caught division_by_zero + trap_zero_divide +------------------ + -1 +(1 row) + +select trap_zero_divide(100000); +NOTICE: should see this +NOTICE: should see this only if 100000 <> 0 +NOTICE: caught numeric_value_out_of_range + trap_zero_divide +------------------ + -2 +(1 row) + +select trap_zero_divide(-100); +NOTICE: should see this +NOTICE: should see this only if -100 <> 0 +NOTICE: should see this only if -100 fits in smallint +ERROR: -100 is less than zero +CONTEXT: PL/pgSQL function trap_zero_divide(integer) line 12 at RAISE +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x; +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql; +select trap_matching_test(50); + trap_matching_test +-------------------- + 2 +(1 row) + +select trap_matching_test(0); +NOTICE: caught data_exception + trap_matching_test +-------------------- + -1 +(1 row) + +select trap_matching_test(100000); +NOTICE: caught data_exception + trap_matching_test +-------------------- + -1 +(1 row) + +select trap_matching_test(1); +NOTICE: caught numeric_value_out_of_range or cardinality_violation + trap_matching_test +-------------------- + -2 +(1 row) + +create temp table foo (f1 int); +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql; +select subxact_rollback_semantics(); + subxact_rollback_semantics +---------------------------- + 20 +(1 row) + +select * from foo; + f1 +---- + 1 + 20 +(2 rows) + +drop table foo; +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1000000000000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql; +begin; +set statement_timeout to 1000; +select trap_timeout(); +NOTICE: nyeah nyeah, can't stop me +ERROR: end of function +CONTEXT: PL/pgSQL function trap_timeout() line 15 at RAISE +rollback; +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql; +select test_variable_storage(); +NOTICE: should see this +NOTICE: should see this only if -100 <> 0 +NOTICE: should see this only if -100 fits in smallint + test_variable_storage +----------------------- + 123456789012 +(1 row) + +-- +-- test foreign key error trapping +-- +create temp table root(f1 int primary key); +create temp table leaf(f1 int references root deferrable); +insert into root values(1); +insert into leaf values(1); +insert into leaf values(2); -- fails +ERROR: insert or update on table "leaf" violates foreign key constraint "leaf_f1_fkey" +DETAIL: Key (f1)=(2) is not present in table "root". +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql; +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql; +select trap_foreign_key(1); + trap_foreign_key +------------------ + 1 +(1 row) + +select trap_foreign_key(2); -- detects FK violation +NOTICE: caught foreign_key_violation + trap_foreign_key +------------------ + 0 +(1 row) + +begin; + set constraints all deferred; + select trap_foreign_key(2); -- should not detect FK violation + trap_foreign_key +------------------ + 1 +(1 row) + + savepoint x; + set constraints all immediate; -- fails +ERROR: insert or update on table "leaf" violates foreign key constraint "leaf_f1_fkey" +DETAIL: Key (f1)=(2) is not present in table "root". + rollback to x; + select trap_foreign_key_2(); -- detects FK violation +NOTICE: caught foreign_key_violation + trap_foreign_key_2 +-------------------- + 0 +(1 row) + +commit; -- still fails +ERROR: insert or update on table "leaf" violates foreign key constraint "leaf_f1_fkey" +DETAIL: Key (f1)=(2) is not present in table "root". +drop function trap_foreign_key(int); +drop function trap_foreign_key_2(); diff --git a/src/pl/plpgsql/src/expected/plpgsql_trigger.out b/src/pl/plpgsql/src/expected/plpgsql_trigger.out new file mode 100644 index 00000000000..3cc67badbaa --- /dev/null +++ b/src/pl/plpgsql/src/expected/plpgsql_trigger.out @@ -0,0 +1,36 @@ +-- Simple test to verify accessibility of the OLD and NEW trigger variables +create table testtr (a int, b text); +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$; +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger(); +insert into testtr values (1, 'one'), (2, 'two'); +NOTICE: tg_op = INSERT +NOTICE: old() = (,) +NOTICE: new(1) = (1,one) +NOTICE: tg_op = INSERT +NOTICE: old() = (,) +NOTICE: new(2) = (2,two) +update testtr set a = a + 1; +NOTICE: tg_op = UPDATE +NOTICE: old(1) = (1,one) +NOTICE: new(2) = (2,one) +NOTICE: tg_op = UPDATE +NOTICE: old(2) = (2,two) +NOTICE: new(3) = (3,two) +delete from testtr; +NOTICE: tg_op = DELETE +NOTICE: old(2) = (2,one) +NOTICE: new() = (,) +NOTICE: tg_op = DELETE +NOTICE: old(3) = (3,two) +NOTICE: new() = (,) diff --git a/src/pl/plpgsql/src/generate-plerrcodes.pl b/src/pl/plpgsql/src/generate-plerrcodes.pl index 834cd5058fb..a3e6efcbb6b 100644 --- a/src/pl/plpgsql/src/generate-plerrcodes.pl +++ b/src/pl/plpgsql/src/generate-plerrcodes.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate the plerrcodes.h header from errcodes.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; diff --git a/src/pl/plpgsql/src/nls.mk b/src/pl/plpgsql/src/nls.mk index 1133668fc71..05512678e8f 100644 --- a/src/pl/plpgsql/src/nls.mk +++ b/src/pl/plpgsql/src/nls.mk @@ -1,6 +1,6 @@ # src/pl/plpgsql/src/nls.mk CATALOG_NAME = plpgsql -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv zh_CN zh_TW +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv tr vi zh_CN zh_TW GETTEXT_FILES = pl_comp.c pl_exec.c pl_gram.c pl_funcs.c pl_handler.c pl_scanner.c GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) yyerror plpgsql_yyerror GETTEXT_FLAGS = $(BACKEND_COMMON_GETTEXT_FLAGS) diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 2f41071dd3f..0c24ba692d2 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * pl_comp.c - Compiler part of the PL/pgSQL * procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -91,10 +91,10 @@ static const ExceptionLabelMap exception_label_map[] = { * ---------- */ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo, - HeapTuple procTup, - PLpgSQL_function *function, - PLpgSQL_func_hashkey *hashkey, - bool forValidator); + HeapTuple procTup, + PLpgSQL_function *function, + PLpgSQL_func_hashkey *hashkey, + bool forValidator); static void plpgsql_compile_error_callback(void *arg); static void add_parameter_name(PLpgSQL_nsitem_type itemtype, int itemno, const char *name); static void add_dummy_return(PLpgSQL_function *function); @@ -102,23 +102,24 @@ static Node *plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref); static Node *plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var); static Node *plpgsql_param_ref(ParseState *pstate, ParamRef *pref); static Node *resolve_column_ref(ParseState *pstate, PLpgSQL_expr *expr, - ColumnRef *cref, bool error_if_no_field); + ColumnRef *cref, bool error_if_no_field); static Node *make_datum_param(PLpgSQL_expr *expr, int dno, int location); static PLpgSQL_row *build_row_from_vars(PLpgSQL_variable **vars, int numvars); -static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod, Oid collation); +static PLpgSQL_type *build_datatype(HeapTuple typeTup, int32 typmod, + Oid collation, TypeName *origtypname); static void plpgsql_start_datums(void); static void plpgsql_finish_datums(PLpgSQL_function *function); static void compute_function_hashkey(FunctionCallInfo fcinfo, - Form_pg_proc procStruct, - PLpgSQL_func_hashkey *hashkey, - bool forValidator); + Form_pg_proc procStruct, + PLpgSQL_func_hashkey *hashkey, + bool forValidator); static void plpgsql_resolve_polymorphic_argtypes(int numargs, - Oid *argtypes, char *argmodes, - Node *call_expr, bool forValidator, - const char *proname); + Oid *argtypes, char *argmodes, + Node *call_expr, bool forValidator, + const char *proname); static PLpgSQL_function *plpgsql_HashTableLookup(PLpgSQL_func_hashkey *func_key); static void plpgsql_HashTableInsert(PLpgSQL_function *function, - PLpgSQL_func_hashkey *func_key); + PLpgSQL_func_hashkey *func_key); static void plpgsql_HashTableDelete(PLpgSQL_function *function); static void delete_function(PLpgSQL_function *func); @@ -368,6 +369,8 @@ do_compile(FunctionCallInfo fcinfo, function->fn_prokind = procStruct->prokind; + function->nstatements = 0; + /* * Initialize the compiler, particularly the namespace stack. The * outermost namespace contains function parameters and other special @@ -423,7 +426,8 @@ do_compile(FunctionCallInfo fcinfo, /* Create datatype info */ argdtype = plpgsql_build_datatype(argtypeid, -1, - function->fn_input_collation); + function->fn_input_collation, + NULL); /* Disallow pseudotype argument */ /* (note we already replaced polymorphic types) */ @@ -545,7 +549,7 @@ do_compile(FunctionCallInfo fcinfo, { if (rettypeid == VOIDOID || rettypeid == RECORDOID) - /* okay */ ; + /* okay */ ; else if (rettypeid == TRIGGEROID || rettypeid == EVTTRIGGEROID) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), @@ -563,9 +567,9 @@ do_compile(FunctionCallInfo fcinfo, function->fn_rettyplen = typeStruct->typlen; /* - * install $0 reference, but only for polymorphic return - * types, and not when the return is specified through an - * output parameter. + * install $0 reference, but only for polymorphic return types, + * and not when the return is specified through an output + * parameter. */ if (IsPolymorphicType(procStruct->prorettype) && num_out_args == 0) @@ -573,7 +577,8 @@ do_compile(FunctionCallInfo fcinfo, (void) plpgsql_build_variable("$0", 0, build_datatype(typeTup, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); } @@ -607,7 +612,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_name", 0, plpgsql_build_datatype(NAMEOID, -1, - InvalidOid), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -617,7 +623,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_when", 0, plpgsql_build_datatype(TEXTOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -627,7 +634,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_level", 0, plpgsql_build_datatype(TEXTOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -637,7 +645,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_op", 0, plpgsql_build_datatype(TEXTOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -647,7 +656,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_relid", 0, plpgsql_build_datatype(OIDOID, -1, - InvalidOid), + InvalidOid, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -657,7 +667,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_relname", 0, plpgsql_build_datatype(NAMEOID, -1, - InvalidOid), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -667,7 +678,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_table_name", 0, plpgsql_build_datatype(NAMEOID, -1, - InvalidOid), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -677,7 +689,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_table_schema", 0, plpgsql_build_datatype(NAMEOID, -1, - InvalidOid), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -687,7 +700,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_nargs", 0, plpgsql_build_datatype(INT4OID, -1, - InvalidOid), + InvalidOid, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -697,7 +711,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_argv", 0, plpgsql_build_datatype(TEXTARRAYOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -722,7 +737,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_event", 0, plpgsql_build_datatype(TEXTOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -732,7 +748,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("tg_tag", 0, plpgsql_build_datatype(TEXTOID, -1, - function->fn_input_collation), + function->fn_input_collation, + NULL), true); Assert(var->dtype == PLPGSQL_DTYPE_VAR); var->dtype = PLPGSQL_DTYPE_PROMISE; @@ -755,7 +772,8 @@ do_compile(FunctionCallInfo fcinfo, var = plpgsql_build_variable("found", 0, plpgsql_build_datatype(BOOLOID, -1, - InvalidOid), + InvalidOid, + NULL), true); function->found_varno = var->dno; @@ -880,6 +898,8 @@ plpgsql_compile_inline(char *proc_source) function->extra_warnings = 0; function->extra_errors = 0; + function->nstatements = 0; + plpgsql_ns_init(); plpgsql_ns_push(func_name, PLPGSQL_LABEL_BLOCK); plpgsql_DumpExecTree = false; @@ -907,7 +927,8 @@ plpgsql_compile_inline(char *proc_source) var = plpgsql_build_variable("found", 0, plpgsql_build_datatype(BOOLOID, -1, - InvalidOid), + InvalidOid, + NULL), true); function->found_varno = var->dno; @@ -1020,6 +1041,7 @@ add_dummy_return(PLpgSQL_function *function) new = palloc0(sizeof(PLpgSQL_stmt_block)); new->cmd_type = PLPGSQL_STMT_BLOCK; + new->stmtid = ++function->nstatements; new->body = list_make1(function->action); function->action = new; @@ -1031,6 +1053,7 @@ add_dummy_return(PLpgSQL_function *function) new = palloc0(sizeof(PLpgSQL_stmt_return)); new->cmd_type = PLPGSQL_STMT_RETURN; + new->stmtid = ++function->nstatements; new->expr = NULL; new->retvarno = function->out_param_varno; @@ -1353,6 +1376,9 @@ make_datum_param(PLpgSQL_expr *expr, int dno, int location) * yytxt is the original token text; we need this to check for quoting, * so that later checks for unreserved keywords work properly. * + * We attempt to recognize the token as a variable only if lookup is true + * and the plpgsql_IdentifierLookup context permits it. + * * If recognized as a variable, fill in *wdatum and return true; * if not recognized, fill in *word and return false. * (Note: those two pointers actually point to members of the same union, @@ -1360,17 +1386,17 @@ make_datum_param(PLpgSQL_expr *expr, int dno, int location) * ---------- */ bool -plpgsql_parse_word(char *word1, const char *yytxt, +plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, PLwdatum *wdatum, PLword *word) { PLpgSQL_nsitem *ns; /* - * We should do nothing in DECLARE sections. In SQL expressions, there's - * no need to do anything either --- lookup will happen when the - * expression is compiled. + * We should not lookup variables in DECLARE sections. In SQL + * expressions, there's no need to do so either --- lookup will happen + * when the expression is compiled. */ - if (plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_NORMAL) + if (lookup && plpgsql_IdentifierLookup == IDENTIFIER_LOOKUP_NORMAL) { /* * Do a lookup in the current namespace stack @@ -1567,6 +1593,7 @@ plpgsql_parse_wordtype(char *ident) { PLpgSQL_type *dtype; PLpgSQL_nsitem *nse; + TypeName *typeName; HeapTuple typeTup; /* @@ -1594,7 +1621,8 @@ plpgsql_parse_wordtype(char *ident) * Word wasn't found in the namespace stack. Try to find a data type with * that name, but ignore shell types and complex types. */ - typeTup = LookupTypeName(NULL, makeTypeName(ident), NULL, false); + typeName = makeTypeName(ident); + typeTup = LookupTypeName(NULL, typeName, NULL, false); if (typeTup) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); @@ -1607,7 +1635,8 @@ plpgsql_parse_wordtype(char *ident) } dtype = build_datatype(typeTup, -1, - plpgsql_curr_compile->fn_input_collation); + plpgsql_curr_compile->fn_input_collation, + typeName); ReleaseSysCache(typeTup); return dtype; @@ -1718,12 +1747,14 @@ plpgsql_parse_cwordtype(List *idents) /* * Found that - build a compiler type struct in the caller's cxt and - * return it + * return it. Note that we treat the type as being found-by-OID; no + * attempt to re-look-up the type name will happen during invalidations. */ MemoryContextSwitchTo(oldCxt); dtype = build_datatype(typetup, attrStruct->atttypmod, - attrStruct->attcollation); + attrStruct->attcollation, + NULL); MemoryContextSwitchTo(plpgsql_compile_tmp_cxt); done: @@ -1748,7 +1779,13 @@ plpgsql_parse_wordrowtype(char *ident) { Oid classOid; - /* Lookup the relation */ + /* + * Look up the relation. Note that because relation rowtypes have the + * same names as their relations, this could be handled as a type lookup + * equally well; we use the relation lookup code path only because the + * errors thrown here have traditionally referred to relations not types. + * But we'll make a TypeName in case we have to do re-look-up of the type. + */ classOid = RelnameGetRelid(ident); if (!OidIsValid(classOid)) ereport(ERROR, @@ -1756,7 +1793,8 @@ plpgsql_parse_wordrowtype(char *ident) errmsg("relation \"%s\" does not exist", ident))); /* Build and return the row type struct */ - return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid); + return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid, + makeTypeName(ident)); } /* ---------- @@ -1771,6 +1809,10 @@ plpgsql_parse_cwordrowtype(List *idents) RangeVar *relvar; MemoryContext oldCxt; + /* + * As above, this is a relation lookup but could be a type lookup if we + * weren't being backwards-compatible about error wording. + */ if (list_length(idents) != 2) return NULL; @@ -1786,7 +1828,8 @@ plpgsql_parse_cwordrowtype(List *idents) MemoryContextSwitchTo(oldCxt); /* Build and return the row type struct */ - return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid); + return plpgsql_build_datatype(get_rel_type_id(classOid), -1, InvalidOid, + makeTypeNameFromNameList(idents)); } /* @@ -1896,7 +1939,9 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars) row = palloc0(sizeof(PLpgSQL_row)); row->dtype = PLPGSQL_DTYPE_ROW; - row->rowtupdesc = CreateTemplateTupleDesc(numvars, false); + row->refname = "(unnamed row)"; + row->lineno = -1; + row->rowtupdesc = CreateTemplateTupleDesc(numvars); row->nfields = numvars; row->fieldnames = palloc(numvars * sizeof(char *)); row->varnos = palloc(numvars * sizeof(int)); @@ -1921,6 +1966,7 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars) break; case PLPGSQL_DTYPE_REC: + /* shouldn't need to revalidate rectypeid already... */ typoid = ((PLpgSQL_rec *) var)->rectypeid; typmod = -1; /* don't know typmod, if it's used at all */ typcoll = InvalidOid; /* composite types have no collation */ @@ -1989,13 +2035,19 @@ plpgsql_build_recfield(PLpgSQL_rec *rec, const char *fldname) /* * plpgsql_build_datatype - * Build PLpgSQL_type struct given type OID, typmod, and collation. + * Build PLpgSQL_type struct given type OID, typmod, collation, + * and type's parsed name. * * If collation is not InvalidOid then it overrides the type's default * collation. But collation is ignored if the datatype is non-collatable. + * + * origtypname is the parsed form of what the user wrote as the type name. + * It can be NULL if the type could not be a composite type, or if it was + * identified by OID to begin with (e.g., it's a function argument type). */ PLpgSQL_type * -plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation) +plpgsql_build_datatype(Oid typeOid, int32 typmod, + Oid collation, TypeName *origtypname) { HeapTuple typeTup; PLpgSQL_type *typ; @@ -2004,7 +2056,7 @@ plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation) if (!HeapTupleIsValid(typeTup)) elog(ERROR, "cache lookup failed for type %u", typeOid); - typ = build_datatype(typeTup, typmod, collation); + typ = build_datatype(typeTup, typmod, collation, origtypname); ReleaseSysCache(typeTup); @@ -2013,9 +2065,11 @@ plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation) /* * Utility subroutine to make a PLpgSQL_type struct given a pg_type entry + * and additional details (see comments for plpgsql_build_datatype). */ static PLpgSQL_type * -build_datatype(HeapTuple typeTup, int32 typmod, Oid collation) +build_datatype(HeapTuple typeTup, int32 typmod, + Oid collation, TypeName *origtypname) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); PLpgSQL_type *typ; @@ -2029,7 +2083,7 @@ build_datatype(HeapTuple typeTup, int32 typmod, Oid collation) typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type)); typ->typname = pstrdup(NameStr(typeStruct->typname)); - typ->typoid = HeapTupleGetOid(typeTup); + typ->typoid = typeStruct->oid; switch (typeStruct->typtype) { case TYPTYPE_BASE: @@ -2086,6 +2140,39 @@ build_datatype(HeapTuple typeTup, int32 typmod, Oid collation) typ->typisarray = false; typ->atttypmod = typmod; + /* + * If it's a named composite type (or domain over one), find the typcache + * entry and record the current tupdesc ID, so we can detect changes + * (including drops). We don't currently support on-the-fly replacement + * of non-composite types, else we might want to do this for them too. + */ + if (typ->ttype == PLPGSQL_TTYPE_REC && typ->typoid != RECORDOID) + { + TypeCacheEntry *typentry; + + typentry = lookup_type_cache(typ->typoid, + TYPECACHE_TUPDESC | + TYPECACHE_DOMAIN_BASE_INFO); + if (typentry->typtype == TYPTYPE_DOMAIN) + typentry = lookup_type_cache(typentry->domainBaseType, + TYPECACHE_TUPDESC); + if (typentry->tupDesc == NULL) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("type %s is not composite", + format_type_be(typ->typoid)))); + + typ->origtypname = origtypname; + typ->tcache = typentry; + typ->tupdesc_id = typentry->tupDesc_identifier; + } + else + { + typ->origtypname = NULL; + typ->tcache = NULL; + typ->tupdesc_id = 0; + } + return typ; } @@ -2201,7 +2288,7 @@ plpgsql_start_datums(void) * ---------- */ void -plpgsql_adddatum(PLpgSQL_datum *new) +plpgsql_adddatum(PLpgSQL_datum *newdatum) { if (plpgsql_nDatums == datums_alloc) { @@ -2209,8 +2296,8 @@ plpgsql_adddatum(PLpgSQL_datum *new) plpgsql_Datums = repalloc(plpgsql_Datums, sizeof(PLpgSQL_datum *) * datums_alloc); } - new->dno = plpgsql_nDatums; - plpgsql_Datums[plpgsql_nDatums++] = new; + newdatum->dno = plpgsql_nDatums; + plpgsql_Datums[plpgsql_nDatums++] = newdatum; } /* ---------- @@ -2441,7 +2528,7 @@ delete_function(PLpgSQL_function *func) plpgsql_free_function_memory(func); } -/* exported so we can call it from plpgsql_init() */ +/* exported so we can call it from _PG_init() */ void plpgsql_HashTableInit(void) { diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 4b6f51ac98d..cb2e19cda48 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * pl_exec.c - Executor for the PL/pgSQL * procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -17,6 +17,7 @@ #include +#include "access/detoast.h" #include "access/htup_details.h" #include "access/transam.h" #include "access/tupconvert.h" @@ -29,8 +30,9 @@ #include "funcapi.h" #include "miscadmin.h" #include "nodes/nodeFuncs.h" -#include "optimizer/planner.h" +#include "optimizer/optimizer.h" #include "parser/parse_coerce.h" +#include "parser/parse_type.h" #include "parser/scansup.h" #include "storage/proc.h" #include "tcop/tcopprot.h" @@ -150,6 +152,7 @@ typedef struct /* cast_hash table entry */ { plpgsql_CastHashKey key; /* hash key --- MUST BE FIRST */ Expr *cast_expr; /* cast expression, or NULL if no-op cast */ + CachedExpression *cast_cexpr; /* cached expression backing the above */ /* ExprState is valid only when cast_lxid matches current LXID */ ExprState *cast_exprstate; /* expression's eval tree */ bool cast_in_use; /* true while we're executing eval tree */ @@ -237,81 +240,81 @@ static HTAB *shared_cast_hash = NULL; * Local function forward declarations ************************************************************/ static void coerce_function_result_tuple(PLpgSQL_execstate *estate, - TupleDesc tupdesc); + TupleDesc tupdesc); static void plpgsql_exec_error_callback(void *arg); static void copy_plpgsql_datums(PLpgSQL_execstate *estate, - PLpgSQL_function *func); + PLpgSQL_function *func); static void plpgsql_fulfill_promise(PLpgSQL_execstate *estate, - PLpgSQL_var *var); + PLpgSQL_var *var); static MemoryContext get_stmt_mcontext(PLpgSQL_execstate *estate); static void push_stmt_mcontext(PLpgSQL_execstate *estate); static void pop_stmt_mcontext(PLpgSQL_execstate *estate); -static int exec_stmt_block(PLpgSQL_execstate *estate, - PLpgSQL_stmt_block *block); -static int exec_stmts(PLpgSQL_execstate *estate, - List *stmts); -static int exec_stmt(PLpgSQL_execstate *estate, - PLpgSQL_stmt *stmt); -static int exec_stmt_assign(PLpgSQL_execstate *estate, - PLpgSQL_stmt_assign *stmt); -static int exec_stmt_perform(PLpgSQL_execstate *estate, - PLpgSQL_stmt_perform *stmt); -static int exec_stmt_call(PLpgSQL_execstate *estate, - PLpgSQL_stmt_call *stmt); -static int exec_stmt_getdiag(PLpgSQL_execstate *estate, - PLpgSQL_stmt_getdiag *stmt); -static int exec_stmt_if(PLpgSQL_execstate *estate, - PLpgSQL_stmt_if *stmt); -static int exec_stmt_case(PLpgSQL_execstate *estate, - PLpgSQL_stmt_case *stmt); -static int exec_stmt_loop(PLpgSQL_execstate *estate, - PLpgSQL_stmt_loop *stmt); -static int exec_stmt_while(PLpgSQL_execstate *estate, - PLpgSQL_stmt_while *stmt); -static int exec_stmt_fori(PLpgSQL_execstate *estate, - PLpgSQL_stmt_fori *stmt); -static int exec_stmt_fors(PLpgSQL_execstate *estate, - PLpgSQL_stmt_fors *stmt); -static int exec_stmt_forc(PLpgSQL_execstate *estate, - PLpgSQL_stmt_forc *stmt); -static int exec_stmt_foreach_a(PLpgSQL_execstate *estate, - PLpgSQL_stmt_foreach_a *stmt); -static int exec_stmt_open(PLpgSQL_execstate *estate, - PLpgSQL_stmt_open *stmt); -static int exec_stmt_fetch(PLpgSQL_execstate *estate, - PLpgSQL_stmt_fetch *stmt); -static int exec_stmt_close(PLpgSQL_execstate *estate, - PLpgSQL_stmt_close *stmt); -static int exec_stmt_exit(PLpgSQL_execstate *estate, - PLpgSQL_stmt_exit *stmt); -static int exec_stmt_return(PLpgSQL_execstate *estate, - PLpgSQL_stmt_return *stmt); -static int exec_stmt_return_next(PLpgSQL_execstate *estate, - PLpgSQL_stmt_return_next *stmt); -static int exec_stmt_return_query(PLpgSQL_execstate *estate, - PLpgSQL_stmt_return_query *stmt); -static int exec_stmt_raise(PLpgSQL_execstate *estate, - PLpgSQL_stmt_raise *stmt); -static int exec_stmt_assert(PLpgSQL_execstate *estate, - PLpgSQL_stmt_assert *stmt); -static int exec_stmt_execsql(PLpgSQL_execstate *estate, - PLpgSQL_stmt_execsql *stmt); -static int exec_stmt_dynexecute(PLpgSQL_execstate *estate, - PLpgSQL_stmt_dynexecute *stmt); -static int exec_stmt_dynfors(PLpgSQL_execstate *estate, - PLpgSQL_stmt_dynfors *stmt); -static int exec_stmt_commit(PLpgSQL_execstate *estate, - PLpgSQL_stmt_commit *stmt); -static int exec_stmt_rollback(PLpgSQL_execstate *estate, - PLpgSQL_stmt_rollback *stmt); -static int exec_stmt_set(PLpgSQL_execstate *estate, - PLpgSQL_stmt_set *stmt); +static int exec_stmt_block(PLpgSQL_execstate *estate, + PLpgSQL_stmt_block *block); +static int exec_stmts(PLpgSQL_execstate *estate, + List *stmts); +static int exec_stmt(PLpgSQL_execstate *estate, + PLpgSQL_stmt *stmt); +static int exec_stmt_assign(PLpgSQL_execstate *estate, + PLpgSQL_stmt_assign *stmt); +static int exec_stmt_perform(PLpgSQL_execstate *estate, + PLpgSQL_stmt_perform *stmt); +static int exec_stmt_call(PLpgSQL_execstate *estate, + PLpgSQL_stmt_call *stmt); +static int exec_stmt_getdiag(PLpgSQL_execstate *estate, + PLpgSQL_stmt_getdiag *stmt); +static int exec_stmt_if(PLpgSQL_execstate *estate, + PLpgSQL_stmt_if *stmt); +static int exec_stmt_case(PLpgSQL_execstate *estate, + PLpgSQL_stmt_case *stmt); +static int exec_stmt_loop(PLpgSQL_execstate *estate, + PLpgSQL_stmt_loop *stmt); +static int exec_stmt_while(PLpgSQL_execstate *estate, + PLpgSQL_stmt_while *stmt); +static int exec_stmt_fori(PLpgSQL_execstate *estate, + PLpgSQL_stmt_fori *stmt); +static int exec_stmt_fors(PLpgSQL_execstate *estate, + PLpgSQL_stmt_fors *stmt); +static int exec_stmt_forc(PLpgSQL_execstate *estate, + PLpgSQL_stmt_forc *stmt); +static int exec_stmt_foreach_a(PLpgSQL_execstate *estate, + PLpgSQL_stmt_foreach_a *stmt); +static int exec_stmt_open(PLpgSQL_execstate *estate, + PLpgSQL_stmt_open *stmt); +static int exec_stmt_fetch(PLpgSQL_execstate *estate, + PLpgSQL_stmt_fetch *stmt); +static int exec_stmt_close(PLpgSQL_execstate *estate, + PLpgSQL_stmt_close *stmt); +static int exec_stmt_exit(PLpgSQL_execstate *estate, + PLpgSQL_stmt_exit *stmt); +static int exec_stmt_return(PLpgSQL_execstate *estate, + PLpgSQL_stmt_return *stmt); +static int exec_stmt_return_next(PLpgSQL_execstate *estate, + PLpgSQL_stmt_return_next *stmt); +static int exec_stmt_return_query(PLpgSQL_execstate *estate, + PLpgSQL_stmt_return_query *stmt); +static int exec_stmt_raise(PLpgSQL_execstate *estate, + PLpgSQL_stmt_raise *stmt); +static int exec_stmt_assert(PLpgSQL_execstate *estate, + PLpgSQL_stmt_assert *stmt); +static int exec_stmt_execsql(PLpgSQL_execstate *estate, + PLpgSQL_stmt_execsql *stmt); +static int exec_stmt_dynexecute(PLpgSQL_execstate *estate, + PLpgSQL_stmt_dynexecute *stmt); +static int exec_stmt_dynfors(PLpgSQL_execstate *estate, + PLpgSQL_stmt_dynfors *stmt); +static int exec_stmt_commit(PLpgSQL_execstate *estate, + PLpgSQL_stmt_commit *stmt); +static int exec_stmt_rollback(PLpgSQL_execstate *estate, + PLpgSQL_stmt_rollback *stmt); +static int exec_stmt_set(PLpgSQL_execstate *estate, + PLpgSQL_stmt_set *stmt); static void plpgsql_estate_setup(PLpgSQL_execstate *estate, - PLpgSQL_function *func, - ReturnSetInfo *rsi, - EState *simple_eval_estate); + PLpgSQL_function *func, + ReturnSetInfo *rsi, + EState *simple_eval_estate); static void exec_eval_cleanup(PLpgSQL_execstate *estate); static void exec_prepare_plan(PLpgSQL_execstate *estate, @@ -322,112 +325,113 @@ static void exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan); static void exec_check_rw_parameter(PLpgSQL_expr *expr, int target_dno); static bool contains_target_param(Node *node, int *target_dno); static bool exec_eval_simple_expr(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, - Datum *result, - bool *isNull, - Oid *rettype, - int32 *rettypmod); + PLpgSQL_expr *expr, + Datum *result, + bool *isNull, + Oid *rettype, + int32 *rettypmod); static void exec_assign_expr(PLpgSQL_execstate *estate, - PLpgSQL_datum *target, - PLpgSQL_expr *expr); + PLpgSQL_datum *target, + PLpgSQL_expr *expr); static void exec_assign_c_string(PLpgSQL_execstate *estate, - PLpgSQL_datum *target, - const char *str); + PLpgSQL_datum *target, + const char *str); static void exec_assign_value(PLpgSQL_execstate *estate, - PLpgSQL_datum *target, - Datum value, bool isNull, - Oid valtype, int32 valtypmod); + PLpgSQL_datum *target, + Datum value, bool isNull, + Oid valtype, int32 valtypmod); static void exec_eval_datum(PLpgSQL_execstate *estate, - PLpgSQL_datum *datum, - Oid *typeid, - int32 *typetypmod, - Datum *value, - bool *isnull); -static int exec_eval_integer(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, - bool *isNull); + PLpgSQL_datum *datum, + Oid *typeid, + int32 *typetypmod, + Datum *value, + bool *isnull); +static int exec_eval_integer(PLpgSQL_execstate *estate, + PLpgSQL_expr *expr, + bool *isNull); static bool exec_eval_boolean(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, - bool *isNull); + PLpgSQL_expr *expr, + bool *isNull); static Datum exec_eval_expr(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, - bool *isNull, - Oid *rettype, - int32 *rettypmod); -static int exec_run_select(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr, long maxtuples, Portal *portalP); -static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt, - Portal portal, bool prefetch_ok); + PLpgSQL_expr *expr, + bool *isNull, + Oid *rettype, + int32 *rettypmod); +static int exec_run_select(PLpgSQL_execstate *estate, + PLpgSQL_expr *expr, long maxtuples, Portal *portalP); +static int exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt, + Portal portal, bool prefetch_ok); static ParamListInfo setup_param_list(PLpgSQL_execstate *estate, - PLpgSQL_expr *expr); + PLpgSQL_expr *expr); static ParamExternData *plpgsql_param_fetch(ParamListInfo params, - int paramid, bool speculative, - ParamExternData *workspace); + int paramid, bool speculative, + ParamExternData *workspace); static void plpgsql_param_compile(ParamListInfo params, Param *param, - ExprState *state, - Datum *resv, bool *resnull); + ExprState *state, + Datum *resv, bool *resnull); static void plpgsql_param_eval_var(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); static void plpgsql_param_eval_var_ro(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); static void plpgsql_param_eval_recfield(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); static void plpgsql_param_eval_generic(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); static void plpgsql_param_eval_generic_ro(ExprState *state, ExprEvalStep *op, - ExprContext *econtext); + ExprContext *econtext); static void exec_move_row(PLpgSQL_execstate *estate, - PLpgSQL_variable *target, - HeapTuple tup, TupleDesc tupdesc); + PLpgSQL_variable *target, + HeapTuple tup, TupleDesc tupdesc); +static void revalidate_rectypeid(PLpgSQL_rec *rec); static ExpandedRecordHeader *make_expanded_record_for_rec(PLpgSQL_execstate *estate, - PLpgSQL_rec *rec, - TupleDesc srctupdesc, - ExpandedRecordHeader *srcerh); + PLpgSQL_rec *rec, + TupleDesc srctupdesc, + ExpandedRecordHeader *srcerh); static void exec_move_row_from_fields(PLpgSQL_execstate *estate, - PLpgSQL_variable *target, - ExpandedRecordHeader *newerh, - Datum *values, bool *nulls, - TupleDesc tupdesc); + PLpgSQL_variable *target, + ExpandedRecordHeader *newerh, + Datum *values, bool *nulls, + TupleDesc tupdesc); static bool compatible_tupdescs(TupleDesc src_tupdesc, TupleDesc dst_tupdesc); static HeapTuple make_tuple_from_row(PLpgSQL_execstate *estate, - PLpgSQL_row *row, - TupleDesc tupdesc); + PLpgSQL_row *row, + TupleDesc tupdesc); static TupleDesc deconstruct_composite_datum(Datum value, - HeapTupleData *tmptup); + HeapTupleData *tmptup); static void exec_move_row_from_datum(PLpgSQL_execstate *estate, - PLpgSQL_variable *target, - Datum value); + PLpgSQL_variable *target, + Datum value); static void instantiate_empty_record_variable(PLpgSQL_execstate *estate, - PLpgSQL_rec *rec); + PLpgSQL_rec *rec); static char *convert_value_to_string(PLpgSQL_execstate *estate, - Datum value, Oid valtype); + Datum value, Oid valtype); static Datum exec_cast_value(PLpgSQL_execstate *estate, - Datum value, bool *isnull, - Oid valtype, int32 valtypmod, - Oid reqtype, int32 reqtypmod); + Datum value, bool *isnull, + Oid valtype, int32 valtypmod, + Oid reqtype, int32 reqtypmod); static plpgsql_CastHashEntry *get_cast_hashentry(PLpgSQL_execstate *estate, - Oid srctype, int32 srctypmod, - Oid dsttype, int32 dsttypmod); + Oid srctype, int32 srctypmod, + Oid dsttype, int32 dsttypmod); static void exec_init_tuple_store(PLpgSQL_execstate *estate); static void exec_set_found(PLpgSQL_execstate *estate, bool state); static void plpgsql_create_econtext(PLpgSQL_execstate *estate); static void plpgsql_destroy_econtext(PLpgSQL_execstate *estate); static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, - Datum newvalue, bool isnull, bool freeable); + Datum newvalue, bool isnull, bool freeable); static void assign_text_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, - const char *str); + const char *str); static void assign_record_var(PLpgSQL_execstate *estate, PLpgSQL_rec *rec, - ExpandedRecordHeader *erh); + ExpandedRecordHeader *erh); static PreparedParamsData *exec_eval_using_params(PLpgSQL_execstate *estate, - List *params); + List *params); static Portal exec_dynquery_with_params(PLpgSQL_execstate *estate, - PLpgSQL_expr *dynquery, List *params, - const char *portalname, int cursorOptions); + PLpgSQL_expr *dynquery, List *params, + const char *portalname, int cursorOptions); static char *format_expr_params(PLpgSQL_execstate *estate, - const PLpgSQL_expr *expr); + const PLpgSQL_expr *expr); static char *format_preparedparamsdata(PLpgSQL_execstate *estate, - const PreparedParamsData *ppd); + const PreparedParamsData *ppd); /* ---------- @@ -488,8 +492,8 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo, PLpgSQL_var *var = (PLpgSQL_var *) estate.datums[n]; assign_simple_var(&estate, var, - fcinfo->arg[i], - fcinfo->argnull[i], + fcinfo->args[i].value, + fcinfo->args[i].isnull, false); /* @@ -540,12 +544,12 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo, { PLpgSQL_rec *rec = (PLpgSQL_rec *) estate.datums[n]; - if (!fcinfo->argnull[i]) + if (!fcinfo->args[i].isnull) { /* Assign row value from composite datum */ exec_move_row_from_datum(&estate, (PLpgSQL_variable *) rec, - fcinfo->arg[i]); + fcinfo->args[i].value); } else { @@ -582,7 +586,7 @@ plpgsql_exec_function(PLpgSQL_function *func, FunctionCallInfo fcinfo, */ estate.err_text = NULL; estate.err_stmt = (PLpgSQL_stmt *) (func->action); - rc = exec_stmt_block(&estate, func->action); + rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action); if (rc != PLPGSQL_RC_RETURN) { estate.err_stmt = NULL; @@ -797,7 +801,7 @@ coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc) { rettup = expanded_record_get_tuple(erh); Assert(rettup); - rettup = do_convert_tuple(rettup, tupmap); + rettup = execute_attr_map_tuple(rettup, tupmap); /* * Copy tuple to upper executor memory, as a tuple Datum. Make @@ -806,6 +810,31 @@ coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc) estate->retval = PointerGetDatum(SPI_returntuple(rettup, tupdesc)); /* no need to free map, we're about to return anyway */ } + else if (!(tupdesc->tdtypeid == erh->er_decltypeid || + (tupdesc->tdtypeid == RECORDOID && + !ExpandedRecordIsDomain(erh)))) + { + /* + * The expanded record has the right physical tupdesc, but the + * wrong type ID. (Typically, the expanded record is RECORDOID + * but the function is declared to return a named composite type. + * As in exec_move_row_from_datum, we don't allow returning a + * composite-domain record from a function declared to return + * RECORD.) So we must flatten the record to a tuple datum and + * overwrite its type fields with the right thing. spi.c doesn't + * provide any easy way to deal with this case, so we end up + * duplicating the guts of datumCopy() :-( + */ + Size resultsize; + HeapTupleHeader tuphdr; + + resultsize = EOH_get_flat_size(&erh->hdr); + tuphdr = (HeapTupleHeader) SPI_palloc(resultsize); + EOH_flatten_into(&erh->hdr, (void *) tuphdr, resultsize); + HeapTupleHeaderSetTypeId(tuphdr, tupdesc->tdtypeid); + HeapTupleHeaderSetTypMod(tuphdr, tupdesc->tdtypmod); + estate->retval = PointerGetDatum(tuphdr); + } else { /* @@ -833,7 +862,7 @@ coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc) /* it might need conversion */ if (tupmap) - rettup = do_convert_tuple(rettup, tupmap); + rettup = execute_attr_map_tuple(rettup, tupmap); /* * Copy tuple to upper executor memory, as a tuple Datum. Make sure @@ -888,11 +917,12 @@ plpgsql_exec_trigger(PLpgSQL_function *func, /* * Put the OLD and NEW tuples into record variables * - * We make the tupdescs available in both records even though only one may - * have a value. This allows parsing of record references to succeed in - * functions that are used for multiple trigger types. For example, we - * might have a test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", - * which should parse regardless of the current trigger type. + * We set up expanded records for both variables even though only one may + * have a value. This allows record references to succeed in functions + * that are used for multiple trigger types. For example, we might have a + * test like "if (TG_OP = 'INSERT' and NEW.foo = 'xyz')", which should + * work regardless of the current trigger type. If a value is actually + * fetched from an unsupplied tuple, it will read as NULL. */ tupdesc = RelationGetDescr(trigdata->tg_relation); @@ -912,16 +942,40 @@ plpgsql_exec_trigger(PLpgSQL_function *func, } else if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) { - expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple, false); + expanded_record_set_tuple(rec_new->erh, trigdata->tg_trigtuple, + false, false); } else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) { - expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple, false); - expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple, false); + expanded_record_set_tuple(rec_new->erh, trigdata->tg_newtuple, + false, false); + expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple, + false, false); + + /* + * In BEFORE trigger, stored generated columns are not computed yet, + * so make them null in the NEW row. (Only needed in UPDATE branch; + * in the INSERT case, they are already null, but in UPDATE, the field + * still contains the old value.) Alternatively, we could construct a + * whole new row structure without the generated columns, but this way + * seems more efficient and potentially less confusing. + */ + if (tupdesc->constr && tupdesc->constr->has_generated_stored && + TRIGGER_FIRED_BEFORE(trigdata->tg_event)) + { + for (int i = 0; i < tupdesc->natts; i++) + if (TupleDescAttr(tupdesc, i)->attgenerated == ATTRIBUTE_GENERATED_STORED) + expanded_record_set_field_internal(rec_new->erh, + i + 1, + (Datum) 0, + true, /* isnull */ + false, false); + } } else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) { - expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple, false); + expanded_record_set_tuple(rec_old->erh, trigdata->tg_trigtuple, + false, false); } else elog(ERROR, "unrecognized trigger action: not INSERT, DELETE, or UPDATE"); @@ -948,7 +1002,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func, */ estate.err_text = NULL; estate.err_stmt = (PLpgSQL_stmt *) (func->action); - rc = exec_stmt_block(&estate, func->action); + rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action); if (rc != PLPGSQL_RC_RETURN) { estate.err_stmt = NULL; @@ -1006,7 +1060,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func, gettext_noop("returned row structure does not match the structure of the triggering table")); /* it might need conversion */ if (tupmap) - rettup = do_convert_tuple(rettup, tupmap); + rettup = execute_attr_map_tuple(rettup, tupmap); /* no need to free map, we're about to return anyway */ } @@ -1034,7 +1088,7 @@ plpgsql_exec_trigger(PLpgSQL_function *func, gettext_noop("returned row structure does not match the structure of the triggering table")); /* it might need conversion */ if (tupmap) - rettup = do_convert_tuple(rettup, tupmap); + rettup = execute_attr_map_tuple(rettup, tupmap); ReleaseTupleDesc(retdesc); /* no need to free map, we're about to return anyway */ @@ -1109,7 +1163,7 @@ plpgsql_exec_event_trigger(PLpgSQL_function *func, EventTriggerData *trigdata) */ estate.err_text = NULL; estate.err_stmt = (PLpgSQL_stmt *) (func->action); - rc = exec_stmt_block(&estate, func->action); + rc = exec_stmt(&estate, (PLpgSQL_stmt *) func->action); if (rc != PLPGSQL_RC_RETURN) { estate.err_stmt = NULL; @@ -2066,153 +2120,221 @@ static int exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt) { PLpgSQL_expr *expr = stmt->expr; - SPIPlanPtr plan; - ParamListInfo paramLI; - LocalTransactionId before_lxid; + volatile LocalTransactionId before_lxid; LocalTransactionId after_lxid; - int rc; - - if (expr->plan == NULL) - { - /* - * Don't save the plan if not in atomic context. Otherwise, - * transaction ends would cause errors about plancache leaks. XXX - * This would be fixable with some plancache/resowner surgery - * elsewhere, but for now we'll just work around this here. - */ - exec_prepare_plan(estate, expr, 0, estate->atomic); - - /* - * The procedure call could end transactions, which would upset the - * snapshot management in SPI_execute*, so don't let it do it. - */ - expr->plan->no_snapshots = true; - } - - paramLI = setup_param_list(estate, expr); - - before_lxid = MyProc->lxid; + volatile bool pushed_active_snap = false; + volatile int rc; + /* PG_TRY to ensure we clear the plan link, if needed, on failure */ PG_TRY(); { - rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI, - estate->readonly_func, 0); - } - PG_CATCH(); - { - /* - * If we aren't saving the plan, unset the pointer. Note that it - * could have been unset already, in case of a recursive call. - */ - if (expr->plan && !expr->plan->saved) - expr->plan = NULL; - PG_RE_THROW(); - } - PG_END_TRY(); - - plan = expr->plan; + SPIPlanPtr plan = expr->plan; + ParamListInfo paramLI; - if (expr->plan && !expr->plan->saved) - expr->plan = NULL; - - after_lxid = MyProc->lxid; + if (plan == NULL) + { - if (rc < 0) - elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s", - expr->query, SPI_result_code_string(rc)); + /* + * Don't save the plan if not in atomic context. Otherwise, + * transaction ends would cause errors about plancache leaks. + * + * XXX This would be fixable with some plancache/resowner surgery + * elsewhere, but for now we'll just work around this here. + */ + exec_prepare_plan(estate, expr, 0, estate->atomic); - /* - * If we are in a new transaction after the call, we need to reset some - * internal state. - */ - if (before_lxid != after_lxid) - { - estate->simple_eval_estate = NULL; - plpgsql_create_econtext(estate); - } + /* + * The procedure call could end transactions, which would upset + * the snapshot management in SPI_execute*, so don't let it do it. + * Instead, we set the snapshots ourselves below. + */ + plan = expr->plan; + plan->no_snapshots = true; - if (SPI_processed == 1) - { - SPITupleTable *tuptab = SPI_tuptable; + /* + * Force target to be recalculated whenever the plan changes, in + * case the procedure's argument list has changed. + */ + stmt->target = NULL; + } /* - * Construct a dummy target row based on the output arguments of the - * procedure call. + * We construct a DTYPE_ROW datum representing the plpgsql variables + * associated with the procedure's output arguments. Then we can use + * exec_move_row() to do the assignments. */ - if (!stmt->target) + if (stmt->is_call && stmt->target == NULL) { Node *node; - ListCell *lc; FuncExpr *funcexpr; - int i; - HeapTuple tuple; - int numargs PG_USED_FOR_ASSERTS_ONLY; + HeapTuple func_tuple; + List *funcargs; Oid *argtypes; char **argnames; char *argmodes; MemoryContext oldcontext; PLpgSQL_row *row; int nfields; + int i; + ListCell *lc; /* - * Get the original CallStmt + * Get the parsed CallStmt, and look up the called procedure */ - node = linitial_node(Query, ((CachedPlanSource *) linitial(plan->plancache_list))->query_list)->utilityStmt; - if (!IsA(node, CallStmt)) - elog(ERROR, "returned row from not a CallStmt"); + node = linitial_node(Query, + ((CachedPlanSource *) linitial(plan->plancache_list))->query_list)->utilityStmt; + if (node == NULL || !IsA(node, CallStmt)) + elog(ERROR, "query for CALL statement is not a CallStmt"); + + funcexpr = ((CallStmt *) node)->funcexpr; - funcexpr = castNode(CallStmt, node)->funcexpr; + func_tuple = SearchSysCache1(PROCOID, + ObjectIdGetDatum(funcexpr->funcid)); + if (!HeapTupleIsValid(func_tuple)) + elog(ERROR, "cache lookup failed for function %u", + funcexpr->funcid); + + /* + * Extract function arguments, and expand any named-arg notation + */ + funcargs = expand_function_arguments(funcexpr->args, + funcexpr->funcresulttype, + func_tuple); /* - * Get the argument modes + * Get the argument names and modes, too */ - tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcexpr->funcid)); - if (!HeapTupleIsValid(tuple)) - elog(ERROR, "cache lookup failed for function %u", funcexpr->funcid); - numargs = get_func_arg_info(tuple, &argtypes, &argnames, &argmodes); - ReleaseSysCache(tuple); + get_func_arg_info(func_tuple, &argtypes, &argnames, &argmodes); - Assert(numargs == list_length(funcexpr->args)); + ReleaseSysCache(func_tuple); /* - * Construct row + * Begin constructing row Datum */ oldcontext = MemoryContextSwitchTo(estate->func->fn_cxt); - row = palloc0(sizeof(*row)); + row = (PLpgSQL_row *) palloc0(sizeof(PLpgSQL_row)); row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = "(unnamed row)"; row->lineno = -1; - row->varnos = palloc(sizeof(int) * FUNC_MAX_ARGS); + row->varnos = (int *) palloc(sizeof(int) * list_length(funcargs)); + + MemoryContextSwitchTo(oldcontext); + /* + * Examine procedure's argument list. Each output arg position + * should be an unadorned plpgsql variable (Datum), which we can + * insert into the row Datum. + */ nfields = 0; i = 0; - foreach (lc, funcexpr->args) + foreach(lc, funcargs) { - Node *n = lfirst(lc); + Node *n = lfirst(lc); - if (argmodes && argmodes[i] == PROARGMODE_INOUT) + if (argmodes && + (argmodes[i] == PROARGMODE_INOUT || + argmodes[i] == PROARGMODE_OUT)) { - Param *param; - - if (!IsA(n, Param)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("argument %d is an output argument but is not writable", i + 1))); + if (IsA(n, Param)) + { + Param *param = (Param *) n; - param = castNode(Param, n); - /* paramid is offset by 1 (see make_datum_param()) */ - row->varnos[nfields++] = param->paramid - 1; + /* paramid is offset by 1 (see make_datum_param()) */ + row->varnos[nfields++] = param->paramid - 1; + } + else + { + /* report error using parameter name, if available */ + if (argnames && argnames[i] && argnames[i][0]) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("procedure parameter \"%s\" is an output parameter but corresponding argument is not writable", + argnames[i]))); + else + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("procedure parameter %d is an output parameter but corresponding argument is not writable", + i + 1))); + } } i++; } row->nfields = nfields; - MemoryContextSwitchTo(oldcontext); - stmt->target = (PLpgSQL_variable *) row; } + paramLI = setup_param_list(estate, expr); + + before_lxid = MyProc->lxid; + + /* + * Set snapshot only for non-read-only procedures, similar to SPI + * behavior. + */ + if (!estate->readonly_func) + { + PushActiveSnapshot(GetTransactionSnapshot()); + pushed_active_snap = true; + } + + rc = SPI_execute_plan_with_paramlist(expr->plan, paramLI, + estate->readonly_func, 0); + } + PG_CATCH(); + { + /* + * If we aren't saving the plan, unset the pointer. Note that it + * could have been unset already, in case of a recursive call. + */ + if (expr->plan && !expr->plan->saved) + expr->plan = NULL; + PG_RE_THROW(); + } + PG_END_TRY(); + + if (expr->plan && !expr->plan->saved) + expr->plan = NULL; + + if (rc < 0) + elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s", + expr->query, SPI_result_code_string(rc)); + + after_lxid = MyProc->lxid; + + if (before_lxid == after_lxid) + { + /* + * If we are still in the same transaction after the call, pop the + * snapshot that we might have pushed. (If it's a new transaction, + * then all the snapshots are gone already.) + */ + if (pushed_active_snap) + PopActiveSnapshot(); + } + else + { + /* + * If we are in a new transaction after the call, we need to reset + * some internal state. + */ + estate->simple_eval_estate = NULL; + plpgsql_create_econtext(estate); + } + + /* + * Check result rowcount; if there's one row, assign procedure's output + * values back to the appropriate variables. + */ + if (SPI_processed == 1) + { + SPITupleTable *tuptab = SPI_tuptable; + + if (!stmt->target) + elog(ERROR, "DO statement returned a row"); + exec_move_row(estate, stmt->target, tuptab->vals[0], tuptab->tupdesc); } else if (SPI_processed > 1) @@ -2258,12 +2380,6 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt) false, INT8OID, -1); break; - case PLPGSQL_GETDIAG_RESULT_OID: - exec_assign_value(estate, var, - ObjectIdGetDatum(estate->eval_lastoid), - false, OIDOID, -1); - break; - case PLPGSQL_GETDIAG_ERROR_CONTEXT: exec_assign_c_string(estate, var, estate->cur_error->context); @@ -2406,7 +2522,8 @@ exec_stmt_case(PLpgSQL_execstate *estate, PLpgSQL_stmt_case *stmt) t_var->datatype->atttypmod != t_typmod) t_var->datatype = plpgsql_build_datatype(t_typoid, t_typmod, - estate->func->fn_input_collation); + estate->func->fn_input_collation, + NULL); /* now we can assign to the variable */ exec_assign_value(estate, @@ -3180,10 +3297,10 @@ exec_stmt_return_next(PLpgSQL_execstate *estate, * reference; in particular, this path is always taken in functions with * one or more OUT parameters. * - * Unlike exec_statement_return, there's no special win here for R/W - * expanded values, since they'll have to get flattened to go into the - * tuplestore. Indeed, we'd better make them R/O to avoid any risk of the - * casting step changing them in-place. + * Unlike exec_stmt_return, there's no special win here for R/W expanded + * values, since they'll have to get flattened to go into the tuplestore. + * Indeed, we'd better make them R/O to avoid any risk of the casting step + * changing them in-place. */ if (stmt->retvarno >= 0) { @@ -3248,7 +3365,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate, gettext_noop("wrong record type supplied in RETURN NEXT")); tuple = expanded_record_get_tuple(rec->erh); if (tupmap) - tuple = do_convert_tuple(tuple, tupmap); + tuple = execute_attr_map_tuple(tuple, tupmap); tuplestore_puttuple(estate->tuple_store, tuple); MemoryContextSwitchTo(oldcontext); } @@ -3311,7 +3428,7 @@ exec_stmt_return_next(PLpgSQL_execstate *estate, tupmap = convert_tuples_by_position(retvaldesc, tupdesc, gettext_noop("returned record type does not match expected record type")); if (tupmap) - tuple = do_convert_tuple(tuple, tupmap); + tuple = execute_attr_map_tuple(tuple, tupmap); tuplestore_puttuple(estate->tuple_store, tuple); ReleaseTupleDesc(retvaldesc); MemoryContextSwitchTo(oldcontext); @@ -3427,7 +3544,7 @@ exec_stmt_return_query(PLpgSQL_execstate *estate, HeapTuple tuple = SPI_tuptable->vals[i]; if (tupmap) - tuple = do_convert_tuple(tuple, tupmap); + tuple = execute_attr_map_tuple(tuple, tupmap); tuplestore_puttuple(estate->tuple_store, tuple); if (tupmap) heap_freetuple(tuple); @@ -3590,7 +3707,7 @@ exec_stmt_raise(PLpgSQL_execstate *estate, PLpgSQL_stmt_raise *stmt) paramvalue, paramtypeid); appendStringInfoString(&ds, extval); - current_param = lnext(current_param); + current_param = lnext(stmt->params, current_param); exec_eval_cleanup(estate); } else @@ -3805,8 +3922,7 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate, estate->datum_context = CurrentMemoryContext; /* initialize our ParamListInfo with appropriate hook functions */ - estate->paramLI = (ParamListInfo) - palloc(offsetof(ParamListInfoData, params)); + estate->paramLI = makeParamList(0); estate->paramLI->paramFetch = plpgsql_param_fetch; estate->paramLI->paramFetchArg = (void *) estate; estate->paramLI->paramCompile = plpgsql_param_compile; @@ -3862,7 +3978,6 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate, estate->eval_tuptable = NULL; estate->eval_processed = 0; - estate->eval_lastoid = InvalidOid; estate->eval_econtext = NULL; estate->err_stmt = NULL; @@ -3943,24 +4058,8 @@ exec_prepare_plan(PLpgSQL_execstate *estate, (void *) expr, cursorOptions); if (plan == NULL) - { - /* Some SPI errors deserve specific error messages */ - switch (SPI_result) - { - case SPI_ERROR_COPY: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot COPY to/from client in PL/pgSQL"))); - case SPI_ERROR_TRANSACTION: - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot begin/end transactions in PL/pgSQL"), - errhint("Use a BEGIN block with an EXCEPTION clause instead."))); - default: - elog(ERROR, "SPI_prepare_params failed for \"%s\": %s", - expr->query, SPI_result_code_string(SPI_result)); - } - } + elog(ERROR, "SPI_prepare_params failed for \"%s\": %s", + expr->query, SPI_result_code_string(SPI_result)); if (keepplan) SPI_keepplan(plan); expr->plan = plan; @@ -3992,10 +4091,16 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, long tcount; int rc; PLpgSQL_expr *expr = stmt->sqlstmt; + int too_many_rows_level = 0; + + if (plpgsql_extra_errors & PLPGSQL_XCHECK_TOOMANYROWS) + too_many_rows_level = ERROR; + else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_TOOMANYROWS) + too_many_rows_level = WARNING; /* * On the first call for this statement generate the plan, and detect - * whether the statement is INSERT/UPDATE/DELETE/MERGE + * whether the statement is INSERT/UPDATE/DELETE */ if (expr->plan == NULL) { @@ -4006,20 +4111,20 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, foreach(l, SPI_plan_get_plan_sources(expr->plan)) { CachedPlanSource *plansource = (CachedPlanSource *) lfirst(l); - ListCell *l2; - foreach(l2, plansource->query_list) + /* + * We could look at the raw_parse_tree, but it seems simpler to + * check the command tag. Note we should *not* look at the Query + * tree(s), since those are the result of rewriting and could have + * been transmogrified into something else entirely. + */ + if (plansource->commandTag && + (strcmp(plansource->commandTag, "INSERT") == 0 || + strcmp(plansource->commandTag, "UPDATE") == 0 || + strcmp(plansource->commandTag, "DELETE") == 0)) { - Query *q = lfirst_node(Query, l2); - - if (q->canSetTag) - { - if (q->commandType == CMD_INSERT || - q->commandType == CMD_UPDATE || - q->commandType == CMD_MERGE || - q->commandType == CMD_DELETE) - stmt->mod_stmt = true; - } + stmt->mod_stmt = true; + break; } } } @@ -4031,9 +4136,10 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, /* * If we have INTO, then we only need one row back ... but if we have INTO - * STRICT, ask for two rows, so that we can verify the statement returns - * only one. INSERT/UPDATE/DELETE are always treated strictly. Without - * INTO, just run the statement to completion (tcount = 0). + * STRICT or extra check too_many_rows, ask for two rows, so that we can + * verify the statement returns only one. INSERT/UPDATE/DELETE are always + * treated strictly. Without INTO, just run the statement to completion + * (tcount = 0). * * We could just ask for two rows always when using INTO, but there are * some cases where demanding the extra row costs significant time, eg by @@ -4042,7 +4148,7 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, */ if (stmt->into) { - if (stmt->strict || stmt->mod_stmt) + if (stmt->strict || stmt->mod_stmt || too_many_rows_level) tcount = 2; else tcount = 1; @@ -4074,7 +4180,6 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, case SPI_OK_INSERT_RETURNING: case SPI_OK_UPDATE_RETURNING: case SPI_OK_DELETE_RETURNING: - case SPI_OK_MERGE: Assert(stmt->mod_stmt); exec_set_found(estate, (SPI_processed != 0)); break; @@ -4085,12 +4190,12 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, break; case SPI_OK_REWRITTEN: - Assert(!stmt->mod_stmt); /* * The command was rewritten into another kind of command. It's * not clear what FOUND would mean in that case (and SPI doesn't - * return the row count either), so just set it to false. + * return the row count either), so just set it to false. Note + * that we can't assert anything about mod_stmt here. */ exec_set_found(estate, false); break; @@ -4100,20 +4205,22 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot COPY to/from client in PL/pgSQL"))); + break; + case SPI_ERROR_TRANSACTION: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot begin/end transactions in PL/pgSQL"), - errhint("Use a BEGIN block with an EXCEPTION clause instead."))); + errmsg("unsupported transaction command in PL/pgSQL"))); + break; default: elog(ERROR, "SPI_execute_plan_with_paramlist failed executing query \"%s\": %s", expr->query, SPI_result_code_string(rc)); + break; } /* All variants should save result info for GET DIAGNOSTICS */ estate->eval_processed = SPI_processed; - estate->eval_lastoid = SPI_lastoid; /* Process INTO if present */ if (stmt->into) @@ -4157,19 +4264,23 @@ exec_stmt_execsql(PLpgSQL_execstate *estate, } else { - if (n > 1 && (stmt->strict || stmt->mod_stmt)) + if (n > 1 && (stmt->strict || stmt->mod_stmt || too_many_rows_level)) { char *errdetail; + int errlevel; if (estate->func->print_strict_params) errdetail = format_expr_params(estate, expr); else errdetail = NULL; - ereport(ERROR, + errlevel = (stmt->strict || stmt->mod_stmt) ? ERROR : too_many_rows_level; + + ereport(errlevel, (errcode(ERRCODE_TOO_MANY_ROWS), errmsg("query returned more than one row"), - errdetail ? errdetail_internal("parameters: %s", errdetail) : 0)); + errdetail ? errdetail_internal("parameters: %s", errdetail) : 0, + errhint("Make sure the query returns a single row, or use LIMIT 1."))); } /* Put the first result row into the target */ exec_move_row(estate, target, tuptab->vals[0], tuptab->tupdesc); @@ -4252,7 +4363,6 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate, case SPI_OK_INSERT_RETURNING: case SPI_OK_UPDATE_RETURNING: case SPI_OK_DELETE_RETURNING: - case SPI_OK_MERGE: case SPI_OK_UTILITY: case SPI_OK_REWRITTEN: break; @@ -4285,11 +4395,13 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate, ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot COPY to/from client in PL/pgSQL"))); + break; + case SPI_ERROR_TRANSACTION: ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("cannot begin/end transactions in PL/pgSQL"), - errhint("Use a BEGIN block with an EXCEPTION clause instead."))); + errmsg("EXECUTE of transaction commands is not implemented"))); + break; default: elog(ERROR, "SPI_execute failed executing query \"%s\": %s", @@ -4299,7 +4411,6 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate, /* Save result info for GET DIAGNOSTICS */ estate->eval_processed = SPI_processed; - estate->eval_lastoid = SPI_lastoid; /* Process INTO if present */ if (stmt->into) @@ -4708,10 +4819,13 @@ exec_stmt_close(PLpgSQL_execstate *estate, PLpgSQL_stmt_close *stmt) static int exec_stmt_commit(PLpgSQL_execstate *estate, PLpgSQL_stmt_commit *stmt) { - HoldPinnedPortals(); - - SPI_commit(); - SPI_start_transaction(); + if (stmt->chain) + SPI_commit_and_chain(); + else + { + SPI_commit(); + SPI_start_transaction(); + } estate->simple_eval_estate = NULL; plpgsql_create_econtext(estate); @@ -4727,10 +4841,13 @@ exec_stmt_commit(PLpgSQL_execstate *estate, PLpgSQL_stmt_commit *stmt) static int exec_stmt_rollback(PLpgSQL_execstate *estate, PLpgSQL_stmt_rollback *stmt) { - HoldPinnedPortals(); - - SPI_rollback(); - SPI_start_transaction(); + if (stmt->chain) + SPI_rollback_and_chain(); + else + { + SPI_rollback(); + SPI_start_transaction(); + } estate->simple_eval_estate = NULL; plpgsql_create_econtext(estate); @@ -5037,7 +5154,7 @@ exec_assign_value(PLpgSQL_execstate *estate, /* And assign it. */ expanded_record_set_field(erh, recfield->finfo.fnumber, - value, isNull); + value, isNull, !estate->atomic); break; } @@ -5143,8 +5260,8 @@ exec_assign_value(PLpgSQL_execstate *estate, /* * Evaluate the subscripts, switch into left-to-right order. - * Like the expression built by ExecInitArrayRef(), complain - * if any subscript is null. + * Like the expression built by ExecInitSubscriptingRef(), + * complain if any subscript is null. */ for (i = 0; i < nsubscripts; i++) { @@ -5494,7 +5611,7 @@ plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate, void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, PLpgSQL_datum *datum, - Oid *typeid, int32 *typmod, Oid *collation) + Oid *typeId, int32 *typMod, Oid *collation) { switch (datum->dtype) { @@ -5503,8 +5620,8 @@ plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, { PLpgSQL_var *var = (PLpgSQL_var *) datum; - *typeid = var->datatype->typoid; - *typmod = var->datatype->atttypmod; + *typeId = var->datatype->typoid; + *typMod = var->datatype->atttypmod; *collation = var->datatype->collation; break; } @@ -5516,15 +5633,15 @@ plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, if (rec->erh == NULL || rec->rectypeid != RECORDOID) { /* Report variable's declared type */ - *typeid = rec->rectypeid; - *typmod = -1; + *typeId = rec->rectypeid; + *typMod = -1; } else { /* Report record's actual type if declared RECORD */ - *typeid = rec->erh->er_typeid; + *typeId = rec->erh->er_typeid; /* do NOT return the mutable typmod of a RECORD variable */ - *typmod = -1; + *typMod = -1; } /* composite types are never collatable */ *collation = InvalidOid; @@ -5562,16 +5679,16 @@ plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, recfield->rectupledescid = rec->erh->er_tupdesc_id; } - *typeid = recfield->finfo.ftypeid; - *typmod = recfield->finfo.ftypmod; + *typeId = recfield->finfo.ftypeid; + *typMod = recfield->finfo.ftypmod; *collation = recfield->finfo.fcollation; break; } default: elog(ERROR, "unrecognized dtype: %d", datum->dtype); - *typeid = InvalidOid; /* keep compiler quiet */ - *typmod = -1; + *typeId = InvalidOid; /* keep compiler quiet */ + *typMod = -1; *collation = InvalidOid; break; } @@ -5769,7 +5886,6 @@ exec_run_select(PLpgSQL_execstate *estate, Assert(estate->eval_tuptable == NULL); estate->eval_tuptable = SPI_tuptable; estate->eval_processed = SPI_processed; - estate->eval_lastoid = SPI_lastoid; return rc; } @@ -5851,7 +5967,8 @@ exec_for_query(PLpgSQL_execstate *estate, PLpgSQL_stmt_forq *stmt, tupdescs_match) { /* Only need to assign a new tuple value */ - expanded_record_set_tuple(rec->erh, tuptab->vals[i], true); + expanded_record_set_tuple(rec->erh, tuptab->vals[i], + true, !estate->atomic); } else { @@ -6623,7 +6740,7 @@ exec_move_row(PLpgSQL_execstate *estate, */ newerh = make_expanded_record_for_rec(estate, rec, NULL, rec->erh); - expanded_record_set_tuple(newerh, NULL, false); + expanded_record_set_tuple(newerh, NULL, false, false); assign_record_var(estate, rec, newerh); } else @@ -6665,7 +6782,7 @@ exec_move_row(PLpgSQL_execstate *estate, else { /* No coercion is needed, so just assign the row value */ - expanded_record_set_tuple(newerh, tup, true); + expanded_record_set_tuple(newerh, tup, true, !estate->atomic); } /* Complete the assignment */ @@ -6722,6 +6839,67 @@ exec_move_row(PLpgSQL_execstate *estate, } } +/* + * Verify that a PLpgSQL_rec's rectypeid is up-to-date. + */ +static void +revalidate_rectypeid(PLpgSQL_rec *rec) +{ + PLpgSQL_type *typ = rec->datatype; + TypeCacheEntry *typentry; + + if (rec->rectypeid == RECORDOID) + return; /* it's RECORD, so nothing to do */ + Assert(typ != NULL); + if (typ->tcache && + typ->tcache->tupDesc_identifier == typ->tupdesc_id) + return; /* known up-to-date */ + + /* + * typcache entry has suffered invalidation, so re-look-up the type name + * if possible, and then recheck the type OID. If we don't have a + * TypeName, then we just have to soldier on with the OID we've got. + */ + if (typ->origtypname != NULL) + { + /* this bit should match parse_datatype() in pl_gram.y */ + typenameTypeIdAndMod(NULL, typ->origtypname, + &typ->typoid, + &typ->atttypmod); + } + + /* this bit should match build_datatype() in pl_comp.c */ + typentry = lookup_type_cache(typ->typoid, + TYPECACHE_TUPDESC | + TYPECACHE_DOMAIN_BASE_INFO); + if (typentry->typtype == TYPTYPE_DOMAIN) + typentry = lookup_type_cache(typentry->domainBaseType, + TYPECACHE_TUPDESC); + if (typentry->tupDesc == NULL) + { + /* + * If we get here, user tried to replace a composite type with a + * non-composite one. We're not gonna support that. + */ + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("type %s is not composite", + format_type_be(typ->typoid)))); + } + + /* + * Update tcache and tupdesc_id. Since we don't support changing to a + * non-composite type, none of the rest of *typ needs to change. + */ + typ->tcache = typentry; + typ->tupdesc_id = typentry->tupDesc_identifier; + + /* + * Update *rec, too. (We'll deal with subsidiary RECFIELDs as needed.) + */ + rec->rectypeid = typ->typoid; +} + /* * Build an expanded record object suitable for assignment to "rec". * @@ -6746,6 +6924,11 @@ make_expanded_record_for_rec(PLpgSQL_execstate *estate, if (rec->rectypeid != RECORDOID) { + /* + * Make sure rec->rectypeid is up-to-date before using it. + */ + revalidate_rectypeid(rec); + /* * New record must be of desired type, but maybe srcerh has already * done all the same lookups. @@ -6803,6 +6986,19 @@ exec_move_row_from_fields(PLpgSQL_execstate *estate, int td_natts = tupdesc ? tupdesc->natts : 0; int fnum; int anum; + int strict_multiassignment_level = 0; + + /* + * The extra check strict strict_multi_assignment can be active, only when + * input tupdesc is specified. + */ + if (tupdesc != NULL) + { + if (plpgsql_extra_errors & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT) + strict_multiassignment_level = ERROR; + else if (plpgsql_extra_warnings & PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT) + strict_multiassignment_level = WARNING; + } /* Handle RECORD-target case */ if (target->dtype == PLPGSQL_DTYPE_REC) @@ -6881,10 +7077,23 @@ exec_move_row_from_fields(PLpgSQL_execstate *estate, } else { + /* no source for destination column */ value = (Datum) 0; isnull = true; valtype = UNKNOWNOID; valtypmod = -1; + + /* When source value is missing */ + if (strict_multiassignment_level) + ereport(strict_multiassignment_level, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("number of source and target fields in assignment does not match"), + /* translator: %s represents a name of an extra check */ + errdetail("%s check of %s is active.", + "strict_multi_assignment", + strict_multiassignment_level == ERROR ? "extra_errors" : + "extra_warnings"), + errhint("Make sure the query returns the exact list of columns."))); } /* Cast the new value to the right type, if needed. */ @@ -6898,12 +7107,35 @@ exec_move_row_from_fields(PLpgSQL_execstate *estate, newnulls[fnum] = isnull; } + /* + * When strict_multiassignment extra check is active, then ensure + * there are no unassigned source attributes. + */ + if (strict_multiassignment_level && anum < td_natts) + { + /* skip dropped columns in the source descriptor */ + while (anum < td_natts && + TupleDescAttr(tupdesc, anum)->attisdropped) + anum++; + + if (anum < td_natts) + ereport(strict_multiassignment_level, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("number of source and target fields in assignment does not match"), + /* translator: %s represents a name of an extra check */ + errdetail("%s check of %s is active.", + "strict_multi_assignment", + strict_multiassignment_level == ERROR ? "extra_errors" : + "extra_warnings"), + errhint("Make sure the query returns the exact list of columns."))); + } + values = newvalues; nulls = newnulls; } /* Insert the coerced field values into the new expanded record */ - expanded_record_set_fields(newerh, values, nulls); + expanded_record_set_fields(newerh, values, nulls, !estate->atomic); /* Complete the assignment */ assign_record_var(estate, rec, newerh); @@ -6954,16 +7186,50 @@ exec_move_row_from_fields(PLpgSQL_execstate *estate, } else { + /* no source for destination column */ value = (Datum) 0; isnull = true; valtype = UNKNOWNOID; valtypmod = -1; + + if (strict_multiassignment_level) + ereport(strict_multiassignment_level, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("number of source and target fields in assignment does not match"), + /* translator: %s represents a name of an extra check */ + errdetail("%s check of %s is active.", + "strict_multi_assignment", + strict_multiassignment_level == ERROR ? "extra_errors" : + "extra_warnings"), + errhint("Make sure the query returns the exact list of columns."))); } exec_assign_value(estate, (PLpgSQL_datum *) var, value, isnull, valtype, valtypmod); } + /* + * When strict_multiassignment extra check is active, ensure there are + * no unassigned source attributes. + */ + if (strict_multiassignment_level && anum < td_natts) + { + while (anum < td_natts && + TupleDescAttr(tupdesc, anum)->attisdropped) + anum++; /* skip dropped column in tuple */ + + if (anum < td_natts) + ereport(strict_multiassignment_level, + (errcode(ERRCODE_DATATYPE_MISMATCH), + errmsg("number of source and target fields in assignment does not match"), + /* translator: %s represents a name of an extra check */ + errdetail("%s check of %s is active.", + "strict_multi_assignment", + strict_multiassignment_level == ERROR ? "extra_errors" : + "extra_warnings"), + errhint("Make sure the query returns the exact list of columns."))); + } + return; } @@ -7134,6 +7400,11 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate, if (erh == rec->erh) return; + /* + * Make sure rec->rectypeid is up-to-date before using it. + */ + revalidate_rectypeid(rec); + /* * If we have a R/W pointer, we're allowed to just commandeer * ownership of the expanded record. If it's of the right type to @@ -7170,7 +7441,8 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate, (erh->er_typmod == rec->erh->er_typmod && erh->er_typmod >= 0))) { - expanded_record_set_tuple(rec->erh, erh->fvalue, true); + expanded_record_set_tuple(rec->erh, erh->fvalue, + true, !estate->atomic); return; } @@ -7192,7 +7464,8 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate, (rec->rectypeid == RECORDOID || rec->rectypeid == erh->er_typeid)) { - expanded_record_set_tuple(newerh, erh->fvalue, true); + expanded_record_set_tuple(newerh, erh->fvalue, + true, !estate->atomic); assign_record_var(estate, rec, newerh); return; } @@ -7282,7 +7555,8 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate, (tupTypmod == rec->erh->er_typmod && tupTypmod >= 0))) { - expanded_record_set_tuple(rec->erh, &tmptup, true); + expanded_record_set_tuple(rec->erh, &tmptup, + true, !estate->atomic); return; } @@ -7299,7 +7573,8 @@ exec_move_row_from_datum(PLpgSQL_execstate *estate, newerh = make_expanded_record_from_typeid(tupType, tupTypmod, mcontext); - expanded_record_set_tuple(newerh, &tmptup, true); + expanded_record_set_tuple(newerh, &tmptup, + true, !estate->atomic); assign_record_var(estate, rec, newerh); return; } @@ -7342,6 +7617,9 @@ instantiate_empty_record_variable(PLpgSQL_execstate *estate, PLpgSQL_rec *rec) errmsg("record \"%s\" is not assigned yet", rec->refname), errdetail("The tuple structure of a not-yet-assigned record is indeterminate."))); + /* Make sure rec->rectypeid is up-to-date before using it */ + revalidate_rectypeid(rec); + /* OK, do it */ rec->erh = make_expanded_record_from_typeid(rec->rectypeid, -1, estate->datum_context); @@ -7460,18 +7738,34 @@ get_cast_hashentry(PLpgSQL_execstate *estate, cast_key.dsttypmod = dsttypmod; cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash, (void *) &cast_key, - HASH_FIND, NULL); + HASH_ENTER, &found); + if (!found) /* initialize if new entry */ + cast_entry->cast_cexpr = NULL; - if (cast_entry == NULL) + if (cast_entry->cast_cexpr == NULL || + !cast_entry->cast_cexpr->is_valid) { - /* We've not looked up this coercion before */ + /* + * We've not looked up this coercion before, or we have but the cached + * expression has been invalidated. + */ Node *cast_expr; + CachedExpression *cast_cexpr; CaseTestExpr *placeholder; + /* + * Drop old cached expression if there is one. + */ + if (cast_entry->cast_cexpr) + { + FreeCachedExpression(cast_entry->cast_cexpr); + cast_entry->cast_cexpr = NULL; + } + /* * Since we could easily fail (no such coercion), construct a * temporary coercion expression tree in the short-lived - * eval_mcontext, then if successful copy it to cast_hash_context. + * eval_mcontext, then if successful save it as a CachedExpression. */ oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate)); @@ -7532,33 +7826,23 @@ get_cast_hashentry(PLpgSQL_execstate *estate, /* Note: we don't bother labeling the expression tree with collation */ + /* Plan the expression and build a CachedExpression */ + cast_cexpr = GetCachedExpression(cast_expr); + cast_expr = cast_cexpr->expr; + /* Detect whether we have a no-op (RelabelType) coercion */ if (IsA(cast_expr, RelabelType) && ((RelabelType *) cast_expr)->arg == (Expr *) placeholder) cast_expr = NULL; - if (cast_expr) - { - /* ExecInitExpr assumes we've planned the expression */ - cast_expr = (Node *) expression_planner((Expr *) cast_expr); - - /* Now copy the tree into cast_hash_context */ - MemoryContextSwitchTo(estate->cast_hash_context); - - cast_expr = copyObject(cast_expr); - } - - MemoryContextSwitchTo(oldcontext); - - /* Now we can fill in a hashtable entry. */ - cast_entry = (plpgsql_CastHashEntry *) hash_search(estate->cast_hash, - (void *) &cast_key, - HASH_ENTER, &found); - Assert(!found); /* wasn't there a moment ago */ + /* Now we can fill in the hashtable entry. */ + cast_entry->cast_cexpr = cast_cexpr; cast_entry->cast_expr = (Expr *) cast_expr; cast_entry->cast_exprstate = NULL; cast_entry->cast_in_use = false; cast_entry->cast_lxid = InvalidLocalTransactionId; + + MemoryContextSwitchTo(oldcontext); } /* Done if we have determined that this is a no-op cast. */ @@ -8027,7 +8311,8 @@ plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid, * assign_simple_var --- assign a new value to any VAR datum. * * This should be the only mechanism for assignment to simple variables, - * lest we do the release of the old value incorrectly. + * lest we do the release of the old value incorrectly (not to mention + * the detoasting business). */ static void assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, @@ -8035,6 +8320,41 @@ assign_simple_var(PLpgSQL_execstate *estate, PLpgSQL_var *var, { Assert(var->dtype == PLPGSQL_DTYPE_VAR || var->dtype == PLPGSQL_DTYPE_PROMISE); + + /* + * In non-atomic contexts, we do not want to store TOAST pointers in + * variables, because such pointers might become stale after a commit. + * Forcibly detoast in such cases. We don't want to detoast (flatten) + * expanded objects, however; those should be OK across a transaction + * boundary since they're just memory-resident objects. (Elsewhere in + * this module, operations on expanded records likewise need to request + * detoasting of record fields when !estate->atomic. Expanded arrays are + * not a problem since all array entries are always detoasted.) + */ + if (!estate->atomic && !isnull && var->datatype->typlen == -1 && + VARATT_IS_EXTERNAL_NON_EXPANDED(DatumGetPointer(newvalue))) + { + MemoryContext oldcxt; + Datum detoasted; + + /* + * Do the detoasting in the eval_mcontext to avoid long-term leakage + * of whatever memory toast fetching might leak. Then we have to copy + * the detoasted datum to the function's main context, which is a + * pain, but there's little choice. + */ + oldcxt = MemoryContextSwitchTo(get_eval_mcontext(estate)); + detoasted = PointerGetDatum(heap_tuple_fetch_attr((struct varlena *) DatumGetPointer(newvalue))); + MemoryContextSwitchTo(oldcxt); + /* Now's a good time to not leak the input value if it's freeable */ + if (freeable) + pfree(DatumGetPointer(newvalue)); + /* Once we copy the value, it's definitely freeable */ + newvalue = datumCopy(detoasted, false, -1); + freeable = true; + /* Can't clean up eval_mcontext here, but it'll happen before long */ + } + /* Free the old value if needed */ if (var->freeval) { diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c index b93f8662233..053f83dc746 100644 --- a/src/pl/plpgsql/src/pl_funcs.c +++ b/src/pl/plpgsql/src/pl_funcs.c @@ -3,7 +3,7 @@ * pl_funcs.c - Misc functions for the PL/pgSQL * procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -307,8 +307,6 @@ plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind) { case PLPGSQL_GETDIAG_ROW_COUNT: return "ROW_COUNT"; - case PLPGSQL_GETDIAG_RESULT_OID: - return "RESULT_OID"; case PLPGSQL_GETDIAG_CONTEXT: return "PG_CONTEXT"; case PLPGSQL_GETDIAG_ERROR_CONTEXT: @@ -1320,14 +1318,20 @@ static void dump_commit(PLpgSQL_stmt_commit *stmt) { dump_ind(); - printf("COMMIT\n"); + if (stmt->chain) + printf("COMMIT AND CHAIN\n"); + else + printf("COMMIT\n"); } static void dump_rollback(PLpgSQL_stmt_rollback *stmt) { dump_ind(); - printf("ROLLBACK\n"); + if (stmt->chain) + printf("ROLLBACK AND CHAIN\n"); + else + printf("ROLLBACK\n"); } static void diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y index f9ba19cbdf0..454071a81f1 100644 --- a/src/pl/plpgsql/src/pl_gram.y +++ b/src/pl/plpgsql/src/pl_gram.y @@ -3,7 +3,7 @@ * * pl_gram.y - Parser for the PL/pgSQL procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -219,6 +219,8 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); %type opt_scrollable %type opt_fetch_direction +%type opt_transaction_chain + %type unreserved_keyword @@ -252,6 +254,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); %token K_ABSOLUTE %token K_ALIAS %token K_ALL +%token K_AND %token K_ARRAY %token K_ASSERT %token K_BACKWARD @@ -259,6 +262,7 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); %token K_BY %token K_CALL %token K_CASE +%token K_CHAIN %token K_CLOSE %token K_COLLATE %token K_COLUMN @@ -304,7 +308,6 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); %token K_LAST %token K_LOG %token K_LOOP -%token K_MERGE %token K_MESSAGE %token K_MESSAGE_TEXT %token K_MOVE @@ -328,7 +331,6 @@ static void check_raise_parameters(PLpgSQL_stmt_raise *stmt); %token K_RAISE %token K_RELATIVE %token K_RESET -%token K_RESULT_OID %token K_RETURN %token K_RETURNED_SQLSTATE %token K_REVERSE @@ -416,6 +418,7 @@ pl_block : decl_sect K_BEGIN proc_sect exception_sect K_END opt_label new->cmd_type = PLPGSQL_STMT_BLOCK; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1.label; new->n_initvars = $1.n_initvars; new->initvarnos = $1.initvarnos; @@ -548,7 +551,8 @@ decl_statement : decl_varname decl_const decl_datatype decl_collate decl_notnull plpgsql_build_variable($1.name, $1.lineno, plpgsql_build_datatype(REFCURSOROID, -1, - InvalidOid), + InvalidOid, + NULL), true); curname_def = palloc0(sizeof(PLpgSQL_expr)); @@ -614,6 +618,7 @@ decl_cursor_args : new = palloc0(sizeof(PLpgSQL_row)); new->dtype = PLPGSQL_DTYPE_ROW; + new->refname = "(unnamed row)"; new->lineno = plpgsql_location_to_lineno(@1); new->rowtupdesc = NULL; new->nfields = list_length($2); @@ -906,6 +911,7 @@ stmt_perform : K_PERFORM expr_until_semi new = palloc0(sizeof(PLpgSQL_stmt_perform)); new->cmd_type = PLPGSQL_STMT_PERFORM; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = $2; $$ = (PLpgSQL_stmt *)new; @@ -919,6 +925,7 @@ stmt_call : K_CALL new = palloc0(sizeof(PLpgSQL_stmt_call)); new->cmd_type = PLPGSQL_STMT_CALL; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = read_sql_stmt("CALL "); new->is_call = true; @@ -933,6 +940,7 @@ stmt_call : K_CALL new = palloc0(sizeof(PLpgSQL_stmt_call)); new->cmd_type = PLPGSQL_STMT_CALL; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = read_sql_stmt("DO "); new->is_call = false; @@ -948,6 +956,7 @@ stmt_assign : assign_var assign_operator expr_until_semi new = palloc0(sizeof(PLpgSQL_stmt_assign)); new->cmd_type = PLPGSQL_STMT_ASSIGN; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->varno = $1->dno; new->expr = $3; @@ -963,6 +972,7 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' new = palloc0(sizeof(PLpgSQL_stmt_getdiag)); new->cmd_type = PLPGSQL_STMT_GETDIAG; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->is_stacked = $2; new->diag_items = $4; @@ -977,7 +987,6 @@ stmt_getdiag : K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';' { /* these fields are disallowed in stacked case */ case PLPGSQL_GETDIAG_ROW_COUNT: - case PLPGSQL_GETDIAG_RESULT_OID: if (new->is_stacked) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), @@ -1060,9 +1069,6 @@ getdiag_item : if (tok_is_keyword(tok, &yylval, K_ROW_COUNT, "row_count")) $$ = PLPGSQL_GETDIAG_ROW_COUNT; - else if (tok_is_keyword(tok, &yylval, - K_RESULT_OID, "result_oid")) - $$ = PLPGSQL_GETDIAG_RESULT_OID; else if (tok_is_keyword(tok, &yylval, K_PG_CONTEXT, "pg_context")) $$ = PLPGSQL_GETDIAG_CONTEXT; @@ -1154,6 +1160,7 @@ stmt_if : K_IF expr_until_then proc_sect stmt_elsifs stmt_else K_END K_IF ';' new = palloc0(sizeof(PLpgSQL_stmt_if)); new->cmd_type = PLPGSQL_STMT_IF; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->cond = $2; new->then_body = $3; new->elsif_list = $4; @@ -1258,6 +1265,7 @@ stmt_loop : opt_loop_label K_LOOP loop_body new = palloc0(sizeof(PLpgSQL_stmt_loop)); new->cmd_type = PLPGSQL_STMT_LOOP; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1; new->body = $3.stmts; @@ -1275,6 +1283,7 @@ stmt_while : opt_loop_label K_WHILE expr_until_loop loop_body new = palloc0(sizeof(PLpgSQL_stmt_while)); new->cmd_type = PLPGSQL_STMT_WHILE; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1; new->cond = $3; new->body = $4.stmts; @@ -1295,6 +1304,7 @@ stmt_for : opt_loop_label K_FOR for_control loop_body new = (PLpgSQL_stmt_fori *) $3; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1; new->body = $4.stmts; $$ = (PLpgSQL_stmt *) new; @@ -1309,6 +1319,7 @@ stmt_for : opt_loop_label K_FOR for_control loop_body /* forq is the common supertype of all three */ new = (PLpgSQL_stmt_forq *) $3; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1; new->body = $4.stmts; $$ = (PLpgSQL_stmt *) new; @@ -1338,6 +1349,7 @@ for_control : for_variable K_IN new = palloc0(sizeof(PLpgSQL_stmt_dynfors)); new->cmd_type = PLPGSQL_STMT_DYNFORS; + new->stmtid = ++plpgsql_curr_compile->nstatements; if ($1.row) { new->var = (PLpgSQL_variable *) $1.row; @@ -1383,6 +1395,7 @@ for_control : for_variable K_IN new = (PLpgSQL_stmt_forc *) palloc0(sizeof(PLpgSQL_stmt_forc)); new->cmd_type = PLPGSQL_STMT_FORC; + new->stmtid = ++plpgsql_curr_compile->nstatements; new->curvar = cursor->dno; /* Should have had a single variable name */ @@ -1492,11 +1505,13 @@ for_control : for_variable K_IN $1.lineno, plpgsql_build_datatype(INT4OID, -1, - InvalidOid), + InvalidOid, + NULL), true); new = palloc0(sizeof(PLpgSQL_stmt_fori)); new->cmd_type = PLPGSQL_STMT_FORI; + new->stmtid = ++plpgsql_curr_compile->nstatements; new->var = fvar; new->reverse = reverse; new->lower = expr1; @@ -1531,6 +1546,7 @@ for_control : for_variable K_IN new = palloc0(sizeof(PLpgSQL_stmt_fors)); new->cmd_type = PLPGSQL_STMT_FORS; + new->stmtid = ++plpgsql_curr_compile->nstatements; if ($1.row) { new->var = (PLpgSQL_variable *) $1.row; @@ -1631,6 +1647,7 @@ stmt_foreach_a : opt_loop_label K_FOREACH for_variable foreach_slice K_IN K_ARRA new = palloc0(sizeof(PLpgSQL_stmt_foreach_a)); new->cmd_type = PLPGSQL_STMT_FOREACH_A; new->lineno = plpgsql_location_to_lineno(@2); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->label = $1; new->slice = $4; new->expr = $7; @@ -1677,6 +1694,7 @@ stmt_exit : exit_type opt_label opt_exitcond new = palloc0(sizeof(PLpgSQL_stmt_exit)); new->cmd_type = PLPGSQL_STMT_EXIT; + new->stmtid = ++plpgsql_curr_compile->nstatements; new->is_exit = $1; new->lineno = plpgsql_location_to_lineno(@1); new->label = $2; @@ -1768,6 +1786,7 @@ stmt_raise : K_RAISE new->cmd_type = PLPGSQL_STMT_RAISE; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->elog_level = ERROR; /* default */ new->condname = NULL; new->message = NULL; @@ -1912,6 +1931,7 @@ stmt_assert : K_ASSERT new->cmd_type = PLPGSQL_STMT_ASSERT; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->cond = read_sql_expression2(',', ';', ", or ;", @@ -1952,10 +1972,6 @@ stmt_execsql : K_IMPORT { $$ = make_execsql_stmt(K_INSERT, @1); } - | K_MERGE - { - $$ = make_execsql_stmt(K_MERGE, @1); - } | T_WORD { int tok; @@ -1993,6 +2009,7 @@ stmt_dynexecute : K_EXECUTE new = palloc(sizeof(PLpgSQL_stmt_dynexecute)); new->cmd_type = PLPGSQL_STMT_DYNEXECUTE; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->query = expr; new->into = false; new->strict = false; @@ -2049,6 +2066,7 @@ stmt_open : K_OPEN cursor_variable new = palloc0(sizeof(PLpgSQL_stmt_open)); new->cmd_type = PLPGSQL_STMT_OPEN; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->curvar = $2->dno; new->cursor_options = CURSOR_OPT_FAST_PLAN; @@ -2173,6 +2191,7 @@ stmt_close : K_CLOSE cursor_variable ';' new = palloc(sizeof(PLpgSQL_stmt_close)); new->cmd_type = PLPGSQL_STMT_CLOSE; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->curvar = $2->dno; $$ = (PLpgSQL_stmt *)new; @@ -2186,30 +2205,40 @@ stmt_null : K_NULL ';' } ; -stmt_commit : K_COMMIT ';' +stmt_commit : K_COMMIT opt_transaction_chain ';' { PLpgSQL_stmt_commit *new; new = palloc(sizeof(PLpgSQL_stmt_commit)); new->cmd_type = PLPGSQL_STMT_COMMIT; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->chain = $2; $$ = (PLpgSQL_stmt *)new; } ; -stmt_rollback : K_ROLLBACK ';' +stmt_rollback : K_ROLLBACK opt_transaction_chain ';' { PLpgSQL_stmt_rollback *new; new = palloc(sizeof(PLpgSQL_stmt_rollback)); new->cmd_type = PLPGSQL_STMT_ROLLBACK; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->chain = $2; $$ = (PLpgSQL_stmt *)new; } ; +opt_transaction_chain: + K_AND K_CHAIN { $$ = true; } + | K_AND K_NO K_CHAIN { $$ = false; } + | /* EMPTY */ { $$ = false; } + ; + stmt_set : K_SET { PLpgSQL_stmt_set *new; @@ -2217,6 +2246,8 @@ stmt_set : K_SET new = palloc0(sizeof(PLpgSQL_stmt_set)); new->cmd_type = PLPGSQL_STMT_SET; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; + new->expr = read_sql_stmt("SET "); $$ = (PLpgSQL_stmt *)new; @@ -2228,6 +2259,7 @@ stmt_set : K_SET new = palloc0(sizeof(PLpgSQL_stmt_set)); new->cmd_type = PLPGSQL_STMT_SET; new->lineno = plpgsql_location_to_lineno(@1); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = read_sql_stmt("RESET "); $$ = (PLpgSQL_stmt *)new; @@ -2287,7 +2319,8 @@ exception_sect : var = plpgsql_build_variable("sqlstate", lineno, plpgsql_build_datatype(TEXTOID, -1, - plpgsql_curr_compile->fn_input_collation), + plpgsql_curr_compile->fn_input_collation, + NULL), true); var->isconst = true; new->sqlstate_varno = var->dno; @@ -2295,7 +2328,8 @@ exception_sect : var = plpgsql_build_variable("sqlerrm", lineno, plpgsql_build_datatype(TEXTOID, -1, - plpgsql_curr_compile->fn_input_collation), + plpgsql_curr_compile->fn_input_collation, + NULL), true); var->isconst = true; new->sqlerrm_varno = var->dno; @@ -2464,10 +2498,12 @@ any_identifier : T_WORD unreserved_keyword : K_ABSOLUTE | K_ALIAS + | K_AND | K_ARRAY | K_ASSERT | K_BACKWARD | K_CALL + | K_CHAIN | K_CLOSE | K_COLLATE | K_COLUMN @@ -2502,7 +2538,6 @@ unreserved_keyword : | K_IS | K_LAST | K_LOG - | K_MERGE | K_MESSAGE | K_MESSAGE_TEXT | K_MOVE @@ -2523,7 +2558,6 @@ unreserved_keyword : | K_RAISE | K_RELATIVE | K_RESET - | K_RESULT_OID | K_RETURN | K_RETURNED_SQLSTATE | K_REVERSE @@ -2966,8 +3000,6 @@ make_execsql_stmt(int firsttoken, int location) { if (prev_tok == K_INSERT) continue; /* INSERT INTO is not an INTO-target */ - if (prev_tok == K_MERGE) - continue; /* MERGE INTO is not an INTO-target */ if (firsttoken == K_IMPORT) continue; /* IMPORT ... INTO is not an INTO-target */ if (have_into) @@ -3013,6 +3045,7 @@ make_execsql_stmt(int firsttoken, int location) execsql = palloc(sizeof(PLpgSQL_stmt_execsql)); execsql->cmd_type = PLPGSQL_STMT_EXECSQL; execsql->lineno = plpgsql_location_to_lineno(location); + execsql->stmtid = ++plpgsql_curr_compile->nstatements; execsql->sqlstmt = expr; execsql->into = have_into; execsql->strict = have_strict; @@ -3038,6 +3071,7 @@ read_fetch_direction(void) */ fetch = (PLpgSQL_stmt_fetch *) palloc0(sizeof(PLpgSQL_stmt_fetch)); fetch->cmd_type = PLPGSQL_STMT_FETCH; + fetch->stmtid = ++plpgsql_curr_compile->nstatements; /* set direction defaults: */ fetch->direction = FETCH_FORWARD; fetch->how_many = 1; @@ -3190,6 +3224,7 @@ make_return_stmt(int location) new = palloc0(sizeof(PLpgSQL_stmt_return)); new->cmd_type = PLPGSQL_STMT_RETURN; new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = NULL; new->retvarno = -1; @@ -3277,6 +3312,7 @@ make_return_next_stmt(int location) new = palloc0(sizeof(PLpgSQL_stmt_return_next)); new->cmd_type = PLPGSQL_STMT_RETURN_NEXT; new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->expr = NULL; new->retvarno = -1; @@ -3340,6 +3376,7 @@ make_return_query_stmt(int location) new = palloc0(sizeof(PLpgSQL_stmt_return_query)); new->cmd_type = PLPGSQL_STMT_RETURN_QUERY; new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; /* check for RETURN QUERY EXECUTE */ if ((tok = yylex()) != K_EXECUTE) @@ -3534,6 +3571,7 @@ read_into_scalar_list(char *initial_name, row = palloc0(sizeof(PLpgSQL_row)); row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = "(unnamed row)"; row->lineno = plpgsql_location_to_lineno(initial_location); row->rowtupdesc = NULL; row->nfields = nfields; @@ -3568,6 +3606,7 @@ make_scalar_list1(char *initial_name, row = palloc0(sizeof(PLpgSQL_row)); row->dtype = PLPGSQL_DTYPE_ROW; + row->refname = "(unnamed row)"; row->lineno = lineno; row->rowtupdesc = NULL; row->nfields = 1; @@ -3656,7 +3695,7 @@ plpgsql_sql_error_callback(void *arg) internalerrposition(myerrpos + errpos - cbarg->leaderlen - 1); } - /* In any case, flush errposition --- we want internalerrpos only */ + /* In any case, flush errposition --- we want internalerrposition only */ errposition(0); } @@ -3672,6 +3711,7 @@ plpgsql_sql_error_callback(void *arg) static PLpgSQL_type * parse_datatype(const char *string, int location) { + TypeName *typeName; Oid type_id; int32 typmod; sql_error_callback_arg cbarg; @@ -3686,14 +3726,16 @@ parse_datatype(const char *string, int location) error_context_stack = &syntax_errcontext; /* Let the main parser try to parse it under standard SQL rules */ - parseTypeString(string, &type_id, &typmod, false); + typeName = typeStringToTypeName(string); + typenameTypeIdAndMod(NULL, typeName, &type_id, &typmod); /* Restore former ereport callback */ error_context_stack = syntax_errcontext.previous; /* Okay, build a PLpgSQL_type data structure for it */ return plpgsql_build_datatype(type_id, typmod, - plpgsql_curr_compile->fn_input_collation); + plpgsql_curr_compile->fn_input_collation, + typeName); } /* @@ -4008,6 +4050,7 @@ make_case(int location, PLpgSQL_expr *t_expr, new = palloc(sizeof(PLpgSQL_stmt_case)); new->cmd_type = PLPGSQL_STMT_CASE; new->lineno = plpgsql_location_to_lineno(location); + new->stmtid = ++plpgsql_curr_compile->nstatements; new->t_expr = t_expr; new->t_varno = 0; new->case_when_list = case_when_list; @@ -4044,7 +4087,8 @@ make_case(int location, PLpgSQL_expr *t_expr, plpgsql_build_variable(varname, new->lineno, plpgsql_build_datatype(INT4OID, -1, - InvalidOid), + InvalidOid, + NULL), true); new->t_varno = t_var->dno; diff --git a/src/pl/plpgsql/src/pl_handler.c b/src/pl/plpgsql/src/pl_handler.c index 61452d9f7fd..ce03f1ef840 100644 --- a/src/pl/plpgsql/src/pl_handler.c +++ b/src/pl/plpgsql/src/pl_handler.c @@ -3,7 +3,7 @@ * pl_handler.c - Handler for the PL/pgSQL * procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -92,6 +92,10 @@ plpgsql_extra_checks_check_hook(char **newvalue, void **extra, GucSource source) if (pg_strcasecmp(tok, "shadowed_variables") == 0) extrachecks |= PLPGSQL_XCHECK_SHADOWVAR; + else if (pg_strcasecmp(tok, "too_many_rows") == 0) + extrachecks |= PLPGSQL_XCHECK_TOOMANYROWS; + else if (pg_strcasecmp(tok, "strict_multi_assignment") == 0) + extrachecks |= PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT; else if (pg_strcasecmp(tok, "all") == 0 || pg_strcasecmp(tok, "none") == 0) { GUC_check_errdetail("Key word \"%s\" cannot be combined with other key words.", tok); @@ -295,9 +299,9 @@ PG_FUNCTION_INFO_V1(plpgsql_inline_handler); Datum plpgsql_inline_handler(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(fake_fcinfo, 0); InlineCodeBlock *codeblock = castNode(InlineCodeBlock, DatumGetPointer(PG_GETARG_DATUM(0))); PLpgSQL_function *func; - FunctionCallInfoData fake_fcinfo; FmgrInfo flinfo; EState *simple_eval_estate; Datum retval; @@ -320,9 +324,9 @@ plpgsql_inline_handler(PG_FUNCTION_ARGS) * plpgsql_exec_function(). In particular note that this sets things up * with no arguments passed. */ - MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); + MemSet(fake_fcinfo, 0, SizeForFunctionCallInfo(0)); MemSet(&flinfo, 0, sizeof(flinfo)); - fake_fcinfo.flinfo = &flinfo; + fake_fcinfo->flinfo = &flinfo; flinfo.fn_oid = InvalidOid; flinfo.fn_mcxt = CurrentMemoryContext; @@ -332,7 +336,7 @@ plpgsql_inline_handler(PG_FUNCTION_ARGS) /* And run the function */ PG_TRY(); { - retval = plpgsql_exec_function(func, &fake_fcinfo, simple_eval_estate, codeblock->atomic); + retval = plpgsql_exec_function(func, fake_fcinfo, simple_eval_estate, codeblock->atomic); } PG_CATCH(); { @@ -462,7 +466,7 @@ plpgsql_validator(PG_FUNCTION_ARGS) /* Postpone body checks if !check_function_bodies */ if (check_function_bodies) { - FunctionCallInfoData fake_fcinfo; + LOCAL_FCINFO(fake_fcinfo, 0); FmgrInfo flinfo; int rc; TriggerData trigdata; @@ -478,26 +482,26 @@ plpgsql_validator(PG_FUNCTION_ARGS) * Set up a fake fcinfo with just enough info to satisfy * plpgsql_compile(). */ - MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); + MemSet(fake_fcinfo, 0, SizeForFunctionCallInfo(0)); MemSet(&flinfo, 0, sizeof(flinfo)); - fake_fcinfo.flinfo = &flinfo; + fake_fcinfo->flinfo = &flinfo; flinfo.fn_oid = funcoid; flinfo.fn_mcxt = CurrentMemoryContext; if (is_dml_trigger) { MemSet(&trigdata, 0, sizeof(trigdata)); trigdata.type = T_TriggerData; - fake_fcinfo.context = (Node *) &trigdata; + fake_fcinfo->context = (Node *) &trigdata; } else if (is_event_trigger) { MemSet(&etrigdata, 0, sizeof(etrigdata)); etrigdata.type = T_EventTriggerData; - fake_fcinfo.context = (Node *) &etrigdata; + fake_fcinfo->context = (Node *) &etrigdata; } /* Test-compile the function */ - plpgsql_compile(&fake_fcinfo, true); + plpgsql_compile(fake_fcinfo, true); /* * Disconnect from SPI manager diff --git a/src/pl/plpgsql/src/pl_reserved_kwlist.h b/src/pl/plpgsql/src/pl_reserved_kwlist.h new file mode 100644 index 00000000000..8425c3ca2ee --- /dev/null +++ b/src/pl/plpgsql/src/pl_reserved_kwlist.h @@ -0,0 +1,52 @@ +/*------------------------------------------------------------------------- + * + * pl_reserved_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/pl/plpgsql/src/pl_reserved_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef PL_RESERVED_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Be careful not to put the same word into pl_unreserved_kwlist.h. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("all", K_ALL) +PG_KEYWORD("begin", K_BEGIN) +PG_KEYWORD("by", K_BY) +PG_KEYWORD("case", K_CASE) +PG_KEYWORD("declare", K_DECLARE) +PG_KEYWORD("else", K_ELSE) +PG_KEYWORD("end", K_END) +PG_KEYWORD("execute", K_EXECUTE) +PG_KEYWORD("for", K_FOR) +PG_KEYWORD("foreach", K_FOREACH) +PG_KEYWORD("from", K_FROM) +PG_KEYWORD("if", K_IF) +PG_KEYWORD("in", K_IN) +PG_KEYWORD("into", K_INTO) +PG_KEYWORD("loop", K_LOOP) +PG_KEYWORD("not", K_NOT) +PG_KEYWORD("null", K_NULL) +PG_KEYWORD("or", K_OR) +PG_KEYWORD("strict", K_STRICT) +PG_KEYWORD("then", K_THEN) +PG_KEYWORD("to", K_TO) +PG_KEYWORD("using", K_USING) +PG_KEYWORD("when", K_WHEN) +PG_KEYWORD("while", K_WHILE) diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c index 256fc0a243b..c260438d7d4 100644 --- a/src/pl/plpgsql/src/pl_scanner.c +++ b/src/pl/plpgsql/src/pl_scanner.c @@ -4,7 +4,7 @@ * lexical scanning for PL/pgSQL * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,16 +22,15 @@ #include "pl_gram.h" /* must be after parser/scanner.h */ -#define PG_KEYWORD(a,b,c) {a,b,c}, - - /* Klugy flag to tell scanner how to look up identifiers */ IdentifierLookup plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; /* * A word about keywords: * - * We keep reserved and unreserved keywords in separate arrays. The + * We keep reserved and unreserved keywords in separate headers. Be careful + * not to put the same word in both headers. Also be sure that pl_gram.y's + * unreserved_keyword production agrees with the unreserved header. The * reserved keywords are passed to the core scanner, so they will be * recognized before (and instead of) any variable name. Unreserved words * are checked for separately, usually after determining that the identifier @@ -57,132 +56,22 @@ IdentifierLookup plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL; * BEGIN BY DECLARE EXECUTE FOREACH IF LOOP STRICT WHILE */ -/* - * Lists of keyword (name, token-value, category) entries. - * - * !!WARNING!!: These lists must be sorted by ASCII name, because binary - * search is used to locate entries. - * - * Be careful not to put the same word in both lists. Also be sure that - * pl_gram.y's unreserved_keyword production agrees with the second list. - */ +/* ScanKeywordList lookup data for PL/pgSQL keywords */ +#include "pl_reserved_kwlist_d.h" +#include "pl_unreserved_kwlist_d.h" -static const ScanKeyword reserved_keywords[] = { - PG_KEYWORD("all", K_ALL, RESERVED_KEYWORD) - PG_KEYWORD("begin", K_BEGIN, RESERVED_KEYWORD) - PG_KEYWORD("by", K_BY, RESERVED_KEYWORD) - PG_KEYWORD("case", K_CASE, RESERVED_KEYWORD) - PG_KEYWORD("declare", K_DECLARE, RESERVED_KEYWORD) - PG_KEYWORD("else", K_ELSE, RESERVED_KEYWORD) - PG_KEYWORD("end", K_END, RESERVED_KEYWORD) - PG_KEYWORD("execute", K_EXECUTE, RESERVED_KEYWORD) - PG_KEYWORD("for", K_FOR, RESERVED_KEYWORD) - PG_KEYWORD("foreach", K_FOREACH, RESERVED_KEYWORD) - PG_KEYWORD("from", K_FROM, RESERVED_KEYWORD) - PG_KEYWORD("if", K_IF, RESERVED_KEYWORD) - PG_KEYWORD("in", K_IN, RESERVED_KEYWORD) - PG_KEYWORD("into", K_INTO, RESERVED_KEYWORD) - PG_KEYWORD("loop", K_LOOP, RESERVED_KEYWORD) - PG_KEYWORD("not", K_NOT, RESERVED_KEYWORD) - PG_KEYWORD("null", K_NULL, RESERVED_KEYWORD) - PG_KEYWORD("or", K_OR, RESERVED_KEYWORD) - PG_KEYWORD("strict", K_STRICT, RESERVED_KEYWORD) - PG_KEYWORD("then", K_THEN, RESERVED_KEYWORD) - PG_KEYWORD("to", K_TO, RESERVED_KEYWORD) - PG_KEYWORD("using", K_USING, RESERVED_KEYWORD) - PG_KEYWORD("when", K_WHEN, RESERVED_KEYWORD) - PG_KEYWORD("while", K_WHILE, RESERVED_KEYWORD) +/* Token codes for PL/pgSQL keywords */ +#define PG_KEYWORD(kwname, value) value, + +static const uint16 ReservedPLKeywordTokens[] = { +#include "pl_reserved_kwlist.h" }; -static const int num_reserved_keywords = lengthof(reserved_keywords); - -static const ScanKeyword unreserved_keywords[] = { - PG_KEYWORD("absolute", K_ABSOLUTE, UNRESERVED_KEYWORD) - PG_KEYWORD("alias", K_ALIAS, UNRESERVED_KEYWORD) - PG_KEYWORD("array", K_ARRAY, UNRESERVED_KEYWORD) - PG_KEYWORD("assert", K_ASSERT, UNRESERVED_KEYWORD) - PG_KEYWORD("backward", K_BACKWARD, UNRESERVED_KEYWORD) - PG_KEYWORD("call", K_CALL, UNRESERVED_KEYWORD) - PG_KEYWORD("close", K_CLOSE, UNRESERVED_KEYWORD) - PG_KEYWORD("collate", K_COLLATE, UNRESERVED_KEYWORD) - PG_KEYWORD("column", K_COLUMN, UNRESERVED_KEYWORD) - PG_KEYWORD("column_name", K_COLUMN_NAME, UNRESERVED_KEYWORD) - PG_KEYWORD("commit", K_COMMIT, UNRESERVED_KEYWORD) - PG_KEYWORD("constant", K_CONSTANT, UNRESERVED_KEYWORD) - PG_KEYWORD("constraint", K_CONSTRAINT, UNRESERVED_KEYWORD) - PG_KEYWORD("constraint_name", K_CONSTRAINT_NAME, UNRESERVED_KEYWORD) - PG_KEYWORD("continue", K_CONTINUE, UNRESERVED_KEYWORD) - PG_KEYWORD("current", K_CURRENT, UNRESERVED_KEYWORD) - PG_KEYWORD("cursor", K_CURSOR, UNRESERVED_KEYWORD) - PG_KEYWORD("datatype", K_DATATYPE, UNRESERVED_KEYWORD) - PG_KEYWORD("debug", K_DEBUG, UNRESERVED_KEYWORD) - PG_KEYWORD("default", K_DEFAULT, UNRESERVED_KEYWORD) - PG_KEYWORD("detail", K_DETAIL, UNRESERVED_KEYWORD) - PG_KEYWORD("diagnostics", K_DIAGNOSTICS, UNRESERVED_KEYWORD) - PG_KEYWORD("do", K_DO, UNRESERVED_KEYWORD) - PG_KEYWORD("dump", K_DUMP, UNRESERVED_KEYWORD) - PG_KEYWORD("elseif", K_ELSIF, UNRESERVED_KEYWORD) - PG_KEYWORD("elsif", K_ELSIF, UNRESERVED_KEYWORD) - PG_KEYWORD("errcode", K_ERRCODE, UNRESERVED_KEYWORD) - PG_KEYWORD("error", K_ERROR, UNRESERVED_KEYWORD) - PG_KEYWORD("exception", K_EXCEPTION, UNRESERVED_KEYWORD) - PG_KEYWORD("exit", K_EXIT, UNRESERVED_KEYWORD) - PG_KEYWORD("fetch", K_FETCH, UNRESERVED_KEYWORD) - PG_KEYWORD("first", K_FIRST, UNRESERVED_KEYWORD) - PG_KEYWORD("forward", K_FORWARD, UNRESERVED_KEYWORD) - PG_KEYWORD("get", K_GET, UNRESERVED_KEYWORD) - PG_KEYWORD("hint", K_HINT, UNRESERVED_KEYWORD) - PG_KEYWORD("import", K_IMPORT, UNRESERVED_KEYWORD) - PG_KEYWORD("info", K_INFO, UNRESERVED_KEYWORD) - PG_KEYWORD("insert", K_INSERT, UNRESERVED_KEYWORD) - PG_KEYWORD("is", K_IS, UNRESERVED_KEYWORD) - PG_KEYWORD("last", K_LAST, UNRESERVED_KEYWORD) - PG_KEYWORD("log", K_LOG, UNRESERVED_KEYWORD) - PG_KEYWORD("merge", K_MERGE, UNRESERVED_KEYWORD) - PG_KEYWORD("message", K_MESSAGE, UNRESERVED_KEYWORD) - PG_KEYWORD("message_text", K_MESSAGE_TEXT, UNRESERVED_KEYWORD) - PG_KEYWORD("move", K_MOVE, UNRESERVED_KEYWORD) - PG_KEYWORD("next", K_NEXT, UNRESERVED_KEYWORD) - PG_KEYWORD("no", K_NO, UNRESERVED_KEYWORD) - PG_KEYWORD("notice", K_NOTICE, UNRESERVED_KEYWORD) - PG_KEYWORD("open", K_OPEN, UNRESERVED_KEYWORD) - PG_KEYWORD("option", K_OPTION, UNRESERVED_KEYWORD) - PG_KEYWORD("perform", K_PERFORM, UNRESERVED_KEYWORD) - PG_KEYWORD("pg_context", K_PG_CONTEXT, UNRESERVED_KEYWORD) - PG_KEYWORD("pg_datatype_name", K_PG_DATATYPE_NAME, UNRESERVED_KEYWORD) - PG_KEYWORD("pg_exception_context", K_PG_EXCEPTION_CONTEXT, UNRESERVED_KEYWORD) - PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL, UNRESERVED_KEYWORD) - PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT, UNRESERVED_KEYWORD) - PG_KEYWORD("print_strict_params", K_PRINT_STRICT_PARAMS, UNRESERVED_KEYWORD) - PG_KEYWORD("prior", K_PRIOR, UNRESERVED_KEYWORD) - PG_KEYWORD("query", K_QUERY, UNRESERVED_KEYWORD) - PG_KEYWORD("raise", K_RAISE, UNRESERVED_KEYWORD) - PG_KEYWORD("relative", K_RELATIVE, UNRESERVED_KEYWORD) - PG_KEYWORD("reset", K_RESET, UNRESERVED_KEYWORD) - PG_KEYWORD("result_oid", K_RESULT_OID, UNRESERVED_KEYWORD) - PG_KEYWORD("return", K_RETURN, UNRESERVED_KEYWORD) - PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE, UNRESERVED_KEYWORD) - PG_KEYWORD("reverse", K_REVERSE, UNRESERVED_KEYWORD) - PG_KEYWORD("rollback", K_ROLLBACK, UNRESERVED_KEYWORD) - PG_KEYWORD("row_count", K_ROW_COUNT, UNRESERVED_KEYWORD) - PG_KEYWORD("rowtype", K_ROWTYPE, UNRESERVED_KEYWORD) - PG_KEYWORD("schema", K_SCHEMA, UNRESERVED_KEYWORD) - PG_KEYWORD("schema_name", K_SCHEMA_NAME, UNRESERVED_KEYWORD) - PG_KEYWORD("scroll", K_SCROLL, UNRESERVED_KEYWORD) - PG_KEYWORD("set", K_SET, UNRESERVED_KEYWORD) - PG_KEYWORD("slice", K_SLICE, UNRESERVED_KEYWORD) - PG_KEYWORD("sqlstate", K_SQLSTATE, UNRESERVED_KEYWORD) - PG_KEYWORD("stacked", K_STACKED, UNRESERVED_KEYWORD) - PG_KEYWORD("table", K_TABLE, UNRESERVED_KEYWORD) - PG_KEYWORD("table_name", K_TABLE_NAME, UNRESERVED_KEYWORD) - PG_KEYWORD("type", K_TYPE, UNRESERVED_KEYWORD) - PG_KEYWORD("use_column", K_USE_COLUMN, UNRESERVED_KEYWORD) - PG_KEYWORD("use_variable", K_USE_VARIABLE, UNRESERVED_KEYWORD) - PG_KEYWORD("variable_conflict", K_VARIABLE_CONFLICT, UNRESERVED_KEYWORD) - PG_KEYWORD("warning", K_WARNING, UNRESERVED_KEYWORD) +static const uint16 UnreservedPLKeywordTokens[] = { +#include "pl_unreserved_kwlist.h" }; -static const int num_unreserved_keywords = lengthof(unreserved_keywords); +#undef PG_KEYWORD /* * This macro must recognize all tokens that can immediately precede a @@ -258,7 +147,7 @@ plpgsql_yylex(void) { int tok1; TokenAuxData aux1; - const ScanKeyword *kw; + int kwnum; tok1 = internal_yylex(&aux1); if (tok1 == IDENT || tok1 == PARAM) @@ -330,16 +219,17 @@ plpgsql_yylex(void) push_back_token(tok2, &aux2); if (plpgsql_parse_word(aux1.lval.str, core_yy.scanbuf + aux1.lloc, + true, &aux1.lval.wdatum, &aux1.lval.word)) tok1 = T_DATUM; else if (!aux1.lval.word.quoted && - (kw = ScanKeywordLookup(aux1.lval.word.ident, - unreserved_keywords, - num_unreserved_keywords))) + (kwnum = ScanKeywordLookup(aux1.lval.word.ident, + &UnreservedPLKeywords)) >= 0) { - aux1.lval.keyword = kw->name; - tok1 = kw->value; + aux1.lval.keyword = GetScanKeyword(kwnum, + &UnreservedPLKeywords); + tok1 = UnreservedPLKeywordTokens[kwnum]; } else tok1 = T_WORD; @@ -351,53 +241,40 @@ plpgsql_yylex(void) push_back_token(tok2, &aux2); /* - * If we are at start of statement, prefer unreserved keywords - * over variable names, unless the next token is assignment or - * '[', in which case prefer variable names. (Note we need not - * consider '.' as the next token; that case was handled above, - * and we always prefer variable names in that case.) If we are - * not at start of statement, always prefer variable names over - * unreserved keywords. + * See if it matches a variable name, except in the context where + * we are at start of statement and the next token isn't + * assignment or '['. In that case, it couldn't validly be a + * variable name, and skipping the lookup allows variable names to + * be used that would conflict with plpgsql or core keywords that + * introduce statements (e.g., "comment"). Without this special + * logic, every statement-introducing keyword would effectively be + * reserved in PL/pgSQL, which would be unpleasant. + * + * If it isn't a variable name, try to match against unreserved + * plpgsql keywords. If not one of those either, it's T_WORD. + * + * Note: we must call plpgsql_parse_word even if we don't want to + * do variable lookup, because it sets up aux1.lval.word for the + * non-variable cases. */ - if (AT_STMT_START(plpgsql_yytoken) && - !(tok2 == '=' || tok2 == COLON_EQUALS || tok2 == '[')) + if (plpgsql_parse_word(aux1.lval.str, + core_yy.scanbuf + aux1.lloc, + (!AT_STMT_START(plpgsql_yytoken) || + (tok2 == '=' || tok2 == COLON_EQUALS || + tok2 == '[')), + &aux1.lval.wdatum, + &aux1.lval.word)) + tok1 = T_DATUM; + else if (!aux1.lval.word.quoted && + (kwnum = ScanKeywordLookup(aux1.lval.word.ident, + &UnreservedPLKeywords)) >= 0) { - /* try for unreserved keyword, then for variable name */ - if (core_yy.scanbuf[aux1.lloc] != '"' && - (kw = ScanKeywordLookup(aux1.lval.str, - unreserved_keywords, - num_unreserved_keywords))) - { - aux1.lval.keyword = kw->name; - tok1 = kw->value; - } - else if (plpgsql_parse_word(aux1.lval.str, - core_yy.scanbuf + aux1.lloc, - &aux1.lval.wdatum, - &aux1.lval.word)) - tok1 = T_DATUM; - else - tok1 = T_WORD; + aux1.lval.keyword = GetScanKeyword(kwnum, + &UnreservedPLKeywords); + tok1 = UnreservedPLKeywordTokens[kwnum]; } else - { - /* try for variable name, then for unreserved keyword */ - if (plpgsql_parse_word(aux1.lval.str, - core_yy.scanbuf + aux1.lloc, - &aux1.lval.wdatum, - &aux1.lval.word)) - tok1 = T_DATUM; - else if (!aux1.lval.word.quoted && - (kw = ScanKeywordLookup(aux1.lval.word.ident, - unreserved_keywords, - num_unreserved_keywords))) - { - aux1.lval.keyword = kw->name; - tok1 = kw->value; - } - else - tok1 = T_WORD; - } + tok1 = T_WORD; } } else @@ -511,9 +388,9 @@ plpgsql_token_is_unreserved_keyword(int token) { int i; - for (i = 0; i < num_unreserved_keywords; i++) + for (i = 0; i < lengthof(UnreservedPLKeywordTokens); i++) { - if (unreserved_keywords[i].value == token) + if (UnreservedPLKeywordTokens[i] == token) return true; } return false; @@ -710,7 +587,7 @@ plpgsql_scanner_init(const char *str) { /* Start up the core scanner */ yyscanner = scanner_init(str, &core_yy, - reserved_keywords, num_reserved_keywords); + &ReservedPLKeywords, ReservedPLKeywordTokens); /* * scanorig points to the original string, which unlike the scanner's diff --git a/src/pl/plpgsql/src/pl_unreserved_kwlist.h b/src/pl/plpgsql/src/pl_unreserved_kwlist.h new file mode 100644 index 00000000000..6d85f9396ea --- /dev/null +++ b/src/pl/plpgsql/src/pl_unreserved_kwlist.h @@ -0,0 +1,112 @@ +/*------------------------------------------------------------------------- + * + * pl_unreserved_kwlist.h + * + * The keyword lists are kept in their own source files for use by + * automatic tools. The exact representation of a keyword is determined + * by the PG_KEYWORD macro, which is not defined in this file; it can + * be defined by the caller for special purposes. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/pl/plpgsql/src/pl_unreserved_kwlist.h + * + *------------------------------------------------------------------------- + */ + +/* There is deliberately not an #ifndef PL_UNRESERVED_KWLIST_H here. */ + +/* + * List of (keyword-name, keyword-token-value) pairs. + * + * Be careful not to put the same word into pl_reserved_kwlist.h. Also be + * sure that pl_gram.y's unreserved_keyword production agrees with this list. + * + * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. + */ + +/* name, value */ +PG_KEYWORD("absolute", K_ABSOLUTE) +PG_KEYWORD("alias", K_ALIAS) +PG_KEYWORD("and", K_AND) +PG_KEYWORD("array", K_ARRAY) +PG_KEYWORD("assert", K_ASSERT) +PG_KEYWORD("backward", K_BACKWARD) +PG_KEYWORD("call", K_CALL) +PG_KEYWORD("chain", K_CHAIN) +PG_KEYWORD("close", K_CLOSE) +PG_KEYWORD("collate", K_COLLATE) +PG_KEYWORD("column", K_COLUMN) +PG_KEYWORD("column_name", K_COLUMN_NAME) +PG_KEYWORD("commit", K_COMMIT) +PG_KEYWORD("constant", K_CONSTANT) +PG_KEYWORD("constraint", K_CONSTRAINT) +PG_KEYWORD("constraint_name", K_CONSTRAINT_NAME) +PG_KEYWORD("continue", K_CONTINUE) +PG_KEYWORD("current", K_CURRENT) +PG_KEYWORD("cursor", K_CURSOR) +PG_KEYWORD("datatype", K_DATATYPE) +PG_KEYWORD("debug", K_DEBUG) +PG_KEYWORD("default", K_DEFAULT) +PG_KEYWORD("detail", K_DETAIL) +PG_KEYWORD("diagnostics", K_DIAGNOSTICS) +PG_KEYWORD("do", K_DO) +PG_KEYWORD("dump", K_DUMP) +PG_KEYWORD("elseif", K_ELSIF) +PG_KEYWORD("elsif", K_ELSIF) +PG_KEYWORD("errcode", K_ERRCODE) +PG_KEYWORD("error", K_ERROR) +PG_KEYWORD("exception", K_EXCEPTION) +PG_KEYWORD("exit", K_EXIT) +PG_KEYWORD("fetch", K_FETCH) +PG_KEYWORD("first", K_FIRST) +PG_KEYWORD("forward", K_FORWARD) +PG_KEYWORD("get", K_GET) +PG_KEYWORD("hint", K_HINT) +PG_KEYWORD("import", K_IMPORT) +PG_KEYWORD("info", K_INFO) +PG_KEYWORD("insert", K_INSERT) +PG_KEYWORD("is", K_IS) +PG_KEYWORD("last", K_LAST) +PG_KEYWORD("log", K_LOG) +PG_KEYWORD("message", K_MESSAGE) +PG_KEYWORD("message_text", K_MESSAGE_TEXT) +PG_KEYWORD("move", K_MOVE) +PG_KEYWORD("next", K_NEXT) +PG_KEYWORD("no", K_NO) +PG_KEYWORD("notice", K_NOTICE) +PG_KEYWORD("open", K_OPEN) +PG_KEYWORD("option", K_OPTION) +PG_KEYWORD("perform", K_PERFORM) +PG_KEYWORD("pg_context", K_PG_CONTEXT) +PG_KEYWORD("pg_datatype_name", K_PG_DATATYPE_NAME) +PG_KEYWORD("pg_exception_context", K_PG_EXCEPTION_CONTEXT) +PG_KEYWORD("pg_exception_detail", K_PG_EXCEPTION_DETAIL) +PG_KEYWORD("pg_exception_hint", K_PG_EXCEPTION_HINT) +PG_KEYWORD("print_strict_params", K_PRINT_STRICT_PARAMS) +PG_KEYWORD("prior", K_PRIOR) +PG_KEYWORD("query", K_QUERY) +PG_KEYWORD("raise", K_RAISE) +PG_KEYWORD("relative", K_RELATIVE) +PG_KEYWORD("reset", K_RESET) +PG_KEYWORD("return", K_RETURN) +PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE) +PG_KEYWORD("reverse", K_REVERSE) +PG_KEYWORD("rollback", K_ROLLBACK) +PG_KEYWORD("row_count", K_ROW_COUNT) +PG_KEYWORD("rowtype", K_ROWTYPE) +PG_KEYWORD("schema", K_SCHEMA) +PG_KEYWORD("schema_name", K_SCHEMA_NAME) +PG_KEYWORD("scroll", K_SCROLL) +PG_KEYWORD("set", K_SET) +PG_KEYWORD("slice", K_SLICE) +PG_KEYWORD("sqlstate", K_SQLSTATE) +PG_KEYWORD("stacked", K_STACKED) +PG_KEYWORD("table", K_TABLE) +PG_KEYWORD("table_name", K_TABLE_NAME) +PG_KEYWORD("type", K_TYPE) +PG_KEYWORD("use_column", K_USE_COLUMN) +PG_KEYWORD("use_variable", K_USE_VARIABLE) +PG_KEYWORD("variable_conflict", K_VARIABLE_CONFLICT) +PG_KEYWORD("warning", K_WARNING) diff --git a/src/pl/plpgsql/src/plpgsql--1.0.sql b/src/pl/plpgsql/src/plpgsql--1.0.sql index 5eeea56824e..ab6fa84ab0d 100644 --- a/src/pl/plpgsql/src/plpgsql--1.0.sql +++ b/src/pl/plpgsql/src/plpgsql--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plpgsql; +CREATE LANGUAGE plpgsql; -COMMENT ON PROCEDURAL LANGUAGE plpgsql IS 'PL/pgSQL procedural language'; +COMMENT ON LANGUAGE plpgsql IS 'PL/pgSQL procedural language'; diff --git a/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql b/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql index 9de7e8392aa..15a74f091d6 100644 --- a/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql +++ b/src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plpgsql/src/plpgsql--unpackaged--1.0.sql */ -ALTER EXTENSION plpgsql ADD PROCEDURAL LANGUAGE plpgsql; +ALTER EXTENSION plpgsql ADD LANGUAGE plpgsql; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plpgsql ADD FUNCTION plpgsql_call_handler(); ALTER EXTENSION plpgsql ADD FUNCTION plpgsql_inline_handler(internal); diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h index 8d30180d424..f66b2baa70a 100644 --- a/src/pl/plpgsql/src/plpgsql.h +++ b/src/pl/plpgsql/src/plpgsql.h @@ -3,7 +3,7 @@ * plpgsql.h - Definitions for the PL/pgSQL * procedural language * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -21,6 +21,7 @@ #include "commands/trigger.h" #include "executor/spi.h" #include "utils/expandedrecord.h" +#include "utils/typcache.h" /********************************************************************** @@ -148,7 +149,6 @@ enum typedef enum PLpgSQL_getdiag_kind { PLPGSQL_GETDIAG_ROW_COUNT, - PLPGSQL_GETDIAG_RESULT_OID, PLPGSQL_GETDIAG_CONTEXT, PLPGSQL_GETDIAG_ERROR_CONTEXT, PLPGSQL_GETDIAG_ERROR_DETAIL, @@ -207,6 +207,10 @@ typedef struct PLpgSQL_type Oid collation; /* from pg_type, but can be overridden */ bool typisarray; /* is "true" array, or domain over one */ int32 atttypmod; /* typmod (taken from someplace else) */ + /* Remaining fields are used only for named composite types (not RECORD) */ + TypeName *origtypname; /* type name as written by user */ + TypeCacheEntry *tcache; /* typcache entry for composite type */ + uint64 tupdesc_id; /* last-seen tupdesc identifier */ } PLpgSQL_type; /* @@ -326,7 +330,12 @@ typedef struct PLpgSQL_var * Note that there's no way to name the row as such from PL/pgSQL code, * so many functions don't need to support these. * - * refname, isconst, notnull, and default_val are unsupported (and hence + * That also means that there's no real name for the row variable, so we + * conventionally set refname to "(unnamed row)". We could leave it NULL, + * but it's too convenient to be able to assume that refname is valid in + * all variants of PLpgSQL_variable. + * + * isconst, notnull, and default_val are unsupported (and hence * always zero/null) for a row. The member variables of a row should have * been checked to be writable at compile time, so isconst is correctly set * to false. notnull and default_val aren't applicable. @@ -368,6 +377,12 @@ typedef struct PLpgSQL_rec PLpgSQL_expr *default_val; /* end of PLpgSQL_variable fields */ + /* + * Note: for non-RECORD cases, we may from time to time re-look-up the + * composite type, using datatype->origtypname. That can result in + * changing rectypeid. + */ + PLpgSQL_type *datatype; /* can be NULL, if rectypeid is RECORDOID */ Oid rectypeid; /* declared type of variable */ /* RECFIELDs for this record are chained together for easy access */ @@ -443,6 +458,13 @@ typedef struct PLpgSQL_stmt { PLpgSQL_stmt_type cmd_type; int lineno; + + /* + * Unique statement ID in this function (starting at 1; 0 is invalid/not + * set). This can be used by a profiler as the index for an array of + * per-statement metrics. + */ + unsigned int stmtid; } PLpgSQL_stmt; /* @@ -482,6 +504,7 @@ typedef struct PLpgSQL_stmt_block { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; List *body; /* List of statements */ int n_initvars; /* Length of initvarnos[] */ @@ -496,6 +519,7 @@ typedef struct PLpgSQL_stmt_assign { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; int varno; PLpgSQL_expr *expr; } PLpgSQL_stmt_assign; @@ -507,6 +531,7 @@ typedef struct PLpgSQL_stmt_perform { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *expr; } PLpgSQL_stmt_perform; @@ -517,6 +542,7 @@ typedef struct PLpgSQL_stmt_call { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *expr; bool is_call; PLpgSQL_variable *target; @@ -529,6 +555,8 @@ typedef struct PLpgSQL_stmt_commit { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; + bool chain; } PLpgSQL_stmt_commit; /* @@ -538,6 +566,8 @@ typedef struct PLpgSQL_stmt_rollback { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; + bool chain; } PLpgSQL_stmt_rollback; /* @@ -547,6 +577,7 @@ typedef struct PLpgSQL_stmt_set { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *expr; } PLpgSQL_stmt_set; @@ -566,6 +597,7 @@ typedef struct PLpgSQL_stmt_getdiag { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; bool is_stacked; /* STACKED or CURRENT diagnostics area? */ List *diag_items; /* List of PLpgSQL_diag_item */ } PLpgSQL_stmt_getdiag; @@ -577,6 +609,7 @@ typedef struct PLpgSQL_stmt_if { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *cond; /* boolean expression for THEN */ List *then_body; /* List of statements */ List *elsif_list; /* List of PLpgSQL_if_elsif structs */ @@ -600,6 +633,7 @@ typedef struct PLpgSQL_stmt_case { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *t_expr; /* test expression, or NULL if none */ int t_varno; /* var to store test expression value into */ List *case_when_list; /* List of PLpgSQL_case_when structs */ @@ -624,6 +658,7 @@ typedef struct PLpgSQL_stmt_loop { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; List *body; /* List of statements */ } PLpgSQL_stmt_loop; @@ -635,6 +670,7 @@ typedef struct PLpgSQL_stmt_while { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_expr *cond; List *body; /* List of statements */ @@ -647,6 +683,7 @@ typedef struct PLpgSQL_stmt_fori { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_var *var; PLpgSQL_expr *lower; @@ -659,12 +696,13 @@ typedef struct PLpgSQL_stmt_fori /* * PLpgSQL_stmt_forq represents a FOR statement running over a SQL query. * It is the common supertype of PLpgSQL_stmt_fors, PLpgSQL_stmt_forc - * and PLpgSQL_dynfors. + * and PLpgSQL_stmt_dynfors. */ typedef struct PLpgSQL_stmt_forq { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_variable *var; /* Loop variable (record or row) */ List *body; /* List of statements */ @@ -677,6 +715,7 @@ typedef struct PLpgSQL_stmt_fors { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_variable *var; /* Loop variable (record or row) */ List *body; /* List of statements */ @@ -691,6 +730,7 @@ typedef struct PLpgSQL_stmt_forc { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_variable *var; /* Loop variable (record or row) */ List *body; /* List of statements */ @@ -706,6 +746,7 @@ typedef struct PLpgSQL_stmt_dynfors { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; PLpgSQL_variable *var; /* Loop variable (record or row) */ List *body; /* List of statements */ @@ -721,6 +762,7 @@ typedef struct PLpgSQL_stmt_foreach_a { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; char *label; int varno; /* loop target variable */ int slice; /* slice dimension, or 0 */ @@ -735,6 +777,7 @@ typedef struct PLpgSQL_stmt_open { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; int curvar; int cursor_options; PLpgSQL_expr *argquery; @@ -750,6 +793,7 @@ typedef struct PLpgSQL_stmt_fetch { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_variable *target; /* target (record or row) */ int curvar; /* cursor variable to fetch from */ FetchDirection direction; /* fetch direction */ @@ -766,6 +810,7 @@ typedef struct PLpgSQL_stmt_close { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; int curvar; } PLpgSQL_stmt_close; @@ -776,6 +821,7 @@ typedef struct PLpgSQL_stmt_exit { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; bool is_exit; /* Is this an exit or a continue? */ char *label; /* NULL if it's an unlabelled EXIT/CONTINUE */ PLpgSQL_expr *cond; @@ -788,6 +834,7 @@ typedef struct PLpgSQL_stmt_return { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *expr; int retvarno; } PLpgSQL_stmt_return; @@ -799,6 +846,7 @@ typedef struct PLpgSQL_stmt_return_next { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *expr; int retvarno; } PLpgSQL_stmt_return_next; @@ -810,6 +858,7 @@ typedef struct PLpgSQL_stmt_return_query { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *query; /* if static query */ PLpgSQL_expr *dynquery; /* if dynamic query (RETURN QUERY EXECUTE) */ List *params; /* USING arguments for dynamic query */ @@ -822,6 +871,7 @@ typedef struct PLpgSQL_stmt_raise { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; int elog_level; char *condname; /* condition name, SQLSTATE, or NULL */ char *message; /* old-style message format literal, or NULL */ @@ -845,6 +895,7 @@ typedef struct PLpgSQL_stmt_assert { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *cond; PLpgSQL_expr *message; } PLpgSQL_stmt_assert; @@ -856,9 +907,10 @@ typedef struct PLpgSQL_stmt_execsql { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *sqlstmt; - bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE/MERGE? - * Note mod_stmt is set when we plan the query */ + bool mod_stmt; /* is the stmt INSERT/UPDATE/DELETE? Note: + * mod_stmt is set when we plan the query */ bool into; /* INTO supplied? */ bool strict; /* INTO STRICT flag */ PLpgSQL_variable *target; /* INTO target (record or row) */ @@ -871,6 +923,7 @@ typedef struct PLpgSQL_stmt_dynexecute { PLpgSQL_stmt_type cmd_type; int lineno; + unsigned int stmtid; PLpgSQL_expr *query; /* string expression */ bool into; /* INTO supplied? */ bool strict; /* INTO STRICT flag */ @@ -959,6 +1012,9 @@ typedef struct PLpgSQL_function int extra_warnings; int extra_errors; + /* count of statements inside function */ + unsigned int nstatements; + /* the datums representing the function's local variables */ int ndatums; PLpgSQL_datum **datums; @@ -1038,7 +1094,6 @@ typedef struct PLpgSQL_execstate /* temporary state for results from evaluation of query or expr */ SPITupleTable *eval_tuptable; uint64 eval_processed; - Oid eval_lastoid; ExprContext *eval_econtext; /* for executing simple expressions */ /* status information for error context reporting */ @@ -1135,10 +1190,12 @@ extern bool plpgsql_print_strict_params; extern bool plpgsql_check_asserts; -/* extra compile-time checks */ -#define PLPGSQL_XCHECK_NONE 0 -#define PLPGSQL_XCHECK_SHADOWVAR 1 -#define PLPGSQL_XCHECK_ALL ((int) ~0) +/* extra compile-time and run-time checks */ +#define PLPGSQL_XCHECK_NONE 0 +#define PLPGSQL_XCHECK_SHADOWVAR (1 << 1) +#define PLPGSQL_XCHECK_TOOMANYROWS (1 << 2) +#define PLPGSQL_XCHECK_STRICTMULTIASSIGNMENT (1 << 3) +#define PLPGSQL_XCHECK_ALL ((int) ~0) extern int plpgsql_extra_warnings; extern int plpgsql_extra_errors; @@ -1166,34 +1223,35 @@ extern PLpgSQL_plugin **plpgsql_plugin_ptr; * Functions in pl_comp.c */ extern PLpgSQL_function *plpgsql_compile(FunctionCallInfo fcinfo, - bool forValidator); + bool forValidator); extern PLpgSQL_function *plpgsql_compile_inline(char *proc_source); extern void plpgsql_parser_setup(struct ParseState *pstate, - PLpgSQL_expr *expr); -extern bool plpgsql_parse_word(char *word1, const char *yytxt, - PLwdatum *wdatum, PLword *word); + PLpgSQL_expr *expr); +extern bool plpgsql_parse_word(char *word1, const char *yytxt, bool lookup, + PLwdatum *wdatum, PLword *word); extern bool plpgsql_parse_dblword(char *word1, char *word2, - PLwdatum *wdatum, PLcword *cword); + PLwdatum *wdatum, PLcword *cword); extern bool plpgsql_parse_tripword(char *word1, char *word2, char *word3, - PLwdatum *wdatum, PLcword *cword); + PLwdatum *wdatum, PLcword *cword); extern PLpgSQL_type *plpgsql_parse_wordtype(char *ident); extern PLpgSQL_type *plpgsql_parse_cwordtype(List *idents); extern PLpgSQL_type *plpgsql_parse_wordrowtype(char *ident); extern PLpgSQL_type *plpgsql_parse_cwordrowtype(List *idents); extern PLpgSQL_type *plpgsql_build_datatype(Oid typeOid, int32 typmod, - Oid collation); + Oid collation, + TypeName *origtypname); extern PLpgSQL_variable *plpgsql_build_variable(const char *refname, int lineno, - PLpgSQL_type *dtype, - bool add2namespace); + PLpgSQL_type *dtype, + bool add2namespace); extern PLpgSQL_rec *plpgsql_build_record(const char *refname, int lineno, - PLpgSQL_type *dtype, Oid rectypeid, - bool add2namespace); + PLpgSQL_type *dtype, Oid rectypeid, + bool add2namespace); extern PLpgSQL_recfield *plpgsql_build_recfield(PLpgSQL_rec *rec, - const char *fldname); -extern int plpgsql_recognize_err_condition(const char *condname, - bool allow_sqlstate); + const char *fldname); +extern int plpgsql_recognize_err_condition(const char *condname, + bool allow_sqlstate); extern PLpgSQL_condition *plpgsql_parse_err_condition(char *condname); -extern void plpgsql_adddatum(PLpgSQL_datum *new); +extern void plpgsql_adddatum(PLpgSQL_datum *newdatum); extern int plpgsql_add_initdatums(int **varnos); extern void plpgsql_HashTableInit(void); @@ -1206,36 +1264,37 @@ extern void _PG_init(void); * Functions in pl_exec.c */ extern Datum plpgsql_exec_function(PLpgSQL_function *func, - FunctionCallInfo fcinfo, - EState *simple_eval_estate, - bool atomic); + FunctionCallInfo fcinfo, + EState *simple_eval_estate, + bool atomic); extern HeapTuple plpgsql_exec_trigger(PLpgSQL_function *func, - TriggerData *trigdata); + TriggerData *trigdata); extern void plpgsql_exec_event_trigger(PLpgSQL_function *func, - EventTriggerData *trigdata); + EventTriggerData *trigdata); extern void plpgsql_xact_cb(XactEvent event, void *arg); extern void plpgsql_subxact_cb(SubXactEvent event, SubTransactionId mySubid, - SubTransactionId parentSubid, void *arg); -extern Oid plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate, - PLpgSQL_datum *datum); + SubTransactionId parentSubid, void *arg); +extern Oid plpgsql_exec_get_datum_type(PLpgSQL_execstate *estate, + PLpgSQL_datum *datum); extern void plpgsql_exec_get_datum_type_info(PLpgSQL_execstate *estate, - PLpgSQL_datum *datum, - Oid *typeid, int32 *typmod, Oid *collation); + PLpgSQL_datum *datum, + Oid *typeId, int32 *typMod, + Oid *collation); /* * Functions for namespace handling in pl_funcs.c */ extern void plpgsql_ns_init(void); extern void plpgsql_ns_push(const char *label, - PLpgSQL_label_type label_type); + PLpgSQL_label_type label_type); extern void plpgsql_ns_pop(void); extern PLpgSQL_nsitem *plpgsql_ns_top(void); extern void plpgsql_ns_additem(PLpgSQL_nsitem_type itemtype, int itemno, const char *name); extern PLpgSQL_nsitem *plpgsql_ns_lookup(PLpgSQL_nsitem *ns_cur, bool localmode, - const char *name1, const char *name2, - const char *name3, int *names_used); + const char *name1, const char *name2, + const char *name3, int *names_used); extern PLpgSQL_nsitem *plpgsql_ns_lookup_label(PLpgSQL_nsitem *ns_cur, - const char *name); + const char *name); extern PLpgSQL_nsitem *plpgsql_ns_find_nearest_loop(PLpgSQL_nsitem *ns_cur); /* @@ -1254,10 +1313,10 @@ extern int plpgsql_yylex(void); extern void plpgsql_push_back_token(int token); extern bool plpgsql_token_is_unreserved_keyword(int token); extern void plpgsql_append_source_text(StringInfo buf, - int startlocation, int endlocation); + int startlocation, int endlocation); extern int plpgsql_peek(void); extern void plpgsql_peek2(int *tok1_p, int *tok2_p, int *tok1_loc, - int *tok2_loc); + int *tok2_loc); extern int plpgsql_scanner_errposition(int location); extern void plpgsql_yyerror(const char *message) pg_attribute_noreturn(); extern int plpgsql_location_to_lineno(int location); diff --git a/src/pl/plpgsql/src/po/cs.po b/src/pl/plpgsql/src/po/cs.po index d5fe9577f3d..b088bf9fa8b 100644 --- a/src/pl/plpgsql/src/po/cs.po +++ b/src/pl/plpgsql/src/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: plpgsql-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-03-17 18:40+0000\n" -"PO-Revision-Date: 2013-03-17 22:17+0100\n" +"POT-Creation-Date: 2018-07-13 19:38+0000\n" +"PO-Revision-Date: 2018-07-13 23:52+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,35 +16,35 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.5\n" +"X-Generator: Poedit 2.0.7\n" -#: pl_comp.c:432 pl_handler.c:276 +#: pl_comp.c:434 pl_handler.c:457 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "funkce v PL/pgSQL nepodporují typ %s" -#: pl_comp.c:513 +#: pl_comp.c:522 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "nelze urÄit skuteÄný návratový typ polymorfní funkce \"%s\"" -#: pl_comp.c:543 +#: pl_comp.c:552 #, c-format msgid "trigger functions can only be called as triggers" msgstr "" "funkce pro obsluhu triggerů mohou být volané pouze prostÅ™ednictvím triggerů" -#: pl_comp.c:547 pl_handler.c:261 +#: pl_comp.c:556 pl_handler.c:441 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "funkce v PL/pgSQL nemohou vracet typ %s" -#: pl_comp.c:590 +#: pl_comp.c:595 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "funkce pro obsluhu triggeru nesmí mít argumenty" -#: pl_comp.c:591 +#: pl_comp.c:596 #, c-format msgid "" "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " @@ -53,42 +53,41 @@ msgstr "" "Parametry triggeru jsou přístupné prostÅ™ednictvím promÄ›nných TG_NARGS a " "TG_ARGV." -#: pl_comp.c:693 +#: pl_comp.c:719 #, c-format -#| msgid "trigger functions cannot have declared arguments" msgid "event trigger functions cannot have declared arguments" msgstr "funkce pro obsluhu event triggeru nesmí mít argumenty" -#: pl_comp.c:950 +#: pl_comp.c:976 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "pÅ™eklad PL/pgSQL funkce \"%s\" poblíž řádku %d" -#: pl_comp.c:973 +#: pl_comp.c:999 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "identifikátor parametru \"%s\" není unikátní" -#: pl_comp.c:1083 +#: pl_comp.c:1109 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "nejednoznaÄný odkaz na sloupec \"%s\"" # pÅ™eložil bych spíš asi jako "Identifikátor může odkazovat na promÄ›nnou PL/pgSQL nebo na sloupec v tabulce." # ok -#: pl_comp.c:1085 +#: pl_comp.c:1111 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "" "Identifikátor může odkazovat na promÄ›nnou PL/pgSQL nebo na sloupec v tabulce." -#: pl_comp.c:1265 pl_comp.c:1293 pl_exec.c:4031 pl_exec.c:4386 pl_exec.c:4472 -#: pl_exec.c:4563 +#: pl_comp.c:1294 pl_exec.c:5048 pl_exec.c:5413 pl_exec.c:5500 pl_exec.c:5591 +#: pl_exec.c:6509 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "záznam \"%s\" nemá položku \"%s\"" -#: pl_comp.c:1824 +#: pl_comp.c:1756 #, c-format msgid "relation \"%s\" does not exist" msgstr "relace \"%s\" neexistuje" @@ -96,408 +95,386 @@ msgstr "relace \"%s\" neexistuje" # asi spíš jako "promÄ›nná \"%s\" má pseudo-typ \"%s\" (slovo "obsahuje" si vykládám spíš jako že je souÄástí) # podivej se do zdrojaku, hlasi, kdyz zkusis deklarovat promennou s pseudotype - takze jsem to prelozil # jeste trochu jinak -#: pl_comp.c:1933 +#: pl_comp.c:1848 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "promÄ›nná \"%s\" je deklarována jako pseudo-typ \"%s\"" -#: pl_comp.c:1999 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "relace \"%s\" není tabulkou" - # spíš asi "je jenom obálka (shell)", # ok -#: pl_comp.c:2159 +#: pl_comp.c:2026 #, c-format msgid "type \"%s\" is only a shell" msgstr "typ \"%s\" je jen obálkou (shell)" -#: pl_comp.c:2233 pl_comp.c:2286 +#: pl_comp.c:2123 pl_comp.c:2176 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "nedefinovaná výjimka \"%s\"" -#: pl_comp.c:2444 +#: pl_comp.c:2390 #, c-format msgid "" "could not determine actual argument type for polymorphic function \"%s\"" msgstr "nelze urÄit skuteÄný typ argumentu polymorfní funkce \"%s\"" -#: pl_exec.c:254 pl_exec.c:514 pl_exec.c:793 +#: pl_exec.c:474 pl_exec.c:886 pl_exec.c:1103 msgid "during initialization of execution state" msgstr "bÄ›hem inicializace promÄ›nné execution state" -#: pl_exec.c:261 +#: pl_exec.c:480 msgid "while storing call arguments into local variables" msgstr "bÄ›hem ukládání parametrů funkce do lokálních promÄ›nných" -#: pl_exec.c:303 pl_exec.c:671 +#: pl_exec.c:568 pl_exec.c:938 msgid "during function entry" msgstr "bÄ›hem vstupu do funkce" -#: pl_exec.c:334 pl_exec.c:702 pl_exec.c:834 -#, c-format -msgid "CONTINUE cannot be used outside a loop" -msgstr "CONTINUE nemůže byt použito mimo tÄ›lo cyklu" - -#: pl_exec.c:338 +#: pl_exec.c:593 #, c-format msgid "control reached end of function without RETURN" msgstr "funkce skonÄila, aniž by byl proveden příkaz RETURN" -#: pl_exec.c:345 +#: pl_exec.c:600 msgid "while casting return value to function's return type" msgstr "bÄ›hem konverze vracené hodnoty do návratového typu funkce" -#: pl_exec.c:358 pl_exec.c:2779 +#: pl_exec.c:613 pl_exec.c:3511 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "funkce vracející tabulku (set-valued) byla zavolána z kontextu, který " "neumožňuje pÅ™ijetí tabulky" -#: pl_exec.c:396 pl_exec.c:2622 +#: pl_exec.c:739 pl_exec.c:967 pl_exec.c:1128 +msgid "during function exit" +msgstr "bÄ›hem ukonÄování funkce" + +#: pl_exec.c:794 pl_exec.c:833 pl_exec.c:3356 msgid "returned record type does not match expected record type" msgstr "" "vracenou hodnotu typu record nelze konvertovat do oÄekávaného typu record" -#: pl_exec.c:456 pl_exec.c:710 pl_exec.c:842 -msgid "during function exit" -msgstr "bÄ›hem ukonÄování funkce" - -#: pl_exec.c:706 pl_exec.c:838 +#: pl_exec.c:963 pl_exec.c:1124 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "funkce obsluhy triggeru skonÄila, aniž by byl proveden příkaz RETURN" -#: pl_exec.c:715 +#: pl_exec.c:972 #, c-format msgid "trigger procedure cannot return a set" msgstr "funkce obsluhy triggeru nemůže vrátit tabulku" -#: pl_exec.c:737 +#: pl_exec.c:1011 pl_exec.c:1039 msgid "" "returned row structure does not match the structure of the triggering table" msgstr "" "struktura vrácené hodnoty neodpovídá struktuÅ™e tabulky svázané s triggerem" -#: pl_exec.c:893 +#. translator: last %s is a phrase such as "during statement block +#. local variable initialization" +#. +#: pl_exec.c:1176 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "PL/pgSQL funkce %s řádek %d %s" -#: pl_exec.c:904 +#. translator: last %s is a phrase such as "while storing call +#. arguments into local variables" +#. +#: pl_exec.c:1187 #, c-format msgid "PL/pgSQL function %s %s" msgstr "PL/pgSQL funkce %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:912 +#: pl_exec.c:1195 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "PL/pgSQL funkce %s řádek %d na %s" -#: pl_exec.c:918 +#: pl_exec.c:1201 #, c-format msgid "PL/pgSQL function %s" msgstr "PL/pgSQL funkce %s" -#: pl_exec.c:1027 +#: pl_exec.c:1539 msgid "during statement block local variable initialization" msgstr "bÄ›hem inicializace lokálních promÄ›nných bloku" -#: pl_exec.c:1069 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "" -"NULL nemůže být výchozí hodnotou promÄ›nné \"%s\" deklarované jako NOT NULL" - -#: pl_exec.c:1119 +#: pl_exec.c:1637 msgid "during statement block entry" msgstr "bÄ›hem zahájení bloku" -#: pl_exec.c:1140 +#: pl_exec.c:1669 msgid "during statement block exit" msgstr "bÄ›hem ukonÄování bloku" -#: pl_exec.c:1183 +#: pl_exec.c:1707 msgid "during exception cleanup" msgstr "bÄ›hem ÄiÅ¡tÄ›ní po zachycení výjimky" -#: pl_exec.c:1530 +#: pl_exec.c:2234 pl_exec.c:2248 +#, c-format +msgid "argument %d is an output argument but is not writable" +msgstr "argument %d je výstupní argument ale není zapisovatelný" + +#: pl_exec.c:2290 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS nelze použít mimo obsluhu výjimky" -#: pl_exec.c:1696 +#: pl_exec.c:2495 #, c-format msgid "case not found" msgstr "varianta nenalezena" -#: pl_exec.c:1697 +#: pl_exec.c:2496 #, c-format msgid "CASE statement is missing ELSE part." msgstr "V příkazu CASE chybí Äást ELSE" -#: pl_exec.c:1849 +#: pl_exec.c:2589 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "spodní limit příkazu FOR nesmí být nullL" -#: pl_exec.c:1864 +#: pl_exec.c:2605 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "horní limit příkazu FOR nesmí být null" -#: pl_exec.c:1881 +#: pl_exec.c:2623 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "krok příkazu FOR nesmí být null" -#: pl_exec.c:1887 +#: pl_exec.c:2629 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "krok příkazu FOR musí být vÄ›tší než nula" -#: pl_exec.c:2057 pl_exec.c:3582 +#: pl_exec.c:2763 pl_exec.c:4478 #, c-format msgid "cursor \"%s\" already in use" msgstr "kurzor \"%s\" se již používá" -#: pl_exec.c:2080 pl_exec.c:3644 +#: pl_exec.c:2786 pl_exec.c:4543 #, c-format msgid "arguments given for cursor without arguments" msgstr "argumenty pro kurzor bez argumentů" -#: pl_exec.c:2099 pl_exec.c:3663 +#: pl_exec.c:2805 pl_exec.c:4562 #, c-format msgid "arguments required for cursor" msgstr "kurzor vyžaduje argumenty" -#: pl_exec.c:2186 +#: pl_exec.c:2892 #, c-format msgid "FOREACH expression must not be null" msgstr "výraz ve FOREACH nesmí být null" # výrazu/příkazu -#: pl_exec.c:2192 +#: pl_exec.c:2907 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "výsledkem výrazu příkazu FOREACH musí být pole, nikoliv %s" -#: pl_exec.c:2209 +#: pl_exec.c:2924 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "dimenze podpole (%d) je mimo validní rozsah 0..%d" -#: pl_exec.c:2236 +#: pl_exec.c:2951 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "FOREACH ... SLICE promÄ›nná cyklu musí být typu pole" -#: pl_exec.c:2240 +#: pl_exec.c:2955 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "FOREACH promÄ›nná cyklu nesmí být typu pole" -#: pl_exec.c:2461 pl_exec.c:2614 +#: pl_exec.c:3117 pl_exec.c:3174 pl_exec.c:3349 #, c-format -#| msgid "while casting return value to function's return type" msgid "" "cannot return non-composite value from function returning composite type" msgstr "z funkce vracející kompozitní typ nelze vracet jednoduchý datový typ" -#: pl_exec.c:2505 pl_gram.y:2972 +#: pl_exec.c:3213 pl_gram.y:3266 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "RETURN NEXT nelze použít ve funkci, která nevrací tabulku" -#: pl_exec.c:2533 pl_exec.c:2656 +#: pl_exec.c:3254 pl_exec.c:3386 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "typ parametru příkazu RETURN NEXT neodpovídá návratovému typu funkce " -#: pl_exec.c:2556 pl_exec.c:4018 pl_exec.c:4344 pl_exec.c:4379 pl_exec.c:4446 -#: pl_exec.c:4465 pl_exec.c:4533 pl_exec.c:4556 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "promÄ›nné \"%s\" typu record jeÅ¡tÄ› nebyla pÅ™iÅ™azena hodnota" - -# teÄka na konci -# ok -#: pl_exec.c:2558 pl_exec.c:4020 pl_exec.c:4346 pl_exec.c:4381 pl_exec.c:4448 -#: pl_exec.c:4467 pl_exec.c:4535 pl_exec.c:4558 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "" -"PromÄ›nná typu record, které jeÅ¡tÄ› nebyla pÅ™iÅ™azena hodnota, nemá definovanou " -"strukturu." - -#: pl_exec.c:2562 pl_exec.c:2582 +#: pl_exec.c:3292 pl_exec.c:3313 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "" "obsah parametru příkazu RETURN NEXT nelze pÅ™evést na návratový typ funkce" -#: pl_exec.c:2674 +#: pl_exec.c:3405 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT musí mít parametr" -#: pl_exec.c:2707 pl_gram.y:3030 +#: pl_exec.c:3431 pl_gram.y:3329 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "uvnitÅ™ funkce, která nevrací tabulku, nelze použít RETURN QUERY" -#: pl_exec.c:2727 +#: pl_exec.c:3455 msgid "structure of query does not match function result type" msgstr "struktura dotazu neodpovídá návratovému typu funkce" -#: pl_exec.c:2825 +#: pl_exec.c:3539 pl_exec.c:3677 #, c-format -msgid "RAISE without parameters cannot be used outside an exception handler" -msgstr "RAISE bez parametrů nesmí být použito mimo obsluhu výjimky" - -#: pl_exec.c:2866 -#, c-format -msgid "too few parameters specified for RAISE" -msgstr "příliÅ¡ málo parametrů příkazu RAISE" +msgid "RAISE option already specified: %s" +msgstr "opakované použití volitelného parametru: %s příkazu RAISE" -#: pl_exec.c:2894 +#: pl_exec.c:3573 #, c-format -msgid "too many parameters specified for RAISE" -msgstr "příliÅ¡ mnoho parametrů příkazu RAISE" +msgid "RAISE without parameters cannot be used outside an exception handler" +msgstr "RAISE bez parametrů nesmí být použito mimo obsluhu výjimky" -#: pl_exec.c:2914 +#: pl_exec.c:3667 #, c-format msgid "RAISE statement option cannot be null" msgstr "volitelný parametr příkazu RAISE nesmí být null" -#: pl_exec.c:2924 pl_exec.c:2933 pl_exec.c:2941 pl_exec.c:2949 -#, c-format -msgid "RAISE option already specified: %s" -msgstr "opakované použití volitelného parametru: %s příkazu RAISE" - -#: pl_exec.c:2985 +#: pl_exec.c:3737 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3135 pl_exec.c:3272 pl_exec.c:3445 +#: pl_exec.c:3792 #, c-format -msgid "cannot COPY to/from client in PL/pgSQL" -msgstr "v PL/pgSQL nelze použít COPY to/from klient" +msgid "assertion failed" +msgstr "assertion selhalo" -#: pl_exec.c:3139 pl_exec.c:3276 pl_exec.c:3449 +#: pl_exec.c:4129 pl_exec.c:4316 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "v PL/pgSQL nelze zahájit/ukonÄit transakci" +msgid "cannot COPY to/from client in PL/pgSQL" +msgstr "v PL/pgSQL nelze použít COPY to/from klient" -#: pl_exec.c:3140 pl_exec.c:3277 pl_exec.c:3450 +#: pl_exec.c:4135 #, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Použijte blok BEGIN .. END s klauzulí EXCEPTION." +msgid "unsupported transaction command in PL/pgSQL" +msgstr "nepodporovaný transakÄní příkaz v PL/pgSQL" # "nevrací" má trochu jiný význam než "nemůže vracet" -#: pl_exec.c:3300 pl_exec.c:3474 +#: pl_exec.c:4159 pl_exec.c:4346 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO je použito v příkazu, který nevrací data" -#: pl_exec.c:3320 pl_exec.c:3494 +#: pl_exec.c:4182 pl_exec.c:4369 #, c-format msgid "query returned no rows" msgstr "dotaz nevrátil žádný řádek" -#: pl_exec.c:3329 pl_exec.c:3503 +#: pl_exec.c:4201 pl_exec.c:4388 #, c-format msgid "query returned more than one row" msgstr "dotaz vrátil více než jeden řádek" -#: pl_exec.c:3344 +#: pl_exec.c:4218 #, c-format msgid "query has no destination for result data" msgstr "chybí cíl pro výsledek dotazu" -#: pl_exec.c:3345 +#: pl_exec.c:4219 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "Pokud nechcete použít výsledek SELECTu, použijte PERFORM." # generující? spíš asi "obsahující" nebo jenom "s dynamickým dotazem" # ok -#: pl_exec.c:3378 pl_exec.c:6341 +#: pl_exec.c:4252 pl_exec.c:8270 #, c-format msgid "query string argument of EXECUTE is null" msgstr "textový argument s dynamickým dotazem příkazu EXECUTE je null" -#: pl_exec.c:3437 +#: pl_exec.c:4308 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "EXECUTE příkazu SELECT ... INTO není implementováno" -#: pl_exec.c:3438 +#: pl_exec.c:4309 #, c-format msgid "" "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " "instead." msgstr "Možná chcete použít EXECUTE ... INTO nebo EXECUTE CREATE TABLE ... AS." +#: pl_exec.c:4322 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "EXECUTE transakÄního příkazu není implementováno" + # myslí se tím promÄ›nná která se pÅ™edává kurzoru nebo samotný kurzor? Pokud kurzor, tak asi spíš kurzorová promÄ›nná. # ok, i kdyz v tom necitim rozdil -#: pl_exec.c:3726 pl_exec.c:3818 +#: pl_exec.c:4624 pl_exec.c:4712 #, c-format msgid "cursor variable \"%s\" is null" msgstr "kurzorová promÄ›nná \"%s\" je null" -#: pl_exec.c:3733 pl_exec.c:3825 +#: pl_exec.c:4635 pl_exec.c:4723 #, c-format msgid "cursor \"%s\" does not exist" msgstr "kurzor \"%s\" neexistuje" -#: pl_exec.c:3747 +#: pl_exec.c:4648 #, c-format msgid "relative or absolute cursor position is null" msgstr "relativní nebo absolutní pozice kurzoru je null" -#: pl_exec.c:3914 +#: pl_exec.c:4898 pl_exec.c:4993 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "promÄ›nné \"%s\" deklarované jako NOT NULL nelze pÅ™iÅ™adit null" # hodnotU -#: pl_exec.c:3961 +#: pl_exec.c:4974 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "promÄ›nné složeného typu nelze pÅ™iÅ™adit jinou než složenou hodnot" -#: pl_exec.c:3985 +#: pl_exec.c:5006 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "promÄ›nné typu record nelze pÅ™iÅ™adit jinou než slouženou hodnotu" -#: pl_exec.c:4130 +#: pl_exec.c:5057 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "nelze pÅ™iÅ™azovat do systémového sloupce \"%s\"" + +#: pl_exec.c:5121 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "poÄet rozmÄ›rů pole (%d) pÅ™ekraÄuje povolené maximum (%d)" -#: pl_exec.c:4162 +#: pl_exec.c:5153 #, c-format msgid "subscripted object is not an array" msgstr "indexovaná promÄ›nná není pole" -#: pl_exec.c:4199 +#: pl_exec.c:5191 #, c-format msgid "array subscript in assignment must not be null" msgstr "index pole v přířazovacím příkazu nesmí být null" -#: pl_exec.c:4671 +#: pl_exec.c:5698 #, c-format msgid "query \"%s\" did not return data" msgstr "dotaz \"%s\" nevrátil žádná data" -#: pl_exec.c:4679 +#: pl_exec.c:5706 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" @@ -505,179 +482,209 @@ msgstr[0] "dotaz \"%s\" vrátil %d sloupec" msgstr[1] "dotaz \"%s\" vrátil %d sloupce" msgstr[2] "dotaz \"%s\" vrátil %d sloupců" -#: pl_exec.c:4705 +#: pl_exec.c:5734 #, c-format msgid "query \"%s\" returned more than one row" msgstr "dotaz \"%s\" vrátil více než jeden řádek" -#: pl_exec.c:4762 +#: pl_exec.c:5797 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "dotaz \"%s\" není SELECT" -#: pl_funcs.c:218 +#: pl_exec.c:6523 pl_exec.c:6563 pl_exec.c:6603 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "typ parametru %d (%s) neodpovídá typu pÅ™i přípravÄ› plánu (%s)" + +#: pl_exec.c:7378 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "promÄ›nné \"%s\" typu record jeÅ¡tÄ› nebyla pÅ™iÅ™azena hodnota" + +# teÄka na konci +# ok +#: pl_exec.c:7379 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "" +"PromÄ›nná typu record, které jeÅ¡tÄ› nebyla pÅ™iÅ™azena hodnota, nemá definovanou " +"strukturu." + +#: pl_funcs.c:239 msgid "statement block" msgstr "blok" -#: pl_funcs.c:220 +#: pl_funcs.c:241 msgid "assignment" msgstr "pÅ™iÅ™azení" -#: pl_funcs.c:230 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "FOR s celoÄíselnou řídící promÄ›nnou" # možná spíš "FOR nad SELECT dotazem # zkusim jeste neco jineho" -#: pl_funcs.c:232 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "FOR nad SELECT(em)" -#: pl_funcs.c:234 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "FOR nad kurzorem" -#: pl_funcs.c:236 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "FOREACH nad polem" -#: pl_funcs.c:248 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "SQL příkaz" -#: pl_funcs.c:250 -msgid "EXECUTE statement" -msgstr "EXECUTE příkaz" - -#: pl_funcs.c:252 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "FOR nad dynamickým výbÄ›rem (FOR over EXECUTE)" -#: pl_gram.y:439 +#: pl_gram.y:485 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "návÄ›stí bloku musí být umístÄ›no pÅ™ed klíÄové slovo DECLARE, nikoliv za" -#: pl_gram.y:459 +#: pl_gram.y:505 #, c-format msgid "collations are not supported by type %s" msgstr "typ %s nepodporuje collations" -# pÅ™ekládat RECORD jako "promÄ›nná složeného typu" mi pÅ™ijde divný (resp. spousta lidí nebude vÄ›dÄ›t o co jde), ale "záznam" se asi Äasto používá pro řádek tabulky ... -# record neprekladam (je to typ), prekladam row, ktery odpovida castecne zaznamu tabulek, ale take odpovida kompozitnim typum -# o zaznamu jsem take uvazoval, ale prislo mi divny, kdybych napsal "promenna typu record nebo zaznam" ponevadz jsou to pro -# pro mnohe z nas synonyma -#: pl_gram.y:474 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "" -"promÄ›nná typu record nebo složeného typu nemůže být oznaÄena jako konstanta" - -#: pl_gram.y:484 +#: pl_gram.y:524 #, c-format -msgid "row or record variable cannot be NOT NULL" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" msgstr "" -"promÄ›nná typu record nebo složeného typu nemůže být oznaÄena jako NOT NULL" +"promÄ›nná \"%s\" musí mít implicitní hodnotu, protože je deklarována jako NOT " +"NULL" -#: pl_gram.y:495 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "" -"nelze zadat defaultní hodnotu promÄ›nným typu record nebo složeného typu" - -#: pl_gram.y:640 pl_gram.y:655 pl_gram.y:681 +#: pl_gram.y:669 pl_gram.y:684 pl_gram.y:710 #, c-format msgid "variable \"%s\" does not exist" msgstr "promÄ›nná \"%s\" neexistuje" -#: pl_gram.y:699 pl_gram.y:712 +#: pl_gram.y:728 pl_gram.y:756 msgid "duplicate declaration" msgstr "duplicitní deklarace" -#: pl_gram.y:890 +#: pl_gram.y:739 pl_gram.y:767 +#, c-format +msgid "variable \"%s\" shadows a previously defined variable" +msgstr "promÄ›nná \"%s\" zastiňuje dříve definovanou promÄ›nnou" + +#: pl_gram.y:983 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "" "diagnostická položka %s není dostupná v příkazu GET STACKED DIAGNOSTICS" -#: pl_gram.y:903 +#: pl_gram.y:1001 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "" "diagnostická položka %s není dostupná v příkazu GET CURRENT DIAGNOSTICS" -#: pl_gram.y:980 +#: pl_gram.y:1099 msgid "unrecognized GET DIAGNOSTICS item" msgstr "neznámá položka příkazu GET DIAGNOSTICS" -#: pl_gram.y:991 pl_gram.y:3217 +#: pl_gram.y:1109 pl_gram.y:3508 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" není skalární promÄ›nná" -#: pl_gram.y:1243 pl_gram.y:1437 +#: pl_gram.y:1357 pl_gram.y:1550 #, c-format msgid "" -"loop variable of loop over rows must be a record or row variable or list of " -"scalar variables" +"loop variable of loop over rows must be a record variable or list of scalar " +"variables" msgstr "" -"řídící promÄ›nná cyklu musí být typu record nebo složeného typu, případnÄ› " -"seznam skalárních promÄ›nných" +"řídící promÄ›nná cyklu nad řádky musí být typu record nebo seznam skalárních " +"promÄ›nných" # asi by tam mÄ›lo být i to FOR, neplatí to pro vÅ¡echny cykly # ok -#: pl_gram.y:1277 +#: pl_gram.y:1391 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "cyklus FOR nad kurzorem musí mít pouze jednu cílovou promÄ›nnou" -#: pl_gram.y:1284 +#: pl_gram.y:1398 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "cyklus FOR nad kurzorem musí použít vázanou promÄ›nnou kurzoru" -#: pl_gram.y:1368 +#: pl_gram.y:1485 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "celoÄiselný cyklus FOR musí mít pouze jednu cílovou promÄ›nnou" -#: pl_gram.y:1404 +#: pl_gram.y:1521 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "nelze zadat atribut REVERSE v případÄ› cyklu FOR nad dotazem" -#: pl_gram.y:1551 +#: pl_gram.y:1652 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "" "řídící promÄ›nná(é) cyklu FOREACH musí být existující promÄ›nná, případnÄ› " "seznam existujících promÄ›nných" -#: pl_gram.y:1603 pl_gram.y:1640 pl_gram.y:1688 pl_gram.y:2673 pl_gram.y:2754 -#: pl_gram.y:2865 pl_gram.y:3618 +#: pl_gram.y:1693 +#, c-format +msgid "" +"there is no label \"%s\" attached to any block or loop enclosing this " +"statement" +msgstr "" +"žádné návÄ›stí \"%s\" není pÅ™iÅ™azeno k žádnému bloku nebo cyklu obsahujícímu " +"tento příkaz" + +#: pl_gram.y:1701 +#, c-format +msgid "block label \"%s\" cannot be used in CONTINUE" +msgstr "návÄ›stí bloku \"%s\" nelze použít v CONTINUE" + +#: pl_gram.y:1716 +#, c-format +msgid "EXIT cannot be used outside a loop, unless it has a label" +msgstr "EXIT nemůže byt použito mimo tÄ›lo cyklu, pokud nemá návÄ›stí" + +#: pl_gram.y:1717 +#, c-format +msgid "CONTINUE cannot be used outside a loop" +msgstr "CONTINUE nemůže byt použito mimo tÄ›lo cyklu" + +#: pl_gram.y:1741 pl_gram.y:1778 pl_gram.y:1826 pl_gram.y:2958 pl_gram.y:3041 +#: pl_gram.y:3152 pl_gram.y:3907 msgid "unexpected end of function definition" msgstr "neoÄekávaný konec definice funkce" -#: pl_gram.y:1708 pl_gram.y:1732 pl_gram.y:1748 pl_gram.y:1754 pl_gram.y:1843 -#: pl_gram.y:1851 pl_gram.y:1865 pl_gram.y:1960 pl_gram.y:2141 pl_gram.y:2224 -#: pl_gram.y:2346 pl_gram.y:3460 pl_gram.y:3521 pl_gram.y:3599 +#: pl_gram.y:1846 pl_gram.y:1870 pl_gram.y:1886 pl_gram.y:1892 pl_gram.y:2009 +#: pl_gram.y:2017 pl_gram.y:2031 pl_gram.y:2125 pl_gram.y:2360 pl_gram.y:2454 +#: pl_gram.y:2612 pl_gram.y:3749 pl_gram.y:3810 pl_gram.y:3888 msgid "syntax error" msgstr "syntaktická chyba" -#: pl_gram.y:1736 pl_gram.y:1738 pl_gram.y:2145 pl_gram.y:2147 +#: pl_gram.y:1874 pl_gram.y:1876 pl_gram.y:2364 pl_gram.y:2366 msgid "invalid SQLSTATE code" msgstr "nevalidní SQLSTATE kód" -#: pl_gram.y:1907 +#: pl_gram.y:2073 msgid "syntax error, expected \"FOR\"" msgstr "syntaktická chyba, oÄekává se \"FOR\"" -#: pl_gram.y:1969 +#: pl_gram.y:2134 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "příkaz FETCH nesmí vracet více řádek" -#: pl_gram.y:2025 +#: pl_gram.y:2244 #, c-format msgid "cursor variable must be a simple variable" msgstr "promÄ›nná kurzoru musí být skalární promÄ›nná" @@ -685,149 +692,160 @@ msgstr "promÄ›nná kurzoru musí být skalární promÄ›nná" # cursor bych asi nepÅ™ekládal, je to přímo název typu, navíc v refcursor to pÅ™eloženo není # kurzor (cursor) neni typ, a refcursor je fakticky varchar - vyhodil bych type # pripadne "promenna musi byt deklarovana jako kurzor nebo jako refcursor" -#: pl_gram.y:2031 +#: pl_gram.y:2250 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "promÄ›nná \"%s\" musí být kurzor nebo referencí na kurzor" -#: pl_gram.y:2199 -msgid "label does not exist" -msgstr "návÄ›stí neexistuje" - -#: pl_gram.y:2317 pl_gram.y:2328 +#: pl_gram.y:2583 pl_gram.y:2594 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" není známou promÄ›nnou" -#: pl_gram.y:2432 pl_gram.y:2442 pl_gram.y:2597 +#: pl_gram.y:2698 pl_gram.y:2708 pl_gram.y:2863 msgid "mismatched parentheses" msgstr "neodpovídající si závorky" -#: pl_gram.y:2446 +#: pl_gram.y:2712 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "chybÄ›jící \"%s\" na konci SQL výrazu" -#: pl_gram.y:2452 +#: pl_gram.y:2718 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "chybÄ›jící \"%s\" na konci SQL příkazu" -#: pl_gram.y:2469 +#: pl_gram.y:2735 msgid "missing expression" msgstr "chybÄ›jící výraz" -#: pl_gram.y:2471 +#: pl_gram.y:2737 msgid "missing SQL statement" msgstr "chybÄ›jící SQL příkaz" -#: pl_gram.y:2599 +#: pl_gram.y:2865 msgid "incomplete data type declaration" msgstr "neúplná deklarace datového typu" -#: pl_gram.y:2622 +#: pl_gram.y:2888 msgid "missing data type declaration" msgstr "chybÄ›jící deklarace datového typu" -#: pl_gram.y:2678 +#: pl_gram.y:2966 msgid "INTO specified more than once" msgstr "opakované použití INTO" -#: pl_gram.y:2846 +#: pl_gram.y:3133 msgid "expected FROM or IN" msgstr "oÄekáváno FROM nebo IN" -#: pl_gram.y:2906 +#: pl_gram.y:3193 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "uvnitÅ™ funkce, která vrací tabulku, RETURN nemá parametr" -#: pl_gram.y:2907 +#: pl_gram.y:3194 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Použijte RETURN NEXT nebo RETURN QUERY." -#: pl_gram.y:2915 +#: pl_gram.y:3204 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "uvnitÅ™ funkce s OUT parametry RETURN nemá parametr" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN v proceduÅ™e nemůže mít parametr" -#: pl_gram.y:2924 +#: pl_gram.y:3209 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "uvnitÅ™ funkce s návratovou hodnotou typu void RETURN nemá parametr" -#: pl_gram.y:2986 +#: pl_gram.y:3218 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "uvnitÅ™ funkce s OUT parametry RETURN nemá parametr" + +#: pl_gram.y:3280 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "uvnitÅ™ funkce s OUT parametry RETURN NEXT nemá paramet" -#: pl_gram.y:3086 +#: pl_gram.y:3387 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\" je deklarováno jako konstanta" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "promÄ›nná \"%s\" je deklarována jako konstanta (CONSTANT)" -#: pl_gram.y:3148 pl_gram.y:3160 +#: pl_gram.y:3450 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" +msgid "record variable cannot be part of multiple-item INTO list" msgstr "" "v seznamu cílových promÄ›nných klauzule INTO není dovoleno použítí promÄ›nné " -"typu record nebo složeného typu" +"typu record" -#: pl_gram.y:3205 +#: pl_gram.y:3496 #, c-format msgid "too many INTO variables specified" msgstr "příliÅ¡ mnoho cílových promÄ›nných v klauzuli INTO" -#: pl_gram.y:3413 +#: pl_gram.y:3702 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "použití koncového návÄ›stí \"%s\" k bloku bez návÄ›stí" -#: pl_gram.y:3420 +#: pl_gram.y:3709 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "koncové návÄ›stí \"%s\" nesouhlasí s návÄ›stím bloku \"%s\"" -#: pl_gram.y:3455 +#: pl_gram.y:3744 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "kurzor \"%s\" je deklarován bez parametrů" -#: pl_gram.y:3469 +#: pl_gram.y:3758 #, c-format msgid "cursor \"%s\" has arguments" msgstr "kurzor \"%s\" vyžaduje parametry" -#: pl_gram.y:3511 +#: pl_gram.y:3800 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "kurzor \"%s\" nemá žádný argument s názvem \"%s\"" -#: pl_gram.y:3531 +#: pl_gram.y:3820 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "hodnota parametru \"%s\" kurzoru \"%s\" zadána více než jednou" -#: pl_gram.y:3556 +#: pl_gram.y:3845 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "nedostatek argumentů pro kurzor \"%s\"" -#: pl_gram.y:3563 +#: pl_gram.y:3852 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "příliÅ¡ mnoho argumentů pro kurzor \"%s\"" -#: pl_gram.y:3635 +#: pl_gram.y:3939 msgid "unrecognized RAISE statement option" msgstr "neznámý volitelný parametr příkazu RAISE" -#: pl_gram.y:3639 +#: pl_gram.y:3943 msgid "syntax error, expected \"=\"" msgstr "syntaktická chyba, oÄekáváno \"=\"" -#: pl_handler.c:61 +#: pl_gram.y:3984 +#, c-format +msgid "too many parameters specified for RAISE" +msgstr "příliÅ¡ mnoho parametrů příkazu RAISE" + +#: pl_gram.y:3988 +#, c-format +msgid "too few parameters specified for RAISE" +msgstr "příliÅ¡ málo parametrů příkazu RAISE" + +#: pl_handler.c:154 msgid "" "Sets handling of conflicts between PL/pgSQL variable names and table column " "names." @@ -835,23 +853,40 @@ msgstr "" "Nastavuje způsob Å™eÅ¡ení konfliktu mezi názvy PL/pgSQL promÄ›nných a názvy " "sloupců tabulek." +#: pl_handler.c:163 +msgid "" +"Print information about parameters in the DETAIL part of the error messages " +"generated on INTO ... STRICT failures." +msgstr "" +"Vypíše informace o parametrech v DETAIL Äásto chybové zprávy generované " +"selháním INTO ... STRICT." + +#: pl_handler.c:171 +msgid "Perform checks given in ASSERT statements." +msgstr "Vyková kontroly uvedené v ASSERT příkazech." + +#: pl_handler.c:179 +msgid "List of programming constructs that should produce a warning." +msgstr "Seznam programovacích kontruktů které by mÄ›ly vygenerovat varování." + +#: pl_handler.c:189 +msgid "List of programming constructs that should produce an error." +msgstr "Seznam programovacích konstruktů které by mÄ›ly vygenerovat chybu." + #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:541 +#: pl_scanner.c:630 #, c-format msgid "%s at end of input" msgstr "\"%s\" na konci vstupu" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:557 +#: pl_scanner.c:646 #, c-format msgid "%s at or near \"%s\"" msgstr "%s na nebo blízko \"%s\"" -#~ msgid "" -#~ "RETURN must specify a record or row variable in function returning row" -#~ msgstr "" -#~ "uvnitÅ™ funkce, která vrací složenou hodnotu, lze použít RETURN pouze s " -#~ "promÄ›nnou typu record nebo složeného typu" +#~ msgid "duplicate value for cursor \"%s\" parameter \"%s\"" +#~ msgstr "duplicitní hodnota pro kurzor \"%s\" parametr \"%s\"" #~ msgid "" #~ "RETURN NEXT must specify a record or row variable in function returning " @@ -860,5 +895,41 @@ msgstr "%s na nebo blízko \"%s\"" #~ "uvnitÅ™ funkce, která vrací složenou hodnotu, lze použít RETURN NEXT pouze " #~ "s promÄ›nnou typu record nebo složeného typu" -#~ msgid "duplicate value for cursor \"%s\" parameter \"%s\"" -#~ msgstr "duplicitní hodnota pro kurzor \"%s\" parametr \"%s\"" +#~ msgid "" +#~ "RETURN must specify a record or row variable in function returning row" +#~ msgstr "" +#~ "uvnitÅ™ funkce, která vrací složenou hodnotu, lze použít RETURN pouze s " +#~ "promÄ›nnou typu record nebo složeného typu" + +#~ msgid "label does not exist" +#~ msgstr "návÄ›stí neexistuje" + +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "" +#~ "nelze zadat defaultní hodnotu promÄ›nným typu record nebo složeného typu" + +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "" +#~ "promÄ›nná typu record nebo složeného typu nemůže být oznaÄena jako NOT NULL" + +# pÅ™ekládat RECORD jako "promÄ›nná složeného typu" mi pÅ™ijde divný (resp. spousta lidí nebude vÄ›dÄ›t o co jde), ale "záznam" se asi Äasto používá pro řádek tabulky ... +# record neprekladam (je to typ), prekladam row, ktery odpovida castecne zaznamu tabulek, ale take odpovida kompozitnim typum +# o zaznamu jsem take uvazoval, ale prislo mi divny, kdybych napsal "promenna typu record nebo zaznam" ponevadz jsou to pro +# pro mnohe z nas synonyma +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "" +#~ "promÄ›nná typu record nebo složeného typu nemůže být oznaÄena jako " +#~ "konstanta" + +#~ msgid "EXECUTE statement" +#~ msgstr "EXECUTE příkaz" + +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "Použijte blok BEGIN .. END s klauzulí EXCEPTION." + +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" +#~ msgstr "" +#~ "NULL nemůže být výchozí hodnotou promÄ›nné \"%s\" deklarované jako NOT NULL" + +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "relace \"%s\" není tabulkou" diff --git a/src/pl/plpgsql/src/po/de.po b/src/pl/plpgsql/src/po/de.po index 7cb006ff7ba..9807f07ff4e 100644 --- a/src/pl/plpgsql/src/po/de.po +++ b/src/pl/plpgsql/src/po/de.po @@ -1,167 +1,162 @@ # German message translation file for plpgsql -# Copyright (C) 2009 - 2015 PostgreSQL Global Development Group +# Copyright (C) 2009 - 2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2009 - 2015. +# Peter Eisentraut , 2009 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.5\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-28 16:07+0000\n" -"PO-Revision-Date: 2016-04-29 13:20-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-09 03:38+0000\n" +"PO-Revision-Date: 2019-05-09 08:52+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: pl_comp.c:432 pl_handler.c:448 +#: pl_comp.c:436 pl_handler.c:461 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "PL/pgSQL-Funktionen können Typ %s nicht annehmen" -#: pl_comp.c:513 +#: pl_comp.c:524 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "konnte den tatsächlichen Rückgabetyp der polymorphischen Funktion »%s« nicht ermitteln" -#: pl_comp.c:543 +#: pl_comp.c:554 #, c-format msgid "trigger functions can only be called as triggers" msgstr "Triggerfunktionen können nur als Trigger aufgerufen werden" -#: pl_comp.c:547 pl_handler.c:433 +#: pl_comp.c:558 pl_handler.c:445 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "PL/pgSQL-Funktionen können keinen Rückgabetyp %s haben" -#: pl_comp.c:588 +#: pl_comp.c:597 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "Triggerfunktionen können keine deklarierten Argumente haben" -#: pl_comp.c:589 +#: pl_comp.c:598 #, c-format msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "Auf die Argumente des Triggers kann stattdessen über TG_NARGS und TG_ARGV zugegriffen werden." -#: pl_comp.c:691 +#: pl_comp.c:721 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "Ereignistriggerfunktionen können keine deklarierten Argumente haben" -#: pl_comp.c:944 +#: pl_comp.c:980 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "Kompilierung der PL/pgSQL-Funktion »%s« nahe Zeile %d" -#: pl_comp.c:967 +#: pl_comp.c:1003 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "Parametername »%s« mehrmals angegeben" -#: pl_comp.c:1077 +#: pl_comp.c:1115 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "Spaltenverweis »%s« ist nicht eindeutig" -#: pl_comp.c:1079 +#: pl_comp.c:1117 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "Er könnte sich entweder auf eine PL/pgSQL-Variable oder eine Tabellenspalte beziehen." -#: pl_comp.c:1259 pl_comp.c:1287 pl_exec.c:4395 pl_exec.c:4744 pl_exec.c:4829 -#: pl_exec.c:4920 +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "Record »%s« hat kein Feld »%s«" -#: pl_comp.c:1818 +#: pl_comp.c:1765 #, c-format msgid "relation \"%s\" does not exist" msgstr "Relation »%s« existiert nicht" -#: pl_comp.c:1927 +#: pl_comp.c:1857 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "Variable »%s« hat Pseudotyp %s" -#: pl_comp.c:1994 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "Relation »%s« ist keine Tabelle" - -#: pl_comp.c:2154 +#: pl_comp.c:2037 #, c-format msgid "type \"%s\" is only a shell" msgstr "Typ »%s« ist nur eine Hülle" -#: pl_comp.c:2243 pl_comp.c:2296 +#: pl_comp.c:2134 pl_comp.c:2187 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "unbekannte Ausnahmebedingung »%s«" -#: pl_comp.c:2503 +#: pl_comp.c:2401 #, c-format msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "konnte den tatsächlichen Argumenttyp der polymorphischen Funktion »%s« nicht ermitteln" -#: pl_exec.c:324 pl_exec.c:612 pl_exec.c:872 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 msgid "during initialization of execution state" msgstr "bei der Initialisierung des Ausführungszustandes" -#: pl_exec.c:331 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "beim Abspeichern der Aufrufargumente in lokale Variablen" -#: pl_exec.c:416 pl_exec.c:760 +#: pl_exec.c:569 pl_exec.c:960 msgid "during function entry" msgstr "beim Eintritts in die Funktion" -#: pl_exec.c:441 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "Kontrollfluss erreichte das Ende der Funktion ohne RETURN" -#: pl_exec.c:448 +#: pl_exec.c:601 msgid "while casting return value to function's return type" msgstr "bei der Umwandlung des Rückgabewerts in den Rückgabetyp der Funktion" -#: pl_exec.c:461 pl_exec.c:2938 +#: pl_exec.c:614 pl_exec.c:3556 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "Funktion mit Mengenergebnis in einem Zusammenhang aufgerufen, der keine Mengenergebnisse verarbeiten kann" -#: pl_exec.c:499 pl_exec.c:2779 -msgid "returned record type does not match expected record type" -msgstr "zurückgegebener Record-Typ stimmt nicht mit erwartetem Record-Typ überein" - -#: pl_exec.c:554 pl_exec.c:789 pl_exec.c:907 +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 msgid "during function exit" msgstr "beim Verlassen der Funktion" -#: pl_exec.c:785 pl_exec.c:903 +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 +msgid "returned record type does not match expected record type" +msgstr "zurückgegebener Record-Typ stimmt nicht mit erwartetem Record-Typ überein" + +#: pl_exec.c:985 pl_exec.c:1146 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "Kontrollfluss erreichte das Ende der Triggerprozedur ohne RETURN" -#: pl_exec.c:794 +#: pl_exec.c:994 #, c-format msgid "trigger procedure cannot return a set" msgstr "Triggerprozedur kann keine Ergebnismenge zurückgeben" -#: pl_exec.c:816 +#: pl_exec.c:1033 pl_exec.c:1061 msgid "returned row structure does not match the structure of the triggering table" msgstr "zurückgegebene Zeilenstruktur stimmt nicht mit der Struktur der Tabelle, die den Trigger ausgelöst hat, überein" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:954 +#: pl_exec.c:1198 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "PL/pgSQL-Funktion %s Zeile %d %s" @@ -169,367 +164,391 @@ msgstr "PL/pgSQL-Funktion %s Zeile %d %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:965 +#: pl_exec.c:1209 #, c-format msgid "PL/pgSQL function %s %s" msgstr "PL/pgSQL-Funktion %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:973 +#: pl_exec.c:1217 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "PL/pgSQL-Funktion %s Zeile %d bei %s" -#: pl_exec.c:979 +#: pl_exec.c:1223 #, c-format msgid "PL/pgSQL function %s" msgstr "PL/pgSQL-Funktion %s" -#: pl_exec.c:1089 +#: pl_exec.c:1561 msgid "during statement block local variable initialization" msgstr "bei der Initialisierung der lokalen Variablen des Anweisungsblocks" -#: pl_exec.c:1128 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "Variable »%s« ist als NOT NULL deklariert und kann daher nicht den Ausgangswert NULL haben" - -#: pl_exec.c:1178 +#: pl_exec.c:1659 msgid "during statement block entry" msgstr "beim Eintreten in den Anweisungsblock" -#: pl_exec.c:1199 +#: pl_exec.c:1691 msgid "during statement block exit" msgstr "beim Verlassen des Anweisungsblocks" -#: pl_exec.c:1242 +#: pl_exec.c:1729 msgid "during exception cleanup" msgstr "beim Aufräumen der Ausnahme" -#: pl_exec.c:1593 +#: pl_exec.c:2225 +#, c-format +msgid "procedure parameter \"%s\" is an output parameter but corresponding argument is not writable" +msgstr "Prozedurparameter »%s« ist ein Ausgabeparameter, aber das entsprechende Argument ist nicht schreibbar" + +#: pl_exec.c:2230 +#, c-format +msgid "procedure parameter %d is an output parameter but corresponding argument is not writable" +msgstr "Prozedurparameter %d ist ein Ausgabeparameter, aber das entsprechende Argument ist nicht schreibbar" + +#: pl_exec.c:2341 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS kann nicht außerhalb einer Ausnahmebehandlung verwendet werden" -#: pl_exec.c:1789 +#: pl_exec.c:2540 #, c-format msgid "case not found" msgstr "Fall nicht gefunden" -#: pl_exec.c:1790 +#: pl_exec.c:2541 #, c-format msgid "CASE statement is missing ELSE part." msgstr "Der CASE-Anweisung fehlt ein ELSE-Teil." -#: pl_exec.c:1944 +#: pl_exec.c:2634 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "Untergrenze einer FOR-Schleife darf nicht NULL sein" -#: pl_exec.c:1960 +#: pl_exec.c:2650 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "Obergrenze einer FOR-Schleife darf nicht NULL sein" -#: pl_exec.c:1978 +#: pl_exec.c:2668 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "BY-Wert einer FOR-Schleife darf nicht NULL sein" -#: pl_exec.c:1984 +#: pl_exec.c:2674 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "BY-Wert einer FOR-Schleife muss größer als null sein" -#: pl_exec.c:2153 pl_exec.c:3912 +#: pl_exec.c:2808 pl_exec.c:4530 #, c-format msgid "cursor \"%s\" already in use" msgstr "Cursor »%s« ist bereits in Verwendung" -#: pl_exec.c:2176 pl_exec.c:3974 +#: pl_exec.c:2831 pl_exec.c:4595 #, c-format msgid "arguments given for cursor without arguments" msgstr "einem Cursor ohne Argumente wurden Argumente übergeben" -#: pl_exec.c:2195 pl_exec.c:3993 +#: pl_exec.c:2850 pl_exec.c:4614 #, c-format msgid "arguments required for cursor" msgstr "Cursor benötigt Argumente" -#: pl_exec.c:2280 +#: pl_exec.c:2937 #, c-format msgid "FOREACH expression must not be null" msgstr "FOREACH-Ausdruck darf nicht NULL sein" -#: pl_exec.c:2286 +#: pl_exec.c:2952 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "FOREACH-Ausdruck muss ein Array ergeben, nicht Typ %s" -#: pl_exec.c:2303 +#: pl_exec.c:2969 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "Slice-Dimension (%d) ist außerhalb des gültigen Bereichs 0..%d" -#: pl_exec.c:2330 +#: pl_exec.c:2996 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "FOREACH ... SLICE Schleifenvariable muss einen Arraytyp haben" -#: pl_exec.c:2334 +#: pl_exec.c:3000 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "FOREACH-Schleifenvariable darf keinen Array-Typ haben" -#: pl_exec.c:2522 pl_exec.c:2604 pl_exec.c:2771 +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 #, c-format msgid "cannot return non-composite value from function returning composite type" msgstr "kann keinen nicht zusammengesetzten Wert aus einer Funktion zurückgeben, die einen zusammengesetzten Typ zurückgibt" -#: pl_exec.c:2648 pl_gram.y:3161 +#: pl_exec.c:3258 pl_gram.y:3305 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "RETURN NEXT kann nur in einer Funktion mit SETOF-Rückgabetyp verwendet werden" -#: pl_exec.c:2682 pl_exec.c:2813 +#: pl_exec.c:3299 pl_exec.c:3431 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "falscher Ergebnistyp angegeben in RETURN NEXT" -#: pl_exec.c:2711 pl_exec.c:4382 pl_exec.c:4711 pl_exec.c:4737 pl_exec.c:4803 -#: pl_exec.c:4822 pl_exec.c:4890 pl_exec.c:4913 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "Record »%s« hat noch keinen Wert" - -#: pl_exec.c:2713 pl_exec.c:4384 pl_exec.c:4713 pl_exec.c:4739 pl_exec.c:4805 -#: pl_exec.c:4824 pl_exec.c:4892 pl_exec.c:4915 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "Die Tupelstruktur eines Records ohne Wert ist unbestimmt." - -#: pl_exec.c:2717 pl_exec.c:2737 +#: pl_exec.c:3337 pl_exec.c:3358 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "falscher Record-Typ angegeben in RETURN NEXT" -#: pl_exec.c:2832 +#: pl_exec.c:3450 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT muss einen Parameter haben" -#: pl_exec.c:2865 pl_gram.y:3223 +#: pl_exec.c:3476 pl_gram.y:3369 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "RETURN QUERY kann nur in einer Funktion mit SETOF-Rückgabetyp verwendet werden" -#: pl_exec.c:2886 +#: pl_exec.c:3500 msgid "structure of query does not match function result type" msgstr "Struktur der Anfrage stimmt nicht mit Rückgabetyp der Funktion überein" -#: pl_exec.c:2966 pl_exec.c:3096 +#: pl_exec.c:3584 pl_exec.c:3722 #, c-format msgid "RAISE option already specified: %s" msgstr "RAISE-Option bereits angegeben: %s" -#: pl_exec.c:2999 +#: pl_exec.c:3618 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "RAISE ohne Parameter kann nicht außerhalb einer Ausnahmebehandlung verwendet werden" -#: pl_exec.c:3086 +#: pl_exec.c:3712 #, c-format msgid "RAISE statement option cannot be null" msgstr "Option einer RAISE-Anweisung darf nicht NULL sein" -#: pl_exec.c:3155 +#: pl_exec.c:3782 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3226 +#: pl_exec.c:3837 #, c-format msgid "assertion failed" msgstr "Assertion fehlgeschlagen" -#: pl_exec.c:3418 pl_exec.c:3562 pl_exec.c:3751 +#: pl_exec.c:4179 pl_exec.c:4369 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "COPY vom/zum Client funktioniert in PL/pgSQL nicht" -#: pl_exec.c:3422 pl_exec.c:3566 pl_exec.c:3755 +#: pl_exec.c:4185 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "Transaktionen können in PL/pgSQL nicht begonnen/beendet werden" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "nicht unterstützter Transaktionsbefehl in PL/pgSQL" -#: pl_exec.c:3423 pl_exec.c:3567 pl_exec.c:3756 -#, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Verwenden Sie stattdessen einen BEGIN-Block mit einer EXCEPTION-Klausel." - -#: pl_exec.c:3590 pl_exec.c:3780 +#: pl_exec.c:4208 pl_exec.c:4398 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO mit einem Befehl verwendet, der keine Daten zurückgeben kann" -#: pl_exec.c:3618 pl_exec.c:3808 +#: pl_exec.c:4231 pl_exec.c:4421 #, c-format msgid "query returned no rows" msgstr "Anfrage gab keine Zeilen zurück" -#: pl_exec.c:3637 pl_exec.c:3827 +#: pl_exec.c:4253 pl_exec.c:4440 #, c-format msgid "query returned more than one row" msgstr "Anfrage gab mehr als eine Zeile zurück" -#: pl_exec.c:3654 +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "Stellen Sie sicher, dass die Anfrage eine einzige Zeile zurückgibt, oder verwenden Sie LIMIT 1." + +#: pl_exec.c:4271 #, c-format msgid "query has no destination for result data" msgstr "Anfrage hat keinen Bestimmungsort für die Ergebnisdaten" -#: pl_exec.c:3655 +#: pl_exec.c:4272 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "Wenn Sie die Ergebnisse eines SELECT verwerfen wollen, verwenden Sie stattdessen PERFORM." -#: pl_exec.c:3687 pl_exec.c:7128 +#: pl_exec.c:4305 pl_exec.c:8416 #, c-format msgid "query string argument of EXECUTE is null" msgstr "Anfrageargument von EXECUTE ist NULL" -#: pl_exec.c:3743 +#: pl_exec.c:4361 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "EXECUTE von SELECT ... INTO ist nicht implementiert" -#: pl_exec.c:3744 +#: pl_exec.c:4362 #, c-format msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." msgstr "Sie könnten stattdessen EXECUTE ... INTO oder EXECUTE CREATE TABLE ... AS verwenden." -#: pl_exec.c:4056 pl_exec.c:4148 +#: pl_exec.c:4375 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "EXECUTE von Transaktionsbefehlen ist nicht implementiert" + +#: pl_exec.c:4676 pl_exec.c:4764 #, c-format msgid "cursor variable \"%s\" is null" msgstr "Cursor-Variable »%s« ist NULL" -#: pl_exec.c:4063 pl_exec.c:4155 +#: pl_exec.c:4687 pl_exec.c:4775 #, c-format msgid "cursor \"%s\" does not exist" msgstr "Cursor »%s« existiert nicht" -#: pl_exec.c:4077 +#: pl_exec.c:4700 #, c-format msgid "relative or absolute cursor position is null" msgstr "relative oder absolute Cursorposition ist NULL" -#: pl_exec.c:4257 +#: pl_exec.c:4956 pl_exec.c:5051 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "NULL-Wert kann der Variable »%s« nicht zugewiesen werden, weil sie als NOT NULL deklariert ist" -#: pl_exec.c:4326 +#: pl_exec.c:5032 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "nicht zusammengesetzter Wert kann nicht einer Zeilenvariable zugewiesen werden" -#: pl_exec.c:4350 +#: pl_exec.c:5064 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "nicht zusammengesetzter Wert kann nicht einer Record-Variable zugewiesen werden" -#: pl_exec.c:4493 +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "kann Systemspalte »%s« keinen Wert zuweisen" + +#: pl_exec.c:5179 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "Anzahl der Arraydimensionen (%d) überschreitet erlaubtes Maximum (%d)" -#: pl_exec.c:4525 +#: pl_exec.c:5211 #, c-format msgid "subscripted object is not an array" msgstr "Objekt mit Arrayindex ist kein Array" -#: pl_exec.c:4562 +#: pl_exec.c:5249 #, c-format msgid "array subscript in assignment must not be null" msgstr "Arrayindex in Zuweisung darf nicht NULL sein" -#: pl_exec.c:5029 +#: pl_exec.c:5756 #, c-format msgid "query \"%s\" did not return data" msgstr "Anfrage »%s« hat keine Daten zurückgegeben" -#: pl_exec.c:5037 +#: pl_exec.c:5764 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "Anfrage »%s« hat %d Spalte zurückgegeben" msgstr[1] "Anfrage »%s« hat %d Spalten zurückgegeben" -#: pl_exec.c:5064 +#: pl_exec.c:5792 #, c-format msgid "query \"%s\" returned more than one row" msgstr "Anfrage »%s« hat mehr als eine Zeile zurückgegeben" -#: pl_exec.c:5128 +#: pl_exec.c:5855 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "Anfrage »%s« ist kein SELECT" -#: pl_funcs.c:237 +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "Typ von Parameter %d (%s) stimmt nicht mit dem überein, als der Plan vorbereitet worden ist (%s)" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment do not match" +msgstr "Anzahl der Quell- und Zielfelder in der Zuweisung stimmt nicht überein" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "" + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "Stellen Sie sicher, dass die Anfrage die genaue Spaltenliste zurückgibt." + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "Record »%s« hat noch keinen Wert" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "Die Tupelstruktur eines Records ohne Wert ist unbestimmt." + +#: pl_funcs.c:239 msgid "statement block" msgstr "Anweisungsblock" -#: pl_funcs.c:239 +#: pl_funcs.c:241 msgid "assignment" msgstr "Zuweisung" -#: pl_funcs.c:249 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "FOR mit ganzzahliger Schleifenvariable" -#: pl_funcs.c:251 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "FOR über SELECT-Zeilen" -#: pl_funcs.c:253 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "FOR über Cursor" -#: pl_funcs.c:255 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "FOREACH über Array" -#: pl_funcs.c:269 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "SQL-Anweisung" -#: pl_funcs.c:273 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "FOR-über-EXECUTE-Anweisung" -#: pl_gram.y:473 +#: pl_gram.y:489 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "Blocklabel muss vor DECLARE stehen, nicht danach" -#: pl_gram.y:493 +#: pl_gram.y:509 #, c-format msgid "collations are not supported by type %s" msgstr "Sortierfolgen werden von Typ %s nicht unterstützt" -#: pl_gram.y:508 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "Zeilen- oder Record-Variable kann nicht CONSTANT sein" - -#: pl_gram.y:518 -#, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "Zeilen- oder Record-Variable kann nicht NOT NULL sein" - -#: pl_gram.y:529 +#: pl_gram.y:528 #, c-format -msgid "default value for row or record variable is not supported" -msgstr "Vorgabewerte werden für Zeilen- oder Record-Variablen nicht unterstützt" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "Variable »%s« muss einen Vorgabewert haben, da sie als NOT NULL deklariert ist" #: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 #, c-format @@ -545,278 +564,283 @@ msgstr "doppelte Deklaration" msgid "variable \"%s\" shadows a previously defined variable" msgstr "Variable »%s« verdeckt eine zuvor definierte Variable" -#: pl_gram.y:951 +#: pl_gram.y:992 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "Diagnostikelement %s ist in GET STACKED DIAGNOSTICS nicht erlaubt" -#: pl_gram.y:969 +#: pl_gram.y:1010 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "Diagnostikelement %s ist in GET CURRENT DIAGNOSTICS nicht erlaubt" -#: pl_gram.y:1067 +#: pl_gram.y:1105 msgid "unrecognized GET DIAGNOSTICS item" msgstr "unbekanntes Element in GET DIAGNOSTICS" -#: pl_gram.y:1078 pl_gram.y:3410 +#: pl_gram.y:1115 pl_gram.y:3549 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "»%s« ist keine skalare Variable" -#: pl_gram.y:1330 pl_gram.y:1524 +#: pl_gram.y:1369 pl_gram.y:1565 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" -msgstr "Schleifenvariable einer Schleife über Zeilen muss eine Record-Variable oder Zeilenvariable oder eine Liste von skalaren Variablen sein" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "Schleifenvariable einer Schleife über Zeilen muss eine Record-Variable oder eine Liste von skalaren Variablen sein" -#: pl_gram.y:1364 +#: pl_gram.y:1404 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "Cursor-FOR-Schleife darf nur eine Zielvariable haben" -#: pl_gram.y:1371 +#: pl_gram.y:1411 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "Cursor-FOR-Schleife muss eine gebundene Cursor-Variable verwenden" -#: pl_gram.y:1455 +#: pl_gram.y:1498 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "ganzzahlige FOR-Schleife darf nur eine Zielvariable haben" -#: pl_gram.y:1491 +#: pl_gram.y:1535 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "REVERSE kann nicht in einer Anfrage-FOR-Schleife verwendet werden" -#: pl_gram.y:1638 +#: pl_gram.y:1668 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "Schleifenvariable von FOREACH muss eine bekannte Variable oder Liste von Variablen sein" -#: pl_gram.y:1679 +#: pl_gram.y:1710 #, c-format msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" msgstr "diese Anweisung umschließt kein Block und keine Schleife mit Label »%s«" -#: pl_gram.y:1687 +#: pl_gram.y:1718 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "Blocklabel »%s« kann nicht in CONTINUE verwendet werden" -#: pl_gram.y:1702 +#: pl_gram.y:1733 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT kann nicht außerhalb einer Schleife verwendet werden, außer wenn es ein Label hat" -#: pl_gram.y:1703 +#: pl_gram.y:1734 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE kann nicht außerhalb einer Schleife verwendet werden" -#: pl_gram.y:1727 pl_gram.y:1764 pl_gram.y:1812 pl_gram.y:2863 pl_gram.y:2945 -#: pl_gram.y:3056 pl_gram.y:3812 +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 msgid "unexpected end of function definition" msgstr "unerwartetes Ende der Funktionsdefinition" -#: pl_gram.y:1832 pl_gram.y:1856 pl_gram.y:1872 pl_gram.y:1878 pl_gram.y:1992 -#: pl_gram.y:2000 pl_gram.y:2014 pl_gram.y:2109 pl_gram.y:2290 pl_gram.y:2384 -#: pl_gram.y:2535 pl_gram.y:3653 pl_gram.y:3714 pl_gram.y:3793 +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 msgid "syntax error" msgstr "Syntaxfehler" -#: pl_gram.y:1860 pl_gram.y:1862 pl_gram.y:2294 pl_gram.y:2296 +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 msgid "invalid SQLSTATE code" msgstr "ungültiger SQLSTATE-Code" -#: pl_gram.y:2056 +#: pl_gram.y:2094 msgid "syntax error, expected \"FOR\"" msgstr "Syntaxfehler, »FOR« erwartet" -#: pl_gram.y:2118 +#: pl_gram.y:2155 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "FETCH-Anweisung kann nicht mehrere Zeilen zurückgeben" -#: pl_gram.y:2174 +#: pl_gram.y:2279 #, c-format msgid "cursor variable must be a simple variable" msgstr "Cursor-Variable muss eine einfache Variable sein" -#: pl_gram.y:2180 +#: pl_gram.y:2285 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "Variable »%s« muss Typ cursor oder refcursor haben" -#: pl_gram.y:2506 pl_gram.y:2517 +#: pl_gram.y:2619 pl_gram.y:2630 #, c-format msgid "\"%s\" is not a known variable" msgstr "»%s« ist keine bekannte Variable" -#: pl_gram.y:2621 pl_gram.y:2631 pl_gram.y:2787 +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 msgid "mismatched parentheses" msgstr "Klammern passen nicht" -#: pl_gram.y:2635 +#: pl_gram.y:2748 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "»%s« fehlt am Ende des SQL-Ausdrucks" -#: pl_gram.y:2641 +#: pl_gram.y:2754 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "»%s« fehlt am Ende der SQL-Anweisung" -#: pl_gram.y:2658 +#: pl_gram.y:2771 msgid "missing expression" msgstr "Ausdruck fehlt" -#: pl_gram.y:2660 +#: pl_gram.y:2773 msgid "missing SQL statement" msgstr "SQL-Anweisung fehlt" -#: pl_gram.y:2789 +#: pl_gram.y:2901 msgid "incomplete data type declaration" msgstr "unvollständige Datentypdeklaration" -#: pl_gram.y:2812 +#: pl_gram.y:2924 msgid "missing data type declaration" msgstr "fehlende Datentypdeklaration" -#: pl_gram.y:2868 +#: pl_gram.y:3002 msgid "INTO specified more than once" msgstr "INTO mehr als einmal angegeben" -#: pl_gram.y:3037 +#: pl_gram.y:3171 msgid "expected FROM or IN" msgstr "FROM oder IN erwartet" -#: pl_gram.y:3097 +#: pl_gram.y:3232 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "RETURN kann keinen Parameter haben in einer Funktion mit Mengenergebnis" -#: pl_gram.y:3098 +#: pl_gram.y:3233 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Verwenden Sie RETURN NEXT oder RETURN QUERY." -#: pl_gram.y:3106 +#: pl_gram.y:3243 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN kann keinen Parameter haben in einer Funktion mit OUT-Parametern" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN kann keinen Parameter haben in einer Prozedur" -#: pl_gram.y:3115 +#: pl_gram.y:3248 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURN kann keinen Parameter haben in einer Funktion, die »void« zurückgibt" -#: pl_gram.y:3175 +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN kann keinen Parameter haben in einer Funktion mit OUT-Parametern" + +#: pl_gram.y:3320 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT kann keinen Parameter haben in einer Funktion mit OUT-Parametern" -#: pl_gram.y:3279 +#: pl_gram.y:3428 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "»%s« wurde als CONSTANT deklariert" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "Variable »%s« ist als CONSTANT deklariert" -#: pl_gram.y:3341 pl_gram.y:3353 +#: pl_gram.y:3491 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "Record- oder Zeilenvariable kann nicht Teil einer INTO-Liste mit mehreren Elementen sein" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "Record-Variable kann nicht Teil einer INTO-Liste mit mehreren Elementen sein" -#: pl_gram.y:3398 +#: pl_gram.y:3537 #, c-format msgid "too many INTO variables specified" msgstr "zu viele INTO-Variablen angegeben" -#: pl_gram.y:3606 +#: pl_gram.y:3745 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "Endlabel »%s« für ungelabelten Block angegeben" -#: pl_gram.y:3613 +#: pl_gram.y:3752 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "Endlabel »%s« unterscheidet sich vom Label des Blocks »%s«" -#: pl_gram.y:3648 +#: pl_gram.y:3787 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "Cursor »%s« hat keine Argumente" -#: pl_gram.y:3662 +#: pl_gram.y:3801 #, c-format msgid "cursor \"%s\" has arguments" msgstr "Cursor »%s« hat Argumente" -#: pl_gram.y:3704 +#: pl_gram.y:3843 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "Cursor »%s« hat kein Argument namens »%s«" -#: pl_gram.y:3724 +#: pl_gram.y:3863 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "Wert für Parameter »%s« von Cursor »%s« mehrmals angegeben" -#: pl_gram.y:3749 +#: pl_gram.y:3888 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "nicht genügend Argumente für Cursor »%s«" -#: pl_gram.y:3756 +#: pl_gram.y:3895 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "zu viele Argumente für Cursor »%s«" -#: pl_gram.y:3844 +#: pl_gram.y:3982 msgid "unrecognized RAISE statement option" msgstr "unbekannte Option für RAISE-Anweisung" -#: pl_gram.y:3848 +#: pl_gram.y:3986 msgid "syntax error, expected \"=\"" msgstr "Syntaxfehler, »=« erwartet" -#: pl_gram.y:3889 +#: pl_gram.y:4027 #, c-format msgid "too many parameters specified for RAISE" msgstr "zu viele Parameter für RAISE angegeben" -#: pl_gram.y:3893 +#: pl_gram.y:4031 #, c-format msgid "too few parameters specified for RAISE" msgstr "zu wenige Parameter für RAISE angegeben" -#: pl_handler.c:149 +#: pl_handler.c:158 msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "Bestimmt die Verarbeitung von Konflikten zwischen PL/pgSQL-Variablennamen und Tabellenspaltennamen." -#: pl_handler.c:158 +#: pl_handler.c:167 msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." msgstr "Informationen über Parameter im DETAIL-Teil von Fehlermeldungen ausgeben, die durch Fehler in INTO ... STRICT erzeugt wurden." -#: pl_handler.c:166 +#: pl_handler.c:175 msgid "Perform checks given in ASSERT statements." msgstr "Prüfungen in ASSERT-Anweisungen ausführen." -#: pl_handler.c:174 +#: pl_handler.c:183 msgid "List of programming constructs that should produce a warning." msgstr "Zählt Programmierkonstrukte auf, die eine Warnung erzeugen sollen." -#: pl_handler.c:184 +#: pl_handler.c:193 msgid "List of programming constructs that should produce an error." msgstr "Zählt Programmierkonstrukte auf, die einen Fehler zeugen sollen." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:621 +#: pl_scanner.c:508 #, c-format msgid "%s at end of input" msgstr "%s am Ende der Eingabe" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:637 +#: pl_scanner.c:524 #, c-format msgid "%s at or near \"%s\"" msgstr "%s bei »%s«" diff --git a/src/pl/plpgsql/src/po/es.po b/src/pl/plpgsql/src/po/es.po index 265ab4cb049..c541ba5d9fc 100644 --- a/src/pl/plpgsql/src/po/es.po +++ b/src/pl/plpgsql/src/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for plpgsql # -# Copyright (C) 2008-2012 PostgreSQL Global Development Group +# Copyright (c) 2008-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Ãlvaro Herrera 2008-2013 @@ -10,12 +10,12 @@ # msgid "" msgstr "" -"Project-Id-Version: plpgsql (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-05-22 07:38+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: plpgsql (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:26-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -23,149 +23,144 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Poedit 1.8.7\n" -#: pl_comp.c:433 pl_handler.c:451 +#: pl_comp.c:436 pl_handler.c:461 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "las funciones PL/pgSQL no pueden aceptar el tipo %s" -#: pl_comp.c:514 +#: pl_comp.c:524 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "no se pudo determinar el verdadero tipo de resultado para la función polimórfica «%s»" -#: pl_comp.c:544 +#: pl_comp.c:554 #, c-format msgid "trigger functions can only be called as triggers" msgstr "las funciones de disparador sólo pueden ser invocadas como disparadores" -#: pl_comp.c:548 pl_handler.c:436 +#: pl_comp.c:558 pl_handler.c:445 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "las funciones PL/pgSQL no pueden retornar el tipo %s" -#: pl_comp.c:589 +#: pl_comp.c:597 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "las funciones de disparador no pueden tener argumentos declarados" -#: pl_comp.c:590 +#: pl_comp.c:598 #, c-format msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "Los argumentos del disparador pueden accederse usando TG_NARGS y TG_ARGV." -#: pl_comp.c:692 +#: pl_comp.c:721 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "las funciones de disparador por eventos no pueden tener argumentos declarados" -#: pl_comp.c:943 +#: pl_comp.c:980 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "compilación de la función PL/pgSQL «%s» cerca de la línea %d" -#: pl_comp.c:966 +#: pl_comp.c:1003 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "el nombre de parámetro «%s» fue usado más de una vez" -#: pl_comp.c:1076 +#: pl_comp.c:1115 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "la referencia a la columna «%s» es ambigua" -#: pl_comp.c:1078 +#: pl_comp.c:1117 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "Podría referirse tanto a una variable PL/pgSQL como a una columna de una tabla." -#: pl_comp.c:1258 pl_comp.c:1286 pl_exec.c:4584 pl_exec.c:4913 pl_exec.c:4998 -#: pl_exec.c:5089 +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "el registro «%s» no tiene un campo «%s»" -#: pl_comp.c:1817 +#: pl_comp.c:1765 #, c-format msgid "relation \"%s\" does not exist" msgstr "no existe la relación «%s»" -#: pl_comp.c:1926 +#: pl_comp.c:1857 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "la variable «%s» tiene pseudotipo %s" -#: pl_comp.c:1993 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "la relación «%s» no es una tabla" - -#: pl_comp.c:2153 +#: pl_comp.c:2037 #, c-format msgid "type \"%s\" is only a shell" msgstr "el tipo «%s» está inconcluso" -#: pl_comp.c:2247 pl_comp.c:2300 +#: pl_comp.c:2134 pl_comp.c:2187 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "no se reconoce la condición de excepción «%s»" -#: pl_comp.c:2508 +#: pl_comp.c:2401 #, c-format msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "no se pudo determinar el verdadero tipo de argumento para la función polimórfica «%s»" -#: pl_exec.c:355 pl_exec.c:644 pl_exec.c:914 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 msgid "during initialization of execution state" msgstr "durante la inicialización del estado de ejecución" -#: pl_exec.c:362 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "mientras se almacenaban los argumentos de invocación en variables locales" -#: pl_exec.c:447 pl_exec.c:796 +#: pl_exec.c:569 pl_exec.c:960 msgid "during function entry" msgstr "durante el ingreso a la función" -#: pl_exec.c:472 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "la ejecución alcanzó el fin de la función sin encontrar RETURN" -#: pl_exec.c:479 +#: pl_exec.c:601 msgid "while casting return value to function's return type" msgstr "mientras se hacía la conversión del valor de retorno al tipo de retorno de la función" -#: pl_exec.c:492 pl_exec.c:3101 +#: pl_exec.c:614 pl_exec.c:3556 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "se llamó una función que retorna un conjunto en un contexto que no puede aceptarlo" -#: pl_exec.c:530 pl_exec.c:2948 -msgid "returned record type does not match expected record type" -msgstr "el tipo de registro retornado no coincide con el tipo de registro esperado" - -#: pl_exec.c:585 pl_exec.c:825 pl_exec.c:949 +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 msgid "during function exit" msgstr "durante la salida de la función" -#: pl_exec.c:821 pl_exec.c:945 +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 +msgid "returned record type does not match expected record type" +msgstr "el tipo de registro retornado no coincide con el tipo de registro esperado" + +#: pl_exec.c:985 pl_exec.c:1146 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "la ejecución alcanzó el fin del procedimiento disparador sin encontrar RETURN" -#: pl_exec.c:830 +#: pl_exec.c:994 #, c-format msgid "trigger procedure cannot return a set" msgstr "los procedimientos disparadores no pueden retornar conjuntos" -#: pl_exec.c:852 +#: pl_exec.c:1033 pl_exec.c:1061 msgid "returned row structure does not match the structure of the triggering table" msgstr "la estructura de fila retornada no coincide con la estructura de la tabla que generó el evento de disparador" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:997 +#: pl_exec.c:1198 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "función PL/pgSQL %s en la línea %d %s" @@ -173,311 +168,345 @@ msgstr "función PL/pgSQL %s en la línea %d %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:1008 +#: pl_exec.c:1209 #, c-format msgid "PL/pgSQL function %s %s" msgstr "función PL/pgSQL %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:1016 +#: pl_exec.c:1217 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "función PL/pgSQL %s en la línea %d en %s" -#: pl_exec.c:1022 +#: pl_exec.c:1223 #, c-format msgid "PL/pgSQL function %s" msgstr "función PL/pgSQL %s" -#: pl_exec.c:1187 +#: pl_exec.c:1561 msgid "during statement block local variable initialization" msgstr "durante inicialización de variables locales en el bloque de sentencias" -#: pl_exec.c:1226 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "la variable «%s» declarada NOT NULL no puede tener un valor por omisión NULL" - -#: pl_exec.c:1277 +#: pl_exec.c:1659 msgid "during statement block entry" msgstr "durante la entrada al bloque de sentencias" -#: pl_exec.c:1309 +#: pl_exec.c:1691 msgid "during statement block exit" msgstr "durante la salida del bloque de sentencias" -#: pl_exec.c:1351 +#: pl_exec.c:1729 msgid "during exception cleanup" msgstr "durante la finalización por excepción" -#: pl_exec.c:1717 +#: pl_exec.c:2225 +#, c-format +msgid "procedure parameter \"%s\" is an output parameter but corresponding argument is not writable" +msgstr "el parámetro de procedimiento «%s» es un parámetro de salida pero el argumento correspondiente no es escribible" + +#: pl_exec.c:2230 +#, c-format +msgid "procedure parameter %d is an output parameter but corresponding argument is not writable" +msgstr "el parámetro de procedimiento %d es un parámetro de salida pero el argumento correspondiente no es escribible" + +#: pl_exec.c:2341 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS no puede ser usado fuera de un manejador de excepción" -#: pl_exec.c:1922 +#: pl_exec.c:2540 #, c-format msgid "case not found" msgstr "caso no encontrado" -#: pl_exec.c:1923 +#: pl_exec.c:2541 #, c-format msgid "CASE statement is missing ELSE part." msgstr "A la sentencia CASE le falta la parte ELSE." -#: pl_exec.c:2077 +#: pl_exec.c:2634 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "el límite inferior de un ciclo FOR no puede ser null" -#: pl_exec.c:2093 +#: pl_exec.c:2650 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "el límite superior de un ciclo FOR no puede ser null" -#: pl_exec.c:2111 +#: pl_exec.c:2668 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "el valor BY de un ciclo FOR no puede ser null" -#: pl_exec.c:2117 +#: pl_exec.c:2674 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "el valor BY de un ciclo FOR debe ser mayor que cero" -#: pl_exec.c:2294 pl_exec.c:4085 +#: pl_exec.c:2808 pl_exec.c:4530 #, c-format msgid "cursor \"%s\" already in use" msgstr "el cursor «%s» ya está en uso" -#: pl_exec.c:2317 pl_exec.c:4150 +#: pl_exec.c:2831 pl_exec.c:4595 #, c-format msgid "arguments given for cursor without arguments" msgstr "se dieron argumentos a un cursor sin argumentos" -#: pl_exec.c:2336 pl_exec.c:4169 +#: pl_exec.c:2850 pl_exec.c:4614 #, c-format msgid "arguments required for cursor" msgstr "se requieren argumentos para el cursor" -#: pl_exec.c:2423 +#: pl_exec.c:2937 #, c-format msgid "FOREACH expression must not be null" msgstr "la expresión FOREACH no debe ser nula" -#: pl_exec.c:2438 +#: pl_exec.c:2952 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "una expresión FOREACH debe retornar un array, no tipo %s" -#: pl_exec.c:2455 +#: pl_exec.c:2969 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "la dimensión del slice (%d) está fuera de rango 0..%d" -#: pl_exec.c:2482 +#: pl_exec.c:2996 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "las variables de bucles FOREACH ... SLICE deben ser de un tipo array" -#: pl_exec.c:2486 +#: pl_exec.c:3000 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "la variable de bucle FOREACH no debe ser de tipo array" -#: pl_exec.c:2689 pl_exec.c:2771 pl_exec.c:2941 +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 #, c-format msgid "cannot return non-composite value from function returning composite type" msgstr "no se puede retornar un valor no-compuesto desde una función que retorne tipos compuestos" -#: pl_exec.c:2815 pl_gram.y:3199 +#: pl_exec.c:3258 pl_gram.y:3305 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "no se puede usar RETURN NEXT en una función que no es SETOF" -#: pl_exec.c:2849 pl_exec.c:2976 +#: pl_exec.c:3299 pl_exec.c:3431 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "se pasó un tipo incorrecto de resultado a RETURN NEXT" -#: pl_exec.c:2878 pl_exec.c:4572 pl_exec.c:4880 pl_exec.c:4906 pl_exec.c:4972 -#: pl_exec.c:4991 pl_exec.c:5059 pl_exec.c:5082 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "el registro «%s» no ha sido asignado aún" - -#: pl_exec.c:2880 pl_exec.c:4574 pl_exec.c:4882 pl_exec.c:4908 pl_exec.c:4974 -#: pl_exec.c:4993 pl_exec.c:5061 pl_exec.c:5084 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "La estructura de fila de un registro aún no asignado no está determinado." - -#: pl_exec.c:2887 pl_exec.c:2906 +#: pl_exec.c:3337 pl_exec.c:3358 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "se pasó un tipo de registro incorrecto a RETURN NEXT" -#: pl_exec.c:2995 +#: pl_exec.c:3450 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT debe tener un parámetro" -#: pl_exec.c:3021 pl_gram.y:3261 +#: pl_exec.c:3476 pl_gram.y:3369 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "no se puede usar RETURN QUERY en una función que no ha sido declarada SETOF" -#: pl_exec.c:3045 +#: pl_exec.c:3500 msgid "structure of query does not match function result type" msgstr "la estructura de la consulta no coincide con el tipo del resultado de la función" -#: pl_exec.c:3129 pl_exec.c:3267 +#: pl_exec.c:3584 pl_exec.c:3722 #, c-format msgid "RAISE option already specified: %s" msgstr "la opción de RAISE ya se especificó: %s" -#: pl_exec.c:3163 +#: pl_exec.c:3618 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "RAISE sin parámetros no puede ser usado fuera de un manejador de excepción" -#: pl_exec.c:3257 +#: pl_exec.c:3712 #, c-format msgid "RAISE statement option cannot be null" msgstr "la opción de sentencia en RAISE no puede ser null" -#: pl_exec.c:3327 +#: pl_exec.c:3782 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3382 +#: pl_exec.c:3837 #, c-format msgid "assertion failed" msgstr "aseveración falló" -#: pl_exec.c:3583 pl_exec.c:3729 pl_exec.c:3919 +#: pl_exec.c:4179 pl_exec.c:4369 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "no se puede ejecutar COPY desde/a un cliente en PL/pgSQL" -#: pl_exec.c:3587 pl_exec.c:3733 pl_exec.c:3923 +#: pl_exec.c:4185 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "no se pueden iniciar o terminar transacciones en PL/pgSQL" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "orden de transacción no soportada en PL/pgSQL" -#: pl_exec.c:3588 pl_exec.c:3734 pl_exec.c:3924 -#, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Utilice un bloque BEGIN con una cláusula EXCEPTION." - -#: pl_exec.c:3757 pl_exec.c:3948 +#: pl_exec.c:4208 pl_exec.c:4398 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO es utilizado con una orden que no puede retornar datos" -#: pl_exec.c:3785 pl_exec.c:3976 +#: pl_exec.c:4231 pl_exec.c:4421 #, c-format msgid "query returned no rows" msgstr "la consulta no regresó filas" -#: pl_exec.c:3804 pl_exec.c:3995 +#: pl_exec.c:4253 pl_exec.c:4440 #, c-format msgid "query returned more than one row" msgstr "la consulta regresó más de una fila" -#: pl_exec.c:3821 +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "Asegúrese que la consulta retorne una única fila, o use LIMIT 1." + +#: pl_exec.c:4271 #, c-format msgid "query has no destination for result data" msgstr "la consulta no tiene un destino para los datos de resultado" -#: pl_exec.c:3822 +#: pl_exec.c:4272 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "Si quiere descartar los resultados de un SELECT, utilice PERFORM." -#: pl_exec.c:3855 pl_exec.c:7292 +#: pl_exec.c:4305 pl_exec.c:8416 #, c-format msgid "query string argument of EXECUTE is null" msgstr "el argumento de consulta a ejecutar en EXECUTE es null" -#: pl_exec.c:3911 +#: pl_exec.c:4361 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "no está implementado EXECUTE de un SELECT ... INTO" -#: pl_exec.c:3912 +#: pl_exec.c:4362 #, c-format msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." msgstr "Puede desear usar EXECUTE ... INTO o EXECUTE CREATE TABLE ... AS en su lugar." -#: pl_exec.c:4233 pl_exec.c:4329 +#: pl_exec.c:4375 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "no está implementado EXECUTE de órdenes de transacción" + +#: pl_exec.c:4676 pl_exec.c:4764 #, c-format msgid "cursor variable \"%s\" is null" msgstr "variable cursor «%s» es null" -#: pl_exec.c:4244 pl_exec.c:4340 +#: pl_exec.c:4687 pl_exec.c:4775 #, c-format msgid "cursor \"%s\" does not exist" msgstr "no existe el cursor «%s»" -#: pl_exec.c:4257 +#: pl_exec.c:4700 #, c-format msgid "relative or absolute cursor position is null" msgstr "la posición relativa o absoluta del cursor es null" -#: pl_exec.c:4448 +#: pl_exec.c:4956 pl_exec.c:5051 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "no puede asignarse un valor null a la variable «%s» que fue declarada NOT NULL" -#: pl_exec.c:4517 +#: pl_exec.c:5032 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "no se puede asignar un valor no compuesto a una variable de tipo row" -#: pl_exec.c:4541 +#: pl_exec.c:5064 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "no se puede asignar un valor no compuesto a una variable de tipo record" -#: pl_exec.c:4661 +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "no se puede asignar a la columna de sistema «%s»" + +#: pl_exec.c:5179 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "el número de dimensiones del array (%d) excede el máximo permitido (%d)" -#: pl_exec.c:4693 +#: pl_exec.c:5211 #, c-format msgid "subscripted object is not an array" msgstr "el objeto al que se le puso un subíndice no es un array" -#: pl_exec.c:4731 +#: pl_exec.c:5249 #, c-format msgid "array subscript in assignment must not be null" msgstr "subíndice de array en asignación no puede ser null" -#: pl_exec.c:5198 +#: pl_exec.c:5756 #, c-format msgid "query \"%s\" did not return data" msgstr "la consulta «%s» no retornó datos" -#: pl_exec.c:5206 +#: pl_exec.c:5764 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "la consulta «%s» retornó %d columna" msgstr[1] "la consulta «%s» retornó %d columnas" -#: pl_exec.c:5233 +#: pl_exec.c:5792 #, c-format msgid "query \"%s\" returned more than one row" msgstr "la consulta «%s» retornó más de una fila" -#: pl_exec.c:5301 +#: pl_exec.c:5855 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "la consulta «%s» no es una orden SELECT" +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "el tipo del parámetro %d (%s) no coincide aquel con que fue preparado el plan (%s)" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment does not match" +msgstr "no coincide el número de campos de origen y destino en la asignación" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "El chequeo %s de %s está activo." + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "Asegúrese que la consulta retorna la lista exacta de columnas." + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "el registro «%s» no ha sido asignado aún" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "La estructura de fila de un registro aún no asignado no está determinado." + #: pl_funcs.c:239 msgid "statement block" msgstr "bloque de sentencias" @@ -510,320 +539,312 @@ msgstr "sentencia SQL" msgid "FOR over EXECUTE statement" msgstr "bucle FOR en torno a una sentencia EXECUTE" -#: pl_gram.y:478 +#: pl_gram.y:489 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "etiqueta de bloque debe estar antes de DECLARE, no después" -#: pl_gram.y:498 +#: pl_gram.y:509 #, c-format msgid "collations are not supported by type %s" msgstr "los ordenamientos (collation) no están soportados por el tipo %s" -#: pl_gram.y:513 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "variable de tipo row o record no puede ser CONSTANT" - -#: pl_gram.y:523 +#: pl_gram.y:528 #, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "variable de tipo row o record no puede ser NOT NULL" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "la variable «%s» debe tener valor por omisión, puesto que está declarado NOT NULL" -#: pl_gram.y:534 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "el valor por omisión de una variable de tipo row o record no está soportado" - -#: pl_gram.y:679 pl_gram.y:694 pl_gram.y:720 +#: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 #, c-format msgid "variable \"%s\" does not exist" msgstr "no existe la variable «%s»" -#: pl_gram.y:738 pl_gram.y:766 +#: pl_gram.y:733 pl_gram.y:761 msgid "duplicate declaration" msgstr "declaración duplicada" -#: pl_gram.y:749 pl_gram.y:777 +#: pl_gram.y:744 pl_gram.y:772 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "la variable «%s» oculta una variable definida anteriormente" -#: pl_gram.y:956 +#: pl_gram.y:992 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "elemento de diagnóstico %s no se permite en GET STACKED DIAGNOSTICS" -#: pl_gram.y:974 +#: pl_gram.y:1010 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "elemento de diagnóstico %s no se permite en GET STACKED DIAGNOSTICS" -#: pl_gram.y:1072 +#: pl_gram.y:1105 msgid "unrecognized GET DIAGNOSTICS item" msgstr "elemento de GET DIAGNOSTICS no reconocido" -#: pl_gram.y:1082 pl_gram.y:3448 +#: pl_gram.y:1115 pl_gram.y:3549 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "«%s» no es una variable escalar" -#: pl_gram.y:1334 pl_gram.y:1528 +#: pl_gram.y:1369 pl_gram.y:1565 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" -msgstr "la variable de bucle de un bucle sobre filas debe ser una variable de tipo record o row o una lista de variables escalares" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "la variable de bucle de un bucle sobre filas debe ser una variable de tipo record o una lista de variables escalares" -#: pl_gram.y:1368 +#: pl_gram.y:1404 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "un bucle FOR de un cursor debe tener sólo una variable de destino" -#: pl_gram.y:1375 +#: pl_gram.y:1411 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "un bucle FOR en torno a un cursor debe usar un cursor enlazado (bound)" -#: pl_gram.y:1459 +#: pl_gram.y:1498 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "un bucle FOR de un número entero debe tener sólo una variable de destino" -#: pl_gram.y:1495 +#: pl_gram.y:1535 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "no se puede especificar REVERSE en un bucle FOR de una consulta" -#: pl_gram.y:1642 +#: pl_gram.y:1668 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "la variable de bucle de FOREACH debe ser una variable conocida o una lista de variables conocidas" -#: pl_gram.y:1683 +#: pl_gram.y:1710 #, c-format msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" msgstr "ningún bloque o bucle que contenga esta sentencia tiene una etiqueta «%s»" -#: pl_gram.y:1691 +#: pl_gram.y:1718 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "la etiqueta de bloque «%s» no puede usarse en CONTINUE" -#: pl_gram.y:1706 +#: pl_gram.y:1733 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT no puede usarse fuera de un bucle, a menos que tenga una etiqueta" -#: pl_gram.y:1707 +#: pl_gram.y:1734 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE no puede usarse fuera de un bucle" -#: pl_gram.y:1731 pl_gram.y:1768 pl_gram.y:1816 pl_gram.y:2898 pl_gram.y:2983 -#: pl_gram.y:3094 pl_gram.y:3850 +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 msgid "unexpected end of function definition" msgstr "fin inesperado de la definición de la función" -#: pl_gram.y:1836 pl_gram.y:1860 pl_gram.y:1876 pl_gram.y:1882 pl_gram.y:2000 -#: pl_gram.y:2008 pl_gram.y:2022 pl_gram.y:2117 pl_gram.y:2304 pl_gram.y:2398 -#: pl_gram.y:2550 pl_gram.y:3691 pl_gram.y:3752 pl_gram.y:3831 +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 msgid "syntax error" msgstr "error de sintaxis" -#: pl_gram.y:1864 pl_gram.y:1866 pl_gram.y:2308 pl_gram.y:2310 +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 msgid "invalid SQLSTATE code" msgstr "código SQLSTATE no válido" -#: pl_gram.y:2064 +#: pl_gram.y:2094 msgid "syntax error, expected \"FOR\"" msgstr "error de sintaxis, se esperaba «FOR»" -#: pl_gram.y:2126 +#: pl_gram.y:2155 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "la sentencia FETCH no puede retornar múltiples filas" -#: pl_gram.y:2188 +#: pl_gram.y:2279 #, c-format msgid "cursor variable must be a simple variable" msgstr "variable de cursor debe ser una variable simple" -#: pl_gram.y:2194 +#: pl_gram.y:2285 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "la variable «%s» debe ser de tipo cursor o refcursor" -#: pl_gram.y:2521 pl_gram.y:2532 +#: pl_gram.y:2619 pl_gram.y:2630 #, c-format msgid "\"%s\" is not a known variable" msgstr "«%s» no es una variable conocida" -#: pl_gram.y:2636 pl_gram.y:2646 pl_gram.y:2802 +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 msgid "mismatched parentheses" msgstr "no coinciden los paréntesis" -#: pl_gram.y:2650 +#: pl_gram.y:2748 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "falta «%s» al final de la expresión SQL" -#: pl_gram.y:2656 +#: pl_gram.y:2754 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "falta «%s» al final de la sentencia SQL" -#: pl_gram.y:2673 +#: pl_gram.y:2771 msgid "missing expression" msgstr "expresión faltante" -#: pl_gram.y:2675 +#: pl_gram.y:2773 msgid "missing SQL statement" msgstr "sentencia SQL faltante" -#: pl_gram.y:2804 +#: pl_gram.y:2901 msgid "incomplete data type declaration" msgstr "declaración de tipo de dato incompleta" -#: pl_gram.y:2827 +#: pl_gram.y:2924 msgid "missing data type declaration" msgstr "declaración de tipo de dato faltante" -#: pl_gram.y:2906 +#: pl_gram.y:3002 msgid "INTO specified more than once" msgstr "INTO fue especificado más de una vez" -#: pl_gram.y:3075 +#: pl_gram.y:3171 msgid "expected FROM or IN" msgstr "se espera FROM o IN" -#: pl_gram.y:3135 +#: pl_gram.y:3232 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "RETURN no puede tener un parámetro en una función que retorna un conjunto" -#: pl_gram.y:3136 +#: pl_gram.y:3233 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Use RETURN NEXT o RETURN QUERY." -#: pl_gram.y:3144 +#: pl_gram.y:3243 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN no puede tener parámetros en una función con parámetros OUT" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN no puede tener un parámetro un procedimiento" -#: pl_gram.y:3153 +#: pl_gram.y:3248 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURN no puede tener parámetro en una función que retorna void" -#: pl_gram.y:3213 +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN no puede tener parámetros en una función con parámetros OUT" + +#: pl_gram.y:3320 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT no puede tener parámetros en una función con parámetros OUT" -#: pl_gram.y:3317 +#: pl_gram.y:3428 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "«%s» esta declarada como CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "la variable «%s» esta declarada como CONSTANT" -#: pl_gram.y:3379 pl_gram.y:3391 +#: pl_gram.y:3491 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "una variable de tipo record o row no puede ser parte de una lista INTO de múltiples elementos" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "una variable de tipo record no puede ser parte de una lista INTO de múltiples elementos" -#: pl_gram.y:3436 +#: pl_gram.y:3537 #, c-format msgid "too many INTO variables specified" msgstr "se especificaron demasiadas variables INTO" -#: pl_gram.y:3644 +#: pl_gram.y:3745 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "etiqueta de término «%s» especificada para un bloque sin etiqueta" -#: pl_gram.y:3651 +#: pl_gram.y:3752 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "etiqueta de término «%s» difiere de la etiqueta de bloque «%s»" -#: pl_gram.y:3686 +#: pl_gram.y:3787 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "el cursor «%s» no tiene argumentos" -#: pl_gram.y:3700 +#: pl_gram.y:3801 #, c-format msgid "cursor \"%s\" has arguments" msgstr "el cursor «%s» tiene argumentos" -#: pl_gram.y:3742 +#: pl_gram.y:3843 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "el cursor «%s» no tiene un argumento llamado «%s»" -#: pl_gram.y:3762 +#: pl_gram.y:3863 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "el valor para el parámetro «%s» del cursor «%s» fue especificado más de una vez" -#: pl_gram.y:3787 +#: pl_gram.y:3888 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "no hay suficientes argumentos para el cursor «%s»" -#: pl_gram.y:3794 +#: pl_gram.y:3895 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "demasiados argumentos para el cursor «%s»" -#: pl_gram.y:3882 +#: pl_gram.y:3982 msgid "unrecognized RAISE statement option" msgstr "no se reconoce la opción de sentencia RAISE" -#: pl_gram.y:3886 +#: pl_gram.y:3986 msgid "syntax error, expected \"=\"" msgstr "error de sintaxis, se esperaba «=»" -#: pl_gram.y:3927 +#: pl_gram.y:4027 #, c-format msgid "too many parameters specified for RAISE" msgstr "se especificaron demasiados parámetros a RAISE" -#: pl_gram.y:3931 +#: pl_gram.y:4031 #, c-format msgid "too few parameters specified for RAISE" msgstr "se especificaron muy pocos parámetros a RAISE" -#: pl_handler.c:154 +#: pl_handler.c:158 msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "Determina el manejo de conflictos entre nombres de variables PL/pgSQL y nombres de columnas de tablas." -#: pl_handler.c:163 +#: pl_handler.c:167 msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." msgstr "Imprimir información de parámetros en la parte DETALLE de los mensajes de error generados por fallos en INTO ... STRICT." -#: pl_handler.c:171 +#: pl_handler.c:175 msgid "Perform checks given in ASSERT statements." msgstr "Ejecuta las verificaciones en sentencias ASSERT." -#: pl_handler.c:179 +#: pl_handler.c:183 msgid "List of programming constructs that should produce a warning." msgstr "Listado de estructuras de programación que deben dar una advertencia." -#: pl_handler.c:189 +#: pl_handler.c:193 msgid "List of programming constructs that should produce an error." msgstr "Listado de estructuras de programación que deben dar un error." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:624 +#: pl_scanner.c:508 #, c-format msgid "%s at end of input" msgstr "%s al final de la entrada" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:640 +#: pl_scanner.c:524 #, c-format msgid "%s at or near \"%s\"" msgstr "%s en o cerca de «%s»" - -#~ msgid "label does not exist" -#~ msgstr "la etiqueta no existe" diff --git a/src/pl/plpgsql/src/po/fr.po b/src/pl/plpgsql/src/po/fr.po index 485bf36a545..36c7812ee22 100644 --- a/src/pl/plpgsql/src/po/fr.po +++ b/src/pl/plpgsql/src/po/fr.po @@ -6,10 +6,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-05-09 08:37+0000\n" -"PO-Revision-Date: 2016-05-09 10:53+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:08+0000\n" +"PO-Revision-Date: 2019-05-17 14:59+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" @@ -17,157 +17,160 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.2.1\n" -#: pl_comp.c:432 pl_handler.c:448 +#: pl_comp.c:436 pl_handler.c:461 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "les fonctions PL/pgsql ne peuvent pas accepter le type %s" -#: pl_comp.c:513 +#: pl_comp.c:524 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "" "n'a pas pu déterminer le type de retour actuel pour la fonction\n" "polymorphique « %s »" -#: pl_comp.c:543 +#: pl_comp.c:554 #, c-format msgid "trigger functions can only be called as triggers" -msgstr "les fonctions triggers peuvent seulement être appelées par des triggers" +msgstr "" +"les fonctions triggers peuvent seulement être appelées par des triggers" -#: pl_comp.c:547 pl_handler.c:433 +#: pl_comp.c:558 pl_handler.c:445 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "les fonctions PL/pgsql ne peuvent pas renvoyer le type %s" -#: pl_comp.c:588 +#: pl_comp.c:597 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "les fonctions triggers ne peuvent pas avoir des arguments déclarés" -#: pl_comp.c:589 +#: pl_comp.c:598 #, c-format -msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." +msgid "" +"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " +"instead." msgstr "" "Les arguments du trigger peuvent être accédés via TG_NARGS et TG_ARGV à\n" "la place." -#: pl_comp.c:691 +#: pl_comp.c:721 #, c-format msgid "event trigger functions cannot have declared arguments" -msgstr "les fonctions triggers sur événement ne peuvent pas avoir des arguments déclarés" +msgstr "" +"les fonctions triggers sur événement ne peuvent pas avoir des arguments " +"déclarés" -#: pl_comp.c:944 +#: pl_comp.c:980 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "compilation de la fonction PL/pgsql « %s » près de la ligne %d" -#: pl_comp.c:967 +#: pl_comp.c:1003 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "le nom du paramètre « %s » est utilisé plus d'une fois" -#: pl_comp.c:1077 +#: pl_comp.c:1115 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "la référence à la colonne « %s » est ambigu" -#: pl_comp.c:1079 +#: pl_comp.c:1117 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "" "Cela pourrait faire référence à une variable PL/pgsql ou à la colonne d'une\n" "table." -#: pl_comp.c:1259 pl_comp.c:1287 pl_exec.c:4395 pl_exec.c:4744 pl_exec.c:4829 -#: pl_exec.c:4920 +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "l'enregistrement « %s » n'a pas de champs « %s »" -#: pl_comp.c:1818 +#: pl_comp.c:1765 #, c-format msgid "relation \"%s\" does not exist" msgstr "la relation « %s » n'existe pas" -#: pl_comp.c:1927 +#: pl_comp.c:1857 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "la variable « %s » a le pseudo-type %s" -#: pl_comp.c:1994 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "la relation « %s » n'est pas une table" - -#: pl_comp.c:2154 +#: pl_comp.c:2037 #, c-format msgid "type \"%s\" is only a shell" msgstr "le type « %s » est seulement un shell" -#: pl_comp.c:2243 pl_comp.c:2296 +#: pl_comp.c:2134 pl_comp.c:2187 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "condition d'exception non reconnue « %s »" -#: pl_comp.c:2503 +#: pl_comp.c:2401 #, c-format -msgid "could not determine actual argument type for polymorphic function \"%s\"" +msgid "" +"could not determine actual argument type for polymorphic function \"%s\"" msgstr "" "n'a pas pu déterminer le type d'argument actuel pour la fonction\n" "polymorphique « %s »" -#: pl_exec.c:324 pl_exec.c:612 pl_exec.c:872 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 msgid "during initialization of execution state" msgstr "durant l'initialisation de l'état de la fonction" -#: pl_exec.c:331 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "lors du stockage des arguments dans les variables locales" -#: pl_exec.c:416 pl_exec.c:760 +#: pl_exec.c:569 pl_exec.c:960 msgid "during function entry" msgstr "durant l'entrée d'une fonction" -#: pl_exec.c:441 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "le contrôle a atteint la fin de la fonction sans RETURN" -#: pl_exec.c:448 +#: pl_exec.c:601 msgid "while casting return value to function's return type" -msgstr "lors de la conversion de la valeur de retour au type de retour de la fonction" +msgstr "" +"lors de la conversion de la valeur de retour au type de retour de la fonction" -#: pl_exec.c:461 pl_exec.c:2938 +#: pl_exec.c:614 pl_exec.c:3556 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "fonction renvoyant un ensemble appelée dans un contexte qui ne peut pas\n" "accepter un ensemble" -#: pl_exec.c:499 pl_exec.c:2779 +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 +msgid "during function exit" +msgstr "lors de la sortie de la fonction" + +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 msgid "returned record type does not match expected record type" msgstr "" "le type d'enregistrement renvoyé ne correspond pas au type d'enregistrement\n" "attendu" -#: pl_exec.c:554 pl_exec.c:789 pl_exec.c:907 -msgid "during function exit" -msgstr "lors de la sortie de la fonction" - -#: pl_exec.c:785 pl_exec.c:903 +#: pl_exec.c:985 pl_exec.c:1146 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "le contrôle a atteint la fin de la procédure trigger sans RETURN" -#: pl_exec.c:794 +#: pl_exec.c:994 #, c-format msgid "trigger procedure cannot return a set" msgstr "la procédure trigger ne peut pas renvoyer un ensemble" -#: pl_exec.c:816 -msgid "returned row structure does not match the structure of the triggering table" +#: pl_exec.c:1033 pl_exec.c:1061 +msgid "" +"returned row structure does not match the structure of the triggering table" msgstr "" "la structure de ligne renvoyée ne correspond pas à la structure de la table\n" "du trigger" @@ -175,7 +178,7 @@ msgstr "" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:954 +#: pl_exec.c:1198 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "fonction PL/pgsql %s, ligne %d, %s" @@ -183,373 +186,431 @@ msgstr "fonction PL/pgsql %s, ligne %d, %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:965 +#: pl_exec.c:1209 #, c-format msgid "PL/pgSQL function %s %s" msgstr "fonction PL/pgsql %s, %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:973 +#: pl_exec.c:1217 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "fonction PL/pgsql %s, ligne %d à %s" -#: pl_exec.c:979 +#: pl_exec.c:1223 #, c-format msgid "PL/pgSQL function %s" msgstr "fonction PL/pgsql %s" -#: pl_exec.c:1089 +#: pl_exec.c:1561 msgid "during statement block local variable initialization" msgstr "lors de l'initialisation de variables locales du bloc d'instructions" -#: pl_exec.c:1128 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "la variable « %s » déclarée NOT NULL ne peut pas valoir NULL par défaut" - -#: pl_exec.c:1178 +#: pl_exec.c:1659 msgid "during statement block entry" msgstr "lors de l'entrée dans le bloc d'instructions" -#: pl_exec.c:1199 +#: pl_exec.c:1691 msgid "during statement block exit" msgstr "lors de la sortie du bloc d'instructions" -#: pl_exec.c:1242 +#: pl_exec.c:1729 msgid "during exception cleanup" msgstr "lors du nettoyage de l'exception" -#: pl_exec.c:1593 +#: pl_exec.c:2225 +#, c-format +msgid "" +"procedure parameter \"%s\" is an output parameter but corresponding argument " +"is not writable" +msgstr "" +"le paramètre de la procédure « %s » est un argument en sortie mais " +"l'argument correspondant n'est pas modifiable" + +#: pl_exec.c:2230 +#, c-format +msgid "" +"procedure parameter %d is an output parameter but corresponding argument is " +"not writable" +msgstr "" +"le paramètre de la procédure %d est un paramètre en sortie mais l'argument " +"correspondant n'est pas modifiable" + +#: pl_exec.c:2341 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "" -"GET STACKED DIAGNOSTICS ne peut pas être utilisé à l'extérieur d'un gestionnaire\n" +"GET STACKED DIAGNOSTICS ne peut pas être utilisé à l'extérieur d'un " +"gestionnaire\n" "d'exception" -#: pl_exec.c:1789 +#: pl_exec.c:2540 #, c-format msgid "case not found" msgstr "case introuvable" -#: pl_exec.c:1790 +#: pl_exec.c:2541 #, c-format msgid "CASE statement is missing ELSE part." msgstr "l'instruction CASE n'a pas la partie ELSE." -#: pl_exec.c:1944 +#: pl_exec.c:2634 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "la limite inférieure de la boucle FOR ne peut pas être NULL" -#: pl_exec.c:1960 +#: pl_exec.c:2650 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "la limite supérieure de la boucle FOR ne peut pas être NULL" -#: pl_exec.c:1978 +#: pl_exec.c:2668 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "la valeur BY d'une boucle FOR ne peut pas être NULL" -#: pl_exec.c:1984 +#: pl_exec.c:2674 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "la valeur BY d'une boucle FOR doit être plus grande que zéro" -#: pl_exec.c:2153 pl_exec.c:3912 +#: pl_exec.c:2808 pl_exec.c:4530 #, c-format msgid "cursor \"%s\" already in use" msgstr "curseur « %s » déjà en cours d'utilisation" -#: pl_exec.c:2176 pl_exec.c:3974 +#: pl_exec.c:2831 pl_exec.c:4595 #, c-format msgid "arguments given for cursor without arguments" msgstr "arguments donnés pour le curseur sans arguments" -#: pl_exec.c:2195 pl_exec.c:3993 +#: pl_exec.c:2850 pl_exec.c:4614 #, c-format msgid "arguments required for cursor" msgstr "arguments requis pour le curseur" -#: pl_exec.c:2280 +#: pl_exec.c:2937 #, c-format msgid "FOREACH expression must not be null" msgstr "l'expression FOREACH ne doit pas être NULL" -#: pl_exec.c:2286 +#: pl_exec.c:2952 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "l'expression FOREACH doit renvoyer un tableau, pas un type %s" -#: pl_exec.c:2303 +#: pl_exec.c:2969 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" -msgstr "la dimension de la partie (%d) est en dehors des valeurs valides (0..%d)" +msgstr "" +"la dimension de la partie (%d) est en dehors des valeurs valides (0..%d)" -#: pl_exec.c:2330 +#: pl_exec.c:2996 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "la variable d'une boucle FOREACH ... SLICE doit être d'un type tableau" -#: pl_exec.c:2334 +#: pl_exec.c:3000 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "la valeur d'une boucle FOREACH ne doit pas être de type tableau" -#: pl_exec.c:2522 pl_exec.c:2604 pl_exec.c:2771 +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 #, c-format -msgid "cannot return non-composite value from function returning composite type" -msgstr "ne peut pas renvoyer de valeurs non composites à partir d'une fonction renvoyant un type composite" +msgid "" +"cannot return non-composite value from function returning composite type" +msgstr "" +"ne peut pas renvoyer de valeurs non composites à partir d'une fonction " +"renvoyant un type composite" -#: pl_exec.c:2648 pl_gram.y:3161 +#: pl_exec.c:3258 pl_gram.y:3305 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "ne peut pas utiliser RETURN NEXT dans une fonction non SETOF" -#: pl_exec.c:2682 pl_exec.c:2813 +#: pl_exec.c:3299 pl_exec.c:3431 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "mauvais type de résultat fourni dans RETURN NEXT" -#: pl_exec.c:2711 pl_exec.c:4382 pl_exec.c:4711 pl_exec.c:4737 pl_exec.c:4803 -#: pl_exec.c:4822 pl_exec.c:4890 pl_exec.c:4913 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "l'enregistrement « %s » n'est pas encore affectée" - -#: pl_exec.c:2713 pl_exec.c:4384 pl_exec.c:4713 pl_exec.c:4739 pl_exec.c:4805 -#: pl_exec.c:4824 pl_exec.c:4892 pl_exec.c:4915 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "La structure de ligne d'un enregistrement pas encore affecté est indéterminée." - -#: pl_exec.c:2717 pl_exec.c:2737 +#: pl_exec.c:3337 pl_exec.c:3358 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "mauvais type d'enregistrement fourni à RETURN NEXT" -#: pl_exec.c:2832 +#: pl_exec.c:3450 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT doit avoir un paramètre" -#: pl_exec.c:2865 pl_gram.y:3223 +#: pl_exec.c:3476 pl_gram.y:3369 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "ne peut pas utiliser RETURN QUERY dans une fonction non SETOF" -#: pl_exec.c:2886 +#: pl_exec.c:3500 msgid "structure of query does not match function result type" -msgstr "la structure de la requête ne correspond pas au type de résultat de la fonction" +msgstr "" +"la structure de la requête ne correspond pas au type de résultat de la " +"fonction" -#: pl_exec.c:2966 pl_exec.c:3096 +#: pl_exec.c:3584 pl_exec.c:3722 #, c-format msgid "RAISE option already specified: %s" msgstr "option RAISE déjà spécifiée : %s" -#: pl_exec.c:2999 +#: pl_exec.c:3618 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "" "RAISE sans paramètre ne peut pas être utilisé sans un gestionnaire\n" "d'exception" -#: pl_exec.c:3086 +#: pl_exec.c:3712 #, c-format msgid "RAISE statement option cannot be null" msgstr "l'option de l'instruction RAISE ne peut pas être NULL" -#: pl_exec.c:3155 +#: pl_exec.c:3782 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3226 +#: pl_exec.c:3837 #, c-format msgid "assertion failed" msgstr "échec de l'assertion" -#: pl_exec.c:3418 pl_exec.c:3562 pl_exec.c:3751 +#: pl_exec.c:4179 pl_exec.c:4369 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "ne peut pas utiliser COPY TO/FROM dans PL/pgsql" -#: pl_exec.c:3422 pl_exec.c:3566 pl_exec.c:3755 +#: pl_exec.c:4185 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "ne peut pas utiliser les instructions BEGIN/END de transactions dans PL/pgsql" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "commande de transaction non supportée dans PL/pgSQL" -#: pl_exec.c:3423 pl_exec.c:3567 pl_exec.c:3756 -#, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Utiliser un bloc BEGIN dans une clause EXCEPTION à la place." - -#: pl_exec.c:3590 pl_exec.c:3780 +#: pl_exec.c:4208 pl_exec.c:4398 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO utilisé dans une commande qui ne peut pas envoyer de données" -#: pl_exec.c:3618 pl_exec.c:3808 +#: pl_exec.c:4231 pl_exec.c:4421 #, c-format msgid "query returned no rows" msgstr "la requête n'a renvoyé aucune ligne" -#: pl_exec.c:3637 pl_exec.c:3827 +#: pl_exec.c:4253 pl_exec.c:4440 #, c-format msgid "query returned more than one row" msgstr "la requête a renvoyé plus d'une ligne" -#: pl_exec.c:3654 +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "" +"Assurez-vous que la requête ne renvoie qu'une seule ligne ou utilisez LIMIT " +"1." + +#: pl_exec.c:4271 #, c-format msgid "query has no destination for result data" msgstr "la requête n'a pas de destination pour les données résultantes" -#: pl_exec.c:3655 +#: pl_exec.c:4272 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." -msgstr "Si vous voulez annuler les résultats d'un SELECT, utilisez PERFORM à la place." +msgstr "" +"Si vous voulez annuler les résultats d'un SELECT, utilisez PERFORM à la " +"place." -#: pl_exec.c:3687 pl_exec.c:7128 +#: pl_exec.c:4305 pl_exec.c:8416 #, c-format msgid "query string argument of EXECUTE is null" msgstr "l'argument de la requête de EXECUTE est NULL" -#: pl_exec.c:3743 +#: pl_exec.c:4361 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "EXECUTE de SELECT ... INTO n'est pas implanté" -#: pl_exec.c:3744 +#: pl_exec.c:4362 +#, c-format +msgid "" +"You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " +"instead." +msgstr "" +"Vous pouvez aussi utiliser EXECUTE ... INTO ou EXECUTE CREATE TABLE ... AS à " +"la place." + +#: pl_exec.c:4375 #, c-format -msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." -msgstr "Vous pouvez aussi utiliser EXECUTE ... INTO ou EXECUTE CREATE TABLE ... AS à la place." +msgid "EXECUTE of transaction commands is not implemented" +msgstr "l'exécution de commandes de transactions n'est pas implémentée" -#: pl_exec.c:4056 pl_exec.c:4148 +#: pl_exec.c:4676 pl_exec.c:4764 #, c-format msgid "cursor variable \"%s\" is null" msgstr "la variable du curseur « %s » est NULL" -#: pl_exec.c:4063 pl_exec.c:4155 +#: pl_exec.c:4687 pl_exec.c:4775 #, c-format msgid "cursor \"%s\" does not exist" msgstr "le curseur « %s » n'existe pas" -#: pl_exec.c:4077 +#: pl_exec.c:4700 #, c-format msgid "relative or absolute cursor position is null" msgstr "la position relative ou absolue du curseur est NULL" -#: pl_exec.c:4257 +#: pl_exec.c:4956 pl_exec.c:5051 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "" "une valeur NULL ne peut pas être affectée à la variable « %s » déclarée\n" "non NULL" -#: pl_exec.c:4326 +#: pl_exec.c:5032 #, c-format msgid "cannot assign non-composite value to a row variable" -msgstr "ne peut pas affecter une valeur non composite à une variable de type ROW" +msgstr "" +"ne peut pas affecter une valeur non composite à une variable de type ROW" -#: pl_exec.c:4350 +#: pl_exec.c:5064 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "ne peut pas affecter une valeur non composite à une variable RECORD" -#: pl_exec.c:4493 +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "ne peut pas affecter à une colonne système « %s »" + +#: pl_exec.c:5179 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "le nombre de dimensions du tableau (%d) dépasse la maximum autorisé (%d)" +msgstr "" +"le nombre de dimensions du tableau (%d) dépasse la maximum autorisé (%d)" -#: pl_exec.c:4525 +#: pl_exec.c:5211 #, c-format msgid "subscripted object is not an array" msgstr "l'objet souscrit n'est pas un tableau" -#: pl_exec.c:4562 +#: pl_exec.c:5249 #, c-format msgid "array subscript in assignment must not be null" msgstr "un indice de tableau dans une affectation ne peut pas être NULL" -#: pl_exec.c:5029 +#: pl_exec.c:5756 #, c-format msgid "query \"%s\" did not return data" msgstr "la requête « %s » ne renvoie pas de données" -#: pl_exec.c:5037 +#: pl_exec.c:5764 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "la requête « %s » a renvoyé %d colonne" msgstr[1] "la requête « %s » a renvoyé %d colonnes" -#: pl_exec.c:5064 +#: pl_exec.c:5792 #, c-format msgid "query \"%s\" returned more than one row" msgstr "la requête « %s » a renvoyé plus d'une ligne" -#: pl_exec.c:5128 +#: pl_exec.c:5855 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "la requête « %s » n'est pas un SELECT" -#: pl_funcs.c:237 +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "" +"le type de paramètre %d (%s) ne correspond pas à ce qui est préparé dans le " +"plan (%s)" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment does not match" +msgstr "" +"le nombre de champs source et celui de champs cible dans l'affectation ne " +"correspondent pas" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "%s vérification de %s est active." + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "Assurez-vous que la requête renvoie la liste exacte de colonnes." + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "l'enregistrement « %s » n'est pas encore affectée" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "" +"La structure de ligne d'un enregistrement pas encore affecté est " +"indéterminée." + +#: pl_funcs.c:239 msgid "statement block" msgstr "bloc d'instructions" -#: pl_funcs.c:239 +#: pl_funcs.c:241 msgid "assignment" msgstr "affectation" -#: pl_funcs.c:249 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "variable entière de boucle FOR" -#: pl_funcs.c:251 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "FOR sur des lignes de SELECT" -#: pl_funcs.c:253 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "FOR sur un curseur" -#: pl_funcs.c:255 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "FOREACH sur un tableau" -#: pl_funcs.c:269 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "instruction SQL" -#: pl_funcs.c:273 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "FOR sur une instruction EXECUTE" -#: pl_gram.y:473 +#: pl_gram.y:489 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "le label du bloc doit être placé avant DECLARE, et non pas après" -#: pl_gram.y:493 +#: pl_gram.y:509 #, c-format msgid "collations are not supported by type %s" msgstr "les collationnements ne sont pas supportés par le type %s" -#: pl_gram.y:508 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "la variable ROW ou RECORD ne peut pas être CONSTANT" - -#: pl_gram.y:518 +#: pl_gram.y:528 #, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "la variable ROW ou RECORD ne peut pas être NOT NULL" - -#: pl_gram.y:529 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "la valeur par défaut de variable ROW ou RECORD n'est pas supportée" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "" +"la variable « %s » doit avoir une valeur par défaut car elle est déclarée " +"NOT NULL" #: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 #, c-format @@ -565,399 +626,469 @@ msgstr "déclaration dupliquée" msgid "variable \"%s\" shadows a previously defined variable" msgstr "la variable « %s » cache une variable définie précédemment" -#: pl_gram.y:951 +#: pl_gram.y:992 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" -msgstr "l'élément %s de diagnostique l'est pas autorisé dans GET STACKED DIAGNOSTICS" +msgstr "" +"l'élément %s de diagnostique l'est pas autorisé dans GET STACKED DIAGNOSTICS" -#: pl_gram.y:969 +#: pl_gram.y:1010 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" -msgstr "l'élément %s de diagnostique l'est pas autorisé dans GET CURRENT DIAGNOSTICS" +msgstr "" +"l'élément %s de diagnostique l'est pas autorisé dans GET CURRENT DIAGNOSTICS" -#: pl_gram.y:1067 +#: pl_gram.y:1105 msgid "unrecognized GET DIAGNOSTICS item" msgstr "élément GET DIAGNOSTICS non reconnu" -#: pl_gram.y:1078 pl_gram.y:3410 +#: pl_gram.y:1115 pl_gram.y:3549 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "« %s » n'est pas une variable scalaire" -#: pl_gram.y:1330 pl_gram.y:1524 +#: pl_gram.y:1369 pl_gram.y:1565 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" +msgid "" +"loop variable of loop over rows must be a record variable or list of scalar " +"variables" msgstr "" "la variable d'une boucle sur des lignes doit être une variable de type\n" -"RECORD ou ROW, ou encore une liste de variables scalaires" +"record ou une liste de variables scalaires" -#: pl_gram.y:1364 +#: pl_gram.y:1404 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "le curseur de la boucle FOR doit avoir seulement une variable cible" -#: pl_gram.y:1371 +#: pl_gram.y:1411 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "le curseur de la boucle FOR doit utiliser une variable curseur limité" -#: pl_gram.y:1455 +#: pl_gram.y:1498 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "la boucle FOR de type entier doit avoir une seule variable cible" -#: pl_gram.y:1491 +#: pl_gram.y:1535 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "ne peut pas spécifier REVERSE dans la requête de la boucle FOR" -#: pl_gram.y:1638 +#: pl_gram.y:1668 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" -msgstr "la variable d'une boucle FOREACH doit être une variable connue ou une liste de variables" +msgstr "" +"la variable d'une boucle FOREACH doit être une variable connue ou une liste " +"de variables" -#: pl_gram.y:1679 +#: pl_gram.y:1710 #, c-format -msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" -msgstr "il n'existe pas de label « %s » attaché à un bloc ou à une boucle englobant cette instruction" +msgid "" +"there is no label \"%s\" attached to any block or loop enclosing this " +"statement" +msgstr "" +"il n'existe pas de label « %s » attaché à un bloc ou à une boucle englobant " +"cette instruction" -#: pl_gram.y:1687 +#: pl_gram.y:1718 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" -msgstr "le label de bloc « %s » ne peut pas être utilisé avec l'instruction CONTINUE" +msgstr "" +"le label de bloc « %s » ne peut pas être utilisé avec l'instruction CONTINUE" -#: pl_gram.y:1702 +#: pl_gram.y:1733 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" -msgstr "EXIT ne peut pas être utilisé à l'extérieur d'une boucle, sauf s'il a un label" +msgstr "" +"EXIT ne peut pas être utilisé à l'extérieur d'une boucle, sauf s'il a un " +"label" -#: pl_gram.y:1703 +#: pl_gram.y:1734 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE ne peut pas être utilisé à l'extérieur d'une boucle" -#: pl_gram.y:1727 pl_gram.y:1764 pl_gram.y:1812 pl_gram.y:2863 pl_gram.y:2945 -#: pl_gram.y:3056 pl_gram.y:3812 +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 msgid "unexpected end of function definition" msgstr "définition inattendue de la fin de fonction" -#: pl_gram.y:1832 pl_gram.y:1856 pl_gram.y:1872 pl_gram.y:1878 pl_gram.y:1992 -#: pl_gram.y:2000 pl_gram.y:2014 pl_gram.y:2109 pl_gram.y:2290 pl_gram.y:2384 -#: pl_gram.y:2535 pl_gram.y:3653 pl_gram.y:3714 pl_gram.y:3793 +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 msgid "syntax error" msgstr "erreur de syntaxe" -#: pl_gram.y:1860 pl_gram.y:1862 pl_gram.y:2294 pl_gram.y:2296 +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 msgid "invalid SQLSTATE code" msgstr "code SQLSTATE invalide" -#: pl_gram.y:2056 +#: pl_gram.y:2094 msgid "syntax error, expected \"FOR\"" msgstr "erreur de syntaxe, « FOR » attendu" -#: pl_gram.y:2118 +#: pl_gram.y:2155 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "l'instruction FETCH ne peut pas renvoyer plusieurs lignes" -#: pl_gram.y:2174 +#: pl_gram.y:2279 #, c-format msgid "cursor variable must be a simple variable" msgstr "la variable de curseur doit être une variable simple" -#: pl_gram.y:2180 +#: pl_gram.y:2285 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "la variable « %s » doit être de type cursor ou refcursor" -#: pl_gram.y:2506 pl_gram.y:2517 +#: pl_gram.y:2619 pl_gram.y:2630 #, c-format msgid "\"%s\" is not a known variable" msgstr "« %s » n'est pas une variable connue" -#: pl_gram.y:2621 pl_gram.y:2631 pl_gram.y:2787 +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 msgid "mismatched parentheses" msgstr "parenthèses non correspondantes" -#: pl_gram.y:2635 +#: pl_gram.y:2748 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "« %s » manquant à la fin de l'expression SQL" -#: pl_gram.y:2641 +#: pl_gram.y:2754 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "« %s » manquant à la fin de l'instruction SQL" -#: pl_gram.y:2658 +#: pl_gram.y:2771 msgid "missing expression" msgstr "expression manquante" -#: pl_gram.y:2660 +#: pl_gram.y:2773 msgid "missing SQL statement" msgstr "instruction SQL manquante" -#: pl_gram.y:2789 +#: pl_gram.y:2901 msgid "incomplete data type declaration" msgstr "déclaration incomplète d'un type de données" -#: pl_gram.y:2812 +#: pl_gram.y:2924 msgid "missing data type declaration" msgstr "déclaration manquante d'un type de données" -#: pl_gram.y:2868 +#: pl_gram.y:3002 msgid "INTO specified more than once" msgstr "INTO spécifié plus d'une fois" -#: pl_gram.y:3037 +#: pl_gram.y:3171 msgid "expected FROM or IN" msgstr "attendait FROM ou IN" -#: pl_gram.y:3097 +#: pl_gram.y:3232 #, c-format msgid "RETURN cannot have a parameter in function returning set" -msgstr "RETURN ne peut pas avoir un paramètre dans une fonction renvoyant un ensemble" +msgstr "" +"RETURN ne peut pas avoir un paramètre dans une fonction renvoyant un ensemble" -#: pl_gram.y:3098 +#: pl_gram.y:3233 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Utilisez RETURN NEXT ou RETURN QUERY." -#: pl_gram.y:3106 +#: pl_gram.y:3243 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN ne peut pas avoir un paramètre dans une fonction avec des paramètres OUT" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN ne peut pas avoir un paramètre dans une procédure" -#: pl_gram.y:3115 +#: pl_gram.y:3248 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURN ne peut pas avoir un paramètre dans une fonction renvoyant void" -#: pl_gram.y:3175 +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "" +"RETURN ne peut pas avoir un paramètre dans une fonction avec des paramètres " +"OUT" + +#: pl_gram.y:3320 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "" "RETURN NEXT ne peut pas avoir un paramètre dans une fonction avec des\n" "paramètres OUT" -#: pl_gram.y:3279 +#: pl_gram.y:3428 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "« %s » est déclaré CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "la variable « %s » est déclarée CONSTANT" -#: pl_gram.y:3341 pl_gram.y:3353 +#: pl_gram.y:3491 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" +msgid "record variable cannot be part of multiple-item INTO list" msgstr "" -"la variable de type RECORD ou ROW ne peut pas faire partie d'une liste INTO à\n" +"la variable de type record ne peut pas faire partie d'une liste INTO à\n" "plusieurs éléments" -#: pl_gram.y:3398 +#: pl_gram.y:3537 #, c-format msgid "too many INTO variables specified" msgstr "trop de variables INTO indiquées" -#: pl_gram.y:3606 +#: pl_gram.y:3745 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "label de fin « %s » spécifié pour un bloc sans label" -#: pl_gram.y:3613 +#: pl_gram.y:3752 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "label de fin « %s » différent du label « %s » du bloc" -#: pl_gram.y:3648 +#: pl_gram.y:3787 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "le curseur « %s » n'a pas d'arguments" -#: pl_gram.y:3662 +#: pl_gram.y:3801 #, c-format msgid "cursor \"%s\" has arguments" msgstr "le curseur « %s » a des arguments" -#: pl_gram.y:3704 +#: pl_gram.y:3843 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "le curseur « %s » n'a pas d'argument nommé « %s »" -#: pl_gram.y:3724 +#: pl_gram.y:3863 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" -msgstr "la valeur du paramètre « %s » pour le curseur « %s » est spécifiée plus d'une fois" +msgstr "" +"la valeur du paramètre « %s » pour le curseur « %s » est spécifiée plus " +"d'une fois" -#: pl_gram.y:3749 +#: pl_gram.y:3888 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "pas assez d'arguments pour le curseur « %s »" -#: pl_gram.y:3756 +#: pl_gram.y:3895 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "trop d'arguments pour le curseur « %s »" -#: pl_gram.y:3844 +#: pl_gram.y:3982 msgid "unrecognized RAISE statement option" msgstr "option de l'instruction RAISE inconnue" -#: pl_gram.y:3848 +#: pl_gram.y:3986 msgid "syntax error, expected \"=\"" msgstr "erreur de syntaxe, « = » attendu" -#: pl_gram.y:3889 +#: pl_gram.y:4027 #, c-format msgid "too many parameters specified for RAISE" msgstr "trop de paramètres pour RAISE" -#: pl_gram.y:3893 +#: pl_gram.y:4031 #, c-format msgid "too few parameters specified for RAISE" msgstr "trop peu de paramètres pour RAISE" -#: pl_handler.c:149 -msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." -msgstr "Configure la gestion des conflits entre les noms de variables PL/pgsql et les noms des colonnes des tables." - #: pl_handler.c:158 -msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." -msgstr "Affiche des informations sur les paramètres dans la partie DETAIL des messages d'erreur générés pour des échecs INTO .. STRICT." +msgid "" +"Sets handling of conflicts between PL/pgSQL variable names and table column " +"names." +msgstr "" +"Configure la gestion des conflits entre les noms de variables PL/pgsql et " +"les noms des colonnes des tables." -#: pl_handler.c:166 +#: pl_handler.c:167 +msgid "" +"Print information about parameters in the DETAIL part of the error messages " +"generated on INTO ... STRICT failures." +msgstr "" +"Affiche des informations sur les paramètres dans la partie DETAIL des " +"messages d'erreur générés pour des échecs INTO .. STRICT." + +#: pl_handler.c:175 msgid "Perform checks given in ASSERT statements." msgstr "Réalise les vérifications données dans les instructions ASSERT." -#: pl_handler.c:174 +#: pl_handler.c:183 msgid "List of programming constructs that should produce a warning." -msgstr "Liste des constructions de programmation qui devraient produire un message d'avertissement." +msgstr "" +"Liste des constructions de programmation qui devraient produire un message " +"d'avertissement." -#: pl_handler.c:184 +#: pl_handler.c:193 msgid "List of programming constructs that should produce an error." -msgstr "Liste des constructions de programmation qui devraient produire une erreur." +msgstr "" +"Liste des constructions de programmation qui devraient produire une erreur." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:621 +#: pl_scanner.c:508 #, c-format msgid "%s at end of input" msgstr "%s à la fin de l'entrée" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:637 +#: pl_scanner.c:524 #, c-format msgid "%s at or near \"%s\"" msgstr "%s sur ou près de « %s »" -#~ msgid "EXECUTE statement" -#~ msgstr "instruction EXECUTE" +#~ msgid "label does not exist" +#~ msgstr "le label n'existe pas" -#~ msgid "relation \"%s.%s\" does not exist" -#~ msgstr "la relation « %s.%s » n'existe pas" +#~ msgid "" +#~ "RETURN must specify a record or row variable in function returning row" +#~ msgstr "" +#~ "RETURN ne peut pas indiquer une variable RECORD ou ROW dans une fonction\n" +#~ "renvoyant une ligne" -#~ msgid "cursor \"%s\" closed unexpectedly" -#~ msgstr "le curseur « %s » a été fermé de façon inattendu" +#~ msgid "" +#~ "RETURN NEXT must specify a record or row variable in function returning " +#~ "row" +#~ msgstr "" +#~ "RETURN NEXT doit indiquer une variable RECORD ou ROW dans une fonction\n" +#~ "renvoyant une ligne" -#~ msgid "row \"%s\" has no field \"%s\"" -#~ msgstr "la ligne « %s » n'a aucun champ « %s »" +#~ msgid "unterminated dollar-quoted string" +#~ msgstr "chaîne entre dollars non terminée" -#~ msgid "row \"%s.%s\" has no field \"%s\"" -#~ msgstr "la ligne « %s.%s » n'a aucun champ « %s »" +#~ msgid "unterminated quoted string" +#~ msgstr "chaîne entre guillemets non terminée" -#~ msgid "expected \"[\"" -#~ msgstr "« [ » attendu" +#~ msgid "unterminated /* comment" +#~ msgstr "commentaire /* non terminé" -#~ msgid "type of \"%s\" does not match that when preparing the plan" -#~ msgstr "le type de « %s » ne correspond pas à ce qui est préparé dans le plan" +#~ msgid "unterminated quoted identifier" +#~ msgstr "identifiant entre guillemets non terminé" -#~ msgid "type of \"%s.%s\" does not match that when preparing the plan" -#~ msgstr "le type de « %s.%s » ne correspond pas à ce qui est préparé dans le plan" +#~ msgid "qualified identifier cannot be used here: %s" +#~ msgstr "l'identifiant qualifié ne peut pas être utilisé ici : %s" -#~ msgid "type of tg_argv[%d] does not match that when preparing the plan" -#~ msgstr "le type de tg_argv[%d] ne correspond pas à ce qui est préparé dans le plan" +#~ msgid "unterminated \" in identifier: %s" +#~ msgstr "\" non terminé dans l'identifiant : %s" -#~ msgid "N/A (dropped column)" -#~ msgstr "N/A (colonne supprimée)" +#~ msgid "variable \"%s\" does not exist in the current block" +#~ msgstr "la variable « %s » n'existe pas dans le bloc actuel" -#~ msgid "Number of returned columns (%d) does not match expected column count (%d)." +#~ msgid "expected \")\"" +#~ msgstr "« ) » attendu" + +#~ msgid "string literal in PL/PgSQL function \"%s\" near line %d" #~ msgstr "" -#~ "Le nombre de colonnes renvoyées (%d) ne correspond pas au nombre de colonnes\n" -#~ "attendues (%d)." +#~ "chaîne littérale dans la fonction PL/pgsql « %s » près de la ligne %d" -#~ msgid "Returned type %s does not match expected type %s in column \"%s\"." -#~ msgstr "Le type %s renvoyé ne correspond pas au type %s attendu dans la colonne « %s »." +#~ msgid "SQL statement in PL/PgSQL function \"%s\" near line %d" +#~ msgstr "" +#~ "instruction SQL dans la fonction PL/pgsql « %s » près de la ligne %d" -#~ msgid "only positional parameters can be aliased" -#~ msgstr "seuls les paramètres de position peuvent avoir un alias" +#~ msgid "" +#~ "Expected record variable, row variable, or list of scalar variables " +#~ "following INTO." +#~ msgstr "" +#~ "Attendait une variable RECORD, ROW ou une liste de variables scalaires\n" +#~ "suivant INTO." -#~ msgid "function has no parameter \"%s\"" -#~ msgstr "la fonction n'a pas de paramètre « %s »" +#~ msgid "cannot assign to tg_argv" +#~ msgstr "ne peut pas affecter à tg_argv" -#~ msgid "expected an integer variable" -#~ msgstr "attend une variable entière" +#~ msgid "" +#~ "RETURN cannot have a parameter in function returning set; use RETURN NEXT " +#~ "or RETURN QUERY" +#~ msgstr "" +#~ "RETURN ne peut pas avoir un paramètre dans une fonction renvoyant des\n" +#~ "lignes ; utilisez RETURN NEXT ou RETURN QUERY" + +#~ msgid "too many variables specified in SQL statement" +#~ msgstr "trop de variables spécifiées dans l'instruction SQL" + +#~ msgid "expected a cursor or refcursor variable" +#~ msgstr "attendait une variable de type cursor ou refcursor" + +#~ msgid "Expected \"FOR\", to open a cursor for an unbound cursor variable." +#~ msgstr "" +#~ "Attendait « FOR » pour ouvrir un curseur pour une variable sans limite." #~ msgid "syntax error at \"%s\"" #~ msgstr "erreur de syntaxe à « %s »" -#~ msgid "Expected \"FOR\", to open a cursor for an unbound cursor variable." -#~ msgstr "Attendait « FOR » pour ouvrir un curseur pour une variable sans limite." +#~ msgid "expected an integer variable" +#~ msgstr "attend une variable entière" -#~ msgid "expected a cursor or refcursor variable" -#~ msgstr "attendait une variable de type cursor ou refcursor" +#~ msgid "function has no parameter \"%s\"" +#~ msgstr "la fonction n'a pas de paramètre « %s »" -#~ msgid "too many variables specified in SQL statement" -#~ msgstr "trop de variables spécifiées dans l'instruction SQL" +#~ msgid "only positional parameters can be aliased" +#~ msgstr "seuls les paramètres de position peuvent avoir un alias" -#~ msgid "RETURN cannot have a parameter in function returning set; use RETURN NEXT or RETURN QUERY" +#~ msgid "Returned type %s does not match expected type %s in column \"%s\"." #~ msgstr "" -#~ "RETURN ne peut pas avoir un paramètre dans une fonction renvoyant des\n" -#~ "lignes ; utilisez RETURN NEXT ou RETURN QUERY" +#~ "Le type %s renvoyé ne correspond pas au type %s attendu dans la colonne « " +#~ "%s »." -#~ msgid "cannot assign to tg_argv" -#~ msgstr "ne peut pas affecter à tg_argv" +#~ msgid "" +#~ "Number of returned columns (%d) does not match expected column count (%d)." +#~ msgstr "" +#~ "Le nombre de colonnes renvoyées (%d) ne correspond pas au nombre de " +#~ "colonnes\n" +#~ "attendues (%d)." + +#~ msgid "N/A (dropped column)" +#~ msgstr "N/A (colonne supprimée)" -#~ msgid "Expected record variable, row variable, or list of scalar variables following INTO." +#~ msgid "type of tg_argv[%d] does not match that when preparing the plan" #~ msgstr "" -#~ "Attendait une variable RECORD, ROW ou une liste de variables scalaires\n" -#~ "suivant INTO." +#~ "le type de tg_argv[%d] ne correspond pas à ce qui est préparé dans le plan" -#~ msgid "SQL statement in PL/PgSQL function \"%s\" near line %d" -#~ msgstr "instruction SQL dans la fonction PL/pgsql « %s » près de la ligne %d" +#~ msgid "type of \"%s.%s\" does not match that when preparing the plan" +#~ msgstr "" +#~ "le type de « %s.%s » ne correspond pas à ce qui est préparé dans le plan" -#~ msgid "string literal in PL/PgSQL function \"%s\" near line %d" -#~ msgstr "chaîne littérale dans la fonction PL/pgsql « %s » près de la ligne %d" +#~ msgid "type of \"%s\" does not match that when preparing the plan" +#~ msgstr "" +#~ "le type de « %s » ne correspond pas à ce qui est préparé dans le plan" -#~ msgid "expected \")\"" -#~ msgstr "« ) » attendu" +#~ msgid "expected \"[\"" +#~ msgstr "« [ » attendu" -#~ msgid "variable \"%s\" does not exist in the current block" -#~ msgstr "la variable « %s » n'existe pas dans le bloc actuel" +#~ msgid "row \"%s.%s\" has no field \"%s\"" +#~ msgstr "la ligne « %s.%s » n'a aucun champ « %s »" -#~ msgid "unterminated \" in identifier: %s" -#~ msgstr "\" non terminé dans l'identifiant : %s" +#~ msgid "row \"%s\" has no field \"%s\"" +#~ msgstr "la ligne « %s » n'a aucun champ « %s »" -#~ msgid "qualified identifier cannot be used here: %s" -#~ msgstr "l'identifiant qualifié ne peut pas être utilisé ici : %s" +#~ msgid "cursor \"%s\" closed unexpectedly" +#~ msgstr "le curseur « %s » a été fermé de façon inattendu" -#~ msgid "unterminated quoted identifier" -#~ msgstr "identifiant entre guillemets non terminé" +#~ msgid "relation \"%s.%s\" does not exist" +#~ msgstr "la relation « %s.%s » n'existe pas" -#~ msgid "unterminated /* comment" -#~ msgstr "commentaire /* non terminé" +#~ msgid "EXECUTE statement" +#~ msgstr "instruction EXECUTE" -#~ msgid "unterminated quoted string" -#~ msgstr "chaîne entre guillemets non terminée" +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "la valeur par défaut de variable ROW ou RECORD n'est pas supportée" -#~ msgid "unterminated dollar-quoted string" -#~ msgstr "chaîne entre dollars non terminée" +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "la variable ROW ou RECORD ne peut pas être NOT NULL" -#~ msgid "RETURN NEXT must specify a record or row variable in function returning row" -#~ msgstr "" -#~ "RETURN NEXT doit indiquer une variable RECORD ou ROW dans une fonction\n" -#~ "renvoyant une ligne" +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "la variable ROW ou RECORD ne peut pas être CONSTANT" -#~ msgid "RETURN must specify a record or row variable in function returning row" +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "Utiliser un bloc BEGIN dans une clause EXCEPTION à la place." + +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" #~ msgstr "" -#~ "RETURN ne peut pas indiquer une variable RECORD ou ROW dans une fonction\n" -#~ "renvoyant une ligne" +#~ "la variable « %s » déclarée NOT NULL ne peut pas valoir NULL par défaut" -#~ msgid "label does not exist" -#~ msgstr "le label n'existe pas" +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "la relation « %s » n'est pas une table" diff --git a/src/pl/plpgsql/src/po/it.po b/src/pl/plpgsql/src/po/it.po index 9d47ac9cfe9..f32ae19e4f7 100644 --- a/src/pl/plpgsql/src/po/it.po +++ b/src/pl/plpgsql/src/po/it.po @@ -1,179 +1,172 @@ # -# Translation of plpgsql to Italian -# PostgreSQL Project +# plpgsql.po +# Italian message translation file for plpgsql # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Diego Cinelli -# * Daniele Varrazzo +# Daniele Varrazzo , 2012-2017. +# Diego Cinelli # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: plpgsql (PostgreSQL) 9.6\n" +"Project-Id-Version: plpgsql (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-17 00:07+0000\n" -"PO-Revision-Date: 2016-04-17 20:58+0100\n" +"POT-Creation-Date: 2018-10-08 14:08+0000\n" +"PO-Revision-Date: 2018-10-08 23:10+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Poedit-SourceCharset: utf-8\n" -"X-Generator: Poedit 1.5.4\n" +"X-Generator: Poedit 2.0.6\n" -#: pl_comp.c:432 pl_handler.c:448 +#: pl_comp.c:434 pl_handler.c:457 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "Le funzioni PL/pgSQL non accettano il tipo %s" -#: pl_comp.c:513 +#: pl_comp.c:522 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "determinazione del tipo di ritorno reale per la funzione polimorfa \"%s\" fallita" -#: pl_comp.c:543 +#: pl_comp.c:552 #, c-format msgid "trigger functions can only be called as triggers" msgstr "le funzioni trigger possono essere chiamate esclusivamente da trigger" -#: pl_comp.c:547 pl_handler.c:433 +#: pl_comp.c:556 pl_handler.c:441 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "Le funzioni PL/pgSQL non possono restituire un tipo %s" -#: pl_comp.c:588 +#: pl_comp.c:595 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "Le funzioni trigger non possono avere argomenti dichiarati" -#: pl_comp.c:589 +#: pl_comp.c:596 #, c-format msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "Gli argomenti del trigger possono essere acceduti tramite TG_NARGS e TG_ARGV invece." -#: pl_comp.c:691 +#: pl_comp.c:719 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "le funzioni trigger di evento non possono avere argomenti dichiarati" -#: pl_comp.c:944 +#: pl_comp.c:976 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "compilazione della funzione PL/pgSQL \"%s\" in prossimità della riga %d" -#: pl_comp.c:967 +#: pl_comp.c:999 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "il nome di parametro \"%s\" è usato più di una volta" -#: pl_comp.c:1077 +#: pl_comp.c:1109 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "il riferimento alla colonna \"%s\" è ambiguo" -#: pl_comp.c:1079 +#: pl_comp.c:1111 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "Può riferirsi o ad una variabile PL/pgSQL o ad una colonna di tabella." -#: pl_comp.c:1259 pl_comp.c:1287 pl_exec.c:4395 pl_exec.c:4744 pl_exec.c:4829 -#: pl_exec.c:4920 +#: pl_comp.c:1294 pl_exec.c:5049 pl_exec.c:5414 pl_exec.c:5501 pl_exec.c:5592 +#: pl_exec.c:6510 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "il record \"%s\" non ha un campo \"%s\"" -#: pl_comp.c:1818 +#: pl_comp.c:1756 #, c-format msgid "relation \"%s\" does not exist" msgstr "la relazione \"%s\" non esiste" -#: pl_comp.c:1927 +#: pl_comp.c:1848 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "la variabile \"%s\" ha lo pseudo-tipo %s" -#: pl_comp.c:1994 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "la relazione \"%s\" non è una tabella" - -#: pl_comp.c:2154 +#: pl_comp.c:2028 #, c-format msgid "type \"%s\" is only a shell" msgstr "il tipo \"%s\" non è completamente definito" -#: pl_comp.c:2243 pl_comp.c:2296 +#: pl_comp.c:2125 pl_comp.c:2178 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "condizione di eccezione \"%s\" sconosciuta" -#: pl_comp.c:2503 +#: pl_comp.c:2392 #, c-format msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "il tipo reale dell'argomento non è determinabile per la funzione polimorfa \"%s\"" -#: pl_exec.c:324 pl_exec.c:612 pl_exec.c:872 +#: pl_exec.c:474 pl_exec.c:886 pl_exec.c:1103 msgid "during initialization of execution state" msgstr "durante l'inizializzazione dello stato di esecuzione" -#: pl_exec.c:331 +#: pl_exec.c:480 msgid "while storing call arguments into local variables" msgstr "durante la memorizzazione degli argomenti di chiamata in variabili locali" -#: pl_exec.c:416 pl_exec.c:760 +#: pl_exec.c:568 pl_exec.c:938 msgid "during function entry" msgstr "durante l'ingresso nella funzione" -#: pl_exec.c:441 +#: pl_exec.c:593 #, c-format msgid "control reached end of function without RETURN" msgstr "il controllo ha raggiunto la fine di una funzione senza incontrare alcun RETURN" -#: pl_exec.c:448 +#: pl_exec.c:600 msgid "while casting return value to function's return type" msgstr "durante la conversione del valore da restituire nel tipo restituito della funzione" -#: pl_exec.c:461 pl_exec.c:2938 +#: pl_exec.c:613 pl_exec.c:3512 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "la funzione che restituisce insiemi è chiamata in un contesto che non può accettare un insieme" -#: pl_exec.c:499 pl_exec.c:2779 -msgid "returned record type does not match expected record type" -msgstr "il tipo del record restituito non coincide con quello atteso" - -#: pl_exec.c:554 pl_exec.c:789 pl_exec.c:907 +#: pl_exec.c:739 pl_exec.c:967 pl_exec.c:1128 msgid "during function exit" msgstr "durante l'uscita della funzione" -#: pl_exec.c:785 pl_exec.c:903 +#: pl_exec.c:794 pl_exec.c:833 pl_exec.c:3357 +msgid "returned record type does not match expected record type" +msgstr "il tipo del record restituito non coincide con quello atteso" + +#: pl_exec.c:963 pl_exec.c:1124 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "il controllo ha raggiunto la fine di una procedura trigger senza incontrare alcun RETURN" -#: pl_exec.c:794 +#: pl_exec.c:972 #, c-format msgid "trigger procedure cannot return a set" msgstr "la procedura trigger non può restituire un insieme" -#: pl_exec.c:816 +#: pl_exec.c:1011 pl_exec.c:1039 msgid "returned row structure does not match the structure of the triggering table" msgstr "la struttura della riga restituita non coincide con la struttura della tabella che ha generato il trigger" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:954 +#: pl_exec.c:1176 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "funzione PL/pgSQL %s riga %d %s" @@ -181,655 +174,658 @@ msgstr "funzione PL/pgSQL %s riga %d %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:965 +#: pl_exec.c:1187 #, c-format msgid "PL/pgSQL function %s %s" msgstr "funzione PL/pgSQL %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:973 +#: pl_exec.c:1195 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "funzione PL/pgSQL %s riga %d a %s" -#: pl_exec.c:979 +#: pl_exec.c:1201 #, c-format msgid "PL/pgSQL function %s" msgstr "funzione PL/pgSQL %s" -#: pl_exec.c:1089 +#: pl_exec.c:1539 msgid "during statement block local variable initialization" msgstr "durante l'inizializzazione di variabili locali del blocco di istruzioni" -#: pl_exec.c:1128 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "la variabile \"%s\" dichiarata NOT NULL non può avere valore predefinito NULL" - -#: pl_exec.c:1178 +#: pl_exec.c:1637 msgid "during statement block entry" msgstr "durante l'entrata nel blocco di istruzioni" -#: pl_exec.c:1199 +#: pl_exec.c:1669 msgid "during statement block exit" msgstr "durante l'uscita dal blocco di istruzioni" -#: pl_exec.c:1242 +#: pl_exec.c:1707 msgid "during exception cleanup" msgstr "durante la pulizia delle eccezioni" -#: pl_exec.c:1593 +#: pl_exec.c:2235 pl_exec.c:2249 +#, c-format +msgid "argument %d is an output argument but is not writable" +msgstr "l'argomento %d è un argomento di output ma non è scrivibile" + +#: pl_exec.c:2291 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS non può essere usato fuori da un gestore di eccezioni" -#: pl_exec.c:1789 +#: pl_exec.c:2496 #, c-format msgid "case not found" msgstr "caso non trovato" -#: pl_exec.c:1790 +#: pl_exec.c:2497 #, c-format msgid "CASE statement is missing ELSE part." msgstr "all'istruzione CASE manca la parte ELSE." -#: pl_exec.c:1944 +#: pl_exec.c:2590 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "il limite inferiore di un ciclo FOR non può essere nullo" -#: pl_exec.c:1960 +#: pl_exec.c:2606 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "il limite superiore di un ciclo FOR non può essere null" -#: pl_exec.c:1978 +#: pl_exec.c:2624 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "il valore BY di un ciclo FOR non può essere null" -#: pl_exec.c:1984 +#: pl_exec.c:2630 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "il valore BY di un ciclo FOR deve essere maggiore di zero" -#: pl_exec.c:2153 pl_exec.c:3912 +#: pl_exec.c:2764 pl_exec.c:4479 #, c-format msgid "cursor \"%s\" already in use" msgstr "il cursore \"%s\" è già in uso" -#: pl_exec.c:2176 pl_exec.c:3974 +#: pl_exec.c:2787 pl_exec.c:4544 #, c-format msgid "arguments given for cursor without arguments" msgstr "sono stati passati argomenti al cursore che non ne accetta" -#: pl_exec.c:2195 pl_exec.c:3993 +#: pl_exec.c:2806 pl_exec.c:4563 #, c-format msgid "arguments required for cursor" msgstr "sono richiesti argomenti per il cursore" -#: pl_exec.c:2280 +#: pl_exec.c:2893 #, c-format msgid "FOREACH expression must not be null" msgstr "l'espressione FOREACH non può essere vuota" -#: pl_exec.c:2286 +#: pl_exec.c:2908 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "l'espressione FOREACH deve generare un array, non il tipo %s" -#: pl_exec.c:2303 +#: pl_exec.c:2925 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "la dimensione della sezione (%d) è fuori dell'intervallo valido 0..%d" -#: pl_exec.c:2330 +#: pl_exec.c:2952 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "la variabile del ciclo FOREACH ... SLICE dev'essere di tipo array" -#: pl_exec.c:2334 +#: pl_exec.c:2956 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "la variabile di ciclo FOREACH non può essere un tipo array" -#: pl_exec.c:2522 pl_exec.c:2604 pl_exec.c:2771 +#: pl_exec.c:3118 pl_exec.c:3175 pl_exec.c:3350 #, c-format msgid "cannot return non-composite value from function returning composite type" msgstr "non è possibile restituire valori non compositi da una funzione che restituisce un tipo composito" -#: pl_exec.c:2648 pl_gram.y:3161 +#: pl_exec.c:3214 pl_gram.y:3267 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "non si può usare RETURN NEXT in una funzione non-SETOF" -#: pl_exec.c:2682 pl_exec.c:2813 +#: pl_exec.c:3255 pl_exec.c:3387 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "è stato fornito un risultato di tipo non corretto a RETURN NEXT" -#: pl_exec.c:2711 pl_exec.c:4382 pl_exec.c:4711 pl_exec.c:4737 pl_exec.c:4803 -#: pl_exec.c:4822 pl_exec.c:4890 pl_exec.c:4913 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "il record \"%s\" non è stato ancora assegnato" - -#: pl_exec.c:2713 pl_exec.c:4384 pl_exec.c:4713 pl_exec.c:4739 pl_exec.c:4805 -#: pl_exec.c:4824 pl_exec.c:4892 pl_exec.c:4915 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "La struttura della tupla di un record non ancora assegnato è indeterminata." - -#: pl_exec.c:2717 pl_exec.c:2737 +#: pl_exec.c:3293 pl_exec.c:3314 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "è stato fornito un record di tipo non corretto a RETURN NEXT" -#: pl_exec.c:2832 +#: pl_exec.c:3406 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT deve avere un parametro" -#: pl_exec.c:2865 pl_gram.y:3223 +#: pl_exec.c:3432 pl_gram.y:3330 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "non si può usare RETURN QUERY in una funzione non-SETOF" -#: pl_exec.c:2886 +#: pl_exec.c:3456 msgid "structure of query does not match function result type" msgstr "la struttura della query non coincide con il tipo del risultato della funzione" -#: pl_exec.c:2966 pl_exec.c:3096 +#: pl_exec.c:3540 pl_exec.c:3678 #, c-format msgid "RAISE option already specified: %s" msgstr "opzione RAISE già specificata: %s" -#: pl_exec.c:2999 +#: pl_exec.c:3574 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "RAISE senza parametri non può essere usato all'esterno di un gestore di eccezioni" -#: pl_exec.c:3086 +#: pl_exec.c:3668 #, c-format msgid "RAISE statement option cannot be null" msgstr "l'opzione dell'istruzione RAISE non può essere nulla" -#: pl_exec.c:3155 +#: pl_exec.c:3738 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3226 +#: pl_exec.c:3793 #, c-format msgid "assertion failed" msgstr "asserzione fallita" -#: pl_exec.c:3418 pl_exec.c:3562 pl_exec.c:3751 +#: pl_exec.c:4130 pl_exec.c:4317 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "non è possibile usare COPY verso/da un client in PL/pgSQL" -#: pl_exec.c:3422 pl_exec.c:3566 pl_exec.c:3755 -#, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "non si possono avviare/terminare transazioni in PL/pgSQL" - -#: pl_exec.c:3423 pl_exec.c:3567 pl_exec.c:3756 +#: pl_exec.c:4136 #, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Utilizza invece un blocco BEGIN con una clausola EXCEPTION." +msgid "unsupported transaction command in PL/pgSQL" +msgstr "comando di transazione non supportato in PL/pgSQL" -#: pl_exec.c:3590 pl_exec.c:3780 +#: pl_exec.c:4160 pl_exec.c:4347 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO usato con un comando che non restituisce alcun dato" -#: pl_exec.c:3618 pl_exec.c:3808 +#: pl_exec.c:4183 pl_exec.c:4370 #, c-format msgid "query returned no rows" msgstr "la query non ha restituito alcuna riga" -#: pl_exec.c:3637 pl_exec.c:3827 +#: pl_exec.c:4202 pl_exec.c:4389 #, c-format msgid "query returned more than one row" msgstr "la query ha restituito più di una riga" -#: pl_exec.c:3654 +#: pl_exec.c:4219 #, c-format msgid "query has no destination for result data" msgstr "la query non ha una destinazione per i dati restituiti" -#: pl_exec.c:3655 +#: pl_exec.c:4220 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "Se vuoi scartare i risultati di una SELECT, utilizza PERFORM." -#: pl_exec.c:3687 pl_exec.c:7128 +#: pl_exec.c:4253 pl_exec.c:8271 #, c-format msgid "query string argument of EXECUTE is null" msgstr "l'argomento della query di EXECUTE è nullo" -#: pl_exec.c:3743 +#: pl_exec.c:4309 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "EXECUTE di SELECT ... INTO non è implementato" -#: pl_exec.c:3744 +#: pl_exec.c:4310 #, c-format msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." msgstr "Potresti usare invece EXECUTE ... INTO oppure EXECUTE CREATE TABLE ... AS." -#: pl_exec.c:4056 pl_exec.c:4148 +#: pl_exec.c:4323 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "l'EXECUTE dei comandi di transazione non è implementato" + +#: pl_exec.c:4625 pl_exec.c:4713 #, c-format msgid "cursor variable \"%s\" is null" msgstr "la variabile del cursore \"%s\" è nulla" -#: pl_exec.c:4063 pl_exec.c:4155 +#: pl_exec.c:4636 pl_exec.c:4724 #, c-format msgid "cursor \"%s\" does not exist" msgstr "il cursore \"%s\" non esiste" -#: pl_exec.c:4077 +#: pl_exec.c:4649 #, c-format msgid "relative or absolute cursor position is null" msgstr "la posizione relativa o assoluta del cursore è nulla" -#: pl_exec.c:4257 +#: pl_exec.c:4899 pl_exec.c:4994 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "il valore null non può essere assegnato alla variabile \"%s\" dichiarata NOT NULL" -#: pl_exec.c:4326 +#: pl_exec.c:4975 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "non è possibile assegnare un valore non composito ad una variabile di tipo row" -#: pl_exec.c:4350 +#: pl_exec.c:5007 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "non è possibile assegnare un valore non composito ad una variabile di tipo record" -#: pl_exec.c:4493 +#: pl_exec.c:5058 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "non è possibile assegnare alla colonna di sistema \"%s\"" + +#: pl_exec.c:5122 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "il numero di dimensioni dell'array (%d) eccede il massimo consentito (%d)" -#: pl_exec.c:4525 +#: pl_exec.c:5154 #, c-format msgid "subscripted object is not an array" msgstr "l'oggetto del quale è stato richiesto un elemento non è un array" -#: pl_exec.c:4562 +#: pl_exec.c:5192 #, c-format msgid "array subscript in assignment must not be null" msgstr "l'indice di un array nell'assegnamento non può essere nullo" -#: pl_exec.c:5029 +#: pl_exec.c:5699 #, c-format msgid "query \"%s\" did not return data" msgstr "la query \"%s\" non ha restituito dati" -#: pl_exec.c:5037 +#: pl_exec.c:5707 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "la query \"%s\" ha restituito %d colonna" msgstr[1] "la query \"%s\" ha restituito %d colonne" -#: pl_exec.c:5064 +#: pl_exec.c:5735 #, c-format msgid "query \"%s\" returned more than one row" msgstr "la query \"%s\" ha restituito più di una riga" -#: pl_exec.c:5128 +#: pl_exec.c:5798 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "la query \"%s\" non è una SELECT" -#: pl_funcs.c:237 +#: pl_exec.c:6524 pl_exec.c:6564 pl_exec.c:6604 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "il tipo del parametro %d (%s) non combacia con quello usato preparando il piano (%s)" + +#: pl_exec.c:7379 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "il record \"%s\" non è stato ancora assegnato" + +#: pl_exec.c:7380 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "La struttura della tupla di un record non ancora assegnato è indeterminata." + +#: pl_funcs.c:239 msgid "statement block" msgstr "blocco di istruzioni" -#: pl_funcs.c:239 +#: pl_funcs.c:241 msgid "assignment" msgstr "assegnazione" -#: pl_funcs.c:249 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "ciclo FOR con variabile di ciclo intera" -#: pl_funcs.c:251 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "ciclo FOR su righe SELECT" -#: pl_funcs.c:253 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "ciclo FOR su cursore" -#: pl_funcs.c:255 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "FOREACH su array" -#: pl_funcs.c:269 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "istruzione SQL" -#: pl_funcs.c:273 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "ciclo FOR su una istruzione EXECUTE" -#: pl_gram.y:473 +#: pl_gram.y:485 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "l'etichetta del blocco dev'essere messa prima di DECLARE, non dopo" -#: pl_gram.y:493 +#: pl_gram.y:505 #, c-format msgid "collations are not supported by type %s" msgstr "gli ordinamenti non sono supportati dal tipo %s" -#: pl_gram.y:508 +#: pl_gram.y:524 #, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "variabile di tipo ROW o RECORD non può essere CONSTANT" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "la variabile \"%s\" deve avere un valore di default, perché è dichiarata NOT NULL" -#: pl_gram.y:518 -#, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "la variabile di tipo ROW o RECORD non può essere NOT NULL" - -#: pl_gram.y:529 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "il valore di default per variabili di tipo ROW o RECORD non è supportato" - -#: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 +#: pl_gram.y:670 pl_gram.y:685 pl_gram.y:711 #, c-format msgid "variable \"%s\" does not exist" msgstr "la variabile \"%s\" non esiste" -#: pl_gram.y:733 pl_gram.y:761 +#: pl_gram.y:729 pl_gram.y:757 msgid "duplicate declaration" msgstr "dichiarazione duplicata" -#: pl_gram.y:744 pl_gram.y:772 +#: pl_gram.y:740 pl_gram.y:768 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "la variabile \"%s\" nasconde una variabile definita precedentemente" -#: pl_gram.y:951 +#: pl_gram.y:984 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "l'elemento diagnostico %s non è consentito in GET STACKED DIAGNOSTICS" -#: pl_gram.y:969 +#: pl_gram.y:1002 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "l'elemento diagnostico %s non è consentito in GET CURRENT DIAGNOSTICS" -#: pl_gram.y:1067 +#: pl_gram.y:1100 msgid "unrecognized GET DIAGNOSTICS item" msgstr "elemento GET DIAGNOSTICS sconosciuto" -#: pl_gram.y:1078 pl_gram.y:3410 +#: pl_gram.y:1110 pl_gram.y:3509 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" non è una variabile scalare" -#: pl_gram.y:1330 pl_gram.y:1524 +#: pl_gram.y:1358 pl_gram.y:1551 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" -msgstr "variabile del ciclo sulle righe deve essere una variabile di tipo row o record o una lista di variabili scalari" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "la variabile di loop di un loop su righe deve essere una variabile record o una lista di variabili scalari" -#: pl_gram.y:1364 +#: pl_gram.y:1392 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "il cursore FOR nel ciclo deve avere solo una variabile di destinazione" -#: pl_gram.y:1371 +#: pl_gram.y:1399 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "il cursore FOR nel ciclo deve usare una variabile cursore vincolata" -#: pl_gram.y:1455 +#: pl_gram.y:1486 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "il valore integer del ciclo FOR deve avere solo una variabile di destinazione" -#: pl_gram.y:1491 +#: pl_gram.y:1522 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "non puoi specificare REVERSE nel ciclo FOR della query" -#: pl_gram.y:1638 +#: pl_gram.y:1653 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "la variabile del ciclo FOREACH dev'essere una variabile o lista di variabili conosciuta" -#: pl_gram.y:1679 +#: pl_gram.y:1694 #, c-format msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" msgstr "non c'è un'etichetta \"%s\" collegata ad alcun blocco o loop contenente questa istruzione" -#: pl_gram.y:1687 +#: pl_gram.y:1702 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "l'etichetta di blocco \"%s\" non può essere usata con CONTINUE" -#: pl_gram.y:1702 +#: pl_gram.y:1717 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT non può essere usato fuori da un loop, a meno che non abbia un'etichetta" -#: pl_gram.y:1703 +#: pl_gram.y:1718 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE non può essere usato all'esterno di un ciclo" -#: pl_gram.y:1727 pl_gram.y:1764 pl_gram.y:1812 pl_gram.y:2863 pl_gram.y:2945 -#: pl_gram.y:3056 pl_gram.y:3812 +#: pl_gram.y:1742 pl_gram.y:1779 pl_gram.y:1827 pl_gram.y:2959 pl_gram.y:3042 +#: pl_gram.y:3153 pl_gram.y:3910 msgid "unexpected end of function definition" msgstr "fine della definizione della funzione inaspettata" -#: pl_gram.y:1832 pl_gram.y:1856 pl_gram.y:1872 pl_gram.y:1878 pl_gram.y:1992 -#: pl_gram.y:2000 pl_gram.y:2014 pl_gram.y:2109 pl_gram.y:2290 pl_gram.y:2384 -#: pl_gram.y:2535 pl_gram.y:3653 pl_gram.y:3714 pl_gram.y:3793 +#: pl_gram.y:1847 pl_gram.y:1871 pl_gram.y:1887 pl_gram.y:1893 pl_gram.y:2010 +#: pl_gram.y:2018 pl_gram.y:2032 pl_gram.y:2126 pl_gram.y:2361 pl_gram.y:2455 +#: pl_gram.y:2613 pl_gram.y:3752 pl_gram.y:3813 pl_gram.y:3891 msgid "syntax error" msgstr "errore di sintassi" -#: pl_gram.y:1860 pl_gram.y:1862 pl_gram.y:2294 pl_gram.y:2296 +#: pl_gram.y:1875 pl_gram.y:1877 pl_gram.y:2365 pl_gram.y:2367 msgid "invalid SQLSTATE code" msgstr "codice SQLSTATE non valido" -#: pl_gram.y:2056 +#: pl_gram.y:2074 msgid "syntax error, expected \"FOR\"" msgstr "errore di sintassi, atteso \"FOR\"" -#: pl_gram.y:2118 +#: pl_gram.y:2135 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "l'istruzione FETCH non può restituire più di una riga" -#: pl_gram.y:2174 +#: pl_gram.y:2245 #, c-format msgid "cursor variable must be a simple variable" msgstr "la variabile cursore deve essere una variabile semplice" -#: pl_gram.y:2180 +#: pl_gram.y:2251 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "la variabile \"%s\" deve essere di tipo cursor o refcursor" -#: pl_gram.y:2506 pl_gram.y:2517 +#: pl_gram.y:2584 pl_gram.y:2595 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" non è una variabile conosciuta" -#: pl_gram.y:2621 pl_gram.y:2631 pl_gram.y:2787 +#: pl_gram.y:2699 pl_gram.y:2709 pl_gram.y:2864 msgid "mismatched parentheses" msgstr "le parentesi non corrispondono" -#: pl_gram.y:2635 +#: pl_gram.y:2713 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "manca \"%s\" alla fine della espressione SQL" -#: pl_gram.y:2641 +#: pl_gram.y:2719 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "manca \"%s\" alla fine dell'istruzione SQL" -#: pl_gram.y:2658 +#: pl_gram.y:2736 msgid "missing expression" msgstr "espressione mancante" -#: pl_gram.y:2660 +#: pl_gram.y:2738 msgid "missing SQL statement" msgstr "istruzione SQL mancante" -#: pl_gram.y:2789 +#: pl_gram.y:2866 msgid "incomplete data type declaration" msgstr "dichiarazione del tipo di dati incompleta" -#: pl_gram.y:2812 +#: pl_gram.y:2889 msgid "missing data type declaration" msgstr "manca la dichiarazione del tipo di dati" -#: pl_gram.y:2868 +#: pl_gram.y:2967 msgid "INTO specified more than once" msgstr "INTO specificato più di una volta" -#: pl_gram.y:3037 +#: pl_gram.y:3134 msgid "expected FROM or IN" msgstr "atteso FROM o IN" -#: pl_gram.y:3097 +#: pl_gram.y:3194 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "RETURN non può avere un parametro in una funzione che restituisce insiemi" -#: pl_gram.y:3098 +#: pl_gram.y:3195 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Usa RETURN NEXT o RETURN QUERY." -#: pl_gram.y:3106 +#: pl_gram.y:3205 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN non può avere un parametro in una funzione con parametri OUT" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN non può avere un parametro in una procedura" # Il fatto che una funzione che restituisce void sia chiamato "procedura" è un visual-basic-ismo che si può dimenticare -#: pl_gram.y:3115 +#: pl_gram.y:3210 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURN non può avere un parametro in una funzione che restituisce void" -#: pl_gram.y:3175 +#: pl_gram.y:3219 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN non può avere un parametro in una funzione con parametri OUT" + +#: pl_gram.y:3281 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT non può avere un parametro in una funzione con parametri OUT" -#: pl_gram.y:3279 +#: pl_gram.y:3388 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\" è dichiarata CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "la variabile \"%s\" è dichiarata CONSTANT" -#: pl_gram.y:3341 pl_gram.y:3353 +#: pl_gram.y:3451 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "un record o variabile riga on può fare parte di una lista INTO con più di un elemento" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "una variabile record non può essere parte di una lista INTO con più di un elemento" -#: pl_gram.y:3398 +#: pl_gram.y:3497 #, c-format msgid "too many INTO variables specified" msgstr "troppe variabili INTO specificate" -#: pl_gram.y:3606 +#: pl_gram.y:3705 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "etichetta finale \"%s\" specificata per un blocco senza etichetta" -#: pl_gram.y:3613 +#: pl_gram.y:3712 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "l'etichetta finale \"%s\" differisce da quella del blocco \"%s\"" -#: pl_gram.y:3648 +#: pl_gram.y:3747 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "il cursore \"%s\" non ha argomenti" -#: pl_gram.y:3662 +#: pl_gram.y:3761 #, c-format msgid "cursor \"%s\" has arguments" msgstr "il cursore \"%s\" ha argomenti" -#: pl_gram.y:3704 +#: pl_gram.y:3803 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "il cursore \"%s\" non ha un argomento di nome \"%s\"" -#: pl_gram.y:3724 +#: pl_gram.y:3823 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "il valore per il parametro \"%s\" del cursore \"%s\" è stato specificato più di una volta" -#: pl_gram.y:3749 +#: pl_gram.y:3848 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "numero di argomenti non sufficiente per il cursore \"%s\"" -#: pl_gram.y:3756 +#: pl_gram.y:3855 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "troppi argomenti per il cursore \"%s\"" -#: pl_gram.y:3844 +#: pl_gram.y:3942 msgid "unrecognized RAISE statement option" msgstr "opzione dell'istruzione RAISE sconosciuta" -#: pl_gram.y:3848 +#: pl_gram.y:3946 msgid "syntax error, expected \"=\"" msgstr "errore di sintassi, atteso \"=\"" -#: pl_gram.y:3889 +#: pl_gram.y:3987 #, c-format msgid "too many parameters specified for RAISE" msgstr "troppi parametri specificati per RAISE" -#: pl_gram.y:3893 +#: pl_gram.y:3991 #, c-format msgid "too few parameters specified for RAISE" msgstr "numero di parametri non sufficiente specificati per RAISE" -#: pl_handler.c:149 +#: pl_handler.c:154 msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "Imposta la gestione dei conflitti tra nomi di variabili PL/pgSQL e nomi di colonne di tabella." -#: pl_handler.c:158 +#: pl_handler.c:163 msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." msgstr "Stampa informazioni sui parametri nella parte DETAIL del messaggio di errore generato su errori in INTO ... STRICT." -#: pl_handler.c:166 +#: pl_handler.c:171 msgid "Perform checks given in ASSERT statements." msgstr "Effettua i controlli dati nelle istruzioni ASSERT." -#: pl_handler.c:174 +#: pl_handler.c:179 msgid "List of programming constructs that should produce a warning." msgstr "Elenco dei costrutti di programmazione che dovrebbero generare un avvertimento." -#: pl_handler.c:184 +#: pl_handler.c:189 msgid "List of programming constructs that should produce an error." msgstr "Elenco dei costrutti di programmazione che dovrebbero generare un errore." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:621 +#: pl_scanner.c:630 #, c-format msgid "%s at end of input" msgstr "%s alla fine dell'input" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:637 +#: pl_scanner.c:646 #, c-format msgid "%s at or near \"%s\"" msgstr "%s a o presso \"%s\"" diff --git a/src/pl/plpgsql/src/po/ja.po b/src/pl/plpgsql/src/po/ja.po index efb8aa9a537..968fe571f3d 100644 --- a/src/pl/plpgsql/src/po/ja.po +++ b/src/pl/plpgsql/src/po/ja.po @@ -1,798 +1,880 @@ +# LANGUAGE message translation file for plpgsql +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the plpgsql (PostgreSQL) package. +# HOTTA Michihde , 2013. +# msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0 beta 3\n" +"Project-Id-Version: plpgsql (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2013-08-18 13:02+0900\n" -"PO-Revision-Date: 2013-08-18 13:04+0900\n" -"Last-Translator: HOTTA Michihde \n" +"POT-Creation-Date: 2018-10-12 11:48+0900\n" +"PO-Revision-Date: 2018-10-12 13:34+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: Japanese\n" -"X-Poedit-Country: JAPAN\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" -#: pl_comp.c:432 pl_handler.c:276 +#: pl_comp.c:434 pl_handler.c:457 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "PL/pgSQL 関数ã§ã¯ %s åž‹ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: pl_comp.c:513 +#: pl_comp.c:522 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" -msgstr "関数 \"%s\" ãŒå¤šæ§˜ãªå½¢ã‚’æŒã¤ãŸã‚ã€å®Ÿéš›ã®æˆ»ã‚Šå€¤ã®åž‹ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "" +"関数 \"%s\" ãŒå¤šæ§˜ãªå½¢ã‚’æŒã¤ãŸã‚ã€å®Ÿéš›ã®æˆ»ã‚Šå€¤ã®åž‹ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: pl_comp.c:543 +#: pl_comp.c:552 #, c-format msgid "trigger functions can only be called as triggers" msgstr "トリガー関数ã¯ãƒˆãƒªã‚¬ãƒ¼ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" -#: pl_comp.c:547 pl_handler.c:261 +#: pl_comp.c:556 pl_handler.c:441 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "PL/pgSQL 関数㯠%s 型を返ã›ã¾ã›ã‚“" -#: pl_comp.c:590 +#: pl_comp.c:595 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "トリガー関数ã«ã¯å¼•数を宣言ã§ãã¾ã›ã‚“" -#: pl_comp.c:591 +#: pl_comp.c:596 #, c-format -msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." -msgstr "ãã®ä»£ã‚りã€ãƒˆãƒªã‚¬ãƒ¼ã®å¼•æ•°ã«ã¯ TG_NARGS 㨠TG_ARGV を通ã—ã¦ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾ã™" +msgid "" +"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " +"instead." +msgstr "" +"ãã®ä»£ã‚りã€ãƒˆãƒªã‚¬ãƒ¼ã®å¼•æ•°ã«ã¯ TG_NARGS 㨠TG_ARGV を通ã—ã¦ã®ã¿ã‚¢ã‚¯ã‚»ã‚¹ã§ãã¾" +"ã™" -#: pl_comp.c:693 +#: pl_comp.c:719 #, c-format -#| msgid "trigger functions cannot have declared arguments" msgid "event trigger functions cannot have declared arguments" -msgstr "イベントトリガー関数ã«ã¯å¼•数を宣言ã§ãã¾ã›ã‚“" +msgstr "イベントトリガー関数ã§ã¯å¼•数を宣言ã§ãã¾ã›ã‚“" -#: pl_comp.c:950 +#: pl_comp.c:976 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "PL/pgSQL 関数 \"%s\" ã® %d 行目付近ã§ã®ã‚³ãƒ³ãƒ‘イル" -#: pl_comp.c:973 +#: pl_comp.c:999 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "パラメータ \"%s\" ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" -#: pl_comp.c:1083 +#: pl_comp.c:1109 #, c-format msgid "column reference \"%s\" is ambiguous" -msgstr "列å‚ç…§\"%s\"ã¯æ›–昧ã§ã™" +msgstr "列å‚ç…§ \"%s\" ãŒä¸€æ„ã«ç‰¹å®šã§ãã¾ã›ã‚“" -#: pl_comp.c:1085 +#: pl_comp.c:1111 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." -msgstr "PL/pgSQL変数もã—ãã¯ãƒ†ãƒ¼ãƒ–ルã®ã‚«ãƒ©ãƒ åã„ãšã‚Œã‹ã‚’å‚ç…§ã—ã¦ã„ãŸå¯èƒ½æ€§ãŒã‚りã¾ã™" +msgstr "" +"PL/pgSQL 変数もã—ãã¯ãƒ†ãƒ¼ãƒ–ルã®ã‚«ãƒ©ãƒ åã®ã©ã¡ã‚‰ã‹ã‚’å‚ç…§ã—ã¦ã„ãŸå¯èƒ½æ€§ãŒã‚りã¾" +"ã™ã€‚" -#: pl_comp.c:1265 pl_comp.c:1293 pl_exec.c:4107 pl_exec.c:4462 pl_exec.c:4547 -#: pl_exec.c:4638 +#: pl_comp.c:1294 pl_exec.c:5049 pl_exec.c:5414 pl_exec.c:5501 pl_exec.c:5592 +#: pl_exec.c:6510 #, c-format msgid "record \"%s\" has no field \"%s\"" -msgstr "レコード \"%s\" ã«ã¯åˆ— \"%s\" ã¯ã‚りã¾ã›ã‚“" +msgstr "レコード \"%s\" ã«ã¯é …ç›® \"%s\" ã¯ã‚りã¾ã›ã‚“" -#: pl_comp.c:1824 +#: pl_comp.c:1756 #, c-format msgid "relation \"%s\" does not exist" msgstr "リレーション \"%s\" ãŒã‚りã¾ã›ã‚“" -#: pl_comp.c:1933 +#: pl_comp.c:1848 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "変数 \"%s\" ã®åž‹ã¯æ“¬ä¼¼ã‚¿ã‚¤ãƒ— %s ã§ã™" -#: pl_comp.c:1999 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "リレーション \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" - -#: pl_comp.c:2159 +#: pl_comp.c:2028 #, c-format msgid "type \"%s\" is only a shell" -msgstr "åž‹ \"%s\" ã¯ã‚·ã‚§ãƒ«ã§ã®ã¿ä½¿ãˆã¾ã™" +msgstr "åž‹ \"%s\" ã¯ã‚·ã‚§ãƒ«ã§ã®ã¿ä½¿ãˆã¾ã™" -#: pl_comp.c:2233 pl_comp.c:2286 +#: pl_comp.c:2125 pl_comp.c:2178 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "例外æ¡ä»¶ \"%s\" ãŒèªè­˜ã§ãã¾ã›ã‚“" -#: pl_comp.c:2444 +#: pl_comp.c:2392 #, c-format -msgid "could not determine actual argument type for polymorphic function \"%s\"" +msgid "" +"could not determine actual argument type for polymorphic function \"%s\"" msgstr "関数 \"%s\" ãŒå¤šæ§˜ãªå½¢ã‚’æŒã¤ãŸã‚ã€å®Ÿéš›ã®å¼•æ•°ã®åž‹ã‚’特定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: pl_exec.c:254 pl_exec.c:514 pl_exec.c:793 +#: pl_exec.c:474 pl_exec.c:886 pl_exec.c:1103 msgid "during initialization of execution state" -msgstr "実行状態ã®åˆæœŸåŒ–中ã«" +msgstr "実行状態ã®åˆæœŸåŒ–ã®éš›" -#: pl_exec.c:261 +#: pl_exec.c:480 msgid "while storing call arguments into local variables" -msgstr "å¼•æ•°ã‚’ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«æ ¼ç´ã™ã‚‹éš›ã«" +msgstr "å¼•æ•°ã‚’ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã«æ ¼ç´ã™ã‚‹éš›" -#: pl_exec.c:303 pl_exec.c:671 +#: pl_exec.c:568 pl_exec.c:938 msgid "during function entry" -msgstr "関数登録ã®éš›ã«" +msgstr "関数ã«å…¥ã‚‹éš›" -#: pl_exec.c:334 pl_exec.c:702 pl_exec.c:834 -#, c-format -msgid "CONTINUE cannot be used outside a loop" -msgstr "CONTINUE ã¯ãƒ«ãƒ¼ãƒ—ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" - -#: pl_exec.c:338 +#: pl_exec.c:593 #, c-format msgid "control reached end of function without RETURN" msgstr "RETURN ãŒç¾ã‚Œã‚‹å‰ã«ã€åˆ¶å¾¡ãŒé–¢æ•°ã®çµ‚ã‚りã«é”ã—ã¾ã—ãŸ" -#: pl_exec.c:345 +#: pl_exec.c:600 msgid "while casting return value to function's return type" msgstr "æˆ»ã‚Šå€¤ã‚’é–¢æ•°ã®æˆ»ã‚Šå€¤ã®åž‹ã¸ã‚­ãƒ£ã‚¹ãƒˆã™ã‚‹éš›ã«" -#: pl_exec.c:358 pl_exec.c:2820 +#: pl_exec.c:613 pl_exec.c:3512 #, c-format msgid "set-valued function called in context that cannot accept a set" -msgstr "値ã®ã‚»ãƒƒãƒˆã‚’å—ã‘付ã‘ãªã„よã†ãªæ–‡è„ˆã§ã€ã‚»ãƒƒãƒˆå€¤ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã°ã‚Œã¾ã—ãŸ" - -#: pl_exec.c:396 pl_exec.c:2663 -msgid "returned record type does not match expected record type" -msgstr "戻りレコードã®åž‹ãŒæœŸå¾…ã™ã‚‹ãƒ¬ã‚³ãƒ¼ãƒ‰ã®åž‹ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "" +"値ã®é›†åˆã‚’å—ã‘付ã‘ãªã„よã†ãªã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ã€é›†åˆå€¤ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã°ã‚Œã¾ã—ãŸ" -#: pl_exec.c:456 pl_exec.c:710 pl_exec.c:842 +#: pl_exec.c:739 pl_exec.c:967 pl_exec.c:1128 msgid "during function exit" -msgstr "関数を抜ã‘ã‚‹éš›ã«" +msgstr "関数を抜ã‘ã‚‹éš›" + +#: pl_exec.c:794 pl_exec.c:833 pl_exec.c:3357 +msgid "returned record type does not match expected record type" +msgstr "è¿”ã•れãŸãƒ¬ã‚³ãƒ¼ãƒ‰ã®åž‹ãŒæœŸå¾…ã™ã‚‹ãƒ¬ã‚³ãƒ¼ãƒ‰ã®åž‹ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: pl_exec.c:706 pl_exec.c:838 +#: pl_exec.c:963 pl_exec.c:1124 #, c-format msgid "control reached end of trigger procedure without RETURN" -msgstr "RETURN ãŒç¾ã‚Œã‚‹å‰ã«ã€åˆ¶å¾¡ãŒãƒˆãƒªã‚¬ãƒ¼æ‰‹ç¶šãã®çµ‚ã‚りã«é”ã—ã¾ã—ãŸ" +msgstr "RETURN ãŒç¾ã‚Œã‚‹å‰ã«ã€åˆ¶å¾¡ãŒãƒˆãƒªã‚¬ãƒ¼ãƒ—ロシージャã®çµ‚ã‚りã«é”ã—ã¾ã—ãŸ" -#: pl_exec.c:715 +#: pl_exec.c:972 #, c-format msgid "trigger procedure cannot return a set" -msgstr "トリガー手続ãã¯ã‚»ãƒƒãƒˆã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" +msgstr "トリガー手続ãã¯é›†åˆå€¤ã‚’è¿”ã™ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: pl_exec.c:737 -msgid "returned row structure does not match the structure of the triggering table" +#: pl_exec.c:1011 pl_exec.c:1039 +msgid "" +"returned row structure does not match the structure of the triggering table" msgstr "è¿”ã•れãŸè¡Œã®æ§‹é€ ãŒã€ãƒˆãƒªã‚¬ãƒ¼ã—ã¦ã„ã‚‹ãƒ†ãƒ¼ãƒ–ãƒ«ã®æ§‹é€ ã¨ãƒžãƒƒãƒã—ã¾ã›ã‚“" -#: pl_exec.c:893 +#. translator: last %s is a phrase such as "during statement block +#. local variable initialization" +#. +#: pl_exec.c:1176 #, c-format msgid "PL/pgSQL function %s line %d %s" -msgstr "PL/pgSQL関数%sã®%d行目ã§%s" +msgstr "PL/pgSQL 関数 %s ã®%d行目 %s" -#: pl_exec.c:904 +#. translator: last %s is a phrase such as "while storing call +#. arguments into local variables" +#. +#: pl_exec.c:1187 #, c-format msgid "PL/pgSQL function %s %s" -msgstr "PL/pgSQL関数%sã§%s" +msgstr "PL/pgSQL 関数 %s - %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:912 +#: pl_exec.c:1195 #, c-format msgid "PL/pgSQL function %s line %d at %s" -msgstr "PL/pgSQL関数%sã®%d行目ã®åž‹%s" +msgstr "PL/pgSQL 関数 %s ã®%d行目 - %s" -#: pl_exec.c:918 +#: pl_exec.c:1201 #, c-format msgid "PL/pgSQL function %s" -msgstr "PL/pgSQL関数%s" +msgstr "PL/pgSQL 関数 %s" -#: pl_exec.c:1027 +#: pl_exec.c:1539 msgid "during statement block local variable initialization" -msgstr "ステートメントブロックã§ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã‚’åˆæœŸåŒ–ã™ã‚‹éš›ã«" +msgstr "ステートメントブロックã§ãƒ­ãƒ¼ã‚«ãƒ«å¤‰æ•°ã‚’åˆæœŸåŒ–中" -#: pl_exec.c:1069 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "変数 \"%s\" 㯠NOT NULL ã¨ã—ã¦å®£è¨€ã•れã¦ã„ã‚‹ãŸã‚ã€åˆæœŸå€¤ã‚’ NULL ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" - -#: pl_exec.c:1119 +#: pl_exec.c:1637 msgid "during statement block entry" -msgstr "ステートメントブロックを登録ã™ã‚‹éš›ã«" +msgstr "ステートメントブロックã«å…¥ã‚‹éš›ã«" -#: pl_exec.c:1140 +#: pl_exec.c:1669 msgid "during statement block exit" msgstr "ステートメントブロックを抜ã‘ã‚‹éš›ã«" -#: pl_exec.c:1183 +#: pl_exec.c:1707 msgid "during exception cleanup" msgstr "例外をクリーンアップã™ã‚‹éš›ã«" -#: pl_exec.c:1536 +#: pl_exec.c:2235 pl_exec.c:2249 +#, c-format +msgid "argument %d is an output argument but is not writable" +msgstr "引数%dã¯å‡ºåŠ›å¼•æ•°ã§ã™ãŒæ›¸ãè¾¼ã¿ä¸å¯ã§ã™" + +#: pl_exec.c:2291 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" -msgstr "GET STACKED DIAGNOSTICSã¯ä¾‹å¤–ãƒãƒ³ãƒ‰ãƒ©ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" +msgstr "GET STACKED DIAGNOSTICS ã¯ä¾‹å¤–ãƒãƒ³ãƒ‰ãƒ©ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_exec.c:1737 +#: pl_exec.c:2496 #, c-format msgid "case not found" msgstr "case ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: pl_exec.c:1738 +#: pl_exec.c:2497 #, c-format msgid "CASE statement is missing ELSE part." msgstr "CASE ステートメント㫠ELSE 部分ãŒã‚りã¾ã›ã‚“" -#: pl_exec.c:1890 +#: pl_exec.c:2590 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "FOR ループã®ä¸‹é™ã‚’ NULL ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: pl_exec.c:1905 +#: pl_exec.c:2606 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "FOR ループã®ä¸Šé™ã‚’ NULL ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: pl_exec.c:1922 +#: pl_exec.c:2624 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "FOR ループã«ãŠã‘ã‚‹ BY ã®å€¤ã‚’ NULL ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: pl_exec.c:1928 +#: pl_exec.c:2630 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "FOR ループã«ãŠã‘ã‚‹ BY ã®å€¤ã¯ã‚¼ãƒ­ã‚ˆã‚Šå¤§ãããªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:2098 pl_exec.c:3658 +#: pl_exec.c:2764 pl_exec.c:4479 #, c-format msgid "cursor \"%s\" already in use" msgstr "カーソル \"%s\" ã¯ã™ã§ã«ä½¿ã‚れã¦ã„ã¾ã™" -#: pl_exec.c:2121 pl_exec.c:3720 +#: pl_exec.c:2787 pl_exec.c:4544 #, c-format msgid "arguments given for cursor without arguments" msgstr "引数ãªã—ã®ã‚«ãƒ¼ã‚½ãƒ«ã«å¼•æ•°ãŒä¸Žãˆã‚‰ã‚Œã¾ã—ãŸ" -#: pl_exec.c:2140 pl_exec.c:3739 +#: pl_exec.c:2806 pl_exec.c:4563 #, c-format msgid "arguments required for cursor" msgstr "カーソルã«ã¯å¼•æ•°ãŒå¿…è¦ã§ã™" -#: pl_exec.c:2227 +#: pl_exec.c:2893 #, c-format msgid "FOREACH expression must not be null" -msgstr "FOREACHå¼ã¯NULLã§ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "FOREACH å¼ã¯ NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:2233 +#: pl_exec.c:2908 #, c-format msgid "FOREACH expression must yield an array, not type %s" -msgstr "FOREACHå¼ã¯%såž‹ã§ã¯ãªãé…列を生æˆã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "FOREACH å¼ã¯ %s åž‹ã§ã¯ãªãé…列を生æˆã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:2250 +#: pl_exec.c:2925 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" -msgstr "範囲次元%dã¯æœ‰åŠ¹ç¯„å›²0ã‹ã‚‰%dã¾ã§ã®é–“ã«ã‚りã¾ã›ã‚“" +msgstr "é…列ã®è¦ç´ æ•° (%d) ãŒæœ‰åŠ¹ç¯„å›²0ã‹ã‚‰%dã¾ã§ã®é–“ã«ã‚りã¾ã›ã‚“" -#: pl_exec.c:2277 +#: pl_exec.c:2952 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" -msgstr "FOREACH ... SLICEループ変数ã¯é…列型ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "FOREACH ... SLICE ループ変数ã¯é…列型ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:2281 +#: pl_exec.c:2956 #, c-format msgid "FOREACH loop variable must not be of an array type" -msgstr "FOREACHループ変数ã¯é…列型ã§ã¯ã„ã‘ã¾ã›ã‚“" +msgstr "FOREACH ループ変数ã¯é…列型ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:2502 pl_exec.c:2655 +#: pl_exec.c:3118 pl_exec.c:3175 pl_exec.c:3350 #, c-format -#| msgid "while casting return value to function's return type" -msgid "cannot return non-composite value from function returning composite type" +msgid "" +"cannot return non-composite value from function returning composite type" msgstr "複åˆåž‹ã‚’è¿”ã™é–¢æ•°ã‹ã‚‰è¤‡åˆåž‹ä»¥å¤–ã®å€¤ã‚’è¿”ã™ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#: pl_exec.c:2546 pl_gram.y:3020 +#: pl_exec.c:3214 pl_gram.y:3267 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "SETOF ã§ãªã„関数ã§ã¯ RETURN NEXT ã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_exec.c:2574 pl_exec.c:2697 +#: pl_exec.c:3255 pl_exec.c:3387 #, c-format msgid "wrong result type supplied in RETURN NEXT" -msgstr "RETURN NEXT ã«ãŠã„ã¦èª¤ã£ãŸæˆ»ã‚Šå€¤ã®åž‹ãŒæŒ‡å®šã•れã¦ã„ã¾ã™" - -#: pl_exec.c:2597 pl_exec.c:4094 pl_exec.c:4420 pl_exec.c:4455 pl_exec.c:4521 -#: pl_exec.c:4540 pl_exec.c:4608 pl_exec.c:4631 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "レコード \"%s\" ã«ã¯ã€ã¾ã å€¤ãŒä»£å…¥ã•れã¦ã„ã¾ã›ã‚“" - -#: pl_exec.c:2599 pl_exec.c:4096 pl_exec.c:4422 pl_exec.c:4457 pl_exec.c:4523 -#: pl_exec.c:4542 pl_exec.c:4610 pl_exec.c:4633 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "ã¾ã ä»£å…¥ã•れã¦ã„ãªã„レコードã®ã‚¿ãƒ—ル構造ã¯ä¸å®šã§ã™" +msgstr "RETURN NEXT ã§æŒ‡å®šã•れã¦ã„ã‚‹çµæžœã®åž‹ãŒèª¤ã£ã¦ã„ã¾ã™" -#: pl_exec.c:2603 pl_exec.c:2623 +#: pl_exec.c:3293 pl_exec.c:3314 #, c-format msgid "wrong record type supplied in RETURN NEXT" -msgstr "RETURN NEXT ã«ãŠã„ã¦ã€èª¤ã£ãŸãƒ¬ã‚³ãƒ¼ãƒ‰åž‹ãŒæŒ‡å®šã•れã¦ã„ã¾ã™" +msgstr "RETURN NEXT ã§æŒ‡å®šã•れã¦ã„るレコードã®åž‹ãŒèª¤ã£ã¦ã„ã¾ã™" -#: pl_exec.c:2715 +#: pl_exec.c:3406 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT ã«ã¯ãƒ‘ラメーターãŒå¿…è¦ã§ã™" -#: pl_exec.c:2748 pl_gram.y:3078 +#: pl_exec.c:3432 pl_gram.y:3330 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "SETOF ã§ãªã„関数ã§ã¯ RETURN QUERY ã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_exec.c:2768 +#: pl_exec.c:3456 msgid "structure of query does not match function result type" -msgstr "ã‚¯ã‚¨ãƒªãƒ¼ã®æ§‹é€ ãŒé–¢æ•°ã®æˆ»ã‚Šå€¤ã®åž‹ã¨ä¸€è‡´ã—ã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›ã®æ§‹é€ ãŒé–¢æ•°ã®çµæžœã®åž‹ã¨ä¸€è‡´ã—ã¾ã›ã‚“" -#: pl_exec.c:2848 pl_exec.c:2980 +#: pl_exec.c:3540 pl_exec.c:3678 #, c-format msgid "RAISE option already specified: %s" msgstr "RAISE ã‚ªãƒ—ã‚·ãƒ§ãƒ³ã¯æ—¢ã«æŒ‡å®šã•れã¦ã„ã¾ã™: %s" -#: pl_exec.c:2881 +#: pl_exec.c:3574 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "引数ã®ç„¡ã„ RAISE ã¯ã€ä¾‹å¤–ãƒãƒ³ãƒ‰ãƒ©ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_exec.c:2922 -#, c-format -msgid "too few parameters specified for RAISE" -msgstr "RAISE ã«æŒ‡å®šã•れãŸãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒ¼ã®æ•°ãŒè¶³ã‚Šã¾ã›ã‚“" - -#: pl_exec.c:2950 -#, c-format -msgid "too many parameters specified for RAISE" -msgstr "RAISE ã«æŒ‡å®šã•れãŸãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒ¼ã®æ•°ãŒå¤šã™ãŽã¾ã™" - -#: pl_exec.c:2970 +#: pl_exec.c:3668 #, c-format msgid "RAISE statement option cannot be null" msgstr "RAISE ステートメントã®ã‚ªãƒ—ションã«ã¯ NULL ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: pl_exec.c:3041 +#: pl_exec.c:3738 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3211 pl_exec.c:3348 pl_exec.c:3521 +#: pl_exec.c:3793 #, c-format -msgid "cannot COPY to/from client in PL/pgSQL" -msgstr "PL/pgSQL 内ã§ã¯ COPY to/from ã¯ä½¿ãˆã¾ã›ã‚“" +msgid "assertion failed" +msgstr "アサーションã«å¤±æ•—" -#: pl_exec.c:3215 pl_exec.c:3352 pl_exec.c:3525 +#: pl_exec.c:4130 pl_exec.c:4317 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "PL/pgSQL 内ã§ã¯ãƒˆãƒ©ãƒ³ã‚¶ã‚¯ã‚·ãƒ§ãƒ³ã‚’é–‹å§‹ï¼çµ‚了ã§ãã¾ã›ã‚“" +msgid "cannot COPY to/from client in PL/pgSQL" +msgstr "PL/pgSQL 内ã§ã¯ COPY to/from クライアントã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_exec.c:3216 pl_exec.c:3353 pl_exec.c:3526 +#: pl_exec.c:4136 #, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "代ã‚り㫠EXCEPTION å¥ã‚’伴ㆠBEGIN ブロックを使用ã—ã¦ãã ã•ã„" +#| msgid "cannot begin/end transactions in PL/pgSQL" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "PL/pgSQL 内ã§ã¯ã‚µãƒãƒ¼ãƒˆã•れãªã„トランザクションコマンド" -#: pl_exec.c:3376 pl_exec.c:3550 +#: pl_exec.c:4160 pl_exec.c:4347 #, c-format msgid "INTO used with a command that cannot return data" -msgstr "データを返ã›ãªã„命令㧠INTO ãŒä½¿ã‚れã¾ã—ãŸ" +msgstr "データを返ã›ãªã„コマンド㧠INTO ãŒä½¿ã‚れã¾ã—ãŸ" -#: pl_exec.c:3396 pl_exec.c:3570 +#: pl_exec.c:4183 pl_exec.c:4370 #, c-format msgid "query returned no rows" -msgstr "クエリーã¯è¡Œã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" +msgstr "å•ã„åˆã‚ã›ã¯è¡Œã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: pl_exec.c:3405 pl_exec.c:3579 +#: pl_exec.c:4202 pl_exec.c:4389 #, c-format msgid "query returned more than one row" -msgstr "クエリーãŒè¤‡æ•°ã®è¡Œã‚’è¿”ã—ã¾ã—ãŸ" +msgstr "å•ã„åˆã‚ã›ãŒè¤‡æ•°ã®è¡Œã‚’è¿”ã—ã¾ã—ãŸ" -#: pl_exec.c:3420 +#: pl_exec.c:4219 #, c-format msgid "query has no destination for result data" -msgstr "クエリーã«çµæžœãƒ‡ãƒ¼ã‚¿ã®è¿”å´å…ˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›ã«çµæžœãƒ‡ãƒ¼ã‚¿ã®è¿”å´å…ˆãŒæŒ‡å®šã•れã¦ã„ã¾ã›ã‚“" -#: pl_exec.c:3421 +#: pl_exec.c:4220 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." -msgstr "SELECT ã®çµæžœã‚’破棄ã—ãŸã„å ´åˆã¯ã€ä»£ã‚り㫠PERFORM を使ã£ã¦ãã ã•ã„" +msgstr "SELECT ã®çµæžœã‚’破棄ã—ãŸã„å ´åˆã€ä»£ã‚り㫠PERFORM を使ã£ã¦ãã ã•ã„" -#: pl_exec.c:3454 pl_exec.c:6414 +#: pl_exec.c:4253 pl_exec.c:8271 #, c-format msgid "query string argument of EXECUTE is null" -msgstr "EXECUTE ã®ã‚¯ã‚¨ãƒªãƒ¼æ–‡å­—列ã®å¼•数㌠NULL ã§ã™" +msgstr "EXECUTE ã®å•ã„åˆã‚ã›æ–‡å­—列ã®å¼•数㌠NULL ã§ã™" -#: pl_exec.c:3513 +#: pl_exec.c:4309 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "SELECT ... INTO ã® EXECUTE ã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: pl_exec.c:3514 +#: pl_exec.c:4310 #, c-format -msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." -msgstr "代ã‚りã«EXECUTE ... INTOã¾ãŸã¯EXECUTE CREATE TABLE ... ASを使用ã™ã‚‹æ–¹ãŒã‚ˆã„ã‹ã‚‚ã—れã¾ã›ã‚“。" +msgid "" +"You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " +"instead." +msgstr "" +"代ã‚り㫠EXECUTE ... INTO ã¾ãŸã¯ EXECUTE CREATE TABLE ... AS ãŒä½¿ãˆã¾ã™ã€‚" + +#: pl_exec.c:4323 +#, c-format +#| msgid "function \"close_sl\" not implemented" +msgid "EXECUTE of transaction commands is not implemented" +msgstr "トランザクションコマンドã®EXECUTEã¯å®Ÿè£…ã•れã¦ã„ã¾ã›ã‚“" -#: pl_exec.c:3802 pl_exec.c:3894 +#: pl_exec.c:4625 pl_exec.c:4713 #, c-format msgid "cursor variable \"%s\" is null" msgstr "カーソル変数 \"%s\" ㌠NULL ã§ã™" -#: pl_exec.c:3809 pl_exec.c:3901 +#: pl_exec.c:4636 pl_exec.c:4724 #, c-format msgid "cursor \"%s\" does not exist" msgstr "カーソル \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: pl_exec.c:3823 +#: pl_exec.c:4649 #, c-format msgid "relative or absolute cursor position is null" msgstr "相対もã—ãã¯çµ¶å¯¾ã‚«ãƒ¼ã‚½ãƒ«ä½ç½®ãŒ NULL ã§ã™" -#: pl_exec.c:3990 +#: pl_exec.c:4899 pl_exec.c:4994 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "NOT NULL ã¨ã—ã¦å®£è¨€ã•れãŸå¤‰æ•° \"%s\" ã«ã¯ NULL を代入ã§ãã¾ã›ã‚“" -#: pl_exec.c:4037 +#: pl_exec.c:4975 #, c-format msgid "cannot assign non-composite value to a row variable" -msgstr "複åˆå€¤ã§ãªã„値を行変数ã«ä»£å…¥ã§ãã¾ã›ã‚“" +msgstr "複åˆåž‹ã§ãªã„値を行変数ã«ä»£å…¥ã§ãã¾ã›ã‚“" -#: pl_exec.c:4061 +#: pl_exec.c:5007 #, c-format msgid "cannot assign non-composite value to a record variable" -msgstr "複åˆå€¤ã§ãªã„値をレコード変数ã«ä»£å…¥ã§ãã¾ã›ã‚“" +msgstr "複åˆåž‹ã§ãªã„値をレコード変数ã«ä»£å…¥ã§ãã¾ã›ã‚“" -#: pl_exec.c:4206 +#: pl_exec.c:5058 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "システム列\"%s\"ã«ä»£å…¥ã§ãã¾ã›ã‚“" + +#: pl_exec.c:5122 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" -msgstr "é…åˆ—ã®æ¬¡å…ƒæ•°(%d)ãŒæŒ‡å®šå¯èƒ½ãªæœ€å¤§å€¤(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" +msgstr "é…åˆ—ã®æ¬¡å…ƒæ•°(%d)ãŒåˆ¶é™å€¤(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" -#: pl_exec.c:4238 +#: pl_exec.c:5154 #, c-format msgid "subscripted object is not an array" msgstr "添字ã¤ãオブジェクトã¯é…列ã§ã¯ã‚りã¾ã›ã‚“" -#: pl_exec.c:4275 +#: pl_exec.c:5192 #, c-format msgid "array subscript in assignment must not be null" msgstr "代入ã«ãŠã‘ã‚‹é…åˆ—ã®æ·»å­—㌠NULL ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: pl_exec.c:4744 +#: pl_exec.c:5699 #, c-format msgid "query \"%s\" did not return data" -msgstr "クエリー \"%s\" ãŒãƒ‡ãƒ¼ã‚¿ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" +msgstr "å•ã„åˆã‚ã› \"%s\" ãŒãƒ‡ãƒ¼ã‚¿ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: pl_exec.c:4752 +#: pl_exec.c:5707 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" -msgstr[0] "クエリー \"%s\" ㌠%d 個ã®åˆ—ã‚’è¿”ã—ã¾ã—ãŸ" -msgstr[1] "クエリー \"%s\" ㌠%d 個ã®åˆ—ã‚’è¿”ã—ã¾ã—ãŸ" +msgstr[0] "å•ã„åˆã‚ã› \"%s\" ㌠%d 個ã®åˆ—ã‚’è¿”ã—ã¾ã—ãŸ" -#: pl_exec.c:4778 +#: pl_exec.c:5735 #, c-format msgid "query \"%s\" returned more than one row" -msgstr "クエリー \"%s\" ãŒè¤‡æ•°ã®è¡Œã‚’è¿”ã—ã¾ã—ãŸ" +msgstr "å•ã„åˆã‚ã› \"%s\" ãŒè¤‡æ•°ã®è¡Œã‚’è¿”ã—ã¾ã—ãŸ" -#: pl_exec.c:4835 +#: pl_exec.c:5798 #, c-format msgid "query \"%s\" is not a SELECT" -msgstr "クエリー \"%s\" ㌠SELECT ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã› \"%s\" ㌠SELECT ã§ã¯ã‚りã¾ã›ã‚“" -#: pl_funcs.c:218 +#: pl_exec.c:6524 pl_exec.c:6564 pl_exec.c:6604 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "パラメータã®åž‹%d(%s)ãŒå®Ÿè¡Œè¨ˆç”»(%s)を準備ã™ã‚‹æ™‚点ã¨ä¸€è‡´ã—ã¾ã›ã‚“" + +#: pl_exec.c:7379 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "レコード \"%s\" ã«ã¯ã¾ã å€¤ãŒä»£å…¥ã•れã¦ã„ã¾ã›ã‚“" + +#: pl_exec.c:7380 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "ã¾ã ä»£å…¥ã•れã¦ã„ãªã„レコードã®ã‚¿ãƒ—ル構造ã¯ä¸å®šã§ã™" + +#: pl_funcs.c:239 msgid "statement block" msgstr "ステートメントブロック" -#: pl_funcs.c:220 +#: pl_funcs.c:241 msgid "assignment" msgstr "代入" -#: pl_funcs.c:230 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" -msgstr "æ•´æ•°ã®ãƒ«ãƒ¼ãƒ—変数を伴ㆠFOR" +msgstr "æ•´æ•°ã®ãƒ«ãƒ¼ãƒ—変数を使ã£ãŸ FOR" -#: pl_funcs.c:232 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" -msgstr "SELECT 行を制御ã™ã‚‹ FOR" +msgstr "SELECT 行を使ã£ãŸ FOR" -#: pl_funcs.c:234 +#: pl_funcs.c:255 msgid "FOR over cursor" -msgstr "カーソルを制御ã™ã‚‹ FOR" +msgstr "カーソルを使ã£ãŸ FOR" -#: pl_funcs.c:236 +#: pl_funcs.c:257 msgid "FOREACH over array" -msgstr "é…列全体ã«å¯¾ã™ã‚‹FOREACH" +msgstr "é…列を巡回ã™ã‚‹ FOREACH" -#: pl_funcs.c:248 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "SQL ステートメント" -#: pl_funcs.c:250 -msgid "EXECUTE statement" -msgstr "EXECUTE ステートメント" - -#: pl_funcs.c:252 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" -msgstr "EXECUTE ステートメントを制御ã™ã‚‹ FOR" +msgstr "EXECUTE ステートメントを使ã£ãŸ FOR" -#: pl_gram.y:450 +#: pl_gram.y:485 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "ブロックラベル㯠DECLARE ã®å¾Œã§ã¯ãªãå‰ã«ç½®ã‹ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:470 +#: pl_gram.y:505 #, c-format msgid "collations are not supported by type %s" -msgstr "%såž‹ã§ã¯ç…§åˆé †åºã¯ã‚µãƒãƒ¼ãƒˆã•れã¾ã›ã‚“" +msgstr "%s åž‹ã§ã¯ç…§åˆé †åºã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#: pl_gram.y:485 +#: pl_gram.y:524 #, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã‚’ CONSTANT ã«ã¯ã§ãã¾ã›ã‚“" - -#: pl_gram.y:495 -#, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã‚’ NOT NULL ã«ã¯ã§ãã¾ã›ã‚“" - -#: pl_gram.y:506 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã®ãƒ‡ãƒ•ォルト値指定ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" +#| msgid "variable \"%s\" must have a numeric type" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "" +"NOT NULL宣言ã•れã¦ã„ã‚‹ãŸã‚ã€å¤‰æ•°\"%s\"ã¯ãƒ‡ãƒ•ォルト値をæŒã¤å¿…è¦ãŒã‚りã¾ã™" -#: pl_gram.y:651 pl_gram.y:666 pl_gram.y:692 +#: pl_gram.y:670 pl_gram.y:685 pl_gram.y:711 #, c-format msgid "variable \"%s\" does not exist" -msgstr "変数\"%s\"ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "変数 \"%s\" ã¯å­˜åœ¨ã—ã¾ã›ã‚“" -#: pl_gram.y:710 pl_gram.y:723 +#: pl_gram.y:729 pl_gram.y:757 msgid "duplicate declaration" msgstr "é‡è¤‡ã—ãŸå®£è¨€ã§ã™ã€‚" -#: pl_gram.y:901 +#: pl_gram.y:740 pl_gram.y:768 +#, c-format +msgid "variable \"%s\" shadows a previously defined variable" +msgstr "変数 \"%s\" ãŒäº‹å‰ã«å®šç¾©ã•れãŸå¤‰æ•°ã‚’ä¸å¯è¦–ã«ã—ã¦ã„ã¾ã™" + +#: pl_gram.y:984 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" -msgstr "GET STACKED DIAGNOSTICSã§ã¯è¨ºæ–­é …ç›®%sã¯è¨±ã•れã¾ã›ã‚“" +msgstr "GET STACKED DIAGNOSTICS ã§ã¯è¨ºæ–­é …ç›® %s ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -#: pl_gram.y:919 +#: pl_gram.y:1002 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" -msgstr "GET CURRENT DIAGNOSTICSã§ã¯è¨ºæ–­é …ç›®%sã¯è¨±ã•れã¾ã›ã‚“" +msgstr "GET CURRENT DIAGNOSTICS ã§ã¯è¨ºæ–­é …ç›® %s ã¯è¨±å¯ã•れã¦ã„ã¾ã›ã‚“" -#: pl_gram.y:1017 +#: pl_gram.y:1100 msgid "unrecognized GET DIAGNOSTICS item" msgstr "GET DIAGNOSTICS é …ç›®ãŒèªè­˜ã§ãã¾ã›ã‚“" -#: pl_gram.y:1028 pl_gram.y:3265 +#: pl_gram.y:1110 pl_gram.y:3509 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" ã¯ã‚¹ã‚«ãƒ©ãƒ¼å¤‰æ•°ã§ã¯ã‚りã¾ã›ã‚“" -#: pl_gram.y:1280 pl_gram.y:1474 +#: pl_gram.y:1358 pl_gram.y:1551 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" -msgstr "行をã¾ãŸãŒã‚‹ãƒ«ãƒ¼ãƒ—ã«ãŠã‘るループ変数ã¯ã€ãƒ¬ã‚³ãƒ¼ãƒ‰ã€è¡Œå¤‰æ•°ã€ã‚¹ã‚«ãƒ©ãƒ¼å¤‰æ•°ä¸¦ã³ã®ã„ãšã‚Œã‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#| msgid "" +#| "loop variable of loop over rows must be a record or row variable or list " +#| "of scalar variables" +msgid "" +"loop variable of loop over rows must be a record variable or list of scalar " +"variables" +msgstr "" +"行ã«å¯¾ã™ã‚‹ãƒ«ãƒ¼ãƒ—ã§ã®ãƒ«ãƒ¼ãƒ—変数ã¯ã€ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã¾ãŸã¯ã‚¹ã‚«ãƒ©ãƒ¼å¤‰æ•°ã®ãƒªã‚¹ãƒˆã§ãª" +"ã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:1314 +#: pl_gram.y:1392 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "カーソルを使ã£ãŸ FOR ループã«ã¯ã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆå¤‰æ•°ãŒï¼‘個ã ã‘å¿…è¦ã§ã™" -#: pl_gram.y:1321 +#: pl_gram.y:1399 #, c-format msgid "cursor FOR loop must use a bound cursor variable" -msgstr "カーソルを使ã£ãŸ FOR ループã§ã¯ã€ãれã«é–¢é€£ä»˜ã‘られãŸã‚«ãƒ¼ã‚½ãƒ«å¤‰æ•°ã‚’使用ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "" +"カーソルを使ã£ãŸ FOR ループã§ã¯ã€ãれã«é–¢é€£ä»˜ã‘られãŸã‚«ãƒ¼ã‚½ãƒ«å¤‰æ•°ã‚’使用ã—ãªã‘" +"れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:1405 +#: pl_gram.y:1486 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "整数を使ã£ãŸ FOR ループã«ã¯ã€ã‚¿ãƒ¼ã‚²ãƒƒãƒˆå¤‰æ•°ãŒï¼‘個ã ã‘å¿…è¦ã§ã™" -#: pl_gram.y:1441 +#: pl_gram.y:1522 #, c-format msgid "cannot specify REVERSE in query FOR loop" -msgstr "クエリーを使ã£ãŸ FOR ループã®ä¸­ã§ã¯ REVERSE ã¯æŒ‡å®šã§ãã¾ã›ã‚“" +msgstr "å•ã„åˆã‚ã›ã‚’使ã£ãŸ FOR ループã®ä¸­ã§ã¯ REVERSE ã¯æŒ‡å®šã§ãã¾ã›ã‚“" -#: pl_gram.y:1588 +#: pl_gram.y:1653 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" -msgstr "FOREACHã®ãƒ«ãƒ¼ãƒ—å¤‰æ•°ã¯æ—¢çŸ¥ã®å¤‰æ•°ã¾ãŸã¯å¤‰æ•°ã®ãƒªã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "" +"FOREACH ã®ãƒ«ãƒ¼ãƒ—変数ã¯ã€æ—¢çŸ¥ã®å¤‰æ•°ã¾ãŸã¯å¤‰æ•°ã®ãƒªã‚¹ãƒˆã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:1640 pl_gram.y:1677 pl_gram.y:1725 pl_gram.y:2721 pl_gram.y:2802 -#: pl_gram.y:2913 pl_gram.y:3666 +#: pl_gram.y:1694 +#, c-format +msgid "" +"there is no label \"%s\" attached to any block or loop enclosing this " +"statement" +msgstr "" +"ã“ã®ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã‚’囲むブロックやループã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸ \"%s\" ã¨ã„ã†ãƒ©ãƒ™ãƒ«" +"ã¯ã‚りã¾ã›ã‚“。" + +#: pl_gram.y:1702 +#, c-format +msgid "block label \"%s\" cannot be used in CONTINUE" +msgstr "ブロックラベル \"%s\" 㯠CONTINUE ã®ä¸­ã§ã¯ä½¿ãˆã¾ã›ã‚“。" + +#: pl_gram.y:1717 +#, c-format +msgid "EXIT cannot be used outside a loop, unless it has a label" +msgstr "ラベルã®ãªã„ EXIT ã¯ã€ãƒ«ãƒ¼ãƒ—ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" + +#: pl_gram.y:1718 +#, c-format +msgid "CONTINUE cannot be used outside a loop" +msgstr "CONTINUE ã¯ãƒ«ãƒ¼ãƒ—ã®å¤–ã§ã¯ä½¿ãˆã¾ã›ã‚“" + +#: pl_gram.y:1742 pl_gram.y:1779 pl_gram.y:1827 pl_gram.y:2959 pl_gram.y:3042 +#: pl_gram.y:3153 pl_gram.y:3910 msgid "unexpected end of function definition" msgstr "予期ã—ãªã„関数定義ã®çµ‚端ã«é”ã—ã¾ã—ãŸ" -#: pl_gram.y:1745 pl_gram.y:1769 pl_gram.y:1785 pl_gram.y:1791 pl_gram.y:1880 -#: pl_gram.y:1888 pl_gram.y:1902 pl_gram.y:1997 pl_gram.y:2178 pl_gram.y:2261 -#: pl_gram.y:2394 pl_gram.y:3508 pl_gram.y:3569 pl_gram.y:3647 +#: pl_gram.y:1847 pl_gram.y:1871 pl_gram.y:1887 pl_gram.y:1893 pl_gram.y:2010 +#: pl_gram.y:2018 pl_gram.y:2032 pl_gram.y:2126 pl_gram.y:2361 pl_gram.y:2455 +#: pl_gram.y:2613 pl_gram.y:3752 pl_gram.y:3813 pl_gram.y:3891 msgid "syntax error" msgstr "構文エラー" -#: pl_gram.y:1773 pl_gram.y:1775 pl_gram.y:2182 pl_gram.y:2184 +#: pl_gram.y:1875 pl_gram.y:1877 pl_gram.y:2365 pl_gram.y:2367 msgid "invalid SQLSTATE code" msgstr "無効㪠SQLSTATE コードã§ã™" -#: pl_gram.y:1944 +#: pl_gram.y:2074 msgid "syntax error, expected \"FOR\"" -msgstr "構文エラー。\"FOR\" を期待ã—ã¦ã„ã¾ã—ãŸ" +msgstr "構文エラー。\"FOR\" ãŒç¾ã‚Œã‚‹ã¹ãã§ã—ãŸã€‚" -#: pl_gram.y:2006 +#: pl_gram.y:2135 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "FETCH ステートメントã¯è¤‡æ•°è¡Œã‚’è¿”ã›ã¾ã›ã‚“" -#: pl_gram.y:2062 +#: pl_gram.y:2245 #, c-format msgid "cursor variable must be a simple variable" msgstr "カーソル変数ã¯å˜ç´”変数ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:2068 +#: pl_gram.y:2251 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "変数 \"%s\" 㯠cursor åž‹ã¾ãŸã¯ refcursor åž‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: pl_gram.y:2236 -msgid "label does not exist" -msgstr "ラベルãŒå­˜åœ¨ã—ã¾ã›ã‚“" - -#: pl_gram.y:2365 pl_gram.y:2376 +#: pl_gram.y:2584 pl_gram.y:2595 #, c-format msgid "\"%s\" is not a known variable" -msgstr "\"%s\"ã¯æ—¢çŸ¥ã®å¤‰æ•°ã§ã¯ã‚りã¾ã›ã‚“" +msgstr "\"%s\" ã¯æ—¢çŸ¥ã®å¤‰æ•°ã§ã¯ã‚りã¾ã›ã‚“" -#: pl_gram.y:2480 pl_gram.y:2490 pl_gram.y:2645 +#: pl_gram.y:2699 pl_gram.y:2709 pl_gram.y:2864 msgid "mismatched parentheses" -msgstr "カッコãŒå¯¾å¿œã—ã¦ã„ã¾ã›ã‚“" +msgstr "括弧ãŒå¯¾å¿œã—ã¦ã„ã¾ã›ã‚“" -#: pl_gram.y:2494 +#: pl_gram.y:2713 #, c-format msgid "missing \"%s\" at end of SQL expression" -msgstr "SQL 表ç¾å¼ã®çµ‚端㫠\"%s\" ãŒã‚りã¾ã›ã‚“" +msgstr "SQL 表ç¾å¼ã®çµ‚ã‚り㫠\"%s\" ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:2500 +#: pl_gram.y:2719 #, c-format msgid "missing \"%s\" at end of SQL statement" -msgstr "SQL ステートメントã®çµ‚端㫠\"%s\" ãŒã‚りã¾ã›ã‚“" +msgstr "SQL ステートメントã®çµ‚ã‚り㫠\"%s\" ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:2517 +#: pl_gram.y:2736 msgid "missing expression" msgstr "表ç¾å¼ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:2519 +#: pl_gram.y:2738 msgid "missing SQL statement" -msgstr "SQLステートメントãŒã‚りã¾ã›ã‚“" +msgstr "SQL ステートメントãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:2647 +#: pl_gram.y:2866 msgid "incomplete data type declaration" msgstr "データ型ã®å®šç¾©ãŒä¸å®Œå…¨ã§ã™" -#: pl_gram.y:2670 +#: pl_gram.y:2889 msgid "missing data type declaration" msgstr "データ型ã®å®šç¾©ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:2726 +#: pl_gram.y:2967 msgid "INTO specified more than once" msgstr "INTO ãŒè¤‡æ•°å›žæŒ‡å®šã•れã¦ã„ã¾ã™" -#: pl_gram.y:2894 +#: pl_gram.y:3134 msgid "expected FROM or IN" -msgstr "FROM ã‚‚ã—ã㯠IN を期待ã—ã¦ã„ã¾ã—ãŸ" +msgstr "FROM ã‚‚ã—ã㯠IN ãŒæ¥ã‚‹ã¹ãã§ã—ãŸ" -#: pl_gram.y:2954 +#: pl_gram.y:3194 #, c-format msgid "RETURN cannot have a parameter in function returning set" -msgstr "値ã®ã‚»ãƒƒãƒˆã‚’è¿”ã™é–¢æ•°ã§ã¯ã€RETURNã«ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" +msgstr "集åˆã‚’è¿”ã™é–¢æ•°ã§ã¯ã€RETURN ã«ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" -#: pl_gram.y:2955 +#: pl_gram.y:3195 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "RETURN NEXT ã‚‚ã—ã㯠RETURN QUERY を使用ã—ã¦ãã ã•ã„" -#: pl_gram.y:2963 +#: pl_gram.y:3205 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "OUT パラメータã®ãªã„関数ã§ã¯ã€RETURN ã«ã¯ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" +#| msgid "RETURN cannot have a parameter in function returning set" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "プロシージャãªã„ã®RETURNã¯ãƒ‘ラメータをå–ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“" -#: pl_gram.y:2972 +#: pl_gram.y:3210 #, c-format msgid "RETURN cannot have a parameter in function returning void" -msgstr "void ã‚’è¿”ã™é–¢æ•°ã§ã¯ã€RETURN ã«ã¯ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" +msgstr "void ã‚’è¿”ã™é–¢æ•°ã§ã¯ã€RETURN ã«ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" -#: pl_gram.y:3034 +#: pl_gram.y:3219 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "OUT パラメータã®ãªã„関数ã§ã¯ã€RETURN ã«ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" + +#: pl_gram.y:3281 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" -msgstr "OUT パラメータã®ãªã„関数ã§ã¯ã€RETURN NEXT ã«ã¯ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" +msgstr "OUT パラメータ付ãã®é–¢æ•°ã§ã¯ã€RETURN NEXT ã«ãƒ‘ラメータを指定ã§ãã¾ã›ã‚“" -#: pl_gram.y:3134 +#: pl_gram.y:3388 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\" 㯠CONSTANT ã¨ã—ã¦å®£è¨€ã•れã¦ã„ã¾ã™" +#| msgid "\"%s\" is declared CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "変数\"%s\" ã¯CONSTANTã¨ã—ã¦å®šç¾©ã•れã¦ã„ã¾ã™" -#: pl_gram.y:3196 pl_gram.y:3208 +#: pl_gram.y:3451 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "レコードもã—ãã¯è¡Œå¤‰æ•°ã¯ã€è¤‡æ•°é …目をæŒã¤ INTO リストã®ä¸€éƒ¨åˆ†ã¨ã—ã¦ã¯æŒ‡å®šã§ãã¾ã›ã‚“" +#| msgid "record or row variable cannot be part of multiple-item INTO list" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "レコード変数ã¯ã€è¤‡æ•°é …目をæŒã¤ INTO リストã§ã¯ä½¿ãˆã¾ã›ã‚“" -#: pl_gram.y:3253 +#: pl_gram.y:3497 #, c-format msgid "too many INTO variables specified" msgstr "INTO å¤‰æ•°ã®æŒ‡å®šãŒå¤šã™ãŽã¾ã™" -#: pl_gram.y:3461 +#: pl_gram.y:3705 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "ラベル無ã—ブロックã§çµ‚端ラベル \"%s\" ãŒæŒ‡å®šã•れã¾ã—ãŸ" -#: pl_gram.y:3468 +#: pl_gram.y:3712 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "終端ラベル \"%s\" ãŒãƒ–ロックã®ãƒ©ãƒ™ãƒ« \"%s\" ã¨ç•°ãªã‚Šã¾ã™" -#: pl_gram.y:3503 +#: pl_gram.y:3747 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "カーソル \"%s\" ã«å¼•æ•°ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:3517 +#: pl_gram.y:3761 #, c-format msgid "cursor \"%s\" has arguments" msgstr "カーソル \"%s\" ã«å¼•æ•°ãŒã¤ã„ã¦ã„ã¾ã™" -#: pl_gram.y:3559 +#: pl_gram.y:3803 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" -msgstr "カーソル\"%s\"ã«\"%s\"ã¨ã„ã†åå‰ã®å¼•æ•°ãŒã‚りã¾ã›ã‚“" +msgstr "カーソル \"%s\" ã« \"%s\" ã¨ã„ã†åå‰ã®å¼•æ•°ãŒã‚りã¾ã›ã‚“" -#: pl_gram.y:3579 +#: pl_gram.y:3823 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" -msgstr "カーソル\"%2$s\"ã®ãƒ‘ラメータ\"%1$s\"ã®å€¤ãŒè¤‡æ•°æŒ‡å®šã•れã¾ã—ãŸ" +msgstr "カーソル \"%2$s\" ã®ãƒ‘ラメータ \"%1$s\" ã®å€¤ãŒè¤‡æ•°å€‹æŒ‡å®šã•れã¾ã—ãŸ" -#: pl_gram.y:3604 +#: pl_gram.y:3848 #, c-format msgid "not enough arguments for cursor \"%s\"" -msgstr "カーソル\"%s\"ã®å¼•æ•°ãŒä¸è¶³ã—ã¦ã„ã¾ã™" +msgstr "カーソル \"%s\" ã®å¼•æ•°ãŒä¸è¶³ã—ã¦ã„ã¾ã™" -#: pl_gram.y:3611 +#: pl_gram.y:3855 #, c-format msgid "too many arguments for cursor \"%s\"" -msgstr "カーソル\"%s\"ã«å¯¾ã™ã‚‹å¼•æ•°ãŒå¤šã™ãŽã¾ã™" +msgstr "カーソル \"%s\" ã«å¯¾ã™ã‚‹å¼•æ•°ãŒå¤šã™ãŽã¾ã™" -#: pl_gram.y:3698 +#: pl_gram.y:3942 msgid "unrecognized RAISE statement option" msgstr "RAISE ステートメントã®ã‚ªãƒ—ションをèªè­˜ã§ãã¾ã›ã‚“" -#: pl_gram.y:3702 +#: pl_gram.y:3946 msgid "syntax error, expected \"=\"" msgstr "構文エラー。\"=\" を期待ã—ã¦ã„ã¾ã—ãŸ" -#: pl_handler.c:61 -msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." -msgstr "PL/pgSQL変数åã¨ãƒ†ãƒ¼ãƒ–ルã®ã‚«ãƒ©ãƒ åã®é–“ã®è¡çªå‡¦ç†ã‚’設定ã—ã¦ãã ã•ã„" +#: pl_gram.y:3987 +#, c-format +msgid "too many parameters specified for RAISE" +msgstr "RAISE ã«æŒ‡å®šã•れãŸãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒ¼ã®æ•°ãŒå¤šã™ãŽã¾ã™" + +#: pl_gram.y:3991 +#, c-format +msgid "too few parameters specified for RAISE" +msgstr "RAISE ã«æŒ‡å®šã•れãŸãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ãƒ¼ã®æ•°ãŒè¶³ã‚Šã¾ã›ã‚“" + +#: pl_handler.c:154 +msgid "" +"Sets handling of conflicts between PL/pgSQL variable names and table column " +"names." +msgstr "PL/pgSQL 変数åã¨ãƒ†ãƒ¼ãƒ–ルã®ã‚«ãƒ©ãƒ åã®é–“ã®è¡çªæ™‚処ç†ã‚’設定ã—ã¾ã™ã€‚" + +#: pl_handler.c:163 +msgid "" +"Print information about parameters in the DETAIL part of the error messages " +"generated on INTO ... STRICT failures." +msgstr "" +"INTO ... STRICT 失敗時ã«ç”Ÿæˆã•れãŸã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã® DETAIL 部分ã®ãƒ‘ラメー" +"ター情報を表示ã—ã¾ã™ã€‚" + +#: pl_handler.c:171 +msgid "Perform checks given in ASSERT statements." +msgstr "ASSERT ã‚¹ãƒ†ãƒ¼ãƒˆãƒ¡ãƒ³ãƒˆã§æŒ‡å®šã•れãŸãƒã‚§ãƒƒã‚¯ã‚’実行ã—ã¾ã™ã€‚" + +#: pl_handler.c:179 +msgid "List of programming constructs that should produce a warning." +msgstr "生æˆã•れãŸãƒ—ログラムã®ä¸­ã§ã€è­¦å‘Šã‚’発生ã™ã¹ã部分ã®ä¸€è¦§ã§ã™ã€‚" + +#: pl_handler.c:189 +msgid "List of programming constructs that should produce an error." +msgstr "生æˆã•れãŸãƒ—ログラムã®ä¸­ã§ã€ã‚¨ãƒ©ãƒ¼ã‚’発生ã™ã¹ã部分ã®ä¸€è¦§ã§ã™ã€‚" #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:553 +#: pl_scanner.c:630 #, c-format msgid "%s at end of input" msgstr "å…¥åŠ›ã®æœ€å¾Œã§ %s" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:569 +#: pl_scanner.c:646 #, c-format msgid "%s at or near \"%s\"" msgstr "\"%2$s\" ã‚‚ã—ãã¯ãã®è¿‘辺㧠%1$s" -#~ msgid "RETURN must specify a record or row variable in function returning row" -#~ msgstr "行を返ã™é–¢æ•°ã§ã¯ã€RETURN ã«ãƒ¬ã‚³ãƒ¼ãƒ‰ã¾ãŸã¯è¡Œå¤‰æ•°ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã®ãƒ‡ãƒ•ォルト値指定ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“" -#~ msgid "syntax error; also virtual memory exhausted" -#~ msgstr "構文エラー: 仮想メモリも枯渇ã—ã¾ã—ãŸ" +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã‚’ NOT NULL ã«ã¯ã§ãã¾ã›ã‚“" -#~ msgid "parser stack overflow" -#~ msgstr "パーサã®ã‚¹ã‚¿ãƒƒã‚¯ãŒã‚ªãƒ¼ãƒãƒ¼ãƒ•ローã—ã¾ã—ãŸ" +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "行ã¾ãŸã¯ãƒ¬ã‚³ãƒ¼ãƒ‰å¤‰æ•°ã¯ CONSTANT ã«ã¯ã§ãã¾ã›ã‚“" -#~ msgid "relation \"%s.%s\" does not exist" -#~ msgstr "リレーション \"%s.%s\" ãŒã‚りã¾ã›ã‚“" +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "代ã‚り㫠EXCEPTION å¥ã‚’伴ㆠBEGIN ブロックを使用ã—ã¦ãã ã•ã„" -#~ msgid "RETURN NEXT must specify a record or row variable in function returning row" -#~ msgstr "行を返ã™é–¢æ•°ã§ã¯ã€RETURN NEXT ã«ãƒ¬ã‚³ãƒ¼ãƒ‰ã¾ãŸã¯è¡Œå¤‰æ•°ã‚’指定ã—ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" +#~ msgstr "" +#~ "変数 \"%s\" 㯠NOT NULL ã¨ã—ã¦å®£è¨€ã•れã¦ã„ã‚‹ãŸã‚ã€ãƒ‡ãƒ•ォルト値を NULL ã«ã™" +#~ "ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" -#~ msgid "syntax error: cannot back up" -#~ msgstr "構文エラー: ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—ã§ãã¾ã›ã‚“" +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "リレーション \"%s\" ã¯ãƒ†ãƒ¼ãƒ–ルã§ã¯ã‚りã¾ã›ã‚“" diff --git a/src/pl/plpgsql/src/po/ko.po b/src/pl/plpgsql/src/po/ko.po index 95d9dc9d242..d11c333359b 100644 --- a/src/pl/plpgsql/src/po/ko.po +++ b/src/pl/plpgsql/src/po/ko.po @@ -4,10 +4,10 @@ # Ioseph Kim , 2010 msgid "" msgstr "" -"Project-Id-Version: plpgsql (PostgreSQL 9.6)\n" +"Project-Id-Version: plpgsql (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 19:23+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 17:02+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -16,821 +16,819 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: pl_comp.c:430 pl_handler.c:450 +#: pl_comp.c:434 pl_handler.c:457 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "PL/pgSQL í•¨ìˆ˜ì— %s 형ì‹ì„ 사용할 수 ì—†ìŒ" -#: pl_comp.c:511 +#: pl_comp.c:522 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "ë‹¤í˜•ì  í•¨ìˆ˜ \"%s\"ì˜ ì‹¤ì œ 반환 형ì‹ì„ 확ì¸í•  수 ì—†ìŒ" -#: pl_comp.c:541 +#: pl_comp.c:552 #, c-format msgid "trigger functions can only be called as triggers" msgstr "트리거 함수는 트리거로만 í˜¸ì¶œë  ìˆ˜ 있ìŒ" -#: pl_comp.c:545 pl_handler.c:435 +#: pl_comp.c:556 pl_handler.c:441 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "PL/pgSQL 함수는 %s 형ì‹ì„ 반환할 수 ì—†ìŒ" -#: pl_comp.c:586 +#: pl_comp.c:595 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "트리거 함수는 ì„ ì–¸ëœ ì¸ìˆ˜ë¥¼ í¬í•¨í•  수 ì—†ìŒ" -#: pl_comp.c:587 +#: pl_comp.c:596 #, c-format -msgid "" -"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " -"instead." +msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "대신 TG_NARGS ë° TG_ARGV를 통해 íŠ¸ë¦¬ê±°ì˜ ì¸ìˆ˜ì— 액세스할 수 있습니다." -#: pl_comp.c:689 +#: pl_comp.c:719 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "ì´ë²¤íЏ 트리거 함수는 ì„ ì–¸ëœ ì¸ìž(declare argument)를 사용할 수 ì—†ìŒ" -#: pl_comp.c:940 +#: pl_comp.c:976 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "PL/pgSQL 함수 \"%s\" 컴파ì¼(%d번째 줄 근처)" -#: pl_comp.c:963 +#: pl_comp.c:999 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "\"%s\" 매개 변수가 여러 번 사용 ë¨" -#: pl_comp.c:1073 +#: pl_comp.c:1109 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "ì—´ 참조 \"%s\" ê°€ 명확하지 않습니다." -#: pl_comp.c:1075 +#: pl_comp.c:1111 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "PL/pgSQL 변수명ë„, í…Œì´ë¸” 칼럼 ì´ë¦„ë„ ì•„ë‹ˆì—¬ì•¼ 함" -#: pl_comp.c:1255 pl_comp.c:1283 pl_exec.c:4393 pl_exec.c:4742 pl_exec.c:4827 -#: pl_exec.c:4918 +#: pl_comp.c:1294 pl_exec.c:5048 pl_exec.c:5413 pl_exec.c:5500 pl_exec.c:5591 +#: pl_exec.c:6509 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "\"%s\" ë ˆì½”ë“œì— \"%s\" 필드가 ì—†ìŒ" -#: pl_comp.c:1814 +#: pl_comp.c:1756 #, c-format msgid "relation \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ë¦´ë ˆì´ì…˜(relation)ì´ ì—†ìŠµë‹ˆë‹¤" -#: pl_comp.c:1923 +#: pl_comp.c:1848 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "\"%s\" ë³€ìˆ˜ì— ì˜ì‚¬ í˜•ì‹ %sì´(ê°€) 있ìŒ" -#: pl_comp.c:1990 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "\"%s\" 관계가 í…Œì´ë¸”ì´ ì•„ë‹˜" - -#: pl_comp.c:2150 +#: pl_comp.c:2026 #, c-format msgid "type \"%s\" is only a shell" msgstr "ìžë£Œí˜• \"%s\" 는 오로지 shell ì—ë§Œ 있습니다. " -#: pl_comp.c:2244 pl_comp.c:2297 +#: pl_comp.c:2123 pl_comp.c:2176 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "ì¸ì‹í•  수 없는 예외 ì¡°ê±´ \"%s\"" -#: pl_comp.c:2504 +#: pl_comp.c:2390 #, c-format -msgid "" -"could not determine actual argument type for polymorphic function \"%s\"" +msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "ë‹¤í˜•ì  í•¨ìˆ˜ \"%s\"ì˜ ì‹¤ì œ ì¸ìˆ˜ 형ì‹ì„ 확ì¸í•  수 ì—†ìŒ" -#: pl_exec.c:324 pl_exec.c:612 pl_exec.c:872 +#: pl_exec.c:474 pl_exec.c:886 pl_exec.c:1103 msgid "during initialization of execution state" msgstr "실행 ìƒíƒœë¥¼ 초기화하는 ë™ì•ˆ" -#: pl_exec.c:331 +#: pl_exec.c:480 msgid "while storing call arguments into local variables" msgstr "호출 ì¸ìˆ˜ë¥¼ 로컬 ë³€ìˆ˜ì— ì €ìž¥í•˜ëŠ” ë™ì•ˆ" -#: pl_exec.c:416 pl_exec.c:760 +#: pl_exec.c:568 pl_exec.c:938 msgid "during function entry" msgstr "함수를 시작하는 ë™ì•ˆ" -#: pl_exec.c:441 +#: pl_exec.c:593 #, c-format msgid "control reached end of function without RETURN" msgstr "ì»¨íŠ¸ë¡¤ì´ RETURN ì—†ì´ í•¨ìˆ˜ ëì— ë„달함" -#: pl_exec.c:448 +#: pl_exec.c:600 msgid "while casting return value to function's return type" msgstr "í•¨ìˆ˜ì˜ ë°˜í™˜ 형ì‹ìœ¼ë¡œ 반환 ê°’ì„ í˜•ë³€í™˜í•˜ëŠ” ë™ì•ˆ" -#: pl_exec.c:461 pl_exec.c:2938 +#: pl_exec.c:613 pl_exec.c:3511 #, c-format msgid "set-valued function called in context that cannot accept a set" -msgstr "" -"set-values 함수(í…Œì´ë¸” 리턴 함수)ê°€ set ì •ì˜ ì—†ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤ (í…Œì´ë¸”ê³¼ í•´" -"당 ì—´ alias 지정하세요)" +msgstr "set-values 함수(í…Œì´ë¸” 리턴 함수)ê°€ set ì •ì˜ ì—†ì´ ì‚¬ìš©ë˜ì—ˆìŠµë‹ˆë‹¤ (í…Œì´ë¸”ê³¼ 해당 ì—´ alias 지정하세요)" -#: pl_exec.c:499 pl_exec.c:2779 -msgid "returned record type does not match expected record type" -msgstr "ë°˜í™˜ëœ ë ˆì½”ë“œ 형ì‹ì´ 필요한 레코드 형ì‹ê³¼ ì¼ì¹˜í•˜ì§€ 않ìŒ" - -#: pl_exec.c:554 pl_exec.c:789 pl_exec.c:907 +#: pl_exec.c:739 pl_exec.c:967 pl_exec.c:1128 msgid "during function exit" msgstr "함수를 종료하는 ë™ì•ˆ" -#: pl_exec.c:785 pl_exec.c:903 +#: pl_exec.c:794 pl_exec.c:833 pl_exec.c:3356 +msgid "returned record type does not match expected record type" +msgstr "ë°˜í™˜ëœ ë ˆì½”ë“œ 형ì‹ì´ 필요한 레코드 형ì‹ê³¼ ì¼ì¹˜í•˜ì§€ 않ìŒ" + +#: pl_exec.c:963 pl_exec.c:1124 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "ì»¨íŠ¸ë¡¤ì´ RETURN ì—†ì´ íŠ¸ë¦¬ê±° 프로시저 ëì— ë„달함" -#: pl_exec.c:794 +#: pl_exec.c:972 #, c-format msgid "trigger procedure cannot return a set" msgstr "트리거 프로시저는 ì§‘í•©ì„ ë°˜í™˜í•  수 ì—†ìŒ" -#: pl_exec.c:816 -msgid "" -"returned row structure does not match the structure of the triggering table" +#: pl_exec.c:1011 pl_exec.c:1039 +msgid "returned row structure does not match the structure of the triggering table" msgstr "ë°˜í™˜ëœ í–‰ 구조가 트리거하는 í…Œì´ë¸”ì˜ êµ¬ì¡°ì™€ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: pl_exec.c:954 +#. translator: last %s is a phrase such as "during statement block +#. local variable initialization" +#. +#: pl_exec.c:1176 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "PL/pgSQL 함수 \"%s\" ì˜ %d번째 줄 %s" -#: pl_exec.c:965 +#. translator: last %s is a phrase such as "while storing call +#. arguments into local variables" +#. +#: pl_exec.c:1187 #, c-format msgid "PL/pgSQL function %s %s" msgstr "PL/pgSQL 함수 %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:973 +#: pl_exec.c:1195 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "PL/pgSQL 함수 \"%s\" ì˜ %d번째 %s" -#: pl_exec.c:979 +#: pl_exec.c:1201 #, c-format msgid "PL/pgSQL function %s" msgstr "PL/pgSQL 함수 %s" -#: pl_exec.c:1089 +#: pl_exec.c:1539 msgid "during statement block local variable initialization" msgstr "문 ë¸”ë¡ ë¡œì»¬ 변수를 초기화하는 ë™ì•ˆ" -#: pl_exec.c:1128 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "NOT NULLì´ ì„ ì–¸ëœ \"%s\" ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì´ NULL로 ì„¤ì •ë  ìˆ˜ ì—†ìŒ" - -#: pl_exec.c:1178 +#: pl_exec.c:1637 msgid "during statement block entry" msgstr "문 블ë¡ì„ 시작하는 ë™ì•ˆ" -#: pl_exec.c:1199 +#: pl_exec.c:1669 msgid "during statement block exit" msgstr "문 블ë¡ì„ 종료하는 ë™ì•ˆ" -#: pl_exec.c:1242 +#: pl_exec.c:1707 msgid "during exception cleanup" msgstr "예외를 정리하는 ë™ì•ˆ" -#: pl_exec.c:1593 +#: pl_exec.c:2234 pl_exec.c:2248 +#, c-format +msgid "argument %d is an output argument but is not writable" +msgstr "%d ì¸ìžëŠ” 출력 ì¸ìžì¸ë°, ê°’ ë³€ê²½ì´ ë¶ˆê°€ëŠ¥ 함" + +#: pl_exec.c:2290 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS êµ¬ë¬¸ì€ ì˜ˆì™¸ì²˜ë¦¬ 헨들러 ë°–ì—서 사용할 수 ì—†ìŒ" -#: pl_exec.c:1789 +#: pl_exec.c:2495 #, c-format msgid "case not found" msgstr "사례를 찾지 못함" -#: pl_exec.c:1790 +#: pl_exec.c:2496 #, c-format msgid "CASE statement is missing ELSE part." msgstr "CASE ë¬¸ì— ELSE ë¶€ë¶„ì´ ëˆ„ë½ë˜ì—ˆìŠµë‹ˆë‹¤." -#: pl_exec.c:1944 +#: pl_exec.c:2589 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "FOR ë£¨í”„ì˜ í•˜í•œì€ nullì¼ ìˆ˜ ì—†ìŒ" -#: pl_exec.c:1960 +#: pl_exec.c:2605 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "FOR ë£¨í”„ì˜ ìƒí•œì€ nullì¼ ìˆ˜ ì—†ìŒ" -#: pl_exec.c:1978 +#: pl_exec.c:2623 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "FOR ë£¨í”„ì˜ BY ê°’ì€ nullì¼ ìˆ˜ ì—†ìŒ" -#: pl_exec.c:1984 +#: pl_exec.c:2629 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "FOR ë£¨í”„ì˜ BY ê°’ì€ 0보다 커야 함" -#: pl_exec.c:2153 pl_exec.c:3910 +#: pl_exec.c:2763 pl_exec.c:4478 #, c-format msgid "cursor \"%s\" already in use" msgstr "\"%s\" 커서가 ì´ë¯¸ 사용 중임" -#: pl_exec.c:2176 pl_exec.c:3972 +#: pl_exec.c:2786 pl_exec.c:4543 #, c-format msgid "arguments given for cursor without arguments" msgstr "ì¸ìˆ˜ê°€ 없는 ì»¤ì„œì— ì¸ìˆ˜ê°€ 제공ë¨" -#: pl_exec.c:2195 pl_exec.c:3991 +#: pl_exec.c:2805 pl_exec.c:4562 #, c-format msgid "arguments required for cursor" msgstr "ì»¤ì„œì— ì¸ìˆ˜ í•„ìš”" -#: pl_exec.c:2280 +#: pl_exec.c:2892 #, c-format msgid "FOREACH expression must not be null" msgstr "FOREACH êµ¬ë¬¸ì€ null ì´ ì•„ë‹ˆì—¬ì•¼ 함" -#: pl_exec.c:2286 +#: pl_exec.c:2907 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "FOREACH 구문ì—서는 ë°°ì—´ì´ ì‚¬ìš©ë©ë‹ˆë‹¤. ì‚¬ìš©ëœ ìžë£Œí˜• %s" -#: pl_exec.c:2303 +#: pl_exec.c:2924 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "slice dimension (%d) ê°’ì´ ë²”ìœ„ë¥¼ 벗어남, 0..%d" -#: pl_exec.c:2330 +#: pl_exec.c:2951 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "FOREACH ... SLICE 루프 변수는 ë°°ì—´ ìžë£Œí˜•ì´ì–´ì•¼ 함" -#: pl_exec.c:2334 +#: pl_exec.c:2955 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "FOREACH 반복 변수는 ë°°ì—´í˜•ì´ ì•„ë‹ˆì—¬ì•¼ 함" -#: pl_exec.c:2522 pl_exec.c:2604 pl_exec.c:2771 +#: pl_exec.c:3117 pl_exec.c:3174 pl_exec.c:3349 #, c-format -msgid "" -"cannot return non-composite value from function returning composite type" -msgstr "" -"í•¨ìˆ˜ì˜ ë°˜í™˜ê°’ì´ ë³µí•© ìžë£Œí˜•ì¸ë°, 복합 ìžë£Œí˜•아닌 ìžë£Œí˜•ì„ ë°˜í™˜í•˜ë ¤ê³  함" +msgid "cannot return non-composite value from function returning composite type" +msgstr "í•¨ìˆ˜ì˜ ë°˜í™˜ê°’ì´ ë³µí•© ìžë£Œí˜•ì¸ë°, 복합 ìžë£Œí˜•아닌 ìžë£Œí˜•ì„ ë°˜í™˜í•˜ë ¤ê³  함" -#: pl_exec.c:2648 pl_gram.y:3190 +#: pl_exec.c:3213 pl_gram.y:3266 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "SETOF 함수가 아닌 함수ì—서 RETURN NEXT를 사용할 수 ì—†ìŒ" -#: pl_exec.c:2682 pl_exec.c:2813 +#: pl_exec.c:3254 pl_exec.c:3386 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "RETURN NEXTì— ìž˜ëª»ëœ ê²°ê³¼ 형ì‹ì´ 제공ë¨" -#: pl_exec.c:2711 pl_exec.c:4380 pl_exec.c:4709 pl_exec.c:4735 pl_exec.c:4801 -#: pl_exec.c:4820 pl_exec.c:4888 pl_exec.c:4911 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "\"%s\" 레코드가 ì•„ì§ í• ë‹¹ë˜ì§€ 않ìŒ" - -#: pl_exec.c:2713 pl_exec.c:4382 pl_exec.c:4711 pl_exec.c:4737 pl_exec.c:4803 -#: pl_exec.c:4822 pl_exec.c:4890 pl_exec.c:4913 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "ì•„ì§ í• ë‹¹ë˜ì§€ ì•Šì€ ë ˆì½”ë“œì˜ íŠœí”Œ 구조는 미정입니다." - -#: pl_exec.c:2717 pl_exec.c:2737 +#: pl_exec.c:3292 pl_exec.c:3313 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "RETURN NEXTì— ìž˜ëª»ëœ ë ˆì½”ë“œ 형ì‹ì´ 제공ë¨" -#: pl_exec.c:2832 +#: pl_exec.c:3405 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXTì— ë§¤ê°œ 변수 í•„ìš”" -#: pl_exec.c:2865 pl_gram.y:3252 +#: pl_exec.c:3431 pl_gram.y:3329 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "SETOF 함수가 아닌 함수ì—서 RETURN QUERY를 사용할 수 ì—†ìŒ" -#: pl_exec.c:2886 +#: pl_exec.c:3455 msgid "structure of query does not match function result type" msgstr "쿼리 구조가 함수 ê²°ê³¼ 형ì‹ê³¼ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: pl_exec.c:2966 pl_exec.c:3096 +#: pl_exec.c:3539 pl_exec.c:3677 #, c-format msgid "RAISE option already specified: %s" msgstr "RAISE ì˜µì…˜ì´ ì´ë¯¸ 지정ë¨: %s" -#: pl_exec.c:2999 +#: pl_exec.c:3573 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "매개 변수 없는 RAISE를 예외 처리기 ì™¸ë¶€ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: pl_exec.c:3086 +#: pl_exec.c:3667 #, c-format msgid "RAISE statement option cannot be null" msgstr "RAISE 문 ì˜µì…˜ì´ nullì¼ ìˆ˜ ì—†ìŒ" -#: pl_exec.c:3155 +#: pl_exec.c:3737 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3226 +#: pl_exec.c:3792 #, c-format msgid "assertion failed" msgstr "assertion 실패" -#: pl_exec.c:3416 pl_exec.c:3560 pl_exec.c:3749 +#: pl_exec.c:4129 pl_exec.c:4316 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "PL/pgSQLì˜ í´ë¼ì´ì–¸íŠ¸ì™€ ìƒí˜¸ 복사할 수 ì—†ìŒ" -#: pl_exec.c:3420 pl_exec.c:3564 pl_exec.c:3753 -#, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "PL/pgSQLì˜ íŠ¸ëžœìž­ì…˜ì„ ì‹œìž‘/종료할 수 ì—†ìŒ" - -#: pl_exec.c:3421 pl_exec.c:3565 pl_exec.c:3754 +#: pl_exec.c:4135 #, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "대신 BEGIN 블ë¡ì„ EXCEPTION 절과 함께 사용하십시오." +msgid "unsupported transaction command in PL/pgSQL" +msgstr "PL/pgSQL 안ì—서는 ì§€ì›í•˜ì§€ 않는 트랜잭션 명령" -#: pl_exec.c:3588 pl_exec.c:3778 +#: pl_exec.c:4159 pl_exec.c:4346 #, c-format msgid "INTO used with a command that cannot return data" msgstr "ë°ì´í„°ë¥¼ 반환할 수 없는 명령과 함께 INTOê°€ 사용ë¨" -#: pl_exec.c:3616 pl_exec.c:3806 +#: pl_exec.c:4182 pl_exec.c:4369 #, c-format msgid "query returned no rows" msgstr "쿼리ì—서 í–‰ì„ ë°˜í™˜í•˜ì§€ 않ìŒ" -#: pl_exec.c:3635 pl_exec.c:3825 +#: pl_exec.c:4201 pl_exec.c:4388 #, c-format msgid "query returned more than one row" msgstr "쿼리ì—서 ë‘ ê°œ ì´ìƒì˜ í–‰ì„ ë°˜í™˜" -#: pl_exec.c:3652 +#: pl_exec.c:4218 #, c-format msgid "query has no destination for result data" msgstr "ì¿¼ë¦¬ì— ê²°ê³¼ ë°ì´í„°ì˜ 대ìƒì´ ì—†ìŒ" -#: pl_exec.c:3653 +#: pl_exec.c:4219 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "SELECTì˜ ê²°ê³¼ë¥¼ 취소하려면 대신 PERFORMì„ ì‚¬ìš©í•˜ì‹­ì‹œì˜¤." -#: pl_exec.c:3685 pl_exec.c:7126 +#: pl_exec.c:4252 pl_exec.c:8270 #, c-format msgid "query string argument of EXECUTE is null" msgstr "EXECUTEì˜ ì¿¼ë¦¬ 문ìžì—´ ì¸ìˆ˜ê°€ nullìž„" -#: pl_exec.c:3741 +#: pl_exec.c:4308 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "SELECTì˜ EXECUTE... INTOê°€ 구현ë˜ì§€ 않ìŒ" -#: pl_exec.c:3742 +#: pl_exec.c:4309 #, c-format -msgid "" -"You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " -"instead." -msgstr "" -"EXECUTE ... INTO ë˜ëŠ” EXECUTE CREATE TABLE ... AS êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." +msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." +msgstr "EXECUTE ... INTO ë˜ëŠ” EXECUTE CREATE TABLE ... AS êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: pl_exec.c:4054 pl_exec.c:4146 +#: pl_exec.c:4322 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "트랜잭션 ëª…ë ¹ë“¤ì˜ EXECUTE ê¸°ëŠ¥ì€ êµ¬í˜„ë˜ì§€ 않았ìŒ" + +#: pl_exec.c:4624 pl_exec.c:4712 #, c-format msgid "cursor variable \"%s\" is null" msgstr "커서 변수 \"%s\"ì´(ê°€) nullìž„" -#: pl_exec.c:4061 pl_exec.c:4153 +#: pl_exec.c:4635 pl_exec.c:4723 #, c-format msgid "cursor \"%s\" does not exist" msgstr "\"%s\" ì´ë¦„ì˜ ì»¤ì„œê°€ ì—†ìŒ" -#: pl_exec.c:4075 +#: pl_exec.c:4648 #, c-format msgid "relative or absolute cursor position is null" msgstr "ìƒëŒ€ ë˜ëŠ” 절대 커서 위치가 nullìž„" -#: pl_exec.c:4255 +#: pl_exec.c:4898 pl_exec.c:4993 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "NOT NULLì´ ì„ ì–¸ëœ \"%s\" ë³€ìˆ˜ì— null ê°’ì„ í• ë‹¹í•  수 ì—†ìŒ" -#: pl_exec.c:4324 +#: pl_exec.c:4974 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "í–‰ ë³€ìˆ˜ì— ë¹„ë³µí•© ê°’ì„ í• ë‹¹í•  수 ì—†ìŒ" -#: pl_exec.c:4348 +#: pl_exec.c:5006 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "레코드 ë³€ìˆ˜ì— ë¹„ë³µí•© ê°’ì„ í• ë‹¹í•  수 ì—†ìŒ" -#: pl_exec.c:4491 +#: pl_exec.c:5057 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "시스템 ì—´ \"%s\"ì— í• ë‹¹í•  수 없습니다." + +#: pl_exec.c:5121 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "지정한 ë°°ì—´ í¬ê¸°(%d)ê°€ 최대치(%d)를 초과했습니다" -#: pl_exec.c:4523 +#: pl_exec.c:5153 #, c-format msgid "subscripted object is not an array" msgstr "하위 스í¬ë¦½íЏ 개체는 ë°°ì—´ì´ ì•„ë‹˜" -#: pl_exec.c:4560 +#: pl_exec.c:5191 #, c-format msgid "array subscript in assignment must not be null" msgstr "ë°°ì—´ 하위 스í¬ë¦½íŠ¸ë¡œ 지정하는 값으로 null ê°’ì„ ì‚¬ìš©í•  수 없습니다" -#: pl_exec.c:5027 +#: pl_exec.c:5698 #, c-format msgid "query \"%s\" did not return data" msgstr "\"%s\" 쿼리ì—서 ë°ì´í„°ë¥¼ 반환하지 않ìŒ" -#: pl_exec.c:5035 +#: pl_exec.c:5706 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "\"%s\" 쿼리가 %d ê°œì˜ ì¹¼ëŸ¼ì„ ë°˜í™˜í•¨" -#: pl_exec.c:5062 +#: pl_exec.c:5734 #, c-format msgid "query \"%s\" returned more than one row" msgstr "\"%s\" 쿼리ì—서 ë‘ ê°œ ì´ìƒì˜ í–‰ì„ ë°˜í™˜í•¨" -#: pl_exec.c:5126 +#: pl_exec.c:5797 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "\"%s\" 쿼리가 SELECTê°€ 아님" -#: pl_funcs.c:237 +#: pl_exec.c:6523 pl_exec.c:6563 pl_exec.c:6603 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "%d번째 매개 ë³€ìˆ˜ì˜ ìžë£Œí˜•(%s)ì´ ë¯¸ë¦¬ ì¤€ë¹„ëœ ì‹¤í–‰ê³„íšì˜ ìžë£Œí˜•(%s)ê³¼ 다릅니다" + +#: pl_exec.c:7378 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "\"%s\" 레코드가 ì•„ì§ í• ë‹¹ë˜ì§€ 않ìŒ" + +#: pl_exec.c:7379 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "ì•„ì§ í• ë‹¹ë˜ì§€ ì•Šì€ ë ˆì½”ë“œì˜ íŠœí”Œ 구조는 미정입니다." + +#: pl_funcs.c:239 msgid "statement block" msgstr "문 블ë¡" -#: pl_funcs.c:239 +#: pl_funcs.c:241 msgid "assignment" msgstr "할당" -#: pl_funcs.c:249 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "정수 루프 변수를 í¬í•¨í•˜ëŠ” FOR" -#: pl_funcs.c:251 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "SELECT í–‰ì„ ì œì–´í•˜ëŠ” FOR" -#: pl_funcs.c:253 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "커서를 제어하는 FOR" -#: pl_funcs.c:255 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "ë°°ì—´ ì´ˆê³¼ëœ FOREACH" -#: pl_funcs.c:269 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "SQL 문" -#: pl_funcs.c:273 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "EXECUTE ë¬¸ì„ ì œì–´í•˜ëŠ” FOR" -#: pl_gram.y:474 +#: pl_gram.y:485 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "ë¸”ë¡ ë¼ë²¨ì€ DECLARE ì˜ì—­ ì•žì— ìžˆì–´ì•¼ 함" -#: pl_gram.y:494 +#: pl_gram.y:505 #, c-format msgid "collations are not supported by type %s" msgstr "%s ìžë£Œí˜•ì€ collation ì§€ì› ì•ˆí•¨" -#: pl_gram.y:509 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "í–‰ ë˜ëŠ” 레코드 변수는 CONSTANTì¼ ìˆ˜ ì—†ìŒ" - -#: pl_gram.y:519 +#: pl_gram.y:524 #, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "í–‰ ë˜ëŠ” 레코드 변수는 NOT NULLì¼ ìˆ˜ ì—†ìŒ" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "\"%s\" 변수는 NOT NULL ì„¤ì •ì´ ìžˆì–´ ê¸°ë³¸ê°’ì„ ê°€ì ¸ì•¼ 합니다" -#: pl_gram.y:530 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "í–‰ ë˜ëŠ” 레코드 ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì´ ì§€ì›ë˜ì§€ 않ìŒ" - -#: pl_gram.y:675 pl_gram.y:690 pl_gram.y:716 +#: pl_gram.y:669 pl_gram.y:684 pl_gram.y:710 #, c-format msgid "variable \"%s\" does not exist" msgstr "\"%s\" 변수가 ì—†ìŒ" -#: pl_gram.y:734 pl_gram.y:762 +#: pl_gram.y:728 pl_gram.y:756 msgid "duplicate declaration" msgstr "중복 ì„ ì–¸" -#: pl_gram.y:745 pl_gram.y:773 +#: pl_gram.y:739 pl_gram.y:767 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "variable \"%s\" shadows a previously defined variable" -#: pl_gram.y:952 +#: pl_gram.y:983 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "GET STACKED DIAGNOSTICS ì—서 %s í•­ëª©ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: pl_gram.y:970 +#: pl_gram.y:1001 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "GET CURRENT DIAGNOSTICS ì—서 %s í•­ëª©ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: pl_gram.y:1068 +#: pl_gram.y:1099 msgid "unrecognized GET DIAGNOSTICS item" msgstr "알 수 없는 GET DIAGNOSTICS 항목" -#: pl_gram.y:1079 pl_gram.y:3439 +#: pl_gram.y:1109 pl_gram.y:3508 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\"ì€(는) ìŠ¤ì¹¼ë¼ ë³€ìˆ˜ê°€ 아님" -#: pl_gram.y:1331 pl_gram.y:1525 +#: pl_gram.y:1357 pl_gram.y:1550 #, c-format -msgid "" -"loop variable of loop over rows must be a record or row variable or list of " -"scalar variables" -msgstr "" -"í–‰ì— ìžˆëŠ” ë£¨í”„ì˜ ë£¨í”„ 변수는 레코드 ë˜ëŠ” í–‰ 변수ì´ê±°ë‚˜ ìŠ¤ì¹¼ë¼ ë³€ìˆ˜ì˜ ëª©ë¡ì´ì–´" -"야 함" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "í–‰ì— ìžˆëŠ” ë£¨í”„ì˜ ë£¨í”„ 변수는 레코드 변수ì´ê±°ë‚˜ ìŠ¤ì¹¼ë¼ ë³€ìˆ˜ì˜ ëª©ë¡ì´ì–´ì•¼ 함" -#: pl_gram.y:1365 +#: pl_gram.y:1391 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "커서 FOR ë£¨í”„ì— ëŒ€ìƒ ë³€ìˆ˜ê°€ 한 개만 있어야 함" -#: pl_gram.y:1372 +#: pl_gram.y:1398 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "커서 FOR 루프는 ë°”ì¸ë”©ëœ 커서 변수를 한 개만 사용해야 함" -#: pl_gram.y:1456 +#: pl_gram.y:1485 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "정수 FOR ë£¨í”„ì— ëŒ€ìƒ ë³€ìˆ˜ê°€ 한 개만 있어야 함" -#: pl_gram.y:1492 +#: pl_gram.y:1521 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "쿼리 FOR ë£¨í”„ì— REVERSE를 지정할 수 ì—†ìŒ" -#: pl_gram.y:1639 +#: pl_gram.y:1652 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "FOREACHì˜ ë°˜ë³µ 변수는 알려진 변수ì´ê±°ë‚˜ ë³€ìˆ˜ì˜ ëª©ë¡ì´ì–´ì•¼ 함" -#: pl_gram.y:1680 +#: pl_gram.y:1693 #, c-format -msgid "" -"there is no label \"%s\" attached to any block or loop enclosing this " -"statement" -msgstr "" -"ìž„ì˜ ë¸”ë¡ì´ë‚˜ 루프 êµ¬ë¬¸ì— í• ë‹¹ëœ \"%s\" ë¼ë²¨ì´ ì—†ìŒ" +msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" +msgstr "ìž„ì˜ ë¸”ë¡ì´ë‚˜ 루프 êµ¬ë¬¸ì— í• ë‹¹ëœ \"%s\" ë¼ë²¨ì´ ì—†ìŒ" -#: pl_gram.y:1688 +#: pl_gram.y:1701 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "CONTINUE 안ì—서 \"%s\" ë¸”ë¡ ë¼ë²¨ì„ 사용할 수 ì—†ìŒ" -#: pl_gram.y:1703 +#: pl_gram.y:1716 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "루프 ì™¸ë¶€ì— ë¼ë²¨ 지정 ì—†ì´ EXIT 사용할 수 ì—†ìŒ" -#: pl_gram.y:1704 +#: pl_gram.y:1717 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE를 루프 ì™¸ë¶€ì— ì‚¬ìš©í•  수 ì—†ìŒ" -#: pl_gram.y:1728 pl_gram.y:1765 pl_gram.y:1813 pl_gram.y:2889 pl_gram.y:2974 -#: pl_gram.y:3085 pl_gram.y:3841 +#: pl_gram.y:1741 pl_gram.y:1778 pl_gram.y:1826 pl_gram.y:2958 pl_gram.y:3041 +#: pl_gram.y:3152 pl_gram.y:3907 msgid "unexpected end of function definition" msgstr "예기치 ì•Šì€ í•¨ìˆ˜ ì •ì˜ì˜ ë" -#: pl_gram.y:1833 pl_gram.y:1857 pl_gram.y:1873 pl_gram.y:1879 pl_gram.y:1997 -#: pl_gram.y:2005 pl_gram.y:2019 pl_gram.y:2114 pl_gram.y:2295 pl_gram.y:2389 -#: pl_gram.y:2541 pl_gram.y:3682 pl_gram.y:3743 pl_gram.y:3822 +#: pl_gram.y:1846 pl_gram.y:1870 pl_gram.y:1886 pl_gram.y:1892 pl_gram.y:2009 +#: pl_gram.y:2017 pl_gram.y:2031 pl_gram.y:2125 pl_gram.y:2360 pl_gram.y:2454 +#: pl_gram.y:2612 pl_gram.y:3749 pl_gram.y:3810 pl_gram.y:3888 msgid "syntax error" msgstr "구문 오류" -#: pl_gram.y:1861 pl_gram.y:1863 pl_gram.y:2299 pl_gram.y:2301 +#: pl_gram.y:1874 pl_gram.y:1876 pl_gram.y:2364 pl_gram.y:2366 msgid "invalid SQLSTATE code" msgstr "ìž˜ëª»ëœ SQLSTATE 코드" -#: pl_gram.y:2061 +#: pl_gram.y:2073 msgid "syntax error, expected \"FOR\"" msgstr "구문 오류, \"FOR\" í•„ìš”" -#: pl_gram.y:2123 +#: pl_gram.y:2134 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "FETCH êµ¬ë¬¸ì€ ë‹¤ì¤‘ 로우를 반환할 수 ì—†ìŒ" -#: pl_gram.y:2179 +#: pl_gram.y:2244 #, c-format msgid "cursor variable must be a simple variable" msgstr "커서 변수는 단순 변수여야 함" -#: pl_gram.y:2185 +#: pl_gram.y:2250 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "\"%s\" 변수는 커서 ë˜ëŠ” ref 커서 형ì‹ì´ì–´ì•¼ 함" -#: pl_gram.y:2512 pl_gram.y:2523 +#: pl_gram.y:2583 pl_gram.y:2594 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" (ì€)는 알려진 변수가 아님" -#: pl_gram.y:2627 pl_gram.y:2637 pl_gram.y:2793 +#: pl_gram.y:2698 pl_gram.y:2708 pl_gram.y:2863 msgid "mismatched parentheses" msgstr "ê´„í˜¸ì˜ ì§ì´ ë§žì§€ 않ìŒ" -#: pl_gram.y:2641 +#: pl_gram.y:2712 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "SQL ì‹ ëì— \"%s\" 누ë½" -#: pl_gram.y:2647 +#: pl_gram.y:2718 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "SQL 문 ëì— \"%s\" 누ë½" -#: pl_gram.y:2664 +#: pl_gram.y:2735 msgid "missing expression" msgstr "í‘œí˜„ì‹ ë¹ ì¡ŒìŒ" -#: pl_gram.y:2666 +#: pl_gram.y:2737 msgid "missing SQL statement" msgstr "SQL ë¬¸ì´ ë¹ ì¡ŒìŒ" -#: pl_gram.y:2795 +#: pl_gram.y:2865 msgid "incomplete data type declaration" msgstr "불완전한 ë°ì´í„° í˜•ì‹ ì„ ì–¸" -#: pl_gram.y:2818 +#: pl_gram.y:2888 msgid "missing data type declaration" msgstr "ë°ì´í„° í˜•ì‹ ì„ ì–¸ 누ë½" -#: pl_gram.y:2897 +#: pl_gram.y:2966 msgid "INTO specified more than once" msgstr "INTOê°€ 여러 번 지정ë¨" -#: pl_gram.y:3066 +#: pl_gram.y:3133 msgid "expected FROM or IN" msgstr "FROM ë˜ëŠ” IN í•„ìš”" -#: pl_gram.y:3126 +#: pl_gram.y:3193 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "ì§‘í•©ì„ ë°˜í™˜í•˜ëŠ” 함수ì—서 RETURN 구문ì—는 ì¸ìžê°€ ì—†ìŒ" -#: pl_gram.y:3127 +#: pl_gram.y:3194 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "RETURN NEXT 나 RETURN QUERY êµ¬ë¬¸ì„ ì‚¬ìš©í•˜ì„¸ìš”." -#: pl_gram.y:3135 +#: pl_gram.y:3204 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURNì€ OUT 매개 변수가 있는 í•¨ìˆ˜ì— ë§¤ê°œ 변수를 í¬í•¨í•  수 ì—†ìŒ" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "프로시져ì—서는 RETURN ë¬¸ì˜ ë§¤ê°œ 변수를 사용할 수 ì—†ìŒ" -#: pl_gram.y:3144 +#: pl_gram.y:3209 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURNì€ void를 반환하는 í•¨ìˆ˜ì— ë§¤ê°œ 변수를 í¬í•¨í•  수 ì—†ìŒ" -#: pl_gram.y:3204 +#: pl_gram.y:3218 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURNì€ OUT 매개 변수가 있는 í•¨ìˆ˜ì— ë§¤ê°œ 변수를 í¬í•¨í•  수 ì—†ìŒ" + +#: pl_gram.y:3280 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT는 OUT 매개 변수가 있는 í•¨ìˆ˜ì— ë§¤ê°œ 변수를 í¬í•¨í•  수 ì—†ìŒ" -#: pl_gram.y:3308 +#: pl_gram.y:3387 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\"ì´(ê°€) CONSTANT로 ì„ ì–¸ë¨" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "\"%s\" 변수는 CONSTANT로 ì„ ì–¸ë¨" -#: pl_gram.y:3370 pl_gram.y:3382 +#: pl_gram.y:3450 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "다중 ì•„ì´í…œ INTO 목ë¡ì˜ 부분으로 record나 row 변수가 ì‚¬ìš©ë  ìˆ˜ ì—†ìŒ" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "다중 ì•„ì´í…œ INTO 목ë¡ì˜ 부분으로 record 변수가 ì‚¬ìš©ë  ìˆ˜ ì—†ìŒ" -#: pl_gram.y:3427 +#: pl_gram.y:3496 #, c-format msgid "too many INTO variables specified" msgstr "너무 ë§Žì€ INTO 변수가 지정ë¨" -#: pl_gram.y:3635 +#: pl_gram.y:3702 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "ë ˆì´ë¸”ì´ ì—†ëŠ” 블ë¡ì— ë ë ˆì´ë¸” \"%s\"ì´(ê°€) 지정ë¨" -#: pl_gram.y:3642 +#: pl_gram.y:3709 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "ë ë ˆì´ë¸” \"%s\"ì´(ê°€) 블ë¡ì˜ \"%s\" ë ˆì´ë¸”ê³¼ 다름" -#: pl_gram.y:3677 +#: pl_gram.y:3744 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "\"%s\" ì»¤ì„œì— ì¸ìˆ˜ê°€ ì—†ìŒ" -#: pl_gram.y:3691 +#: pl_gram.y:3758 #, c-format msgid "cursor \"%s\" has arguments" msgstr "\"%s\" ì»¤ì„œì— ì¸ìˆ˜ê°€ 있ìŒ" -#: pl_gram.y:3733 +#: pl_gram.y:3800 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "\"%s\" 커서는 \"%s\" ì´ë¦„ì˜ ì¸ìžê°€ ì—†ìŒ" -#: pl_gram.y:3753 +#: pl_gram.y:3820 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "\"%s\" ì´ë¦„ì˜ ì¸ìžê°€ \"%s\" 커서ì—서 중복ë¨" -#: pl_gram.y:3778 +#: pl_gram.y:3845 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "\"%s\" 커서를 위한 충분하지 ì•Šì€ ì¸ìž" -#: pl_gram.y:3785 +#: pl_gram.y:3852 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "\"%s\" 커서를 위한 ì¸ìžê°€ 너무 ë§ŽìŒ" -#: pl_gram.y:3873 +#: pl_gram.y:3939 msgid "unrecognized RAISE statement option" msgstr "ì¸ì‹í•  수 없는 RAISE 문 옵션" -#: pl_gram.y:3877 +#: pl_gram.y:3943 msgid "syntax error, expected \"=\"" msgstr "구문 오류, \"=\" í•„ìš”" -#: pl_gram.y:3918 +#: pl_gram.y:3984 #, c-format msgid "too many parameters specified for RAISE" msgstr "RAISEì— ì§€ì •ëœ ë§¤ê°œ 변수가 너무 ë§ŽìŒ" -#: pl_gram.y:3922 +#: pl_gram.y:3988 #, c-format msgid "too few parameters specified for RAISE" msgstr "RAISEì— ì§€ì •ëœ ë§¤ê°œ 변수가 너무 ì ìŒ" -#: pl_handler.c:151 -msgid "" -"Sets handling of conflicts between PL/pgSQL variable names and table column " -"names." +#: pl_handler.c:154 +msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "PL/pgSQL 변수명과 í…Œì´ë¸” 칼럼명 ì‚¬ì´ ì¶©ëŒì´ ì¼ì–´ë‚  ê²½ìš°ì— ëŒ€í•œ 처리를 하세요." -#: pl_handler.c:160 -msgid "" -"Print information about parameters in the DETAIL part of the error messages " -"generated on INTO ... STRICT failures." -msgstr "" -"INTO ... STRICT 실패ì—서 오류 메시지를 만들 때 ê·¸ DETAIL ë¶€ë¶„ì— ë“¤ì–´ê°ˆ ë‚´ìš©ì„ " -"출력 하세요" +#: pl_handler.c:163 +msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." +msgstr "INTO ... STRICT 실패ì—서 오류 메시지를 만들 때 ê·¸ DETAIL ë¶€ë¶„ì— ë“¤ì–´ê°ˆ ë‚´ìš©ì„ ì¶œë ¥ 하세요" -#: pl_handler.c:168 +#: pl_handler.c:171 msgid "Perform checks given in ASSERT statements." msgstr "ASSERT 구문ì—서 주어진 검사를 수행하세요." -#: pl_handler.c:176 +#: pl_handler.c:179 msgid "List of programming constructs that should produce a warning." msgstr "경고로 처리할 í”„ë¡œê·¸ëž˜ë° ì»¨ìŠ¤íŠ¸ëŸ­íŠ¸ 목ë¡" -#: pl_handler.c:186 +#: pl_handler.c:189 msgid "List of programming constructs that should produce an error." msgstr "오류로 처리할 í”„ë¡œê·¸ëž˜ë° ì»¨ìŠ¤íŠ¸ëŸ­íŠ¸ 목ë¡" #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:622 +#: pl_scanner.c:630 #, c-format msgid "%s at end of input" msgstr "%s, ìž…ë ¥ ë부분" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:638 +#: pl_scanner.c:646 #, c-format msgid "%s at or near \"%s\"" msgstr "%s, \"%s\" 부근" + +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "í–‰ ë˜ëŠ” 레코드 ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì´ ì§€ì›ë˜ì§€ 않ìŒ" + +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "í–‰ ë˜ëŠ” 레코드 변수는 NOT NULLì¼ ìˆ˜ ì—†ìŒ" + +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "í–‰ ë˜ëŠ” 레코드 변수는 CONSTANTì¼ ìˆ˜ ì—†ìŒ" + +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "대신 BEGIN 블ë¡ì„ EXCEPTION 절과 함께 사용하십시오." + +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" +#~ msgstr "NOT NULLì´ ì„ ì–¸ëœ \"%s\" ë³€ìˆ˜ì˜ ê¸°ë³¸ ê°’ì´ NULL로 ì„¤ì •ë  ìˆ˜ ì—†ìŒ" + +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "\"%s\" 관계가 í…Œì´ë¸”ì´ ì•„ë‹˜" diff --git a/src/pl/plpgsql/src/po/ru.po b/src/pl/plpgsql/src/po/ru.po index 759f368b13a..55e5b05938d 100644 --- a/src/pl/plpgsql/src/po/ru.po +++ b/src/pl/plpgsql/src/po/ru.po @@ -1,14 +1,13 @@ # Russian message translation file for plpgsql # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: plpgsql (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-02 23:37+0000\n" -"PO-Revision-Date: 2016-11-24 11:24+0300\n" +"POT-Creation-Date: 2019-04-30 07:03+0300\n" +"PO-Revision-Date: 2018-11-19 14:21+0300\n" "Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" @@ -18,34 +17,34 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -#: pl_comp.c:433 pl_handler.c:451 +#: pl_comp.c:434 pl_handler.c:457 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "функции PL/pgSQL не могут принимать тип %s" -#: pl_comp.c:514 +#: pl_comp.c:522 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "" "не удалоÑÑŒ определить фактичеÑкий тип результата Ð´Ð»Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾Ñ€Ñ„Ð½Ð¾Ð¹ функции \"%s" "\"" -#: pl_comp.c:544 +#: pl_comp.c:552 #, c-format msgid "trigger functions can only be called as triggers" msgstr "триггерные функции могут вызыватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в триггерах" -#: pl_comp.c:548 pl_handler.c:436 +#: pl_comp.c:556 pl_handler.c:441 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "функции PL/pgSQL не могут возвращать тип %s" -#: pl_comp.c:589 +#: pl_comp.c:595 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "у триггерных функций не может быть объÑвленных аргументов" -#: pl_comp.c:590 +#: pl_comp.c:596 #, c-format msgid "" "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " @@ -54,63 +53,58 @@ msgstr "" "При необходимоÑти к аргументам триггера можно обращатьÑÑ Ñ‡ÐµÑ€ÐµÐ· переменные " "TG_NARGS and TG_ARGV." -#: pl_comp.c:692 +#: pl_comp.c:719 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "у функций Ñобытийных триггеров не может быть объÑвленных аргументов" -#: pl_comp.c:943 +#: pl_comp.c:976 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "компилÑÑ†Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ PL/pgSQL \"%s\" в районе Ñтроки %d" -#: pl_comp.c:966 +#: pl_comp.c:999 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "Ð¸Ð¼Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"%s\" указано неоднократно" -#: pl_comp.c:1076 +#: pl_comp.c:1109 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "Ð½ÐµÐ¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñ‡Ð½Ð°Ñ ÑÑылка на Ñтолбец \"%s\"" -#: pl_comp.c:1078 +#: pl_comp.c:1111 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "ПодразумеваетÑÑ ÑÑылка на переменную PL/pgSQL или Ñтолбец таблицы." -#: pl_comp.c:1258 pl_comp.c:1286 pl_exec.c:4624 pl_exec.c:4953 pl_exec.c:5038 -#: pl_exec.c:5129 +#: pl_comp.c:1294 pl_exec.c:5075 pl_exec.c:5440 pl_exec.c:5527 pl_exec.c:5618 +#: pl_exec.c:6536 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "в запиÑи \"%s\" нет Ð¿Ð¾Ð»Ñ \"%s\"" -#: pl_comp.c:1817 +#: pl_comp.c:1756 #, c-format msgid "relation \"%s\" does not exist" msgstr "отношение \"%s\" не ÑущеÑтвует" -#: pl_comp.c:1926 +#: pl_comp.c:1848 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\" имеет пÑевдотип %s" -#: pl_comp.c:1993 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "отношение \"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹" - -#: pl_comp.c:2153 +#: pl_comp.c:2028 #, c-format msgid "type \"%s\" is only a shell" msgstr "тип \"%s\" - лишь пуÑтышка" -#: pl_comp.c:2247 pl_comp.c:2300 +#: pl_comp.c:2125 pl_comp.c:2178 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "нераÑпознанное уÑловие иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ \"%s\"" -#: pl_comp.c:2508 +#: pl_comp.c:2392 #, c-format msgid "" "could not determine actual argument type for polymorphic function \"%s\"" @@ -118,52 +112,52 @@ msgstr "" "не удалоÑÑŒ определить фактичеÑкий тип аргумента Ð´Ð»Ñ Ð¿Ð¾Ð»Ð¸Ð¼Ð¾Ñ€Ñ„Ð½Ð¾Ð¹ функции \"%s" "\"" -#: pl_exec.c:355 pl_exec.c:644 pl_exec.c:951 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1105 msgid "during initialization of execution state" msgstr "в процеÑÑе инициализации ÑоÑтоÑÐ½Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ" -#: pl_exec.c:362 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "при Ñохранении аргументов вызова в локальных переменных" -#: pl_exec.c:447 pl_exec.c:833 +#: pl_exec.c:569 pl_exec.c:940 msgid "during function entry" msgstr "при входе в функцию" -#: pl_exec.c:472 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "конец функции доÑтигнут без RETURN" -#: pl_exec.c:479 +#: pl_exec.c:601 msgid "while casting return value to function's return type" msgstr "при приведении возвращаемого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ðº типу результата функции" -#: pl_exec.c:492 pl_exec.c:3138 +#: pl_exec.c:614 pl_exec.c:3542 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво, вызвана в контекÑте, где ему нет меÑта" -#: pl_exec.c:530 pl_exec.c:2985 -msgid "returned record type does not match expected record type" -msgstr "возвращаемый тип запиÑи не ÑоответÑтвует ожидаемому" - -#: pl_exec.c:585 pl_exec.c:862 pl_exec.c:986 +#: pl_exec.c:740 pl_exec.c:969 pl_exec.c:1130 msgid "during function exit" msgstr "при выходе из функции" -#: pl_exec.c:858 pl_exec.c:982 +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3387 +msgid "returned record type does not match expected record type" +msgstr "возвращаемый тип запиÑи не ÑоответÑтвует ожидаемому" + +#: pl_exec.c:965 pl_exec.c:1126 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "конец триггерной процедуры доÑтигнут без RETURN" -#: pl_exec.c:867 +#: pl_exec.c:974 #, c-format msgid "trigger procedure cannot return a set" msgstr "Ñ‚Ñ€Ð¸Ð³Ð³ÐµÑ€Ð½Ð°Ñ Ð¿Ñ€Ð¾Ñ†ÐµÐ´ÑƒÑ€Ð° не может возвращать множеÑтво" -#: pl_exec.c:889 +#: pl_exec.c:1013 pl_exec.c:1041 msgid "" "returned row structure does not match the structure of the triggering table" msgstr "" @@ -173,7 +167,7 @@ msgstr "" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:1034 +#: pl_exec.c:1178 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/pgSQL %s, Ñтрока %d, %s" @@ -181,250 +175,243 @@ msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/pgSQL %s, Ñтрока %d, %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:1045 +#: pl_exec.c:1189 #, c-format msgid "PL/pgSQL function %s %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/pgSQL %s, %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:1053 +#: pl_exec.c:1197 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/pgSQL %s, Ñтрока %d, оператор %s" -#: pl_exec.c:1059 +#: pl_exec.c:1203 #, c-format msgid "PL/pgSQL function %s" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/pgSQL %s" -#: pl_exec.c:1224 +#: pl_exec.c:1541 msgid "during statement block local variable initialization" msgstr "при инициализации локальной переменной в блоке операторов" -#: pl_exec.c:1263 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "" -"Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\", объÑÐ²Ð»ÐµÐ½Ð½Ð°Ñ NOT NULL, не может иметь значение по " -"умолчанию NULL" - -#: pl_exec.c:1314 +#: pl_exec.c:1639 msgid "during statement block entry" msgstr "при входе в блок операторов" -#: pl_exec.c:1346 +#: pl_exec.c:1671 msgid "during statement block exit" msgstr "при выходе из блока операторов" -#: pl_exec.c:1388 +#: pl_exec.c:1709 msgid "during exception cleanup" msgstr "при очиÑтке поÑле иÑключениÑ" -#: pl_exec.c:1754 +#: pl_exec.c:2205 +#, c-format +msgid "" +"procedure parameter \"%s\" is an output parameter but corresponding argument " +"is not writable" +msgstr "" +"параметр процедуры \"%s\" ÑвлÑетÑÑ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ð¼, но ÑоответÑтвующий аргумент не " +"допуÑкает запиÑÑŒ" + +#: pl_exec.c:2210 +#, c-format +msgid "" +"procedure parameter %d is an output parameter but corresponding argument is " +"not writable" +msgstr "" +"параметр процедуры %d ÑвлÑетÑÑ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ñ‹Ð¼, но ÑоответÑтвующий аргумент не " +"допуÑкает запиÑÑŒ" + +#: pl_exec.c:2321 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "" "GET STACKED DIAGNOSTICS Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать вне блока обработчика иÑключениÑ" -#: pl_exec.c:1959 +#: pl_exec.c:2526 #, c-format msgid "case not found" msgstr "неправильный CASE" -#: pl_exec.c:1960 +#: pl_exec.c:2527 #, c-format msgid "CASE statement is missing ELSE part." msgstr "Ð’ операторе CASE не хватает чаÑти ELSE." -#: pl_exec.c:2114 +#: pl_exec.c:2620 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "нижнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° цикла FOR не может быть равна NULL" -#: pl_exec.c:2130 +#: pl_exec.c:2636 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "верхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° цикла FOR не может быть равна NULL" -#: pl_exec.c:2148 +#: pl_exec.c:2654 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "значение BY в цикле FOR не может быть равно NULL" -#: pl_exec.c:2154 +#: pl_exec.c:2660 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "значение BY в цикле FOR должно быть больше нулÑ" -#: pl_exec.c:2331 pl_exec.c:4125 +#: pl_exec.c:2794 pl_exec.c:4509 #, c-format msgid "cursor \"%s\" already in use" msgstr "курÑор \"%s\" уже иÑпользуетÑÑ" -#: pl_exec.c:2354 pl_exec.c:4190 +#: pl_exec.c:2817 pl_exec.c:4574 #, c-format msgid "arguments given for cursor without arguments" msgstr "курÑору без аргументов были переданы аргументы" -#: pl_exec.c:2373 pl_exec.c:4209 +#: pl_exec.c:2836 pl_exec.c:4593 #, c-format msgid "arguments required for cursor" msgstr "курÑору требуютÑÑ Ð°Ñ€Ð³ÑƒÐ¼ÐµÐ½Ñ‚Ñ‹" -#: pl_exec.c:2460 +#: pl_exec.c:2923 #, c-format msgid "FOREACH expression must not be null" msgstr "выражение FOREACH не может быть равно NULL" -#: pl_exec.c:2475 +#: pl_exec.c:2938 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "выражение в FOREACH должно быть маÑÑивом, но не типом %s" -#: pl_exec.c:2492 +#: pl_exec.c:2955 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "размерноÑть Ñреза (%d) вне допуÑтимого диапазона 0..%d" -#: pl_exec.c:2519 +#: pl_exec.c:2982 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ†Ð¸ÐºÐ»Ð° FOREACH ... SLICE должна быть маÑÑивом" -#: pl_exec.c:2523 +#: pl_exec.c:2986 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ†Ð¸ÐºÐ»Ð° FOREACH не должна быть маÑÑивом" -#: pl_exec.c:2726 pl_exec.c:2808 pl_exec.c:2978 +#: pl_exec.c:3148 pl_exec.c:3205 pl_exec.c:3380 #, c-format msgid "" "cannot return non-composite value from function returning composite type" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ ÑоÑтавной тип, не может вернуть неÑоÑтавное значение" -#: pl_exec.c:2852 pl_gram.y:3199 +#: pl_exec.c:3244 pl_gram.y:3267 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "" "RETURN NEXT можно иÑпользовать только в функциÑÑ…, возвращающих множеÑтва" -#: pl_exec.c:2886 pl_exec.c:3013 +#: pl_exec.c:3285 pl_exec.c:3417 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "в RETURN NEXT передан неправильный тип результата" -#: pl_exec.c:2915 pl_exec.c:4612 pl_exec.c:4920 pl_exec.c:4946 pl_exec.c:5012 -#: pl_exec.c:5031 pl_exec.c:5099 pl_exec.c:5122 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "запиÑи \"%s\" не приÑвоено значение" - -#: pl_exec.c:2917 pl_exec.c:4614 pl_exec.c:4922 pl_exec.c:4948 pl_exec.c:5014 -#: pl_exec.c:5033 pl_exec.c:5101 pl_exec.c:5124 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "" -"Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, которой не приÑвоено значение, Ñтруктура кортежа не определена." - -#: pl_exec.c:2924 pl_exec.c:2943 +#: pl_exec.c:3323 pl_exec.c:3344 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "в RETURN NEXT передан неправильный тип запиÑи" -#: pl_exec.c:3032 +#: pl_exec.c:3436 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "у оператора RETURN NEXT должен быть параметр" -#: pl_exec.c:3058 pl_gram.y:3261 +#: pl_exec.c:3462 pl_gram.y:3330 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "" "RETURN QUERY можно иÑпользовать только в функциÑÑ…, возвращающих множеÑтва" -#: pl_exec.c:3082 +#: pl_exec.c:3486 msgid "structure of query does not match function result type" msgstr "Ñтруктура запроÑа не ÑоответÑтвует типу результата функции" -#: pl_exec.c:3166 pl_exec.c:3304 +#: pl_exec.c:3570 pl_exec.c:3708 #, c-format msgid "RAISE option already specified: %s" msgstr "Ñтот параметр RAISE уже указан: %s" -#: pl_exec.c:3200 +#: pl_exec.c:3604 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "" "RAISE без параметров Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать вне блока обработчика иÑключениÑ" -#: pl_exec.c:3294 +#: pl_exec.c:3698 #, c-format msgid "RAISE statement option cannot be null" msgstr "параметром оператора RAISE не может быть NULL" -#: pl_exec.c:3364 +#: pl_exec.c:3768 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3419 +#: pl_exec.c:3823 #, c-format msgid "assertion failed" msgstr "нарушение иÑтинноÑти" -#: pl_exec.c:3623 pl_exec.c:3769 pl_exec.c:3959 +#: pl_exec.c:4160 pl_exec.c:4347 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "в PL/pgSQL Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ COPY Ñ ÑƒÑ‡Ð°Ñтием клиента" -#: pl_exec.c:3627 pl_exec.c:3773 pl_exec.c:3963 -#, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "в PL/pgSQL Ð½ÐµÐ»ÑŒÐ·Ñ Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ‚ÑŒ/заканчивать транзакции" - -#: pl_exec.c:3628 pl_exec.c:3774 pl_exec.c:3964 +#: pl_exec.c:4166 #, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "ИÑпользуйте блок BEGIN Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ EXCEPTION." +msgid "unsupported transaction command in PL/pgSQL" +msgstr "Ð½ÐµÐ¿Ð¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð° в PL/pgSQL" -#: pl_exec.c:3797 pl_exec.c:3988 +#: pl_exec.c:4190 pl_exec.c:4377 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ не может возвращать данные" -#: pl_exec.c:3825 pl_exec.c:4016 +#: pl_exec.c:4213 pl_exec.c:4400 #, c-format msgid "query returned no rows" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ðµ вернул Ñтрок" -#: pl_exec.c:3844 pl_exec.c:4035 +#: pl_exec.c:4232 pl_exec.c:4419 #, c-format msgid "query returned more than one row" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð²ÐµÑ€Ð½ÑƒÐ» неÑколько Ñтрок" -#: pl_exec.c:3861 +#: pl_exec.c:4249 #, c-format msgid "query has no destination for result data" msgstr "в запроÑе нет Ð½Ð°Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… результата" -#: pl_exec.c:3862 +#: pl_exec.c:4250 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "ЕÑли вам нужно отброÑить результаты SELECT, иÑпользуйте PERFORM." -#: pl_exec.c:3895 pl_exec.c:7332 +#: pl_exec.c:4283 pl_exec.c:8297 #, c-format msgid "query string argument of EXECUTE is null" msgstr "в качеÑтве текÑта запроÑа в EXECUTE передан NULL" -#: pl_exec.c:3951 +#: pl_exec.c:4339 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "возможноÑть Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ SELECT ... INTO в EXECUTE не реализована" # skip-rule: space-before-ellipsis -#: pl_exec.c:3952 +#: pl_exec.c:4340 #, c-format msgid "" "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " @@ -433,74 +420,103 @@ msgstr "" "Ðльтернативой может Ñтать EXECUTE ... INTO или EXECUTE CREATE TABLE ... " "AS ..." -#: pl_exec.c:4273 pl_exec.c:4369 +#: pl_exec.c:4353 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "EXECUTE Ñ Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ð¾Ð½Ð½Ñ‹Ð¼Ð¸ командами не поддерживаетÑÑ" + +#: pl_exec.c:4655 pl_exec.c:4743 #, c-format msgid "cursor variable \"%s\" is null" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ ÐºÑƒÑ€Ñора \"%s\" равна NULL" -#: pl_exec.c:4284 pl_exec.c:4380 +#: pl_exec.c:4666 pl_exec.c:4754 #, c-format msgid "cursor \"%s\" does not exist" msgstr "курÑор \"%s\" не ÑущеÑтвует" -#: pl_exec.c:4297 +#: pl_exec.c:4679 #, c-format msgid "relative or absolute cursor position is null" msgstr "отноÑÐ¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð»Ð¸ абÑÐ¾Ð»ÑŽÑ‚Ð½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ ÐºÑƒÑ€Ñора равна NULL" -#: pl_exec.c:4488 +#: pl_exec.c:4925 pl_exec.c:5020 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "значение NULL Ð½ÐµÐ»ÑŒÐ·Ñ Ð¿Ñ€Ð¸Ñвоить переменной \"%s\", объÑвленной NOT NULL" -#: pl_exec.c:4557 +#: pl_exec.c:5001 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "переменной типа кортеж можно приÑвоить только ÑоÑтавное значение" -#: pl_exec.c:4581 +#: pl_exec.c:5033 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "переменной типа запиÑÑŒ можно приÑвоить только ÑоÑтавное значение" -#: pl_exec.c:4701 +#: pl_exec.c:5084 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "приÑвоить значение ÑиÑтемному Ñтолбцу \"%s\" нельзÑ" + +#: pl_exec.c:5148 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "чиÑло размерноÑтей маÑÑива (%d) превышает предел (%d)" -#: pl_exec.c:4733 +#: pl_exec.c:5180 #, c-format msgid "subscripted object is not an array" msgstr "Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð° указан индекÑ, но Ñтот объект - не маÑÑив" -#: pl_exec.c:4771 +#: pl_exec.c:5218 #, c-format msgid "array subscript in assignment must not be null" msgstr "Ð¸Ð½Ð´ÐµÐºÑ Ñлемента маÑÑива в приÑваивании не может быть NULL" -#: pl_exec.c:5238 +#: pl_exec.c:5725 #, c-format msgid "query \"%s\" did not return data" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" не вернул данные" -#: pl_exec.c:5246 +#: pl_exec.c:5733 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" -msgstr[0] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтроку" -msgstr[1] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтроки" -msgstr[2] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтрок" +msgstr[0] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтолбец" +msgstr[1] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтолбца" +msgstr[2] "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул %d Ñтолбцов" -#: pl_exec.c:5273 +#: pl_exec.c:5761 #, c-format msgid "query \"%s\" returned more than one row" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" вернул неÑколько Ñтрок" -#: pl_exec.c:5341 +#: pl_exec.c:5824 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "Ð·Ð°Ð¿Ñ€Ð¾Ñ \"%s\" - не SELECT" +#: pl_exec.c:6550 pl_exec.c:6590 pl_exec.c:6630 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "" +"тип параметра %d (%s) не ÑоответÑтвует тому, Ñ ÐºÐ¾Ñ‚Ð¾Ñ€Ñ‹Ð¼ подготавливалÑÑ Ð¿Ð»Ð°Ð½ " +"(%s)" + +#: pl_exec.c:7405 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "запиÑи \"%s\" не приÑвоено значение" + +#: pl_exec.c:7406 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "" +"Ð”Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, которой не приÑвоено значение, Ñтруктура кортежа не определена." + #: pl_funcs.c:239 msgid "statement block" msgstr "блок операторов" @@ -533,296 +549,293 @@ msgstr "SQL-оператор" msgid "FOR over EXECUTE statement" msgstr "FOR по результатам EXECUTE" -#: pl_gram.y:478 +#: pl_gram.y:485 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "метка блока должна помещатьÑÑ Ð´Ð¾ DECLARE, а не поÑле" -#: pl_gram.y:498 +#: pl_gram.y:505 #, c-format msgid "collations are not supported by type %s" msgstr "тип %s не поддерживает Ñортировку (COLLATION)" -#: pl_gram.y:513 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может быть конÑтантой" - -#: pl_gram.y:523 +#: pl_gram.y:524 #, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может быть NULL" - -#: pl_gram.y:534 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может иметь Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "" +"у переменной \"%s\" должно быть значение по умолчанию, так как она объÑвлена " +"как NOT NULL" -#: pl_gram.y:679 pl_gram.y:694 pl_gram.y:720 +#: pl_gram.y:670 pl_gram.y:685 pl_gram.y:711 #, c-format msgid "variable \"%s\" does not exist" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\" не ÑущеÑтвует" -#: pl_gram.y:738 pl_gram.y:766 +#: pl_gram.y:729 pl_gram.y:757 msgid "duplicate declaration" msgstr "повторÑющееÑÑ Ð¾Ð±ÑŠÑвление" -#: pl_gram.y:749 pl_gram.y:777 +#: pl_gram.y:740 pl_gram.y:768 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\" Ñкрывает ранее определённую переменную" -#: pl_gram.y:956 +#: pl_gram.y:984 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "команда GET STACKED DIAGNOSTICS не принимает Ñлемент %s" -#: pl_gram.y:974 +#: pl_gram.y:1002 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "команда GET CURRENT DIAGNOSTICS не принимает Ñлемент %s" -#: pl_gram.y:1072 +#: pl_gram.y:1100 msgid "unrecognized GET DIAGNOSTICS item" msgstr "нераÑпознанный Ñлемент GET DIAGNOSTICS" -#: pl_gram.y:1082 pl_gram.y:3448 +#: pl_gram.y:1110 pl_gram.y:3509 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" - не ÑкалÑÑ€Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ" -#: pl_gram.y:1334 pl_gram.y:1528 +#: pl_gram.y:1358 pl_gram.y:1551 #, c-format msgid "" -"loop variable of loop over rows must be a record or row variable or list of " -"scalar variables" +"loop variable of loop over rows must be a record variable or list of scalar " +"variables" msgstr "" -"Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ†Ð¸ÐºÐ»Ð° по кортежам должна быть переменной типа запиÑÑŒ или кортеж " -"или ÑпиÑком ÑкалÑрных переменных" +"Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ†Ð¸ÐºÐ»Ð° по кортежам должна быть переменной типа запиÑÑŒ или ÑпиÑком " +"ÑкалÑрных переменных" -#: pl_gram.y:1368 +#: pl_gram.y:1392 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "в цикле FOR Ñ ÐºÑƒÑ€Ñором должна быть только одна переменнаÑ" -#: pl_gram.y:1375 +#: pl_gram.y:1399 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "" "в цикле FOR Ñ ÐºÑƒÑ€Ñором должен иÑпользоватьÑÑ ÐºÑƒÑ€Ñор, привÑзанный к запроÑу" -#: pl_gram.y:1459 +#: pl_gram.y:1486 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "в целочиÑленном цикле FOR должна быть только одна переменнаÑ" -#: pl_gram.y:1495 +#: pl_gram.y:1522 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "в цикле FOR Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñом Ð½ÐµÐ»ÑŒÐ·Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ REVERSE" -#: pl_gram.y:1642 +#: pl_gram.y:1653 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "" "переменной цикла FOREACH должна быть извеÑÑ‚Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð¸Ð»Ð¸ ÑпиÑок " "переменных" -#: pl_gram.y:1683 +#: pl_gram.y:1694 #, c-format msgid "" "there is no label \"%s\" attached to any block or loop enclosing this " "statement" msgstr "в блоке или цикле, окружающем Ñтот оператор, нет метки \"%s\"" -#: pl_gram.y:1691 +#: pl_gram.y:1702 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "метку блока \"%s\" Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать в CONTINUE" -#: pl_gram.y:1706 +#: pl_gram.y:1717 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT можно иÑпользовать вне цикла только Ñ ÑƒÐºÐ°Ð·Ð°Ð½Ð¸ÐµÐ¼ метки" -#: pl_gram.y:1707 +#: pl_gram.y:1718 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE Ð½ÐµÐ»ÑŒÐ·Ñ Ð¸Ñпользовать вне цикла" -#: pl_gram.y:1731 pl_gram.y:1768 pl_gram.y:1816 pl_gram.y:2898 pl_gram.y:2983 -#: pl_gram.y:3094 pl_gram.y:3850 +#: pl_gram.y:1742 pl_gram.y:1779 pl_gram.y:1827 pl_gram.y:2959 pl_gram.y:3042 +#: pl_gram.y:3153 pl_gram.y:3910 msgid "unexpected end of function definition" msgstr "неожиданный конец Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸" -#: pl_gram.y:1836 pl_gram.y:1860 pl_gram.y:1876 pl_gram.y:1882 pl_gram.y:2000 -#: pl_gram.y:2008 pl_gram.y:2022 pl_gram.y:2117 pl_gram.y:2304 pl_gram.y:2398 -#: pl_gram.y:2550 pl_gram.y:3691 pl_gram.y:3752 pl_gram.y:3831 +#: pl_gram.y:1847 pl_gram.y:1871 pl_gram.y:1887 pl_gram.y:1893 pl_gram.y:2010 +#: pl_gram.y:2018 pl_gram.y:2032 pl_gram.y:2126 pl_gram.y:2361 pl_gram.y:2455 +#: pl_gram.y:2613 pl_gram.y:3752 pl_gram.y:3813 pl_gram.y:3891 msgid "syntax error" msgstr "ошибка ÑинтакÑиÑа" -#: pl_gram.y:1864 pl_gram.y:1866 pl_gram.y:2308 pl_gram.y:2310 +#: pl_gram.y:1875 pl_gram.y:1877 pl_gram.y:2365 pl_gram.y:2367 msgid "invalid SQLSTATE code" msgstr "неверный код SQLSTATE" -#: pl_gram.y:2064 +#: pl_gram.y:2074 msgid "syntax error, expected \"FOR\"" msgstr "ошибка ÑинтакÑиÑа, ожидалÑÑ \"FOR\"" -#: pl_gram.y:2126 +#: pl_gram.y:2135 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "оператор FETCH не может вернуть неÑколько Ñтрок" -#: pl_gram.y:2188 +#: pl_gram.y:2245 #, c-format msgid "cursor variable must be a simple variable" msgstr "переменнаÑ-курÑор должна быть проÑтой переменной" -#: pl_gram.y:2194 +#: pl_gram.y:2251 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\" должна быть типа cursor или refcursor" -#: pl_gram.y:2521 pl_gram.y:2532 +#: pl_gram.y:2584 pl_gram.y:2595 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" - не извеÑÑ‚Ð½Ð°Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ" -#: pl_gram.y:2636 pl_gram.y:2646 pl_gram.y:2802 +#: pl_gram.y:2699 pl_gram.y:2709 pl_gram.y:2864 msgid "mismatched parentheses" msgstr "непарные Ñкобки" -#: pl_gram.y:2650 +#: pl_gram.y:2713 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "отÑутÑтвует \"%s\" в конце Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ SQL" -#: pl_gram.y:2656 +#: pl_gram.y:2719 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "отÑутÑтвует \"%s\" в конце оператора SQL" -#: pl_gram.y:2673 +#: pl_gram.y:2736 msgid "missing expression" msgstr "отÑутÑтвует выражение" -#: pl_gram.y:2675 +#: pl_gram.y:2738 msgid "missing SQL statement" msgstr "отÑутÑтвует оператор SQL" -#: pl_gram.y:2804 +#: pl_gram.y:2866 msgid "incomplete data type declaration" msgstr "неполное определение типа данных" -#: pl_gram.y:2827 +#: pl_gram.y:2889 msgid "missing data type declaration" msgstr "отÑутÑтвует определение типа данных" -#: pl_gram.y:2906 +#: pl_gram.y:2967 msgid "INTO specified more than once" msgstr "INTO указано неоднократно" -#: pl_gram.y:3075 +#: pl_gram.y:3134 msgid "expected FROM or IN" msgstr "ожидалоÑÑŒ FROM или IN" -#: pl_gram.y:3135 +#: pl_gram.y:3194 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "в функции, возвращающей множеÑтво, RETURN должен быть без параметров" -#: pl_gram.y:3136 +#: pl_gram.y:3195 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "ИÑпользуйте RETURN NEXT или RETURN QUERY." -#: pl_gram.y:3144 +#: pl_gram.y:3205 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN должен быть без параметров в функции Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ OUT" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "в процедуре RETURN должен быть без параметров" -#: pl_gram.y:3153 +#: pl_gram.y:3210 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "в функции, не возвращающей ничего, RETURN не должен иметь параметров" -#: pl_gram.y:3213 +#: pl_gram.y:3219 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN должен быть без параметров в функции Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ OUT" + +#: pl_gram.y:3281 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT должен быть без параметров в функции Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ OUT" -#: pl_gram.y:3317 +#: pl_gram.y:3388 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\" объÑвлена как CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\" объÑвлена как CONSTANT" -#: pl_gram.y:3379 pl_gram.y:3391 +#: pl_gram.y:3451 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" +msgid "record variable cannot be part of multiple-item INTO list" msgstr "" -"Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° запиÑÑŒ или кортеж не может быть чаÑтью ÑпиÑка INTO Ñ " -"неÑколькими Ñлементами" +"Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° запиÑÑŒ не может быть чаÑтью ÑпиÑка INTO Ñ Ð½ÐµÑколькими " +"Ñлементами" -#: pl_gram.y:3436 +#: pl_gram.y:3497 #, c-format msgid "too many INTO variables specified" msgstr "указано Ñлишком много переменных INTO" -#: pl_gram.y:3644 +#: pl_gram.y:3705 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "ÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° \"%s\" указана Ð´Ð»Ñ Ð½Ðµ помеченного блока" -#: pl_gram.y:3651 +#: pl_gram.y:3712 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "ÐºÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° \"%s\" отличаетÑÑ Ð¾Ñ‚ метки блока \"%s\"" -#: pl_gram.y:3686 +#: pl_gram.y:3747 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "курÑор \"%s\" не имеет аргументов" -#: pl_gram.y:3700 +#: pl_gram.y:3761 #, c-format msgid "cursor \"%s\" has arguments" msgstr "курÑор \"%s\" имеет аргументы" -#: pl_gram.y:3742 +#: pl_gram.y:3803 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "курÑор \"%s\" не имеет аргумента \"%s\"" -#: pl_gram.y:3762 +#: pl_gram.y:3823 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "значение параметра \"%s\" курÑора \"%s\" указано неоднократно" -#: pl_gram.y:3787 +#: pl_gram.y:3848 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "недоÑтаточно аргументов Ð´Ð»Ñ ÐºÑƒÑ€Ñора \"%s\"" -#: pl_gram.y:3794 +#: pl_gram.y:3855 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "Ñлишком много аргументов Ð´Ð»Ñ ÐºÑƒÑ€Ñора \"%s\"" -#: pl_gram.y:3882 +#: pl_gram.y:3942 msgid "unrecognized RAISE statement option" msgstr "нераÑпознанный параметр оператора RAISE" -#: pl_gram.y:3886 +#: pl_gram.y:3946 msgid "syntax error, expected \"=\"" msgstr "ошибка ÑинтакÑиÑа, ожидалоÑÑŒ \"=\"" -#: pl_gram.y:3927 +#: pl_gram.y:3987 #, c-format msgid "too many parameters specified for RAISE" msgstr "Ñлишком много параметров Ð´Ð»Ñ RAISE" -#: pl_gram.y:3931 +#: pl_gram.y:3991 #, c-format msgid "too few parameters specified for RAISE" msgstr "недоÑтаточно параметров Ð´Ð»Ñ RAISE" @@ -857,17 +870,38 @@ msgid "List of programming constructs that should produce an error." msgstr "СпиÑок программных конÑтрукций, которые должны выдавать ошибку." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:624 +#: pl_scanner.c:630 #, c-format msgid "%s at end of input" msgstr "%s в конце" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:640 +#: pl_scanner.c:646 #, c-format msgid "%s at or near \"%s\"" msgstr "%s (примерное положение: \"%s\")" +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "отношение \"%s\" не ÑвлÑетÑÑ Ñ‚Ð°Ð±Ð»Ð¸Ñ†ÐµÐ¹" + +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" +#~ msgstr "" +#~ "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ \"%s\", объÑÐ²Ð»ÐµÐ½Ð½Ð°Ñ NOT NULL, не может иметь значение по " +#~ "умолчанию NULL" + +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "ИÑпользуйте блок BEGIN Ñ Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ EXCEPTION." + +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может быть конÑтантой" + +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может быть NULL" + +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "" +#~ "Ð¿ÐµÑ€ÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ñ‚Ð¸Ð¿Ð° кортеж или запиÑÑŒ не может иметь Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾ умолчанию" + #~ msgid "EXECUTE statement" #~ msgstr "оператор EXECUTE" diff --git a/src/pl/plpgsql/src/po/sv.po b/src/pl/plpgsql/src/po/sv.po index 780d220aa38..bbe2364c2cf 100644 --- a/src/pl/plpgsql/src/po/sv.po +++ b/src/pl/plpgsql/src/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for plpgsql # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: plpgsql (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-02 18:08+0000\n" -"PO-Revision-Date: 2017-08-05 15:50+0200\n" +"Project-Id-Version: plpgsql (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-10 19:08+0000\n" +"PO-Revision-Date: 2019-05-10 22:32+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,149 +17,144 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: pl_comp.c:433 pl_handler.c:451 +#: pl_comp.c:436 pl_handler.c:461 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "PL/pgSQL-funktioner kan inte acceptera typ %s" -#: pl_comp.c:514 +#: pl_comp.c:524 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "kunde inte bestämma aktuell returtyp för polymorfisk funktion \"%s\"" -#: pl_comp.c:544 +#: pl_comp.c:554 #, c-format msgid "trigger functions can only be called as triggers" msgstr "utlösarfunktioner kan bara anropas som utlösare" -#: pl_comp.c:548 pl_handler.c:436 +#: pl_comp.c:558 pl_handler.c:445 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "PL/pgSQL-funktioner kan inte returnera typ %s" -#: pl_comp.c:589 +#: pl_comp.c:597 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "utlösarfunktioner kan inte ha deklarerade argument" -#: pl_comp.c:590 +#: pl_comp.c:598 #, c-format msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "Argumenten till utlösaren kan accessas via TG_NARGS och TG_ARGV istället." -#: pl_comp.c:692 +#: pl_comp.c:721 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "händelseutlösarfunktioner kan inte ha deklarerade argument" -#: pl_comp.c:943 +#: pl_comp.c:980 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "kompilering av PL/pgSQL-funktion \"%s\" nära rad %d" -#: pl_comp.c:966 +#: pl_comp.c:1003 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "parameternamn \"%s\" angivet mer än en gÃ¥ng" -#: pl_comp.c:1076 +#: pl_comp.c:1115 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "kolumnreferens \"%s\" är tvetydig" -#: pl_comp.c:1078 +#: pl_comp.c:1117 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "Det kan referera till antingen en PL/pgSQL-variabel eller en tabellkolumn." -#: pl_comp.c:1258 pl_comp.c:1286 pl_exec.c:4584 pl_exec.c:4913 pl_exec.c:4998 -#: pl_exec.c:5089 +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "post \"%s\" saknar fält \"%s\"" -#: pl_comp.c:1818 +#: pl_comp.c:1765 #, c-format msgid "relation \"%s\" does not exist" msgstr "relationen \"%s\" existerar inte" -#: pl_comp.c:1927 +#: pl_comp.c:1857 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "variabel \"%s\" har pseudotyp %s" -#: pl_comp.c:1995 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "relation \"%s\" är inte en tabell" - -#: pl_comp.c:2155 +#: pl_comp.c:2037 #, c-format msgid "type \"%s\" is only a shell" msgstr "typ \"%s\" är bara ett skal" -#: pl_comp.c:2249 pl_comp.c:2302 +#: pl_comp.c:2134 pl_comp.c:2187 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "okänt avbrottsvillkor \"%s\"" -#: pl_comp.c:2510 +#: pl_comp.c:2401 #, c-format msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "kunde inte bestämma argumenttyp för polymorfisk funktion function \"%s\"" -#: pl_exec.c:355 pl_exec.c:644 pl_exec.c:914 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 msgid "during initialization of execution state" msgstr "unde initiering av körtillstÃ¥nd" -#: pl_exec.c:362 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "under sparande av anropsargument till lokala variabler" -#: pl_exec.c:447 pl_exec.c:796 +#: pl_exec.c:569 pl_exec.c:960 msgid "during function entry" msgstr "under funktionsingÃ¥ngen" -#: pl_exec.c:472 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "kontrollen nÃ¥dde slutet av funktionen utan RETURN" -#: pl_exec.c:479 +#: pl_exec.c:601 msgid "while casting return value to function's return type" msgstr "under typomvandling av returvärde till funktionens returtyp" -#: pl_exec.c:492 pl_exec.c:3101 +#: pl_exec.c:614 pl_exec.c:3556 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "en funktion som returnerar en mängd anropades i kontext som inte godtar en mängd" -#: pl_exec.c:530 pl_exec.c:2948 -msgid "returned record type does not match expected record type" -msgstr "returnerad posttyp matchar inte förväntad posttyp" - -#: pl_exec.c:585 pl_exec.c:825 pl_exec.c:949 +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 msgid "during function exit" msgstr "under funktionsavslutning" -#: pl_exec.c:821 pl_exec.c:945 +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 +msgid "returned record type does not match expected record type" +msgstr "returnerad posttyp matchar inte förväntad posttyp" + +#: pl_exec.c:985 pl_exec.c:1146 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "kontroll nÃ¥dde slutet pÃ¥ utlösarprocedur utan RETURN" -#: pl_exec.c:830 +#: pl_exec.c:994 #, c-format msgid "trigger procedure cannot return a set" msgstr "utlösarprocedur kan inte returnera en mängd" -#: pl_exec.c:852 +#: pl_exec.c:1033 pl_exec.c:1061 msgid "returned row structure does not match the structure of the triggering table" msgstr "returnerad radstruktur matchar inte strukturen pÃ¥ utlösande tabell" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:997 +#: pl_exec.c:1198 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "PL/pgSQL-funktion %s rad %d %s" @@ -167,311 +162,345 @@ msgstr "PL/pgSQL-funktion %s rad %d %s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:1008 +#: pl_exec.c:1209 #, c-format msgid "PL/pgSQL function %s %s" msgstr "PL/pgSQL-funktion %s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:1016 +#: pl_exec.c:1217 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "PL/pgSQL-funktion %s rad %d vid %s" -#: pl_exec.c:1022 +#: pl_exec.c:1223 #, c-format msgid "PL/pgSQL function %s" msgstr "PL/pgSQL-funktion %s" -#: pl_exec.c:1187 +#: pl_exec.c:1561 msgid "during statement block local variable initialization" msgstr "under initiering av lokala variabler i satsblock" -#: pl_exec.c:1226 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "variabel \"%s\" deklarerad NOT NULL kan inte default:a till NULL" - -#: pl_exec.c:1277 +#: pl_exec.c:1659 msgid "during statement block entry" msgstr "under ingÃ¥ng till satsblock" -#: pl_exec.c:1309 +#: pl_exec.c:1691 msgid "during statement block exit" msgstr "under satsblockavslutning" -#: pl_exec.c:1351 +#: pl_exec.c:1729 msgid "during exception cleanup" msgstr "under avbrottsuppstädning" -#: pl_exec.c:1717 +#: pl_exec.c:2225 +#, c-format +msgid "procedure parameter \"%s\" is an output parameter but corresponding argument is not writable" +msgstr "procedurparameter \"%s\" är en utdataparameter men motsvarande argument är inte skrivbar" + +#: pl_exec.c:2230 +#, c-format +msgid "procedure parameter %d is an output parameter but corresponding argument is not writable" +msgstr "procedurparameter %d är en utdataparameter men motsvarande argument är inte skrivbar" + +#: pl_exec.c:2341 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICS kan inte användas utanför en avbrottshanterare" -#: pl_exec.c:1922 +#: pl_exec.c:2540 #, c-format msgid "case not found" msgstr "hittade inte alternativ" -#: pl_exec.c:1923 +#: pl_exec.c:2541 #, c-format msgid "CASE statement is missing ELSE part." msgstr "CASE-sats saknar ELSE-del." -#: pl_exec.c:2077 +#: pl_exec.c:2634 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "lägre gräns i FOR-loop kan inte vara null" -#: pl_exec.c:2093 +#: pl_exec.c:2650 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "övre gräns i FOR-loop kan inte vara null" -#: pl_exec.c:2111 +#: pl_exec.c:2668 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "BY-värde i FOR-loop kan inte vara null" -#: pl_exec.c:2117 +#: pl_exec.c:2674 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "BY-värde i FOR-loop mÃ¥ste vara större än noll" -#: pl_exec.c:2294 pl_exec.c:4085 +#: pl_exec.c:2808 pl_exec.c:4530 #, c-format msgid "cursor \"%s\" already in use" msgstr "markören \"%s\" används redan" -#: pl_exec.c:2317 pl_exec.c:4150 +#: pl_exec.c:2831 pl_exec.c:4595 #, c-format msgid "arguments given for cursor without arguments" msgstr "argument angivna till markör utan argumnet" -#: pl_exec.c:2336 pl_exec.c:4169 +#: pl_exec.c:2850 pl_exec.c:4614 #, c-format msgid "arguments required for cursor" msgstr "argument krävs för markör" -#: pl_exec.c:2423 +#: pl_exec.c:2937 #, c-format msgid "FOREACH expression must not be null" msgstr "FOREACH-uttryck fÃ¥r inte vara null" -#: pl_exec.c:2438 +#: pl_exec.c:2952 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "FOREACH-uttryck mÃ¥ste ge en array, inte typ %s" -#: pl_exec.c:2455 +#: pl_exec.c:2969 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "slice-storlek (%d) är utanför giltigt intervall 0..%d" -#: pl_exec.c:2482 +#: pl_exec.c:2996 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "FOREACH ... SLICE-loop-variabel mÃ¥ste ha typen array" -#: pl_exec.c:2486 +#: pl_exec.c:3000 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "FOREACH-loop-variable fÃ¥r inte ha typen array" -#: pl_exec.c:2689 pl_exec.c:2771 pl_exec.c:2941 +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 #, c-format msgid "cannot return non-composite value from function returning composite type" msgstr "kan inte returnera icke-composit-värde frÃ¥n funktion med returtyp composit" -#: pl_exec.c:2815 pl_gram.y:3199 +#: pl_exec.c:3258 pl_gram.y:3305 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "kan inte använda RETURN NEXT i en icke-SETOF-funktion" -#: pl_exec.c:2849 pl_exec.c:2976 +#: pl_exec.c:3299 pl_exec.c:3431 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "fel resultattyp given i RETURN NEXT" -#: pl_exec.c:2878 pl_exec.c:4572 pl_exec.c:4880 pl_exec.c:4906 pl_exec.c:4972 -#: pl_exec.c:4991 pl_exec.c:5059 pl_exec.c:5082 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "posten \"%s\" är inte tilldelad än" - -#: pl_exec.c:2880 pl_exec.c:4574 pl_exec.c:4882 pl_exec.c:4908 pl_exec.c:4974 -#: pl_exec.c:4993 pl_exec.c:5061 pl_exec.c:5084 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "Tuple-strukturen av en ej-ännu-tilldelad post är obestämd." - -#: pl_exec.c:2887 pl_exec.c:2906 +#: pl_exec.c:3337 pl_exec.c:3358 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "fel posttyp given i RETURN NEXT" -#: pl_exec.c:2995 +#: pl_exec.c:3450 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXT mÃ¥ste ha en parameter" -#: pl_exec.c:3021 pl_gram.y:3261 +#: pl_exec.c:3476 pl_gram.y:3369 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "kan inte använda RETURN QUERY i en icke-SETOF-funktion" -#: pl_exec.c:3045 +#: pl_exec.c:3500 msgid "structure of query does not match function result type" msgstr "strukturen pÃ¥ frÃ¥gan matchar inte funktionens resultattyp" -#: pl_exec.c:3129 pl_exec.c:3267 +#: pl_exec.c:3584 pl_exec.c:3722 #, c-format msgid "RAISE option already specified: %s" msgstr "RAISE-flagga redan angiven: %s" -#: pl_exec.c:3163 +#: pl_exec.c:3618 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "RAISE utan parametrar kan inte användas utanför en avbrottshanterare" -#: pl_exec.c:3257 +#: pl_exec.c:3712 #, c-format msgid "RAISE statement option cannot be null" msgstr "RAISE-satsens flagga fÃ¥r inte vare null" -#: pl_exec.c:3327 +#: pl_exec.c:3782 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3382 +#: pl_exec.c:3837 #, c-format msgid "assertion failed" msgstr "assert misslyckades" -#: pl_exec.c:3583 pl_exec.c:3729 pl_exec.c:3919 +#: pl_exec.c:4179 pl_exec.c:4369 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "kan inte COPY till/frÃ¥n klient i PL/pgSQL" -#: pl_exec.c:3587 pl_exec.c:3733 pl_exec.c:3923 +#: pl_exec.c:4185 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "kan inte starta/avsluta transaktioner i PL/pgSQL" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "transaktionskommando saknar stöd i PL/pgSQL" -#: pl_exec.c:3588 pl_exec.c:3734 pl_exec.c:3924 -#, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "Använd ett BEGIN-block men en EXCEPTION-klausul istället." - -#: pl_exec.c:3757 pl_exec.c:3948 +#: pl_exec.c:4208 pl_exec.c:4398 #, c-format msgid "INTO used with a command that cannot return data" msgstr "INTO använd med ett kommando som inte returnerar data" -#: pl_exec.c:3785 pl_exec.c:3976 +#: pl_exec.c:4231 pl_exec.c:4421 #, c-format msgid "query returned no rows" msgstr "frÃ¥gan returnerade inga rader" -#: pl_exec.c:3804 pl_exec.c:3995 +#: pl_exec.c:4253 pl_exec.c:4440 #, c-format msgid "query returned more than one row" msgstr "frÃ¥gan returnerade mer än en rad" -#: pl_exec.c:3821 +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "Se till att frÃ¥gan returerar exakt en rad eller använd LIMIT 1." + +#: pl_exec.c:4271 #, c-format msgid "query has no destination for result data" msgstr "frÃ¥gan har ingen destination för resultatdatan" -#: pl_exec.c:3822 +#: pl_exec.c:4272 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "Om du vill slänga resultatet av en SELECT, använd PERFORM istället." -#: pl_exec.c:3855 pl_exec.c:7292 +#: pl_exec.c:4305 pl_exec.c:8416 #, c-format msgid "query string argument of EXECUTE is null" msgstr "frÃ¥gesträngargumentet till EXECUTE är null" -#: pl_exec.c:3911 +#: pl_exec.c:4361 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "EXECUTE för SELECT ... INTO är inte implementerad" -#: pl_exec.c:3912 +#: pl_exec.c:4362 #, c-format msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." msgstr "Du vill nog använda EXECUTE ... INTO eller EXECUTE CREATE TABLE ... AS istället." -#: pl_exec.c:4233 pl_exec.c:4329 +#: pl_exec.c:4375 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "EXECUTE pÃ¥ transaktionskommanon är inte implementerat" + +#: pl_exec.c:4676 pl_exec.c:4764 #, c-format msgid "cursor variable \"%s\" is null" msgstr "markörvariabel \"%s\" är null" -#: pl_exec.c:4244 pl_exec.c:4340 +#: pl_exec.c:4687 pl_exec.c:4775 #, c-format msgid "cursor \"%s\" does not exist" msgstr "markör \"%s\" existerar inte" -#: pl_exec.c:4257 +#: pl_exec.c:4700 #, c-format msgid "relative or absolute cursor position is null" msgstr "relativ eller absolut markörposition är null" -#: pl_exec.c:4448 +#: pl_exec.c:4956 pl_exec.c:5051 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "null-value kan inte tilldelas till variabel \"%s\" som deklarerats NOT NULL" -#: pl_exec.c:4517 +#: pl_exec.c:5032 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "kan inte tilldela icke-composite-värde till radvariabel" -#: pl_exec.c:4541 +#: pl_exec.c:5064 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "kan inte tilldela icke-composite-värde till en post-variabel" -#: pl_exec.c:4661 +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "kan inte skriva till systemkolumn \"%s\"" + +#: pl_exec.c:5179 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "antalet array-dimensioner (%d) överskrider det maximalt tillÃ¥tna (%d)" -#: pl_exec.c:4693 +#: pl_exec.c:5211 #, c-format msgid "subscripted object is not an array" msgstr "arrayindexobjekt är inte en array" -#: pl_exec.c:4731 +#: pl_exec.c:5249 #, c-format msgid "array subscript in assignment must not be null" msgstr "arrayindex i tilldelning kan inte vara null" -#: pl_exec.c:5198 +#: pl_exec.c:5756 #, c-format msgid "query \"%s\" did not return data" msgstr "frÃ¥gan \"%s\" returnerade ingen data" -#: pl_exec.c:5206 +#: pl_exec.c:5764 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "frÃ¥gan \"%s\" returnerade %d kolumn" msgstr[1] "frÃ¥gan \"%s\" returnerade %d kolumner" -#: pl_exec.c:5233 +#: pl_exec.c:5792 #, c-format msgid "query \"%s\" returned more than one row" msgstr "frÃ¥gan \"%s\" returnerade mer än en rad" -#: pl_exec.c:5301 +#: pl_exec.c:5855 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "frÃ¥gan \"%s\" är inte en SELECT" +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "typen av parameter %d (%s) matchar inte det som var vid preparerande av plan (%s)" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment does not match" +msgstr "antal käll- och mÃ¥l-fält i tilldelningen matchar inte" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "%s kontroll av %s är aktiv." + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "Se till att frÃ¥gan returerar exakt rätt lista med kolumner." + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "posten \"%s\" är inte tilldelad än" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "Tuple-strukturen av en ej-ännu-tilldelad post är obestämd." + #: pl_funcs.c:239 msgid "statement block" msgstr "satsblock" @@ -504,317 +533,312 @@ msgstr "SQL-sats" msgid "FOR over EXECUTE statement" msgstr "FOR över EXECUTE-sats" -#: pl_gram.y:478 +#: pl_gram.y:489 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "blocketikett mÃ¥ste anges före DECLARE, inte efter" -#: pl_gram.y:498 +#: pl_gram.y:509 #, c-format msgid "collations are not supported by type %s" -msgstr "sorteringar stöds inte för typ %s" - -#: pl_gram.y:513 -#, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "rad- eller post-variabel fÃ¥r inte vara CONSTANT" +msgstr "jämförelser stöds inte för typ %s" -#: pl_gram.y:523 +#: pl_gram.y:528 #, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "rad- eller post-variabel fÃ¥r inte vara NOT NULL" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "variabel \"%s\" mÃ¥ste ha ett default-värde dÃ¥ det inte deklarerats som NOT NULL" -#: pl_gram.y:534 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "standardvärde för rad- eller post-variabel stöds inte" - -#: pl_gram.y:679 pl_gram.y:694 pl_gram.y:720 +#: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 #, c-format msgid "variable \"%s\" does not exist" msgstr "variabel \"%s\" finns inte" -#: pl_gram.y:738 pl_gram.y:766 +#: pl_gram.y:733 pl_gram.y:761 msgid "duplicate declaration" msgstr "duplicerad deklaration" -#: pl_gram.y:749 pl_gram.y:777 +#: pl_gram.y:744 pl_gram.y:772 #, c-format msgid "variable \"%s\" shadows a previously defined variable" msgstr "variabeln \"%s\" döljer en tidigare definierad variabel" -#: pl_gram.y:956 +#: pl_gram.y:992 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "diagnostikdel %s tillÃ¥ts inte i GET STACKED DIAGNOSTICS" -#: pl_gram.y:974 +#: pl_gram.y:1010 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "diagnostikdel %s tillÃ¥ts inte i GET CURRENT DIAGNOSTICS" -#: pl_gram.y:1072 +#: pl_gram.y:1105 msgid "unrecognized GET DIAGNOSTICS item" msgstr "okänd GET DIAGNOSTICS-del" -#: pl_gram.y:1082 pl_gram.y:3448 +#: pl_gram.y:1115 pl_gram.y:3549 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" är inte ett skalärt värde" -#: pl_gram.y:1334 pl_gram.y:1528 +#: pl_gram.y:1369 pl_gram.y:1565 #, c-format -msgid "loop variable of loop over rows must be a record or row variable or list of scalar variables" -msgstr "loop-variabeln för loop över rader mÃ¥ste vara en post- eller rad-variabel alternativt en lista av skalärvariabler" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "loop-variabeln för loop över rader mÃ¥ste vara en postvariabel eller en lista av skalärvariabler" -#: pl_gram.y:1368 +#: pl_gram.y:1404 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "markör-FOR-loop mÃ¥ste ha exakt en mÃ¥lvariabel" -#: pl_gram.y:1375 +#: pl_gram.y:1411 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "markör-FOR-loop mÃ¥ste använda en bunden markörvariabel" -#: pl_gram.y:1459 +#: pl_gram.y:1498 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "heltals-FOR-loop mÃ¥ste ha exakt en mÃ¥lvariabel" -#: pl_gram.y:1495 +#: pl_gram.y:1535 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "kan inte ange REVERSE i frÃ¥ge-FOR-loop" -#: pl_gram.y:1642 +#: pl_gram.y:1668 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "loop-variabel för FOREACH mÃ¥ste vara en känd variabel eller lista av variabler" -#: pl_gram.y:1683 +#: pl_gram.y:1710 #, c-format msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" msgstr "det finns ingen etikett \"%s\" kopplad till nÃ¥got block eller loop-omslutning i denna sats" -#: pl_gram.y:1691 +#: pl_gram.y:1718 #, c-format msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "blocketikett \"%s\" kan inte användas i CONTINUE" -#: pl_gram.y:1706 +#: pl_gram.y:1733 #, c-format msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "EXIT kan inte användas utanför en loop, om den inte har en etikett" -#: pl_gram.y:1707 +#: pl_gram.y:1734 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "CONTINUE kan inte användas utanför en loop" -#: pl_gram.y:1731 pl_gram.y:1768 pl_gram.y:1816 pl_gram.y:2898 pl_gram.y:2983 -#: pl_gram.y:3094 pl_gram.y:3850 +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 msgid "unexpected end of function definition" msgstr "oväntat slut pÃ¥ funktionsdefinitionen" -#: pl_gram.y:1836 pl_gram.y:1860 pl_gram.y:1876 pl_gram.y:1882 pl_gram.y:2000 -#: pl_gram.y:2008 pl_gram.y:2022 pl_gram.y:2117 pl_gram.y:2304 pl_gram.y:2398 -#: pl_gram.y:2550 pl_gram.y:3691 pl_gram.y:3752 pl_gram.y:3831 +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 msgid "syntax error" msgstr "syntaxfel" -#: pl_gram.y:1864 pl_gram.y:1866 pl_gram.y:2308 pl_gram.y:2310 +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 msgid "invalid SQLSTATE code" msgstr "ogiltig SQLSTATE-kod" -#: pl_gram.y:2064 +#: pl_gram.y:2094 msgid "syntax error, expected \"FOR\"" msgstr "syntaxfel, förväntade \"FOR\"" -#: pl_gram.y:2126 +#: pl_gram.y:2155 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "FETCH-sats kan inte returnera multipla rader" -#: pl_gram.y:2188 +#: pl_gram.y:2279 #, c-format msgid "cursor variable must be a simple variable" msgstr "markörvariabel mÃ¥ste vara en enkel variabel" -#: pl_gram.y:2194 +#: pl_gram.y:2285 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "variabel \"%s\" mÃ¥ste ha typen cursor eller refcursor" -#: pl_gram.y:2521 pl_gram.y:2532 +#: pl_gram.y:2619 pl_gram.y:2630 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" är inte en känd variabel" -#: pl_gram.y:2636 pl_gram.y:2646 pl_gram.y:2802 +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 msgid "mismatched parentheses" msgstr "missmatchade parenteser" -#: pl_gram.y:2650 +#: pl_gram.y:2748 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "saknar \"%s\" vid slutet av SQL-uttryck" -#: pl_gram.y:2656 +#: pl_gram.y:2754 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "saknar \"%s\" vid slutet av SQL-sats" -#: pl_gram.y:2673 +#: pl_gram.y:2771 msgid "missing expression" msgstr "saknar uttryck" -#: pl_gram.y:2675 +#: pl_gram.y:2773 msgid "missing SQL statement" msgstr "saknars SQL-sats" -#: pl_gram.y:2804 +#: pl_gram.y:2901 msgid "incomplete data type declaration" msgstr "inkomplett datatypdeklaration" -#: pl_gram.y:2827 +#: pl_gram.y:2924 msgid "missing data type declaration" msgstr "saknar datatypdeklaration" -#: pl_gram.y:2906 +#: pl_gram.y:3002 msgid "INTO specified more than once" msgstr "INTO angiven mer än en gÃ¥ng" -#: pl_gram.y:3075 +#: pl_gram.y:3171 msgid "expected FROM or IN" msgstr "förväntade FROM eller IN" -#: pl_gram.y:3135 +#: pl_gram.y:3232 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "RETURN kan inte ha en parameter i funktion som returnerar en mängd" -#: pl_gram.y:3136 +#: pl_gram.y:3233 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "Använd RETURN NEXT eller RETURN QUERY." -#: pl_gram.y:3144 +#: pl_gram.y:3243 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "RETURN kan inte ha en parameter i en funktion med OUT-parameterar" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN kan inte ha en parameter i en procedur" -#: pl_gram.y:3153 +#: pl_gram.y:3248 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "RETURN kan inte ha en parameter i funktion som returnerar void" -#: pl_gram.y:3213 +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN kan inte ha en parameter i en funktion med OUT-parameterar" + +#: pl_gram.y:3320 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "RETURN NEXT kan inte ha en parameter i funktion med OUT-parametrar" -#: pl_gram.y:3317 +#: pl_gram.y:3428 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\" är deklarerad CONSTANT" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "variabel \"%s\" är deklarerad CONSTANT" -#: pl_gram.y:3379 pl_gram.y:3391 +#: pl_gram.y:3491 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "post- eller rad-variabel kan inte vara del av en multipel-INTO-lista" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "postvariabel kan inte vara del av en multipel-INTO-lista" -#: pl_gram.y:3436 +#: pl_gram.y:3537 #, c-format msgid "too many INTO variables specified" msgstr "för mÃ¥nga INTO-variabler angivna" -#: pl_gram.y:3644 +#: pl_gram.y:3745 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "slutetikett \"%s\" angiven för block utan etikett" -#: pl_gram.y:3651 +#: pl_gram.y:3752 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "slutetikett \"%s\" stämmer inte med blockets etikett \"%s\"" -#: pl_gram.y:3686 +#: pl_gram.y:3787 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "markör \"%s\" har inga argument" -#: pl_gram.y:3700 +#: pl_gram.y:3801 #, c-format msgid "cursor \"%s\" has arguments" msgstr "markör \"%s\" har argument" -#: pl_gram.y:3742 +#: pl_gram.y:3843 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "markör \"%s\" har inga argument med namn \"%s\"" -#: pl_gram.y:3762 +#: pl_gram.y:3863 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "värdet för parameter \"%s\" i markör \"%s\" är angivet mer än en gÃ¥ng" -#: pl_gram.y:3787 +#: pl_gram.y:3888 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "ej tillräckligt med argument för markör \"%s\"" -#: pl_gram.y:3794 +#: pl_gram.y:3895 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "fär mÃ¥nga argument för markör \"%s\"" -#: pl_gram.y:3882 +#: pl_gram.y:3982 msgid "unrecognized RAISE statement option" msgstr "okänd RAISE-sats-flagga" -#: pl_gram.y:3886 +#: pl_gram.y:3986 msgid "syntax error, expected \"=\"" msgstr "syntaxfel, förväntade \"=\"" -#: pl_gram.y:3927 +#: pl_gram.y:4027 #, c-format msgid "too many parameters specified for RAISE" msgstr "för mÃ¥nga parametrar angivna för RAISE" -#: pl_gram.y:3931 +#: pl_gram.y:4031 #, c-format msgid "too few parameters specified for RAISE" msgstr "för fÃ¥ parametrar angivna för RAISE" -#: pl_handler.c:154 +#: pl_handler.c:158 msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "Sätter hantering av konflikter mellan PL/pgSQL-variabelnamn och tabellkolumnnamn." -#: pl_handler.c:163 +#: pl_handler.c:167 msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." msgstr "Skriv information om parametrar i DETAIL-delen av felmeddelanden vid INTO ... STRICT-fel." -#: pl_handler.c:171 +#: pl_handler.c:175 msgid "Perform checks given in ASSERT statements." msgstr "Utför kontroller angivna i ASSERT-satser." -#: pl_handler.c:179 +#: pl_handler.c:183 msgid "List of programming constructs that should produce a warning." msgstr "Lista av programmeringskonstruktioner som skall ge en varning." -#: pl_handler.c:189 +#: pl_handler.c:193 msgid "List of programming constructs that should produce an error." msgstr "Lista av programmeringskonstruktioner som skall ge ett fel" #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:624 +#: pl_scanner.c:508 #, c-format msgid "%s at end of input" msgstr "%s vid slutet av indatan" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:640 +#: pl_scanner.c:524 #, c-format msgid "%s at or near \"%s\"" msgstr "%s vid eller nära \"%s\"" diff --git a/src/pl/plpgsql/src/po/tr.po b/src/pl/plpgsql/src/po/tr.po new file mode 100644 index 00000000000..907f2c6969e --- /dev/null +++ b/src/pl/plpgsql/src/po/tr.po @@ -0,0 +1,929 @@ +# LANGUAGE message translation file for plpgsql +# Copyright (C) 2009 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2009. +# Abdullah Gülner , 2017, 2018, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 8.4\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:38+0000\n" +"PO-Revision-Date: 2019-06-13 17:09+0300\n" +"Last-Translator: Abdullah Gülner\n" +"Language-Team: TR \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: pl_comp.c:436 pl_handler.c:461 +#, c-format +msgid "PL/pgSQL functions cannot accept type %s" +msgstr "PL/pgSQL fonksiyonları %s veri tipini kabul etmezler" + +#: pl_comp.c:524 +#, c-format +msgid "could not determine actual return type for polymorphic function \"%s\"" +msgstr "\"%s\" polimorfik fonksiyonunun asıl dönüşdeÄŸeri belirlenemedi" + +#: pl_comp.c:554 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "trigger fonksiyonları sadece trigger olarak çağırılabilirler" + +#: pl_comp.c:558 pl_handler.c:445 +#, c-format +msgid "PL/pgSQL functions cannot return type %s" +msgstr "PL/pgSQL fonksiyonları %s tipini döndüremezler" + +#: pl_comp.c:597 +#, c-format +msgid "trigger functions cannot have declared arguments" +msgstr "trigger fonksiyonları belirtilmiÅŸ (declared) argümanlara sahip olamaz" + +#: pl_comp.c:598 +#, c-format +msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." +msgstr "Tetikleyici bağımsız deÄŸiÅŸkenlerine TG_NARGS ve TG_ARGV üzerinden eriÅŸilebilir." + +#: pl_comp.c:721 +#, c-format +msgid "event trigger functions cannot have declared arguments" +msgstr "olay tetikleyici (trigger) fonksiyonları belirtilmiÅŸ (declared) argümanlara sahip olamaz" + +#: pl_comp.c:980 +#, c-format +msgid "compilation of PL/pgSQL function \"%s\" near line %d" +msgstr "\"%s\" fonkiyonununun %d numaralı satırının civarlarında derlenmesi" + +#: pl_comp.c:1003 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "\"%s\" parametresi birden fazla kez kullanılmıştır" + +#: pl_comp.c:1115 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "\"%s\" sütun referansı iki anlamlı" + +#: pl_comp.c:1117 +#, c-format +msgid "It could refer to either a PL/pgSQL variable or a table column." +msgstr "Ya bir PL/pgSQL deÄŸiÅŸkenine ya da bir tablo sütununa atıfta bulunuyor olabilir." + +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 +#, c-format +msgid "record \"%s\" has no field \"%s\"" +msgstr "\"%s\" kaydı \"%s\" alanını içermiyor" + +#: pl_comp.c:1765 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "\"%s\" nesnesi mevcut deÄŸil" + +#: pl_comp.c:1857 +#, c-format +msgid "variable \"%s\" has pseudo-type %s" +msgstr "\"%s\" deÄŸiÅŸkeni %s pseudo tipine sahip" + +#: pl_comp.c:2037 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "\"%s\" tipi bir shelldir" + +#: pl_comp.c:2134 pl_comp.c:2187 +#, c-format +msgid "unrecognized exception condition \"%s\"" +msgstr "tanımlanamayan exception durumu \"%s\"" + +#: pl_comp.c:2401 +#, c-format +msgid "could not determine actual argument type for polymorphic function \"%s\"" +msgstr "\"%s\" polimorfik fonksiyonu için gerçek argüman tipi belirlenemedi" + +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 +msgid "during initialization of execution state" +msgstr "çalıştırma durumu ilklendirmesi sırasında" + +#: pl_exec.c:481 +msgid "while storing call arguments into local variables" +msgstr "çaÄŸrı argümanlarını yerel deÄŸiÅŸkenlerde saklarken" + +#: pl_exec.c:569 pl_exec.c:960 +msgid "during function entry" +msgstr "fonksiyon giriÅŸi sırasında" + +#: pl_exec.c:594 +#, c-format +msgid "control reached end of function without RETURN" +msgstr "control fonksiyonun sonuna RETURNsüz ulaÅŸtı" + +#: pl_exec.c:601 +msgid "while casting return value to function's return type" +msgstr "dönüş deÄŸerini fonksiyonun dönüş tipine dönüştürürken" + +#: pl_exec.c:614 pl_exec.c:3556 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "set deÄŸerini kabul etmediÄŸi ortamda set deÄŸeri alan fonksiyon çağırılmış" + +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 +msgid "during function exit" +msgstr "fonksiyon çıkışı sırasında" + +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 +msgid "returned record type does not match expected record type" +msgstr "dönen kayıt tipi beklenen kayıt tipine uymuyor" + +#: pl_exec.c:985 pl_exec.c:1146 +#, c-format +msgid "control reached end of trigger procedure without RETURN" +msgstr "trigger yordamı RETURN olmadan bitti" + +#: pl_exec.c:994 +#, c-format +msgid "trigger procedure cannot return a set" +msgstr "trigger yordamı bir küme döndüremez" + +#: pl_exec.c:1033 pl_exec.c:1061 +msgid "returned row structure does not match the structure of the triggering table" +msgstr "dönen satır yapısı tetikleyen tablonun yapısına uymuyor" + +#. translator: last %s is a phrase such as "during statement block +#. local variable initialization" +#. +#: pl_exec.c:1198 +#, c-format +msgid "PL/pgSQL function %s line %d %s" +msgstr "PL/pgSQL fonksiyonu %s satır %d %s" + +#. translator: last %s is a phrase such as "while storing call +#. arguments into local variables" +#. +#: pl_exec.c:1209 +#, c-format +msgid "PL/pgSQL function %s %s" +msgstr "PL/pgSQL fonksiyonu %s %s" + +#. translator: last %s is a plpgsql statement type name +#: pl_exec.c:1217 +#, c-format +msgid "PL/pgSQL function %s line %d at %s" +msgstr "%s PL/pgSQL fonksiyonu, %d. satır, %s içinde" + +#: pl_exec.c:1223 +#, c-format +msgid "PL/pgSQL function %s" +msgstr "PL/pgSQL fonksiyonu %s" + +#: pl_exec.c:1561 +msgid "during statement block local variable initialization" +msgstr "ifade (statement) bloÄŸu yerel deÄŸiÅŸken ilklendirmesi sırasında" + +#: pl_exec.c:1659 +msgid "during statement block entry" +msgstr "ifade bloÄŸu giriÅŸi sırasında" + +#: pl_exec.c:1691 +msgid "during statement block exit" +msgstr "ifade bloÄŸu çıkışı sırasında" + +#: pl_exec.c:1729 +msgid "during exception cleanup" +msgstr "exception temizlemesi sırasında" + +#: pl_exec.c:2225 +#, c-format +msgid "procedure parameter \"%s\" is an output parameter but corresponding argument is not writable" +msgstr "\"%s\" prosedür parametresi bir çıktı (output) parametresidir fakat karşılık gelen parametre yazılabilir deÄŸil" + +#: pl_exec.c:2230 +#, c-format +msgid "procedure parameter %d is an output parameter but corresponding argument is not writable" +msgstr "%d prosedür parametresi bir çıktı (output) parametresidir fakat karşılık gelen parametre yazılabilir deÄŸil" + +#: pl_exec.c:2341 +#, c-format +msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" +msgstr "GET STACKED DIAGNOSTICS özel durum iÅŸleyici (exception handler) dışında kullanılamaz" + +#: pl_exec.c:2540 +#, c-format +msgid "case not found" +msgstr "case bulunamadı" + +#: pl_exec.c:2541 +#, c-format +msgid "CASE statement is missing ELSE part." +msgstr "CASE ifadesindeki ELSE eksik." + +#: pl_exec.c:2634 +#, c-format +msgid "lower bound of FOR loop cannot be null" +msgstr "FOR döngüsünün alt sınırı null olamaz" + +#: pl_exec.c:2650 +#, c-format +msgid "upper bound of FOR loop cannot be null" +msgstr "For döngüsünün üst sınırı null olamaz" + +#: pl_exec.c:2668 +#, c-format +msgid "BY value of FOR loop cannot be null" +msgstr "FOR döngüsünün BY deÄŸeri null olamaz" + +#: pl_exec.c:2674 +#, c-format +msgid "BY value of FOR loop must be greater than zero" +msgstr "FOR döngüsünn BY deÄŸeri sıfırdan büyük olmalıdır" + +#: pl_exec.c:2808 pl_exec.c:4530 +#, c-format +msgid "cursor \"%s\" already in use" +msgstr "\"%s\" imleci kullanımda" + +#: pl_exec.c:2831 pl_exec.c:4595 +#, c-format +msgid "arguments given for cursor without arguments" +msgstr "argümansız imleç (cursor) için verilen argümanlar" + +#: pl_exec.c:2850 pl_exec.c:4614 +#, c-format +msgid "arguments required for cursor" +msgstr "imleç için gereken argümanlar" + +#: pl_exec.c:2937 +#, c-format +msgid "FOREACH expression must not be null" +msgstr "FOREACH ifadesi NULL olamaz" + +#: pl_exec.c:2952 +#, c-format +msgid "FOREACH expression must yield an array, not type %s" +msgstr "FOREACH ifadesi %s deÄŸil bir dizi (array) saÄŸlamalı" + +#: pl_exec.c:2969 +#, c-format +msgid "slice dimension (%d) is out of the valid range 0..%d" +msgstr "slice boyutu (%d) geçerli kapsamın dışındadır: 0..%d" + +#: pl_exec.c:2996 +#, c-format +msgid "FOREACH ... SLICE loop variable must be of an array type" +msgstr "FOREACH ... SLICE döngü deÄŸiÅŸkeni bir dizi (array) tipinde olmalı" + +#: pl_exec.c:3000 +#, c-format +msgid "FOREACH loop variable must not be of an array type" +msgstr "FOREACH döngü deÄŸiÅŸkeni dizgi tipinde olamaz" + +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 +#, c-format +msgid "cannot return non-composite value from function returning composite type" +msgstr "bileÅŸik tip dönen fonksiyondan bileÅŸik olmayan deÄŸer döndürülemez" + +#: pl_exec.c:3258 pl_gram.y:3305 +#, c-format +msgid "cannot use RETURN NEXT in a non-SETOF function" +msgstr "SETOF olmayan fonksiyonda RETURN NEXT kullanılamaz" + +#: pl_exec.c:3299 pl_exec.c:3431 +#, c-format +msgid "wrong result type supplied in RETURN NEXT" +msgstr "RETURN NEXT içinde yanlış dönüş tipi verildi" + +#: pl_exec.c:3337 pl_exec.c:3358 +#, c-format +msgid "wrong record type supplied in RETURN NEXT" +msgstr "RETURN NEXT içinde yanlış kayıt tipi verildi" + +#: pl_exec.c:3450 +#, c-format +msgid "RETURN NEXT must have a parameter" +msgstr "RETURN NEXT bir parameter içermeli" + +#: pl_exec.c:3476 pl_gram.y:3369 +#, c-format +msgid "cannot use RETURN QUERY in a non-SETOF function" +msgstr "RETURN QUERY, SETOF olmayan bir fonksiyon içinde bulunamaz" + +#: pl_exec.c:3500 +msgid "structure of query does not match function result type" +msgstr "sorgunun yapısı fonksiyonun sonuç tipine uymuyor" + +#: pl_exec.c:3584 pl_exec.c:3722 +#, c-format +msgid "RAISE option already specified: %s" +msgstr "RAISE seçeneÄŸi zaten belirtilmiÅŸ: %s" + +#: pl_exec.c:3618 +#, c-format +msgid "RAISE without parameters cannot be used outside an exception handler" +msgstr "parametresi olmayan RAISE bir özel durum iÅŸleyici (exception handler) dışında kullanılamaz" + +#: pl_exec.c:3712 +#, c-format +msgid "RAISE statement option cannot be null" +msgstr "RAISE ifadesi seçeneÄŸi null olamaz" + +#: pl_exec.c:3782 +#, c-format +msgid "%s" +msgstr "%s" + +#: pl_exec.c:3837 +#, c-format +msgid "assertion failed" +msgstr "ısrar hatası" + +#: pl_exec.c:4179 pl_exec.c:4369 +#, c-format +msgid "cannot COPY to/from client in PL/pgSQL" +msgstr "PL/pgSQL'de istemcide ya da istemciden COPY çalıştırılamaz" + +#: pl_exec.c:4185 +#, c-format +msgid "unsupported transaction command in PL/pgSQL" +msgstr "PL/pgSQL'de desteklenmeyen iÅŸlem (transaction) komutu" + +#: pl_exec.c:4208 pl_exec.c:4398 +#, c-format +msgid "INTO used with a command that cannot return data" +msgstr "Veri döndüremeyen bir komutta INTO kullanıldı" + +#: pl_exec.c:4231 pl_exec.c:4421 +#, c-format +msgid "query returned no rows" +msgstr "sorgu satır döndürmedi" + +#: pl_exec.c:4253 pl_exec.c:4440 +#, c-format +msgid "query returned more than one row" +msgstr "sorgu birden fazla satır döndürdü" + +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "Sorgunun tek bir satır döndürdüğünden emin olun, veya LIMIT 1 kullanın." + +#: pl_exec.c:4271 +#, c-format +msgid "query has no destination for result data" +msgstr "Sorgu sonuç verisi için bir hedef içermiyor" + +#: pl_exec.c:4272 +#, c-format +msgid "If you want to discard the results of a SELECT, use PERFORM instead." +msgstr "SELECT'den gelen sonuçları gözardı etmek istiyorsanız SELECT yerine PERFORM kullanın." + +#: pl_exec.c:4305 pl_exec.c:8416 +#, c-format +msgid "query string argument of EXECUTE is null" +msgstr "EXECUTE' un sorgu dizesi argümanı boÅŸtur (null)" + +#: pl_exec.c:4361 +#, c-format +msgid "EXECUTE of SELECT ... INTO is not implemented" +msgstr "EXECUTE of SELECT ... INTO kodlanmadı" + +#: pl_exec.c:4362 +#, c-format +msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." +msgstr "Bunun yerine, EXECUTE ... INTO ya da EXECUTE CREATE TABLE ... AS kullanmak isteyebilirsiniz." + +#: pl_exec.c:4375 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "iÅŸlem (transaction) komutlarının EXECUTE'u implement edilmemiÅŸtir" + +#: pl_exec.c:4676 pl_exec.c:4764 +#, c-format +msgid "cursor variable \"%s\" is null" +msgstr "\"%s\" imleç deÄŸiÅŸkeni null'dır" + +#: pl_exec.c:4687 pl_exec.c:4775 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "\"%s\" imleci mevcut deÄŸil" + +#: pl_exec.c:4700 +#, c-format +msgid "relative or absolute cursor position is null" +msgstr "bağıl ya da mutlak imleç pozisyonu null" + +#: pl_exec.c:4956 pl_exec.c:5051 +#, c-format +msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" +msgstr "NOT NULL olarak belirtilen \"%s\" deÄŸiÅŸkenine null deÄŸer atanamaz" + +#: pl_exec.c:5032 +#, c-format +msgid "cannot assign non-composite value to a row variable" +msgstr "bir satır deÄŸiÅŸkenine bileÅŸik olmayan bir deÄŸer atanamaz" + +#: pl_exec.c:5064 +#, c-format +msgid "cannot assign non-composite value to a record variable" +msgstr "bir kayıt deÄŸiÅŸkenine bileÅŸik olmayan bir deÄŸer atanamaz" + +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "\"%s\" sistem sütununa veri atanamıyor" + +#: pl_exec.c:5179 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "dizin boyut sayısı (%d), izin verilern en yüksek deÄŸerini (%d) aÅŸmaktadır" + +#: pl_exec.c:5211 +#, c-format +msgid "subscripted object is not an array" +msgstr "subscript edilen nesne bir dizi (array) deÄŸil" + +#: pl_exec.c:5249 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "atamada array subscript null olamaz" + +#: pl_exec.c:5756 +#, c-format +msgid "query \"%s\" did not return data" +msgstr "\"%s\" sorgusu veri döndürmedi" + +#: pl_exec.c:5764 +#, c-format +msgid "query \"%s\" returned %d column" +msgid_plural "query \"%s\" returned %d columns" +msgstr[0] "\"%s\" sorgusu %d kolon döndürdü" + +#: pl_exec.c:5792 +#, c-format +msgid "query \"%s\" returned more than one row" +msgstr "\"%s\" sorgusu birden fazla satır döndürdü" + +#: pl_exec.c:5855 +#, c-format +msgid "query \"%s\" is not a SELECT" +msgstr "\"%s\" sorgusu bir SELECT deÄŸil" + +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "%d parametresinin tipi (%s) planın hazırlandığı andakiyle (%s) uyuÅŸmuyor" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment do not match" +msgstr "atamadaki (assignment) kaynak ve hedef alanları eÅŸleÅŸmiyor" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "%2$s'nin %1$s denetimi etkindir." + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "Sorgunun sütunların tam listesini döndürdüğünden emin olun." + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "\"%s\" kaydı henüz atanmamış" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "Henüz atanmamış kaydın satır yapısı belirsizdir." + +#: pl_funcs.c:239 +msgid "statement block" +msgstr "ifade bloÄŸu" + +#: pl_funcs.c:241 +msgid "assignment" +msgstr "atama" + +#: pl_funcs.c:251 +msgid "FOR with integer loop variable" +msgstr "tamsayı döngüsünde FOR" + +#: pl_funcs.c:253 +msgid "FOR over SELECT rows" +msgstr "FOR over SELECT rows" + +#: pl_funcs.c:255 +msgid "FOR over cursor" +msgstr "FOR over cursor" + +#: pl_funcs.c:257 +msgid "FOREACH over array" +msgstr "FOREACH dizgi üstünde" + +#: pl_funcs.c:271 +msgid "SQL statement" +msgstr "SQL ifadesi" + +#: pl_funcs.c:275 +msgid "FOR over EXECUTE statement" +msgstr "EXECUTE ifadesinde FOR" + +#: pl_gram.y:489 +#, c-format +msgid "block label must be placed before DECLARE, not after" +msgstr "blok etiketi DECLARE'den önce yerleÅŸtirilmelidir, sonra deÄŸil." + +#: pl_gram.y:509 +#, c-format +msgid "collations are not supported by type %s" +msgstr "%s veri tipinde collation desteklenmemektedir" + +#: pl_gram.y:528 +#, c-format +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "\"%s\" deÄŸiÅŸkeni NOT NULL olarak tanımlandığı için varsayılan (default) bir deÄŸeri olmalı" + +#: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 +#, c-format +msgid "variable \"%s\" does not exist" +msgstr "\"%s\" deÄŸiÅŸkeni mevcut deÄŸil" + +#: pl_gram.y:733 pl_gram.y:761 +msgid "duplicate declaration" +msgstr "tekrarlanmış veri tipi deklarasyonu" + +#: pl_gram.y:744 pl_gram.y:772 +#, c-format +msgid "variable \"%s\" shadows a previously defined variable" +msgstr "\"%s\" deÄŸiÅŸkeni daha önce tanımlanan bir deÄŸiÅŸkeni gölgeliyor" + +#: pl_gram.y:992 +#, c-format +msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" +msgstr "%s tanılayıcı elemanı GET STACKED DIAGNOSTICS içinde kullanılamaz" + +#: pl_gram.y:1010 +#, c-format +msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" +msgstr "%s tanılayıcı elemanı GET CURRENT DIAGNOSTICS içinde kullanılamaz" + +#: pl_gram.y:1105 +msgid "unrecognized GET DIAGNOSTICS item" +msgstr "tanımlanamayan GET DIAGNOSTICS öğesi" + +#: pl_gram.y:1115 pl_gram.y:3549 +#, c-format +msgid "\"%s\" is not a scalar variable" +msgstr "\"%s\" scalar bir deÄŸiÅŸken deÄŸil" + +#: pl_gram.y:1369 pl_gram.y:1565 +#, c-format +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "döngü satırları üzerindeki döngü deÄŸiÅŸkeni, bir kayıt veya satır deÄŸiÅŸkeni veya sayısal (scalar) deÄŸiÅŸkenlerin listesi olmalıdır" + +#: pl_gram.y:1404 +#, c-format +msgid "cursor FOR loop must have only one target variable" +msgstr "imleç (cursor) FOR döngüsünde sadece bir tane hedef deÄŸiÅŸken olabilir" + +#: pl_gram.y:1411 +#, c-format +msgid "cursor FOR loop must use a bound cursor variable" +msgstr "imleç (cursor) FOR döngüsü bir sınırlı (bound) imleç (cursor) deÄŸiÅŸkeni kullanmalı" + +#: pl_gram.y:1498 +#, c-format +msgid "integer FOR loop must have only one target variable" +msgstr "Tamsayı FOR döngüsünde sadece bir tane hedef deÄŸiÅŸken olabilir" + +#: pl_gram.y:1535 +#, c-format +msgid "cannot specify REVERSE in query FOR loop" +msgstr "FOR döngü sorgusu içinde REVERSE belirtilemez" + +#: pl_gram.y:1668 +#, c-format +msgid "loop variable of FOREACH must be a known variable or list of variables" +msgstr "FOREACH'in döngü deÄŸiÅŸkeni bilinen bir deÄŸiÅŸken ya da deÄŸiÅŸkenlerin listesi olmalıdır" + +#: pl_gram.y:1710 +#, c-format +msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" +msgstr "bu ifadeyi barındıran bir blok ya da döngüye ekli bir \"%s\" etiketi bulunmuyor" + +#: pl_gram.y:1718 +#, c-format +msgid "block label \"%s\" cannot be used in CONTINUE" +msgstr "\"%s\" blok etiketi CONTINUE içinde kullanılamaz" + +#: pl_gram.y:1733 +#, c-format +msgid "EXIT cannot be used outside a loop, unless it has a label" +msgstr "EXIT, bir etiketi olmadıkça bir döngü dışında kullanılamaz" + +#: pl_gram.y:1734 +#, c-format +msgid "CONTINUE cannot be used outside a loop" +msgstr "CONTINUE bir döngü dışında kullanılamaz" + +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 +msgid "unexpected end of function definition" +msgstr "fonksiyon tanımında beklenmeyen sonlanma" + +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 +msgid "syntax error" +msgstr "söz dizim hatası " + +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 +msgid "invalid SQLSTATE code" +msgstr "geçersiz SQLSTATE kodu" + +#: pl_gram.y:2094 +msgid "syntax error, expected \"FOR\"" +msgstr "sözdizimi hatası, \"FOR\" bekleniyordu" + +#: pl_gram.y:2155 +#, c-format +msgid "FETCH statement cannot return multiple rows" +msgstr "RAISE ifadesi çoklu satır döndüremez" + +#: pl_gram.y:2279 +#, c-format +msgid "cursor variable must be a simple variable" +msgstr "imleç deÄŸiÅŸkeni basit bir deÄŸiÅŸken olmalıdır" + +#: pl_gram.y:2285 +#, c-format +msgid "variable \"%s\" must be of type cursor or refcursor" +msgstr "\"%s\" deÄŸiÅŸkeni cursor ya da refcursor tiplerinden birisi olmalıdır" + +#: pl_gram.y:2619 pl_gram.y:2630 +#, c-format +msgid "\"%s\" is not a known variable" +msgstr "\"%s\" bilinen bir deÄŸiÅŸken deÄŸil" + +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 +msgid "mismatched parentheses" +msgstr "eÅŸlenmemiÅŸ parantezler" + +#: pl_gram.y:2748 +#, c-format +msgid "missing \"%s\" at end of SQL expression" +msgstr "SQL ifadesinin sonunda eksik \"%s\" " + +#: pl_gram.y:2754 +#, c-format +msgid "missing \"%s\" at end of SQL statement" +msgstr "SQL ifadesinin sonunda \"%s\" eksik" + +#: pl_gram.y:2771 +msgid "missing expression" +msgstr "eksik ifade" + +#: pl_gram.y:2773 +msgid "missing SQL statement" +msgstr "eksik SQL ifadesi" + +#: pl_gram.y:2901 +msgid "incomplete data type declaration" +msgstr "eksik veri tipi deklarasyonu" + +#: pl_gram.y:2924 +msgid "missing data type declaration" +msgstr "eksik veri tipi deklarasyonu" + +#: pl_gram.y:3002 +msgid "INTO specified more than once" +msgstr "INTO birden fazla belirtildi" + +#: pl_gram.y:3171 +msgid "expected FROM or IN" +msgstr "FROM ya da IN bekleniyordu" + +#: pl_gram.y:3232 +#, c-format +msgid "RETURN cannot have a parameter in function returning set" +msgstr "RETURN, fonksiyon return set içinde parametre alamaz" + +#: pl_gram.y:3233 +#, c-format +msgid "Use RETURN NEXT or RETURN QUERY." +msgstr "RETURN NEXT ya da RETURN QUERY kullanın." + +#: pl_gram.y:3243 +#, c-format +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN, bir prosedür içinde parametre alamaz" + +#: pl_gram.y:3248 +#, c-format +msgid "RETURN cannot have a parameter in function returning void" +msgstr "RETURN, void dönen bir fonksiyonda parametre alamaz" + +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN, OUT parametreleri olan fonksiyonda parametre içeremez" + +#: pl_gram.y:3320 +#, c-format +msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" +msgstr "RETURN NEXT OUT parametreleri olan fonksiyonda parametre içeremez" + +#: pl_gram.y:3428 +#, c-format +msgid "variable \"%s\" is declared CONSTANT" +msgstr "\"%s\" CONSTANT olarak deklare edilmiÅŸ" + +#: pl_gram.y:3491 +#, c-format +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "kayıt veya satır deÄŸiÅŸkeni çok-ögeli INTO listesinin bir parçası olamaz" + +#: pl_gram.y:3537 +#, c-format +msgid "too many INTO variables specified" +msgstr "çok fazla INTO deÄŸiÅŸkeni belirtilmiÅŸ" + +#: pl_gram.y:3745 +#, c-format +msgid "end label \"%s\" specified for unlabelled block" +msgstr "etiketlenmemiÅŸ blok için \"%s\" bitiÅŸ etiketi tanımlanmış" + +#: pl_gram.y:3752 +#, c-format +msgid "end label \"%s\" differs from block's label \"%s\"" +msgstr "\"%s\" bitiÅŸ etiketi bloÄŸun etiketi \"%s\"den farklı" + +#: pl_gram.y:3787 +#, c-format +msgid "cursor \"%s\" has no arguments" +msgstr "\"%s\" imlecinin argümanı yok" + +#: pl_gram.y:3801 +#, c-format +msgid "cursor \"%s\" has arguments" +msgstr "\"%s\" imlecinin argümanları var" + +#: pl_gram.y:3843 +#, c-format +msgid "cursor \"%s\" has no argument named \"%s\"" +msgstr "\"%s\" imlecinin \"%s\" adlı bir argümanı yok" + +#: pl_gram.y:3863 +#, c-format +msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" +msgstr "\"%2$s\" imlecinin (cursor) \"%1$s\" parametresinin deÄŸeri birden fazla kez belirtilmiÅŸtir" + +#: pl_gram.y:3888 +#, c-format +msgid "not enough arguments for cursor \"%s\"" +msgstr "\"%s\" imleci (cursor) için yetersiz sayıda argüman " + +#: pl_gram.y:3895 +#, c-format +msgid "too many arguments for cursor \"%s\"" +msgstr "\"%s\" imleci (cursor) için çok fazla argüman" + +#: pl_gram.y:3982 +msgid "unrecognized RAISE statement option" +msgstr "tanımsız RAISE ifadesi seçeneÄŸi" + +#: pl_gram.y:3986 +msgid "syntax error, expected \"=\"" +msgstr "sözdizimi hatası, \"=\" bekleniyordu" + +#: pl_gram.y:4027 +#, c-format +msgid "too many parameters specified for RAISE" +msgstr "RAISE için çok fazla parametre var" + +#: pl_gram.y:4031 +#, c-format +msgid "too few parameters specified for RAISE" +msgstr "RAISE için çok az parametre var" + +#: pl_handler.c:158 +msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." +msgstr "PL/pgSQL deÄŸiÅŸken adları ve tablo sütun adları arasındaki çatışmaların ele alınmasını ayarlar." + +#: pl_handler.c:167 +msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." +msgstr "INTO ... STRICT hatalarında oluÅŸturulan hata mesajlarının DETAIL kısmındaki parametrelerle ilgili bilgileri yazdır." + +#: pl_handler.c:175 +msgid "Perform checks given in ASSERT statements." +msgstr "ASSERT ifadelerinde verilen kontrolleri gerçekleÅŸtir." + +#: pl_handler.c:183 +msgid "List of programming constructs that should produce a warning." +msgstr "Uyarı üretmesi gereken programlama construct'larının yapısı" + +#: pl_handler.c:193 +msgid "List of programming constructs that should produce an error." +msgstr "Hata üretmesi gereken programlama construct'larının yapısı" + +#. translator: %s is typically the translation of "syntax error" +#: pl_scanner.c:508 +#, c-format +msgid "%s at end of input" +msgstr "giriÅŸ sonuna %s" + +#. translator: first %s is typically the translation of "syntax error" +#: pl_scanner.c:524 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "\"%2$s\" yerinde %1$s" + +#~ msgid "relation \"%s\" is not a table" +#~ msgstr "\"%s\" bir tablo deÄŸil" + +#~ msgid "variable \"%s\" declared NOT NULL cannot default to NULL" +#~ msgstr "NOT NULL olarak belirtilen \"%s\" deÄŸiÅŸkeni öntanımlı olarak NULL olamaz" + +#~ msgid "Use a BEGIN block with an EXCEPTION clause instead." +#~ msgstr "Bunun yerine BEGIN bloÄŸunu EXCEPTION yantümcesi ile kullanın." + +#~ msgid "row or record variable cannot be CONSTANT" +#~ msgstr "Satır ya da kayıt deÄŸiÅŸkeni CONSTANT olamaz" + +#~ msgid "row or record variable cannot be NOT NULL" +#~ msgstr "satır ya da kayıt deÄŸiÅŸkeni NOT NULL olamaz" + +#~ msgid "default value for row or record variable is not supported" +#~ msgstr "satır ya da kayıt deÄŸiÅŸkenlerine öntanımlı deÄŸer atanması desteklenmiyor" + +#~ msgid "unterminated dollar-quoted string" +#~ msgstr "sonuçlandırılmamış dolar iÅŸeretiyle sınırlandırılmış satır" + +#~ msgid "unterminated quoted string" +#~ msgstr "sonuçlandırılmamış tırnakla sınırlandırılmış satır" + +#~ msgid "unterminated /* comment" +#~ msgstr "/* açıklama sonlandırılmamış" + +#~ msgid "unterminated quoted identifier" +#~ msgstr "sonuçlandırılmamış tırnakla sınırlandırılmış tanım" + +#~ msgid "unterminated \" in identifier: %s" +#~ msgstr "belirteçte sonlandırılmamış *\" : %s" + +#~ msgid "variable \"%s\" does not exist in the current block" +#~ msgstr "\"%s\" deÄŸiÅŸkeni mevcut bloÄŸun içinde yok" + +#~ msgid "expected \")\"" +#~ msgstr "\")\" bekleniyordu" + +#~ msgid "cannot assign to tg_argv" +#~ msgstr "tg_argv'ye atama yapılamadı" + +#~ msgid "too many variables specified in SQL statement" +#~ msgstr "SQL ifadesinde çok fazla deÄŸiÅŸken belirtilmiÅŸ" + +#~ msgid "expected a cursor or refcursor variable" +#~ msgstr "cursor ya da refcursonr deÄŸiÅŸkeni beklendi" + +#~ msgid "syntax error at \"%s\"" +#~ msgstr "\"%s\" içinde sözdizimi hatası" + +#~ msgid "expected an integer variable" +#~ msgstr "tamsayı deÄŸiÅŸken bekleniyordu" + +#~ msgid "function has no parameter \"%s\"" +#~ msgstr "fonksiyonun \"%s\" parametresi var" + +#~ msgid "Number of returned columns (%d) does not match expected column count (%d)." +#~ msgstr "Dönen kolonların sayısı (%d) beklenen kolon sayısı (%d) ile eÅŸleÅŸmiyor." + +#~ msgid "N/A (dropped column)" +#~ msgstr "N/A (silinmiÅŸ kolon)" + +#~ msgid "row \"%s.%s\" has no field \"%s\"" +#~ msgstr "\"%s.%s\" satırında \"%s\" alanı yok." + +#~ msgid "row \"%s\" has no field \"%s\"" +#~ msgstr "\"%s\" satırının bir alanı yok \"%s\"" + +#~ msgid "expected \"[\"" +#~ msgstr " \"[\" bekleniyordu" + +#~ msgid "relation \"%s.%s\" does not exist" +#~ msgstr "\"%s.%s\" nesnesi mevcut deÄŸil" + +#~ msgid "EXECUTE statement" +#~ msgstr "EXECUTE ifadesi" + +#~ msgid "RETURN NEXT must specify a record or row variable in function returning row" +#~ msgstr "RETURN NEXT satır döndüren fonksiyonda kayıt ya da satır deÄŸiÅŸkeni belirtmelidir" + +#~ msgid "label does not exist" +#~ msgstr "etiket bulunamadı" diff --git a/src/pl/plpgsql/src/po/vi.po b/src/pl/plpgsql/src/po/vi.po new file mode 100644 index 00000000000..6620dea6440 --- /dev/null +++ b/src/pl/plpgsql/src/po/vi.po @@ -0,0 +1,850 @@ +# LANGUAGE message translation file for plpgsql +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the plpgsql (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: plpgsql (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:08+0000\n" +"PO-Revision-Date: 2018-05-13 15:28+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: \n" +"Language: vi_VN\n" + +#: pl_comp.c:434 pl_handler.c:457 +#, c-format +msgid "PL/pgSQL functions cannot accept type %s" +msgstr "Các hàm PL/pgSQL không thể chấp nhận kiểu %s" + +#: pl_comp.c:522 +#, c-format +msgid "could not determine actual return type for polymorphic function \"%s\"" +msgstr "không thể xác định kiểu thá»±c tế trả vá» cho hàm Ä‘a hình \"%s\"" + +#: pl_comp.c:552 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "hàm trigger chỉ có thể được gá»i như má»™t trigger" + +#: pl_comp.c:556 pl_handler.c:441 +#, c-format +msgid "PL/pgSQL functions cannot return type %s" +msgstr "Các hàm PL/pgSQL không thể trả vá» kiểu %s" + +#: pl_comp.c:595 +#, c-format +msgid "trigger functions cannot have declared arguments" +msgstr "không thể khai báo đối số cho hàm trigger" + +#: pl_comp.c:596 +#, c-format +msgid "" +"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " +"instead." +msgstr "" +"Thay vào đó các đối số cá»§a trigger có thể được truy cập thông qua TG_NARGS " +"và TG_ARGV." + +#: pl_comp.c:719 +#, c-format +msgid "event trigger functions cannot have declared arguments" +msgstr "không thể khai báo đối số cho hàm sá»± kiện trigger" + +#: pl_comp.c:976 +#, c-format +msgid "compilation of PL/pgSQL function \"%s\" near line %d" +msgstr "biên dịch hàm PL/pgSQL \"%s\" gần dòng %d" + +#: pl_comp.c:999 +#, c-format +msgid "parameter name \"%s\" used more than once" +msgstr "tên thông số \"%s\" được sá»­ dụng nhiá»u lần" + +#: pl_comp.c:1109 +#, c-format +msgid "column reference \"%s\" is ambiguous" +msgstr "tham chiếu cá»™t \"%s\" không rõ ràng" + +#: pl_comp.c:1111 +#, c-format +msgid "It could refer to either a PL/pgSQL variable or a table column." +msgstr "Nó có thể tham chiếu đến má»™t biến PL/pgSQL hoặc má»™t cá»™t bảng." + +#: pl_comp.c:1294 pl_exec.c:5031 pl_exec.c:5396 pl_exec.c:5483 pl_exec.c:5574 +#: pl_exec.c:6491 +#, c-format +msgid "record \"%s\" has no field \"%s\"" +msgstr "bản ghi \"%s\" không có trưá»ng \"%s\"" + +#: pl_comp.c:1756 +#, c-format +msgid "relation \"%s\" does not exist" +msgstr "relation \"%s\" không tồn tại" + +#: pl_comp.c:1848 +#, c-format +msgid "variable \"%s\" has pseudo-type %s" +msgstr "biến \"%s\" có pseudo-type %s" + +#: pl_comp.c:2026 +#, c-format +msgid "type \"%s\" is only a shell" +msgstr "kiểu \"%s\" chỉ là má»™t shell(chưa được định nghÄ©a ná»™i dung)" + +#: pl_comp.c:2123 pl_comp.c:2176 +#, c-format +msgid "unrecognized exception condition \"%s\"" +msgstr "không thể nhận ra Ä‘iá»u kiện cá»§a ngoại lệ \"%s\"" + +#: pl_comp.c:2390 +#, c-format +msgid "" +"could not determine actual argument type for polymorphic function \"%s\"" +msgstr "không thể xác định loại đối số thá»±c tế cho hàm Ä‘a hình \"%s\"" + +#: pl_exec.c:473 pl_exec.c:885 pl_exec.c:1098 +msgid "during initialization of execution state" +msgstr "trong khi khởi tạo trạng thái thá»±c thi" + +#: pl_exec.c:479 +msgid "while storing call arguments into local variables" +msgstr "trong khi lưu trữ các đối số gá»i vào trong các biến cục bá»™" + +#: pl_exec.c:567 pl_exec.c:933 +msgid "during function entry" +msgstr "trong lúc Ä‘i vào hàm" + +#: pl_exec.c:592 +#, c-format +msgid "control reached end of function without RETURN" +msgstr "Hàm đã kết thúc trước khi trả vá» RETURN" + +#: pl_exec.c:599 +msgid "while casting return value to function's return type" +msgstr "trong khi ép kiểu giá trị trả vá» cho kiểu trả vá» cá»§a hàm" + +#: pl_exec.c:612 pl_exec.c:3484 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "" +"hàm thiết lập giá trị được gá»i trong ngữ cảnh không thể chấp nhận má»™t tập hợp" + +#: pl_exec.c:738 pl_exec.c:962 pl_exec.c:1123 +msgid "during function exit" +msgstr "trong lúc kết thúc hàm" + +#: pl_exec.c:793 pl_exec.c:832 pl_exec.c:3329 +msgid "returned record type does not match expected record type" +msgstr "loại bản ghi đã trả vá» không khá»›p vá»›i kiểu được ghi kỳ vá»ng" + +#: pl_exec.c:958 pl_exec.c:1119 +#, c-format +msgid "control reached end of trigger procedure without RETURN" +msgstr "thá»§ tục trigger kết thúc trước khi tra vá» RETURN" + +#: pl_exec.c:967 +#, c-format +msgid "trigger procedure cannot return a set" +msgstr "thá»§ tục trigger không thể trả vá» má»™t tập hợp" + +#: pl_exec.c:1006 pl_exec.c:1034 +msgid "" +"returned row structure does not match the structure of the triggering table" +msgstr "cấu trúc hàng trả vá» không khá»›p vá»›i cấu trúc cá»§a trigger bảng" + +#. translator: last %s is a phrase such as "during statement block +#. local variable initialization" +#. +#: pl_exec.c:1171 +#, c-format +msgid "PL/pgSQL function %s line %d %s" +msgstr "Hàm PL/pgSQL %s dòng %d %s" + +#. translator: last %s is a phrase such as "while storing call +#. arguments into local variables" +#. +#: pl_exec.c:1182 +#, c-format +msgid "PL/pgSQL function %s %s" +msgstr "Hàm PL/pgSQL %s %s" + +#. translator: last %s is a plpgsql statement type name +#: pl_exec.c:1190 +#, c-format +msgid "PL/pgSQL function %s line %d at %s" +msgstr "Hàm PL/pgSQL %s dòng %d tại %s" + +#: pl_exec.c:1196 +#, c-format +msgid "PL/pgSQL function %s" +msgstr "Hàm PL/pgSQL %s" + +#: pl_exec.c:1534 +msgid "during statement block local variable initialization" +msgstr "trong khi khởi tạo biến cục bá»™ trong khối lệnh" + +#: pl_exec.c:1632 +msgid "during statement block entry" +msgstr "trong khi vào khối lệnh" + +#: pl_exec.c:1664 +msgid "during statement block exit" +msgstr "trong khi kết thúc khối lệnh" + +#: pl_exec.c:1702 +msgid "during exception cleanup" +msgstr "trong khi dá»n dẹp ngoại lệ" + +#: pl_exec.c:2207 pl_exec.c:2221 +#, c-format +msgid "argument %d is an output argument but is not writable" +msgstr "đối số %d là đối số đầu ra nhưng không thể ghi" + +#: pl_exec.c:2263 +#, c-format +msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" +msgstr "" +"GET STACKED DIAGNOSTICS không thể được sá»­ dụng bên ngoài bên ngoài má»™t trình " +"xá»­ lý ngoại lệ" + +#: pl_exec.c:2468 +#, c-format +msgid "case not found" +msgstr "không tìm thấy trưá»ng hợp này" + +#: pl_exec.c:2469 +#, c-format +msgid "CASE statement is missing ELSE part." +msgstr "Câu lệnh CASE thiếu phần ELSE." + +#: pl_exec.c:2562 +#, c-format +msgid "lower bound of FOR loop cannot be null" +msgstr "giá»›i hạn dưới cá»§a vòng lặp FOR không thể là null" + +#: pl_exec.c:2578 +#, c-format +msgid "upper bound of FOR loop cannot be null" +msgstr "giá»›i hạn trên cá»§a vòng lặp FOR không thể là null" + +#: pl_exec.c:2596 +#, c-format +msgid "BY value of FOR loop cannot be null" +msgstr "Giá trị BY cá»§a vòng lặp FOR không thể là null" + +#: pl_exec.c:2602 +#, c-format +msgid "BY value of FOR loop must be greater than zero" +msgstr "Giá trị BY cá»§a vòng lặp FOR phải lá»›n hÆ¡n 0" + +#: pl_exec.c:2736 pl_exec.c:4461 +#, c-format +msgid "cursor \"%s\" already in use" +msgstr "con trá» \"%s\" đã Ä‘ang được sá»­ dụng" + +#: pl_exec.c:2759 pl_exec.c:4526 +#, c-format +msgid "arguments given for cursor without arguments" +msgstr "đối số được đưa ra cho con trá» không có đối số" + +#: pl_exec.c:2778 pl_exec.c:4545 +#, c-format +msgid "arguments required for cursor" +msgstr "đối số cần thiết cho con trá»" + +#: pl_exec.c:2865 +#, c-format +msgid "FOREACH expression must not be null" +msgstr "Biểu thức FOREACH không được là null" + +#: pl_exec.c:2880 +#, c-format +msgid "FOREACH expression must yield an array, not type %s" +msgstr "Biểu thức FOREACH phải tạo ra má»™t mảng, không phải kiểu %s" + +#: pl_exec.c:2897 +#, c-format +msgid "slice dimension (%d) is out of the valid range 0..%d" +msgstr "kích thước slice (%d) nằm ngoài phạm vi hợp lệ 0..%d" + +#: pl_exec.c:2924 +#, c-format +msgid "FOREACH ... SLICE loop variable must be of an array type" +msgstr "Biến cho vòng lặp FOREACH ... SLICE phải là má»™t kiểu mảng" + +#: pl_exec.c:2928 +#, c-format +msgid "FOREACH loop variable must not be of an array type" +msgstr "Biến vòng lặp FOREACH không được thuá»™c loại mảng" + +#: pl_exec.c:3090 pl_exec.c:3147 pl_exec.c:3322 +#, c-format +msgid "" +"cannot return non-composite value from function returning composite type" +msgstr "không thể trả vá» giá trị không-phức hợp từ hàm trả vá» kiểu phức hợp" + +#: pl_exec.c:3186 pl_gram.y:3266 +#, c-format +msgid "cannot use RETURN NEXT in a non-SETOF function" +msgstr "không thể sá»­ dụng RETURN NEXT trong má»™t hàm không phải-SETOF" + +#: pl_exec.c:3227 pl_exec.c:3359 +#, c-format +msgid "wrong result type supplied in RETURN NEXT" +msgstr "kiểu kết quả trả vá» không đúng trong RETURN NEXT" + +#: pl_exec.c:3265 pl_exec.c:3286 +#, c-format +msgid "wrong record type supplied in RETURN NEXT" +msgstr "kiểu bản ghi trả vá» không đúng trong RETURN NEXT" + +#: pl_exec.c:3378 +#, c-format +msgid "RETURN NEXT must have a parameter" +msgstr "RETURN NEXT phải có má»™t tham số" + +#: pl_exec.c:3404 pl_gram.y:3329 +#, c-format +msgid "cannot use RETURN QUERY in a non-SETOF function" +msgstr "không thể sá»­ dụng RETURN QUERY trong má»™t hàm không phải-SETOF" + +#: pl_exec.c:3428 +msgid "structure of query does not match function result type" +msgstr "cấu trúc cá»§a truy vấn không khá»›p vá»›i kiểu kết quả hàm" + +#: pl_exec.c:3512 pl_exec.c:3650 +#, c-format +msgid "RAISE option already specified: %s" +msgstr "Tùy chá»n RAISE đã được chỉ định: %s" + +#: pl_exec.c:3546 +#, c-format +msgid "RAISE without parameters cannot be used outside an exception handler" +msgstr "" +"RAISE không có tham số không thể được sá»­ dụng bên ngoài má»™t trình xá»­ lý " +"ngoại lệ" + +#: pl_exec.c:3640 +#, c-format +msgid "RAISE statement option cannot be null" +msgstr "Tùy chá»n lệnh RAISE không thể là null" + +#: pl_exec.c:3710 +#, c-format +msgid "%s" +msgstr "%s" + +#: pl_exec.c:3765 +#, c-format +msgid "assertion failed" +msgstr "lá»—i assertion" + +#: pl_exec.c:3970 pl_exec.c:4117 pl_exec.c:4301 +#, c-format +msgid "cannot COPY to/from client in PL/pgSQL" +msgstr "không thể COPY tá»›i/từ client trong PL/pgSQL" + +#: pl_exec.c:3974 pl_exec.c:4121 pl_exec.c:4305 +#, c-format +msgid "cannot begin/end transactions in PL/pgSQL" +msgstr "không thể begin/end transactions trong PL/pgSQL" + +#: pl_exec.c:3975 pl_exec.c:4122 pl_exec.c:4306 +#, c-format +msgid "Use a BEGIN block with an EXCEPTION clause instead." +msgstr "Sá»­ dụng má»™t khối BEGIN vá»›i má»™t cấu trúc EXCEPTION để thay thế." + +#: pl_exec.c:4144 pl_exec.c:4329 +#, c-format +msgid "INTO used with a command that cannot return data" +msgstr "INTO được sá»­ dụng vá»›i lệnh không thể trả vá» dữ liệu" + +#: pl_exec.c:4167 pl_exec.c:4352 +#, c-format +msgid "query returned no rows" +msgstr "truy vấn không trả lại dòng nào" + +#: pl_exec.c:4186 pl_exec.c:4371 +#, c-format +msgid "query returned more than one row" +msgstr "truy vấn trả vá» nhiá»u dòng" + +#: pl_exec.c:4203 +#, c-format +msgid "query has no destination for result data" +msgstr "truy vấn không có đích cho dữ liệu kết quả" + +#: pl_exec.c:4204 +#, c-format +msgid "If you want to discard the results of a SELECT, use PERFORM instead." +msgstr "Nếu bạn không muốn sá»­ dụng kết quả cá»§a SELECT, hãy sá»­ dụng PERFORM." + +#: pl_exec.c:4237 pl_exec.c:8212 +#, c-format +msgid "query string argument of EXECUTE is null" +msgstr "đối số chuá»—i truy vấn cá»§a EXECUTE là null" + +#: pl_exec.c:4293 +#, c-format +msgid "EXECUTE of SELECT ... INTO is not implemented" +msgstr "EXECUTE cá»§a SELECT ... INTO chưa được thá»±c thi" + +#: pl_exec.c:4294 +#, c-format +msgid "" +"You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " +"instead." +msgstr "" +"Thay vào đó có thể bạn muốn sá»­ dụng EXECUTE ... INTO hoặc EXECUTE CREATE " +"TABLE ... AS." + +#: pl_exec.c:4607 pl_exec.c:4695 +#, c-format +msgid "cursor variable \"%s\" is null" +msgstr "biến con trá» \"%s\" là null" + +#: pl_exec.c:4618 pl_exec.c:4706 +#, c-format +msgid "cursor \"%s\" does not exist" +msgstr "con trá» \"%s\" không tồn tại" + +#: pl_exec.c:4631 +#, c-format +msgid "relative or absolute cursor position is null" +msgstr "vị trí con trá» tương đối hoặc tuyệt đối là null" + +#: pl_exec.c:4881 pl_exec.c:4976 +#, c-format +msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" +msgstr "giá trị null không thể được gán cho biến \"%s\" được khai báo NOT NULL" + +#: pl_exec.c:4957 +#, c-format +msgid "cannot assign non-composite value to a row variable" +msgstr "không thể gán giá trị không-phức hợp cho biến dòng" + +#: pl_exec.c:4989 +#, c-format +msgid "cannot assign non-composite value to a record variable" +msgstr "không thể gán giá trị không phải-phức hợp cho biến bản ghi" + +#: pl_exec.c:5040 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "không thể gán cho cá»™t hệ thống \"%s\"" + +#: pl_exec.c:5104 +#, c-format +msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" +msgstr "số lượng chiá»u cá»§a mảng (%d) vượt quá số lượng tối Ä‘a cho phép (%d)" + +#: pl_exec.c:5136 +#, c-format +msgid "subscripted object is not an array" +msgstr "đối tượng chỉ số không phải là má»™t mảng" + +#: pl_exec.c:5174 +#, c-format +msgid "array subscript in assignment must not be null" +msgstr "chỉ số mảng sá»­ dụng trong gán không thể là null" + +#: pl_exec.c:5681 +#, c-format +msgid "query \"%s\" did not return data" +msgstr "truy vấn \"%s\" không trả vá» dữ liệu" + +#: pl_exec.c:5689 +#, c-format +msgid "query \"%s\" returned %d column" +msgid_plural "query \"%s\" returned %d columns" +msgstr[0] "truy vấn \"%s\" trả lại %d cá»™t" + +#: pl_exec.c:5717 +#, c-format +msgid "query \"%s\" returned more than one row" +msgstr "truy vấn \"%s\" đã trả lại nhiá»u hàng" + +#: pl_exec.c:5780 +#, c-format +msgid "query \"%s\" is not a SELECT" +msgstr "truy vấn \"%s\" không phải là má»™t SELECT" + +#: pl_exec.c:6505 pl_exec.c:6545 pl_exec.c:6585 +#, c-format +msgid "" +"type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "kiểu tham số %d (%s) không khá»›p vá»›i thông số khi chuẩn bị plan (%s)" + +#: pl_exec.c:7356 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "bản ghi \"%s\" chưa được gán" + +#: pl_exec.c:7357 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "Cấu trúc tuple cá»§a má»™t bản ghi chưa được gán là không xác định." + +#: pl_funcs.c:239 +msgid "statement block" +msgstr "khối câu lệnh" + +#: pl_funcs.c:241 +msgid "assignment" +msgstr "gán" + +#: pl_funcs.c:251 +msgid "FOR with integer loop variable" +msgstr "FOR vá»›i biến số nguyên vòng lặp" + +#: pl_funcs.c:253 +msgid "FOR over SELECT rows" +msgstr "FOR trên các dòng SELECT" + +#: pl_funcs.c:255 +msgid "FOR over cursor" +msgstr "FOR trên con trá»" + +#: pl_funcs.c:257 +msgid "FOREACH over array" +msgstr "FOREACH trên mảng" + +#: pl_funcs.c:271 +msgid "SQL statement" +msgstr "Câu lệnh SQL" + +#: pl_funcs.c:275 +msgid "FOR over EXECUTE statement" +msgstr "FOR trên câu lệnh EXECUTE" + +#: pl_gram.y:485 +#, c-format +msgid "block label must be placed before DECLARE, not after" +msgstr "nhãn khối phải được đặt trước DECLARE, không phải sau" + +#: pl_gram.y:505 +#, c-format +msgid "collations are not supported by type %s" +msgstr "collation không được há»— trợ bởi kiểu %s" + +#: pl_gram.y:524 +#, c-format +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "biến \"%s\" phải có giá trị mặc định, vì nó được khai báo là NOT NULL" + +#: pl_gram.y:669 pl_gram.y:684 pl_gram.y:710 +#, c-format +msgid "variable \"%s\" does not exist" +msgstr "biến \"%s\" không tồn tại" + +#: pl_gram.y:728 pl_gram.y:756 +msgid "duplicate declaration" +msgstr "khai báo trùng lặp" + +#: pl_gram.y:739 pl_gram.y:767 +#, c-format +msgid "variable \"%s\" shadows a previously defined variable" +msgstr "biến \"%s\" làm cho má»™t biến được định nghÄ©a trước đó không khả thị" + +#: pl_gram.y:983 +#, c-format +msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" +msgstr "diagnostics mục %s không được phép trong GET STACKED DIAGNOSTICS" + +#: pl_gram.y:1001 +#, c-format +msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" +msgstr "diagnostics mục %s không được cho phép trong GET CURRENT DIAGNOSTICS" + +#: pl_gram.y:1099 +msgid "unrecognized GET DIAGNOSTICS item" +msgstr "không nhận ra mục GET DIAGNOSTICS" + +#: pl_gram.y:1109 pl_gram.y:3508 +#, c-format +msgid "\"%s\" is not a scalar variable" +msgstr "\"%s\" không phải là biến vô hướng" + +#: pl_gram.y:1357 pl_gram.y:1550 +#, c-format +msgid "" +"loop variable of loop over rows must be a record variable or list of scalar " +"variables" +msgstr "" +"vòng lặp cá»§a vòng lặp trên các dòng phải là má»™t biến bản ghi hoặc danh sách " +"các biến vô hướng" + +#: pl_gram.y:1391 +#, c-format +msgid "cursor FOR loop must have only one target variable" +msgstr "vòng lặp FOR sá»­ dụng con trá» chỉ có má»™t biến đích" + +#: pl_gram.y:1398 +#, c-format +msgid "cursor FOR loop must use a bound cursor variable" +msgstr "vòng lặp FOR sá»­ dụng con trá» phải sá»­ dụng má»™t biến con trá»" + +#: pl_gram.y:1485 +#, c-format +msgid "integer FOR loop must have only one target variable" +msgstr "vòng lặp FOR sá»­ dụng số nguyên chỉ được phép có má»™t biến đích" + +#: pl_gram.y:1521 +#, c-format +msgid "cannot specify REVERSE in query FOR loop" +msgstr "không thể chỉ định REVERSE trong vòng lặp truy vấn FOR" + +#: pl_gram.y:1652 +#, c-format +msgid "loop variable of FOREACH must be a known variable or list of variables" +msgstr "biến vòng lặp cá»§a FOREACH phải là biến được biết hoặc danh sách biến" + +#: pl_gram.y:1693 +#, c-format +msgid "" +"there is no label \"%s\" attached to any block or loop enclosing this " +"statement" +msgstr "" +"không có nhãn \"%s\" được đính kèm vá»›i bất kỳ khối hoặc vòng lặp nào kèm " +"theo câu lệnh này" + +#: pl_gram.y:1701 +#, c-format +msgid "block label \"%s\" cannot be used in CONTINUE" +msgstr "không thể sá»­ dụng nhãn khối \"%s\" trong CONTINUE" + +#: pl_gram.y:1716 +#, c-format +msgid "EXIT cannot be used outside a loop, unless it has a label" +msgstr "" +"EXIT không thể được sá»­ dụng bên ngoài má»™t vòng lặp, trừ khi nó có má»™t nhãn" + +#: pl_gram.y:1717 +#, c-format +msgid "CONTINUE cannot be used outside a loop" +msgstr "Không thể sá»­ dụng CONTINUE bên ngoài vòng lặp" + +#: pl_gram.y:1741 pl_gram.y:1778 pl_gram.y:1826 pl_gram.y:2958 pl_gram.y:3041 +#: pl_gram.y:3152 pl_gram.y:3907 +msgid "unexpected end of function definition" +msgstr "định nghÄ©a kết thúc hàm không mong đợi" + +#: pl_gram.y:1846 pl_gram.y:1870 pl_gram.y:1886 pl_gram.y:1892 pl_gram.y:2009 +#: pl_gram.y:2017 pl_gram.y:2031 pl_gram.y:2125 pl_gram.y:2360 pl_gram.y:2454 +#: pl_gram.y:2612 pl_gram.y:3749 pl_gram.y:3810 pl_gram.y:3888 +msgid "syntax error" +msgstr "lá»—i cú pháp" + +#: pl_gram.y:1874 pl_gram.y:1876 pl_gram.y:2364 pl_gram.y:2366 +msgid "invalid SQLSTATE code" +msgstr "mã SQLSTATE không hợp lệ" + +#: pl_gram.y:2073 +msgid "syntax error, expected \"FOR\"" +msgstr "lá»—i cú pháp, kỳ vá»ng \"FOR\"" + +#: pl_gram.y:2134 +#, c-format +msgid "FETCH statement cannot return multiple rows" +msgstr "Câu lệnh FETCH không thể trả vá» nhiá»u hàng" + +#: pl_gram.y:2244 +#, c-format +msgid "cursor variable must be a simple variable" +msgstr "biến con trá» phải là má»™t biến đơn giản" + +#: pl_gram.y:2250 +#, c-format +msgid "variable \"%s\" must be of type cursor or refcursor" +msgstr "biến \"%s\" phải là kiểu con trá» hoặc refcursor" + +#: pl_gram.y:2583 pl_gram.y:2594 +#, c-format +msgid "\"%s\" is not a known variable" +msgstr "\"%s\" không phải là má»™t biến" + +#: pl_gram.y:2698 pl_gram.y:2708 pl_gram.y:2863 +msgid "mismatched parentheses" +msgstr "dấu ngoặc đơn không khá»›p" + +#: pl_gram.y:2712 +#, c-format +msgid "missing \"%s\" at end of SQL expression" +msgstr "thiếu \"%s\" ở cuối biểu thức SQL" + +#: pl_gram.y:2718 +#, c-format +msgid "missing \"%s\" at end of SQL statement" +msgstr "thiếu \"%s\" ở cuối câu lệnh SQL" + +#: pl_gram.y:2735 +msgid "missing expression" +msgstr "thiếu biểu thức" + +#: pl_gram.y:2737 +msgid "missing SQL statement" +msgstr "thiếu câu lệnh SQL" + +#: pl_gram.y:2865 +msgid "incomplete data type declaration" +msgstr "khai báo kiểu dữ liệu không đầy đủ" + +#: pl_gram.y:2888 +msgid "missing data type declaration" +msgstr "thiếu khai báo kiểu dữ liệu" + +#: pl_gram.y:2966 +msgid "INTO specified more than once" +msgstr "INTO được chỉ định nhiá»u lần" + +#: pl_gram.y:3133 +msgid "expected FROM or IN" +msgstr "kỳ vá»ng FROM hoặc IN" + +#: pl_gram.y:3193 +#, c-format +msgid "RETURN cannot have a parameter in function returning set" +msgstr "RETURN không thể có tham số trong tập hợp giá trị trả vá» cá»§a hàm" + +#: pl_gram.y:3194 +#, c-format +msgid "Use RETURN NEXT or RETURN QUERY." +msgstr "sá»­ dụng RETURN NEXT hay RETURN QUERY." + +#: pl_gram.y:3204 +#, c-format +msgid "RETURN cannot have a parameter in a procedure" +msgstr "RETURN không thể có tham số trong má»™t thá»§ tục" + +#: pl_gram.y:3209 +#, c-format +msgid "RETURN cannot have a parameter in function returning void" +msgstr "RETURN không thể có tham số trong hàm trả vá» void" + +#: pl_gram.y:3218 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "RETURN không thể có tham số trong hàm vá»›i tham số OUT" + +#: pl_gram.y:3280 +#, c-format +msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" +msgstr "RETURN NEXT không thể có tham số trong hàm vá»›i tham số OUT" + +#: pl_gram.y:3387 +#, c-format +msgid "variable \"%s\" is declared CONSTANT" +msgstr "biến \"%s\" được khai báo CONSTANT" + +#: pl_gram.y:3450 +#, c-format +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "biến bản ghi không thể là má»™t phần cá»§a danh sách INTO nhiá»u mục" + +#: pl_gram.y:3496 +#, c-format +msgid "too many INTO variables specified" +msgstr "quá nhiá»u biến INTO được chỉ định" + +#: pl_gram.y:3702 +#, c-format +msgid "end label \"%s\" specified for unlabelled block" +msgstr "nhãn kết thúc \"%s\" được chỉ định cho khối không được gắn nhãn" + +#: pl_gram.y:3709 +#, c-format +msgid "end label \"%s\" differs from block's label \"%s\"" +msgstr "nhãn kết thúc \"%s\" khác vá»›i nhãn cá»§a block \"%s\"" + +#: pl_gram.y:3744 +#, c-format +msgid "cursor \"%s\" has no arguments" +msgstr "con trá» \"%s\" không có đối số" + +#: pl_gram.y:3758 +#, c-format +msgid "cursor \"%s\" has arguments" +msgstr "con trá» \"%s\" có đối số" + +#: pl_gram.y:3800 +#, c-format +msgid "cursor \"%s\" has no argument named \"%s\"" +msgstr "con trá» \"%s\" không có đối số tên là \"%s\"" + +#: pl_gram.y:3820 +#, c-format +msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" +msgstr "giá trị cho tham số \"%s\" cá»§a con trá» \"%s\" được chỉ định nhiá»u lần" + +#: pl_gram.y:3845 +#, c-format +msgid "not enough arguments for cursor \"%s\"" +msgstr "không đủ đối số cho con trá» \"%s\"" + +#: pl_gram.y:3852 +#, c-format +msgid "too many arguments for cursor \"%s\"" +msgstr "quá nhiá»u đối số cho con trá» \"%s\"" + +#: pl_gram.y:3939 +msgid "unrecognized RAISE statement option" +msgstr "không thể xác định tùy chá»n cho lệnh RAISE" + +#: pl_gram.y:3943 +msgid "syntax error, expected \"=\"" +msgstr "lá»—i cú pháp, kỳ vá»ng \"=\"" + +#: pl_gram.y:3984 +#, c-format +msgid "too many parameters specified for RAISE" +msgstr "quá nhiá»u thông số được chỉ định cho RAISE" + +#: pl_gram.y:3988 +#, c-format +msgid "too few parameters specified for RAISE" +msgstr "quá ít thông số được chỉ định cho RAISE" + +#: pl_handler.c:154 +msgid "" +"Sets handling of conflicts between PL/pgSQL variable names and table column " +"names." +msgstr "Äặt xá»­ lý xung đột giữa tên biến PL/pgSQL và tên cá»™t bảng." + +#: pl_handler.c:163 +msgid "" +"Print information about parameters in the DETAIL part of the error messages " +"generated on INTO ... STRICT failures." +msgstr "" +"Hiển thị thông tin vá» các tham số trong phần DETAIL cá»§a các thông báo lá»—i " +"được tạo ra khi INTO ... STRICT lá»—i." + +#: pl_handler.c:171 +msgid "Perform checks given in ASSERT statements." +msgstr "Thá»±c hiện các kiểm tra được đưa ra trong các câu lệnh ASSERT." + +#: pl_handler.c:179 +msgid "List of programming constructs that should produce a warning." +msgstr "Danh sách các cấu trúc lập trình sẽ tạo ra má»™t cảnh báo." + +#: pl_handler.c:189 +msgid "List of programming constructs that should produce an error." +msgstr "Danh sách các cấu trúc lập trình sẽ tạo ra lá»—i." + +#. translator: %s is typically the translation of "syntax error" +#: pl_scanner.c:630 +#, c-format +msgid "%s at end of input" +msgstr "%s tại nÆ¡i kết thúc đầu vào" + +#. translator: first %s is typically the translation of "syntax error" +#: pl_scanner.c:646 +#, c-format +msgid "%s at or near \"%s\"" +msgstr "%s tại hoặc gần\"%s\"" diff --git a/src/pl/plpgsql/src/po/zh_CN.po b/src/pl/plpgsql/src/po/zh_CN.po index 9858e4e6674..bbbf72c4c98 100644 --- a/src/pl/plpgsql/src/po/zh_CN.po +++ b/src/pl/plpgsql/src/po/zh_CN.po @@ -5,12 +5,12 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:37+0000\n" -"PO-Revision-Date: 2016-05-19 20:45+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Weibin \n" +"Project-Id-Version: plpgsql (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:08+0000\n" +"PO-Revision-Date: 2019-05-16 18:20+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,153 +18,144 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.5.7\n" -#: pl_comp.c:432 pl_handler.c:448 +#: pl_comp.c:436 pl_handler.c:461 #, c-format msgid "PL/pgSQL functions cannot accept type %s" msgstr "PL/pgSQL函数ä¸ä½¿ç”¨ç±»åž‹%s" -#: pl_comp.c:513 +#: pl_comp.c:524 #, c-format msgid "could not determine actual return type for polymorphic function \"%s\"" msgstr "无法确定多æ€å‡½æ•°\"%s\"的实际返回类型" -#: pl_comp.c:543 +#: pl_comp.c:554 #, c-format msgid "trigger functions can only be called as triggers" msgstr "触å‘器函数åªèƒ½ä»¥è§¦å‘器的形å¼è°ƒç”¨" -#: pl_comp.c:547 pl_handler.c:433 +#: pl_comp.c:558 pl_handler.c:445 #, c-format msgid "PL/pgSQL functions cannot return type %s" msgstr "PL/pgSQL函数ä¸èƒ½è¿”回类型%s" -#: pl_comp.c:588 +#: pl_comp.c:597 #, c-format msgid "trigger functions cannot have declared arguments" msgstr "触å‘器函数ä¸èƒ½æœ‰å·²å£°æ˜Žçš„傿•°" -#: pl_comp.c:589 +#: pl_comp.c:598 #, c-format -msgid "" -"The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV " -"instead." +msgid "The arguments of the trigger can be accessed through TG_NARGS and TG_ARGV instead." msgstr "触å‘å™¨çš„å‚æ•°å¯ä»¥é€šè¿‡TG_NARGSå’ŒTG_ARGV进行访问." -#: pl_comp.c:691 +#: pl_comp.c:721 #, c-format msgid "event trigger functions cannot have declared arguments" msgstr "事件触å‘器函数ä¸èƒ½æœ‰å·²å£°æ˜Žçš„傿•°" -#: pl_comp.c:944 +#: pl_comp.c:980 #, c-format msgid "compilation of PL/pgSQL function \"%s\" near line %d" msgstr "在第%2$d行附件编译PL/pgSQL函数\"%1$s\"" -#: pl_comp.c:967 +#: pl_comp.c:1003 #, c-format msgid "parameter name \"%s\" used more than once" msgstr "å¤šæ¬¡ä½¿ç”¨å‚æ•°åç§° \"%s\"" -#: pl_comp.c:1077 +#: pl_comp.c:1115 #, c-format msgid "column reference \"%s\" is ambiguous" msgstr "å­—æ®µå…³è” \"%s\" æ˜¯ä¸æ˜Žç¡®çš„" -#: pl_comp.c:1079 +#: pl_comp.c:1117 #, c-format msgid "It could refer to either a PL/pgSQL variable or a table column." msgstr "å¯ä»¥æŒ‡å‘一个PL/pgSQLå˜é‡æˆ–表中的列" -#: pl_comp.c:1259 pl_comp.c:1287 pl_exec.c:4395 pl_exec.c:4744 pl_exec.c:4829 -#: pl_exec.c:4920 +#: pl_comp.c:1300 pl_exec.c:5106 pl_exec.c:5471 pl_exec.c:5558 pl_exec.c:5649 +#: pl_exec.c:6566 #, c-format msgid "record \"%s\" has no field \"%s\"" msgstr "记录\"%s\"没有字段\"%s\"" -#: pl_comp.c:1818 +#: pl_comp.c:1765 #, c-format msgid "relation \"%s\" does not exist" msgstr "关系 \"%s\" ä¸å­˜åœ¨" -#: pl_comp.c:1927 +#: pl_comp.c:1857 #, c-format msgid "variable \"%s\" has pseudo-type %s" msgstr "å˜é‡\"%s\"具有伪类型%s" -#: pl_comp.c:1994 -#, c-format -msgid "relation \"%s\" is not a table" -msgstr "关系 \"%s\"䏿˜¯ä¸€å¼ è¡¨" - -#: pl_comp.c:2154 +#: pl_comp.c:2037 #, c-format msgid "type \"%s\" is only a shell" msgstr "类型 \"%s\" åªæ˜¯ä¸€ä¸ª shell" -#: pl_comp.c:2243 pl_comp.c:2296 +#: pl_comp.c:2134 pl_comp.c:2187 #, c-format msgid "unrecognized exception condition \"%s\"" msgstr "ä¸å¯è¯†åˆ«çš„异常æ¡ä»¶\"%s\"" -#: pl_comp.c:2503 +#: pl_comp.c:2401 #, c-format -msgid "" -"could not determine actual argument type for polymorphic function \"%s\"" +msgid "could not determine actual argument type for polymorphic function \"%s\"" msgstr "无法确定多æ€å‡½æ•°\"%s\"çš„å®žé™…å‚æ•°ç±»åž‹" -#: pl_exec.c:324 pl_exec.c:612 pl_exec.c:872 +#: pl_exec.c:475 pl_exec.c:887 pl_exec.c:1125 msgid "during initialization of execution state" msgstr "在执行状æ€çš„åˆå§‹åŒ–期间" -#: pl_exec.c:331 +#: pl_exec.c:481 msgid "while storing call arguments into local variables" msgstr "åœ¨å°†è°ƒç”¨çš„å‚æ•°å­˜å‚¨åˆ°æœ¬åœ°å˜é‡æ—¶" -#: pl_exec.c:416 pl_exec.c:760 +#: pl_exec.c:569 pl_exec.c:960 msgid "during function entry" msgstr "在进入函数期间" -#: pl_exec.c:441 +#: pl_exec.c:594 #, c-format msgid "control reached end of function without RETURN" msgstr "控制æµç¨‹åˆ°è¾¾å‡½æ•°çš„结æŸéƒ¨åˆ†ï¼Œä½†æ˜¯æ²¡æœ‰çœ‹åˆ°RETURN" -#: pl_exec.c:448 +#: pl_exec.c:601 msgid "while casting return value to function's return type" msgstr "正在将返回值强行指派为函数的返回类型" -#: pl_exec.c:461 pl_exec.c:2938 +#: pl_exec.c:614 pl_exec.c:3556 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "é›†å€¼å‡½æ•°åœ¨ä¸æŽ¥å—使用集åˆçš„环境中调用" -#: pl_exec.c:499 pl_exec.c:2779 -msgid "returned record type does not match expected record type" -msgstr "所返回的记录类型与所期待的记录类型ä¸åŒ¹é…" - -#: pl_exec.c:554 pl_exec.c:789 pl_exec.c:907 +#: pl_exec.c:740 pl_exec.c:989 pl_exec.c:1150 msgid "during function exit" msgstr "在函数退出期间" -#: pl_exec.c:785 pl_exec.c:903 +#: pl_exec.c:795 pl_exec.c:834 pl_exec.c:3401 +msgid "returned record type does not match expected record type" +msgstr "所返回的记录类型与所期待的记录类型ä¸åŒ¹é…" + +#: pl_exec.c:985 pl_exec.c:1146 #, c-format msgid "control reached end of trigger procedure without RETURN" msgstr "控制æµç¨‹åˆ°è¾¾è§¦å‘器/存储过程的结æŸéƒ¨åˆ†ï¼Œä½†æ˜¯æ²¡æœ‰çœ‹åˆ°RETURN" -#: pl_exec.c:794 +#: pl_exec.c:994 #, c-format msgid "trigger procedure cannot return a set" msgstr "触å‘器存储过程无法返回集åˆ" -#: pl_exec.c:816 -msgid "" -"returned row structure does not match the structure of the triggering table" +#: pl_exec.c:1033 pl_exec.c:1061 +msgid "returned row structure does not match the structure of the triggering table" msgstr "所返回的记录结构与触å‘表的结构ä¸åŒ¹é…" #. translator: last %s is a phrase such as "during statement block #. local variable initialization" #. -#: pl_exec.c:954 +#: pl_exec.c:1198 #, c-format msgid "PL/pgSQL function %s line %d %s" msgstr "PL/pgSQL 函数%s在第%d行%s" @@ -172,369 +163,390 @@ msgstr "PL/pgSQL 函数%s在第%d行%s" #. translator: last %s is a phrase such as "while storing call #. arguments into local variables" #. -#: pl_exec.c:965 +#: pl_exec.c:1209 #, c-format msgid "PL/pgSQL function %s %s" msgstr "PL/pgSQL 函数%s %s" #. translator: last %s is a plpgsql statement type name -#: pl_exec.c:973 +#: pl_exec.c:1217 #, c-format msgid "PL/pgSQL function %s line %d at %s" msgstr "在%3$s的第%2$d行的PL/pgSQL函数%1$s" -#: pl_exec.c:979 +#: pl_exec.c:1223 #, c-format msgid "PL/pgSQL function %s" msgstr "PL/pgSQL函数 %s" -#: pl_exec.c:1089 +#: pl_exec.c:1561 msgid "during statement block local variable initialization" msgstr "在åˆå§‹åŒ–语å¥å—的局部å˜é‡æœŸé—´" -#: pl_exec.c:1128 -#, c-format -msgid "variable \"%s\" declared NOT NULL cannot default to NULL" -msgstr "声明为NOT NULLçš„å˜é‡\"%s\"无法将缺çœå€¼è®¾ä¸ºNULL" - -#: pl_exec.c:1178 +#: pl_exec.c:1659 msgid "during statement block entry" msgstr "在进入语å¥å—期间" -#: pl_exec.c:1199 +#: pl_exec.c:1691 msgid "during statement block exit" msgstr "在退出语å¥å—期间" -#: pl_exec.c:1242 +#: pl_exec.c:1729 msgid "during exception cleanup" msgstr "在清ç†å¼‚常期间" -#: pl_exec.c:1593 +#: pl_exec.c:2225 +#, c-format +msgid "procedure parameter \"%s\" is an output parameter but corresponding argument is not writable" +msgstr "è¿‡ç¨‹å‚æ•°\"%s\"æ˜¯è¾“å‡ºå‚æ•°ï¼Œä½†ç›¸åº”çš„å‚æ•°ä¸å¯å†™" + +#: pl_exec.c:2230 +#, c-format +msgid "procedure parameter %d is an output parameter but corresponding argument is not writable" +msgstr "è¿‡ç¨‹å‚æ•°%dæ˜¯è¾“å‡ºå‚æ•°ï¼Œä½†ç›¸åº”çš„å‚æ•°ä¸å¯å†™" + +#: pl_exec.c:2341 #, c-format msgid "GET STACKED DIAGNOSTICS cannot be used outside an exception handler" msgstr "GET STACKED DIAGNOSTICSä¸èƒ½ç”¨äºŽå¼‚常处ç†ä¹‹å¤–" -#: pl_exec.c:1789 +#: pl_exec.c:2540 #, c-format msgid "case not found" msgstr "没有找到CASE" -#: pl_exec.c:1790 +#: pl_exec.c:2541 #, c-format msgid "CASE statement is missing ELSE part." msgstr "在CASE语å¥ç»“构中丢失ELSE部分" -#: pl_exec.c:1944 +#: pl_exec.c:2634 #, c-format msgid "lower bound of FOR loop cannot be null" msgstr "FOR循环的低ä½è¾¹ç•Œä¸èƒ½ä¸ºç©º" -#: pl_exec.c:1960 +#: pl_exec.c:2650 #, c-format msgid "upper bound of FOR loop cannot be null" msgstr "FOR循环的高ä½è¾¹ç•Œä¸èƒ½ä¸ºç©º" -#: pl_exec.c:1978 +#: pl_exec.c:2668 #, c-format msgid "BY value of FOR loop cannot be null" msgstr "FOR循环的BY值ä¸èƒ½ä¸ºç©º" -#: pl_exec.c:1984 +#: pl_exec.c:2674 #, c-format msgid "BY value of FOR loop must be greater than zero" msgstr "FOR循环的BY值必须大于0" -#: pl_exec.c:2153 pl_exec.c:3912 +#: pl_exec.c:2808 pl_exec.c:4530 #, c-format msgid "cursor \"%s\" already in use" msgstr "游标\"%s\"å·²ç»åœ¨ä½¿ç”¨" -#: pl_exec.c:2176 pl_exec.c:3974 +#: pl_exec.c:2831 pl_exec.c:4595 #, c-format msgid "arguments given for cursor without arguments" msgstr "ç»™ä¸å¸¦æœ‰å‚æ•°çš„æ¸¸æ ‡æŒ‡å®šå‚æ•°" -#: pl_exec.c:2195 pl_exec.c:3993 +#: pl_exec.c:2850 pl_exec.c:4614 #, c-format msgid "arguments required for cursor" msgstr "游标需è¦å‚æ•°" -#: pl_exec.c:2280 +#: pl_exec.c:2937 #, c-format msgid "FOREACH expression must not be null" msgstr "FOREACH表达å¼ä¸èƒ½ä¸ºç©º" -#: pl_exec.c:2286 +#: pl_exec.c:2952 #, c-format msgid "FOREACH expression must yield an array, not type %s" msgstr "FOREACH表达å¼çš„结果必须是数组, è€Œä¸æ˜¯ç±»åž‹ %s" -#: pl_exec.c:2303 +#: pl_exec.c:2969 #, c-format msgid "slice dimension (%d) is out of the valid range 0..%d" msgstr "索引维数(%d)超出有效范围: 0..%d" -#: pl_exec.c:2330 +#: pl_exec.c:2996 #, c-format msgid "FOREACH ... SLICE loop variable must be of an array type" msgstr "FOREACH ... SLICE循环å˜é‡å¿…须属于数组类型" -#: pl_exec.c:2334 +#: pl_exec.c:3000 #, c-format msgid "FOREACH loop variable must not be of an array type" msgstr "FOREACH循环å˜é‡ä¸èƒ½ä¸ºæ•°ç»„类型" -#: pl_exec.c:2522 pl_exec.c:2604 pl_exec.c:2771 +#: pl_exec.c:3162 pl_exec.c:3219 pl_exec.c:3394 #, c-format -msgid "" -"cannot return non-composite value from function returning composite type" +msgid "cannot return non-composite value from function returning composite type" msgstr "返回值为组åˆç±»åž‹çš„函数ä¸èƒ½è¿”回éžç»„åˆåž‹çš„值" -#: pl_exec.c:2648 pl_gram.y:3161 +#: pl_exec.c:3258 pl_gram.y:3305 #, c-format msgid "cannot use RETURN NEXT in a non-SETOF function" msgstr "无法在éžSETOF函数中使用RETURN NEXT" -#: pl_exec.c:2682 pl_exec.c:2813 +#: pl_exec.c:3299 pl_exec.c:3431 #, c-format msgid "wrong result type supplied in RETURN NEXT" msgstr "在RETURN NEXT中æä¾›äº†é”™è¯¯çš„结果类型" -#: pl_exec.c:2711 pl_exec.c:4382 pl_exec.c:4711 pl_exec.c:4737 pl_exec.c:4803 -#: pl_exec.c:4822 pl_exec.c:4890 pl_exec.c:4913 -#, c-format -msgid "record \"%s\" is not assigned yet" -msgstr "记录 \"%s\"还没有分é…" - -#: pl_exec.c:2713 pl_exec.c:4384 pl_exec.c:4713 pl_exec.c:4739 pl_exec.c:4805 -#: pl_exec.c:4824 pl_exec.c:4892 pl_exec.c:4915 -#, c-format -msgid "The tuple structure of a not-yet-assigned record is indeterminate." -msgstr "未分é…记录的元组结构未确定." - -#: pl_exec.c:2717 pl_exec.c:2737 +#: pl_exec.c:3337 pl_exec.c:3358 #, c-format msgid "wrong record type supplied in RETURN NEXT" msgstr "在RETURN NEXT中æä¾›äº†é”™è¯¯çš„记录类型" -#: pl_exec.c:2832 +#: pl_exec.c:3450 #, c-format msgid "RETURN NEXT must have a parameter" msgstr "RETURN NEXTå¿…é¡»æœ‰ä¸€ä¸ªå‚æ•°" -#: pl_exec.c:2865 pl_gram.y:3223 +#: pl_exec.c:3476 pl_gram.y:3369 #, c-format msgid "cannot use RETURN QUERY in a non-SETOF function" msgstr "无法在éžSETOF函数中使用RETURN QUERY" -#: pl_exec.c:2886 +#: pl_exec.c:3500 msgid "structure of query does not match function result type" msgstr "查询的结构与函数的返回类型ä¸åŒ¹é…" -#: pl_exec.c:2966 pl_exec.c:3096 +#: pl_exec.c:3584 pl_exec.c:3722 #, c-format msgid "RAISE option already specified: %s" msgstr "å·²ç»æŒ‡å®šäº†RAISE选项:%s" -#: pl_exec.c:2999 +#: pl_exec.c:3618 #, c-format msgid "RAISE without parameters cannot be used outside an exception handler" msgstr "ä¸å¸¦æœ‰å‚æ•°çš„RAISEä¸èƒ½åœ¨å¼‚常处ç†çš„外部使用" -#: pl_exec.c:3086 +#: pl_exec.c:3712 #, c-format msgid "RAISE statement option cannot be null" msgstr "RAISE语å¥é€‰é¡¹ä¸èƒ½ä¸ºç©º" -#: pl_exec.c:3155 +#: pl_exec.c:3782 #, c-format msgid "%s" msgstr "%s" -#: pl_exec.c:3226 +#: pl_exec.c:3837 #, c-format msgid "assertion failed" msgstr "断言失败" -#: pl_exec.c:3418 pl_exec.c:3562 pl_exec.c:3751 +#: pl_exec.c:4179 pl_exec.c:4369 #, c-format msgid "cannot COPY to/from client in PL/pgSQL" msgstr "无法在PL/pgSQL中从客户端或å‘客户端使用COPY命令" -#: pl_exec.c:3422 pl_exec.c:3566 pl_exec.c:3755 +#: pl_exec.c:4185 #, c-format -msgid "cannot begin/end transactions in PL/pgSQL" -msgstr "无法在PL/pgSQL中无法使用begin/end事务" +msgid "unsupported transaction command in PL/pgSQL" +msgstr "PL/pgSQL䏭䏿”¯æŒçš„事务命令" -#: pl_exec.c:3423 pl_exec.c:3567 pl_exec.c:3756 -#, c-format -msgid "Use a BEGIN block with an EXCEPTION clause instead." -msgstr "使用带有一个EXCEPTIONå­å¥çš„BEGIN代ç å—." - -#: pl_exec.c:3590 pl_exec.c:3780 +#: pl_exec.c:4208 pl_exec.c:4398 #, c-format msgid "INTO used with a command that cannot return data" msgstr "使用了带有无法返回数æ®çš„命令的INTO" -#: pl_exec.c:3618 pl_exec.c:3808 +#: pl_exec.c:4231 pl_exec.c:4421 #, c-format msgid "query returned no rows" msgstr "查询没有返回记录" -#: pl_exec.c:3637 pl_exec.c:3827 +#: pl_exec.c:4253 pl_exec.c:4440 #, c-format msgid "query returned more than one row" msgstr "查询返回多æ¡è®°å½•" -#: pl_exec.c:3654 +#: pl_exec.c:4255 +#, c-format +msgid "Make sure the query returns a single row, or use LIMIT 1." +msgstr "" + +#: pl_exec.c:4271 #, c-format msgid "query has no destination for result data" msgstr "对于结果数æ®ï¼ŒæŸ¥è¯¢æ²¡æœ‰ç›®æ ‡" -#: pl_exec.c:3655 +#: pl_exec.c:4272 #, c-format msgid "If you want to discard the results of a SELECT, use PERFORM instead." msgstr "å¦‚æžœæ‚¨æƒ³è¦æ”¾å¼ƒSELECT语å¥çš„结果,请使用PERFORM." -#: pl_exec.c:3687 pl_exec.c:7128 +#: pl_exec.c:4305 pl_exec.c:8416 #, c-format msgid "query string argument of EXECUTE is null" msgstr "EXECUTEçš„æŸ¥è¯¢å­—ç¬¦ä¸²å‚æ•°æ˜¯ç©ºå€¼" -#: pl_exec.c:3743 +#: pl_exec.c:4361 #, c-format msgid "EXECUTE of SELECT ... INTO is not implemented" msgstr "没有执行EXECUTE of SELECT ... INTO " -#: pl_exec.c:3744 +#: pl_exec.c:4362 #, c-format -msgid "" -"You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS " -"instead." +msgid "You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead." msgstr "您å¯ä»¥ä½¿ç”¨EXECUTE ... INTO或者EXECUTE CREATE TABLE ... ASè¯­å¥æ¥æ›¿ä»£" -#: pl_exec.c:4056 pl_exec.c:4148 +#: pl_exec.c:4375 +#, c-format +msgid "EXECUTE of transaction commands is not implemented" +msgstr "未执行事务命令" + +#: pl_exec.c:4676 pl_exec.c:4764 #, c-format msgid "cursor variable \"%s\" is null" msgstr "游标å˜é‡\"%s\"是空的" -#: pl_exec.c:4063 pl_exec.c:4155 +#: pl_exec.c:4687 pl_exec.c:4775 #, c-format msgid "cursor \"%s\" does not exist" msgstr "游标 \"%s\" ä¸å­˜åœ¨" -#: pl_exec.c:4077 +#: pl_exec.c:4700 #, c-format msgid "relative or absolute cursor position is null" msgstr "游标的相对或ç»å¯¹ä½ç½®æ˜¯ç©ºçš„" -#: pl_exec.c:4257 +#: pl_exec.c:4956 pl_exec.c:5051 #, c-format msgid "null value cannot be assigned to variable \"%s\" declared NOT NULL" msgstr "ä¸èƒ½å°†å£°æ˜Žä¸ºNOT NULLçš„å˜é‡\"%s\" 分é…空值" -#: pl_exec.c:4326 +#: pl_exec.c:5032 #, c-format msgid "cannot assign non-composite value to a row variable" msgstr "无法将éžç»„åˆå€¼åˆ†é…给记录å˜é‡" -#: pl_exec.c:4350 +#: pl_exec.c:5064 #, c-format msgid "cannot assign non-composite value to a record variable" msgstr "无法将éžç»„åˆå€¼åˆ†é…给记录类型å˜é‡" -#: pl_exec.c:4493 +#: pl_exec.c:5115 +#, c-format +msgid "cannot assign to system column \"%s\"" +msgstr "ä¸èƒ½æŒ‡å®šç³»ç»Ÿå­—段å \"%s\"" + +#: pl_exec.c:5179 #, c-format msgid "number of array dimensions (%d) exceeds the maximum allowed (%d)" msgstr "数组维数(%d)超过了最大å…许值(%d)" -#: pl_exec.c:4525 +#: pl_exec.c:5211 #, c-format msgid "subscripted object is not an array" msgstr "ä¸‹æ ‡å¯¹è±¡ä¸æ˜¯ä¸€ä¸ªæ•°ç»„" -#: pl_exec.c:4562 +#: pl_exec.c:5249 #, c-format msgid "array subscript in assignment must not be null" msgstr "在赋值中数组下标ä¸èƒ½ä¸ºç©º" -#: pl_exec.c:5029 +#: pl_exec.c:5756 #, c-format msgid "query \"%s\" did not return data" msgstr "查询\"%s\"没有返回数æ®" -#: pl_exec.c:5037 +#: pl_exec.c:5764 #, c-format msgid "query \"%s\" returned %d column" msgid_plural "query \"%s\" returned %d columns" msgstr[0] "查询\"%s\"返回%d列" -#: pl_exec.c:5064 +#: pl_exec.c:5792 #, c-format msgid "query \"%s\" returned more than one row" msgstr "查询\"%s\"è¿”å›žå¤šæ¡æ•°æ®" -#: pl_exec.c:5128 +#: pl_exec.c:5855 #, c-format msgid "query \"%s\" is not a SELECT" msgstr "查询 \"%s\"䏿˜¯SELECT语å¥" -#: pl_funcs.c:237 +#: pl_exec.c:6580 pl_exec.c:6620 pl_exec.c:6660 +#, c-format +msgid "type of parameter %d (%s) does not match that when preparing the plan (%s)" +msgstr "第%dä¸ªå‚æ•°(%s)的类型与正在执行计划(%s)中的ä¸åŒ¹é…" + +#: pl_exec.c:6996 pl_exec.c:7030 pl_exec.c:7104 pl_exec.c:7130 +#, c-format +msgid "number of source and target fields in assignment does not match" +msgstr "" + +#. translator: %s represents a name of an extra check +#: pl_exec.c:6998 pl_exec.c:7032 pl_exec.c:7106 pl_exec.c:7132 +#, c-format +msgid "%s check of %s is active." +msgstr "" + +#: pl_exec.c:7002 pl_exec.c:7036 pl_exec.c:7110 pl_exec.c:7136 +#, c-format +msgid "Make sure the query returns the exact list of columns." +msgstr "" + +#: pl_exec.c:7518 +#, c-format +msgid "record \"%s\" is not assigned yet" +msgstr "记录 \"%s\"还没有分é…" + +#: pl_exec.c:7519 +#, c-format +msgid "The tuple structure of a not-yet-assigned record is indeterminate." +msgstr "未分é…记录的元组结构未确定." + +#: pl_funcs.c:239 msgid "statement block" msgstr "语å¥å—" -#: pl_funcs.c:239 +#: pl_funcs.c:241 msgid "assignment" msgstr "赋值" -#: pl_funcs.c:249 +#: pl_funcs.c:251 msgid "FOR with integer loop variable" msgstr "带有整型循环å˜é‡çš„FOR语å¥" -#: pl_funcs.c:251 +#: pl_funcs.c:253 msgid "FOR over SELECT rows" msgstr "在SELECT记录上的FOR语å¥" -#: pl_funcs.c:253 +#: pl_funcs.c:255 msgid "FOR over cursor" msgstr "在游标上è¿è¡Œçš„FOR语å¥" -#: pl_funcs.c:255 +#: pl_funcs.c:257 msgid "FOREACH over array" msgstr "在数组上è¿è¡Œçš„FOREACH语å¥" -#: pl_funcs.c:269 +#: pl_funcs.c:271 msgid "SQL statement" msgstr "SQL语å¥" -#: pl_funcs.c:273 +#: pl_funcs.c:275 msgid "FOR over EXECUTE statement" msgstr "在EXECUTE语å¥ä¸Šçš„FOR语å¥" -#: pl_gram.y:473 +#: pl_gram.y:489 #, c-format msgid "block label must be placed before DECLARE, not after" msgstr "代ç å—标签必须放在DECLAREçš„å‰é¢ï¼Œè€Œä¸æ˜¯åŽé¢" -#: pl_gram.y:493 +#: pl_gram.y:509 #, c-format msgid "collations are not supported by type %s" msgstr "类型 %s䏿”¯æŒæ ¡å¯¹å‡½æ•°" -#: pl_gram.y:508 +#: pl_gram.y:528 #, c-format -msgid "row or record variable cannot be CONSTANT" -msgstr "记录或者记录类型å˜é‡ä¸èƒ½æ˜¯CONSTANT类型" - -#: pl_gram.y:518 -#, c-format -msgid "row or record variable cannot be NOT NULL" -msgstr "记录或者记录类型å˜é‡ä¸èƒ½æ˜¯NOT NULL" - -#: pl_gram.y:529 -#, c-format -msgid "default value for row or record variable is not supported" -msgstr "䏿”¯æŒä¸ºè®°å½•或记录类型å˜é‡è®¾ç½®ç¼ºçœå€¼" +msgid "variable \"%s\" must have a default value, since it's declared NOT NULL" +msgstr "å˜é‡\"%s\"必须有默认值,因为它声明为éžç©º" #: pl_gram.y:674 pl_gram.y:689 pl_gram.y:715 #, c-format @@ -550,398 +562,283 @@ msgstr "é‡å¤å£°æ˜Ž" msgid "variable \"%s\" shadows a previously defined variable" msgstr "å˜é‡\"%s\"éšè—了å‰ä¸€ä¸ªå·²å®šä¹‰çš„å˜é‡" -#: pl_gram.y:951 +#: pl_gram.y:992 #, c-format msgid "diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS" msgstr "诊断项 %s ä¸å…许出现在GET STACKED DIAGNOSTICS的结果中" -#: pl_gram.y:969 +#: pl_gram.y:1010 #, c-format msgid "diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS" msgstr "诊断项 %s ä¸å…许出现在GET CURRENT DIAGNOSTICS的结果中" -#: pl_gram.y:1067 +#: pl_gram.y:1105 msgid "unrecognized GET DIAGNOSTICS item" msgstr "无法识别的项GET DIAGNOSTICS" -#: pl_gram.y:1078 pl_gram.y:3410 +#: pl_gram.y:1115 pl_gram.y:3549 #, c-format msgid "\"%s\" is not a scalar variable" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªæ ‡é‡å˜é‡" -#: pl_gram.y:1330 pl_gram.y:1524 +#: pl_gram.y:1369 pl_gram.y:1565 #, c-format -msgid "" -"loop variable of loop over rows must be a record or row variable or list of " -"scalar variables" -msgstr "在记录集上进行循环的循环å˜é‡å¿…须是记录或记录类型å˜é‡æˆ–æ ‡é‡å˜é‡çš„列表" +msgid "loop variable of loop over rows must be a record variable or list of scalar variables" +msgstr "在记录集上进行循环的循环å˜é‡å¿…须是记录å˜é‡æˆ–æ ‡é‡å˜é‡åˆ—表" -#: pl_gram.y:1364 +#: pl_gram.y:1404 #, c-format msgid "cursor FOR loop must have only one target variable" msgstr "游标的FOR循环åªèƒ½æœ‰ä¸€ä¸ªç›®æ ‡å˜é‡" -#: pl_gram.y:1371 +#: pl_gram.y:1411 #, c-format msgid "cursor FOR loop must use a bound cursor variable" msgstr "游标的FOR循环必须使用有界游标å˜é‡" -#: pl_gram.y:1455 +#: pl_gram.y:1498 #, c-format msgid "integer FOR loop must have only one target variable" msgstr "æ•´æ•°FOR循环必须åªèƒ½æœ‰ä¸€ä¸ªç›®æ ‡å˜é‡" -#: pl_gram.y:1491 +#: pl_gram.y:1535 #, c-format msgid "cannot specify REVERSE in query FOR loop" msgstr "无法在查询FOR循环中指定REVERSE " -#: pl_gram.y:1638 +#: pl_gram.y:1668 #, c-format msgid "loop variable of FOREACH must be a known variable or list of variables" msgstr "FOREACH的循环å˜é‡å¿…须是已知类型或者是å˜é‡åˆ—表" -#: pl_gram.y:1679 +#: pl_gram.y:1710 #, c-format -msgid "" -"there is no label \"%s\" attached to any block or loop enclosing this " -"statement" +msgid "there is no label \"%s\" attached to any block or loop enclosing this statement" msgstr "在任何包围这个语å¥çš„å—æˆ–è€…å¾ªçŽ¯ä¸Šéƒ½æ²¡æœ‰é™„ç€æ ‡ç­¾\"%s\"" -#: pl_gram.y:1687 +#: pl_gram.y:1718 #, c-format -#| msgid "portal \"%s\" cannot be run" msgid "block label \"%s\" cannot be used in CONTINUE" msgstr "å—æ ‡ç­¾ \"%s\" ä¸èƒ½è¢«ç”¨åœ¨ CONTINUE 中" -#: pl_gram.y:1702 +#: pl_gram.y:1733 #, c-format -#| msgid "CONTINUE cannot be used outside a loop" msgid "EXIT cannot be used outside a loop, unless it has a label" msgstr "ä¸èƒ½åœ¨å¾ªçŽ¯å¤–éƒ¨ä½¿ç”¨EXIT,除éžè¯¥å¾ªçŽ¯æœ‰ä¸€ä¸ªæ ‡ç­¾" -#: pl_gram.y:1703 +#: pl_gram.y:1734 #, c-format msgid "CONTINUE cannot be used outside a loop" msgstr "在循环的外部ä¸èƒ½ä½¿ç”¨CONTINUE" -#: pl_gram.y:1727 pl_gram.y:1764 pl_gram.y:1812 pl_gram.y:2863 pl_gram.y:2945 -#: pl_gram.y:3056 pl_gram.y:3812 +#: pl_gram.y:1758 pl_gram.y:1796 pl_gram.y:1844 pl_gram.y:2994 pl_gram.y:3079 +#: pl_gram.y:3190 pl_gram.y:3950 msgid "unexpected end of function definition" msgstr "在函数定义中æ„å¤–å‡ºçŽ°çš„ç»“æŸæ ‡å¿—" -#: pl_gram.y:1832 pl_gram.y:1856 pl_gram.y:1872 pl_gram.y:1878 pl_gram.y:1992 -#: pl_gram.y:2000 pl_gram.y:2014 pl_gram.y:2109 pl_gram.y:2290 pl_gram.y:2384 -#: pl_gram.y:2535 pl_gram.y:3653 pl_gram.y:3714 pl_gram.y:3793 +#: pl_gram.y:1864 pl_gram.y:1888 pl_gram.y:1904 pl_gram.y:1910 pl_gram.y:2029 +#: pl_gram.y:2037 pl_gram.y:2051 pl_gram.y:2146 pl_gram.y:2395 pl_gram.y:2489 +#: pl_gram.y:2648 pl_gram.y:3792 pl_gram.y:3853 pl_gram.y:3931 msgid "syntax error" msgstr "语法错误" -#: pl_gram.y:1860 pl_gram.y:1862 pl_gram.y:2294 pl_gram.y:2296 +#: pl_gram.y:1892 pl_gram.y:1894 pl_gram.y:2399 pl_gram.y:2401 msgid "invalid SQLSTATE code" msgstr "无效的SQLSTATE代ç " -#: pl_gram.y:2056 +#: pl_gram.y:2094 msgid "syntax error, expected \"FOR\"" msgstr "语法错误,期望\"FOR\"" -#: pl_gram.y:2118 +#: pl_gram.y:2155 #, c-format msgid "FETCH statement cannot return multiple rows" msgstr "FETCHè¯­å¥æ— æ³•返回多æ¡è®°å½•" -#: pl_gram.y:2174 +#: pl_gram.y:2279 #, c-format msgid "cursor variable must be a simple variable" msgstr "游标å˜é‡å¿…须是一个简å•å˜é‡" -#: pl_gram.y:2180 +#: pl_gram.y:2285 #, c-format msgid "variable \"%s\" must be of type cursor or refcursor" msgstr "å˜é‡\"%s\" 必须属于游标类型或refcursor类型" -#: pl_gram.y:2506 pl_gram.y:2517 +#: pl_gram.y:2619 pl_gram.y:2630 #, c-format msgid "\"%s\" is not a known variable" msgstr "\"%s\" 䏿˜¯ä¸€ä¸ªå·²çŸ¥å˜é‡" -#: pl_gram.y:2621 pl_gram.y:2631 pl_gram.y:2787 +#: pl_gram.y:2734 pl_gram.y:2744 pl_gram.y:2899 msgid "mismatched parentheses" msgstr "括å·ä¸åŒ¹é…" -#: pl_gram.y:2635 +#: pl_gram.y:2748 #, c-format msgid "missing \"%s\" at end of SQL expression" msgstr "在SQL表达å¼çš„结尾处丢失\"%s\"" -#: pl_gram.y:2641 +#: pl_gram.y:2754 #, c-format msgid "missing \"%s\" at end of SQL statement" msgstr "在SQL语å¥çš„结尾处丢失\"%s\"" -#: pl_gram.y:2658 +#: pl_gram.y:2771 msgid "missing expression" msgstr "缺少表达å¼" -#: pl_gram.y:2660 +#: pl_gram.y:2773 msgid "missing SQL statement" msgstr "缺少SQL语å¥" -#: pl_gram.y:2789 +#: pl_gram.y:2901 msgid "incomplete data type declaration" msgstr "未完æˆçš„æ•°æ®ç±»åž‹å£°æ˜Ž" -#: pl_gram.y:2812 +#: pl_gram.y:2924 msgid "missing data type declaration" msgstr "丢失数æ®ç±»åž‹å£°æ˜Ž" -#: pl_gram.y:2868 +#: pl_gram.y:3002 msgid "INTO specified more than once" msgstr "多次指定INTO" -#: pl_gram.y:3037 +#: pl_gram.y:3171 msgid "expected FROM or IN" msgstr "期望关键字FROM或IN" -#: pl_gram.y:3097 +#: pl_gram.y:3232 #, c-format msgid "RETURN cannot have a parameter in function returning set" msgstr "在返回为集åˆçš„函数中RETURNä¸èƒ½å¸¦æœ‰å‚æ•°" -#: pl_gram.y:3098 +#: pl_gram.y:3233 #, c-format msgid "Use RETURN NEXT or RETURN QUERY." msgstr "使用RETURN NEXT或RETURN QUERY." -#: pl_gram.y:3106 +#: pl_gram.y:3243 #, c-format -msgid "RETURN cannot have a parameter in function with OUT parameters" -msgstr "åœ¨å¸¦æœ‰è¾“å‡ºå‚æ•°çš„函数中RETURNä¸èƒ½æœ‰å‚æ•°" +msgid "RETURN cannot have a parameter in a procedure" +msgstr "在过程中RETURNä¸èƒ½å¸¦æœ‰å‚æ•°" -#: pl_gram.y:3115 +#: pl_gram.y:3248 #, c-format msgid "RETURN cannot have a parameter in function returning void" msgstr "在返回为空的函数中RETURNä¸èƒ½æœ‰å‚æ•°" -#: pl_gram.y:3175 +#: pl_gram.y:3257 +#, c-format +msgid "RETURN cannot have a parameter in function with OUT parameters" +msgstr "åœ¨å¸¦æœ‰è¾“å‡ºå‚æ•°çš„函数中RETURNä¸èƒ½æœ‰å‚æ•°" + +#: pl_gram.y:3320 #, c-format msgid "RETURN NEXT cannot have a parameter in function with OUT parameters" msgstr "åœ¨å¸¦æœ‰è¾“å‡ºå‚æ•°çš„函数中RETURN NEXTä¸èƒ½æœ‰å‚æ•°" -#: pl_gram.y:3279 +#: pl_gram.y:3428 #, c-format -msgid "\"%s\" is declared CONSTANT" -msgstr "\"%s\"被声明为常é‡" +msgid "variable \"%s\" is declared CONSTANT" +msgstr "å˜é‡\"%s\"被声明为常é‡" -#: pl_gram.y:3341 pl_gram.y:3353 +#: pl_gram.y:3491 #, c-format -msgid "record or row variable cannot be part of multiple-item INTO list" -msgstr "记录或行类型å˜é‡ä¸èƒ½ä½œä¸ºå¸¦æœ‰å¤šä¸ªé¡¹çš„INTO列表中的一部分" +msgid "record variable cannot be part of multiple-item INTO list" +msgstr "记录å˜é‡ä¸èƒ½ä½œä¸ºå¸¦æœ‰å¤šä¸ªé¡¹çš„INTO列表中的一部分" -#: pl_gram.y:3398 +#: pl_gram.y:3537 #, c-format msgid "too many INTO variables specified" msgstr "在INTOåŽé¢æŒ‡å®šäº†å¤ªå¤šçš„å˜é‡" -#: pl_gram.y:3606 +#: pl_gram.y:3745 #, c-format msgid "end label \"%s\" specified for unlabelled block" msgstr "为没有标签的代ç å—æŒ‡å®šç»“æŸæ ‡ç­¾\"%s\" " -#: pl_gram.y:3613 +#: pl_gram.y:3752 #, c-format msgid "end label \"%s\" differs from block's label \"%s\"" msgstr "ç»“æŸæ ‡ç­¾\"%s\" 与代ç å—标签\"%s\"ä¸åŒ" -#: pl_gram.y:3648 +#: pl_gram.y:3787 #, c-format msgid "cursor \"%s\" has no arguments" msgstr "游标\"%s\" æ²¡æœ‰å‚æ•°" -#: pl_gram.y:3662 +#: pl_gram.y:3801 #, c-format msgid "cursor \"%s\" has arguments" msgstr "游标\"%s\"æœ‰å‚æ•°" -#: pl_gram.y:3704 +#: pl_gram.y:3843 #, c-format msgid "cursor \"%s\" has no argument named \"%s\"" msgstr "游标\"%s\" 没有å为 \"%s\"çš„å‚æ•°" -#: pl_gram.y:3724 +#: pl_gram.y:3863 #, c-format msgid "value for parameter \"%s\" of cursor \"%s\" specified more than once" msgstr "游标\"%2$s\"ä¸­çš„å‚æ•°å€¼\"%1$s\"指定了多次" -#: pl_gram.y:3749 +#: pl_gram.y:3888 #, c-format msgid "not enough arguments for cursor \"%s\"" msgstr "游标 \"%s\"æ²¡æœ‰è¶³å¤Ÿçš„å‚æ•°" -#: pl_gram.y:3756 +#: pl_gram.y:3895 #, c-format msgid "too many arguments for cursor \"%s\"" msgstr "游标 \"%s\"ç»™å®šçš„å‚æ•°å¤ªå¤š" -#: pl_gram.y:3844 +#: pl_gram.y:3982 msgid "unrecognized RAISE statement option" msgstr "无法识别的RAISE语å¥é€‰é¡¹" -#: pl_gram.y:3848 +#: pl_gram.y:3986 msgid "syntax error, expected \"=\"" msgstr "语法错误,期望\"=\"" -#: pl_gram.y:3889 +#: pl_gram.y:4027 #, c-format msgid "too many parameters specified for RAISE" msgstr "为RAISEå­å¥æŒ‡å®šå‚数过多" -#: pl_gram.y:3893 +#: pl_gram.y:4031 #, c-format msgid "too few parameters specified for RAISE" msgstr "为RAISEå­å¥æŒ‡å®šå‚数过少" -#: pl_handler.c:149 -msgid "" -"Sets handling of conflicts between PL/pgSQL variable names and table column " -"names." +#: pl_handler.c:158 +msgid "Sets handling of conflicts between PL/pgSQL variable names and table column names." msgstr "设置在PL/pgSQLå˜é‡å称和表中列åå†²çªæ—¶çš„处ç†åŽŸåˆ™" -#: pl_handler.c:158 -msgid "" -"Print information about parameters in the DETAIL part of the error messages " -"generated on INTO ... STRICT failures." +#: pl_handler.c:167 +msgid "Print information about parameters in the DETAIL part of the error messages generated on INTO ... STRICT failures." msgstr "打å°äº§ç”ŸäºŽINTO...STRICT失败时的详细的错误消æ¯é‡Œçš„傿•°ä¿¡æ¯" -#: pl_handler.c:166 +#: pl_handler.c:175 msgid "Perform checks given in ASSERT statements." msgstr "执行在ASSERT语å¥ä¸­ç»™å®šçš„æ£€æŸ¥ã€‚" -#: pl_handler.c:174 +#: pl_handler.c:183 msgid "List of programming constructs that should produce a warning." msgstr "ç¨‹åºæž„造列表必须输出警告." -#: pl_handler.c:184 +#: pl_handler.c:193 msgid "List of programming constructs that should produce an error." msgstr "ç¨‹åºæž„é€ åˆ—è¡¨å¿…é¡»è¾“å‡ºä¸€ä¸ªé”™è¯¯ä¿¡æ¯æç¤º." #. translator: %s is typically the translation of "syntax error" -#: pl_scanner.c:621 +#: pl_scanner.c:508 #, c-format msgid "%s at end of input" msgstr "%s 在输入的末尾" #. translator: first %s is typically the translation of "syntax error" -#: pl_scanner.c:637 +#: pl_scanner.c:524 #, c-format msgid "%s at or near \"%s\"" msgstr "%s 在 \"%s\" 或附近的" - -#~ msgid "EXECUTE statement" -#~ msgstr "EXECUTE 语å¥" - -#~ msgid "" -#~ "RETURN must specify a record or row variable in function returning row" -#~ msgstr "在返回记录的函数中RETURN必须制定一个记录或记录类型å˜é‡" - -#~ msgid "" -#~ "RETURN NEXT must specify a record or row variable in function returning " -#~ "row" -#~ msgstr "在返回记录的函数中RETURN NEXT必须指定记录或记录类型å˜é‡" - -#~ msgid "unterminated dollar-quoted string" -#~ msgstr "未结æŸçš„$引用字符串" - -#~ msgid "unterminated quoted string" -#~ msgstr "未结æŸçš„引用字符串" - -#~ msgid "unterminated /* comment" -#~ msgstr "/* 注释没有结æŸ" - -#~ msgid "unterminated quoted identifier" -#~ msgstr "未结æŸçš„引用标识符" - -#~ msgid "qualified identifier cannot be used here: %s" -#~ msgstr "在这里ä¸èƒ½ä½¿ç”¨é™å®šæ ‡è¯†ç¬¦ï¼š%s" - -#~ msgid "unterminated \" in identifier: %s" -#~ msgstr "在标识符中未结æŸçš„\":%s" - -#~ msgid "variable \"%s\" does not exist in the current block" -#~ msgstr "在当å‰ä»£ç å—中ä¸å­˜åœ¨å˜é‡ \"%s\"" - -#~ msgid "expected \")\"" -#~ msgstr "期望\")\"" - -#~ msgid "string literal in PL/PgSQL function \"%s\" near line %d" -#~ msgstr "在PL/PgSQL函数 \"%s\" 第%d行附近的字符串常é‡" - -#~ msgid "SQL statement in PL/PgSQL function \"%s\" near line %d" -#~ msgstr "在PL/PgSQL函数 \"%s\" 第%d行附近的SQL语å¥" - -#~ msgid "" -#~ "Expected record variable, row variable, or list of scalar variables " -#~ "following INTO." -#~ msgstr "在INTOåŽæœŸæœ›è®°å½•类型å˜é‡ï¼Œè®°å½•å˜é‡æˆ–æ ‡é‡å˜é‡çš„列表." - -#~ msgid "cannot assign to tg_argv" -#~ msgstr "无法分é…到tg_argv" - -#~ msgid "" -#~ "RETURN cannot have a parameter in function returning set; use RETURN NEXT " -#~ "or RETURN QUERY" -#~ msgstr "在返回集åˆçš„函数中RETURNä¸èƒ½æœ‰å‚æ•°;使用RETURN NEXT或RETURN QUERY" - -#~ msgid "too many variables specified in SQL statement" -#~ msgstr "在SQL语å¥ä¸­æŒ‡å®šäº†å¤ªå¤šçš„å˜é‡" - -#~ msgid "expected a cursor or refcursor variable" -#~ msgstr "期望游标或refcursor类型å˜é‡" - -#~ msgid "Expected \"FOR\", to open a cursor for an unbound cursor variable." -#~ msgstr "期望\"FOR\"æ¥ä¸ºæ— ç•Œæ¸¸æ ‡å˜é‡æ‰“开游标" - -#~ msgid "syntax error at \"%s\"" -#~ msgstr "在\"%s\"上出现语法错误" - -#~ msgid "expected an integer variable" -#~ msgstr "期望一个整型å˜é‡" - -#~ msgid "function has no parameter \"%s\"" -#~ msgstr "å‡½æ•°ä¸­æ²¡æœ‰å‚æ•°\"%s\"" - -#~ msgid "only positional parameters can be aliased" -#~ msgstr "åªæœ‰å·²å®šä½çš„傿•°èƒ½ä½¿ç”¨åŒ–å" - -#~ msgid "Returned type %s does not match expected type %s in column \"%s\"." -#~ msgstr "所返回的类型%1$s与列\"%3$s\"中期待的类型%2$sä¸åŒ¹é…." - -#~ msgid "" -#~ "Number of returned columns (%d) does not match expected column count (%d)." -#~ msgstr "所返回列的数é‡ï¼ˆ%d列)与所期望列的数é‡(%d)ä¸åŒ¹é…." - -#~ msgid "N/A (dropped column)" -#~ msgstr "N/A (已删除的列)" - -#~ msgid "type of tg_argv[%d] does not match that when preparing the plan" -#~ msgstr "tg_argv[%d]的类型与正在准备计划时的类型ä¸åŒ¹é…" - -#~ msgid "type of \"%s.%s\" does not match that when preparing the plan" -#~ msgstr " \"%s.%s\"类型与正在准备计划时的类型ä¸åŒ¹é…" - -#~ msgid "type of \"%s\" does not match that when preparing the plan" -#~ msgstr " \"%s\"类型与正在准备计划时的类型ä¸åŒ¹é…" - -#~ msgid "row \"%s.%s\" has no field \"%s\"" -#~ msgstr "记录\"%s.%s\"没有字段\"%s\"" - -#~ msgid "row \"%s\" has no field \"%s\"" -#~ msgstr "记录\"%s\"没有字段\"%s\"" - -#~ msgid "expected \"[\"" -#~ msgstr "期望 \"[\"" - -#~ msgid "relation \"%s.%s\" does not exist" -#~ msgstr "关系 \"%s.%s\" ä¸å­˜åœ¨" - -#~ msgid "label does not exist" -#~ msgstr "标签ä¸å­˜åœ¨" diff --git a/src/pl/plpgsql/src/sql/plpgsql_cache.sql b/src/pl/plpgsql/src/sql/plpgsql_cache.sql new file mode 100644 index 00000000000..f3b64d9209f --- /dev/null +++ b/src/pl/plpgsql/src/sql/plpgsql_cache.sql @@ -0,0 +1,50 @@ +-- +-- Cache-behavior-dependent test cases +-- +-- These tests logically belong in plpgsql_record.sql, and perhaps someday +-- can be merged back into it. For now, however, their results are different +-- between regular and CLOBBER_CACHE_ALWAYS builds, so we must have two +-- expected-output files to cover both cases. To minimize the maintenance +-- effort resulting from that, this file should contain only tests that +-- do have different results under CLOBBER_CACHE_ALWAYS. +-- + +-- check behavior with changes of a named rowtype +create table c_mutable(f1 int, f2 text); + +create function c_sillyaddone(int) returns int language plpgsql as +$$ declare r c_mutable; begin r.f1 := $1; return r.f1 + 1; end $$; +select c_sillyaddone(42); + +alter table c_mutable drop column f1; +alter table c_mutable add column f1 float8; + +-- currently, this fails due to cached plan for "r.f1 + 1" expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select c_sillyaddone(42); + +-- but it's OK if we force plan rebuilding +discard plans; +select c_sillyaddone(42); + +-- check behavior with changes in a record rowtype +create function show_result_type(text) returns text language plpgsql as +$$ + declare + r record; + t text; + begin + execute $1 into r; + select pg_typeof(r.a) into t; + return format('type %s value %s', t, r.a::text); + end; +$$; + +select show_result_type('select 1 as a'); +-- currently this fails due to cached plan for pg_typeof expression +-- (but a CLOBBER_CACHE_ALWAYS build will succeed) +select show_result_type('select 2.0 as a'); + +-- but it's OK if we force plan rebuilding +discard plans; +select show_result_type('select 2.0 as a'); diff --git a/src/pl/plpgsql/src/sql/plpgsql_call.sql b/src/pl/plpgsql/src/sql/plpgsql_call.sql index 551bb77c703..4702bd14d12 100644 --- a/src/pl/plpgsql/src/sql/plpgsql_call.sql +++ b/src/pl/plpgsql/src/sql/plpgsql_call.sql @@ -142,6 +142,101 @@ $$; CALL test_proc7(100, -1, -1); +-- named parameters and defaults + +CREATE PROCEDURE test_proc8a(INOUT a int, INOUT b int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %', a, b; + a := a * 10; + b := b + 10; +END; +$$; + +CALL test_proc8a(10, 20); +CALL test_proc8a(b => 20, a => 10); + +DO $$ +DECLARE _a int; _b int; +BEGIN + _a := 10; _b := 30; + CALL test_proc8a(_a, _b); + RAISE NOTICE '_a: %, _b: %', _a, _b; + CALL test_proc8a(b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %', _a, _b; +END +$$; + + +CREATE PROCEDURE test_proc8b(INOUT a int, INOUT b int, INOUT c int) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$; + +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8b(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + CALL test_proc8b(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; + + +CREATE PROCEDURE test_proc8c(INOUT a int, INOUT b int, INOUT c int DEFAULT 11) +LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'a: %, b: %, c: %', a, b, c; + a := a * 10; + b := b + 10; + c := c * -10; +END; +$$; + +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b, _c); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, c => _c, b => _b); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(c => _c, b => _b, a => _a); + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; + +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; + +DO $$ +DECLARE _a int; _b int; _c int; +BEGIN + _a := 10; _b := 30; _c := 50; + CALL test_proc8c(_a, b => _b); -- fail, no output argument for c + RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c; +END +$$; + + -- transition variable assignment TRUNCATE test1; @@ -171,3 +266,52 @@ DROP PROCEDURE test_proc3; DROP PROCEDURE test_proc4; DROP TABLE test1; + + +-- more checks for named-parameter handling + +CREATE PROCEDURE p1(v_cnt int, v_Text inout text = NULL) +AS $$ +BEGIN + v_Text := 'v_cnt = ' || v_cnt; +END +$$ LANGUAGE plpgsql; + +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt); -- error, must supply something for v_Text + RAISE NOTICE '%', v_Text; +END; +$$; + +DO $$ +DECLARE + v_Text text; + v_cnt integer := 42; +BEGIN + CALL p1(v_cnt := v_cnt, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$; + +DO $$ +DECLARE + v_Text text; +BEGIN + CALL p1(10, v_Text := v_Text); + RAISE NOTICE '%', v_Text; +END; +$$; + +DO $$ +DECLARE + v_Text text; + v_cnt integer; +BEGIN + CALL p1(v_Text := v_Text, v_cnt := v_cnt); + RAISE NOTICE '%', v_Text; +END; +$$; diff --git a/src/pl/plpgsql/src/sql/plpgsql_record.sql b/src/pl/plpgsql/src/sql/plpgsql_record.sql index 781ccb0ccb5..e93aeac5b9a 100644 --- a/src/pl/plpgsql/src/sql/plpgsql_record.sql +++ b/src/pl/plpgsql/src/sql/plpgsql_record.sql @@ -270,14 +270,8 @@ create function sillyaddone(int) returns int language plpgsql as $$ declare r mutable; begin r.f1 := $1; return r.f1 + 1; end $$; select sillyaddone(42); -alter table mutable drop column f1; -alter table mutable add column f1 float8; - --- currently, this fails due to cached plan for "r.f1 + 1" expression --- select sillyaddone(42); -\c - --- but it's OK after a reconnect -select sillyaddone(42); +-- test for change of type of column f1 should be here someday; +-- for now see plpgsql_cache test alter table mutable drop column f1; select sillyaddone(42); -- fail @@ -294,6 +288,22 @@ alter table mutable drop column f3; select getf3(null::mutable); -- fails again \set SHOW_CONTEXT errors +-- check behavior with creating/dropping a named rowtype +set check_function_bodies = off; -- else reference to nonexistent type fails + +create function sillyaddtwo(int) returns int language plpgsql as +$$ declare r mutable2; begin r.f1 := $1; return r.f1 + 2; end $$; + +reset check_function_bodies; + +select sillyaddtwo(42); -- fail +create table mutable2(f1 int, f2 text); +select sillyaddtwo(42); +drop table mutable2; +select sillyaddtwo(42); -- fail +create table mutable2(f0 text, f1 int, f2 text); +select sillyaddtwo(42); + -- check access to system columns in a record variable create function sillytrig() returns trigger language plpgsql as @@ -447,3 +457,13 @@ begin d.f2 := r.b; end loop; end$$; + +-- check coercion of a record result to named-composite function output type +create function compresult(int8) returns two_int8s language plpgsql as +$$ declare r record; begin r := row($1,$1); return r; end $$; + +create table two_int8s_tab (f1 two_int8s); +insert into two_int8s_tab values (compresult(42)); +-- reconnect so we lose any local knowledge of anonymous record types +\c - +table two_int8s_tab; diff --git a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql index 373d89864a2..7575655c1ae 100644 --- a/src/pl/plpgsql/src/sql/plpgsql_transaction.sql +++ b/src/pl/plpgsql/src/sql/plpgsql_transaction.sql @@ -116,6 +116,19 @@ $$; CALL transaction_test5(); +-- SECURITY DEFINER currently disallow transaction statements +CREATE PROCEDURE transaction_test5b() +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + COMMIT; +END; +$$; + +CALL transaction_test5b(); + + TRUNCATE test1; -- nested procedure calls @@ -316,6 +329,44 @@ $$; SELECT * FROM test3; +-- failure while trying to persist a cursor across a transaction (bug #15703) +CREATE PROCEDURE cursor_fail_during_commit() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + COMMIT; + END LOOP; + END; +$$; + +TRUNCATE test1; + +CALL cursor_fail_during_commit(); + +-- note that error occurs during first COMMIT, hence nothing is in test1 +SELECT count(*) FROM test1; + +CREATE PROCEDURE cursor_fail_during_rollback() + LANGUAGE plpgsql +AS $$ + DECLARE id int; + BEGIN + FOR id IN SELECT 1/(x-1000) FROM generate_series(1,1000) x LOOP + INSERT INTO test1 VALUES(id); + ROLLBACK; + END LOOP; + END; +$$; + +TRUNCATE test1; + +CALL cursor_fail_during_rollback(); + +SELECT count(*) FROM test1; + -- SET TRANSACTION DO LANGUAGE plpgsql $$ @@ -335,13 +386,126 @@ BEGIN END; $$; --- error case +-- error cases DO LANGUAGE plpgsql $$ BEGIN SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; END; $$; +DO LANGUAGE plpgsql $$ +BEGIN + SAVEPOINT foo; +END; +$$; + +DO LANGUAGE plpgsql $$ +BEGIN + EXECUTE 'COMMIT'; +END; +$$; + + +-- snapshot handling test +TRUNCATE test2; + +CREATE PROCEDURE transaction_test9() +LANGUAGE SQL +AS $$ +INSERT INTO test2 VALUES (42); +$$; + +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + CALL transaction_test9(); +END +$$; + +SELECT * FROM test2; + + +-- Test transaction in procedure with output parameters. This uses a +-- different portal strategy and different code paths in pquery.c. +CREATE PROCEDURE transaction_test10a(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x + 1; + COMMIT; +END; +$$; + +CALL transaction_test10a(10); + +CREATE PROCEDURE transaction_test10b(INOUT x int) +LANGUAGE plpgsql +AS $$ +BEGIN + x := x - 1; + ROLLBACK; +END; +$$; + +CALL transaction_test10b(10); + + +-- transaction timestamp vs. statement timestamp +CREATE PROCEDURE transaction_test11() +LANGUAGE plpgsql +AS $$ +DECLARE + s1 timestamp with time zone; + s2 timestamp with time zone; + s3 timestamp with time zone; + t1 timestamp with time zone; + t2 timestamp with time zone; + t3 timestamp with time zone; +BEGIN + s1 := statement_timestamp(); + t1 := transaction_timestamp(); + ASSERT s1 = t1; + PERFORM pg_sleep(0.001); + COMMIT; + s2 := statement_timestamp(); + t2 := transaction_timestamp(); + ASSERT s2 = s1; + ASSERT t2 > t1; + PERFORM pg_sleep(0.001); + ROLLBACK; + s3 := statement_timestamp(); + t3 := transaction_timestamp(); + ASSERT s3 = s1; + ASSERT t3 > t2; +END; +$$; + +CALL transaction_test11(); + + +-- transaction chain + +TRUNCATE test1; + +DO LANGUAGE plpgsql $$ +BEGIN + ROLLBACK; + SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; + FOR i IN 0..3 LOOP + RAISE INFO 'transaction_isolation = %', current_setting('transaction_isolation'); + INSERT INTO test1 (a) VALUES (i); + IF i % 2 = 0 THEN + COMMIT AND CHAIN; + ELSE + ROLLBACK AND CHAIN; + END IF; + END LOOP; +END +$$; + +SELECT * FROM test1; + + DROP TABLE test1; DROP TABLE test2; DROP TABLE test3; diff --git a/src/pl/plpgsql/src/sql/plpgsql_trap.sql b/src/pl/plpgsql/src/sql/plpgsql_trap.sql new file mode 100644 index 00000000000..c6c1ad894b5 --- /dev/null +++ b/src/pl/plpgsql/src/sql/plpgsql_trap.sql @@ -0,0 +1,175 @@ +-- +-- Test error trapping +-- + +create function trap_zero_divide(int) returns int as $$ +declare x int; + sx smallint; +begin + begin -- start a subtransaction + raise notice 'should see this'; + x := 100 / $1; + raise notice 'should see this only if % <> 0', $1; + sx := $1; + raise notice 'should see this only if % fits in smallint', $1; + if $1 < 0 then + raise exception '% is less than zero', $1; + end if; + exception + when division_by_zero then + raise notice 'caught division_by_zero'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE then + raise notice 'caught numeric_value_out_of_range'; + x := -2; + end; + return x; +end$$ language plpgsql; + +select trap_zero_divide(50); +select trap_zero_divide(0); +select trap_zero_divide(100000); +select trap_zero_divide(-100); + +create table match_source as + select x as id, x*10 as data, x/10 as ten from generate_series(1,100) x; + +create function trap_matching_test(int) returns int as $$ +declare x int; + sx smallint; + y int; +begin + begin -- start a subtransaction + x := 100 / $1; + sx := $1; + select into y data from match_source where id = + (select id from match_source b where ten = $1); + exception + when data_exception then -- category match + raise notice 'caught data_exception'; + x := -1; + when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then + raise notice 'caught numeric_value_out_of_range or cardinality_violation'; + x := -2; + end; + return x; +end$$ language plpgsql; + +select trap_matching_test(50); +select trap_matching_test(0); +select trap_matching_test(100000); +select trap_matching_test(1); + +create temp table foo (f1 int); + +create function subxact_rollback_semantics() returns int as $$ +declare x int; +begin + x := 1; + insert into foo values(x); + begin + x := x + 1; + insert into foo values(x); + raise exception 'inner'; + exception + when others then + x := x * 10; + end; + insert into foo values(x); + return x; +end$$ language plpgsql; + +select subxact_rollback_semantics(); +select * from foo; +drop table foo; + +create function trap_timeout() returns void as $$ +begin + declare x int; + begin + -- we assume this will take longer than 1 second: + select count(*) into x from generate_series(1, 1000000000000); + exception + when others then + raise notice 'caught others?'; + when query_canceled then + raise notice 'nyeah nyeah, can''t stop me'; + end; + -- Abort transaction to abandon the statement_timeout setting. Otherwise, + -- the next top-level statement would be vulnerable to the timeout. + raise exception 'end of function'; +end$$ language plpgsql; + +begin; +set statement_timeout to 1000; +select trap_timeout(); +rollback; + +-- Test for pass-by-ref values being stored in proper context +create function test_variable_storage() returns text as $$ +declare x text; +begin + x := '1234'; + begin + x := x || '5678'; + -- force error inside subtransaction SPI context + perform trap_zero_divide(-100); + exception + when others then + x := x || '9012'; + end; + return x; +end$$ language plpgsql; + +select test_variable_storage(); + +-- +-- test foreign key error trapping +-- + +create temp table root(f1 int primary key); + +create temp table leaf(f1 int references root deferrable); + +insert into root values(1); +insert into leaf values(1); +insert into leaf values(2); -- fails + +create function trap_foreign_key(int) returns int as $$ +begin + begin -- start a subtransaction + insert into leaf values($1); + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql; + +create function trap_foreign_key_2() returns int as $$ +begin + begin -- start a subtransaction + set constraints all immediate; + exception + when foreign_key_violation then + raise notice 'caught foreign_key_violation'; + return 0; + end; + return 1; +end$$ language plpgsql; + +select trap_foreign_key(1); +select trap_foreign_key(2); -- detects FK violation + +begin; + set constraints all deferred; + select trap_foreign_key(2); -- should not detect FK violation + savepoint x; + set constraints all immediate; -- fails + rollback to x; + select trap_foreign_key_2(); -- detects FK violation +commit; -- still fails + +drop function trap_foreign_key(int); +drop function trap_foreign_key_2(); diff --git a/src/pl/plpgsql/src/sql/plpgsql_trigger.sql b/src/pl/plpgsql/src/sql/plpgsql_trigger.sql new file mode 100644 index 00000000000..e04c273c51a --- /dev/null +++ b/src/pl/plpgsql/src/sql/plpgsql_trigger.sql @@ -0,0 +1,24 @@ +-- Simple test to verify accessibility of the OLD and NEW trigger variables + +create table testtr (a int, b text); + +create function testtr_trigger() returns trigger language plpgsql as +$$begin + raise notice 'tg_op = %', tg_op; + raise notice 'old(%) = %', old.a, row(old.*); + raise notice 'new(%) = %', new.a, row(new.*); + if (tg_op = 'DELETE') then + return old; + else + return new; + end if; +end$$; + +create trigger testtr_trigger before insert or delete or update on testtr + for each row execute function testtr_trigger(); + +insert into testtr values (1, 'one'), (2, 'two'); + +update testtr set a = a + 1; + +delete from testtr; diff --git a/src/pl/plpython/Makefile b/src/pl/plpython/Makefile index fb785496ea5..667a74469ec 100644 --- a/src/pl/plpython/Makefile +++ b/src/pl/plpython/Makefile @@ -39,6 +39,21 @@ ifeq ($(python_majorversion),2) DATA += plpythonu.control plpythonu--1.0.sql plpythonu--unpackaged--1.0.sql endif +# header files to install - it's not clear which of these might be needed +# so install them all. +INCS = plpython.h \ + plpy_cursorobject.h \ + plpy_elog.h \ + plpy_exec.h \ + plpy_main.h \ + plpy_planobject.h \ + plpy_plpymodule.h \ + plpy_procedure.h \ + plpy_resultobject.h \ + plpy_spi.h \ + plpy_subxactobject.h \ + plpy_typeio.h \ + plpy_util.h # Python on win32 ships with import libraries only for Microsoft Visual C++, # which are not compatible with mingw gcc. Therefore we need to build a @@ -99,16 +114,20 @@ include $(top_srcdir)/src/Makefile.shlib all: all-lib +# Ensure parallel safety if a build is started in this directory +$(OBJS): | submake-generated-headers + install: all install-lib install-data installdirs: installdirs-lib - $(MKDIR_P) '$(DESTDIR)$(datadir)/extension' '$(DESTDIR)$(includedir_server)' + $(MKDIR_P) '$(DESTDIR)$(datadir)/extension' '$(DESTDIR)$(includedir_server)' '$(DESTDIR)$(pgxsdir)/src/pl/plpython' uninstall: uninstall-lib uninstall-data install-data: installdirs $(INSTALL_DATA) $(addprefix $(srcdir)/, $(DATA)) '$(DESTDIR)$(datadir)/extension/' - $(INSTALL_DATA) $(srcdir)/plpython.h $(srcdir)/plpy_util.h '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) $(addprefix $(srcdir)/, $(INCS)) '$(DESTDIR)$(includedir_server)' + $(INSTALL_DATA) $(srcdir)/regress-python3-mangle.mk '$(DESTDIR)$(pgxsdir)/src/pl/plpython' uninstall-data: rm -f $(addprefix '$(DESTDIR)$(datadir)/extension'/, $(notdir $(DATA))) @@ -128,7 +147,7 @@ installcheck: submake-pg-regress .PHONY: submake-pg-regress -submake-pg-regress: +submake-pg-regress: | submake-generated-headers $(MAKE) -C $(top_builddir)/src/test/regress pg_regress$(X) clean distclean: clean-lib diff --git a/src/pl/plpython/expected/plpython_subtransaction.out b/src/pl/plpython/expected/plpython_subtransaction.out index da3b312a06b..069f0992abd 100644 --- a/src/pl/plpython/expected/plpython_subtransaction.out +++ b/src/pl/plpython/expected/plpython_subtransaction.out @@ -43,7 +43,7 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT subtransaction_test('SPI'); -ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for integer: "oops" +ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops" LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops') ^ QUERY: INSERT INTO subtransaction_tbl VALUES ('oops') @@ -95,7 +95,7 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT subtransaction_ctx_test('SPI'); -ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for integer: "oops" +ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops" LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops') ^ QUERY: INSERT INTO subtransaction_tbl VALUES ('oops') @@ -134,7 +134,7 @@ with plpy.subtransaction(): except plpy.SPIError, e: if not swallow: raise - plpy.notice("Swallowed %r" % e) + plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0])) return "ok" $$ LANGUAGE plpythonu; SELECT subtransaction_nested_test(); @@ -153,7 +153,7 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT subtransaction_nested_test('t'); -NOTICE: Swallowed SyntaxError('syntax error at or near "error"',) +NOTICE: Swallowed SyntaxError('syntax error at or near "error"') subtransaction_nested_test ---------------------------- ok @@ -178,7 +178,7 @@ with plpy.subtransaction(): return "ok" $$ LANGUAGE plpythonu; SELECT subtransaction_deeply_nested_test(); -NOTICE: Swallowed SyntaxError('syntax error at or near "error"',) +NOTICE: Swallowed SyntaxError('syntax error at or near "error"') subtransaction_deeply_nested_test ----------------------------------- ok diff --git a/src/pl/plpython/expected/plpython_subtransaction_0.out b/src/pl/plpython/expected/plpython_subtransaction_0.out index e6cc38a0338..97ee42b5a9a 100644 --- a/src/pl/plpython/expected/plpython_subtransaction_0.out +++ b/src/pl/plpython/expected/plpython_subtransaction_0.out @@ -43,7 +43,7 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT subtransaction_test('SPI'); -ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for integer: "oops" +ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops" LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops') ^ QUERY: INSERT INTO subtransaction_tbl VALUES ('oops') @@ -128,7 +128,7 @@ with plpy.subtransaction(): except plpy.SPIError, e: if not swallow: raise - plpy.notice("Swallowed %r" % e) + plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0])) return "ok" $$ LANGUAGE plpythonu; ERROR: could not compile PL/Python function "subtransaction_nested_test" diff --git a/src/pl/plpython/expected/plpython_subtransaction_5.out b/src/pl/plpython/expected/plpython_subtransaction_5.out index 6fbafa31661..e172e98f86a 100644 --- a/src/pl/plpython/expected/plpython_subtransaction_5.out +++ b/src/pl/plpython/expected/plpython_subtransaction_5.out @@ -43,7 +43,7 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT subtransaction_test('SPI'); -ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for integer: "oops" +ERROR: spiexceptions.InvalidTextRepresentation: invalid input syntax for type integer: "oops" LINE 1: INSERT INTO subtransaction_tbl VALUES ('oops') ^ QUERY: INSERT INTO subtransaction_tbl VALUES ('oops') @@ -128,7 +128,7 @@ with plpy.subtransaction(): except plpy.SPIError, e: if not swallow: raise - plpy.notice("Swallowed %r" % e) + plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0])) return "ok" $$ LANGUAGE plpythonu; ERROR: could not compile PL/Python function "subtransaction_nested_test" diff --git a/src/pl/plpython/expected/plpython_trigger.out b/src/pl/plpython/expected/plpython_trigger.out index d7ab8ac6b8e..742988a5b59 100644 --- a/src/pl/plpython/expected/plpython_trigger.out +++ b/src/pl/plpython/expected/plpython_trigger.out @@ -67,6 +67,10 @@ SELECT * FROM users; -- dump trigger data CREATE TABLE trigger_test (i int, v text ); +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpythonu AS $$ if 'relid' in TD: @@ -203,6 +207,77 @@ NOTICE: TD[when] => BEFORE DROP TRIGGER show_trigger_data_trig_stmt on trigger_test; DROP TRIGGER show_trigger_data_trig_before on trigger_test; DROP TRIGGER show_trigger_data_trig_after on trigger_test; +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +insert into trigger_test_generated (i) values (1); +NOTICE: TD[args] => None +NOTICE: TD[event] => INSERT +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_before +NOTICE: TD[new] => {'i': 1} +NOTICE: TD[old] => None +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => BEFORE +NOTICE: TD[args] => None +NOTICE: TD[event] => INSERT +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_after +NOTICE: TD[new] => {'i': 1, 'j': 2} +NOTICE: TD[old] => None +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => AFTER +update trigger_test_generated set i = 11 where i = 1; +NOTICE: TD[args] => None +NOTICE: TD[event] => UPDATE +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_before +NOTICE: TD[new] => {'i': 11} +NOTICE: TD[old] => {'i': 1, 'j': 2} +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => BEFORE +NOTICE: TD[args] => None +NOTICE: TD[event] => UPDATE +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_after +NOTICE: TD[new] => {'i': 11, 'j': 22} +NOTICE: TD[old] => {'i': 1, 'j': 2} +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => AFTER +delete from trigger_test_generated; +NOTICE: TD[args] => None +NOTICE: TD[event] => DELETE +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_before +NOTICE: TD[new] => None +NOTICE: TD[old] => {'i': 11, 'j': 22} +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => BEFORE +NOTICE: TD[args] => None +NOTICE: TD[event] => DELETE +NOTICE: TD[level] => ROW +NOTICE: TD[name] => show_trigger_data_trig_after +NOTICE: TD[new] => None +NOTICE: TD[old] => {'i': 11, 'j': 22} +NOTICE: TD[relid] => bogus:12345 +NOTICE: TD[table_name] => trigger_test_generated +NOTICE: TD[table_schema] => public +NOTICE: TD[when] => AFTER +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; insert into trigger_test values(1,'insert'); CREATE VIEW trigger_test_view AS SELECT * FROM trigger_test; CREATE TRIGGER show_trigger_data_trig @@ -524,3 +599,22 @@ INFO: old: 1 -> a INFO: new: 1 -> b DROP TABLE transition_table_test; DROP FUNCTION transition_table_test_f(); +-- dealing with generated columns +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE plpythonu +AS $$ +TD['new']['j'] = 5 # not allowed +return 'MODIFY' +$$; +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +ERROR: cannot set generated column "j" +CONTEXT: while modifying trigger row +PL/Python function "generated_test_func1" +SELECT * FROM trigger_test_generated; + i | j +---+--- +(0 rows) + diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out index eda965a9e0d..98b89b7d5c1 100644 --- a/src/pl/plpython/expected/plpython_types.out +++ b/src/pl/plpython/expected/plpython_types.out @@ -684,7 +684,7 @@ CREATE FUNCTION test_type_conversion_array_mixed2() RETURNS int[] AS $$ return [123, 'abc'] $$ LANGUAGE plpythonu; SELECT * FROM test_type_conversion_array_mixed2(); -ERROR: invalid input syntax for integer: "abc" +ERROR: invalid input syntax for type integer: "abc" CONTEXT: while creating return value PL/Python function "test_type_conversion_array_mixed2" CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$ diff --git a/src/pl/plpython/expected/plpython_types_3.out b/src/pl/plpython/expected/plpython_types_3.out index 69f958cbf28..a6ec10d5e18 100644 --- a/src/pl/plpython/expected/plpython_types_3.out +++ b/src/pl/plpython/expected/plpython_types_3.out @@ -684,7 +684,7 @@ CREATE FUNCTION test_type_conversion_array_mixed2() RETURNS int[] AS $$ return [123, 'abc'] $$ LANGUAGE plpython3u; SELECT * FROM test_type_conversion_array_mixed2(); -ERROR: invalid input syntax for integer: "abc" +ERROR: invalid input syntax for type integer: "abc" CONTEXT: while creating return value PL/Python function "test_type_conversion_array_mixed2" CREATE FUNCTION test_type_conversion_mdarray_malformed() RETURNS int[] AS $$ diff --git a/src/pl/plpython/generate-spiexceptions.pl b/src/pl/plpython/generate-spiexceptions.pl index 73ca50e875a..092a801a03b 100644 --- a/src/pl/plpython/generate-spiexceptions.pl +++ b/src/pl/plpython/generate-spiexceptions.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate the spiexceptions.h header from errcodes.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; diff --git a/src/pl/plpython/nls.mk b/src/pl/plpython/nls.mk index 6c7359c1a2e..b3e10d035cf 100644 --- a/src/pl/plpython/nls.mk +++ b/src/pl/plpython/nls.mk @@ -1,6 +1,6 @@ # src/pl/plpython/nls.mk CATALOG_NAME = plpython -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv zh_CN +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ru sv tr vi zh_CN GETTEXT_FILES = plpy_cursorobject.c plpy_elog.c plpy_exec.c plpy_main.c plpy_planobject.c plpy_plpymodule.c \ plpy_procedure.c plpy_resultobject.c plpy_spi.c plpy_subxactobject.c plpy_typeio.c plpy_util.c GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) PLy_elog:2 PLy_exception_set:2 PLy_exception_set_plural:2,3 diff --git a/src/pl/plpython/plpy_cursorobject.c b/src/pl/plpython/plpy_cursorobject.c index e32bc568bc2..e4d543a4d46 100644 --- a/src/pl/plpython/plpy_cursorobject.c +++ b/src/pl/plpython/plpy_cursorobject.c @@ -43,37 +43,14 @@ static PyMethodDef PLy_cursor_methods[] = { static PyTypeObject PLy_CursorType = { PyVarObject_HEAD_INIT(NULL, 0) - "PLyCursor", /* tp_name */ - sizeof(PLyCursorObject), /* tp_size */ - 0, /* tp_itemsize */ - - /* - * methods - */ - PLy_cursor_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ - PLy_cursor_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - PLy_cursor_iternext, /* tp_iternext */ - PLy_cursor_methods, /* tp_tpmethods */ + .tp_name = "PLyCursor", + .tp_basicsize = sizeof(PLyCursorObject), + .tp_dealloc = PLy_cursor_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER, + .tp_doc = PLy_cursor_doc, + .tp_iter = PyObject_SelfIter, + .tp_iternext = PLy_cursor_iternext, + .tp_methods = PLy_cursor_methods, }; void @@ -380,7 +357,7 @@ PLy_cursor_iternext(PyObject *self) exec_ctx->curr_proc); ret = PLy_input_from_tuple(&cursor->result, SPI_tuptable->vals[0], - SPI_tuptable->tupdesc); + SPI_tuptable->tupdesc, true); } SPI_freetuptable(SPI_tuptable); @@ -476,7 +453,8 @@ PLy_cursor_fetch(PyObject *self, PyObject *args) { PyObject *row = PLy_input_from_tuple(&cursor->result, SPI_tuptable->vals[i], - SPI_tuptable->tupdesc); + SPI_tuptable->tupdesc, + true); PyList_SetItem(ret->rows, i, row); } diff --git a/src/pl/plpython/plpy_elog.c b/src/pl/plpython/plpy_elog.c index e244104fed7..25930f99d78 100644 --- a/src/pl/plpython/plpy_elog.c +++ b/src/pl/plpython/plpy_elog.c @@ -22,14 +22,14 @@ PyObject *PLy_exc_spi_error = NULL; static void PLy_traceback(PyObject *e, PyObject *v, PyObject *tb, - char **xmsg, char **tbmsg, int *tb_depth); + char **xmsg, char **tbmsg, int *tb_depth); static void PLy_get_spi_error_data(PyObject *exc, int *sqlerrcode, char **detail, - char **hint, char **query, int *position, - char **schema_name, char **table_name, char **column_name, - char **datatype_name, char **constraint_name); + char **hint, char **query, int *position, + char **schema_name, char **table_name, char **column_name, + char **datatype_name, char **constraint_name); static void PLy_get_error_data(PyObject *exc, int *sqlerrcode, char **detail, - char **hint, char **schema_name, char **table_name, char **column_name, - char **datatype_name, char **constraint_name); + char **hint, char **schema_name, char **table_name, char **column_name, + char **datatype_name, char **constraint_name); static char *get_source_line(const char *src, int lineno); static void get_string_attr(PyObject *obj, char *attrname, char **str); @@ -46,6 +46,7 @@ static bool set_string_attr(PyObject *obj, char *attrname, char *str); void PLy_elog_impl(int elevel, const char *fmt,...) { + int save_errno = errno; char *xmsg; char *tbmsg; int tb_depth; @@ -96,6 +97,7 @@ PLy_elog_impl(int elevel, const char *fmt,...) va_list ap; int needed; + errno = save_errno; va_start(ap, fmt); needed = appendStringInfoVA(&emsg, dgettext(TEXTDOMAIN, fmt), ap); va_end(ap); @@ -242,7 +244,7 @@ PLy_traceback(PyObject *e, PyObject *v, PyObject *tb, *tb_depth = 0; initStringInfo(&tbstr); - /* Mimick Python traceback reporting as close as possible. */ + /* Mimic Python traceback reporting as close as possible. */ appendStringInfoString(&tbstr, "Traceback (most recent call last):"); while (tb != NULL && tb != Py_None) { diff --git a/src/pl/plpython/plpy_elog.h b/src/pl/plpython/plpy_elog.h index e4b30c3cca1..e02ef4ffe9f 100644 --- a/src/pl/plpython/plpy_elog.h +++ b/src/pl/plpython/plpy_elog.h @@ -5,6 +5,8 @@ #ifndef PLPY_ELOG_H #define PLPY_ELOG_H +#include "plpython.h" + /* global exception classes */ extern PyObject *PLy_exc_error; extern PyObject *PLy_exc_fatal; @@ -15,7 +17,6 @@ extern PyObject *PLy_exc_spi_error; * * See comments at elog() about the compiler hinting. */ -#ifdef HAVE__VA_ARGS #ifdef HAVE__BUILTIN_CONSTANT_P #define PLy_elog(elevel, ...) \ do { \ @@ -32,16 +33,13 @@ extern PyObject *PLy_exc_spi_error; pg_unreachable(); \ } while(0) #endif /* HAVE__BUILTIN_CONSTANT_P */ -#else /* !HAVE__VA_ARGS */ -#define PLy_elog PLy_elog_impl -#endif /* HAVE__VA_ARGS */ extern void PLy_elog_impl(int elevel, const char *fmt,...) pg_attribute_printf(2, 3); extern void PLy_exception_set(PyObject *exc, const char *fmt,...) pg_attribute_printf(2, 3); extern void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(2, 5) pg_attribute_printf(3, 5); + unsigned long n,...) pg_attribute_printf(2, 5) pg_attribute_printf(3, 5); extern void PLy_exception_set_with_details(PyObject *excclass, ErrorData *edata); diff --git a/src/pl/plpython/plpy_exec.c b/src/pl/plpython/plpy_exec.c index 7c8c7dee87c..920322e912b 100644 --- a/src/pl/plpython/plpy_exec.c +++ b/src/pl/plpython/plpy_exec.c @@ -13,6 +13,7 @@ #include "executor/spi.h" #include "funcapi.h" #include "utils/builtins.h" +#include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/typcache.h" @@ -44,9 +45,9 @@ static void plpython_srf_cleanup_callback(void *arg); static void plpython_return_error_callback(void *arg); static PyObject *PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, - HeapTuple *rv); + HeapTuple *rv); static HeapTuple PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, - TriggerData *tdata, HeapTuple otup); + TriggerData *tdata, HeapTuple otup); static void plpython_trigger_error_callback(void *arg); static PyObject *PLy_procedure_call(PLyProcedure *proc, const char *kargs, PyObject *vargs); @@ -199,10 +200,10 @@ PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc) error_context_stack = &plerrcontext; /* - * For a procedure or function declared to return void, the Python return value - * must be None. For void-returning functions, we also treat a None - * return value as a special "void datum" rather than NULL (as is the - * case for non-void-returning functions). + * For a procedure or function declared to return void, the Python + * return value must be None. For void-returning functions, we also + * treat a None return value as a special "void datum" rather than + * NULL (as is the case for non-void-returning functions). */ if (proc->result.typoid == VOIDOID) { @@ -436,10 +437,10 @@ PLy_function_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc) { PLyDatumToOb *arginfo = &proc->args[i]; - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) arg = NULL; else - arg = PLy_input_convert(arginfo, fcinfo->arg[i]); + arg = PLy_input_convert(arginfo, fcinfo->args[i].value); if (arg == NULL) { @@ -751,6 +752,11 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r PyDict_SetItemString(pltdata, "level", pltlevel); Py_DECREF(pltlevel); + /* + * Note: In BEFORE trigger, stored generated columns are not + * computed yet, so don't make them accessible in NEW row. + */ + if (TRIGGER_FIRED_BY_INSERT(tdata->tg_event)) { pltevent = PyString_FromString("INSERT"); @@ -758,7 +764,8 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r PyDict_SetItemString(pltdata, "old", Py_None); pytnew = PLy_input_from_tuple(&proc->result_in, tdata->tg_trigtuple, - rel_descr); + rel_descr, + !TRIGGER_FIRED_BEFORE(tdata->tg_event)); PyDict_SetItemString(pltdata, "new", pytnew); Py_DECREF(pytnew); *rv = tdata->tg_trigtuple; @@ -770,7 +777,8 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r PyDict_SetItemString(pltdata, "new", Py_None); pytold = PLy_input_from_tuple(&proc->result_in, tdata->tg_trigtuple, - rel_descr); + rel_descr, + true); PyDict_SetItemString(pltdata, "old", pytold); Py_DECREF(pytold); *rv = tdata->tg_trigtuple; @@ -781,12 +789,14 @@ PLy_trigger_build_args(FunctionCallInfo fcinfo, PLyProcedure *proc, HeapTuple *r pytnew = PLy_input_from_tuple(&proc->result_in, tdata->tg_newtuple, - rel_descr); + rel_descr, + !TRIGGER_FIRED_BEFORE(tdata->tg_event)); PyDict_SetItemString(pltdata, "new", pytnew); Py_DECREF(pytnew); pytold = PLy_input_from_tuple(&proc->result_in, tdata->tg_trigtuple, - rel_descr); + rel_descr, + true); PyDict_SetItemString(pltdata, "old", pytold); Py_DECREF(pytold); *rv = tdata->tg_newtuple; @@ -952,6 +962,11 @@ PLy_modify_tuple(PLyProcedure *proc, PyObject *pltd, TriggerData *tdata, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot set system attribute \"%s\"", plattstr))); + if (TupleDescAttr(tupdesc, attn - 1)->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), + errmsg("cannot set generated column \"%s\"", + plattstr))); plval = PyDict_GetItem(plntup, platt); if (plval == NULL) diff --git a/src/pl/plpython/plpy_main.c b/src/pl/plpython/plpy_main.c index 6a66eba1762..6edfcf207e5 100644 --- a/src/pl/plpython/plpy_main.c +++ b/src/pl/plpython/plpy_main.c @@ -299,8 +299,8 @@ plpython2_call_handler(PG_FUNCTION_ARGS) Datum plpython_inline_handler(PG_FUNCTION_ARGS) { + LOCAL_FCINFO(fake_fcinfo, 0); InlineCodeBlock *codeblock = (InlineCodeBlock *) DatumGetPointer(PG_GETARG_DATUM(0)); - FunctionCallInfoData fake_fcinfo; FmgrInfo flinfo; PLyProcedure proc; PLyExecutionContext *exec_ctx; @@ -312,9 +312,9 @@ plpython_inline_handler(PG_FUNCTION_ARGS) if (SPI_connect_ext(codeblock->atomic ? 0 : SPI_OPT_NONATOMIC) != SPI_OK_CONNECT) elog(ERROR, "SPI_connect failed"); - MemSet(&fake_fcinfo, 0, sizeof(fake_fcinfo)); + MemSet(fcinfo, 0, SizeForFunctionCallInfo(0)); MemSet(&flinfo, 0, sizeof(flinfo)); - fake_fcinfo.flinfo = &flinfo; + fake_fcinfo->flinfo = &flinfo; flinfo.fn_oid = InvalidOid; flinfo.fn_mcxt = CurrentMemoryContext; @@ -352,7 +352,7 @@ plpython_inline_handler(PG_FUNCTION_ARGS) PLy_procedure_compile(&proc, codeblock->source_text); exec_ctx->curr_proc = &proc; - PLy_exec_function(&fake_fcinfo, &proc); + PLy_exec_function(fake_fcinfo, &proc); } PG_CATCH(); { diff --git a/src/pl/plpython/plpy_planobject.c b/src/pl/plpython/plpy_planobject.c index 390b4e90d45..96ea24cbcf5 100644 --- a/src/pl/plpython/plpy_planobject.c +++ b/src/pl/plpython/plpy_planobject.c @@ -34,37 +34,12 @@ static PyMethodDef PLy_plan_methods[] = { static PyTypeObject PLy_PlanType = { PyVarObject_HEAD_INIT(NULL, 0) - "PLyPlan", /* tp_name */ - sizeof(PLyPlanObject), /* tp_size */ - 0, /* tp_itemsize */ - - /* - * methods - */ - PLy_plan_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PLy_plan_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PLy_plan_methods, /* tp_tpmethods */ + .tp_name = "PLyPlan", + .tp_basicsize = sizeof(PLyPlanObject), + .tp_dealloc = PLy_plan_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = PLy_plan_doc, + .tp_methods = PLy_plan_methods, }; void diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c index c55cd959c29..c80b35040bf 100644 --- a/src/pl/plpython/plpy_plpymodule.c +++ b/src/pl/plpython/plpy_plpymodule.c @@ -29,8 +29,8 @@ HTAB *PLy_spi_exceptions = NULL; static void PLy_add_exceptions(PyObject *plpy); static PyObject *PLy_create_exception(char *name, - PyObject *base, PyObject *dict, - const char *modname, PyObject *mod); + PyObject *base, PyObject *dict, + const char *modname, PyObject *mod); static void PLy_generate_spi_exceptions(PyObject *mod, PyObject *base); /* module functions */ @@ -115,23 +115,17 @@ static PyMethodDef PLy_exc_methods[] = { #if PY_MAJOR_VERSION >= 3 static PyModuleDef PLy_module = { - PyModuleDef_HEAD_INIT, /* m_base */ - "plpy", /* m_name */ - NULL, /* m_doc */ - -1, /* m_size */ - PLy_methods, /* m_methods */ + PyModuleDef_HEAD_INIT, + .m_name = "plpy", + .m_size = -1, + .m_methods = PLy_methods, }; static PyModuleDef PLy_exc_module = { - PyModuleDef_HEAD_INIT, /* m_base */ - "spiexceptions", /* m_name */ - NULL, /* m_doc */ - -1, /* m_size */ - PLy_exc_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ + PyModuleDef_HEAD_INIT, + .m_name = "spiexceptions", + .m_size = -1, + .m_methods = PLy_exc_methods, }; /* @@ -304,7 +298,7 @@ PLy_generate_spi_exceptions(PyObject *mod, PyObject *base) * don't confuse these with PLy_elog */ static PyObject *PLy_output(volatile int level, PyObject *self, - PyObject *args, PyObject *kw); + PyObject *args, PyObject *kw); static PyObject * PLy_debug(PyObject *self, PyObject *args, PyObject *kw) @@ -594,8 +588,6 @@ PLy_commit(PyObject *self, PyObject *args) { PLyExecutionContext *exec_ctx = PLy_current_execution_context(); - HoldPinnedPortals(); - SPI_commit(); SPI_start_transaction(); @@ -610,8 +602,6 @@ PLy_rollback(PyObject *self, PyObject *args) { PLyExecutionContext *exec_ctx = PLy_current_execution_context(); - HoldPinnedPortals(); - SPI_rollback(); SPI_start_transaction(); diff --git a/src/pl/plpython/plpy_procedure.c b/src/pl/plpython/plpy_procedure.c index 50b07cad820..6e08c03fcdb 100644 --- a/src/pl/plpython/plpy_procedure.c +++ b/src/pl/plpython/plpy_procedure.c @@ -471,7 +471,7 @@ PLy_procedure_munge_source(const char *name, const char *src) *mp = '\0'; if (mp > (mrc + mlen)) - elog(FATAL, "buffer overrun in PLy_munge_source"); + elog(FATAL, "buffer overrun in PLy_procedure_munge_source"); return mrc; } diff --git a/src/pl/plpython/plpy_resultobject.c b/src/pl/plpython/plpy_resultobject.c index ca70e256892..20cf3edea87 100644 --- a/src/pl/plpython/plpy_resultobject.c +++ b/src/pl/plpython/plpy_resultobject.c @@ -20,8 +20,6 @@ static PyObject *PLy_result_nrows(PyObject *self, PyObject *args); static PyObject *PLy_result_status(PyObject *self, PyObject *args); static Py_ssize_t PLy_result_length(PyObject *arg); static PyObject *PLy_result_item(PyObject *arg, Py_ssize_t idx); -static PyObject *PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx); -static int PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice); static PyObject *PLy_result_str(PyObject *arg); static PyObject *PLy_result_subscript(PyObject *arg, PyObject *item); static int PLy_result_ass_subscript(PyObject *self, PyObject *item, PyObject *value); @@ -31,19 +29,14 @@ static char PLy_result_doc[] = { }; static PySequenceMethods PLy_result_as_sequence = { - PLy_result_length, /* sq_length */ - NULL, /* sq_concat */ - NULL, /* sq_repeat */ - PLy_result_item, /* sq_item */ - PLy_result_slice, /* sq_slice */ - NULL, /* sq_ass_item */ - PLy_result_ass_slice, /* sq_ass_slice */ + .sq_length = PLy_result_length, + .sq_item = PLy_result_item, }; static PyMappingMethods PLy_result_as_mapping = { - PLy_result_length, /* mp_length */ - PLy_result_subscript, /* mp_subscript */ - PLy_result_ass_subscript, /* mp_ass_subscript */ + .mp_length = PLy_result_length, + .mp_subscript = PLy_result_subscript, + .mp_ass_subscript = PLy_result_ass_subscript, }; static PyMethodDef PLy_result_methods[] = { @@ -57,37 +50,15 @@ static PyMethodDef PLy_result_methods[] = { static PyTypeObject PLy_ResultType = { PyVarObject_HEAD_INIT(NULL, 0) - "PLyResult", /* tp_name */ - sizeof(PLyResultObject), /* tp_size */ - 0, /* tp_itemsize */ - - /* - * methods - */ - PLy_result_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &PLy_result_as_sequence, /* tp_as_sequence */ - &PLy_result_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - &PLy_result_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PLy_result_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PLy_result_methods, /* tp_tpmethods */ + .tp_name = "PLyResult", + .tp_basicsize = sizeof(PLyResultObject), + .tp_dealloc = PLy_result_dealloc, + .tp_as_sequence = &PLy_result_as_sequence, + .tp_as_mapping = &PLy_result_as_mapping, + .tp_str = &PLy_result_str, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = PLy_result_doc, + .tp_methods = PLy_result_methods, }; void @@ -254,24 +225,6 @@ PLy_result_item(PyObject *arg, Py_ssize_t idx) return rv; } -static PyObject * -PLy_result_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx) -{ - PLyResultObject *ob = (PLyResultObject *) arg; - - return PyList_GetSlice(ob->rows, lidx, hidx); -} - -static int -PLy_result_ass_slice(PyObject *arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject *slice) -{ - int rv; - PLyResultObject *ob = (PLyResultObject *) arg; - - rv = PyList_SetSlice(ob->rows, lidx, hidx, slice); - return rv; -} - static PyObject * PLy_result_str(PyObject *arg) { diff --git a/src/pl/plpython/plpy_resultobject.h b/src/pl/plpython/plpy_resultobject.h index bbaca0dd00f..978c4cc176c 100644 --- a/src/pl/plpython/plpy_resultobject.h +++ b/src/pl/plpython/plpy_resultobject.h @@ -7,6 +7,8 @@ #include "access/tupdesc.h" +#include "plpython.h" + typedef struct PLyResultObject { diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c index 41155fc81ec..2fe435d42b0 100644 --- a/src/pl/plpython/plpy_spi.c +++ b/src/pl/plpython/plpy_spi.c @@ -31,7 +31,7 @@ static PyObject *PLy_spi_execute_query(char *query, long limit); static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *tuptable, - uint64 rows, int status); + uint64 rows, int status); static void PLy_spi_exception_set(PyObject *excclass, ErrorData *edata); @@ -419,7 +419,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status) { PyObject *row = PLy_input_from_tuple(&ininfo, tuptable->vals[i], - tuptable->tupdesc); + tuptable->tupdesc, + true); PyList_SetItem(result->rows, i, row); } diff --git a/src/pl/plpython/plpy_spi.h b/src/pl/plpython/plpy_spi.h index 5a0eef78dcd..ec7b6893597 100644 --- a/src/pl/plpython/plpy_spi.h +++ b/src/pl/plpython/plpy_spi.h @@ -7,6 +7,8 @@ #include "utils/resowner.h" +#include "plpython.h" + extern PyObject *PLy_spi_prepare(PyObject *self, PyObject *args); extern PyObject *PLy_spi_execute(PyObject *self, PyObject *args); extern PyObject *PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit); diff --git a/src/pl/plpython/plpy_subxactobject.c b/src/pl/plpython/plpy_subxactobject.c index 331d2b859c0..5dfb8a4cb54 100644 --- a/src/pl/plpython/plpy_subxactobject.c +++ b/src/pl/plpython/plpy_subxactobject.c @@ -38,37 +38,12 @@ static PyMethodDef PLy_subtransaction_methods[] = { static PyTypeObject PLy_SubtransactionType = { PyVarObject_HEAD_INIT(NULL, 0) - "PLySubtransaction", /* tp_name */ - sizeof(PLySubtransactionObject), /* tp_size */ - 0, /* tp_itemsize */ - - /* - * methods - */ - PLy_subtransaction_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - PLy_subtransaction_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - PLy_subtransaction_methods, /* tp_tpmethods */ + .tp_name = "PLySubtransaction", + .tp_basicsize = sizeof(PLySubtransactionObject), + .tp_dealloc = PLy_subtransaction_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = PLy_subtransaction_doc, + .tp_methods = PLy_subtransaction_methods, }; @@ -157,7 +132,7 @@ PLy_subtransaction_enter(PyObject *self, PyObject *unused) * * Exit an explicit subtransaction. exc_type is an exception type, exc * is the exception object, tb is the traceback. If exc_type is None, - * commit the subtransactiony, if not abort it. + * commit the subtransaction, if not abort it. * * The method signature is chosen to allow subtransaction objects to * be used as context managers as described in diff --git a/src/pl/plpython/plpy_subxactobject.h b/src/pl/plpython/plpy_subxactobject.h index 92a9e635f3a..1ee85c0cdf3 100644 --- a/src/pl/plpython/plpy_subxactobject.h +++ b/src/pl/plpython/plpy_subxactobject.h @@ -8,6 +8,8 @@ #include "nodes/pg_list.h" #include "utils/resowner.h" +#include "plpython.h" + /* a list of nested explicit subtransactions */ extern List *explicit_subtransactions; diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c index d6a6a849c32..371e534fd22 100644 --- a/src/pl/plpython/plpy_typeio.c +++ b/src/pl/plpython/plpy_typeio.c @@ -39,28 +39,28 @@ static PyObject *PLyString_FromScalar(PLyDatumToOb *arg, Datum d); static PyObject *PLyObject_FromTransform(PLyDatumToOb *arg, Datum d); static PyObject *PLyList_FromArray(PLyDatumToOb *arg, Datum d); static PyObject *PLyList_FromArray_recurse(PLyDatumToOb *elm, int *dims, int ndim, int dim, - char **dataptr_p, bits8 **bitmap_p, int *bitmask_p); + char **dataptr_p, bits8 **bitmap_p, int *bitmask_p); static PyObject *PLyDict_FromComposite(PLyDatumToOb *arg, Datum d); -static PyObject *PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc); +static PyObject *PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated); /* conversion from Python objects to Datums */ static Datum PLyObject_ToBool(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLyObject_ToBytea(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLyObject_ToComposite(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLyObject_ToScalar(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLyObject_ToDomain(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLyObject_ToTransform(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static Datum PLySequence_ToArray(PLyObToDatum *arg, PyObject *plrv, - bool *isnull, bool inarray); + bool *isnull, bool inarray); static void PLySequence_ToArray_recurse(PLyObToDatum *elm, PyObject *list, - int *dims, int ndim, int dim, - Datum *elems, bool *nulls, int *currelem); + int *dims, int ndim, int dim, + Datum *elems, bool *nulls, int *currelem); /* conversion from Python objects to composite Datums */ static Datum PLyString_ToComposite(PLyObToDatum *arg, PyObject *string, bool inarray); @@ -134,7 +134,7 @@ PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull) * but in practice all callers have the right tupdesc available. */ PyObject * -PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc) +PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated) { PyObject *dict; PLyExecutionContext *exec_ctx = PLy_current_execution_context(); @@ -148,7 +148,7 @@ PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc) oldcontext = MemoryContextSwitchTo(scratch_context); - dict = PLyDict_FromTuple(arg, tuple, desc); + dict = PLyDict_FromTuple(arg, tuple, desc, include_generated); MemoryContextSwitchTo(oldcontext); @@ -804,7 +804,7 @@ PLyDict_FromComposite(PLyDatumToOb *arg, Datum d) tmptup.t_len = HeapTupleHeaderGetDatumLength(td); tmptup.t_data = td; - dict = PLyDict_FromTuple(arg, &tmptup, tupdesc); + dict = PLyDict_FromTuple(arg, &tmptup, tupdesc, true); ReleaseTupleDesc(tupdesc); @@ -815,7 +815,7 @@ PLyDict_FromComposite(PLyDatumToOb *arg, Datum d) * Transform a tuple into a Python dict object. */ static PyObject * -PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc) +PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated) { PyObject *volatile dict; @@ -842,6 +842,13 @@ PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc) if (attr->attisdropped) continue; + if (attr->attgenerated) + { + /* don't include unless requested */ + if (!include_generated) + continue; + } + key = NameStr(attr->attname); vattr = heap_getattr(tuple, (i + 1), desc, &is_null); diff --git a/src/pl/plpython/plpy_typeio.h b/src/pl/plpython/plpy_typeio.h index 82bdfae5487..3412a9817bf 100644 --- a/src/pl/plpython/plpy_typeio.h +++ b/src/pl/plpython/plpy_typeio.h @@ -9,6 +9,8 @@ #include "fmgr.h" #include "utils/typcache.h" +#include "plpython.h" + struct PLyProcedure; /* avoid requiring plpy_procedure.h here */ @@ -148,25 +150,25 @@ struct PLyObToDatum extern PyObject *PLy_input_convert(PLyDatumToOb *arg, Datum val); extern Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, - bool *isnull); + bool *isnull); extern PyObject *PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, - TupleDesc desc); + TupleDesc desc, bool include_generated); extern void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, - Oid typeOid, int32 typmod, - struct PLyProcedure *proc); + Oid typeOid, int32 typmod, + struct PLyProcedure *proc); extern void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, - Oid typeOid, int32 typmod, - struct PLyProcedure *proc); + Oid typeOid, int32 typmod, + struct PLyProcedure *proc); extern void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, - struct PLyProcedure *proc); + struct PLyProcedure *proc); extern void PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, - struct PLyProcedure *proc); + struct PLyProcedure *proc); extern void PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, - struct PLyProcedure *proc); + struct PLyProcedure *proc); /* conversion from Python objects to C strings --- exported for transforms */ extern char *PLyObject_AsString(PyObject *plrv); diff --git a/src/pl/plpython/plpy_util.h b/src/pl/plpython/plpy_util.h index f990bb08908..c9ba7edc0ec 100644 --- a/src/pl/plpython/plpy_util.h +++ b/src/pl/plpython/plpy_util.h @@ -6,6 +6,8 @@ #ifndef PLPY_UTIL_H #define PLPY_UTIL_H +#include "plpython.h" + extern PyObject *PLyUnicode_Bytes(PyObject *unicode); extern char *PLyUnicode_AsString(PyObject *unicode); diff --git a/src/pl/plpython/plpython.h b/src/pl/plpython/plpython.h index 5c2e6a83f30..3a1f0d56d7c 100644 --- a/src/pl/plpython/plpython.h +++ b/src/pl/plpython/plpython.h @@ -2,7 +2,7 @@ * * plpython.h - Python as a procedural language for PostgreSQL * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/pl/plpython/plpython.h @@ -14,7 +14,8 @@ /* * Include order should be: postgres.h, other postgres headers, plpython.h, - * other plpython headers + * other plpython headers. (In practice, other plpython headers will also + * include this file, so that they can compile standalone.) */ #ifndef POSTGRES_H #error postgres.h must be included before plpython.h @@ -27,18 +28,20 @@ */ #undef _POSIX_C_SOURCE #undef _XOPEN_SOURCE -#undef HAVE_STRERROR #undef HAVE_TZNAME /* * Sometimes python carefully scribbles on our *printf macros. * So we undefine them here and redefine them after it's done its dirty deed. */ - -#ifdef USE_REPL_SNPRINTF -#undef snprintf #undef vsnprintf -#endif +#undef snprintf +#undef vsprintf +#undef sprintf +#undef vfprintf +#undef fprintf +#undef vprintf +#undef printf #if defined(_MSC_VER) && defined(_DEBUG) /* Python uses #pragma to bring in a non-default libpython on VC++ if @@ -124,22 +127,40 @@ typedef int Py_ssize_t; #include #include -/* put back our snprintf and vsnprintf */ -#ifdef USE_REPL_SNPRINTF +/* put back our *printf macros ... this must match src/include/port.h */ +#ifdef vsnprintf +#undef vsnprintf +#endif #ifdef snprintf #undef snprintf #endif -#ifdef vsnprintf -#undef vsnprintf +#ifdef vsprintf +#undef vsprintf #endif -#ifdef __GNUC__ -#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) -#define snprintf(...) pg_snprintf(__VA_ARGS__) -#else -#define vsnprintf pg_vsnprintf -#define snprintf pg_snprintf -#endif /* __GNUC__ */ -#endif /* USE_REPL_SNPRINTF */ +#ifdef sprintf +#undef sprintf +#endif +#ifdef vfprintf +#undef vfprintf +#endif +#ifdef fprintf +#undef fprintf +#endif +#ifdef vprintf +#undef vprintf +#endif +#ifdef printf +#undef printf +#endif + +#define vsnprintf pg_vsnprintf +#define snprintf pg_snprintf +#define vsprintf pg_vsprintf +#define sprintf pg_sprintf +#define vfprintf pg_vfprintf +#define fprintf pg_fprintf +#define vprintf pg_vprintf +#define printf(...) pg_printf(__VA_ARGS__) /* * Used throughout, and also by the Python 2/3 porting layer, so it's easier to diff --git a/src/pl/plpython/plpython2u--1.0.sql b/src/pl/plpython/plpython2u--1.0.sql index e3a12b952ee..661cc66a891 100644 --- a/src/pl/plpython/plpython2u--1.0.sql +++ b/src/pl/plpython/plpython2u--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plpython2u; +CREATE LANGUAGE plpython2u; -COMMENT ON PROCEDURAL LANGUAGE plpython2u IS 'PL/Python2U untrusted procedural language'; +COMMENT ON LANGUAGE plpython2u IS 'PL/Python2U untrusted procedural language'; diff --git a/src/pl/plpython/plpython2u--unpackaged--1.0.sql b/src/pl/plpython/plpython2u--unpackaged--1.0.sql index a89d8b4d09e..6efa2dbad93 100644 --- a/src/pl/plpython/plpython2u--unpackaged--1.0.sql +++ b/src/pl/plpython/plpython2u--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plpython/plpython2u--unpackaged--1.0.sql */ -ALTER EXTENSION plpython2u ADD PROCEDURAL LANGUAGE plpython2u; +ALTER EXTENSION plpython2u ADD LANGUAGE plpython2u; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plpython2u ADD FUNCTION plpython2_call_handler(); ALTER EXTENSION plpython2u ADD FUNCTION plpython2_inline_handler(internal); diff --git a/src/pl/plpython/plpython3u--1.0.sql b/src/pl/plpython/plpython3u--1.0.sql index cd1fb636a00..c0d6ea82c2d 100644 --- a/src/pl/plpython/plpython3u--1.0.sql +++ b/src/pl/plpython/plpython3u--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plpython3u; +CREATE LANGUAGE plpython3u; -COMMENT ON PROCEDURAL LANGUAGE plpython3u IS 'PL/Python3U untrusted procedural language'; +COMMENT ON LANGUAGE plpython3u IS 'PL/Python3U untrusted procedural language'; diff --git a/src/pl/plpython/plpython3u--unpackaged--1.0.sql b/src/pl/plpython/plpython3u--unpackaged--1.0.sql index b1c0d03a304..fb8d3d6a652 100644 --- a/src/pl/plpython/plpython3u--unpackaged--1.0.sql +++ b/src/pl/plpython/plpython3u--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plpython/plpython3u--unpackaged--1.0.sql */ -ALTER EXTENSION plpython3u ADD PROCEDURAL LANGUAGE plpython3u; +ALTER EXTENSION plpython3u ADD LANGUAGE plpython3u; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plpython3u ADD FUNCTION plpython3_call_handler(); ALTER EXTENSION plpython3u ADD FUNCTION plpython3_inline_handler(internal); diff --git a/src/pl/plpython/plpythonu--1.0.sql b/src/pl/plpython/plpythonu--1.0.sql index 61d3d554c93..4a3e64aac50 100644 --- a/src/pl/plpython/plpythonu--1.0.sql +++ b/src/pl/plpython/plpythonu--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE plpythonu; +CREATE LANGUAGE plpythonu; -COMMENT ON PROCEDURAL LANGUAGE plpythonu IS 'PL/PythonU untrusted procedural language'; +COMMENT ON LANGUAGE plpythonu IS 'PL/PythonU untrusted procedural language'; diff --git a/src/pl/plpython/plpythonu--unpackaged--1.0.sql b/src/pl/plpython/plpythonu--unpackaged--1.0.sql index 79262332508..16b828f2fed 100644 --- a/src/pl/plpython/plpythonu--unpackaged--1.0.sql +++ b/src/pl/plpython/plpythonu--unpackaged--1.0.sql @@ -1,6 +1,6 @@ /* src/pl/plpython/plpythonu--unpackaged--1.0.sql */ -ALTER EXTENSION plpythonu ADD PROCEDURAL LANGUAGE plpythonu; +ALTER EXTENSION plpythonu ADD LANGUAGE plpythonu; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION plpythonu ADD FUNCTION plpython_call_handler(); ALTER EXTENSION plpythonu ADD FUNCTION plpython_inline_handler(internal); diff --git a/src/pl/plpython/po/cs.po b/src/pl/plpython/po/cs.po index 265c515dbce..ff67ead25f2 100644 --- a/src/pl/plpython/po/cs.po +++ b/src/pl/plpython/po/cs.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: plpython-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-09-18 16:39+0000\n" -"PO-Revision-Date: 2012-09-19 01:51+0200\n" +"POT-Creation-Date: 2018-07-13 19:37+0000\n" +"PO-Revision-Date: 2018-07-13 23:53+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" @@ -16,24 +16,24 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Lokalize 1.4\n" +"X-Generator: Poedit 2.0.7\n" -#: plpy_cursorobject.c:98 +#: plpy_cursorobject.c:101 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor oÄekával dotaz nebo plán" -#: plpy_cursorobject.c:171 +#: plpy_cursorobject.c:184 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor jako druhý argument oÄekává sekvenci" -#: plpy_cursorobject.c:187 plpy_spi.c:222 +#: plpy_cursorobject.c:200 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "nelze spustit plán" -#: plpy_cursorobject.c:190 plpy_spi.c:225 +#: plpy_cursorobject.c:203 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" @@ -41,98 +41,107 @@ msgstr[0] "OÄekávána posloupnost %d argument, pÅ™edáno %d: %s" msgstr[1] "OÄekávána posloupnost %d argumentů, pÅ™edáno %d: %s" msgstr[2] "OÄekávána posloupnost %d argumentů, pÅ™edáno %d: %s" -#: plpy_cursorobject.c:340 +#: plpy_cursorobject.c:352 #, c-format msgid "iterating a closed cursor" msgstr "iterování uzavÅ™eného kurzoru" -#: plpy_cursorobject.c:348 plpy_cursorobject.c:415 +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "iterování kurzoru ve zruÅ¡ené subtransakci" -#: plpy_cursorobject.c:407 +#: plpy_cursorobject.c:418 #, c-format msgid "fetch from a closed cursor" msgstr "fetch ze zavÅ™eného kurzoru" -#: plpy_cursorobject.c:486 +#: plpy_cursorobject.c:461 plpy_spi.c:409 +#, c-format +msgid "query result has too many rows to fit in a Python list" +msgstr "výsledek dotazu má příliÅ¡ mnoho řádek a nevejde se to Python seznamu" + +#: plpy_cursorobject.c:512 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "uzavÅ™ení kurzoru ve zruÅ¡ené subtransakci" -#: plpy_elog.c:103 plpy_elog.c:104 plpy_plpymodule.c:420 +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:90 +#: plpy_exec.c:142 #, c-format msgid "unsupported set function return mode" msgstr "nepodporovaný návratový mód funkce vracející tabulku" -#: plpy_exec.c:91 +#: plpy_exec.c:143 #, c-format msgid "" -"PL/Python set-returning functions only support returning only value per call." +"PL/Python set-returning functions only support returning one value per call." msgstr "" -"PL/Python funkce vracející tabulku podporují pouze vracení hodnoty pro každé " -"volání." +"PL/Python funkce vracející tabulku podporují pouze vracení jedné hodnoty pro " +"každé volání." -#: plpy_exec.c:103 +#: plpy_exec.c:156 #, c-format msgid "returned object cannot be iterated" msgstr "pÅ™es vrácený objekt nelze iterovat" -#: plpy_exec.c:104 +#: plpy_exec.c:157 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python funkce vracející tabulku musí vracet iterovatelný objekt." -#: plpy_exec.c:129 +#: plpy_exec.c:171 #, c-format msgid "error fetching next item from iterator" msgstr "chyba pÅ™i naÄítání další položky z iterátoru" -#: plpy_exec.c:164 +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python procedura nevrátila hodnotu None" + +#: plpy_exec.c:218 #, c-format msgid "PL/Python function with return type \"void\" did not return None" -msgstr "" -"PL/Python funkce s návratovým typem \"void\" nevrátila hodnotu \"None\"" +msgstr "PL/Python funkce s návratovým typem \"void\" nevrátila hodnotu None" -#: plpy_exec.c:288 plpy_exec.c:314 +#: plpy_exec.c:374 plpy_exec.c:400 #, c-format msgid "unexpected return value from trigger procedure" msgstr "neoÄekávaná návratová hodnota z trigger procedury" -#: plpy_exec.c:289 +#: plpy_exec.c:375 #, c-format msgid "Expected None or a string." msgstr "OÄekáváno None nebo Å™etÄ›zec." -#: plpy_exec.c:304 +#: plpy_exec.c:390 #, c-format msgid "" "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "" "PL/Python trigger funkce vrátila \"MODIFY\" v DELETE triggeru -- ignorováno" -#: plpy_exec.c:315 +#: plpy_exec.c:401 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "OÄekáváno None, \"OK\", \"SKIP\", nebo \"MODIFY\"." -#: plpy_exec.c:396 +#: plpy_exec.c:451 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "volání PyList_SetItem() selhalo bÄ›hem vytváření argumentů" -#: plpy_exec.c:400 +#: plpy_exec.c:455 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "volání PyDict_SetItemString() selhalo bÄ›hem přípravy argumentů" -#: plpy_exec.c:412 +#: plpy_exec.c:467 #, c-format msgid "" "function returning record called in context that cannot accept type record" @@ -140,32 +149,27 @@ msgstr "" "funkce vracející záznam byla zavolána z kontextu, který neumožňuje pÅ™ijetí " "záznamu" -#: plpy_exec.c:450 +#: plpy_exec.c:684 #, c-format msgid "while creating return value" msgstr "bÄ›hem vytváření návratové hodnoty" -#: plpy_exec.c:474 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "bÄ›hem vytváření argumentů triggeru nelze vytvářet nový slovník" - -#: plpy_exec.c:664 +#: plpy_exec.c:909 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] smazáno, nelze modifikovat řádek" -#: plpy_exec.c:667 +#: plpy_exec.c:914 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] není slovník" -#: plpy_exec.c:691 +#: plpy_exec.c:941 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "TD[\"new\"] klÃ­Ä slovníku na pozici %d není Å™etÄ›zec" -#: plpy_exec.c:697 +#: plpy_exec.c:948 #, c-format msgid "" "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " @@ -173,227 +177,212 @@ msgid "" msgstr "" "klÃ­Ä \"%s\" nalezený v TD[\"new\"] neexistuje jako sloupec v triggering řádku" -#: plpy_exec.c:778 +#: plpy_exec.c:953 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "nelze nastavit systémový atribut \"%s\"" + +#: plpy_exec.c:1011 #, c-format msgid "while modifying trigger row" msgstr "bÄ›hem modifikace řádku triggeru" -#: plpy_exec.c:839 +#: plpy_exec.c:1072 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "vynucené ukonÄení subtransakce která nebyla dokonÄena" -#: plpy_main.c:100 +#: plpy_main.c:125 #, c-format -msgid "Python major version mismatch in session" -msgstr "Rozpor mezi hlavními verzemi Pythonu v session" +msgid "multiple Python libraries are present in session" +msgstr "v session je naÄteno nÄ›kolik Python knihoven" -#: plpy_main.c:101 +#: plpy_main.c:126 #, c-format -msgid "" -"This session has previously used Python major version %d, and it is now " -"attempting to use Python major version %d." -msgstr "" -"Tato session již dříve používala Python s hlavní verzí %d, a nyní se pokouší " -"použít Python s hlavní verzí %d." +msgid "Only one Python major version can be used in one session." +msgstr "Pouze jedna major verze Pythonu může být použita v jedné session." -#: plpy_main.c:103 -#, c-format -msgid "Start a new session to use a different Python major version." -msgstr "SpouÅ¡tí se nová session pro použití jiné hlavní verze Pythonu." - -#: plpy_main.c:118 +#: plpy_main.c:142 #, c-format msgid "untrapped error in initialization" msgstr "nezachycená chyba v inicializaci" -#: plpy_main.c:141 +#: plpy_main.c:165 #, c-format msgid "could not import \"__main__\" module" msgstr "nepodaÅ™ilo se naimportovat \"__main__\" modul" -#: plpy_main.c:146 -#, c-format -msgid "could not create globals" -msgstr "nepodaÅ™ilo se vytvoÅ™it globals" - -#: plpy_main.c:150 +#: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "nepodaÅ™ilo se inicializovat globální promÄ›nné (globals)" -#: plpy_main.c:347 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "PL/Python procedura \"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python funkce \"%s\"" -#: plpy_main.c:354 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python anonymní blok kódu" -#: plpy_planobject.c:126 -#, c-format -msgid "plan.status takes no arguments" -msgstr "plan.status nepÅ™ijímá žádné argumenty" - -#: plpy_plpymodule.c:178 plpy_plpymodule.c:181 +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 #, c-format -#| msgid "could not import \"__main__\" module" msgid "could not import \"plpy\" module" msgstr "nepodaÅ™ilo se naimportovat \"plpy\" modul" -#: plpy_plpymodule.c:196 +#: plpy_plpymodule.c:210 #, c-format -msgid "could not add the spiexceptions module" -msgstr "nepodaÅ™ilo se naimportovat \"__main__\" modul" +msgid "could not create the spiexceptions module" +msgstr "nepodaÅ™ilo se vytvoÅ™it spiexceptions modul" -#: plpy_plpymodule.c:217 +#: plpy_plpymodule.c:218 #, c-format -msgid "could not create the base SPI exceptions" -msgstr "nepodaÅ™ilo se vygenerovat základní SPI výjimky" +msgid "could not add the spiexceptions module" +msgstr "nepodaÅ™ilo se naimportovat \"__main__\" modul" -#: plpy_plpymodule.c:253 plpy_plpymodule.c:257 +#: plpy_plpymodule.c:286 #, c-format msgid "could not generate SPI exceptions" msgstr "nepodaÅ™ilo se vygenerovat SPI výjimky" -#: plpy_plpymodule.c:388 +#: plpy_plpymodule.c:454 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "nepodaÅ™ilo se rozbalit argumenty v plpy.elog" -#: plpy_plpymodule.c:396 +#: plpy_plpymodule.c:463 msgid "could not parse error message in plpy.elog" msgstr "nepodaÅ™ilo se naparsovat chybovou hlášku v plpy.elog" -#: plpy_procedure.c:194 +#: plpy_plpymodule.c:480 +#, c-format +msgid "argument 'message' given by name and position" +msgstr "argument 'message' zadán jménem a pozicí" + +#: plpy_plpymodule.c:507 +#, c-format +msgid "'%s' is an invalid keyword argument for this function" +msgstr "'%s' je neplatný keyword argument pro tuto funkci" + +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 +#, c-format +msgid "invalid SQLSTATE code" +msgstr "chybný SQLSTATE kód" + +#: plpy_procedure.c:230 #, c-format msgid "trigger functions can only be called as triggers" msgstr "" "funkce pro obsluhu triggerů mohou být volané pouze prostÅ™ednictvím triggerů" -#: plpy_procedure.c:199 plpy_typeio.c:406 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python funkce nemohou vracet typ %s" -#: plpy_procedure.c:281 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python funkce nepodporují typ %s" -#: plpy_procedure.c:377 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "nelze zkompiloval PL/Python funkci \"%s\"" -#: plpy_procedure.c:380 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "nelze zkompiloval anonymní PL/Python blok" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 #, c-format msgid "command did not produce a result set" msgstr "příkaz nevrátil žádný výsledek" -#: plpy_spi.c:56 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "druhý argument pro plpy.prepare musí být posloupnost" -#: plpy_spi.c:105 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: název typu na pozici %d není Å™etÄ›zec" -#: plpy_spi.c:137 -#, c-format -msgid "plpy.prepare does not support composite types" -msgstr "plpy.prepare nepodporuje složené typy" - -#: plpy_spi.c:187 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute oÄekávala dotaz nebo plán" -#: plpy_spi.c:206 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute jako druhý argument oÄekává posloupnost" -#: plpy_spi.c:330 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "volání SPI_execute_plan selhalo: %s" -#: plpy_spi.c:372 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "volání SPI_execute selhalo: %s" -#: plpy_spi.c:439 -#, c-format -msgid "unrecognized error in PLy_spi_execute_fetch_result" -msgstr "nerozpoznaná chyba v PLy_spi_execute_fetch_result" - #: plpy_subxactobject.c:122 #, c-format msgid "this subtransaction has already been entered" msgstr "tato subtransakce již byla zahájena" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:180 +#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 #, c-format msgid "this subtransaction has already been exited" msgstr "tato subtransakce již byla dokonÄena" -#: plpy_subxactobject.c:174 +#: plpy_subxactobject.c:180 #, c-format msgid "this subtransaction has not been entered" msgstr "tato subtransakce nebyla zahájena" -#: plpy_subxactobject.c:186 +#: plpy_subxactobject.c:192 #, c-format msgid "there is no subtransaction to exit from" msgstr "nenalezena subtransakce k ukonÄení" -#: plpy_typeio.c:291 -#, c-format -msgid "could not create new dictionary" -msgstr "nepodaÅ™ilo se vytvoÅ™it nový slovník" - -#: plpy_typeio.c:408 -#, c-format -msgid "PL/Python does not support conversion to arrays of row types." -msgstr "PL/Python nepodporuje konverzi na pole řádkových typů." - -#: plpy_typeio.c:584 +#: plpy_typeio.c:591 #, c-format -msgid "cannot convert multidimensional array to Python list" -msgstr "vícerozmÄ›rné pole nelze pÅ™evést na Python seznam (list)" +msgid "could not import a module for Decimal constructor" +msgstr "nepodaÅ™ilo se naimportovat modul pro Decimal constructor" -#: plpy_typeio.c:585 +#: plpy_typeio.c:595 #, c-format -msgid "PL/Python only supports one-dimensional arrays." -msgstr "PL/Python podporuje pouze jednorozmÄ›rná pole." +msgid "no Decimal attribute in module" +msgstr "modul nemá žádný Decimal atribut" -#: plpy_typeio.c:591 +#: plpy_typeio.c:601 #, c-format -msgid "could not create new Python list" -msgstr "nelze vytvoÅ™it nový Python seznam" +msgid "conversion from numeric to Decimal failed" +msgstr "konverze z numeric na Decimal selhala" -#: plpy_typeio.c:650 +#: plpy_typeio.c:908 #, c-format msgid "could not create bytes representation of Python object" msgstr "nepodaÅ™ilo se vytvoÅ™it bytovou reprezentaci Python objektu" -#: plpy_typeio.c:742 +#: plpy_typeio.c:1056 #, c-format msgid "could not create string representation of Python object" msgstr "nepodaÅ™ilo se vytvoÅ™it Å™etÄ›zcovou reprezentaci Python objektu" -#: plpy_typeio.c:753 +#: plpy_typeio.c:1067 #, c-format msgid "" "could not convert Python object into cstring: Python string representation " @@ -402,7 +391,22 @@ msgstr "" "nepodaÅ™ilo se pÅ™evést Python objekt na cstring: zdá se že Å™etÄ›zcová " "reprezentace Python objektu obsahuje null byty" -#: plpy_typeio.c:787 +#: plpy_typeio.c:1176 +#, c-format +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "poÄet dimenzí pole pÅ™ekraÄuje povolené maximum (%d)" + +#: plpy_typeio.c:1180 +#, c-format +msgid "could not determine sequence length for function return value" +msgstr "nelze urÄit délku posloupnosti pro návratovou hodnotu funkce" + +#: plpy_typeio.c:1183 plpy_typeio.c:1187 +#, c-format +msgid "array size exceeds the maximum allowed" +msgstr "velikost pole pÅ™ekraÄuje povolené maximum" + +#: plpy_typeio.c:1213 #, c-format msgid "" "return value of function with array return type is not a Python sequence" @@ -410,12 +414,45 @@ msgstr "" "návratová hodnota funkce s návratovým typem pole není Python posloupnost " "(sequence)" -#: plpy_typeio.c:886 +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "chybná délka vnitÄní sekvence: má délku %d, ale oÄekáváno bylo %d" + +#: plpy_typeio.c:1261 +#, c-format +msgid "" +"To construct a multidimensional array, the inner sequences must all have the " +"same length." +msgstr "" +"Pro vytvoÅ™ení vícerozmÄ›rného pole musí mít vÄechny vnitÅ™ní sekvence stejnou " +"délku." + +#: plpy_typeio.c:1340 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "chybný literál záznamu: \"%s\"" + +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "ChybÄ›jící levá závorka." + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "" +"To return a composite type in an array, return the composite type as a " +"Python tuple, e.g., \"[('foo',)]\"." +msgstr "" +"Pro vrácení kompozitního typu v poli, vracejte kompozitní typ jako Python " +"tuple, e.g., \"[('foo',)]\"." + +#: plpy_typeio.c:1389 #, c-format msgid "key \"%s\" not found in mapping" msgstr "klÃ­Ä \"%s\" nenalezen v mapování" -#: plpy_typeio.c:887 +#: plpy_typeio.c:1390 #, c-format msgid "" "To return null in a column, add the value None to the mapping with the key " @@ -424,17 +461,17 @@ msgstr "" "Pro vrácení hodnoty null ve sloupci, pÅ™idejte do mapování hodnotu None s " "klíÄem pojmenovaným jako sloupec." -#: plpy_typeio.c:935 +#: plpy_typeio.c:1443 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "délka vrácené posloupnosti neodpovídala poÄtu sloupců v řádku" -#: plpy_typeio.c:1043 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "atribut \"%s\" v Python objektu neexistuje" -#: plpy_typeio.c:1044 +#: plpy_typeio.c:1544 #, c-format msgid "" "To return null in a column, let the returned object have an attribute named " @@ -443,18 +480,58 @@ msgstr "" "Pro vrácení null ve sloupci, nechÅ¥ vracený objekt má atribut pojmenovaný po " "sloupcis hodnotou None." -#: plpy_util.c:70 +#: plpy_util.c:35 #, c-format -#| msgid "" -#| "could not convert Python Unicode object to PostgreSQL server encoding" msgid "could not convert Python Unicode object to bytes" msgstr "nelze pÅ™evést Python Unicode objekt na byty" -#: plpy_util.c:75 +#: plpy_util.c:41 #, c-format -#| msgid "could not generate SPI exceptions" msgid "could not extract bytes from encoded string" msgstr "nepodaÅ™ilo se získat byty z kódovaného Å™etÄ›zce" +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "bÄ›hem vytváření argumentů triggeru nelze vytvářet nový slovník" + +#~ msgid "" +#~ "This session has previously used Python major version %d, and it is now " +#~ "attempting to use Python major version %d." +#~ msgstr "" +#~ "Tato session již dříve používala Python s hlavní verzí %d, a nyní se " +#~ "pokouší použít Python s hlavní verzí %d." + +#~ msgid "Start a new session to use a different Python major version." +#~ msgstr "SpouÅ¡tí se nová session pro použití jiné hlavní verze Pythonu." + +#~ msgid "could not create globals" +#~ msgstr "nepodaÅ™ilo se vytvoÅ™it globals" + +#~ msgid "plan.status takes no arguments" +#~ msgstr "plan.status nepÅ™ijímá žádné argumenty" + +#~ msgid "could not create the base SPI exceptions" +#~ msgstr "nepodaÅ™ilo se vygenerovat základní SPI výjimky" + +#~ msgid "plpy.prepare does not support composite types" +#~ msgstr "plpy.prepare nepodporuje složené typy" + +#~ msgid "unrecognized error in PLy_spi_execute_fetch_result" +#~ msgstr "nerozpoznaná chyba v PLy_spi_execute_fetch_result" + +#~ msgid "could not create new dictionary" +#~ msgstr "nepodaÅ™ilo se vytvoÅ™it nový slovník" + +#~ msgid "PL/Python does not support conversion to arrays of row types." +#~ msgstr "PL/Python nepodporuje konverzi na pole řádkových typů." + +#~ msgid "cannot convert multidimensional array to Python list" +#~ msgstr "vícerozmÄ›rné pole nelze pÅ™evést na Python seznam (list)" + +#~ msgid "PL/Python only supports one-dimensional arrays." +#~ msgstr "PL/Python podporuje pouze jednorozmÄ›rná pole." + +#~ msgid "could not create new Python list" +#~ msgstr "nelze vytvoÅ™it nový Python seznam" + #~ msgid "could not initialize plpy" #~ msgstr "nepodaÅ™ilo se inicializovat plpy" diff --git a/src/pl/plpython/po/de.po b/src/pl/plpython/po/de.po index 4dae50327c9..ce8e24b552b 100644 --- a/src/pl/plpython/po/de.po +++ b/src/pl/plpython/po/de.po @@ -1,182 +1,187 @@ # German message translation file for plpython -# Copyright (C) 2009 - 2017 PostgreSQL Global Development Group +# Copyright (C) 2009 - 2019 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Peter Eisentraut , 2009 - 2017. +# Peter Eisentraut , 2009 - 2019. # # Use these quotes: »%s« # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-04 15:37+0000\n" -"PO-Revision-Date: 2017-08-04 13:01-0400\n" -"Last-Translator: Peter Eisentraut \n" -"Language-Team: German \n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-07 04:38+0000\n" +"PO-Revision-Date: 2019-05-07 15:35+0200\n" +"Last-Translator: Peter Eisentraut \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:78 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor hat eine Anfrage oder einen Plan erwartet" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:161 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor nimmt eine Sequenz als zweites Argument" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:177 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "konnte Plan nicht ausführen" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:180 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Sequenz aus %d Argument erwartet, aber %d erhalten: %s" msgstr[1] "Sequenz aus %d Argumenten erwartet, aber %d erhalten: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:329 #, c-format msgid "iterating a closed cursor" msgstr "Iteration mit einem geschlossenen Cursor" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "Iteration mit einem Cursor in einer abgebrochenen Transaktionen" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:395 #, c-format msgid "fetch from a closed cursor" msgstr "Lesen aus einem geschlossenen Cursor" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:438 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "Anfrageergebnis hat zu viele Zeilen, um in eine Python-Liste zu passen" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:490 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "Schließen eines Cursors in einer abgebrochenen Subtransaktion" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:143 #, c-format msgid "unsupported set function return mode" msgstr "nicht unterstützter Rückgabemodus für Funktion mit Mengenergebnis" -#: plpy_exec.c:141 +#: plpy_exec.c:144 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "PL/Python unterstützt für Funktionen mit Mengenergebnis nur das Zurückgeben von einem Wert pro Aufruf." -#: plpy_exec.c:154 +#: plpy_exec.c:157 #, c-format msgid "returned object cannot be iterated" msgstr "zurückgegebenes Objekt kann nicht iteriert werden" -#: plpy_exec.c:155 +#: plpy_exec.c:158 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python-Funktionen mit Mengenergebnis müssen ein iterierbares Objekt zurückgeben." -#: plpy_exec.c:169 +#: plpy_exec.c:172 #, c-format msgid "error fetching next item from iterator" msgstr "Fehler beim Auslesen des nächsten Elements vom Iterator" -#: plpy_exec.c:210 +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python-Prozedur hat nicht None zurückgegeben" + +#: plpy_exec.c:219 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "PL/Python-Funktion mit Rückgabetyp »void« hat nicht None zurückgegeben" -#: plpy_exec.c:379 plpy_exec.c:405 +#: plpy_exec.c:375 plpy_exec.c:401 #, c-format msgid "unexpected return value from trigger procedure" msgstr "unerwarteter Rückgabewert von Triggerprozedur" -#: plpy_exec.c:380 +#: plpy_exec.c:376 #, c-format msgid "Expected None or a string." msgstr "Erwartete None oder eine Zeichenkette." -#: plpy_exec.c:395 +#: plpy_exec.c:391 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "PL/Python-Funktion gab in einem DELETE-Trigger \"MODIFY\" zurück -- ignoriert" -#: plpy_exec.c:406 +#: plpy_exec.c:402 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Erwartete None, \"OK\", \"SKIP\" oder \"MODIFY\"." -#: plpy_exec.c:487 +#: plpy_exec.c:452 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() fehlgeschlagen, beim Einrichten der Argumente" -#: plpy_exec.c:491 +#: plpy_exec.c:456 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() fehlgeschlagen, beim Einrichten der Argumente" -#: plpy_exec.c:503 +#: plpy_exec.c:468 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "Funktion, die einen Record zurückgibt, in einem Zusammenhang aufgerufen, der Typ record nicht verarbeiten kann" -#: plpy_exec.c:719 +#: plpy_exec.c:685 #, c-format msgid "while creating return value" msgstr "beim Erzeugen des Rückgabewerts" -#: plpy_exec.c:743 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "konnte neues Dictionary nicht erzeugen, beim Aufbauen der Triggerargumente" - -#: plpy_exec.c:931 +#: plpy_exec.c:919 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] wurde gelöscht, kann Zeile nicht ändern" -#: plpy_exec.c:936 +#: plpy_exec.c:924 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] ist kein Dictionary" -#: plpy_exec.c:963 +#: plpy_exec.c:951 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "Dictionary-Schlüssel auf Position %d in TD[\"new\"] ist keine Zeichenkette" -#: plpy_exec.c:970 +#: plpy_exec.c:958 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "in TD[\"new\"] gefundener Schlüssel »%s« existiert nicht als Spalte in der den Trigger auslösenden Zeile" -#: plpy_exec.c:975 +#: plpy_exec.c:963 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "Systemattribut »%s« kann nicht gesetzt werden" -#: plpy_exec.c:1046 +#: plpy_exec.c:968 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "kann generierte Spalte »%s« nicht setzen" + +#: plpy_exec.c:1026 #, c-format msgid "while modifying trigger row" msgstr "beim Ändern der Triggerzeile" -#: plpy_exec.c:1107 +#: plpy_exec.c:1087 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "Abbruch einer Subtransaktion, die nicht beendet wurde, wird erzwungen" @@ -201,71 +206,66 @@ msgstr "nicht abgefangener Fehler bei der Initialisierung" msgid "could not import \"__main__\" module" msgstr "konnte Modul »__main__« nicht importieren" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "konnte globale Objekte nicht erzeugen" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "konnte globale Objekte nicht initialisieren" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "PL/Python-Prozedur »%s«" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python-Funktion »%s«" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "anonymer PL/Python-Codeblock" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 #, c-format msgid "could not import \"plpy\" module" msgstr "konnte Modul »plpy« nicht importieren" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:204 #, c-format msgid "could not create the spiexceptions module" msgstr "konnte das Modul »spiexceptions« nicht erzeugen" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:212 #, c-format msgid "could not add the spiexceptions module" msgstr "konnte das Modul »spiexceptions« nicht hinzufügen" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "konnte Ausnahme »%s« nicht erzeugen" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:280 #, c-format msgid "could not generate SPI exceptions" msgstr "konnte SPI-Ausnahmen nicht erzeugen" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:448 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "konnte Argumente in plpy.elog nicht entpacken" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:457 msgid "could not parse error message in plpy.elog" msgstr "konnte Fehlermeldung in plpy.elog nicht parsen" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:474 #, c-format msgid "argument 'message' given by name and position" msgstr "Argument »message« wurde durch Namen und Position angegeben" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:501 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "»%s« ist ein ungültiges Schlüsselwortargument für diese Funktion" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 #, c-format msgid "invalid SQLSTATE code" msgstr "ungültiger SQLSTATE-Code" @@ -275,188 +275,187 @@ msgstr "ungültiger SQLSTATE-Code" msgid "trigger functions can only be called as triggers" msgstr "Triggerfunktionen können nur als Trigger aufgerufen werden" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python-Funktionen können keinen Rückgabetyp %s haben" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python-Funktionen können Typ %s nicht annehmen" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "konnte PL/Python-Funktion »%s« nicht kompilieren" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "konnte anonymen PL/Python-Codeblock nicht kompilieren" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 #, c-format msgid "command did not produce a result set" msgstr "Befehl hat keine Ergebnismenge erzeugt" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "zweites Argument von plpy.prepare muss eine Sequenz sein" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: Typname auf Position %d ist keine Zeichenkette" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute hat eine Anfrage oder einen Plan erwartet" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute nimmt eine Sequenz als zweites Argument" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan fehlgeschlagen: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute fehlgeschlagen: %s" -#: plpy_subxactobject.c:122 +#: plpy_subxactobject.c:97 #, c-format msgid "this subtransaction has already been entered" msgstr "diese Subtransaktion wurde bereits begonnen" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 #, c-format msgid "this subtransaction has already been exited" msgstr "diese Subtransaktion wurde bereits beendet" -#: plpy_subxactobject.c:180 +#: plpy_subxactobject.c:155 #, c-format msgid "this subtransaction has not been entered" msgstr "diese Subtransaktion wurde nicht begonnen" -#: plpy_subxactobject.c:192 +#: plpy_subxactobject.c:167 #, c-format msgid "there is no subtransaction to exit from" msgstr "es gibt keine Subtransaktion zu beenden" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "konnte neues Dictionary nicht erzeugen" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "konnte kein Modul für den »Decimal«-Konstruktor importieren" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "kein Attribut »Decimal« im Modul" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "Umwandlung von numeric in Decimal fehlgeschlagen" -#: plpy_typeio.c:773 +#: plpy_typeio.c:915 #, c-format msgid "could not create bytes representation of Python object" msgstr "konnte Bytes-Darstellung eines Python-Objektes nicht erzeugen" -#: plpy_typeio.c:882 +#: plpy_typeio.c:1063 #, c-format msgid "could not create string representation of Python object" msgstr "konnte Zeichenkettendarstellung eines Python-Objektes nicht erzeugen" -#: plpy_typeio.c:893 +#: plpy_typeio.c:1074 #, c-format msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" msgstr "konnte Python-Objekt nicht in cstring umwandeln: Python-Zeichenkettendarstellung enthält anscheinend Null-Bytes" -#: plpy_typeio.c:950 -#, c-format -msgid "malformed record literal: \"%s\"" -msgstr "fehlerhafte Record-Konstante: »%s«" - -#: plpy_typeio.c:951 -#, c-format -msgid "Missing left parenthesis." -msgstr "Linke Klammer fehlt." - -#: plpy_typeio.c:952 plpy_typeio.c:1390 -#, c-format -msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." -msgstr "Um einen zusammengesetzten Typ in einem Array zurückzugeben, geben Sie den zusammengesetzten Typ als ein Python-Tupel zurück, z.B. »[('foo',)]«." - -#: plpy_typeio.c:1001 +#: plpy_typeio.c:1183 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "Anzahl der Arraydimensionen überschreitet erlaubtes Maximum (%d)" -#: plpy_typeio.c:1005 +#: plpy_typeio.c:1187 #, c-format -msgid "cannot determine sequence length for function return value" -msgstr "kann Sequenzlänge für Funktionsrückgabewert nicht ermitteln" +msgid "could not determine sequence length for function return value" +msgstr "konnte Sequenzlänge für Funktionsrückgabewert nicht ermitteln" -#: plpy_typeio.c:1008 plpy_typeio.c:1012 +#: plpy_typeio.c:1190 plpy_typeio.c:1194 #, c-format msgid "array size exceeds the maximum allowed" msgstr "Arraygröße überschreitet erlaubtes Maximum" -#: plpy_typeio.c:1038 +#: plpy_typeio.c:1220 #, c-format msgid "return value of function with array return type is not a Python sequence" msgstr "Rückgabewert von Funktion mit Array-Rückgabetyp ist keine Python-Sequenz" -#: plpy_typeio.c:1091 -#, fuzzy, c-format -#| msgid "multidimensional arrays must have array expressions with matching dimensions" -msgid "multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length %d while expected %d" -msgstr "mehrdimensionale Arrays müssen Arraysausdrücke mit gleicher Anzahl Dimensionen haben" +#: plpy_typeio.c:1266 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "falsche Länge der inneren Sequenz: hat Länge %d, aber %d wurde erwartet" + +#: plpy_typeio.c:1268 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "Um ein mehrdimensionales Array zu konstruieren, müssen die inneren Sequenzen alle die gleiche Länge haben." + +#: plpy_typeio.c:1347 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "fehlerhafte Record-Konstante: »%s«" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "Linke Klammer fehlt." + +#: plpy_typeio.c:1349 plpy_typeio.c:1550 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "Um einen zusammengesetzten Typ in einem Array zurückzugeben, geben Sie den zusammengesetzten Typ als ein Python-Tupel zurück, z.B. »[('foo',)]«." -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1396 #, c-format msgid "key \"%s\" not found in mapping" msgstr "Schlüssel »%s« nicht in Mapping gefunden" -#: plpy_typeio.c:1214 +#: plpy_typeio.c:1397 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "Um einen NULL-Wert in einer Spalte zurückzugeben, muss der Wert None mit einem nach der Spalte benannten Schlüssel in das Mapping eingefügt werden." -#: plpy_typeio.c:1265 +#: plpy_typeio.c:1450 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "Länge der zurückgegebenen Sequenz hat nicht mit der Anzahl der Spalten in der Zeile übereingestimmt" -#: plpy_typeio.c:1388 +#: plpy_typeio.c:1548 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "Attribut »%s« existiert nicht in Python-Objekt" -#: plpy_typeio.c:1391 +#: plpy_typeio.c:1551 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "Um einen NULL-Wert in einer Spalte zurückzugeben, muss das zurückzugebende Objekt ein nach der Spalte benanntes Attribut mit dem Wert None haben." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "konnte Python-Unicode-Objekt nicht in Bytes umwandeln" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "konnte kodierte Zeichenkette nicht in Bytes umwandeln" diff --git a/src/pl/plpython/po/es.po b/src/pl/plpython/po/es.po index a942e5e8737..9f1369c8eca 100644 --- a/src/pl/plpython/po/es.po +++ b/src/pl/plpython/po/es.po @@ -1,6 +1,6 @@ # Spanish message translation file for plpython # -# Copyright (C) 2009-2012 PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Emanuel Calvo Franco , 2009. @@ -8,12 +8,12 @@ # msgid "" msgstr "" -"Project-Id-Version: plpython (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:07+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: plpython (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:26-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -21,165 +21,170 @@ msgstr "" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Poedit 2.0.2\n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:78 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor espera una consulta o un plan" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:161 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor lleva una secuencia como segundo argumento" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:177 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "no se pudo ejecutar el plan" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:180 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Se esperaba una secuencia de %d argumento, se obtuvo %d: %s" msgstr[1] "Se esperaba una secuencia de %d argumentos, se obtuvo %d: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:329 #, c-format msgid "iterating a closed cursor" msgstr "iterando un cursor cerrado" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "iterando un cursor en una subtransacción abortada" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:395 #, c-format msgid "fetch from a closed cursor" msgstr "haciendo «fetch» en un cursor cerrado" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:438 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "el resultado de la consulta tiene demasiados registros y no entran en una lista de Python" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:490 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "cerrando un cursor en una subtransacción abortada" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:143 #, c-format msgid "unsupported set function return mode" msgstr "modo de retorno de conjunto de función no soportado" -#: plpy_exec.c:141 +#: plpy_exec.c:144 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "Las funciones PL/Python que retornan conjuntos sólo permiten retornar un valor por invocación." -#: plpy_exec.c:154 +#: plpy_exec.c:157 #, c-format msgid "returned object cannot be iterated" msgstr "objeto retornado no puede ser iterado" -#: plpy_exec.c:155 +#: plpy_exec.c:158 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "Los funciones PL/Python que retornan conjuntos deben retornar un objeto iterable." -#: plpy_exec.c:169 +#: plpy_exec.c:172 #, c-format msgid "error fetching next item from iterator" msgstr "error extrayendo el próximo elemento del iterador" -#: plpy_exec.c:210 +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "procedimiento PL/Python no returnó None" + +#: plpy_exec.c:219 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "función PL/Python con tipo de retorno «void» no retorna None" -#: plpy_exec.c:379 plpy_exec.c:405 +#: plpy_exec.c:375 plpy_exec.c:401 #, c-format msgid "unexpected return value from trigger procedure" msgstr "valor de retorno no esperado desde el procedimiento disparador" -#: plpy_exec.c:380 +#: plpy_exec.c:376 #, c-format msgid "Expected None or a string." msgstr "Se esperaba None o una cadena." -#: plpy_exec.c:395 +#: plpy_exec.c:391 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "función de disparador de PL/Python retorno «MODIFY» en un disparador de tipo DELETE -- ignorado" -#: plpy_exec.c:406 +#: plpy_exec.c:402 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Se esperaba None, «OK», «SKIP» o «MODIFY»." -#: plpy_exec.c:487 +#: plpy_exec.c:452 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() falló, mientras se inicializaban los argumentos" -#: plpy_exec.c:491 +#: plpy_exec.c:456 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() falló, mientras se inicializaban los argumentos" -#: plpy_exec.c:503 +#: plpy_exec.c:468 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" -#: plpy_exec.c:719 +#: plpy_exec.c:685 #, c-format msgid "while creating return value" msgstr "mientras se creaba el valor de retorno" -#: plpy_exec.c:743 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "no se pudo crear un nuevo diccionario mientras se construían los argumentos de disparador" - -#: plpy_exec.c:931 +#: plpy_exec.c:919 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] borrado, no se puede modicar el registro" -#: plpy_exec.c:936 +#: plpy_exec.c:924 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] no es un diccionario" -#: plpy_exec.c:963 +#: plpy_exec.c:951 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "el nombre del atributo de TD[\"new\"] en la posición %d no es una cadena" -#: plpy_exec.c:970 +#: plpy_exec.c:958 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "la llave «%s» en TD[\"new\"] no existe como columna en la fila disparadora" -#: plpy_exec.c:975 +#: plpy_exec.c:963 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "no se puede definir el atributo de sistema «%s»" -#: plpy_exec.c:1046 +#: plpy_exec.c:968 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "no se puede definir el atributo generado «%s»" + +#: plpy_exec.c:1026 #, c-format msgid "while modifying trigger row" msgstr "mientras se modificaba la fila de disparador" # FIXME not very happy with this -#: plpy_exec.c:1107 +#: plpy_exec.c:1087 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "abortando una subtransacción que no se ha cerrado" @@ -204,71 +209,66 @@ msgstr "error no capturado en la inicialización" msgid "could not import \"__main__\" module" msgstr "no se pudo importar el módulo «__main__»" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "no se pudo crear las globales" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "no se pudo inicializar las globales" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "procedimiento PL/Python «%s»" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "función PL/Python «%s»" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "bloque de código anónimo de PL/Python" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 #, c-format msgid "could not import \"plpy\" module" msgstr "no se pudo importar el módulo «plpy»" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:204 #, c-format msgid "could not create the spiexceptions module" msgstr "no se pudo crear el módulo spiexceptions" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:212 #, c-format msgid "could not add the spiexceptions module" msgstr "no se pudo importar el módulo spiexceptions" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "no se pudo crear la excepción «%s»" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:280 #, c-format msgid "could not generate SPI exceptions" msgstr "no se pudo generar excepciones SPI" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:448 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "no se pudo desempaquetar los argumentos de plpy.elog" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:457 msgid "could not parse error message in plpy.elog" msgstr "no se pudo analizar el mensaje de error de plpy.elog" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:474 #, c-format msgid "argument 'message' given by name and position" msgstr "el argumento 'message' fue pasado por nombre y posición" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:501 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "«%s» no es un argumento válido para esta función" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 #, c-format msgid "invalid SQLSTATE code" msgstr "código SQLSTATE no válido" @@ -278,217 +278,187 @@ msgstr "código SQLSTATE no válido" msgid "trigger functions can only be called as triggers" msgstr "las funciones disparadoras sólo pueden ser llamadas como disparadores" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "las funciones PL/Python no pueden retornar el tipo %s" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "la funciones PL/Python no pueden aceptar el tipo %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "no se pudo compilar la función PL/Python «%s»" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "no se pudo compilar el bloque anónimo PL/Python" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 #, c-format msgid "command did not produce a result set" msgstr "la orden no produjo un conjunto de resultados" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "el segundo argumento de plpy.prepare debe ser una secuencia" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: el nombre de tipo en la posición %d no es una cadena" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute espera una consulta o un plan" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute lleva una secuencia como segundo argumento" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "falló SPI_execute_plan: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "falló SPI_execute: %s" -#: plpy_subxactobject.c:122 +#: plpy_subxactobject.c:97 #, c-format msgid "this subtransaction has already been entered" msgstr "ya se ha entrado en esta subtransacción" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 #, c-format msgid "this subtransaction has already been exited" msgstr "ya se ha salido de esta subtransacción" -#: plpy_subxactobject.c:180 +#: plpy_subxactobject.c:155 #, c-format msgid "this subtransaction has not been entered" msgstr "no se ha entrado en esta subtransacción" -#: plpy_subxactobject.c:192 +#: plpy_subxactobject.c:167 #, c-format msgid "there is no subtransaction to exit from" msgstr "no hay una subtransacción de la cual salir" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "no se pudo crear un nuevo diccionario" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "no se pudo importar un módulo para el constructor Decimal" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "no se encontró atributo Decimal en el módulo" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "falló la conversión de numeric a Decimal" -#: plpy_typeio.c:773 +#: plpy_typeio.c:915 #, c-format msgid "could not create bytes representation of Python object" msgstr "no se pudo crear la representación de cadena de bytes de Python" -#: plpy_typeio.c:882 +#: plpy_typeio.c:1063 #, c-format msgid "could not create string representation of Python object" msgstr "no se pudo crear la representación de cadena de texto del objeto de Python" -#: plpy_typeio.c:893 +#: plpy_typeio.c:1074 #, c-format msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" msgstr "no se pudo convertir el objeto Python a un cstring: la representación de cadena Python parece tener bytes nulos (\\0)" -#: plpy_typeio.c:950 -#, c-format -msgid "malformed record literal: \"%s\"" -msgstr "literal de record no es válido: «%s»" - -#: plpy_typeio.c:951 -#, c-format -msgid "Missing left parenthesis." -msgstr "Falta paréntesis izquierdo." - -#: plpy_typeio.c:952 plpy_typeio.c:1390 -#, c-format -msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." -msgstr "Para retornar un tipo compuesto en un array, retorne el tipo compuesto como una tupla de Python, e.g., «[('foo',)]»." - -#: plpy_typeio.c:1001 +#: plpy_typeio.c:1183 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "el número de dimensiones del array excede el máximo permitido (%d)" -#: plpy_typeio.c:1005 +#: plpy_typeio.c:1187 #, c-format -msgid "cannot determine sequence length for function return value" -msgstr "no se puede determinar el tamaño de la secuencia para el valor de retorno de la función" +msgid "could not determine sequence length for function return value" +msgstr "no se pudo determinar el largo de secuencia del retorno de valor de la función" -#: plpy_typeio.c:1008 plpy_typeio.c:1012 +#: plpy_typeio.c:1190 plpy_typeio.c:1194 #, c-format msgid "array size exceeds the maximum allowed" msgstr "el tamaño del array excede el máximo permitido" -#: plpy_typeio.c:1038 +#: plpy_typeio.c:1220 #, c-format msgid "return value of function with array return type is not a Python sequence" msgstr "el valor de retorno de la función con tipo de retorno array no es una secuencia Python" -#: plpy_typeio.c:1091 +#: plpy_typeio.c:1266 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "largo incorrecto de secuencia interna: tiene largo %d, pero se esperaba %d" + +#: plpy_typeio.c:1268 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "Para construir un array multidimensional, las secuencias internas deben tener todas el mismo largo." + +#: plpy_typeio.c:1347 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "literal de record no es válido: «%s»" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "Falta paréntesis izquierdo." + +#: plpy_typeio.c:1349 plpy_typeio.c:1550 #, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length %d while expected %d" -msgstr "los arrays multidimensionales deben contener expresiones de array con igual número de dimensiones. El valor de retorno de la función PL/Python tiene un tamaño de secuencia %d pero se esperaba %d" +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "Para retornar un tipo compuesto en un array, retorne el tipo compuesto como una tupla de Python, e.g., «[('foo',)]»." -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1396 #, c-format msgid "key \"%s\" not found in mapping" msgstr "la llave «%s» no fue encontrada en el mapa" -#: plpy_typeio.c:1214 +#: plpy_typeio.c:1397 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "Para retornar null en una columna, agregue el valor None al mapa, con llave llamada igual que la columna." -#: plpy_typeio.c:1265 +#: plpy_typeio.c:1450 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "el tamaño de la secuencia retornada no concuerda con el número de columnas de la fila" -#: plpy_typeio.c:1388 +#: plpy_typeio.c:1548 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "el atributo «%s» no existe en el objeto Python" -#: plpy_typeio.c:1391 +#: plpy_typeio.c:1551 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "Para retornar null en una columna, haga que el objeto retornado tenga un atributo llamado igual que la columna, con valor None." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "no se pudo convertir el objeto Unicode de Python a bytes" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "no se pudo extraer bytes desde la cadena codificada" - -#~ msgid "plan.status takes no arguments" -#~ msgstr "plan.status no lleva argumentos" - -#~ msgid "could not create the base SPI exceptions" -#~ msgstr "no se pudo crear las excepciones SPI basales" - -#~ msgid "the message is already specified" -#~ msgstr "el mensaje ya está definido" - -#~ msgid "cannot convert multidimensional array to Python list" -#~ msgstr "no se puede convertir array multidimensional a una lista Python" - -#~ msgid "PL/Python only supports one-dimensional arrays." -#~ msgstr "PL/Python sólo soporta arrays unidimensionales." - -#~ msgid "could not create new Python list" -#~ msgstr "no se pudo crear una nueva lista Python" - -#~ msgid "PL/Python does not support conversion to arrays of row types." -#~ msgstr "PL/Python no soporta la conversión de arrays a tipos de registro." - -#~ msgid "plpy.prepare does not support composite types" -#~ msgstr "plpy.prepare no soporta tipos compuestos" - -#~ msgid "Start a new session to use a different Python major version." -#~ msgstr "Inicie una nueva sesión para usar una versión mayor de Python diferente." - -#~ msgid "This session has previously used Python major version %d, and it is now attempting to use Python major version %d." -#~ msgstr "Esta sesión ha usado previamente la versión mayor de Python %d, y ahora está intentando usar la versión mayor %d." diff --git a/src/pl/plpython/po/fr.po b/src/pl/plpython/po/fr.po index 43988c08697..5de52a42136 100644 --- a/src/pl/plpython/po/fr.po +++ b/src/pl/plpython/po/fr.po @@ -6,10 +6,10 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-06 14:37+0000\n" -"PO-Revision-Date: 2017-07-06 18:07+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:07+0000\n" +"PO-Revision-Date: 2019-05-17 14:58+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" @@ -17,178 +17,189 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:78 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor attendait une requête ou un plan" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:161 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor prends une séquence dans son second argument" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:177 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "n'a pas pu exécuter le plan" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:180 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Séquence attendue de %d argument, %d obtenu : %s" msgstr[1] "Séquence attendue de %d arguments, %d obtenus : %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:329 #, c-format msgid "iterating a closed cursor" msgstr "itération d'un curseur fermé" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "itération d'un curseur dans une sous-transaction annulée" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:395 #, c-format msgid "fetch from a closed cursor" msgstr "récupérer à partir d'un curseur fermé" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:438 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" -msgstr "le résultat de la requête contient trop de lignes pour être intégré dans une liste Python" +msgstr "" +"le résultat de la requête contient trop de lignes pour être intégré dans une " +"liste Python" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:490 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "fermeture d'un curseur dans une sous-transaction annulée" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:143 #, c-format msgid "unsupported set function return mode" msgstr "mode de retour non supporté pour la fonction SET" -#: plpy_exec.c:141 +#: plpy_exec.c:144 #, c-format -msgid "PL/Python set-returning functions only support returning one value per call." +msgid "" +"PL/Python set-returning functions only support returning one value per call." msgstr "" "les fonctions PL/python renvoyant des ensembles supportent seulement une\n" "valeur renvoyée par appel." -#: plpy_exec.c:154 +#: plpy_exec.c:157 #, c-format msgid "returned object cannot be iterated" msgstr "l'objet renvoyé ne supporte pas les itérations" -#: plpy_exec.c:155 +#: plpy_exec.c:158 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "" "les fonctions PL/python renvoyant des ensembles doivent renvoyer un objet\n" "itérable" -#: plpy_exec.c:169 +#: plpy_exec.c:172 #, c-format msgid "error fetching next item from iterator" msgstr "erreur lors de la récupération du prochain élément de l'itérateur" -#: plpy_exec.c:210 +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "la procédure PL/python n'a pas renvoyé None" + +#: plpy_exec.c:219 #, c-format msgid "PL/Python function with return type \"void\" did not return None" -msgstr "la fonction PL/python avec un code de retour « void » ne renvoyait pas None" +msgstr "" +"la fonction PL/python avec un code de retour « void » ne renvoyait pas None" -#: plpy_exec.c:379 plpy_exec.c:405 +#: plpy_exec.c:375 plpy_exec.c:401 #, c-format msgid "unexpected return value from trigger procedure" msgstr "valeur de retour inattendue de la procédure trigger" -#: plpy_exec.c:380 +#: plpy_exec.c:376 #, c-format msgid "Expected None or a string." msgstr "Attendait None ou une chaîne de caractères." -#: plpy_exec.c:395 +#: plpy_exec.c:391 #, c-format -msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" +msgid "" +"PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "" "la fonction trigger PL/python a renvoyé « MODIFY » dans un trigger DELETE\n" "-- ignoré" -#: plpy_exec.c:406 +#: plpy_exec.c:402 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Attendait None, « OK », « SKIP » ou « MODIFY »." -#: plpy_exec.c:487 +#: plpy_exec.c:452 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "échec de PyList_SetItem() lors de l'initialisation des arguments" -#: plpy_exec.c:491 +#: plpy_exec.c:456 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "échec de PyDict_SetItemString() lors de l'initialisation des arguments" -#: plpy_exec.c:503 +#: plpy_exec.c:468 #, c-format -msgid "function returning record called in context that cannot accept type record" +msgid "" +"function returning record called in context that cannot accept type record" msgstr "" "fonction renvoyant le type record appelée dans un contexte qui ne peut pas\n" "accepter le type record" -#: plpy_exec.c:719 +#: plpy_exec.c:685 #, c-format msgid "while creating return value" msgstr "lors de la création de la valeur de retour" -#: plpy_exec.c:743 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "" -"n'a pas pu créer un nouveau dictionnaire lors de la construction des\n" -"arguments du trigger" - -#: plpy_exec.c:931 +#: plpy_exec.c:919 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] supprimé, ne peut pas modifier la ligne" -#: plpy_exec.c:936 +#: plpy_exec.c:924 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] n'est pas un dictionnaire" -#: plpy_exec.c:963 +#: plpy_exec.c:951 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "la clé TD[\"new\"] à la position ordinale %d n'est pas une chaîne" -#: plpy_exec.c:970 +#: plpy_exec.c:958 #, c-format -msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" +msgid "" +"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " +"row" msgstr "" "la clé « %s » trouvée dans TD[\"new\"] n'existe pas comme colonne\n" "de la ligne impactée par le trigger" -#: plpy_exec.c:975 +#: plpy_exec.c:963 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "ne peut pas initialiser l'attribut système « %s »" -#: plpy_exec.c:1046 +#: plpy_exec.c:968 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "ne peut pas initialiser la colonne générée « %s »" + +#: plpy_exec.c:1026 #, c-format msgid "while modifying trigger row" msgstr "lors de la modification de la ligne du trigger" -#: plpy_exec.c:1107 +#: plpy_exec.c:1087 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "annulation forcée d'une sous-transaction qui n'a jamais été quittée" @@ -201,7 +212,8 @@ msgstr "plusieurs bibliothèques Python sont présentes dans la session" #: plpy_main.c:126 #, c-format msgid "Only one Python major version can be used in one session." -msgstr "Seule une version majeure de Python peut être utilisée dans une session." +msgstr "" +"Seule une version majeure de Python peut être utilisée dans une session." #: plpy_main.c:142 #, c-format @@ -213,71 +225,66 @@ msgstr "erreur non récupérée dans l'initialisation" msgid "could not import \"__main__\" module" msgstr "n'a pas pu importer le module « __main__ »" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "n'a pas pu créer les globales" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "n'a pas pu initialiser les variables globales" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "procédure PL/python « %s »" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "fonction PL/python « %s »" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "bloc de code PL/Python anonyme" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 #, c-format msgid "could not import \"plpy\" module" msgstr "n'a pas pu importer le module « plpy »" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:204 #, c-format msgid "could not create the spiexceptions module" msgstr "n'a pas pu créer le module « spiexceptions »" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:212 #, c-format msgid "could not add the spiexceptions module" msgstr "n'a pas pu ajouter le module « spiexceptions »" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "n'a pas pu créer l'exception « %s »" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:280 #, c-format msgid "could not generate SPI exceptions" msgstr "n'a pas pu générer les exceptions SPI" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:448 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "n'a pas pu déballer les arguments dans plpy.elog" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:457 msgid "could not parse error message in plpy.elog" msgstr "n'a pas pu analyser le message d'erreur dans plpy.elog" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:474 #, c-format msgid "argument 'message' given by name and position" msgstr "argument 'message' donné par nom et position" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:501 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "'%s' est une argument mot-clé invalide pour cette fonction" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 #, c-format msgid "invalid SQLSTATE code" msgstr "code SQLSTATE invalide" @@ -287,283 +294,342 @@ msgstr "code SQLSTATE invalide" msgid "trigger functions can only be called as triggers" msgstr "les fonctions trigger peuvent seulement être appelées par des triggers" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "les fonctions PL/python ne peuvent pas renvoyer le type %s" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "les fonctions PL/python ne peuvent pas accepter le type %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "n'a pas pu compiler la fonction PL/python « %s »" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "n'a pas pu compiler le bloc de code anonyme PL/python" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 #, c-format msgid "command did not produce a result set" msgstr "la commande n'a pas fourni d'ensemble de résultats" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "le second argument de plpy.prepare doit être une séquence" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" -msgstr "plpy.prepare : le nom du type sur la position ordinale %d n'est pas une chaîne" +msgstr "" +"plpy.prepare : le nom du type sur la position ordinale %d n'est pas une " +"chaîne" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.prepare attendait une requête ou un plan" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute prends une séquence dans son second argument" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "échec de SPI_execute_plan : %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "échec de SPI_execute : %s" -#: plpy_subxactobject.c:122 +#: plpy_subxactobject.c:97 #, c-format msgid "this subtransaction has already been entered" msgstr "cette sous-transaction est en cours d'utilisation" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 #, c-format msgid "this subtransaction has already been exited" msgstr "déjà sorti de cette sous-transaction" -#: plpy_subxactobject.c:180 +#: plpy_subxactobject.c:155 #, c-format msgid "this subtransaction has not been entered" msgstr "cette sous-transaction n'a jamais été utilisée" -#: plpy_subxactobject.c:192 +#: plpy_subxactobject.c:167 #, c-format msgid "there is no subtransaction to exit from" msgstr "il n'y a pas de transaction à quitter" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "n'a pas pu créer le nouveau dictionnaire" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "n'a pas pu importer un module pour le constructeur Decimal" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "pas d'attribut Decimal dans le module" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "échec de la conversion numeric vers Decimal" -#: plpy_typeio.c:773 +#: plpy_typeio.c:915 #, c-format msgid "could not create bytes representation of Python object" msgstr "n'a pas pu créer une représentation octets de l'objet Python" -#: plpy_typeio.c:882 +#: plpy_typeio.c:1063 #, c-format msgid "could not create string representation of Python object" -msgstr "n'a pas pu créer une représentation chaîne de caractères de l'objet Python" +msgstr "" +"n'a pas pu créer une représentation chaîne de caractères de l'objet Python" -#: plpy_typeio.c:893 +#: plpy_typeio.c:1074 #, c-format -msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" -msgstr "n'a pas pu convertir l'objet Python en csting : la représentation de la chaîne Python contient des octets nuls" +msgid "" +"could not convert Python object into cstring: Python string representation " +"appears to contain null bytes" +msgstr "" +"n'a pas pu convertir l'objet Python en csting : la représentation de la " +"chaîne Python contient des octets nuls" -#: plpy_typeio.c:950 +#: plpy_typeio.c:1183 #, c-format -msgid "malformed record literal: \"%s\"" -msgstr "enregistrement litéral invalide : « %s »" +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "le nombre de dimensions du tableau dépasse le maximum autorisé (%d)" -#: plpy_typeio.c:951 +#: plpy_typeio.c:1187 #, c-format -msgid "Missing left parenthesis." -msgstr "Parenthèse gauche manquante" +msgid "could not determine sequence length for function return value" +msgstr "" +"n'a pas pu déterminer la longueur de la séquence pour la valeur de retour de " +"la fonction" -#: plpy_typeio.c:952 plpy_typeio.c:1390 +#: plpy_typeio.c:1190 plpy_typeio.c:1194 #, c-format -msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." -msgstr "Pour renvoyer un type composite dans un tableau, renvoyez le type composite sous la forme d'un tuple Python, c'est-à-dire \"[('foo',)]\"." +msgid "array size exceeds the maximum allowed" +msgstr "la taille du tableau dépasse le maximum permis" -#: plpy_typeio.c:1001 +#: plpy_typeio.c:1220 #, c-format -msgid "number of array dimensions exceeds the maximum allowed (%d)" -msgstr "le nombre de dimensions du tableau dépasse le maximum autorisé (%d)" +msgid "" +"return value of function with array return type is not a Python sequence" +msgstr "" +"la valeur de retour de la fonction de type tableau n'est pas une séquence " +"Python" -#: plpy_typeio.c:1005 +#: plpy_typeio.c:1266 #, c-format -msgid "cannot determine sequence length for function return value" -msgstr "ne peut pas déterminer la longueur de la séquence pour la valeur de retour de la fonction" +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "" +"mauvaise longueur de la séquence interne : a une longueur %d, mais %d était " +"attendu" -#: plpy_typeio.c:1008 plpy_typeio.c:1012 +#: plpy_typeio.c:1268 #, c-format -msgid "array size exceeds the maximum allowed" -msgstr "la taille du tableau dépasse le maximum permis" +msgid "" +"To construct a multidimensional array, the inner sequences must all have the " +"same length." +msgstr "" +"Pour construire un tableau multidimensionnel, les séquences internes doivent " +"toutes avoir la même longueur." -#: plpy_typeio.c:1038 +#: plpy_typeio.c:1347 #, c-format -msgid "return value of function with array return type is not a Python sequence" -msgstr "la valeur de retour de la fonction de type tableau n'est pas une séquence Python" +msgid "malformed record literal: \"%s\"" +msgstr "enregistrement litéral invalide : « %s »" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "Parenthèse gauche manquante" -#: plpy_typeio.c:1091 +#: plpy_typeio.c:1349 plpy_typeio.c:1550 #, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length %d while expected %d" +msgid "" +"To return a composite type in an array, return the composite type as a " +"Python tuple, e.g., \"[('foo',)]\"." msgstr "" -"les tableaux multidimensionnels doivent avoir des expressions de tableaux\n" -"avec des dimensions correspondantes. La valeur de retour de la fonction\n" -"PL/Python a une longueur de séquence %d alors que %d est attendue" +"Pour renvoyer un type composite dans un tableau, renvoyez le type composite " +"sous la forme d'un tuple Python, c'est-à-dire \"[('foo',)]\"." -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1396 #, c-format msgid "key \"%s\" not found in mapping" msgstr "la clé « %s » introuvable dans la correspondance" -#: plpy_typeio.c:1214 +#: plpy_typeio.c:1397 #, c-format -msgid "To return null in a column, add the value None to the mapping with the key named after the column." +msgid "" +"To return null in a column, add the value None to the mapping with the key " +"named after the column." msgstr "" "Pour renvoyer NULL dans une colonne, ajoutez la valeur None à la\n" "correspondance de la clé nommée d'après la colonne." -#: plpy_typeio.c:1265 +#: plpy_typeio.c:1450 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "" "la longueur de la séquence renvoyée ne correspondait pas au nombre de\n" "colonnes dans la ligne" -#: plpy_typeio.c:1388 +#: plpy_typeio.c:1548 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "l'attribut « %s » n'existe pas dans l'objet Python" -#: plpy_typeio.c:1391 +#: plpy_typeio.c:1551 #, c-format -msgid "To return null in a column, let the returned object have an attribute named after column with value None." +msgid "" +"To return null in a column, let the returned object have an attribute named " +"after column with value None." msgstr "" -"Pour renvoyer NULL dans une colonne, faites en sorte que l'objet renvoyé ait\n" +"Pour renvoyer NULL dans une colonne, faites en sorte que l'objet renvoyé " +"ait\n" "un attribut nommé suivant la colonne de valeur None." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "n'a pas pu convertir l'objet Unicode Python en octets" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "n'a pas pu extraire les octets de la chaîne encodée" -#~ msgid "could not create the base SPI exceptions" -#~ msgstr "n'a pas pu créer les exceptions SPI de base" +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "" +#~ "n'a pas pu créer un nouveau dictionnaire lors de la construction des\n" +#~ "arguments du trigger" -#~ msgid "Python major version mismatch in session" -#~ msgstr "Différence de version majeure de Python dans la session" +#~ msgid "could not create globals" +#~ msgstr "n'a pas pu créer les globales" -#~ msgid "This session has previously used Python major version %d, and it is now attempting to use Python major version %d." -#~ msgstr "" -#~ "Cette session a auparavant utilisé la version majeure %d de Python et elle\n" -#~ "essaie maintenant d'utiliser la version majeure %d." +#~ msgid "could not create exception \"%s\"" +#~ msgstr "n'a pas pu créer l'exception « %s »" -#~ msgid "Start a new session to use a different Python major version." -#~ msgstr "" -#~ "Lancez une nouvelle session pour utiliser une version majeure différente de\n" -#~ "Python." +#~ msgid "could not create new dictionary" +#~ msgstr "n'a pas pu créer le nouveau dictionnaire" -#~ msgid "PL/Python function \"%s\" could not execute plan" -#~ msgstr "la fonction PL/python « %s » n'a pas pu exécuter un plan" +#~ msgid "plan.status takes no arguments" +#~ msgstr "plan.status ne prends pas d'arguments" -#~ msgid "could not create string representation of Python object in PL/Python function \"%s\" while creating return value" -#~ msgstr "" -#~ "n'a pas pu créer la représentation en chaîne de caractère de l'objet\n" -#~ "Python dans la fonction PL/python « %s » lors de la création de la valeur\n" -#~ "de retour" +#~ msgid "cannot convert multidimensional array to Python list" +#~ msgstr "ne peut pas convertir un tableau multidimensionnel en liste Python" + +#~ msgid "PL/Python only supports one-dimensional arrays." +#~ msgstr "PL/Python supporte seulement les tableaux uni-dimensionnels." -#~ msgid "could not compute string representation of Python object in PL/Python function \"%s\" while modifying trigger row" +#~ msgid "could not create new Python list" +#~ msgstr "n'a pas pu créer la nouvelle liste Python" + +#~ msgid "the message is already specified" +#~ msgstr "le message est déjà spécifié" + +#~ msgid "plpy.prepare does not support composite types" +#~ msgstr "plpy.prepare ne supporte pas les types composites" + +#~ msgid "PL/Python does not support conversion to arrays of row types." #~ msgstr "" -#~ "n'a pas pu traiter la représentation de la chaîne d'un objet Python dans\n" -#~ "la fonction PL/Python « %s » lors de la modification de la ligne du trigger" +#~ "PL/Python ne supporte pas les conversions vers des tableaux de types row." -#~ msgid "PL/Python function \"%s\" failed" -#~ msgstr "échec de la fonction PL/python « %s »" +#~ msgid "unrecognized error in PLy_spi_execute_fetch_result" +#~ msgstr "erreur inconnue dans PLy_spi_execute_fetch_result" -#~ msgid "out of memory" -#~ msgstr "mémoire épuisée" +#~ msgid "PyCObject_AsVoidPtr() failed" +#~ msgstr "échec de PyCObject_AsVoidPtr()" -#~ msgid "PL/Python: %s" -#~ msgstr "PL/python : %s" +#~ msgid "PyCObject_FromVoidPtr() failed" +#~ msgstr "échec de PyCObject_FromVoidPtr()" -#~ msgid "could not create procedure cache" -#~ msgstr "n'a pas pu créer le cache de procédure" +#~ msgid "transaction aborted" +#~ msgstr "transaction annulée" -#~ msgid "unrecognized error in PLy_spi_execute_query" -#~ msgstr "erreur inconnue dans PLy_spi_execute_query" +#~ msgid "invalid arguments for plpy.prepare" +#~ msgstr "arguments invalides pour plpy.prepare" + +#~ msgid "unrecognized error in PLy_spi_prepare" +#~ msgstr "erreur inconnue dans PLy_spi_prepare" #~ msgid "unrecognized error in PLy_spi_execute_plan" #~ msgstr "erreur inconnue dans PLy_spi_execute_plan" -#~ msgid "unrecognized error in PLy_spi_prepare" -#~ msgstr "erreur inconnue dans PLy_spi_prepare" +#~ msgid "unrecognized error in PLy_spi_execute_query" +#~ msgstr "erreur inconnue dans PLy_spi_execute_query" -#~ msgid "invalid arguments for plpy.prepare" -#~ msgstr "arguments invalides pour plpy.prepare" +#~ msgid "could not create procedure cache" +#~ msgstr "n'a pas pu créer le cache de procédure" -#~ msgid "transaction aborted" -#~ msgstr "transaction annulée" +#~ msgid "PL/Python: %s" +#~ msgstr "PL/python : %s" -#~ msgid "PyCObject_FromVoidPtr() failed" -#~ msgstr "échec de PyCObject_FromVoidPtr()" +#~ msgid "out of memory" +#~ msgstr "mémoire épuisée" -#~ msgid "PyCObject_AsVoidPtr() failed" -#~ msgstr "échec de PyCObject_AsVoidPtr()" +#~ msgid "PL/Python function \"%s\" failed" +#~ msgstr "échec de la fonction PL/python « %s »" -#~ msgid "unrecognized error in PLy_spi_execute_fetch_result" -#~ msgstr "erreur inconnue dans PLy_spi_execute_fetch_result" +#~ msgid "" +#~ "could not compute string representation of Python object in PL/Python " +#~ "function \"%s\" while modifying trigger row" +#~ msgstr "" +#~ "n'a pas pu traiter la représentation de la chaîne d'un objet Python dans\n" +#~ "la fonction PL/Python « %s » lors de la modification de la ligne du " +#~ "trigger" -#~ msgid "PL/Python does not support conversion to arrays of row types." -#~ msgstr "PL/Python ne supporte pas les conversions vers des tableaux de types row." +#~ msgid "" +#~ "could not create string representation of Python object in PL/Python " +#~ "function \"%s\" while creating return value" +#~ msgstr "" +#~ "n'a pas pu créer la représentation en chaîne de caractère de l'objet\n" +#~ "Python dans la fonction PL/python « %s » lors de la création de la " +#~ "valeur\n" +#~ "de retour" -#~ msgid "plpy.prepare does not support composite types" -#~ msgstr "plpy.prepare ne supporte pas les types composites" +#~ msgid "PL/Python function \"%s\" could not execute plan" +#~ msgstr "la fonction PL/python « %s » n'a pas pu exécuter un plan" -#~ msgid "the message is already specified" -#~ msgstr "le message est déjà spécifié" +#~ msgid "Start a new session to use a different Python major version." +#~ msgstr "" +#~ "Lancez une nouvelle session pour utiliser une version majeure différente " +#~ "de\n" +#~ "Python." -#~ msgid "could not create new Python list" -#~ msgstr "n'a pas pu créer la nouvelle liste Python" +#~ msgid "" +#~ "This session has previously used Python major version %d, and it is now " +#~ "attempting to use Python major version %d." +#~ msgstr "" +#~ "Cette session a auparavant utilisé la version majeure %d de Python et " +#~ "elle\n" +#~ "essaie maintenant d'utiliser la version majeure %d." -#~ msgid "PL/Python only supports one-dimensional arrays." -#~ msgstr "PL/Python supporte seulement les tableaux uni-dimensionnels." +#~ msgid "Python major version mismatch in session" +#~ msgstr "Différence de version majeure de Python dans la session" -#~ msgid "cannot convert multidimensional array to Python list" -#~ msgstr "ne peut pas convertir un tableau multidimensionnel en liste Python" +#~ msgid "could not create the base SPI exceptions" +#~ msgstr "n'a pas pu créer les exceptions SPI de base" -#~ msgid "plan.status takes no arguments" -#~ msgstr "plan.status ne prends pas d'arguments" +#~ msgid "" +#~ "multidimensional arrays must have array expressions with matching " +#~ "dimensions. PL/Python function return value has sequence length %d while " +#~ "expected %d" +#~ msgstr "" +#~ "les tableaux multidimensionnels doivent avoir des expressions de " +#~ "tableaux\n" +#~ "avec des dimensions correspondantes. La valeur de retour de la fonction\n" +#~ "PL/Python a une longueur de séquence %d alors que %d est attendue" diff --git a/src/pl/plpython/po/it.po b/src/pl/plpython/po/it.po index bf8ccb7ddc7..32e65293565 100644 --- a/src/pl/plpython/po/it.po +++ b/src/pl/plpython/po/it.po @@ -1,193 +1,191 @@ # -# Translation of plpython to Italian -# PostgreSQL Project +# plpython.po +# Italian message translation file for plpython # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Flavio Spada -# * Daniele Varrazzo +# Daniele Varrazzo , 2012-2017. +# Flavio Spada # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" -"Project-Id-Version: plpython (PostgreSQL) 10\n" +"Project-Id-Version: plpython (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-22 22:37+0000\n" -"PO-Revision-Date: 2017-05-29 17:46+0100\n" +"POT-Creation-Date: 2018-10-08 14:07+0000\n" +"PO-Revision-Date: 2018-10-08 23:11+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Poedit 1.8.7.1\n" +"X-Generator: Poedit 2.0.6\n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:101 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor richiede una query o un piano" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:184 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor richiede una sequenza come secondo argomento" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:200 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "esecuzione del piano fallita" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:203 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Attesa sequenza di %d argomento, ricevuti %d: %s" msgstr[1] "Attesa sequenza di %d argomenti, ricevuti %d: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:352 #, c-format msgid "iterating a closed cursor" msgstr "iterazione di un cursore chiuso" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "iterazione di un cursore in una sotto-transazione interrotta" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:418 #, c-format msgid "fetch from a closed cursor" msgstr "lettura da un cursore chiuso" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:461 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "il risultato della query ha troppe righe per una lista Python" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:512 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "chiusura di un cursore in una sotto-transazione interrotta" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:142 #, c-format msgid "unsupported set function return mode" msgstr "modalità di ritorno della funzione set non supportata" -#: plpy_exec.c:141 +#: plpy_exec.c:143 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "Le funzioni PL/Python che restituiscono insiemi supportano la restituzione di un solo valore per chiamata." -#: plpy_exec.c:154 +#: plpy_exec.c:156 #, c-format msgid "returned object cannot be iterated" msgstr "l'oggetto restituito non può essere iterato" -#: plpy_exec.c:155 +#: plpy_exec.c:157 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "Le funzioni PL/Python che restituiscono insiemi devono restituire un oggetto iterabile." -#: plpy_exec.c:169 +#: plpy_exec.c:171 #, c-format msgid "error fetching next item from iterator" msgstr "errore nell'ottenere l'elemento successivo dall'iteratore" -#: plpy_exec.c:210 +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "la procedura PL/Python non ha restituito None" + +#: plpy_exec.c:218 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "la funzione PL/Python che restituisce \"void\" non ha restituito None" -#: plpy_exec.c:379 plpy_exec.c:405 +#: plpy_exec.c:374 plpy_exec.c:400 #, c-format msgid "unexpected return value from trigger procedure" msgstr "la prodedura trigger ha restituito un valore inatteso" -#: plpy_exec.c:380 +#: plpy_exec.c:375 #, c-format msgid "Expected None or a string." msgstr "Atteso None o una stringa." -#: plpy_exec.c:395 +#: plpy_exec.c:390 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "la funzione trigger PL/Python ha restituito \"MODIFY\" in un trigger DELETE -- ignorato" -#: plpy_exec.c:406 +#: plpy_exec.c:401 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Atteso None, \"OK\", \"SKIP\", o \"MODIFY\"." -#: plpy_exec.c:487 +#: plpy_exec.c:451 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() è fallita durante l'impostazione degli argomenti" -#: plpy_exec.c:491 +#: plpy_exec.c:455 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() è fallita durante l'impostazione degli argomenti" -#: plpy_exec.c:503 +#: plpy_exec.c:467 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "la funzione che restituisce un record è chiamata in un contesto che non può accettare il tipo record" -#: plpy_exec.c:719 +#: plpy_exec.c:684 #, c-format msgid "while creating return value" msgstr "durante la creazione del valore da restituire" -#: plpy_exec.c:743 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "creazione del nuovo dizionario nella costruzione degli argomenti del trigger fallita" - -#: plpy_exec.c:931 +#: plpy_exec.c:909 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] cancellato, non è possibile modificare la riga" -#: plpy_exec.c:936 +#: plpy_exec.c:914 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] non è un dizionario" -#: plpy_exec.c:963 +#: plpy_exec.c:941 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "la chiave di dizionario TD[\"new\"] alla posizione %d non è una stringa" -#: plpy_exec.c:970 +#: plpy_exec.c:948 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "la chiave \"%s\" trovata in TD[\"new\"] non esiste come colonna nella riga del trigger" -#: plpy_exec.c:975 +#: plpy_exec.c:953 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "non è possibile impostare l'attributo di sistema \"%s\"" -#: plpy_exec.c:1046 +#: plpy_exec.c:1011 #, c-format msgid "while modifying trigger row" msgstr "durante la modifica della riga trigger" -#: plpy_exec.c:1107 +#: plpy_exec.c:1072 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "interruzione forzata di una sotto-transazione che non è terminata" @@ -212,71 +210,66 @@ msgstr "errore non catturato durante l'inizializzazione" msgid "could not import \"__main__\" module" msgstr "importazione del modulo \"__main__\"" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "creazione delle variabili globali fallita" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "inizializzazione delle variabili globali fallita" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "procedura PL/Python \"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "funzione PL/Python \"%s\"" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "blocco di codice anonimo in PL/Python" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 #, c-format msgid "could not import \"plpy\" module" msgstr "importazione del modulo \"plpy\" fallita" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:210 #, c-format msgid "could not create the spiexceptions module" msgstr "creazione del modulo spiexceptions fallita" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:218 #, c-format msgid "could not add the spiexceptions module" msgstr "aggiunta del modulo spiexceptions fallita" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "creazione dell'eccezione \"%s\" fallita" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:286 #, c-format msgid "could not generate SPI exceptions" msgstr "generazione delle eccezioni SPI fallita" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:454 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "non è stato possibile espandere gli argomenti in plpy.elog" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:463 msgid "could not parse error message in plpy.elog" msgstr "non è stato possibile interpretare il messaggio di errore in plpy.elog" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:480 #, c-format -msgid "Argument 'message' given by name and position" -msgstr "Parametro 'message' dato con nome e posizione" +msgid "argument 'message' given by name and position" +msgstr "parametro 'message' dato con nome e posizione" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:507 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "'%s' è un nome di argomento non valido per questa funzione" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 #, c-format msgid "invalid SQLSTATE code" msgstr "codice SQLSTATE non valido" @@ -286,57 +279,57 @@ msgstr "codice SQLSTATE non valido" msgid "trigger functions can only be called as triggers" msgstr "le funzioni trigger possono essere chiamate esclusivamente da trigger" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "le funzioni PL/Python non possono restituire il tipo %s" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "le funzioni PL/Python non possono accettare il tipo %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "compilazione della funzione PL/Python \"%s\" fallita" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "compilazione del blocco di codice anonimo PL/Python fallita" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 #, c-format msgid "command did not produce a result set" msgstr "il comando non ha prodotto risultati" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "il secondo argomento di plpy.prepare deve essere una sequenza" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: il nome del tipo nella posizione %d non è una stringa" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute si aspetta una query o un plan" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute richiede una sequenza come secondo argomento" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan ha fallito: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute ha fallito: %s" @@ -361,112 +354,112 @@ msgstr "non si è entrati in questa sotto-transazione" msgid "there is no subtransaction to exit from" msgstr "non c'è nessuna transazione da cui uscire" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "creazione del nuovo dizionario fallita" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "importazione di un modulo per il costrutto Decimal fallita" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "attributo Decimal non trovato nel modulo" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "conversione da numeric a Decimal fallita" -#: plpy_typeio.c:772 +#: plpy_typeio.c:908 #, c-format msgid "could not create bytes representation of Python object" msgstr "creazione della rappresentazione in byte dell'oggetto Python fallita" -#: plpy_typeio.c:881 +#: plpy_typeio.c:1056 #, c-format msgid "could not create string representation of Python object" msgstr "creazione della rappresentazione stringa dell'oggetto Python fallita" -#: plpy_typeio.c:892 +#: plpy_typeio.c:1067 #, c-format msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" msgstr "conversione dell'oggetto Python in cstring fallita: la rappresentazione stringa Python sembra contenere byte null" -#: plpy_typeio.c:949 -#, c-format -msgid "malformed record literal: \"%s\"" -msgstr "letterale di record non corretto: \"%s\"" - -#: plpy_typeio.c:950 -#, c-format -msgid "Missing left parenthesis." -msgstr "Parentesi aperta mancante." - -#: plpy_typeio.c:951 plpy_typeio.c:1389 -#, c-format -msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g. \"[('foo')]\"" -msgstr "Per restutuire un tipo composito in un array, restituisci il tipo composito come tupla Python, per esempio \"[('foo')]\"" - -#: plpy_typeio.c:1000 +#: plpy_typeio.c:1176 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "il numero di dimensioni dell'array supera il massimo consentito (%d)" -#: plpy_typeio.c:1004 +#: plpy_typeio.c:1180 #, c-format -msgid "cannot determine sequence length for function return value" +msgid "could not determine sequence length for function return value" msgstr "errore nel determinare la lunghezza della sequenza per il valore di ritorno della funzione" -#: plpy_typeio.c:1007 plpy_typeio.c:1011 +#: plpy_typeio.c:1183 plpy_typeio.c:1187 #, c-format msgid "array size exceeds the maximum allowed" msgstr "la dimensione dell'array supera il massimo consentito" -#: plpy_typeio.c:1037 +#: plpy_typeio.c:1213 #, c-format msgid "return value of function with array return type is not a Python sequence" msgstr "il valore restituito dalla funzione con tipo restituito array non è una sequenza Python" -#: plpy_typeio.c:1090 +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "lunghezza errata della sequenza interna: la lunghezza è %d ma era atteso %d" + +#: plpy_typeio.c:1261 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "Per costruire un array multidimensionale le sequenze interne devono avere tutte la stessa lunghezza." + +#: plpy_typeio.c:1340 #, c-format -msgid "multidimensional arrays must have array expressions with matching dimensions. PL/Python function return value has sequence length %d while expected %d" -msgstr "gli array multidimensionali devono avere espressioni array di dimensioni corrispondenti. il valore di ritorno della funzione PL/Python ha una sequenza di lungezza %d, mentre era atteso %d" +msgid "malformed record literal: \"%s\"" +msgstr "letterale di record non corretto: \"%s\"" -#: plpy_typeio.c:1212 +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "Parentesi aperta mancante." + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "Per restutuire un tipo composito in un array, restituisci il tipo composito come tupla Python, per esempio \"[('foo',)]\" " + +#: plpy_typeio.c:1389 #, c-format msgid "key \"%s\" not found in mapping" msgstr "la chiave \"%s\" non è stata trovata nel dizionario" -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1390 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "Per restituire null in una colonna, inserire nella mappa il valore None con una chiave chiamata come la colonna." -#: plpy_typeio.c:1264 +#: plpy_typeio.c:1443 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "la lunghezza della sequenza ritornata non rispetta il numero di colonne presenti nella riga" -#: plpy_typeio.c:1387 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "l'attributo \"%s\" non esiste nell'oggetto Python" -#: plpy_typeio.c:1390 +#: plpy_typeio.c:1544 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "Per restituire null in una colonna, l'oggetto restituito deve avere un attributo chiamato come la colonna con valore None." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "conversione dell'oggetto Unicode Python in byte fallita" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "estrazione dei byte dalla stringa codificata fallita" diff --git a/src/pl/plpython/po/ja.po b/src/pl/plpython/po/ja.po index 5a5040ee0b5..a663498d5fa 100644 --- a/src/pl/plpython/po/ja.po +++ b/src/pl/plpython/po/ja.po @@ -1,447 +1,466 @@ # LANGUAGE message translation file for plpython -# Copyright (C) 2009 PostgreSQL Global Development Group +# Copyright (C) 2018 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. +# Honda Shigehiro , 2012. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.1 beta2\n" +"Project-Id-Version: plpython (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-08-11 16:28+0900\n" -"PO-Revision-Date: 2012-08-11 16:37+0900\n" -"Last-Translator: Honda Shigehiro \n" +"POT-Creation-Date: 2018-08-31 16:22+0900\n" +"PO-Revision-Date: 2018-08-21 20:45+0900\n" +"Last-Translator: Kyotaro Horiguchi \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.5.4\n" -#: plpy_cursorobject.c:98 +#: plpy_cursorobject.c:101 #, c-format msgid "plpy.cursor expected a query or a plan" -msgstr "plpy.cursorã¯ã‚¯ã‚¨ãƒªãƒ¼ã‚‚ã—ãã¯å®Ÿè¡Œè¨ˆç”»ã‚’期待ã—ã¦ã„ã¾ã—ãŸ" +msgstr "plpy.cursor ã¯å•ã„åˆã‚ã›ã‚‚ã—ãã¯å®Ÿè¡Œè¨ˆç”»ã‚’期待ã—ã¦ã„ã¾ã—ãŸ" -#: plpy_cursorobject.c:171 +#: plpy_cursorobject.c:184 #, c-format msgid "plpy.cursor takes a sequence as its second argument" -msgstr "plpy.cursorã¯ç¬¬äºŒå¼•æ•°ã¨ã—ã¦ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’å–りã¾ã™" +msgstr "plpy.cursor ã¯ç¬¬äºŒå¼•æ•°ã¨ã—ã¦ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’å–りã¾ã™" -#: plpy_cursorobject.c:187 plpy_spi.c:222 +#: plpy_cursorobject.c:200 plpy_spi.c:211 #, c-format msgid "could not execute plan" -msgstr "プランを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "実行計画を実行ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_cursorobject.c:190 plpy_spi.c:225 +#: plpy_cursorobject.c:203 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" -msgstr[0] "%d 番目ã®å¼•æ•°ã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’期待ã—ã¦ã„ã¾ã—ãŸãŒã€%d ãŒç¾ã‚Œã¾ã—ãŸï¼š%s" +msgstr[0] "%d 個ã®å¼•æ•°ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’期待ã—ã¦ã„ã¾ã—ãŸãŒã€å€‹æ•°ã¯ %d ã§ã—ãŸï¼š%s" -#: plpy_cursorobject.c:340 +#: plpy_cursorobject.c:352 #, c-format msgid "iterating a closed cursor" -msgstr "クローズã•れãŸã‚«ãƒ¼sã‚‹ã®å復" +msgstr "å復利用ã—よã†ã¨ã—ã¦ã„るカーソルã¯ã€ã™ã§ã«ã‚¯ãƒ­ãƒ¼ã‚ºã•れã¦ã„ã¾ã™" -#: plpy_cursorobject.c:348 plpy_cursorobject.c:415 +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 #, c-format msgid "iterating a cursor in an aborted subtransaction" -msgstr "アボートã•れãŸã‚µãƒ–トランザクション内ã®ã‚«ãƒ¼ã‚½ãƒ«ã®å復" +msgstr "中断ã•れãŸã‚µãƒ–トランザクションã®ä¸­ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’å復利用ã—よã†ã¨ã—ã¦ã„ã¾ã™" -#: plpy_cursorobject.c:407 +#: plpy_cursorobject.c:418 #, c-format msgid "fetch from a closed cursor" msgstr "クローズã•れãŸã‚«ãƒ¼ã‚½ãƒ«ã‹ã‚‰ã®ãƒ•ェッãƒ" -#: plpy_cursorobject.c:486 +#: plpy_cursorobject.c:461 plpy_spi.c:409 +#, c-format +msgid "query result has too many rows to fit in a Python list" +msgstr "å•ã„åˆã‚ã›ã®çµæžœã«å«ã¾ã‚Œã‚‹è¡Œæ•°ãŒã€Python ã®ãƒªã‚¹ãƒˆã«å¯¾ã—ã¦å¤šã™ãŽã¾ã™" + +#: plpy_cursorobject.c:512 #, c-format msgid "closing a cursor in an aborted subtransaction" -msgstr "アボートã•れãŸã‚µãƒ–トランザクションã«ãŠã‘るカーソルクローズ" +msgstr "中断ã•れãŸã‚µãƒ–トランザクションã®ä¸­ã§ã‚«ãƒ¼ã‚½ãƒ«ã‚’クローズã—よã†ã¨ã—ã¦ã„ã¾ã™" -#: plpy_elog.c:103 plpy_elog.c:104 plpy_plpymodule.c:420 +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:90 +#: plpy_exec.c:142 #, c-format msgid "unsupported set function return mode" -msgstr "未サãƒãƒ¼ãƒˆã®é›†åˆé–¢æ•°ãƒªã‚¿ãƒ¼ãƒ³ãƒ¢ãƒ¼ãƒ‰ã§ã™" +msgstr "未サãƒãƒ¼ãƒˆã®é›†åˆé–¢æ•°ãƒªã‚¿ãƒ¼ãƒ³ãƒ¢ãƒ¼ãƒ‰ã§ã™ã€‚" -#: plpy_exec.c:91 +#: plpy_exec.c:143 #, c-format -msgid "PL/Python set-returning functions only support returning only value per call." -msgstr "PL/Python ã®é›†åˆã‚’è¿”ã™é–¢æ•°ã§ã¯ã€ï¼‘回ã®ã‚³ãƒ¼ãƒ«ã®ãŸã³ã«å€¤ã ã‘ã‚’è¿”ã™ã“ã¨ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™" +msgid "PL/Python set-returning functions only support returning one value per call." +msgstr "PL/Python ã®é›†åˆã‚’è¿”ã™é–¢æ•°ã§ã¯ã€ï¼‘回ã®å‘¼ã³å‡ºã—ã«å¯¾ã—ã¦ï¼‘ã¤ã®å€¤ã‚’è¿”ã™ã“ã¨ã®ã¿ãŒã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã™ã€‚" -#: plpy_exec.c:103 +#: plpy_exec.c:156 #, c-format msgid "returned object cannot be iterated" -msgstr "è¿”ã•れãŸã‚ªãƒ–ジェクトã¯å復é©ç”¨ã§ãã¾ã›ã‚“" +msgstr "è¿”ã•れãŸã‚ªãƒ–ジェクトã¯å復利用ã§ãã¾ã›ã‚“" -#: plpy_exec.c:104 +#: plpy_exec.c:157 #, c-format msgid "PL/Python set-returning functions must return an iterable object." -msgstr "PL/Python ã®é›†åˆã‚’è¿”ã™é–¢æ•°ã§ã¯ã€ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ï¼ˆå復å­ï¼‰ã‚ªãƒ–ジェクトを返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgstr "PL/Python ã®é›†åˆã‚’è¿”ã™é–¢æ•°ã¯ã€ã‚¤ãƒ†ãƒ¬ãƒ¼ã‚¿ï¼ˆå復利用å¯èƒ½ï¼‰ã‚ªãƒ–ジェクトを返ã•ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" -#: plpy_exec.c:129 +#: plpy_exec.c:171 #, c-format msgid "error fetching next item from iterator" msgstr "イテレータ(å復å­ï¼‰ã‹ã‚‰æ¬¡ã®é …目をフェッãƒï¼ˆå–り出ã—)ã§ãã¾ã›ã‚“" -#: plpy_exec.c:164 +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python プロシージャ㌠None ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" + +#: plpy_exec.c:218 #, c-format msgid "PL/Python function with return type \"void\" did not return None" -msgstr "\"void\" 型を返㙠PL/Python 関数㯠None 型を返ã—ã¾ã›ã‚“" +msgstr "戻り値㌠\"void\" åž‹ã§ã‚ã‚‹ PL/Python 関数㌠None ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_exec.c:288 plpy_exec.c:314 +#: plpy_exec.c:374 plpy_exec.c:400 #, c-format msgid "unexpected return value from trigger procedure" -msgstr "トリガー手続ãã‹ã‚‰æœŸå¾…ã—ãªã„戻り値ãŒè¿”ã•れã¾ã—ãŸ" +msgstr "トリガプロシージャã‹ã‚‰æœŸå¾…ã—ãªã„戻り値ãŒè¿”ã•れã¾ã—ãŸ" -#: plpy_exec.c:289 +#: plpy_exec.c:375 #, c-format msgid "Expected None or a string." msgstr "None ã‚‚ã—ãã¯æ–‡å­—列を期待ã—ã¦ã„ã¾ã—ãŸã€‚" -#: plpy_exec.c:304 +#: plpy_exec.c:390 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" -msgstr "PL/Python トリガー関数ãŒã€DELETE トリガー㧠\"MODIFY\" ã‚’è¿”ã—ã¾ã—ãŸ-- 無視ã—ã¾ã—ãŸ" +msgstr "PL/Python トリガ関数ãŒã€DELETE トリガ㧠\"MODIFY\" ã‚’è¿”ã—ã¾ã—ãŸ-- 無視ã•れã¾ã—ãŸ" -#: plpy_exec.c:315 +#: plpy_exec.c:401 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "None, \"OK\", \"SKIP\", \"MODIFY\" ã®ã„ãšã‚Œã‹ã‚’期待ã—ã¦ã„ã¾ã—ãŸã€‚" -#: plpy_exec.c:396 +#: plpy_exec.c:451 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "引数を設定ã™ã‚‹éš›ã«ã€PyList_SetItem() ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: plpy_exec.c:400 +#: plpy_exec.c:455 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "引数を設定ã™ã‚‹éš›ã«ã€PyDict_SetItemString() ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: plpy_exec.c:412 +#: plpy_exec.c:467 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "レコード型をå—ã‘付ã‘られãªã„コンテキストã§ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã³å‡ºã•れã¾ã—ãŸ" -#: plpy_exec.c:450 +#: plpy_exec.c:684 #, c-format msgid "while creating return value" msgstr "戻り値を生æˆã™ã‚‹éš›ã«" -#: plpy_exec.c:474 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "トリガーã®å¼•æ•°ã‚’æ§‹æˆä¸­ã«ã€æ–°ã—ã„辞書を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: plpy_exec.c:664 +#: plpy_exec.c:909 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" -msgstr "TD[\"new\"] ã¯å‰Šé™¤ã•れã¾ã—ãŸã€‚ã‚‚ã¯ã‚„変更ã§ãã¾ã›ã‚“" +msgstr "TD[\"new\"] ã¯å‰Šé™¤ã•れã¾ã—ãŸã€‚行を変更ã§ãã¾ã›ã‚“。" -#: plpy_exec.c:667 +#: plpy_exec.c:914 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] ã¯è¾žæ›¸ã§ã¯ã‚りã¾ã›ã‚“" -#: plpy_exec.c:691 +#: plpy_exec.c:941 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "TD[\"new\"] 辞書ã®%d番目ã®ã‚­ãƒ¼ãŒæ–‡å­—列ã§ã¯ã‚りã¾ã›ã‚“" -#: plpy_exec.c:697 +#: plpy_exec.c:948 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" -msgstr "TD[\"new\"] ã§è¦‹ã¤ã‹ã£ãŸã‚­ãƒ¼ \"%s\" ã¯ã€è¡Œãƒ¬ãƒ™ãƒ«ãƒˆãƒªã‚¬ãƒ¼ã«ãŠã‘るカラムã¨ã—ã¦ã¯å­˜åœ¨ã—ã¾ã›ã‚“" +msgstr "TD[\"new\"] ã§è¦‹ã¤ã‹ã£ãŸã‚­ãƒ¼ \"%s\" ã¯ã€è¡Œãƒ¬ãƒ™ãƒ«ãƒˆãƒªã‚¬ã«ãŠã‘るカラムã¨ã—ã¦ã¯å­˜åœ¨ã—ã¾ã›ã‚“" + +#: plpy_exec.c:953 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "システム属性 \"%s\" を設定ã§ãã¾ã›ã‚“" -#: plpy_exec.c:778 +#: plpy_exec.c:1011 #, c-format msgid "while modifying trigger row" -msgstr "トリガー行を変更ã™ã‚‹éš›ã«" +msgstr "トリガ行を変更ã™ã‚‹éš›ã«" -#: plpy_exec.c:839 +#: plpy_exec.c:1072 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "終了ã—ã¦ã„ãªã„サブトランザクションを強制的ã«ã‚¢ãƒœãƒ¼ãƒˆã—ã¦ã„ã¾ã™" -#: plpy_main.c:100 -#, c-format -msgid "Python major version mismatch in session" -msgstr "セッションã«ãŠã„㦠Python ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒåˆè‡´ã—ã¾ã›ã‚“" - -#: plpy_main.c:101 +#: plpy_main.c:125 #, c-format -msgid "This session has previously used Python major version %d, and it is now attempting to use Python major version %d." -msgstr "ã“ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§ã¯ã™ã§ã« Python ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d ãŒä½¿ã‚れã¦ã„ã¾ã—ãŸãŒã€ã“ã“ã§ Python ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ %d を使ãŠã†ã¨ã—ã¦ã„ã¾ã™ã€‚" +msgid "multiple Python libraries are present in session" +msgstr "セッションã«è¤‡æ•°ã® Python ライブラリãŒå­˜åœ¨ã—ã¾ã™" -#: plpy_main.c:103 +#: plpy_main.c:126 #, c-format -msgid "Start a new session to use a different Python major version." -msgstr "Python ã®ç•°ãªã£ãŸãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã‚’使ã†å ´åˆã¯ã€æ–°ã—ã„セッションを開始ã—ã¦ãã ã•ã„" +msgid "Only one Python major version can be used in one session." +msgstr "1個ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ä¸­ã§ä½¿ãˆã‚‹ Python ã®ãƒ¡ã‚¸ãƒ£ãƒ¼ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯ï¼‘種類ã ã‘ã§ã™ã€‚" -#: plpy_main.c:118 +#: plpy_main.c:142 #, c-format msgid "untrapped error in initialization" -msgstr "åˆæœŸåŒ–ä¸­ã«æ•ç²ã§ããªã„エラーãŒã‚りã¾ã—ãŸ" +msgstr "åˆæœŸåŒ–ä¸­ã«æ•æ‰ã§ããªã„エラーãŒã‚りã¾ã—ãŸ" -#: plpy_main.c:141 +#: plpy_main.c:165 #, c-format msgid "could not import \"__main__\" module" msgstr "\"__main__\" モジュールをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_main.c:146 -#, c-format -msgid "could not create globals" -msgstr "globalsを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#: plpy_main.c:150 +#: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "グローãƒãƒ«å¤‰æ•°(globals)ã‚’åˆæœŸåŒ–ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_main.c:347 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "PL/Python プロシージャ \"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python 関数 \"%s\"" -#: plpy_main.c:354 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python ã®ç„¡åコードブロック" -#: plpy_planobject.c:126 -#, c-format -msgid "plan.status takes no arguments" -msgstr "plan.status ã¯å¼•æ•°ã‚’å–りã¾ã›ã‚“" - -#: plpy_plpymodule.c:178 plpy_plpymodule.c:181 +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 #, c-format msgid "could not import \"plpy\" module" -msgstr "\"plpy\"モジュールをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "\"plpy\" モジュールをインãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_plpymodule.c:196 +#: plpy_plpymodule.c:210 #, c-format -msgid "could not add the spiexceptions module" -msgstr "spiexceptionsモジュールを追加ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "could not create the spiexceptions module" +msgstr "spiexceptions モジュールを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_plpymodule.c:217 +#: plpy_plpymodule.c:218 #, c-format -msgid "could not create the base SPI exceptions" -msgstr "基本SPI例外を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "could not add the spiexceptions module" +msgstr "spiexceptions モジュールを追加ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_plpymodule.c:253 plpy_plpymodule.c:257 +#: plpy_plpymodule.c:286 #, c-format msgid "could not generate SPI exceptions" -msgstr "SPI例外を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "SPI 例外を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_plpymodule.c:388 +#: plpy_plpymodule.c:454 #, c-format msgid "could not unpack arguments in plpy.elog" -msgstr "plpy.elogã§å¼•数を展開ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "plpy.elog ã§å¼•数を展開ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_plpymodule.c:396 +#: plpy_plpymodule.c:463 msgid "could not parse error message in plpy.elog" msgstr "plpy.elog ã§ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’パースã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_procedure.c:194 +#: plpy_plpymodule.c:480 +#, c-format +msgid "argument 'message' given by name and position" +msgstr "åå‰ã¨ä½ç½®ã§ 'message' å¼•æ•°ãŒæ¸¡ã•れã¾ã—ãŸ" + +#: plpy_plpymodule.c:507 +#, c-format +msgid "'%s' is an invalid keyword argument for this function" +msgstr "ã“ã®é–¢æ•°ã«å¯¾ã—㦠'%s' ã¯ç„¡åйãªã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰å¼•æ•°ã§ã™" + +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 +#, c-format +msgid "invalid SQLSTATE code" +msgstr "無効㪠SQLSTATE コードã§ã™" + +#: plpy_procedure.c:230 #, c-format msgid "trigger functions can only be called as triggers" -msgstr "トリガー関数ã¯ãƒˆãƒªã‚¬ãƒ¼ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" +msgstr "トリガ関数ã¯ãƒˆãƒªã‚¬ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" -#: plpy_procedure.c:199 plpy_typeio.c:406 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python 関数㯠%s 型を返ã›ã¾ã›ã‚“" -#: plpy_procedure.c:281 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" -msgstr "PL/Python 関数㯠%s 型をå—ã‘付ã‘ã¾ã›ã‚“" +msgstr "PL/Python 関数㯠%s 型をå—ã‘付ã‘られã¾ã›ã‚“" -#: plpy_procedure.c:377 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" -msgstr "PL/Python 関数 \"%s\" をコンパイルã§ãã¾ã›ã‚“" +msgstr "PL/Python 関数 \"%s\" をコンパイルã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_procedure.c:380 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" -msgstr "PL/Python匿åコードブロックをコンパイルã§ãã¾ã›ã‚“" +msgstr "匿åã® PL/Python コードブロックをコンパイルã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 #, c-format msgid "command did not produce a result set" msgstr "コマンドã¯çµæžœã‚»ãƒƒãƒˆã‚’生æˆã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_spi.c:56 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "plpy.prepare ã®ç¬¬äºŒå¼•æ•°ã¯ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" -#: plpy_spi.c:105 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: %d 番目ã®åž‹åãŒæ–‡å­—列ã§ã¯ã‚りã¾ã›ã‚“" -#: plpy_spi.c:137 -#, c-format -msgid "plpy.prepare does not support composite types" -msgstr "plpy.prepare ã¯è¤‡åˆåž‹ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#: plpy_spi.c:187 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" -msgstr "plpy.execute ã¯ã‚¯ã‚¨ãƒªãƒ¼ã‚‚ã—ãã¯å®Ÿè¡Œè¨ˆç”»ã‚’期待ã—ã¦ã„ã¾ã—ãŸ" +msgstr "plpy.execute ã¯å•ã„åˆã‚ã›ã‚‚ã—ãã¯å®Ÿè¡Œè¨ˆç”»ã‚’期待ã—ã¦ã„ã¾ã—ãŸ" -#: plpy_spi.c:206 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute ã¯ç¬¬äºŒå¼•æ•°ã¨ã—ã¦ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã‚’å–りã¾ã™" -#: plpy_spi.c:330 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan ãŒå¤±æ•—ã—ã¾ã—ãŸï¼š%s" -#: plpy_spi.c:372 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute ãŒå¤±æ•—ã—ã¾ã—ãŸï¼š%s" -#: plpy_spi.c:439 -#, c-format -msgid "unrecognized error in PLy_spi_execute_fetch_result" -msgstr "PLy_spi_execute_fetch_result ã§èªè­˜ã§ããªã„エラーを検出ã—ã¾ã—ãŸ" - #: plpy_subxactobject.c:122 #, c-format msgid "this subtransaction has already been entered" -msgstr "ã“ã®ã‚µãƒ–トランザクションã¯åˆ°é”済ã¿ã§ã™" +msgstr "ã™ã§ã«ã“ã®ã‚µãƒ–トランザクションã®ä¸­ã«å…¥ã£ã¦ã„ã¾ã™" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:180 +#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 #, c-format msgid "this subtransaction has already been exited" -msgstr "ã“ã®ã‚µãƒ–トランザクションã¯çµ‚了済ã¿ã§ã™" +msgstr "ã“ã®ã‚µãƒ–トランザクションã‹ã‚‰ã™ã§ã«æŠœã‘ã¦ã„ã¾ã™" -#: plpy_subxactobject.c:174 +#: plpy_subxactobject.c:180 #, c-format msgid "this subtransaction has not been entered" -msgstr "ã“ã®ã‚µãƒ–トランザクションã«ã¯åˆ°é”ã—ã¾ã›ã‚“" +msgstr "ã“ã®ã‚µãƒ–トランザクションã«ã¯å…¥ã£ã¦ã„ã¾ã›ã‚“" -#: plpy_subxactobject.c:186 +#: plpy_subxactobject.c:192 #, c-format msgid "there is no subtransaction to exit from" -msgstr "終了ã™ã‚‹ãŸã‚ã®ã‚µãƒ–トランザクションãŒã‚りã¾ã›ã‚“" +msgstr "抜ã‘ã‚‹ã¹ãサブトランザクションãŒã‚りã¾ã›ã‚“" -#: plpy_typeio.c:291 -#, c-format -msgid "could not create new dictionary" -msgstr "æ–°ã—ã„ディレクトリを作れã¾ã›ã‚“" - -#: plpy_typeio.c:408 -#, c-format -msgid "PL/Python does not support conversion to arrays of row types." -msgstr "PL/Python ã¯è¡Œã‚¿ã‚¤ãƒ—é…列ã¸ã®å¤‰æ›ã‚’サãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“" - -#: plpy_typeio.c:584 +#: plpy_typeio.c:591 #, c-format -msgid "cannot convert multidimensional array to Python list" -msgstr "多次元é…列を Python ã® list ã«å¤‰æ›ã§ãã¾ã›ã‚“" +msgid "could not import a module for Decimal constructor" +msgstr "Decimal コンストラクタã®ãŸã‚ã®ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«ã‚’インãƒãƒ¼ãƒˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_typeio.c:585 +#: plpy_typeio.c:595 #, c-format -msgid "PL/Python only supports one-dimensional arrays." -msgstr "PL/Python ã§ã‚µãƒãƒ¼ãƒˆã—ã¦ã„ã‚‹ã®ã¯ä¸€æ¬¡å…ƒé…列ã®ã¿ã§ã™ã€‚" +msgid "no Decimal attribute in module" +msgstr "モジュールã®ä¸­ã« Decimal 属性ãŒå«ã¾ã‚Œã¦ã„ã¾ã›ã‚“" -#: plpy_typeio.c:591 +#: plpy_typeio.c:601 #, c-format -msgid "could not create new Python list" -msgstr "æ–°ã—ã„Pythonリストを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgid "conversion from numeric to Decimal failed" +msgstr "numeric ã‹ã‚‰ Decimal ã¸ã®å¤‰æ›ã«å¤±æ•—ã—ã¾ã—ãŸ" -#: plpy_typeio.c:650 +#: plpy_typeio.c:908 #, c-format msgid "could not create bytes representation of Python object" msgstr "ãƒã‚¤ãƒˆè¡¨ç¾ã® Python オブジェクトを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_typeio.c:742 +#: plpy_typeio.c:1056 #, c-format msgid "could not create string representation of Python object" msgstr "文字列表ç¾ã® Python オブジェクトを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_typeio.c:753 +#: plpy_typeio.c:1067 #, c-format msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" -msgstr "Python オブジェクトを cstring ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸï¼šPython ã®æ–‡å­—列表ç¾ãŒ null ãƒã‚¤ãƒˆã‚’æŒã¤ã“ã¨ã«ãªã£ã¦ã—ã¾ã„ã¾ã™" +msgstr "Python オブジェクトを cstring ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸï¼šPython ã®æ–‡å­—列表ç¾ã« null ãƒã‚¤ãƒˆãŒå«ã¾ã‚Œã¦ã„るよã†ã§ã™" + +#: plpy_typeio.c:1176 +#, c-format +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "é…åˆ—ã®æ¬¡å…ƒæ•°ãŒåˆ¶é™å€¤(%d)ã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: plpy_typeio.c:1180 +#, c-format +msgid "could not determine sequence length for function return value" +msgstr "é–¢æ•°ã®æˆ»ã‚Šå€¤ã«ã¤ã„ã¦ã€ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®é•·ã•を決定ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_typeio.c:787 +#: plpy_typeio.c:1183 plpy_typeio.c:1187 +#, c-format +msgid "array size exceeds the maximum allowed" +msgstr "é…列ã®ã‚µã‚¤ã‚ºãŒåˆ¶é™å€¤ã‚’è¶…ãˆã¦ã„ã¾ã™" + +#: plpy_typeio.c:1213 #, c-format msgid "return value of function with array return type is not a Python sequence" -msgstr "戻り値ãŒé…列ã§ã‚ã‚‹é–¢æ•°ã®æˆ»ã‚Šå€¤ãŒ Python シーケンスã§ã¯ã‚りã¾ã›ã‚“" +msgstr "é…列型を返ã™é–¢æ•°ã®æˆ»ã‚Šå€¤ãŒ Python ã®ã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã§ã¯ã‚りã¾ã›ã‚“" + +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "内部シーケンスã§é•·ã•ãŒç•°å¸¸ã§ã™ï¼šé•·ã•㯠%d ã§ã™ãŒã€æœŸå¾…ã™ã‚‹å€¤ã¯ %d ã§ã—ãŸ" -#: plpy_typeio.c:886 +#: plpy_typeio.c:1261 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "多次元é…列を生æˆã™ã‚‹å ´åˆã€å†…部シーケンスã¯ã™ã¹ã¦åŒã˜é•·ã•ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" + +#: plpy_typeio.c:1340 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "䏿­£ãªå½¢å¼ã®ãƒ¬ã‚³ãƒ¼ãƒ‰ãƒªãƒ†ãƒ©ãƒ«ã§ã™: \"%s\"" + +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "左括弧ãŒã‚りã¾ã›ã‚“。" + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "複åˆåž‹ã‚’é…列ã«å…¥ã‚Œã¦è¿”ã—ãŸã„å ´åˆã€ \"[('foo',)]\" ã®ã‚ˆã†ã«è¤‡åˆåž‹ã‚’ Pythonã®ã‚¿ãƒ—ルã¨ã—ã¦è¿”ã™ã‚ˆã†ã«ã—ã¦ãã ã•ã„。" + +#: plpy_typeio.c:1389 #, c-format msgid "key \"%s\" not found in mapping" msgstr "マッピング上ã«ã‚­ãƒ¼ \"%s\" ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" -#: plpy_typeio.c:887 +#: plpy_typeio.c:1390 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." -msgstr "カラム㫠null を入れã¦è¿”ã™ã«ã¯ã€ã‚«ãƒ©ãƒ ã®å¾Œã«ã¤ã‘ãŸåå‰ã‚’キーã¨ã—ã¦ã€ãƒžãƒƒãƒ”ング㫠None 値を追加ã—ã¦ãã ã•ã„" +msgstr "カラム㫠null を入れã¦è¿”ã™å ´åˆã€ã‚«ãƒ©ãƒ åをキーã¨ã—ã¦å€¤ãŒ None ã®ã‚¨ãƒ³ãƒˆãƒªã‚’マッピングã«è¿½åŠ ã—ã¦ãã ã•ã„" -#: plpy_typeio.c:935 +#: plpy_typeio.c:1443 #, c-format msgid "length of returned sequence did not match number of columns in row" -msgstr "è¿”ã•れãŸã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®é•·ã•ãŒã€ãã®è¡Œã®ã‚«ãƒ©ãƒ æ•°ã¨ç•°ãªã‚Šã¾ã™" +msgstr "è¿”ã•れãŸã‚·ãƒ¼ã‚±ãƒ³ã‚¹ã®é•·ã•ãŒè¡Œã®ã‚«ãƒ©ãƒ æ•°ã¨ãƒžãƒƒãƒã—ã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_typeio.c:1043 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "属性 \"%s\" ㌠Python オブジェクト中ã«å­˜åœ¨ã—ã¾ã›ã‚“" -#: plpy_typeio.c:1044 +#: plpy_typeio.c:1544 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." -msgstr "カラム㫠null を入れã¦è¿”ã™å ´åˆã¯ã€ãã®ã‚«ãƒ©ãƒ ã®å¾Œã«ã¤ã‘ãŸåå‰ã§è¡¨ã•れる属性ãŒå€¤ã¨ã—㦠None ã‚’æŒã¡ã€è¿”ã•れるオブジェクトãŒãã®å±žæ€§ã‚’å«ã‚€ã‚ˆã†ã«ã—ã¦ãã ã•ã„" +msgstr "カラム㫠null を入れã¦è¿”ã™å ´åˆã€ã‚«ãƒ©ãƒ åをキーã¨ã—ã¦å€¤ãŒ None ã§ã‚る属性をæŒã¤ã‚ªãƒ–ジェクトを返ã™ã‚ˆã†ã«ã—ã¦ãã ã•ã„。" -#: plpy_util.c:70 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" -msgstr "Pythonã®Unicodeオブジェクトをãƒã‚¤ãƒˆã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "Python ã® Unicode オブジェクトをãƒã‚¤ãƒˆåˆ—ã«å¤‰æ›ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#: plpy_util.c:75 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" -msgstr "符å·åŒ–ã•ã‚ŒãŸæ–‡å­—列ã‹ã‚‰ãƒã‚¤ãƒˆã‚’抽出ã§ãã¾ã›ã‚“ã§ã—ãŸ" - -#~ msgid "PyCObject_AsVoidPtr() failed" -#~ msgstr "PyCObject_AsVoidPtr() ã«å¤±æ•—ã—ã¾ã—ãŸ" - -#~ msgid "invalid arguments for plpy.prepare" -#~ msgstr "plpy.prepare ã®å¼•æ•°ãŒä¸æ­£ã§ã™" - -#~ msgid "PyCObject_FromVoidPtr() failed" -#~ msgstr "PyCObject_FromVoidPtr() ã«å¤±æ•—ã—ã¾ã—ãŸ" - -#~ msgid "unrecognized error in PLy_spi_prepare" -#~ msgstr "PLy_spi_prepare ã§èªè­˜ã§ããªã„エラーを検出ã—ã¾ã—ãŸ" - -#~ msgid "transaction aborted" -#~ msgstr "トランザクションãŒã‚¢ãƒœãƒ¼ãƒˆã—ã¾ã—ãŸ" - -#~ msgid "could not create procedure cache" -#~ msgstr "手続ã用キャッシュ(procedure cache)を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" +msgstr "エンコードã•ã‚ŒãŸæ–‡å­—列ã‹ã‚‰ãƒã‚¤ãƒˆåˆ—を抽出ã§ãã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "PL/Python: %s" -#~ msgstr "PL/Python: %s" +#~ msgid "could not create new dictionary" +#~ msgstr "æ–°ã—ã„辞書を作れã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "out of memory" -#~ msgstr "メモリä¸è¶³ã§ã™" +#~ msgid "could not create exception \"%s\"" +#~ msgstr "例外 \"%s \"を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "unrecognized error in PLy_spi_execute_plan" -#~ msgstr "PLy_spi_execute_plan ã§èªè­˜ã§ããªã„エラーを検出ã—ã¾ã—ãŸ" +#~ msgid "could not create globals" +#~ msgstr "グローãƒãƒ«å¤‰æ•°(globals)を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" -#~ msgid "unrecognized error in PLy_spi_execute_query" -#~ msgstr "PLy_spi_execute_query ã§èªè­˜ã§ããªã„エラーを検出ã—ã¾ã—ãŸ" +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "トリガã®å¼•æ•°ã‚’æ§‹æˆä¸­ã€æ–°ã—ã„辞書を生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ" diff --git a/src/pl/plpython/po/ko.po b/src/pl/plpython/po/ko.po index 8608d1ba94b..8c068a016e7 100644 --- a/src/pl/plpython/po/ko.po +++ b/src/pl/plpython/po/ko.po @@ -1,14 +1,14 @@ # LANGUAGE message translation file for plpython # Copyright (C) 2015 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# FIRST AUTHOR , 2015. +# Ioseph Kim , 2015. # msgid "" msgstr "" -"Project-Id-Version: plpython (PostgreSQL) 9.6\n" +"Project-Id-Version: plpython (PostgreSQL) 11\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-09-26 14:02+0900\n" -"PO-Revision-Date: 2016-09-26 19:31+0900\n" +"POT-Creation-Date: 2018-09-04 15:55+0900\n" +"PO-Revision-Date: 2018-09-07 17:06+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean \n" "Language: ko\n" @@ -22,87 +22,86 @@ msgstr "" msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor ê°ì²´ëŠ” 쿼리나 plpy.prepare ê°ì²´ë¥¼ ì¸ìžë¡œ 사용합니다" -#: plpy_cursorobject.c:177 +#: plpy_cursorobject.c:184 #, c-format msgid "plpy.cursor takes a sequence as its second argument" -msgstr "" -"plpy.cursor ê°ì²´ì˜ ì¸ìžë¡œ plpy.prepare ê°ì²´ë¥¼ 사용한 경우 ë‘번째 ì¸ìžëŠ” " -"prepare ê°ì²´ì˜ 매개변수가 있어야 합니다." +msgstr "plpy.cursor ê°ì²´ì˜ ì¸ìžë¡œ plpy.prepare ê°ì²´ë¥¼ 사용한 경우 ë‘번째 ì¸ìžëŠ” prepare ê°ì²´ì˜ 매개변수가 있어야 합니다." -#: plpy_cursorobject.c:193 plpy_spi.c:227 +#: plpy_cursorobject.c:200 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "plpy.prepare ê°ì²´ë¥¼ 실행할 수 ì—†ìŒ" -#: plpy_cursorobject.c:196 plpy_spi.c:230 +#: plpy_cursorobject.c:203 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "%d ê°œì˜ ì¸ìžê°€ 필요한ë°, %dê°œì˜ ì¸ìžë¥¼ 지정했ìŒ: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:352 #, c-format msgid "iterating a closed cursor" msgstr "ì´ë¯¸ 닫긴 커서ì—서 ë‹¤ìŒ ìžë£Œë¥¼ 요구하고 있ìŒ" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "ì¤‘ì§€ëœ ì„œë¸Œ íŠ¸ëžœìž­ì…˜ì— ìžˆëŠ” 커서ì—서 ë‹¤ìŒ ìžë£Œë¥¼ 요구하고 있ìŒ" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:418 #, c-format msgid "fetch from a closed cursor" msgstr "닫긴 커서ì—서 fetch" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:461 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "쿼리 결과가 Python 리스트로 담기ì—는 너무 많습니다" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:512 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "ì¤‘ì§€ëœ ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì—서 커서를 ë‹«ê³  있ìŒ" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:527 +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:142 #, c-format msgid "unsupported set function return mode" msgstr "ì§€ì›í•˜ì§€ 않는 ì§‘í•© 함수 리턴 모드" -#: plpy_exec.c:141 +#: plpy_exec.c:143 #, c-format -msgid "" -"PL/Python set-returning functions only support returning one value per call." -msgstr "" -"PL/Python ì§‘í•©-반환 함수는 í•œë²ˆì˜ í˜¸ì¶œì— ëŒ€í•´ì„œ í•˜ë‚˜ì˜ ê°’ë§Œ 반환할 수 있습니" -"다." +msgid "PL/Python set-returning functions only support returning one value per call." +msgstr "PL/Python ì§‘í•©-반환 함수는 í•œë²ˆì˜ í˜¸ì¶œì— ëŒ€í•´ì„œ í•˜ë‚˜ì˜ ê°’ë§Œ 반환할 수 있습니다." -#: plpy_exec.c:154 +#: plpy_exec.c:156 #, c-format msgid "returned object cannot be iterated" msgstr "반환하는 ê°ì²´ê°€ iterable í˜•ì´ ì•„ë‹˜" -#: plpy_exec.c:155 +#: plpy_exec.c:157 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python ì§‘í•©-반환 함수는 iterable ê°ì²´ë¥¼ 반환해야 합니다." -#: plpy_exec.c:169 +#: plpy_exec.c:171 #, c-format msgid "error fetching next item from iterator" msgstr "iteratorì—서 ë‹¤ìŒ ì•„ì´í…œì„ 가져올 수 ì—†ìŒ" -#: plpy_exec.c:210 +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python 프로시져가 Noneì„ ë°˜í™˜í•˜ì§€ 않았ìŒ" + +#: plpy_exec.c:218 #, c-format msgid "PL/Python function with return type \"void\" did not return None" -msgstr "" -"반환 ìžë£Œí˜•ì´ \"void\"ì¸ PL/Python 함수가 return None으로 ë나지 않았ìŒ" +msgstr "반환 ìžë£Œí˜•ì´ \"void\"ì¸ PL/Python 함수가 return None으로 ë나지 않았ìŒ" #: plpy_exec.c:374 plpy_exec.c:400 #, c-format @@ -116,71 +115,65 @@ msgstr "None ì´ë‚˜ 문ìžì—´ì´ 있어야합니다." #: plpy_exec.c:390 #, c-format -msgid "" -"PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" -msgstr "" -"PL/Python 트리거 함수가 DELETE 트리거ì—서 \"MODIFY\"를 ë°˜í™˜í–ˆìŒ -- 무시함" +msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" +msgstr "PL/Python 트리거 함수가 DELETE 트리거ì—서 \"MODIFY\"를 ë°˜í™˜í–ˆìŒ -- 무시함" #: plpy_exec.c:401 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "None, \"OK\", \"SKIP\", ë˜ëŠ” \"MODIFY\"를 사용해야 함." -#: plpy_exec.c:482 +#: plpy_exec.c:451 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() 함수가 ì¸ìž 설정하는 중 실패" -#: plpy_exec.c:486 +#: plpy_exec.c:455 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() 함수가 ì¸ìž 설정하는 중 실패" -#: plpy_exec.c:498 +#: plpy_exec.c:467 #, c-format -msgid "" -"function returning record called in context that cannot accept type record" +msgid "function returning record called in context that cannot accept type record" msgstr "반환 ìžë£Œí˜•ì´ recordì¸ë° 함수가 ê·¸ ìžë£Œí˜•으로 반환하지 않ìŒ" -#: plpy_exec.c:714 +#: plpy_exec.c:684 #, c-format msgid "while creating return value" msgstr "ë°˜í™˜ê°’ì„ ë§Œë“¤ê³  ìžˆì€ ì¤‘" -#: plpy_exec.c:738 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "트리거 ì¸ìžë¥¼ 구성하는 중 새 딕션너리를 만들 수 ì—†ìŒ" - -#: plpy_exec.c:927 +#: plpy_exec.c:909 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] 변수가 ì‚­ì œë˜ì—ˆìŒ, 로우를 수정할 수 ì—†ìŒ" -#: plpy_exec.c:932 +#: plpy_exec.c:914 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] 변수가 딕션너리 형태가 아님" -#: plpy_exec.c:957 +#: plpy_exec.c:941 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "%d 번째 TD[\"new\"] 딕션너리 키가 문ìžì—´ì´ 아님" -#: plpy_exec.c:964 +#: plpy_exec.c:948 #, c-format -msgid "" -"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " -"row" -msgstr "" -"로우 트리거 작업ì—서 칼럼으로 사용ë˜ëŠ” \"%s\" 키가 TD[\"new\"] ë³€ìˆ˜ì— ì—†ìŒ." +msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" +msgstr "로우 트리거 작업ì—서 칼럼으로 사용ë˜ëŠ” \"%s\" 키가 TD[\"new\"] ë³€ìˆ˜ì— ì—†ìŒ." -#: plpy_exec.c:1044 +#: plpy_exec.c:953 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" 시스템 ì†ì„±ì„ 지정할 수 ì—†ìŒ" + +#: plpy_exec.c:1011 #, c-format msgid "while modifying trigger row" msgstr "로우 변경 트리거 작업 ë„중" -#: plpy_exec.c:1105 +#: plpy_exec.c:1072 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì´ ì¤‘ì§€ë¨ìœ¼ë¡œ 강제로 중지ë¨" @@ -205,71 +198,66 @@ msgstr "plpy 모듈 초기화 실패" msgid "could not import \"__main__\" module" msgstr "\"__main__\" ëª¨ë“ˆì€ ìž„í¬íЏ í•  수 ì—†ìŒ" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "ì „ì—­ë³€ìˆ˜ë“¤ì„ ë§Œë“¤ 수 ì—†ìŒ" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "ì „ì—­ë³€ìˆ˜ë“¤ì„ ì´ˆê¸°í™” í•  수 ì—†ìŒ" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "\"%s\" PL/Python 프로시져" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "\"%s\" PL/Python 함수" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python ìµëª… 코드 블럭" -#: plpy_planobject.c:123 -#, c-format -msgid "plan.status takes no arguments" -msgstr "plan.statusì˜ ì¸ìžê°€ 없습니다." - -#: plpy_plpymodule.c:178 plpy_plpymodule.c:181 +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 #, c-format msgid "could not import \"plpy\" module" msgstr "\"plpy\" ëª¨ë“ˆì„ ìž„í¬íЏ í•  수 ì—†ìŒ" -#: plpy_plpymodule.c:196 +#: plpy_plpymodule.c:210 #, c-format -msgid "could not add the spiexceptions module" -msgstr "spiexceptions ëª¨ë“ˆì„ ì¶”ê°€í•  수 ì—†ìŒ" +msgid "could not create the spiexceptions module" +msgstr "spiexceptions ëª¨ë“ˆì„ ë§Œë“¤ 수 ì—†ìŒ" -#: plpy_plpymodule.c:217 +#: plpy_plpymodule.c:218 #, c-format -msgid "could not create the base SPI exceptions" -msgstr "기본 SPI 예외처리를 만들 수 ì—†ìŒ" +msgid "could not add the spiexceptions module" +msgstr "spiexceptions ëª¨ë“ˆì„ ì¶”ê°€í•  수 ì—†ìŒ" -#: plpy_plpymodule.c:252 plpy_plpymodule.c:256 +#: plpy_plpymodule.c:286 #, c-format msgid "could not generate SPI exceptions" msgstr "SPI 예외처리를 ìƒì„±í•  수 ì—†ìŒ" -#: plpy_plpymodule.c:422 +#: plpy_plpymodule.c:454 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "ìž˜ëª»ëœ ì¸ìžë¡œ êµ¬ì„±ëœ plpy.elog" -#: plpy_plpymodule.c:431 +#: plpy_plpymodule.c:463 msgid "could not parse error message in plpy.elog" msgstr "plpy.elog ì—서 오류 메시지를 ë¶„ì„í•  수 ì—†ìŒ" -#: plpy_plpymodule.c:448 +#: plpy_plpymodule.c:480 #, c-format -msgid "Argument 'message' given by name and position" +msgid "argument 'message' given by name and position" msgstr "'message' ì¸ìžëŠ” ì´ë¦„ê³¼ 위치가 있어야 함" -#: plpy_plpymodule.c:475 +#: plpy_plpymodule.c:507 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "'%s' ê°’ì€ ì´ í•¨ìˆ˜ì—서 ìž˜ëª»ëœ ì˜ˆì•½ì–´ ì¸ìžìž…니다" -#: plpy_plpymodule.c:486 plpy_plpymodule.c:492 +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 #, c-format msgid "invalid SQLSTATE code" msgstr "ìž˜ëª»ëœ SQLSTATE 코드" @@ -279,27 +267,27 @@ msgstr "ìž˜ëª»ëœ SQLSTATE 코드" msgid "trigger functions can only be called as triggers" msgstr "트리거 함수는 트리거로만 í˜¸ì¶œë  ìˆ˜ 있ìŒ" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•  수 ì—†ìŒ" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python 함수는 %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "\"%s\" PL/Python 함수를 ì»´íŒŒì¼ í•  수 ì—†ìŒ" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "anonymous PL/Python 코드 블ë¡ì„ ì»´íŒŒì¼ í•  수 ì—†ìŒ" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 #, c-format msgid "command did not produce a result set" msgstr "ëª…ë ¹ì˜ ê²°ê³¼ê°’ì´ ì—†ìŒ" @@ -309,158 +297,169 @@ msgstr "ëª…ë ¹ì˜ ê²°ê³¼ê°’ì´ ì—†ìŒ" msgid "second argument of plpy.prepare must be a sequence" msgstr "plpy.prepare í•¨ìˆ˜ì˜ ë‘번째 ì¸ìžëŠ” Python 시퀀스형ì´ì–´ì•¼ 함" -#: plpy_spi.c:116 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: %d 번째 ì¸ìžì˜ ìžë£Œí˜•ì´ ë¬¸ìžì—´ì´ 아님" -#: plpy_spi.c:192 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute í•¨ìˆ˜ì˜ ì¸ìžëŠ” 쿼리문ì´ë‚˜ plpy.prepare ê°ì²´ì—¬ì•¼ 함" -#: plpy_spi.c:211 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execut í•¨ìˆ˜ì˜ ë‘번째 ì¸ìžëŠ” python ì‹œí€€ìŠ¤í˜•ì´ ì™€ì•¼í•¨" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan 실패: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute 실패: %s" -#: plpy_subxactobject.c:123 +#: plpy_subxactobject.c:122 #, c-format msgid "this subtransaction has already been entered" msgstr "ì´ ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì€ ì´ë¯¸ 시작ë˜ì—ˆìŒ" -#: plpy_subxactobject.c:129 plpy_subxactobject.c:187 +#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 #, c-format msgid "this subtransaction has already been exited" msgstr "ì´ ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì€ ì´ë¯¸ ë났ìŒ" -#: plpy_subxactobject.c:181 +#: plpy_subxactobject.c:180 #, c-format msgid "this subtransaction has not been entered" msgstr "ì´ ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì´ ì‹œìž‘ë˜ì§€ 않았ìŒ" -#: plpy_subxactobject.c:193 +#: plpy_subxactobject.c:192 #, c-format msgid "there is no subtransaction to exit from" msgstr "종료할 ì„œë¸ŒíŠ¸ëžœìž­ì…˜ì´ ì—†ìŒ, 위치:" -#: plpy_typeio.c:286 -#, c-format -msgid "could not create new dictionary" -msgstr "새 디렉터리를 만들 수 ì—†ìŒ" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "Decimal ìžë£Œí˜• 처리를 위해 ëª¨ë“ˆì„ ìž„í¬íЏ í•  수 ì—†ìŒ" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "ëª¨ë“ˆì•ˆì— Decimal ì†ì„±ì´ ì—†ìŒ" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "numeric í˜•ì„ Decimal 형으로 변환할 수 ì—†ìŒ" -#: plpy_typeio.c:645 +#: plpy_typeio.c:908 #, c-format -msgid "cannot convert multidimensional array to Python list" -msgstr "다중 ì°¨ì› ë°°ì—´ì€ Python 리스트로 변환할 수 ì—†ìŒ" +msgid "could not create bytes representation of Python object" +msgstr "Python ê°ì²´ë¥¼ bytea ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" -#: plpy_typeio.c:646 +#: plpy_typeio.c:1056 #, c-format -msgid "PL/Python only supports one-dimensional arrays." -msgstr "PL/Pythonì—서는 1ì°¨ì› ë°°ì—´ë§Œ ì§€ì›í•¨" +msgid "could not create string representation of Python object" +msgstr "Python ê°ì²´ë¥¼ 문ìžì—´ ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" -#: plpy_typeio.c:652 +#: plpy_typeio.c:1067 #, c-format -msgid "could not create new Python list" -msgstr "새 Python 리스트를 만들 수 ì—†ìŒ" +msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" +msgstr "Python ê°ì²´ë¥¼ cstring 형으로 변환할 수 ì—†ìŒ: Python string ë³€ìˆ˜ì— null문ìžì—´ì´ í¬í•¨ë˜ì–´ 있ìŒ" -#: plpy_typeio.c:711 +#: plpy_typeio.c:1176 #, c-format -msgid "could not create bytes representation of Python object" -msgstr "Python ê°ì²´ë¥¼ bytea ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "ë°°ì—´ ì°¨ì›ì´ 최대치 (%d)를 초과 했습니다." -#: plpy_typeio.c:820 +#: plpy_typeio.c:1180 #, c-format -msgid "could not create string representation of Python object" -msgstr "Python ê°ì²´ë¥¼ 문ìžì—´ ìžë£Œí˜•으로 변환할 수 ì—†ìŒ" +msgid "could not determine sequence length for function return value" +msgstr "함수 반환 값으로 시퀀스 길ì´ë¥¼ ê²°ì •í•  수 ì—†ìŒ" -#: plpy_typeio.c:831 +#: plpy_typeio.c:1183 plpy_typeio.c:1187 #, c-format -msgid "" -"could not convert Python object into cstring: Python string representation " -"appears to contain null bytes" -msgstr "" -"Python ê°ì²´ë¥¼ cstring 형으로 변환할 수 ì—†ìŒ: Python string ë³€ìˆ˜ì— null문ìžì—´" -"ì´ í¬í•¨ë˜ì–´ 있ìŒ" +msgid "array size exceeds the maximum allowed" +msgstr "ë°°ì—´ 최대 í¬ê¸°ë¥¼ 초과함" -#: plpy_typeio.c:877 +#: plpy_typeio.c:1213 #, c-format -msgid "" -"return value of function with array return type is not a Python sequence" +msgid "return value of function with array return type is not a Python sequence" msgstr "배열형으로 넘길 ìžë£Œí˜•ì´ Python ì‹œí€€ìŠ¤í˜•ì´ ì•„ë‹˜" -#: plpy_typeio.c:996 +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "ìž˜ëª»ëœ ë‚´ë¶€ 시퀀스 길ì´, ê¸¸ì´ %d, %d 초과했ìŒ" + +#: plpy_typeio.c:1261 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "ë‹¤ì°¨ì› ë°°ì—´ì„ ì‚¬ìš©í•˜ë ¤ë©´, ê·¸ 하위 ë°°ì—´ì˜ ì°¨ì›ì´ ëª¨ë‘ ê°™ì•„ì•¼í•©ë‹ˆë‹¤." + +#: plpy_typeio.c:1340 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "ìž˜ëª»ëœ ë ˆì½”ë“œ 표현: \"%s\"" + +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "왼쪽 괄호가 ì—†ìŒ." + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "ë°°ì—´ì—서 복합 ìžë£Œí˜•ì„ ë°˜í™˜í•˜ë ¤ë©´, Python 튜플 í˜•ì„ ì‚¬ìš©í•˜ì„¸ìš”. 예: \"[('foo',)]\"." + +#: plpy_typeio.c:1389 #, c-format msgid "key \"%s\" not found in mapping" msgstr "ë§µ ì•ˆì— \"%s\" 키가 ì—†ìŒ" -#: plpy_typeio.c:997 +#: plpy_typeio.c:1390 #, c-format -msgid "" -"To return null in a column, add the value None to the mapping with the key " -"named after the column." -msgstr "" -"칼럼값으로 nullì„ ë°˜í™˜í•˜ë ¤ë©´, 칼럼 다ìŒì— 해당 키 ì´ë¦„ê³¼ 맵핑 ë˜ëŠ” Noneê°’ì„ ì§€ì •í•˜ì„¸ìš”" +msgid "To return null in a column, add the value None to the mapping with the key named after the column." +msgstr "칼럼값으로 nullì„ ë°˜í™˜í•˜ë ¤ë©´, 칼럼 다ìŒì— 해당 키 ì´ë¦„ê³¼ 맵핑 ë˜ëŠ” Noneê°’ì„ ì§€ì •í•˜ì„¸ìš”" -#: plpy_typeio.c:1048 +#: plpy_typeio.c:1443 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "반환ë˜ëŠ” 시퀀스형 ë³€ìˆ˜ì˜ ê¸¸ì´ê°€ ë¡œìš°ì˜ ì¹¼ëŸ¼ìˆ˜ì™€ ì¼ì¹˜í•˜ì§€ 않ìŒ" -#: plpy_typeio.c:1159 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "Python ê°ì²´ ê°€ìš´ë° \"%s\" ì†ì„±ì´ ì—†ìŒ" -#: plpy_typeio.c:1160 +#: plpy_typeio.c:1544 #, c-format -msgid "" -"To return null in a column, let the returned object have an attribute named " -"after column with value None." -msgstr "" -"칼럼 값으로 null ì„ ë°˜í™˜í•˜ë ¤ë©´, 값으로 None ê°’ì„ ê°€ì§€ëŠ” 칼럼 ë’¤ì—, " -"ì†ì„± ì´ë¦„ì´ ìžˆëŠ” ê°ì²´ë¥¼ 반환하세요" +msgid "To return null in a column, let the returned object have an attribute named after column with value None." +msgstr "칼럼 값으로 null ì„ ë°˜í™˜í•˜ë ¤ë©´, 값으로 None ê°’ì„ ê°€ì§€ëŠ” 칼럼 ë’¤ì—, ì†ì„± ì´ë¦„ì´ ìžˆëŠ” ê°ì²´ë¥¼ 반환하세요" -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "Python 유니코드 ê°ì²´ë¥¼ UTF-8 문ìžì—´ë¡œ 변환할 수 ì—†ìŒ" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "해당 ì¸ì½”드 문ìžì—´ì„ Pythonì—서 사용할 수 ì—†ìŒ" -#~ msgid "Start a new session to use a different Python major version." -#~ msgstr "Python ë©”ì´ì ¸ ë²„ì „ì„ ë‹¬ë¦¬ 사용하려면 새 세션으로 시작하세요." +#~ msgid "could not create new dictionary" +#~ msgstr "새 디렉터리를 만들 수 ì—†ìŒ" + +#~ msgid "could not create exception \"%s\"" +#~ msgstr "\"%s\" 예외처리를 ìƒì„±í•  수 ì—†ìŒ" + +#~ msgid "could not create globals" +#~ msgstr "ì „ì—­ë³€ìˆ˜ë“¤ì„ ë§Œë“¤ 수 ì—†ìŒ" -#~ msgid "" -#~ "This session has previously used Python major version %d, and it is now " -#~ "attempting to use Python major version %d." -#~ msgstr "" -#~ "ì´ ì„¸ì…˜ì€ ì´ì „ì— %d ë²„ì „ì„ ì‚¬ìš©í–ˆëŠ”ë°, ì§€ê¸ˆì€ %d ë²„ì „ì„ ì‚¬ìš©í•˜ë ¤ê³  합니다." +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "트리거 ì¸ìžë¥¼ 구성하는 중 새 딕션너리를 만들 수 ì—†ìŒ" diff --git a/src/pl/plpython/po/ru.po b/src/pl/plpython/po/ru.po index cb3a2ed3cb1..5ab94749e87 100644 --- a/src/pl/plpython/po/ru.po +++ b/src/pl/plpython/po/ru.po @@ -1,14 +1,14 @@ # Russian message translation file for plpython # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Alexander Lakhin , 2012-2017. -# +# Alexander Lakhin , 2012-2017, 2018. msgid "" msgstr "" "Project-Id-Version: plpython (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-04-02 23:37+0000\n" -"PO-Revision-Date: 2017-03-29 13:53+0300\n" +"POT-Creation-Date: 2018-10-05 21:51+0300\n" +"PO-Revision-Date: 2018-10-02 16:46+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,24 +16,23 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"Last-Translator: Alexander Lakhin \n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:101 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor ожидает Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð»Ð¸ план" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:184 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor принимает в качеÑтве второго аргумента поÑледовательноÑть" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:200 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "Ð½ÐµÐ»ÑŒÐ·Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÑŒ план" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:203 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" @@ -41,43 +40,43 @@ msgstr[0] "ОжидалаÑÑŒ поÑледовательноÑть из %d ар msgstr[1] "ОжидалаÑÑŒ поÑледовательноÑть из %d аргументов, получено %d: %s" msgstr[2] "ОжидалаÑÑŒ поÑледовательноÑть из %d аргументов, получено %d: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:352 #, c-format msgid "iterating a closed cursor" msgstr "перемещение закрытого курÑора" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "перемещение курÑора в прерванной подтранзакции" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:418 #, c-format msgid "fetch from a closed cursor" msgstr "выборка из закрытого курÑора" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:461 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "" "результат запроÑа Ñодержит Ñлишком много Ñтрок Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ в ÑпиÑке Python" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:512 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "закрытие курÑора в прерванной подтранзакции" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:142 #, c-format msgid "unsupported set function return mode" msgstr "неподдерживаемый режим возврата Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¸ Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼-множеÑтвом" -#: plpy_exec.c:141 +#: plpy_exec.c:143 #, c-format msgid "" "PL/Python set-returning functions only support returning one value per call." @@ -85,24 +84,29 @@ msgstr "" "Функции PL/Python Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼-множеÑтвом могут возвращать только одно " "значение за вызов." -#: plpy_exec.c:154 +#: plpy_exec.c:156 #, c-format msgid "returned object cannot be iterated" msgstr "возвращаемый объект не поддерживает итерации" -#: plpy_exec.c:155 +#: plpy_exec.c:157 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "" "Функции PL/Python Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼-множеÑтвом должны возвращать объекты Ñ " "возможноÑтью итерации." -#: plpy_exec.c:169 +#: plpy_exec.c:171 #, c-format msgid "error fetching next item from iterator" msgstr "ошибка Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñледующего Ñлемента из итератора" -#: plpy_exec.c:210 +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "процедура PL/Python вернула не None" + +#: plpy_exec.c:218 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Python Ñ Ñ‚Ð¸Ð¿Ð¾Ð¼ результата \"void\" вернула не None" @@ -130,49 +134,44 @@ msgstr "" msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "ОжидалоÑÑŒ None, \"OK\", \"SKIP\" или \"MODIFY\"." -#: plpy_exec.c:482 +#: plpy_exec.c:451 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "ошибка в PyList_SetItem() при наÑтройке аргументов" -#: plpy_exec.c:486 +#: plpy_exec.c:455 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "ошибка в PyDict_SetItemString() при наÑтройке аргументов" -#: plpy_exec.c:498 +#: plpy_exec.c:467 #, c-format msgid "" "function returning record called in context that cannot accept type record" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ, вызвана в контекÑте, не допуÑкающем Ñтот тип" -#: plpy_exec.c:714 +#: plpy_exec.c:684 #, c-format msgid "while creating return value" msgstr "при Ñоздании возвращаемого значениÑ" -#: plpy_exec.c:738 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "не удалоÑÑŒ Ñоздать Ñловарь Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ аргументов триггера" - -#: plpy_exec.c:926 +#: plpy_exec.c:909 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "Ñлемент TD[\"new\"] удалён -- изменить Ñтроку нельзÑ" -#: plpy_exec.c:931 +#: plpy_exec.c:914 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] - не Ñловарь" -#: plpy_exec.c:958 +#: plpy_exec.c:941 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "ключ ÑÐ»Ð¾Ð²Ð°Ñ€Ñ TD[\"new\"] Ñ Ð¿Ð¾Ñ€Ñдковым номером %d не ÑвлÑетÑÑ Ñтрокой" -#: plpy_exec.c:965 +#: plpy_exec.c:948 #, c-format msgid "" "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " @@ -181,17 +180,17 @@ msgstr "" "ключу \"%s\", найденному в TD[\"new\"], не ÑоответÑтвует Ñтолбец в Ñтроке, " "обрабатываемой триггером" -#: plpy_exec.c:970 +#: plpy_exec.c:953 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "уÑтановить ÑиÑтемный атрибут \"%s\" нельзÑ" -#: plpy_exec.c:1041 +#: plpy_exec.c:1011 #, c-format msgid "while modifying trigger row" msgstr "при изменении Ñтроки в триггере" -#: plpy_exec.c:1102 +#: plpy_exec.c:1072 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "принудительное прерывание незавершённой подтранзакции" @@ -216,71 +215,66 @@ msgstr "Ð½ÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° при инициализац msgid "could not import \"__main__\" module" msgstr "не удалоÑÑŒ импортировать модуль \"__main__\"" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "не удалоÑÑŒ Ñоздать глобальные данные" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "не удалоÑÑŒ инициализировать глобальные данные" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "процедура PL/Python \"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ PL/Python \"%s\"" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "анонимный блок кода PL/Python" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 #, c-format msgid "could not import \"plpy\" module" msgstr "не удалоÑÑŒ импортировать модуль \"plpy\"" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:210 #, c-format msgid "could not create the spiexceptions module" msgstr "не удалоÑÑŒ Ñоздать модуль spiexceptions" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:218 #, c-format msgid "could not add the spiexceptions module" msgstr "не удалоÑÑŒ добавить модуль spiexceptions" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "не удалоÑÑŒ Ñгенерировать иÑключение \"%s\"" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:286 #, c-format msgid "could not generate SPI exceptions" msgstr "не удалоÑÑŒ Ñгенерировать иÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ SPI" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:454 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "не удалоÑÑŒ раÑпаковать аргументы в plpy.elog" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:463 msgid "could not parse error message in plpy.elog" msgstr "не удалоÑÑŒ разобрать Ñообщение об ошибке в plpy.elog" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:480 #, c-format -msgid "Argument 'message' given by name and position" -msgstr "Ðргумент 'message' задан и по имени, и по позиции" +msgid "argument 'message' given by name and position" +msgstr "аргумент 'message' задан и по имени, и по позиции" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:507 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "'%s' - недопуÑтимое ключевое Ñлово (аргумент) Ð´Ð»Ñ Ñтой функции" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 #, c-format msgid "invalid SQLSTATE code" msgstr "неверный код SQLSTATE" @@ -290,57 +284,57 @@ msgstr "неверный код SQLSTATE" msgid "trigger functions can only be called as triggers" msgstr "триггерные функции могут вызыватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в триггерах" -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "функции PL/Python не могут возвращать тип %s" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "функции PL/Python не могут принимать тип %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "не удалоÑÑŒ Ñкомпилировать функцию PL/Python \"%s\"" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "не удалоÑÑŒ Ñкомпилировать анонимный блок кода PL/Python" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 #, c-format msgid "command did not produce a result set" msgstr "команда не выдала результирующий набор" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "вторым аргументом plpy.prepare должна быть поÑледовательноÑть" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: Ð¸Ð¼Ñ Ñ‚Ð¸Ð¿Ð° Ñ Ð¿Ð¾Ñ€Ñдковым номером %d не ÑвлÑетÑÑ Ñтрокой" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute ожидает Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð¸Ð»Ð¸ план" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute принимает в качеÑтве второго аргумента поÑледовательноÑть" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "ошибка в SPI_execute_plan: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "ошибка в SPI_execute: %s" @@ -365,37 +359,32 @@ msgstr "Ñта Ð¿Ð¾Ð´Ñ‚Ñ€Ð°Ð½Ð·Ð°ÐºÑ†Ð¸Ñ ÐµÑ‰Ñ‘ не начата" msgid "there is no subtransaction to exit from" msgstr "нет подтранзакции, которую нужно закончить" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "не удалоÑÑŒ Ñоздать Ñловарь" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "не удалоÑÑŒ импортировать модуль Ð´Ð»Ñ ÐºÐ¾Ð½Ñтруктора Decimal" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "в модуле нет атрибута Decimal" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "не удалоÑÑŒ преобразовать numeric в Decimal" -#: plpy_typeio.c:772 +#: plpy_typeio.c:908 #, c-format msgid "could not create bytes representation of Python object" msgstr "не удалоÑÑŒ Ñоздать байтовое предÑтавление объекта Python" -#: plpy_typeio.c:881 +#: plpy_typeio.c:1056 #, c-format msgid "could not create string representation of Python object" msgstr "не удалоÑÑŒ Ñоздать Ñтроковое предÑтавление объекта Python" -#: plpy_typeio.c:892 +#: plpy_typeio.c:1067 #, c-format msgid "" "could not convert Python object into cstring: Python string representation " @@ -404,43 +393,24 @@ msgstr "" "не удалоÑÑŒ преобразовать объект Python в cstring: похоже, предÑтавление " "Ñтроки Python Ñодержит нулевые байты" -#: plpy_typeio.c:949 -#, c-format -msgid "malformed record literal: \"%s\"" -msgstr "ошибка в литерале запиÑи: \"%s\"" - -#: plpy_typeio.c:950 -#, c-format -msgid "Missing left parenthesis." -msgstr "ОтÑутÑтвует Ð»ÐµÐ²Ð°Ñ Ñкобка." - -#: plpy_typeio.c:951 plpy_typeio.c:1389 -#, c-format -msgid "" -"To return a composite type in an array, return the composite type as a " -"Python tuple, e.g. \"[('foo')]\"" -msgstr "" -"Чтобы возвратить ÑоÑтавной тип в маÑÑиве, нужно возвратить ÑоÑтавное " -"значение в виде кортежа Python, например: \"[('foo')]\"" - -#: plpy_typeio.c:1000 +#: plpy_typeio.c:1176 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "чиÑло размерноÑтей маÑÑива превышает предел (%d)" -#: plpy_typeio.c:1004 +#: plpy_typeio.c:1180 #, c-format -msgid "cannot determine sequence length for function return value" +msgid "could not determine sequence length for function return value" msgstr "" "не удалоÑÑŒ определить длину поÑледовательноÑти в возвращаемом функцией " "значении" -#: plpy_typeio.c:1007 plpy_typeio.c:1011 +#: plpy_typeio.c:1183 plpy_typeio.c:1187 #, c-format msgid "array size exceeds the maximum allowed" msgstr "размер маÑÑива превышает предел" -#: plpy_typeio.c:1037 +#: plpy_typeio.c:1213 #, c-format msgid "" "return value of function with array return type is not a Python sequence" @@ -448,23 +418,45 @@ msgstr "" "возвращаемое значение функции Ñ Ñ€ÐµÐ·ÑƒÐ»ÑŒÑ‚Ð°Ñ‚Ð¾Ð¼-маÑÑивом не ÑвлÑетÑÑ " "поÑледовательноÑтью" -#: plpy_typeio.c:1090 +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "Ð½ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð»Ð¸Ð½Ð° внутренней поÑледовательноÑти: %d (ожидалоÑÑŒ: %d)" + +#: plpy_typeio.c:1261 #, c-format msgid "" -"multidimensional arrays must have array expressions with matching " -"dimensions. PL/Python function return value has sequence length %d while " -"expected %d" +"To construct a multidimensional array, the inner sequences must all have the " +"same length." msgstr "" -"Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ñ… маÑÑивов должны задаватьÑÑ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÑоответÑтвующими " -"размерноÑÑ‚Ñми. Ð’ возвращаемом функцией на PL/Python значении " -"поÑледовательноÑть имеет длину %d (а ожидалоÑÑŒ %d)" +"Ð”Ð»Ñ Ð¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ð¾Ð³Ð¾ маÑÑива внутренние поÑледовательноÑти должны " +"иметь одинаковую длину." + +#: plpy_typeio.c:1340 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "ошибка в литерале запиÑи: \"%s\"" -#: plpy_typeio.c:1212 +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "ОтÑутÑтвует Ð»ÐµÐ²Ð°Ñ Ñкобка." + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "" +"To return a composite type in an array, return the composite type as a " +"Python tuple, e.g., \"[('foo',)]\"." +msgstr "" +"Чтобы возвратить ÑоÑтавной тип в маÑÑиве, нужно возвратить ÑоÑтавное " +"значение в виде кортежа Python, например: \"[('foo',)]\"." + +#: plpy_typeio.c:1389 #, c-format msgid "key \"%s\" not found in mapping" msgstr "ключ \"%s\" не найден в ÑопоÑтавлении" -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1390 #, c-format msgid "" "To return null in a column, add the value None to the mapping with the key " @@ -473,17 +465,17 @@ msgstr "" "Чтобы приÑвоить Ñтолбцу NULL, добавьте в ÑопоÑтавление значение None Ñ " "ключом-именем Ñтолбца." -#: plpy_typeio.c:1264 +#: plpy_typeio.c:1443 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "длина возвращённой поÑледовательноÑти не равна чиÑлу Ñтолбцов в Ñтроке" -#: plpy_typeio.c:1387 +#: plpy_typeio.c:1541 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "в объекте Python не ÑущеÑтвует атрибут \"%s\"" -#: plpy_typeio.c:1390 +#: plpy_typeio.c:1544 #, c-format msgid "" "To return null in a column, let the returned object have an attribute named " @@ -492,16 +484,37 @@ msgstr "" "Чтобы приÑвоить Ñтолбцу NULL, приÑвойте возвращаемому значению атрибут Ñ " "именем Ñтолбца и значением None." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "не удалоÑÑŒ преобразовать объект Python Unicode в байты" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "не удалоÑÑŒ извлечь байты из кодированной Ñтроки" +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "не удалоÑÑŒ Ñоздать Ñловарь Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð¸ аргументов триггера" + +#~ msgid "could not create globals" +#~ msgstr "не удалоÑÑŒ Ñоздать глобальные данные" + +#~ msgid "could not create exception \"%s\"" +#~ msgstr "не удалоÑÑŒ Ñгенерировать иÑключение \"%s\"" + +#~ msgid "could not create new dictionary" +#~ msgstr "не удалоÑÑŒ Ñоздать Ñловарь" + +#~ msgid "" +#~ "multidimensional arrays must have array expressions with matching " +#~ "dimensions. PL/Python function return value has sequence length %d while " +#~ "expected %d" +#~ msgstr "" +#~ "Ð´Ð»Ñ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑ€Ð½Ñ‹Ñ… маÑÑивов должны задаватьÑÑ Ð²Ñ‹Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ ÑоответÑтвующими " +#~ "размерноÑÑ‚Ñми. Ð’ возвращаемом функцией на PL/Python значении " +#~ "поÑледовательноÑть имеет длину %d (а ожидалоÑÑŒ %d)" + #~ msgid "plan.status takes no arguments" #~ msgstr "plan.status не принимает аргументы" diff --git a/src/pl/plpython/po/sv.po b/src/pl/plpython/po/sv.po index d178b46503f..4d8ddf71046 100644 --- a/src/pl/plpython/po/sv.po +++ b/src/pl/plpython/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for plpython # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: plpython (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-08-05 14:07+0000\n" -"PO-Revision-Date: 2017-08-06 08:32+0200\n" +"Project-Id-Version: plpython (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 12:37+0000\n" +"PO-Revision-Date: 2019-04-29 14:54+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,164 +17,169 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: plpy_cursorobject.c:100 +#: plpy_cursorobject.c:78 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor förväntade sig en frÃ¥ga eller en plan" -#: plpy_cursorobject.c:176 +#: plpy_cursorobject.c:161 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor tar en sekvens som sitt andra argument" -#: plpy_cursorobject.c:192 plpy_spi.c:226 +#: plpy_cursorobject.c:177 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "kunde inte exekvera plan" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:180 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "Förväntade sekvens med %d argument, fick %d: %s" msgstr[1] "Förväntade sekvens med %d argument, fick %d: %s" -#: plpy_cursorobject.c:350 +#: plpy_cursorobject.c:329 #, c-format msgid "iterating a closed cursor" msgstr "itererar med en stängd markör" -#: plpy_cursorobject.c:358 plpy_cursorobject.c:423 +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "itererar med en markör i en avbruten subtransaktion" -#: plpy_cursorobject.c:415 +#: plpy_cursorobject.c:395 #, c-format msgid "fetch from a closed cursor" msgstr "hämta frÃ¥n en stängd markör" -#: plpy_cursorobject.c:463 plpy_spi.c:434 +#: plpy_cursorobject.c:438 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "frÃ¥geresultet har för mÃ¥nga rader för att fÃ¥ plats i en Python-lista" -#: plpy_cursorobject.c:504 +#: plpy_cursorobject.c:490 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "stänger en markör i en avbruten subtransaktion" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:548 +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:143 #, c-format msgid "unsupported set function return mode" msgstr "ej supportat returläge för mängdfunktion" -#: plpy_exec.c:141 +#: plpy_exec.c:144 #, c-format msgid "PL/Python set-returning functions only support returning one value per call." msgstr "PL/Python mängdreturnerande funktioner stöder bara ett värde per anrop." -#: plpy_exec.c:154 +#: plpy_exec.c:157 #, c-format msgid "returned object cannot be iterated" msgstr "returnerat objekt kan inte itereras" -#: plpy_exec.c:155 +#: plpy_exec.c:158 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python mängdreturnerande funktioner mÃ¥ste returnera ett itererbart objekt." -#: plpy_exec.c:169 +#: plpy_exec.c:172 #, c-format msgid "error fetching next item from iterator" msgstr "fel vid hämtning av nästa del frÃ¥n iteratorn" -#: plpy_exec.c:210 +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python-procedur returnerade inte None" + +#: plpy_exec.c:219 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "PL/Python-funktion med returtyp \"void\" returnerade inte None" -#: plpy_exec.c:379 plpy_exec.c:405 +#: plpy_exec.c:375 plpy_exec.c:401 #, c-format msgid "unexpected return value from trigger procedure" msgstr "oväntat returvärde frÃ¥n utlösarprocedur" -#: plpy_exec.c:380 +#: plpy_exec.c:376 #, c-format msgid "Expected None or a string." msgstr "Förväntade None eller en sträng." -#: plpy_exec.c:395 +#: plpy_exec.c:391 #, c-format msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "PL/Python-utlösarfunktion returnerade \"MODIFY\" i en DELETE-utlösare -- ignorerad" -#: plpy_exec.c:406 +#: plpy_exec.c:402 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "Förväntade None, \"OK\", \"SKIP\" eller \"MODIFY\"." -#: plpy_exec.c:487 +#: plpy_exec.c:452 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "PyList_SetItem() misslyckades vid uppsättning av argument" -#: plpy_exec.c:491 +#: plpy_exec.c:456 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "PyDict_SetItemString() misslyckades vid uppsättning av argument" -#: plpy_exec.c:503 +#: plpy_exec.c:468 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "en funktion med post som värde anropades i sammanhang där poster inte kan godtagas." -#: plpy_exec.c:719 +#: plpy_exec.c:685 #, c-format msgid "while creating return value" msgstr "vid skapande av returvärde" -#: plpy_exec.c:743 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "kunde inte skapa ny katalog vid byggande av utlösarargument" - -#: plpy_exec.c:931 +#: plpy_exec.c:919 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] raderad, kan inte modifiera rad" -#: plpy_exec.c:936 +#: plpy_exec.c:924 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"] är inte en dictionary" -#: plpy_exec.c:963 +#: plpy_exec.c:951 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "TD[\"new\"] dictionary-nyckel vid numerisk position %d är inte en sträng" -#: plpy_exec.c:970 +#: plpy_exec.c:958 #, c-format msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "nyckel \"%s\" hittad i TD[\"new\"] finns inte som en kolumn i den utlösande raden" -#: plpy_exec.c:975 +#: plpy_exec.c:963 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "kan inte sätta systemattribut \"%s\"" -#: plpy_exec.c:1046 +#: plpy_exec.c:968 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "kan inte sätta genererad kolumn \"%s\"" + +#: plpy_exec.c:1026 #, c-format msgid "while modifying trigger row" msgstr "vid modifiering av utlösande rad" -#: plpy_exec.c:1107 +#: plpy_exec.c:1087 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "tvingar avbrytande av subtransaktion som inte har avslutats" @@ -199,71 +204,66 @@ msgstr "ej fÃ¥ngar fel i initiering" msgid "could not import \"__main__\" module" msgstr "kunde inte importera \"__main__\"-modul" -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "kundew inte skapa globaler" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "kunde inte initierar globaler" -#: plpy_main.c:387 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "PL/Python-procedur \"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python-funktion \"%s\"" -#: plpy_main.c:394 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python anonymt kodblock" -#: plpy_plpymodule.c:181 plpy_plpymodule.c:184 +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 #, c-format msgid "could not import \"plpy\" module" msgstr "kunde inte importera \"plpy\"-modul" -#: plpy_plpymodule.c:199 +#: plpy_plpymodule.c:204 #, c-format msgid "could not create the spiexceptions module" msgstr "kunde inte skapa modulen spiexceptions" -#: plpy_plpymodule.c:207 +#: plpy_plpymodule.c:212 #, c-format msgid "could not add the spiexceptions module" msgstr "kunde inte lägga till modulen spiexceptions" -#: plpy_plpymodule.c:236 -#, c-format -msgid "could not create exception \"%s\"" -msgstr "kunde inte skapa undantag \"%s\"" - -#: plpy_plpymodule.c:271 plpy_plpymodule.c:275 +#: plpy_plpymodule.c:280 #, c-format msgid "could not generate SPI exceptions" msgstr "kunde inte skapa SPI-undantag" -#: plpy_plpymodule.c:443 +#: plpy_plpymodule.c:448 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "kunde inte packa upp argument i plpy.elog" -#: plpy_plpymodule.c:452 +#: plpy_plpymodule.c:457 msgid "could not parse error message in plpy.elog" msgstr "kunde inte parsa felmeddelande i plpy.elog" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:474 #, c-format msgid "argument 'message' given by name and position" msgstr "argumentet 'message' angivet med namn och position" -#: plpy_plpymodule.c:496 +#: plpy_plpymodule.c:501 #, c-format msgid "'%s' is an invalid keyword argument for this function" msgstr "'%s' är ett ogiltigt nyckelordsargument för denna funktion" -#: plpy_plpymodule.c:507 plpy_plpymodule.c:513 +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 #, c-format msgid "invalid SQLSTATE code" msgstr "ogiltig SQLSTATE-kod" @@ -273,192 +273,199 @@ msgstr "ogiltig SQLSTATE-kod" msgid "trigger functions can only be called as triggers" msgstr "Triggningsfunktioner kan bara anropas vid triggning." -#: plpy_procedure.c:235 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python-funktioner kan inte returnera typ %s" -#: plpy_procedure.c:316 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python-funktioner kan inte ta emot typ %s" -#: plpy_procedure.c:412 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "kunde inte kompilera PL/Python-funktion \"%s\"" -#: plpy_procedure.c:415 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "kunde inte kompilera anonymt PL/Python-kodblock" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 #, c-format msgid "command did not produce a result set" msgstr "kommandot producerade inte en resultatmängd" -#: plpy_spi.c:59 +#: plpy_spi.c:60 #, c-format msgid "second argument of plpy.prepare must be a sequence" msgstr "andra argumentet till plpy.prepare mÃ¥ste vara en sekvens" -#: plpy_spi.c:115 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: typnamn vid numerisk position %d är inte en sträng" -#: plpy_spi.c:191 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute förväntade en frÃ¥ga eller en plan" -#: plpy_spi.c:210 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute tar en sekvens som sitt andra argument" -#: plpy_spi.c:335 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "SPI_execute_plan misslyckades: %s" -#: plpy_spi.c:377 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute misslyckades: %s" -#: plpy_subxactobject.c:122 +#: plpy_subxactobject.c:97 #, c-format msgid "this subtransaction has already been entered" msgstr "denna subtransaktion har redan gÃ¥tts in i" -#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 #, c-format msgid "this subtransaction has already been exited" msgstr "denna subtransaktion har redan avslutat" -#: plpy_subxactobject.c:180 +#: plpy_subxactobject.c:155 #, c-format msgid "this subtransaction has not been entered" msgstr "denna subtransaktion har inte gÃ¥tts in i" -#: plpy_subxactobject.c:192 +#: plpy_subxactobject.c:167 #, c-format msgid "there is no subtransaction to exit from" msgstr "det finns ingen subtransaktion att avsluta frÃ¥n" -#: plpy_typeio.c:292 -#, c-format -msgid "could not create new dictionary" -msgstr "kunde inte skapa ny katalog" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "kunde inte importera en modul för Decimal-konstruktorn" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "inga Decimal-attribut i modulen" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "konvertering frÃ¥n numeric till Decimal misslyckades" -#: plpy_typeio.c:773 +#: plpy_typeio.c:915 #, c-format msgid "could not create bytes representation of Python object" msgstr "kunde inte skapa byte-representation av Python-objekt" -#: plpy_typeio.c:882 +#: plpy_typeio.c:1063 #, c-format msgid "could not create string representation of Python object" msgstr "kunde inte skapa strängrepresentation av Python-objekt" -#: plpy_typeio.c:893 +#: plpy_typeio.c:1074 #, c-format msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" msgstr "kunde inte konvertera Python-objekt till cstring: Python-strängrepresentationen verkar innehÃ¥lla noll-bytes" -#: plpy_typeio.c:950 -#, c-format -msgid "malformed record literal: \"%s\"" -msgstr "felaktig postliteral: \"%s\"" - -#: plpy_typeio.c:951 -#, c-format -msgid "Missing left parenthesis." -msgstr "Saknar vänster parentes" - -#: plpy_typeio.c:952 plpy_typeio.c:1390 -#, c-format -msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." -msgstr "För att returnera en composite-typ i en array, returnera composite-typen som en Python-tupel, t.ex. \"[('foo',)]\"." - -#: plpy_typeio.c:1001 +#: plpy_typeio.c:1183 #, c-format msgid "number of array dimensions exceeds the maximum allowed (%d)" msgstr "antal array-dimensioner överskriver maximalt tillÃ¥tna (%d)" -#: plpy_typeio.c:1005 +#: plpy_typeio.c:1187 #, c-format msgid "could not determine sequence length for function return value" msgstr "kunde inte bestämma sekvenslängd för funktionens returvärde" -#: plpy_typeio.c:1008 plpy_typeio.c:1012 +#: plpy_typeio.c:1190 plpy_typeio.c:1194 #, c-format msgid "array size exceeds the maximum allowed" msgstr "array-storlek överskrider maximalt tillÃ¥tna" -#: plpy_typeio.c:1038 +#: plpy_typeio.c:1220 #, c-format msgid "return value of function with array return type is not a Python sequence" msgstr "returvärde för funktion med array-returtyp är inte en Python-sekvens" -#: plpy_typeio.c:1091 +#: plpy_typeio.c:1266 #, c-format msgid "wrong length of inner sequence: has length %d, but %d was expected" msgstr "fel längd pÃ¥ inre sekvens: har längd %d, men %d förväntades" -#: plpy_typeio.c:1093 +#: plpy_typeio.c:1268 #, c-format msgid "To construct a multidimensional array, the inner sequences must all have the same length." msgstr "För att skapa en multidimensionell array sÃ¥ skall alla de inre sekvenserna ha samma längd." -#: plpy_typeio.c:1213 +#: plpy_typeio.c:1347 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "felaktig postliteral: \"%s\"" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "Saknar vänster parentes" + +#: plpy_typeio.c:1349 plpy_typeio.c:1550 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "För att returnera en composite-typ i en array, returnera composite-typen som en Python-tupel, t.ex. \"[('foo',)]\"." + +#: plpy_typeio.c:1396 #, c-format msgid "key \"%s\" not found in mapping" msgstr "nyckeln \"%s\" hittades inte i mapping" -#: plpy_typeio.c:1214 +#: plpy_typeio.c:1397 #, c-format msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "För att returnera null i en kolumn sÃ¥ lägg till värdet None till mappningen med nyckelnamn taget frÃ¥n kolumnen." -#: plpy_typeio.c:1265 +#: plpy_typeio.c:1450 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "längden pÃ¥ den returnerade sekvensen matchade inte antal kolumner i raden" -#: plpy_typeio.c:1388 +#: plpy_typeio.c:1548 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "attributet \"%s\" finns inte i Python-objektet" -#: plpy_typeio.c:1391 +#: plpy_typeio.c:1551 #, c-format msgid "To return null in a column, let the returned object have an attribute named after column with value None." msgstr "För att returnera null i en kolumn sÃ¥ lÃ¥t det returnerade objektet ha ett attribut med namn efter kolumnen och med värdet None." -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "kunde inte konvertera Python-unicode-objekt till bytes" -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "kunde inte extrahera bytes frÃ¥n kodad sträng" + +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "kunde inte skapa ny katalog vid byggande av utlösarargument" + +#~ msgid "could not create globals" +#~ msgstr "kundew inte skapa globaler" + +#~ msgid "could not create exception \"%s\"" +#~ msgstr "kunde inte skapa undantag \"%s\"" + +#~ msgid "could not create new dictionary" +#~ msgstr "kunde inte skapa ny katalog" diff --git a/src/pl/plpython/po/tr.po b/src/pl/plpython/po/tr.po new file mode 100644 index 00000000000..330162aa5d4 --- /dev/null +++ b/src/pl/plpython/po/tr.po @@ -0,0 +1,537 @@ +# LANGUAGE message translation file for plpython +# Copyright (C) 2009 PostgreSQL Global Development Group +# This file is distributed under the same license as the PostgreSQL package. +# FIRST AUTHOR , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: PostgreSQL 8.4\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:38+0000\n" +"PO-Revision-Date: 2019-06-13 17:10+0300\n" +"Last-Translator: Abdullah G. Gülner \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7.1\n" + +#: plpy_cursorobject.c:78 +#, c-format +msgid "plpy.cursor expected a query or a plan" +msgstr "plpy.cursor bir sorgu ya da bir plan bekledi" + +#: plpy_cursorobject.c:161 +#, c-format +msgid "plpy.cursor takes a sequence as its second argument" +msgstr "plpy.cursor bir sequence'ı ikinci argüman olarak alır" + +#: plpy_cursorobject.c:177 plpy_spi.c:211 +#, c-format +msgid "could not execute plan" +msgstr "plan çalıştırılamadı" + +#: plpy_cursorobject.c:180 plpy_spi.c:214 +#, c-format +msgid "Expected sequence of %d argument, got %d: %s" +msgid_plural "Expected sequence of %d arguments, got %d: %s" +msgstr[0] "%d argümanının sequence'ı beklendi; %d alındı: %s" + +#: plpy_cursorobject.c:329 +#, c-format +msgid "iterating a closed cursor" +msgstr "kapalı bir imleç (cursor) yineleniyor" + +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 +#, c-format +msgid "iterating a cursor in an aborted subtransaction" +msgstr "iptal edilen bir alt-iÅŸlemdeki (subtransaction) bir cursor yineleniyor" + +#: plpy_cursorobject.c:395 +#, c-format +msgid "fetch from a closed cursor" +msgstr "kapalı bir cursor'dan getir" + +#: plpy_cursorobject.c:438 plpy_spi.c:409 +#, c-format +msgid "query result has too many rows to fit in a Python list" +msgstr "sorgu sonucundaki satır sayısı bir Python listesine sığabilecekten çok fazla " + +#: plpy_cursorobject.c:490 +#, c-format +msgid "closing a cursor in an aborted subtransaction" +msgstr "iptal edilen bir alt-iÅŸlemdeki (subtransaction) bir cursor kapatılıyor" + +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 +#, c-format +msgid "%s" +msgstr "%s" + +#: plpy_exec.c:143 +#, c-format +msgid "unsupported set function return mode" +msgstr "desteklenmeyen küme fonksiyonu dönüş modu" + +#: plpy_exec.c:144 +#, c-format +msgid "PL/Python set-returning functions only support returning one value per call." +msgstr "PL/Python küme dönen fonksiyonları sadece her çaÄŸrı içinde bir deÄŸer döndürmeyi desteklerler" + +#: plpy_exec.c:157 +#, c-format +msgid "returned object cannot be iterated" +msgstr "dönen nesne yinelenemez" + +#: plpy_exec.c:158 +#, c-format +msgid "PL/Python set-returning functions must return an iterable object." +msgstr "PL/Python küme dönen fonksiyonları yinelenebilir bir nesne dönmelidir." + +#: plpy_exec.c:172 +#, c-format +msgid "error fetching next item from iterator" +msgstr "yineleticiden sonraki öğeyi alırken hata" + +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python prosedürü None döndürmedi" + +#: plpy_exec.c:219 +#, c-format +msgid "PL/Python function with return type \"void\" did not return None" +msgstr "dönüş tipi \"void\" olan PL/Python fonksiyonu None döndürmedi" + +#: plpy_exec.c:375 plpy_exec.c:401 +#, c-format +msgid "unexpected return value from trigger procedure" +msgstr "trigger yordamından beklenmeyen dönüş deÄŸeri" + +#: plpy_exec.c:376 +#, c-format +msgid "Expected None or a string." +msgstr "None ya da string bekleniyordu." + +#: plpy_exec.c:391 +#, c-format +msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" +msgstr "PL/Python trigger fonksiyonu DELETE triggerında \"MODIFY\" döndürdü -- gözardı edildi" + +#: plpy_exec.c:402 +#, c-format +msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." +msgstr "None, \"OK\", \"SKIP\", ya da \"MODIFY\" bekleniyordu" + +#: plpy_exec.c:452 +#, c-format +msgid "PyList_SetItem() failed, while setting up arguments" +msgstr "PyList_SetItem() bağımsız deÄŸiÅŸkenler ayarlanırken baÅŸarısız oldu" + +#: plpy_exec.c:456 +#, c-format +msgid "PyDict_SetItemString() failed, while setting up arguments" +msgstr "PyDict_SetItemString() bağımsız deÄŸiÅŸkenler ayarlanırken baÅŸarısız oldu" + +#: plpy_exec.c:468 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "tip kaydı içermeyen alanda çağırılan ve kayıt döndüren fonksiyon" + +#: plpy_exec.c:685 +#, c-format +msgid "while creating return value" +msgstr "dönüş deÄŸeri yaratılırken" + +#: plpy_exec.c:919 +#, c-format +msgid "TD[\"new\"] deleted, cannot modify row" +msgstr "TD[\"new\"] silindi, satır düzenlenemiyor" + +#: plpy_exec.c:924 +#, c-format +msgid "TD[\"new\"] is not a dictionary" +msgstr "TD[\"new\"] bir sözlük deÄŸil" + +#: plpy_exec.c:951 +#, c-format +msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" +msgstr "%d sıra pozisyonundaki TD[\"new\"] sözlük anahtarı dizi deÄŸil" + +#: plpy_exec.c:958 +#, c-format +msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" +msgstr "TD[\"new\"] içinde bulunan \"%s\" anahtarı tetikleyen satırda bir kolon olarak bulunmuyor" + +#: plpy_exec.c:963 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" sistem niteliÄŸi ayarlanamıyor" + +#: plpy_exec.c:968 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "oluÅŸturulan \"%s\" sütunu ayarlanamıyor" + +#: plpy_exec.c:1026 +#, c-format +msgid "while modifying trigger row" +msgstr "tetikleyici satırını düzenlerken" + +#: plpy_exec.c:1087 +#, c-format +msgid "forcibly aborting a subtransaction that has not been exited" +msgstr "çıkış yapılmamış bir alt-iÅŸlem (subtransaction) zorla iptal ediliyor" + +#: plpy_main.c:125 +#, c-format +msgid "multiple Python libraries are present in session" +msgstr "oturumda birden çok Python kütüphanesi mevcut" + +#: plpy_main.c:126 +#, c-format +msgid "Only one Python major version can be used in one session." +msgstr "Bir oturumda sadece bir Python ana sürümü kullanılabilir." + +#: plpy_main.c:142 +#, c-format +msgid "untrapped error in initialization" +msgstr "ilklendirme aÅŸamasında yakalanamayan hata" + +#: plpy_main.c:165 +#, c-format +msgid "could not import \"__main__\" module" +msgstr "\"__main__\" modülü alınamadı" + +#: plpy_main.c:174 +#, c-format +msgid "could not initialize globals" +msgstr "global deÄŸerler ilklendirilemedi" + +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "\"%s\" PL/Python prosedürü" + +#: plpy_main.c:402 +#, c-format +msgid "PL/Python function \"%s\"" +msgstr "\"%s\" PL/Python fonksiyonu" + +#: plpy_main.c:410 +#, c-format +msgid "PL/Python anonymous code block" +msgstr "PL/Python anonim kod bloÄŸu" + +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 +#, c-format +msgid "could not import \"plpy\" module" +msgstr "\"plpy\" modülü alınamadı" + +#: plpy_plpymodule.c:204 +#, c-format +msgid "could not create the spiexceptions module" +msgstr "spiexceptions modülü oluÅŸturulamadı" + +#: plpy_plpymodule.c:212 +#, c-format +msgid "could not add the spiexceptions module" +msgstr "spiexceptions modülü eklenemedi" + +#: plpy_plpymodule.c:280 +#, c-format +msgid "could not generate SPI exceptions" +msgstr "SPI istisnaları (exception) üretilemedi" + +#: plpy_plpymodule.c:448 +#, c-format +msgid "could not unpack arguments in plpy.elog" +msgstr "plpy.elog dosyasındaki argümanlar unpack edilemedi" + +#: plpy_plpymodule.c:457 +msgid "could not parse error message in plpy.elog" +msgstr "plpy.elog dosyasındaki hata mesajı ayrıştırılamadı" + +#: plpy_plpymodule.c:474 +#, c-format +msgid "argument 'message' given by name and position" +msgstr "ad ve konum tarafından verilen argüman 'mesajı'" + +#: plpy_plpymodule.c:501 +#, c-format +msgid "'%s' is an invalid keyword argument for this function" +msgstr "'%s' bu fonksiyon için geçersiz bir anahtar kelime argümanıdır" + +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 +#, c-format +msgid "invalid SQLSTATE code" +msgstr "geçersiz SQLSTATE kodu" + +#: plpy_procedure.c:230 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "trigger fonksiyonları sadece trigger olarak çağırılabilirler." + +#: plpy_procedure.c:234 +#, c-format +msgid "PL/Python functions cannot return type %s" +msgstr "PL/Python fonksiyonları %s tipini döndüremezler" + +#: plpy_procedure.c:312 +#, c-format +msgid "PL/Python functions cannot accept type %s" +msgstr "PL/Python fonksiyonlar %s tipini kabul etmezler" + +#: plpy_procedure.c:402 +#, c-format +msgid "could not compile PL/Python function \"%s\"" +msgstr "\"%s\" PL/Python fonksiyonu derlenemedi" + +#: plpy_procedure.c:405 +#, c-format +msgid "could not compile anonymous PL/Python code block" +msgstr "anonim PL/Python kod bloÄŸu derlenemedi" + +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 +#, c-format +msgid "command did not produce a result set" +msgstr "komut bir sonuç kümesi üretmedi" + +#: plpy_spi.c:60 +#, c-format +msgid "second argument of plpy.prepare must be a sequence" +msgstr "plpy.prepare'in ikinci argümanı sequence olmalıdır" + +#: plpy_spi.c:104 +#, c-format +msgid "plpy.prepare: type name at ordinal position %d is not a string" +msgstr "plpy.prepare: %d sıra posizyonundaki veri tipi dizi deÄŸil" + +#: plpy_spi.c:176 +#, c-format +msgid "plpy.execute expected a query or a plan" +msgstr "plpy.execute bir sorgu ya da bir plan bekledi" + +#: plpy_spi.c:195 +#, c-format +msgid "plpy.execute takes a sequence as its second argument" +msgstr "plpy.execute bir sequence'ı ikinci argüman olarak alır" + +#: plpy_spi.c:305 +#, c-format +msgid "SPI_execute_plan failed: %s" +msgstr "SPI_execute_plan baÅŸarısız oldu: %s" + +#: plpy_spi.c:347 +#, c-format +msgid "SPI_execute failed: %s" +msgstr "SPI_execute baÅŸarısız oldu: %s" + +#: plpy_subxactobject.c:97 +#, c-format +msgid "this subtransaction has already been entered" +msgstr "bu alt-iÅŸleme (subtransaction) zaten girilmiÅŸ" + +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 +#, c-format +msgid "this subtransaction has already been exited" +msgstr "bu alt-iÅŸlemden (subtransaction) zaten çıkılmış" + +#: plpy_subxactobject.c:155 +#, c-format +msgid "this subtransaction has not been entered" +msgstr "bu alt-iÅŸleme (subtransaction) girilmemiÅŸ" + +#: plpy_subxactobject.c:167 +#, c-format +msgid "there is no subtransaction to exit from" +msgstr "çıkılacak bir alt-iÅŸlem (subtransaction) yok" + +#: plpy_typeio.c:591 +#, c-format +msgid "could not import a module for Decimal constructor" +msgstr "Decimal constructor için bir modül alınamadı" + +#: plpy_typeio.c:595 +#, c-format +msgid "no Decimal attribute in module" +msgstr "modülde Decimal niteliÄŸi yok" + +#: plpy_typeio.c:601 +#, c-format +msgid "conversion from numeric to Decimal failed" +msgstr "numeric'ten Decimal'e dönüşüm baÅŸarısız oldu" + +#: plpy_typeio.c:915 +#, c-format +msgid "could not create bytes representation of Python object" +msgstr "Python nesnesinin bytes gösterimi yaratılamadı" + +#: plpy_typeio.c:1063 +#, c-format +msgid "could not create string representation of Python object" +msgstr "Python nesnesinin dizgi gösterimi yaratılamadı" + +#: plpy_typeio.c:1074 +#, c-format +msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" +msgstr "Python nesnesi cstring'e dönüştürülemedi: Python dizgi gösterimi null bayt içeriyor olabilir." + +#: plpy_typeio.c:1183 +#, c-format +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "dizi (array) boyut sayısı izin verilen en yüksek deÄŸeri (%d) aÅŸmaktadır" + +#: plpy_typeio.c:1187 +#, c-format +msgid "could not determine sequence length for function return value" +msgstr "fonksiyon dönüş deÄŸeri için sequence uzunluÄŸu belirlenemedi" + +#: plpy_typeio.c:1190 plpy_typeio.c:1194 +#, c-format +msgid "array size exceeds the maximum allowed" +msgstr "dizi (array) boyutu izin verilen en yüksek deÄŸeri aÅŸmaktadır" + +#: plpy_typeio.c:1220 +#, c-format +msgid "return value of function with array return type is not a Python sequence" +msgstr "dizi dönüp tipli dönüş deÄŸeri olan fonksiyon Python sequence'ı deÄŸildir" + +#: plpy_typeio.c:1266 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "iç sequence'in uzunluÄŸu yanlış: %d uzunlukta, fakat %d bekleniyordu" + +#: plpy_typeio.c:1268 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "Çok boyutlu bir dizi oluÅŸturmak için, iç sequence'lerin tamamı aynı uzunlukta olmalı." + +#: plpy_typeio.c:1347 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "hatalı deÄŸer: \"%s\"" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "Sol parantez eksik." + +#: plpy_typeio.c:1349 plpy_typeio.c:1550 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "Bir bileÅŸik türü dizi (array) içinde döndürmek için, bileÅŸik türü bir Python tuple, e.g., \"[('foo',)]\"." + +#: plpy_typeio.c:1396 +#, c-format +msgid "key \"%s\" not found in mapping" +msgstr "\"%s\" anahtarı planlamada bulunnamadı" + +#: plpy_typeio.c:1397 +#, c-format +msgid "To return null in a column, add the value None to the mapping with the key named after the column." +msgstr "Bir kolondan Null döndürmek için, kolonun ismindeki eÅŸleÅŸmenin anahtarına, NONE deÄŸerini ekleyin" + +#: plpy_typeio.c:1450 +#, c-format +msgid "length of returned sequence did not match number of columns in row" +msgstr "Dönen sequence'in uzunluÄŸu satırdaki kolonların sayısı ile eÅŸleÅŸmiyor." + +#: plpy_typeio.c:1548 +#, c-format +msgid "attribute \"%s\" does not exist in Python object" +msgstr "\"%s\" niteliÄŸi Python nesnesinde bulunmaz" + +#: plpy_typeio.c:1551 +#, c-format +msgid "To return null in a column, let the returned object have an attribute named after column with value None." +msgstr " Bir kolondan null döndürmek için, döndürdüğünüz nesnenin, kolonun adına sahip bir özelliÄŸinin olmasını ve bu özelliÄŸin deÄŸerinin NONE olmasını saÄŸlamanız gerekir" + +#: plpy_util.c:35 +#, c-format +msgid "could not convert Python Unicode object to bytes" +msgstr "Python unicode nesnesi baytlara dönüştürülemedi." + +#: plpy_util.c:41 +#, c-format +msgid "could not extract bytes from encoded string" +msgstr "kodlanmış string den baytlar çıkarılamadı" + +#~ msgid "could not create new dictionary while building trigger arguments" +#~ msgstr "trigger argümanlarını oluÅŸtururken yeni sözlük yaratılamadı" + +#~ msgid "could not create globals" +#~ msgstr "evrensel deÄŸerler (globals) oluÅŸturulamadı" + +#~ msgid "could not create exception \"%s\"" +#~ msgstr "\"%s\" istisnası (exception) oluÅŸturulamadı" + +#~ msgid "could not create new dictionary" +#~ msgstr "Yeni sözlük yaratılamadı" + +#~ msgid "PL/Python function \"%s\" could not execute plan" +#~ msgstr "\"%s\" PL/Python fonksiyonu planı çalıştıramadı" + +#~ msgid "PL/Python function \"%s\" failed" +#~ msgstr "\"%s\" PL/Python fonksiyonu baÅŸarısız oldu" + +#~ msgid "could not create string representation of Python object in PL/Python function \"%s\" while creating return value" +#~ msgstr "dönüş deÄŸeri yaratılırken \"%s\" Pl/Python fonksiyonunun içindeki Python ensnesinin dizi gösterimi yaratılamadı" + +#~ msgid "could not compute string representation of Python object in PL/Python function \"%s\" while modifying trigger row" +#~ msgstr "tetikleyici satırı düzenlerken \"%s\" PL/Python fonksiyonunun içindeki Python nesnesinin dizi gösterimi hesaplanamadı" + +#~ msgid "out of memory" +#~ msgstr "yetersiz bellek" + +#~ msgid "PL/Python: %s" +#~ msgstr "PL/Python: %s" + +#~ msgid "could not create procedure cache" +#~ msgstr "yordam önbelleÄŸi yaratılamadı" + +#~ msgid "Start a new session to use a different Python major version." +#~ msgstr "Farklı bir Python ana sürümü kullanmak için yeni bir oturum açın." + +#~ msgid "This session has previously used Python major version %d, and it is now attempting to use Python major version %d." +#~ msgstr "Bu oturum daha önceden %d Python ana sürümünü kullandı, ve ÅŸimdi %d ana sürümünü kullanmayı deniyor." + +#~ msgid "unrecognized error in PLy_spi_execute_fetch_result" +#~ msgstr "PLy_spi_execute_fetch_result içinde tanımlanamayan hata" + +#~ msgid "unrecognized error in PLy_spi_execute_query" +#~ msgstr "PLy_spi_execute_query içinde tanımlanamayan hata" + +#~ msgid "unrecognized error in PLy_spi_execute_plan" +#~ msgstr "PLy_spi_execute_plan içinde beklenmeyen hata" + +#~ msgid "unrecognized error in PLy_spi_prepare" +#~ msgstr "PLy_spi_prepare içinde tanımlanamayan hata" + +#~ msgid "plpy.prepare does not support composite types" +#~ msgstr "plpy.prepare kompozit tipleri desteklemez" + +#~ msgid "invalid arguments for plpy.prepare" +#~ msgstr "plpy.prepare için geçersiz argümanlar" + +#~ msgid "transaction aborted" +#~ msgstr "transaction iptal edildi" + +#~ msgid "plan.status takes no arguments" +#~ msgstr "plan.status bir argüman almaz" + +#~ msgid "PL/Python only supports one-dimensional arrays." +#~ msgstr "PL/Python sadece bir boyutlu dizileri destekler." + +#~ msgid "cannot convert multidimensional array to Python list" +#~ msgstr "çok boyutlu dizi, Python listesine dönüştürülemedi" + +#~ msgid "PL/Python does not support conversion to arrays of row types." +#~ msgstr "PL/Python satır tiplerinin dizilere dönüşümünü desteklemez." + +#~ msgid "PyCObject_FromVoidPtr() failed" +#~ msgstr "PyCObject_FromVoidPtr() baÅŸarısız oldu" + +#~ msgid "PyCObject_AsVoidPtr() failed" +#~ msgstr "PyCObject_AsVoidPtr() baÅŸarısız oldu" diff --git a/src/pl/plpython/po/vi.po b/src/pl/plpython/po/vi.po new file mode 100644 index 00000000000..58e05056574 --- /dev/null +++ b/src/pl/plpython/po/vi.po @@ -0,0 +1,485 @@ +# LANGUAGE message translation file for plpython +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the plpython (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: plpython (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:08+0000\n" +"PO-Revision-Date: 2018-05-06 22:57+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Language: vi_VN\n" + +#: plpy_cursorobject.c:101 +#, c-format +msgid "plpy.cursor expected a query or a plan" +msgstr "plpy.cursor kỳ vá»ng má»™t câu truy vấn hoặc má»™t plan" + +#: plpy_cursorobject.c:184 +#, c-format +msgid "plpy.cursor takes a sequence as its second argument" +msgstr "plpy.cursor lấy má»™t chuá»—i làm đối số thứ hai" + +#: plpy_cursorobject.c:200 plpy_spi.c:211 +#, c-format +msgid "could not execute plan" +msgstr "không thể chạy plan" + +#: plpy_cursorobject.c:203 plpy_spi.c:214 +#, c-format +msgid "Expected sequence of %d argument, got %d: %s" +msgid_plural "Expected sequence of %d arguments, got %d: %s" +msgstr[0] "Kỳ vá»ng chuá»—i cá»§a đối số %d, đã nhận %d: %s" + +#: plpy_cursorobject.c:352 +#, c-format +msgid "iterating a closed cursor" +msgstr "lặp lại con trỠđã đóng" + +#: plpy_cursorobject.c:360 plpy_cursorobject.c:426 +#, c-format +msgid "iterating a cursor in an aborted subtransaction" +msgstr "lặp lại má»™t con trá» trong má»™t subtransaction đã bị há»§y bá»" + +#: plpy_cursorobject.c:418 +#, c-format +msgid "fetch from a closed cursor" +msgstr "fetch từ má»™t con trỠđã bị đóng" + +#: plpy_cursorobject.c:461 plpy_spi.c:409 +#, c-format +msgid "query result has too many rows to fit in a Python list" +msgstr "kết quả câu truy vấn có quá nhiá»u hàng để vừa vá»›i má»™t danh sách Python" + +#: plpy_cursorobject.c:512 +#, c-format +msgid "closing a cursor in an aborted subtransaction" +msgstr "đóng má»™t con trá» trong má»™t subtransaction bị há»§y bá»" + +#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:559 +#, c-format +msgid "%s" +msgstr "%s" + +#: plpy_exec.c:142 +#, c-format +msgid "unsupported set function return mode" +msgstr "không há»— trợ thiết lập hàm trả vá» mode" + +#: plpy_exec.c:143 +#, c-format +msgid "" +"PL/Python set-returning functions only support returning one value per call." +msgstr "" +"PL/Python hàm thiết lập-trả vá» chỉ há»— trợ trả vá» má»™t giá trị cho má»™t lần gá»i." + +#: plpy_exec.c:156 +#, c-format +msgid "returned object cannot be iterated" +msgstr "đối tượng trả vá» không thể được lặp lại" + +#: plpy_exec.c:157 +#, c-format +msgid "PL/Python set-returning functions must return an iterable object." +msgstr "PL/Python hàm thiết lập-trả vá» phải trả vá» má»™t iterable object." + +#: plpy_exec.c:171 +#, c-format +msgid "error fetching next item from iterator" +msgstr "lá»—i khi fetch item tiếp theo từ iterator" + +#: plpy_exec.c:214 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "Thá»§ tục PL/Python đã không trả vá» None" + +#: plpy_exec.c:218 +#, c-format +msgid "PL/Python function with return type \"void\" did not return None" +msgstr "Hàm PL/Python vá»›i kiểu trả vá» là \"void\" đã không trả vá» None" + +#: plpy_exec.c:374 plpy_exec.c:400 +#, c-format +msgid "unexpected return value from trigger procedure" +msgstr "không mong đợi giá trị trả vá» từ thá»§ tục trigger" + +#: plpy_exec.c:375 +#, c-format +msgid "Expected None or a string." +msgstr "Kỳ vá»ng None hoặc má»™t chuá»—i." + +#: plpy_exec.c:390 +#, c-format +msgid "" +"PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" +msgstr "" +"Hàm trigger PL/Python đã trả vá» \"MODIFY\" trong má»™t DELETE trigger -- bá» qua" + +#: plpy_exec.c:401 +#, c-format +msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." +msgstr "Kỳ vá»ng None, \"OK\", \"SKIP\", hoặc \"MODIFY\"." + +#: plpy_exec.c:451 +#, c-format +msgid "PyList_SetItem() failed, while setting up arguments" +msgstr "Lá»—i PyList_SetItem(), trong khi thiết lập đối số" + +#: plpy_exec.c:455 +#, c-format +msgid "PyDict_SetItemString() failed, while setting up arguments" +msgstr "Lá»—i PyDict_SetItemString(), trong khi thiết lập đối số" + +#: plpy_exec.c:467 +#, c-format +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"hàm trả vá» bản ghi được gá»i trong ngữ cảnh không thể chấp nhận kiểu bản ghi" + +#: plpy_exec.c:684 +#, c-format +msgid "while creating return value" +msgstr "trong khi tạo ra giá trị trả vá»" + +#: plpy_exec.c:909 +#, c-format +msgid "TD[\"new\"] deleted, cannot modify row" +msgstr "TD[\"new\"] đã bị xóa, không thể sá»­a đổi hàng" + +#: plpy_exec.c:914 +#, c-format +msgid "TD[\"new\"] is not a dictionary" +msgstr "TD[\"new\"] không phải là từ Ä‘iển" + +#: plpy_exec.c:941 +#, c-format +msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" +msgstr "Khóa từ Ä‘iển TD[\"new\"] ở vị trí thứ tá»± %d không phải là chuá»—i" + +#: plpy_exec.c:948 +#, c-format +msgid "" +"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " +"row" +msgstr "" +"khóa \"%s\" được tìm thấy trong TD[\"new\"] không tồn tại như là trigger mức " +"độ hàng" + +#: plpy_exec.c:953 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "không thể thiết lập thuá»™c tính hệ thống \"%s\"" + +#: plpy_exec.c:1011 +#, c-format +msgid "while modifying trigger row" +msgstr "trong khi sá»­a đổi trigger mức độ hàng" + +#: plpy_exec.c:1072 +#, c-format +msgid "forcibly aborting a subtransaction that has not been exited" +msgstr "buá»™c phải há»§y bá» má»™t subtransaction chưa được thoát" + +#: plpy_main.c:125 +#, c-format +msgid "multiple Python libraries are present in session" +msgstr "có nhiá»u thư viện Python trong má»™t phiên" + +#: plpy_main.c:126 +#, c-format +msgid "Only one Python major version can be used in one session." +msgstr "Chỉ có thể sá»­ dụng má»™t phiên bản chính cá»§a Python trong má»™t phiên." + +#: plpy_main.c:142 +#, c-format +msgid "untrapped error in initialization" +msgstr "lá»—i chưa được bẫy trong lúc khởi tạo" + +#: plpy_main.c:165 +#, c-format +msgid "could not import \"__main__\" module" +msgstr "không thể nhập mô-Ä‘un \"__main__\"" + +#: plpy_main.c:174 +#, c-format +msgid "could not initialize globals" +msgstr "không thể khởi tạo biến global" + +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "Thá»§ tục PL/Python \"%s\"" + +#: plpy_main.c:402 +#, c-format +msgid "PL/Python function \"%s\"" +msgstr "Hàm PL/Python \"%s\"" + +#: plpy_main.c:410 +#, c-format +msgid "PL/Python anonymous code block" +msgstr "Khối mã ẩn danh PL/Python" + +#: plpy_plpymodule.c:192 plpy_plpymodule.c:195 +#, c-format +msgid "could not import \"plpy\" module" +msgstr "không thể nhập mô-Ä‘un \"plpy\"" + +#: plpy_plpymodule.c:210 +#, c-format +msgid "could not create the spiexceptions module" +msgstr "không thể tạo mô-Ä‘un spiexceptions" + +#: plpy_plpymodule.c:218 +#, c-format +msgid "could not add the spiexceptions module" +msgstr "không thể thêm mô-Ä‘un spiexceptions" + +#: plpy_plpymodule.c:286 +#, c-format +msgid "could not generate SPI exceptions" +msgstr "không thể tạo exception SPI" + +#: plpy_plpymodule.c:454 +#, c-format +msgid "could not unpack arguments in plpy.elog" +msgstr "không thể giải nén đối số trong plpy.elog" + +#: plpy_plpymodule.c:463 +msgid "could not parse error message in plpy.elog" +msgstr "không thể phân tích cú pháp thông Ä‘iệp lá»—i trong plpy.elog" + +#: plpy_plpymodule.c:480 +#, c-format +msgid "argument 'message' given by name and position" +msgstr "đối số 'message' được chỉ định theo tên và vị trí" + +#: plpy_plpymodule.c:507 +#, c-format +msgid "'%s' is an invalid keyword argument for this function" +msgstr "'%s' là đối số từ khóa không hợp lệ cho hàm này" + +#: plpy_plpymodule.c:518 plpy_plpymodule.c:524 +#, c-format +msgid "invalid SQLSTATE code" +msgstr "mã SQLSTATE không hợp lệ" + +#: plpy_procedure.c:230 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "hàm trigger chỉ có thể được gá»i như trigger" + +#: plpy_procedure.c:234 +#, c-format +msgid "PL/Python functions cannot return type %s" +msgstr "Hàm PL/Python không thể trả vá» kiểu %s" + +#: plpy_procedure.c:312 +#, c-format +msgid "PL/Python functions cannot accept type %s" +msgstr "Các hàm PL/Python không thể chấp nhận kiểu %s" + +#: plpy_procedure.c:402 +#, c-format +msgid "could not compile PL/Python function \"%s\"" +msgstr "không thể biên dịch hàm PL/Python \"%s\"" + +#: plpy_procedure.c:405 +#, c-format +msgid "could not compile anonymous PL/Python code block" +msgstr "không thể biên dịch khối mã ẩn danh PL/Python" + +#: plpy_resultobject.c:150 plpy_resultobject.c:176 plpy_resultobject.c:202 +#, c-format +msgid "command did not produce a result set" +msgstr "lệnh không tạo ra má»™t tập hợp kết quả" + +#: plpy_spi.c:60 +#, c-format +msgid "second argument of plpy.prepare must be a sequence" +msgstr "đối số thứ hai cá»§a plpy.prepare phải là má»™t chuá»—i" + +#: plpy_spi.c:104 +#, c-format +msgid "plpy.prepare: type name at ordinal position %d is not a string" +msgstr "plpy.prepare: gõ tên tại vị trí thứ tá»± %d không phải là má»™t chuá»—i" + +#: plpy_spi.c:176 +#, c-format +msgid "plpy.execute expected a query or a plan" +msgstr "plpy.execute kỳ vá»ng má»™t truy vấn hoặc má»™t plan" + +#: plpy_spi.c:195 +#, c-format +msgid "plpy.execute takes a sequence as its second argument" +msgstr "plpy.execute lấy má»™t chuá»—i làm đối số thứ hai" + +#: plpy_spi.c:305 +#, c-format +msgid "SPI_execute_plan failed: %s" +msgstr "SPI_execute_plan lá»—i: %s" + +#: plpy_spi.c:347 +#, c-format +msgid "SPI_execute failed: %s" +msgstr "SPI_execute lá»—i: %s" + +#: plpy_subxactobject.c:122 +#, c-format +msgid "this subtransaction has already been entered" +msgstr "subtransaction này đã được nhập" + +#: plpy_subxactobject.c:128 plpy_subxactobject.c:186 +#, c-format +msgid "this subtransaction has already been exited" +msgstr "subtransaction này đã được thoát" + +#: plpy_subxactobject.c:180 +#, c-format +msgid "this subtransaction has not been entered" +msgstr "subtransaction này chưa được nhập" + +#: plpy_subxactobject.c:192 +#, c-format +msgid "there is no subtransaction to exit from" +msgstr "không có subtransaction để thoát khá»i" + +#: plpy_typeio.c:591 +#, c-format +msgid "could not import a module for Decimal constructor" +msgstr "không thể nhập mô-Ä‘un cho Decimal constructor" + +#: plpy_typeio.c:595 +#, c-format +msgid "no Decimal attribute in module" +msgstr "không có thuá»™c tính thập phân trong mô-Ä‘un" + +#: plpy_typeio.c:601 +#, c-format +msgid "conversion from numeric to Decimal failed" +msgstr "chuyển đổi từ numeric sang thập phân không thành công" + +#: plpy_typeio.c:908 +#, c-format +msgid "could not create bytes representation of Python object" +msgstr "không thể tạo đại diện cho cá»§a đối tượng Python" + +#: plpy_typeio.c:1056 +#, c-format +msgid "could not create string representation of Python object" +msgstr "không thể tạo ra chuá»—i đại diện cho đối tượng Python" + +#: plpy_typeio.c:1067 +#, c-format +msgid "" +"could not convert Python object into cstring: Python string representation " +"appears to contain null bytes" +msgstr "" +"không thể chuyển đổi đối tượng Python thành cstring: đại diện chuá»—i Python " +"chứa byte null" + +#: plpy_typeio.c:1176 +#, c-format +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "số lượng hướng cá»§a mảng vượt quá số lượng tối Ä‘a cho phép (%d)" + +#: plpy_typeio.c:1180 +#, c-format +msgid "could not determine sequence length for function return value" +msgstr "không thể xác định độ dài chuá»—i cho giá trị trả vá» hàm" + +#: plpy_typeio.c:1183 plpy_typeio.c:1187 +#, c-format +msgid "array size exceeds the maximum allowed" +msgstr "kích thước mảng vượt quá mức tối Ä‘a cho phép" + +#: plpy_typeio.c:1213 +#, c-format +msgid "" +"return value of function with array return type is not a Python sequence" +msgstr "" +"giá trị trả vá» cá»§a hàm vá»›i kiểu trả vá» là mảng không phải là má»™t chuá»—i Python" + +#: plpy_typeio.c:1259 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "sai độ dài cá»§a chuá»—i bên trong: có độ dài %d, nhưng %d được mong đợi" + +#: plpy_typeio.c:1261 +#, c-format +msgid "" +"To construct a multidimensional array, the inner sequences must all have the " +"same length." +msgstr "" +"Äể xây dá»±ng má»™t mảng Ä‘a chiá»u, các chuá»—i bên trong phải có cùng độ dài." + +#: plpy_typeio.c:1340 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "bản ghi literal không đúng định dạng: \"%s\"" + +#: plpy_typeio.c:1341 +#, c-format +msgid "Missing left parenthesis." +msgstr "Thiếu dấu ngoặc đơn trái." + +#: plpy_typeio.c:1342 plpy_typeio.c:1543 +#, c-format +msgid "" +"To return a composite type in an array, return the composite type as a " +"Python tuple, e.g., \"[('foo',)]\"." +msgstr "" +"Äể trả vá» kiểu phức hợp trong má»™t mảng, hãy trả vá» kiểu phức hợp dưới dạng " +"má»™t hàng Python, ví dụ: \"[('foo',)]\"." + +#: plpy_typeio.c:1389 +#, c-format +msgid "key \"%s\" not found in mapping" +msgstr "không tìm thấy khóa \"%s\" trong ánh xạ" + +#: plpy_typeio.c:1390 +#, c-format +msgid "" +"To return null in a column, add the value None to the mapping with the key " +"named after the column." +msgstr "" +"Äể trả vá» null trong má»™t cá»™t, thêm giá trị None vào ánh xạ vá»›i khóa được đặt " +"tên sau cá»™t." + +#: plpy_typeio.c:1443 +#, c-format +msgid "length of returned sequence did not match number of columns in row" +msgstr "độ dài cá»§a chuá»—i được trả vá» không khá»›p vá»›i số cá»™t trong hàng" + +#: plpy_typeio.c:1541 +#, c-format +msgid "attribute \"%s\" does not exist in Python object" +msgstr "thuá»™c tính \"%s\" không tồn tại trong đối tượng Python" + +#: plpy_typeio.c:1544 +#, c-format +msgid "" +"To return null in a column, let the returned object have an attribute named " +"after column with value None." +msgstr "" +"Äể trả vá» null trong má»™t cá»™t, hãy để đối tượng trả vá» có má»™t thuá»™c tính được " +"đặt tên sau cá»™t vá»›i giá trị None." + +#: plpy_util.c:35 +#, c-format +msgid "could not convert Python Unicode object to bytes" +msgstr "không thể chuyển đổi đối tượng Python Unicode thành byte" + +#: plpy_util.c:41 +#, c-format +msgid "could not extract bytes from encoded string" +msgstr "không thể trích xuất byte từ chuá»—i đã được mã hóa" diff --git a/src/pl/plpython/po/zh_CN.po b/src/pl/plpython/po/zh_CN.po index d44eb9dd5e1..64c7532887c 100644 --- a/src/pl/plpython/po/zh_CN.po +++ b/src/pl/plpython/po/zh_CN.po @@ -5,12 +5,12 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-04-18 04:37+0000\n" -"PO-Revision-Date: 2016-05-19 20:47+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Weibin \n" +"Project-Id-Version: plpython (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:08+0000\n" +"PO-Revision-Date: 2019-05-17 18:48+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -18,165 +18,171 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Poedit 1.5.7\n" -#: plpy_cursorobject.c:101 +#: plpy_cursorobject.c:78 #, c-format msgid "plpy.cursor expected a query or a plan" msgstr "plpy.cursor期望一个查询或一个计划" -#: plpy_cursorobject.c:179 +#: plpy_cursorobject.c:161 #, c-format msgid "plpy.cursor takes a sequence as its second argument" msgstr "plpy.cursor将一个åºåˆ—ä½œä¸ºå®ƒçš„ç¬¬äºŒä¸ªå‚æ•°" -#: plpy_cursorobject.c:195 plpy_spi.c:229 +#: plpy_cursorobject.c:177 plpy_spi.c:211 #, c-format msgid "could not execute plan" msgstr "无法执行计划" -#: plpy_cursorobject.c:198 plpy_spi.c:232 +#: plpy_cursorobject.c:180 plpy_spi.c:214 #, c-format msgid "Expected sequence of %d argument, got %d: %s" msgid_plural "Expected sequence of %d arguments, got %d: %s" msgstr[0] "期望%dåºåˆ—傿•°,但是得到%d: %s" # sql_help.h:345 -#: plpy_cursorobject.c:354 +#: plpy_cursorobject.c:329 #, c-format msgid "iterating a closed cursor" msgstr "é历一个关闭的游标" -#: plpy_cursorobject.c:362 plpy_cursorobject.c:427 +#: plpy_cursorobject.c:337 plpy_cursorobject.c:403 #, c-format msgid "iterating a cursor in an aborted subtransaction" msgstr "在终止的å­äº‹åŠ¡é‡Œé历一个游标" # sql_help.h:109 -#: plpy_cursorobject.c:419 +#: plpy_cursorobject.c:395 #, c-format msgid "fetch from a closed cursor" msgstr "从关闭的游标里获å–结果" -#: plpy_cursorobject.c:467 plpy_spi.c:438 +#: plpy_cursorobject.c:438 plpy_spi.c:409 #, c-format msgid "query result has too many rows to fit in a Python list" msgstr "查询结果中的行太多,无法放在一个Python列表中" -#: plpy_cursorobject.c:508 +#: plpy_cursorobject.c:490 #, c-format msgid "closing a cursor in an aborted subtransaction" msgstr "在终止的å­äº‹åŠ¡é‡Œå…³é—­ä¸€ä¸ªæ¸¸æ ‡" -#: plpy_elog.c:127 plpy_elog.c:128 plpy_plpymodule.c:513 +#: plpy_elog.c:129 plpy_elog.c:130 plpy_plpymodule.c:553 #, c-format msgid "%s" msgstr "%s" -#: plpy_exec.c:140 +#: plpy_exec.c:143 #, c-format msgid "unsupported set function return mode" msgstr "䏿”¯æŒé›†åˆå‡½æ•°è¿”回模å¼" -#: plpy_exec.c:141 +#: plpy_exec.c:144 #, c-format -msgid "" -"PL/Python set-returning functions only support returning one value per call." +msgid "PL/Python set-returning functions only support returning one value per call." msgstr "PL/Python集åˆè¿”å›žå‡½æ•°åªæ”¯æŒåœ¨æ¯æ¬¡è°ƒç”¨æ—¶è¿”回一个值。" -#: plpy_exec.c:154 +#: plpy_exec.c:157 #, c-format msgid "returned object cannot be iterated" msgstr "所返回的对象无法迭代" -#: plpy_exec.c:155 +#: plpy_exec.c:158 #, c-format msgid "PL/Python set-returning functions must return an iterable object." msgstr "PL/Python集åˆè¿”回函数必须返回一个å¯è¿­ä»£çš„对象." -#: plpy_exec.c:169 +#: plpy_exec.c:172 #, c-format msgid "error fetching next item from iterator" msgstr "当从迭代器中å–回下一个æˆå‘˜æ—¶å‡ºçŽ°é”™è¯¯" -#: plpy_exec.c:210 +#: plpy_exec.c:215 +#, c-format +msgid "PL/Python procedure did not return None" +msgstr "PL/Python过程没有返回None" + +#: plpy_exec.c:219 #, c-format msgid "PL/Python function with return type \"void\" did not return None" msgstr "返回类型为\"void\"çš„PL/Python函数ä¸è¿”回None" -#: plpy_exec.c:374 plpy_exec.c:400 +#: plpy_exec.c:375 plpy_exec.c:401 #, c-format msgid "unexpected return value from trigger procedure" msgstr "在触å‘å™¨å­˜å‚¨è¿‡ç¨‹å‡ºçŽ°éžæœŸæœ›çš„返回值" -#: plpy_exec.c:375 +#: plpy_exec.c:376 #, c-format msgid "Expected None or a string." msgstr "期望空值或一个字符串" -#: plpy_exec.c:390 +#: plpy_exec.c:391 #, c-format -msgid "" -"PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" +msgid "PL/Python trigger function returned \"MODIFY\" in a DELETE trigger -- ignored" msgstr "在DELETE触å‘器中的PL/Python 触å‘器函数返回 \"MODIFY\" -- 忽略" -#: plpy_exec.c:401 +#: plpy_exec.c:402 #, c-format msgid "Expected None, \"OK\", \"SKIP\", or \"MODIFY\"." msgstr "期望None, \"OK\", \"SKIP\", 或\"MODIFY\"" -#: plpy_exec.c:482 +#: plpy_exec.c:452 #, c-format msgid "PyList_SetItem() failed, while setting up arguments" msgstr "å½“è®¾ç½®å‚æ•°çš„åŒæ—¶, 执行PyList_SetItem()失败" -#: plpy_exec.c:486 +#: plpy_exec.c:456 #, c-format msgid "PyDict_SetItemString() failed, while setting up arguments" msgstr "å½“è®¾ç½®å‚æ•°çš„åŒæ—¶, 执行PyDict_SetItemString()失败" -#: plpy_exec.c:498 +#: plpy_exec.c:468 #, c-format -msgid "" -"function returning record called in context that cannot accept type record" +msgid "function returning record called in context that cannot accept type record" msgstr "è¿”å›žå€¼ç±»åž‹æ˜¯è®°å½•çš„å‡½æ•°åœ¨ä¸æŽ¥å—使用记录类型的环境中调用" -#: plpy_exec.c:714 +#: plpy_exec.c:685 #, c-format msgid "while creating return value" msgstr "åŒæ—¶åœ¨åˆ›å»ºè¿”回值" -#: plpy_exec.c:738 -#, c-format -msgid "could not create new dictionary while building trigger arguments" -msgstr "在构建触å‘噍傿•°çš„åŒæ—¶æ— æ³•创建新的字典." - -#: plpy_exec.c:927 +#: plpy_exec.c:919 #, c-format msgid "TD[\"new\"] deleted, cannot modify row" msgstr "TD[\"new\"] 已删除,无法修改记录" -#: plpy_exec.c:932 +#: plpy_exec.c:924 #, c-format msgid "TD[\"new\"] is not a dictionary" msgstr "TD[\"new\"]䏿˜¯ä¸€ä¸ªå­—å…¸" -#: plpy_exec.c:957 +#: plpy_exec.c:951 #, c-format msgid "TD[\"new\"] dictionary key at ordinal position %d is not a string" msgstr "在顺åºä½ç½®%dçš„TD[\"new\"]字兏键值䏿˜¯å­—符串" -#: plpy_exec.c:964 +#: plpy_exec.c:958 #, c-format -msgid "" -"key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering " -"row" +msgid "key \"%s\" found in TD[\"new\"] does not exist as a column in the triggering row" msgstr "在 TD[\"new\"]中找到的键 \"%s\"在正在触å‘çš„è®°å½•ä¸­ä¸æ˜¯ä½œä¸ºåˆ—而存在." -#: plpy_exec.c:1044 +#: plpy_exec.c:963 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" + +#: plpy_exec.c:968 +#, fuzzy, c-format +#| msgid "cannot set system attribute \"%s\"" +msgid "cannot set generated column \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" + +#: plpy_exec.c:1026 #, c-format msgid "while modifying trigger row" msgstr "åŒæ—¶æ­£åœ¨ä¿®æ”¹è§¦å‘器记录" -#: plpy_exec.c:1105 +#: plpy_exec.c:1087 #, c-format msgid "forcibly aborting a subtransaction that has not been exited" msgstr "强行终止一个还未退出的å­äº‹åŠ¡" @@ -188,7 +194,6 @@ msgstr "会è¯ä¸­å­˜åœ¨å¤šä¸ªPython库" #: plpy_main.c:126 #, c-format -#| msgid "Python major version mismatch in session" msgid "Only one Python major version can be used in one session." msgstr "一个会è¯ä¸­åªèƒ½ä½¿ç”¨ä¸€ä¸ªPython主版本." @@ -202,104 +207,96 @@ msgstr "在åˆå§‹åŒ–过程中出现无法æ•获的错误" msgid "could not import \"__main__\" module" msgstr "无法导入模å—\"__main__\" " -#: plpy_main.c:170 -#, c-format -msgid "could not create globals" -msgstr "无法创建全局å˜é‡" - #: plpy_main.c:174 #, c-format msgid "could not initialize globals" msgstr "无法åˆå§‹åŒ–全局å˜é‡" -#: plpy_main.c:389 +#: plpy_main.c:399 +#, c-format +msgid "PL/Python procedure \"%s\"" +msgstr "PL/Python过程\"%s\"" + +#: plpy_main.c:402 #, c-format msgid "PL/Python function \"%s\"" msgstr "PL/Python函数\"%s\"" -#: plpy_main.c:396 +#: plpy_main.c:410 #, c-format msgid "PL/Python anonymous code block" msgstr "PL/Python匿å代ç å—" -#: plpy_planobject.c:123 -#, c-format -msgid "plan.status takes no arguments" -msgstr "plan.statusä¸å¸¦æœ‰å‚æ•°" - -#: plpy_plpymodule.c:178 plpy_plpymodule.c:181 +#: plpy_plpymodule.c:186 plpy_plpymodule.c:189 #, c-format msgid "could not import \"plpy\" module" msgstr "无法导入模å—\"plpy\" " -#: plpy_plpymodule.c:196 +#: plpy_plpymodule.c:204 #, c-format -msgid "could not add the spiexceptions module" -msgstr "无法添加spiexceptionsæ¨¡å— " +msgid "could not create the spiexceptions module" +msgstr "无法创建spiexceptions模å—" -# fe-connect.c:891 -#: plpy_plpymodule.c:217 +#: plpy_plpymodule.c:212 #, c-format -msgid "could not create the base SPI exceptions" -msgstr "无法创建基本的SPI异常" +msgid "could not add the spiexceptions module" +msgstr "无法添加spiexceptionsæ¨¡å— " -#: plpy_plpymodule.c:252 plpy_plpymodule.c:256 +#: plpy_plpymodule.c:280 #, c-format msgid "could not generate SPI exceptions" msgstr "无法产生SPI异常" -#: plpy_plpymodule.c:421 +#: plpy_plpymodule.c:448 #, c-format msgid "could not unpack arguments in plpy.elog" msgstr "无法解æžplpy.elogä¸­çš„å‚æ•°" -#: plpy_plpymodule.c:430 +#: plpy_plpymodule.c:457 msgid "could not parse error message in plpy.elog" msgstr "无法解æžåœ¨plpy.elog中的错误消æ¯" -#: plpy_plpymodule.c:446 +#: plpy_plpymodule.c:474 #, c-format -#| msgid "type \"%s\" is already defined" -msgid "the message is already specified" -msgstr "该消æ¯å·²ç»è¢«æŒ‡å®š" +msgid "argument 'message' given by name and position" +msgstr "ç”±åç§°å’Œä½ç½®æä¾›çš„傿•°'message'" -#: plpy_plpymodule.c:469 +#: plpy_plpymodule.c:501 #, c-format -#| msgid "%s: invalid argument for -x option\n" msgid "'%s' is an invalid keyword argument for this function" msgstr "对于这个函数,'%s'是一个无效的关键è¯å‚æ•°" -#: plpy_plpymodule.c:477 plpy_plpymodule.c:480 +#: plpy_plpymodule.c:512 plpy_plpymodule.c:518 #, c-format msgid "invalid SQLSTATE code" msgstr "无效的SQLSTATE代ç " -#: plpy_procedure.c:232 +#: plpy_procedure.c:230 #, c-format msgid "trigger functions can only be called as triggers" msgstr "触å‘器函数åªèƒ½ä»¥è§¦å‘器的形å¼è°ƒç”¨" -#: plpy_procedure.c:237 +#: plpy_procedure.c:234 #, c-format msgid "PL/Python functions cannot return type %s" msgstr "PL/Python函数ä¸èƒ½è¿”回类型%s" -#: plpy_procedure.c:318 +#: plpy_procedure.c:312 #, c-format msgid "PL/Python functions cannot accept type %s" msgstr "PL/Python函数ä¸èƒ½æŽ¥å—类型%s" -#: plpy_procedure.c:414 +#: plpy_procedure.c:402 #, c-format msgid "could not compile PL/Python function \"%s\"" msgstr "无法编译PL/Python函数\"%s\"" -#: plpy_procedure.c:417 +#: plpy_procedure.c:405 #, c-format msgid "could not compile anonymous PL/Python code block" msgstr "无法编译PL/Python中的匿å代ç å—" -#: plpy_resultobject.c:145 plpy_resultobject.c:165 plpy_resultobject.c:185 +#: plpy_resultobject.c:121 plpy_resultobject.c:147 plpy_resultobject.c:173 #, c-format msgid "command did not produce a result set" msgstr "命令没有产生结果集" @@ -309,209 +306,157 @@ msgstr "命令没有产生结果集" msgid "second argument of plpy.prepare must be a sequence" msgstr "plpy.prepareçš„ç¬¬äºŒä¸ªå‚æ•°å¿…须是一个åºåˆ—" -#: plpy_spi.c:118 +#: plpy_spi.c:104 #, c-format msgid "plpy.prepare: type name at ordinal position %d is not a string" msgstr "plpy.prepare: 在顺åºä½ç½®%d的类型åç§°ä¸æ˜¯string" -#: plpy_spi.c:194 +#: plpy_spi.c:176 #, c-format msgid "plpy.execute expected a query or a plan" msgstr "plpy.execute期望一个查询或一个计划" -#: plpy_spi.c:213 +#: plpy_spi.c:195 #, c-format msgid "plpy.execute takes a sequence as its second argument" msgstr "plpy.execute将一个åºåˆ—ä½œä¸ºå®ƒçš„ç¬¬äºŒä¸ªå‚æ•°" -#: plpy_spi.c:337 +#: plpy_spi.c:305 #, c-format msgid "SPI_execute_plan failed: %s" msgstr "执行SPI_execute_plan失败: %s" -#: plpy_spi.c:379 +#: plpy_spi.c:347 #, c-format msgid "SPI_execute failed: %s" msgstr "SPI_execute执行失败: %s" -#: plpy_subxactobject.c:123 +#: plpy_subxactobject.c:97 #, c-format msgid "this subtransaction has already been entered" msgstr "å·²ç»è¿›å…¥è¯¥å­äº‹åŠ¡" -#: plpy_subxactobject.c:129 plpy_subxactobject.c:187 +#: plpy_subxactobject.c:103 plpy_subxactobject.c:161 #, c-format msgid "this subtransaction has already been exited" msgstr "å·²ç»é€€å‡ºè¯¥å­äº‹åŠ¡" -#: plpy_subxactobject.c:181 +#: plpy_subxactobject.c:155 #, c-format msgid "this subtransaction has not been entered" msgstr "该å­äº‹åС仿²¡æœ‰è¿›å…¥" -#: plpy_subxactobject.c:193 +#: plpy_subxactobject.c:167 #, c-format msgid "there is no subtransaction to exit from" msgstr "没有å­äº‹åŠ¡å¯ä»¥é€€å‡º" -#: plpy_typeio.c:286 -#, c-format -msgid "could not create new dictionary" -msgstr "无法创建新的字典" - -#: plpy_typeio.c:560 +#: plpy_typeio.c:591 #, c-format msgid "could not import a module for Decimal constructor" msgstr "无法为å进制构造函数导入模å—" -#: plpy_typeio.c:564 +#: plpy_typeio.c:595 #, c-format msgid "no Decimal attribute in module" msgstr "模å—ä¸­æ²¡æœ‰å°æ•°ä½å±žæ€§" -#: plpy_typeio.c:570 +#: plpy_typeio.c:601 #, c-format msgid "conversion from numeric to Decimal failed" msgstr "ç”±numeric数值到Decimalå°æ•°è½¬æ¢å¤±è´¥" -#: plpy_typeio.c:645 +#: plpy_typeio.c:915 #, c-format -msgid "cannot convert multidimensional array to Python list" -msgstr "无法将多维数组转æ¢ä¸ºPython列表" +msgid "could not create bytes representation of Python object" +msgstr "无法创建Python对象的字节表达å¼" -#: plpy_typeio.c:646 +#: plpy_typeio.c:1063 #, c-format -msgid "PL/Python only supports one-dimensional arrays." -msgstr "PL/Pythonåªæ”¯æŒä½¿ç”¨ä¸€ç»´æ•°ç»„" +msgid "could not create string representation of Python object" +msgstr "无法创建Python对象的字符串表达å¼" -#: plpy_typeio.c:652 +#: plpy_typeio.c:1074 #, c-format -msgid "could not create new Python list" -msgstr "无法创建新的Python列表" +msgid "could not convert Python object into cstring: Python string representation appears to contain null bytes" +msgstr "无法将Python对象转æ¢ä¸ºcstring: Python字符串表达å¼å¯èƒ½åŒ…å«ç©ºå­—节" -#: plpy_typeio.c:711 +#: plpy_typeio.c:1183 #, c-format -msgid "could not create bytes representation of Python object" -msgstr "无法创建Python对象的字节表达å¼" +msgid "number of array dimensions exceeds the maximum allowed (%d)" +msgstr "数组的维数超过最大å…许值(%d)" -#: plpy_typeio.c:822 +#: plpy_typeio.c:1187 #, c-format -msgid "could not create string representation of Python object" -msgstr "无法创建Python对象的字符串表达å¼" +msgid "could not determine sequence length for function return value" +msgstr "无法确定函数返回值的åºåˆ—长度" -#: plpy_typeio.c:833 +#: plpy_typeio.c:1190 plpy_typeio.c:1194 #, c-format -msgid "" -"could not convert Python object into cstring: Python string representation " -"appears to contain null bytes" -msgstr "无法将Python对象转æ¢ä¸ºcstring: Python字符串表达å¼å¯èƒ½åŒ…å«ç©ºå­—节" +msgid "array size exceeds the maximum allowed" +msgstr "数组的大å°è¶…过了最大å…许值" -#: plpy_typeio.c:879 +#: plpy_typeio.c:1220 #, c-format -msgid "" -"return value of function with array return type is not a Python sequence" +msgid "return value of function with array return type is not a Python sequence" msgstr "å¸¦æœ‰æ•°ç»„è¿”å›žç±»åž‹çš„å‡½æ•°è¿”å›žå€¼ä¸æ˜¯ä¸€ä¸ªPythonåºåˆ—" -#: plpy_typeio.c:1000 +#: plpy_typeio.c:1266 +#, c-format +msgid "wrong length of inner sequence: has length %d, but %d was expected" +msgstr "内部åºåˆ—的长度错误:长度为%d,但应为%d" + +#: plpy_typeio.c:1268 +#, c-format +msgid "To construct a multidimensional array, the inner sequences must all have the same length." +msgstr "è¦æž„造多维数组,内部åºåˆ—的长度必须相åŒ." + +#: plpy_typeio.c:1347 +#, c-format +msgid "malformed record literal: \"%s\"" +msgstr "有缺陷的记录常é‡: \"%s\"" + +#: plpy_typeio.c:1348 +#, c-format +msgid "Missing left parenthesis." +msgstr "缺少一个左括弧" + +#: plpy_typeio.c:1349 plpy_typeio.c:1550 +#, c-format +msgid "To return a composite type in an array, return the composite type as a Python tuple, e.g., \"[('foo',)]\"." +msgstr "è¦è¿”回数组中的å¤åˆç±»åž‹ï¼Œè¯·å°†å¤åˆç±»åž‹ä½œä¸ºPython元组返回,例如 \"[('foo',)]\"." + +#: plpy_typeio.c:1396 #, c-format msgid "key \"%s\" not found in mapping" msgstr "在映射中没有找到键\"%s\"" -#: plpy_typeio.c:1001 +#: plpy_typeio.c:1397 #, c-format -msgid "" -"To return null in a column, add the value None to the mapping with the key " -"named after the column." +msgid "To return null in a column, add the value None to the mapping with the key named after the column." msgstr "为了在一列中返回空值, 需è¦åœ¨åˆ—çš„åŽé¢å¯¹å¸¦æœ‰å·²å‘½å键的映射添加值None" -#: plpy_typeio.c:1052 +#: plpy_typeio.c:1450 #, c-format msgid "length of returned sequence did not match number of columns in row" msgstr "所返回åºåˆ—的长度与在记录中列的数é‡ä¸åŒ¹é…" -#: plpy_typeio.c:1163 +#: plpy_typeio.c:1548 #, c-format msgid "attribute \"%s\" does not exist in Python object" msgstr "在Python对象中ä¸å­˜åœ¨å±žæ€§\"%s\"" -#: plpy_typeio.c:1164 +#: plpy_typeio.c:1551 #, c-format -msgid "" -"To return null in a column, let the returned object have an attribute named " -"after column with value None." -msgstr "" -"为了在一列中返回空值, 需è¦è®©è¿”回的对象在带有值None的列åŽé¢çš„带有已命å属性" +msgid "To return null in a column, let the returned object have an attribute named after column with value None." +msgstr "为了在一列中返回空值, 需è¦è®©è¿”回的对象在带有值None的列åŽé¢çš„带有已命å属性" -#: plpy_util.c:36 +#: plpy_util.c:35 #, c-format msgid "could not convert Python Unicode object to bytes" msgstr "无法将Python中以Unicodeç¼–ç çš„对象转æ¢ä¸ºPostgreSQLæœåŠ¡å™¨å­—èŠ‚ç " -#: plpy_util.c:42 +#: plpy_util.c:41 #, c-format msgid "could not extract bytes from encoded string" msgstr "无法从已编ç å­—符串里æå–相应字节ç å€¼" - -#~ msgid "plpy.prepare does not support composite types" -#~ msgstr "plpy.prepare䏿”¯æŒä½¿ç”¨ç»„åˆç±»åž‹" - -#~ msgid "PL/Python does not support conversion to arrays of row types." -#~ msgstr "PL/Python䏿”¯æŒå¯¹è¡Œç±»åž‹æ•°ç»„的转æ¢ã€‚" - -#~ msgid "PyCObject_AsVoidPtr() failed" -#~ msgstr "执行PyCObject_AsVoidPtr()失败" - -#~ msgid "PyCObject_FromVoidPtr() failed" -#~ msgstr "执行PyCObject_FromVoidPtr()失败" - -#~ msgid "transaction aborted" -#~ msgstr "事务终止" - -#~ msgid "invalid arguments for plpy.prepare" -#~ msgstr " plpy.prepareçš„æ— æ•ˆå‚æ•°" - -#~ msgid "unrecognized error in PLy_spi_prepare" -#~ msgstr "在PLy_spi_prepare中无法识别的错误" - -#~ msgid "unrecognized error in PLy_spi_execute_plan" -#~ msgstr "在PLy_spi_execute_plan中出现无法识别的错误" - -#~ msgid "unrecognized error in PLy_spi_execute_query" -#~ msgstr "在PLy_spi_execute_query中出现无法识别的错误" - -#~ msgid "could not create procedure cache" -#~ msgstr "无法创建存储过程缓存" - -#~ msgid "PL/Python: %s" -#~ msgstr "PL/Python: %s" - -#~ msgid "out of memory" -#~ msgstr "内存用尽" - -#~ msgid "" -#~ "could not compute string representation of Python object in PL/Python " -#~ "function \"%s\" while modifying trigger row" -#~ msgstr "" -#~ "在修改触å‘å™¨è®°å½•çš„åŒæ—¶æ— æ³•计算在PL/Python函数\"%s\"中Python对象的字符串表" -#~ "è¾¾å¼" - -#~ msgid "" -#~ "could not create string representation of Python object in PL/Python " -#~ "function \"%s\" while creating return value" -#~ msgstr "" -#~ "在创建返回值时, 无法计算在PL/Python函数\"%s\"中Python对象的字符串表达å¼" - -#~ msgid "PL/Python function \"%s\" failed" -#~ msgstr "PL/Python函数 \"%s\" 执行失败" - -#~ msgid "unrecognized error in PLy_spi_execute_fetch_result" -#~ msgstr "在PLy_spi_execute_fetch_result中出现无法识别的错误" - -#~ msgid "Start a new session to use a different Python major version." -#~ msgstr "å¯åŠ¨ä¸€ä¸ªæ–°çš„ä¼šè¯æ¥ä½¿ç”¨ä¸€ä¸ªä¸åŒçš„Python的主è¦ç‰ˆæœ¬" - -#~ msgid "" -#~ "This session has previously used Python major version %d, and it is now " -#~ "attempting to use Python major version %d." -#~ msgstr "" -#~ "这个会è¯å…ˆå‰å·²ç»ä½¿ç”¨çš„Python主版本是%d,现在它试图使用的Python主版本是%d " diff --git a/src/pl/plpython/sql/plpython_subtransaction.sql b/src/pl/plpython/sql/plpython_subtransaction.sql index 3c188e3dd2d..398c65720ce 100644 --- a/src/pl/plpython/sql/plpython_subtransaction.sql +++ b/src/pl/plpython/sql/plpython_subtransaction.sql @@ -80,7 +80,7 @@ with plpy.subtransaction(): except plpy.SPIError, e: if not swallow: raise - plpy.notice("Swallowed %r" % e) + plpy.notice("Swallowed %s(%r)" % (e.__class__.__name__, e.args[0])) return "ok" $$ LANGUAGE plpythonu; diff --git a/src/pl/plpython/sql/plpython_trigger.sql b/src/pl/plpython/sql/plpython_trigger.sql index 79c24b714b5..19852dc5851 100644 --- a/src/pl/plpython/sql/plpython_trigger.sql +++ b/src/pl/plpython/sql/plpython_trigger.sql @@ -67,6 +67,11 @@ SELECT * FROM users; CREATE TABLE trigger_test (i int, v text ); +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); + CREATE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpythonu AS $$ if 'relid' in TD: @@ -109,6 +114,21 @@ DROP TRIGGER show_trigger_data_trig_stmt on trigger_test; DROP TRIGGER show_trigger_data_trig_before on trigger_test; DROP TRIGGER show_trigger_data_trig_after on trigger_test; +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); + +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); + +insert into trigger_test_generated (i) values (1); +update trigger_test_generated set i = 11 where i = 1; +delete from trigger_test_generated; + +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; + insert into trigger_test values(1,'insert'); CREATE VIEW trigger_test_view AS SELECT * FROM trigger_test; @@ -430,3 +450,20 @@ UPDATE transition_table_test SET name = 'b'; DROP TABLE transition_table_test; DROP FUNCTION transition_table_test_f(); + + +-- dealing with generated columns + +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE plpythonu +AS $$ +TD['new']['j'] = 5 # not allowed +return 'MODIFY' +$$; + +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); + +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +SELECT * FROM trigger_test_generated; diff --git a/src/pl/tcl/Makefile b/src/pl/tcl/Makefile index ef61ee596e0..8ee4c3ff156 100644 --- a/src/pl/tcl/Makefile +++ b/src/pl/tcl/Makefile @@ -28,7 +28,7 @@ DATA = pltcl.control pltcl--1.0.sql pltcl--unpackaged--1.0.sql \ pltclu.control pltclu--1.0.sql pltclu--unpackaged--1.0.sql REGRESS_OPTS = --dbname=$(PL_TESTDB) --load-extension=pltcl -REGRESS = pltcl_setup pltcl_queries pltcl_call pltcl_start_proc pltcl_subxact pltcl_unicode pltcl_transaction +REGRESS = pltcl_setup pltcl_queries pltcl_trigger pltcl_call pltcl_start_proc pltcl_subxact pltcl_unicode pltcl_transaction # Tcl on win32 ships with import libraries only for Microsoft Visual C++, # which are not compatible with mingw gcc. Therefore we need to build a diff --git a/src/pl/tcl/expected/pltcl_queries.out b/src/pl/tcl/expected/pltcl_queries.out index 736671cc1bc..2d922c2333e 100644 --- a/src/pl/tcl/expected/pltcl_queries.out +++ b/src/pl/tcl/expected/pltcl_queries.out @@ -1,319 +1,5 @@ -- suppress CONTEXT so that function OIDs aren't in output \set VERBOSITY terse -insert into T_pkey1 values (1, 'key1-1', 'test key'); -insert into T_pkey1 values (1, 'key1-2', 'test key'); -insert into T_pkey1 values (1, 'key1-3', 'test key'); -insert into T_pkey1 values (2, 'key2-1', 'test key'); -insert into T_pkey1 values (2, 'key2-2', 'test key'); -insert into T_pkey1 values (2, 'key2-3', 'test key'); -insert into T_pkey2 values (1, 'key1-1', 'test key'); -insert into T_pkey2 values (1, 'key1-2', 'test key'); -insert into T_pkey2 values (1, 'key1-3', 'test key'); -insert into T_pkey2 values (2, 'key2-1', 'test key'); -insert into T_pkey2 values (2, 'key2-2', 'test key'); -insert into T_pkey2 values (2, 'key2-3', 'test key'); -select * from T_pkey1; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | key1-1 | test key - 1 | key1-2 | test key - 1 | key1-3 | test key - 2 | key2-1 | test key - 2 | key2-2 | test key - 2 | key2-3 | test key -(6 rows) - --- key2 in T_pkey2 should have upper case only -select * from T_pkey2; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | KEY1-1 | test key - 1 | KEY1-2 | test key - 1 | KEY1-3 | test key - 2 | KEY2-1 | test key - 2 | KEY2-2 | test key - 2 | KEY2-3 | test key -(6 rows) - -insert into T_pkey1 values (1, 'KEY1-3', 'should work'); --- Due to the upper case translation in trigger this must fail -insert into T_pkey2 values (1, 'KEY1-3', 'should fail'); -ERROR: duplicate key '1', 'KEY1-3' for T_pkey2 -insert into T_dta1 values ('trec 1', 1, 'key1-1'); -insert into T_dta1 values ('trec 2', 1, 'key1-2'); -insert into T_dta1 values ('trec 3', 1, 'key1-3'); --- Must fail due to unknown key in T_pkey1 -insert into T_dta1 values ('trec 4', 1, 'key1-4'); -ERROR: key for t_dta1 not in t_pkey1 -insert into T_dta2 values ('trec 1', 1, 'KEY1-1'); -insert into T_dta2 values ('trec 2', 1, 'KEY1-2'); -insert into T_dta2 values ('trec 3', 1, 'KEY1-3'); --- Must fail due to unknown key in T_pkey2 -insert into T_dta2 values ('trec 4', 1, 'KEY1-4'); -ERROR: key for t_dta2 not in t_pkey2 -select * from T_dta1; - tkey | ref1 | ref2 -------------+------+---------------------- - trec 1 | 1 | key1-1 - trec 2 | 1 | key1-2 - trec 3 | 1 | key1-3 -(3 rows) - -select * from T_dta2; - tkey | ref1 | ref2 -------------+------+---------------------- - trec 1 | 1 | KEY1-1 - trec 2 | 1 | KEY1-2 - trec 3 | 1 | KEY1-3 -(3 rows) - -update T_pkey1 set key2 = 'key2-9' where key1 = 2 and key2 = 'key2-1'; -update T_pkey1 set key2 = 'key1-9' where key1 = 1 and key2 = 'key1-1'; -ERROR: key '1', 'key1-1 ' referenced by T_dta1 -delete from T_pkey1 where key1 = 2 and key2 = 'key2-2'; -delete from T_pkey1 where key1 = 1 and key2 = 'key1-2'; -ERROR: key '1', 'key1-2 ' referenced by T_dta1 -update T_pkey2 set key2 = 'KEY2-9' where key1 = 2 and key2 = 'KEY2-1'; -update T_pkey2 set key2 = 'KEY1-9' where key1 = 1 and key2 = 'KEY1-1'; -NOTICE: updated 1 entries in T_dta2 for new key in T_pkey2 -delete from T_pkey2 where key1 = 2 and key2 = 'KEY2-2'; -delete from T_pkey2 where key1 = 1 and key2 = 'KEY1-2'; -NOTICE: deleted 1 entries from T_dta2 -select * from T_pkey1; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | key1-1 | test key - 1 | key1-2 | test key - 1 | key1-3 | test key - 2 | key2-3 | test key - 1 | KEY1-3 | should work - 2 | key2-9 | test key -(6 rows) - -select * from T_pkey2; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | KEY1-3 | test key - 2 | KEY2-3 | test key - 2 | KEY2-9 | test key - 1 | KEY1-9 | test key -(4 rows) - -select * from T_dta1; - tkey | ref1 | ref2 -------------+------+---------------------- - trec 1 | 1 | key1-1 - trec 2 | 1 | key1-2 - trec 3 | 1 | key1-3 -(3 rows) - -select * from T_dta2; - tkey | ref1 | ref2 -------------+------+---------------------- - trec 3 | 1 | KEY1-3 - trec 1 | 1 | KEY1-9 -(2 rows) - -select tcl_avg(key1) from T_pkey1; - tcl_avg ---------- - 1 -(1 row) - -select tcl_sum(key1) from T_pkey1; - tcl_sum ---------- - 8 -(1 row) - -select tcl_avg(key1) from T_pkey2; - tcl_avg ---------- - 1 -(1 row) - -select tcl_sum(key1) from T_pkey2; - tcl_sum ---------- - 6 -(1 row) - --- The following should return NULL instead of 0 -select tcl_avg(key1) from T_pkey1 where key1 = 99; - tcl_avg ---------- - -(1 row) - -select tcl_sum(key1) from T_pkey1 where key1 = 99; - tcl_sum ---------- - 0 -(1 row) - -select 1 @< 2; - ?column? ----------- - t -(1 row) - -select 100 @< 4; - ?column? ----------- - f -(1 row) - -select * from T_pkey1 order by key1 using @<, key2 collate "C"; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | KEY1-3 | should work - 1 | key1-1 | test key - 1 | key1-2 | test key - 1 | key1-3 | test key - 2 | key2-3 | test key - 2 | key2-9 | test key -(6 rows) - -select * from T_pkey2 order by key1 using @<, key2 collate "C"; - key1 | key2 | txt -------+----------------------+------------------------------------------ - 1 | KEY1-3 | test key - 1 | KEY1-9 | test key - 2 | KEY2-3 | test key - 2 | KEY2-9 | test key -(4 rows) - --- show dump of trigger data -insert into trigger_test values(1,'insert'); -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: INSERT -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert} -NOTICE: OLD: {} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_trig -NOTICE: TG_op: INSERT -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {23 skidoo} -insert into trigger_test_view values(2,'insert'); -NOTICE: NEW: {i: 2, v: insert} -NOTICE: OLD: {} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_view_trig -NOTICE: TG_op: INSERT -NOTICE: TG_relatts: {{} i v} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test_view -NOTICE: TG_table_schema: public -NOTICE: TG_when: {INSTEAD OF} -NOTICE: args: {24 {skidoo view}} -update trigger_test_view set v = 'update' where i=1; -NOTICE: NEW: {i: 1, v: update} -NOTICE: OLD: {i: 1, v: insert} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_view_trig -NOTICE: TG_op: UPDATE -NOTICE: TG_relatts: {{} i v} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test_view -NOTICE: TG_table_schema: public -NOTICE: TG_when: {INSTEAD OF} -NOTICE: args: {24 {skidoo view}} -delete from trigger_test_view; -NOTICE: NEW: {} -NOTICE: OLD: {i: 1, v: insert} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_view_trig -NOTICE: TG_op: DELETE -NOTICE: TG_relatts: {{} i v} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test_view -NOTICE: TG_table_schema: public -NOTICE: TG_when: {INSTEAD OF} -NOTICE: args: {24 {skidoo view}} -update trigger_test set v = 'update', test_skip=true where i = 1; -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: UPDATE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -NOTICE: SKIPPING OPERATION UPDATE -update trigger_test set v = 'update' where i = 1; -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: UPDATE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update} -NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_trig -NOTICE: TG_op: UPDATE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {23 skidoo} -delete from trigger_test; -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: DELETE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -NOTICE: NEW: {} -NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update} -NOTICE: TG_level: ROW -NOTICE: TG_name: show_trigger_data_trig -NOTICE: TG_op: DELETE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {23 skidoo} -truncate trigger_test; -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: TRUNCATE -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -- Test composite-type arguments select tcl_composite_arg_ref1(row('tkey', 42, 'ref2')); tcl_composite_arg_ref1 @@ -328,17 +14,17 @@ select tcl_composite_arg_ref2(row('tkey', 42, 'ref2')); (1 row) -- More tests for composite argument/result types -create domain d_dta1 as T_dta1 check ((value).ref1 > 0); +create domain d_comp1 as T_comp1 check ((value).ref1 > 0); create function tcl_record_arg(record, fldname text) returns int as ' return $1($2) ' language pltcl; -select tcl_record_arg(row('tkey', 42, 'ref2')::T_dta1, 'ref1'); +select tcl_record_arg(row('tkey', 42, 'ref2')::T_comp1, 'ref1'); tcl_record_arg ---------------- 42 (1 row) -select tcl_record_arg(row('tkey', 42, 'ref2')::d_dta1, 'ref1'); +select tcl_record_arg(row('tkey', 42, 'ref2')::d_comp1, 'ref1'); tcl_record_arg ---------------- 42 @@ -350,7 +36,7 @@ select tcl_record_arg(row(2,4), 'f2'); 4 (1 row) -create function tcl_cdomain_arg(d_dta1) returns int as ' +create function tcl_cdomain_arg(d_comp1) returns int as ' return $1(ref1) ' language pltcl; select tcl_cdomain_arg(row('tkey', 42, 'ref2')); @@ -359,14 +45,14 @@ select tcl_cdomain_arg(row('tkey', 42, 'ref2')); 42 (1 row) -select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_dta1); +select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_comp1); tcl_cdomain_arg ----------------- 42 (1 row) select tcl_cdomain_arg(row('tkey', -1, 'ref2')); -- fail -ERROR: value for domain d_dta1 violates check constraint "d_dta1_check" +ERROR: value for domain d_comp1 violates check constraint "d_comp1_check" -- Test argisnull primitive select tcl_argisnull('foo'); tcl_argisnull @@ -386,37 +72,6 @@ select tcl_argisnull(null); t (1 row) --- should error -insert into trigger_test(test_argisnull) values(true); -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: INSERT -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -ERROR: argisnull cannot be used in triggers -select trigger_data(); -ERROR: trigger functions can only be called as triggers --- Test spi_lastoid primitive -create temp table t1 (f1 int); -select tcl_lastoid('t1'); - tcl_lastoid -------------- - 0 -(1 row) - -create temp table t2 (f1 int) with oids; -select tcl_lastoid('t2') > 0; - ?column? ----------- - t -(1 row) - -- test some error cases create function tcl_error(out a int, out b int) as $$return {$$ language pltcl; select tcl_error(); @@ -479,7 +134,7 @@ $$ language pltcl; select bad_field_srf(); ERROR: column name/value list contains nonexistent column name "cow" -- test composite and domain-over-composite results -create function tcl_composite_result(int) returns T_dta1 as $$ +create function tcl_composite_result(int) returns T_comp1 as $$ return [list tkey tkey1 ref1 $1 ref2 ref22] $$ language pltcl; select tcl_composite_result(1001); @@ -494,7 +149,7 @@ select * from tcl_composite_result(1002); tkey1 | 1002 | ref22 (1 row) -create function tcl_dcomposite_result(int) returns d_dta1 as $$ +create function tcl_dcomposite_result(int) returns d_comp1 as $$ return [list tkey tkey2 ref1 $1 ref2 ref42] $$ language pltcl; select tcl_dcomposite_result(1001); @@ -510,7 +165,7 @@ select * from tcl_dcomposite_result(1002); (1 row) select * from tcl_dcomposite_result(-1); -- fail -ERROR: value for domain d_dta1 violates check constraint "d_dta1_check" +ERROR: value for domain d_comp1 violates check constraint "d_comp1_check" create function tcl_record_result(int) returns record as $$ return [list q1 sometext q2 $1 q3 moretext] $$ language pltcl; @@ -557,20 +212,6 @@ ERROR: expected integer but got "abc" -- Test return_null select tcl_eval('return_null 14'); ERROR: wrong # args: should be "return_null " --- should error -insert into trigger_test(test_return_null) values(true); -NOTICE: NEW: {} -NOTICE: OLD: {} -NOTICE: TG_level: STATEMENT -NOTICE: TG_name: statement_trigger -NOTICE: TG_op: INSERT -NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} -NOTICE: TG_relid: bogus:12345 -NOTICE: TG_table_name: trigger_test -NOTICE: TG_table_schema: public -NOTICE: TG_when: BEFORE -NOTICE: args: {42 {statement trigger}} -ERROR: return_null cannot be used in triggers -- Test spi_exec select tcl_eval('spi_exec'); ERROR: wrong # args: should be "spi_exec ?-count n? ?-array name? query ?loop body?" @@ -754,24 +395,3 @@ select tcl_eval($$ (1 row) --- test transition table visibility -create table transition_table_test (id int, name text); -insert into transition_table_test values (1, 'a'); -create function transition_table_test_f() returns trigger language pltcl as -$$ - spi_exec -array C "SELECT id, name FROM old_table" { - elog INFO "old: $C(id) -> $C(name)" - } - spi_exec -array C "SELECT id, name FROM new_table" { - elog INFO "new: $C(id) -> $C(name)" - } - return OK -$$; -CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); -update transition_table_test set name = 'b'; -INFO: old: 1 -> a -INFO: new: 1 -> b -drop table transition_table_test; -drop function transition_table_test_f(); diff --git a/src/pl/tcl/expected/pltcl_setup.out b/src/pl/tcl/expected/pltcl_setup.out index f1958c3a984..ed809f02bfb 100644 --- a/src/pl/tcl/expected/pltcl_setup.out +++ b/src/pl/tcl/expected/pltcl_setup.out @@ -1,440 +1,17 @@ --- --- Create the tables used in the test queries --- --- T_pkey1 is the primary key table for T_dta1. Entries from T_pkey1 --- Cannot be changed or deleted if they are referenced from T_dta1. --- --- T_pkey2 is the primary key table for T_dta2. If the key values in --- T_pkey2 are changed, the references in T_dta2 follow. If entries --- are deleted, the referencing entries from T_dta2 are deleted too. --- The values for field key2 in T_pkey2 are silently converted to --- upper case on insert/update. --- -create table T_pkey1 ( - key1 int4, - key2 char(20), - txt char(40) -); -create table T_pkey2 ( - key1 int4, - key2 char(20), - txt char(40) -); -create table T_dta1 ( - tkey char(10), - ref1 int4, - ref2 char(20) -); -create table T_dta2 ( +create table T_comp1 ( tkey char(10), ref1 int4, ref2 char(20) ); --- --- Function to check key existence in T_pkey1 --- -create function check_pkey1_exists(int4, bpchar) returns bool as E' - if {![info exists GD]} { - set GD(plan) [spi_prepare \\ - "select 1 from T_pkey1 \\ - where key1 = \\$1 and key2 = \\$2" \\ - {int4 bpchar}] - } - - set n [spi_execp -count 1 $GD(plan) [list $1 $2]] - - if {$n > 0} { - return "t" - } - return "f" -' language pltcl; --- dump trigger data -CREATE TABLE trigger_test ( - i int, - v text, - dropme text, - test_skip boolean DEFAULT false, - test_return_null boolean DEFAULT false, - test_argisnull boolean DEFAULT false -); --- Make certain dropped attributes are handled correctly -ALTER TABLE trigger_test DROP dropme; -CREATE VIEW trigger_test_view AS SELECT i, v FROM trigger_test; -CREATE FUNCTION trigger_data() returns trigger language pltcl as $_$ - if {$TG_table_name eq "trigger_test" && $TG_level eq "ROW" && $TG_op ne "DELETE"} { - # Special case tests - if {$NEW(test_return_null) eq "t" } { - return_null - } - if {$NEW(test_argisnull) eq "t" } { - set should_error [argisnull 1] - } - if {$NEW(test_skip) eq "t" } { - elog NOTICE "SKIPPING OPERATION $TG_op" - return SKIP - } - } - - if { [info exists TG_relid] } { - set TG_relid "bogus:12345" - } - - set dnames [info locals {[a-zA-Z]*} ] - - foreach key [lsort $dnames] { - - if { [array exists $key] } { - set str "{" - foreach akey [lsort [ array names $key ] ] { - if {[string length $str] > 1} { set str "$str, " } - set cmd "($akey)" - set cmd "set val \$$key$cmd" - eval $cmd - set str "$str$akey: $val" - } - set str "$str}" - elog NOTICE "$key: $str" - } else { - set val [eval list "\$$key" ] - elog NOTICE "$key: $val" - } - } - - - return OK - -$_$; -CREATE TRIGGER show_trigger_data_trig -BEFORE INSERT OR UPDATE OR DELETE ON trigger_test -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -CREATE TRIGGER statement_trigger -BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE ON trigger_test -FOR EACH STATEMENT EXECUTE PROCEDURE trigger_data(42,'statement trigger'); -CREATE TRIGGER show_trigger_data_view_trig -INSTEAD OF INSERT OR UPDATE OR DELETE ON trigger_test_view -FOR EACH ROW EXECUTE PROCEDURE trigger_data(24,'skidoo view'); --- --- Trigger function on every change to T_pkey1 --- -create function trig_pkey1_before() returns trigger as E' - # - # Create prepared plans on the first call - # - if {![info exists GD]} { - # - # Plan to check for duplicate key in T_pkey1 - # - set GD(plan_pkey1) [spi_prepare \\ - "select check_pkey1_exists(\\$1, \\$2) as ret" \\ - {int4 bpchar}] - # - # Plan to check for references from T_dta1 - # - set GD(plan_dta1) [spi_prepare \\ - "select 1 from T_dta1 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Initialize flags - # - set check_old_ref 0 - set check_new_dup 0 - - switch $TG_op { - INSERT { - # - # Must check for duplicate key on INSERT - # - set check_new_dup 1 - } - UPDATE { - # - # Must check for duplicate key on UPDATE only if - # the key changes. In that case we must check for - # references to OLD values too. - # - if {[string compare $NEW(key1) $OLD(key1)] != 0} { - set check_old_ref 1 - set check_new_dup 1 - } - if {[string compare $NEW(key2) $OLD(key2)] != 0} { - set check_old_ref 1 - set check_new_dup 1 - } - } - DELETE { - # - # Must only check for references to OLD on DELETE - # - set check_old_ref 1 - } - } - - if {$check_new_dup} { - # - # Check for duplicate key - # - spi_execp -count 1 $GD(plan_pkey1) [list $NEW(key1) $NEW(key2)] - if {$ret == "t"} { - elog ERROR \\ - "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey1" - } - } - - if {$check_old_ref} { - # - # Check for references to OLD - # - set n [spi_execp -count 1 $GD(plan_dta1) [list $OLD(key1) $OLD(key2)]] - if {$n > 0} { - elog ERROR \\ - "key ''$OLD(key1)'', ''$OLD(key2)'' referenced by T_dta1" - } - } - - # - # Anything is fine - let operation pass through - # - return OK -' language pltcl; -create trigger pkey1_before before insert or update or delete on T_pkey1 - for each row execute procedure - trig_pkey1_before(); --- --- Trigger function to check for duplicate keys in T_pkey2 --- and to force key2 to be upper case only without leading whitespaces --- -create function trig_pkey2_before() returns trigger as E' - # - # Prepare plan on first call - # - if {![info exists GD]} { - set GD(plan_pkey2) [spi_prepare \\ - "select 1 from T_pkey2 \\ - where key1 = \\$1 and key2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Convert key2 value - # - set NEW(key2) [string toupper [string trim $NEW(key2)]] - - # - # Check for duplicate key - # - set n [spi_execp -count 1 $GD(plan_pkey2) [list $NEW(key1) $NEW(key2)]] - if {$n > 0} { - elog ERROR \\ - "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey2" - } - - # - # Return modified tuple in NEW - # - return [array get NEW] -' language pltcl; -create trigger pkey2_before before insert or update on T_pkey2 - for each row execute procedure - trig_pkey2_before(); --- --- Trigger function to force references from T_dta2 follow changes --- in T_pkey2 or be deleted too. This must be done AFTER the changes --- in T_pkey2 are done so the trigger for primkey check on T_dta2 --- fired on our updates will see the new key values in T_pkey2. --- -create function trig_pkey2_after() returns trigger as E' - # - # Prepare plans on first call - # - if {![info exists GD]} { - # - # Plan to update references from T_dta2 - # - set GD(plan_dta2_upd) [spi_prepare \\ - "update T_dta2 set ref1 = \\$3, ref2 = \\$4 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar int4 bpchar}] - # - # Plan to delete references from T_dta2 - # - set GD(plan_dta2_del) [spi_prepare \\ - "delete from T_dta2 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Initialize flags - # - set old_ref_follow 0 - set old_ref_delete 0 - - switch $TG_op { - UPDATE { - # - # On update we must let old references follow - # - set NEW(key2) [string toupper $NEW(key2)] - - if {[string compare $NEW(key1) $OLD(key1)] != 0} { - set old_ref_follow 1 - } - if {[string compare $NEW(key2) $OLD(key2)] != 0} { - set old_ref_follow 1 - } - } - DELETE { - # - # On delete we must delete references too - # - set old_ref_delete 1 - } - } - - if {$old_ref_follow} { - # - # Let old references follow and fire NOTICE message if - # there where some - # - set n [spi_execp $GD(plan_dta2_upd) \\ - [list $OLD(key1) $OLD(key2) $NEW(key1) $NEW(key2)]] - if {$n > 0} { - elog NOTICE \\ - "updated $n entries in T_dta2 for new key in T_pkey2" - } - } - - if {$old_ref_delete} { - # - # delete references and fire NOTICE message if - # there where some - # - set n [spi_execp $GD(plan_dta2_del) \\ - [list $OLD(key1) $OLD(key2)]] - if {$n > 0} { - elog NOTICE \\ - "deleted $n entries from T_dta2" - } - } - - return OK -' language pltcl; -create trigger pkey2_after after update or delete on T_pkey2 - for each row execute procedure - trig_pkey2_after(); --- --- Generic trigger function to check references in T_dta1 and T_dta2 --- -create function check_primkey() returns trigger as E' - # - # For every trigger/relation pair we create - # a saved plan and hold them in GD - # - set plankey [list "plan" $TG_name $TG_relid] - set planrel [list "relname" $TG_relid] - - # - # Extract the pkey relation name - # - set keyidx [expr [llength $args] / 2] - set keyrel [string tolower [lindex $args $keyidx]] - - if {![info exists GD($plankey)]} { - # - # We must prepare a new plan. Build up a query string - # for the primary key check. - # - set keylist [lrange $args [expr $keyidx + 1] end] - - set query "select 1 from $keyrel" - set qual " where" - set typlist "" - set idx 1 - foreach key $keylist { - set key [string tolower $key] - # - # Add the qual part to the query string - # - append query "$qual $key = \\$$idx" - set qual " and" - - # - # Lookup the fields type in pg_attribute - # - set n [spi_exec "select T.typname \\ - from pg_catalog.pg_type T, pg_catalog.pg_attribute A, pg_catalog.pg_class C \\ - where C.relname = ''[quote $keyrel]'' \\ - and C.oid = A.attrelid \\ - and A.attname = ''[quote $key]'' \\ - and A.atttypid = T.oid"] - if {$n != 1} { - elog ERROR "table $keyrel doesn''t have a field named $key" - } - - # - # Append the fields type to the argument type list - # - lappend typlist $typname - incr idx - } - - # - # Prepare the plan - # - set GD($plankey) [spi_prepare $query $typlist] - - # - # Lookup and remember the table name for later error messages - # - spi_exec "select relname from pg_catalog.pg_class \\ - where oid = ''$TG_relid''::oid" - set GD($planrel) $relname - } - - # - # Build the argument list from the NEW row - # - incr keyidx -1 - set arglist "" - foreach arg [lrange $args 0 $keyidx] { - lappend arglist $NEW($arg) - } - - # - # Check for the primary key - # - set n [spi_execp -count 1 $GD($plankey) $arglist] - if {$n <= 0} { - elog ERROR "key for $GD($planrel) not in $keyrel" - } - - # - # Anything is fine - # - return OK -' language pltcl; -create trigger dta1_before before insert or update on T_dta1 - for each row execute procedure - check_primkey('ref1', 'ref2', 'T_pkey1', 'key1', 'key2'); -create trigger dta2_before before insert or update on T_dta2 - for each row execute procedure - check_primkey('ref1', 'ref2', 'T_pkey2', 'key1', 'key2'); -create function tcl_composite_arg_ref1(T_dta1) returns int as ' +create function tcl_composite_arg_ref1(T_comp1) returns int as ' return $1(ref1) ' language pltcl; -create function tcl_composite_arg_ref2(T_dta1) returns text as ' +create function tcl_composite_arg_ref2(T_comp1) returns text as ' return $1(ref2) ' language pltcl; create function tcl_argisnull(text) returns bool as ' argisnull 1 ' language pltcl; -create function tcl_lastoid(tabname text) returns int8 as ' - spi_exec "insert into $1 default values" - spi_lastoid -' language pltcl; create function tcl_int4add(int4,int4) returns int4 as ' return [expr $1 + $2] ' language pltcl; diff --git a/src/pl/tcl/expected/pltcl_subxact.out b/src/pl/tcl/expected/pltcl_subxact.out index 4393f4acf69..5e19bbbc636 100644 --- a/src/pl/tcl/expected/pltcl_subxact.out +++ b/src/pl/tcl/expected/pltcl_subxact.out @@ -71,9 +71,9 @@ SELECT * FROM subtransaction_tbl; TRUNCATE subtransaction_tbl; SELECT pltcl_wrapper('SELECT subtransaction_ctx_test(''SPI'')'); - pltcl_wrapper -------------------------------------------------- - ERROR: invalid input syntax for integer: "oops" + pltcl_wrapper +------------------------------------------------------ + ERROR: invalid input syntax for type integer: "oops" (1 row) SELECT * FROM subtransaction_tbl; diff --git a/src/pl/tcl/expected/pltcl_trigger.out b/src/pl/tcl/expected/pltcl_trigger.out new file mode 100644 index 00000000000..008ea195095 --- /dev/null +++ b/src/pl/tcl/expected/pltcl_trigger.out @@ -0,0 +1,888 @@ +-- suppress CONTEXT so that function OIDs aren't in output +\set VERBOSITY terse +-- +-- Create the tables used in the test queries +-- +-- T_pkey1 is the primary key table for T_dta1. Entries from T_pkey1 +-- Cannot be changed or deleted if they are referenced from T_dta1. +-- +-- T_pkey2 is the primary key table for T_dta2. If the key values in +-- T_pkey2 are changed, the references in T_dta2 follow. If entries +-- are deleted, the referencing entries from T_dta2 are deleted too. +-- The values for field key2 in T_pkey2 are silently converted to +-- upper case on insert/update. +-- +create table T_pkey1 ( + key1 int4, + key2 char(20), + txt char(40) +); +create table T_pkey2 ( + key1 int4, + key2 char(20), + txt char(40) +); +create table T_dta1 ( + tkey char(10), + ref1 int4, + ref2 char(20) +); +create table T_dta2 ( + tkey char(10), + ref1 int4, + ref2 char(20) +); +-- +-- Function to check key existence in T_pkey1 +-- +create function check_pkey1_exists(int4, bpchar) returns bool as E' + if {![info exists GD]} { + set GD(plan) [spi_prepare \\ + "select 1 from T_pkey1 \\ + where key1 = \\$1 and key2 = \\$2" \\ + {int4 bpchar}] + } + + set n [spi_execp -count 1 $GD(plan) [list $1 $2]] + + if {$n > 0} { + return "t" + } + return "f" +' language pltcl; +-- dump trigger data +CREATE TABLE trigger_test ( + i int, + v text, + dropme text, + test_skip boolean DEFAULT false, + test_return_null boolean DEFAULT false, + test_argisnull boolean DEFAULT false +); +-- Make certain dropped attributes are handled correctly +ALTER TABLE trigger_test DROP dropme; +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); +CREATE VIEW trigger_test_view AS SELECT i, v FROM trigger_test; +CREATE FUNCTION trigger_data() returns trigger language pltcl as $_$ + if {$TG_table_name eq "trigger_test" && $TG_level eq "ROW" && $TG_op ne "DELETE"} { + # Special case tests + if {$NEW(test_return_null) eq "t" } { + return_null + } + if {$NEW(test_argisnull) eq "t" } { + set should_error [argisnull 1] + } + if {$NEW(test_skip) eq "t" } { + elog NOTICE "SKIPPING OPERATION $TG_op" + return SKIP + } + } + + if { [info exists TG_relid] } { + set TG_relid "bogus:12345" + } + + set dnames [info locals {[a-zA-Z]*} ] + + foreach key [lsort $dnames] { + + if { [array exists $key] } { + set str "{" + foreach akey [lsort [ array names $key ] ] { + if {[string length $str] > 1} { set str "$str, " } + set cmd "($akey)" + set cmd "set val \$$key$cmd" + eval $cmd + set str "$str$akey: $val" + } + set str "$str}" + elog NOTICE "$key: $str" + } else { + set val [eval list "\$$key" ] + elog NOTICE "$key: $val" + } + } + + + return OK + +$_$; +CREATE TRIGGER show_trigger_data_trig +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +CREATE TRIGGER statement_trigger +BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE ON trigger_test +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_data(42,'statement trigger'); +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +CREATE TRIGGER show_trigger_data_view_trig +INSTEAD OF INSERT OR UPDATE OR DELETE ON trigger_test_view +FOR EACH ROW EXECUTE PROCEDURE trigger_data(24,'skidoo view'); +-- +-- Trigger function on every change to T_pkey1 +-- +create function trig_pkey1_before() returns trigger as E' + # + # Create prepared plans on the first call + # + if {![info exists GD]} { + # + # Plan to check for duplicate key in T_pkey1 + # + set GD(plan_pkey1) [spi_prepare \\ + "select check_pkey1_exists(\\$1, \\$2) as ret" \\ + {int4 bpchar}] + # + # Plan to check for references from T_dta1 + # + set GD(plan_dta1) [spi_prepare \\ + "select 1 from T_dta1 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Initialize flags + # + set check_old_ref 0 + set check_new_dup 0 + + switch $TG_op { + INSERT { + # + # Must check for duplicate key on INSERT + # + set check_new_dup 1 + } + UPDATE { + # + # Must check for duplicate key on UPDATE only if + # the key changes. In that case we must check for + # references to OLD values too. + # + if {[string compare $NEW(key1) $OLD(key1)] != 0} { + set check_old_ref 1 + set check_new_dup 1 + } + if {[string compare $NEW(key2) $OLD(key2)] != 0} { + set check_old_ref 1 + set check_new_dup 1 + } + } + DELETE { + # + # Must only check for references to OLD on DELETE + # + set check_old_ref 1 + } + } + + if {$check_new_dup} { + # + # Check for duplicate key + # + spi_execp -count 1 $GD(plan_pkey1) [list $NEW(key1) $NEW(key2)] + if {$ret == "t"} { + elog ERROR \\ + "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey1" + } + } + + if {$check_old_ref} { + # + # Check for references to OLD + # + set n [spi_execp -count 1 $GD(plan_dta1) [list $OLD(key1) $OLD(key2)]] + if {$n > 0} { + elog ERROR \\ + "key ''$OLD(key1)'', ''$OLD(key2)'' referenced by T_dta1" + } + } + + # + # Anything is fine - let operation pass through + # + return OK +' language pltcl; +create trigger pkey1_before before insert or update or delete on T_pkey1 + for each row execute procedure + trig_pkey1_before(); +-- +-- Trigger function to check for duplicate keys in T_pkey2 +-- and to force key2 to be upper case only without leading whitespaces +-- +create function trig_pkey2_before() returns trigger as E' + # + # Prepare plan on first call + # + if {![info exists GD]} { + set GD(plan_pkey2) [spi_prepare \\ + "select 1 from T_pkey2 \\ + where key1 = \\$1 and key2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Convert key2 value + # + set NEW(key2) [string toupper [string trim $NEW(key2)]] + + # + # Check for duplicate key + # + set n [spi_execp -count 1 $GD(plan_pkey2) [list $NEW(key1) $NEW(key2)]] + if {$n > 0} { + elog ERROR \\ + "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey2" + } + + # + # Return modified tuple in NEW + # + return [array get NEW] +' language pltcl; +create trigger pkey2_before before insert or update on T_pkey2 + for each row execute procedure + trig_pkey2_before(); +-- +-- Trigger function to force references from T_dta2 follow changes +-- in T_pkey2 or be deleted too. This must be done AFTER the changes +-- in T_pkey2 are done so the trigger for primkey check on T_dta2 +-- fired on our updates will see the new key values in T_pkey2. +-- +create function trig_pkey2_after() returns trigger as E' + # + # Prepare plans on first call + # + if {![info exists GD]} { + # + # Plan to update references from T_dta2 + # + set GD(plan_dta2_upd) [spi_prepare \\ + "update T_dta2 set ref1 = \\$3, ref2 = \\$4 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar int4 bpchar}] + # + # Plan to delete references from T_dta2 + # + set GD(plan_dta2_del) [spi_prepare \\ + "delete from T_dta2 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Initialize flags + # + set old_ref_follow 0 + set old_ref_delete 0 + + switch $TG_op { + UPDATE { + # + # On update we must let old references follow + # + set NEW(key2) [string toupper $NEW(key2)] + + if {[string compare $NEW(key1) $OLD(key1)] != 0} { + set old_ref_follow 1 + } + if {[string compare $NEW(key2) $OLD(key2)] != 0} { + set old_ref_follow 1 + } + } + DELETE { + # + # On delete we must delete references too + # + set old_ref_delete 1 + } + } + + if {$old_ref_follow} { + # + # Let old references follow and fire NOTICE message if + # there where some + # + set n [spi_execp $GD(plan_dta2_upd) \\ + [list $OLD(key1) $OLD(key2) $NEW(key1) $NEW(key2)]] + if {$n > 0} { + elog NOTICE \\ + "updated $n entries in T_dta2 for new key in T_pkey2" + } + } + + if {$old_ref_delete} { + # + # delete references and fire NOTICE message if + # there where some + # + set n [spi_execp $GD(plan_dta2_del) \\ + [list $OLD(key1) $OLD(key2)]] + if {$n > 0} { + elog NOTICE \\ + "deleted $n entries from T_dta2" + } + } + + return OK +' language pltcl; +create trigger pkey2_after after update or delete on T_pkey2 + for each row execute procedure + trig_pkey2_after(); +-- +-- Generic trigger function to check references in T_dta1 and T_dta2 +-- +create function check_primkey() returns trigger as E' + # + # For every trigger/relation pair we create + # a saved plan and hold them in GD + # + set plankey [list "plan" $TG_name $TG_relid] + set planrel [list "relname" $TG_relid] + + # + # Extract the pkey relation name + # + set keyidx [expr [llength $args] / 2] + set keyrel [string tolower [lindex $args $keyidx]] + + if {![info exists GD($plankey)]} { + # + # We must prepare a new plan. Build up a query string + # for the primary key check. + # + set keylist [lrange $args [expr $keyidx + 1] end] + + set query "select 1 from $keyrel" + set qual " where" + set typlist "" + set idx 1 + foreach key $keylist { + set key [string tolower $key] + # + # Add the qual part to the query string + # + append query "$qual $key = \\$$idx" + set qual " and" + + # + # Lookup the fields type in pg_attribute + # + set n [spi_exec "select T.typname \\ + from pg_catalog.pg_type T, pg_catalog.pg_attribute A, pg_catalog.pg_class C \\ + where C.relname = ''[quote $keyrel]'' \\ + and C.oid = A.attrelid \\ + and A.attname = ''[quote $key]'' \\ + and A.atttypid = T.oid"] + if {$n != 1} { + elog ERROR "table $keyrel doesn''t have a field named $key" + } + + # + # Append the fields type to the argument type list + # + lappend typlist $typname + incr idx + } + + # + # Prepare the plan + # + set GD($plankey) [spi_prepare $query $typlist] + + # + # Lookup and remember the table name for later error messages + # + spi_exec "select relname from pg_catalog.pg_class \\ + where oid = ''$TG_relid''::oid" + set GD($planrel) $relname + } + + # + # Build the argument list from the NEW row + # + incr keyidx -1 + set arglist "" + foreach arg [lrange $args 0 $keyidx] { + lappend arglist $NEW($arg) + } + + # + # Check for the primary key + # + set n [spi_execp -count 1 $GD($plankey) $arglist] + if {$n <= 0} { + elog ERROR "key for $GD($planrel) not in $keyrel" + } + + # + # Anything is fine + # + return OK +' language pltcl; +create trigger dta1_before before insert or update on T_dta1 + for each row execute procedure + check_primkey('ref1', 'ref2', 'T_pkey1', 'key1', 'key2'); +create trigger dta2_before before insert or update on T_dta2 + for each row execute procedure + check_primkey('ref1', 'ref2', 'T_pkey2', 'key1', 'key2'); +insert into T_pkey1 values (1, 'key1-1', 'test key'); +insert into T_pkey1 values (1, 'key1-2', 'test key'); +insert into T_pkey1 values (1, 'key1-3', 'test key'); +insert into T_pkey1 values (2, 'key2-1', 'test key'); +insert into T_pkey1 values (2, 'key2-2', 'test key'); +insert into T_pkey1 values (2, 'key2-3', 'test key'); +insert into T_pkey2 values (1, 'key1-1', 'test key'); +insert into T_pkey2 values (1, 'key1-2', 'test key'); +insert into T_pkey2 values (1, 'key1-3', 'test key'); +insert into T_pkey2 values (2, 'key2-1', 'test key'); +insert into T_pkey2 values (2, 'key2-2', 'test key'); +insert into T_pkey2 values (2, 'key2-3', 'test key'); +select * from T_pkey1; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | key1-1 | test key + 1 | key1-2 | test key + 1 | key1-3 | test key + 2 | key2-1 | test key + 2 | key2-2 | test key + 2 | key2-3 | test key +(6 rows) + +-- key2 in T_pkey2 should have upper case only +select * from T_pkey2; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | KEY1-1 | test key + 1 | KEY1-2 | test key + 1 | KEY1-3 | test key + 2 | KEY2-1 | test key + 2 | KEY2-2 | test key + 2 | KEY2-3 | test key +(6 rows) + +insert into T_pkey1 values (1, 'KEY1-3', 'should work'); +-- Due to the upper case translation in trigger this must fail +insert into T_pkey2 values (1, 'KEY1-3', 'should fail'); +ERROR: duplicate key '1', 'KEY1-3' for T_pkey2 +insert into T_dta1 values ('trec 1', 1, 'key1-1'); +insert into T_dta1 values ('trec 2', 1, 'key1-2'); +insert into T_dta1 values ('trec 3', 1, 'key1-3'); +-- Must fail due to unknown key in T_pkey1 +insert into T_dta1 values ('trec 4', 1, 'key1-4'); +ERROR: key for t_dta1 not in t_pkey1 +insert into T_dta2 values ('trec 1', 1, 'KEY1-1'); +insert into T_dta2 values ('trec 2', 1, 'KEY1-2'); +insert into T_dta2 values ('trec 3', 1, 'KEY1-3'); +-- Must fail due to unknown key in T_pkey2 +insert into T_dta2 values ('trec 4', 1, 'KEY1-4'); +ERROR: key for t_dta2 not in t_pkey2 +select * from T_dta1; + tkey | ref1 | ref2 +------------+------+---------------------- + trec 1 | 1 | key1-1 + trec 2 | 1 | key1-2 + trec 3 | 1 | key1-3 +(3 rows) + +select * from T_dta2; + tkey | ref1 | ref2 +------------+------+---------------------- + trec 1 | 1 | KEY1-1 + trec 2 | 1 | KEY1-2 + trec 3 | 1 | KEY1-3 +(3 rows) + +update T_pkey1 set key2 = 'key2-9' where key1 = 2 and key2 = 'key2-1'; +update T_pkey1 set key2 = 'key1-9' where key1 = 1 and key2 = 'key1-1'; +ERROR: key '1', 'key1-1 ' referenced by T_dta1 +delete from T_pkey1 where key1 = 2 and key2 = 'key2-2'; +delete from T_pkey1 where key1 = 1 and key2 = 'key1-2'; +ERROR: key '1', 'key1-2 ' referenced by T_dta1 +update T_pkey2 set key2 = 'KEY2-9' where key1 = 2 and key2 = 'KEY2-1'; +update T_pkey2 set key2 = 'KEY1-9' where key1 = 1 and key2 = 'KEY1-1'; +NOTICE: updated 1 entries in T_dta2 for new key in T_pkey2 +delete from T_pkey2 where key1 = 2 and key2 = 'KEY2-2'; +delete from T_pkey2 where key1 = 1 and key2 = 'KEY1-2'; +NOTICE: deleted 1 entries from T_dta2 +select * from T_pkey1; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | key1-1 | test key + 1 | key1-2 | test key + 1 | key1-3 | test key + 2 | key2-3 | test key + 1 | KEY1-3 | should work + 2 | key2-9 | test key +(6 rows) + +select * from T_pkey2; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | KEY1-3 | test key + 2 | KEY2-3 | test key + 2 | KEY2-9 | test key + 1 | KEY1-9 | test key +(4 rows) + +select * from T_dta1; + tkey | ref1 | ref2 +------------+------+---------------------- + trec 1 | 1 | key1-1 + trec 2 | 1 | key1-2 + trec 3 | 1 | key1-3 +(3 rows) + +select * from T_dta2; + tkey | ref1 | ref2 +------------+------+---------------------- + trec 3 | 1 | KEY1-3 + trec 1 | 1 | KEY1-9 +(2 rows) + +select tcl_avg(key1) from T_pkey1; + tcl_avg +--------- + 1 +(1 row) + +select tcl_sum(key1) from T_pkey1; + tcl_sum +--------- + 8 +(1 row) + +select tcl_avg(key1) from T_pkey2; + tcl_avg +--------- + 1 +(1 row) + +select tcl_sum(key1) from T_pkey2; + tcl_sum +--------- + 6 +(1 row) + +-- The following should return NULL instead of 0 +select tcl_avg(key1) from T_pkey1 where key1 = 99; + tcl_avg +--------- + +(1 row) + +select tcl_sum(key1) from T_pkey1 where key1 = 99; + tcl_sum +--------- + 0 +(1 row) + +select 1 @< 2; + ?column? +---------- + t +(1 row) + +select 100 @< 4; + ?column? +---------- + f +(1 row) + +select * from T_pkey1 order by key1 using @<, key2 collate "C"; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | KEY1-3 | should work + 1 | key1-1 | test key + 1 | key1-2 | test key + 1 | key1-3 | test key + 2 | key2-3 | test key + 2 | key2-9 | test key +(6 rows) + +select * from T_pkey2 order by key1 using @<, key2 collate "C"; + key1 | key2 | txt +------+----------------------+------------------------------------------ + 1 | KEY1-3 | test key + 1 | KEY1-9 | test key + 2 | KEY2-3 | test key + 2 | KEY2-9 | test key +(4 rows) + +-- show dump of trigger data +insert into trigger_test values(1,'insert'); +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert} +NOTICE: OLD: {} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {23 skidoo} +insert into trigger_test_generated (i) values (1); +NOTICE: NEW: {i: 1} +NOTICE: OLD: {} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_before +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {} +NOTICE: NEW: {i: 1, j: 2} +NOTICE: OLD: {} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_after +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: AFTER +NOTICE: args: {} +update trigger_test_generated set i = 11 where i = 1; +NOTICE: NEW: {i: 11} +NOTICE: OLD: {i: 1, j: 2} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_before +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {} +NOTICE: NEW: {i: 11, j: 22} +NOTICE: OLD: {i: 1, j: 2} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_after +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: AFTER +NOTICE: args: {} +delete from trigger_test_generated; +NOTICE: NEW: {} +NOTICE: OLD: {i: 11, j: 22} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_before +NOTICE: TG_op: DELETE +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {} +NOTICE: NEW: {} +NOTICE: OLD: {i: 11, j: 22} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig_after +NOTICE: TG_op: DELETE +NOTICE: TG_relatts: {{} i j} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_generated +NOTICE: TG_table_schema: public +NOTICE: TG_when: AFTER +NOTICE: args: {} +insert into trigger_test_view values(2,'insert'); +NOTICE: NEW: {i: 2, v: insert} +NOTICE: OLD: {} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_view_trig +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i v} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_view +NOTICE: TG_table_schema: public +NOTICE: TG_when: {INSTEAD OF} +NOTICE: args: {24 {skidoo view}} +update trigger_test_view set v = 'update' where i=1; +NOTICE: NEW: {i: 1, v: update} +NOTICE: OLD: {i: 1, v: insert} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_view_trig +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i v} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_view +NOTICE: TG_table_schema: public +NOTICE: TG_when: {INSTEAD OF} +NOTICE: args: {24 {skidoo view}} +delete from trigger_test_view; +NOTICE: NEW: {} +NOTICE: OLD: {i: 1, v: insert} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_view_trig +NOTICE: TG_op: DELETE +NOTICE: TG_relatts: {{} i v} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test_view +NOTICE: TG_table_schema: public +NOTICE: TG_when: {INSTEAD OF} +NOTICE: args: {24 {skidoo view}} +update trigger_test set v = 'update', test_skip=true where i = 1; +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +NOTICE: SKIPPING OPERATION UPDATE +update trigger_test set v = 'update' where i = 1; +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +NOTICE: NEW: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update} +NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: insert} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig +NOTICE: TG_op: UPDATE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {23 skidoo} +delete from trigger_test; +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: DELETE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +NOTICE: NEW: {} +NOTICE: OLD: {i: 1, test_argisnull: f, test_return_null: f, test_skip: f, v: update} +NOTICE: TG_level: ROW +NOTICE: TG_name: show_trigger_data_trig +NOTICE: TG_op: DELETE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {23 skidoo} +truncate trigger_test; +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: TRUNCATE +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; +-- should error +insert into trigger_test(test_argisnull) values(true); +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +ERROR: argisnull cannot be used in triggers +-- should error +insert into trigger_test(test_return_null) values(true); +NOTICE: NEW: {} +NOTICE: OLD: {} +NOTICE: TG_level: STATEMENT +NOTICE: TG_name: statement_trigger +NOTICE: TG_op: INSERT +NOTICE: TG_relatts: {{} i v {} test_skip test_return_null test_argisnull} +NOTICE: TG_relid: bogus:12345 +NOTICE: TG_table_name: trigger_test +NOTICE: TG_table_schema: public +NOTICE: TG_when: BEFORE +NOTICE: args: {42 {statement trigger}} +ERROR: return_null cannot be used in triggers +-- test transition table visibility +create table transition_table_test (id int, name text); +insert into transition_table_test values (1, 'a'); +create function transition_table_test_f() returns trigger language pltcl as +$$ + spi_exec -array C "SELECT id, name FROM old_table" { + elog INFO "old: $C(id) -> $C(name)" + } + spi_exec -array C "SELECT id, name FROM new_table" { + elog INFO "new: $C(id) -> $C(name)" + } + return OK +$$; +CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); +update transition_table_test set name = 'b'; +INFO: old: 1 -> a +INFO: new: 1 -> b +drop table transition_table_test; +drop function transition_table_test_f(); +-- dealing with generated columns +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE pltcl +AS $$ +# not allowed +set NEW(j) 5 +return [array get NEW] +$$; +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +ERROR: cannot set generated column "j" +SELECT * FROM trigger_test_generated; + i | j +---+--- +(0 rows) + diff --git a/src/pl/tcl/generate-pltclerrcodes.pl b/src/pl/tcl/generate-pltclerrcodes.pl index b5a595510cb..11132c55584 100644 --- a/src/pl/tcl/generate-pltclerrcodes.pl +++ b/src/pl/tcl/generate-pltclerrcodes.pl @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Generate the pltclerrcodes.h header from errcodes.txt -# Copyright (c) 2000-2018, PostgreSQL Global Development Group +# Copyright (c) 2000-2019, PostgreSQL Global Development Group use warnings; use strict; diff --git a/src/pl/tcl/nls.mk b/src/pl/tcl/nls.mk index f896dcbfa43..88c2679375c 100644 --- a/src/pl/tcl/nls.mk +++ b/src/pl/tcl/nls.mk @@ -1,6 +1,6 @@ # src/pl/tcl/nls.mk CATALOG_NAME = pltcl -AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv tr zh_CN zh_TW +AVAIL_LANGUAGES = cs de es fr it ja ko pl pt_BR ro ru sv tr vi zh_CN zh_TW GETTEXT_FILES = pltcl.c GETTEXT_TRIGGERS = $(BACKEND_COMMON_GETTEXT_TRIGGERS) GETTEXT_FLAGS = $(BACKEND_COMMON_GETTEXT_FLAGS) diff --git a/src/pl/tcl/pltcl--1.0.sql b/src/pl/tcl/pltcl--1.0.sql index ecb264c818f..34a68c8471f 100644 --- a/src/pl/tcl/pltcl--1.0.sql +++ b/src/pl/tcl/pltcl--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE pltcl; +CREATE LANGUAGE pltcl; -COMMENT ON PROCEDURAL LANGUAGE pltcl IS 'PL/Tcl procedural language'; +COMMENT ON LANGUAGE pltcl IS 'PL/Tcl procedural language'; diff --git a/src/pl/tcl/pltcl--unpackaged--1.0.sql b/src/pl/tcl/pltcl--unpackaged--1.0.sql index dfad66c268b..294125892af 100644 --- a/src/pl/tcl/pltcl--unpackaged--1.0.sql +++ b/src/pl/tcl/pltcl--unpackaged--1.0.sql @@ -1,5 +1,5 @@ /* src/pl/tcl/pltcl--unpackaged--1.0.sql */ -ALTER EXTENSION pltcl ADD PROCEDURAL LANGUAGE pltcl; +ALTER EXTENSION pltcl ADD LANGUAGE pltcl; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION pltcl ADD FUNCTION pltcl_call_handler(); diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 558cabc9493..8277d1ea857 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -263,7 +263,7 @@ static const TclExceptionNameMap exception_name_map[] = { void _PG_init(void); static void pltcl_init_interp(pltcl_interp_desc *interp_desc, - Oid prolang, bool pltrusted); + Oid prolang, bool pltrusted); static pltcl_interp_desc *pltcl_fetch_interp(Oid prolang, bool pltrusted); static void call_pltcl_start_proc(Oid prolang, bool pltrusted); static void start_proc_error_callback(void *arg); @@ -271,65 +271,63 @@ static void start_proc_error_callback(void *arg); static Datum pltcl_handler(PG_FUNCTION_ARGS, bool pltrusted); static Datum pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, - bool pltrusted); + bool pltrusted); static HeapTuple pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, - bool pltrusted); + bool pltrusted); static void pltcl_event_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, - bool pltrusted); + bool pltrusted); static void throw_tcl_error(Tcl_Interp *interp, const char *proname); static pltcl_proc_desc *compile_pltcl_function(Oid fn_oid, Oid tgreloid, - bool is_event_trigger, - bool pltrusted); + bool is_event_trigger, + bool pltrusted); -static int pltcl_elog(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); +static int pltcl_elog(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static void pltcl_construct_errorCode(Tcl_Interp *interp, ErrorData *edata); static const char *pltcl_get_condition_name(int sqlstate); -static int pltcl_quote(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_returnnext(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_SPI_execute(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_process_SPI_result(Tcl_Interp *interp, - const char *arrayname, - Tcl_Obj *loop_body, - int spi_rc, - SPITupleTable *tuptable, - uint64 ntuples); -static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_subtransaction(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_commit(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); -static int pltcl_rollback(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); +static int pltcl_quote(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_argisnull(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_returnnull(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_returnnext(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_SPI_execute(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_process_SPI_result(Tcl_Interp *interp, + const char *arrayname, + Tcl_Obj *loop_body, + int spi_rc, + SPITupleTable *tuptable, + uint64 ntuples); +static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_subtransaction(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_commit(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); +static int pltcl_rollback(ClientData cdata, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static void pltcl_subtrans_begin(MemoryContext oldcontext, - ResourceOwner oldowner); + ResourceOwner oldowner); static void pltcl_subtrans_commit(MemoryContext oldcontext, - ResourceOwner oldowner); + ResourceOwner oldowner); static void pltcl_subtrans_abort(Tcl_Interp *interp, - MemoryContext oldcontext, - ResourceOwner oldowner); + MemoryContext oldcontext, + ResourceOwner oldowner); static void pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname, - uint64 tupno, HeapTuple tuple, TupleDesc tupdesc); -static Tcl_Obj *pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc); + uint64 tupno, HeapTuple tuple, TupleDesc tupdesc); +static Tcl_Obj *pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, bool include_generated); static HeapTuple pltcl_build_tuple_result(Tcl_Interp *interp, - Tcl_Obj **kvObjv, int kvObjc, - pltcl_call_state *call_state); + Tcl_Obj **kvObjv, int kvObjc, + pltcl_call_state *call_state); static void pltcl_init_tuple_store(pltcl_call_state *call_state); @@ -523,8 +521,6 @@ pltcl_init_interp(pltcl_interp_desc *interp_desc, Oid prolang, bool pltrusted) pltcl_SPI_prepare, NULL, NULL); Tcl_CreateObjCommand(interp, "spi_execp", pltcl_SPI_execute_plan, NULL, NULL); - Tcl_CreateObjCommand(interp, "spi_lastoid", - pltcl_SPI_lastoid, NULL, NULL); Tcl_CreateObjCommand(interp, "subtransaction", pltcl_subtransaction, NULL, NULL); Tcl_CreateObjCommand(interp, "commit", @@ -591,6 +587,7 @@ pltcl_fetch_interp(Oid prolang, bool pltrusted) static void call_pltcl_start_proc(Oid prolang, bool pltrusted) { + LOCAL_FCINFO(fcinfo, 0); char *start_proc; const char *gucname; ErrorContextCallback errcallback; @@ -601,7 +598,6 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted) Form_pg_proc procStruct; AclResult aclresult; FmgrInfo finfo; - FunctionCallInfoData fcinfo; PgStat_FunctionCallUsage fcusage; /* select appropriate GUC */ @@ -614,7 +610,7 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted) /* Set up errcontext callback to make errors more helpful */ errcallback.callback = start_proc_error_callback; - errcallback.arg = (void *) gucname; + errcallback.arg = unconstify(char *, gucname); errcallback.previous = error_context_stack; error_context_stack = &errcallback; @@ -662,11 +658,11 @@ call_pltcl_start_proc(Oid prolang, bool pltrusted) */ InvokeFunctionExecuteHook(procOid); fmgr_info(procOid, &finfo); - InitFunctionCallInfoData(fcinfo, &finfo, + InitFunctionCallInfoData(*fcinfo, &finfo, 0, InvalidOid, NULL, NULL); - pgstat_init_function_usage(&fcinfo, &fcusage); - (void) FunctionCallInvoke(&fcinfo); + pgstat_init_function_usage(fcinfo, &fcusage); + (void) FunctionCallInvoke(fcinfo); pgstat_end_function_usage(&fcusage, true); /* Pop the error context stack */ @@ -873,7 +869,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, /************************************************** * For tuple values, add a list for 'array set ...' **************************************************/ - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj()); else { @@ -884,7 +880,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, HeapTupleData tmptup; Tcl_Obj *list_tmp; - td = DatumGetHeapTupleHeader(fcinfo->arg[i]); + td = DatumGetHeapTupleHeader(fcinfo->args[i].value); /* Extract rowtype info and find a tupdesc */ tupType = HeapTupleHeaderGetTypeId(td); tupTypmod = HeapTupleHeaderGetTypMod(td); @@ -893,7 +889,7 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, tmptup.t_len = HeapTupleHeaderGetDatumLength(td); tmptup.t_data = td; - list_tmp = pltcl_build_tuple_argument(&tmptup, tupdesc); + list_tmp = pltcl_build_tuple_argument(&tmptup, tupdesc, true); Tcl_ListObjAppendElement(NULL, tcl_cmd, list_tmp); ReleaseTupleDesc(tupdesc); @@ -905,14 +901,14 @@ pltcl_func_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, * Single values are added as string element * of their external representation **************************************************/ - if (fcinfo->argnull[i]) + if (fcinfo->args[i].isnull) Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj()); else { char *tmp; tmp = OutputFunctionCall(&prodesc->arg_out_func[i], - fcinfo->arg[i]); + fcinfo->args[i].value); UTF_BEGIN; Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewStringObj(UTF_E2U(tmp), -1)); @@ -1064,7 +1060,6 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, volatile HeapTuple rettup; Tcl_Obj *tcl_cmd; Tcl_Obj *tcl_trigtup; - Tcl_Obj *tcl_newtup; int tcl_rc; int i; const char *result; @@ -1166,20 +1161,22 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewStringObj("ROW", -1)); - /* Build the data list for the trigtuple */ - tcl_trigtup = pltcl_build_tuple_argument(trigdata->tg_trigtuple, - tupdesc); - /* * Now the command part of the event for TG_op and data for NEW * and OLD + * + * Note: In BEFORE trigger, stored generated columns are not + * computed yet, so don't make them accessible in NEW row. */ if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) { Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewStringObj("INSERT", -1)); - Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup); + Tcl_ListObjAppendElement(NULL, tcl_cmd, + pltcl_build_tuple_argument(trigdata->tg_trigtuple, + tupdesc, + !TRIGGER_FIRED_BEFORE(trigdata->tg_event))); Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj()); rettup = trigdata->tg_trigtuple; @@ -1190,7 +1187,10 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, Tcl_NewStringObj("DELETE", -1)); Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewObj()); - Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup); + Tcl_ListObjAppendElement(NULL, tcl_cmd, + pltcl_build_tuple_argument(trigdata->tg_trigtuple, + tupdesc, + true)); rettup = trigdata->tg_trigtuple; } @@ -1199,11 +1199,14 @@ pltcl_trigger_handler(PG_FUNCTION_ARGS, pltcl_call_state *call_state, Tcl_ListObjAppendElement(NULL, tcl_cmd, Tcl_NewStringObj("UPDATE", -1)); - tcl_newtup = pltcl_build_tuple_argument(trigdata->tg_newtuple, - tupdesc); - - Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_newtup); - Tcl_ListObjAppendElement(NULL, tcl_cmd, tcl_trigtup); + Tcl_ListObjAppendElement(NULL, tcl_cmd, + pltcl_build_tuple_argument(trigdata->tg_newtuple, + tupdesc, + !TRIGGER_FIRED_BEFORE(trigdata->tg_event))); + Tcl_ListObjAppendElement(NULL, tcl_cmd, + pltcl_build_tuple_argument(trigdata->tg_trigtuple, + tupdesc, + true)); rettup = trigdata->tg_newtuple; } @@ -1631,7 +1634,7 @@ compile_pltcl_function(Oid fn_oid, Oid tgreloid, /************************************************************ * prefix procedure body with - * upvar #0 GD + * upvar #0 GD * and with appropriate setting of arguments ************************************************************/ Tcl_DStringAppend(&proc_internal_body, "upvar #0 ", -1); @@ -2451,7 +2454,8 @@ pltcl_process_SPI_result(Tcl_Interp *interp, Tcl_SetObjResult(interp, Tcl_NewIntObj(0)); break; } - /* FALL THRU for utility returning tuples */ + /* fall through for utility returning tuples */ + /* FALLTHROUGH */ case SPI_OK_SELECT: case SPI_OK_INSERT_RETURNING: @@ -2761,7 +2765,7 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, } /************************************************************ - * If there was a argtype list on preparation, we need + * If there was an argtype list on preparation, we need * an argument value list now ************************************************************/ if (qdesc->nargs > 0) @@ -2872,28 +2876,6 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp, } -/********************************************************************** - * pltcl_SPI_lastoid() - return the last oid. To - * be used after insert queries - **********************************************************************/ -static int -pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - /* - * Check call syntax - */ - if (objc != 1) - { - Tcl_WrongNumArgs(interp, 1, objv, ""); - return TCL_ERROR; - } - - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(SPI_lastoid)); - return TCL_OK; -} - - /********************************************************************** * pltcl_subtransaction() - Execute some Tcl code in a subtransaction * @@ -3045,7 +3027,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname, const char *nullname = NULL; /************************************************************ - * Prepare pointers for Tcl_SetVar2() below + * Prepare pointers for Tcl_SetVar2Ex() below ************************************************************/ if (arrayname == NULL) { @@ -3106,7 +3088,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname, else Tcl_UnsetVar2(interp, *arrptr, *nameptr, 0); - pfree((char *) attname); + pfree(unconstify(char *, attname)); } } @@ -3116,7 +3098,7 @@ pltcl_set_tuple_values(Tcl_Interp *interp, const char *arrayname, * from all attributes of a given tuple **********************************************************************/ static Tcl_Obj * -pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc) +pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc, bool include_generated) { Tcl_Obj *retobj = Tcl_NewObj(); int i; @@ -3135,6 +3117,13 @@ pltcl_build_tuple_argument(HeapTuple tuple, TupleDesc tupdesc) if (att->attisdropped) continue; + if (att->attgenerated) + { + /* don't include unless requested */ + if (!include_generated) + continue; + } + /************************************************************ * Get the attribute name ************************************************************/ @@ -3244,6 +3233,12 @@ pltcl_build_tuple_result(Tcl_Interp *interp, Tcl_Obj **kvObjv, int kvObjc, errmsg("cannot set system attribute \"%s\"", fieldName))); + if (TupleDescAttr(tupdesc, attn - 1)->attgenerated) + ereport(ERROR, + (errcode(ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED), + errmsg("cannot set generated column \"%s\"", + fieldName))); + values[attn - 1] = utf_u2e(Tcl_GetString(kvObjv[i + 1])); } diff --git a/src/pl/tcl/pltclu--1.0.sql b/src/pl/tcl/pltclu--1.0.sql index 72dcef11e5b..e05b470aaf2 100644 --- a/src/pl/tcl/pltclu--1.0.sql +++ b/src/pl/tcl/pltclu--1.0.sql @@ -6,6 +6,6 @@ * knowledge into this script. */ -CREATE PROCEDURAL LANGUAGE pltclu; +CREATE LANGUAGE pltclu; -COMMENT ON PROCEDURAL LANGUAGE pltclu IS 'PL/TclU untrusted procedural language'; +COMMENT ON LANGUAGE pltclu IS 'PL/TclU untrusted procedural language'; diff --git a/src/pl/tcl/pltclu--unpackaged--1.0.sql b/src/pl/tcl/pltclu--unpackaged--1.0.sql index a5d359fc047..dac18f8d87b 100644 --- a/src/pl/tcl/pltclu--unpackaged--1.0.sql +++ b/src/pl/tcl/pltclu--unpackaged--1.0.sql @@ -1,5 +1,5 @@ /* src/pl/tcl/pltclu--unpackaged--1.0.sql */ -ALTER EXTENSION pltclu ADD PROCEDURAL LANGUAGE pltclu; +ALTER EXTENSION pltclu ADD LANGUAGE pltclu; -- ALTER ADD LANGUAGE doesn't pick up the support functions, so we have to. ALTER EXTENSION pltclu ADD FUNCTION pltclu_call_handler(); diff --git a/src/pl/tcl/po/cs.po b/src/pl/tcl/po/cs.po index e08253a5ed2..d86021a1355 100644 --- a/src/pl/tcl/po/cs.po +++ b/src/pl/tcl/po/cs.po @@ -3,26 +3,65 @@ # This file is distributed under the same license as the PostgreSQL package. # # Tomáš Vondra , 2012, 2013. - msgid "" msgstr "" "Project-Id-Version: pltcl-cs (PostgreSQL 9.3)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2012-04-07 18:18+0200\n" -"PO-Revision-Date: 2012-MO-DA HO:MI+ZONE\n" +"POT-Creation-Date: 2018-07-13 19:37+0000\n" +"PO-Revision-Date: 2018-07-13 23:54+0200\n" "Last-Translator: Tomas Vondra \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.7\n" + +#: pltcl.c:466 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "PL/Tcl funkce kterou zavolat jednou pÅ™i prvním použití pltcl." + +#: pltcl.c:473 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "PL/TclU funkce kterou zavolat jednou pÅ™i prvním použití pltclu." + +#: pltcl.c:640 +#, c-format +msgid "function \"%s\" is in the wrong language" +msgstr "funkce \"%s\" je ve Å¡patném jazyce" + +#: pltcl.c:651 +#, c-format +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "funkce \"%s\" nesmí být SECURITY DEFINER" + +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:685 +#, c-format +msgid "processing %s parameter" +msgstr "zpracovávám %s parametr" + +#: pltcl.c:846 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "set-valued funkce volána v kontextu který nemůže pÅ™ijmout více řádek" + +#: pltcl.c:1019 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "funkce vracející záznam volána v kontextu který nemůže pÅ™ijmout záznam" + +#: pltcl.c:1296 +#, c-format +msgid "could not split return value from trigger: %s" +msgstr "z triggeru nelze oddÄ›lit návratovou hodnotu: %s" -#: pltcl.c:1150 +#: pltcl.c:1376 pltcl.c:1806 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1151 +#: pltcl.c:1377 #, c-format msgid "" "%s\n" @@ -31,27 +70,43 @@ msgstr "" "%s\n" "v PL/Tcl funkci \"%s\"" -#: pltcl.c:1255 pltcl.c:1262 -#, c-format -msgid "out of memory" -msgstr "paměť vyÄerpána" - -#: pltcl.c:1309 +#: pltcl.c:1541 #, c-format msgid "trigger functions can only be called as triggers" msgstr "funkce pro obsluhu triggerů mohou být volané pouze prostÅ™ednictvím triggerů" -#: pltcl.c:1318 +#: pltcl.c:1545 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "PL/Tcl funkce nemohou vracet datový typ %s" -#: pltcl.c:1330 -#, c-format -msgid "PL/Tcl functions cannot return composite types" -msgstr "PL/Tcl funkce nemohou vracet složené datové typy" - -#: pltcl.c:1369 +#: pltcl.c:1584 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "PL/Tcl funkce nemohou pÅ™ijímat datový typ %s" + +#: pltcl.c:1698 +#, c-format +msgid "could not create internal procedure \"%s\": %s" +msgstr "nelze vytvoÅ™it interní proceduru \"%s\": %s" + +#: pltcl.c:3220 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "seznam názvů sloupců a hodnot musí mít sudý poÄet položek" + +#: pltcl.c:3238 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "seznam názvů sloupců a hodnot obsahuje neexistující název sloupce \"%s\"" + +#: pltcl.c:3245 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "nelze nastavit systémový atribut \"%s\"" + +#~ msgid "out of memory" +#~ msgstr "paměť vyÄerpána" + +#~ msgid "PL/Tcl functions cannot return composite types" +#~ msgstr "PL/Tcl funkce nemohou vracet složené datové typy" diff --git a/src/pl/tcl/po/es.po b/src/pl/tcl/po/es.po index f79b3a4c251..b505328ce58 100644 --- a/src/pl/tcl/po/es.po +++ b/src/pl/tcl/po/es.po @@ -1,6 +1,6 @@ # Spanish translation file for pltcl # -# Copyright (C) 2009-2012 PostgreSQL Global Development Group +# Copyright (c) 2009-2019, PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # # Emanuel Calvo Franco , 2009. @@ -8,63 +8,63 @@ # msgid "" msgstr "" -"Project-Id-Version: pltcl (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-05 15:07+0000\n" -"PO-Revision-Date: 2017-07-10 12:14-0400\n" +"Project-Id-Version: pltcl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-06 17:08+0000\n" +"PO-Revision-Date: 2019-06-06 17:26-0400\n" "Last-Translator: Carlos Chapi \n" -"Language-Team: PgSQL-es-Ayuda \n" +"Language-Team: PgSQL-es-Ayuda \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.0.2\n" -#: pltcl.c:459 +#: pltcl.c:464 msgid "PL/Tcl function to call once when pltcl is first used." msgstr "función PL/Tcl a ejecutar cuando se use pltcl por primera vez." -#: pltcl.c:466 +#: pltcl.c:471 msgid "PL/TclU function to call once when pltclu is first used." msgstr "función PL/TclU a ejecutar cuando se use pltclu por primera vez." -#: pltcl.c:629 +#: pltcl.c:636 #, c-format msgid "function \"%s\" is in the wrong language" msgstr "la función «%s» está en el lenguaje equivocado" -#: pltcl.c:640 +#: pltcl.c:647 #, c-format msgid "function \"%s\" must not be SECURITY DEFINER" msgstr "la función «%s» no debe ser SECURITY DEFINER" #. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" -#: pltcl.c:674 +#: pltcl.c:681 #, c-format msgid "processing %s parameter" msgstr "procesando el parámetro %s" -#: pltcl.c:830 +#: pltcl.c:842 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "se llamó una función que retorna un conjunto en un contexto que no puede aceptarlo" -#: pltcl.c:994 +#: pltcl.c:1015 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "se llamó una función que retorna un registro en un contexto que no puede aceptarlo" -#: pltcl.c:1263 +#: pltcl.c:1299 #, c-format msgid "could not split return value from trigger: %s" msgstr "no se pudo separar el valor de retorno del disparador: %s" -#: pltcl.c:1343 pltcl.c:1771 +#: pltcl.c:1379 pltcl.c:1809 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1344 +#: pltcl.c:1380 #, c-format msgid "" "%s\n" @@ -73,52 +73,42 @@ msgstr "" "%s\n" "en función PL/Tcl \"%s\"" -#: pltcl.c:1509 +#: pltcl.c:1544 #, c-format msgid "trigger functions can only be called as triggers" msgstr "las funciones disparadoras sólo pueden ser invocadas como disparadores" -#: pltcl.c:1513 +#: pltcl.c:1548 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "las funciones PL/Tcl no pueden retornar tipo %s" -#: pltcl.c:1549 +#: pltcl.c:1587 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "las funciones PL/Tcl no pueden aceptar el tipog%s" -#: pltcl.c:1663 +#: pltcl.c:1701 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "no se pudo crear procedimiento interno «%s»: %s" -#: pltcl.c:3100 +#: pltcl.c:3208 #, c-format msgid "column name/value list must have even number of elements" msgstr "la lista de nombres de columnas y valores debe tener un número par de elementos" -#: pltcl.c:3118 +#: pltcl.c:3226 #, c-format msgid "column name/value list contains nonexistent column name \"%s\"" msgstr "la lista de nombres de columnas y valores contiene el nombre de columna no existente «%s»" -#: pltcl.c:3125 +#: pltcl.c:3233 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "no se puede definir el atributo de sistema «%s»" -#~ msgid "module \"unknown\" not found in pltcl_modules" -#~ msgstr "módulo «unknown» no encontrado en pltcl_modules" - -#~ msgid "could not load module \"unknown\": %s" -#~ msgstr "no se pudo carga módulo «unknown»: %s" - -#~ msgid "unrecognized attribute \"%s\"" -#~ msgstr "atributo «%s» no reconocido" - -#~ msgid "out of memory" -#~ msgstr "memoria agotada" - -#~ msgid "PL/Tcl functions cannot return composite types" -#~ msgstr "las funciones PL/Tcl no pueden retornar tipos compuestos" +#: pltcl.c:3239 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "no se puede definir el atributo generado «%s»" diff --git a/src/pl/tcl/po/fr.po b/src/pl/tcl/po/fr.po index a7b63a232bb..cca8823e25a 100644 --- a/src/pl/tcl/po/fr.po +++ b/src/pl/tcl/po/fr.po @@ -6,71 +6,72 @@ # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.6\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-06 14:37+0000\n" -"PO-Revision-Date: 2017-07-06 18:12+0200\n" +"Project-Id-Version: PostgreSQL 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-05-17 01:07+0000\n" +"PO-Revision-Date: 2019-05-17 14:57+0200\n" "Last-Translator: Guillaume Lelarge \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.8.12\n" +"X-Generator: Poedit 2.2.1\n" -#: pltcl.c:459 +#: pltcl.c:464 msgid "PL/Tcl function to call once when pltcl is first used." msgstr "" "Fonction PL/Tcl à appeler une fois quand pltcl est utilisé pour la\n" "première fois" -#: pltcl.c:466 +#: pltcl.c:471 msgid "PL/TclU function to call once when pltclu is first used." msgstr "" "Fonction PL/TclU à appeler une fois quand pltcl est utilisé pour la\n" "première fois" -#: pltcl.c:629 +#: pltcl.c:636 #, c-format msgid "function \"%s\" is in the wrong language" msgstr "la fonction « %s » est dans le mauvais langage" -#: pltcl.c:640 +#: pltcl.c:647 #, c-format msgid "function \"%s\" must not be SECURITY DEFINER" msgstr "la fonction « %s » doit être définie en SECURITY DEFINER" #. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" -#: pltcl.c:674 +#: pltcl.c:681 #, c-format msgid "processing %s parameter" msgstr "traitement du paramètre %s" -#: pltcl.c:830 +#: pltcl.c:842 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "la fonction avec set-value a été appelé dans un contexte qui n'accepte pas\n" "un ensemble" -#: pltcl.c:994 +#: pltcl.c:1015 #, c-format -msgid "function returning record called in context that cannot accept type record" +msgid "" +"function returning record called in context that cannot accept type record" msgstr "" "fonction renvoyant le type record appelée dans un contexte qui ne peut pas\n" "accepter le type record" -#: pltcl.c:1263 +#: pltcl.c:1299 #, c-format msgid "could not split return value from trigger: %s" msgstr "n'a pas pu séparer la valeur de retour du trigger : %s" -#: pltcl.c:1343 pltcl.c:1771 +#: pltcl.c:1379 pltcl.c:1809 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1344 +#: pltcl.c:1380 #, c-format msgid "" "%s\n" @@ -79,55 +80,62 @@ msgstr "" "%s\n" "dans la fonction PL/Tcl « %s »" -#: pltcl.c:1509 +#: pltcl.c:1544 #, c-format msgid "trigger functions can only be called as triggers" msgstr "les fonctions trigger peuvent seulement être appelées par des triggers" -#: pltcl.c:1513 +#: pltcl.c:1548 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "les fonctions PL/Tcl ne peuvent pas renvoyer le type %s" -#: pltcl.c:1549 +#: pltcl.c:1587 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "les fonctions PL/Tcl ne peuvent pas accepter le type %s" -#: pltcl.c:1663 +#: pltcl.c:1701 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "n'a pas pu créer la procédure interne « %s » : %s" -#: pltcl.c:3100 +#: pltcl.c:3208 #, c-format msgid "column name/value list must have even number of elements" msgstr "la liste de nom de colonne/valeur doit avoir un nombre pair d'éléments" -#: pltcl.c:3118 +#: pltcl.c:3226 #, c-format msgid "column name/value list contains nonexistent column name \"%s\"" -msgstr "la liste de nom de colonne/valeur contient des noms de colonne inexistantes (« %s »)" +msgstr "" +"la liste de nom de colonne/valeur contient des noms de colonne inexistantes " +"(« %s »)" -#: pltcl.c:3125 +#: pltcl.c:3233 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "ne peut pas initialiser l'attribut système « %s »" -#~ msgid "PL/Tcl functions cannot return composite types" -#~ msgstr "les fonctions PL/Tcl ne peuvent pas renvoyer des types composites" +#: pltcl.c:3239 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "ne peut pas initialiser la colonne générée « %s »" -#~ msgid "out of memory" -#~ msgstr "mémoire épuisée" +#~ msgid "module \"unknown\" not found in pltcl_modules" +#~ msgstr "module « unkown » introuvable dans pltcl_modules" -#~ msgid "unrecognized attribute \"%s\"" -#~ msgstr "attribut « %s » non reconnu" +#~ msgid "could not load module \"unknown\": %s" +#~ msgstr "n'a pas pu charger le module « unknown » : %s" #~ msgid "trigger's return list must have even number of elements" #~ msgstr "la liste de retour du trigger doit avoir un nombre pair d'éléments" -#~ msgid "could not load module \"unknown\": %s" -#~ msgstr "n'a pas pu charger le module « unknown » : %s" +#~ msgid "unrecognized attribute \"%s\"" +#~ msgstr "attribut « %s » non reconnu" -#~ msgid "module \"unknown\" not found in pltcl_modules" -#~ msgstr "module « unkown » introuvable dans pltcl_modules" +#~ msgid "out of memory" +#~ msgstr "mémoire épuisée" + +#~ msgid "PL/Tcl functions cannot return composite types" +#~ msgstr "les fonctions PL/Tcl ne peuvent pas renvoyer des types composites" diff --git a/src/pl/tcl/po/it.po b/src/pl/tcl/po/it.po index 4b6a7f41b4c..0aa100f3a93 100644 --- a/src/pl/tcl/po/it.po +++ b/src/pl/tcl/po/it.po @@ -1,18 +1,17 @@ # -# Translation of pltcl to Italian -# PostgreSQL Project +# pltcl.po +# Italian message translation file for pltcl # -# Associazione Culturale ITPUG - Italian PostgreSQL Users Group -# http://www.itpug.org/ - info@itpug.org +# For development and bug report please use: +# https://github.com/dvarrazzo/postgresql-it # -# Traduttori: -# * Flavio Spada +# Copyright (C) 2012-2017 PostgreSQL Global Development Group +# Copyright (C) 2010, Associazione Culturale ITPUG # -# Revisori: -# * Gabriele Bartolini +# Daniele Varrazzo , 2012-2017. +# Flavio Spada # -# Copyright (c) 2010, Associazione Culturale ITPUG -# Distributed under the same license of the PostgreSQL project +# This file is distributed under the same license as the PostgreSQL package. # msgid "" msgstr "" @@ -21,7 +20,7 @@ msgstr "" "POT-Creation-Date: 2017-05-22 07:37+0000\n" "PO-Revision-Date: 2017-05-29 17:51+0100\n" "Last-Translator: Daniele Varrazzo \n" -"Language-Team: Gruppo traduzioni ITPUG \n" +"Language-Team: https://github.com/dvarrazzo/postgresql-it\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/src/pl/tcl/po/ja.po b/src/pl/tcl/po/ja.po index 94ea8d8211c..9b34d24d2f6 100644 --- a/src/pl/tcl/po/ja.po +++ b/src/pl/tcl/po/ja.po @@ -1,58 +1,71 @@ # LANGUAGE message translation file for pltcl -# Copyright (C) 2009 PostgreSQL Global Development Group +# Copyright (C) 2018 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# FIRST AUTHOR , 2009. +# KOIZUMI Satoru , 2015. # msgid "" msgstr "" -"Project-Id-Version: pltcl (PostgreSQL) 9.5\n" +"Project-Id-Version: pltcl (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2015-09-21 01:07+0000\n" -"PO-Revision-Date: 2015-10-04 18:15+0900\n" -"Last-Translator: KOIZUMI Satoru \n" +"POT-Creation-Date: 2018-01-26 10:21+0900\n" +"PO-Revision-Date: 2018-01-29 10:39+0900\n" +"Last-Translator: Michihide Hotta \n" "Language-Team: Japan PostgreSQL Users Group \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.6\n" -#: pltcl.c:555 +#: pltcl.c:459 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "pltcl ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦ã ã‘呼ã³å‡ºã•れる PL/Tcl 関数。" + +#: pltcl.c:466 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "pltclu ãŒæœ€åˆã«ä½¿ç”¨ã•れる際ã«ä¸€åº¦ã ã‘呼ã³å‡ºã•れる PL/TclU 関数。" + +#: pltcl.c:629 #, c-format -msgid "module \"unknown\" not found in pltcl_modules" -msgstr "pltcl_modulesã«ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«\"unknown\"ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“" +msgid "function \"%s\" is in the wrong language" +msgstr "関数 \"%s\" ã¯è¨€èªžãŒç•°ãªã‚Šã¾ã™" -#: pltcl.c:591 +#: pltcl.c:640 #, c-format -msgid "could not load module \"unknown\": %s" -msgstr "モジュール\"unknown\"をロードã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "関数 \"%s\" 㯠SECURITY DEFINER ã§ã‚ã£ã¦ã¯ãªã‚Šã¾ã›ã‚“" -#: pltcl.c:1047 +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:674 #, c-format -msgid "could not split return value from trigger: %s" -msgstr "トリガã‹ã‚‰ã®æˆ»ã‚Šå€¤ã‚’分割ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" +msgid "processing %s parameter" +msgstr "%s パラメーターを処ç†ã—ã¦ã„ã¾ã™" -#: pltcl.c:1058 +#: pltcl.c:830 #, c-format -msgid "trigger's return list must have even number of elements" -msgstr "トリガãŒè¿”ã™ãƒªã‚¹ãƒˆã®è¦ç´ ã¯å¶æ•°å€‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" +msgid "set-valued function called in context that cannot accept a set" +msgstr "ã“ã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ã¯ã€é›†åˆå€¤ã®é–¢æ•°ã¯é›†åˆã‚’å—ã‘付ã‘られã¾ã›ã‚“" -#: pltcl.c:1094 +#: pltcl.c:994 #, c-format -msgid "unrecognized attribute \"%s\"" -msgstr "未知ã®å±žæ€§ \"%s\"" +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"レコード型をå—ã‘付ã‘られãªã„コンテキストã§ãƒ¬ã‚³ãƒ¼ãƒ‰ã‚’è¿”ã™é–¢æ•°ãŒå‘¼ã³å‡ºã•れã¾" +"ã—ãŸ" -#: pltcl.c:1099 +#: pltcl.c:1263 #, c-format -msgid "cannot set system attribute \"%s\"" -msgstr "システム属性\"%s\"を設定ã§ãã¾ã›ã‚“" +msgid "could not split return value from trigger: %s" +msgstr "トリガーã‹ã‚‰ã®æˆ»ã‚Šå€¤ã‚’分割ã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" -#: pltcl.c:1222 pltcl.c:1648 +#: pltcl.c:1343 pltcl.c:1771 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1223 +#: pltcl.c:1344 #, c-format msgid "" "%s\n" @@ -61,32 +74,37 @@ msgstr "" "%s\n" "PL/Tcl 関数 \"%s\"" -#: pltcl.c:1331 pltcl.c:1338 -#, c-format -msgid "out of memory" -msgstr "メモリä¸è¶³ã§ã™" - -#: pltcl.c:1386 +#: pltcl.c:1509 #, c-format msgid "trigger functions can only be called as triggers" -msgstr "トリガ関数ã¯ãƒˆãƒªã‚¬ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" +msgstr "トリガー関数ã¯ãƒˆãƒªã‚¬ãƒ¼ã¨ã—ã¦ã®ã¿ã‚³ãƒ¼ãƒ«ã§ãã¾ã™" -#: pltcl.c:1395 +#: pltcl.c:1513 #, c-format msgid "PL/Tcl functions cannot return type %s" -msgstr "PL/Tcl é–¢æ•°ã¯æˆ»ã‚Šå€¤ã®åž‹ %s ã‚’è¿”ã›ã¾ã›ã‚“" +msgstr "PL/Tcl 関数㯠%s åž‹ã®æˆ»ã‚Šå€¤ã‚’è¿”ã›ã¾ã›ã‚“" -#: pltcl.c:1407 -#, c-format -msgid "PL/Tcl functions cannot return composite types" -msgstr "PL/Tcl é–¢æ•°ã¯æˆ»ã‚Šå€¤ã®åž‹ã¨ã—ã¦è¤‡åˆåž‹ã‚’è¿”ã›ã¾ã›ã‚“" - -#: pltcl.c:1446 +#: pltcl.c:1549 #, c-format msgid "PL/Tcl functions cannot accept type %s" -msgstr "PL/Tcl 関数ã¯åž‹ %s ã‚’å—ã‘付ã‘ã¾ã›ã‚“" +msgstr "PL/Tcl 関数㯠%s 型をå—ã‘付ã‘ã¾ã›ã‚“" -#: pltcl.c:1564 +#: pltcl.c:1663 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "内部プロシージャ \"%s\" を作æˆã§ãã¾ã›ã‚“ã§ã—ãŸ: %s" + +#: pltcl.c:3100 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "列å/値ã®ãƒªã‚¹ãƒˆã®è¦ç´ ã¯å¶æ•°å€‹ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“" + +#: pltcl.c:3118 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "列å/値ã®ãƒªã‚¹ãƒˆã®ä¸­ã«ã€å­˜åœ¨ã—ãªã„列å \"%s\" ãŒå«ã¾ã‚Œã¦ã„ã¾ã™" + +#: pltcl.c:3125 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "システム属性 \"%s\" を設定ã§ãã¾ã›ã‚“" diff --git a/src/pl/tcl/po/ko.po b/src/pl/tcl/po/ko.po index 650b4bccc08..5d2b09a7bd0 100644 --- a/src/pl/tcl/po/ko.po +++ b/src/pl/tcl/po/ko.po @@ -5,53 +5,65 @@ # msgid "" msgstr "" -"Project-Id-Version: pltcl (PostgreSQL) 9.5\n" +"Project-Id-Version: pltcl (PostgreSQL) 10\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2016-02-01 11:24+0900\n" -"PO-Revision-Date: 2016-02-01 11:47+0900\n" +"POT-Creation-Date: 2017-09-19 09:51+0900\n" +"PO-Revision-Date: 2017-09-19 10:29+0900\n" "Last-Translator: Ioseph Kim \n" "Language-Team: Korean Team \n" +"Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: ko\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: pltcl.c:459 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "pltcl 언어가 ì²˜ìŒ ì‚¬ìš©ë  ë•Œ 한번 호출 ë  PL/Tcl 함수" -#: pltcl.c:555 +#: pltcl.c:466 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "pltclu 언어가 ì²˜ìŒ ì‚¬ìš©ë  ë•Œ 한번 호출 ë  PL/Tcl 함수" + +#: pltcl.c:629 #, c-format -msgid "module \"unknown\" not found in pltcl_modules" -msgstr "pltcl_modules ì•ˆì— \"unknown\" ëª¨ë“ˆì„ ì°¾ì„ ìˆ˜ ì—†ìŒ" +msgid "function \"%s\" is in the wrong language" +msgstr "\"%s\" í•¨ìˆ˜ì— ìž˜ëª»ëœ ì–¸ì–´ê°€ 있ìŒ" -#: pltcl.c:591 +#: pltcl.c:640 #, c-format -msgid "could not load module \"unknown\": %s" -msgstr "\"unknown\" ëª¨ë“ˆì„ ë¶ˆëŸ¬ì˜¬ 수 ì—†ìŒ: %s" +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "\"%s\" 함수는 SECURITY DEFINER ì†ì„±ì´ 없어야 합니다" -#: pltcl.c:1047 +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:674 #, c-format -msgid "could not split return value from trigger: %s" -msgstr "트리거ì—서 ë°˜í™˜ê°’ì„ ë¶„ë¦¬í•  수 ì—†ìŒ: %s" +msgid "processing %s parameter" +msgstr "%s 매개 변수 처리 중" -#: pltcl.c:1058 +#: pltcl.c:830 #, c-format -msgid "trigger's return list must have even number of elements" -msgstr "트리거 반환 목ë¡ì€ ê·¸ ìš”ì†Œì˜ ê°œìˆ˜ê°€ ì§ìˆ˜ì—¬ì•¼ 함" +msgid "set-valued function called in context that cannot accept a set" +msgstr "ì§‘í•©ì´ ê°’ì´ í•¨ìˆ˜ê°€ ì§‘í•©ì„ ì‚¬ìš©í•  수 없는 구문ì—서 호출 ë˜ì—ˆìŒ" -#: pltcl.c:1094 +#: pltcl.c:994 #, c-format -msgid "unrecognized attribute \"%s\"" -msgstr "\"%s\" ì†ì„±ì„ 알 수 ì—†ìŒ" +msgid "" +"function returning record called in context that cannot accept type record" +msgstr "" +"레코드를 반환하는 함수가 레코드 í˜•ì„ ì‚¬ìš©í•  수 없는 구문ì—서 호출 ë˜ì—ˆìŒ" -#: pltcl.c:1099 +#: pltcl.c:1263 #, c-format -msgid "cannot set system attribute \"%s\"" -msgstr "\"%s\" 시스템 ì†ì„±ì„ 지정할 수 ì—†ìŒ" +msgid "could not split return value from trigger: %s" +msgstr "트리거ì—서 ë°˜í™˜ê°’ì„ ë¶„ë¦¬í•  수 ì—†ìŒ: %s" -#: pltcl.c:1222 pltcl.c:1648 +#: pltcl.c:1343 pltcl.c:1771 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1223 +#: pltcl.c:1344 #, c-format msgid "" "%s\n" @@ -60,32 +72,37 @@ msgstr "" "%s\n" "해당 PL/Tcl 함수: \"%s\"" -#: pltcl.c:1331 pltcl.c:1338 -#, c-format -msgid "out of memory" -msgstr "메모리 부족" - -#: pltcl.c:1386 +#: pltcl.c:1509 #, c-format msgid "trigger functions can only be called as triggers" msgstr "트리거 함수는 트리거로만 í˜¸ì¶œë  ìˆ˜ 있ìŒ" -#: pltcl.c:1395 +#: pltcl.c:1513 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "PL/Tcl 함수는 %s ìžë£Œí˜•ì„ ë°˜í™˜í•  수 ì—†ìŒ" -#: pltcl.c:1407 -#, c-format -msgid "PL/Tcl functions cannot return composite types" -msgstr "PL/Tcl 함수는 복합 ìžë£Œí˜•ì„ ë°˜í™˜í•  수 ì—†ìŒ" - -#: pltcl.c:1446 +#: pltcl.c:1549 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "PL/Tcl 함수는 %s ìžë£Œí˜•ì„ ì‚¬ìš©í•  수 ì—†ìŒ" -#: pltcl.c:1564 +#: pltcl.c:1663 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "\"%s\" ë‚´ë¶€ 프로시져를 만들 수 ì—†ìŒ: %s" + +#: pltcl.c:3100 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "칼럼 ì´ë¦„/ê°’ 목ë¡ì€ ê·¸ ìš”ì†Œì˜ ê°œìˆ˜ê°€ ì§ìˆ˜ì—¬ì•¼ 함" + +#: pltcl.c:3118 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "칼럼 ì´ë¦„/ê°’ 목ë¡ì— \"%s\" ì¹¼ëŸ¼ì— ëŒ€í•œ ê°’ì´ ì—†ìŒ" + +#: pltcl.c:3125 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" 시스템 ì†ì„±ì„ 지정할 수 ì—†ìŒ" diff --git a/src/pl/tcl/po/ru.po b/src/pl/tcl/po/ru.po index d048170a98e..27d1bb86ae5 100644 --- a/src/pl/tcl/po/ru.po +++ b/src/pl/tcl/po/ru.po @@ -2,13 +2,13 @@ # Copyright (C) 2012-2016 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. # Alexander Lakhin , 2012-2017. -# msgid "" msgstr "" "Project-Id-Version: pltcl (PostgreSQL current)\n" "Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-03-27 12:37+0000\n" +"POT-Creation-Date: 2018-10-05 21:51+0300\n" "PO-Revision-Date: 2017-03-29 14:01+0300\n" +"Last-Translator: Alexander Lakhin \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,56 +16,55 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"Last-Translator: Alexander Lakhin \n" -#: pltcl.c:459 +#: pltcl.c:466 msgid "PL/Tcl function to call once when pltcl is first used." msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° PL/Tcl, Ð²Ñ‹Ð·Ñ‹Ð²Ð°ÐµÐ¼Ð°Ñ Ð¿Ñ€Ð¸ первом иÑпользовании pltcl." -#: pltcl.c:466 +#: pltcl.c:473 msgid "PL/TclU function to call once when pltclu is first used." msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð½Ð° PL/TclU, Ð²Ñ‹Ð·Ñ‹Ð²Ð°ÐµÐ¼Ð°Ñ Ð¿Ñ€Ð¸ первом иÑпользовании pltclu." -#: pltcl.c:629 +#: pltcl.c:640 #, c-format msgid "function \"%s\" is in the wrong language" msgstr "Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" объÑвлена на другом Ñзыке" -#: pltcl.c:640 +#: pltcl.c:651 #, c-format msgid "function \"%s\" must not be SECURITY DEFINER" msgstr "Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ \"%s\" не должна иметь характериÑтику SECURITY DEFINER" #. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" -#: pltcl.c:674 +#: pltcl.c:685 #, c-format msgid "processing %s parameter" msgstr "обработка параметра %s" -#: pltcl.c:830 +#: pltcl.c:846 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑтво, вызвана в контекÑте, где ему нет меÑта" -#: pltcl.c:994 +#: pltcl.c:1019 #, c-format msgid "" "function returning record called in context that cannot accept type record" msgstr "" "функциÑ, Ð²Ð¾Ð·Ð²Ñ€Ð°Ñ‰Ð°ÑŽÑ‰Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ, вызвана в контекÑте, не допуÑкающем Ñтот тип" -#: pltcl.c:1258 +#: pltcl.c:1296 #, c-format msgid "could not split return value from trigger: %s" msgstr "разложить возвращаемое из триггера значение не удалоÑÑŒ: %s" -#: pltcl.c:1338 pltcl.c:1766 +#: pltcl.c:1376 pltcl.c:1806 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1339 +#: pltcl.c:1377 #, c-format msgid "" "%s\n" @@ -74,38 +73,38 @@ msgstr "" "%s\n" "в функции PL/Tcl \"%s\"" -#: pltcl.c:1504 +#: pltcl.c:1541 #, c-format msgid "trigger functions can only be called as triggers" msgstr "триггерные функции могут вызыватьÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ в триггерах" -#: pltcl.c:1508 +#: pltcl.c:1545 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "функции PL/Tcl не могут возвращать тип %s" -#: pltcl.c:1544 +#: pltcl.c:1584 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "функции PL/Tcl не могут принимать тип %s" -#: pltcl.c:1658 +#: pltcl.c:1698 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "не удалоÑÑŒ Ñоздать внутреннюю процедуру \"%s\": %s" -#: pltcl.c:3095 +#: pltcl.c:3220 #, c-format msgid "column name/value list must have even number of elements" msgstr "в ÑпиÑке имён/значений Ñтолбцов должно быть чётное чиÑло Ñлементов" -#: pltcl.c:3113 +#: pltcl.c:3238 #, c-format msgid "column name/value list contains nonexistent column name \"%s\"" msgstr "" "ÑпиÑок имён/значений Ñтолбцов Ñодержит Ð¸Ð¼Ñ Ð½ÐµÑущеÑтвующего Ñтолбца \"%s\"" -#: pltcl.c:3120 +#: pltcl.c:3245 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "уÑтановить ÑиÑтемный атрибут \"%s\" нельзÑ" diff --git a/src/pl/tcl/po/sv.po b/src/pl/tcl/po/sv.po index cb6d8ae07da..8cf57dc04e2 100644 --- a/src/pl/tcl/po/sv.po +++ b/src/pl/tcl/po/sv.po @@ -1,14 +1,14 @@ # Swedish message translation file for pltcl # Copyright (C) 2017 PostgreSQL Global Development Group # This file is distributed under the same license as the PostgreSQL package. -# Dennis Björklund , 2017. +# Dennis Björklund , 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: pltcl (PostgreSQL) 10\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2017-07-20 21:07+0000\n" -"PO-Revision-Date: 2017-07-21 06:04+0200\n" +"Project-Id-Version: pltcl (PostgreSQL) 12\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-29 12:37+0000\n" +"PO-Revision-Date: 2019-04-29 14:55+0200\n" "Last-Translator: Dennis Björklund \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -16,51 +16,51 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: pltcl.c:459 +#: pltcl.c:464 msgid "PL/Tcl function to call once when pltcl is first used." msgstr "PL/Tcl-funktion att anropa en gÃ¥ng när pltcl först används." -#: pltcl.c:466 +#: pltcl.c:471 msgid "PL/TclU function to call once when pltclu is first used." msgstr "PL/TclU-funktion att anrop en gÃ¥ng när pltclu först används." -#: pltcl.c:629 +#: pltcl.c:636 #, c-format msgid "function \"%s\" is in the wrong language" msgstr "funktionen \"%s\" är skriven i fel sprÃ¥k" -#: pltcl.c:640 +#: pltcl.c:647 #, c-format msgid "function \"%s\" must not be SECURITY DEFINER" msgstr "funktionen \"%s\" fÃ¥r ej vara SECURITY DEFINER" #. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" -#: pltcl.c:674 +#: pltcl.c:681 #, c-format msgid "processing %s parameter" msgstr "processar parameter %s" -#: pltcl.c:830 +#: pltcl.c:842 #, c-format msgid "set-valued function called in context that cannot accept a set" msgstr "en funktion som returnerar en mängd anropades i kontext som inte godtar en mängd" -#: pltcl.c:994 +#: pltcl.c:1015 #, c-format msgid "function returning record called in context that cannot accept type record" msgstr "en funktion med post som värde anropades i sammanhang där poster inte kan godtagas." -#: pltcl.c:1263 +#: pltcl.c:1299 #, c-format msgid "could not split return value from trigger: %s" msgstr "kunde inte dela pÃ¥ returvärde och utlösare: %s" -#: pltcl.c:1343 pltcl.c:1771 +#: pltcl.c:1379 pltcl.c:1809 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1344 +#: pltcl.c:1380 #, c-format msgid "" "%s\n" @@ -69,37 +69,42 @@ msgstr "" "%s\n" "i PL/Tcl-funktion \"%s\"" -#: pltcl.c:1509 +#: pltcl.c:1544 #, c-format msgid "trigger functions can only be called as triggers" msgstr "Triggningsfunktioner kan bara anropas vid triggning." -#: pltcl.c:1513 +#: pltcl.c:1548 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "PL/Tcl-funktioner kan inte returnera typ %s" -#: pltcl.c:1549 +#: pltcl.c:1587 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "PL/Tcl-funktioner kan inte ta emot typ %s" -#: pltcl.c:1663 +#: pltcl.c:1701 #, c-format msgid "could not create internal procedure \"%s\": %s" msgstr "kunde inte skapa en intern procedur \"%s\": %s" -#: pltcl.c:3100 +#: pltcl.c:3208 #, c-format msgid "column name/value list must have even number of elements" msgstr "kolumn-namn/-värde mÃ¥ste ha ett jämt antal element" -#: pltcl.c:3118 +#: pltcl.c:3226 #, c-format msgid "column name/value list contains nonexistent column name \"%s\"" msgstr "listan med kolumn-namn/-värde innehÃ¥ller det icke existerande kolumnnamnet \"%s\"" -#: pltcl.c:3125 +#: pltcl.c:3233 #, c-format msgid "cannot set system attribute \"%s\"" msgstr "kan inte sätta systemattribut \"%s\"" + +#: pltcl.c:3239 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "kan inte sätta genererad kolumn \"%s\"" diff --git a/src/pl/tcl/po/tr.po b/src/pl/tcl/po/tr.po index 373a2894208..ee51dfd0f17 100644 --- a/src/pl/tcl/po/tr.po +++ b/src/pl/tcl/po/tr.po @@ -6,22 +6,62 @@ msgid "" msgstr "" "Project-Id-Version: PostgreSQL 8.4\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2009-04-29 07:08+0000\n" -"PO-Revision-Date: 2013-09-04 20:50-0400\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-04-26 13:38+0000\n" +"PO-Revision-Date: 2019-06-13 17:11+0300\n" "Last-Translator: Devrim GÜNDÜZ \n" -"Language-Team: TR >\n" +"Language-Team: TR \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" -#: pltcl.c:1027 +#: pltcl.c:464 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "pltcl ilk sefer kullanıldığında bir kez çaÄŸrılacak PL/Tcl fonksiyonu" + +#: pltcl.c:471 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "pltclu ilk sefer kullanıldığında bir kez çaÄŸrılacak PL/Tclu fonksiyonu" + +#: pltcl.c:636 +#, c-format +msgid "function \"%s\" is in the wrong language" +msgstr "\"%s\" fonksiyonu yanlış dilde" + +#: pltcl.c:647 +#, c-format +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "\"%s\" fonksiyonu SECURITY DEFINER olmamalı" + +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:681 +#, c-format +msgid "processing %s parameter" +msgstr "%s parametresi iÅŸleniyor" + +#: pltcl.c:842 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "set deÄŸerini kabul etmediÄŸi ortamda set deÄŸeri alan fonksiyon çağırılmış" + +#: pltcl.c:1015 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "tip kaydı içermeyen alanda çağırılan ve kayıt döndüren fonksiyon" + +#: pltcl.c:1299 +#, c-format +msgid "could not split return value from trigger: %s" +msgstr "sdönüş deÄŸeri tetikleyiciden (trigger) ayrılamadı: %s" + +#: pltcl.c:1379 pltcl.c:1809 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1028 +#: pltcl.c:1380 #, c-format msgid "" "%s\n" @@ -30,25 +70,48 @@ msgstr "" "%s\n" "Åžu PL/Tcl fonksiyonunda: \"%s\"" -#: pltcl.c:1127 -msgid "out of memory" -msgstr "yetersiz bellek" - -#: pltcl.c:1192 +#: pltcl.c:1544 +#, c-format msgid "trigger functions can only be called as triggers" msgstr "trigger fonksiyonları sadece trigger olarak çağırılabilirler" -#: pltcl.c:1201 +#: pltcl.c:1548 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "PL/Tcl fonksiyonları %s tipini döndüremezler" -#: pltcl.c:1213 -msgid "PL/Tcl functions cannot return composite types" -msgstr "PL/Tcl fonksiyonları composit tip döndüremezler" - -#: pltcl.c:1253 +#: pltcl.c:1587 #, c-format msgid "PL/Tcl functions cannot accept type %s" msgstr "PL/Tcl fonksiyonları %s veri tipini kabul etmezler" +#: pltcl.c:1701 +#, c-format +msgid "could not create internal procedure \"%s\": %s" +msgstr "\"%s\" dahili yordamı oluÅŸturulamadı: %s" + +#: pltcl.c:3208 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "sütun adı/deÄŸer listesinin çift sayıda öğesi olmalı" + +#: pltcl.c:3226 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "sütun adı/deÄŸer listesi mevcut olmayan \"%s\" sütun adını içeriyor" + +#: pltcl.c:3233 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "\"%s\" sistem niteliÄŸi ayarlanamaz" + +#: pltcl.c:3239 +#, c-format +msgid "cannot set generated column \"%s\"" +msgstr "oluÅŸturulan \"%s\" sütunu ayarlanamıyor" + +#~ msgid "out of memory" +#~ msgstr "yetersiz bellek" + +#~ msgid "PL/Tcl functions cannot return composite types" +#~ msgstr "PL/Tcl fonksiyonları composit tip döndüremezler" diff --git a/src/pl/tcl/po/vi.po b/src/pl/tcl/po/vi.po new file mode 100644 index 00000000000..7224bf14863 --- /dev/null +++ b/src/pl/tcl/po/vi.po @@ -0,0 +1,107 @@ +# LANGUAGE message translation file for pltcl +# Copyright (C) 2018 PostgreSQL Global Development Group +# This file is distributed under the same license as the pltcl (PostgreSQL) package. +# FIRST AUTHOR , 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: pltcl (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" +"POT-Creation-Date: 2018-04-22 12:08+0000\n" +"PO-Revision-Date: 2018-04-29 22:56+0900\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: Dang Minh Huong \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"Language: vi_VN\n" + +#: pltcl.c:466 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "Chỉ định hàm PL/Tcl được gá»i má»™t lần khi pltcl sá»­ dụng lần đầu tiên." + +#: pltcl.c:473 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "Chỉ định hàm PL/TclU được gá»i má»™t lần khi pltclu sá»­ dụng lần đầu tiên." + +#: pltcl.c:640 +#, c-format +msgid "function \"%s\" is in the wrong language" +msgstr "hàm \"%s\" không đúng ngôn ngữ" + +#: pltcl.c:651 +#, c-format +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "hàm \"%s\" không được là SECURITY DEFINER" + +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:685 +#, c-format +msgid "processing %s parameter" +msgstr "xá»­ lý tham số %s" + +#: pltcl.c:846 +#, c-format +msgid "set-valued function called in context that cannot accept a set" +msgstr "hàm thiết lập giá trị được gá»i trong ngữ cảnh không thể chấp nhận má»™t tập hợp" + +#: pltcl.c:1019 +#, c-format +msgid "function returning record called in context that cannot accept type record" +msgstr "hàm trả vá» bản ghi được gá»i trong ngữ cảnh không thể chấp nhận kiểu bản ghi" + +#: pltcl.c:1296 +#, c-format +msgid "could not split return value from trigger: %s" +msgstr "không thể tách giá trị trả vá» khá»i trigger: %s" + +#: pltcl.c:1376 pltcl.c:1806 +#, c-format +msgid "%s" +msgstr "%s" + +#: pltcl.c:1377 +#, c-format +msgid "" +"%s\n" +"in PL/Tcl function \"%s\"" +msgstr "" +"%s\n" +"trong hàm PL/Tcl \"%s\"" + +#: pltcl.c:1541 +#, c-format +msgid "trigger functions can only be called as triggers" +msgstr "hàm trigger chỉ có thể được goi như những triggers." + +#: pltcl.c:1545 +#, c-format +msgid "PL/Tcl functions cannot return type %s" +msgstr "Hàm PL/Tcl không thể trả vá» kiểu %s" + +#: pltcl.c:1584 +#, c-format +msgid "PL/Tcl functions cannot accept type %s" +msgstr "Hàm PL/Tcl không thể chấp nhận kiểu %s" + +#: pltcl.c:1698 +#, c-format +msgid "could not create internal procedure \"%s\": %s" +msgstr "không thể tạo procedure ná»™i bá»™ \"%s\": %s" + +#: pltcl.c:3219 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "danh sách cá»™t tên/giá trị phải có giá trị chẵn cho số phần tá»­" + +#: pltcl.c:3237 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "danh sách cá»™t tên/giá trị chứa tên cá»™t không tồn tại \"%s\"" + +#: pltcl.c:3244 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "không thể thiết lập attribute hệ thống \"%s\"" diff --git a/src/pl/tcl/po/zh_CN.po b/src/pl/tcl/po/zh_CN.po index 21ae0d1d0c6..4a9bc380037 100644 --- a/src/pl/tcl/po/zh_CN.po +++ b/src/pl/tcl/po/zh_CN.po @@ -1,64 +1,67 @@ # LANGUAGE message translation file for pltcl -# Copyright (C) 2010 PostgreSQL Global Development Group -# This file is distributed under the same license as the PostgreSQL package. -# FIRST AUTHOR , 2010. +# Copyright (C) 2019 PostgreSQL Global Development Group +# This file is distributed under the same license as the pltcl (PostgreSQL) package. +# FIRST AUTHOR , 2019. # msgid "" msgstr "" -"Project-Id-Version: PostgreSQL 9.0\n" -"Report-Msgid-Bugs-To: pgsql-bugs@postgresql.org\n" -"POT-Creation-Date: 2015-11-26 18:37+0000\n" -"PO-Revision-Date: 2015-12-02 14:52+0800\n" -"Last-Translator: Yuwei Peng \n" -"Language-Team: Weibin \n" +"Project-Id-Version: pltcl (PostgreSQL) 11\n" +"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n" +"POT-Creation-Date: 2019-06-04 12:07+0000\n" +"PO-Revision-Date: 2019-05-17 18:00+0800\n" +"Last-Translator: Jie Zhang \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.7\n" -#: pltcl.c:555 +#: pltcl.c:464 +msgid "PL/Tcl function to call once when pltcl is first used." +msgstr "PL/Tcl函数在首次使用pltcl时调用一次." + +#: pltcl.c:471 +msgid "PL/TclU function to call once when pltclu is first used." +msgstr "PL/TclU函数在首次使用pltcl时调用一次." + +#: pltcl.c:636 #, c-format -msgid "module \"unknown\" not found in pltcl_modules" -msgstr "在pltcl_modules中没有找到模å—\"unknown\"" +msgid "function \"%s\" is in the wrong language" +msgstr "函数\"%s\"的语言错误" -#: pltcl.c:591 +#: pltcl.c:647 #, c-format -#| msgid "could not load library \"%s\": %s" -msgid "could not load module \"unknown\": %s" -msgstr "无法载入模å—\"unknown\":%s" +msgid "function \"%s\" must not be SECURITY DEFINER" +msgstr "函数\"%s\"ä¸èƒ½æ˜¯å®‰å…¨å®šä¹‰è€…" -# fe-exec.c:2325 -#: pltcl.c:1047 +#. translator: %s is "pltcl.start_proc" or "pltclu.start_proc" +#: pltcl.c:681 #, c-format -#| msgid "could not interpret result from server: %s" -msgid "could not split return value from trigger: %s" -msgstr "无法分离æ¥è‡ªè§¦å‘器的返回值:%s" +msgid "processing %s parameter" +msgstr "正在处ç†%s傿•°" -#: pltcl.c:1058 +#: pltcl.c:842 #, c-format -#| msgid "argument list must have even number of elements" -msgid "trigger's return list must have even number of elements" -msgstr "触å‘å™¨çš„è¿”å›žåˆ—è¡¨å¿…é¡»å…·æœ‰å¶æ•°ä¸ªå…ƒç´ " +msgid "set-valued function called in context that cannot accept a set" +msgstr "在ä¸èƒ½æŽ¥å—使用集åˆçš„环境中调用set-valued函数" -#: pltcl.c:1094 +#: pltcl.c:1015 #, c-format -#| msgid "unrecognized parameter \"%s\"" -msgid "unrecognized attribute \"%s\"" -msgstr "未识别的属性\"%s\"" +msgid "function returning record called in context that cannot accept type record" +msgstr "è¿”å›žå€¼ç±»åž‹æ˜¯è®°å½•çš„å‡½æ•°åœ¨ä¸æŽ¥å—使用记录类型的环境中调用" -#: pltcl.c:1099 +#: pltcl.c:1299 #, c-format -#| msgid "cannot move system relation \"%s\"" -msgid "cannot set system attribute \"%s\"" -msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" +msgid "could not split return value from trigger: %s" +msgstr "无法分离æ¥è‡ªè§¦å‘器的返回值:%s" -#: pltcl.c:1222 pltcl.c:1648 +#: pltcl.c:1379 pltcl.c:1809 #, c-format msgid "%s" msgstr "%s" -#: pltcl.c:1223 +#: pltcl.c:1380 #, c-format msgid "" "%s\n" @@ -67,33 +70,43 @@ msgstr "" "%s\n" "在PL/Tcl函数\"%s\"中" -#: pltcl.c:1331 pltcl.c:1338 -#, c-format -msgid "out of memory" -msgstr "内存用尽" - -#: pltcl.c:1386 +#: pltcl.c:1544 #, c-format msgid "trigger functions can only be called as triggers" msgstr "触å‘器函数åªèƒ½ä»¥è§¦å‘器的形å¼è°ƒç”¨" -#: pltcl.c:1395 +#: pltcl.c:1548 #, c-format msgid "PL/Tcl functions cannot return type %s" msgstr "PL/Tcl函数ä¸èƒ½è¿”回类型%s" -#: pltcl.c:1407 -#, c-format -msgid "PL/Tcl functions cannot return composite types" -msgstr "PL/Tcl 函数ä¸èƒ½è¿”回组åˆç±»åž‹" - -#: pltcl.c:1446 +#: pltcl.c:1587 #, c-format msgid "PL/Tcl functions cannot accept type %s" -msgstr "PL/Tcl行数ä¸èƒ½ä½¿ç”¨ç±»åž‹ %s" +msgstr "PL/Tcl函数ä¸èƒ½ä½¿ç”¨ç±»åž‹ %s" -#: pltcl.c:1564 +#: pltcl.c:1701 #, c-format -#| msgid "could not create locale \"%s\": %m" msgid "could not create internal procedure \"%s\": %s" msgstr "无法创建内部过程\"%s\":%s" + +#: pltcl.c:3208 +#, c-format +msgid "column name/value list must have even number of elements" +msgstr "列å/å€¼åˆ—è¡¨å¿…é¡»å…·æœ‰å¶æ•°ä¸ªå…ƒç´ " + +#: pltcl.c:3226 +#, c-format +msgid "column name/value list contains nonexistent column name \"%s\"" +msgstr "列å/值列表包å«ä¸å­˜åœ¨çš„列å\"%s\"" + +#: pltcl.c:3233 +#, c-format +msgid "cannot set system attribute \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" + +#: pltcl.c:3239 +#, fuzzy, c-format +#| msgid "cannot set system attribute \"%s\"" +msgid "cannot set generated column \"%s\"" +msgstr "ä¸èƒ½è®¾ç½®ç³»ç»Ÿå±žæ€§\"%s\"" diff --git a/src/pl/tcl/sql/pltcl_queries.sql b/src/pl/tcl/sql/pltcl_queries.sql index 71c1238bd20..bbd2d979992 100644 --- a/src/pl/tcl/sql/pltcl_queries.sql +++ b/src/pl/tcl/sql/pltcl_queries.sql @@ -1,127 +1,34 @@ -- suppress CONTEXT so that function OIDs aren't in output \set VERBOSITY terse -insert into T_pkey1 values (1, 'key1-1', 'test key'); -insert into T_pkey1 values (1, 'key1-2', 'test key'); -insert into T_pkey1 values (1, 'key1-3', 'test key'); -insert into T_pkey1 values (2, 'key2-1', 'test key'); -insert into T_pkey1 values (2, 'key2-2', 'test key'); -insert into T_pkey1 values (2, 'key2-3', 'test key'); - -insert into T_pkey2 values (1, 'key1-1', 'test key'); -insert into T_pkey2 values (1, 'key1-2', 'test key'); -insert into T_pkey2 values (1, 'key1-3', 'test key'); -insert into T_pkey2 values (2, 'key2-1', 'test key'); -insert into T_pkey2 values (2, 'key2-2', 'test key'); -insert into T_pkey2 values (2, 'key2-3', 'test key'); - -select * from T_pkey1; - --- key2 in T_pkey2 should have upper case only -select * from T_pkey2; - -insert into T_pkey1 values (1, 'KEY1-3', 'should work'); - --- Due to the upper case translation in trigger this must fail -insert into T_pkey2 values (1, 'KEY1-3', 'should fail'); - -insert into T_dta1 values ('trec 1', 1, 'key1-1'); -insert into T_dta1 values ('trec 2', 1, 'key1-2'); -insert into T_dta1 values ('trec 3', 1, 'key1-3'); - --- Must fail due to unknown key in T_pkey1 -insert into T_dta1 values ('trec 4', 1, 'key1-4'); - -insert into T_dta2 values ('trec 1', 1, 'KEY1-1'); -insert into T_dta2 values ('trec 2', 1, 'KEY1-2'); -insert into T_dta2 values ('trec 3', 1, 'KEY1-3'); - --- Must fail due to unknown key in T_pkey2 -insert into T_dta2 values ('trec 4', 1, 'KEY1-4'); - -select * from T_dta1; - -select * from T_dta2; - -update T_pkey1 set key2 = 'key2-9' where key1 = 2 and key2 = 'key2-1'; -update T_pkey1 set key2 = 'key1-9' where key1 = 1 and key2 = 'key1-1'; -delete from T_pkey1 where key1 = 2 and key2 = 'key2-2'; -delete from T_pkey1 where key1 = 1 and key2 = 'key1-2'; - -update T_pkey2 set key2 = 'KEY2-9' where key1 = 2 and key2 = 'KEY2-1'; -update T_pkey2 set key2 = 'KEY1-9' where key1 = 1 and key2 = 'KEY1-1'; -delete from T_pkey2 where key1 = 2 and key2 = 'KEY2-2'; -delete from T_pkey2 where key1 = 1 and key2 = 'KEY1-2'; - -select * from T_pkey1; -select * from T_pkey2; -select * from T_dta1; -select * from T_dta2; - -select tcl_avg(key1) from T_pkey1; -select tcl_sum(key1) from T_pkey1; -select tcl_avg(key1) from T_pkey2; -select tcl_sum(key1) from T_pkey2; - --- The following should return NULL instead of 0 -select tcl_avg(key1) from T_pkey1 where key1 = 99; -select tcl_sum(key1) from T_pkey1 where key1 = 99; - -select 1 @< 2; -select 100 @< 4; - -select * from T_pkey1 order by key1 using @<, key2 collate "C"; -select * from T_pkey2 order by key1 using @<, key2 collate "C"; - --- show dump of trigger data -insert into trigger_test values(1,'insert'); - -insert into trigger_test_view values(2,'insert'); -update trigger_test_view set v = 'update' where i=1; -delete from trigger_test_view; - -update trigger_test set v = 'update', test_skip=true where i = 1; -update trigger_test set v = 'update' where i = 1; -delete from trigger_test; -truncate trigger_test; - -- Test composite-type arguments select tcl_composite_arg_ref1(row('tkey', 42, 'ref2')); select tcl_composite_arg_ref2(row('tkey', 42, 'ref2')); -- More tests for composite argument/result types -create domain d_dta1 as T_dta1 check ((value).ref1 > 0); +create domain d_comp1 as T_comp1 check ((value).ref1 > 0); create function tcl_record_arg(record, fldname text) returns int as ' return $1($2) ' language pltcl; -select tcl_record_arg(row('tkey', 42, 'ref2')::T_dta1, 'ref1'); -select tcl_record_arg(row('tkey', 42, 'ref2')::d_dta1, 'ref1'); +select tcl_record_arg(row('tkey', 42, 'ref2')::T_comp1, 'ref1'); +select tcl_record_arg(row('tkey', 42, 'ref2')::d_comp1, 'ref1'); select tcl_record_arg(row(2,4), 'f2'); -create function tcl_cdomain_arg(d_dta1) returns int as ' +create function tcl_cdomain_arg(d_comp1) returns int as ' return $1(ref1) ' language pltcl; select tcl_cdomain_arg(row('tkey', 42, 'ref2')); -select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_dta1); +select tcl_cdomain_arg(row('tkey', 42, 'ref2')::T_comp1); select tcl_cdomain_arg(row('tkey', -1, 'ref2')); -- fail -- Test argisnull primitive select tcl_argisnull('foo'); select tcl_argisnull(''); select tcl_argisnull(null); --- should error -insert into trigger_test(test_argisnull) values(true); -select trigger_data(); - --- Test spi_lastoid primitive -create temp table t1 (f1 int); -select tcl_lastoid('t1'); -create temp table t2 (f1 int) with oids; -select tcl_lastoid('t2') > 0; -- test some error cases create function tcl_error(out a int, out b int) as $$return {$$ language pltcl; @@ -157,13 +64,13 @@ $$ language pltcl; select bad_field_srf(); -- test composite and domain-over-composite results -create function tcl_composite_result(int) returns T_dta1 as $$ +create function tcl_composite_result(int) returns T_comp1 as $$ return [list tkey tkey1 ref1 $1 ref2 ref22] $$ language pltcl; select tcl_composite_result(1001); select * from tcl_composite_result(1002); -create function tcl_dcomposite_result(int) returns d_dta1 as $$ +create function tcl_dcomposite_result(int) returns d_comp1 as $$ return [list tkey tkey2 ref1 $1 ref2 ref42] $$ language pltcl; select tcl_dcomposite_result(1001); @@ -191,8 +98,6 @@ select tcl_eval('argisnull abc'); -- Test return_null select tcl_eval('return_null 14'); --- should error -insert into trigger_test(test_return_null) values(true); -- Test spi_exec select tcl_eval('spi_exec'); @@ -259,23 +164,3 @@ select tcl_eval($$ after 100 {set ::tcl_vwait 1} vwait ::tcl_vwait unset -nocomplain ::tcl_vwait$$); - --- test transition table visibility -create table transition_table_test (id int, name text); -insert into transition_table_test values (1, 'a'); -create function transition_table_test_f() returns trigger language pltcl as -$$ - spi_exec -array C "SELECT id, name FROM old_table" { - elog INFO "old: $C(id) -> $C(name)" - } - spi_exec -array C "SELECT id, name FROM new_table" { - elog INFO "new: $C(id) -> $C(name)" - } - return OK -$$; -CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test - REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); -update transition_table_test set name = 'b'; -drop table transition_table_test; -drop function transition_table_test_f(); diff --git a/src/pl/tcl/sql/pltcl_setup.sql b/src/pl/tcl/sql/pltcl_setup.sql index 56a90dc8449..e9f59989b5b 100644 --- a/src/pl/tcl/sql/pltcl_setup.sql +++ b/src/pl/tcl/sql/pltcl_setup.sql @@ -1,463 +1,14 @@ --- --- Create the tables used in the test queries --- --- T_pkey1 is the primary key table for T_dta1. Entries from T_pkey1 --- Cannot be changed or deleted if they are referenced from T_dta1. --- --- T_pkey2 is the primary key table for T_dta2. If the key values in --- T_pkey2 are changed, the references in T_dta2 follow. If entries --- are deleted, the referencing entries from T_dta2 are deleted too. --- The values for field key2 in T_pkey2 are silently converted to --- upper case on insert/update. --- -create table T_pkey1 ( - key1 int4, - key2 char(20), - txt char(40) -); - -create table T_pkey2 ( - key1 int4, - key2 char(20), - txt char(40) -); - -create table T_dta1 ( - tkey char(10), - ref1 int4, - ref2 char(20) -); - -create table T_dta2 ( +create table T_comp1 ( tkey char(10), ref1 int4, ref2 char(20) ); - --- --- Function to check key existence in T_pkey1 --- -create function check_pkey1_exists(int4, bpchar) returns bool as E' - if {![info exists GD]} { - set GD(plan) [spi_prepare \\ - "select 1 from T_pkey1 \\ - where key1 = \\$1 and key2 = \\$2" \\ - {int4 bpchar}] - } - - set n [spi_execp -count 1 $GD(plan) [list $1 $2]] - - if {$n > 0} { - return "t" - } - return "f" -' language pltcl; - - --- dump trigger data - -CREATE TABLE trigger_test ( - i int, - v text, - dropme text, - test_skip boolean DEFAULT false, - test_return_null boolean DEFAULT false, - test_argisnull boolean DEFAULT false -); --- Make certain dropped attributes are handled correctly -ALTER TABLE trigger_test DROP dropme; - -CREATE VIEW trigger_test_view AS SELECT i, v FROM trigger_test; - -CREATE FUNCTION trigger_data() returns trigger language pltcl as $_$ - if {$TG_table_name eq "trigger_test" && $TG_level eq "ROW" && $TG_op ne "DELETE"} { - # Special case tests - if {$NEW(test_return_null) eq "t" } { - return_null - } - if {$NEW(test_argisnull) eq "t" } { - set should_error [argisnull 1] - } - if {$NEW(test_skip) eq "t" } { - elog NOTICE "SKIPPING OPERATION $TG_op" - return SKIP - } - } - - if { [info exists TG_relid] } { - set TG_relid "bogus:12345" - } - - set dnames [info locals {[a-zA-Z]*} ] - - foreach key [lsort $dnames] { - - if { [array exists $key] } { - set str "{" - foreach akey [lsort [ array names $key ] ] { - if {[string length $str] > 1} { set str "$str, " } - set cmd "($akey)" - set cmd "set val \$$key$cmd" - eval $cmd - set str "$str$akey: $val" - } - set str "$str}" - elog NOTICE "$key: $str" - } else { - set val [eval list "\$$key" ] - elog NOTICE "$key: $val" - } - } - - - return OK - -$_$; - -CREATE TRIGGER show_trigger_data_trig -BEFORE INSERT OR UPDATE OR DELETE ON trigger_test -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); -CREATE TRIGGER statement_trigger -BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE ON trigger_test -FOR EACH STATEMENT EXECUTE PROCEDURE trigger_data(42,'statement trigger'); - -CREATE TRIGGER show_trigger_data_view_trig -INSTEAD OF INSERT OR UPDATE OR DELETE ON trigger_test_view -FOR EACH ROW EXECUTE PROCEDURE trigger_data(24,'skidoo view'); - --- --- Trigger function on every change to T_pkey1 --- -create function trig_pkey1_before() returns trigger as E' - # - # Create prepared plans on the first call - # - if {![info exists GD]} { - # - # Plan to check for duplicate key in T_pkey1 - # - set GD(plan_pkey1) [spi_prepare \\ - "select check_pkey1_exists(\\$1, \\$2) as ret" \\ - {int4 bpchar}] - # - # Plan to check for references from T_dta1 - # - set GD(plan_dta1) [spi_prepare \\ - "select 1 from T_dta1 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Initialize flags - # - set check_old_ref 0 - set check_new_dup 0 - - switch $TG_op { - INSERT { - # - # Must check for duplicate key on INSERT - # - set check_new_dup 1 - } - UPDATE { - # - # Must check for duplicate key on UPDATE only if - # the key changes. In that case we must check for - # references to OLD values too. - # - if {[string compare $NEW(key1) $OLD(key1)] != 0} { - set check_old_ref 1 - set check_new_dup 1 - } - if {[string compare $NEW(key2) $OLD(key2)] != 0} { - set check_old_ref 1 - set check_new_dup 1 - } - } - DELETE { - # - # Must only check for references to OLD on DELETE - # - set check_old_ref 1 - } - } - - if {$check_new_dup} { - # - # Check for duplicate key - # - spi_execp -count 1 $GD(plan_pkey1) [list $NEW(key1) $NEW(key2)] - if {$ret == "t"} { - elog ERROR \\ - "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey1" - } - } - - if {$check_old_ref} { - # - # Check for references to OLD - # - set n [spi_execp -count 1 $GD(plan_dta1) [list $OLD(key1) $OLD(key2)]] - if {$n > 0} { - elog ERROR \\ - "key ''$OLD(key1)'', ''$OLD(key2)'' referenced by T_dta1" - } - } - - # - # Anything is fine - let operation pass through - # - return OK -' language pltcl; - - -create trigger pkey1_before before insert or update or delete on T_pkey1 - for each row execute procedure - trig_pkey1_before(); - - --- --- Trigger function to check for duplicate keys in T_pkey2 --- and to force key2 to be upper case only without leading whitespaces --- -create function trig_pkey2_before() returns trigger as E' - # - # Prepare plan on first call - # - if {![info exists GD]} { - set GD(plan_pkey2) [spi_prepare \\ - "select 1 from T_pkey2 \\ - where key1 = \\$1 and key2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Convert key2 value - # - set NEW(key2) [string toupper [string trim $NEW(key2)]] - - # - # Check for duplicate key - # - set n [spi_execp -count 1 $GD(plan_pkey2) [list $NEW(key1) $NEW(key2)]] - if {$n > 0} { - elog ERROR \\ - "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey2" - } - - # - # Return modified tuple in NEW - # - return [array get NEW] -' language pltcl; - - -create trigger pkey2_before before insert or update on T_pkey2 - for each row execute procedure - trig_pkey2_before(); - - --- --- Trigger function to force references from T_dta2 follow changes --- in T_pkey2 or be deleted too. This must be done AFTER the changes --- in T_pkey2 are done so the trigger for primkey check on T_dta2 --- fired on our updates will see the new key values in T_pkey2. --- -create function trig_pkey2_after() returns trigger as E' - # - # Prepare plans on first call - # - if {![info exists GD]} { - # - # Plan to update references from T_dta2 - # - set GD(plan_dta2_upd) [spi_prepare \\ - "update T_dta2 set ref1 = \\$3, ref2 = \\$4 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar int4 bpchar}] - # - # Plan to delete references from T_dta2 - # - set GD(plan_dta2_del) [spi_prepare \\ - "delete from T_dta2 \\ - where ref1 = \\$1 and ref2 = \\$2" \\ - {int4 bpchar}] - } - - # - # Initialize flags - # - set old_ref_follow 0 - set old_ref_delete 0 - - switch $TG_op { - UPDATE { - # - # On update we must let old references follow - # - set NEW(key2) [string toupper $NEW(key2)] - - if {[string compare $NEW(key1) $OLD(key1)] != 0} { - set old_ref_follow 1 - } - if {[string compare $NEW(key2) $OLD(key2)] != 0} { - set old_ref_follow 1 - } - } - DELETE { - # - # On delete we must delete references too - # - set old_ref_delete 1 - } - } - - if {$old_ref_follow} { - # - # Let old references follow and fire NOTICE message if - # there where some - # - set n [spi_execp $GD(plan_dta2_upd) \\ - [list $OLD(key1) $OLD(key2) $NEW(key1) $NEW(key2)]] - if {$n > 0} { - elog NOTICE \\ - "updated $n entries in T_dta2 for new key in T_pkey2" - } - } - - if {$old_ref_delete} { - # - # delete references and fire NOTICE message if - # there where some - # - set n [spi_execp $GD(plan_dta2_del) \\ - [list $OLD(key1) $OLD(key2)]] - if {$n > 0} { - elog NOTICE \\ - "deleted $n entries from T_dta2" - } - } - - return OK -' language pltcl; - - -create trigger pkey2_after after update or delete on T_pkey2 - for each row execute procedure - trig_pkey2_after(); - - --- --- Generic trigger function to check references in T_dta1 and T_dta2 --- -create function check_primkey() returns trigger as E' - # - # For every trigger/relation pair we create - # a saved plan and hold them in GD - # - set plankey [list "plan" $TG_name $TG_relid] - set planrel [list "relname" $TG_relid] - - # - # Extract the pkey relation name - # - set keyidx [expr [llength $args] / 2] - set keyrel [string tolower [lindex $args $keyidx]] - - if {![info exists GD($plankey)]} { - # - # We must prepare a new plan. Build up a query string - # for the primary key check. - # - set keylist [lrange $args [expr $keyidx + 1] end] - - set query "select 1 from $keyrel" - set qual " where" - set typlist "" - set idx 1 - foreach key $keylist { - set key [string tolower $key] - # - # Add the qual part to the query string - # - append query "$qual $key = \\$$idx" - set qual " and" - - # - # Lookup the fields type in pg_attribute - # - set n [spi_exec "select T.typname \\ - from pg_catalog.pg_type T, pg_catalog.pg_attribute A, pg_catalog.pg_class C \\ - where C.relname = ''[quote $keyrel]'' \\ - and C.oid = A.attrelid \\ - and A.attname = ''[quote $key]'' \\ - and A.atttypid = T.oid"] - if {$n != 1} { - elog ERROR "table $keyrel doesn''t have a field named $key" - } - - # - # Append the fields type to the argument type list - # - lappend typlist $typname - incr idx - } - - # - # Prepare the plan - # - set GD($plankey) [spi_prepare $query $typlist] - - # - # Lookup and remember the table name for later error messages - # - spi_exec "select relname from pg_catalog.pg_class \\ - where oid = ''$TG_relid''::oid" - set GD($planrel) $relname - } - - # - # Build the argument list from the NEW row - # - incr keyidx -1 - set arglist "" - foreach arg [lrange $args 0 $keyidx] { - lappend arglist $NEW($arg) - } - - # - # Check for the primary key - # - set n [spi_execp -count 1 $GD($plankey) $arglist] - if {$n <= 0} { - elog ERROR "key for $GD($planrel) not in $keyrel" - } - - # - # Anything is fine - # - return OK -' language pltcl; - - -create trigger dta1_before before insert or update on T_dta1 - for each row execute procedure - check_primkey('ref1', 'ref2', 'T_pkey1', 'key1', 'key2'); - - -create trigger dta2_before before insert or update on T_dta2 - for each row execute procedure - check_primkey('ref1', 'ref2', 'T_pkey2', 'key1', 'key2'); - - -create function tcl_composite_arg_ref1(T_dta1) returns int as ' +create function tcl_composite_arg_ref1(T_comp1) returns int as ' return $1(ref1) ' language pltcl; -create function tcl_composite_arg_ref2(T_dta1) returns text as ' +create function tcl_composite_arg_ref2(T_comp1) returns text as ' return $1(ref2) ' language pltcl; @@ -465,11 +16,6 @@ create function tcl_argisnull(text) returns bool as ' argisnull 1 ' language pltcl; -create function tcl_lastoid(tabname text) returns int8 as ' - spi_exec "insert into $1 default values" - spi_lastoid -' language pltcl; - create function tcl_int4add(int4,int4) returns int4 as ' return [expr $1 + $2] diff --git a/src/pl/tcl/sql/pltcl_trigger.sql b/src/pl/tcl/sql/pltcl_trigger.sql new file mode 100644 index 00000000000..2db75a333a0 --- /dev/null +++ b/src/pl/tcl/sql/pltcl_trigger.sql @@ -0,0 +1,603 @@ +-- suppress CONTEXT so that function OIDs aren't in output +\set VERBOSITY terse + +-- +-- Create the tables used in the test queries +-- +-- T_pkey1 is the primary key table for T_dta1. Entries from T_pkey1 +-- Cannot be changed or deleted if they are referenced from T_dta1. +-- +-- T_pkey2 is the primary key table for T_dta2. If the key values in +-- T_pkey2 are changed, the references in T_dta2 follow. If entries +-- are deleted, the referencing entries from T_dta2 are deleted too. +-- The values for field key2 in T_pkey2 are silently converted to +-- upper case on insert/update. +-- +create table T_pkey1 ( + key1 int4, + key2 char(20), + txt char(40) +); + +create table T_pkey2 ( + key1 int4, + key2 char(20), + txt char(40) +); + +create table T_dta1 ( + tkey char(10), + ref1 int4, + ref2 char(20) +); + +create table T_dta2 ( + tkey char(10), + ref1 int4, + ref2 char(20) +); + + +-- +-- Function to check key existence in T_pkey1 +-- +create function check_pkey1_exists(int4, bpchar) returns bool as E' + if {![info exists GD]} { + set GD(plan) [spi_prepare \\ + "select 1 from T_pkey1 \\ + where key1 = \\$1 and key2 = \\$2" \\ + {int4 bpchar}] + } + + set n [spi_execp -count 1 $GD(plan) [list $1 $2]] + + if {$n > 0} { + return "t" + } + return "f" +' language pltcl; + + +-- dump trigger data + +CREATE TABLE trigger_test ( + i int, + v text, + dropme text, + test_skip boolean DEFAULT false, + test_return_null boolean DEFAULT false, + test_argisnull boolean DEFAULT false +); +-- Make certain dropped attributes are handled correctly +ALTER TABLE trigger_test DROP dropme; + +CREATE TABLE trigger_test_generated ( + i int, + j int GENERATED ALWAYS AS (i * 2) STORED +); + +CREATE VIEW trigger_test_view AS SELECT i, v FROM trigger_test; + +CREATE FUNCTION trigger_data() returns trigger language pltcl as $_$ + if {$TG_table_name eq "trigger_test" && $TG_level eq "ROW" && $TG_op ne "DELETE"} { + # Special case tests + if {$NEW(test_return_null) eq "t" } { + return_null + } + if {$NEW(test_argisnull) eq "t" } { + set should_error [argisnull 1] + } + if {$NEW(test_skip) eq "t" } { + elog NOTICE "SKIPPING OPERATION $TG_op" + return SKIP + } + } + + if { [info exists TG_relid] } { + set TG_relid "bogus:12345" + } + + set dnames [info locals {[a-zA-Z]*} ] + + foreach key [lsort $dnames] { + + if { [array exists $key] } { + set str "{" + foreach akey [lsort [ array names $key ] ] { + if {[string length $str] > 1} { set str "$str, " } + set cmd "($akey)" + set cmd "set val \$$key$cmd" + eval $cmd + set str "$str$akey: $val" + } + set str "$str}" + elog NOTICE "$key: $str" + } else { + set val [eval list "\$$key" ] + elog NOTICE "$key: $val" + } + } + + + return OK + +$_$; + +CREATE TRIGGER show_trigger_data_trig +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +CREATE TRIGGER statement_trigger +BEFORE INSERT OR UPDATE OR DELETE OR TRUNCATE ON trigger_test +FOR EACH STATEMENT EXECUTE PROCEDURE trigger_data(42,'statement trigger'); + +CREATE TRIGGER show_trigger_data_trig_before +BEFORE INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); +CREATE TRIGGER show_trigger_data_trig_after +AFTER INSERT OR UPDATE OR DELETE ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE trigger_data(); + +CREATE TRIGGER show_trigger_data_view_trig +INSTEAD OF INSERT OR UPDATE OR DELETE ON trigger_test_view +FOR EACH ROW EXECUTE PROCEDURE trigger_data(24,'skidoo view'); + +-- +-- Trigger function on every change to T_pkey1 +-- +create function trig_pkey1_before() returns trigger as E' + # + # Create prepared plans on the first call + # + if {![info exists GD]} { + # + # Plan to check for duplicate key in T_pkey1 + # + set GD(plan_pkey1) [spi_prepare \\ + "select check_pkey1_exists(\\$1, \\$2) as ret" \\ + {int4 bpchar}] + # + # Plan to check for references from T_dta1 + # + set GD(plan_dta1) [spi_prepare \\ + "select 1 from T_dta1 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Initialize flags + # + set check_old_ref 0 + set check_new_dup 0 + + switch $TG_op { + INSERT { + # + # Must check for duplicate key on INSERT + # + set check_new_dup 1 + } + UPDATE { + # + # Must check for duplicate key on UPDATE only if + # the key changes. In that case we must check for + # references to OLD values too. + # + if {[string compare $NEW(key1) $OLD(key1)] != 0} { + set check_old_ref 1 + set check_new_dup 1 + } + if {[string compare $NEW(key2) $OLD(key2)] != 0} { + set check_old_ref 1 + set check_new_dup 1 + } + } + DELETE { + # + # Must only check for references to OLD on DELETE + # + set check_old_ref 1 + } + } + + if {$check_new_dup} { + # + # Check for duplicate key + # + spi_execp -count 1 $GD(plan_pkey1) [list $NEW(key1) $NEW(key2)] + if {$ret == "t"} { + elog ERROR \\ + "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey1" + } + } + + if {$check_old_ref} { + # + # Check for references to OLD + # + set n [spi_execp -count 1 $GD(plan_dta1) [list $OLD(key1) $OLD(key2)]] + if {$n > 0} { + elog ERROR \\ + "key ''$OLD(key1)'', ''$OLD(key2)'' referenced by T_dta1" + } + } + + # + # Anything is fine - let operation pass through + # + return OK +' language pltcl; + + +create trigger pkey1_before before insert or update or delete on T_pkey1 + for each row execute procedure + trig_pkey1_before(); + + +-- +-- Trigger function to check for duplicate keys in T_pkey2 +-- and to force key2 to be upper case only without leading whitespaces +-- +create function trig_pkey2_before() returns trigger as E' + # + # Prepare plan on first call + # + if {![info exists GD]} { + set GD(plan_pkey2) [spi_prepare \\ + "select 1 from T_pkey2 \\ + where key1 = \\$1 and key2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Convert key2 value + # + set NEW(key2) [string toupper [string trim $NEW(key2)]] + + # + # Check for duplicate key + # + set n [spi_execp -count 1 $GD(plan_pkey2) [list $NEW(key1) $NEW(key2)]] + if {$n > 0} { + elog ERROR \\ + "duplicate key ''$NEW(key1)'', ''$NEW(key2)'' for T_pkey2" + } + + # + # Return modified tuple in NEW + # + return [array get NEW] +' language pltcl; + + +create trigger pkey2_before before insert or update on T_pkey2 + for each row execute procedure + trig_pkey2_before(); + + +-- +-- Trigger function to force references from T_dta2 follow changes +-- in T_pkey2 or be deleted too. This must be done AFTER the changes +-- in T_pkey2 are done so the trigger for primkey check on T_dta2 +-- fired on our updates will see the new key values in T_pkey2. +-- +create function trig_pkey2_after() returns trigger as E' + # + # Prepare plans on first call + # + if {![info exists GD]} { + # + # Plan to update references from T_dta2 + # + set GD(plan_dta2_upd) [spi_prepare \\ + "update T_dta2 set ref1 = \\$3, ref2 = \\$4 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar int4 bpchar}] + # + # Plan to delete references from T_dta2 + # + set GD(plan_dta2_del) [spi_prepare \\ + "delete from T_dta2 \\ + where ref1 = \\$1 and ref2 = \\$2" \\ + {int4 bpchar}] + } + + # + # Initialize flags + # + set old_ref_follow 0 + set old_ref_delete 0 + + switch $TG_op { + UPDATE { + # + # On update we must let old references follow + # + set NEW(key2) [string toupper $NEW(key2)] + + if {[string compare $NEW(key1) $OLD(key1)] != 0} { + set old_ref_follow 1 + } + if {[string compare $NEW(key2) $OLD(key2)] != 0} { + set old_ref_follow 1 + } + } + DELETE { + # + # On delete we must delete references too + # + set old_ref_delete 1 + } + } + + if {$old_ref_follow} { + # + # Let old references follow and fire NOTICE message if + # there where some + # + set n [spi_execp $GD(plan_dta2_upd) \\ + [list $OLD(key1) $OLD(key2) $NEW(key1) $NEW(key2)]] + if {$n > 0} { + elog NOTICE \\ + "updated $n entries in T_dta2 for new key in T_pkey2" + } + } + + if {$old_ref_delete} { + # + # delete references and fire NOTICE message if + # there where some + # + set n [spi_execp $GD(plan_dta2_del) \\ + [list $OLD(key1) $OLD(key2)]] + if {$n > 0} { + elog NOTICE \\ + "deleted $n entries from T_dta2" + } + } + + return OK +' language pltcl; + + +create trigger pkey2_after after update or delete on T_pkey2 + for each row execute procedure + trig_pkey2_after(); + + +-- +-- Generic trigger function to check references in T_dta1 and T_dta2 +-- +create function check_primkey() returns trigger as E' + # + # For every trigger/relation pair we create + # a saved plan and hold them in GD + # + set plankey [list "plan" $TG_name $TG_relid] + set planrel [list "relname" $TG_relid] + + # + # Extract the pkey relation name + # + set keyidx [expr [llength $args] / 2] + set keyrel [string tolower [lindex $args $keyidx]] + + if {![info exists GD($plankey)]} { + # + # We must prepare a new plan. Build up a query string + # for the primary key check. + # + set keylist [lrange $args [expr $keyidx + 1] end] + + set query "select 1 from $keyrel" + set qual " where" + set typlist "" + set idx 1 + foreach key $keylist { + set key [string tolower $key] + # + # Add the qual part to the query string + # + append query "$qual $key = \\$$idx" + set qual " and" + + # + # Lookup the fields type in pg_attribute + # + set n [spi_exec "select T.typname \\ + from pg_catalog.pg_type T, pg_catalog.pg_attribute A, pg_catalog.pg_class C \\ + where C.relname = ''[quote $keyrel]'' \\ + and C.oid = A.attrelid \\ + and A.attname = ''[quote $key]'' \\ + and A.atttypid = T.oid"] + if {$n != 1} { + elog ERROR "table $keyrel doesn''t have a field named $key" + } + + # + # Append the fields type to the argument type list + # + lappend typlist $typname + incr idx + } + + # + # Prepare the plan + # + set GD($plankey) [spi_prepare $query $typlist] + + # + # Lookup and remember the table name for later error messages + # + spi_exec "select relname from pg_catalog.pg_class \\ + where oid = ''$TG_relid''::oid" + set GD($planrel) $relname + } + + # + # Build the argument list from the NEW row + # + incr keyidx -1 + set arglist "" + foreach arg [lrange $args 0 $keyidx] { + lappend arglist $NEW($arg) + } + + # + # Check for the primary key + # + set n [spi_execp -count 1 $GD($plankey) $arglist] + if {$n <= 0} { + elog ERROR "key for $GD($planrel) not in $keyrel" + } + + # + # Anything is fine + # + return OK +' language pltcl; + + +create trigger dta1_before before insert or update on T_dta1 + for each row execute procedure + check_primkey('ref1', 'ref2', 'T_pkey1', 'key1', 'key2'); + + +create trigger dta2_before before insert or update on T_dta2 + for each row execute procedure + check_primkey('ref1', 'ref2', 'T_pkey2', 'key1', 'key2'); + + +insert into T_pkey1 values (1, 'key1-1', 'test key'); +insert into T_pkey1 values (1, 'key1-2', 'test key'); +insert into T_pkey1 values (1, 'key1-3', 'test key'); +insert into T_pkey1 values (2, 'key2-1', 'test key'); +insert into T_pkey1 values (2, 'key2-2', 'test key'); +insert into T_pkey1 values (2, 'key2-3', 'test key'); + +insert into T_pkey2 values (1, 'key1-1', 'test key'); +insert into T_pkey2 values (1, 'key1-2', 'test key'); +insert into T_pkey2 values (1, 'key1-3', 'test key'); +insert into T_pkey2 values (2, 'key2-1', 'test key'); +insert into T_pkey2 values (2, 'key2-2', 'test key'); +insert into T_pkey2 values (2, 'key2-3', 'test key'); + +select * from T_pkey1; + +-- key2 in T_pkey2 should have upper case only +select * from T_pkey2; + +insert into T_pkey1 values (1, 'KEY1-3', 'should work'); + +-- Due to the upper case translation in trigger this must fail +insert into T_pkey2 values (1, 'KEY1-3', 'should fail'); + +insert into T_dta1 values ('trec 1', 1, 'key1-1'); +insert into T_dta1 values ('trec 2', 1, 'key1-2'); +insert into T_dta1 values ('trec 3', 1, 'key1-3'); + +-- Must fail due to unknown key in T_pkey1 +insert into T_dta1 values ('trec 4', 1, 'key1-4'); + +insert into T_dta2 values ('trec 1', 1, 'KEY1-1'); +insert into T_dta2 values ('trec 2', 1, 'KEY1-2'); +insert into T_dta2 values ('trec 3', 1, 'KEY1-3'); + +-- Must fail due to unknown key in T_pkey2 +insert into T_dta2 values ('trec 4', 1, 'KEY1-4'); + +select * from T_dta1; + +select * from T_dta2; + +update T_pkey1 set key2 = 'key2-9' where key1 = 2 and key2 = 'key2-1'; +update T_pkey1 set key2 = 'key1-9' where key1 = 1 and key2 = 'key1-1'; +delete from T_pkey1 where key1 = 2 and key2 = 'key2-2'; +delete from T_pkey1 where key1 = 1 and key2 = 'key1-2'; + +update T_pkey2 set key2 = 'KEY2-9' where key1 = 2 and key2 = 'KEY2-1'; +update T_pkey2 set key2 = 'KEY1-9' where key1 = 1 and key2 = 'KEY1-1'; +delete from T_pkey2 where key1 = 2 and key2 = 'KEY2-2'; +delete from T_pkey2 where key1 = 1 and key2 = 'KEY1-2'; + +select * from T_pkey1; +select * from T_pkey2; +select * from T_dta1; +select * from T_dta2; + +select tcl_avg(key1) from T_pkey1; +select tcl_sum(key1) from T_pkey1; +select tcl_avg(key1) from T_pkey2; +select tcl_sum(key1) from T_pkey2; + +-- The following should return NULL instead of 0 +select tcl_avg(key1) from T_pkey1 where key1 = 99; +select tcl_sum(key1) from T_pkey1 where key1 = 99; + +select 1 @< 2; +select 100 @< 4; + +select * from T_pkey1 order by key1 using @<, key2 collate "C"; +select * from T_pkey2 order by key1 using @<, key2 collate "C"; + +-- show dump of trigger data +insert into trigger_test values(1,'insert'); + +insert into trigger_test_generated (i) values (1); +update trigger_test_generated set i = 11 where i = 1; +delete from trigger_test_generated; + +insert into trigger_test_view values(2,'insert'); +update trigger_test_view set v = 'update' where i=1; +delete from trigger_test_view; + +update trigger_test set v = 'update', test_skip=true where i = 1; +update trigger_test set v = 'update' where i = 1; +delete from trigger_test; +truncate trigger_test; + +DROP TRIGGER show_trigger_data_trig_before ON trigger_test_generated; +DROP TRIGGER show_trigger_data_trig_after ON trigger_test_generated; + +-- should error +insert into trigger_test(test_argisnull) values(true); + +-- should error +insert into trigger_test(test_return_null) values(true); + +-- test transition table visibility +create table transition_table_test (id int, name text); +insert into transition_table_test values (1, 'a'); +create function transition_table_test_f() returns trigger language pltcl as +$$ + spi_exec -array C "SELECT id, name FROM old_table" { + elog INFO "old: $C(id) -> $C(name)" + } + spi_exec -array C "SELECT id, name FROM new_table" { + elog INFO "new: $C(id) -> $C(name)" + } + return OK +$$; +CREATE TRIGGER a_t AFTER UPDATE ON transition_table_test + REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table + FOR EACH STATEMENT EXECUTE PROCEDURE transition_table_test_f(); +update transition_table_test set name = 'b'; +drop table transition_table_test; +drop function transition_table_test_f(); + +-- dealing with generated columns + +CREATE FUNCTION generated_test_func1() RETURNS trigger +LANGUAGE pltcl +AS $$ +# not allowed +set NEW(j) 5 +return [array get NEW] +$$; + +CREATE TRIGGER generated_test_trigger1 BEFORE INSERT ON trigger_test_generated +FOR EACH ROW EXECUTE PROCEDURE generated_test_func1(); + +TRUNCATE trigger_test_generated; +INSERT INTO trigger_test_generated (i) VALUES (1); +SELECT * FROM trigger_test_generated; diff --git a/src/port/.gitignore b/src/port/.gitignore index 53a40324447..2037b7d2ab6 100644 --- a/src/port/.gitignore +++ b/src/port/.gitignore @@ -1,3 +1,4 @@ /libpgport.a +/libpgport_shlib.a /libpgport_srv.a /pg_config_paths.h diff --git a/src/port/Makefile b/src/port/Makefile index d7467fb0788..b9492b741f4 100644 --- a/src/port/Makefile +++ b/src/port/Makefile @@ -1,18 +1,23 @@ #------------------------------------------------------------------------- # # Makefile -# Makefile for the port-specific subsystem of the backend +# Makefile for src/port # -# These files are used in other directories for portability on systems -# with broken/missing library files, and for common code sharing. +# These files are used by the Postgres backend, and also by frontend +# programs. Primarily, they are meant to provide portability on systems +# with broken/missing library files. # -# This makefile generates two outputs: +# This makefile generates three outputs: # # libpgport.a - contains object files with FRONTEND defined, -# for use by client application and libraries +# for use by client applications +# +# libpgport_shlib.a - contains object files with FRONTEND defined, +# built suitably for use in shared libraries; for use +# by frontend libraries # # libpgport_srv.a - contains object files without FRONTEND defined, -# for use only by the backend binaries +# for use only by the backend # # LIBOBJS is set by configure (via Makefile.global) to be the list of object # files that are conditionally needed as determined by configure's probing. @@ -31,44 +36,65 @@ override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) OBJS = $(LIBOBJS) $(PG_CRC32C_OBJS) chklocale.o erand48.o inet_net_ntop.o \ - noblock.o path.o pgcheckdir.o pgmkdirp.o pgsleep.o \ - pgstrcasecmp.o pqsignal.o \ - qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o - -ifeq ($(enable_strong_random), yes) -OBJS += pg_strong_random.o -endif - -# foo_srv.o and foo.o are both built from foo.c, but only foo.o has -DFRONTEND + noblock.o path.o pg_bitutils.o pgcheckdir.o pgmkdirp.o pgsleep.o \ + pg_strong_random.o pgstrcasecmp.o pgstrsignal.o pqsignal.o \ + qsort.o qsort_arg.o quotes.o snprintf.o sprompt.o strerror.o \ + tar.o thread.o + +# libpgport.a, libpgport_shlib.a, and libpgport_srv.a contain the same files +# foo.o, foo_shlib.o, and foo_srv.o are all built from foo.c +OBJS_SHLIB = $(OBJS:%.o=%_shlib.o) OBJS_SRV = $(OBJS:%.o=%_srv.o) -all: libpgport.a libpgport_srv.a +all: libpgport.a libpgport_shlib.a libpgport_srv.a # libpgport is needed by some contrib install: all installdirs $(INSTALL_STLIB) libpgport.a '$(DESTDIR)$(libdir)/libpgport.a' + $(INSTALL_STLIB) libpgport_shlib.a '$(DESTDIR)$(libdir)/libpgport_shlib.a' installdirs: $(MKDIR_P) '$(DESTDIR)$(libdir)' uninstall: rm -f '$(DESTDIR)$(libdir)/libpgport.a' + rm -f '$(DESTDIR)$(libdir)/libpgport_shlib.a' libpgport.a: $(OBJS) rm -f $@ $(AR) $(AROPT) $@ $^ -# thread.o needs PTHREAD_CFLAGS (but thread_srv.o does not) +# thread.o and thread_shlib.o need PTHREAD_CFLAGS (but thread_srv.o does not) thread.o: CFLAGS+=$(PTHREAD_CFLAGS) +thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS) -# pg_crc32c_sse42.o and its _srv.o version need CFLAGS_SSE42 +# all versions of pg_crc32c_sse42.o need CFLAGS_SSE42 pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42) +pg_crc32c_sse42_shlib.o: CFLAGS+=$(CFLAGS_SSE42) pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42) -# pg_crc32c_armv8.o and its _srv.o version need CFLAGS_ARMV8_CRC32C +# all versions of pg_crc32c_armv8.o need CFLAGS_ARMV8_CRC32C pg_crc32c_armv8.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C) +pg_crc32c_armv8_shlib.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C) pg_crc32c_armv8_srv.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C) +# +# Shared library versions of object files +# + +libpgport_shlib.a: $(OBJS_SHLIB) + rm -f $@ + $(AR) $(AROPT) $@ $^ + +# Because this uses its own compilation rule, it doesn't use the +# dependency tracking logic from Makefile.global. To make sure that +# dependency tracking works anyway for the *_shlib.o files, depend on +# their *.o siblings as well, which do have proper dependencies. It's +# a hack that might fail someday if there is a *_shlib.o without a +# corresponding *.o, but there seems little reason for that. +%_shlib.o: %.c %.o + $(CC) $(CFLAGS) $(CFLAGS_SL) $(CPPFLAGS) -c $< -o $@ + # # Server versions of object files # @@ -91,6 +117,8 @@ libpgport_srv.a: $(OBJS_SRV) path.o: path.c pg_config_paths.h +path_shlib.o: path.c pg_config_paths.h + path_srv.o: path.c pg_config_paths.h # We create a separate file rather than put these in pg_config.h @@ -111,4 +139,5 @@ pg_config_paths.h: $(top_builddir)/src/Makefile.global echo "#define MANDIR \"$(mandir)\"" >>$@ clean distclean maintainer-clean: - rm -f libpgport.a libpgport_srv.a $(OBJS) $(OBJS_SRV) pg_config_paths.h + rm -f libpgport.a libpgport_shlib.a libpgport_srv.a + rm -f $(OBJS) $(OBJS_SHLIB) $(OBJS_SRV) pg_config_paths.h diff --git a/src/port/README b/src/port/README index 4ae96da0158..c446b46e26e 100644 --- a/src/port/README +++ b/src/port/README @@ -18,7 +18,7 @@ and adding infrastructure to recompile the object files: OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \ connect.o misc.o path.o exec.o \ - $(filter snprintf.o, $(LIBOBJS)) + $(filter strlcat.o, $(LIBOBJS)) The problem is that there is no testing of which object files need to be added, but missing functions usually show up when linking user diff --git a/src/port/chklocale.c b/src/port/chklocale.c index dde913099f1..9b753c85e97 100644 --- a/src/port/chklocale.c +++ b/src/port/chklocale.c @@ -4,7 +4,7 @@ * Functions for handling locale-related info * * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/port/crypt.c b/src/port/crypt.c deleted file mode 100644 index 786161ff351..00000000000 --- a/src/port/crypt.c +++ /dev/null @@ -1,1088 +0,0 @@ -/* src/port/crypt.c */ -/* $NetBSD: crypt.c,v 1.18 2001/03/01 14:37:35 wiz Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Tom Truscott. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 -static char sccsid[] = "@(#)crypt.c 8.1.1.1 (Berkeley) 8/18/93"; -#else -__RCSID("$NetBSD: crypt.c,v 1.18 2001/03/01 14:37:35 wiz Exp $"); -#endif -#endif /* not lint */ - -#include "c.h" - -#include - -#ifndef WIN32 -#include -#endif - -static int des_setkey(const char *key); -static int des_cipher(const char *in, char *out, long salt, int num_iter); - -/* - * UNIX password, and DES, encryption. - * By Tom Truscott, trt@rti.rti.org, - * from algorithms by Robert W. Baldwin and James Gillogly. - * - * References: - * "Mathematical Cryptology for Computer Scientists and Mathematicians," - * by Wayne Patterson, 1987, ISBN 0-8476-7438-X. - * - * "Password Security: A Case History," R. Morris and Ken Thompson, - * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979. - * - * "DES will be Totally Insecure within Ten Years," M.E. Hellman, - * IEEE Spectrum, vol. 16, pp. 32-39, July 1979. - */ - -/* ===== Configuration ==================== */ - -/* - * define "MUST_ALIGN" if your compiler cannot load/store - * long integers at arbitrary (e.g. odd) memory locations. - * (Either that or never pass unaligned addresses to des_cipher!) - */ -/* #define MUST_ALIGN */ - -#ifdef CHAR_BITS -#if CHAR_BITS != 8 -#error C_block structure assumes 8 bit characters -#endif -#endif - -/* - * define "B64" to be the declaration for a 64 bit integer. - * XXX this feature is currently unused, see "endian" comment below. - */ -/* #define B64 int64 */ - -/* - * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes - * of lookup tables. This speeds up des_setkey() and des_cipher(), but has - * little effect on crypt(). - */ -/* #define LARGEDATA */ - -/* compile with "-DSTATIC=void" when profiling */ -#ifndef STATIC -#define STATIC static void -#endif - -/* - * Define the "int32_t" type for integral type with a width of at least - * 32 bits. - */ -typedef int int32_t; - -/* ==================================== */ - -#define _PASSWORD_EFMT1 '_' /* extended encryption format */ - -/* - * Cipher-block representation (Bob Baldwin): - * - * DES operates on groups of 64 bits, numbered 1..64 (sigh). One - * representation is to store one bit per byte in an array of bytes. Bit N of - * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array. - * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the - * first byte, 9..16 in the second, and so on. The DES spec apparently has - * bit 1 in the MSB of the first byte, but that is particularly noxious so we - * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is - * the MSB of the first byte. Specifically, the 64-bit input data and key are - * converted to LSB format, and the output 64-bit block is converted back into - * MSB format. - * - * DES operates internally on groups of 32 bits which are expanded to 48 bits - * by permutation E and shrunk back to 32 bits by the S boxes. To speed up - * the computation, the expansion is applied only once, the expanded - * representation is maintained during the encryption, and a compression - * permutation is applied only at the end. To speed up the S-box lookups, - * the 48 bits are maintained as eight 6 bit groups, one per byte, which - * directly feed the eight S-boxes. Within each byte, the 6 bits are the - * most significant ones. The low two bits of each byte are zero. (Thus, - * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the - * first byte in the eight byte representation, bit 2 of the 48 bit value is - * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is - * used, in which the output is the 64 bit result of an S-box lookup which - * has been permuted by P and expanded by E, and is ready for use in the next - * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this - * lookup. Since each byte in the 48 bit path is a multiple of four, indexed - * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and - * "salt" are also converted to this 8*(6+2) format. The SPE table size is - * 8*64*8 = 4K bytes. - * - * To speed up bit-parallel operations (such as XOR), the 8 byte - * representation is "union"ed with 32 bit values "i0" and "i1", and, on - * machines which support it, a 64 bit value "b64". This data structure, - * "C_block", has two problems. First, alignment restrictions must be - * honored. Second, the byte-order (e.g. little-endian or big-endian) of - * the architecture becomes visible. - * - * The byte-order problem is unfortunate, since on the one hand it is good - * to have a machine-independent C_block representation (bits 1..8 in the - * first byte, etc.), and on the other hand it is good for the LSB of the - * first byte to be the LSB of i0. We cannot have both these things, so we - * currently use the "little-endian" representation and avoid any multi-byte - * operations that depend on byte order. This largely precludes use of the - * 64-bit datatype since the relative order of i0 and i1 are unknown. It - * also inhibits grouping the SPE table to look up 12 bits at a time. (The - * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1 - * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the - * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup - * requires a 128 kilobyte table, so perhaps this is not a big loss. - * - * Permutation representation (Jim Gillogly): - * - * A transformation is defined by its effect on each of the 8 bytes of the - * 64-bit input. For each byte we give a 64-bit output that has the bits in - * the input distributed appropriately. The transformation is then the OR - * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for - * each transformation. Unless LARGEDATA is defined, however, a more compact - * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks. - * The smaller table uses 16*16*8 = 2K bytes for each transformation. This - * is slower but tolerable, particularly for password encryption in which - * the SPE transformation is iterated many times. The small tables total 9K - * bytes, the large tables total 72K bytes. - * - * The transformations used are: - * IE3264: MSB->LSB conversion, initial permutation, and expansion. - * This is done by collecting the 32 even-numbered bits and applying - * a 32->64 bit transformation, and then collecting the 32 odd-numbered - * bits and applying the same transformation. Since there are only - * 32 input bits, the IE3264 transformation table is half the size of - * the usual table. - * CF6464: Compression, final permutation, and LSB->MSB conversion. - * This is done by two trivial 48->32 bit compressions to obtain - * a 64-bit block (the bit numbering is given in the "CIFP" table) - * followed by a 64->64 bit "cleanup" transformation. (It would - * be possible to group the bits in the 64-bit block so that 2 - * identical 32->32 bit transformations could be used instead, - * saving a factor of 4 in space and possibly 2 in time, but - * byte-ordering and other complications rear their ugly head. - * Similar opportunities/problems arise in the key schedule - * transforms.) - * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation. - * This admittedly baroque 64->64 bit transformation is used to - * produce the first code (in 8*(6+2) format) of the key schedule. - * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation. - * It would be possible to define 15 more transformations, each - * with a different rotation, to generate the entire key schedule. - * To save space, however, we instead permute each code into the - * next by using a transformation that "undoes" the PC2 permutation, - * rotates the code, and then applies PC2. Unfortunately, PC2 - * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not - * invertible. We get around that problem by using a modified PC2 - * which retains the 8 otherwise-lost bits in the unused low-order - * bits of each byte. The low-order bits are cleared when the - * codes are stored into the key schedule. - * PC2ROT[1]: Same as PC2ROT[0], but with two rotations. - * This is faster than applying PC2ROT[0] twice, - * - * The Bell Labs "salt" (Bob Baldwin): - * - * The salting is a simple permutation applied to the 48-bit result of E. - * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and - * i+24 of the result are swapped. The salt is thus a 24 bit number, with - * 16777216 possible values. (The original salt was 12 bits and could not - * swap bits 13..24 with 36..48.) - * - * It is possible, but ugly, to warp the SPE table to account for the salt - * permutation. Fortunately, the conditional bit swapping requires only - * about four machine instructions and can be done on-the-fly with about an - * 8% performance penalty. - */ - -typedef union -{ - unsigned char b[8]; - struct - { - int32_t i0; - int32_t i1; - } b32; -#if defined(B64) - B64 b64; -#endif -} C_block; - -/* - * Convert twenty-four-bit long in host-order - * to six bits (and 2 low-order zeroes) per char little-endian format. - */ -#define TO_SIX_BIT(rslt, src) { \ - C_block cvt; \ - cvt.b[0] = src; src >>= 6; \ - cvt.b[1] = src; src >>= 6; \ - cvt.b[2] = src; src >>= 6; \ - cvt.b[3] = src; \ - rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \ - } - -/* - * These macros may someday permit efficient use of 64-bit integers. - */ -#define ZERO(d,d0,d1) d0 = 0, d1 = 0 -#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1 -#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1 -#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1 -#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1 -#define DCL_BLOCK(d,d0,d1) int32_t d0, d1 - -#if defined(LARGEDATA) - /* Waste memory like crazy. Also, do permutations in line */ -#define LGCHUNKBITS 3 -#define CHUNKBITS (1<> 4]; - OR(D, D0, D1, *tp); - p += (1 << CHUNKBITS); - } while (--chars_in > 0); - STORE(D, D0, D1, *out); -} -#endif /* LARGEDATA */ - - -/* ===== (mostly) Standard DES Tables ==================== */ - -static const unsigned char IP[] = { /* initial permutation */ - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7, -}; - -/* The final permutation is the inverse of IP - no table is necessary */ - -static const unsigned char ExpandTr[] = { /* expansion operation */ - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1, -}; - -static const unsigned char PC1[] = { /* permuted choice table 1 */ - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4, -}; - -static const unsigned char Rotates[] = { /* PC1 rotation schedule */ - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, -}; - -/* note: each "row" of PC2 is left-padded with bits that make it invertible */ -static const unsigned char PC2[] = { /* permuted choice table 2 */ - 9, 18, 14, 17, 11, 24, 1, 5, - 22, 25, 3, 28, 15, 6, 21, 10, - 35, 38, 23, 19, 12, 4, 26, 8, - 43, 54, 16, 7, 27, 20, 13, 2, - - 0, 0, 41, 52, 31, 37, 47, 55, - 0, 0, 30, 40, 51, 45, 33, 48, - 0, 0, 44, 49, 39, 56, 34, 53, - 0, 0, 46, 42, 50, 36, 29, 32, -}; - -static const unsigned char S[8][64] = { /* 48->32 bit substitution tables */ - /* S[1] */ - {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, - /* S[2] */ - {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, - /* S[3] */ - {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, - /* S[4] */ - {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, - /* S[5] */ - {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, - /* S[6] */ - {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, - /* S[7] */ - {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, - /* S[8] */ - {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} -}; - -static const unsigned char P32Tr[] = { /* 32-bit permutation function */ - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25, -}; - -static const unsigned char CIFP[] = { /* compressed/interleaved permutation */ - 1, 2, 3, 4, 17, 18, 19, 20, - 5, 6, 7, 8, 21, 22, 23, 24, - 9, 10, 11, 12, 25, 26, 27, 28, - 13, 14, 15, 16, 29, 30, 31, 32, - - 33, 34, 35, 36, 49, 50, 51, 52, - 37, 38, 39, 40, 53, 54, 55, 56, - 41, 42, 43, 44, 57, 58, 59, 60, - 45, 46, 47, 48, 61, 62, 63, 64, -}; - -static const unsigned char itoa64[] = /* 0..63 => ascii-64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - - -/* ===== Tables that are initialized at run time ==================== */ - - -static unsigned char a64toi[128]; /* ascii-64 => 0..63 */ - -/* Initial key schedule permutation */ -static C_block PC1ROT[64 / CHUNKBITS][1 << CHUNKBITS]; - -/* Subsequent key schedule rotation permutations */ -static C_block PC2ROT[2][64 / CHUNKBITS][1 << CHUNKBITS]; - -/* Initial permutation/expansion table */ -static C_block IE3264[32 / CHUNKBITS][1 << CHUNKBITS]; - -/* Table that combines the S, P, and E operations. */ -static int32_t SPE[2][8][64]; - -/* compressed/interleaved => final permutation table */ -static C_block CF6464[64 / CHUNKBITS][1 << CHUNKBITS]; - - -/* ==================================== */ - - -static C_block constdatablock; /* encryption constant */ -static char cryptresult[1 + 4 + 4 + 11 + 1]; /* encrypted result */ - -extern char *__md5crypt(const char *, const char *); /* XXX */ -extern char *__bcrypt(const char *, const char *); /* XXX */ - - -/* - * Return a pointer to static data consisting of the "setting" - * followed by an encryption produced by the "key" and "setting". - */ -char * -crypt(key, setting) -const char *key; -const char *setting; -{ - char *encp; - int32_t i; - int t; - int32_t salt; - int num_iter, - salt_size; - C_block keyblock, - rsltblock; - -#if 0 - /* Non-DES encryption schemes hook in here. */ - if (setting[0] == _PASSWORD_NONDES) - { - switch (setting[1]) - { - case '2': - return (__bcrypt(key, setting)); - case '1': - default: - return (__md5crypt(key, setting)); - } - } -#endif - - for (i = 0; i < 8; i++) - { - if ((t = 2 * (unsigned char) (*key)) != 0) - key++; - keyblock.b[i] = t; - } - if (des_setkey((char *) keyblock.b)) /* also initializes "a64toi" */ - return (NULL); - - encp = &cryptresult[0]; - switch (*setting) - { - case _PASSWORD_EFMT1: - - /* - * Involve the rest of the password 8 characters at a time. - */ - while (*key) - { - if (des_cipher((char *) (void *) &keyblock, - (char *) (void *) &keyblock, 0L, 1)) - return (NULL); - for (i = 0; i < 8; i++) - { - if ((t = 2 * (unsigned char) (*key)) != 0) - key++; - keyblock.b[i] ^= t; - } - if (des_setkey((char *) keyblock.b)) - return (NULL); - } - - *encp++ = *setting++; - - /* get iteration count */ - num_iter = 0; - for (i = 4; --i >= 0;) - { - if ((t = (unsigned char) setting[i]) == '\0') - t = '.'; - encp[i] = t; - num_iter = (num_iter << 6) | a64toi[t]; - } - setting += 4; - encp += 4; - salt_size = 4; - break; - default: - num_iter = 25; - salt_size = 2; - } - - salt = 0; - for (i = salt_size; --i >= 0;) - { - if ((t = (unsigned char) setting[i]) == '\0') - t = '.'; - encp[i] = t; - salt = (salt << 6) | a64toi[t]; - } - encp += salt_size; - if (des_cipher((char *) (void *) &constdatablock, - (char *) (void *) &rsltblock, salt, num_iter)) - return (NULL); - - /* - * Encode the 64 cipher bits as 11 ascii characters. - */ - i = ((int32_t) ((rsltblock.b[0] << 8) | rsltblock.b[1]) << 8) | - rsltblock.b[2]; - encp[3] = itoa64[i & 0x3f]; - i >>= 6; - encp[2] = itoa64[i & 0x3f]; - i >>= 6; - encp[1] = itoa64[i & 0x3f]; - i >>= 6; - encp[0] = itoa64[i]; - encp += 4; - i = ((int32_t) ((rsltblock.b[3] << 8) | rsltblock.b[4]) << 8) | - rsltblock.b[5]; - encp[3] = itoa64[i & 0x3f]; - i >>= 6; - encp[2] = itoa64[i & 0x3f]; - i >>= 6; - encp[1] = itoa64[i & 0x3f]; - i >>= 6; - encp[0] = itoa64[i]; - encp += 4; - i = ((int32_t) ((rsltblock.b[6]) << 8) | rsltblock.b[7]) << 2; - encp[2] = itoa64[i & 0x3f]; - i >>= 6; - encp[1] = itoa64[i & 0x3f]; - i >>= 6; - encp[0] = itoa64[i]; - - encp[3] = 0; - - return (cryptresult); -} - - -/* - * The Key Schedule, filled in by des_setkey() or setkey(). - */ -#define KS_SIZE 16 -static C_block KS[KS_SIZE]; - -static volatile int des_ready = 0; - -/* - * Set up the key schedule from the key. - */ -static int -des_setkey(key) -const char *key; -{ - DCL_BLOCK(K, K0, K1); - C_block *ptabp; - int i; - - if (!des_ready) - init_des(); - - PERM6464(K, K0, K1, (unsigned char *) key, (C_block *) PC1ROT); - key = (char *) &KS[0]; - STORE(K & ~0x03030303L, K0 & ~0x03030303L, K1, *(C_block *) key); - for (i = 1; i < 16; i++) - { - key += sizeof(C_block); - STORE(K, K0, K1, *(C_block *) key); - ptabp = (C_block *) PC2ROT[Rotates[i] - 1]; - PERM6464(K, K0, K1, (unsigned char *) key, ptabp); - STORE(K & ~0x03030303L, K0 & ~0x03030303L, K1, *(C_block *) key); - } - return (0); -} - -/* - * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter) - * iterations of DES, using the given 24-bit salt and the pre-computed key - * schedule, and store the resulting 8 chars at "out" (in == out is permitted). - * - * NOTE: the performance of this routine is critically dependent on your - * compiler and machine architecture. - */ -static int -des_cipher(in, out, salt, num_iter) -const char *in; -char *out; -long salt; -int num_iter; -{ - /* variables that we want in registers, most important first */ -#if defined(pdp11) - int j; -#endif - int32_t L0, - L1, - R0, - R1, - k; - C_block *kp; - int ks_inc, - loop_count; - C_block B; - - L0 = salt; - TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */ - -#if defined(__vax__) || defined(pdp11) - salt = ~salt; /* "x &~ y" is faster than "x & y". */ -#define SALT (~salt) -#else -#define SALT salt -#endif - -#if defined(MUST_ALIGN) - B.b[0] = in[0]; - B.b[1] = in[1]; - B.b[2] = in[2]; - B.b[3] = in[3]; - B.b[4] = in[4]; - B.b[5] = in[5]; - B.b[6] = in[6]; - B.b[7] = in[7]; - LOAD(L, L0, L1, B); -#else - LOAD(L, L0, L1, *(C_block *) in); -#endif - LOADREG(R, R0, R1, L, L0, L1); - L0 &= 0x55555555L; - L1 &= 0x55555555L; - L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */ - R0 &= 0xaaaaaaaaL; - R1 = (R1 >> 1) & 0x55555555L; - L1 = R0 | R1; /* L1 is the odd-numbered input bits */ - STORE(L, L0, L1, B); - PERM3264(L, L0, L1, B.b, (C_block *) IE3264); /* even bits */ - PERM3264(R, R0, R1, B.b + 4, (C_block *) IE3264); /* odd bits */ - - if (num_iter >= 0) - { /* encryption */ - kp = &KS[0]; - ks_inc = sizeof(*kp); - } - else - { /* decryption */ - num_iter = -num_iter; - kp = &KS[KS_SIZE - 1]; - ks_inc = -(long) sizeof(*kp); - } - - while (--num_iter >= 0) - { - loop_count = 8; - do - { - -#define SPTAB(t, i) \ - (*(int32_t *)((unsigned char *)(t) + (i)*(sizeof(int32_t)/4))) -#if defined(gould) - /* use this if B.b[i] is evaluated just once ... */ -#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]); -#else -#if defined(pdp11) - /* use this if your "long" int indexing is slow */ -#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j); -#else - /* use this if "k" is allocated to a register ... */ -#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k); -#endif -#endif - -#define CRUNCH(p0, p1, q0, q1) \ - k = ((q0) ^ (q1)) & SALT; \ - B.b32.i0 = k ^ (q0) ^ kp->b32.i0; \ - B.b32.i1 = k ^ (q1) ^ kp->b32.i1; \ - kp = (C_block *)((char *)kp+ks_inc); \ - \ - DOXOR(p0, p1, 0); \ - DOXOR(p0, p1, 1); \ - DOXOR(p0, p1, 2); \ - DOXOR(p0, p1, 3); \ - DOXOR(p0, p1, 4); \ - DOXOR(p0, p1, 5); \ - DOXOR(p0, p1, 6); \ - DOXOR(p0, p1, 7); - - CRUNCH(L0, L1, R0, R1); - CRUNCH(R0, R1, L0, L1); - } while (--loop_count != 0); - kp = (C_block *) ((char *) kp - (ks_inc * KS_SIZE)); - - - /* swap L and R */ - L0 ^= R0; - L1 ^= R1; - R0 ^= L0; - R1 ^= L1; - L0 ^= R0; - L1 ^= R1; - } - - /* store the encrypted (or decrypted) result */ - L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L); - L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L); - STORE(L, L0, L1, B); - PERM6464(L, L0, L1, B.b, (C_block *) CF6464); -#if defined(MUST_ALIGN) - STORE(L, L0, L1, B); - out[0] = B.b[0]; - out[1] = B.b[1]; - out[2] = B.b[2]; - out[3] = B.b[3]; - out[4] = B.b[4]; - out[5] = B.b[5]; - out[6] = B.b[6]; - out[7] = B.b[7]; -#else - STORE(L, L0, L1, *(C_block *) out); -#endif - return (0); -} - - -/* - * Initialize various tables. This need only be done once. It could even be - * done at compile time, if the compiler were capable of that sort of thing. - */ -STATIC -init_des() -{ - int i, - j; - int32_t k; - int tableno; - static unsigned char perm[64], - tmp32[32]; /* "static" for speed */ - -/* static volatile long init_start = 0; not used */ - - /* - * table that converts chars "./0-9A-Za-z"to integers 0-63. - */ - for (i = 0; i < 64; i++) - a64toi[itoa64[i]] = i; - - /* - * PC1ROT - bit reverse, then PC1, then Rotate, then PC2. - */ - for (i = 0; i < 64; i++) - perm[i] = 0; - for (i = 0; i < 64; i++) - { - if ((k = PC2[i]) == 0) - continue; - k += Rotates[0] - 1; - if ((k % 28) < Rotates[0]) - k -= 28; - k = PC1[k]; - if (k > 0) - { - k--; - k = (k | 07) - (k & 07); - k++; - } - perm[i] = k; - } -#ifdef DEBUG - prtab("pc1tab", perm, 8); -#endif - init_perm(PC1ROT, perm, 8, 8); - - /* - * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2. - */ - for (j = 0; j < 2; j++) - { - unsigned char pc2inv[64]; - - for (i = 0; i < 64; i++) - perm[i] = pc2inv[i] = 0; - for (i = 0; i < 64; i++) - { - if ((k = PC2[i]) == 0) - continue; - pc2inv[k - 1] = i + 1; - } - for (i = 0; i < 64; i++) - { - if ((k = PC2[i]) == 0) - continue; - k += j; - if ((k % 28) <= j) - k -= 28; - perm[i] = pc2inv[k]; - } -#ifdef DEBUG - prtab("pc2tab", perm, 8); -#endif - init_perm(PC2ROT[j], perm, 8, 8); - } - - /* - * Bit reverse, then initial permutation, then expansion. - */ - for (i = 0; i < 8; i++) - { - for (j = 0; j < 8; j++) - { - k = (j < 2) ? 0 : IP[ExpandTr[i * 6 + j - 2] - 1]; - if (k > 32) - k -= 32; - else if (k > 0) - k--; - if (k > 0) - { - k--; - k = (k | 07) - (k & 07); - k++; - } - perm[i * 8 + j] = k; - } - } -#ifdef DEBUG - prtab("ietab", perm, 8); -#endif - init_perm(IE3264, perm, 4, 8); - - /* - * Compression, then final permutation, then bit reverse. - */ - for (i = 0; i < 64; i++) - { - k = IP[CIFP[i] - 1]; - if (k > 0) - { - k--; - k = (k | 07) - (k & 07); - k++; - } - perm[k - 1] = i + 1; - } -#ifdef DEBUG - prtab("cftab", perm, 8); -#endif - init_perm(CF6464, perm, 8, 8); - - /* - * SPE table - */ - for (i = 0; i < 48; i++) - perm[i] = P32Tr[ExpandTr[i] - 1]; - for (tableno = 0; tableno < 8; tableno++) - { - for (j = 0; j < 64; j++) - { - k = (((j >> 0) & 01) << 5) | - (((j >> 1) & 01) << 3) | - (((j >> 2) & 01) << 2) | - (((j >> 3) & 01) << 1) | - (((j >> 4) & 01) << 0) | - (((j >> 5) & 01) << 4); - k = S[tableno][k]; - k = (((k >> 3) & 01) << 0) | - (((k >> 2) & 01) << 1) | - (((k >> 1) & 01) << 2) | - (((k >> 0) & 01) << 3); - for (i = 0; i < 32; i++) - tmp32[i] = 0; - for (i = 0; i < 4; i++) - tmp32[4 * tableno + i] = (k >> i) & 01; - k = 0; - for (i = 24; --i >= 0;) - k = (k << 1) | tmp32[perm[i] - 1]; - TO_SIX_BIT(SPE[0][tableno][j], k); - k = 0; - for (i = 24; --i >= 0;) - k = (k << 1) | tmp32[perm[i + 24] - 1]; - TO_SIX_BIT(SPE[1][tableno][j], k); - } - } - - des_ready = 1; -} - -/* - * Initialize "perm" to represent transformation "p", which rearranges - * (perhaps with expansion and/or contraction) one packed array of bits - * (of size "chars_in" characters) into another array (of size "chars_out" - * characters). - * - * "perm" must be all-zeroes on entry to this routine. - */ -STATIC -init_perm(perm, p, chars_in, chars_out) -C_block perm[64 / CHUNKBITS][1 << CHUNKBITS]; -unsigned char p[64]; -int chars_in, - chars_out; - -{ - int i, - j, - k, - l; - - for (k = 0; k < chars_out * 8; k++) - { /* each output bit position */ - l = p[k] - 1; /* where this bit comes from */ - if (l < 0) - continue; /* output bit is always 0 */ - i = l >> LGCHUNKBITS; /* which chunk this bit comes from */ - l = 1 << (l & (CHUNKBITS - 1)); /* mask for this bit */ - for (j = 0; j < (1 << CHUNKBITS); j++) - { /* each chunk value */ - if ((j & l) != 0) - perm[i][j].b[k >> 3] |= 1 << (k & 07); - } - } -} - -/* - * "setkey" routine (for backwards compatibility) - */ -#ifdef NOT_USED -int -setkey(key) -const char *key; -{ - int i, - j, - k; - C_block keyblock; - - for (i = 0; i < 8; i++) - { - k = 0; - for (j = 0; j < 8; j++) - { - k <<= 1; - k |= (unsigned char) *key++; - } - keyblock.b[i] = k; - } - return (des_setkey((char *) keyblock.b)); -} - -/* - * "encrypt" routine (for backwards compatibility) - */ -static int -encrypt(block, flag) -char *block; -int flag; -{ - int i, - j, - k; - C_block cblock; - - for (i = 0; i < 8; i++) - { - k = 0; - for (j = 0; j < 8; j++) - { - k <<= 1; - k |= (unsigned char) *block++; - } - cblock.b[i] = k; - } - if (des_cipher((char *) &cblock, (char *) &cblock, 0L, (flag ? -1 : 1))) - return (1); - for (i = 7; i >= 0; i--) - { - k = cblock.b[i]; - for (j = 7; j >= 0; j--) - { - *--block = k & 01; - k >>= 1; - } - } - return (0); -} -#endif - -#ifdef DEBUG -STATIC -prtab(s, t, num_rows) -char *s; -unsigned char *t; -int num_rows; - -{ - int i, - j; - - (void) printf("%s:\n", s); - for (i = 0; i < num_rows; i++) - { - for (j = 0; j < 8; j++) - (void) printf("%3d", t[i * 8 + j]); - (void) printf("\n"); - } - (void) printf("\n"); -} - -#endif diff --git a/src/port/dirent.c b/src/port/dirent.c index 7d1d069647a..be26db4dc2f 100644 --- a/src/port/dirent.c +++ b/src/port/dirent.c @@ -3,7 +3,7 @@ * dirent.c * opendir/readdir/closedir for win32/msvc * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -83,7 +83,11 @@ readdir(DIR *d) d->handle = FindFirstFile(d->dirname, &fd); if (d->handle == INVALID_HANDLE_VALUE) { - errno = ENOENT; + /* If there are no files, force errno=0 (unlike mingw) */ + if (GetLastError() == ERROR_FILE_NOT_FOUND) + errno = 0; + else + _dosmaperr(GetLastError()); return NULL; } } @@ -91,13 +95,11 @@ readdir(DIR *d) { if (!FindNextFile(d->handle, &fd)) { + /* If there are no more files, force errno=0 (like mingw) */ if (GetLastError() == ERROR_NO_MORE_FILES) - { - /* No more files, force errno=0 (unlike mingw) */ errno = 0; - return NULL; - } - _dosmaperr(GetLastError()); + else + _dosmaperr(GetLastError()); return NULL; } } diff --git a/src/port/dirmod.c b/src/port/dirmod.c index 26611922db0..d7932401ef0 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -3,7 +3,7 @@ * dirmod.c * directory handling functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * This includes replacement versions of functions that work on diff --git a/src/port/dlopen.c b/src/port/dlopen.c new file mode 100644 index 00000000000..05ad85b5b33 --- /dev/null +++ b/src/port/dlopen.c @@ -0,0 +1,145 @@ +/*------------------------------------------------------------------------- + * + * dlopen.c + * dynamic loader for platforms without dlopen() + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/port/dlopen.c + * + *------------------------------------------------------------------------- + */ + +#include "c.h" + +#if defined(__hpux) + +/* System includes */ +#include +#include + +void * +dlopen(const char *file, int mode) +{ + int flags = 0; + + if (mode & RTLD_NOW) + flags |= BIND_IMMEDIATE; +#ifdef NOT_USED + if (mode & RTLD_LAZY) + flags |= BIND_DEFERRED; +#endif + + return shl_load(file, flags | BIND_VERBOSE, 0L); +} + +void * +dlsym(void *handle, const char *symbol) +{ + void *value; + + if (shl_findsym((shl_t *) & handle, symbol, TYPE_PROCEDURE, &value) == -1) + return NULL; + return value; +} + +int +dlclose(void *handle) +{ + return shl_unload((shl_t) handle); +} + +char * +dlerror(void) +{ + static char errmsg[] = "shl_load failed"; + + if (errno) + return strerror(errno); + + return errmsg; +} + +#elif defined(WIN32) + +static char last_dyn_error[512]; + +static void +set_dl_error(void) +{ + DWORD err = GetLastError(); + + if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + last_dyn_error, + sizeof(last_dyn_error) - 1, + NULL) == 0) + { + snprintf(last_dyn_error, sizeof(last_dyn_error) - 1, + "unknown error %lu", err); + } +} + +char * +dlerror(void) +{ + if (last_dyn_error[0]) + return last_dyn_error; + else + return NULL; +} + +int +dlclose(void *handle) +{ + if (!FreeLibrary((HMODULE) handle)) + { + set_dl_error(); + return 1; + } + last_dyn_error[0] = 0; + return 0; +} + +void * +dlsym(void *handle, const char *symbol) +{ + void *ptr; + + ptr = GetProcAddress((HMODULE) handle, symbol); + if (!ptr) + { + set_dl_error(); + return NULL; + } + last_dyn_error[0] = 0; + return ptr; +} + +void * +dlopen(const char *file, int mode) +{ + HMODULE h; + int prevmode; + + /* Disable popup error messages when loading DLLs */ + prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + h = LoadLibrary(file); + SetErrorMode(prevmode); + + if (!h) + { + set_dl_error(); + return NULL; + } + last_dyn_error[0] = 0; + return (void *) h; +} + +#endif diff --git a/src/port/erand48.c b/src/port/erand48.c index 716816bc361..3d5b592b979 100644 --- a/src/port/erand48.c +++ b/src/port/erand48.c @@ -2,17 +2,21 @@ * * erand48.c * - * This file supplies pg_erand48(), pg_lrand48(), and pg_srand48(), which - * are just like erand48(), lrand48(), and srand48() except that we use - * our own implementation rather than the one provided by the operating - * system. We used to test for an operating system version rather than + * This file supplies pg_erand48() and related functions, which except + * for the names are just like the POSIX-standard erand48() family. + * (We don't supply the full set though, only the ones we have found use + * for in Postgres. In particular, we do *not* implement lcong48(), so + * that there is no need for the multiplier and addend to be variable.) + * + * We used to test for an operating system version rather than * unconditionally using our own, but (1) some versions of Cygwin have a * buggy erand48() that always returns zero and (2) as of 2011, glibc's * erand48() is strangely coded to be almost-but-not-quite thread-safe, * which doesn't matter for the backend but is important for pgbench. * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * - * Copyright (c) 1993 Martin Birgmeier + * Portions Copyright (c) 1993 Martin Birgmeier * All rights reserved. * * You may redistribute unmodified or modified versions of this source @@ -33,79 +37,100 @@ #include +/* These values are specified by POSIX */ +#define RAND48_MULT UINT64CONST(0x0005deece66d) +#define RAND48_ADD UINT64CONST(0x000b) + +/* POSIX specifies 0x330e's use in srand48, but the other bits are arbitrary */ #define RAND48_SEED_0 (0x330e) #define RAND48_SEED_1 (0xabcd) #define RAND48_SEED_2 (0x1234) -#define RAND48_MULT_0 (0xe66d) -#define RAND48_MULT_1 (0xdeec) -#define RAND48_MULT_2 (0x0005) -#define RAND48_ADD (0x000b) static unsigned short _rand48_seed[3] = { RAND48_SEED_0, RAND48_SEED_1, RAND48_SEED_2 }; -static unsigned short _rand48_mult[3] = { - RAND48_MULT_0, - RAND48_MULT_1, - RAND48_MULT_2 -}; -static unsigned short _rand48_add = RAND48_ADD; -static void +/* + * Advance the 48-bit value stored in xseed[] to the next "random" number. + * + * Also returns the value of that number --- without masking it to 48 bits. + * If caller uses the result, it must mask off the bits it wants. + */ +static uint64 _dorand48(unsigned short xseed[3]) { - unsigned long accu; - unsigned short temp[2]; - - accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] + - (unsigned long) _rand48_add; - temp[0] = (unsigned short) accu; /* lower 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] + - (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0]; - temp[1] = (unsigned short) accu; /* middle 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0]; - xseed[0] = temp[0]; - xseed[1] = temp[1]; - xseed[2] = (unsigned short) accu; + /* + * We do the arithmetic in uint64; any type wider than 48 bits would work. + */ + uint64 in; + uint64 out; + + in = (uint64) xseed[2] << 32 | (uint64) xseed[1] << 16 | (uint64) xseed[0]; + + out = in * RAND48_MULT + RAND48_ADD; + + xseed[0] = out & 0xFFFF; + xseed[1] = (out >> 16) & 0xFFFF; + xseed[2] = (out >> 32) & 0xFFFF; + + return out; } +/* + * Generate a random floating-point value using caller-supplied state. + * Values are uniformly distributed over the interval [0.0, 1.0). + */ double pg_erand48(unsigned short xseed[3]) { - _dorand48(xseed); - return ldexp((double) xseed[0], -48) + - ldexp((double) xseed[1], -32) + - ldexp((double) xseed[2], -16); + uint64 x = _dorand48(xseed); + + return ldexp((double) (x & UINT64CONST(0xFFFFFFFFFFFF)), -48); } +/* + * Generate a random non-negative integral value using internal state. + * Values are uniformly distributed over the interval [0, 2^31). + */ long pg_lrand48(void) { - _dorand48(_rand48_seed); - return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1); + uint64 x = _dorand48(_rand48_seed); + + return (x >> 17) & UINT64CONST(0x7FFFFFFF); } +/* + * Generate a random signed integral value using caller-supplied state. + * Values are uniformly distributed over the interval [-2^31, 2^31). + */ long pg_jrand48(unsigned short xseed[3]) { - _dorand48(xseed); - return ((long) xseed[2] << 16) + ((long) xseed[1]); + uint64 x = _dorand48(xseed); + + return (int32) ((x >> 16) & UINT64CONST(0xFFFFFFFF)); } +/* + * Initialize the internal state using the given seed. + * + * Per POSIX, this uses only 32 bits from "seed" even if "long" is wider. + * Hence, the set of possible seed values is smaller than it could be. + * Better practice is to use caller-supplied state and initialize it with + * random bits obtained from a high-quality source of random bits. + * + * Note: POSIX specifies a function seed48() that allows all 48 bits + * of the internal state to be set, but we don't currently support that. + */ void pg_srand48(long seed) { _rand48_seed[0] = RAND48_SEED_0; _rand48_seed[1] = (unsigned short) seed; _rand48_seed[2] = (unsigned short) (seed >> 16); - _rand48_mult[0] = RAND48_MULT_0; - _rand48_mult[1] = RAND48_MULT_1; - _rand48_mult[2] = RAND48_MULT_2; - _rand48_add = RAND48_ADD; } diff --git a/src/port/explicit_bzero.c b/src/port/explicit_bzero.c new file mode 100644 index 00000000000..7e7f24ef97e --- /dev/null +++ b/src/port/explicit_bzero.c @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * explicit_bzero.c + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * src/port/explicit_bzero.c + * + *------------------------------------------------------------------------- + */ + +#include "c.h" + +#if defined(HAVE_MEMSET_S) + +void +explicit_bzero(void *buf, size_t len) +{ + (void) memset_s(buf, len, 0, len); +} + +#elif defined(WIN32) + +void +explicit_bzero(void *buf, size_t len) +{ + (void) SecureZeroMemory(buf, len); +} + +#else + +/* + * Indirect call through a volatile pointer to hopefully avoid dead-store + * optimisation eliminating the call. (Idea taken from OpenSSH.) We can't + * assume bzero() is present either, so for simplicity we define our own. + */ + +static void +bzero2(void *buf, size_t len) +{ + memset(buf, 0, len); +} + +static void (* volatile bzero_p)(void *, size_t) = bzero2; + +void +explicit_bzero(void *buf, size_t len) +{ + bzero_p(buf, len); +} + +#endif diff --git a/src/port/fls.c b/src/port/fls.c index 46dceb59d53..6b1cf373486 100644 --- a/src/port/fls.c +++ b/src/port/fls.c @@ -3,7 +3,7 @@ * fls.c * finds the last (most significant) bit that is set * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/port/fseeko.c b/src/port/fseeko.c index 38b9cbde911..3fc13b9014b 100644 --- a/src/port/fseeko.c +++ b/src/port/fseeko.c @@ -3,7 +3,7 @@ * fseeko.c * 64-bit versions of fseeko/ftello() * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c index 21f1f1b94b6..9e5829b6dd2 100644 --- a/src/port/getaddrinfo.c +++ b/src/port/getaddrinfo.c @@ -13,7 +13,7 @@ * use the Windows native routines, but if not, we use our own. * * - * Copyright (c) 2003-2018, PostgreSQL Global Development Group + * Copyright (c) 2003-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/port/getaddrinfo.c @@ -49,8 +49,8 @@ typedef void (__stdcall * freeaddrinfo_ptr_t) (struct addrinfo *ai); typedef int (__stdcall * getnameinfo_ptr_t) (const struct sockaddr *sa, int salen, - char *host, int hostlen, - char *serv, int servlen, + char *node, int nodelen, + char *service, int servicelen, int flags); /* static pointers to the native routines, so we only do the lookup once. */ @@ -387,9 +387,10 @@ getnameinfo(const struct sockaddr *sa, int salen, { if (sa->sa_family == AF_INET) { - if (inet_net_ntop(AF_INET, &((struct sockaddr_in *) sa)->sin_addr, - sa->sa_family == AF_INET ? 32 : 128, - node, nodelen) == NULL) + if (pg_inet_net_ntop(AF_INET, + &((struct sockaddr_in *) sa)->sin_addr, + sa->sa_family == AF_INET ? 32 : 128, + node, nodelen) == NULL) return EAI_MEMORY; } else @@ -405,7 +406,7 @@ getnameinfo(const struct sockaddr *sa, int salen, ret = snprintf(service, servicelen, "%d", pg_ntoh16(((struct sockaddr_in *) sa)->sin_port)); } - if (ret == -1 || ret >= servicelen) + if (ret < 0 || ret >= servicelen) return EAI_MEMORY; } diff --git a/src/port/getopt.c b/src/port/getopt.c index 10f4228d7c9..207c2836d35 100644 --- a/src/port/getopt.c +++ b/src/port/getopt.c @@ -1,7 +1,5 @@ /* src/port/getopt.c */ -/* This is used by psql under Win32 */ - /* * Copyright (c) 1987, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -40,10 +38,11 @@ static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; /* - * On some versions of Solaris, opterr and friends are defined in core libc - * rather than in a separate getopt module. Define these variables only - * if configure found they aren't there by default. (We assume that testing - * opterr is sufficient for all of these.) + * On OpenBSD and some versions of Solaris, opterr and friends are defined in + * core libc rather than in a separate getopt module. Define these variables + * only if configure found they aren't there by default; otherwise, this + * module and its callers will just use libc's variables. (We assume that + * testing opterr is sufficient for all of these.) */ #ifndef HAVE_INT_OPTERR diff --git a/src/port/getpeereid.c b/src/port/getpeereid.c index fa871ae68ff..af6c0bc9de6 100644 --- a/src/port/getpeereid.c +++ b/src/port/getpeereid.c @@ -3,7 +3,7 @@ * getpeereid.c * get peer userid for UNIX-domain socket connection * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/port/getrusage.c b/src/port/getrusage.c index 229b5bb7fe9..72c645fbbc5 100644 --- a/src/port/getrusage.c +++ b/src/port/getrusage.c @@ -3,7 +3,7 @@ * getrusage.c * get information about resource utilisation * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/inet_net_ntop.c b/src/port/inet_net_ntop.c index f27fda96ca1..b8ad69c3909 100644 --- a/src/port/inet_net_ntop.c +++ b/src/port/inet_net_ntop.c @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * src/backend/utils/adt/inet_net_ntop.c + * src/port/inet_net_ntop.c */ #if defined(LIBC_SCCS) && !defined(lint) @@ -36,7 +36,7 @@ static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 m #else /* * In a frontend build, we can't include inet.h, but we still need to have - * sensible definitions of these two constants. Note that inet_net_ntop() + * sensible definitions of these two constants. Note that pg_inet_net_ntop() * assumes that PGSQL_AF_INET is equal to AF_INET. */ #define PGSQL_AF_INET (AF_INET + 0) @@ -54,27 +54,27 @@ static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 m #endif static char *inet_net_ntop_ipv4(const u_char *src, int bits, - char *dst, size_t size); + char *dst, size_t size); static char *inet_net_ntop_ipv6(const u_char *src, int bits, - char *dst, size_t size); + char *dst, size_t size); /* * char * - * inet_net_ntop(af, src, bits, dst, size) + * pg_inet_net_ntop(af, src, bits, dst, size) * convert host/network address from network to presentation format. * "src"'s size is determined from its "af". * return: * pointer to dst, or NULL if an error occurred (check errno). * note: * 192.5.5.1/28 has a nonzero host part, which means it isn't a network - * as called for by inet_net_pton() but it can be a host address with + * as called for by pg_inet_net_pton() but it can be a host address with * an included netmask. * author: * Paul Vixie (ISC), October 1998 */ char * -inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) +pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) { /* * We need to cover both the address family constants used by the PG inet diff --git a/src/port/isinf.c b/src/port/isinf.c index 9990f9c4226..e4823d4133d 100644 --- a/src/port/isinf.c +++ b/src/port/isinf.c @@ -2,7 +2,7 @@ * * isinf.c * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,6 +22,7 @@ #if HAVE_IEEEFP_H #include #endif + int isinf(double d) { @@ -44,9 +45,9 @@ isinf(double d) #if HAVE_FP_CLASS_H #include #endif + int -isinf(x) -double x; +isinf(double x) { #if HAVE_FP_CLASS int fpclass = fp_class(x); @@ -60,7 +61,9 @@ double x; return -1; return 0; } + #elif defined(HAVE_CLASS) + int isinf(double x) { @@ -72,6 +75,7 @@ isinf(double x) return -1; return 0; } + #endif #endif diff --git a/src/port/kill.c b/src/port/kill.c index fee5abfdfab..79215b2081f 100644 --- a/src/port/kill.c +++ b/src/port/kill.c @@ -3,7 +3,7 @@ * kill.c * kill() * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * This is a replacement version of kill for Win32 which sends * signals that the backend can recognize. diff --git a/src/port/mkdtemp.c b/src/port/mkdtemp.c index e0b3ada28a5..269ebc51deb 100644 --- a/src/port/mkdtemp.c +++ b/src/port/mkdtemp.c @@ -3,7 +3,7 @@ * mkdtemp.c * create a mode-0700 temporary directory * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/port/noblock.c b/src/port/noblock.c index bd26bd5f529..73b88486717 100644 --- a/src/port/noblock.c +++ b/src/port/noblock.c @@ -3,7 +3,7 @@ * noblock.c * set a file descriptor as blocking or non-blocking * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/port/open.c b/src/port/open.c index a3ad946a60c..f37afc75121 100644 --- a/src/port/open.c +++ b/src/port/open.c @@ -4,7 +4,7 @@ * Win32 open() replacement * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/port/open.c * @@ -70,6 +70,23 @@ pgwin32_open(const char *fileName, int fileFlags,...) (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) | _O_SHORT_LIVED | O_DSYNC | O_DIRECT | (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags); +#ifndef FRONTEND + Assert(pgwin32_signal_event != NULL); /* small chance of pg_usleep() */ +#endif + +#ifdef FRONTEND + + /* + * Since PostgreSQL 12, those concurrent-safe versions of open() and + * fopen() can be used by frontends, having as side-effect to switch the + * file-translation mode from O_TEXT to O_BINARY if none is specified. + * Caller may want to enforce the binary or text mode, but if nothing is + * defined make sure that the default mode maps with what versions older + * than 12 have been doing. + */ + if ((fileFlags & O_BINARY) == 0) + fileFlags |= O_TEXT; +#endif sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; diff --git a/src/port/path.c b/src/port/path.c index 1ac1dbea4f2..710988bd243 100644 --- a/src/port/path.c +++ b/src/port/path.c @@ -3,7 +3,7 @@ * path.c * portable path handling routines * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -45,7 +45,7 @@ #endif static void make_relative_path(char *ret_path, const char *target_path, - const char *bin_path, const char *my_exec_path); + const char *bin_path, const char *my_exec_path); static void trim_directory(char *path); static void trim_trailing_separator(char *path); @@ -106,7 +106,7 @@ first_dir_separator(const char *filename) for (p = skip_drive(filename); *p; p++) if (IS_DIR_SEP(*p)) - return (char *) p; + return unconstify(char *, p); return NULL; } @@ -124,7 +124,7 @@ first_path_var_separator(const char *pathlist) /* skip_drive is not needed */ for (p = pathlist; *p; p++) if (IS_PATH_VAR_SEP(*p)) - return (char *) p; + return unconstify(char *, p); return NULL; } @@ -143,7 +143,7 @@ last_dir_separator(const char *filename) for (p = skip_drive(filename); *p; p++) if (IS_DIR_SEP(*p)) ret = p; - return (char *) ret; + return unconstify(char *, ret); } diff --git a/src/port/pg_bitutils.c b/src/port/pg_bitutils.c new file mode 100644 index 00000000000..7847e8a451c --- /dev/null +++ b/src/port/pg_bitutils.c @@ -0,0 +1,321 @@ +/*------------------------------------------------------------------------- + * + * pg_bitutils.c + * Miscellaneous functions for bit-wise operations. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/port/pg_bitutils.c + * + *------------------------------------------------------------------------- + */ +#include "c.h" + +#ifdef HAVE__GET_CPUID +#include +#endif +#ifdef HAVE__CPUID +#include +#endif + +#include "port/pg_bitutils.h" + + +/* + * Array giving the position of the left-most set bit for each possible + * byte value. We count the right-most position as the 0th bit, and the + * left-most the 7th bit. The 0th entry of the array should not be used. + * + * Note: this is not used by the functions in pg_bitutils.h when + * HAVE__BUILTIN_CLZ is defined, but we provide it anyway, so that + * extensions possibly compiled with a different compiler can use it. + */ +const uint8 pg_leftmost_one_pos[256] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +/* + * Array giving the position of the right-most set bit for each possible + * byte value. We count the right-most position as the 0th bit, and the + * left-most the 7th bit. The 0th entry of the array should not be used. + * + * Note: this is not used by the functions in pg_bitutils.h when + * HAVE__BUILTIN_CTZ is defined, but we provide it anyway, so that + * extensions possibly compiled with a different compiler can use it. + */ +const uint8 pg_rightmost_one_pos[256] = { + 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, + 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 +}; + +/* + * Array giving the number of 1-bits in each possible byte value. + * + * Note: we export this for use by functions in which explicit use + * of the popcount functions seems unlikely to be a win. + */ +const uint8 pg_number_of_ones[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +/* + * On x86_64, we can use the hardware popcount instruction, but only if + * we can verify that the CPU supports it via the cpuid instruction. + * + * Otherwise, we fall back to __builtin_popcount if the compiler has that, + * or a hand-rolled implementation if not. + */ +#ifdef HAVE_X86_64_POPCNTQ +#if defined(HAVE__GET_CPUID) || defined(HAVE__CPUID) +#define USE_POPCNT_ASM 1 +#endif +#endif + +static int pg_popcount32_slow(uint32 word); +static int pg_popcount64_slow(uint64 word); + +#ifdef USE_POPCNT_ASM +static bool pg_popcount_available(void); +static int pg_popcount32_choose(uint32 word); +static int pg_popcount64_choose(uint64 word); +static int pg_popcount32_asm(uint32 word); +static int pg_popcount64_asm(uint64 word); + +int (*pg_popcount32) (uint32 word) = pg_popcount32_choose; +int (*pg_popcount64) (uint64 word) = pg_popcount64_choose; +#else +int (*pg_popcount32) (uint32 word) = pg_popcount32_slow; +int (*pg_popcount64) (uint64 word) = pg_popcount64_slow; +#endif /* USE_POPCNT_ASM */ + +#ifdef USE_POPCNT_ASM + +/* + * Return true if CPUID indicates that the POPCNT instruction is available. + */ +static bool +pg_popcount_available(void) +{ + unsigned int exx[4] = {0, 0, 0, 0}; + +#if defined(HAVE__GET_CPUID) + __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); +#elif defined(HAVE__CPUID) + __cpuid(exx, 1); +#else +#error cpuid instruction not available +#endif + + return (exx[2] & (1 << 23)) != 0; /* POPCNT */ +} + +/* + * These functions get called on the first call to pg_popcount32 etc. + * They detect whether we can use the asm implementations, and replace + * the function pointers so that subsequent calls are routed directly to + * the chosen implementation. + */ +static int +pg_popcount32_choose(uint32 word) +{ + if (pg_popcount_available()) + { + pg_popcount32 = pg_popcount32_asm; + pg_popcount64 = pg_popcount64_asm; + } + else + { + pg_popcount32 = pg_popcount32_slow; + pg_popcount64 = pg_popcount64_slow; + } + + return pg_popcount32(word); +} + +static int +pg_popcount64_choose(uint64 word) +{ + if (pg_popcount_available()) + { + pg_popcount32 = pg_popcount32_asm; + pg_popcount64 = pg_popcount64_asm; + } + else + { + pg_popcount32 = pg_popcount32_slow; + pg_popcount64 = pg_popcount64_slow; + } + + return pg_popcount64(word); +} + +/* + * pg_popcount32_asm + * Return the number of 1 bits set in word + */ +static int +pg_popcount32_asm(uint32 word) +{ + uint32 res; + +__asm__ __volatile__(" popcntl %1,%0\n":"=q"(res):"rm"(word):"cc"); + return (int) res; +} + +/* + * pg_popcount64_asm + * Return the number of 1 bits set in word + */ +static int +pg_popcount64_asm(uint64 word) +{ + uint64 res; + +__asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc"); + return (int) res; +} + +#endif /* USE_POPCNT_ASM */ + + +/* + * pg_popcount32_slow + * Return the number of 1 bits set in word + */ +static int +pg_popcount32_slow(uint32 word) +{ +#ifdef HAVE__BUILTIN_POPCOUNT + return __builtin_popcount(word); +#else /* !HAVE__BUILTIN_POPCOUNT */ + int result = 0; + + while (word != 0) + { + result += pg_number_of_ones[word & 255]; + word >>= 8; + } + + return result; +#endif /* HAVE__BUILTIN_POPCOUNT */ +} + +/* + * pg_popcount64_slow + * Return the number of 1 bits set in word + */ +static int +pg_popcount64_slow(uint64 word) +{ +#ifdef HAVE__BUILTIN_POPCOUNT +#if defined(HAVE_LONG_INT_64) + return __builtin_popcountl(word); +#elif defined(HAVE_LONG_LONG_INT_64) + return __builtin_popcountll(word); +#else +#error must have a working 64-bit integer datatype +#endif +#else /* !HAVE__BUILTIN_POPCOUNT */ + int result = 0; + + while (word != 0) + { + result += pg_number_of_ones[word & 255]; + word >>= 8; + } + + return result; +#endif /* HAVE__BUILTIN_POPCOUNT */ +} + + +/* + * pg_popcount + * Returns the number of 1-bits in buf + */ +uint64 +pg_popcount(const char *buf, int bytes) +{ + uint64 popcnt = 0; + +#if SIZEOF_VOID_P >= 8 + /* Process in 64-bit chunks if the buffer is aligned. */ + if (buf == (const char *) TYPEALIGN(8, buf)) + { + const uint64 *words = (const uint64 *) buf; + + while (bytes >= 8) + { + popcnt += pg_popcount64(*words++); + bytes -= 8; + } + + buf = (const char *) words; + } +#else + /* Process in 32-bit chunks if the buffer is aligned. */ + if (buf == (const char *) TYPEALIGN(4, buf)) + { + const uint32 *words = (const uint32 *) buf; + + while (bytes >= 4) + { + popcnt += pg_popcount32(*words++); + bytes -= 4; + } + + buf = (const char *) words; + } +#endif + + /* Process any remaining bytes */ + while (bytes--) + popcnt += pg_number_of_ones[(unsigned char) *buf++]; + + return popcnt; +} diff --git a/src/port/pg_crc32c_armv8.c b/src/port/pg_crc32c_armv8.c index b35b0f758c5..ebe449ec8c6 100644 --- a/src/port/pg_crc32c_armv8.c +++ b/src/port/pg_crc32c_armv8.c @@ -3,7 +3,7 @@ * pg_crc32c_armv8.c * Compute CRC-32C checksum using ARMv8 CRC Extension instructions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -29,17 +29,20 @@ pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len) * significantly faster. Process leading bytes so that the loop below * starts with a pointer aligned to eight bytes. */ - if (!PointerIsAligned(p, uint16) && p + 1 <= pend) + if (!PointerIsAligned(p, uint16) && + p + 1 <= pend) { crc = __crc32cb(crc, *p); p += 1; } - if (!PointerIsAligned(p, uint32) && p + 2 <= pend) + if (!PointerIsAligned(p, uint32) && + p + 2 <= pend) { crc = __crc32ch(crc, *(uint16 *) p); p += 2; } - if (!PointerIsAligned(p, uint64) && p + 4 <= pend) + if (!PointerIsAligned(p, uint64) && + p + 4 <= pend) { crc = __crc32cw(crc, *(uint32 *) p); p += 4; diff --git a/src/port/pg_crc32c_armv8_choose.c b/src/port/pg_crc32c_armv8_choose.c index f21a8243e9a..9f6217b6736 100644 --- a/src/port/pg_crc32c_armv8_choose.c +++ b/src/port/pg_crc32c_armv8_choose.c @@ -8,11 +8,7 @@ * computation. Otherwise, fall back to the pure software implementation * (slicing-by-8). * - * XXX: The glibc-specific getauxval() function, with the HWCAP_CRC32 - * flag, is used to determine if the CRC Extension is available on the - * current platform. Is there a more portable way to determine that? - * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -22,19 +18,63 @@ *------------------------------------------------------------------------- */ -#include "c.h" +#ifndef FRONTEND +#include "postgres.h" +#else +#include "postgres_fe.h" +#endif -#include -#include +#include +#include #include "port/pg_crc32c.h" + +static sigjmp_buf illegal_instruction_jump; + +/* + * Probe by trying to execute pg_comp_crc32c_armv8(). If the instruction + * isn't available, we expect to get SIGILL, which we can trap. + */ +static void +illegal_instruction_handler(SIGNAL_ARGS) +{ + siglongjmp(illegal_instruction_jump, 1); +} + static bool pg_crc32c_armv8_available(void) { - unsigned long auxv = getauxval(AT_HWCAP); + uint64 data = 42; + int result; + + /* + * Be careful not to do anything that might throw an error while we have + * the SIGILL handler set to a nonstandard value. + */ + pqsignal(SIGILL, illegal_instruction_handler); + if (sigsetjmp(illegal_instruction_jump, 1) == 0) + { + /* Rather than hard-wiring an expected result, compare to SB8 code */ + result = (pg_comp_crc32c_armv8(0, &data, sizeof(data)) == + pg_comp_crc32c_sb8(0, &data, sizeof(data))); + } + else + { + /* We got the SIGILL trap */ + result = -1; + } + pqsignal(SIGILL, SIG_DFL); + +#ifndef FRONTEND + /* We don't expect this case, so complain loudly */ + if (result == 0) + elog(ERROR, "crc32 hardware and software results disagree"); + + elog(DEBUG1, "using armv8 crc32 hardware = %d", (result > 0)); +#endif - return (auxv & HWCAP_CRC32) != 0; + return (result > 0); } /* diff --git a/src/port/pg_crc32c_sb8.c b/src/port/pg_crc32c_sb8.c index 5205ba9cdcc..b0c731254ce 100644 --- a/src/port/pg_crc32c_sb8.c +++ b/src/port/pg_crc32c_sb8.c @@ -8,7 +8,7 @@ * Generation", IEEE Transactions on Computers, vol.57, no. 11, * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85 * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/pg_crc32c_sse42.c b/src/port/pg_crc32c_sse42.c index b9def7e2ea5..ef56cff4e12 100644 --- a/src/port/pg_crc32c_sse42.c +++ b/src/port/pg_crc32c_sse42.c @@ -3,7 +3,7 @@ * pg_crc32c_sse42.c * Compute CRC-32C checksum using Intel SSE 4.2 instructions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/pg_crc32c_sse42_choose.c b/src/port/pg_crc32c_sse42_choose.c index c2d1242d913..51ebdbfd7a3 100644 --- a/src/port/pg_crc32c_sse42_choose.c +++ b/src/port/pg_crc32c_sse42_choose.c @@ -8,7 +8,7 @@ * computation. Otherwise, fall back to the pure software implementation * (slicing-by-8). * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/pg_strong_random.c b/src/port/pg_strong_random.c index bc7a8aacb93..6be5874cbfb 100644 --- a/src/port/pg_strong_random.c +++ b/src/port/pg_strong_random.c @@ -6,7 +6,11 @@ * Our definition of "strong" is that it's suitable for generating random * salts and query cancellation keys, during authentication. * - * Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Note: this code is run quite early in postmaster and backend startup; + * therefore, even when built for backend, it cannot rely on backend + * infrastructure such as elog() or palloc(). + * + * Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/port/pg_strong_random.c @@ -14,11 +18,7 @@ *------------------------------------------------------------------------- */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif +#include "c.h" #include #include @@ -27,11 +27,11 @@ #ifdef USE_OPENSSL #include #endif -#ifdef WIN32 +#ifdef USE_WIN32_RANDOM #include #endif -#ifdef WIN32 +#ifdef USE_WIN32_RANDOM /* * Cache a global crypto provider that only gets freed when the process * exits, in case we need random numbers more than once. @@ -44,7 +44,7 @@ static HCRYPTPROV hProvider = 0; * Read (random) bytes from a file. */ static bool -random_from_file(char *filename, void *buf, size_t len) +random_from_file(const char *filename, void *buf, size_t len) { int f; char *p = buf; @@ -103,6 +103,35 @@ pg_strong_random(void *buf, size_t len) * When built with OpenSSL, use OpenSSL's RAND_bytes function. */ #if defined(USE_OPENSSL_RANDOM) + int i; + + /* + * Check that OpenSSL's CSPRNG has been sufficiently seeded, and if not + * add more seed data using RAND_poll(). With some older versions of + * OpenSSL, it may be necessary to call RAND_poll() a number of times. + */ +#define NUM_RAND_POLL_RETRIES 8 + + for (i = 0; i < NUM_RAND_POLL_RETRIES; i++) + { + if (RAND_status() == 1) + { + /* The CSPRNG is sufficiently seeded */ + break; + } + + if (RAND_poll() == 0) + { + /* + * RAND_poll() failed to generate any seed data, which means that + * RAND_bytes() will probably fail. For now, just fall through + * and let that happen. XXX: maybe we could seed it some other + * way. + */ + break; + } + } + if (RAND_bytes(buf, len) == 1) return true; return false; diff --git a/src/port/pgcheckdir.c b/src/port/pgcheckdir.c index b5b999b3858..7acc1107bb1 100644 --- a/src/port/pgcheckdir.c +++ b/src/port/pgcheckdir.c @@ -5,7 +5,7 @@ * A simple subroutine to check whether a directory exists and is empty or not. * Useful in both initdb and the backend. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- diff --git a/src/port/pgsleep.c b/src/port/pgsleep.c index 48536f4b7a2..84e1c3049ac 100644 --- a/src/port/pgsleep.c +++ b/src/port/pgsleep.c @@ -4,7 +4,7 @@ * Portable delay handling. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/port/pgsleep.c * diff --git a/src/port/pgstrcasecmp.c b/src/port/pgstrcasecmp.c index 3aaea305c0c..b6c8592fd75 100644 --- a/src/port/pgstrcasecmp.c +++ b/src/port/pgstrcasecmp.c @@ -18,7 +18,7 @@ * C library thinks the locale is. * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/port/pgstrcasecmp.c * diff --git a/src/port/pgstrsignal.c b/src/port/pgstrsignal.c new file mode 100644 index 00000000000..93c6ef97ecf --- /dev/null +++ b/src/port/pgstrsignal.c @@ -0,0 +1,64 @@ +/*------------------------------------------------------------------------- + * + * pgstrsignal.c + * Identify a Unix signal number + * + * On platforms compliant with modern POSIX, this just wraps strsignal(3). + * Elsewhere, we do the best we can. + * + * This file is not currently built in MSVC builds, since it's useless + * on non-Unix platforms. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/port/pgstrsignal.c + * + *------------------------------------------------------------------------- + */ + +#include "c.h" + + +/* + * pg_strsignal + * + * Return a string identifying the given Unix signal number. + * + * The result is declared "const char *" because callers should not + * modify the string. Note, however, that POSIX does not promise that + * the string will remain valid across later calls to strsignal(). + * + * This version guarantees to return a non-NULL pointer, although + * some platforms' versions of strsignal() reputedly do not. + * + * Note that the fallback cases just return constant strings such as + * "unrecognized signal". Project style is for callers to print the + * numeric signal value along with the result of this function, so + * there's no need to work harder than that. + */ +const char * +pg_strsignal(int signum) +{ + const char *result; + + /* + * If we have strsignal(3), use that --- but check its result for NULL. + */ +#ifdef HAVE_STRSIGNAL + result = strsignal(signum); + if (result == NULL) + result = "unrecognized signal"; +#else + + /* + * We used to have code here to try to use sys_siglist[] if available. + * However, it seems that all platforms with sys_siglist[] have also had + * strsignal() for many years now, so that was just a waste of code. + */ + result = "(signal names not available on this platform)"; +#endif + + return result; +} diff --git a/src/port/pqsignal.c b/src/port/pqsignal.c index 5d8d5042b0f..ecb9ca261f5 100644 --- a/src/port/pqsignal.c +++ b/src/port/pqsignal.c @@ -4,7 +4,7 @@ * reliable BSD-style signal(2) routine stolen from RWW who stole it * from Stevens... * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/pread.c b/src/port/pread.c new file mode 100644 index 00000000000..a84859e8126 --- /dev/null +++ b/src/port/pread.c @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * pread.c + * Implementation of pread(2) for platforms that lack one. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/port/pread.c + * + * Note that this implementation changes the current file position, unlike + * the POSIX function, so we use the name pg_pread(). + * + *------------------------------------------------------------------------- + */ + + +#include "postgres.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +ssize_t +pg_pread(int fd, void *buf, size_t size, off_t offset) +{ +#ifdef WIN32 + OVERLAPPED overlapped = {0}; + HANDLE handle; + DWORD result; + + handle = (HANDLE) _get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + overlapped.Offset = offset; + if (!ReadFile(handle, buf, size, &result, &overlapped)) + { + _dosmaperr(GetLastError()); + return -1; + } + + return result; +#else + if (lseek(fd, offset, SEEK_SET) < 0) + return -1; + + return read(fd, buf, size); +#endif +} diff --git a/src/port/pwrite.c b/src/port/pwrite.c new file mode 100644 index 00000000000..a44e9912772 --- /dev/null +++ b/src/port/pwrite.c @@ -0,0 +1,55 @@ +/*------------------------------------------------------------------------- + * + * pwrite.c + * Implementation of pwrite(2) for platforms that lack one. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/port/pwrite.c + * + * Note that this implementation changes the current file position, unlike + * the POSIX function, so we use the name pg_pwrite(). + * + *------------------------------------------------------------------------- + */ + + +#include "postgres.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +ssize_t +pg_pwrite(int fd, const void *buf, size_t size, off_t offset) +{ +#ifdef WIN32 + OVERLAPPED overlapped = {0}; + HANDLE handle; + DWORD result; + + handle = (HANDLE) _get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + overlapped.Offset = offset; + if (!WriteFile(handle, buf, size, &result, &overlapped)) + { + _dosmaperr(GetLastError()); + return -1; + } + + return result; +#else + if (lseek(fd, offset, SEEK_SET) < 0) + return -1; + + return write(fd, buf, size); +#endif +} diff --git a/src/port/qsort.c b/src/port/qsort.c index 1a8ee08c8be..409f69a128b 100644 --- a/src/port/qsort.c +++ b/src/port/qsort.c @@ -48,7 +48,7 @@ static char *med3(char *a, char *b, char *c, - int (*cmp) (const void *, const void *)); + int (*cmp) (const void *, const void *)); static void swapfunc(char *, char *, size_t, int); /* diff --git a/src/port/qsort_arg.c b/src/port/qsort_arg.c index 24acd2cd4e4..a2194b0fb18 100644 --- a/src/port/qsort_arg.c +++ b/src/port/qsort_arg.c @@ -48,7 +48,7 @@ static char *med3(char *a, char *b, char *c, - qsort_arg_comparator cmp, void *arg); + qsort_arg_comparator cmp, void *arg); static void swapfunc(char *, char *, size_t, int); /* diff --git a/src/port/quotes.c b/src/port/quotes.c index 29770c7a00e..ce60f81c6cc 100644 --- a/src/port/quotes.c +++ b/src/port/quotes.c @@ -3,7 +3,7 @@ * quotes.c * string quoting and escaping functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -19,7 +19,7 @@ * Escape (by doubling) any single quotes or backslashes in given string * * Note: this is used to process postgresql.conf entries and to quote - * string literals in pg_basebackup for creating recovery.conf. + * string literals in pg_basebackup for writing the recovery configuration. * Since postgresql.conf strings are defined to treat backslashes as escapes, * we have to double backslashes here. * diff --git a/src/port/random.c b/src/port/random.c index 3996225c92d..034c33f06ee 100644 --- a/src/port/random.c +++ b/src/port/random.c @@ -3,7 +3,7 @@ * random.c * random() wrapper * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/rint.c b/src/port/rint.c index d27fdfa6b4a..d59d9ab7743 100644 --- a/src/port/rint.c +++ b/src/port/rint.c @@ -12,7 +12,6 @@ */ #include "c.h" -#include #include /* diff --git a/src/port/snprintf.c b/src/port/snprintf.c index 83584259802..8fd997553eb 100644 --- a/src/port/snprintf.c +++ b/src/port/snprintf.c @@ -2,6 +2,7 @@ * Copyright (c) 1983, 1995, 1996 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,28 +33,23 @@ #include "c.h" -#include -#ifdef _MSC_VER -#include /* for _isnan */ -#endif -#include #include -#ifndef WIN32 -#include -#endif -#include -#ifndef NL_ARGMAX -#define NL_ARGMAX 16 -#endif +/* + * We used to use the platform's NL_ARGMAX here, but that's a bad idea, + * first because the point of this module is to remove platform dependencies + * not perpetuate them, and second because some platforms use ridiculously + * large values, leading to excessive stack consumption in dopr(). + */ +#define PG_NL_ARGMAX 31 /* * SNPRINTF, VSNPRINTF and friends * * These versions have been grabbed off the net. They have been - * cleaned up to compile properly and support for most of the Single Unix - * Specification has been added. Remaining unimplemented features are: + * cleaned up to compile properly and support for most of the C99 + * specification has been added. Remaining unimplemented features are: * * 1. No locale support: the radix character is always '.' and the ' * (single quote) format flag is ignored. @@ -66,26 +62,33 @@ * * 5. Space and '#' flags are not implemented. * + * In addition, we support some extensions over C99: + * + * 1. Argument order control through "%n$" and "*n$", as required by POSIX. + * + * 2. "%m" expands to the value of strerror(errno), where errno is the + * value that variable had at the start of the call. This is a glibc + * extension, but a very useful one. + * * - * The result values of these functions are not the same across different - * platforms. This implementation is compatible with the Single Unix Spec: + * Historically the result values of sprintf/snprintf varied across platforms. + * This implementation now follows the C99 standard: * - * 1. -1 is returned only if processing is abandoned due to an invalid - * parameter, such as incorrect format string. (Although not required by - * the spec, this happens only when no characters have yet been transmitted - * to the destination.) + * 1. -1 is returned if an error is detected in the format string, or if + * a write to the target stream fails (as reported by fwrite). Note that + * overrunning snprintf's target buffer is *not* an error. * - * 2. For snprintf and sprintf, 0 is returned if str == NULL or count == 0; - * no data has been stored. + * 2. For successful writes to streams, the actual number of bytes written + * to the stream is returned. * - * 3. Otherwise, the number of bytes actually transmitted to the destination - * is returned (excluding the trailing '\0' for snprintf and sprintf). + * 3. For successful sprintf/snprintf, the number of bytes that would have + * been written to an infinite-size buffer (excluding the trailing '\0') + * is returned. snprintf will truncate its output to fit in the buffer + * (ensuring a trailing '\0' unless count == 0), but this is not reflected + * in the function result. * - * For snprintf with nonzero count, the result cannot be more than count-1 - * (a trailing '\0' is always stored); it is not possible to distinguish - * buffer overrun from exact fit. This is unlike some implementations that - * return the number of bytes that would have been needed for the complete - * result string. + * snprintf buffer overrun can be detected by checking for function result + * greater than or equal to the supplied count. */ /************************************************************** @@ -99,20 +102,34 @@ /* Prevent recursion */ #undef vsnprintf #undef snprintf +#undef vsprintf #undef sprintf #undef vfprintf #undef fprintf +#undef vprintf #undef printf -/* Info about where the formatted output is going */ +/* + * Info about where the formatted output is going. + * + * dopr and subroutines will not write at/past bufend, but snprintf + * reserves one byte, ensuring it may place the trailing '\0' there. + * + * In snprintf, we use nchars to count the number of bytes dropped on the + * floor due to buffer overrun. The correct result of snprintf is thus + * (bufptr - bufstart) + nchars. (This isn't as inconsistent as it might + * seem: nchars is the number of emitted bytes that are not in the buffer now, + * either because we sent them to the stream or because we couldn't fit them + * into the buffer to begin with.) + */ typedef struct { char *bufptr; /* next buffer output position */ char *bufstart; /* first buffer element */ - char *bufend; /* last buffer element, or NULL */ + char *bufend; /* last+1 buffer element, or NULL */ /* bufend == NULL is for sprintf, where we assume buf is big enough */ FILE *stream; /* eventual output destination, or NULL */ - int nchars; /* # chars already sent to stream */ + int nchars; /* # chars sent to stream, or dropped */ bool failed; /* call is a failure; errno is set */ } PrintfTarget; @@ -136,7 +153,7 @@ typedef union { int i; long l; - int64 ll; + long long ll; double d; char *cptr; } PrintfArgValue; @@ -146,21 +163,39 @@ static void flushbuffer(PrintfTarget *target); static void dopr(PrintfTarget *target, const char *format, va_list args); +/* + * Externally visible entry points. + * + * All of these are just wrappers around dopr(). Note it's essential that + * they not change the value of "errno" before reaching dopr(). + */ + int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) { PrintfTarget target; + char onebyte[1]; - if (str == NULL || count == 0) - return 0; + /* + * C99 allows the case str == NULL when count == 0. Rather than + * special-casing this situation further down, we substitute a one-byte + * local buffer. Callers cannot tell, since the function result doesn't + * depend on count. + */ + if (count == 0) + { + str = onebyte; + count = 1; + } target.bufstart = target.bufptr = str; target.bufend = str + count - 1; target.stream = NULL; - /* target.nchars is unused in this case */ + target.nchars = 0; target.failed = false; dopr(&target, fmt, args); *(target.bufptr) = '\0'; - return target.failed ? -1 : (target.bufptr - target.bufstart); + return target.failed ? -1 : (target.bufptr - target.bufstart + + target.nchars); } int @@ -175,21 +210,20 @@ pg_snprintf(char *str, size_t count, const char *fmt,...) return len; } -static int +int pg_vsprintf(char *str, const char *fmt, va_list args) { PrintfTarget target; - if (str == NULL) - return 0; target.bufstart = target.bufptr = str; target.bufend = NULL; target.stream = NULL; - /* target.nchars is unused in this case */ + target.nchars = 0; /* not really used in this case */ target.failed = false; dopr(&target, fmt, args); *(target.bufptr) = '\0'; - return target.failed ? -1 : (target.bufptr - target.bufstart); + return target.failed ? -1 : (target.bufptr - target.bufstart + + target.nchars); } int @@ -216,7 +250,7 @@ pg_vfprintf(FILE *stream, const char *fmt, va_list args) return -1; } target.bufstart = target.bufptr = buffer; - target.bufend = buffer + sizeof(buffer) - 1; + target.bufend = buffer + sizeof(buffer); /* use the whole buffer */ target.stream = stream; target.nchars = 0; target.failed = false; @@ -238,6 +272,12 @@ pg_fprintf(FILE *stream, const char *fmt,...) return len; } +int +pg_vprintf(const char *fmt, va_list args) +{ + return pg_vfprintf(stdout, fmt, args); +} + int pg_printf(const char *fmt,...) { @@ -259,6 +299,10 @@ flushbuffer(PrintfTarget *target) { size_t nc = target->bufptr - target->bufstart; + /* + * Don't write anything if we already failed; this is to ensure we + * preserve the original failure's errno. + */ if (!target->failed && nc > 0) { size_t written; @@ -272,35 +316,69 @@ flushbuffer(PrintfTarget *target) } -static void fmtstr(char *value, int leftjust, int minlen, int maxwidth, - int pointflag, PrintfTarget *target); +static bool find_arguments(const char *format, va_list args, + PrintfArgValue *argvalues); +static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth, + int pointflag, PrintfTarget *target); static void fmtptr(void *value, PrintfTarget *target); -static void fmtint(int64 value, char type, int forcesign, - int leftjust, int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target); +static void fmtint(long long value, char type, int forcesign, + int leftjust, int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target); static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target); static void fmtfloat(double value, char type, int forcesign, - int leftjust, int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target); + int leftjust, int minlen, int zpad, int precision, int pointflag, + PrintfTarget *target); static void dostr(const char *str, int slen, PrintfTarget *target); static void dopr_outch(int c, PrintfTarget *target); +static void dopr_outchmulti(int c, int slen, PrintfTarget *target); static int adjust_sign(int is_negative, int forcesign, int *signvalue); -static void adjust_padlen(int minlen, int vallen, int leftjust, int *padlen); -static void leading_pad(int zpad, int *signvalue, int *padlen, - PrintfTarget *target); -static void trailing_pad(int *padlen, PrintfTarget *target); +static int compute_padlen(int minlen, int vallen, int leftjust); +static void leading_pad(int zpad, int signvalue, int *padlen, + PrintfTarget *target); +static void trailing_pad(int padlen, PrintfTarget *target); + +/* + * If strchrnul exists (it's a glibc-ism), it's a good bit faster than the + * equivalent manual loop. If it doesn't exist, provide a replacement. + * + * Note: glibc declares this as returning "char *", but that would require + * casting away const internally, so we don't follow that detail. + */ +#ifndef HAVE_STRCHRNUL + +static inline const char * +strchrnul(const char *s, int c) +{ + while (*s != '\0' && *s != c) + s++; + return s; +} + +#else + +/* + * glibc's declares strchrnul only if _GNU_SOURCE is defined. + * While we typically use that on glibc platforms, configure will set + * HAVE_STRCHRNUL whether it's used or not. Fill in the missing declaration + * so that this file will compile cleanly with or without _GNU_SOURCE. + */ +#ifndef _GNU_SOURCE +extern char *strchrnul(const char *s, int c); +#endif + +#endif /* HAVE_STRCHRNUL */ /* - * dopr(): poor man's version of doprintf + * dopr(): the guts of *printf for all cases. */ static void dopr(PrintfTarget *target, const char *format, va_list args) { - const char *format_start = format; + int save_errno = errno; + const char *first_pct = NULL; int ch; bool have_dollar; - bool have_non_dollar; bool have_star; bool afterstar; int accum; @@ -312,233 +390,68 @@ dopr(PrintfTarget *target, const char *format, va_list args) int precision; int zpad; int forcesign; - int last_dollar; int fmtpos; int cvalue; - int64 numvalue; + long long numvalue; double fvalue; char *strvalue; - int i; - PrintfArgType argtypes[NL_ARGMAX + 1]; - PrintfArgValue argvalues[NL_ARGMAX + 1]; + PrintfArgValue argvalues[PG_NL_ARGMAX + 1]; /* - * Parse the format string to determine whether there are %n$ format - * specs, and identify the types and order of the format parameters. + * Initially, we suppose the format string does not use %n$. The first + * time we come to a conversion spec that has that, we'll call + * find_arguments() to check for consistent use of %n$ and fill the + * argvalues array with the argument values in the correct order. */ - have_dollar = have_non_dollar = false; - last_dollar = 0; - MemSet(argtypes, 0, sizeof(argtypes)); + have_dollar = false; - while ((ch = *format++) != '\0') + while (*format != '\0') { - if (ch != '%') - continue; - longflag = longlongflag = pointflag = 0; - fmtpos = accum = 0; - afterstar = false; -nextch1: - ch = *format++; - if (ch == '\0') - break; /* illegal, but we don't complain */ - switch (ch) + /* Locate next conversion specifier */ + if (*format != '%') { - case '-': - case '+': - goto nextch1; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - accum = accum * 10 + (ch - '0'); - goto nextch1; - case '.': - pointflag = 1; - accum = 0; - goto nextch1; - case '*': - if (afterstar) - have_non_dollar = true; /* multiple stars */ - afterstar = true; - accum = 0; - goto nextch1; - case '$': - have_dollar = true; - if (accum <= 0 || accum > NL_ARGMAX) - goto bad_format; - if (afterstar) - { - if (argtypes[accum] && - argtypes[accum] != ATYPE_INT) - goto bad_format; - argtypes[accum] = ATYPE_INT; - last_dollar = Max(last_dollar, accum); - afterstar = false; - } - else - fmtpos = accum; - accum = 0; - goto nextch1; - case 'l': - if (longflag) - longlongflag = 1; - else - longflag = 1; - goto nextch1; - case 'z': -#if SIZEOF_SIZE_T == 8 -#ifdef HAVE_LONG_INT_64 - longflag = 1; -#elif defined(HAVE_LONG_LONG_INT_64) - longlongflag = 1; -#else -#error "Don't know how to print 64bit integers" -#endif -#else - /* assume size_t is same size as int */ -#endif - goto nextch1; - case 'h': - case '\'': - /* ignore these */ - goto nextch1; - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - if (fmtpos) - { - PrintfArgType atype; + /* Scan to next '%' or end of string */ + const char *next_pct = strchrnul(format + 1, '%'); - if (longlongflag) - atype = ATYPE_LONGLONG; - else if (longflag) - atype = ATYPE_LONG; - else - atype = ATYPE_INT; - if (argtypes[fmtpos] && - argtypes[fmtpos] != atype) - goto bad_format; - argtypes[fmtpos] = atype; - last_dollar = Max(last_dollar, fmtpos); - } - else - have_non_dollar = true; - break; - case 'c': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_INT) - goto bad_format; - argtypes[fmtpos] = ATYPE_INT; - last_dollar = Max(last_dollar, fmtpos); - } - else - have_non_dollar = true; - break; - case 's': - case 'p': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_CHARPTR) - goto bad_format; - argtypes[fmtpos] = ATYPE_CHARPTR; - last_dollar = Max(last_dollar, fmtpos); - } - else - have_non_dollar = true; + /* Dump literal data we just scanned over */ + dostr(format, next_pct - format, target); + if (target->failed) break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_DOUBLE) - goto bad_format; - argtypes[fmtpos] = ATYPE_DOUBLE; - last_dollar = Max(last_dollar, fmtpos); - } - else - have_non_dollar = true; - break; - case '%': + + if (*next_pct == '\0') break; + format = next_pct; } /* - * If we finish the spec with afterstar still set, there's a - * non-dollar star in there. + * Remember start of first conversion spec; if we find %n$, then it's + * sufficient for find_arguments() to start here, without rescanning + * earlier literal text. */ - if (afterstar) - have_non_dollar = true; - } + if (first_pct == NULL) + first_pct = format; - /* Per spec, you use either all dollar or all not. */ - if (have_dollar && have_non_dollar) - goto bad_format; + /* Process conversion spec starting at *format */ + format++; - /* - * In dollar mode, collect the arguments in physical order. - */ - for (i = 1; i <= last_dollar; i++) - { - switch (argtypes[i]) + /* Fast path for conversion spec that is exactly %s */ + if (*format == 's') { - case ATYPE_NONE: - goto bad_format; - case ATYPE_INT: - argvalues[i].i = va_arg(args, int); - break; - case ATYPE_LONG: - argvalues[i].l = va_arg(args, long); - break; - case ATYPE_LONGLONG: - argvalues[i].ll = va_arg(args, int64); - break; - case ATYPE_DOUBLE: - argvalues[i].d = va_arg(args, double); - break; - case ATYPE_CHARPTR: - argvalues[i].cptr = va_arg(args, char *); + format++; + strvalue = va_arg(args, char *); + Assert(strvalue != NULL); + dostr(strvalue, strlen(strvalue), target); + if (target->failed) break; - } - } - - /* - * At last we can parse the format for real. - */ - format = format_start; - while ((ch = *format++) != '\0') - { - if (target->failed) - break; - - if (ch != '%') - { - dopr_outch(ch, target); continue; } + fieldwidth = precision = zpad = leftjust = forcesign = 0; longflag = longlongflag = pointflag = 0; fmtpos = accum = 0; have_star = afterstar = false; nextch2: ch = *format++; - if (ch == '\0') - break; /* illegal, but we don't complain */ switch (ch) { case '-': @@ -574,7 +487,11 @@ dopr(PrintfTarget *target, const char *format, va_list args) case '*': if (have_dollar) { - /* process value after reading n$ */ + /* + * We'll process value after reading n$. Note it's OK to + * assume have_dollar is set correctly, because in a valid + * format string the initial % must have had n$ if * does. + */ afterstar = true; } else @@ -605,6 +522,14 @@ dopr(PrintfTarget *target, const char *format, va_list args) accum = 0; goto nextch2; case '$': + /* First dollar sign? */ + if (!have_dollar) + { + /* Yup, so examine all conversion specs in format */ + if (!find_arguments(first_pct, args, argvalues)) + goto bad_format; + have_dollar = true; + } if (afterstar) { /* fetch and process star value */ @@ -678,7 +603,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) else { if (longlongflag) - numvalue = va_arg(args, int64); + numvalue = va_arg(args, long long); else if (longflag) numvalue = va_arg(args, long); else @@ -701,7 +626,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) if (have_dollar) { if (longlongflag) - numvalue = (uint64) argvalues[fmtpos].ll; + numvalue = (unsigned long long) argvalues[fmtpos].ll; else if (longflag) numvalue = (unsigned long) argvalues[fmtpos].l; else @@ -710,7 +635,7 @@ dopr(PrintfTarget *target, const char *format, va_list args) else { if (longlongflag) - numvalue = (uint64) va_arg(args, int64); + numvalue = (unsigned long long) va_arg(args, long long); else if (longflag) numvalue = (unsigned long) va_arg(args, long); else @@ -779,10 +704,30 @@ dopr(PrintfTarget *target, const char *format, va_list args) precision, pointflag, target); break; + case 'm': + { + char errbuf[PG_STRERROR_R_BUFLEN]; + const char *errm = strerror_r(save_errno, + errbuf, sizeof(errbuf)); + + dostr(errm, strlen(errm), target); + } + break; case '%': dopr_outch('%', target); break; + default: + + /* + * Anything else --- in particular, '\0' indicating end of + * format string --- is bogus. + */ + goto bad_format; } + + /* Check for failure after each conversion spec */ + if (target->failed) + break; } return; @@ -792,33 +737,261 @@ dopr(PrintfTarget *target, const char *format, va_list args) target->failed = true; } -static void -fmtstr(char *value, int leftjust, int minlen, int maxwidth, - int pointflag, PrintfTarget *target) +/* + * find_arguments(): sort out the arguments for a format spec with %n$ + * + * If format is valid, return true and fill argvalues[i] with the value + * for the conversion spec that has %i$ or *i$. Else return false. + */ +static bool +find_arguments(const char *format, va_list args, + PrintfArgValue *argvalues) { - int padlen, - vallen; /* amount to pad */ + int ch; + bool afterstar; + int accum; + int longlongflag; + int longflag; + int fmtpos; + int i; + int last_dollar; + PrintfArgType argtypes[PG_NL_ARGMAX + 1]; + + /* Initialize to "no dollar arguments known" */ + last_dollar = 0; + MemSet(argtypes, 0, sizeof(argtypes)); /* - * If a maxwidth (precision) is specified, we must not fetch more bytes - * than that. + * This loop must accept the same format strings as the one in dopr(). + * However, we don't need to analyze them to the same level of detail. + * + * Since we're only called if there's a dollar-type spec somewhere, we can + * fail immediately if we find a non-dollar spec. Per the C99 standard, + * all argument references in the format string must be one or the other. */ - if (pointflag) - vallen = strnlen(value, maxwidth); - else - vallen = strlen(value); - - adjust_padlen(minlen, vallen, leftjust, &padlen); - - while (padlen > 0) + while (*format != '\0') { - dopr_outch(' ', target); - --padlen; - } + /* Locate next conversion specifier */ + if (*format != '%') + { + /* Unlike dopr, we can just quit if there's no more specifiers */ + format = strchr(format + 1, '%'); + if (format == NULL) + break; + } - dostr(value, vallen, target); + /* Process conversion spec starting at *format */ + format++; + longflag = longlongflag = 0; + fmtpos = accum = 0; + afterstar = false; +nextch1: + ch = *format++; + switch (ch) + { + case '-': + case '+': + goto nextch1; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + accum = accum * 10 + (ch - '0'); + goto nextch1; + case '.': + accum = 0; + goto nextch1; + case '*': + if (afterstar) + return false; /* previous star missing dollar */ + afterstar = true; + accum = 0; + goto nextch1; + case '$': + if (accum <= 0 || accum > PG_NL_ARGMAX) + return false; + if (afterstar) + { + if (argtypes[accum] && + argtypes[accum] != ATYPE_INT) + return false; + argtypes[accum] = ATYPE_INT; + last_dollar = Max(last_dollar, accum); + afterstar = false; + } + else + fmtpos = accum; + accum = 0; + goto nextch1; + case 'l': + if (longflag) + longlongflag = 1; + else + longflag = 1; + goto nextch1; + case 'z': +#if SIZEOF_SIZE_T == 8 +#ifdef HAVE_LONG_INT_64 + longflag = 1; +#elif defined(HAVE_LONG_LONG_INT_64) + longlongflag = 1; +#else +#error "Don't know how to print 64bit integers" +#endif +#else + /* assume size_t is same size as int */ +#endif + goto nextch1; + case 'h': + case '\'': + /* ignore these */ + goto nextch1; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (fmtpos) + { + PrintfArgType atype; + + if (longlongflag) + atype = ATYPE_LONGLONG; + else if (longflag) + atype = ATYPE_LONG; + else + atype = ATYPE_INT; + if (argtypes[fmtpos] && + argtypes[fmtpos] != atype) + return false; + argtypes[fmtpos] = atype; + last_dollar = Max(last_dollar, fmtpos); + } + else + return false; /* non-dollar conversion spec */ + break; + case 'c': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_INT) + return false; + argtypes[fmtpos] = ATYPE_INT; + last_dollar = Max(last_dollar, fmtpos); + } + else + return false; /* non-dollar conversion spec */ + break; + case 's': + case 'p': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_CHARPTR) + return false; + argtypes[fmtpos] = ATYPE_CHARPTR; + last_dollar = Max(last_dollar, fmtpos); + } + else + return false; /* non-dollar conversion spec */ + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (fmtpos) + { + if (argtypes[fmtpos] && + argtypes[fmtpos] != ATYPE_DOUBLE) + return false; + argtypes[fmtpos] = ATYPE_DOUBLE; + last_dollar = Max(last_dollar, fmtpos); + } + else + return false; /* non-dollar conversion spec */ + break; + case 'm': + case '%': + break; + default: + return false; /* bogus format string */ + } + + /* + * If we finish the spec with afterstar still set, there's a + * non-dollar star in there. + */ + if (afterstar) + return false; /* non-dollar conversion spec */ + } - trailing_pad(&padlen, target); + /* + * Format appears valid so far, so collect the arguments in physical + * order. (Since we rejected any non-dollar specs that would have + * collected arguments, we know that dopr() hasn't collected any yet.) + */ + for (i = 1; i <= last_dollar; i++) + { + switch (argtypes[i]) + { + case ATYPE_NONE: + return false; + case ATYPE_INT: + argvalues[i].i = va_arg(args, int); + break; + case ATYPE_LONG: + argvalues[i].l = va_arg(args, long); + break; + case ATYPE_LONGLONG: + argvalues[i].ll = va_arg(args, long long); + break; + case ATYPE_DOUBLE: + argvalues[i].d = va_arg(args, double); + break; + case ATYPE_CHARPTR: + argvalues[i].cptr = va_arg(args, char *); + break; + } + } + + return true; +} + +static void +fmtstr(const char *value, int leftjust, int minlen, int maxwidth, + int pointflag, PrintfTarget *target) +{ + int padlen, + vallen; /* amount to pad */ + + /* + * If a maxwidth (precision) is specified, we must not fetch more bytes + * than that. + */ + if (pointflag) + vallen = strnlen(value, maxwidth); + else + vallen = strlen(value); + + padlen = compute_padlen(minlen, vallen, leftjust); + + if (padlen > 0) + { + dopr_outchmulti(' ', padlen, target); + padlen = 0; + } + + dostr(value, vallen, target); + + trailing_pad(padlen, target); } static void @@ -836,17 +1009,18 @@ fmtptr(void *value, PrintfTarget *target) } static void -fmtint(int64 value, char type, int forcesign, int leftjust, +fmtint(long long value, char type, int forcesign, int leftjust, int minlen, int zpad, int precision, int pointflag, PrintfTarget *target) { - uint64 base; + unsigned long long base; + unsigned long long uvalue; int dosign; const char *cvt = "0123456789abcdef"; int signvalue = 0; char convert[64]; int vallen = 0; - int padlen = 0; /* amount to pad */ + int padlen; /* amount to pad */ int zeropad; /* extra leading zeroes */ switch (type) @@ -877,9 +1051,19 @@ fmtint(int64 value, char type, int forcesign, int leftjust, return; /* keep compiler quiet */ } + /* disable MSVC warning about applying unary minus to an unsigned value */ +#if _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4146) +#endif /* Handle +/- */ if (dosign && adjust_sign((value < 0), forcesign, &signvalue)) - value = -value; + uvalue = -(unsigned long long) value; + else + uvalue = (unsigned long long) value; +#if _MSC_VER +#pragma warning(pop) +#endif /* * SUS: the result of converting 0 with an explicit precision of 0 is no @@ -890,46 +1074,43 @@ fmtint(int64 value, char type, int forcesign, int leftjust, else { /* make integer string */ - uint64 uvalue = (uint64) value; - do { - convert[vallen++] = cvt[uvalue % base]; + convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base]; uvalue = uvalue / base; } while (uvalue); } zeropad = Max(0, precision - vallen); - adjust_padlen(minlen, vallen + zeropad, leftjust, &padlen); + padlen = compute_padlen(minlen, vallen + zeropad, leftjust); - leading_pad(zpad, &signvalue, &padlen, target); + leading_pad(zpad, signvalue, &padlen, target); - while (zeropad-- > 0) - dopr_outch('0', target); + if (zeropad > 0) + dopr_outchmulti('0', zeropad, target); - while (vallen > 0) - dopr_outch(convert[--vallen], target); + dostr(convert + sizeof(convert) - vallen, vallen, target); - trailing_pad(&padlen, target); + trailing_pad(padlen, target); } static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target) { - int padlen = 0; /* amount to pad */ + int padlen; /* amount to pad */ - adjust_padlen(minlen, 1, leftjust, &padlen); + padlen = compute_padlen(minlen, 1, leftjust); - while (padlen > 0) + if (padlen > 0) { - dopr_outch(' ', target); - --padlen; + dopr_outchmulti(' ', padlen, target); + padlen = 0; } dopr_outch(value, target); - trailing_pad(&padlen, target); + trailing_pad(padlen, target); } static void @@ -940,10 +1121,10 @@ fmtfloat(double value, char type, int forcesign, int leftjust, int signvalue = 0; int prec; int vallen; - char fmt[32]; + char fmt[8]; char convert[1024]; int zeropadlen = 0; /* amount to pad with zeroes */ - int padlen = 0; /* amount to pad with spaces */ + int padlen; /* amount to pad with spaces */ /* * We rely on the regular C library's sprintf to do the basic conversion, @@ -958,34 +1139,82 @@ fmtfloat(double value, char type, int forcesign, int leftjust, * bytes and limit requested precision to 350 digits; this should prevent * buffer overrun even with non-IEEE math. If the original precision * request was more than 350, separately pad with zeroes. + * + * We handle infinities and NaNs specially to ensure platform-independent + * output. */ if (precision < 0) /* cover possible overflow of "accum" */ precision = 0; prec = Min(precision, 350); - if (pointflag) + if (isnan(value)) { - if (sprintf(fmt, "%%.%d%c", prec, type) < 0) - goto fail; - zeropadlen = precision - prec; + strcpy(convert, "NaN"); + vallen = 3; + /* no zero padding, regardless of precision spec */ } - else if (sprintf(fmt, "%%%c", type) < 0) - goto fail; + else + { + /* + * Handle sign (NaNs have no sign, so we don't do this in the case + * above). "value < 0.0" will not be true for IEEE minus zero, so we + * detect that by looking for the case where value equals 0.0 + * according to == but not according to memcmp. + */ + static const double dzero = 0.0; - if (!isnan(value) && adjust_sign((value < 0), forcesign, &signvalue)) - value = -value; + if (adjust_sign((value < 0.0 || + (value == 0.0 && + memcmp(&value, &dzero, sizeof(double)) != 0)), + forcesign, &signvalue)) + value = -value; - vallen = sprintf(convert, fmt, value); - if (vallen < 0) - goto fail; + if (isinf(value)) + { + strcpy(convert, "Infinity"); + vallen = 8; + /* no zero padding, regardless of precision spec */ + } + else if (pointflag) + { + zeropadlen = precision - prec; + fmt[0] = '%'; + fmt[1] = '.'; + fmt[2] = '*'; + fmt[3] = type; + fmt[4] = '\0'; + vallen = sprintf(convert, fmt, prec, value); + } + else + { + fmt[0] = '%'; + fmt[1] = type; + fmt[2] = '\0'; + vallen = sprintf(convert, fmt, value); + } + if (vallen < 0) + goto fail; - /* If it's infinity or NaN, forget about doing any zero-padding */ - if (zeropadlen > 0 && !isdigit((unsigned char) convert[vallen - 1])) - zeropadlen = 0; + /* + * Windows, alone among our supported platforms, likes to emit + * three-digit exponent fields even when two digits would do. Hack + * such results to look like the way everyone else does it. + */ +#ifdef WIN32 + if (vallen >= 6 && + convert[vallen - 5] == 'e' && + convert[vallen - 3] == '0') + { + convert[vallen - 3] = convert[vallen - 2]; + convert[vallen - 2] = convert[vallen - 1]; + vallen--; + } +#endif + } - adjust_padlen(minlen, vallen + zeropadlen, leftjust, &padlen); + padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust); - leading_pad(zpad, &signvalue, &padlen, target); + leading_pad(zpad, signvalue, &padlen, target); if (zeropadlen > 0) { @@ -996,18 +1225,18 @@ fmtfloat(double value, char type, int forcesign, int leftjust, epos = strrchr(convert, 'E'); if (epos) { - /* pad after exponent */ + /* pad before exponent */ dostr(convert, epos - convert, target); - while (zeropadlen-- > 0) - dopr_outch('0', target); + if (zeropadlen > 0) + dopr_outchmulti('0', zeropadlen, target); dostr(epos, vallen - (epos - convert), target); } else { /* no exponent, pad after the digits */ dostr(convert, vallen, target); - while (zeropadlen-- > 0) - dopr_outch('0', target); + if (zeropadlen > 0) + dopr_outchmulti('0', zeropadlen, target); } } else @@ -1016,16 +1245,124 @@ fmtfloat(double value, char type, int forcesign, int leftjust, dostr(convert, vallen, target); } - trailing_pad(&padlen, target); + trailing_pad(padlen, target); return; fail: target->failed = true; } +/* + * Nonstandard entry point to print a double value efficiently. + * + * This is approximately equivalent to strfromd(), but has an API more + * adapted to what float8out() wants. The behavior is like snprintf() + * with a format of "%.ng", where n is the specified precision. + * However, the target buffer must be nonempty (i.e. count > 0), and + * the precision is silently bounded to a sane range. + */ +int +pg_strfromd(char *str, size_t count, int precision, double value) +{ + PrintfTarget target; + int signvalue = 0; + int vallen; + char fmt[8]; + char convert[64]; + + /* Set up the target like pg_snprintf, but require nonempty buffer */ + Assert(count > 0); + target.bufstart = target.bufptr = str; + target.bufend = str + count - 1; + target.stream = NULL; + target.nchars = 0; + target.failed = false; + + /* + * We bound precision to a reasonable range; the combination of this and + * the knowledge that we're using "g" format without padding allows the + * convert[] buffer to be reasonably small. + */ + if (precision < 1) + precision = 1; + else if (precision > 32) + precision = 32; + + /* + * The rest is just an inlined version of the fmtfloat() logic above, + * simplified using the knowledge that no padding is wanted. + */ + if (isnan(value)) + { + strcpy(convert, "NaN"); + vallen = 3; + } + else + { + static const double dzero = 0.0; + + if (value < 0.0 || + (value == 0.0 && + memcmp(&value, &dzero, sizeof(double)) != 0)) + { + signvalue = '-'; + value = -value; + } + + if (isinf(value)) + { + strcpy(convert, "Infinity"); + vallen = 8; + } + else + { + fmt[0] = '%'; + fmt[1] = '.'; + fmt[2] = '*'; + fmt[3] = 'g'; + fmt[4] = '\0'; + vallen = sprintf(convert, fmt, precision, value); + if (vallen < 0) + { + target.failed = true; + goto fail; + } + +#ifdef WIN32 + if (vallen >= 6 && + convert[vallen - 5] == 'e' && + convert[vallen - 3] == '0') + { + convert[vallen - 3] = convert[vallen - 2]; + convert[vallen - 2] = convert[vallen - 1]; + vallen--; + } +#endif + } + } + + if (signvalue) + dopr_outch(signvalue, &target); + + dostr(convert, vallen, &target); + +fail: + *(target.bufptr) = '\0'; + return target.failed ? -1 : (target.bufptr - target.bufstart + + target.nchars); +} + + static void dostr(const char *str, int slen, PrintfTarget *target) { + /* fast path for common case of slen == 1 */ + if (slen == 1) + { + dopr_outch(*str, target); + return; + } + while (slen > 0) { int avail; @@ -1038,7 +1375,10 @@ dostr(const char *str, int slen, PrintfTarget *target) { /* buffer full, can we dump to stream? */ if (target->stream == NULL) - return; /* no, lose the data */ + { + target->nchars += slen; /* no, lose the data */ + return; + } flushbuffer(target); continue; } @@ -1057,12 +1397,51 @@ dopr_outch(int c, PrintfTarget *target) { /* buffer full, can we dump to stream? */ if (target->stream == NULL) - return; /* no, lose the data */ + { + target->nchars++; /* no, lose the data */ + return; + } flushbuffer(target); } *(target->bufptr++) = c; } +static void +dopr_outchmulti(int c, int slen, PrintfTarget *target) +{ + /* fast path for common case of slen == 1 */ + if (slen == 1) + { + dopr_outch(c, target); + return; + } + + while (slen > 0) + { + int avail; + + if (target->bufend != NULL) + avail = target->bufend - target->bufptr; + else + avail = slen; + if (avail <= 0) + { + /* buffer full, can we dump to stream? */ + if (target->stream == NULL) + { + target->nchars += slen; /* no, lose the data */ + return; + } + flushbuffer(target); + continue; + } + avail = Min(avail, slen); + memset(target->bufptr, c, avail); + target->bufptr += avail; + slen -= avail; + } +} + static int adjust_sign(int is_negative, int forcesign, int *signvalue) @@ -1078,42 +1457,48 @@ adjust_sign(int is_negative, int forcesign, int *signvalue) } -static void -adjust_padlen(int minlen, int vallen, int leftjust, int *padlen) +static int +compute_padlen(int minlen, int vallen, int leftjust) { - *padlen = minlen - vallen; - if (*padlen < 0) - *padlen = 0; + int padlen; + + padlen = minlen - vallen; + if (padlen < 0) + padlen = 0; if (leftjust) - *padlen = -(*padlen); + padlen = -padlen; + return padlen; } static void -leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target) +leading_pad(int zpad, int signvalue, int *padlen, PrintfTarget *target) { + int maxpad; + if (*padlen > 0 && zpad) { - if (*signvalue) + if (signvalue) { - dopr_outch(*signvalue, target); + dopr_outch(signvalue, target); --(*padlen); - *signvalue = 0; + signvalue = 0; } - while (*padlen > 0) + if (*padlen > 0) { - dopr_outch(zpad, target); - --(*padlen); + dopr_outchmulti(zpad, *padlen, target); + *padlen = 0; } } - while (*padlen > (*signvalue != 0)) + maxpad = (signvalue != 0); + if (*padlen > maxpad) { - dopr_outch(' ', target); - --(*padlen); + dopr_outchmulti(' ', *padlen - maxpad, target); + *padlen = maxpad; } - if (*signvalue) + if (signvalue) { - dopr_outch(*signvalue, target); + dopr_outch(signvalue, target); if (*padlen > 0) --(*padlen); else if (*padlen < 0) @@ -1123,11 +1508,8 @@ leading_pad(int zpad, int *signvalue, int *padlen, PrintfTarget *target) static void -trailing_pad(int *padlen, PrintfTarget *target) +trailing_pad(int padlen, PrintfTarget *target) { - while (*padlen < 0) - { - dopr_outch(' ', target); - ++(*padlen); - } + if (padlen < 0) + dopr_outchmulti(' ', -padlen, target); } diff --git a/src/port/sprompt.c b/src/port/sprompt.c index 70dfa69d7ba..02164d497a5 100644 --- a/src/port/sprompt.c +++ b/src/port/sprompt.c @@ -3,7 +3,7 @@ * sprompt.c * simple_prompt() routine * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -40,15 +40,13 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) FILE *termin, *termout; -#ifdef HAVE_TERMIOS_H +#if defined(HAVE_TERMIOS_H) struct termios t_orig, t; -#else -#ifdef WIN32 +#elif defined(WIN32) HANDLE t = NULL; DWORD t_orig = 0; #endif -#endif #ifdef WIN32 @@ -66,8 +64,11 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) * * XXX fgets() still receives text in the console's input code page. This * makes non-ASCII credentials unportable. + * + * Unintuitively, we also open termin in mode "w+", even though we only + * read it; that's needed for SetConsoleMode() to succeed. */ - termin = fopen("CONIN$", "r"); + termin = fopen("CONIN$", "w+"); termout = fopen("CONOUT$", "w+"); #else @@ -99,29 +100,25 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) termout = stderr; } -#ifdef HAVE_TERMIOS_H if (!echo) { +#if defined(HAVE_TERMIOS_H) + /* disable echo via tcgetattr/tcsetattr */ tcgetattr(fileno(termin), &t); t_orig = t; t.c_lflag &= ~ECHO; tcsetattr(fileno(termin), TCSAFLUSH, &t); - } -#else -#ifdef WIN32 - if (!echo) - { - /* get a new handle to turn echo off */ - t = GetStdHandle(STD_INPUT_HANDLE); +#elif defined(WIN32) + /* need the file's HANDLE to turn echo off */ + t = (HANDLE) _get_osfhandle(_fileno(termin)); /* save the old configuration first */ GetConsoleMode(t, &t_orig); /* set to the new mode */ SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); - } -#endif #endif + } if (prompt) { @@ -147,28 +144,25 @@ simple_prompt(const char *prompt, char *destination, size_t destlen, bool echo) } while (buflen > 0 && buf[buflen - 1] != '\n'); } - if (length > 0 && destination[length - 1] == '\n') - /* remove trailing newline */ - destination[length - 1] = '\0'; + /* strip trailing newline, including \r in case we're on Windows */ + while (length > 0 && + (destination[length - 1] == '\n' || + destination[length - 1] == '\r')) + destination[--length] = '\0'; -#ifdef HAVE_TERMIOS_H if (!echo) { + /* restore previous echo behavior, then echo \n */ +#if defined(HAVE_TERMIOS_H) tcsetattr(fileno(termin), TCSAFLUSH, &t_orig); fputs("\n", termout); fflush(termout); - } -#else -#ifdef WIN32 - if (!echo) - { - /* reset to the original console mode */ +#elif defined(WIN32) SetConsoleMode(t, t_orig); fputs("\n", termout); fflush(termout); - } -#endif #endif + } if (termin != stdin) { diff --git a/src/port/srandom.c b/src/port/srandom.c index 6939260d33b..406088c83f6 100644 --- a/src/port/srandom.c +++ b/src/port/srandom.c @@ -3,7 +3,7 @@ * srandom.c * srandom() wrapper * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/strerror.c b/src/port/strerror.c index e92ebc9f55a..599e6b887f8 100644 --- a/src/port/strerror.c +++ b/src/port/strerror.c @@ -1,30 +1,322 @@ -/* src/port/strerror.c */ - -/* - * strerror - map error number to descriptive string +/*------------------------------------------------------------------------- + * + * strerror.c + * Replacements for standard strerror() and strerror_r() functions + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * - * This version is obviously somewhat Unix-specific. * - * based on code by Henry Spencer - * modified for ANSI by D'Arcy J.M. Cain + * IDENTIFICATION + * src/port/strerror.c + * + *------------------------------------------------------------------------- */ - #include "c.h" +/* + * Within this file, "strerror" means the platform's function not pg_strerror, + * and likewise for "strerror_r" + */ +#undef strerror +#undef strerror_r + +static char *gnuish_strerror_r(int errnum, char *buf, size_t buflen); +static char *get_errno_symbol(int errnum); +#ifdef WIN32 +static char *win32_socket_strerror(int errnum, char *buf, size_t buflen); +#endif -extern const char *const sys_errlist[]; -extern int sys_nerr; -const char * -strerror(int errnum) +/* + * A slightly cleaned-up version of strerror() + */ +char * +pg_strerror(int errnum) { - static char buf[24]; + static char errorstr_buf[PG_STRERROR_R_BUFLEN]; + + return pg_strerror_r(errnum, errorstr_buf, sizeof(errorstr_buf)); +} - if (errnum < 0 || errnum > sys_nerr) +/* + * A slightly cleaned-up version of strerror_r() + */ +char * +pg_strerror_r(int errnum, char *buf, size_t buflen) +{ + char *str; + + /* If it's a Windows Winsock error, that needs special handling */ +#ifdef WIN32 + /* Winsock error code range, per WinError.h */ + if (errnum >= 10000 && errnum <= 11999) + return win32_socket_strerror(errnum, buf, buflen); +#endif + + /* Try the platform's strerror_r(), or maybe just strerror() */ + str = gnuish_strerror_r(errnum, buf, buflen); + + /* + * Some strerror()s return an empty string for out-of-range errno. This + * is ANSI C spec compliant, but not exactly useful. Also, we may get + * back strings of question marks if libc cannot transcode the message to + * the codeset specified by LC_CTYPE. If we get nothing useful, first try + * get_errno_symbol(), and if that fails, print the numeric errno. + */ + if (str == NULL || *str == '\0' || *str == '?') + str = get_errno_symbol(errnum); + + if (str == NULL) { - sprintf(buf, _("unrecognized error %d"), errnum); + snprintf(buf, buflen, _("operating system error %d"), errnum); + str = buf; + } + + return str; +} + +/* + * Simple wrapper to emulate GNU strerror_r if what the platform provides is + * POSIX. Also, if platform lacks strerror_r altogether, fall back to plain + * strerror; it might not be very thread-safe, but tough luck. + */ +static char * +gnuish_strerror_r(int errnum, char *buf, size_t buflen) +{ +#ifdef HAVE_STRERROR_R +#ifdef STRERROR_R_INT + /* POSIX API */ + if (strerror_r(errnum, buf, buflen) == 0) return buf; + return NULL; /* let caller deal with failure */ +#else + /* GNU API */ + return strerror_r(errnum, buf, buflen); +#endif +#else /* !HAVE_STRERROR_R */ + char *sbuf = strerror(errnum); + + if (sbuf == NULL) /* can this still happen anywhere? */ + return NULL; + /* To minimize thread-unsafety hazard, copy into caller's buffer */ + strlcpy(buf, sbuf, buflen); + return buf; +#endif +} + +/* + * Returns a symbol (e.g. "ENOENT") for an errno code. + * Returns NULL if the code is unrecognized. + */ +static char * +get_errno_symbol(int errnum) +{ + switch (errnum) + { + case E2BIG: + return "E2BIG"; + case EACCES: + return "EACCES"; +#ifdef EADDRINUSE + case EADDRINUSE: + return "EADDRINUSE"; +#endif +#ifdef EADDRNOTAVAIL + case EADDRNOTAVAIL: + return "EADDRNOTAVAIL"; +#endif + case EAFNOSUPPORT: + return "EAFNOSUPPORT"; +#ifdef EAGAIN + case EAGAIN: + return "EAGAIN"; +#endif +#ifdef EALREADY + case EALREADY: + return "EALREADY"; +#endif + case EBADF: + return "EBADF"; +#ifdef EBADMSG + case EBADMSG: + return "EBADMSG"; +#endif + case EBUSY: + return "EBUSY"; + case ECHILD: + return "ECHILD"; +#ifdef ECONNABORTED + case ECONNABORTED: + return "ECONNABORTED"; +#endif + case ECONNREFUSED: + return "ECONNREFUSED"; +#ifdef ECONNRESET + case ECONNRESET: + return "ECONNRESET"; +#endif + case EDEADLK: + return "EDEADLK"; + case EDOM: + return "EDOM"; + case EEXIST: + return "EEXIST"; + case EFAULT: + return "EFAULT"; + case EFBIG: + return "EFBIG"; +#ifdef EHOSTUNREACH + case EHOSTUNREACH: + return "EHOSTUNREACH"; +#endif + case EIDRM: + return "EIDRM"; + case EINPROGRESS: + return "EINPROGRESS"; + case EINTR: + return "EINTR"; + case EINVAL: + return "EINVAL"; + case EIO: + return "EIO"; +#ifdef EISCONN + case EISCONN: + return "EISCONN"; +#endif + case EISDIR: + return "EISDIR"; +#ifdef ELOOP + case ELOOP: + return "ELOOP"; +#endif + case EMFILE: + return "EMFILE"; + case EMLINK: + return "EMLINK"; + case EMSGSIZE: + return "EMSGSIZE"; + case ENAMETOOLONG: + return "ENAMETOOLONG"; + case ENFILE: + return "ENFILE"; + case ENOBUFS: + return "ENOBUFS"; + case ENODEV: + return "ENODEV"; + case ENOENT: + return "ENOENT"; + case ENOEXEC: + return "ENOEXEC"; + case ENOMEM: + return "ENOMEM"; + case ENOSPC: + return "ENOSPC"; + case ENOSYS: + return "ENOSYS"; +#ifdef ENOTCONN + case ENOTCONN: + return "ENOTCONN"; +#endif + case ENOTDIR: + return "ENOTDIR"; +#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */ + case ENOTEMPTY: + return "ENOTEMPTY"; +#endif +#ifdef ENOTSOCK + case ENOTSOCK: + return "ENOTSOCK"; +#endif +#ifdef ENOTSUP + case ENOTSUP: + return "ENOTSUP"; +#endif + case ENOTTY: + return "ENOTTY"; + case ENXIO: + return "ENXIO"; +#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP)) + case EOPNOTSUPP: + return "EOPNOTSUPP"; +#endif +#ifdef EOVERFLOW + case EOVERFLOW: + return "EOVERFLOW"; +#endif + case EPERM: + return "EPERM"; + case EPIPE: + return "EPIPE"; + case EPROTONOSUPPORT: + return "EPROTONOSUPPORT"; + case ERANGE: + return "ERANGE"; +#ifdef EROFS + case EROFS: + return "EROFS"; +#endif + case ESRCH: + return "ESRCH"; +#ifdef ETIMEDOUT + case ETIMEDOUT: + return "ETIMEDOUT"; +#endif +#ifdef ETXTBSY + case ETXTBSY: + return "ETXTBSY"; +#endif +#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) + case EWOULDBLOCK: + return "EWOULDBLOCK"; +#endif + case EXDEV: + return "EXDEV"; + } + + return NULL; +} + + +#ifdef WIN32 + +/* + * Windows' strerror() doesn't know the Winsock codes, so handle them this way + */ +static char * +win32_socket_strerror(int errnum, char *buf, size_t buflen) +{ + static HANDLE handleDLL = INVALID_HANDLE_VALUE; + + if (handleDLL == INVALID_HANDLE_VALUE) + { + handleDLL = LoadLibraryEx("netmsg.dll", NULL, + DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if (handleDLL == NULL) + { + snprintf(buf, buflen, + "winsock error %d (could not load netmsg.dll to translate: error code %lu)", + errnum, GetLastError()); + return buf; + } + } + + ZeroMemory(buf, buflen); + if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_FROM_HMODULE, + handleDLL, + errnum, + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + buf, + buflen - 1, + NULL) == 0) + { + /* Failed to get id */ + snprintf(buf, buflen, "unrecognized winsock error %d", errnum); } - return sys_errlist[errnum]; + return buf; } + +#endif /* WIN32 */ diff --git a/src/port/strlcpy.c b/src/port/strlcpy.c index 920d7f88f54..418c6a672ff 100644 --- a/src/port/strlcpy.c +++ b/src/port/strlcpy.c @@ -3,7 +3,7 @@ * strlcpy.c * strncpy done right * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/port/strnlen.c b/src/port/strnlen.c index bd4b56bbb15..eb2185fe0b6 100644 --- a/src/port/strnlen.c +++ b/src/port/strnlen.c @@ -4,7 +4,7 @@ * Fallback implementation of strnlen(). * * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION diff --git a/src/port/strtof.c b/src/port/strtof.c new file mode 100644 index 00000000000..904cc5ff721 --- /dev/null +++ b/src/port/strtof.c @@ -0,0 +1,132 @@ +/*------------------------------------------------------------------------- + * + * strtof.c + * + * Portions Copyright (c) 2019, PostgreSQL Global Development Group + * + * + * IDENTIFICATION + * src/port/strtof.c + * + *------------------------------------------------------------------------- + */ + +#include "c.h" + +#include +#include + +#ifndef HAVE_STRTOF +/* + * strtof() is part of C99; this version is only for the benefit of obsolete + * platforms. As such, it is known to return incorrect values for edge cases, + * which have to be allowed for in variant files for regression test results + * for any such platform. + */ + +float +strtof(const char *nptr, char **endptr) +{ + int caller_errno = errno; + double dresult; + float fresult; + + errno = 0; + dresult = strtod(nptr, endptr); + fresult = (float) dresult; + + if (errno == 0) + { + /* + * Value might be in-range for double but not float. + */ + if (dresult != 0 && fresult == 0) + caller_errno = ERANGE; /* underflow */ + if (!isinf(dresult) && isinf(fresult)) + caller_errno = ERANGE; /* overflow */ + } + else + caller_errno = errno; + + errno = caller_errno; + return fresult; +} + +#elif HAVE_BUGGY_STRTOF +/* + * On Windows, there's a slightly different problem: VS2013 has a strtof() + * that returns the correct results for valid input, but may fail to report an + * error for underflow or overflow, returning 0 instead. Work around that by + * trying strtod() when strtof() returns 0.0 or [+-]Inf, and calling it an + * error if the result differs. Also, strtof() doesn't handle subnormal input + * well, so prefer to round the strtod() result in such cases. (Normally we'd + * just say "too bad" if strtof() doesn't support subnormals, but since we're + * already in here fixing stuff, we might as well do the best fix we can.) + * + * Cygwin has a strtof() which is literally just (float)strtod(), which means + * we can't avoid the double-rounding problem; but using this wrapper does get + * us proper over/underflow checks. (Also, if they fix their strtof(), the + * wrapper doesn't break anything.) + * + * Test results on Mingw suggest that it has the same problem, though looking + * at the code I can't figure out why. + */ +float +pg_strtof(const char *nptr, char **endptr) +{ + int caller_errno = errno; + float fresult; + + errno = 0; + fresult = (strtof) (nptr, endptr); + if (errno) + { + /* On error, just return the error to the caller. */ + return fresult; + } + else if ((*endptr == nptr) || isnan(fresult) || + ((fresult >= FLT_MIN || fresult <= -FLT_MIN) && !isinf(fresult))) + { + /* + * If we got nothing parseable, or if we got a non-0 non-subnormal + * finite value (or NaN) without error, then return that to the caller + * without error. + */ + errno = caller_errno; + return fresult; + } + else + { + /* + * Try again. errno is already 0 here. + */ + double dresult = strtod(nptr, NULL); + + if (errno) + { + /* On error, just return the error */ + return fresult; + } + else if ((dresult == 0.0 && fresult == 0.0) || + (isinf(dresult) && isinf(fresult) && (fresult == dresult))) + { + /* both values are 0 or infinities of the same sign */ + errno = caller_errno; + return fresult; + } + else if ((dresult > 0 && dresult <= FLT_MIN && (float) dresult != 0.0) || + (dresult < 0 && dresult >= -FLT_MIN && (float) dresult != 0.0)) + { + /* subnormal but nonzero value */ + errno = caller_errno; + return (float) dresult; + } + else + { + errno = ERANGE; + return fresult; + } + } +} + +#endif diff --git a/src/port/system.c b/src/port/system.c index 9d5766e33c4..32c0c918919 100644 --- a/src/port/system.c +++ b/src/port/system.c @@ -29,7 +29,7 @@ * quote character on the command line, preserving any text after the last * quote character. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/port/system.c * diff --git a/src/port/thread.c b/src/port/thread.c index da2df1f8087..046f300d07c 100644 --- a/src/port/thread.c +++ b/src/port/thread.c @@ -5,7 +5,7 @@ * Prototypes and macros around system calls, used to help make * threaded libraries reentrant and safe to use from threaded applications. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * src/port/thread.c * @@ -53,33 +53,6 @@ */ -/* - * Wrapper around strerror and strerror_r to use the former if it is - * available and also return a more useful value (the error string). - */ -char * -pqStrerror(int errnum, char *strerrbuf, size_t buflen) -{ -#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_STRERROR_R) - /* reentrant strerror_r is available */ -#ifdef STRERROR_R_INT - /* SUSv3 version */ - if (strerror_r(errnum, strerrbuf, buflen) == 0) - return strerrbuf; - else - return "Unknown error"; -#else - /* GNU libc */ - return strerror_r(errnum, strerrbuf, buflen); -#endif -#else - /* no strerror_r() available, just use strerror */ - strlcpy(strerrbuf, strerror(errnum), buflen); - - return strerrbuf; -#endif -} - /* * Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r() * behaviour, if that function is not available or required. @@ -110,7 +83,7 @@ pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, /* * Wrapper around gethostbyname() or gethostbyname_r() to mimic * POSIX gethostbyname_r() behaviour, if it is not available or required. - * This function is called _only_ by our getaddinfo() portability function. + * This function is called _only_ by our getaddrinfo() portability function. */ #ifndef HAVE_GETADDRINFO int diff --git a/src/port/unsetenv.c b/src/port/unsetenv.c index 78414314821..82dd2260f9e 100644 --- a/src/port/unsetenv.c +++ b/src/port/unsetenv.c @@ -3,7 +3,7 @@ * unsetenv.c * unsetenv() emulation for machines without it * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/win32env.c b/src/port/win32env.c index af8555a7a7f..6f4994c96a8 100644 --- a/src/port/win32env.c +++ b/src/port/win32env.c @@ -4,7 +4,7 @@ * putenv() and unsetenv() for win32, which update both process environment * and caches in (potentially multiple) C run-time library (CRT) versions. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * diff --git a/src/port/win32error.c b/src/port/win32error.c index 71f6e89ddd3..7fd29eab377 100644 --- a/src/port/win32error.c +++ b/src/port/win32error.c @@ -3,7 +3,7 @@ * win32error.c * Map win32 error codes to errno values * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/port/win32error.c diff --git a/src/port/win32security.c b/src/port/win32security.c index 8d7bcd2d926..eb250d38563 100644 --- a/src/port/win32security.c +++ b/src/port/win32security.c @@ -3,7 +3,7 @@ * win32security.c * Microsoft Windows Win32 Security Support Functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/port/win32security.c diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.c index 0597c2afca4..710dbb9b9d4 100644 --- a/src/port/win32setlocale.c +++ b/src/port/win32setlocale.c @@ -3,7 +3,7 @@ * win32setlocale.c * Wrapper to work around bugs in Windows setlocale() implementation * - * Copyright (c) 2011-2018, PostgreSQL Global Development Group + * Copyright (c) 2011-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/port/win32setlocale.c @@ -183,7 +183,7 @@ pgwin32_setlocale(int category, const char *locale) * forbidden to modify, so casting away the "const" is innocuous. */ if (result) - result = (char *) map_locale(locale_map_result, result); + result = unconstify(char *, map_locale(locale_map_result, result)); return result; } diff --git a/src/port/win32ver.rc b/src/port/win32ver.rc index a62fde4b0cf..5631ee91426 100644 --- a/src/port/win32ver.rc +++ b/src/port/win32ver.rc @@ -2,8 +2,8 @@ #include "pg_config.h" VS_VERSION_INFO VERSIONINFO - FILEVERSION 11,0,0,0 - PRODUCTVERSION 11,0,0,0 + FILEVERSION 13,0,0,0 + PRODUCTVERSION 13,0,0,0 FILEFLAGSMASK 0x17L FILEFLAGS 0x0L FILEOS VOS_NT_WINDOWS32 @@ -17,7 +17,7 @@ BEGIN VALUE "CompanyName", "PostgreSQL Global Development Group" VALUE "FileDescription", FILEDESC VALUE "FileVersion", PG_VERSION - VALUE "LegalCopyright", "Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group. Portions Copyright (c) 1994, Regents of the University of California." + VALUE "LegalCopyright", "Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group. Portions Copyright (c) 1994, Regents of the University of California." VALUE "ProductName", "PostgreSQL" VALUE "ProductVersion", PG_VERSION END diff --git a/src/template/darwin b/src/template/darwin index ea6d3b0b042..c05adca0bfb 100644 --- a/src/template/darwin +++ b/src/template/darwin @@ -3,6 +3,19 @@ # Note: Darwin is the original code name for macOS, also known as OS X. # We still use "darwin" as the port name, partly because config.guess does. +# Select where system include files should be sought. +if test x"$PG_SYSROOT" = x"" ; then + PG_SYSROOT=`xcodebuild -version -sdk macosx Path 2>/dev/null` +fi +# Old xcodebuild versions may produce garbage, so validate the result. +if test x"$PG_SYSROOT" != x"" ; then + if test -d "$PG_SYSROOT" ; then + CPPFLAGS="-isysroot $PG_SYSROOT $CPPFLAGS" + else + PG_SYSROOT="" + fi +fi + # Select appropriate semaphore support. Darwin 6.0 (macOS 10.2) and up # support System V semaphores; before that we have to use named POSIX # semaphores, which are less good for our purposes because they eat a diff --git a/src/template/linux b/src/template/linux index f820bf7280f..e39290845ad 100644 --- a/src/template/linux +++ b/src/template/linux @@ -6,6 +6,7 @@ if test x"$PREFERRED_SEMAPHORES" = x"" ; then fi # Force _GNU_SOURCE on; plperl is broken with Perl 5.8.0 otherwise +# This is also required for ppoll(2), and perhaps other things CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" # If --enable-profiling is specified, we need -DLINUX_PROFILE diff --git a/src/test/authentication/Makefile b/src/test/authentication/Makefile index 218452ec764..4dfa795fd37 100644 --- a/src/test/authentication/Makefile +++ b/src/test/authentication/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/authentication # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/authentication/Makefile diff --git a/src/test/authentication/README b/src/test/authentication/README index dd797467538..a8f27bfdaf5 100644 --- a/src/test/authentication/README +++ b/src/test/authentication/README @@ -11,10 +11,16 @@ are more complicated, and are not safe to run in a multi-user system. Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. -NOTE: This requires the --enable-tap-tests argument to configure. +Either way, this test initializes, starts, and stops a test Postgres +cluster. diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl index 9340f2f1ab4..aae6de8b345 100644 --- a/src/test/authentication/t/001_password.pl +++ b/src/test/authentication/t/001_password.pl @@ -17,7 +17,7 @@ } else { - plan tests => 8; + plan tests => 10; } @@ -31,6 +31,7 @@ sub reset_pg_hba unlink($node->data_dir . '/pg_hba.conf'); $node->append_conf('pg_hba.conf', "local all all $hba_method"); $node->reload; + return; } # Test access for a single role, useful to wrap all tests into one. @@ -47,6 +48,7 @@ sub test_role my $res = $node->psql('postgres', undef, extra_params => [ '-U', $role ]); is($res, $expected_res, "authentication $status_string for method $method, role $role"); + return; } # Initialize master node @@ -57,10 +59,11 @@ sub test_role # Create 3 roles with different password methods for each one. The same # password is used for all of them. $node->safe_psql('postgres', -"SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';" + "SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';" ); $node->safe_psql('postgres', -"SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';"); + "SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';" +); $ENV{"PGPASSWORD"} = 'pass'; # For "trust" method, all users should be able to connect. @@ -83,3 +86,13 @@ sub test_role reset_pg_hba($node, 'md5'); test_role($node, 'scram_role', 'md5', 0); test_role($node, 'md5_role', 'md5', 0); + +# Tests for channel binding without SSL. +# Using the password authentication method; channel binding can't work +reset_pg_hba($node, 'password'); +$ENV{"PGCHANNELBINDING"} = 'require'; +test_role($node, 'scram_role', 'scram-sha-256', 2); +# SSL not in use; channel binding still can't work +reset_pg_hba($node, 'scram-sha-256'); +$ENV{"PGCHANNELBINDING"} = 'require'; +test_role($node, 'scram_role', 'scram-sha-256', 2); diff --git a/src/test/authentication/t/002_saslprep.pl b/src/test/authentication/t/002_saslprep.pl index e09273edd46..c4b335c45fe 100644 --- a/src/test/authentication/t/002_saslprep.pl +++ b/src/test/authentication/t/002_saslprep.pl @@ -27,6 +27,7 @@ sub reset_pg_hba unlink($node->data_dir . '/pg_hba.conf'); $node->append_conf('pg_hba.conf', "local all all $hba_method"); $node->reload; + return; } # Test access for a single role, useful to wrap all tests into one. @@ -45,6 +46,7 @@ sub test_login is($res, $expected_res, "authentication $status_string for role $role with password $password" ); + return; } # Initialize master node. Force UTF-8 encoding, so that we can use non-ASCII diff --git a/src/test/examples/testlibpq.c b/src/test/examples/testlibpq.c index 92a05e53093..18c98083de9 100644 --- a/src/test/examples/testlibpq.c +++ b/src/test/examples/testlibpq.c @@ -48,10 +48,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); diff --git a/src/test/examples/testlibpq2.c b/src/test/examples/testlibpq2.c index 76787fe010b..511246763a6 100644 --- a/src/test/examples/testlibpq2.c +++ b/src/test/examples/testlibpq2.c @@ -77,10 +77,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); @@ -140,6 +140,7 @@ main(int argc, char **argv) notify->relname, notify->be_pid); PQfreemem(notify); nnotifies++; + PQconsumeInput(conn); } } diff --git a/src/test/examples/testlibpq3.c b/src/test/examples/testlibpq3.c index 00e62b43d28..dda45af859a 100644 --- a/src/test/examples/testlibpq3.c +++ b/src/test/examples/testlibpq3.c @@ -10,9 +10,10 @@ * * CREATE SCHEMA testlibpq3; * SET search_path = testlibpq3; + * SET standard_conforming_strings = ON; * CREATE TABLE test1 (i int4, t text, b bytea); - * INSERT INTO test1 values (1, 'joe''s place', '\\000\\001\\002\\003\\004'); - * INSERT INTO test1 values (2, 'ho there', '\\004\\003\\002\\001\\000'); + * INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); + * INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); * * The expected output is: * @@ -142,7 +143,7 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SET search_path = testlibpq3"); if (PQresultStatus(res) != PGRES_COMMAND_OK) { diff --git a/src/test/examples/testlibpq3.sql b/src/test/examples/testlibpq3.sql index 22133065099..35a95ca347b 100644 --- a/src/test/examples/testlibpq3.sql +++ b/src/test/examples/testlibpq3.sql @@ -1,5 +1,6 @@ CREATE SCHEMA testlibpq3; SET search_path = testlibpq3; +SET standard_conforming_strings = ON; CREATE TABLE test1 (i int4, t text, b bytea); -INSERT INTO test1 values (1, 'joe''s place', '\\000\\001\\002\\003\\004'); -INSERT INTO test1 values (2, 'ho there', '\\004\\003\\002\\001\\000'); +INSERT INTO test1 values (1, 'joe''s place', '\000\001\002\003\004'); +INSERT INTO test1 values (2, 'ho there', '\004\003\002\001\000'); diff --git a/src/test/examples/testlibpq4.c b/src/test/examples/testlibpq4.c index a20f6249b4e..df8e454b5df 100644 --- a/src/test/examples/testlibpq4.c +++ b/src/test/examples/testlibpq4.c @@ -34,10 +34,10 @@ check_prepare_conn(PGconn *conn, const char *dbName) exit(1); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); diff --git a/src/test/examples/testlo.c b/src/test/examples/testlo.c index be5c72b9a67..a0c442a549d 100644 --- a/src/test/examples/testlo.c +++ b/src/test/examples/testlo.c @@ -3,7 +3,7 @@ * testlo.c * test using large objects with libpq * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -232,10 +232,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); diff --git a/src/test/examples/testlo64.c b/src/test/examples/testlo64.c index 39ba009c523..915aa70c862 100644 --- a/src/test/examples/testlo64.c +++ b/src/test/examples/testlo64.c @@ -3,7 +3,7 @@ * testlo64.c * test using large objects with libpq using 64-bit APIs * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * @@ -256,10 +256,10 @@ main(int argc, char **argv) exit_nicely(conn); } - /* Set always-secure search path, so malicous users can't take control. */ + /* Set always-secure search path, so malicious users can't take control. */ res = PQexec(conn, "SELECT pg_catalog.set_config('search_path', '', false)"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "SET failed: %s", PQerrorMessage(conn)); PQclear(res); diff --git a/src/test/isolation/Makefile b/src/test/isolation/Makefile index c3c8280ea23..dc22e5ca9d4 100644 --- a/src/test/isolation/Makefile +++ b/src/test/isolation/Makefile @@ -55,7 +55,7 @@ installcheck: all check: all $(pg_isolation_regress_check) --schedule=$(srcdir)/isolation_schedule -# Versions of the check tests that include the prepared_transactions test +# Versions of the check tests that include the prepared-transactions test # It only makes sense to run these if set up to use prepared transactions, # via TEMP_CONFIG for the check case, or via the postgresql.conf for the # installcheck case. diff --git a/src/test/isolation/README b/src/test/isolation/README index bea278a856f..780b6dca1b8 100644 --- a/src/test/isolation/README +++ b/src/test/isolation/README @@ -108,8 +108,8 @@ Each step may contain commands that block until further action has been taken deadlock). A test that uses this ability must manually specify valid permutations, i.e. those that would not expect a blocked session to execute a command. If a test fails to follow that rule, isolationtester will cancel it -after 60 seconds. If the cancel doesn't work, isolationtester will exit -uncleanly after a total of 75 seconds of wait time. Testing invalid +after 180 seconds. If the cancel doesn't work, isolationtester will exit +uncleanly after a total of 200 seconds of wait time. Testing invalid permutations should be avoided because they can make the isolation tests take a very long time to run, and they serve no useful testing purpose. diff --git a/src/test/isolation/expected/async-notify.out b/src/test/isolation/expected/async-notify.out index 92d281a7d1f..7ad26b7d8f2 100644 --- a/src/test/isolation/expected/async-notify.out +++ b/src/test/isolation/expected/async-notify.out @@ -1,17 +1,100 @@ Parsed test spec with 2 sessions -starting permutation: listen begin check notify check -step listen: LISTEN a; -step begin: BEGIN; -step check: SELECT pg_notification_queue_usage() > 0 AS nonzero; +starting permutation: listenc notify1 notify2 notify3 notifyf +step listenc: LISTEN c1; LISTEN c2; +step notify1: NOTIFY c1; +notifier: NOTIFY "c1" with payload "" from notifier +step notify2: NOTIFY c2, 'payload'; +notifier: NOTIFY "c2" with payload "payload" from notifier +step notify3: NOTIFY c3, 'payload3'; +step notifyf: SELECT pg_notify('c2', NULL); +pg_notify + + +notifier: NOTIFY "c2" with payload "" from notifier + +starting permutation: listenc notifyd1 notifyd2 notifys1 +step listenc: LISTEN c1; LISTEN c2; +step notifyd1: NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; +notifier: NOTIFY "c2" with payload "payload" from notifier +notifier: NOTIFY "c1" with payload "" from notifier +step notifyd2: NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; +notifier: NOTIFY "c1" with payload "" from notifier +notifier: NOTIFY "c1" with payload "p1" from notifier +notifier: NOTIFY "c1" with payload "p2" from notifier +step notifys1: + BEGIN; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + SAVEPOINT s1; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads'; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads'; + RELEASE SAVEPOINT s1; + SAVEPOINT s2; + NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload'; + NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads'; + NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload'; + NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads'; + ROLLBACK TO SAVEPOINT s2; + COMMIT; + +notifier: NOTIFY "c1" with payload "payload" from notifier +notifier: NOTIFY "c2" with payload "payload" from notifier +notifier: NOTIFY "c1" with payload "payloads" from notifier +notifier: NOTIFY "c2" with payload "payloads" from notifier + +starting permutation: llisten notify1 notify2 notify3 notifyf lcheck +step llisten: LISTEN c1; LISTEN c2; +step notify1: NOTIFY c1; +step notify2: NOTIFY c2, 'payload'; +step notify3: NOTIFY c3, 'payload3'; +step notifyf: SELECT pg_notify('c2', NULL); +pg_notify + + +step lcheck: SELECT 1 AS x; +x + +1 +listener: NOTIFY "c1" with payload "" from notifier +listener: NOTIFY "c2" with payload "payload" from notifier +listener: NOTIFY "c2" with payload "" from notifier + +starting permutation: listenc llisten notify1 notify2 notify3 notifyf lcheck +step listenc: LISTEN c1; LISTEN c2; +step llisten: LISTEN c1; LISTEN c2; +step notify1: NOTIFY c1; +notifier: NOTIFY "c1" with payload "" from notifier +step notify2: NOTIFY c2, 'payload'; +notifier: NOTIFY "c2" with payload "payload" from notifier +step notify3: NOTIFY c3, 'payload3'; +step notifyf: SELECT pg_notify('c2', NULL); +pg_notify + + +notifier: NOTIFY "c2" with payload "" from notifier +step lcheck: SELECT 1 AS x; +x + +1 +listener: NOTIFY "c1" with payload "" from notifier +listener: NOTIFY "c2" with payload "payload" from notifier +listener: NOTIFY "c2" with payload "" from notifier + +starting permutation: llisten lbegin usage bignotify usage +step llisten: LISTEN c1; LISTEN c2; +step lbegin: BEGIN; +step usage: SELECT pg_notification_queue_usage() > 0 AS nonzero; nonzero f -step notify: SELECT count(pg_notify('a', s::text)) FROM generate_series(1, 1000) s; +step bignotify: SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; count 1000 -step check: SELECT pg_notification_queue_usage() > 0 AS nonzero; +step usage: SELECT pg_notification_queue_usage() > 0 AS nonzero; nonzero t diff --git a/src/test/isolation/expected/deadlock-parallel.out b/src/test/isolation/expected/deadlock-parallel.out new file mode 100644 index 00000000000..cf4d07e6156 --- /dev/null +++ b/src/test/isolation/expected/deadlock-parallel.out @@ -0,0 +1,54 @@ +Parsed test spec with 4 sessions + +starting permutation: d1a1 d2a2 e1l e2l d1a2 d2a1 d1c e1c d2c e2c +step d1a1: SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; +lock_share lock_excl + +1 1 +step d2a2: select lock_share(2,x) FROM bigt LIMIT 1; +lock_share + +1 +step e1l: SELECT lock_excl(1,x) FROM bigt LIMIT 1; +step e2l: SELECT lock_excl(2,x) FROM bigt LIMIT 1; +step d1a2: SET force_parallel_mode = on; + SET parallel_setup_cost = 0; + SET parallel_tuple_cost = 0; + SET min_parallel_table_scan_size = 0; + SET parallel_leader_participation = off; + SET max_parallel_workers_per_gather = 3; + SELECT sum(lock_share(2,x)) FROM bigt; +step d2a1: SET force_parallel_mode = on; + SET parallel_setup_cost = 0; + SET parallel_tuple_cost = 0; + SET min_parallel_table_scan_size = 0; + SET parallel_leader_participation = off; + SET max_parallel_workers_per_gather = 3; + SELECT sum(lock_share(1,x)) FROM bigt; + SET force_parallel_mode = off; + RESET parallel_setup_cost; + RESET parallel_tuple_cost; + SELECT lock_share(3,x) FROM bigt LIMIT 1; +step d1a2: <... completed> +sum + +10000 +step d1c: COMMIT; +step e1l: <... completed> +lock_excl + +1 +step d2a1: <... completed> +sum + +10000 +lock_share + +1 +step e1c: COMMIT; +step d2c: COMMIT; +step e2l: <... completed> +lock_excl + +1 +step e2c: COMMIT; diff --git a/src/test/isolation/expected/eval-plan-qual.out b/src/test/isolation/expected/eval-plan-qual.out index fed01459cf0..65d3a5f0ae4 100644 --- a/src/test/isolation/expected/eval-plan-qual.out +++ b/src/test/isolation/expected/eval-plan-qual.out @@ -1,10 +1,16 @@ Parsed test spec with 3 sessions starting permutation: wx1 wx2 c1 c2 read -step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; -step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; step c1: COMMIT; step wx2: <... completed> +balance + +850 step c2: COMMIT; step read: SELECT * FROM accounts ORDER BY accountid; accountid balance @@ -13,10 +19,15 @@ checking 850 savings 600 starting permutation: wy1 wy2 c1 c2 read -step wy1: UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking'; -step wy2: UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000; +step wy1: UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking' RETURNING balance; +balance + +1100 +step wy2: UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000 RETURNING balance; step c1: COMMIT; step wy2: <... completed> +balance + step c2: COMMIT; step read: SELECT * FROM accounts ORDER BY accountid; accountid balance @@ -24,6 +35,563 @@ accountid balance checking 1100 savings 600 +starting permutation: wx1 wx2 r1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +step r1: ROLLBACK; +step wx2: <... completed> +balance + +1050 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1050 +savings 600 + +starting permutation: wy1 wy2 r1 c2 read +step wy1: UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking' RETURNING balance; +balance + +1100 +step wy2: UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000 RETURNING balance; +step r1: ROLLBACK; +step wy2: <... completed> +balance + +1600 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1600 +savings 600 + +starting permutation: wx1 d1 wx2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +balance + +400 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +step c1: COMMIT; +step wx2: <... completed> +balance + +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: wx2 d1 c2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step c2: COMMIT; +step d1: <... completed> +balance + +1050 +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: wx2 wx2 d1 c2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1500 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step c2: COMMIT; +step d1: <... completed> +balance + +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1500 +savings 600 + +starting permutation: wx2 d2 d1 c2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step d2: DELETE FROM accounts WHERE accountid = 'checking'; +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step c2: COMMIT; +step d1: <... completed> +balance + +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: wx1 d1 wx2 r1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +balance + +400 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +step r1: ROLLBACK; +step wx2: <... completed> +balance + +1050 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1050 +savings 600 + +starting permutation: wx2 d1 r2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step r2: ROLLBACK; +step d1: <... completed> +balance + +600 +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: wx2 wx2 d1 r2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1500 +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step r2: ROLLBACK; +step d1: <... completed> +balance + +600 +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: wx2 d2 d1 r2 c1 read +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 +step d2: DELETE FROM accounts WHERE accountid = 'checking'; +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +step r2: ROLLBACK; +step d1: <... completed> +balance + +600 +step c1: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: d1 wx2 c1 c2 read +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +balance + +600 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +step c1: COMMIT; +step wx2: <... completed> +balance + +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +savings 600 + +starting permutation: d1 wx2 r1 c2 read +step d1: DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; +balance + +600 +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +step r1: ROLLBACK; +step wx2: <... completed> +balance + +1050 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1050 +savings 600 + +starting permutation: wnested2 c1 c2 read +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +s2: NOTICE: upid: text savings = text checking: f +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking -600 +savings 600 + +starting permutation: wx1 wxext1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 400 > numeric 200.0: t +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 400 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 400 > numeric 200.0: t +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking -800 +savings 600 + +starting permutation: wx1 wx1 wxext1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +200 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 400 > numeric 200.0: t +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 200 > numeric 200.0: f +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 200 +savings 600 + +starting permutation: wx1 wx1 wxext1 wxext1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +200 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +200 +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 200 > numeric 200.0: f +s2: NOTICE: lock_id: text savings = text checking: f +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 200 +savings 600 + +starting permutation: wx1 wxext1 wxext1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step wxext1: UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +200 +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 200 > numeric 200.0: f +s2: NOTICE: lock_id: text savings = text checking: f +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 400 +savings 600 + +starting permutation: wx1 tocds1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step tocds1: UPDATE accounts SET accountid = 'cds' WHERE accountid = 'checking'; +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: upid: text cds = text checking: f +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +cds 400 +savings 600 + +starting permutation: wx1 tocdsext1 wnested2 c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step tocdsext1: UPDATE accounts_ext SET accountid = 'cds' WHERE accountid = 'checking'; +s2: NOTICE: upid: text checking = text checking: t +s2: NOTICE: up: numeric 600 > numeric 200.0: t +s2: NOTICE: lock_id: text checking = text checking: t +s2: NOTICE: lock_bal: numeric 600 > numeric 200.0: t +step wnested2: + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); + +step c1: COMMIT; +s2: NOTICE: lock_id: text cds = text checking: f +s2: NOTICE: lock_id: text savings = text checking: f +s2: NOTICE: upid: text savings = text checking: f +step wnested2: <... completed> +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 400 +savings 600 + +starting permutation: wx1 updwcte c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step updwcte: WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; +step c1: COMMIT; +step updwcte: <... completed> +accountid balance accountid balance + +savings 1600 checking 1500 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1500 +savings 1600 + +starting permutation: wx1 updwctefail c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step updwctefail: WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; +step c1: COMMIT; +step updwctefail: <... completed> +error in steps c1 updwctefail: ERROR: tuple to be updated was already modified by an operation triggered by the current command +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 400 +savings 600 + +starting permutation: wx1 delwcte c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step delwcte: WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) DELETE FROM accounts a USING doup RETURNING *; +step c1: COMMIT; +step delwcte: <... completed> +accountid balance accountid balance + +savings 600 checking 1500 +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 1500 + +starting permutation: wx1 delwctefail c1 c2 read +step wx1: UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; +balance + +400 +step delwctefail: WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) DELETE FROM accounts a USING doup RETURNING *; +step c1: COMMIT; +step delwctefail: <... completed> +error in steps c1 delwctefail: ERROR: tuple to be deleted was already modified by an operation triggered by the current command +step c2: COMMIT; +step read: SELECT * FROM accounts ORDER BY accountid; +accountid balance + +checking 400 +savings 600 + starting permutation: upsert1 upsert2 c1 c2 read step upsert1: WITH upsert AS @@ -106,7 +674,10 @@ a b c step c2: COMMIT; starting permutation: wx2 partiallock c2 c1 read -step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 step partiallock: SELECT * FROM accounts a1, accounts a2 WHERE a1.accountid = a2.accountid @@ -126,10 +697,15 @@ checking 1050 savings 600 starting permutation: wx2 lockwithvalues c2 c1 read -step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; +step wx2: UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; +balance + +1050 step lockwithvalues: - SELECT * FROM accounts a1, (values('checking'),('savings')) v(id) - WHERE a1.accountid = v.id + -- Reference rowmark column that differs in type from targetlist at some attno. + -- See CAHU7rYZo_C4ULsAx_LAj8az9zqgrD8WDd4hTegDTMM1LMqrBsg@mail.gmail.com + SELECT a1.*, v.id FROM accounts a1, (values('checking'::text, 'nan'::text),('savings', 'nan')) v(id, notnumeric) + WHERE a1.accountid = v.id AND v.notnumeric != 'einszwei' FOR UPDATE OF a1; step c2: COMMIT; @@ -145,6 +721,26 @@ accountid balance checking 1050 savings 600 +starting permutation: wx2_ext partiallock_ext c2 c1 read_ext +step wx2_ext: UPDATE accounts_ext SET balance = balance + 450; +step partiallock_ext: + SELECT * FROM accounts_ext a1, accounts_ext a2 + WHERE a1.accountid = a2.accountid + FOR UPDATE OF a1; + +step c2: COMMIT; +step partiallock_ext: <... completed> +accountid balance other newcol newcol2 accountid balance other newcol newcol2 + +checking 1050 other 42 checking 600 other 42 +savings 1150 42 savings 700 42 +step c1: COMMIT; +step read_ext: SELECT * FROM accounts_ext ORDER BY accountid; +accountid balance other newcol newcol2 + +checking 1050 other 42 +savings 1150 42 + starting permutation: updateforss readforss c1 c2 step updateforss: UPDATE table_a SET value = 'newTableAValue' WHERE id = 1; @@ -164,6 +760,37 @@ ta_id ta_value tb_row 1 newTableAValue (1,tableBValue) step c2: COMMIT; +starting permutation: updateforcip updateforcip2 c1 c2 read_a +step updateforcip: + UPDATE table_a SET value = NULL WHERE id = 1; + +step updateforcip2: + UPDATE table_a SET value = COALESCE(value, (SELECT text 'newValue')) WHERE id = 1; + +step c1: COMMIT; +step updateforcip2: <... completed> +step c2: COMMIT; +step read_a: SELECT * FROM table_a ORDER BY id; +id value + +1 newValue + +starting permutation: updateforcip updateforcip3 c1 c2 read_a +step updateforcip: + UPDATE table_a SET value = NULL WHERE id = 1; + +step updateforcip3: + WITH d(val) AS (SELECT text 'newValue' FROM generate_series(1,1)) + UPDATE table_a SET value = COALESCE(value, (SELECT val FROM d)) WHERE id = 1; + +step c1: COMMIT; +step updateforcip3: <... completed> +step c2: COMMIT; +step read_a: SELECT * FROM table_a ORDER BY id; +id value + +1 newValue + starting permutation: wrtwcte readwcte c1 c2 step wrtwcte: UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; step readwcte: @@ -188,9 +815,9 @@ id value starting permutation: wrjt selectjoinforupdate c2 c1 step wrjt: UPDATE jointest SET data = 42 WHERE id = 7; step selectjoinforupdate: - set enable_nestloop to 0; - set enable_hashjoin to 0; - set enable_seqscan to 0; + set local enable_nestloop to 0; + set local enable_hashjoin to 0; + set local enable_seqscan to 0; explain (costs off) select * from jointest a join jointest b on a.id=b.id for update; select * from jointest a join jointest b on a.id=b.id for update; @@ -218,6 +845,45 @@ id data id data 10 0 10 0 step c1: COMMIT; +starting permutation: wrjt selectresultforupdate c2 c1 +step wrjt: UPDATE jointest SET data = 42 WHERE id = 7; +step selectresultforupdate: + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y; + explain (verbose, costs off) + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y for update of jt, ss1, ss2; + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y for update of jt, ss1, ss2; + +step c2: COMMIT; +step selectresultforupdate: <... completed> +x y id value id data + +1 7 1 tableAValue 7 0 +QUERY PLAN + +LockRows + Output: 1, 7, a.id, a.value, jt.id, jt.data, jt.ctid, a.ctid + -> Nested Loop Left Join + Output: 1, 7, a.id, a.value, jt.id, jt.data, jt.ctid, a.ctid + -> Nested Loop + Output: jt.id, jt.data, jt.ctid + -> Seq Scan on public.jointest jt + Output: jt.id, jt.data, jt.ctid + Filter: (jt.id = 7) + -> Result + -> Seq Scan on public.table_a a + Output: a.id, a.value, a.ctid + Filter: (a.id = 1) +x y id value id data + +1 7 1 tableAValue 7 42 +step c1: COMMIT; + starting permutation: wrtwcte multireadwcte c1 c2 step wrtwcte: UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; step multireadwcte: @@ -232,3 +898,67 @@ step multireadwcte: <... completed> subid id 1 1 + +starting permutation: simplepartupdate complexpartupdate c1 c2 +step simplepartupdate: + update parttbl set a = a; + +step complexpartupdate: + with u as (update parttbl set a = a returning parttbl.*) + update parttbl set a = u.a from u; + +step c1: COMMIT; +step complexpartupdate: <... completed> +step c2: COMMIT; + +starting permutation: simplepartupdate_route1to2 complexpartupdate_route_err1 c1 c2 +step simplepartupdate_route1to2: + update parttbl set a = 2 where c = 1 returning *; + +a b c + +2 1 1 +step complexpartupdate_route_err1: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = u.a from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_route_err1: <... completed> +error in steps c1 complexpartupdate_route_err1: ERROR: tuple to be locked was already moved to another partition due to concurrent update +step c2: COMMIT; + +starting permutation: simplepartupdate_noroute complexpartupdate_route c1 c2 +step simplepartupdate_noroute: + update parttbl set b = 2 where c = 1 returning *; + +a b c + +1 2 1 +step complexpartupdate_route: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = p.b from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_route: <... completed> +a b c + +2 2 1 +step c2: COMMIT; + +starting permutation: simplepartupdate_noroute complexpartupdate_doesnt_route c1 c2 +step simplepartupdate_noroute: + update parttbl set b = 2 where c = 1 returning *; + +a b c + +1 2 1 +step complexpartupdate_doesnt_route: + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = 3 - p.b from u where p.a = u.a and p.c = 1 returning p.*; + +step c1: COMMIT; +step complexpartupdate_doesnt_route: <... completed> +a b c + +1 2 1 +step c2: COMMIT; diff --git a/src/test/isolation/expected/fk-partitioned-1.out b/src/test/isolation/expected/fk-partitioned-1.out new file mode 100644 index 00000000000..aea2b6d56b4 --- /dev/null +++ b/src/test/isolation/expected/fk-partitioned-1.out @@ -0,0 +1,133 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s1d s1c s2b s2a s2c +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s1c: commit; +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s1d s2b s1c s2a s2c +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s2b: begin; +step s1c: commit; +step s2a: alter table pfk attach partition pfk1 for values in (1); +ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s1d s2b s2a s1c s2c +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1c: commit; +step s2a: <... completed> +error in steps s1c s2a: ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s2b s1d s1c s2a s2c +step s1b: begin; +step s2b: begin; +step s1d: delete from ppk1 where a = 1; +step s1c: commit; +step s2a: alter table pfk attach partition pfk1 for values in (1); +ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s2b s1d s2a s1c s2c +step s1b: begin; +step s2b: begin; +step s1d: delete from ppk1 where a = 1; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1c: commit; +step s2a: <... completed> +error in steps s1c s2a: ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s2b s2a s1d s2c s1c +step s1b: begin; +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1d: delete from ppk1 where a = 1; +step s2c: commit; +step s1d: <... completed> +error in steps s2c s1d: ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s1b s2b s2a s2c s1d s1c +step s1b: begin; +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s2c: commit; +step s1d: delete from ppk1 where a = 1; +ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s2b s1b s1d s1c s2a s2c +step s2b: begin; +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s1c: commit; +step s2a: alter table pfk attach partition pfk1 for values in (1); +ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s2b s1b s1d s2a s1c s2c +step s2b: begin; +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1c: commit; +step s2a: <... completed> +error in steps s1c s2a: ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s2b s1b s2a s1d s2c s1c +step s2b: begin; +step s1b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1d: delete from ppk1 where a = 1; +step s2c: commit; +step s1d: <... completed> +error in steps s2c s1d: ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s2b s1b s2a s2c s1d s1c +step s2b: begin; +step s1b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s2c: commit; +step s1d: delete from ppk1 where a = 1; +ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s2b s2a s1b s1d s2c s1c +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +step s2c: commit; +step s1d: <... completed> +error in steps s2c s1d: ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s2b s2a s1b s2c s1d s1c +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s1b: begin; +step s2c: commit; +step s1d: delete from ppk1 where a = 1; +ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s2b s2a s2c s1b s1d s1c +step s2b: begin; +step s2a: alter table pfk attach partition pfk1 for values in (1); +step s2c: commit; +step s1b: begin; +step s1d: delete from ppk1 where a = 1; +ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; diff --git a/src/test/isolation/expected/fk-partitioned-2.out b/src/test/isolation/expected/fk-partitioned-2.out new file mode 100644 index 00000000000..722b615c6ea --- /dev/null +++ b/src/test/isolation/expected/fk-partitioned-2.out @@ -0,0 +1,70 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s1d s2b s2i s1c s2c +step s1b: begin; +step s1d: delete from ppk where a = 1; +step s2b: begin; +step s2i: insert into pfk values (1); +step s1c: commit; +step s2i: <... completed> +error in steps s1c s2i: ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s1d s2bs s2i s1c s2c +step s1b: begin; +step s1d: delete from ppk where a = 1; +step s2bs: begin isolation level serializable; select 1; +?column? + +1 +step s2i: insert into pfk values (1); +step s1c: commit; +step s2i: <... completed> +error in steps s1c s2i: ERROR: could not serialize access due to concurrent update +step s2c: commit; + +starting permutation: s1b s2b s1d s2i s1c s2c +step s1b: begin; +step s2b: begin; +step s1d: delete from ppk where a = 1; +step s2i: insert into pfk values (1); +step s1c: commit; +step s2i: <... completed> +error in steps s1c s2i: ERROR: insert or update on table "pfk1" violates foreign key constraint "pfk_a_fkey" +step s2c: commit; + +starting permutation: s1b s2bs s1d s2i s1c s2c +step s1b: begin; +step s2bs: begin isolation level serializable; select 1; +?column? + +1 +step s1d: delete from ppk where a = 1; +step s2i: insert into pfk values (1); +step s1c: commit; +step s2i: <... completed> +error in steps s1c s2i: ERROR: could not serialize access due to concurrent update +step s2c: commit; + +starting permutation: s1b s2b s2i s1d s2c s1c +step s1b: begin; +step s2b: begin; +step s2i: insert into pfk values (1); +step s1d: delete from ppk where a = 1; +step s2c: commit; +step s1d: <... completed> +error in steps s2c s1d: ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; + +starting permutation: s1b s2bs s2i s1d s2c s1c +step s1b: begin; +step s2bs: begin isolation level serializable; select 1; +?column? + +1 +step s2i: insert into pfk values (1); +step s1d: delete from ppk where a = 1; +step s2c: commit; +step s1d: <... completed> +error in steps s2c s1d: ERROR: update or delete on table "ppk1" violates foreign key constraint "pfk_a_fkey1" on table "pfk" +step s1c: commit; diff --git a/src/test/isolation/expected/inherit-temp.out b/src/test/isolation/expected/inherit-temp.out new file mode 100644 index 00000000000..edfc8f906cb --- /dev/null +++ b/src/test/isolation/expected/inherit-temp.out @@ -0,0 +1,217 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_select_p: SELECT a FROM inh_parent; +a + +1 +2 +3 +4 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +3 +4 +step s2_select_p: SELECT a FROM inh_parent; +a + +1 +2 +5 +6 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 +6 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_update_p s1_update_c s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_update_p: UPDATE inh_parent SET a = 11 WHERE a = 1; +step s1_update_c: UPDATE inh_parent SET a = 13 WHERE a IN (3, 5); +step s1_select_p: SELECT a FROM inh_parent; +a + +2 +11 +4 +13 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +4 +13 +step s2_select_p: SELECT a FROM inh_parent; +a + +2 +11 +5 +6 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 +6 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s2_update_c s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s2_update_c: UPDATE inh_parent SET a = 15 WHERE a IN (3, 5); +step s1_select_p: SELECT a FROM inh_parent; +a + +1 +2 +3 +4 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +3 +4 +step s2_select_p: SELECT a FROM inh_parent; +a + +1 +2 +6 +15 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +6 +15 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_delete_p s1_delete_c s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_delete_p: DELETE FROM inh_parent WHERE a = 2; +step s1_delete_c: DELETE FROM inh_parent WHERE a IN (4, 6); +step s1_select_p: SELECT a FROM inh_parent; +a + +1 +3 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +3 +step s2_select_p: SELECT a FROM inh_parent; +a + +1 +5 +6 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 +6 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s2_delete_c s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s2_delete_c: DELETE FROM inh_parent WHERE a IN (4, 6); +step s1_select_p: SELECT a FROM inh_parent; +a + +1 +2 +3 +4 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +3 +4 +step s2_select_p: SELECT a FROM inh_parent; +a + +1 +2 +5 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_truncate_p s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_truncate_p: TRUNCATE inh_parent; +step s1_select_p: SELECT a FROM inh_parent; +a + +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +step s2_select_p: SELECT a FROM inh_parent; +a + +5 +6 +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 +6 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s2_truncate_p s1_select_p s1_select_c s2_select_p s2_select_c +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s2_truncate_p: TRUNCATE inh_parent; +step s1_select_p: SELECT a FROM inh_parent; +a + +3 +4 +step s1_select_c: SELECT a FROM inh_temp_child_s1; +a + +3 +4 +step s2_select_p: SELECT a FROM inh_parent; +a + +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_begin s1_truncate_p s2_select_p s1_commit +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_begin: BEGIN; +step s1_truncate_p: TRUNCATE inh_parent; +step s2_select_p: SELECT a FROM inh_parent; +step s1_commit: COMMIT; +step s2_select_p: <... completed> +a + +5 +6 + +starting permutation: s1_insert_p s1_insert_c s2_insert_c s1_begin s1_truncate_p s2_select_c s1_commit +step s1_insert_p: INSERT INTO inh_parent VALUES (1), (2); +step s1_insert_c: INSERT INTO inh_temp_child_s1 VALUES (3), (4); +step s2_insert_c: INSERT INTO inh_temp_child_s2 VALUES (5), (6); +step s1_begin: BEGIN; +step s1_truncate_p: TRUNCATE inh_parent; +step s2_select_c: SELECT a FROM inh_temp_child_s2; +a + +5 +6 +step s1_commit: COMMIT; diff --git a/src/test/isolation/expected/insert-conflict-specconflict.out b/src/test/isolation/expected/insert-conflict-specconflict.out new file mode 100644 index 00000000000..20cc421b872 --- /dev/null +++ b/src/test/isolation/expected/insert-conflict-specconflict.out @@ -0,0 +1,217 @@ +Parsed test spec with 3 sessions + +starting permutation: controller_locks controller_show s1_upsert s2_upsert controller_show controller_unlock_1_1 controller_unlock_2_1 controller_unlock_1_3 controller_unlock_2_3 controller_show controller_unlock_2_2 controller_show controller_unlock_1_2 controller_show +step controller_locks: SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock); +pg_advisory_locksess lock + + 1 1 + 1 2 + 1 3 + 2 1 + 2 2 + 2 3 +step controller_show: SELECT * FROM upserttest; +key data + +s1: NOTICE: called for k1 +s1: NOTICE: blocking 3 +step s1_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; +s2: NOTICE: called for k1 +s2: NOTICE: blocking 3 +step s2_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_1_1: SELECT pg_advisory_unlock(1, 1); +pg_advisory_unlock + +t +step controller_unlock_2_1: SELECT pg_advisory_unlock(2, 1); +pg_advisory_unlock + +t +step controller_unlock_1_3: SELECT pg_advisory_unlock(1, 3); +pg_advisory_unlock + +t +s1: NOTICE: called for k1 +s1: NOTICE: blocking 2 +step controller_unlock_2_3: SELECT pg_advisory_unlock(2, 3); +pg_advisory_unlock + +t +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_2_2: SELECT pg_advisory_unlock(2, 2); +pg_advisory_unlock + +t +step s2_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s2 +step controller_unlock_1_2: SELECT pg_advisory_unlock(1, 2); +pg_advisory_unlock + +t +s1: NOTICE: called for k1 +s1: NOTICE: blocking 2 +s1: NOTICE: called for k1 +s1: NOTICE: blocking 2 +step s1_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s2 with conflict update s1 + +starting permutation: controller_locks controller_show s1_upsert s2_upsert controller_show controller_unlock_1_1 controller_unlock_2_1 controller_unlock_1_3 controller_unlock_2_3 controller_show controller_unlock_1_2 controller_show controller_unlock_2_2 controller_show +step controller_locks: SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock); +pg_advisory_locksess lock + + 1 1 + 1 2 + 1 3 + 2 1 + 2 2 + 2 3 +step controller_show: SELECT * FROM upserttest; +key data + +s1: NOTICE: called for k1 +s1: NOTICE: blocking 3 +step s1_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; +s2: NOTICE: called for k1 +s2: NOTICE: blocking 3 +step s2_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_1_1: SELECT pg_advisory_unlock(1, 1); +pg_advisory_unlock + +t +step controller_unlock_2_1: SELECT pg_advisory_unlock(2, 1); +pg_advisory_unlock + +t +step controller_unlock_1_3: SELECT pg_advisory_unlock(1, 3); +pg_advisory_unlock + +t +s1: NOTICE: called for k1 +s1: NOTICE: blocking 2 +step controller_unlock_2_3: SELECT pg_advisory_unlock(2, 3); +pg_advisory_unlock + +t +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_1_2: SELECT pg_advisory_unlock(1, 2); +pg_advisory_unlock + +t +step s1_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s1 +step controller_unlock_2_2: SELECT pg_advisory_unlock(2, 2); +pg_advisory_unlock + +t +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step s2_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s1 with conflict update s2 + +starting permutation: controller_locks controller_show s1_begin s2_begin s1_upsert s2_upsert controller_show controller_unlock_1_1 controller_unlock_2_1 controller_unlock_1_3 controller_unlock_2_3 controller_show controller_unlock_1_2 controller_show controller_unlock_2_2 controller_show s1_commit controller_show s2_commit controller_show +step controller_locks: SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock); +pg_advisory_locksess lock + + 1 1 + 1 2 + 1 3 + 2 1 + 2 2 + 2 3 +step controller_show: SELECT * FROM upserttest; +key data + +step s1_begin: BEGIN; +step s2_begin: BEGIN; +s1: NOTICE: called for k1 +s1: NOTICE: blocking 3 +step s1_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; +s2: NOTICE: called for k1 +s2: NOTICE: blocking 3 +step s2_upsert: INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_1_1: SELECT pg_advisory_unlock(1, 1); +pg_advisory_unlock + +t +step controller_unlock_2_1: SELECT pg_advisory_unlock(2, 1); +pg_advisory_unlock + +t +step controller_unlock_1_3: SELECT pg_advisory_unlock(1, 3); +pg_advisory_unlock + +t +s1: NOTICE: called for k1 +s1: NOTICE: blocking 2 +step controller_unlock_2_3: SELECT pg_advisory_unlock(2, 3); +pg_advisory_unlock + +t +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_1_2: SELECT pg_advisory_unlock(1, 2); +pg_advisory_unlock + +t +step s1_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +step controller_unlock_2_2: SELECT pg_advisory_unlock(2, 2); +pg_advisory_unlock + +t +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step controller_show: SELECT * FROM upserttest; +key data + +step s1_commit: COMMIT; +s2: NOTICE: called for k1 +s2: NOTICE: blocking 2 +step s2_upsert: <... completed> +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s1 +step s2_commit: COMMIT; +step controller_show: SELECT * FROM upserttest; +key data + +k1 inserted s1 with conflict update s2 diff --git a/src/test/isolation/expected/merge-delete.out b/src/test/isolation/expected/merge-delete.out deleted file mode 100644 index 40e62901b70..00000000000 --- a/src/test/isolation/expected/merge-delete.out +++ /dev/null @@ -1,97 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: delete c1 select2 c2 -step delete: DELETE FROM target t WHERE t.key = 1; -step c1: COMMIT; -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: merge_delete c1 select2 c2 -step merge_delete: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; -step c1: COMMIT; -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: delete c1 update1 select2 c2 -step delete: DELETE FROM target t WHERE t.key = 1; -step c1: COMMIT; -step update1: UPDATE target t SET val = t.val || ' updated by update1' WHERE t.key = 1; -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: merge_delete c1 update1 select2 c2 -step merge_delete: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; -step c1: COMMIT; -step update1: UPDATE target t SET val = t.val || ' updated by update1' WHERE t.key = 1; -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: delete c1 merge2 select2 c2 -step delete: DELETE FROM target t WHERE t.key = 1; -step c1: COMMIT; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -step select2: SELECT * FROM target; -key val - -1 merge2a -step c2: COMMIT; - -starting permutation: merge_delete c1 merge2 select2 c2 -step merge_delete: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; -step c1: COMMIT; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -step select2: SELECT * FROM target; -key val - -1 merge2a -step c2: COMMIT; - -starting permutation: delete update1 c1 select2 c2 -step delete: DELETE FROM target t WHERE t.key = 1; -step update1: UPDATE target t SET val = t.val || ' updated by update1' WHERE t.key = 1; -step c1: COMMIT; -step update1: <... completed> -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: merge_delete update1 c1 select2 c2 -step merge_delete: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; -step update1: UPDATE target t SET val = t.val || ' updated by update1' WHERE t.key = 1; -step c1: COMMIT; -step update1: <... completed> -step select2: SELECT * FROM target; -key val - -step c2: COMMIT; - -starting permutation: delete merge2 c1 select2 c2 -step delete: DELETE FROM target t WHERE t.key = 1; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -step c1: COMMIT; -step merge2: <... completed> -step select2: SELECT * FROM target; -key val - -1 merge2a -step c2: COMMIT; - -starting permutation: merge_delete merge2 c1 select2 c2 -step merge_delete: MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -step c1: COMMIT; -step merge2: <... completed> -step select2: SELECT * FROM target; -key val - -1 merge2a -step c2: COMMIT; diff --git a/src/test/isolation/expected/merge-insert-update.out b/src/test/isolation/expected/merge-insert-update.out deleted file mode 100644 index 317fa16a3d5..00000000000 --- a/src/test/isolation/expected/merge-insert-update.out +++ /dev/null @@ -1,84 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: merge1 c1 select2 c2 -step merge1: MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge1'; -step c1: COMMIT; -step select2: SELECT * FROM target; -key val - -1 merge1 -step c2: COMMIT; - -starting permutation: merge1 c1 merge2 select2 c2 -step merge1: MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge1'; -step c1: COMMIT; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step select2: SELECT * FROM target; -key val - -1 merge1 updated by merge2 -step c2: COMMIT; - -starting permutation: insert1 merge2 c1 select2 c2 -step insert1: INSERT INTO target VALUES (1, 'insert1'); -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step c1: COMMIT; -step merge2: <... completed> -error in steps c1 merge2: ERROR: duplicate key value violates unique constraint "target_pkey" -step select2: SELECT * FROM target; -ERROR: current transaction is aborted, commands ignored until end of transaction block -step c2: COMMIT; - -starting permutation: merge1 merge2 c1 select2 c2 -step merge1: MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge1'; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step c1: COMMIT; -step merge2: <... completed> -error in steps c1 merge2: ERROR: duplicate key value violates unique constraint "target_pkey" -step select2: SELECT * FROM target; -ERROR: current transaction is aborted, commands ignored until end of transaction block -step c2: COMMIT; - -starting permutation: merge1 merge2 a1 select2 c2 -step merge1: MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge1'; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step a1: ABORT; -step merge2: <... completed> -step select2: SELECT * FROM target; -key val - -1 merge2 -step c2: COMMIT; - -starting permutation: delete1 insert1 c1 merge2 select2 c2 -step delete1: DELETE FROM target WHERE key = 1; -step insert1: INSERT INTO target VALUES (1, 'insert1'); -step c1: COMMIT; -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step select2: SELECT * FROM target; -key val - -1 insert1 updated by merge2 -step c2: COMMIT; - -starting permutation: delete1 insert1 merge2 c1 select2 c2 -step delete1: DELETE FROM target WHERE key = 1; -step insert1: INSERT INTO target VALUES (1, 'insert1'); -step merge2: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step c1: COMMIT; -step merge2: <... completed> -error in steps c1 merge2: ERROR: duplicate key value violates unique constraint "target_pkey" -step select2: SELECT * FROM target; -ERROR: current transaction is aborted, commands ignored until end of transaction block -step c2: COMMIT; - -starting permutation: delete1 insert1 merge2i c1 select2 c2 -step delete1: DELETE FROM target WHERE key = 1; -step insert1: INSERT INTO target VALUES (1, 'insert1'); -step merge2i: MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; -step c1: COMMIT; -step select2: SELECT * FROM target; -key val - -1 insert1 -step c2: COMMIT; diff --git a/src/test/isolation/expected/merge-match-recheck.out b/src/test/isolation/expected/merge-match-recheck.out deleted file mode 100644 index 96a9f45ac88..00000000000 --- a/src/test/isolation/expected/merge-match-recheck.out +++ /dev/null @@ -1,106 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: update1 merge_status c2 select1 c1 -step update1: UPDATE target t SET balance = balance + 10, val = t.val || ' updated by update1' WHERE t.key = 1; -step merge_status: - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND status = 's1' THEN - UPDATE SET status = 's2', val = t.val || ' when1' - WHEN MATCHED AND status = 's2' THEN - UPDATE SET status = 's3', val = t.val || ' when2' - WHEN MATCHED AND status = 's3' THEN - UPDATE SET status = 's4', val = t.val || ' when3'; - -step c2: COMMIT; -step merge_status: <... completed> -step select1: SELECT * FROM target; -key balance status val - -1 170 s2 setup updated by update1 when1 -step c1: COMMIT; - -starting permutation: update2 merge_status c2 select1 c1 -step update2: UPDATE target t SET status = 's2', val = t.val || ' updated by update2' WHERE t.key = 1; -step merge_status: - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND status = 's1' THEN - UPDATE SET status = 's2', val = t.val || ' when1' - WHEN MATCHED AND status = 's2' THEN - UPDATE SET status = 's3', val = t.val || ' when2' - WHEN MATCHED AND status = 's3' THEN - UPDATE SET status = 's4', val = t.val || ' when3'; - -step c2: COMMIT; -step merge_status: <... completed> -step select1: SELECT * FROM target; -key balance status val - -1 160 s3 setup updated by update2 when2 -step c1: COMMIT; - -starting permutation: update3 merge_status c2 select1 c1 -step update3: UPDATE target t SET status = 's3', val = t.val || ' updated by update3' WHERE t.key = 1; -step merge_status: - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND status = 's1' THEN - UPDATE SET status = 's2', val = t.val || ' when1' - WHEN MATCHED AND status = 's2' THEN - UPDATE SET status = 's3', val = t.val || ' when2' - WHEN MATCHED AND status = 's3' THEN - UPDATE SET status = 's4', val = t.val || ' when3'; - -step c2: COMMIT; -step merge_status: <... completed> -step select1: SELECT * FROM target; -key balance status val - -1 160 s4 setup updated by update3 when3 -step c1: COMMIT; - -starting permutation: update5 merge_status c2 select1 c1 -step update5: UPDATE target t SET status = 's5', val = t.val || ' updated by update5' WHERE t.key = 1; -step merge_status: - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND status = 's1' THEN - UPDATE SET status = 's2', val = t.val || ' when1' - WHEN MATCHED AND status = 's2' THEN - UPDATE SET status = 's3', val = t.val || ' when2' - WHEN MATCHED AND status = 's3' THEN - UPDATE SET status = 's4', val = t.val || ' when3'; - -step c2: COMMIT; -step merge_status: <... completed> -step select1: SELECT * FROM target; -key balance status val - -1 160 s5 setup updated by update5 -step c1: COMMIT; - -starting permutation: update_bal1 merge_bal c2 select1 c1 -step update_bal1: UPDATE target t SET balance = 50, val = t.val || ' updated by update_bal1' WHERE t.key = 1; -step merge_bal: - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND balance < 100 THEN - UPDATE SET balance = balance * 2, val = t.val || ' when1' - WHEN MATCHED AND balance < 200 THEN - UPDATE SET balance = balance * 4, val = t.val || ' when2' - WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; - -step c2: COMMIT; -step merge_bal: <... completed> -step select1: SELECT * FROM target; -key balance status val - -1 100 s1 setup updated by update_bal1 when1 -step c1: COMMIT; diff --git a/src/test/isolation/expected/merge-update.out b/src/test/isolation/expected/merge-update.out deleted file mode 100644 index 00069a3e459..00000000000 --- a/src/test/isolation/expected/merge-update.out +++ /dev/null @@ -1,238 +0,0 @@ -Parsed test spec with 2 sessions - -starting permutation: merge1 c1 select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge1 -step c2: COMMIT; - -starting permutation: merge1 c1 merge2a select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step merge2a: - MERGE INTO target t - USING (SELECT 1 as key, 'merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge1 -1 merge2a -step c2: COMMIT; - -starting permutation: merge1 merge2a c1 select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step merge2a: - MERGE INTO target t - USING (SELECT 1 as key, 'merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step merge2a: <... completed> -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge1 -1 merge2a -step c2: COMMIT; - -starting permutation: merge1 merge2a a1 select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step merge2a: - MERGE INTO target t - USING (SELECT 1 as key, 'merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step a1: ABORT; -step merge2a: <... completed> -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge2a -step c2: COMMIT; - -starting permutation: merge1 merge2b c1 select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step merge2b: - MERGE INTO target t - USING (SELECT 1 as key, 'merge2b' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED AND t.key < 2 THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step merge2b: <... completed> -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge1 -1 merge2b -step c2: COMMIT; - -starting permutation: merge1 merge2c c1 select2 c2 -step merge1: - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step merge2c: - MERGE INTO target t - USING (SELECT 1 as key, 'merge2c' as val) s - ON s.key = t.key AND t.key < 2 - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step merge2c: <... completed> -step select2: SELECT * FROM target; -key val - -2 setup1 updated by merge1 -1 merge2c -step c2: COMMIT; - -starting permutation: pa_merge1 pa_merge2a c1 pa_select2 c2 -step pa_merge1: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set val = t.val || ' updated by ' || s.val; - -step pa_merge2a: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step pa_merge2a: <... completed> -step pa_select2: SELECT * FROM pa_target; -key val - -2 initial -2 initial updated by pa_merge2a -step c2: COMMIT; - -starting permutation: pa_merge2 pa_merge2a c1 pa_select2 c2 -step pa_merge2: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step pa_merge2a: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step pa_merge2a: <... completed> -error in steps c1 pa_merge2a: ERROR: tuple to be deleted was already moved to another partition due to concurrent update -step pa_select2: SELECT * FROM pa_target; -ERROR: current transaction is aborted, commands ignored until end of transaction block -step c2: COMMIT; - -starting permutation: pa_merge2 c1 pa_merge2a pa_select2 c2 -step pa_merge2: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step c1: COMMIT; -step pa_merge2a: - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; - -step pa_select2: SELECT * FROM pa_target; -key val - -1 pa_merge2a -2 initial -2 initial updated by pa_merge1 -step c2: COMMIT; diff --git a/src/test/isolation/expected/partition-key-update-1.out b/src/test/isolation/expected/partition-key-update-1.out index 37fe6a7b277..c1a9c56ae49 100644 --- a/src/test/isolation/expected/partition-key-update-1.out +++ b/src/test/isolation/expected/partition-key-update-1.out @@ -15,7 +15,17 @@ step s1u: UPDATE foo SET a=2 WHERE a=1; step s2d: DELETE FROM foo WHERE a=1; step s1c: COMMIT; step s2d: <... completed> -error in steps s1c s2d: ERROR: tuple to be deleted was already moved to another partition due to concurrent update +error in steps s1c s2d: ERROR: tuple to be locked was already moved to another partition due to concurrent update +step s2c: COMMIT; + +starting permutation: s1b s2b s1u s2u s1c s2c +step s1b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s2u: UPDATE foo SET b='EFG' WHERE a=1; +step s1c: COMMIT; +step s2u: <... completed> +error in steps s1c s2u: ERROR: tuple to be locked was already moved to another partition due to concurrent update step s2c: COMMIT; starting permutation: s1b s2b s2d s1u s2c s1c diff --git a/src/test/isolation/expected/partition-key-update-4.out b/src/test/isolation/expected/partition-key-update-4.out new file mode 100644 index 00000000000..774a7faf6ce --- /dev/null +++ b/src/test/isolation/expected/partition-key-update-4.out @@ -0,0 +1,60 @@ +Parsed test spec with 2 sessions + +starting permutation: s1b s2b s2u1 s1u s2c s1c s1s +step s1b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2u1: UPDATE foo SET b = b || ' update2' WHERE a = 1; +step s1u: UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; +step s2c: COMMIT; +step s1u: <... completed> +step s1c: COMMIT; +step s1s: SELECT tableoid::regclass, * FROM foo ORDER BY a; +tableoid a b + +foo2 2 ABC update2 update1 + +starting permutation: s1b s2b s2ut1 s1ut s2c s1c s1st s1stl +step s1b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2ut1: UPDATE footrg SET b = b || ' update2' WHERE a = 1; +step s1ut: UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; +step s2c: COMMIT; +step s1ut: <... completed> +step s1c: COMMIT; +step s1st: SELECT tableoid::regclass, * FROM footrg ORDER BY a; +tableoid a b + +footrg2 2 ABC update2 update1 +step s1stl: SELECT * FROM triglog ORDER BY a; +a b + +1 ABC update2 trigger + +starting permutation: s1b s2b s2u2 s1u s2c s1c s1s +step s1b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2u2: UPDATE foo SET b = 'EFG' WHERE a = 1; +step s1u: UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; +step s2c: COMMIT; +step s1u: <... completed> +step s1c: COMMIT; +step s1s: SELECT tableoid::regclass, * FROM foo ORDER BY a; +tableoid a b + +foo1 1 EFG + +starting permutation: s1b s2b s2ut2 s1ut s2c s1c s1st s1stl +step s1b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2b: BEGIN ISOLATION LEVEL READ COMMITTED; +step s2ut2: UPDATE footrg SET b = 'EFG' WHERE a = 1; +step s1ut: UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; +step s2c: COMMIT; +step s1ut: <... completed> +step s1c: COMMIT; +step s1st: SELECT tableoid::regclass, * FROM footrg ORDER BY a; +tableoid a b + +footrg1 1 EFG +step s1stl: SELECT * FROM triglog ORDER BY a; +a b + diff --git a/src/test/isolation/expected/plpgsql-toast.out b/src/test/isolation/expected/plpgsql-toast.out new file mode 100644 index 00000000000..fc557da5e77 --- /dev/null +++ b/src/test/isolation/expected/plpgsql-toast.out @@ -0,0 +1,194 @@ +Parsed test spec with 2 sessions + +starting permutation: lock assign1 vacuum unlock +pg_advisory_unlock_all + + +pg_advisory_unlock_all + + +step lock: + SELECT pg_advisory_lock(1); + +pg_advisory_lock + + +step assign1: +do $$ + declare + x text; + begin + select test1.b into x from test1; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(x) = %', length(x); + end; +$$; + +step vacuum: + VACUUM test1; + +step unlock: + SELECT pg_advisory_unlock(1); + +pg_advisory_unlock + +t +s1: NOTICE: length(x) = 6000 +step assign1: <... completed> + +starting permutation: lock assign2 vacuum unlock +pg_advisory_unlock_all + + +pg_advisory_unlock_all + + +step lock: + SELECT pg_advisory_lock(1); + +pg_advisory_lock + + +step assign2: +do $$ + declare + x text; + begin + x := (select test1.b from test1); + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(x) = %', length(x); + end; +$$; + +step vacuum: + VACUUM test1; + +step unlock: + SELECT pg_advisory_unlock(1); + +pg_advisory_unlock + +t +s1: NOTICE: length(x) = 6000 +step assign2: <... completed> + +starting permutation: lock assign3 vacuum unlock +pg_advisory_unlock_all + + +pg_advisory_unlock_all + + +step lock: + SELECT pg_advisory_lock(1); + +pg_advisory_lock + + +step assign3: +do $$ + declare + r record; + begin + select * into r from test1; + r.b := (select test1.b from test1); + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; + +step vacuum: + VACUUM test1; + +step unlock: + SELECT pg_advisory_unlock(1); + +pg_advisory_unlock + +t +s1: NOTICE: length(r) = 6004 +step assign3: <... completed> + +starting permutation: lock assign4 vacuum unlock +pg_advisory_unlock_all + + +pg_advisory_unlock_all + + +step lock: + SELECT pg_advisory_lock(1); + +pg_advisory_lock + + +step assign4: +do $$ + declare + r test2; + begin + select * into r from test1; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; + +step vacuum: + VACUUM test1; + +step unlock: + SELECT pg_advisory_unlock(1); + +pg_advisory_unlock + +t +s1: NOTICE: length(r) = 6004 +step assign4: <... completed> + +starting permutation: lock assign5 vacuum unlock +pg_advisory_unlock_all + + +pg_advisory_unlock_all + + +step lock: + SELECT pg_advisory_lock(1); + +pg_advisory_lock + + +step assign5: +do $$ + declare + r record; + begin + for r in select test1.b from test1 loop + null; + end loop; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; + +step vacuum: + VACUUM test1; + +step unlock: + SELECT pg_advisory_unlock(1); + +pg_advisory_unlock + +t +s1: NOTICE: length(r) = 6002 +step assign5: <... completed> diff --git a/src/test/isolation/expected/predicate-gin.out b/src/test/isolation/expected/predicate-gin.out index 4f5501f6f01..77eb5aaff79 100644 --- a/src/test/isolation/expected/predicate-gin.out +++ b/src/test/isolation/expected/predicate-gin.out @@ -1,756 +1,457 @@ -Parsed test spec with 2 sessions +Parsed test spec with 3 sessions -starting permutation: rxy1 wx1 c1 rxy2 wy2 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step c1: commit; -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10050 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step c2: commit; +starting permutation: ra1 ro2 wo1 c1 wa2 c2 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -starting permutation: rxy2 wy2 c2 rxy1 wx1 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +{1} +step ro2: select count(*) from other_tbl; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step c2: commit; -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10050 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step c1: commit; - -starting permutation: rxy3 wx3 c1 rxy4 wy4 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count - -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count - -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step c2: commit; - -starting permutation: rxy4 wy4 c2 rxy3 wx3 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count - -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +step wa2: insert into gin_tbl values (array[1]); +ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count - -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c1: commit; -starting permutation: rxy1 wx1 rxy2 c1 wy2 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: ro2 ra1 wo1 c1 wa2 c2 +step ro2: select count(*) from other_tbl; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count +0 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -10000 +{1} +step wo1: insert into other_tbl values (1); step c1: commit; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +step wa2: insert into gin_tbl values (array[1]); ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -starting permutation: rxy1 wx1 rxy2 wy2 c1 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: ro2 ra1 wo1 wa2 c1 c2 +step ro2: select count(*) from other_tbl; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count +0 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +{1} +step wo1: insert into other_tbl values (1); +step wa2: insert into gin_tbl values (array[1]); step c1: commit; step c2: commit; ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy1 wx1 rxy2 wy2 c2 c1 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count +starting permutation: ra1 ro2 wa2 wo1 c1 c2 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +{1} +step ro2: select count(*) from other_tbl; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step c2: commit; +0 +step wa2: insert into gin_tbl values (array[1]); +step wo1: insert into other_tbl values (1); step c1: commit; +step c2: commit; ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy1 rxy2 wx1 c1 wy2 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: rb1 ro2 wo1 c1 wb2 c2 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +1 +step ro2: select count(*) from other_tbl; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +step wb2: insert into gin_tbl values (array[2]); ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -starting permutation: rxy1 rxy2 wx1 wy2 c1 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: ro2 rb1 wo1 c1 wb2 c2 +step ro2: select count(*) from other_tbl; count -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +0 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +1 +step wo1: insert into other_tbl values (1); step c1: commit; -step c2: commit; +step wb2: insert into gin_tbl values (array[2]); ERROR: could not serialize access due to read/write dependencies among transactions - -starting permutation: rxy1 rxy2 wx1 wy2 c2 c1 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; step c2: commit; -step c1: commit; -ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy1 rxy2 wy2 wx1 c1 c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: ro2 rb1 wo1 wb2 c1 c2 +step ro2: select count(*) from other_tbl; count -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +0 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +1 +step wo1: insert into other_tbl values (1); +step wb2: insert into gin_tbl values (array[2]); step c1: commit; step c2: commit; ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy1 rxy2 wy2 wx1 c2 c1 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: rb1 ro2 wb2 wo1 c1 c2 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +1 +step ro2: select count(*) from other_tbl; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step c2: commit; +0 +step wb2: insert into gin_tbl values (array[2]); +step wo1: insert into other_tbl values (1); step c1: commit; -ERROR: could not serialize access due to read/write dependencies among transactions - -starting permutation: rxy1 rxy2 wy2 c2 wx1 c1 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; step c2: commit; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; ERROR: could not serialize access due to read/write dependencies among transactions -step c1: commit; -starting permutation: rxy2 rxy1 wx1 c1 wy2 c2 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +starting permutation: rc1 ro2 wo1 c1 wc2 c2 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +1 +step ro2: select count(*) from other_tbl; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +step wc2: insert into gin_tbl values (array[800]); ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -starting permutation: rxy2 rxy1 wx1 wy2 c1 c2 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +starting permutation: ro2 rc1 wo1 c1 wc2 c2 +step ro2: select count(*) from other_tbl; count -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +0 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; +1 +step wo1: insert into other_tbl values (1); step c1: commit; -step c2: commit; +step wc2: insert into gin_tbl values (array[800]); ERROR: could not serialize access due to read/write dependencies among transactions - -starting permutation: rxy2 rxy1 wx1 wy2 c2 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; step c2: commit; -step c1: commit; -ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy2 rxy1 wy2 wx1 c1 c2 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +starting permutation: ro2 rc1 wo1 wc2 c1 c2 +step ro2: select count(*) from other_tbl; count -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +0 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +1 +step wo1: insert into other_tbl values (1); +step wc2: insert into gin_tbl values (array[800]); step c1: commit; step c2: commit; ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy2 rxy1 wy2 wx1 c2 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +starting permutation: rc1 ro2 wc2 wo1 c1 c2 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +1 +step ro2: select count(*) from other_tbl; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step c2: commit; +0 +step wc2: insert into gin_tbl values (array[800]); +step wo1: insert into other_tbl values (1); step c1: commit; -ERROR: could not serialize access due to read/write dependencies among transactions - -starting permutation: rxy2 rxy1 wy2 c2 wx1 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10000 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; step c2: commit; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; ERROR: could not serialize access due to read/write dependencies among transactions -step c1: commit; -starting permutation: rxy2 wy2 rxy1 wx1 c1 c2 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count +starting permutation: ra1 ro2 wo1 c1 wb2 c2 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +{1} +step ro2: select count(*) from other_tbl; count -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wb2: insert into gin_tbl values (array[2]); step c2: commit; -ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: rxy2 wy2 rxy1 wx1 c2 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +starting permutation: ro2 ra1 wo1 c1 wc2 c2 +step ro2: select count(*) from other_tbl; count -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count +0 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -10000 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -step c2: commit; +{1} +step wo1: insert into other_tbl values (1); step c1: commit; -ERROR: could not serialize access due to read/write dependencies among transactions - -starting permutation: rxy2 wy2 rxy1 c2 wx1 c1 -step rxy2: select count(*) from gin_tbl where p @> array[5,6]; -count - -10000 -step wy2: insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; -count - -10000 +step wc2: insert into gin_tbl values (array[800]); step c2: commit; -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; -ERROR: could not serialize access due to read/write dependencies among transactions -step c1: commit; -starting permutation: rxy3 wx3 rxy4 c1 wy4 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: ro2 rb1 wo1 wa2 c1 c2 +step ro2: select count(*) from other_tbl; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +0 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -4 +1 +step wo1: insert into other_tbl values (1); +step wa2: insert into gin_tbl values (array[1]); step c1: commit; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; step c2: commit; -starting permutation: rxy3 wx3 rxy4 wy4 c1 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: rc1 ro2 wa2 wo1 c1 c2 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +1 +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +0 +step wa2: insert into gin_tbl values (array[1]); +step wo1: insert into other_tbl values (1); step c1: commit; step c2: commit; -starting permutation: rxy3 wx3 rxy4 wy4 c2 c1 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: rb1 ro2 wo1 c1 wa2 c2 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +1 +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step c2: commit; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wa2: insert into gin_tbl values (array[1]); +step c2: commit; -starting permutation: rxy3 rxy4 wx3 c1 wy4 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: ro2 rb1 wo1 c1 wc2 c2 +step ro2: select count(*) from other_tbl; count -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +0 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +1 +step wo1: insert into other_tbl values (1); step c1: commit; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +step wc2: insert into gin_tbl values (array[800]); step c2: commit; -starting permutation: rxy3 rxy4 wx3 wy4 c1 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: ro2 ra1 wo1 wb2 c1 c2 +step ro2: select count(*) from other_tbl; count -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count +0 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +{1} +step wo1: insert into other_tbl values (1); +step wb2: insert into gin_tbl values (array[2]); step c1: commit; step c2: commit; -starting permutation: rxy3 rxy4 wx3 wy4 c2 c1 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: rc1 ro2 wb2 wo1 c1 c2 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +1 +step ro2: select count(*) from other_tbl; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step c2: commit; +0 +step wb2: insert into gin_tbl values (array[2]); +step wo1: insert into other_tbl values (1); step c1: commit; +step c2: commit; -starting permutation: rxy3 rxy4 wy4 wx3 c1 c2 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: rc1 ro2 wo1 c1 wa2 c2 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +1 +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wa2: insert into gin_tbl values (array[1]); step c2: commit; -starting permutation: rxy3 rxy4 wy4 wx3 c2 c1 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +starting permutation: ro2 rc1 wo1 c1 wb2 c2 +step ro2: select count(*) from other_tbl; count -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +0 +step rc1: select count(*) from gin_tbl where p @> array[800]; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c2: commit; +1 +step wo1: insert into other_tbl values (1); step c1: commit; - -starting permutation: rxy3 rxy4 wy4 c2 wx3 c1 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count - -4 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count - -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +step wb2: insert into gin_tbl values (array[2]); step c2: commit; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c1: commit; -starting permutation: rxy4 rxy3 wx3 c1 wy4 c2 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +starting permutation: ro2 ra1 wo1 wc2 c1 c2 +step ro2: select count(*) from other_tbl; count -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count +0 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +{1} +step wo1: insert into other_tbl values (1); +step wc2: insert into gin_tbl values (array[800]); step c1: commit; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; step c2: commit; -starting permutation: rxy4 rxy3 wx3 wy4 c1 c2 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +starting permutation: rb1 ro2 wc2 wo1 c1 c2 +step rb1: select count(*) from gin_tbl where p @> array[2]; count -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +1 +step ro2: select count(*) from other_tbl; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +0 +step wc2: insert into gin_tbl values (array[800]); +step wo1: insert into other_tbl values (1); step c1: commit; step c2: commit; -starting permutation: rxy4 rxy3 wx3 wy4 c2 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count +starting permutation: fu ra1 ro2 wo1 c1 wa2 c2 +step fu: alter index ginidx set (fastupdate = on); +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +{1} +step ro2: select count(*) from other_tbl; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step c2: commit; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wa2: insert into gin_tbl values (array[1]); +ERROR: could not serialize access due to read/write dependencies among transactions +step c2: commit; -starting permutation: rxy4 rxy3 wy4 wx3 c1 c2 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count +starting permutation: fu ra1 ro2 wo1 c1 wb2 c2 +step fu: alter index ginidx set (fastupdate = on); +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +{1} +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wb2: insert into gin_tbl values (array[2]); +ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -starting permutation: rxy4 rxy3 wy4 wx3 c2 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count +starting permutation: ra1 ro2 wo1 c1 fu wa2 c2 +step ra1: select * from gin_tbl where p @> array[1] limit 1; +p -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +{1} +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c2: commit; +0 +step wo1: insert into other_tbl values (1); step c1: commit; - -starting permutation: rxy4 rxy3 wy4 c2 wx3 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count - -4 -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count - -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; +step fu: alter index ginidx set (fastupdate = on); +step wa2: insert into gin_tbl values (array[1]); +ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c1: commit; -starting permutation: rxy4 wy4 rxy3 wx3 c1 c2 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +starting permutation: rd1 ro2 wo1 c1 wd2 c2 +step rd1: select count(*) from gin_tbl where p @> array[2000]; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +0 +step ro2: select count(*) from other_tbl; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; +0 +step wo1: insert into other_tbl values (1); step c1: commit; +step wd2: insert into gin_tbl values (array[2000]); +ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -starting permutation: rxy4 wy4 rxy3 wx3 c2 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; +starting permutation: ro2 rd1 wo1 c1 wd2 c2 +step ro2: select count(*) from other_tbl; count -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +0 +step rd1: select count(*) from gin_tbl where p @> array[2000]; count -4 -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c2: commit; +0 +step wo1: insert into other_tbl values (1); step c1: commit; - -starting permutation: rxy4 wy4 rxy3 c2 wx3 c1 -step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; -count - -4 -step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; -step rxy3: select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; -count - -4 +step wd2: insert into gin_tbl values (array[2000]); +ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; -step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; -step c1: commit; -starting permutation: rxy1 rxy2fu wx1 c1 wy2fu c2 -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: ro2 rd1 wo1 wd2 c1 c2 +step ro2: select count(*) from other_tbl; count -10000 -step rxy2fu: select count(*) from gin_tbl where p @> array[10000,10005]; +0 +step rd1: select count(*) from gin_tbl where p @> array[2000]; count 0 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +step wo1: insert into other_tbl values (1); +step wd2: insert into gin_tbl values (array[2000]); step c1: commit; -step wy2fu: insert into gin_tbl select g, array[10000,10005] from - generate_series(20051, 20100) g; step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions -starting permutation: fu1 rxy1 rxy2fu wx1 c1 wy2fu c2 -step fu1: alter index ginidx set (fastupdate = on); - commit; - begin isolation level serializable; - set enable_seqscan=off; -step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +starting permutation: rd1 ro2 wd2 wo1 c1 c2 +step rd1: select count(*) from gin_tbl where p @> array[2000]; count -10000 -step rxy2fu: select count(*) from gin_tbl where p @> array[10000,10005]; +0 +step ro2: select count(*) from other_tbl; count 0 -step wx1: insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; +step wd2: insert into gin_tbl values (array[2000]); +step wo1: insert into other_tbl values (1); step c1: commit; -step wy2fu: insert into gin_tbl select g, array[10000,10005] from - generate_series(20051, 20100) g; -ERROR: could not serialize access due to read/write dependencies among transactions step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions diff --git a/src/test/isolation/expected/predicate-lock-hot-tuple.out b/src/test/isolation/expected/predicate-lock-hot-tuple.out new file mode 100644 index 00000000000..d1c69bbbd03 --- /dev/null +++ b/src/test/isolation/expected/predicate-lock-hot-tuple.out @@ -0,0 +1,20 @@ +Parsed test spec with 2 sessions + +starting permutation: b1 b2 r1 r2 w1 w2 c1 c2 +step b1: BEGIN ISOLATION LEVEL SERIALIZABLE; +step b2: BEGIN ISOLATION LEVEL SERIALIZABLE; +step r1: SELECT * FROM test WHERE i IN (5, 7) +i t + +5 apple +7 pear_hot_updated +step r2: SELECT * FROM test WHERE i IN (5, 7) +i t + +5 apple +7 pear_hot_updated +step w1: UPDATE test SET t = 'pear_xact1' WHERE i = 7 +step w2: UPDATE test SET t = 'apple_xact2' WHERE i = 5 +step c1: COMMIT; +step c2: COMMIT; +ERROR: could not serialize access due to read/write dependencies among transactions diff --git a/src/test/isolation/expected/reindex-concurrently.out b/src/test/isolation/expected/reindex-concurrently.out new file mode 100644 index 00000000000..9e04169b2fd --- /dev/null +++ b/src/test/isolation/expected/reindex-concurrently.out @@ -0,0 +1,78 @@ +Parsed test spec with 3 sessions + +starting permutation: reindex sel1 upd2 ins2 del2 end1 end2 +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step end1: COMMIT; +step end2: COMMIT; + +starting permutation: sel1 reindex upd2 ins2 del2 end1 end2 +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step end1: COMMIT; +step end2: COMMIT; +step reindex: <... completed> + +starting permutation: sel1 upd2 reindex ins2 del2 end1 end2 +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step end1: COMMIT; +step end2: COMMIT; +step reindex: <... completed> + +starting permutation: sel1 upd2 ins2 reindex del2 end1 end2 +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step end1: COMMIT; +step end2: COMMIT; +step reindex: <... completed> + +starting permutation: sel1 upd2 ins2 del2 reindex end1 end2 +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step end1: COMMIT; +step end2: COMMIT; +step reindex: <... completed> + +starting permutation: sel1 upd2 ins2 del2 end1 reindex end2 +step sel1: SELECT data FROM reind_con_tab WHERE id = 3; +data + +aaaa +step upd2: UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; +step ins2: INSERT INTO reind_con_tab(data) VALUES ('cccc'); +step del2: DELETE FROM reind_con_tab WHERE data = 'cccc'; +step end1: COMMIT; +step reindex: REINDEX TABLE CONCURRENTLY reind_con_tab; +step end2: COMMIT; +step reindex: <... completed> diff --git a/src/test/isolation/expected/serializable-parallel-2.out b/src/test/isolation/expected/serializable-parallel-2.out new file mode 100644 index 00000000000..9a693c4dc62 --- /dev/null +++ b/src/test/isolation/expected/serializable-parallel-2.out @@ -0,0 +1,44 @@ +Parsed test spec with 2 sessions + +starting permutation: s1r s2r1 s1c s2r2 s2c +step s1r: SELECT * FROM foo; +a + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +step s2r1: SELECT * FROM foo; +a + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +step s1c: COMMIT; +step s2r2: SELECT * FROM foo; +a + +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +step s2c: COMMIT; diff --git a/src/test/isolation/expected/serializable-parallel.out b/src/test/isolation/expected/serializable-parallel.out new file mode 100644 index 00000000000..f43aa6a2990 --- /dev/null +++ b/src/test/isolation/expected/serializable-parallel.out @@ -0,0 +1,44 @@ +Parsed test spec with 3 sessions + +starting permutation: s2rx s2ry s1ry s1wy s1c s2wx s2c s3c +step s2rx: SELECT balance FROM bank_account WHERE id = 'X'; +balance + +0 +step s2ry: SELECT balance FROM bank_account WHERE id = 'Y'; +balance + +0 +step s1ry: SELECT balance FROM bank_account WHERE id = 'Y'; +balance + +0 +step s1wy: UPDATE bank_account SET balance = 20 WHERE id = 'Y'; +step s1c: COMMIT; +step s2wx: UPDATE bank_account SET balance = -11 WHERE id = 'X'; +step s2c: COMMIT; +step s3c: COMMIT; + +starting permutation: s2rx s2ry s1ry s1wy s1c s3r s3c s2wx +step s2rx: SELECT balance FROM bank_account WHERE id = 'X'; +balance + +0 +step s2ry: SELECT balance FROM bank_account WHERE id = 'Y'; +balance + +0 +step s1ry: SELECT balance FROM bank_account WHERE id = 'Y'; +balance + +0 +step s1wy: UPDATE bank_account SET balance = 20 WHERE id = 'Y'; +step s1c: COMMIT; +step s3r: SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; +id balance + +X 0 +Y 20 +step s3c: COMMIT; +step s2wx: UPDATE bank_account SET balance = -11 WHERE id = 'X'; +ERROR: could not serialize access due to read/write dependencies among transactions diff --git a/src/test/isolation/expected/truncate-conflict.out b/src/test/isolation/expected/truncate-conflict.out new file mode 100644 index 00000000000..2c10f8d40d4 --- /dev/null +++ b/src/test/isolation/expected/truncate-conflict.out @@ -0,0 +1,99 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_begin s1_tab_lookup s2_auth s2_truncate s1_commit s2_reset +step s1_begin: BEGIN; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +ERROR: permission denied for table truncate_tab +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s2_truncate s1_tab_lookup s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +ERROR: permission denied for table truncate_tab +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s1_tab_lookup s2_truncate s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_truncate_conflict; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s2_truncate: TRUNCATE truncate_tab; +ERROR: permission denied for table truncate_tab +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s2_auth s2_truncate s1_begin s1_tab_lookup s1_commit s2_reset +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +ERROR: permission denied for table truncate_tab +step s1_begin: BEGIN; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s1_tab_lookup s2_grant s2_auth s2_truncate s1_commit s2_reset +step s1_begin: BEGIN; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s2_grant: GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +step s1_commit: COMMIT; +step s2_truncate: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s2_truncate s1_tab_lookup s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s1_tab_lookup s2_truncate s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; +step s2_auth: SET ROLE regress_truncate_conflict; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s2_truncate: TRUNCATE truncate_tab; +step s1_commit: COMMIT; +step s2_truncate: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s2_grant s2_auth s2_truncate s1_begin s1_tab_lookup s1_commit s2_reset +step s2_grant: GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; +step s2_auth: SET ROLE regress_truncate_conflict; +step s2_truncate: TRUNCATE truncate_tab; +step s1_begin: BEGIN; +step s1_tab_lookup: SELECT count(*) >= 0 FROM truncate_tab; +?column? + +t +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; diff --git a/src/test/isolation/expected/tuplelock-upgrade-no-deadlock.out b/src/test/isolation/expected/tuplelock-upgrade-no-deadlock.out new file mode 100644 index 00000000000..8e04a543948 --- /dev/null +++ b/src/test/isolation/expected/tuplelock-upgrade-no-deadlock.out @@ -0,0 +1,195 @@ +Parsed test spec with 4 sessions + +starting permutation: s1_share s2_for_update s3_share s3_for_update s1_rollback s3_rollback s2_rollback +step s1_share: select id from tlu_job where id = 1 for share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_share: select id from tlu_job where id = 1 for share; +id + +1 +step s3_for_update: select id from tlu_job where id = 1 for update; +step s1_rollback: rollback; +step s3_for_update: <... completed> +id + +1 +step s3_rollback: rollback; +step s2_for_update: <... completed> +id + +1 +step s2_rollback: rollback; + +starting permutation: s1_keyshare s2_for_update s3_keyshare s1_update s3_update s1_rollback s3_rollback s2_rollback +step s1_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s1_update: update tlu_job set name = 'b' where id = 1; +step s3_update: update tlu_job set name = 'c' where id = 1; +step s1_rollback: rollback; +step s3_update: <... completed> +step s3_rollback: rollback; +step s2_for_update: <... completed> +id + +1 +step s2_rollback: rollback; + +starting permutation: s1_keyshare s2_for_update s3_keyshare s1_update s3_update s1_commit s3_rollback s2_rollback +step s1_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s1_update: update tlu_job set name = 'b' where id = 1; +step s3_update: update tlu_job set name = 'c' where id = 1; +step s1_commit: commit; +step s3_update: <... completed> +step s3_rollback: rollback; +step s2_for_update: <... completed> +id + +1 +step s2_rollback: rollback; + +starting permutation: s1_keyshare s2_for_update s3_keyshare s3_delete s1_rollback s3_rollback s2_rollback +step s1_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s3_delete: delete from tlu_job where id = 1; +step s1_rollback: rollback; +step s3_delete: <... completed> +step s3_rollback: rollback; +step s2_for_update: <... completed> +id + +1 +step s2_rollback: rollback; + +starting permutation: s1_keyshare s2_for_update s3_keyshare s3_delete s1_rollback s3_commit s2_rollback +step s1_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s3_delete: delete from tlu_job where id = 1; +step s1_rollback: rollback; +step s3_delete: <... completed> +step s3_commit: commit; +step s2_for_update: <... completed> +id + +step s2_rollback: rollback; + +starting permutation: s1_share s2_for_update s3_for_update s1_rollback s2_rollback s3_rollback +step s1_share: select id from tlu_job where id = 1 for share; +id + +1 +step s2_for_update: select id from tlu_job where id = 1 for update; +step s3_for_update: select id from tlu_job where id = 1 for update; +step s1_rollback: rollback; +step s2_for_update: <... completed> +id + +1 +step s2_rollback: rollback; +step s3_for_update: <... completed> +id + +1 +step s3_rollback: rollback; + +starting permutation: s1_share s2_update s3_update s1_rollback s2_rollback s3_rollback +step s1_share: select id from tlu_job where id = 1 for share; +id + +1 +step s2_update: update tlu_job set name = 'b' where id = 1; +step s3_update: update tlu_job set name = 'c' where id = 1; +step s1_rollback: rollback; +step s2_update: <... completed> +step s2_rollback: rollback; +step s3_update: <... completed> +step s3_rollback: rollback; + +starting permutation: s1_share s2_delete s3_delete s1_rollback s2_rollback s3_rollback +step s1_share: select id from tlu_job where id = 1 for share; +id + +1 +step s2_delete: delete from tlu_job where id = 1; +step s3_delete: delete from tlu_job where id = 1; +step s1_rollback: rollback; +step s2_delete: <... completed> +step s2_rollback: rollback; +step s3_delete: <... completed> +step s3_rollback: rollback; + +starting permutation: s1_keyshare s3_for_update s2_for_keyshare s1_savept_e s1_share s1_savept_f s1_fornokeyupd s2_fornokeyupd s0_begin s0_keyshare s1_rollback_f s0_keyshare s1_rollback_e s1_rollback s2_rollback s0_rollback s3_rollback +step s1_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s3_for_update: select id from tlu_job where id = 1 for update; +step s2_for_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s1_savept_e: savepoint s1_e; +step s1_share: select id from tlu_job where id = 1 for share; +id + +1 +step s1_savept_f: savepoint s1_f; +step s1_fornokeyupd: select id from tlu_job where id = 1 for no key update; +id + +1 +step s2_fornokeyupd: select id from tlu_job where id = 1 for no key update; +step s0_begin: begin; +step s0_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s1_rollback_f: rollback to s1_f; +step s0_keyshare: select id from tlu_job where id = 1 for key share; +id + +1 +step s1_rollback_e: rollback to s1_e; +step s2_fornokeyupd: <... completed> +id + +1 +step s1_rollback: rollback; +step s2_rollback: rollback; +step s0_rollback: rollback; +step s3_for_update: <... completed> +id + +1 +step s3_rollback: rollback; diff --git a/src/test/isolation/expected/vacuum-concurrent-drop.out b/src/test/isolation/expected/vacuum-concurrent-drop.out index bb92e80b923..cf348d7e5df 100644 --- a/src/test/isolation/expected/vacuum-concurrent-drop.out +++ b/src/test/isolation/expected/vacuum-concurrent-drop.out @@ -10,7 +10,7 @@ step drop_and_commit: DROP TABLE part2; COMMIT; -WARNING: skipping vacuum of "part2" --- relation no longer exists +s2: WARNING: skipping vacuum of "part2" --- relation no longer exists step vac_specified: <... completed> starting permutation: lock vac_all_parts drop_and_commit @@ -35,7 +35,7 @@ step drop_and_commit: DROP TABLE part2; COMMIT; -WARNING: skipping analyze of "part2" --- relation no longer exists +s2: WARNING: skipping analyze of "part2" --- relation no longer exists step analyze_specified: <... completed> starting permutation: lock analyze_all_parts drop_and_commit @@ -60,7 +60,7 @@ step drop_and_commit: DROP TABLE part2; COMMIT; -WARNING: skipping vacuum of "part2" --- relation no longer exists +s2: WARNING: skipping vacuum of "part2" --- relation no longer exists step vac_analyze_specified: <... completed> starting permutation: lock vac_analyze_all_parts drop_and_commit diff --git a/src/test/isolation/expected/vacuum-conflict.out b/src/test/isolation/expected/vacuum-conflict.out new file mode 100644 index 00000000000..ffde537305f --- /dev/null +++ b/src/test/isolation/expected/vacuum-conflict.out @@ -0,0 +1,149 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_begin s1_lock s2_auth s2_vacuum s1_commit s2_reset +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can vacuum it +step s2_vacuum: VACUUM vacuum_tab; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s2_vacuum s1_lock s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can vacuum it +step s2_vacuum: VACUUM vacuum_tab; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s1_lock s2_vacuum s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can vacuum it +step s2_vacuum: VACUUM vacuum_tab; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s2_auth s2_vacuum s1_begin s1_lock s1_commit s2_reset +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can vacuum it +step s2_vacuum: VACUUM vacuum_tab; +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s1_lock s2_auth s2_analyze s1_commit s2_reset +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can analyze it +step s2_analyze: ANALYZE vacuum_tab; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s2_analyze s1_lock s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can analyze it +step s2_analyze: ANALYZE vacuum_tab; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_auth s1_lock s2_analyze s1_commit s2_reset +step s1_begin: BEGIN; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can analyze it +step s2_analyze: ANALYZE vacuum_tab; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s2_auth s2_analyze s1_begin s1_lock s1_commit s2_reset +step s2_auth: SET ROLE regress_vacuum_conflict; +s2: WARNING: skipping "vacuum_tab" --- only table or database owner can analyze it +step s2_analyze: ANALYZE vacuum_tab; +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s1_lock s2_auth s2_vacuum s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_vacuum: VACUUM vacuum_tab; +step s1_commit: COMMIT; +step s2_vacuum: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s2_vacuum s1_lock s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_vacuum: VACUUM vacuum_tab; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s1_lock s2_vacuum s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_vacuum: VACUUM vacuum_tab; +step s1_commit: COMMIT; +step s2_vacuum: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s2_grant s2_auth s2_vacuum s1_begin s1_lock s1_commit s2_reset +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_vacuum: VACUUM vacuum_tab; +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s1_lock s2_auth s2_analyze s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_analyze: ANALYZE vacuum_tab; +step s1_commit: COMMIT; +step s2_analyze: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s2_analyze s1_lock s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_analyze: ANALYZE vacuum_tab; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; + +starting permutation: s1_begin s2_grant s2_auth s1_lock s2_analyze s1_commit s2_reset +step s1_begin: BEGIN; +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s2_analyze: ANALYZE vacuum_tab; +step s1_commit: COMMIT; +step s2_analyze: <... completed> +step s2_reset: RESET ROLE; + +starting permutation: s2_grant s2_auth s2_analyze s1_begin s1_lock s1_commit s2_reset +step s2_grant: ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; +step s2_auth: SET ROLE regress_vacuum_conflict; +step s2_analyze: ANALYZE vacuum_tab; +step s1_begin: BEGIN; +step s1_lock: LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; +step s1_commit: COMMIT; +step s2_reset: RESET ROLE; diff --git a/src/test/isolation/expected/vacuum-skip-locked.out b/src/test/isolation/expected/vacuum-skip-locked.out new file mode 100644 index 00000000000..99db281a159 --- /dev/null +++ b/src/test/isolation/expected/vacuum-skip-locked.out @@ -0,0 +1,171 @@ +Parsed test spec with 2 sessions + +starting permutation: lock_share vac_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_specified: VACUUM (SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_all_parts: VACUUM (SKIP_LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share analyze_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +s2: WARNING: skipping analyze of "part1" --- lock not available +step analyze_specified: ANALYZE (SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share analyze_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step analyze_all_parts: ANALYZE (SKIP_LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share vac_analyze_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_analyze_specified: VACUUM (ANALYZE, SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_analyze_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_analyze_all_parts: VACUUM (ANALYZE, SKIP_LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share vac_full_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_full_specified: VACUUM (SKIP_LOCKED, FULL) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_full_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_full_all_parts: VACUUM (SKIP_LOCKED, FULL) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_specified: VACUUM (SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step vac_all_parts: VACUUM (SKIP_LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive analyze_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +s2: WARNING: skipping analyze of "part1" --- lock not available +step analyze_specified: ANALYZE (SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive analyze_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step analyze_all_parts: ANALYZE (SKIP_LOCKED) parted; +step commit: + COMMIT; + +step analyze_all_parts: <... completed> + +starting permutation: lock_access_exclusive vac_analyze_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_analyze_specified: VACUUM (ANALYZE, SKIP_LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_analyze_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step vac_analyze_all_parts: VACUUM (ANALYZE, SKIP_LOCKED) parted; +step commit: + COMMIT; + +step vac_analyze_all_parts: <... completed> + +starting permutation: lock_access_exclusive vac_full_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +s2: WARNING: skipping vacuum of "part1" --- lock not available +step vac_full_specified: VACUUM (SKIP_LOCKED, FULL) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_full_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step vac_full_all_parts: VACUUM (SKIP_LOCKED, FULL) parted; +step commit: + COMMIT; + diff --git a/src/test/isolation/isolation_main.c b/src/test/isolation/isolation_main.c index 58402b74d80..b9e25337726 100644 --- a/src/test/isolation/isolation_main.c +++ b/src/test/isolation/isolation_main.c @@ -2,7 +2,7 @@ * * isolation_main --- pg_regress test launcher for isolation tests * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/isolation/isolation_main.c @@ -36,6 +36,7 @@ isolation_start_test(const char *testname, char expectfile[MAXPGPATH]; char psql_cmd[MAXPGPATH * 3]; size_t offset = 0; + char *appnameenv; /* need to do the path lookup here, check isolation_init() for details */ if (!looked_up_isolation_exec) @@ -75,15 +76,30 @@ isolation_start_test(const char *testname, add_stringlist_item(expectfiles, expectfile); if (launcher) + { offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, "%s ", launcher); + if (offset >= sizeof(psql_cmd)) + { + fprintf(stderr, _("command too long\n")); + exit(2); + } + } - snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, - "\"%s\" \"dbname=%s\" < \"%s\" > \"%s\" 2>&1", - isolation_exec, - dblist->str, - infile, - outfile); + offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, + "\"%s\" \"dbname=%s\" < \"%s\" > \"%s\" 2>&1", + isolation_exec, + dblist->str, + infile, + outfile); + if (offset >= sizeof(psql_cmd)) + { + fprintf(stderr, _("command too long\n")); + exit(2); + } + + appnameenv = psprintf("PGAPPNAME=isolation/%s", testname); + putenv(appnameenv); pid = spawn_process(psql_cmd); @@ -94,6 +110,9 @@ isolation_start_test(const char *testname, exit(2); } + unsetenv("PGAPPNAME"); + free(appnameenv); + return pid; } diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 4abad7c15ee..69ae2279533 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -17,26 +17,28 @@ test: partial-index test: two-ids test: multiple-row-versions test: index-only-scan +test: predicate-lock-hot-tuple test: deadlock-simple test: deadlock-hard test: deadlock-soft test: deadlock-soft-2 +test: deadlock-parallel test: fk-contention test: fk-deadlock test: fk-deadlock2 +test: fk-partitioned-1 +test: fk-partitioned-2 test: eval-plan-qual test: lock-update-delete test: lock-update-traversal +test: inherit-temp test: insert-conflict-do-nothing test: insert-conflict-do-nothing-2 test: insert-conflict-do-update test: insert-conflict-do-update-2 test: insert-conflict-do-update-3 test: insert-conflict-toast -test: merge-insert-update -test: merge-delete -test: merge-update -test: merge-match-recheck +test: insert-conflict-specconflict test: delete-abort-savept test: delete-abort-savept-2 test: aborted-keyrevoke @@ -45,9 +47,11 @@ test: multixact-no-forget test: lock-committed-update test: lock-committed-keyupdate test: update-locked-tuple +test: reindex-concurrently test: propagate-lock-delete test: tuplelock-conflict test: tuplelock-update +test: tuplelock-upgrade-no-deadlock test: freeze-the-dead test: nowait test: nowait-2 @@ -70,9 +74,16 @@ test: async-notify test: vacuum-reltuples test: timeouts test: vacuum-concurrent-drop +test: vacuum-conflict +test: vacuum-skip-locked test: predicate-hash test: predicate-gist test: predicate-gin test: partition-key-update-1 test: partition-key-update-2 test: partition-key-update-3 +test: partition-key-update-4 +test: plpgsql-toast +test: truncate-conflict +test: serializable-parallel +test: serializable-parallel-2 diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c index 4ecad038bdc..556b46d93f4 100644 --- a/src/test/isolation/isolationtester.c +++ b/src/test/isolation/isolationtester.c @@ -23,41 +23,40 @@ /* * conns[0] is the global setup, teardown, and watchdog connection. Additional - * connections represent spec-defined sessions. + * connections represent spec-defined sessions. We also track the backend + * PID, in numeric and string formats, for each connection. */ static PGconn **conns = NULL; -static const char **backend_pids = NULL; +static int *backend_pids = NULL; +static const char **backend_pid_strs = NULL; static int nconns = 0; -/* In dry run only output permutations to be run by the tester. */ -static int dry_run = false; - -static void exit_nicely(void) pg_attribute_noreturn(); static void run_testspec(TestSpec *testspec); static void run_all_permutations(TestSpec *testspec); static void run_all_permutations_recurse(TestSpec *testspec, int nsteps, - Step **steps); + Step **steps); static void run_named_permutations(TestSpec *testspec); static void run_permutation(TestSpec *testspec, int nsteps, Step **steps); #define STEP_NONBLOCK 0x1 /* return 0 as soon as cmd waits for a lock */ #define STEP_RETRY 0x2 /* this is a retry of a previously-waiting cmd */ -static bool try_complete_step(Step *step, int flags); +static bool try_complete_step(TestSpec *testspec, Step *step, int flags); static int step_qsort_cmp(const void *a, const void *b); static int step_bsearch_cmp(const void *a, const void *b); static void printResultSet(PGresult *res); +static void isotesterNoticeProcessor(void *arg, const char *message); +static void blackholeNoticeProcessor(void *arg, const char *message); -/* close all connections and exit */ static void -exit_nicely(void) +disconnect_atexit(void) { int i; for (i = 0; i < nconns; i++) - PQfinish(conns[i]); - exit(1); + if (conns[i]) + PQfinish(conns[i]); } int @@ -74,18 +73,15 @@ main(int argc, char **argv) int nallsteps; Step **allsteps; - while ((opt = getopt(argc, argv, "nV")) != -1) + while ((opt = getopt(argc, argv, "V")) != -1) { switch (opt) { - case 'n': - dry_run = true; - break; case 'V': puts("isolationtester (PostgreSQL) " PG_VERSION); exit(0); default: - fprintf(stderr, "Usage: isolationtester [-n] [CONNINFO]\n"); + fprintf(stderr, "Usage: isolationtester [CONNINFO]\n"); return EXIT_FAILURE; } } @@ -138,20 +134,10 @@ main(int argc, char **argv) { fprintf(stderr, "duplicate step name: %s\n", testspec->allsteps[i]->name); - exit_nicely(); + exit(1); } } - /* - * In dry-run mode, just print the permutations that would be run, and - * exit. - */ - if (dry_run) - { - run_testspec(testspec); - return 0; - } - printf("Parsed test spec with %d sessions\n", testspec->nsessions); /* @@ -159,8 +145,11 @@ main(int argc, char **argv) * extra for lock wait detection and global work. */ nconns = 1 + testspec->nsessions; - conns = calloc(nconns, sizeof(PGconn *)); - backend_pids = calloc(nconns, sizeof(*backend_pids)); + conns = (PGconn **) pg_malloc0(nconns * sizeof(PGconn *)); + backend_pids = pg_malloc0(nconns * sizeof(*backend_pids)); + backend_pid_strs = pg_malloc0(nconns * sizeof(*backend_pid_strs)); + atexit(disconnect_atexit); + for (i = 0; i < nconns; i++) { conns[i] = PQconnectdb(conninfo); @@ -168,41 +157,27 @@ main(int argc, char **argv) { fprintf(stderr, "Connection %d to database failed: %s", i, PQerrorMessage(conns[i])); - exit_nicely(); + exit(1); } /* - * Suppress NOTIFY messages, which otherwise pop into results at odd - * places. + * Set up notice processors for the user-defined connections, so that + * messages can get printed prefixed with the session names. The + * control connection gets a "blackhole" processor instead (hides all + * messages). */ - res = PQexec(conns[i], "SET client_min_messages = warning;"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "message level setup failed: %s", PQerrorMessage(conns[i])); - exit_nicely(); - } - PQclear(res); - - /* Get the backend pid for lock wait checking. */ - res = PQexec(conns[i], "SELECT pg_backend_pid()"); - if (PQresultStatus(res) == PGRES_TUPLES_OK) - { - if (PQntuples(res) == 1 && PQnfields(res) == 1) - backend_pids[i] = pg_strdup(PQgetvalue(res, 0, 0)); - else - { - fprintf(stderr, "backend pid query returned %d rows and %d columns, expected 1 row and 1 column", - PQntuples(res), PQnfields(res)); - exit_nicely(); - } - } + if (i != 0) + PQsetNoticeProcessor(conns[i], + isotesterNoticeProcessor, + (void *) (testspec->sessions[i - 1]->name)); else - { - fprintf(stderr, "backend pid query failed: %s", - PQerrorMessage(conns[i])); - exit_nicely(); - } - PQclear(res); + PQsetNoticeProcessor(conns[i], + blackholeNoticeProcessor, + NULL); + + /* Save each connection's backend PID for subsequent use. */ + backend_pids[i] = PQbackendPID(conns[i]); + backend_pid_strs[i] = psprintf("%d", backend_pids[i]); } /* Set the session index fields in steps. */ @@ -227,9 +202,9 @@ main(int argc, char **argv) appendPQExpBufferStr(&wait_query, "SELECT pg_catalog.pg_isolation_test_session_is_blocked($1, '{"); /* The spec syntax requires at least one session; assume that here. */ - appendPQExpBufferStr(&wait_query, backend_pids[1]); + appendPQExpBufferStr(&wait_query, backend_pid_strs[1]); for (i = 2; i < nconns; i++) - appendPQExpBuffer(&wait_query, ",%s", backend_pids[i]); + appendPQExpBuffer(&wait_query, ",%s", backend_pid_strs[i]); appendPQExpBufferStr(&wait_query, "}')"); res = PQprepare(conns[0], PREP_WAITING, wait_query.data, 0, NULL); @@ -237,7 +212,7 @@ main(int argc, char **argv) { fprintf(stderr, "prepare of lock wait query failed: %s", PQerrorMessage(conns[0])); - exit_nicely(); + exit(1); } PQclear(res); termPQExpBuffer(&wait_query); @@ -248,9 +223,6 @@ main(int argc, char **argv) */ run_testspec(testspec); - /* Clean up and exit */ - for (i = 0; i < nconns; i++) - PQfinish(conns[i]); return 0; } @@ -263,10 +235,23 @@ static int *piles; static void run_testspec(TestSpec *testspec) { + int i; + if (testspec->permutations) run_named_permutations(testspec); else run_all_permutations(testspec); + + /* + * Verify that all steps have been used, complaining about anything + * defined but not used. + */ + for (i = 0; i < testspec->nallsteps; i++) + { + if (!testspec->allsteps[i]->used) + fprintf(stderr, "unused step name: %s\n", + testspec->allsteps[i]->name); + } } /* @@ -358,7 +343,7 @@ run_named_permutations(TestSpec *testspec) { fprintf(stderr, "undefined step \"%s\" specified in permutation\n", p->stepnames[j]); - exit_nicely(); + exit(1); } steps[j] = *this; } @@ -461,25 +446,16 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) Step **waiting; Step **errorstep; - /* - * In dry run mode, just display the permutation in the same format used - * by spec files, and return. - */ - if (dry_run) - { - printf("permutation"); - for (i = 0; i < nsteps; i++) - printf(" \"%s\"", steps[i]->name); - printf("\n"); - return; - } - waiting = pg_malloc(sizeof(Step *) * testspec->nsessions); errorstep = pg_malloc(sizeof(Step *) * testspec->nsessions); printf("\nstarting permutation:"); for (i = 0; i < nsteps; i++) + { + /* Track the permutation as in-use */ + steps[i]->used = true; printf(" %s", steps[i]->name); + } printf("\n"); /* Perform setup */ @@ -493,7 +469,7 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) else if (PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "setup failed: %s", PQerrorMessage(conns[0])); - exit_nicely(); + exit(1); } PQclear(res); } @@ -513,7 +489,7 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) fprintf(stderr, "setup of session %s failed: %s", testspec->sessions[i]->name, PQerrorMessage(conns[i + 1])); - exit_nicely(); + exit(1); } PQclear(res); } @@ -548,7 +524,7 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) oldstep = waiting[w]; /* Wait for previous step on this connection. */ - try_complete_step(oldstep, STEP_RETRY); + try_complete_step(testspec, oldstep, STEP_RETRY); /* Remove that step from the waiting[] array. */ if (w + 1 < nwaiting) @@ -570,7 +546,8 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) nerrorstep = 0; while (w < nwaiting) { - if (try_complete_step(waiting[w], STEP_NONBLOCK | STEP_RETRY)) + if (try_complete_step(testspec, waiting[w], + STEP_NONBLOCK | STEP_RETRY)) { /* Still blocked on a lock, leave it alone. */ w++; @@ -594,19 +571,20 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) if (!PQsendQuery(conn, step->sql)) { fprintf(stdout, "failed to send query for step %s: %s\n", - step->name, PQerrorMessage(conns[1 + step->session])); - exit_nicely(); + step->name, PQerrorMessage(conn)); + exit(1); } /* Try to complete this step without blocking. */ - mustwait = try_complete_step(step, STEP_NONBLOCK); + mustwait = try_complete_step(testspec, step, STEP_NONBLOCK); /* Check for completion of any steps that were previously waiting. */ w = 0; nerrorstep = 0; while (w < nwaiting) { - if (try_complete_step(waiting[w], STEP_NONBLOCK | STEP_RETRY)) + if (try_complete_step(testspec, waiting[w], + STEP_NONBLOCK | STEP_RETRY)) w++; else { @@ -629,7 +607,7 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) /* Wait for any remaining queries. */ for (w = 0; w < nwaiting; ++w) { - try_complete_step(waiting[w], STEP_RETRY); + try_complete_step(testspec, waiting[w], STEP_RETRY); report_error_message(waiting[w]); } @@ -692,7 +670,7 @@ run_permutation(TestSpec *testspec, int nsteps, Step **steps) * a lock, returns true. Otherwise, returns false. */ static bool -try_complete_step(Step *step, int flags) +try_complete_step(TestSpec *testspec, Step *step, int flags) { PGconn *conn = conns[1 + step->session]; fd_set read_set; @@ -701,12 +679,13 @@ try_complete_step(Step *step, int flags) int sock = PQsocket(conn); int ret; PGresult *res; + PGnotify *notify; bool canceled = false; if (sock < 0) { fprintf(stderr, "invalid socket: %s", PQerrorMessage(conn)); - exit_nicely(); + exit(1); } gettimeofday(&start_time, NULL); @@ -724,7 +703,7 @@ try_complete_step(Step *step, int flags) if (errno == EINTR) continue; fprintf(stderr, "select failed: %s\n", strerror(errno)); - exit_nicely(); + exit(1); } else if (ret == 0) /* select() timeout: check for lock wait */ { @@ -737,20 +716,42 @@ try_complete_step(Step *step, int flags) bool waiting; res = PQexecPrepared(conns[0], PREP_WAITING, 1, - &backend_pids[step->session + 1], + &backend_pid_strs[step->session + 1], NULL, NULL, 0); if (PQresultStatus(res) != PGRES_TUPLES_OK || PQntuples(res) != 1) { fprintf(stderr, "lock wait query failed: %s", - PQerrorMessage(conn)); - exit_nicely(); + PQerrorMessage(conns[0])); + exit(1); } waiting = ((PQgetvalue(res, 0, 0))[0] == 't'); PQclear(res); if (waiting) /* waiting to acquire a lock */ { + /* + * Since it takes time to perform the lock-check query, + * some data --- notably, NOTICE messages --- might have + * arrived since we looked. We must call PQconsumeInput + * and then PQisBusy to collect and process any such + * messages. In the (unlikely) case that PQisBusy then + * returns false, we might as well go examine the + * available result. + */ + if (!PQconsumeInput(conn)) + { + fprintf(stderr, "PQconsumeInput failed: %s\n", + PQerrorMessage(conn)); + exit(1); + } + if (!PQisBusy(conn)) + break; + + /* + * conn is still busy, so conclude that the step really is + * waiting. + */ if (!(flags & STEP_RETRY)) printf("step %s: %s \n", step->name, step->sql); @@ -766,15 +767,15 @@ try_complete_step(Step *step, int flags) td += (int64) current_time.tv_usec - (int64) start_time.tv_usec; /* - * After 60 seconds, try to cancel the query. + * After 180 seconds, try to cancel the query. * * If the user tries to test an invalid permutation, we don't want * to hang forever, especially when this is running in the - * buildfarm. So try to cancel it after a minute. This will - * presumably lead to this permutation failing, but remaining - * permutations and tests should still be OK. + * buildfarm. This will presumably lead to this permutation + * failing, but remaining permutations and tests should still be + * OK. */ - if (td > 60 * USECS_PER_SEC && !canceled) + if (td > 180 * USECS_PER_SEC && !canceled) { PGcancel *cancel = PQgetCancel(conn); @@ -791,24 +792,24 @@ try_complete_step(Step *step, int flags) } /* - * After 75 seconds, just give up and die. + * After 200 seconds, just give up and die. * * Since cleanup steps won't be run in this case, this may cause * later tests to fail. That stinks, but it's better than waiting * forever for the server to respond to the cancel. */ - if (td > 75 * USECS_PER_SEC) + if (td > 200 * USECS_PER_SEC) { - fprintf(stderr, "step %s timed out after 75 seconds\n", + fprintf(stderr, "step %s timed out after 200 seconds\n", step->name); - exit_nicely(); + exit(1); } } else if (!PQconsumeInput(conn)) /* select(): data available */ { fprintf(stderr, "PQconsumeInput failed: %s\n", PQerrorMessage(conn)); - exit_nicely(); + exit(1); } } @@ -857,6 +858,35 @@ try_complete_step(Step *step, int flags) PQclear(res); } + /* Report any available NOTIFY messages, too */ + PQconsumeInput(conn); + while ((notify = PQnotifies(conn)) != NULL) + { + /* Try to identify which session it came from */ + const char *sendername = NULL; + char pidstring[32]; + + for (int i = 0; i < testspec->nsessions; i++) + { + if (notify->be_pid == backend_pids[i + 1]) + { + sendername = testspec->sessions[i]->name; + break; + } + } + if (sendername == NULL) + { + /* Doesn't seem to be any test session, so show the hard way */ + snprintf(pidstring, sizeof(pidstring), "PID %d", notify->be_pid); + sendername = pidstring; + } + printf("%s: NOTIFY \"%s\" with payload \"%s\" from %s\n", + testspec->sessions[step->session]->name, + notify->relname, notify->extra, sendername); + PQfreemem(notify); + PQconsumeInput(conn); + } + return false; } @@ -881,3 +911,17 @@ printResultSet(PGresult *res) printf("\n"); } } + +/* notice processor, prefixes each message with the session name */ +static void +isotesterNoticeProcessor(void *arg, const char *message) +{ + printf("%s: %s", (char *) arg, message); +} + +/* notice processor, hides the message */ +static void +blackholeNoticeProcessor(void *arg, const char *message) +{ + /* do nothing */ +} diff --git a/src/test/isolation/isolationtester.h b/src/test/isolation/isolationtester.h index a4d989bd1a2..d9d2a14ecf4 100644 --- a/src/test/isolation/isolationtester.h +++ b/src/test/isolation/isolationtester.h @@ -3,7 +3,7 @@ * isolationtester.h * include file for isolation tests * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION @@ -29,6 +29,7 @@ struct Session struct Step { int session; + bool used; char *name; char *sql; char *errormsg; diff --git a/src/test/isolation/specparse.y b/src/test/isolation/specparse.y index 654716194c1..2dfe3533ff7 100644 --- a/src/test/isolation/specparse.y +++ b/src/test/isolation/specparse.y @@ -4,7 +4,7 @@ * specparse.y * bison grammar for the isolation test file format * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- @@ -145,6 +145,7 @@ step: $$ = pg_malloc(sizeof(Step)); $$->name = $2; $$->sql = $3; + $$->used = false; $$->errormsg = NULL; } ; diff --git a/src/test/isolation/specs/async-notify.spec b/src/test/isolation/specs/async-notify.spec index 8adad42c7c8..daf7bef903c 100644 --- a/src/test/isolation/specs/async-notify.spec +++ b/src/test/isolation/specs/async-notify.spec @@ -1,14 +1,70 @@ -# Verify that pg_notification_queue_usage correctly reports a non-zero result, -# after submitting notifications while another connection is listening for -# those notifications and waiting inside an active transaction. +# Tests for LISTEN/NOTIFY -session "listener" -step "listen" { LISTEN a; } -step "begin" { BEGIN; } -teardown { ROLLBACK; UNLISTEN *; } +# Most of these tests use only the "notifier" session and hence exercise only +# self-notifies, which are convenient because they minimize timing concerns. +# Note we assume that each step is delivered to the backend as a single Query +# message so it will run as one transaction. session "notifier" -step "check" { SELECT pg_notification_queue_usage() > 0 AS nonzero; } -step "notify" { SELECT count(pg_notify('a', s::text)) FROM generate_series(1, 1000) s; } +step "listenc" { LISTEN c1; LISTEN c2; } +step "notify1" { NOTIFY c1; } +step "notify2" { NOTIFY c2, 'payload'; } +step "notify3" { NOTIFY c3, 'payload3'; } # not listening to c3 +step "notifyf" { SELECT pg_notify('c2', NULL); } +step "notifyd1" { NOTIFY c2, 'payload'; NOTIFY c1; NOTIFY "c2", 'payload'; } +step "notifyd2" { NOTIFY c1; NOTIFY c1; NOTIFY c1, 'p1'; NOTIFY c1, 'p2'; } +step "notifys1" { + BEGIN; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + SAVEPOINT s1; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads'; + NOTIFY c1, 'payload'; NOTIFY "c2", 'payload'; + NOTIFY c1, 'payloads'; NOTIFY "c2", 'payloads'; + RELEASE SAVEPOINT s1; + SAVEPOINT s2; + NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload'; + NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads'; + NOTIFY c1, 'rpayload'; NOTIFY "c2", 'rpayload'; + NOTIFY c1, 'rpayloads'; NOTIFY "c2", 'rpayloads'; + ROLLBACK TO SAVEPOINT s2; + COMMIT; +} +step "usage" { SELECT pg_notification_queue_usage() > 0 AS nonzero; } +step "bignotify" { SELECT count(pg_notify('c1', s::text)) FROM generate_series(1, 1000) s; } +teardown { UNLISTEN *; } + +# The listener session is used for cross-backend notify checks. + +session "listener" +step "llisten" { LISTEN c1; LISTEN c2; } +step "lcheck" { SELECT 1 AS x; } +step "lbegin" { BEGIN; } +teardown { UNLISTEN *; } + + +# Trivial cases. +permutation "listenc" "notify1" "notify2" "notify3" "notifyf" + +# Check simple and less-simple deduplication. +permutation "listenc" "notifyd1" "notifyd2" "notifys1" + +# Cross-backend notification delivery. We use a "select 1" to force the +# listener session to check for notifies. In principle we could just wait +# for delivery, but that would require extra support in isolationtester +# and might have portability-of-timing issues. +permutation "llisten" "notify1" "notify2" "notify3" "notifyf" "lcheck" + +# Again, with local delivery too. +permutation "listenc" "llisten" "notify1" "notify2" "notify3" "notifyf" "lcheck" + +# Verify that pg_notification_queue_usage correctly reports a non-zero result, +# after submitting notifications while another connection is listening for +# those notifications and waiting inside an active transaction. We have to +# fill a page of the notify SLRU to make this happen, which is a good deal +# of traffic. To not bloat the expected output, we intentionally don't +# commit the listener's transaction, so that it never reports these events. +# Hence, this should be the last test in this script. -permutation "listen" "begin" "check" "notify" "check" +permutation "llisten" "lbegin" "usage" "bignotify" "usage" diff --git a/src/test/isolation/specs/deadlock-parallel.spec b/src/test/isolation/specs/deadlock-parallel.spec new file mode 100644 index 00000000000..7ad290c0bdd --- /dev/null +++ b/src/test/isolation/specs/deadlock-parallel.spec @@ -0,0 +1,113 @@ +# Test deadlock resolution with parallel process groups. + +# It's fairly hard to get parallel worker processes to block on locks, +# since generally they don't want any locks their leader didn't already +# take. We cheat like mad here by making a function that takes a lock, +# and is incorrectly marked parallel-safe so that it can execute in a worker. + +# Note that we explicitly override any global settings of isolation level +# or force_parallel_mode, to ensure we're testing what we intend to. + +# Otherwise, this is morally equivalent to deadlock-soft.spec: +# Four-process deadlock with two hard edges and two soft edges. +# d2 waits for e1 (soft edge), e1 waits for d1 (hard edge), +# d1 waits for e2 (soft edge), e2 waits for d2 (hard edge). +# The deadlock detector resolves the deadlock by reversing the d1-e2 edge, +# unblocking d1. + +# However ... it's not actually that well-defined whether the deadlock +# detector will prefer to unblock d1 or d2. It depends on which backend +# is first to run DeadLockCheck after the deadlock condition is created: +# that backend will search outwards from its own wait condition, and will +# first find a loop involving the *other* lock. We encourage that to be +# one of the d2a1 parallel workers, which will therefore unblock d1a2 +# workers, by setting a shorter deadlock_timeout in session d2. But on +# slow machines, one or more d1a2 workers may not yet have reached their +# lock waits, so that they're not unblocked by the first DeadLockCheck. +# The next DeadLockCheck may choose to unblock the d2a1 workers instead, +# which would allow d2a1 to complete before d1a2, causing the test to +# freeze up because isolationtester isn't expecting that completion order. +# (In effect, we have an undetectable deadlock because d2 is waiting for +# d1's completion, but on the client side.) To fix this, introduce an +# additional lock (advisory lock 3), which is initially taken by d1 and +# then d2a1 will wait for it after completing the main part of the test. +# In this way, the deadlock detector can see that d1 must be completed +# first, regardless of timing. + +setup +{ + create function lock_share(int,int) returns int language sql as + 'select pg_advisory_xact_lock_shared($1); select 1;' parallel safe; + + create function lock_excl(int,int) returns int language sql as + 'select pg_advisory_xact_lock($1); select 1;' parallel safe; + + create table bigt as select x from generate_series(1, 10000) x; + analyze bigt; +} + +teardown +{ + drop function lock_share(int,int); + drop function lock_excl(int,int); + drop table bigt; +} + +session "d1" +setup { BEGIN isolation level repeatable read; + SET force_parallel_mode = off; + SET deadlock_timeout = '10s'; +} +# these locks will be taken in the leader, so they will persist: +step "d1a1" { SELECT lock_share(1,x), lock_excl(3,x) FROM bigt LIMIT 1; } +# this causes all the parallel workers to take locks: +step "d1a2" { SET force_parallel_mode = on; + SET parallel_setup_cost = 0; + SET parallel_tuple_cost = 0; + SET min_parallel_table_scan_size = 0; + SET parallel_leader_participation = off; + SET max_parallel_workers_per_gather = 3; + SELECT sum(lock_share(2,x)) FROM bigt; } +step "d1c" { COMMIT; } + +session "d2" +setup { BEGIN isolation level repeatable read; + SET force_parallel_mode = off; + SET deadlock_timeout = '10ms'; +} +# this lock will be taken in the leader, so it will persist: +step "d2a2" { select lock_share(2,x) FROM bigt LIMIT 1; } +# this causes all the parallel workers to take locks; +# after which, make the leader take lock 3 to prevent client-driven deadlock +step "d2a1" { SET force_parallel_mode = on; + SET parallel_setup_cost = 0; + SET parallel_tuple_cost = 0; + SET min_parallel_table_scan_size = 0; + SET parallel_leader_participation = off; + SET max_parallel_workers_per_gather = 3; + SELECT sum(lock_share(1,x)) FROM bigt; + SET force_parallel_mode = off; + RESET parallel_setup_cost; + RESET parallel_tuple_cost; + SELECT lock_share(3,x) FROM bigt LIMIT 1; } +step "d2c" { COMMIT; } + +session "e1" +setup { BEGIN isolation level repeatable read; + SET force_parallel_mode = on; + SET deadlock_timeout = '10s'; +} +# this lock will be taken in a parallel worker, but we don't need it to persist +step "e1l" { SELECT lock_excl(1,x) FROM bigt LIMIT 1; } +step "e1c" { COMMIT; } + +session "e2" +setup { BEGIN isolation level repeatable read; + SET force_parallel_mode = on; + SET deadlock_timeout = '10s'; +} +# this lock will be taken in a parallel worker, but we don't need it to persist +step "e2l" { SELECT lock_excl(2,x) FROM bigt LIMIT 1; } +step "e2c" { COMMIT; } + +permutation "d1a1" "d2a2" "e1l" "e2l" "d1a2" "d2a1" "d1c" "e1c" "d2c" "e2c" diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec index 51ab61dc862..222195873ac 100644 --- a/src/test/isolation/specs/eval-plan-qual.spec +++ b/src/test/isolation/specs/eval-plan-qual.spec @@ -9,6 +9,14 @@ setup CREATE TABLE accounts (accountid text PRIMARY KEY, balance numeric not null); INSERT INTO accounts VALUES ('checking', 600), ('savings', 600); + CREATE FUNCTION update_checking(int) RETURNS bool LANGUAGE sql AS $$ + UPDATE accounts SET balance = balance + 1 WHERE accountid = 'checking'; SELECT true;$$; + + CREATE TABLE accounts_ext (accountid text PRIMARY KEY, balance numeric not null, other text); + INSERT INTO accounts_ext VALUES ('checking', 600, 'other'), ('savings', 700, null); + ALTER TABLE accounts_ext ADD COLUMN newcol int DEFAULT 42; + ALTER TABLE accounts_ext ADD COLUMN newcol2 text DEFAULT NULL; + CREATE TABLE p (a int, b int, c int); CREATE TABLE c1 () INHERITS (p); CREATE TABLE c2 () INHERITS (p); @@ -24,21 +32,57 @@ setup CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data; CREATE INDEX ON jointest(id); + + CREATE TABLE parttbl (a int, b int, c int) PARTITION BY LIST (a); + CREATE TABLE parttbl1 PARTITION OF parttbl FOR VALUES IN (1); + CREATE TABLE parttbl2 PARTITION OF parttbl FOR VALUES IN (2); + INSERT INTO parttbl VALUES (1, 1, 1); + + CREATE TABLE another_parttbl (a int, b int, c int) PARTITION BY LIST (a); + CREATE TABLE another_parttbl1 PARTITION OF another_parttbl FOR VALUES IN (1); + CREATE TABLE another_parttbl2 PARTITION OF another_parttbl FOR VALUES IN (2); + INSERT INTO another_parttbl VALUES (1, 1, 1); + + CREATE FUNCTION noisy_oper(p_comment text, p_a anynonarray, p_op text, p_b anynonarray) + RETURNS bool LANGUAGE plpgsql AS $$ + DECLARE + r bool; + BEGIN + EXECUTE format('SELECT $1 %s $2', p_op) INTO r USING p_a, p_b; + RAISE NOTICE '%: % % % % %: %', p_comment, pg_typeof(p_a), p_a, p_op, pg_typeof(p_b), p_b, r; + RETURN r; + END;$$; } teardown { DROP TABLE accounts; + DROP FUNCTION update_checking(int); + DROP TABLE accounts_ext; DROP TABLE p CASCADE; DROP TABLE table_a, table_b, jointest; + DROP TABLE parttbl; + DROP TABLE another_parttbl; + DROP FUNCTION noisy_oper(text, anynonarray, text, anynonarray) } session "s1" setup { BEGIN ISOLATION LEVEL READ COMMITTED; } # wx1 then wx2 checks the basic case of re-fetching up-to-date values -step "wx1" { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking'; } +step "wx1" { UPDATE accounts SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; } # wy1 then wy2 checks the case where quals pass then fail -step "wy1" { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking'; } +step "wy1" { UPDATE accounts SET balance = balance + 500 WHERE accountid = 'checking' RETURNING balance; } + +step "wxext1" { UPDATE accounts_ext SET balance = balance - 200 WHERE accountid = 'checking' RETURNING balance; } +step "tocds1" { UPDATE accounts SET accountid = 'cds' WHERE accountid = 'checking'; } +step "tocdsext1" { UPDATE accounts_ext SET accountid = 'cds' WHERE accountid = 'checking'; } + +# d1 then wx1 checks that update can deal with the updated row vanishing +# wx2 then d1 checks that the delete affects the updated row +# wx2, wx2 then d1 checks that the delete checks the quals correctly (balance too high) +# wx2, d2, then d1 checks that delete handles a vanishing row correctly +step "d1" { DELETE FROM accounts WHERE accountid = 'checking' AND balance < 1500 RETURNING balance; } + # upsert tests are to check writable-CTE cases step "upsert1" { WITH upsert AS @@ -58,8 +102,9 @@ step "readp1" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND step "writep1" { UPDATE p SET b = -1 WHERE a = 1 AND b = 1 AND c = 0; } step "writep2" { UPDATE p SET b = -b WHERE a = 1 AND c = 0; } step "c1" { COMMIT; } +step "r1" { ROLLBACK; } -# these tests are meant to exercise EvalPlanQualFetchRowMarks, +# these tests are meant to exercise EvalPlanQualFetchRowMark, # ie, handling non-locked tables in an EvalPlanQual recheck step "partiallock" { @@ -68,8 +113,15 @@ step "partiallock" { FOR UPDATE OF a1; } step "lockwithvalues" { - SELECT * FROM accounts a1, (values('checking'),('savings')) v(id) - WHERE a1.accountid = v.id + -- Reference rowmark column that differs in type from targetlist at some attno. + -- See CAHU7rYZo_C4ULsAx_LAj8az9zqgrD8WDd4hTegDTMM1LMqrBsg@mail.gmail.com + SELECT a1.*, v.id FROM accounts a1, (values('checking'::text, 'nan'::text),('savings', 'nan')) v(id, notnumeric) + WHERE a1.accountid = v.id AND v.notnumeric != 'einszwei' + FOR UPDATE OF a1; +} +step "partiallock_ext" { + SELECT * FROM accounts_ext a1, accounts_ext a2 + WHERE a1.accountid = a2.accountid FOR UPDATE OF a1; } @@ -81,22 +133,62 @@ step "updateforss" { UPDATE table_b SET value = 'newTableBValue' WHERE id = 1; } +# these tests exercise EvalPlanQual with conditional InitPlans which +# have not been executed prior to the EPQ + +step "updateforcip" { + UPDATE table_a SET value = NULL WHERE id = 1; +} + # these tests exercise mark/restore during EPQ recheck, cf bug #15032 step "selectjoinforupdate" { - set enable_nestloop to 0; - set enable_hashjoin to 0; - set enable_seqscan to 0; + set local enable_nestloop to 0; + set local enable_hashjoin to 0; + set local enable_seqscan to 0; explain (costs off) select * from jointest a join jointest b on a.id=b.id for update; select * from jointest a join jointest b on a.id=b.id for update; } +# these tests exercise Result plan nodes participating in EPQ + +step "selectresultforupdate" { + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y; + explain (verbose, costs off) + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y for update of jt, ss1, ss2; + select * from (select 1 as x) ss1 join (select 7 as y) ss2 on true + left join table_a a on a.id = x, jointest jt + where jt.id = y for update of jt, ss1, ss2; +} + +# test for EPQ on a partitioned result table + +step "simplepartupdate" { + update parttbl set a = a; +} + +# test scenarios where update may cause row movement + +step "simplepartupdate_route1to2" { + update parttbl set a = 2 where c = 1 returning *; +} + +step "simplepartupdate_noroute" { + update parttbl set b = 2 where c = 1 returning *; +} + session "s2" setup { BEGIN ISOLATION LEVEL READ COMMITTED; } -step "wx2" { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking'; } -step "wy2" { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000; } +step "wx2" { UPDATE accounts SET balance = balance + 450 WHERE accountid = 'checking' RETURNING balance; } +step "wy2" { UPDATE accounts SET balance = balance + 1000 WHERE accountid = 'checking' AND balance < 1000 RETURNING balance; } +step "d2" { DELETE FROM accounts WHERE accountid = 'checking'; } + step "upsert2" { WITH upsert AS (UPDATE accounts SET balance = balance + 1234 @@ -105,6 +197,7 @@ step "upsert2" { INSERT INTO accounts SELECT 'savings', 1234 WHERE NOT EXISTS (SELECT 1 FROM upsert); } +step "wx2_ext" { UPDATE accounts_ext SET balance = balance + 450; } step "readp2" { SELECT tableoid::regclass, ctid, * FROM p WHERE b IN (0, 1) AND c = 0 FOR UPDATE; } step "returningp1" { WITH u AS ( UPDATE p SET b = b WHERE a > 0 RETURNING * ) @@ -117,13 +210,66 @@ step "readforss" { FROM table_a ta WHERE ta.id = 1 FOR UPDATE OF ta; } +step "updateforcip2" { + UPDATE table_a SET value = COALESCE(value, (SELECT text 'newValue')) WHERE id = 1; +} +step "updateforcip3" { + WITH d(val) AS (SELECT text 'newValue' FROM generate_series(1,1)) + UPDATE table_a SET value = COALESCE(value, (SELECT val FROM d)) WHERE id = 1; +} step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; } step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; } +step "complexpartupdate" { + with u as (update parttbl set a = a returning parttbl.*) + update parttbl set a = u.a from u; +} + +step "complexpartupdate_route_err1" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = u.a from u where p.a = u.a and p.c = 1 returning p.*; +} + +step "complexpartupdate_route" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = p.b from u where p.a = u.a and p.c = 1 returning p.*; +} + +step "complexpartupdate_doesnt_route" { + with u as (update another_parttbl set a = 1 returning another_parttbl.*) + update parttbl p set a = 3 - p.b from u where p.a = u.a and p.c = 1 returning p.*; +} + +# Use writable CTEs to create self-updated rows, that then are +# (updated|deleted). The *fail versions of the tests additionally +# perform an update, via a function, in a different command, to test +# behaviour relating to that. +step "updwcte" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } +step "updwctefail" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) UPDATE accounts a SET balance = doup.balance + 100 FROM doup RETURNING *; } +step "delwcte" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *) DELETE FROM accounts a USING doup RETURNING *; } +step "delwctefail" { WITH doup AS (UPDATE accounts SET balance = balance + 1100 WHERE accountid = 'checking' RETURNING *, update_checking(999)) DELETE FROM accounts a USING doup RETURNING *; } + +# Check that nested EPQ works correctly +step "wnested2" { + UPDATE accounts SET balance = balance - 1200 + WHERE noisy_oper('upid', accountid, '=', 'checking') + AND noisy_oper('up', balance, '>', 200.0) + AND EXISTS ( + SELECT accountid + FROM accounts_ext ae + WHERE noisy_oper('lock_id', ae.accountid, '=', accounts.accountid) + AND noisy_oper('lock_bal', ae.balance, '>', 200.0) + FOR UPDATE + ); +} + step "c2" { COMMIT; } +step "r2" { ROLLBACK; } session "s3" setup { BEGIN ISOLATION LEVEL READ COMMITTED; } step "read" { SELECT * FROM accounts ORDER BY accountid; } +step "read_ext" { SELECT * FROM accounts_ext ORDER BY accountid; } +step "read_a" { SELECT * FROM table_a ORDER BY id; } # this test exercises EvalPlanQual with a CTE, cf bug #14328 step "readwcte" { @@ -149,14 +295,61 @@ step "multireadwcte" { teardown { COMMIT; } +# test that normal update follows update chains, and reverifies quals permutation "wx1" "wx2" "c1" "c2" "read" permutation "wy1" "wy2" "c1" "c2" "read" +permutation "wx1" "wx2" "r1" "c2" "read" +permutation "wy1" "wy2" "r1" "c2" "read" + +# test that deletes follow chains, and if necessary reverifies quals +permutation "wx1" "d1" "wx2" "c1" "c2" "read" +permutation "wx2" "d1" "c2" "c1" "read" +permutation "wx2" "wx2" "d1" "c2" "c1" "read" +permutation "wx2" "d2" "d1" "c2" "c1" "read" +permutation "wx1" "d1" "wx2" "r1" "c2" "read" +permutation "wx2" "d1" "r2" "c1" "read" +permutation "wx2" "wx2" "d1" "r2" "c1" "read" +permutation "wx2" "d2" "d1" "r2" "c1" "read" +permutation "d1" "wx2" "c1" "c2" "read" +permutation "d1" "wx2" "r1" "c2" "read" + +# Check that nested EPQ works correctly +permutation "wnested2" "c1" "c2" "read" +permutation "wx1" "wxext1" "wnested2" "c1" "c2" "read" +permutation "wx1" "wx1" "wxext1" "wnested2" "c1" "c2" "read" +permutation "wx1" "wx1" "wxext1" "wxext1" "wnested2" "c1" "c2" "read" +permutation "wx1" "wxext1" "wxext1" "wnested2" "c1" "c2" "read" +permutation "wx1" "tocds1" "wnested2" "c1" "c2" "read" +permutation "wx1" "tocdsext1" "wnested2" "c1" "c2" "read" + +# test that an update to a self-modified row is ignored when +# previously updated by the same cid +permutation "wx1" "updwcte" "c1" "c2" "read" +# test that an update to a self-modified row throws error when +# previously updated by a different cid +permutation "wx1" "updwctefail" "c1" "c2" "read" +# test that a delete to a self-modified row is ignored when +# previously updated by the same cid +permutation "wx1" "delwcte" "c1" "c2" "read" +# test that a delete to a self-modified row throws error when +# previously updated by a different cid +permutation "wx1" "delwctefail" "c1" "c2" "read" + permutation "upsert1" "upsert2" "c1" "c2" "read" permutation "readp1" "writep1" "readp2" "c1" "c2" permutation "writep2" "returningp1" "c1" "c2" permutation "wx2" "partiallock" "c2" "c1" "read" permutation "wx2" "lockwithvalues" "c2" "c1" "read" +permutation "wx2_ext" "partiallock_ext" "c2" "c1" "read_ext" permutation "updateforss" "readforss" "c1" "c2" +permutation "updateforcip" "updateforcip2" "c1" "c2" "read_a" +permutation "updateforcip" "updateforcip3" "c1" "c2" "read_a" permutation "wrtwcte" "readwcte" "c1" "c2" permutation "wrjt" "selectjoinforupdate" "c2" "c1" +permutation "wrjt" "selectresultforupdate" "c2" "c1" permutation "wrtwcte" "multireadwcte" "c1" "c2" + +permutation "simplepartupdate" "complexpartupdate" "c1" "c2" +permutation "simplepartupdate_route1to2" "complexpartupdate_route_err1" "c1" "c2" +permutation "simplepartupdate_noroute" "complexpartupdate_route" "c1" "c2" +permutation "simplepartupdate_noroute" "complexpartupdate_doesnt_route" "c1" "c2" diff --git a/src/test/isolation/specs/fk-partitioned-1.spec b/src/test/isolation/specs/fk-partitioned-1.spec new file mode 100644 index 00000000000..4c760e89b34 --- /dev/null +++ b/src/test/isolation/specs/fk-partitioned-1.spec @@ -0,0 +1,45 @@ +# Verify that cloning a foreign key constraint to a partition ensures +# that referenced values exist, even if they're being concurrently +# deleted. +setup { +drop table if exists ppk, pfk, pfk1; + create table ppk (a int primary key) partition by list (a); + create table ppk1 partition of ppk for values in (1); + insert into ppk values (1); + create table pfk (a int references ppk) partition by list (a); + create table pfk1 (a int not null); + insert into pfk1 values (1); +} + +session "s1" +step "s1b" { begin; } +step "s1d" { delete from ppk1 where a = 1; } +step "s1c" { commit; } + +session "s2" +step "s2b" { begin; } +step "s2a" { alter table pfk attach partition pfk1 for values in (1); } +step "s2c" { commit; } + +teardown { drop table ppk, pfk, pfk1; } + +permutation "s1b" "s1d" "s1c" "s2b" "s2a" "s2c" +permutation "s1b" "s1d" "s2b" "s1c" "s2a" "s2c" +permutation "s1b" "s1d" "s2b" "s2a" "s1c" "s2c" +#permutation "s1b" "s1d" "s2b" "s2a" "s2c" "s1c" +permutation "s1b" "s2b" "s1d" "s1c" "s2a" "s2c" +permutation "s1b" "s2b" "s1d" "s2a" "s1c" "s2c" +#permutation "s1b" "s2b" "s1d" "s2a" "s2c" "s1c" +#permutation "s1b" "s2b" "s2a" "s1d" "s1c" "s2c" +permutation "s1b" "s2b" "s2a" "s1d" "s2c" "s1c" +permutation "s1b" "s2b" "s2a" "s2c" "s1d" "s1c" +permutation "s2b" "s1b" "s1d" "s1c" "s2a" "s2c" +permutation "s2b" "s1b" "s1d" "s2a" "s1c" "s2c" +#permutation "s2b" "s1b" "s1d" "s2a" "s2c" "s1c" +#permutation "s2b" "s1b" "s2a" "s1d" "s1c" "s2c" +permutation "s2b" "s1b" "s2a" "s1d" "s2c" "s1c" +permutation "s2b" "s1b" "s2a" "s2c" "s1d" "s1c" +#permutation "s2b" "s2a" "s1b" "s1d" "s1c" "s2c" +permutation "s2b" "s2a" "s1b" "s1d" "s2c" "s1c" +permutation "s2b" "s2a" "s1b" "s2c" "s1d" "s1c" +permutation "s2b" "s2a" "s2c" "s1b" "s1d" "s1c" diff --git a/src/test/isolation/specs/fk-partitioned-2.spec b/src/test/isolation/specs/fk-partitioned-2.spec new file mode 100644 index 00000000000..f1a76e801cf --- /dev/null +++ b/src/test/isolation/specs/fk-partitioned-2.spec @@ -0,0 +1,29 @@ +# Make sure that FKs referencing partitioned tables actually work. +setup { + drop table if exists ppk, pfk, pfk1; + create table ppk (a int primary key) partition by list (a); + create table ppk1 partition of ppk for values in (1); + insert into ppk values (1); + create table pfk (a int references ppk) partition by list (a); + create table pfk1 partition of pfk for values in (1); +} + +session "s1" +step "s1b" { begin; } +step "s1d" { delete from ppk where a = 1; } +step "s1c" { commit; } + +session "s2" +step "s2b" { begin; } +step "s2bs" { begin isolation level serializable; select 1; } +step "s2i" { insert into pfk values (1); } +step "s2c" { commit; } + +teardown { drop table ppk, pfk, pfk1; } + +permutation "s1b" "s1d" "s2b" "s2i" "s1c" "s2c" +permutation "s1b" "s1d" "s2bs" "s2i" "s1c" "s2c" +permutation "s1b" "s2b" "s1d" "s2i" "s1c" "s2c" +permutation "s1b" "s2bs" "s1d" "s2i" "s1c" "s2c" +permutation "s1b" "s2b" "s2i" "s1d" "s2c" "s1c" +permutation "s1b" "s2bs" "s2i" "s1d" "s2c" "s1c" diff --git a/src/test/isolation/specs/freeze-the-dead.spec b/src/test/isolation/specs/freeze-the-dead.spec index e24d7d5d116..915bf15b925 100644 --- a/src/test/isolation/specs/freeze-the-dead.spec +++ b/src/test/isolation/specs/freeze-the-dead.spec @@ -19,7 +19,6 @@ session "s1" step "s1_begin" { BEGIN; } step "s1_update" { UPDATE tab_freeze SET x = x + 1 WHERE id = 3; } step "s1_commit" { COMMIT; } -step "s1_vacuum" { VACUUM FREEZE tab_freeze; } step "s1_selectone" { BEGIN; SET LOCAL enable_seqscan = false; @@ -28,7 +27,6 @@ step "s1_selectone" { COMMIT; } step "s1_selectall" { SELECT * FROM tab_freeze ORDER BY name, id; } -step "s1_reindex" { REINDEX TABLE tab_freeze; } session "s2" step "s2_begin" { BEGIN; } @@ -40,9 +38,8 @@ session "s3" step "s3_begin" { BEGIN; } step "s3_key_share" { SELECT id FROM tab_freeze WHERE id = 3 FOR KEY SHARE; } step "s3_commit" { COMMIT; } -step "s3_vacuum" { VACUUM FREEZE tab_freeze; } -# This permutation verfies that a previous bug +# This permutation verifies that a previous bug # https://postgr.es/m/E5711E62-8FDF-4DCA-A888-C200BF6B5742@amazon.com # https://postgr.es/m/20171102112019.33wb7g5wp4zpjelu@alap3.anarazel.de # is not reintroduced. We used to make wrong pruning / freezing diff --git a/src/test/isolation/specs/inherit-temp.spec b/src/test/isolation/specs/inherit-temp.spec new file mode 100644 index 00000000000..5cd251d0aaa --- /dev/null +++ b/src/test/isolation/specs/inherit-temp.spec @@ -0,0 +1,78 @@ +# Tests for inheritance trees with temporary relations +# +# Inheritance trees are allowed to mix relations with different persistence +# as long as a persistent child relation does not try to inherit from a +# temporary parent. This checks several scenarios with SELECT, INSERT, UPDATE, +# DELETE and TRUNCATE. Any temporary relation inheriting from the same +# persistent parent should be isolated and handled only in its own session. + +setup +{ + CREATE TABLE inh_parent (a int); +} + +teardown +{ + DROP TABLE inh_parent; +} + +# Session 1 executes actions which act directly on both the parent and +# its child. Abbreviation "c" is used for queries working on the child +# and "p" on the parent. +session "s1" +setup +{ + CREATE TEMPORARY TABLE inh_temp_child_s1 () INHERITS (inh_parent); +} +step "s1_begin" { BEGIN; } +step "s1_truncate_p" { TRUNCATE inh_parent; } +step "s1_select_p" { SELECT a FROM inh_parent; } +step "s1_select_c" { SELECT a FROM inh_temp_child_s1; } +step "s1_insert_p" { INSERT INTO inh_parent VALUES (1), (2); } +step "s1_insert_c" { INSERT INTO inh_temp_child_s1 VALUES (3), (4); } +step "s1_update_p" { UPDATE inh_parent SET a = 11 WHERE a = 1; } +step "s1_update_c" { UPDATE inh_parent SET a = 13 WHERE a IN (3, 5); } +step "s1_delete_p" { DELETE FROM inh_parent WHERE a = 2; } +step "s1_delete_c" { DELETE FROM inh_parent WHERE a IN (4, 6); } +step "s1_commit" { COMMIT; } +teardown +{ + DROP TABLE inh_temp_child_s1; +} + +# Session 2 executes actions on the parent which act only on the child. +session "s2" +setup +{ + CREATE TEMPORARY TABLE inh_temp_child_s2 () INHERITS (inh_parent); +} +step "s2_truncate_p" { TRUNCATE inh_parent; } +step "s2_select_p" { SELECT a FROM inh_parent; } +step "s2_select_c" { SELECT a FROM inh_temp_child_s2; } +step "s2_insert_c" { INSERT INTO inh_temp_child_s2 VALUES (5), (6); } +step "s2_update_c" { UPDATE inh_parent SET a = 15 WHERE a IN (3, 5); } +step "s2_delete_c" { DELETE FROM inh_parent WHERE a IN (4, 6); } +teardown +{ + DROP TABLE inh_temp_child_s2; +} + +# Check INSERT behavior across sessions +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" + +# Check UPDATE behavior across sessions +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_update_p" "s1_update_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_update_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" + +# Check DELETE behavior across sessions +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_delete_p" "s1_delete_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_delete_c" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" + +# Check TRUNCATE behavior across sessions +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_truncate_p" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s2_truncate_p" "s1_select_p" "s1_select_c" "s2_select_p" "s2_select_c" + +# TRUNCATE on a parent tree does not block access to temporary child relation +# of another session, and blocks when scanning the parent. +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_begin" "s1_truncate_p" "s2_select_p" "s1_commit" +permutation "s1_insert_p" "s1_insert_c" "s2_insert_c" "s1_begin" "s1_truncate_p" "s2_select_c" "s1_commit" diff --git a/src/test/isolation/specs/insert-conflict-do-nothing.spec b/src/test/isolation/specs/insert-conflict-do-nothing.spec index 9b92c35cec6..71acc380c7a 100644 --- a/src/test/isolation/specs/insert-conflict-do-nothing.spec +++ b/src/test/isolation/specs/insert-conflict-do-nothing.spec @@ -33,7 +33,6 @@ setup step "donothing2" { INSERT INTO ints(key, val) VALUES(1, 'donothing2') ON CONFLICT DO NOTHING; } step "select2" { SELECT * FROM ints; } step "c2" { COMMIT; } -step "a2" { ABORT; } # Regular case where one session block-waits on another to determine if it # should proceed with an insert or do nothing. diff --git a/src/test/isolation/specs/insert-conflict-do-update-2.spec b/src/test/isolation/specs/insert-conflict-do-update-2.spec index f5b4f601b58..12f6be8000f 100644 --- a/src/test/isolation/specs/insert-conflict-do-update-2.spec +++ b/src/test/isolation/specs/insert-conflict-do-update-2.spec @@ -32,7 +32,6 @@ setup step "insert2" { INSERT INTO upsert(key, payload) VALUES('FOOFOO', 'insert2') ON CONFLICT (lower(key)) DO UPDATE set key = EXCLUDED.key, payload = upsert.payload || ' updated by insert2'; } step "select2" { SELECT * FROM upsert; } step "c2" { COMMIT; } -step "a2" { ABORT; } # One session (session 2) block-waits on another (session 1) to determine if it # should proceed with an insert or update. The user can still usefully UPDATE diff --git a/src/test/isolation/specs/insert-conflict-do-update.spec b/src/test/isolation/specs/insert-conflict-do-update.spec index 5d335a34449..7c8cb471002 100644 --- a/src/test/isolation/specs/insert-conflict-do-update.spec +++ b/src/test/isolation/specs/insert-conflict-do-update.spec @@ -30,7 +30,6 @@ setup step "insert2" { INSERT INTO upsert(key, val) VALUES(1, 'insert2') ON CONFLICT (key) DO UPDATE set val = upsert.val || ' updated by insert2'; } step "select2" { SELECT * FROM upsert; } step "c2" { COMMIT; } -step "a2" { ABORT; } # One session (session 2) block-waits on another (session 1) to determine if it # should proceed with an insert or update. Notably, this entails updating a diff --git a/src/test/isolation/specs/insert-conflict-specconflict.spec b/src/test/isolation/specs/insert-conflict-specconflict.spec new file mode 100644 index 00000000000..3a70484fc29 --- /dev/null +++ b/src/test/isolation/specs/insert-conflict-specconflict.spec @@ -0,0 +1,149 @@ +# INSERT ... ON CONFLICT test verifying that speculative insertion +# failures are handled +# +# Does this by using advisory locks controlling progress of +# insertions. By waiting when building the index keys, it's possible +# to schedule concurrent INSERT ON CONFLICTs so that there will always +# be a speculative conflict. + +setup +{ + CREATE OR REPLACE FUNCTION blurt_and_lock(text) RETURNS text IMMUTABLE LANGUAGE plpgsql AS $$ + BEGIN + RAISE NOTICE 'called for %', $1; + + -- depending on lock state, wait for lock 2 or 3 + IF pg_try_advisory_xact_lock(current_setting('spec.session')::int, 1) THEN + RAISE NOTICE 'blocking 2'; + PERFORM pg_advisory_xact_lock(current_setting('spec.session')::int, 2); + ELSE + RAISE NOTICE 'blocking 3'; + PERFORM pg_advisory_xact_lock(current_setting('spec.session')::int, 3); + END IF; + RETURN $1; + END;$$; + + CREATE TABLE upserttest(key text, data text); + + CREATE UNIQUE INDEX ON upserttest((blurt_and_lock(key))); +} + +teardown +{ + DROP TABLE upserttest; +} + +session "controller" +setup +{ + SET default_transaction_isolation = 'read committed'; +} +step "controller_locks" {SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock);} +step "controller_unlock_1_1" { SELECT pg_advisory_unlock(1, 1); } +step "controller_unlock_2_1" { SELECT pg_advisory_unlock(2, 1); } +step "controller_unlock_1_2" { SELECT pg_advisory_unlock(1, 2); } +step "controller_unlock_2_2" { SELECT pg_advisory_unlock(2, 2); } +step "controller_unlock_1_3" { SELECT pg_advisory_unlock(1, 3); } +step "controller_unlock_2_3" { SELECT pg_advisory_unlock(2, 3); } +step "controller_show" {SELECT * FROM upserttest; } + +session "s1" +setup +{ + SET default_transaction_isolation = 'read committed'; + SET spec.session = 1; +} +step "s1_begin" { BEGIN; } +step "s1_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s1') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s1'; } +step "s1_commit" { COMMIT; } + +session "s2" +setup +{ + SET default_transaction_isolation = 'read committed'; + SET spec.session = 2; +} +step "s2_begin" { BEGIN; } +step "s2_upsert" { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; } +step "s2_commit" { COMMIT; } + +# Test that speculative locks are correctly acquired and released, s2 +# inserts, s1 updates. +permutation + # acquire a number of locks, to control execution flow - the + # blurt_and_lock function acquires advisory locks that allow us to + # continue after a) the optimistic conflict probe b) after the + # insertion of the speculative tuple. + "controller_locks" + "controller_show" + "s1_upsert" "s2_upsert" + "controller_show" + # Switch both sessions to wait on the other lock next time (the speculative insertion) + "controller_unlock_1_1" "controller_unlock_2_1" + # Allow both sessions to continue + "controller_unlock_1_3" "controller_unlock_2_3" + "controller_show" + # Allow the second session to finish insertion + "controller_unlock_2_2" + # This should now show a successful insertion + "controller_show" + # Allow the first session to finish insertion + "controller_unlock_1_2" + # This should now show a successful UPSERT + "controller_show" + +# Test that speculative locks are correctly acquired and released, s2 +# inserts, s1 updates. +permutation + # acquire a number of locks, to control execution flow - the + # blurt_and_lock function acquires advisory locks that allow us to + # continue after a) the optimistic conflict probe b) after the + # insertion of the speculative tuple. + "controller_locks" + "controller_show" + "s1_upsert" "s2_upsert" + "controller_show" + # Switch both sessions to wait on the other lock next time (the speculative insertion) + "controller_unlock_1_1" "controller_unlock_2_1" + # Allow both sessions to continue + "controller_unlock_1_3" "controller_unlock_2_3" + "controller_show" + # Allow the first session to finish insertion + "controller_unlock_1_2" + # This should now show a successful insertion + "controller_show" + # Allow the second session to finish insertion + "controller_unlock_2_2" + # This should now show a successful UPSERT + "controller_show" + +# Test that speculative locks are correctly acquired and released, s2 +# inserts, s1 updates. With the added complication that transactions +# don't immediately commit. +permutation + # acquire a number of locks, to control execution flow - the + # blurt_and_lock function acquires advisory locks that allow us to + # continue after a) the optimistic conflict probe b) after the + # insertion of the speculative tuple. + "controller_locks" + "controller_show" + "s1_begin" "s2_begin" + "s1_upsert" "s2_upsert" + "controller_show" + # Switch both sessions to wait on the other lock next time (the speculative insertion) + "controller_unlock_1_1" "controller_unlock_2_1" + # Allow both sessions to continue + "controller_unlock_1_3" "controller_unlock_2_3" + "controller_show" + # Allow the first session to finish insertion + "controller_unlock_1_2" + # But the change isn't visible yet, nor should the second session continue + "controller_show" + # Allow the second session to finish insertion, but it's blocked + "controller_unlock_2_2" + "controller_show" + # But committing should unblock + "s1_commit" + "controller_show" + "s2_commit" + "controller_show" diff --git a/src/test/isolation/specs/merge-delete.spec b/src/test/isolation/specs/merge-delete.spec deleted file mode 100644 index 656954f8474..00000000000 --- a/src/test/isolation/specs/merge-delete.spec +++ /dev/null @@ -1,51 +0,0 @@ -# MERGE DELETE -# -# This test looks at the interactions involving concurrent deletes -# comparing the behavior of MERGE, DELETE and UPDATE - -setup -{ - CREATE TABLE target (key int primary key, val text); - INSERT INTO target VALUES (1, 'setup1'); -} - -teardown -{ - DROP TABLE target; -} - -session "s1" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "delete" { DELETE FROM target t WHERE t.key = 1; } -step "merge_delete" { MERGE INTO target t USING (SELECT 1 as key) s ON s.key = t.key WHEN MATCHED THEN DELETE; } -step "c1" { COMMIT; } -step "a1" { ABORT; } - -session "s2" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "update1" { UPDATE target t SET val = t.val || ' updated by update1' WHERE t.key = 1; } -step "merge2" { MERGE INTO target t USING (SELECT 1 as key, 'merge2a' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; } -step "select2" { SELECT * FROM target; } -step "c2" { COMMIT; } - -# Basic effects -permutation "delete" "c1" "select2" "c2" -permutation "merge_delete" "c1" "select2" "c2" - -# One after the other, no concurrency -permutation "delete" "c1" "update1" "select2" "c2" -permutation "merge_delete" "c1" "update1" "select2" "c2" -permutation "delete" "c1" "merge2" "select2" "c2" -permutation "merge_delete" "c1" "merge2" "select2" "c2" - -# Now with concurrency -permutation "delete" "update1" "c1" "select2" "c2" -permutation "merge_delete" "update1" "c1" "select2" "c2" -permutation "delete" "merge2" "c1" "select2" "c2" -permutation "merge_delete" "merge2" "c1" "select2" "c2" diff --git a/src/test/isolation/specs/merge-insert-update.spec b/src/test/isolation/specs/merge-insert-update.spec deleted file mode 100644 index 704492be1f3..00000000000 --- a/src/test/isolation/specs/merge-insert-update.spec +++ /dev/null @@ -1,52 +0,0 @@ -# MERGE INSERT UPDATE -# -# This looks at how we handle concurrent INSERTs, illustrating how the -# behavior differs from INSERT ... ON CONFLICT - -setup -{ - CREATE TABLE target (key int primary key, val text); -} - -teardown -{ - DROP TABLE target; -} - -session "s1" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "merge1" { MERGE INTO target t USING (SELECT 1 as key, 'merge1' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge1'; } -step "delete1" { DELETE FROM target WHERE key = 1; } -step "insert1" { INSERT INTO target VALUES (1, 'insert1'); } -step "c1" { COMMIT; } -step "a1" { ABORT; } - -session "s2" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "merge2" { MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN NOT MATCHED THEN INSERT VALUES (s.key, s.val) WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; } - -step "merge2i" { MERGE INTO target t USING (SELECT 1 as key, 'merge2' as val) s ON s.key = t.key WHEN MATCHED THEN UPDATE set val = t.val || ' updated by merge2'; } - -step "select2" { SELECT * FROM target; } -step "c2" { COMMIT; } -step "a2" { ABORT; } - -# Basic effects -permutation "merge1" "c1" "select2" "c2" -permutation "merge1" "c1" "merge2" "select2" "c2" - -# check concurrent inserts -permutation "insert1" "merge2" "c1" "select2" "c2" -permutation "merge1" "merge2" "c1" "select2" "c2" -permutation "merge1" "merge2" "a1" "select2" "c2" - -# check how we handle when visible row has been concurrently deleted, then same key re-inserted -permutation "delete1" "insert1" "c1" "merge2" "select2" "c2" -permutation "delete1" "insert1" "merge2" "c1" "select2" "c2" -permutation "delete1" "insert1" "merge2i" "c1" "select2" "c2" diff --git a/src/test/isolation/specs/merge-match-recheck.spec b/src/test/isolation/specs/merge-match-recheck.spec deleted file mode 100644 index 193033da172..00000000000 --- a/src/test/isolation/specs/merge-match-recheck.spec +++ /dev/null @@ -1,79 +0,0 @@ -# MERGE MATCHED RECHECK -# -# This test looks at what happens when we have complex -# WHEN MATCHED AND conditions and a concurrent UPDATE causes a -# recheck of the AND condition on the new row - -setup -{ - CREATE TABLE target (key int primary key, balance integer, status text, val text); - INSERT INTO target VALUES (1, 160, 's1', 'setup'); -} - -teardown -{ - DROP TABLE target; -} - -session "s1" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "merge_status" -{ - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND status = 's1' THEN - UPDATE SET status = 's2', val = t.val || ' when1' - WHEN MATCHED AND status = 's2' THEN - UPDATE SET status = 's3', val = t.val || ' when2' - WHEN MATCHED AND status = 's3' THEN - UPDATE SET status = 's4', val = t.val || ' when3'; -} - -step "merge_bal" -{ - MERGE INTO target t - USING (SELECT 1 as key) s - ON s.key = t.key - WHEN MATCHED AND balance < 100 THEN - UPDATE SET balance = balance * 2, val = t.val || ' when1' - WHEN MATCHED AND balance < 200 THEN - UPDATE SET balance = balance * 4, val = t.val || ' when2' - WHEN MATCHED AND balance < 300 THEN - UPDATE SET balance = balance * 8, val = t.val || ' when3'; -} - -step "select1" { SELECT * FROM target; } -step "c1" { COMMIT; } -step "a1" { ABORT; } - -session "s2" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "update1" { UPDATE target t SET balance = balance + 10, val = t.val || ' updated by update1' WHERE t.key = 1; } -step "update2" { UPDATE target t SET status = 's2', val = t.val || ' updated by update2' WHERE t.key = 1; } -step "update3" { UPDATE target t SET status = 's3', val = t.val || ' updated by update3' WHERE t.key = 1; } -step "update5" { UPDATE target t SET status = 's5', val = t.val || ' updated by update5' WHERE t.key = 1; } -step "update_bal1" { UPDATE target t SET balance = 50, val = t.val || ' updated by update_bal1' WHERE t.key = 1; } -step "select2" { SELECT * FROM target; } -step "c2" { COMMIT; } - -# merge_status sees concurrently updated row and rechecks WHEN conditions, but recheck passes and final status = 's2' -permutation "update1" "merge_status" "c2" "select1" "c1" - -# merge_status sees concurrently updated row and rechecks WHEN conditions, recheck fails, so final status = 's3' not 's2' -permutation "update2" "merge_status" "c2" "select1" "c1" - -# merge_status sees concurrently updated row and rechecks WHEN conditions, recheck fails, so final status = 's4' not 's2' -permutation "update3" "merge_status" "c2" "select1" "c1" - -# merge_status sees concurrently updated row and rechecks WHEN conditions, recheck fails, but we skip update and MERGE does nothing -permutation "update5" "merge_status" "c2" "select1" "c1" - -# merge_bal sees concurrently updated row and rechecks WHEN conditions, recheck fails, so final balance = 100 not 640 -permutation "update_bal1" "merge_bal" "c2" "select1" "c1" diff --git a/src/test/isolation/specs/merge-update.spec b/src/test/isolation/specs/merge-update.spec deleted file mode 100644 index 625b477eb9f..00000000000 --- a/src/test/isolation/specs/merge-update.spec +++ /dev/null @@ -1,133 +0,0 @@ -# MERGE UPDATE -# -# This test exercises atypical cases -# 1. UPDATEs of PKs that change the join in the ON clause -# 2. UPDATEs with WHEN AND conditions that would fail after concurrent update -# 3. UPDATEs with extra ON conditions that would fail after concurrent update - -setup -{ - CREATE TABLE target (key int primary key, val text); - INSERT INTO target VALUES (1, 'setup1'); - - CREATE TABLE pa_target (key integer, val text) - PARTITION BY LIST (key); - CREATE TABLE part1 (key integer, val text); - CREATE TABLE part2 (val text, key integer); - CREATE TABLE part3 (key integer, val text); - - ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4); - ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6); - ALTER TABLE pa_target ATTACH PARTITION part3 DEFAULT; - - INSERT INTO pa_target VALUES (1, 'initial'); - INSERT INTO pa_target VALUES (2, 'initial'); -} - -teardown -{ - DROP TABLE target; - DROP TABLE pa_target CASCADE; -} - -session "s1" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "merge1" -{ - MERGE INTO target t - USING (SELECT 1 as key, 'merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "pa_merge1" -{ - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set val = t.val || ' updated by ' || s.val; -} -step "pa_merge2" -{ - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge1' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "c1" { COMMIT; } -step "a1" { ABORT; } - -session "s2" -setup -{ - BEGIN ISOLATION LEVEL READ COMMITTED; -} -step "merge2a" -{ - MERGE INTO target t - USING (SELECT 1 as key, 'merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "merge2b" -{ - MERGE INTO target t - USING (SELECT 1 as key, 'merge2b' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED AND t.key < 2 THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "merge2c" -{ - MERGE INTO target t - USING (SELECT 1 as key, 'merge2c' as val) s - ON s.key = t.key AND t.key < 2 - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "pa_merge2a" -{ - MERGE INTO pa_target t - USING (SELECT 1 as key, 'pa_merge2a' as val) s - ON s.key = t.key - WHEN NOT MATCHED THEN - INSERT VALUES (s.key, s.val) - WHEN MATCHED THEN - UPDATE set key = t.key + 1, val = t.val || ' updated by ' || s.val; -} -step "select2" { SELECT * FROM target; } -step "pa_select2" { SELECT * FROM pa_target; } -step "c2" { COMMIT; } - -# Basic effects -permutation "merge1" "c1" "select2" "c2" - -# One after the other, no concurrency -permutation "merge1" "c1" "merge2a" "select2" "c2" - -# Now with concurrency -permutation "merge1" "merge2a" "c1" "select2" "c2" -permutation "merge1" "merge2a" "a1" "select2" "c2" -permutation "merge1" "merge2b" "c1" "select2" "c2" -permutation "merge1" "merge2c" "c1" "select2" "c2" -permutation "pa_merge1" "pa_merge2a" "c1" "pa_select2" "c2" -permutation "pa_merge2" "pa_merge2a" "c1" "pa_select2" "c2" # fails -permutation "pa_merge2" "c1" "pa_merge2a" "pa_select2" "c2" # succeeds diff --git a/src/test/isolation/specs/partition-key-update-1.spec b/src/test/isolation/specs/partition-key-update-1.spec index 8393f47c596..79db1d0f307 100644 --- a/src/test/isolation/specs/partition-key-update-1.spec +++ b/src/test/isolation/specs/partition-key-update-1.spec @@ -66,6 +66,7 @@ step "s2c" { COMMIT; } # Concurrency error from ExecUpdate and ExecDelete. permutation "s1b" "s2b" "s1u" "s1c" "s2d" "s2c" permutation "s1b" "s2b" "s1u" "s2d" "s1c" "s2c" +permutation "s1b" "s2b" "s1u" "s2u" "s1c" "s2c" permutation "s1b" "s2b" "s2d" "s1u" "s2c" "s1c" # Concurrency error from GetTupleForTrigger diff --git a/src/test/isolation/specs/partition-key-update-4.spec b/src/test/isolation/specs/partition-key-update-4.spec new file mode 100644 index 00000000000..3d1579b244e --- /dev/null +++ b/src/test/isolation/specs/partition-key-update-4.spec @@ -0,0 +1,76 @@ +# Test that a row that ends up in a new partition contains changes made by +# a concurrent transaction. + +setup +{ + -- + -- Setup to test concurrent handling of ExecDelete(). + -- + CREATE TABLE foo (a int, b text) PARTITION BY LIST(a); + CREATE TABLE foo1 PARTITION OF foo FOR VALUES IN (1); + CREATE TABLE foo2 PARTITION OF foo FOR VALUES IN (2); + INSERT INTO foo VALUES (1, 'ABC'); + + -- + -- Setup to test concurrent handling of GetTupleForTrigger(). + -- + CREATE TABLE footrg (a int, b text) PARTITION BY LIST(a); + CREATE TABLE triglog as select * from footrg; + CREATE TABLE footrg1 PARTITION OF footrg FOR VALUES IN (1); + CREATE TABLE footrg2 PARTITION OF footrg FOR VALUES IN (2); + INSERT INTO footrg VALUES (1, 'ABC'); + CREATE FUNCTION func_footrg() RETURNS TRIGGER AS $$ + BEGIN + OLD.b = OLD.b || ' trigger'; + + -- This will verify that the trigger is not run *before* the row is + -- refetched by EvalPlanQual. The OLD row should contain the changes made + -- by the concurrent session. + INSERT INTO triglog select OLD.*; + + RETURN OLD; + END $$ LANGUAGE PLPGSQL; + CREATE TRIGGER footrg_ondel BEFORE DELETE ON footrg1 + FOR EACH ROW EXECUTE PROCEDURE func_footrg(); + +} + +teardown +{ + DROP TABLE foo; + DROP TRIGGER footrg_ondel ON footrg1; + DROP FUNCTION func_footrg(); + DROP TABLE footrg; + DROP TABLE triglog; +} + +session "s1" +step "s1b" { BEGIN ISOLATION LEVEL READ COMMITTED; } +step "s1u" { UPDATE foo SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } +step "s1ut" { UPDATE footrg SET a = a + 1, b = b || ' update1' WHERE b like '%ABC%'; } +step "s1s" { SELECT tableoid::regclass, * FROM foo ORDER BY a; } +step "s1st" { SELECT tableoid::regclass, * FROM footrg ORDER BY a; } +step "s1stl" { SELECT * FROM triglog ORDER BY a; } +step "s1c" { COMMIT; } + +session "s2" +step "s2b" { BEGIN ISOLATION LEVEL READ COMMITTED; } +step "s2u1" { UPDATE foo SET b = b || ' update2' WHERE a = 1; } +step "s2u2" { UPDATE foo SET b = 'EFG' WHERE a = 1; } +step "s2ut1" { UPDATE footrg SET b = b || ' update2' WHERE a = 1; } +step "s2ut2" { UPDATE footrg SET b = 'EFG' WHERE a = 1; } +step "s2c" { COMMIT; } + + +# Session s1 is moving a row into another partition, but is waiting for +# another session s2 that is updating the original row. The row that ends up +# in the new partition should contain the changes made by session s2. +permutation "s1b" "s2b" "s2u1" "s1u" "s2c" "s1c" "s1s" + +# Same as above, except, session s1 is waiting in GetTupleForTrigger(). +permutation "s1b" "s2b" "s2ut1" "s1ut" "s2c" "s1c" "s1st" "s1stl" + +# Below two cases are similar to the above two; except that the session s1 +# fails EvalPlanQual() test, so partition key update does not happen. +permutation "s1b" "s2b" "s2u2" "s1u" "s2c" "s1c" "s1s" +permutation "s1b" "s2b" "s2ut2" "s1ut" "s2c" "s1c" "s1st" "s1stl" diff --git a/src/test/isolation/specs/plpgsql-toast.spec b/src/test/isolation/specs/plpgsql-toast.spec new file mode 100644 index 00000000000..fe7090addbb --- /dev/null +++ b/src/test/isolation/specs/plpgsql-toast.spec @@ -0,0 +1,137 @@ +# Test TOAST behavior in PL/pgSQL procedures with transaction control. +# +# We need to ensure that values stored in PL/pgSQL variables are free +# of external TOAST references, because those could disappear after a +# transaction is committed (leading to errors "missing chunk number +# ... for toast value ..."). The tests here do this by running VACUUM +# in a second session. Advisory locks are used to have the VACUUM +# kick in at the right time. The different "assign" steps test +# different code paths for variable assignments in PL/pgSQL. + +setup +{ + CREATE TABLE test1 (a int, b text); + ALTER TABLE test1 ALTER COLUMN b SET STORAGE EXTERNAL; + INSERT INTO test1 VALUES (1, repeat('foo', 2000)); + CREATE TYPE test2 AS (a bigint, b text); +} + +teardown +{ + DROP TABLE test1; + DROP TYPE test2; +} + +session "s1" + +setup +{ + SELECT pg_advisory_unlock_all(); +} + +# assign_simple_var() +step "assign1" +{ +do $$ + declare + x text; + begin + select test1.b into x from test1; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(x) = %', length(x); + end; +$$; +} + +# assign_simple_var() +step "assign2" +{ +do $$ + declare + x text; + begin + x := (select test1.b from test1); + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(x) = %', length(x); + end; +$$; +} + +# expanded_record_set_field() +step "assign3" +{ +do $$ + declare + r record; + begin + select * into r from test1; + r.b := (select test1.b from test1); + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; +} + +# expanded_record_set_fields() +step "assign4" +{ +do $$ + declare + r test2; + begin + select * into r from test1; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; +} + +# expanded_record_set_tuple() +step "assign5" +{ +do $$ + declare + r record; + begin + for r in select test1.b from test1 loop + null; + end loop; + delete from test1; + commit; + perform pg_advisory_lock(1); + raise notice 'length(r) = %', length(r::text); + end; +$$; +} + +session "s2" +setup +{ + SELECT pg_advisory_unlock_all(); +} +step "lock" +{ + SELECT pg_advisory_lock(1); +} +step "vacuum" +{ + VACUUM test1; +} +step "unlock" +{ + SELECT pg_advisory_unlock(1); +} + +permutation "lock" "assign1" "vacuum" "unlock" +permutation "lock" "assign2" "vacuum" "unlock" +permutation "lock" "assign3" "vacuum" "unlock" +permutation "lock" "assign4" "vacuum" "unlock" +permutation "lock" "assign5" "vacuum" "unlock" diff --git a/src/test/isolation/specs/predicate-gin.spec b/src/test/isolation/specs/predicate-gin.spec index 9f0cda80573..46fc51befd4 100644 --- a/src/test/isolation/specs/predicate-gin.spec +++ b/src/test/isolation/specs/predicate-gin.spec @@ -11,15 +11,17 @@ setup { - create table gin_tbl(id int4, p int4[]); - insert into gin_tbl select g, array[g, g*2,g*3] from generate_series(1, 10000) g; - insert into gin_tbl select g, array[4,5,6] from generate_series(10001, 20000) g; + create table gin_tbl(p int4[]); + insert into gin_tbl select array[1] from generate_series(1, 8192) g; + insert into gin_tbl select array[g] from generate_series(2, 800) g; create index ginidx on gin_tbl using gin(p) with (fastupdate = off); + create table other_tbl(v int4); } teardown { drop table gin_tbl; + drop table other_tbl; } session "s1" @@ -29,19 +31,13 @@ setup set enable_seqscan=off; } -# enable pending list for a small subset of tests -step "fu1" { alter index ginidx set (fastupdate = on); - commit; - begin isolation level serializable; - set enable_seqscan=off; } - -step "rxy1" { select count(*) from gin_tbl where p @> array[4,5]; } -step "wx1" { insert into gin_tbl select g, array[5,6] from generate_series - (20001, 20050) g; } -step "rxy3" { select count(*) from gin_tbl where p @> array[1,2] or - p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; } -step "wx3" { insert into gin_tbl select g, array[g,g*2] from generate_series - (1, 50) g; } +step "ra1" { select * from gin_tbl where p @> array[1] limit 1; } +step "rb1" { select count(*) from gin_tbl where p @> array[2]; } +step "rc1" { select count(*) from gin_tbl where p @> array[800]; } +step "rd1" { select count(*) from gin_tbl where p @> array[2000]; } + +step "wo1" { insert into other_tbl values (1); } + step "c1" { commit; } session "s2" @@ -51,84 +47,69 @@ setup set enable_seqscan=off; } -step "rxy2" { select count(*) from gin_tbl where p @> array[5,6]; } -step "rxy2fu" { select count(*) from gin_tbl where p @> array[10000,10005]; } -step "wy2" { insert into gin_tbl select g, array[4,5] from - generate_series(20051, 20100) g; } -step "wy2fu" { insert into gin_tbl select g, array[10000,10005] from - generate_series(20051, 20100) g; } -step "rxy4" { select count(*) from gin_tbl where p @> array[4000,8000] or - p @> array[5000,10000] or p @> array[6000,12000] or - p @> array[8000,16000]; } -step "wy4" { insert into gin_tbl select g, array[g,g*2] from generate_series - (10000, 10050) g; } -step "c2" { commit; } - - -# An index scan (from one transaction) and an index insert (from another transaction) -# try to access the same part of the index but one transaction commits before other -# transaction begins so no r-w conflict. - -permutation "rxy1" "wx1" "c1" "rxy2" "wy2" "c2" -permutation "rxy2" "wy2" "c2" "rxy1" "wx1" "c1" - -# An index scan (from one transaction) and an index insert (from another transaction) -# try to access different parts of the index and also one transaction commits before -# other transaction begins, so no r-w conflict. - -permutation "rxy3" "wx3" "c1" "rxy4" "wy4" "c2" -permutation "rxy4" "wy4" "c2" "rxy3" "wx3" "c1" - - -# An index scan (from one transaction) and an index insert (from another transaction) -# try to access the same part of the index and one transaction begins before other -# transaction commits so there is a r-w conflict. - -permutation "rxy1" "wx1" "rxy2" "c1" "wy2" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c1" "c2" -permutation "rxy1" "wx1" "rxy2" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wx1" "c1" "wy2" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c1" "c2" -permutation "rxy1" "rxy2" "wx1" "wy2" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "wx1" "c1" "c2" -permutation "rxy1" "rxy2" "wy2" "wx1" "c2" "c1" -permutation "rxy1" "rxy2" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "rxy1" "wx1" "c1" "wy2" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c1" "c2" -permutation "rxy2" "rxy1" "wx1" "wy2" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "wx1" "c1" "c2" -permutation "rxy2" "rxy1" "wy2" "wx1" "c2" "c1" -permutation "rxy2" "rxy1" "wy2" "c2" "wx1" "c1" -permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" -permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" -permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" - -# An index scan (from one transaction) and an index insert (from another transaction) -# try to access different parts of the index so no r-w conflict. - -permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c1" "c2" -permutation "rxy3" "wx3" "rxy4" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wx3" "c1" "wy4" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c1" "c2" -permutation "rxy3" "rxy4" "wx3" "wy4" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "wx3" "c1" "c2" -permutation "rxy3" "rxy4" "wy4" "wx3" "c2" "c1" -permutation "rxy3" "rxy4" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "rxy3" "wx3" "c1" "wy4" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c1" "c2" -permutation "rxy4" "rxy3" "wx3" "wy4" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "wx3" "c1" "c2" -permutation "rxy4" "rxy3" "wy4" "wx3" "c2" "c1" -permutation "rxy4" "rxy3" "wy4" "c2" "wx3" "c1" -permutation "rxy4" "wy4" "rxy3" "wx3" "c1" "c2" -permutation "rxy4" "wy4" "rxy3" "wx3" "c2" "c1" -permutation "rxy4" "wy4" "rxy3" "c2" "wx3" "c1" - -# Test fastupdate = on. First test should pass because fastupdate is off and -# sessions touches different parts of index, second should fail because -# with fastupdate on, then whole index should be under predicate lock. - -permutation "rxy1" "rxy2fu" "wx1" "c1" "wy2fu" "c2" -permutation "fu1" "rxy1" "rxy2fu" "wx1" "c1" "wy2fu" "c2" +step "ro2" { select count(*) from other_tbl; } + +step "wa2" { insert into gin_tbl values (array[1]); } +step "wb2" { insert into gin_tbl values (array[2]); } +step "wc2" { insert into gin_tbl values (array[800]); } +step "wd2" { insert into gin_tbl values (array[2000]); } + +step "c2" { commit; } + +session "s3" +step "fu" { alter index ginidx set (fastupdate = on); } + +# An index scan (from one transaction) and an index insert (from another +# transaction) try to access the same part of the index. So, there is a +# r-w conflict. + +permutation "ra1" "ro2" "wo1" "c1" "wa2" "c2" +permutation "ro2" "ra1" "wo1" "c1" "wa2" "c2" +permutation "ro2" "ra1" "wo1" "wa2" "c1" "c2" +permutation "ra1" "ro2" "wa2" "wo1" "c1" "c2" + +permutation "rb1" "ro2" "wo1" "c1" "wb2" "c2" +permutation "ro2" "rb1" "wo1" "c1" "wb2" "c2" +permutation "ro2" "rb1" "wo1" "wb2" "c1" "c2" +permutation "rb1" "ro2" "wb2" "wo1" "c1" "c2" + +permutation "rc1" "ro2" "wo1" "c1" "wc2" "c2" +permutation "ro2" "rc1" "wo1" "c1" "wc2" "c2" +permutation "ro2" "rc1" "wo1" "wc2" "c1" "c2" +permutation "rc1" "ro2" "wc2" "wo1" "c1" "c2" + +# An index scan (from one transaction) and an index insert (from another +# transaction) try to access different parts of the index. So, there is no +# r-w conflict. + +permutation "ra1" "ro2" "wo1" "c1" "wb2" "c2" +permutation "ro2" "ra1" "wo1" "c1" "wc2" "c2" +permutation "ro2" "rb1" "wo1" "wa2" "c1" "c2" +permutation "rc1" "ro2" "wa2" "wo1" "c1" "c2" + +permutation "rb1" "ro2" "wo1" "c1" "wa2" "c2" +permutation "ro2" "rb1" "wo1" "c1" "wc2" "c2" +permutation "ro2" "ra1" "wo1" "wb2" "c1" "c2" +permutation "rc1" "ro2" "wb2" "wo1" "c1" "c2" + +permutation "rc1" "ro2" "wo1" "c1" "wa2" "c2" +permutation "ro2" "rc1" "wo1" "c1" "wb2" "c2" +permutation "ro2" "ra1" "wo1" "wc2" "c1" "c2" +permutation "rb1" "ro2" "wc2" "wo1" "c1" "c2" + +# With fastupdate = on all index is under predicate lock. So we can't +# distinguish particular keys. + +permutation "fu" "ra1" "ro2" "wo1" "c1" "wa2" "c2" +permutation "fu" "ra1" "ro2" "wo1" "c1" "wb2" "c2" + +# Check fastupdate turned on concurrently. + +permutation "ra1" "ro2" "wo1" "c1" "fu" "wa2" "c2" + +# Tests for conflicts with previously non-existing key +permutation "rd1" "ro2" "wo1" "c1" "wd2" "c2" +permutation "ro2" "rd1" "wo1" "c1" "wd2" "c2" +permutation "ro2" "rd1" "wo1" "wd2" "c1" "c2" +permutation "rd1" "ro2" "wd2" "wo1" "c1" "c2" diff --git a/src/test/isolation/specs/predicate-hash.spec b/src/test/isolation/specs/predicate-hash.spec index 8c83cb33e19..852c1ca29df 100644 --- a/src/test/isolation/specs/predicate-hash.spec +++ b/src/test/isolation/specs/predicate-hash.spec @@ -28,7 +28,7 @@ teardown } session "s1" -setup +setup { begin isolation level serializable; set enable_seqscan=off; @@ -45,7 +45,7 @@ step "c1" { commit; } session "s2" -setup +setup { begin isolation level serializable; set enable_seqscan=off; @@ -99,7 +99,7 @@ permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" -# An index scan (from one transaction) and an index insert (from another +# An index scan (from one transaction) and an index insert (from another # transaction) try to access different buckets of the index so no r-w conflict. permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" diff --git a/src/test/isolation/specs/predicate-lock-hot-tuple.spec b/src/test/isolation/specs/predicate-lock-hot-tuple.spec new file mode 100644 index 00000000000..d16fb60533b --- /dev/null +++ b/src/test/isolation/specs/predicate-lock-hot-tuple.spec @@ -0,0 +1,37 @@ +# Test predicate locks on HOT updated tuples. +# +# This test has two serializable transactions. Both select two rows +# from the table, and then update one of them. +# If these were serialized (run one at a time), the transaction that +# runs later would see one of the rows to be updated. +# +# Any overlap between the transactions must cause a serialization failure. +# We used to have a bug in predicate locking HOT updated tuples, which +# caused the conflict to be missed, if the row was HOT updated. + +setup +{ + CREATE TABLE test (i int PRIMARY KEY, t text); + INSERT INTO test VALUES (5, 'apple'), (7, 'pear'), (11, 'banana'); + -- HOT-update 'pear' row. + UPDATE test SET t = 'pear_hot_updated' WHERE i = 7; +} + +teardown +{ + DROP TABLE test; +} + +session "s1" +step "b1" { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step "r1" { SELECT * FROM test WHERE i IN (5, 7) } +step "w1" { UPDATE test SET t = 'pear_xact1' WHERE i = 7 } +step "c1" { COMMIT; } + +session "s2" +step "b2" { BEGIN ISOLATION LEVEL SERIALIZABLE; } +step "r2" { SELECT * FROM test WHERE i IN (5, 7) } +step "w2" { UPDATE test SET t = 'apple_xact2' WHERE i = 5 } +step "c2" { COMMIT; } + +permutation "b1" "b2" "r1" "r2" "w1" "w2" "c1" "c2" diff --git a/src/test/isolation/specs/read-only-anomaly-3.spec b/src/test/isolation/specs/read-only-anomaly-3.spec index 58a159a9495..d43fc2e03f2 100644 --- a/src/test/isolation/specs/read-only-anomaly-3.spec +++ b/src/test/isolation/specs/read-only-anomaly-3.spec @@ -2,7 +2,7 @@ # isolation"[1]. # # Here we test that serializable snapshot isolation can avoid the anomaly -# without aborting any tranasctions, by instead causing s3 to be deferred +# without aborting any transactions, by instead causing s3 to be deferred # until a safe snapshot can be taken. # # [1] http://www.cs.umb.edu/~poneil/ROAnom.pdf diff --git a/src/test/isolation/specs/reindex-concurrently.spec b/src/test/isolation/specs/reindex-concurrently.spec new file mode 100644 index 00000000000..eb59fe0cba4 --- /dev/null +++ b/src/test/isolation/specs/reindex-concurrently.spec @@ -0,0 +1,40 @@ +# REINDEX CONCURRENTLY +# +# Ensure that concurrent operations work correctly when a REINDEX is performed +# concurrently. + +setup +{ + CREATE TABLE reind_con_tab(id serial primary key, data text); + INSERT INTO reind_con_tab(data) VALUES ('aa'); + INSERT INTO reind_con_tab(data) VALUES ('aaa'); + INSERT INTO reind_con_tab(data) VALUES ('aaaa'); + INSERT INTO reind_con_tab(data) VALUES ('aaaaa'); +} + +teardown +{ + DROP TABLE reind_con_tab; +} + +session "s1" +setup { BEGIN; } +step "sel1" { SELECT data FROM reind_con_tab WHERE id = 3; } +step "end1" { COMMIT; } + +session "s2" +setup { BEGIN; } +step "upd2" { UPDATE reind_con_tab SET data = 'bbbb' WHERE id = 3; } +step "ins2" { INSERT INTO reind_con_tab(data) VALUES ('cccc'); } +step "del2" { DELETE FROM reind_con_tab WHERE data = 'cccc'; } +step "end2" { COMMIT; } + +session "s3" +step "reindex" { REINDEX TABLE CONCURRENTLY reind_con_tab; } + +permutation "reindex" "sel1" "upd2" "ins2" "del2" "end1" "end2" +permutation "sel1" "reindex" "upd2" "ins2" "del2" "end1" "end2" +permutation "sel1" "upd2" "reindex" "ins2" "del2" "end1" "end2" +permutation "sel1" "upd2" "ins2" "reindex" "del2" "end1" "end2" +permutation "sel1" "upd2" "ins2" "del2" "reindex" "end1" "end2" +permutation "sel1" "upd2" "ins2" "del2" "end1" "reindex" "end2" diff --git a/src/test/isolation/specs/sequence-ddl.spec b/src/test/isolation/specs/sequence-ddl.spec index 5c51fcdae68..f2a3ff628bf 100644 --- a/src/test/isolation/specs/sequence-ddl.spec +++ b/src/test/isolation/specs/sequence-ddl.spec @@ -15,7 +15,6 @@ setup { BEGIN; } step "s1alter" { ALTER SEQUENCE seq1 MAXVALUE 10; } step "s1alter2" { ALTER SEQUENCE seq1 MAXVALUE 20; } step "s1restart" { ALTER SEQUENCE seq1 RESTART WITH 5; } -step "s1setval" { SELECT setval('seq1', 5); } step "s1commit" { COMMIT; } session "s2" @@ -29,7 +28,7 @@ permutation "s1alter" "s1commit" "s2nv" # change, but now it waits. permutation "s1alter" "s2nv" "s1commit" -# Prior to PG10, the s2nv step would see the uncommitted s1reset +# Prior to PG10, the s2nv step would see the uncommitted s1restart # change, but now it waits. permutation "s1restart" "s2nv" "s1commit" diff --git a/src/test/isolation/specs/serializable-parallel-2.spec b/src/test/isolation/specs/serializable-parallel-2.spec new file mode 100644 index 00000000000..7f90f75d882 --- /dev/null +++ b/src/test/isolation/specs/serializable-parallel-2.spec @@ -0,0 +1,30 @@ +# Exercise the case where a read-only serializable transaction has +# SXACT_FLAG_RO_SAFE set in a parallel query. + +setup +{ + CREATE TABLE foo AS SELECT generate_series(1, 10)::int a; + ALTER TABLE foo SET (parallel_workers = 2); +} + +teardown +{ + DROP TABLE foo; +} + +session "s1" +setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } +step "s1r" { SELECT * FROM foo; } +step "s1c" { COMMIT; } + +session "s2" +setup { + BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE READ ONLY; + SET parallel_setup_cost = 0; + SET parallel_tuple_cost = 0; + } +step "s2r1" { SELECT * FROM foo; } +step "s2r2" { SELECT * FROM foo; } +step "s2c" { COMMIT; } + +permutation "s1r" "s2r1" "s1c" "s2r2" "s2c" diff --git a/src/test/isolation/specs/serializable-parallel.spec b/src/test/isolation/specs/serializable-parallel.spec new file mode 100644 index 00000000000..a4f488adfc8 --- /dev/null +++ b/src/test/isolation/specs/serializable-parallel.spec @@ -0,0 +1,47 @@ +# The example from the paper "A read-only transaction anomaly under snapshot +# isolation"[1]. +# +# Here we test that serializable snapshot isolation (SERIALIZABLE) doesn't +# suffer from the anomaly, because s2 is aborted upon detection of a cycle. +# In this case the read only query s3 happens to be running in a parallel +# worker. +# +# [1] http://www.cs.umb.edu/~poneil/ROAnom.pdf + +setup +{ + CREATE TABLE bank_account (id TEXT PRIMARY KEY, balance DECIMAL NOT NULL); + INSERT INTO bank_account (id, balance) VALUES ('X', 0), ('Y', 0); +} + +teardown +{ + DROP TABLE bank_account; +} + +session "s1" +setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } +step "s1ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } +step "s1wy" { UPDATE bank_account SET balance = 20 WHERE id = 'Y'; } +step "s1c" { COMMIT; } + +session "s2" +setup { BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; } +step "s2rx" { SELECT balance FROM bank_account WHERE id = 'X'; } +step "s2ry" { SELECT balance FROM bank_account WHERE id = 'Y'; } +step "s2wx" { UPDATE bank_account SET balance = -11 WHERE id = 'X'; } +step "s2c" { COMMIT; } + +session "s3" +setup { + BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; + SET force_parallel_mode = on; + } +step "s3r" { SELECT id, balance FROM bank_account WHERE id IN ('X', 'Y') ORDER BY id; } +step "s3c" { COMMIT; } + +# without s3, s1 and s2 commit +permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s2wx" "s2c" "s3c" + +# once s3 observes the data committed by s1, a cycle is created and s2 aborts +permutation "s2rx" "s2ry" "s1ry" "s1wy" "s1c" "s3r" "s3c" "s2wx" diff --git a/src/test/isolation/specs/truncate-conflict.spec b/src/test/isolation/specs/truncate-conflict.spec new file mode 100644 index 00000000000..3c1b1d1b348 --- /dev/null +++ b/src/test/isolation/specs/truncate-conflict.spec @@ -0,0 +1,38 @@ +# Tests for locking conflicts with TRUNCATE commands. + +setup +{ + CREATE ROLE regress_truncate_conflict; + CREATE TABLE truncate_tab (a int); +} + +teardown +{ + DROP TABLE truncate_tab; + DROP ROLE regress_truncate_conflict; +} + +session "s1" +step "s1_begin" { BEGIN; } +step "s1_tab_lookup" { SELECT count(*) >= 0 FROM truncate_tab; } +step "s1_commit" { COMMIT; } + +session "s2" +step "s2_grant" { GRANT TRUNCATE ON truncate_tab TO regress_truncate_conflict; } +step "s2_auth" { SET ROLE regress_truncate_conflict; } +step "s2_truncate" { TRUNCATE truncate_tab; } +step "s2_reset" { RESET ROLE; } + +# The role doesn't have privileges to truncate the table, so TRUNCATE should +# immediately fail without waiting for a lock. +permutation "s1_begin" "s1_tab_lookup" "s2_auth" "s2_truncate" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s2_truncate" "s1_tab_lookup" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s1_tab_lookup" "s2_truncate" "s1_commit" "s2_reset" +permutation "s2_auth" "s2_truncate" "s1_begin" "s1_tab_lookup" "s1_commit" "s2_reset" + +# The role has privileges to truncate the table, TRUNCATE will block if +# another session holds a lock on the table and succeed in all cases. +permutation "s1_begin" "s1_tab_lookup" "s2_grant" "s2_auth" "s2_truncate" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s2_truncate" "s1_tab_lookup" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s1_tab_lookup" "s2_truncate" "s1_commit" "s2_reset" +permutation "s2_grant" "s2_auth" "s2_truncate" "s1_begin" "s1_tab_lookup" "s1_commit" "s2_reset" diff --git a/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec b/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec new file mode 100644 index 00000000000..106c2465c0a --- /dev/null +++ b/src/test/isolation/specs/tuplelock-upgrade-no-deadlock.spec @@ -0,0 +1,69 @@ +# This test checks that multiple sessions locking a single row in a table +# do not deadlock each other when one of them upgrades its existing lock +# while the others are waiting for it. + +setup +{ + drop table if exists tlu_job; + create table tlu_job (id integer primary key, name text); + + insert into tlu_job values(1, 'a'); +} + + +teardown +{ + drop table tlu_job; +} + +session "s0" +step "s0_begin" { begin; } +step "s0_keyshare" { select id from tlu_job where id = 1 for key share;} +step "s0_rollback" { rollback; } + +session "s1" +setup { begin; } +step "s1_keyshare" { select id from tlu_job where id = 1 for key share;} +step "s1_share" { select id from tlu_job where id = 1 for share; } +step "s1_fornokeyupd" { select id from tlu_job where id = 1 for no key update; } +step "s1_update" { update tlu_job set name = 'b' where id = 1; } +step "s1_savept_e" { savepoint s1_e; } +step "s1_savept_f" { savepoint s1_f; } +step "s1_rollback_e" { rollback to s1_e; } +step "s1_rollback_f" { rollback to s1_f; } +step "s1_rollback" { rollback; } +step "s1_commit" { commit; } + +session "s2" +setup { begin; } +step "s2_for_keyshare" { select id from tlu_job where id = 1 for key share; } +step "s2_fornokeyupd" { select id from tlu_job where id = 1 for no key update; } +step "s2_for_update" { select id from tlu_job where id = 1 for update; } +step "s2_update" { update tlu_job set name = 'b' where id = 1; } +step "s2_delete" { delete from tlu_job where id = 1; } +step "s2_rollback" { rollback; } + +session "s3" +setup { begin; } +step "s3_keyshare" { select id from tlu_job where id = 1 for key share; } +step "s3_share" { select id from tlu_job where id = 1 for share; } +step "s3_for_update" { select id from tlu_job where id = 1 for update; } +step "s3_update" { update tlu_job set name = 'c' where id = 1; } +step "s3_delete" { delete from tlu_job where id = 1; } +step "s3_rollback" { rollback; } +step "s3_commit" { commit; } + +# test that s2 will not deadlock with s3 when s1 is rolled back +permutation "s1_share" "s2_for_update" "s3_share" "s3_for_update" "s1_rollback" "s3_rollback" "s2_rollback" +# test that update does not cause deadlocks if it can proceed +permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s1_update" "s3_update" "s1_rollback" "s3_rollback" "s2_rollback" +permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s1_update" "s3_update" "s1_commit" "s3_rollback" "s2_rollback" +# test that delete does not cause deadlocks if it can proceed +permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s3_delete" "s1_rollback" "s3_rollback" "s2_rollback" +permutation "s1_keyshare" "s2_for_update" "s3_keyshare" "s3_delete" "s1_rollback" "s3_commit" "s2_rollback" +# test that sessions that don't upgrade locks acquire them in order +permutation "s1_share" "s2_for_update" "s3_for_update" "s1_rollback" "s2_rollback" "s3_rollback" +permutation "s1_share" "s2_update" "s3_update" "s1_rollback" "s2_rollback" "s3_rollback" +permutation "s1_share" "s2_delete" "s3_delete" "s1_rollback" "s2_rollback" "s3_rollback" +# test s2 retrying the overall tuple lock algorithm after initially avoiding deadlock +permutation "s1_keyshare" "s3_for_update" "s2_for_keyshare" "s1_savept_e" "s1_share" "s1_savept_f" "s1_fornokeyupd" "s2_fornokeyupd" "s0_begin" "s0_keyshare" "s1_rollback_f" "s0_keyshare" "s1_rollback_e" "s1_rollback" "s2_rollback" "s0_rollback" "s3_rollback" diff --git a/src/test/isolation/specs/vacuum-conflict.spec b/src/test/isolation/specs/vacuum-conflict.spec new file mode 100644 index 00000000000..9b45d26c65b --- /dev/null +++ b/src/test/isolation/specs/vacuum-conflict.spec @@ -0,0 +1,51 @@ +# Tests for locking conflicts with VACUUM and ANALYZE commands. + +setup +{ + CREATE ROLE regress_vacuum_conflict; + CREATE TABLE vacuum_tab (a int); +} + +teardown +{ + DROP TABLE vacuum_tab; + DROP ROLE regress_vacuum_conflict; +} + +session "s1" +step "s1_begin" { BEGIN; } +step "s1_lock" { LOCK vacuum_tab IN SHARE UPDATE EXCLUSIVE MODE; } +step "s1_commit" { COMMIT; } + +session "s2" +step "s2_grant" { ALTER TABLE vacuum_tab OWNER TO regress_vacuum_conflict; } +step "s2_auth" { SET ROLE regress_vacuum_conflict; } +step "s2_vacuum" { VACUUM vacuum_tab; } +step "s2_analyze" { ANALYZE vacuum_tab; } +step "s2_reset" { RESET ROLE; } + +# The role doesn't have privileges to vacuum the table, so VACUUM should +# immediately skip the table without waiting for a lock. +permutation "s1_begin" "s1_lock" "s2_auth" "s2_vacuum" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s2_vacuum" "s1_lock" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s1_lock" "s2_vacuum" "s1_commit" "s2_reset" +permutation "s2_auth" "s2_vacuum" "s1_begin" "s1_lock" "s1_commit" "s2_reset" + +# Same as previously for ANALYZE +permutation "s1_begin" "s1_lock" "s2_auth" "s2_analyze" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s2_analyze" "s1_lock" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_auth" "s1_lock" "s2_analyze" "s1_commit" "s2_reset" +permutation "s2_auth" "s2_analyze" "s1_begin" "s1_lock" "s1_commit" "s2_reset" + +# The role has privileges to vacuum the table, VACUUM will block if +# another session holds a lock on the table and succeed in all cases. +permutation "s1_begin" "s2_grant" "s1_lock" "s2_auth" "s2_vacuum" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s2_vacuum" "s1_lock" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s1_lock" "s2_vacuum" "s1_commit" "s2_reset" +permutation "s2_grant" "s2_auth" "s2_vacuum" "s1_begin" "s1_lock" "s1_commit" "s2_reset" + +# Same as previously for ANALYZE +permutation "s1_begin" "s2_grant" "s1_lock" "s2_auth" "s2_analyze" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s2_analyze" "s1_lock" "s1_commit" "s2_reset" +permutation "s1_begin" "s2_grant" "s2_auth" "s1_lock" "s2_analyze" "s1_commit" "s2_reset" +permutation "s2_grant" "s2_auth" "s2_analyze" "s1_begin" "s1_lock" "s1_commit" "s2_reset" diff --git a/src/test/isolation/specs/vacuum-skip-locked.spec b/src/test/isolation/specs/vacuum-skip-locked.spec new file mode 100644 index 00000000000..4d59b294ca9 --- /dev/null +++ b/src/test/isolation/specs/vacuum-skip-locked.spec @@ -0,0 +1,59 @@ +# Test for SKIP_LOCKED option of VACUUM and ANALYZE commands. +# +# This also verifies that log messages are not emitted for skipped relations +# that were not specified in the VACUUM or ANALYZE command. + +setup +{ + CREATE TABLE parted (a INT) PARTITION BY LIST (a); + CREATE TABLE part1 PARTITION OF parted FOR VALUES IN (1); + CREATE TABLE part2 PARTITION OF parted FOR VALUES IN (2); +} + +teardown +{ + DROP TABLE IF EXISTS parted; +} + +session "s1" +step "lock_share" +{ + BEGIN; + LOCK part1 IN SHARE MODE; +} +step "lock_access_exclusive" +{ + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; +} +step "commit" +{ + COMMIT; +} + +session "s2" +step "vac_specified" { VACUUM (SKIP_LOCKED) part1, part2; } +step "vac_all_parts" { VACUUM (SKIP_LOCKED) parted; } +step "analyze_specified" { ANALYZE (SKIP_LOCKED) part1, part2; } +step "analyze_all_parts" { ANALYZE (SKIP_LOCKED) parted; } +step "vac_analyze_specified" { VACUUM (ANALYZE, SKIP_LOCKED) part1, part2; } +step "vac_analyze_all_parts" { VACUUM (ANALYZE, SKIP_LOCKED) parted; } +step "vac_full_specified" { VACUUM (SKIP_LOCKED, FULL) part1, part2; } +step "vac_full_all_parts" { VACUUM (SKIP_LOCKED, FULL) parted; } + +permutation "lock_share" "vac_specified" "commit" +permutation "lock_share" "vac_all_parts" "commit" +permutation "lock_share" "analyze_specified" "commit" +permutation "lock_share" "analyze_all_parts" "commit" +permutation "lock_share" "vac_analyze_specified" "commit" +permutation "lock_share" "vac_analyze_all_parts" "commit" +permutation "lock_share" "vac_full_specified" "commit" +permutation "lock_share" "vac_full_all_parts" "commit" +permutation "lock_access_exclusive" "vac_specified" "commit" +permutation "lock_access_exclusive" "vac_all_parts" "commit" +permutation "lock_access_exclusive" "analyze_specified" "commit" +permutation "lock_access_exclusive" "analyze_all_parts" "commit" +permutation "lock_access_exclusive" "vac_analyze_specified" "commit" +permutation "lock_access_exclusive" "vac_analyze_all_parts" "commit" +permutation "lock_access_exclusive" "vac_full_specified" "commit" +permutation "lock_access_exclusive" "vac_full_all_parts" "commit" diff --git a/src/test/isolation/specscanner.l b/src/test/isolation/specscanner.l index f97f4027f2f..3924c992945 100644 --- a/src/test/isolation/specscanner.l +++ b/src/test/isolation/specscanner.l @@ -4,7 +4,7 @@ * specscanner.l * a lexical scanner for an isolation test specification * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * *------------------------------------------------------------------------- diff --git a/src/test/kerberos/Makefile b/src/test/kerberos/Makefile index 4df4989470a..0f3edd4712e 100644 --- a/src/test/kerberos/Makefile +++ b/src/test/kerberos/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/kerberos # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/kerberos/Makefile diff --git a/src/test/kerberos/README b/src/test/kerberos/README index cdfaeb89d33..93af72e1636 100644 --- a/src/test/kerberos/README +++ b/src/test/kerberos/README @@ -16,11 +16,19 @@ users. Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. + +Either way, this test initializes, starts, and stops a test Postgres +cluster, as well as a test KDC server. Requirements ============ @@ -30,6 +38,6 @@ supported. Debian/Ubuntu packages: krb5-admin-server krb5-kdc krb5-user -RHEL/CentOS packages: krb5-server krb5-workstation +RHEL/CentOS/Fedora packages: krb5-server krb5-workstation FreeBSD port: krb5 (base system has Heimdal) diff --git a/src/test/kerberos/t/001_auth.pl b/src/test/kerberos/t/001_auth.pl index f26460e627f..e3eb0521604 100644 --- a/src/test/kerberos/t/001_auth.pl +++ b/src/test/kerberos/t/001_auth.pl @@ -1,3 +1,16 @@ +# Sets up a KDC and then runs a variety of tests to make sure that the +# GSSAPI/Kerberos authentication and encryption are working properly, +# that the options in pg_hba.conf and pg_ident.conf are handled correctly, +# and that the server-side pg_stat_gssapi view reports what we expect to +# see for each test. +# +# Since this requires setting up a full KDC, it doesn't make much sense +# to have multiple test scripts (since they'd have to also create their +# own KDC and that could cause race conditions or other problems)- so +# just add whatever other tests are needed to here. +# +# See the README for additional information. + use strict; use warnings; use TestLib; @@ -6,7 +19,7 @@ if ($ENV{with_gssapi} eq 'yes') { - plan tests => 4; + plan tests => 12; } else { @@ -17,12 +30,12 @@ if ($^O eq 'darwin') { - $krb5_bin_dir = '/usr/local/opt/krb5/bin'; + $krb5_bin_dir = '/usr/local/opt/krb5/bin'; $krb5_sbin_dir = '/usr/local/opt/krb5/sbin'; } elsif ($^O eq 'freebsd') { - $krb5_bin_dir = '/usr/local/bin'; + $krb5_bin_dir = '/usr/local/bin'; $krb5_sbin_dir = '/usr/local/sbin'; } elsif ($^O eq 'linux') @@ -30,45 +43,50 @@ $krb5_sbin_dir = '/usr/sbin'; } -my $krb5_config = 'krb5-config'; -my $kinit = 'kinit'; -my $kdb5_util = 'kdb5_util'; +my $krb5_config = 'krb5-config'; +my $kinit = 'kinit'; +my $kdb5_util = 'kdb5_util'; my $kadmin_local = 'kadmin.local'; -my $krb5kdc = 'krb5kdc'; +my $krb5kdc = 'krb5kdc'; if ($krb5_bin_dir && -d $krb5_bin_dir) { $krb5_config = $krb5_bin_dir . '/' . $krb5_config; - $kinit = $krb5_bin_dir . '/' . $kinit; + $kinit = $krb5_bin_dir . '/' . $kinit; } if ($krb5_sbin_dir && -d $krb5_sbin_dir) { - $kdb5_util = $krb5_sbin_dir . '/' . $kdb5_util; + $kdb5_util = $krb5_sbin_dir . '/' . $kdb5_util; $kadmin_local = $krb5_sbin_dir . '/' . $kadmin_local; - $krb5kdc = $krb5_sbin_dir . '/' . $krb5kdc; + $krb5kdc = $krb5_sbin_dir . '/' . $krb5kdc; } -my $realm = 'EXAMPLE.COM'; +my $host = 'auth-test-localhost.postgresql.example.com'; +my $hostaddr = '127.0.0.1'; +my $realm = 'EXAMPLE.COM'; -my $krb5_conf = "${TestLib::tmp_check}/krb5.conf"; -my $kdc_conf = "${TestLib::tmp_check}/kdc.conf"; -my $krb5_log = "${TestLib::tmp_check}/krb5libs.log"; -my $kdc_log = "${TestLib::tmp_check}/krb5kdc.log"; -my $kdc_port = int(rand() * 16384) + 49152; +my $krb5_conf = "${TestLib::tmp_check}/krb5.conf"; +my $kdc_conf = "${TestLib::tmp_check}/kdc.conf"; +my $krb5_log = "${TestLib::log_path}/krb5libs.log"; +my $kdc_log = "${TestLib::log_path}/krb5kdc.log"; +my $kdc_port = get_free_port(); my $kdc_datadir = "${TestLib::tmp_check}/krb5kdc"; my $kdc_pidfile = "${TestLib::tmp_check}/krb5kdc.pid"; -my $keytab = "${TestLib::tmp_check}/krb5.keytab"; +my $keytab = "${TestLib::tmp_check}/krb5.keytab"; note "setting up Kerberos"; my ($stdout, $krb5_version); -run_log [ $krb5_config, '--version' ], '>', \$stdout or BAIL_OUT("could not execute krb5-config"); +run_log [ $krb5_config, '--version' ], '>', \$stdout + or BAIL_OUT("could not execute krb5-config"); BAIL_OUT("Heimdal is not supported") if $stdout =~ m/heimdal/; -$stdout =~ m/Kerberos 5 release ([0-9]+\.[0-9]+)/ or BAIL_OUT("could not get Kerberos version"); +$stdout =~ m/Kerberos 5 release ([0-9]+\.[0-9]+)/ + or BAIL_OUT("could not get Kerberos version"); $krb5_version = $1; -append_to_file($krb5_conf, -qq![logging] +append_to_file( + $krb5_conf, + qq![logging] default = FILE:$krb5_log kdc = FILE:$kdc_log @@ -77,30 +95,35 @@ [realms] $realm = { - kdc = localhost:$kdc_port + kdc = $hostaddr:$kdc_port }!); -append_to_file($kdc_conf, -qq![kdcdefaults] +append_to_file( + $kdc_conf, + qq![kdcdefaults] !); + # For new-enough versions of krb5, use the _listen settings rather # than the _ports settings so that we can bind to localhost only. if ($krb5_version >= 1.15) { - append_to_file($kdc_conf, -qq!kdc_listen = localhost:$kdc_port -kdc_tcp_listen = localhost:$kdc_port + append_to_file( + $kdc_conf, + qq!kdc_listen = $hostaddr:$kdc_port +kdc_tcp_listen = $hostaddr:$kdc_port !); } else { - append_to_file($kdc_conf, -qq!kdc_ports = $kdc_port + append_to_file( + $kdc_conf, + qq!kdc_ports = $kdc_port kdc_tcp_ports = $kdc_port !); } -append_to_file($kdc_conf, -qq! +append_to_file( + $kdc_conf, + qq! [realms] $realm = { database_name = $kdc_datadir/principal @@ -111,10 +134,10 @@ mkdir $kdc_datadir or die; -$ENV{'KRB5_CONFIG'} = $krb5_conf; +$ENV{'KRB5_CONFIG'} = $krb5_conf; $ENV{'KRB5_KDC_PROFILE'} = $kdc_conf; -my $service_principal = "$ENV{with_krb_srvnam}/localhost"; +my $service_principal = "$ENV{with_krb_srvnam}/$host"; system_or_bail $kdb5_util, 'create', '-s', '-P', 'secret0'; @@ -128,14 +151,14 @@ END { - kill 'INT', `cat $kdc_pidfile` if -f $kdc_pidfile; + kill 'INT', `cat $kdc_pidfile` if -f $kdc_pidfile; } note "setting up PostgreSQL instance"; my $node = get_new_node('node'); $node->init; -$node->append_conf('postgresql.conf', "listen_addresses = 'localhost'"); +$node->append_conf('postgresql.conf', "listen_addresses = '$hostaddr'"); $node->append_conf('postgresql.conf', "krb_server_keyfile = '$keytab'"); $node->start; @@ -145,33 +168,124 @@ END sub test_access { - my ($node, $role, $expected_res, $test_name) = @_; + my ($node, $role, $server_check, $expected_res, $gssencmode, $test_name) + = @_; # need to connect over TCP/IP for Kerberos - my $res = $node->psql('postgres', 'SELECT 1', - extra_params => [ '-d', $node->connstr('postgres').' host=localhost', - '-U', $role ]); - is($res, $expected_res, $test_name); + my ($res, $stdoutres, $stderrres) = $node->psql( + 'postgres', + "$server_check", + extra_params => [ + '-XAtd', + $node->connstr('postgres') + . " host=$host hostaddr=$hostaddr $gssencmode", + '-U', + $role + ]); + + # If we get a query result back, it should be true. + if ($res == $expected_res and $res eq 0) + { + is($stdoutres, "t", $test_name); + } + else + { + is($res, $expected_res, $test_name); + } + return; } unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{host all all localhost gss map=mymap}); +$node->append_conf('pg_hba.conf', + qq{host all all $hostaddr/32 gss map=mymap}); $node->restart; -test_access($node, 'test1', 2, 'fails without ticket'); +test_access($node, 'test1', 'SELECT true', 2, '', 'fails without ticket'); run_log [ $kinit, 'test1' ], \$test1_password or BAIL_OUT($?); -test_access($node, 'test1', 2, 'fails without mapping'); +test_access($node, 'test1', 'SELECT true', 2, '', 'fails without mapping'); $node->append_conf('pg_ident.conf', qq{mymap /^(.*)\@$realm\$ \\1}); $node->restart; -test_access($node, 'test1', 0, 'succeeds with mapping'); +test_access( + $node, + 'test1', + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + '', + 'succeeds with mapping with default gssencmode and host hba'); +test_access( + $node, + "test1", + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=prefer", + "succeeds with GSS-encrypted access preferred with host hba"); +test_access( + $node, + "test1", + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=require", + "succeeds with GSS-encrypted access required with host hba"); + +unlink($node->data_dir . '/pg_hba.conf'); +$node->append_conf('pg_hba.conf', + qq{hostgssenc all all $hostaddr/32 gss map=mymap}); +$node->restart; + +test_access( + $node, + "test1", + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=prefer", + "succeeds with GSS-encrypted access preferred and hostgssenc hba"); +test_access( + $node, + "test1", + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=require", + "succeeds with GSS-encrypted access required and hostgssenc hba"); +test_access($node, "test1", 'SELECT true', 2, "gssencmode=disable", + "fails with GSS encryption disabled and hostgssenc hba"); + +unlink($node->data_dir . '/pg_hba.conf'); +$node->append_conf('pg_hba.conf', + qq{hostnogssenc all all $hostaddr/32 gss map=mymap}); +$node->restart; + +test_access( + $node, + "test1", + 'SELECT gss_authenticated and not encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=prefer", + "succeeds with GSS-encrypted access preferred and hostnogssenc hba, but no encryption" +); +test_access($node, "test1", 'SELECT true', 2, "gssencmode=require", + "fails with GSS-encrypted access required and hostnogssenc hba"); +test_access( + $node, + "test1", + 'SELECT gss_authenticated and not encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + "gssencmode=disable", + "succeeds with GSS encryption disabled and hostnogssenc hba"); truncate($node->data_dir . '/pg_ident.conf', 0); unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{host all all localhost gss include_realm=0}); +$node->append_conf('pg_hba.conf', + qq{host all all $hostaddr/32 gss include_realm=0}); $node->restart; -test_access($node, 'test1', 0, 'succeeds with include_realm=0'); +test_access( + $node, + 'test1', + 'SELECT gss_authenticated AND encrypted from pg_stat_gssapi where pid = pg_backend_pid();', + 0, + '', + 'succeeds with include_realm=0 and defaults'); diff --git a/src/test/ldap/Makefile b/src/test/ldap/Makefile index 74fef48650b..4b0a6e01c5e 100644 --- a/src/test/ldap/Makefile +++ b/src/test/ldap/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/ldap # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/ldap/Makefile diff --git a/src/test/ldap/README b/src/test/ldap/README index 61578385c5f..826b15373f2 100644 --- a/src/test/ldap/README +++ b/src/test/ldap/README @@ -17,8 +17,36 @@ users. Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. + +Either way, this test initializes, starts, and stops a test Postgres +cluster, as well as a test LDAP server. + +Requirements +============ + +LDAP server and client tools are required. + +Debian/Ubuntu packages: slapd ldap-utils + +RHEL/CentOS/Fedora packages: openldap-clients openldap-servers +(You will already have needed openldap and openldap-devel to build.) + +FreeBSD: openldap-server +(You will already have needed openldap-client to build. If building +from the ports source tree, you want to build net/openldap24-client +and net/openldap24-server.) + +macOS: We do not recommend trying to use the Apple-provided version of +OpenLDAP; it's very old, plus Apple seem to have changed the launching +conventions for slapd. The paths in the test file are set on the +assumption that you installed OpenLDAP using Homebrew or MacPorts. diff --git a/src/test/ldap/t/001_auth.pl b/src/test/ldap/t/001_auth.pl index 3a71e053538..f8941144f5e 100644 --- a/src/test/ldap/t/001_auth.pl +++ b/src/test/ldap/t/001_auth.pl @@ -6,7 +6,7 @@ if ($ENV{with_ldap} eq 'yes') { - plan tests => 19; + plan tests => 22; } else { @@ -15,22 +15,29 @@ my ($slapd, $ldap_bin_dir, $ldap_schema_dir); -$ldap_bin_dir = undef; # usually in PATH +$ldap_bin_dir = undef; # usually in PATH -if ($^O eq 'darwin') +if ($^O eq 'darwin' && -d '/usr/local/opt/openldap') { - $slapd = '/usr/local/opt/openldap/libexec/slapd'; + # typical paths for Homebrew + $slapd = '/usr/local/opt/openldap/libexec/slapd'; $ldap_schema_dir = '/usr/local/etc/openldap/schema'; } +elsif ($^O eq 'darwin' && -d '/opt/local/etc/openldap') +{ + # typical paths for MacPorts + $slapd = '/opt/local/libexec/slapd'; + $ldap_schema_dir = '/opt/local/etc/openldap/schema'; +} elsif ($^O eq 'linux') { - $slapd = '/usr/sbin/slapd'; + $slapd = '/usr/sbin/slapd'; $ldap_schema_dir = '/etc/ldap/schema' if -d '/etc/ldap/schema'; $ldap_schema_dir = '/etc/openldap/schema' if -d '/etc/openldap/schema'; } elsif ($^O eq 'freebsd') { - $slapd = '/usr/local/libexec/slapd'; + $slapd = '/usr/local/libexec/slapd'; $ldap_schema_dir = '/usr/local/etc/openldap/schema'; } @@ -41,26 +48,27 @@ $ENV{PATH} = "$ldap_bin_dir:$ENV{PATH}" if $ldap_bin_dir; -my $ldap_datadir = "${TestLib::tmp_check}/openldap-data"; -my $slapd_certs = "${TestLib::tmp_check}/slapd-certs"; -my $slapd_conf = "${TestLib::tmp_check}/slapd.conf"; +my $ldap_datadir = "${TestLib::tmp_check}/openldap-data"; +my $slapd_certs = "${TestLib::tmp_check}/slapd-certs"; +my $slapd_conf = "${TestLib::tmp_check}/slapd.conf"; my $slapd_pidfile = "${TestLib::tmp_check}/slapd.pid"; -my $slapd_logfile = "${TestLib::tmp_check}/slapd.log"; -my $ldap_conf = "${TestLib::tmp_check}/ldap.conf"; -my $ldap_server = 'localhost'; -my $ldap_port = int(rand() * 16384) + 49152; -my $ldaps_port = $ldap_port + 1; -my $ldap_url = "ldap://$ldap_server:$ldap_port"; -my $ldaps_url = "ldaps://$ldap_server:$ldaps_port"; -my $ldap_basedn = 'dc=example,dc=net'; -my $ldap_rootdn = 'cn=Manager,dc=example,dc=net'; -my $ldap_rootpw = 'secret'; -my $ldap_pwfile = "${TestLib::tmp_check}/ldappassword"; +my $slapd_logfile = "${TestLib::log_path}/slapd.log"; +my $ldap_conf = "${TestLib::tmp_check}/ldap.conf"; +my $ldap_server = 'localhost'; +my $ldap_port = get_free_port(); +my $ldaps_port = get_free_port(); +my $ldap_url = "ldap://$ldap_server:$ldap_port"; +my $ldaps_url = "ldaps://$ldap_server:$ldaps_port"; +my $ldap_basedn = 'dc=example,dc=net'; +my $ldap_rootdn = 'cn=Manager,dc=example,dc=net'; +my $ldap_rootpw = 'secret'; +my $ldap_pwfile = "${TestLib::tmp_check}/ldappassword"; note "setting up slapd"; -append_to_file($slapd_conf, -qq{include $ldap_schema_dir/core.schema +append_to_file( + $slapd_conf, + qq{include $ldap_schema_dir/core.schema include $ldap_schema_dir/cosine.schema include $ldap_schema_dir/nis.schema include $ldap_schema_dir/inetorgperson.schema @@ -84,16 +92,23 @@ rootpw $ldap_rootpw}); # don't bother to check the server's cert (though perhaps we should) -append_to_file($ldap_conf, -qq{TLS_REQCERT never +append_to_file( + $ldap_conf, + qq{TLS_REQCERT never }); mkdir $ldap_datadir or die; -mkdir $slapd_certs or die; - -system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", "$slapd_certs/ca.key", "-x509", "-out", "$slapd_certs/ca.crt", "-subj", "/cn=CA"; -system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", "$slapd_certs/server.key", "-out", "$slapd_certs/server.csr", "-subj", "/cn=server"; -system_or_bail "openssl", "x509", "-req", "-in", "$slapd_certs/server.csr", "-CA", "$slapd_certs/ca.crt", "-CAkey", "$slapd_certs/ca.key", "-CAcreateserial", "-out", "$slapd_certs/server.crt"; +mkdir $slapd_certs or die; + +system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", + "$slapd_certs/ca.key", "-x509", "-out", "$slapd_certs/ca.crt", "-subj", + "/CN=CA"; +system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", + "$slapd_certs/server.key", "-out", "$slapd_certs/server.csr", "-subj", + "/CN=server"; +system_or_bail "openssl", "x509", "-req", "-in", "$slapd_certs/server.csr", + "-CA", "$slapd_certs/ca.crt", "-CAkey", "$slapd_certs/ca.key", + "-CAcreateserial", "-out", "$slapd_certs/server.crt"; system_or_bail $slapd, '-f', $slapd_conf, '-h', "$ldap_url $ldaps_url"; @@ -105,15 +120,33 @@ END append_to_file($ldap_pwfile, $ldap_rootpw); chmod 0600, $ldap_pwfile or die; -$ENV{'LDAPURI'} = $ldap_url; +# wait until slapd accepts requests +my $retries = 0; +while (1) +{ + last + if ( + system_log( + "ldapsearch", "-h", $ldap_server, "-p", + $ldap_port, "-s", "base", "-b", + $ldap_basedn, "-D", $ldap_rootdn, "-y", + $ldap_pwfile, "-n", "'objectclass=*'") == 0); + die "cannot connect to slapd" if ++$retries >= 300; + note "waiting for slapd to accept requests..."; + Time::HiRes::usleep(1000000); +} + +$ENV{'LDAPURI'} = $ldap_url; $ENV{'LDAPBINDDN'} = $ldap_rootdn; -$ENV{'LDAPCONF'} = $ldap_conf; +$ENV{'LDAPCONF'} = $ldap_conf; note "loading LDAP data"; -system_or_bail 'ldapadd', '-x', '-y', $ldap_pwfile, '-f', 'authdata.ldif'; -system_or_bail 'ldappasswd', '-x', '-y', $ldap_pwfile, '-s', 'secret1', 'uid=test1,dc=example,dc=net'; -system_or_bail 'ldappasswd', '-x', '-y', $ldap_pwfile, '-s', 'secret2', 'uid=test2,dc=example,dc=net'; +system_or_bail 'ldapadd', '-x', '-y', $ldap_pwfile, '-f', 'authdata.ldif'; +system_or_bail 'ldappasswd', '-x', '-y', $ldap_pwfile, '-s', 'secret1', + 'uid=test1,dc=example,dc=net'; +system_or_bail 'ldappasswd', '-x', '-y', $ldap_pwfile, '-s', 'secret2', + 'uid=test2,dc=example,dc=net'; note "setting up PostgreSQL instance"; @@ -131,50 +164,83 @@ sub test_access { my ($node, $role, $expected_res, $test_name) = @_; - my $res = $node->psql('postgres', 'SELECT 1', extra_params => [ '-U', $role ]); - is($res, $expected_res, $test_name); + my $res = + $node->psql('postgres', 'SELECT 1', extra_params => [ '-U', $role ]); + is($res, $expected_res, $test_name); + return; } note "simple bind"; unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="uid=" ldapsuffix=",dc=example,dc=net"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="uid=" ldapsuffix=",dc=example,dc=net"} +); $node->restart; $ENV{"PGPASSWORD"} = 'wrong'; -test_access($node, 'test0', 2, 'simple bind authentication fails if user not found in LDAP'); -test_access($node, 'test1', 2, 'simple bind authentication fails with wrong password'); +test_access($node, 'test0', 2, + 'simple bind authentication fails if user not found in LDAP'); +test_access($node, 'test1', 2, + 'simple bind authentication fails with wrong password'); $ENV{"PGPASSWORD"} = 'secret1'; test_access($node, 'test1', 0, 'simple bind authentication succeeds'); note "search+bind"; unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn"} +); +$node->restart; + +$ENV{"PGPASSWORD"} = 'wrong'; +test_access($node, 'test0', 2, + 'search+bind authentication fails if user not found in LDAP'); +test_access($node, 'test1', 2, + 'search+bind authentication fails with wrong password'); +$ENV{"PGPASSWORD"} = 'secret1'; +test_access($node, 'test1', 0, 'search+bind authentication succeeds'); + +note "multiple servers"; + +unlink($node->data_dir . '/pg_hba.conf'); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver="$ldap_server $ldap_server" ldapport=$ldap_port ldapbasedn="$ldap_basedn"} +); $node->restart; $ENV{"PGPASSWORD"} = 'wrong'; -test_access($node, 'test0', 2, 'search+bind authentication fails if user not found in LDAP'); -test_access($node, 'test1', 2, 'search+bind authentication fails with wrong password'); +test_access($node, 'test0', 2, + 'search+bind authentication fails if user not found in LDAP'); +test_access($node, 'test1', 2, + 'search+bind authentication fails with wrong password'); $ENV{"PGPASSWORD"} = 'secret1'; test_access($node, 'test1', 0, 'search+bind authentication succeeds'); note "LDAP URLs"; unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn?uid?sub"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn?uid?sub"}); $node->restart; $ENV{"PGPASSWORD"} = 'wrong'; -test_access($node, 'test0', 2, 'search+bind with LDAP URL authentication fails if user not found in LDAP'); -test_access($node, 'test1', 2, 'search+bind with LDAP URL authentication fails with wrong password'); +test_access($node, 'test0', 2, + 'search+bind with LDAP URL authentication fails if user not found in LDAP' +); +test_access($node, 'test1', 2, + 'search+bind with LDAP URL authentication fails with wrong password'); $ENV{"PGPASSWORD"} = 'secret1'; -test_access($node, 'test1', 0, 'search+bind with LDAP URL authentication succeeds'); +test_access($node, 'test1', 0, + 'search+bind with LDAP URL authentication succeeds'); note "search filters"; unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -185,7 +251,9 @@ sub test_access note "search filters in LDAP URLs"; unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub?(|(uid=\$username)(mail=\$username))"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub?(|(uid=\$username)(mail=\$username))"} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -197,7 +265,9 @@ sub test_access # settings. ldapurl is always parsed first, then the other settings # override. It might be useful in a case like this. unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapurl="$ldap_url/$ldap_basedn??sub" ldapsearchfilter="(|(uid=\$username)(mail=\$username))"} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -207,7 +277,9 @@ sub test_access # note bad ldapprefix with a question mark that triggers a diagnostic message unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="?uid=" ldapsuffix=""}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapprefix="?uid=" ldapsuffix=""} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -217,7 +289,9 @@ sub test_access # request StartTLS with ldaptls=1 unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(uid=\$username)" ldaptls=1}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapport=$ldap_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(uid=\$username)" ldaptls=1} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -225,7 +299,9 @@ sub test_access # request LDAPS with ldapscheme=ldaps unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapserver=$ldap_server ldapscheme=ldaps ldapport=$ldaps_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(uid=\$username)"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapserver=$ldap_server ldapscheme=ldaps ldapport=$ldaps_port ldapbasedn="$ldap_basedn" ldapsearchfilter="(uid=\$username)"} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -233,7 +309,9 @@ sub test_access # request LDAPS with ldapurl=ldaps://... unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapurl="$ldaps_url/$ldap_basedn??sub?(uid=\$username)"}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapurl="$ldaps_url/$ldap_basedn??sub?(uid=\$username)"} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; @@ -241,7 +319,9 @@ sub test_access # bad combination of LDAPS and StartTLS unlink($node->data_dir . '/pg_hba.conf'); -$node->append_conf('pg_hba.conf', qq{local all all ldap ldapurl="$ldaps_url/$ldap_basedn??sub?(uid=\$username)" ldaptls=1}); +$node->append_conf('pg_hba.conf', + qq{local all all ldap ldapurl="$ldaps_url/$ldap_basedn??sub?(uid=\$username)" ldaptls=1} +); $node->restart; $ENV{"PGPASSWORD"} = 'secret1'; diff --git a/src/test/locale/sort-test.py b/src/test/locale/sort-test.py index 1dafcedde50..53019038ab1 100755 --- a/src/test/locale/sort-test.py +++ b/src/test/locale/sort-test.py @@ -3,7 +3,7 @@ import sys, string, locale locale.setlocale(locale.LC_ALL, "") -if len(sys.argv) <> 2: +if len(sys.argv) != 2: sys.stderr.write("Usage: sort.py filename\n") sys.exit(1) @@ -14,5 +14,5 @@ for i in range(0, len(list)): list[i] = list[i][:-1] # chop! -list.sort(locale.strcoll) -print string.join(list, '\n') +list.sort(key=locale.strxfrm) +print('\n'.join(list)) diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index 19d60a506e1..b2eaef3bff5 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -7,17 +7,22 @@ include $(top_builddir)/src/Makefile.global SUBDIRS = \ brin \ commit_ts \ + dummy_index_am \ dummy_seclabel \ snapshot_too_old \ test_bloomfilter \ test_ddl_deparse \ test_extensions \ + test_ginpostinglist \ + test_integerset \ + test_misc \ test_parser \ test_pg_dump \ test_predtest \ test_rbtree \ test_rls_hooks \ test_shm_mq \ + unsafe_tests \ worker_spi $(recurse) diff --git a/src/test/modules/README b/src/test/modules/README index 99f921d582a..025ecac7243 100644 --- a/src/test/modules/README +++ b/src/test/modules/README @@ -6,6 +6,13 @@ intended for testing PostgreSQL and/or to serve as example code. The extensions here aren't intended to be installed in a production server and aren't suitable for "real work". +Furthermore, while you can do "make install" and "make installcheck" in +this directory or its children, it is NOT ADVISABLE to do so with a server +containing valuable data. Some of these tests may have undesirable +side-effects on roles or other global objects within the tested server. +"make installcheck-world" at the top level does not recurse into this +directory. + Most extensions have their own pg_regress tests or isolationtester specs. Some are also used by tests elsewhere in the tree. diff --git a/src/test/modules/brin/.gitignore b/src/test/modules/brin/.gitignore index 62bbe8f6b1a..44f600cb6c7 100644 --- a/src/test/modules/brin/.gitignore +++ b/src/test/modules/brin/.gitignore @@ -1,3 +1,3 @@ # Generated subdirectories -/isolation_output/ +/output_iso/ /tmp_check/ diff --git a/src/test/modules/brin/Makefile b/src/test/modules/brin/Makefile index 566655cd61d..c8715939060 100644 --- a/src/test/modules/brin/Makefile +++ b/src/test/modules/brin/Makefile @@ -1,12 +1,9 @@ # src/test/modules/brin/Makefile -# Note: because we don't tell the Makefile there are any regression tests, -# we have to clean those result files explicitly -EXTRA_CLEAN = $(pg_regress_clean_files) ./isolation_output +EXTRA_INSTALL = contrib/pageinspect -EXTRA_INSTALL=contrib/pageinspect - -ISOLATIONCHECKS=summarization-and-inprogress-insertion +ISOLATION = summarization-and-inprogress-insertion +TAP_TESTS = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -18,19 +15,3 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - -check: isolation-check prove-check - -isolation-check: | submake-isolation temp-install - $(MKDIR_P) isolation_output - $(pg_isolation_regress_check) \ - --outputdir=./isolation_output \ - $(ISOLATIONCHECKS) - -prove-check: | temp-install - $(prove_check) - -.PHONY: check isolation-check prove-check - -submake-isolation: - $(MAKE) -C $(top_builddir)/src/test/isolation all diff --git a/src/test/modules/brin/t/01_workitems.pl b/src/test/modules/brin/t/01_workitems.pl index 11c9981d40d..534ab63ab26 100644 --- a/src/test/modules/brin/t/01_workitems.pl +++ b/src/test/modules/brin/t/01_workitems.pl @@ -15,7 +15,8 @@ $node->safe_psql('postgres', 'create extension pageinspect'); # Create a table with an autosummarizing BRIN index -$node->safe_psql('postgres', +$node->safe_psql( + 'postgres', 'create table brin_wi (a int) with (fillfactor = 10); create index brin_wi_idx on brin_wi using brin (a) with (pages_per_range=1, autosummarize=on); ' @@ -28,7 +29,8 @@ $node->safe_psql('postgres', 'insert into brin_wi select * from generate_series(1, 100)'); -$node->poll_query_until('postgres', +$node->poll_query_until( + 'postgres', "select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)", 't'); diff --git a/src/test/modules/commit_ts/Makefile b/src/test/modules/commit_ts/Makefile index 6d4f3be358e..113bcfa210b 100644 --- a/src/test/modules/commit_ts/Makefile +++ b/src/test/modules/commit_ts/Makefile @@ -2,6 +2,11 @@ REGRESS = commit_timestamp REGRESS_OPTS = --temp-config=$(top_srcdir)/src/test/modules/commit_ts/commit_ts.conf +# Disabled because these tests require "track_commit_timestamp = on", +# which typical installcheck users do not have (e.g. buildfarm clients). +NO_INSTALLCHECK = 1 + +TAP_TESTS = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -13,8 +18,3 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - -check: prove-check - -prove-check: | temp-install - $(prove_check) diff --git a/src/test/modules/commit_ts/t/001_base.pl b/src/test/modules/commit_ts/t/001_base.pl index 9290a85d89e..f8d5d84cc52 100644 --- a/src/test/modules/commit_ts/t/001_base.pl +++ b/src/test/modules/commit_ts/t/001_base.pl @@ -16,11 +16,11 @@ $node->safe_psql('postgres', 'create table t as select now from (select now(), pg_sleep(1)) f'); my $true = $node->safe_psql('postgres', -'select t.now - ts.* < \'1s\' from t, pg_class c, pg_xact_commit_timestamp(c.xmin) ts where relname = \'t\'' + 'select t.now - ts.* < \'1s\' from t, pg_class c, pg_xact_commit_timestamp(c.xmin) ts where relname = \'t\'' ); is($true, 't', 'commit TS is set'); my $ts = $node->safe_psql('postgres', -'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t\'' + 'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t\'' ); # Verify that we read the same TS after crash recovery @@ -28,6 +28,6 @@ $node->start; my $recovered_ts = $node->safe_psql('postgres', -'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t\'' + 'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t\'' ); is($recovered_ts, $ts, 'commit TS remains after crash recovery'); diff --git a/src/test/modules/commit_ts/t/002_standby.pl b/src/test/modules/commit_ts/t/002_standby.pl index 83e851954b3..f376b595962 100644 --- a/src/test/modules/commit_ts/t/002_standby.pl +++ b/src/test/modules/commit_ts/t/002_standby.pl @@ -28,7 +28,7 @@ $master->safe_psql('postgres', "create table t$i()"); } my $master_ts = $master->safe_psql('postgres', -qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't10'} + qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't10'} ); my $master_lsn = $master->safe_psql('postgres', 'select pg_current_wal_lsn()'); @@ -37,7 +37,7 @@ or die "standby never caught up"; my $standby_ts = $standby->safe_psql('postgres', -qq{select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = 't10'} + qq{select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = 't10'} ); is($master_ts, $standby_ts, "standby gives same value as master"); @@ -52,7 +52,7 @@ # This one should raise an error now my ($ret, $standby_ts_stdout, $standby_ts_stderr) = $standby->psql('postgres', -'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t10\'' + 'select ts.* from pg_class, pg_xact_commit_timestamp(xmin) ts where relname = \'t10\'' ); is($ret, 3, 'standby errors when master turned feature off'); is($standby_ts_stdout, '', diff --git a/src/test/modules/commit_ts/t/003_standby_2.pl b/src/test/modules/commit_ts/t/003_standby_2.pl index 27494709e17..9165d500536 100644 --- a/src/test/modules/commit_ts/t/003_standby_2.pl +++ b/src/test/modules/commit_ts/t/003_standby_2.pl @@ -40,7 +40,7 @@ my ($psql_ret, $standby_ts_stdout, $standby_ts_stderr) = $standby->psql( 'postgres', -qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't10'} + qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't10'} ); is($psql_ret, 3, 'expect error when getting commit timestamp after restart'); is($standby_ts_stdout, '', "standby does not return a value after restart"); @@ -58,7 +58,7 @@ $standby->safe_psql('postgres', "create table t11()"); my $standby_ts = $standby->safe_psql('postgres', -qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't11'} + qq{SELECT ts.* FROM pg_class, pg_xact_commit_timestamp(xmin) AS ts WHERE relname = 't11'} ); isnt($standby_ts, '', "standby gives valid value ($standby_ts) after promotion"); diff --git a/src/test/modules/commit_ts/t/004_restart.pl b/src/test/modules/commit_ts/t/004_restart.pl index daf42d3a029..bd4b9433056 100644 --- a/src/test/modules/commit_ts/t/004_restart.pl +++ b/src/test/modules/commit_ts/t/004_restart.pl @@ -1,4 +1,4 @@ -# Testing of commit timestamps preservation across clean restarts +# Testing of commit timestamps preservation across restarts use strict; use warnings; use PostgresNode; @@ -71,12 +71,37 @@ 'timestamps before and after restart are equal'); # Now disable commit timestamps - $node_master->append_conf('postgresql.conf', 'track_commit_timestamp = off'); - $node_master->stop('fast'); + +# Start the server, which generates a XLOG_PARAMETER_CHANGE record where +# the parameter change is registered. $node_master->start; +# Now restart again the server so as no XLOG_PARAMETER_CHANGE record are +# replayed with the follow-up immediate shutdown. +$node_master->restart; + +# Move commit timestamps across page boundaries. Things should still +# be able to work across restarts with those transactions committed while +# track_commit_timestamp is disabled. +$node_master->safe_psql( + 'postgres', + qq(CREATE PROCEDURE consume_xid(cnt int) +AS \$\$ +DECLARE + i int; + BEGIN + FOR i in 1..cnt LOOP + EXECUTE 'SELECT txid_current()'; + COMMIT; + END LOOP; + END; +\$\$ +LANGUAGE plpgsql; +)); +$node_master->safe_psql('postgres', 'CALL consume_xid(2000)'); + ($ret, $stdout, $stderr) = $node_master->psql('postgres', qq[SELECT pg_xact_commit_timestamp('$xid');]); is($ret, 3, 'no commit timestamp from enable tx when cts disabled'); @@ -106,10 +131,12 @@ # Re-enable, restart and ensure we can still get the old timestamps $node_master->append_conf('postgresql.conf', 'track_commit_timestamp = on'); -$node_master->stop('fast'); +# An immediate shutdown is used here. At next startup recovery will +# replay transactions which committed when track_commit_timestamp was +# disabled, and the facility should be able to work properly. +$node_master->stop('immediate'); $node_master->start; - my $after_enable_ts = $node_master->safe_psql('postgres', qq[SELECT pg_xact_commit_timestamp('$xid');]); is($after_enable_ts, '', 'timestamp of enabled tx null after re-enable'); diff --git a/src/test/modules/dummy_index_am/.gitignore b/src/test/modules/dummy_index_am/.gitignore new file mode 100644 index 00000000000..44d119cfcc2 --- /dev/null +++ b/src/test/modules/dummy_index_am/.gitignore @@ -0,0 +1,3 @@ +# Generated subdirectories +/log/ +/results/ diff --git a/src/test/modules/dummy_index_am/Makefile b/src/test/modules/dummy_index_am/Makefile new file mode 100644 index 00000000000..aaf544a3854 --- /dev/null +++ b/src/test/modules/dummy_index_am/Makefile @@ -0,0 +1,20 @@ +# src/test/modules/dummy_index_am/Makefile + +MODULES = dummy_index_am + +EXTENSION = dummy_index_am +DATA = dummy_index_am--1.0.sql +PGFILEDESC = "dummy_index_am - index access method template" + +REGRESS = reloptions + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/dummy_index_am +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/dummy_index_am/README b/src/test/modules/dummy_index_am/README new file mode 100644 index 00000000000..61510f02fae --- /dev/null +++ b/src/test/modules/dummy_index_am/README @@ -0,0 +1,12 @@ +Dummy Index AM +============== + +Dummy index AM is a module for testing any facility usable by an index +access method, whose code is kept a maximum simple. + +This includes tests for all relation option types: +- boolean +- enum +- integer +- real +- strings (with and without NULL as default) diff --git a/src/test/modules/dummy_index_am/dummy_index_am--1.0.sql b/src/test/modules/dummy_index_am/dummy_index_am--1.0.sql new file mode 100644 index 00000000000..005863de878 --- /dev/null +++ b/src/test/modules/dummy_index_am/dummy_index_am--1.0.sql @@ -0,0 +1,19 @@ +/* src/test/modules/dummy_index_am/dummy_index_am--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION dummy_index_am" to load this file. \quit + +CREATE FUNCTION dihandler(internal) +RETURNS index_am_handler +AS 'MODULE_PATHNAME' +LANGUAGE C; + +-- Access method +CREATE ACCESS METHOD dummy_index_am TYPE INDEX HANDLER dihandler; +COMMENT ON ACCESS METHOD dummy_index_am IS 'dummy index access method'; + +-- Operator classes +CREATE OPERATOR CLASS int4_ops +DEFAULT FOR TYPE int4 USING dummy_index_am AS + OPERATOR 1 = (int4, int4), + FUNCTION 1 hashint4(int4); diff --git a/src/test/modules/dummy_index_am/dummy_index_am.c b/src/test/modules/dummy_index_am/dummy_index_am.c new file mode 100644 index 00000000000..bc68767f3a0 --- /dev/null +++ b/src/test/modules/dummy_index_am/dummy_index_am.c @@ -0,0 +1,335 @@ +/*------------------------------------------------------------------------- + * + * dummy_index_am.c + * Index AM template main file. + * + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/test/modules/dummy_index_am/dummy_index_am.c + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/amapi.h" +#include "access/reloptions.h" +#include "catalog/index.h" +#include "nodes/pathnodes.h" +#include "utils/guc.h" +#include "utils/rel.h" + +PG_MODULE_MAGIC; + +void _PG_init(void); + +/* parse table for fillRelOptions */ +relopt_parse_elt di_relopt_tab[6]; + +/* Kind of relation options for dummy index */ +relopt_kind di_relopt_kind; + +typedef enum DummyAmEnum { + DUMMY_AM_ENUM_ONE, + DUMMY_AM_ENUM_TWO +} DummyAmEnum; + +/* Dummy index options */ +typedef struct DummyIndexOptions +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int option_int; + double option_real; + bool option_bool; + DummyAmEnum option_enum; + int option_string_val_offset; + int option_string_null_offset; +} DummyIndexOptions; + +relopt_enum_elt_def dummyAmEnumValues[] = +{ + {"one", DUMMY_AM_ENUM_ONE}, + {"two", DUMMY_AM_ENUM_TWO}, + {(const char *)NULL} /* list terminator */ +}; + +/* Handler for index AM */ +PG_FUNCTION_INFO_V1(dihandler); + +/* + * Validation function for string relation options. + */ +static void +validate_string_option(const char *value) +{ + ereport(NOTICE, + (errmsg("new option value for string parameter %s", + value ? value : "NULL"))); +} + +/* + * This function creates a full set of relation option types, + * with various patterns. + */ +static void +create_reloptions_table(void) +{ + di_relopt_kind = add_reloption_kind(); + + add_int_reloption(di_relopt_kind, "option_int", + "Integer option for dummy_index_am", + 10, -10, 100, AccessExclusiveLock); + di_relopt_tab[0].optname = "option_int"; + di_relopt_tab[0].opttype = RELOPT_TYPE_INT; + di_relopt_tab[0].offset = offsetof(DummyIndexOptions, option_int); + + add_real_reloption(di_relopt_kind, "option_real", + "Real option for dummy_index_am", + 3.1415, -10, 100, AccessExclusiveLock); + di_relopt_tab[1].optname = "option_real"; + di_relopt_tab[1].opttype = RELOPT_TYPE_REAL; + di_relopt_tab[1].offset = offsetof(DummyIndexOptions, option_real); + + add_bool_reloption(di_relopt_kind, "option_bool", + "Boolean option for dummy_index_am", + true, AccessExclusiveLock); + di_relopt_tab[2].optname = "option_bool"; + di_relopt_tab[2].opttype = RELOPT_TYPE_BOOL; + di_relopt_tab[2].offset = offsetof(DummyIndexOptions, option_bool); + + add_enum_reloption(di_relopt_kind, "option_enum", + "Enum option for dummy_index_am", + dummyAmEnumValues, + DUMMY_AM_ENUM_ONE, + "Valid values are \"one\" and \"two\".", + AccessExclusiveLock); + di_relopt_tab[3].optname = "option_enum"; + di_relopt_tab[3].opttype = RELOPT_TYPE_ENUM; + di_relopt_tab[3].offset = offsetof(DummyIndexOptions, option_enum); + + add_string_reloption(di_relopt_kind, "option_string_val", + "String option for dummy_index_am with non-NULL default", + "DefaultValue", &validate_string_option, + AccessExclusiveLock); + di_relopt_tab[4].optname = "option_string_val"; + di_relopt_tab[4].opttype = RELOPT_TYPE_STRING; + di_relopt_tab[4].offset = offsetof(DummyIndexOptions, + option_string_val_offset); + + /* + * String option for dummy_index_am with NULL default, and without + * description. + */ + add_string_reloption(di_relopt_kind, "option_string_null", + NULL, /* description */ + NULL, &validate_string_option, + AccessExclusiveLock); + di_relopt_tab[5].optname = "option_string_null"; + di_relopt_tab[5].opttype = RELOPT_TYPE_STRING; + di_relopt_tab[5].offset = offsetof(DummyIndexOptions, + option_string_null_offset); +} + + +/* + * Build a new index. + */ +static IndexBuildResult * +dibuild(Relation heap, Relation index, IndexInfo *indexInfo) +{ + IndexBuildResult *result; + + result = (IndexBuildResult *) palloc(sizeof(IndexBuildResult)); + + /* let's pretend that no tuples were scanned */ + result->heap_tuples = 0; + /* and no index tuples were created (that is true) */ + result->index_tuples = 0; + + return result; +} + +/* + * Build an empty index for the initialiation fork. + */ +static void +dibuildempty(Relation index) +{ + /* No need to build an init fork for a dummy index */ +} + +/* + * Insert new tuple to index AM. + */ +static bool +diinsert(Relation index, Datum *values, bool *isnull, + ItemPointer ht_ctid, Relation heapRel, + IndexUniqueCheck checkUnique, + IndexInfo *indexInfo) +{ + /* nothing to do */ + return false; +} + +/* + * Bulk deletion of all index entries pointing to a set of table tuples. + */ +static IndexBulkDeleteResult * +dibulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, + IndexBulkDeleteCallback callback, void *callback_state) +{ + /* + * There is nothing to delete. Return NULL as there is nothing to pass to + * amvacuumcleanup. + */ + return NULL; +} + +/* + * Post-VACUUM cleanup for index AM. + */ +static IndexBulkDeleteResult * +divacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) +{ + /* Index has not been modified, so returning NULL is fine */ + return NULL; +} + +/* + * Estimate cost of index AM. + */ +static void +dicostestimate(PlannerInfo *root, IndexPath *path, double loop_count, + Cost *indexStartupCost, Cost *indexTotalCost, + Selectivity *indexSelectivity, double *indexCorrelation, + double *indexPages) +{ + /* Tell planner to never use this index! */ + *indexStartupCost = 1.0e10; + *indexTotalCost = 1.0e10; + + /* Do not care about the rest */ + *indexSelectivity = 1; + *indexCorrelation = 0; + *indexPages = 1; +} + +/* + * Parse relation options for index AM, returning a DummyIndexOptions + * structure filled with option values. + */ +static bytea * +dioptions(Datum reloptions, bool validate) +{ + relopt_value *options; + int numoptions; + DummyIndexOptions *rdopts; + + /* Parse the user-given reloptions */ + options = parseRelOptions(reloptions, validate, di_relopt_kind, &numoptions); + rdopts = allocateReloptStruct(sizeof(DummyIndexOptions), options, numoptions); + fillRelOptions((void *) rdopts, sizeof(DummyIndexOptions), options, numoptions, + validate, di_relopt_tab, lengthof(di_relopt_tab)); + + return (bytea *) rdopts; +} + +/* + * Validator for index AM. + */ +static bool +divalidate(Oid opclassoid) +{ + /* Index is dummy so we are happy with any opclass */ + return true; +} + +/* + * Begin scan of index AM. + */ +static IndexScanDesc +dibeginscan(Relation r, int nkeys, int norderbys) +{ + IndexScanDesc scan; + + /* Let's pretend we are doing something */ + scan = RelationGetIndexScan(r, nkeys, norderbys); + return scan; +} + +/* + * Rescan of index AM. + */ +static void +direscan(IndexScanDesc scan, ScanKey scankey, int nscankeys, + ScanKey orderbys, int norderbys) +{ + /* nothing to do */ +} + +/* + * End scan of index AM. + */ +static void +diendscan(IndexScanDesc scan) +{ + /* nothing to do */ +} + +/* + * Index AM handler function: returns IndexAmRoutine with access method + * parameters and callbacks. + */ +Datum +dihandler(PG_FUNCTION_ARGS) +{ + IndexAmRoutine *amroutine = makeNode(IndexAmRoutine); + + amroutine->amstrategies = 0; + amroutine->amsupport = 1; + amroutine->amcanorder = false; + amroutine->amcanorderbyop = false; + amroutine->amcanbackward = false; + amroutine->amcanunique = false; + amroutine->amcanmulticol = false; + amroutine->amoptionalkey = false; + amroutine->amsearcharray = false; + amroutine->amsearchnulls = false; + amroutine->amstorage = false; + amroutine->amclusterable = false; + amroutine->ampredlocks = false; + amroutine->amcanparallel = false; + amroutine->amcaninclude = false; + amroutine->amkeytype = InvalidOid; + + amroutine->ambuild = dibuild; + amroutine->ambuildempty = dibuildempty; + amroutine->aminsert = diinsert; + amroutine->ambulkdelete = dibulkdelete; + amroutine->amvacuumcleanup = divacuumcleanup; + amroutine->amcanreturn = NULL; + amroutine->amcostestimate = dicostestimate; + amroutine->amoptions = dioptions; + amroutine->amproperty = NULL; + amroutine->ambuildphasename = NULL; + amroutine->amvalidate = divalidate; + amroutine->ambeginscan = dibeginscan; + amroutine->amrescan = direscan; + amroutine->amgettuple = NULL; + amroutine->amgetbitmap = NULL; + amroutine->amendscan = diendscan; + amroutine->ammarkpos = NULL; + amroutine->amrestrpos = NULL; + amroutine->amestimateparallelscan = NULL; + amroutine->aminitparallelscan = NULL; + amroutine->amparallelrescan = NULL; + + PG_RETURN_POINTER(amroutine); +} + +void +_PG_init(void) +{ + create_reloptions_table(); +} diff --git a/src/test/modules/dummy_index_am/dummy_index_am.control b/src/test/modules/dummy_index_am/dummy_index_am.control new file mode 100644 index 00000000000..77bdea08ae0 --- /dev/null +++ b/src/test/modules/dummy_index_am/dummy_index_am.control @@ -0,0 +1,5 @@ +# dummy_index_am extension +comment = 'dummy_index_am - index access method template' +default_version = '1.0' +module_pathname = '$libdir/dummy_index_am' +relocatable = true diff --git a/src/test/modules/dummy_index_am/expected/reloptions.out b/src/test/modules/dummy_index_am/expected/reloptions.out new file mode 100644 index 00000000000..c873a80bb75 --- /dev/null +++ b/src/test/modules/dummy_index_am/expected/reloptions.out @@ -0,0 +1,145 @@ +-- Tests for relation options +CREATE EXTENSION dummy_index_am; +CREATE TABLE dummy_test_tab (i int4); +-- Silence validation checks for strings +SET client_min_messages TO 'warning'; +-- Test with default values. +CREATE INDEX dummy_test_idx ON dummy_test_tab + USING dummy_index_am (i); +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +-------- +(0 rows) + +DROP INDEX dummy_test_idx; +-- Test with full set of options. +-- Allow validation checks for strings, just for the index creation +SET client_min_messages TO 'notice'; +CREATE INDEX dummy_test_idx ON dummy_test_tab + USING dummy_index_am (i) WITH ( + option_bool = false, + option_int = 5, + option_real = 3.1, + option_enum = 'two', + option_string_val = NULL, + option_string_null = 'val'); +NOTICE: new option value for string parameter null +NOTICE: new option value for string parameter val +-- Silence again validation checks for strings until the end of the test. +SET client_min_messages TO 'warning'; +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +------------------------ + option_bool=false + option_int=5 + option_real=3.1 + option_enum=two + option_string_val=null + option_string_null=val +(6 rows) + +-- ALTER INDEX .. SET +ALTER INDEX dummy_test_idx SET (option_int = 10); +ALTER INDEX dummy_test_idx SET (option_bool = true); +ALTER INDEX dummy_test_idx SET (option_real = 3.2); +ALTER INDEX dummy_test_idx SET (option_string_val = 'val2'); +ALTER INDEX dummy_test_idx SET (option_string_null = NULL); +ALTER INDEX dummy_test_idx SET (option_enum = 'one'); +ALTER INDEX dummy_test_idx SET (option_enum = 'three'); +ERROR: invalid value for enum option "option_enum": three +DETAIL: Valid values are "one" and "two". +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +------------------------- + option_int=10 + option_bool=true + option_real=3.2 + option_string_val=val2 + option_string_null=null + option_enum=one +(6 rows) + +-- ALTER INDEX .. RESET +ALTER INDEX dummy_test_idx RESET (option_int); +ALTER INDEX dummy_test_idx RESET (option_bool); +ALTER INDEX dummy_test_idx RESET (option_real); +ALTER INDEX dummy_test_idx RESET (option_enum); +ALTER INDEX dummy_test_idx RESET (option_string_val); +ALTER INDEX dummy_test_idx RESET (option_string_null); +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +-------- +(0 rows) + +-- Cross-type checks for reloption values +-- Integer +ALTER INDEX dummy_test_idx SET (option_int = 3.3); -- ok +ALTER INDEX dummy_test_idx SET (option_int = true); -- error +ERROR: invalid value for integer option "option_int": true +ALTER INDEX dummy_test_idx SET (option_int = 'val3'); -- error +ERROR: invalid value for integer option "option_int": val3 +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +---------------- + option_int=3.3 +(1 row) + +ALTER INDEX dummy_test_idx RESET (option_int); +-- Boolean +ALTER INDEX dummy_test_idx SET (option_bool = 4); -- error +ERROR: invalid value for boolean option "option_bool": 4 +ALTER INDEX dummy_test_idx SET (option_bool = 1); -- ok, as true +ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error +ERROR: invalid value for boolean option "option_bool": 3.4 +ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error +ERROR: invalid value for boolean option "option_bool": val4 +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +--------------- + option_bool=1 +(1 row) + +ALTER INDEX dummy_test_idx RESET (option_bool); +-- Float +ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok +ALTER INDEX dummy_test_idx SET (option_real = true); -- error +ERROR: invalid value for floating point option "option_real": true +ALTER INDEX dummy_test_idx SET (option_real = 'val5'); -- error +ERROR: invalid value for floating point option "option_real": val5 +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +--------------- + option_real=4 +(1 row) + +ALTER INDEX dummy_test_idx RESET (option_real); +-- Enum +ALTER INDEX dummy_test_idx SET (option_enum = 'one'); -- ok +ALTER INDEX dummy_test_idx SET (option_enum = 0); -- error +ERROR: invalid value for enum option "option_enum": 0 +DETAIL: Valid values are "one" and "two". +ALTER INDEX dummy_test_idx SET (option_enum = true); -- error +ERROR: invalid value for enum option "option_enum": true +DETAIL: Valid values are "one" and "two". +ALTER INDEX dummy_test_idx SET (option_enum = 'three'); -- error +ERROR: invalid value for enum option "option_enum": three +DETAIL: Valid values are "one" and "two". +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +----------------- + option_enum=one +(1 row) + +ALTER INDEX dummy_test_idx RESET (option_enum); +-- String +ALTER INDEX dummy_test_idx SET (option_string_val = 4); -- ok +ALTER INDEX dummy_test_idx SET (option_string_val = 3.5); -- ok +ALTER INDEX dummy_test_idx SET (option_string_val = true); -- ok, as "true" +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + unnest +------------------------ + option_string_val=true +(1 row) + +ALTER INDEX dummy_test_idx RESET (option_string_val); +DROP INDEX dummy_test_idx; diff --git a/src/test/modules/dummy_index_am/sql/reloptions.sql b/src/test/modules/dummy_index_am/sql/reloptions.sql new file mode 100644 index 00000000000..6749d763e6a --- /dev/null +++ b/src/test/modules/dummy_index_am/sql/reloptions.sql @@ -0,0 +1,83 @@ +-- Tests for relation options +CREATE EXTENSION dummy_index_am; + +CREATE TABLE dummy_test_tab (i int4); + +-- Silence validation checks for strings +SET client_min_messages TO 'warning'; + +-- Test with default values. +CREATE INDEX dummy_test_idx ON dummy_test_tab + USING dummy_index_am (i); +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +DROP INDEX dummy_test_idx; + +-- Test with full set of options. +-- Allow validation checks for strings, just for the index creation +SET client_min_messages TO 'notice'; +CREATE INDEX dummy_test_idx ON dummy_test_tab + USING dummy_index_am (i) WITH ( + option_bool = false, + option_int = 5, + option_real = 3.1, + option_enum = 'two', + option_string_val = NULL, + option_string_null = 'val'); +-- Silence again validation checks for strings until the end of the test. +SET client_min_messages TO 'warning'; +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + +-- ALTER INDEX .. SET +ALTER INDEX dummy_test_idx SET (option_int = 10); +ALTER INDEX dummy_test_idx SET (option_bool = true); +ALTER INDEX dummy_test_idx SET (option_real = 3.2); +ALTER INDEX dummy_test_idx SET (option_string_val = 'val2'); +ALTER INDEX dummy_test_idx SET (option_string_null = NULL); +ALTER INDEX dummy_test_idx SET (option_enum = 'one'); +ALTER INDEX dummy_test_idx SET (option_enum = 'three'); +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + +-- ALTER INDEX .. RESET +ALTER INDEX dummy_test_idx RESET (option_int); +ALTER INDEX dummy_test_idx RESET (option_bool); +ALTER INDEX dummy_test_idx RESET (option_real); +ALTER INDEX dummy_test_idx RESET (option_enum); +ALTER INDEX dummy_test_idx RESET (option_string_val); +ALTER INDEX dummy_test_idx RESET (option_string_null); +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; + +-- Cross-type checks for reloption values +-- Integer +ALTER INDEX dummy_test_idx SET (option_int = 3.3); -- ok +ALTER INDEX dummy_test_idx SET (option_int = true); -- error +ALTER INDEX dummy_test_idx SET (option_int = 'val3'); -- error +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +ALTER INDEX dummy_test_idx RESET (option_int); +-- Boolean +ALTER INDEX dummy_test_idx SET (option_bool = 4); -- error +ALTER INDEX dummy_test_idx SET (option_bool = 1); -- ok, as true +ALTER INDEX dummy_test_idx SET (option_bool = 3.4); -- error +ALTER INDEX dummy_test_idx SET (option_bool = 'val4'); -- error +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +ALTER INDEX dummy_test_idx RESET (option_bool); +-- Float +ALTER INDEX dummy_test_idx SET (option_real = 4); -- ok +ALTER INDEX dummy_test_idx SET (option_real = true); -- error +ALTER INDEX dummy_test_idx SET (option_real = 'val5'); -- error +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +ALTER INDEX dummy_test_idx RESET (option_real); +-- Enum +ALTER INDEX dummy_test_idx SET (option_enum = 'one'); -- ok +ALTER INDEX dummy_test_idx SET (option_enum = 0); -- error +ALTER INDEX dummy_test_idx SET (option_enum = true); -- error +ALTER INDEX dummy_test_idx SET (option_enum = 'three'); -- error +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +ALTER INDEX dummy_test_idx RESET (option_enum); +-- String +ALTER INDEX dummy_test_idx SET (option_string_val = 4); -- ok +ALTER INDEX dummy_test_idx SET (option_string_val = 3.5); -- ok +ALTER INDEX dummy_test_idx SET (option_string_val = true); -- ok, as "true" +SELECT unnest(reloptions) FROM pg_class WHERE relname = 'dummy_test_idx'; +ALTER INDEX dummy_test_idx RESET (option_string_val); + +DROP INDEX dummy_test_idx; diff --git a/src/test/modules/dummy_seclabel/dummy_seclabel.c b/src/test/modules/dummy_seclabel/dummy_seclabel.c index fc1e7454441..15d3cc0da8f 100644 --- a/src/test/modules/dummy_seclabel/dummy_seclabel.c +++ b/src/test/modules/dummy_seclabel/dummy_seclabel.c @@ -7,12 +7,13 @@ * perspective, but allows regression testing independent of platform-specific * features like SELinux. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California */ #include "postgres.h" #include "commands/seclabel.h" +#include "fmgr.h" #include "miscadmin.h" #include "utils/rel.h" diff --git a/src/test/modules/snapshot_too_old/Makefile b/src/test/modules/snapshot_too_old/Makefile index b6d998f3207..dfb4537f63c 100644 --- a/src/test/modules/snapshot_too_old/Makefile +++ b/src/test/modules/snapshot_too_old/Makefile @@ -4,7 +4,12 @@ # we have to clean those result files explicitly EXTRA_CLEAN = $(pg_regress_clean_files) -ISOLATIONCHECKS=sto_using_cursor sto_using_select sto_using_hash_index +ISOLATION = sto_using_cursor sto_using_select sto_using_hash_index +ISOLATION_OPTS = --temp-config $(top_srcdir)/src/test/modules/snapshot_too_old/sto.conf + +# Disabled because these tests require "old_snapshot_threshold" >= 0, which +# typical installcheck users do not have (e.g. buildfarm clients). +NO_INSTALLCHECK = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -17,31 +22,7 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif -# Disabled because these tests require "old_snapshot_threshold" >= 0, which -# typical installcheck users do not have (e.g. buildfarm clients). -installcheck:; - # But it can nonetheless be very helpful to run tests on preexisting # installation, allow to do so, but only if requested explicitly. -installcheck-force: isolationcheck-install-force - -check: isolationcheck - -submake-isolation: - $(MAKE) -C $(top_builddir)/src/test/isolation all - -submake-test_snapshot_too_old: - $(MAKE) -C $(top_builddir)/src/test/modules/snapshot_too_old - -isolationcheck: | submake-isolation submake-test_snapshot_too_old temp-install - $(pg_isolation_regress_check) \ - --temp-config $(top_srcdir)/src/test/modules/snapshot_too_old/sto.conf \ - $(ISOLATIONCHECKS) - -isolationcheck-install-force: all | submake-isolation submake-test_snapshot_too_old temp-install - $(pg_isolation_regress_installcheck) \ - $(ISOLATIONCHECKS) - -.PHONY: check submake-test_snapshot_too_old isolationcheck isolationcheck-install-force - -temp-install: EXTRA_INSTALL=src/test/modules/snapshot_too_old +installcheck-force: + $(pg_isolation_regress_installcheck) $(ISOLATION) diff --git a/src/test/modules/test_bloomfilter/test_bloomfilter.c b/src/test/modules/test_bloomfilter/test_bloomfilter.c index 358afbefa38..b36537e6138 100644 --- a/src/test/modules/test_bloomfilter/test_bloomfilter.c +++ b/src/test/modules/test_bloomfilter/test_bloomfilter.c @@ -3,7 +3,7 @@ * test_bloomfilter.c * Test false positive rate of Bloom filter. * - * Copyright (c) 2018, PostgreSQL Global Development Group + * Copyright (c) 2018-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_bloomfilter/test_bloomfilter.c @@ -93,7 +93,7 @@ create_and_test_bloom(int power, int64 nelements, int callerseed) nfalsepos = nfalsepos_for_missing_strings(filter, nelements); ereport((nfalsepos > nelements * FPOSITIVE_THRESHOLD) ? WARNING : DEBUG1, - (errmsg_internal("seed: " UINT64_FORMAT " false positives: " INT64_FORMAT " (%.6f%%) bitset %.2f%% set" , + (errmsg_internal("seed: " UINT64_FORMAT " false positives: " INT64_FORMAT " (%.6f%%) bitset %.2f%% set", seed, nfalsepos, (double) nfalsepos / nelements, 100.0 * bloom_prop_bits_set(filter)))); diff --git a/src/test/modules/test_ddl_deparse/expected/alter_table.out b/src/test/modules/test_ddl_deparse/expected/alter_table.out index e304787bc55..141060fbdcf 100644 --- a/src/test/modules/test_ddl_deparse/expected/alter_table.out +++ b/src/test/modules/test_ddl_deparse/expected/alter_table.out @@ -16,3 +16,14 @@ NOTICE: DDL test: type simple, tag ALTER TABLE ALTER TABLE parent ADD CONSTRAINT a_pos CHECK (a > 0); NOTICE: DDL test: type alter table, tag ALTER TABLE NOTICE: subcommand: ADD CONSTRAINT (and recurse) +CREATE TABLE part ( + a int +) PARTITION BY RANGE (a); +NOTICE: DDL test: type simple, tag CREATE TABLE +CREATE TABLE part1 PARTITION OF part FOR VALUES FROM (1) to (100); +NOTICE: DDL test: type simple, tag CREATE TABLE +ALTER TABLE part ADD PRIMARY KEY (a); +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: SET NOT NULL +NOTICE: subcommand: SET NOT NULL +NOTICE: subcommand: ADD INDEX diff --git a/src/test/modules/test_ddl_deparse/expected/create_table.out b/src/test/modules/test_ddl_deparse/expected/create_table.out index d27a7752570..523c9960933 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_table.out +++ b/src/test/modules/test_ddl_deparse/expected/create_table.out @@ -85,6 +85,8 @@ CREATE TABLE employees OF employee_type ( salary WITH OPTIONS DEFAULT 1000 ); NOTICE: DDL test: type simple, tag CREATE TABLE +NOTICE: DDL test: type alter table, tag ALTER TABLE +NOTICE: subcommand: SET NOT NULL NOTICE: DDL test: type simple, tag CREATE INDEX -- Inheritance CREATE TABLE person ( @@ -98,7 +100,7 @@ NOTICE: DDL test: type simple, tag CREATE INDEX CREATE TABLE emp ( salary int4, manager name -) INHERITS (person) WITH OIDS; +) INHERITS (person); NOTICE: DDL test: type simple, tag CREATE TABLE CREATE TABLE student ( gpa float8 diff --git a/src/test/modules/test_ddl_deparse/expected/create_transform.out b/src/test/modules/test_ddl_deparse/expected/create_transform.out index 0d1cc360f4e..5066051fca1 100644 --- a/src/test/modules/test_ddl_deparse/expected/create_transform.out +++ b/src/test/modules/test_ddl_deparse/expected/create_transform.out @@ -5,9 +5,11 @@ -- The function FROM SQL should have internal as single argument as well -- as return type. The function TO SQL should have as single argument -- internal and as return argument the datatype of the transform done. --- pl/plpgsql does not authorize the use of internal as data type. +-- We choose some random built-in functions that have the right signature. +-- This won't actually be used, because the SQL function language +-- doesn't implement transforms (there would be no point). CREATE TRANSFORM FOR int LANGUAGE SQL ( - FROM SQL WITH FUNCTION varchar_transform(internal), + FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); NOTICE: DDL test: type simple, tag CREATE TRANSFORM DROP TRANSFORM FOR int LANGUAGE SQL; diff --git a/src/test/modules/test_ddl_deparse/sql/alter_table.sql b/src/test/modules/test_ddl_deparse/sql/alter_table.sql index 6e2cca754e3..dec53a0640f 100644 --- a/src/test/modules/test_ddl_deparse/sql/alter_table.sql +++ b/src/test/modules/test_ddl_deparse/sql/alter_table.sql @@ -11,3 +11,11 @@ ALTER TABLE parent ADD COLUMN b serial; ALTER TABLE parent RENAME COLUMN b TO c; ALTER TABLE parent ADD CONSTRAINT a_pos CHECK (a > 0); + +CREATE TABLE part ( + a int +) PARTITION BY RANGE (a); + +CREATE TABLE part1 PARTITION OF part FOR VALUES FROM (1) to (100); + +ALTER TABLE part ADD PRIMARY KEY (a); diff --git a/src/test/modules/test_ddl_deparse/sql/create_table.sql b/src/test/modules/test_ddl_deparse/sql/create_table.sql index 5e784527297..dd3a908638d 100644 --- a/src/test/modules/test_ddl_deparse/sql/create_table.sql +++ b/src/test/modules/test_ddl_deparse/sql/create_table.sql @@ -86,7 +86,7 @@ CREATE TABLE person ( CREATE TABLE emp ( salary int4, manager name -) INHERITS (person) WITH OIDS; +) INHERITS (person); CREATE TABLE student ( diff --git a/src/test/modules/test_ddl_deparse/sql/create_transform.sql b/src/test/modules/test_ddl_deparse/sql/create_transform.sql index 096870233f8..970d89e03dc 100644 --- a/src/test/modules/test_ddl_deparse/sql/create_transform.sql +++ b/src/test/modules/test_ddl_deparse/sql/create_transform.sql @@ -6,9 +6,11 @@ -- The function FROM SQL should have internal as single argument as well -- as return type. The function TO SQL should have as single argument -- internal and as return argument the datatype of the transform done. --- pl/plpgsql does not authorize the use of internal as data type. +-- We choose some random built-in functions that have the right signature. +-- This won't actually be used, because the SQL function language +-- doesn't implement transforms (there would be no point). CREATE TRANSFORM FOR int LANGUAGE SQL ( - FROM SQL WITH FUNCTION varchar_transform(internal), + FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); DROP TRANSFORM FOR int LANGUAGE SQL; diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c index 82a51eb3039..7f77f194407 100644 --- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c +++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c @@ -2,7 +2,7 @@ * test_ddl_deparse.c * Support functions for the test_ddl_deparse module * - * Copyright (c) 2014-2018, PostgreSQL Global Development Group + * Copyright (c) 2014-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_ddl_deparse/test_ddl_deparse.c @@ -117,6 +117,9 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_SetNotNull: strtype = "SET NOT NULL"; break; + case AT_CheckNotNull: + strtype = "CHECK NOT NULL"; + break; case AT_SetStatistics: strtype = "SET STATS"; break; @@ -195,12 +198,6 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS) case AT_SetUnLogged: strtype = "SET UNLOGGED"; break; - case AT_AddOids: - strtype = "ADD OIDS"; - break; - case AT_AddOidsRecurse: - strtype = "ADD OIDS (and recurse)"; - break; case AT_DropOids: strtype = "DROP OIDS"; break; diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out index 28d86c4b87f..b5cbdfcad4f 100644 --- a/src/test/modules/test_extensions/expected/test_extensions.out +++ b/src/test/modules/test_extensions/expected/test_extensions.out @@ -121,3 +121,36 @@ Objects in extension "test_ext8" -- dropping it should still work drop extension test_ext8; +-- Test creation of extension in temporary schema with two-phase commit, +-- which should not work. This function wrapper is useful for portability. +-- Avoid noise caused by CONTEXT and NOTICE messages including the temporary +-- schema name. +\set SHOW_CONTEXT never +SET client_min_messages TO 'warning'; +-- First enforce presence of temporary schema. +CREATE TEMP TABLE test_ext4_tab (); +CREATE OR REPLACE FUNCTION create_extension_with_temp_schema() + RETURNS VOID AS $$ + DECLARE + tmpschema text; + query text; + BEGIN + SELECT INTO tmpschema pg_my_temp_schema()::regnamespace; + query := 'CREATE EXTENSION test_ext4 SCHEMA ' || tmpschema || ' CASCADE;'; + RAISE NOTICE 'query %', query; + EXECUTE query; + END; $$ LANGUAGE plpgsql; +BEGIN; +SELECT create_extension_with_temp_schema(); + create_extension_with_temp_schema +----------------------------------- + +(1 row) + +PREPARE TRANSACTION 'twophase_extension'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- Clean up +DROP TABLE test_ext4_tab; +DROP FUNCTION create_extension_with_temp_schema(); +RESET client_min_messages; +\unset SHOW_CONTEXT diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql b/src/test/modules/test_extensions/sql/test_extensions.sql index 9e64503eb50..f505466ab4e 100644 --- a/src/test/modules/test_extensions/sql/test_extensions.sql +++ b/src/test/modules/test_extensions/sql/test_extensions.sql @@ -64,3 +64,32 @@ end'; -- dropping it should still work drop extension test_ext8; + +-- Test creation of extension in temporary schema with two-phase commit, +-- which should not work. This function wrapper is useful for portability. + +-- Avoid noise caused by CONTEXT and NOTICE messages including the temporary +-- schema name. +\set SHOW_CONTEXT never +SET client_min_messages TO 'warning'; +-- First enforce presence of temporary schema. +CREATE TEMP TABLE test_ext4_tab (); +CREATE OR REPLACE FUNCTION create_extension_with_temp_schema() + RETURNS VOID AS $$ + DECLARE + tmpschema text; + query text; + BEGIN + SELECT INTO tmpschema pg_my_temp_schema()::regnamespace; + query := 'CREATE EXTENSION test_ext4 SCHEMA ' || tmpschema || ' CASCADE;'; + RAISE NOTICE 'query %', query; + EXECUTE query; + END; $$ LANGUAGE plpgsql; +BEGIN; +SELECT create_extension_with_temp_schema(); +PREPARE TRANSACTION 'twophase_extension'; +-- Clean up +DROP TABLE test_ext4_tab; +DROP FUNCTION create_extension_with_temp_schema(); +RESET client_min_messages; +\unset SHOW_CONTEXT diff --git a/src/test/modules/test_ginpostinglist/.gitignore b/src/test/modules/test_ginpostinglist/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/test_ginpostinglist/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/test_ginpostinglist/Makefile b/src/test/modules/test_ginpostinglist/Makefile new file mode 100644 index 00000000000..4d45ac999af --- /dev/null +++ b/src/test/modules/test_ginpostinglist/Makefile @@ -0,0 +1,21 @@ +# src/test/modules/test_ginpostinglist/Makefile + +MODULE_big = test_ginpostinglist +OBJS = test_ginpostinglist.o $(WIN32RES) +PGFILEDESC = "test_ginpostinglist - test code for src/backend/access/gin//ginpostinglist.c" + +EXTENSION = test_ginpostinglist +DATA = test_ginpostinglist--1.0.sql + +REGRESS = test_ginpostinglist + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_ginpostinglist +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_ginpostinglist/README b/src/test/modules/test_ginpostinglist/README new file mode 100644 index 00000000000..66684dd0da4 --- /dev/null +++ b/src/test/modules/test_ginpostinglist/README @@ -0,0 +1,2 @@ +test_ginpostinglist contains unit tests for the GIN posting list code in +src/backend/access/gin/ginpostinglist.c. diff --git a/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out b/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out new file mode 100644 index 00000000000..4d0beaecea9 --- /dev/null +++ b/src/test/modules/test_ginpostinglist/expected/test_ginpostinglist.out @@ -0,0 +1,19 @@ +CREATE EXTENSION test_ginpostinglist; +-- +-- All the logic is in the test_ginpostinglist() function. It will throw +-- a error if something fails. +-- +SELECT test_ginpostinglist(); +NOTICE: testing with (0, 1), (0, 2), max 14 bytes +NOTICE: encoded 2 item pointers to 10 bytes +NOTICE: testing with (0, 1), (0, 291), max 14 bytes +NOTICE: encoded 2 item pointers to 10 bytes +NOTICE: testing with (0, 1), (4294967294, 291), max 14 bytes +NOTICE: encoded 1 item pointers to 8 bytes +NOTICE: testing with (0, 1), (4294967294, 291), max 16 bytes +NOTICE: encoded 2 item pointers to 16 bytes + test_ginpostinglist +--------------------- + +(1 row) + diff --git a/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql b/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql new file mode 100644 index 00000000000..b8cab7accec --- /dev/null +++ b/src/test/modules/test_ginpostinglist/sql/test_ginpostinglist.sql @@ -0,0 +1,7 @@ +CREATE EXTENSION test_ginpostinglist; + +-- +-- All the logic is in the test_ginpostinglist() function. It will throw +-- a error if something fails. +-- +SELECT test_ginpostinglist(); diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql b/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql new file mode 100644 index 00000000000..37396a48424 --- /dev/null +++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql @@ -0,0 +1,8 @@ +/* src/test/modules/test_ginpostinglist/test_ginpostinglist--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_ginpostinglist" to load this file. \quit + +CREATE FUNCTION test_ginpostinglist() +RETURNS pg_catalog.void STRICT +AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist.c b/src/test/modules/test_ginpostinglist/test_ginpostinglist.c new file mode 100644 index 00000000000..bab073bcecc --- /dev/null +++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist.c @@ -0,0 +1,96 @@ +/*-------------------------------------------------------------------------- + * + * test_ginpostinglist.c + * Test varbyte-encoding in ginpostinglist.c + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_ginpostinglist/test_ginpostinglist.c + * + * ------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "fmgr.h" +#include "access/ginblock.h" +#include "access/gin_private.h" +#include "access/htup_details.h" + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(test_ginpostinglist); + +/* + * Encodes a pair of TIDs, and decodes it back. The first TID is always + * (0, 1), the second one is formed from the blk/off arguments. The 'maxsize' + * argument is passed to ginCompressPostingList(); it can be used to test the + * overflow checks. + * + * The reason that we test a pair, instead of just a single TID, is that + * the GinPostingList stores the first TID as is, and the varbyte-encoding + * is only used for the deltas between TIDs. So testing a single TID would + * not exercise the varbyte encoding at all. + * + * This function prints NOTICEs to describe what is tested, and how large the + * resulting GinPostingList is. Any incorrect results, e.g. if the encode + + * decode round trip doesn't return the original input, are reported as + * ERRORs. + */ +static void +test_itemptr_pair(BlockNumber blk, OffsetNumber off, int maxsize) +{ + ItemPointerData orig_itemptrs[2]; + ItemPointer decoded_itemptrs; + GinPostingList *pl; + int nwritten; + int ndecoded; + + elog(NOTICE, "testing with (%u, %d), (%u, %d), max %d bytes", + 0, 1, blk, off, maxsize); + ItemPointerSet(&orig_itemptrs[0], 0, 1); + ItemPointerSet(&orig_itemptrs[1], blk, off); + + /* Encode, and decode it back */ + pl = ginCompressPostingList(orig_itemptrs, 2, maxsize, &nwritten); + elog(NOTICE, "encoded %d item pointers to %zu bytes", + nwritten, SizeOfGinPostingList(pl)); + + if (SizeOfGinPostingList(pl) > maxsize) + elog(ERROR, "overflow: result was %zu bytes, max %d", + SizeOfGinPostingList(pl), maxsize); + + decoded_itemptrs = ginPostingListDecode(pl, &ndecoded); + if (nwritten != ndecoded) + elog(NOTICE, "encoded %d itemptrs, %d came back", nwritten, ndecoded); + + /* Check the result */ + if (!ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0])) + elog(ERROR, "mismatch on first itemptr: (%u, %d) vs (%u, %d)", + 0, 1, + ItemPointerGetBlockNumber(&decoded_itemptrs[0]), + ItemPointerGetOffsetNumber(&decoded_itemptrs[0])); + + if (ndecoded == 2 && + !ItemPointerEquals(&orig_itemptrs[0], &decoded_itemptrs[0])) + { + elog(ERROR, "mismatch on second itemptr: (%u, %d) vs (%u, %d)", + 0, 1, + ItemPointerGetBlockNumber(&decoded_itemptrs[0]), + ItemPointerGetOffsetNumber(&decoded_itemptrs[0])); + } +} + +/* + * SQL-callable entry point to perform all tests. + */ +Datum +test_ginpostinglist(PG_FUNCTION_ARGS) +{ + test_itemptr_pair(0, 2, 14); + test_itemptr_pair(0, MaxHeapTuplesPerPage, 14); + test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 14); + test_itemptr_pair(MaxBlockNumber, MaxHeapTuplesPerPage, 16); + + PG_RETURN_VOID(); +} diff --git a/src/test/modules/test_ginpostinglist/test_ginpostinglist.control b/src/test/modules/test_ginpostinglist/test_ginpostinglist.control new file mode 100644 index 00000000000..e4f5a7ceadb --- /dev/null +++ b/src/test/modules/test_ginpostinglist/test_ginpostinglist.control @@ -0,0 +1,4 @@ +comment = 'Test code for ginpostinglist.c' +default_version = '1.0' +module_pathname = '$libdir/test_ginpostinglist' +relocatable = true diff --git a/src/test/modules/test_integerset/.gitignore b/src/test/modules/test_integerset/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/test_integerset/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/test_integerset/Makefile b/src/test/modules/test_integerset/Makefile new file mode 100644 index 00000000000..3b7c4999d6f --- /dev/null +++ b/src/test/modules/test_integerset/Makefile @@ -0,0 +1,21 @@ +# src/test/modules/test_integerset/Makefile + +MODULE_big = test_integerset +OBJS = test_integerset.o $(WIN32RES) +PGFILEDESC = "test_integerset - test code for src/backend/lib/integerset.c" + +EXTENSION = test_integerset +DATA = test_integerset--1.0.sql + +REGRESS = test_integerset + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_integerset +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_integerset/README b/src/test/modules/test_integerset/README new file mode 100644 index 00000000000..a8b271869a9 --- /dev/null +++ b/src/test/modules/test_integerset/README @@ -0,0 +1,7 @@ +test_integerset contains unit tests for testing the integer set implementation +in src/backend/lib/integerset.c. + +The tests verify the correctness of the implementation, but they can also be +used as a micro-benchmark. If you set the 'intset_test_stats' flag in +test_integerset.c, the tests will print extra information about execution time +and memory usage. diff --git a/src/test/modules/test_integerset/expected/test_integerset.out b/src/test/modules/test_integerset/expected/test_integerset.out new file mode 100644 index 00000000000..822dd031e9e --- /dev/null +++ b/src/test/modules/test_integerset/expected/test_integerset.out @@ -0,0 +1,31 @@ +CREATE EXTENSION test_integerset; +-- +-- All the logic is in the test_integerset() function. It will throw +-- an error if something fails. +-- +SELECT test_integerset(); +NOTICE: testing intset with empty set +NOTICE: testing intset with distances > 2^60 between values +NOTICE: testing intset with single value 0 +NOTICE: testing intset with single value 1 +NOTICE: testing intset with single value 18446744073709551614 +NOTICE: testing intset with single value 18446744073709551615 +NOTICE: testing intset with value 0, and all between 1000 and 2000 +NOTICE: testing intset with value 1, and all between 1000 and 2000 +NOTICE: testing intset with value 1, and all between 1000 and 2000000 +NOTICE: testing intset with value 18446744073709551614, and all between 1000 and 2000 +NOTICE: testing intset with value 18446744073709551615, and all between 1000 and 2000 +NOTICE: testing intset with pattern "all ones" +NOTICE: testing intset with pattern "alternating bits" +NOTICE: testing intset with pattern "clusters of ten" +NOTICE: testing intset with pattern "clusters of hundred" +NOTICE: testing intset with pattern "one-every-64k" +NOTICE: testing intset with pattern "sparse" +NOTICE: testing intset with pattern "single values, distance > 2^32" +NOTICE: testing intset with pattern "clusters, distance > 2^32" +NOTICE: testing intset with pattern "clusters, distance > 2^60" + test_integerset +----------------- + +(1 row) + diff --git a/src/test/modules/test_integerset/sql/test_integerset.sql b/src/test/modules/test_integerset/sql/test_integerset.sql new file mode 100644 index 00000000000..9d970dd1f9e --- /dev/null +++ b/src/test/modules/test_integerset/sql/test_integerset.sql @@ -0,0 +1,7 @@ +CREATE EXTENSION test_integerset; + +-- +-- All the logic is in the test_integerset() function. It will throw +-- an error if something fails. +-- +SELECT test_integerset(); diff --git a/src/test/modules/test_integerset/test_integerset--1.0.sql b/src/test/modules/test_integerset/test_integerset--1.0.sql new file mode 100644 index 00000000000..d6d5a3f6cf7 --- /dev/null +++ b/src/test/modules/test_integerset/test_integerset--1.0.sql @@ -0,0 +1,8 @@ +/* src/test/modules/test_integerset/test_integerset--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_integerset" to load this file. \quit + +CREATE FUNCTION test_integerset() +RETURNS pg_catalog.void STRICT +AS 'MODULE_PATHNAME' LANGUAGE C; diff --git a/src/test/modules/test_integerset/test_integerset.c b/src/test/modules/test_integerset/test_integerset.c new file mode 100644 index 00000000000..e3925a156d6 --- /dev/null +++ b/src/test/modules/test_integerset/test_integerset.c @@ -0,0 +1,623 @@ +/*-------------------------------------------------------------------------- + * + * test_integerset.c + * Test integer set data structure. + * + * Copyright (c) 2019, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_integerset/test_integerset.c + * + * ------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "fmgr.h" +#include "lib/integerset.h" +#include "nodes/bitmapset.h" +#include "utils/memutils.h" +#include "utils/timestamp.h" +#include "storage/block.h" +#include "storage/itemptr.h" +#include "miscadmin.h" + +/* + * If you enable this, the "pattern" tests will print information about + * how long populating, probing, and iterating the test set takes, and + * how much memory the test set consumed. That can be used as + * micro-benchmark of various operations and input patterns (you might + * want to increase the number of values used in each of the test, if + * you do that, to reduce noise). + * + * The information is printed to the server's stderr, mostly because + * that's where MemoryContextStats() output goes. + */ +static const bool intset_test_stats = false; + +PG_MODULE_MAGIC; + +PG_FUNCTION_INFO_V1(test_integerset); + +/* + * A struct to define a pattern of integers, for use with the test_pattern() + * function. + */ +typedef struct +{ + char *test_name; /* short name of the test, for humans */ + char *pattern_str; /* a bit pattern */ + uint64 spacing; /* pattern repeats at this interval */ + uint64 num_values; /* number of integers to set in total */ +} test_spec; + +static const test_spec test_specs[] = { + { + "all ones", "1111111111", + 10, 10000000 + }, + { + "alternating bits", "0101010101", + 10, 10000000 + }, + { + "clusters of ten", "1111111111", + 10000, 10000000 + }, + { + "clusters of hundred", + "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", + 10000, 100000000 + }, + { + "one-every-64k", "1", + 65536, 10000000 + }, + { + "sparse", "100000000000000000000000000000001", + 10000000, 10000000 + }, + { + "single values, distance > 2^32", "1", + UINT64CONST(10000000000), 1000000 + }, + { + "clusters, distance > 2^32", "10101010", + UINT64CONST(10000000000), 10000000 + }, + { + "clusters, distance > 2^60", "10101010", + UINT64CONST(2000000000000000000), + 23 /* can't be much higher than this, or we + * overflow uint64 */ + } +}; + +static void test_pattern(const test_spec *spec); +static void test_empty(void); +static void test_single_value(uint64 value); +static void check_with_filler(IntegerSet *intset, uint64 x, uint64 value, uint64 filler_min, uint64 filler_max); +static void test_single_value_and_filler(uint64 value, uint64 filler_min, uint64 filler_max); +static void test_huge_distances(void); + +/* + * SQL-callable entry point to perform all tests. + */ +Datum +test_integerset(PG_FUNCTION_ARGS) +{ + /* Tests for various corner cases */ + test_empty(); + test_huge_distances(); + test_single_value(0); + test_single_value(1); + test_single_value(PG_UINT64_MAX - 1); + test_single_value(PG_UINT64_MAX); + test_single_value_and_filler(0, 1000, 2000); + test_single_value_and_filler(1, 1000, 2000); + test_single_value_and_filler(1, 1000, 2000000); + test_single_value_and_filler(PG_UINT64_MAX - 1, 1000, 2000); + test_single_value_and_filler(PG_UINT64_MAX, 1000, 2000); + + /* Test different test patterns, with lots of entries */ + for (int i = 0; i < lengthof(test_specs); i++) + { + test_pattern(&test_specs[i]); + } + + PG_RETURN_VOID(); +} + +/* + * Test with a repeating pattern, defined by the 'spec'. + */ +static void +test_pattern(const test_spec *spec) +{ + IntegerSet *intset; + MemoryContext intset_ctx; + MemoryContext old_ctx; + TimestampTz starttime; + TimestampTz endtime; + uint64 n; + uint64 last_int; + int patternlen; + uint64 *pattern_values; + uint64 pattern_num_values; + + elog(NOTICE, "testing intset with pattern \"%s\"", spec->test_name); + if (intset_test_stats) + fprintf(stderr, "-----\ntesting intset with pattern \"%s\"\n", spec->test_name); + + /* Pre-process the pattern, creating an array of integers from it. */ + patternlen = strlen(spec->pattern_str); + pattern_values = palloc(patternlen * sizeof(uint64)); + pattern_num_values = 0; + for (int i = 0; i < patternlen; i++) + { + if (spec->pattern_str[i] == '1') + pattern_values[pattern_num_values++] = i; + } + + /* + * Allocate the integer set. + * + * Allocate it in a separate memory context, so that we can print its + * memory usage easily. (intset_create() creates a memory context of its + * own, too, but we don't have direct access to it, so we cannot call + * MemoryContextStats() on it directly). + */ + intset_ctx = AllocSetContextCreate(CurrentMemoryContext, + "intset test", + ALLOCSET_SMALL_SIZES); + MemoryContextSetIdentifier(intset_ctx, spec->test_name); + old_ctx = MemoryContextSwitchTo(intset_ctx); + intset = intset_create(); + MemoryContextSwitchTo(old_ctx); + + /* + * Add values to the set. + */ + starttime = GetCurrentTimestamp(); + + n = 0; + last_int = 0; + while (n < spec->num_values) + { + uint64 x = 0; + + for (int i = 0; i < pattern_num_values && n < spec->num_values; i++) + { + x = last_int + pattern_values[i]; + + intset_add_member(intset, x); + n++; + } + last_int += spec->spacing; + } + + endtime = GetCurrentTimestamp(); + + if (intset_test_stats) + fprintf(stderr, "added " UINT64_FORMAT " values in %d ms\n", + spec->num_values, (int) (endtime - starttime) / 1000); + + /* + * Print stats on the amount of memory used. + * + * We print the usage reported by intset_memory_usage(), as well as the + * stats from the memory context. They should be in the same ballpark, + * but it's hard to automate testing that, so if you're making changes to + * the implementation, just observe that manually. + */ + if (intset_test_stats) + { + uint64 mem_usage; + + /* + * Also print memory usage as reported by intset_memory_usage(). It + * should be in the same ballpark as the usage reported by + * MemoryContextStats(). + */ + mem_usage = intset_memory_usage(intset); + fprintf(stderr, "intset_memory_usage() reported " UINT64_FORMAT " (%0.2f bytes / integer)\n", + mem_usage, (double) mem_usage / spec->num_values); + + MemoryContextStats(intset_ctx); + } + + /* Check that intset_get_num_entries works */ + n = intset_num_entries(intset); + if (n != spec->num_values) + elog(ERROR, "intset_num_entries returned " UINT64_FORMAT ", expected " UINT64_FORMAT, n, spec->num_values); + + /* + * Test random-access probes with intset_is_member() + */ + starttime = GetCurrentTimestamp(); + + for (n = 0; n < 100000; n++) + { + bool b; + bool expected; + uint64 x; + + /* + * Pick next value to probe at random. We limit the probes to the + * last integer that we added to the set, plus an arbitrary constant + * (1000). There's no point in probing the whole 0 - 2^64 range, if + * only a small part of the integer space is used. We would very + * rarely hit values that are actually in the set. + */ + x = (pg_lrand48() << 31) | pg_lrand48(); + x = x % (last_int + 1000); + + /* Do we expect this value to be present in the set? */ + if (x >= last_int) + expected = false; + else + { + uint64 idx = x % spec->spacing; + + if (idx >= patternlen) + expected = false; + else if (spec->pattern_str[idx] == '1') + expected = true; + else + expected = false; + } + + /* Is it present according to intset_is_member() ? */ + b = intset_is_member(intset, x); + + if (b != expected) + elog(ERROR, "mismatch at " UINT64_FORMAT ": %d vs %d", x, b, expected); + } + endtime = GetCurrentTimestamp(); + if (intset_test_stats) + fprintf(stderr, "probed " UINT64_FORMAT " values in %d ms\n", + n, (int) (endtime - starttime) / 1000); + + /* + * Test iterator + */ + starttime = GetCurrentTimestamp(); + + intset_begin_iterate(intset); + n = 0; + last_int = 0; + while (n < spec->num_values) + { + for (int i = 0; i < pattern_num_values && n < spec->num_values; i++) + { + uint64 expected = last_int + pattern_values[i]; + uint64 x; + + if (!intset_iterate_next(intset, &x)) + break; + + if (x != expected) + elog(ERROR, "iterate returned wrong value; got " UINT64_FORMAT ", expected " UINT64_FORMAT, x, expected); + n++; + } + last_int += spec->spacing; + } + endtime = GetCurrentTimestamp(); + if (intset_test_stats) + fprintf(stderr, "iterated " UINT64_FORMAT " values in %d ms\n", + n, (int) (endtime - starttime) / 1000); + + if (n < spec->num_values) + elog(ERROR, "iterator stopped short after " UINT64_FORMAT " entries, expected " UINT64_FORMAT, n, spec->num_values); + if (n > spec->num_values) + elog(ERROR, "iterator returned " UINT64_FORMAT " entries, " UINT64_FORMAT " was expected", n, spec->num_values); + + MemoryContextDelete(intset_ctx); +} + +/* + * Test with a set containing a single integer. + */ +static void +test_single_value(uint64 value) +{ + IntegerSet *intset; + uint64 x; + uint64 num_entries; + bool found; + + elog(NOTICE, "testing intset with single value " UINT64_FORMAT, value); + + /* Create the set. */ + intset = intset_create(); + intset_add_member(intset, value); + + /* Test intset_get_num_entries() */ + num_entries = intset_num_entries(intset); + if (num_entries != 1) + elog(ERROR, "intset_num_entries returned " UINT64_FORMAT ", expected 1", num_entries); + + /* + * Test intset_is_member() at various special values, like 0 and maximum + * possible 64-bit integer, as well as the value itself. + */ + if (intset_is_member(intset, 0) != (value == 0)) + elog(ERROR, "intset_is_member failed for 0"); + if (intset_is_member(intset, 1) != (value == 1)) + elog(ERROR, "intset_is_member failed for 1"); + if (intset_is_member(intset, PG_UINT64_MAX) != (value == PG_UINT64_MAX)) + elog(ERROR, "intset_is_member failed for PG_UINT64_MAX"); + if (intset_is_member(intset, value) != true) + elog(ERROR, "intset_is_member failed for the tested value"); + + /* + * Test iterator + */ + intset_begin_iterate(intset); + found = intset_iterate_next(intset, &x); + if (!found || x != value) + elog(ERROR, "intset_iterate_next failed for " UINT64_FORMAT, x); + + found = intset_iterate_next(intset, &x); + if (found) + elog(ERROR, "intset_iterate_next failed " UINT64_FORMAT, x); +} + +/* + * Test with an integer set that contains: + * + * - a given single 'value', and + * - all integers between 'filler_min' and 'filler_max'. + * + * This exercises different codepaths than testing just with a single value, + * because the implementation buffers newly-added values. If we add just a + * single value to the set, we won't test the internal B-tree code at all, + * just the code that deals with the buffer. + */ +static void +test_single_value_and_filler(uint64 value, uint64 filler_min, uint64 filler_max) +{ + IntegerSet *intset; + uint64 x; + bool found; + uint64 *iter_expected; + uint64 n = 0; + uint64 num_entries = 0; + uint64 mem_usage; + + elog(NOTICE, "testing intset with value " UINT64_FORMAT ", and all between " UINT64_FORMAT " and " UINT64_FORMAT, + value, filler_min, filler_max); + + intset = intset_create(); + + iter_expected = palloc(sizeof(uint64) * (filler_max - filler_min + 1)); + if (value < filler_min) + { + intset_add_member(intset, value); + iter_expected[n++] = value; + } + + for (x = filler_min; x < filler_max; x++) + { + intset_add_member(intset, x); + iter_expected[n++] = x; + } + + if (value >= filler_max) + { + intset_add_member(intset, value); + iter_expected[n++] = value; + } + + /* Test intset_get_num_entries() */ + num_entries = intset_num_entries(intset); + if (num_entries != n) + elog(ERROR, "intset_num_entries returned " UINT64_FORMAT ", expected " UINT64_FORMAT, num_entries, n); + + /* + * Test intset_is_member() at various spots, at and around the values that + * we expect to be set, as well as 0 and the maximum possible value. + */ + check_with_filler(intset, 0, + value, filler_min, filler_max); + check_with_filler(intset, 1, + value, filler_min, filler_max); + check_with_filler(intset, filler_min - 1, + value, filler_min, filler_max); + check_with_filler(intset, filler_min, + value, filler_min, filler_max); + check_with_filler(intset, filler_min + 1, + value, filler_min, filler_max); + check_with_filler(intset, value - 1, + value, filler_min, filler_max); + check_with_filler(intset, value, + value, filler_min, filler_max); + check_with_filler(intset, value + 1, + value, filler_min, filler_max); + check_with_filler(intset, filler_max - 1, + value, filler_min, filler_max); + check_with_filler(intset, filler_max, + value, filler_min, filler_max); + check_with_filler(intset, filler_max + 1, + value, filler_min, filler_max); + check_with_filler(intset, PG_UINT64_MAX - 1, + value, filler_min, filler_max); + check_with_filler(intset, PG_UINT64_MAX, + value, filler_min, filler_max); + + intset_begin_iterate(intset); + for (uint64 i = 0; i < n; i++) + { + found = intset_iterate_next(intset, &x); + if (!found || x != iter_expected[i]) + elog(ERROR, "intset_iterate_next failed for " UINT64_FORMAT, x); + } + found = intset_iterate_next(intset, &x); + if (found) + elog(ERROR, "intset_iterate_next failed " UINT64_FORMAT, x); + + mem_usage = intset_memory_usage(intset); + if (mem_usage < 5000 || mem_usage > 500000000) + elog(ERROR, "intset_memory_usage() reported suspicious value: " UINT64_FORMAT, mem_usage); +} + +/* + * Helper function for test_single_value_and_filler. + * + * Calls intset_is_member() for value 'x', and checks that the result is what + * we expect. + */ +static void +check_with_filler(IntegerSet *intset, uint64 x, + uint64 value, uint64 filler_min, uint64 filler_max) +{ + bool expected; + bool actual; + + expected = (x == value || (filler_min <= x && x < filler_max)); + + actual = intset_is_member(intset, x); + + if (actual != expected) + elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x); +} + +/* + * Test empty set + */ +static void +test_empty(void) +{ + IntegerSet *intset; + uint64 x; + + elog(NOTICE, "testing intset with empty set"); + + intset = intset_create(); + + /* Test intset_is_member() */ + if (intset_is_member(intset, 0) != false) + elog(ERROR, "intset_is_member on empty set returned true"); + if (intset_is_member(intset, 1) != false) + elog(ERROR, "intset_is_member on empty set returned true"); + if (intset_is_member(intset, PG_UINT64_MAX) != false) + elog(ERROR, "intset_is_member on empty set returned true"); + + /* Test iterator */ + intset_begin_iterate(intset); + if (intset_iterate_next(intset, &x)) + elog(ERROR, "intset_iterate_next on empty set returned a value (" UINT64_FORMAT ")", x); +} + +/* + * Test with integers that are more than 2^60 apart. + * + * The Simple-8b encoding used by the set implementation can only encode + * values up to 2^60. That makes large differences like this interesting + * to test. + */ +static void +test_huge_distances(void) +{ + IntegerSet *intset; + uint64 values[1000]; + int num_values = 0; + uint64 val = 0; + bool found; + uint64 x; + + elog(NOTICE, "testing intset with distances > 2^60 between values"); + + val = 0; + values[num_values++] = val; + + /* Test differences on both sides of the 2^60 boundary. */ + val += UINT64CONST(1152921504606846976) - 1; /* 2^60 - 1 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) - 1; /* 2^60 - 1 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976); /* 2^60 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976); /* 2^60 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976); /* 2^60 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) + 1; /* 2^60 + 1 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) + 1; /* 2^60 + 1 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) + 1; /* 2^60 + 1 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) + 2; /* 2^60 + 2 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976) + 2; /* 2^60 + 2 */ + values[num_values++] = val; + + val += UINT64CONST(1152921504606846976); /* 2^60 */ + values[num_values++] = val; + + /* + * We're now very close to 2^64, so can't add large values anymore. But + * add more smaller values to the end, to make sure that all the above + * values get flushed and packed into the tree structure. + */ + while (num_values < 1000) + { + val += pg_lrand48(); + values[num_values++] = val; + } + + /* Create an IntegerSet using these values */ + intset = intset_create(); + for (int i = 0; i < num_values; i++) + intset_add_member(intset, values[i]); + + /* + * Test intset_is_member() around each of these values + */ + for (int i = 0; i < num_values; i++) + { + uint64 x = values[i]; + bool expected; + bool result; + + if (x > 0) + { + expected = (values[i - 1] == x - 1); + result = intset_is_member(intset, x - 1); + if (result != expected) + elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x - 1); + } + + result = intset_is_member(intset, x); + if (result != true) + elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x); + + expected = (i != num_values - 1) ? (values[i + 1] == x + 1) : false; + result = intset_is_member(intset, x + 1); + if (result != expected) + elog(ERROR, "intset_is_member failed for " UINT64_FORMAT, x + 1); + } + + /* + * Test iterator + */ + intset_begin_iterate(intset); + for (int i = 0; i < num_values; i++) + { + found = intset_iterate_next(intset, &x); + if (!found || x != values[i]) + elog(ERROR, "intset_iterate_next failed for " UINT64_FORMAT, x); + } + found = intset_iterate_next(intset, &x); + if (found) + elog(ERROR, "intset_iterate_next failed " UINT64_FORMAT, x); +} diff --git a/src/test/modules/test_integerset/test_integerset.control b/src/test/modules/test_integerset/test_integerset.control new file mode 100644 index 00000000000..7d20c2d7b88 --- /dev/null +++ b/src/test/modules/test_integerset/test_integerset.control @@ -0,0 +1,4 @@ +comment = 'Test code for integerset' +default_version = '1.0' +module_pathname = '$libdir/test_integerset' +relocatable = true diff --git a/src/test/modules/test_misc/.gitignore b/src/test/modules/test_misc/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/test_misc/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/test_misc/Makefile b/src/test/modules/test_misc/Makefile new file mode 100644 index 00000000000..39c6c2014a0 --- /dev/null +++ b/src/test/modules/test_misc/Makefile @@ -0,0 +1,14 @@ +# src/test/modules/test_misc/Makefile + +TAP_TESTS = 1 + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_misc +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/test_misc/README b/src/test/modules/test_misc/README new file mode 100644 index 00000000000..4876733fa25 --- /dev/null +++ b/src/test/modules/test_misc/README @@ -0,0 +1,4 @@ +This directory doesn't actually contain any extension module. + +What it is is a home for otherwise-unclassified TAP tests that exercise core +server features. We might equally well have called it, say, src/test/misc. diff --git a/src/test/modules/test_misc/t/001_constraint_validation.pl b/src/test/modules/test_misc/t/001_constraint_validation.pl new file mode 100644 index 00000000000..f762bc21c19 --- /dev/null +++ b/src/test/modules/test_misc/t/001_constraint_validation.pl @@ -0,0 +1,310 @@ +# Verify that ALTER TABLE optimizes certain operations as expected + +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 42; + +# Initialize a test cluster +my $node = get_new_node('master'); +$node->init(); +# Turn message level up to DEBUG1 so that we get the messages we want to see +$node->append_conf('postgresql.conf', 'client_min_messages = DEBUG1'); +$node->start; + +# Run a SQL command and return psql's stderr (including debug messages) +sub run_sql_command +{ + my $sql = shift; + my $stderr; + + $node->psql( + 'postgres', + $sql, + stderr => \$stderr, + on_error_die => 1, + on_error_stop => 1); + return $stderr; +} + +# Check whether result of run_sql_command shows that we did a verify pass +sub is_table_verified +{ + my $output = shift; + return index($output, 'DEBUG: verifying table') != -1; +} + +my $output; + +note "test alter table set not null"; + +run_sql_command( + 'create table atacc1 (test_a int, test_b int); + insert into atacc1 values (1, 2);'); + +$output = run_sql_command('alter table atacc1 alter test_a set not null;'); +ok(is_table_verified($output), + 'column test_a without constraint will scan table'); + +run_sql_command( + 'alter table atacc1 alter test_a drop not null; + alter table atacc1 add constraint atacc1_constr_a_valid + check(test_a is not null);'); + +# normal run will verify table data +$output = run_sql_command('alter table atacc1 alter test_a set not null;'); +ok(!is_table_verified($output), 'with constraint will not scan table'); +ok( $output =~ + m/existing constraints on column "atacc1"."test_a" are sufficient to prove that it does not contain nulls/, + 'test_a proved by constraints'); + +run_sql_command('alter table atacc1 alter test_a drop not null;'); + +# we have check only for test_a column, so we need verify table for test_b +$output = run_sql_command( + 'alter table atacc1 alter test_b set not null, alter test_a set not null;' +); +ok(is_table_verified($output), 'table was scanned'); +# we may miss debug message for test_a constraint because we need verify table due test_b +ok( !( $output =~ + m/existing constraints on column "atacc1"."test_b" are sufficient to prove that it does not contain nulls/ + ), + 'test_b not proved by wrong constraints'); +run_sql_command( + 'alter table atacc1 alter test_a drop not null, alter test_b drop not null;' +); + +# test with both columns having check constraints +run_sql_command( + 'alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null);' +); +$output = run_sql_command( + 'alter table atacc1 alter test_b set not null, alter test_a set not null;' +); +ok(!is_table_verified($output), 'table was not scanned for both columns'); +ok( $output =~ + m/existing constraints on column "atacc1"."test_a" are sufficient to prove that it does not contain nulls/, + 'test_a proved by constraints'); +ok( $output =~ + m/existing constraints on column "atacc1"."test_b" are sufficient to prove that it does not contain nulls/, + 'test_b proved by constraints'); +run_sql_command('drop table atacc1;'); + +note "test alter table attach partition"; + +run_sql_command( + 'CREATE TABLE list_parted2 ( + a int, + b char + ) PARTITION BY LIST (a); + CREATE TABLE part_3_4 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IN (3)));'); + +# need NOT NULL to skip table scan +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4);' +); +ok(is_table_verified($output), 'table part_3_4 scanned'); + +run_sql_command( + 'ALTER TABLE list_parted2 DETACH PARTITION part_3_4; + ALTER TABLE part_3_4 ALTER a SET NOT NULL;'); + +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4);' +); +ok(!is_table_verified($output), 'table part_3_4 not scanned'); +ok( $output =~ + m/partition constraint for table "part_3_4" is implied by existing constraints/, + 'part_3_4 verified by existing constraints'); + +# test attach default partition +run_sql_command( + 'CREATE TABLE list_parted2_def ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IN (5, 6)));'); +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION list_parted2_def default;'); +ok(!is_table_verified($output), 'table list_parted2_def not scanned'); +ok( $output =~ + m/partition constraint for table "list_parted2_def" is implied by existing constraints/, + 'list_parted2_def verified by existing constraints'); + +$output = run_sql_command( + 'CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66);' +); +ok(!is_table_verified($output), 'table list_parted2_def not scanned'); +ok( $output =~ + m/updated partition constraint for default partition "list_parted2_def" is implied by existing constraints/, + 'updated partition constraint for default partition list_parted2_def'); + +# test attach another partitioned table +run_sql_command( + 'CREATE TABLE part_5 ( + LIKE list_parted2 + ) PARTITION BY LIST (b); + CREATE TABLE part_5_a PARTITION OF part_5 FOR VALUES IN (\'a\'); + ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5);' +); +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);'); +ok(!($output =~ m/verifying table "part_5"/), 'table part_5 not scanned'); +ok($output =~ m/verifying table "list_parted2_def"/, + 'list_parted2_def scanned'); +ok( $output =~ + m/partition constraint for table "part_5" is implied by existing constraints/, + 'part_5 verified by existing constraints'); + +run_sql_command( + 'ALTER TABLE list_parted2 DETACH PARTITION part_5; + ALTER TABLE part_5 DROP CONSTRAINT check_a;'); + +# scan should again be skipped, even though NOT NULL is now a column property +run_sql_command( + 'ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), + ALTER a SET NOT NULL;' +); +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5);'); +ok(!($output =~ m/verifying table "part_5"/), 'table part_5 not scanned'); +ok($output =~ m/verifying table "list_parted2_def"/, + 'list_parted2_def scanned'); +ok( $output =~ + m/partition constraint for table "part_5" is implied by existing constraints/, + 'part_5 verified by existing constraints'); + +# Check the case where attnos of the partitioning columns in the table being +# attached differs from the parent. It should not affect the constraint- +# checking logic that allows to skip the scan. +run_sql_command( + 'CREATE TABLE part_6 ( + c int, + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 6) + ); + ALTER TABLE part_6 DROP c;'); +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6);'); +ok(!($output =~ m/verifying table "part_6"/), 'table part_6 not scanned'); +ok($output =~ m/verifying table "list_parted2_def"/, + 'list_parted2_def scanned'); +ok( $output =~ + m/partition constraint for table "part_6" is implied by existing constraints/, + 'part_6 verified by existing constraints'); + +# Similar to above, but the table being attached is a partitioned table +# whose partition has still different attnos for the root partitioning +# columns. +run_sql_command( + 'CREATE TABLE part_7 ( + LIKE list_parted2, + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) + ) PARTITION BY LIST (b); + CREATE TABLE part_7_a_null ( + c int, + d int, + e int, + LIKE list_parted2, -- a will have attnum = 4 + CONSTRAINT check_b CHECK (b IS NULL OR b = \'a\'), + CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 7) + ); + ALTER TABLE part_7_a_null DROP c, DROP d, DROP e;'); + +$output = run_sql_command( + 'ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN (\'a\', null);' +); +ok(!is_table_verified($output), 'table not scanned'); +ok( $output =~ + m/partition constraint for table "part_7_a_null" is implied by existing constraints/, + 'part_7_a_null verified by existing constraints'); +$output = run_sql_command( + 'ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7);'); +ok(!is_table_verified($output), 'tables not scanned'); +ok( $output =~ + m/partition constraint for table "part_7" is implied by existing constraints/, + 'part_7 verified by existing constraints'); +ok( $output =~ + m/updated partition constraint for default partition "list_parted2_def" is implied by existing constraints/, + 'updated partition constraint for default partition list_parted2_def'); + +run_sql_command( + 'CREATE TABLE range_parted ( + a int, + b int + ) PARTITION BY RANGE (a, b); + CREATE TABLE range_part1 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL);'); + +$output = run_sql_command( + 'ALTER TABLE range_parted ATTACH PARTITION range_part1 FOR VALUES FROM (1, 1) TO (1, 10);' +); +ok(is_table_verified($output), 'table range_part1 scanned'); +ok( !( $output =~ + m/partition constraint for table "range_part1" is implied by existing constraints/ + ), + 'range_part1 not verified by existing constraints'); + +run_sql_command( + 'CREATE TABLE range_part2 ( + a int NOT NULL CHECK (a = 1), + b int NOT NULL CHECK (b >= 10 and b < 18) +);'); +$output = run_sql_command( + 'ALTER TABLE range_parted ATTACH PARTITION range_part2 FOR VALUES FROM (1, 10) TO (1, 20);' +); +ok(!is_table_verified($output), 'table range_part2 not scanned'); +ok( $output =~ + m/partition constraint for table "range_part2" is implied by existing constraints/, + 'range_part2 verified by existing constraints'); + +# If a partitioned table being created or an existing table being attached +# as a partition does not have a constraint that would allow validation scan +# to be skipped, but an individual partition does, then the partition's +# validation scan is skipped. +run_sql_command( + 'CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a); + CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b); + CREATE TABLE quuux_default1 PARTITION OF quuux_default ( + CONSTRAINT check_1 CHECK (a IS NOT NULL AND a = 1) + ) FOR VALUES IN (\'b\'); + CREATE TABLE quuux1 (a int, b text);'); + +$output = run_sql_command( + 'ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1);'); +ok(is_table_verified($output), 'quuux1 table scanned'); +ok( !( $output =~ + m/partition constraint for table "quuux1" is implied by existing constraints/ + ), + 'quuux1 verified by existing constraints'); + +run_sql_command('CREATE TABLE quuux2 (a int, b text);'); +$output = run_sql_command( + 'ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2);'); +ok(!($output =~ m/verifying table "quuux_default1"/), + 'quuux_default1 not scanned'); +ok($output =~ m/verifying table "quuux2"/, 'quuux2 scanned'); +ok( $output =~ + m/updated partition constraint for default partition "quuux_default1" is implied by existing constraints/, + 'updated partition constraint for default partition quuux_default1'); +run_sql_command('DROP TABLE quuux1, quuux2;'); + +# should validate for quuux1, but not for quuux2 +$output = run_sql_command( + 'CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1);'); +ok(!is_table_verified($output), 'tables not scanned'); +ok( !( $output =~ + m/partition constraint for table "quuux1" is implied by existing constraints/ + ), + 'quuux1 verified by existing constraints'); +$output = run_sql_command( + 'CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2);'); +ok(!is_table_verified($output), 'tables not scanned'); +ok( $output =~ + m/updated partition constraint for default partition "quuux_default1" is implied by existing constraints/, + 'updated partition constraint for default partition quuux_default1'); +run_sql_command('DROP TABLE quuux;'); + +$node->stop('fast'); diff --git a/src/test/modules/test_parser/test_parser.c b/src/test/modules/test_parser/test_parser.c index bb700f8a3d0..c505a775ab1 100644 --- a/src/test/modules/test_parser/test_parser.c +++ b/src/test/modules/test_parser/test_parser.c @@ -3,7 +3,7 @@ * test_parser.c * Simple example of a text search parser * - * Copyright (c) 2007-2018, PostgreSQL Global Development Group + * Copyright (c) 2007-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_parser/test_parser.c diff --git a/src/test/modules/test_pg_dump/Makefile b/src/test/modules/test_pg_dump/Makefile index c64b3537072..6123b994f60 100644 --- a/src/test/modules/test_pg_dump/Makefile +++ b/src/test/modules/test_pg_dump/Makefile @@ -7,6 +7,7 @@ EXTENSION = test_pg_dump DATA = test_pg_dump--1.0.sql REGRESS = test_pg_dump +TAP_TESTS = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -18,8 +19,3 @@ top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif - -check: prove-check - -prove-check: | temp-install - $(prove_check) diff --git a/src/test/modules/test_pg_dump/t/001_base.pl b/src/test/modules/test_pg_dump/t/001_base.pl index 2bc47878716..fb4ecf8acac 100644 --- a/src/test/modules/test_pg_dump/t/001_base.pl +++ b/src/test/modules/test_pg_dump/t/001_base.pl @@ -43,12 +43,16 @@ dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/binary_upgrade.sql", '--schema-only', - '--binary-upgrade', '--dbname=postgres', ], }, + '--binary-upgrade', '--dbname=postgres', + ], + }, clean => { dump_cmd => [ 'pg_dump', "--file=$tempdir/clean.sql", '-c', '--no-sync', - '--dbname=postgres', ], }, + '--dbname=postgres', + ], + }, clean_if_exists => { dump_cmd => [ 'pg_dump', @@ -57,23 +61,29 @@ '-c', '--if-exists', '--encoding=UTF8', # no-op, just tests that option is accepted - 'postgres', ], }, + 'postgres', + ], + }, createdb => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/createdb.sql", '-C', - '-R', # no-op, just for testing - 'postgres', ], }, + '-R', # no-op, just for testing + 'postgres', + ], + }, data_only => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/data_only.sql", '-a', - '-v', # no-op, just make sure it works - 'postgres', ], }, + '-v', # no-op, just make sure it works + 'postgres', + ], + }, defaults => { dump_cmd => [ 'pg_dump', '-f', "$tempdir/defaults.sql", 'postgres', ], }, @@ -81,70 +91,96 @@ test_key => 'defaults', dump_cmd => [ 'pg_dump', '--no-sync', '-Fc', '-Z6', - "--file=$tempdir/defaults_custom_format.dump", 'postgres', ], + "--file=$tempdir/defaults_custom_format.dump", 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/defaults_custom_format.sql", - "$tempdir/defaults_custom_format.dump", ], }, + "$tempdir/defaults_custom_format.dump", + ], + }, defaults_dir_format => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '--no-sync', '-Fd', - "--file=$tempdir/defaults_dir_format", 'postgres', ], + "--file=$tempdir/defaults_dir_format", 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/defaults_dir_format.sql", - "$tempdir/defaults_dir_format", ], }, + "$tempdir/defaults_dir_format", + ], + }, defaults_parallel => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '--no-sync', '-Fd', '-j2', - "--file=$tempdir/defaults_parallel", 'postgres', ], + "--file=$tempdir/defaults_parallel", 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/defaults_parallel.sql", - "$tempdir/defaults_parallel", ], }, + "$tempdir/defaults_parallel", + ], + }, defaults_tar_format => { test_key => 'defaults', dump_cmd => [ 'pg_dump', '--no-sync', '-Ft', - "--file=$tempdir/defaults_tar_format.tar", 'postgres', ], + "--file=$tempdir/defaults_tar_format.tar", 'postgres', + ], restore_cmd => [ 'pg_restore', "--file=$tempdir/defaults_tar_format.sql", - "$tempdir/defaults_tar_format.tar", ], }, + "$tempdir/defaults_tar_format.tar", + ], + }, pg_dumpall_globals => { dump_cmd => [ 'pg_dumpall', '--no-sync', - "--file=$tempdir/pg_dumpall_globals.sql", '-g', ], }, + "--file=$tempdir/pg_dumpall_globals.sql", '-g', + ], + }, no_privs => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/no_privs.sql", '-x', - 'postgres', ], }, + 'postgres', + ], + }, no_owner => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/no_owner.sql", '-O', - 'postgres', ], }, + 'postgres', + ], + }, schema_only => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/schema_only.sql", - '-s', 'postgres', ], }, + '-s', 'postgres', + ], + }, section_pre_data => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/section_pre_data.sql", '--section=pre-data', - 'postgres', ], }, + 'postgres', + ], + }, section_data => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/section_data.sql", '--section=data', - 'postgres', ], }, + 'postgres', + ], + }, section_post_data => { dump_cmd => [ 'pg_dump', '--no-sync', "--file=$tempdir/section_post_data.sql", - '--section=post-data', 'postgres', ], },); + '--section=post-data', 'postgres', + ], + },); ############################################################### # Definition of the tests to run. @@ -178,26 +214,26 @@ # Tests which are considered 'full' dumps by pg_dump, but there # are flags used to exclude specific items (ACLs, blobs, etc). my %full_runs = ( - binary_upgrade => 1, - clean => 1, - clean_if_exists => 1, - createdb => 1, - defaults => 1, - no_privs => 1, - no_owner => 1, -); + binary_upgrade => 1, + clean => 1, + clean_if_exists => 1, + createdb => 1, + defaults => 1, + no_privs => 1, + no_owner => 1,); my %tests = ( 'ALTER EXTENSION test_pg_dump' => { create_order => 9, create_sql => -'ALTER EXTENSION test_pg_dump ADD TABLE regress_pg_dump_table_added;', + 'ALTER EXTENSION test_pg_dump ADD TABLE regress_pg_dump_table_added;', regexp => qr/^ \QCREATE TABLE public.regress_pg_dump_table_added (\E \n\s+\Qcol1 integer NOT NULL,\E \n\s+\Qcol2 integer\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE EXTENSION test_pg_dump' => { create_order => 2, @@ -207,16 +243,18 @@ \n/xm, like => { %full_runs, - schema_only => 1, - section_pre_data => 1, }, - unlike => { - binary_upgrade => 1, }, }, + schema_only => 1, + section_pre_data => 1, + }, + unlike => { binary_upgrade => 1, }, + }, 'CREATE ROLE regress_dump_test_role' => { create_order => 1, create_sql => 'CREATE ROLE regress_dump_test_role;', regexp => qr/^CREATE ROLE regress_dump_test_role;\n/m, - like => { pg_dumpall_globals => 1, }, }, + like => { pg_dumpall_globals => 1, }, + }, 'CREATE SEQUENCE regress_pg_dump_table_col1_seq' => { regexp => qr/^ @@ -228,18 +266,20 @@ \n\s+\QNO MAXVALUE\E \n\s+\QCACHE 1;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE TABLE regress_pg_dump_table_added' => { create_order => 7, create_sql => -'CREATE TABLE regress_pg_dump_table_added (col1 int not null, col2 int);', + 'CREATE TABLE regress_pg_dump_table_added (col1 int not null, col2 int);', regexp => qr/^ \QCREATE TABLE public.regress_pg_dump_table_added (\E \n\s+\Qcol1 integer NOT NULL,\E \n\s+\Qcol2 integer\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE SEQUENCE regress_pg_dump_seq' => { regexp => qr/^ @@ -250,7 +290,8 @@ \n\s+\QNO MAXVALUE\E \n\s+\QCACHE 1;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'SETVAL SEQUENCE regress_seq_dumpable' => { create_order => 6, @@ -260,8 +301,10 @@ \n/xm, like => { %full_runs, - data_only => 1, - section_data => 1, }, }, + data_only => 1, + section_data => 1, + }, + }, 'CREATE TABLE regress_pg_dump_table' => { regexp => qr/^ @@ -269,13 +312,15 @@ \n\s+\Qcol1 integer NOT NULL,\E \n\s+\Qcol2 integer\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE ACCESS METHOD regress_test_am' => { regexp => qr/^ \QCREATE ACCESS METHOD regress_test_am TYPE INDEX HANDLER bthandler;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'COMMENT ON EXTENSION test_pg_dump' => { regexp => qr/^ @@ -285,30 +330,34 @@ like => { %full_runs, schema_only => 1, - section_pre_data => 1, }, }, + section_pre_data => 1, + }, + }, 'GRANT SELECT regress_pg_dump_table_added pre-ALTER EXTENSION' => { create_order => 8, create_sql => -'GRANT SELECT ON regress_pg_dump_table_added TO regress_dump_test_role;', + 'GRANT SELECT ON regress_pg_dump_table_added TO regress_dump_test_role;', regexp => qr/^ \QGRANT SELECT ON TABLE public.regress_pg_dump_table_added TO regress_dump_test_role;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'REVOKE SELECT regress_pg_dump_table_added post-ALTER EXTENSION' => { create_order => 10, create_sql => -'REVOKE SELECT ON regress_pg_dump_table_added FROM regress_dump_test_role;', + 'REVOKE SELECT ON regress_pg_dump_table_added FROM regress_dump_test_role;', regexp => qr/^ \QREVOKE SELECT ON TABLE public.regress_pg_dump_table_added FROM regress_dump_test_role;\E \n/xm, like => { %full_runs, schema_only => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, 'GRANT SELECT ON TABLE regress_pg_dump_table' => { regexp => qr/^ @@ -316,7 +365,8 @@ \QGRANT SELECT ON TABLE public.regress_pg_dump_table TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT SELECT(col1) ON regress_pg_dump_table' => { regexp => qr/^ @@ -324,10 +374,12 @@ \QGRANT SELECT(col1) ON TABLE public.regress_pg_dump_table TO PUBLIC;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, - 'GRANT SELECT(col2) ON regress_pg_dump_table TO regress_dump_test_role' => - { create_order => 4, + 'GRANT SELECT(col2) ON regress_pg_dump_table TO regress_dump_test_role' + => { + create_order => 4, create_sql => 'GRANT SELECT(col2) ON regress_pg_dump_table TO regress_dump_test_role;', regexp => qr/^ @@ -336,9 +388,10 @@ like => { %full_runs, schema_only => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON regress_pg_dump_table_col1_seq TO regress_dump_test_role' => { @@ -351,15 +404,17 @@ like => { %full_runs, schema_only => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, 'GRANT USAGE ON regress_pg_dump_seq TO regress_dump_test_role' => { regexp => qr/^ \QGRANT USAGE ON SEQUENCE public.regress_pg_dump_seq TO regress_dump_test_role;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'REVOKE SELECT(col1) ON regress_pg_dump_table' => { create_order => 3, @@ -371,18 +426,20 @@ like => { %full_runs, schema_only => 1, - section_pre_data => 1, }, - unlike => { - no_privs => 1, }, }, + section_pre_data => 1, + }, + unlike => { no_privs => 1, }, + }, - # Objects included in extension part of a schema created by this extension */ + # Objects included in extension part of a schema created by this extension */ 'CREATE TABLE regress_pg_dump_schema.test_table' => { regexp => qr/^ \QCREATE TABLE regress_pg_dump_schema.test_table (\E \n\s+\Qcol1 integer,\E \n\s+\Qcol2 integer\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT SELECT ON regress_pg_dump_schema.test_table' => { regexp => qr/^ @@ -390,7 +447,8 @@ \QGRANT SELECT ON TABLE regress_pg_dump_schema.test_table TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE SEQUENCE regress_pg_dump_schema.test_seq' => { regexp => qr/^ @@ -401,7 +459,8 @@ \n\s+\QNO MAXVALUE\E \n\s+\QCACHE 1;\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT USAGE ON regress_pg_dump_schema.test_seq' => { regexp => qr/^ @@ -409,14 +468,16 @@ \QGRANT USAGE ON SEQUENCE regress_pg_dump_schema.test_seq TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE TYPE regress_pg_dump_schema.test_type' => { regexp => qr/^ \QCREATE TYPE regress_pg_dump_schema.test_type AS (\E \n\s+\Qcol1 integer\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT USAGE ON regress_pg_dump_schema.test_type' => { regexp => qr/^ @@ -424,14 +485,16 @@ \QGRANT ALL ON TYPE regress_pg_dump_schema.test_type TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE FUNCTION regress_pg_dump_schema.test_func' => { regexp => qr/^ \QCREATE FUNCTION regress_pg_dump_schema.test_func() RETURNS integer\E \n\s+\QLANGUAGE sql\E \n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT ALL ON regress_pg_dump_schema.test_func' => { regexp => qr/^ @@ -439,7 +502,8 @@ \QGRANT ALL ON FUNCTION regress_pg_dump_schema.test_func() TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'CREATE AGGREGATE regress_pg_dump_schema.test_agg' => { regexp => qr/^ @@ -447,7 +511,8 @@ \n\s+\QSFUNC = int2_sum,\E \n\s+\QSTYPE = bigint\E \n\);\n/xm, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, 'GRANT ALL ON regress_pg_dump_schema.test_agg' => { regexp => qr/^ @@ -455,7 +520,8 @@ \QGRANT ALL ON FUNCTION regress_pg_dump_schema.test_agg(smallint) TO regress_dump_test_role;\E\n \QSELECT pg_catalog.binary_upgrade_set_record_init_privs(false);\E \n/xms, - like => { binary_upgrade => 1, }, }, + like => { binary_upgrade => 1, }, + }, # Objects not included in extension, part of schema created by extension 'CREATE TABLE regress_pg_dump_schema.external_tab' => { @@ -468,9 +534,10 @@ \n\);\n/xm, like => { %full_runs, - schema_only => 1, - section_pre_data => 1, }, }, -); + schema_only => 1, + section_pre_data => 1, + }, + },); ######################################### # Create a PG instance to test actually dumping from @@ -505,7 +572,8 @@ foreach my $test (sort keys %tests) { # If there is a like entry, but no unlike entry, then we will test the like case - if ($tests{$test}->{like}->{$test_key} && !defined($tests{$test}->{unlike}->{$test_key})) + if ($tests{$test}->{like}->{$test_key} + && !defined($tests{$test}->{unlike}->{$test_key})) { $num_tests++; } @@ -585,18 +653,18 @@ { # Run the test listed as a like, unless it is specifically noted # as an unlike (generally due to an explicit exclusion or similar). - if ($tests{$test}->{like}->{$test_key} && !defined($tests{$test}->{unlike}->{$test_key})) + if ($tests{$test}->{like}->{$test_key} + && !defined($tests{$test}->{unlike}->{$test_key})) { - if (!ok($output_file =~ $tests{$test}->{regexp}, "$run: should dump $test")) + if (!ok($output_file =~ $tests{$test}->{regexp}, + "$run: should dump $test")) { diag("Review $run results in $tempdir"); } } else { - if (!ok( - $output_file !~ - $tests{$test}->{regexp}, + if (!ok($output_file !~ $tests{$test}->{regexp}, "$run: should not dump $test")) { diag("Review $run results in $tempdir"); diff --git a/src/test/modules/test_predtest/expected/test_predtest.out b/src/test/modules/test_predtest/expected/test_predtest.out index 5574e03204f..6d21bcd603e 100644 --- a/src/test/modules/test_predtest/expected/test_predtest.out +++ b/src/test/modules/test_predtest/expected/test_predtest.out @@ -19,6 +19,9 @@ from generate_series(0, 11*11-1) i; -- and a simple strict function that's opaque to the optimizer create function strictf(bool, bool) returns bool language plpgsql as $$begin return $1 and not $2; end$$ strict; +-- a simple function to make arrays opaque to the optimizer +create function opaque_array(int[]) returns int[] +language plpgsql as $$begin return $1; end$$ strict; -- Basic proof rules for single boolean variables select * from test_predtest($$ select x, x @@ -837,3 +840,257 @@ w_i_holds | f s_r_holds | f w_r_holds | f +-- In these tests, we want to prevent predtest.c from breaking down the +-- ScalarArrayOpExpr into an AND/OR tree, so as to exercise the logic +-- that handles ScalarArrayOpExpr directly. We use opaque_array() if +-- possible, otherwise an array longer than MAX_SAOP_ARRAY_SIZE. +-- ScalarArrayOpExpr implies scalar IS NOT NULL +select * from test_predtest($$ +select x is not null, x = any(opaque_array(array[1])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | t +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | t +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- but for ALL, we have to be able to prove the array nonempty +select * from test_predtest($$ +select x is not null, x <> all(opaque_array(array[1])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | t +w_i_holds | f +s_r_holds | f +w_r_holds | f + +select * from test_predtest($$ +select x is not null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101 +]) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | t +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | t +w_i_holds | f +s_r_holds | f +w_r_holds | f + +select * from test_predtest($$ +select x is not null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,y +]) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | t +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | t +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- check empty-array cases +select * from test_predtest($$ +select x is not null, x = any(opaque_array(array[]::int[])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | t +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | t +w_i_holds | t +s_r_holds | t +w_r_holds | t + +select * from test_predtest($$ +select x is not null, x <> all(opaque_array(array[]::int[])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- same thing under a strict function doesn't prove it +select * from test_predtest($$ +select x is not null, strictf(true, x = any(opaque_array(array[]::int[]))) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- ScalarArrayOpExpr refutes scalar IS NULL +select * from test_predtest($$ +select x is null, x = any(opaque_array(array[1])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | t +weak_refuted_by | t +s_i_holds | f +w_i_holds | f +s_r_holds | t +w_r_holds | t + +-- but for ALL, we have to be able to prove the array nonempty +select * from test_predtest($$ +select x is null, x <> all(opaque_array(array[1])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | f +s_r_holds | t +w_r_holds | t + +select * from test_predtest($$ +select x is null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101 +]) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | t +weak_refuted_by | t +s_i_holds | f +w_i_holds | f +s_r_holds | t +w_r_holds | t + +-- check empty-array cases +select * from test_predtest($$ +select x is null, x = any(opaque_array(array[]::int[])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | t +weak_refuted_by | t +s_i_holds | t +w_i_holds | t +s_r_holds | t +w_r_holds | t + +select * from test_predtest($$ +select x is null, x <> all(opaque_array(array[]::int[])) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- same thing under a strict function doesn't prove it +select * from test_predtest($$ +select x is null, strictf(true, x = any(opaque_array(array[]::int[]))) +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | f +s_r_holds | f +w_r_holds | f + +-- Also, nullness of the scalar weakly refutes a SAOP +select * from test_predtest($$ +select x = any(opaque_array(array[1])), x is null +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | t +s_i_holds | f +w_i_holds | t +s_r_holds | f +w_r_holds | t + +-- as does nullness of the array +select * from test_predtest($$ +select x = any(opaque_array(array[y])), array[y] is null +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | t +s_i_holds | t +w_i_holds | t +s_r_holds | t +w_r_holds | t + +-- ... unless we need to prove array empty +select * from test_predtest($$ +select x = all(opaque_array(array[1])), x is null +from integers +$$); +-[ RECORD 1 ]-----+-- +strong_implied_by | f +weak_implied_by | f +strong_refuted_by | f +weak_refuted_by | f +s_i_holds | f +w_i_holds | t +s_r_holds | f +w_r_holds | t + diff --git a/src/test/modules/test_predtest/sql/test_predtest.sql b/src/test/modules/test_predtest/sql/test_predtest.sql index 27347358439..072eb5b0d50 100644 --- a/src/test/modules/test_predtest/sql/test_predtest.sql +++ b/src/test/modules/test_predtest/sql/test_predtest.sql @@ -25,6 +25,10 @@ from generate_series(0, 11*11-1) i; create function strictf(bool, bool) returns bool language plpgsql as $$begin return $1 and not $2; end$$ strict; +-- a simple function to make arrays opaque to the optimizer +create function opaque_array(int[]) returns int[] +language plpgsql as $$begin return $1; end$$ strict; + -- Basic proof rules for single boolean variables select * from test_predtest($$ @@ -325,3 +329,114 @@ select * from test_predtest($$ select x <= y, x = any(array[1,3,y]) from integers $$); + +-- In these tests, we want to prevent predtest.c from breaking down the +-- ScalarArrayOpExpr into an AND/OR tree, so as to exercise the logic +-- that handles ScalarArrayOpExpr directly. We use opaque_array() if +-- possible, otherwise an array longer than MAX_SAOP_ARRAY_SIZE. + +-- ScalarArrayOpExpr implies scalar IS NOT NULL +select * from test_predtest($$ +select x is not null, x = any(opaque_array(array[1])) +from integers +$$); + +-- but for ALL, we have to be able to prove the array nonempty +select * from test_predtest($$ +select x is not null, x <> all(opaque_array(array[1])) +from integers +$$); + +select * from test_predtest($$ +select x is not null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101 +]) +from integers +$$); + +select * from test_predtest($$ +select x is not null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,y +]) +from integers +$$); + +-- check empty-array cases +select * from test_predtest($$ +select x is not null, x = any(opaque_array(array[]::int[])) +from integers +$$); + +select * from test_predtest($$ +select x is not null, x <> all(opaque_array(array[]::int[])) +from integers +$$); + +-- same thing under a strict function doesn't prove it +select * from test_predtest($$ +select x is not null, strictf(true, x = any(opaque_array(array[]::int[]))) +from integers +$$); + +-- ScalarArrayOpExpr refutes scalar IS NULL +select * from test_predtest($$ +select x is null, x = any(opaque_array(array[1])) +from integers +$$); + +-- but for ALL, we have to be able to prove the array nonempty +select * from test_predtest($$ +select x is null, x <> all(opaque_array(array[1])) +from integers +$$); + +select * from test_predtest($$ +select x is null, x <> all(array[ + 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28, + 29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78, + 79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101 +]) +from integers +$$); + +-- check empty-array cases +select * from test_predtest($$ +select x is null, x = any(opaque_array(array[]::int[])) +from integers +$$); + +select * from test_predtest($$ +select x is null, x <> all(opaque_array(array[]::int[])) +from integers +$$); + +-- same thing under a strict function doesn't prove it +select * from test_predtest($$ +select x is null, strictf(true, x = any(opaque_array(array[]::int[]))) +from integers +$$); + +-- Also, nullness of the scalar weakly refutes a SAOP +select * from test_predtest($$ +select x = any(opaque_array(array[1])), x is null +from integers +$$); + +-- as does nullness of the array +select * from test_predtest($$ +select x = any(opaque_array(array[y])), array[y] is null +from integers +$$); + +-- ... unless we need to prove array empty +select * from test_predtest($$ +select x = all(opaque_array(array[1])), x is null +from integers +$$); diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c index 51320ade2e5..10cd4f9ae5a 100644 --- a/src/test/modules/test_predtest/test_predtest.c +++ b/src/test/modules/test_predtest/test_predtest.c @@ -3,7 +3,7 @@ * test_predtest.c * Test correctness of optimizer's predicate proof logic. * - * Copyright (c) 2018, PostgreSQL Global Development Group + * Copyright (c) 2018-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_predtest/test_predtest.c @@ -17,8 +17,8 @@ #include "catalog/pg_type.h" #include "executor/spi.h" #include "funcapi.h" -#include "optimizer/clauses.h" -#include "optimizer/predtest.h" +#include "nodes/makefuncs.h" +#include "optimizer/optimizer.h" #include "utils/builtins.h" PG_MODULE_MAGIC; @@ -185,7 +185,7 @@ test_predtest(PG_FUNCTION_ARGS) if (SPI_finish() != SPI_OK_FINISH) elog(ERROR, "SPI_finish failed"); - tupdesc = CreateTemplateTupleDesc(8, false); + tupdesc = CreateTemplateTupleDesc(8); TupleDescInitEntry(tupdesc, (AttrNumber) 1, "strong_implied_by", BOOLOID, -1, 0); TupleDescInitEntry(tupdesc, (AttrNumber) 2, diff --git a/src/test/modules/test_rbtree/test_rbtree.c b/src/test/modules/test_rbtree/test_rbtree.c index 1274b9995d8..2a18c267861 100644 --- a/src/test/modules/test_rbtree/test_rbtree.c +++ b/src/test/modules/test_rbtree/test_rbtree.c @@ -3,7 +3,7 @@ * test_rbtree.c * Test correctness of red-black tree operations. * - * Copyright (c) 2009-2018, PostgreSQL Global Development Group + * Copyright (c) 2009-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_rbtree/test_rbtree.c @@ -25,7 +25,7 @@ PG_MODULE_MAGIC; */ typedef struct IntRBTreeNode { - RBNode rbnode; + RBTNode rbtnode; int key; } IntRBTreeNode; @@ -35,7 +35,7 @@ typedef struct IntRBTreeNode * since none of our test keys are negative. */ static int -irb_cmp(const RBNode *a, const RBNode *b, void *arg) +irbt_cmp(const RBTNode *a, const RBTNode *b, void *arg) { const IntRBTreeNode *ea = (const IntRBTreeNode *) a; const IntRBTreeNode *eb = (const IntRBTreeNode *) b; @@ -48,7 +48,7 @@ irb_cmp(const RBNode *a, const RBNode *b, void *arg) * try to combine unequal keys. */ static void -irb_combine(RBNode *existing, const RBNode *newdata, void *arg) +irbt_combine(RBTNode *existing, const RBTNode *newdata, void *arg) { const IntRBTreeNode *eexist = (const IntRBTreeNode *) existing; const IntRBTreeNode *enew = (const IntRBTreeNode *) newdata; @@ -59,15 +59,15 @@ irb_combine(RBNode *existing, const RBNode *newdata, void *arg) } /* Node allocator */ -static RBNode * -irb_alloc(void *arg) +static RBTNode * +irbt_alloc(void *arg) { - return (RBNode *) palloc(sizeof(IntRBTreeNode)); + return (RBTNode *) palloc(sizeof(IntRBTreeNode)); } /* Node freer */ static void -irb_free(RBNode *node, void *arg) +irbt_free(RBTNode *node, void *arg) { pfree(node); } @@ -78,12 +78,12 @@ irb_free(RBNode *node, void *arg) static RBTree * create_int_rbtree(void) { - return rb_create(sizeof(IntRBTreeNode), - irb_cmp, - irb_combine, - irb_alloc, - irb_free, - NULL); + return rbt_create(sizeof(IntRBTreeNode), + irbt_cmp, + irbt_combine, + irbt_alloc, + irbt_free, + NULL); } /* @@ -123,7 +123,7 @@ GetPermutation(int size) * 0, step, 2*step, 3*step, ..., inserting them in random order */ static void -rb_populate(RBTree *tree, int size, int step) +rbt_populate(RBTree *tree, int size, int step) { int *permutation = GetPermutation(size); IntRBTreeNode node; @@ -134,9 +134,9 @@ rb_populate(RBTree *tree, int size, int step) for (i = 0; i < size; i++) { node.key = step * permutation[i]; - rb_insert(tree, (RBNode *) &node, &isNew); + rbt_insert(tree, (RBTNode *) &node, &isNew); if (!isNew) - elog(ERROR, "unexpected !isNew result from rb_insert"); + elog(ERROR, "unexpected !isNew result from rbt_insert"); } /* @@ -146,9 +146,9 @@ rb_populate(RBTree *tree, int size, int step) if (size > 0) { node.key = step * permutation[0]; - rb_insert(tree, (RBNode *) &node, &isNew); + rbt_insert(tree, (RBTNode *) &node, &isNew); if (isNew) - elog(ERROR, "unexpected isNew result from rb_insert"); + elog(ERROR, "unexpected isNew result from rbt_insert"); } pfree(permutation); @@ -169,17 +169,17 @@ testleftright(int size) int count = 0; /* check iteration over empty tree */ - rb_begin_iterate(tree, LeftRightWalk, &iter); - if (rb_iterate(&iter) != NULL) + rbt_begin_iterate(tree, LeftRightWalk, &iter); + if (rbt_iterate(&iter) != NULL) elog(ERROR, "left-right walk over empty tree produced an element"); /* fill tree with consecutive natural numbers */ - rb_populate(tree, size, 1); + rbt_populate(tree, size, 1); /* iterate over the tree */ - rb_begin_iterate(tree, LeftRightWalk, &iter); + rbt_begin_iterate(tree, LeftRightWalk, &iter); - while ((node = (IntRBTreeNode *) rb_iterate(&iter)) != NULL) + while ((node = (IntRBTreeNode *) rbt_iterate(&iter)) != NULL) { /* check that order is increasing */ if (node->key <= lastKey) @@ -209,17 +209,17 @@ testrightleft(int size) int count = 0; /* check iteration over empty tree */ - rb_begin_iterate(tree, RightLeftWalk, &iter); - if (rb_iterate(&iter) != NULL) + rbt_begin_iterate(tree, RightLeftWalk, &iter); + if (rbt_iterate(&iter) != NULL) elog(ERROR, "right-left walk over empty tree produced an element"); /* fill tree with consecutive natural numbers */ - rb_populate(tree, size, 1); + rbt_populate(tree, size, 1); /* iterate over the tree */ - rb_begin_iterate(tree, RightLeftWalk, &iter); + rbt_begin_iterate(tree, RightLeftWalk, &iter); - while ((node = (IntRBTreeNode *) rb_iterate(&iter)) != NULL) + while ((node = (IntRBTreeNode *) rbt_iterate(&iter)) != NULL) { /* check that order is decreasing */ if (node->key >= lastKey) @@ -235,7 +235,7 @@ testrightleft(int size) } /* - * Check the correctness of the rb_find operation by searching for + * Check the correctness of the rbt_find operation by searching for * both elements we inserted and elements we didn't. */ static void @@ -245,7 +245,7 @@ testfind(int size) int i; /* Insert even integers from 0 to 2 * (size-1) */ - rb_populate(tree, size, 2); + rbt_populate(tree, size, 2); /* Check that all inserted elements can be found */ for (i = 0; i < size; i++) @@ -254,7 +254,7 @@ testfind(int size) IntRBTreeNode *resultNode; node.key = 2 * i; - resultNode = (IntRBTreeNode *) rb_find(tree, (RBNode *) &node); + resultNode = (IntRBTreeNode *) rbt_find(tree, (RBTNode *) &node); if (resultNode == NULL) elog(ERROR, "inserted element was not found"); if (node.key != resultNode->key) @@ -271,14 +271,14 @@ testfind(int size) IntRBTreeNode *resultNode; node.key = i; - resultNode = (IntRBTreeNode *) rb_find(tree, (RBNode *) &node); + resultNode = (IntRBTreeNode *) rbt_find(tree, (RBTNode *) &node); if (resultNode != NULL) elog(ERROR, "not-inserted element was found"); } } /* - * Check the correctness of the rb_leftmost operation. + * Check the correctness of the rbt_leftmost operation. * This operation should always return the smallest element of the tree. */ static void @@ -288,20 +288,20 @@ testleftmost(int size) IntRBTreeNode *result; /* Check that empty tree has no leftmost element */ - if (rb_leftmost(tree) != NULL) + if (rbt_leftmost(tree) != NULL) elog(ERROR, "leftmost node of empty tree is not NULL"); /* fill tree with consecutive natural numbers */ - rb_populate(tree, size, 1); + rbt_populate(tree, size, 1); /* Check that leftmost element is the smallest one */ - result = (IntRBTreeNode *) rb_leftmost(tree); + result = (IntRBTreeNode *) rbt_leftmost(tree); if (result == NULL || result->key != 0) - elog(ERROR, "rb_leftmost gave wrong result"); + elog(ERROR, "rbt_leftmost gave wrong result"); } /* - * Check the correctness of the rb_delete operation. + * Check the correctness of the rbt_delete operation. */ static void testdelete(int size, int delsize) @@ -312,7 +312,7 @@ testdelete(int size, int delsize) int i; /* fill tree with consecutive natural numbers */ - rb_populate(tree, size, 1); + rbt_populate(tree, size, 1); /* Choose unique ids to delete */ deleteIds = (int *) palloc(delsize * sizeof(int)); @@ -336,11 +336,11 @@ testdelete(int size, int delsize) find.key = deleteIds[i]; /* Locate the node to be deleted */ - node = (IntRBTreeNode *) rb_find(tree, (RBNode *) &find); + node = (IntRBTreeNode *) rbt_find(tree, (RBTNode *) &find); if (node == NULL || node->key != deleteIds[i]) elog(ERROR, "expected element was not found during deleting"); /* Delete it */ - rb_delete(tree, (RBNode *) node); + rbt_delete(tree, (RBTNode *) node); } /* Check that deleted elements are deleted */ @@ -350,7 +350,7 @@ testdelete(int size, int delsize) IntRBTreeNode *result; node.key = i; - result = (IntRBTreeNode *) rb_find(tree, (RBNode *) &node); + result = (IntRBTreeNode *) rbt_find(tree, (RBTNode *) &node); if (chosen[i]) { /* Deleted element should be absent */ @@ -375,15 +375,15 @@ testdelete(int size, int delsize) continue; find.key = i; /* Locate the node to be deleted */ - node = (IntRBTreeNode *) rb_find(tree, (RBNode *) &find); + node = (IntRBTreeNode *) rbt_find(tree, (RBTNode *) &find); if (node == NULL || node->key != i) elog(ERROR, "expected element was not found during deleting"); /* Delete it */ - rb_delete(tree, (RBNode *) node); + rbt_delete(tree, (RBTNode *) node); } /* Tree should now be empty */ - if (rb_leftmost(tree) != NULL) + if (rbt_leftmost(tree) != NULL) elog(ERROR, "deleting all elements failed"); pfree(deleteIds); diff --git a/src/test/modules/test_rls_hooks/Makefile b/src/test/modules/test_rls_hooks/Makefile index 6b772c4db12..284fdaf0958 100644 --- a/src/test/modules/test_rls_hooks/Makefile +++ b/src/test/modules/test_rls_hooks/Makefile @@ -9,6 +9,9 @@ EXTENSION = test_rls_hooks REGRESS = test_rls_hooks REGRESS_OPTS = --temp-config=$(top_srcdir)/src/test/modules/test_rls_hooks/rls_hooks.conf +# Disabled because these tests require "shared_preload_libraries=test_rls_hooks", +# which typical installcheck users do not have (e.g. buildfarm clients). +NO_INSTALLCHECK = 1 ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/src/test/modules/test_rls_hooks/README b/src/test/modules/test_rls_hooks/README index b61dace572f..c22e0d3fb43 100644 --- a/src/test/modules/test_rls_hooks/README +++ b/src/test/modules/test_rls_hooks/README @@ -3,13 +3,13 @@ define additional policies to be used. Functions ========= -test_rls_hook_permissive(CmdType cmdtype, Relation relation) +test_rls_hooks_permissive(CmdType cmdtype, Relation relation) RETURNS List* Returns a list of policies which should be added to any existing policies on the relation, combined with OR. -test_rls_hook_restrictive(CmdType cmdtype, Relation relation) +test_rls_hooks_restrictive(CmdType cmdtype, Relation relation) RETURNS List* Returns a list of policies which should be added to any existing diff --git a/src/test/modules/test_rls_hooks/test_rls_hooks.c b/src/test/modules/test_rls_hooks/test_rls_hooks.c index cab67a60aa9..10379bc59c0 100644 --- a/src/test/modules/test_rls_hooks/test_rls_hooks.c +++ b/src/test/modules/test_rls_hooks/test_rls_hooks.c @@ -3,7 +3,7 @@ * test_rls_hooks.c * Code for testing RLS hooks. * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_rls_hooks/test_rls_hooks.c @@ -22,6 +22,7 @@ #include "nodes/makefuncs.h" #include "nodes/makefuncs.h" #include "parser/parse_clause.h" +#include "parser/parse_collate.h" #include "parser/parse_node.h" #include "parser/parse_relation.h" #include "rewrite/rowsecurity.h" @@ -74,14 +75,14 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation) ParseState *qual_pstate; RangeTblEntry *rte; - if (strcmp(RelationGetRelationName(relation), "rls_test_permissive") - && strcmp(RelationGetRelationName(relation), "rls_test_both")) + if (strcmp(RelationGetRelationName(relation), "rls_test_permissive") != 0 && + strcmp(RelationGetRelationName(relation), "rls_test_both") != 0) return NIL; qual_pstate = make_parsestate(NULL); - rte = addRangeTableEntryForRelation(qual_pstate, relation, NULL, false, - false); + rte = addRangeTableEntryForRelation(qual_pstate, relation, AccessShareLock, + NULL, false, false); addRTEtoQuery(qual_pstate, rte, false, true, true); role = ObjectIdGetDatum(ACL_ID_PUBLIC); @@ -107,6 +108,8 @@ test_rls_hooks_permissive(CmdType cmdtype, Relation relation) policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e), EXPR_KIND_POLICY, "POLICY"); + /* Fix up collation information */ + assign_expr_collations(qual_pstate, (Node *) policy->qual); policy->with_check_qual = copyObject(policy->qual); policy->hassublinks = false; @@ -137,14 +140,14 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation) RangeTblEntry *rte; - if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive") - && strcmp(RelationGetRelationName(relation), "rls_test_both")) + if (strcmp(RelationGetRelationName(relation), "rls_test_restrictive") != 0 && + strcmp(RelationGetRelationName(relation), "rls_test_both") != 0) return NIL; qual_pstate = make_parsestate(NULL); - rte = addRangeTableEntryForRelation(qual_pstate, relation, NULL, false, - false); + rte = addRangeTableEntryForRelation(qual_pstate, relation, AccessShareLock, + NULL, false, false); addRTEtoQuery(qual_pstate, rte, false, true, true); role = ObjectIdGetDatum(ACL_ID_PUBLIC); @@ -165,6 +168,8 @@ test_rls_hooks_restrictive(CmdType cmdtype, Relation relation) policy->qual = (Expr *) transformWhereClause(qual_pstate, copyObject(e), EXPR_KIND_POLICY, "POLICY"); + /* Fix up collation information */ + assign_expr_collations(qual_pstate, (Node *) policy->qual); policy->with_check_qual = copyObject(policy->qual); policy->hassublinks = false; diff --git a/src/test/modules/test_rls_hooks/test_rls_hooks.h b/src/test/modules/test_rls_hooks/test_rls_hooks.h index 774c64ff432..d9894a3fc54 100644 --- a/src/test/modules/test_rls_hooks/test_rls_hooks.h +++ b/src/test/modules/test_rls_hooks/test_rls_hooks.h @@ -3,7 +3,7 @@ * test_rls_hooks.h * Definitions for RLS hooks * - * Copyright (c) 2015-2018, PostgreSQL Global Development Group + * Copyright (c) 2015-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_rls_hooks/test_rls_hooks.h diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c index 97e8617b3e9..a3181685f69 100644 --- a/src/test/modules/test_shm_mq/setup.c +++ b/src/test/modules/test_shm_mq/setup.c @@ -5,7 +5,7 @@ * number of background workers for shared memory message queue * testing. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_shm_mq/setup.c @@ -31,14 +31,14 @@ typedef struct } worker_state; static void setup_dynamic_shared_memory(int64 queue_size, int nworkers, - dsm_segment **segp, - test_shm_mq_header **hdrp, - shm_mq **outp, shm_mq **inp); + dsm_segment **segp, + test_shm_mq_header **hdrp, + shm_mq **outp, shm_mq **inp); static worker_state *setup_background_workers(int nworkers, - dsm_segment *seg); + dsm_segment *seg); static void cleanup_background_workers(dsm_segment *seg, Datum arg); static void wait_for_workers_to_become_ready(worker_state *wstate, - volatile test_shm_mq_header *hdr); + volatile test_shm_mq_header *hdr); static bool check_worker_status(worker_state *wstate); /* @@ -280,7 +280,8 @@ wait_for_workers_to_become_ready(worker_state *wstate, } /* Wait to be signalled. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, PG_WAIT_EXTENSION); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + PG_WAIT_EXTENSION); /* Reset the latch so we don't spin. */ ResetLatch(MyLatch); diff --git a/src/test/modules/test_shm_mq/test.c b/src/test/modules/test_shm_mq/test.c index ebab9866017..9b849cccc30 100644 --- a/src/test/modules/test_shm_mq/test.c +++ b/src/test/modules/test_shm_mq/test.c @@ -3,7 +3,7 @@ * test.c * Test harness code for shared memory message queues. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_shm_mq/test.c @@ -27,7 +27,7 @@ PG_FUNCTION_INFO_V1(test_shm_mq_pipelined); void _PG_init(void); static void verify_message(Size origlen, char *origdata, Size newlen, - char *newdata); + char *newdata); /* * Simple test of the shared memory message queue infrastructure. @@ -231,7 +231,8 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS) * have read or written data and therefore there may now be work * for us to do. */ - WaitLatch(MyLatch, WL_LATCH_SET, 0, PG_WAIT_EXTENSION); + (void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0, + PG_WAIT_EXTENSION); ResetLatch(MyLatch); CHECK_FOR_INTERRUPTS(); } diff --git a/src/test/modules/test_shm_mq/test_shm_mq.h b/src/test/modules/test_shm_mq/test_shm_mq.h index 2134b1fdf1b..4c0722297e9 100644 --- a/src/test/modules/test_shm_mq/test_shm_mq.h +++ b/src/test/modules/test_shm_mq/test_shm_mq.h @@ -3,7 +3,7 @@ * test_shm_mq.h * Definitions for shared memory message queues * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_shm_mq/test_shm_mq.h @@ -36,8 +36,8 @@ typedef struct /* Set up dynamic shared memory and background workers for test run. */ extern void test_shm_mq_setup(int64 queue_size, int32 nworkers, - dsm_segment **seg, shm_mq_handle **output, - shm_mq_handle **input); + dsm_segment **seg, shm_mq_handle **output, + shm_mq_handle **input); /* Main entrypoint for a worker. */ extern void test_shm_mq_main(Datum) pg_attribute_noreturn(); diff --git a/src/test/modules/test_shm_mq/worker.c b/src/test/modules/test_shm_mq/worker.c index bcb992e1e43..9f8e77e08c3 100644 --- a/src/test/modules/test_shm_mq/worker.c +++ b/src/test/modules/test_shm_mq/worker.c @@ -9,7 +9,7 @@ * but it should be possible to use much of the control logic just * as presented here. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/test_shm_mq/worker.c @@ -24,14 +24,13 @@ #include "storage/procarray.h" #include "storage/shm_mq.h" #include "storage/shm_toc.h" -#include "utils/resowner.h" #include "test_shm_mq.h" static void handle_sigterm(SIGNAL_ARGS); static void attach_to_queues(dsm_segment *seg, shm_toc *toc, - int myworkernumber, shm_mq_handle **inqhp, - shm_mq_handle **outqhp); + int myworkernumber, shm_mq_handle **inqhp, + shm_mq_handle **outqhp); static void copy_messages(shm_mq_handle *inqh, shm_mq_handle *outqh); /* @@ -69,13 +68,16 @@ test_shm_mq_main(Datum main_arg) * Connect to the dynamic shared memory segment. * * The backend that registered this worker passed us the ID of a shared - * memory segment to which we must attach for further instructions. In - * order to attach to dynamic shared memory, we need a resource owner. - * Once we've mapped the segment in our address space, attach to the table - * of contents so we can locate the various data structures we'll need to + * memory segment to which we must attach for further instructions. Once + * we've mapped the segment in our address space, attach to the table of + * contents so we can locate the various data structures we'll need to * find within the segment. + * + * Note: at this point, we have not created any ResourceOwner in this + * process. This will result in our DSM mapping surviving until process + * exit, which is fine. If there were a ResourceOwner, it would acquire + * ownership of the mapping, but we have no need for that. */ - CurrentResourceOwner = ResourceOwnerCreate(NULL, "test_shm_mq worker"); seg = dsm_attach(DatumGetInt32(main_arg)); if (seg == NULL) ereport(ERROR, @@ -133,10 +135,8 @@ test_shm_mq_main(Datum main_arg) copy_messages(inqh, outqh); /* - * We're done. Explicitly detach the shared memory segment so that we - * don't get a resource leak warning at commit time. This will fire any - * on_dsm_detach callbacks we've registered, as well. Once that's done, - * we can go ahead and exit. + * We're done. For cleanliness, explicitly detach from the shared memory + * segment (that would happen anyway during process exit, though). */ dsm_detach(seg); proc_exit(1); diff --git a/src/test/modules/unsafe_tests/.gitignore b/src/test/modules/unsafe_tests/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/unsafe_tests/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/unsafe_tests/Makefile b/src/test/modules/unsafe_tests/Makefile new file mode 100644 index 00000000000..321252f8d51 --- /dev/null +++ b/src/test/modules/unsafe_tests/Makefile @@ -0,0 +1,14 @@ +# src/test/modules/unsafe_tests/Makefile + +REGRESS = rolenames + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/unsafe_tests +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif diff --git a/src/test/modules/unsafe_tests/README b/src/test/modules/unsafe_tests/README new file mode 100644 index 00000000000..a7e5b2a04f5 --- /dev/null +++ b/src/test/modules/unsafe_tests/README @@ -0,0 +1,8 @@ +This directory doesn't actually contain any extension module. + +What it is is a home for regression tests that we don't want to run +during "make installcheck" because they could have side-effects that +seem undesirable for a production installation. + +An example is that rolenames.sql tests ALTER USER ALL and so could +have effects on pre-existing roles. diff --git a/src/test/regress/expected/rolenames.out b/src/test/modules/unsafe_tests/expected/rolenames.out similarity index 94% rename from src/test/regress/expected/rolenames.out rename to src/test/modules/unsafe_tests/expected/rolenames.out index 7daba9fc128..03c1a255f4f 100644 --- a/src/test/regress/expected/rolenames.out +++ b/src/test/modules/unsafe_tests/expected/rolenames.out @@ -37,11 +37,19 @@ SELECT r.rolname, s.srvname, m.umoptions JOIN pg_foreign_server s ON (s.oid = m.umserver) ORDER BY 2; $$ LANGUAGE SQL; +-- +-- We test creation and use of these role names to ensure that the server +-- correctly distinguishes role keywords from quoted names that look like +-- those keywords. In a test environment, creation of these roles may +-- provoke warnings, so hide the warnings by raising client_min_messages. +-- +SET client_min_messages = ERROR; CREATE ROLE "Public"; CREATE ROLE "None"; CREATE ROLE "current_user"; CREATE ROLE "session_user"; CREATE ROLE "user"; +RESET client_min_messages; CREATE ROLE current_user; -- error ERROR: CURRENT_USER cannot be used as a role name here LINE 1: CREATE ROLE current_user; @@ -435,7 +443,6 @@ LINE 1: ALTER USER NONE SET application_name to 'BOMB'; ALTER USER nonexistent SET application_name to 'BOMB'; -- error ERROR: role "nonexistent" does not exist -- CREATE SCHEMA -set client_min_messages to error; CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER; CREATE SCHEMA newschema2 AUTHORIZATION "current_user"; CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER; @@ -472,10 +479,15 @@ SELECT n.nspname, r.rolname FROM pg_namespace n (5 rows) CREATE SCHEMA IF NOT EXISTS newschema1 AUTHORIZATION CURRENT_USER; +NOTICE: schema "newschema1" already exists, skipping CREATE SCHEMA IF NOT EXISTS newschema2 AUTHORIZATION "current_user"; +NOTICE: schema "newschema2" already exists, skipping CREATE SCHEMA IF NOT EXISTS newschema3 AUTHORIZATION SESSION_USER; +NOTICE: schema "newschema3" already exists, skipping CREATE SCHEMA IF NOT EXISTS newschema4 AUTHORIZATION regress_testrolx; +NOTICE: schema "newschema4" already exists, skipping CREATE SCHEMA IF NOT EXISTS newschema5 AUTHORIZATION "Public"; +NOTICE: schema "newschema5" already exists, skipping CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; -- error ERROR: syntax error at or near "USER" LINE 1: CREATE SCHEMA IF NOT EXISTS newschema6 AUTHORIZATION USER; @@ -509,7 +521,6 @@ SELECT n.nspname, r.rolname FROM pg_namespace n -- ALTER TABLE OWNER TO \c - SET SESSION AUTHORIZATION regress_testrol0; -set client_min_messages to error; CREATE TABLE testtab1 (a int); CREATE TABLE testtab2 (a int); CREATE TABLE testtab3 (a int); @@ -944,9 +955,56 @@ SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; testagg9 | (9 rows) +-- DEFAULT MONITORING ROLES +CREATE ROLE regress_role_haspriv; +CREATE ROLE regress_role_nopriv; +-- pg_read_all_stats +GRANT pg_read_all_stats TO regress_role_haspriv; +SET SESSION AUTHORIZATION regress_role_haspriv; +-- returns true with role member of pg_read_all_stats +SELECT COUNT(*) = 0 AS haspriv FROM pg_stat_activity + WHERE query = ''; + haspriv +--------- + t +(1 row) + +SET SESSION AUTHORIZATION regress_role_nopriv; +-- returns false with role not member of pg_read_all_stats +SELECT COUNT(*) = 0 AS haspriv FROM pg_stat_activity + WHERE query = ''; + haspriv +--------- + f +(1 row) + +RESET SESSION AUTHORIZATION; +REVOKE pg_read_all_stats FROM regress_role_haspriv; +-- pg_read_all_settings +GRANT pg_read_all_settings TO regress_role_haspriv; +BEGIN; +-- A GUC using GUC_SUPERUSER_ONLY is useful for negative tests. +SET LOCAL session_preload_libraries TO 'path-to-preload-libraries'; +SET SESSION AUTHORIZATION regress_role_haspriv; +-- passes with role member of pg_read_all_settings +SHOW session_preload_libraries; + session_preload_libraries +----------------------------- + "path-to-preload-libraries" +(1 row) + +SET SESSION AUTHORIZATION regress_role_nopriv; +-- fails with role not member of pg_read_all_settings +SHOW session_preload_libraries; +ERROR: must be superuser or a member of pg_read_all_settings to examine "session_preload_libraries" +RESET SESSION AUTHORIZATION; +ERROR: current transaction is aborted, commands ignored until end of transaction block +ROLLBACK; +REVOKE pg_read_all_settings FROM regress_role_haspriv; -- clean up \c DROP SCHEMA test_roles_schema; DROP OWNED BY regress_testrol0, "Public", "current_user", regress_testrol1, regress_testrol2, regress_testrolx CASCADE; DROP ROLE regress_testrol0, regress_testrol1, regress_testrol2, regress_testrolx; DROP ROLE "Public", "None", "current_user", "session_user", "user"; +DROP ROLE regress_role_haspriv, regress_role_nopriv; diff --git a/src/test/regress/sql/rolenames.sql b/src/test/modules/unsafe_tests/sql/rolenames.sql similarity index 91% rename from src/test/regress/sql/rolenames.sql rename to src/test/modules/unsafe_tests/sql/rolenames.sql index 5fe8bc8bca2..5a3cf44d82c 100644 --- a/src/test/regress/sql/rolenames.sql +++ b/src/test/modules/unsafe_tests/sql/rolenames.sql @@ -40,12 +40,22 @@ SELECT r.rolname, s.srvname, m.umoptions ORDER BY 2; $$ LANGUAGE SQL; +-- +-- We test creation and use of these role names to ensure that the server +-- correctly distinguishes role keywords from quoted names that look like +-- those keywords. In a test environment, creation of these roles may +-- provoke warnings, so hide the warnings by raising client_min_messages. +-- +SET client_min_messages = ERROR; + CREATE ROLE "Public"; CREATE ROLE "None"; CREATE ROLE "current_user"; CREATE ROLE "session_user"; CREATE ROLE "user"; +RESET client_min_messages; + CREATE ROLE current_user; -- error CREATE ROLE current_role; -- error CREATE ROLE session_user; -- error @@ -177,7 +187,6 @@ ALTER USER NONE SET application_name to 'BOMB'; -- error ALTER USER nonexistent SET application_name to 'BOMB'; -- error -- CREATE SCHEMA -set client_min_messages to error; CREATE SCHEMA newschema1 AUTHORIZATION CURRENT_USER; CREATE SCHEMA newschema2 AUTHORIZATION "current_user"; CREATE SCHEMA newschema3 AUTHORIZATION SESSION_USER; @@ -215,7 +224,6 @@ SELECT n.nspname, r.rolname FROM pg_namespace n -- ALTER TABLE OWNER TO \c - SET SESSION AUTHORIZATION regress_testrol0; -set client_min_messages to error; CREATE TABLE testtab1 (a int); CREATE TABLE testtab2 (a int); CREATE TABLE testtab3 (a int); @@ -438,6 +446,38 @@ REVOKE ALL PRIVILEGES ON FUNCTION testagg9(int2) FROM "none"; --error SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; +-- DEFAULT MONITORING ROLES +CREATE ROLE regress_role_haspriv; +CREATE ROLE regress_role_nopriv; + +-- pg_read_all_stats +GRANT pg_read_all_stats TO regress_role_haspriv; +SET SESSION AUTHORIZATION regress_role_haspriv; +-- returns true with role member of pg_read_all_stats +SELECT COUNT(*) = 0 AS haspriv FROM pg_stat_activity + WHERE query = ''; +SET SESSION AUTHORIZATION regress_role_nopriv; +-- returns false with role not member of pg_read_all_stats +SELECT COUNT(*) = 0 AS haspriv FROM pg_stat_activity + WHERE query = ''; +RESET SESSION AUTHORIZATION; +REVOKE pg_read_all_stats FROM regress_role_haspriv; + +-- pg_read_all_settings +GRANT pg_read_all_settings TO regress_role_haspriv; +BEGIN; +-- A GUC using GUC_SUPERUSER_ONLY is useful for negative tests. +SET LOCAL session_preload_libraries TO 'path-to-preload-libraries'; +SET SESSION AUTHORIZATION regress_role_haspriv; +-- passes with role member of pg_read_all_settings +SHOW session_preload_libraries; +SET SESSION AUTHORIZATION regress_role_nopriv; +-- fails with role not member of pg_read_all_settings +SHOW session_preload_libraries; +RESET SESSION AUTHORIZATION; +ROLLBACK; +REVOKE pg_read_all_settings FROM regress_role_haspriv; + -- clean up \c @@ -445,3 +485,4 @@ DROP SCHEMA test_roles_schema; DROP OWNED BY regress_testrol0, "Public", "current_user", regress_testrol1, regress_testrol2, regress_testrolx CASCADE; DROP ROLE regress_testrol0, regress_testrol1, regress_testrol2, regress_testrolx; DROP ROLE "Public", "None", "current_user", "session_user", "user"; +DROP ROLE regress_role_haspriv, regress_role_nopriv; diff --git a/src/test/modules/worker_spi/.gitignore b/src/test/modules/worker_spi/.gitignore new file mode 100644 index 00000000000..5dcb3ff9723 --- /dev/null +++ b/src/test/modules/worker_spi/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/worker_spi/Makefile b/src/test/modules/worker_spi/Makefile index 7cdb33c9dfc..cbf9b2e37fd 100644 --- a/src/test/modules/worker_spi/Makefile +++ b/src/test/modules/worker_spi/Makefile @@ -6,6 +6,14 @@ EXTENSION = worker_spi DATA = worker_spi--1.0.sql PGFILEDESC = "worker_spi - background worker example" +REGRESS = worker_spi + +# enable our module in shared_preload_libraries for dynamic bgworkers +REGRESS_OPTS = --temp-config $(top_srcdir)/src/test/modules/worker_spi/dynamic.conf + +# Disable installcheck to ensure we cover dynamic bgworkers. +NO_INSTALLCHECK = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/src/test/modules/worker_spi/dynamic.conf b/src/test/modules/worker_spi/dynamic.conf new file mode 100644 index 00000000000..bfe015f6644 --- /dev/null +++ b/src/test/modules/worker_spi/dynamic.conf @@ -0,0 +1,2 @@ +shared_preload_libraries = worker_spi +worker_spi.database = contrib_regression diff --git a/src/test/modules/worker_spi/expected/worker_spi.out b/src/test/modules/worker_spi/expected/worker_spi.out new file mode 100644 index 00000000000..dc0a79bf759 --- /dev/null +++ b/src/test/modules/worker_spi/expected/worker_spi.out @@ -0,0 +1,50 @@ +CREATE EXTENSION worker_spi; +SELECT worker_spi_launch(4) IS NOT NULL; + ?column? +---------- + t +(1 row) + +-- wait until the worker completes its initialization +DO $$ +DECLARE + visible bool; + loops int := 0; +BEGIN + LOOP + visible := table_name IS NOT NULL + FROM information_schema.tables + WHERE table_schema = 'schema4' AND table_name = 'counted'; + IF visible OR loops > 120 * 10 THEN EXIT; END IF; + PERFORM pg_sleep(0.1); + loops := loops + 1; + END LOOP; +END +$$; +INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1); +SELECT pg_reload_conf(); + pg_reload_conf +---------------- + t +(1 row) + +-- wait until the worker has processed the tuple we just inserted +DO $$ +DECLARE + count int; + loops int := 0; +BEGIN + LOOP + count := count(*) FROM schema4.counted WHERE type = 'delta'; + IF count = 0 OR loops > 120 * 10 THEN EXIT; END IF; + PERFORM pg_sleep(0.1); + loops := loops + 1; + END LOOP; +END +$$; +SELECT * FROM schema4.counted; + type | value +-------+------- + total | 1 +(1 row) + diff --git a/src/test/modules/worker_spi/sql/worker_spi.sql b/src/test/modules/worker_spi/sql/worker_spi.sql new file mode 100644 index 00000000000..4683523b29d --- /dev/null +++ b/src/test/modules/worker_spi/sql/worker_spi.sql @@ -0,0 +1,35 @@ +CREATE EXTENSION worker_spi; +SELECT worker_spi_launch(4) IS NOT NULL; +-- wait until the worker completes its initialization +DO $$ +DECLARE + visible bool; + loops int := 0; +BEGIN + LOOP + visible := table_name IS NOT NULL + FROM information_schema.tables + WHERE table_schema = 'schema4' AND table_name = 'counted'; + IF visible OR loops > 120 * 10 THEN EXIT; END IF; + PERFORM pg_sleep(0.1); + loops := loops + 1; + END LOOP; +END +$$; +INSERT INTO schema4.counted VALUES ('total', 0), ('delta', 1); +SELECT pg_reload_conf(); +-- wait until the worker has processed the tuple we just inserted +DO $$ +DECLARE + count int; + loops int := 0; +BEGIN + LOOP + count := count(*) FROM schema4.counted WHERE type = 'delta'; + IF count = 0 OR loops > 120 * 10 THEN EXIT; END IF; + PERFORM pg_sleep(0.1); + loops := loops + 1; + END LOOP; +END +$$; +SELECT * FROM schema4.counted; diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index 0d705a3f2ed..bc9ef64a508 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -13,7 +13,7 @@ * "delta" type. Delta rows will be deleted by this worker and their values * aggregated into the total. * - * Copyright (c) 2013-2018, PostgreSQL Global Development Group + * Copyright (c) 2013-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/test/modules/worker_spi/worker_spi.c @@ -55,6 +55,7 @@ static volatile sig_atomic_t got_sigterm = false; /* GUC variables */ static int worker_spi_naptime = 10; static int worker_spi_total_workers = 2; +static char *worker_spi_database = NULL; typedef struct worktable @@ -179,7 +180,7 @@ worker_spi_main(Datum main_arg) BackgroundWorkerUnblockSignals(); /* Connect to our database */ - BackgroundWorkerInitializeConnection("postgres", NULL, 0); + BackgroundWorkerInitializeConnection(worker_spi_database, NULL, 0); elog(LOG, "%s initialized with %s.%s", MyBgworkerEntry->bgw_name, table->schema, table->name); @@ -217,7 +218,6 @@ worker_spi_main(Datum main_arg) while (!got_sigterm) { int ret; - int rc; /* * Background workers mustn't call usleep() or any direct equivalent: @@ -225,16 +225,12 @@ worker_spi_main(Datum main_arg) * necessary, but is awakened if postmaster dies. That way the * background process goes away immediately in an emergency. */ - rc = WaitLatch(MyLatch, - WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, - worker_spi_naptime * 1000L, - PG_WAIT_EXTENSION); + (void) WaitLatch(MyLatch, + WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + worker_spi_naptime * 1000L, + PG_WAIT_EXTENSION); ResetLatch(MyLatch); - /* emergency bailout if postmaster has died */ - if (rc & WL_POSTMASTER_DEATH) - proc_exit(1); - CHECK_FOR_INTERRUPTS(); /* @@ -344,6 +340,15 @@ _PG_init(void) NULL, NULL); + DefineCustomStringVariable("worker_spi.database", + "Database to connect to.", + NULL, + &worker_spi_database, + "postgres", + PGC_POSTMASTER, + 0, + NULL, NULL, NULL); + /* set up common data for all our workers */ memset(&worker, 0, sizeof(worker)); worker.bgw_flags = BGWORKER_SHMEM_ACCESS | diff --git a/src/test/perl/Makefile b/src/test/perl/Makefile index 8e7012d9434..3af0ef66fdb 100644 --- a/src/test/perl/Makefile +++ b/src/test/perl/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/perl # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/perl/Makefile diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index 5a8f084efeb..270bd6c8566 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -63,6 +63,9 @@ PostgresNode - class representing PostgreSQL server instance # Stop the server $node->stop('fast'); + # Find a free, unprivileged TCP port to bind some other service to + my $port = get_free_port(); + =head1 DESCRIPTION PostgresNode contains a set of routines able to work on a PostgreSQL node, @@ -102,29 +105,23 @@ use Scalar::Util qw(blessed); our @EXPORT = qw( get_new_node + get_free_port ); -our ($test_localhost, $test_pghost, $last_port_assigned, @all_nodes, $died); - -# Windows path to virtual file system root - -our $vfs_path = ''; -if ($Config{osname} eq 'msys') -{ - $vfs_path = `cd / && pwd -W`; - chomp $vfs_path; -} +our ($use_tcp, $test_localhost, $test_pghost, $last_host_assigned, + $last_port_assigned, @all_nodes, $died); INIT { - # PGHOST is set once and for all through a single series of tests when - # this module is loaded. - $test_localhost = "127.0.0.1"; - $test_pghost = - $TestLib::windows_os ? $test_localhost : TestLib::tempdir_short; - $ENV{PGHOST} = $test_pghost; - $ENV{PGDATABASE} = 'postgres'; + # Set PGHOST for backward compatibility. This doesn't work for own_host + # nodes, so prefer to not rely on this when writing new tests. + $use_tcp = $TestLib::windows_os; + $test_localhost = "127.0.0.1"; + $last_host_assigned = 1; + $test_pghost = $use_tcp ? $test_localhost : TestLib::tempdir_short; + $ENV{PGHOST} = $test_pghost; + $ENV{PGDATABASE} = 'postgres'; # Tracking of last port value assigned to accelerate free port lookup. $last_port_assigned = int(rand() * 16384) + 49152; @@ -155,7 +152,10 @@ sub new _host => $pghost, _basedir => "$TestLib::tmp_check/t_${testname}_${name}_data", _name => $name, - _logfile => "$TestLib::log_path/${testname}_${name}.log" }; + _logfile_generation => 0, + _logfile_base => "$TestLib::log_path/${testname}_${name}", + _logfile => "$TestLib::log_path/${testname}_${name}.log" + }; bless $self, $class; mkdir $self->{_basedir} @@ -284,7 +284,7 @@ sub group_access my $dir_stat = stat($self->data_dir); defined($dir_stat) - or die('unable to stat ' . $self->data_dir); + or die('unable to stat ' . $self->data_dir); return (S_IMODE($dir_stat->mode) == 0750); } @@ -371,6 +371,7 @@ sub dump_info { my ($self) = @_; print $self->info; + return; } @@ -389,9 +390,10 @@ sub set_replication_conf if ($TestLib::windows_os) { print $hba -"host replication all $test_localhost/32 sspi include_realm=1 map=regress\n"; + "host replication all $test_localhost/32 sspi include_realm=1 map=regress\n"; } close $hba; + return; } =pod @@ -434,7 +436,8 @@ sub init TestLib::system_or_bail('initdb', '-D', $pgdata, '-A', 'trust', '-N', @{ $params{extra} }); - TestLib::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata); + TestLib::system_or_bail($ENV{PG_REGRESS}, '--config-auth', $pgdata, + @{ $params{auth_extra} }); open my $conf, '>>', "$pgdata/postgresql.conf"; print $conf "\n# Added by PostgresNode.pm\n"; @@ -442,10 +445,19 @@ sub init print $conf "restart_after_crash = off\n"; print $conf "log_line_prefix = '%m [%p] %q%a '\n"; print $conf "log_statement = all\n"; - print $conf "log_min_messages = debug1\n"; print $conf "log_replication_commands = on\n"; print $conf "wal_retrieve_retry_interval = '500ms'\n"; - print $conf "port = $port\n"; + + # If a setting tends to affect whether tests pass or fail, print it after + # TEMP_CONFIG. Otherwise, print it before TEMP_CONFIG, thereby permitting + # overrides. Settings that merely improve performance or ease debugging + # belong before TEMP_CONFIG. + print $conf TestLib::slurp_file($ENV{TEMP_CONFIG}) + if defined $ENV{TEMP_CONFIG}; + + # XXX Neutralize any stats_temp_directory in TEMP_CONFIG. Nodes running + # concurrently must not share a stats_temp_directory. + print $conf "stats_temp_directory = 'pg_stat_tmp'\n"; if ($params{allows_streaming}) { @@ -471,8 +483,10 @@ sub init print $conf "max_wal_senders = 0\n"; } - if ($TestLib::windows_os) + print $conf "port = $port\n"; + if ($use_tcp) { + print $conf "unix_socket_directories = ''\n"; print $conf "listen_addresses = '$host'\n"; } else @@ -482,11 +496,12 @@ sub init } close $conf; - chmod($self->group_access ? 0640 : 0600, "$pgdata/postgresql.conf") - or die("unable to set permissions for $pgdata/postgresql.conf"); + chmod($self->group_access ? 0640 : 0600, "$pgdata/postgresql.conf") + or die("unable to set permissions for $pgdata/postgresql.conf"); $self->set_replication_conf if $params{allows_streaming}; $self->enable_archiving if $params{has_archiving}; + return; } =pod @@ -510,8 +525,10 @@ sub append_conf TestLib::append_to_file($conffile, $str . "\n"); - chmod($self->group_access() ? 0640 : 0600, $conffile) - or die("unable to set permissions for $conffile"); + chmod($self->group_access() ? 0640 : 0600, $conffile) + or die("unable to set permissions for $conffile"); + + return; } =pod @@ -531,13 +548,13 @@ sub backup { my ($self, $backup_name) = @_; my $backup_path = $self->backup_dir . '/' . $backup_name; - my $port = $self->port; my $name = $self->name; print "# Taking pg_basebackup $backup_name from node \"$name\"\n"; - TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-p', $port, - '--no-sync'); + TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-h', + $self->host, '-p', $self->port, '--no-sync'); print "# Backup finished\n"; + return; } =item $node->backup_fs_hot(backup_name) @@ -556,6 +573,7 @@ sub backup_fs_hot { my ($self, $backup_name) = @_; $self->_backup_fs($backup_name, 1); + return; } =item $node->backup_fs_cold(backup_name) @@ -572,6 +590,7 @@ sub backup_fs_cold { my ($self, $backup_name) = @_; $self->_backup_fs($backup_name, 0); + return; } @@ -612,6 +631,7 @@ sub _backup_fs } print "# Backup finished\n"; + return; } @@ -626,8 +646,6 @@ of a backup previously created on that node with $node->backup. Does not start the node after initializing it. -A recovery.conf is not created. - Streaming replication can be enabled on this node by passing the keyword parameter has_streaming => 1. This is disabled by default. @@ -644,6 +662,7 @@ sub init_from_backup { my ($self, $root_node, $backup_name, %params) = @_; my $backup_path = $root_node->backup_dir . '/' . $backup_name; + my $host = $self->host; my $port = $self->port; my $node_name = $self->name; my $root_name = $root_node->name; @@ -652,7 +671,7 @@ sub init_from_backup $params{has_restoring} = 0 unless defined $params{has_restoring}; print -"# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n"; + "# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n"; croak "Backup \"$backup_name\" does not exist at $backup_path" unless -d $backup_path; @@ -670,39 +689,118 @@ sub init_from_backup qq( port = $port )); + if ($use_tcp) + { + $self->append_conf('postgresql.conf', "listen_addresses = '$host'"); + } + else + { + $self->append_conf('postgresql.conf', + "unix_socket_directories = '$host'"); + } $self->enable_streaming($root_node) if $params{has_streaming}; $self->enable_restoring($root_node) if $params{has_restoring}; + return; } =pod -=item $node->start() +=item $node->rotate_logfile() + +Switch to a new PostgreSQL log file. This does not alter any running +PostgreSQL process. Subsequent method calls, including pg_ctl invocations, +will use the new name. Return the new name. + +=cut + +sub rotate_logfile +{ + my ($self) = @_; + $self->{_logfile} = sprintf('%s_%d.log', + $self->{_logfile_base}, + ++$self->{_logfile_generation}); + return $self->{_logfile}; +} + +=pod + +=item $node->start(%params) => success_or_failure Wrapper for pg_ctl start Start the node and wait until it is ready to accept connections. +=over + +=item fail_ok => 1 + +By default, failure terminates the entire F invocation. If given, +instead return a true or false value to indicate success or failure. + +=back + =cut sub start { - my ($self) = @_; + my ($self, %params) = @_; my $port = $self->port; my $pgdata = $self->data_dir; my $name = $self->name; + my $ret; + BAIL_OUT("node \"$name\" is already running") if defined $self->{_pid}; + print("### Starting node \"$name\"\n"); - my $ret = TestLib::system_log('pg_ctl', '-D', $self->data_dir, '-l', - $self->logfile, 'start'); + + { + # Temporarily unset PGAPPNAME so that the server doesn't + # inherit it. Otherwise this could affect libpqwalreceiver + # connections in confusing ways. + local %ENV = %ENV; + delete $ENV{PGAPPNAME}; + + # Note: We set the cluster_name here, not in postgresql.conf (in + # sub init) so that it does not get copied to standbys. + $ret = TestLib::system_log('pg_ctl', '-D', $self->data_dir, '-l', + $self->logfile, '-o', "--cluster-name=$name", 'start'); + } if ($ret != 0) { print "# pg_ctl start failed; logfile:\n"; print TestLib::slurp_file($self->logfile); - BAIL_OUT("pg_ctl start failed"); + BAIL_OUT("pg_ctl start failed") unless $params{fail_ok}; + return 0; } $self->_update_pid(1); + return 1; +} + +=pod + +=item $node->kill9() + +Send SIGKILL (signal 9) to the postmaster. + +Note: if the node is already known stopped, this does nothing. +However, if we think it's running and it's not, it's important for +this to fail. Otherwise, tests might fail to detect server crashes. + +=cut + +sub kill9 +{ + my ($self) = @_; + my $name = $self->name; + return unless defined $self->{_pid}; + print "### Killing node \"$name\" using signal 9\n"; + # kill(9, ...) fails under msys Perl 5.8.8, so fall back on pg_ctl. + kill(9, $self->{_pid}) + or TestLib::system_or_bail('pg_ctl', 'kill', 'KILL', $self->{_pid}); + $self->{_pid} = undef; + return; } =pod @@ -728,6 +826,7 @@ sub stop print "### Stopping node \"$name\" using mode $mode\n"; TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop'); $self->_update_pid(0); + return; } =pod @@ -746,6 +845,7 @@ sub reload my $name = $self->name; print "### Reloading node \"$name\"\n"; TestLib::system_or_bail('pg_ctl', '-D', $pgdata, 'reload'); + return; } =pod @@ -763,10 +863,19 @@ sub restart my $pgdata = $self->data_dir; my $logfile = $self->logfile; my $name = $self->name; + print "### Restarting node \"$name\"\n"; - TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile, - 'restart'); + + { + local %ENV = %ENV; + delete $ENV{PGAPPNAME}; + + TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile, + 'restart'); + } + $self->_update_pid(1); + return; } =pod @@ -787,6 +896,28 @@ sub promote print "### Promoting node \"$name\"\n"; TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile, 'promote'); + return; +} + +=pod + +=item $node->logrotate() + +Wrapper for pg_ctl logrotate + +=cut + +sub logrotate +{ + my ($self) = @_; + my $port = $self->port; + my $pgdata = $self->data_dir; + my $logfile = $self->logfile; + my $name = $self->name; + print "### Rotating log in node \"$name\"\n"; + TestLib::system_or_bail('pg_ctl', '-D', $pgdata, '-l', $logfile, + 'logrotate'); + return; } # Internal routine to enable streaming replication on a standby node. @@ -798,17 +929,18 @@ sub enable_streaming print "### Enabling streaming replication for node \"$name\"\n"; $self->append_conf( - 'recovery.conf', qq( -primary_conninfo='$root_connstr application_name=$name' -standby_mode=on + 'postgresql.conf', qq( +primary_conninfo='$root_connstr' )); + $self->set_standby_mode(); + return; } # Internal routine to enable archive recovery command on a standby node sub enable_restoring { my ($self, $root_node) = @_; - my $path = $vfs_path . $root_node->archive_dir; + my $path = TestLib::perl2host($root_node->archive_dir); my $name = $self->name; print "### Enabling WAL restore for node \"$name\"\n"; @@ -826,17 +958,34 @@ sub enable_restoring : qq{cp "$path/%f" "%p"}; $self->append_conf( - 'recovery.conf', qq( + 'postgresql.conf', qq( restore_command = '$copy_command' -standby_mode = on )); + $self->set_standby_mode(); + return; +} + +=pod + +=item $node->set_standby_mode() + +Place standby.signal file. + +=cut + +sub set_standby_mode +{ + my ($self) = @_; + + $self->append_conf('standby.signal', ''); + return; } # Internal routine to enable archiving sub enable_archiving { my ($self) = @_; - my $path = $vfs_path . $self->archive_dir; + my $path = TestLib::perl2host($self->archive_dir); my $name = $self->name; print "### Enabling WAL archiving for node \"$name\"\n"; @@ -859,6 +1008,7 @@ sub enable_archiving archive_mode = on archive_command = '$copy_command' )); + return; } # Internal method @@ -885,11 +1035,12 @@ sub _update_pid # Complain if we expected to find a pidfile. BAIL_OUT("postmaster.pid unexpectedly not present") if $is_running; + return; } =pod -=item PostgresNode->get_new_node(node_name) +=item PostgresNode->get_new_node(node_name, %params) Build a new object of class C (or of a subclass, if you have one), assigning a free port number. Remembers the node, to prevent its port @@ -898,6 +1049,22 @@ shut down when the test script exits. You should generally use this instead of C. +=over + +=item port => [1,65535] + +By default, this function assigns a port number to each node. Specify this to +force a particular port number. The caller is responsible for evaluating +potential conflicts and privilege requirements. + +=item own_host => 1 + +By default, all nodes use the same PGHOST value. If specified, generate a +PGHOST specific to this node. This allows multiple nodes to use the same +port. + +=back + For backwards compatibility, it is also exported as a standalone function, which can only create objects of class C. @@ -906,8 +1073,68 @@ which can only create objects of class C. sub get_new_node { my $class = 'PostgresNode'; - $class = shift if 1 < scalar @_; - my $name = shift; + $class = shift if scalar(@_) % 2 != 1; + my ($name, %params) = @_; + + # Select a port. + my $port; + if (defined $params{port}) + { + $port = $params{port}; + } + else + { + # When selecting a port, we look for an unassigned TCP port number, + # even if we intend to use only Unix-domain sockets. This is clearly + # necessary on $use_tcp (Windows) configurations, and it seems like a + # good idea on Unixen as well. + $port = get_free_port(); + } + + # Select a host. + my $host = $test_pghost; + if ($params{own_host}) + { + if ($use_tcp) + { + $last_host_assigned++; + $last_host_assigned > 254 and BAIL_OUT("too many own_host nodes"); + $host = '127.0.0.' . $last_host_assigned; + } + else + { + $host = "$test_pghost/$name"; # Assume $name =~ /^[-_a-zA-Z0-9]+$/ + mkdir $host; + } + } + + # Lock port number found by creating a new node + my $node = $class->new($name, $host, $port); + + # Add node to list of nodes + push(@all_nodes, $node); + + return $node; +} + +=pod + +=item get_free_port() + +Locate an unprivileged (high) TCP port that's not currently bound to +anything. This is used by get_new_node, and is also exported for use +by test cases that need to start other, non-Postgres servers. + +Ports assigned to existing PostgresNode objects are automatically +excluded, even if those servers are not currently running. + +XXX A port available now may become unavailable by the time we start +the desired service. + +=cut + +sub get_free_port +{ my $found = 0; my $port = $last_port_assigned; @@ -927,39 +1154,56 @@ sub get_new_node } # Check to see if anything else is listening on this TCP port. - # This is *necessary* on Windows, and seems like a good idea - # on Unixen as well, even though we don't ask the postmaster - # to open a TCP port on Unix. + # Seek a port available for all possible listen_addresses values, + # so callers can harness this port for the widest range of purposes. + # The 0.0.0.0 test achieves that for post-2006 Cygwin, which + # automatically sets SO_EXCLUSIVEADDRUSE. The same holds for MSYS (a + # Cygwin fork). Testing 0.0.0.0 is insufficient for Windows native + # Perl (https://stackoverflow.com/a/14388707), so we also test + # individual addresses. + # + # On non-Linux, non-Windows kernels, binding to 127.0.0/24 addresses + # other than 127.0.0.1 might fail with EADDRNOTAVAIL. Binding to + # 0.0.0.0 is unnecessary on non-Windows systems. if ($found == 1) { - my $iaddr = inet_aton($test_localhost); - my $paddr = sockaddr_in($port, $iaddr); - my $proto = getprotobyname("tcp"); - - socket(SOCK, PF_INET, SOCK_STREAM, $proto) - or die "socket failed: $!"; - - # As in postmaster, don't use SO_REUSEADDR on Windows - setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) - unless $TestLib::windows_os; - (bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN)) - or $found = 0; - close(SOCK); + foreach my $addr (qw(127.0.0.1), + $use_tcp ? qw(127.0.0.2 127.0.0.3 0.0.0.0) : ()) + { + if (!can_bind($addr, $port)) + { + $found = 0; + last; + } + } } } - print "# Found free port $port\n"; - - # Lock port number found by creating a new node - my $node = $class->new($name, $test_pghost, $port); - - # Add node to list of nodes - push(@all_nodes, $node); + print "# Found port $port\n"; - # And update port for next time + # Update port for next time $last_port_assigned = $port; - return $node; + return $port; +} + +# Internal routine to check whether a host:port is available to bind +sub can_bind +{ + my ($host, $port) = @_; + my $iaddr = inet_aton($host); + my $paddr = sockaddr_in($port, $iaddr); + my $proto = getprotobyname("tcp"); + + socket(SOCK, PF_INET, SOCK_STREAM, $proto) + or die "socket failed: $!"; + + # As in postmaster, don't use SO_REUSEADDR on Windows + setsockopt(SOCK, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) + unless $TestLib::windows_os; + my $ret = bind(SOCK, $paddr) && listen(SOCK, SOMAXCONN); + close(SOCK); + return $ret; } # Retain the errno on die() if set, else assume a generic errno of 1. @@ -1014,7 +1258,7 @@ sub teardown_node my $self = shift; $self->stop('immediate'); - + return; } =pod @@ -1030,6 +1274,7 @@ sub clean_node my $self = shift; rmtree $self->{_basedir} unless defined $self->{_pid}; + return; } =pod @@ -1197,12 +1442,12 @@ sub psql my $ret; - # Run psql and capture any possible exceptions. If the exception is - # because of a timeout and the caller requested to handle that, just return - # and set the flag. Otherwise, and for any other exception, rethrow. - # - # For background, see - # http://search.cpan.org/~ether/Try-Tiny-0.24/lib/Try/Tiny.pm + # Run psql and capture any possible exceptions. If the exception is + # because of a timeout and the caller requested to handle that, just return + # and set the flag. Otherwise, and for any other exception, rethrow. + # + # For background, see + # https://metacpan.org/pod/release/ETHER/Try-Tiny-0.24/lib/Try/Tiny.pm do { local $@; @@ -1272,7 +1517,7 @@ sub psql die "connection error: '$$stderr'\nwhile running '@psql_params'" if $ret == 2; die -"error running SQL: '$$stderr'\nwhile running '@psql_params' with sql '$sql'" + "error running SQL: '$$stderr'\nwhile running '@psql_params' with sql '$sql'" if $ret == 3; die "psql returns $ret: '$$stderr'\nwhile running '@psql_params'"; } @@ -1328,9 +1573,18 @@ sub poll_query_until $attempts++; } - # The query result didn't change in 180 seconds. Give up. Print the stderr - # from the last attempt, hopefully that's useful for debugging. - diag $stderr; + # The query result didn't change in 180 seconds. Give up. Print the + # output from the last attempt, hopefully that's useful for debugging. + chomp($stderr); + $stderr =~ s/\r//g if $TestLib::windows_os; + diag qq(poll_query_until timed out executing this query: +$query +expecting this output: +$expected +last actual query output: +$stdout +with stderr: +$stderr); return 0; } @@ -1338,70 +1592,86 @@ sub poll_query_until =item $node->command_ok(...) -Runs a shell command like TestLib::command_ok, but with PGPORT -set so that the command will default to connecting to this -PostgresNode. +Runs a shell command like TestLib::command_ok, but with PGHOST and PGPORT set +so that the command will default to connecting to this PostgresNode. =cut sub command_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; TestLib::command_ok(@_); + return; } =pod =item $node->command_fails(...) -TestLib::command_fails with our PGPORT. See command_ok(...) +TestLib::command_fails with our connection parameters. See command_ok(...) =cut sub command_fails { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; TestLib::command_fails(@_); + return; } =pod =item $node->command_like(...) -TestLib::command_like with our PGPORT. See command_ok(...) +TestLib::command_like with our connection parameters. See command_ok(...) =cut sub command_like { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; TestLib::command_like(@_); + return; } =pod =item $node->command_checks_all(...) -TestLib::command_checks_all with our PGPORT. See command_ok(...) +TestLib::command_checks_all with our connection parameters. See +command_ok(...) =cut sub command_checks_all { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my $self = shift; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; TestLib::command_checks_all(@_); + return; } =pod @@ -1418,8 +1688,11 @@ The log file is truncated prior to running the command, however. sub issues_sql_like { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($self, $cmd, $expected_sql, $test_name) = @_; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; truncate $self->logfile, 0; @@ -1427,14 +1700,15 @@ sub issues_sql_like ok($result, "@$cmd exit code 0"); my $log = TestLib::slurp_file($self->logfile); like($log, $expected_sql, "$test_name: SQL found in server log"); + return; } =pod =item $node->run_log(...) -Runs a shell command like TestLib::run_log, but with PGPORT set so -that the command will default to connecting to this PostgresNode. +Runs a shell command like TestLib::run_log, but with connection parameters set +so that the command will default to connecting to this PostgresNode. =cut @@ -1442,9 +1716,11 @@ sub run_log { my $self = shift; + local $ENV{PGHOST} = $self->host; local $ENV{PGPORT} = $self->port; TestLib::run_log(@_); + return; } =pod @@ -1499,7 +1775,8 @@ also works for logical subscriptions) until its replication location in pg_stat_replication equals or passes the upstream's WAL insert point at the time this function is called. By default the replay_lsn is waited for, but 'mode' may be specified to wait for any of -sent|write|flush|replay. +sent|write|flush|replay. The connection catching up must be in a streaming +state. If there is no active replication connection from this peer, waits until poll_query_until timeout. @@ -1535,7 +1812,7 @@ sub wait_for_catchup } else { - $lsn_expr = 'pg_current_wal_lsn()' + $lsn_expr = 'pg_current_wal_lsn()'; } print "Waiting for replication conn " . $standby_name . "'s " @@ -1544,10 +1821,11 @@ sub wait_for_catchup . $lsn_expr . " on " . $self->name . "\n"; my $query = -qq[SELECT $lsn_expr <= ${mode}_lsn FROM pg_catalog.pg_stat_replication WHERE application_name = '$standby_name';]; + qq[SELECT $lsn_expr <= ${mode}_lsn AND state = 'streaming' FROM pg_catalog.pg_stat_replication WHERE application_name = '$standby_name';]; $self->poll_query_until('postgres', $query) or croak "timed out waiting for catchup"; print "done\n"; + return; } =pod @@ -1586,10 +1864,11 @@ sub wait_for_slot_catchup . $target_lsn . " on " . $self->name . "\n"; my $query = -qq[SELECT '$target_lsn' <= ${mode}_lsn FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name';]; + qq[SELECT '$target_lsn' <= ${mode}_lsn FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name';]; $self->poll_query_until('postgres', $query) or croak "timed out waiting for catchup"; print "done\n"; + return; } =pod @@ -1661,7 +1940,7 @@ sub slot 'restart_lsn'); return $self->query_hash( 'postgres', -"SELECT __COLUMNS__ FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name'", + "SELECT __COLUMNS__ FROM pg_catalog.pg_replication_slots WHERE slot_name = '$slot_name'", @columns); } @@ -1686,8 +1965,8 @@ to check for timeout. retval is undef on timeout. sub pg_recvlogical_upto { - my ($self, $dbname, $slot_name, $endpos, $timeout_secs, %plugin_options) = - @_; + my ($self, $dbname, $slot_name, $endpos, $timeout_secs, %plugin_options) + = @_; my ($stdout, $stderr); my $timeout_exception = 'pg_recvlogical timed out'; @@ -1736,7 +2015,7 @@ sub pg_recvlogical_upto unless $timeout->is_expired; die -"$exc_save waiting for endpos $endpos with stdout '$stdout', stderr '$stderr'" + "$exc_save waiting for endpos $endpos with stdout '$stdout', stderr '$stderr'" unless wantarray; } }; @@ -1751,7 +2030,7 @@ sub pg_recvlogical_upto else { die -"pg_recvlogical exited with code '$ret', stdout '$stdout' and stderr '$stderr'" + "pg_recvlogical exited with code '$ret', stdout '$stdout' and stderr '$stderr'" if $ret; return $stdout; } diff --git a/src/test/perl/RecursiveCopy.pm b/src/test/perl/RecursiveCopy.pm index 5bce720b356..baf5d0ac63b 100644 --- a/src/test/perl/RecursiveCopy.pm +++ b/src/test/perl/RecursiveCopy.pm @@ -71,7 +71,7 @@ sub copypath { croak "if specified, filterfn must be a subroutine reference" unless defined(ref $params{filterfn}) - and (ref $params{filterfn} eq 'CODE'); + and (ref $params{filterfn} eq 'CODE'); $filterfn = $params{filterfn}; } diff --git a/src/test/perl/SimpleTee.pm b/src/test/perl/SimpleTee.pm index ea2f2ee8287..9de7b1ac323 100644 --- a/src/test/perl/SimpleTee.pm +++ b/src/test/perl/SimpleTee.pm @@ -13,7 +13,7 @@ use strict; sub TIEHANDLE { my $self = shift; - bless \@_, $self; + return bless \@_, $self; } sub PRINT diff --git a/src/test/perl/TestLib.pm b/src/test/perl/TestLib.pm index 8047404efd4..905d0d178ff 100644 --- a/src/test/perl/TestLib.pm +++ b/src/test/perl/TestLib.pm @@ -1,9 +1,41 @@ -# TestLib, low-level routines and actions regression tests. -# -# This module contains a set of routines dedicated to environment setup for -# a PostgreSQL regression test run and includes some low-level routines -# aimed at controlling command execution, logging and test functions. This -# module should never depend on any other PostgreSQL regression test modules. +=pod + +=head1 NAME + +TestLib - helper module for writing PostgreSQL's C tests. + +=head1 SYNOPSIS + + use TestLib; + + # Test basic output of a command + program_help_ok('initdb'); + program_version_ok('initdb'); + program_options_handling_ok('initdb'); + + # Test option combinations + command_fails(['initdb', '--invalid-option'], + 'command fails with invalid option'); + my $tempdir = TestLib::tempdir; + command_ok('initdb', '-D', $tempdir); + + # Miscellanea + print "on Windows" if $TestLib::windows_os; + my $path = TestLib::perl2host($backup_dir); + ok(check_mode_recursive($stream_dir, 0700, 0600), + "check stream dir permissions"); + TestLib::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid); + +=head1 DESCRIPTION + +C contains a set of routines dedicated to environment setup for +a PostgreSQL regression test run and includes some low-level routines +aimed at controlling command execution, logging and test functions. + +=cut + +# This module should never depend on any other PostgreSQL regression test +# modules. package TestLib; @@ -22,7 +54,8 @@ use File::Temp (); use IPC::Run; use SimpleTee; -# specify a recent enough version of Test::More to support the done_testing() function +# specify a recent enough version of Test::More to support the +# done_testing() function use Test::More 0.87; our @EXPORT = qw( @@ -36,6 +69,7 @@ our @EXPORT = qw( system_or_bail system_log run_log + run_command command_ok command_fails @@ -72,6 +106,7 @@ BEGIN delete $ENV{PGUSER}; delete $ENV{PGPORT}; delete $ENV{PGHOST}; + delete $ENV{PG_COLOR}; $ENV{PGAPPNAME} = basename($0); @@ -79,6 +114,20 @@ BEGIN $windows_os = $Config{osname} eq 'MSWin32' || $Config{osname} eq 'msys'; } +=pod + +=head1 EXPORTED VARIABLES + +=over + +=item C<$windows_os> + +Set to true when running under Windows, except on Cygwin. + +=back + +=cut + INIT { @@ -133,9 +182,20 @@ END $File::Temp::KEEP_ALL = 1 unless all_tests_passing(); } +=pod + +=head1 ROUTINES + +=over + +=item all_tests_passing() + +Return 1 if all the tests run so far have passed. Otherwise, return 0. + +=cut + sub all_tests_passing { - my $fail_count = 0; foreach my $status (Test::More->builder->summary) { return 0 unless $status; @@ -143,9 +203,19 @@ sub all_tests_passing return 1; } -# -# Helper functions -# +=pod + +=item tempdir(prefix) + +Securely create a temporary directory inside C<$tmp_check>, like C, +and return its name. The directory will be removed automatically at the +end of the tests. + +If C is given, the new directory is templated as C<${prefix}_XXXX>. +Otherwise the template is C. + +=cut + sub tempdir { my ($prefix) = @_; @@ -156,52 +226,132 @@ sub tempdir CLEANUP => 1); } +=pod + +=item tempdir_short() + +As above, but the directory is outside the build tree so that it has a short +name, to avoid path length issues. + +=cut + sub tempdir_short { - # Use a separate temp dir outside the build tree for the - # Unix-domain socket, to avoid file name length issues. return File::Temp::tempdir(CLEANUP => 1); } -# Return the real directory for a virtual path directory under msys. -# The directory must exist. If it's not an existing directory or we're -# not under msys, return the input argument unchanged. -sub real_dir +=pod + +=item perl2host() + +Translate a Perl file name to a host file name. Currently, this is a no-op +except for the case of Perl=msys and host=mingw32. The subject need not +exist, but its parent directory must exist. + +=cut + +sub perl2host { - my $dir = "$_[0]"; - return $dir unless -d $dir; - return $dir unless $Config{osname} eq 'msys'; - my $here = cwd; - chdir $dir; + my ($subject) = @_; + return $subject unless $Config{osname} eq 'msys'; + my $here = cwd; + my $leaf; + if (chdir $subject) + { + $leaf = ''; + } + else + { + $leaf = '/' . basename $subject; + my $parent = dirname $subject; + chdir $parent or die "could not chdir \"$parent\": $!"; + } + # this odd way of calling 'pwd -W' is the only way that seems to work. - $dir = qx{sh -c "pwd -W"}; - chomp $dir; - chdir $here; - return $dir; + my $dir = qx{sh -c "pwd -W"}; + chomp $dir; + chdir $here; + return $dir . $leaf; } +=pod + +=item system_log(@cmd) + +Run (via C) the command passed as argument; the return +value is passed through. + +=cut + sub system_log { print("# Running: " . join(" ", @_) . "\n"); return system(@_); } +=pod + +=item system_or_bail(@cmd) + +Run (via C) the command passed as argument, and returns +if the command is successful. +On failure, abandon further tests and exit the program. + +=cut + sub system_or_bail { if (system_log(@_) != 0) { BAIL_OUT("system $_[0] failed"); } + return; } +=pod + +=item run_log(@cmd) + +Run the given command via C, noting it in the log. +The return value from the command is passed through. + +=cut + sub run_log { print("# Running: " . join(" ", @{ $_[0] }) . "\n"); return IPC::Run::run(@_); } -# Generate a string made of the given range of ASCII characters +=pod + +=item run_command(cmd) + +Run (via C) the command passed as argument. +The return value from the command is ignored. +The return value is C<($stdout, $stderr)>. + +=cut + +sub run_command +{ + my ($cmd) = @_; + my ($stdout, $stderr); + my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr; + chomp($stdout); + chomp($stderr); + return ($stdout, $stderr); +} + +=pod + +=item generate_ascii_string(from_char, to_char) + +Generate a string made of the given range of ASCII characters. + +=cut + sub generate_ascii_string { my ($from_char, $to_char) = @_; @@ -214,6 +364,14 @@ sub generate_ascii_string return $res; } +=pod + +=item slurp_dir(dir) + +Return the complete list of entries in the specified directory. + +=cut + sub slurp_dir { my ($dir) = @_; @@ -224,6 +382,14 @@ sub slurp_dir return @direntries; } +=pod + +=item slurp_file(filename) + +Return the full contents of the specified file. + +=cut + sub slurp_file { my ($filename) = @_; @@ -236,6 +402,15 @@ sub slurp_file return $contents; } +=pod + +=item append_to_file(filename, str) + +Append a string at the end of a given file. (Note: no newline is appended at +end of file.) + +=cut + sub append_to_file { my ($filename, $str) = @_; @@ -243,10 +418,18 @@ sub append_to_file or die "could not write \"$filename\": $!"; print $fh $str; close $fh; + return; } -# Check that all file/dir modes in a directory match the expected values, -# ignoring the mode of any specified files. +=pod + +=item check_mode_recursive(dir, expected_dir_mode, expected_file_mode, ignore_list) + +Check that all file/dir modes in a directory match the expected values, +ignoring files in C (basename only). + +=cut + sub check_mode_recursive { my ($dir, $expected_dir_mode, $expected_file_mode, $ignore_list) = @_; @@ -254,14 +437,10 @@ sub check_mode_recursive # Result defaults to true my $result = 1; - find - ( - {follow_fast => 1, - wanted => - sub - { - my $file_stat = stat($File::Find::name); - + find( + { + follow_fast => 1, + wanted => sub { # Is file in the ignore list? foreach my $ignore ($ignore_list ? @{$ignore_list} : []) { @@ -271,8 +450,23 @@ sub check_mode_recursive } } - defined($file_stat) - or die("unable to stat $File::Find::name"); + # Allow ENOENT. A running server can delete files, such as + # those in pg_stat. Other stat() failures are fatal. + my $file_stat = stat($File::Find::name); + unless (defined($file_stat)) + { + my $is_ENOENT = $!{ENOENT}; + my $msg = "unable to stat $File::Find::name: $!"; + if ($is_ENOENT) + { + warn $msg; + return; + } + else + { + die $msg; + } + } my $file_mode = S_IMODE($file_stat->mode); @@ -281,66 +475,83 @@ sub check_mode_recursive { if ($file_mode != $expected_file_mode) { - print(*STDERR, + print( + *STDERR, sprintf("$File::Find::name mode must be %04o\n", - $expected_file_mode)); + $expected_file_mode)); $result = 0; return; } } + # Else a directory? elsif (S_ISDIR($file_stat->mode)) { if ($file_mode != $expected_dir_mode) { - print(*STDERR, + print( + *STDERR, sprintf("$File::Find::name mode must be %04o\n", - $expected_dir_mode)); + $expected_dir_mode)); $result = 0; return; } } + # Else something we can't handle else { die "unknown file type for $File::Find::name"; } - }}, - $dir - ); + } + }, + $dir); return $result; } -# Change mode recursively on a directory +=pod + +=item chmod_recursive(dir, dir_mode, file_mode) + +C recursively each file and directory within the given directory. + +=cut + sub chmod_recursive { my ($dir, $dir_mode, $file_mode) = @_; - find - ( - {follow_fast => 1, - wanted => - sub - { + find( + { + follow_fast => 1, + wanted => sub { my $file_stat = stat($File::Find::name); if (defined($file_stat)) { - chmod(S_ISDIR($file_stat->mode) ? $dir_mode : $file_mode, - $File::Find::name) - or die "unable to chmod $File::Find::name"; + chmod( + S_ISDIR($file_stat->mode) ? $dir_mode : $file_mode, + $File::Find::name + ) or die "unable to chmod $File::Find::name"; } - }}, - $dir - ); + } + }, + $dir); + return; } -# Check presence of a given regexp within pg_config.h for the installation -# where tests are running, returning a match status result depending on -# that. +=pod + +=item check_pg_config(regexp) + +Return the number of matches of the given regular expression +within the installation's C. + +=cut + sub check_pg_config { my ($regexp) = @_; @@ -349,32 +560,65 @@ sub check_pg_config \$stdout, '2>', \$stderr or die "could not execute pg_config"; chomp($stdout); + $stdout =~ s/\r$//; open my $pg_config_h, '<', "$stdout/pg_config.h" or die "$!"; - my $match = (grep {/^$regexp/} <$pg_config_h>); + my $match = (grep { /^$regexp/ } <$pg_config_h>); close $pg_config_h; return $match; } -# -# Test functions -# +=pod + +=back + +=head1 Test::More-LIKE METHODS + +=over + +=item command_ok(cmd, test_name) + +Check that the command runs (via C) successfully. + +=cut + sub command_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd, $test_name) = @_; my $result = run_log($cmd); ok($result, $test_name); + return; } +=pod + +=item command_fails(cmd, test_name) + +Check that the command fails (when run via C). + +=cut + sub command_fails { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd, $test_name) = @_; my $result = run_log($cmd); ok(!$result, $test_name); + return; } +=pod + +=item command_exit_is(cmd, expected, test_name) + +Check that the command exit code matches the expected exit code. + +=cut + sub command_exit_is { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd, $expected, $test_name) = @_; print("# Running: " . join(" ", @{$cmd}) . "\n"); my $h = IPC::Run::start $cmd; @@ -386,16 +630,26 @@ sub command_exit_is # header file). IPC::Run's result function always returns exit code >> 8, # assuming the Unix convention, which will always return 0 on Windows as # long as the process was not terminated by an exception. To work around - # that, use $h->full_result on Windows instead. + # that, use $h->full_results on Windows instead. my $result = ($Config{osname} eq "MSWin32") ? ($h->full_results)[0] : $h->result(0); is($result, $expected, $test_name); + return; } +=pod + +=item program_help_ok(cmd) + +Check that the command supports the C<--help> option. + +=cut + sub program_help_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd) = @_; my ($stdout, $stderr); print("# Running: $cmd --help\n"); @@ -404,10 +658,20 @@ sub program_help_ok ok($result, "$cmd --help exit code 0"); isnt($stdout, '', "$cmd --help goes to stdout"); is($stderr, '', "$cmd --help nothing to stderr"); + return; } +=pod + +=item program_version_ok(cmd) + +Check that the command supports the C<--version> option. + +=cut + sub program_version_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd) = @_; my ($stdout, $stderr); print("# Running: $cmd --version\n"); @@ -416,10 +680,21 @@ sub program_version_ok ok($result, "$cmd --version exit code 0"); isnt($stdout, '', "$cmd --version goes to stdout"); is($stderr, '', "$cmd --version nothing to stderr"); + return; } +=pod + +=item program_options_handling_ok(cmd) + +Check that a command with an invalid option returns a non-zero +exit code and error message. + +=cut + sub program_options_handling_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd) = @_; my ($stdout, $stderr); print("# Running: $cmd --not-a-valid-option\n"); @@ -428,10 +703,21 @@ sub program_options_handling_ok '2>', \$stderr; ok(!$result, "$cmd with invalid option nonzero exit code"); isnt($stderr, '', "$cmd with invalid option prints error message"); + return; } +=pod + +=item command_like(cmd, expected_stdout, test_name) + +Check that the command runs successfully and the output +matches the given regular expression. + +=cut + sub command_like { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd, $expected_stdout, $test_name) = @_; my ($stdout, $stderr); print("# Running: " . join(" ", @{$cmd}) . "\n"); @@ -439,10 +725,22 @@ sub command_like ok($result, "$test_name: exit code 0"); is($stderr, '', "$test_name: no stderr"); like($stdout, $expected_stdout, "$test_name: matches"); + return; } +=pod + +=item command_like_safe(cmd, expected_stdout, test_name) + +Check that the command runs successfully and the output +matches the given regular expression. Doesn't assume that the +output files are closed. + +=cut + sub command_like_safe { + local $Test::Builder::Level = $Test::Builder::Level + 1; # Doesn't rely on detecting end of file on the file descriptors, # which can fail, causing the process to hang, notably on Msys @@ -458,27 +756,57 @@ sub command_like_safe ok($result, "$test_name: exit code 0"); is($stderr, '', "$test_name: no stderr"); like($stdout, $expected_stdout, "$test_name: matches"); + return; } +=pod + +=item command_fails_like(cmd, expected_stderr, test_name) + +Check that the command fails and the error message matches +the given regular expression. + +=cut + sub command_fails_like { + local $Test::Builder::Level = $Test::Builder::Level + 1; my ($cmd, $expected_stderr, $test_name) = @_; my ($stdout, $stderr); print("# Running: " . join(" ", @{$cmd}) . "\n"); my $result = IPC::Run::run $cmd, '>', \$stdout, '2>', \$stderr; ok(!$result, "$test_name: exit code not 0"); like($stderr, $expected_stderr, "$test_name: matches"); + return; } -# Run a command and check its status and outputs. -# The 5 arguments are: -# - cmd: ref to list for command, options and arguments to run -# - ret: expected exit status -# - out: ref to list of re to be checked against stdout (all must match) -# - err: ref to list of re to be checked against stderr (all must match) -# - test_name: name of test +=pod + +=item command_checks_all(cmd, ret, out, err, test_name) + +Run a command and check its status and outputs. +Arguments: + +=over + +=item C: Array reference of command and arguments to run + +=item C: Expected exit code + +=item C: Expected stdout from command + +=item C: Expected stderr from command + +=item C: test name + +=back + +=cut + sub command_checks_all { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($cmd, $expected_ret, $out, $err, $test_name) = @_; # run command @@ -507,6 +835,14 @@ sub command_checks_all { like($stderr, $re, "$test_name stderr /$re/"); } + + return; } +=pod + +=back + +=cut + 1; diff --git a/src/test/recovery/Makefile b/src/test/recovery/Makefile index daf79a0b1fc..e66e69521f2 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/recovery # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/recovery/Makefile diff --git a/src/test/recovery/README b/src/test/recovery/README index 93bdcf4fed6..632e720ebef 100644 --- a/src/test/recovery/README +++ b/src/test/recovery/README @@ -8,14 +8,18 @@ This directory contains a test suite for recovery and replication. Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Also, to use "make installcheck", you must have built and installed +contrib/test_decoding in addition to the core code. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. -NOTE: This creates a temporary installation (in the case of "check"), -and some tests may create one or multiple nodes, be they master or -standby(s) for the purpose of the tests. - -NOTE: This requires the --enable-tap-tests argument to configure. +Either way, this test initializes, starts, and stops several test Postgres +clusters. diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl index fb279250699..3c743d7d7cc 100644 --- a/src/test/recovery/t/001_stream_rep.pl +++ b/src/test/recovery/t/001_stream_rep.pl @@ -3,11 +3,15 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 28; +use Test::More tests => 32; # Initialize master node my $node_master = get_new_node('master'); -$node_master->init(allows_streaming => 1); +# A specific role is created to perform some tests related to replication, +# and it needs proper authentication configuration. +$node_master->init( + allows_streaming => 1, + auth_extra => [ '--create-role', 'repl_role' ]); $node_master->start; my $backup_name = 'my_backup'; @@ -95,8 +99,10 @@ sub test_target_session_attrs extra_params => [ '-d', $connstr ]); is( $status == $ret && $stdout eq $target_node->port, 1, -"connect to node $target_name if mode \"$mode\" and $node1_name,$node2_name listed" + "connect to node $target_name if mode \"$mode\" and $node1_name,$node2_name listed" ); + + return; } # Connect to master in "read-write" mode with master,standby1 list. @@ -115,6 +121,64 @@ sub test_target_session_attrs test_target_session_attrs($node_standby_1, $node_master, $node_standby_1, "any", 0); +# Test for SHOW commands using a WAL sender connection with a replication +# role. +note "testing SHOW commands for replication connection"; + +$node_master->psql( + 'postgres', " +CREATE ROLE repl_role REPLICATION LOGIN; +GRANT pg_read_all_settings TO repl_role;"); +my $master_host = $node_master->host; +my $master_port = $node_master->port; +my $connstr_common = "host=$master_host port=$master_port user=repl_role"; +my $connstr_rep = "$connstr_common replication=1"; +my $connstr_db = "$connstr_common replication=database dbname=postgres"; + +# Test SHOW ALL +my ($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW ALL;', + on_error_die => 1, + extra_params => [ '-d', $connstr_rep ]); +ok($ret == 0, "SHOW ALL with replication role and physical replication"); +($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW ALL;', + on_error_die => 1, + extra_params => [ '-d', $connstr_db ]); +ok($ret == 0, "SHOW ALL with replication role and logical replication"); + +# Test SHOW with a user-settable parameter +($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW work_mem;', + on_error_die => 1, + extra_params => [ '-d', $connstr_rep ]); +ok( $ret == 0, + "SHOW with user-settable parameter, replication role and physical replication" +); +($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW work_mem;', + on_error_die => 1, + extra_params => [ '-d', $connstr_db ]); +ok( $ret == 0, + "SHOW with user-settable parameter, replication role and logical replication" +); + +# Test SHOW with a superuser-settable parameter +($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW primary_conninfo;', + on_error_die => 1, + extra_params => [ '-d', $connstr_rep ]); +ok( $ret == 0, + "SHOW with superuser-settable parameter, replication role and physical replication" +); +($ret, $stdout, $stderr) = $node_master->psql( + 'postgres', 'SHOW primary_conninfo;', + on_error_die => 1, + extra_params => [ '-d', $connstr_db ]); +ok( $ret == 0, + "SHOW with superuser-settable parameter, replication role and logical replication" +); + note "switching to physical replication slot"; # Switch to using a physical replication slot. We can do this without a new @@ -129,7 +193,7 @@ sub test_target_session_attrs qq[SELECT pg_create_physical_replication_slot('$slotname_1');]), 0, 'physical slot created on master'); -$node_standby_1->append_conf('recovery.conf', +$node_standby_1->append_conf('postgresql.conf', "primary_slot_name = $slotname_1"); $node_standby_1->append_conf('postgresql.conf', "wal_receiver_status_interval = 1"); @@ -140,7 +204,7 @@ sub test_target_session_attrs qq[SELECT pg_create_physical_replication_slot('$slotname_2');]), 0, 'physical slot created on intermediate replica'); -$node_standby_2->append_conf('recovery.conf', +$node_standby_2->append_conf('postgresql.conf', "primary_slot_name = $slotname_2"); $node_standby_2->append_conf('postgresql.conf', "wal_receiver_status_interval = 1"); @@ -183,7 +247,7 @@ sub get_slot_xmins sub replay_check { my $newval = $node_master->safe_psql('postgres', -'INSERT INTO replayed(val) SELECT coalesce(max(val),0) + 1 AS newval FROM replayed RETURNING val' + 'INSERT INTO replayed(val) SELECT coalesce(max(val),0) + 1 AS newval FROM replayed RETURNING val' ); $node_master->wait_for_catchup($node_standby_1, 'replay', $node_master->lsn('insert')); @@ -195,6 +259,7 @@ sub replay_check $node_standby_2->safe_psql('postgres', qq[SELECT 1 FROM replayed WHERE val = $newval]) or die "standby_2 didn't replay standby_1 value $newval"; + return; } replay_check(); @@ -279,27 +344,3 @@ sub replay_check is($xmin, '', 'xmin of cascaded slot null with hs feedback reset'); is($catalog_xmin, '', 'catalog xmin of cascaded slot still null with hs_feedback reset'); - -note "re-enabling hot_standby_feedback and disabling while stopped"; -$node_standby_2->safe_psql('postgres', - 'ALTER SYSTEM SET hot_standby_feedback = on;'); -$node_standby_2->reload; - -$node_master->safe_psql('postgres', qq[INSERT INTO tab_int VALUES (11000);]); -replay_check(); - -$node_standby_2->safe_psql('postgres', - 'ALTER SYSTEM SET hot_standby_feedback = off;'); -$node_standby_2->stop; - -($xmin, $catalog_xmin) = - get_slot_xmins($node_standby_1, $slotname_2, "xmin IS NOT NULL"); -isnt($xmin, '', 'xmin of cascaded slot non-null with postgres shut down'); - -# Xmin from a previous run should be cleared on startup. -$node_standby_2->start; - -($xmin, $catalog_xmin) = - get_slot_xmins($node_standby_1, $slotname_2, "xmin IS NULL"); -is($xmin, '', - 'xmin of cascaded slot reset after startup with hs feedback reset'); diff --git a/src/test/recovery/t/002_archiving.pl b/src/test/recovery/t/002_archiving.pl index e1bd3c95cca..683c33b5100 100644 --- a/src/test/recovery/t/002_archiving.pl +++ b/src/test/recovery/t/002_archiving.pl @@ -3,7 +3,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 1; +use Test::More tests => 3; use File::Copy; # Initialize master node, doing archives @@ -49,3 +49,26 @@ my $result = $node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int"); is($result, qq(1000), 'check content from archives'); + +# Check the presence of temporary files specifically generated during +# archive recovery. To ensure the presence of the temporary history +# file, switch to a timeline large enough to allow a standby to recover +# a history file from an archive. As this requires at least two timeline +# switches, promote the existing standby first. Then create a second +# standby based on the promoted one. Finally, the second standby is +# promoted. +$node_standby->promote; + +my $node_standby2 = get_new_node('standby2'); +$node_standby2->init_from_backup($node_master, $backup_name, + has_restoring => 1); +$node_standby2->start; + +# Now promote standby2, and check that temporary files specifically +# generated during archive recovery are removed by the end of recovery. +$node_standby2->promote; +my $node_standby2_data = $node_standby2->data_dir; +ok( !-f "$node_standby2_data/pg_wal/RECOVERYHISTORY", + "RECOVERYHISTORY removed after promotion"); +ok( !-f "$node_standby2_data/pg_wal/RECOVERYXLOG", + "RECOVERYXLOG removed after promotion"); diff --git a/src/test/recovery/t/003_recovery_targets.pl b/src/test/recovery/t/003_recovery_targets.pl index 824fa4da529..d8fbd500112 100644 --- a/src/test/recovery/t/003_recovery_targets.pl +++ b/src/test/recovery/t/003_recovery_targets.pl @@ -3,7 +3,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 9; +use Test::More tests => 8; # Create and test a standby from given backup, with a certain recovery target. # Choose $until_lsn later than the transaction commit that causes the row @@ -23,7 +23,7 @@ sub test_recovery_standby foreach my $param_item (@$recovery_params) { - $node_standby->append_conf('recovery.conf', qq($param_item)); + $node_standby->append_conf('postgresql.conf', qq($param_item)); } $node_standby->start; @@ -41,6 +41,8 @@ sub test_recovery_standby # Stop standby node $node_standby->teardown_node; + + return; } # Initialize master node @@ -114,30 +116,32 @@ sub test_recovery_standby "5000", $lsn5); # Multiple targets -# Last entry has priority (note that an array respects the order of items -# not hashes). +# +# Multiple conflicting settings are not allowed, but setting the same +# parameter multiple times or unsetting a parameter and setting a +# different one is allowed. + @recovery_params = ( "recovery_target_name = '$recovery_name'", - "recovery_target_xid = '$recovery_txid'", + "recovery_target_name = ''", "recovery_target_time = '$recovery_time'"); -test_recovery_standby('name + XID + time', +test_recovery_standby('multiple overriding settings', 'standby_6', $node_master, \@recovery_params, "3000", $lsn3); -@recovery_params = ( - "recovery_target_time = '$recovery_time'", - "recovery_target_name = '$recovery_name'", - "recovery_target_xid = '$recovery_txid'"); -test_recovery_standby('time + name + XID', - 'standby_7', $node_master, \@recovery_params, "2000", $lsn2); -@recovery_params = ( - "recovery_target_xid = '$recovery_txid'", - "recovery_target_time = '$recovery_time'", - "recovery_target_name = '$recovery_name'"); -test_recovery_standby('XID + time + name', - 'standby_8', $node_master, \@recovery_params, "4000", $lsn4); -@recovery_params = ( - "recovery_target_xid = '$recovery_txid'", - "recovery_target_time = '$recovery_time'", - "recovery_target_name = '$recovery_name'", - "recovery_target_lsn = '$recovery_lsn'",); -test_recovery_standby('XID + time + name + LSN', - 'standby_9', $node_master, \@recovery_params, "5000", $lsn5); + +my $node_standby = get_new_node('standby_7'); +$node_standby->init_from_backup($node_master, 'my_backup', + has_restoring => 1); +$node_standby->append_conf( + 'postgresql.conf', "recovery_target_name = '$recovery_name' +recovery_target_time = '$recovery_time'"); + +my $res = run_log( + [ + 'pg_ctl', '-D', $node_standby->data_dir, '-l', + $node_standby->logfile, 'start' + ]); +ok(!$res, 'invalid recovery startup fails'); + +my $logfile = slurp_file($node_standby->logfile()); +ok($logfile =~ qr/multiple recovery targets specified/, + 'multiple conflicting settings'); diff --git a/src/test/recovery/t/004_timeline_switch.pl b/src/test/recovery/t/004_timeline_switch.pl index 34ee3351296..7e952d36676 100644 --- a/src/test/recovery/t/004_timeline_switch.pl +++ b/src/test/recovery/t/004_timeline_switch.pl @@ -6,7 +6,7 @@ use File::Path qw(rmtree); use PostgresNode; use TestLib; -use Test::More tests => 1; +use Test::More tests => 2; $ENV{PGDATABASE} = 'postgres'; @@ -37,18 +37,22 @@ $node_master->wait_for_catchup($node_standby_1, 'replay', $node_master->lsn('write')); -# Stop and remove master, and promote standby 1, switching it to a new timeline +# Stop and remove master $node_master->teardown_node; -$node_standby_1->promote; + +# promote standby 1 using "pg_promote", switching it to a new timeline +my $psql_out = ''; +$node_standby_1->psql( + 'postgres', + "SELECT pg_promote(wait_seconds => 300)", + stdout => \$psql_out); +is($psql_out, 't', "promotion of standby with pg_promote"); # Switch standby 2 to replay from standby 1 -rmtree($node_standby_2->data_dir . '/recovery.conf'); my $connstr_1 = $node_standby_1->connstr; $node_standby_2->append_conf( - 'recovery.conf', qq( -primary_conninfo='$connstr_1 application_name=@{[$node_standby_2->name]}' -standby_mode=on -recovery_target_timeline='latest' + 'postgresql.conf', qq( +primary_conninfo='$connstr_1' )); $node_standby_2->restart; diff --git a/src/test/recovery/t/005_replay_delay.pl b/src/test/recovery/t/005_replay_delay.pl index 8909c4548bf..6c85c928c10 100644 --- a/src/test/recovery/t/005_replay_delay.pl +++ b/src/test/recovery/t/005_replay_delay.pl @@ -25,7 +25,7 @@ $node_standby->init_from_backup($node_master, $backup_name, has_streaming => 1); $node_standby->append_conf( - 'recovery.conf', qq( + 'postgresql.conf', qq( recovery_min_apply_delay = '${delay}s' )); $node_standby->start; diff --git a/src/test/recovery/t/006_logical_decoding.pl b/src/test/recovery/t/006_logical_decoding.pl index 8b35bc84381..c23cc4dda76 100644 --- a/src/test/recovery/t/006_logical_decoding.pl +++ b/src/test/recovery/t/006_logical_decoding.pl @@ -7,7 +7,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 16; +use Test::More tests => 10; use Config; # Initialize master node @@ -24,10 +24,11 @@ qq[CREATE TABLE decoding_test(x integer, y text);]); $node_master->safe_psql('postgres', -qq[SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding');]); + qq[SELECT pg_create_logical_replication_slot('test_slot', 'test_decoding');] +); $node_master->safe_psql('postgres', -qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;] + qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,10) s;] ); # Basic decoding works @@ -50,7 +51,7 @@ # Insert some rows and verify that we get the same results from pg_recvlogical # and the SQL interface. $node_master->safe_psql('postgres', -qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,4) s;] + qq[INSERT INTO decoding_test(x,y) SELECT s, s::text FROM generate_series(1,4) s;] ); my $expected = q{BEGIN @@ -61,17 +62,17 @@ COMMIT}; my $stdout_sql = $node_master->safe_psql('postgres', -qq[SELECT data FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] + qq[SELECT data FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');] ); is($stdout_sql, $expected, 'got expected output from SQL decoding session'); my $endpos = $node_master->safe_psql('postgres', -"SELECT lsn FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" + "SELECT lsn FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" ); print "waiting to replay $endpos\n"; my $stdout_recv = $node_master->pg_recvlogical_upto( - 'postgres', 'test_slot', $endpos, 10, + 'postgres', 'test_slot', $endpos, 180, 'include-xids' => '0', 'skip-empty-xacts' => '1'); chomp($stdout_recv); @@ -79,12 +80,11 @@ 'got same expected output from pg_recvlogical decoding session'); $node_master->poll_query_until('postgres', -"SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_slot' AND active_pid IS NULL)" -) - or die "slot never became inactive"; + "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'test_slot' AND active_pid IS NULL)" +) or die "slot never became inactive"; $stdout_recv = $node_master->pg_recvlogical_upto( - 'postgres', 'test_slot', $endpos, 10, + 'postgres', 'test_slot', $endpos, 180, 'include-xids' => '0', 'skip-empty-xacts' => '1'); chomp($stdout_recv); @@ -95,27 +95,29 @@ is( $node_master->psql( 'otherdb', -"SELECT lsn FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" + "SELECT lsn FROM pg_logical_slot_peek_changes('test_slot', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" ), 3, 'replaying logical slot from another database fails'); $node_master->safe_psql('otherdb', -qq[SELECT pg_create_logical_replication_slot('otherdb_slot', 'test_decoding');] + qq[SELECT pg_create_logical_replication_slot('otherdb_slot', 'test_decoding');] ); # make sure you can't drop a slot while active SKIP: { - # some Windows Perls at least don't like IPC::Run's start/kill_kill regime. + # some Windows Perls at least don't like IPC::Run's start/kill_kill regime. skip "Test fails on Windows perl", 2 if $Config{osname} eq 'MSWin32'; my $pg_recvlogical = IPC::Run::start( - [ 'pg_recvlogical', '-d', $node_master->connstr('otherdb'), - '-S', 'otherdb_slot', '-f', '-', '--start' ]); + [ + 'pg_recvlogical', '-d', $node_master->connstr('otherdb'), + '-S', 'otherdb_slot', '-f', '-', '--start' + ]); $node_master->poll_query_until('otherdb', -"SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'otherdb_slot' AND active_pid IS NOT NULL)" + "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'otherdb_slot' AND active_pid IS NOT NULL)" ) or die "slot never became active"; is($node_master->psql('postgres', 'DROP DATABASE otherdb'), 3, 'dropping a DB with active logical slots fails'); @@ -125,7 +127,7 @@ } $node_master->poll_query_until('otherdb', -"SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'otherdb_slot' AND active_pid IS NULL)" + "SELECT EXISTS (SELECT 1 FROM pg_replication_slots WHERE slot_name = 'otherdb_slot' AND active_pid IS NULL)" ) or die "slot never became inactive"; is($node_master->psql('postgres', 'DROP DATABASE otherdb'), @@ -133,26 +135,5 @@ is($node_master->slot('otherdb_slot')->{'slot_name'}, undef, 'logical slot was actually dropped with DB'); -# Restarting a node with wal_level = logical that has existing -# slots must succeed, but decoding from those slots must fail. -$node_master->safe_psql('postgres', 'ALTER SYSTEM SET wal_level = replica'); -is($node_master->safe_psql('postgres', 'SHOW wal_level'), - 'logical', 'wal_level is still logical before restart'); -$node_master->restart; -is($node_master->safe_psql('postgres', 'SHOW wal_level'), - 'replica', 'wal_level is replica'); -isnt($node_master->slot('test_slot')->{'catalog_xmin'}, - '0', 'restored slot catalog_xmin is nonzero'); -is( $node_master->psql( - 'postgres', - qq[SELECT pg_logical_slot_get_changes('test_slot', NULL, NULL);]), - 3, - 'reading from slot with wal_level < logical fails'); -is( $node_master->psql( - 'postgres', q[SELECT pg_drop_replication_slot('test_slot')]), - 0, - 'can drop logical slot while wal_level = replica'); -is($node_master->slot('test_slot')->{'catalog_xmin'}, '', 'slot was dropped'); - # done with the node $node_master->stop; diff --git a/src/test/recovery/t/007_sync_rep.pl b/src/test/recovery/t/007_sync_rep.pl index e21d1a52746..05803bed4e3 100644 --- a/src/test/recovery/t/007_sync_rep.pl +++ b/src/test/recovery/t/007_sync_rep.pl @@ -7,7 +7,7 @@ # Query checking sync_priority and sync_state of each standby my $check_sql = -"SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;"; + "SELECT application_name, sync_priority, sync_state FROM pg_stat_replication ORDER BY application_name;"; # Check that sync_state of each standby is expected (waiting till it is). # If $setting is given, synchronous_standby_names is set to it and @@ -18,12 +18,31 @@ sub test_sync_state if (defined($setting)) { - $self->psql('postgres', + $self->safe_psql('postgres', "ALTER SYSTEM SET synchronous_standby_names = '$setting';"); $self->reload; } ok($self->poll_query_until('postgres', $check_sql, $expected), $msg); + return; +} + +# Start a standby and check that it is registered within the WAL sender +# array of the given primary. This polls the primary's pg_stat_replication +# until the standby is confirmed as registered. +sub start_standby_and_wait +{ + my ($master, $standby) = @_; + my $master_name = $master->name; + my $standby_name = $standby->name; + my $query = + "SELECT count(1) = 1 FROM pg_stat_replication WHERE application_name = '$standby_name'"; + + $standby->start; + + print("### Waiting for standby \"$standby_name\" on \"$master_name\"\n"); + $master->poll_query_until('postgres', $query); + return; } # Initialize master node @@ -35,23 +54,26 @@ sub test_sync_state # Take backup $node_master->backup($backup_name); +# Create all the standbys. Their status on the primary is checked to ensure +# the ordering of each one of them in the WAL sender array of the primary. + # Create standby1 linking to master my $node_standby_1 = get_new_node('standby1'); $node_standby_1->init_from_backup($node_master, $backup_name, has_streaming => 1); -$node_standby_1->start; +start_standby_and_wait($node_master, $node_standby_1); # Create standby2 linking to master my $node_standby_2 = get_new_node('standby2'); $node_standby_2->init_from_backup($node_master, $backup_name, has_streaming => 1); -$node_standby_2->start; +start_standby_and_wait($node_master, $node_standby_2); # Create standby3 linking to master my $node_standby_3 = get_new_node('standby3'); $node_standby_3->init_from_backup($node_master, $backup_name, has_streaming => 1); -$node_standby_3->start; +start_standby_and_wait($node_master, $node_standby_3); # Check that sync_state is determined correctly when # synchronous_standby_names is specified in old syntax. @@ -81,8 +103,10 @@ sub test_sync_state $node_standby_2->stop; $node_standby_3->stop; -$node_standby_2->start; -$node_standby_3->start; +# Make sure that each standby reports back to the primary in the wanted +# order. +start_standby_and_wait($node_master, $node_standby_2); +start_standby_and_wait($node_master, $node_standby_3); # Specify 2 as the number of sync standbys. # Check that two standbys are in 'sync' state. @@ -93,7 +117,7 @@ sub test_sync_state '2(standby1,standby2,standby3)'); # Start standby1 -$node_standby_1->start; +start_standby_and_wait($node_master, $node_standby_1); # Create standby4 linking to master my $node_standby_4 = get_new_node('standby4'); @@ -125,14 +149,16 @@ sub test_sync_state # The setting that * comes before another standby name is acceptable # but does not make sense in most cases. Check that sync_state is -# chosen properly even in case of that setting. -# The priority of standby2 should be 2 because it matches * first. +# chosen properly even in case of that setting. standby1 is selected +# as synchronous as it has the highest priority, and is followed by a +# second standby listed first in the WAL sender array, which is +# standby2 in this case. test_sync_state( $node_master, qq(standby1|1|sync standby2|2|sync standby3|2|potential standby4|2|potential), - 'asterisk comes before another standby name', + 'asterisk before another standby name', '2(standby1,*,standby2)'); # Check that the setting of '2(*)' chooses standby2 and standby3 that are stored diff --git a/src/test/recovery/t/009_twophase.pl b/src/test/recovery/t/009_twophase.pl index 95f22bc4210..1b748ad857b 100644 --- a/src/test/recovery/t/009_twophase.pl +++ b/src/test/recovery/t/009_twophase.pl @@ -4,7 +4,7 @@ use PostgresNode; use TestLib; -use Test::More tests => 20; +use Test::More tests => 24; my $psql_out = ''; my $psql_rc = ''; @@ -20,6 +20,7 @@ sub configure_and_reload )); $node->psql('postgres', "SELECT pg_reload_conf()", stdout => \$psql_out); is($psql_out, 't', "reload node $name with $parameter"); + return; } # Set up two nodes, which will alternately be master and replication standby. @@ -228,10 +229,6 @@ sub configure_and_reload # restart old master as new standby $cur_standby->enable_streaming($cur_master); -$cur_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $cur_standby->start; ############################################################################### @@ -266,10 +263,6 @@ sub configure_and_reload # restart old master as new standby $cur_standby->enable_streaming($cur_master); -$cur_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $cur_standby->start; $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_11'"); @@ -306,10 +299,6 @@ sub configure_and_reload # restart old master as new standby $cur_standby->enable_streaming($cur_master); -$cur_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $cur_standby->start; $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_12'"); @@ -333,9 +322,9 @@ sub configure_and_reload # Ensure that last transaction is replayed on standby. my $cur_master_lsn = - $cur_master->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); + $cur_master->safe_psql('postgres', "SELECT pg_current_wal_lsn()"); my $caughtup_query = - "SELECT '$cur_master_lsn'::pg_lsn <= pg_last_wal_replay_lsn()"; + "SELECT '$cur_master_lsn'::pg_lsn <= pg_last_wal_replay_lsn()"; $cur_standby->poll_query_until('postgres', $caughtup_query) or die "Timed out while waiting for standby to catch up"; @@ -345,6 +334,60 @@ sub configure_and_reload stdout => \$psql_out); is($psql_out, '1', "Replay prepared transaction with DDL"); +############################################################################### +# Check recovery of prepared transaction with DDL inside after a hard restart +# of the master. +############################################################################### + +$cur_master->psql( + 'postgres', " + BEGIN; + CREATE TABLE t_009_tbl3 (id int, msg text); + SAVEPOINT s1; + INSERT INTO t_009_tbl3 VALUES (28, 'issued to ${cur_master_name}'); + PREPARE TRANSACTION 'xact_009_14'; + BEGIN; + CREATE TABLE t_009_tbl4 (id int, msg text); + SAVEPOINT s1; + INSERT INTO t_009_tbl4 VALUES (29, 'issued to ${cur_master_name}'); + PREPARE TRANSACTION 'xact_009_15';"); + +$cur_master->teardown_node; +$cur_master->start; + +$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_14'"); +is($psql_rc, '0', 'Commit prepared transaction after teardown'); + +$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_15'"); +is($psql_rc, '0', 'Rollback prepared transaction after teardown'); + +############################################################################### +# Check recovery of prepared transaction with DDL inside after a soft restart +# of the master. +############################################################################### + +$cur_master->psql( + 'postgres', " + BEGIN; + CREATE TABLE t_009_tbl5 (id int, msg text); + SAVEPOINT s1; + INSERT INTO t_009_tbl5 VALUES (30, 'issued to ${cur_master_name}'); + PREPARE TRANSACTION 'xact_009_16'; + BEGIN; + CREATE TABLE t_009_tbl6 (id int, msg text); + SAVEPOINT s1; + INSERT INTO t_009_tbl6 VALUES (31, 'issued to ${cur_master_name}'); + PREPARE TRANSACTION 'xact_009_17';"); + +$cur_master->stop; +$cur_master->start; + +$psql_rc = $cur_master->psql('postgres', "COMMIT PREPARED 'xact_009_16'"); +is($psql_rc, '0', 'Commit prepared transaction after restart'); + +$psql_rc = $cur_master->psql('postgres', "ROLLBACK PREPARED 'xact_009_17'"); +is($psql_rc, '0', 'Rollback prepared transaction after restart'); + ############################################################################### # Verify expected data appears on both servers. ############################################################################### diff --git a/src/test/recovery/t/010_logical_decoding_timelines.pl b/src/test/recovery/t/010_logical_decoding_timelines.pl index 5620450acfe..e582b200050 100644 --- a/src/test/recovery/t/010_logical_decoding_timelines.pl +++ b/src/test/recovery/t/010_logical_decoding_timelines.pl @@ -48,7 +48,7 @@ note "testing logical timeline following with a filesystem-level copy"; $node_master->safe_psql('postgres', -"SELECT pg_create_logical_replication_slot('before_basebackup', 'test_decoding');" + "SELECT pg_create_logical_replication_slot('before_basebackup', 'test_decoding');" ); $node_master->safe_psql('postgres', "CREATE TABLE decoding(blah text);"); $node_master->safe_psql('postgres', @@ -60,7 +60,8 @@ # the same physical copy trick, so: $node_master->safe_psql('postgres', 'CREATE DATABASE dropme;'); $node_master->safe_psql('dropme', -"SELECT pg_create_logical_replication_slot('dropme_slot', 'test_decoding');"); + "SELECT pg_create_logical_replication_slot('dropme_slot', 'test_decoding');" +); $node_master->safe_psql('postgres', 'CHECKPOINT;'); @@ -75,7 +76,7 @@ $node_master, $backup_name, has_streaming => 1, has_restoring => 1); -$node_replica->append_conf('recovery.conf', +$node_replica->append_conf('postgresql.conf', q[primary_slot_name = 'phys_slot']); $node_replica->start; @@ -95,7 +96,7 @@ # Back to testing failover... $node_master->safe_psql('postgres', -"SELECT pg_create_logical_replication_slot('after_basebackup', 'test_decoding');" + "SELECT pg_create_logical_replication_slot('after_basebackup', 'test_decoding');" ); $node_master->safe_psql('postgres', "INSERT INTO decoding(blah) VALUES ('afterbb');"); @@ -141,7 +142,7 @@ # Shouldn't be able to read from slot created after base backup ($ret, $stdout, $stderr) = $node_replica->psql('postgres', -"SELECT data FROM pg_logical_slot_peek_changes('after_basebackup', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');" + "SELECT data FROM pg_logical_slot_peek_changes('after_basebackup', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');" ); is($ret, 3, 'replaying from after_basebackup slot fails'); like( @@ -152,7 +153,7 @@ # Should be able to read from slot created before base backup ($ret, $stdout, $stderr) = $node_replica->psql( 'postgres', -"SELECT data FROM pg_logical_slot_peek_changes('before_basebackup', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');", + "SELECT data FROM pg_logical_slot_peek_changes('before_basebackup', NULL, NULL, 'include-xids', '0', 'skip-empty-xacts', '1');", timeout => 30); is($ret, 0, 'replay from slot before_basebackup succeeds'); @@ -174,7 +175,7 @@ BEGIN # of the last transaction. There's no max(pg_lsn), so: my $endpos = $node_replica->safe_psql('postgres', -"SELECT lsn FROM pg_logical_slot_peek_changes('before_basebackup', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" + "SELECT lsn FROM pg_logical_slot_peek_changes('before_basebackup', NULL, NULL) ORDER BY lsn DESC LIMIT 1;" ); # now use the walsender protocol to peek the slot changes and make sure we see @@ -182,7 +183,7 @@ BEGIN $stdout = $node_replica->pg_recvlogical_upto( 'postgres', 'before_basebackup', - $endpos, 30, + $endpos, 180, 'include-xids' => '0', 'skip-empty-xacts' => '1'); diff --git a/src/test/recovery/t/011_crash_recovery.pl b/src/test/recovery/t/011_crash_recovery.pl index 7afa94a8274..526a3481fb5 100644 --- a/src/test/recovery/t/011_crash_recovery.pl +++ b/src/test/recovery/t/011_crash_recovery.pl @@ -10,7 +10,7 @@ if ($Config{osname} eq 'MSWin32') { - # some Windows Perls at least don't like IPC::Run's start/kill_kill regime. + # some Windows Perls at least don't like IPC::Run's start/kill_kill regime. plan skip_all => "Test fails on Windows perl"; } else @@ -29,8 +29,10 @@ # an xact to be in-progress when we crash and we need to know # its xid. my $tx = IPC::Run::start( - [ 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', - $node->connstr('postgres') ], + [ + 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', + $node->connstr('postgres') + ], '<', \$stdin, '>', @@ -49,7 +51,7 @@ chomp($xid); is($node->safe_psql('postgres', qq[SELECT txid_status('$xid');]), - 'in progress', 'own xid is in-progres'); + 'in progress', 'own xid is in-progress'); # Crash and restart the postmaster $node->stop('immediate'); diff --git a/src/test/recovery/t/012_subtransactions.pl b/src/test/recovery/t/012_subtransactions.pl index 216c3331d6b..292cd40fe2d 100644 --- a/src/test/recovery/t/012_subtransactions.pl +++ b/src/test/recovery/t/012_subtransactions.pl @@ -76,7 +76,7 @@ ############################################################################### # Check that replay will correctly set 2PC with more than -# PGPROC_MAX_CACHED_SUBXIDS subtransations and also show data properly +# PGPROC_MAX_CACHED_SUBXIDS subtransactions and also show data properly # on promotion ############################################################################### $node_master->psql('postgres', "DELETE FROM t_012_tbl"); @@ -119,10 +119,6 @@ # restore state ($node_master, $node_standby) = ($node_standby, $node_master); $node_standby->enable_streaming($node_master); -$node_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $node_standby->start; $node_standby->psql( 'postgres', @@ -170,14 +166,10 @@ # restore state ($node_master, $node_standby) = ($node_standby, $node_master); $node_standby->enable_streaming($node_master); -$node_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $node_standby->start; $psql_rc = $node_master->psql('postgres', "COMMIT PREPARED 'xact_012_1'"); is($psql_rc, '0', -"Restore of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted standby" + "Restore of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted standby" ); $node_master->psql( @@ -211,14 +203,10 @@ # restore state ($node_master, $node_standby) = ($node_standby, $node_master); $node_standby->enable_streaming($node_master); -$node_standby->append_conf( - 'recovery.conf', qq( -recovery_target_timeline='latest' -)); $node_standby->start; $psql_rc = $node_master->psql('postgres', "ROLLBACK PREPARED 'xact_012_1'"); is($psql_rc, '0', -"Rollback of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted standby" + "Rollback of PGPROC_MAX_CACHED_SUBXIDS+ prepared transaction on promoted standby" ); $node_master->psql( diff --git a/src/test/recovery/t/013_crash_restart.pl b/src/test/recovery/t/013_crash_restart.pl index 91a8ef90c16..2c477978e7d 100644 --- a/src/test/recovery/t/013_crash_restart.pl +++ b/src/test/recovery/t/013_crash_restart.pl @@ -30,16 +30,19 @@ $node->start(); # by default PostgresNode doesn't doesn't restart after a crash -$node->safe_psql('postgres', - q[ALTER SYSTEM SET restart_after_crash = 1; +$node->safe_psql( + 'postgres', + q[ALTER SYSTEM SET restart_after_crash = 1; ALTER SYSTEM SET log_connections = 1; SELECT pg_reload_conf();]); # Run psql, keeping session alive, so we have an alive backend to kill. my ($killme_stdin, $killme_stdout, $killme_stderr) = ('', '', ''); my $killme = IPC::Run::start( - [ 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', - $node->connstr('postgres') ], + [ + 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', + $node->connstr('postgres') + ], '<', \$killme_stdin, '>', @@ -51,8 +54,10 @@ # Need a second psql to check if crash-restart happened. my ($monitor_stdin, $monitor_stdout, $monitor_stderr) = ('', '', ''); my $monitor = IPC::Run::start( - [ 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', - $node->connstr('postgres') ], + [ + 'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d', + $node->connstr('postgres') + ], '<', \$monitor_stdin, '>', @@ -68,7 +73,7 @@ SELECT pg_backend_pid(); ]; ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m), - 'acquired pid for SIGQUIT'); + 'acquired pid for SIGQUIT'); my $pid = $killme_stdout; chomp($pid); $killme_stdout = ''; @@ -80,20 +85,20 @@ INSERT INTO alive VALUES($$in-progress-before-sigquit$$) RETURNING status; ]; ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigquit/m), - 'inserted in-progress-before-sigquit'); + 'inserted in-progress-before-sigquit'); $killme_stdout = ''; $killme_stderr = ''; -# Start longrunning query in second session, it's failure will signal -# that crash-restart has occurred. The initial wait for the trivial -# select is to be sure that psql successfully connected to backend. +# Start longrunning query in second session; its failure will signal that +# crash-restart has occurred. The initial wait for the trivial select is to +# be sure that psql successfully connected to backend. $monitor_stdin .= q[ SELECT $$psql-connected$$; SELECT pg_sleep(3600); ]; ok(pump_until($monitor, \$monitor_stdout, qr/psql-connected/m), - 'monitor connected'); + 'monitor connected'); $monitor_stdout = ''; $monitor_stderr = ''; @@ -107,8 +112,12 @@ $killme_stdin .= q[ SELECT 1; ]; -ok(pump_until($killme, \$killme_stderr, qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly/m), - "psql query died successfully after SIGQUIT"); +ok( pump_until( + $killme, + \$killme_stderr, + qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m + ), + "psql query died successfully after SIGQUIT"); $killme_stderr = ''; $killme_stdout = ''; $killme->finish; @@ -116,13 +125,21 @@ # Wait till server restarts - we should get the WARNING here, but # sometimes the server is unable to send that, if interrupted while # sending. -ok(pump_until($monitor, \$monitor_stderr, qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly/m), - "psql monitor died successfully after SIGQUIT"); +ok( pump_until( + $monitor, + \$monitor_stderr, + qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m + ), + "psql monitor died successfully after SIGQUIT"); $monitor->finish; # Wait till server restarts -is($node->poll_query_until('postgres', 'SELECT $$restarted after sigquit$$;', 'restarted after sigquit'), - "1", "reconnected after SIGQUIT"); +is( $node->poll_query_until( + 'postgres', + 'SELECT $$restarted after sigquit$$;', + 'restarted after sigquit'), + "1", + "reconnected after SIGQUIT"); # restart psql processes, now that the crash cycle finished @@ -137,10 +154,9 @@ SELECT pg_backend_pid(); ]; ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m), - "acquired pid for SIGKILL"); + "acquired pid for SIGKILL"); $pid = $killme_stdout; chomp($pid); -$pid = $killme_stdout; $killme_stdout = ''; $killme_stderr = ''; @@ -151,26 +167,25 @@ INSERT INTO alive VALUES($$in-progress-before-sigkill$$) RETURNING status; ]; ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigkill/m), - 'inserted in-progress-before-sigkill'); + 'inserted in-progress-before-sigkill'); $killme_stdout = ''; $killme_stderr = ''; -# Re-start longrunning query in second session, it's failure will -# signal that crash-restart has occurred. The initial wait for the -# trivial select is to be sure that psql successfully connected to -# backend. -$monitor_stdin = q[ +# Re-start longrunning query in second session; its failure will signal that +# crash-restart has occurred. The initial wait for the trivial select is to +# be sure that psql successfully connected to backend. +$monitor_stdin .= q[ SELECT $$psql-connected$$; SELECT pg_sleep(3600); ]; ok(pump_until($monitor, \$monitor_stdout, qr/psql-connected/m), - 'monitor connected'); + 'monitor connected'); $monitor_stdout = ''; $monitor_stderr = ''; # kill with SIGKILL this time - we expect the backend to exit, without -# being able to emit an error error message +# being able to emit an error message $ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid); is($ret, 0, "killed process with KILL"); @@ -179,35 +194,54 @@ $killme_stdin .= q[ SELECT 1; ]; -ok(pump_until($killme, \$killme_stderr, qr/server closed the connection unexpectedly/m), - "psql query died successfully after SIGKILL"); +ok( pump_until( + $killme, + \$killme_stderr, + qr/server closed the connection unexpectedly|connection to server was lost/m + ), + "psql query died successfully after SIGKILL"); $killme->finish; # Wait till server restarts - we should get the WARNING here, but # sometimes the server is unable to send that, if interrupted while # sending. -ok(pump_until($monitor, \$monitor_stderr, qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly/m), - "psql monitor died successfully after SIGKILL"); +ok( pump_until( + $monitor, + \$monitor_stderr, + qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m + ), + "psql monitor died successfully after SIGKILL"); $monitor->finish; # Wait till server restarts -is($node->poll_query_until('postgres', 'SELECT 1', '1'), "1", "reconnected after SIGKILL"); +is($node->poll_query_until('postgres', 'SELECT 1', '1'), + "1", "reconnected after SIGKILL"); # Make sure the committed rows survived, in-progress ones not -is($node->safe_psql('postgres', 'SELECT * FROM alive'), - "committed-before-sigquit\ncommitted-before-sigkill", 'data survived'); +is( $node->safe_psql('postgres', 'SELECT * FROM alive'), + "committed-before-sigquit\ncommitted-before-sigkill", + 'data survived'); -is($node->safe_psql('postgres', 'INSERT INTO alive VALUES($$before-orderly-restart$$) RETURNING status'), - 'before-orderly-restart', 'can still write after crash restart'); +is( $node->safe_psql( + 'postgres', + 'INSERT INTO alive VALUES($$before-orderly-restart$$) RETURNING status' + ), + 'before-orderly-restart', + 'can still write after crash restart'); # Just to be sure, check that an orderly restart now still works $node->restart(); -is($node->safe_psql('postgres', 'SELECT * FROM alive'), - "committed-before-sigquit\ncommitted-before-sigkill\nbefore-orderly-restart", 'data survived'); +is( $node->safe_psql('postgres', 'SELECT * FROM alive'), + "committed-before-sigquit\ncommitted-before-sigkill\nbefore-orderly-restart", + 'data survived'); -is($node->safe_psql('postgres', 'INSERT INTO alive VALUES($$after-orderly-restart$$) RETURNING status'), - 'after-orderly-restart', 'can still write after orderly restart'); +is( $node->safe_psql( + 'postgres', + 'INSERT INTO alive VALUES($$after-orderly-restart$$) RETURNING status' + ), + 'after-orderly-restart', + 'can still write after orderly restart'); $node->stop(); @@ -218,10 +252,11 @@ sub pump_until $proc->pump_nb(); while (1) { + last if $$stream =~ /$untl/; if ($psql_timeout->is_expired) { diag("aborting wait: program timed out"); - diag("stream contents: >>", $$stream,"<<"); + diag("stream contents: >>", $$stream, "<<"); diag("pattern searched for: ", $untl); return 0; @@ -229,14 +264,13 @@ sub pump_until if (not $proc->pumpable()) { diag("aborting wait: program died"); - diag("stream contents: >>", $$stream,"<<"); + diag("stream contents: >>", $$stream, "<<"); diag("pattern searched for: ", $untl); return 0; } $proc->pump(); - last if $$stream =~ /$untl/; } return 1; -}; +} diff --git a/src/test/recovery/t/014_unlogged_reinit.pl b/src/test/recovery/t/014_unlogged_reinit.pl index 446144a7836..ee05e1a1ee1 100644 --- a/src/test/recovery/t/014_unlogged_reinit.pl +++ b/src/test/recovery/t/014_unlogged_reinit.pl @@ -30,10 +30,9 @@ my $tablespaceDir = TestLib::tempdir; -my $realTSDir = TestLib::real_dir($tablespaceDir); +my $realTSDir = TestLib::perl2host($tablespaceDir); -$node->safe_psql('postgres', - "CREATE TABLESPACE ts1 LOCATION '$realTSDir'"); +$node->safe_psql('postgres', "CREATE TABLESPACE ts1 LOCATION '$realTSDir'"); $node->safe_psql('postgres', 'CREATE UNLOGGED TABLE ts1_unlogged (id int) TABLESPACE ts1'); @@ -64,11 +63,9 @@ $node->start; # check unlogged table in base -ok(-f "$pgdata/${baseUnloggedPath}_init", - 'init fork in base still exists'); -ok(-f "$pgdata/$baseUnloggedPath", - 'main fork in base recreated at startup'); -ok( !-f "$pgdata/${baseUnloggedPath}_vm", +ok(-f "$pgdata/${baseUnloggedPath}_init", 'init fork in base still exists'); +ok(-f "$pgdata/$baseUnloggedPath", 'main fork in base recreated at startup'); +ok(!-f "$pgdata/${baseUnloggedPath}_vm", 'vm fork in base removed at startup'); ok( !-f "$pgdata/${baseUnloggedPath}_fsm", 'fsm fork in base removed at startup'); diff --git a/src/test/recovery/t/015_promotion_pages.pl b/src/test/recovery/t/015_promotion_pages.pl new file mode 100644 index 00000000000..6fb70b5001b --- /dev/null +++ b/src/test/recovery/t/015_promotion_pages.pl @@ -0,0 +1,85 @@ +# Test for promotion handling with WAL records generated post-promotion +# before the first checkpoint is generated. This test case checks for +# invalid page references at replay based on the minimum consistent +# recovery point defined. +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 1; + +# Initialize primary node +my $alpha = get_new_node('alpha'); +$alpha->init(allows_streaming => 1); +# Setting wal_log_hints to off is important to get invalid page +# references. +$alpha->append_conf("postgresql.conf", <start; + +# setup/start a standby +$alpha->backup('bkp'); +my $bravo = get_new_node('bravo'); +$bravo->init_from_backup($alpha, 'bkp', has_streaming => 1); +$bravo->append_conf('postgresql.conf', <start; + +# Dummy table for the upcoming tests. +$alpha->safe_psql('postgres', 'create table test1 (a int)'); +$alpha->safe_psql('postgres', + 'insert into test1 select generate_series(1, 10000)'); + +# take a checkpoint +$alpha->safe_psql('postgres', 'checkpoint'); + +# The following vacuum will set visibility map bits and create +# problematic WAL records. +$alpha->safe_psql('postgres', 'vacuum verbose test1'); +# Wait for last record to have been replayed on the standby. +$alpha->wait_for_catchup($bravo, 'replay', $alpha->lsn('insert')); + +# Now force a checkpoint on the standby. This seems unnecessary but for "some" +# reason, the previous checkpoint on the primary does not reflect on the standby +# and without an explicit checkpoint, it may start redo recovery from a much +# older point, which includes even create table and initial page additions. +$bravo->safe_psql('postgres', 'checkpoint'); + +# Now just use a dummy table and run some operations to move minRecoveryPoint +# beyond the previous vacuum. +$alpha->safe_psql('postgres', 'create table test2 (a int, b text)'); +$alpha->safe_psql('postgres', + 'insert into test2 select generate_series(1,10000), md5(random()::text)'); +$alpha->safe_psql('postgres', 'truncate test2'); + +# Wait again for all records to be replayed. +$alpha->wait_for_catchup($bravo, 'replay', $alpha->lsn('insert')); + +# Do the promotion, which reinitializes minRecoveryPoint in the control +# file so as WAL is replayed up to the end. +$bravo->promote; + +# Truncate the table on the promoted standby, vacuum and extend it +# again to create new page references. The first post-recovery checkpoint +# has not happened yet. +$bravo->safe_psql('postgres', 'truncate test1'); +$bravo->safe_psql('postgres', 'vacuum verbose test1'); +$bravo->safe_psql('postgres', + 'insert into test1 select generate_series(1,1000)'); + +# Now crash-stop the promoted standby and restart. This makes sure that +# replay does not see invalid page references because of an invalid +# minimum consistent recovery point. +$bravo->stop('immediate'); +$bravo->start; + +# Check state of the table after full crash recovery. All its data should +# be here. +my $psql_out; +$bravo->psql('postgres', "SELECT count(*) FROM test1", stdout => \$psql_out); +is($psql_out, '1000', "Check that table state is correct"); diff --git a/src/test/recovery/t/016_min_consistency.pl b/src/test/recovery/t/016_min_consistency.pl new file mode 100644 index 00000000000..707538b9869 --- /dev/null +++ b/src/test/recovery/t/016_min_consistency.pl @@ -0,0 +1,138 @@ +# Test for checking consistency of on-disk pages for a cluster with +# the minimum recovery LSN, ensuring that the updates happen across +# all processes. In this test, the updates from the startup process +# and the checkpointer (which triggers non-startup code paths) are +# both checked. + +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 1; + +# Find the largest LSN in the set of pages part of the given relation +# file. This is used for offline checks of page consistency. The LSN +# is historically stored as a set of two numbers of 4 byte-length +# located at the beginning of each page. +sub find_largest_lsn +{ + my $blocksize = int(shift); + my $filename = shift; + my ($max_hi, $max_lo) = (0, 0); + open(my $fh, "<:raw", $filename) + or die "failed to open $filename: $!"; + my ($buf, $len); + while ($len = read($fh, $buf, $blocksize)) + { + $len == $blocksize + or die "read only $len of $blocksize bytes from $filename"; + my ($hi, $lo) = unpack("LL", $buf); + + if ($hi > $max_hi or ($hi == $max_hi and $lo > $max_lo)) + { + ($max_hi, $max_lo) = ($hi, $lo); + } + } + defined($len) or die "read error on $filename: $!"; + close($fh); + + return sprintf("%X/%X", $max_hi, $max_lo); +} + +# Initialize primary node +my $primary = get_new_node('primary'); +$primary->init(allows_streaming => 1); + +# Set shared_buffers to a very low value to enforce discard and flush +# of PostgreSQL buffers on standby, enforcing other processes than the +# startup process to update the minimum recovery LSN in the control +# file. Autovacuum is disabled so as there is no risk of having other +# processes than the checkpointer doing page flushes. +$primary->append_conf("postgresql.conf", <start; + +# setup/start a standby +$primary->backup('bkp'); +my $standby = get_new_node('standby'); +$standby->init_from_backup($primary, 'bkp', has_streaming => 1); +$standby->start; + +# Create base table whose data consistency is checked. +$primary->safe_psql( + 'postgres', " +CREATE TABLE test1 (a int) WITH (fillfactor = 10); +INSERT INTO test1 SELECT generate_series(1, 10000);"); + +# Take a checkpoint and enforce post-checkpoint full page writes +# which makes the startup process replay those pages, updating +# minRecoveryPoint. +$primary->safe_psql('postgres', 'CHECKPOINT;'); +$primary->safe_psql('postgres', 'UPDATE test1 SET a = a + 1;'); + +# Wait for last record to have been replayed on the standby. +$primary->wait_for_catchup($standby, 'replay', $primary->lsn('insert')); + +# Fill in the standby's shared buffers with the data filled in +# previously. +$standby->safe_psql('postgres', 'SELECT count(*) FROM test1;'); + +# Update the table again, this does not generate full page writes so +# the standby will replay records associated with it, but the startup +# process will not flush those pages. +$primary->safe_psql('postgres', 'UPDATE test1 SET a = a + 1;'); + +# Extract from the relation the last block created and its relation +# file, this will be used at the end of the test for sanity checks. +my $blocksize = $primary->safe_psql('postgres', + "SELECT setting::int FROM pg_settings WHERE name = 'block_size';"); +my $last_block = $primary->safe_psql('postgres', + "SELECT pg_relation_size('test1')::int / $blocksize - 1;"); +my $relfilenode = $primary->safe_psql('postgres', + "SELECT pg_relation_filepath('test1'::regclass);"); + +# Wait for last record to have been replayed on the standby. +$primary->wait_for_catchup($standby, 'replay', $primary->lsn('insert')); + +# Issue a restart point on the standby now, which makes the checkpointer +# update minRecoveryPoint. +$standby->safe_psql('postgres', 'CHECKPOINT;'); + +# Now shut down the primary violently so as the standby does not +# receive the shutdown checkpoint, making sure that the startup +# process does not flush any pages on its side. The standby is +# cleanly stopped, which makes the checkpointer update minRecoveryPoint +# with the restart point created at shutdown. +$primary->stop('immediate'); +$standby->stop('fast'); + +# Check the data consistency of the instance while offline. This is +# done by directly scanning the on-disk relation blocks and what +# pg_controldata lets know. +my $standby_data = $standby->data_dir; +my $offline_max_lsn = + find_largest_lsn($blocksize, "$standby_data/$relfilenode"); + +# Fetch minRecoveryPoint from the control file itself +my ($stdout, $stderr) = run_command([ 'pg_controldata', $standby_data ]); +my @control_data = split("\n", $stdout); +my $offline_recovery_lsn = undef; +foreach (@control_data) +{ + if ($_ =~ /^Minimum recovery ending location:\s*(.*)$/mg) + { + $offline_recovery_lsn = $1; + last; + } +} +die "No minRecoveryPoint in control file found\n" + unless defined($offline_recovery_lsn); + +# minRecoveryPoint should never be older than the maximum LSN for all +# the pages on disk. +ok($offline_recovery_lsn ge $offline_max_lsn, + "Check offline that table data is consistent with minRecoveryPoint"); diff --git a/src/test/recovery/t/017_shm.pl b/src/test/recovery/t/017_shm.pl new file mode 100644 index 00000000000..dc0dcd3ca27 --- /dev/null +++ b/src/test/recovery/t/017_shm.pl @@ -0,0 +1,214 @@ +# +# Tests of pg_shmem.h functions +# +use strict; +use warnings; +use Config; +use File::stat qw(stat); +use IPC::Run 'run'; +use PostgresNode; +use Test::More; +use TestLib; +use Time::HiRes qw(usleep); + +# If we don't have shmem support, skip the whole thing +eval { + require IPC::SharedMem; + IPC::SharedMem->import; + require IPC::SysV; + IPC::SysV->import(qw(IPC_CREAT IPC_EXCL S_IRUSR S_IWUSR)); +}; +if ($@ || $windows_os) +{ + plan skip_all => 'SysV shared memory not supported by this platform'; +} +else +{ + plan tests => 4; +} + +my $tempdir = TestLib::tempdir; + +# Log "ipcs" diffs on a best-effort basis, swallowing any error. +my $ipcs_before = "$tempdir/ipcs_before"; +eval { run_log [ 'ipcs', '-am' ], '>', $ipcs_before; }; + +sub log_ipcs +{ + eval { run_log [ 'ipcs', '-am' ], '|', [ 'diff', $ipcs_before, '-' ] }; + return; +} + +# Node setup. +my $gnat = PostgresNode->get_new_node('gnat'); +$gnat->init; + +# Create a shmem segment that will conflict with gnat's first choice +# of shmem key. (If we fail to create it because something else is +# already using that key, that's perfectly fine, though the test will +# exercise a different scenario than it usually does.) +my $gnat_dir_stat = stat($gnat->data_dir); +defined($gnat_dir_stat) or die('unable to stat ' . $gnat->data_dir); +my $gnat_inode = $gnat_dir_stat->ino; +note "gnat's datadir inode = $gnat_inode"; + +# Note: must reference IPC::SysV's constants as functions, or this file +# fails to compile when that module is not available. +my $gnat_conflict_shm = + IPC::SharedMem->new($gnat_inode, 1024, + IPC_CREAT() | IPC_EXCL() | S_IRUSR() | S_IWUSR()); +note "could not create conflicting shmem" if !defined($gnat_conflict_shm); +log_ipcs(); + +$gnat->start; +log_ipcs(); + +$gnat->restart; # should keep same shmem key +log_ipcs(); + +# Upon postmaster death, postmaster children exit automatically. +$gnat->kill9; +log_ipcs(); +poll_start($gnat); # gnat recycles its former shm key. +log_ipcs(); + +note "removing the conflicting shmem ..."; +$gnat_conflict_shm->remove if $gnat_conflict_shm; +log_ipcs(); + +# Upon postmaster death, postmaster children exit automatically. +$gnat->kill9; +log_ipcs(); + +# In this start, gnat will use its normal shmem key, and fail to remove +# the higher-keyed segment that the previous postmaster was using. +# That's not great, but key collisions should be rare enough to not +# make this a big problem. +poll_start($gnat); +log_ipcs(); +$gnat->stop; +log_ipcs(); + +# Re-create the conflicting segment, and start/stop normally, just so +# this test script doesn't leak the higher-keyed segment. +note "re-creating conflicting shmem ..."; +$gnat_conflict_shm = + IPC::SharedMem->new($gnat_inode, 1024, + IPC_CREAT() | IPC_EXCL() | S_IRUSR() | S_IWUSR()); +note "could not create conflicting shmem" if !defined($gnat_conflict_shm); +log_ipcs(); + +$gnat->start; +log_ipcs(); +$gnat->stop; +log_ipcs(); + +note "removing the conflicting shmem ..."; +$gnat_conflict_shm->remove if $gnat_conflict_shm; +log_ipcs(); + +# Scenarios involving no postmaster.pid, dead postmaster, and a live backend. +# Use a regress.c function to emulate the responsiveness of a backend working +# through a CPU-intensive task. +$gnat->start; +log_ipcs(); + +my $regress_shlib = TestLib::perl2host($ENV{REGRESS_SHLIB}); +$gnat->safe_psql('postgres', <connstr('postgres'), + '-c', $slow_query + ], + '<', + \undef, + '>', + \$stdout, + '2>', + \$stderr, + IPC::Run::timeout(900)); # five times the poll_query_until timeout +ok( $gnat->poll_query_until( + 'postgres', + "SELECT 1 FROM pg_stat_activity WHERE query = '$slow_query'", '1'), + 'slow query started'); +my $slow_pid = $gnat->safe_psql('postgres', + "SELECT pid FROM pg_stat_activity WHERE query = '$slow_query'"); +$gnat->kill9; +unlink($gnat->data_dir . '/postmaster.pid'); +$gnat->rotate_logfile; # on Windows, can't open old log for writing +log_ipcs(); +# Reject ordinary startup. Retry for the same reasons poll_start() does. +my $pre_existing_msg = qr/pre-existing shared memory block/; +{ + my $max_attempts = 180 * 10; # Retry every 0.1s for at least 180s. + my $attempts = 0; + while ($attempts < $max_attempts) + { + last + if $gnat->start(fail_ok => 1) + || slurp_file($gnat->logfile) =~ $pre_existing_msg; + usleep(100_000); + $attempts++; + } +} +like(slurp_file($gnat->logfile), + $pre_existing_msg, 'detected live backend via shared memory'); +# Reject single-user startup. +my $single_stderr; +ok( !run_log( + [ 'postgres', '--single', '-D', $gnat->data_dir, 'template1' ], + '<', \undef, '2>', \$single_stderr), + 'live query blocks --single'); +print STDERR $single_stderr; +like($single_stderr, $pre_existing_msg, + 'single-user mode detected live backend via shared memory'); +log_ipcs(); + +# cleanup slow backend +TestLib::system_log('pg_ctl', 'kill', 'QUIT', $slow_pid); +$slow_client->finish; # client has detected backend termination +log_ipcs(); + +# now startup should work +poll_start($gnat); +log_ipcs(); + +# finish testing +$gnat->stop; +log_ipcs(); + + +# We may need retries to start a new postmaster. Causes: +# - kernel is slow to deliver SIGKILL +# - postmaster parent is slow to waitpid() +# - postmaster child is slow to exit in response to SIGQUIT +# - postmaster child is slow to exit after postmaster death +sub poll_start +{ + my ($node) = @_; + + my $max_attempts = 180 * 10; + my $attempts = 0; + + while ($attempts < $max_attempts) + { + $node->start(fail_ok => 1) && return 1; + + # Wait 0.1 second before retrying. + usleep(100_000); + + $attempts++; + } + + # No success within 180 seconds. Try one last time without fail_ok, which + # will BAIL_OUT unless it succeeds. + $node->start && return 1; + return 0; +} diff --git a/src/test/regress/.gitignore b/src/test/regress/.gitignore index 173f995d240..89129d7358a 100644 --- a/src/test/regress/.gitignore +++ b/src/test/regress/.gitignore @@ -6,6 +6,6 @@ /results/ /log/ -# Note: regreesion.* are only left behind on a failure; that's why they're not ignored +# Note: regression.* are only left behind on a failure; that's why they're not ignored #/regression.diffs #/regression.out diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile index 7ba4e9c5abb..a24cfd4e016 100644 --- a/src/test/regress/GNUmakefile +++ b/src/test/regress/GNUmakefile @@ -3,7 +3,7 @@ # GNUmakefile-- # Makefile for src/test/regress (the regression tests) # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/regress/GNUmakefile @@ -43,7 +43,8 @@ pg_regress$(X): pg_regress.o pg_regress_main.o $(WIN32RES) | submake-libpgport pg_regress.o: pg_regress.c $(top_builddir)/src/port/pg_config_paths.h pg_regress.o: override CPPFLAGS += -I$(top_builddir)/src/port $(EXTRADEFS) -$(top_builddir)/src/port/pg_config_paths.h: $(top_builddir)/src/Makefile.global +# note: because of the submake dependency, this rule's action is really a no-op +$(top_builddir)/src/port/pg_config_paths.h: | submake-libpgport $(MAKE) -C $(top_builddir)/src/port pg_config_paths.h install: all installdirs @@ -65,6 +66,9 @@ include $(top_srcdir)/src/Makefile.shlib all: all-lib +# Ensure parallel safety if a build is started in this directory +$(OBJS): | submake-libpgport submake-generated-headers + # Test input and expected files. These are created by pg_regress itself, so we # don't have a rule to create them. We do need rules to clean them however. input_files = $(patsubst $(srcdir)/input/%.source,sql/%.sql, $(wildcard $(srcdir)/input/*.source)) @@ -105,7 +109,7 @@ $(top_builddir)/contrib/spi/refint$(DLSUFFIX): | submake-contrib-spi ; $(top_builddir)/contrib/spi/autoinc$(DLSUFFIX): | submake-contrib-spi ; -submake-contrib-spi: | submake-libpgport +submake-contrib-spi: | submake-libpgport submake-generated-headers $(MAKE) -C $(top_builddir)/contrib/spi .PHONY: submake-contrib-spi diff --git a/src/test/regress/expected/abstime.out b/src/test/regress/expected/abstime.out deleted file mode 100644 index ed48f642ab3..00000000000 --- a/src/test/regress/expected/abstime.out +++ /dev/null @@ -1,136 +0,0 @@ --- --- ABSTIME --- testing built-in time type abstime --- uses reltime and tinterval --- --- --- timezones may vary based not only on location but the operating --- system. the main correctness issue is that the OS may not get --- daylight savings time right for times prior to Unix epoch (jan 1 1970). --- -CREATE TABLE ABSTIME_TBL (f1 abstime); -BEGIN; -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now'); -SELECT count(*) AS two FROM ABSTIME_TBL WHERE f1 = 'now' ; - two ------ - 2 -(1 row) - -END; -DELETE FROM ABSTIME_TBL; -INSERT INTO ABSTIME_TBL (f1) VALUES ('Jan 14, 1973 03:14:21'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'Mon May 1 00:30:30 1995'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'epoch'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'infinity'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime '-infinity'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'May 10, 1947 23:59:12'); --- what happens if we specify slightly misformatted abstime? -INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00'); -ERROR: date/time field value out of range: "Feb 35, 1946 10:00:00" -LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00'... - ^ -HINT: Perhaps you need a different "datestyle" setting. -INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10'); -ERROR: date/time field value out of range: "Feb 28, 1984 25:08:10" -LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10'... - ^ --- badly formatted abstimes: these should result in invalid abstimes -INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format'); -ERROR: invalid input syntax for type abstime: "bad date format" -LINE 1: INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format'); - ^ -INSERT INTO ABSTIME_TBL (f1) VALUES ('Jun 10, 1843'); --- test abstime operators -SELECT '' AS eight, * FROM ABSTIME_TBL; - eight | f1 --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST - | infinity - | -infinity - | Sat May 10 23:59:12 1947 PST - | invalid -(7 rows) - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 < abstime 'Jun 30, 2001'; - six | f1 ------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST - | -infinity - | Sat May 10 23:59:12 1947 PST -(5 rows) - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 > abstime '-infinity'; - six | f1 ------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST - | infinity - | Sat May 10 23:59:12 1947 PST - | invalid -(6 rows) - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE abstime 'May 10, 1947 23:59:12' <> ABSTIME_TBL.f1; - six | f1 ------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST - | infinity - | -infinity - | invalid -(6 rows) - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE abstime 'epoch' >= ABSTIME_TBL.f1; - three | f1 --------+------------------------------ - | Wed Dec 31 16:00:00 1969 PST - | -infinity - | Sat May 10 23:59:12 1947 PST -(3 rows) - -SELECT '' AS four, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 <= abstime 'Jan 14, 1973 03:14:21'; - four | f1 -------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Wed Dec 31 16:00:00 1969 PST - | -infinity - | Sat May 10 23:59:12 1947 PST -(4 rows) - -SELECT '' AS four, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 - tinterval '["Apr 1 1950 00:00:00" "Dec 30 1999 23:00:00"]'; - four | f1 -------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST -(3 rows) - -SELECT '' AS four, f1 AS abstime, - date_part('year', f1) AS year, date_part('month', f1) AS month, - date_part('day',f1) AS day, date_part('hour', f1) AS hour, - date_part('minute', f1) AS minute, date_part('second', f1) AS second - FROM ABSTIME_TBL - WHERE isfinite(f1) - ORDER BY abstime; - four | abstime | year | month | day | hour | minute | second -------+------------------------------+------+-------+-----+------+--------+-------- - | Sat May 10 23:59:12 1947 PST | 1947 | 5 | 10 | 23 | 59 | 12 - | Wed Dec 31 16:00:00 1969 PST | 1969 | 12 | 31 | 16 | 0 | 0 - | Sun Jan 14 03:14:21 1973 PST | 1973 | 1 | 14 | 3 | 14 | 21 - | Mon May 01 00:30:30 1995 PDT | 1995 | 5 | 1 | 0 | 30 | 30 -(4 rows) - diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out index f85e9138504..be4ddf86a43 100644 --- a/src/test/regress/expected/aggregates.out +++ b/src/test/regress/expected/aggregates.out @@ -1,6 +1,8 @@ -- -- AGGREGATES -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; SELECT avg(four) AS avg_1 FROM onek; avg_1 -------------------- @@ -198,6 +200,50 @@ select avg('NaN'::numeric) from generate_series(1,3); NaN (1 row) +-- verify correct results for infinite inputs +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('1'), ('infinity')) v(x); + avg | var_pop +----------+--------- + Infinity | NaN +(1 row) + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('1')) v(x); + avg | var_pop +----------+--------- + Infinity | NaN +(1 row) + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('infinity')) v(x); + avg | var_pop +----------+--------- + Infinity | NaN +(1 row) + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('infinity')) v(x); + avg | var_pop +-----+--------- + NaN | NaN +(1 row) + +-- test accuracy with a large input offset +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x); + avg | var_pop +-----------+--------- + 100000005 | 2.5 +(1 row) + +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (7000000000005), (7000000000007)) v(x); + avg | var_pop +---------------+--------- + 7000000000006 | 1 +(1 row) + -- SQL2003 binary aggregates SELECT regr_count(b, a) FROM aggtest; regr_count @@ -253,6 +299,90 @@ SELECT corr(b, a) FROM aggtest; 0.139634516517873 (1 row) +-- test accum and combine functions directly +CREATE TABLE regr_test (x float8, y float8); +INSERT INTO regr_test VALUES (10,150),(20,250),(30,350),(80,540),(100,200); +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30,80); + count | sum | regr_sxx | sum | regr_syy | regr_sxy +-------+-----+----------+------+----------+---------- + 4 | 140 | 2900 | 1290 | 83075 | 15050 +(1 row) + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test; + count | sum | regr_sxx | sum | regr_syy | regr_sxy +-------+-----+----------+------+----------+---------- + 5 | 240 | 6280 | 1490 | 95080 | 8680 +(1 row) + +SELECT float8_accum('{4,140,2900}'::float8[], 100); + float8_accum +-------------- + {5,240,6280} +(1 row) + +SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100); + float8_regr_accum +------------------------------ + {5,240,6280,1490,95080,8680} +(1 row) + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30); + count | sum | regr_sxx | sum | regr_syy | regr_sxy +-------+-----+----------+-----+----------+---------- + 3 | 60 | 200 | 750 | 20000 | 2000 +(1 row) + +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (80,100); + count | sum | regr_sxx | sum | regr_syy | regr_sxy +-------+-----+----------+-----+----------+---------- + 2 | 180 | 200 | 740 | 57800 | -3400 +(1 row) + +SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[]); + float8_combine +---------------- + {3,60,200} +(1 row) + +SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[]); + float8_combine +---------------- + {2,180,200} +(1 row) + +SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[]); + float8_combine +---------------- + {5,240,6280} +(1 row) + +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{0,0,0,0,0,0}'::float8[]); + float8_regr_combine +--------------------------- + {3,60,200,750,20000,2000} +(1 row) + +SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); + float8_regr_combine +----------------------------- + {2,180,200,740,57800,-3400} +(1 row) + +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); + float8_regr_combine +------------------------------ + {5,240,6280,1490,95080,8680} +(1 row) + +DROP TABLE regr_test; +-- test count, distinct SELECT count(four) AS cnt_1000 FROM onek; cnt_1000 ---------- @@ -1017,9 +1147,52 @@ explain (costs off) select * from t3 group by a,b,c; -> Seq Scan on t3 (3 rows) -drop table t1; +create temp table t1c () inherits (t1); +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d; + QUERY PLAN +------------------------------------- + HashAggregate + Group Key: t1.a, t1.b, t1.c, t1.d + -> Append + -> Seq Scan on t1 + -> Seq Scan on t1c +(5 rows) + +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d; + QUERY PLAN +---------------------- + HashAggregate + Group Key: a, b + -> Seq Scan on t1 +(3 rows) + +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a); +create temp table p_t1_1 partition of p_t1 for values in(1); +create temp table p_t1_2 partition of p_t1 for values in(2); +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d; + QUERY PLAN +--------------------------------- + HashAggregate + Group Key: p_t1_1.a, p_t1_1.b + -> Append + -> Seq Scan on p_t1_1 + -> Seq Scan on p_t1_2 +(5 rows) + +drop table t1 cascade; +NOTICE: drop cascades to table t1c drop table t2; drop table t3; +drop table p_t1; -- -- Test combinations of DISTINCT and/or ORDER BY -- @@ -1674,7 +1847,7 @@ LINE 1: select rank(3) within group (order by stringu1,stringu2) fro... ^ HINT: To use the hypothetical-set aggregate rank, the number of hypothetical direct arguments (here 1) must match the number of ordering columns (here 2). select rank('fred') within group (order by x) from generate_series(1,5) x; -ERROR: invalid input syntax for integer: "fred" +ERROR: invalid input syntax for type integer: "fred" LINE 1: select rank('fred') within group (order by x) from generate_... ^ select rank('adam'::text collate "C") within group (order by x collate "POSIX") @@ -1857,10 +2030,10 @@ NOTICE: avg_transfn called with 3 -- this should not share the state due to different input columns. select my_avg(one),my_sum(two) from (values(1,2),(3,4)) t(one,two); -NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 1 -NOTICE: avg_transfn called with 4 +NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 3 +NOTICE: avg_transfn called with 4 my_avg | my_sum --------+-------- 2 | 6 @@ -2065,3 +2238,96 @@ SELECT balk(hundred) FROM tenk1; (1 row) ROLLBACK; +-- test coverage for aggregate combine/serial/deserial functions +BEGIN ISOLATION LEVEL REPEATABLE READ; +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 4; +SET enable_indexonlyscan = off; +-- variance(int4) covers numeric_poly_combine +-- sum(int8) covers int8_avg_combine +-- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg +EXPLAIN (COSTS OFF, VERBOSE) + SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Finalize Aggregate + Output: variance(unique1), sum((unique1)::bigint), regr_count((unique1)::double precision, (unique1)::double precision) + -> Gather + Output: (PARTIAL variance(unique1)), (PARTIAL sum((unique1)::bigint)), (PARTIAL regr_count((unique1)::double precision, (unique1)::double precision)) + Workers Planned: 4 + -> Partial Aggregate + Output: PARTIAL variance(unique1), PARTIAL sum((unique1)::bigint), PARTIAL regr_count((unique1)::double precision, (unique1)::double precision) + -> Parallel Seq Scan on public.tenk1 + Output: unique1, unique2, two, four, ten, twenty, hundred, thousand, twothousand, fivethous, tenthous, odd, even, stringu1, stringu2, string4 +(9 rows) + +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + variance | sum | regr_count +----------------------+----------+------------ + 8334166.666666666667 | 49995000 | 10000 +(1 row) + +ROLLBACK; +-- test coverage for dense_rank +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1; + dense_rank +------------ + 1 + 1 + 1 +(3 rows) + +-- Ensure that the STRICT checks for aggregates does not take NULLness +-- of ORDER BY columns into account. See bug report around +-- 2a505161-2727-2473-7c46-591ed108ac52@email.cz +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y); + min +----- + 1 +(1 row) + +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y); + min +----- + 1 +(1 row) + +-- check collation-sensitive matching between grouping expressions +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + ?column? | case | count +----------+------+------- + aa | 1 | 1 + ba | 0 | 1 +(2 rows) + +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + ?column? | case | count +----------+------+------- + aa | 1 | 1 + ba | 0 | 1 +(2 rows) + +-- Make sure that generation of HashAggregate for uniqification purposes +-- does not lead to array overflow due to unexpected duplicate hash keys +-- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com +explain (costs off) + select 1 from tenk1 + where (hundred, thousand) in (select twothousand, twothousand from onek); + QUERY PLAN +------------------------------------------------------------- + Hash Join + Hash Cond: (tenk1.hundred = onek.twothousand) + -> Seq Scan on tenk1 + Filter: (hundred = thousand) + -> Hash + -> HashAggregate + Group Key: onek.twothousand, onek.twothousand + -> Seq Scan on onek +(8 rows) + diff --git a/src/test/regress/expected/alter_generic.out b/src/test/regress/expected/alter_generic.out index f24a17f40e7..8663f0c39c9 100644 --- a/src/test/regress/expected/alter_generic.out +++ b/src/test/regress/expected/alter_generic.out @@ -354,9 +354,9 @@ ERROR: invalid operator number 0, must be between 1 and 5 ALTER OPERATOR FAMILY alt_opf4 USING btree ADD OPERATOR 1 < ; -- operator without argument types ERROR: operator argument types must be specified in ALTER OPERATOR FAMILY ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 0 btint42cmp(int4, int2); -- function number should be between 1 and 5 -ERROR: invalid procedure number 0, must be between 1 and 3 +ERROR: invalid function number 0, must be between 1 and 3 ALTER OPERATOR FAMILY alt_opf4 USING btree ADD FUNCTION 6 btint42cmp(int4, int2); -- function number should be between 1 and 5 -ERROR: invalid procedure number 6, must be between 1 and 3 +ERROR: invalid function number 6, must be between 1 and 3 ALTER OPERATOR FAMILY alt_opf4 USING btree ADD STORAGE invalid_storage; -- Ensure STORAGE is not a part of ALTER OPERATOR FAMILY ERROR: STORAGE cannot be specified in ALTER OPERATOR FAMILY DROP OPERATOR FAMILY alt_opf4 USING btree; @@ -412,7 +412,7 @@ BEGIN TRANSACTION; CREATE OPERATOR FAMILY alt_opf12 USING btree; CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2); -ERROR: btree comparison procedures must return integer +ERROR: btree comparison functions must return integer DROP OPERATOR FAMILY alt_opf12 USING btree; ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK; @@ -421,7 +421,7 @@ BEGIN TRANSACTION; CREATE OPERATOR FAMILY alt_opf13 USING hash; CREATE FUNCTION fn_opf13 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; ALTER OPERATOR FAMILY alt_opf13 USING hash ADD FUNCTION 1 fn_opf13(int4); -ERROR: hash procedure 1 must return integer +ERROR: hash function 1 must return integer DROP OPERATOR FAMILY alt_opf13 USING hash; ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK; @@ -430,7 +430,7 @@ BEGIN TRANSACTION; CREATE OPERATOR FAMILY alt_opf14 USING btree; CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4); -ERROR: btree comparison procedures must have two arguments +ERROR: btree comparison functions must have two arguments DROP OPERATOR FAMILY alt_opf14 USING btree; ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK; @@ -439,7 +439,7 @@ BEGIN TRANSACTION; CREATE OPERATOR FAMILY alt_opf15 USING hash; CREATE FUNCTION fn_opf15 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL; ALTER OPERATOR FAMILY alt_opf15 USING hash ADD FUNCTION 1 fn_opf15(int4, int2); -ERROR: hash procedure 1 must have one argument +ERROR: hash function 1 must have one argument DROP OPERATOR FAMILY alt_opf15 USING hash; ERROR: current transaction is aborted, commands ignored until end of transaction block ROLLBACK; @@ -447,7 +447,7 @@ ROLLBACK; -- without defining left / right type in ALTER OPERATOR FAMILY ... ADD FUNCTION CREATE OPERATOR FAMILY alt_opf16 USING gist; ALTER OPERATOR FAMILY alt_opf16 USING gist ADD FUNCTION 1 btint42cmp(int4, int2); -ERROR: associated data types must be specified for index support procedure +ERROR: associated data types must be specified for index support function DROP OPERATOR FAMILY alt_opf16 USING gist; -- Should fail. duplicate operator number / function number in ALTER OPERATOR FAMILY ... ADD FUNCTION CREATE OPERATOR FAMILY alt_opf17 USING btree; @@ -464,7 +464,7 @@ ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 5 > (int4, int2) , FUNCTION 1 btint42cmp(int4, int2) , FUNCTION 1 btint42cmp(int4, int2); -- procedure 1 appears twice in same statement -ERROR: procedure number 1 for (integer,smallint) appears more than once +ERROR: function number 1 for (integer,smallint) appears more than once ALTER OPERATOR FAMILY alt_opf17 USING btree ADD OPERATOR 1 < (int4, int2) , OPERATOR 2 <= (int4, int2) , @@ -679,7 +679,6 @@ SELECT nspname, prsname --- --- Cleanup resources --- -\set VERBOSITY terse \\ -- suppress cascade details DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE; NOTICE: drop cascades to server alt_fserv2 DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE; @@ -688,8 +687,45 @@ DROP LANGUAGE alt_lang2 CASCADE; DROP LANGUAGE alt_lang3 CASCADE; DROP SCHEMA alt_nsp1 CASCADE; NOTICE: drop cascades to 28 other objects +DETAIL: drop cascades to function alt_func3(integer) +drop cascades to function alt_agg3(integer) +drop cascades to function alt_func4(integer) +drop cascades to function alt_func2(integer) +drop cascades to function alt_agg4(integer) +drop cascades to function alt_agg2(integer) +drop cascades to conversion alt_conv3 +drop cascades to conversion alt_conv4 +drop cascades to conversion alt_conv2 +drop cascades to operator @+@(integer,integer) +drop cascades to operator @-@(integer,integer) +drop cascades to operator family alt_opf3 for access method hash +drop cascades to operator family alt_opc1 for access method hash +drop cascades to operator family alt_opc2 for access method hash +drop cascades to operator family alt_opf4 for access method hash +drop cascades to operator family alt_opf2 for access method hash +drop cascades to table alt_regress_1 +drop cascades to table alt_regress_2 +drop cascades to text search dictionary alt_ts_dict3 +drop cascades to text search dictionary alt_ts_dict4 +drop cascades to text search dictionary alt_ts_dict2 +drop cascades to text search configuration alt_ts_conf3 +drop cascades to text search configuration alt_ts_conf4 +drop cascades to text search configuration alt_ts_conf2 +drop cascades to text search template alt_ts_temp3 +drop cascades to text search template alt_ts_temp2 +drop cascades to text search parser alt_ts_prs3 +drop cascades to text search parser alt_ts_prs2 DROP SCHEMA alt_nsp2 CASCADE; NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to function alt_nsp2.alt_func2(integer) +drop cascades to function alt_nsp2.alt_agg2(integer) +drop cascades to conversion alt_nsp2.alt_conv2 +drop cascades to operator alt_nsp2.@-@(integer,integer) +drop cascades to operator family alt_nsp2.alt_opf2 for access method hash +drop cascades to text search dictionary alt_nsp2.alt_ts_dict2 +drop cascades to text search configuration alt_nsp2.alt_ts_conf2 +drop cascades to text search template alt_nsp2.alt_ts_temp2 +drop cascades to text search parser alt_nsp2.alt_ts_prs2 DROP USER regress_alter_generic_user1; DROP USER regress_alter_generic_user2; DROP USER regress_alter_generic_user3; diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 1d6cc9ca6cd..23d4265555c 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -23,37 +23,34 @@ ALTER TABLE attmp ADD COLUMN d float8; ALTER TABLE attmp ADD COLUMN e float4; ALTER TABLE attmp ADD COLUMN f int2; ALTER TABLE attmp ADD COLUMN g polygon; -ALTER TABLE attmp ADD COLUMN h abstime; ALTER TABLE attmp ADD COLUMN i char; -ALTER TABLE attmp ADD COLUMN j abstime[]; ALTER TABLE attmp ADD COLUMN k int4; ALTER TABLE attmp ADD COLUMN l tid; ALTER TABLE attmp ADD COLUMN m xid; ALTER TABLE attmp ADD COLUMN n oidvector; --ALTER TABLE attmp ADD COLUMN o lock; -ALTER TABLE attmp ADD COLUMN p smgr; +ALTER TABLE attmp ADD COLUMN p boolean; ALTER TABLE attmp ADD COLUMN q point; ALTER TABLE attmp ADD COLUMN r lseg; ALTER TABLE attmp ADD COLUMN s path; ALTER TABLE attmp ADD COLUMN t box; -ALTER TABLE attmp ADD COLUMN u tinterval; ALTER TABLE attmp ADD COLUMN v timestamp; ALTER TABLE attmp ADD COLUMN w interval; ALTER TABLE attmp ADD COLUMN x float8[]; ALTER TABLE attmp ADD COLUMN y float4[]; ALTER TABLE attmp ADD COLUMN z int2[]; -INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', - 'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}', + 'c', 314159, '(1,1)', '512', - '1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', - '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); SELECT * FROM attmp; - initial | a | b | c | d | e | f | g | h | i | j | k | l | m | n | p | q | r | s | t | u | v | w | x | y | z ----------+---+------+------+-----+-----+---+-----------------------+------------------------------+---+------------------------------------------------------------------------------------------------+--------+-------+-----+-----------------+---------------+-----------+-----------------------+-----------------------------+---------------------+---------------------------------------------+--------------------------+------------------+-----------+-----------+----------- - | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | Mon May 01 00:30:30 1995 PDT | c | {"Mon May 01 00:30:30 1995 PDT","Mon Aug 24 14:43:07 1992 PDT","Wed Dec 31 16:00:00 1969 PST"} | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | magnetic disk | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | ["Wed Dec 31 16:00:00 1969 PST" "infinity"] | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4} + initial | a | b | c | d | e | f | g | i | k | l | m | n | p | q | r | s | t | v | w | x | y | z +---------+---+------+------+-----+-----+---+-----------------------+---+--------+-------+-----+-----------------+---+-----------+-----------------------+-----------------------------+---------------------+--------------------------+------------------+-----------+-----------+----------- + | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | c | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | t | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4} (1 row) DROP TABLE attmp; @@ -68,37 +65,34 @@ ALTER TABLE attmp ADD COLUMN d float8; ALTER TABLE attmp ADD COLUMN e float4; ALTER TABLE attmp ADD COLUMN f int2; ALTER TABLE attmp ADD COLUMN g polygon; -ALTER TABLE attmp ADD COLUMN h abstime; ALTER TABLE attmp ADD COLUMN i char; -ALTER TABLE attmp ADD COLUMN j abstime[]; ALTER TABLE attmp ADD COLUMN k int4; ALTER TABLE attmp ADD COLUMN l tid; ALTER TABLE attmp ADD COLUMN m xid; ALTER TABLE attmp ADD COLUMN n oidvector; --ALTER TABLE attmp ADD COLUMN o lock; -ALTER TABLE attmp ADD COLUMN p smgr; +ALTER TABLE attmp ADD COLUMN p boolean; ALTER TABLE attmp ADD COLUMN q point; ALTER TABLE attmp ADD COLUMN r lseg; ALTER TABLE attmp ADD COLUMN s path; ALTER TABLE attmp ADD COLUMN t box; -ALTER TABLE attmp ADD COLUMN u tinterval; ALTER TABLE attmp ADD COLUMN v timestamp; ALTER TABLE attmp ADD COLUMN w interval; ALTER TABLE attmp ADD COLUMN x float8[]; ALTER TABLE attmp ADD COLUMN y float4[]; ALTER TABLE attmp ADD COLUMN z int2[]; -INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', - 'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}', + 'c', 314159, '(1,1)', '512', - '1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', - '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); SELECT * FROM attmp; - initial | a | b | c | d | e | f | g | h | i | j | k | l | m | n | p | q | r | s | t | u | v | w | x | y | z ----------+---+------+------+-----+-----+---+-----------------------+------------------------------+---+------------------------------------------------------------------------------------------------+--------+-------+-----+-----------------+---------------+-----------+-----------------------+-----------------------------+---------------------+---------------------------------------------+--------------------------+------------------+-----------+-----------+----------- - | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | Mon May 01 00:30:30 1995 PDT | c | {"Mon May 01 00:30:30 1995 PDT","Mon Aug 24 14:43:07 1992 PDT","Wed Dec 31 16:00:00 1969 PST"} | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | magnetic disk | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | ["Wed Dec 31 16:00:00 1969 PST" "infinity"] | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4} + initial | a | b | c | d | e | f | g | i | k | l | m | n | p | q | r | s | t | v | w | x | y | z +---------+---+------+------+-----+-----+---+-----------------------+---+--------+-------+-----+-----------------+---+-----------+-----------------------+-----------------------------+---------------------+--------------------------+------------------+-----------+-----------+----------- + | 4 | name | text | 4.1 | 4.1 | 2 | ((4.1,4.1),(3.1,3.1)) | c | 314159 | (1,1) | 512 | 1 2 3 4 5 6 7 8 | t | (1.1,1.1) | [(4.1,4.1),(3.1,3.1)] | ((0,2),(4.1,4.1),(3.1,3.1)) | (4.1,4.1),(3.1,3.1) | Thu Jan 01 00:00:00 1970 | @ 1 hour 10 secs | {1,2,3,4} | {1,2,3,4} | {1,2,3,4} (1 row) CREATE INDEX attmp_idx ON attmp (a, (d + e), b); @@ -111,12 +105,12 @@ ERROR: cannot alter statistics on non-expression column "a" of index "attmp_idx HINT: Alter statistics on table column instead. ALTER INDEX attmp_idx ALTER COLUMN 2 SET STATISTICS 1000; \d+ attmp_idx - Index "public.attmp_idx" - Column | Type | Definition | Storage | Stats target ---------+------------------+------------+---------+-------------- - a | integer | a | plain | - expr | double precision | (d + e) | plain | 1000 - b | cstring | b | plain | + Index "public.attmp_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+------------------+------+------------+---------+-------------- + a | integer | yes | a | plain | + expr | double precision | yes | (d + e) | plain | 1000 + b | cstring | yes | b | plain | btree, for table "public.attmp" ALTER INDEX attmp_idx ALTER COLUMN 3 SET STATISTICS 1000; @@ -159,6 +153,24 @@ SELECT * FROM attmp_new2; DROP TABLE attmp_new; DROP TABLE attmp_new2; +-- check rename of partitioned tables and indexes also +CREATE TABLE part_attmp (a int primary key) partition by range (a); +CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100); +ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index; +ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index; +ALTER TABLE part_attmp RENAME TO part_at2tmp; +ALTER TABLE part_attmp1 RENAME TO part_at2tmp1; +SET ROLE regress_alter_table_user1; +ALTER INDEX part_attmp_index RENAME TO fail; +ERROR: must be owner of index part_attmp_index +ALTER INDEX part_attmp1_index RENAME TO fail; +ERROR: must be owner of index part_attmp1_index +ALTER TABLE part_at2tmp RENAME TO fail; +ERROR: must be owner of table part_at2tmp +ALTER TABLE part_at2tmp1 RENAME TO fail; +ERROR: must be owner of table part_at2tmp1 +RESET ROLE; +DROP TABLE part_at2tmp; -- -- check renaming to a table's array type's autogenerated name -- (the array type's name should get out of the way) @@ -381,6 +393,28 @@ ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; -- NOTICE: relation "constraint_not_exist" does not exist, skipping ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a); NOTICE: relation "constraint_rename_test" does not exist, skipping +-- renaming constraints with cache reset of target relation +CREATE TABLE constraint_rename_cache (a int, + CONSTRAINT chk_a CHECK (a > 0), + PRIMARY KEY (a)); +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT chk_a TO chk_a_new; +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new; +CREATE TABLE like_constraint_rename_cache + (LIKE constraint_rename_cache INCLUDING ALL); +\d like_constraint_rename_cache + Table "public.like_constraint_rename_cache" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | not null | +Indexes: + "like_constraint_rename_cache_pkey" PRIMARY KEY, btree (a) +Check constraints: + "chk_a_new" CHECK (a > 0) + +DROP TABLE constraint_rename_cache; +DROP TABLE like_constraint_rename_cache; -- FOREIGN KEY CONSTRAINT adding TEST CREATE TABLE attmp2 (a int primary key); CREATE TABLE attmp3 (a int, b int); @@ -621,26 +655,26 @@ CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet, -- This should fail, because we just chose really odd types CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable; -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. DROP TABLE FKTABLE; -- Again, so should this... CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable(ptest1, ptest2); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. DROP TABLE FKTABLE; -- This fails because we mixed up the column ordering CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet); ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable(ptest2, ptest1); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet. -- As does this... ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1) references pktable(ptest1, ptest2); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer. DROP TABLE FKTABLE; DROP TABLE PKTABLE; @@ -837,7 +871,7 @@ ERROR: check constraint "foo" is violated by some row drop table atacc2; drop table atacc1; -- test unique constraint adding -create table atacc1 ( test int ) with oids; +create table atacc1 ( test int ) ; -- add a unique constraint alter table atacc1 add constraint atacc_test1 unique (test); -- insert first value @@ -848,8 +882,6 @@ ERROR: duplicate key value violates unique constraint "atacc_test1" DETAIL: Key (test)=(2) already exists. -- should succeed insert into atacc1 (test) values (4); --- try adding a unique oid constraint -alter table atacc1 add constraint atacc_oid1 unique(oid); -- try to create duplicates via alter table using - should fail alter table atacc1 alter column test type integer using 0; ERROR: could not create unique index "atacc_test1" @@ -898,7 +930,7 @@ ERROR: duplicate key value violates unique constraint "atacc1_test_key" DETAIL: Key (test)=(3) already exists. drop table atacc1; -- test primary key constraint adding -create table atacc1 ( test int ) with oids; +create table atacc1 ( id serial, test int) ; -- add a primary key constraint alter table atacc1 add constraint atacc_test1 primary key (test); -- insert first value @@ -912,14 +944,14 @@ insert into atacc1 (test) values (4); -- inserting NULL should fail insert into atacc1 (test) values(NULL); ERROR: null value in column "test" violates not-null constraint -DETAIL: Failing row contains (null). +DETAIL: Failing row contains (4, null). -- try adding a second primary key (should fail) -alter table atacc1 add constraint atacc_oid1 primary key(oid); +alter table atacc1 add constraint atacc_oid1 primary key(id); ERROR: multiple primary keys for table "atacc1" are not allowed -- drop first primary key constraint alter table atacc1 drop constraint atacc_test1 restrict; -- try adding a primary key on oid (should succeed) -alter table atacc1 add constraint atacc_oid1 primary key(oid); +alter table atacc1 add constraint atacc_oid1 primary key(id); drop table atacc1; -- let's do one where the primary key constraint fails when added create table atacc1 ( test int ); @@ -946,7 +978,7 @@ drop table atacc1; create table atacc1 ( test int ); -- add a primary key constraint (fails) alter table atacc1 add constraint atacc_test1 primary key (test1); -ERROR: column "test1" named in key does not exist +ERROR: column "test1" of relation "atacc1" does not exist drop table atacc1; -- adding a new column as primary key to a non-empty table. -- should fail unless the column has a non-null default value. @@ -958,6 +990,13 @@ ERROR: column "test2" contains null values -- now add a primary key column with a default (succeeds). alter table atacc1 add column test2 int default 0 primary key; drop table atacc1; +-- this combination used to have order-of-execution problems (bug #15580) +create table atacc1 (a int); +insert into atacc1 values(1); +alter table atacc1 + add column b float8 not null default random(), + add primary key(a); +drop table atacc1; -- something a little more complicated create table atacc1 ( test int, test2 int); -- add a primary key constraint @@ -1009,7 +1048,7 @@ alter table non_existent alter column bar drop not null; ERROR: relation "non_existent" does not exist -- test setting columns to null and not null and vice versa -- test checking for null values and primary key -create table atacc1 (test int not null) with oids; +create table atacc1 (test int not null); alter table atacc1 add constraint "atacc1_pkey" primary key (test); alter table atacc1 alter column test drop not null; ERROR: column "test" is in a primary key @@ -1025,11 +1064,6 @@ alter table atacc1 alter bar set not null; ERROR: column "bar" of relation "atacc1" does not exist alter table atacc1 alter bar drop not null; ERROR: column "bar" of relation "atacc1" does not exist --- try altering the oid column, should fail -alter table atacc1 alter oid set not null; -ERROR: cannot alter system column "oid" -alter table atacc1 alter oid drop not null; -ERROR: cannot alter system column "oid" -- try creating a view and altering that, should fail create view myview as select * from atacc1; alter table myview alter column test drop not null; @@ -1038,6 +1072,41 @@ alter table myview alter column test set not null; ERROR: "myview" is not a table or foreign table drop view myview; drop table atacc1; +-- set not null verified by constraints +create table atacc1 (test_a int, test_b int); +insert into atacc1 values (null, 1); +-- constraint not cover all values, should fail +alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10); +alter table atacc1 alter test_a set not null; +ERROR: column "test_a" contains null values +alter table atacc1 drop constraint atacc1_constr_or; +-- not valid constraint, should fail +alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid; +alter table atacc1 alter test_a set not null; +ERROR: column "test_a" contains null values +alter table atacc1 drop constraint atacc1_constr_invalid; +-- with valid constraint +update atacc1 set test_a = 1; +alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null); +alter table atacc1 alter test_a set not null; +delete from atacc1; +insert into atacc1 values (2, null); +alter table atacc1 alter test_a drop not null; +-- test multiple set not null at same time +-- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan +alter table atacc1 alter test_a set not null, alter test_b set not null; +ERROR: column "test_b" contains null values +-- commands order has no importance +alter table atacc1 alter test_b set not null, alter test_a set not null; +ERROR: column "test_b" contains null values +-- valid one by table scan, one by check constraints +update atacc1 set test_b = 1; +alter table atacc1 alter test_b set not null, alter test_a set not null; +alter table atacc1 alter test_a drop not null, alter test_b drop not null; +-- both column has check constraints +alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null); +alter table atacc1 alter test_b set not null, alter test_a set not null; +drop table atacc1; -- test inheritance create table parent (a int); create table child (b varchar(255)) inherits (parent); @@ -1095,7 +1164,7 @@ select * from def_test; -- set defaults to an incorrect type: this should fail alter table def_test alter column c1 set default 'wrong_datatype'; -ERROR: invalid input syntax for integer: "wrong_datatype" +ERROR: invalid input syntax for type integer: "wrong_datatype" alter table def_test alter column c2 set default 20; -- set defaults on a non-existent column: this should fail alter table def_test alter column c3 set default 30; @@ -1135,7 +1204,7 @@ ERROR: permission denied: "pg_class" is a system catalog alter table nosuchtable drop column bar; ERROR: relation "nosuchtable" does not exist -- test dropping columns -create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) with oids; +create table atacc1 (a int4 not null, b int4, c int4 not null, d int4); insert into atacc1 values (1, 2, 3, 4); alter table atacc1 drop a; alter table atacc1 drop a; @@ -1280,8 +1349,13 @@ delete from atacc1; -- try dropping a non-existent column, should fail alter table atacc1 drop bar; ERROR: column "bar" of relation "atacc1" does not exist --- try dropping the oid column, should succeed -alter table atacc1 drop oid; +-- try removing an oid column, should succeed (as it's nonexistent) +alter table atacc1 SET WITHOUT OIDS; +-- try adding an oid column, should fail (not supported) +alter table atacc1 SET WITH OIDS; +ERROR: syntax error at or near "WITH" +LINE 1: alter table atacc1 SET WITH OIDS; + ^ -- try dropping the xmin column, should fail alter table atacc1 drop xmin; ERROR: cannot drop system column "xmin" @@ -1337,9 +1411,9 @@ ERROR: column "a" does not exist alter table atacc1 rename "........pg.dropped.1........" to x; ERROR: column "........pg.dropped.1........" does not exist alter table atacc1 add primary key(a); -ERROR: column "a" named in key does not exist +ERROR: column "a" of relation "atacc1" does not exist alter table atacc1 add primary key("........pg.dropped.1........"); -ERROR: column "........pg.dropped.1........" named in key does not exist +ERROR: column "........pg.dropped.1........" of relation "atacc1" does not exist alter table atacc1 add unique(a); ERROR: column "a" named in key does not exist alter table atacc1 add unique("........pg.dropped.1........"); @@ -1679,131 +1753,6 @@ order by attrelid::regclass::text, attnum; depth2 | c | 1 | f (3 rows) --- --- Test the ALTER TABLE SET WITH/WITHOUT OIDS command --- -create table altstartwith (col integer) with oids; -insert into altstartwith values (1); -select oid > 0, * from altstartwith; - ?column? | col -----------+----- - t | 1 -(1 row) - -alter table altstartwith set without oids; -select oid > 0, * from altstartwith; -- fails -ERROR: column "oid" does not exist -LINE 1: select oid > 0, * from altstartwith; - ^ -select * from altstartwith; - col ------ - 1 -(1 row) - -alter table altstartwith set with oids; -select oid > 0, * from altstartwith; - ?column? | col -----------+----- - t | 1 -(1 row) - -drop table altstartwith; --- Check inheritance cases -create table altwithoid (col integer) with oids; --- Inherits parents oid column anyway -create table altinhoid () inherits (altwithoid) without oids; -insert into altinhoid values (1); -select oid > 0, * from altwithoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -select oid > 0, * from altinhoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -alter table altwithoid set without oids; -select oid > 0, * from altwithoid; -- fails -ERROR: column "oid" does not exist -LINE 1: select oid > 0, * from altwithoid; - ^ -select oid > 0, * from altinhoid; -- fails -ERROR: column "oid" does not exist -LINE 1: select oid > 0, * from altinhoid; - ^ -select * from altwithoid; - col ------ - 1 -(1 row) - -select * from altinhoid; - col ------ - 1 -(1 row) - -alter table altwithoid set with oids; -select oid > 0, * from altwithoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -select oid > 0, * from altinhoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -drop table altwithoid cascade; -NOTICE: drop cascades to table altinhoid -create table altwithoid (col integer) without oids; --- child can have local oid column -create table altinhoid () inherits (altwithoid) with oids; -insert into altinhoid values (1); -select oid > 0, * from altwithoid; -- fails -ERROR: column "oid" does not exist -LINE 1: select oid > 0, * from altwithoid; - ^ -select oid > 0, * from altinhoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -alter table altwithoid set with oids; -NOTICE: merging definition of column "oid" for child "altinhoid" -select oid > 0, * from altwithoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -select oid > 0, * from altinhoid; - ?column? | col -----------+----- - t | 1 -(1 row) - --- the child's local definition should remain -alter table altwithoid set without oids; -select oid > 0, * from altwithoid; -- fails -ERROR: column "oid" does not exist -LINE 1: select oid > 0, * from altwithoid; - ^ -select oid > 0, * from altinhoid; - ?column? | col -----------+----- - t | 1 -(1 row) - -drop table altwithoid cascade; -NOTICE: drop cascades to table altinhoid -- test renumbering of child-table columns in inherited operations create table p1 (f1 int); create table c1 (f2 text, f3 int) inherits (p1); @@ -1844,7 +1793,7 @@ select * from foo; (1 row) drop domain mytype cascade; -NOTICE: drop cascades to table foo column f2 +NOTICE: drop cascades to column f2 of table foo select * from foo; f1 | f3 ----+---- @@ -1950,6 +1899,64 @@ select * from anothertab; f | IT WAS NULL! (3 rows) +drop table anothertab; +-- Test index handling in alter table column type (cf. bugs #15835, #15865) +create table anothertab(f1 int primary key, f2 int unique, + f3 int, f4 int, f5 int); +alter table anothertab + add exclude using btree (f3 with =); +alter table anothertab + add exclude using btree (f4 with =) where (f4 is not null); +alter table anothertab + add exclude using btree (f4 with =) where (f5 > 0); +alter table anothertab + add unique(f1,f4); +create index on anothertab(f2,f3); +create unique index on anothertab(f4); +\d anothertab + Table "public.anothertab" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + f1 | integer | | not null | + f2 | integer | | | + f3 | integer | | | + f4 | integer | | | + f5 | integer | | | +Indexes: + "anothertab_pkey" PRIMARY KEY, btree (f1) + "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4) + "anothertab_f2_f3_idx" btree (f2, f3) + "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2) + "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =) + "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL) + "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0) + "anothertab_f4_idx" UNIQUE, btree (f4) + +alter table anothertab alter column f1 type bigint; +alter table anothertab + alter column f2 type bigint, + alter column f3 type bigint, + alter column f4 type bigint; +alter table anothertab alter column f5 type bigint; +\d anothertab + Table "public.anothertab" + Column | Type | Collation | Nullable | Default +--------+--------+-----------+----------+--------- + f1 | bigint | | not null | + f2 | bigint | | | + f3 | bigint | | | + f4 | bigint | | | + f5 | bigint | | | +Indexes: + "anothertab_pkey" PRIMARY KEY, btree (f1) + "anothertab_f1_f4_key" UNIQUE CONSTRAINT, btree (f1, f4) + "anothertab_f2_f3_idx" btree (f2, f3) + "anothertab_f2_key" UNIQUE CONSTRAINT, btree (f2) + "anothertab_f3_excl" EXCLUDE USING btree (f3 WITH =) + "anothertab_f4_excl" EXCLUDE USING btree (f4 WITH =) WHERE (f4 IS NOT NULL) + "anothertab_f4_excl1" EXCLUDE USING btree (f4 WITH =) WHERE (f5 > 0) + "anothertab_f4_idx" UNIQUE, btree (f4) + drop table anothertab; create table another (f1 int, f2 text); insert into another values(1, 'one'); @@ -2041,6 +2048,94 @@ Indexes: "at_part_2_a_idx" btree (a) "at_part_2_b_idx" btree (b) +drop table at_partitioned; +-- Alter column type when no table rewrite is required +-- Also check that comments are preserved +create table at_partitioned(id int, name varchar(64), unique (id, name)) + partition by hash(id); +comment on constraint at_partitioned_id_name_key on at_partitioned is 'parent constraint'; +comment on index at_partitioned_id_name_key is 'parent index'; +create table at_partitioned_0 partition of at_partitioned + for values with (modulus 2, remainder 0); +comment on constraint at_partitioned_0_id_name_key on at_partitioned_0 is 'child 0 constraint'; +comment on index at_partitioned_0_id_name_key is 'child 0 index'; +create table at_partitioned_1 partition of at_partitioned + for values with (modulus 2, remainder 1); +comment on constraint at_partitioned_1_id_name_key on at_partitioned_1 is 'child 1 constraint'; +comment on index at_partitioned_1_id_name_key is 'child 1 index'; +insert into at_partitioned values(1, 'foo'); +insert into at_partitioned values(3, 'bar'); +create temp table old_oids as + select relname, oid as oldoid, relfilenode as oldfilenode + from pg_class where relname like 'at_partitioned%'; +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname; + relname | orig_oid | storage | desc +------------------------------+----------+---------+--------------- + at_partitioned | t | none | + at_partitioned_0 | t | own | + at_partitioned_0_id_name_key | t | own | child 0 index + at_partitioned_1 | t | own | + at_partitioned_1_id_name_key | t | own | child 1 index + at_partitioned_id_name_key | t | none | parent index +(6 rows) + +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname; + conname | desc +------------------------------+-------------------- + at_partitioned_0_id_name_key | child 0 constraint + at_partitioned_1_id_name_key | child 1 constraint + at_partitioned_id_name_key | parent constraint +(3 rows) + +alter table at_partitioned alter column name type varchar(127); +-- Note: these tests currently show the wrong behavior for comments :-( +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname; + relname | orig_oid | storage | desc +------------------------------+----------+---------+-------------- + at_partitioned | t | none | + at_partitioned_0 | t | own | + at_partitioned_0_id_name_key | f | own | parent index + at_partitioned_1 | t | own | + at_partitioned_1_id_name_key | f | own | parent index + at_partitioned_id_name_key | f | none | parent index +(6 rows) + +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname; + conname | desc +------------------------------+------------------- + at_partitioned_0_id_name_key | + at_partitioned_1_id_name_key | + at_partitioned_id_name_key | parent constraint +(3 rows) + +-- Don't remove this DROP, it exposes bug #15672 +drop table at_partitioned; -- disallow recursive containment of row types create temp table recur1 (f1 int); alter table recur1 add column f2 recur1; -- fails @@ -2618,7 +2713,7 @@ as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2 create operator alter1.=(procedure = alter1.same, leftarg = alter1.ctype, rightarg = alter1.ctype); create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as operator 1 alter1.=(alter1.ctype, alter1.ctype); -create conversion alter1.ascii_to_utf8 for 'sql_ascii' to 'utf8' from ascii_to_utf8; +create conversion alter1.latin1_to_utf8 for 'latin1' to 'utf8' from iso8859_1_to_utf8; create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); create text search configuration alter1.cfg(parser = alter1.prs); create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize); @@ -2636,7 +2731,7 @@ alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2; alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2; alter type alter1.ctype set schema alter1; -- no-op, same schema alter type alter1.ctype set schema alter2; -alter conversion alter1.ascii_to_utf8 set schema alter2; +alter conversion alter1.latin1_to_utf8 set schema alter2; alter text search parser alter1.prs set schema alter2; alter text search configuration alter1.cfg set schema alter2; alter text search template alter1.tmpl set schema alter2; @@ -2676,15 +2771,15 @@ DETAIL: drop cascades to table alter2.t1 drop cascades to view alter2.v1 drop cascades to function alter2.plus1(integer) drop cascades to type alter2.posint -drop cascades to operator family alter2.ctype_hash_ops for access method hash drop cascades to type alter2.ctype drop cascades to function alter2.same(alter2.ctype,alter2.ctype) drop cascades to operator alter2.=(alter2.ctype,alter2.ctype) -drop cascades to conversion ascii_to_utf8 -drop cascades to text search parser prs -drop cascades to text search configuration cfg -drop cascades to text search template tmpl -drop cascades to text search dictionary dict +drop cascades to operator family alter2.ctype_hash_ops for access method hash +drop cascades to conversion alter2.latin1_to_utf8 +drop cascades to text search parser alter2.prs +drop cascades to text search configuration alter2.cfg +drop cascades to text search template alter2.tmpl +drop cascades to text search dictionary alter2.dict -- -- composite types -- @@ -2870,8 +2965,8 @@ DROP TABLE test_tbl2_subclass; CREATE TYPE test_typex AS (a int, b text); CREATE TABLE test_tblx (x int, y test_typex check ((y).a > 0)); ALTER TYPE test_typex DROP ATTRIBUTE a; -- fails -ERROR: cannot drop composite type test_typex column a because other objects depend on it -DETAIL: constraint test_tblx_y_check on table test_tblx depends on composite type test_typex column a +ERROR: cannot drop column a of composite type test_typex because other objects depend on it +DETAIL: constraint test_tblx_y_check on table test_tblx depends on column a of composite type test_typex HINT: Use DROP ... CASCADE to drop the dependent objects too. ALTER TYPE test_typex DROP ATTRIBUTE a CASCADE; NOTICE: drop cascades to constraint test_tblx_y_check on table test_tblx @@ -2904,7 +2999,7 @@ CREATE TABLE tt3 (y numeric(8,2), x int); -- wrong column order CREATE TABLE tt4 (x int); -- too few columns CREATE TABLE tt5 (x int, y numeric(8,2), z int); -- too few columns CREATE TABLE tt6 () INHERITS (tt0); -- can't have a parent -CREATE TABLE tt7 (x int, q text, y numeric(8,2)) WITH OIDS; +CREATE TABLE tt7 (x int, q text, y numeric(8,2)); ALTER TABLE tt7 DROP q; -- OK ALTER TABLE tt0 OF tt_t0; ALTER TABLE tt1 OF tt_t0; @@ -2976,6 +3071,41 @@ Check constraints: DROP TABLE alter2.tt8; DROP SCHEMA alter2; +-- +-- Check conflicts between index and CHECK constraint names +-- +CREATE TABLE tt9(c integer); +ALTER TABLE tt9 ADD CHECK(c > 1); +ALTER TABLE tt9 ADD CHECK(c > 2); -- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 3); +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 4); -- fail, dup name +ERROR: constraint "foo" for relation "tt9" already exists +ALTER TABLE tt9 ADD UNIQUE(c); +ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE(c); -- fail, dup name +ERROR: relation "tt9_c_key" already exists +ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE(c); -- fail, dup name +ERROR: constraint "foo" for relation "tt9" already exists +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK(c > 5); -- fail, dup name +ERROR: constraint "tt9_c_key" for relation "tt9" already exists +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK(c > 6); +ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name +\d tt9 + Table "public.tt9" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c | integer | | | +Indexes: + "tt9_c_key" UNIQUE CONSTRAINT, btree (c) + "tt9_c_key1" UNIQUE CONSTRAINT, btree (c) + "tt9_c_key3" UNIQUE CONSTRAINT, btree (c) +Check constraints: + "foo" CHECK (c > 3) + "tt9_c_check" CHECK (c > 1) + "tt9_c_check1" CHECK (c > 2) + "tt9_c_key2" CHECK (c > 6) + +DROP TABLE tt9; -- Check that comments on constraints and indexes are not lost at ALTER TABLE. CREATE TABLE comment_test ( id int, @@ -3108,10 +3238,9 @@ DETAIL: System catalog modifications are currently disallowed. -- instead create in public first, move to catalog CREATE TABLE new_system_table(id serial primary key, othercol text); ALTER TABLE new_system_table SET SCHEMA pg_catalog; --- XXX: it's currently impossible to move relations out of pg_catalog ALTER TABLE new_system_table SET SCHEMA public; -ERROR: cannot remove dependency on schema pg_catalog because it is a system object --- move back, will be ignored -- already there +ALTER TABLE new_system_table SET SCHEMA pg_catalog; +-- will be ignored -- already there: ALTER TABLE new_system_table SET SCHEMA pg_catalog; ALTER TABLE new_system_table RENAME TO old_system_table; CREATE INDEX old_system_table__othercol ON old_system_table (othercol); @@ -3231,6 +3360,9 @@ ALTER TABLE test_add_column ALTER TABLE test_add_column ADD COLUMN c2 integer; -- fail because c2 already exists ERROR: column "c2" of relation "test_add_column" already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN c2 integer; -- fail because c2 already exists +ERROR: column "c2" of relation "test_add_column" already exists \d test_add_column Table "public.test_add_column" Column | Type | Collation | Nullable | Default @@ -3241,6 +3373,9 @@ ERROR: column "c2" of relation "test_add_column" already exists ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists NOTICE: column "c2" of relation "test_add_column" already exists, skipping +ALTER TABLE ONLY test_add_column + ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists +NOTICE: column "c2" of relation "test_add_column" already exists, skipping \d test_add_column Table "public.test_add_column" Column | Type | Collation | Nullable | Default @@ -3311,13 +3446,13 @@ LINE 1: ALTER TABLE partitioned ADD EXCLUDE USING gist (a WITH &&); ^ -- cannot drop column that is part of the partition key ALTER TABLE partitioned DROP COLUMN a; -ERROR: cannot drop column named in partition key +ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned" ALTER TABLE partitioned ALTER COLUMN a TYPE char(5); -ERROR: cannot alter type of column named in partition key +ERROR: cannot alter column "a" because it is part of the partition key of relation "partitioned" ALTER TABLE partitioned DROP COLUMN b; -ERROR: cannot drop column referenced in partition key expression +ERROR: cannot drop column "b" because it is part of the partition key of relation "partitioned" ALTER TABLE partitioned ALTER COLUMN b TYPE char(5); -ERROR: cannot alter type of column referenced in partition key expression +ERROR: cannot alter column "b" because it is part of the partition key of relation "partitioned" -- partitioned table cannot participate in regular inheritance CREATE TABLE nonpartitioned ( a int, @@ -3355,8 +3490,8 @@ LINE 1: ...list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) T... ^ DROP TABLE fail_part; -- check that the table being attached exists -ALTER TABLE list_parted ATTACH PARTITION nonexistant FOR VALUES IN (1); -ERROR: relation "nonexistant" does not exist +ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1); +ERROR: relation "nonexistent" does not exist -- check ownership of the source table CREATE ROLE regress_test_me; CREATE ROLE regress_test_not_me; @@ -3394,16 +3529,6 @@ ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); ERROR: cannot attach a typed table as partition DROP TYPE mytype CASCADE; NOTICE: drop cascades to table fail_part --- check existence (or non-existence) of oid column -ALTER TABLE list_parted SET WITH OIDS; -CREATE TABLE fail_part (a int); -ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); -ERROR: cannot attach table "fail_part" without OIDs as partition of table "list_parted" with OIDs -ALTER TABLE list_parted SET WITHOUT OIDS; -ALTER TABLE fail_part SET WITH OIDS; -ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); -ERROR: cannot attach table "fail_part" with OIDs as partition of table "list_parted" without OIDs -DROP TABLE fail_part; -- check that the table being attached has only columns present in the parent CREATE TABLE fail_part (like list_parted, c int); ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); @@ -3508,11 +3633,9 @@ ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4); ALTER TABLE list_parted2 DETACH PARTITION part_3_4; ALTER TABLE part_3_4 ALTER a SET NOT NULL; ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4); -INFO: partition constraint for table "part_3_4" is implied by existing constraints -- check if default partition scan skipped ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6)); CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66); -INFO: updated partition constraint for default partition "list_parted2_def" is implied by existing constraints -- check validation when attaching range partitions CREATE TABLE range_parted ( a int, @@ -3537,7 +3660,6 @@ CREATE TABLE part2 ( b int NOT NULL CHECK (b >= 10 AND b < 18) ); ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20); -INFO: partition constraint for table "part2" is implied by existing constraints -- Create default partition CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT; -- Only one default partition is allowed, hence, following should give error @@ -3565,13 +3687,11 @@ ERROR: partition constraint is violated by some row DELETE FROM part_5_a WHERE a NOT IN (3); ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IS NOT NULL AND a = 5); ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5); -INFO: partition constraint for table "part_5" is implied by existing constraints ALTER TABLE list_parted2 DETACH PARTITION part_5; ALTER TABLE part_5 DROP CONSTRAINT check_a; -- scan should again be skipped, even though NOT NULL is now a column property ALTER TABLE part_5 ADD CONSTRAINT check_a CHECK (a IN (5)), ALTER a SET NOT NULL; ALTER TABLE list_parted2 ATTACH PARTITION part_5 FOR VALUES IN (5); -INFO: partition constraint for table "part_5" is implied by existing constraints -- Check the case where attnos of the partitioning columns in the table being -- attached differs from the parent. It should not affect the constraint- -- checking logic that allows to skip the scan. @@ -3582,7 +3702,6 @@ CREATE TABLE part_6 ( ); ALTER TABLE part_6 DROP c; ALTER TABLE list_parted2 ATTACH PARTITION part_6 FOR VALUES IN (6); -INFO: partition constraint for table "part_6" is implied by existing constraints -- Similar to above, but the table being attached is a partitioned table -- whose partition has still different attnos for the root partitioning -- columns. @@ -3600,10 +3719,7 @@ CREATE TABLE part_7_a_null ( ); ALTER TABLE part_7_a_null DROP c, DROP d, DROP e; ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', null); -INFO: partition constraint for table "part_7_a_null" is implied by existing constraints ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7); -INFO: partition constraint for table "part_7" is implied by existing constraints -INFO: updated partition constraint for default partition "list_parted2_def" is implied by existing constraints -- Same example, but check this time that the constraint correctly detects -- violating rows ALTER TABLE list_parted2 DETACH PARTITION part_7; @@ -3617,7 +3733,6 @@ SELECT tableoid::regclass, a, b FROM part_7 order by a; (2 rows) ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7); -INFO: updated partition constraint for default partition "list_parted2_def" is implied by existing constraints ERROR: partition constraint is violated by some row -- check that leaf partitions of default partition are scanned when -- attaching a partitioned table. @@ -3654,28 +3769,19 @@ CREATE TABLE quuux1 (a int, b text); ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1); -- validate! CREATE TABLE quuux2 (a int, b text); ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2); -- skip validation -INFO: updated partition constraint for default partition "quuux_default1" is implied by existing constraints DROP TABLE quuux1, quuux2; -- should validate for quuux1, but not for quuux2 CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1); CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2); -INFO: updated partition constraint for default partition "quuux_default1" is implied by existing constraints DROP TABLE quuux; -- check validation when attaching hash partitions --- The default hash functions as they exist today aren't portable; they can --- return different results on different machines. Depending upon how the --- values are hashed, the row may map to different partitions, which result in --- regression failure. To avoid this, let's create a non-default hash function --- that just returns the input value unchanged. -CREATE OR REPLACE FUNCTION dummy_hashint4(a int4, seed int8) RETURNS int8 AS -$$ BEGIN RETURN (a + 1 + seed); END; $$ LANGUAGE 'plpgsql' IMMUTABLE; -CREATE OPERATOR CLASS custom_opclass FOR TYPE int4 USING HASH AS -OPERATOR 1 = , FUNCTION 2 dummy_hashint4(int4, int8); +-- Use hand-rolled hash functions and operator class to get predictable result +-- on different matchines. part_test_int4_ops is defined in insert.sql. -- check that the new partition won't overlap with an existing partition CREATE TABLE hash_parted ( a int, b int -) PARTITION BY HASH (a custom_opclass); +) PARTITION BY HASH (a part_test_int4_ops); CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0); CREATE TABLE fail_part (LIKE hpart_1); ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4); @@ -3786,7 +3892,8 @@ ERROR: cannot alter inherited column "b" -- cannot add/drop NOT NULL or check constraints to *only* the parent, when -- partitions exist ALTER TABLE ONLY list_parted2 ALTER b SET NOT NULL; -ERROR: cannot add constraint to only the partitioned table when partitions exist +ERROR: constraint must be added to child tables too +DETAIL: Column "b" of relation "part_2" is not already NOT NULL. HINT: Do not specify the ONLY keyword. ALTER TABLE ONLY list_parted2 ADD CONSTRAINT check_b CHECK (b <> 'zz'); ERROR: constraint must be added to child tables too @@ -3826,9 +3933,9 @@ ERROR: cannot change inheritance of a partition -- partitioned tables; for example, part_5, which is list_parted2's -- partition, is partitioned on b; ALTER TABLE list_parted2 DROP COLUMN b; -ERROR: cannot drop column named in partition key +ERROR: cannot drop column "b" because it is part of the partition key of relation "part_5" ALTER TABLE list_parted2 ALTER COLUMN b TYPE text; -ERROR: cannot alter type of column named in partition key +ERROR: cannot alter column "b" because it is part of the partition key of relation "part_5" -- dropping non-partition key columns should be allowed on the parent table. ALTER TABLE list_parted DROP COLUMN b; SELECT * FROM list_parted; @@ -3840,8 +3947,6 @@ SELECT * FROM list_parted; DROP TABLE list_parted, list_parted2, range_parted; DROP TABLE fail_def_part; DROP TABLE hash_parted; -DROP OPERATOR CLASS custom_opclass USING HASH; -DROP FUNCTION dummy_hashint4(a int4, seed int8); -- more tests for certain multi-level partitioning scenarios create table p (a int, b int) partition by range (a, b); create table p1 (b int, a int not null) partition by range (b); @@ -3887,3 +3992,71 @@ ALTER TABLE attmp ALTER COLUMN i RESET (n_distinct_inherited); ANALYZE attmp; DROP TABLE attmp; DROP USER regress_alter_table_user1; +-- check that violating rows are correctly reported when attaching as the +-- default partition +create table defpart_attach_test (a int) partition by list (a); +create table defpart_attach_test1 partition of defpart_attach_test for values in (1); +create table defpart_attach_test_d (b int, a int); +alter table defpart_attach_test_d drop b; +insert into defpart_attach_test_d values (1), (2); +-- error because its constraint as the default partition would be violated +-- by the row containing 1 +alter table defpart_attach_test attach partition defpart_attach_test_d default; +ERROR: partition constraint is violated by some row +delete from defpart_attach_test_d where a = 1; +alter table defpart_attach_test_d add check (a > 1); +-- should be attached successfully and without needing to be scanned +alter table defpart_attach_test attach partition defpart_attach_test_d default; +-- check that attaching a partition correctly reports any rows in the default +-- partition that should not be there for the new partition to be attached +-- successfully +create table defpart_attach_test_2 (like defpart_attach_test_d); +alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2); +ERROR: updated partition constraint for default partition would be violated by some row +drop table defpart_attach_test; +-- check combinations of temporary and permanent relations when attaching +-- partitions. +create table perm_part_parent (a int) partition by list (a); +create temp table temp_part_parent (a int) partition by list (a); +create table perm_part_child (a int); +create temp table temp_part_child (a int); +alter table temp_part_parent attach partition perm_part_child default; -- error +ERROR: cannot attach a permanent relation as partition of temporary relation "temp_part_parent" +alter table perm_part_parent attach partition temp_part_child default; -- error +ERROR: cannot attach a temporary relation as partition of permanent relation "perm_part_parent" +alter table temp_part_parent attach partition temp_part_child default; -- ok +drop table perm_part_parent cascade; +drop table temp_part_parent cascade; +-- check that attaching partitions to a table while it is being used is +-- prevented +create table tab_part_attach (a int) partition by list (a); +create or replace function func_part_attach() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_attach_1 (a int)'; + execute 'alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)'; + return null; + end $$; +create trigger trig_part_attach before insert on tab_part_attach + for each statement execute procedure func_part_attach(); +insert into tab_part_attach values (1); +ERROR: cannot ALTER TABLE "tab_part_attach" because it is being used by active queries in this session +CONTEXT: SQL statement "alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)" +PL/pgSQL function func_part_attach() line 4 at EXECUTE +drop table tab_part_attach; +drop function func_part_attach(); +-- test case where the partitioning operator is a SQL function whose +-- evaluation results in the table's relcache being rebuilt partway through +-- the execution of an ATTACH PARTITION command +create function at_test_sql_partop (int4, int4) returns int language sql +as $$ select case when $1 = $2 then 0 when $1 > $2 then 1 else -1 end; $$; +create operator class at_test_sql_partop for type int4 using btree as + operator 1 < (int4, int4), operator 2 <= (int4, int4), + operator 3 = (int4, int4), operator 4 >= (int4, int4), + operator 5 > (int4, int4), function 1 at_test_sql_partop(int4, int4); +create table at_test_sql_partop (a int) partition by range (a at_test_sql_partop); +create table at_test_sql_partop_1 (a int); +alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values from (0) to (10); +drop table at_test_sql_partop; +drop operator class at_test_sql_partop using btree; +drop function at_test_sql_partop; diff --git a/src/test/regress/expected/amutils.out b/src/test/regress/expected/amutils.out index 24cd3c5e2e4..d92a6d12c62 100644 --- a/src/test/regress/expected/amutils.out +++ b/src/test/regress/expected/amutils.out @@ -75,7 +75,7 @@ select prop, can_unique | f | | can_multi_col | t | | can_exclude | t | | - can_include | f | | + can_include | t | | bogus | | | (19 rows) @@ -83,7 +83,8 @@ select prop, pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as btree, pg_index_column_has_property('hash_i4_index'::regclass, 1, prop) as hash, pg_index_column_has_property('gcircleind'::regclass, 1, prop) as gist, - pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist, + pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist_radix, + pg_index_column_has_property('sp_quad_ind'::regclass, 1, prop) as spgist_quad, pg_index_column_has_property('botharrayidx'::regclass, 1, prop) as gin, pg_index_column_has_property('brinidx'::regclass, 1, prop) as brin from unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', @@ -92,18 +93,18 @@ select prop, 'bogus']::text[]) with ordinality as u(prop,ord) order by ord; - prop | btree | hash | gist | spgist | gin | brin ---------------------+-------+------+------+--------+-----+------ - asc | t | f | f | f | f | f - desc | f | f | f | f | f | f - nulls_first | f | f | f | f | f | f - nulls_last | t | f | f | f | f | f - orderable | t | f | f | f | f | f - distance_orderable | f | f | t | f | f | f - returnable | t | f | f | t | f | f - search_array | t | f | f | f | f | f - search_nulls | t | f | t | t | f | t - bogus | | | | | | + prop | btree | hash | gist | spgist_radix | spgist_quad | gin | brin +--------------------+-------+------+------+--------------+-------------+-----+------ + asc | t | f | f | f | f | f | f + desc | f | f | f | f | f | f | f + nulls_first | f | f | f | f | f | f | f + nulls_last | t | f | f | f | f | f | f + orderable | t | f | f | f | f | f | f + distance_orderable | f | f | t | f | t | f | f + returnable | t | f | f | t | t | f | f + search_array | t | f | f | f | f | f | f + search_nulls | t | f | t | t | t | f | t + bogus | | | | | | | (10 rows) select prop, @@ -158,7 +159,7 @@ select amname, prop, pg_indexam_has_property(a.oid, prop) as p gist | can_unique | f gist | can_multi_col | t gist | can_exclude | t - gist | can_include | f + gist | can_include | t gist | bogus | hash | can_order | f hash | can_unique | f diff --git a/src/test/regress/expected/bit.out b/src/test/regress/expected/bit.out index 9c7d202149f..255b39b07e2 100644 --- a/src/test/regress/expected/bit.out +++ b/src/test/regress/expected/bit.out @@ -477,6 +477,50 @@ SELECT POSITION(B'1101' IN b), 0 | 0 | 0000000000000001 (16 rows) +SELECT b, b >> 1 AS bsr, b << 1 AS bsl + FROM BIT_SHIFT_TABLE ; + b | bsr | bsl +------------------+------------------+------------------ + 1101100000000000 | 0110110000000000 | 1011000000000000 + 0110110000000000 | 0011011000000000 | 1101100000000000 + 0011011000000000 | 0001101100000000 | 0110110000000000 + 0001101100000000 | 0000110110000000 | 0011011000000000 + 0000110110000000 | 0000011011000000 | 0001101100000000 + 0000011011000000 | 0000001101100000 | 0000110110000000 + 0000001101100000 | 0000000110110000 | 0000011011000000 + 0000000110110000 | 0000000011011000 | 0000001101100000 + 0000000011011000 | 0000000001101100 | 0000000110110000 + 0000000001101100 | 0000000000110110 | 0000000011011000 + 0000000000110110 | 0000000000011011 | 0000000001101100 + 0000000000011011 | 0000000000001101 | 0000000000110110 + 0000000000001101 | 0000000000000110 | 0000000000011010 + 0000000000000110 | 0000000000000011 | 0000000000001100 + 0000000000000011 | 0000000000000001 | 0000000000000110 + 0000000000000001 | 0000000000000000 | 0000000000000010 +(16 rows) + +SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl + FROM BIT_SHIFT_TABLE ; + b | bsr | bsl +-----------------+-----------------+----------------- + 110110000000000 | 011011000000000 | 101100000000000 + 011011000000000 | 001101100000000 | 110110000000000 + 001101100000000 | 000110110000000 | 011011000000000 + 000110110000000 | 000011011000000 | 001101100000000 + 000011011000000 | 000001101100000 | 000110110000000 + 000001101100000 | 000000110110000 | 000011011000000 + 000000110110000 | 000000011011000 | 000001101100000 + 000000011011000 | 000000001101100 | 000000110110000 + 000000001101100 | 000000000110110 | 000000011011000 + 000000000110110 | 000000000011011 | 000000001101100 + 000000000011011 | 000000000001101 | 000000000110110 + 000000000001101 | 000000000000110 | 000000000011010 + 000000000000110 | 000000000000011 | 000000000001100 + 000000000000011 | 000000000000001 | 000000000000110 + 000000000000001 | 000000000000000 | 000000000000010 + 000000000000000 | 000000000000000 | 000000000000000 +(16 rows) + CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)); INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011'); INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE; @@ -507,6 +551,28 @@ SELECT POSITION(B'1101' IN v), 16 | 16 | 00000000000000011011 (16 rows) +SELECT v, v >> 1 AS vsr, v << 1 AS vsl + FROM VARBIT_SHIFT_TABLE ; + v | vsr | vsl +----------------------+----------------------+---------------------- + 11011 | 01101 | 10110 + 011011 | 001101 | 110110 + 0011011 | 0001101 | 0110110 + 00011011 | 00001101 | 00110110 + 000011011 | 000001101 | 000110110 + 0000011011 | 0000001101 | 0000110110 + 00000011011 | 00000001101 | 00000110110 + 000000011011 | 000000001101 | 000000110110 + 0000000011011 | 0000000001101 | 0000000110110 + 00000000011011 | 00000000001101 | 00000000110110 + 000000000011011 | 000000000001101 | 000000000110110 + 0000000000011011 | 0000000000001101 | 0000000000110110 + 00000000000011011 | 00000000000001101 | 00000000000110110 + 000000000000011011 | 000000000000001101 | 000000000000110110 + 0000000000000011011 | 0000000000000001101 | 0000000000000110110 + 00000000000000011011 | 00000000000000001101 | 00000000000000110110 +(16 rows) + DROP TABLE BIT_SHIFT_TABLE; DROP TABLE VARBIT_SHIFT_TABLE; -- Get/Set bit @@ -549,3 +615,26 @@ SELECT overlay(B'0101011100' placing '001' from 20); 0101011100001 (1 row) +-- This table is intentionally left around to exercise pg_dump/pg_upgrade +CREATE TABLE bit_defaults( + b1 bit(4) DEFAULT '1001', + b2 bit(4) DEFAULT B'0101', + b3 bit varying(5) DEFAULT '1001', + b4 bit varying(5) DEFAULT B'0101' +); +\d bit_defaults + Table "public.bit_defaults" + Column | Type | Collation | Nullable | Default +--------+----------------+-----------+----------+--------------------- + b1 | bit(4) | | | '1001'::"bit" + b2 | bit(4) | | | '0101'::"bit" + b3 | bit varying(5) | | | '1001'::bit varying + b4 | bit varying(5) | | | '0101'::"bit" + +INSERT INTO bit_defaults DEFAULT VALUES; +TABLE bit_defaults; + b1 | b2 | b3 | b4 +------+------+------+------ + 1001 | 0101 | 1001 | 0101 +(1 row) + diff --git a/src/test/regress/expected/box.out b/src/test/regress/expected/box.out index 49af242c8ce..4d0f169214f 100644 --- a/src/test/regress/expected/box.out +++ b/src/test/regress/expected/box.out @@ -18,6 +18,7 @@ CREATE TABLE BOX_TBL (f1 box); INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)'); INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)'); +INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))'); -- degenerate cases where the box is a line or a point -- note that lines and points boxes all have zero area INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)'); @@ -27,6 +28,18 @@ INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)'); ERROR: invalid input syntax for type box: "(2.3, 4.5)" LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)'); ^ +INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)'); +ERROR: invalid input syntax for type box: "[1, 2, 3, 4)" +LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)'); + ^ +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]'); +ERROR: invalid input syntax for type box: "(1, 2, 3, 4]" +LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]'); + ^ +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x'); +ERROR: invalid input syntax for type box: "(1, 2, 3, 4) x" +LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x'); + ^ INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad'); ERROR: invalid input syntax for type box: "asdfasdf(ad" LINE 1: INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad'); @@ -36,9 +49,10 @@ SELECT '' AS four, * FROM BOX_TBL; ------+--------------------- | (2,2),(0,0) | (3,3),(1,1) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | (3,3),(3,3) -(4 rows) +(5 rows) SELECT '' AS four, b.*, area(b.f1) as barea FROM BOX_TBL b; @@ -46,9 +60,10 @@ SELECT '' AS four, b.*, area(b.f1) as barea ------+---------------------+------- | (2,2),(0,0) | 4 | (3,3),(1,1) | 4 + | (-2,2),(-8,-10) | 72 | (2.5,3.5),(2.5,2.5) | 0 | (3,3),(3,3) | 0 -(4 rows) +(5 rows) -- overlap SELECT '' AS three, b.f1 @@ -68,8 +83,9 @@ SELECT '' AS two, b1.* two | f1 -----+--------------------- | (2,2),(0,0) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) -(2 rows) +(3 rows) -- right-or-overlap (x only) SELECT '' AS two, b1.* @@ -88,8 +104,9 @@ SELECT '' AS two, b.f1 two | f1 -----+--------------------- | (2,2),(0,0) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) -(2 rows) +(3 rows) -- area <= SELECT '' AS four, b.f1 @@ -127,11 +144,12 @@ SELECT '' AS two, b.f1 SELECT '' AS two, b.f1 FROM BOX_TBL b -- zero area WHERE b.f1 > box '(3.5,3.0,4.5,3.0)'; - two | f1 ------+------------- + two | f1 +-----+----------------- | (2,2),(0,0) | (3,3),(1,1) -(2 rows) + | (-2,2),(-8,-10) +(3 rows) -- area >= SELECT '' AS four, b.f1 @@ -141,9 +159,10 @@ SELECT '' AS four, b.f1 ------+--------------------- | (2,2),(0,0) | (3,3),(1,1) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | (3,3),(3,3) -(4 rows) +(5 rows) -- right of SELECT '' AS two, b.f1 @@ -152,8 +171,9 @@ SELECT '' AS two, b.f1 two | f1 -----+--------------------- | (2,2),(0,0) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) -(2 rows) +(3 rows) -- contained in SELECT '' AS three, b.f1 @@ -193,9 +213,10 @@ SELECT '' AS four, @@(b1.f1) AS p ------+--------- | (1,1) | (2,2) + | (-5,-4) | (2.5,3) | (3,3) -(4 rows) +(5 rows) -- wholly-contained SELECT '' AS one, b1.*, b2.* @@ -211,9 +232,10 @@ SELECT '' AS four, height(f1), width(f1) FROM BOX_TBL; ------+--------+------- | 2 | 2 | 2 | 2 + | 12 | 6 | 1 | 0 | 0 | 0 -(4 rows) +(5 rows) -- -- Test the SP-GiST index @@ -458,23 +480,33 @@ DROP INDEX box_spgist; -- -- Test the SP-GiST index on the larger volume of data -- -CREATE TABLE quad_box_tbl (b box); +CREATE TABLE quad_box_tbl (id int, b box); INSERT INTO quad_box_tbl - SELECT box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) - FROM generate_series(1, 100) x, - generate_series(1, 100) y; + SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y; -- insert repeating data to test allTheSame INSERT INTO quad_box_tbl - SELECT '((200, 300),(210, 310))' - FROM generate_series(1, 1000); + SELECT i, '((200, 300),(210, 310))' + FROM generate_series(10001, 11000) AS i; INSERT INTO quad_box_tbl - VALUES - (NULL), - (NULL), - ('((-infinity,-infinity),(infinity,infinity))'), - ('((-infinity,100),(-infinity,500))'), - ('((-infinity,-infinity),(700,infinity))'); +VALUES + (11001, NULL), + (11002, NULL), + (11003, '((-infinity,-infinity),(infinity,infinity))'), + (11004, '((-infinity,100),(-infinity,500))'), + (11005, '((-infinity,-infinity),(700,infinity))'); CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b); +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON; +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; +CREATE TABLE quad_box_tbl_ord_seq1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; +CREATE TABLE quad_box_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; SET enable_seqscan = OFF; SET enable_indexscan = ON; SET enable_bitmapscan = ON; @@ -556,6 +588,54 @@ SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))'; 1 (1 row) +-- test ORDER BY distance +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + QUERY PLAN +--------------------------------------------------------- + WindowAgg + -> Index Scan using quad_box_tbl_idx on quad_box_tbl + Order By: (b <-> '(123,456)'::point) +(3 rows) + +CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; +SELECT * +FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + n | dist | id | n | dist | id +---+------+----+---+------+---- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + QUERY PLAN +--------------------------------------------------------- + WindowAgg + -> Index Scan using quad_box_tbl_idx on quad_box_tbl + Index Cond: (b <@ '(500,600),(200,300)'::box) + Order By: (b <-> '(123,456)'::point) +(4 rows) + +CREATE TEMP TABLE quad_box_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; +SELECT * +FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + n | dist | id | n | dist | id +---+------+----+---+------+---- +(0 rows) + RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; diff --git a/src/test/regress/expected/btree_index.out b/src/test/regress/expected/btree_index.out index 4778ac14a4c..acab8e0b115 100644 --- a/src/test/regress/expected/btree_index.out +++ b/src/test/regress/expected/btree_index.out @@ -105,6 +105,15 @@ SELECT b.* set enable_seqscan to false; set enable_indexscan to true; set enable_bitmapscan to false; +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + QUERY PLAN +------------------------------------------------------------------------------ + Index Only Scan using pg_proc_proname_args_nsp_index on pg_proc + Index Cond: ((proname >= 'RI_FKey'::text) AND (proname < 'RI_FKez'::text)) + Filter: (proname ~~ 'RI\_FKey%del'::text) +(3 rows) + select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; proname ------------------------ @@ -115,8 +124,42 @@ select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; RI_FKey_setnull_del (5 rows) +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1; + QUERY PLAN +-------------------------------------------------------------------- + Index Only Scan using pg_proc_proname_args_nsp_index on pg_proc + Index Cond: ((proname >= '00'::text) AND (proname < '01'::text)) + Filter: (proname ~~* '00%foo'::text) +(3 rows) + +select proname from pg_proc where proname ilike '00%foo' order by 1; + proname +--------- +(0 rows) + +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1; + QUERY PLAN +----------------------------------------------------------------- + Index Only Scan using pg_proc_proname_args_nsp_index on pg_proc + Filter: (proname ~~* 'ri%foo'::text) +(2 rows) + set enable_indexscan to false; set enable_bitmapscan to true; +explain (costs off) +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------ + Sort + Sort Key: proname + -> Bitmap Heap Scan on pg_proc + Filter: (proname ~~ 'RI\_FKey%del'::text) + -> Bitmap Index Scan on pg_proc_proname_args_nsp_index + Index Cond: ((proname >= 'RI_FKey'::text) AND (proname < 'RI_FKez'::text)) +(6 rows) + select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; proname ------------------------ @@ -127,29 +170,51 @@ select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; RI_FKey_setnull_del (5 rows) +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1; + QUERY PLAN +-------------------------------------------------------------------------------- + Sort + Sort Key: proname + -> Bitmap Heap Scan on pg_proc + Filter: (proname ~~* '00%foo'::text) + -> Bitmap Index Scan on pg_proc_proname_args_nsp_index + Index Cond: ((proname >= '00'::text) AND (proname < '01'::text)) +(6 rows) + +select proname from pg_proc where proname ilike '00%foo' order by 1; + proname +--------- +(0 rows) + +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1; + QUERY PLAN +----------------------------------------------------------------- + Index Only Scan using pg_proc_proname_args_nsp_index on pg_proc + Filter: (proname ~~* 'ri%foo'::text) +(2 rows) + +reset enable_seqscan; +reset enable_indexscan; +reset enable_bitmapscan; -- --- Test B-tree page deletion. In particular, deleting a non-leaf page. +-- Test B-tree fast path (cache rightmost leaf page) optimization. -- --- First create a tree that's at least four levels deep. The text inserted --- is long and poorly compressible. That way only a few index tuples fit on --- each page, allowing us to get a tall tree with fewer pages. -create table btree_tall_tbl(id int4, t text); -create index btree_tall_idx on btree_tall_tbl (id, t) with (fillfactor = 10); -insert into btree_tall_tbl - select g, g::text || '_' || - (select string_agg(md5(i::text), '_') from generate_series(1, 50) i) -from generate_series(1, 100) g; --- Delete most entries, and vacuum. This causes page deletions. -delete from btree_tall_tbl where id < 950; -vacuum btree_tall_tbl; +-- First create a tree that's at least three levels deep (i.e. has one level +-- between the root and leaf levels). The text inserted is long. It won't be +-- compressed because we use plain storage in the table. Only a few index +-- tuples fit on each internal page, allowing us to get a tall tree with few +-- pages. (A tall tree is required to trigger caching.) -- --- Test B-tree insertion with a metapage update (XLOG_BTREE_INSERT_META --- WAL record type). This happens when a "fast root" page is split. --- --- The vacuum above should've turned the leaf page into a fast root. We just --- need to insert some rows to cause the fast root page to split. -insert into btree_tall_tbl (id, t) - select g, repeat('x', 100) from generate_series(1, 500) g; +-- The text column must be the leading column in the index, since suffix +-- truncation would otherwise truncate tuples on internal pages, leaving us +-- with a short tree. +create table btree_tall_tbl(id int4, t text); +alter table btree_tall_tbl alter COLUMN t set storage plain; +create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10); +insert into btree_tall_tbl select g, repeat('x', 250) +from generate_series(1, 130) g; -- -- Test vacuum_cleanup_index_scale_factor -- @@ -165,7 +230,7 @@ select reloptions from pg_class WHERE oid = 'btree_idx1'::regclass; -- Fail while setting improper values create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = -10.0); ERROR: value -10.0 out of bounds for option "vacuum_cleanup_index_scale_factor" -DETAIL: Valid values are between "0.000000" and "100.000000". +DETAIL: Valid values are between "0.000000" and "10000000000.000000". create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = 100.0); create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_factor = 'string'); ERROR: invalid value for floating point option "vacuum_cleanup_index_scale_factor": string @@ -179,3 +244,21 @@ select reloptions from pg_class WHERE oid = 'btree_idx1'::regclass; {vacuum_cleanup_index_scale_factor=70.0} (1 row) +-- +-- Test for multilevel page deletion +-- +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990; +VACUUM delete_test_table; +-- +-- Test B-tree insertion with a metapage update (XLOG_BTREE_INSERT_META +-- WAL record type). This happens when a "fast root" page is split. This +-- also creates coverage for nbtree FSM page recycling. +-- +-- The vacuum above should've turned the leaf page into a fast root. We just +-- need to insert some rows to cause the fast root page to split. +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; diff --git a/src/test/regress/expected/case.out b/src/test/regress/expected/case.out index 36bf15c4acb..c0c8acf035a 100644 --- a/src/test/regress/expected/case.out +++ b/src/test/regress/expected/case.out @@ -372,6 +372,20 @@ SELECT CASE make_ad(1,2) right (1 row) +ROLLBACK; +-- Test interaction of CASE with ArrayCoerceExpr (bug #15471) +BEGIN; +CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g'); +SELECT + CASE 'foo'::text + WHEN 'foo' THEN ARRAY['a', 'b', 'c', 'd'] || enum_range(NULL::casetestenum)::text[] + ELSE ARRAY['x', 'y'] + END; + array +----------------- + {a,b,c,d,e,f,g} +(1 row) + ROLLBACK; -- -- Clean up diff --git a/src/test/regress/expected/circle.out b/src/test/regress/expected/circle.out index 9ba4a0495d2..218300f1263 100644 --- a/src/test/regress/expected/circle.out +++ b/src/test/regress/expected/circle.out @@ -1,18 +1,31 @@ -- -- CIRCLE -- +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits = -1; CREATE TABLE CIRCLE_TBL (f1 circle); INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>'); INSERT INTO CIRCLE_TBL VALUES ('<(1,2),100>'); INSERT INTO CIRCLE_TBL VALUES ('1,3,5'); INSERT INTO CIRCLE_TBL VALUES ('((1,2),3)'); INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10>'); -INSERT INTO CIRCLE_TBL VALUES ('<(100,1),115>'); +INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > '); +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>'); -- Zero radius +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>'); -- NaN radius -- bad values INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>'); ERROR: invalid input syntax for type circle: "<(-100,0),-100>" LINE 1: INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>'); ^ +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10'); +ERROR: invalid input syntax for type circle: "<(100,200),10" +LINE 1: INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10'); + ^ +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x'); +ERROR: invalid input syntax for type circle: "<(100,200),10> x" +LINE 1: INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x'); + ^ INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5'); ERROR: invalid input syntax for type circle: "1abc,3,5" LINE 1: INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5'); @@ -30,7 +43,9 @@ SELECT * FROM CIRCLE_TBL; <(1,2),3> <(100,200),10> <(100,1),115> -(6 rows) + <(3,5),0> + <(3,5),NaN> +(8 rows) SELECT '' AS six, center(f1) AS center FROM CIRCLE_TBL; @@ -42,7 +57,9 @@ SELECT '' AS six, center(f1) AS center | (1,2) | (100,200) | (100,1) -(6 rows) + | (3,5) + | (3,5) +(8 rows) SELECT '' AS six, radius(f1) AS radius FROM CIRCLE_TBL; @@ -54,7 +71,9 @@ SELECT '' AS six, radius(f1) AS radius | 3 | 10 | 115 -(6 rows) + | 0 + | NaN +(8 rows) SELECT '' AS six, diameter(f1) AS diameter FROM CIRCLE_TBL; @@ -66,14 +85,17 @@ SELECT '' AS six, diameter(f1) AS diameter | 6 | 20 | 230 -(6 rows) + | 0 + | NaN +(8 rows) SELECT '' AS two, f1 FROM CIRCLE_TBL WHERE radius(f1) < 5; two | f1 -----+----------- | <(5,1),3> | <(1,2),3> -(2 rows) + | <(3,5),0> +(3 rows) SELECT '' AS four, f1 FROM CIRCLE_TBL WHERE diameter(f1) >= 10; four | f1 @@ -82,7 +104,8 @@ SELECT '' AS four, f1 FROM CIRCLE_TBL WHERE diameter(f1) >= 10; | <(1,3),5> | <(100,200),10> | <(100,1),115> -(4 rows) + | <(3,5),NaN> +(5 rows) SELECT '' as five, c1.f1 AS one, c2.f1 AS two, (c1.f1 <-> c2.f1) AS distance FROM CIRCLE_TBL c1, CIRCLE_TBL c2 @@ -90,10 +113,13 @@ SELECT '' as five, c1.f1 AS one, c2.f1 AS two, (c1.f1 <-> c2.f1) AS distance ORDER BY distance, area(c1.f1), area(c2.f1); five | one | two | distance ------+----------------+----------------+------------------ + | <(3,5),0> | <(1,2),3> | 0.60555127546399 + | <(3,5),0> | <(5,1),3> | 1.4721359549996 | <(100,200),10> | <(100,1),115> | 74 - | <(100,200),10> | <(1,2),100> | 111.370729772479 - | <(1,3),5> | <(100,200),10> | 205.476756144497 + | <(100,200),10> | <(1,2),100> | 111.37072977248 + | <(1,3),5> | <(100,200),10> | 205.4767561445 | <(5,1),3> | <(100,200),10> | 207.51303816328 - | <(1,2),3> | <(100,200),10> | 208.370729772479 -(5 rows) + | <(3,5),0> | <(100,200),10> | 207.79348015953 + | <(1,2),3> | <(100,200),10> | 208.37072977248 +(8 rows) diff --git a/src/test/regress/expected/collate.icu.utf8.out b/src/test/regress/expected/collate.icu.utf8.out index e8cf5d50d1d..2b86ce90286 100644 --- a/src/test/regress/expected/collate.icu.utf8.out +++ b/src/test/regress/expected/collate.icu.utf8.out @@ -1,6 +1,13 @@ /* * This test is for ICU collations. */ +/* skip test if not UTF8 server encoding or no ICU collations installed */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i') = 0 + AS skip_test \gset +\if :skip_test +\quit +\endif SET client_encoding TO UTF8; CREATE SCHEMA collate_tests; SET search_path = collate_tests; @@ -976,6 +983,38 @@ SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_t collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_tests.collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX") (4 rows) +set enable_seqscan = off; +explain (costs off) +select * from collate_test1 where b ilike 'abc'; + QUERY PLAN +------------------------------- + Seq Scan on collate_test1 + Filter: (b ~~* 'abc'::text) +(2 rows) + +select * from collate_test1 where b ilike 'abc'; + a | b +---+----- + 1 | abc + 4 | ABC +(2 rows) + +explain (costs off) +select * from collate_test1 where b ilike 'ABC'; + QUERY PLAN +------------------------------- + Seq Scan on collate_test1 + Filter: (b ~~* 'ABC'::text) +(2 rows) + +select * from collate_test1 where b ilike 'ABC'; + a | b +---+----- + 1 | abc + 4 | ABC +(2 rows) + +reset enable_seqscan; -- schema manipulation commands CREATE ROLE regress_test_role; CREATE SCHEMA test_schema; @@ -1056,17 +1095,17 @@ CREATE TABLE collate_dep_test4t (a int, b text); CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0); DROP COLLATION test0 RESTRICT; -- fail ERROR: cannot drop collation test0 because other objects depend on it -DETAIL: table collate_dep_test1 column b depends on collation test0 +DETAIL: column b of table collate_dep_test1 depends on collation test0 type collate_dep_dom1 depends on collation test0 -composite type collate_dep_test2 column y depends on collation test0 +column y of composite type collate_dep_test2 depends on collation test0 view collate_dep_test3 depends on collation test0 index collate_dep_test4i depends on collation test0 HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP COLLATION test0 CASCADE; NOTICE: drop cascades to 5 other objects -DETAIL: drop cascades to table collate_dep_test1 column b +DETAIL: drop cascades to column b of table collate_dep_test1 drop cascades to type collate_dep_dom1 -drop cascades to composite type collate_dep_test2 column y +drop cascades to column y of composite type collate_dep_test2 drop cascades to view collate_dep_test3 drop cascades to index collate_dep_test4i \d collate_dep_test1 @@ -1100,27 +1139,771 @@ select textrange_en_us('A','Z') @> 'b'::text; drop type textrange_c; drop type textrange_en_us; +-- test ICU collation customization +-- test the attributes handled by icu_set_collation_attributes() +CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes'); +SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes'); +SELECT 'coté' < 'côte' COLLATE "und-x-icu", 'coté' > 'côte' COLLATE testcoll_backwards; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower'); +CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper'); +SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted'); +SELECT 'de-luge' < 'deanza' COLLATE "und-x-icu", 'de-luge' > 'deanza' COLLATE testcoll_shifted; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes'); +SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_numeric; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower'); +ERROR: could not open collator for locale "@colNumeric=lower": U_ILLEGAL_ARGUMENT_ERROR +-- test that attributes not handled by icu_set_collation_attributes() +-- (handled by ucol_open() directly) also work +CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook'); +SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +-- nondeterministic collations +CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true); +CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false); +CREATE TABLE test6 (a int, b text); +-- same string in different normal forms +INSERT INTO test6 VALUES (1, U&'\00E4bc'); +INSERT INTO test6 VALUES (2, U&'\0061\0308bc'); +SELECT * FROM test6; + a | b +---+----- + 1 | äbc + 2 | äbc +(2 rows) + +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det; + a | b +---+----- + 1 | äbc +(1 row) + +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet; + a | b +---+----- + 1 | äbc + 2 | äbc +(2 rows) + +CREATE COLLATION case_sensitive (provider = icu, locale = ''); +CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false); +SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive; + ?column? | ?column? +----------+---------- + t | f +(1 row) + +SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive; + ?column? | ?column? +----------+---------- + t | t +(1 row) + +CREATE TABLE test1cs (x text COLLATE case_sensitive); +CREATE TABLE test2cs (x text COLLATE case_sensitive); +CREATE TABLE test3cs (x text COLLATE case_sensitive); +INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2cs VALUES ('ABC'), ('ghi'); +INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi'); +SELECT x FROM test3cs WHERE x = 'abc'; + x +----- + abc +(1 row) + +SELECT x FROM test3cs WHERE x <> 'abc'; + x +----- + ABC + def + ghi +(3 rows) + +SELECT x FROM test3cs WHERE x LIKE 'a%'; + x +----- + abc +(1 row) + +SELECT x FROM test3cs WHERE x ILIKE 'a%'; + x +----- + abc + ABC +(2 rows) + +SELECT x FROM test3cs WHERE x SIMILAR TO 'a%'; + x +----- + abc +(1 row) + +SELECT x FROM test3cs WHERE x ~ 'a'; + x +----- + abc +(1 row) + +SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x; + x +----- + abc + ABC + def + ghi +(4 rows) + +SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x; + x +----- + abc + ABC + def + ghi +(4 rows) + +SELECT x FROM test1cs INTERSECT SELECT x FROM test2cs; + x +----- + ghi +(1 row) + +SELECT x FROM test2cs INTERSECT SELECT x FROM test1cs; + x +----- + ghi +(1 row) + +SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs; + x +----- + abc + def +(2 rows) + +SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs; + x +----- + ABC +(1 row) + +SELECT DISTINCT x FROM test3cs ORDER BY x; + x +----- + abc + ABC + def + ghi +(4 rows) + +SELECT count(DISTINCT x) FROM test3cs; + count +------- + 4 +(1 row) + +SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x; + x | count +-----+------- + abc | 1 + ABC | 1 + def | 1 + ghi | 1 +(4 rows) + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x; + x | row_number | rank +-----+------------+------ + abc | 1 | 1 + ABC | 2 | 2 + def | 3 | 3 + ghi | 4 | 4 +(4 rows) + +CREATE UNIQUE INDEX ON test1cs (x); -- ok +INSERT INTO test1cs VALUES ('ABC'); -- ok +CREATE UNIQUE INDEX ON test3cs (x); -- ok +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc'); + string_to_array +----------------- + {ABC,DEF,GHI} +(1 row) + +SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b'); + string_to_array +--------------------- + {A,B,C,D,E,F,G,H,I} +(1 row) + +CREATE TABLE test1ci (x text COLLATE case_insensitive); +CREATE TABLE test2ci (x text COLLATE case_insensitive); +CREATE TABLE test3ci (x text COLLATE case_insensitive); +CREATE INDEX ON test3ci (x text_pattern_ops); -- error +ERROR: nondeterministic collations are not supported for operator class "text_pattern_ops" +INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2ci VALUES ('ABC'), ('ghi'); +INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); +SELECT x FROM test3ci WHERE x = 'abc'; + x +----- + abc + ABC +(2 rows) + +SELECT x FROM test3ci WHERE x <> 'abc'; + x +----- + def + ghi +(2 rows) + +SELECT x FROM test3ci WHERE x LIKE 'a%'; +ERROR: nondeterministic collations are not supported for LIKE +SELECT x FROM test3ci WHERE x ILIKE 'a%'; +ERROR: nondeterministic collations are not supported for ILIKE +SELECT x FROM test3ci WHERE x SIMILAR TO 'a%'; +ERROR: nondeterministic collations are not supported for regular expressions +SELECT x FROM test3ci WHERE x ~ 'a'; +ERROR: nondeterministic collations are not supported for regular expressions +SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x; + x +----- + abc + def + ghi +(3 rows) + +SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x; + x +----- + ABC + def + ghi +(3 rows) + +SELECT x FROM test1ci INTERSECT SELECT x FROM test2ci ORDER BY x; + x +----- + abc + ghi +(2 rows) + +SELECT x FROM test2ci INTERSECT SELECT x FROM test1ci ORDER BY x; + x +----- + ABC + ghi +(2 rows) + +SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci; + x +----- + def +(1 row) + +SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci; + x +--- +(0 rows) + +SELECT DISTINCT x FROM test3ci ORDER BY x; + x +----- + abc + def + ghi +(3 rows) + +SELECT count(DISTINCT x) FROM test3ci; + count +------- + 3 +(1 row) + +SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x; + x | count +-----+------- + abc | 2 + def | 1 + ghi | 1 +(3 rows) + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x; + x | row_number | rank +-----+------------+------ + abc | 1 | 1 + ABC | 2 | 1 + def | 3 | 3 + ghi | 4 | 4 +(4 rows) + +CREATE UNIQUE INDEX ON test1ci (x); -- ok +INSERT INTO test1ci VALUES ('ABC'); -- error +ERROR: duplicate key value violates unique constraint "test1ci_x_idx" +DETAIL: Key (x)=(ABC) already exists. +CREATE UNIQUE INDEX ON test3ci (x); -- error +ERROR: could not create unique index "test3ci_x_idx" +DETAIL: Key (x)=(abc) is duplicated. +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc'); +ERROR: nondeterministic collations are not supported for substring searches +SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b'); + string_to_array +------------------------ + {A,NULL,C,D,E,F,G,H,I} +(1 row) + +-- bpchar +CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive); +CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive); +CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive); +CREATE INDEX ON test3bpci (x bpchar_pattern_ops); -- error +ERROR: nondeterministic collations are not supported for operator class "bpchar_pattern_ops" +INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2bpci VALUES ('ABC'), ('ghi'); +INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); +SELECT x FROM test3bpci WHERE x = 'abc'; + x +----- + abc + ABC +(2 rows) + +SELECT x FROM test3bpci WHERE x <> 'abc'; + x +----- + def + ghi +(2 rows) + +SELECT x FROM test3bpci WHERE x LIKE 'a%'; +ERROR: nondeterministic collations are not supported for LIKE +SELECT x FROM test3bpci WHERE x ILIKE 'a%'; +ERROR: nondeterministic collations are not supported for ILIKE +SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%'; +ERROR: nondeterministic collations are not supported for regular expressions +SELECT x FROM test3bpci WHERE x ~ 'a'; +ERROR: nondeterministic collations are not supported for regular expressions +SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x; + x +----- + abc + def + ghi +(3 rows) + +SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x; + x +----- + ABC + def + ghi +(3 rows) + +SELECT x FROM test1bpci INTERSECT SELECT x FROM test2bpci ORDER BY x; + x +----- + abc + ghi +(2 rows) + +SELECT x FROM test2bpci INTERSECT SELECT x FROM test1bpci ORDER BY x; + x +----- + ABC + ghi +(2 rows) + +SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci; + x +----- + def +(1 row) + +SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci; + x +--- +(0 rows) + +SELECT DISTINCT x FROM test3bpci ORDER BY x; + x +----- + abc + def + ghi +(3 rows) + +SELECT count(DISTINCT x) FROM test3bpci; + count +------- + 3 +(1 row) + +SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x; + x | count +-----+------- + abc | 2 + def | 1 + ghi | 1 +(3 rows) + +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x; + x | row_number | rank +-----+------------+------ + abc | 1 | 1 + ABC | 2 | 1 + def | 3 | 3 + ghi | 4 | 4 +(4 rows) + +CREATE UNIQUE INDEX ON test1bpci (x); -- ok +INSERT INTO test1bpci VALUES ('ABC'); -- error +ERROR: duplicate key value violates unique constraint "test1bpci_x_idx" +DETAIL: Key (x)=(ABC) already exists. +CREATE UNIQUE INDEX ON test3bpci (x); -- error +ERROR: could not create unique index "test3bpci_x_idx" +DETAIL: Key (x)=(abc) is duplicated. +SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc'); +ERROR: nondeterministic collations are not supported for substring searches +SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b'); + string_to_array +------------------------ + {A,NULL,C,D,E,F,G,H,I} +(1 row) + +-- This tests the issue described in match_pattern_prefix(). In the +-- absence of that check, the case_insensitive tests below would +-- return no rows where they should logically return one. +CREATE TABLE test4c (x text COLLATE "C"); +INSERT INTO test4c VALUES ('abc'); +CREATE INDEX ON test4c (x); +SET enable_seqscan = off; +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive; -- ok, no rows + x +--- +(0 rows) + +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive; -- ok, no rows + x +--- +(0 rows) + +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive; -- error +ERROR: nondeterministic collations are not supported for LIKE +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive; -- error +ERROR: nondeterministic collations are not supported for LIKE +RESET enable_seqscan; +-- Unicode special case: different variants of Greek lower case sigma. +-- A naive implementation like citext that just does lower(x) = +-- lower(y) will do the wrong thing here, because lower('Σ') is 'σ' +-- but upper('Ï‚') is 'Σ'. +SELECT 'ὀδυσσεÏÏ‚' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive; + ?column? +---------- + f +(1 row) + +SELECT 'ὀδυσσεÏÏ‚' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive; + ?column? +---------- + t +(1 row) + +-- name vs. text comparison operators +SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive; + relname +---------- + pg_class +(1 row) + +SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive; + relname +---------- + pg_class +(1 row) + +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND typname <> 'INT2'::text + COLLATE case_insensitive ORDER BY typname; + typname +--------- + int4 + int8 +(2 rows) + +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND 'INT2'::text <> typname + COLLATE case_insensitive ORDER BY typname; + typname +--------- + int4 + int8 +(2 rows) + +-- test case adapted from subselect.sql +CREATE TEMP TABLE outer_text (f1 text COLLATE case_insensitive, f2 text); +INSERT INTO outer_text VALUES ('a', 'a'); +INSERT INTO outer_text VALUES ('b', 'a'); +INSERT INTO outer_text VALUES ('A', NULL); +INSERT INTO outer_text VALUES ('B', NULL); +CREATE TEMP TABLE inner_text (c1 text COLLATE case_insensitive, c2 text); +INSERT INTO inner_text VALUES ('a', NULL); +SELECT * FROM outer_text WHERE (f1, f2) NOT IN (SELECT * FROM inner_text); + f1 | f2 +----+---- + b | a + B | +(2 rows) + +-- accents +CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes', deterministic = false); +CREATE TABLE test4 (a int, b text); +INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté'); +SELECT * FROM test4 WHERE b = 'cote'; + a | b +---+------ + 1 | cote +(1 row) + +SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents; + a | b +---+------ + 1 | cote + 2 | côte + 3 | coté + 4 | côté +(4 rows) + +SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents; -- still case-sensitive + a | b +---+--- +(0 rows) + +SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive; + a | b +---+------ + 1 | cote +(1 row) + +-- foreign keys (should use collation of primary key) +-- PK is case-sensitive, FK is case-insensitive +CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY); +INSERT INTO test10pk VALUES ('abc'), ('def'), ('ghi'); +CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); +INSERT INTO test10fk VALUES ('abc'); -- ok +INSERT INTO test10fk VALUES ('ABC'); -- error +ERROR: insert or update on table "test10fk" violates foreign key constraint "test10fk_x_fkey" +DETAIL: Key (x)=(ABC) is not present in table "test10pk". +INSERT INTO test10fk VALUES ('xyz'); -- error +ERROR: insert or update on table "test10fk" violates foreign key constraint "test10fk_x_fkey" +DETAIL: Key (x)=(xyz) is not present in table "test10pk". +SELECT * FROM test10pk; + x +----- + abc + def + ghi +(3 rows) + +SELECT * FROM test10fk; + x +----- + abc +(1 row) + +-- restrict update even though the values are "equal" in the FK table +UPDATE test10fk SET x = 'ABC' WHERE x = 'abc'; -- error +ERROR: insert or update on table "test10fk" violates foreign key constraint "test10fk_x_fkey" +DETAIL: Key (x)=(ABC) is not present in table "test10pk". +SELECT * FROM test10fk; + x +----- + abc +(1 row) + +DELETE FROM test10pk WHERE x = 'abc'; +SELECT * FROM test10pk; + x +----- + def + ghi +(2 rows) + +SELECT * FROM test10fk; + x +--- +(0 rows) + +-- PK is case-insensitive, FK is case-sensitive +CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY); +INSERT INTO test11pk VALUES ('abc'), ('def'), ('ghi'); +CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE); +INSERT INTO test11fk VALUES ('abc'); -- ok +INSERT INTO test11fk VALUES ('ABC'); -- ok +INSERT INTO test11fk VALUES ('xyz'); -- error +ERROR: insert or update on table "test11fk" violates foreign key constraint "test11fk_x_fkey" +DETAIL: Key (x)=(xyz) is not present in table "test11pk". +SELECT * FROM test11pk; + x +----- + abc + def + ghi +(3 rows) + +SELECT * FROM test11fk; + x +----- + abc + ABC +(2 rows) + +-- cascade update even though the values are "equal" in the PK table +UPDATE test11pk SET x = 'ABC' WHERE x = 'abc'; +SELECT * FROM test11fk; + x +----- + ABC + ABC +(2 rows) + +DELETE FROM test11pk WHERE x = 'abc'; +SELECT * FROM test11pk; + x +----- + def + ghi +(2 rows) + +SELECT * FROM test11fk; + x +--- +(0 rows) + +-- partitioning +CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b); +CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc'); +INSERT INTO test20 VALUES (1, 'abc'); +INSERT INTO test20 VALUES (2, 'ABC'); +SELECT * FROM test20_1; + a | b +---+----- + 1 | abc + 2 | ABC +(2 rows) + +CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b); +CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF'); +INSERT INTO test21 VALUES (1, 'abc'); +INSERT INTO test21 VALUES (2, 'ABC'); +SELECT * FROM test21_1; + a | b +---+----- + 1 | abc + 2 | ABC +(2 rows) + +CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b); +CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test22 VALUES (1, 'def'); +INSERT INTO test22 VALUES (2, 'DEF'); +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1); + ?column? +---------- + t +(1 row) + +CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b); +CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test23 VALUES (1, 'def'); +INSERT INTO test23 VALUES (2, 'DEF'); +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1); + ?column? +---------- + t +(1 row) + +CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b); +CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc'); +INSERT INTO test30 VALUES (1, 'abc'); +INSERT INTO test30 VALUES (2, 'ABC'); +SELECT * FROM test30_1; + a | b +---+----- + 1 | abc + 2 | ABC +(2 rows) + +CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b); +CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF'); +INSERT INTO test31 VALUES (1, 'abc'); +INSERT INTO test31 VALUES (2, 'ABC'); +SELECT * FROM test31_1; + a | b +---+----- + 1 | abc + 2 | ABC +(2 rows) + +CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b); +CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test32 VALUES (1, 'def'); +INSERT INTO test32 VALUES (2, 'DEF'); +-- they end up in different partitions +SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1); + ?column? +---------- + t +(1 row) + +CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b); +CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test33 VALUES (1, 'def'); +INSERT INTO test33 VALUES (2, 'DEF'); +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1); + ?column? +---------- + t +(1 row) + -- cleanup -DROP SCHEMA collate_tests CASCADE; -NOTICE: drop cascades to 18 other objects -DETAIL: drop cascades to table collate_test1 -drop cascades to table collate_test_like -drop cascades to table collate_test2 -drop cascades to table collate_test3 -drop cascades to type testdomain_sv -drop cascades to table collate_test4 -drop cascades to table collate_test5 -drop cascades to table collate_test10 -drop cascades to table collate_test6 -drop cascades to view collview1 -drop cascades to view collview2 -drop cascades to view collview3 -drop cascades to type testdomain -drop cascades to function mylt(text,text) -drop cascades to function mylt_noninline(text,text) -drop cascades to function mylt_plpgsql(text,text) -drop cascades to function mylt2(text,text) -drop cascades to function dup(anyelement) RESET search_path; +SET client_min_messages TO warning; +DROP SCHEMA collate_tests CASCADE; +RESET client_min_messages; -- leave a collation for pg_upgrade test CREATE COLLATION coll_icu_upgrade FROM "und-x-icu"; diff --git a/src/test/regress/expected/collate.icu.utf8_1.out b/src/test/regress/expected/collate.icu.utf8_1.out new file mode 100644 index 00000000000..a6a33b39aba --- /dev/null +++ b/src/test/regress/expected/collate.icu.utf8_1.out @@ -0,0 +1,9 @@ +/* + * This test is for ICU collations. + */ +/* skip test if not UTF8 server encoding or no ICU collations installed */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i') = 0 + AS skip_test \gset +\if :skip_test +\quit diff --git a/src/test/regress/expected/collate.linux.utf8.out b/src/test/regress/expected/collate.linux.utf8.out index 4eb2322e539..ad56ff9caa3 100644 --- a/src/test/regress/expected/collate.linux.utf8.out +++ b/src/test/regress/expected/collate.linux.utf8.out @@ -3,6 +3,13 @@ * locales is installed. It must be run in a database with UTF-8 encoding, * because other encodings don't support all the characters used. */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test \gset +\if :skip_test +\quit +\endif SET client_encoding TO UTF8; CREATE SCHEMA collate_tests; SET search_path = collate_tests; @@ -430,6 +437,18 @@ SELECT relname FROM pg_class WHERE relname ~* '^abc'; -- to_char SET lc_time TO 'tr_TR'; +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY'); + to_char +------------- + 01 ÅžUB 2010 +(1 row) + +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY' COLLATE "tr_TR"); + to_char +------------- + 01 ÅžUB 2010 +(1 row) + SELECT to_char(date '2010-04-01', 'DD TMMON YYYY'); to_char ------------- @@ -1073,17 +1092,17 @@ CREATE TABLE collate_dep_test4t (a int, b text); CREATE INDEX collate_dep_test4i ON collate_dep_test4t (b COLLATE test0); DROP COLLATION test0 RESTRICT; -- fail ERROR: cannot drop collation test0 because other objects depend on it -DETAIL: table collate_dep_test1 column b depends on collation test0 +DETAIL: column b of table collate_dep_test1 depends on collation test0 type collate_dep_dom1 depends on collation test0 -composite type collate_dep_test2 column y depends on collation test0 +column y of composite type collate_dep_test2 depends on collation test0 view collate_dep_test3 depends on collation test0 index collate_dep_test4i depends on collation test0 HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP COLLATION test0 CASCADE; NOTICE: drop cascades to 5 other objects -DETAIL: drop cascades to table collate_dep_test1 column b +DETAIL: drop cascades to column b of table collate_dep_test1 drop cascades to type collate_dep_dom1 -drop cascades to composite type collate_dep_test2 column y +drop cascades to column y of composite type collate_dep_test2 drop cascades to view collate_dep_test3 drop cascades to index collate_dep_test4i \d collate_dep_test1 @@ -1117,24 +1136,11 @@ select textrange_en_us('A','Z') @> 'b'::text; drop type textrange_c; drop type textrange_en_us; +-- nondeterministic collations +-- (not supported with libc provider) +CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true); +CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false); +ERROR: nondeterministic collations not supported with this provider -- cleanup +SET client_min_messages TO warning; DROP SCHEMA collate_tests CASCADE; -NOTICE: drop cascades to 18 other objects -DETAIL: drop cascades to table collate_test1 -drop cascades to table collate_test_like -drop cascades to table collate_test2 -drop cascades to table collate_test3 -drop cascades to type testdomain_sv -drop cascades to table collate_test4 -drop cascades to table collate_test5 -drop cascades to table collate_test10 -drop cascades to table collate_test6 -drop cascades to view collview1 -drop cascades to view collview2 -drop cascades to view collview3 -drop cascades to type testdomain -drop cascades to function mylt(text,text) -drop cascades to function mylt_noninline(text,text) -drop cascades to function mylt_plpgsql(text,text) -drop cascades to function mylt2(text,text) -drop cascades to function dup(anyelement) diff --git a/src/test/regress/expected/collate.linux.utf8_1.out b/src/test/regress/expected/collate.linux.utf8_1.out new file mode 100644 index 00000000000..ede5fdb5dcc --- /dev/null +++ b/src/test/regress/expected/collate.linux.utf8_1.out @@ -0,0 +1,11 @@ +/* + * This test is for Linux/glibc systems and assumes that a full set of + * locales is installed. It must be run in a database with UTF-8 encoding, + * because other encodings don't support all the characters used. + */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test \gset +\if :skip_test +\quit diff --git a/src/test/regress/expected/collate.out b/src/test/regress/expected/collate.out index f045f2b291c..0dee7d783a0 100644 --- a/src/test/regress/expected/collate.out +++ b/src/test/regress/expected/collate.out @@ -498,6 +498,21 @@ SELECT a, b, a < b as lt FROM A | b | t (2 rows) +-- collation mismatch in subselects +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10); +ERROR: could not determine which collation to use for string hashing +HINT: Use the COLLATE clause to set the collation explicitly. +-- now it works with overrides +SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10); + a | x | y +---+---+--- +(0 rows) + +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10); + a | x | y +---+---+--- +(0 rows) + -- casting SELECT CAST('42' AS text COLLATE "C"); ERROR: syntax error at or near "COLLATE" @@ -631,7 +646,7 @@ DROP COLLATION mycoll1; CREATE TABLE collate_test23 (f1 text collate mycoll2); DROP COLLATION mycoll2; -- fail ERROR: cannot drop collation mycoll2 because other objects depend on it -DETAIL: table collate_test23 column f1 depends on collation mycoll2 +DETAIL: column f1 of table collate_test23 depends on collation mycoll2 HINT: Use DROP ... CASCADE to drop the dependent objects too. -- invalid: non-lowercase quoted identifiers CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX"); @@ -666,6 +681,22 @@ SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); -- trying to run any platform-specific collation tests later, so we -- must get rid of them. -- -\set VERBOSITY terse DROP SCHEMA collate_tests CASCADE; NOTICE: drop cascades to 17 other objects +DETAIL: drop cascades to table collate_test1 +drop cascades to table collate_test_like +drop cascades to table collate_test2 +drop cascades to type testdomain_p +drop cascades to table collate_test4 +drop cascades to table collate_test5 +drop cascades to table collate_test10 +drop cascades to view collview1 +drop cascades to view collview2 +drop cascades to view collview3 +drop cascades to type testdomain +drop cascades to function dup(anyelement) +drop cascades to table collate_test20 +drop cascades to table collate_test21 +drop cascades to table collate_test22 +drop cascades to collation mycoll2 +drop cascades to table collate_test23 diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out index e606a5fda47..c53ed3ebf59 100644 --- a/src/test/regress/expected/copy2.out +++ b/src/test/regress/expected/copy2.out @@ -4,7 +4,7 @@ CREATE TEMP TABLE x ( c text not null default 'stuff', d text, e text -) WITH OIDS; +) ; CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' BEGIN NEW.e := ''before trigger fired''::text; @@ -33,7 +33,7 @@ COPY x (a, b, c, d, e, d, c) from stdin; ERROR: column "d" specified more than once -- missing data: should fail COPY x from stdin; -ERROR: invalid input syntax for integer: "" +ERROR: invalid input syntax for type integer: "" CONTEXT: COPY x, line 1, column a: "" COPY x from stdin; ERROR: missing data for column "e" @@ -46,9 +46,35 @@ COPY x from stdin; ERROR: extra data after last expected column CONTEXT: COPY x, line 1: "2002 232 40 50 60 70 80" -- various COPY options: delimiters, oids, NULL string, encoding -COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x'; +COPY x (b, c, d, e) from stdin delimiter ',' null 'x'; COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii'; +COPY x TO stdout WHERE a = 1; +ERROR: WHERE clause not allowed with COPY TO +LINE 1: COPY x TO stdout WHERE a = 1; + ^ +COPY x from stdin WHERE a = 50004; +COPY x from stdin WHERE a > 60003; +COPY x from stdin WHERE f > 60003; +ERROR: column "f" does not exist +LINE 1: COPY x from stdin WHERE f > 60003; + ^ +COPY x from stdin WHERE a = max(x.b); +ERROR: aggregate functions are not allowed in COPY FROM WHERE conditions +LINE 1: COPY x from stdin WHERE a = max(x.b); + ^ +COPY x from stdin WHERE a IN (SELECT 1 FROM x); +ERROR: cannot use subquery in COPY FROM WHERE condition +LINE 1: COPY x from stdin WHERE a IN (SELECT 1 FROM x); + ^ +COPY x from stdin WHERE a IN (generate_series(1,5)); +ERROR: set-returning functions are not allowed in COPY FROM WHERE conditions +LINE 1: COPY x from stdin WHERE a IN (generate_series(1,5)); + ^ +COPY x from stdin WHERE a = row_number() over(b); +ERROR: window functions are not allowed in COPY FROM WHERE conditions +LINE 1: COPY x from stdin WHERE a = row_number() over(b); + ^ -- check results of copy in SELECT * FROM x; a | b | c | d | e @@ -73,25 +99,16 @@ SELECT * FROM x; 4006 | 6 | BackslashN | \N | before trigger fired 4007 | 7 | XX | XX | before trigger fired 4008 | 8 | Delimiter | : | before trigger fired + 50004 | 25 | 35 | 45 | before trigger fired + 60004 | 25 | 35 | 45 | before trigger fired + 60005 | 26 | 36 | 46 | before trigger fired 1 | 1 | stuff | test_1 | after trigger fired 2 | 2 | stuff | test_2 | after trigger fired 3 | 3 | stuff | test_3 | after trigger fired 4 | 4 | stuff | test_4 | after trigger fired 5 | 5 | stuff | test_5 | after trigger fired -(25 rows) +(28 rows) --- COPY w/ oids on a table w/o oids should fail -CREATE TABLE no_oids ( - a int, - b int -) WITHOUT OIDS; -INSERT INTO no_oids (a, b) VALUES (5, 10); -INSERT INTO no_oids (a, b) VALUES (20, 30); --- should fail -COPY no_oids FROM stdin WITH OIDS; -ERROR: table "no_oids" does not have OIDs -COPY no_oids TO stdout WITH OIDS; -ERROR: table "no_oids" does not have OIDs -- check copy out COPY x TO stdout; 9999 \N \\N NN before trigger fired @@ -114,6 +131,9 @@ COPY x TO stdout; 4006 6 BackslashN \\N before trigger fired 4007 7 XX XX before trigger fired 4008 8 Delimiter : before trigger fired +50004 25 35 45 before trigger fired +60004 25 35 45 before trigger fired +60005 26 36 46 before trigger fired 1 1 stuff test_1 after trigger fired 2 2 stuff test_2 after trigger fired 3 3 stuff test_3 after trigger fired @@ -140,6 +160,9 @@ N before trigger fired BackslashN before trigger fired XX before trigger fired Delimiter before trigger fired +35 before trigger fired +35 before trigger fired +36 before trigger fired stuff after trigger fired stuff after trigger fired stuff after trigger fired @@ -166,6 +189,9 @@ I'm null before trigger fired 6 before trigger fired 7 before trigger fired 8 before trigger fired +25 before trigger fired +25 before trigger fired +26 before trigger fired 1 after trigger fired 2 after trigger fired 3 after trigger fired @@ -334,12 +360,12 @@ SELECT * FROM vistest; COMMIT; TRUNCATE vistest; COPY vistest FROM stdin CSV FREEZE; -ERROR: cannot perform FREEZE because the table was not created or truncated in the current subtransaction +ERROR: cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction BEGIN; TRUNCATE vistest; SAVEPOINT s1; COPY vistest FROM stdin CSV FREEZE; -ERROR: cannot perform FREEZE because the table was not created or truncated in the current subtransaction +ERROR: cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction COMMIT; BEGIN; INSERT INTO vistest VALUES ('z'); @@ -347,7 +373,7 @@ SAVEPOINT s1; TRUNCATE vistest; ROLLBACK TO SAVEPOINT s1; COPY vistest FROM stdin CSV FREEZE; -ERROR: cannot perform FREEZE because the table was not created or truncated in the current subtransaction +ERROR: cannot perform COPY FREEZE because the table was not created or truncated in the current subtransaction COMMIT; CREATE FUNCTION truncate_in_subxact() RETURNS VOID AS $$ @@ -557,6 +583,23 @@ SELECT * FROM instead_of_insert_tbl; 1 | test1 (1 row) +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); +COPY instead_of_insert_tbl_view_2 FROM stdin; +SELECT * FROM instead_of_insert_tbl; + id | name +----+------- + 1 | test1 + 2 | test1 +(2 rows) + +COMMIT; -- clean up DROP TABLE forcetest; DROP TABLE vistest; @@ -569,4 +612,5 @@ DROP FUNCTION fn_x_before(); DROP FUNCTION fn_x_after(); DROP TABLE instead_of_insert_tbl; DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; DROP FUNCTION fun_instead_of_insert_tbl(); diff --git a/src/test/regress/expected/create_aggregate.out b/src/test/regress/expected/create_aggregate.out index b9b7fbcc9e4..a2eb9996e15 100644 --- a/src/test/regress/expected/create_aggregate.out +++ b/src/test/regress/expected/create_aggregate.out @@ -148,7 +148,7 @@ CREATE AGGREGATE myavg (numeric) serialfunc = numeric_avg_serialize, deserialfunc = numeric_avg_deserialize, combinefunc = numeric_avg_combine, - finalfunc_modify = sharable -- just to test a non-default setting + finalfunc_modify = shareable -- just to test a non-default setting ); -- Ensure all these functions made it into the catalog SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, @@ -160,6 +160,77 @@ WHERE aggfnoid = 'myavg'::REGPROC; myavg | numeric_avg_accum | numeric_avg_combine | internal | numeric_avg_serialize | numeric_avg_deserialize | s (1 row) +DROP AGGREGATE myavg (numeric); +-- create or replace aggregate +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg +); +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +); +-- Ensure all these functions made it into the catalog again +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn | aggfinalmodify +----------+-------------------+---------------------+--------------+-----------------------+-------------------------+---------------- + myavg | numeric_avg_accum | numeric_avg_combine | internal | numeric_avg_serialize | numeric_avg_deserialize | s +(1 row) + +-- can change stype: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add +); +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + aggfnoid | aggtransfn | aggcombinefn | aggtranstype | aggserialfn | aggdeserialfn | aggfinalmodify +----------+-------------+--------------+--------------+-------------+---------------+---------------- + myavg | numeric_add | - | numeric | - | - | r +(1 row) + +-- can't change return type: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add, + finalfunc = numeric_out +); +ERROR: cannot change return type of existing function +HINT: Use DROP AGGREGATE myavg(numeric) first. +-- can't change to a different kind: +CREATE OR REPLACE AGGREGATE myavg (order by numeric) +( + stype = numeric, + sfunc = numeric_add +); +ERROR: cannot change routine kind +DETAIL: "myavg" is an ordinary aggregate function. +-- can't change plain function to aggregate: +create function sum4(int8,int8,int8,int8) returns int8 as +'select $1 + $2 + $3 + $4' language sql strict immutable; +CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8) +( + stype = int8, + sfunc = sum4 +); +ERROR: cannot change routine kind +DETAIL: "sum3" is a function. +drop function sum4(int8,int8,int8,int8); DROP AGGREGATE myavg (numeric); -- invalid: bad parallel-safety marking CREATE AGGREGATE mysum (int) diff --git a/src/test/regress/expected/create_am.out b/src/test/regress/expected/create_am.out index 47dd885c4e9..84da403afc5 100644 --- a/src/test/regress/expected/create_am.out +++ b/src/test/regress/expected/create_am.out @@ -3,6 +3,11 @@ -- -- Make gist2 over gisthandler. In fact, it would be a synonym to gist. CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler; +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in; +ERROR: function int4in(internal) does not exist +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler; +ERROR: function heap_tableam_handler must return type index_am_handler -- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base); ERROR: data type box has no default operator class for access method "gist2" @@ -99,3 +104,195 @@ HINT: Use DROP ... CASCADE to drop the dependent objects too. -- Drop access method cascade DROP ACCESS METHOD gist2 CASCADE; NOTICE: drop cascades to index grect2ind2 +-- +-- Test table access methods +-- +-- prevent empty values +SET default_table_access_method = ''; +ERROR: invalid value for parameter "default_table_access_method": "" +DETAIL: default_table_access_method cannot be empty. +-- prevent nonexistent values +SET default_table_access_method = 'I do not exist AM'; +ERROR: invalid value for parameter "default_table_access_method": "I do not exist AM" +DETAIL: Table access method "I do not exist AM" does not exist. +-- prevent setting it to an index AM +SET default_table_access_method = 'btree'; +ERROR: access method "btree" is not of type TABLE +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler; +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in; +ERROR: function int4in(internal) does not exist +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler; +ERROR: function bthandler must return type table_am_handler +SELECT amname, amhandler, amtype FROM pg_am where amtype = 't' ORDER BY 1, 2; + amname | amhandler | amtype +--------+----------------------+-------- + heap | heap_tableam_handler | t + heap2 | heap_tableam_handler | t +(2 rows) + +-- First create tables employing the new AM using USING +-- plain CREATE TABLE +CREATE TABLE tableam_tbl_heap2(f1 int) USING heap2; +INSERT INTO tableam_tbl_heap2 VALUES(1); +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + f1 +---- + 1 +(1 row) + +-- CREATE TABLE AS +CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + f1 +---- + 1 +(1 row) + +-- SELECT INTO doesn't support USING +SELECT INTO tableam_tblselectinto_heap2 USING heap2 FROM tableam_tbl_heap2; +ERROR: syntax error at or near "USING" +LINE 1: SELECT INTO tableam_tblselectinto_heap2 USING heap2 FROM tab... + ^ +-- CREATE VIEW doesn't support USING +CREATE VIEW tableam_view_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; +ERROR: syntax error at or near "USING" +LINE 1: CREATE VIEW tableam_view_heap2 USING heap2 AS SELECT * FROM ... + ^ +-- CREATE SEQUENCE doesn't support USING +CREATE SEQUENCE tableam_seq_heap2 USING heap2; +ERROR: syntax error at or near "USING" +LINE 1: CREATE SEQUENCE tableam_seq_heap2 USING heap2; + ^ +-- CREATE MATERIALIZED VIEW does support USING +CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; +SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1; + f1 +---- + 1 +(1 row) + +-- CREATE TABLE .. PARTITION BY doesn't not support USING +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) USING heap2; +ERROR: specifying a table access method is not supported on a partitioned table +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a); +-- new partitions will inherit from the current default, rather the partition root +SET default_table_access_method = 'heap'; +CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a'); +SET default_table_access_method = 'heap2'; +CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b'); +RESET default_table_access_method; +-- but the method can be explicitly specified +CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap; +CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING heap2; +-- List all objects in AM +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc, + pg_am AS pa +WHERE pa.oid = pc.relam + AND pa.amname = 'heap2' +ORDER BY 3, 1, 2; + relkind | amname | relname +---------+--------+---------------------------------- + r | heap2 | tableam_parted_b_heap2 + r | heap2 | tableam_parted_d_heap2 + r | heap2 | tableam_tbl_heap2 + r | heap2 | tableam_tblas_heap2 + m | heap2 | tableam_tblmv_heap2 + t | heap2 | toast for tableam_parted_b_heap2 + t | heap2 | toast for tableam_parted_d_heap2 +(7 rows) + +-- Show dependencies onto AM - there shouldn't be any for toast +SELECT pg_describe_object(classid,objid,objsubid) AS obj +FROM pg_depend, pg_am +WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_am.amname = 'heap2' +ORDER BY classid, objid, objsubid; + obj +--------------------------------------- + table tableam_tbl_heap2 + table tableam_tblas_heap2 + materialized view tableam_tblmv_heap2 + table tableam_parted_b_heap2 + table tableam_parted_d_heap2 +(5 rows) + +-- Second, create objects in the new AM by changing the default AM +BEGIN; +SET LOCAL default_table_access_method = 'heap2'; +-- following tests should all respect the default AM +CREATE TABLE tableam_tbl_heapx(f1 int); +CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx; +SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx; +CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx; +CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY list (a); +CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b'); +-- but an explicitly set AM overrides it +CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') USING heap; +-- sequences, views and foreign servers shouldn't have an AM +CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx; +CREATE SEQUENCE tableam_seq_heapx; +CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator; +CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2 ; +CREATE FOREIGN table tableam_fdw_heapx () SERVER fs_heap2; +-- Verify that new AM was used for tables, matviews, but not for sequences, views and fdws +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc + LEFT JOIN pg_am AS pa ON (pa.oid = pc.relam) +WHERE pc.relname LIKE 'tableam_%_heapx' +ORDER BY 3, 1, 2; + relkind | amname | relname +---------+--------+----------------------------- + f | | tableam_fdw_heapx + r | heap2 | tableam_parted_1_heapx + r | heap | tableam_parted_2_heapx + p | | tableam_parted_heapx + S | | tableam_seq_heapx + r | heap2 | tableam_tbl_heapx + r | heap2 | tableam_tblas_heapx + m | heap2 | tableam_tblmv_heapx + r | heap2 | tableam_tblselectinto_heapx + v | | tableam_view_heapx +(10 rows) + +-- don't want to keep those tables, nor the default +ROLLBACK; +-- Third, check that we can neither create a table using a nonexistent +-- AM, nor using an index AM +CREATE TABLE i_am_a_failure() USING ""; +ERROR: zero-length delimited identifier at or near """" +LINE 1: CREATE TABLE i_am_a_failure() USING ""; + ^ +CREATE TABLE i_am_a_failure() USING i_do_not_exist_am; +ERROR: access method "i_do_not_exist_am" does not exist +CREATE TABLE i_am_a_failure() USING "I do not exist AM"; +ERROR: access method "I do not exist AM" does not exist +CREATE TABLE i_am_a_failure() USING "btree"; +ERROR: access method "btree" is not of type TABLE +-- Drop table access method, which fails as objects depends on it +DROP ACCESS METHOD heap2; +ERROR: cannot drop access method heap2 because other objects depend on it +DETAIL: table tableam_tbl_heap2 depends on access method heap2 +table tableam_tblas_heap2 depends on access method heap2 +materialized view tableam_tblmv_heap2 depends on access method heap2 +table tableam_parted_b_heap2 depends on access method heap2 +table tableam_parted_d_heap2 depends on access method heap2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- we intentionally leave the objects created above alive, to verify pg_dump support diff --git a/src/test/regress/expected/create_function_3.out b/src/test/regress/expected/create_function_3.out index 3301885fc82..ba260df9960 100644 --- a/src/test/regress/expected/create_function_3.out +++ b/src/test/regress/expected/create_function_3.out @@ -341,9 +341,28 @@ SELECT * FROM voidtest5(3); (0 rows) -- Cleanup -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA temp_func_test CASCADE; NOTICE: drop cascades to 21 other objects -\set VERBOSITY default +DETAIL: drop cascades to function functest_a_1(text,date) +drop cascades to function functest_a_2(text[]) +drop cascades to function functest_a_3() +drop cascades to function functest_b_2(integer) +drop cascades to function functest_b_3(integer) +drop cascades to function functest_b_4(integer) +drop cascades to function functest_c_1(integer) +drop cascades to function functest_c_2(integer) +drop cascades to function functest_c_3(integer) +drop cascades to function functest_e_1(integer) +drop cascades to function functest_e_2(integer) +drop cascades to function functest_f_1(integer) +drop cascades to function functest_f_2(integer) +drop cascades to function functest_f_3(integer) +drop cascades to function functest_f_4(integer) +drop cascades to function functest_b_2(bigint) +drop cascades to function voidtest1(integer) +drop cascades to function voidtest2(integer,integer) +drop cascades to function voidtest3(integer) +drop cascades to function voidtest4(integer) +drop cascades to function voidtest5(integer) DROP USER regress_unpriv_user; RESET search_path; diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index fe5b698669c..324db1b6ae1 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -68,25 +68,7 @@ CREATE TEMP TABLE gcircle_tbl AS CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1); CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1); -- --- SP-GiST --- -CREATE TABLE quad_point_tbl AS - SELECT point(unique1,unique2) AS p FROM tenk1; -INSERT INTO quad_point_tbl - SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); -INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); -CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); -CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; -CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); -CREATE TABLE radix_text_tbl AS - SELECT name AS t FROM road WHERE name !~ '^[0-9]'; -INSERT INTO radix_text_tbl - SELECT 'P0123456789abcdef' FROM generate_series(1,1000); -INSERT INTO radix_text_tbl VALUES ('P0123456789abcde'); -INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF'); -CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t); --- --- Test GiST and SP-GiST indexes +-- Test GiST indexes -- -- get non-indexed results for comparison purposes SET enable_seqscan = ON; @@ -157,7 +139,7 @@ SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1; SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'; count ------- - 3 + 5 (1 row) SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; @@ -175,7 +157,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; count ------- - 2 + 3 (1 row) SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; @@ -187,7 +169,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; count ------- - 3 + 4 (1 row) SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; @@ -197,16 +179,19 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; (1 row) SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; - f1 ------------- + f1 +------------------- (0,0) + (1e-300,-1e-300) (-3,4) (-10,0) (10,10) (-5,-12) (5.1,34.5) + (1e+300,Infinity) + (NaN,NaN) -(7 rows) +(10 rows) SELECT * FROM point_tbl WHERE f1 IS NULL; f1 @@ -215,168 +200,28 @@ SELECT * FROM point_tbl WHERE f1 IS NULL; (1 row) SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; - f1 ------------- + f1 +------------------- + (1e-300,-1e-300) (0,0) (-3,4) (-10,0) (10,10) (-5,-12) (5.1,34.5) -(6 rows) + (1e+300,Infinity) + (NaN,NaN) +(9 rows) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; - f1 ---------- + f1 +------------------ (0,0) + (1e-300,-1e-300) (-3,4) (-10,0) (10,10) -(4 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - count -------- - 3 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - count -------- - 11000 -(1 row) - -SELECT count(*) FROM quad_point_tbl; - count -------- - 11003 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - count -------- - 1000 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - count -------- - 272 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - count -------- - 272 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - count -------- - 273 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - count -------- - 273 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - count -------- - 1 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - count -------- - 2 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - count -------- - 50 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - count -------- - 50 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - count -------- - 48 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - count -------- - 48 -(1 row) - -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - count -------- - 2 -(1 row) +(5 rows) SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; f1 @@ -574,7 +419,7 @@ SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50, SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)'; count ------- - 3 + 4 (1 row) EXPLAIN (COSTS OFF) @@ -582,1224 +427,243 @@ SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; QUERY PLAN ---------------------------------------------------- Aggregate - -> Index Only Scan using gpointind on point_tbl - Index Cond: (f1 <@ '<(50,50),50>'::circle) -(3 rows) - -SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Index Only Scan using gpointind on point_tbl p - Index Cond: (f1 << '(0,0)'::point) -(3 rows) - -SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; - count -------- - 3 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Index Only Scan using gpointind on point_tbl p - Index Cond: (f1 >> '(0,0)'::point) -(3 rows) - -SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; - count -------- - 2 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Index Only Scan using gpointind on point_tbl p - Index Cond: (f1 <^ '(0,0)'::point) -(3 rows) - -SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Index Only Scan using gpointind on point_tbl p - Index Cond: (f1 >^ '(0,0)'::point) -(3 rows) - -SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; - count -------- - 3 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Index Only Scan using gpointind on point_tbl p - Index Cond: (f1 ~= '(-5,-12)'::point) -(3 rows) - -SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; - QUERY PLAN ----------------------------------------------- - Index Only Scan using gpointind on point_tbl - Order By: (f1 <-> '(0,1)'::point) -(2 rows) - -SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; - f1 ------------- - (0,0) - (-3,4) - (-10,0) - (10,10) - (-5,-12) - (5.1,34.5) - -(7 rows) - -EXPLAIN (COSTS OFF) -SELECT * FROM point_tbl WHERE f1 IS NULL; - QUERY PLAN ----------------------------------------------- - Index Only Scan using gpointind on point_tbl - Index Cond: (f1 IS NULL) -(2 rows) - -SELECT * FROM point_tbl WHERE f1 IS NULL; - f1 ----- - -(1 row) - -EXPLAIN (COSTS OFF) -SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; - QUERY PLAN ----------------------------------------------- - Index Only Scan using gpointind on point_tbl - Index Cond: (f1 IS NOT NULL) - Order By: (f1 <-> '(0,1)'::point) -(3 rows) - -SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; - f1 ------------- - (0,0) - (-3,4) - (-10,0) - (10,10) - (-5,-12) - (5.1,34.5) -(6 rows) - -EXPLAIN (COSTS OFF) -SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; - QUERY PLAN ------------------------------------------------- - Index Only Scan using gpointind on point_tbl - Index Cond: (f1 <@ '(10,10),(-10,-10)'::box) - Order By: (f1 <-> '(0,1)'::point) -(3 rows) - -SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; - f1 ---------- - (0,0) - (-3,4) - (-10,0) - (10,10) -(4 rows) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p IS NULL) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - count -------- - 3 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p IS NOT NULL) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - count -------- - 11000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl -(2 rows) - -SELECT count(*) FROM quad_point_tbl; - count -------- - 11003 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p << '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p >> '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p <^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p >^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p ~= '(4585,365)'::point) -(3 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p << '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p >> '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p >^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p ~= '(4585,365)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcdef'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - count -------- - 1000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcde'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcdefF'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t < 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~<~ 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t <= 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - QUERY PLAN -------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~<=~ 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - count -------- - 2 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t >= 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - QUERY PLAN -------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~>=~ 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t > 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~>~ 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ^@ 'Worth'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - count -------- - 2 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; - QUERY PLAN ------------------------------------------------------ - Limit - -> Index Scan using ggpolygonind on gpolygon_tbl - Order By: (f1 <-> '(0,0)'::point) -(3 rows) - -SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; - f1 -------------------------------------------------- - ((240,359),(240,455),(337,455),(337,359)) - ((662,163),(662,187),(759,187),(759,163)) - ((1000,0),(0,1000)) - ((0,1000),(1000,1000)) - ((1346,344),(1346,403),(1444,403),(1444,344)) - ((278,1409),(278,1457),(369,1457),(369,1409)) - ((907,1156),(907,1201),(948,1201),(948,1156)) - ((1517,971),(1517,1043),(1594,1043),(1594,971)) - ((175,1820),(175,1850),(259,1850),(259,1820)) - ((2424,81),(2424,160),(2424,160),(2424,81)) -(10 rows) - -EXPLAIN (COSTS OFF) -SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; - QUERY PLAN ---------------------------------------------------- - Limit - -> Index Scan using ggcircleind on gcircle_tbl - Order By: (f1 <-> '(200,300)'::point) -(3 rows) - -SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; - circle_center | radius -----------------+-------- - (288.5,407) | 68 - (710.5,175) | 50 - (323.5,1433) | 51 - (927.5,1178.5) | 30 - (1395,373.5) | 57 - (1555.5,1007) | 53 - (217,1835) | 45 - (489,2421.5) | 22 - (2424,120.5) | 40 - (751.5,2655) | 20 -(10 rows) - --- Now check the results from bitmap indexscan -SET enable_seqscan = OFF; -SET enable_indexscan = OFF; -SET enable_bitmapscan = ON; -EXPLAIN (COSTS OFF) -SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; - QUERY PLAN ------------------------------------------------------------- - Sort - Sort Key: ((f1 <-> '(0,1)'::point)) - -> Bitmap Heap Scan on point_tbl - Recheck Cond: (f1 <@ '(10,10),(-10,-10)'::box) - -> Bitmap Index Scan on gpointind - Index Cond: (f1 <@ '(10,10),(-10,-10)'::box) -(6 rows) - -SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; - f1 ---------- - (0,0) - (-3,4) - (-10,0) - (10,10) -(4 rows) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p IS NULL) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p IS NULL) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - count -------- - 3 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p IS NOT NULL) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p IS NOT NULL) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - count -------- - 11000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - -> Bitmap Index Scan on sp_quad_ind -(3 rows) - -SELECT count(*) FROM quad_point_tbl; - count -------- - 11003 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: ('(1000,1000),(200,200)'::box @> p) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: ('(1000,1000),(200,200)'::box @> p) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p << '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p << '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p >> '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p >> '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p <^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p <^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p >^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p >^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p ~= '(4585,365)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p ~= '(4585,365)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: ('(1000,1000),(200,200)'::box @> p) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: ('(1000,1000),(200,200)'::box @> p) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p << '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p << '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p >> '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p >> '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p <^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p <^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p >^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p >^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p ~= '(4585,365)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p ~= '(4585,365)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcdef'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcdef'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - count -------- - 1000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - QUERY PLAN ----------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcde'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcde'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcdefF'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcdefF'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t < 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t < 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~<~ 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~<~ 'Aztec Ct '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl + Index Cond: (f1 <@ '<(50,50),50>'::circle) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; +SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>'; count ------- - 272 + 1 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------------ +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; + QUERY PLAN +------------------------------------------------------ Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t <= 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t <= 'Aztec Ct '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl p + Index Cond: (f1 << '(0,0)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; +SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; count ------- - 273 + 3 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - QUERY PLAN -------------------------------------------------------------------------------- +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; + QUERY PLAN +------------------------------------------------------ Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~<=~ 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~<=~ 'Aztec Ct '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl p + Index Cond: (f1 >> '(0,0)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; +SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; count ------- - 273 + 3 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------------- +SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; + QUERY PLAN +------------------------------------------------------ Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'Aztec Ct '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl p + Index Cond: (f1 <^ '(0,0)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; +SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; count ------- 1 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------------- +SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; + QUERY PLAN +------------------------------------------------------ Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'Worth St '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl p + Index Cond: (f1 >^ '(0,0)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; +SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; count ------- - 2 + 4 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------------ +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; + QUERY PLAN +------------------------------------------------------ Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t >= 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t >= 'Worth St '::text) -(5 rows) + -> Index Only Scan using gpointind on point_tbl p + Index Cond: (f1 ~= '(-5,-12)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; +SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; count ------- - 50 + 1 (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - QUERY PLAN -------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~>=~ 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~>=~ 'Worth St '::text) -(5 rows) +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; + QUERY PLAN +---------------------------------------------- + Index Only Scan using gpointind on point_tbl + Order By: (f1 <-> '(0,1)'::point) +(2 rows) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - count -------- - 50 -(1 row) +SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; + f1 +------------------- + (0,0) + (1e-300,-1e-300) + (-3,4) + (-10,0) + (10,10) + (-5,-12) + (5.1,34.5) + (1e+300,Infinity) + (NaN,NaN) + +(10 rows) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t > 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t > 'Worth St '::text) -(5 rows) +SELECT * FROM point_tbl WHERE f1 IS NULL; + QUERY PLAN +---------------------------------------------- + Index Only Scan using gpointind on point_tbl + Index Cond: (f1 IS NULL) +(2 rows) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - count -------- - 48 +SELECT * FROM point_tbl WHERE f1 IS NULL; + f1 +---- + (1 row) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~>~ 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~>~ 'Worth St '::text) -(5 rows) +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; + QUERY PLAN +---------------------------------------------- + Index Only Scan using gpointind on point_tbl + Index Cond: (f1 IS NOT NULL) + Order By: (f1 <-> '(0,1)'::point) +(3 rows) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - count -------- - 48 -(1 row) +SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; + f1 +------------------- + (0,0) + (1e-300,-1e-300) + (-3,4) + (-10,0) + (10,10) + (-5,-12) + (5.1,34.5) + (1e+300,Infinity) + (NaN,NaN) +(9 rows) EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; QUERY PLAN ------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ^@ 'Worth'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ^@ 'Worth'::text) + Index Only Scan using gpointind on point_tbl + Index Cond: (f1 <@ '(10,10),(-10,-10)'::box) + Order By: (f1 <-> '(0,1)'::point) +(3 rows) + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + f1 +------------------ + (0,0) + (1e-300,-1e-300) + (-3,4) + (-10,0) + (10,10) (5 rows) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - count -------- - 2 -(1 row) +EXPLAIN (COSTS OFF) +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; + QUERY PLAN +----------------------------------------------------- + Limit + -> Index Scan using ggpolygonind on gpolygon_tbl + Order By: (f1 <-> '(0,0)'::point) +(3 rows) + +SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; + f1 +------------------------------------------------- + ((240,359),(240,455),(337,455),(337,359)) + ((662,163),(662,187),(759,187),(759,163)) + ((1000,0),(0,1000)) + ((0,1000),(1000,1000)) + ((1346,344),(1346,403),(1444,403),(1444,344)) + ((278,1409),(278,1457),(369,1457),(369,1409)) + ((907,1156),(907,1201),(948,1201),(948,1156)) + ((1517,971),(1517,1043),(1594,1043),(1594,971)) + ((175,1820),(175,1850),(259,1850),(259,1820)) + ((2424,81),(2424,160),(2424,160),(2424,81)) +(10 rows) + +EXPLAIN (COSTS OFF) +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; + QUERY PLAN +--------------------------------------------------- + Limit + -> Index Scan using ggcircleind on gcircle_tbl + Order By: (f1 <-> '(200,300)'::point) +(3 rows) + +SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; + circle_center | radius +----------------+-------- + (288.5,407) | 68 + (710.5,175) | 50 + (323.5,1433) | 51 + (927.5,1178.5) | 30 + (1395,373.5) | 57 + (1555.5,1007) | 53 + (217,1835) | 45 + (489,2421.5) | 22 + (2424,120.5) | 40 + (751.5,2655) | 20 +(10 rows) + +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF; +SET enable_indexscan = OFF; +SET enable_bitmapscan = ON; +EXPLAIN (COSTS OFF) +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + QUERY PLAN +------------------------------------------------------------ + Sort + Sort Key: ((f1 <-> '(0,1)'::point)) + -> Bitmap Heap Scan on point_tbl + Recheck Cond: (f1 <@ '(10,10),(-10,-10)'::box) + -> Bitmap Index Scan on gpointind + Index Cond: (f1 <@ '(10,10),(-10,-10)'::box) +(6 rows) + +SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; + f1 +------------------ + (0,0) + (1e-300,-1e-300) + (-3,4) + (-10,0) + (10,10) +(5 rows) RESET enable_seqscan; RESET enable_indexscan; @@ -2362,10 +1226,10 @@ DROP TABLE array_gin_test; CREATE INDEX gin_relopts_test ON array_index_op_test USING gin (i) WITH (FASTUPDATE=on, GIN_PENDING_LIST_LIMIT=128); \d+ gin_relopts_test - Index "public.gin_relopts_test" - Column | Type | Definition | Storage | Stats target ---------+---------+------------+---------+-------------- - i | integer | i | plain | + Index "public.gin_relopts_test" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + i | integer | yes | i | plain | gin, for table "public.array_index_op_test" Options: fastupdate=on, gin_pending_list_limit=128 @@ -2510,10 +1374,10 @@ VACUUM FULL concur_heap; f1 | text | | | f2 | text | | | Indexes: - "concur_index2" UNIQUE, btree (f1) - "concur_index3" UNIQUE, btree (f2) INVALID "concur_heap_expr_idx" btree ((f2 || f1)) "concur_index1" btree (f2, f1) + "concur_index2" UNIQUE, btree (f1) + "concur_index3" UNIQUE, btree (f2) INVALID "concur_index4" btree (f2) WHERE f1 = 'a'::text "concur_index5" btree (f2) WHERE f1 = 'x'::text "std_index" btree (f2) @@ -2526,10 +1390,10 @@ REINDEX TABLE concur_heap; f1 | text | | | f2 | text | | | Indexes: - "concur_index2" UNIQUE, btree (f1) - "concur_index3" UNIQUE, btree (f2) "concur_heap_expr_idx" btree ((f2 || f1)) "concur_index1" btree (f2, f1) + "concur_index2" UNIQUE, btree (f1) + "concur_index3" UNIQUE, btree (f2) "concur_index4" btree (f2) WHERE f1 = 'a'::text "concur_index5" btree (f2) WHERE f1 = 'x'::text "std_index" btree (f2) @@ -2582,11 +1446,11 @@ Indexes: "cwi_uniq_idx" PRIMARY KEY, btree (a, b) \d cwi_uniq_idx - Index "public.cwi_uniq_idx" - Column | Type | Definition ---------+-----------------------+------------ - a | integer | a - b | character varying(10) | b + Index "public.cwi_uniq_idx" + Column | Type | Key? | Definition +--------+-----------------------+------+------------ + a | integer | yes | a + b | character varying(10) | yes | b primary key, btree, for table "public.cwi_test" CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a); @@ -2605,11 +1469,11 @@ Indexes: "cwi_replaced_pkey" PRIMARY KEY, btree (b, a) \d cwi_replaced_pkey - Index "public.cwi_replaced_pkey" - Column | Type | Definition ---------+-----------------------+------------ - b | character varying(10) | b - a | integer | a + Index "public.cwi_replaced_pkey" + Column | Type | Key? | Definition +--------+-----------------------+------+------------ + b | character varying(10) | yes | b + a | integer | yes | a primary key, btree, for table "public.cwi_test" DROP INDEX cwi_replaced_pkey; -- Should fail; a constraint depends on it @@ -2625,19 +1489,17 @@ DROP TABLE cwi_test; -- -- Check handling of indexes on system columns -- -CREATE TABLE oid_table (a INT) WITH OIDS; --- An index on the OID column should be allowed -CREATE INDEX ON oid_table (oid); --- Other system columns cannot be indexed -CREATE INDEX ON oid_table (ctid); -ERROR: index creation on system columns is not supported +CREATE TABLE syscol_table (a INT); +-- System columns cannot be indexed +CREATE INDEX ON syscolcol_table (ctid); +ERROR: relation "syscolcol_table" does not exist -- nor used in expressions -CREATE INDEX ON oid_table ((ctid >= '(1000,0)')); +CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')); ERROR: index creation on system columns is not supported -- nor used in predicates -CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)'; +CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)'; ERROR: index creation on system columns is not supported -DROP TABLE oid_table; +DROP TABLE syscol_table; -- -- Tests for IS NULL/IS NOT NULL with b-tree indexes -- @@ -3029,8 +1891,7 @@ explain (costs off) Limit -> Index Scan using boolindex_b_i_key on boolindex Index Cond: (b = true) - Filter: b -(4 rows) +(3 rows) explain (costs off) select * from boolindex where b = true order by i desc limit 10; @@ -3039,8 +1900,7 @@ explain (costs off) Limit -> Index Scan Backward using boolindex_b_i_key on boolindex Index Cond: (b = true) - Filter: b -(4 rows) +(3 rows) explain (costs off) select * from boolindex where not b order by i limit 10; @@ -3049,18 +1909,340 @@ explain (costs off) Limit -> Index Scan using boolindex_b_i_key on boolindex Index Cond: (b = false) - Filter: (NOT b) -(4 rows) +(3 rows) + +explain (costs off) + select * from boolindex where b is true order by i desc limit 10; + QUERY PLAN +---------------------------------------------------------------- + Limit + -> Index Scan Backward using boolindex_b_i_key on boolindex + Index Cond: (b = true) +(3 rows) + +explain (costs off) + select * from boolindex where b is false order by i desc limit 10; + QUERY PLAN +---------------------------------------------------------------- + Limit + -> Index Scan Backward using boolindex_b_i_key on boolindex + Index Cond: (b = false) +(3 rows) -- -- REINDEX (VERBOSE) -- CREATE TABLE reindex_verbose(id integer primary key); -\set VERBOSITY terse +\set VERBOSITY terse \\ -- suppress machine-dependent details REINDEX (VERBOSE) TABLE reindex_verbose; INFO: index "reindex_verbose_pkey" was reindexed +\set VERBOSITY default DROP TABLE reindex_verbose; -- +-- REINDEX CONCURRENTLY +-- +CREATE TABLE concur_reindex_tab (c1 int); +-- REINDEX +REINDEX TABLE concur_reindex_tab; -- notice +NOTICE: table "concur_reindex_tab" has no indexes to reindex +REINDEX TABLE CONCURRENTLY concur_reindex_tab; -- notice +NOTICE: table "concur_reindex_tab" has no indexes that can be reindexed concurrently +ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index +-- Normal index with integer column +CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1); +-- Normal index with text column +CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2); +-- UNIQUE index with expression +CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)); +-- Duplicate column names +CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2); +-- Create table for check on foreign key dependence switch with indexes swapped +ALTER TABLE concur_reindex_tab ADD PRIMARY KEY USING INDEX concur_reindex_ind1; +CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab); +INSERT INTO concur_reindex_tab VALUES (1, 'a'); +INSERT INTO concur_reindex_tab VALUES (2, 'a'); +-- Reindex concurrently of exclusion constraint currently not supported +CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)); +INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]'); +REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl; -- error +ERROR: concurrent index creation for exclusion constraints is not supported +REINDEX TABLE CONCURRENTLY concur_reindex_tab3; -- succeeds with warning +WARNING: cannot reindex exclusion constraint index "public.concur_reindex_tab3_c2_excl" concurrently, skipping +INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]'); +ERROR: conflicting key value violates exclusion constraint "concur_reindex_tab3_c2_excl" +DETAIL: Key (c2)=([2,5)) conflicts with existing key (c2)=([1,3)). +-- Check materialized views +CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab; +REINDEX INDEX CONCURRENTLY concur_reindex_ind1; +REINDEX TABLE CONCURRENTLY concur_reindex_tab; +REINDEX TABLE CONCURRENTLY concur_reindex_matview; +-- Check that comments are preserved +CREATE TABLE testcomment (i int); +CREATE INDEX testcomment_idx1 ON testcomment (i); +COMMENT ON INDEX testcomment_idx1 IS 'test comment'; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + obj_description +----------------- + test comment +(1 row) + +REINDEX TABLE testcomment; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + obj_description +----------------- + test comment +(1 row) + +REINDEX TABLE CONCURRENTLY testcomment ; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); + obj_description +----------------- + test comment +(1 row) + +DROP TABLE testcomment; +-- Partitions +-- Create some partitioned tables +CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1); +CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2); +CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (1); +CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (2); +-- This partitioned table will have no partitions. +CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2); +-- Create some partitioned indexes +CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1); +CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1); +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0; +-- This partitioned index will have no partitions. +CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1); +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10; +CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1); +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1; +CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1); +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + relid | parentrelid | level +-------------------------------+-----------------------------+------- + concur_reindex_part_index | | 0 + concur_reindex_part_index_0 | concur_reindex_part_index | 1 + concur_reindex_part_index_10 | concur_reindex_part_index | 1 + concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 + concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 +(5 rows) + +-- REINDEX fails for partitioned indexes +REINDEX INDEX concur_reindex_part_index_10; +ERROR: REINDEX is not yet implemented for partitioned indexes +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_10; +ERROR: REINDEX is not yet implemented for partitioned indexes +-- REINDEX is a no-op for partitioned tables +REINDEX TABLE concur_reindex_part_10; +WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10" +NOTICE: table "concur_reindex_part_10" has no indexes to reindex +REINDEX TABLE CONCURRENTLY concur_reindex_part_10; +WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10" +NOTICE: table "concur_reindex_part_10" has no indexes that can be reindexed concurrently +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + relid | parentrelid | level +-------------------------------+-----------------------------+------- + concur_reindex_part_index | | 0 + concur_reindex_part_index_0 | concur_reindex_part_index | 1 + concur_reindex_part_index_10 | concur_reindex_part_index | 1 + concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 + concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 +(5 rows) + +-- REINDEX should preserve dependencies of partition tree. +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1; +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + relid | parentrelid | level +-------------------------------+-----------------------------+------- + concur_reindex_part_index | | 0 + concur_reindex_part_index_0 | concur_reindex_part_index | 1 + concur_reindex_part_index_10 | concur_reindex_part_index | 1 + concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 + concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 +(5 rows) + +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1; +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; + relid | parentrelid | level +-------------------------------+-----------------------------+------- + concur_reindex_part_index | | 0 + concur_reindex_part_index_0 | concur_reindex_part_index | 1 + concur_reindex_part_index_10 | concur_reindex_part_index | 1 + concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 + concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 +(5 rows) + +DROP TABLE concur_reindex_part; +-- Check errors +-- Cannot run inside a transaction block +BEGIN; +REINDEX TABLE CONCURRENTLY concur_reindex_tab; +ERROR: REINDEX CONCURRENTLY cannot run inside a transaction block +COMMIT; +REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation +ERROR: cannot reindex system catalogs concurrently +REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index +ERROR: cannot reindex system catalogs concurrently +-- These are the toast table and index of pg_authid. +REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table +ERROR: cannot reindex system catalogs concurrently +REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index +ERROR: cannot reindex system catalogs concurrently +REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM +ERROR: cannot reindex system catalogs concurrently +-- Warns about catalog relations +REINDEX SCHEMA CONCURRENTLY pg_catalog; +WARNING: cannot reindex system catalogs concurrently, skipping all +-- Check the relation status, there should not be invalid indexes +\d concur_reindex_tab + Table "public.concur_reindex_tab" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | integer | | not null | + c2 | text | | | +Indexes: + "concur_reindex_ind1" PRIMARY KEY, btree (c1) + "concur_reindex_ind2" btree (c2) + "concur_reindex_ind3" UNIQUE, btree (abs(c1)) + "concur_reindex_ind4" btree (c1, c1, c2) +Referenced by: + TABLE "concur_reindex_tab2" CONSTRAINT "concur_reindex_tab2_c1_fkey" FOREIGN KEY (c1) REFERENCES concur_reindex_tab(c1) + +DROP MATERIALIZED VIEW concur_reindex_matview; +DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3; +-- Check handling of invalid indexes +CREATE TABLE concur_reindex_tab4 (c1 int); +INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); +-- This trick creates an invalid index. +CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); +ERROR: could not create unique index "concur_reindex_ind5" +DETAIL: Key (c1)=(1) is duplicated. +-- Reindexing concurrently this index fails with the same failure. +-- The extra index created is itself invalid, and can be dropped. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; +ERROR: could not create unique index "concur_reindex_ind5_ccnew" +DETAIL: Key (c1)=(1) is duplicated. +\d concur_reindex_tab4 + Table "public.concur_reindex_tab4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | integer | | | +Indexes: + "concur_reindex_ind5" UNIQUE, btree (c1) INVALID + "concur_reindex_ind5_ccnew" UNIQUE, btree (c1) INVALID + +DROP INDEX concur_reindex_ind5_ccnew; +-- This makes the previous failure go away, so the index can become valid. +DELETE FROM concur_reindex_tab4 WHERE c1 = 1; +-- The invalid index is not processed when running REINDEX TABLE. +REINDEX TABLE CONCURRENTLY concur_reindex_tab4; +WARNING: cannot reindex invalid index "public.concur_reindex_ind5" concurrently, skipping +NOTICE: table "concur_reindex_tab4" has no indexes that can be reindexed concurrently +\d concur_reindex_tab4 + Table "public.concur_reindex_tab4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | integer | | | +Indexes: + "concur_reindex_ind5" UNIQUE, btree (c1) INVALID + +-- But it is fixed with REINDEX INDEX. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; +\d concur_reindex_tab4 + Table "public.concur_reindex_tab4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | integer | | | +Indexes: + "concur_reindex_ind5" UNIQUE, btree (c1) + +DROP TABLE concur_reindex_tab4; +-- Check handling of indexes with expressions and predicates. The +-- definitions of the rebuilt indexes should match the original +-- definitions. +CREATE TABLE concur_exprs_tab (c1 int , c2 boolean); +INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), + (414515746, TRUE), + (897778963, FALSE); +CREATE UNIQUE INDEX concur_exprs_index_expr + ON concur_exprs_tab ((c1::text COLLATE "C")); +CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) + WHERE (c1::text > 500000000::text COLLATE "C"); +CREATE UNIQUE INDEX concur_exprs_index_pred_2 + ON concur_exprs_tab ((1 / c1)) + WHERE ('-H') >= (c2::TEXT) COLLATE "C"; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + pg_get_indexdef +--------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + pg_get_indexdef +---------------------------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + pg_get_indexdef +-------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= ((c2)::text COLLATE "C")) +(1 row) + +REINDEX TABLE CONCURRENTLY concur_exprs_tab; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + pg_get_indexdef +--------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + pg_get_indexdef +---------------------------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + pg_get_indexdef +-------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= ((c2)::text COLLATE "C")) +(1 row) + +-- ALTER TABLE recreates the indexes, which should keep their collations. +ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); + pg_get_indexdef +--------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); + pg_get_indexdef +---------------------------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) +(1 row) + +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); + pg_get_indexdef +------------------------------------------------------------------------------------------------------------------------------------------ + CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= (c2 COLLATE "C")) +(1 row) + +DROP TABLE concur_exprs_tab; +-- -- REINDEX SCHEMA -- REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist @@ -3119,6 +2301,8 @@ BEGIN; REINDEX SCHEMA schema_to_reindex; -- failure, cannot run in a transaction ERROR: REINDEX SCHEMA cannot run inside a transaction block END; +-- concurrently +REINDEX SCHEMA CONCURRENTLY schema_to_reindex; -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser; @@ -3127,6 +2311,11 @@ ERROR: must be owner of schema schema_to_reindex -- Clean up RESET ROLE; DROP ROLE regress_reindexuser; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA schema_to_reindex CASCADE; NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to table table1 +drop cascades to table table2 +drop cascades to materialized view matview +drop cascades to view view +drop cascades to table reindex_before +drop cascades to table reindex_after diff --git a/src/test/regress/expected/create_index_spgist.out b/src/test/regress/expected/create_index_spgist.out new file mode 100644 index 00000000000..1dd110dfc51 --- /dev/null +++ b/src/test/regress/expected/create_index_spgist.out @@ -0,0 +1,1309 @@ +-- +-- SP-GiST index tests +-- +CREATE TABLE quad_point_tbl AS + SELECT point(unique1,unique2) AS p FROM tenk1; +INSERT INTO quad_point_tbl + SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); +CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); +CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; +CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); +CREATE TABLE radix_text_tbl AS + SELECT name AS t FROM road WHERE name !~ '^[0-9]'; +INSERT INTO radix_text_tbl + SELECT 'P0123456789abcdef' FROM generate_series(1,1000); +INSERT INTO radix_text_tbl VALUES ('P0123456789abcde'); +INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF'); +CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t); +-- get non-indexed results for comparison purposes +SET enable_seqscan = ON; +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + count +------- + 1057 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + count +------- + 1057 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + count +------- + 6000 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + count +------- + 4999 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + count +------- + 5000 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + count +------- + 5999 +(1 row) + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + count +------- + 1 +(1 row) + +CREATE TEMP TABLE quad_point_tbl_ord_seq1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; +CREATE TEMP TABLE quad_point_tbl_ord_seq2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +CREATE TEMP TABLE quad_point_tbl_ord_seq3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + count +------- + 1000 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + count +------- + 272 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + count +------- + 272 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + count +------- + 273 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + count +------- + 273 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + count +------- + 1 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + count +------- + 2 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + count +------- + 50 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + count +------- + 50 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + count +------- + 48 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + count +------- + 48 +(1 row) + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + count +------- + 2 +(1 row) + +-- Now check the results from plain indexscan +SET enable_seqscan = OFF; +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p IS NULL) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p IS NOT NULL) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl +(2 rows) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p << '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + count +------- + 6000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p >> '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + count +------- + 4999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p <^ '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + count +------- + 5000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p >^ '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + count +------- + 5999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p ~= '(4585,365)'::point) +(3 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; + QUERY PLAN +----------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Order By: (p <-> '(0,0)'::point) +(3 rows) + +CREATE TEMP TABLE quad_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN quad_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +----------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) + Order By: (p <-> '(0,0)'::point) +(4 rows) + +CREATE TEMP TABLE quad_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN quad_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +----------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_quad_ind on quad_point_tbl + Index Cond: (p IS NOT NULL) + Order By: (p <-> '(333,400)'::point) +(4 rows) + +CREATE TEMP TABLE quad_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN quad_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +--------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + QUERY PLAN +--------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p << '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + count +------- + 6000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p >> '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + count +------- + 4999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p <^ '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + count +------- + 5000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p >^ '(5000,4000)'::point) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + count +------- + 5999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p ~= '(4585,365)'::point) +(3 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; + QUERY PLAN +------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Order By: (p <-> '(0,0)'::point) +(3 rows) + +CREATE TEMP TABLE kd_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN kd_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +--------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p <@ '(1000,1000),(200,200)'::box) + Order By: (p <-> '(0,0)'::point) +(4 rows) + +CREATE TEMP TABLE kd_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN kd_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +------------------------------------------------------- + WindowAgg + -> Index Only Scan using sp_kd_ind on kd_point_tbl + Index Cond: (p IS NOT NULL) + Order By: (p <-> '(333,400)'::point) +(4 rows) + +CREATE TEMP TABLE kd_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN kd_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + n | dist | p | n | dist | p +---+------+---+---+------+--- +(0 rows) + +-- check ORDER BY distance to NULL +SELECT (SELECT p FROM kd_point_tbl ORDER BY p <-> pt, p <-> '0,0' LIMIT 1) +FROM (VALUES (point '1,2'), (NULL), ('1234,5678')) pts(pt); + p +------------- + (59,21) + (59,21) + (1239,5647) +(3 rows) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t = 'P0123456789abcdef'::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + count +------- + 1000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t = 'P0123456789abcde'::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t = 'P0123456789abcdefF'::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t < 'Aztec Ct '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + count +------- + 272 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + QUERY PLAN +------------------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t ~<~ 'Aztec Ct '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + count +------- + 272 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + QUERY PLAN +----------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t <= 'Aztec Ct '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + count +------- + 273 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + QUERY PLAN +------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t ~<=~ 'Aztec Ct '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + count +------- + 273 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t = 'Aztec Ct '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t = 'Worth St '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + count +------- + 2 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + QUERY PLAN +----------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t >= 'Worth St '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + count +------- + 50 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + QUERY PLAN +------------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t ~>=~ 'Worth St '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + count +------- + 50 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + QUERY PLAN +---------------------------------------------------------------------- + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t > 'Worth St '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + count +------- + 48 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + QUERY PLAN +------------------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t ~>~ 'Worth St '::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + count +------- + 48 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Index Only Scan using sp_radix_ind on radix_text_tbl + Index Cond: (t ^@ 'Worth'::text) +(3 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + count +------- + 2 +(1 row) + +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF; +SET enable_indexscan = OFF; +SET enable_bitmapscan = ON; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p IS NULL) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p IS NULL) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + count +------- + 3 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p IS NOT NULL) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p IS NOT NULL) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + count +------- + 11000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; + QUERY PLAN +---------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + -> Bitmap Index Scan on sp_quad_ind +(3 rows) + +SELECT count(*) FROM quad_point_tbl; + count +------- + 11003 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: ('(1000,1000),(200,200)'::box @> p) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p << '(5000,4000)'::point) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p << '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + count +------- + 6000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p >> '(5000,4000)'::point) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p >> '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + count +------- + 4999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p <^ '(5000,4000)'::point) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p <^ '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + count +------- + 5000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p >^ '(5000,4000)'::point) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p >^ '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + count +------- + 5999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + QUERY PLAN +------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on quad_point_tbl + Recheck Cond: (p ~= '(4585,365)'::point) + -> Bitmap Index Scan on sp_quad_ind + Index Cond: (p ~= '(4585,365)'::point) +(5 rows) + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + QUERY PLAN +--------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: ('(1000,1000),(200,200)'::box @> p) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p <@ '(1000,1000),(200,200)'::box) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + count +------- + 1057 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p << '(5000,4000)'::point) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p << '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + count +------- + 6000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p >> '(5000,4000)'::point) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p >> '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + count +------- + 4999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p <^ '(5000,4000)'::point) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p <^ '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + count +------- + 5000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p >^ '(5000,4000)'::point) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p >^ '(5000,4000)'::point) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + count +------- + 5999 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + QUERY PLAN +------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on kd_point_tbl + Recheck Cond: (p ~= '(4585,365)'::point) + -> Bitmap Index Scan on sp_kd_ind + Index Cond: (p ~= '(4585,365)'::point) +(5 rows) + +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + QUERY PLAN +----------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t = 'P0123456789abcdef'::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t = 'P0123456789abcdef'::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + count +------- + 1000 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t = 'P0123456789abcde'::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t = 'P0123456789abcde'::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + QUERY PLAN +------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t = 'P0123456789abcdefF'::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t = 'P0123456789abcdefF'::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + QUERY PLAN +---------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t < 'Aztec Ct '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t < 'Aztec Ct '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + count +------- + 272 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + QUERY PLAN +------------------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t ~<~ 'Aztec Ct '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t ~<~ 'Aztec Ct '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + count +------- + 272 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + QUERY PLAN +----------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t <= 'Aztec Ct '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t <= 'Aztec Ct '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + count +------- + 273 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + QUERY PLAN +------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t ~<=~ 'Aztec Ct '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t ~<=~ 'Aztec Ct '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + count +------- + 273 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + QUERY PLAN +---------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t = 'Aztec Ct '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t = 'Aztec Ct '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + count +------- + 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + QUERY PLAN +---------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t = 'Worth St '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t = 'Worth St '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + count +------- + 2 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + QUERY PLAN +----------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t >= 'Worth St '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t >= 'Worth St '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + count +------- + 50 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + QUERY PLAN +------------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t ~>=~ 'Worth St '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t ~>=~ 'Worth St '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + count +------- + 50 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + QUERY PLAN +---------------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t > 'Worth St '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t > 'Worth St '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + count +------- + 48 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + QUERY PLAN +------------------------------------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t ~>~ 'Worth St '::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t ~>~ 'Worth St '::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + count +------- + 48 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + QUERY PLAN +------------------------------------------------ + Aggregate + -> Bitmap Heap Scan on radix_text_tbl + Recheck Cond: (t ^@ 'Worth'::text) + -> Bitmap Index Scan on sp_radix_ind + Index Cond: (t ^@ 'Worth'::text) +(5 rows) + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + count +------- + 2 +(1 row) + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; diff --git a/src/test/regress/expected/create_misc.out b/src/test/regress/expected/create_misc.out index 8366841ff04..cee35ed02f1 100644 --- a/src/test/regress/expected/create_misc.out +++ b/src/test/regress/expected/create_misc.out @@ -130,6 +130,13 @@ INSERT INTO f_star (class, e) VALUES ('f', '-12'::int2); INSERT INTO f_star (class, f) VALUES ('f', '(11111111,33333333),(22222222,44444444)'::polygon); INSERT INTO f_star (class) VALUES ('f'); +-- Analyze the X_star tables for better plan stability in later tests +ANALYZE a_star; +ANALYZE b_star; +ANALYZE c_star; +ANALYZE d_star; +ANALYZE e_star; +ANALYZE f_star; -- -- for internal portal (cursor) tests -- diff --git a/src/test/regress/expected/create_operator.out b/src/test/regress/expected/create_operator.out index e35eb092505..54e8b791595 100644 --- a/src/test/regress/expected/create_operator.out +++ b/src/test/regress/expected/create_operator.out @@ -4,7 +4,7 @@ CREATE OPERATOR ## ( leftarg = path, rightarg = path, - procedure = path_inter, + function = path_inter, commutator = ## ); CREATE OPERATOR <% ( @@ -45,6 +45,80 @@ CREATE OPERATOR => ( ERROR: syntax error at or near "=>" LINE 1: CREATE OPERATOR => ( ^ +-- lexing of <=, >=, <>, != has a number of edge cases +-- (=> is tested elsewhere) +-- this is legal because ! is not allowed in sql ops +CREATE OPERATOR !=- ( + leftarg = int8, -- right unary + procedure = numeric_fac +); +SELECT 2 !=-; + ?column? +---------- + 2 +(1 row) + +-- make sure lexer returns != as <> even in edge cases +SELECT 2 !=/**/ 1, 2 !=/**/ 2; + ?column? | ?column? +----------+---------- + t | f +(1 row) + +SELECT 2 !=-- comment to be removed by psql + 1; + ?column? +---------- + t +(1 row) + +DO $$ -- use DO to protect -- from psql + declare r boolean; + begin + execute $e$ select 2 !=-- comment + 1 $e$ into r; + raise info 'r = %', r; + end; +$$; +INFO: r = t +-- check that <= etc. followed by more operator characters are returned +-- as the correct token with correct precedence +SELECT true<>-1 BETWEEN 1 AND 1; -- BETWEEN has prec. above <> but below Op + ?column? +---------- + t +(1 row) + +SELECT false<>/**/1 BETWEEN 1 AND 1; + ?column? +---------- + t +(1 row) + +SELECT false<=-1 BETWEEN 1 AND 1; + ?column? +---------- + t +(1 row) + +SELECT false>=-1 BETWEEN 1 AND 1; + ?column? +---------- + t +(1 row) + +SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3; + ?column? | ?column? | ?column? +----------+----------+---------- + t | t | t +(1 row) + +SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2; + ?column? | ?column? | ?column? +----------+----------+---------- + f | f | f +(1 row) + -- Should fail. CREATE OPERATOR requires USAGE on SCHEMA BEGIN TRANSACTION; CREATE ROLE regress_rol_op1; @@ -107,7 +181,7 @@ ERROR: at least one of leftarg or rightarg must be specified CREATE OPERATOR #@%# ( leftarg = int8 ); -ERROR: operator procedure must be specified +ERROR: operator function must be specified -- Should fail. CREATE OPERATOR requires USAGE on TYPE BEGIN TRANSACTION; CREATE ROLE regress_rol_op3; @@ -185,11 +259,11 @@ CREATE OPERATOR === ( "Leftarg" = box, "Rightarg" = box, - "Procedure" = area_equal_procedure, + "Procedure" = area_equal_function, "Commutator" = ===, "Negator" = !==, - "Restrict" = area_restriction_procedure, - "Join" = area_join_procedure, + "Restrict" = area_restriction_function, + "Join" = area_join_function, "Hashes", "Merges" ); @@ -202,4 +276,4 @@ WARNING: operator attribute "Restrict" not recognized WARNING: operator attribute "Join" not recognized WARNING: operator attribute "Hashes" not recognized WARNING: operator attribute "Merges" not recognized -ERROR: operator procedure must be specified +ERROR: operator function must be specified diff --git a/src/test/regress/expected/create_procedure.out b/src/test/regress/expected/create_procedure.out index 66cdad760ca..211a42cefa0 100644 --- a/src/test/regress/expected/create_procedure.out +++ b/src/test/regress/expected/create_procedure.out @@ -1,8 +1,8 @@ CALL nonexistent(); -- error -ERROR: function nonexistent() does not exist +ERROR: procedure nonexistent() does not exist LINE 1: CALL nonexistent(); ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. +HINT: No procedure matches the given name and argument types. You might need to add explicit type casts. CALL random(); -- error ERROR: random() is not a procedure LINE 1: CALL random(); @@ -15,14 +15,6 @@ LANGUAGE SQL AS $$ INSERT INTO cp_test VALUES (1, x); $$; -SELECT ptest1('x'); -- error -ERROR: ptest1(unknown) is a procedure -LINE 1: SELECT ptest1('x'); - ^ -HINT: To call a procedure, use CALL. -CALL ptest1('a'); -- ok -CALL ptest1('xy' || 'zzy'); -- ok, constant-folded arg -CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)); -- ok, volatile arg \df ptest1 List of functions Schema | Name | Result data type | Argument data types | Type @@ -41,6 +33,30 @@ SELECT pg_get_functiondef('ptest1'::regproc); (1 row) +-- show only normal functions +\dfn public.*test*1 + List of functions + Schema | Name | Result data type | Argument data types | Type +--------+--------------+------------------+---------------------+------ + public | cp_testfunc1 | integer | a integer | func +(1 row) + +-- show only procedures +\dfp public.*test*1 + List of functions + Schema | Name | Result data type | Argument data types | Type +--------+--------+------------------+---------------------+------ + public | ptest1 | | x text | proc +(1 row) + +SELECT ptest1('x'); -- error +ERROR: ptest1(unknown) is a procedure +LINE 1: SELECT ptest1('x'); + ^ +HINT: To call a procedure, use CALL. +CALL ptest1('a'); -- ok +CALL ptest1('xy' || 'zzy'); -- ok, constant-folded arg +CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)); -- ok, volatile arg SELECT * FROM cp_test ORDER BY b COLLATE "C"; a | b ---+------- @@ -91,6 +107,45 @@ $$; ERROR: calling procedures with output arguments is not supported in SQL functions CONTEXT: SQL function "ptest4b" DROP PROCEDURE ptest4a; +-- named and default parameters +CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES(a, b); +INSERT INTO cp_test VALUES(c, b); +$$; +TRUNCATE cp_test; +CALL ptest5(10, 'Hello', 20); +CALL ptest5(10, 'Hello'); +CALL ptest5(10, b => 'Hello'); +CALL ptest5(b => 'Hello', a => 10); +SELECT * FROM cp_test; + a | b +-----+------- + 10 | Hello + 20 | Hello + 10 | Hello + 100 | Hello + 10 | Hello + 100 | Hello + 10 | Hello + 100 | Hello +(8 rows) + +-- polymorphic types +CREATE PROCEDURE ptest6(a int, b anyelement) +LANGUAGE SQL +AS $$ +SELECT NULL::int; +$$; +CALL ptest6(1, 2); +-- collation assignment +CREATE PROCEDURE ptest7(a text, b text) +LANGUAGE SQL +AS $$ +SELECT a = b; +$$; +CALL ptest7(least('a', 'b'), 'a'); -- various error cases CALL version(); -- error: not a procedure ERROR: version() is not a procedure @@ -101,6 +156,7 @@ CALL sum(1); -- error: not a procedure ERROR: sum(integer) is not a procedure LINE 1: CALL sum(1); ^ +HINT: To call a function, use SELECT. CREATE PROCEDURE ptestx() LANGUAGE SQL WINDOW AS $$ INSERT INTO cp_test VALUES (1, 'a') $$; ERROR: invalid attribute in procedure definition LINE 1: CREATE PROCEDURE ptestx() LANGUAGE SQL WINDOW AS $$ INSERT I... diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index e7244390372..ce2484fd4e4 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -47,7 +47,7 @@ CREATE TABLE tenk1 ( stringu1 name, stringu2 name, string4 name -) WITH OIDS; +); CREATE TABLE tenk2 ( unique1 int4, unique2 int4, @@ -74,7 +74,7 @@ CREATE TABLE person ( CREATE TABLE emp ( salary int4, manager name -) INHERITS (person) WITH OIDS; +) INHERITS (person); CREATE TABLE student ( gpa float8 ) INHERITS (person); @@ -218,8 +218,6 @@ NOTICE: relation "test_tsvector" already exists, skipping -- invalid: non-lowercase quoted reloptions identifiers CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a; ERROR: unrecognized parameter "Fillfactor" -CREATE TABLE tas_case (a text) WITH ("Oids" = true); -ERROR: unrecognized parameter "Oids" CREATE UNLOGGED TABLE unlogged1 (a int primary key); -- OK CREATE TEMPORARY TABLE unlogged2 (a int primary key); -- OK SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname; @@ -263,9 +261,76 @@ ERROR: relation "as_select1" already exists CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; NOTICE: relation "as_select1" already exists, skipping DROP TABLE as_select1; --- check that the oid column is added before the primary key is checked -CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; -DROP TABLE oid_pk; +PREPARE select1 AS SELECT 1 as a; +CREATE TABLE as_select1 AS EXECUTE select1; +CREATE TABLE as_select1 AS EXECUTE select1; +ERROR: relation "as_select1" already exists +SELECT * FROM as_select1; + a +--- + 1 +(1 row) + +CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1; +NOTICE: relation "as_select1" already exists, skipping +DROP TABLE as_select1; +DEALLOCATE select1; +-- create an extra wide table to test for issues related to that +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +\set ECHO none +INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col'); +SELECT firstc, lastc FROM extra_wide_table; + firstc | lastc +-----------+---------- + first col | last col +(1 row) + +-- check that tables with oids cannot be created anymore +CREATE TABLE withoid() WITH OIDS; +ERROR: syntax error at or near "OIDS" +LINE 1: CREATE TABLE withoid() WITH OIDS; + ^ +CREATE TABLE withoid() WITH (oids); +ERROR: tables declared WITH OIDS are not supported +CREATE TABLE withoid() WITH (oids = true); +ERROR: tables declared WITH OIDS are not supported +-- but explicitly not adding oids is still supported +CREATE TEMP TABLE withoutoid() WITHOUT OIDS; DROP TABLE withoutoid; +CREATE TEMP TABLE withoutoid() WITH (oids = false); DROP TABLE withoutoid; +-- check restriction with default expressions +-- invalid use of column reference in default expressions +CREATE TABLE default_expr_column (id int DEFAULT (id)); +ERROR: cannot use column reference in DEFAULT expression +LINE 1: CREATE TABLE default_expr_column (id int DEFAULT (id)); + ^ +CREATE TABLE default_expr_column (id int DEFAULT (bar.id)); +ERROR: cannot use column reference in DEFAULT expression +LINE 1: CREATE TABLE default_expr_column (id int DEFAULT (bar.id)); + ^ +CREATE TABLE default_expr_agg_column (id int DEFAULT (avg(id))); +ERROR: cannot use column reference in DEFAULT expression +LINE 1: ...TE TABLE default_expr_agg_column (id int DEFAULT (avg(id))); + ^ +-- invalid column definition +CREATE TABLE default_expr_non_column (a int DEFAULT (avg(non_existent))); +ERROR: cannot use column reference in DEFAULT expression +LINE 1: ...TABLE default_expr_non_column (a int DEFAULT (avg(non_existe... + ^ +-- invalid use of aggregate +CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))); +ERROR: aggregate functions are not allowed in DEFAULT expressions +LINE 1: CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))); + ^ +-- invalid use of subquery +CREATE TABLE default_expr_agg (a int DEFAULT (select 1)); +ERROR: cannot use subquery in DEFAULT expression +LINE 1: CREATE TABLE default_expr_agg (a int DEFAULT (select 1)); + ^ +-- invalid use of set-returning function +CREATE TABLE default_expr_agg (a int DEFAULT (generate_series(1,3))); +ERROR: set-returning functions are not allowed in DEFAULT expressions +LINE 1: CREATE TABLE default_expr_agg (a int DEFAULT (generate_serie... + ^ -- -- Partitioned tables -- @@ -288,11 +353,6 @@ CREATE TABLE partitioned ( ERROR: exclusion constraints are not supported on partitioned tables LINE 3: EXCLUDE USING gist (a WITH &&) ^ --- prevent column from being used twice in the partition key -CREATE TABLE partitioned ( - a int -) PARTITION BY RANGE (a, a); -ERROR: column "a" appears more than once in partition key -- prevent using prohibited expressions in the key CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE; CREATE TABLE partitioned ( @@ -333,11 +393,15 @@ CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (b); ERROR: column "b" named in partition key does not exist +LINE 3: ) PARTITION BY RANGE (b); + ^ -- cannot use system columns in partition key CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (xmin); ERROR: cannot use system column "xmin" in partition key +LINE 3: ) PARTITION BY RANGE (xmin); + ^ -- functions in key must be immutable CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; CREATE TABLE partitioned ( @@ -354,7 +418,7 @@ ERROR: partition key expressions cannot contain whole-row references CREATE TABLE partitioned ( a point ) PARTITION BY LIST (a); -ERROR: data type point has no default btree operator class +ERROR: data type point has no default operator class for access method "btree" HINT: You must specify a btree operator class or define a default btree operator class for the data type. CREATE TABLE partitioned ( a point @@ -363,7 +427,7 @@ ERROR: operator class "point_ops" does not exist for access method "btree" CREATE TABLE partitioned ( a point ) PARTITION BY RANGE (a); -ERROR: data type point has no default btree operator class +ERROR: data type point has no default operator class for access method "btree" HINT: You must specify a btree operator class or define a default btree operator class for the data type. CREATE TABLE partitioned ( a point @@ -404,7 +468,7 @@ CREATE TABLE fail () INHERITS (partitioned2); ERROR: cannot inherit from partitioned table "partitioned2" -- Partition key in describe output \d partitioned - Table "public.partitioned" + Partitioned table "public.partitioned" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -415,7 +479,7 @@ Partition key: RANGE (a oid_ops, plusone(b), c, d COLLATE "C") Number of partitions: 0 \d+ partitioned2 - Table "public.partitioned2" + Partitioned table "public.partitioned2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- a | integer | | | | plain | | @@ -437,6 +501,42 @@ Partition of: partitioned2 FOR VALUES FROM ('-1', 'aaaaa') TO (100, 'ccccc') Partition constraint: (((a + 1) IS NOT NULL) AND (substr(b, 1, 5) IS NOT NULL) AND (((a + 1) > '-1'::integer) OR (((a + 1) = '-1'::integer) AND (substr(b, 1, 5) >= 'aaaaa'::text))) AND (((a + 1) < 100) OR (((a + 1) = 100) AND (substr(b, 1, 5) < 'ccccc'::text)))) DROP TABLE partitioned, partitioned2; +-- check that dependencies of partition columns are handled correctly +create domain intdom1 as int; +create table partitioned ( + a intdom1, + b text +) partition by range (a); +alter table partitioned drop column a; -- fail +ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned" +drop domain intdom1; -- fail, requires cascade +ERROR: cannot drop type intdom1 because other objects depend on it +DETAIL: table partitioned depends on type intdom1 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +drop domain intdom1 cascade; +NOTICE: drop cascades to table partitioned +table partitioned; -- gone +ERROR: relation "partitioned" does not exist +LINE 1: table partitioned; + ^ +-- likewise for columns used in partition expressions +create domain intdom1 as int; +create table partitioned ( + a intdom1, + b text +) partition by range (plusone(a)); +alter table partitioned drop column a; -- fail +ERROR: cannot drop column "a" because it is part of the partition key of relation "partitioned" +drop domain intdom1; -- fail, requires cascade +ERROR: cannot drop type intdom1 because other objects depend on it +DETAIL: table partitioned depends on type intdom1 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +drop domain intdom1 cascade; +NOTICE: drop cascades to table partitioned +table partitioned; -- gone +ERROR: relation "partitioned" does not exist +LINE 1: table partitioned; + ^ -- -- Partitions -- @@ -444,19 +544,54 @@ DROP TABLE partitioned, partitioned2; CREATE TABLE list_parted ( a int ) PARTITION BY LIST (a); --- syntax allows only string literal, numeric literal and null to be --- specified for a partition bound value -CREATE TABLE part_1 PARTITION OF list_parted FOR VALUES IN ('1'); -CREATE TABLE part_2 PARTITION OF list_parted FOR VALUES IN (2); +CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1'); +CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2); +CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN ((2+1)); CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null); -CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN (int '1'); -ERROR: syntax error at or near "int" -LINE 1: ... fail_part PARTITION OF list_parted FOR VALUES IN (int '1'); - ^ -CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN ('1'::int); -ERROR: syntax error at or near "::" -LINE 1: ...fail_part PARTITION OF list_parted FOR VALUES IN ('1'::int); - ^ +\d+ list_parted + Partitioned table "public.list_parted" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | +Partition key: LIST (a) +Partitions: part_null FOR VALUES IN (NULL), + part_p1 FOR VALUES IN (1), + part_p2 FOR VALUES IN (2), + part_p3 FOR VALUES IN (3) + +-- forbidden expressions for partition bound with list partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename); +ERROR: cannot use column reference in partition bound expression +LINE 1: ...expr_fail PARTITION OF list_parted FOR VALUES IN (somename); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename); +ERROR: cannot use column reference in partition bound expression +LINE 1: ...expr_fail PARTITION OF list_parted FOR VALUES IN (somename.s... + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a); +ERROR: cannot use column reference in partition bound expression +LINE 1: ..._bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)); +ERROR: cannot use column reference in partition bound expression +LINE 1: ...s_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename)); +ERROR: cannot use column reference in partition bound expression +LINE 1: ..._fail PARTITION OF list_parted FOR VALUES IN (sum(somename))... + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)); +ERROR: aggregate functions are not allowed in partition bound +LINE 1: ...s_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)); +ERROR: cannot use subquery in partition bound +LINE 1: ...expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)... + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6)); +ERROR: set-returning functions are not allowed in partition bound +LINE 1: ...expr_fail PARTITION OF list_parted FOR VALUES IN (generate_s... + ^ -- syntax does not allow empty list of values for list partitions CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN (); ERROR: syntax error at or near ")" @@ -485,19 +620,15 @@ ERROR: specified value cannot be cast to type boolean for column "a" LINE 1: ...REATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1); ^ DROP TABLE bools; --- specified literal can be cast, but cast isn't immutable +-- specified literal can be cast, and the cast might not be immutable CREATE TABLE moneyp ( a money ) PARTITION BY LIST (a); CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10); -ERROR: specified value cannot be cast to type money for column "a" -LINE 1: ...EATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10); - ^ -DETAIL: The cast requires a non-immutable conversion. -HINT: Try putting the literal value in single quotes. -CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN ('10'); +CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11'); +CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int); DROP TABLE moneyp; --- immutable cast should work, though +-- cast is immutable CREATE TABLE bigintp ( a bigint ) PARTITION BY LIST (a); @@ -509,6 +640,47 @@ DROP TABLE bigintp; CREATE TABLE range_parted ( a date ) PARTITION BY RANGE (a); +-- forbidden expressions for partition bounds with range partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename) TO ('2019-01-01'); +ERROR: cannot use column reference in partition bound expression +LINE 2: FOR VALUES FROM (somename) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename.somename) TO ('2019-01-01'); +ERROR: cannot use column reference in partition bound expression +LINE 2: FOR VALUES FROM (somename.somename) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (a) TO ('2019-01-01'); +ERROR: cannot use column reference in partition bound expression +LINE 2: FOR VALUES FROM (a) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(a)) TO ('2019-01-01'); +ERROR: cannot use column reference in partition bound expression +LINE 2: FOR VALUES FROM (max(a)) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(somename)) TO ('2019-01-01'); +ERROR: cannot use column reference in partition bound expression +LINE 2: FOR VALUES FROM (max(somename)) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01'); +ERROR: aggregate functions are not allowed in partition bound +LINE 2: FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01'... + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM ((select 1)) TO ('2019-01-01'); +ERROR: cannot use subquery in partition bound +LINE 2: FOR VALUES FROM ((select 1)) TO ('2019-01-01'); + ^ +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01'); +ERROR: set-returning functions are not allowed in partition bound +LINE 2: FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01'); + ^ -- trying to specify list for range partitioned table CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a'); ERROR: invalid bound specification for a range partition @@ -576,29 +748,6 @@ CREATE TEMP TABLE temp_parted ( CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a'); ERROR: cannot create a permanent relation as partition of temporary relation "temp_parted" DROP TABLE temp_parted; --- cannot create a table with oids as partition of table without oids -CREATE TABLE no_oids_parted ( - a int -) PARTITION BY RANGE (a) WITHOUT OIDS; -CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS; -ERROR: cannot create table with OIDs as partition of table without OIDs -DROP TABLE no_oids_parted; --- If the partitioned table has oids, then the partition must have them. --- If the WITHOUT OIDS option is specified for partition, it is overridden. -CREATE TABLE oids_parted ( - a int -) PARTITION BY RANGE (a) WITH OIDS; -CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS; -\d+ part_forced_oids - Table "public.part_forced_oids" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+---------+--------------+------------- - a | integer | | | | plain | | -Partition of: oids_parted FOR VALUES FROM (1) TO (10) -Partition constraint: ((a IS NOT NULL) AND (a >= 1) AND (a < 10)) -Has OIDs: yes - -DROP TABLE oids_parted, part_forced_oids; -- check for partition bound overlap and other invalid specifications CREATE TABLE list_parted2 ( a varchar @@ -710,23 +859,100 @@ CREATE TABLE part_b PARTITION OF parted ( ) FOR VALUES IN ('b'); ERROR: column "b" specified more than once CREATE TABLE part_b PARTITION OF parted ( - b NOT NULL DEFAULT 1 CHECK (b >= 0), - CONSTRAINT check_a CHECK (length(a) > 0) + b NOT NULL DEFAULT 1, + CONSTRAINT check_a CHECK (length(a) > 0), + CONSTRAINT check_b CHECK (b >= 0) ) FOR VALUES IN ('b'); NOTICE: merging constraint "check_a" with inherited definition --- conislocal should be false for any merged constraints -SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass AND conname = 'check_a'; +-- conislocal should be false for any merged constraints, true otherwise +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY conislocal, coninhcount; conislocal | coninhcount ------------+------------- f | 1 -(1 row) + t | 0 +(2 rows) + +-- Once check_b is added to the parent, it should be made non-local for part_b +ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0); +NOTICE: merging constraint "check_b" with inherited definition +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass; + conislocal | coninhcount +------------+------------- + f | 1 + f | 1 +(2 rows) + +-- Neither check_a nor check_b are droppable from part_b +ALTER TABLE part_b DROP CONSTRAINT check_a; +ERROR: cannot drop inherited constraint "check_a" of relation "part_b" +ALTER TABLE part_b DROP CONSTRAINT check_b; +ERROR: cannot drop inherited constraint "check_b" of relation "part_b" +-- And dropping it from parted should leave no trace of them on part_b, unlike +-- traditional inheritance where they will be left behind, because they would +-- be local constraints. +ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b; +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass; + conislocal | coninhcount +------------+------------- +(0 rows) -- specify PARTITION BY for a partition CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c); ERROR: column "c" named in partition key does not exist +LINE 1: ...TITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c); + ^ CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b)); -- create a level-2 partition CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); +-- check that NOT NULL and default value are inherited correctly +create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a); +create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1); +insert into parted_notnull_inh_test (b) values (null); +ERROR: null value in column "b" violates not-null constraint +DETAIL: Failing row contains (1, null). +-- note that while b's default is overriden, a's default is preserved +\d parted_notnull_inh_test1 + Table "public.parted_notnull_inh_test1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | not null | 1 + b | integer | | not null | 1 +Partition of: parted_notnull_inh_test FOR VALUES IN (1) + +drop table parted_notnull_inh_test; +-- check for a conflicting COLLATE clause +create table parted_collate_must_match (a text collate "C", b text collate "C") + partition by range (a); +-- on the partition key +create table parted_collate_must_match1 partition of parted_collate_must_match + (a collate "POSIX") for values from ('a') to ('m'); +-- on another column +create table parted_collate_must_match2 partition of parted_collate_must_match + (b collate "POSIX") for values from ('m') to ('z'); +drop table parted_collate_must_match; +-- check that specifying incompatible collations for partition bound +-- expressions fails promptly +create table test_part_coll_posix (a text) partition by range (a collate "POSIX"); +-- fail +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "C") to ('g'); +ERROR: collation of partition bound value for column "a" does not match partition key collation "POSIX" +LINE 1: ...artition of test_part_coll_posix for values from ('a' collat... + ^ +-- ok +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "POSIX") to ('g'); +-- ok +create table test_part_coll2 partition of test_part_coll_posix for values from ('g') to ('m'); +-- using a cast expression uses the target type's default collation +-- fail +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "C") to ('s'); +ERROR: collation of partition bound value for column "a" does not match partition key collation "POSIX" +LINE 1: ...ion of test_part_coll_posix for values from (name 'm' collat... + ^ +-- ok +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "POSIX") to ('s'); +-- ok; partition collation silently overrides the default collation of type 'name' +create table test_part_coll_cast2 partition of test_part_coll_posix for values from (name 's') to ('z'); +drop table test_part_coll_posix; -- Partition bound in describe output \d+ part_b Table "public.part_b" @@ -736,13 +962,10 @@ CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); b | integer | | not null | 1 | plain | | Partition of: parted FOR VALUES IN ('b') Partition constraint: ((a IS NOT NULL) AND (a = 'b'::text)) -Check constraints: - "check_a" CHECK (length(a) > 0) - "part_b_b_check" CHECK (b >= 0) -- Both partition bound and partition key in describe output \d+ part_c - Table "public.part_c" + Partitioned table "public.part_c" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- a | text | | | | extended | | @@ -750,8 +973,6 @@ Check constraints: Partition of: parted FOR VALUES IN ('c') Partition constraint: ((a IS NOT NULL) AND (a = 'c'::text)) Partition key: RANGE (b) -Check constraints: - "check_a" CHECK (length(a) > 0) Partitions: part_c_1_10 FOR VALUES FROM (1) TO (10) -- a level-2 partition's constraint will include the parent's expressions @@ -763,26 +984,22 @@ Partitions: part_c_1_10 FOR VALUES FROM (1) TO (10) b | integer | | not null | 0 | plain | | Partition of: part_c FOR VALUES FROM (1) TO (10) Partition constraint: ((a IS NOT NULL) AND (a = 'c'::text) AND (b IS NOT NULL) AND (b >= 1) AND (b < 10)) -Check constraints: - "check_a" CHECK (length(a) > 0) -- Show partition count in the parent's describe output -- Tempted to include \d+ output listing partitions with bound info but -- output could vary depending on the order in which partition oids are -- returned. \d parted - Table "public.parted" + Partitioned table "public.parted" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | text | | | b | integer | | not null | 0 Partition key: LIST (a) -Check constraints: - "check_a" CHECK (length(a) > 0) Number of partitions: 3 (Use \d+ to list them.) \d hash_parted - Table "public.hash_parted" + Partitioned table "public.hash_parted" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -837,10 +1054,22 @@ Partition of: range_parted4 FOR VALUES FROM (6, 8, MINVALUE) TO (9, MAXVALUE, MA Partition constraint: ((abs(a) IS NOT NULL) AND (abs(b) IS NOT NULL) AND (c IS NOT NULL) AND ((abs(a) > 6) OR ((abs(a) = 6) AND (abs(b) >= 8))) AND (abs(a) <= 9)) DROP TABLE range_parted4; +-- user-defined operator class in partition key +CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql + AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$; +CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4), + OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4), + OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4); +CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops); +CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000); +INSERT INTO partkey_t VALUES (100); +INSERT INTO partkey_t VALUES (200); -- cleanup DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3; -DROP TABLE hash_parted; -DROP TABLE hash_parted2; +DROP TABLE partkey_t, hash_parted, hash_parted2; +DROP OPERATOR CLASS test_int4_ops USING btree; +DROP FUNCTION my_int4_sort(int4,int4); -- comments on partitioned tables columns CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a); COMMENT ON TABLE parted_col_comment IS 'Am partitioned table'; @@ -852,7 +1081,7 @@ SELECT obj_description('parted_col_comment'::regclass); (1 row) \d+ parted_col_comment - Table "public.parted_col_comment" + Partitioned table "public.parted_col_comment" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+--------------- a | integer | | | | plain | | Partition key @@ -870,6 +1099,72 @@ CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}'); --------+-----------+-----------+----------+---------+----------+--------------+------------- a | integer[] | | | | extended | | Partition of: arrlp FOR VALUES IN ('{1}', '{2}') -Partition constraint: ((a IS NOT NULL) AND (((a)::anyarray OPERATOR(pg_catalog.=) '{1}'::integer[]) OR ((a)::anyarray OPERATOR(pg_catalog.=) '{2}'::integer[]))) +Partition constraint: ((a IS NOT NULL) AND ((a = '{1}'::integer[]) OR (a = '{2}'::integer[]))) DROP TABLE arrlp; +-- partition on boolean column +create table boolspart (a bool) partition by list (a); +create table boolspart_t partition of boolspart for values in (true); +create table boolspart_f partition of boolspart for values in (false); +\d+ boolspart + Partitioned table "public.boolspart" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | boolean | | | | plain | | +Partition key: LIST (a) +Partitions: boolspart_f FOR VALUES IN (false), + boolspart_t FOR VALUES IN (true) + +drop table boolspart; +-- partitions mixing temporary and permanent relations +create table perm_parted (a int) partition by list (a); +create temporary table temp_parted (a int) partition by list (a); +create table perm_part partition of temp_parted default; -- error +ERROR: cannot create a permanent relation as partition of temporary relation "temp_parted" +create temp table temp_part partition of perm_parted default; -- error +ERROR: cannot create a temporary relation as partition of permanent relation "perm_parted" +create temp table temp_part partition of temp_parted default; -- ok +drop table perm_parted cascade; +drop table temp_parted cascade; +-- check that adding partitions to a table while it is being used is prevented +create table tab_part_create (a int) partition by list (a); +create or replace function func_part_create() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; + return null; + end $$; +create trigger trig_part_create before insert on tab_part_create + for each statement execute procedure func_part_create(); +insert into tab_part_create values (1); +ERROR: cannot CREATE TABLE .. PARTITION OF "tab_part_create" because it is being used by active queries in this session +CONTEXT: SQL statement "create table tab_part_create_1 partition of tab_part_create for values in (1)" +PL/pgSQL function func_part_create() line 3 at EXECUTE +drop table tab_part_create; +drop function func_part_create(); +-- test using a volatile expression as partition bound +create table volatile_partbound_test (partkey timestamp) partition by range (partkey); +create table volatile_partbound_test1 partition of volatile_partbound_test for values from (minvalue) to (current_timestamp); +create table volatile_partbound_test2 partition of volatile_partbound_test for values from (current_timestamp) to (maxvalue); +-- this should go into the partition volatile_partbound_test2 +insert into volatile_partbound_test values (current_timestamp); +select tableoid::regclass from volatile_partbound_test; + tableoid +-------------------------- + volatile_partbound_test2 +(1 row) + +drop table volatile_partbound_test; +-- test the case where a check constraint on default partition allows +-- to avoid scanning it when adding a new partition +create table defcheck (a int, b int) partition by list (b); +create table defcheck_def (a int, c int, b int); +alter table defcheck_def drop c; +alter table defcheck attach partition defcheck_def default; +alter table defcheck_def add check (b <= 0 and b is not null); +create table defcheck_1 partition of defcheck for values in (1, null); +-- test that complex default partition constraints are enforced correctly +insert into defcheck_def values (0, 0); +create table defcheck_0 partition of defcheck for values in (0); +ERROR: updated partition constraint for default partition "defcheck_def" would be violated by some row +drop table defcheck; diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out index 8d4543bfe8d..2a063a8369a 100644 --- a/src/test/regress/expected/create_table_like.out +++ b/src/test/regress/expected/create_table_like.out @@ -113,6 +113,126 @@ SELECT * FROM test_like_id_3; -- identity was copied and applied (1 row) DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3; +CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +\d test_like_gen_1 + Table "public.test_like_gen_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | generated always as (a * 2) stored + +INSERT INTO test_like_gen_1 (a) VALUES (1); +SELECT * FROM test_like_gen_1; + a | b +---+--- + 1 | 2 +(1 row) + +CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1); +\d test_like_gen_2 + Table "public.test_like_gen_2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + +INSERT INTO test_like_gen_2 (a) VALUES (1); +SELECT * FROM test_like_gen_2; + a | b +---+--- + 1 | +(1 row) + +CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED); +\d test_like_gen_3 + Table "public.test_like_gen_3" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | generated always as (a * 2) stored + +INSERT INTO test_like_gen_3 (a) VALUES (1); +SELECT * FROM test_like_gen_3; + a | b +---+--- + 1 | 2 +(1 row) + +DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3; +CREATE TABLE test_like_4 (a int, b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED); +\d test_like_4 + Table "public.test_like_4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | 42 + c | integer | | | generated always as (a * 2) stored + +CREATE TABLE test_like_4a (LIKE test_like_4); +CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS); +CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED); +CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED); +\d test_like_4a + Table "public.test_like_4a" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + c | integer | | | + +INSERT INTO test_like_4a VALUES(11); +TABLE test_like_4a; + a | b | c +----+---+--- + 11 | | +(1 row) + +\d test_like_4b + Table "public.test_like_4b" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | 42 + c | integer | | | + +INSERT INTO test_like_4b VALUES(11); +TABLE test_like_4b; + a | b | c +----+----+--- + 11 | 42 | +(1 row) + +\d test_like_4c + Table "public.test_like_4c" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | + c | integer | | | generated always as (a * 2) stored + +INSERT INTO test_like_4c VALUES(11); +TABLE test_like_4c; + a | b | c +----+---+---- + 11 | | 22 +(1 row) + +\d test_like_4d + Table "public.test_like_4d" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | 42 + c | integer | | | generated always as (a * 2) stored + +INSERT INTO test_like_4d VALUES(11); +TABLE test_like_4d; + a | b | c +----+----+---- + 11 | 42 | 22 +(1 row) + +DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d; CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text); /* copies indexes */ INSERT INTO inhg VALUES (5, 10); INSERT INTO inhg VALUES (20, 10); -- should fail @@ -243,7 +363,7 @@ Indexes: Check constraints: "ctlt1_a_check" CHECK (length(a) > 2) Statistics objects: - "public"."ctlt_all_a_b_stat" (ndistinct, dependencies) ON a, b FROM ctlt_all + "public"."ctlt_all_a_b_stat" (ndistinct, dependencies, mcv) ON a, b FROM ctlt_all SELECT c.relname, objsubid, description FROM pg_description, pg_index i, pg_class c WHERE classoid = 'pg_class'::regclass AND objoid = i.indexrelid AND c.oid = i.indexrelid AND i.indrelid = 'ctlt_all'::regclass ORDER BY c.relname, objsubid; relname | objsubid | description @@ -285,37 +405,3 @@ DROP TYPE ctlty1; DROP VIEW ctlv1; DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12; NOTICE: table "ctlt10" does not exist, skipping -/* LIKE WITH OIDS */ -CREATE TABLE has_oid (x INTEGER) WITH OIDS; -CREATE TABLE no_oid (y INTEGER); -CREATE TABLE like_test (z INTEGER, LIKE has_oid); -SELECT oid FROM like_test; - oid ------ -(0 rows) - -CREATE TABLE like_test2 (z INTEGER, LIKE no_oid); -SELECT oid FROM like_test2; -- fail -ERROR: column "oid" does not exist -LINE 1: SELECT oid FROM like_test2; - ^ -CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid); -SELECT oid FROM like_test3; - oid ------ -(0 rows) - -CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid); -SELECT oid FROM like_test4; - oid ------ -(0 rows) - -CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS; -SELECT oid FROM like_test5; - oid ------ -(0 rows) - -DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, - like_test4, like_test5; diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out index 2f7d5f94d7b..8309756030d 100644 --- a/src/test/regress/expected/create_type.out +++ b/src/test/regress/expected/create_type.out @@ -161,13 +161,13 @@ DROP FUNCTION base_fn_out(opaque); -- error ERROR: function base_fn_out(opaque) does not exist DROP TYPE base_type; -- error ERROR: cannot drop type base_type because other objects depend on it -DETAIL: function base_fn_out(base_type) depends on type base_type -function base_fn_in(cstring) depends on type base_type +DETAIL: function base_fn_in(cstring) depends on type base_type +function base_fn_out(base_type) depends on type base_type HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP TYPE base_type CASCADE; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to function base_fn_out(base_type) -drop cascades to function base_fn_in(cstring) +DETAIL: drop cascades to function base_fn_in(cstring) +drop cascades to function base_fn_out(base_type) -- Check usage of typmod with a user-defined type -- (we have borrowed numeric's typmod functions) CREATE TEMP TABLE mytab (foo widget(42,13,7)); -- should fail diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out index 141fc6da62a..2fd36ca9a14 100644 --- a/src/test/regress/expected/create_view.out +++ b/src/test/regress/expected/create_view.out @@ -20,6 +20,16 @@ COMMENT ON VIEW noview IS 'no view'; ERROR: relation "noview" does not exist COMMENT ON VIEW toyemp IS 'is a view'; COMMENT ON VIEW toyemp IS NULL; +-- These views are left around mainly to exercise special cases in pg_dump. +CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20)); +CREATE VIEW key_dependent_view AS + SELECT * FROM view_base_table GROUP BY key; +ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey; -- fails +ERROR: cannot drop constraint view_base_table_pkey on table view_base_table because other objects depend on it +DETAIL: view key_dependent_view depends on constraint view_base_table_pkey on table view_base_table +HINT: Use DROP ... CASCADE to drop the dependent objects too. +CREATE VIEW key_dependent_view_no_cols AS + SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0; -- -- CREATE OR REPLACE VIEW -- @@ -759,6 +769,41 @@ View definition: FROM temp_view_test.tx1 tx1_1 WHERE tx1.y1 = tx1_1.f1)); +-- Test aliasing of joins +create view view_of_joins as +select * from + (select * from (tbl1 cross join tbl2) same) ss, + (tbl3 cross join tbl4) same; +\d+ view_of_joins + View "testviewschm2.view_of_joins" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+---------+-----------+----------+---------+---------+------------- + a | integer | | | | plain | + b | integer | | | | plain | + c | integer | | | | plain | + d | integer | | | | plain | + e | integer | | | | plain | + f | integer | | | | plain | + g | integer | | | | plain | + h | integer | | | | plain | +View definition: + SELECT ss.a, + ss.b, + ss.c, + ss.d, + same.e, + same.f, + same.g, + same.h + FROM ( SELECT same_1.a, + same_1.b, + same_1.c, + same_1.d + FROM (tbl1 + CROSS JOIN tbl2) same_1) ss, + (tbl3 + CROSS JOIN tbl4) same; + -- Test view decompilation in the face of column addition/deletion/renaming create table tt2 (a int, b int, c int); create table tt3 (ax int8, b int2, c numeric); @@ -1707,8 +1752,97 @@ select pg_get_ruledef(oid, true) from pg_rewrite (1 row) -- clean up all the random objects we made above -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA temp_view_test CASCADE; NOTICE: drop cascades to 27 other objects +DETAIL: drop cascades to table temp_view_test.base_table +drop cascades to view v2_temp +drop cascades to view v4_temp +drop cascades to view v6_temp +drop cascades to view v7_temp +drop cascades to view v10_temp +drop cascades to view v8_temp +drop cascades to view v9_temp +drop cascades to view v11_temp +drop cascades to view v12_temp +drop cascades to table temp_view_test.base_table2 +drop cascades to view v5_temp +drop cascades to view temp_view_test.v1 +drop cascades to view temp_view_test.v2 +drop cascades to view temp_view_test.v3 +drop cascades to view temp_view_test.v4 +drop cascades to view temp_view_test.v5 +drop cascades to view temp_view_test.v6 +drop cascades to view temp_view_test.v7 +drop cascades to view temp_view_test.v8 +drop cascades to sequence temp_view_test.seq1 +drop cascades to view temp_view_test.v9 +drop cascades to table temp_view_test.tx1 +drop cascades to view aliased_view_1 +drop cascades to view aliased_view_2 +drop cascades to view aliased_view_3 +drop cascades to view aliased_view_4 DROP SCHEMA testviewschm2 CASCADE; -NOTICE: drop cascades to 62 other objects +NOTICE: drop cascades to 63 other objects +DETAIL: drop cascades to table t1 +drop cascades to view temporal1 +drop cascades to view temporal2 +drop cascades to view temporal3 +drop cascades to view temporal4 +drop cascades to table t2 +drop cascades to view nontemp1 +drop cascades to view nontemp2 +drop cascades to view nontemp3 +drop cascades to view nontemp4 +drop cascades to table tbl1 +drop cascades to table tbl2 +drop cascades to table tbl3 +drop cascades to table tbl4 +drop cascades to view mytempview +drop cascades to view pubview +drop cascades to view mysecview1 +drop cascades to view mysecview2 +drop cascades to view mysecview3 +drop cascades to view mysecview4 +drop cascades to view unspecified_types +drop cascades to table tt1 +drop cascades to table tx1 +drop cascades to view view_of_joins +drop cascades to table tt2 +drop cascades to table tt3 +drop cascades to table tt4 +drop cascades to view v1 +drop cascades to view v1a +drop cascades to view v2 +drop cascades to view v2a +drop cascades to view v3 +drop cascades to table tt5 +drop cascades to table tt6 +drop cascades to view vv1 +drop cascades to table tt7 +drop cascades to table tt8 +drop cascades to view vv2 +drop cascades to view vv3 +drop cascades to view vv4 +drop cascades to table tt7a +drop cascades to table tt8a +drop cascades to view vv2a +drop cascades to table tt9 +drop cascades to table tt10 +drop cascades to view vv5 +drop cascades to table tt11 +drop cascades to table tt12 +drop cascades to table tt13 +drop cascades to view vv6 +drop cascades to table tt14t +drop cascades to function tt14f() +drop cascades to view tt14v +drop cascades to type nestedcomposite +drop cascades to view tt15v +drop cascades to view tt16v +drop cascades to view tt17v +drop cascades to view tt18v +drop cascades to view tt19v +drop cascades to view tt20v +drop cascades to view tt21v +drop cascades to view tt22v +drop cascades to view tt23v diff --git a/src/test/regress/expected/date.out b/src/test/regress/expected/date.out index 1bcc9465a93..4686d0d8cab 100644 --- a/src/test/regress/expected/date.out +++ b/src/test/regress/expected/date.out @@ -1444,9 +1444,6 @@ SELECT EXTRACT(EPOCH FROM DATE 'infinity'); -- Infinity SELECT EXTRACT(MICROSEC FROM DATE 'infinity'); -- ERROR: timestamp units "microsec" not recognized ERROR: timestamp units "microsec" not recognized CONTEXT: SQL function "date_part" statement 1 -SELECT EXTRACT(UNDEFINED FROM DATE 'infinity'); -- ERROR: timestamp units "undefined" not supported -ERROR: timestamp units "undefined" not supported -CONTEXT: SQL function "date_part" statement 1 -- test constructors select make_date(2013, 7, 15); make_date diff --git a/src/test/regress/expected/dependency.out b/src/test/regress/expected/dependency.out index 8e50f8ffbb0..b4a11b8aa9b 100644 --- a/src/test/regress/expected/dependency.out +++ b/src/test/regress/expected/dependency.out @@ -128,14 +128,22 @@ FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t'; -- doesn't work: grant still exists DROP USER regress_dep_user1; ERROR: role "regress_dep_user1" cannot be dropped because some objects depend on it -DETAIL: owner of default privileges on new relations belonging to role regress_dep_user1 in schema deptest -privileges for database regression +DETAIL: privileges for database regression privileges for table deptest1 +owner of default privileges on new relations belonging to role regress_dep_user1 in schema deptest DROP OWNED BY regress_dep_user1; DROP USER regress_dep_user1; -\set VERBOSITY terse DROP USER regress_dep_user2; ERROR: role "regress_dep_user2" cannot be dropped because some objects depend on it +DETAIL: owner of schema deptest +owner of sequence deptest_a_seq +owner of table deptest +owner of function deptest_func() +owner of type deptest_enum +owner of type deptest_range +owner of table deptest2 +owner of sequence ss1 +owner of type deptest_t DROP OWNED BY regress_dep_user2, regress_dep_user0; DROP USER regress_dep_user2; DROP USER regress_dep_user0; diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index f4eebb75cf2..4ff1b4af418 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -298,8 +298,8 @@ ERROR: operator does not exist: character varying > double precision HINT: No operator matches the given name and argument types. You might need to add explicit type casts. alter type comptype alter attribute r type bigint; alter type comptype drop attribute r; -- fail -ERROR: cannot drop composite type comptype column r because other objects depend on it -DETAIL: constraint c1 depends on composite type comptype column r +ERROR: cannot drop column r of composite type comptype because other objects depend on it +DETAIL: constraint c1 depends on column r of composite type comptype HINT: Use DROP ... CASCADE to drop the dependent objects too. alter type comptype drop attribute i; select conname, obj_description(oid, 'pg_constraint') from pg_constraint @@ -645,8 +645,8 @@ alter domain dnotnulltest drop not null; update domnotnull set col1 = null; drop domain dnotnulltest cascade; NOTICE: drop cascades to 2 other objects -DETAIL: drop cascades to table domnotnull column col1 -drop cascades to table domnotnull column col2 +DETAIL: drop cascades to column col2 of table domnotnull +drop cascades to column col1 of table domnotnull -- Test ALTER DOMAIN .. DEFAULT .. create table domdeftest (col1 ddef1); insert into domdeftest default values; @@ -1019,6 +1019,31 @@ drop function array_elem_check(int); create domain di as int; create function dom_check(int) returns di as $$ declare d di; +begin + d := $1::di; + return d; +end +$$ language plpgsql immutable; +select dom_check(0); + dom_check +----------- + 0 +(1 row) + +alter domain di add constraint pos check (value > 0); +select dom_check(0); -- fail +ERROR: value for domain di violates check constraint "pos" +CONTEXT: PL/pgSQL function dom_check(integer) line 4 at assignment +alter domain di drop constraint pos; +select dom_check(0); + dom_check +----------- + 0 +(1 row) + +-- implicit cast during assignment is a separate code path, test that too +create or replace function dom_check(int) returns di as $$ +declare d di; begin d := $1; return d; diff --git a/src/test/regress/expected/drop_if_exists.out b/src/test/regress/expected/drop_if_exists.out index b80c5ed2d87..6a174677177 100644 --- a/src/test/regress/expected/drop_if_exists.out +++ b/src/test/regress/expected/drop_if_exists.out @@ -301,3 +301,32 @@ DROP TYPE IF EXISTS no_such_schema.foo; NOTICE: schema "no_such_schema" does not exist, skipping DROP VIEW IF EXISTS no_such_schema.foo; NOTICE: schema "no_such_schema" does not exist, skipping +-- Check we receive an ambiguous function error when there are +-- multiple matching functions. +CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql; +CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql; +DROP FUNCTION test_ambiguous_funcname; +ERROR: function name "test_ambiguous_funcname" is not unique +HINT: Specify the argument list to select the function unambiguously. +DROP FUNCTION IF EXISTS test_ambiguous_funcname; +ERROR: function name "test_ambiguous_funcname" is not unique +HINT: Specify the argument list to select the function unambiguously. +-- cleanup +DROP FUNCTION test_ambiguous_funcname(int); +DROP FUNCTION test_ambiguous_funcname(text); +-- Likewise for procedures. +CREATE PROCEDURE test_ambiguous_procname(int) as $$ begin end; $$ language plpgsql; +CREATE PROCEDURE test_ambiguous_procname(text) as $$ begin end; $$ language plpgsql; +DROP PROCEDURE test_ambiguous_procname; +ERROR: procedure name "test_ambiguous_procname" is not unique +HINT: Specify the argument list to select the procedure unambiguously. +DROP PROCEDURE IF EXISTS test_ambiguous_procname; +ERROR: procedure name "test_ambiguous_procname" is not unique +HINT: Specify the argument list to select the procedure unambiguously. +-- Check we get a similar error if we use ROUTINE instead of PROCEDURE. +DROP ROUTINE IF EXISTS test_ambiguous_procname; +ERROR: routine name "test_ambiguous_procname" is not unique +HINT: Specify the argument list to select the routine unambiguously. +-- cleanup +DROP PROCEDURE test_ambiguous_procname(int); +DROP PROCEDURE test_ambiguous_procname(text); diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out index a0b81608a1b..dffff88928e 100644 --- a/src/test/regress/expected/enum.out +++ b/src/test/regress/expected/enum.out @@ -581,19 +581,60 @@ ERROR: enum label "green" already exists -- check transactional behaviour of ALTER TYPE ... ADD VALUE -- CREATE TYPE bogus AS ENUM('good'); --- check that we can't add new values to existing enums in a transaction +-- check that we can add new values to existing enums in a transaction +-- but we can't use them BEGIN; -ALTER TYPE bogus ADD VALUE 'bad'; -ERROR: ALTER TYPE ... ADD cannot run inside a transaction block +ALTER TYPE bogus ADD VALUE 'new'; +SAVEPOINT x; +SELECT 'new'::bogus; -- unsafe +ERROR: unsafe use of new value "new" of enum type bogus +LINE 1: SELECT 'new'::bogus; + ^ +HINT: New enum values must be committed before they can be used. +ROLLBACK TO x; +SELECT enum_first(null::bogus); -- safe + enum_first +------------ + good +(1 row) + +SELECT enum_last(null::bogus); -- unsafe +ERROR: unsafe use of new value "new" of enum type bogus +HINT: New enum values must be committed before they can be used. +ROLLBACK TO x; +SELECT enum_range(null::bogus); -- unsafe +ERROR: unsafe use of new value "new" of enum type bogus +HINT: New enum values must be committed before they can be used. +ROLLBACK TO x; COMMIT; +SELECT 'new'::bogus; -- now safe + bogus +------- + new +(1 row) + +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'bogus'::regtype +ORDER BY 2; + enumlabel | enumsortorder +-----------+--------------- + good | 1 + new | 2 +(2 rows) + -- check that we recognize the case where the enum already existed but was --- modified in the current txn +-- modified in the current txn; this should not be considered safe BEGIN; ALTER TYPE bogus RENAME TO bogon; ALTER TYPE bogon ADD VALUE 'bad'; -ERROR: ALTER TYPE ... ADD cannot run inside a transaction block +SELECT 'bad'::bogon; +ERROR: unsafe use of new value "bad" of enum type bogon +LINE 1: SELECT 'bad'::bogon; + ^ +HINT: New enum values must be committed before they can be used. ROLLBACK; --- but ALTER TYPE RENAME VALUE is safe in a transaction +-- but a renamed value is safe to use later in same transaction BEGIN; ALTER TYPE bogus RENAME VALUE 'good' to 'bad'; SELECT 'bad'::bogus; @@ -604,12 +645,27 @@ SELECT 'bad'::bogus; ROLLBACK; DROP TYPE bogus; --- check that we *can* add new values to existing enums in a transaction, --- if the type is new as well +-- check that values created during CREATE TYPE can be used in any case +BEGIN; +CREATE TYPE bogus AS ENUM('good','bad','ugly'); +ALTER TYPE bogus RENAME TO bogon; +select enum_range(null::bogon); + enum_range +----------------- + {good,bad,ugly} +(1 row) + +ROLLBACK; +-- ideally, we'd allow this usage; but it requires keeping track of whether +-- the enum type was created in the current transaction, which is expensive BEGIN; -CREATE TYPE bogus AS ENUM(); -ALTER TYPE bogus ADD VALUE 'good'; -ALTER TYPE bogus ADD VALUE 'ugly'; +CREATE TYPE bogus AS ENUM('good'); +ALTER TYPE bogus RENAME TO bogon; +ALTER TYPE bogon ADD VALUE 'bad'; +ALTER TYPE bogon ADD VALUE 'ugly'; +select enum_range(null::bogon); -- fails +ERROR: unsafe use of new value "bad" of enum type bogon +HINT: New enum values must be committed before they can be used. ROLLBACK; -- -- Cleanup @@ -629,7 +685,7 @@ SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow'; SELECT * FROM pg_enum WHERE NOT EXISTS (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid); - enumtypid | enumsortorder | enumlabel ------------+---------------+----------- + oid | enumtypid | enumsortorder | enumlabel +-----+-----------+---------------+----------- (0 rows) diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out index ce473a03efd..7dd8a5b33e4 100644 --- a/src/test/regress/expected/errors.out +++ b/src/test/regress/expected/errors.out @@ -103,8 +103,8 @@ ERROR: column "nonesuchatt" does not exist alter table emp rename column salary to manager; ERROR: column "manager" of relation "stud_emp" already exists -- conflict -alter table emp rename column salary to oid; -ERROR: column name "oid" conflicts with a system column name +alter table emp rename column salary to ctid; +ERROR: column name "ctid" conflicts with a system column name -- -- TRANSACTION STUFF -- not in a xact diff --git a/src/test/regress/expected/event_trigger.out b/src/test/regress/expected/event_trigger.out index 008e859d4c2..788be86b33a 100644 --- a/src/test/regress/expected/event_trigger.out +++ b/src/test/regress/expected/event_trigger.out @@ -27,7 +27,7 @@ create event trigger regress_event_trigger on ddl_command_start execute procedure test_event_trigger(); -- OK create event trigger regress_event_trigger_end on ddl_command_end - execute procedure test_event_trigger(); + execute function test_event_trigger(); -- should fail, food is not a valid filter variable create event trigger regress_event_trigger2 on ddl_command_start when food in ('sandwich') @@ -112,10 +112,45 @@ create table event_trigger_fire5 (a int); NOTICE: test_event_trigger: ddl_command_start CREATE TABLE NOTICE: test_event_trigger: ddl_command_start CREATE TABLE NOTICE: test_event_trigger: ddl_command_end CREATE TABLE +-- non-top-level command +create function f1() returns int +language plpgsql +as $$ +begin + create table event_trigger_fire6 (a int); + return 0; +end $$; +NOTICE: test_event_trigger: ddl_command_start CREATE FUNCTION +NOTICE: test_event_trigger: ddl_command_start CREATE FUNCTION +NOTICE: test_event_trigger: ddl_command_end CREATE FUNCTION +select f1(); +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_end CREATE TABLE + f1 +---- + 0 +(1 row) + +-- non-top-level command +create procedure p1() +language plpgsql +as $$ +begin + create table event_trigger_fire7 (a int); +end $$; +NOTICE: test_event_trigger: ddl_command_start CREATE PROCEDURE +NOTICE: test_event_trigger: ddl_command_end CREATE PROCEDURE +call p1(); +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_start CREATE TABLE +NOTICE: test_event_trigger: ddl_command_end CREATE TABLE -- clean up alter event trigger regress_event_trigger disable; -drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5; +drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, event_trigger_fire6, event_trigger_fire7; NOTICE: test_event_trigger: ddl_command_end DROP TABLE +drop routine f1(), p1(); +NOTICE: test_event_trigger: ddl_command_end DROP ROUTINE -- regress_event_trigger_end should fire on these commands grant all on table event_trigger_fire1 to public; NOTICE: test_event_trigger: ddl_command_end GRANT @@ -153,8 +188,8 @@ ERROR: event trigger "regress_event_trigger" does not exist drop role regress_evt_user; ERROR: role "regress_evt_user" cannot be dropped because some objects depend on it DETAIL: owner of event trigger regress_event_trigger3 -owner of default privileges on new relations belonging to role regress_evt_user owner of user mapping for regress_evt_user on server useless_server +owner of default privileges on new relations belonging to role regress_evt_user -- cleanup before next test -- these are all OK; the second one should emit a NOTICE drop event trigger if exists regress_event_trigger2; @@ -349,6 +384,18 @@ CREATE SCHEMA evttrig CREATE TABLE one (col_a SERIAL PRIMARY KEY, col_b text DEFAULT 'forty two') CREATE INDEX one_idx ON one (col_b) CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42); +-- Partitioned tables with a partitioned index +CREATE TABLE evttrig.parted ( + id int PRIMARY KEY) + PARTITION BY RANGE (id); +CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (1) TO (10); +CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id); +CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (10) TO (15); +CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (15) TO (20); ALTER TABLE evttrig.two DROP COLUMN col_c; NOTICE: NORMAL: orig=t normal=f istemp=f type=table column identity=evttrig.two.col_c name={evttrig,two,col_c} args={} NOTICE: NORMAL: orig=f normal=t istemp=f type=table constraint identity=two_col_c_check on evttrig.two name={evttrig,two,two_col_c_check} args={} @@ -359,14 +406,20 @@ NOTICE: NORMAL: orig=t normal=f istemp=f type=table constraint identity=one_pke DROP INDEX evttrig.one_idx; NOTICE: NORMAL: orig=t normal=f istemp=f type=index identity=evttrig.one_idx name={evttrig,one_idx} args={} DROP SCHEMA evttrig CASCADE; -NOTICE: drop cascades to 2 other objects +NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table evttrig.one drop cascades to table evttrig.two +drop cascades to table evttrig.parted NOTICE: NORMAL: orig=t normal=f istemp=f type=schema identity=evttrig name={evttrig} args={} NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.one name={evttrig,one} args={} NOTICE: NORMAL: orig=f normal=t istemp=f type=sequence identity=evttrig.one_col_a_seq name={evttrig,one_col_a_seq} args={} NOTICE: NORMAL: orig=f normal=t istemp=f type=default value identity=for evttrig.one.col_a name={evttrig,one,col_a} args={} NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.two name={evttrig,two} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.parted name={evttrig,parted} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_1_10 name={evttrig,part_1_10} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_10_20 name={evttrig,part_10_20} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_10_15 name={evttrig,part_10_15} args={} +NOTICE: NORMAL: orig=f normal=t istemp=f type=table identity=evttrig.part_15_20 name={evttrig,part_15_20} args={} DROP TABLE a_temp_tbl; NOTICE: NORMAL: orig=t normal=f istemp=t type=table identity=pg_temp.a_temp_tbl name={pg_temp,a_temp_tbl} args={} DROP EVENT TRIGGER regress_event_trigger_report_dropped; @@ -382,7 +435,7 @@ END; $$; create event trigger no_rewrite_allowed on table_rewrite execute procedure test_evtrig_no_rewrite(); -create table rewriteme (id serial primary key, foo float); +create table rewriteme (id serial primary key, foo float, bar timestamptz); insert into rewriteme select x * 1.001 from generate_series(1, 500) as t(x); alter table rewriteme alter column foo type numeric; @@ -405,6 +458,15 @@ alter table rewriteme NOTICE: Table 'rewriteme' is being rewritten (reason = 4) -- shouldn't trigger a table_rewrite event alter table rewriteme alter column foo type numeric(12,4); +begin; +set timezone to 'UTC'; +alter table rewriteme alter column bar type timestamp; +set timezone to '0'; +alter table rewriteme alter column bar type timestamptz; +set timezone to 'Europe/London'; +alter table rewriteme alter column bar type timestamp; -- does rewrite +NOTICE: Table 'rewriteme' is being rewritten (reason = 4) +rollback; -- typed tables are rewritten when their type changes. Don't emit table -- name, because firing order is not stable. CREATE OR REPLACE FUNCTION test_evtrig_no_rewrite() RETURNS event_trigger diff --git a/src/test/regress/expected/expressions.out b/src/test/regress/expected/expressions.out index 719455b0ebb..4f4deaec223 100644 --- a/src/test/regress/expected/expressions.out +++ b/src/test/regress/expected/expressions.out @@ -1,5 +1,5 @@ -- --- expression evaluated tests that don't fit into a more specific file +-- expression evaluation tests that don't fit into a more specific file -- -- -- Tests for SQLVAlueFunction @@ -18,12 +18,24 @@ SELECT now()::timetz::text = current_time::text; t (1 row) +SELECT now()::timetz(4)::text = current_time(4)::text; + ?column? +---------- + t +(1 row) + SELECT now()::time::text = localtime::text; ?column? ---------- t (1 row) +SELECT now()::time(3)::text = localtime(3)::text; + ?column? +---------- + t +(1 row) + -- current_timestamp / localtimestamp (always matches because of transactional behaviour) SELECT current_timestamp = NOW(); ?column? @@ -75,3 +87,74 @@ SELECT current_schema; (1 row) RESET search_path; +-- +-- Tests for BETWEEN +-- +explain (costs off) +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; + QUERY PLAN +----------------------------------------------------------------------------- + Aggregate + -> Seq Scan on date_tbl + Filter: ((f1 >= '01-01-1997'::date) AND (f1 <= '01-01-1998'::date)) +(3 rows) + +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; + count +------- + 3 +(1 row) + +explain (costs off) +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; + QUERY PLAN +-------------------------------------------------------------------------- + Aggregate + -> Seq Scan on date_tbl + Filter: ((f1 < '01-01-1997'::date) OR (f1 > '01-01-1998'::date)) +(3 rows) + +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; + count +------- + 12 +(1 row) + +explain (costs off) +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Seq Scan on date_tbl + Filter: (((f1 >= '01-01-1997'::date) AND (f1 <= '01-01-1998'::date)) OR ((f1 >= '01-01-1998'::date) AND (f1 <= '01-01-1997'::date))) +(3 rows) + +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; + count +------- + 3 +(1 row) + +explain (costs off) +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + -> Seq Scan on date_tbl + Filter: (((f1 < '01-01-1997'::date) OR (f1 > '01-01-1998'::date)) AND ((f1 < '01-01-1998'::date) OR (f1 > '01-01-1997'::date))) +(3 rows) + +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; + count +------- + 12 +(1 row) + diff --git a/src/test/regress/expected/fast_default.out b/src/test/regress/expected/fast_default.out index 3568fa7b8a9..10bc5ff757c 100644 --- a/src/test/regress/expected/fast_default.out +++ b/src/test/regress/expected/fast_default.out @@ -505,7 +505,305 @@ SELECT comp(); Unchanged (1 row) +-- query to exercise expand_tuple function +CREATE TABLE t1 AS +SELECT 1::int AS a , 2::int AS b +FROM generate_series(1,20) q; +ALTER TABLE t1 ADD COLUMN c text; +SELECT a, + stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4)) + OVER (PARTITION BY a,b,c ORDER BY b) + AS z +FROM t1; + a | z +---+--- + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 + 1 | 0 +(20 rows) + DROP TABLE T; +-- test that we account for missing columns without defaults correctly +-- in expand_tuple, and that rows are correctly expanded for triggers +CREATE FUNCTION test_trigger() +RETURNS trigger +LANGUAGE plpgsql +AS $$ + +begin + raise notice 'old tuple: %', to_json(OLD)::text; + if TG_OP = 'DELETE' + then + return OLD; + else + return NEW; + end if; +end; + +$$; +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | 4 | 5 +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":4,"y":5} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | 4 | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | 4 | +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":4,"y":null} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | 4 | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | | 5 +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":null,"y":5} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | | +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":3,"x":null,"y":null} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | 3 | | 2 +(1 row) + +DROP TABLE t; +-- same as last 4 tests but here the last original column has a NULL value +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | 4 | 5 +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":4,"y":5} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | 4 | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | 4 | +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":4,"y":null} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | 4 | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | | 5 +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":null,"y":5} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | | 2 +(1 row) + +DROP TABLE t; +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | | +(1 row) + +UPDATE t SET y = 2; +NOTICE: old tuple: {"id":1,"a":1,"b":2,"c":null,"x":null,"y":null} +SELECT * FROM t; + id | a | b | c | x | y +----+---+---+---+---+--- + 1 | 1 | 2 | | | 2 +(1 row) + +DROP TABLE t; +-- make sure expanded tuple has correct self pointer +-- it will be required by the RI trigger doing the cascading delete +CREATE TABLE leader (a int PRIMARY KEY, b int); +CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int); +INSERT INTO leader VALUES (1, 1), (2, 2); +ALTER TABLE leader ADD c int; +ALTER TABLE leader DROP c; +DELETE FROM leader; +-- check that ALTER TABLE ... ALTER TYPE does the right thing +CREATE TABLE vtype( a integer); +INSERT INTO vtype VALUES (1); +ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2; +ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true; +SELECT * FROM vtype; + a | b | c +---+-----+--- + 1 | 0.2 | t +(1 row) + +ALTER TABLE vtype + ALTER b TYPE text USING b::text, + ALTER c TYPE text USING c::text; +NOTICE: rewriting table vtype for reason 4 +SELECT * FROM vtype; + a | b | c +---+-----+------ + 1 | 0.2 | true +(1 row) + +-- also check the case that doesn't rewrite the table +CREATE TABLE vtype2 (a int); +INSERT INTO vtype2 VALUES (1); +ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx'; +ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy'; +INSERT INTO vtype2 VALUES (2); +ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20); +SELECT * FROM vtype2; + a | b +---+----- + 1 | xxx + 2 | yyy +(2 rows) + +-- Ensure that defaults are checked when evaluating whether HOT update +-- is possible, this was broken for a while: +-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de +BEGIN; +CREATE TABLE t(); +INSERT INTO t DEFAULT VALUES; +ALTER TABLE t ADD COLUMN a int DEFAULT 1; +CREATE INDEX ON t(a); +-- set column with a default 1 to NULL, due to a bug that wasn't +-- noticed has heap_getattr buggily returned NULL for default columns +UPDATE t SET a = NULL; +-- verify that index and non-index scans show the same result +SET LOCAL enable_seqscan = true; +SELECT * FROM t WHERE a IS NULL; + a +--- + +(1 row) + +SET LOCAL enable_seqscan = false; +SELECT * FROM t WHERE a IS NULL; + a +--- + +(1 row) + +ROLLBACK; +-- cleanup +DROP TABLE vtype; +DROP TABLE vtype2; +DROP TABLE follower; +DROP TABLE leader; +DROP FUNCTION test_trigger(); +DROP TABLE t1; DROP FUNCTION set(name); DROP FUNCTION comp(); DROP TABLE m; @@ -513,3 +811,14 @@ DROP TABLE has_volatile; DROP EVENT TRIGGER has_volatile_rewrite; DROP FUNCTION log_rewrite; DROP SCHEMA fast_default; +-- Leave a table with an active fast default in place, for pg_upgrade testing +set search_path = public; +create table has_fast_default(f1 int); +insert into has_fast_default values(1); +alter table has_fast_default add column f2 int default 42; +table has_fast_default; + f1 | f2 +----+---- + 1 | 42 +(1 row) + diff --git a/src/test/regress/expected/float4-exp-three-digits.out b/src/test/regress/expected/float4-exp-three-digits.out deleted file mode 100644 index f17f95697a2..00000000000 --- a/src/test/regress/expected/float4-exp-three-digits.out +++ /dev/null @@ -1,259 +0,0 @@ --- --- FLOAT4 --- -CREATE TABLE FLOAT4_TBL (f1 float4); -INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0'); -INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 '); -INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 '); -INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20'); -INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20'); --- test for over and under flow -INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); -ERROR: value out of range: overflow -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); -ERROR: value out of range: overflow -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); -ERROR: value out of range: underflow -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); -ERROR: value out of range: underflow -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); - ^ --- bad input -INSERT INTO FLOAT4_TBL(f1) VALUES (''); -ERROR: invalid input syntax for type real: "" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (''); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for type real: " " -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' '); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz'); -ERROR: invalid input syntax for type real: "xyz" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0'); -ERROR: invalid input syntax for type real: "5.0.0" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0'); -ERROR: invalid input syntax for type real: "5 . 0" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0'); -ERROR: invalid input syntax for type real: "5. 0" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0'); -ERROR: invalid input syntax for type real: " - 3.0" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0'); - ^ -INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); -ERROR: invalid input syntax for type real: "123 5" -LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); - ^ --- special inputs -SELECT 'NaN'::float4; - float4 --------- - NaN -(1 row) - -SELECT 'nan'::float4; - float4 --------- - NaN -(1 row) - -SELECT ' NAN '::float4; - float4 --------- - NaN -(1 row) - -SELECT 'infinity'::float4; - float4 ----------- - Infinity -(1 row) - -SELECT ' -INFINiTY '::float4; - float4 ------------ - -Infinity -(1 row) - --- bad special inputs -SELECT 'N A N'::float4; -ERROR: invalid input syntax for type real: "N A N" -LINE 1: SELECT 'N A N'::float4; - ^ -SELECT 'NaN x'::float4; -ERROR: invalid input syntax for type real: "NaN x" -LINE 1: SELECT 'NaN x'::float4; - ^ -SELECT ' INFINITY x'::float4; -ERROR: invalid input syntax for type real: " INFINITY x" -LINE 1: SELECT ' INFINITY x'::float4; - ^ -SELECT 'Infinity'::float4 + 100.0; - ?column? ----------- - Infinity -(1 row) - -SELECT 'Infinity'::float4 / 'Infinity'::float4; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::float4 / 'nan'::float4; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::numeric::float4; - float4 --------- - NaN -(1 row) - -SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+-------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e+020 - | 1.23457e-020 -(5 rows) - -SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3'; - four | f1 -------+-------------- - | 0 - | -34.84 - | 1.23457e+020 - | 1.23457e-020 -(4 rows) - -SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3'; - one | f1 ------+-------- - | 1004.3 -(1 row) - -SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1; - three | f1 --------+-------------- - | 0 - | -34.84 - | 1.23457e-020 -(3 rows) - -SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3'; - three | f1 --------+-------------- - | 0 - | -34.84 - | 1.23457e-020 -(3 rows) - -SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1; - four | f1 -------+-------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e-020 -(4 rows) - -SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3'; - four | f1 -------+-------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e-020 -(4 rows) - -SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+--------------+--------------- - | 1004.3 | -10043 - | 1.23457e+020 | -1.23457e+021 - | 1.23457e-020 | -1.23457e-019 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+--------------+-------------- - | 1004.3 | 994.3 - | 1.23457e+020 | 1.23457e+020 - | 1.23457e-020 | -10 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+--------------+--------------- - | 1004.3 | -100.43 - | 1.23457e+020 | -1.23457e+019 - | 1.23457e-020 | -1.23457e-021 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+--------------+-------------- - | 1004.3 | 1014.3 - | 1.23457e+020 | 1.23457e+020 - | 1.23457e-020 | 10 -(3 rows) - --- test divide by zero -SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f; -ERROR: division by zero -SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+-------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e+020 - | 1.23457e-020 -(5 rows) - --- test the unary float4abs operator -SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f; - five | f1 | abs_f1 -------+--------------+-------------- - | 0 | 0 - | 1004.3 | 1004.3 - | -34.84 | 34.84 - | 1.23457e+020 | 1.23457e+020 - | 1.23457e-020 | 1.23457e-020 -(5 rows) - -UPDATE FLOAT4_TBL - SET f1 = FLOAT4_TBL.f1 * '-1' - WHERE FLOAT4_TBL.f1 > '0.0'; -SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+--------------- - | 0 - | -34.84 - | -1004.3 - | -1.23457e+020 - | -1.23457e-020 -(5 rows) - diff --git a/src/test/regress/expected/float4-misrounded-input.out b/src/test/regress/expected/float4-misrounded-input.out new file mode 100644 index 00000000000..6c89af6394f --- /dev/null +++ b/src/test/regress/expected/float4-misrounded-input.out @@ -0,0 +1,949 @@ +-- +-- FLOAT4 +-- +CREATE TABLE FLOAT4_TBL (f1 float4); +INSERT INTO FLOAT4_TBL(f1) VALUES (' 0.0'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('1004.30 '); +INSERT INTO FLOAT4_TBL(f1) VALUES (' -34.84 '); +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20'); +-- test for over and under flow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); +ERROR: "10e70" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); +ERROR: "-10e70" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); +ERROR: "10e-70" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); +ERROR: "-10e-70" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8); +ERROR: value out of range: overflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8); +ERROR: value out of range: overflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8); +ERROR: value out of range: underflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8); +ERROR: value out of range: underflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); +ERROR: "10e400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); +ERROR: "-10e400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); +ERROR: "10e-400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); +ERROR: "-10e-400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); + ^ +-- bad input +INSERT INTO FLOAT4_TBL(f1) VALUES (''); +ERROR: invalid input syntax for type real: "" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (''); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES (' '); +ERROR: invalid input syntax for type real: " " +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' '); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz'); +ERROR: invalid input syntax for type real: "xyz" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('xyz'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0'); +ERROR: invalid input syntax for type real: "5.0.0" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5.0.0'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0'); +ERROR: invalid input syntax for type real: "5 . 0" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5 . 0'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0'); +ERROR: invalid input syntax for type real: "5. 0" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('5. 0'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0'); +ERROR: invalid input syntax for type real: " - 3.0" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES (' - 3.0'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); +ERROR: invalid input syntax for type real: "123 5" +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('123 5'); + ^ +-- special inputs +SELECT 'NaN'::float4; + float4 +-------- + NaN +(1 row) + +SELECT 'nan'::float4; + float4 +-------- + NaN +(1 row) + +SELECT ' NAN '::float4; + float4 +-------- + NaN +(1 row) + +SELECT 'infinity'::float4; + float4 +---------- + Infinity +(1 row) + +SELECT ' -INFINiTY '::float4; + float4 +----------- + -Infinity +(1 row) + +-- bad special inputs +SELECT 'N A N'::float4; +ERROR: invalid input syntax for type real: "N A N" +LINE 1: SELECT 'N A N'::float4; + ^ +SELECT 'NaN x'::float4; +ERROR: invalid input syntax for type real: "NaN x" +LINE 1: SELECT 'NaN x'::float4; + ^ +SELECT ' INFINITY x'::float4; +ERROR: invalid input syntax for type real: " INFINITY x" +LINE 1: SELECT ' INFINITY x'::float4; + ^ +SELECT 'Infinity'::float4 + 100.0; + ?column? +---------- + Infinity +(1 row) + +SELECT 'Infinity'::float4 / 'Infinity'::float4; + ?column? +---------- + NaN +(1 row) + +SELECT 'nan'::float4 / 'nan'::float4; + ?column? +---------- + NaN +(1 row) + +SELECT 'nan'::numeric::float4; + float4 +-------- + NaN +(1 row) + +SELECT '' AS five, * FROM FLOAT4_TBL; + five | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 +(5 rows) + +SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3'; + four | f1 +------+--------------- + | 0 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 +(4 rows) + +SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3'; + one | f1 +-----+-------- + | 1004.3 +(1 row) + +SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1; + three | f1 +-------+--------------- + | 0 + | -34.84 + | 1.2345679e-20 +(3 rows) + +SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3'; + three | f1 +-------+--------------- + | 0 + | -34.84 + | 1.2345679e-20 +(3 rows) + +SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1; + four | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e-20 +(4 rows) + +SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3'; + four | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e-20 +(4 rows) + +SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + three | f1 | x +-------+---------------+---------------- + | 1004.3 | -10043 + | 1.2345679e+20 | -1.2345678e+21 + | 1.2345679e-20 | -1.2345678e-19 +(3 rows) + +SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + three | f1 | x +-------+---------------+--------------- + | 1004.3 | 994.3 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | -10 +(3 rows) + +SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + three | f1 | x +-------+---------------+---------------- + | 1004.3 | -100.43 + | 1.2345679e+20 | -1.2345679e+19 + | 1.2345679e-20 | -1.2345679e-21 +(3 rows) + +SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f + WHERE f.f1 > '0.0'; + three | f1 | x +-------+---------------+--------------- + | 1004.3 | 1014.3 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | 10 +(3 rows) + +-- test divide by zero +SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f; +ERROR: division by zero +SELECT '' AS five, * FROM FLOAT4_TBL; + five | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 +(5 rows) + +-- test the unary float4abs operator +SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f; + five | f1 | abs_f1 +------+---------------+--------------- + | 0 | 0 + | 1004.3 | 1004.3 + | -34.84 | 34.84 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | 1.2345679e-20 +(5 rows) + +UPDATE FLOAT4_TBL + SET f1 = FLOAT4_TBL.f1 * '-1' + WHERE FLOAT4_TBL.f1 > '0.0'; +SELECT '' AS five, * FROM FLOAT4_TBL; + five | f1 +------+---------------- + | 0 + | -34.84 + | -1004.3 + | -1.2345679e+20 + | -1.2345679e-20 +(5 rows) + +-- test edge-case coercions to integer +SELECT '32767.4'::float4::int2; + int2 +------- + 32767 +(1 row) + +SELECT '32767.6'::float4::int2; +ERROR: smallint out of range +SELECT '-32768.4'::float4::int2; + int2 +-------- + -32768 +(1 row) + +SELECT '-32768.6'::float4::int2; +ERROR: smallint out of range +SELECT '2147483520'::float4::int4; + int4 +------------ + 2147483520 +(1 row) + +SELECT '2147483647'::float4::int4; +ERROR: integer out of range +SELECT '-2147483648.5'::float4::int4; + int4 +------------- + -2147483648 +(1 row) + +SELECT '-2147483900'::float4::int4; +ERROR: integer out of range +SELECT '9223369837831520256'::float4::int8; + int8 +--------------------- + 9223369837831520256 +(1 row) + +SELECT '9223372036854775807'::float4::int8; +ERROR: bigint out of range +SELECT '-9223372036854775808.5'::float4::int8; + int8 +---------------------- + -9223372036854775808 +(1 row) + +SELECT '-9223380000000000000'::float4::int8; +ERROR: bigint out of range +-- Test for correct input rounding in edge cases. +-- These lists are from Paxson 1991, excluding subnormals and +-- inputs of over 9 sig. digits. +SELECT float4send('5e-20'::float4); + float4send +------------ + \x1f6c1e4a +(1 row) + +SELECT float4send('67e14'::float4); + float4send +------------ + \x59be6cea +(1 row) + +SELECT float4send('985e15'::float4); + float4send +------------ + \x5d5ab6c4 +(1 row) + +SELECT float4send('55895e-16'::float4); + float4send +------------ + \x2cc4a9bd +(1 row) + +SELECT float4send('7038531e-32'::float4); + float4send +------------ + \x15ae43fe +(1 row) + +SELECT float4send('702990899e-20'::float4); + float4send +------------ + \x2cf757ca +(1 row) + +SELECT float4send('3e-23'::float4); + float4send +------------ + \x1a111234 +(1 row) + +SELECT float4send('57e18'::float4); + float4send +------------ + \x6045c22c +(1 row) + +SELECT float4send('789e-35'::float4); + float4send +------------ + \x0a23de70 +(1 row) + +SELECT float4send('2539e-18'::float4); + float4send +------------ + \x2736f449 +(1 row) + +SELECT float4send('76173e28'::float4); + float4send +------------ + \x7616398a +(1 row) + +SELECT float4send('887745e-11'::float4); + float4send +------------ + \x3714f05c +(1 row) + +SELECT float4send('5382571e-37'::float4); + float4send +------------ + \x0d2eaca7 +(1 row) + +SELECT float4send('82381273e-35'::float4); + float4send +------------ + \x128289d0 +(1 row) + +SELECT float4send('750486563e-38'::float4); + float4send +------------ + \x0f18377e +(1 row) + +-- Test that the smallest possible normalized input value inputs +-- correctly, either in 9-significant-digit or shortest-decimal +-- format. +-- +-- exact val is 1.1754943508... +-- shortest val is 1.1754944000 +-- midpoint to next val is 1.1754944208... +SELECT float4send('1.17549435e-38'::float4); + float4send +------------ + \x00800000 +(1 row) + +SELECT float4send('1.1754944e-38'::float4); + float4send +------------ + \x00800000 +(1 row) + +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). +create type xfloat4; +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in'; +NOTICE: return type xfloat4 is only a shell +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out'; +NOTICE: argument type xfloat4 is only a shell +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4); +create cast (xfloat4 as float4) without function; +create cast (float4 as xfloat4) without function; +create cast (xfloat4 as integer) without function; +create cast (integer as xfloat4) without function; +-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + ibits | flt +------------+--------------- + \x00000001 | 1e-45 + \x00000002 | 3e-45 + \x00000003 | 4e-45 + \x00000010 | 2.2e-44 + \x00000011 | 2.4e-44 + \x00000100 | 3.59e-43 + \x00000101 | 3.6e-43 + \x00004000 | 2.2959e-41 + \x00004001 | 2.296e-41 + \x00080000 | 7.34684e-40 + \x00080001 | 7.34685e-40 + \x0053c4f4 | 7.693e-39 + \x006c85c4 | 9.96622e-39 + \x0041ca76 | 6.041937e-39 + \x004b7678 | 6.930161e-39 + \x00000007 | 1e-44 + \x00424fe2 | 6.0898e-39 + \x007ffff0 | 1.1754921e-38 + \x007ffff1 | 1.1754922e-38 + \x007ffffe | 1.1754941e-38 + \x007fffff | 1.1754942e-38 +(21 rows) + +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + ibits | flt | r_flt | obits | correct +------------+----------------+----------------+------------+--------- + \x00000000 | 0 | 0 | \x00000000 | t + \x00800000 | 1.1754944e-38 | 1.1754944e-38 | \x00800000 | t + \x00800001 | 1.1754945e-38 | 1.1754945e-38 | \x00800001 | t + \x00800004 | 1.1754949e-38 | 1.1754949e-38 | \x00800004 | t + \x00800005 | 1.175495e-38 | 1.175495e-38 | \x00800005 | t + \x00800006 | 1.1754952e-38 | 1.1754952e-38 | \x00800006 | t + \x008002f1 | 1.1755999e-38 | 1.1755999e-38 | \x008002f1 | t + \x008002f2 | 1.1756e-38 | 1.1756e-38 | \x008002f2 | t + \x008002f3 | 1.1756001e-38 | 1.1756001e-38 | \x008002f3 | t + \x00800e17 | 1.1759998e-38 | 1.1759998e-38 | \x00800e17 | t + \x00800e18 | 1.176e-38 | 1.176e-38 | \x00800e18 | t + \x00800e19 | 1.1760001e-38 | 1.1760001e-38 | \x00800e19 | t + \x01000001 | 2.350989e-38 | 2.350989e-38 | \x01000001 | t + \x01102843 | 2.647751e-38 | 2.647751e-38 | \x01102843 | t + \x01a52c98 | 6.0675416e-38 | 6.0675416e-38 | \x01a52c98 | t + \x0219c229 | 1.1296386e-37 | 1.1296386e-37 | \x0219c229 | t + \x02e4464d | 3.354194e-37 | 3.354194e-37 | \x02e4464d | t + \x037343c1 | 7.148906e-37 | 7.148906e-37 | \x037343c1 | t + \x03a91b36 | 9.939175e-37 | 9.939175e-37 | \x03a91b36 | t + \x047ada65 | 2.948764e-36 | 2.948764e-36 | \x047ada65 | t + \x0496fe87 | 3.5498577e-36 | 3.5498577e-36 | \x0496fe87 | t + \x0550844f | 9.804414e-36 | 9.804414e-36 | \x0550844f | t + \x05999da3 | 1.4445957e-35 | 1.4445957e-35 | \x05999da3 | t + \x060ea5e2 | 2.6829103e-35 | 2.6829103e-35 | \x060ea5e2 | t + \x06e63c45 | 8.660494e-35 | 8.660494e-35 | \x06e63c45 | t + \x07f1e548 | 3.639641e-34 | 3.639641e-34 | \x07f1e548 | t + \x0fc5282b | 1.9441172e-29 | 1.9441172e-29 | \x0fc5282b | t + \x1f850283 | 5.6331846e-20 | 5.6331846e-20 | \x1f850283 | t + \x2874a9d6 | 1.3581548e-14 | 1.3581548e-14 | \x2874a9d6 | t + \x3356bf94 | 4.9999997e-08 | 4.9999997e-08 | \x3356bf94 | t + \x3356bf95 | 5e-08 | 5e-08 | \x3356bf95 | t + \x3356bf96 | 5.0000004e-08 | 5.0000004e-08 | \x3356bf96 | t + \x33d6bf94 | 9.9999994e-08 | 9.9999994e-08 | \x33d6bf94 | t + \x33d6bf95 | 1e-07 | 1e-07 | \x33d6bf95 | t + \x33d6bf96 | 1.0000001e-07 | 1.0000001e-07 | \x33d6bf96 | t + \x34a10faf | 2.9999998e-07 | 2.9999998e-07 | \x34a10faf | t + \x34a10fb0 | 3e-07 | 3e-07 | \x34a10fb0 | t + \x34a10fb1 | 3.0000004e-07 | 3.0000004e-07 | \x34a10fb1 | t + \x350637bc | 4.9999994e-07 | 4.9999994e-07 | \x350637bc | t + \x350637bd | 5e-07 | 5e-07 | \x350637bd | t + \x350637be | 5.0000006e-07 | 5.0000006e-07 | \x350637be | t + \x35719786 | 8.999999e-07 | 8.999999e-07 | \x35719786 | t + \x35719787 | 9e-07 | 9e-07 | \x35719787 | t + \x35719788 | 9.0000003e-07 | 9.0000003e-07 | \x35719788 | t + \x358637bc | 9.999999e-07 | 9.999999e-07 | \x358637bc | t + \x358637bd | 1e-06 | 1e-06 | \x358637bd | t + \x358637be | 1.0000001e-06 | 1.0000001e-06 | \x358637be | t + \x36a7c5ab | 4.9999994e-06 | 4.9999994e-06 | \x36a7c5ab | t + \x36a7c5ac | 5e-06 | 5e-06 | \x36a7c5ac | t + \x36a7c5ad | 5.0000003e-06 | 5.0000003e-06 | \x36a7c5ad | t + \x3727c5ab | 9.999999e-06 | 9.999999e-06 | \x3727c5ab | t + \x3727c5ac | 1e-05 | 1e-05 | \x3727c5ac | t + \x3727c5ad | 1.0000001e-05 | 1.0000001e-05 | \x3727c5ad | t + \x38d1b714 | 9.9999976e-05 | 9.9999976e-05 | \x38d1b714 | t + \x38d1b715 | 9.999998e-05 | 9.999998e-05 | \x38d1b715 | t + \x38d1b716 | 9.999999e-05 | 9.999999e-05 | \x38d1b716 | t + \x38d1b717 | 0.0001 | 0.0001 | \x38d1b717 | t + \x38d1b718 | 0.000100000005 | 0.000100000005 | \x38d1b718 | t + \x38d1b719 | 0.00010000001 | 0.00010000001 | \x38d1b719 | t + \x38d1b71a | 0.00010000002 | 0.00010000002 | \x38d1b71a | t + \x38d1b71b | 0.00010000003 | 0.00010000003 | \x38d1b71b | t + \x38d1b71c | 0.000100000034 | 0.000100000034 | \x38d1b71c | t + \x38d1b71d | 0.00010000004 | 0.00010000004 | \x38d1b71d | t + \x38dffffe | 0.00010681151 | 0.00010681151 | \x38dffffe | t + \x38dfffff | 0.000106811516 | 0.000106811516 | \x38dfffff | t + \x38e00000 | 0.00010681152 | 0.00010681152 | \x38e00000 | t + \x38efffff | 0.00011444091 | 0.00011444091 | \x38efffff | t + \x38f00000 | 0.00011444092 | 0.00011444092 | \x38f00000 | t + \x38f00001 | 0.000114440925 | 0.000114440925 | \x38f00001 | t + \x3a83126e | 0.0009999999 | 0.0009999999 | \x3a83126e | t + \x3a83126f | 0.001 | 0.001 | \x3a83126f | t + \x3a831270 | 0.0010000002 | 0.0010000002 | \x3a831270 | t + \x3c23d709 | 0.009999999 | 0.009999999 | \x3c23d709 | t + \x3c23d70a | 0.01 | 0.01 | \x3c23d70a | t + \x3c23d70b | 0.010000001 | 0.010000001 | \x3c23d70b | t + \x3dcccccc | 0.099999994 | 0.099999994 | \x3dcccccc | t + \x3dcccccd | 0.1 | 0.1 | \x3dcccccd | t + \x3dccccce | 0.10000001 | 0.10000001 | \x3dccccce | t + \x3dcccd6f | 0.10000121 | 0.10000121 | \x3dcccd6f | t + \x3dcccd70 | 0.100001216 | 0.100001216 | \x3dcccd70 | t + \x3dcccd71 | 0.10000122 | 0.10000122 | \x3dcccd71 | t + \x3effffff | 0.49999997 | 0.49999997 | \x3effffff | t + \x3f000000 | 0.5 | 0.5 | \x3f000000 | t + \x3f000001 | 0.50000006 | 0.50000006 | \x3f000001 | t + \x3f333332 | 0.6999999 | 0.6999999 | \x3f333332 | t + \x3f333333 | 0.7 | 0.7 | \x3f333333 | t + \x3f333334 | 0.70000005 | 0.70000005 | \x3f333334 | t + \x3f666665 | 0.8999999 | 0.8999999 | \x3f666665 | t + \x3f666666 | 0.9 | 0.9 | \x3f666666 | t + \x3f666667 | 0.90000004 | 0.90000004 | \x3f666667 | t + \x3f7d70a3 | 0.98999995 | 0.98999995 | \x3f7d70a3 | t + \x3f7d70a4 | 0.99 | 0.99 | \x3f7d70a4 | t + \x3f7d70a5 | 0.99000007 | 0.99000007 | \x3f7d70a5 | t + \x3f7fbe76 | 0.99899995 | 0.99899995 | \x3f7fbe76 | t + \x3f7fbe77 | 0.999 | 0.999 | \x3f7fbe77 | t + \x3f7fbe78 | 0.9990001 | 0.9990001 | \x3f7fbe78 | t + \x3f7ff971 | 0.9998999 | 0.9998999 | \x3f7ff971 | t + \x3f7ff972 | 0.9999 | 0.9999 | \x3f7ff972 | t + \x3f7ff973 | 0.99990004 | 0.99990004 | \x3f7ff973 | t + \x3f7fff57 | 0.9999899 | 0.9999899 | \x3f7fff57 | t + \x3f7fff58 | 0.99999 | 0.99999 | \x3f7fff58 | t + \x3f7fff59 | 0.99999005 | 0.99999005 | \x3f7fff59 | t + \x3f7fffee | 0.9999989 | 0.9999989 | \x3f7fffee | t + \x3f7fffef | 0.999999 | 0.999999 | \x3f7fffef | t + \x3f7ffff0 | 0.99999905 | 0.99999905 | \x3f7ffff0 | t + \x3f7ffff1 | 0.9999991 | 0.9999991 | \x3f7ffff1 | t + \x3f7ffff2 | 0.99999917 | 0.99999917 | \x3f7ffff2 | t + \x3f7ffff3 | 0.9999992 | 0.9999992 | \x3f7ffff3 | t + \x3f7ffff4 | 0.9999993 | 0.9999993 | \x3f7ffff4 | t + \x3f7ffff5 | 0.99999934 | 0.99999934 | \x3f7ffff5 | t + \x3f7ffff6 | 0.9999994 | 0.9999994 | \x3f7ffff6 | t + \x3f7ffff7 | 0.99999946 | 0.99999946 | \x3f7ffff7 | t + \x3f7ffff8 | 0.9999995 | 0.9999995 | \x3f7ffff8 | t + \x3f7ffff9 | 0.9999996 | 0.9999996 | \x3f7ffff9 | t + \x3f7ffffa | 0.99999964 | 0.99999964 | \x3f7ffffa | t + \x3f7ffffb | 0.9999997 | 0.9999997 | \x3f7ffffb | t + \x3f7ffffc | 0.99999976 | 0.99999976 | \x3f7ffffc | t + \x3f7ffffd | 0.9999998 | 0.9999998 | \x3f7ffffd | t + \x3f7ffffe | 0.9999999 | 0.9999999 | \x3f7ffffe | t + \x3f7fffff | 0.99999994 | 0.99999994 | \x3f7fffff | t + \x3f800000 | 1 | 1 | \x3f800000 | t + \x3f800001 | 1.0000001 | 1.0000001 | \x3f800001 | t + \x3f800002 | 1.0000002 | 1.0000002 | \x3f800002 | t + \x3f800003 | 1.0000004 | 1.0000004 | \x3f800003 | t + \x3f800004 | 1.0000005 | 1.0000005 | \x3f800004 | t + \x3f800005 | 1.0000006 | 1.0000006 | \x3f800005 | t + \x3f800006 | 1.0000007 | 1.0000007 | \x3f800006 | t + \x3f800007 | 1.0000008 | 1.0000008 | \x3f800007 | t + \x3f800008 | 1.000001 | 1.000001 | \x3f800008 | t + \x3f800009 | 1.0000011 | 1.0000011 | \x3f800009 | t + \x3f80000f | 1.0000018 | 1.0000018 | \x3f80000f | t + \x3f800010 | 1.0000019 | 1.0000019 | \x3f800010 | t + \x3f800011 | 1.000002 | 1.000002 | \x3f800011 | t + \x3f800012 | 1.0000021 | 1.0000021 | \x3f800012 | t + \x3f800013 | 1.0000023 | 1.0000023 | \x3f800013 | t + \x3f800014 | 1.0000024 | 1.0000024 | \x3f800014 | t + \x3f800017 | 1.0000027 | 1.0000027 | \x3f800017 | t + \x3f800018 | 1.0000029 | 1.0000029 | \x3f800018 | t + \x3f800019 | 1.000003 | 1.000003 | \x3f800019 | t + \x3f80001a | 1.0000031 | 1.0000031 | \x3f80001a | t + \x3f80001b | 1.0000032 | 1.0000032 | \x3f80001b | t + \x3f80001c | 1.0000033 | 1.0000033 | \x3f80001c | t + \x3f800029 | 1.0000049 | 1.0000049 | \x3f800029 | t + \x3f80002a | 1.000005 | 1.000005 | \x3f80002a | t + \x3f80002b | 1.0000051 | 1.0000051 | \x3f80002b | t + \x3f800053 | 1.0000099 | 1.0000099 | \x3f800053 | t + \x3f800054 | 1.00001 | 1.00001 | \x3f800054 | t + \x3f800055 | 1.0000101 | 1.0000101 | \x3f800055 | t + \x3f800346 | 1.0000999 | 1.0000999 | \x3f800346 | t + \x3f800347 | 1.0001 | 1.0001 | \x3f800347 | t + \x3f800348 | 1.0001001 | 1.0001001 | \x3f800348 | t + \x3f8020c4 | 1.0009999 | 1.0009999 | \x3f8020c4 | t + \x3f8020c5 | 1.001 | 1.001 | \x3f8020c5 | t + \x3f8020c6 | 1.0010002 | 1.0010002 | \x3f8020c6 | t + \x3f8147ad | 1.0099999 | 1.0099999 | \x3f8147ad | t + \x3f8147ae | 1.01 | 1.01 | \x3f8147ae | t + \x3f8147af | 1.0100001 | 1.0100001 | \x3f8147af | t + \x3f8ccccc | 1.0999999 | 1.0999999 | \x3f8ccccc | t + \x3f8ccccd | 1.1 | 1.1 | \x3f8ccccd | t + \x3f8cccce | 1.1000001 | 1.1000001 | \x3f8cccce | t + \x3fc90fdb | 1.5707964 | 1.5707964 | \x3fc90fdb | t + \x402df854 | 2.7182817 | 2.7182817 | \x402df854 | t + \x40490fdb | 3.1415927 | 3.1415927 | \x40490fdb | t + \x409fffff | 4.9999995 | 4.9999995 | \x409fffff | t + \x40a00000 | 5 | 5 | \x40a00000 | t + \x40a00001 | 5.0000005 | 5.0000005 | \x40a00001 | t + \x40afffff | 5.4999995 | 5.4999995 | \x40afffff | t + \x40b00000 | 5.5 | 5.5 | \x40b00000 | t + \x40b00001 | 5.5000005 | 5.5000005 | \x40b00001 | t + \x411fffff | 9.999999 | 9.999999 | \x411fffff | t + \x41200000 | 10 | 10 | \x41200000 | t + \x41200001 | 10.000001 | 10.000001 | \x41200001 | t + \x42c7ffff | 99.99999 | 99.99999 | \x42c7ffff | t + \x42c80000 | 100 | 100 | \x42c80000 | t + \x42c80001 | 100.00001 | 100.00001 | \x42c80001 | t + \x4479ffff | 999.99994 | 999.99994 | \x4479ffff | t + \x447a0000 | 1000 | 1000 | \x447a0000 | t + \x447a0001 | 1000.00006 | 1000.00006 | \x447a0001 | t + \x461c3fff | 9999.999 | 9999.999 | \x461c3fff | t + \x461c4000 | 10000 | 10000 | \x461c4000 | t + \x461c4001 | 10000.001 | 10000.001 | \x461c4001 | t + \x47c34fff | 99999.99 | 99999.99 | \x47c34fff | t + \x47c35000 | 100000 | 100000 | \x47c35000 | t + \x47c35001 | 100000.01 | 100000.01 | \x47c35001 | t + \x497423ff | 999999.94 | 999999.94 | \x497423ff | t + \x49742400 | 1e+06 | 1e+06 | \x49742400 | t + \x49742401 | 1.00000006e+06 | 1.00000006e+06 | \x49742401 | t + \x4b18967f | 9.999999e+06 | 9.999999e+06 | \x4b18967f | t + \x4b189680 | 1e+07 | 1e+07 | \x4b189680 | t + \x4b189681 | 1.0000001e+07 | 1.0000001e+07 | \x4b189681 | t + \x4cbebc1f | 9.999999e+07 | 9.999999e+07 | \x4cbebc1f | t + \x4cbebc20 | 1e+08 | 1e+08 | \x4cbebc20 | t + \x4cbebc21 | 1.0000001e+08 | 1.0000001e+08 | \x4cbebc21 | t + \x4e6e6b27 | 9.9999994e+08 | 9.9999994e+08 | \x4e6e6b27 | t + \x4e6e6b28 | 1e+09 | 1e+09 | \x4e6e6b28 | t + \x4e6e6b29 | 1.00000006e+09 | 1.00000006e+09 | \x4e6e6b29 | t + \x501502f8 | 9.999999e+09 | 9.999999e+09 | \x501502f8 | t + \x501502f9 | 1e+10 | 1e+10 | \x501502f9 | t + \x501502fa | 1.0000001e+10 | 1.0000001e+10 | \x501502fa | t + \x51ba43b6 | 9.999999e+10 | 9.999999e+10 | \x51ba43b6 | t + \x51ba43b7 | 1e+11 | 1e+11 | \x51ba43b7 | t + \x51ba43b8 | 1.0000001e+11 | 1.0000001e+11 | \x51ba43b8 | t + \x1f6c1e4a | 5e-20 | 5e-20 | \x1f6c1e4a | t + \x59be6cea | 6.7e+15 | 6.7e+15 | \x59be6cea | t + \x5d5ab6c4 | 9.85e+17 | 9.85e+17 | \x5d5ab6c4 | t + \x2cc4a9bd | 5.5895e-12 | 5.5895e-12 | \x2cc4a9bd | t + \x15ae43fd | 7.038531e-26 | 7.0385313e-26 | \x15ae43fe | f + \x2cf757ca | 7.0299088e-12 | 7.0299088e-12 | \x2cf757ca | t + \x665ba998 | 2.5933168e+23 | 2.5933168e+23 | \x665ba998 | t + \x743c3324 | 5.9642887e+31 | 5.9642887e+31 | \x743c3324 | t + \x47f1205a | 123456.7 | 123456.7 | \x47f1205a | t + \x4640e6ae | 12345.67 | 12345.67 | \x4640e6ae | t + \x449a5225 | 1234.567 | 1234.567 | \x449a5225 | t + \x42f6e9d5 | 123.4567 | 123.4567 | \x42f6e9d5 | t + \x414587dd | 12.34567 | 12.34567 | \x414587dd | t + \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t + \x4c000004 | 3.3554448e+07 | 3.3554448e+07 | \x4c000004 | t + \x50061c46 | 8.999999e+09 | 8.999999e+09 | \x50061c46 | t + \x510006a8 | 3.4366718e+10 | 3.4366718e+10 | \x510006a8 | t + \x48951f84 | 305404.12 | 305404.12 | \x48951f84 | t + \x45fd1840 | 8099.0312 | 8099.0312 | \x45fd1840 | t + \x39800000 | 0.00024414062 | 0.00024414062 | \x39800000 | t + \x3b200000 | 0.0024414062 | 0.0024414062 | \x3b200000 | t + \x3b900000 | 0.0043945312 | 0.0043945312 | \x3b900000 | t + \x3bd00000 | 0.0063476562 | 0.0063476562 | \x3bd00000 | t + \x63800000 | 4.7223665e+21 | 4.7223665e+21 | \x63800000 | t + \x4b000000 | 8.388608e+06 | 8.388608e+06 | \x4b000000 | t + \x4b800000 | 1.6777216e+07 | 1.6777216e+07 | \x4b800000 | t + \x4c000001 | 3.3554436e+07 | 3.3554436e+07 | \x4c000001 | t + \x4c800b0d | 6.7131496e+07 | 6.7131496e+07 | \x4c800b0d | t + \x00d24584 | 1.9310392e-38 | 1.9310392e-38 | \x00d24584 | t + \x00d90b88 | 1.993244e-38 | 1.993244e-38 | \x00d90b88 | t + \x45803f34 | 4103.9004 | 4103.9004 | \x45803f34 | t + \x4f9f24f7 | 5.3399997e+09 | 5.3399997e+09 | \x4f9f24f7 | t + \x3a8722c3 | 0.0010310042 | 0.0010310042 | \x3a8722c3 | t + \x5c800041 | 2.882326e+17 | 2.882326e+17 | \x5c800041 | t + \x15ae43fd | 7.038531e-26 | 7.0385313e-26 | \x15ae43fe | f + \x5d4cccfb | 9.223404e+17 | 9.223404e+17 | \x5d4cccfb | t + \x4c800001 | 6.710887e+07 | 6.710887e+07 | \x4c800001 | t + \x57800ed8 | 2.816025e+14 | 2.816025e+14 | \x57800ed8 | t + \x5f000000 | 9.223372e+18 | 9.223372e+18 | \x5f000000 | t + \x700000f0 | 1.5846086e+29 | 1.5846086e+29 | \x700000f0 | t + \x5f23e9ac | 1.1811161e+19 | 1.1811161e+19 | \x5f23e9ac | t + \x5e9502f9 | 5.368709e+18 | 5.368709e+18 | \x5e9502f9 | t + \x5e8012b1 | 4.6143166e+18 | 4.6143166e+18 | \x5e8012b1 | t + \x3c000028 | 0.007812537 | 0.007812537 | \x3c000028 | t + \x60cde861 | 1.18697725e+20 | 1.18697725e+20 | \x60cde861 | t + \x03aa2a50 | 1.00014165e-36 | 1.00014165e-36 | \x03aa2a50 | t + \x43480000 | 200 | 200 | \x43480000 | t + \x4c000000 | 3.3554432e+07 | 3.3554432e+07 | \x4c000000 | t + \x5d1502f9 | 6.7108864e+17 | 6.7108864e+17 | \x5d1502f9 | t + \x5d9502f9 | 1.3421773e+18 | 1.3421773e+18 | \x5d9502f9 | t + \x5e1502f9 | 2.6843546e+18 | 2.6843546e+18 | \x5e1502f9 | t + \x3f99999a | 1.2 | 1.2 | \x3f99999a | t + \x3f9d70a4 | 1.23 | 1.23 | \x3f9d70a4 | t + \x3f9df3b6 | 1.234 | 1.234 | \x3f9df3b6 | t + \x3f9e0419 | 1.2345 | 1.2345 | \x3f9e0419 | t + \x3f9e0610 | 1.23456 | 1.23456 | \x3f9e0610 | t + \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t + \x3f9e0651 | 1.2345678 | 1.2345678 | \x3f9e0651 | t + \x03d20cfe | 1.23456735e-36 | 1.23456735e-36 | \x03d20cfe | t +(261 rows) + +-- clean up, lest opr_sanity complain +drop type xfloat4 cascade; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to function xfloat4in(cstring) +drop cascades to function xfloat4out(xfloat4) +drop cascades to cast from xfloat4 to real +drop cascades to cast from real to xfloat4 +drop cascades to cast from xfloat4 to integer +drop cascades to cast from integer to xfloat4 diff --git a/src/test/regress/expected/float4.out b/src/test/regress/expected/float4.out index fd46a4a1db7..d6c22c1752a 100644 --- a/src/test/regress/expected/float4.out +++ b/src/test/regress/expected/float4.out @@ -9,21 +9,45 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e+20'); INSERT INTO FLOAT4_TBL(f1) VALUES ('1.2345678901234e-20'); -- test for over and under flow INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); -ERROR: value out of range: overflow +ERROR: "10e70" is out of range for type real LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'); ^ INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); -ERROR: value out of range: overflow +ERROR: "-10e70" is out of range for type real LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); ^ INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); -ERROR: value out of range: underflow +ERROR: "10e-70" is out of range for type real LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); ^ INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); -ERROR: value out of range: underflow +ERROR: "-10e-70" is out of range for type real LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8); +ERROR: value out of range: overflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8); +ERROR: value out of range: overflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8); +ERROR: value out of range: underflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8); +ERROR: value out of range: underflow +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); +ERROR: "10e400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); +ERROR: "-10e400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); +ERROR: "10e-400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); + ^ +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); +ERROR: "-10e-400" is out of range for type real +LINE 1: INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); + ^ -- bad input INSERT INTO FLOAT4_TBL(f1) VALUES (''); ERROR: invalid input syntax for type real: "" @@ -126,22 +150,22 @@ SELECT 'nan'::numeric::float4; (1 row) SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e+20 - | 1.23457e-20 + five | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 (5 rows) SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <> '1004.3'; - four | f1 -------+------------- - | 0 - | -34.84 - | 1.23457e+20 - | 1.23457e-20 + four | f1 +------+--------------- + | 0 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 (4 rows) SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3'; @@ -151,109 +175,775 @@ SELECT '' AS one, f.* FROM FLOAT4_TBL f WHERE f.f1 = '1004.3'; (1 row) SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE '1004.3' > f.f1; - three | f1 --------+------------- - | 0 - | -34.84 - | 1.23457e-20 + three | f1 +-------+--------------- + | 0 + | -34.84 + | 1.2345679e-20 (3 rows) SELECT '' AS three, f.* FROM FLOAT4_TBL f WHERE f.f1 < '1004.3'; - three | f1 --------+------------- - | 0 - | -34.84 - | 1.23457e-20 + three | f1 +-------+--------------- + | 0 + | -34.84 + | 1.2345679e-20 (3 rows) SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE '1004.3' >= f.f1; - four | f1 -------+------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e-20 + four | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e-20 (4 rows) SELECT '' AS four, f.* FROM FLOAT4_TBL f WHERE f.f1 <= '1004.3'; - four | f1 -------+------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e-20 + four | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e-20 (4 rows) SELECT '' AS three, f.f1, f.f1 * '-10' AS x FROM FLOAT4_TBL f WHERE f.f1 > '0.0'; - three | f1 | x --------+-------------+-------------- - | 1004.3 | -10043 - | 1.23457e+20 | -1.23457e+21 - | 1.23457e-20 | -1.23457e-19 + three | f1 | x +-------+---------------+---------------- + | 1004.3 | -10043 + | 1.2345679e+20 | -1.2345678e+21 + | 1.2345679e-20 | -1.2345678e-19 (3 rows) SELECT '' AS three, f.f1, f.f1 + '-10' AS x FROM FLOAT4_TBL f WHERE f.f1 > '0.0'; - three | f1 | x --------+-------------+------------- - | 1004.3 | 994.3 - | 1.23457e+20 | 1.23457e+20 - | 1.23457e-20 | -10 + three | f1 | x +-------+---------------+--------------- + | 1004.3 | 994.3 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | -10 (3 rows) SELECT '' AS three, f.f1, f.f1 / '-10' AS x FROM FLOAT4_TBL f WHERE f.f1 > '0.0'; - three | f1 | x --------+-------------+-------------- - | 1004.3 | -100.43 - | 1.23457e+20 | -1.23457e+19 - | 1.23457e-20 | -1.23457e-21 + three | f1 | x +-------+---------------+---------------- + | 1004.3 | -100.43 + | 1.2345679e+20 | -1.2345679e+19 + | 1.2345679e-20 | -1.2345679e-21 (3 rows) SELECT '' AS three, f.f1, f.f1 - '-10' AS x FROM FLOAT4_TBL f WHERE f.f1 > '0.0'; - three | f1 | x --------+-------------+------------- - | 1004.3 | 1014.3 - | 1.23457e+20 | 1.23457e+20 - | 1.23457e-20 | 10 + three | f1 | x +-------+---------------+--------------- + | 1004.3 | 1014.3 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | 10 (3 rows) -- test divide by zero SELECT '' AS bad, f.f1 / '0.0' from FLOAT4_TBL f; ERROR: division by zero SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+------------- - | 0 - | 1004.3 - | -34.84 - | 1.23457e+20 - | 1.23457e-20 + five | f1 +------+--------------- + | 0 + | 1004.3 + | -34.84 + | 1.2345679e+20 + | 1.2345679e-20 (5 rows) -- test the unary float4abs operator SELECT '' AS five, f.f1, @f.f1 AS abs_f1 FROM FLOAT4_TBL f; - five | f1 | abs_f1 -------+-------------+------------- - | 0 | 0 - | 1004.3 | 1004.3 - | -34.84 | 34.84 - | 1.23457e+20 | 1.23457e+20 - | 1.23457e-20 | 1.23457e-20 + five | f1 | abs_f1 +------+---------------+--------------- + | 0 | 0 + | 1004.3 | 1004.3 + | -34.84 | 34.84 + | 1.2345679e+20 | 1.2345679e+20 + | 1.2345679e-20 | 1.2345679e-20 (5 rows) UPDATE FLOAT4_TBL SET f1 = FLOAT4_TBL.f1 * '-1' WHERE FLOAT4_TBL.f1 > '0.0'; SELECT '' AS five, * FROM FLOAT4_TBL; - five | f1 -------+-------------- - | 0 - | -34.84 - | -1004.3 - | -1.23457e+20 - | -1.23457e-20 + five | f1 +------+---------------- + | 0 + | -34.84 + | -1004.3 + | -1.2345679e+20 + | -1.2345679e-20 (5 rows) +-- test edge-case coercions to integer +SELECT '32767.4'::float4::int2; + int2 +------- + 32767 +(1 row) + +SELECT '32767.6'::float4::int2; +ERROR: smallint out of range +SELECT '-32768.4'::float4::int2; + int2 +-------- + -32768 +(1 row) + +SELECT '-32768.6'::float4::int2; +ERROR: smallint out of range +SELECT '2147483520'::float4::int4; + int4 +------------ + 2147483520 +(1 row) + +SELECT '2147483647'::float4::int4; +ERROR: integer out of range +SELECT '-2147483648.5'::float4::int4; + int4 +------------- + -2147483648 +(1 row) + +SELECT '-2147483900'::float4::int4; +ERROR: integer out of range +SELECT '9223369837831520256'::float4::int8; + int8 +--------------------- + 9223369837831520256 +(1 row) + +SELECT '9223372036854775807'::float4::int8; +ERROR: bigint out of range +SELECT '-9223372036854775808.5'::float4::int8; + int8 +---------------------- + -9223372036854775808 +(1 row) + +SELECT '-9223380000000000000'::float4::int8; +ERROR: bigint out of range +-- Test for correct input rounding in edge cases. +-- These lists are from Paxson 1991, excluding subnormals and +-- inputs of over 9 sig. digits. +SELECT float4send('5e-20'::float4); + float4send +------------ + \x1f6c1e4a +(1 row) + +SELECT float4send('67e14'::float4); + float4send +------------ + \x59be6cea +(1 row) + +SELECT float4send('985e15'::float4); + float4send +------------ + \x5d5ab6c4 +(1 row) + +SELECT float4send('55895e-16'::float4); + float4send +------------ + \x2cc4a9bd +(1 row) + +SELECT float4send('7038531e-32'::float4); + float4send +------------ + \x15ae43fd +(1 row) + +SELECT float4send('702990899e-20'::float4); + float4send +------------ + \x2cf757ca +(1 row) + +SELECT float4send('3e-23'::float4); + float4send +------------ + \x1a111234 +(1 row) + +SELECT float4send('57e18'::float4); + float4send +------------ + \x6045c22c +(1 row) + +SELECT float4send('789e-35'::float4); + float4send +------------ + \x0a23de70 +(1 row) + +SELECT float4send('2539e-18'::float4); + float4send +------------ + \x2736f449 +(1 row) + +SELECT float4send('76173e28'::float4); + float4send +------------ + \x7616398a +(1 row) + +SELECT float4send('887745e-11'::float4); + float4send +------------ + \x3714f05c +(1 row) + +SELECT float4send('5382571e-37'::float4); + float4send +------------ + \x0d2eaca7 +(1 row) + +SELECT float4send('82381273e-35'::float4); + float4send +------------ + \x128289d1 +(1 row) + +SELECT float4send('750486563e-38'::float4); + float4send +------------ + \x0f18377e +(1 row) + +-- Test that the smallest possible normalized input value inputs +-- correctly, either in 9-significant-digit or shortest-decimal +-- format. +-- +-- exact val is 1.1754943508... +-- shortest val is 1.1754944000 +-- midpoint to next val is 1.1754944208... +SELECT float4send('1.17549435e-38'::float4); + float4send +------------ + \x00800000 +(1 row) + +SELECT float4send('1.1754944e-38'::float4); + float4send +------------ + \x00800000 +(1 row) + +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). +create type xfloat4; +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in'; +NOTICE: return type xfloat4 is only a shell +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out'; +NOTICE: argument type xfloat4 is only a shell +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4); +create cast (xfloat4 as float4) without function; +create cast (float4 as xfloat4) without function; +create cast (xfloat4 as integer) without function; +create cast (integer as xfloat4) without function; +-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + ibits | flt +------------+--------------- + \x00000001 | 1e-45 + \x00000002 | 3e-45 + \x00000003 | 4e-45 + \x00000010 | 2.2e-44 + \x00000011 | 2.4e-44 + \x00000100 | 3.59e-43 + \x00000101 | 3.6e-43 + \x00004000 | 2.2959e-41 + \x00004001 | 2.296e-41 + \x00080000 | 7.34684e-40 + \x00080001 | 7.34685e-40 + \x0053c4f4 | 7.693e-39 + \x006c85c4 | 9.96622e-39 + \x0041ca76 | 6.041937e-39 + \x004b7678 | 6.930161e-39 + \x00000007 | 1e-44 + \x00424fe2 | 6.0898e-39 + \x007ffff0 | 1.1754921e-38 + \x007ffff1 | 1.1754922e-38 + \x007ffffe | 1.1754941e-38 + \x007fffff | 1.1754942e-38 +(21 rows) + +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + ibits | flt | r_flt | obits | correct +------------+----------------+----------------+------------+--------- + \x00000000 | 0 | 0 | \x00000000 | t + \x00800000 | 1.1754944e-38 | 1.1754944e-38 | \x00800000 | t + \x00800001 | 1.1754945e-38 | 1.1754945e-38 | \x00800001 | t + \x00800004 | 1.1754949e-38 | 1.1754949e-38 | \x00800004 | t + \x00800005 | 1.175495e-38 | 1.175495e-38 | \x00800005 | t + \x00800006 | 1.1754952e-38 | 1.1754952e-38 | \x00800006 | t + \x008002f1 | 1.1755999e-38 | 1.1755999e-38 | \x008002f1 | t + \x008002f2 | 1.1756e-38 | 1.1756e-38 | \x008002f2 | t + \x008002f3 | 1.1756001e-38 | 1.1756001e-38 | \x008002f3 | t + \x00800e17 | 1.1759998e-38 | 1.1759998e-38 | \x00800e17 | t + \x00800e18 | 1.176e-38 | 1.176e-38 | \x00800e18 | t + \x00800e19 | 1.1760001e-38 | 1.1760001e-38 | \x00800e19 | t + \x01000001 | 2.350989e-38 | 2.350989e-38 | \x01000001 | t + \x01102843 | 2.647751e-38 | 2.647751e-38 | \x01102843 | t + \x01a52c98 | 6.0675416e-38 | 6.0675416e-38 | \x01a52c98 | t + \x0219c229 | 1.1296386e-37 | 1.1296386e-37 | \x0219c229 | t + \x02e4464d | 3.354194e-37 | 3.354194e-37 | \x02e4464d | t + \x037343c1 | 7.148906e-37 | 7.148906e-37 | \x037343c1 | t + \x03a91b36 | 9.939175e-37 | 9.939175e-37 | \x03a91b36 | t + \x047ada65 | 2.948764e-36 | 2.948764e-36 | \x047ada65 | t + \x0496fe87 | 3.5498577e-36 | 3.5498577e-36 | \x0496fe87 | t + \x0550844f | 9.804414e-36 | 9.804414e-36 | \x0550844f | t + \x05999da3 | 1.4445957e-35 | 1.4445957e-35 | \x05999da3 | t + \x060ea5e2 | 2.6829103e-35 | 2.6829103e-35 | \x060ea5e2 | t + \x06e63c45 | 8.660494e-35 | 8.660494e-35 | \x06e63c45 | t + \x07f1e548 | 3.639641e-34 | 3.639641e-34 | \x07f1e548 | t + \x0fc5282b | 1.9441172e-29 | 1.9441172e-29 | \x0fc5282b | t + \x1f850283 | 5.6331846e-20 | 5.6331846e-20 | \x1f850283 | t + \x2874a9d6 | 1.3581548e-14 | 1.3581548e-14 | \x2874a9d6 | t + \x3356bf94 | 4.9999997e-08 | 4.9999997e-08 | \x3356bf94 | t + \x3356bf95 | 5e-08 | 5e-08 | \x3356bf95 | t + \x3356bf96 | 5.0000004e-08 | 5.0000004e-08 | \x3356bf96 | t + \x33d6bf94 | 9.9999994e-08 | 9.9999994e-08 | \x33d6bf94 | t + \x33d6bf95 | 1e-07 | 1e-07 | \x33d6bf95 | t + \x33d6bf96 | 1.0000001e-07 | 1.0000001e-07 | \x33d6bf96 | t + \x34a10faf | 2.9999998e-07 | 2.9999998e-07 | \x34a10faf | t + \x34a10fb0 | 3e-07 | 3e-07 | \x34a10fb0 | t + \x34a10fb1 | 3.0000004e-07 | 3.0000004e-07 | \x34a10fb1 | t + \x350637bc | 4.9999994e-07 | 4.9999994e-07 | \x350637bc | t + \x350637bd | 5e-07 | 5e-07 | \x350637bd | t + \x350637be | 5.0000006e-07 | 5.0000006e-07 | \x350637be | t + \x35719786 | 8.999999e-07 | 8.999999e-07 | \x35719786 | t + \x35719787 | 9e-07 | 9e-07 | \x35719787 | t + \x35719788 | 9.0000003e-07 | 9.0000003e-07 | \x35719788 | t + \x358637bc | 9.999999e-07 | 9.999999e-07 | \x358637bc | t + \x358637bd | 1e-06 | 1e-06 | \x358637bd | t + \x358637be | 1.0000001e-06 | 1.0000001e-06 | \x358637be | t + \x36a7c5ab | 4.9999994e-06 | 4.9999994e-06 | \x36a7c5ab | t + \x36a7c5ac | 5e-06 | 5e-06 | \x36a7c5ac | t + \x36a7c5ad | 5.0000003e-06 | 5.0000003e-06 | \x36a7c5ad | t + \x3727c5ab | 9.999999e-06 | 9.999999e-06 | \x3727c5ab | t + \x3727c5ac | 1e-05 | 1e-05 | \x3727c5ac | t + \x3727c5ad | 1.0000001e-05 | 1.0000001e-05 | \x3727c5ad | t + \x38d1b714 | 9.9999976e-05 | 9.9999976e-05 | \x38d1b714 | t + \x38d1b715 | 9.999998e-05 | 9.999998e-05 | \x38d1b715 | t + \x38d1b716 | 9.999999e-05 | 9.999999e-05 | \x38d1b716 | t + \x38d1b717 | 0.0001 | 0.0001 | \x38d1b717 | t + \x38d1b718 | 0.000100000005 | 0.000100000005 | \x38d1b718 | t + \x38d1b719 | 0.00010000001 | 0.00010000001 | \x38d1b719 | t + \x38d1b71a | 0.00010000002 | 0.00010000002 | \x38d1b71a | t + \x38d1b71b | 0.00010000003 | 0.00010000003 | \x38d1b71b | t + \x38d1b71c | 0.000100000034 | 0.000100000034 | \x38d1b71c | t + \x38d1b71d | 0.00010000004 | 0.00010000004 | \x38d1b71d | t + \x38dffffe | 0.00010681151 | 0.00010681151 | \x38dffffe | t + \x38dfffff | 0.000106811516 | 0.000106811516 | \x38dfffff | t + \x38e00000 | 0.00010681152 | 0.00010681152 | \x38e00000 | t + \x38efffff | 0.00011444091 | 0.00011444091 | \x38efffff | t + \x38f00000 | 0.00011444092 | 0.00011444092 | \x38f00000 | t + \x38f00001 | 0.000114440925 | 0.000114440925 | \x38f00001 | t + \x3a83126e | 0.0009999999 | 0.0009999999 | \x3a83126e | t + \x3a83126f | 0.001 | 0.001 | \x3a83126f | t + \x3a831270 | 0.0010000002 | 0.0010000002 | \x3a831270 | t + \x3c23d709 | 0.009999999 | 0.009999999 | \x3c23d709 | t + \x3c23d70a | 0.01 | 0.01 | \x3c23d70a | t + \x3c23d70b | 0.010000001 | 0.010000001 | \x3c23d70b | t + \x3dcccccc | 0.099999994 | 0.099999994 | \x3dcccccc | t + \x3dcccccd | 0.1 | 0.1 | \x3dcccccd | t + \x3dccccce | 0.10000001 | 0.10000001 | \x3dccccce | t + \x3dcccd6f | 0.10000121 | 0.10000121 | \x3dcccd6f | t + \x3dcccd70 | 0.100001216 | 0.100001216 | \x3dcccd70 | t + \x3dcccd71 | 0.10000122 | 0.10000122 | \x3dcccd71 | t + \x3effffff | 0.49999997 | 0.49999997 | \x3effffff | t + \x3f000000 | 0.5 | 0.5 | \x3f000000 | t + \x3f000001 | 0.50000006 | 0.50000006 | \x3f000001 | t + \x3f333332 | 0.6999999 | 0.6999999 | \x3f333332 | t + \x3f333333 | 0.7 | 0.7 | \x3f333333 | t + \x3f333334 | 0.70000005 | 0.70000005 | \x3f333334 | t + \x3f666665 | 0.8999999 | 0.8999999 | \x3f666665 | t + \x3f666666 | 0.9 | 0.9 | \x3f666666 | t + \x3f666667 | 0.90000004 | 0.90000004 | \x3f666667 | t + \x3f7d70a3 | 0.98999995 | 0.98999995 | \x3f7d70a3 | t + \x3f7d70a4 | 0.99 | 0.99 | \x3f7d70a4 | t + \x3f7d70a5 | 0.99000007 | 0.99000007 | \x3f7d70a5 | t + \x3f7fbe76 | 0.99899995 | 0.99899995 | \x3f7fbe76 | t + \x3f7fbe77 | 0.999 | 0.999 | \x3f7fbe77 | t + \x3f7fbe78 | 0.9990001 | 0.9990001 | \x3f7fbe78 | t + \x3f7ff971 | 0.9998999 | 0.9998999 | \x3f7ff971 | t + \x3f7ff972 | 0.9999 | 0.9999 | \x3f7ff972 | t + \x3f7ff973 | 0.99990004 | 0.99990004 | \x3f7ff973 | t + \x3f7fff57 | 0.9999899 | 0.9999899 | \x3f7fff57 | t + \x3f7fff58 | 0.99999 | 0.99999 | \x3f7fff58 | t + \x3f7fff59 | 0.99999005 | 0.99999005 | \x3f7fff59 | t + \x3f7fffee | 0.9999989 | 0.9999989 | \x3f7fffee | t + \x3f7fffef | 0.999999 | 0.999999 | \x3f7fffef | t + \x3f7ffff0 | 0.99999905 | 0.99999905 | \x3f7ffff0 | t + \x3f7ffff1 | 0.9999991 | 0.9999991 | \x3f7ffff1 | t + \x3f7ffff2 | 0.99999917 | 0.99999917 | \x3f7ffff2 | t + \x3f7ffff3 | 0.9999992 | 0.9999992 | \x3f7ffff3 | t + \x3f7ffff4 | 0.9999993 | 0.9999993 | \x3f7ffff4 | t + \x3f7ffff5 | 0.99999934 | 0.99999934 | \x3f7ffff5 | t + \x3f7ffff6 | 0.9999994 | 0.9999994 | \x3f7ffff6 | t + \x3f7ffff7 | 0.99999946 | 0.99999946 | \x3f7ffff7 | t + \x3f7ffff8 | 0.9999995 | 0.9999995 | \x3f7ffff8 | t + \x3f7ffff9 | 0.9999996 | 0.9999996 | \x3f7ffff9 | t + \x3f7ffffa | 0.99999964 | 0.99999964 | \x3f7ffffa | t + \x3f7ffffb | 0.9999997 | 0.9999997 | \x3f7ffffb | t + \x3f7ffffc | 0.99999976 | 0.99999976 | \x3f7ffffc | t + \x3f7ffffd | 0.9999998 | 0.9999998 | \x3f7ffffd | t + \x3f7ffffe | 0.9999999 | 0.9999999 | \x3f7ffffe | t + \x3f7fffff | 0.99999994 | 0.99999994 | \x3f7fffff | t + \x3f800000 | 1 | 1 | \x3f800000 | t + \x3f800001 | 1.0000001 | 1.0000001 | \x3f800001 | t + \x3f800002 | 1.0000002 | 1.0000002 | \x3f800002 | t + \x3f800003 | 1.0000004 | 1.0000004 | \x3f800003 | t + \x3f800004 | 1.0000005 | 1.0000005 | \x3f800004 | t + \x3f800005 | 1.0000006 | 1.0000006 | \x3f800005 | t + \x3f800006 | 1.0000007 | 1.0000007 | \x3f800006 | t + \x3f800007 | 1.0000008 | 1.0000008 | \x3f800007 | t + \x3f800008 | 1.000001 | 1.000001 | \x3f800008 | t + \x3f800009 | 1.0000011 | 1.0000011 | \x3f800009 | t + \x3f80000f | 1.0000018 | 1.0000018 | \x3f80000f | t + \x3f800010 | 1.0000019 | 1.0000019 | \x3f800010 | t + \x3f800011 | 1.000002 | 1.000002 | \x3f800011 | t + \x3f800012 | 1.0000021 | 1.0000021 | \x3f800012 | t + \x3f800013 | 1.0000023 | 1.0000023 | \x3f800013 | t + \x3f800014 | 1.0000024 | 1.0000024 | \x3f800014 | t + \x3f800017 | 1.0000027 | 1.0000027 | \x3f800017 | t + \x3f800018 | 1.0000029 | 1.0000029 | \x3f800018 | t + \x3f800019 | 1.000003 | 1.000003 | \x3f800019 | t + \x3f80001a | 1.0000031 | 1.0000031 | \x3f80001a | t + \x3f80001b | 1.0000032 | 1.0000032 | \x3f80001b | t + \x3f80001c | 1.0000033 | 1.0000033 | \x3f80001c | t + \x3f800029 | 1.0000049 | 1.0000049 | \x3f800029 | t + \x3f80002a | 1.000005 | 1.000005 | \x3f80002a | t + \x3f80002b | 1.0000051 | 1.0000051 | \x3f80002b | t + \x3f800053 | 1.0000099 | 1.0000099 | \x3f800053 | t + \x3f800054 | 1.00001 | 1.00001 | \x3f800054 | t + \x3f800055 | 1.0000101 | 1.0000101 | \x3f800055 | t + \x3f800346 | 1.0000999 | 1.0000999 | \x3f800346 | t + \x3f800347 | 1.0001 | 1.0001 | \x3f800347 | t + \x3f800348 | 1.0001001 | 1.0001001 | \x3f800348 | t + \x3f8020c4 | 1.0009999 | 1.0009999 | \x3f8020c4 | t + \x3f8020c5 | 1.001 | 1.001 | \x3f8020c5 | t + \x3f8020c6 | 1.0010002 | 1.0010002 | \x3f8020c6 | t + \x3f8147ad | 1.0099999 | 1.0099999 | \x3f8147ad | t + \x3f8147ae | 1.01 | 1.01 | \x3f8147ae | t + \x3f8147af | 1.0100001 | 1.0100001 | \x3f8147af | t + \x3f8ccccc | 1.0999999 | 1.0999999 | \x3f8ccccc | t + \x3f8ccccd | 1.1 | 1.1 | \x3f8ccccd | t + \x3f8cccce | 1.1000001 | 1.1000001 | \x3f8cccce | t + \x3fc90fdb | 1.5707964 | 1.5707964 | \x3fc90fdb | t + \x402df854 | 2.7182817 | 2.7182817 | \x402df854 | t + \x40490fdb | 3.1415927 | 3.1415927 | \x40490fdb | t + \x409fffff | 4.9999995 | 4.9999995 | \x409fffff | t + \x40a00000 | 5 | 5 | \x40a00000 | t + \x40a00001 | 5.0000005 | 5.0000005 | \x40a00001 | t + \x40afffff | 5.4999995 | 5.4999995 | \x40afffff | t + \x40b00000 | 5.5 | 5.5 | \x40b00000 | t + \x40b00001 | 5.5000005 | 5.5000005 | \x40b00001 | t + \x411fffff | 9.999999 | 9.999999 | \x411fffff | t + \x41200000 | 10 | 10 | \x41200000 | t + \x41200001 | 10.000001 | 10.000001 | \x41200001 | t + \x42c7ffff | 99.99999 | 99.99999 | \x42c7ffff | t + \x42c80000 | 100 | 100 | \x42c80000 | t + \x42c80001 | 100.00001 | 100.00001 | \x42c80001 | t + \x4479ffff | 999.99994 | 999.99994 | \x4479ffff | t + \x447a0000 | 1000 | 1000 | \x447a0000 | t + \x447a0001 | 1000.00006 | 1000.00006 | \x447a0001 | t + \x461c3fff | 9999.999 | 9999.999 | \x461c3fff | t + \x461c4000 | 10000 | 10000 | \x461c4000 | t + \x461c4001 | 10000.001 | 10000.001 | \x461c4001 | t + \x47c34fff | 99999.99 | 99999.99 | \x47c34fff | t + \x47c35000 | 100000 | 100000 | \x47c35000 | t + \x47c35001 | 100000.01 | 100000.01 | \x47c35001 | t + \x497423ff | 999999.94 | 999999.94 | \x497423ff | t + \x49742400 | 1e+06 | 1e+06 | \x49742400 | t + \x49742401 | 1.00000006e+06 | 1.00000006e+06 | \x49742401 | t + \x4b18967f | 9.999999e+06 | 9.999999e+06 | \x4b18967f | t + \x4b189680 | 1e+07 | 1e+07 | \x4b189680 | t + \x4b189681 | 1.0000001e+07 | 1.0000001e+07 | \x4b189681 | t + \x4cbebc1f | 9.999999e+07 | 9.999999e+07 | \x4cbebc1f | t + \x4cbebc20 | 1e+08 | 1e+08 | \x4cbebc20 | t + \x4cbebc21 | 1.0000001e+08 | 1.0000001e+08 | \x4cbebc21 | t + \x4e6e6b27 | 9.9999994e+08 | 9.9999994e+08 | \x4e6e6b27 | t + \x4e6e6b28 | 1e+09 | 1e+09 | \x4e6e6b28 | t + \x4e6e6b29 | 1.00000006e+09 | 1.00000006e+09 | \x4e6e6b29 | t + \x501502f8 | 9.999999e+09 | 9.999999e+09 | \x501502f8 | t + \x501502f9 | 1e+10 | 1e+10 | \x501502f9 | t + \x501502fa | 1.0000001e+10 | 1.0000001e+10 | \x501502fa | t + \x51ba43b6 | 9.999999e+10 | 9.999999e+10 | \x51ba43b6 | t + \x51ba43b7 | 1e+11 | 1e+11 | \x51ba43b7 | t + \x51ba43b8 | 1.0000001e+11 | 1.0000001e+11 | \x51ba43b8 | t + \x1f6c1e4a | 5e-20 | 5e-20 | \x1f6c1e4a | t + \x59be6cea | 6.7e+15 | 6.7e+15 | \x59be6cea | t + \x5d5ab6c4 | 9.85e+17 | 9.85e+17 | \x5d5ab6c4 | t + \x2cc4a9bd | 5.5895e-12 | 5.5895e-12 | \x2cc4a9bd | t + \x15ae43fd | 7.038531e-26 | 7.038531e-26 | \x15ae43fd | t + \x2cf757ca | 7.0299088e-12 | 7.0299088e-12 | \x2cf757ca | t + \x665ba998 | 2.5933168e+23 | 2.5933168e+23 | \x665ba998 | t + \x743c3324 | 5.9642887e+31 | 5.9642887e+31 | \x743c3324 | t + \x47f1205a | 123456.7 | 123456.7 | \x47f1205a | t + \x4640e6ae | 12345.67 | 12345.67 | \x4640e6ae | t + \x449a5225 | 1234.567 | 1234.567 | \x449a5225 | t + \x42f6e9d5 | 123.4567 | 123.4567 | \x42f6e9d5 | t + \x414587dd | 12.34567 | 12.34567 | \x414587dd | t + \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t + \x4c000004 | 3.3554448e+07 | 3.3554448e+07 | \x4c000004 | t + \x50061c46 | 8.999999e+09 | 8.999999e+09 | \x50061c46 | t + \x510006a8 | 3.4366718e+10 | 3.4366718e+10 | \x510006a8 | t + \x48951f84 | 305404.12 | 305404.12 | \x48951f84 | t + \x45fd1840 | 8099.0312 | 8099.0312 | \x45fd1840 | t + \x39800000 | 0.00024414062 | 0.00024414062 | \x39800000 | t + \x3b200000 | 0.0024414062 | 0.0024414062 | \x3b200000 | t + \x3b900000 | 0.0043945312 | 0.0043945312 | \x3b900000 | t + \x3bd00000 | 0.0063476562 | 0.0063476562 | \x3bd00000 | t + \x63800000 | 4.7223665e+21 | 4.7223665e+21 | \x63800000 | t + \x4b000000 | 8.388608e+06 | 8.388608e+06 | \x4b000000 | t + \x4b800000 | 1.6777216e+07 | 1.6777216e+07 | \x4b800000 | t + \x4c000001 | 3.3554436e+07 | 3.3554436e+07 | \x4c000001 | t + \x4c800b0d | 6.7131496e+07 | 6.7131496e+07 | \x4c800b0d | t + \x00d24584 | 1.9310392e-38 | 1.9310392e-38 | \x00d24584 | t + \x00d90b88 | 1.993244e-38 | 1.993244e-38 | \x00d90b88 | t + \x45803f34 | 4103.9004 | 4103.9004 | \x45803f34 | t + \x4f9f24f7 | 5.3399997e+09 | 5.3399997e+09 | \x4f9f24f7 | t + \x3a8722c3 | 0.0010310042 | 0.0010310042 | \x3a8722c3 | t + \x5c800041 | 2.882326e+17 | 2.882326e+17 | \x5c800041 | t + \x15ae43fd | 7.038531e-26 | 7.038531e-26 | \x15ae43fd | t + \x5d4cccfb | 9.223404e+17 | 9.223404e+17 | \x5d4cccfb | t + \x4c800001 | 6.710887e+07 | 6.710887e+07 | \x4c800001 | t + \x57800ed8 | 2.816025e+14 | 2.816025e+14 | \x57800ed8 | t + \x5f000000 | 9.223372e+18 | 9.223372e+18 | \x5f000000 | t + \x700000f0 | 1.5846086e+29 | 1.5846086e+29 | \x700000f0 | t + \x5f23e9ac | 1.1811161e+19 | 1.1811161e+19 | \x5f23e9ac | t + \x5e9502f9 | 5.368709e+18 | 5.368709e+18 | \x5e9502f9 | t + \x5e8012b1 | 4.6143166e+18 | 4.6143166e+18 | \x5e8012b1 | t + \x3c000028 | 0.007812537 | 0.007812537 | \x3c000028 | t + \x60cde861 | 1.18697725e+20 | 1.18697725e+20 | \x60cde861 | t + \x03aa2a50 | 1.00014165e-36 | 1.00014165e-36 | \x03aa2a50 | t + \x43480000 | 200 | 200 | \x43480000 | t + \x4c000000 | 3.3554432e+07 | 3.3554432e+07 | \x4c000000 | t + \x5d1502f9 | 6.7108864e+17 | 6.7108864e+17 | \x5d1502f9 | t + \x5d9502f9 | 1.3421773e+18 | 1.3421773e+18 | \x5d9502f9 | t + \x5e1502f9 | 2.6843546e+18 | 2.6843546e+18 | \x5e1502f9 | t + \x3f99999a | 1.2 | 1.2 | \x3f99999a | t + \x3f9d70a4 | 1.23 | 1.23 | \x3f9d70a4 | t + \x3f9df3b6 | 1.234 | 1.234 | \x3f9df3b6 | t + \x3f9e0419 | 1.2345 | 1.2345 | \x3f9e0419 | t + \x3f9e0610 | 1.23456 | 1.23456 | \x3f9e0610 | t + \x3f9e064b | 1.234567 | 1.234567 | \x3f9e064b | t + \x3f9e0651 | 1.2345678 | 1.2345678 | \x3f9e0651 | t + \x03d20cfe | 1.23456735e-36 | 1.23456735e-36 | \x03d20cfe | t +(261 rows) + +-- clean up, lest opr_sanity complain +drop type xfloat4 cascade; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to function xfloat4in(cstring) +drop cascades to function xfloat4out(xfloat4) +drop cascades to cast from xfloat4 to real +drop cascades to cast from real to xfloat4 +drop cascades to cast from xfloat4 to integer +drop cascades to cast from integer to xfloat4 diff --git a/src/test/regress/expected/float8-exp-three-digits-win32.out b/src/test/regress/expected/float8-exp-three-digits-win32.out deleted file mode 100644 index 7e1153308f5..00000000000 --- a/src/test/regress/expected/float8-exp-three-digits-win32.out +++ /dev/null @@ -1,550 +0,0 @@ --- --- FLOAT8 --- -CREATE TABLE FLOAT8_TBL(f1 float8); -INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 '); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 '); -INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200'); --- test for underflow and overflow handling -SELECT '10e400'::float8; -ERROR: "10e400" is out of range for type double precision -LINE 1: SELECT '10e400'::float8; - ^ -SELECT '-10e400'::float8; -ERROR: "-10e400" is out of range for type double precision -LINE 1: SELECT '-10e400'::float8; - ^ -SELECT '10e-400'::float8; -ERROR: "10e-400" is out of range for type double precision -LINE 1: SELECT '10e-400'::float8; - ^ -SELECT '-10e-400'::float8; -ERROR: "-10e-400" is out of range for type double precision -LINE 1: SELECT '-10e-400'::float8; - ^ --- bad input -INSERT INTO FLOAT8_TBL(f1) VALUES (''); -ERROR: invalid input syntax for type double precision: "" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (''); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for type double precision: " " -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' '); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); -ERROR: invalid input syntax for type double precision: "xyz" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); -ERROR: invalid input syntax for type double precision: "5.0.0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); -ERROR: invalid input syntax for type double precision: "5 . 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); -ERROR: invalid input syntax for type double precision: "5. 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); -ERROR: invalid input syntax for type double precision: " - 3" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); -ERROR: invalid input syntax for type double precision: "123 5" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); - ^ --- special inputs -SELECT 'NaN'::float8; - float8 --------- - NaN -(1 row) - -SELECT 'nan'::float8; - float8 --------- - NaN -(1 row) - -SELECT ' NAN '::float8; - float8 --------- - NaN -(1 row) - -SELECT 'infinity'::float8; - float8 ----------- - Infinity -(1 row) - -SELECT ' -INFINiTY '::float8; - float8 ------------ - -Infinity -(1 row) - --- bad special inputs -SELECT 'N A N'::float8; -ERROR: invalid input syntax for type double precision: "N A N" -LINE 1: SELECT 'N A N'::float8; - ^ -SELECT 'NaN x'::float8; -ERROR: invalid input syntax for type double precision: "NaN x" -LINE 1: SELECT 'NaN x'::float8; - ^ -SELECT ' INFINITY x'::float8; -ERROR: invalid input syntax for type double precision: " INFINITY x" -LINE 1: SELECT ' INFINITY x'::float8; - ^ -SELECT 'Infinity'::float8 + 100.0; - ?column? ----------- - Infinity -(1 row) - -SELECT 'Infinity'::float8 / 'Infinity'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::float8 / 'nan'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::numeric::float8; - float8 --------- - NaN -(1 row) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3'; - four | f1 -------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3'; - one | f1 ------+-------- - | 1004.3 -(1 row) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3'; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3'; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS three, f.f1, f.f1 * '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -10043 - | 1.2345678901234e+200 | -1.2345678901234e+201 - | 1.2345678901234e-200 | -1.2345678901234e-199 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 + '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 994.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | -10 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 / '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -100.43 - | 1.2345678901234e+200 | -1.2345678901234e+199 - | 1.2345678901234e-200 | -1.2345678901234e-201 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 - '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 1014.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 10 -(3 rows) - -SELECT '' AS one, f.f1 ^ '2.0' AS square_f1 - FROM FLOAT8_TBL f where f.f1 = '1004.3'; - one | square_f1 ------+------------ - | 1008618.49 -(1 row) - --- absolute value -SELECT '' AS five, f.f1, @f.f1 AS abs_f1 - FROM FLOAT8_TBL f; - five | f1 | abs_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004.3 - | -34.84 | 34.84 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 1.2345678901234e-200 -(5 rows) - --- truncate -SELECT '' AS five, f.f1, trunc(f.f1) AS trunc_f1 - FROM FLOAT8_TBL f; - five | f1 | trunc_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -34 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- round -SELECT '' AS five, f.f1, round(f.f1) AS round_f1 - FROM FLOAT8_TBL f; - five | f1 | round_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -35 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- ceil / ceiling -select ceil(f1) as ceil_f1 from float8_tbl f; - ceil_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - -select ceiling(f1) as ceiling_f1 from float8_tbl f; - ceiling_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - --- floor -select floor(f1) as floor_f1 from float8_tbl f; - floor_f1 ----------------------- - 0 - 1004 - -35 - 1.2345678901234e+200 - 0 -(5 rows) - --- sign -select sign(f1) as sign_f1 from float8_tbl f; - sign_f1 ---------- - 0 - 1 - -1 - 1 - 1 -(5 rows) - --- square root -SELECT sqrt(float8 '64') AS eight; - eight -------- - 8 -(1 row) - -SELECT |/ float8 '64' AS eight; - eight -------- - 8 -(1 row) - -SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | sqrt_f1 --------+----------------------+----------------------- - | 1004.3 | 31.6906926399535 - | 1.2345678901234e+200 | 1.11111110611109e+100 - | 1.2345678901234e-200 | 1.11111110611109e-100 -(3 rows) - --- power -SELECT power(float8 '144', float8 '0.5'); - power -------- - 12 -(1 row) - --- take exp of ln(f.f1) -SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | exp_ln_f1 --------+----------------------+----------------------- - | 1004.3 | 1004.3 - | 1.2345678901234e+200 | 1.23456789012338e+200 - | 1.2345678901234e-200 | 1.23456789012339e-200 -(3 rows) - --- cube root -SELECT ||/ float8 '27' AS three; - three -------- - 3 -(1 row) - -SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f; - five | f1 | cbrt_f1 -------+----------------------+----------------------- - | 0 | 0 - | 1004.3 | 10.014312837827 - | -34.84 | -3.26607421344208 - | 1.2345678901234e+200 | 4.97933859234765e+066 - | 1.2345678901234e-200 | 2.3112042409018e-067 -(5 rows) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -UPDATE FLOAT8_TBL - SET f1 = FLOAT8_TBL.f1 * '-1' - WHERE FLOAT8_TBL.f1 > '0.0'; -SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; - ?column? ----------- - 2 -(1 row) - -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; -ERROR: cannot take logarithm of zero -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ; -ERROR: cannot take logarithm of a negative number -SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f; -ERROR: value out of range: underflow -SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f; -ERROR: division by zero -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test for over- and underflow -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); -ERROR: "10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); -ERROR: "-10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400'); -ERROR: "10e-400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400'); -ERROR: "-10e-400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400'); - ^ --- maintain external table consistency across platforms --- delete all values and reinsert well-behaved ones -DELETE FROM FLOAT8_TBL; -INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1004.30'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200'); -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test exact cases for trigonometric functions in degrees -SET extra_float_digits = 3; -SELECT x, - sind(x), - sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact -FROM (VALUES (0), (30), (90), (150), (180), - (210), (270), (330), (360)) AS t(x); - x | sind | sind_exact ------+------+------------ - 0 | 0 | t - 30 | 0.5 | t - 90 | 1 | t - 150 | 0.5 | t - 180 | 0 | t - 210 | -0.5 | t - 270 | -1 | t - 330 | -0.5 | t - 360 | 0 | t -(9 rows) - -SELECT x, - cosd(x), - cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact -FROM (VALUES (0), (60), (90), (120), (180), - (240), (270), (300), (360)) AS t(x); - x | cosd | cosd_exact ------+------+------------ - 0 | 1 | t - 60 | 0.5 | t - 90 | 0 | t - 120 | -0.5 | t - 180 | -1 | t - 240 | -0.5 | t - 270 | 0 | t - 300 | 0.5 | t - 360 | 1 | t -(9 rows) - -SELECT x, - tand(x), - tand(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS tand_exact, - cotd(x), - cotd(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS cotd_exact -FROM (VALUES (0), (45), (90), (135), (180), - (225), (270), (315), (360)) AS t(x); - x | tand | tand_exact | cotd | cotd_exact ------+-----------+------------+-----------+------------ - 0 | 0 | t | Infinity | t - 45 | 1 | t | 1 | t - 90 | Infinity | t | 0 | t - 135 | -1 | t | -1 | t - 180 | 0 | t | -Infinity | t - 225 | 1 | t | 1 | t - 270 | -Infinity | t | 0 | t - 315 | -1 | t | -1 | t - 360 | 0 | t | Infinity | t -(9 rows) - -SELECT x, - asind(x), - asind(x) IN (-90,-30,0,30,90) AS asind_exact, - acosd(x), - acosd(x) IN (0,60,90,120,180) AS acosd_exact -FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x); - x | asind | asind_exact | acosd | acosd_exact -------+-------+-------------+-------+------------- - -1 | -90 | t | 180 | t - -0.5 | -30 | t | 120 | t - 0 | 0 | t | 90 | t - 0.5 | 30 | t | 60 | t - 1 | 90 | t | 0 | t -(5 rows) - -SELECT x, - atand(x), - atand(x) IN (-90,-45,0,45,90) AS atand_exact -FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), - ('Infinity'::float8)) AS t(x); - x | atand | atand_exact ------------+-------+------------- - -Infinity | -90 | t - -1 | -45 | t - 0 | 0 | t - 1 | 45 | t - Infinity | 90 | t -(5 rows) - -SELECT x, y, - atan2d(y, x), - atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact -FROM (SELECT 10*cosd(a), 10*sind(a) - FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y); - x | y | atan2d | atan2d_exact ------+-----+--------+-------------- - 10 | 0 | 0 | t - 0 | 10 | 90 | t - -10 | 0 | 180 | t - 0 | -10 | -90 | t - 10 | 0 | 0 | t -(5 rows) - -RESET extra_float_digits; diff --git a/src/test/regress/expected/float8-small-is-zero.out b/src/test/regress/expected/float8-small-is-zero.out deleted file mode 100644 index 26b83781500..00000000000 --- a/src/test/regress/expected/float8-small-is-zero.out +++ /dev/null @@ -1,548 +0,0 @@ --- --- FLOAT8 --- -CREATE TABLE FLOAT8_TBL(f1 float8); -INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 '); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 '); -INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200'); --- test for underflow and overflow handling -SELECT '10e400'::float8; -ERROR: "10e400" is out of range for type double precision -LINE 1: SELECT '10e400'::float8; - ^ -SELECT '-10e400'::float8; -ERROR: "-10e400" is out of range for type double precision -LINE 1: SELECT '-10e400'::float8; - ^ -SELECT '10e-400'::float8; - float8 --------- - 0 -(1 row) - -SELECT '-10e-400'::float8; - float8 --------- - -0 -(1 row) - --- bad input -INSERT INTO FLOAT8_TBL(f1) VALUES (''); -ERROR: invalid input syntax for type double precision: "" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (''); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for type double precision: " " -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' '); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); -ERROR: invalid input syntax for type double precision: "xyz" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); -ERROR: invalid input syntax for type double precision: "5.0.0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); -ERROR: invalid input syntax for type double precision: "5 . 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); -ERROR: invalid input syntax for type double precision: "5. 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); -ERROR: invalid input syntax for type double precision: " - 3" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); -ERROR: invalid input syntax for type double precision: "123 5" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); - ^ --- special inputs -SELECT 'NaN'::float8; - float8 --------- - NaN -(1 row) - -SELECT 'nan'::float8; - float8 --------- - NaN -(1 row) - -SELECT ' NAN '::float8; - float8 --------- - NaN -(1 row) - -SELECT 'infinity'::float8; - float8 ----------- - Infinity -(1 row) - -SELECT ' -INFINiTY '::float8; - float8 ------------ - -Infinity -(1 row) - --- bad special inputs -SELECT 'N A N'::float8; -ERROR: invalid input syntax for type double precision: "N A N" -LINE 1: SELECT 'N A N'::float8; - ^ -SELECT 'NaN x'::float8; -ERROR: invalid input syntax for type double precision: "NaN x" -LINE 1: SELECT 'NaN x'::float8; - ^ -SELECT ' INFINITY x'::float8; -ERROR: invalid input syntax for type double precision: " INFINITY x" -LINE 1: SELECT ' INFINITY x'::float8; - ^ -SELECT 'Infinity'::float8 + 100.0; - ?column? ----------- - Infinity -(1 row) - -SELECT 'Infinity'::float8 / 'Infinity'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::float8 / 'nan'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::numeric::float8; - float8 --------- - NaN -(1 row) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3'; - four | f1 -------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3'; - one | f1 ------+-------- - | 1004.3 -(1 row) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3'; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3'; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS three, f.f1, f.f1 * '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -10043 - | 1.2345678901234e+200 | -1.2345678901234e+201 - | 1.2345678901234e-200 | -1.2345678901234e-199 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 + '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 994.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | -10 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 / '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -100.43 - | 1.2345678901234e+200 | -1.2345678901234e+199 - | 1.2345678901234e-200 | -1.2345678901234e-201 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 - '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 1014.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 10 -(3 rows) - -SELECT '' AS one, f.f1 ^ '2.0' AS square_f1 - FROM FLOAT8_TBL f where f.f1 = '1004.3'; - one | square_f1 ------+------------ - | 1008618.49 -(1 row) - --- absolute value -SELECT '' AS five, f.f1, @f.f1 AS abs_f1 - FROM FLOAT8_TBL f; - five | f1 | abs_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004.3 - | -34.84 | 34.84 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 1.2345678901234e-200 -(5 rows) - --- truncate -SELECT '' AS five, f.f1, trunc(f.f1) AS trunc_f1 - FROM FLOAT8_TBL f; - five | f1 | trunc_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -34 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- round -SELECT '' AS five, f.f1, round(f.f1) AS round_f1 - FROM FLOAT8_TBL f; - five | f1 | round_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -35 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- ceil / ceiling -select ceil(f1) as ceil_f1 from float8_tbl f; - ceil_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - -select ceiling(f1) as ceiling_f1 from float8_tbl f; - ceiling_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - --- floor -select floor(f1) as floor_f1 from float8_tbl f; - floor_f1 ----------------------- - 0 - 1004 - -35 - 1.2345678901234e+200 - 0 -(5 rows) - --- sign -select sign(f1) as sign_f1 from float8_tbl f; - sign_f1 ---------- - 0 - 1 - -1 - 1 - 1 -(5 rows) - --- square root -SELECT sqrt(float8 '64') AS eight; - eight -------- - 8 -(1 row) - -SELECT |/ float8 '64' AS eight; - eight -------- - 8 -(1 row) - -SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | sqrt_f1 --------+----------------------+----------------------- - | 1004.3 | 31.6906926399535 - | 1.2345678901234e+200 | 1.11111110611109e+100 - | 1.2345678901234e-200 | 1.11111110611109e-100 -(3 rows) - --- power -SELECT power(float8 '144', float8 '0.5'); - power -------- - 12 -(1 row) - --- take exp of ln(f.f1) -SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | exp_ln_f1 --------+----------------------+----------------------- - | 1004.3 | 1004.3 - | 1.2345678901234e+200 | 1.23456789012338e+200 - | 1.2345678901234e-200 | 1.23456789012339e-200 -(3 rows) - --- cube root -SELECT ||/ float8 '27' AS three; - three -------- - 3 -(1 row) - -SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f; - five | f1 | cbrt_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 10.014312837827 - | -34.84 | -3.26607421344208 - | 1.2345678901234e+200 | 4.97933859234765e+66 - | 1.2345678901234e-200 | 2.3112042409018e-67 -(5 rows) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -UPDATE FLOAT8_TBL - SET f1 = FLOAT8_TBL.f1 * '-1' - WHERE FLOAT8_TBL.f1 > '0.0'; -SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; - ?column? ----------- - 2 -(1 row) - -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; -ERROR: cannot take logarithm of zero -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ; -ERROR: cannot take logarithm of a negative number -SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f; -ERROR: value out of range: underflow -SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f; -ERROR: division by zero -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test for over- and underflow -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); -ERROR: "10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); -ERROR: "-10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400'); --- maintain external table consistency across platforms --- delete all values and reinsert well-behaved ones -DELETE FROM FLOAT8_TBL; -INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1004.30'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200'); -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test exact cases for trigonometric functions in degrees -SET extra_float_digits = 3; -SELECT x, - sind(x), - sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact -FROM (VALUES (0), (30), (90), (150), (180), - (210), (270), (330), (360)) AS t(x); - x | sind | sind_exact ------+------+------------ - 0 | 0 | t - 30 | 0.5 | t - 90 | 1 | t - 150 | 0.5 | t - 180 | 0 | t - 210 | -0.5 | t - 270 | -1 | t - 330 | -0.5 | t - 360 | 0 | t -(9 rows) - -SELECT x, - cosd(x), - cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact -FROM (VALUES (0), (60), (90), (120), (180), - (240), (270), (300), (360)) AS t(x); - x | cosd | cosd_exact ------+------+------------ - 0 | 1 | t - 60 | 0.5 | t - 90 | 0 | t - 120 | -0.5 | t - 180 | -1 | t - 240 | -0.5 | t - 270 | 0 | t - 300 | 0.5 | t - 360 | 1 | t -(9 rows) - -SELECT x, - tand(x), - tand(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS tand_exact, - cotd(x), - cotd(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS cotd_exact -FROM (VALUES (0), (45), (90), (135), (180), - (225), (270), (315), (360)) AS t(x); - x | tand | tand_exact | cotd | cotd_exact ------+-----------+------------+-----------+------------ - 0 | 0 | t | Infinity | t - 45 | 1 | t | 1 | t - 90 | Infinity | t | 0 | t - 135 | -1 | t | -1 | t - 180 | 0 | t | -Infinity | t - 225 | 1 | t | 1 | t - 270 | -Infinity | t | 0 | t - 315 | -1 | t | -1 | t - 360 | 0 | t | Infinity | t -(9 rows) - -SELECT x, - asind(x), - asind(x) IN (-90,-30,0,30,90) AS asind_exact, - acosd(x), - acosd(x) IN (0,60,90,120,180) AS acosd_exact -FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x); - x | asind | asind_exact | acosd | acosd_exact -------+-------+-------------+-------+------------- - -1 | -90 | t | 180 | t - -0.5 | -30 | t | 120 | t - 0 | 0 | t | 90 | t - 0.5 | 30 | t | 60 | t - 1 | 90 | t | 0 | t -(5 rows) - -SELECT x, - atand(x), - atand(x) IN (-90,-45,0,45,90) AS atand_exact -FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), - ('Infinity'::float8)) AS t(x); - x | atand | atand_exact ------------+-------+------------- - -Infinity | -90 | t - -1 | -45 | t - 0 | 0 | t - 1 | 45 | t - Infinity | 90 | t -(5 rows) - -SELECT x, y, - atan2d(y, x), - atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact -FROM (SELECT 10*cosd(a), 10*sind(a) - FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y); - x | y | atan2d | atan2d_exact ------+-----+--------+-------------- - 10 | 0 | 0 | t - 0 | 10 | 90 | t - -10 | 0 | 180 | t - 0 | -10 | -90 | t - 10 | 0 | 0 | t -(5 rows) - -RESET extra_float_digits; diff --git a/src/test/regress/expected/float8-small-is-zero_1.out b/src/test/regress/expected/float8-small-is-zero_1.out deleted file mode 100644 index cea27908ebf..00000000000 --- a/src/test/regress/expected/float8-small-is-zero_1.out +++ /dev/null @@ -1,548 +0,0 @@ --- --- FLOAT8 --- -CREATE TABLE FLOAT8_TBL(f1 float8); -INSERT INTO FLOAT8_TBL(f1) VALUES (' 0.0 '); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1004.30 '); -INSERT INTO FLOAT8_TBL(f1) VALUES (' -34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('1.2345678901234e-200'); --- test for underflow and overflow handling -SELECT '10e400'::float8; -ERROR: "10e400" is out of range for type double precision -LINE 1: SELECT '10e400'::float8; - ^ -SELECT '-10e400'::float8; -ERROR: "-10e400" is out of range for type double precision -LINE 1: SELECT '-10e400'::float8; - ^ -SELECT '10e-400'::float8; - float8 --------- - 0 -(1 row) - -SELECT '-10e-400'::float8; - float8 --------- - 0 -(1 row) - --- bad input -INSERT INTO FLOAT8_TBL(f1) VALUES (''); -ERROR: invalid input syntax for type double precision: "" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (''); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for type double precision: " " -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' '); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); -ERROR: invalid input syntax for type double precision: "xyz" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('xyz'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); -ERROR: invalid input syntax for type double precision: "5.0.0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5.0.0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); -ERROR: invalid input syntax for type double precision: "5 . 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5 . 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); -ERROR: invalid input syntax for type double precision: "5. 0" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('5. 0'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); -ERROR: invalid input syntax for type double precision: " - 3" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES (' - 3'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); -ERROR: invalid input syntax for type double precision: "123 5" -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('123 5'); - ^ --- special inputs -SELECT 'NaN'::float8; - float8 --------- - NaN -(1 row) - -SELECT 'nan'::float8; - float8 --------- - NaN -(1 row) - -SELECT ' NAN '::float8; - float8 --------- - NaN -(1 row) - -SELECT 'infinity'::float8; - float8 ----------- - Infinity -(1 row) - -SELECT ' -INFINiTY '::float8; - float8 ------------ - -Infinity -(1 row) - --- bad special inputs -SELECT 'N A N'::float8; -ERROR: invalid input syntax for type double precision: "N A N" -LINE 1: SELECT 'N A N'::float8; - ^ -SELECT 'NaN x'::float8; -ERROR: invalid input syntax for type double precision: "NaN x" -LINE 1: SELECT 'NaN x'::float8; - ^ -SELECT ' INFINITY x'::float8; -ERROR: invalid input syntax for type double precision: " INFINITY x" -LINE 1: SELECT ' INFINITY x'::float8; - ^ -SELECT 'Infinity'::float8 + 100.0; - ?column? ----------- - Infinity -(1 row) - -SELECT 'Infinity'::float8 / 'Infinity'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::float8 / 'nan'::float8; - ?column? ----------- - NaN -(1 row) - -SELECT 'nan'::numeric::float8; - float8 --------- - NaN -(1 row) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <> '1004.3'; - four | f1 -------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS one, f.* FROM FLOAT8_TBL f WHERE f.f1 = '1004.3'; - one | f1 ------+-------- - | 1004.3 -(1 row) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE '1004.3' > f.f1; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS three, f.* FROM FLOAT8_TBL f WHERE f.f1 < '1004.3'; - three | f1 --------+---------------------- - | 0 - | -34.84 - | 1.2345678901234e-200 -(3 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE '1004.3' >= f.f1; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS four, f.* FROM FLOAT8_TBL f WHERE f.f1 <= '1004.3'; - four | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e-200 -(4 rows) - -SELECT '' AS three, f.f1, f.f1 * '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -10043 - | 1.2345678901234e+200 | -1.2345678901234e+201 - | 1.2345678901234e-200 | -1.2345678901234e-199 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 + '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 994.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | -10 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 / '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+----------------------- - | 1004.3 | -100.43 - | 1.2345678901234e+200 | -1.2345678901234e+199 - | 1.2345678901234e-200 | -1.2345678901234e-201 -(3 rows) - -SELECT '' AS three, f.f1, f.f1 - '-10' AS x - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | x --------+----------------------+---------------------- - | 1004.3 | 1014.3 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 10 -(3 rows) - -SELECT '' AS one, f.f1 ^ '2.0' AS square_f1 - FROM FLOAT8_TBL f where f.f1 = '1004.3'; - one | square_f1 ------+------------ - | 1008618.49 -(1 row) - --- absolute value -SELECT '' AS five, f.f1, @f.f1 AS abs_f1 - FROM FLOAT8_TBL f; - five | f1 | abs_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004.3 - | -34.84 | 34.84 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 1.2345678901234e-200 -(5 rows) - --- truncate -SELECT '' AS five, f.f1, trunc(f.f1) AS trunc_f1 - FROM FLOAT8_TBL f; - five | f1 | trunc_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -34 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- round -SELECT '' AS five, f.f1, round(f.f1) AS round_f1 - FROM FLOAT8_TBL f; - five | f1 | round_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 1004 - | -34.84 | -35 - | 1.2345678901234e+200 | 1.2345678901234e+200 - | 1.2345678901234e-200 | 0 -(5 rows) - --- ceil / ceiling -select ceil(f1) as ceil_f1 from float8_tbl f; - ceil_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - -select ceiling(f1) as ceiling_f1 from float8_tbl f; - ceiling_f1 ----------------------- - 0 - 1005 - -34 - 1.2345678901234e+200 - 1 -(5 rows) - --- floor -select floor(f1) as floor_f1 from float8_tbl f; - floor_f1 ----------------------- - 0 - 1004 - -35 - 1.2345678901234e+200 - 0 -(5 rows) - --- sign -select sign(f1) as sign_f1 from float8_tbl f; - sign_f1 ---------- - 0 - 1 - -1 - 1 - 1 -(5 rows) - --- square root -SELECT sqrt(float8 '64') AS eight; - eight -------- - 8 -(1 row) - -SELECT |/ float8 '64' AS eight; - eight -------- - 8 -(1 row) - -SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | sqrt_f1 --------+----------------------+----------------------- - | 1004.3 | 31.6906926399535 - | 1.2345678901234e+200 | 1.11111110611109e+100 - | 1.2345678901234e-200 | 1.11111110611109e-100 -(3 rows) - --- power -SELECT power(float8 '144', float8 '0.5'); - power -------- - 12 -(1 row) - --- take exp of ln(f.f1) -SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 - FROM FLOAT8_TBL f - WHERE f.f1 > '0.0'; - three | f1 | exp_ln_f1 --------+----------------------+----------------------- - | 1004.3 | 1004.3 - | 1.2345678901234e+200 | 1.23456789012338e+200 - | 1.2345678901234e-200 | 1.23456789012339e-200 -(3 rows) - --- cube root -SELECT ||/ float8 '27' AS three; - three -------- - 3 -(1 row) - -SELECT '' AS five, f.f1, ||/f.f1 AS cbrt_f1 FROM FLOAT8_TBL f; - five | f1 | cbrt_f1 -------+----------------------+---------------------- - | 0 | 0 - | 1004.3 | 10.014312837827 - | -34.84 | -3.26607421344208 - | 1.2345678901234e+200 | 4.97933859234765e+66 - | 1.2345678901234e-200 | 2.3112042409018e-67 -(5 rows) - -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+---------------------- - | 0 - | 1004.3 - | -34.84 - | 1.2345678901234e+200 - | 1.2345678901234e-200 -(5 rows) - -UPDATE FLOAT8_TBL - SET f1 = FLOAT8_TBL.f1 * '-1' - WHERE FLOAT8_TBL.f1 > '0.0'; -SELECT '' AS bad, f.f1 * '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT '' AS bad, f.f1 ^ '1e200' from FLOAT8_TBL f; -ERROR: value out of range: overflow -SELECT 0 ^ 0 + 0 ^ 1 + 0 ^ 0.0 + 0 ^ 0.5; - ?column? ----------- - 2 -(1 row) - -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 = '0.0' ; -ERROR: cannot take logarithm of zero -SELECT '' AS bad, ln(f.f1) from FLOAT8_TBL f where f.f1 < '0.0' ; -ERROR: cannot take logarithm of a negative number -SELECT '' AS bad, exp(f.f1) from FLOAT8_TBL f; -ERROR: value out of range: underflow -SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f; -ERROR: division by zero -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test for over- and underflow -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); -ERROR: "10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); -ERROR: "-10e400" is out of range for type double precision -LINE 1: INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e400'); - ^ -INSERT INTO FLOAT8_TBL(f1) VALUES ('10e-400'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-10e-400'); --- maintain external table consistency across platforms --- delete all values and reinsert well-behaved ones -DELETE FROM FLOAT8_TBL; -INSERT INTO FLOAT8_TBL(f1) VALUES ('0.0'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-34.84'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1004.30'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e+200'); -INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200'); -SELECT '' AS five, * FROM FLOAT8_TBL; - five | f1 -------+----------------------- - | 0 - | -34.84 - | -1004.3 - | -1.2345678901234e+200 - | -1.2345678901234e-200 -(5 rows) - --- test exact cases for trigonometric functions in degrees -SET extra_float_digits = 3; -SELECT x, - sind(x), - sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact -FROM (VALUES (0), (30), (90), (150), (180), - (210), (270), (330), (360)) AS t(x); - x | sind | sind_exact ------+------+------------ - 0 | 0 | t - 30 | 0.5 | t - 90 | 1 | t - 150 | 0.5 | t - 180 | 0 | t - 210 | -0.5 | t - 270 | -1 | t - 330 | -0.5 | t - 360 | 0 | t -(9 rows) - -SELECT x, - cosd(x), - cosd(x) IN (-1,-0.5,0,0.5,1) AS cosd_exact -FROM (VALUES (0), (60), (90), (120), (180), - (240), (270), (300), (360)) AS t(x); - x | cosd | cosd_exact ------+------+------------ - 0 | 1 | t - 60 | 0.5 | t - 90 | 0 | t - 120 | -0.5 | t - 180 | -1 | t - 240 | -0.5 | t - 270 | 0 | t - 300 | 0.5 | t - 360 | 1 | t -(9 rows) - -SELECT x, - tand(x), - tand(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS tand_exact, - cotd(x), - cotd(x) IN ('-Infinity'::float8,-1,0, - 1,'Infinity'::float8) AS cotd_exact -FROM (VALUES (0), (45), (90), (135), (180), - (225), (270), (315), (360)) AS t(x); - x | tand | tand_exact | cotd | cotd_exact ------+-----------+------------+-----------+------------ - 0 | 0 | t | Infinity | t - 45 | 1 | t | 1 | t - 90 | Infinity | t | 0 | t - 135 | -1 | t | -1 | t - 180 | 0 | t | -Infinity | t - 225 | 1 | t | 1 | t - 270 | -Infinity | t | 0 | t - 315 | -1 | t | -1 | t - 360 | 0 | t | Infinity | t -(9 rows) - -SELECT x, - asind(x), - asind(x) IN (-90,-30,0,30,90) AS asind_exact, - acosd(x), - acosd(x) IN (0,60,90,120,180) AS acosd_exact -FROM (VALUES (-1), (-0.5), (0), (0.5), (1)) AS t(x); - x | asind | asind_exact | acosd | acosd_exact -------+-------+-------------+-------+------------- - -1 | -90 | t | 180 | t - -0.5 | -30 | t | 120 | t - 0 | 0 | t | 90 | t - 0.5 | 30 | t | 60 | t - 1 | 90 | t | 0 | t -(5 rows) - -SELECT x, - atand(x), - atand(x) IN (-90,-45,0,45,90) AS atand_exact -FROM (VALUES ('-Infinity'::float8), (-1), (0), (1), - ('Infinity'::float8)) AS t(x); - x | atand | atand_exact ------------+-------+------------- - -Infinity | -90 | t - -1 | -45 | t - 0 | 0 | t - 1 | 45 | t - Infinity | 90 | t -(5 rows) - -SELECT x, y, - atan2d(y, x), - atan2d(y, x) IN (-90,0,90,180) AS atan2d_exact -FROM (SELECT 10*cosd(a), 10*sind(a) - FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y); - x | y | atan2d | atan2d_exact ------+-----+--------+-------------- - 10 | 0 | 0 | t - 0 | 10 | 90 | t - -10 | 0 | 180 | t - 0 | -10 | -90 | t - 10 | 0 | 0 | t -(5 rows) - -RESET extra_float_digits; diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out index 20c985e5df8..aaef20bcfdc 100644 --- a/src/test/regress/expected/float8.out +++ b/src/test/regress/expected/float8.out @@ -24,6 +24,13 @@ SELECT '-10e-400'::float8; ERROR: "-10e-400" is out of range for type double precision LINE 1: SELECT '-10e-400'::float8; ^ +-- test smallest normalized input +SELECT float8send('2.2250738585072014E-308'::float8); + float8send +-------------------- + \x0010000000000000 +(1 row) + -- bad input INSERT INTO FLOAT8_TBL(f1) VALUES (''); ERROR: invalid input syntax for type double precision: "" @@ -209,7 +216,7 @@ SELECT '' AS three, f.f1, f.f1 / '-10' AS x WHERE f.f1 > '0.0'; three | f1 | x -------+----------------------+----------------------- - | 1004.3 | -100.43 + | 1004.3 | -100.42999999999999 | 1.2345678901234e+200 | -1.2345678901234e+199 | 1.2345678901234e-200 | -1.2345678901234e-201 (3 rows) @@ -226,9 +233,9 @@ SELECT '' AS three, f.f1, f.f1 - '-10' AS x SELECT '' AS one, f.f1 ^ '2.0' AS square_f1 FROM FLOAT8_TBL f where f.f1 = '1004.3'; - one | square_f1 ------+------------ - | 1008618.49 + one | square_f1 +-----+-------------------- + | 1008618.4899999999 (1 row) -- absolute value @@ -310,6 +317,8 @@ select sign(f1) as sign_f1 from float8_tbl f; 1 (5 rows) +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; -- square root SELECT sqrt(float8 '64') AS eight; eight @@ -340,6 +349,42 @@ SELECT power(float8 '144', float8 '0.5'); 12 (1 row) +SELECT power(float8 'NaN', float8 '0.5'); + power +------- + NaN +(1 row) + +SELECT power(float8 '144', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 'NaN', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '-1', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '1', float8 'NaN'); + power +------- + 1 +(1 row) + +SELECT power(float8 'NaN', float8 '0'); + power +------- + 1 +(1 row) + -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM FLOAT8_TBL f @@ -409,6 +454,139 @@ SELECT '' AS five, * FROM FLOAT8_TBL; | -1.2345678901234e-200 (5 rows) +-- hyperbolic functions +-- we run these with extra_float_digits = 0 too, since different platforms +-- tend to produce results that vary in the last place. +SELECT sinh(float8 '1'); + sinh +----------------- + 1.1752011936438 +(1 row) + +SELECT cosh(float8 '1'); + cosh +------------------ + 1.54308063481524 +(1 row) + +SELECT tanh(float8 '1'); + tanh +------------------- + 0.761594155955765 +(1 row) + +SELECT asinh(float8 '1'); + asinh +------------------- + 0.881373587019543 +(1 row) + +SELECT acosh(float8 '2'); + acosh +------------------ + 1.31695789692482 +(1 row) + +SELECT atanh(float8 '0.5'); + atanh +------------------- + 0.549306144334055 +(1 row) + +-- test Inf/NaN cases for hyperbolic functions +SELECT sinh(float8 'infinity'); + sinh +---------- + Infinity +(1 row) + +SELECT sinh(float8 '-infinity'); + sinh +----------- + -Infinity +(1 row) + +SELECT sinh(float8 'nan'); + sinh +------ + NaN +(1 row) + +SELECT cosh(float8 'infinity'); + cosh +---------- + Infinity +(1 row) + +SELECT cosh(float8 '-infinity'); + cosh +---------- + Infinity +(1 row) + +SELECT cosh(float8 'nan'); + cosh +------ + NaN +(1 row) + +SELECT tanh(float8 'infinity'); + tanh +------ + 1 +(1 row) + +SELECT tanh(float8 '-infinity'); + tanh +------ + -1 +(1 row) + +SELECT tanh(float8 'nan'); + tanh +------ + NaN +(1 row) + +SELECT asinh(float8 'infinity'); + asinh +---------- + Infinity +(1 row) + +SELECT asinh(float8 '-infinity'); + asinh +----------- + -Infinity +(1 row) + +SELECT asinh(float8 'nan'); + asinh +------- + NaN +(1 row) + +-- acosh(Inf) should be Inf, but some mingw versions produce NaN, so skip test +-- SELECT acosh(float8 'infinity'); +SELECT acosh(float8 '-infinity'); +ERROR: input is out of range +SELECT acosh(float8 'nan'); + acosh +------- + NaN +(1 row) + +SELECT atanh(float8 'infinity'); +ERROR: input is out of range +SELECT atanh(float8 '-infinity'); +ERROR: input is out of range +SELECT atanh(float8 'nan'); + atanh +------- + NaN +(1 row) + +RESET extra_float_digits; -- test for over- and underflow INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); ERROR: "10e400" is out of range for type double precision @@ -444,8 +622,56 @@ SELECT '' AS five, * FROM FLOAT8_TBL; | -1.2345678901234e-200 (5 rows) +-- test edge-case coercions to integer +SELECT '32767.4'::float8::int2; + int2 +------- + 32767 +(1 row) + +SELECT '32767.6'::float8::int2; +ERROR: smallint out of range +SELECT '-32768.4'::float8::int2; + int2 +-------- + -32768 +(1 row) + +SELECT '-32768.6'::float8::int2; +ERROR: smallint out of range +SELECT '2147483647.4'::float8::int4; + int4 +------------ + 2147483647 +(1 row) + +SELECT '2147483647.6'::float8::int4; +ERROR: integer out of range +SELECT '-2147483648.4'::float8::int4; + int4 +------------- + -2147483648 +(1 row) + +SELECT '-2147483648.6'::float8::int4; +ERROR: integer out of range +SELECT '9223372036854773760'::float8::int8; + int8 +--------------------- + 9223372036854773760 +(1 row) + +SELECT '9223372036854775807'::float8::int8; +ERROR: bigint out of range +SELECT '-9223372036854775808.5'::float8::int8; + int8 +---------------------- + -9223372036854775808 +(1 row) + +SELECT '-9223372036854780000'::float8::int8; +ERROR: bigint out of range -- test exact cases for trigonometric functions in degrees -SET extra_float_digits = 3; SELECT x, sind(x), sind(x) IN (-1,-0.5,0,0.5,1) AS sind_exact @@ -547,4 +773,435 @@ FROM (SELECT 10*cosd(a), 10*sind(a) 10 | 0 | 0 | t (5 rows) -RESET extra_float_digits; +-- +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). +create type xfloat8; +create function xfloat8in(cstring) returns xfloat8 immutable strict + language internal as 'int8in'; +NOTICE: return type xfloat8 is only a shell +create function xfloat8out(xfloat8) returns cstring immutable strict + language internal as 'int8out'; +NOTICE: argument type xfloat8 is only a shell +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8); +create cast (xfloat8 as float8) without function; +create cast (float8 as xfloat8) without function; +create cast (xfloat8 as bigint) without function; +create cast (bigint as xfloat8) without function; +-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4) +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. +with testdata(bits) as (values + -- small subnormals + (x'0000000000000001'), + (x'0000000000000002'), (x'0000000000000003'), + (x'0000000000001000'), (x'0000000100000000'), + (x'0000010000000000'), (x'0000010100000000'), + (x'0000400000000000'), (x'0000400100000000'), + (x'0000800000000000'), (x'0000800000000001'), + -- these values taken from upstream testsuite + (x'00000000000f4240'), + (x'00000000016e3600'), + (x'0000008cdcdea440'), + -- borderline between subnormal and normal + (x'000ffffffffffff0'), (x'000ffffffffffff1'), + (x'000ffffffffffffe'), (x'000fffffffffffff')) +select float8send(flt) as ibits, + flt + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + ibits | flt +--------------------+------------------------- + \x0000000000000001 | 5e-324 + \x0000000000000002 | 1e-323 + \x0000000000000003 | 1.5e-323 + \x0000000000001000 | 2.0237e-320 + \x0000000100000000 | 2.121995791e-314 + \x0000010000000000 | 5.43230922487e-312 + \x0000010100000000 | 5.45352918278e-312 + \x0000400000000000 | 3.4766779039175e-310 + \x0000400100000000 | 3.4768901034966e-310 + \x0000800000000000 | 6.953355807835e-310 + \x0000800000000001 | 6.95335580783505e-310 + \x00000000000f4240 | 4.940656e-318 + \x00000000016e3600 | 1.18575755e-316 + \x0000008cdcdea440 | 2.989102097996e-312 + \x000ffffffffffff0 | 2.2250738585071935e-308 + \x000ffffffffffff1 | 2.225073858507194e-308 + \x000ffffffffffffe | 2.2250738585072004e-308 + \x000fffffffffffff | 2.225073858507201e-308 +(18 rows) + +-- round-trip tests +with testdata(bits) as (values + (x'0000000000000000'), + -- smallest normal values + (x'0010000000000000'), (x'0010000000000001'), + (x'0010000000000002'), (x'0018000000000000'), + -- + (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'), + (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'), + (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'), + (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'), + (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'), + (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'), + (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'), + (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'), + (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'), + (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'), + -- values very close to 1 + (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'), + (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'), + (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'), + (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'), + (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'), + (x'3fefffffffffffff'), + (x'3ff0000000000000'), + (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'), + (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'), + (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'), + -- + (x'3ff921fb54442d18'), + (x'4005bf0a8b14576a'), + (x'400921fb54442d18'), + -- + (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'), + (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'), + (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'), + (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'), + (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'), + (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'), + (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'), + (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'), + (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'), + (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'), + (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'), + (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'), + (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'), + (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'), + (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'), + (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'), + (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'), + (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'), + (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'), + (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'), + (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'), + (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'), + (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'), + (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'), + (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'), + -- + (x'7feffffffffffffe'), (x'7fefffffffffffff'), + -- round to even tests (+ve) + (x'4350000000000002'), + (x'4350000000002e06'), + (x'4352000000000003'), + (x'4352000000000004'), + (x'4358000000000003'), + (x'4358000000000004'), + (x'435f000000000020'), + -- round to even tests (-ve) + (x'c350000000000002'), + (x'c350000000002e06'), + (x'c352000000000003'), + (x'c352000000000004'), + (x'c358000000000003'), + (x'c358000000000004'), + (x'c35f000000000020'), + -- exercise fixed-point memmoves + (x'42dc12218377de66'), + (x'42a674e79c5fe51f'), + (x'4271f71fb04cb74c'), + (x'423cbe991a145879'), + (x'4206fee0e1a9e061'), + (x'41d26580b487e6b4'), + (x'419d6f34540ca453'), + (x'41678c29dcd6e9dc'), + (x'4132d687e3df217d'), + (x'40fe240c9fcb68c8'), + (x'40c81cd6e63c53d3'), + (x'40934a4584fd0fdc'), + (x'405edd3c07fb4c93'), + (x'4028b0fcd32f7076'), + (x'3ff3c0ca428c59f8'), + -- these cases come from the upstream's testsuite + -- LotsOfTrailingZeros) + (x'3e60000000000000'), + -- Regression + (x'c352bd2668e077c4'), + (x'434018601510c000'), + (x'43d055dc36f24000'), + (x'43e052961c6f8000'), + (x'3ff3c0ca2a5b1d5d'), + -- LooksLikePow5 + (x'4830f0cf064dd592'), + (x'4840f0cf064dd592'), + (x'4850f0cf064dd592'), + -- OutputLength + (x'3ff3333333333333'), + (x'3ff3ae147ae147ae'), + (x'3ff3be76c8b43958'), + (x'3ff3c083126e978d'), + (x'3ff3c0c1fc8f3238'), + (x'3ff3c0c9539b8887'), + (x'3ff3c0ca2a5b1d5d'), + (x'3ff3c0ca4283de1b'), + (x'3ff3c0ca43db770a'), + (x'3ff3c0ca428abd53'), + (x'3ff3c0ca428c1d2b'), + (x'3ff3c0ca428c51f2'), + (x'3ff3c0ca428c58fc'), + (x'3ff3c0ca428c59dd'), + (x'3ff3c0ca428c59f8'), + (x'3ff3c0ca428c59fb'), + -- 32-bit chunking + (x'40112e0be8047a7d'), + (x'40112e0be815a889'), + (x'40112e0be826d695'), + (x'40112e0be83804a1'), + (x'40112e0be84932ad'), + -- MinMaxShift + (x'0040000000000000'), + (x'007fffffffffffff'), + (x'0290000000000000'), + (x'029fffffffffffff'), + (x'4350000000000000'), + (x'435fffffffffffff'), + (x'1330000000000000'), + (x'133fffffffffffff'), + (x'3a6fa7161a4d6e0c') +) +select float8send(flt) as ibits, + flt, + flt::text::float8 as r_flt, + float8send(flt::text::float8) as obits, + float8send(flt::text::float8) = float8send(flt) as correct + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + ibits | flt | r_flt | obits | correct +--------------------+-------------------------+-------------------------+--------------------+--------- + \x0000000000000000 | 0 | 0 | \x0000000000000000 | t + \x0010000000000000 | 2.2250738585072014e-308 | 2.2250738585072014e-308 | \x0010000000000000 | t + \x0010000000000001 | 2.225073858507202e-308 | 2.225073858507202e-308 | \x0010000000000001 | t + \x0010000000000002 | 2.2250738585072024e-308 | 2.2250738585072024e-308 | \x0010000000000002 | t + \x0018000000000000 | 3.337610787760802e-308 | 3.337610787760802e-308 | \x0018000000000000 | t + \x3ddb7cdfd9d7bdba | 9.999999999999999e-11 | 9.999999999999999e-11 | \x3ddb7cdfd9d7bdba | t + \x3ddb7cdfd9d7bdbb | 1e-10 | 1e-10 | \x3ddb7cdfd9d7bdbb | t + \x3ddb7cdfd9d7bdbc | 1.0000000000000002e-10 | 1.0000000000000002e-10 | \x3ddb7cdfd9d7bdbc | t + \x3e112e0be826d694 | 9.999999999999999e-10 | 9.999999999999999e-10 | \x3e112e0be826d694 | t + \x3e112e0be826d695 | 1e-09 | 1e-09 | \x3e112e0be826d695 | t + \x3e112e0be826d696 | 1.0000000000000003e-09 | 1.0000000000000003e-09 | \x3e112e0be826d696 | t + \x3e45798ee2308c39 | 9.999999999999999e-09 | 9.999999999999999e-09 | \x3e45798ee2308c39 | t + \x3e45798ee2308c3a | 1e-08 | 1e-08 | \x3e45798ee2308c3a | t + \x3e45798ee2308c3b | 1.0000000000000002e-08 | 1.0000000000000002e-08 | \x3e45798ee2308c3b | t + \x3e7ad7f29abcaf47 | 9.999999999999998e-08 | 9.999999999999998e-08 | \x3e7ad7f29abcaf47 | t + \x3e7ad7f29abcaf48 | 1e-07 | 1e-07 | \x3e7ad7f29abcaf48 | t + \x3e7ad7f29abcaf49 | 1.0000000000000001e-07 | 1.0000000000000001e-07 | \x3e7ad7f29abcaf49 | t + \x3eb0c6f7a0b5ed8c | 9.999999999999997e-07 | 9.999999999999997e-07 | \x3eb0c6f7a0b5ed8c | t + \x3eb0c6f7a0b5ed8d | 1e-06 | 1e-06 | \x3eb0c6f7a0b5ed8d | t + \x3eb0c6f7a0b5ed8e | 1.0000000000000002e-06 | 1.0000000000000002e-06 | \x3eb0c6f7a0b5ed8e | t + \x3ee4f8b588e368ef | 9.999999999999997e-06 | 9.999999999999997e-06 | \x3ee4f8b588e368ef | t + \x3ee4f8b588e368f0 | 9.999999999999999e-06 | 9.999999999999999e-06 | \x3ee4f8b588e368f0 | t + \x3ee4f8b588e368f1 | 1e-05 | 1e-05 | \x3ee4f8b588e368f1 | t + \x3f1a36e2eb1c432c | 9.999999999999999e-05 | 9.999999999999999e-05 | \x3f1a36e2eb1c432c | t + \x3f1a36e2eb1c432d | 0.0001 | 0.0001 | \x3f1a36e2eb1c432d | t + \x3f1a36e2eb1c432e | 0.00010000000000000002 | 0.00010000000000000002 | \x3f1a36e2eb1c432e | t + \x3f50624dd2f1a9fb | 0.0009999999999999998 | 0.0009999999999999998 | \x3f50624dd2f1a9fb | t + \x3f50624dd2f1a9fc | 0.001 | 0.001 | \x3f50624dd2f1a9fc | t + \x3f50624dd2f1a9fd | 0.0010000000000000002 | 0.0010000000000000002 | \x3f50624dd2f1a9fd | t + \x3f847ae147ae147a | 0.009999999999999998 | 0.009999999999999998 | \x3f847ae147ae147a | t + \x3f847ae147ae147b | 0.01 | 0.01 | \x3f847ae147ae147b | t + \x3f847ae147ae147c | 0.010000000000000002 | 0.010000000000000002 | \x3f847ae147ae147c | t + \x3fb9999999999999 | 0.09999999999999999 | 0.09999999999999999 | \x3fb9999999999999 | t + \x3fb999999999999a | 0.1 | 0.1 | \x3fb999999999999a | t + \x3fb999999999999b | 0.10000000000000002 | 0.10000000000000002 | \x3fb999999999999b | t + \x3feffffffffffff0 | 0.9999999999999982 | 0.9999999999999982 | \x3feffffffffffff0 | t + \x3feffffffffffff1 | 0.9999999999999983 | 0.9999999999999983 | \x3feffffffffffff1 | t + \x3feffffffffffff2 | 0.9999999999999984 | 0.9999999999999984 | \x3feffffffffffff2 | t + \x3feffffffffffff3 | 0.9999999999999986 | 0.9999999999999986 | \x3feffffffffffff3 | t + \x3feffffffffffff4 | 0.9999999999999987 | 0.9999999999999987 | \x3feffffffffffff4 | t + \x3feffffffffffff5 | 0.9999999999999988 | 0.9999999999999988 | \x3feffffffffffff5 | t + \x3feffffffffffff6 | 0.9999999999999989 | 0.9999999999999989 | \x3feffffffffffff6 | t + \x3feffffffffffff7 | 0.999999999999999 | 0.999999999999999 | \x3feffffffffffff7 | t + \x3feffffffffffff8 | 0.9999999999999991 | 0.9999999999999991 | \x3feffffffffffff8 | t + \x3feffffffffffff9 | 0.9999999999999992 | 0.9999999999999992 | \x3feffffffffffff9 | t + \x3feffffffffffffa | 0.9999999999999993 | 0.9999999999999993 | \x3feffffffffffffa | t + \x3feffffffffffffb | 0.9999999999999994 | 0.9999999999999994 | \x3feffffffffffffb | t + \x3feffffffffffffc | 0.9999999999999996 | 0.9999999999999996 | \x3feffffffffffffc | t + \x3feffffffffffffd | 0.9999999999999997 | 0.9999999999999997 | \x3feffffffffffffd | t + \x3feffffffffffffe | 0.9999999999999998 | 0.9999999999999998 | \x3feffffffffffffe | t + \x3fefffffffffffff | 0.9999999999999999 | 0.9999999999999999 | \x3fefffffffffffff | t + \x3ff0000000000000 | 1 | 1 | \x3ff0000000000000 | t + \x3ff0000000000001 | 1.0000000000000002 | 1.0000000000000002 | \x3ff0000000000001 | t + \x3ff0000000000002 | 1.0000000000000004 | 1.0000000000000004 | \x3ff0000000000002 | t + \x3ff0000000000003 | 1.0000000000000007 | 1.0000000000000007 | \x3ff0000000000003 | t + \x3ff0000000000004 | 1.0000000000000009 | 1.0000000000000009 | \x3ff0000000000004 | t + \x3ff0000000000005 | 1.000000000000001 | 1.000000000000001 | \x3ff0000000000005 | t + \x3ff0000000000006 | 1.0000000000000013 | 1.0000000000000013 | \x3ff0000000000006 | t + \x3ff0000000000007 | 1.0000000000000016 | 1.0000000000000016 | \x3ff0000000000007 | t + \x3ff0000000000008 | 1.0000000000000018 | 1.0000000000000018 | \x3ff0000000000008 | t + \x3ff0000000000009 | 1.000000000000002 | 1.000000000000002 | \x3ff0000000000009 | t + \x3ff921fb54442d18 | 1.5707963267948966 | 1.5707963267948966 | \x3ff921fb54442d18 | t + \x4005bf0a8b14576a | 2.7182818284590455 | 2.7182818284590455 | \x4005bf0a8b14576a | t + \x400921fb54442d18 | 3.141592653589793 | 3.141592653589793 | \x400921fb54442d18 | t + \x4023ffffffffffff | 9.999999999999998 | 9.999999999999998 | \x4023ffffffffffff | t + \x4024000000000000 | 10 | 10 | \x4024000000000000 | t + \x4024000000000001 | 10.000000000000002 | 10.000000000000002 | \x4024000000000001 | t + \x4058ffffffffffff | 99.99999999999999 | 99.99999999999999 | \x4058ffffffffffff | t + \x4059000000000000 | 100 | 100 | \x4059000000000000 | t + \x4059000000000001 | 100.00000000000001 | 100.00000000000001 | \x4059000000000001 | t + \x408f3fffffffffff | 999.9999999999999 | 999.9999999999999 | \x408f3fffffffffff | t + \x408f400000000000 | 1000 | 1000 | \x408f400000000000 | t + \x408f400000000001 | 1000.0000000000001 | 1000.0000000000001 | \x408f400000000001 | t + \x40c387ffffffffff | 9999.999999999998 | 9999.999999999998 | \x40c387ffffffffff | t + \x40c3880000000000 | 10000 | 10000 | \x40c3880000000000 | t + \x40c3880000000001 | 10000.000000000002 | 10000.000000000002 | \x40c3880000000001 | t + \x40f869ffffffffff | 99999.99999999999 | 99999.99999999999 | \x40f869ffffffffff | t + \x40f86a0000000000 | 100000 | 100000 | \x40f86a0000000000 | t + \x40f86a0000000001 | 100000.00000000001 | 100000.00000000001 | \x40f86a0000000001 | t + \x412e847fffffffff | 999999.9999999999 | 999999.9999999999 | \x412e847fffffffff | t + \x412e848000000000 | 1000000 | 1000000 | \x412e848000000000 | t + \x412e848000000001 | 1000000.0000000001 | 1000000.0000000001 | \x412e848000000001 | t + \x416312cfffffffff | 9999999.999999998 | 9999999.999999998 | \x416312cfffffffff | t + \x416312d000000000 | 10000000 | 10000000 | \x416312d000000000 | t + \x416312d000000001 | 10000000.000000002 | 10000000.000000002 | \x416312d000000001 | t + \x4197d783ffffffff | 99999999.99999999 | 99999999.99999999 | \x4197d783ffffffff | t + \x4197d78400000000 | 100000000 | 100000000 | \x4197d78400000000 | t + \x4197d78400000001 | 100000000.00000001 | 100000000.00000001 | \x4197d78400000001 | t + \x41cdcd64ffffffff | 999999999.9999999 | 999999999.9999999 | \x41cdcd64ffffffff | t + \x41cdcd6500000000 | 1000000000 | 1000000000 | \x41cdcd6500000000 | t + \x41cdcd6500000001 | 1000000000.0000001 | 1000000000.0000001 | \x41cdcd6500000001 | t + \x4202a05f1fffffff | 9999999999.999998 | 9999999999.999998 | \x4202a05f1fffffff | t + \x4202a05f20000000 | 10000000000 | 10000000000 | \x4202a05f20000000 | t + \x4202a05f20000001 | 10000000000.000002 | 10000000000.000002 | \x4202a05f20000001 | t + \x42374876e7ffffff | 99999999999.99998 | 99999999999.99998 | \x42374876e7ffffff | t + \x42374876e8000000 | 100000000000 | 100000000000 | \x42374876e8000000 | t + \x42374876e8000001 | 100000000000.00002 | 100000000000.00002 | \x42374876e8000001 | t + \x426d1a94a1ffffff | 999999999999.9999 | 999999999999.9999 | \x426d1a94a1ffffff | t + \x426d1a94a2000000 | 1000000000000 | 1000000000000 | \x426d1a94a2000000 | t + \x426d1a94a2000001 | 1000000000000.0001 | 1000000000000.0001 | \x426d1a94a2000001 | t + \x42a2309ce53fffff | 9999999999999.998 | 9999999999999.998 | \x42a2309ce53fffff | t + \x42a2309ce5400000 | 10000000000000 | 10000000000000 | \x42a2309ce5400000 | t + \x42a2309ce5400001 | 10000000000000.002 | 10000000000000.002 | \x42a2309ce5400001 | t + \x42d6bcc41e8fffff | 99999999999999.98 | 99999999999999.98 | \x42d6bcc41e8fffff | t + \x42d6bcc41e900000 | 100000000000000 | 100000000000000 | \x42d6bcc41e900000 | t + \x42d6bcc41e900001 | 100000000000000.02 | 100000000000000.02 | \x42d6bcc41e900001 | t + \x430c6bf52633ffff | 999999999999999.9 | 999999999999999.9 | \x430c6bf52633ffff | t + \x430c6bf526340000 | 1e+15 | 1e+15 | \x430c6bf526340000 | t + \x430c6bf526340001 | 1.0000000000000001e+15 | 1.0000000000000001e+15 | \x430c6bf526340001 | t + \x4341c37937e07fff | 9.999999999999998e+15 | 9.999999999999998e+15 | \x4341c37937e07fff | t + \x4341c37937e08000 | 1e+16 | 1e+16 | \x4341c37937e08000 | t + \x4341c37937e08001 | 1.0000000000000002e+16 | 1.0000000000000002e+16 | \x4341c37937e08001 | t + \x4376345785d89fff | 9.999999999999998e+16 | 9.999999999999998e+16 | \x4376345785d89fff | t + \x4376345785d8a000 | 1e+17 | 1e+17 | \x4376345785d8a000 | t + \x4376345785d8a001 | 1.0000000000000002e+17 | 1.0000000000000002e+17 | \x4376345785d8a001 | t + \x43abc16d674ec7ff | 9.999999999999999e+17 | 9.999999999999999e+17 | \x43abc16d674ec7ff | t + \x43abc16d674ec800 | 1e+18 | 1e+18 | \x43abc16d674ec800 | t + \x43abc16d674ec801 | 1.0000000000000001e+18 | 1.0000000000000001e+18 | \x43abc16d674ec801 | t + \x43e158e460913cff | 9.999999999999998e+18 | 9.999999999999998e+18 | \x43e158e460913cff | t + \x43e158e460913d00 | 1e+19 | 1e+19 | \x43e158e460913d00 | t + \x43e158e460913d01 | 1.0000000000000002e+19 | 1.0000000000000002e+19 | \x43e158e460913d01 | t + \x4415af1d78b58c3f | 9.999999999999998e+19 | 9.999999999999998e+19 | \x4415af1d78b58c3f | t + \x4415af1d78b58c40 | 1e+20 | 1e+20 | \x4415af1d78b58c40 | t + \x4415af1d78b58c41 | 1.0000000000000002e+20 | 1.0000000000000002e+20 | \x4415af1d78b58c41 | t + \x444b1ae4d6e2ef4f | 9.999999999999999e+20 | 9.999999999999999e+20 | \x444b1ae4d6e2ef4f | t + \x444b1ae4d6e2ef50 | 1e+21 | 1e+21 | \x444b1ae4d6e2ef50 | t + \x444b1ae4d6e2ef51 | 1.0000000000000001e+21 | 1.0000000000000001e+21 | \x444b1ae4d6e2ef51 | t + \x4480f0cf064dd591 | 9.999999999999998e+21 | 9.999999999999998e+21 | \x4480f0cf064dd591 | t + \x4480f0cf064dd592 | 1e+22 | 1e+22 | \x4480f0cf064dd592 | t + \x4480f0cf064dd593 | 1.0000000000000002e+22 | 1.0000000000000002e+22 | \x4480f0cf064dd593 | t + \x44b52d02c7e14af5 | 9.999999999999997e+22 | 9.999999999999997e+22 | \x44b52d02c7e14af5 | t + \x44b52d02c7e14af6 | 9.999999999999999e+22 | 9.999999999999999e+22 | \x44b52d02c7e14af6 | t + \x44b52d02c7e14af7 | 1.0000000000000001e+23 | 1.0000000000000001e+23 | \x44b52d02c7e14af7 | t + \x44ea784379d99db3 | 9.999999999999998e+23 | 9.999999999999998e+23 | \x44ea784379d99db3 | t + \x44ea784379d99db4 | 1e+24 | 1e+24 | \x44ea784379d99db4 | t + \x44ea784379d99db5 | 1.0000000000000001e+24 | 1.0000000000000001e+24 | \x44ea784379d99db5 | t + \x45208b2a2c280290 | 9.999999999999999e+24 | 9.999999999999999e+24 | \x45208b2a2c280290 | t + \x45208b2a2c280291 | 1e+25 | 1e+25 | \x45208b2a2c280291 | t + \x45208b2a2c280292 | 1.0000000000000003e+25 | 1.0000000000000003e+25 | \x45208b2a2c280292 | t + \x7feffffffffffffe | 1.7976931348623155e+308 | 1.7976931348623155e+308 | \x7feffffffffffffe | t + \x7fefffffffffffff | 1.7976931348623157e+308 | 1.7976931348623157e+308 | \x7fefffffffffffff | t + \x4350000000000002 | 1.8014398509481992e+16 | 1.8014398509481992e+16 | \x4350000000000002 | t + \x4350000000002e06 | 1.8014398509529112e+16 | 1.8014398509529112e+16 | \x4350000000002e06 | t + \x4352000000000003 | 2.0266198323167244e+16 | 2.0266198323167244e+16 | \x4352000000000003 | t + \x4352000000000004 | 2.0266198323167248e+16 | 2.0266198323167248e+16 | \x4352000000000004 | t + \x4358000000000003 | 2.7021597764222988e+16 | 2.7021597764222988e+16 | \x4358000000000003 | t + \x4358000000000004 | 2.7021597764222992e+16 | 2.7021597764222992e+16 | \x4358000000000004 | t + \x435f000000000020 | 3.4902897112121472e+16 | 3.4902897112121472e+16 | \x435f000000000020 | t + \xc350000000000002 | -1.8014398509481992e+16 | -1.8014398509481992e+16 | \xc350000000000002 | t + \xc350000000002e06 | -1.8014398509529112e+16 | -1.8014398509529112e+16 | \xc350000000002e06 | t + \xc352000000000003 | -2.0266198323167244e+16 | -2.0266198323167244e+16 | \xc352000000000003 | t + \xc352000000000004 | -2.0266198323167248e+16 | -2.0266198323167248e+16 | \xc352000000000004 | t + \xc358000000000003 | -2.7021597764222988e+16 | -2.7021597764222988e+16 | \xc358000000000003 | t + \xc358000000000004 | -2.7021597764222992e+16 | -2.7021597764222992e+16 | \xc358000000000004 | t + \xc35f000000000020 | -3.4902897112121472e+16 | -3.4902897112121472e+16 | \xc35f000000000020 | t + \x42dc12218377de66 | 123456789012345.6 | 123456789012345.6 | \x42dc12218377de66 | t + \x42a674e79c5fe51f | 12345678901234.56 | 12345678901234.56 | \x42a674e79c5fe51f | t + \x4271f71fb04cb74c | 1234567890123.456 | 1234567890123.456 | \x4271f71fb04cb74c | t + \x423cbe991a145879 | 123456789012.3456 | 123456789012.3456 | \x423cbe991a145879 | t + \x4206fee0e1a9e061 | 12345678901.23456 | 12345678901.23456 | \x4206fee0e1a9e061 | t + \x41d26580b487e6b4 | 1234567890.123456 | 1234567890.123456 | \x41d26580b487e6b4 | t + \x419d6f34540ca453 | 123456789.0123456 | 123456789.0123456 | \x419d6f34540ca453 | t + \x41678c29dcd6e9dc | 12345678.90123456 | 12345678.90123456 | \x41678c29dcd6e9dc | t + \x4132d687e3df217d | 1234567.890123456 | 1234567.890123456 | \x4132d687e3df217d | t + \x40fe240c9fcb68c8 | 123456.7890123456 | 123456.7890123456 | \x40fe240c9fcb68c8 | t + \x40c81cd6e63c53d3 | 12345.67890123456 | 12345.67890123456 | \x40c81cd6e63c53d3 | t + \x40934a4584fd0fdc | 1234.567890123456 | 1234.567890123456 | \x40934a4584fd0fdc | t + \x405edd3c07fb4c93 | 123.4567890123456 | 123.4567890123456 | \x405edd3c07fb4c93 | t + \x4028b0fcd32f7076 | 12.34567890123456 | 12.34567890123456 | \x4028b0fcd32f7076 | t + \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t + \x3e60000000000000 | 2.9802322387695312e-08 | 2.9802322387695312e-08 | \x3e60000000000000 | t + \xc352bd2668e077c4 | -2.1098088986959632e+16 | -2.1098088986959632e+16 | \xc352bd2668e077c4 | t + \x434018601510c000 | 9.0608011534336e+15 | 9.0608011534336e+15 | \x434018601510c000 | t + \x43d055dc36f24000 | 4.708356024711512e+18 | 4.708356024711512e+18 | \x43d055dc36f24000 | t + \x43e052961c6f8000 | 9.409340012568248e+18 | 9.409340012568248e+18 | \x43e052961c6f8000 | t + \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t + \x4830f0cf064dd592 | 5.764607523034235e+39 | 5.764607523034235e+39 | \x4830f0cf064dd592 | t + \x4840f0cf064dd592 | 1.152921504606847e+40 | 1.152921504606847e+40 | \x4840f0cf064dd592 | t + \x4850f0cf064dd592 | 2.305843009213694e+40 | 2.305843009213694e+40 | \x4850f0cf064dd592 | t + \x3ff3333333333333 | 1.2 | 1.2 | \x3ff3333333333333 | t + \x3ff3ae147ae147ae | 1.23 | 1.23 | \x3ff3ae147ae147ae | t + \x3ff3be76c8b43958 | 1.234 | 1.234 | \x3ff3be76c8b43958 | t + \x3ff3c083126e978d | 1.2345 | 1.2345 | \x3ff3c083126e978d | t + \x3ff3c0c1fc8f3238 | 1.23456 | 1.23456 | \x3ff3c0c1fc8f3238 | t + \x3ff3c0c9539b8887 | 1.234567 | 1.234567 | \x3ff3c0c9539b8887 | t + \x3ff3c0ca2a5b1d5d | 1.2345678 | 1.2345678 | \x3ff3c0ca2a5b1d5d | t + \x3ff3c0ca4283de1b | 1.23456789 | 1.23456789 | \x3ff3c0ca4283de1b | t + \x3ff3c0ca43db770a | 1.234567895 | 1.234567895 | \x3ff3c0ca43db770a | t + \x3ff3c0ca428abd53 | 1.2345678901 | 1.2345678901 | \x3ff3c0ca428abd53 | t + \x3ff3c0ca428c1d2b | 1.23456789012 | 1.23456789012 | \x3ff3c0ca428c1d2b | t + \x3ff3c0ca428c51f2 | 1.234567890123 | 1.234567890123 | \x3ff3c0ca428c51f2 | t + \x3ff3c0ca428c58fc | 1.2345678901234 | 1.2345678901234 | \x3ff3c0ca428c58fc | t + \x3ff3c0ca428c59dd | 1.23456789012345 | 1.23456789012345 | \x3ff3c0ca428c59dd | t + \x3ff3c0ca428c59f8 | 1.234567890123456 | 1.234567890123456 | \x3ff3c0ca428c59f8 | t + \x3ff3c0ca428c59fb | 1.2345678901234567 | 1.2345678901234567 | \x3ff3c0ca428c59fb | t + \x40112e0be8047a7d | 4.294967294 | 4.294967294 | \x40112e0be8047a7d | t + \x40112e0be815a889 | 4.294967295 | 4.294967295 | \x40112e0be815a889 | t + \x40112e0be826d695 | 4.294967296 | 4.294967296 | \x40112e0be826d695 | t + \x40112e0be83804a1 | 4.294967297 | 4.294967297 | \x40112e0be83804a1 | t + \x40112e0be84932ad | 4.294967298 | 4.294967298 | \x40112e0be84932ad | t + \x0040000000000000 | 1.7800590868057611e-307 | 1.7800590868057611e-307 | \x0040000000000000 | t + \x007fffffffffffff | 2.8480945388892175e-306 | 2.8480945388892175e-306 | \x007fffffffffffff | t + \x0290000000000000 | 2.446494580089078e-296 | 2.446494580089078e-296 | \x0290000000000000 | t + \x029fffffffffffff | 4.8929891601781557e-296 | 4.8929891601781557e-296 | \x029fffffffffffff | t + \x4350000000000000 | 1.8014398509481984e+16 | 1.8014398509481984e+16 | \x4350000000000000 | t + \x435fffffffffffff | 3.6028797018963964e+16 | 3.6028797018963964e+16 | \x435fffffffffffff | t + \x1330000000000000 | 2.900835519859558e-216 | 2.900835519859558e-216 | \x1330000000000000 | t + \x133fffffffffffff | 5.801671039719115e-216 | 5.801671039719115e-216 | \x133fffffffffffff | t + \x3a6fa7161a4d6e0c | 3.196104012172126e-27 | 3.196104012172126e-27 | \x3a6fa7161a4d6e0c | t +(209 rows) + +-- clean up, lest opr_sanity complain +drop type xfloat8 cascade; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to function xfloat8in(cstring) +drop cascades to function xfloat8out(xfloat8) +drop cascades to cast from xfloat8 to double precision +drop cascades to cast from double precision to xfloat8 +drop cascades to cast from xfloat8 to bigint +drop cascades to cast from bigint to xfloat8 diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out index 7b54e96d30e..b9e25820bc0 100644 --- a/src/test/regress/expected/foreign_data.out +++ b/src/test/regress/expected/foreign_data.out @@ -30,8 +30,8 @@ SELECT srvname, srvoptions FROM pg_foreign_server; (0 rows) SELECT * FROM pg_user_mapping; - umuser | umserver | umoptions ---------+----------+----------- + oid | umuser | umserver | umoptions +-----+--------+----------+----------- (0 rows) -- CREATE FOREIGN DATA WRAPPER @@ -238,9 +238,9 @@ CREATE SERVER s1 FOREIGN DATA WRAPPER foo; COMMENT ON SERVER s1 IS 'foreign server'; CREATE USER MAPPING FOR current_user SERVER s1; CREATE USER MAPPING FOR current_user SERVER s1; -- ERROR -ERROR: user mapping for "regress_foreign_data_user" already exists for server s1 +ERROR: user mapping for "regress_foreign_data_user" already exists for server "s1" CREATE USER MAPPING IF NOT EXISTS FOR current_user SERVER s1; -- NOTICE -NOTICE: user mapping for "regress_foreign_data_user" already exists for server s1, skipping +NOTICE: user mapping for "regress_foreign_data_user" already exists for server "s1", skipping \dew+ List of foreign-data wrappers Name | Owner | Handler | Validator | Access privileges | FDW options | Description @@ -441,8 +441,8 @@ ALTER SERVER s1 OWNER TO regress_test_indirect; RESET ROLE; DROP ROLE regress_test_indirect; -- ERROR ERROR: role "regress_test_indirect" cannot be dropped because some objects depend on it -DETAIL: owner of server s1 -privileges for foreign-data wrapper foo +DETAIL: privileges for foreign-data wrapper foo +owner of server s1 \des+ List of foreign servers Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | FDW options | Description @@ -578,7 +578,7 @@ CREATE USER MAPPING FOR current_user SERVER s1; -- ERROR ERROR: server "s1" does not exist CREATE USER MAPPING FOR current_user SERVER s4; CREATE USER MAPPING FOR user SERVER s4; -- ERROR duplicate -ERROR: user mapping for "regress_foreign_data_user" already exists for server s4 +ERROR: user mapping for "regress_foreign_data_user" already exists for server "s4" CREATE USER MAPPING FOR public SERVER s4 OPTIONS ("this mapping" 'is public'); CREATE USER MAPPING FOR user SERVER s8 OPTIONS (username 'test', password 'secret'); -- ERROR ERROR: invalid option "username" @@ -618,7 +618,7 @@ ERROR: role "regress_test_missing_role" does not exist ALTER USER MAPPING FOR user SERVER ss4 OPTIONS (gotcha 'true'); -- ERROR ERROR: server "ss4" does not exist ALTER USER MAPPING FOR public SERVER s5 OPTIONS (gotcha 'true'); -- ERROR -ERROR: user mapping for "public" does not exist for the server +ERROR: user mapping for "public" does not exist for server "s5" ALTER USER MAPPING FOR current_user SERVER s8 OPTIONS (username 'test'); -- ERROR ERROR: invalid option "username" HINT: Valid options in this context are: user, password @@ -648,13 +648,13 @@ ERROR: role "regress_test_missing_role" does not exist DROP USER MAPPING FOR user SERVER ss4; ERROR: server "ss4" does not exist DROP USER MAPPING FOR public SERVER s7; -- ERROR -ERROR: user mapping for "public" does not exist for the server +ERROR: user mapping for "public" does not exist for server "s7" DROP USER MAPPING IF EXISTS FOR regress_test_missing_role SERVER s4; NOTICE: role "regress_test_missing_role" does not exist, skipping DROP USER MAPPING IF EXISTS FOR user SERVER ss4; -NOTICE: server does not exist, skipping +NOTICE: server "ss4" does not exist, skipping DROP USER MAPPING IF EXISTS FOR public SERVER s7; -NOTICE: user mapping for "public" does not exist for the server, skipping +NOTICE: user mapping for "public" does not exist for server "s7", skipping CREATE USER MAPPING FOR public SERVER s8; SET ROLE regress_test_role; DROP USER MAPPING FOR public SERVER s8; -- ERROR @@ -684,10 +684,6 @@ LINE 1: CREATE FOREIGN TABLE ft1 (); ^ CREATE FOREIGN TABLE ft1 () SERVER no_server; -- ERROR ERROR: server "no_server" does not exist -CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS; -- ERROR -ERROR: syntax error at or near "WITH" -LINE 1: CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS; - ^ CREATE FOREIGN TABLE ft1 ( c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY, c2 text OPTIONS (param2 'val2', param3 'val3'), @@ -749,6 +745,65 @@ SELECT * FROM ft1; -- ERROR ERROR: foreign-data wrapper "dummy" has no handler EXPLAIN SELECT * FROM ft1; -- ERROR ERROR: foreign-data wrapper "dummy" has no handler +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; +CREATE INDEX ON lt1 (a); -- skips partition +CREATE UNIQUE INDEX ON lt1 (a); -- ERROR +ERROR: cannot create unique index on partitioned table "lt1" +DETAIL: Table "lt1" contains partitions that are foreign tables. +ALTER TABLE lt1 ADD PRIMARY KEY (a); -- ERROR +ERROR: cannot create unique index on partitioned table "lt1" +DETAIL: Table "lt1" contains partitions that are foreign tables. +DROP TABLE lt1; +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE INDEX ON lt1 (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; +CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0; +ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000); +DROP FOREIGN TABLE ft_part1, ft_part2; +CREATE UNIQUE INDEX ON lt1 (a); +ALTER TABLE lt1 ADD PRIMARY KEY (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; -- ERROR +ERROR: cannot create foreign partition of partitioned table "lt1" +DETAIL: Table "lt1" contains indexes that are unique. +CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0; +ALTER TABLE lt1 ATTACH PARTITION ft_part2 + FOR VALUES FROM (1000) TO (2000); -- ERROR +ERROR: cannot attach foreign table "ft_part2" as partition of partitioned table "lt1" +DETAIL: Table "lt1" contains unique indexes. +DROP TABLE lt1; +DROP FOREIGN TABLE ft_part2; +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE INDEX ON lt1 (a); +CREATE TABLE lt1_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) + PARTITION BY RANGE (a); +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; +CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0; +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); +CREATE UNIQUE INDEX ON lt1 (a); +ERROR: cannot create unique index on partitioned table "lt1" +DETAIL: Table "lt1" contains partitions that are foreign tables. +ALTER TABLE lt1 ADD PRIMARY KEY (a); +ERROR: cannot create unique index on partitioned table "lt1_part1" +DETAIL: Table "lt1_part1" contains partitions that are foreign tables. +DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2; +CREATE UNIQUE INDEX ON lt1 (a); +ALTER TABLE lt1 ADD PRIMARY KEY (a); +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; +ERROR: cannot create foreign partition of partitioned table "lt1_part1" +DETAIL: Table "lt1_part1" contains indexes that are unique. +CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0; +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); +ERROR: cannot attach foreign table "ft_part_1_2" as partition of partitioned table "lt1_part1" +DETAIL: Table "lt1_part1" contains unique indexes. +DROP TABLE lt1; +DROP FOREIGN TABLE ft_part_1_2; -- ALTER FOREIGN TABLE COMMENT ON FOREIGN TABLE ft1 IS 'foreign table'; COMMENT ON FOREIGN TABLE ft1 IS NULL; @@ -815,7 +870,6 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const; -- ERROR ERROR: constraint "no_const" of relation "ft1" does not exist ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const; NOTICE: constraint "no_const" of relation "ft1" does not exist, skipping -ALTER FOREIGN TABLE ft1 SET WITH OIDS; ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role; ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@'); ALTER FOREIGN TABLE ft1 DROP COLUMN no_column; -- ERROR @@ -1201,11 +1255,10 @@ ERROR: permission denied for foreign-data wrapper foo ALTER SERVER s9 VERSION '1.1'; GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role; CREATE USER MAPPING FOR current_user SERVER s9; --- We use terse mode to avoid ordering issues in cascade detail output. -\set VERBOSITY terse DROP SERVER s9 CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to user mapping for public on server s9 +drop cascades to user mapping for regress_unprivileged_role on server s9 RESET ROLE; CREATE SERVER s9 FOREIGN DATA WRAPPER foo; GRANT USAGE ON FOREIGN SERVER s9 TO regress_unprivileged_role; @@ -1273,10 +1326,10 @@ SET ROLE regress_unprivileged_role; (9 rows) RESET ROLE; -\set VERBOSITY terse DROP SERVER s10 CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to user mapping for public on server s10 +drop cascades to user mapping for regress_unprivileged_role on server s10 -- Triggers CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ BEGIN @@ -1618,12 +1671,15 @@ Inherits: fd_pt1 Child tables: ct3, ft3 -\set VERBOSITY terse DROP FOREIGN TABLE ft2; -- ERROR ERROR: cannot drop foreign table ft2 because other objects depend on it +DETAIL: table ct3 depends on foreign table ft2 +foreign table ft3 depends on foreign table ft2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP FOREIGN TABLE ft2 CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to table ct3 +drop cascades to foreign table ft3 CREATE FOREIGN TABLE ft2 ( c1 integer NOT NULL, c2 text, @@ -1718,63 +1774,6 @@ Server: s0 FDW options: (delimiter ',', quote '"', "be quoted" 'value') Inherits: fd_pt1 --- OID system column -ALTER TABLE fd_pt1 SET WITH OIDS; -\d+ fd_pt1 - Table "public.fd_pt1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+----------+--------------+------------- - c1 | integer | | not null | | plain | 10000 | - c2 | text | | | | extended | | - c3 | date | | | | plain | | -Check constraints: - "fd_pt1chk3" CHECK (c2 <> ''::text) -Child tables: ft2 -Has OIDs: yes - -\d+ ft2 - Foreign table "public.ft2" - Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description ---------+---------+-----------+----------+---------+-------------+----------+--------------+------------- - c1 | integer | | not null | | | plain | | - c2 | text | | | | | extended | | - c3 | date | | | | | plain | | -Check constraints: - "fd_pt1chk2" CHECK (c2 <> ''::text) - "fd_pt1chk3" CHECK (c2 <> ''::text) -Server: s0 -FDW options: (delimiter ',', quote '"', "be quoted" 'value') -Inherits: fd_pt1 -Has OIDs: yes - -ALTER TABLE ft2 SET WITHOUT OIDS; -- ERROR -ERROR: cannot drop inherited column "oid" -ALTER TABLE fd_pt1 SET WITHOUT OIDS; -\d+ fd_pt1 - Table "public.fd_pt1" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+----------+--------------+------------- - c1 | integer | | not null | | plain | 10000 | - c2 | text | | | | extended | | - c3 | date | | | | plain | | -Check constraints: - "fd_pt1chk3" CHECK (c2 <> ''::text) -Child tables: ft2 - -\d+ ft2 - Foreign table "public.ft2" - Column | Type | Collation | Nullable | Default | FDW options | Storage | Stats target | Description ---------+---------+-----------+----------+---------+-------------+----------+--------------+------------- - c1 | integer | | not null | | | plain | | - c2 | text | | | | | extended | | - c3 | date | | | | | plain | | -Check constraints: - "fd_pt1chk2" CHECK (c2 <> ''::text) - "fd_pt1chk3" CHECK (c2 <> ''::text) -Server: s0 -FDW options: (delimiter ',', quote '"', "be quoted" 'value') -Inherits: fd_pt1 - -- changes name of an attribute recursively ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1; ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2; @@ -1846,7 +1845,7 @@ CREATE TABLE fd_pt2 ( CREATE FOREIGN TABLE fd_pt2_1 PARTITION OF fd_pt2 FOR VALUES IN (1) SERVER s0 OPTIONS (delimiter ',', quote '"', "be quoted" 'value'); \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -1891,7 +1890,7 @@ ERROR: table "fd_pt2_1" contains column "c4" not found in parent "fd_pt2" DETAIL: The new partition may contain only the columns present in parent. DROP FOREIGN TABLE fd_pt2_1; \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -1918,7 +1917,7 @@ FDW options: (delimiter ',', quote '"', "be quoted" 'value') -- no attach partition validation occurs for foreign tables ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -1946,7 +1945,7 @@ ERROR: cannot add column to a partition ALTER TABLE fd_pt2_1 ALTER c3 SET NOT NULL; ALTER TABLE fd_pt2_1 ADD CONSTRAINT p21chk CHECK (c2 <> ''); \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -1976,7 +1975,7 @@ ERROR: column "c1" is marked NOT NULL in parent table ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1; ALTER TABLE fd_pt2 ALTER c2 SET NOT NULL; \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -2004,7 +2003,7 @@ ALTER TABLE fd_pt2 ATTACH PARTITION fd_pt2_1 FOR VALUES IN (1); ALTER TABLE fd_pt2 DETACH PARTITION fd_pt2_1; ALTER TABLE fd_pt2 ADD CONSTRAINT fd_pt2chk1 CHECK (c1 > 0); \d+ fd_pt2 - Table "public.fd_pt2" + Partitioned table "public.fd_pt2" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- c1 | integer | | not null | | plain | | @@ -2038,22 +2037,38 @@ TRUNCATE fd_pt2; -- ERROR ERROR: "fd_pt2_1" is not a table DROP FOREIGN TABLE fd_pt2_1; DROP TABLE fd_pt2; +-- foreign table cannot be part of partition tree made of temporary +-- relations. +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a); +CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT + SERVER s0; -- ERROR +ERROR: cannot create a permanent relation as partition of temporary relation "temp_parted" +CREATE FOREIGN TABLE foreign_part (a int) SERVER s0; +ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT; -- ERROR +ERROR: cannot attach a permanent relation as partition of temporary relation "temp_parted" +DROP FOREIGN TABLE foreign_part; +DROP TABLE temp_parted; -- Cleanup DROP SCHEMA foreign_schema CASCADE; DROP ROLE regress_test_role; -- ERROR ERROR: role "regress_test_role" cannot be dropped because some objects depend on it -DETAIL: privileges for server s4 -privileges for foreign-data wrapper foo +DETAIL: privileges for foreign-data wrapper foo +privileges for server s4 owner of user mapping for regress_test_role on server s6 DROP SERVER t1 CASCADE; NOTICE: drop cascades to user mapping for public on server t1 DROP USER MAPPING FOR regress_test_role SERVER s6; -\set VERBOSITY terse DROP FOREIGN DATA WRAPPER foo CASCADE; NOTICE: drop cascades to 5 other objects +DETAIL: drop cascades to server s4 +drop cascades to user mapping for regress_foreign_data_user on server s4 +drop cascades to server s6 +drop cascades to server s9 +drop cascades to user mapping for regress_unprivileged_role on server s9 DROP SERVER s8 CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to user mapping for regress_foreign_data_user on server s8 +drop cascades to user mapping for public on server s8 DROP ROLE regress_test_indirect; DROP ROLE regress_test_role; DROP ROLE regress_unprivileged_role; -- ERROR @@ -2079,7 +2094,7 @@ SELECT srvname, srvoptions FROM pg_foreign_server; (0 rows) SELECT * FROM pg_user_mapping; - umuser | umserver | umoptions ---------+----------+----------- + oid | umuser | umserver | umoptions +-----+--------+----------+----------- (0 rows) diff --git a/src/test/regress/expected/foreign_key.out b/src/test/regress/expected/foreign_key.out index b90c4926e29..894084f94f1 100644 --- a/src/test/regress/expected/foreign_key.out +++ b/src/test/regress/expected/foreign_key.out @@ -143,6 +143,12 @@ SELECT * FROM FKTABLE; | | 8 (5 rows) +-- Check update with part of key null +UPDATE FKTABLE SET ftest1 = NULL WHERE ftest1 = 1; +ERROR: insert or update on table "fktable" violates foreign key constraint "constrname" +DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. +-- Check update with old and new key values equal +UPDATE FKTABLE SET ftest1 = 1 WHERE ftest1 = 1; -- Try altering the column type where foreign keys are involved ALTER TABLE PKTABLE ALTER COLUMN ptest1 TYPE bigint; ALTER TABLE FKTABLE ALTER COLUMN ftest1 TYPE bigint; @@ -158,11 +164,11 @@ SELECT * FROM PKTABLE; SELECT * FROM FKTABLE; ftest1 | ftest2 | ftest3 --------+--------+-------- - 1 | 3 | 5 3 | 6 | 12 | | 0 | | 4 | | 8 + 1 | 3 | 5 (5 rows) DROP TABLE PKTABLE CASCADE; @@ -333,6 +339,18 @@ SELECT * FROM PKTABLE; 0 | Test4 (4 rows) +DROP TABLE FKTABLE; +DROP TABLE PKTABLE; +-- +-- Check initial check upon ALTER TABLE +-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, PRIMARY KEY(ptest1, ptest2) ); +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int ); +INSERT INTO PKTABLE VALUES (1, 2); +INSERT INTO FKTABLE VALUES (1, NULL); +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL; +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_ftest2_fkey" +DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. DROP TABLE FKTABLE; DROP TABLE PKTABLE; -- MATCH SIMPLE @@ -397,6 +415,30 @@ SELECT * from FKTABLE; | 3 | 4 | 5 (5 rows) +DROP TABLE FKTABLE; +DROP TABLE PKTABLE; +-- restrict with null values +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE(ptest1, ptest2, ptest3) ); +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE (ptest1, ptest2, ptest3)); +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); +INSERT INTO PKTABLE VALUES (1, 3, NULL, 'test2'); +INSERT INTO PKTABLE VALUES (2, NULL, 4, 'test3'); +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); +DELETE FROM PKTABLE WHERE ptest1 = 2; +SELECT * FROM PKTABLE; + ptest1 | ptest2 | ptest3 | ptest4 +--------+--------+--------+-------- + 1 | 2 | 3 | test1 + 1 | 3 | | test2 +(2 rows) + +SELECT * FROM FKTABLE; + ftest1 | ftest2 | ftest3 | ftest4 +--------+--------+--------+-------- + 1 | 2 | 3 | 1 +(1 row) + DROP TABLE FKTABLE; DROP TABLE PKTABLE; -- cascade update/delete @@ -787,23 +829,23 @@ DROP TABLE PKTABLE; CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2)); -- This should fail, because we just chose really odd types CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. -- Again, so should this... CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer. -- This fails because we mixed up the column ordering CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer. -- As does this... CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2)); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented DETAIL: Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer. -- And again.. CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet. -- This works... CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1)); @@ -824,17 +866,17 @@ DROP TABLE PKTABLE; -- This shouldn't (mixed up columns) CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3, ptest4) REFERENCES pktable(ptest2, ptest1)); -ERROR: foreign key constraint "pktable_ptest3_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_ptest3_ptest4_fkey" cannot be implemented DETAIL: Key columns "ptest3" and "ptest2" are of incompatible types: integer and inet. -- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, ptest3) REFERENCES pktable(ptest1, ptest2)); -ERROR: foreign key constraint "pktable_ptest4_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_ptest4_ptest3_fkey" cannot be implemented DETAIL: Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer. -- Not this one either... Same as the last one except we didn't defined the columns being referenced. CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4, ptest3) REFERENCES pktable); -ERROR: foreign key constraint "pktable_ptest4_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_ptest4_ptest3_fkey" cannot be implemented DETAIL: Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer. -- -- Now some cases with inheritance @@ -875,19 +917,19 @@ insert into pktable(base1, ptest1) values (1, 1); insert into pktable(base1, ptest1) values (2, 2); -- let's insert a non-existent fktable value insert into fktable(ftest1, ftest2) values (3, 1); -ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" +ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_ftest2_fkey" DETAIL: Key (ftest1, ftest2)=(3, 1) is not present in table "pktable". -- let's make a valid row for that insert into pktable(base1,ptest1) values (3, 1); insert into fktable(ftest1, ftest2) values (3, 1); -- let's try removing a row that should fail from pktable delete from pktable where base1>2; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" +ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_ftest2_fkey" on table "fktable" DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable". -- okay, let's try updating all of the base1 values to *4 -- which should fail. update pktable set base1=base1*4; -ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" +ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_ftest2_fkey" on table "fktable" DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable". -- okay, let's try an update that should work. update pktable set base1=base1*4 where base1<3; @@ -907,15 +949,15 @@ insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1); insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2); -- fails (3,2) isn't in base1, ptest1 insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2); -ERROR: insert or update on table "pktable" violates foreign key constraint "pktable_base2_fkey" +ERROR: insert or update on table "pktable" violates foreign key constraint "pktable_base2_ptest2_fkey" DETAIL: Key (base2, ptest2)=(3, 2) is not present in table "pktable". -- fails (2,2) is being referenced delete from pktable where base1=2; -ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" +ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_ptest2_fkey" on table "pktable" DETAIL: Key (base1, ptest1)=(2, 2) is still referenced from table "pktable". -- fails (1,1) is being referenced (twice) update pktable set base1=3 where base1=1; -ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" +ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_ptest2_fkey" on table "pktable" DETAIL: Key (base1, ptest1)=(1, 1) is still referenced from table "pktable". -- this sequence of two deletes will work, since after the first there will be no (2,*) references delete from pktable where base2=2; @@ -927,20 +969,20 @@ create table pktable_base(base1 int not null); create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base); -- just generally bad types (with and without column references on the referenced table) create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer. create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "base1" are of incompatible types: cidr and integer. -- let's mix up which columns reference which create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer. create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1)); -ERROR: foreign key constraint "fktable_ftest2_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest2_ftest1_fkey" cannot be implemented DETAIL: Key columns "ftest2" and "base1" are of incompatible types: inet and integer. create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1)); -ERROR: foreign key constraint "fktable_ftest1_fkey" cannot be implemented +ERROR: foreign key constraint "fktable_ftest1_ftest2_fkey" cannot be implemented DETAIL: Key columns "ftest1" and "ptest1" are of incompatible types: integer and inet. drop table pktable; drop table pktable_base; @@ -948,26 +990,25 @@ drop table pktable_base; create table pktable_base(base1 int not null, base2 int); create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(base1, ptest1)) inherits (pktable_base); -ERROR: foreign key constraint "pktable_base2_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_base2_ptest2_fkey" cannot be implemented DETAIL: Key columns "ptest2" and "ptest1" are of incompatible types: inet[] and inet. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references pktable(ptest1, base1)) inherits (pktable_base); -ERROR: foreign key constraint "pktable_base2_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_base2_ptest2_fkey" cannot be implemented DETAIL: Key columns "base2" and "ptest1" are of incompatible types: integer and inet. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -ERROR: foreign key constraint "pktable_ptest2_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_ptest2_base2_fkey" cannot be implemented DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer. create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references pktable(base1, ptest1)) inherits (pktable_base); -ERROR: foreign key constraint "pktable_ptest2_fkey" cannot be implemented +ERROR: foreign key constraint "pktable_ptest2_base2_fkey" cannot be implemented DETAIL: Key columns "ptest2" and "base1" are of incompatible types: inet and integer. drop table pktable; ERROR: table "pktable" does not exist drop table pktable_base; -- -- Deferrable constraints --- (right now, only FOREIGN KEY constraints can be deferred) -- -- deferrable, explicitly deferred CREATE TABLE pktable ( @@ -1339,7 +1380,7 @@ DETAIL: Key (f1)=(1) is still referenced from table "defc". -- Test the difference between NO ACTION and RESTRICT -- create temp table pp (f1 int primary key); -create temp table cc (f1 int references pp on update no action); +create temp table cc (f1 int references pp on update no action on delete no action); insert into pp values(12); insert into pp values(11); update pp set f1=f1+1; @@ -1348,9 +1389,12 @@ update pp set f1=f1+1; update pp set f1=f1+1; -- fail ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc" DETAIL: Key (f1)=(13) is still referenced from table "cc". +delete from pp where f1 = 13; -- fail +ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc" +DETAIL: Key (f1)=(13) is still referenced from table "cc". drop table pp, cc; create temp table pp (f1 int primary key); -create temp table cc (f1 int references pp on update restrict); +create temp table cc (f1 int references pp on update restrict on delete restrict); insert into pp values(12); insert into pp values(11); update pp set f1=f1+1; @@ -1358,6 +1402,9 @@ insert into cc values(13); update pp set f1=f1+1; -- fail ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc" DETAIL: Key (f1)=(13) is still referenced from table "cc". +delete from pp where f1 = 13; -- fail +ERROR: update or delete on table "pp" violates foreign key constraint "cc_f1_fkey" on table "cc" +DETAIL: Key (f1)=(13) is still referenced from table "cc". drop table pp, cc; -- -- Test interaction of foreign-key optimization with rules (bug #14219) @@ -1388,12 +1435,32 @@ create table fktable2 (d int, e int, foreign key (d, e) references pktable2); insert into pktable2 values (1, 2, 3, 4, 5); insert into fktable2 values (4, 5); delete from pktable2; -ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_fkey" on table "fktable2" +ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_e_fkey" on table "fktable2" DETAIL: Key (d, e)=(4, 5) is still referenced from table "fktable2". update pktable2 set d = 5; -ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_fkey" on table "fktable2" +ERROR: update or delete on table "pktable2" violates foreign key constraint "fktable2_d_e_fkey" on table "fktable2" DETAIL: Key (d, e)=(4, 5) is still referenced from table "fktable2". drop table pktable2, fktable2; +-- Test truncation of long foreign key names +create table pktable1 (a int primary key); +create table pktable2 (a int, b int, primary key (a, b)); +create table fktable2 ( + a int, + b int, + very_very_long_column_name_to_exceed_63_characters int, + foreign key (very_very_long_column_name_to_exceed_63_characters) references pktable1, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2 +); +select conname from pg_constraint where conrelid = 'fktable2'::regclass order by conname; + conname +----------------------------------------------------------------- + fktable2_a_very_very_long_column_name_to_exceed_63_charac_fkey1 + fktable2_a_very_very_long_column_name_to_exceed_63_charact_fkey + fktable2_very_very_long_column_name_to_exceed_63_character_fkey +(3 rows) + +drop table pktable1, pktable2, fktable2; -- -- Test deferred FK check on a tuple deleted by a rolled-back subtransaction -- @@ -1427,23 +1494,44 @@ delete from pktable2 where f1 = 1; alter table fktable2 drop constraint fktable2_f1_fkey; ERROR: cannot ALTER TABLE "pktable2" because it has pending trigger events commit; +drop table pktable2, fktable2; +-- +-- Test keys that "look" different but compare as equal +-- +create table pktable2 (a float8, b float8, primary key (a, b)); +create table fktable2 (x float8, y float8, foreign key (x, y) references pktable2 (a, b) on update cascade); +insert into pktable2 values ('-0', '-0'); +insert into fktable2 values ('-0', '-0'); +select * from pktable2; + a | b +----+---- + -0 | -0 +(1 row) + +select * from fktable2; + x | y +----+---- + -0 | -0 +(1 row) + +update pktable2 set a = '0' where a = '-0'; +select * from pktable2; + a | b +---+---- + 0 | -0 +(1 row) + +-- should have updated fktable2.x +select * from fktable2; + x | y +---+---- + 0 | -0 +(1 row) + drop table pktable2, fktable2; -- -- Foreign keys and partitioned tables -- --- partitioned table in the referenced side are not allowed -CREATE TABLE fk_partitioned_pk (a int, b int, primary key (a, b)) - PARTITION BY RANGE (a, b); --- verify with create table first ... -CREATE TABLE fk_notpartitioned_fk (a int, b int, - FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk); -ERROR: cannot reference partitioned table "fk_partitioned_pk" --- and then with alter table. -CREATE TABLE fk_notpartitioned_fk_2 (a int, b int); -ALTER TABLE fk_notpartitioned_fk_2 ADD FOREIGN KEY (a, b) - REFERENCES fk_partitioned_pk; -ERROR: cannot reference partitioned table "fk_partitioned_pk" -DROP TABLE fk_partitioned_pk, fk_notpartitioned_fk_2; -- Creation of a partitioned hierarchy with irregular definitions CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, PRIMARY KEY (a, b)); @@ -1465,31 +1553,42 @@ CREATE TABLE fk_partitioned_fk_3_0 PARTITION OF fk_partitioned_fk_3 FOR VALUES W CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES WITH (MODULUS 5, REMAINDER 1); ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FROM (2000,2000) TO (3000,3000); --- these inserts, targetting both the partition directly as well as the +-- Creating a foreign key with ONLY on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk; +ERROR: cannot use ONLY for foreign key on partitioned table "fk_partitioned_fk" referencing relation "fk_notpartitioned_pk" +-- Adding a NOT VALID foreign key on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk NOT VALID; +ERROR: cannot add NOT VALID foreign key on partitioned table "fk_partitioned_fk" referencing relation "fk_notpartitioned_pk" +DETAIL: This feature is not yet supported on partitioned tables. +-- these inserts, targeting both the partition directly as well as the -- partitioned table, should all fail INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501); -ERROR: insert or update on table "fk_partitioned_fk_1" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(500, 501) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk_1 (a,b) VALUES (500, 501); -ERROR: insert or update on table "fk_partitioned_fk_1" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(500, 501) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk (a,b) VALUES (1500, 1501); -ERROR: insert or update on table "fk_partitioned_fk_2" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_2" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(1500, 1501) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk_2 (a,b) VALUES (1500, 1501); -ERROR: insert or update on table "fk_partitioned_fk_2" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_2" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(1500, 1501) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502); -ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2500, 2502) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2500, 2502); -ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2500, 2502) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503); -ERROR: insert or update on table "fk_partitioned_fk_3_0" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3_0" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2501, 2503) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk_3 (a,b) VALUES (2501, 2503); -ERROR: insert or update on table "fk_partitioned_fk_3_0" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3_0" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2501, 2503) is not present in table "fk_notpartitioned_pk". -- but if we insert the values that make them valid, then they work INSERT INTO fk_notpartitioned_pk VALUES (500, 501), (1500, 1501), @@ -1500,24 +1599,48 @@ INSERT INTO fk_partitioned_fk (a,b) VALUES (2500, 2502); INSERT INTO fk_partitioned_fk (a,b) VALUES (2501, 2503); -- this update fails because there is no referenced row UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501; -ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2502, 2503) is not present in table "fk_notpartitioned_pk". -- but we can fix it thusly: INSERT INTO fk_notpartitioned_pk (a,b) VALUES (2502, 2503); UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501; -- these updates would leave lingering rows in the referencing table; disallow UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500; -ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_fkey" on table "fk_partitioned_fk" +ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" on table "fk_partitioned_fk" DETAIL: Key (a, b)=(500, 501) is still referenced from table "fk_partitioned_fk". UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500; -ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_fkey" on table "fk_partitioned_fk" +ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" on table "fk_partitioned_fk" DETAIL: Key (a, b)=(1500, 1501) is still referenced from table "fk_partitioned_fk". UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500; -ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_fkey" on table "fk_partitioned_fk" +ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" on table "fk_partitioned_fk" DETAIL: Key (a, b)=(2500, 2502) is still referenced from table "fk_partitioned_fk". -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +-- check psql behavior +\d fk_notpartitioned_pk + Table "public.fk_notpartitioned_pk" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | not null | + b | integer | | not null | +Indexes: + "fk_notpartitioned_pk_pkey" PRIMARY KEY, btree (a, b) +Referenced by: + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) + +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; -- done. DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; +-- Altering a type referenced by a foreign key needs to drop/recreate the FK. +-- Ensure that works. +CREATE TABLE fk_notpartitioned_pk (a INT, PRIMARY KEY(a), CHECK (a > 0)); +CREATE TABLE fk_partitioned_fk (a INT REFERENCES fk_notpartitioned_pk(a) PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (MINVALUE) TO (MAXVALUE); +INSERT INTO fk_notpartitioned_pk VALUES (1); +INSERT INTO fk_partitioned_fk VALUES (1); +ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint; +DELETE FROM fk_notpartitioned_pk WHERE a = 1; +ERROR: update or delete on table "fk_notpartitioned_pk" violates foreign key constraint "fk_partitioned_fk_a_fkey" on table "fk_partitioned_fk" +DETAIL: Key (a)=(1) is still referenced from table "fk_partitioned_fk". +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; -- Test some other exotic foreign key features: MATCH SIMPLE, ON UPDATE/DELETE -- actions CREATE TABLE fk_notpartitioned_pk (a int, b int, primary key (a, b)); @@ -1531,10 +1654,10 @@ CREATE TABLE fk_partitioned_fk_3 (a int, b int); ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES IN (2500,2501,2502,2503); -- this insert fails INSERT INTO fk_partitioned_fk (a, b) VALUES (2502, 2503); -ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2502, 2503) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); -ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2502, 2503) is not present in table "fk_notpartitioned_pk". -- but since the FK is MATCH SIMPLE, this one doesn't INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, NULL); @@ -1544,6 +1667,20 @@ INSERT INTO fk_notpartitioned_pk VALUES (2502, 2503); INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); -- this always works INSERT INTO fk_partitioned_fk (a,b) VALUES (NULL, NULL); +-- MATCH FULL +INSERT INTO fk_notpartitioned_pk VALUES (1, 2); +CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x); +CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT; +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; -- fails +ERROR: insert or update on table "fk_partitioned_fk_full_1" violates foreign key constraint "fk_partitioned_fk_full_x_y_fkey" +DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. +TRUNCATE fk_partitioned_fk_full; +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); -- fails +ERROR: insert or update on table "fk_partitioned_fk_full_1" violates foreign key constraint "fk_partitioned_fk_full_x_y_fkey" +DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. +DROP TABLE fk_partitioned_fk_full; -- ON UPDATE SET NULL SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a; tableoid | a | b @@ -1577,7 +1714,7 @@ SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL; (1 row) -- ON UPDATE/DELETE SET DEFAULT -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE SET DEFAULT ON UPDATE SET DEFAULT; @@ -1586,7 +1723,7 @@ INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); -- this fails, because the defaults for the referencing table are not present -- in the referenced table: UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502; -ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_3" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(2501, 142857) is not present in table "fk_notpartitioned_pk". -- but inserting the row we can make it work: INSERT INTO fk_notpartitioned_pk VALUES (2501, 142857); @@ -1598,7 +1735,7 @@ SELECT * FROM fk_partitioned_fk WHERE b = 142857; (1 row) -- ON UPDATE/DELETE CASCADE -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE CASCADE ON UPDATE CASCADE; @@ -1625,6 +1762,125 @@ SELECT * FROM fk_partitioned_fk WHERE a = 142857; -- verify that DROP works DROP TABLE fk_partitioned_fk_2; +-- Test behavior of the constraint together with attaching and detaching +-- partitions. +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2; +BEGIN; +DROP TABLE fk_partitioned_fk; +-- constraint should still be there +\d fk_partitioned_fk_2; + Table "public.fk_partitioned_fk_2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | 2501 + b | integer | | | 142857 +Foreign-key constraints: + "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE + +ROLLBACK; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); +DROP TABLE fk_partitioned_fk_2; +CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CASCADE ON DELETE CASCADE); +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN c; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); +-- should have only one constraint +\d fk_partitioned_fk_2 + Table "public.fk_partitioned_fk_2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + b | integer | | | + a | integer | | | +Partition of: fk_partitioned_fk FOR VALUES IN (1500, 1502) +Foreign-key constraints: + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE + +DROP TABLE fk_partitioned_fk_2; +CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE) PARTITION BY RANGE (b, a); +CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1,1) TO (100,100); +CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL); +ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100,100) TO (1000,1000); +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); +-- should only have one constraint +\d fk_partitioned_fk_4 + Partitioned table "public.fk_partitioned_fk_4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Partition of: fk_partitioned_fk FOR VALUES IN (3500, 3502) +Partition key: RANGE (b, a) +Foreign-key constraints: + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE +Number of partitions: 2 (Use \d+ to list them.) + +\d fk_partitioned_fk_4_1 + Table "public.fk_partitioned_fk_4_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Partition of: fk_partitioned_fk_4 FOR VALUES FROM (1, 1) TO (100, 100) +Foreign-key constraints: + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE + +-- this one has an FK with mismatched properties +\d fk_partitioned_fk_4_2 + Table "public.fk_partitioned_fk_4_2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Partition of: fk_partitioned_fk_4 FOR VALUES FROM (100, 100) TO (1000, 1000) +Foreign-key constraints: + "fk_partitioned_fk_4_2_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE + +CREATE TABLE fk_partitioned_fk_5 (a int, b int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE) + PARTITION BY RANGE (a); +CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk); +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); +-- this one has two constraints, similar but not quite the one in the parent, +-- so it gets a new one +\d fk_partitioned_fk_5 + Partitioned table "public.fk_partitioned_fk_5" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Partition of: fk_partitioned_fk FOR VALUES IN (4500) +Partition key: RANGE (a) +Foreign-key constraints: + "fk_partitioned_fk_5_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE + "fk_partitioned_fk_5_a_b_fkey1" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE +Number of partitions: 1 (Use \d+ to list them.) + +-- verify that it works to reattaching a child with multiple candidate +-- constraints +ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1; +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); +\d fk_partitioned_fk_5_1 + Table "public.fk_partitioned_fk_5_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | +Partition of: fk_partitioned_fk_5 FOR VALUES FROM (0) TO (10) +Foreign-key constraints: + "fk_partitioned_fk_5_1_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) + TABLE "fk_partitioned_fk_5" CONSTRAINT "fk_partitioned_fk_5_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE + TABLE "fk_partitioned_fk_5" CONSTRAINT "fk_partitioned_fk_5_a_b_fkey1" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE + TABLE "fk_partitioned_fk" CONSTRAINT "fk_partitioned_fk_a_b_fkey" FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE + -- verify that attaching a table checks that the existing data satisfies the -- constraint CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b); @@ -1633,9 +1889,508 @@ CREATE TABLE fk_partitioned_fk_2_2 PARTITION OF fk_partitioned_fk_2 FOR VALUES F INSERT INTO fk_partitioned_fk_2 VALUES (1600, 601), (1600, 1601); ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1600); -ERROR: insert or update on table "fk_partitioned_fk_2" violates foreign key constraint "fk_partitioned_fk_a_fkey" +ERROR: insert or update on table "fk_partitioned_fk_2_1" violates foreign key constraint "fk_partitioned_fk_a_b_fkey" DETAIL: Key (a, b)=(1600, 601) is not present in table "fk_notpartitioned_pk". INSERT INTO fk_notpartitioned_pk VALUES (1600, 601), (1600, 1601); ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1600); -- leave these tables around intentionally +-- test the case when the referenced table is owned by a different user +create role regress_other_partitioned_fk_owner; +grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner; +set role regress_other_partitioned_fk_owner; +create table other_partitioned_fk(a int, b int) partition by list (a); +create table other_partitioned_fk_1 partition of other_partitioned_fk + for values in (2048); +insert into other_partitioned_fk + select 2048, x from generate_series(1,10) x; +-- this should fail +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); +ERROR: insert or update on table "other_partitioned_fk_1" violates foreign key constraint "other_partitioned_fk_a_b_fkey" +DETAIL: Key (a, b)=(2048, 1) is not present in table "fk_notpartitioned_pk". +-- add the missing keys and retry +reset role; +insert into fk_notpartitioned_pk (a, b) + select 2048, x from generate_series(1,10) x; +set role regress_other_partitioned_fk_owner; +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); +-- clean up +drop table other_partitioned_fk; +reset role; +revoke all on fk_notpartitioned_pk from regress_other_partitioned_fk_owner; +drop role regress_other_partitioned_fk_owner; +-- Test creating a constraint at the parent that already exists in partitions. +-- There should be no duplicated constraints, and attempts to drop the +-- constraint in partitions should raise appropriate errors. +create schema fkpart0 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (1) + create table fk_part_23 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (2, 3) + partition by list (a) + create table fk_part_23_2 partition of fk_part_23 for values in (2); +alter table fkpart0.fk_part add foreign key (a) references fkpart0.pkey; +\d fkpart0.fk_part_1 \\ -- should have only one FK + Table "fkpart0.fk_part_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: fkpart0.fk_part FOR VALUES IN (1) +Foreign-key constraints: + TABLE "fkpart0.fk_part" CONSTRAINT "fk_part_a_fkey" FOREIGN KEY (a) REFERENCES fkpart0.pkey(a) + +alter table fkpart0.fk_part_1 drop constraint fk_part_1_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_1_a_fkey" of relation "fk_part_1" +\d fkpart0.fk_part_23 \\ -- should have only one FK + Partitioned table "fkpart0.fk_part_23" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: fkpart0.fk_part FOR VALUES IN (2, 3) +Partition key: LIST (a) +Foreign-key constraints: + TABLE "fkpart0.fk_part" CONSTRAINT "fk_part_a_fkey" FOREIGN KEY (a) REFERENCES fkpart0.pkey(a) +Number of partitions: 1 (Use \d+ to list them.) + +\d fkpart0.fk_part_23_2 \\ -- should have only one FK + Table "fkpart0.fk_part_23_2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: fkpart0.fk_part_23 FOR VALUES IN (2) +Foreign-key constraints: + TABLE "fkpart0.fk_part" CONSTRAINT "fk_part_a_fkey" FOREIGN KEY (a) REFERENCES fkpart0.pkey(a) + +alter table fkpart0.fk_part_23 drop constraint fk_part_23_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_23_a_fkey" of relation "fk_part_23" +alter table fkpart0.fk_part_23_2 drop constraint fk_part_23_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_23_a_fkey" of relation "fk_part_23_2" +create table fkpart0.fk_part_4 partition of fkpart0.fk_part for values in (4); +\d fkpart0.fk_part_4 + Table "fkpart0.fk_part_4" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: fkpart0.fk_part FOR VALUES IN (4) +Foreign-key constraints: + TABLE "fkpart0.fk_part" CONSTRAINT "fk_part_a_fkey" FOREIGN KEY (a) REFERENCES fkpart0.pkey(a) + +alter table fkpart0.fk_part_4 drop constraint fk_part_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_a_fkey" of relation "fk_part_4" +create table fkpart0.fk_part_56 partition of fkpart0.fk_part + for values in (5,6) partition by list (a); +create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56 + for values in (5); +\d fkpart0.fk_part_56 + Partitioned table "fkpart0.fk_part_56" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: fkpart0.fk_part FOR VALUES IN (5, 6) +Partition key: LIST (a) +Foreign-key constraints: + TABLE "fkpart0.fk_part" CONSTRAINT "fk_part_a_fkey" FOREIGN KEY (a) REFERENCES fkpart0.pkey(a) +Number of partitions: 1 (Use \d+ to list them.) + +alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_a_fkey" of relation "fk_part_56" +alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey; +ERROR: cannot drop inherited constraint "fk_part_a_fkey" of relation "fk_part_56_5" +-- verify that attaching and detaching partitions maintains the right set of +-- triggers +create schema fkpart1 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fk_part_1 for values in (1); +alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey; +insert into fkpart1.fk_part values (1); -- should fail +ERROR: insert or update on table "fk_part_1_1" violates foreign key constraint "fk_part_a_fkey" +DETAIL: Key (a)=(1) is not present in table "pkey". +insert into fkpart1.pkey values (1); +insert into fkpart1.fk_part values (1); +delete from fkpart1.pkey where a = 1; -- should fail +ERROR: update or delete on table "pkey" violates foreign key constraint "fk_part_a_fkey" on table "fk_part" +DETAIL: Key (a)=(1) is still referenced from table "fk_part". +alter table fkpart1.fk_part detach partition fkpart1.fk_part_1; +create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2); +insert into fkpart1.fk_part_1 values (2); -- should fail +ERROR: insert or update on table "fk_part_1_2" violates foreign key constraint "fk_part_a_fkey" +DETAIL: Key (a)=(2) is not present in table "pkey". +delete from fkpart1.pkey where a = 1; +ERROR: update or delete on table "pkey" violates foreign key constraint "fk_part_a_fkey" on table "fk_part_1" +DETAIL: Key (a)=(1) is still referenced from table "fk_part_1". +-- verify that attaching and detaching partitions manipulates the inheritance +-- properties of their FK constraints correctly +create schema fkpart2 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart2.pkey) partition by list (a) + create table fk_part_1 partition of fkpart2.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 (a int, constraint my_fkey foreign key (a) references fkpart2.pkey); +alter table fkpart2.fk_part_1 attach partition fkpart2.fk_part_1_1 for values in (1); +alter table fkpart2.fk_part_1 drop constraint fkey; -- should fail +ERROR: cannot drop inherited constraint "fkey" of relation "fk_part_1" +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; -- should fail +ERROR: cannot drop inherited constraint "my_fkey" of relation "fk_part_1_1" +alter table fkpart2.fk_part detach partition fkpart2.fk_part_1; +alter table fkpart2.fk_part_1 drop constraint fkey; -- ok +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; -- doesn't exist +ERROR: constraint "my_fkey" of relation "fk_part_1_1" does not exist +drop schema fkpart0, fkpart1, fkpart2 cascade; +NOTICE: drop cascades to 8 other objects +DETAIL: drop cascades to table fkpart2.pkey +drop cascades to table fkpart2.fk_part +drop cascades to table fkpart2.fk_part_1 +drop cascades to table fkpart1.pkey +drop cascades to table fkpart1.fk_part +drop cascades to table fkpart1.fk_part_1 +drop cascades to table fkpart0.pkey +drop cascades to table fkpart0.fk_part +-- Test a partitioned table as referenced table. +-- Verify basic functionality with a regular partition creation and a partition +-- with a different column layout, as well as partitions added (created and +-- attached) after creating the foreign key. +CREATE SCHEMA fkpart3; +SET search_path TO fkpart3; +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000); +CREATE TABLE pk2 (b int, a int); +ALTER TABLE pk2 DROP COLUMN b; +ALTER TABLE pk2 ALTER a SET NOT NULL; +ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000); +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; +CREATE TABLE fk2 (b int, a int) ; +ALTER TABLE fk2 DROP COLUMN b; +ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500); +CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000); +CREATE TABLE pk4 (LIKE pk); +ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000); +CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a); +ALTER TABLE pk5 DROP COLUMN b, DROP COLUMN c; +CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500); +CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000); +ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000); +CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000); +-- these should fail: referenced value not present +INSERT into fk VALUES (1); +ERROR: insert or update on table "fk1" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(1) is not present in table "pk". +INSERT into fk VALUES (1000); +ERROR: insert or update on table "fk2" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(1000) is not present in table "pk". +INSERT into fk VALUES (2000); +ERROR: insert or update on table "fk2" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(2000) is not present in table "pk". +INSERT into fk VALUES (3000); +ERROR: insert or update on table "fk2" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(3000) is not present in table "pk". +INSERT into fk VALUES (4000); +ERROR: insert or update on table "fk3" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(4000) is not present in table "pk". +INSERT into fk VALUES (4500); +ERROR: insert or update on table "fk3" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(4500) is not present in table "pk". +-- insert into the referenced table, now they should work +INSERT into pk VALUES (1), (1000), (2000), (3000), (4000), (4500); +INSERT into fk VALUES (1), (1000), (2000), (3000), (4000), (4500); +-- should fail: referencing value present +DELETE FROM pk WHERE a = 1; +ERROR: update or delete on table "pk1" violates foreign key constraint "fk_a_fkey1" on table "fk" +DETAIL: Key (a)=(1) is still referenced from table "fk". +DELETE FROM pk WHERE a = 1000; +ERROR: update or delete on table "pk2" violates foreign key constraint "fk_a_fkey2" on table "fk" +DETAIL: Key (a)=(1000) is still referenced from table "fk". +DELETE FROM pk WHERE a = 2000; +ERROR: update or delete on table "pk3" violates foreign key constraint "fk_a_fkey3" on table "fk" +DETAIL: Key (a)=(2000) is still referenced from table "fk". +DELETE FROM pk WHERE a = 3000; +ERROR: update or delete on table "pk4" violates foreign key constraint "fk_a_fkey4" on table "fk" +DETAIL: Key (a)=(3000) is still referenced from table "fk". +DELETE FROM pk WHERE a = 4000; +ERROR: update or delete on table "pk51" violates foreign key constraint "fk_a_fkey6" on table "fk" +DETAIL: Key (a)=(4000) is still referenced from table "fk". +DELETE FROM pk WHERE a = 4500; +ERROR: update or delete on table "pk52" violates foreign key constraint "fk_a_fkey7" on table "fk" +DETAIL: Key (a)=(4500) is still referenced from table "fk". +UPDATE pk SET a = 2 WHERE a = 1; +ERROR: update or delete on table "pk1" violates foreign key constraint "fk_a_fkey1" on table "fk" +DETAIL: Key (a)=(1) is still referenced from table "fk". +UPDATE pk SET a = 1002 WHERE a = 1000; +ERROR: update or delete on table "pk2" violates foreign key constraint "fk_a_fkey2" on table "fk" +DETAIL: Key (a)=(1000) is still referenced from table "fk". +UPDATE pk SET a = 2002 WHERE a = 2000; +ERROR: update or delete on table "pk3" violates foreign key constraint "fk_a_fkey3" on table "fk" +DETAIL: Key (a)=(2000) is still referenced from table "fk". +UPDATE pk SET a = 3002 WHERE a = 3000; +ERROR: update or delete on table "pk4" violates foreign key constraint "fk_a_fkey4" on table "fk" +DETAIL: Key (a)=(3000) is still referenced from table "fk". +UPDATE pk SET a = 4002 WHERE a = 4000; +ERROR: update or delete on table "pk51" violates foreign key constraint "fk_a_fkey6" on table "fk" +DETAIL: Key (a)=(4000) is still referenced from table "fk". +UPDATE pk SET a = 4502 WHERE a = 4500; +ERROR: update or delete on table "pk52" violates foreign key constraint "fk_a_fkey7" on table "fk" +DETAIL: Key (a)=(4500) is still referenced from table "fk". +-- now they should work +DELETE FROM fk; +UPDATE pk SET a = 2 WHERE a = 1; +DELETE FROM pk WHERE a = 2; +UPDATE pk SET a = 1002 WHERE a = 1000; +DELETE FROM pk WHERE a = 1002; +UPDATE pk SET a = 2002 WHERE a = 2000; +DELETE FROM pk WHERE a = 2002; +UPDATE pk SET a = 3002 WHERE a = 3000; +DELETE FROM pk WHERE a = 3002; +UPDATE pk SET a = 4002 WHERE a = 4000; +DELETE FROM pk WHERE a = 4002; +UPDATE pk SET a = 4502 WHERE a = 4500; +DELETE FROM pk WHERE a = 4502; +CREATE SCHEMA fkpart4; +SET search_path TO fkpart4; +-- dropping/detaching PARTITIONs is prevented if that would break +-- a foreign key's existing data +CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000); +CREATE TABLE droppk_d PARTITION OF droppk DEFAULT; +CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) + PARTITION BY RANGE (a); +CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400); +CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT; +INSERT into droppk VALUES (1), (1000), (1500), (2000); +CREATE TABLE dropfk (a int REFERENCES droppk); +INSERT into dropfk VALUES (1), (1000), (1500), (2000); +-- these should all fail +ALTER TABLE droppk DETACH PARTITION droppk_d; +ERROR: removing partition "droppk_d" violates foreign key constraint "dropfk_a_fkey5" +DETAIL: Key (a)=(2000) is still referenced from table "dropfk". +ALTER TABLE droppk2 DETACH PARTITION droppk2_d; +ERROR: removing partition "droppk2_d" violates foreign key constraint "dropfk_a_fkey4" +DETAIL: Key (a)=(1500) is still referenced from table "dropfk". +ALTER TABLE droppk DETACH PARTITION droppk1; +ERROR: removing partition "droppk1" violates foreign key constraint "dropfk_a_fkey1" +DETAIL: Key (a)=(1) is still referenced from table "dropfk". +ALTER TABLE droppk DETACH PARTITION droppk2; +ERROR: removing partition "droppk2" violates foreign key constraint "dropfk_a_fkey2" +DETAIL: Key (a)=(1000) is still referenced from table "dropfk". +ALTER TABLE droppk2 DETACH PARTITION droppk21; +ERROR: removing partition "droppk21" violates foreign key constraint "dropfk_a_fkey3" +DETAIL: Key (a)=(1000) is still referenced from table "dropfk". +-- dropping partitions is disallowed +DROP TABLE droppk_d; +ERROR: cannot drop table droppk_d because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk_d +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk2_d; +ERROR: cannot drop table droppk2_d because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk2_d +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk1; +ERROR: cannot drop table droppk1 because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk1 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk2; +ERROR: cannot drop table droppk2 because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk21; +ERROR: cannot drop table droppk21 because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk21 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DELETE FROM dropfk; +-- dropping partitions is disallowed, even when no referencing values +DROP TABLE droppk_d; +ERROR: cannot drop table droppk_d because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk_d +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk2_d; +ERROR: cannot drop table droppk2_d because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk2_d +HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP TABLE droppk1; +ERROR: cannot drop table droppk1 because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk1 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- but DETACH is allowed, and DROP afterwards works +ALTER TABLE droppk2 DETACH PARTITION droppk21; +DROP TABLE droppk2; +ERROR: cannot drop table droppk2 because other objects depend on it +DETAIL: constraint dropfk_a_fkey on table dropfk depends on table droppk2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- Verify that initial constraint creation and cloning behave correctly +CREATE SCHEMA fkpart5; +SET search_path TO fkpart5; +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a); +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1); +CREATE TABLE fk (a int) PARTITION BY LIST (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2); +CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a); +CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31); +CREATE TABLE pk32 (b int, a int NOT NULL); +ALTER TABLE pk32 DROP COLUMN b; +ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32); +ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32); +CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2); +CREATE TABLE fk3 (b int, a int); +ALTER TABLE fk3 DROP COLUMN b; +ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3); +SELECT pg_describe_object('pg_constraint'::regclass, oid, 0), confrelid::regclass, + CASE WHEN conparentid <> 0 THEN pg_describe_object('pg_constraint'::regclass, conparentid, 0) ELSE 'TOP' END +FROM pg_catalog.pg_constraint +WHERE conrelid IN (SELECT relid FROM pg_partition_tree('fk')) +ORDER BY conrelid::regclass::text, conname; + pg_describe_object | confrelid | case +------------------------------------+-----------+----------------------------------- + constraint fk_a_fkey on table fk | pk | TOP + constraint fk_a_fkey1 on table fk | pk1 | constraint fk_a_fkey on table fk + constraint fk_a_fkey2 on table fk | pk11 | constraint fk_a_fkey1 on table fk + constraint fk_a_fkey3 on table fk | pk2 | constraint fk_a_fkey on table fk + constraint fk_a_fkey4 on table fk | pk3 | constraint fk_a_fkey on table fk + constraint fk_a_fkey5 on table fk | pk31 | constraint fk_a_fkey4 on table fk + constraint fk_a_fkey6 on table fk | pk32 | constraint fk_a_fkey4 on table fk + constraint fk_a_fkey on table fk1 | pk | constraint fk_a_fkey on table fk + constraint fk_a_fkey on table fk11 | pk | constraint fk_a_fkey on table fk1 + constraint fk_a_fkey on table fk2 | pk | constraint fk_a_fkey on table fk + constraint fk_a_fkey on table fk3 | pk | constraint fk_a_fkey on table fk +(11 rows) + +CREATE TABLE fk4 (LIKE fk); +INSERT INTO fk4 VALUES (50); +ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50); +ERROR: insert or update on table "fk4" violates foreign key constraint "fk_a_fkey" +DETAIL: Key (a)=(50) is not present in table "pk". +-- Verify ON UPDATE/DELETE behavior +CREATE SCHEMA fkpart6; +SET search_path TO fkpart6; +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50); +CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100); +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO pk VALUES (1); +INSERT INTO fk VALUES (1); +UPDATE pk SET a = 20; +SELECT tableoid::regclass, * FROM fk; + tableoid | a +----------+---- + fk12 | 20 +(1 row) + +DELETE FROM pk WHERE a = 20; +SELECT tableoid::regclass, * FROM fk; + tableoid | a +----------+--- +(0 rows) + +DROP TABLE fk; +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (50); +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (20), (50); +UPDATE pk SET a = 21 WHERE a = 20; +DELETE FROM pk WHERE a = 50; +SELECT tableoid::regclass, * FROM fk; + tableoid | a +----------+--- + fk_d | + fk_d | +(2 rows) + +DROP TABLE fk; +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (30), (50); +CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (1, 20), (2, 30); +DELETE FROM pk WHERE a = 20 RETURNING *; + a +---- + 20 +(1 row) + +UPDATE pk SET a = 90 WHERE a = 30 RETURNING *; + a +---- + 90 +(1 row) + +SELECT tableoid::regclass, * FROM fk; + tableoid | id | a +----------+----+---- + fk12 | 1 | 50 + fk12 | 2 | 50 +(2 rows) + +DROP TABLE fk; +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (30); +CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (20), (30); +DELETE FROM pk WHERE a = 20; +ERROR: update or delete on table "pk11" violates foreign key constraint "fk_a_fkey2" on table "fk" +DETAIL: Key (a)=(20) is still referenced from table "fk". +UPDATE pk SET a = 90 WHERE a = 30; +ERROR: update or delete on table "pk11" violates foreign key constraint "fk_a_fkey2" on table "fk" +DETAIL: Key (a)=(30) is still referenced from table "fk". +SELECT tableoid::regclass, * FROM fk; + tableoid | a +----------+---- + fk12 | 20 + fk12 | 30 +(2 rows) + +DROP TABLE fk; +-- test for reported bug: relispartition not set +-- https://postgr.es/m/CA+HiwqHMsRtRYRWYTWavKJ8x14AFsv7bmAV46mYwnfD3vy8goQ@mail.gmail.com +CREATE SCHEMA fkpart7 + CREATE TABLE pkpart (a int) PARTITION BY LIST (a) + CREATE TABLE pkpart1 PARTITION OF pkpart FOR VALUES IN (1); +ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a); +ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a); +CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart); +DROP SCHEMA fkpart7 CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table fkpart7.pkpart +drop cascades to table fkpart7.fk +-- ensure we check partitions are "not used" when dropping constraints +CREATE SCHEMA fkpart8 + CREATE TABLE tbl1(f1 int PRIMARY KEY) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE(f1) + CREATE TABLE tbl2_p1 PARTITION OF tbl2 FOR VALUES FROM (minvalue) TO (maxvalue); +INSERT INTO fkpart8.tbl1 VALUES(1); +BEGIN; +INSERT INTO fkpart8.tbl2 VALUES(1); +ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey; +ERROR: cannot ALTER TABLE "tbl2_p1" because it has pending trigger events +COMMIT; +DROP SCHEMA fkpart8 CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table fkpart8.tbl1 +drop cascades to table fkpart8.tbl2 diff --git a/src/test/regress/expected/func_index.out b/src/test/regress/expected/func_index.out deleted file mode 100644 index 307ac97b4bc..00000000000 --- a/src/test/regress/expected/func_index.out +++ /dev/null @@ -1,64 +0,0 @@ -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=false); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 0 -(1 row) - -rollback; -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=true); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 1 -(1 row) - -update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 1 -(1 row) - -update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 2 -(1 row) - -rollback; -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 1 -(1 row) - -update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 1 -(1 row) - -update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); - pg_stat_get_xact_tuples_hot_updated -------------------------------------- - 2 -(1 row) - -rollback; diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out new file mode 100644 index 00000000000..f62c93f4686 --- /dev/null +++ b/src/test/regress/expected/generated.out @@ -0,0 +1,796 @@ +-- sanity check of system catalog +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's'); + attrelid | attname | attgenerated +----------+---------+-------------- +(0 rows) + +CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED); +CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2; + table_name | column_name | column_default | is_nullable | is_generated | generation_expression +------------+-------------+----------------+-------------+--------------+----------------------- + gtest0 | a | | NO | NEVER | + gtest0 | b | | YES | ALWAYS | 55 + gtest1 | a | | NO | NEVER | + gtest1 | b | | YES | ALWAYS | (a * 2) +(4 rows) + +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage ORDER BY 1, 2, 3; + table_name | column_name | dependent_column +------------+-------------+------------------ + gtest1 | a | b +(1 row) + +\d gtest1 + Table "public.gtest1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | not null | + b | integer | | | generated always as (a * 2) stored +Indexes: + "gtest1_pkey" PRIMARY KEY, btree (a) + +-- duplicate generated +CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED); +ERROR: multiple generation clauses specified for column "b" of table "gtest_err_1" +LINE 1: ...ARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ... + ^ +-- references to other generated columns, including self-references +CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED); +ERROR: cannot use generated column "b" in column generation expression +LINE 1: ...2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STO... + ^ +DETAIL: A generated column cannot reference another generated column. +CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED); +ERROR: cannot use generated column "b" in column generation expression +LINE 1: ...AYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STO... + ^ +DETAIL: A generated column cannot reference another generated column. +-- invalid reference +CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED); +ERROR: column "c" does not exist +LINE 1: ..._3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STO... + ^ +-- generation expression must be immutable +CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED); +ERROR: generation expression is not immutable +-- cannot have default/identity and generated +CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED); +ERROR: both default and generation expression specified for column "b" of table "gtest_err_5a" +LINE 1: ... gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ... + ^ +CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED); +ERROR: both identity and generation expression specified for column "b" of table "gtest_err_5b" +LINE 1: ...t PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ... + ^ +-- reference to system column not allowed in generated column +CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED); +ERROR: cannot use system column "xmin" in column generation expression +LINE 1: ...a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37... + ^ +-- various prohibited constructs +CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED); +ERROR: aggregate functions are not allowed in column generation expressions +LINE 1: ...7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) ST... + ^ +CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED); +ERROR: window functions are not allowed in column generation expressions +LINE 1: ...7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number... + ^ +CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED); +ERROR: cannot use subquery in column generation expression +LINE 1: ...7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)... + ^ +CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED); +ERROR: set-returning functions are not allowed in column generation expressions +LINE 1: ...7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_s... + ^ +-- GENERATED BY DEFAULT not allowed +CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED); +ERROR: for a generated column, GENERATED ALWAYS must be specified +LINE 1: ...E gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT... + ^ +INSERT INTO gtest1 VALUES (1); +INSERT INTO gtest1 VALUES (2, DEFAULT); +INSERT INTO gtest1 VALUES (3, 33); -- error +ERROR: cannot insert into column "b" +DETAIL: Column "b" is a generated column. +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 1 | 2 + 2 | 4 +(2 rows) + +UPDATE gtest1 SET b = DEFAULT WHERE a = 1; +UPDATE gtest1 SET b = 11 WHERE a = 1; -- error +ERROR: column "b" can only be updated to DEFAULT +DETAIL: Column "b" is a generated column. +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 1 | 2 + 2 | 4 +(2 rows) + +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a; + a | b | b2 +---+---+---- + 1 | 2 | 4 + 2 | 4 | 8 +(2 rows) + +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a; + a | b +---+--- + 2 | 4 +(1 row) + +-- test that overflow error happens on write +INSERT INTO gtest1 VALUES (2000000000); +ERROR: integer out of range +SELECT * FROM gtest1; + a | b +---+--- + 2 | 4 + 1 | 2 +(2 rows) + +DELETE FROM gtest1 WHERE a = 2000000000; +-- test with joins +CREATE TABLE gtestx (x int, y int); +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3); +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a; + x | y | a | b +----+---+---+--- + 11 | 1 | 1 | 2 + 22 | 2 | 2 | 4 +(2 rows) + +DROP TABLE gtestx; +-- test UPDATE/DELETE quals +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 1 | 2 + 2 | 4 +(2 rows) + +UPDATE gtest1 SET a = 3 WHERE b = 4; +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 1 | 2 + 3 | 6 +(2 rows) + +DELETE FROM gtest1 WHERE b = 2; +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 3 | 6 +(1 row) + +-- views +CREATE VIEW gtest1v AS SELECT * FROM gtest1; +SELECT * FROM gtest1v; + a | b +---+--- + 3 | 6 +(1 row) + +INSERT INTO gtest1v VALUES (4, 8); -- fails +ERROR: cannot insert into column "b" +DETAIL: Column "b" is a generated column. +DROP VIEW gtest1v; +-- CTEs +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo; + a | b +---+--- + 3 | 6 +(1 row) + +-- inheritance +CREATE TABLE gtest1_1 () INHERITS (gtest1); +SELECT * FROM gtest1_1; + a | b +---+--- +(0 rows) + +\d gtest1_1 + Table "public.gtest1_1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | not null | + b | integer | | | generated always as (a * 2) stored +Inherits: gtest1 + +INSERT INTO gtest1_1 VALUES (4); +SELECT * FROM gtest1_1; + a | b +---+--- + 4 | 8 +(1 row) + +SELECT * FROM gtest1; + a | b +---+--- + 3 | 6 + 4 | 8 +(2 rows) + +-- test inheritance mismatch +CREATE TABLE gtesty (x int, b int); +CREATE TABLE gtest1_2 () INHERITS (gtest1, gtesty); -- error +NOTICE: merging multiple inherited definitions of column "b" +ERROR: inherited column "b" has a generation conflict +DROP TABLE gtesty; +-- test stored update +CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED); +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL); +SELECT * FROM gtest3 ORDER BY a; + a | b +---+--- + 1 | 3 + 2 | 6 + 3 | 9 + | +(4 rows) + +UPDATE gtest3 SET a = 22 WHERE a = 2; +SELECT * FROM gtest3 ORDER BY a; + a | b +----+---- + 1 | 3 + 3 | 9 + 22 | 66 + | +(4 rows) + +CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED); +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL); +SELECT * FROM gtest3a ORDER BY a; + a | b +---+----- + a | a+a + b | b+b + c | c+c + | +(4 rows) + +UPDATE gtest3a SET a = 'bb' WHERE a = 'b'; +SELECT * FROM gtest3a ORDER BY a; + a | b +----+------- + a | a+a + bb | bb+bb + c | c+c + | +(4 rows) + +-- COPY +TRUNCATE gtest1; +INSERT INTO gtest1 (a) VALUES (1), (2); +COPY gtest1 TO stdout; +1 +2 +COPY gtest1 (a, b) TO stdout; +ERROR: column "b" is a generated column +DETAIL: Generated columns cannot be used in COPY. +COPY gtest1 FROM stdin; +COPY gtest1 (a, b) FROM stdin; +ERROR: column "b" is a generated column +DETAIL: Generated columns cannot be used in COPY. +SELECT * FROM gtest1 ORDER BY a; + a | b +---+--- + 1 | 2 + 2 | 4 + 3 | 6 + 4 | 8 +(4 rows) + +TRUNCATE gtest3; +INSERT INTO gtest3 (a) VALUES (1), (2); +COPY gtest3 TO stdout; +1 +2 +COPY gtest3 (a, b) TO stdout; +ERROR: column "b" is a generated column +DETAIL: Generated columns cannot be used in COPY. +COPY gtest3 FROM stdin; +COPY gtest3 (a, b) FROM stdin; +ERROR: column "b" is a generated column +DETAIL: Generated columns cannot be used in COPY. +SELECT * FROM gtest3 ORDER BY a; + a | b +---+---- + 1 | 3 + 2 | 6 + 3 | 9 + 4 | 12 +(4 rows) + +-- null values +CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED); +INSERT INTO gtest2 VALUES (1); +SELECT * FROM gtest2; + a | b +---+--- + 1 | +(1 row) + +-- composite types +CREATE TYPE double_int as (a int, b int); +CREATE TABLE gtest4 ( + a int, + b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED +); +INSERT INTO gtest4 VALUES (1), (6); +SELECT * FROM gtest4; + a | b +---+--------- + 1 | (2,3) + 6 | (12,18) +(2 rows) + +DROP TABLE gtest4; +DROP TYPE double_int; +-- using tableoid is allowed +CREATE TABLE gtest_tableoid ( + a int PRIMARY KEY, + b bool GENERATED ALWAYS AS (tableoid <> 0) STORED +); +INSERT INTO gtest_tableoid VALUES (1), (2); +SELECT * FROM gtest_tableoid; + a | b +---+--- + 1 | t + 2 | t +(2 rows) + +-- drop column behavior +CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); +ALTER TABLE gtest10 DROP COLUMN b; +\d gtest10 + Table "public.gtest10" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | not null | +Indexes: + "gtest10_pkey" PRIMARY KEY, btree (a) + +CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +ALTER TABLE gtest10a DROP COLUMN b; +INSERT INTO gtest10a (a) VALUES (1); +-- privileges +CREATE USER regress_user11; +CREATE TABLE gtest11s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); +INSERT INTO gtest11s VALUES (1, 10), (2, 20); +GRANT SELECT (a, c) ON gtest11s TO regress_user11; +CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL; +REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; +CREATE TABLE gtest12s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); +INSERT INTO gtest12s VALUES (1, 10), (2, 20); +GRANT SELECT (a, c) ON gtest12s TO regress_user11; +SET ROLE regress_user11; +SELECT a, b FROM gtest11s; -- not allowed +ERROR: permission denied for table gtest11s +SELECT a, c FROM gtest11s; -- allowed + a | c +---+---- + 1 | 20 + 2 | 40 +(2 rows) + +SELECT gf1(10); -- not allowed +ERROR: permission denied for function gf1 +SELECT a, c FROM gtest12s; -- allowed + a | c +---+---- + 1 | 30 + 2 | 60 +(2 rows) + +RESET ROLE; +DROP TABLE gtest11s, gtest12s; +DROP FUNCTION gf1(int); +DROP USER regress_user11; +-- check constraints +CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50)); +INSERT INTO gtest20 (a) VALUES (10); -- ok +INSERT INTO gtest20 (a) VALUES (30); -- violates constraint +ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check" +DETAIL: Failing row contains (30, 60). +CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20a (a) VALUES (10); +INSERT INTO gtest20a (a) VALUES (30); +ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row +ERROR: check constraint "gtest20a_b_check" is violated by some row +CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20b (a) VALUES (10); +INSERT INTO gtest20b (a) VALUES (30); +ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; +ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row +ERROR: check constraint "chk" is violated by some row +-- not-null constraints +CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); +INSERT INTO gtest21a (a) VALUES (1); -- ok +INSERT INTO gtest21a (a) VALUES (0); -- violates constraint +ERROR: null value in column "b" violates not-null constraint +DETAIL: Failing row contains (0, null). +CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED); +ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL; +INSERT INTO gtest21b (a) VALUES (1); -- ok +INSERT INTO gtest21b (a) VALUES (0); -- violates constraint +ERROR: null value in column "b" violates not-null constraint +DETAIL: Failing row contains (0, null). +ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL; +INSERT INTO gtest21b (a) VALUES (0); -- ok now +-- index constraints +CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE); +INSERT INTO gtest22a VALUES (2); +INSERT INTO gtest22a VALUES (3); +ERROR: duplicate key value violates unique constraint "gtest22a_b_key" +DETAIL: Key (b)=(1) already exists. +INSERT INTO gtest22a VALUES (4); +CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b)); +INSERT INTO gtest22b VALUES (2); +INSERT INTO gtest22b VALUES (2); +ERROR: duplicate key value violates unique constraint "gtest22b_pkey" +DETAIL: Key (a, b)=(2, 1) already exists. +-- indexes +CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +CREATE INDEX gtest22c_b_idx ON gtest22c (b); +CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3)); +CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0; +\d gtest22c + Table "public.gtest22c" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | | + b | integer | | | generated always as (a * 2) stored +Indexes: + "gtest22c_b_idx" btree (b) + "gtest22c_expr_idx" btree ((b * 3)) + "gtest22c_pred_idx" btree (a) WHERE b > 0 + +INSERT INTO gtest22c VALUES (1), (2), (3); +SET enable_seqscan TO off; +SET enable_bitmapscan TO off; +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 4; + QUERY PLAN +--------------------------------------------- + Index Scan using gtest22c_b_idx on gtest22c + Index Cond: (b = 4) +(2 rows) + +SELECT * FROM gtest22c WHERE b = 4; + a | b +---+--- + 2 | 4 +(1 row) + +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 6; + QUERY PLAN +------------------------------------------------ + Index Scan using gtest22c_expr_idx on gtest22c + Index Cond: ((b * 3) = 6) +(2 rows) + +SELECT * FROM gtest22c WHERE b * 3 = 6; + a | b +---+--- + 1 | 2 +(1 row) + +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + QUERY PLAN +------------------------------------------------ + Index Scan using gtest22c_pred_idx on gtest22c + Index Cond: (a = 1) +(2 rows) + +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; + a | b +---+--- + 1 | 2 +(1 row) + +RESET enable_seqscan; +RESET enable_bitmapscan; +-- foreign keys +CREATE TABLE gtest23a (x int PRIMARY KEY, y int); +INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33); +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); -- error +ERROR: invalid ON UPDATE action for foreign key constraint containing generated column +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); -- error +ERROR: invalid ON DELETE action for foreign key constraint containing generated column +CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x)); +\d gtest23b + Table "public.gtest23b" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + a | integer | | not null | + b | integer | | | generated always as (a * 2) stored +Indexes: + "gtest23b_pkey" PRIMARY KEY, btree (a) +Foreign-key constraints: + "gtest23b_b_fkey" FOREIGN KEY (b) REFERENCES gtest23a(x) + +INSERT INTO gtest23b VALUES (1); -- ok +INSERT INTO gtest23b VALUES (5); -- error +ERROR: insert or update on table "gtest23b" violates foreign key constraint "gtest23b_b_fkey" +DETAIL: Key (b)=(10) is not present in table "gtest23a". +DROP TABLE gtest23b; +DROP TABLE gtest23a; +CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y)); +INSERT INTO gtest23p VALUES (1), (2), (3); +CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y)); +INSERT INTO gtest23q VALUES (1, 2); -- ok +INSERT INTO gtest23q VALUES (2, 5); -- error +ERROR: insert or update on table "gtest23q" violates foreign key constraint "gtest23q_b_fkey" +DETAIL: Key (b)=(5) is not present in table "gtest23p". +-- domains +CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); +CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest24 (a) VALUES (4); -- ok +INSERT INTO gtest24 (a) VALUES (6); -- error +ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check" +-- typed tables (currently not supported) +CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); +CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED); +ERROR: generated columns are not supported on typed tables +DROP TYPE gtest_type CASCADE; +-- table partitions (currently not supported) +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 text, f3 bigint) PARTITION BY RANGE (f1); +CREATE TABLE gtest_child PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 2) STORED +) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error +ERROR: generated columns are not supported on partitions +DROP TABLE gtest_parent; +-- partitioned table +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1); +CREATE TABLE gtest_child PARTITION OF gtest_parent FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); +SELECT * FROM gtest_parent; + f1 | f2 | f3 +------------+----+---- + 07-15-2016 | 1 | 2 +(1 row) + +SELECT * FROM gtest_child; + f1 | f2 | f3 +------------+----+---- + 07-15-2016 | 1 | 2 +(1 row) + +DROP TABLE gtest_parent; +-- generated columns in partition key (not allowed) +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); +ERROR: cannot use generated column in partition key +LINE 1: ...ENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); + ^ +DETAIL: Column "f3" is a generated column. +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); +ERROR: cannot use generated column in partition key +LINE 1: ...ED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); + ^ +DETAIL: Column "f3" is a generated column. +-- ALTER TABLE ... ADD COLUMN +CREATE TABLE gtest25 (a int PRIMARY KEY); +INSERT INTO gtest25 VALUES (3), (4); +ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 3) STORED; +SELECT * FROM gtest25 ORDER BY a; + a | b +---+---- + 3 | 9 + 4 | 12 +(2 rows) + +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error +ERROR: cannot use generated column "b" in column generation expression +DETAIL: A generated column cannot reference another generated column. +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error +ERROR: column "z" does not exist +-- ALTER TABLE ... ALTER COLUMN +CREATE TABLE gtest27 ( + a int, + b int GENERATED ALWAYS AS (a * 2) STORED +); +INSERT INTO gtest27 (a) VALUES (3), (4); +ALTER TABLE gtest27 ALTER COLUMN a TYPE text; -- error +ERROR: cannot alter type of a column used by a generated column +DETAIL: Column "a" is used by generated column "b". +ALTER TABLE gtest27 ALTER COLUMN b TYPE numeric; +\d gtest27 + Table "public.gtest27" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+-------------------------------------- + a | integer | | | + b | numeric | | | generated always as ((a * 2)) stored + +SELECT * FROM gtest27; + a | b +---+--- + 3 | 6 + 4 | 8 +(2 rows) + +ALTER TABLE gtest27 ALTER COLUMN b TYPE boolean USING b <> 0; -- error +ERROR: generation expression for column "b" cannot be cast automatically to type boolean +ALTER TABLE gtest27 ALTER COLUMN b DROP DEFAULT; -- error +ERROR: column "b" of relation "gtest27" is a generated column +\d gtest27 + Table "public.gtest27" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+-------------------------------------- + a | integer | | | + b | numeric | | | generated always as ((a * 2)) stored + +-- triggers +CREATE TABLE gtest26 ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); +CREATE FUNCTION gtest_trigger_func() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + IF tg_op IN ('DELETE', 'UPDATE') THEN + RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD; + END IF; + IF tg_op IN ('INSERT', 'UPDATE') THEN + RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW; + END IF; + IF tg_op = 'DELETE' THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; +END +$$; +CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); +CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- error + EXECUTE PROCEDURE gtest_trigger_func(); +ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns +LINE 3: WHEN (NEW.b < 0) + ^ +DETAIL: Column "b" is a generated column. +CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.* IS NOT NULL) -- error + EXECUTE PROCEDURE gtest_trigger_func(); +ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns +LINE 3: WHEN (NEW.* IS NOT NULL) + ^ +DETAIL: A whole-row reference is used and the table contains generated columns. +CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26 + FOR EACH ROW + WHEN (NEW.a < 0) + EXECUTE PROCEDURE gtest_trigger_func(); +CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); +CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); +INSERT INTO gtest26 (a) VALUES (-2), (0), (3); +INFO: gtest2: BEFORE: new = (-2,) +INFO: gtest4: AFTER: new = (-2,-4) +SELECT * FROM gtest26 ORDER BY a; + a | b +----+---- + -2 | -4 + 0 | 0 + 3 | 6 +(3 rows) + +UPDATE gtest26 SET a = a * -2; +INFO: gtest1: BEFORE: old = (-2,-4) +INFO: gtest1: BEFORE: new = (4,) +INFO: gtest3: AFTER: old = (-2,-4) +INFO: gtest3: AFTER: new = (4,8) +INFO: gtest4: AFTER: old = (3,6) +INFO: gtest4: AFTER: new = (-6,-12) +SELECT * FROM gtest26 ORDER BY a; + a | b +----+----- + -6 | -12 + 0 | 0 + 4 | 8 +(3 rows) + +DELETE FROM gtest26 WHERE a = -6; +INFO: gtest1: BEFORE: old = (-6,-12) +INFO: gtest3: AFTER: old = (-6,-12) +SELECT * FROM gtest26 ORDER BY a; + a | b +---+--- + 0 | 0 + 4 | 8 +(2 rows) + +DROP TRIGGER gtest1 ON gtest26; +DROP TRIGGER gtest2 ON gtest26; +DROP TRIGGER gtest3 ON gtest26; +-- Check that an UPDATE of "a" fires the trigger for UPDATE OF b, per +-- SQL standard. +CREATE FUNCTION gtest_trigger_func3() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'OK'; + RETURN NEW; +END +$$; +CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func3(); +UPDATE gtest26 SET a = 1 WHERE a = 0; +NOTICE: OK +DROP TRIGGER gtest11 ON gtest26; +TRUNCATE gtest26; +-- check that modifications of stored generated columns in triggers do +-- not get propagated +CREATE FUNCTION gtest_trigger_func4() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + NEW.a = 10; + NEW.b = 300; + RETURN NEW; +END; +$$; +CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); +CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func4(); +CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); +INSERT INTO gtest26 (a) VALUES (1); +UPDATE gtest26 SET a = 11 WHERE a = 1; +INFO: gtest12_01: BEFORE: old = (1,2) +INFO: gtest12_01: BEFORE: new = (11,) +INFO: gtest12_03: BEFORE: old = (1,2) +INFO: gtest12_03: BEFORE: new = (10,) +SELECT * FROM gtest26 ORDER BY a; + a | b +----+---- + 10 | 20 +(1 row) + +-- LIKE INCLUDING GENERATED and dropped column handling +CREATE TABLE gtest28a ( + a int, + b int, + c int, + x int GENERATED ALWAYS AS (b * 2) STORED +); +ALTER TABLE gtest28a DROP COLUMN a; +CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED); +\d gtest28* + Table "public.gtest28a" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + b | integer | | | + c | integer | | | + x | integer | | | generated always as (b * 2) stored + + Table "public.gtest28b" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+------------------------------------ + b | integer | | | + c | integer | | | + x | integer | | | generated always as (b * 2) stored + diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out index e4c00390400..5b9d37030f3 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -13,9 +13,10 @@ SELECT '' AS four, center(f1) AS center ------+--------- | (1,1) | (2,2) + | (-5,-4) | (2.5,3) | (3,3) -(4 rows) +(5 rows) SELECT '' AS four, (@@ f1) AS center FROM BOX_TBL; @@ -23,9 +24,10 @@ SELECT '' AS four, (@@ f1) AS center ------+--------- | (1,1) | (2,2) + | (-5,-4) | (2.5,3) | (3,3) -(4 rows) +(5 rows) SELECT '' AS six, point(f1) AS center FROM CIRCLE_TBL; @@ -37,7 +39,9 @@ SELECT '' AS six, point(f1) AS center | (1,2) | (100,200) | (100,1) -(6 rows) + | (3,5) + | (3,5) +(8 rows) SELECT '' AS six, (@@ f1) AS center FROM CIRCLE_TBL; @@ -49,7 +53,9 @@ SELECT '' AS six, (@@ f1) AS center | (1,2) | (100,200) | (100,1) -(6 rows) + | (3,5) + | (3,5) +(8 rows) SELECT '' AS two, (@@ f1) AS center FROM POLYGON_TBL @@ -58,27 +64,32 @@ SELECT '' AS two, (@@ f1) AS center -----+------------------------------- | (1.33333333333,1.33333333333) | (2.33333333333,1.33333333333) -(2 rows) + | (4,5) + | (4,5) + | (4,3) +(5 rows) -- "is horizontal" function SELECT '' AS two, p1.f1 FROM POINT_TBL p1 WHERE ishorizontal(p1.f1, point '(0,0)'); - two | f1 ------+--------- + two | f1 +-----+------------------ | (0,0) | (-10,0) -(2 rows) + | (1e-300,-1e-300) +(3 rows) -- "is horizontal" operator SELECT '' AS two, p1.f1 FROM POINT_TBL p1 WHERE p1.f1 ?- point '(0,0)'; - two | f1 ------+--------- + two | f1 +-----+------------------ | (0,0) | (-10,0) -(2 rows) + | (1e-300,-1e-300) +(3 rows) -- "is vertical" function SELECT '' AS one, p1.f1 @@ -98,6 +109,1455 @@ SELECT '' AS one, p1.f1 | (5.1,34.5) (1 row) +-- Slope +SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; + f1 | f1 | slope +-------------------+-------------------+-------------------- + (0,0) | (0,0) | 1.79769313486e+308 + (0,0) | (-10,0) | 0 + (0,0) | (-3,4) | -1.33333333333 + (0,0) | (5.1,34.5) | 6.76470588235 + (0,0) | (-5,-12) | 2.4 + (0,0) | (1e-300,-1e-300) | 1.79769313486e+308 + (0,0) | (1e+300,Infinity) | Infinity + (0,0) | (NaN,NaN) | NaN + (0,0) | (10,10) | 1 + (-10,0) | (0,0) | 0 + (-10,0) | (-10,0) | 1.79769313486e+308 + (-10,0) | (-3,4) | 0.571428571429 + (-10,0) | (5.1,34.5) | 2.28476821192 + (-10,0) | (-5,-12) | -2.4 + (-10,0) | (1e-300,-1e-300) | 0 + (-10,0) | (1e+300,Infinity) | Infinity + (-10,0) | (NaN,NaN) | NaN + (-10,0) | (10,10) | 0.5 + (-3,4) | (0,0) | -1.33333333333 + (-3,4) | (-10,0) | 0.571428571429 + (-3,4) | (-3,4) | 1.79769313486e+308 + (-3,4) | (5.1,34.5) | 3.76543209877 + (-3,4) | (-5,-12) | 8 + (-3,4) | (1e-300,-1e-300) | -1.33333333333 + (-3,4) | (1e+300,Infinity) | Infinity + (-3,4) | (NaN,NaN) | NaN + (-3,4) | (10,10) | 0.461538461538 + (5.1,34.5) | (0,0) | 6.76470588235 + (5.1,34.5) | (-10,0) | 2.28476821192 + (5.1,34.5) | (-3,4) | 3.76543209877 + (5.1,34.5) | (5.1,34.5) | 1.79769313486e+308 + (5.1,34.5) | (-5,-12) | 4.60396039604 + (5.1,34.5) | (1e-300,-1e-300) | 6.76470588235 + (5.1,34.5) | (1e+300,Infinity) | Infinity + (5.1,34.5) | (NaN,NaN) | NaN + (5.1,34.5) | (10,10) | -5 + (-5,-12) | (0,0) | 2.4 + (-5,-12) | (-10,0) | -2.4 + (-5,-12) | (-3,4) | 8 + (-5,-12) | (5.1,34.5) | 4.60396039604 + (-5,-12) | (-5,-12) | 1.79769313486e+308 + (-5,-12) | (1e-300,-1e-300) | 2.4 + (-5,-12) | (1e+300,Infinity) | Infinity + (-5,-12) | (NaN,NaN) | NaN + (-5,-12) | (10,10) | 1.46666666667 + (1e-300,-1e-300) | (0,0) | 1.79769313486e+308 + (1e-300,-1e-300) | (-10,0) | 0 + (1e-300,-1e-300) | (-3,4) | -1.33333333333 + (1e-300,-1e-300) | (5.1,34.5) | 6.76470588235 + (1e-300,-1e-300) | (-5,-12) | 2.4 + (1e-300,-1e-300) | (1e-300,-1e-300) | 1.79769313486e+308 + (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + (1e-300,-1e-300) | (NaN,NaN) | NaN + (1e-300,-1e-300) | (10,10) | 1 + (1e+300,Infinity) | (0,0) | Infinity + (1e+300,Infinity) | (-10,0) | Infinity + (1e+300,Infinity) | (-3,4) | Infinity + (1e+300,Infinity) | (5.1,34.5) | Infinity + (1e+300,Infinity) | (-5,-12) | Infinity + (1e+300,Infinity) | (1e-300,-1e-300) | Infinity + (1e+300,Infinity) | (1e+300,Infinity) | 1.79769313486e+308 + (1e+300,Infinity) | (NaN,NaN) | NaN + (1e+300,Infinity) | (10,10) | Infinity + (NaN,NaN) | (0,0) | NaN + (NaN,NaN) | (-10,0) | NaN + (NaN,NaN) | (-3,4) | NaN + (NaN,NaN) | (5.1,34.5) | NaN + (NaN,NaN) | (-5,-12) | NaN + (NaN,NaN) | (1e-300,-1e-300) | NaN + (NaN,NaN) | (1e+300,Infinity) | NaN + (NaN,NaN) | (NaN,NaN) | NaN + (NaN,NaN) | (10,10) | NaN + (10,10) | (0,0) | 1 + (10,10) | (-10,0) | 0.5 + (10,10) | (-3,4) | 0.461538461538 + (10,10) | (5.1,34.5) | -5 + (10,10) | (-5,-12) | 1.46666666667 + (10,10) | (1e-300,-1e-300) | 1 + (10,10) | (1e+300,Infinity) | Infinity + (10,10) | (NaN,NaN) | NaN + (10,10) | (10,10) | 1.79769313486e+308 +(81 rows) + +-- Add point +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + f1 | f1 | ?column? +-------------------+-------------------+------------------- + (0,0) | (0,0) | (0,0) + (0,0) | (-10,0) | (-10,0) + (0,0) | (-3,4) | (-3,4) + (0,0) | (5.1,34.5) | (5.1,34.5) + (0,0) | (-5,-12) | (-5,-12) + (0,0) | (1e-300,-1e-300) | (1e-300,-1e-300) + (0,0) | (1e+300,Infinity) | (1e+300,Infinity) + (0,0) | (NaN,NaN) | (NaN,NaN) + (0,0) | (10,10) | (10,10) + (-10,0) | (0,0) | (-10,0) + (-10,0) | (-10,0) | (-20,0) + (-10,0) | (-3,4) | (-13,4) + (-10,0) | (5.1,34.5) | (-4.9,34.5) + (-10,0) | (-5,-12) | (-15,-12) + (-10,0) | (1e-300,-1e-300) | (-10,-1e-300) + (-10,0) | (1e+300,Infinity) | (1e+300,Infinity) + (-10,0) | (NaN,NaN) | (NaN,NaN) + (-10,0) | (10,10) | (0,10) + (-3,4) | (0,0) | (-3,4) + (-3,4) | (-10,0) | (-13,4) + (-3,4) | (-3,4) | (-6,8) + (-3,4) | (5.1,34.5) | (2.1,38.5) + (-3,4) | (-5,-12) | (-8,-8) + (-3,4) | (1e-300,-1e-300) | (-3,4) + (-3,4) | (1e+300,Infinity) | (1e+300,Infinity) + (-3,4) | (NaN,NaN) | (NaN,NaN) + (-3,4) | (10,10) | (7,14) + (5.1,34.5) | (0,0) | (5.1,34.5) + (5.1,34.5) | (-10,0) | (-4.9,34.5) + (5.1,34.5) | (-3,4) | (2.1,38.5) + (5.1,34.5) | (5.1,34.5) | (10.2,69) + (5.1,34.5) | (-5,-12) | (0.1,22.5) + (5.1,34.5) | (1e-300,-1e-300) | (5.1,34.5) + (5.1,34.5) | (1e+300,Infinity) | (1e+300,Infinity) + (5.1,34.5) | (NaN,NaN) | (NaN,NaN) + (5.1,34.5) | (10,10) | (15.1,44.5) + (-5,-12) | (0,0) | (-5,-12) + (-5,-12) | (-10,0) | (-15,-12) + (-5,-12) | (-3,4) | (-8,-8) + (-5,-12) | (5.1,34.5) | (0.1,22.5) + (-5,-12) | (-5,-12) | (-10,-24) + (-5,-12) | (1e-300,-1e-300) | (-5,-12) + (-5,-12) | (1e+300,Infinity) | (1e+300,Infinity) + (-5,-12) | (NaN,NaN) | (NaN,NaN) + (-5,-12) | (10,10) | (5,-2) + (1e-300,-1e-300) | (0,0) | (1e-300,-1e-300) + (1e-300,-1e-300) | (-10,0) | (-10,-1e-300) + (1e-300,-1e-300) | (-3,4) | (-3,4) + (1e-300,-1e-300) | (5.1,34.5) | (5.1,34.5) + (1e-300,-1e-300) | (-5,-12) | (-5,-12) + (1e-300,-1e-300) | (1e-300,-1e-300) | (2e-300,-2e-300) + (1e-300,-1e-300) | (1e+300,Infinity) | (1e+300,Infinity) + (1e-300,-1e-300) | (NaN,NaN) | (NaN,NaN) + (1e-300,-1e-300) | (10,10) | (10,10) + (1e+300,Infinity) | (0,0) | (1e+300,Infinity) + (1e+300,Infinity) | (-10,0) | (1e+300,Infinity) + (1e+300,Infinity) | (-3,4) | (1e+300,Infinity) + (1e+300,Infinity) | (5.1,34.5) | (1e+300,Infinity) + (1e+300,Infinity) | (-5,-12) | (1e+300,Infinity) + (1e+300,Infinity) | (1e-300,-1e-300) | (1e+300,Infinity) + (1e+300,Infinity) | (1e+300,Infinity) | (2e+300,Infinity) + (1e+300,Infinity) | (NaN,NaN) | (NaN,NaN) + (1e+300,Infinity) | (10,10) | (1e+300,Infinity) + (NaN,NaN) | (0,0) | (NaN,NaN) + (NaN,NaN) | (-10,0) | (NaN,NaN) + (NaN,NaN) | (-3,4) | (NaN,NaN) + (NaN,NaN) | (5.1,34.5) | (NaN,NaN) + (NaN,NaN) | (-5,-12) | (NaN,NaN) + (NaN,NaN) | (1e-300,-1e-300) | (NaN,NaN) + (NaN,NaN) | (1e+300,Infinity) | (NaN,NaN) + (NaN,NaN) | (NaN,NaN) | (NaN,NaN) + (NaN,NaN) | (10,10) | (NaN,NaN) + (10,10) | (0,0) | (10,10) + (10,10) | (-10,0) | (0,10) + (10,10) | (-3,4) | (7,14) + (10,10) | (5.1,34.5) | (15.1,44.5) + (10,10) | (-5,-12) | (5,-2) + (10,10) | (1e-300,-1e-300) | (10,10) + (10,10) | (1e+300,Infinity) | (1e+300,Infinity) + (10,10) | (NaN,NaN) | (NaN,NaN) + (10,10) | (10,10) | (20,20) +(81 rows) + +-- Subtract point +SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + f1 | f1 | ?column? +-------------------+-------------------+--------------------- + (0,0) | (0,0) | (0,0) + (0,0) | (-10,0) | (10,0) + (0,0) | (-3,4) | (3,-4) + (0,0) | (5.1,34.5) | (-5.1,-34.5) + (0,0) | (-5,-12) | (5,12) + (0,0) | (1e-300,-1e-300) | (-1e-300,1e-300) + (0,0) | (1e+300,Infinity) | (-1e+300,-Infinity) + (0,0) | (NaN,NaN) | (NaN,NaN) + (0,0) | (10,10) | (-10,-10) + (-10,0) | (0,0) | (-10,0) + (-10,0) | (-10,0) | (0,0) + (-10,0) | (-3,4) | (-7,-4) + (-10,0) | (5.1,34.5) | (-15.1,-34.5) + (-10,0) | (-5,-12) | (-5,12) + (-10,0) | (1e-300,-1e-300) | (-10,1e-300) + (-10,0) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-10,0) | (NaN,NaN) | (NaN,NaN) + (-10,0) | (10,10) | (-20,-10) + (-3,4) | (0,0) | (-3,4) + (-3,4) | (-10,0) | (7,4) + (-3,4) | (-3,4) | (0,0) + (-3,4) | (5.1,34.5) | (-8.1,-30.5) + (-3,4) | (-5,-12) | (2,16) + (-3,4) | (1e-300,-1e-300) | (-3,4) + (-3,4) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-3,4) | (NaN,NaN) | (NaN,NaN) + (-3,4) | (10,10) | (-13,-6) + (5.1,34.5) | (0,0) | (5.1,34.5) + (5.1,34.5) | (-10,0) | (15.1,34.5) + (5.1,34.5) | (-3,4) | (8.1,30.5) + (5.1,34.5) | (5.1,34.5) | (0,0) + (5.1,34.5) | (-5,-12) | (10.1,46.5) + (5.1,34.5) | (1e-300,-1e-300) | (5.1,34.5) + (5.1,34.5) | (1e+300,Infinity) | (-1e+300,-Infinity) + (5.1,34.5) | (NaN,NaN) | (NaN,NaN) + (5.1,34.5) | (10,10) | (-4.9,24.5) + (-5,-12) | (0,0) | (-5,-12) + (-5,-12) | (-10,0) | (5,-12) + (-5,-12) | (-3,4) | (-2,-16) + (-5,-12) | (5.1,34.5) | (-10.1,-46.5) + (-5,-12) | (-5,-12) | (0,0) + (-5,-12) | (1e-300,-1e-300) | (-5,-12) + (-5,-12) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-5,-12) | (NaN,NaN) | (NaN,NaN) + (-5,-12) | (10,10) | (-15,-22) + (1e-300,-1e-300) | (0,0) | (1e-300,-1e-300) + (1e-300,-1e-300) | (-10,0) | (10,-1e-300) + (1e-300,-1e-300) | (-3,4) | (3,-4) + (1e-300,-1e-300) | (5.1,34.5) | (-5.1,-34.5) + (1e-300,-1e-300) | (-5,-12) | (5,12) + (1e-300,-1e-300) | (1e-300,-1e-300) | (0,0) + (1e-300,-1e-300) | (1e+300,Infinity) | (-1e+300,-Infinity) + (1e-300,-1e-300) | (NaN,NaN) | (NaN,NaN) + (1e-300,-1e-300) | (10,10) | (-10,-10) + (1e+300,Infinity) | (0,0) | (1e+300,Infinity) + (1e+300,Infinity) | (-10,0) | (1e+300,Infinity) + (1e+300,Infinity) | (-3,4) | (1e+300,Infinity) + (1e+300,Infinity) | (5.1,34.5) | (1e+300,Infinity) + (1e+300,Infinity) | (-5,-12) | (1e+300,Infinity) + (1e+300,Infinity) | (1e-300,-1e-300) | (1e+300,Infinity) + (1e+300,Infinity) | (1e+300,Infinity) | (0,NaN) + (1e+300,Infinity) | (NaN,NaN) | (NaN,NaN) + (1e+300,Infinity) | (10,10) | (1e+300,Infinity) + (NaN,NaN) | (0,0) | (NaN,NaN) + (NaN,NaN) | (-10,0) | (NaN,NaN) + (NaN,NaN) | (-3,4) | (NaN,NaN) + (NaN,NaN) | (5.1,34.5) | (NaN,NaN) + (NaN,NaN) | (-5,-12) | (NaN,NaN) + (NaN,NaN) | (1e-300,-1e-300) | (NaN,NaN) + (NaN,NaN) | (1e+300,Infinity) | (NaN,NaN) + (NaN,NaN) | (NaN,NaN) | (NaN,NaN) + (NaN,NaN) | (10,10) | (NaN,NaN) + (10,10) | (0,0) | (10,10) + (10,10) | (-10,0) | (20,10) + (10,10) | (-3,4) | (13,6) + (10,10) | (5.1,34.5) | (4.9,-24.5) + (10,10) | (-5,-12) | (15,22) + (10,10) | (1e-300,-1e-300) | (10,10) + (10,10) | (1e+300,Infinity) | (-1e+300,-Infinity) + (10,10) | (NaN,NaN) | (NaN,NaN) + (10,10) | (10,10) | (0,0) +(81 rows) + +-- Multiply with point +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +------------+-------------------+----------------------- + (5.1,34.5) | (0,0) | (0,0) + (10,10) | (0,0) | (0,0) + (5.1,34.5) | (-10,0) | (-51,-345) + (10,10) | (-10,0) | (-100,-100) + (5.1,34.5) | (-3,4) | (-153.3,-83.1) + (10,10) | (-3,4) | (-70,10) + (5.1,34.5) | (5.1,34.5) | (-1164.24,351.9) + (10,10) | (5.1,34.5) | (-294,396) + (5.1,34.5) | (-5,-12) | (388.5,-233.7) + (10,10) | (-5,-12) | (70,-170) + (5.1,34.5) | (1e-300,-1e-300) | (3.96e-299,2.94e-299) + (10,10) | (1e-300,-1e-300) | (2e-299,0) + (5.1,34.5) | (1e+300,Infinity) | (-Infinity,Infinity) + (10,10) | (1e+300,Infinity) | (-Infinity,Infinity) + (5.1,34.5) | (NaN,NaN) | (NaN,NaN) + (10,10) | (NaN,NaN) | (NaN,NaN) + (5.1,34.5) | (10,10) | (-294,396) + (10,10) | (10,10) | (0,200) +(18 rows) + +-- Underflow error +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1; +ERROR: value out of range: underflow +-- Divide by point +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +-------------------+------------+------------------------------------------- + (0,0) | (5.1,34.5) | (0,0) + (0,0) | (10,10) | (0,0) + (-10,0) | (5.1,34.5) | (-0.0419318237877,0.283656455034) + (-10,0) | (10,10) | (-0.5,0.5) + (-3,4) | (5.1,34.5) | (0.100883034877,0.101869666025) + (-3,4) | (10,10) | (0.05,0.35) + (5.1,34.5) | (5.1,34.5) | (1,0) + (5.1,34.5) | (10,10) | (1.98,1.47) + (-5,-12) | (5.1,34.5) | (-0.361353657935,0.0915100389719) + (-5,-12) | (10,10) | (-0.85,-0.35) + (1e-300,-1e-300) | (5.1,34.5) | (-2.41724631247e-302,-3.25588278822e-302) + (1e-300,-1e-300) | (10,10) | (0,-1e-301) + (1e+300,Infinity) | (5.1,34.5) | (Infinity,Infinity) + (1e+300,Infinity) | (10,10) | (Infinity,Infinity) + (NaN,NaN) | (5.1,34.5) | (NaN,NaN) + (NaN,NaN) | (10,10) | (NaN,NaN) + (10,10) | (5.1,34.5) | (0.325588278822,-0.241724631247) + (10,10) | (10,10) | (1,0) +(18 rows) + +-- Overflow error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000; +ERROR: value out of range: overflow +-- Division by 0 error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1 ~= '(0,0)'::point; +ERROR: division by zero +-- Distance to line +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l; + f1 | s | dist_pl | dist_lp +-------------------+---------------------------------------+--------------------+-------------------- + (0,0) | {0,-1,5} | 5 | 5 + (0,0) | {1,0,5} | 5 | 5 + (0,0) | {0,3,0} | 0 | 0 + (0,0) | {1,-1,0} | 0 | 0 + (0,0) | {-0.4,-1,-6} | 5.57086014531 | 5.57086014531 + (0,0) | {-0.000184615384615,-1,15.3846153846} | 15.3846151224 | 15.3846151224 + (0,0) | {3,NaN,5} | NaN | NaN + (0,0) | {NaN,NaN,NaN} | NaN | NaN + (0,0) | {0,-1,3} | 3 | 3 + (0,0) | {-1,0,3} | 3 | 3 + (-10,0) | {0,-1,5} | 5 | 5 + (-10,0) | {1,0,5} | 5 | 5 + (-10,0) | {0,3,0} | 0 | 0 + (-10,0) | {1,-1,0} | 7.07106781187 | 7.07106781187 + (-10,0) | {-0.4,-1,-6} | 1.85695338177 | 1.85695338177 + (-10,0) | {-0.000184615384615,-1,15.3846153846} | 15.3864612763 | 15.3864612763 + (-10,0) | {3,NaN,5} | NaN | NaN + (-10,0) | {NaN,NaN,NaN} | NaN | NaN + (-10,0) | {0,-1,3} | 3 | 3 + (-10,0) | {-1,0,3} | 13 | 13 + (-3,4) | {0,-1,5} | 1 | 1 + (-3,4) | {1,0,5} | 2 | 2 + (-3,4) | {0,3,0} | 4 | 4 + (-3,4) | {1,-1,0} | 4.94974746831 | 4.94974746831 + (-3,4) | {-0.4,-1,-6} | 8.17059487979 | 8.17059487979 + (-3,4) | {-0.000184615384615,-1,15.3846153846} | 11.3851690368 | 11.3851690368 + (-3,4) | {3,NaN,5} | NaN | NaN + (-3,4) | {NaN,NaN,NaN} | NaN | NaN + (-3,4) | {0,-1,3} | 1 | 1 + (-3,4) | {-1,0,3} | 6 | 6 + (5.1,34.5) | {0,-1,5} | 29.5 | 29.5 + (5.1,34.5) | {1,0,5} | 10.1 | 10.1 + (5.1,34.5) | {0,3,0} | 34.5 | 34.5 + (5.1,34.5) | {1,-1,0} | 20.7889393669 | 20.7889393669 + (5.1,34.5) | {-0.4,-1,-6} | 39.4973984303 | 39.4973984303 + (5.1,34.5) | {-0.000184615384615,-1,15.3846153846} | 19.1163258281 | 19.1163258281 + (5.1,34.5) | {3,NaN,5} | NaN | NaN + (5.1,34.5) | {NaN,NaN,NaN} | NaN | NaN + (5.1,34.5) | {0,-1,3} | 31.5 | 31.5 + (5.1,34.5) | {-1,0,3} | 2.1 | 2.1 + (-5,-12) | {0,-1,5} | 17 | 17 + (-5,-12) | {1,0,5} | 0 | 0 + (-5,-12) | {0,3,0} | 12 | 12 + (-5,-12) | {1,-1,0} | 4.94974746831 | 4.94974746831 + (-5,-12) | {-0.4,-1,-6} | 7.42781352708 | 7.42781352708 + (-5,-12) | {-0.000184615384615,-1,15.3846153846} | 27.3855379948 | 27.3855379948 + (-5,-12) | {3,NaN,5} | NaN | NaN + (-5,-12) | {NaN,NaN,NaN} | NaN | NaN + (-5,-12) | {0,-1,3} | 15 | 15 + (-5,-12) | {-1,0,3} | 8 | 8 + (1e-300,-1e-300) | {0,-1,5} | 5 | 5 + (1e-300,-1e-300) | {1,0,5} | 5 | 5 + (1e-300,-1e-300) | {0,3,0} | 1e-300 | 1e-300 + (1e-300,-1e-300) | {1,-1,0} | 1.41421356237e-300 | 1.41421356237e-300 + (1e-300,-1e-300) | {-0.4,-1,-6} | 5.57086014531 | 5.57086014531 + (1e-300,-1e-300) | {-0.000184615384615,-1,15.3846153846} | 15.3846151224 | 15.3846151224 + (1e-300,-1e-300) | {3,NaN,5} | NaN | NaN + (1e-300,-1e-300) | {NaN,NaN,NaN} | NaN | NaN + (1e-300,-1e-300) | {0,-1,3} | 3 | 3 + (1e-300,-1e-300) | {-1,0,3} | 3 | 3 + (1e+300,Infinity) | {0,-1,5} | Infinity | Infinity + (1e+300,Infinity) | {1,0,5} | NaN | NaN + (1e+300,Infinity) | {0,3,0} | Infinity | Infinity + (1e+300,Infinity) | {1,-1,0} | Infinity | Infinity + (1e+300,Infinity) | {-0.4,-1,-6} | Infinity | Infinity + (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | Infinity | Infinity + (1e+300,Infinity) | {3,NaN,5} | NaN | NaN + (1e+300,Infinity) | {NaN,NaN,NaN} | NaN | NaN + (1e+300,Infinity) | {0,-1,3} | Infinity | Infinity + (1e+300,Infinity) | {-1,0,3} | NaN | NaN + (NaN,NaN) | {0,-1,5} | NaN | NaN + (NaN,NaN) | {1,0,5} | NaN | NaN + (NaN,NaN) | {0,3,0} | NaN | NaN + (NaN,NaN) | {1,-1,0} | NaN | NaN + (NaN,NaN) | {-0.4,-1,-6} | NaN | NaN + (NaN,NaN) | {-0.000184615384615,-1,15.3846153846} | NaN | NaN + (NaN,NaN) | {3,NaN,5} | NaN | NaN + (NaN,NaN) | {NaN,NaN,NaN} | NaN | NaN + (NaN,NaN) | {0,-1,3} | NaN | NaN + (NaN,NaN) | {-1,0,3} | NaN | NaN + (10,10) | {0,-1,5} | 5 | 5 + (10,10) | {1,0,5} | 15 | 15 + (10,10) | {0,3,0} | 10 | 10 + (10,10) | {1,-1,0} | 0 | 0 + (10,10) | {-0.4,-1,-6} | 18.5695338177 | 18.5695338177 + (10,10) | {-0.000184615384615,-1,15.3846153846} | 5.38276913903 | 5.38276913903 + (10,10) | {3,NaN,5} | NaN | NaN + (10,10) | {NaN,NaN,NaN} | NaN | NaN + (10,10) | {0,-1,3} | 7 | 7 + (10,10) | {-1,0,3} | 7 | 7 +(90 rows) + +-- Distance to line segment +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l; + f1 | s | dist_ps | dist_sp +-------------------+-------------------------------+--------------------+-------------------- + (0,0) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (0,0) | [(0,0),(6,6)] | 0 | 0 + (0,0) | [(10,-10),(-3,-4)] | 4.88901207039 | 4.88901207039 + (0,0) | [(-1000000,200),(300000,-40)] | 15.3846151224 | 15.3846151224 + (0,0) | [(11,22),(33,44)] | 24.5967477525 | 24.5967477525 + (0,0) | [(-10,2),(-10,3)] | 10.1980390272 | 10.1980390272 + (0,0) | [(0,-20),(30,-20)] | 20 | 20 + (0,0) | [(NaN,1),(NaN,90)] | NaN | NaN + (-10,0) | [(1,2),(3,4)] | 11.1803398875 | 11.1803398875 + (-10,0) | [(0,0),(6,6)] | 10 | 10 + (-10,0) | [(10,-10),(-3,-4)] | 8.0622577483 | 8.0622577483 + (-10,0) | [(-1000000,200),(300000,-40)] | 15.3864612763 | 15.3864612763 + (-10,0) | [(11,22),(33,44)] | 30.4138126515 | 30.4138126515 + (-10,0) | [(-10,2),(-10,3)] | 2 | 2 + (-10,0) | [(0,-20),(30,-20)] | 22.360679775 | 22.360679775 + (-10,0) | [(NaN,1),(NaN,90)] | NaN | NaN + (-3,4) | [(1,2),(3,4)] | 4.472135955 | 4.472135955 + (-3,4) | [(0,0),(6,6)] | 4.94974746831 | 4.94974746831 + (-3,4) | [(10,-10),(-3,-4)] | 8 | 8 + (-3,4) | [(-1000000,200),(300000,-40)] | 11.3851690367 | 11.3851690367 + (-3,4) | [(11,22),(33,44)] | 22.803508502 | 22.803508502 + (-3,4) | [(-10,2),(-10,3)] | 7.07106781187 | 7.07106781187 + (-3,4) | [(0,-20),(30,-20)] | 24.1867732449 | 24.1867732449 + (-3,4) | [(NaN,1),(NaN,90)] | NaN | NaN + (5.1,34.5) | [(1,2),(3,4)] | 30.5722096028 | 30.5722096028 + (5.1,34.5) | [(0,0),(6,6)] | 28.5142069853 | 28.5142069853 + (5.1,34.5) | [(10,-10),(-3,-4)] | 39.3428519556 | 39.3428519556 + (5.1,34.5) | [(-1000000,200),(300000,-40)] | 19.1163258281 | 19.1163258281 + (5.1,34.5) | [(11,22),(33,44)] | 13.0107647738 | 13.0107647738 + (5.1,34.5) | [(-10,2),(-10,3)] | 34.932220084 | 34.932220084 + (5.1,34.5) | [(0,-20),(30,-20)] | 54.5 | 54.5 + (5.1,34.5) | [(NaN,1),(NaN,90)] | NaN | NaN + (-5,-12) | [(1,2),(3,4)] | 15.2315462117 | 15.2315462117 + (-5,-12) | [(0,0),(6,6)] | 13 | 13 + (-5,-12) | [(10,-10),(-3,-4)] | 8.10179143093 | 8.10179143093 + (-5,-12) | [(-1000000,200),(300000,-40)] | 27.3855379949 | 27.3855379949 + (-5,-12) | [(11,22),(33,44)] | 37.5765884561 | 37.5765884561 + (-5,-12) | [(-10,2),(-10,3)] | 14.8660687473 | 14.8660687473 + (-5,-12) | [(0,-20),(30,-20)] | 9.43398113206 | 9.43398113206 + (-5,-12) | [(NaN,1),(NaN,90)] | NaN | NaN + (1e-300,-1e-300) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | [(0,0),(6,6)] | 1.41421356237e-300 | 1.41421356237e-300 + (1e-300,-1e-300) | [(10,-10),(-3,-4)] | 4.88901207039 | 4.88901207039 + (1e-300,-1e-300) | [(-1000000,200),(300000,-40)] | 15.3846151224 | 15.3846151224 + (1e-300,-1e-300) | [(11,22),(33,44)] | 24.5967477525 | 24.5967477525 + (1e-300,-1e-300) | [(-10,2),(-10,3)] | 10.1980390272 | 10.1980390272 + (1e-300,-1e-300) | [(0,-20),(30,-20)] | 20 | 20 + (1e-300,-1e-300) | [(NaN,1),(NaN,90)] | NaN | NaN + (1e+300,Infinity) | [(1,2),(3,4)] | Infinity | Infinity + (1e+300,Infinity) | [(0,0),(6,6)] | Infinity | Infinity + (1e+300,Infinity) | [(10,-10),(-3,-4)] | Infinity | Infinity + (1e+300,Infinity) | [(-1000000,200),(300000,-40)] | Infinity | Infinity + (1e+300,Infinity) | [(11,22),(33,44)] | Infinity | Infinity + (1e+300,Infinity) | [(-10,2),(-10,3)] | Infinity | Infinity + (1e+300,Infinity) | [(0,-20),(30,-20)] | Infinity | Infinity + (1e+300,Infinity) | [(NaN,1),(NaN,90)] | Infinity | Infinity + (NaN,NaN) | [(1,2),(3,4)] | NaN | NaN + (NaN,NaN) | [(0,0),(6,6)] | NaN | NaN + (NaN,NaN) | [(10,-10),(-3,-4)] | NaN | NaN + (NaN,NaN) | [(-1000000,200),(300000,-40)] | NaN | NaN + (NaN,NaN) | [(11,22),(33,44)] | NaN | NaN + (NaN,NaN) | [(-10,2),(-10,3)] | NaN | NaN + (NaN,NaN) | [(0,-20),(30,-20)] | NaN | NaN + (NaN,NaN) | [(NaN,1),(NaN,90)] | NaN | NaN + (10,10) | [(1,2),(3,4)] | 9.21954445729 | 9.21954445729 + (10,10) | [(0,0),(6,6)] | 5.65685424949 | 5.65685424949 + (10,10) | [(10,-10),(-3,-4)] | 18.15918769 | 18.15918769 + (10,10) | [(-1000000,200),(300000,-40)] | 5.38276913904 | 5.38276913904 + (10,10) | [(11,22),(33,44)] | 12.0415945788 | 12.0415945788 + (10,10) | [(-10,2),(-10,3)] | 21.1896201004 | 21.1896201004 + (10,10) | [(0,-20),(30,-20)] | 30 | 30 + (10,10) | [(NaN,1),(NaN,90)] | NaN | NaN +(72 rows) + +-- Distance to box +SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b; + f1 | f1 | dist_pb | dist_bp +-------------------+---------------------+--------------------+-------------------- + (0,0) | (2,2),(0,0) | 0 | 0 + (0,0) | (3,3),(1,1) | 1.41421356237 | 1.41421356237 + (0,0) | (-2,2),(-8,-10) | 2 | 2 + (0,0) | (2.5,3.5),(2.5,2.5) | 3.53553390593 | 3.53553390593 + (0,0) | (3,3),(3,3) | 4.24264068712 | 4.24264068712 + (-10,0) | (2,2),(0,0) | 10 | 10 + (-10,0) | (3,3),(1,1) | 11.0453610172 | 11.0453610172 + (-10,0) | (-2,2),(-8,-10) | 2 | 2 + (-10,0) | (2.5,3.5),(2.5,2.5) | 12.747548784 | 12.747548784 + (-10,0) | (3,3),(3,3) | 13.3416640641 | 13.3416640641 + (-3,4) | (2,2),(0,0) | 3.60555127546 | 3.60555127546 + (-3,4) | (3,3),(1,1) | 4.12310562562 | 4.12310562562 + (-3,4) | (-2,2),(-8,-10) | 2 | 2 + (-3,4) | (2.5,3.5),(2.5,2.5) | 5.52268050859 | 5.52268050859 + (-3,4) | (3,3),(3,3) | 6.0827625303 | 6.0827625303 + (5.1,34.5) | (2,2),(0,0) | 32.6475113906 | 32.6475113906 + (5.1,34.5) | (3,3),(1,1) | 31.5699223946 | 31.5699223946 + (5.1,34.5) | (-2,2),(-8,-10) | 33.2664996656 | 33.2664996656 + (5.1,34.5) | (2.5,3.5),(2.5,2.5) | 31.108841187 | 31.108841187 + (5.1,34.5) | (3,3),(3,3) | 31.5699223946 | 31.5699223946 + (-5,-12) | (2,2),(0,0) | 13 | 13 + (-5,-12) | (3,3),(1,1) | 14.3178210633 | 14.3178210633 + (-5,-12) | (-2,2),(-8,-10) | 2 | 2 + (-5,-12) | (2.5,3.5),(2.5,2.5) | 16.3248277173 | 16.3248277173 + (-5,-12) | (3,3),(3,3) | 17 | 17 + (1e-300,-1e-300) | (2,2),(0,0) | 1.41421356237e-300 | 1.41421356237e-300 + (1e-300,-1e-300) | (3,3),(1,1) | 1.41421356237 | 1.41421356237 + (1e-300,-1e-300) | (-2,2),(-8,-10) | 2 | 2 + (1e-300,-1e-300) | (2.5,3.5),(2.5,2.5) | 3.53553390593 | 3.53553390593 + (1e-300,-1e-300) | (3,3),(3,3) | 4.24264068712 | 4.24264068712 + (1e+300,Infinity) | (2,2),(0,0) | Infinity | Infinity + (1e+300,Infinity) | (3,3),(1,1) | Infinity | Infinity + (1e+300,Infinity) | (-2,2),(-8,-10) | Infinity | Infinity + (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) | Infinity | Infinity + (1e+300,Infinity) | (3,3),(3,3) | Infinity | Infinity + (NaN,NaN) | (2,2),(0,0) | NaN | NaN + (NaN,NaN) | (3,3),(1,1) | NaN | NaN + (NaN,NaN) | (-2,2),(-8,-10) | NaN | NaN + (NaN,NaN) | (2.5,3.5),(2.5,2.5) | NaN | NaN + (NaN,NaN) | (3,3),(3,3) | NaN | NaN + (10,10) | (2,2),(0,0) | 11.313708499 | 11.313708499 + (10,10) | (3,3),(1,1) | 9.89949493661 | 9.89949493661 + (10,10) | (-2,2),(-8,-10) | 14.4222051019 | 14.4222051019 + (10,10) | (2.5,3.5),(2.5,2.5) | 9.92471662064 | 9.92471662064 + (10,10) | (3,3),(3,3) | 9.89949493661 | 9.89949493661 +(45 rows) + +-- Distance to path +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1; + f1 | f1 | dist_ppath | dist_pathp +-------------------+---------------------------+--------------------+-------------------- + (0,0) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (0,0) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (0,0) | [(0,0),(3,0),(4,5),(1,6)] | 0 | 0 + (0,0) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (0,0) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (0,0) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (0,0) | ((10,20)) | 22.360679775 | 22.360679775 + (0,0) | [(11,12),(13,14)] | 16.2788205961 | 16.2788205961 + (0,0) | ((11,12),(13,14)) | 16.2788205961 | 16.2788205961 + (-10,0) | [(1,2),(3,4)] | 11.1803398875 | 11.1803398875 + (-10,0) | ((1,2),(3,4)) | 11.1803398875 | 11.1803398875 + (-10,0) | [(0,0),(3,0),(4,5),(1,6)] | 10 | 10 + (-10,0) | ((1,2),(3,4)) | 11.1803398875 | 11.1803398875 + (-10,0) | ((1,2),(3,4)) | 11.1803398875 | 11.1803398875 + (-10,0) | [(1,2),(3,4)] | 11.1803398875 | 11.1803398875 + (-10,0) | ((10,20)) | 28.2842712475 | 28.2842712475 + (-10,0) | [(11,12),(13,14)] | 24.1867732449 | 24.1867732449 + (-10,0) | ((11,12),(13,14)) | 24.1867732449 | 24.1867732449 + (-3,4) | [(1,2),(3,4)] | 4.472135955 | 4.472135955 + (-3,4) | ((1,2),(3,4)) | 4.472135955 | 4.472135955 + (-3,4) | [(0,0),(3,0),(4,5),(1,6)] | 4.472135955 | 4.472135955 + (-3,4) | ((1,2),(3,4)) | 4.472135955 | 4.472135955 + (-3,4) | ((1,2),(3,4)) | 4.472135955 | 4.472135955 + (-3,4) | [(1,2),(3,4)] | 4.472135955 | 4.472135955 + (-3,4) | ((10,20)) | 20.6155281281 | 20.6155281281 + (-3,4) | [(11,12),(13,14)] | 16.1245154966 | 16.1245154966 + (-3,4) | ((11,12),(13,14)) | 16.1245154966 | 16.1245154966 + (5.1,34.5) | [(1,2),(3,4)] | 30.5722096028 | 30.5722096028 + (5.1,34.5) | ((1,2),(3,4)) | 30.5722096028 | 30.5722096028 + (5.1,34.5) | [(0,0),(3,0),(4,5),(1,6)] | 28.793402022 | 28.793402022 + (5.1,34.5) | ((1,2),(3,4)) | 30.5722096028 | 30.5722096028 + (5.1,34.5) | ((1,2),(3,4)) | 30.5722096028 | 30.5722096028 + (5.1,34.5) | [(1,2),(3,4)] | 30.5722096028 | 30.5722096028 + (5.1,34.5) | ((10,20)) | 15.3055545473 | 15.3055545473 + (5.1,34.5) | [(11,12),(13,14)] | 21.9695243462 | 21.9695243462 + (5.1,34.5) | ((11,12),(13,14)) | 21.9695243462 | 21.9695243462 + (-5,-12) | [(1,2),(3,4)] | 15.2315462117 | 15.2315462117 + (-5,-12) | ((1,2),(3,4)) | 15.2315462117 | 15.2315462117 + (-5,-12) | [(0,0),(3,0),(4,5),(1,6)] | 13 | 13 + (-5,-12) | ((1,2),(3,4)) | 15.2315462117 | 15.2315462117 + (-5,-12) | ((1,2),(3,4)) | 15.2315462117 | 15.2315462117 + (-5,-12) | [(1,2),(3,4)] | 15.2315462117 | 15.2315462117 + (-5,-12) | ((10,20)) | 35.3411940941 | 35.3411940941 + (-5,-12) | [(11,12),(13,14)] | 28.8444102037 | 28.8444102037 + (-5,-12) | ((11,12),(13,14)) | 28.8444102037 | 28.8444102037 + (1e-300,-1e-300) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | [(0,0),(3,0),(4,5),(1,6)] | 1.41421356237e-300 | 1.41421356237e-300 + (1e-300,-1e-300) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | ((1,2),(3,4)) | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | [(1,2),(3,4)] | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | ((10,20)) | 22.360679775 | 22.360679775 + (1e-300,-1e-300) | [(11,12),(13,14)] | 16.2788205961 | 16.2788205961 + (1e-300,-1e-300) | ((11,12),(13,14)) | 16.2788205961 | 16.2788205961 + (1e+300,Infinity) | [(1,2),(3,4)] | Infinity | Infinity + (1e+300,Infinity) | ((1,2),(3,4)) | Infinity | Infinity + (1e+300,Infinity) | [(0,0),(3,0),(4,5),(1,6)] | Infinity | Infinity + (1e+300,Infinity) | ((1,2),(3,4)) | Infinity | Infinity + (1e+300,Infinity) | ((1,2),(3,4)) | Infinity | Infinity + (1e+300,Infinity) | [(1,2),(3,4)] | Infinity | Infinity + (1e+300,Infinity) | ((10,20)) | Infinity | Infinity + (1e+300,Infinity) | [(11,12),(13,14)] | Infinity | Infinity + (1e+300,Infinity) | ((11,12),(13,14)) | Infinity | Infinity + (NaN,NaN) | [(1,2),(3,4)] | NaN | NaN + (NaN,NaN) | ((1,2),(3,4)) | NaN | NaN + (NaN,NaN) | [(0,0),(3,0),(4,5),(1,6)] | NaN | NaN + (NaN,NaN) | ((1,2),(3,4)) | NaN | NaN + (NaN,NaN) | ((1,2),(3,4)) | NaN | NaN + (NaN,NaN) | [(1,2),(3,4)] | NaN | NaN + (NaN,NaN) | ((10,20)) | NaN | NaN + (NaN,NaN) | [(11,12),(13,14)] | NaN | NaN + (NaN,NaN) | ((11,12),(13,14)) | NaN | NaN + (10,10) | [(1,2),(3,4)] | 9.21954445729 | 9.21954445729 + (10,10) | ((1,2),(3,4)) | 9.21954445729 | 9.21954445729 + (10,10) | [(0,0),(3,0),(4,5),(1,6)] | 7.81024967591 | 7.81024967591 + (10,10) | ((1,2),(3,4)) | 9.21954445729 | 9.21954445729 + (10,10) | ((1,2),(3,4)) | 9.21954445729 | 9.21954445729 + (10,10) | [(1,2),(3,4)] | 9.21954445729 | 9.21954445729 + (10,10) | ((10,20)) | 10 | 10 + (10,10) | [(11,12),(13,14)] | 2.2360679775 | 2.2360679775 + (10,10) | ((11,12),(13,14)) | 2.2360679775 | 2.2360679775 +(81 rows) + +-- Distance to polygon +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1; + f1 | f1 | dist_ppoly | dist_polyp +-------------------+----------------------------+---------------+--------------- + (0,0) | ((2,0),(2,4),(0,0)) | 0 | 0 + (0,0) | ((3,1),(3,3),(1,0)) | 1 | 1 + (0,0) | ((1,2),(3,4),(5,6),(7,8)) | 2.2360679775 | 2.2360679775 + (0,0) | ((7,8),(5,6),(3,4),(1,2)) | 2.2360679775 | 2.2360679775 + (0,0) | ((1,2),(7,8),(5,6),(3,-4)) | 1.58113883008 | 1.58113883008 + (0,0) | ((0,0)) | 0 | 0 + (0,0) | ((0,1),(0,1)) | 1 | 1 + (-10,0) | ((2,0),(2,4),(0,0)) | 10 | 10 + (-10,0) | ((3,1),(3,3),(1,0)) | 11 | 11 + (-10,0) | ((1,2),(3,4),(5,6),(7,8)) | 11.1803398875 | 11.1803398875 + (-10,0) | ((7,8),(5,6),(3,4),(1,2)) | 11.1803398875 | 11.1803398875 + (-10,0) | ((1,2),(7,8),(5,6),(3,-4)) | 11.1803398875 | 11.1803398875 + (-10,0) | ((0,0)) | 10 | 10 + (-10,0) | ((0,1),(0,1)) | 10.0498756211 | 10.0498756211 + (-3,4) | ((2,0),(2,4),(0,0)) | 4.472135955 | 4.472135955 + (-3,4) | ((3,1),(3,3),(1,0)) | 5.54700196225 | 5.54700196225 + (-3,4) | ((1,2),(3,4),(5,6),(7,8)) | 4.472135955 | 4.472135955 + (-3,4) | ((7,8),(5,6),(3,4),(1,2)) | 4.472135955 | 4.472135955 + (-3,4) | ((1,2),(7,8),(5,6),(3,-4)) | 4.472135955 | 4.472135955 + (-3,4) | ((0,0)) | 5 | 5 + (-3,4) | ((0,1),(0,1)) | 4.24264068712 | 4.24264068712 + (5.1,34.5) | ((2,0),(2,4),(0,0)) | 30.6571362002 | 30.6571362002 + (5.1,34.5) | ((3,1),(3,3),(1,0)) | 31.5699223946 | 31.5699223946 + (5.1,34.5) | ((1,2),(3,4),(5,6),(7,8)) | 26.5680258958 | 26.5680258958 + (5.1,34.5) | ((7,8),(5,6),(3,4),(1,2)) | 26.5680258958 | 26.5680258958 + (5.1,34.5) | ((1,2),(7,8),(5,6),(3,-4)) | 26.5680258958 | 26.5680258958 + (5.1,34.5) | ((0,0)) | 34.8749193547 | 34.8749193547 + (5.1,34.5) | ((0,1),(0,1)) | 33.8859853037 | 33.8859853037 + (-5,-12) | ((2,0),(2,4),(0,0)) | 13 | 13 + (-5,-12) | ((3,1),(3,3),(1,0)) | 13.416407865 | 13.416407865 + (-5,-12) | ((1,2),(3,4),(5,6),(7,8)) | 15.2315462117 | 15.2315462117 + (-5,-12) | ((7,8),(5,6),(3,4),(1,2)) | 15.2315462117 | 15.2315462117 + (-5,-12) | ((1,2),(7,8),(5,6),(3,-4)) | 11.313708499 | 11.313708499 + (-5,-12) | ((0,0)) | 13 | 13 + (-5,-12) | ((0,1),(0,1)) | 13.9283882772 | 13.9283882772 + (1e-300,-1e-300) | ((2,0),(2,4),(0,0)) | 0 | 0 + (1e-300,-1e-300) | ((3,1),(3,3),(1,0)) | 1 | 1 + (1e-300,-1e-300) | ((1,2),(3,4),(5,6),(7,8)) | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | ((7,8),(5,6),(3,4),(1,2)) | 2.2360679775 | 2.2360679775 + (1e-300,-1e-300) | ((1,2),(7,8),(5,6),(3,-4)) | 1.58113883008 | 1.58113883008 + (1e-300,-1e-300) | ((0,0)) | 0 | 0 + (1e-300,-1e-300) | ((0,1),(0,1)) | 1 | 1 + (1e+300,Infinity) | ((2,0),(2,4),(0,0)) | Infinity | Infinity + (1e+300,Infinity) | ((3,1),(3,3),(1,0)) | Infinity | Infinity + (1e+300,Infinity) | ((1,2),(3,4),(5,6),(7,8)) | Infinity | Infinity + (1e+300,Infinity) | ((7,8),(5,6),(3,4),(1,2)) | Infinity | Infinity + (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | Infinity | Infinity + (1e+300,Infinity) | ((0,0)) | Infinity | Infinity + (1e+300,Infinity) | ((0,1),(0,1)) | Infinity | Infinity + (NaN,NaN) | ((2,0),(2,4),(0,0)) | 0 | 0 + (NaN,NaN) | ((3,1),(3,3),(1,0)) | 0 | 0 + (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | 0 | 0 + (NaN,NaN) | ((7,8),(5,6),(3,4),(1,2)) | 0 | 0 + (NaN,NaN) | ((1,2),(7,8),(5,6),(3,-4)) | 0 | 0 + (NaN,NaN) | ((0,0)) | 0 | 0 + (NaN,NaN) | ((0,1),(0,1)) | 0 | 0 + (10,10) | ((2,0),(2,4),(0,0)) | 10 | 10 + (10,10) | ((3,1),(3,3),(1,0)) | 9.89949493661 | 9.89949493661 + (10,10) | ((1,2),(3,4),(5,6),(7,8)) | 3.60555127546 | 3.60555127546 + (10,10) | ((7,8),(5,6),(3,4),(1,2)) | 3.60555127546 | 3.60555127546 + (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | 3.60555127546 | 3.60555127546 + (10,10) | ((0,0)) | 14.1421356237 | 14.1421356237 + (10,10) | ((0,1),(0,1)) | 13.4536240471 | 13.4536240471 +(63 rows) + +-- Closest point to line +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; + f1 | s | ?column? +-------------------+---------------------------------------+---------------------------------- + (0,0) | {0,-1,5} | (0,5) + (0,0) | {1,0,5} | (-5,0) + (0,0) | {0,3,0} | (0,0) + (0,0) | {1,-1,0} | (0,0) + (0,0) | {-0.4,-1,-6} | (-2.06896551724,-5.1724137931) + (0,0) | {-0.000184615384615,-1,15.3846153846} | (0.00284023658959,15.3846148603) + (0,0) | {3,NaN,5} | + (0,0) | {NaN,NaN,NaN} | + (0,0) | {0,-1,3} | (0,3) + (0,0) | {-1,0,3} | (3,0) + (-10,0) | {0,-1,5} | (-10,5) + (-10,0) | {1,0,5} | (-5,0) + (-10,0) | {0,3,0} | (-10,0) + (-10,0) | {1,-1,0} | (-5,-5) + (-10,0) | {-0.4,-1,-6} | (-10.6896551724,-1.72413793103) + (-10,0) | {-0.000184615384615,-1,15.3846153846} | (-9.99715942258,15.386461014) + (-10,0) | {3,NaN,5} | + (-10,0) | {NaN,NaN,NaN} | + (-10,0) | {0,-1,3} | (-10,3) + (-10,0) | {-1,0,3} | (3,0) + (-3,4) | {0,-1,5} | (-3,5) + (-3,4) | {1,0,5} | (-5,4) + (-3,4) | {0,3,0} | (-3,0) + (-3,4) | {1,-1,0} | (0.5,0.5) + (-3,4) | {-0.4,-1,-6} | (-6.03448275862,-3.58620689655) + (-3,4) | {-0.000184615384615,-1,15.3846153846} | (-2.99789812268,15.3851688427) + (-3,4) | {3,NaN,5} | + (-3,4) | {NaN,NaN,NaN} | + (-3,4) | {0,-1,3} | (-3,3) + (-3,4) | {-1,0,3} | (3,4) + (5.1,34.5) | {0,-1,5} | (5.1,5) + (5.1,34.5) | {1,0,5} | (-5,34.5) + (5.1,34.5) | {0,3,0} | (5.1,0) + (5.1,34.5) | {1,-1,0} | (19.8,19.8) + (5.1,34.5) | {-0.4,-1,-6} | (-9.56896551724,-2.1724137931) + (5.1,34.5) | {-0.000184615384615,-1,15.3846153846} | (5.09647083221,15.3836744977) + (5.1,34.5) | {3,NaN,5} | + (5.1,34.5) | {NaN,NaN,NaN} | + (5.1,34.5) | {0,-1,3} | (5.1,3) + (5.1,34.5) | {-1,0,3} | (3,34.5) + (-5,-12) | {0,-1,5} | (-5,5) + (-5,-12) | {1,0,5} | (-5,-12) + (-5,-12) | {0,3,0} | (-5,0) + (-5,-12) | {1,-1,0} | (-8.5,-8.5) + (-5,-12) | {-0.4,-1,-6} | (-2.24137931034,-5.10344827586) + (-5,-12) | {-0.000184615384615,-1,15.3846153846} | (-4.99494420846,15.3855375282) + (-5,-12) | {3,NaN,5} | + (-5,-12) | {NaN,NaN,NaN} | + (-5,-12) | {0,-1,3} | (-5,3) + (-5,-12) | {-1,0,3} | (3,-12) + (1e-300,-1e-300) | {0,-1,5} | (1e-300,5) + (1e-300,-1e-300) | {1,0,5} | (-5,-1e-300) + (1e-300,-1e-300) | {0,3,0} | (1e-300,0) + (1e-300,-1e-300) | {1,-1,0} | (0,0) + (1e-300,-1e-300) | {-0.4,-1,-6} | (-2.06896551724,-5.1724137931) + (1e-300,-1e-300) | {-0.000184615384615,-1,15.3846153846} | (0.00284023658959,15.3846148603) + (1e-300,-1e-300) | {3,NaN,5} | + (1e-300,-1e-300) | {NaN,NaN,NaN} | + (1e-300,-1e-300) | {0,-1,3} | (1e-300,3) + (1e-300,-1e-300) | {-1,0,3} | (3,-1e-300) + (1e+300,Infinity) | {0,-1,5} | (1e+300,5) + (1e+300,Infinity) | {1,0,5} | + (1e+300,Infinity) | {0,3,0} | (1e+300,0) + (1e+300,Infinity) | {1,-1,0} | (Infinity,NaN) + (1e+300,Infinity) | {-0.4,-1,-6} | (-Infinity,NaN) + (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | (-Infinity,NaN) + (1e+300,Infinity) | {3,NaN,5} | + (1e+300,Infinity) | {NaN,NaN,NaN} | + (1e+300,Infinity) | {0,-1,3} | (1e+300,3) + (1e+300,Infinity) | {-1,0,3} | + (NaN,NaN) | {0,-1,5} | + (NaN,NaN) | {1,0,5} | + (NaN,NaN) | {0,3,0} | + (NaN,NaN) | {1,-1,0} | + (NaN,NaN) | {-0.4,-1,-6} | + (NaN,NaN) | {-0.000184615384615,-1,15.3846153846} | + (NaN,NaN) | {3,NaN,5} | + (NaN,NaN) | {NaN,NaN,NaN} | + (NaN,NaN) | {0,-1,3} | + (NaN,NaN) | {-1,0,3} | + (10,10) | {0,-1,5} | (10,5) + (10,10) | {1,0,5} | (-5,10) + (10,10) | {0,3,0} | (10,0) + (10,10) | {1,-1,0} | (10,10) + (10,10) | {-0.4,-1,-6} | (3.10344827586,-7.24137931034) + (10,10) | {-0.000184615384615,-1,15.3846153846} | (10.000993742,15.3827690473) + (10,10) | {3,NaN,5} | + (10,10) | {NaN,NaN,NaN} | + (10,10) | {0,-1,3} | (10,3) + (10,10) | {-1,0,3} | (3,10) +(90 rows) + +-- Closest point to line segment +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; + f1 | s | ?column? +-------------------+-------------------------------+---------------------------------- + (0,0) | [(1,2),(3,4)] | (1,2) + (0,0) | [(0,0),(6,6)] | (0,0) + (0,0) | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) + (0,0) | [(-1000000,200),(300000,-40)] | (0.00284023658959,15.3846148603) + (0,0) | [(11,22),(33,44)] | (11,22) + (0,0) | [(-10,2),(-10,3)] | (-10,2) + (0,0) | [(0,-20),(30,-20)] | (0,-20) + (0,0) | [(NaN,1),(NaN,90)] | + (-10,0) | [(1,2),(3,4)] | (1,2) + (-10,0) | [(0,0),(6,6)] | (0,0) + (-10,0) | [(10,-10),(-3,-4)] | (-3,-4) + (-10,0) | [(-1000000,200),(300000,-40)] | (-9.99715942258,15.386461014) + (-10,0) | [(11,22),(33,44)] | (11,22) + (-10,0) | [(-10,2),(-10,3)] | (-10,2) + (-10,0) | [(0,-20),(30,-20)] | (0,-20) + (-10,0) | [(NaN,1),(NaN,90)] | + (-3,4) | [(1,2),(3,4)] | (1,2) + (-3,4) | [(0,0),(6,6)] | (0.5,0.5) + (-3,4) | [(10,-10),(-3,-4)] | (-3,-4) + (-3,4) | [(-1000000,200),(300000,-40)] | (-2.99789812268,15.3851688427) + (-3,4) | [(11,22),(33,44)] | (11,22) + (-3,4) | [(-10,2),(-10,3)] | (-10,3) + (-3,4) | [(0,-20),(30,-20)] | (0,-20) + (-3,4) | [(NaN,1),(NaN,90)] | + (5.1,34.5) | [(1,2),(3,4)] | (3,4) + (5.1,34.5) | [(0,0),(6,6)] | (6,6) + (5.1,34.5) | [(10,-10),(-3,-4)] | (-3,-4) + (5.1,34.5) | [(-1000000,200),(300000,-40)] | (5.09647083221,15.3836744977) + (5.1,34.5) | [(11,22),(33,44)] | (14.3,25.3) + (5.1,34.5) | [(-10,2),(-10,3)] | (-10,3) + (5.1,34.5) | [(0,-20),(30,-20)] | (5.1,-20) + (5.1,34.5) | [(NaN,1),(NaN,90)] | + (-5,-12) | [(1,2),(3,4)] | (1,2) + (-5,-12) | [(0,0),(6,6)] | (0,0) + (-5,-12) | [(10,-10),(-3,-4)] | (-1.60487804878,-4.64390243902) + (-5,-12) | [(-1000000,200),(300000,-40)] | (-4.99494420846,15.3855375282) + (-5,-12) | [(11,22),(33,44)] | (11,22) + (-5,-12) | [(-10,2),(-10,3)] | (-10,2) + (-5,-12) | [(0,-20),(30,-20)] | (0,-20) + (-5,-12) | [(NaN,1),(NaN,90)] | + (1e-300,-1e-300) | [(1,2),(3,4)] | (1,2) + (1e-300,-1e-300) | [(0,0),(6,6)] | (0,0) + (1e-300,-1e-300) | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) + (1e-300,-1e-300) | [(-1000000,200),(300000,-40)] | (0.00284023658959,15.3846148603) + (1e-300,-1e-300) | [(11,22),(33,44)] | (11,22) + (1e-300,-1e-300) | [(-10,2),(-10,3)] | (-10,2) + (1e-300,-1e-300) | [(0,-20),(30,-20)] | (0,-20) + (1e-300,-1e-300) | [(NaN,1),(NaN,90)] | + (1e+300,Infinity) | [(1,2),(3,4)] | (3,4) + (1e+300,Infinity) | [(0,0),(6,6)] | (6,6) + (1e+300,Infinity) | [(10,-10),(-3,-4)] | (-3,-4) + (1e+300,Infinity) | [(-1000000,200),(300000,-40)] | (300000,-40) + (1e+300,Infinity) | [(11,22),(33,44)] | (33,44) + (1e+300,Infinity) | [(-10,2),(-10,3)] | (-10,3) + (1e+300,Infinity) | [(0,-20),(30,-20)] | (30,-20) + (1e+300,Infinity) | [(NaN,1),(NaN,90)] | (NaN,90) + (NaN,NaN) | [(1,2),(3,4)] | + (NaN,NaN) | [(0,0),(6,6)] | + (NaN,NaN) | [(10,-10),(-3,-4)] | + (NaN,NaN) | [(-1000000,200),(300000,-40)] | + (NaN,NaN) | [(11,22),(33,44)] | + (NaN,NaN) | [(-10,2),(-10,3)] | + (NaN,NaN) | [(0,-20),(30,-20)] | + (NaN,NaN) | [(NaN,1),(NaN,90)] | + (10,10) | [(1,2),(3,4)] | (3,4) + (10,10) | [(0,0),(6,6)] | (6,6) + (10,10) | [(10,-10),(-3,-4)] | (2.39024390244,-6.48780487805) + (10,10) | [(-1000000,200),(300000,-40)] | (10.000993742,15.3827690473) + (10,10) | [(11,22),(33,44)] | (11,22) + (10,10) | [(-10,2),(-10,3)] | (-10,3) + (10,10) | [(0,-20),(30,-20)] | (10,-20) + (10,10) | [(NaN,1),(NaN,90)] | +(72 rows) + +-- Closest point to box +SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; + f1 | f1 | ?column? +-------------------+---------------------+-------------- + (0,0) | (2,2),(0,0) | (0,0) + (0,0) | (3,3),(1,1) | (1,1) + (0,0) | (-2,2),(-8,-10) | (-2,0) + (0,0) | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + (0,0) | (3,3),(3,3) | (3,3) + (-10,0) | (2,2),(0,0) | (0,0) + (-10,0) | (3,3),(1,1) | (1,1) + (-10,0) | (-2,2),(-8,-10) | (-8,0) + (-10,0) | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + (-10,0) | (3,3),(3,3) | (3,3) + (-3,4) | (2,2),(0,0) | (0,2) + (-3,4) | (3,3),(1,1) | (1,3) + (-3,4) | (-2,2),(-8,-10) | (-3,2) + (-3,4) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + (-3,4) | (3,3),(3,3) | (3,3) + (5.1,34.5) | (2,2),(0,0) | (2,2) + (5.1,34.5) | (3,3),(1,1) | (3,3) + (5.1,34.5) | (-2,2),(-8,-10) | (-2,2) + (5.1,34.5) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + (5.1,34.5) | (3,3),(3,3) | (3,3) + (-5,-12) | (2,2),(0,0) | (0,0) + (-5,-12) | (3,3),(1,1) | (1,1) + (-5,-12) | (-2,2),(-8,-10) | (-5,-10) + (-5,-12) | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + (-5,-12) | (3,3),(3,3) | (3,3) + (1e-300,-1e-300) | (2,2),(0,0) | (0,0) + (1e-300,-1e-300) | (3,3),(1,1) | (1,1) + (1e-300,-1e-300) | (-2,2),(-8,-10) | (-2,-1e-300) + (1e-300,-1e-300) | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + (1e-300,-1e-300) | (3,3),(3,3) | (3,3) + (1e+300,Infinity) | (2,2),(0,0) | (0,2) + (1e+300,Infinity) | (3,3),(1,1) | (1,3) + (1e+300,Infinity) | (-2,2),(-8,-10) | (-8,2) + (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + (1e+300,Infinity) | (3,3),(3,3) | (3,3) + (NaN,NaN) | (2,2),(0,0) | + (NaN,NaN) | (3,3),(1,1) | + (NaN,NaN) | (-2,2),(-8,-10) | + (NaN,NaN) | (2.5,3.5),(2.5,2.5) | + (NaN,NaN) | (3,3),(3,3) | + (10,10) | (2,2),(0,0) | (2,2) + (10,10) | (3,3),(1,1) | (3,3) + (10,10) | (-2,2),(-8,-10) | (-2,2) + (10,10) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + (10,10) | (3,3),(3,3) | (3,3) +(45 rows) + +-- On line +SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s; + f1 | s +------------------+---------- + (0,0) | {0,3,0} + (0,0) | {1,-1,0} + (-10,0) | {0,3,0} + (-5,-12) | {1,0,5} + (1e-300,-1e-300) | {0,3,0} + (1e-300,-1e-300) | {1,-1,0} + (10,10) | {1,-1,0} +(7 rows) + +-- On line segment +SELECT p.f1, l.s FROM POINT_TBL p, LSEG_TBL l WHERE p.f1 <@ l.s; + f1 | s +------------------+--------------- + (0,0) | [(0,0),(6,6)] + (1e-300,-1e-300) | [(0,0),(6,6)] +(2 rows) + +-- On path +SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1; + f1 | f1 +------------------+--------------------------- + (0,0) | [(0,0),(3,0),(4,5),(1,6)] + (1e-300,-1e-300) | [(0,0),(3,0),(4,5),(1,6)] + (NaN,NaN) | ((1,2),(3,4)) + (NaN,NaN) | ((1,2),(3,4)) + (NaN,NaN) | ((1,2),(3,4)) + (NaN,NaN) | ((10,20)) + (NaN,NaN) | ((11,12),(13,14)) +(7 rows) + +-- +-- Lines +-- +-- Vertical +SELECT s FROM LINE_TBL WHERE ?| s; + s +---------- + {1,0,5} + {-1,0,3} +(2 rows) + +-- Horizontal +SELECT s FROM LINE_TBL WHERE ?- s; + s +---------- + {0,-1,5} + {0,3,0} + {0,-1,3} +(3 rows) + +-- Same as line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s = l2.s; + s | s +---------------------------------------+--------------------------------------- + {0,-1,5} | {0,-1,5} + {1,0,5} | {1,0,5} + {0,3,0} | {0,3,0} + {1,-1,0} | {1,-1,0} + {-0.4,-1,-6} | {-0.4,-1,-6} + {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} + {3,NaN,5} | {3,NaN,5} + {NaN,NaN,NaN} | {NaN,NaN,NaN} + {0,-1,3} | {0,-1,3} + {-1,0,3} | {-1,0,3} +(10 rows) + +-- Parallel to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?|| l2.s; + s | s +---------------------------------------+--------------------------------------- + {0,-1,5} | {0,-1,5} + {0,-1,5} | {0,3,0} + {0,-1,5} | {0,-1,3} + {1,0,5} | {1,0,5} + {1,0,5} | {-1,0,3} + {0,3,0} | {0,-1,5} + {0,3,0} | {0,3,0} + {0,3,0} | {0,-1,3} + {1,-1,0} | {1,-1,0} + {-0.4,-1,-6} | {-0.4,-1,-6} + {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} + {0,-1,3} | {0,-1,5} + {0,-1,3} | {0,3,0} + {0,-1,3} | {0,-1,3} + {-1,0,3} | {1,0,5} + {-1,0,3} | {-1,0,3} +(16 rows) + +-- Perpendicular to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?-| l2.s; + s | s +----------+---------- + {0,-1,5} | {1,0,5} + {0,-1,5} | {-1,0,3} + {1,0,5} | {0,-1,5} + {1,0,5} | {0,3,0} + {1,0,5} | {0,-1,3} + {0,3,0} | {1,0,5} + {0,3,0} | {-1,0,3} + {0,-1,3} | {1,0,5} + {0,-1,3} | {-1,0,3} + {-1,0,3} | {0,-1,5} + {-1,0,3} | {0,3,0} + {-1,0,3} | {0,-1,3} +(12 rows) + +-- Distance to line +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2; + s | s | ?column? +---------------------------------------+---------------------------------------+---------- + {0,-1,5} | {0,-1,5} | 0 + {0,-1,5} | {1,0,5} | 0 + {0,-1,5} | {0,3,0} | 5 + {0,-1,5} | {1,-1,0} | 0 + {0,-1,5} | {-0.4,-1,-6} | 0 + {0,-1,5} | {-0.000184615384615,-1,15.3846153846} | 0 + {0,-1,5} | {3,NaN,5} | 0 + {0,-1,5} | {NaN,NaN,NaN} | 0 + {0,-1,5} | {0,-1,3} | 2 + {0,-1,5} | {-1,0,3} | 0 + {1,0,5} | {0,-1,5} | 0 + {1,0,5} | {1,0,5} | 0 + {1,0,5} | {0,3,0} | 0 + {1,0,5} | {1,-1,0} | 0 + {1,0,5} | {-0.4,-1,-6} | 0 + {1,0,5} | {-0.000184615384615,-1,15.3846153846} | 0 + {1,0,5} | {3,NaN,5} | 0 + {1,0,5} | {NaN,NaN,NaN} | 0 + {1,0,5} | {0,-1,3} | 0 + {1,0,5} | {-1,0,3} | 8 + {0,3,0} | {0,-1,5} | 5 + {0,3,0} | {1,0,5} | 0 + {0,3,0} | {0,3,0} | 0 + {0,3,0} | {1,-1,0} | 0 + {0,3,0} | {-0.4,-1,-6} | 0 + {0,3,0} | {-0.000184615384615,-1,15.3846153846} | 0 + {0,3,0} | {3,NaN,5} | 0 + {0,3,0} | {NaN,NaN,NaN} | 0 + {0,3,0} | {0,-1,3} | 3 + {0,3,0} | {-1,0,3} | 0 + {1,-1,0} | {0,-1,5} | 0 + {1,-1,0} | {1,0,5} | 0 + {1,-1,0} | {0,3,0} | 0 + {1,-1,0} | {1,-1,0} | 0 + {1,-1,0} | {-0.4,-1,-6} | 0 + {1,-1,0} | {-0.000184615384615,-1,15.3846153846} | 0 + {1,-1,0} | {3,NaN,5} | 0 + {1,-1,0} | {NaN,NaN,NaN} | 0 + {1,-1,0} | {0,-1,3} | 0 + {1,-1,0} | {-1,0,3} | 0 + {-0.4,-1,-6} | {0,-1,5} | 0 + {-0.4,-1,-6} | {1,0,5} | 0 + {-0.4,-1,-6} | {0,3,0} | 0 + {-0.4,-1,-6} | {1,-1,0} | 0 + {-0.4,-1,-6} | {-0.4,-1,-6} | 0 + {-0.4,-1,-6} | {-0.000184615384615,-1,15.3846153846} | 0 + {-0.4,-1,-6} | {3,NaN,5} | 0 + {-0.4,-1,-6} | {NaN,NaN,NaN} | 0 + {-0.4,-1,-6} | {0,-1,3} | 0 + {-0.4,-1,-6} | {-1,0,3} | 0 + {-0.000184615384615,-1,15.3846153846} | {0,-1,5} | 0 + {-0.000184615384615,-1,15.3846153846} | {1,0,5} | 0 + {-0.000184615384615,-1,15.3846153846} | {0,3,0} | 0 + {-0.000184615384615,-1,15.3846153846} | {1,-1,0} | 0 + {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6} | 0 + {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} | 0 + {-0.000184615384615,-1,15.3846153846} | {3,NaN,5} | 0 + {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN} | 0 + {-0.000184615384615,-1,15.3846153846} | {0,-1,3} | 0 + {-0.000184615384615,-1,15.3846153846} | {-1,0,3} | 0 + {3,NaN,5} | {0,-1,5} | 0 + {3,NaN,5} | {1,0,5} | 0 + {3,NaN,5} | {0,3,0} | 0 + {3,NaN,5} | {1,-1,0} | 0 + {3,NaN,5} | {-0.4,-1,-6} | 0 + {3,NaN,5} | {-0.000184615384615,-1,15.3846153846} | 0 + {3,NaN,5} | {3,NaN,5} | 0 + {3,NaN,5} | {NaN,NaN,NaN} | 0 + {3,NaN,5} | {0,-1,3} | 0 + {3,NaN,5} | {-1,0,3} | 0 + {NaN,NaN,NaN} | {0,-1,5} | 0 + {NaN,NaN,NaN} | {1,0,5} | 0 + {NaN,NaN,NaN} | {0,3,0} | 0 + {NaN,NaN,NaN} | {1,-1,0} | 0 + {NaN,NaN,NaN} | {-0.4,-1,-6} | 0 + {NaN,NaN,NaN} | {-0.000184615384615,-1,15.3846153846} | 0 + {NaN,NaN,NaN} | {3,NaN,5} | 0 + {NaN,NaN,NaN} | {NaN,NaN,NaN} | 0 + {NaN,NaN,NaN} | {0,-1,3} | 0 + {NaN,NaN,NaN} | {-1,0,3} | 0 + {0,-1,3} | {0,-1,5} | 2 + {0,-1,3} | {1,0,5} | 0 + {0,-1,3} | {0,3,0} | 3 + {0,-1,3} | {1,-1,0} | 0 + {0,-1,3} | {-0.4,-1,-6} | 0 + {0,-1,3} | {-0.000184615384615,-1,15.3846153846} | 0 + {0,-1,3} | {3,NaN,5} | 0 + {0,-1,3} | {NaN,NaN,NaN} | 0 + {0,-1,3} | {0,-1,3} | 0 + {0,-1,3} | {-1,0,3} | 0 + {-1,0,3} | {0,-1,5} | 0 + {-1,0,3} | {1,0,5} | 8 + {-1,0,3} | {0,3,0} | 0 + {-1,0,3} | {1,-1,0} | 0 + {-1,0,3} | {-0.4,-1,-6} | 0 + {-1,0,3} | {-0.000184615384615,-1,15.3846153846} | 0 + {-1,0,3} | {3,NaN,5} | 0 + {-1,0,3} | {NaN,NaN,NaN} | 0 + {-1,0,3} | {0,-1,3} | 0 + {-1,0,3} | {-1,0,3} | 0 +(100 rows) + +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 FROM LINE_TBL l, BOX_TBL b; +ERROR: function "dist_lb" not implemented +SELECT l.s, b.f1, b.f1 <-> l.s FROM LINE_TBL l, BOX_TBL b; +ERROR: function "dist_bl" not implemented +-- Intersect with line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s; + s | s +---------------------------------------+--------------------------------------- + {0,-1,5} | {1,0,5} + {0,-1,5} | {1,-1,0} + {0,-1,5} | {-0.4,-1,-6} + {0,-1,5} | {-0.000184615384615,-1,15.3846153846} + {0,-1,5} | {3,NaN,5} + {0,-1,5} | {NaN,NaN,NaN} + {0,-1,5} | {-1,0,3} + {1,0,5} | {0,-1,5} + {1,0,5} | {0,3,0} + {1,0,5} | {1,-1,0} + {1,0,5} | {-0.4,-1,-6} + {1,0,5} | {-0.000184615384615,-1,15.3846153846} + {1,0,5} | {3,NaN,5} + {1,0,5} | {NaN,NaN,NaN} + {1,0,5} | {0,-1,3} + {0,3,0} | {1,0,5} + {0,3,0} | {1,-1,0} + {0,3,0} | {-0.4,-1,-6} + {0,3,0} | {-0.000184615384615,-1,15.3846153846} + {0,3,0} | {3,NaN,5} + {0,3,0} | {NaN,NaN,NaN} + {0,3,0} | {-1,0,3} + {1,-1,0} | {0,-1,5} + {1,-1,0} | {1,0,5} + {1,-1,0} | {0,3,0} + {1,-1,0} | {-0.4,-1,-6} + {1,-1,0} | {-0.000184615384615,-1,15.3846153846} + {1,-1,0} | {3,NaN,5} + {1,-1,0} | {NaN,NaN,NaN} + {1,-1,0} | {0,-1,3} + {1,-1,0} | {-1,0,3} + {-0.4,-1,-6} | {0,-1,5} + {-0.4,-1,-6} | {1,0,5} + {-0.4,-1,-6} | {0,3,0} + {-0.4,-1,-6} | {1,-1,0} + {-0.4,-1,-6} | {-0.000184615384615,-1,15.3846153846} + {-0.4,-1,-6} | {3,NaN,5} + {-0.4,-1,-6} | {NaN,NaN,NaN} + {-0.4,-1,-6} | {0,-1,3} + {-0.4,-1,-6} | {-1,0,3} + {-0.000184615384615,-1,15.3846153846} | {0,-1,5} + {-0.000184615384615,-1,15.3846153846} | {1,0,5} + {-0.000184615384615,-1,15.3846153846} | {0,3,0} + {-0.000184615384615,-1,15.3846153846} | {1,-1,0} + {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6} + {-0.000184615384615,-1,15.3846153846} | {3,NaN,5} + {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN} + {-0.000184615384615,-1,15.3846153846} | {0,-1,3} + {-0.000184615384615,-1,15.3846153846} | {-1,0,3} + {3,NaN,5} | {0,-1,5} + {3,NaN,5} | {1,0,5} + {3,NaN,5} | {0,3,0} + {3,NaN,5} | {1,-1,0} + {3,NaN,5} | {-0.4,-1,-6} + {3,NaN,5} | {-0.000184615384615,-1,15.3846153846} + {3,NaN,5} | {3,NaN,5} + {3,NaN,5} | {NaN,NaN,NaN} + {3,NaN,5} | {0,-1,3} + {3,NaN,5} | {-1,0,3} + {NaN,NaN,NaN} | {0,-1,5} + {NaN,NaN,NaN} | {1,0,5} + {NaN,NaN,NaN} | {0,3,0} + {NaN,NaN,NaN} | {1,-1,0} + {NaN,NaN,NaN} | {-0.4,-1,-6} + {NaN,NaN,NaN} | {-0.000184615384615,-1,15.3846153846} + {NaN,NaN,NaN} | {3,NaN,5} + {NaN,NaN,NaN} | {NaN,NaN,NaN} + {NaN,NaN,NaN} | {0,-1,3} + {NaN,NaN,NaN} | {-1,0,3} + {0,-1,3} | {1,0,5} + {0,-1,3} | {1,-1,0} + {0,-1,3} | {-0.4,-1,-6} + {0,-1,3} | {-0.000184615384615,-1,15.3846153846} + {0,-1,3} | {3,NaN,5} + {0,-1,3} | {NaN,NaN,NaN} + {0,-1,3} | {-1,0,3} + {-1,0,3} | {0,-1,5} + {-1,0,3} | {0,3,0} + {-1,0,3} | {1,-1,0} + {-1,0,3} | {-0.4,-1,-6} + {-1,0,3} | {-0.000184615384615,-1,15.3846153846} + {-1,0,3} | {3,NaN,5} + {-1,0,3} | {NaN,NaN,NaN} + {-1,0,3} | {0,-1,3} +(84 rows) + +-- Intersect with box +SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + s | f1 +--------------+--------------------- + {1,0,5} | (-2,2),(-8,-10) + {0,3,0} | (2,2),(0,0) + {0,3,0} | (-2,2),(-8,-10) + {1,-1,0} | (2,2),(0,0) + {1,-1,0} | (3,3),(1,1) + {1,-1,0} | (-2,2),(-8,-10) + {1,-1,0} | (2.5,3.5),(2.5,2.5) + {1,-1,0} | (3,3),(3,3) + {-0.4,-1,-6} | (-2,2),(-8,-10) + {0,-1,3} | (3,3),(1,1) + {0,-1,3} | (2.5,3.5),(2.5,2.5) + {0,-1,3} | (3,3),(3,3) + {-1,0,3} | (3,3),(1,1) +(13 rows) + +-- Intersection point with line +SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2; + s | s | ?column? +---------------------------------------+---------------------------------------+----------------------------------- + {0,-1,5} | {0,-1,5} | + {0,-1,5} | {1,0,5} | (-5,5) + {0,-1,5} | {0,3,0} | + {0,-1,5} | {1,-1,0} | (5,5) + {0,-1,5} | {-0.4,-1,-6} | (-27.5,5) + {0,-1,5} | {-0.000184615384615,-1,15.3846153846} | (56250,5) + {0,-1,5} | {3,NaN,5} | (NaN,NaN) + {0,-1,5} | {NaN,NaN,NaN} | (NaN,NaN) + {0,-1,5} | {0,-1,3} | + {0,-1,5} | {-1,0,3} | (3,5) + {1,0,5} | {0,-1,5} | (-5,5) + {1,0,5} | {1,0,5} | + {1,0,5} | {0,3,0} | (-5,0) + {1,0,5} | {1,-1,0} | (-5,-5) + {1,0,5} | {-0.4,-1,-6} | (-5,-4) + {1,0,5} | {-0.000184615384615,-1,15.3846153846} | (-5,15.3855384615) + {1,0,5} | {3,NaN,5} | (NaN,NaN) + {1,0,5} | {NaN,NaN,NaN} | (NaN,NaN) + {1,0,5} | {0,-1,3} | (-5,3) + {1,0,5} | {-1,0,3} | + {0,3,0} | {0,-1,5} | + {0,3,0} | {1,0,5} | (-5,0) + {0,3,0} | {0,3,0} | + {0,3,0} | {1,-1,0} | (0,0) + {0,3,0} | {-0.4,-1,-6} | (-15,0) + {0,3,0} | {-0.000184615384615,-1,15.3846153846} | (83333.3333333,0) + {0,3,0} | {3,NaN,5} | (NaN,NaN) + {0,3,0} | {NaN,NaN,NaN} | (NaN,NaN) + {0,3,0} | {0,-1,3} | + {0,3,0} | {-1,0,3} | (3,0) + {1,-1,0} | {0,-1,5} | (5,5) + {1,-1,0} | {1,0,5} | (-5,-5) + {1,-1,0} | {0,3,0} | (0,0) + {1,-1,0} | {1,-1,0} | + {1,-1,0} | {-0.4,-1,-6} | (-4.28571428571,-4.28571428571) + {1,-1,0} | {-0.000184615384615,-1,15.3846153846} | (15.3817756722,15.3817756722) + {1,-1,0} | {3,NaN,5} | (NaN,NaN) + {1,-1,0} | {NaN,NaN,NaN} | (NaN,NaN) + {1,-1,0} | {0,-1,3} | (3,3) + {1,-1,0} | {-1,0,3} | (3,3) + {-0.4,-1,-6} | {0,-1,5} | (-27.5,5) + {-0.4,-1,-6} | {1,0,5} | (-5,-4) + {-0.4,-1,-6} | {0,3,0} | (-15,0) + {-0.4,-1,-6} | {1,-1,0} | (-4.28571428571,-4.28571428571) + {-0.4,-1,-6} | {-0.4,-1,-6} | + {-0.4,-1,-6} | {-0.000184615384615,-1,15.3846153846} | (-53.4862244113,15.3944897645) + {-0.4,-1,-6} | {3,NaN,5} | (NaN,NaN) + {-0.4,-1,-6} | {NaN,NaN,NaN} | (NaN,NaN) + {-0.4,-1,-6} | {0,-1,3} | (-22.5,3) + {-0.4,-1,-6} | {-1,0,3} | (3,-7.2) + {-0.000184615384615,-1,15.3846153846} | {0,-1,5} | (56250,5) + {-0.000184615384615,-1,15.3846153846} | {1,0,5} | (-5,15.3855384615) + {-0.000184615384615,-1,15.3846153846} | {0,3,0} | (83333.3333333,-1.7763568394e-15) + {-0.000184615384615,-1,15.3846153846} | {1,-1,0} | (15.3817756722,15.3817756722) + {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6} | (-53.4862244113,15.3944897645) + {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} | + {-0.000184615384615,-1,15.3846153846} | {3,NaN,5} | (NaN,NaN) + {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN} | (NaN,NaN) + {-0.000184615384615,-1,15.3846153846} | {0,-1,3} | (67083.3333333,3) + {-0.000184615384615,-1,15.3846153846} | {-1,0,3} | (3,15.3840615385) + {3,NaN,5} | {0,-1,5} | (NaN,NaN) + {3,NaN,5} | {1,0,5} | (NaN,NaN) + {3,NaN,5} | {0,3,0} | (NaN,NaN) + {3,NaN,5} | {1,-1,0} | (NaN,NaN) + {3,NaN,5} | {-0.4,-1,-6} | (NaN,NaN) + {3,NaN,5} | {-0.000184615384615,-1,15.3846153846} | (NaN,NaN) + {3,NaN,5} | {3,NaN,5} | (NaN,NaN) + {3,NaN,5} | {NaN,NaN,NaN} | (NaN,NaN) + {3,NaN,5} | {0,-1,3} | (NaN,NaN) + {3,NaN,5} | {-1,0,3} | (NaN,NaN) + {NaN,NaN,NaN} | {0,-1,5} | (NaN,NaN) + {NaN,NaN,NaN} | {1,0,5} | (NaN,NaN) + {NaN,NaN,NaN} | {0,3,0} | (NaN,NaN) + {NaN,NaN,NaN} | {1,-1,0} | (NaN,NaN) + {NaN,NaN,NaN} | {-0.4,-1,-6} | (NaN,NaN) + {NaN,NaN,NaN} | {-0.000184615384615,-1,15.3846153846} | (NaN,NaN) + {NaN,NaN,NaN} | {3,NaN,5} | (NaN,NaN) + {NaN,NaN,NaN} | {NaN,NaN,NaN} | (NaN,NaN) + {NaN,NaN,NaN} | {0,-1,3} | (NaN,NaN) + {NaN,NaN,NaN} | {-1,0,3} | (NaN,NaN) + {0,-1,3} | {0,-1,5} | + {0,-1,3} | {1,0,5} | (-5,3) + {0,-1,3} | {0,3,0} | + {0,-1,3} | {1,-1,0} | (3,3) + {0,-1,3} | {-0.4,-1,-6} | (-22.5,3) + {0,-1,3} | {-0.000184615384615,-1,15.3846153846} | (67083.3333333,3) + {0,-1,3} | {3,NaN,5} | (NaN,NaN) + {0,-1,3} | {NaN,NaN,NaN} | (NaN,NaN) + {0,-1,3} | {0,-1,3} | + {0,-1,3} | {-1,0,3} | (3,3) + {-1,0,3} | {0,-1,5} | (3,5) + {-1,0,3} | {1,0,5} | + {-1,0,3} | {0,3,0} | (3,0) + {-1,0,3} | {1,-1,0} | (3,3) + {-1,0,3} | {-0.4,-1,-6} | (3,-7.2) + {-1,0,3} | {-0.000184615384615,-1,15.3846153846} | (3,15.3840615385) + {-1,0,3} | {3,NaN,5} | (NaN,NaN) + {-1,0,3} | {NaN,NaN,NaN} | (NaN,NaN) + {-1,0,3} | {0,-1,3} | (3,3) + {-1,0,3} | {-1,0,3} | +(100 rows) + +-- Closest point to line segment +SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1; + s | s | ?column? +---------------------------------------+-------------------------------+----------------------------------- + {0,-1,5} | [(1,2),(3,4)] | (3,4) + {0,-1,5} | [(0,0),(6,6)] | (5,5) + {0,-1,5} | [(10,-10),(-3,-4)] | (-3,-4) + {0,-1,5} | [(-1000000,200),(300000,-40)] | (56250,5) + {0,-1,5} | [(11,22),(33,44)] | (11,22) + {0,-1,5} | [(-10,2),(-10,3)] | (-10,3) + {0,-1,5} | [(0,-20),(30,-20)] | + {0,-1,5} | [(NaN,1),(NaN,90)] | + {1,0,5} | [(1,2),(3,4)] | (1,2) + {1,0,5} | [(0,0),(6,6)] | (0,0) + {1,0,5} | [(10,-10),(-3,-4)] | (-3,-4) + {1,0,5} | [(-1000000,200),(300000,-40)] | (-5,15.3855384615) + {1,0,5} | [(11,22),(33,44)] | (11,22) + {1,0,5} | [(-10,2),(-10,3)] | + {1,0,5} | [(0,-20),(30,-20)] | (0,-20) + {1,0,5} | [(NaN,1),(NaN,90)] | + {0,3,0} | [(1,2),(3,4)] | (1,2) + {0,3,0} | [(0,0),(6,6)] | (0,0) + {0,3,0} | [(10,-10),(-3,-4)] | (-3,-4) + {0,3,0} | [(-1000000,200),(300000,-40)] | (83333.3333333,-1.7763568394e-15) + {0,3,0} | [(11,22),(33,44)] | (11,22) + {0,3,0} | [(-10,2),(-10,3)] | (-10,2) + {0,3,0} | [(0,-20),(30,-20)] | + {0,3,0} | [(NaN,1),(NaN,90)] | + {1,-1,0} | [(1,2),(3,4)] | + {1,-1,0} | [(0,0),(6,6)] | + {1,-1,0} | [(10,-10),(-3,-4)] | (-3,-4) + {1,-1,0} | [(-1000000,200),(300000,-40)] | (15.3817756722,15.3817756722) + {1,-1,0} | [(11,22),(33,44)] | + {1,-1,0} | [(-10,2),(-10,3)] | (-10,2) + {1,-1,0} | [(0,-20),(30,-20)] | (0,-20) + {1,-1,0} | [(NaN,1),(NaN,90)] | + {-0.4,-1,-6} | [(1,2),(3,4)] | (1,2) + {-0.4,-1,-6} | [(0,0),(6,6)] | (0,0) + {-0.4,-1,-6} | [(10,-10),(-3,-4)] | (10,-10) + {-0.4,-1,-6} | [(-1000000,200),(300000,-40)] | (-53.4862244113,15.3944897645) + {-0.4,-1,-6} | [(11,22),(33,44)] | (11,22) + {-0.4,-1,-6} | [(-10,2),(-10,3)] | (-10,2) + {-0.4,-1,-6} | [(0,-20),(30,-20)] | (30,-20) + {-0.4,-1,-6} | [(NaN,1),(NaN,90)] | + {-0.000184615384615,-1,15.3846153846} | [(1,2),(3,4)] | (3,4) + {-0.000184615384615,-1,15.3846153846} | [(0,0),(6,6)] | (6,6) + {-0.000184615384615,-1,15.3846153846} | [(10,-10),(-3,-4)] | (-3,-4) + {-0.000184615384615,-1,15.3846153846} | [(-1000000,200),(300000,-40)] | + {-0.000184615384615,-1,15.3846153846} | [(11,22),(33,44)] | (11,22) + {-0.000184615384615,-1,15.3846153846} | [(-10,2),(-10,3)] | (-10,3) + {-0.000184615384615,-1,15.3846153846} | [(0,-20),(30,-20)] | (30,-20) + {-0.000184615384615,-1,15.3846153846} | [(NaN,1),(NaN,90)] | + {3,NaN,5} | [(1,2),(3,4)] | + {3,NaN,5} | [(0,0),(6,6)] | + {3,NaN,5} | [(10,-10),(-3,-4)] | + {3,NaN,5} | [(-1000000,200),(300000,-40)] | + {3,NaN,5} | [(11,22),(33,44)] | + {3,NaN,5} | [(-10,2),(-10,3)] | + {3,NaN,5} | [(0,-20),(30,-20)] | + {3,NaN,5} | [(NaN,1),(NaN,90)] | + {NaN,NaN,NaN} | [(1,2),(3,4)] | + {NaN,NaN,NaN} | [(0,0),(6,6)] | + {NaN,NaN,NaN} | [(10,-10),(-3,-4)] | + {NaN,NaN,NaN} | [(-1000000,200),(300000,-40)] | + {NaN,NaN,NaN} | [(11,22),(33,44)] | + {NaN,NaN,NaN} | [(-10,2),(-10,3)] | + {NaN,NaN,NaN} | [(0,-20),(30,-20)] | + {NaN,NaN,NaN} | [(NaN,1),(NaN,90)] | + {0,-1,3} | [(1,2),(3,4)] | (2,3) + {0,-1,3} | [(0,0),(6,6)] | (3,3) + {0,-1,3} | [(10,-10),(-3,-4)] | (-3,-4) + {0,-1,3} | [(-1000000,200),(300000,-40)] | (67083.3333333,3) + {0,-1,3} | [(11,22),(33,44)] | (11,22) + {0,-1,3} | [(-10,2),(-10,3)] | (-10,3) + {0,-1,3} | [(0,-20),(30,-20)] | + {0,-1,3} | [(NaN,1),(NaN,90)] | + {-1,0,3} | [(1,2),(3,4)] | (3,4) + {-1,0,3} | [(0,0),(6,6)] | (3,3) + {-1,0,3} | [(10,-10),(-3,-4)] | (3,-6.76923076923) + {-1,0,3} | [(-1000000,200),(300000,-40)] | (3,15.3840615385) + {-1,0,3} | [(11,22),(33,44)] | (11,22) + {-1,0,3} | [(-10,2),(-10,3)] | + {-1,0,3} | [(0,-20),(30,-20)] | (3,-20) + {-1,0,3} | [(NaN,1),(NaN,90)] | +(80 rows) + +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LINE_TBL l, BOX_TBL b; +ERROR: function "close_lb" not implemented -- -- Line segments -- @@ -108,42 +1568,728 @@ ERROR: operator does not exist: lseg # point LINE 1: SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection ^ HINT: No operator matches the given name and argument types. You might need to add explicit type casts. --- closest point -SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest - FROM LSEG_TBL l, POINT_TBL p; - thirty | f1 | s | closest ---------+------------+-------------------------------+---------------------------------- - | (0,0) | [(1,2),(3,4)] | (1,2) - | (0,0) | [(0,0),(6,6)] | (-0,0) - | (0,0) | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) - | (0,0) | [(-1000000,200),(300000,-40)] | (0.00284023658959,15.3846148603) - | (0,0) | [(11,22),(33,44)] | (11,22) - | (-10,0) | [(1,2),(3,4)] | (1,2) - | (-10,0) | [(0,0),(6,6)] | (0,0) - | (-10,0) | [(10,-10),(-3,-4)] | (-3,-4) - | (-10,0) | [(-1000000,200),(300000,-40)] | (-9.99715942258,15.386461014) - | (-10,0) | [(11,22),(33,44)] | (11,22) - | (-3,4) | [(1,2),(3,4)] | (1,2) - | (-3,4) | [(0,0),(6,6)] | (0.5,0.5) - | (-3,4) | [(10,-10),(-3,-4)] | (-3,-4) - | (-3,4) | [(-1000000,200),(300000,-40)] | (-2.99789812268,15.3851688427) - | (-3,4) | [(11,22),(33,44)] | (11,22) - | (5.1,34.5) | [(1,2),(3,4)] | (3,4) - | (5.1,34.5) | [(0,0),(6,6)] | (6,6) - | (5.1,34.5) | [(10,-10),(-3,-4)] | (-3,-4) - | (5.1,34.5) | [(-1000000,200),(300000,-40)] | (5.09647083221,15.3836744977) - | (5.1,34.5) | [(11,22),(33,44)] | (14.3,25.3) - | (-5,-12) | [(1,2),(3,4)] | (1,2) - | (-5,-12) | [(0,0),(6,6)] | (0,0) - | (-5,-12) | [(10,-10),(-3,-4)] | (-1.60487804878,-4.64390243902) - | (-5,-12) | [(-1000000,200),(300000,-40)] | (-4.99494420846,15.3855375282) - | (-5,-12) | [(11,22),(33,44)] | (11,22) - | (10,10) | [(1,2),(3,4)] | (3,4) - | (10,10) | [(0,0),(6,6)] | (6,6) - | (10,10) | [(10,-10),(-3,-4)] | (2.39024390244,-6.48780487805) - | (10,10) | [(-1000000,200),(300000,-40)] | (10.000993742,15.3827690473) - | (10,10) | [(11,22),(33,44)] | (11,22) -(30 rows) +-- Length +SELECT s, @-@ s FROM LSEG_TBL; + s | ?column? +-------------------------------+--------------- + [(1,2),(3,4)] | 2.82842712475 + [(0,0),(6,6)] | 8.48528137424 + [(10,-10),(-3,-4)] | 14.3178210633 + [(-1000000,200),(300000,-40)] | 1300000.02215 + [(11,22),(33,44)] | 31.1126983722 + [(-10,2),(-10,3)] | 1 + [(0,-20),(30,-20)] | 30 + [(NaN,1),(NaN,90)] | NaN +(8 rows) + +-- Vertical +SELECT s FROM LSEG_TBL WHERE ?| s; + s +------------------- + [(-10,2),(-10,3)] +(1 row) + +-- Horizontal +SELECT s FROM LSEG_TBL WHERE ?- s; + s +-------------------- + [(0,-20),(30,-20)] +(1 row) + +-- Center +SELECT s, @@ s FROM LSEG_TBL; + s | ?column? +-------------------------------+-------------- + [(1,2),(3,4)] | (2,3) + [(0,0),(6,6)] | (3,3) + [(10,-10),(-3,-4)] | (3.5,-7) + [(-1000000,200),(300000,-40)] | (-350000,80) + [(11,22),(33,44)] | (22,33) + [(-10,2),(-10,3)] | (-10,2.5) + [(0,-20),(30,-20)] | (15,-20) + [(NaN,1),(NaN,90)] | (NaN,45.5) +(8 rows) + +-- To point +SELECT s, s::point FROM LSEG_TBL; + s | s +-------------------------------+-------------- + [(1,2),(3,4)] | (2,3) + [(0,0),(6,6)] | (3,3) + [(10,-10),(-3,-4)] | (3.5,-7) + [(-1000000,200),(300000,-40)] | (-350000,80) + [(11,22),(33,44)] | (22,33) + [(-10,2),(-10,3)] | (-10,2.5) + [(0,-20),(30,-20)] | (15,-20) + [(NaN,1),(NaN,90)] | (NaN,45.5) +(8 rows) + +-- Has points less than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s < l2.s; + s | s +--------------------+------------------------------- + [(1,2),(3,4)] | [(0,0),(6,6)] + [(1,2),(3,4)] | [(10,-10),(-3,-4)] + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] + [(1,2),(3,4)] | [(11,22),(33,44)] + [(1,2),(3,4)] | [(0,-20),(30,-20)] + [(0,0),(6,6)] | [(10,-10),(-3,-4)] + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] + [(0,0),(6,6)] | [(11,22),(33,44)] + [(0,0),(6,6)] | [(0,-20),(30,-20)] + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] + [(10,-10),(-3,-4)] | [(11,22),(33,44)] + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] + [(-10,2),(-10,3)] | [(1,2),(3,4)] + [(-10,2),(-10,3)] | [(0,0),(6,6)] + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] + [(-10,2),(-10,3)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] + [(0,-20),(30,-20)] | [(11,22),(33,44)] +(21 rows) + +-- Has points less than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s <= l2.s; + s | s +-------------------------------+------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(0,0),(6,6)] + [(1,2),(3,4)] | [(10,-10),(-3,-4)] + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] + [(1,2),(3,4)] | [(11,22),(33,44)] + [(1,2),(3,4)] | [(0,-20),(30,-20)] + [(0,0),(6,6)] | [(0,0),(6,6)] + [(0,0),(6,6)] | [(10,-10),(-3,-4)] + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] + [(0,0),(6,6)] | [(11,22),(33,44)] + [(0,0),(6,6)] | [(0,-20),(30,-20)] + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] + [(10,-10),(-3,-4)] | [(11,22),(33,44)] + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] + [(11,22),(33,44)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(1,2),(3,4)] + [(-10,2),(-10,3)] | [(0,0),(6,6)] + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] + [(-10,2),(-10,3)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] + [(0,-20),(30,-20)] | [(11,22),(33,44)] + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] +(28 rows) + +-- Has points equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s = l2.s; + s | s +-------------------------------+------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(0,0),(6,6)] | [(0,0),(6,6)] + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] + [(11,22),(33,44)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] + [(NaN,1),(NaN,90)] | [(NaN,1),(NaN,90)] +(8 rows) + +-- Has points greater than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s >= l2.s; + s | s +-------------------------------+------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(-10,2),(-10,3)] + [(0,0),(6,6)] | [(1,2),(3,4)] + [(0,0),(6,6)] | [(0,0),(6,6)] + [(0,0),(6,6)] | [(-10,2),(-10,3)] + [(10,-10),(-3,-4)] | [(1,2),(3,4)] + [(10,-10),(-3,-4)] | [(0,0),(6,6)] + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] + [(11,22),(33,44)] | [(1,2),(3,4)] + [(11,22),(33,44)] | [(0,0),(6,6)] + [(11,22),(33,44)] | [(10,-10),(-3,-4)] + [(11,22),(33,44)] | [(11,22),(33,44)] + [(11,22),(33,44)] | [(-10,2),(-10,3)] + [(11,22),(33,44)] | [(0,-20),(30,-20)] + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] + [(0,-20),(30,-20)] | [(1,2),(3,4)] + [(0,-20),(30,-20)] | [(0,0),(6,6)] + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] +(28 rows) + +-- Has points greater than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s > l2.s; + s | s +-------------------------------+-------------------- + [(1,2),(3,4)] | [(-10,2),(-10,3)] + [(0,0),(6,6)] | [(1,2),(3,4)] + [(0,0),(6,6)] | [(-10,2),(-10,3)] + [(10,-10),(-3,-4)] | [(1,2),(3,4)] + [(10,-10),(-3,-4)] | [(0,0),(6,6)] + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] + [(11,22),(33,44)] | [(1,2),(3,4)] + [(11,22),(33,44)] | [(0,0),(6,6)] + [(11,22),(33,44)] | [(10,-10),(-3,-4)] + [(11,22),(33,44)] | [(-10,2),(-10,3)] + [(11,22),(33,44)] | [(0,-20),(30,-20)] + [(0,-20),(30,-20)] | [(1,2),(3,4)] + [(0,-20),(30,-20)] | [(0,0),(6,6)] + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] +(21 rows) + +-- Has points not equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s != l2.s; + s | s +-------------------------------+------------------------------- + [(1,2),(3,4)] | [(0,0),(6,6)] + [(1,2),(3,4)] | [(10,-10),(-3,-4)] + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] + [(1,2),(3,4)] | [(11,22),(33,44)] + [(1,2),(3,4)] | [(-10,2),(-10,3)] + [(1,2),(3,4)] | [(0,-20),(30,-20)] + [(1,2),(3,4)] | [(NaN,1),(NaN,90)] + [(0,0),(6,6)] | [(1,2),(3,4)] + [(0,0),(6,6)] | [(10,-10),(-3,-4)] + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] + [(0,0),(6,6)] | [(11,22),(33,44)] + [(0,0),(6,6)] | [(-10,2),(-10,3)] + [(0,0),(6,6)] | [(0,-20),(30,-20)] + [(0,0),(6,6)] | [(NaN,1),(NaN,90)] + [(10,-10),(-3,-4)] | [(1,2),(3,4)] + [(10,-10),(-3,-4)] | [(0,0),(6,6)] + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] + [(10,-10),(-3,-4)] | [(11,22),(33,44)] + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] + [(10,-10),(-3,-4)] | [(NaN,1),(NaN,90)] + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] + [(-1000000,200),(300000,-40)] | [(NaN,1),(NaN,90)] + [(11,22),(33,44)] | [(1,2),(3,4)] + [(11,22),(33,44)] | [(0,0),(6,6)] + [(11,22),(33,44)] | [(10,-10),(-3,-4)] + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] + [(11,22),(33,44)] | [(-10,2),(-10,3)] + [(11,22),(33,44)] | [(0,-20),(30,-20)] + [(11,22),(33,44)] | [(NaN,1),(NaN,90)] + [(-10,2),(-10,3)] | [(1,2),(3,4)] + [(-10,2),(-10,3)] | [(0,0),(6,6)] + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] + [(-10,2),(-10,3)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] + [(-10,2),(-10,3)] | [(NaN,1),(NaN,90)] + [(0,-20),(30,-20)] | [(1,2),(3,4)] + [(0,-20),(30,-20)] | [(0,0),(6,6)] + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] + [(0,-20),(30,-20)] | [(11,22),(33,44)] + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] + [(0,-20),(30,-20)] | [(NaN,1),(NaN,90)] + [(NaN,1),(NaN,90)] | [(1,2),(3,4)] + [(NaN,1),(NaN,90)] | [(0,0),(6,6)] + [(NaN,1),(NaN,90)] | [(10,-10),(-3,-4)] + [(NaN,1),(NaN,90)] | [(-1000000,200),(300000,-40)] + [(NaN,1),(NaN,90)] | [(11,22),(33,44)] + [(NaN,1),(NaN,90)] | [(-10,2),(-10,3)] + [(NaN,1),(NaN,90)] | [(0,-20),(30,-20)] +(56 rows) + +-- Parallel with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?|| l2.s; + s | s +-------------------------------+------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(0,0),(6,6)] + [(1,2),(3,4)] | [(11,22),(33,44)] + [(0,0),(6,6)] | [(1,2),(3,4)] + [(0,0),(6,6)] | [(0,0),(6,6)] + [(0,0),(6,6)] | [(11,22),(33,44)] + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] + [(11,22),(33,44)] | [(1,2),(3,4)] + [(11,22),(33,44)] | [(0,0),(6,6)] + [(11,22),(33,44)] | [(11,22),(33,44)] + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] +(13 rows) + +-- Perpendicular with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s; + s | s +--------------------+-------------------- + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] +(2 rows) + +-- Distance to line +SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1; + s | s | dist_sl | dist_ls +-------------------------------+---------------------------------------+----------------+---------------- + [(1,2),(3,4)] | {0,-1,5} | 1 | 1 + [(0,0),(6,6)] | {0,-1,5} | 0 | 0 + [(10,-10),(-3,-4)] | {0,-1,5} | 9 | 9 + [(-1000000,200),(300000,-40)] | {0,-1,5} | 0 | 0 + [(11,22),(33,44)] | {0,-1,5} | 17 | 17 + [(-10,2),(-10,3)] | {0,-1,5} | 2 | 2 + [(0,-20),(30,-20)] | {0,-1,5} | 25 | 25 + [(NaN,1),(NaN,90)] | {0,-1,5} | NaN | NaN + [(1,2),(3,4)] | {1,0,5} | 6 | 6 + [(0,0),(6,6)] | {1,0,5} | 5 | 5 + [(10,-10),(-3,-4)] | {1,0,5} | 2 | 2 + [(-1000000,200),(300000,-40)] | {1,0,5} | 0 | 0 + [(11,22),(33,44)] | {1,0,5} | 16 | 16 + [(-10,2),(-10,3)] | {1,0,5} | 5 | 5 + [(0,-20),(30,-20)] | {1,0,5} | 5 | 5 + [(NaN,1),(NaN,90)] | {1,0,5} | NaN | NaN + [(1,2),(3,4)] | {0,3,0} | 2 | 2 + [(0,0),(6,6)] | {0,3,0} | 0 | 0 + [(10,-10),(-3,-4)] | {0,3,0} | 4 | 4 + [(-1000000,200),(300000,-40)] | {0,3,0} | 0 | 0 + [(11,22),(33,44)] | {0,3,0} | 22 | 22 + [(-10,2),(-10,3)] | {0,3,0} | 2 | 2 + [(0,-20),(30,-20)] | {0,3,0} | 20 | 20 + [(NaN,1),(NaN,90)] | {0,3,0} | NaN | NaN + [(1,2),(3,4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 + [(0,0),(6,6)] | {1,-1,0} | 0 | 0 + [(10,-10),(-3,-4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 + [(-1000000,200),(300000,-40)] | {1,-1,0} | 0 | 0 + [(11,22),(33,44)] | {1,-1,0} | 7.77817459305 | 7.77817459305 + [(-10,2),(-10,3)] | {1,-1,0} | 8.48528137424 | 8.48528137424 + [(0,-20),(30,-20)] | {1,-1,0} | 14.1421356237 | 14.1421356237 + [(NaN,1),(NaN,90)] | {1,-1,0} | NaN | NaN + [(1,2),(3,4)] | {-0.4,-1,-6} | 7.79920420344 | 7.79920420344 + [(0,0),(6,6)] | {-0.4,-1,-6} | 5.57086014531 | 5.57086014531 + [(10,-10),(-3,-4)] | {-0.4,-1,-6} | 0 | 0 + [(-1000000,200),(300000,-40)] | {-0.4,-1,-6} | 0 | 0 + [(11,22),(33,44)] | {-0.4,-1,-6} | 30.0826447847 | 30.0826447847 + [(-10,2),(-10,3)] | {-0.4,-1,-6} | 3.71390676354 | 3.71390676354 + [(0,-20),(30,-20)] | {-0.4,-1,-6} | 1.85695338177 | 1.85695338177 + [(NaN,1),(NaN,90)] | {-0.4,-1,-6} | NaN | NaN + [(1,2),(3,4)] | {-0.000184615384615,-1,15.3846153846} | 11.3840613445 | 11.3840613445 + [(0,0),(6,6)] | {-0.000184615384615,-1,15.3846153846} | 9.3835075324 | 9.3835075324 + [(10,-10),(-3,-4)] | {-0.000184615384615,-1,15.3846153846} | 19.3851689004 | 19.3851689004 + [(-1000000,200),(300000,-40)] | {-0.000184615384615,-1,15.3846153846} | 0 | 0 + [(11,22),(33,44)] | {-0.000184615384615,-1,15.3846153846} | 6.61741527185 | 6.61741527185 + [(-10,2),(-10,3)] | {-0.000184615384615,-1,15.3846153846} | 12.3864613274 | 12.3864613274 + [(0,-20),(30,-20)] | {-0.000184615384615,-1,15.3846153846} | 35.3790763202 | 35.3790763202 + [(NaN,1),(NaN,90)] | {-0.000184615384615,-1,15.3846153846} | NaN | NaN + [(1,2),(3,4)] | {3,NaN,5} | NaN | NaN + [(0,0),(6,6)] | {3,NaN,5} | NaN | NaN + [(10,-10),(-3,-4)] | {3,NaN,5} | NaN | NaN + [(-1000000,200),(300000,-40)] | {3,NaN,5} | NaN | NaN + [(11,22),(33,44)] | {3,NaN,5} | NaN | NaN + [(-10,2),(-10,3)] | {3,NaN,5} | NaN | NaN + [(0,-20),(30,-20)] | {3,NaN,5} | NaN | NaN + [(NaN,1),(NaN,90)] | {3,NaN,5} | NaN | NaN + [(1,2),(3,4)] | {NaN,NaN,NaN} | NaN | NaN + [(0,0),(6,6)] | {NaN,NaN,NaN} | NaN | NaN + [(10,-10),(-3,-4)] | {NaN,NaN,NaN} | NaN | NaN + [(-1000000,200),(300000,-40)] | {NaN,NaN,NaN} | NaN | NaN + [(11,22),(33,44)] | {NaN,NaN,NaN} | NaN | NaN + [(-10,2),(-10,3)] | {NaN,NaN,NaN} | NaN | NaN + [(0,-20),(30,-20)] | {NaN,NaN,NaN} | NaN | NaN + [(NaN,1),(NaN,90)] | {NaN,NaN,NaN} | NaN | NaN + [(1,2),(3,4)] | {0,-1,3} | 0 | 0 + [(0,0),(6,6)] | {0,-1,3} | 0 | 0 + [(10,-10),(-3,-4)] | {0,-1,3} | 7 | 7 + [(-1000000,200),(300000,-40)] | {0,-1,3} | 0 | 0 + [(11,22),(33,44)] | {0,-1,3} | 19 | 19 + [(-10,2),(-10,3)] | {0,-1,3} | 0 | 0 + [(0,-20),(30,-20)] | {0,-1,3} | 23 | 23 + [(NaN,1),(NaN,90)] | {0,-1,3} | NaN | NaN + [(1,2),(3,4)] | {-1,0,3} | 0 | 0 + [(0,0),(6,6)] | {-1,0,3} | 0 | 0 + [(10,-10),(-3,-4)] | {-1,0,3} | 0 | 0 + [(-1000000,200),(300000,-40)] | {-1,0,3} | 0 | 0 + [(11,22),(33,44)] | {-1,0,3} | 8 | 8 + [(-10,2),(-10,3)] | {-1,0,3} | 13 | 13 + [(0,-20),(30,-20)] | {-1,0,3} | 0 | 0 + [(NaN,1),(NaN,90)] | {-1,0,3} | NaN | NaN +(80 rows) + +-- Distance to line segment +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + s | s | ?column? +-------------------------------+-------------------------------+---------------- + [(1,2),(3,4)] | [(1,2),(3,4)] | 0 + [(1,2),(3,4)] | [(0,0),(6,6)] | 0.707106781187 + [(1,2),(3,4)] | [(10,-10),(-3,-4)] | 7.12398901685 + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] | 11.3840613445 + [(1,2),(3,4)] | [(11,22),(33,44)] | 19.6977156036 + [(1,2),(3,4)] | [(-10,2),(-10,3)] | 11 + [(1,2),(3,4)] | [(0,-20),(30,-20)] | 22 + [(1,2),(3,4)] | [(NaN,1),(NaN,90)] | NaN + [(0,0),(6,6)] | [(1,2),(3,4)] | 0.707106781187 + [(0,0),(6,6)] | [(0,0),(6,6)] | 0 + [(0,0),(6,6)] | [(10,-10),(-3,-4)] | 4.88901207039 + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] | 9.3835075324 + [(0,0),(6,6)] | [(11,22),(33,44)] | 16.7630546142 + [(0,0),(6,6)] | [(-10,2),(-10,3)] | 10.1980390272 + [(0,0),(6,6)] | [(0,-20),(30,-20)] | 20 + [(0,0),(6,6)] | [(NaN,1),(NaN,90)] | NaN + [(10,-10),(-3,-4)] | [(1,2),(3,4)] | 7.12398901685 + [(10,-10),(-3,-4)] | [(0,0),(6,6)] | 4.88901207039 + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] | 0 + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] | 19.3851689004 + [(10,-10),(-3,-4)] | [(11,22),(33,44)] | 29.4737584815 + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] | 9.21954445729 + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] | 10 + [(10,-10),(-3,-4)] | [(NaN,1),(NaN,90)] | NaN + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] | 11.3840613445 + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] | 9.3835075324 + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] | 19.3851689004 + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] | 0 + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] | 6.61741527185 + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] | 12.3864613274 + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] | 35.3790763202 + [(-1000000,200),(300000,-40)] | [(NaN,1),(NaN,90)] | NaN + [(11,22),(33,44)] | [(1,2),(3,4)] | 19.6977156036 + [(11,22),(33,44)] | [(0,0),(6,6)] | 16.7630546142 + [(11,22),(33,44)] | [(10,-10),(-3,-4)] | 29.4737584815 + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] | 6.61741527185 + [(11,22),(33,44)] | [(11,22),(33,44)] | 0 + [(11,22),(33,44)] | [(-10,2),(-10,3)] | 28.319604517 + [(11,22),(33,44)] | [(0,-20),(30,-20)] | 42 + [(11,22),(33,44)] | [(NaN,1),(NaN,90)] | NaN + [(-10,2),(-10,3)] | [(1,2),(3,4)] | 11 + [(-10,2),(-10,3)] | [(0,0),(6,6)] | 10.1980390272 + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] | 9.21954445729 + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] | 12.3864613274 + [(-10,2),(-10,3)] | [(11,22),(33,44)] | 28.319604517 + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] | 0 + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] | 24.1660919472 + [(-10,2),(-10,3)] | [(NaN,1),(NaN,90)] | NaN + [(0,-20),(30,-20)] | [(1,2),(3,4)] | 22 + [(0,-20),(30,-20)] | [(0,0),(6,6)] | 20 + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] | 10 + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] | 35.3790763202 + [(0,-20),(30,-20)] | [(11,22),(33,44)] | 42 + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] | 24.1660919472 + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] | 0 + [(0,-20),(30,-20)] | [(NaN,1),(NaN,90)] | NaN + [(NaN,1),(NaN,90)] | [(1,2),(3,4)] | NaN + [(NaN,1),(NaN,90)] | [(0,0),(6,6)] | NaN + [(NaN,1),(NaN,90)] | [(10,-10),(-3,-4)] | NaN + [(NaN,1),(NaN,90)] | [(-1000000,200),(300000,-40)] | NaN + [(NaN,1),(NaN,90)] | [(11,22),(33,44)] | NaN + [(NaN,1),(NaN,90)] | [(-10,2),(-10,3)] | NaN + [(NaN,1),(NaN,90)] | [(0,-20),(30,-20)] | NaN + [(NaN,1),(NaN,90)] | [(NaN,1),(NaN,90)] | NaN +(64 rows) + +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM LSEG_TBL l, BOX_TBL b; + s | f1 | dist_sb | dist_bs +-------------------------------+---------------------+----------------+---------------- + [(1,2),(3,4)] | (2,2),(0,0) | 0 | 0 + [(1,2),(3,4)] | (3,3),(1,1) | 0 | 0 + [(1,2),(3,4)] | (-2,2),(-8,-10) | 3 | 3 + [(1,2),(3,4)] | (2.5,3.5),(2.5,2.5) | 0 | 0 + [(1,2),(3,4)] | (3,3),(3,3) | 0.707106781187 | 0.707106781187 + [(0,0),(6,6)] | (2,2),(0,0) | 0 | 0 + [(0,0),(6,6)] | (3,3),(1,1) | 0 | 0 + [(0,0),(6,6)] | (-2,2),(-8,-10) | 2 | 2 + [(0,0),(6,6)] | (2.5,3.5),(2.5,2.5) | 0 | 0 + [(0,0),(6,6)] | (3,3),(3,3) | 0 | 0 + [(10,-10),(-3,-4)] | (2,2),(0,0) | 4.88901207039 | 4.88901207039 + [(10,-10),(-3,-4)] | (3,3),(1,1) | 6.21602963235 | 6.21602963235 + [(10,-10),(-3,-4)] | (-2,2),(-8,-10) | 0 | 0 + [(10,-10),(-3,-4)] | (2.5,3.5),(2.5,2.5) | 8.20655597529 | 8.20655597529 + [(10,-10),(-3,-4)] | (3,3),(3,3) | 8.87006475627 | 8.87006475627 + [(-1000000,200),(300000,-40)] | (2,2),(0,0) | 13.3842459258 | 13.3842459258 + [(-1000000,200),(300000,-40)] | (3,3),(1,1) | 12.3840613274 | 12.3840613274 + [(-1000000,200),(300000,-40)] | (-2,2),(-8,-10) | 13.3849843873 | 13.3849843873 + [(-1000000,200),(300000,-40)] | (2.5,3.5),(2.5,2.5) | 11.8841536436 | 11.8841536436 + [(-1000000,200),(300000,-40)] | (3,3),(3,3) | 12.3840613274 | 12.3840613274 + [(11,22),(33,44)] | (2,2),(0,0) | 21.9317121995 | 21.9317121995 + [(11,22),(33,44)] | (3,3),(1,1) | 20.6155281281 | 20.6155281281 + [(11,22),(33,44)] | (-2,2),(-8,-10) | 23.8537208838 | 23.8537208838 + [(11,22),(33,44)] | (2.5,3.5),(2.5,2.5) | 20.3592730715 | 20.3592730715 + [(11,22),(33,44)] | (3,3),(3,3) | 20.6155281281 | 20.6155281281 + [(-10,2),(-10,3)] | (2,2),(0,0) | 10 | 10 + [(-10,2),(-10,3)] | (3,3),(1,1) | 11 | 11 + [(-10,2),(-10,3)] | (-2,2),(-8,-10) | 2 | 2 + [(-10,2),(-10,3)] | (2.5,3.5),(2.5,2.5) | 12.5 | 12.5 + [(-10,2),(-10,3)] | (3,3),(3,3) | 13 | 13 + [(0,-20),(30,-20)] | (2,2),(0,0) | 20 | 20 + [(0,-20),(30,-20)] | (3,3),(1,1) | 21 | 21 + [(0,-20),(30,-20)] | (-2,2),(-8,-10) | 10.1980390272 | 10.1980390272 + [(0,-20),(30,-20)] | (2.5,3.5),(2.5,2.5) | 22.5 | 22.5 + [(0,-20),(30,-20)] | (3,3),(3,3) | 23 | 23 + [(NaN,1),(NaN,90)] | (2,2),(0,0) | NaN | NaN + [(NaN,1),(NaN,90)] | (3,3),(1,1) | NaN | NaN + [(NaN,1),(NaN,90)] | (-2,2),(-8,-10) | NaN | NaN + [(NaN,1),(NaN,90)] | (2.5,3.5),(2.5,2.5) | NaN | NaN + [(NaN,1),(NaN,90)] | (3,3),(3,3) | NaN | NaN +(40 rows) + +-- Intersect with line segment +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s ?# l1.s; + s | s +-------------------------------+-------------- + [(0,0),(6,6)] | {0,-1,5} + [(-1000000,200),(300000,-40)] | {0,-1,5} + [(-1000000,200),(300000,-40)] | {1,0,5} + [(0,0),(6,6)] | {0,3,0} + [(-1000000,200),(300000,-40)] | {0,3,0} + [(-1000000,200),(300000,-40)] | {1,-1,0} + [(10,-10),(-3,-4)] | {-0.4,-1,-6} + [(-1000000,200),(300000,-40)] | {-0.4,-1,-6} + [(1,2),(3,4)] | {0,-1,3} + [(0,0),(6,6)] | {0,-1,3} + [(-1000000,200),(300000,-40)] | {0,-1,3} + [(-10,2),(-10,3)] | {0,-1,3} + [(1,2),(3,4)] | {-1,0,3} + [(0,0),(6,6)] | {-1,0,3} + [(10,-10),(-3,-4)] | {-1,0,3} + [(-1000000,200),(300000,-40)] | {-1,0,3} + [(0,-20),(30,-20)] | {-1,0,3} +(17 rows) + +-- Intersect with box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + s | f1 +--------------------+--------------------- + [(1,2),(3,4)] | (2,2),(0,0) + [(1,2),(3,4)] | (3,3),(1,1) + [(1,2),(3,4)] | (2.5,3.5),(2.5,2.5) + [(0,0),(6,6)] | (2,2),(0,0) + [(0,0),(6,6)] | (3,3),(1,1) + [(0,0),(6,6)] | (2.5,3.5),(2.5,2.5) + [(0,0),(6,6)] | (3,3),(3,3) + [(10,-10),(-3,-4)] | (-2,2),(-8,-10) +(8 rows) + +-- Intersection point with line segment +SELECT l1.s, l2.s, l1.s # l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + s | s | ?column? +-------------------------------+-------------------------------+---------- + [(1,2),(3,4)] | [(1,2),(3,4)] | + [(1,2),(3,4)] | [(0,0),(6,6)] | + [(1,2),(3,4)] | [(10,-10),(-3,-4)] | + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] | + [(1,2),(3,4)] | [(11,22),(33,44)] | + [(1,2),(3,4)] | [(-10,2),(-10,3)] | + [(1,2),(3,4)] | [(0,-20),(30,-20)] | + [(1,2),(3,4)] | [(NaN,1),(NaN,90)] | + [(0,0),(6,6)] | [(1,2),(3,4)] | + [(0,0),(6,6)] | [(0,0),(6,6)] | + [(0,0),(6,6)] | [(10,-10),(-3,-4)] | + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] | + [(0,0),(6,6)] | [(11,22),(33,44)] | + [(0,0),(6,6)] | [(-10,2),(-10,3)] | + [(0,0),(6,6)] | [(0,-20),(30,-20)] | + [(0,0),(6,6)] | [(NaN,1),(NaN,90)] | + [(10,-10),(-3,-4)] | [(1,2),(3,4)] | + [(10,-10),(-3,-4)] | [(0,0),(6,6)] | + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] | + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] | + [(10,-10),(-3,-4)] | [(11,22),(33,44)] | + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] | + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] | + [(10,-10),(-3,-4)] | [(NaN,1),(NaN,90)] | + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] | + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] | + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] | + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] | + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] | + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] | + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] | + [(-1000000,200),(300000,-40)] | [(NaN,1),(NaN,90)] | + [(11,22),(33,44)] | [(1,2),(3,4)] | + [(11,22),(33,44)] | [(0,0),(6,6)] | + [(11,22),(33,44)] | [(10,-10),(-3,-4)] | + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] | + [(11,22),(33,44)] | [(11,22),(33,44)] | + [(11,22),(33,44)] | [(-10,2),(-10,3)] | + [(11,22),(33,44)] | [(0,-20),(30,-20)] | + [(11,22),(33,44)] | [(NaN,1),(NaN,90)] | + [(-10,2),(-10,3)] | [(1,2),(3,4)] | + [(-10,2),(-10,3)] | [(0,0),(6,6)] | + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] | + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] | + [(-10,2),(-10,3)] | [(11,22),(33,44)] | + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] | + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] | + [(-10,2),(-10,3)] | [(NaN,1),(NaN,90)] | + [(0,-20),(30,-20)] | [(1,2),(3,4)] | + [(0,-20),(30,-20)] | [(0,0),(6,6)] | + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] | + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] | + [(0,-20),(30,-20)] | [(11,22),(33,44)] | + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] | + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] | + [(0,-20),(30,-20)] | [(NaN,1),(NaN,90)] | + [(NaN,1),(NaN,90)] | [(1,2),(3,4)] | + [(NaN,1),(NaN,90)] | [(0,0),(6,6)] | + [(NaN,1),(NaN,90)] | [(10,-10),(-3,-4)] | + [(NaN,1),(NaN,90)] | [(-1000000,200),(300000,-40)] | + [(NaN,1),(NaN,90)] | [(11,22),(33,44)] | + [(NaN,1),(NaN,90)] | [(-10,2),(-10,3)] | + [(NaN,1),(NaN,90)] | [(0,-20),(30,-20)] | + [(NaN,1),(NaN,90)] | [(NaN,1),(NaN,90)] | +(64 rows) + +-- Closest point to line +SELECT l.s, l1.s, l.s ## l1.s FROM LSEG_TBL l, LINE_TBL l1; +ERROR: function "close_sl" not implemented +-- Closest point to line segment +SELECT l1.s, l2.s, l1.s ## l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + s | s | ?column? +-------------------------------+-------------------------------+--------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] | + [(1,2),(3,4)] | [(0,0),(6,6)] | + [(1,2),(3,4)] | [(10,-10),(-3,-4)] | (-1.98536585366,-4.46829268293) + [(1,2),(3,4)] | [(-1000000,200),(300000,-40)] | (3.00210167283,15.3840611505) + [(1,2),(3,4)] | [(11,22),(33,44)] | + [(1,2),(3,4)] | [(-10,2),(-10,3)] | (-10,2) + [(1,2),(3,4)] | [(0,-20),(30,-20)] | (1,-20) + [(1,2),(3,4)] | [(NaN,1),(NaN,90)] | + [(0,0),(6,6)] | [(1,2),(3,4)] | + [(0,0),(6,6)] | [(0,0),(6,6)] | + [(0,0),(6,6)] | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) + [(0,0),(6,6)] | [(-1000000,200),(300000,-40)] | (6.00173233982,15.3835073725) + [(0,0),(6,6)] | [(11,22),(33,44)] | + [(0,0),(6,6)] | [(-10,2),(-10,3)] | (-10,2) + [(0,0),(6,6)] | [(0,-20),(30,-20)] | (0,-20) + [(0,0),(6,6)] | [(NaN,1),(NaN,90)] | + [(10,-10),(-3,-4)] | [(1,2),(3,4)] | (1,2) + [(10,-10),(-3,-4)] | [(0,0),(6,6)] | (0,0) + [(10,-10),(-3,-4)] | [(10,-10),(-3,-4)] | + [(10,-10),(-3,-4)] | [(-1000000,200),(300000,-40)] | (-2.99642119965,15.3851685701) + [(10,-10),(-3,-4)] | [(11,22),(33,44)] | (11,22) + [(10,-10),(-3,-4)] | [(-10,2),(-10,3)] | (-10,2) + [(10,-10),(-3,-4)] | [(0,-20),(30,-20)] | (10,-20) + [(10,-10),(-3,-4)] | [(NaN,1),(NaN,90)] | + [(-1000000,200),(300000,-40)] | [(1,2),(3,4)] | (3,4) + [(-1000000,200),(300000,-40)] | [(0,0),(6,6)] | (6,6) + [(-1000000,200),(300000,-40)] | [(10,-10),(-3,-4)] | (-3,-4) + [(-1000000,200),(300000,-40)] | [(-1000000,200),(300000,-40)] | + [(-1000000,200),(300000,-40)] | [(11,22),(33,44)] | (11,22) + [(-1000000,200),(300000,-40)] | [(-10,2),(-10,3)] | (-10,3) + [(-1000000,200),(300000,-40)] | [(0,-20),(30,-20)] | (30,-20) + [(-1000000,200),(300000,-40)] | [(NaN,1),(NaN,90)] | + [(11,22),(33,44)] | [(1,2),(3,4)] | + [(11,22),(33,44)] | [(0,0),(6,6)] | + [(11,22),(33,44)] | [(10,-10),(-3,-4)] | (-1.3512195122,-4.76097560976) + [(11,22),(33,44)] | [(-1000000,200),(300000,-40)] | (10.9987783234,15.3825848409) + [(11,22),(33,44)] | [(11,22),(33,44)] | + [(11,22),(33,44)] | [(-10,2),(-10,3)] | (-10,3) + [(11,22),(33,44)] | [(0,-20),(30,-20)] | (11,-20) + [(11,22),(33,44)] | [(NaN,1),(NaN,90)] | + [(-10,2),(-10,3)] | [(1,2),(3,4)] | (1,2) + [(-10,2),(-10,3)] | [(0,0),(6,6)] | (0,0) + [(-10,2),(-10,3)] | [(10,-10),(-3,-4)] | (-3,-4) + [(-10,2),(-10,3)] | [(-1000000,200),(300000,-40)] | (-9.99771326872,15.3864611163) + [(-10,2),(-10,3)] | [(11,22),(33,44)] | (11,22) + [(-10,2),(-10,3)] | [(-10,2),(-10,3)] | + [(-10,2),(-10,3)] | [(0,-20),(30,-20)] | (0,-20) + [(-10,2),(-10,3)] | [(NaN,1),(NaN,90)] | + [(0,-20),(30,-20)] | [(1,2),(3,4)] | (1,2) + [(0,-20),(30,-20)] | [(0,0),(6,6)] | (0,0) + [(0,-20),(30,-20)] | [(10,-10),(-3,-4)] | (10,-10) + [(0,-20),(30,-20)] | [(-1000000,200),(300000,-40)] | (30.0065315217,15.3790757173) + [(0,-20),(30,-20)] | [(11,22),(33,44)] | (11,22) + [(0,-20),(30,-20)] | [(-10,2),(-10,3)] | (-10,2) + [(0,-20),(30,-20)] | [(0,-20),(30,-20)] | + [(0,-20),(30,-20)] | [(NaN,1),(NaN,90)] | + [(NaN,1),(NaN,90)] | [(1,2),(3,4)] | + [(NaN,1),(NaN,90)] | [(0,0),(6,6)] | + [(NaN,1),(NaN,90)] | [(10,-10),(-3,-4)] | + [(NaN,1),(NaN,90)] | [(-1000000,200),(300000,-40)] | + [(NaN,1),(NaN,90)] | [(11,22),(33,44)] | + [(NaN,1),(NaN,90)] | [(-10,2),(-10,3)] | + [(NaN,1),(NaN,90)] | [(0,-20),(30,-20)] | + [(NaN,1),(NaN,90)] | [(NaN,1),(NaN,90)] | +(64 rows) + +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LSEG_TBL l, BOX_TBL b; + s | f1 | ?column? +-------------------------------+---------------------+------------- + [(1,2),(3,4)] | (2,2),(0,0) | (1,2) + [(1,2),(3,4)] | (3,3),(1,1) | (1.5,2.5) + [(1,2),(3,4)] | (-2,2),(-8,-10) | (-2,2) + [(1,2),(3,4)] | (2.5,3.5),(2.5,2.5) | (2.25,3.25) + [(1,2),(3,4)] | (3,3),(3,3) | (3,3) + [(0,0),(6,6)] | (2,2),(0,0) | (1,1) + [(0,0),(6,6)] | (3,3),(1,1) | (2,2) + [(0,0),(6,6)] | (-2,2),(-8,-10) | (-2,0) + [(0,0),(6,6)] | (2.5,3.5),(2.5,2.5) | (2.75,2.75) + [(0,0),(6,6)] | (3,3),(3,3) | (3,3) + [(10,-10),(-3,-4)] | (2,2),(0,0) | (0,0) + [(10,-10),(-3,-4)] | (3,3),(1,1) | (1,1) + [(10,-10),(-3,-4)] | (-2,2),(-8,-10) | (-3,-4) + [(10,-10),(-3,-4)] | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + [(10,-10),(-3,-4)] | (3,3),(3,3) | (3,3) + [(-1000000,200),(300000,-40)] | (2,2),(0,0) | (2,2) + [(-1000000,200),(300000,-40)] | (3,3),(1,1) | (3,3) + [(-1000000,200),(300000,-40)] | (-2,2),(-8,-10) | (-2,2) + [(-1000000,200),(300000,-40)] | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + [(-1000000,200),(300000,-40)] | (3,3),(3,3) | (3,3) + [(11,22),(33,44)] | (2,2),(0,0) | (2,2) + [(11,22),(33,44)] | (3,3),(1,1) | (3,3) + [(11,22),(33,44)] | (-2,2),(-8,-10) | (-2,2) + [(11,22),(33,44)] | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + [(11,22),(33,44)] | (3,3),(3,3) | (3,3) + [(-10,2),(-10,3)] | (2,2),(0,0) | (0,2) + [(-10,2),(-10,3)] | (3,3),(1,1) | (1,2) + [(-10,2),(-10,3)] | (-2,2),(-8,-10) | (-8,2) + [(-10,2),(-10,3)] | (2.5,3.5),(2.5,2.5) | (2.5,3) + [(-10,2),(-10,3)] | (3,3),(3,3) | (3,3) + [(0,-20),(30,-20)] | (2,2),(0,0) | (0,0) + [(0,-20),(30,-20)] | (3,3),(1,1) | (1,1) + [(0,-20),(30,-20)] | (-2,2),(-8,-10) | (-2,-10) + [(0,-20),(30,-20)] | (2.5,3.5),(2.5,2.5) | (2.5,2.5) + [(0,-20),(30,-20)] | (3,3),(3,3) | (3,3) + [(NaN,1),(NaN,90)] | (2,2),(0,0) | + [(NaN,1),(NaN,90)] | (3,3),(1,1) | + [(NaN,1),(NaN,90)] | (-2,2),(-8,-10) | + [(NaN,1),(NaN,90)] | (2.5,3.5),(2.5,2.5) | + [(NaN,1),(NaN,90)] | (3,3),(3,3) | +(40 rows) + +-- On line +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s <@ l1.s; + s | s +-------------------------------+--------------------------------------- + [(0,0),(6,6)] | {1,-1,0} + [(-1000000,200),(300000,-40)] | {-0.000184615384615,-1,15.3846153846} +(2 rows) + +-- On box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s <@ b.f1; + s | f1 +---+---- +(0 rows) -- -- Boxes @@ -157,138 +2303,176 @@ SELECT '' as six, box(f1) AS box FROM CIRCLE_TBL; | (3.12132034356,4.12132034356),(-1.12132034356,-0.12132034356) | (107.071067812,207.071067812),(92.9289321881,192.928932188) | (181.317279836,82.3172798365),(18.6827201635,-80.3172798365) -(6 rows) + | (3,5),(3,5) + | (NaN,NaN),(NaN,NaN) +(8 rows) -- translation SELECT '' AS twentyfour, b.f1 + p.f1 AS translation FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+------------------------- + twentyfour | translation +------------+------------------------------------- | (2,2),(0,0) | (3,3),(1,1) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | (-8,2),(-10,0) | (-7,3),(-9,1) + | (-12,2),(-18,-10) | (-7.5,3.5),(-7.5,2.5) | (-7,3),(-7,3) | (-1,6),(-3,4) | (0,7),(-2,5) + | (-5,6),(-11,-6) | (-0.5,7.5),(-0.5,6.5) | (0,7),(0,7) | (7.1,36.5),(5.1,34.5) | (8.1,37.5),(6.1,35.5) + | (3.1,36.5),(-2.9,24.5) | (7.6,38),(7.6,37) | (8.1,37.5),(8.1,37.5) | (-3,-10),(-5,-12) | (-2,-9),(-4,-11) + | (-7,-10),(-13,-22) | (-2.5,-8.5),(-2.5,-9.5) | (-2,-9),(-2,-9) + | (2,2),(1e-300,-1e-300) + | (3,3),(1,1) + | (-2,2),(-8,-10) + | (2.5,3.5),(2.5,2.5) + | (3,3),(3,3) + | (1e+300,Infinity),(1e+300,Infinity) + | (1e+300,Infinity),(1e+300,Infinity) + | (1e+300,Infinity),(1e+300,Infinity) + | (1e+300,Infinity),(1e+300,Infinity) + | (1e+300,Infinity),(1e+300,Infinity) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) | (12,12),(10,10) | (13,13),(11,11) + | (8,12),(2,0) | (12.5,13.5),(12.5,12.5) | (13,13),(13,13) -(24 rows) +(45 rows) SELECT '' AS twentyfour, b.f1 - p.f1 AS translation FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+--------------------------- + twentyfour | translation +------------+----------------------------------------- | (2,2),(0,0) | (3,3),(1,1) + | (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | (12,2),(10,0) | (13,3),(11,1) + | (8,2),(2,-10) | (12.5,3.5),(12.5,2.5) | (13,3),(13,3) | (5,-2),(3,-4) | (6,-1),(4,-3) + | (1,-2),(-5,-14) | (5.5,-0.5),(5.5,-1.5) | (6,-1),(6,-1) | (-3.1,-32.5),(-5.1,-34.5) | (-2.1,-31.5),(-4.1,-33.5) + | (-7.1,-32.5),(-13.1,-44.5) | (-2.6,-31),(-2.6,-32) | (-2.1,-31.5),(-2.1,-31.5) | (7,14),(5,12) | (8,15),(6,13) + | (3,14),(-3,2) | (7.5,15.5),(7.5,14.5) | (8,15),(8,15) + | (2,2),(-1e-300,1e-300) + | (3,3),(1,1) + | (-2,2),(-8,-10) + | (2.5,3.5),(2.5,2.5) + | (3,3),(3,3) + | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) + | (NaN,NaN),(NaN,NaN) | (-8,-8),(-10,-10) | (-7,-7),(-9,-9) + | (-12,-8),(-18,-20) | (-7.5,-6.5),(-7.5,-7.5) | (-7,-7),(-7,-7) -(24 rows) +(45 rows) --- scaling and rotation -SELECT '' AS twentyfour, b.f1 * p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | rotation -------------+----------------------------- - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (-0,0),(-20,-20) - | (-10,-10),(-30,-30) - | (-25,-25),(-25,-35) - | (-30,-30),(-30,-30) - | (-0,2),(-14,0) - | (-7,3),(-21,1) - | (-17.5,2.5),(-21.5,-0.5) - | (-21,3),(-21,3) - | (0,79.2),(-58.8,0) - | (-29.4,118.8),(-88.2,39.6) - | (-73.5,104.1),(-108,99) - | (-88.2,118.8),(-88.2,118.8) - | (14,-0),(0,-34) - | (21,-17),(7,-51) - | (29.5,-42.5),(17.5,-47.5) - | (21,-51),(21,-51) - | (0,40),(0,0) - | (0,60),(0,20) - | (0,60),(-10,50) - | (0,60),(0,60) -(24 rows) - -SELECT '' AS twenty, b.f1 / p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p - WHERE (p.f1 <-> point '(0,0)') >= 1; - twenty | rotation ---------+---------------------------------------------------------------------- - | (0,-0),(-0.2,-0.2) - | (0.08,-0),(0,-0.56) - | (0.0651176557644,0),(0,-0.0483449262493) - | (-0,0.0828402366864),(-0.201183431953,0) - | (0.2,0),(0,0) - | (-0.1,-0.1),(-0.3,-0.3) - | (0.12,-0.28),(0.04,-0.84) - | (0.0976764836466,-0.0241724631247),(0.0325588278822,-0.072517389374) - | (-0.100591715976,0.12426035503),(-0.301775147929,0.0414201183432) - | (0.3,0),(0.1,0) - | (-0.25,-0.25),(-0.25,-0.35) - | (0.26,-0.7),(0.1,-0.82) - | (0.109762715209,-0.0562379754329),(0.0813970697055,-0.0604311578117) - | (-0.251479289941,0.103550295858),(-0.322485207101,0.0739644970414) - | (0.3,0.05),(0.25,0) - | (-0.3,-0.3),(-0.3,-0.3) - | (0.12,-0.84),(0.12,-0.84) - | (0.0976764836466,-0.072517389374),(0.0976764836466,-0.072517389374) - | (-0.301775147929,0.12426035503),(-0.301775147929,0.12426035503) - | (0.3,0),(0.3,0) -(20 rows) +-- Multiply with point +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +---------------------+------------+----------------------------- + (2,2),(0,0) | (5.1,34.5) | (0,79.2),(-58.8,0) + (2,2),(0,0) | (10,10) | (0,40),(0,0) + (3,3),(1,1) | (5.1,34.5) | (-29.4,118.8),(-88.2,39.6) + (3,3),(1,1) | (10,10) | (0,60),(0,20) + (-2,2),(-8,-10) | (5.1,34.5) | (304.2,-58.8),(-79.2,-327) + (-2,2),(-8,-10) | (10,10) | (20,0),(-40,-180) + (2.5,3.5),(2.5,2.5) | (5.1,34.5) | (-73.5,104.1),(-108,99) + (2.5,3.5),(2.5,2.5) | (10,10) | (0,60),(-10,50) + (3,3),(3,3) | (5.1,34.5) | (-88.2,118.8),(-88.2,118.8) + (3,3),(3,3) | (10,10) | (0,60),(0,60) +(10 rows) + +-- Overflow error +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000; + f1 | f1 | ?column? +---------------------+-------------------+-------------------------------------------- + (2,2),(0,0) | (1e+300,Infinity) | (NaN,NaN),(-Infinity,Infinity) + (2,2),(0,0) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) + (3,3),(1,1) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (3,3),(1,1) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) + (-2,2),(-8,-10) | (1e+300,Infinity) | (Infinity,-Infinity),(-Infinity,-Infinity) + (-2,2),(-8,-10) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) + (2.5,3.5),(2.5,2.5) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (2.5,3.5),(2.5,2.5) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) + (3,3),(3,3) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (3,3),(3,3) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) +(10 rows) + +-- Divide by point +SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +---------------------+------------+---------------------------------------------------------------------- + (2,2),(0,0) | (5.1,34.5) | (0.0651176557644,0),(0,-0.0483449262493) + (2,2),(0,0) | (10,10) | (0.2,0),(0,0) + (3,3),(1,1) | (5.1,34.5) | (0.0976764836466,-0.0241724631247),(0.0325588278822,-0.072517389374) + (3,3),(1,1) | (10,10) | (0.3,0),(0.1,0) + (-2,2),(-8,-10) | (5.1,34.5) | (0.0483449262493,0.18499334024),(-0.317201914064,0.0651176557644) + (-2,2),(-8,-10) | (10,10) | (0,0.2),(-0.9,-0.1) + (2.5,3.5),(2.5,2.5) | (5.1,34.5) | (0.109762715209,-0.0562379754329),(0.0813970697055,-0.0604311578117) + (2.5,3.5),(2.5,2.5) | (10,10) | (0.3,0.05),(0.25,0) + (3,3),(3,3) | (5.1,34.5) | (0.0976764836466,-0.072517389374),(0.0976764836466,-0.072517389374) + (3,3),(3,3) | (10,10) | (0.3,0),(0.3,0) +(10 rows) +-- To box SELECT f1::box FROM POINT_TBL; - f1 ------------------------ + f1 +------------------------------------- (0,0),(0,0) (-10,0),(-10,0) (-3,4),(-3,4) (5.1,34.5),(5.1,34.5) (-5,-12),(-5,-12) + (1e-300,-1e-300),(1e-300,-1e-300) + (1e+300,Infinity),(1e+300,Infinity) + (NaN,NaN),(NaN,NaN) (10,10),(10,10) -(6 rows) +(9 rows) SELECT bound_box(a.f1, b.f1) FROM BOX_TBL a, BOX_TBL b; @@ -296,76 +2480,935 @@ SELECT bound_box(a.f1, b.f1) --------------------- (2,2),(0,0) (3,3),(0,0) + (2,2),(-8,-10) (2.5,3.5),(0,0) (3,3),(0,0) (3,3),(0,0) (3,3),(1,1) + (3,3),(-8,-10) (3,3.5),(1,1) (3,3),(1,1) + (2,2),(-8,-10) + (3,3),(-8,-10) + (-2,2),(-8,-10) + (2.5,3.5),(-8,-10) + (3,3),(-8,-10) (2.5,3.5),(0,0) (3,3.5),(1,1) + (2.5,3.5),(-8,-10) (2.5,3.5),(2.5,2.5) (3,3.5),(2.5,2.5) (3,3),(0,0) (3,3),(1,1) + (3,3),(-8,-10) (3,3.5),(2.5,2.5) (3,3),(3,3) -(16 rows) +(25 rows) + +-- Below box +SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + f1 | f1 | ?column? +---------------------+---------------------+---------- + (2,2),(0,0) | (2,2),(0,0) | f + (2,2),(0,0) | (3,3),(1,1) | f + (2,2),(0,0) | (-2,2),(-8,-10) | f + (2,2),(0,0) | (2.5,3.5),(2.5,2.5) | t + (2,2),(0,0) | (3,3),(3,3) | t + (3,3),(1,1) | (2,2),(0,0) | f + (3,3),(1,1) | (3,3),(1,1) | f + (3,3),(1,1) | (-2,2),(-8,-10) | f + (3,3),(1,1) | (2.5,3.5),(2.5,2.5) | f + (3,3),(1,1) | (3,3),(3,3) | t + (-2,2),(-8,-10) | (2,2),(0,0) | f + (-2,2),(-8,-10) | (3,3),(1,1) | f + (-2,2),(-8,-10) | (-2,2),(-8,-10) | f + (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | t + (-2,2),(-8,-10) | (3,3),(3,3) | t + (2.5,3.5),(2.5,2.5) | (2,2),(0,0) | f + (2.5,3.5),(2.5,2.5) | (3,3),(1,1) | f + (2.5,3.5),(2.5,2.5) | (-2,2),(-8,-10) | f + (2.5,3.5),(2.5,2.5) | (2.5,3.5),(2.5,2.5) | f + (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | f + (3,3),(3,3) | (2,2),(0,0) | f + (3,3),(3,3) | (3,3),(1,1) | f + (3,3),(3,3) | (-2,2),(-8,-10) | f + (3,3),(3,3) | (2.5,3.5),(2.5,2.5) | f + (3,3),(3,3) | (3,3),(3,3) | t +(25 rows) + +-- Above box +SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + f1 | f1 | ?column? +---------------------+---------------------+---------- + (2,2),(0,0) | (2,2),(0,0) | f + (2,2),(0,0) | (3,3),(1,1) | f + (2,2),(0,0) | (-2,2),(-8,-10) | f + (2,2),(0,0) | (2.5,3.5),(2.5,2.5) | f + (2,2),(0,0) | (3,3),(3,3) | f + (3,3),(1,1) | (2,2),(0,0) | f + (3,3),(1,1) | (3,3),(1,1) | f + (3,3),(1,1) | (-2,2),(-8,-10) | f + (3,3),(1,1) | (2.5,3.5),(2.5,2.5) | f + (3,3),(1,1) | (3,3),(3,3) | f + (-2,2),(-8,-10) | (2,2),(0,0) | f + (-2,2),(-8,-10) | (3,3),(1,1) | f + (-2,2),(-8,-10) | (-2,2),(-8,-10) | f + (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | f + (-2,2),(-8,-10) | (3,3),(3,3) | f + (2.5,3.5),(2.5,2.5) | (2,2),(0,0) | t + (2.5,3.5),(2.5,2.5) | (3,3),(1,1) | f + (2.5,3.5),(2.5,2.5) | (-2,2),(-8,-10) | t + (2.5,3.5),(2.5,2.5) | (2.5,3.5),(2.5,2.5) | f + (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | f + (3,3),(3,3) | (2,2),(0,0) | t + (3,3),(3,3) | (3,3),(1,1) | t + (3,3),(3,3) | (-2,2),(-8,-10) | t + (3,3),(3,3) | (2.5,3.5),(2.5,2.5) | f + (3,3),(3,3) | (3,3),(3,3) | t +(25 rows) + +-- Intersection point with box +SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + f1 | f1 | ?column? +---------------------+---------------------+--------------------- + (2,2),(0,0) | (2,2),(0,0) | (2,2),(0,0) + (2,2),(0,0) | (3,3),(1,1) | (2,2),(1,1) + (2,2),(0,0) | (-2,2),(-8,-10) | + (2,2),(0,0) | (2.5,3.5),(2.5,2.5) | + (2,2),(0,0) | (3,3),(3,3) | + (3,3),(1,1) | (2,2),(0,0) | (2,2),(1,1) + (3,3),(1,1) | (3,3),(1,1) | (3,3),(1,1) + (3,3),(1,1) | (-2,2),(-8,-10) | + (3,3),(1,1) | (2.5,3.5),(2.5,2.5) | (2.5,3),(2.5,2.5) + (3,3),(1,1) | (3,3),(3,3) | (3,3),(3,3) + (-2,2),(-8,-10) | (2,2),(0,0) | + (-2,2),(-8,-10) | (3,3),(1,1) | + (-2,2),(-8,-10) | (-2,2),(-8,-10) | (-2,2),(-8,-10) + (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | + (-2,2),(-8,-10) | (3,3),(3,3) | + (2.5,3.5),(2.5,2.5) | (2,2),(0,0) | + (2.5,3.5),(2.5,2.5) | (3,3),(1,1) | (2.5,3),(2.5,2.5) + (2.5,3.5),(2.5,2.5) | (-2,2),(-8,-10) | + (2.5,3.5),(2.5,2.5) | (2.5,3.5),(2.5,2.5) | (2.5,3.5),(2.5,2.5) + (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | + (3,3),(3,3) | (2,2),(0,0) | + (3,3),(3,3) | (3,3),(1,1) | (3,3),(3,3) + (3,3),(3,3) | (-2,2),(-8,-10) | + (3,3),(3,3) | (2.5,3.5),(2.5,2.5) | + (3,3),(3,3) | (3,3),(3,3) | (3,3),(3,3) +(25 rows) + +-- Diagonal +SELECT f1, diagonal(f1) FROM BOX_TBL; + f1 | diagonal +---------------------+----------------------- + (2,2),(0,0) | [(2,2),(0,0)] + (3,3),(1,1) | [(3,3),(1,1)] + (-2,2),(-8,-10) | [(-2,2),(-8,-10)] + (2.5,3.5),(2.5,2.5) | [(2.5,3.5),(2.5,2.5)] + (3,3),(3,3) | [(3,3),(3,3)] +(5 rows) + +-- Distance to box +SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + f1 | f1 | ?column? +---------------------+---------------------+--------------- + (2,2),(0,0) | (2,2),(0,0) | 0 + (2,2),(0,0) | (3,3),(1,1) | 1.41421356237 + (2,2),(0,0) | (-2,2),(-8,-10) | 7.81024967591 + (2,2),(0,0) | (2.5,3.5),(2.5,2.5) | 2.5 + (2,2),(0,0) | (3,3),(3,3) | 2.82842712475 + (3,3),(1,1) | (2,2),(0,0) | 1.41421356237 + (3,3),(1,1) | (3,3),(1,1) | 0 + (3,3),(1,1) | (-2,2),(-8,-10) | 9.21954445729 + (3,3),(1,1) | (2.5,3.5),(2.5,2.5) | 1.11803398875 + (3,3),(1,1) | (3,3),(3,3) | 1.41421356237 + (-2,2),(-8,-10) | (2,2),(0,0) | 7.81024967591 + (-2,2),(-8,-10) | (3,3),(1,1) | 9.21954445729 + (-2,2),(-8,-10) | (-2,2),(-8,-10) | 0 + (-2,2),(-8,-10) | (2.5,3.5),(2.5,2.5) | 10.2591422643 + (-2,2),(-8,-10) | (3,3),(3,3) | 10.6301458127 + (2.5,3.5),(2.5,2.5) | (2,2),(0,0) | 2.5 + (2.5,3.5),(2.5,2.5) | (3,3),(1,1) | 1.11803398875 + (2.5,3.5),(2.5,2.5) | (-2,2),(-8,-10) | 10.2591422643 + (2.5,3.5),(2.5,2.5) | (2.5,3.5),(2.5,2.5) | 0 + (2.5,3.5),(2.5,2.5) | (3,3),(3,3) | 0.5 + (3,3),(3,3) | (2,2),(0,0) | 2.82842712475 + (3,3),(3,3) | (3,3),(1,1) | 1.41421356237 + (3,3),(3,3) | (-2,2),(-8,-10) | 10.6301458127 + (3,3),(3,3) | (2.5,3.5),(2.5,2.5) | 0.5 + (3,3),(3,3) | (3,3),(3,3) | 0 +(25 rows) -- -- Paths -- -SELECT '' AS eight, npoints(f1) AS npoints, f1 AS path FROM PATH_TBL; - eight | npoints | path --------+---------+--------------------------- - | 2 | [(1,2),(3,4)] - | 2 | ((1,2),(3,4)) - | 4 | [(0,0),(3,0),(4,5),(1,6)] - | 2 | ((1,2),(3,4)) - | 2 | ((1,2),(3,4)) - | 2 | [(1,2),(3,4)] - | 2 | [(11,12),(13,14)] - | 2 | ((11,12),(13,14)) -(8 rows) +-- Points +SELECT f1, npoints(f1) FROM PATH_TBL; + f1 | npoints +---------------------------+--------- + [(1,2),(3,4)] | 2 + ((1,2),(3,4)) | 2 + [(0,0),(3,0),(4,5),(1,6)] | 4 + ((1,2),(3,4)) | 2 + ((1,2),(3,4)) | 2 + [(1,2),(3,4)] | 2 + ((10,20)) | 1 + [(11,12),(13,14)] | 2 + ((11,12),(13,14)) | 2 +(9 rows) -SELECT '' AS four, path(f1) FROM POLYGON_TBL; - four | path -------+--------------------- - | ((2,0),(2,4),(0,0)) - | ((3,1),(3,3),(1,0)) - | ((0,0)) - | ((0,1),(0,1)) -(4 rows) +-- Area +SELECT f1, area(f1) FROM PATH_TBL; + f1 | area +---------------------------+------ + [(1,2),(3,4)] | + ((1,2),(3,4)) | 0 + [(0,0),(3,0),(4,5),(1,6)] | + ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | + ((10,20)) | 0 + [(11,12),(13,14)] | + ((11,12),(13,14)) | 0 +(9 rows) --- translation -SELECT '' AS eight, p1.f1 + point '(10,10)' AS dist_add - FROM PATH_TBL p1; - eight | dist_add --------+----------------------------------- - | [(11,12),(13,14)] - | ((11,12),(13,14)) - | [(10,10),(13,10),(14,15),(11,16)] - | ((11,12),(13,14)) - | ((11,12),(13,14)) - | [(11,12),(13,14)] - | [(21,22),(23,24)] - | ((21,22),(23,24)) -(8 rows) +-- Length +SELECT f1, @-@ f1 FROM PATH_TBL; + f1 | ?column? +---------------------------+--------------- + [(1,2),(3,4)] | 2.82842712475 + ((1,2),(3,4)) | 5.65685424949 + [(0,0),(3,0),(4,5),(1,6)] | 11.2612971738 + ((1,2),(3,4)) | 5.65685424949 + ((1,2),(3,4)) | 5.65685424949 + [(1,2),(3,4)] | 2.82842712475 + ((10,20)) | 0 + [(11,12),(13,14)] | 2.82842712475 + ((11,12),(13,14)) | 5.65685424949 +(9 rows) --- scaling and rotation -SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul - FROM PATH_TBL p1; - eight | dist_mul --------+------------------------------ - | [(4,3),(10,5)] - | ((4,3),(10,5)) - | [(0,0),(6,-3),(13,6),(8,11)] - | ((4,3),(10,5)) - | ((4,3),(10,5)) - | [(4,3),(10,5)] - | [(34,13),(40,15)] - | ((34,13),(40,15)) -(8 rows) +-- Center +SELECT f1, @@ f1 FROM PATH_TBL; +ERROR: function "path_center" not implemented +-- To polygon +SELECT f1, f1::polygon FROM PATH_TBL WHERE isclosed(f1); + f1 | f1 +-------------------+------------------- + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((10,20)) | ((10,20)) + ((11,12),(13,14)) | ((11,12),(13,14)) +(5 rows) + +-- Open path cannot be converted to polygon error +SELECT f1, f1::polygon FROM PATH_TBL WHERE isopen(f1); +ERROR: open path cannot be converted to polygon +-- Has points less than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 < p2.f1; + f1 | f1 +-------------------+--------------------------- + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] + ((10,20)) | [(1,2),(3,4)] + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | [(0,0),(3,0),(4,5),(1,6)] + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | [(1,2),(3,4)] + ((10,20)) | [(11,12),(13,14)] + ((10,20)) | ((11,12),(13,14)) + [(11,12),(13,14)] | [(0,0),(3,0),(4,5),(1,6)] + ((11,12),(13,14)) | [(0,0),(3,0),(4,5),(1,6)] +(15 rows) + +-- Has points less than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 <= p2.f1; + f1 | f1 +---------------------------+--------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((10,20)) | [(1,2),(3,4)] + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | [(0,0),(3,0),(4,5),(1,6)] + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | ((1,2),(3,4)) + ((10,20)) | [(1,2),(3,4)] + ((10,20)) | ((10,20)) + ((10,20)) | [(11,12),(13,14)] + ((10,20)) | ((11,12),(13,14)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | [(0,0),(3,0),(4,5),(1,6)] + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | [(11,12),(13,14)] + [(11,12),(13,14)] | ((11,12),(13,14)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | [(0,0),(3,0),(4,5),(1,6)] + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | [(11,12),(13,14)] + ((11,12),(13,14)) | ((11,12),(13,14)) +(66 rows) + +-- Has points equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 = p2.f1; + f1 | f1 +---------------------------+--------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((10,20)) | ((10,20)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | [(11,12),(13,14)] + [(11,12),(13,14)] | ((11,12),(13,14)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | [(11,12),(13,14)] + ((11,12),(13,14)) | ((11,12),(13,14)) +(51 rows) + +-- Has points greater than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 >= p2.f1; + f1 | f1 +---------------------------+--------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((10,20)) + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((10,20)) + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6)] + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((10,20)) + [(0,0),(3,0),(4,5),(1,6)] | [(11,12),(13,14)] + [(0,0),(3,0),(4,5),(1,6)] | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((10,20)) + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | ((1,2),(3,4)) + ((1,2),(3,4)) | [(1,2),(3,4)] + ((1,2),(3,4)) | ((10,20)) + ((1,2),(3,4)) | [(11,12),(13,14)] + ((1,2),(3,4)) | ((11,12),(13,14)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | ((1,2),(3,4)) + [(1,2),(3,4)] | [(1,2),(3,4)] + [(1,2),(3,4)] | ((10,20)) + [(1,2),(3,4)] | [(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) + ((10,20)) | ((10,20)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | ((1,2),(3,4)) + [(11,12),(13,14)] | [(1,2),(3,4)] + [(11,12),(13,14)] | ((10,20)) + [(11,12),(13,14)] | [(11,12),(13,14)] + [(11,12),(13,14)] | ((11,12),(13,14)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | ((1,2),(3,4)) + ((11,12),(13,14)) | [(1,2),(3,4)] + ((11,12),(13,14)) | ((10,20)) + ((11,12),(13,14)) | [(11,12),(13,14)] + ((11,12),(13,14)) | ((11,12),(13,14)) +(66 rows) + +-- Has points greater than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 > p2.f1; + f1 | f1 +---------------------------+------------------- + [(1,2),(3,4)] | ((10,20)) + ((1,2),(3,4)) | ((10,20)) + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((10,20)) + [(0,0),(3,0),(4,5),(1,6)] | [(11,12),(13,14)] + [(0,0),(3,0),(4,5),(1,6)] | ((11,12),(13,14)) + ((1,2),(3,4)) | ((10,20)) + ((1,2),(3,4)) | ((10,20)) + [(1,2),(3,4)] | ((10,20)) + [(11,12),(13,14)] | ((10,20)) + ((11,12),(13,14)) | ((10,20)) +(15 rows) + +-- Add path +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM PATH_TBL p1, PATH_TBL p2; + f1 | f1 | ?column? +---------------------------+---------------------------+--------------------------------------------------- + [(1,2),(3,4)] | [(1,2),(3,4)] | [(1,2),(3,4),(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4),(0,0),(3,0),(4,5),(1,6)] + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | [(1,2),(3,4)] | [(1,2),(3,4),(1,2),(3,4)] + [(1,2),(3,4)] | ((10,20)) | + [(1,2),(3,4)] | [(11,12),(13,14)] | [(1,2),(3,4),(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((10,20)) | + ((1,2),(3,4)) | [(11,12),(13,14)] | + ((1,2),(3,4)) | ((11,12),(13,14)) | + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6),(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | + [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6),(0,0),(3,0),(4,5),(1,6)] + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6),(1,2),(3,4)] + [(0,0),(3,0),(4,5),(1,6)] | ((10,20)) | + [(0,0),(3,0),(4,5),(1,6)] | [(11,12),(13,14)] | [(0,0),(3,0),(4,5),(1,6),(11,12),(13,14)] + [(0,0),(3,0),(4,5),(1,6)] | ((11,12),(13,14)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((10,20)) | + ((1,2),(3,4)) | [(11,12),(13,14)] | + ((1,2),(3,4)) | ((11,12),(13,14)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | ((1,2),(3,4)) | + ((1,2),(3,4)) | [(1,2),(3,4)] | + ((1,2),(3,4)) | ((10,20)) | + ((1,2),(3,4)) | [(11,12),(13,14)] | + ((1,2),(3,4)) | ((11,12),(13,14)) | + [(1,2),(3,4)] | [(1,2),(3,4)] | [(1,2),(3,4),(1,2),(3,4)] + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4),(0,0),(3,0),(4,5),(1,6)] + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | ((1,2),(3,4)) | + [(1,2),(3,4)] | [(1,2),(3,4)] | [(1,2),(3,4),(1,2),(3,4)] + [(1,2),(3,4)] | ((10,20)) | + [(1,2),(3,4)] | [(11,12),(13,14)] | [(1,2),(3,4),(11,12),(13,14)] + [(1,2),(3,4)] | ((11,12),(13,14)) | + ((10,20)) | [(1,2),(3,4)] | + ((10,20)) | ((1,2),(3,4)) | + ((10,20)) | [(0,0),(3,0),(4,5),(1,6)] | + ((10,20)) | ((1,2),(3,4)) | + ((10,20)) | ((1,2),(3,4)) | + ((10,20)) | [(1,2),(3,4)] | + ((10,20)) | ((10,20)) | + ((10,20)) | [(11,12),(13,14)] | + ((10,20)) | ((11,12),(13,14)) | + [(11,12),(13,14)] | [(1,2),(3,4)] | [(11,12),(13,14),(1,2),(3,4)] + [(11,12),(13,14)] | ((1,2),(3,4)) | + [(11,12),(13,14)] | [(0,0),(3,0),(4,5),(1,6)] | [(11,12),(13,14),(0,0),(3,0),(4,5),(1,6)] + [(11,12),(13,14)] | ((1,2),(3,4)) | + [(11,12),(13,14)] | ((1,2),(3,4)) | + [(11,12),(13,14)] | [(1,2),(3,4)] | [(11,12),(13,14),(1,2),(3,4)] + [(11,12),(13,14)] | ((10,20)) | + [(11,12),(13,14)] | [(11,12),(13,14)] | [(11,12),(13,14),(11,12),(13,14)] + [(11,12),(13,14)] | ((11,12),(13,14)) | + ((11,12),(13,14)) | [(1,2),(3,4)] | + ((11,12),(13,14)) | ((1,2),(3,4)) | + ((11,12),(13,14)) | [(0,0),(3,0),(4,5),(1,6)] | + ((11,12),(13,14)) | ((1,2),(3,4)) | + ((11,12),(13,14)) | ((1,2),(3,4)) | + ((11,12),(13,14)) | [(1,2),(3,4)] | + ((11,12),(13,14)) | ((10,20)) | + ((11,12),(13,14)) | [(11,12),(13,14)] | + ((11,12),(13,14)) | ((11,12),(13,14)) | +(81 rows) + +-- Add point +SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1; + f1 | f1 | ?column? +---------------------------+-------------------+--------------------------------------------------------------------------- + [(1,2),(3,4)] | (0,0) | [(1,2),(3,4)] + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | (0,0) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + [(1,2),(3,4)] | (0,0) | [(1,2),(3,4)] + ((10,20)) | (0,0) | ((10,20)) + [(11,12),(13,14)] | (0,0) | [(11,12),(13,14)] + ((11,12),(13,14)) | (0,0) | ((11,12),(13,14)) + [(1,2),(3,4)] | (-10,0) | [(-9,2),(-7,4)] + ((1,2),(3,4)) | (-10,0) | ((-9,2),(-7,4)) + [(0,0),(3,0),(4,5),(1,6)] | (-10,0) | [(-10,0),(-7,0),(-6,5),(-9,6)] + ((1,2),(3,4)) | (-10,0) | ((-9,2),(-7,4)) + ((1,2),(3,4)) | (-10,0) | ((-9,2),(-7,4)) + [(1,2),(3,4)] | (-10,0) | [(-9,2),(-7,4)] + ((10,20)) | (-10,0) | ((0,20)) + [(11,12),(13,14)] | (-10,0) | [(1,12),(3,14)] + ((11,12),(13,14)) | (-10,0) | ((1,12),(3,14)) + [(1,2),(3,4)] | (-3,4) | [(-2,6),(0,8)] + ((1,2),(3,4)) | (-3,4) | ((-2,6),(0,8)) + [(0,0),(3,0),(4,5),(1,6)] | (-3,4) | [(-3,4),(0,4),(1,9),(-2,10)] + ((1,2),(3,4)) | (-3,4) | ((-2,6),(0,8)) + ((1,2),(3,4)) | (-3,4) | ((-2,6),(0,8)) + [(1,2),(3,4)] | (-3,4) | [(-2,6),(0,8)] + ((10,20)) | (-3,4) | ((7,24)) + [(11,12),(13,14)] | (-3,4) | [(8,16),(10,18)] + ((11,12),(13,14)) | (-3,4) | ((8,16),(10,18)) + [(1,2),(3,4)] | (5.1,34.5) | [(6.1,36.5),(8.1,38.5)] + ((1,2),(3,4)) | (5.1,34.5) | ((6.1,36.5),(8.1,38.5)) + [(0,0),(3,0),(4,5),(1,6)] | (5.1,34.5) | [(5.1,34.5),(8.1,34.5),(9.1,39.5),(6.1,40.5)] + ((1,2),(3,4)) | (5.1,34.5) | ((6.1,36.5),(8.1,38.5)) + ((1,2),(3,4)) | (5.1,34.5) | ((6.1,36.5),(8.1,38.5)) + [(1,2),(3,4)] | (5.1,34.5) | [(6.1,36.5),(8.1,38.5)] + ((10,20)) | (5.1,34.5) | ((15.1,54.5)) + [(11,12),(13,14)] | (5.1,34.5) | [(16.1,46.5),(18.1,48.5)] + ((11,12),(13,14)) | (5.1,34.5) | ((16.1,46.5),(18.1,48.5)) + [(1,2),(3,4)] | (-5,-12) | [(-4,-10),(-2,-8)] + ((1,2),(3,4)) | (-5,-12) | ((-4,-10),(-2,-8)) + [(0,0),(3,0),(4,5),(1,6)] | (-5,-12) | [(-5,-12),(-2,-12),(-1,-7),(-4,-6)] + ((1,2),(3,4)) | (-5,-12) | ((-4,-10),(-2,-8)) + ((1,2),(3,4)) | (-5,-12) | ((-4,-10),(-2,-8)) + [(1,2),(3,4)] | (-5,-12) | [(-4,-10),(-2,-8)] + ((10,20)) | (-5,-12) | ((5,8)) + [(11,12),(13,14)] | (-5,-12) | [(6,0),(8,2)] + ((11,12),(13,14)) | (-5,-12) | ((6,0),(8,2)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(1,2),(3,4)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | (1e-300,-1e-300) | [(1e-300,-1e-300),(3,-1e-300),(4,5),(1,6)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(1,2),(3,4)] + ((10,20)) | (1e-300,-1e-300) | ((10,20)) + [(11,12),(13,14)] | (1e-300,-1e-300) | [(11,12),(13,14)] + ((11,12),(13,14)) | (1e-300,-1e-300) | ((11,12),(13,14)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity)) + [(0,0),(3,0),(4,5),(1,6)] | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity),(1e+300,Infinity),(1e+300,Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity)) + ((1,2),(3,4)) | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity)] + ((10,20)) | (1e+300,Infinity) | ((1e+300,Infinity)) + [(11,12),(13,14)] | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity)] + ((11,12),(13,14)) | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((10,20)) | (NaN,NaN) | ((NaN,NaN)) + [(11,12),(13,14)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((11,12),(13,14)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (10,10) | [(11,12),(13,14)] + ((1,2),(3,4)) | (10,10) | ((11,12),(13,14)) + [(0,0),(3,0),(4,5),(1,6)] | (10,10) | [(10,10),(13,10),(14,15),(11,16)] + ((1,2),(3,4)) | (10,10) | ((11,12),(13,14)) + ((1,2),(3,4)) | (10,10) | ((11,12),(13,14)) + [(1,2),(3,4)] | (10,10) | [(11,12),(13,14)] + ((10,20)) | (10,10) | ((20,30)) + [(11,12),(13,14)] | (10,10) | [(21,22),(23,24)] + ((11,12),(13,14)) | (10,10) | ((21,22),(23,24)) +(81 rows) + +-- Subtract point +SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; + f1 | f1 | ?column? +---------------------------+-------------------+----------------------------------------------------------------------------------- + [(1,2),(3,4)] | (0,0) | [(1,2),(3,4)] + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | (0,0) | [(0,0),(3,0),(4,5),(1,6)] + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + ((1,2),(3,4)) | (0,0) | ((1,2),(3,4)) + [(1,2),(3,4)] | (0,0) | [(1,2),(3,4)] + ((10,20)) | (0,0) | ((10,20)) + [(11,12),(13,14)] | (0,0) | [(11,12),(13,14)] + ((11,12),(13,14)) | (0,0) | ((11,12),(13,14)) + [(1,2),(3,4)] | (-10,0) | [(11,2),(13,4)] + ((1,2),(3,4)) | (-10,0) | ((11,2),(13,4)) + [(0,0),(3,0),(4,5),(1,6)] | (-10,0) | [(10,0),(13,0),(14,5),(11,6)] + ((1,2),(3,4)) | (-10,0) | ((11,2),(13,4)) + ((1,2),(3,4)) | (-10,0) | ((11,2),(13,4)) + [(1,2),(3,4)] | (-10,0) | [(11,2),(13,4)] + ((10,20)) | (-10,0) | ((20,20)) + [(11,12),(13,14)] | (-10,0) | [(21,12),(23,14)] + ((11,12),(13,14)) | (-10,0) | ((21,12),(23,14)) + [(1,2),(3,4)] | (-3,4) | [(4,-2),(6,0)] + ((1,2),(3,4)) | (-3,4) | ((4,-2),(6,0)) + [(0,0),(3,0),(4,5),(1,6)] | (-3,4) | [(3,-4),(6,-4),(7,1),(4,2)] + ((1,2),(3,4)) | (-3,4) | ((4,-2),(6,0)) + ((1,2),(3,4)) | (-3,4) | ((4,-2),(6,0)) + [(1,2),(3,4)] | (-3,4) | [(4,-2),(6,0)] + ((10,20)) | (-3,4) | ((13,16)) + [(11,12),(13,14)] | (-3,4) | [(14,8),(16,10)] + ((11,12),(13,14)) | (-3,4) | ((14,8),(16,10)) + [(1,2),(3,4)] | (5.1,34.5) | [(-4.1,-32.5),(-2.1,-30.5)] + ((1,2),(3,4)) | (5.1,34.5) | ((-4.1,-32.5),(-2.1,-30.5)) + [(0,0),(3,0),(4,5),(1,6)] | (5.1,34.5) | [(-5.1,-34.5),(-2.1,-34.5),(-1.1,-29.5),(-4.1,-28.5)] + ((1,2),(3,4)) | (5.1,34.5) | ((-4.1,-32.5),(-2.1,-30.5)) + ((1,2),(3,4)) | (5.1,34.5) | ((-4.1,-32.5),(-2.1,-30.5)) + [(1,2),(3,4)] | (5.1,34.5) | [(-4.1,-32.5),(-2.1,-30.5)] + ((10,20)) | (5.1,34.5) | ((4.9,-14.5)) + [(11,12),(13,14)] | (5.1,34.5) | [(5.9,-22.5),(7.9,-20.5)] + ((11,12),(13,14)) | (5.1,34.5) | ((5.9,-22.5),(7.9,-20.5)) + [(1,2),(3,4)] | (-5,-12) | [(6,14),(8,16)] + ((1,2),(3,4)) | (-5,-12) | ((6,14),(8,16)) + [(0,0),(3,0),(4,5),(1,6)] | (-5,-12) | [(5,12),(8,12),(9,17),(6,18)] + ((1,2),(3,4)) | (-5,-12) | ((6,14),(8,16)) + ((1,2),(3,4)) | (-5,-12) | ((6,14),(8,16)) + [(1,2),(3,4)] | (-5,-12) | [(6,14),(8,16)] + ((10,20)) | (-5,-12) | ((15,32)) + [(11,12),(13,14)] | (-5,-12) | [(16,24),(18,26)] + ((11,12),(13,14)) | (-5,-12) | ((16,24),(18,26)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(1,2),(3,4)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + [(0,0),(3,0),(4,5),(1,6)] | (1e-300,-1e-300) | [(-1e-300,1e-300),(3,1e-300),(4,5),(1,6)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + ((1,2),(3,4)) | (1e-300,-1e-300) | ((1,2),(3,4)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(1,2),(3,4)] + ((10,20)) | (1e-300,-1e-300) | ((10,20)) + [(11,12),(13,14)] | (1e-300,-1e-300) | [(11,12),(13,14)] + ((11,12),(13,14)) | (1e-300,-1e-300) | ((11,12),(13,14)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity)) + [(0,0),(3,0),(4,5),(1,6)] | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity),(-1e+300,-Infinity),(-1e+300,-Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity)) + ((1,2),(3,4)) | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity)] + ((10,20)) | (1e+300,Infinity) | ((-1e+300,-Infinity)) + [(11,12),(13,14)] | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity)] + ((11,12),(13,14)) | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((10,20)) | (NaN,NaN) | ((NaN,NaN)) + [(11,12),(13,14)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((11,12),(13,14)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (10,10) | [(-9,-8),(-7,-6)] + ((1,2),(3,4)) | (10,10) | ((-9,-8),(-7,-6)) + [(0,0),(3,0),(4,5),(1,6)] | (10,10) | [(-10,-10),(-7,-10),(-6,-5),(-9,-4)] + ((1,2),(3,4)) | (10,10) | ((-9,-8),(-7,-6)) + ((1,2),(3,4)) | (10,10) | ((-9,-8),(-7,-6)) + [(1,2),(3,4)] | (10,10) | [(-9,-8),(-7,-6)] + ((10,20)) | (10,10) | ((0,10)) + [(11,12),(13,14)] | (10,10) | [(1,2),(3,4)] + ((11,12),(13,14)) | (10,10) | ((1,2),(3,4)) +(81 rows) + +-- Multiply with point +SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; + f1 | f1 | ?column? +---------------------------+-------------------+---------------------------------------------------------------------- + [(1,2),(3,4)] | (0,0) | [(0,0),(0,0)] + ((1,2),(3,4)) | (0,0) | ((0,0),(0,0)) + [(0,0),(3,0),(4,5),(1,6)] | (0,0) | [(0,0),(0,0),(0,0),(0,0)] + ((1,2),(3,4)) | (0,0) | ((0,0),(0,0)) + ((1,2),(3,4)) | (0,0) | ((0,0),(0,0)) + [(1,2),(3,4)] | (0,0) | [(0,0),(0,0)] + ((10,20)) | (0,0) | ((0,0)) + [(11,12),(13,14)] | (0,0) | [(0,0),(0,0)] + ((11,12),(13,14)) | (0,0) | ((0,0),(0,0)) + [(1,2),(3,4)] | (-10,0) | [(-10,-20),(-30,-40)] + ((1,2),(3,4)) | (-10,0) | ((-10,-20),(-30,-40)) + [(0,0),(3,0),(4,5),(1,6)] | (-10,0) | [(-0,0),(-30,0),(-40,-50),(-10,-60)] + ((1,2),(3,4)) | (-10,0) | ((-10,-20),(-30,-40)) + ((1,2),(3,4)) | (-10,0) | ((-10,-20),(-30,-40)) + [(1,2),(3,4)] | (-10,0) | [(-10,-20),(-30,-40)] + ((10,20)) | (-10,0) | ((-100,-200)) + [(11,12),(13,14)] | (-10,0) | [(-110,-120),(-130,-140)] + ((11,12),(13,14)) | (-10,0) | ((-110,-120),(-130,-140)) + [(1,2),(3,4)] | (-3,4) | [(-11,-2),(-25,0)] + ((1,2),(3,4)) | (-3,4) | ((-11,-2),(-25,0)) + [(0,0),(3,0),(4,5),(1,6)] | (-3,4) | [(-0,0),(-9,12),(-32,1),(-27,-14)] + ((1,2),(3,4)) | (-3,4) | ((-11,-2),(-25,0)) + ((1,2),(3,4)) | (-3,4) | ((-11,-2),(-25,0)) + [(1,2),(3,4)] | (-3,4) | [(-11,-2),(-25,0)] + ((10,20)) | (-3,4) | ((-110,-20)) + [(11,12),(13,14)] | (-3,4) | [(-81,8),(-95,10)] + ((11,12),(13,14)) | (-3,4) | ((-81,8),(-95,10)) + [(1,2),(3,4)] | (5.1,34.5) | [(-63.9,44.7),(-122.7,123.9)] + ((1,2),(3,4)) | (5.1,34.5) | ((-63.9,44.7),(-122.7,123.9)) + [(0,0),(3,0),(4,5),(1,6)] | (5.1,34.5) | [(0,0),(15.3,103.5),(-152.1,163.5),(-201.9,65.1)] + ((1,2),(3,4)) | (5.1,34.5) | ((-63.9,44.7),(-122.7,123.9)) + ((1,2),(3,4)) | (5.1,34.5) | ((-63.9,44.7),(-122.7,123.9)) + [(1,2),(3,4)] | (5.1,34.5) | [(-63.9,44.7),(-122.7,123.9)] + ((10,20)) | (5.1,34.5) | ((-639,447)) + [(11,12),(13,14)] | (5.1,34.5) | [(-357.9,440.7),(-416.7,519.9)] + ((11,12),(13,14)) | (5.1,34.5) | ((-357.9,440.7),(-416.7,519.9)) + [(1,2),(3,4)] | (-5,-12) | [(19,-22),(33,-56)] + ((1,2),(3,4)) | (-5,-12) | ((19,-22),(33,-56)) + [(0,0),(3,0),(4,5),(1,6)] | (-5,-12) | [(0,-0),(-15,-36),(40,-73),(67,-42)] + ((1,2),(3,4)) | (-5,-12) | ((19,-22),(33,-56)) + ((1,2),(3,4)) | (-5,-12) | ((19,-22),(33,-56)) + [(1,2),(3,4)] | (-5,-12) | [(19,-22),(33,-56)] + ((10,20)) | (-5,-12) | ((190,-220)) + [(11,12),(13,14)] | (-5,-12) | [(89,-192),(103,-226)] + ((11,12),(13,14)) | (-5,-12) | ((89,-192),(103,-226)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(3e-300,1e-300),(7e-300,1e-300)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((3e-300,1e-300),(7e-300,1e-300)) + [(0,0),(3,0),(4,5),(1,6)] | (1e-300,-1e-300) | [(0,0),(3e-300,-3e-300),(9e-300,1e-300),(7e-300,5e-300)] + ((1,2),(3,4)) | (1e-300,-1e-300) | ((3e-300,1e-300),(7e-300,1e-300)) + ((1,2),(3,4)) | (1e-300,-1e-300) | ((3e-300,1e-300),(7e-300,1e-300)) + [(1,2),(3,4)] | (1e-300,-1e-300) | [(3e-300,1e-300),(7e-300,1e-300)] + ((10,20)) | (1e-300,-1e-300) | ((3e-299,1e-299)) + [(11,12),(13,14)] | (1e-300,-1e-300) | [(2.3e-299,1e-300),(2.7e-299,1e-300)] + ((11,12),(13,14)) | (1e-300,-1e-300) | ((2.3e-299,1e-300),(2.7e-299,1e-300)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(-Infinity,Infinity),(-Infinity,Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity)) + [(0,0),(3,0),(4,5),(1,6)] | (1e+300,Infinity) | [(NaN,NaN),(NaN,Infinity),(-Infinity,Infinity),(-Infinity,Infinity)] + ((1,2),(3,4)) | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity)) + ((1,2),(3,4)) | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity)) + [(1,2),(3,4)] | (1e+300,Infinity) | [(-Infinity,Infinity),(-Infinity,Infinity)] + ((10,20)) | (1e+300,Infinity) | ((-Infinity,Infinity)) + [(11,12),(13,14)] | (1e+300,Infinity) | [(-Infinity,Infinity),(-Infinity,Infinity)] + ((11,12),(13,14)) | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((10,20)) | (NaN,NaN) | ((NaN,NaN)) + [(11,12),(13,14)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] + ((11,12),(13,14)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) + [(1,2),(3,4)] | (10,10) | [(-10,30),(-10,70)] + ((1,2),(3,4)) | (10,10) | ((-10,30),(-10,70)) + [(0,0),(3,0),(4,5),(1,6)] | (10,10) | [(0,0),(30,30),(-10,90),(-50,70)] + ((1,2),(3,4)) | (10,10) | ((-10,30),(-10,70)) + ((1,2),(3,4)) | (10,10) | ((-10,30),(-10,70)) + [(1,2),(3,4)] | (10,10) | [(-10,30),(-10,70)] + ((10,20)) | (10,10) | ((-100,300)) + [(11,12),(13,14)] | (10,10) | [(-10,230),(-10,270)] + ((11,12),(13,14)) | (10,10) | ((-10,230),(-10,270)) +(81 rows) + +-- Divide by point +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +---------------------------+------------+----------------------------------------------------------------------------------------------------------------- + [(1,2),(3,4)] | (5.1,34.5) | [(0.0609244733856,-0.0199792807459),(0.12604212915,-0.0683242069952)] + [(1,2),(3,4)] | (10,10) | [(0.15,0.05),(0.35,0.05)] + ((1,2),(3,4)) | (5.1,34.5) | ((0.0609244733856,-0.0199792807459),(0.12604212915,-0.0683242069952)) + ((1,2),(3,4)) | (10,10) | ((0.15,0.05),(0.35,0.05)) + [(0,0),(3,0),(4,5),(1,6)] | (5.1,34.5) | [(0,0),(0.0125795471363,-0.0850969365103),(0.158600957032,-0.0924966701199),(0.174387055399,-0.00320655123082)] + [(0,0),(3,0),(4,5),(1,6)] | (10,10) | [(0,0),(0.15,-0.15),(0.45,0.05),(0.35,0.25)] + ((1,2),(3,4)) | (5.1,34.5) | ((0.0609244733856,-0.0199792807459),(0.12604212915,-0.0683242069952)) + ((1,2),(3,4)) | (10,10) | ((0.15,0.05),(0.35,0.05)) + ((1,2),(3,4)) | (5.1,34.5) | ((0.0609244733856,-0.0199792807459),(0.12604212915,-0.0683242069952)) + ((1,2),(3,4)) | (10,10) | ((0.15,0.05),(0.35,0.05)) + [(1,2),(3,4)] | (5.1,34.5) | [(0.0609244733856,-0.0199792807459),(0.12604212915,-0.0683242069952)] + [(1,2),(3,4)] | (10,10) | [(0.15,0.05),(0.35,0.05)] + ((10,20)) | (5.1,34.5) | ((0.609244733856,-0.199792807459)) + ((10,20)) | (10,10) | ((1.5,0.5)) + [(11,12),(13,14)] | (5.1,34.5) | [(0.386512752208,-0.261703911993),(0.451630407972,-0.310048838242)] + [(11,12),(13,14)] | (10,10) | [(1.15,0.05),(1.35,0.05)] + ((11,12),(13,14)) | (5.1,34.5) | ((0.386512752208,-0.261703911993),(0.451630407972,-0.310048838242)) + ((11,12),(13,14)) | (10,10) | ((1.15,0.05),(1.35,0.05)) +(18 rows) + +-- Division by 0 error +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1 ~= '(0,0)'::point; +ERROR: division by zero +-- Distance to path +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM PATH_TBL p1, PATH_TBL p2; + f1 | f1 | ?column? +---------------------------+---------------------------+---------------- + [(1,2),(3,4)] | [(1,2),(3,4)] | 0 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] | 0.784464540553 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | [(1,2),(3,4)] | 0 + [(1,2),(3,4)] | ((10,20)) | 17.4642491966 + [(1,2),(3,4)] | [(11,12),(13,14)] | 11.313708499 + [(1,2),(3,4)] | ((11,12),(13,14)) | 11.313708499 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | 0.784464540553 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((10,20)) | 17.4642491966 + ((1,2),(3,4)) | [(11,12),(13,14)] | 11.313708499 + ((1,2),(3,4)) | ((11,12),(13,14)) | 11.313708499 + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] | 0.784464540553 + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | 0.784464540553 + [(0,0),(3,0),(4,5),(1,6)] | [(0,0),(3,0),(4,5),(1,6)] | 0 + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | 0.784464540553 + [(0,0),(3,0),(4,5),(1,6)] | ((1,2),(3,4)) | 0.784464540553 + [(0,0),(3,0),(4,5),(1,6)] | [(1,2),(3,4)] | 0.784464540553 + [(0,0),(3,0),(4,5),(1,6)] | ((10,20)) | 16.1554944214 + [(0,0),(3,0),(4,5),(1,6)] | [(11,12),(13,14)] | 9.89949493661 + [(0,0),(3,0),(4,5),(1,6)] | ((11,12),(13,14)) | 9.89949493661 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | 0.784464540553 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((10,20)) | 17.4642491966 + ((1,2),(3,4)) | [(11,12),(13,14)] | 11.313708499 + ((1,2),(3,4)) | ((11,12),(13,14)) | 11.313708499 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(0,0),(3,0),(4,5),(1,6)] | 0.784464540553 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | ((1,2),(3,4)) | 0 + ((1,2),(3,4)) | [(1,2),(3,4)] | 0 + ((1,2),(3,4)) | ((10,20)) | 17.4642491966 + ((1,2),(3,4)) | [(11,12),(13,14)] | 11.313708499 + ((1,2),(3,4)) | ((11,12),(13,14)) | 11.313708499 + [(1,2),(3,4)] | [(1,2),(3,4)] | 0 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | [(0,0),(3,0),(4,5),(1,6)] | 0.784464540553 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | ((1,2),(3,4)) | 0 + [(1,2),(3,4)] | [(1,2),(3,4)] | 0 + [(1,2),(3,4)] | ((10,20)) | 17.4642491966 + [(1,2),(3,4)] | [(11,12),(13,14)] | 11.313708499 + [(1,2),(3,4)] | ((11,12),(13,14)) | 11.313708499 + ((10,20)) | [(1,2),(3,4)] | 17.4642491966 + ((10,20)) | ((1,2),(3,4)) | 17.4642491966 + ((10,20)) | [(0,0),(3,0),(4,5),(1,6)] | 16.1554944214 + ((10,20)) | ((1,2),(3,4)) | 17.4642491966 + ((10,20)) | ((1,2),(3,4)) | 17.4642491966 + ((10,20)) | [(1,2),(3,4)] | 17.4642491966 + ((10,20)) | ((10,20)) | 0 + ((10,20)) | [(11,12),(13,14)] | 6.7082039325 + ((10,20)) | ((11,12),(13,14)) | 6.7082039325 + [(11,12),(13,14)] | [(1,2),(3,4)] | 11.313708499 + [(11,12),(13,14)] | ((1,2),(3,4)) | 11.313708499 + [(11,12),(13,14)] | [(0,0),(3,0),(4,5),(1,6)] | 9.89949493661 + [(11,12),(13,14)] | ((1,2),(3,4)) | 11.313708499 + [(11,12),(13,14)] | ((1,2),(3,4)) | 11.313708499 + [(11,12),(13,14)] | [(1,2),(3,4)] | 11.313708499 + [(11,12),(13,14)] | ((10,20)) | 6.7082039325 + [(11,12),(13,14)] | [(11,12),(13,14)] | 0 + [(11,12),(13,14)] | ((11,12),(13,14)) | 0 + ((11,12),(13,14)) | [(1,2),(3,4)] | 11.313708499 + ((11,12),(13,14)) | ((1,2),(3,4)) | 11.313708499 + ((11,12),(13,14)) | [(0,0),(3,0),(4,5),(1,6)] | 9.89949493661 + ((11,12),(13,14)) | ((1,2),(3,4)) | 11.313708499 + ((11,12),(13,14)) | ((1,2),(3,4)) | 11.313708499 + ((11,12),(13,14)) | [(1,2),(3,4)] | 11.313708499 + ((11,12),(13,14)) | ((10,20)) | 6.7082039325 + ((11,12),(13,14)) | [(11,12),(13,14)] | 0 + ((11,12),(13,14)) | ((11,12),(13,14)) | 0 +(81 rows) -- -- Polygons @@ -373,73 +3416,154 @@ SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul -- containment SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contains -------------+------------+---------------------+---------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) + twentyfour | f1 | f1 | contains +------------+-------------------+----------------------------+---------- + | (0,0) | ((2,0),(2,4),(0,0)) | t + | (0,0) | ((3,1),(3,3),(1,0)) | f + | (0,0) | ((1,2),(3,4),(5,6),(7,8)) | f + | (0,0) | ((7,8),(5,6),(3,4),(1,2)) | f + | (0,0) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (0,0) | ((0,0)) | t + | (0,0) | ((0,1),(0,1)) | f + | (-10,0) | ((2,0),(2,4),(0,0)) | f + | (-10,0) | ((3,1),(3,3),(1,0)) | f + | (-10,0) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-10,0) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-10,0) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-10,0) | ((0,0)) | f + | (-10,0) | ((0,1),(0,1)) | f + | (-3,4) | ((2,0),(2,4),(0,0)) | f + | (-3,4) | ((3,1),(3,3),(1,0)) | f + | (-3,4) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-3,4) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-3,4) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-3,4) | ((0,0)) | f + | (-3,4) | ((0,1),(0,1)) | f + | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f + | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f + | (5.1,34.5) | ((1,2),(3,4),(5,6),(7,8)) | f + | (5.1,34.5) | ((7,8),(5,6),(3,4),(1,2)) | f + | (5.1,34.5) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (5.1,34.5) | ((0,0)) | f + | (5.1,34.5) | ((0,1),(0,1)) | f + | (-5,-12) | ((2,0),(2,4),(0,0)) | f + | (-5,-12) | ((3,1),(3,3),(1,0)) | f + | (-5,-12) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-5,-12) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-5,-12) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-5,-12) | ((0,0)) | f + | (-5,-12) | ((0,1),(0,1)) | f + | (1e-300,-1e-300) | ((2,0),(2,4),(0,0)) | t + | (1e-300,-1e-300) | ((3,1),(3,3),(1,0)) | f + | (1e-300,-1e-300) | ((1,2),(3,4),(5,6),(7,8)) | f + | (1e-300,-1e-300) | ((7,8),(5,6),(3,4),(1,2)) | f + | (1e-300,-1e-300) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (1e-300,-1e-300) | ((0,0)) | t + | (1e-300,-1e-300) | ((0,1),(0,1)) | f + | (1e+300,Infinity) | ((2,0),(2,4),(0,0)) | f + | (1e+300,Infinity) | ((3,1),(3,3),(1,0)) | f + | (1e+300,Infinity) | ((1,2),(3,4),(5,6),(7,8)) | f + | (1e+300,Infinity) | ((7,8),(5,6),(3,4),(1,2)) | f + | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (1e+300,Infinity) | ((0,0)) | f + | (1e+300,Infinity) | ((0,1),(0,1)) | f + | (NaN,NaN) | ((2,0),(2,4),(0,0)) | t + | (NaN,NaN) | ((3,1),(3,3),(1,0)) | t + | (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | t + | (NaN,NaN) | ((7,8),(5,6),(3,4),(1,2)) | t + | (NaN,NaN) | ((1,2),(7,8),(5,6),(3,-4)) | t + | (NaN,NaN) | ((0,0)) | t + | (NaN,NaN) | ((0,1),(0,1)) | t + | (10,10) | ((2,0),(2,4),(0,0)) | f + | (10,10) | ((3,1),(3,3),(1,0)) | f + | (10,10) | ((1,2),(3,4),(5,6),(7,8)) | f + | (10,10) | ((7,8),(5,6),(3,4),(1,2)) | f + | (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (10,10) | ((0,0)) | f + | (10,10) | ((0,1),(0,1)) | f +(63 rows) SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contained -------------+------------+---------------------+----------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) + twentyfour | f1 | f1 | contained +------------+-------------------+----------------------------+----------- + | (0,0) | ((2,0),(2,4),(0,0)) | t + | (0,0) | ((3,1),(3,3),(1,0)) | f + | (0,0) | ((1,2),(3,4),(5,6),(7,8)) | f + | (0,0) | ((7,8),(5,6),(3,4),(1,2)) | f + | (0,0) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (0,0) | ((0,0)) | t + | (0,0) | ((0,1),(0,1)) | f + | (-10,0) | ((2,0),(2,4),(0,0)) | f + | (-10,0) | ((3,1),(3,3),(1,0)) | f + | (-10,0) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-10,0) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-10,0) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-10,0) | ((0,0)) | f + | (-10,0) | ((0,1),(0,1)) | f + | (-3,4) | ((2,0),(2,4),(0,0)) | f + | (-3,4) | ((3,1),(3,3),(1,0)) | f + | (-3,4) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-3,4) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-3,4) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-3,4) | ((0,0)) | f + | (-3,4) | ((0,1),(0,1)) | f + | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f + | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f + | (5.1,34.5) | ((1,2),(3,4),(5,6),(7,8)) | f + | (5.1,34.5) | ((7,8),(5,6),(3,4),(1,2)) | f + | (5.1,34.5) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (5.1,34.5) | ((0,0)) | f + | (5.1,34.5) | ((0,1),(0,1)) | f + | (-5,-12) | ((2,0),(2,4),(0,0)) | f + | (-5,-12) | ((3,1),(3,3),(1,0)) | f + | (-5,-12) | ((1,2),(3,4),(5,6),(7,8)) | f + | (-5,-12) | ((7,8),(5,6),(3,4),(1,2)) | f + | (-5,-12) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (-5,-12) | ((0,0)) | f + | (-5,-12) | ((0,1),(0,1)) | f + | (1e-300,-1e-300) | ((2,0),(2,4),(0,0)) | t + | (1e-300,-1e-300) | ((3,1),(3,3),(1,0)) | f + | (1e-300,-1e-300) | ((1,2),(3,4),(5,6),(7,8)) | f + | (1e-300,-1e-300) | ((7,8),(5,6),(3,4),(1,2)) | f + | (1e-300,-1e-300) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (1e-300,-1e-300) | ((0,0)) | t + | (1e-300,-1e-300) | ((0,1),(0,1)) | f + | (1e+300,Infinity) | ((2,0),(2,4),(0,0)) | f + | (1e+300,Infinity) | ((3,1),(3,3),(1,0)) | f + | (1e+300,Infinity) | ((1,2),(3,4),(5,6),(7,8)) | f + | (1e+300,Infinity) | ((7,8),(5,6),(3,4),(1,2)) | f + | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (1e+300,Infinity) | ((0,0)) | f + | (1e+300,Infinity) | ((0,1),(0,1)) | f + | (NaN,NaN) | ((2,0),(2,4),(0,0)) | t + | (NaN,NaN) | ((3,1),(3,3),(1,0)) | t + | (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | t + | (NaN,NaN) | ((7,8),(5,6),(3,4),(1,2)) | t + | (NaN,NaN) | ((1,2),(7,8),(5,6),(3,-4)) | t + | (NaN,NaN) | ((0,0)) | t + | (NaN,NaN) | ((0,1),(0,1)) | t + | (10,10) | ((2,0),(2,4),(0,0)) | f + | (10,10) | ((3,1),(3,3),(1,0)) | f + | (10,10) | ((1,2),(3,4),(5,6),(7,8)) | f + | (10,10) | ((7,8),(5,6),(3,4),(1,2)) | f + | (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (10,10) | ((0,0)) | f + | (10,10) | ((0,1),(0,1)) | f +(63 rows) SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon FROM POLYGON_TBL; - four | npoints | polygon -------+---------+--------------------- + four | npoints | polygon +------+---------+---------------------------- | 3 | ((2,0),(2,4),(0,0)) | 3 | ((3,1),(3,3),(1,0)) + | 4 | ((1,2),(3,4),(5,6),(7,8)) + | 4 | ((7,8),(5,6),(3,4),(1,2)) + | 4 | ((1,2),(7,8),(5,6),(3,-4)) | 1 | ((0,0)) | 2 | ((0,1),(0,1)) -(4 rows) +(7 rows) SELECT '' AS four, polygon(f1) FROM BOX_TBL; @@ -447,9 +3571,10 @@ SELECT '' AS four, polygon(f1) ------+------------------------------------------- | ((0,0),(0,2),(2,2),(2,0)) | ((1,1),(1,3),(3,3),(3,1)) + | ((-8,-10),(-8,2),(-2,2),(-2,-10)) | ((2.5,2.5),(2.5,3.5),(2.5,3.5),(2.5,2.5)) | ((3,3),(3,3),(3,3),(3,3)) -(4 rows) +(5 rows) SELECT '' AS four, polygon(f1) FROM PATH_TBL WHERE isclosed(f1); @@ -458,8 +3583,9 @@ SELECT '' AS four, polygon(f1) | ((1,2),(3,4)) | ((1,2),(3,4)) | ((1,2),(3,4)) + | ((10,20)) | ((11,12),(13,14)) -(4 rows) +(5 rows) SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon FROM PATH_TBL @@ -472,56 +3598,351 @@ SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon | [(11,12),(13,14)] | ((11,12),(13,14)) (4 rows) --- convert circles to polygons using the default number of points -SELECT '' AS six, polygon(f1) - FROM CIRCLE_TBL; - six | polygon ------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - | ((2,1),(2.40192378865,2.5),(3.5,3.59807621135),(5,4),(6.5,3.59807621135),(7.59807621135,2.5),(8,1),(7.59807621135,-0.5),(6.5,-1.59807621135),(5,-2),(3.5,-1.59807621135),(2.40192378865,-0.5)) - | ((-99,2),(-85.6025403784,52),(-49,88.6025403784),(1,102),(51,88.6025403784),(87.6025403784,52),(101,2),(87.6025403784,-48),(51,-84.6025403784),(1,-98),(-49,-84.6025403784),(-85.6025403784,-48)) - | ((-4,3),(-3.33012701892,5.5),(-1.5,7.33012701892),(1,8),(3.5,7.33012701892),(5.33012701892,5.5),(6,3),(5.33012701892,0.5),(3.5,-1.33012701892),(1,-2),(-1.5,-1.33012701892),(-3.33012701892,0.5)) - | ((-2,2),(-1.59807621135,3.5),(-0.5,4.59807621135),(1,5),(2.5,4.59807621135),(3.59807621135,3.5),(4,2),(3.59807621135,0.5),(2.5,-0.598076211353),(1,-1),(-0.5,-0.598076211353),(-1.59807621135,0.5)) - | ((90,200),(91.3397459622,205),(95,208.660254038),(100,210),(105,208.660254038),(108.660254038,205),(110,200),(108.660254038,195),(105,191.339745962),(100,190),(95,191.339745962),(91.3397459622,195)) - | ((-15,1),(0.40707856479,58.5),(42.5,100.592921435),(100,116),(157.5,100.592921435),(199.592921435,58.5),(215,1),(199.592921435,-56.5),(157.5,-98.5929214352),(100,-114),(42.5,-98.5929214352),(0.40707856479,-56.5)) -(6 rows) +-- To box +SELECT f1, f1::box FROM POLYGON_TBL; + f1 | f1 +----------------------------+-------------- + ((2,0),(2,4),(0,0)) | (2,4),(0,0) + ((3,1),(3,3),(1,0)) | (3,3),(1,0) + ((1,2),(3,4),(5,6),(7,8)) | (7,8),(1,2) + ((7,8),(5,6),(3,4),(1,2)) | (7,8),(1,2) + ((1,2),(7,8),(5,6),(3,-4)) | (7,8),(1,-4) + ((0,0)) | (0,0),(0,0) + ((0,1),(0,1)) | (0,1),(0,1) +(7 rows) --- convert the circle to an 8-point polygon -SELECT '' AS six, polygon(8, f1) - FROM CIRCLE_TBL; - six | polygon ------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ - | ((2,1),(2.87867965644,3.12132034356),(5,4),(7.12132034356,3.12132034356),(8,1),(7.12132034356,-1.12132034356),(5,-2),(2.87867965644,-1.12132034356)) - | ((-99,2),(-69.7106781187,72.7106781187),(1,102),(71.7106781187,72.7106781187),(101,2),(71.7106781187,-68.7106781187),(1,-98),(-69.7106781187,-68.7106781187)) - | ((-4,3),(-2.53553390593,6.53553390593),(1,8),(4.53553390593,6.53553390593),(6,3),(4.53553390593,-0.535533905933),(1,-2),(-2.53553390593,-0.535533905933)) - | ((-2,2),(-1.12132034356,4.12132034356),(1,5),(3.12132034356,4.12132034356),(4,2),(3.12132034356,-0.12132034356),(1,-1),(-1.12132034356,-0.12132034356)) - | ((90,200),(92.9289321881,207.071067812),(100,210),(107.071067812,207.071067812),(110,200),(107.071067812,192.928932188),(100,190),(92.9289321881,192.928932188)) - | ((-15,1),(18.6827201635,82.3172798365),(100,116),(181.317279836,82.3172798365),(215,1),(181.317279836,-80.3172798365),(100,-114),(18.6827201635,-80.3172798365)) -(6 rows) +-- To path +SELECT f1, f1::path FROM POLYGON_TBL; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(7 rows) + +-- Same as polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 ~= p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(9 rows) + +-- Contained by polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <@ p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(12 rows) + +-- Contains polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 @> p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(12 rows) + +-- Overlap with polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 && p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((3,1),(3,3),(1,0)) + ((2,0),(2,4),(0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((2,0),(2,4),(0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((2,0),(2,4),(0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((2,0),(2,4),(0,0)) | ((0,0)) + ((3,1),(3,3),(1,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(3,4),(5,6),(7,8)) | ((2,0),(2,4),(0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((2,0),(2,4),(0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(7,8),(5,6),(3,-4)) | ((2,0),(2,4),(0,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((3,1),(3,3),(1,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(25 rows) + +-- Left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 << p2.f1; + f1 | f1 +---------------+---------------------------- + ((0,0)) | ((3,1),(3,3),(1,0)) + ((0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,1),(0,1)) | ((3,1),(3,3),(1,0)) + ((0,1),(0,1)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,1),(0,1)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,1),(0,1)) | ((1,2),(7,8),(5,6),(3,-4)) +(8 rows) + +-- Overlap of left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &< p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((3,1),(3,3),(1,0)) + ((2,0),(2,4),(0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((2,0),(2,4),(0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((2,0),(2,4),(0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((3,1),(3,3),(1,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((3,1),(3,3),(1,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((3,1),(3,3),(1,0)) + ((0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,0)) | ((0,1),(0,1)) + ((0,1),(0,1)) | ((2,0),(2,4),(0,0)) + ((0,1),(0,1)) | ((3,1),(3,3),(1,0)) + ((0,1),(0,1)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,1),(0,1)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,1),(0,1)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,1),(0,1)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(32 rows) + +-- Right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 >> p2.f1; + f1 | f1 +----------------------------+--------------- + ((3,1),(3,3),(1,0)) | ((0,0)) + ((3,1),(3,3),(1,0)) | ((0,1),(0,1)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,1),(0,1)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,1),(0,1)) + ((1,2),(7,8),(5,6),(3,-4)) | ((0,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((0,1),(0,1)) +(8 rows) + +-- Overlap of right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &> p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((0,0)) + ((2,0),(2,4),(0,0)) | ((0,1),(0,1)) + ((3,1),(3,3),(1,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((3,1),(3,3),(1,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((3,1),(3,3),(1,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((3,1),(3,3),(1,0)) | ((0,0)) + ((3,1),(3,3),(1,0)) | ((0,1),(0,1)) + ((1,2),(3,4),(5,6),(7,8)) | ((2,0),(2,4),(0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,1),(0,1)) + ((7,8),(5,6),(3,4),(1,2)) | ((2,0),(2,4),(0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((3,1),(3,3),(1,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,1),(0,1)) + ((1,2),(7,8),(5,6),(3,-4)) | ((2,0),(2,4),(0,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((3,1),(3,3),(1,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(7,8),(5,6),(3,-4)) | ((0,0)) + ((1,2),(7,8),(5,6),(3,-4)) | ((0,1),(0,1)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((0,0)) + ((0,0)) | ((0,1),(0,1)) + ((0,1),(0,1)) | ((2,0),(2,4),(0,0)) + ((0,1),(0,1)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(37 rows) + +-- Below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <<| p2.f1; + f1 | f1 +---------------+--------------------------- + ((0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,0)) | ((0,1),(0,1)) + ((0,1),(0,1)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,1),(0,1)) | ((7,8),(5,6),(3,4),(1,2)) +(5 rows) + +-- Overlap or below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &<| p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((2,0),(2,4),(0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((2,0),(2,4),(0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((3,1),(3,3),(1,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((3,1),(3,3),(1,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((3,1),(3,3),(1,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((3,1),(3,3),(1,0)) + ((0,0)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,0)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,0)) | ((0,1),(0,1)) + ((0,1),(0,1)) | ((2,0),(2,4),(0,0)) + ((0,1),(0,1)) | ((3,1),(3,3),(1,0)) + ((0,1),(0,1)) | ((1,2),(3,4),(5,6),(7,8)) + ((0,1),(0,1)) | ((7,8),(5,6),(3,4),(1,2)) + ((0,1),(0,1)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(31 rows) +-- Above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |>> p2.f1; + f1 | f1 +---------------------------+--------------- + ((1,2),(3,4),(5,6),(7,8)) | ((0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,1),(0,1)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,1),(0,1)) + ((0,1),(0,1)) | ((0,0)) +(5 rows) + +-- Overlap or above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1; + f1 | f1 +----------------------------+---------------------------- + ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) + ((2,0),(2,4),(0,0)) | ((3,1),(3,3),(1,0)) + ((2,0),(2,4),(0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((2,0),(2,4),(0,0)) | ((0,0)) + ((3,1),(3,3),(1,0)) | ((2,0),(2,4),(0,0)) + ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) + ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((3,1),(3,3),(1,0)) | ((0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((2,0),(2,4),(0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((3,1),(3,3),(1,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) + ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) + ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,0)) + ((1,2),(3,4),(5,6),(7,8)) | ((0,1),(0,1)) + ((7,8),(5,6),(3,4),(1,2)) | ((2,0),(2,4),(0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((3,1),(3,3),(1,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) + ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) + ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,0)) + ((7,8),(5,6),(3,4),(1,2)) | ((0,1),(0,1)) + ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((2,0),(2,4),(0,0)) + ((0,0)) | ((3,1),(3,3),(1,0)) + ((0,0)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,0)) | ((0,0)) + ((0,1),(0,1)) | ((2,0),(2,4),(0,0)) + ((0,1),(0,1)) | ((3,1),(3,3),(1,0)) + ((0,1),(0,1)) | ((1,2),(7,8),(5,6),(3,-4)) + ((0,1),(0,1)) | ((0,0)) + ((0,1),(0,1)) | ((0,1),(0,1)) +(32 rows) + +-- Distance to polygon +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2; +ERROR: function "poly_distance" not implemented -- -- Circles -- SELECT '' AS six, circle(f1, 50.0) FROM POINT_TBL; - six | circle ------+----------------- + six | circle +-----+------------------------ | <(0,0),50> | <(-10,0),50> | <(-3,4),50> | <(5.1,34.5),50> | <(-5,-12),50> + | <(1e-300,-1e-300),50> + | <(1e+300,Infinity),50> + | <(NaN,NaN),50> | <(10,10),50> -(6 rows) +(9 rows) SELECT '' AS four, circle(f1) FROM BOX_TBL; - four | circle -------+----------------------- + four | circle +------+------------------------ | <(1,1),1.41421356237> | <(2,2),1.41421356237> + | <(-5,-4),6.7082039325> | <(2.5,3),0.5> | <(3,3),0> -(4 rows) +(5 rows) SELECT '' AS two, circle(f1) FROM POLYGON_TBL @@ -530,34 +3951,942 @@ SELECT '' AS two, circle(f1) -----+----------------------------------------------- | <(1.33333333333,1.33333333333),2.04168905064> | <(2.33333333333,1.33333333333),1.47534300379> -(2 rows) + | <(4,5),2.82842712475> + | <(4,5),2.82842712475> + | <(4,3),4.80664375676> +(5 rows) SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance FROM CIRCLE_TBL c1, POINT_TBL p1 WHERE (p1.f1 <-> c1.f1) > 0 ORDER BY distance, area(c1.f1), p1.f1[0]; - twentyfour | circle | point | distance -------------+----------------+------------+--------------- - | <(1,2),3> | (-3,4) | 1.472135955 - | <(5,1),3> | (0,0) | 2.09901951359 - | <(5,1),3> | (-3,4) | 5.54400374532 - | <(1,3),5> | (-10,0) | 6.40175425099 - | <(1,3),5> | (10,10) | 6.40175425099 - | <(5,1),3> | (10,10) | 7.29563014099 - | <(1,2),3> | (-10,0) | 8.1803398875 - | <(1,2),3> | (10,10) | 9.04159457879 - | <(1,3),5> | (-5,-12) | 11.1554944214 - | <(5,1),3> | (-10,0) | 12.0332963784 - | <(1,2),3> | (-5,-12) | 12.2315462117 - | <(5,1),3> | (-5,-12) | 13.4012194669 - | <(1,3),5> | (5.1,34.5) | 26.7657047773 - | <(1,2),3> | (5.1,34.5) | 29.7575945393 - | <(5,1),3> | (5.1,34.5) | 30.5001492534 - | <(100,200),10> | (5.1,34.5) | 180.778038568 - | <(100,200),10> | (10,10) | 200.237960416 - | <(100,200),10> | (-3,4) | 211.415898255 - | <(100,200),10> | (0,0) | 213.60679775 - | <(100,200),10> | (-10,0) | 218.25424421 - | <(100,200),10> | (-5,-12) | 226.577682802 -(21 rows) + twentyfour | circle | point | distance +------------+----------------+-------------------+--------------- + | <(1,2),3> | (-3,4) | 1.472135955 + | <(5,1),3> | (0,0) | 2.09901951359 + | <(5,1),3> | (1e-300,-1e-300) | 2.09901951359 + | <(5,1),3> | (-3,4) | 5.54400374532 + | <(3,5),0> | (0,0) | 5.83095189485 + | <(3,5),0> | (1e-300,-1e-300) | 5.83095189485 + | <(3,5),0> | (-3,4) | 6.0827625303 + | <(1,3),5> | (-10,0) | 6.40175425099 + | <(1,3),5> | (10,10) | 6.40175425099 + | <(5,1),3> | (10,10) | 7.29563014099 + | <(1,2),3> | (-10,0) | 8.1803398875 + | <(3,5),0> | (10,10) | 8.60232526704 + | <(1,2),3> | (10,10) | 9.04159457879 + | <(1,3),5> | (-5,-12) | 11.1554944214 + | <(5,1),3> | (-10,0) | 12.0332963784 + | <(1,2),3> | (-5,-12) | 12.2315462117 + | <(5,1),3> | (-5,-12) | 13.4012194669 + | <(3,5),0> | (-10,0) | 13.9283882772 + | <(3,5),0> | (-5,-12) | 18.7882942281 + | <(1,3),5> | (5.1,34.5) | 26.7657047773 + | <(3,5),0> | (5.1,34.5) | 29.5746513082 + | <(1,2),3> | (5.1,34.5) | 29.7575945393 + | <(5,1),3> | (5.1,34.5) | 30.5001492534 + | <(100,200),10> | (5.1,34.5) | 180.778038568 + | <(100,200),10> | (10,10) | 200.237960416 + | <(100,200),10> | (-3,4) | 211.415898255 + | <(100,200),10> | (0,0) | 213.60679775 + | <(100,200),10> | (1e-300,-1e-300) | 213.60679775 + | <(100,200),10> | (-10,0) | 218.25424421 + | <(100,200),10> | (-5,-12) | 226.577682802 + | <(3,5),0> | (1e+300,Infinity) | Infinity + | <(1,2),3> | (1e+300,Infinity) | Infinity + | <(5,1),3> | (1e+300,Infinity) | Infinity + | <(1,3),5> | (1e+300,Infinity) | Infinity + | <(100,200),10> | (1e+300,Infinity) | Infinity + | <(1,2),100> | (1e+300,Infinity) | Infinity + | <(100,1),115> | (1e+300,Infinity) | Infinity + | <(3,5),0> | (NaN,NaN) | NaN + | <(1,2),3> | (NaN,NaN) | NaN + | <(5,1),3> | (NaN,NaN) | NaN + | <(1,3),5> | (NaN,NaN) | NaN + | <(100,200),10> | (NaN,NaN) | NaN + | <(1,2),100> | (NaN,NaN) | NaN + | <(100,1),115> | (NaN,NaN) | NaN + | <(3,5),NaN> | (-10,0) | NaN + | <(3,5),NaN> | (-5,-12) | NaN + | <(3,5),NaN> | (-3,4) | NaN + | <(3,5),NaN> | (0,0) | NaN + | <(3,5),NaN> | (1e-300,-1e-300) | NaN + | <(3,5),NaN> | (5.1,34.5) | NaN + | <(3,5),NaN> | (10,10) | NaN + | <(3,5),NaN> | (1e+300,Infinity) | NaN + | <(3,5),NaN> | (NaN,NaN) | NaN +(53 rows) + +-- To polygon +SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + f1 | f1 +----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + <(5,1),3> | ((2,1),(2.40192378865,2.5),(3.5,3.59807621135),(5,4),(6.5,3.59807621135),(7.59807621135,2.5),(8,1),(7.59807621135,-0.5),(6.5,-1.59807621135),(5,-2),(3.5,-1.59807621135),(2.40192378865,-0.5)) + <(1,2),100> | ((-99,2),(-85.6025403784,52),(-49,88.6025403784),(1,102),(51,88.6025403784),(87.6025403784,52),(101,2),(87.6025403784,-48),(51,-84.6025403784),(1,-98),(-49,-84.6025403784),(-85.6025403784,-48)) + <(1,3),5> | ((-4,3),(-3.33012701892,5.5),(-1.5,7.33012701892),(1,8),(3.5,7.33012701892),(5.33012701892,5.5),(6,3),(5.33012701892,0.5),(3.5,-1.33012701892),(1,-2),(-1.5,-1.33012701892),(-3.33012701892,0.5)) + <(1,2),3> | ((-2,2),(-1.59807621135,3.5),(-0.5,4.59807621135),(1,5),(2.5,4.59807621135),(3.59807621135,3.5),(4,2),(3.59807621135,0.5),(2.5,-0.598076211353),(1,-1),(-0.5,-0.598076211353),(-1.59807621135,0.5)) + <(100,200),10> | ((90,200),(91.3397459622,205),(95,208.660254038),(100,210),(105,208.660254038),(108.660254038,205),(110,200),(108.660254038,195),(105,191.339745962),(100,190),(95,191.339745962),(91.3397459622,195)) + <(100,1),115> | ((-15,1),(0.40707856479,58.5),(42.5,100.592921435),(100,116),(157.5,100.592921435),(199.592921435,58.5),(215,1),(199.592921435,-56.5),(157.5,-98.5929214352),(100,-114),(42.5,-98.5929214352),(0.40707856479,-56.5)) +(6 rows) + +-- To polygon with less points +SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + f1 | polygon +----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ + <(5,1),3> | ((2,1),(2.87867965644,3.12132034356),(5,4),(7.12132034356,3.12132034356),(8,1),(7.12132034356,-1.12132034356),(5,-2),(2.87867965644,-1.12132034356)) + <(1,2),100> | ((-99,2),(-69.7106781187,72.7106781187),(1,102),(71.7106781187,72.7106781187),(101,2),(71.7106781187,-68.7106781187),(1,-98),(-69.7106781187,-68.7106781187)) + <(1,3),5> | ((-4,3),(-2.53553390593,6.53553390593),(1,8),(4.53553390593,6.53553390593),(6,3),(4.53553390593,-0.535533905933),(1,-2),(-2.53553390593,-0.535533905933)) + <(1,2),3> | ((-2,2),(-1.12132034356,4.12132034356),(1,5),(3.12132034356,4.12132034356),(4,2),(3.12132034356,-0.12132034356),(1,-1),(-1.12132034356,-0.12132034356)) + <(100,200),10> | ((90,200),(92.9289321881,207.071067812),(100,210),(107.071067812,207.071067812),(110,200),(107.071067812,192.928932188),(100,190),(92.9289321881,192.928932188)) + <(100,1),115> | ((-15,1),(18.6827201635,82.3172798365),(100,116),(181.317279836,82.3172798365),(215,1),(181.317279836,-80.3172798365),(100,-114),(18.6827201635,-80.3172798365)) +(6 rows) + +-- Too less points error +SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; +ERROR: must request at least 2 points +-- Zero radius error +SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>'; +ERROR: cannot convert circle with radius zero to polygon +-- Same as circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(1,2),100> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(3,5),0> + <(3,5),NaN> | <(3,5),0> + <(3,5),NaN> | <(3,5),NaN> +(9 rows) + +-- Overlap with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(1,2),3> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(5,1),3> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(1,3),5> + <(1,2),100> | <(1,2),3> + <(1,2),100> | <(100,1),115> + <(1,2),100> | <(3,5),0> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(1,2),3> + <(1,3),5> | <(100,1),115> + <(1,3),5> | <(3,5),0> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(5,1),3> + <(100,1),115> | <(1,2),100> + <(100,1),115> | <(1,3),5> + <(100,1),115> | <(1,2),3> + <(100,1),115> | <(100,1),115> + <(100,1),115> | <(3,5),0> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(33 rows) + +-- Overlap or left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(100,200),10> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(100,200),10> + <(100,200),10> | <(100,1),115> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(28 rows) + +-- Left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1; + f1 | f1 +-----------+---------------- + <(5,1),3> | <(100,200),10> + <(1,3),5> | <(100,200),10> + <(1,2),3> | <(100,200),10> + <(3,5),0> | <(100,200),10> +(4 rows) + +-- Right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1; + f1 | f1 +----------------+----------- + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(3,5),0> +(4 rows) + +-- Overlap or right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(1,2),3> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(1,2),100> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,200),10> | <(100,1),115> + <(100,200),10> | <(3,5),0> + <(100,1),115> | <(1,2),100> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(28 rows) + +-- Contained by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(1,2),100> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(17 rows) + +-- Contain by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(1,2),100> | <(5,1),3> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(1,3),5> + <(1,2),100> | <(1,2),3> + <(1,2),100> | <(3,5),0> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(1,2),3> + <(1,3),5> | <(3,5),0> + <(1,2),3> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(5,1),3> + <(100,1),115> | <(1,3),5> + <(100,1),115> | <(1,2),3> + <(100,1),115> | <(100,1),115> + <(100,1),115> | <(3,5),0> + <(3,5),0> | <(3,5),0> +(17 rows) + +-- Below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1; + f1 | f1 +---------------+---------------- + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(3,5),0> + <(1,2),100> | <(100,200),10> + <(1,3),5> | <(100,200),10> + <(1,2),3> | <(100,200),10> + <(100,1),115> | <(100,200),10> + <(3,5),0> | <(100,200),10> +(7 rows) + +-- Above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1; + f1 | f1 +----------------+--------------- + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(100,1),115> + <(100,200),10> | <(3,5),0> + <(3,5),0> | <(5,1),3> +(7 rows) + +-- Overlap or below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(1,2),3> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(5,1),3> | <(3,5),0> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(100,200),10> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(1,2),3> | <(3,5),0> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(100,200),10> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(29 rows) + +-- Overlap or above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,200),10> | <(100,1),115> + <(100,200),10> | <(3,5),0> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(29 rows) + +-- Area equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),3> + <(1,2),100> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(9 rows) + +-- Area not equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(5,1),3> | <(3,5),0> + <(1,2),100> | <(5,1),3> + <(1,2),100> | <(1,3),5> + <(1,2),100> | <(1,2),3> + <(1,2),100> | <(100,200),10> + <(1,2),100> | <(100,1),115> + <(1,2),100> | <(3,5),0> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,2),3> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,3),5> | <(3,5),0> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(1,2),3> | <(3,5),0> + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(100,1),115> + <(100,200),10> | <(3,5),0> + <(100,1),115> | <(5,1),3> + <(100,1),115> | <(1,2),100> + <(100,1),115> | <(1,3),5> + <(100,1),115> | <(1,2),3> + <(100,1),115> | <(100,200),10> + <(100,1),115> | <(3,5),0> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> +(40 rows) + +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> +(20 rows) + +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(3,5),0> + <(1,2),100> | <(5,1),3> + <(1,2),100> | <(1,3),5> + <(1,2),100> | <(1,2),3> + <(1,2),100> | <(100,200),10> + <(1,2),100> | <(3,5),0> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,2),3> + <(1,3),5> | <(3,5),0> + <(1,2),3> | <(3,5),0> + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(3,5),0> + <(100,1),115> | <(5,1),3> + <(100,1),115> | <(1,2),100> + <(100,1),115> | <(1,3),5> + <(100,1),115> | <(1,2),3> + <(100,1),115> | <(100,200),10> + <(100,1),115> | <(3,5),0> +(20 rows) + +-- Area less than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(1,2),3> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(100,200),10> + <(100,200),10> | <(100,1),115> + <(100,1),115> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> + <(3,5),0> | <(3,5),0> +(29 rows) + +-- Area greater than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(5,1),3> + <(5,1),3> | <(1,2),3> + <(5,1),3> | <(3,5),0> + <(1,2),100> | <(5,1),3> + <(1,2),100> | <(1,2),100> + <(1,2),100> | <(1,3),5> + <(1,2),100> | <(1,2),3> + <(1,2),100> | <(100,200),10> + <(1,2),100> | <(3,5),0> + <(1,3),5> | <(5,1),3> + <(1,3),5> | <(1,3),5> + <(1,3),5> | <(1,2),3> + <(1,3),5> | <(3,5),0> + <(1,2),3> | <(5,1),3> + <(1,2),3> | <(1,2),3> + <(1,2),3> | <(3,5),0> + <(100,200),10> | <(5,1),3> + <(100,200),10> | <(1,3),5> + <(100,200),10> | <(1,2),3> + <(100,200),10> | <(100,200),10> + <(100,200),10> | <(3,5),0> + <(100,1),115> | <(5,1),3> + <(100,1),115> | <(1,2),100> + <(100,1),115> | <(1,3),5> + <(100,1),115> | <(1,2),3> + <(100,1),115> | <(100,200),10> + <(100,1),115> | <(100,1),115> + <(100,1),115> | <(3,5),0> + <(3,5),0> | <(3,5),0> +(29 rows) + +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> +(20 rows) + +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + f1 | f1 +----------------+---------------- + <(5,1),3> | <(1,2),100> + <(5,1),3> | <(1,3),5> + <(5,1),3> | <(100,200),10> + <(5,1),3> | <(100,1),115> + <(1,2),100> | <(100,1),115> + <(1,3),5> | <(1,2),100> + <(1,3),5> | <(100,200),10> + <(1,3),5> | <(100,1),115> + <(1,2),3> | <(1,2),100> + <(1,2),3> | <(1,3),5> + <(1,2),3> | <(100,200),10> + <(1,2),3> | <(100,1),115> + <(100,200),10> | <(1,2),100> + <(100,200),10> | <(100,1),115> + <(3,5),0> | <(5,1),3> + <(3,5),0> | <(1,2),100> + <(3,5),0> | <(1,3),5> + <(3,5),0> | <(1,2),3> + <(3,5),0> | <(100,200),10> + <(3,5),0> | <(100,1),115> +(20 rows) + +-- Add point +SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + f1 | f1 | ?column? +----------------+-------------------+------------------------- + <(5,1),3> | (0,0) | <(5,1),3> + <(1,2),100> | (0,0) | <(1,2),100> + <(1,3),5> | (0,0) | <(1,3),5> + <(1,2),3> | (0,0) | <(1,2),3> + <(100,200),10> | (0,0) | <(100,200),10> + <(100,1),115> | (0,0) | <(100,1),115> + <(3,5),0> | (0,0) | <(3,5),0> + <(3,5),NaN> | (0,0) | <(3,5),NaN> + <(5,1),3> | (-10,0) | <(-5,1),3> + <(1,2),100> | (-10,0) | <(-9,2),100> + <(1,3),5> | (-10,0) | <(-9,3),5> + <(1,2),3> | (-10,0) | <(-9,2),3> + <(100,200),10> | (-10,0) | <(90,200),10> + <(100,1),115> | (-10,0) | <(90,1),115> + <(3,5),0> | (-10,0) | <(-7,5),0> + <(3,5),NaN> | (-10,0) | <(-7,5),NaN> + <(5,1),3> | (-3,4) | <(2,5),3> + <(1,2),100> | (-3,4) | <(-2,6),100> + <(1,3),5> | (-3,4) | <(-2,7),5> + <(1,2),3> | (-3,4) | <(-2,6),3> + <(100,200),10> | (-3,4) | <(97,204),10> + <(100,1),115> | (-3,4) | <(97,5),115> + <(3,5),0> | (-3,4) | <(0,9),0> + <(3,5),NaN> | (-3,4) | <(0,9),NaN> + <(5,1),3> | (5.1,34.5) | <(10.1,35.5),3> + <(1,2),100> | (5.1,34.5) | <(6.1,36.5),100> + <(1,3),5> | (5.1,34.5) | <(6.1,37.5),5> + <(1,2),3> | (5.1,34.5) | <(6.1,36.5),3> + <(100,200),10> | (5.1,34.5) | <(105.1,234.5),10> + <(100,1),115> | (5.1,34.5) | <(105.1,35.5),115> + <(3,5),0> | (5.1,34.5) | <(8.1,39.5),0> + <(3,5),NaN> | (5.1,34.5) | <(8.1,39.5),NaN> + <(5,1),3> | (-5,-12) | <(0,-11),3> + <(1,2),100> | (-5,-12) | <(-4,-10),100> + <(1,3),5> | (-5,-12) | <(-4,-9),5> + <(1,2),3> | (-5,-12) | <(-4,-10),3> + <(100,200),10> | (-5,-12) | <(95,188),10> + <(100,1),115> | (-5,-12) | <(95,-11),115> + <(3,5),0> | (-5,-12) | <(-2,-7),0> + <(3,5),NaN> | (-5,-12) | <(-2,-7),NaN> + <(5,1),3> | (1e-300,-1e-300) | <(5,1),3> + <(1,2),100> | (1e-300,-1e-300) | <(1,2),100> + <(1,3),5> | (1e-300,-1e-300) | <(1,3),5> + <(1,2),3> | (1e-300,-1e-300) | <(1,2),3> + <(100,200),10> | (1e-300,-1e-300) | <(100,200),10> + <(100,1),115> | (1e-300,-1e-300) | <(100,1),115> + <(3,5),0> | (1e-300,-1e-300) | <(3,5),0> + <(3,5),NaN> | (1e-300,-1e-300) | <(3,5),NaN> + <(5,1),3> | (1e+300,Infinity) | <(1e+300,Infinity),3> + <(1,2),100> | (1e+300,Infinity) | <(1e+300,Infinity),100> + <(1,3),5> | (1e+300,Infinity) | <(1e+300,Infinity),5> + <(1,2),3> | (1e+300,Infinity) | <(1e+300,Infinity),3> + <(100,200),10> | (1e+300,Infinity) | <(1e+300,Infinity),10> + <(100,1),115> | (1e+300,Infinity) | <(1e+300,Infinity),115> + <(3,5),0> | (1e+300,Infinity) | <(1e+300,Infinity),0> + <(3,5),NaN> | (1e+300,Infinity) | <(1e+300,Infinity),NaN> + <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> + <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> + <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> + <(1,2),3> | (NaN,NaN) | <(NaN,NaN),3> + <(100,200),10> | (NaN,NaN) | <(NaN,NaN),10> + <(100,1),115> | (NaN,NaN) | <(NaN,NaN),115> + <(3,5),0> | (NaN,NaN) | <(NaN,NaN),0> + <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> + <(5,1),3> | (10,10) | <(15,11),3> + <(1,2),100> | (10,10) | <(11,12),100> + <(1,3),5> | (10,10) | <(11,13),5> + <(1,2),3> | (10,10) | <(11,12),3> + <(100,200),10> | (10,10) | <(110,210),10> + <(100,1),115> | (10,10) | <(110,11),115> + <(3,5),0> | (10,10) | <(13,15),0> + <(3,5),NaN> | (10,10) | <(13,15),NaN> +(72 rows) + +-- Subtract point +SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + f1 | f1 | ?column? +----------------+-------------------+--------------------------- + <(5,1),3> | (0,0) | <(5,1),3> + <(1,2),100> | (0,0) | <(1,2),100> + <(1,3),5> | (0,0) | <(1,3),5> + <(1,2),3> | (0,0) | <(1,2),3> + <(100,200),10> | (0,0) | <(100,200),10> + <(100,1),115> | (0,0) | <(100,1),115> + <(3,5),0> | (0,0) | <(3,5),0> + <(3,5),NaN> | (0,0) | <(3,5),NaN> + <(5,1),3> | (-10,0) | <(15,1),3> + <(1,2),100> | (-10,0) | <(11,2),100> + <(1,3),5> | (-10,0) | <(11,3),5> + <(1,2),3> | (-10,0) | <(11,2),3> + <(100,200),10> | (-10,0) | <(110,200),10> + <(100,1),115> | (-10,0) | <(110,1),115> + <(3,5),0> | (-10,0) | <(13,5),0> + <(3,5),NaN> | (-10,0) | <(13,5),NaN> + <(5,1),3> | (-3,4) | <(8,-3),3> + <(1,2),100> | (-3,4) | <(4,-2),100> + <(1,3),5> | (-3,4) | <(4,-1),5> + <(1,2),3> | (-3,4) | <(4,-2),3> + <(100,200),10> | (-3,4) | <(103,196),10> + <(100,1),115> | (-3,4) | <(103,-3),115> + <(3,5),0> | (-3,4) | <(6,1),0> + <(3,5),NaN> | (-3,4) | <(6,1),NaN> + <(5,1),3> | (5.1,34.5) | <(-0.1,-33.5),3> + <(1,2),100> | (5.1,34.5) | <(-4.1,-32.5),100> + <(1,3),5> | (5.1,34.5) | <(-4.1,-31.5),5> + <(1,2),3> | (5.1,34.5) | <(-4.1,-32.5),3> + <(100,200),10> | (5.1,34.5) | <(94.9,165.5),10> + <(100,1),115> | (5.1,34.5) | <(94.9,-33.5),115> + <(3,5),0> | (5.1,34.5) | <(-2.1,-29.5),0> + <(3,5),NaN> | (5.1,34.5) | <(-2.1,-29.5),NaN> + <(5,1),3> | (-5,-12) | <(10,13),3> + <(1,2),100> | (-5,-12) | <(6,14),100> + <(1,3),5> | (-5,-12) | <(6,15),5> + <(1,2),3> | (-5,-12) | <(6,14),3> + <(100,200),10> | (-5,-12) | <(105,212),10> + <(100,1),115> | (-5,-12) | <(105,13),115> + <(3,5),0> | (-5,-12) | <(8,17),0> + <(3,5),NaN> | (-5,-12) | <(8,17),NaN> + <(5,1),3> | (1e-300,-1e-300) | <(5,1),3> + <(1,2),100> | (1e-300,-1e-300) | <(1,2),100> + <(1,3),5> | (1e-300,-1e-300) | <(1,3),5> + <(1,2),3> | (1e-300,-1e-300) | <(1,2),3> + <(100,200),10> | (1e-300,-1e-300) | <(100,200),10> + <(100,1),115> | (1e-300,-1e-300) | <(100,1),115> + <(3,5),0> | (1e-300,-1e-300) | <(3,5),0> + <(3,5),NaN> | (1e-300,-1e-300) | <(3,5),NaN> + <(5,1),3> | (1e+300,Infinity) | <(-1e+300,-Infinity),3> + <(1,2),100> | (1e+300,Infinity) | <(-1e+300,-Infinity),100> + <(1,3),5> | (1e+300,Infinity) | <(-1e+300,-Infinity),5> + <(1,2),3> | (1e+300,Infinity) | <(-1e+300,-Infinity),3> + <(100,200),10> | (1e+300,Infinity) | <(-1e+300,-Infinity),10> + <(100,1),115> | (1e+300,Infinity) | <(-1e+300,-Infinity),115> + <(3,5),0> | (1e+300,Infinity) | <(-1e+300,-Infinity),0> + <(3,5),NaN> | (1e+300,Infinity) | <(-1e+300,-Infinity),NaN> + <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> + <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> + <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> + <(1,2),3> | (NaN,NaN) | <(NaN,NaN),3> + <(100,200),10> | (NaN,NaN) | <(NaN,NaN),10> + <(100,1),115> | (NaN,NaN) | <(NaN,NaN),115> + <(3,5),0> | (NaN,NaN) | <(NaN,NaN),0> + <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> + <(5,1),3> | (10,10) | <(-5,-9),3> + <(1,2),100> | (10,10) | <(-9,-8),100> + <(1,3),5> | (10,10) | <(-9,-7),5> + <(1,2),3> | (10,10) | <(-9,-8),3> + <(100,200),10> | (10,10) | <(90,190),10> + <(100,1),115> | (10,10) | <(90,-9),115> + <(3,5),0> | (10,10) | <(-7,-5),0> + <(3,5),NaN> | (10,10) | <(-7,-5),NaN> +(72 rows) + +-- Multiply with point +SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + f1 | f1 | ?column? +----------------+-------------------+-------------------------------------------- + <(5,1),3> | (0,0) | <(0,0),0> + <(1,2),100> | (0,0) | <(0,0),0> + <(1,3),5> | (0,0) | <(0,0),0> + <(1,2),3> | (0,0) | <(0,0),0> + <(100,200),10> | (0,0) | <(0,0),0> + <(100,1),115> | (0,0) | <(0,0),0> + <(3,5),0> | (0,0) | <(0,0),0> + <(3,5),NaN> | (0,0) | <(0,0),NaN> + <(5,1),3> | (-10,0) | <(-50,-10),30> + <(1,2),100> | (-10,0) | <(-10,-20),1000> + <(1,3),5> | (-10,0) | <(-10,-30),50> + <(1,2),3> | (-10,0) | <(-10,-20),30> + <(100,200),10> | (-10,0) | <(-1000,-2000),100> + <(100,1),115> | (-10,0) | <(-1000,-10),1150> + <(3,5),0> | (-10,0) | <(-30,-50),0> + <(3,5),NaN> | (-10,0) | <(-30,-50),NaN> + <(5,1),3> | (-3,4) | <(-19,17),15> + <(1,2),100> | (-3,4) | <(-11,-2),500> + <(1,3),5> | (-3,4) | <(-15,-5),25> + <(1,2),3> | (-3,4) | <(-11,-2),15> + <(100,200),10> | (-3,4) | <(-1100,-200),50> + <(100,1),115> | (-3,4) | <(-304,397),575> + <(3,5),0> | (-3,4) | <(-29,-3),0> + <(3,5),NaN> | (-3,4) | <(-29,-3),NaN> + <(5,1),3> | (5.1,34.5) | <(-9,177.6),104.624758064> + <(1,2),100> | (5.1,34.5) | <(-63.9,44.7),3487.49193547> + <(1,3),5> | (5.1,34.5) | <(-98.4,49.8),174.374596774> + <(1,2),3> | (5.1,34.5) | <(-63.9,44.7),104.624758064> + <(100,200),10> | (5.1,34.5) | <(-6390,4470),348.749193547> + <(100,1),115> | (5.1,34.5) | <(475.5,3455.1),4010.6157258> + <(3,5),0> | (5.1,34.5) | <(-157.2,129),0> + <(3,5),NaN> | (5.1,34.5) | <(-157.2,129),NaN> + <(5,1),3> | (-5,-12) | <(-13,-65),39> + <(1,2),100> | (-5,-12) | <(19,-22),1300> + <(1,3),5> | (-5,-12) | <(31,-27),65> + <(1,2),3> | (-5,-12) | <(19,-22),39> + <(100,200),10> | (-5,-12) | <(1900,-2200),130> + <(100,1),115> | (-5,-12) | <(-488,-1205),1495> + <(3,5),0> | (-5,-12) | <(45,-61),0> + <(3,5),NaN> | (-5,-12) | <(45,-61),NaN> + <(5,1),3> | (1e-300,-1e-300) | <(6e-300,-4e-300),4.24264068712e-300> + <(1,2),100> | (1e-300,-1e-300) | <(3e-300,1e-300),1.41421356237e-298> + <(1,3),5> | (1e-300,-1e-300) | <(4e-300,2e-300),7.07106781187e-300> + <(1,2),3> | (1e-300,-1e-300) | <(3e-300,1e-300),4.24264068712e-300> + <(100,200),10> | (1e-300,-1e-300) | <(3e-298,1e-298),1.41421356237e-299> + <(100,1),115> | (1e-300,-1e-300) | <(1.01e-298,-9.9e-299),1.62634559673e-298> + <(3,5),0> | (1e-300,-1e-300) | <(8e-300,2e-300),0> + <(3,5),NaN> | (1e-300,-1e-300) | <(8e-300,2e-300),NaN> + <(5,1),3> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(1,2),100> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(1,3),5> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(1,2),3> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(100,200),10> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(100,1),115> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> + <(3,5),0> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> + <(3,5),NaN> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> + <(5,1),3> | (NaN,NaN) | <(NaN,NaN),NaN> + <(1,2),100> | (NaN,NaN) | <(NaN,NaN),NaN> + <(1,3),5> | (NaN,NaN) | <(NaN,NaN),NaN> + <(1,2),3> | (NaN,NaN) | <(NaN,NaN),NaN> + <(100,200),10> | (NaN,NaN) | <(NaN,NaN),NaN> + <(100,1),115> | (NaN,NaN) | <(NaN,NaN),NaN> + <(3,5),0> | (NaN,NaN) | <(NaN,NaN),NaN> + <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> + <(5,1),3> | (10,10) | <(40,60),42.4264068712> + <(1,2),100> | (10,10) | <(-10,30),1414.21356237> + <(1,3),5> | (10,10) | <(-20,40),70.7106781187> + <(1,2),3> | (10,10) | <(-10,30),42.4264068712> + <(100,200),10> | (10,10) | <(-1000,3000),141.421356237> + <(100,1),115> | (10,10) | <(990,1010),1626.34559673> + <(3,5),0> | (10,10) | <(-20,80),0> + <(3,5),NaN> | (10,10) | <(-20,80),NaN> +(72 rows) + +-- Divide by point +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + f1 | f1 | ?column? +----------------+------------+------------------------------------------------------ + <(5,1),3> | (5.1,34.5) | <(0.0493315573973,-0.137635045138),0.0860217042937> + <(5,1),3> | (10,10) | <(0.3,-0.2),0.212132034356> + <(1,2),100> | (5.1,34.5) | <(0.0609244733856,-0.0199792807459),2.86739014312> + <(1,2),100> | (10,10) | <(0.15,0.05),7.07106781187> + <(1,3),5> | (5.1,34.5) | <(0.0892901188891,-0.0157860983671),0.143369507156> + <(1,3),5> | (10,10) | <(0.2,0.1),0.353553390593> + <(1,2),3> | (5.1,34.5) | <(0.0609244733856,-0.0199792807459),0.0860217042937> + <(1,2),3> | (10,10) | <(0.15,0.05),0.212132034356> + <(100,200),10> | (5.1,34.5) | <(6.09244733856,-1.99792807459),0.286739014312> + <(100,200),10> | (10,10) | <(15,5),0.707106781187> + <(100,1),115> | (5.1,34.5) | <(0.44768388338,-2.83237136796),3.29749866459> + <(100,1),115> | (10,10) | <(5.05,-4.95),8.13172798365> + <(3,5),0> | (5.1,34.5) | <(0.154407774653,-0.0641310246164),0> + <(3,5),0> | (10,10) | <(0.4,0.1),0> + <(3,5),NaN> | (5.1,34.5) | <(0.154407774653,-0.0641310246164),NaN> + <(3,5),NaN> | (10,10) | <(0.4,0.1),NaN> +(16 rows) + +-- Overflow error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000; +ERROR: value out of range: overflow +-- Division by 0 error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0,0)'::point; +ERROR: division by zero +-- Distance to polygon +SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p; + f1 | f1 | ?column? +----------------+----------------------------+---------------- + <(5,1),3> | ((2,0),(2,4),(0,0)) | 0 + <(5,1),3> | ((3,1),(3,3),(1,0)) | 0 + <(5,1),3> | ((1,2),(3,4),(5,6),(7,8)) | 0.535533905933 + <(5,1),3> | ((7,8),(5,6),(3,4),(1,2)) | 0.535533905933 + <(5,1),3> | ((1,2),(7,8),(5,6),(3,-4)) | 0 + <(5,1),3> | ((0,0)) | 2.09901951359 + <(5,1),3> | ((0,1),(0,1)) | 2 + <(1,2),100> | ((2,0),(2,4),(0,0)) | 0 + <(1,2),100> | ((3,1),(3,3),(1,0)) | 0 + <(1,2),100> | ((1,2),(3,4),(5,6),(7,8)) | 0 + <(1,2),100> | ((7,8),(5,6),(3,4),(1,2)) | 0 + <(1,2),100> | ((1,2),(7,8),(5,6),(3,-4)) | 0 + <(1,2),100> | ((0,0)) | 0 + <(1,2),100> | ((0,1),(0,1)) | 0 + <(1,3),5> | ((2,0),(2,4),(0,0)) | 0 + <(1,3),5> | ((3,1),(3,3),(1,0)) | 0 + <(1,3),5> | ((1,2),(3,4),(5,6),(7,8)) | 0 + <(1,3),5> | ((7,8),(5,6),(3,4),(1,2)) | 0 + <(1,3),5> | ((1,2),(7,8),(5,6),(3,-4)) | 0 + <(1,3),5> | ((0,0)) | 0 + <(1,3),5> | ((0,1),(0,1)) | 0 + <(1,2),3> | ((2,0),(2,4),(0,0)) | 0 + <(1,2),3> | ((3,1),(3,3),(1,0)) | 0 + <(1,2),3> | ((1,2),(3,4),(5,6),(7,8)) | 0 + <(1,2),3> | ((7,8),(5,6),(3,4),(1,2)) | 0 + <(1,2),3> | ((1,2),(7,8),(5,6),(3,-4)) | 0 + <(1,2),3> | ((0,0)) | 0 + <(1,2),3> | ((0,1),(0,1)) | 0 + <(100,200),10> | ((2,0),(2,4),(0,0)) | 209.134661795 + <(100,200),10> | ((3,1),(3,3),(1,0)) | 209.585974051 + <(100,200),10> | ((1,2),(3,4),(5,6),(7,8)) | 203.337760371 + <(100,200),10> | ((7,8),(5,6),(3,4),(1,2)) | 203.337760371 + <(100,200),10> | ((1,2),(7,8),(5,6),(3,-4)) | 203.337760371 + <(100,200),10> | ((0,0)) | 213.60679775 + <(100,200),10> | ((0,1),(0,1)) | 212.712819568 + <(100,1),115> | ((2,0),(2,4),(0,0)) | 0 + <(100,1),115> | ((3,1),(3,3),(1,0)) | 0 + <(100,1),115> | ((1,2),(3,4),(5,6),(7,8)) | 0 + <(100,1),115> | ((7,8),(5,6),(3,4),(1,2)) | 0 + <(100,1),115> | ((1,2),(7,8),(5,6),(3,-4)) | 0 + <(100,1),115> | ((0,0)) | 0 + <(100,1),115> | ((0,1),(0,1)) | 0 + <(3,5),0> | ((2,0),(2,4),(0,0)) | 1.41421356237 + <(3,5),0> | ((3,1),(3,3),(1,0)) | 2 + <(3,5),0> | ((1,2),(3,4),(5,6),(7,8)) | 0.707106781187 + <(3,5),0> | ((7,8),(5,6),(3,4),(1,2)) | 0.707106781187 + <(3,5),0> | ((1,2),(7,8),(5,6),(3,-4)) | 0.707106781187 + <(3,5),0> | ((0,0)) | 5.83095189485 + <(3,5),0> | ((0,1),(0,1)) | 5 + <(3,5),NaN> | ((2,0),(2,4),(0,0)) | NaN + <(3,5),NaN> | ((3,1),(3,3),(1,0)) | NaN + <(3,5),NaN> | ((1,2),(3,4),(5,6),(7,8)) | NaN + <(3,5),NaN> | ((7,8),(5,6),(3,4),(1,2)) | NaN + <(3,5),NaN> | ((1,2),(7,8),(5,6),(3,-4)) | NaN + <(3,5),NaN> | ((0,0)) | NaN + <(3,5),NaN> | ((0,1),(0,1)) | NaN +(56 rows) diff --git a/src/test/regress/expected/geometry_1.out b/src/test/regress/expected/geometry_1.out deleted file mode 100644 index 3b92e230599..00000000000 --- a/src/test/regress/expected/geometry_1.out +++ /dev/null @@ -1,563 +0,0 @@ --- --- GEOMETRY --- --- Back off displayed precision a little bit to reduce platform-to-platform --- variation in results. -SET extra_float_digits TO -3; --- --- Points --- -SELECT '' AS four, center(f1) AS center - FROM BOX_TBL; - four | center -------+--------- - | (1,1) - | (2,2) - | (2.5,3) - | (3,3) -(4 rows) - -SELECT '' AS four, (@@ f1) AS center - FROM BOX_TBL; - four | center -------+--------- - | (1,1) - | (2,2) - | (2.5,3) - | (3,3) -(4 rows) - -SELECT '' AS six, point(f1) AS center - FROM CIRCLE_TBL; - six | center ------+----------- - | (5,1) - | (1,2) - | (1,3) - | (1,2) - | (100,200) - | (100,1) -(6 rows) - -SELECT '' AS six, (@@ f1) AS center - FROM CIRCLE_TBL; - six | center ------+----------- - | (5,1) - | (1,2) - | (1,3) - | (1,2) - | (100,200) - | (100,1) -(6 rows) - -SELECT '' AS two, (@@ f1) AS center - FROM POLYGON_TBL - WHERE (# f1) > 2; - two | center ------+------------------------------- - | (1.33333333333,1.33333333333) - | (2.33333333333,1.33333333333) -(2 rows) - --- "is horizontal" function -SELECT '' AS two, p1.f1 - FROM POINT_TBL p1 - WHERE ishorizontal(p1.f1, point '(0,0)'); - two | f1 ------+--------- - | (0,0) - | (-10,0) -(2 rows) - --- "is horizontal" operator -SELECT '' AS two, p1.f1 - FROM POINT_TBL p1 - WHERE p1.f1 ?- point '(0,0)'; - two | f1 ------+--------- - | (0,0) - | (-10,0) -(2 rows) - --- "is vertical" function -SELECT '' AS one, p1.f1 - FROM POINT_TBL p1 - WHERE isvertical(p1.f1, point '(5.1,34.5)'); - one | f1 ------+------------ - | (5.1,34.5) -(1 row) - --- "is vertical" operator -SELECT '' AS one, p1.f1 - FROM POINT_TBL p1 - WHERE p1.f1 ?| point '(5.1,34.5)'; - one | f1 ------+------------ - | (5.1,34.5) -(1 row) - --- --- Line segments --- --- intersection -SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection - FROM LSEG_TBL l, POINT_TBL p; -ERROR: operator does not exist: lseg # point -LINE 1: SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection - ^ -HINT: No operator matches the given name and argument types. You might need to add explicit type casts. --- closest point -SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest - FROM LSEG_TBL l, POINT_TBL p; - thirty | f1 | s | closest ---------+------------+-------------------------------+---------------------------------- - | (0,0) | [(1,2),(3,4)] | (1,2) - | (0,0) | [(0,0),(6,6)] | (0,0) - | (0,0) | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) - | (0,0) | [(-1000000,200),(300000,-40)] | (0.00284023658959,15.3846148603) - | (0,0) | [(11,22),(33,44)] | (11,22) - | (-10,0) | [(1,2),(3,4)] | (1,2) - | (-10,0) | [(0,0),(6,6)] | (0,0) - | (-10,0) | [(10,-10),(-3,-4)] | (-3,-4) - | (-10,0) | [(-1000000,200),(300000,-40)] | (-9.99715942258,15.386461014) - | (-10,0) | [(11,22),(33,44)] | (11,22) - | (-3,4) | [(1,2),(3,4)] | (1,2) - | (-3,4) | [(0,0),(6,6)] | (0.5,0.5) - | (-3,4) | [(10,-10),(-3,-4)] | (-3,-4) - | (-3,4) | [(-1000000,200),(300000,-40)] | (-2.99789812268,15.3851688427) - | (-3,4) | [(11,22),(33,44)] | (11,22) - | (5.1,34.5) | [(1,2),(3,4)] | (3,4) - | (5.1,34.5) | [(0,0),(6,6)] | (6,6) - | (5.1,34.5) | [(10,-10),(-3,-4)] | (-3,-4) - | (5.1,34.5) | [(-1000000,200),(300000,-40)] | (5.09647083221,15.3836744977) - | (5.1,34.5) | [(11,22),(33,44)] | (14.3,25.3) - | (-5,-12) | [(1,2),(3,4)] | (1,2) - | (-5,-12) | [(0,0),(6,6)] | (0,0) - | (-5,-12) | [(10,-10),(-3,-4)] | (-1.60487804878,-4.64390243902) - | (-5,-12) | [(-1000000,200),(300000,-40)] | (-4.99494420846,15.3855375282) - | (-5,-12) | [(11,22),(33,44)] | (11,22) - | (10,10) | [(1,2),(3,4)] | (3,4) - | (10,10) | [(0,0),(6,6)] | (6,6) - | (10,10) | [(10,-10),(-3,-4)] | (2.39024390244,-6.48780487805) - | (10,10) | [(-1000000,200),(300000,-40)] | (10.000993742,15.3827690473) - | (10,10) | [(11,22),(33,44)] | (11,22) -(30 rows) - --- --- Boxes --- -SELECT '' as six, box(f1) AS box FROM CIRCLE_TBL; - six | box ------+---------------------------------------------------------------- - | (7.12132034356,3.12132034356),(2.87867965644,-1.12132034356) - | (71.7106781187,72.7106781187),(-69.7106781187,-68.7106781187) - | (4.53553390593,6.53553390593),(-2.53553390593,-0.535533905933) - | (3.12132034356,4.12132034356),(-1.12132034356,-0.12132034356) - | (107.071067812,207.071067812),(92.9289321881,192.928932188) - | (181.317279836,82.3172798365),(18.6827201635,-80.3172798365) -(6 rows) - --- translation -SELECT '' AS twentyfour, b.f1 + p.f1 AS translation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+------------------------- - | (2,2),(0,0) - | (3,3),(1,1) - | (2.5,3.5),(2.5,2.5) - | (3,3),(3,3) - | (-8,2),(-10,0) - | (-7,3),(-9,1) - | (-7.5,3.5),(-7.5,2.5) - | (-7,3),(-7,3) - | (-1,6),(-3,4) - | (0,7),(-2,5) - | (-0.5,7.5),(-0.5,6.5) - | (0,7),(0,7) - | (7.1,36.5),(5.1,34.5) - | (8.1,37.5),(6.1,35.5) - | (7.6,38),(7.6,37) - | (8.1,37.5),(8.1,37.5) - | (-3,-10),(-5,-12) - | (-2,-9),(-4,-11) - | (-2.5,-8.5),(-2.5,-9.5) - | (-2,-9),(-2,-9) - | (12,12),(10,10) - | (13,13),(11,11) - | (12.5,13.5),(12.5,12.5) - | (13,13),(13,13) -(24 rows) - -SELECT '' AS twentyfour, b.f1 - p.f1 AS translation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+--------------------------- - | (2,2),(0,0) - | (3,3),(1,1) - | (2.5,3.5),(2.5,2.5) - | (3,3),(3,3) - | (12,2),(10,0) - | (13,3),(11,1) - | (12.5,3.5),(12.5,2.5) - | (13,3),(13,3) - | (5,-2),(3,-4) - | (6,-1),(4,-3) - | (5.5,-0.5),(5.5,-1.5) - | (6,-1),(6,-1) - | (-3.1,-32.5),(-5.1,-34.5) - | (-2.1,-31.5),(-4.1,-33.5) - | (-2.6,-31),(-2.6,-32) - | (-2.1,-31.5),(-2.1,-31.5) - | (7,14),(5,12) - | (8,15),(6,13) - | (7.5,15.5),(7.5,14.5) - | (8,15),(8,15) - | (-8,-8),(-10,-10) - | (-7,-7),(-9,-9) - | (-7.5,-6.5),(-7.5,-7.5) - | (-7,-7),(-7,-7) -(24 rows) - --- scaling and rotation -SELECT '' AS twentyfour, b.f1 * p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | rotation -------------+----------------------------- - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(-20,-20) - | (-10,-10),(-30,-30) - | (-25,-25),(-25,-35) - | (-30,-30),(-30,-30) - | (0,2),(-14,0) - | (-7,3),(-21,1) - | (-17.5,2.5),(-21.5,-0.5) - | (-21,3),(-21,3) - | (0,79.2),(-58.8,0) - | (-29.4,118.8),(-88.2,39.6) - | (-73.5,104.1),(-108,99) - | (-88.2,118.8),(-88.2,118.8) - | (14,0),(0,-34) - | (21,-17),(7,-51) - | (29.5,-42.5),(17.5,-47.5) - | (21,-51),(21,-51) - | (0,40),(0,0) - | (0,60),(0,20) - | (0,60),(-10,50) - | (0,60),(0,60) -(24 rows) - -SELECT '' AS twenty, b.f1 / p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p - WHERE (p.f1 <-> point '(0,0)') >= 1; - twenty | rotation ---------+---------------------------------------------------------------------- - | (0,0),(-0.2,-0.2) - | (0.08,0),(0,-0.56) - | (0.0651176557644,0),(0,-0.0483449262493) - | (0,0.0828402366864),(-0.201183431953,0) - | (0.2,0),(0,0) - | (-0.1,-0.1),(-0.3,-0.3) - | (0.12,-0.28),(0.04,-0.84) - | (0.0976764836466,-0.0241724631247),(0.0325588278822,-0.072517389374) - | (-0.100591715976,0.12426035503),(-0.301775147929,0.0414201183432) - | (0.3,0),(0.1,0) - | (-0.25,-0.25),(-0.25,-0.35) - | (0.26,-0.7),(0.1,-0.82) - | (0.109762715209,-0.0562379754329),(0.0813970697055,-0.0604311578117) - | (-0.251479289941,0.103550295858),(-0.322485207101,0.0739644970414) - | (0.3,0.05),(0.25,0) - | (-0.3,-0.3),(-0.3,-0.3) - | (0.12,-0.84),(0.12,-0.84) - | (0.0976764836466,-0.072517389374),(0.0976764836466,-0.072517389374) - | (-0.301775147929,0.12426035503),(-0.301775147929,0.12426035503) - | (0.3,0),(0.3,0) -(20 rows) - -SELECT f1::box - FROM POINT_TBL; - f1 ------------------------ - (0,0),(0,0) - (-10,0),(-10,0) - (-3,4),(-3,4) - (5.1,34.5),(5.1,34.5) - (-5,-12),(-5,-12) - (10,10),(10,10) -(6 rows) - -SELECT bound_box(a.f1, b.f1) - FROM BOX_TBL a, BOX_TBL b; - bound_box ---------------------- - (2,2),(0,0) - (3,3),(0,0) - (2.5,3.5),(0,0) - (3,3),(0,0) - (3,3),(0,0) - (3,3),(1,1) - (3,3.5),(1,1) - (3,3),(1,1) - (2.5,3.5),(0,0) - (3,3.5),(1,1) - (2.5,3.5),(2.5,2.5) - (3,3.5),(2.5,2.5) - (3,3),(0,0) - (3,3),(1,1) - (3,3.5),(2.5,2.5) - (3,3),(3,3) -(16 rows) - --- --- Paths --- -SELECT '' AS eight, npoints(f1) AS npoints, f1 AS path FROM PATH_TBL; - eight | npoints | path --------+---------+--------------------------- - | 2 | [(1,2),(3,4)] - | 2 | ((1,2),(3,4)) - | 4 | [(0,0),(3,0),(4,5),(1,6)] - | 2 | ((1,2),(3,4)) - | 2 | ((1,2),(3,4)) - | 2 | [(1,2),(3,4)] - | 2 | [(11,12),(13,14)] - | 2 | ((11,12),(13,14)) -(8 rows) - -SELECT '' AS four, path(f1) FROM POLYGON_TBL; - four | path -------+--------------------- - | ((2,0),(2,4),(0,0)) - | ((3,1),(3,3),(1,0)) - | ((0,0)) - | ((0,1),(0,1)) -(4 rows) - --- translation -SELECT '' AS eight, p1.f1 + point '(10,10)' AS dist_add - FROM PATH_TBL p1; - eight | dist_add --------+----------------------------------- - | [(11,12),(13,14)] - | ((11,12),(13,14)) - | [(10,10),(13,10),(14,15),(11,16)] - | ((11,12),(13,14)) - | ((11,12),(13,14)) - | [(11,12),(13,14)] - | [(21,22),(23,24)] - | ((21,22),(23,24)) -(8 rows) - --- scaling and rotation -SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul - FROM PATH_TBL p1; - eight | dist_mul --------+------------------------------ - | [(4,3),(10,5)] - | ((4,3),(10,5)) - | [(0,0),(6,-3),(13,6),(8,11)] - | ((4,3),(10,5)) - | ((4,3),(10,5)) - | [(4,3),(10,5)] - | [(34,13),(40,15)] - | ((34,13),(40,15)) -(8 rows) - --- --- Polygons --- --- containment -SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains - FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contains -------------+------------+---------------------+---------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) - -SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained - FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contained -------------+------------+---------------------+----------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) - -SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon - FROM POLYGON_TBL; - four | npoints | polygon -------+---------+--------------------- - | 3 | ((2,0),(2,4),(0,0)) - | 3 | ((3,1),(3,3),(1,0)) - | 1 | ((0,0)) - | 2 | ((0,1),(0,1)) -(4 rows) - -SELECT '' AS four, polygon(f1) - FROM BOX_TBL; - four | polygon -------+------------------------------------------- - | ((0,0),(0,2),(2,2),(2,0)) - | ((1,1),(1,3),(3,3),(3,1)) - | ((2.5,2.5),(2.5,3.5),(2.5,3.5),(2.5,2.5)) - | ((3,3),(3,3),(3,3),(3,3)) -(4 rows) - -SELECT '' AS four, polygon(f1) - FROM PATH_TBL WHERE isclosed(f1); - four | polygon -------+------------------- - | ((1,2),(3,4)) - | ((1,2),(3,4)) - | ((1,2),(3,4)) - | ((11,12),(13,14)) -(4 rows) - -SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon - FROM PATH_TBL - WHERE isopen(f1); - four | open_path | polygon -------+---------------------------+--------------------------- - | [(1,2),(3,4)] | ((1,2),(3,4)) - | [(0,0),(3,0),(4,5),(1,6)] | ((0,0),(3,0),(4,5),(1,6)) - | [(1,2),(3,4)] | ((1,2),(3,4)) - | [(11,12),(13,14)] | ((11,12),(13,14)) -(4 rows) - --- convert circles to polygons using the default number of points -SELECT '' AS six, polygon(f1) - FROM CIRCLE_TBL; - six | polygon ------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - | ((2,1),(2.40192378865,2.5),(3.5,3.59807621135),(5,4),(6.5,3.59807621135),(7.59807621135,2.5),(8,1),(7.59807621135,-0.5),(6.5,-1.59807621135),(5,-2),(3.5,-1.59807621135),(2.40192378865,-0.5)) - | ((-99,2),(-85.6025403784,52),(-49,88.6025403784),(1,102),(51,88.6025403784),(87.6025403784,52),(101,2),(87.6025403784,-48),(51,-84.6025403784),(1,-98),(-49,-84.6025403784),(-85.6025403784,-48)) - | ((-4,3),(-3.33012701892,5.5),(-1.5,7.33012701892),(1,8),(3.5,7.33012701892),(5.33012701892,5.5),(6,3),(5.33012701892,0.5),(3.5,-1.33012701892),(1,-2),(-1.5,-1.33012701892),(-3.33012701892,0.5)) - | ((-2,2),(-1.59807621135,3.5),(-0.5,4.59807621135),(1,5),(2.5,4.59807621135),(3.59807621135,3.5),(4,2),(3.59807621135,0.5),(2.5,-0.598076211353),(1,-1),(-0.5,-0.598076211353),(-1.59807621135,0.5)) - | ((90,200),(91.3397459622,205),(95,208.660254038),(100,210),(105,208.660254038),(108.660254038,205),(110,200),(108.660254038,195),(105,191.339745962),(100,190),(95,191.339745962),(91.3397459622,195)) - | ((-15,1),(0.40707856479,58.5),(42.5,100.592921435),(100,116),(157.5,100.592921435),(199.592921435,58.5),(215,1),(199.592921435,-56.5),(157.5,-98.5929214352),(100,-114),(42.5,-98.5929214352),(0.40707856479,-56.5)) -(6 rows) - --- convert the circle to an 8-point polygon -SELECT '' AS six, polygon(8, f1) - FROM CIRCLE_TBL; - six | polygon ------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ - | ((2,1),(2.87867965644,3.12132034356),(5,4),(7.12132034356,3.12132034356),(8,1),(7.12132034356,-1.12132034356),(5,-2),(2.87867965644,-1.12132034356)) - | ((-99,2),(-69.7106781187,72.7106781187),(1,102),(71.7106781187,72.7106781187),(101,2),(71.7106781187,-68.7106781187),(1,-98),(-69.7106781187,-68.7106781187)) - | ((-4,3),(-2.53553390593,6.53553390593),(1,8),(4.53553390593,6.53553390593),(6,3),(4.53553390593,-0.535533905933),(1,-2),(-2.53553390593,-0.535533905933)) - | ((-2,2),(-1.12132034356,4.12132034356),(1,5),(3.12132034356,4.12132034356),(4,2),(3.12132034356,-0.12132034356),(1,-1),(-1.12132034356,-0.12132034356)) - | ((90,200),(92.9289321881,207.071067812),(100,210),(107.071067812,207.071067812),(110,200),(107.071067812,192.928932188),(100,190),(92.9289321881,192.928932188)) - | ((-15,1),(18.6827201635,82.3172798365),(100,116),(181.317279836,82.3172798365),(215,1),(181.317279836,-80.3172798365),(100,-114),(18.6827201635,-80.3172798365)) -(6 rows) - --- --- Circles --- -SELECT '' AS six, circle(f1, 50.0) - FROM POINT_TBL; - six | circle ------+----------------- - | <(0,0),50> - | <(-10,0),50> - | <(-3,4),50> - | <(5.1,34.5),50> - | <(-5,-12),50> - | <(10,10),50> -(6 rows) - -SELECT '' AS four, circle(f1) - FROM BOX_TBL; - four | circle -------+----------------------- - | <(1,1),1.41421356237> - | <(2,2),1.41421356237> - | <(2.5,3),0.5> - | <(3,3),0> -(4 rows) - -SELECT '' AS two, circle(f1) - FROM POLYGON_TBL - WHERE (# f1) >= 3; - two | circle ------+----------------------------------------------- - | <(1.33333333333,1.33333333333),2.04168905064> - | <(2.33333333333,1.33333333333),1.47534300379> -(2 rows) - -SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance - FROM CIRCLE_TBL c1, POINT_TBL p1 - WHERE (p1.f1 <-> c1.f1) > 0 - ORDER BY distance, area(c1.f1), p1.f1[0]; - twentyfour | circle | point | distance -------------+----------------+------------+--------------- - | <(1,2),3> | (-3,4) | 1.472135955 - | <(5,1),3> | (0,0) | 2.09901951359 - | <(5,1),3> | (-3,4) | 5.54400374532 - | <(1,3),5> | (-10,0) | 6.40175425099 - | <(1,3),5> | (10,10) | 6.40175425099 - | <(5,1),3> | (10,10) | 7.29563014099 - | <(1,2),3> | (-10,0) | 8.1803398875 - | <(1,2),3> | (10,10) | 9.04159457879 - | <(1,3),5> | (-5,-12) | 11.1554944214 - | <(5,1),3> | (-10,0) | 12.0332963784 - | <(1,2),3> | (-5,-12) | 12.2315462117 - | <(5,1),3> | (-5,-12) | 13.4012194669 - | <(1,3),5> | (5.1,34.5) | 26.7657047773 - | <(1,2),3> | (5.1,34.5) | 29.7575945393 - | <(5,1),3> | (5.1,34.5) | 30.5001492534 - | <(100,200),10> | (5.1,34.5) | 180.778038568 - | <(100,200),10> | (10,10) | 200.237960416 - | <(100,200),10> | (-3,4) | 211.415898255 - | <(100,200),10> | (0,0) | 213.60679775 - | <(100,200),10> | (-10,0) | 218.25424421 - | <(100,200),10> | (-5,-12) | 226.577682802 -(21 rows) - diff --git a/src/test/regress/expected/geometry_2.out b/src/test/regress/expected/geometry_2.out deleted file mode 100644 index 5a922bcd3f3..00000000000 --- a/src/test/regress/expected/geometry_2.out +++ /dev/null @@ -1,563 +0,0 @@ --- --- GEOMETRY --- --- Back off displayed precision a little bit to reduce platform-to-platform --- variation in results. -SET extra_float_digits TO -3; --- --- Points --- -SELECT '' AS four, center(f1) AS center - FROM BOX_TBL; - four | center -------+--------- - | (1,1) - | (2,2) - | (2.5,3) - | (3,3) -(4 rows) - -SELECT '' AS four, (@@ f1) AS center - FROM BOX_TBL; - four | center -------+--------- - | (1,1) - | (2,2) - | (2.5,3) - | (3,3) -(4 rows) - -SELECT '' AS six, point(f1) AS center - FROM CIRCLE_TBL; - six | center ------+----------- - | (5,1) - | (1,2) - | (1,3) - | (1,2) - | (100,200) - | (100,1) -(6 rows) - -SELECT '' AS six, (@@ f1) AS center - FROM CIRCLE_TBL; - six | center ------+----------- - | (5,1) - | (1,2) - | (1,3) - | (1,2) - | (100,200) - | (100,1) -(6 rows) - -SELECT '' AS two, (@@ f1) AS center - FROM POLYGON_TBL - WHERE (# f1) > 2; - two | center ------+------------------------------- - | (1.33333333333,1.33333333333) - | (2.33333333333,1.33333333333) -(2 rows) - --- "is horizontal" function -SELECT '' AS two, p1.f1 - FROM POINT_TBL p1 - WHERE ishorizontal(p1.f1, point '(0,0)'); - two | f1 ------+--------- - | (0,0) - | (-10,0) -(2 rows) - --- "is horizontal" operator -SELECT '' AS two, p1.f1 - FROM POINT_TBL p1 - WHERE p1.f1 ?- point '(0,0)'; - two | f1 ------+--------- - | (0,0) - | (-10,0) -(2 rows) - --- "is vertical" function -SELECT '' AS one, p1.f1 - FROM POINT_TBL p1 - WHERE isvertical(p1.f1, point '(5.1,34.5)'); - one | f1 ------+------------ - | (5.1,34.5) -(1 row) - --- "is vertical" operator -SELECT '' AS one, p1.f1 - FROM POINT_TBL p1 - WHERE p1.f1 ?| point '(5.1,34.5)'; - one | f1 ------+------------ - | (5.1,34.5) -(1 row) - --- --- Line segments --- --- intersection -SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection - FROM LSEG_TBL l, POINT_TBL p; -ERROR: operator does not exist: lseg # point -LINE 1: SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection - ^ -HINT: No operator matches the given name and argument types. You might need to add explicit type casts. --- closest point -SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest - FROM LSEG_TBL l, POINT_TBL p; - thirty | f1 | s | closest ---------+------------+-------------------------------+---------------------------------- - | (0,0) | [(1,2),(3,4)] | (1,2) - | (0,0) | [(0,0),(6,6)] | (0,0) - | (0,0) | [(10,-10),(-3,-4)] | (-2.0487804878,-4.43902439024) - | (0,0) | [(-1000000,200),(300000,-40)] | (0.00284023658959,15.3846148603) - | (0,0) | [(11,22),(33,44)] | (11,22) - | (-10,0) | [(1,2),(3,4)] | (1,2) - | (-10,0) | [(0,0),(6,6)] | (0,0) - | (-10,0) | [(10,-10),(-3,-4)] | (-3,-4) - | (-10,0) | [(-1000000,200),(300000,-40)] | (-9.99715942258,15.386461014) - | (-10,0) | [(11,22),(33,44)] | (11,22) - | (-3,4) | [(1,2),(3,4)] | (1,2) - | (-3,4) | [(0,0),(6,6)] | (0.5,0.5) - | (-3,4) | [(10,-10),(-3,-4)] | (-3,-4) - | (-3,4) | [(-1000000,200),(300000,-40)] | (-2.99789812268,15.3851688427) - | (-3,4) | [(11,22),(33,44)] | (11,22) - | (5.1,34.5) | [(1,2),(3,4)] | (3,4) - | (5.1,34.5) | [(0,0),(6,6)] | (6,6) - | (5.1,34.5) | [(10,-10),(-3,-4)] | (-3,-4) - | (5.1,34.5) | [(-1000000,200),(300000,-40)] | (5.09647083221,15.3836744977) - | (5.1,34.5) | [(11,22),(33,44)] | (14.3,25.3) - | (-5,-12) | [(1,2),(3,4)] | (1,2) - | (-5,-12) | [(0,0),(6,6)] | (0,0) - | (-5,-12) | [(10,-10),(-3,-4)] | (-1.60487804878,-4.64390243902) - | (-5,-12) | [(-1000000,200),(300000,-40)] | (-4.99494420846,15.3855375282) - | (-5,-12) | [(11,22),(33,44)] | (11,22) - | (10,10) | [(1,2),(3,4)] | (3,4) - | (10,10) | [(0,0),(6,6)] | (6,6) - | (10,10) | [(10,-10),(-3,-4)] | (2.39024390244,-6.48780487805) - | (10,10) | [(-1000000,200),(300000,-40)] | (10.000993742,15.3827690473) - | (10,10) | [(11,22),(33,44)] | (11,22) -(30 rows) - --- --- Boxes --- -SELECT '' as six, box(f1) AS box FROM CIRCLE_TBL; - six | box ------+---------------------------------------------------------------- - | (7.12132034356,3.12132034356),(2.87867965644,-1.12132034356) - | (71.7106781187,72.7106781187),(-69.7106781187,-68.7106781187) - | (4.53553390593,6.53553390593),(-2.53553390593,-0.535533905933) - | (3.12132034356,4.12132034356),(-1.12132034356,-0.12132034356) - | (107.071067812,207.071067812),(92.9289321881,192.928932188) - | (181.317279836,82.3172798365),(18.6827201635,-80.3172798365) -(6 rows) - --- translation -SELECT '' AS twentyfour, b.f1 + p.f1 AS translation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+------------------------- - | (2,2),(0,0) - | (3,3),(1,1) - | (2.5,3.5),(2.5,2.5) - | (3,3),(3,3) - | (-8,2),(-10,0) - | (-7,3),(-9,1) - | (-7.5,3.5),(-7.5,2.5) - | (-7,3),(-7,3) - | (-1,6),(-3,4) - | (0,7),(-2,5) - | (-0.5,7.5),(-0.5,6.5) - | (0,7),(0,7) - | (7.1,36.5),(5.1,34.5) - | (8.1,37.5),(6.1,35.5) - | (7.6,38),(7.6,37) - | (8.1,37.5),(8.1,37.5) - | (-3,-10),(-5,-12) - | (-2,-9),(-4,-11) - | (-2.5,-8.5),(-2.5,-9.5) - | (-2,-9),(-2,-9) - | (12,12),(10,10) - | (13,13),(11,11) - | (12.5,13.5),(12.5,12.5) - | (13,13),(13,13) -(24 rows) - -SELECT '' AS twentyfour, b.f1 - p.f1 AS translation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | translation -------------+--------------------------- - | (2,2),(0,0) - | (3,3),(1,1) - | (2.5,3.5),(2.5,2.5) - | (3,3),(3,3) - | (12,2),(10,0) - | (13,3),(11,1) - | (12.5,3.5),(12.5,2.5) - | (13,3),(13,3) - | (5,-2),(3,-4) - | (6,-1),(4,-3) - | (5.5,-0.5),(5.5,-1.5) - | (6,-1),(6,-1) - | (-3.1,-32.5),(-5.1,-34.5) - | (-2.1,-31.5),(-4.1,-33.5) - | (-2.6,-31),(-2.6,-32) - | (-2.1,-31.5),(-2.1,-31.5) - | (7,14),(5,12) - | (8,15),(6,13) - | (7.5,15.5),(7.5,14.5) - | (8,15),(8,15) - | (-8,-8),(-10,-10) - | (-7,-7),(-9,-9) - | (-7.5,-6.5),(-7.5,-7.5) - | (-7,-7),(-7,-7) -(24 rows) - --- scaling and rotation -SELECT '' AS twentyfour, b.f1 * p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p; - twentyfour | rotation -------------+----------------------------- - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (0,0),(0,0) - | (-0,0),(-20,-20) - | (-10,-10),(-30,-30) - | (-25,-25),(-25,-35) - | (-30,-30),(-30,-30) - | (-0,2),(-14,0) - | (-7,3),(-21,1) - | (-17.5,2.5),(-21.5,-0.5) - | (-21,3),(-21,3) - | (0,79.2),(-58.8,0) - | (-29.4,118.8),(-88.2,39.6) - | (-73.5,104.1),(-108,99) - | (-88.2,118.8),(-88.2,118.8) - | (14,-0),(0,-34) - | (21,-17),(7,-51) - | (29.5,-42.5),(17.5,-47.5) - | (21,-51),(21,-51) - | (0,40),(0,0) - | (0,60),(0,20) - | (0,60),(-10,50) - | (0,60),(0,60) -(24 rows) - -SELECT '' AS twenty, b.f1 / p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p - WHERE (p.f1 <-> point '(0,0)') >= 1; - twenty | rotation ---------+---------------------------------------------------------------------- - | (0,-0),(-0.2,-0.2) - | (0.08,-0),(0,-0.56) - | (0.0651176557644,0),(0,-0.0483449262493) - | (-0,0.0828402366864),(-0.201183431953,0) - | (0.2,0),(0,0) - | (-0.1,-0.1),(-0.3,-0.3) - | (0.12,-0.28),(0.04,-0.84) - | (0.0976764836466,-0.0241724631247),(0.0325588278822,-0.072517389374) - | (-0.100591715976,0.12426035503),(-0.301775147929,0.0414201183432) - | (0.3,0),(0.1,0) - | (-0.25,-0.25),(-0.25,-0.35) - | (0.26,-0.7),(0.1,-0.82) - | (0.109762715209,-0.0562379754329),(0.0813970697055,-0.0604311578117) - | (-0.251479289941,0.103550295858),(-0.322485207101,0.0739644970414) - | (0.3,0.05),(0.25,0) - | (-0.3,-0.3),(-0.3,-0.3) - | (0.12,-0.84),(0.12,-0.84) - | (0.0976764836466,-0.072517389374),(0.0976764836466,-0.072517389374) - | (-0.301775147929,0.12426035503),(-0.301775147929,0.12426035503) - | (0.3,0),(0.3,0) -(20 rows) - -SELECT f1::box - FROM POINT_TBL; - f1 ------------------------ - (0,0),(0,0) - (-10,0),(-10,0) - (-3,4),(-3,4) - (5.1,34.5),(5.1,34.5) - (-5,-12),(-5,-12) - (10,10),(10,10) -(6 rows) - -SELECT bound_box(a.f1, b.f1) - FROM BOX_TBL a, BOX_TBL b; - bound_box ---------------------- - (2,2),(0,0) - (3,3),(0,0) - (2.5,3.5),(0,0) - (3,3),(0,0) - (3,3),(0,0) - (3,3),(1,1) - (3,3.5),(1,1) - (3,3),(1,1) - (2.5,3.5),(0,0) - (3,3.5),(1,1) - (2.5,3.5),(2.5,2.5) - (3,3.5),(2.5,2.5) - (3,3),(0,0) - (3,3),(1,1) - (3,3.5),(2.5,2.5) - (3,3),(3,3) -(16 rows) - --- --- Paths --- -SELECT '' AS eight, npoints(f1) AS npoints, f1 AS path FROM PATH_TBL; - eight | npoints | path --------+---------+--------------------------- - | 2 | [(1,2),(3,4)] - | 2 | ((1,2),(3,4)) - | 4 | [(0,0),(3,0),(4,5),(1,6)] - | 2 | ((1,2),(3,4)) - | 2 | ((1,2),(3,4)) - | 2 | [(1,2),(3,4)] - | 2 | [(11,12),(13,14)] - | 2 | ((11,12),(13,14)) -(8 rows) - -SELECT '' AS four, path(f1) FROM POLYGON_TBL; - four | path -------+--------------------- - | ((2,0),(2,4),(0,0)) - | ((3,1),(3,3),(1,0)) - | ((0,0)) - | ((0,1),(0,1)) -(4 rows) - --- translation -SELECT '' AS eight, p1.f1 + point '(10,10)' AS dist_add - FROM PATH_TBL p1; - eight | dist_add --------+----------------------------------- - | [(11,12),(13,14)] - | ((11,12),(13,14)) - | [(10,10),(13,10),(14,15),(11,16)] - | ((11,12),(13,14)) - | ((11,12),(13,14)) - | [(11,12),(13,14)] - | [(21,22),(23,24)] - | ((21,22),(23,24)) -(8 rows) - --- scaling and rotation -SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul - FROM PATH_TBL p1; - eight | dist_mul --------+------------------------------ - | [(4,3),(10,5)] - | ((4,3),(10,5)) - | [(0,0),(6,-3),(13,6),(8,11)] - | ((4,3),(10,5)) - | ((4,3),(10,5)) - | [(4,3),(10,5)] - | [(34,13),(40,15)] - | ((34,13),(40,15)) -(8 rows) - --- --- Polygons --- --- containment -SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains - FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contains -------------+------------+---------------------+---------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) - -SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained - FROM POLYGON_TBL poly, POINT_TBL p; - twentyfour | f1 | f1 | contained -------------+------------+---------------------+----------- - | (0,0) | ((2,0),(2,4),(0,0)) | t - | (0,0) | ((3,1),(3,3),(1,0)) | f - | (0,0) | ((0,0)) | t - | (0,0) | ((0,1),(0,1)) | f - | (-10,0) | ((2,0),(2,4),(0,0)) | f - | (-10,0) | ((3,1),(3,3),(1,0)) | f - | (-10,0) | ((0,0)) | f - | (-10,0) | ((0,1),(0,1)) | f - | (-3,4) | ((2,0),(2,4),(0,0)) | f - | (-3,4) | ((3,1),(3,3),(1,0)) | f - | (-3,4) | ((0,0)) | f - | (-3,4) | ((0,1),(0,1)) | f - | (5.1,34.5) | ((2,0),(2,4),(0,0)) | f - | (5.1,34.5) | ((3,1),(3,3),(1,0)) | f - | (5.1,34.5) | ((0,0)) | f - | (5.1,34.5) | ((0,1),(0,1)) | f - | (-5,-12) | ((2,0),(2,4),(0,0)) | f - | (-5,-12) | ((3,1),(3,3),(1,0)) | f - | (-5,-12) | ((0,0)) | f - | (-5,-12) | ((0,1),(0,1)) | f - | (10,10) | ((2,0),(2,4),(0,0)) | f - | (10,10) | ((3,1),(3,3),(1,0)) | f - | (10,10) | ((0,0)) | f - | (10,10) | ((0,1),(0,1)) | f -(24 rows) - -SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon - FROM POLYGON_TBL; - four | npoints | polygon -------+---------+--------------------- - | 3 | ((2,0),(2,4),(0,0)) - | 3 | ((3,1),(3,3),(1,0)) - | 1 | ((0,0)) - | 2 | ((0,1),(0,1)) -(4 rows) - -SELECT '' AS four, polygon(f1) - FROM BOX_TBL; - four | polygon -------+------------------------------------------- - | ((0,0),(0,2),(2,2),(2,0)) - | ((1,1),(1,3),(3,3),(3,1)) - | ((2.5,2.5),(2.5,3.5),(2.5,3.5),(2.5,2.5)) - | ((3,3),(3,3),(3,3),(3,3)) -(4 rows) - -SELECT '' AS four, polygon(f1) - FROM PATH_TBL WHERE isclosed(f1); - four | polygon -------+------------------- - | ((1,2),(3,4)) - | ((1,2),(3,4)) - | ((1,2),(3,4)) - | ((11,12),(13,14)) -(4 rows) - -SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon - FROM PATH_TBL - WHERE isopen(f1); - four | open_path | polygon -------+---------------------------+--------------------------- - | [(1,2),(3,4)] | ((1,2),(3,4)) - | [(0,0),(3,0),(4,5),(1,6)] | ((0,0),(3,0),(4,5),(1,6)) - | [(1,2),(3,4)] | ((1,2),(3,4)) - | [(11,12),(13,14)] | ((11,12),(13,14)) -(4 rows) - --- convert circles to polygons using the default number of points -SELECT '' AS six, polygon(f1) - FROM CIRCLE_TBL; - six | polygon ------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - | ((2,1),(2.40192378865,2.5),(3.5,3.59807621135),(5,4),(6.5,3.59807621135),(7.59807621135,2.5),(8,1),(7.59807621135,-0.5),(6.5,-1.59807621135),(5,-2),(3.5,-1.59807621135),(2.40192378865,-0.5)) - | ((-99,2),(-85.6025403784,52),(-49,88.6025403784),(1,102),(51,88.6025403784),(87.6025403784,52),(101,2),(87.6025403784,-48),(51,-84.6025403784),(1,-98),(-49,-84.6025403784),(-85.6025403784,-48)) - | ((-4,3),(-3.33012701892,5.5),(-1.5,7.33012701892),(1,8),(3.5,7.33012701892),(5.33012701892,5.5),(6,3),(5.33012701892,0.5),(3.5,-1.33012701892),(1,-2),(-1.5,-1.33012701892),(-3.33012701892,0.5)) - | ((-2,2),(-1.59807621135,3.5),(-0.5,4.59807621135),(1,5),(2.5,4.59807621135),(3.59807621135,3.5),(4,2),(3.59807621135,0.5),(2.5,-0.598076211353),(1,-1),(-0.5,-0.598076211353),(-1.59807621135,0.5)) - | ((90,200),(91.3397459622,205),(95,208.660254038),(100,210),(105,208.660254038),(108.660254038,205),(110,200),(108.660254038,195),(105,191.339745962),(100,190),(95,191.339745962),(91.3397459622,195)) - | ((-15,1),(0.40707856479,58.5),(42.5,100.592921435),(100,116),(157.5,100.592921435),(199.592921435,58.5),(215,1),(199.592921435,-56.5),(157.5,-98.5929214352),(100,-114),(42.5,-98.5929214352),(0.40707856479,-56.5)) -(6 rows) - --- convert the circle to an 8-point polygon -SELECT '' AS six, polygon(8, f1) - FROM CIRCLE_TBL; - six | polygon ------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ - | ((2,1),(2.87867965644,3.12132034356),(5,4),(7.12132034356,3.12132034356),(8,1),(7.12132034356,-1.12132034356),(5,-2),(2.87867965644,-1.12132034356)) - | ((-99,2),(-69.7106781187,72.7106781187),(1,102),(71.7106781187,72.7106781187),(101,2),(71.7106781187,-68.7106781187),(1,-98),(-69.7106781187,-68.7106781187)) - | ((-4,3),(-2.53553390593,6.53553390593),(1,8),(4.53553390593,6.53553390593),(6,3),(4.53553390593,-0.535533905933),(1,-2),(-2.53553390593,-0.535533905933)) - | ((-2,2),(-1.12132034356,4.12132034356),(1,5),(3.12132034356,4.12132034356),(4,2),(3.12132034356,-0.12132034356),(1,-1),(-1.12132034356,-0.12132034356)) - | ((90,200),(92.9289321881,207.071067812),(100,210),(107.071067812,207.071067812),(110,200),(107.071067812,192.928932188),(100,190),(92.9289321881,192.928932188)) - | ((-15,1),(18.6827201635,82.3172798365),(100,116),(181.317279836,82.3172798365),(215,1),(181.317279836,-80.3172798365),(100,-114),(18.6827201635,-80.3172798365)) -(6 rows) - --- --- Circles --- -SELECT '' AS six, circle(f1, 50.0) - FROM POINT_TBL; - six | circle ------+----------------- - | <(0,0),50> - | <(-10,0),50> - | <(-3,4),50> - | <(5.1,34.5),50> - | <(-5,-12),50> - | <(10,10),50> -(6 rows) - -SELECT '' AS four, circle(f1) - FROM BOX_TBL; - four | circle -------+----------------------- - | <(1,1),1.41421356237> - | <(2,2),1.41421356237> - | <(2.5,3),0.5> - | <(3,3),0> -(4 rows) - -SELECT '' AS two, circle(f1) - FROM POLYGON_TBL - WHERE (# f1) >= 3; - two | circle ------+----------------------------------------------- - | <(1.33333333333,1.33333333333),2.04168905064> - | <(2.33333333333,1.33333333333),1.47534300379> -(2 rows) - -SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS distance - FROM CIRCLE_TBL c1, POINT_TBL p1 - WHERE (p1.f1 <-> c1.f1) > 0 - ORDER BY distance, area(c1.f1), p1.f1[0]; - twentyfour | circle | point | distance -------------+----------------+------------+--------------- - | <(1,2),3> | (-3,4) | 1.472135955 - | <(5,1),3> | (0,0) | 2.09901951359 - | <(5,1),3> | (-3,4) | 5.54400374532 - | <(1,3),5> | (-10,0) | 6.40175425099 - | <(1,3),5> | (10,10) | 6.40175425099 - | <(5,1),3> | (10,10) | 7.29563014099 - | <(1,2),3> | (-10,0) | 8.1803398875 - | <(1,2),3> | (10,10) | 9.04159457879 - | <(1,3),5> | (-5,-12) | 11.1554944214 - | <(5,1),3> | (-10,0) | 12.0332963784 - | <(1,2),3> | (-5,-12) | 12.2315462117 - | <(5,1),3> | (-5,-12) | 13.4012194669 - | <(1,3),5> | (5.1,34.5) | 26.7657047773 - | <(1,2),3> | (5.1,34.5) | 29.7575945393 - | <(5,1),3> | (5.1,34.5) | 30.5001492534 - | <(100,200),10> | (5.1,34.5) | 180.778038568 - | <(100,200),10> | (10,10) | 200.237960416 - | <(100,200),10> | (-3,4) | 211.415898255 - | <(100,200),10> | (0,0) | 213.60679775 - | <(100,200),10> | (-10,0) | 218.25424421 - | <(100,200),10> | (-5,-12) | 226.577682802 -(21 rows) - diff --git a/src/test/regress/expected/gist.out b/src/test/regress/expected/gist.out index f5a2993aaf2..90edb4061d4 100644 --- a/src/test/regress/expected/gist.out +++ b/src/test/regress/expected/gist.out @@ -12,7 +12,7 @@ create index gist_pointidx4 on gist_point_tbl using gist(p) with (buffering = au drop index gist_pointidx2, gist_pointidx3, gist_pointidx4; -- Make sure bad values are refused create index gist_pointidx5 on gist_point_tbl using gist(p) with (buffering = invalid_value); -ERROR: invalid value for "buffering" option +ERROR: invalid value for enum option "buffering": invalid_value DETAIL: Valid values are "on", "off", and "auto". create index gist_pointidx5 on gist_point_tbl using gist(p) with (fillfactor=9); ERROR: value 9 out of bounds for option "fillfactor" @@ -27,10 +27,8 @@ insert into gist_point_tbl (id, p) select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g; -- To test vacuum, delete some entries from all over the index. delete from gist_point_tbl where id % 2 = 1; --- And also delete some concentration of values. (GiST doesn't currently --- attempt to delete pages even when they become empty, but if it did, this --- would exercise it) -delete from gist_point_tbl where id < 10000; +-- And also delete some concentration of values. +delete from gist_point_tbl where id > 5000; vacuum analyze gist_point_tbl; -- rebuild the index with a different fillfactor alter index gist_pointidx SET (fillfactor = 40); @@ -205,6 +203,82 @@ select b from gist_tbl where b <@ box(point(5,5), point(6,6)); (6,6),(6,6) (21 rows) +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + QUERY PLAN +------------------------------------------------------ + Index Only Scan using gist_tbl_box_index on gist_tbl + Index Cond: (b <@ '(6,6),(5,5)'::box) + Order By: (b <-> '(5.2,5.91)'::point) +(3 rows) + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + b +------------------------- + (5.55,5.55),(5.55,5.55) + (5.6,5.6),(5.6,5.6) + (5.5,5.5),(5.5,5.5) + (5.65,5.65),(5.65,5.65) + (5.45,5.45),(5.45,5.45) + (5.7,5.7),(5.7,5.7) + (5.4,5.4),(5.4,5.4) + (5.75,5.75),(5.75,5.75) + (5.35,5.35),(5.35,5.35) + (5.8,5.8),(5.8,5.8) + (5.3,5.3),(5.3,5.3) + (5.85,5.85),(5.85,5.85) + (5.25,5.25),(5.25,5.25) + (5.9,5.9),(5.9,5.9) + (5.2,5.2),(5.2,5.2) + (5.95,5.95),(5.95,5.95) + (5.15,5.15),(5.15,5.15) + (6,6),(6,6) + (5.1,5.1),(5.1,5.1) + (5.05,5.05),(5.05,5.05) + (5,5),(5,5) +(21 rows) + +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + QUERY PLAN +------------------------------------------------------ + Index Only Scan using gist_tbl_box_index on gist_tbl + Index Cond: (b <@ '(6,6),(5,5)'::box) + Order By: (b <-> '(5.2,5.91)'::point) +(3 rows) + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + b +------------------------- + (5.55,5.55),(5.55,5.55) + (5.6,5.6),(5.6,5.6) + (5.5,5.5),(5.5,5.5) + (5.65,5.65),(5.65,5.65) + (5.45,5.45),(5.45,5.45) + (5.7,5.7),(5.7,5.7) + (5.4,5.4),(5.4,5.4) + (5.75,5.75),(5.75,5.75) + (5.35,5.35),(5.35,5.35) + (5.8,5.8),(5.8,5.8) + (5.3,5.3),(5.3,5.3) + (5.85,5.85),(5.85,5.85) + (5.25,5.25),(5.25,5.25) + (5.9,5.9),(5.9,5.9) + (5.2,5.2),(5.2,5.2) + (5.95,5.95),(5.95,5.95) + (5.15,5.15),(5.15,5.15) + (6,6),(6,6) + (5.1,5.1),(5.1,5.1) + (5.05,5.05),(5.05,5.05) + (5,5),(5,5) +(21 rows) + drop index gist_tbl_box_index; -- Test that an index-only scan is not chosen, when the query involves the -- circle column (the circle opclass does not support index-only scans). diff --git a/src/test/regress/expected/groupingsets.out b/src/test/regress/expected/groupingsets.out index c7deec2ff40..c1f802c88a7 100644 --- a/src/test/regress/expected/groupingsets.out +++ b/src/test/regress/expected/groupingsets.out @@ -637,6 +637,19 @@ select a, b, sum(v.x) | | 9 (12 rows) +-- Test reordering of grouping sets +explain (costs off) +select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a; + QUERY PLAN +------------------------------------------------------------------------------ + GroupAggregate + Group Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 + Group Key: "*VALUES*".column3 + -> Sort + Sort Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 + -> Values Scan on "*VALUES*" +(6 rows) + -- Agg level check. This query should error out. select (select grouping(a,b) from gstest2) from gstest2 group by a,b; ERROR: arguments to GROUPING must be grouping expressions of the associated query level @@ -1347,6 +1360,61 @@ explain (costs off) -> Function Scan on gstest_data (10 rows) +-- Verify that we correctly handle the child node returning a +-- non-minimal slot, which happens if the input is pre-sorted, +-- e.g. due to an index scan. +BEGIN; +SET LOCAL enable_hashagg = false; +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + QUERY PLAN +--------------------------------------- + Sort + Sort Key: a, b + -> GroupAggregate + Group Key: a + Group Key: () + Sort Key: b + Group Key: b + -> Sort + Sort Key: a + -> Seq Scan on gstest3 +(10 rows) + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + a | b | count | max | max +---+---+-------+-----+----- + 1 | | 1 | 1 | 1 + 2 | | 1 | 2 | 2 + | 1 | 1 | 1 | 1 + | 2 | 1 | 2 | 2 + | | 2 | 2 | 2 +(5 rows) + +SET LOCAL enable_seqscan = false; +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + QUERY PLAN +------------------------------------------------------ + Sort + Sort Key: a, b + -> GroupAggregate + Group Key: a + Group Key: () + Sort Key: b + Group Key: b + -> Index Scan using gstest3_pkey on gstest3 +(8 rows) + +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; + a | b | count | max | max +---+---+-------+-----+----- + 1 | | 1 | 1 | 1 + 2 | | 1 | 2 | 2 + | 1 | 1 | 1 | 1 + | 2 | 1 | 2 | 2 + | | 2 | 2 | 2 +(5 rows) + +COMMIT; -- More rescan tests select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; a | a | four | ten | count @@ -1540,4 +1608,29 @@ explain (costs off) -> Seq Scan on tenk1 (12 rows) +-- check collation-sensitive matching between grouping expressions +-- (similar to a check for aggregates, but there are additional code +-- paths for GROUPING, so check again here) +select v||'a', case grouping(v||'a') when 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; + ?column? | case | count +----------+------+------- + aa | 0 | 1 + ba | 0 | 1 + | 1 | 2 + | 1 | 2 +(4 rows) + +select v||'a', case when grouping(v||'a') = 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; + ?column? | case | count +----------+------+------- + aa | 0 | 1 + ba | 0 | 1 + | 1 | 2 + | 1 | 2 +(4 rows) + -- end diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out index 43ac5f5f11c..811f80a0976 100644 --- a/src/test/regress/expected/guc.out +++ b/src/test/regress/expected/guc.out @@ -149,11 +149,11 @@ SELECT '2006-08-13 12:34:56'::timestamptz; (1 row) SAVEPOINT first_sp; -SET vacuum_cost_delay TO 80; +SET vacuum_cost_delay TO 80.1; SHOW vacuum_cost_delay; vacuum_cost_delay ------------------- - 80ms + 80100us (1 row) SET datestyle = 'German, DMY'; @@ -183,7 +183,7 @@ SELECT '2006-08-13 12:34:56'::timestamptz; (1 row) SAVEPOINT second_sp; -SET vacuum_cost_delay TO 90; +SET vacuum_cost_delay TO '900us'; SET datestyle = 'SQL, YMD'; SHOW datestyle; DateStyle @@ -222,7 +222,7 @@ ROLLBACK TO third_sp; SHOW vacuum_cost_delay; vacuum_cost_delay ------------------- - 90ms + 900us (1 row) SHOW datestyle; @@ -506,6 +506,11 @@ SELECT '2006-08-13 12:34:56'::timestamptz; Sun Aug 13 12:34:56 2006 PDT (1 row) +-- Test some simple error cases +SET seq_page_cost TO 'NaN'; +ERROR: invalid value for parameter "seq_page_cost": "NaN" +SET vacuum_cost_delay TO '10s'; +ERROR: 10000 ms is outside the valid range for parameter "vacuum_cost_delay" (0 .. 100) -- -- Test DISCARD TEMP -- @@ -767,3 +772,7 @@ NOTICE: text search configuration "no_such_config" does not exist select func_with_bad_set(); ERROR: invalid value for parameter "default_text_search_config": "no_such_config" reset check_function_bodies; +set default_with_oids to f; +-- Should not allow to set it to true. +set default_with_oids to t; +ERROR: tables declared WITH OIDS are not supported diff --git a/src/test/regress/expected/hash_part.out b/src/test/regress/expected/hash_part.out index 9e9e56f6fc4..8db316be27e 100644 --- a/src/test/regress/expected/hash_part.out +++ b/src/test/regress/expected/hash_part.out @@ -1,16 +1,11 @@ -- -- Hash partitioning. -- -CREATE OR REPLACE FUNCTION hashint4_noop(int4, int8) RETURNS int8 AS -$$SELECT coalesce($1,0)::int8$$ LANGUAGE sql IMMUTABLE; -CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING HASH AS -OPERATOR 1 = , FUNCTION 2 hashint4_noop(int4, int8); -CREATE OR REPLACE FUNCTION hashtext_length(text, int8) RETURNS int8 AS -$$SELECT length(coalesce($1,''))::int8$$ LANGUAGE sql IMMUTABLE; -CREATE OPERATOR CLASS test_text_ops FOR TYPE text USING HASH AS -OPERATOR 1 = , FUNCTION 2 hashtext_length(text, int8); +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. See the definitions of +-- part_part_test_int4_ops and part_test_text_ops in insert.sql. CREATE TABLE mchash (a int, b text, c jsonb) - PARTITION BY HASH (a test_int4_ops, b test_text_ops); + PARTITION BY HASH (a part_test_int4_ops, b part_test_text_ops); CREATE TABLE mchash1 PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0); -- invalid OID, no such table @@ -66,7 +61,7 @@ SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text); (1 row) -- ok, should be true -SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 1, ''::text); +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text); satisfies_hash_partition -------------------------- t @@ -79,7 +74,7 @@ SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, ERROR: column 2 of the partition key has type "text", but supplied value is of type "integer" -- multiple partitioning columns of the same type CREATE TABLE mcinthash (a int, b int, c jsonb) - PARTITION BY HASH (a test_int4_ops, b test_int4_ops); + PARTITION BY HASH (a part_test_int4_ops, b part_test_int4_ops); -- now variadic should work, should be false SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, variadic array[0, 0]); @@ -90,7 +85,7 @@ SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, -- should be true SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, - variadic array[1, 0]); + variadic array[0, 1]); satisfies_hash_partition -------------------------- t @@ -104,10 +99,20 @@ ERROR: number of partitioning columns (2) does not match number of partition ke SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, variadic array[now(), now()]); ERROR: column 1 of the partition key has type "integer", but supplied value is of type "timestamp with time zone" +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a); +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0); +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1); +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies; + satisfies +----------- + t +(1 row) + -- cleanup DROP TABLE mchash; DROP TABLE mcinthash; -DROP OPERATOR CLASS test_text_ops USING hash; -DROP OPERATOR CLASS test_int4_ops USING hash; -DROP FUNCTION hashint4_noop(int4, int8); -DROP FUNCTION hashtext_length(text, int8); +DROP TABLE text_hashp; diff --git a/src/test/regress/expected/horology.out b/src/test/regress/expected/horology.out index 63e39198e68..6b53876e062 100644 --- a/src/test/regress/expected/horology.out +++ b/src/test/regress/expected/horology.out @@ -2046,70 +2046,6 @@ SELECT '' AS "226", d1.f1 AS timestamp1, d2.f1 AS timestamp2, d1.f1 - d2.f1 AS d | Sat Sep 22 18:19:20 2001 PDT | Sat Sep 22 18:19:20 2001 PDT | @ 0 (256 rows) --- --- abstime, reltime arithmetic --- -SELECT '' AS ten, ABSTIME_TBL.f1 AS abstime, RELTIME_TBL.f1 AS reltime - FROM ABSTIME_TBL, RELTIME_TBL - WHERE (ABSTIME_TBL.f1 + RELTIME_TBL.f1) < abstime 'Jan 14 14:00:00 1971' - ORDER BY abstime, reltime; - ten | abstime | reltime ------+------------------------------+--------------- - | Sat May 10 23:59:12 1947 PST | @ 14 secs ago - | Sat May 10 23:59:12 1947 PST | @ 1 min - | Sat May 10 23:59:12 1947 PST | @ 5 hours - | Sat May 10 23:59:12 1947 PST | @ 10 days - | Sat May 10 23:59:12 1947 PST | @ 3 mons - | Wed Dec 31 16:00:00 1969 PST | @ 14 secs ago - | Wed Dec 31 16:00:00 1969 PST | @ 1 min - | Wed Dec 31 16:00:00 1969 PST | @ 5 hours - | Wed Dec 31 16:00:00 1969 PST | @ 10 days - | Wed Dec 31 16:00:00 1969 PST | @ 3 mons -(10 rows) - --- these four queries should return the same answer --- the "infinity" and "-infinity" tuples in ABSTIME_TBL cannot be added and --- therefore, should not show up in the results. -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 + reltime '@ 3 year') -- +3 years - < abstime 'Jan 14 14:00:00 1977'; - three | f1 --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Wed Dec 31 16:00:00 1969 PST - | Sat May 10 23:59:12 1947 PST -(3 rows) - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 + reltime '@ 3 year ago') -- -3 years - < abstime 'Jan 14 14:00:00 1971'; - three | f1 --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Wed Dec 31 16:00:00 1969 PST - | Sat May 10 23:59:12 1947 PST -(3 rows) - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 - reltime '@ 3 year') -- -(+3) years - < abstime 'Jan 14 14:00:00 1971'; - three | f1 --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Wed Dec 31 16:00:00 1969 PST - | Sat May 10 23:59:12 1947 PST -(3 rows) - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 - reltime '@ 3 year ago') -- -(-3) years - < abstime 'Jan 14 14:00:00 1977'; - three | f1 --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Wed Dec 31 16:00:00 1969 PST - | Sat May 10 23:59:12 1947 PST -(3 rows) - -- -- Conversions -- @@ -2137,80 +2073,6 @@ SELECT '' AS "16", f1 AS "timestamp", date(f1) AS date | Sat Sep 22 18:19:20 2001 PDT | 09-22-2001 (16 rows) -SELECT '' AS "16", f1 AS "timestamp", abstime(f1) AS abstime - FROM TEMP_TIMESTAMP - ORDER BY abstime; - 16 | timestamp | abstime -----+------------------------------+------------------------------ - | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 PST - | Wed Feb 28 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST - | Fri Dec 31 17:32:01 1999 PST | Fri Dec 31 17:32:01 1999 PST - | Sat Jan 01 17:32:01 2000 PST | Sat Jan 01 17:32:01 2000 PST - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 02:14:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 03:14:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 08:14:01 2000 PST - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 12:14:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 13:14:02 2000 PST - | Sun Dec 31 17:32:01 2000 PST | Sun Dec 31 17:32:01 2000 PST - | Mon Jan 01 17:32:01 2001 PST | Mon Jan 01 17:32:01 2001 PST - | Sat Sep 22 18:19:20 2001 PDT | Sat Sep 22 18:19:20 2001 PDT -(16 rows) - -SELECT '' AS four, f1 AS abstime, date(f1) AS date - FROM ABSTIME_TBL - WHERE isfinite(f1) AND f1 <> abstime 'now' - ORDER BY date, abstime; - four | abstime | date -------+------------------------------+------------ - | Sat May 10 23:59:12 1947 PST | 05-10-1947 - | Wed Dec 31 16:00:00 1969 PST | 12-31-1969 - | Sun Jan 14 03:14:21 1973 PST | 01-14-1973 - | Mon May 01 00:30:30 1995 PDT | 05-01-1995 -(4 rows) - -SELECT '' AS two, d1 AS "timestamp", abstime(d1) AS abstime - FROM TIMESTAMP_TBL WHERE NOT isfinite(d1); - two | timestamp | abstime ------+-----------+----------- - | -infinity | -infinity - | infinity | infinity -(2 rows) - -SELECT '' AS three, f1 as abstime, cast(f1 as timestamp) AS "timestamp" - FROM ABSTIME_TBL WHERE NOT isfinite(f1); -ERROR: cannot convert abstime "invalid" to timestamp -SELECT '' AS ten, f1 AS interval, reltime(f1) AS reltime - FROM INTERVAL_TBL; - ten | interval | reltime ------+-------------------------------+------------------------------- - | @ 1 min | @ 1 min - | @ 5 hours | @ 5 hours - | @ 10 days | @ 10 days - | @ 34 years | @ 34 years - | @ 3 mons | @ 3 mons - | @ 14 secs ago | @ 14 secs ago - | @ 1 day 2 hours 3 mins 4 secs | @ 1 day 2 hours 3 mins 4 secs - | @ 6 years | @ 6 years - | @ 5 mons | @ 5 mons - | @ 5 mons 12 hours | @ 5 mons 12 hours -(10 rows) - -SELECT '' AS six, f1 as reltime, CAST(f1 AS interval) AS interval - FROM RELTIME_TBL; - six | reltime | interval ------+---------------+--------------- - | @ 1 min | @ 1 min - | @ 5 hours | @ 5 hours - | @ 10 days | @ 10 days - | @ 34 years | @ 34 years - | @ 3 mons | @ 3 mons - | @ 14 secs ago | @ 14 secs ago -(6 rows) - DROP TABLE TEMP_TIMESTAMP; -- -- Formats @@ -2292,18 +2154,6 @@ SELECT '' AS "64", d1 AS us_postgres FROM TIMESTAMP_TBL; | Mon Jan 01 17:32:01 2001 (65 rows) -SELECT '' AS seven, f1 AS us_postgres FROM ABSTIME_TBL; - seven | us_postgres --------+------------------------------ - | Sun Jan 14 03:14:21 1973 PST - | Mon May 01 00:30:30 1995 PDT - | Wed Dec 31 16:00:00 1969 PST - | infinity - | -infinity - | Sat May 10 23:59:12 1947 PST - | invalid -(7 rows) - SET DateStyle TO 'US,ISO'; SELECT '' AS "64", d1 AS us_iso FROM TIMESTAMP_TBL; 64 | us_iso @@ -2375,18 +2225,6 @@ SELECT '' AS "64", d1 AS us_iso FROM TIMESTAMP_TBL; | 2001-01-01 17:32:01 (65 rows) -SELECT '' AS seven, f1 AS us_iso FROM ABSTIME_TBL; - seven | us_iso --------+------------------------ - | 1973-01-14 03:14:21-08 - | 1995-05-01 00:30:30-07 - | 1969-12-31 16:00:00-08 - | infinity - | -infinity - | 1947-05-10 23:59:12-08 - | invalid -(7 rows) - SET DateStyle TO 'US,SQL'; SHOW DateStyle; DateStyle @@ -2464,18 +2302,6 @@ SELECT '' AS "64", d1 AS us_sql FROM TIMESTAMP_TBL; | 01/01/2001 17:32:01 (65 rows) -SELECT '' AS seven, f1 AS us_sql FROM ABSTIME_TBL; - seven | us_sql --------+------------------------- - | 01/14/1973 03:14:21 PST - | 05/01/1995 00:30:30 PDT - | 12/31/1969 16:00:00 PST - | infinity - | -infinity - | 05/10/1947 23:59:12 PST - | invalid -(7 rows) - SET DateStyle TO 'European,Postgres'; SHOW DateStyle; DateStyle @@ -2561,18 +2387,6 @@ SELECT '' AS "65", d1 AS european_postgres FROM TIMESTAMP_TBL; | Thu 13 Jun 00:00:00 1957 (66 rows) -SELECT '' AS seven, f1 AS european_postgres FROM ABSTIME_TBL; - seven | european_postgres --------+------------------------------ - | Sun 14 Jan 03:14:21 1973 PST - | Mon 01 May 00:30:30 1995 PDT - | Wed 31 Dec 16:00:00 1969 PST - | infinity - | -infinity - | Sat 10 May 23:59:12 1947 PST - | invalid -(7 rows) - SET DateStyle TO 'European,ISO'; SHOW DateStyle; DateStyle @@ -2651,18 +2465,6 @@ SELECT '' AS "65", d1 AS european_iso FROM TIMESTAMP_TBL; | 1957-06-13 00:00:00 (66 rows) -SELECT '' AS seven, f1 AS european_iso FROM ABSTIME_TBL; - seven | european_iso --------+------------------------ - | 1973-01-14 03:14:21-08 - | 1995-05-01 00:30:30-07 - | 1969-12-31 16:00:00-08 - | infinity - | -infinity - | 1947-05-10 23:59:12-08 - | invalid -(7 rows) - SET DateStyle TO 'European,SQL'; SHOW DateStyle; DateStyle @@ -2741,18 +2543,6 @@ SELECT '' AS "65", d1 AS european_sql FROM TIMESTAMP_TBL; | 13/06/1957 00:00:00 (66 rows) -SELECT '' AS seven, f1 AS european_sql FROM ABSTIME_TBL; - seven | european_sql --------+------------------------- - | 14/01/1973 03:14:21 PST - | 01/05/1995 00:30:30 PDT - | 31/12/1969 16:00:00 PST - | infinity - | -infinity - | 10/05/1947 23:59:12 PST - | invalid -(7 rows) - RESET DateStyle; -- -- to_timestamp() @@ -2769,14 +2559,32 @@ SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS'); Sat Feb 16 08:14:30 0097 PST (1 row) +SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS'); + to_timestamp +------------------------------ + Fri Mar 18 23:38:15 2011 PDT +(1 row) + SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD'); to_timestamp ------------------------------ Sat Jan 12 00:00:00 1985 PST (1 row) +SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD'); + to_timestamp +------------------------------ + Sat Jan 12 00:00:00 1985 PST +(1 row) + +SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD'); + to_timestamp +------------------------------ + Sat Jan 12 00:00:00 1985 PST +(1 row) + SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', - '"My birthday-> Year" YYYY, "Month:" FMMonth, "Day:" DD'); + '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD'); to_timestamp ------------------------------ Sun May 16 00:00:00 1976 PDT @@ -2789,7 +2597,7 @@ SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); (1 row) SELECT to_timestamp('15 "text between quote marks" 98 54 45', - E'HH24 "\\text between quote marks\\"" YY MI SS'); + E'HH24 "\\"text between quote marks\\"" YY MI SS'); to_timestamp ------------------------------ Thu Jan 01 15:54:45 1998 PST @@ -2810,6 +2618,24 @@ SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay'); SELECT to_timestamp('97/Feb/16', 'YYMonDD'); ERROR: invalid value "/Fe" for "Mon" DETAIL: The given value did not match any of the allowed values for this field. +SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD'); + to_timestamp +------------------------------ + Sun Feb 16 00:00:00 1997 PST +(1 row) + +SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD'); + to_timestamp +------------------------------ + Sun Feb 16 00:00:00 1997 PST +(1 row) + +SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD'); + to_timestamp +------------------------------ + Sun Feb 16 00:00:00 1997 PST +(1 row) + SELECT to_timestamp('19971116', 'YYYYMMDD'); to_timestamp ------------------------------ @@ -2960,13 +2786,92 @@ SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM'); Sun Dec 18 03:18:00 2011 PST (1 row) +SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+------------------------------ + 1 | Fri Nov 02 12:34:56 2018 PDT + 2 | Fri Nov 02 12:34:56 2018 PDT + 3 | Fri Nov 02 12:34:56 2018 PDT + 4 | Fri Nov 02 12:34:56 2018 PDT + 5 | Fri Nov 02 12:34:56 2018 PDT + 6 | Fri Nov 02 12:34:56 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.1', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+-------------------------------- + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.1 2018 PDT + 3 | Fri Nov 02 12:34:56.1 2018 PDT + 4 | Fri Nov 02 12:34:56.1 2018 PDT + 5 | Fri Nov 02 12:34:56.1 2018 PDT + 6 | Fri Nov 02 12:34:56.1 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.12', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+--------------------------------- + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.12 2018 PDT + 3 | Fri Nov 02 12:34:56.12 2018 PDT + 4 | Fri Nov 02 12:34:56.12 2018 PDT + 5 | Fri Nov 02 12:34:56.12 2018 PDT + 6 | Fri Nov 02 12:34:56.12 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.123', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+---------------------------------- + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.12 2018 PDT + 3 | Fri Nov 02 12:34:56.123 2018 PDT + 4 | Fri Nov 02 12:34:56.123 2018 PDT + 5 | Fri Nov 02 12:34:56.123 2018 PDT + 6 | Fri Nov 02 12:34:56.123 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.1234', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+----------------------------------- + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.12 2018 PDT + 3 | Fri Nov 02 12:34:56.123 2018 PDT + 4 | Fri Nov 02 12:34:56.1234 2018 PDT + 5 | Fri Nov 02 12:34:56.1234 2018 PDT + 6 | Fri Nov 02 12:34:56.1234 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.12345', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+------------------------------------ + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.12 2018 PDT + 3 | Fri Nov 02 12:34:56.123 2018 PDT + 4 | Fri Nov 02 12:34:56.1235 2018 PDT + 5 | Fri Nov 02 12:34:56.12345 2018 PDT + 6 | Fri Nov 02 12:34:56.12345 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.123456', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + i | to_timestamp +---+------------------------------------- + 1 | Fri Nov 02 12:34:56.1 2018 PDT + 2 | Fri Nov 02 12:34:56.12 2018 PDT + 3 | Fri Nov 02 12:34:56.123 2018 PDT + 4 | Fri Nov 02 12:34:56.1235 2018 PDT + 5 | Fri Nov 02 12:34:56.12346 2018 PDT + 6 | Fri Nov 02 12:34:56.123456 2018 PDT +(6 rows) + +SELECT i, to_timestamp('2018-11-02 12:34:56.123456789', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +ERROR: date/time field value out of range: "2018-11-02 12:34:56.123456789" -- -- Check handling of multiple spaces in format and/or input -- SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); to_timestamp ------------------------------ - Sun Dec 18 03:38:15 2011 PST + Sun Dec 18 23:38:15 2011 PST (1 row) SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); @@ -2996,7 +2901,64 @@ SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); to_timestamp ------------------------------ - Sun Dec 18 03:38:15 2011 PST + Sun Dec 18 23:38:15 2011 PST +(1 row) + +SELECT to_timestamp('2000+ JUN', 'YYYY/MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp('2000 +JUN', 'YYYY//MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp('2000 + JUN', 'YYYY MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp('2000 ++ JUN', 'YYYY MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); +ERROR: invalid value "+ J" for "MON" +DETAIL: The given value did not match any of the allowed values for this field. +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); + to_timestamp +------------------------------ + Thu Jun 01 00:00:00 2000 PDT +(1 row) + +SELECT to_timestamp('2000 -10', 'YYYY TZH'); + to_timestamp +------------------------------ + Sat Jan 01 02:00:00 2000 PST +(1 row) + +SELECT to_timestamp('2000 -10', 'YYYY TZH'); + to_timestamp +------------------------------ + Fri Dec 31 06:00:00 1999 PST (1 row) SELECT to_date('2011 12 18', 'YYYY MM DD'); @@ -3014,13 +2976,13 @@ SELECT to_date('2011 12 18', 'YYYY MM DD'); SELECT to_date('2011 12 18', 'YYYY MM DD'); to_date ------------ - 12-08-2011 + 12-18-2011 (1 row) SELECT to_date('2011 12 18', 'YYYY MM DD'); to_date ------------ - 02-18-2011 + 12-18-2011 (1 row) SELECT to_date('2011 12 18', 'YYYY MM DD'); @@ -3035,6 +2997,21 @@ SELECT to_date('2011 12 18', 'YYYY MM DD'); 12-18-2011 (1 row) +SELECT to_date('2011 12 18', 'YYYYxMMxDD'); + to_date +------------ + 12-18-2011 +(1 row) + +SELECT to_date('2011x 12x 18', 'YYYYxMMxDD'); + to_date +------------ + 12-18-2011 +(1 row) + +SELECT to_date('2011 x12 x18', 'YYYYxMMxDD'); +ERROR: invalid value "x1" for "MM" +DETAIL: Value must be an integer. -- -- Check errors for some incorrect usages of to_timestamp() and to_date() -- @@ -3100,6 +3077,14 @@ SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS'); -- ok SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS'); ERROR: date/time field value out of range: "2015-02-11 86400" +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS'); -- ok + to_timestamp +------------------------------ + Wed Feb 11 23:53:20 2015 PST +(1 row) + +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS'); +ERROR: date/time field value out of range: "2015-02-11 86400" SELECT to_date('2016-13-10', 'YYYY-MM-DD'); ERROR: date/time field value out of range: "2016-13-10" SELECT to_date('2016-02-30', 'YYYY-MM-DD'); @@ -3163,4 +3148,16 @@ SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); 2012-12-12 12:00:00 -01:30 (1 row) +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS'); + to_char +------------------ + 2012-12-12 43200 +(1 row) + +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS'); + to_char +------------------ + 2012-12-12 43200 +(1 row) + RESET TIME ZONE; diff --git a/src/test/regress/expected/hs_standby_allowed.out b/src/test/regress/expected/hs_standby_allowed.out index 526f88f2bec..00b8faf9eb6 100644 --- a/src/test/regress/expected/hs_standby_allowed.out +++ b/src/test/regress/expected/hs_standby_allowed.out @@ -208,6 +208,9 @@ LOCK hs1 IN ACCESS SHARE MODE; LOCK hs1 IN ROW SHARE MODE; LOCK hs1 IN ROW EXCLUSIVE MODE; COMMIT; +-- UNLISTEN +UNLISTEN a; +UNLISTEN *; -- LOAD -- should work, easier if there is no test for that... -- ALLOWED COMMANDS diff --git a/src/test/regress/expected/hs_standby_disallowed.out b/src/test/regress/expected/hs_standby_disallowed.out index bc117413ffd..dff0953e9a6 100644 --- a/src/test/regress/expected/hs_standby_disallowed.out +++ b/src/test/regress/expected/hs_standby_disallowed.out @@ -118,10 +118,6 @@ listen a; ERROR: cannot execute LISTEN during recovery notify a; ERROR: cannot execute NOTIFY during recovery -unlisten a; -ERROR: cannot execute UNLISTEN during recovery -unlisten *; -ERROR: cannot execute UNLISTEN during recovery -- disallowed commands ANALYZE hs1; ERROR: cannot execute ANALYZE during recovery diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out index 3a6016c80a6..36a239363a9 100644 --- a/src/test/regress/expected/identity.out +++ b/src/test/regress/expected/identity.out @@ -250,6 +250,7 @@ SELECT * FROM itestv11; 11 | xyz (3 rows) +DROP VIEW itestv10, itestv11; -- ADD COLUMN CREATE TABLE itest13 (a int); -- add column to empty table @@ -289,6 +290,18 @@ SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regcl ALTER TABLE itest3 ALTER COLUMN a TYPE text; -- error ERROR: identity column type must be smallint, integer, or bigint +-- kinda silly to change property in the same command, but it should work +ALTER TABLE itest3 + ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, + ALTER COLUMN c SET GENERATED ALWAYS; +\d itest3 + Table "public.itest3" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+---------------------------------- + a | integer | | not null | generated by default as identity + b | text | | | + c | integer | | not null | generated always as identity + -- ALTER COLUMN ... SET CREATE TABLE itest6 (a int GENERATED ALWAYS AS IDENTITY, b text); INSERT INTO itest6 DEFAULT VALUES; @@ -386,58 +399,8 @@ CREATE TABLE itest_child PARTITION OF itest_parent ( ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error ERROR: identity columns are not supported on partitions DROP TABLE itest_parent; --- MERGE tests -CREATE TABLE itest14 (a int GENERATED ALWAYS AS IDENTITY, b text); -CREATE TABLE itest15 (a int GENERATED BY DEFAULT AS IDENTITY, b text); -MERGE INTO itest14 t -USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) VALUES (s.s_a, s.s_b); -ERROR: cannot insert into column "a" -DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS. -HINT: Use OVERRIDING SYSTEM VALUE to override. -MERGE INTO itest14 t -USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b); -ERROR: cannot insert into column "a" -DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS. -HINT: Use OVERRIDING SYSTEM VALUE to override. -MERGE INTO itest14 t -USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b); -MERGE INTO itest15 t -USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) VALUES (s.s_a, s.s_b); -MERGE INTO itest15 t -USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b); -MERGE INTO itest15 t -USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b); -SELECT * FROM itest14; - a | b -----+------------------- - 30 | inserted by merge -(1 row) - -SELECT * FROM itest15; - a | b -----+------------------- - 10 | inserted by merge - 1 | inserted by merge - 30 | inserted by merge -(3 rows) - -DROP TABLE itest14; -DROP TABLE itest15; +-- test that sequence of half-dropped serial column is properly ignored +CREATE TABLE itest14 (id serial); +ALTER TABLE itest14 ALTER id DROP DEFAULT; +ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY; +INSERT INTO itest14 (id) VALUES (DEFAULT); diff --git a/src/test/regress/expected/index_including.out b/src/test/regress/expected/index_including.out index 1d253ee77d6..2405709f409 100644 --- a/src/test/regress/expected/index_including.out +++ b/src/test/regress/expected/index_including.out @@ -1,81 +1,88 @@ /* * 1.test CREATE INDEX + * + * Deliberately avoid dropping objects in this section, to get some pg_dump + * coverage. */ -- Regular index with included columns -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c3,c4); --- must fail because of intersection of key and included columns -CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c1,c3); -ERROR: included columns must not intersect with key columns +CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE INDEX tbl_include_reg_idx ON tbl_include_reg (c1, c2) INCLUDE (c3, c4); +-- duplicate column is pretty pointless, but we allow it anyway +CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; - pg_get_indexdef --------------------------------------------------------------------------- - CREATE INDEX tbl_idx ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4) -(1 row) +WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname; + pg_get_indexdef +--------------------------------------------------------------------------------------------------------------- + CREATE INDEX tbl_include_reg_c1_c2_c11_c3_idx ON public.tbl_include_reg USING btree (c1, c2) INCLUDE (c1, c3) + CREATE INDEX tbl_include_reg_idx ON public.tbl_include_reg USING btree (c1, c2) INCLUDE (c3, c4) +(2 rows) + +\d tbl_include_reg_idx + Index "public.tbl_include_reg_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + c1 | integer | yes | c1 + c2 | integer | yes | c2 + c3 | integer | no | c3 + c4 | box | no | c4 +btree, for table "public.tbl_include_reg" -DROP TABLE tbl; -- Unique index and unique constraint -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique; -ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4); +CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4); +ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique; +ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; - pg_get_indexdef ---------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX tbl_c1_c2_c3_c4_key ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4) - CREATE UNIQUE INDEX tbl_idx_unique ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4) +WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname; + pg_get_indexdef +----------------------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX tbl_include_unique1_c1_c2_c3_c4_key ON public.tbl_include_unique1 USING btree (c1, c2) INCLUDE (c3, c4) + CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON public.tbl_include_unique1 USING btree (c1, c2) INCLUDE (c3, c4) (2 rows) -DROP TABLE tbl; -- Unique index and unique constraint. Both must fail. -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ERROR: could not create unique index "tbl_idx_unique" +CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4); +ERROR: could not create unique index "tbl_include_unique2_idx_unique" DETAIL: Key (c1, c2)=(1, 2) is duplicated. -ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4); -ERROR: could not create unique index "tbl_c1_c2_c3_c4_key" +ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4); +ERROR: could not create unique index "tbl_include_unique2_c1_c2_c3_c4_key" DETAIL: Key (c1, c2)=(1, 2) is duplicated. -DROP TABLE tbl; -- PK constraint -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); +CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; - pg_get_indexdef ----------------------------------------------------------------------------------- - CREATE UNIQUE INDEX tbl_pkey ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4) +WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname; + pg_get_indexdef +-------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX tbl_include_pk_pkey ON public.tbl_include_pk USING btree (c1, c2) INCLUDE (c3, c4) (1 row) -DROP TABLE tbl; -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique; +CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4); +ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique; SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; - pg_get_indexdef ----------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX tbl_idx_unique ON public.tbl USING btree (c1, c2) INCLUDE (c3, c4) +WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname; + pg_get_indexdef +---------------------------------------------------------------------------------------------------------------- + CREATE UNIQUE INDEX tbl_include_box_idx_unique ON public.tbl_include_box USING btree (c1, c2) INCLUDE (c3, c4) (1 row) -DROP TABLE tbl; -- PK constraint. Must fail. -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); -ERROR: could not create unique index "tbl_pkey" +CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); +ERROR: could not create unique index "tbl_include_box_pk_pkey" DETAIL: Key (c1, c2)=(1, 2) is duplicated. -DROP TABLE tbl; /* * 2. Test CREATE TABLE with constraint */ @@ -87,10 +94,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i covering | 4 | 2 | t | f | 1 2 3 4 | 1978 1978 (1 row) -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; - pg_get_constraintdef | conname | conkey | conincluding -----------------------------------+----------+--------+-------------- - UNIQUE (c1, c2) INCLUDE (c3, c4) | covering | {1,2} | {3,4} +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + pg_get_constraintdef | conname | conkey +----------------------------------+----------+-------- + UNIQUE (c1, c2) INCLUDE (c3, c4) | covering | {1,2} (1 row) -- ensure that constraint works @@ -106,10 +113,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i covering | 4 | 2 | t | t | 1 2 3 4 | 1978 1978 (1 row) -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; - pg_get_constraintdef | conname | conkey | conincluding ----------------------------------------+----------+--------+-------------- - PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | covering | {1,2} | {3,4} +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + pg_get_constraintdef | conname | conkey +---------------------------------------+----------+-------- + PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | covering | {1,2} (1 row) -- ensure that constraint works @@ -119,8 +126,44 @@ DETAIL: Key (c1, c2)=(1, 2) already exists. INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; ERROR: null value in column "c2" violates not-null constraint DETAIL: Failing row contains (1, null, 3, (4,4),(4,4)). -INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x; +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x; +explain (costs off) +select * from tbl where (c1,c2,c3) < (2,5,1); + QUERY PLAN +------------------------------------------------ + Bitmap Heap Scan on tbl + Filter: (ROW(c1, c2, c3) < ROW(2, 5, 1)) + -> Bitmap Index Scan on covering + Index Cond: (ROW(c1, c2) <= ROW(2, 5)) +(4 rows) + +select * from tbl where (c1,c2,c3) < (2,5,1); + c1 | c2 | c3 | c4 +----+----+----+---- + 1 | 2 | | + 2 | 4 | | +(2 rows) + +-- row comparison that compares high key at page boundary +SET enable_seqscan = off; +explain (costs off) +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; + QUERY PLAN +---------------------------------------------------- + Limit + -> Index Only Scan using covering on tbl + Index Cond: (ROW(c1, c2) <= ROW(262, 1)) + Filter: (ROW(c1, c2, c3) < ROW(262, 1, 1)) +(4 rows) + +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; + c1 | c2 | c3 | c4 +----+----+----+---- + 1 | 2 | | +(1 row) + DROP TABLE tbl; +RESET enable_seqscan; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1,c2) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; @@ -129,10 +172,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i tbl_c1_c2_c3_c4_key | 4 | 2 | t | f | 1 2 3 4 | 1978 1978 (1 row) -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; - pg_get_constraintdef | conname | conkey | conincluding -----------------------------------+---------------------+--------+-------------- - UNIQUE (c1, c2) INCLUDE (c3, c4) | tbl_c1_c2_c3_c4_key | {1,2} | {3,4} +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + pg_get_constraintdef | conname | conkey +----------------------------------+---------------------+-------- + UNIQUE (c1, c2) INCLUDE (c3, c4) | tbl_c1_c2_c3_c4_key | {1,2} (1 row) -- ensure that constraint works @@ -148,10 +191,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i tbl_pkey | 4 | 2 | t | t | 1 2 3 4 | 1978 1978 (1 row) -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; - pg_get_constraintdef | conname | conkey | conincluding ----------------------------------------+----------+--------+-------------- - PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | tbl_pkey | {1,2} | {3,4} +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + pg_get_constraintdef | conname | conkey +---------------------------------------+----------+-------- + PRIMARY KEY (c1, c2) INCLUDE (c3, c4) | tbl_pkey | {1,2} (1 row) -- ensure that constraint works @@ -171,10 +214,10 @@ SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, i tbl_c1_c3_c4_excl | 3 | 1 | f | f | 1 3 4 | 1978 (1 row) -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; - pg_get_constraintdef | conname | conkey | conincluding ---------------------------------------------------+-------------------+--------+-------------- - EXCLUDE USING btree (c1 WITH =) INCLUDE (c3, c4) | tbl_c1_c3_c4_excl | {1} | {3,4} +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; + pg_get_constraintdef | conname | conkey +--------------------------------------------------+-------------------+-------- + EXCLUDE USING btree (c1 WITH =) INCLUDE (c3, c4) | tbl_c1_c3_c4_excl | {1} (1 row) -- ensure that constraint works @@ -246,6 +289,20 @@ SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; ---------- (0 rows) +DROP TABLE tbl; +/* + * 3.3 Test ALTER TABLE SET STATISTICS + */ +CREATE TABLE tbl (c1 int, c2 int); +CREATE INDEX tbl_idx ON tbl (c1, (c1+0)) INCLUDE (c2); +ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000; +ERROR: cannot alter statistics on non-expression column "c1" of index "tbl_idx" +HINT: Alter statistics on table column instead. +ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000; +ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000; +ERROR: cannot alter statistics on included column "c2" of index "tbl_idx" +ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000; +ERROR: column number 4 of relation "tbl_idx" does not exist DROP TABLE tbl; /* * 4. CREATE INDEX CONCURRENTLY @@ -292,22 +349,20 @@ SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; DROP TABLE tbl; /* - * 7. Check various AMs. All but btree must fail. + * 7. Check various AMs. All but btree and gist must fail. */ CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box); CREATE INDEX on tbl USING brin(c1, c2) INCLUDE (c3, c4); ERROR: access method "brin" does not support included columns -CREATE INDEX on tbl USING gist(c3) INCLUDE (c4); -ERROR: access method "gist" does not support included columns +CREATE INDEX on tbl USING gist(c3) INCLUDE (c1, c4); CREATE INDEX on tbl USING spgist(c3) INCLUDE (c4); ERROR: access method "spgist" does not support included columns CREATE INDEX on tbl USING gin(c1, c2) INCLUDE (c3, c4); ERROR: access method "gin" does not support included columns CREATE INDEX on tbl USING hash(c1, c2) INCLUDE (c3, c4); ERROR: access method "hash" does not support included columns -CREATE INDEX on tbl USING rtree(c1, c2) INCLUDE (c3, c4); +CREATE INDEX on tbl USING rtree(c3) INCLUDE (c1, c4); NOTICE: substituting access method "gist" for obsolete method "rtree" -ERROR: access method "gist" does not support included columns CREATE INDEX on tbl USING btree(c1, c2) INCLUDE (c3, c4); DROP TABLE tbl; /* diff --git a/src/test/regress/expected/index_including_gist.out b/src/test/regress/expected/index_including_gist.out new file mode 100644 index 00000000000..ed9906da669 --- /dev/null +++ b/src/test/regress/expected/index_including_gist.out @@ -0,0 +1,166 @@ +/* + * 1.1. test CREATE INDEX with buffered build + */ +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +-- size is chosen to exceed page size and trigger actual truncation +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; + pg_get_indexdef +----------------------------------------------------------------------------------- + CREATE INDEX tbl_gist_idx ON public.tbl_gist USING gist (c4) INCLUDE (c1, c2, c3) +(1 row) + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + c1 | c2 | c3 | c4 +----+----+----+------------- + 1 | 2 | 3 | (2,3),(1,2) + 2 | 4 | 6 | (4,5),(2,3) + 3 | 6 | 9 | (6,7),(3,4) + 4 | 8 | 12 | (8,9),(4,5) +(4 rows) + +SET enable_bitmapscan TO off; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + QUERY PLAN +------------------------------------------------ + Index Only Scan using tbl_gist_idx on tbl_gist + Index Cond: (c4 <@ '(10,10),(1,1)'::box) +(2 rows) + +SET enable_bitmapscan TO default; +DROP TABLE tbl_gist; +/* + * 1.2. test CREATE INDEX with inserts + */ +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +-- size is chosen to exceed page size and trigger actual truncation +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; + pg_get_indexdef +----------------------------------------------------------------------------------- + CREATE INDEX tbl_gist_idx ON public.tbl_gist USING gist (c4) INCLUDE (c1, c2, c3) +(1 row) + +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + c1 | c2 | c3 | c4 +----+----+----+------------- + 1 | 2 | 3 | (2,3),(1,2) + 2 | 4 | 6 | (4,5),(2,3) + 3 | 6 | 9 | (6,7),(3,4) + 4 | 8 | 12 | (8,9),(4,5) +(4 rows) + +SET enable_bitmapscan TO off; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + QUERY PLAN +------------------------------------------------ + Index Only Scan using tbl_gist_idx on tbl_gist + Index Cond: (c4 <@ '(10,10),(1,1)'::box) +(2 rows) + +SET enable_bitmapscan TO default; +DROP TABLE tbl_gist; +/* + * 2. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + indexdef +----------------------------------------------------------------------------------- + CREATE INDEX tbl_gist_idx ON public.tbl_gist USING gist (c4) INCLUDE (c1, c2, c3) +(1 row) + +DROP TABLE tbl_gist; +/* + * 3. REINDEX + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + indexdef +------------------------------------------------------------------------------- + CREATE INDEX tbl_gist_idx ON public.tbl_gist USING gist (c4) INCLUDE (c1, c3) +(1 row) + +REINDEX INDEX tbl_gist_idx; +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + indexdef +------------------------------------------------------------------------------- + CREATE INDEX tbl_gist_idx ON public.tbl_gist USING gist (c4) INCLUDE (c1, c3) +(1 row) + +ALTER TABLE tbl_gist DROP COLUMN c1; +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; + indexdef +---------- +(0 rows) + +DROP TABLE tbl_gist; +/* + * 4. Update, delete values in indexed table. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2; +UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3; +DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12; +DROP TABLE tbl_gist; +/* + * 5. Alter column type. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +ALTER TABLE tbl_gist ALTER c1 TYPE bigint; +ALTER TABLE tbl_gist ALTER c3 TYPE bigint; +\d tbl_gist + Table "public.tbl_gist" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | bigint | | | + c2 | integer | | | + c3 | bigint | | | + c4 | box | | | +Indexes: + "tbl_gist_idx" gist (c4) INCLUDE (c1, c3) + +DROP TABLE tbl_gist; +/* + * 6. EXCLUDE constraint. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3)); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +ERROR: conflicting key value violates exclusion constraint "tbl_gist_c4_c1_c2_c3_excl" +DETAIL: Key (c4)=((4,5),(2,3)) conflicts with existing key (c4)=((2,3),(1,2)). +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(3*x,2*x),point(3*x+1,2*x+1)) FROM generate_series(1,10) AS x; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); + QUERY PLAN +------------------------------------------------------------- + Index Only Scan using tbl_gist_c4_c1_c2_c3_excl on tbl_gist + Index Cond: (c4 <@ '(10,10),(1,1)'::box) +(2 rows) + +\d tbl_gist + Table "public.tbl_gist" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + c1 | integer | | | + c2 | integer | | | + c3 | integer | | | + c4 | box | | | +Indexes: + "tbl_gist_c4_c1_c2_c3_excl" EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3) + +DROP TABLE tbl_gist; diff --git a/src/test/regress/expected/indexing.out b/src/test/regress/expected/indexing.out index 33f68aab712..c143df5114f 100644 --- a/src/test/regress/expected/indexing.out +++ b/src/test/regress/expected/indexing.out @@ -1,25 +1,52 @@ -- Creating an index on a partitioned table makes the partitions -- automatically get the index create table idxpart (a int, b int, c text) partition by range (a); +-- relhassubclass of a partitioned index is false before creating any partition. +-- It will be set after the first partition is created. +create index idxpart_idx on idxpart (a); +select relhassubclass from pg_class where relname = 'idxpart_idx'; + relhassubclass +---------------- + f +(1 row) + +-- Check that partitioned indexes are present in pg_indexes. +select indexdef from pg_indexes where indexname like 'idxpart_idx%'; + indexdef +----------------------------------------------------------------- + CREATE INDEX idxpart_idx ON ONLY public.idxpart USING btree (a) +(1 row) + +drop index idxpart_idx; create table idxpart1 partition of idxpart for values from (0) to (10); create table idxpart2 partition of idxpart for values from (10) to (100) partition by range (b); create table idxpart21 partition of idxpart2 for values from (0) to (100); +-- Even with partitions, relhassubclass should not be set if a partitioned +-- index is created only on the parent. +create index idxpart_idx on only idxpart(a); +select relhassubclass from pg_class where relname = 'idxpart_idx'; + relhassubclass +---------------- + f +(1 row) + +drop index idxpart_idx; create index on idxpart (a); -select relname, relkind, inhparent::regclass +select relname, relkind, relhassubclass, inhparent::regclass from pg_class left join pg_index ix on (indexrelid = oid) left join pg_inherits on (ix.indexrelid = inhrelid) where relname like 'idxpart%' order by relname; - relname | relkind | inhparent ------------------+---------+---------------- - idxpart | p | - idxpart1 | r | - idxpart1_a_idx | i | idxpart_a_idx - idxpart2 | p | - idxpart21 | r | - idxpart21_a_idx | i | idxpart2_a_idx - idxpart2_a_idx | I | idxpart_a_idx - idxpart_a_idx | I | + relname | relkind | relhassubclass | inhparent +-----------------+---------+----------------+---------------- + idxpart | p | t | + idxpart1 | r | f | + idxpart1_a_idx | i | f | idxpart_a_idx + idxpart2 | p | t | + idxpart21 | r | f | + idxpart21_a_idx | i | f | idxpart2_a_idx + idxpart2_a_idx | I | t | idxpart_a_idx + idxpart_a_idx | I | t | (8 rows) drop table idxpart; @@ -40,6 +67,14 @@ SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2); (0 rows) DROP table idxpart, idxpart_two; +-- Verify bugfix with index rewrite on ALTER TABLE / SET DATA TYPE +-- https://postgr.es/m/CAKcux6mxNCGsgATwf5CGMF8g4WSupCXicCVMeKUTuWbyxHOMsQ@mail.gmail.com +CREATE TABLE idxpart (a INT, b TEXT, c INT) PARTITION BY RANGE(a); +CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (MINVALUE) TO (MAXVALUE); +CREATE INDEX partidx_abc_idx ON idxpart (a, b, c); +INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i; +ALTER TABLE idxpart ALTER COLUMN c TYPE numeric; +DROP TABLE idxpart; -- If a table without index is attached as partition to a table with -- an index, the index is automatically created create table idxpart (a int, b int, c text) partition by range (a); @@ -67,6 +102,25 @@ Indexes: "idxpart1_a_idx" btree (a) "idxpart1_b_c_idx" btree (b, c) +\d+ idxpart1_a_idx + Index "public.idxpart1_a_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + a | integer | yes | a | plain | +Partition of: idxparti +No partition constraint +btree, for table "public.idxpart1" + +\d+ idxpart1_b_c_idx + Index "public.idxpart1_b_c_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+----------+-------------- + b | integer | yes | b | plain | + c | text | yes | c | extended | +Partition of: idxparti2 +No partition constraint +btree, for table "public.idxpart1" + drop table idxpart; -- If a partition already has an index, don't create a duplicative one create table idxpart (a int, b int) partition by range (a, b); @@ -83,16 +137,16 @@ Partition of: idxpart FOR VALUES FROM (0, 0) TO (10, 10) Indexes: "idxpart1_a_b_idx" btree (a, b) -select relname, relkind, inhparent::regclass +select relname, relkind, relhassubclass, inhparent::regclass from pg_class left join pg_index ix on (indexrelid = oid) left join pg_inherits on (ix.indexrelid = inhrelid) where relname like 'idxpart%' order by relname; - relname | relkind | inhparent -------------------+---------+----------------- - idxpart | p | - idxpart1 | r | - idxpart1_a_b_idx | i | idxpart_a_b_idx - idxpart_a_b_idx | I | + relname | relkind | relhassubclass | inhparent +------------------+---------+----------------+----------------- + idxpart | p | t | + idxpart1 | r | f | + idxpart1_a_b_idx | i | f | idxpart_a_b_idx + idxpart_a_b_idx | I | t | (4 rows) drop table idxpart; @@ -213,7 +267,7 @@ Indexes: "idxpart1_a_idx" btree (a) \d idxpart2 - Table "public.idxpart2" + Partitioned table "public.idxpart2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -258,7 +312,7 @@ where indexrelid::regclass::text like 'idxpart%' -- attaching idxpart22 is not enough to set idxpart22_a_idx valid ... alter index idxpart2_a_idx attach partition idxpart22_a_idx; \d idxpart2 - Table "public.idxpart2" + Partitioned table "public.idxpart2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -272,7 +326,7 @@ Number of partitions: 2 (Use \d+ to list them.) create index on idxpart21 (a); alter index idxpart2_a_idx attach partition idxpart21_a_idx; \d idxpart2 - Table "public.idxpart2" + Partitioned table "public.idxpart2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -474,6 +528,30 @@ select relname, relkind from pg_class where relname like 'idxpart%' order by rel ---------+--------- (0 rows) +create table idxpart (a int, b int, c int) partition by range(a); +create index on idxpart(c); +create table idxpart1 partition of idxpart for values from (0) to (250); +create table idxpart2 partition of idxpart for values from (250) to (500); +alter table idxpart detach partition idxpart2; +\d idxpart2 + Table "public.idxpart2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + c | integer | | | +Indexes: + "idxpart2_c_idx" btree (c) + +alter table idxpart2 drop column c; +\d idxpart2 + Table "public.idxpart2" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | integer | | | + +drop table idxpart, idxpart2; -- Verify that expression indexes inherit correctly create table idxpart (a int, b int) partition by range (a); create table idxpart1 (like idxpart); @@ -631,17 +709,21 @@ alter table idxpart2 drop column col1, drop column col2; create index on idxpart2 (abs(b)); alter table idxpart attach partition idxpart2 for values from (0) to (1); create index on idxpart (abs(b)); +create index on idxpart ((b + 1)); alter table idxpart attach partition idxpart1 for values from (1) to (2); select c.relname, pg_get_indexdef(indexrelid) from pg_class c join pg_index i on c.oid = i.indexrelid where indrelid::regclass::text like 'idxpart%' order by indexrelid::regclass::text collate "C"; - relname | pg_get_indexdef -------------------+-------------------------------------------------------------------------- - idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b)) - idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b)) - idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b)) -(3 rows) + relname | pg_get_indexdef +-------------------+------------------------------------------------------------------------------ + idxpart1_abs_idx | CREATE INDEX idxpart1_abs_idx ON public.idxpart1 USING btree (abs(b)) + idxpart1_expr_idx | CREATE INDEX idxpart1_expr_idx ON public.idxpart1 USING btree (((b + 1))) + idxpart2_abs_idx | CREATE INDEX idxpart2_abs_idx ON public.idxpart2 USING btree (abs(b)) + idxpart2_expr_idx | CREATE INDEX idxpart2_expr_idx ON public.idxpart2 USING btree (((b + 1))) + idxpart_abs_idx | CREATE INDEX idxpart_abs_idx ON ONLY public.idxpart USING btree (abs(b)) + idxpart_expr_idx | CREATE INDEX idxpart_expr_idx ON ONLY public.idxpart USING btree (((b + 1))) +(6 rows) drop table idxpart; -- Verify that columns are mapped correctly for WHERE in a partial index @@ -677,7 +759,7 @@ create table idxpart (col_keep int) partition by range (col_keep); create index on idxpart (col_keep); alter table idxpart attach partition idxpart1 for values from (0) to (1000); \d idxpart - Table "public.idxpart" + Partitioned table "public.idxpart" Column | Type | Collation | Nullable | Default ----------+---------+-----------+----------+--------- col_keep | integer | | | @@ -720,7 +802,7 @@ create index on idxpart1 (col_keep); create index on idxpart (col_keep); alter table idxpart attach partition idxpart1 for values from (0) to (1000); \d idxpart - Table "public.idxpart" + Partitioned table "public.idxpart" Column | Type | Collation | Nullable | Default ----------+---------+-----------+----------+--------- col_keep | integer | | | @@ -759,7 +841,7 @@ drop table idxpart; -- Verify that it works to add primary key / unique to partitioned tables create table idxpart (a int primary key, b int) partition by range (a); \d idxpart - Table "public.idxpart" + Partitioned table "public.idxpart" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | not null | @@ -769,8 +851,24 @@ Indexes: "idxpart_pkey" PRIMARY KEY, btree (a) Number of partitions: 0 +-- multiple primary key on child should fail +create table failpart partition of idxpart (b primary key) for values from (0) to (100); +ERROR: multiple primary keys for table "failpart" are not allowed drop table idxpart; --- but not if you fail to use the full partition key +-- primary key on child is okay if there's no PK in the parent, though +create table idxpart (a int) partition by range (a); +create table idxpart1pk partition of idxpart (a primary key) for values from (0) to (100); +\d idxpart1pk + Table "public.idxpart1pk" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | not null | +Partition of: idxpart FOR VALUES FROM (0) TO (100) +Indexes: + "idxpart1pk_pkey" PRIMARY KEY, btree (a) + +drop table idxpart; +-- Failing to use the full partition key is not allowed create table idxpart (a int unique, b int) partition by range (a, b); ERROR: insufficient columns in UNIQUE constraint definition DETAIL: UNIQUE constraint on table "idxpart" lacks column "b" which is part of the partition key. @@ -805,7 +903,7 @@ ERROR: insufficient columns in PRIMARY KEY constraint definition DETAIL: PRIMARY KEY constraint on table "idxpart" lacks column "b" which is part of the partition key. alter table idxpart add primary key (a, b); -- this works \d idxpart - Table "public.idxpart" + Partitioned table "public.idxpart" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | not null | @@ -836,7 +934,7 @@ ERROR: insufficient columns in UNIQUE constraint definition DETAIL: UNIQUE constraint on table "idxpart" lacks column "b" which is part of the partition key. alter table idxpart add unique (b, a); -- this works \d idxpart - Table "public.idxpart" + Partitioned table "public.idxpart" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | | @@ -1000,6 +1098,21 @@ select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid idxpart | idxpart_pkey | | t | idxpart_pkey | t | 0 | t | t (2 rows) +drop table idxpart; +-- Related to the above scenario: ADD PRIMARY KEY on the parent mustn't +-- automatically propagate NOT NULL to child columns. +create table idxpart (a int) partition by range (a); +create table idxpart0 (like idxpart); +alter table idxpart0 add unique (a); +alter table idxpart attach partition idxpart0 default; +alter table only idxpart add primary key (a); -- fail, no NOT NULL constraint +ERROR: constraint must be added to child tables too +DETAIL: Column "a" of relation "idxpart0" is not already NOT NULL. +HINT: Do not specify the ONLY keyword. +alter table idxpart0 alter column a set not null; +alter table only idxpart add primary key (a); -- now it works +alter table idxpart0 alter column a drop not null; -- fail, pkey needs it +ERROR: column "a" is marked NOT NULL in parent table drop table idxpart; -- if a partition has a unique index without a constraint, does not attach -- automatically; creates a new index instead. @@ -1067,239 +1180,6 @@ select tableoid::regclass, * from idxpart order by a; (8 rows) drop table idxpart; --- test fastpath mechanism for index insertion -create table fastpath (a int, b text, c numeric); -create unique index fpindex1 on fastpath(a); -insert into fastpath values (1, 'b1', 100.00); -insert into fastpath values (1, 'b1', 100.00); -- unique key check -ERROR: duplicate key value violates unique constraint "fpindex1" -DETAIL: Key (a)=(1) already exists. -truncate fastpath; -insert into fastpath select generate_series(1,10000), 'b', 100; --- vacuum the table so as to improve chances of index-only scans. we can't --- guarantee if index-only scans will be picked up in all cases or not, but --- that fuzziness actually helps the test. -vacuum fastpath; -set enable_seqscan to false; -set enable_bitmapscan to false; -select sum(a) from fastpath where a = 6456; - sum ------- - 6456 -(1 row) - -select sum(a) from fastpath where a >= 5000 and a < 5700; - sum ---------- - 3744650 -(1 row) - --- drop the only index on the table and compute hashes for --- a few queries which orders the results in various different ways. -drop index fpindex1; -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - --- now create a multi-column index with both column asc -create index fpindex2 on fastpath(a, b); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; --- again, vacuum here either forces index-only scans or creates fuzziness -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - --- same queries with a different kind of index now. the final result must not --- change irrespective of what kind of index we have. -drop index fpindex2; -create index fpindex3 on fastpath(a desc, b asc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - --- repeat again -drop index fpindex3; -create index fpindex4 on fastpath(a asc, b desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - --- and again, this time indexing by (b, a). Note that column "b" has non-unique --- values. -drop index fpindex4; -create index fpindex5 on fastpath(b asc, a desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - --- one last time -drop index fpindex5; -create index fpindex6 on fastpath(b desc, a desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 6167a852b3e0679886b84a5405b5b53d -(1 row) - -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - dfcf2bd5e5fea8397d47b2fd14618d31 -(1 row) - -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - md5 ----------------------------------- - 2ca216010a558a52d7df12f76dfc77ab -(1 row) - -drop table fastpath; -- intentionally leave some objects around create table idxpart (a int) partition by range (a); create table idxpart1 partition of idxpart for values from (0) to (100); @@ -1313,3 +1193,68 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; create index on idxpart (a); create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a); create table idxpart_another_1 partition of idxpart_another for values from (0) to (100); +create table idxpart3 (c int, b int, a int) partition by range (a); +alter table idxpart3 drop column b, drop column c; +create table idxpart31 partition of idxpart3 for values from (1000) to (1200); +create table idxpart32 partition of idxpart3 for values from (1200) to (1400); +alter table idxpart attach partition idxpart3 for values from (1000) to (2000); +-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade +-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql +create schema regress_indexing; +set search_path to regress_indexing; +create table pk (a int primary key) partition by range (a); +create table pk1 partition of pk for values from (0) to (1000); +create table pk2 (b int, a int); +alter table pk2 drop column b; +alter table pk2 alter a set not null; +alter table pk attach partition pk2 for values from (1000) to (2000); +create table pk3 partition of pk for values from (2000) to (3000); +create table pk4 (like pk); +alter table pk attach partition pk4 for values from (3000) to (4000); +create table pk5 (like pk) partition by range (a); +create table pk51 partition of pk5 for values from (4000) to (4500); +create table pk52 partition of pk5 for values from (4500) to (5000); +alter table pk attach partition pk5 for values from (4000) to (5000); +reset search_path; +-- Test that covering partitioned indexes work in various cases +create table covidxpart (a int, b int) partition by list (a); +create unique index on covidxpart (a) include (b); +create table covidxpart1 partition of covidxpart for values in (1); +create table covidxpart2 partition of covidxpart for values in (2); +insert into covidxpart values (1, 1); +insert into covidxpart values (1, 1); +ERROR: duplicate key value violates unique constraint "covidxpart1_a_b_idx" +DETAIL: Key (a)=(1) already exists. +create table covidxpart3 (b int, c int, a int); +alter table covidxpart3 drop c; +alter table covidxpart attach partition covidxpart3 for values in (3); +insert into covidxpart values (3, 1); +insert into covidxpart values (3, 1); +ERROR: duplicate key value violates unique constraint "covidxpart3_a_b_idx" +DETAIL: Key (a)=(3) already exists. +create table covidxpart4 (b int, a int); +create unique index on covidxpart4 (a) include (b); +create unique index on covidxpart4 (a); +alter table covidxpart attach partition covidxpart4 for values in (4); +insert into covidxpart values (4, 1); +insert into covidxpart values (4, 1); +ERROR: duplicate key value violates unique constraint "covidxpart4_a_b_idx" +DETAIL: Key (a)=(4) already exists. +create unique index on covidxpart (b) include (a); -- should fail +ERROR: insufficient columns in UNIQUE constraint definition +DETAIL: UNIQUE constraint on table "covidxpart" lacks column "a" which is part of the partition key. +-- check that detaching a partition also detaches the primary key constraint +create table parted_pk_detach_test (a int primary key) partition by list (a); +create table parted_pk_detach_test1 partition of parted_pk_detach_test for values in (1); +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; -- should fail +ERROR: cannot drop inherited constraint "parted_pk_detach_test1_pkey" of relation "parted_pk_detach_test1" +alter table parted_pk_detach_test detach partition parted_pk_detach_test1; +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; +drop table parted_pk_detach_test, parted_pk_detach_test1; +create table parted_uniq_detach_test (a int unique) partition by list (a); +create table parted_uniq_detach_test1 partition of parted_uniq_detach_test for values in (1); +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; -- should fail +ERROR: cannot drop inherited constraint "parted_uniq_detach_test1_a_key" of relation "parted_uniq_detach_test1" +alter table parted_uniq_detach_test detach partition parted_uniq_detach_test1; +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; +drop table parted_uniq_detach_test, parted_uniq_detach_test1; diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out index be9427eb6b8..12df25fe9d5 100644 --- a/src/test/regress/expected/inet.out +++ b/src/test/regress/expected/inet.out @@ -242,6 +242,15 @@ SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL; -- check that btree index works correctly CREATE INDEX inet_idx1 ON inet_tbl(i); SET enable_seqscan TO off; +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; + QUERY PLAN +------------------------------------------------------------------------------- + Index Scan using inet_idx1 on inet_tbl + Index Cond: ((i > '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) + Filter: (i << '192.168.1.0/24'::inet) +(3 rows) + SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; c | i ----------------+------------------ @@ -250,6 +259,15 @@ SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; 192.168.1.0/26 | 192.168.1.226 (3 rows) +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; + QUERY PLAN +-------------------------------------------------------------------------------- + Index Scan using inet_idx1 on inet_tbl + Index Cond: ((i >= '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) + Filter: (i <<= '192.168.1.0/24'::inet) +(3 rows) + SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; c | i ----------------+------------------ @@ -261,6 +279,43 @@ SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; 192.168.1.0/26 | 192.168.1.226 (6 rows) +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; + QUERY PLAN +-------------------------------------------------------------------------------- + Index Scan using inet_idx1 on inet_tbl + Index Cond: ((i >= '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) + Filter: ('192.168.1.0/24'::inet >>= i) +(3 rows) + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; + c | i +----------------+------------------ + 192.168.1.0/24 | 192.168.1.0/24 + 192.168.1.0/24 | 192.168.1.226/24 + 192.168.1.0/24 | 192.168.1.255/24 + 192.168.1.0/24 | 192.168.1.0/25 + 192.168.1.0/24 | 192.168.1.255/25 + 192.168.1.0/26 | 192.168.1.226 +(6 rows) + +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; + QUERY PLAN +------------------------------------------------------------------------------- + Index Scan using inet_idx1 on inet_tbl + Index Cond: ((i > '192.168.1.0/24'::inet) AND (i <= '192.168.1.255'::inet)) + Filter: ('192.168.1.0/24'::inet >> i) +(3 rows) + +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; + c | i +----------------+------------------ + 192.168.1.0/24 | 192.168.1.0/25 + 192.168.1.0/24 | 192.168.1.255/25 + 192.168.1.0/26 | 192.168.1.226 +(3 rows) + SET enable_seqscan TO on; DROP INDEX inet_idx1; -- check that gist index works correctly @@ -790,3 +845,192 @@ SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i); ::/24 (17 rows) +-- Test inet sortsupport with a variety of boundary inputs: +SELECT a FROM (VALUES + ('0.0.0.0/0'::inet), + ('0.0.0.0/1'::inet), + ('0.0.0.0/32'::inet), + ('0.0.0.1/0'::inet), + ('0.0.0.1/1'::inet), + ('127.126.127.127/0'::inet), + ('127.127.127.127/0'::inet), + ('127.128.127.127/0'::inet), + ('192.168.1.0/24'::inet), + ('192.168.1.0/25'::inet), + ('192.168.1.1/23'::inet), + ('192.168.1.1/5'::inet), + ('192.168.1.1/6'::inet), + ('192.168.1.1/25'::inet), + ('192.168.1.2/25'::inet), + ('192.168.1.1/26'::inet), + ('192.168.1.2/26'::inet), + ('192.168.1.2/23'::inet), + ('192.168.1.255/5'::inet), + ('192.168.1.255/6'::inet), + ('192.168.1.3/1'::inet), + ('192.168.1.3/23'::inet), + ('192.168.1.4/0'::inet), + ('192.168.1.5/0'::inet), + ('255.0.0.0/0'::inet), + ('255.1.0.0/0'::inet), + ('255.2.0.0/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/15'::inet), + ('255.255.000.000/16'::inet), + ('255.255.255.254/32'::inet), + ('255.255.255.000/32'::inet), + ('255.255.255.001/31'::inet), + ('255.255.255.002/31'::inet), + ('255.255.255.003/31'::inet), + ('255.255.255.003/32'::inet), + ('255.255.255.001/32'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/1'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/31'::inet), + ('255.255.255.255/32'::inet), + ('255.255.255.253/32'::inet), + ('255.255.255.252/32'::inet), + ('255.3.0.0/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet), + ('10:23::f1/64'::inet), + ('10:23::f1/65'::inet), + ('10:23::ffff'::inet), + ('127::1'::inet), + ('127::2'::inet), + ('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet), + ('::1:ffff:ffff:ffff:ffff/128'::inet), + ('::2:ffff:ffff:ffff:ffff/128'::inet), + ('::4:3:2:0/24'::inet), + ('::4:3:2:1/24'::inet), + ('::4:3:2:2/24'::inet), + ('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet), + ('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet), + ('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet), + ('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet), + ('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet), + ('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet), + ('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet), + ('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet), + ('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet), + ('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet), + ('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet), + ('ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffd::/128'::inet), + ('ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffe::/128'::inet), + ('ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:0/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:1/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:2/24'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet) +) AS i(a) ORDER BY a; + a +-------------------------------------------- + 0.0.0.0/0 + 0.0.0.1/0 + 127.126.127.127/0 + 127.127.127.127/0 + 127.128.127.127/0 + 192.168.1.4/0 + 192.168.1.5/0 + 255.0.0.0/0 + 255.1.0.0/0 + 255.2.0.0/0 + 255.3.0.0/0 + 255.255.0.0/0 + 255.255.0.0/0 + 255.255.255.255/0 + 255.255.255.255/0 + 255.255.255.255/0 + 0.0.0.0/1 + 0.0.0.1/1 + 0.0.0.0 + 192.168.1.3/1 + 255.255.255.255/1 + 192.168.1.1/5 + 192.168.1.255/5 + 192.168.1.1/6 + 192.168.1.255/6 + 192.168.1.1/23 + 192.168.1.2/23 + 192.168.1.3/23 + 192.168.1.0/24 + 192.168.1.0/25 + 192.168.1.1/25 + 192.168.1.2/25 + 192.168.1.1/26 + 192.168.1.2/26 + 255.255.0.0/15 + 255.255.0.0/16 + 255.255.255.255/16 + 255.255.255.255/16 + 255.255.255.1/31 + 255.255.255.0 + 255.255.255.1 + 255.255.255.2/31 + 255.255.255.3/31 + 255.255.255.3 + 255.255.255.252 + 255.255.255.253 + 255.255.255.255/31 + 255.255.255.254 + 255.255.255.255 + ::/0 + ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0 + ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0 + ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0 + ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0 + ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0 + ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0 + ::4:3:2:0/24 + ::4:3:2:1/24 + ::4:3:2:2/24 + :: + ::1 + ::1:ffff:ffff:ffff:ffff + ::2:ffff:ffff:ffff:ffff + 10:23::f1/64 + 10:23::f1/65 + 10:23::ffff + 127::1 + 127::2 + 8000::/1 + ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70 + ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44 + ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69 + ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73 + ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89 + ffff:8dd0:646:694c:7c16:7e35:6a26:171/104 + ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121 + ffff:90e7:e744:664:a93:8efe:1f25:7663/122 + ffff:9597:c69c:8b24:57a:8639:ec78:6026/111 + ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88 + ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23 + ffff:ffff:ffff:ffff:4:3:2:0/24 + ffff:ffff:ffff:ffff:4:3:2:1/24 + ffff:ffff:ffff:ffff:4:3:2:2/24 + ffff:ffff:ffff:fffd:: + ffff:ffff:ffff:fffe:: + ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +(91 rows) + diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out index b2b912ed5c1..44d51ed7110 100644 --- a/src/test/regress/expected/inherit.out +++ b/src/test/regress/expected/inherit.out @@ -539,6 +539,47 @@ CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a); INSERT INTO z VALUES (NULL, 'text'); -- should fail ERROR: null value in column "aa" violates not-null constraint DETAIL: Failing row contains (null, text). +-- Check inherited UPDATE with all children excluded +create table some_tab (a int, b int); +create table some_tab_child () inherits (some_tab); +insert into some_tab_child values(1,2); +explain (verbose, costs off) +update some_tab set a = a + 1 where false; + QUERY PLAN +---------------------------------- + Update on public.some_tab + Update on public.some_tab + -> Result + Output: (a + 1), b, ctid + One-Time Filter: false +(5 rows) + +update some_tab set a = a + 1 where false; +explain (verbose, costs off) +update some_tab set a = a + 1 where false returning b, a; + QUERY PLAN +---------------------------------- + Update on public.some_tab + Output: b, a + Update on public.some_tab + -> Result + Output: (a + 1), b, ctid + One-Time Filter: false +(6 rows) + +update some_tab set a = a + 1 where false returning b, a; + b | a +---+--- +(0 rows) + +table some_tab; + a | b +---+--- + 1 | 2 +(1 row) + +drop table some_tab cascade; +NOTICE: drop cascades to table some_tab_child -- Check UPDATE with inherited target and an inherited source table create temp table foo(f1 int, f2 int); create temp table foo2(f3 int) inherits (foo); @@ -624,6 +665,15 @@ select tableoid::regclass::text as relname, parted_tab.* from parted_tab order b parted_tab_part3 | 3 | a (3 rows) +-- modifies partition key, but no rows will actually be updated +explain update parted_tab set a = 2 where false; + QUERY PLAN +-------------------------------------------------------- + Update on parted_tab (cost=0.00..0.00 rows=0 width=0) + -> Result (cost=0.00..0.00 rows=0 width=0) + One-Time Filter: false +(3 rows) + drop table parted_tab; -- Check UPDATE with multi-level partitioned inherited target create table mlparted_tab (a int, b char, c text) partition by list (a); @@ -673,55 +723,16 @@ select * from d; 32 | one | two | three (1 row) --- check that oid column is handled properly during alter table inherit -create table oid_parent (a int) with oids; -create table oid_child () inherits (oid_parent); -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - attinhcount | attislocal --------------+------------ - 1 | f -(1 row) - -drop table oid_child; -create table oid_child (a int) without oids; -alter table oid_child inherit oid_parent; -- fail -ERROR: table "oid_child" without OIDs cannot inherit from table "oid_parent" with OIDs -alter table oid_child set with oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - attinhcount | attislocal --------------+------------ - 0 | t -(1 row) - -alter table oid_child inherit oid_parent; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - attinhcount | attislocal --------------+------------ - 1 | t -(1 row) - -alter table oid_child set without oids; -- fail -ERROR: cannot drop inherited column "oid" -alter table oid_parent set without oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - attinhcount | attislocal --------------+------------ - 0 | t -(1 row) - -alter table oid_child set without oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - attinhcount | attislocal --------------+------------ -(0 rows) - -drop table oid_parent cascade; -NOTICE: drop cascades to table oid_child +-- The above verified that we can change the type of a multiply-inherited +-- column; but we should reject that if any definition was inherited from +-- an unrelated parent. +create temp table parent1(f1 int, f2 int); +create temp table parent2(f1 int, f3 bigint); +create temp table childtab(f4 int) inherits(parent1, parent2); +NOTICE: merging multiple inherited definitions of column "f1" +alter table parent1 alter column f1 type bigint; -- fail, conflict w/parent2 +ERROR: cannot alter inherited column "f1" of relation "childtab" +alter table parent1 alter column f2 type bigint; -- ok -- Test non-inheritable parent constraints create table p1(ff1 int); alter table p1 add constraint p1chk check (ff1 > 0) no inherit; @@ -764,6 +775,8 @@ NOTICE: drop cascades to table c1 -- tables. See the pgsql-hackers thread beginning Dec. 4/04 create table base (i integer); create table derived () inherits (base); +create table more_derived (like derived, b int) inherits (derived); +NOTICE: merging column "i" with inherited definition insert into derived (i) values (0); select derived::base from derived; derived @@ -777,6 +790,22 @@ select NULL::derived::base; (1 row) +-- remove redundant conversions. +explain (verbose on, costs off) select row(i, b)::more_derived::derived::base from more_derived; + QUERY PLAN +------------------------------------------- + Seq Scan on public.more_derived + Output: (ROW(i, b)::more_derived)::base +(2 rows) + +explain (verbose on, costs off) select (1, 2)::more_derived::derived::base; + QUERY PLAN +----------------------- + Result + Output: '(1)'::base +(2 rows) + +drop table more_derived; drop table derived; drop table base; create table p1(ff1 int); @@ -797,7 +826,7 @@ drop table p1; CREATE TABLE ac (aa TEXT); alter table ac add constraint ac_check check (aa is not null); CREATE TABLE bc (bb TEXT) INHERITS (ac); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+----------+---------+------------+-------------+------------------ ac | ac_check | c | t | 0 | (aa IS NOT NULL) @@ -813,14 +842,14 @@ DETAIL: Failing row contains (null, null). alter table bc drop constraint ac_check; -- fail, disallowed ERROR: cannot drop inherited constraint "ac_check" of relation "bc" alter table ac drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+-------- (0 rows) -- try the unnamed-constraint case alter table ac add check (aa is not null); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+-------------+---------+------------+-------------+------------------ ac | ac_aa_check | c | t | 0 | (aa IS NOT NULL) @@ -836,14 +865,14 @@ DETAIL: Failing row contains (null, null). alter table bc drop constraint ac_aa_check; -- fail, disallowed ERROR: cannot drop inherited constraint "ac_aa_check" of relation "bc" alter table ac drop constraint ac_aa_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+-------- (0 rows) alter table ac add constraint ac_check check (aa is not null); alter table bc no inherit ac; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+----------+---------+------------+-------------+------------------ ac | ac_check | c | t | 0 | (aa IS NOT NULL) @@ -851,14 +880,14 @@ select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg (2 rows) alter table bc drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+----------+---------+------------+-------------+------------------ ac | ac_check | c | t | 0 | (aa IS NOT NULL) (1 row) alter table ac drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+-------- (0 rows) @@ -869,7 +898,7 @@ create table ac (a int constraint check_a check (a <> 0)); create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac); NOTICE: merging column "a" with inherited definition NOTICE: merging constraint "check_a" with inherited definition -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+---------- ac | check_a | c | t | 0 | (a <> 0) @@ -882,7 +911,7 @@ drop table ac; create table ac (a int constraint check_a check (a <> 0)); create table bc (b int constraint check_b check (b <> 0)); create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+---------- ac | check_a | c | t | 0 | (a <> 0) @@ -893,7 +922,7 @@ select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg (5 rows) alter table cc no inherit bc; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; relname | conname | contype | conislocal | coninhcount | consrc ---------+---------+---------+------------+-------------+---------- ac | check_a | c | t | 0 | (a <> 0) @@ -1710,6 +1739,37 @@ select * from cnullparent where f1 = 2; drop table cnullparent cascade; NOTICE: drop cascades to table cnullchild -- +-- Check use of temporary tables with inheritance trees +-- +create table inh_perm_parent (a1 int); +create temp table inh_temp_parent (a1 int); +create temp table inh_temp_child () inherits (inh_perm_parent); -- ok +create table inh_perm_child () inherits (inh_temp_parent); -- error +ERROR: cannot inherit from temporary relation "inh_temp_parent" +create temp table inh_temp_child_2 () inherits (inh_temp_parent); -- ok +insert into inh_perm_parent values (1); +insert into inh_temp_parent values (2); +insert into inh_temp_child values (3); +insert into inh_temp_child_2 values (4); +select tableoid::regclass, a1 from inh_perm_parent; + tableoid | a1 +-----------------+---- + inh_perm_parent | 1 + inh_temp_child | 3 +(2 rows) + +select tableoid::regclass, a1 from inh_temp_parent; + tableoid | a1 +------------------+---- + inh_temp_parent | 2 + inh_temp_child_2 | 4 +(2 rows) + +drop table inh_perm_parent cascade; +NOTICE: drop cascades to table inh_temp_child +drop table inh_temp_parent cascade; +NOTICE: drop cascades to table inh_temp_child_2 +-- -- Check that constraint exclusion works correctly with partitions using -- implicit constraints generated from the partition bound information. -- @@ -1729,12 +1789,11 @@ explain (costs off) select * from list_parted; (4 rows) explain (costs off) select * from list_parted where a is null; - QUERY PLAN --------------------------------- - Append - -> Seq Scan on part_null_xy - Filter: (a IS NULL) -(3 rows) + QUERY PLAN +-------------------------- + Seq Scan on part_null_xy + Filter: (a IS NULL) +(2 rows) explain (costs off) select * from list_parted where a is not null; QUERY PLAN @@ -1759,20 +1818,18 @@ explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); (5 rows) explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd'); - QUERY PLAN ---------------------------------------------------------------------------------------- - Append - -> Seq Scan on part_ab_cd - Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) -(3 rows) + QUERY PLAN +--------------------------------------------------------------------------------- + Seq Scan on part_ab_cd + Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) +(2 rows) explain (costs off) select * from list_parted where a = 'ab'; - QUERY PLAN ------------------------------------------- - Append - -> Seq Scan on part_ab_cd - Filter: ((a)::text = 'ab'::text) -(3 rows) + QUERY PLAN +------------------------------------ + Seq Scan on part_ab_cd + Filter: ((a)::text = 'ab'::text) +(2 rows) create table range_list_parted ( a int, @@ -1852,12 +1909,11 @@ explain (costs off) select * from range_list_parted where a is null; /* Should only select rows from the null-accepting partition */ explain (costs off) select * from range_list_parted where b is null; - QUERY PLAN ------------------------------------- - Append - -> Seq Scan on part_40_inf_null - Filter: (b IS NULL) -(3 rows) + QUERY PLAN +------------------------------ + Seq Scan on part_40_inf_null + Filter: (b IS NULL) +(2 rows) explain (costs off) select * from range_list_parted where a is not null and a < 67; QUERY PLAN @@ -1980,12 +2036,11 @@ explain (costs off) select * from mcrparted where a > -1; -- scans all partition (15 rows) explain (costs off) select * from mcrparted where a = 20 and abs(b) = 10 and c > 10; -- scans mcrparted4 - QUERY PLAN ------------------------------------------------------------ - Append - -> Seq Scan on mcrparted4 - Filter: ((c > 10) AND (a = 20) AND (abs(b) = 10)) -(3 rows) + QUERY PLAN +----------------------------------------------------- + Seq Scan on mcrparted4 + Filter: ((c > 10) AND (a = 20) AND (abs(b) = 10)) +(2 rows) explain (costs off) select * from mcrparted where a = 20 and c > 20; -- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def QUERY PLAN @@ -2001,7 +2056,6 @@ explain (costs off) select * from mcrparted where a = 20 and c > 20; -- scans mc Filter: ((c > 20) AND (a = 20)) (9 rows) -drop table mcrparted; -- check that partitioned table Appends cope with being referenced in -- subplans create table parted_minmax (a int, b varchar(16)) partition by range (a); @@ -2009,22 +2063,18 @@ create table parted_minmax1 partition of parted_minmax for values from (1) to (1 create index parted_minmax1i on parted_minmax1 (a, b); insert into parted_minmax values (1,'12345'); explain (costs off) select min(a), max(a) from parted_minmax where b = '12345'; - QUERY PLAN -------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Result InitPlan 1 (returns $0) -> Limit - -> Merge Append - Sort Key: parted_minmax1.a - -> Index Only Scan using parted_minmax1i on parted_minmax1 - Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) + -> Index Only Scan using parted_minmax1i on parted_minmax1 + Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) InitPlan 2 (returns $1) -> Limit - -> Merge Append - Sort Key: parted_minmax1_1.a DESC - -> Index Only Scan Backward using parted_minmax1i on parted_minmax1 parted_minmax1_1 - Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) -(13 rows) + -> Index Only Scan Backward using parted_minmax1i on parted_minmax1 parted_minmax1_1 + Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) +(9 rows) select min(a), max(a) from parted_minmax where b = '12345'; min | max @@ -2033,3 +2083,255 @@ select min(a), max(a) from parted_minmax where b = '12345'; (1 row) drop table parted_minmax; +-- Test code that uses Append nodes in place of MergeAppend when the +-- partition ordering matches the desired ordering. +create index mcrparted_a_abs_c_idx on mcrparted (a, abs(b), c); +-- MergeAppend must be used when a default partition exists +explain (costs off) select * from mcrparted order by a, abs(b), c; + QUERY PLAN +------------------------------------------------------------------- + Merge Append + Sort Key: mcrparted0.a, (abs(mcrparted0.b)), mcrparted0.c + -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 + -> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 + -> Index Scan using mcrparted_def_a_abs_c_idx on mcrparted_def +(9 rows) + +drop table mcrparted_def; +-- Append is used for a RANGE partitioned table with no default +-- and no subpartitions +explain (costs off) select * from mcrparted order by a, abs(b), c; + QUERY PLAN +------------------------------------------------------------- + Append + -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 + -> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 +(7 rows) + +-- Append is used with subpaths in reverse order with backwards index scans +explain (costs off) select * from mcrparted order by a desc, abs(b) desc, c desc; + QUERY PLAN +---------------------------------------------------------------------- + Append + -> Index Scan Backward using mcrparted5_a_abs_c_idx on mcrparted5 + -> Index Scan Backward using mcrparted4_a_abs_c_idx on mcrparted4 + -> Index Scan Backward using mcrparted3_a_abs_c_idx on mcrparted3 + -> Index Scan Backward using mcrparted2_a_abs_c_idx on mcrparted2 + -> Index Scan Backward using mcrparted1_a_abs_c_idx on mcrparted1 + -> Index Scan Backward using mcrparted0_a_abs_c_idx on mcrparted0 +(7 rows) + +-- check that Append plan is used containing a MergeAppend for sub-partitions +-- that are unordered. +drop table mcrparted5; +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a); +create table mcrparted5a partition of mcrparted5 for values in(20); +create table mcrparted5_def partition of mcrparted5 default; +explain (costs off) select * from mcrparted order by a, abs(b), c; + QUERY PLAN +--------------------------------------------------------------------------- + Append + -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 + -> Merge Append + Sort Key: mcrparted5a.a, (abs(mcrparted5a.b)), mcrparted5a.c + -> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a + -> Index Scan using mcrparted5_def_a_abs_c_idx on mcrparted5_def +(10 rows) + +drop table mcrparted5_def; +-- check that an Append plan is used and the sub-partitions are flattened +-- into the main Append when the sub-partition is unordered but contains +-- just a single sub-partition. +explain (costs off) select a, abs(b) from mcrparted order by a, abs(b), c; + QUERY PLAN +--------------------------------------------------------------- + Append + -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 + -> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a +(7 rows) + +-- check that Append is used when the sub-partitioned tables are pruned +-- during planning. +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c; + QUERY PLAN +------------------------------------------------------------- + Append + -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 + Index Cond: (a < 20) + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + Index Cond: (a < 20) + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + Index Cond: (a < 20) + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + Index Cond: (a < 20) +(9 rows) + +create table mclparted (a int) partition by list(a); +create table mclparted1 partition of mclparted for values in(1); +create table mclparted2 partition of mclparted for values in(2); +create index on mclparted (a); +-- Ensure an Append is used for a list partition with an order by. +explain (costs off) select * from mclparted order by a; + QUERY PLAN +------------------------------------------------------------ + Append + -> Index Only Scan using mclparted1_a_idx on mclparted1 + -> Index Only Scan using mclparted2_a_idx on mclparted2 +(3 rows) + +-- Ensure a MergeAppend is used when a partition exists with interleaved +-- datums in the partition bound. +create table mclparted3_5 partition of mclparted for values in(3,5); +create table mclparted4 partition of mclparted for values in(4); +explain (costs off) select * from mclparted order by a; + QUERY PLAN +---------------------------------------------------------------- + Merge Append + Sort Key: mclparted1.a + -> Index Only Scan using mclparted1_a_idx on mclparted1 + -> Index Only Scan using mclparted2_a_idx on mclparted2 + -> Index Only Scan using mclparted3_5_a_idx on mclparted3_5 + -> Index Only Scan using mclparted4_a_idx on mclparted4 +(6 rows) + +drop table mclparted; +-- Ensure subplans which don't have a path with the correct pathkeys get +-- sorted correctly. +drop index mcrparted_a_abs_c_idx; +create index on mcrparted1 (a, abs(b), c); +create index on mcrparted2 (a, abs(b), c); +create index on mcrparted3 (a, abs(b), c); +create index on mcrparted4 (a, abs(b), c); +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c limit 1; + QUERY PLAN +------------------------------------------------------------------------- + Limit + -> Append + -> Sort + Sort Key: mcrparted0.a, (abs(mcrparted0.b)), mcrparted0.c + -> Seq Scan on mcrparted0 + Filter: (a < 20) + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + Index Cond: (a < 20) + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + Index Cond: (a < 20) + -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 + Index Cond: (a < 20) +(12 rows) + +set enable_bitmapscan = 0; +-- Ensure Append node can be used when the partition is ordered by some +-- pathkeys which were deemed redundant. +explain (costs off) select * from mcrparted where a = 10 order by a, abs(b), c; + QUERY PLAN +------------------------------------------------------------- + Append + -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 + Index Cond: (a = 10) + -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 + Index Cond: (a = 10) +(5 rows) + +reset enable_bitmapscan; +drop table mcrparted; +-- Ensure LIST partitions allow an Append to be used instead of a MergeAppend +create table bool_lp (b bool) partition by list(b); +create table bool_lp_true partition of bool_lp for values in(true); +create table bool_lp_false partition of bool_lp for values in(false); +create index on bool_lp (b); +explain (costs off) select * from bool_lp order by b; + QUERY PLAN +------------------------------------------------------------------ + Append + -> Index Only Scan using bool_lp_false_b_idx on bool_lp_false + -> Index Only Scan using bool_lp_true_b_idx on bool_lp_true +(3 rows) + +drop table bool_lp; +-- Ensure const bool quals can be properly detected as redundant +create table bool_rp (b bool, a int) partition by range(b,a); +create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000); +create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000); +create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000); +create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000); +create index on bool_rp (b,a); +explain (costs off) select * from bool_rp where b = true order by b,a; + QUERY PLAN +------------------------------------------------------------------------ + Append + -> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k + Index Cond: (b = true) + -> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k + Index Cond: (b = true) +(5 rows) + +explain (costs off) select * from bool_rp where b = false order by b,a; + QUERY PLAN +-------------------------------------------------------------------------- + Append + -> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k + Index Cond: (b = false) + -> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k + Index Cond: (b = false) +(5 rows) + +explain (costs off) select * from bool_rp where b = true order by a; + QUERY PLAN +------------------------------------------------------------------------ + Append + -> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k + Index Cond: (b = true) + -> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k + Index Cond: (b = true) +(5 rows) + +explain (costs off) select * from bool_rp where b = false order by a; + QUERY PLAN +-------------------------------------------------------------------------- + Append + -> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k + Index Cond: (b = false) + -> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k + Index Cond: (b = false) +(5 rows) + +drop table bool_rp; +-- Ensure an Append scan is chosen when the partition order is a subset of +-- the required order. +create table range_parted (a int, b int, c int) partition by range(a, b); +create table range_parted1 partition of range_parted for values from (0,0) to (10,10); +create table range_parted2 partition of range_parted for values from (10,10) to (20,20); +create index on range_parted (a,b,c); +explain (costs off) select * from range_parted order by a,b,c; + QUERY PLAN +---------------------------------------------------------------------- + Append + -> Index Only Scan using range_parted1_a_b_c_idx on range_parted1 + -> Index Only Scan using range_parted2_a_b_c_idx on range_parted2 +(3 rows) + +explain (costs off) select * from range_parted order by a desc,b desc,c desc; + QUERY PLAN +------------------------------------------------------------------------------- + Append + -> Index Only Scan Backward using range_parted2_a_b_c_idx on range_parted2 + -> Index Only Scan Backward using range_parted1_a_b_c_idx on range_parted1 +(3 rows) + +drop table range_parted; diff --git a/src/test/regress/expected/insert.out b/src/test/regress/expected/insert.out index 97419a744ff..75e25cdf484 100644 --- a/src/test/regress/expected/insert.out +++ b/src/test/regress/expected/insert.out @@ -387,15 +387,31 @@ select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_p (9 rows) -- direct partition inserts should check hash partition bound constraint --- create custom operator class and hash function, for the same reason --- explained in alter_table.sql -create or replace function dummy_hashint4(a int4, seed int8) returns int8 as -$$ begin return (a + seed); end; $$ language 'plpgsql' immutable; -create operator class custom_opclass for type int4 using hash as -operator 1 = , function 2 dummy_hashint4(int4, int8); +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. The hash function for int4 simply returns +-- the sum of the values passed to it and the one for text returns the length +-- of the non-empty string value passed to it or 0. +create or replace function part_hashint4_noop(value int4, seed int8) +returns int8 as $$ +select value + seed; +$$ language sql immutable; +create operator class part_test_int4_ops +for type int4 +using hash as +operator 1 =, +function 2 part_hashint4_noop(int4, int8); +create or replace function part_hashtext_length(value text, seed int8) +RETURNS int8 AS $$ +select length(coalesce(value, ''))::int8 +$$ language sql immutable; +create operator class part_test_text_ops +for type text +using hash as +operator 1 =, +function 2 part_hashtext_length(text, int8); create table hash_parted ( a int -) partition by hash (a custom_opclass); +) partition by hash (a part_test_int4_ops); create table hpart0 partition of hash_parted for values with (modulus 4, remainder 0); create table hpart1 partition of hash_parted for values with (modulus 4, remainder 1); create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2); @@ -432,7 +448,7 @@ from hash_parted order by part; -- test \d+ output on a table which has both partitioned and unpartitioned -- partitions \d+ list_parted - Table "public.list_parted" + Partitioned table "public.list_parted" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- a | text | | | | extended | | @@ -449,8 +465,6 @@ Partitions: part_aa_bb FOR VALUES IN ('aa', 'bb'), -- cleanup drop table range_parted, list_parted; drop table hash_parted; -drop operator class custom_opclass using hash; -drop function dummy_hashint4(a int4, seed int8); -- test that a default partition added as the first partition accepts any value -- including null create table list_parted (a int) partition by list (a); @@ -615,6 +629,62 @@ select tableoid::regclass, * from mlparted_def; mlparted_defd | 70 | 100 | (4 rows) +-- Check multi-level tuple routing with attributes dropped from the +-- top-most parent. First remove the last attribute. +alter table mlparted add d int, add e int; +alter table mlparted drop e; +create table mlparted5 partition of mlparted + for values from (1, 40) to (1, 50) partition by range (c); +create table mlparted5_ab partition of mlparted5 + for values from ('a') to ('c') partition by list (c); +-- This partitioned table should remain with no partitions. +create table mlparted5_cd partition of mlparted5 + for values from ('c') to ('e') partition by list (c); +create table mlparted5_a partition of mlparted5_ab for values in ('a'); +create table mlparted5_b (d int, b int, c text, a int); +alter table mlparted5_ab attach partition mlparted5_b for values in ('b'); +truncate mlparted; +insert into mlparted values (1, 2, 'a', 1); +insert into mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails +ERROR: no partition of relation "mlparted5_cd" found for row +DETAIL: Partition key of the failing row contains (c) = (c). +insert into mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails +ERROR: no partition of relation "mlparted5" found for row +DETAIL: Partition key of the failing row contains (c) = (f). +select tableoid::regclass, * from mlparted order by a, b, c, d; + tableoid | a | b | c | d +-------------+---+----+---+--- + mlparted11 | 1 | 2 | a | 1 + mlparted5_a | 1 | 40 | a | 1 + mlparted5_b | 1 | 45 | b | 1 +(3 rows) + +alter table mlparted drop d; +truncate mlparted; +-- Remove the before last attribute. +alter table mlparted add e int, add d int; +alter table mlparted drop e; +insert into mlparted values (1, 2, 'a', 1); +insert into mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails +ERROR: no partition of relation "mlparted5_cd" found for row +DETAIL: Partition key of the failing row contains (c) = (c). +insert into mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails +ERROR: no partition of relation "mlparted5" found for row +DETAIL: Partition key of the failing row contains (c) = (f). +select tableoid::regclass, * from mlparted order by a, b, c, d; + tableoid | a | b | c | d +-------------+---+----+---+--- + mlparted11 | 1 | 2 | a | 1 + mlparted5_a | 1 | 40 | a | 1 + mlparted5_b | 1 | 45 | b | 1 +(3 rows) + +alter table mlparted drop d; +drop table mlparted5; -- check that message shown after failure to find a partition shows the -- appropriate key description (or none) in various situations create table key_desc (a int, b int) partition by list ((a+0)); @@ -785,7 +855,7 @@ create table mcrparted6_common_ge_10 partition of mcrparted for values from ('co create table mcrparted7_gt_common_lt_d partition of mcrparted for values from ('common', maxvalue) to ('d', minvalue); create table mcrparted8_ge_d partition of mcrparted for values from ('d', minvalue) to (maxvalue, maxvalue); \d+ mcrparted - Table "public.mcrparted" + Partitioned table "public.mcrparted" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+----------+--------------+------------- a | text | | | | extended | | diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out index 2d7061fa1b0..1338b2b23e1 100644 --- a/src/test/regress/expected/insert_conflict.out +++ b/src/test/regress/expected/insert_conflict.out @@ -443,18 +443,14 @@ drop table insertconflicttest; -- -- Verify that EXCLUDED does not allow system column references. These -- do not make sense because EXCLUDED isn't an already stored tuple --- (and thus doesn't have a ctid, oids are not assigned yet, etc). +-- (and thus doesn't have a ctid etc). -- -create table syscolconflicttest(key int4, data text) WITH OIDS; +create table syscolconflicttest(key int4, data text); insert into syscolconflicttest values (1); insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text; ERROR: column excluded.ctid does not exist LINE 1: ...values (1) on conflict (key) do update set data = excluded.c... ^ -insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.oid::text; -ERROR: column excluded.oid does not exist -LINE 1: ...values (1) on conflict (key) do update set data = excluded.o... - ^ drop table syscolconflicttest; -- -- Previous tests all managed to not test any expressions requiring @@ -620,65 +616,6 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET -- clean up drop table excluded; --- Check tables w/o oids are handled correctly -create table testoids(key int primary key, data text) without oids; --- first without oids -insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 1 | 1 -(1 row) - -insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 1 | 2 -(1 row) - --- add oids -alter table testoids set with oids; --- update existing row, that didn't have an oid -insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 1 | 3 -(1 row) - --- insert a new row -insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 2 | 1 -(1 row) - --- and update it -insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 2 | 2 -(1 row) - --- remove oids again, test -alter table testoids set without oids; -insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 1 | 4 -(1 row) - -insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 3 | 1 -(1 row) - -insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *; - key | data ------+------ - 3 | 2 -(1 row) - -DROP TABLE testoids; -- check that references to columns after dropped columns are handled correctly create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float); insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1); @@ -876,12 +813,54 @@ drop table parted_conflict; -- partition create table parted_conflict (a int, b text) partition by range (a); create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a); +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); create unique index on only parted_conflict_1 (a); create unique index on only parted_conflict (a); alter index parted_conflict_a_idx attach partition parted_conflict_1_a_idx; -create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); insert into parted_conflict values (40, 'forty'); insert into parted_conflict_1 values (40, 'cuarenta') on conflict (a) do update set b = excluded.b; ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification drop table parted_conflict; +-- test whole-row Vars in ON CONFLICT expressions +create table parted_conflict (a int, b text, c int) partition by range (a); +create table parted_conflict_1 (drp text, c int, a int, b text); +alter table parted_conflict_1 drop column drp; +create unique index on parted_conflict (a, b); +alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000); +truncate parted_conflict; +insert into parted_conflict values (50, 'cincuenta', 1); +insert into parted_conflict values (50, 'cincuenta', 2) + on conflict (a, b) do update set (a, b, c) = row(excluded.*) + where parted_conflict = (50, text 'cincuenta', 1) and + excluded = (50, text 'cincuenta', 2); +-- should see (50, 'cincuenta', 2) +select * from parted_conflict order by a; + a | b | c +----+-----------+--- + 50 | cincuenta | 2 +(1 row) + +-- test with statement level triggers +create or replace function parted_conflict_update_func() returns trigger as $$ +declare + r record; +begin + for r in select * from inserted loop + raise notice 'a = %, b = %, c = %', r.a, r.b, r.c; + end loop; + return new; +end; +$$ language plpgsql; +create trigger parted_conflict_update + after update on parted_conflict + referencing new table as inserted + for each statement + execute procedure parted_conflict_update_func(); +truncate parted_conflict; +insert into parted_conflict values (0, 'cero', 1); +insert into parted_conflict values(0, 'cero', 1) + on conflict (a,b) do update set c = parted_conflict.c + 1; +NOTICE: a = 0, b = cero, c = 2 +drop table parted_conflict; +drop function parted_conflict_update_func(); diff --git a/src/test/regress/expected/int2.out b/src/test/regress/expected/int2.out index 3ea4ed93a0a..8c255b9e4dd 100644 --- a/src/test/regress/expected/int2.out +++ b/src/test/regress/expected/int2.out @@ -6,7 +6,7 @@ INSERT INTO INT2_TBL(f1) VALUES ('0 '); INSERT INTO INT2_TBL(f1) VALUES (' 1234 '); INSERT INTO INT2_TBL(f1) VALUES (' -1234'); INSERT INTO INT2_TBL(f1) VALUES ('34.5'); -ERROR: invalid input syntax for integer: "34.5" +ERROR: invalid input syntax for type smallint: "34.5" LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('34.5'); ^ -- largest and smallest values @@ -18,27 +18,27 @@ ERROR: value "100000" is out of range for type smallint LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('100000'); ^ INSERT INTO INT2_TBL(f1) VALUES ('asdf'); -ERROR: invalid input syntax for integer: "asdf" +ERROR: invalid input syntax for type smallint: "asdf" LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('asdf'); ^ INSERT INTO INT2_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for integer: " " +ERROR: invalid input syntax for type smallint: " " LINE 1: INSERT INTO INT2_TBL(f1) VALUES (' '); ^ INSERT INTO INT2_TBL(f1) VALUES ('- 1234'); -ERROR: invalid input syntax for integer: "- 1234" +ERROR: invalid input syntax for type smallint: "- 1234" LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('- 1234'); ^ INSERT INTO INT2_TBL(f1) VALUES ('4 444'); -ERROR: invalid input syntax for integer: "4 444" +ERROR: invalid input syntax for type smallint: "4 444" LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('4 444'); ^ INSERT INTO INT2_TBL(f1) VALUES ('123 dt'); -ERROR: invalid input syntax for integer: "123 dt" +ERROR: invalid input syntax for type smallint: "123 dt" LINE 1: INSERT INTO INT2_TBL(f1) VALUES ('123 dt'); ^ INSERT INTO INT2_TBL(f1) VALUES (''); -ERROR: invalid input syntax for integer: "" +ERROR: invalid input syntax for type smallint: "" LINE 1: INSERT INTO INT2_TBL(f1) VALUES (''); ^ SELECT '' AS five, * FROM INT2_TBL; diff --git a/src/test/regress/expected/int4.out b/src/test/regress/expected/int4.out index 372fd4d94c8..bda7a8daefc 100644 --- a/src/test/regress/expected/int4.out +++ b/src/test/regress/expected/int4.out @@ -6,7 +6,7 @@ INSERT INTO INT4_TBL(f1) VALUES (' 0 '); INSERT INTO INT4_TBL(f1) VALUES ('123456 '); INSERT INTO INT4_TBL(f1) VALUES (' -123456'); INSERT INTO INT4_TBL(f1) VALUES ('34.5'); -ERROR: invalid input syntax for integer: "34.5" +ERROR: invalid input syntax for type integer: "34.5" LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('34.5'); ^ -- largest and smallest values @@ -18,27 +18,27 @@ ERROR: value "1000000000000" is out of range for type integer LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('1000000000000'); ^ INSERT INTO INT4_TBL(f1) VALUES ('asdf'); -ERROR: invalid input syntax for integer: "asdf" +ERROR: invalid input syntax for type integer: "asdf" LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('asdf'); ^ INSERT INTO INT4_TBL(f1) VALUES (' '); -ERROR: invalid input syntax for integer: " " +ERROR: invalid input syntax for type integer: " " LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' '); ^ INSERT INTO INT4_TBL(f1) VALUES (' asdf '); -ERROR: invalid input syntax for integer: " asdf " +ERROR: invalid input syntax for type integer: " asdf " LINE 1: INSERT INTO INT4_TBL(f1) VALUES (' asdf '); ^ INSERT INTO INT4_TBL(f1) VALUES ('- 1234'); -ERROR: invalid input syntax for integer: "- 1234" +ERROR: invalid input syntax for type integer: "- 1234" LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('- 1234'); ^ INSERT INTO INT4_TBL(f1) VALUES ('123 5'); -ERROR: invalid input syntax for integer: "123 5" +ERROR: invalid input syntax for type integer: "123 5" LINE 1: INSERT INTO INT4_TBL(f1) VALUES ('123 5'); ^ INSERT INTO INT4_TBL(f1) VALUES (''); -ERROR: invalid input syntax for integer: "" +ERROR: invalid input syntax for type integer: "" LINE 1: INSERT INTO INT4_TBL(f1) VALUES (''); ^ SELECT '' AS five, * FROM INT4_TBL; diff --git a/src/test/regress/expected/int8-exp-three-digits.out b/src/test/regress/expected/int8-exp-three-digits.out deleted file mode 100644 index 7ad4dcea0fd..00000000000 --- a/src/test/regress/expected/int8-exp-three-digits.out +++ /dev/null @@ -1,888 +0,0 @@ --- --- INT8 --- Test int8 64-bit integers. --- -CREATE TABLE INT8_TBL(q1 int8, q2 int8); -INSERT INTO INT8_TBL VALUES(' 123 ',' 456'); -INSERT INTO INT8_TBL VALUES('123 ','4567890123456789'); -INSERT INTO INT8_TBL VALUES('4567890123456789','123'); -INSERT INTO INT8_TBL VALUES(+4567890123456789,'4567890123456789'); -INSERT INTO INT8_TBL VALUES('+4567890123456789','-4567890123456789'); --- bad inputs -INSERT INTO INT8_TBL(q1) VALUES (' '); -ERROR: invalid input syntax for integer: " " -LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' '); - ^ -INSERT INTO INT8_TBL(q1) VALUES ('xxx'); -ERROR: invalid input syntax for integer: "xxx" -LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('xxx'); - ^ -INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485'); -ERROR: value "3908203590239580293850293850329485" is out of range for type bigint -LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('39082035902395802938502938... - ^ -INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340329840934'); -ERROR: value "-1204982019841029840928340329840934" is out of range for type bigint -LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340... - ^ -INSERT INTO INT8_TBL(q1) VALUES ('- 123'); -ERROR: invalid input syntax for integer: "- 123" -LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('- 123'); - ^ -INSERT INTO INT8_TBL(q1) VALUES (' 345 5'); -ERROR: invalid input syntax for integer: " 345 5" -LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' 345 5'); - ^ -INSERT INTO INT8_TBL(q1) VALUES (''); -ERROR: invalid input syntax for integer: "" -LINE 1: INSERT INTO INT8_TBL(q1) VALUES (''); - ^ -SELECT * FROM INT8_TBL; - q1 | q2 -------------------+------------------- - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(5 rows) - --- int8/int8 cmp -SELECT * FROM INT8_TBL WHERE q2 = 4567890123456789; - q1 | q2 -------------------+------------------ - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE q2 <> 4567890123456789; - q1 | q2 -------------------+------------------- - 123 | 456 - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE q2 < 4567890123456789; - q1 | q2 -------------------+------------------- - 123 | 456 - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE q2 > 4567890123456789; - q1 | q2 -----+---- -(0 rows) - -SELECT * FROM INT8_TBL WHERE q2 <= 4567890123456789; - q1 | q2 -------------------+------------------- - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(5 rows) - -SELECT * FROM INT8_TBL WHERE q2 >= 4567890123456789; - q1 | q2 -------------------+------------------ - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(2 rows) - --- int8/int4 cmp -SELECT * FROM INT8_TBL WHERE q2 = 456; - q1 | q2 ------+----- - 123 | 456 -(1 row) - -SELECT * FROM INT8_TBL WHERE q2 <> 456; - q1 | q2 -------------------+------------------- - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(4 rows) - -SELECT * FROM INT8_TBL WHERE q2 < 456; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE q2 > 456; - q1 | q2 -------------------+------------------ - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE q2 <= 456; - q1 | q2 -------------------+------------------- - 123 | 456 - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE q2 >= 456; - q1 | q2 -------------------+------------------ - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(3 rows) - --- int4/int8 cmp -SELECT * FROM INT8_TBL WHERE 123 = q1; - q1 | q2 ------+------------------ - 123 | 456 - 123 | 4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE 123 <> q1; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE 123 < q1; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE 123 > q1; - q1 | q2 -----+---- -(0 rows) - -SELECT * FROM INT8_TBL WHERE 123 <= q1; - q1 | q2 -------------------+------------------- - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(5 rows) - -SELECT * FROM INT8_TBL WHERE 123 >= q1; - q1 | q2 ------+------------------ - 123 | 456 - 123 | 4567890123456789 -(2 rows) - --- int8/int2 cmp -SELECT * FROM INT8_TBL WHERE q2 = '456'::int2; - q1 | q2 ------+----- - 123 | 456 -(1 row) - -SELECT * FROM INT8_TBL WHERE q2 <> '456'::int2; - q1 | q2 -------------------+------------------- - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(4 rows) - -SELECT * FROM INT8_TBL WHERE q2 < '456'::int2; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE q2 > '456'::int2; - q1 | q2 -------------------+------------------ - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE q2 <= '456'::int2; - q1 | q2 -------------------+------------------- - 123 | 456 - 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE q2 >= '456'::int2; - q1 | q2 -------------------+------------------ - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(3 rows) - --- int2/int8 cmp -SELECT * FROM INT8_TBL WHERE '123'::int2 = q1; - q1 | q2 ------+------------------ - 123 | 456 - 123 | 4567890123456789 -(2 rows) - -SELECT * FROM INT8_TBL WHERE '123'::int2 <> q1; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE '123'::int2 < q1; - q1 | q2 -------------------+------------------- - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(3 rows) - -SELECT * FROM INT8_TBL WHERE '123'::int2 > q1; - q1 | q2 -----+---- -(0 rows) - -SELECT * FROM INT8_TBL WHERE '123'::int2 <= q1; - q1 | q2 -------------------+------------------- - 123 | 456 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(5 rows) - -SELECT * FROM INT8_TBL WHERE '123'::int2 >= q1; - q1 | q2 ------+------------------ - 123 | 456 - 123 | 4567890123456789 -(2 rows) - -SELECT '' AS five, q1 AS plus, -q1 AS minus FROM INT8_TBL; - five | plus | minus -------+------------------+------------------- - | 123 | -123 - | 123 | -123 - | 4567890123456789 | -4567890123456789 - | 4567890123456789 | -4567890123456789 - | 4567890123456789 | -4567890123456789 -(5 rows) - -SELECT '' AS five, q1, q2, q1 + q2 AS plus FROM INT8_TBL; - five | q1 | q2 | plus -------+------------------+-------------------+------------------ - | 123 | 456 | 579 - | 123 | 4567890123456789 | 4567890123456912 - | 4567890123456789 | 123 | 4567890123456912 - | 4567890123456789 | 4567890123456789 | 9135780246913578 - | 4567890123456789 | -4567890123456789 | 0 -(5 rows) - -SELECT '' AS five, q1, q2, q1 - q2 AS minus FROM INT8_TBL; - five | q1 | q2 | minus -------+------------------+-------------------+------------------- - | 123 | 456 | -333 - | 123 | 4567890123456789 | -4567890123456666 - | 4567890123456789 | 123 | 4567890123456666 - | 4567890123456789 | 4567890123456789 | 0 - | 4567890123456789 | -4567890123456789 | 9135780246913578 -(5 rows) - -SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL; -ERROR: bigint out of range -SELECT '' AS three, q1, q2, q1 * q2 AS multiply FROM INT8_TBL - WHERE q1 < 1000 or (q2 > 0 and q2 < 1000); - three | q1 | q2 | multiply --------+------------------+------------------+-------------------- - | 123 | 456 | 56088 - | 123 | 4567890123456789 | 561850485185185047 - | 4567890123456789 | 123 | 561850485185185047 -(3 rows) - -SELECT '' AS five, q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL; - five | q1 | q2 | divide | mod -------+------------------+-------------------+----------------+----- - | 123 | 456 | 0 | 123 - | 123 | 4567890123456789 | 0 | 123 - | 4567890123456789 | 123 | 37137318076884 | 57 - | 4567890123456789 | 4567890123456789 | 1 | 0 - | 4567890123456789 | -4567890123456789 | -1 | 0 -(5 rows) - -SELECT '' AS five, q1, float8(q1) FROM INT8_TBL; - five | q1 | float8 -------+------------------+----------------------- - | 123 | 123 - | 123 | 123 - | 4567890123456789 | 4.56789012345679e+015 - | 4567890123456789 | 4.56789012345679e+015 - | 4567890123456789 | 4.56789012345679e+015 -(5 rows) - -SELECT '' AS five, q2, float8(q2) FROM INT8_TBL; - five | q2 | float8 -------+-------------------+------------------------ - | 456 | 456 - | 4567890123456789 | 4.56789012345679e+015 - | 123 | 123 - | 4567890123456789 | 4.56789012345679e+015 - | -4567890123456789 | -4.56789012345679e+015 -(5 rows) - -SELECT 37 + q1 AS plus4 FROM INT8_TBL; - plus4 ------------------- - 160 - 160 - 4567890123456826 - 4567890123456826 - 4567890123456826 -(5 rows) - -SELECT 37 - q1 AS minus4 FROM INT8_TBL; - minus4 -------------------- - -86 - -86 - -4567890123456752 - -4567890123456752 - -4567890123456752 -(5 rows) - -SELECT '' AS five, 2 * q1 AS "twice int4" FROM INT8_TBL; - five | twice int4 -------+------------------ - | 246 - | 246 - | 9135780246913578 - | 9135780246913578 - | 9135780246913578 -(5 rows) - -SELECT '' AS five, q1 * 2 AS "twice int4" FROM INT8_TBL; - five | twice int4 -------+------------------ - | 246 - | 246 - | 9135780246913578 - | 9135780246913578 - | 9135780246913578 -(5 rows) - --- int8 op int4 -SELECT q1 + 42::int4 AS "8plus4", q1 - 42::int4 AS "8minus4", q1 * 42::int4 AS "8mul4", q1 / 42::int4 AS "8div4" FROM INT8_TBL; - 8plus4 | 8minus4 | 8mul4 | 8div4 -------------------+------------------+--------------------+----------------- - 165 | 81 | 5166 | 2 - 165 | 81 | 5166 | 2 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 -(5 rows) - --- int4 op int8 -SELECT 246::int4 + q1 AS "4plus8", 246::int4 - q1 AS "4minus8", 246::int4 * q1 AS "4mul8", 246::int4 / q1 AS "4div8" FROM INT8_TBL; - 4plus8 | 4minus8 | 4mul8 | 4div8 -------------------+-------------------+---------------------+------- - 369 | 123 | 30258 | 2 - 369 | 123 | 30258 | 2 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 -(5 rows) - --- int8 op int2 -SELECT q1 + 42::int2 AS "8plus2", q1 - 42::int2 AS "8minus2", q1 * 42::int2 AS "8mul2", q1 / 42::int2 AS "8div2" FROM INT8_TBL; - 8plus2 | 8minus2 | 8mul2 | 8div2 -------------------+------------------+--------------------+----------------- - 165 | 81 | 5166 | 2 - 165 | 81 | 5166 | 2 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 - 4567890123456831 | 4567890123456747 | 191851385185185138 | 108759288653733 -(5 rows) - --- int2 op int8 -SELECT 246::int2 + q1 AS "2plus8", 246::int2 - q1 AS "2minus8", 246::int2 * q1 AS "2mul8", 246::int2 / q1 AS "2div8" FROM INT8_TBL; - 2plus8 | 2minus8 | 2mul8 | 2div8 -------------------+-------------------+---------------------+------- - 369 | 123 | 30258 | 2 - 369 | 123 | 30258 | 2 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 - 4567890123457035 | -4567890123456543 | 1123700970370370094 | 0 -(5 rows) - -SELECT q2, abs(q2) FROM INT8_TBL; - q2 | abs --------------------+------------------ - 456 | 456 - 4567890123456789 | 4567890123456789 - 123 | 123 - 4567890123456789 | 4567890123456789 - -4567890123456789 | 4567890123456789 -(5 rows) - -SELECT min(q1), min(q2) FROM INT8_TBL; - min | min ------+------------------- - 123 | -4567890123456789 -(1 row) - -SELECT max(q1), max(q2) FROM INT8_TBL; - max | max -------------------+------------------ - 4567890123456789 | 4567890123456789 -(1 row) - --- TO_CHAR() --- -SELECT '' AS to_char_1, to_char(q1, '9G999G999G999G999G999'), to_char(q2, '9,999,999,999,999,999') - FROM INT8_TBL; - to_char_1 | to_char | to_char ------------+------------------------+------------------------ - | 123 | 456 - | 123 | 4,567,890,123,456,789 - | 4,567,890,123,456,789 | 123 - | 4,567,890,123,456,789 | 4,567,890,123,456,789 - | 4,567,890,123,456,789 | -4,567,890,123,456,789 -(5 rows) - -SELECT '' AS to_char_2, to_char(q1, '9G999G999G999G999G999D999G999'), to_char(q2, '9,999,999,999,999,999.999,999') - FROM INT8_TBL; - to_char_2 | to_char | to_char ------------+--------------------------------+-------------------------------- - | 123.000,000 | 456.000,000 - | 123.000,000 | 4,567,890,123,456,789.000,000 - | 4,567,890,123,456,789.000,000 | 123.000,000 - | 4,567,890,123,456,789.000,000 | 4,567,890,123,456,789.000,000 - | 4,567,890,123,456,789.000,000 | -4,567,890,123,456,789.000,000 -(5 rows) - -SELECT '' AS to_char_3, to_char( (q1 * -1), '9999999999999999PR'), to_char( (q2 * -1), '9999999999999999.999PR') - FROM INT8_TBL; - to_char_3 | to_char | to_char ------------+--------------------+------------------------ - | <123> | <456.000> - | <123> | <4567890123456789.000> - | <4567890123456789> | <123.000> - | <4567890123456789> | <4567890123456789.000> - | <4567890123456789> | 4567890123456789.000 -(5 rows) - -SELECT '' AS to_char_4, to_char( (q1 * -1), '9999999999999999S'), to_char( (q2 * -1), 'S9999999999999999') - FROM INT8_TBL; - to_char_4 | to_char | to_char ------------+-------------------+------------------- - | 123- | -456 - | 123- | -4567890123456789 - | 4567890123456789- | -123 - | 4567890123456789- | -4567890123456789 - | 4567890123456789- | +4567890123456789 -(5 rows) - -SELECT '' AS to_char_5, to_char(q2, 'MI9999999999999999') FROM INT8_TBL; - to_char_5 | to_char ------------+------------------- - | 456 - | 4567890123456789 - | 123 - | 4567890123456789 - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_6, to_char(q2, 'FMS9999999999999999') FROM INT8_TBL; - to_char_6 | to_char ------------+------------------- - | +456 - | +4567890123456789 - | +123 - | +4567890123456789 - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_7, to_char(q2, 'FM9999999999999999THPR') FROM INT8_TBL; - to_char_7 | to_char ------------+-------------------- - | 456TH - | 4567890123456789TH - | 123RD - | 4567890123456789TH - | <4567890123456789> -(5 rows) - -SELECT '' AS to_char_8, to_char(q2, 'SG9999999999999999th') FROM INT8_TBL; - to_char_8 | to_char ------------+--------------------- - | + 456th - | +4567890123456789th - | + 123rd - | +4567890123456789th - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_9, to_char(q2, '0999999999999999') FROM INT8_TBL; - to_char_9 | to_char ------------+------------------- - | 0000000000000456 - | 4567890123456789 - | 0000000000000123 - | 4567890123456789 - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_10, to_char(q2, 'S0999999999999999') FROM INT8_TBL; - to_char_10 | to_char -------------+------------------- - | +0000000000000456 - | +4567890123456789 - | +0000000000000123 - | +4567890123456789 - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_11, to_char(q2, 'FM0999999999999999') FROM INT8_TBL; - to_char_11 | to_char -------------+------------------- - | 0000000000000456 - | 4567890123456789 - | 0000000000000123 - | 4567890123456789 - | -4567890123456789 -(5 rows) - -SELECT '' AS to_char_12, to_char(q2, 'FM9999999999999999.000') FROM INT8_TBL; - to_char_12 | to_char -------------+----------------------- - | 456.000 - | 4567890123456789.000 - | 123.000 - | 4567890123456789.000 - | -4567890123456789.000 -(5 rows) - -SELECT '' AS to_char_13, to_char(q2, 'L9999999999999999.000') FROM INT8_TBL; - to_char_13 | to_char -------------+------------------------ - | 456.000 - | 4567890123456789.000 - | 123.000 - | 4567890123456789.000 - | -4567890123456789.000 -(5 rows) - -SELECT '' AS to_char_14, to_char(q2, 'FM9999999999999999.999') FROM INT8_TBL; - to_char_14 | to_char -------------+-------------------- - | 456. - | 4567890123456789. - | 123. - | 4567890123456789. - | -4567890123456789. -(5 rows) - -SELECT '' AS to_char_15, to_char(q2, 'S 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 . 9 9 9') FROM INT8_TBL; - to_char_15 | to_char -------------+------------------------------------------- - | +4 5 6 . 0 0 0 - | +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0 - | +1 2 3 . 0 0 0 - | +4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0 - | -4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 . 0 0 0 -(5 rows) - -SELECT '' AS to_char_16, to_char(q2, E'99999 "text" 9999 "9999" 999 "\\"text between quote marks\\"" 9999') FROM INT8_TBL; - to_char_16 | to_char -------------+----------------------------------------------------------- - | text 9999 "text between quote marks" 456 - | 45678 text 9012 9999 345 "text between quote marks" 6789 - | text 9999 "text between quote marks" 123 - | 45678 text 9012 9999 345 "text between quote marks" 6789 - | -45678 text 9012 9999 345 "text between quote marks" 6789 -(5 rows) - -SELECT '' AS to_char_17, to_char(q2, '999999SG9999999999') FROM INT8_TBL; - to_char_17 | to_char -------------+------------------- - | + 456 - | 456789+0123456789 - | + 123 - | 456789+0123456789 - | 456789-0123456789 -(5 rows) - --- check min/max values and overflow behavior -select '-9223372036854775808'::int8; - int8 ----------------------- - -9223372036854775808 -(1 row) - -select '-9223372036854775809'::int8; -ERROR: value "-9223372036854775809" is out of range for type bigint -LINE 1: select '-9223372036854775809'::int8; - ^ -select '9223372036854775807'::int8; - int8 ---------------------- - 9223372036854775807 -(1 row) - -select '9223372036854775808'::int8; -ERROR: value "9223372036854775808" is out of range for type bigint -LINE 1: select '9223372036854775808'::int8; - ^ -select -('-9223372036854775807'::int8); - ?column? ---------------------- - 9223372036854775807 -(1 row) - -select -('-9223372036854775808'::int8); -ERROR: bigint out of range -select '9223372036854775800'::int8 + '9223372036854775800'::int8; -ERROR: bigint out of range -select '-9223372036854775800'::int8 + '-9223372036854775800'::int8; -ERROR: bigint out of range -select '9223372036854775800'::int8 - '-9223372036854775800'::int8; -ERROR: bigint out of range -select '-9223372036854775800'::int8 - '9223372036854775800'::int8; -ERROR: bigint out of range -select '9223372036854775800'::int8 * '9223372036854775800'::int8; -ERROR: bigint out of range -select '9223372036854775800'::int8 / '0'::int8; -ERROR: division by zero -select '9223372036854775800'::int8 % '0'::int8; -ERROR: division by zero -select abs('-9223372036854775808'::int8); -ERROR: bigint out of range -select '9223372036854775800'::int8 + '100'::int4; -ERROR: bigint out of range -select '-9223372036854775800'::int8 - '100'::int4; -ERROR: bigint out of range -select '9223372036854775800'::int8 * '100'::int4; -ERROR: bigint out of range -select '100'::int4 + '9223372036854775800'::int8; -ERROR: bigint out of range -select '-100'::int4 - '9223372036854775800'::int8; -ERROR: bigint out of range -select '100'::int4 * '9223372036854775800'::int8; -ERROR: bigint out of range -select '9223372036854775800'::int8 + '100'::int2; -ERROR: bigint out of range -select '-9223372036854775800'::int8 - '100'::int2; -ERROR: bigint out of range -select '9223372036854775800'::int8 * '100'::int2; -ERROR: bigint out of range -select '-9223372036854775808'::int8 / '0'::int2; -ERROR: division by zero -select '100'::int2 + '9223372036854775800'::int8; -ERROR: bigint out of range -select '-100'::int2 - '9223372036854775800'::int8; -ERROR: bigint out of range -select '100'::int2 * '9223372036854775800'::int8; -ERROR: bigint out of range -select '100'::int2 / '0'::int8; -ERROR: division by zero -SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 = 456; - q1 ------ - 123 -(1 row) - -SELECT CAST(q1 AS int4) FROM int8_tbl WHERE q2 <> 456; -ERROR: integer out of range -SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 = 456; - q1 ------ - 123 -(1 row) - -SELECT CAST(q1 AS int2) FROM int8_tbl WHERE q2 <> 456; -ERROR: smallint out of range -SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8); - int8 | int8 -------+------ - 42 | -37 -(1 row) - -SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL; - q1 | q2 ---------------+------------------------ - 123 | 456 - 123 | 4.56789012345679e+015 - 4.56789e+015 | 123 - 4.56789e+015 | 4.56789012345679e+015 - 4.56789e+015 | -4.56789012345679e+015 -(5 rows) - -SELECT CAST('36854775807.0'::float4 AS int8); - int8 -------------- - 36854775808 -(1 row) - -SELECT CAST('922337203685477580700.0'::float8 AS int8); -ERROR: bigint out of range -SELECT CAST(q1 AS oid) FROM INT8_TBL; -ERROR: OID out of range -SELECT oid::int8 FROM pg_class WHERE relname = 'pg_class'; - oid ------- - 1259 -(1 row) - --- bit operations -SELECT q1, q2, q1 & q2 AS "and", q1 | q2 AS "or", q1 # q2 AS "xor", ~q1 AS "not" FROM INT8_TBL; - q1 | q2 | and | or | xor | not -------------------+-------------------+------------------+------------------+------------------+------------------- - 123 | 456 | 72 | 507 | 435 | -124 - 123 | 4567890123456789 | 17 | 4567890123456895 | 4567890123456878 | -124 - 4567890123456789 | 123 | 17 | 4567890123456895 | 4567890123456878 | -4567890123456790 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 0 | -4567890123456790 - 4567890123456789 | -4567890123456789 | 1 | -1 | -2 | -4567890123456790 -(5 rows) - -SELECT q1, q1 << 2 AS "shl", q1 >> 3 AS "shr" FROM INT8_TBL; - q1 | shl | shr -------------------+-------------------+----------------- - 123 | 492 | 15 - 123 | 492 | 15 - 4567890123456789 | 18271560493827156 | 570986265432098 - 4567890123456789 | 18271560493827156 | 570986265432098 - 4567890123456789 | 18271560493827156 | 570986265432098 -(5 rows) - --- generate_series -SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8); - generate_series ------------------- - 4567890123456789 - 4567890123456790 - 4567890123456791 - 4567890123456792 - 4567890123456793 - 4567890123456794 - 4567890123456795 - 4567890123456796 - 4567890123456797 - 4567890123456798 - 4567890123456799 -(11 rows) - -SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 0); -ERROR: step size cannot equal zero -SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::int8, 2); - generate_series ------------------- - 4567890123456789 - 4567890123456791 - 4567890123456793 - 4567890123456795 - 4567890123456797 - 4567890123456799 -(6 rows) - --- corner case -SELECT (-1::int8<<63)::text; - text ----------------------- - -9223372036854775808 -(1 row) - -SELECT ((-1::int8<<63)+1)::text; - text ----------------------- - -9223372036854775807 -(1 row) - --- check sane handling of INT64_MIN overflow cases -SELECT (-9223372036854775808)::int8 * (-1)::int8; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 / (-1)::int8; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 % (-1)::int8; - ?column? ----------- - 0 -(1 row) - -SELECT (-9223372036854775808)::int8 * (-1)::int4; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 / (-1)::int4; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 % (-1)::int4; - ?column? ----------- - 0 -(1 row) - -SELECT (-9223372036854775808)::int8 * (-1)::int2; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 / (-1)::int2; -ERROR: bigint out of range -SELECT (-9223372036854775808)::int8 % (-1)::int2; - ?column? ----------- - 0 -(1 row) - --- check rounding when casting from float -SELECT x, x::int8 AS int8_value -FROM (VALUES (-2.5::float8), - (-1.5::float8), - (-0.5::float8), - (0.0::float8), - (0.5::float8), - (1.5::float8), - (2.5::float8)) t(x); - x | int8_value -------+------------ - -2.5 | -2 - -1.5 | -2 - -0.5 | 0 - 0 | 0 - 0.5 | 0 - 1.5 | 2 - 2.5 | 2 -(7 rows) - --- check rounding when casting from numeric -SELECT x, x::int8 AS int8_value -FROM (VALUES (-2.5::numeric), - (-1.5::numeric), - (-0.5::numeric), - (0.0::numeric), - (0.5::numeric), - (1.5::numeric), - (2.5::numeric)) t(x); - x | int8_value -------+------------ - -2.5 | -3 - -1.5 | -2 - -0.5 | -1 - 0.0 | 0 - 0.5 | 1 - 1.5 | 2 - 2.5 | 3 -(7 rows) - diff --git a/src/test/regress/expected/int8.out b/src/test/regress/expected/int8.out index ed0bd34221e..8447a28c3d3 100644 --- a/src/test/regress/expected/int8.out +++ b/src/test/regress/expected/int8.out @@ -10,11 +10,11 @@ INSERT INTO INT8_TBL VALUES(+4567890123456789,'4567890123456789'); INSERT INTO INT8_TBL VALUES('+4567890123456789','-4567890123456789'); -- bad inputs INSERT INTO INT8_TBL(q1) VALUES (' '); -ERROR: invalid input syntax for integer: " " +ERROR: invalid input syntax for type bigint: " " LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' '); ^ INSERT INTO INT8_TBL(q1) VALUES ('xxx'); -ERROR: invalid input syntax for integer: "xxx" +ERROR: invalid input syntax for type bigint: "xxx" LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('xxx'); ^ INSERT INTO INT8_TBL(q1) VALUES ('3908203590239580293850293850329485'); @@ -26,15 +26,15 @@ ERROR: value "-1204982019841029840928340329840934" is out of range for type big LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('-1204982019841029840928340... ^ INSERT INTO INT8_TBL(q1) VALUES ('- 123'); -ERROR: invalid input syntax for integer: "- 123" +ERROR: invalid input syntax for type bigint: "- 123" LINE 1: INSERT INTO INT8_TBL(q1) VALUES ('- 123'); ^ INSERT INTO INT8_TBL(q1) VALUES (' 345 5'); -ERROR: invalid input syntax for integer: " 345 5" +ERROR: invalid input syntax for type bigint: " 345 5" LINE 1: INSERT INTO INT8_TBL(q1) VALUES (' 345 5'); ^ INSERT INTO INT8_TBL(q1) VALUES (''); -ERROR: invalid input syntax for integer: "" +ERROR: invalid input syntax for type bigint: "" LINE 1: INSERT INTO INT8_TBL(q1) VALUES (''); ^ SELECT * FROM INT8_TBL; @@ -329,23 +329,23 @@ SELECT '' AS five, q1, q2, q1 / q2 AS divide, q1 % q2 AS mod FROM INT8_TBL; (5 rows) SELECT '' AS five, q1, float8(q1) FROM INT8_TBL; - five | q1 | float8 -------+------------------+---------------------- - | 123 | 123 - | 123 | 123 - | 4567890123456789 | 4.56789012345679e+15 - | 4567890123456789 | 4.56789012345679e+15 - | 4567890123456789 | 4.56789012345679e+15 + five | q1 | float8 +------+------------------+----------------------- + | 123 | 123 + | 123 | 123 + | 4567890123456789 | 4.567890123456789e+15 + | 4567890123456789 | 4.567890123456789e+15 + | 4567890123456789 | 4.567890123456789e+15 (5 rows) SELECT '' AS five, q2, float8(q2) FROM INT8_TBL; - five | q2 | float8 -------+-------------------+----------------------- - | 456 | 456 - | 4567890123456789 | 4.56789012345679e+15 - | 123 | 123 - | 4567890123456789 | 4.56789012345679e+15 - | -4567890123456789 | -4.56789012345679e+15 + five | q2 | float8 +------+-------------------+------------------------ + | 456 | 456 + | 4567890123456789 | 4.567890123456789e+15 + | 123 | 123 + | 4567890123456789 | 4.567890123456789e+15 + | -4567890123456789 | -4.567890123456789e+15 (5 rows) SELECT 37 + q1 AS plus4 FROM INT8_TBL; @@ -726,13 +726,13 @@ SELECT CAST('42'::int2 AS int8), CAST('-37'::int2 AS int8); (1 row) SELECT CAST(q1 AS float4), CAST(q2 AS float8) FROM INT8_TBL; - q1 | q2 --------------+----------------------- - 123 | 456 - 123 | 4.56789012345679e+15 - 4.56789e+15 | 123 - 4.56789e+15 | 4.56789012345679e+15 - 4.56789e+15 | -4.56789012345679e+15 + q1 | q2 +-------------+------------------------ + 123 | 456 + 123 | 4.567890123456789e+15 + 4.56789e+15 | 123 + 4.56789e+15 | 4.567890123456789e+15 + 4.56789e+15 | -4.567890123456789e+15 (5 rows) SELECT CAST('36854775807.0'::float4 AS int8); diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index 84c6e9b5a40..b58d560163b 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -31,6 +31,10 @@ INSERT INTO J2_TBL VALUES (5, -5); INSERT INTO J2_TBL VALUES (0, NULL); INSERT INTO J2_TBL VALUES (NULL, NULL); INSERT INTO J2_TBL VALUES (NULL, 0); +-- useful in some tests below +create temp table onerow(); +insert into onerow default values; +analyze onerow; -- -- CORRELATION NAMES -- Make sure that table/column aliases are supported @@ -2024,6 +2028,20 @@ NATURAL FULL JOIN ee | | 42 | 2 | (4 rows) +-- Constants as join keys can also be problematic +SELECT * FROM + (SELECT name, n as s1_n FROM t1) as s1 +FULL JOIN + (SELECT name, 2 as s2_n FROM t2) as s2 +ON (s1_n = s2_n); + name | s1_n | name | s2_n +------+------+------+------ + | | bb | 2 + | | cc | 2 + | | ee | 2 + bb | 11 | | +(4 rows) + -- Test for propagation of nullability constraints into sub-joins create temp table x (x1 int, x2 int); insert into x values (1,11); @@ -2213,20 +2231,17 @@ explain (costs off) select * from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 order by 1, 2; - QUERY PLAN -------------------------------------------------- + QUERY PLAN +------------------------------------------- Sort Sort Key: i1.q1, i1.q2 -> Hash Left Join Hash Cond: (i1.q2 = i2.q2) -> Seq Scan on int8_tbl i1 -> Hash - -> Hash Join - Hash Cond: (i2.q1 = (123)) - -> Seq Scan on int8_tbl i2 - -> Hash - -> Result -(11 rows) + -> Seq Scan on int8_tbl i2 + Filter: (q1 = 123) +(8 rows) select * from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 @@ -2672,6 +2687,36 @@ select * from a left join b on i = x and i = y and x = i; ---+---+--- (0 rows) +rollback; +-- +-- test handling of merge clauses using record_ops +-- +begin; +create type mycomptype as (id int, v bigint); +create temp table tidv (idv mycomptype); +create index on tidv (idv); +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + QUERY PLAN +---------------------------------------------------------- + Merge Join + Merge Cond: (a.idv = b.idv) + -> Index Only Scan using tidv_idv_idx on tidv a + -> Materialize + -> Index Only Scan using tidv_idv_idx on tidv b +(5 rows) + +set enable_mergejoin = 0; +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + QUERY PLAN +---------------------------------------------------- + Nested Loop + -> Seq Scan on tidv a + -> Index Only Scan using tidv_idv_idx on tidv b + Index Cond: (idv = a.idv) +(4 rows) + rollback; -- -- test NULL behavior of whole-row Vars, per bug #5025 @@ -2824,7 +2869,7 @@ SELECT qq, unique1 --------------------------------------------------------------------------------------------------------- Nested Loop -> Hash Full Join - Hash Cond: (COALESCE(a.q1, '0'::bigint) = COALESCE(b.q2, '-1'::bigint)) + Hash Cond: ((COALESCE(a.q1, '0'::bigint)) = (COALESCE(b.q2, '-1'::bigint))) -> Seq Scan on int8_tbl a -> Hash -> Seq Scan on int8_tbl b @@ -3015,11 +3060,14 @@ select * from int4_tbl a full join int4_tbl b on false; -- -- test for ability to use a cartesian join when necessary -- +create temp table q1 as select 1 as q1; +create temp table q2 as select 0 as q2; +analyze q1; +analyze q2; explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, - int4(sin(1)) q1, - int4(sin(0)) q2 + q1, q2 where q1 = thousand or q2 = thousand; QUERY PLAN ------------------------------------------------------------------------ @@ -3027,15 +3075,15 @@ where q1 = thousand or q2 = thousand; Hash Cond: (tenk1.twothousand = int4_tbl.f1) -> Nested Loop -> Nested Loop - -> Function Scan on q1 - -> Function Scan on q2 + -> Seq Scan on q1 + -> Seq Scan on q2 -> Bitmap Heap Scan on tenk1 Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand)) -> BitmapOr -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (q1.q1 = thousand) + Index Cond: (thousand = q1.q1) -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (q2.q2 = thousand) + Index Cond: (thousand = q2.q2) -> Hash -> Seq Scan on int4_tbl (15 rows) @@ -3043,8 +3091,7 @@ where q1 = thousand or q2 = thousand; explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, - int4(sin(1)) q1, - int4(sin(0)) q2 + q1, q2 where thousand = (q1 + q2); QUERY PLAN -------------------------------------------------------------- @@ -3052,8 +3099,8 @@ where thousand = (q1 + q2); Hash Cond: (tenk1.twothousand = int4_tbl.f1) -> Nested Loop -> Nested Loop - -> Function Scan on q1 - -> Function Scan on q2 + -> Seq Scan on q1 + -> Seq Scan on q2 -> Bitmap Heap Scan on tenk1 Recheck Cond: (thousand = (q1.q1 + q2.q2)) -> Bitmap Index Scan on tenk1_thous_tenthous @@ -3089,8 +3136,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -3100,27 +3147,26 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; QUERY PLAN ----------------------------------------------------------------------- Nested Loop - Join Filter: (t1.stringu1 > t2.stringu2) -> Nested Loop - Join Filter: ((0) = i1.f1) + Join Filter: (t1.stringu1 > t2.stringu2) -> Nested Loop -> Nested Loop - Join Filter: ((1) = (1)) - -> Result - -> Result + -> Seq Scan on onerow + -> Seq Scan on onerow onerow_1 -> Index Scan using tenk1_unique2 on tenk1 t1 Index Cond: ((unique2 = (11)) AND (unique2 < 42)) - -> Seq Scan on int4_tbl i1 - -> Index Scan using tenk1_unique1 on tenk1 t2 - Index Cond: (unique1 = (3)) -(14 rows) + -> Index Scan using tenk1_unique1 on tenk1 t2 + Index Cond: (unique1 = (3)) + -> Seq Scan on int4_tbl i1 + Filter: (f1 = 0) +(13 rows) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -3152,6 +3198,210 @@ where t1.unique1 < i4.f1; ---- (0 rows) +-- this variant is foldable by the remove-useless-RESULT-RTEs code +explain (costs off) +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + QUERY PLAN +----------------------------------------------------------------- + Nested Loop + Join Filter: (t1.stringu1 > t2.stringu2) + -> Nested Loop + -> Seq Scan on int4_tbl i1 + Filter: (f1 = 0) + -> Index Scan using tenk1_unique2 on tenk1 t1 + Index Cond: ((unique2 = (11)) AND (unique2 < 42)) + -> Index Scan using tenk1_unique1 on tenk1 t2 + Index Cond: (unique1 = (3)) +(9 rows) + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + unique2 | stringu1 | unique1 | stringu2 +---------+----------+---------+---------- + 11 | WFAAAA | 3 | LKIAAA +(1 row) + +-- +-- test inlining of immutable functions +-- +create function f_immutable_int4(i integer) returns integer as +$$ begin return i; end; $$ language plpgsql immutable; +-- check optimization of function scan with join +explain (costs off) +select unique1 from tenk1, (select * from f_immutable_int4(1) x) x +where x = unique1; + QUERY PLAN +---------------------------------------------- + Index Only Scan using tenk1_unique1 on tenk1 + Index Cond: (unique1 = 1) +(2 rows) + +explain (verbose, costs off) +select unique1, x.* +from tenk1, (select *, random() from f_immutable_int4(1) x) x +where x = unique1; + QUERY PLAN +----------------------------------------------------------- + Nested Loop + Output: tenk1.unique1, (1), (random()) + -> Result + Output: 1, random() + -> Index Only Scan using tenk1_unique1 on public.tenk1 + Output: tenk1.unique1 + Index Cond: (tenk1.unique1 = (1)) +(7 rows) + +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; + QUERY PLAN +---------------------------------------------- + Index Only Scan using tenk1_unique1 on tenk1 + Index Cond: (unique1 = 1) +(2 rows) + +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; + QUERY PLAN +---------------------------------------------- + Index Only Scan using tenk1_unique1 on tenk1 + Index Cond: (unique1 = 1) +(2 rows) + +explain (costs off) +select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; + QUERY PLAN +---------------------------------------------- + Index Only Scan using tenk1_unique1 on tenk1 + Index Cond: (unique1 = 1) +(2 rows) + +explain (costs off) +select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; + QUERY PLAN +---------------------------------------------------- + Nested Loop Left Join + Join Filter: (tenk1.unique1 = 1) + -> Index Only Scan using tenk1_unique1 on tenk1 + -> Materialize + -> Result +(5 rows) + +explain (costs off) +select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; + QUERY PLAN +---------------------------------------------------- + Nested Loop Left Join + -> Result + -> Index Only Scan using tenk1_unique1 on tenk1 + Index Cond: (unique1 = 1) +(4 rows) + +explain (costs off) +select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; + QUERY PLAN +---------------------------------------------------- + Merge Full Join + Merge Cond: (tenk1.unique1 = (1)) + -> Index Only Scan using tenk1_unique1 on tenk1 + -> Sort + Sort Key: (1) + -> Result +(6 rows) + +-- check that pullup of a const function allows further const-folding +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = 42; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +-- test inlining of immutable functions with PlaceHolderVars +explain (costs off) +select nt3.id +from nt3 as nt3 + left join + (select nt2.*, (nt2.b1 or i4 = 42) AS b3 + from nt2 as nt2 + left join + f_immutable_int4(0) i4 + on i4 = nt2.nt1_id + ) as ss2 + on ss2.id = nt3.nt2_id +where nt3.id = 1 and ss2.b3; + QUERY PLAN +---------------------------------------------- + Nested Loop Left Join + Filter: ((nt2.b1 OR ((0) = 42))) + -> Index Scan using nt3_pkey on nt3 + Index Cond: (id = 1) + -> Nested Loop Left Join + Join Filter: (0 = nt2.nt1_id) + -> Index Scan using nt2_pkey on nt2 + Index Cond: (id = nt3.nt2_id) + -> Result +(9 rows) + +drop function f_immutable_int4(int); +-- test inlining when function returns composite +create function mki8(bigint, bigint) returns int8_tbl as +$$select row($1,$2)::int8_tbl$$ language sql; +create function mki4(int) returns int4_tbl as +$$select row($1)::int4_tbl$$ language sql; +explain (verbose, costs off) +select * from mki8(1,2); + QUERY PLAN +------------------------------------ + Function Scan on mki8 + Output: q1, q2 + Function Call: '(1,2)'::int8_tbl +(3 rows) + +select * from mki8(1,2); + q1 | q2 +----+---- + 1 | 2 +(1 row) + +explain (verbose, costs off) +select * from mki4(42); + QUERY PLAN +----------------------------------- + Function Scan on mki4 + Output: f1 + Function Call: '(42)'::int4_tbl +(3 rows) + +select * from mki4(42); + f1 +---- + 42 +(1 row) + +drop function mki8(bigint, bigint); +drop function mki4(int); -- -- test extraction of restriction OR clauses from join OR clause -- (we used to only do this for indexable clauses) @@ -3244,7 +3494,7 @@ where t1.unique1 = 1; -> Bitmap Heap Scan on tenk1 t2 Recheck Cond: (t1.hundred = hundred) -> Bitmap Index Scan on tenk1_hundred - Index Cond: (t1.hundred = hundred) + Index Cond: (hundred = t1.hundred) -> Index Scan using tenk1_unique2 on tenk1 t3 Index Cond: (unique2 = t2.thousand) (11 rows) @@ -3264,7 +3514,7 @@ where t1.unique1 = 1; -> Bitmap Heap Scan on tenk1 t2 Recheck Cond: (t1.hundred = hundred) -> Bitmap Index Scan on tenk1_hundred - Index Cond: (t1.hundred = hundred) + Index Cond: (hundred = t1.hundred) -> Index Scan using tenk1_unique2 on tenk1 t3 Index Cond: (unique2 = t2.thousand) (11 rows) @@ -3320,7 +3570,7 @@ select b.unique1 from -> Nested Loop -> Seq Scan on int4_tbl i1 -> Index Scan using tenk1_thous_tenthous on tenk1 b - Index Cond: ((thousand = i1.f1) AND (i2.f1 = tenthous)) + Index Cond: ((thousand = i1.f1) AND (tenthous = i2.f1)) -> Index Scan using tenk1_unique1 on tenk1 a Index Cond: (unique1 = b.unique2) -> Index Only Scan using tenk1_thous_tenthous on tenk1 c @@ -3356,7 +3606,7 @@ order by fault; Filter: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1) = 122) -> Seq Scan on int8_tbl -> Index Scan using tenk1_unique2 on tenk1 - Index Cond: (int8_tbl.q2 = unique2) + Index Cond: (unique2 = int8_tbl.q2) (5 rows) select * from @@ -3371,6 +3621,33 @@ order by fault; | 123 | 122 (1 row) +explain (costs off) +select * from +(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) +left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x +left join unnest(v1ys) as u1(u1y) on u1y = v2y; + QUERY PLAN +------------------------------------------------------------- + Nested Loop Left Join + -> Values Scan on "*VALUES*" + -> Hash Right Join + Hash Cond: (u1.u1y = "*VALUES*_1".column2) + Filter: ("*VALUES*_1".column1 = "*VALUES*".column1) + -> Function Scan on unnest u1 + -> Hash + -> Values Scan on "*VALUES*_1" +(8 rows) + +select * from +(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) +left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x +left join unnest(v1ys) as u1(u1y) on u1y = v2y; + v1x | v1ys | v2x | v2y | u1y +-----+---------+-----+-----+----- + 1 | {10,20} | 1 | 10 | 10 + 2 | {20,30} | 2 | 20 | 20 +(2 rows) + -- -- test handling of potential equivalence clauses above outer joins -- @@ -3384,7 +3661,7 @@ select q1, unique2, thousand, hundred Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) -> Seq Scan on int8_tbl a -> Index Scan using tenk1_unique2 on tenk1 b - Index Cond: (a.q1 = unique2) + Index Cond: (unique2 = a.q1) (5 rows) select q1, unique2, thousand, hundred @@ -3525,7 +3802,7 @@ select t1.* from -> Hash Right Join Output: i8.q2 Hash Cond: ((NULL::integer) = i8b1.q2) - -> Hash Left Join + -> Hash Join Output: i8.q2, (NULL::integer) Hash Cond: (i8.q1 = i8b2.q1) -> Seq Scan on public.int8_tbl i8 @@ -3947,10 +4224,10 @@ select * from QUERY PLAN --------------------------------------- Nested Loop Left Join - Join Filter: ((1) = COALESCE((1))) -> Result -> Hash Full Join Hash Cond: (a1.unique1 = (1)) + Filter: (1 = COALESCE((1))) -> Seq Scan on tenk1 a1 -> Hash -> Result @@ -4471,7 +4748,7 @@ explain (costs off) Nested Loop Left Join -> Seq Scan on int4_tbl x -> Index Scan using tenk1_unique1 on tenk1 - Index Cond: (x.f1 = unique1) + Index Cond: (unique1 = x.f1) (4 rows) -- check scoping of lateral versus parent references @@ -4880,13 +5157,10 @@ select v.* from -4567890123456789 | (20 rows) -create temp table dual(); -insert into dual default values; -analyze dual; select v.* from (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) left join int4_tbl z on z.f1 = x.q2, - lateral (select x.q1,y.q1 from dual union all select x.q2,y.q2 from dual) v(vx,vy); + lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); vx | vy -------------------+------------------- 4567890123456789 | 123 @@ -5268,6 +5542,35 @@ select * from Output: 3 (11 rows) +-- check dummy rels with lateral references (bug #15694) +explain (verbose, costs off) +select * from int8_tbl i8 left join lateral + (select *, i8.q2 from int4_tbl where false) ss on true; + QUERY PLAN +-------------------------------------- + Nested Loop Left Join + Output: i8.q1, i8.q2, f1, (i8.q2) + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, i8.q2 + -> Result + Output: f1, i8.q2 + One-Time Filter: false +(7 rows) + +explain (verbose, costs off) +select * from int8_tbl i8 left join lateral + (select *, i8.q2 from int4_tbl i1, int4_tbl i2 where false) ss on true; + QUERY PLAN +----------------------------------------- + Nested Loop Left Join + Output: i8.q1, i8.q2, f1, f1, (i8.q2) + -> Seq Scan on public.int8_tbl i8 + Output: i8.q1, i8.q2 + -> Result + Output: f1, f1, i8.q2 + One-Time Filter: false +(7 rows) + -- check handling of nested appendrels inside LATERAL select * from ((select 2 as v) union all (select 3 as v)) as q1 @@ -5820,22 +6123,26 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; set enable_nestloop to 0; set enable_hashjoin to 0; set enable_sort to 0; --- create an index that will be preferred over the PK to perform the join +-- create indexes that will be preferred over the PKs to perform the join create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; -explain (costs off) select * from j1 j1 -inner join j1 j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 +create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; +-- need an additional row in j2, if we want j2_id1_idx to be preferred +insert into j2 values(1,2); +analyze j2; +explain (costs off) select * from j1 +inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; - QUERY PLAN --------------------------------------------- + QUERY PLAN +----------------------------------------- Merge Join Merge Cond: (j1.id1 = j2.id1) Join Filter: (j1.id2 = j2.id2) -> Index Scan using j1_id1_idx on j1 - -> Index Scan using j1_id1_idx on j1 j2 + -> Index Scan using j2_id1_idx on j2 (5 rows) -select * from j1 j1 -inner join j1 j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 +select * from j1 +inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; id1 | id2 | id1 | id2 -----+-----+-----+----- @@ -5906,883 +6213,3 @@ where exists (select 1 from j3 (13 rows) drop table j3; --- --- exercises for the hash join code --- -begin; -set local min_parallel_table_scan_size = 0; -set local parallel_setup_cost = 0; --- Extract bucket and batch counts from an explain analyze plan. In --- general we can't make assertions about how many batches (or --- buckets) will be required because it can vary, but we can in some --- special cases and we can check for growth. -create or replace function find_hash(node json) -returns json language plpgsql -as -$$ -declare - x json; - child json; -begin - if node->>'Node Type' = 'Hash' then - return node; - else - for child in select json_array_elements(node->'Plans') - loop - x := find_hash(child); - if x is not null then - return x; - end if; - end loop; - return null; - end if; -end; -$$; -create or replace function hash_join_batches(query text) -returns table (original int, final int) language plpgsql -as -$$ -declare - whole_plan json; - hash_node json; -begin - for whole_plan in - execute 'explain (analyze, format ''json'') ' || query - loop - hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); - original := hash_node->>'Original Hash Batches'; - final := hash_node->>'Hash Batches'; - return next; - end loop; -end; -$$; --- Make a simple relation with well distributed keys and correctly --- estimated size. -create table simple as - select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; -alter table simple set (parallel_workers = 2); -analyze simple; --- Make a relation whose size we will under-estimate. We want stats --- to say 1000 rows, but actually there are 20,000 rows. -create table bigger_than_it_looks as - select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; -alter table bigger_than_it_looks set (autovacuum_enabled = 'false'); -alter table bigger_than_it_looks set (parallel_workers = 2); -analyze bigger_than_it_looks; -update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks'; --- Make a relation whose size we underestimate and that also has a --- kind of skew that breaks our batching scheme. We want stats to say --- 2 rows, but actually there are 20,000 rows with the same key. -create table extremely_skewed (id int, t text); -alter table extremely_skewed set (autovacuum_enabled = 'false'); -alter table extremely_skewed set (parallel_workers = 2); -analyze extremely_skewed; -insert into extremely_skewed - select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - from generate_series(1, 20000); -update pg_class - set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 - where relname = 'extremely_skewed'; --- Make a relation with a couple of enormous tuples. -create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t; -alter table wide set (parallel_workers = 2); --- The "optimal" case: the hash table fits in memory; we plan for 1 --- batch, we stick to that number, and peak memory usage stays within --- our work_mem budget --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '4MB'; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | f -(1 row) - -rollback to settings; --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN -------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(9 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | f -(1 row) - -rollback to settings; --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN -------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Parallel Hash - -> Parallel Seq Scan on simple s -(9 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | f -(1 row) - -rollback to settings; --- The "good" case: batches required, but we plan the right number; we --- plan for some number of batches, and we stick to that number, and --- peak memory usage says within our work_mem budget --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - t | f -(1 row) - -rollback to settings; --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN -------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(9 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - t | f -(1 row) - -rollback to settings; --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '192kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join simple s using (id); - QUERY PLAN -------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Parallel Hash - -> Parallel Seq Scan on simple s -(9 rows) - -select count(*) from simple r join simple s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - t | f -(1 row) - -rollback to settings; --- The "bad" case: during execution we need to increase number of --- batches; in this case we plan for 1 batch, and increase at least a --- couple of times, and peak memory usage stays within our work_mem --- budget --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on bigger_than_it_looks s -(6 rows) - -select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | t -(1 row) - -rollback to settings; --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join bigger_than_it_looks s using (id); - QUERY PLAN ------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Hash - -> Seq Scan on bigger_than_it_looks s -(9 rows) - -select count(*) from simple r join bigger_than_it_looks s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join bigger_than_it_looks s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | t -(1 row) - -rollback to settings; --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 1; -set local work_mem = '192kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join bigger_than_it_looks s using (id); - QUERY PLAN ---------------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 1 - -> Partial Aggregate - -> Parallel Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Parallel Hash - -> Parallel Seq Scan on bigger_than_it_looks s -(9 rows) - -select count(*) from simple r join bigger_than_it_looks s using (id); - count -------- - 20000 -(1 row) - -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join bigger_than_it_looks s using (id); -$$); - initially_multibatch | increased_batches -----------------------+------------------- - f | t -(1 row) - -rollback to settings; --- The "ugly" case: increasing the number of batches during execution --- doesn't help, so stop trying to fit in work_mem and hope for the --- best; in this case we plan for 1 batch, increases just once and --- then stop increasing because that didn't help at all, so we blow --- right through the work_mem budget and hope for the best... --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); - QUERY PLAN --------------------------------------------------- - Aggregate - -> Hash Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on extremely_skewed s -(6 rows) - -select count(*) from simple r join extremely_skewed s using (id); - count -------- - 20000 -(1 row) - -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); - original | final -----------+------- - 1 | 2 -(1 row) - -rollback to settings; --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); - QUERY PLAN --------------------------------------------------------- - Aggregate - -> Gather - Workers Planned: 2 - -> Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Hash - -> Seq Scan on extremely_skewed s -(8 rows) - -select count(*) from simple r join extremely_skewed s using (id); - count -------- - 20000 -(1 row) - -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); - original | final -----------+------- - 1 | 2 -(1 row) - -rollback to settings; --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 1; -set local work_mem = '128kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); - QUERY PLAN ------------------------------------------------------------------------ - Finalize Aggregate - -> Gather - Workers Planned: 1 - -> Partial Aggregate - -> Parallel Hash Join - Hash Cond: (r.id = s.id) - -> Parallel Seq Scan on simple r - -> Parallel Hash - -> Parallel Seq Scan on extremely_skewed s -(9 rows) - -select count(*) from simple r join extremely_skewed s using (id); - count -------- - 20000 -(1 row) - -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); - original | final -----------+------- - 1 | 4 -(1 row) - -rollback to settings; --- A couple of other hash join tests unrelated to work_mem management. --- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local parallel_leader_participation = off; -select * from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); - original | final -----------+------- - 1 | 1 -(1 row) - -rollback to settings; --- Exercise rescans. We'll turn off parallel_leader_participation so --- that we can check that instrumentation comes back correctly. -create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t; -alter table join_foo set (parallel_workers = 0); -create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t; -alter table join_bar set (parallel_workers = 2); --- multi-batch with rescan, parallel-oblivious -savepoint settings; -set enable_parallel_hash = off; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '64kB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Hash - -> Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; --- single-batch with rescan, parallel-oblivious -savepoint settings; -set enable_parallel_hash = off; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Hash - -> Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - f -(1 row) - -rollback to settings; --- multi-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '64kB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Parallel Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Parallel Hash - -> Parallel Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; --- single-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Parallel Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Parallel Hash - -> Parallel Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - f -(1 row) - -rollback to settings; --- A full outer join where every record is matched. --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r full outer join simple s using (id); - count -------- - 20000 -(1 row) - -rollback to settings; --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r full outer join simple s using (id); - count -------- - 20000 -(1 row) - -rollback to settings; --- An full outer join where every record is not matched. --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: ((0 - s.id) = r.id) - -> Seq Scan on simple s - -> Hash - -> Seq Scan on simple r -(6 rows) - -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - count -------- - 40000 -(1 row) - -rollback to settings; --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: ((0 - s.id) = r.id) - -> Seq Scan on simple s - -> Hash - -> Seq Scan on simple r -(6 rows) - -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - count -------- - 40000 -(1 row) - -rollback to settings; --- exercise special code paths for huge tuples (note use of non-strict --- expression and left join required to get the detoasted tuple into --- the hash table) --- parallel with parallel-aware hash join (hits ExecParallelHashLoadTuple and --- sts_puttuple oversized tuple cases because it's multi-batch) -savepoint settings; -set max_parallel_workers_per_gather = 2; -set enable_parallel_hash = on; -set work_mem = '128kB'; -explain (costs off) - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); - QUERY PLAN ----------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Hash Left Join - Hash Cond: (wide.id = wide_1.id) - -> Parallel Seq Scan on wide - -> Parallel Hash - -> Parallel Seq Scan on wide wide_1 -(9 rows) - -select length(max(s.t)) -from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); - length --------- - 320000 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; -rollback; diff --git a/src/test/regress/expected/join_hash.out b/src/test/regress/expected/join_hash.out new file mode 100644 index 00000000000..3a91c144a27 --- /dev/null +++ b/src/test/regress/expected/join_hash.out @@ -0,0 +1,1015 @@ +-- +-- exercises for the hash join code +-- +begin; +set local min_parallel_table_scan_size = 0; +set local parallel_setup_cost = 0; +set local enable_hashjoin = on; +-- Extract bucket and batch counts from an explain analyze plan. In +-- general we can't make assertions about how many batches (or +-- buckets) will be required because it can vary, but we can in some +-- special cases and we can check for growth. +create or replace function find_hash(node json) +returns json language plpgsql +as +$$ +declare + x json; + child json; +begin + if node->>'Node Type' = 'Hash' then + return node; + else + for child in select json_array_elements(node->'Plans') + loop + x := find_hash(child); + if x is not null then + return x; + end if; + end loop; + return null; + end if; +end; +$$; +create or replace function hash_join_batches(query text) +returns table (original int, final int) language plpgsql +as +$$ +declare + whole_plan json; + hash_node json; +begin + for whole_plan in + execute 'explain (analyze, format ''json'') ' || query + loop + hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); + original := hash_node->>'Original Hash Batches'; + final := hash_node->>'Hash Batches'; + return next; + end loop; +end; +$$; +-- Make a simple relation with well distributed keys and correctly +-- estimated size. +create table simple as + select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +alter table simple set (parallel_workers = 2); +analyze simple; +-- Make a relation whose size we will under-estimate. We want stats +-- to say 1000 rows, but actually there are 20,000 rows. +create table bigger_than_it_looks as + select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +alter table bigger_than_it_looks set (autovacuum_enabled = 'false'); +alter table bigger_than_it_looks set (parallel_workers = 2); +analyze bigger_than_it_looks; +update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks'; +-- Make a relation whose size we underestimate and that also has a +-- kind of skew that breaks our batching scheme. We want stats to say +-- 2 rows, but actually there are 20,000 rows with the same key. +create table extremely_skewed (id int, t text); +alter table extremely_skewed set (autovacuum_enabled = 'false'); +alter table extremely_skewed set (parallel_workers = 2); +analyze extremely_skewed; +insert into extremely_skewed + select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + from generate_series(1, 20000); +update pg_class + set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 + where relname = 'extremely_skewed'; +-- Make a relation with a couple of enormous tuples. +create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t; +alter table wide set (parallel_workers = 2); +-- The "optimal" case: the hash table fits in memory; we plan for 1 +-- batch, we stick to that number, and peak memory usage stays within +-- our work_mem budget +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '4MB'; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(6 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | f +(1 row) + +rollback to settings; +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(9 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | f +(1 row) + +rollback to settings; +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +------------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Parallel Hash + -> Parallel Seq Scan on simple s +(9 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | f +(1 row) + +rollback to settings; +-- The "good" case: batches required, but we plan the right number; we +-- plan for some number of batches, and we stick to that number, and +-- peak memory usage says within our work_mem budget +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(6 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + t | f +(1 row) + +rollback to settings; +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(9 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + t | f +(1 row) + +rollback to settings; +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '192kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join simple s using (id); + QUERY PLAN +------------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Parallel Hash + -> Parallel Seq Scan on simple s +(9 rows) + +select count(*) from simple r join simple s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + t | f +(1 row) + +rollback to settings; +-- The "bad" case: during execution we need to increase number of +-- batches; in this case we plan for 1 batch, and increase at least a +-- couple of times, and peak memory usage stays within our work_mem +-- budget +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); + QUERY PLAN +------------------------------------------------------ + Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on bigger_than_it_looks s +(6 rows) + +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | t +(1 row) + +rollback to settings; +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id); + QUERY PLAN +------------------------------------------------------------------ + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Hash + -> Seq Scan on bigger_than_it_looks s +(9 rows) + +select count(*) from simple r join bigger_than_it_looks s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | t +(1 row) + +rollback to settings; +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 1; +set local work_mem = '192kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id); + QUERY PLAN +--------------------------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 1 + -> Partial Aggregate + -> Parallel Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Parallel Hash + -> Parallel Seq Scan on bigger_than_it_looks s +(9 rows) + +select count(*) from simple r join bigger_than_it_looks s using (id); + count +------- + 20000 +(1 row) + +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); + initially_multibatch | increased_batches +----------------------+------------------- + f | t +(1 row) + +rollback to settings; +-- The "ugly" case: increasing the number of batches during execution +-- doesn't help, so stop trying to fit in work_mem and hope for the +-- best; in this case we plan for 1 batch, increases just once and +-- then stop increasing because that didn't help at all, so we blow +-- right through the work_mem budget and hope for the best... +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); + QUERY PLAN +-------------------------------------------------- + Aggregate + -> Hash Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on extremely_skewed s +(6 rows) + +select count(*) from simple r join extremely_skewed s using (id); + count +------- + 20000 +(1 row) + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + original | final +----------+------- + 1 | 2 +(1 row) + +rollback to settings; +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); + QUERY PLAN +-------------------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Hash + -> Seq Scan on extremely_skewed s +(8 rows) + +select count(*) from simple r join extremely_skewed s using (id); + count +------- + 20000 +(1 row) + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + original | final +----------+------- + 1 | 2 +(1 row) + +rollback to settings; +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 1; +set local work_mem = '128kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); + QUERY PLAN +----------------------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 1 + -> Partial Aggregate + -> Parallel Hash Join + Hash Cond: (r.id = s.id) + -> Parallel Seq Scan on simple r + -> Parallel Hash + -> Parallel Seq Scan on extremely_skewed s +(9 rows) + +select count(*) from simple r join extremely_skewed s using (id); + count +------- + 20000 +(1 row) + +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); + original | final +----------+------- + 1 | 4 +(1 row) + +rollback to settings; +-- A couple of other hash join tests unrelated to work_mem management. +-- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local parallel_leader_participation = off; +select * from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); + original | final +----------+------- + 1 | 1 +(1 row) + +rollback to settings; +-- Exercise rescans. We'll turn off parallel_leader_participation so +-- that we can check that instrumentation comes back correctly. +create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t; +alter table join_foo set (parallel_workers = 0); +create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t; +alter table join_bar set (parallel_workers = 2); +-- multi-batch with rescan, parallel-oblivious +savepoint settings; +set enable_parallel_hash = off; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '64kB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) + -> Seq Scan on join_foo + -> Gather + Workers Planned: 2 + -> Hash Join + Hash Cond: (b1.id = b2.id) + -> Parallel Seq Scan on join_bar b1 + -> Hash + -> Seq Scan on join_bar b2 +(11 rows) + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + count +------- + 3 +(1 row) + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + multibatch +------------ + t +(1 row) + +rollback to settings; +-- single-batch with rescan, parallel-oblivious +savepoint settings; +set enable_parallel_hash = off; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '4MB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) + -> Seq Scan on join_foo + -> Gather + Workers Planned: 2 + -> Hash Join + Hash Cond: (b1.id = b2.id) + -> Parallel Seq Scan on join_bar b1 + -> Hash + -> Seq Scan on join_bar b2 +(11 rows) + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + count +------- + 3 +(1 row) + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + multibatch +------------ + f +(1 row) + +rollback to settings; +-- multi-batch with rescan, parallel-aware +savepoint settings; +set enable_parallel_hash = on; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '64kB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) + -> Seq Scan on join_foo + -> Gather + Workers Planned: 2 + -> Parallel Hash Join + Hash Cond: (b1.id = b2.id) + -> Parallel Seq Scan on join_bar b1 + -> Parallel Hash + -> Parallel Seq Scan on join_bar b2 +(11 rows) + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + count +------- + 3 +(1 row) + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + multibatch +------------ + t +(1 row) + +rollback to settings; +-- single-batch with rescan, parallel-aware +savepoint settings; +set enable_parallel_hash = on; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '4MB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + -> Nested Loop Left Join + Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) + -> Seq Scan on join_foo + -> Gather + Workers Planned: 2 + -> Parallel Hash Join + Hash Cond: (b1.id = b2.id) + -> Parallel Seq Scan on join_bar b1 + -> Parallel Hash + -> Parallel Seq Scan on join_bar b2 +(11 rows) + +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; + count +------- + 3 +(1 row) + +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); + multibatch +------------ + f +(1 row) + +rollback to settings; +-- A full outer join where every record is matched. +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +explain (costs off) + select count(*) from simple r full outer join simple s using (id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Full Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(6 rows) + +select count(*) from simple r full outer join simple s using (id); + count +------- + 20000 +(1 row) + +rollback to settings; +-- parallelism not possible with parallel-oblivious outer hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +explain (costs off) + select count(*) from simple r full outer join simple s using (id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Full Join + Hash Cond: (r.id = s.id) + -> Seq Scan on simple r + -> Hash + -> Seq Scan on simple s +(6 rows) + +select count(*) from simple r full outer join simple s using (id); + count +------- + 20000 +(1 row) + +rollback to settings; +-- An full outer join where every record is not matched. +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Full Join + Hash Cond: ((0 - s.id) = r.id) + -> Seq Scan on simple s + -> Hash + -> Seq Scan on simple r +(6 rows) + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + count +------- + 40000 +(1 row) + +rollback to settings; +-- parallelism not possible with parallel-oblivious outer hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Full Join + Hash Cond: ((0 - s.id) = r.id) + -> Seq Scan on simple s + -> Hash + -> Seq Scan on simple r +(6 rows) + +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); + count +------- + 40000 +(1 row) + +rollback to settings; +-- exercise special code paths for huge tuples (note use of non-strict +-- expression and left join required to get the detoasted tuple into +-- the hash table) +-- parallel with parallel-aware hash join (hits ExecParallelHashLoadTuple and +-- sts_puttuple oversized tuple cases because it's multi-batch) +savepoint settings; +set max_parallel_workers_per_gather = 2; +set enable_parallel_hash = on; +set work_mem = '128kB'; +explain (costs off) + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); + QUERY PLAN +---------------------------------------------------------------- + Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Hash Left Join + Hash Cond: (wide.id = wide_1.id) + -> Parallel Seq Scan on wide + -> Parallel Hash + -> Parallel Seq Scan on wide wide_1 +(9 rows) + +select length(max(s.t)) +from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); + length +-------- + 320000 +(1 row) + +select final > 1 as multibatch + from hash_join_batches( +$$ + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); +$$); + multibatch +------------ + t +(1 row) + +rollback to settings; +rollback; +-- Verify that hash key expressions reference the correct +-- nodes. Hashjoin's hashkeys need to reference its outer plan, Hash's +-- need to reference Hash's outer plan (which is below HashJoin's +-- inner plan). It's not trivial to verify that the references are +-- correct (we don't display the hashkeys themselves), but if the +-- hashkeys contain subplan references, those will be displayed. Force +-- subplans to appear just about everywhere. +-- +-- Bug report: +-- https://www.postgresql.org/message-id/CAPpHfdvGVegF_TKKRiBrSmatJL2dR9uwFCuR%2BteQ_8tEXU8mxg%40mail.gmail.com +-- +BEGIN; +SET LOCAL enable_sort = OFF; -- avoid mergejoins +SET LOCAL from_collapse_limit = 1; -- allows easy changing of join order +CREATE TABLE hjtest_1 (a text, b int, id int, c bool); +CREATE TABLE hjtest_2 (a bool, id int, b text, c int); +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false); -- matches +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false); -- fails id join condition +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false); -- fails < 50 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2); -- matches +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7); -- fails id join condition +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90); -- fails < 55 +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1); -- fails hjtest_1.a <> hjtest_2.b; +EXPLAIN (COSTS OFF, VERBOSE) +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Hash Join + Output: hjtest_1.a, hjtest_2.a, (hjtest_1.tableoid)::regclass, (hjtest_2.tableoid)::regclass + Hash Cond: ((hjtest_1.id = (SubPlan 1)) AND ((SubPlan 2) = (SubPlan 3))) + Join Filter: (hjtest_1.a <> hjtest_2.b) + -> Seq Scan on public.hjtest_1 + Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b + Filter: ((SubPlan 4) < 50) + SubPlan 4 + -> Result + Output: (hjtest_1.b * 5) + -> Hash + Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b + -> Seq Scan on public.hjtest_2 + Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b + Filter: ((SubPlan 5) < 55) + SubPlan 5 + -> Result + Output: (hjtest_2.c * 5) + SubPlan 1 + -> Result + Output: 1 + One-Time Filter: (hjtest_2.id = 1) + SubPlan 3 + -> Result + Output: (hjtest_2.c * 5) + SubPlan 2 + -> Result + Output: (hjtest_1.b * 5) +(28 rows) + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + a1 | a2 | t1 | t2 +------+----+----------+---------- + text | t | hjtest_1 | hjtest_2 +(1 row) + +EXPLAIN (COSTS OFF, VERBOSE) +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Hash Join + Output: hjtest_1.a, hjtest_2.a, (hjtest_1.tableoid)::regclass, (hjtest_2.tableoid)::regclass + Hash Cond: (((SubPlan 1) = hjtest_1.id) AND ((SubPlan 3) = (SubPlan 2))) + Join Filter: (hjtest_1.a <> hjtest_2.b) + -> Seq Scan on public.hjtest_2 + Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b + Filter: ((SubPlan 5) < 55) + SubPlan 5 + -> Result + Output: (hjtest_2.c * 5) + -> Hash + Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b + -> Seq Scan on public.hjtest_1 + Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b + Filter: ((SubPlan 4) < 50) + SubPlan 4 + -> Result + Output: (hjtest_1.b * 5) + SubPlan 2 + -> Result + Output: (hjtest_1.b * 5) + SubPlan 1 + -> Result + Output: 1 + One-Time Filter: (hjtest_2.id = 1) + SubPlan 3 + -> Result + Output: (hjtest_2.c * 5) +(28 rows) + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + a1 | a2 | t1 | t2 +------+----+----------+---------- + text | t | hjtest_1 | hjtest_2 +(1 row) + +ROLLBACK; diff --git a/src/test/regress/expected/json.out b/src/test/regress/expected/json.out index 9998bf2085e..c4156cf2a66 100644 --- a/src/test/regress/expected/json.out +++ b/src/test/regress/expected/json.out @@ -384,13 +384,17 @@ SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)), (1 row) -- anyarray column -select to_json(histogram_bounds) histogram_bounds +analyze rows; +select attname, to_json(histogram_bounds) histogram_bounds from pg_stats -where attname = 'tmplname' and tablename = 'pg_pltemplate'; - histogram_bounds ---------------------------------------------------------------------------------------- - ["plperl","plperlu","plpgsql","plpython2u","plpython3u","plpythonu","pltcl","pltclu"] -(1 row) +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; + attname | histogram_bounds +---------+------------------------ + x | [1,2,3] + y | ["txt1","txt2","txt3"] +(2 rows) -- to_json, timestamps select to_json(timestamp '2014-05-28 12:22:35.614298'); @@ -1401,7 +1405,7 @@ SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": null}') q; (1 row) SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia". SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [1, "2", null, 4]}') q; ia @@ -1416,10 +1420,10 @@ SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1, 2], [3, 4]]}') q; (1 row) SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], 2]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia". SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": [[1], [2, 3]]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ia FROM json_populate_record(NULL::jsrec, '{"ia": "{1,2,3}"}') q; ia @@ -1434,7 +1438,7 @@ SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": null}') q; (1 row) SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia1". SELECT ia1 FROM json_populate_record(NULL::jsrec, '{"ia1": [1, "2", null, 4]}') q; ia1 @@ -1455,7 +1459,7 @@ SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": null}') q; (1 row) SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia1d". SELECT ia1d FROM json_populate_record(NULL::jsrec, '{"ia1d": [1, "2", null, 4]}') q; ERROR: value for domain js_int_array_1d violates check constraint "js_int_array_1d_check" @@ -1484,10 +1488,10 @@ SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[], []]}') q; (1 row) SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], [3]]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ia2 FROM json_populate_record(NULL::jsrec, '{"ia2": [[1, 2], 3, 4]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia2". SELECT ia2d FROM json_populate_record(NULL::jsrec, '{"ia2d": [[1, "2"], [null, 4]]}') q; ERROR: value for domain js_int_array_2d violates check constraint "js_int_array_2d_check" @@ -1528,7 +1532,7 @@ SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [ (1 row) SELECT ia3 FROM json_populate_record(NULL::jsrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": null}') q; ta @@ -1537,7 +1541,7 @@ SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": null}') q; (1 row) SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ta". SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [1, "2", null, 4]}') q; ta @@ -1546,7 +1550,7 @@ SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [1, "2", null, 4]}') q; (1 row) SELECT ta FROM json_populate_record(NULL::jsrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ta". SELECT c FROM json_populate_record(NULL::jsrec, '{"c": null}') q; c @@ -1575,7 +1579,7 @@ SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": null}') q; (1 row) SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ca". SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [1, "2", null, 4]}') q; ca @@ -1586,7 +1590,7 @@ SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [1, "2", null, 4]}') q; SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q; ERROR: value too long for type character(10) SELECT ca FROM json_populate_record(NULL::jsrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ca". SELECT js FROM json_populate_record(NULL::jsrec, '{"js": null}') q; js @@ -1679,7 +1683,7 @@ SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": null}') q; (1 row) SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "jsa". SELECT jsa FROM json_populate_record(NULL::jsrec, '{"jsa": [1, "2", null, 4]}') q; jsa @@ -1710,7 +1714,7 @@ SELECT rec FROM json_populate_record(NULL::jsrec, '{"rec": "(abc,42,01.02.2003)" (1 row) SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "reca". SELECT reca FROM json_populate_record(NULL::jsrec, '{"reca": [1, 2]}') q; ERROR: cannot call populate_composite on a scalar @@ -1744,13 +1748,21 @@ SELECT rec FROM json_populate_record( -- anonymous record type SELECT json_populate_record(null::record, '{"x": 0, "y": 1}'); -ERROR: record type has not been registered +ERROR: could not determine row type for result of json_populate_record +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. SELECT json_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); json_populate_record ---------------------- (0,1) (1 row) +SELECT * FROM + json_populate_record(null::record, '{"x": 776}') AS (x int, y int); + x | y +-----+--- + 776 | +(1 row) + -- composite domain SELECT json_populate_record(null::j_ordered_pair, '{"x": 0, "y": 1}'); json_populate_record @@ -1834,13 +1846,51 @@ select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,3 -- anonymous record type SELECT json_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); -ERROR: record type has not been registered +ERROR: could not determine row type for result of json_populate_recordset +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); json_populate_recordset ------------------------- (0,1) (1 row) +SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); + i | json_populate_recordset +---+------------------------- + 1 | (42,50) + 1 | (1,43) + 2 | (42,50) + 2 | (2,43) +(4 rows) + +SELECT * FROM + json_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + x | y +-----+--- + 776 | +(1 row) + +-- empty array is a corner case +SELECT json_populate_recordset(null::record, '[]'); +ERROR: could not determine row type for result of json_populate_recordset +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. +SELECT json_populate_recordset(row(1,2), '[]'); + json_populate_recordset +------------------------- +(0 rows) + +SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q; + a | b | c +---+---+--- +(0 rows) + +SELECT * FROM + json_populate_recordset(null::record, '[]') AS (x int, y int); + x | y +---+--- +(0 rows) + -- composite domain SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]'); json_populate_recordset @@ -2215,7 +2265,7 @@ select * from json_to_record('{"ia": null}') as x(ia _int4); (1 row) select * from json_to_record('{"ia": 123}') as x(ia _int4); -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia". select * from json_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4); ia @@ -2230,10 +2280,10 @@ select * from json_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4); (1 row) select * from json_to_record('{"ia": [[1], 2]}') as x(ia _int4); -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia". select * from json_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4); -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); ia2 @@ -2253,6 +2303,42 @@ select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); {{{1},{2},{3}}} (1 row) +select * from json_to_record('{"out": {"key": 1}}') as x(out json); + out +------------ + {"key": 1} +(1 row) + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json); + out +-------------- + [{"key": 1}] +(1 row) + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json); + out +---------------- + "{\"key\": 1}" +(1 row) + +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb); + out +------------ + {"key": 1} +(1 row) + +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + out +-------------- + [{"key": 1}] +(1 row) + +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + out +---------------- + "{\"key\": 1}" +(1 row) + -- json_strip_nulls select json_strip_nulls(null); json_strip_nulls @@ -2404,7 +2490,7 @@ select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": '123':5 '456':7 'aaa':1 'bbb':3 (1 row) --- ts_vector corner cases +-- to_tsvector corner cases select to_tsvector('""'::json); to_tsvector ------------- @@ -2456,7 +2542,7 @@ select json_to_tsvector('null'::json, '"all"'); select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '""'); ERROR: wrong flag in flag array: "" -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '{}'); ERROR: wrong flag type, only arrays and scalars are allowed select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '[]'); @@ -2467,10 +2553,10 @@ select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, 'null'); ERROR: flag array element is not a string -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["all", null]'); ERROR: flag array element is not a string -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". -- ts_headline for json select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::json, tsquery('bbb & ddd & hhh')); ts_headline diff --git a/src/test/regress/expected/jsonb.out b/src/test/regress/expected/jsonb.out index f705417b091..a2a19f81041 100644 --- a/src/test/regress/expected/jsonb.out +++ b/src/test/regress/expected/jsonb.out @@ -280,13 +280,20 @@ SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']); (1 row) -- anyarray column -select to_jsonb(histogram_bounds) histogram_bounds +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x; +analyze rows; +select attname, to_jsonb(histogram_bounds) histogram_bounds from pg_stats -where attname = 'tmplname' and tablename = 'pg_pltemplate'; - histogram_bounds ----------------------------------------------------------------------------------------------- - ["plperl", "plperlu", "plpgsql", "plpython2u", "plpython3u", "plpythonu", "pltcl", "pltclu"] -(1 row) +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; + attname | histogram_bounds +---------+-------------------------- + x | [1, 2, 3] + y | ["txt1", "txt2", "txt3"] +(2 rows) -- to_jsonb, timestamps select to_jsonb(timestamp '2014-05-28 12:22:35.614298'); @@ -354,9 +361,6 @@ select to_jsonb(timestamptz '-Infinity'); (1 row) --jsonb_agg -CREATE TEMP TABLE rows AS -SELECT x, 'txt' || x as y -FROM generate_series(1,3) AS x; SELECT jsonb_agg(q) FROM ( SELECT $$a$$ || x AS b, y AS c, ARRAY[ROW(x.*,ARRAY[1,2,3]), @@ -2090,7 +2094,7 @@ SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": null}') q; (1 row) SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia". SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [1, "2", null, 4]}') q; ia @@ -2105,10 +2109,10 @@ SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1, 2], [3, 4]]}') q (1 row) SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], 2]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia". SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": [[1], [2, 3]]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ia FROM jsonb_populate_record(NULL::jsbrec, '{"ia": "{1,2,3}"}') q; ia @@ -2123,7 +2127,7 @@ SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": null}') q; (1 row) SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia1". SELECT ia1 FROM jsonb_populate_record(NULL::jsbrec, '{"ia1": [1, "2", null, 4]}') q; ia1 @@ -2144,7 +2148,7 @@ SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": null}') q; (1 row) SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia1d". SELECT ia1d FROM jsonb_populate_record(NULL::jsbrec, '{"ia1d": [1, "2", null, 4]}') q; ERROR: value for domain jsb_int_array_1d violates check constraint "jsb_int_array_1d_check" @@ -2173,10 +2177,10 @@ SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[], []]}') q; (1 row) SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], [3]]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ia2 FROM jsonb_populate_record(NULL::jsbrec, '{"ia2": [[1, 2], 3, 4]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia2". SELECT ia2d FROM jsonb_populate_record(NULL::jsbrec, '{"ia2d": [[1, "2"], [null, 4]]}') q; ERROR: value for domain jsb_int_array_2d violates check constraint "jsb_int_array_2d_check" @@ -2217,7 +2221,7 @@ SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], (1 row) SELECT ia3 FROM jsonb_populate_record(NULL::jsbrec, '{"ia3": [ [[1, 2], [3, 4]], [[5, 6], [7, 8], [9, 10]] ]}') q; -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": null}') q; ta @@ -2226,7 +2230,7 @@ SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": null}') q; (1 row) SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ta". SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [1, "2", null, 4]}') q; ta @@ -2235,7 +2239,7 @@ SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [1, "2", null, 4]}') (1 row) SELECT ta FROM jsonb_populate_record(NULL::jsbrec, '{"ta": [[1, 2, 3], {"k": "v"}]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ta". SELECT c FROM jsonb_populate_record(NULL::jsbrec, '{"c": null}') q; c @@ -2264,7 +2268,7 @@ SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": null}') q; (1 row) SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ca". SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [1, "2", null, 4]}') q; ca @@ -2275,7 +2279,7 @@ SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [1, "2", null, 4]}') SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": ["aaaaaaaaaaaaaaaa"]}') q; ERROR: value too long for type character(10) SELECT ca FROM jsonb_populate_record(NULL::jsbrec, '{"ca": [[1, 2, 3], {"k": "v"}]}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ca". SELECT js FROM jsonb_populate_record(NULL::jsbrec, '{"js": null}') q; js @@ -2368,7 +2372,7 @@ SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": null}') q; (1 row) SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "jsa". SELECT jsa FROM jsonb_populate_record(NULL::jsbrec, '{"jsa": [1, "2", null, 4]}') q; jsa @@ -2399,7 +2403,7 @@ SELECT rec FROM jsonb_populate_record(NULL::jsbrec, '{"rec": "(abc,42,01.02.2003 (1 row) SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": 123}') q; -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "reca". SELECT reca FROM jsonb_populate_record(NULL::jsbrec, '{"reca": [1, 2]}') q; ERROR: cannot call populate_composite on a scalar @@ -2433,13 +2437,21 @@ SELECT rec FROM jsonb_populate_record( -- anonymous record type SELECT jsonb_populate_record(null::record, '{"x": 0, "y": 1}'); -ERROR: record type has not been registered +ERROR: could not determine row type for result of jsonb_populate_record +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. SELECT jsonb_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); jsonb_populate_record ----------------------- (0,1) (1 row) +SELECT * FROM + jsonb_populate_record(null::record, '{"x": 776}') AS (x int, y int); + x | y +-----+--- + 776 | +(1 row) + -- composite domain SELECT jsonb_populate_record(null::jb_ordered_pair, '{"x": 0, "y": 1}'); jsonb_populate_record @@ -2516,13 +2528,51 @@ SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200 -- anonymous record type SELECT jsonb_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); -ERROR: record type has not been registered +ERROR: could not determine row type for result of jsonb_populate_recordset +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); jsonb_populate_recordset -------------------------- (0,1) (1 row) +SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); + i | jsonb_populate_recordset +---+-------------------------- + 1 | (42,50) + 1 | (1,43) + 2 | (42,50) + 2 | (2,43) +(4 rows) + +SELECT * FROM + jsonb_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + x | y +-----+--- + 776 | +(1 row) + +-- empty array is a corner case +SELECT jsonb_populate_recordset(null::record, '[]'); +ERROR: could not determine row type for result of jsonb_populate_recordset +HINT: Provide a non-null record argument, or call the function in the FROM clause using a column definition list. +SELECT jsonb_populate_recordset(row(1,2), '[]'); + jsonb_populate_recordset +-------------------------- +(0 rows) + +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q; + a | b | c +---+---+--- +(0 rows) + +SELECT * FROM + jsonb_populate_recordset(null::record, '[]') AS (x int, y int); + x | y +---+--- +(0 rows) + -- composite domain SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]'); jsonb_populate_recordset @@ -2591,7 +2641,7 @@ select * from jsonb_to_record('{"ia": null}') as x(ia _int4); (1 row) select * from jsonb_to_record('{"ia": 123}') as x(ia _int4); -ERROR: expected json array +ERROR: expected JSON array HINT: See the value of key "ia". select * from jsonb_to_record('{"ia": [1, "2", null, 4]}') as x(ia _int4); ia @@ -2606,10 +2656,10 @@ select * from jsonb_to_record('{"ia": [[1, 2], [3, 4]]}') as x(ia _int4); (1 row) select * from jsonb_to_record('{"ia": [[1], 2]}') as x(ia _int4); -ERROR: expected json array +ERROR: expected JSON array HINT: See the array element [1] of key "ia". select * from jsonb_to_record('{"ia": [[1], [2, 3]]}') as x(ia _int4); -ERROR: malformed json array +ERROR: malformed JSON array DETAIL: Multidimensional arrays must have sub-arrays with matching dimensions. select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); ia2 @@ -2629,6 +2679,42 @@ select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); {{{1},{2},{3}}} (1 row) +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json); + out +------------ + {"key": 1} +(1 row) + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json); + out +-------------- + [{"key": 1}] +(1 row) + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json); + out +---------------- + "{\"key\": 1}" +(1 row) + +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb); + out +------------ + {"key": 1} +(1 row) + +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb); + out +-------------- + [{"key": 1}] +(1 row) + +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + out +---------------- + "{\"key\": 1}" +(1 row) + -- test type info caching in jsonb_populate_record() CREATE TEMP TABLE jsbpoptest (js jsonb); INSERT INTO jsbpoptest @@ -2708,6 +2794,114 @@ SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; 42 (1 row) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + count +------- + 1012 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; + count +------- + 194 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; + count +------- + 0 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; + count +------- + 337 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; + count +------- + 42 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + count +------- + 1012 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + count +------- + 194 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + count +------- + 0 +(1 row) + CREATE INDEX jidx ON testjsonb USING gin (j); SET enable_seqscan = off; SELECT count(*) FROM testjsonb WHERE j @> '{"wait":null}'; @@ -2783,6 +2977,196 @@ SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; 42 (1 row) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + QUERY PLAN +----------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on testjsonb + Recheck Cond: (j @@ '($."wait" == null)'::jsonpath) + -> Bitmap Index Scan on jidx + Index Cond: (j @@ '($."wait" == null)'::jsonpath) +(5 rows) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + count +------- + 1012 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; + count +------- + 194 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; + count +------- + 0 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; + count +------- + 337 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; + count +------- + 42 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on testjsonb + Recheck Cond: (j @? '$."wait"?(@ == null)'::jsonpath) + -> Bitmap Index Scan on jidx + Index Cond: (j @? '$."wait"?(@ == null)'::jsonpath) +(5 rows) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + count +------- + 1012 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + count +------- + 194 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + count +------- + 0 +(1 row) + -- array exists - array elements should behave as keys (for GIN index scans too) CREATE INDEX jidx_array ON testjsonb USING gin((j->'array')); SELECT count(*) from testjsonb WHERE j->'array' ? 'bar'; @@ -2933,6 +3317,161 @@ SELECT count(*) FROM testjsonb WHERE j @> '{}'; 1012 (1 row) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + count +------- + 1012 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + QUERY PLAN +------------------------------------------------------------------- + Aggregate + -> Bitmap Heap Scan on testjsonb + Recheck Cond: (j @? '$."wait"?(@ == null)'::jsonpath) + -> Bitmap Index Scan on jidx + Index Cond: (j @? '$."wait"?(@ == null)'::jsonpath) +(5 rows) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; + count +------- + 1 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; + count +------- + 15 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; + count +------- + 2 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; + count +------- + 3 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$'; + count +------- + 1012 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; + count +------- + 194 +(1 row) + +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + count +------- + 0 +(1 row) + RESET enable_seqscan; DROP INDEX jidx; -- nested tests @@ -4202,7 +4741,7 @@ select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d" '123':5 '456':7 'aaa':1 'bbb':3 (1 row) --- ts_vector corner cases +-- to_tsvector corner cases select to_tsvector('""'::jsonb); to_tsvector ------------- @@ -4254,7 +4793,7 @@ select jsonb_to_tsvector('null'::jsonb, '"all"'); select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '""'); ERROR: wrong flag in flag array: "" -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '{}'); ERROR: wrong flag type, only arrays and scalars are allowed select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '[]'); @@ -4265,10 +4804,10 @@ select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d" select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, 'null'); ERROR: flag array element is not a string -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["all", null]'); ERROR: flag array element is not a string -HINT: Possible values are: "string", "numeric", "boolean", "key" and "all" +HINT: Possible values are: "string", "numeric", "boolean", "key", and "all". -- ts_headline for jsonb select ts_headline('{"a": "aaa bbb", "b": {"c": "ccc ddd fff", "c1": "ccc1 ddd1"}, "d": ["ggg hhh", "iii jjj"]}'::jsonb, tsquery('bbb & ddd & hhh')); ts_headline @@ -4321,7 +4860,7 @@ select 'true'::jsonb::bool; (1 row) select '[]'::jsonb::bool; -ERROR: jsonb value must be boolean +ERROR: cannot cast jsonb array to type boolean select '1.0'::jsonb::float; float8 -------- @@ -4329,7 +4868,7 @@ select '1.0'::jsonb::float; (1 row) select '[1.0]'::jsonb::float; -ERROR: jsonb value must be numeric +ERROR: cannot cast jsonb array to type double precision select '12345'::jsonb::int4; int4 ------- @@ -4337,7 +4876,7 @@ select '12345'::jsonb::int4; (1 row) select '"hello"'::jsonb::int4; -ERROR: jsonb value must be numeric +ERROR: cannot cast jsonb string to type integer select '12345'::jsonb::numeric; numeric --------- @@ -4345,7 +4884,7 @@ select '12345'::jsonb::numeric; (1 row) select '{}'::jsonb::numeric; -ERROR: jsonb value must be numeric +ERROR: cannot cast jsonb object to type numeric select '12345.05'::jsonb::numeric; numeric ---------- @@ -4353,9 +4892,9 @@ select '12345.05'::jsonb::numeric; (1 row) select '12345.05'::jsonb::float4; - float4 --------- - 12345 + float4 +---------- + 12345.05 (1 row) select '12345.05'::jsonb::float8; diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out new file mode 100644 index 00000000000..063f1c27711 --- /dev/null +++ b/src/test/regress/expected/jsonb_jsonpath.out @@ -0,0 +1,2519 @@ +select jsonb '{"a": 12}' @? '$'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": 12}' @? '1'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": 12}' @? '$.a.b'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": 12}' @? '$.b'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": 12}' @? '$.a + 2'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": 12}' @? '$.b + 2'; + ?column? +---------- + +(1 row) + +select jsonb '{"a": {"a": 12}}' @? '$.a.a'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"a": 12}}' @? '$.*.a'; + ?column? +---------- + t +(1 row) + +select jsonb '{"b": {"a": 12}}' @? '$.*.a'; + ?column? +---------- + t +(1 row) + +select jsonb '{"b": {"a": 12}}' @? '$.*.b'; + ?column? +---------- + f +(1 row) + +select jsonb '{"b": {"a": 12}}' @? 'strict $.*.b'; + ?column? +---------- + +(1 row) + +select jsonb '{}' @? '$.*'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": 1}' @? '$.*'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{1}'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{2}'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{3}'; + ?column? +---------- + f +(1 row) + +select jsonb '[]' @? '$[*]'; + ?column? +---------- + f +(1 row) + +select jsonb '[1]' @? '$[*]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1]' @? '$[1]'; + ?column? +---------- + f +(1 row) + +select jsonb '[1]' @? 'strict $[1]'; + ?column? +---------- + +(1 row) + +select jsonb_path_query('[1]', 'strict $[1]'); +ERROR: jsonpath array subscript is out of bounds +select jsonb_path_query('[1]', 'strict $[1]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb '[1]' @? 'lax $[10000000000000000]'; + ?column? +---------- + +(1 row) + +select jsonb '[1]' @? 'strict $[10000000000000000]'; + ?column? +---------- + +(1 row) + +select jsonb_path_query('[1]', 'lax $[10000000000000000]'); +ERROR: jsonpath array subscript is out of integer range +select jsonb_path_query('[1]', 'strict $[10000000000000000]'); +ERROR: jsonpath array subscript is out of integer range +select jsonb '[1]' @? '$[0]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1]' @? '$[0.3]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1]' @? '$[0.5]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1]' @? '$[0.9]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1]' @? '$[1.2]'; + ?column? +---------- + f +(1 row) + +select jsonb '[1]' @? 'strict $[1.2]'; + ?column? +---------- + +(1 row) + +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] > @.b[*])'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] >= @.b[*])'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? '$ ? (@.a[*] >= @.b[*])'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? 'strict $ ? (@.a[*] >= @.b[*])'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": [1,2,3], "b": [3,4,null]}' @? '$ ? (@.a[*] >= @.b[*])'; + ?column? +---------- + t +(1 row) + +select jsonb '1' @? '$ ? ((@ == "1") is unknown)'; + ?column? +---------- + t +(1 row) + +select jsonb '1' @? '$ ? ((@ == 1) is unknown)'; + ?column? +---------- + f +(1 row) + +select jsonb '[{"a": 1}, {"a": 2}]' @? '$[0 to 1] ? (@.a > 1)'; + ?column? +---------- + t +(1 row) + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => false); + jsonb_path_exists +------------------- + t +(1 row) + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true); + jsonb_path_exists +------------------- + t +(1 row) + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false); +ERROR: jsonpath member accessor can only be applied to an object +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true); + jsonb_path_exists +------------------- + +(1 row) + +select jsonb_path_query('1', 'lax $.a'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1', 'strict $.a'); +ERROR: jsonpath member accessor can only be applied to an object +select jsonb_path_query('1', 'strict $.*'); +ERROR: jsonpath wildcard member accessor can only be applied to an object +select jsonb_path_query('1', 'strict $.a', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1', 'strict $.*', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'lax $.a'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $.a'); +ERROR: jsonpath member accessor can only be applied to an object +select jsonb_path_query('[]', 'strict $.a', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{}', 'lax $.a'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{}', 'strict $.a'); +ERROR: JSON object does not contain key "a" +select jsonb_path_query('{}', 'strict $.a', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1', 'strict $[1]'); +ERROR: jsonpath array accessor can only be applied to an array +select jsonb_path_query('1', 'strict $[*]'); +ERROR: jsonpath wildcard array accessor can only be applied to an array +select jsonb_path_query('[]', 'strict $[1]'); +ERROR: jsonpath array subscript is out of bounds +select jsonb_path_query('[]', 'strict $["a"]'); +ERROR: jsonpath array subscript is not a single numeric value +select jsonb_path_query('1', 'strict $[1]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1', 'strict $[*]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $[1]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $["a"]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.a'); + jsonb_path_query +------------------ + 12 +(1 row) + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.b'); + jsonb_path_query +------------------ + {"a": 13} +(1 row) + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.*'); + jsonb_path_query +------------------ + 12 + {"a": 13} +(2 rows) + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', 'lax $.*.a'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].a'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].*'); + jsonb_path_query +------------------ + 13 + 14 +(2 rows) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0].a'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[1].a'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[2].a'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0,1].a'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10].a'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10 / 0].a'); +ERROR: division by zero +select jsonb_path_query('[12, {"a": 13}, {"b": 14}, "ccc", true]', '$[2.5 - 1 to $.size() - 2]'); + jsonb_path_query +------------------ + {"a": 13} + {"b": 14} + "ccc" +(3 rows) + +select jsonb_path_query('1', 'lax $[0]'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('1', 'lax $[*]'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('[1]', 'lax $[0]'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('[1]', 'lax $[*]'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('[1,2,3]', 'lax $[*]'); + jsonb_path_query +------------------ + 1 + 2 + 3 +(3 rows) + +select jsonb_path_query('[1,2,3]', 'strict $[*].a'); +ERROR: jsonpath member accessor can only be applied to an object +select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', '$[last]'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', '$[last ? (exists(last))]'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $[last]'); +ERROR: jsonpath array subscript is out of bounds +select jsonb_path_query('[]', 'strict $[last]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[1]', '$[last]'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('[1,2,3]', '$[last]'); + jsonb_path_query +------------------ + 3 +(1 row) + +select jsonb_path_query('[1,2,3]', '$[last - 1]'); + jsonb_path_query +------------------ + 2 +(1 row) + +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]'); + jsonb_path_query +------------------ + 3 +(1 row) + +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]'); +ERROR: jsonpath array subscript is not a single numeric value +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select * from jsonb_path_query('{"a": 10}', '$'); + jsonb_path_query +------------------ + {"a": 10} +(1 row) + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); +ERROR: could not find jsonpath variable "value" +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); +ERROR: "vars" argument is not an object +DETAIL: Jsonpath parameters should be encoded as key-value pairs of "vars" object. +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]'); +ERROR: "vars" argument is not an object +DETAIL: Jsonpath parameters should be encoded as key-value pairs of "vars" object. +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}'); + jsonb_path_query +------------------ + {"a": 10} +(1 row) + +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 8}'); + jsonb_path_query +------------------ +(0 rows) + +select * from jsonb_path_query('{"a": 10}', '$.a ? (@ < $value)', '{"value" : 13}'); + jsonb_path_query +------------------ + 10 +(1 row) + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{"value" : 13}'); + jsonb_path_query +------------------ + 10 + 11 + 12 +(3 rows) + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{"x": {"value" : 13}}'); + jsonb_path_query +------------------ + 10 + 11 +(2 rows) + +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{"value" : 15}'); + jsonb_path_query +------------------ + 10 + 11 + 12 +(3 rows) + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == "1")'); + jsonb_path_query +------------------ + "1" +(1 row) + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : "1"}'); + jsonb_path_query +------------------ + "1" +(1 row) + +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : null}'); + jsonb_path_query +------------------ + null +(1 row) + +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ != null)'); + jsonb_path_query +------------------ + 1 + "2" +(2 rows) + +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ == null)'); + jsonb_path_query +------------------ + null +(1 row) + +select * from jsonb_path_query('{}', '$ ? (@ == @)'); + jsonb_path_query +------------------ +(0 rows) + +select * from jsonb_path_query('[]', 'strict $ ? (@ == @)'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**'); + jsonb_path_query +------------------ + {"a": {"b": 1}} + {"b": 1} + 1 +(3 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}'); + jsonb_path_query +------------------ + {"a": {"b": 1}} +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}'); + jsonb_path_query +------------------ + {"a": {"b": 1}} + {"b": 1} + 1 +(3 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}'); + jsonb_path_query +------------------ + {"b": 1} +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}'); + jsonb_path_query +------------------ + {"b": 1} + 1 +(2 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2}'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2 to last}'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{3 to last}'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{last}'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}.b ? (@ > 0)'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0}.b ? (@ > 0)'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1}.b ? (@ > 0)'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)'); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)'; + ?column? +---------- + f +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)'; + ?column? +---------- + t +(1 row) + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x))'); + jsonb_path_query +------------------ + {"x": 2} +(1 row) + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.y))'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))'); + jsonb_path_query +------------------ + {"x": 2} +(1 row) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x))'); + jsonb_path_query +------------------ + {"x": 2} +(1 row) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x + "3"))'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? ((exists (@.x + "3")) is unknown)'); + jsonb_path_query +------------------ + {"x": 2} + {"y": 3} +(2 rows) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? (exists (@.x))'); + jsonb_path_query +------------------ + {"x": 2} +(1 row) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? ((exists (@.x)) is unknown)'); + jsonb_path_query +------------------ + {"y": 3} +(1 row) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? (exists (@[*].x))'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? ((exists (@[*].x)) is unknown)'); + jsonb_path_query +---------------------- + [{"x": 2}, {"y": 3}] +(1 row) + +--test ternary logic +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true && $y == true) || + @ == false && !($x == true && $y == true) || + @ == null && ($x == true && $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x && y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + x | y | x && y +--------+--------+-------- + true | true | true + true | false | false + true | "null" | null + false | true | false + false | false | false + false | "null" | false + "null" | true | null + "null" | false | false + "null" | "null" | null +(9 rows) + +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true || $y == true) || + @ == false && !($x == true || $y == true) || + @ == null && ($x == true || $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x || y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + x | y | x || y +--------+--------+-------- + true | true | true + true | false | true + true | "null" | true + false | true | true + false | false | false + false | "null" | null + "null" | true | true + "null" | false | null + "null" | "null" | null +(9 rows) + +select jsonb '{"a": 1, "b":1}' @? '$ ? (@.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$ ? (@.a == @.b)'; + ?column? +---------- + f +(1 row) + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? (@.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? ($.c.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.* ? (@.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": 1, "b":1}' @? '$.** ? (@.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.** ? (@.a == @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == 1 + 1)'); + jsonb_path_query +------------------ + {"a": 2, "b": 1} +(1 row) + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (1 + 1))'); + jsonb_path_query +------------------ + {"a": 2, "b": 1} +(1 row) + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == @.b + 1)'); + jsonb_path_query +------------------ + {"a": 2, "b": 1} +(1 row) + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (@.b + 1))'); + jsonb_path_query +------------------ + {"a": 2, "b": 1} +(1 row) + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - 1)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -1)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -@.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 2, "b":1}}' @? '$.** ? (@.a == 1 - - @.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - +@.b)'; + ?column? +---------- + t +(1 row) + +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +2)'; + ?column? +---------- + t +(1 row) + +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +3)'; + ?column? +---------- + f +(1 row) + +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -2)'; + ?column? +---------- + t +(1 row) + +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -3)'; + ?column? +---------- + f +(1 row) + +select jsonb '1' @? '$ ? ($ > 0)'; + ?column? +---------- + t +(1 row) + +-- arithmetic errors +select jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)'); + jsonb_path_query +------------------ + 1 + 2 + 3 +(3 rows) + +select jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)'); + jsonb_path_query +------------------ + 0 +(1 row) + +select jsonb_path_query('0', '1 / $'); +ERROR: division by zero +select jsonb_path_query('0', '1 / $ + 2'); +ERROR: division by zero +select jsonb_path_query('0', '-(3 + 1 % $)'); +ERROR: division by zero +select jsonb_path_query('1', '$ + "2"'); +ERROR: right operand of jsonpath operator + is not a single numeric value +select jsonb_path_query('[1, 2]', '3 * $'); +ERROR: right operand of jsonpath operator * is not a single numeric value +select jsonb_path_query('"a"', '-$'); +ERROR: operand of unary jsonpath operator - is not a numeric value +select jsonb_path_query('[1,"2",3]', '+$'); +ERROR: operand of unary jsonpath operator + is not a numeric value +select jsonb_path_query('1', '$ + "2"', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[1, 2]', '3 * $', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('"a"', '-$', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[1,"2",3]', '+$', silent => true); + jsonb_path_query +------------------ + 1 +(1 row) + +select jsonb '["1",2,0,3]' @? '-$[*]'; + ?column? +---------- + t +(1 row) + +select jsonb '[1,"2",0,3]' @? '-$[*]'; + ?column? +---------- + t +(1 row) + +select jsonb '["1",2,0,3]' @? 'strict -$[*]'; + ?column? +---------- + +(1 row) + +select jsonb '[1,"2",0,3]' @? 'strict -$[*]'; + ?column? +---------- + +(1 row) + +-- unwrapping of operator arguments in lax mode +select jsonb_path_query('{"a": [2]}', 'lax $.a * 3'); + jsonb_path_query +------------------ + 6 +(1 row) + +select jsonb_path_query('{"a": [2]}', 'lax $.a + 3'); + jsonb_path_query +------------------ + 5 +(1 row) + +select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a'); + jsonb_path_query +------------------ + -2 + -3 + -4 +(3 rows) + +-- should fail +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3'); +ERROR: left operand of jsonpath operator * is not a single numeric value +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true); + jsonb_path_query +------------------ +(0 rows) + +-- extension: boolean expressions +select jsonb_path_query('2', '$ > 1'); + jsonb_path_query +------------------ + true +(1 row) + +select jsonb_path_query('2', '$ <= 1'); + jsonb_path_query +------------------ + false +(1 row) + +select jsonb_path_query('2', '$ == "2"'); + jsonb_path_query +------------------ + null +(1 row) + +select jsonb '2' @? '$ == "2"'; + ?column? +---------- + t +(1 row) + +select jsonb '2' @@ '$ > 1'; + ?column? +---------- + t +(1 row) + +select jsonb '2' @@ '$ <= 1'; + ?column? +---------- + f +(1 row) + +select jsonb '2' @@ '$ == "2"'; + ?column? +---------- + +(1 row) + +select jsonb '2' @@ '1'; + ?column? +---------- + +(1 row) + +select jsonb '{}' @@ '$'; + ?column? +---------- + +(1 row) + +select jsonb '[]' @@ '$'; + ?column? +---------- + +(1 row) + +select jsonb '[1,2,3]' @@ '$[*]'; + ?column? +---------- + +(1 row) + +select jsonb '[]' @@ '$[*]'; + ?column? +---------- + +(1 row) + +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}'); + jsonb_path_match +------------------ + f +(1 row) + +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}'); + jsonb_path_match +------------------ + t +(1 row) + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => false); + jsonb_path_match +------------------ + t +(1 row) + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => true); + jsonb_path_match +------------------ + t +(1 row) + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => false); + jsonb_path_match +------------------ + +(1 row) + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => true); + jsonb_path_match +------------------ + +(1 row) + +select jsonb_path_query('[null,1,true,"a",[],{}]', '$.type()'); + jsonb_path_query +------------------ + "array" +(1 row) + +select jsonb_path_query('[null,1,true,"a",[],{}]', 'lax $.type()'); + jsonb_path_query +------------------ + "array" +(1 row) + +select jsonb_path_query('[null,1,true,"a",[],{}]', '$[*].type()'); + jsonb_path_query +------------------ + "null" + "number" + "boolean" + "string" + "array" + "object" +(6 rows) + +select jsonb_path_query('null', 'null.type()'); + jsonb_path_query +------------------ + "null" +(1 row) + +select jsonb_path_query('null', 'true.type()'); + jsonb_path_query +------------------ + "boolean" +(1 row) + +select jsonb_path_query('null', '(123).type()'); + jsonb_path_query +------------------ + "number" +(1 row) + +select jsonb_path_query('null', '"123".type()'); + jsonb_path_query +------------------ + "string" +(1 row) + +select jsonb_path_query('{"a": 2}', '($.a - 5).abs() + 10'); + jsonb_path_query +------------------ + 13 +(1 row) + +select jsonb_path_query('{"a": 2.5}', '-($.a * $.a).floor() % 4.3'); + jsonb_path_query +------------------ + -1.7 +(1 row) + +select jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)'); + jsonb_path_query +------------------ + true +(1 row) + +select jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()'); + jsonb_path_query +------------------ + "boolean" +(1 row) + +select jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()'); + jsonb_path_query +------------------ + "boolean" +(1 row) + +select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()'); + jsonb_path_query +------------------ + "null" +(1 row) + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()'); +ERROR: jsonpath item method .size() can only be applied to an array +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'lax $[*].size()'); + jsonb_path_query +------------------ + 1 + 1 + 1 + 1 + 0 + 1 + 3 + 1 + 1 +(9 rows) + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()'); + jsonb_path_query +------------------ + 0 + 1 + 2 + 3.4 + 5.6 +(5 rows) + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()'); + jsonb_path_query +------------------ + 0 + 1 + -2 + -4 + 5 +(5 rows) + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()'); + jsonb_path_query +------------------ + 0 + 1 + -2 + -3 + 6 +(5 rows) + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()'); + jsonb_path_query +------------------ + 0 + 1 + 2 + 3 + 6 +(5 rows) + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()'); + jsonb_path_query +------------------ + "number" + "number" + "number" + "number" + "number" +(5 rows) + +select jsonb_path_query('[{},1]', '$[*].keyvalue()'); +ERROR: jsonpath item method .keyvalue() can only be applied to an object +select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{}', '$.keyvalue()'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{"a": 1, "b": [1, 2], "c": {"a": "bbb"}}', '$.keyvalue()'); + jsonb_path_query +---------------------------------------------- + {"id": 0, "key": "a", "value": 1} + {"id": 0, "key": "b", "value": [1, 2]} + {"id": 0, "key": "c", "value": {"a": "bbb"}} +(3 rows) + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].keyvalue()'); + jsonb_path_query +----------------------------------------------- + {"id": 12, "key": "a", "value": 1} + {"id": 12, "key": "b", "value": [1, 2]} + {"id": 72, "key": "c", "value": {"a": "bbb"}} +(3 rows) + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()'); +ERROR: jsonpath item method .keyvalue() can only be applied to an object +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()'); + jsonb_path_query +----------------------------------------------- + {"id": 12, "key": "a", "value": 1} + {"id": 12, "key": "b", "value": [1, 2]} + {"id": 72, "key": "c", "value": {"a": "bbb"}} +(3 rows) + +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a'); +ERROR: jsonpath item method .keyvalue() can only be applied to an object +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()'; + ?column? +---------- + t +(1 row) + +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key'; + ?column? +---------- + t +(1 row) + +select jsonb_path_query('null', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a string or numeric value +select jsonb_path_query('true', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a string or numeric value +select jsonb_path_query('null', '$.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('true', '$.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', '$.double()'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $.double()'); +ERROR: jsonpath item method .double() can only be applied to a string or numeric value +select jsonb_path_query('{}', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a string or numeric value +select jsonb_path_query('[]', 'strict $.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{}', '$.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('1.23', '$.double()'); + jsonb_path_query +------------------ + 1.23 +(1 row) + +select jsonb_path_query('"1.23"', '$.double()'); + jsonb_path_query +------------------ + 1.23 +(1 row) + +select jsonb_path_query('"1.23aaa"', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a numeric value +select jsonb_path_query('"nan"', '$.double()'); + jsonb_path_query +------------------ + "NaN" +(1 row) + +select jsonb_path_query('"NaN"', '$.double()'); + jsonb_path_query +------------------ + "NaN" +(1 row) + +select jsonb_path_query('"inf"', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a numeric value +select jsonb_path_query('"-inf"', '$.double()'); +ERROR: jsonpath item method .double() can only be applied to a numeric value +select jsonb_path_query('"inf"', '$.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('"-inf"', '$.double()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('{}', '$.abs()'); +ERROR: jsonpath item method .abs() can only be applied to a numeric value +select jsonb_path_query('true', '$.floor()'); +ERROR: jsonpath item method .floor() can only be applied to a numeric value +select jsonb_path_query('"1.2"', '$.ceiling()'); +ERROR: jsonpath item method .ceiling() can only be applied to a numeric value +select jsonb_path_query('{}', '$.abs()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('true', '$.floor()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('"1.2"', '$.ceiling()', silent => true); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('["", "a", "abc", "abcabc"]', '$[*] ? (@ starts with "abc")'); + jsonb_path_query +------------------ + "abc" + "abcabc" +(2 rows) + +select jsonb_path_query('["", "a", "abc", "abcabc"]', 'strict $ ? (@[*] starts with "abc")'); + jsonb_path_query +---------------------------- + ["", "a", "abc", "abcabc"] +(1 row) + +select jsonb_path_query('["", "a", "abd", "abdabc"]', 'strict $ ? (@[*] starts with "abc")'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? (@[*] starts with "abc")'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? ((@[*] starts with "abc") is unknown)'); + jsonb_path_query +---------------------------- + ["abc", "abcabc", null, 1] +(1 row) + +select jsonb_path_query('[[null, 1, "abc", "abcabc"]]', 'lax $ ? (@[*] starts with "abc")'); + jsonb_path_query +---------------------------- + [null, 1, "abc", "abcabc"] +(1 row) + +select jsonb_path_query('[[null, 1, "abd", "abdabc"]]', 'lax $ ? ((@[*] starts with "abc") is unknown)'); + jsonb_path_query +---------------------------- + [null, 1, "abd", "abdabc"] +(1 row) + +select jsonb_path_query('[null, 1, "abd", "abdabc"]', 'lax $[*] ? ((@ starts with "abc") is unknown)'); + jsonb_path_query +------------------ + null + 1 +(2 rows) + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c")'); + jsonb_path_query +------------------ + "abc" + "abdacb" +(2 rows) + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "i")'); + jsonb_path_query +------------------ + "abc" + "aBdC" + "abdacb" +(3 rows) + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")'); + jsonb_path_query +------------------ + "abc" + "abdacb" + "adc\nabc" +(3 rows) + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")'); + jsonb_path_query +------------------ + "abc" + "abdacb" + "ab\nadc" +(3 rows) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")'); + jsonb_path_query +------------------ + "a\\b" + "^a\\b$" +(2 rows) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")'); + jsonb_path_query +------------------ + "a\b" +(1 row) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")'); + jsonb_path_query +------------------ + "^a\\b$" +(1 row) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")'); + jsonb_path_query +------------------ + "^a\\b$" +(1 row) + +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")'); + jsonb_path_query +------------------ + "a\b" +(1 row) + +select jsonb_path_query('null', '$.datetime()'); +ERROR: jsonpath item method .datetime() can only be applied to a string +select jsonb_path_query('true', '$.datetime()'); +ERROR: jsonpath item method .datetime() can only be applied to a string +select jsonb_path_query('1', '$.datetime()'); +ERROR: jsonpath item method .datetime() can only be applied to a string +select jsonb_path_query('[]', '$.datetime()'); + jsonb_path_query +------------------ +(0 rows) + +select jsonb_path_query('[]', 'strict $.datetime()'); +ERROR: jsonpath item method .datetime() can only be applied to a string +select jsonb_path_query('{}', '$.datetime()'); +ERROR: jsonpath item method .datetime() can only be applied to a string +select jsonb_path_query('""', '$.datetime()'); +ERROR: datetime format is not unrecognized +HINT: use datetime template argument for explicit format specification +select jsonb_path_query('"12:34"', '$.datetime("aaa")'); +ERROR: invalid datetime format separator: "a" +select jsonb_path_query('"aaaa"', '$.datetime("HH24")'); +ERROR: invalid value "aa" for "HH24" +DETAIL: Value must be an integer. +select jsonb '"10-03-2017"' @? '$.datetime("dd-mm-yyyy")'; + ?column? +---------- + t +(1 row) + +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy")'); + jsonb_path_query +------------------ + "2017-03-10" +(1 row) + +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy").type()'); + jsonb_path_query +------------------ + "date" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy")'); +ERROR: trailing characters remain in input string after datetime format +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy").type()'); +ERROR: trailing characters remain in input string after datetime format +select jsonb_path_query('"10-03-2017 12:34"', ' $.datetime("dd-mm-yyyy HH24:MI").type()'); + jsonb_path_query +------------------------------- + "timestamp without time zone" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM").type()'); + jsonb_path_query +---------------------------- + "timestamp with time zone" +(1 row) + +select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()'); + jsonb_path_query +-------------------------- + "time without time zone" +(1 row) + +select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()'); + jsonb_path_query +----------------------- + "time with time zone" +(1 row) + +set time zone '+00'; +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); + jsonb_path_query +----------------------- + "2017-03-10T12:34:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +ERROR: input string is too short for datetime format +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00+05:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00-05:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00+05:20" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00-05:20" +(1 row) + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); + jsonb_path_query +------------------ + "12:34:00" +(1 row) + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); +ERROR: input string is too short for datetime format +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); + jsonb_path_query +------------------ + "12:34:00+05:00" +(1 row) + +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); + jsonb_path_query +------------------ + "12:34:00-05:00" +(1 row) + +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); + jsonb_path_query +------------------ + "12:34:00+05:20" +(1 row) + +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + jsonb_path_query +------------------ + "12:34:00-05:20" +(1 row) + +set time zone '+10'; +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); + jsonb_path_query +----------------------- + "2017-03-10T12:34:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +ERROR: input string is too short for datetime format +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00+05:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00-05:00" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00+05:20" +(1 row) + +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:00-05:20" +(1 row) + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); + jsonb_path_query +------------------ + "12:34:00" +(1 row) + +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); +ERROR: input string is too short for datetime format +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); + jsonb_path_query +------------------ + "12:34:00+05:00" +(1 row) + +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); + jsonb_path_query +------------------ + "12:34:00-05:00" +(1 row) + +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); + jsonb_path_query +------------------ + "12:34:00+05:20" +(1 row) + +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + jsonb_path_query +------------------ + "12:34:00-05:20" +(1 row) + +set time zone default; +select jsonb_path_query('"2017-03-10"', '$.datetime().type()'); + jsonb_path_query +------------------ + "date" +(1 row) + +select jsonb_path_query('"2017-03-10"', '$.datetime()'); + jsonb_path_query +------------------ + "2017-03-10" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime().type()'); + jsonb_path_query +------------------------------- + "timestamp without time zone" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime()'); + jsonb_path_query +----------------------- + "2017-03-10T12:34:56" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56 +3"', '$.datetime().type()'); + jsonb_path_query +---------------------------- + "timestamp with time zone" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56 +3"', '$.datetime()'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:56+03:00" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56 +3:10"', '$.datetime().type()'); + jsonb_path_query +---------------------------- + "timestamp with time zone" +(1 row) + +select jsonb_path_query('"2017-03-10 12:34:56 +3:10"', '$.datetime()'); + jsonb_path_query +----------------------------- + "2017-03-10T12:34:56+03:10" +(1 row) + +select jsonb_path_query('"12:34:56"', '$.datetime().type()'); + jsonb_path_query +-------------------------- + "time without time zone" +(1 row) + +select jsonb_path_query('"12:34:56"', '$.datetime()'); + jsonb_path_query +------------------ + "12:34:56" +(1 row) + +select jsonb_path_query('"12:34:56 +3"', '$.datetime().type()'); + jsonb_path_query +----------------------- + "time with time zone" +(1 row) + +select jsonb_path_query('"12:34:56 +3"', '$.datetime()'); + jsonb_path_query +------------------ + "12:34:56+03:00" +(1 row) + +select jsonb_path_query('"12:34:56 +3:10"', '$.datetime().type()'); + jsonb_path_query +----------------------- + "time with time zone" +(1 row) + +select jsonb_path_query('"12:34:56 +3:10"', '$.datetime()'); + jsonb_path_query +------------------ + "12:34:56+03:10" +(1 row) + +set time zone '+00'; +-- date comparison +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); +ERROR: cannot convert value from date to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); +ERROR: cannot convert value from date to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); +ERROR: cannot convert value from date to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10" + "2017-03-10T00:00:00" + "2017-03-10T03:00:00+03:00" +(3 rows) + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10" + "2017-03-11" + "2017-03-10T00:00:00" + "2017-03-10T12:34:56" + "2017-03-10T03:00:00+03:00" +(5 rows) + +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-09" + "2017-03-10T01:02:03+04:00" +(2 rows) + +-- time comparison +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); + jsonb_path_query_tz +--------------------- + "12:35:00" + "12:35:00+00:00" +(2 rows) + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); + jsonb_path_query_tz +--------------------- + "12:35:00" + "12:36:00" + "12:35:00+00:00" +(3 rows) + +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); + jsonb_path_query_tz +--------------------- + "12:34:00" + "12:35:00+01:00" + "13:35:00+01:00" +(3 rows) + +-- timetz comparison +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); +ERROR: cannot convert value from time to timetz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); + jsonb_path_query_tz +--------------------- + "12:35:00+01:00" +(1 row) + +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); + jsonb_path_query_tz +--------------------- + "12:35:00+01:00" + "12:36:00+01:00" + "12:35:00-02:00" + "11:35:00" + "12:35:00" +(5 rows) + +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); + jsonb_path_query_tz +--------------------- + "12:34:00+01:00" + "12:35:00+02:00" + "10:35:00" +(3 rows) + +-- timestamp comparison +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:35:00" + "2017-03-10T13:35:00+01:00" +(2 rows) + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:35:00" + "2017-03-10T12:36:00" + "2017-03-10T13:35:00+01:00" + "2017-03-10T12:35:00-01:00" + "2017-03-11" +(5 rows) + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:34:00" + "2017-03-10T12:35:00+01:00" + "2017-03-10" +(3 rows) + +-- timestamptz comparison +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +ERROR: cannot convert value from timestamp to timestamptz without timezone usage +HINT: use *_tz() function for timezone support +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:35:00+01:00" + "2017-03-10T11:35:00" +(2 rows) + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:35:00+01:00" + "2017-03-10T12:36:00+01:00" + "2017-03-10T12:35:00-02:00" + "2017-03-10T11:35:00" + "2017-03-10T12:35:00" + "2017-03-11" +(6 rows) + +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + jsonb_path_query_tz +----------------------------- + "2017-03-10T12:34:00+01:00" + "2017-03-10T12:35:00+02:00" + "2017-03-10T10:35:00" + "2017-03-10" +(4 rows) + +set time zone default; +-- jsonpath operators +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]'); + jsonb_path_query +------------------ + {"a": 1} + {"a": 2} +(2 rows) + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)'); + jsonb_path_query +------------------ +(0 rows) + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); +ERROR: JSON object does not contain key "a" +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a'); + jsonb_path_query_array +------------------------ + [1, 2] +(1 row) + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); + jsonb_path_query_array +------------------------ + [1] +(1 row) + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); + jsonb_path_query_array +------------------------ + [] +(1 row) + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); + jsonb_path_query_array +------------------------ + [2, 3] +(1 row) + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + jsonb_path_query_array +------------------------ + [] +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); +ERROR: JSON object does not contain key "a" +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true); + jsonb_path_query_first +------------------------ + 1 +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a'); + jsonb_path_query_first +------------------------ + 1 +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); + jsonb_path_query_first +------------------------ + 1 +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); + jsonb_path_query_first +------------------------ + +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); + jsonb_path_query_first +------------------------ + 2 +(1 row) + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + jsonb_path_query_first +------------------------ + +(1 row) + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)'; + ?column? +---------- + t +(1 row) + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)'; + ?column? +---------- + f +(1 row) + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)'); + jsonb_path_exists +------------------- + t +(1 row) + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}'); + jsonb_path_exists +------------------- + t +(1 row) + +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}'); + jsonb_path_exists +------------------- + f +(1 row) + +SELECT jsonb_path_match('true', '$', silent => false); + jsonb_path_match +------------------ + t +(1 row) + +SELECT jsonb_path_match('false', '$', silent => false); + jsonb_path_match +------------------ + f +(1 row) + +SELECT jsonb_path_match('null', '$', silent => false); + jsonb_path_match +------------------ + +(1 row) + +SELECT jsonb_path_match('1', '$', silent => true); + jsonb_path_match +------------------ + +(1 row) + +SELECT jsonb_path_match('1', '$', silent => false); +ERROR: single boolean result is expected +SELECT jsonb_path_match('"a"', '$', silent => false); +ERROR: single boolean result is expected +SELECT jsonb_path_match('{}', '$', silent => false); +ERROR: single boolean result is expected +SELECT jsonb_path_match('[true]', '$', silent => false); +ERROR: single boolean result is expected +SELECT jsonb_path_match('{}', 'lax $.a', silent => false); +ERROR: single boolean result is expected +SELECT jsonb_path_match('{}', 'strict $.a', silent => false); +ERROR: JSON object does not contain key "a" +SELECT jsonb_path_match('{}', 'strict $.a', silent => true); + jsonb_path_match +------------------ + +(1 row) + +SELECT jsonb_path_match('[true, true]', '$[*]', silent => false); +ERROR: single boolean result is expected +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1'; + ?column? +---------- + t +(1 row) + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2'; + ?column? +---------- + f +(1 row) + +SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1'); + jsonb_path_match +------------------ + t +(1 row) + +-- test string comparison (Unicode codepoint collation) +WITH str(j, num) AS +( + SELECT jsonb_build_object('s', s), num + FROM unnest('{"", "a", "ab", "abc", "abcd", "b", "A", "AB", "ABC", "ABc", "ABcD", "B"}'::text[]) WITH ORDINALITY AS a(s, num) +) +SELECT + s1.j, s2.j, + jsonb_path_query_first(s1.j, '$.s < $s', vars => s2.j) lt, + jsonb_path_query_first(s1.j, '$.s <= $s', vars => s2.j) le, + jsonb_path_query_first(s1.j, '$.s == $s', vars => s2.j) eq, + jsonb_path_query_first(s1.j, '$.s >= $s', vars => s2.j) ge, + jsonb_path_query_first(s1.j, '$.s > $s', vars => s2.j) gt +FROM str s1, str s2 +ORDER BY s1.num, s2.num; + j | j | lt | le | eq | ge | gt +---------------+---------------+-------+-------+-------+-------+------- + {"s": ""} | {"s": ""} | false | true | true | true | false + {"s": ""} | {"s": "a"} | true | true | false | false | false + {"s": ""} | {"s": "ab"} | true | true | false | false | false + {"s": ""} | {"s": "abc"} | true | true | false | false | false + {"s": ""} | {"s": "abcd"} | true | true | false | false | false + {"s": ""} | {"s": "b"} | true | true | false | false | false + {"s": ""} | {"s": "A"} | true | true | false | false | false + {"s": ""} | {"s": "AB"} | true | true | false | false | false + {"s": ""} | {"s": "ABC"} | true | true | false | false | false + {"s": ""} | {"s": "ABc"} | true | true | false | false | false + {"s": ""} | {"s": "ABcD"} | true | true | false | false | false + {"s": ""} | {"s": "B"} | true | true | false | false | false + {"s": "a"} | {"s": ""} | false | false | false | true | true + {"s": "a"} | {"s": "a"} | false | true | true | true | false + {"s": "a"} | {"s": "ab"} | true | true | false | false | false + {"s": "a"} | {"s": "abc"} | true | true | false | false | false + {"s": "a"} | {"s": "abcd"} | true | true | false | false | false + {"s": "a"} | {"s": "b"} | true | true | false | false | false + {"s": "a"} | {"s": "A"} | false | false | false | true | true + {"s": "a"} | {"s": "AB"} | false | false | false | true | true + {"s": "a"} | {"s": "ABC"} | false | false | false | true | true + {"s": "a"} | {"s": "ABc"} | false | false | false | true | true + {"s": "a"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "a"} | {"s": "B"} | false | false | false | true | true + {"s": "ab"} | {"s": ""} | false | false | false | true | true + {"s": "ab"} | {"s": "a"} | false | false | false | true | true + {"s": "ab"} | {"s": "ab"} | false | true | true | true | false + {"s": "ab"} | {"s": "abc"} | true | true | false | false | false + {"s": "ab"} | {"s": "abcd"} | true | true | false | false | false + {"s": "ab"} | {"s": "b"} | true | true | false | false | false + {"s": "ab"} | {"s": "A"} | false | false | false | true | true + {"s": "ab"} | {"s": "AB"} | false | false | false | true | true + {"s": "ab"} | {"s": "ABC"} | false | false | false | true | true + {"s": "ab"} | {"s": "ABc"} | false | false | false | true | true + {"s": "ab"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "ab"} | {"s": "B"} | false | false | false | true | true + {"s": "abc"} | {"s": ""} | false | false | false | true | true + {"s": "abc"} | {"s": "a"} | false | false | false | true | true + {"s": "abc"} | {"s": "ab"} | false | false | false | true | true + {"s": "abc"} | {"s": "abc"} | false | true | true | true | false + {"s": "abc"} | {"s": "abcd"} | true | true | false | false | false + {"s": "abc"} | {"s": "b"} | true | true | false | false | false + {"s": "abc"} | {"s": "A"} | false | false | false | true | true + {"s": "abc"} | {"s": "AB"} | false | false | false | true | true + {"s": "abc"} | {"s": "ABC"} | false | false | false | true | true + {"s": "abc"} | {"s": "ABc"} | false | false | false | true | true + {"s": "abc"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "abc"} | {"s": "B"} | false | false | false | true | true + {"s": "abcd"} | {"s": ""} | false | false | false | true | true + {"s": "abcd"} | {"s": "a"} | false | false | false | true | true + {"s": "abcd"} | {"s": "ab"} | false | false | false | true | true + {"s": "abcd"} | {"s": "abc"} | false | false | false | true | true + {"s": "abcd"} | {"s": "abcd"} | false | true | true | true | false + {"s": "abcd"} | {"s": "b"} | true | true | false | false | false + {"s": "abcd"} | {"s": "A"} | false | false | false | true | true + {"s": "abcd"} | {"s": "AB"} | false | false | false | true | true + {"s": "abcd"} | {"s": "ABC"} | false | false | false | true | true + {"s": "abcd"} | {"s": "ABc"} | false | false | false | true | true + {"s": "abcd"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "abcd"} | {"s": "B"} | false | false | false | true | true + {"s": "b"} | {"s": ""} | false | false | false | true | true + {"s": "b"} | {"s": "a"} | false | false | false | true | true + {"s": "b"} | {"s": "ab"} | false | false | false | true | true + {"s": "b"} | {"s": "abc"} | false | false | false | true | true + {"s": "b"} | {"s": "abcd"} | false | false | false | true | true + {"s": "b"} | {"s": "b"} | false | true | true | true | false + {"s": "b"} | {"s": "A"} | false | false | false | true | true + {"s": "b"} | {"s": "AB"} | false | false | false | true | true + {"s": "b"} | {"s": "ABC"} | false | false | false | true | true + {"s": "b"} | {"s": "ABc"} | false | false | false | true | true + {"s": "b"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "b"} | {"s": "B"} | false | false | false | true | true + {"s": "A"} | {"s": ""} | false | false | false | true | true + {"s": "A"} | {"s": "a"} | true | true | false | false | false + {"s": "A"} | {"s": "ab"} | true | true | false | false | false + {"s": "A"} | {"s": "abc"} | true | true | false | false | false + {"s": "A"} | {"s": "abcd"} | true | true | false | false | false + {"s": "A"} | {"s": "b"} | true | true | false | false | false + {"s": "A"} | {"s": "A"} | false | true | true | true | false + {"s": "A"} | {"s": "AB"} | true | true | false | false | false + {"s": "A"} | {"s": "ABC"} | true | true | false | false | false + {"s": "A"} | {"s": "ABc"} | true | true | false | false | false + {"s": "A"} | {"s": "ABcD"} | true | true | false | false | false + {"s": "A"} | {"s": "B"} | true | true | false | false | false + {"s": "AB"} | {"s": ""} | false | false | false | true | true + {"s": "AB"} | {"s": "a"} | true | true | false | false | false + {"s": "AB"} | {"s": "ab"} | true | true | false | false | false + {"s": "AB"} | {"s": "abc"} | true | true | false | false | false + {"s": "AB"} | {"s": "abcd"} | true | true | false | false | false + {"s": "AB"} | {"s": "b"} | true | true | false | false | false + {"s": "AB"} | {"s": "A"} | false | false | false | true | true + {"s": "AB"} | {"s": "AB"} | false | true | true | true | false + {"s": "AB"} | {"s": "ABC"} | true | true | false | false | false + {"s": "AB"} | {"s": "ABc"} | true | true | false | false | false + {"s": "AB"} | {"s": "ABcD"} | true | true | false | false | false + {"s": "AB"} | {"s": "B"} | true | true | false | false | false + {"s": "ABC"} | {"s": ""} | false | false | false | true | true + {"s": "ABC"} | {"s": "a"} | true | true | false | false | false + {"s": "ABC"} | {"s": "ab"} | true | true | false | false | false + {"s": "ABC"} | {"s": "abc"} | true | true | false | false | false + {"s": "ABC"} | {"s": "abcd"} | true | true | false | false | false + {"s": "ABC"} | {"s": "b"} | true | true | false | false | false + {"s": "ABC"} | {"s": "A"} | false | false | false | true | true + {"s": "ABC"} | {"s": "AB"} | false | false | false | true | true + {"s": "ABC"} | {"s": "ABC"} | false | true | true | true | false + {"s": "ABC"} | {"s": "ABc"} | true | true | false | false | false + {"s": "ABC"} | {"s": "ABcD"} | true | true | false | false | false + {"s": "ABC"} | {"s": "B"} | true | true | false | false | false + {"s": "ABc"} | {"s": ""} | false | false | false | true | true + {"s": "ABc"} | {"s": "a"} | true | true | false | false | false + {"s": "ABc"} | {"s": "ab"} | true | true | false | false | false + {"s": "ABc"} | {"s": "abc"} | true | true | false | false | false + {"s": "ABc"} | {"s": "abcd"} | true | true | false | false | false + {"s": "ABc"} | {"s": "b"} | true | true | false | false | false + {"s": "ABc"} | {"s": "A"} | false | false | false | true | true + {"s": "ABc"} | {"s": "AB"} | false | false | false | true | true + {"s": "ABc"} | {"s": "ABC"} | false | false | false | true | true + {"s": "ABc"} | {"s": "ABc"} | false | true | true | true | false + {"s": "ABc"} | {"s": "ABcD"} | true | true | false | false | false + {"s": "ABc"} | {"s": "B"} | true | true | false | false | false + {"s": "ABcD"} | {"s": ""} | false | false | false | true | true + {"s": "ABcD"} | {"s": "a"} | true | true | false | false | false + {"s": "ABcD"} | {"s": "ab"} | true | true | false | false | false + {"s": "ABcD"} | {"s": "abc"} | true | true | false | false | false + {"s": "ABcD"} | {"s": "abcd"} | true | true | false | false | false + {"s": "ABcD"} | {"s": "b"} | true | true | false | false | false + {"s": "ABcD"} | {"s": "A"} | false | false | false | true | true + {"s": "ABcD"} | {"s": "AB"} | false | false | false | true | true + {"s": "ABcD"} | {"s": "ABC"} | false | false | false | true | true + {"s": "ABcD"} | {"s": "ABc"} | false | false | false | true | true + {"s": "ABcD"} | {"s": "ABcD"} | false | true | true | true | false + {"s": "ABcD"} | {"s": "B"} | true | true | false | false | false + {"s": "B"} | {"s": ""} | false | false | false | true | true + {"s": "B"} | {"s": "a"} | true | true | false | false | false + {"s": "B"} | {"s": "ab"} | true | true | false | false | false + {"s": "B"} | {"s": "abc"} | true | true | false | false | false + {"s": "B"} | {"s": "abcd"} | true | true | false | false | false + {"s": "B"} | {"s": "b"} | true | true | false | false | false + {"s": "B"} | {"s": "A"} | false | false | false | true | true + {"s": "B"} | {"s": "AB"} | false | false | false | true | true + {"s": "B"} | {"s": "ABC"} | false | false | false | true | true + {"s": "B"} | {"s": "ABc"} | false | false | false | true | true + {"s": "B"} | {"s": "ABcD"} | false | false | false | true | true + {"s": "B"} | {"s": "B"} | false | true | true | true | false +(144 rows) + diff --git a/src/test/regress/expected/jsonpath.out b/src/test/regress/expected/jsonpath.out new file mode 100644 index 00000000000..e399fa96312 --- /dev/null +++ b/src/test/regress/expected/jsonpath.out @@ -0,0 +1,964 @@ +--jsonpath io +select ''::jsonpath; +ERROR: invalid input syntax for type jsonpath: "" +LINE 1: select ''::jsonpath; + ^ +select '$'::jsonpath; + jsonpath +---------- + $ +(1 row) + +select 'strict $'::jsonpath; + jsonpath +---------- + strict $ +(1 row) + +select 'lax $'::jsonpath; + jsonpath +---------- + $ +(1 row) + +select '$.a'::jsonpath; + jsonpath +---------- + $."a" +(1 row) + +select '$.a.v'::jsonpath; + jsonpath +----------- + $."a"."v" +(1 row) + +select '$.a.*'::jsonpath; + jsonpath +---------- + $."a".* +(1 row) + +select '$.*[*]'::jsonpath; + jsonpath +---------- + $.*[*] +(1 row) + +select '$.a[*]'::jsonpath; + jsonpath +---------- + $."a"[*] +(1 row) + +select '$.a[*][*]'::jsonpath; + jsonpath +------------- + $."a"[*][*] +(1 row) + +select '$[*]'::jsonpath; + jsonpath +---------- + $[*] +(1 row) + +select '$[0]'::jsonpath; + jsonpath +---------- + $[0] +(1 row) + +select '$[*][0]'::jsonpath; + jsonpath +---------- + $[*][0] +(1 row) + +select '$[*].a'::jsonpath; + jsonpath +---------- + $[*]."a" +(1 row) + +select '$[*][0].a.b'::jsonpath; + jsonpath +----------------- + $[*][0]."a"."b" +(1 row) + +select '$.a.**.b'::jsonpath; + jsonpath +-------------- + $."a".**."b" +(1 row) + +select '$.a.**{2}.b'::jsonpath; + jsonpath +----------------- + $."a".**{2}."b" +(1 row) + +select '$.a.**{2 to 2}.b'::jsonpath; + jsonpath +----------------- + $."a".**{2}."b" +(1 row) + +select '$.a.**{2 to 5}.b'::jsonpath; + jsonpath +---------------------- + $."a".**{2 to 5}."b" +(1 row) + +select '$.a.**{0 to 5}.b'::jsonpath; + jsonpath +---------------------- + $."a".**{0 to 5}."b" +(1 row) + +select '$.a.**{5 to last}.b'::jsonpath; + jsonpath +------------------------- + $."a".**{5 to last}."b" +(1 row) + +select '$.a.**{last}.b'::jsonpath; + jsonpath +-------------------- + $."a".**{last}."b" +(1 row) + +select '$.a.**{last to 5}.b'::jsonpath; + jsonpath +------------------------- + $."a".**{last to 5}."b" +(1 row) + +select '$+1'::jsonpath; + jsonpath +---------- + ($ + 1) +(1 row) + +select '$-1'::jsonpath; + jsonpath +---------- + ($ - 1) +(1 row) + +select '$--+1'::jsonpath; + jsonpath +---------- + ($ - -1) +(1 row) + +select '$.a/+-1'::jsonpath; + jsonpath +-------------- + ($."a" / -1) +(1 row) + +select '1 * 2 + 4 % -3 != false'::jsonpath; + jsonpath +--------------------------- + (1 * 2 + 4 % -3 != false) +(1 row) + +select '"\b\f\r\n\t\v\"\''\\"'::jsonpath; + jsonpath +------------------------- + "\b\f\r\n\t\u000b\"'\\" +(1 row) + +select '"\x50\u0067\u{53}\u{051}\u{00004C}"'::jsonpath; + jsonpath +---------- + "PgSQL" +(1 row) + +select '$.foo\x50\u0067\u{53}\u{051}\u{00004C}\t\"bar'::jsonpath; + jsonpath +--------------------- + $."fooPgSQL\t\"bar" +(1 row) + +select '"\z"'::jsonpath; -- unrecognized escape is just the literal char + jsonpath +---------- + "z" +(1 row) + +select '$.g ? ($.a == 1)'::jsonpath; + jsonpath +-------------------- + $."g"?($."a" == 1) +(1 row) + +select '$.g ? (@ == 1)'::jsonpath; + jsonpath +---------------- + $."g"?(@ == 1) +(1 row) + +select '$.g ? (@.a == 1)'::jsonpath; + jsonpath +-------------------- + $."g"?(@."a" == 1) +(1 row) + +select '$.g ? (@.a == 1 || @.a == 4)'::jsonpath; + jsonpath +---------------------------------- + $."g"?(@."a" == 1 || @."a" == 4) +(1 row) + +select '$.g ? (@.a == 1 && @.a == 4)'::jsonpath; + jsonpath +---------------------------------- + $."g"?(@."a" == 1 && @."a" == 4) +(1 row) + +select '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath; + jsonpath +------------------------------------------------ + $."g"?(@."a" == 1 || @."a" == 4 && @."b" == 7) +(1 row) + +select '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath; + jsonpath +--------------------------------------------------- + $."g"?(@."a" == 1 || !(@."a" == 4) && @."b" == 7) +(1 row) + +select '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath; + jsonpath +------------------------------------------------------------------- + $."g"?(@."a" == 1 || !(@."x" >= 123 || @."a" == 4) && @."b" == 7) +(1 row) + +select '$.g ? (@.x >= @[*]?(@.a > "abc"))'::jsonpath; + jsonpath +--------------------------------------- + $."g"?(@."x" >= @[*]?(@."a" > "abc")) +(1 row) + +select '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath; + jsonpath +------------------------------------------------- + $."g"?((@."x" >= 123 || @."a" == 4) is unknown) +(1 row) + +select '$.g ? (exists (@.x))'::jsonpath; + jsonpath +------------------------ + $."g"?(exists (@."x")) +(1 row) + +select '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath; + jsonpath +---------------------------------- + $."g"?(exists (@."x"?(@ == 14))) +(1 row) + +select '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath; + jsonpath +------------------------------------------------------------------ + $."g"?((@."x" >= 123 || @."a" == 4) && exists (@."x"?(@ == 14))) +(1 row) + +select '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath; + jsonpath +------------------------------------ + $."g"?(+@."x" >= +(-(+@."a" + 2))) +(1 row) + +select '$a'::jsonpath; + jsonpath +---------- + $"a" +(1 row) + +select '$a.b'::jsonpath; + jsonpath +---------- + $"a"."b" +(1 row) + +select '$a[*]'::jsonpath; + jsonpath +---------- + $"a"[*] +(1 row) + +select '$.g ? (@.zip == $zip)'::jsonpath; + jsonpath +--------------------------- + $."g"?(@."zip" == $"zip") +(1 row) + +select '$.a[1,2, 3 to 16]'::jsonpath; + jsonpath +-------------------- + $."a"[1,2,3 to 16] +(1 row) + +select '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath; + jsonpath +---------------------------------------- + $."a"[$"a" + 1,$"b"[*] to -($[0] * 2)] +(1 row) + +select '$.a[$.a.size() - 3]'::jsonpath; + jsonpath +------------------------- + $."a"[$."a".size() - 3] +(1 row) + +select 'last'::jsonpath; +ERROR: LAST is allowed only in array subscripts +LINE 1: select 'last'::jsonpath; + ^ +select '"last"'::jsonpath; + jsonpath +---------- + "last" +(1 row) + +select '$.last'::jsonpath; + jsonpath +---------- + $."last" +(1 row) + +select '$ ? (last > 0)'::jsonpath; +ERROR: LAST is allowed only in array subscripts +LINE 1: select '$ ? (last > 0)'::jsonpath; + ^ +select '$[last]'::jsonpath; + jsonpath +---------- + $[last] +(1 row) + +select '$[$[0] ? (last > 0)]'::jsonpath; + jsonpath +-------------------- + $[$[0]?(last > 0)] +(1 row) + +select 'null.type()'::jsonpath; + jsonpath +------------- + null.type() +(1 row) + +select '1.type()'::jsonpath; + jsonpath +---------- + 1.type() +(1 row) + +select '(1).type()'::jsonpath; + jsonpath +---------- + 1.type() +(1 row) + +select '1.2.type()'::jsonpath; + jsonpath +------------ + 1.2.type() +(1 row) + +select '"aaa".type()'::jsonpath; + jsonpath +-------------- + "aaa".type() +(1 row) + +select 'true.type()'::jsonpath; + jsonpath +------------- + true.type() +(1 row) + +select '$.double().floor().ceiling().abs()'::jsonpath; + jsonpath +------------------------------------ + $.double().floor().ceiling().abs() +(1 row) + +select '$.keyvalue().key'::jsonpath; + jsonpath +-------------------- + $.keyvalue()."key" +(1 row) + +select '$.datetime()'::jsonpath; + jsonpath +-------------- + $.datetime() +(1 row) + +select '$.datetime("datetime template")'::jsonpath; + jsonpath +--------------------------------- + $.datetime("datetime template") +(1 row) + +select '$ ? (@ starts with "abc")'::jsonpath; + jsonpath +------------------------- + $?(@ starts with "abc") +(1 row) + +select '$ ? (@ starts with $var)'::jsonpath; + jsonpath +-------------------------- + $?(@ starts with $"var") +(1 row) + +select '$ ? (@ like_regex "(invalid pattern")'::jsonpath; +ERROR: invalid regular expression: parentheses () not balanced +LINE 1: select '$ ? (@ like_regex "(invalid pattern")'::jsonpath; + ^ +select '$ ? (@ like_regex "pattern")'::jsonpath; + jsonpath +---------------------------- + $?(@ like_regex "pattern") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "")'::jsonpath; + jsonpath +---------------------------- + $?(@ like_regex "pattern") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath; + jsonpath +------------------------------------- + $?(@ like_regex "pattern" flag "i") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath; + jsonpath +-------------------------------------- + $?(@ like_regex "pattern" flag "is") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath; + jsonpath +--------------------------------------- + $?(@ like_regex "pattern" flag "ism") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; +ERROR: XQuery "x" flag (expanded regular expressions) is not implemented +LINE 1: select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; + ^ +select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath; + jsonpath +------------------------------------- + $?(@ like_regex "pattern" flag "q") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath; + jsonpath +-------------------------------------- + $?(@ like_regex "pattern" flag "iq") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath; + jsonpath +----------------------------------------- + $?(@ like_regex "pattern" flag "ismxq") +(1 row) + +select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; + ^ +DETAIL: unrecognized flag character "a" in LIKE_REGEX predicate +select '$ < 1'::jsonpath; + jsonpath +---------- + ($ < 1) +(1 row) + +select '($ < 1) || $.a.b <= $x'::jsonpath; + jsonpath +------------------------------ + ($ < 1 || $."a"."b" <= $"x") +(1 row) + +select '@ + 1'::jsonpath; +ERROR: @ is not allowed in root expressions +LINE 1: select '@ + 1'::jsonpath; + ^ +select '($).a.b'::jsonpath; + jsonpath +----------- + $."a"."b" +(1 row) + +select '($.a.b).c.d'::jsonpath; + jsonpath +------------------- + $."a"."b"."c"."d" +(1 row) + +select '($.a.b + -$.x.y).c.d'::jsonpath; + jsonpath +---------------------------------- + ($."a"."b" + -$."x"."y")."c"."d" +(1 row) + +select '(-+$.a.b).c.d'::jsonpath; + jsonpath +------------------------- + (-(+$."a"."b"))."c"."d" +(1 row) + +select '1 + ($.a.b + 2).c.d'::jsonpath; + jsonpath +------------------------------- + (1 + ($."a"."b" + 2)."c"."d") +(1 row) + +select '1 + ($.a.b > 2).c.d'::jsonpath; + jsonpath +------------------------------- + (1 + ($."a"."b" > 2)."c"."d") +(1 row) + +select '($)'::jsonpath; + jsonpath +---------- + $ +(1 row) + +select '(($))'::jsonpath; + jsonpath +---------- + $ +(1 row) + +select '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath; + jsonpath +------------------------------------------------- + (($ + 1)."a" + 2."b"?(@ > 1 || exists (@."c"))) +(1 row) + +select '$ ? (@.a < 1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < -1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < -1) +(1 row) + +select '$ ? (@.a < +1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < .1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < .1)'::jsonpath; + ^ +select '$ ? (@.a < -.1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < -.1)'::jsonpath; + ^ +select '$ ? (@.a < +.1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < +.1)'::jsonpath; + ^ +select '$ ? (@.a < 0.1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 0.1) +(1 row) + +select '$ ? (@.a < -0.1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < -0.1) +(1 row) + +select '$ ? (@.a < +0.1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 0.1) +(1 row) + +select '$ ? (@.a < 10.1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 10.1) +(1 row) + +select '$ ? (@.a < -10.1)'::jsonpath; + jsonpath +------------------- + $?(@."a" < -10.1) +(1 row) + +select '$ ? (@.a < +10.1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 10.1) +(1 row) + +select '$ ? (@.a < 1e1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < 10) +(1 row) + +select '$ ? (@.a < -1e1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < -10) +(1 row) + +select '$ ? (@.a < +1e1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < 10) +(1 row) + +select '$ ? (@.a < .1e1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < .1e1)'::jsonpath; + ^ +select '$ ? (@.a < -.1e1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < -.1e1)'::jsonpath; + ^ +select '$ ? (@.a < +.1e1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < +.1e1)'::jsonpath; + ^ +select '$ ? (@.a < 0.1e1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < -0.1e1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < -1) +(1 row) + +select '$ ? (@.a < +0.1e1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < 10.1e1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 101) +(1 row) + +select '$ ? (@.a < -10.1e1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < -101) +(1 row) + +select '$ ? (@.a < +10.1e1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 101) +(1 row) + +select '$ ? (@.a < 1e-1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 0.1) +(1 row) + +select '$ ? (@.a < -1e-1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < -0.1) +(1 row) + +select '$ ? (@.a < +1e-1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 0.1) +(1 row) + +select '$ ? (@.a < .1e-1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < .1e-1)'::jsonpath; + ^ +select '$ ? (@.a < -.1e-1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < -.1e-1)'::jsonpath; + ^ +select '$ ? (@.a < +.1e-1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < +.1e-1)'::jsonpath; + ^ +select '$ ? (@.a < 0.1e-1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 0.01) +(1 row) + +select '$ ? (@.a < -0.1e-1)'::jsonpath; + jsonpath +------------------- + $?(@."a" < -0.01) +(1 row) + +select '$ ? (@.a < +0.1e-1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 0.01) +(1 row) + +select '$ ? (@.a < 10.1e-1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 1.01) +(1 row) + +select '$ ? (@.a < -10.1e-1)'::jsonpath; + jsonpath +------------------- + $?(@."a" < -1.01) +(1 row) + +select '$ ? (@.a < +10.1e-1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < 1.01) +(1 row) + +select '$ ? (@.a < 1e+1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < 10) +(1 row) + +select '$ ? (@.a < -1e+1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < -10) +(1 row) + +select '$ ? (@.a < +1e+1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < 10) +(1 row) + +select '$ ? (@.a < .1e+1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < .1e+1)'::jsonpath; + ^ +select '$ ? (@.a < -.1e+1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < -.1e+1)'::jsonpath; + ^ +select '$ ? (@.a < +.1e+1)'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '$ ? (@.a < +.1e+1)'::jsonpath; + ^ +select '$ ? (@.a < 0.1e+1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < -0.1e+1)'::jsonpath; + jsonpath +---------------- + $?(@."a" < -1) +(1 row) + +select '$ ? (@.a < +0.1e+1)'::jsonpath; + jsonpath +--------------- + $?(@."a" < 1) +(1 row) + +select '$ ? (@.a < 10.1e+1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 101) +(1 row) + +select '$ ? (@.a < -10.1e+1)'::jsonpath; + jsonpath +------------------ + $?(@."a" < -101) +(1 row) + +select '$ ? (@.a < +10.1e+1)'::jsonpath; + jsonpath +----------------- + $?(@."a" < 101) +(1 row) + +select '0'::jsonpath; + jsonpath +---------- + 0 +(1 row) + +select '00'::jsonpath; +ERROR: syntax error, unexpected IDENT_P at end of jsonpath input +LINE 1: select '00'::jsonpath; + ^ +select '0.0'::jsonpath; + jsonpath +---------- + 0.0 +(1 row) + +select '0.000'::jsonpath; + jsonpath +---------- + 0.000 +(1 row) + +select '0.000e1'::jsonpath; + jsonpath +---------- + 0.00 +(1 row) + +select '0.000e2'::jsonpath; + jsonpath +---------- + 0.0 +(1 row) + +select '0.000e3'::jsonpath; + jsonpath +---------- + 0 +(1 row) + +select '0.0010'::jsonpath; + jsonpath +---------- + 0.0010 +(1 row) + +select '0.0010e-1'::jsonpath; + jsonpath +---------- + 0.00010 +(1 row) + +select '0.0010e+1'::jsonpath; + jsonpath +---------- + 0.010 +(1 row) + +select '0.0010e+2'::jsonpath; + jsonpath +---------- + 0.10 +(1 row) + +select '1e'::jsonpath; +ERROR: invalid floating point number at or near "1e" of jsonpath input +LINE 1: select '1e'::jsonpath; + ^ +select '1.e'::jsonpath; + jsonpath +---------- + 1."e" +(1 row) + +select '1.2e'::jsonpath; +ERROR: invalid floating point number at or near "1.2e" of jsonpath input +LINE 1: select '1.2e'::jsonpath; + ^ +select '1.2.e'::jsonpath; + jsonpath +---------- + 1.2."e" +(1 row) + +select '(1.2).e'::jsonpath; + jsonpath +---------- + 1.2."e" +(1 row) + +select '1e3'::jsonpath; + jsonpath +---------- + 1000 +(1 row) + +select '1.e3'::jsonpath; + jsonpath +---------- + 1."e3" +(1 row) + +select '1.e3.e'::jsonpath; + jsonpath +------------ + 1."e3"."e" +(1 row) + +select '1.e3.e4'::jsonpath; + jsonpath +------------- + 1."e3"."e4" +(1 row) + +select '1.2e3'::jsonpath; + jsonpath +---------- + 1200 +(1 row) + +select '1.2.e3'::jsonpath; + jsonpath +---------- + 1.2."e3" +(1 row) + +select '(1.2).e3'::jsonpath; + jsonpath +---------- + 1.2."e3" +(1 row) + +select '1..e'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '1..e'::jsonpath; + ^ +select '1..e3'::jsonpath; +ERROR: syntax error, unexpected '.' at or near "." of jsonpath input +LINE 1: select '1..e3'::jsonpath; + ^ +select '(1.).e'::jsonpath; +ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input +LINE 1: select '(1.).e'::jsonpath; + ^ +select '(1.).e3'::jsonpath; +ERROR: syntax error, unexpected ')' at or near ")" of jsonpath input +LINE 1: select '(1.).e3'::jsonpath; + ^ diff --git a/src/test/regress/expected/jsonpath_encoding.out b/src/test/regress/expected/jsonpath_encoding.out new file mode 100644 index 00000000000..ecffe095b59 --- /dev/null +++ b/src/test/regress/expected/jsonpath_encoding.out @@ -0,0 +1,165 @@ +-- encoding-sensitive tests for jsonpath +-- checks for double-quoted values +-- basic unicode input +SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u" of jsonpath input +LINE 1: SELECT '"\u"'::jsonpath; + ^ +SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input +LINE 1: SELECT '"\u00"'::jsonpath; + ^ +SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input +LINE 1: SELECT '"\u000g"'::jsonpath; + ^ +SELECT '"\u0000"'::jsonpath; -- OK, legal escape +ERROR: unsupported Unicode escape sequence +LINE 1: SELECT '"\u0000"'::jsonpath; + ^ +DETAIL: \u0000 cannot be converted to text. +SELECT '"\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK + jsonpath +---------- + "ê¯" +(1 row) + +-- handling of unicode surrogate pairs +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; + correct_in_utf8 +----------------- + "😄ðŸ¶" +(1 row) + +select '"\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ud83d\ud83d"'::jsonpath; + ^ +DETAIL: Unicode high surrogate must not follow a high surrogate. +select '"\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ude04\ud83d"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '"\ud83dX"'::jsonpath; -- orphan high surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ud83dX"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '"\ude04X"'::jsonpath; -- orphan low surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ude04X"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +--handling of simple unicode escapes +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; + correct_in_utf8 +------------------------ + "the Copyright © sign" +(1 row) + +select '"dollar \u0024 character"'::jsonpath as correct_everywhere; + correct_everywhere +---------------------- + "dollar $ character" +(1 row) + +select '"dollar \\u0024 character"'::jsonpath as not_an_escape; + not_an_escape +---------------------------- + "dollar \\u0024 character" +(1 row) + +select '"null \u0000 escape"'::jsonpath as not_unescaped; +ERROR: unsupported Unicode escape sequence +LINE 1: select '"null \u0000 escape"'::jsonpath as not_unescaped; + ^ +DETAIL: \u0000 cannot be converted to text. +select '"null \\u0000 escape"'::jsonpath as not_an_escape; + not_an_escape +----------------------- + "null \\u0000 escape" +(1 row) + +-- checks for quoted key names +-- basic unicode input +SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u" of jsonpath input +LINE 1: SELECT '$."\u"'::jsonpath; + ^ +SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input +LINE 1: SELECT '$."\u00"'::jsonpath; + ^ +SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input +LINE 1: SELECT '$."\u000g"'::jsonpath; + ^ +SELECT '$."\u0000"'::jsonpath; -- OK, legal escape +ERROR: unsupported Unicode escape sequence +LINE 1: SELECT '$."\u0000"'::jsonpath; + ^ +DETAIL: \u0000 cannot be converted to text. +SELECT '$."\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK + jsonpath +---------- + $."ê¯" +(1 row) + +-- handling of unicode surrogate pairs +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; + correct_in_utf8 +----------------- + $."😄ðŸ¶" +(1 row) + +select '$."\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ud83d\ud83d"'::jsonpath; + ^ +DETAIL: Unicode high surrogate must not follow a high surrogate. +select '$."\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ude04\ud83d"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '$."\ud83dX"'::jsonpath; -- orphan high surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ud83dX"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '$."\ude04X"'::jsonpath; -- orphan low surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ude04X"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +--handling of simple unicode escapes +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; + correct_in_utf8 +-------------------------- + $."the Copyright © sign" +(1 row) + +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere; + correct_everywhere +------------------------ + $."dollar $ character" +(1 row) + +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape; + not_an_escape +------------------------------ + $."dollar \\u0024 character" +(1 row) + +select '$."null \u0000 escape"'::jsonpath as not_unescaped; +ERROR: unsupported Unicode escape sequence +LINE 1: select '$."null \u0000 escape"'::jsonpath as not_unescaped; + ^ +DETAIL: \u0000 cannot be converted to text. +select '$."null \\u0000 escape"'::jsonpath as not_an_escape; + not_an_escape +------------------------- + $."null \\u0000 escape" +(1 row) + diff --git a/src/test/regress/expected/jsonpath_encoding_1.out b/src/test/regress/expected/jsonpath_encoding_1.out new file mode 100644 index 00000000000..c8cc2173a8c --- /dev/null +++ b/src/test/regress/expected/jsonpath_encoding_1.out @@ -0,0 +1,159 @@ +-- encoding-sensitive tests for jsonpath +-- checks for double-quoted values +-- basic unicode input +SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u" of jsonpath input +LINE 1: SELECT '"\u"'::jsonpath; + ^ +SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input +LINE 1: SELECT '"\u00"'::jsonpath; + ^ +SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input +LINE 1: SELECT '"\u000g"'::jsonpath; + ^ +SELECT '"\u0000"'::jsonpath; -- OK, legal escape +ERROR: unsupported Unicode escape sequence +LINE 1: SELECT '"\u0000"'::jsonpath; + ^ +DETAIL: \u0000 cannot be converted to text. +SELECT '"\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK +ERROR: invalid input syntax for type jsonpath +LINE 1: SELECT '"\uaBcD"'::jsonpath; + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +-- handling of unicode surrogate pairs +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_... + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +select '"\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ud83d\ud83d"'::jsonpath; + ^ +DETAIL: Unicode high surrogate must not follow a high surrogate. +select '"\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ude04\ud83d"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '"\ud83dX"'::jsonpath; -- orphan high surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ud83dX"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '"\ude04X"'::jsonpath; -- orphan low surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"\ude04X"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +--handling of simple unicode escapes +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; +ERROR: invalid input syntax for type jsonpath +LINE 1: select '"the Copyright \u00a9 sign"'::jsonpath as correct_in... + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +select '"dollar \u0024 character"'::jsonpath as correct_everywhere; + correct_everywhere +---------------------- + "dollar $ character" +(1 row) + +select '"dollar \\u0024 character"'::jsonpath as not_an_escape; + not_an_escape +---------------------------- + "dollar \\u0024 character" +(1 row) + +select '"null \u0000 escape"'::jsonpath as not_unescaped; +ERROR: unsupported Unicode escape sequence +LINE 1: select '"null \u0000 escape"'::jsonpath as not_unescaped; + ^ +DETAIL: \u0000 cannot be converted to text. +select '"null \\u0000 escape"'::jsonpath as not_an_escape; + not_an_escape +----------------------- + "null \\u0000 escape" +(1 row) + +-- checks for quoted key names +-- basic unicode input +SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u" of jsonpath input +LINE 1: SELECT '$."\u"'::jsonpath; + ^ +SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape +ERROR: invalid unicode sequence at or near "\u00" of jsonpath input +LINE 1: SELECT '$."\u00"'::jsonpath; + ^ +SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit +ERROR: invalid unicode sequence at or near "\u000" of jsonpath input +LINE 1: SELECT '$."\u000g"'::jsonpath; + ^ +SELECT '$."\u0000"'::jsonpath; -- OK, legal escape +ERROR: unsupported Unicode escape sequence +LINE 1: SELECT '$."\u0000"'::jsonpath; + ^ +DETAIL: \u0000 cannot be converted to text. +SELECT '$."\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK +ERROR: invalid input syntax for type jsonpath +LINE 1: SELECT '$."\uaBcD"'::jsonpath; + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +-- handling of unicode surrogate pairs +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_i... + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +select '$."\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ud83d\ud83d"'::jsonpath; + ^ +DETAIL: Unicode high surrogate must not follow a high surrogate. +select '$."\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ude04\ud83d"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '$."\ud83dX"'::jsonpath; -- orphan high surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ud83dX"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +select '$."\ude04X"'::jsonpath; -- orphan low surrogate +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."\ude04X"'::jsonpath; + ^ +DETAIL: Unicode low surrogate must follow a high surrogate. +--handling of simple unicode escapes +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; +ERROR: invalid input syntax for type jsonpath +LINE 1: select '$."the Copyright \u00a9 sign"'::jsonpath as correct_... + ^ +DETAIL: Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8. +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere; + correct_everywhere +------------------------ + $."dollar $ character" +(1 row) + +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape; + not_an_escape +------------------------------ + $."dollar \\u0024 character" +(1 row) + +select '$."null \u0000 escape"'::jsonpath as not_unescaped; +ERROR: unsupported Unicode escape sequence +LINE 1: select '$."null \u0000 escape"'::jsonpath as not_unescaped; + ^ +DETAIL: \u0000 cannot be converted to text. +select '$."null \\u0000 escape"'::jsonpath as not_an_escape; + not_an_escape +------------------------- + $."null \\u0000 escape" +(1 row) + diff --git a/src/test/regress/expected/line.out b/src/test/regress/expected/line.out index f20abdc4301..fe106589c6a 100644 --- a/src/test/regress/expected/line.out +++ b/src/test/regress/expected/line.out @@ -4,24 +4,43 @@ -- --DROP TABLE LINE_TBL; CREATE TABLE LINE_TBL (s line); -INSERT INTO LINE_TBL VALUES ('{1,-1,1}'); -INSERT INTO LINE_TBL VALUES ('(0,0),(6,6)'); +INSERT INTO LINE_TBL VALUES ('{0,-1,5}'); -- A == 0 +INSERT INTO LINE_TBL VALUES ('{1,0,5}'); -- B == 0 +INSERT INTO LINE_TBL VALUES ('{0,3,0}'); -- A == C == 0 +INSERT INTO LINE_TBL VALUES (' (0,0), (6,6)'); INSERT INTO LINE_TBL VALUES ('10,-10 ,-5,-4'); INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); -INSERT INTO LINE_TBL VALUES ('(11,22,33,44)'); -INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); -ERROR: invalid line specification: must be two distinct points -LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); - ^ +INSERT INTO LINE_TBL VALUES ('{3,NaN,5}'); +INSERT INTO LINE_TBL VALUES ('{NaN,NaN,NaN}'); -- horizontal INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]'); -- vertical -INSERT INTO LINE_TBL VALUES ('[(3,1),(3,2)]'); +INSERT INTO LINE_TBL VALUES (line(point '(3,1)', point '(3,2)')); -- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{}'); +ERROR: invalid input syntax for type line: "{}" +LINE 1: INSERT INTO LINE_TBL VALUES ('{}'); + ^ +INSERT INTO LINE_TBL VALUES ('{0'); +ERROR: invalid input syntax for type line: "{0" +LINE 1: INSERT INTO LINE_TBL VALUES ('{0'); + ^ +INSERT INTO LINE_TBL VALUES ('{0,0}'); +ERROR: invalid input syntax for type line: "{0,0}" +LINE 1: INSERT INTO LINE_TBL VALUES ('{0,0}'); + ^ +INSERT INTO LINE_TBL VALUES ('{0,0,1'); +ERROR: invalid input syntax for type line: "{0,0,1" +LINE 1: INSERT INTO LINE_TBL VALUES ('{0,0,1'); + ^ INSERT INTO LINE_TBL VALUES ('{0,0,1}'); ERROR: invalid line specification: A and B cannot both be zero LINE 1: INSERT INTO LINE_TBL VALUES ('{0,0,1}'); ^ +INSERT INTO LINE_TBL VALUES ('{0,0,1} x'); +ERROR: invalid input syntax for type line: "{0,0,1} x" +LINE 1: INSERT INTO LINE_TBL VALUES ('{0,0,1} x'); + ^ INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); ERROR: invalid input syntax for type line: "(3asdf,2 ,3,4r2)" LINE 1: INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); @@ -38,234 +57,31 @@ INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); ERROR: invalid input syntax for type line: "[(1,2),(3,4)" LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); ^ +INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]'); +ERROR: invalid line specification: must be two distinct points +LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]'); + ^ +INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)')); +ERROR: invalid line specification: must be two distinct points select * from LINE_TBL; - s ---------------------------------------------- - {1,-1,1} + s +------------------------------------------------ + {0,-1,5} + {1,0,5} + {0,3,0} {1,-1,0} {-0.4,-1,-6} - {-0.000184615384615385,-1,15.3846153846154} - {1,-1,11} + {-0.0001846153846153846,-1,15.384615384615387} + {3,NaN,5} + {NaN,NaN,NaN} {0,-1,3} {-1,0,3} -(7 rows) - --- functions and operators -SELECT * FROM LINE_TBL WHERE (s <-> line '[(1,2),(3,4)]') < 10; - s ---------------------------------------------- - {1,-1,1} - {1,-1,0} - {-0.4,-1,-6} - {-0.000184615384615385,-1,15.3846153846154} - {1,-1,11} - {0,-1,3} - {-1,0,3} -(7 rows) - -SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1; - s ----------- - {1,-1,1} - {1,-1,0} -(2 rows) - -SELECT * FROM LINE_TBL WHERE (lseg '[(0.1,0.1),(0.2,0.2)]' <-> s) < 1; - s ----------- - {1,-1,1} - {1,-1,0} -(2 rows) - -SELECT line '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; - ?column? ----------- - 2 -(1 row) - -SELECT lseg '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; - ?column? ----------- - 2 -(1 row) - -SELECT point '(-1,1)' <-> line '[(-3,0),(-4,0)]'; - ?column? ----------- - 1 -(1 row) - -SELECT lseg '[(1,1),(5,5)]' ?# line '[(2,0),(0,2)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT lseg '[(1,1),(5,5)]' ?# line '[(0,0),(1,0)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT line '[(0,0),(1,1)]' ?# box '(0,0,2,2)'; -- true - ?column? ----------- - t -(1 row) - -SELECT line '[(3,0),(4,1)]' ?# box '(0,0,2,2)'; -- false - ?column? ----------- - f -(1 row) - -SELECT point '(1,1)' <@ line '[(0,0),(2,2)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT point '(1,1)' <@ line '[(0,0),(1,0)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT point '(1,1)' @ line '[(0,0),(2,2)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT point '(1,1)' @ line '[(0,0),(1,0)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT lseg '[(1,1),(2,2)]' <@ line '[(0,0),(2,2)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT lseg '[(1,1),(2,1)]' <@ line '[(0,0),(1,0)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT lseg '[(1,1),(2,2)]' @ line '[(0,0),(2,2)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT lseg '[(1,1),(2,1)]' @ line '[(0,0),(1,0)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT point '(0,1)' ## line '[(0,0),(1,1)]'; - ?column? ------------ - (0.5,0.5) -(1 row) - -SELECT line '[(0,0),(1,1)]' ## lseg '[(1,0),(2,0)]'; - ?column? ----------- - (1,0) -(1 row) - -SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(2,1)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(1,1)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT line '[(0,0),(1,1)]' # line '[(1,0),(2,1)]'; - ?column? ----------- - -(1 row) - -SELECT line '[(0,0),(1,1)]' # line '[(1,0),(1,1)]'; - ?column? ----------- - (1,1) -(1 row) - -SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(2,1)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(1,1)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT line '[(0,0),(1,0)]' ?-| line '[(0,0),(0,1)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT line '[(0,0),(1,1)]' ?-| line '[(1,0),(1,1)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT ?- line '[(0,0),(1,0)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT ?- line '[(0,0),(1,1)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT ?| line '[(0,0),(0,1)]'; -- true - ?column? ----------- - t -(1 row) - -SELECT ?| line '[(0,0),(1,1)]'; -- false - ?column? ----------- - f -(1 row) - -SELECT line(point '(1,2)', point '(3,4)'); - line ----------- - {1,-1,1} -(1 row) - -SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,5)]'; -- true - ?column? ----------- - t -(1 row) +(10 rows) -SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,4)]'; -- false - ?column? ----------- - f +select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line as false; + true | false +------+------- + t | f (1 row) diff --git a/src/test/regress/expected/lock.out b/src/test/regress/expected/lock.out index 964e6f2cdf7..185fd2f879b 100644 --- a/src/test/regress/expected/lock.out +++ b/src/test/regress/expected/lock.out @@ -120,6 +120,17 @@ select relname from pg_locks l, pg_class c lock_view6 (2 rows) +ROLLBACK; +-- detecting infinite recursions in view definitions +CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3; +BEGIN TRANSACTION; +LOCK TABLE lock_view2 IN EXCLUSIVE MODE; +ERROR: infinite recursion detected in rules for relation "lock_view2" +ROLLBACK; +CREATE VIEW lock_view7 AS SELECT * from lock_view2; +BEGIN TRANSACTION; +LOCK TABLE lock_view7 IN EXCLUSIVE MODE; +ERROR: infinite recursion detected in rules for relation "lock_view2" ROLLBACK; -- Verify that we can lock a table with inheritance children. CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1); @@ -142,11 +153,12 @@ RESET ROLE; -- -- Clean up -- +DROP VIEW lock_view7; DROP VIEW lock_view6; DROP VIEW lock_view5; DROP VIEW lock_view4; -DROP VIEW lock_view3; -DROP VIEW lock_view2; +DROP VIEW lock_view3 CASCADE; +NOTICE: drop cascades to view lock_view2 DROP VIEW lock_view1; DROP TABLE lock_tbl3; DROP TABLE lock_tbl2; diff --git a/src/test/regress/expected/lseg.out b/src/test/regress/expected/lseg.out index bba1f3ee807..7e878b55779 100644 --- a/src/test/regress/expected/lseg.out +++ b/src/test/regress/expected/lseg.out @@ -8,7 +8,10 @@ INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]'); INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)'); INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4'); INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); -INSERT INTO LSEG_TBL VALUES ('(11,22,33,44)'); +INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44))); +INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]'); -- vertical +INSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]'); -- horizontal +INSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]'); -- NaN -- bad values for parser testing INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)'); ERROR: invalid input syntax for type lseg: "(3asdf,2 ,3,4r2)" @@ -34,19 +37,8 @@ select * from LSEG_TBL; [(10,-10),(-3,-4)] [(-1000000,200),(300000,-40)] [(11,22),(33,44)] -(5 rows) - -SELECT * FROM LSEG_TBL WHERE s <= lseg '[(1,2),(3,4)]'; - s ---------------- - [(1,2),(3,4)] -(1 row) - -SELECT * FROM LSEG_TBL WHERE (s <-> lseg '[(1,2),(3,4)]') < 10; - s --------------------- - [(1,2),(3,4)] - [(0,0),(6,6)] - [(10,-10),(-3,-4)] -(3 rows) + [(-10,2),(-10,3)] + [(0,-20),(30,-20)] + [(NaN,1),(NaN,90)] +(8 rows) diff --git a/src/test/regress/expected/matview.out b/src/test/regress/expected/matview.out index 08cd4bea485..d0121a7b0b8 100644 --- a/src/test/regress/expected/matview.out +++ b/src/test/regress/expected/matview.out @@ -311,12 +311,12 @@ SELECT type, m.totamt AS mtot, v.totamt AS vtot FROM mvtest_tm m LEFT JOIN mvtes DROP TABLE mvtest_t; ERROR: cannot drop table mvtest_t because other objects depend on it DETAIL: view mvtest_tv depends on table mvtest_t +materialized view mvtest_mvschema.mvtest_tvm depends on view mvtest_tv +materialized view mvtest_tvmm depends on materialized view mvtest_mvschema.mvtest_tvm view mvtest_tvv depends on view mvtest_tv materialized view mvtest_tvvm depends on view mvtest_tvv view mvtest_tvvmv depends on materialized view mvtest_tvvm materialized view mvtest_bb depends on view mvtest_tvvmv -materialized view mvtest_mvschema.mvtest_tvm depends on view mvtest_tv -materialized view mvtest_tvmm depends on materialized view mvtest_mvschema.mvtest_tvm materialized view mvtest_tm depends on table mvtest_t materialized view mvtest_tmm depends on materialized view mvtest_tm HINT: Use DROP ... CASCADE to drop the dependent objects too. @@ -327,12 +327,12 @@ BEGIN; DROP TABLE mvtest_t CASCADE; NOTICE: drop cascades to 9 other objects DETAIL: drop cascades to view mvtest_tv +drop cascades to materialized view mvtest_mvschema.mvtest_tvm +drop cascades to materialized view mvtest_tvmm drop cascades to view mvtest_tvv drop cascades to materialized view mvtest_tvvm drop cascades to view mvtest_tvvmv drop cascades to materialized view mvtest_bb -drop cascades to materialized view mvtest_mvschema.mvtest_tvm -drop cascades to materialized view mvtest_tvmm drop cascades to materialized view mvtest_tm drop cascades to materialized view mvtest_tmm ROLLBACK; diff --git a/src/test/regress/expected/merge.out b/src/test/regress/expected/merge.out deleted file mode 100644 index 03e30ef5599..00000000000 --- a/src/test/regress/expected/merge.out +++ /dev/null @@ -1,1672 +0,0 @@ --- --- MERGE --- ---\set VERBOSITY verbose ---set debug_print_rewritten = true; ---set debug_print_parse = true; ---set debug_print_pretty = true; -CREATE USER merge_privs; -CREATE USER merge_no_privs; -DROP TABLE IF EXISTS target; -NOTICE: table "target" does not exist, skipping -DROP TABLE IF EXISTS source; -NOTICE: table "source" does not exist, skipping -CREATE TABLE target (tid integer, balance integer); -CREATE TABLE source (sid integer, delta integer); --no index -INSERT INTO target VALUES (1, 10); -INSERT INTO target VALUES (2, 20); -INSERT INTO target VALUES (3, 30); -SELECT t.ctid is not null as matched, t.*, s.* FROM source s FULL OUTER JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid; - matched | tid | balance | sid | delta ----------+-----+---------+-----+------- - t | 1 | 10 | | - t | 2 | 20 | | - t | 3 | 30 | | -(3 rows) - -ALTER TABLE target OWNER TO merge_privs; -ALTER TABLE source OWNER TO merge_privs; -CREATE TABLE target2 (tid integer, balance integer); -CREATE TABLE source2 (sid integer, delta integer); -ALTER TABLE target2 OWNER TO merge_no_privs; -ALTER TABLE source2 OWNER TO merge_no_privs; -GRANT INSERT ON target TO merge_no_privs; -SET SESSION AUTHORIZATION merge_privs; -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; - QUERY PLAN ------------------------------------------- - Merge on target t - -> Merge Join - Merge Cond: (t_1.tid = s.sid) - -> Sort - Sort Key: t_1.tid - -> Seq Scan on target t_1 - -> Sort - Sort Key: s.sid - -> Seq Scan on source s -(9 rows) - --- --- Errors --- -MERGE INTO target t RANDOMWORD -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -ERROR: syntax error at or near "RANDOMWORD" -LINE 1: MERGE INTO target t RANDOMWORD - ^ --- MATCHED/INSERT error -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - INSERT DEFAULT VALUES -; -ERROR: syntax error at or near "INSERT" -LINE 5: INSERT DEFAULT VALUES - ^ --- incorrectly specifying INTO target -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT INTO target DEFAULT VALUES -; -ERROR: syntax error at or near "INTO" -LINE 5: INSERT INTO target DEFAULT VALUES - ^ --- Multiple VALUES clause -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (1,1), (2,2); -ERROR: syntax error at or near "," -LINE 5: INSERT VALUES (1,1), (2,2); - ^ -; --- SELECT query for INSERT -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT SELECT (1, 1); -ERROR: syntax error at or near "SELECT" -LINE 5: INSERT SELECT (1, 1); - ^ -; --- NOT MATCHED/UPDATE -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - UPDATE SET balance = 0 -; -ERROR: syntax error at or near "UPDATE" -LINE 5: UPDATE SET balance = 0 - ^ --- UPDATE tablename -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE target SET balance = 0 -; -ERROR: syntax error at or near "target" -LINE 5: UPDATE target SET balance = 0 - ^ --- unsupported relation types --- view -CREATE VIEW tv AS SELECT * FROM target; -MERGE INTO tv t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -ERROR: MERGE is not supported for this relation type -DROP VIEW tv; --- materialized view -CREATE MATERIALIZED VIEW mv AS SELECT * FROM target; -MERGE INTO mv t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -ERROR: MERGE is not supported for this relation type -DROP MATERIALIZED VIEW mv; --- inherited table -CREATE TABLE inhp (tid int, balance int); -CREATE TABLE child1() INHERITS (inhp); -CREATE TABLE child2() INHERITS (child1); -MERGE INTO inhp t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -ERROR: MERGE is not supported for relations with inheritance -MERGE INTO child1 t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -ERROR: MERGE is not supported for relations with inheritance --- this should be ok -MERGE INTO child2 t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -DROP TABLE inhp, child1, child2; --- permissions -MERGE INTO target -USING source2 -ON target.tid = source2.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -ERROR: permission denied for table source2 -GRANT INSERT ON target TO merge_no_privs; -SET SESSION AUTHORIZATION merge_no_privs; -MERGE INTO target -USING source2 -ON target.tid = source2.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -ERROR: permission denied for table target -GRANT UPDATE ON target2 TO merge_privs; -SET SESSION AUTHORIZATION merge_privs; -MERGE INTO target2 -USING source -ON target2.tid = source.sid -WHEN MATCHED THEN - DELETE -; -ERROR: permission denied for table target2 -MERGE INTO target2 -USING source -ON target2.tid = source.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -ERROR: permission denied for table target2 --- check if the target can be accessed from source relation subquery; we should --- not be able to do so -MERGE INTO target t -USING (SELECT * FROM source WHERE t.tid > sid) s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -ERROR: invalid reference to FROM-clause entry for table "t" -LINE 2: USING (SELECT * FROM source WHERE t.tid > sid) s - ^ -HINT: There is an entry for table "t", but it cannot be referenced from this part of the query. --- --- initial tests --- --- zero rows in source has no effect -MERGE INTO target -USING source -ON target.tid = source.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -ROLLBACK; --- insert some non-matching source rows to work from -INSERT INTO source VALUES (4, 40); -SELECT * FROM source ORDER BY sid; - sid | delta ------+------- - 4 | 40 -(1 row) - -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - DO NOTHING -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - | -(4 rows) - -ROLLBACK; --- index plans -INSERT INTO target SELECT generate_series(1000,2500), 0; -ALTER TABLE target ADD PRIMARY KEY (tid); -ANALYZE target; -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; - QUERY PLAN ------------------------------------------- - Merge on target t - -> Hash Join - Hash Cond: (s.sid = t_1.tid) - -> Seq Scan on source s - -> Hash - -> Seq Scan on target t_1 -(6 rows) - -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; - QUERY PLAN ------------------------------------------- - Merge on target t - -> Hash Join - Hash Cond: (s.sid = t_1.tid) - -> Seq Scan on source s - -> Hash - -> Seq Scan on target t_1 -(6 rows) - -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, NULL); - QUERY PLAN ------------------------------------------- - Merge on target t - -> Hash Left Join - Hash Cond: (s.sid = t_1.tid) - -> Seq Scan on source s - -> Hash - -> Seq Scan on target t_1 -(6 rows) - -; -DELETE FROM target WHERE tid > 100; -ANALYZE target; --- insert some matching source rows to work from -INSERT INTO source VALUES (2, 5); -INSERT INTO source VALUES (3, 20); -SELECT * FROM source ORDER BY sid; - sid | delta ------+------- - 2 | 5 - 3 | 20 - 4 | 40 -(3 rows) - -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - --- equivalent of an UPDATE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 0 - 3 | 0 -(3 rows) - -ROLLBACK; --- equivalent of a DELETE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 -(1 row) - -ROLLBACK; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, NULL) -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | -(4 rows) - -ROLLBACK; --- duplicate source row causes multiple target row update ERROR -INSERT INTO source VALUES (2, 5); -SELECT * FROM source ORDER BY sid; - sid | delta ------+------- - 2 | 5 - 2 | 5 - 3 | 20 - 4 | 40 -(4 rows) - -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -ERROR: MERGE command cannot affect row a second time -HINT: Ensure that not more than one source row matches any one target row -ROLLBACK; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -ERROR: MERGE command cannot affect row a second time -HINT: Ensure that not more than one source row matches any one target row -ROLLBACK; --- correct source data -DELETE FROM source WHERE sid = 2; -INSERT INTO source VALUES (2, 5); -SELECT * FROM source ORDER BY sid; - sid | delta ------+------- - 2 | 5 - 3 | 20 - 4 | 40 -(3 rows) - -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - --- remove constraints -alter table target drop CONSTRAINT target_pkey; -alter table target alter column tid drop not null; --- multiple actions -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, 4) -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 0 - 3 | 0 - 4 | 4 -(4 rows) - -ROLLBACK; --- should be equivalent -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -WHEN NOT MATCHED THEN - INSERT VALUES (4, 4); -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 0 - 3 | 0 - 4 | 4 -(4 rows) - -ROLLBACK; --- column references --- do a simple equivalent of an UPDATE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance + s.delta -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 25 - 3 | 50 -(3 rows) - -ROLLBACK; --- do a simple equivalent of an INSERT SELECT -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | 40 -(4 rows) - -ROLLBACK; --- and again with explicitly identified column list -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | 40 -(4 rows) - -ROLLBACK; --- and again with a subtle error: referring to non-existent target row for NOT MATCHED -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (t.tid, s.delta) -; -ERROR: invalid reference to FROM-clause entry for table "t" -LINE 5: INSERT (tid, balance) VALUES (t.tid, s.delta) - ^ -HINT: There is an entry for table "t", but it cannot be referenced from this part of the query. --- and again with a constant ON clause -BEGIN; -MERGE INTO target t -USING source AS s -ON (SELECT true) -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (t.tid, s.delta) -; -ERROR: invalid reference to FROM-clause entry for table "t" -LINE 5: INSERT (tid, balance) VALUES (t.tid, s.delta) - ^ -HINT: There is an entry for table "t", but it cannot be referenced from this part of the query. -SELECT * FROM target ORDER BY tid; -ERROR: current transaction is aborted, commands ignored until end of transaction block -ROLLBACK; --- now the classic UPSERT -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance + s.delta -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 25 - 3 | 50 - 4 | 40 -(4 rows) - -ROLLBACK; --- unreachable WHEN clause should ERROR -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */ - DELETE -WHEN MATCHED AND s.delta > 0 THEN - UPDATE SET balance = t.balance - s.delta -; -ERROR: unreachable WHEN clause specified after unconditional WHEN clause -ROLLBACK; --- conditional WHEN clause -CREATE TABLE wq_target (tid integer not null, balance integer DEFAULT -1); -CREATE TABLE wq_source (balance integer, sid integer); -INSERT INTO wq_source (sid, balance) VALUES (1, 100); -BEGIN; --- try a simple INSERT with default values first -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | -1 -(1 row) - -ROLLBACK; --- this time with a FALSE condition -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND FALSE THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - tid | balance ------+--------- -(0 rows) - --- this time with an actual condition which returns false -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance <> 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - tid | balance ------+--------- -(0 rows) - -BEGIN; --- and now with a condition which returns true -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | -1 -(1 row) - -ROLLBACK; --- conditions in the NOT MATCHED clause can only refer to source columns -BEGIN; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND t.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -ERROR: invalid reference to FROM-clause entry for table "t" -LINE 3: WHEN NOT MATCHED AND t.balance = 100 THEN - ^ -HINT: There is an entry for table "t", but it cannot be referenced from this part of the query. -SELECT * FROM wq_target; -ERROR: current transaction is aborted, commands ignored until end of transaction block -ROLLBACK; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | -1 -(1 row) - --- conditions in MATCHED clause can refer to both source and target -SELECT * FROM wq_source; - balance | sid ----------+----- - 100 | 1 -(1 row) - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND s.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 99 -(1 row) - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 99 -(1 row) - --- check if AND works -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 AND s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 99 -(1 row) - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 AND s.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 199 -(1 row) - --- check if OR works -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 OR s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 199 -(1 row) - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 199 OR s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 299 -(1 row) - --- check if subqueries work in the conditions? -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance > (SELECT max(balance) FROM target) THEN - UPDATE SET balance = t.balance + s.balance; --- check if we can access system columns in the conditions -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.xmin = t.xmax THEN - UPDATE SET balance = t.balance + s.balance; -ERROR: system column "xmin" reference in WHEN AND condition is invalid -LINE 3: WHEN MATCHED AND t.xmin = t.xmax THEN - ^ -ALTER TABLE wq_target SET WITH OIDS; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 399 -(1 row) - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.oid >= 0 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - tid | balance ------+--------- - 1 | 499 -(1 row) - --- test preventing WHEN AND conditions from writing to the database -create or replace function merge_when_and_write() returns boolean -language plpgsql as -$$ -BEGIN - INSERT INTO target VALUES (100, 100); - RETURN TRUE; -END; -$$; -BEGIN; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND (merge_when_and_write()) THEN - UPDATE SET balance = t.balance + s.balance; -ROLLBACK; -drop function merge_when_and_write(); -DROP TABLE wq_target, wq_source; --- test triggers -create or replace function merge_trigfunc () returns trigger -language plpgsql as -$$ -BEGIN - RAISE NOTICE '% % % trigger', TG_WHEN, TG_OP, TG_LEVEL; - IF (TG_WHEN = 'BEFORE' AND TG_LEVEL = 'ROW') THEN - IF (TG_OP = 'DELETE') THEN - RETURN OLD; - ELSE - RETURN NEW; - END IF; - ELSE - RETURN NULL; - END IF; -END; -$$; -CREATE TRIGGER merge_bsi BEFORE INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bsu BEFORE UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bsd BEFORE DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asi AFTER INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asu AFTER UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asd AFTER DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); --- now the classic UPSERT, with a DELETE -BEGIN; -UPDATE target SET balance = 0 WHERE tid = 3; -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED AND t.balance > s.delta THEN - UPDATE SET balance = t.balance - s.delta -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE DELETE STATEMENT trigger -NOTICE: BEFORE INSERT ROW trigger -NOTICE: BEFORE DELETE ROW trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER INSERT ROW trigger -NOTICE: AFTER DELETE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER DELETE STATEMENT trigger -NOTICE: AFTER UPDATE STATEMENT trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 15 - 4 | 40 -(3 rows) - -ROLLBACK; --- test from PL/pgSQL --- make sure MERGE INTO isn't interpreted to mean returning variables like SELECT INTO -BEGIN; -DO LANGUAGE plpgsql $$ -BEGIN -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED AND t.balance > s.delta THEN - UPDATE SET balance = t.balance - s.delta -; -END; -$$; -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger -ROLLBACK; ---source constants -BEGIN; -MERGE INTO target t -USING (SELECT 9 AS sid, 57 AS delta) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE INSERT ROW trigger -NOTICE: AFTER INSERT ROW trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 9 | 57 -(4 rows) - -ROLLBACK; ---source query -BEGIN; -MERGE INTO target t -USING (SELECT sid, delta FROM source WHERE delta > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE INSERT ROW trigger -NOTICE: AFTER INSERT ROW trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | 40 -(4 rows) - -ROLLBACK; -BEGIN; -MERGE INTO target t -USING (SELECT sid, delta as newname FROM source WHERE delta > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.newname) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE INSERT ROW trigger -NOTICE: AFTER INSERT ROW trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | 40 -(4 rows) - -ROLLBACK; ---self-merge -BEGIN; -MERGE INTO target t1 -USING target t2 -ON t1.tid = t2.tid -WHEN MATCHED THEN - UPDATE SET balance = t1.balance + t2.balance -WHEN NOT MATCHED THEN - INSERT VALUES (t2.tid, t2.balance) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 20 - 2 | 40 - 3 | 60 -(3 rows) - -ROLLBACK; -BEGIN; -MERGE INTO target t -USING (SELECT tid as sid, balance as delta FROM target WHERE balance > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - -ROLLBACK; -BEGIN; -MERGE INTO target t -USING -(SELECT sid, max(delta) AS delta - FROM source - GROUP BY sid - HAVING count(*) = 1 - ORDER BY sid ASC) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -NOTICE: BEFORE INSERT STATEMENT trigger -NOTICE: BEFORE INSERT ROW trigger -NOTICE: AFTER INSERT ROW trigger -NOTICE: AFTER INSERT STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 30 - 4 | 40 -(4 rows) - -ROLLBACK; --- plpgsql parameters and results -BEGIN; -CREATE FUNCTION merge_func (p_id integer, p_bal integer) -RETURNS INTEGER -LANGUAGE plpgsql -AS $$ -DECLARE - result integer; -BEGIN -MERGE INTO target t -USING (SELECT p_id AS sid) AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance - p_bal -; -IF FOUND THEN - GET DIAGNOSTICS result := ROW_COUNT; -END IF; -RETURN result; -END; -$$; -SELECT merge_func(3, 4); -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger - merge_func ------------- - 1 -(1 row) - -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 10 - 2 | 20 - 3 | 26 -(3 rows) - -ROLLBACK; --- PREPARE -BEGIN; -prepare foom as merge into target t using (select 1 as sid) s on (t.tid = s.sid) when matched then update set balance = 1; -execute foom; -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 1 - 2 | 20 - 3 | 30 -(3 rows) - -ROLLBACK; -BEGIN; -PREPARE foom2 (integer, integer) AS -MERGE INTO target t -USING (SELECT 1) s -ON t.tid = $1 -WHEN MATCHED THEN -UPDATE SET balance = $2; ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -execute foom2 (1, 1); -NOTICE: BEFORE UPDATE STATEMENT trigger -NOTICE: BEFORE UPDATE ROW trigger -NOTICE: AFTER UPDATE ROW trigger -NOTICE: AFTER UPDATE STATEMENT trigger -SELECT * FROM target ORDER BY tid; - tid | balance ------+--------- - 1 | 1 - 2 | 20 - 3 | 30 -(3 rows) - -ROLLBACK; --- subqueries in source relation -CREATE TABLE sq_target (tid integer NOT NULL, balance integer); -CREATE TABLE sq_source (delta integer, sid integer, balance integer DEFAULT 0); -INSERT INTO sq_target(tid, balance) VALUES (1,100), (2,200), (3,300); -INSERT INTO sq_source(sid, delta) VALUES (1,10), (2,20), (4,40); -BEGIN; -MERGE INTO sq_target t -USING (SELECT * FROM sq_source) s -ON tid = sid -WHEN MATCHED AND t.balance > delta THEN - UPDATE SET balance = t.balance + delta; -SELECT * FROM sq_target; - tid | balance ------+--------- - 3 | 300 - 1 | 110 - 2 | 220 -(3 rows) - -ROLLBACK; --- try a view -CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2; -BEGIN; -MERGE INTO sq_target -USING v -ON tid = sid -WHEN MATCHED THEN - UPDATE SET balance = v.balance + delta; -SELECT * FROM sq_target; - tid | balance ------+--------- - 2 | 200 - 3 | 300 - 1 | 10 -(3 rows) - -ROLLBACK; --- ambiguous reference to a column -BEGIN; -MERGE INTO sq_target -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE; -ERROR: column reference "balance" is ambiguous -LINE 5: UPDATE SET balance = balance + delta - ^ -ROLLBACK; -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE; -SELECT * FROM sq_target; - tid | balance ------+--------- - 2 | 200 - 3 | 300 - -1 | -11 -(3 rows) - -ROLLBACK; --- CTEs -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -WITH targq AS ( - SELECT * FROM v -) -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE -; -ROLLBACK; --- RETURNING -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE -RETURNING * -; -ERROR: syntax error at or near "RETURNING" -LINE 10: RETURNING * - ^ -ROLLBACK; --- EXPLAIN -CREATE TABLE ex_mtarget (a int, b int); -CREATE TABLE ex_msource (a int, b int); -INSERT INTO ex_mtarget SELECT i, i*10 FROM generate_series(1,100,2) i; -INSERT INTO ex_msource SELECT i, i*10 FROM generate_series(1,100,1) i; --- only updates ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = t.b + 1; --- only updates to selected tuples ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1; --- updates + deletes ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1 -WHEN MATCHED AND t.a >= 10 AND t.a <= 20 THEN - DELETE; --- only inserts ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN NOT MATCHED AND s.a < 10 THEN - INSERT VALUES (a, b); --- all three ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1 -WHEN MATCHED AND t.a >= 30 AND t.a <= 40 THEN - DELETE -WHEN NOT MATCHED AND s.a < 20 THEN - INSERT VALUES (a, b); -DROP TABLE ex_msource, ex_mtarget; --- Subqueries -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED THEN - UPDATE SET balance = (SELECT count(*) FROM sq_target) -; -SELECT * FROM sq_target WHERE tid = 1; - tid | balance ------+--------- - 1 | 3 -(1 row) - -ROLLBACK; -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND (SELECT count(*) > 0 FROM sq_target) THEN - UPDATE SET balance = 42 -; -SELECT * FROM sq_target WHERE tid = 1; - tid | balance ------+--------- - 1 | 42 -(1 row) - -ROLLBACK; -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid AND (SELECT count(*) > 0 FROM sq_target) -WHEN MATCHED THEN - UPDATE SET balance = 42 -; -SELECT * FROM sq_target WHERE tid = 1; - tid | balance ------+--------- - 1 | 42 -(1 row) - -ROLLBACK; -DROP TABLE sq_target, sq_source CASCADE; -NOTICE: drop cascades to view v -CREATE TABLE pa_target (tid integer, balance float, val text) - PARTITION BY LIST (tid); -CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1,4); -CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2,5,6); -CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3,8,9); -CREATE TABLE part4 PARTITION OF pa_target DEFAULT; -CREATE TABLE pa_source (sid integer, delta float); --- insert many rows to the source table -INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,14,2) AS id; --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 1 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 3 | 330 | initial updated by merge - 4 | 40 | inserted by merge - 5 | 550 | initial updated by merge - 6 | 60 | inserted by merge - 7 | 770 | initial updated by merge - 8 | 80 | inserted by merge - 9 | 990 | initial updated by merge - 10 | 100 | inserted by merge - 11 | 1210 | initial updated by merge - 12 | 120 | inserted by merge - 13 | 1430 | initial updated by merge - 14 | 140 | inserted by merge -(14 rows) - -ROLLBACK; --- same with a constant qual -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid AND tid = 1 - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 1 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 3 | 30 | inserted by merge - 3 | 300 | initial - 4 | 40 | inserted by merge - 5 | 500 | initial - 5 | 50 | inserted by merge - 6 | 60 | inserted by merge - 7 | 700 | initial - 7 | 70 | inserted by merge - 8 | 80 | inserted by merge - 9 | 90 | inserted by merge - 9 | 900 | initial - 10 | 100 | inserted by merge - 11 | 1100 | initial - 11 | 110 | inserted by merge - 12 | 120 | inserted by merge - 13 | 1300 | initial - 13 | 130 | inserted by merge - 14 | 140 | inserted by merge -(20 rows) - -ROLLBACK; --- try updating the partition key column -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 2 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 4 | 40 | inserted by merge - 4 | 330 | initial updated by merge - 6 | 550 | initial updated by merge - 6 | 60 | inserted by merge - 8 | 80 | inserted by merge - 8 | 770 | initial updated by merge - 10 | 990 | initial updated by merge - 10 | 100 | inserted by merge - 12 | 1210 | initial updated by merge - 12 | 120 | inserted by merge - 14 | 1430 | initial updated by merge - 14 | 140 | inserted by merge -(14 rows) - -ROLLBACK; -DROP TABLE pa_target CASCADE; --- The target table is partitioned in the same way, but this time by attaching --- partitions which have columns in different order, dropped columns etc. -CREATE TABLE pa_target (tid integer, balance float, val text) - PARTITION BY LIST (tid); -CREATE TABLE part1 (tid integer, balance float, val text); -CREATE TABLE part2 (balance float, tid integer, val text); -CREATE TABLE part3 (tid integer, balance float, val text); -CREATE TABLE part4 (extraid text, tid integer, balance float, val text); -ALTER TABLE part4 DROP COLUMN extraid; -ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4); -ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6); -ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3,8,9); -ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT; --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,14,2) AS id; --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 1 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 3 | 330 | initial updated by merge - 4 | 40 | inserted by merge - 5 | 550 | initial updated by merge - 6 | 60 | inserted by merge - 7 | 770 | initial updated by merge - 8 | 80 | inserted by merge - 9 | 990 | initial updated by merge - 10 | 100 | inserted by merge - 11 | 1210 | initial updated by merge - 12 | 120 | inserted by merge - 13 | 1430 | initial updated by merge - 14 | 140 | inserted by merge -(14 rows) - -ROLLBACK; --- same with a constant qual -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid AND tid = 1 - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 1 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 3 | 30 | inserted by merge - 3 | 300 | initial - 4 | 40 | inserted by merge - 5 | 500 | initial - 5 | 50 | inserted by merge - 6 | 60 | inserted by merge - 7 | 700 | initial - 7 | 70 | inserted by merge - 8 | 80 | inserted by merge - 9 | 90 | inserted by merge - 9 | 900 | initial - 10 | 100 | inserted by merge - 11 | 1100 | initial - 11 | 110 | inserted by merge - 12 | 120 | inserted by merge - 13 | 1300 | initial - 13 | 130 | inserted by merge - 14 | 140 | inserted by merge -(20 rows) - -ROLLBACK; --- try updating the partition key column -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - tid | balance | val ------+---------+-------------------------- - 2 | 110 | initial updated by merge - 2 | 20 | inserted by merge - 4 | 40 | inserted by merge - 4 | 330 | initial updated by merge - 6 | 550 | initial updated by merge - 6 | 60 | inserted by merge - 8 | 80 | inserted by merge - 8 | 770 | initial updated by merge - 10 | 990 | initial updated by merge - 10 | 100 | inserted by merge - 12 | 1210 | initial updated by merge - 12 | 120 | inserted by merge - 14 | 1430 | initial updated by merge - 14 | 140 | inserted by merge -(14 rows) - -ROLLBACK; -DROP TABLE pa_source; -DROP TABLE pa_target CASCADE; --- Sub-partitionin -CREATE TABLE pa_target (logts timestamp, tid integer, balance float, val text) - PARTITION BY RANGE (logts); -CREATE TABLE part_m01 PARTITION OF pa_target - FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') - PARTITION BY LIST (tid); -CREATE TABLE part_m01_odd PARTITION OF part_m01 - FOR VALUES IN (1,3,5,7,9); -CREATE TABLE part_m01_even PARTITION OF part_m01 - FOR VALUES IN (2,4,6,8); -CREATE TABLE part_m02 PARTITION OF pa_target - FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') - PARTITION BY LIST (tid); -CREATE TABLE part_m02_odd PARTITION OF part_m02 - FOR VALUES IN (1,3,5,7,9); -CREATE TABLE part_m02_even PARTITION OF part_m02 - FOR VALUES IN (2,4,6,8); -CREATE TABLE pa_source (sid integer, delta float); --- insert many rows to the source table -INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1,9,3) AS id; -INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2,9,3) AS id; --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING (SELECT '2017-01-15' AS slogts, * FROM pa_source WHERE sid < 10) s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (slogts::timestamp, sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; - logts | tid | balance | val ---------------------------+-----+---------+-------------------------- - Tue Jan 31 00:00:00 2017 | 1 | 110 | initial updated by merge - Tue Feb 28 00:00:00 2017 | 2 | 220 | initial updated by merge - Sun Jan 15 00:00:00 2017 | 3 | 30 | inserted by merge - Tue Jan 31 00:00:00 2017 | 4 | 440 | initial updated by merge - Tue Feb 28 00:00:00 2017 | 5 | 550 | initial updated by merge - Sun Jan 15 00:00:00 2017 | 6 | 60 | inserted by merge - Tue Jan 31 00:00:00 2017 | 7 | 770 | initial updated by merge - Tue Feb 28 00:00:00 2017 | 8 | 880 | initial updated by merge - Sun Jan 15 00:00:00 2017 | 9 | 90 | inserted by merge -(9 rows) - -ROLLBACK; -DROP TABLE pa_source; -DROP TABLE pa_target CASCADE; --- some complex joins on the source side -CREATE TABLE cj_target (tid integer, balance float, val text); -CREATE TABLE cj_source1 (sid1 integer, scat integer, delta integer); -CREATE TABLE cj_source2 (sid2 integer, sval text); -INSERT INTO cj_source1 VALUES (1, 10, 100); -INSERT INTO cj_source1 VALUES (1, 20, 200); -INSERT INTO cj_source1 VALUES (2, 20, 300); -INSERT INTO cj_source1 VALUES (3, 10, 400); -INSERT INTO cj_source2 VALUES (1, 'initial source2'); -INSERT INTO cj_source2 VALUES (2, 'initial source2'); -INSERT INTO cj_source2 VALUES (3, 'initial source2'); --- source relation is an unalised join -MERGE INTO cj_target t -USING cj_source1 s1 - INNER JOIN cj_source2 s2 ON sid1 = sid2 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid1, delta, sval); --- try accessing columns from either side of the source join -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid2, delta, sval) -WHEN MATCHED THEN - DELETE; --- some simple expressions in INSERT targetlist -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid2, delta + scat, sval) -WHEN MATCHED THEN - UPDATE SET val = val || ' updated by merge'; -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 -ON t.tid = sid1 -WHEN MATCHED THEN - UPDATE SET val = val || ' ' || delta::text; -SELECT * FROM cj_target; - tid | balance | val ------+---------+---------------------------------- - 3 | 400 | initial source2 updated by merge - 1 | 220 | initial source2 200 - 1 | 110 | initial source2 200 - 2 | 320 | initial source2 300 -(4 rows) - -ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid; -ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid; -TRUNCATE cj_target; -MERGE INTO cj_target t -USING cj_source1 s1 - INNER JOIN cj_source2 s2 ON s1.sid = s2.sid -ON t.tid = s1.sid -WHEN NOT MATCHED THEN - INSERT VALUES (s2.sid, delta, sval); -DROP TABLE cj_source2, cj_source1, cj_target; --- Function scans -CREATE TABLE fs_target (a int, b int, c text); -MERGE INTO fs_target t -USING generate_series(1,100,1) AS id -ON t.a = id -WHEN MATCHED THEN - UPDATE SET b = b + id -WHEN NOT MATCHED THEN - INSERT VALUES (id, -1); -MERGE INTO fs_target t -USING generate_series(1,100,2) AS id -ON t.a = id -WHEN MATCHED THEN - UPDATE SET b = b + id, c = 'updated '|| id.*::text -WHEN NOT MATCHED THEN - INSERT VALUES (id, -1, 'inserted ' || id.*::text); -SELECT count(*) FROM fs_target; - count -------- - 100 -(1 row) - -DROP TABLE fs_target; --- SERIALIZABLE test --- handled in isolation tests --- prepare -RESET SESSION AUTHORIZATION; -DROP TABLE target, target2; -DROP TABLE source, source2; -DROP FUNCTION merge_trigfunc(); -DROP USER merge_privs; -DROP USER merge_no_privs; diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 130a0e4be3a..0879c885eb3 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -133,3 +133,63 @@ ERROR: function num_nulls() does not exist LINE 1: SELECT num_nulls(); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. +-- +-- Test adding a support function to a subject function +-- +CREATE FUNCTION my_int_eq(int, int) RETURNS bool + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$int4eq$$; +-- By default, planner does not think that's selective +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + QUERY PLAN +---------------------------------------------- + Hash Join + Hash Cond: (b.unique1 = a.unique1) + -> Seq Scan on tenk1 b + -> Hash + -> Seq Scan on tenk1 a + Filter: my_int_eq(unique2, 42) +(6 rows) + +-- With support function that knows it's int4eq, we get a different plan +ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func; +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + QUERY PLAN +------------------------------------------------- + Nested Loop + -> Seq Scan on tenk1 a + Filter: my_int_eq(unique2, 42) + -> Index Scan using tenk1_unique1 on tenk1 b + Index Cond: (unique1 = a.unique1) +(5 rows) + +-- Also test non-default rowcount estimate +CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$generate_series_int4$$ + SUPPORT test_support_func; +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g; + QUERY PLAN +---------------------------------------- + Hash Join + Hash Cond: (g.g = a.unique1) + -> Function Scan on my_gen_series g + -> Hash + -> Seq Scan on tenk1 a +(5 rows) + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g; + QUERY PLAN +------------------------------------------------- + Nested Loop + -> Function Scan on my_gen_series g + -> Index Scan using tenk1_unique1 on tenk1 a + Index Cond: (unique1 = g.g) +(4 rows) + diff --git a/src/test/regress/expected/misc_sanity.out b/src/test/regress/expected/misc_sanity.out index 5aaae6c39fc..8538173ff8c 100644 --- a/src/test/regress/expected/misc_sanity.out +++ b/src/test/regress/expected/misc_sanity.out @@ -52,7 +52,10 @@ declare relnm text; begin for relnm, reloid, shared in select relname, oid, relisshared from pg_class - where relhasoids and oid < 16384 order by 1 + where EXISTS( + SELECT * FROM pg_attribute + WHERE attrelid = pg_class.oid AND attname = 'oid') + and relkind = 'r' and oid < 16384 order by 1 loop execute 'select min(oid) from ' || relnm into lowoid; continue when lowoid is null or lowoid >= 16384; @@ -71,8 +74,38 @@ loop end loop; end$$; NOTICE: pg_constraint contains unpinned initdb-created object(s) -NOTICE: pg_conversion contains unpinned initdb-created object(s) NOTICE: pg_database contains unpinned initdb-created object(s) NOTICE: pg_extension contains unpinned initdb-created object(s) NOTICE: pg_rewrite contains unpinned initdb-created object(s) NOTICE: pg_tablespace contains unpinned initdb-created object(s) +-- **************** pg_class **************** +-- Look for system tables with varlena columns but no toast table. All +-- system tables with toastable columns should have toast tables, with +-- the following exceptions: +-- 1. pg_class, pg_attribute, and pg_index, due to fear of recursive +-- dependencies as toast tables depend on them. +-- 2. pg_largeobject and pg_largeobject_metadata. Large object catalogs +-- and toast tables are mutually exclusive and large object data is handled +-- as user data by pg_upgrade, which would cause failures. +SELECT relname, attname, atttypid::regtype +FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid +WHERE c.oid < 16384 AND + reltoastrelid = 0 AND + relkind = 'r' AND + attstorage != 'p' +ORDER BY 1, 2; + relname | attname | atttypid +-------------------------+---------------+-------------- + pg_attribute | attacl | aclitem[] + pg_attribute | attfdwoptions | text[] + pg_attribute | attmissingval | anyarray + pg_attribute | attoptions | text[] + pg_class | relacl | aclitem[] + pg_class | reloptions | text[] + pg_class | relpartbound | pg_node_tree + pg_index | indexprs | pg_node_tree + pg_index | indpred | pg_node_tree + pg_largeobject | data | bytea + pg_largeobject_metadata | lomacl | aclitem[] +(11 rows) + diff --git a/src/test/regress/expected/money.out b/src/test/regress/expected/money.out index ab86595fc02..fc71a72fed3 100644 --- a/src/test/regress/expected/money.out +++ b/src/test/regress/expected/money.out @@ -1,6 +1,8 @@ -- -- MONEY -- +-- Note that we assume lc_monetary has been set to C. +-- CREATE TABLE money_data (m money); INSERT INTO money_data VALUES ('123'); SELECT * FROM money_data; @@ -476,7 +478,7 @@ SELECT (-12345678901234567)::numeric::money; -$12,345,678,901,234,567.00 (1 row) --- Cast from money +-- Cast from money to numeric SELECT '12345678901234567'::money::numeric; numeric ---------------------- @@ -489,3 +491,15 @@ SELECT '-12345678901234567'::money::numeric; -12345678901234567.00 (1 row) +SELECT '92233720368547758.07'::money::numeric; + numeric +---------------------- + 92233720368547758.07 +(1 row) + +SELECT '-92233720368547758.08'::money::numeric; + numeric +----------------------- + -92233720368547758.08 +(1 row) + diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out index 17985e85401..1cb3c3bfab7 100644 --- a/src/test/regress/expected/numeric.out +++ b/src/test/regress/expected/numeric.out @@ -1664,6 +1664,37 @@ select 0.0 ^ 12.34; 0.0000000000000000 (1 row) +-- NaNs +select 'NaN'::numeric ^ 'NaN'::numeric; + ?column? +---------- + NaN +(1 row) + +select 'NaN'::numeric ^ 0; + ?column? +---------- + 1 +(1 row) + +select 'NaN'::numeric ^ 1; + ?column? +---------- + NaN +(1 row) + +select 0 ^ 'NaN'::numeric; + ?column? +---------- + NaN +(1 row) + +select 1 ^ 'NaN'::numeric; + ?column? +---------- + 1 +(1 row) + -- invalid inputs select 0.0 ^ (-12.34); ERROR: zero raised to a negative power is undefined diff --git a/src/test/regress/expected/numerology_1.out b/src/test/regress/expected/numerology_1.out deleted file mode 100644 index d404d9db681..00000000000 --- a/src/test/regress/expected/numerology_1.out +++ /dev/null @@ -1,136 +0,0 @@ --- --- NUMEROLOGY --- Test various combinations of numeric types and functions. --- --- --- Test implicit type conversions --- This fails for Postgres v6.1 (and earlier?) --- so let's try explicit conversions for now - tgl 97/05/07 --- -CREATE TABLE TEMP_FLOAT (f1 FLOAT8); -INSERT INTO TEMP_FLOAT (f1) - SELECT float8(f1) FROM INT4_TBL; -INSERT INTO TEMP_FLOAT (f1) - SELECT float8(f1) FROM INT2_TBL; -SELECT '' AS ten, f1 FROM TEMP_FLOAT - ORDER BY f1; - ten | f1 ------+------------- - | -2147483647 - | -123456 - | -32767 - | -1234 - | 0 - | 0 - | 1234 - | 32767 - | 123456 - | 2147483647 -(10 rows) - --- int4 -CREATE TABLE TEMP_INT4 (f1 INT4); -INSERT INTO TEMP_INT4 (f1) - SELECT int4(f1) FROM FLOAT8_TBL - WHERE (f1 > -2147483647) AND (f1 < 2147483647); -INSERT INTO TEMP_INT4 (f1) - SELECT int4(f1) FROM INT2_TBL; -SELECT '' AS nine, f1 FROM TEMP_INT4 - ORDER BY f1; - nine | f1 -------+-------- - | -32767 - | -1234 - | -1004 - | -35 - | 0 - | 0 - | 0 - | 1234 - | 32767 -(9 rows) - --- int2 -CREATE TABLE TEMP_INT2 (f1 INT2); -INSERT INTO TEMP_INT2 (f1) - SELECT int2(f1) FROM FLOAT8_TBL - WHERE (f1 >= -32767) AND (f1 <= 32767); -INSERT INTO TEMP_INT2 (f1) - SELECT int2(f1) FROM INT4_TBL - WHERE (f1 >= -32767) AND (f1 <= 32767); -SELECT '' AS five, f1 FROM TEMP_INT2 - ORDER BY f1; - five | f1 -------+------- - | -1004 - | -35 - | 0 - | 0 - | 0 -(5 rows) - --- --- Group-by combinations --- -CREATE TABLE TEMP_GROUP (f1 INT4, f2 INT4, f3 FLOAT8); -INSERT INTO TEMP_GROUP - SELECT 1, (- i.f1), (- f.f1) - FROM INT4_TBL i, FLOAT8_TBL f; -INSERT INTO TEMP_GROUP - SELECT 2, i.f1, f.f1 - FROM INT4_TBL i, FLOAT8_TBL f; -SELECT DISTINCT f1 AS two FROM TEMP_GROUP ORDER BY 1; - two ------ - 1 - 2 -(2 rows) - -SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, max_float, min_float; - two | max_float | min_float ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | 0 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - --- GROUP BY a result column name is not legal per SQL92, but we accept it --- anyway (if the name is not the name of any column exposed by FROM). -SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float - FROM TEMP_GROUP - GROUP BY two - ORDER BY two, max_float, min_float; - two | max_float | min_float ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | 0 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - -SELECT f1 AS two, (max(f3) + 1) AS max_plus_1, (min(f3) - 1) AS min_minus_1 - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, min_minus_1; - two | max_plus_1 | min_minus_1 ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | -1 - 2 | 1 | -1.2345678901234e+200 -(2 rows) - -SELECT f1 AS two, - max(f2) + min(f2) AS max_plus_min, - min(f3) - 1 AS min_minus_1 - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, min_minus_1; - two | max_plus_min | min_minus_1 ------+--------------+----------------------- - 1 | 0 | -1 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - -DROP TABLE TEMP_INT2; -DROP TABLE TEMP_INT4; -DROP TABLE TEMP_FLOAT; -DROP TABLE TEMP_GROUP; diff --git a/src/test/regress/expected/object_address.out b/src/test/regress/expected/object_address.out index bfd9d54c119..d6d14701563 100644 --- a/src/test/regress/expected/object_address.out +++ b/src/test/regress/expected/object_address.out @@ -19,6 +19,9 @@ CREATE TEXT SEARCH PARSER addr_ts_prs CREATE TABLE addr_nsp.gentable ( a serial primary key CONSTRAINT a_chk CHECK (a > 0), b text DEFAULT 'hello'); +CREATE TABLE addr_nsp.parttable ( + a int PRIMARY KEY +) PARTITION BY RANGE (a); CREATE VIEW addr_nsp.genview AS SELECT * from addr_nsp.gentable; CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable; CREATE TYPE addr_nsp.gencomptype AS (a int); @@ -34,11 +37,16 @@ CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw; CREATE USER MAPPING FOR regress_addr_user SERVER "integer"; ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regress_addr_user; ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM regress_addr_user; +-- this transform would be quite unsafe to leave lying around, +-- except that the SQL language pays no attention to transforms: CREATE TRANSFORM FOR int LANGUAGE SQL ( - FROM SQL WITH FUNCTION varchar_transform(internal), + FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; -CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); +RESET client_min_messages; +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; -- test some error cases @@ -368,7 +376,9 @@ ERROR: name list length must be exactly 1 -- test successful cases WITH objects (type, name, args) AS (VALUES ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]), + ('table', '{addr_nsp, parttable}'::text[], '{}'::text[]), ('index', '{addr_nsp, gentable_pkey}', '{}'), + ('index', '{addr_nsp, parttable_pkey}', '{}'), ('sequence', '{addr_nsp, gentable_a_seq}', '{}'), -- toast table ('view', '{addr_nsp, genview}', '{}'), @@ -387,7 +397,7 @@ WITH objects (type, name, args) AS (VALUES ('collation', '{default}', '{}'), ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), - ('conversion', '{pg_catalog, ascii_to_mic}', '{}'), + ('conversion', '{pg_catalog, koi8_r_to_mic}', '{}'), ('default value', '{addr_nsp, gentable, b}', '{}'), ('language', '{plpgsql}', '{}'), -- large object @@ -418,7 +428,7 @@ WITH objects (type, name, args) AS (VALUES ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), - ('subscription', '{addr_sub}', '{}'), + ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') ) SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, @@ -444,6 +454,8 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, table | addr_nsp | gentable | addr_nsp.gentable | t table column | addr_nsp | gentable | addr_nsp.gentable.b | t index | addr_nsp | gentable_pkey | addr_nsp.gentable_pkey | t + table | addr_nsp | parttable | addr_nsp.parttable | t + index | addr_nsp | parttable_pkey | addr_nsp.parttable_pkey | t view | addr_nsp | genview | addr_nsp.genview | t materialized view | addr_nsp | genmatview | addr_nsp.genmatview | t foreign table | addr_nsp | genftable | addr_nsp.genftable | t @@ -459,7 +471,7 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, cast | | | (bigint AS integer) | t table constraint | addr_nsp | | a_chk on addr_nsp.gentable | t domain constraint | addr_nsp | | domconstr on addr_nsp.gendomain | t - conversion | pg_catalog | ascii_to_mic | pg_catalog.ascii_to_mic | t + conversion | pg_catalog | koi8_r_to_mic | pg_catalog.koi8_r_to_mic | t language | | plpgsql | plpgsql | t schema | | addr_nsp | addr_nsp | t operator class | pg_catalog | int4_ops | pg_catalog.int4_ops USING btree | t @@ -475,20 +487,37 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, text search parser | addr_nsp | addr_ts_prs | addr_nsp.addr_ts_prs | t text search configuration | addr_nsp | addr_ts_conf | addr_nsp.addr_ts_conf | t text search template | addr_nsp | addr_ts_temp | addr_nsp.addr_ts_temp | t - subscription | | addr_sub | addr_sub | t + subscription | | regress_addr_sub | regress_addr_sub | t publication | | addr_pub | addr_pub | t - publication relation | | | gentable in publication addr_pub | t -(47 rows) + publication relation | | | addr_nsp.gentable in publication addr_pub | t +(49 rows) --- --- Cleanup resources --- -\set VERBOSITY terse \\ -- suppress cascade details DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; NOTICE: drop cascades to 4 other objects +DETAIL: drop cascades to server addr_fserv +drop cascades to foreign table genftable +drop cascades to server integer +drop cascades to user mapping for regress_addr_user on server integer DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub; +DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; -NOTICE: drop cascades to 13 other objects +NOTICE: drop cascades to 14 other objects +DETAIL: drop cascades to text search dictionary addr_ts_dict +drop cascades to text search configuration addr_ts_conf +drop cascades to text search template addr_ts_temp +drop cascades to text search parser addr_ts_prs +drop cascades to table gentable +drop cascades to table parttable +drop cascades to view genview +drop cascades to materialized view genmatview +drop cascades to type gencomptype +drop cascades to type genenum +drop cascades to function genaggr(integer) +drop cascades to type gendomain +drop cascades to function trig() +drop cascades to function proc(integer) DROP OWNED BY regress_addr_user; DROP USER regress_addr_user; diff --git a/src/test/regress/expected/oidjoins.out b/src/test/regress/expected/oidjoins.out index d56c70c8474..1302cc271ba 100644 --- a/src/test/regress/expected/oidjoins.out +++ b/src/test/regress/expected/oidjoins.out @@ -761,6 +761,14 @@ WHERE partrelid != 0 AND ------+----------- (0 rows) +SELECT ctid, partdefid +FROM pg_catalog.pg_partitioned_table fk +WHERE partdefid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partdefid); + ctid | partdefid +------+----------- +(0 rows) + SELECT ctid, polrelid FROM pg_catalog.pg_policy fk WHERE polrelid != 0 AND @@ -801,12 +809,12 @@ WHERE provariadic != 0 AND ------+------------- (0 rows) -SELECT ctid, protransform +SELECT ctid, prosupport FROM pg_catalog.pg_proc fk -WHERE protransform != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.protransform); - ctid | protransform -------+-------------- +WHERE prosupport != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prosupport); + ctid | prosupport +------+------------ (0 rows) SELECT ctid, prorettype @@ -977,6 +985,14 @@ WHERE stxowner != 0 AND ------+---------- (0 rows) +SELECT ctid, stxoid +FROM pg_catalog.pg_statistic_ext_data fk +WHERE stxoid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_statistic_ext pk WHERE pk.oid = fk.stxoid); + ctid | stxoid +------+-------- +(0 rows) + SELECT ctid, spcowner FROM pg_catalog.pg_tablespace fk WHERE spcowner != 0 AND diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index a1e18a6ceba..c19740e5db8 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -19,6 +19,8 @@ -- Helper functions to deal with cases where binary-coercible matches are -- allowed. -- This should match IsBinaryCoercible() in parse_coerce.c. +-- It doesn't currently know about some cases, notably domains, anyelement, +-- anynonarray, anyenum, or record, but it doesn't need to (yet). create function binary_coercible(oid, oid) returns bool as $$ begin if $1 = $2 then return true; end if; @@ -39,9 +41,11 @@ begin return false; end $$ language plpgsql strict stable; --- This one ignores castcontext, so it considers only physical equivalence --- and not whether the coercion can be invoked implicitly. -create function physically_coercible(oid, oid) returns bool as $$ +-- This one ignores castcontext, so it will allow cases where an explicit +-- (but still binary) cast would be required to convert the input type. +-- We don't currently use this for any tests in this file, but it is a +-- reasonable alternative definition for some scenarios. +create function explicitly_binary_coercible(oid, oid) returns bool as $$ begin if $1 = $2 then return true; end if; if EXISTS(select 1 from pg_catalog.pg_cast where @@ -449,10 +453,10 @@ WHERE proallargtypes IS NOT NULL AND -----+---------+-------------+----------------+------------- (0 rows) --- Check for protransform functions with the wrong signature +-- Check for prosupport functions with the wrong signature SELECT p1.oid, p1.proname, p2.oid, p2.proname FROM pg_proc AS p1, pg_proc AS p2 -WHERE p2.oid = p1.protransform AND +WHERE p2.oid = p1.prosupport AND (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); oid | proname | oid | proname @@ -521,24 +525,20 @@ int24ge(smallint,integer) int42ge(integer,smallint) oideq(oid,oid) oidne(oid,oid) -abstimeeq(abstime,abstime) -abstimene(abstime,abstime) -abstimelt(abstime,abstime) -abstimegt(abstime,abstime) -abstimele(abstime,abstime) -abstimege(abstime,abstime) -reltimeeq(reltime,reltime) -reltimene(reltime,reltime) -reltimelt(reltime,reltime) -reltimegt(reltime,reltime) -reltimele(reltime,reltime) -reltimege(reltime,reltime) -tintervalleneq(tinterval,reltime) -tintervallenne(tinterval,reltime) -tintervallenlt(tinterval,reltime) -tintervallengt(tinterval,reltime) -tintervallenle(tinterval,reltime) -tintervallenge(tinterval,reltime) +nameeqtext(name,text) +namelttext(name,text) +nameletext(name,text) +namegetext(name,text) +namegttext(name,text) +namenetext(name,text) +btnametextcmp(name,text) +texteqname(text,name) +textltname(text,name) +textlename(text,name) +textgename(text,name) +textgtname(text,name) +textnename(text,name) +bttextnamecmp(text,name) float4eq(real,real) float4ne(real,real) float4lt(real,real) @@ -563,6 +563,18 @@ float84lt(double precision,real) float84le(double precision,real) float84gt(double precision,real) float84ge(double precision,real) +btint2cmp(smallint,smallint) +btint4cmp(integer,integer) +btfloat4cmp(real,real) +btfloat8cmp(double precision,double precision) +btoidcmp(oid,oid) +btcharcmp("char","char") +btnamecmp(name,name) +bttextcmp(text,text) +cash_cmp(money,money) +btoidvectorcmp(oidvector,oidvector) +text_larger(text,text) +text_smaller(text,text) int8eq(bigint,bigint) int8ne(bigint,bigint) int8lt(bigint,bigint) @@ -575,25 +587,31 @@ int84lt(bigint,integer) int84gt(bigint,integer) int84le(bigint,integer) int84ge(bigint,integer) +oidvectorne(oidvector,oidvector) namelt(name,name) namele(name,name) namegt(name,name) namege(name,name) namene(name,name) +oidvectorlt(oidvector,oidvector) +oidvectorle(oidvector,oidvector) +oidvectoreq(oidvector,oidvector) +oidvectorge(oidvector,oidvector) +oidvectorgt(oidvector,oidvector) oidlt(oid,oid) oidle(oid,oid) -tintervaleq(tinterval,tinterval) -tintervalne(tinterval,tinterval) -tintervallt(tinterval,tinterval) -tintervalgt(tinterval,tinterval) -tintervalle(tinterval,tinterval) -tintervalge(tinterval,tinterval) +text_lt(text,text) +text_le(text,text) +text_gt(text,text) +text_ge(text,text) macaddr_eq(macaddr,macaddr) macaddr_lt(macaddr,macaddr) macaddr_le(macaddr,macaddr) macaddr_gt(macaddr,macaddr) macaddr_ge(macaddr,macaddr) macaddr_ne(macaddr,macaddr) +macaddr_cmp(macaddr,macaddr) +btint8cmp(bigint,bigint) int48eq(integer,bigint) int48ne(integer,bigint) int48lt(integer,bigint) @@ -612,20 +630,30 @@ network_le(inet,inet) network_gt(inet,inet) network_ge(inet,inet) network_ne(inet,inet) +network_cmp(inet,inet) lseg_eq(lseg,lseg) bpchareq(character,character) +bpcharlt(character,character) +bpcharle(character,character) +bpchargt(character,character) +bpcharge(character,character) bpcharne(character,character) +bpchar_larger(character,character) +bpchar_smaller(character,character) +bpcharcmp(character,character) date_eq(date,date) date_lt(date,date) date_le(date,date) date_gt(date,date) date_ge(date,date) date_ne(date,date) +date_cmp(date,date) time_lt(time without time zone,time without time zone) time_le(time without time zone,time without time zone) time_gt(time without time zone,time without time zone) time_ge(time without time zone,time without time zone) time_ne(time without time zone,time without time zone) +time_cmp(time without time zone,time without time zone) time_eq(time without time zone,time without time zone) timestamptz_eq(timestamp with time zone,timestamp with time zone) timestamptz_ne(timestamp with time zone,timestamp with time zone) @@ -642,6 +670,8 @@ interval_gt(interval,interval) charlt("char","char") tidne(tid,tid) tideq(tid,tid) +timestamptz_cmp(timestamp with time zone,timestamp with time zone) +interval_cmp(interval,interval) xideqint4(xid,integer) timetz_eq(time with time zone,time with time zone) timetz_ne(time with time zone,time with time zone) @@ -649,6 +679,7 @@ timetz_lt(time with time zone,time with time zone) timetz_le(time with time zone,time with time zone) timetz_ge(time with time zone,time with time zone) timetz_gt(time with time zone,time with time zone) +timetz_cmp(time with time zone,time with time zone) circle_eq(circle,circle) circle_ne(circle,circle) circle_lt(circle,circle) @@ -666,6 +697,7 @@ bitge(bit,bit) bitgt(bit,bit) bitle(bit,bit) bitlt(bit,bit) +bitcmp(bit,bit) oidgt(oid,oid) oidge(oid,oid) varbiteq(bit varying,bit varying) @@ -674,8 +706,10 @@ varbitge(bit varying,bit varying) varbitgt(bit varying,bit varying) varbitle(bit varying,bit varying) varbitlt(bit varying,bit varying) +varbitcmp(bit varying,bit varying) boolle(boolean,boolean) boolge(boolean,boolean) +btboolcmp(boolean,boolean) int28eq(smallint,bigint) int28ne(smallint,bigint) int28lt(smallint,bigint) @@ -694,30 +728,60 @@ byteale(bytea,bytea) byteagt(bytea,bytea) byteage(bytea,bytea) byteane(bytea,bytea) +byteacmp(bytea,bytea) +timestamp_cmp(timestamp without time zone,timestamp without time zone) timestamp_eq(timestamp without time zone,timestamp without time zone) timestamp_ne(timestamp without time zone,timestamp without time zone) timestamp_lt(timestamp without time zone,timestamp without time zone) timestamp_le(timestamp without time zone,timestamp without time zone) timestamp_ge(timestamp without time zone,timestamp without time zone) timestamp_gt(timestamp without time zone,timestamp without time zone) +text_pattern_lt(text,text) +text_pattern_le(text,text) +text_pattern_ge(text,text) +text_pattern_gt(text,text) +bttext_pattern_cmp(text,text) +bpchar_pattern_lt(character,character) +bpchar_pattern_le(character,character) +bpchar_pattern_ge(character,character) +bpchar_pattern_gt(character,character) +btbpchar_pattern_cmp(character,character) +btint48cmp(integer,bigint) +btint84cmp(bigint,integer) +btint24cmp(smallint,integer) +btint42cmp(integer,smallint) +btint28cmp(smallint,bigint) +btint82cmp(bigint,smallint) +btfloat48cmp(real,double precision) +btfloat84cmp(double precision,real) md5(text) md5(bytea) tidgt(tid,tid) tidlt(tid,tid) tidge(tid,tid) tidle(tid,tid) +bttidcmp(tid,tid) uuid_lt(uuid,uuid) uuid_le(uuid,uuid) uuid_eq(uuid,uuid) uuid_ge(uuid,uuid) uuid_gt(uuid,uuid) uuid_ne(uuid,uuid) +uuid_cmp(uuid,uuid) +pg_lsn_lt(pg_lsn,pg_lsn) +pg_lsn_le(pg_lsn,pg_lsn) +pg_lsn_eq(pg_lsn,pg_lsn) +pg_lsn_ge(pg_lsn,pg_lsn) +pg_lsn_gt(pg_lsn,pg_lsn) +pg_lsn_ne(pg_lsn,pg_lsn) +pg_lsn_cmp(pg_lsn,pg_lsn) xidneq(xid,xid) xidneqint4(xid,integer) sha224(bytea) sha256(bytea) sha384(bytea) sha512(bytea) +gen_random_uuid() starts_with(text,text) macaddr8_eq(macaddr8,macaddr8) macaddr8_lt(macaddr8,macaddr8) @@ -725,6 +789,7 @@ macaddr8_le(macaddr8,macaddr8) macaddr8_gt(macaddr8,macaddr8) macaddr8_ge(macaddr8,macaddr8) macaddr8_ne(macaddr8,macaddr8) +macaddr8_cmp(macaddr8,macaddr8) -- restore normal output mode \a\t -- List of functions used by libpq's fe-lobj.c @@ -782,8 +847,8 @@ SELECT * FROM pg_cast c WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i') OR castmethod NOT IN ('f', 'b' ,'i'); - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) -- Check that castfunc is nonzero only for cast methods that need a function, @@ -792,8 +857,8 @@ SELECT * FROM pg_cast c WHERE (castmethod = 'f' AND castfunc = 0) OR (castmethod IN ('b', 'i') AND castfunc <> 0); - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) -- Look for casts to/from the same type that aren't length coercion functions. @@ -802,15 +867,15 @@ WHERE (castmethod = 'f' AND castfunc = 0) SELECT * FROM pg_cast c WHERE castsource = casttarget AND castfunc = 0; - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) SELECT c.* FROM pg_cast c, pg_proc p WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget; - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) -- Look for cast functions that don't have the right signature. The @@ -828,8 +893,8 @@ WHERE c.castfunc = p.oid AND OR (c.castsource = 'character'::regtype AND p.proargtypes[0] = 'text'::regtype)) OR NOT binary_coercible(p.prorettype, c.casttarget)); - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) SELECT c.* @@ -837,8 +902,8 @@ FROM pg_cast c, pg_proc p WHERE c.castfunc = p.oid AND ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype)); - castsource | casttarget | castfunc | castcontext | castmethod -------------+------------+----------+-------------+------------ + oid | castsource | casttarget | castfunc | castcontext | castmethod +-----+------------+------------+----------+-------------+------------ (0 rows) -- Look for binary compatible casts that do not have the reverse @@ -867,11 +932,12 @@ WHERE c.castmethod = 'b' AND pg_node_tree | text | 0 | i pg_ndistinct | bytea | 0 | i pg_dependencies | bytea | 0 | i + pg_mcv_list | bytea | 0 | i cidr | inet | 0 | i xml | text | 0 | a xml | character varying | 0 | a xml | character | 0 | a -(9 rows) +(10 rows) -- **************** pg_conversion **************** -- Look for illegal values in pg_conversion fields. @@ -1039,9 +1105,6 @@ ORDER BY 1, 2; !~* | ~* !~~ | ~~ !~~* | ~~* - #< | #>= - #<= | #> - #<> | #= *< | *>= *<= | *> *<> | *= @@ -1051,7 +1114,7 @@ ORDER BY 1, 2; <> | ~= ~<=~ | ~>~ ~<~ | ~>=~ -(16 rows) +(13 rows) -- A mergejoinable or hashjoinable operator must be binary, must return -- boolean, and must have a commutator (itself, unless it's a cross-type @@ -1216,7 +1279,7 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999; -- Check that operators' underlying functions have suitable comments, -- namely 'implementation of XXX operator'. (Note: it's not necessary to --- put such comments into pg_proc.h; initdb will generate them as needed.) +-- put such comments into pg_proc.dat; initdb will generate them as needed.) -- In some cases involving legacy names for operators, there are multiple -- operators referencing the same pg_proc entry, so ignore operators whose -- comments say they are deprecated. @@ -1275,6 +1338,45 @@ ORDER BY 1; 3953 | json_extract_path_text | get value from json as text with path elements (9 rows) +-- Operators that are commutator pairs should have identical volatility +-- and leakproofness markings on their implementation functions. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + oid | oprcode | oid | oprcode +-----+---------+-----+--------- +(0 rows) + +-- Likewise for negator pairs. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + oid | oprcode | oid | oprcode +-----+---------+-----+--------- +(0 rows) + +-- Btree comparison operators' functions should have the same volatility +-- and leakproofness markings as the associated comparison support function. +SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp, + po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo +FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao +WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND + ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + ao.amopfamily = ap.amprocfamily AND + ao.amoplefttype = ap.amproclefttype AND + ao.amoprighttype = ap.amprocrighttype AND + ap.amprocnum = 1 AND + (pp.provolatile != po.provolatile OR + pp.proleakproof != po.proleakproof) +ORDER BY 1; + proc | vp | lp | opr | vo | lo +------+----+----+-----+----+---- +(0 rows) + -- **************** pg_aggregate **************** -- Look for illegal values in pg_aggregate fields. SELECT ctid, aggfnoid::oid @@ -1318,8 +1420,6 @@ WHERE a.aggfnoid = p.oid AND (0 rows) -- Cross-check transfn against its entry in pg_proc. --- NOTE: use physically_coercible here, not binary_coercible, because --- max and min on abstime are implemented using int4larger/int4smaller. SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr WHERE a.aggfnoid = p.oid AND @@ -1328,15 +1428,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggtranstype) - OR NOT physically_coercible(a.aggtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggtranstype) + OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); aggfnoid | proname | oid | proname ----------+---------+-----+--------- @@ -1358,7 +1459,8 @@ WHERE a.aggfnoid = p.oid AND NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) OR (pfn.pronargs > 3 AND NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) - -- we could carry the check further, but 3 args is enough for now + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) ); aggfnoid | proname | oid | proname ----------+---------+-----+--------- @@ -1414,15 +1516,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggmtranstype) - OR NOT physically_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); aggfnoid | proname | oid | proname ----------+---------+-----+--------- @@ -1437,15 +1540,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggmtranstype) - OR NOT physically_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); aggfnoid | proname | oid | proname ----------+---------+-----+--------- @@ -1467,7 +1571,8 @@ WHERE a.aggfnoid = p.oid AND NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) OR (pfn.pronargs > 3 AND NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) - -- we could carry the check further, but 3 args is enough for now + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) ); aggfnoid | proname | oid | proname ----------+---------+-----+--------- @@ -1499,15 +1604,13 @@ WHERE a.aggfnoid = p.oid AND -- Check that all combine functions have signature -- combine(transtype, transtype) returns transtype --- NOTE: use physically_coercible here, not binary_coercible, because --- max and min on abstime are implemented using int4larger/int4smaller. SELECT a.aggfnoid, p.proname FROM pg_aggregate as a, pg_proc as p WHERE a.aggcombinefn = p.oid AND (p.pronargs != 2 OR p.prorettype != p.proargtypes[0] OR p.prorettype != p.proargtypes[1] OR - NOT physically_coercible(a.aggtranstype, p.proargtypes[0])); + NOT binary_coercible(a.aggtranstype, p.proargtypes[0])); aggfnoid | proname ----------+--------- (0 rows) @@ -1676,6 +1779,16 @@ WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; ----- (0 rows) +-- Look for opfamilies having no opclasses. While most validation of +-- opfamilies is now handled by AM-specific amvalidate functions, that's +-- driven from pg_opclass entries below, so an empty opfamily would not +-- get noticed. +SELECT oid, opfname FROM pg_opfamily f +WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid); + oid | opfname +-----+--------- +(0 rows) + -- **************** pg_opclass **************** -- Look for illegal values in pg_opclass fields SELECT p1.oid @@ -1721,11 +1834,24 @@ WHERE p1.amhandler = 0; -----+-------- (0 rows) --- Check for amhandler functions with the wrong signature +-- Check for index amhandler functions with the wrong signature +SELECT p1.oid, p1.amname, p2.oid, p2.proname +FROM pg_am AS p1, pg_proc AS p2 +WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND + (p2.prorettype != 'index_am_handler'::regtype + OR p2.proretset + OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype); + oid | amname | oid | proname +-----+--------+-----+--------- +(0 rows) + +-- Check for table amhandler functions with the wrong signature SELECT p1.oid, p1.amname, p2.oid, p2.proname FROM pg_am AS p1, pg_proc AS p2 -WHERE p2.oid = p1.amhandler AND - (p2.prorettype != 'index_am_handler'::regtype OR p2.proretset +WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND + (p2.prorettype != 'table_am_handler'::regtype + OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); oid | amname | oid | proname @@ -1825,6 +1951,8 @@ ORDER BY 1, 2, 3; 2742 | 9 | ? 2742 | 10 | ?| 2742 | 11 | ?& + 2742 | 15 | @? + 2742 | 16 | @@ 3580 | 1 | < 3580 | 1 | << 3580 | 2 | &< @@ -1876,6 +2004,7 @@ ORDER BY 1, 2, 3; 4000 | 12 | <= 4000 | 12 | |&> 4000 | 14 | >= + 4000 | 15 | <-> 4000 | 15 | > 4000 | 16 | @> 4000 | 18 | = @@ -1889,7 +2018,7 @@ ORDER BY 1, 2, 3; 4000 | 26 | >> 4000 | 27 | >>= 4000 | 28 | ^@ -(122 rows) +(125 rows) -- Check that all opclass search operators have selectivity estimators. -- This is not absolutely required, but it seems a reasonable thing @@ -2039,18 +2168,25 @@ ORDER BY 1; -- a representational error in pg_index, but simply wrong catalog design. -- It's bad because we expect to be able to clone template0 and assign the -- copy a different database collation. It would especially not work for --- shared catalogs. Note that although text columns will show a collation --- in indcollation, they're still okay to index with text_pattern_ops, --- so allow that case. +-- shared catalogs. +SELECT relname, attname, attcollation +FROM pg_class c, pg_attribute a +WHERE c.oid = attrelid AND c.oid < 16384 AND + c.relkind != 'v' AND -- we don't care about columns in views + attcollation != 0 AND + attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C'); + relname | attname | attcollation +---------+---------+-------------- +(0 rows) + +-- Double-check that collation-sensitive indexes have "C" collation, too. SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll FROM (SELECT indexrelid, indrelid, unnest(indclass) as iclass, unnest(indcollation) as icoll FROM pg_index WHERE indrelid < 16384) ss -WHERE icoll != 0 AND iclass != - (SELECT oid FROM pg_opclass - WHERE opcname = 'text_pattern_ops' AND opcmethod = - (SELECT oid FROM pg_am WHERE amname = 'btree')); +WHERE icoll != 0 AND + icoll != (SELECT oid FROM pg_collation WHERE collname = 'C'); indexrelid | indrelid | iclass | icoll ------------+----------+--------+------- (0 rows) diff --git a/src/test/regress/expected/partition_aggregate.out b/src/test/regress/expected/partition_aggregate.out index 76a8209ec20..10349ec29c4 100644 --- a/src/test/regress/expected/partition_aggregate.out +++ b/src/test/regress/expected/partition_aggregate.out @@ -144,7 +144,7 @@ SELECT c, sum(a) FROM pagg_tab WHERE 1 = 2 GROUP BY c; QUERY PLAN -------------------------------- HashAggregate - Group Key: pagg_tab.c + Group Key: c -> Result One-Time Filter: false (4 rows) @@ -159,7 +159,7 @@ SELECT c, sum(a) FROM pagg_tab WHERE c = 'x' GROUP BY c; QUERY PLAN -------------------------------- GroupAggregate - Group Key: pagg_tab.c + Group Key: c -> Result One-Time Filter: false (4 rows) @@ -449,6 +449,38 @@ SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2 24 | 900 | 100 (5 rows) +-- Check with whole-row reference; partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + QUERY PLAN +------------------------------------------------------------- + Sort + Sort Key: t1.x, (sum(t1.y)), (count(((t1.*)::pagg_tab1))) + -> HashAggregate + Group Key: t1.x + -> Hash Join + Hash Cond: (t1.x = t2.y) + -> Append + -> Seq Scan on pagg_tab1_p1 t1 + -> Seq Scan on pagg_tab1_p2 t1_1 + -> Seq Scan on pagg_tab1_p3 t1_2 + -> Hash + -> Append + -> Seq Scan on pagg_tab2_p1 t2 + -> Seq Scan on pagg_tab2_p2 t2_1 + -> Seq Scan on pagg_tab2_p3 t2_2 +(15 rows) + +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + x | sum | count +----+------+------- + 0 | 500 | 100 + 6 | 1100 | 100 + 12 | 700 | 100 + 18 | 1300 | 100 + 24 | 900 | 100 +(5 rows) + -- GROUP BY having other matching key EXPLAIN (COSTS OFF) SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3; @@ -684,37 +716,33 @@ SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y G | 500 (16 rows) --- LEFT JOIN, with dummy relation on right side, +-- LEFT JOIN, with dummy relation on right side, ideally -- should produce full partitionwise aggregation plan as GROUP BY is on --- non-nullable columns +-- non-nullable columns. +-- But right now we are unable to do partitionwise join in this case. EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; - QUERY PLAN ------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------- Sort - Sort Key: pagg_tab1_p1.x, y - -> Append - -> HashAggregate - Group Key: pagg_tab1_p1.x, y - -> Hash Left Join - Hash Cond: (pagg_tab1_p1.x = y) - Filter: ((pagg_tab1_p1.x > 5) OR (y < 20)) + Sort Key: pagg_tab1_p1.x, pagg_tab2_p2.y + -> HashAggregate + Group Key: pagg_tab1_p1.x, pagg_tab2_p2.y + -> Hash Left Join + Hash Cond: (pagg_tab1_p1.x = pagg_tab2_p2.y) + Filter: ((pagg_tab1_p1.x > 5) OR (pagg_tab2_p2.y < 20)) + -> Append -> Seq Scan on pagg_tab1_p1 Filter: (x < 20) - -> Hash - -> Result - One-Time Filter: false - -> HashAggregate - Group Key: pagg_tab1_p2.x, pagg_tab2_p2.y - -> Hash Left Join - Hash Cond: (pagg_tab1_p2.x = pagg_tab2_p2.y) - Filter: ((pagg_tab1_p2.x > 5) OR (pagg_tab2_p2.y < 20)) -> Seq Scan on pagg_tab1_p2 Filter: (x < 20) - -> Hash + -> Hash + -> Append -> Seq Scan on pagg_tab2_p2 Filter: (y > 10) -(23 rows) + -> Seq Scan on pagg_tab2_p3 + Filter: (y > 10) +(18 rows) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; x | y | count @@ -728,49 +756,33 @@ SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOI 18 | 18 | 100 (7 rows) --- FULL JOIN, with dummy relations on both sides, +-- FULL JOIN, with dummy relations on both sides, ideally -- should produce partial partitionwise aggregation plan as GROUP BY is on --- nullable columns +-- nullable columns. +-- But right now we are unable to do partitionwise join in this case. EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------ - Finalize GroupAggregate - Group Key: pagg_tab1_p1.x, y - -> Sort - Sort Key: pagg_tab1_p1.x, y - -> Append - -> Partial HashAggregate - Group Key: pagg_tab1_p1.x, y - -> Hash Full Join - Hash Cond: (pagg_tab1_p1.x = y) - Filter: ((pagg_tab1_p1.x > 5) OR (y < 20)) - -> Seq Scan on pagg_tab1_p1 - Filter: (x < 20) - -> Hash - -> Result - One-Time Filter: false - -> Partial HashAggregate - Group Key: pagg_tab1_p2.x, pagg_tab2_p2.y - -> Hash Full Join - Hash Cond: (pagg_tab1_p2.x = pagg_tab2_p2.y) - Filter: ((pagg_tab1_p2.x > 5) OR (pagg_tab2_p2.y < 20)) - -> Seq Scan on pagg_tab1_p2 - Filter: (x < 20) - -> Hash - -> Seq Scan on pagg_tab2_p2 - Filter: (y > 10) - -> Partial HashAggregate - Group Key: x, pagg_tab2_p3.y - -> Hash Full Join - Hash Cond: (pagg_tab2_p3.y = x) - Filter: ((x > 5) OR (pagg_tab2_p3.y < 20)) + QUERY PLAN +----------------------------------------------------------------------- + Sort + Sort Key: pagg_tab1_p1.x, pagg_tab2_p2.y + -> HashAggregate + Group Key: pagg_tab1_p1.x, pagg_tab2_p2.y + -> Hash Full Join + Hash Cond: (pagg_tab1_p1.x = pagg_tab2_p2.y) + Filter: ((pagg_tab1_p1.x > 5) OR (pagg_tab2_p2.y < 20)) + -> Append + -> Seq Scan on pagg_tab1_p1 + Filter: (x < 20) + -> Seq Scan on pagg_tab1_p2 + Filter: (x < 20) + -> Hash + -> Append + -> Seq Scan on pagg_tab2_p2 + Filter: (y > 10) -> Seq Scan on pagg_tab2_p3 Filter: (y > 10) - -> Hash - -> Result - One-Time Filter: false -(35 rows) +(18 rows) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; x | y | count @@ -1394,3 +1406,108 @@ SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 11 | 16500 | 11.0000000000000000 | 1500 (4 rows) +-- Test when parent can produce parallel paths but not any (or some) of its children +ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0); +ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0); +ANALYZE pagg_tab_para; +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + QUERY PLAN +-------------------------------------------------------------------------------------- + Sort + Sort Key: pagg_tab_para_p1.x, (sum(pagg_tab_para_p1.y)), (avg(pagg_tab_para_p1.y)) + -> Finalize GroupAggregate + Group Key: pagg_tab_para_p1.x + Filter: (avg(pagg_tab_para_p1.y) < '7'::numeric) + -> Gather Merge + Workers Planned: 2 + -> Sort + Sort Key: pagg_tab_para_p1.x + -> Partial HashAggregate + Group Key: pagg_tab_para_p1.x + -> Parallel Append + -> Seq Scan on pagg_tab_para_p1 + -> Seq Scan on pagg_tab_para_p3 + -> Parallel Seq Scan on pagg_tab_para_p2 +(15 rows) + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + x | sum | avg | count +----+------+--------------------+------- + 0 | 5000 | 5.0000000000000000 | 1000 + 1 | 6000 | 6.0000000000000000 | 1000 + 10 | 5000 | 5.0000000000000000 | 1000 + 11 | 6000 | 6.0000000000000000 | 1000 + 20 | 5000 | 5.0000000000000000 | 1000 + 21 | 6000 | 6.0000000000000000 | 1000 +(6 rows) + +ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0); +ANALYZE pagg_tab_para; +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + QUERY PLAN +-------------------------------------------------------------------------------------- + Sort + Sort Key: pagg_tab_para_p1.x, (sum(pagg_tab_para_p1.y)), (avg(pagg_tab_para_p1.y)) + -> Finalize GroupAggregate + Group Key: pagg_tab_para_p1.x + Filter: (avg(pagg_tab_para_p1.y) < '7'::numeric) + -> Gather Merge + Workers Planned: 2 + -> Sort + Sort Key: pagg_tab_para_p1.x + -> Partial HashAggregate + Group Key: pagg_tab_para_p1.x + -> Parallel Append + -> Seq Scan on pagg_tab_para_p1 + -> Seq Scan on pagg_tab_para_p2 + -> Seq Scan on pagg_tab_para_p3 +(15 rows) + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + x | sum | avg | count +----+------+--------------------+------- + 0 | 5000 | 5.0000000000000000 | 1000 + 1 | 6000 | 6.0000000000000000 | 1000 + 10 | 5000 | 5.0000000000000000 | 1000 + 11 | 6000 | 6.0000000000000000 | 1000 + 20 | 5000 | 5.0000000000000000 | 1000 + 21 | 6000 | 6.0000000000000000 | 1000 +(6 rows) + +-- Reset parallelism parameters to get partitionwise aggregation plan. +RESET min_parallel_table_scan_size; +RESET parallel_setup_cost; +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + QUERY PLAN +-------------------------------------------------------------------------------------- + Sort + Sort Key: pagg_tab_para_p1.x, (sum(pagg_tab_para_p1.y)), (avg(pagg_tab_para_p1.y)) + -> Append + -> HashAggregate + Group Key: pagg_tab_para_p1.x + Filter: (avg(pagg_tab_para_p1.y) < '7'::numeric) + -> Seq Scan on pagg_tab_para_p1 + -> HashAggregate + Group Key: pagg_tab_para_p2.x + Filter: (avg(pagg_tab_para_p2.y) < '7'::numeric) + -> Seq Scan on pagg_tab_para_p2 + -> HashAggregate + Group Key: pagg_tab_para_p3.x + Filter: (avg(pagg_tab_para_p3.y) < '7'::numeric) + -> Seq Scan on pagg_tab_para_p3 +(15 rows) + +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + x | sum | avg | count +----+------+--------------------+------- + 0 | 5000 | 5.0000000000000000 | 1000 + 1 | 6000 | 6.0000000000000000 | 1000 + 10 | 5000 | 5.0000000000000000 | 1000 + 11 | 6000 | 6.0000000000000000 | 1000 + 20 | 5000 | 5.0000000000000000 | 1000 + 21 | 6000 | 6.0000000000000000 | 1000 +(6 rows) + diff --git a/src/test/regress/expected/partition_info.out b/src/test/regress/expected/partition_info.out new file mode 100644 index 00000000000..42b6bc77cad --- /dev/null +++ b/src/test/regress/expected/partition_info.out @@ -0,0 +1,351 @@ +-- +-- Tests for functions providing information about partitions +-- +SELECT * FROM pg_partition_tree(NULL); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_tree(0); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_ancestors(NULL); + relid +------- +(0 rows) + +SELECT * FROM pg_partition_ancestors(0); + relid +------- +(0 rows) + +SELECT pg_partition_root(NULL); + pg_partition_root +------------------- + +(1 row) + +SELECT pg_partition_root(0); + pg_partition_root +------------------- + +(1 row) + +-- Test table partition trees +CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a); +CREATE TABLE ptif_test0 PARTITION OF ptif_test + FOR VALUES FROM (minvalue) TO (0) PARTITION BY list (b); +CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1); +CREATE TABLE ptif_test1 PARTITION OF ptif_test + FOR VALUES FROM (0) TO (100) PARTITION BY list (b); +CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1); +CREATE TABLE ptif_test2 PARTITION OF ptif_test + FOR VALUES FROM (100) TO (200); +-- This partitioned table should remain with no partitions. +CREATE TABLE ptif_test3 PARTITION OF ptif_test + FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b); +-- Test pg_partition_root for tables +SELECT pg_partition_root('ptif_test'); + pg_partition_root +------------------- + ptif_test +(1 row) + +SELECT pg_partition_root('ptif_test0'); + pg_partition_root +------------------- + ptif_test +(1 row) + +SELECT pg_partition_root('ptif_test01'); + pg_partition_root +------------------- + ptif_test +(1 row) + +SELECT pg_partition_root('ptif_test3'); + pg_partition_root +------------------- + ptif_test +(1 row) + +-- Test index partition tree +CREATE INDEX ptif_test_index ON ONLY ptif_test (a); +CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index; +CREATE INDEX ptif_test01_index ON ptif_test01 (a); +ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index; +CREATE INDEX ptif_test1_index ON ONLY ptif_test1 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index; +CREATE INDEX ptif_test11_index ON ptif_test11 (a); +ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index; +CREATE INDEX ptif_test2_index ON ptif_test2 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index; +CREATE INDEX ptif_test3_index ON ptif_test3 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index; +-- Test pg_partition_root for indexes +SELECT pg_partition_root('ptif_test_index'); + pg_partition_root +------------------- + ptif_test_index +(1 row) + +SELECT pg_partition_root('ptif_test0_index'); + pg_partition_root +------------------- + ptif_test_index +(1 row) + +SELECT pg_partition_root('ptif_test01_index'); + pg_partition_root +------------------- + ptif_test_index +(1 row) + +SELECT pg_partition_root('ptif_test3_index'); + pg_partition_root +------------------- + ptif_test_index +(1 row) + +-- List all tables members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test'); + relid | parentrelid | level | isleaf +-------------+-------------+-------+-------- + ptif_test | | 0 | f + ptif_test0 | ptif_test | 1 | f + ptif_test1 | ptif_test | 1 | f + ptif_test2 | ptif_test | 1 | t + ptif_test3 | ptif_test | 1 | f + ptif_test01 | ptif_test0 | 2 | t + ptif_test11 | ptif_test1 | 2 | t +(7 rows) + +-- List tables from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------+-------------+-------+-------- + ptif_test0 | ptif_test | 0 | f + ptif_test01 | ptif_test0 | 1 | t +(2 rows) + +-- List from leaf table +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------+-------------+-------+-------- + ptif_test01 | ptif_test0 | 0 | t +(1 row) + +-- List from partitioned table with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +------------+-------------+-------+-------- + ptif_test3 | ptif_test | 0 | f +(1 row) + +-- List all ancestors of root and leaf tables +SELECT * FROM pg_partition_ancestors('ptif_test01'); + relid +------------- + ptif_test01 + ptif_test0 + ptif_test +(3 rows) + +SELECT * FROM pg_partition_ancestors('ptif_test'); + relid +----------- + ptif_test +(1 row) + +-- List all members using pg_partition_root with leaf table reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01')) p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------+-------------+-------+-------- + ptif_test | | 0 | f + ptif_test0 | ptif_test | 1 | f + ptif_test1 | ptif_test | 1 | f + ptif_test2 | ptif_test | 1 | t + ptif_test3 | ptif_test | 1 | f + ptif_test01 | ptif_test0 | 2 | t + ptif_test11 | ptif_test1 | 2 | t +(7 rows) + +-- List all indexes members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test_index'); + relid | parentrelid | level | isleaf +-------------------+------------------+-------+-------- + ptif_test_index | | 0 | f + ptif_test0_index | ptif_test_index | 1 | f + ptif_test1_index | ptif_test_index | 1 | f + ptif_test2_index | ptif_test_index | 1 | t + ptif_test3_index | ptif_test_index | 1 | f + ptif_test01_index | ptif_test0_index | 2 | t + ptif_test11_index | ptif_test1_index | 2 | t +(7 rows) + +-- List indexes from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0_index') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------------+------------------+-------+-------- + ptif_test0_index | ptif_test_index | 0 | f + ptif_test01_index | ptif_test0_index | 1 | t +(2 rows) + +-- List from leaf index +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01_index') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------------+------------------+-------+-------- + ptif_test01_index | ptif_test0_index | 0 | t +(1 row) + +-- List from partitioned index with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3_index') p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +------------------+-----------------+-------+-------- + ptif_test3_index | ptif_test_index | 0 | f +(1 row) + +-- List all members using pg_partition_root with leaf index reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p + JOIN pg_class c ON (p.relid = c.oid); + relid | parentrelid | level | isleaf +-------------------+------------------+-------+-------- + ptif_test_index | | 0 | f + ptif_test0_index | ptif_test_index | 1 | f + ptif_test1_index | ptif_test_index | 1 | f + ptif_test2_index | ptif_test_index | 1 | t + ptif_test3_index | ptif_test_index | 1 | f + ptif_test01_index | ptif_test0_index | 2 | t + ptif_test11_index | ptif_test1_index | 2 | t +(7 rows) + +-- List all ancestors of root and leaf indexes +SELECT * FROM pg_partition_ancestors('ptif_test01_index'); + relid +------------------- + ptif_test01_index + ptif_test0_index + ptif_test_index +(3 rows) + +SELECT * FROM pg_partition_ancestors('ptif_test_index'); + relid +----------------- + ptif_test_index +(1 row) + +DROP TABLE ptif_test; +-- Table that is not part of any partition tree is not listed. +CREATE TABLE ptif_normal_table(a int); +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_normal_table'); + relid | parentrelid | level | isleaf +-------+-------------+-------+-------- +(0 rows) + +SELECT * FROM pg_partition_ancestors('ptif_normal_table'); + relid +------- +(0 rows) + +SELECT pg_partition_root('ptif_normal_table'); + pg_partition_root +------------------- + +(1 row) + +DROP TABLE ptif_normal_table; +-- Various partitioning-related functions return empty/NULL if passed relations +-- of types that cannot be part of a partition tree; for example, views, +-- materialized views, legacy inheritance children or parents, etc. +CREATE VIEW ptif_test_view AS SELECT 1; +CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1; +CREATE TABLE ptif_li_parent (); +CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent); +SELECT * FROM pg_partition_tree('ptif_test_view'); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_tree('ptif_test_matview'); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_tree('ptif_li_parent'); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_tree('ptif_li_child'); + relid | parentrelid | isleaf | level +-------+-------------+--------+------- +(0 rows) + +SELECT * FROM pg_partition_ancestors('ptif_test_view'); + relid +------- +(0 rows) + +SELECT * FROM pg_partition_ancestors('ptif_test_matview'); + relid +------- +(0 rows) + +SELECT * FROM pg_partition_ancestors('ptif_li_parent'); + relid +------- +(0 rows) + +SELECT * FROM pg_partition_ancestors('ptif_li_child'); + relid +------- +(0 rows) + +SELECT pg_partition_root('ptif_test_view'); + pg_partition_root +------------------- + +(1 row) + +SELECT pg_partition_root('ptif_test_matview'); + pg_partition_root +------------------- + +(1 row) + +SELECT pg_partition_root('ptif_li_parent'); + pg_partition_root +------------------- + +(1 row) + +SELECT pg_partition_root('ptif_li_child'); + pg_partition_root +------------------- + +(1 row) + +DROP VIEW ptif_test_view; +DROP MATERIALIZED VIEW ptif_test_matview; +DROP TABLE ptif_li_parent, ptif_li_child; diff --git a/src/test/regress/expected/partition_join.out b/src/test/regress/expected/partition_join.out index b983f9c5065..cad8dd591aa 100644 --- a/src/test/regress/expected/partition_join.out +++ b/src/test/regress/expected/partition_join.out @@ -62,33 +62,28 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 450 | 0450 | 450 | 0450 (4 rows) --- left outer join, with whole-row reference +-- left outer join, with whole-row reference; partitionwise join does not apply EXPLAIN (COSTS OFF) SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; QUERY PLAN -------------------------------------------------- Sort Sort Key: t1.a, t2.b - -> Append - -> Hash Right Join - Hash Cond: (t2.b = t1.a) + -> Hash Right Join + Hash Cond: (t2.b = t1.a) + -> Append -> Seq Scan on prt2_p1 t2 - -> Hash + -> Seq Scan on prt2_p2 t2_1 + -> Seq Scan on prt2_p3 t2_2 + -> Hash + -> Append -> Seq Scan on prt1_p1 t1 Filter: (b = 0) - -> Hash Right Join - Hash Cond: (t2_1.b = t1_1.a) - -> Seq Scan on prt2_p2 t2_1 - -> Hash -> Seq Scan on prt1_p2 t1_1 Filter: (b = 0) - -> Hash Right Join - Hash Cond: (t2_2.b = t1_2.a) - -> Seq Scan on prt2_p3 t2_2 - -> Hash -> Seq Scan on prt1_p3 t1_2 Filter: (b = 0) -(21 rows) +(16 rows) SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; t1 | t2 @@ -191,19 +186,18 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT 50 phv, * FROM prt1 WHERE prt1.b = 0) -- Join with pruned partitions from joining relations EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------- Sort Sort Key: t1.a - -> Append - -> Hash Join - Hash Cond: (t2.b = t1.a) - -> Seq Scan on prt2_p2 t2 - Filter: (b > 250) - -> Hash - -> Seq Scan on prt1_p2 t1 - Filter: ((a < 450) AND (b = 0)) -(10 rows) + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Seq Scan on prt2_p2 t2 + Filter: (b > 250) + -> Hash + -> Seq Scan on prt1_p2 t1 + Filter: ((a < 450) AND (b = 0)) +(9 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -211,28 +205,27 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 300 | 0300 | 300 | 0300 (1 row) +-- Currently we can't do partitioned join if nullable-side partitions are pruned EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; QUERY PLAN ----------------------------------------------------------- Sort - Sort Key: prt1_p1.a, b - -> Append - -> Hash Left Join - Hash Cond: (prt1_p1.a = b) - -> Seq Scan on prt1_p1 - Filter: ((a < 450) AND (b = 0)) - -> Hash - -> Result - One-Time Filter: false - -> Hash Right Join - Hash Cond: (prt2_p2.b = prt1_p2.a) + Sort Key: prt1_p1.a, prt2_p2.b + -> Hash Right Join + Hash Cond: (prt2_p2.b = prt1_p1.a) + -> Append -> Seq Scan on prt2_p2 Filter: (b > 250) - -> Hash + -> Seq Scan on prt2_p3 + Filter: (b > 250) + -> Hash + -> Append + -> Seq Scan on prt1_p1 + Filter: ((a < 450) AND (b = 0)) -> Seq Scan on prt1_p2 Filter: ((a < 450) AND (b = 0)) -(17 rows) +(15 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -248,38 +241,28 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JO 400 | 0400 | | (9 rows) +-- Currently we can't do partitioned join if nullable-side partitions are pruned EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; - QUERY PLAN ------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Sort - Sort Key: prt1_p1.a, b - -> Append - -> Hash Full Join - Hash Cond: (prt1_p1.a = b) - Filter: ((prt1_p1.b = 0) OR (a = 0)) + Sort Key: prt1_p1.a, prt2_p2.b + -> Hash Full Join + Hash Cond: (prt1_p1.a = prt2_p2.b) + Filter: ((prt1_p1.b = 0) OR (prt2_p2.a = 0)) + -> Append -> Seq Scan on prt1_p1 Filter: (a < 450) - -> Hash - -> Result - One-Time Filter: false - -> Hash Full Join - Hash Cond: (prt1_p2.a = prt2_p2.b) - Filter: ((prt1_p2.b = 0) OR (prt2_p2.a = 0)) -> Seq Scan on prt1_p2 Filter: (a < 450) - -> Hash + -> Hash + -> Append -> Seq Scan on prt2_p2 Filter: (b > 250) - -> Hash Full Join - Hash Cond: (prt2_p3.b = a) - Filter: ((b = 0) OR (prt2_p3.a = 0)) - -> Seq Scan on prt2_p3 - Filter: (b > 250) - -> Hash - -> Result - One-Time Filter: false -(27 rows) + -> Seq Scan on prt2_p3 + Filter: (b > 250) +(16 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -652,7 +635,7 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 -> Seq Scan on prt1_e_p1 t3 Filter: (c = 0) -> Index Scan using iprt2_p1_b on prt2_p1 t2 - Index Cond: (t1.a = b) + Index Cond: (b = t1.a) -> Nested Loop Left Join -> Hash Right Join Hash Cond: (t1_1.a = ((t3_1.a + t3_1.b) / 2)) @@ -661,7 +644,7 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 -> Seq Scan on prt1_e_p2 t3_1 Filter: (c = 0) -> Index Scan using iprt2_p2_b on prt2_p2 t2_1 - Index Cond: (t1_1.a = b) + Index Cond: (b = t1_1.a) -> Nested Loop Left Join -> Hash Right Join Hash Cond: (t1_2.a = ((t3_2.a + t3_2.b) / 2)) @@ -670,7 +653,7 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 -> Seq Scan on prt1_e_p3 t3_2 Filter: (c = 0) -> Index Scan using iprt2_p3_b on prt2_p3 t2_2 - Index Cond: (t1_2.a = b) + Index Cond: (b = t1_2.a) (30 rows) SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; @@ -806,8 +789,8 @@ SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1, prt1_e t2 WHER EXPLAIN (COSTS OFF) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; - QUERY PLAN -------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------- Sort Sort Key: t1.a -> Append @@ -836,19 +819,18 @@ SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN ( Index Cond: (a = t1_4.b) Filter: (b = 0) -> Nested Loop - -> Unique - -> Sort - Sort Key: t1_5.b - -> Hash Semi Join - Hash Cond: (t1_5.b = ((t1_8.a + t1_8.b) / 2)) - -> Seq Scan on prt2_p3 t1_5 - -> Hash - -> Seq Scan on prt1_e_p3 t1_8 - Filter: (c = 0) + -> HashAggregate + Group Key: t1_5.b + -> Hash Semi Join + Hash Cond: (t1_5.b = ((t1_8.a + t1_8.b) / 2)) + -> Seq Scan on prt2_p3 t1_5 + -> Hash + -> Seq Scan on prt1_e_p3 t1_8 + Filter: (c = 0) -> Index Scan using iprt1_p3_a on prt1_p3 t1_2 Index Cond: (a = t1_5.b) Filter: (b = 0) -(40 rows) +(39 rows) SELECT t1.* FROM prt1 t1 WHERE t1.a IN (SELECT t1.b FROM prt2 t1 WHERE t1.b IN (SELECT (t1.a + t1.b)/2 FROM prt1_e t1 WHERE t1.c = 0)) AND t1.b = 0 ORDER BY t1.a; a | b | c @@ -999,34 +981,30 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 (12 rows) -- MergeAppend on nullable column +-- This should generate a partitionwise join, but currently fails to EXPLAIN (COSTS OFF) SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; QUERY PLAN ----------------------------------------------------------- Sort - Sort Key: prt1_p1.a, b - -> Append - -> Merge Left Join - Merge Cond: (prt1_p1.a = b) - -> Sort - Sort Key: prt1_p1.a + Sort Key: prt1_p1.a, prt2_p2.b + -> Merge Left Join + Merge Cond: (prt1_p1.a = prt2_p2.b) + -> Sort + Sort Key: prt1_p1.a + -> Append -> Seq Scan on prt1_p1 Filter: ((a < 450) AND (b = 0)) - -> Sort - Sort Key: b - -> Result - One-Time Filter: false - -> Merge Left Join - Merge Cond: (prt1_p2.a = prt2_p2.b) - -> Sort - Sort Key: prt1_p2.a -> Seq Scan on prt1_p2 Filter: ((a < 450) AND (b = 0)) - -> Sort - Sort Key: prt2_p2.b + -> Sort + Sort Key: prt2_p2.b + -> Append -> Seq Scan on prt2_p2 Filter: (b > 250) -(23 rows) + -> Seq Scan on prt2_p3 + Filter: (b > 250) +(18 rows) SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; a | b @@ -1042,6 +1020,40 @@ SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * 400 | (9 rows) +-- merge join when expression with whole-row reference needs to be sorted; +-- partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + QUERY PLAN +----------------------------------------------------------------------------------------- + Merge Join + Merge Cond: ((t1.a = t2.b) AND (((((t1.*)::prt1))::text) = ((((t2.*)::prt2))::text))) + -> Sort + Sort Key: t1.a, ((((t1.*)::prt1))::text) + -> Result + -> Append + -> Seq Scan on prt1_p1 t1 + -> Seq Scan on prt1_p2 t1_1 + -> Seq Scan on prt1_p3 t1_2 + -> Sort + Sort Key: t2.b, ((((t2.*)::prt2))::text) + -> Result + -> Append + -> Seq Scan on prt2_p1 t2 + -> Seq Scan on prt2_p2 t2_1 + -> Seq Scan on prt2_p3 t2_2 +(16 rows) + +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + a | b +----+---- + 0 | 0 + 6 | 6 + 12 | 12 + 18 | 18 + 24 | 24 +(5 rows) + RESET enable_hashjoin; RESET enable_nestloop; -- @@ -1328,6 +1340,76 @@ SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, ph 273.0000000000000000 | 273.0000000000000000 | 548.0000000000000000 | 0005 | 0005 | A0005 (6 rows) +-- test default partition behavior for range +ALTER TABLE prt1 DETACH PARTITION prt1_p3; +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT; +ANALYZE prt1; +ALTER TABLE prt2 DETACH PARTITION prt2_p3; +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT; +ANALYZE prt2; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +-------------------------------------------------- + Sort + Sort Key: t1.a + -> Append + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Seq Scan on prt2_p1 t2 + -> Hash + -> Seq Scan on prt1_p1 t1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_1.b = t1_1.a) + -> Seq Scan on prt2_p2 t2_1 + -> Hash + -> Seq Scan on prt1_p2 t1_1 + Filter: (b = 0) + -> Hash Join + Hash Cond: (t2_2.b = t1_2.a) + -> Seq Scan on prt2_p3 t2_2 + -> Hash + -> Seq Scan on prt1_p3 t1_2 + Filter: (b = 0) +(21 rows) + +-- test default partition behavior for list +ALTER TABLE plt1 DETACH PARTITION plt1_p3; +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT; +ANALYZE plt1; +ALTER TABLE plt2 DETACH PARTITION plt2_p3; +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT; +ANALYZE plt2; +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c; + QUERY PLAN +-------------------------------------------------------- + Sort + Sort Key: t1.c + -> HashAggregate + Group Key: t1.c, t2.c + -> Append + -> Hash Join + Hash Cond: (t2.c = t1.c) + -> Seq Scan on plt2_p1 t2 + -> Hash + -> Seq Scan on plt1_p1 t1 + Filter: ((a % 25) = 0) + -> Hash Join + Hash Cond: (t2_1.c = t1_1.c) + -> Seq Scan on plt2_p2 t2_1 + -> Hash + -> Seq Scan on plt1_p2 t1_1 + Filter: ((a % 25) = 0) + -> Hash Join + Hash Cond: (t2_2.c = t1_2.c) + -> Seq Scan on plt2_p3 t2_2 + -> Hash + -> Seq Scan on plt1_p3 t1_2 + Filter: ((a % 25) = 0) +(23 rows) + -- -- multiple levels of partitioning -- @@ -1382,10 +1464,9 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1 -> Seq Scan on prt2_l_p3_p1 t2_3 -> Seq Scan on prt2_l_p3_p2 t2_4 -> Hash - -> Append - -> Seq Scan on prt1_l_p3_p1 t1_3 - Filter: (b = 0) -(29 rows) + -> Seq Scan on prt1_l_p3_p1 t1_3 + Filter: (b = 0) +(28 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1, prt2_l t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -1428,10 +1509,9 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b -> Seq Scan on prt2_l_p3_p1 t2_3 -> Seq Scan on prt2_l_p3_p2 t2_4 -> Hash - -> Append - -> Seq Scan on prt1_l_p3_p1 t1_3 - Filter: (b = 0) -(30 rows) + -> Seq Scan on prt1_l_p3_p1 t1_3 + Filter: (b = 0) +(29 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 LEFT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t1.b = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -1482,10 +1562,9 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b -> Seq Scan on prt1_l_p3_p1 t1_3 -> Seq Scan on prt1_l_p3_p2 t1_4 -> Hash - -> Append - -> Seq Scan on prt2_l_p3_p1 t2_3 - Filter: (a = 0) -(30 rows) + -> Seq Scan on prt2_l_p3_p1 t2_3 + Filter: (a = 0) +(29 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_l t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.c = t2.c WHERE t2.a = 0 ORDER BY t1.a, t2.b; a | c | b | c @@ -1531,14 +1610,12 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 Filter: (a = 0) -> Hash Full Join Hash Cond: ((prt1_l_p3_p1.a = prt2_l_p3_p1.b) AND ((prt1_l_p3_p1.c)::text = (prt2_l_p3_p1.c)::text)) - -> Append - -> Seq Scan on prt1_l_p3_p1 - Filter: (b = 0) + -> Seq Scan on prt1_l_p3_p1 + Filter: (b = 0) -> Hash - -> Append - -> Seq Scan on prt2_l_p3_p1 - Filter: (a = 0) -(33 rows) + -> Seq Scan on prt2_l_p3_p1 + Filter: (a = 0) +(31 rows) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE prt1_l.b = 0) t1 FULL JOIN (SELECT * FROM prt2_l WHERE prt2_l.a = 0) t2 ON (t1.a = t2.b AND t1.c = t2.c) ORDER BY t1.a, t2.b; a | c | b | c @@ -1599,9 +1676,8 @@ SELECT * FROM prt1_l t1 LEFT JOIN LATERAL -> Seq Scan on prt1_l_p2_p2 t2_2 Filter: ((t1_2.a = a) AND ((t1_2.c)::text = (c)::text)) -> Nested Loop Left Join - -> Append - -> Seq Scan on prt1_l_p3_p1 t1_3 - Filter: (b = 0) + -> Seq Scan on prt1_l_p3_p1 t1_3 + Filter: (b = 0) -> Hash Join Hash Cond: ((t3_3.b = t2_3.a) AND ((t3_3.c)::text = (t2_3.c)::text)) -> Append @@ -1613,7 +1689,7 @@ SELECT * FROM prt1_l t1 LEFT JOIN LATERAL Filter: ((t1_3.a = a) AND ((t1_3.c)::text = (c)::text)) -> Seq Scan on prt1_l_p3_p2 t2_4 Filter: ((t1_3.a = a) AND ((t1_3.c)::text = (c)::text)) -(45 rows) +(44 rows) SELECT * FROM prt1_l t1 LEFT JOIN LATERAL (SELECT t2.a AS t2a, t2.c AS t2c, t2.b AS t2b, t3.b AS t3b, least(t1.a,t2.a,t3.b) FROM prt1_l t2 JOIN prt2_l t3 ON (t2.a = t3.b AND t2.c = t3.c)) ss @@ -1652,6 +1728,49 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) One-Time Filter: false (11 rows) +-- Test case to verify proper handling of subqueries in a partitioned delete. +-- The weird-looking lateral join is just there to force creation of a +-- nestloop parameter within the subquery, which exposes the problem if the +-- planner fails to make multiple copies of the subquery as appropriate. +EXPLAIN (COSTS OFF) +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL); + QUERY PLAN +--------------------------------------------------------------- + Delete on prt1_l + Delete on prt1_l_p1 + Delete on prt1_l_p3_p1 + Delete on prt1_l_p3_p2 + -> Nested Loop Semi Join + -> Seq Scan on prt1_l_p1 + Filter: (c IS NULL) + -> Nested Loop + -> Seq Scan on int4_tbl + -> Subquery Scan on ss + -> Limit + -> Seq Scan on int8_tbl + -> Nested Loop Semi Join + -> Seq Scan on prt1_l_p3_p1 + Filter: (c IS NULL) + -> Nested Loop + -> Seq Scan on int4_tbl + -> Subquery Scan on ss_1 + -> Limit + -> Seq Scan on int8_tbl int8_tbl_1 + -> Nested Loop Semi Join + -> Seq Scan on prt1_l_p3_p2 + Filter: (c IS NULL) + -> Nested Loop + -> Seq Scan on int4_tbl + -> Subquery Scan on ss_2 + -> Limit + -> Seq Scan on int8_tbl int8_tbl_2 +(28 rows) + -- -- negative testcases -- @@ -1737,11 +1856,11 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1 LEFT JOIN prt2 t2 ON (t1.a < t2.b); -> Seq Scan on prt1_p3 t1_2 -> Append -> Index Scan using iprt2_p1_b on prt2_p1 t2 - Index Cond: (t1.a < b) + Index Cond: (b > t1.a) -> Index Scan using iprt2_p2_b on prt2_p2 t2_1 - Index Cond: (t1.a < b) + Index Cond: (b > t1.a) -> Index Scan using iprt2_p3_b on prt2_p3 t2_2 - Index Cond: (t1.a < b) + Index Cond: (b > t1.a) (12 rows) -- equi-join with join condition on partial keys does not qualify for @@ -1840,7 +1959,7 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOI (16 rows) -- partitionwise join can not be applied for a join between list and range --- partitioned table +-- partitioned tables EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c); QUERY PLAN @@ -1857,3 +1976,30 @@ SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c); -> Seq Scan on prt1_n_p2 t1_1 (10 rows) +-- partitionwise join can not be applied if only one of joining tables has +-- default partition +ALTER TABLE prt2 DETACH PARTITION prt2_p3; +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 FOR VALUES FROM (500) TO (600); +ANALYZE prt2; +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + QUERY PLAN +-------------------------------------------------- + Sort + Sort Key: t1.a + -> Hash Join + Hash Cond: (t2.b = t1.a) + -> Append + -> Seq Scan on prt2_p1 t2 + -> Seq Scan on prt2_p2 t2_1 + -> Seq Scan on prt2_p3 t2_2 + -> Hash + -> Append + -> Seq Scan on prt1_p1 t1 + Filter: (b = 0) + -> Seq Scan on prt1_p2 t1_1 + Filter: (b = 0) + -> Seq Scan on prt1_p3 t1_2 + Filter: (b = 0) +(16 rows) + diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index df3fca025e6..3511181f6d3 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -1,6 +1,8 @@ -- -- Test partitioning planner code -- +-- Force generic plans to be used for all prepared statements in this file. +set plan_cache_mode = force_generic_plan; create table lp (a char) partition by list (a); create table lp_default partition of lp default; create table lp_ef partition of lp for values in ('e', 'f'); @@ -43,20 +45,18 @@ explain (costs off) select * from lp where a > 'a' and a <= 'd'; (7 rows) explain (costs off) select * from lp where a = 'a'; - QUERY PLAN ------------------------------------ - Append - -> Seq Scan on lp_ad - Filter: (a = 'a'::bpchar) -(3 rows) + QUERY PLAN +----------------------------- + Seq Scan on lp_ad + Filter: (a = 'a'::bpchar) +(2 rows) explain (costs off) select * from lp where 'a' = a; /* commuted */ - QUERY PLAN ------------------------------------ - Append - -> Seq Scan on lp_ad - Filter: ('a'::bpchar = a) -(3 rows) + QUERY PLAN +----------------------------- + Seq Scan on lp_ad + Filter: ('a'::bpchar = a) +(2 rows) explain (costs off) select * from lp where a is not null; QUERY PLAN @@ -75,12 +75,11 @@ explain (costs off) select * from lp where a is not null; (11 rows) explain (costs off) select * from lp where a is null; - QUERY PLAN ------------------------------ - Append - -> Seq Scan on lp_null - Filter: (a IS NULL) -(3 rows) + QUERY PLAN +----------------------- + Seq Scan on lp_null + Filter: (a IS NULL) +(2 rows) explain (costs off) select * from lp where a = 'a' or a = 'c'; QUERY PLAN @@ -150,12 +149,11 @@ create table coll_pruning_a partition of coll_pruning for values in ('a'); create table coll_pruning_b partition of coll_pruning for values in ('b'); create table coll_pruning_def partition of coll_pruning default; explain (costs off) select * from coll_pruning where a collate "C" = 'a' collate "C"; - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on coll_pruning_a - Filter: (a = 'a'::text COLLATE "C") -(3 rows) + QUERY PLAN +--------------------------------------- + Seq Scan on coll_pruning_a + Filter: (a = 'a'::text COLLATE "C") +(2 rows) -- collation doesn't match the partitioning collation, no pruning occurs explain (costs off) select * from coll_pruning where a collate "POSIX" = 'a' collate "POSIX"; @@ -192,20 +190,18 @@ create table rlp5 partition of rlp for values from (31) to (maxvalue) partition create table rlp5_default partition of rlp5 default; create table rlp5_1 partition of rlp5 for values from (31) to (40); explain (costs off) select * from rlp where a < 1; - QUERY PLAN -------------------------- - Append - -> Seq Scan on rlp1 - Filter: (a < 1) -(3 rows) + QUERY PLAN +------------------- + Seq Scan on rlp1 + Filter: (a < 1) +(2 rows) explain (costs off) select * from rlp where 1 > a; /* commuted */ - QUERY PLAN -------------------------- - Append - -> Seq Scan on rlp1 - Filter: (1 > a) -(3 rows) + QUERY PLAN +------------------- + Seq Scan on rlp1 + Filter: (1 > a) +(2 rows) explain (costs off) select * from rlp where a <= 1; QUERY PLAN @@ -218,20 +214,18 @@ explain (costs off) select * from rlp where a <= 1; (5 rows) explain (costs off) select * from rlp where a = 1; - QUERY PLAN -------------------------- - Append - -> Seq Scan on rlp2 - Filter: (a = 1) -(3 rows) + QUERY PLAN +------------------- + Seq Scan on rlp2 + Filter: (a = 1) +(2 rows) explain (costs off) select * from rlp where a = 1::bigint; /* same as above */ - QUERY PLAN ------------------------------------ - Append - -> Seq Scan on rlp2 - Filter: (a = '1'::bigint) -(3 rows) + QUERY PLAN +----------------------------- + Seq Scan on rlp2 + Filter: (a = '1'::bigint) +(2 rows) explain (costs off) select * from rlp where a = 1::numeric; /* no pruning */ QUERY PLAN @@ -384,20 +378,18 @@ explain (costs off) select * from rlp where a = 16; (9 rows) explain (costs off) select * from rlp where a = 16 and b in ('not', 'in', 'here'); - QUERY PLAN ----------------------------------------------------------------------------- - Append - -> Seq Scan on rlp3_default - Filter: ((a = 16) AND ((b)::text = ANY ('{not,in,here}'::text[]))) -(3 rows) + QUERY PLAN +---------------------------------------------------------------------- + Seq Scan on rlp3_default + Filter: ((a = 16) AND ((b)::text = ANY ('{not,in,here}'::text[]))) +(2 rows) explain (costs off) select * from rlp where a = 16 and b < 'ab'; - QUERY PLAN ---------------------------------------------------------- - Append - -> Seq Scan on rlp3_default - Filter: (((b)::text < 'ab'::text) AND (a = 16)) -(3 rows) + QUERY PLAN +--------------------------------------------------- + Seq Scan on rlp3_default + Filter: (((b)::text < 'ab'::text) AND (a = 16)) +(2 rows) explain (costs off) select * from rlp where a = 16 and b <= 'ab'; QUERY PLAN @@ -410,12 +402,11 @@ explain (costs off) select * from rlp where a = 16 and b <= 'ab'; (5 rows) explain (costs off) select * from rlp where a = 16 and b is null; - QUERY PLAN --------------------------------------------- - Append - -> Seq Scan on rlp3nullxy - Filter: ((b IS NULL) AND (a = 16)) -(3 rows) + QUERY PLAN +-------------------------------------- + Seq Scan on rlp3nullxy + Filter: ((b IS NULL) AND (a = 16)) +(2 rows) explain (costs off) select * from rlp where a = 16 and b is not null; QUERY PLAN @@ -432,12 +423,11 @@ explain (costs off) select * from rlp where a = 16 and b is not null; (9 rows) explain (costs off) select * from rlp where a is null; - QUERY PLAN ------------------------------------- - Append - -> Seq Scan on rlp_default_null - Filter: (a IS NULL) -(3 rows) + QUERY PLAN +------------------------------ + Seq Scan on rlp_default_null + Filter: (a IS NULL) +(2 rows) explain (costs off) select * from rlp where a is not null; QUERY PLAN @@ -486,12 +476,11 @@ explain (costs off) select * from rlp where a > 30; (7 rows) explain (costs off) select * from rlp where a = 30; /* only default is scanned */ - QUERY PLAN ----------------------------------- - Append - -> Seq Scan on rlp_default_30 - Filter: (a = 30) -(3 rows) + QUERY PLAN +---------------------------- + Seq Scan on rlp_default_30 + Filter: (a = 30) +(2 rows) explain (costs off) select * from rlp where a <= 31; QUERY PLAN @@ -517,23 +506,20 @@ explain (costs off) select * from rlp where a <= 31; Filter: (a <= 31) -> Seq Scan on rlp5_1 Filter: (a <= 31) - -> Seq Scan on rlp5_default - Filter: (a <= 31) -> Seq Scan on rlp_default_10 Filter: (a <= 31) -> Seq Scan on rlp_default_30 Filter: (a <= 31) -> Seq Scan on rlp_default_default Filter: (a <= 31) -(29 rows) +(27 rows) explain (costs off) select * from rlp where a = 1 or a = 7; - QUERY PLAN --------------------------------------- - Append - -> Seq Scan on rlp2 - Filter: ((a = 1) OR (a = 7)) -(3 rows) + QUERY PLAN +-------------------------------- + Seq Scan on rlp2 + Filter: ((a = 1) OR (a = 7)) +(2 rows) explain (costs off) select * from rlp where a = 1 or b = 'ab'; QUERY PLAN @@ -573,19 +559,14 @@ explain (costs off) select * from rlp where a > 20 and a < 27; Filter: ((a > 20) AND (a < 27)) -> Seq Scan on rlp4_2 Filter: ((a > 20) AND (a < 27)) - -> Seq Scan on rlp4_default - Filter: ((a > 20) AND (a < 27)) - -> Seq Scan on rlp_default_default - Filter: ((a > 20) AND (a < 27)) -(9 rows) +(5 rows) explain (costs off) select * from rlp where a = 29; - QUERY PLAN --------------------------------- - Append - -> Seq Scan on rlp4_default - Filter: (a = 29) -(3 rows) + QUERY PLAN +-------------------------- + Seq Scan on rlp4_default + Filter: (a = 29) +(2 rows) explain (costs off) select * from rlp where a >= 29; QUERY PLAN @@ -603,14 +584,41 @@ explain (costs off) select * from rlp where a >= 29; Filter: (a >= 29) (11 rows) --- redundant clauses are eliminated -explain (costs off) select * from rlp where a > 1 and a = 10; /* only default */ +explain (costs off) select * from rlp where a < 1 or (a > 20 and a < 25); + QUERY PLAN +------------------------------------------------------ + Append + -> Seq Scan on rlp1 + Filter: ((a < 1) OR ((a > 20) AND (a < 25))) + -> Seq Scan on rlp4_1 + Filter: ((a < 1) OR ((a > 20) AND (a < 25))) +(5 rows) + +-- where clause contradicts sub-partition's constraint +explain (costs off) select * from rlp where a = 20 or a = 40; QUERY PLAN ---------------------------------------- Append - -> Seq Scan on rlp_default_10 - Filter: ((a > 1) AND (a = 10)) -(3 rows) + -> Seq Scan on rlp4_1 + Filter: ((a = 20) OR (a = 40)) + -> Seq Scan on rlp5_default + Filter: ((a = 20) OR (a = 40)) +(5 rows) + +explain (costs off) select * from rlp3 where a = 20; /* empty */ + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +-- redundant clauses are eliminated +explain (costs off) select * from rlp where a > 1 and a = 10; /* only default */ + QUERY PLAN +---------------------------------- + Seq Scan on rlp_default_10 + Filter: ((a > 1) AND (a = 10)) +(2 rows) explain (costs off) select * from rlp where a > 1 and a >=15; /* rlp3 onwards, including default */ QUERY PLAN @@ -797,20 +805,18 @@ explain (costs off) select * from mc3p where a <= 10 and abs(b) < 10; (9 rows) explain (costs off) select * from mc3p where a = 11 and abs(b) = 0; - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mc3p_default - Filter: ((a = 11) AND (abs(b) = 0)) -(3 rows) + QUERY PLAN +--------------------------------------- + Seq Scan on mc3p_default + Filter: ((a = 11) AND (abs(b) = 0)) +(2 rows) explain (costs off) select * from mc3p where a = 20 and abs(b) = 10 and c = 100; - QUERY PLAN ------------------------------------------------------------- - Append - -> Seq Scan on mc3p6 - Filter: ((a = 20) AND (c = 100) AND (abs(b) = 10)) -(3 rows) + QUERY PLAN +------------------------------------------------------ + Seq Scan on mc3p6 + Filter: ((a = 20) AND (c = 100) AND (abs(b) = 10)) +(2 rows) explain (costs off) select * from mc3p where a > 20; QUERY PLAN @@ -962,12 +968,11 @@ explain (costs off) select * from mc2p where a < 2; (9 rows) explain (costs off) select * from mc2p where a = 2 and b < 1; - QUERY PLAN ---------------------------------------- - Append - -> Seq Scan on mc2p3 - Filter: ((b < 1) AND (a = 2)) -(3 rows) + QUERY PLAN +--------------------------------- + Seq Scan on mc2p3 + Filter: ((b < 1) AND (a = 2)) +(2 rows) explain (costs off) select * from mc2p where a > 1; QUERY PLAN @@ -986,12 +991,47 @@ explain (costs off) select * from mc2p where a > 1; (11 rows) explain (costs off) select * from mc2p where a = 1 and b > 1; - QUERY PLAN ---------------------------------------- - Append - -> Seq Scan on mc2p2 - Filter: ((b > 1) AND (a = 1)) -(3 rows) + QUERY PLAN +--------------------------------- + Seq Scan on mc2p2 + Filter: ((b > 1) AND (a = 1)) +(2 rows) + +-- all partitions but the default one should be pruned +explain (costs off) select * from mc2p where a = 1 and b is null; + QUERY PLAN +------------------------------------- + Seq Scan on mc2p_default + Filter: ((b IS NULL) AND (a = 1)) +(2 rows) + +explain (costs off) select * from mc2p where a is null and b is null; + QUERY PLAN +----------------------------------------- + Seq Scan on mc2p_default + Filter: ((a IS NULL) AND (b IS NULL)) +(2 rows) + +explain (costs off) select * from mc2p where a is null and b = 1; + QUERY PLAN +------------------------------------- + Seq Scan on mc2p_default + Filter: ((a IS NULL) AND (b = 1)) +(2 rows) + +explain (costs off) select * from mc2p where a is null; + QUERY PLAN +-------------------------- + Seq Scan on mc2p_default + Filter: (a IS NULL) +(2 rows) + +explain (costs off) select * from mc2p where b is null; + QUERY PLAN +-------------------------- + Seq Scan on mc2p_default + Filter: (b IS NULL) +(2 rows) -- boolean partitioning create table boolpart (a bool) partition by list (a); @@ -1009,20 +1049,18 @@ explain (costs off) select * from boolpart where a in (true, false); (5 rows) explain (costs off) select * from boolpart where a = false; - QUERY PLAN ------------------------------- - Append - -> Seq Scan on boolpart_f - Filter: (NOT a) -(3 rows) + QUERY PLAN +------------------------ + Seq Scan on boolpart_f + Filter: (NOT a) +(2 rows) explain (costs off) select * from boolpart where not a = false; - QUERY PLAN ------------------------------- - Append - -> Seq Scan on boolpart_t - Filter: a -(3 rows) + QUERY PLAN +------------------------ + Seq Scan on boolpart_t + Filter: a +(2 rows) explain (costs off) select * from boolpart where a is true or a is not true; QUERY PLAN @@ -1035,12 +1073,11 @@ explain (costs off) select * from boolpart where a is true or a is not true; (5 rows) explain (costs off) select * from boolpart where a is not true; - QUERY PLAN ---------------------------------- - Append - -> Seq Scan on boolpart_f - Filter: (a IS NOT TRUE) -(3 rows) + QUERY PLAN +--------------------------- + Seq Scan on boolpart_f + Filter: (a IS NOT TRUE) +(2 rows) explain (costs off) select * from boolpart where a is not true and a is not false; QUERY PLAN @@ -1073,51 +1110,196 @@ explain (costs off) select * from boolpart where a is not unknown; Filter: (a IS NOT UNKNOWN) (7 rows) --- --- some more cases --- --- --- pruning for partitioned table appearing inside a sub-query --- --- pruning won't work for mc3p, because some keys are Params -explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = t1.b and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1; - QUERY PLAN ------------------------------------------------------------------------ - Nested Loop - -> Append - -> Seq Scan on mc2p1 t1 - Filter: (a = 1) - -> Seq Scan on mc2p2 t1_1 - Filter: (a = 1) - -> Seq Scan on mc2p_default t1_2 - Filter: (a = 1) - -> Aggregate - -> Append - -> Seq Scan on mc3p0 t2 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p1 t2_1 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p2 t2_2 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p3 t2_3 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p4 t2_4 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p5 t2_5 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p6 t2_6 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p7 t2_7 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) - -> Seq Scan on mc3p_default t2_8 - Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) -(28 rows) +create table boolrangep (a bool, b bool, c int) partition by range (a,b,c); +create table boolrangep_tf partition of boolrangep for values from ('true', 'false', 0) to ('true', 'false', 100); +create table boolrangep_ft partition of boolrangep for values from ('false', 'true', 0) to ('false', 'true', 100); +create table boolrangep_ff1 partition of boolrangep for values from ('false', 'false', 0) to ('false', 'false', 50); +create table boolrangep_ff2 partition of boolrangep for values from ('false', 'false', 50) to ('false', 'false', 100); +-- try a more complex case that's been known to trip up pruning in the past +explain (costs off) select * from boolrangep where not a and not b and c = 25; + QUERY PLAN +---------------------------------------------- + Seq Scan on boolrangep_ff1 + Filter: ((NOT a) AND (NOT b) AND (c = 25)) +(2 rows) --- pruning should work fine, because values for a prefix of keys (a, b) are --- available -explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.c = t1.b and abs(t2.b) = 1 and t2.a = 1) s where t1.a = 1; - QUERY PLAN ------------------------------------------------------------------------ +-- test scalar-to-array operators +create table coercepart (a varchar) partition by list (a); +create table coercepart_ab partition of coercepart for values in ('ab'); +create table coercepart_bc partition of coercepart for values in ('bc'); +create table coercepart_cd partition of coercepart for values in ('cd'); +explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------ + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text = ANY ((ARRAY['ab'::character varying, (to_char(125, '999'::text))::character varying])::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text = ANY ((ARRAY['ab'::character varying, (to_char(125, '999'::text))::character varying])::text[])) + -> Seq Scan on coercepart_cd + Filter: ((a)::text = ANY ((ARRAY['ab'::character varying, (to_char(125, '999'::text))::character varying])::text[])) +(7 rows) + +explain (costs off) select * from coercepart where a ~ any ('{ab}'); + QUERY PLAN +---------------------------------------------------- + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text ~ ANY ('{ab}'::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text ~ ANY ('{ab}'::text[])) + -> Seq Scan on coercepart_cd + Filter: ((a)::text ~ ANY ('{ab}'::text[])) +(7 rows) + +explain (costs off) select * from coercepart where a !~ all ('{ab}'); + QUERY PLAN +----------------------------------------------------- + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text !~ ALL ('{ab}'::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text !~ ALL ('{ab}'::text[])) + -> Seq Scan on coercepart_cd + Filter: ((a)::text !~ ALL ('{ab}'::text[])) +(7 rows) + +explain (costs off) select * from coercepart where a ~ any ('{ab,bc}'); + QUERY PLAN +------------------------------------------------------- + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text ~ ANY ('{ab,bc}'::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text ~ ANY ('{ab,bc}'::text[])) + -> Seq Scan on coercepart_cd + Filter: ((a)::text ~ ANY ('{ab,bc}'::text[])) +(7 rows) + +explain (costs off) select * from coercepart where a !~ all ('{ab,bc}'); + QUERY PLAN +-------------------------------------------------------- + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text !~ ALL ('{ab,bc}'::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text !~ ALL ('{ab,bc}'::text[])) + -> Seq Scan on coercepart_cd + Filter: ((a)::text !~ ALL ('{ab,bc}'::text[])) +(7 rows) + +explain (costs off) select * from coercepart where a = any ('{ab,bc}'); + QUERY PLAN +------------------------------------------------------- + Append + -> Seq Scan on coercepart_ab + Filter: ((a)::text = ANY ('{ab,bc}'::text[])) + -> Seq Scan on coercepart_bc + Filter: ((a)::text = ANY ('{ab,bc}'::text[])) +(5 rows) + +explain (costs off) select * from coercepart where a = any ('{ab,null}'); + QUERY PLAN +--------------------------------------------------- + Seq Scan on coercepart_ab + Filter: ((a)::text = ANY ('{ab,NULL}'::text[])) +(2 rows) + +explain (costs off) select * from coercepart where a = any (null::text[]); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +explain (costs off) select * from coercepart where a = all ('{ab}'); + QUERY PLAN +---------------------------------------------- + Seq Scan on coercepart_ab + Filter: ((a)::text = ALL ('{ab}'::text[])) +(2 rows) + +explain (costs off) select * from coercepart where a = all ('{ab,bc}'); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +explain (costs off) select * from coercepart where a = all ('{ab,null}'); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +explain (costs off) select * from coercepart where a = all (null::text[]); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +drop table coercepart; +CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a); +CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2); +CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a); +CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT; +INSERT INTO part VALUES (-1,-1), (1,1), (2,NULL), (NULL,-2),(NULL,NULL); +EXPLAIN (COSTS OFF) SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3; + QUERY PLAN +--------------------------------------------------------------------------- + Sort + Sort Key: ((part_p2_p1.tableoid)::regclass), part_p2_p1.a, part_p2_p1.b + -> Seq Scan on part_p2_p1 + Filter: (a IS NULL) +(4 rows) + +-- +-- some more cases +-- +-- +-- pruning for partitioned table appearing inside a sub-query +-- +-- pruning won't work for mc3p, because some keys are Params +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = t1.b and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1; + QUERY PLAN +----------------------------------------------------------------------- + Nested Loop + -> Append + -> Seq Scan on mc2p1 t1 + Filter: (a = 1) + -> Seq Scan on mc2p2 t1_1 + Filter: (a = 1) + -> Seq Scan on mc2p_default t1_2 + Filter: (a = 1) + -> Aggregate + -> Append + -> Seq Scan on mc3p0 t2 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p1 t2_1 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p2 t2_2 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p3 t2_3 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p4 t2_4 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p5 t2_5 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p6 t2_6 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p7 t2_7 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p_default t2_8 + Filter: ((a = t1.b) AND (c = 1) AND (abs(b) = 1)) +(28 rows) + +-- pruning should work fine, because values for a prefix of keys (a, b) are +-- available +explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.c = t1.b and abs(t2.b) = 1 and t2.a = 1) s where t1.a = 1; + QUERY PLAN +----------------------------------------------------------------------- Nested Loop -> Append -> Seq Scan on mc2p1 t1 @@ -1138,13 +1320,12 @@ explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 -- also here, because values for all keys are provided explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 where t2.a = 1 and abs(t2.b) = 1 and t2.c = 1) s where t1.a = 1; - QUERY PLAN --------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------- Nested Loop -> Aggregate - -> Append - -> Seq Scan on mc3p1 t2 - Filter: ((a = 1) AND (c = 1) AND (abs(b) = 1)) + -> Seq Scan on mc3p1 t2 + Filter: ((a = 1) AND (c = 1) AND (abs(b) = 1)) -> Append -> Seq Scan on mc2p1 t1 Filter: (a = 1) @@ -1152,7 +1333,7 @@ explain (costs off) select * from mc2p t1, lateral (select count(*) from mc3p t2 Filter: (a = 1) -> Seq Scan on mc2p_default t1_2 Filter: (a = 1) -(12 rows) +(11 rows) -- -- pruning with clauses containing <> operator @@ -1273,12 +1454,11 @@ explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'a' co -- pruning, with values provided for both keys explain (costs off) select * from coll_pruning_multi where substr(a, 1) = 'e' collate "C" and substr(a, 1) = 'a' collate "POSIX"; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Append - -> Seq Scan on coll_pruning_multi2 - Filter: ((substr(a, 1) = 'e'::text COLLATE "C") AND (substr(a, 1) = 'a'::text COLLATE "POSIX")) -(3 rows) + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Seq Scan on coll_pruning_multi2 + Filter: ((substr(a, 1) = 'e'::text COLLATE "C") AND (substr(a, 1) = 'a'::text COLLATE "POSIX")) +(2 rows) -- -- LIKE operators don't prune @@ -1323,14 +1503,198 @@ explain (costs off) select * from rparted_by_int2 where a > 100000000000000; create table rparted_by_int2_maxvalue partition of rparted_by_int2 for values from (16384) to (maxvalue); -- all partitions but rparted_by_int2_maxvalue pruned explain (costs off) select * from rparted_by_int2 where a > 100000000000000; + QUERY PLAN +------------------------------------------- + Seq Scan on rparted_by_int2_maxvalue + Filter: (a > '100000000000000'::bigint) +(2 rows) + +drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2; +-- +-- Test Partition pruning for HASH partitioning +-- +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. See the definitions of +-- part_part_test_int4_ops and part_test_text_ops in insert.sql. +-- +create table hp (a int, b text) partition by hash (a part_test_int4_ops, b part_test_text_ops); +create table hp0 partition of hp for values with (modulus 4, remainder 0); +create table hp3 partition of hp for values with (modulus 4, remainder 3); +create table hp1 partition of hp for values with (modulus 4, remainder 1); +create table hp2 partition of hp for values with (modulus 4, remainder 2); +insert into hp values (null, null); +insert into hp values (1, null); +insert into hp values (1, 'xxx'); +insert into hp values (null, 'xxx'); +insert into hp values (2, 'xxx'); +insert into hp values (1, 'abcde'); +select tableoid::regclass, * from hp order by 1; + tableoid | a | b +----------+---+------- + hp0 | | + hp0 | 1 | xxx + hp3 | 2 | xxx + hp1 | 1 | + hp2 | | xxx + hp2 | 1 | abcde +(6 rows) + +-- partial keys won't prune, nor would non-equality conditions +explain (costs off) select * from hp where a = 1; + QUERY PLAN +------------------------- + Append + -> Seq Scan on hp0 + Filter: (a = 1) + -> Seq Scan on hp1 + Filter: (a = 1) + -> Seq Scan on hp2 + Filter: (a = 1) + -> Seq Scan on hp3 + Filter: (a = 1) +(9 rows) + +explain (costs off) select * from hp where b = 'xxx'; + QUERY PLAN +----------------------------------- + Append + -> Seq Scan on hp0 + Filter: (b = 'xxx'::text) + -> Seq Scan on hp1 + Filter: (b = 'xxx'::text) + -> Seq Scan on hp2 + Filter: (b = 'xxx'::text) + -> Seq Scan on hp3 + Filter: (b = 'xxx'::text) +(9 rows) + +explain (costs off) select * from hp where a is null; + QUERY PLAN +----------------------------- + Append + -> Seq Scan on hp0 + Filter: (a IS NULL) + -> Seq Scan on hp1 + Filter: (a IS NULL) + -> Seq Scan on hp2 + Filter: (a IS NULL) + -> Seq Scan on hp3 + Filter: (a IS NULL) +(9 rows) + +explain (costs off) select * from hp where b is null; + QUERY PLAN +----------------------------- + Append + -> Seq Scan on hp0 + Filter: (b IS NULL) + -> Seq Scan on hp1 + Filter: (b IS NULL) + -> Seq Scan on hp2 + Filter: (b IS NULL) + -> Seq Scan on hp3 + Filter: (b IS NULL) +(9 rows) + +explain (costs off) select * from hp where a < 1 and b = 'xxx'; QUERY PLAN ------------------------------------------------- Append - -> Seq Scan on rparted_by_int2_maxvalue - Filter: (a > '100000000000000'::bigint) -(3 rows) + -> Seq Scan on hp0 + Filter: ((a < 1) AND (b = 'xxx'::text)) + -> Seq Scan on hp1 + Filter: ((a < 1) AND (b = 'xxx'::text)) + -> Seq Scan on hp2 + Filter: ((a < 1) AND (b = 'xxx'::text)) + -> Seq Scan on hp3 + Filter: ((a < 1) AND (b = 'xxx'::text)) +(9 rows) + +explain (costs off) select * from hp where a <> 1 and b = 'yyy'; + QUERY PLAN +-------------------------------------------------- + Append + -> Seq Scan on hp0 + Filter: ((a <> 1) AND (b = 'yyy'::text)) + -> Seq Scan on hp1 + Filter: ((a <> 1) AND (b = 'yyy'::text)) + -> Seq Scan on hp2 + Filter: ((a <> 1) AND (b = 'yyy'::text)) + -> Seq Scan on hp3 + Filter: ((a <> 1) AND (b = 'yyy'::text)) +(9 rows) + +explain (costs off) select * from hp where a <> 1 and b <> 'xxx'; + QUERY PLAN +--------------------------------------------------- + Append + -> Seq Scan on hp0 + Filter: ((a <> 1) AND (b <> 'xxx'::text)) + -> Seq Scan on hp1 + Filter: ((a <> 1) AND (b <> 'xxx'::text)) + -> Seq Scan on hp2 + Filter: ((a <> 1) AND (b <> 'xxx'::text)) + -> Seq Scan on hp3 + Filter: ((a <> 1) AND (b <> 'xxx'::text)) +(9 rows) + +-- pruning should work if either a value or a IS NULL clause is provided for +-- each of the keys +explain (costs off) select * from hp where a is null and b is null; + QUERY PLAN +----------------------------------------- + Seq Scan on hp0 + Filter: ((a IS NULL) AND (b IS NULL)) +(2 rows) + +explain (costs off) select * from hp where a = 1 and b is null; + QUERY PLAN +------------------------------------- + Seq Scan on hp1 + Filter: ((b IS NULL) AND (a = 1)) +(2 rows) + +explain (costs off) select * from hp where a = 1 and b = 'xxx'; + QUERY PLAN +------------------------------------------- + Seq Scan on hp0 + Filter: ((a = 1) AND (b = 'xxx'::text)) +(2 rows) + +explain (costs off) select * from hp where a is null and b = 'xxx'; + QUERY PLAN +----------------------------------------------- + Seq Scan on hp2 + Filter: ((a IS NULL) AND (b = 'xxx'::text)) +(2 rows) + +explain (costs off) select * from hp where a = 2 and b = 'xxx'; + QUERY PLAN +------------------------------------------- + Seq Scan on hp3 + Filter: ((a = 2) AND (b = 'xxx'::text)) +(2 rows) + +explain (costs off) select * from hp where a = 1 and b = 'abcde'; + QUERY PLAN +--------------------------------------------- + Seq Scan on hp2 + Filter: ((a = 1) AND (b = 'abcde'::text)) +(2 rows) + +explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Append + -> Seq Scan on hp0 + Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) + -> Seq Scan on hp2 + Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) + -> Seq Scan on hp3 + Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) +(7 rows) -drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2; +drop table hp; -- -- Test runtime partition pruning -- @@ -1353,33 +1717,6 @@ create table ab_a3_b3 partition of ab_a3 for values in (3); set enable_indexonlyscan = off; prepare ab_q1 (int, int, int) as select * from ab where a between $1 and $2 and b <= $3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q1 (1, 8, 3); - a | b ----+--- -(0 rows) - -execute ab_q1 (1, 8, 3); - a | b ----+--- -(0 rows) - -execute ab_q1 (1, 8, 3); - a | b ----+--- -(0 rows) - -execute ab_q1 (1, 8, 3); - a | b ----+--- -(0 rows) - -execute ab_q1 (1, 8, 3); - a | b ----+--- -(0 rows) - explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3); QUERY PLAN --------------------------------------------------------- @@ -1416,33 +1753,6 @@ deallocate ab_q1; -- Runtime pruning after optimizer pruning prepare ab_q1 (int, int) as select a from ab where a between $1 and $2 and b < 3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q1 (1, 8); - a ---- -(0 rows) - -execute ab_q1 (1, 8); - a ---- -(0 rows) - -execute ab_q1 (1, 8); - a ---- -(0 rows) - -execute ab_q1 (1, 8); - a ---- -(0 rows) - -execute ab_q1 (1, 8); - a ---- -(0 rows) - explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2); QUERY PLAN ------------------------------------------------------- @@ -1469,35 +1779,10 @@ explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4); Filter: ((a >= $1) AND (a <= $2) AND (b < 3)) (10 rows) --- Ensure a mix of external and exec params work together at different --- levels of partitioning. +-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at +-- different levels of partitioning. prepare ab_q2 (int, int) as select a from ab where a between $1 and $2 and b < (select 3); -execute ab_q2 (1, 8); - a ---- -(0 rows) - -execute ab_q2 (1, 8); - a ---- -(0 rows) - -execute ab_q2 (1, 8); - a ---- -(0 rows) - -execute ab_q2 (1, 8); - a ---- -(0 rows) - -execute ab_q2 (1, 8); - a ---- -(0 rows) - explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2); QUERY PLAN -------------------------------------------------------- @@ -1513,34 +1798,9 @@ explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2); Filter: ((a >= $1) AND (a <= $2) AND (b < $0)) (10 rows) --- As above, but with swap the exec param to the first partition level +-- As above, but swap the PARAM_EXEC Param to the first partition level prepare ab_q3 (int, int) as select a from ab where b between $1 and $2 and a < (select 3); -execute ab_q3 (1, 8); - a ---- -(0 rows) - -execute ab_q3 (1, 8); - a ---- -(0 rows) - -execute ab_q3 (1, 8); - a ---- -(0 rows) - -execute ab_q3 (1, 8); - a ---- -(0 rows) - -execute ab_q3 (1, 8); - a ---- -(0 rows) - explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2); QUERY PLAN -------------------------------------------------------- @@ -1556,7 +1816,102 @@ explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2); Filter: ((b >= $1) AND (b <= $2) AND (a < $0)) (10 rows) +-- Test a backwards Append scan +create table list_part (a int) partition by list (a); +create table list_part1 partition of list_part for values in (1); +create table list_part2 partition of list_part for values in (2); +create table list_part3 partition of list_part for values in (3); +create table list_part4 partition of list_part for values in (4); +insert into list_part select generate_series(1,4); +begin; +-- Don't select an actual value out of the table as the order of the Append's +-- subnodes may not be stable. +declare cur SCROLL CURSOR for select 1 from list_part where a > (select 1) and a < (select 4); +-- move beyond the final row +move 3 from cur; +-- Ensure we get two rows. +fetch backward all from cur; + ?column? +---------- + 1 + 1 +(2 rows) + +commit; +begin; +-- Test run-time pruning using stable functions +create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable; +-- Ensure pruning works using a stable function containing no Vars +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1); + QUERY PLAN +------------------------------------------------------ + Append (actual rows=1 loops=1) + Subplans Removed: 3 + -> Seq Scan on list_part1 (actual rows=1 loops=1) + Filter: (a = list_part_fn(1)) +(4 rows) + +-- Ensure pruning does not take place when the function has a Var parameter +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a); + QUERY PLAN +------------------------------------------------------ + Append (actual rows=4 loops=1) + -> Seq Scan on list_part1 (actual rows=1 loops=1) + Filter: (a = list_part_fn(a)) + -> Seq Scan on list_part2 (actual rows=1 loops=1) + Filter: (a = list_part_fn(a)) + -> Seq Scan on list_part3 (actual rows=1 loops=1) + Filter: (a = list_part_fn(a)) + -> Seq Scan on list_part4 (actual rows=1 loops=1) + Filter: (a = list_part_fn(a)) +(9 rows) + +-- Ensure pruning does not take place when the expression contains a Var. +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a; + QUERY PLAN +------------------------------------------------------ + Append (actual rows=0 loops=1) + -> Seq Scan on list_part1 (actual rows=0 loops=1) + Filter: (a = (list_part_fn(1) + a)) + Rows Removed by Filter: 1 + -> Seq Scan on list_part2 (actual rows=0 loops=1) + Filter: (a = (list_part_fn(1) + a)) + Rows Removed by Filter: 1 + -> Seq Scan on list_part3 (actual rows=0 loops=1) + Filter: (a = (list_part_fn(1) + a)) + Rows Removed by Filter: 1 + -> Seq Scan on list_part4 (actual rows=0 loops=1) + Filter: (a = (list_part_fn(1) + a)) + Rows Removed by Filter: 1 +(13 rows) + +rollback; +drop table list_part; -- Parallel append +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see '(never executed)' +-- notations because that's the only way to verify runtime pruning. +create function explain_parallel_append(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + return next ln; + end loop; +end; +$$; prepare ab_q4 (int, int) as select avg(a) from ab where a between $1 and $2 and b < 4; -- Encourage use of parallel plans @@ -1564,150 +1919,108 @@ set parallel_setup_cost = 0; set parallel_tuple_cost = 0; set min_parallel_table_scan_size = 0; set max_parallel_workers_per_gather = 2; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q4 (1, 8); - avg ------ - -(1 row) - -execute ab_q4 (1, 8); - avg ------ - -(1 row) - -execute ab_q4 (1, 8); - avg ------ - -(1 row) - -execute ab_q4 (1, 8); - avg ------ - -(1 row) - -execute ab_q4 (1, 8); - avg ------ - -(1 row) - -explain (analyze, costs off, summary off, timing off) execute ab_q4 (2, 2); - QUERY PLAN +select explain_parallel_append('execute ab_q4 (2, 2)'); + explain_parallel_append ------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=3 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 2 - Workers Launched: 2 - -> Partial Aggregate (actual rows=1 loops=3) - -> Parallel Append (actual rows=0 loops=3) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Parallel Append (actual rows=N loops=N) Subplans Removed: 6 - -> Parallel Seq Scan on ab_a2_b1 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b1 (actual rows=N loops=N) Filter: ((a >= $1) AND (a <= $2) AND (b < 4)) - -> Parallel Seq Scan on ab_a2_b2 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b2 (actual rows=N loops=N) Filter: ((a >= $1) AND (a <= $2) AND (b < 4)) - -> Parallel Seq Scan on ab_a2_b3 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b3 (actual rows=N loops=N) Filter: ((a >= $1) AND (a <= $2) AND (b < 4)) (13 rows) -- Test run-time pruning with IN lists. prepare ab_q5 (int, int, int) as select avg(a) from ab where a in($1,$2,$3) and b < 4; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q5 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q5 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q5 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q5 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q5 (1, 2, 3); - avg ------ - -(1 row) - -explain (analyze, costs off, summary off, timing off) execute ab_q5 (1, 1, 1); - QUERY PLAN +select explain_parallel_append('execute ab_q5 (1, 1, 1)'); + explain_parallel_append ------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=3 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 2 - Workers Launched: 2 - -> Partial Aggregate (actual rows=1 loops=3) - -> Parallel Append (actual rows=0 loops=3) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Parallel Append (actual rows=N loops=N) Subplans Removed: 6 - -> Parallel Seq Scan on ab_a1_b1 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a1_b1 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a1_b2 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a1_b2 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a1_b3 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a1_b3 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) (13 rows) -explain (analyze, costs off, summary off, timing off) execute ab_q5 (2, 3, 3); - QUERY PLAN +select explain_parallel_append('execute ab_q5 (2, 3, 3)'); + explain_parallel_append ------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=3 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 2 - Workers Launched: 2 - -> Partial Aggregate (actual rows=1 loops=3) - -> Parallel Append (actual rows=0 loops=3) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Parallel Append (actual rows=N loops=N) Subplans Removed: 3 - -> Parallel Seq Scan on ab_a2_b1 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b1 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a2_b2 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b2 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a2_b3 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a2_b3 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a3_b1 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a3_b1 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a3_b2 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a3_b2 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) - -> Parallel Seq Scan on ab_a3_b3 (actual rows=0 loops=1) + -> Parallel Seq Scan on ab_a3_b3 (actual rows=N loops=N) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) (19 rows) -- Try some params whose values do not belong to any partition. -- We'll still get a single subplan in this case, but it should not be scanned. -explain (analyze, costs off, summary off, timing off) execute ab_q5 (33, 44, 55); - QUERY PLAN +select explain_parallel_append('execute ab_q5 (33, 44, 55)'); + explain_parallel_append ------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=3 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 2 - Workers Launched: 2 - -> Partial Aggregate (actual rows=1 loops=3) - -> Parallel Append (actual rows=0 loops=3) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Parallel Append (actual rows=N loops=N) Subplans Removed: 8 -> Parallel Seq Scan on ab_a1_b1 (never executed) Filter: ((b < 4) AND (a = ANY (ARRAY[$1, $2, $3]))) (9 rows) --- Test parallel Append with IN list and parameterized nested loops +-- Test Parallel Append with PARAM_EXEC Params +select explain_parallel_append('select count(*) from ab where (a = (select 1) or a = (select 3)) and b = 2'); + explain_parallel_append +------------------------------------------------------------------------- + Aggregate (actual rows=N loops=N) + InitPlan 1 (returns $0) + -> Result (actual rows=N loops=N) + InitPlan 2 (returns $1) + -> Result (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 2 + Params Evaluated: $0, $1 + Workers Launched: N + -> Parallel Append (actual rows=N loops=N) + -> Parallel Seq Scan on ab_a1_b2 (actual rows=N loops=N) + Filter: ((b = 2) AND ((a = $0) OR (a = $1))) + -> Parallel Seq Scan on ab_a2_b2 (never executed) + Filter: ((b = 2) AND ((a = $0) OR (a = $1))) + -> Parallel Seq Scan on ab_a3_b2 (actual rows=N loops=N) + Filter: ((b = 2) AND ((a = $0) OR (a = $1))) +(16 rows) + +-- Test pruning during parallel nested loop query create table lprt_a (a int not null); -- Insert some values we won't find in ab insert into lprt_a select 0 from generate_series(1,100); @@ -1725,55 +2038,23 @@ create index ab_a3_b2_a_idx on ab_a3_b2 (a); create index ab_a3_b3_a_idx on ab_a3_b3 (a); set enable_hashjoin = 0; set enable_mergejoin = 0; -prepare ab_q6 (int, int, int) as -select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in($1,$2,$3); -execute ab_q6 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q6 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q6 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q6 (1, 2, 3); - avg ------ - -(1 row) - -execute ab_q6 (1, 2, 3); - avg ------ - -(1 row) - -explain (analyze, costs off, summary off, timing off) execute ab_q6 (0, 0, 1); - QUERY PLAN +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(0, 0, 1)'); + explain_parallel_append --------------------------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=2 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 1 - Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - -> Nested Loop (actual rows=0 loops=2) - -> Parallel Seq Scan on lprt_a a (actual rows=51 loops=2) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Nested Loop (actual rows=N loops=N) + -> Parallel Seq Scan on lprt_a a (actual rows=N loops=N) Filter: (a = ANY ('{0,0,1}'::integer[])) - -> Append (actual rows=0 loops=102) - -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=0 loops=2) + -> Append (actual rows=N loops=N) + -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=N loops=N) Index Cond: (a = a.a) -> Index Scan using ab_a2_b1_a_idx on ab_a2_b1 (never executed) Index Cond: (a = a.a) @@ -1789,24 +2070,58 @@ explain (analyze, costs off, summary off, timing off) execute ab_q6 (0, 0, 1); Index Cond: (a = a.a) (27 rows) +-- Ensure the same partitions are pruned when we make the nested loop +-- parameter an Expr rather than a plain Param. +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a + 0 where a.a in(0, 0, 1)'); + explain_parallel_append +--------------------------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) + Workers Planned: 1 + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Nested Loop (actual rows=N loops=N) + -> Parallel Seq Scan on lprt_a a (actual rows=N loops=N) + Filter: (a = ANY ('{0,0,1}'::integer[])) + -> Append (actual rows=N loops=N) + -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=N loops=N) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=N loops=N) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=N loops=N) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a2_b1_a_idx on ab_a2_b1 (never executed) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a2_b2_a_idx on ab_a2_b2 (never executed) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a2_b3_a_idx on ab_a2_b3 (never executed) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a3_b1_a_idx on ab_a3_b1 (never executed) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a3_b2_a_idx on ab_a3_b2 (never executed) + Index Cond: (a = (a.a + 0)) + -> Index Scan using ab_a3_b3_a_idx on ab_a3_b3 (never executed) + Index Cond: (a = (a.a + 0)) +(27 rows) + insert into lprt_a values(3),(3); -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 3); - QUERY PLAN +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 3)'); + explain_parallel_append --------------------------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=2 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 1 - Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - -> Nested Loop (actual rows=0 loops=2) - -> Parallel Seq Scan on lprt_a a (actual rows=52 loops=2) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Nested Loop (actual rows=N loops=N) + -> Parallel Seq Scan on lprt_a a (actual rows=N loops=N) Filter: (a = ANY ('{1,0,3}'::integer[])) - -> Append (actual rows=0 loops=104) - -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=0 loops=2) + -> Append (actual rows=N loops=N) + -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=N loops=N) Index Cond: (a = a.a) -> Index Scan using ab_a2_b1_a_idx on ab_a2_b1 (never executed) Index Cond: (a = a.a) @@ -1814,32 +2129,32 @@ explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 3); Index Cond: (a = a.a) -> Index Scan using ab_a2_b3_a_idx on ab_a2_b3 (never executed) Index Cond: (a = a.a) - -> Index Scan using ab_a3_b1_a_idx on ab_a3_b1 (actual rows=0 loops=2) + -> Index Scan using ab_a3_b1_a_idx on ab_a3_b1 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a3_b2_a_idx on ab_a3_b2 (actual rows=0 loops=2) + -> Index Scan using ab_a3_b2_a_idx on ab_a3_b2 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a3_b3_a_idx on ab_a3_b3 (actual rows=0 loops=2) + -> Index Scan using ab_a3_b3_a_idx on ab_a3_b3 (actual rows=N loops=N) Index Cond: (a = a.a) (27 rows) -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 0); - QUERY PLAN +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); + explain_parallel_append --------------------------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=2 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 1 - Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - -> Nested Loop (actual rows=0 loops=2) - -> Parallel Seq Scan on lprt_a a (actual rows=51 loops=2) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Nested Loop (actual rows=N loops=N) + -> Parallel Seq Scan on lprt_a a (actual rows=N loops=N) Filter: (a = ANY ('{1,0,0}'::integer[])) Rows Removed by Filter: 1 - -> Append (actual rows=0 loops=102) - -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=0 loops=2) + -> Append (actual rows=N loops=N) + -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (actual rows=N loops=N) Index Cond: (a = a.a) - -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=0 loops=2) + -> Index Scan using ab_a1_b3_a_idx on ab_a1_b3 (actual rows=N loops=N) Index Cond: (a = a.a) -> Index Scan using ab_a2_b1_a_idx on ab_a2_b1 (never executed) Index Cond: (a = a.a) @@ -1856,19 +2171,19 @@ explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 0); (28 rows) delete from lprt_a where a = 1; -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 0); - QUERY PLAN +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); + explain_parallel_append -------------------------------------------------------------------------------------------- - Finalize Aggregate (actual rows=1 loops=1) - -> Gather (actual rows=2 loops=1) + Finalize Aggregate (actual rows=N loops=N) + -> Gather (actual rows=N loops=N) Workers Planned: 1 - Workers Launched: 1 - -> Partial Aggregate (actual rows=1 loops=2) - -> Nested Loop (actual rows=0 loops=2) - -> Parallel Seq Scan on lprt_a a (actual rows=50 loops=2) + Workers Launched: N + -> Partial Aggregate (actual rows=N loops=N) + -> Nested Loop (actual rows=N loops=N) + -> Parallel Seq Scan on lprt_a a (actual rows=N loops=N) Filter: (a = ANY ('{1,0,0}'::integer[])) Rows Removed by Filter: 1 - -> Append (actual rows=0 loops=100) + -> Append (actual rows=N loops=N) -> Index Scan using ab_a1_b1_a_idx on ab_a1_b1 (never executed) Index Cond: (a = a.a) -> Index Scan using ab_a1_b2_a_idx on ab_a1_b2 (never executed) @@ -1954,12 +2269,282 @@ select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 Index Cond: (a = $0) (52 rows) +-- Test run-time partition pruning with UNION ALL parents +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1); + QUERY PLAN +------------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=0 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 ab_a1_b1_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b2 ab_a1_b2_1 (never executed) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b2_a_idx (never executed) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b3 ab_a1_b3_1 (never executed) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b3_a_idx (never executed) + Index Cond: (a = 1) + -> Seq Scan on ab_a1_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a1_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a1_b3 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a2_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b3 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a3_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a3_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a3_b3 (never executed) + Filter: (b = $0) +(37 rows) + +-- A case containing a UNION ALL with a non-partitioned child. +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1); + QUERY PLAN +------------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Append (actual rows=0 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 ab_a1_b1_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b2 ab_a1_b2_1 (never executed) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b2_a_idx (never executed) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b3 ab_a1_b3_1 (never executed) + Recheck Cond: (a = 1) + Filter: (b = $0) + -> Bitmap Index Scan on ab_a1_b3_a_idx (never executed) + Index Cond: (a = 1) + -> Result (actual rows=0 loops=1) + One-Time Filter: (5 = $0) + -> Seq Scan on ab_a1_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a1_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a1_b3 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a2_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b3 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a3_b1 (actual rows=0 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a3_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a3_b3 (never executed) + Filter: (b = $0) +(39 rows) + +-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning. +create table xy_1 (x int, y int); +insert into xy_1 values(100,-10); +set enable_bitmapscan = 0; +set enable_indexscan = 0; +prepare ab_q6 as +select * from ( + select tableoid::regclass,a,b from ab +union all + select tableoid::regclass,x,y from xy_1 +union all + select tableoid::regclass,a,b from ab +) ab where a = $1 and b = (select -10); +-- Ensure the xy_1 subplan is not pruned. +explain (analyze, costs off, summary off, timing off) execute ab_q6(1); + QUERY PLAN +-------------------------------------------------------- + Append (actual rows=0 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + Subplans Removed: 12 + -> Seq Scan on ab_a1_b1 (never executed) + Filter: ((a = $1) AND (b = $0)) + -> Seq Scan on ab_a1_b2 (never executed) + Filter: ((a = $1) AND (b = $0)) + -> Seq Scan on ab_a1_b3 (never executed) + Filter: ((a = $1) AND (b = $0)) + -> Seq Scan on xy_1 (actual rows=0 loops=1) + Filter: ((x = $1) AND (y = $0)) + Rows Removed by Filter: 1 + -> Seq Scan on ab_a1_b1 ab_a1_b1_1 (never executed) + Filter: ((a = $1) AND (b = $0)) + -> Seq Scan on ab_a1_b2 ab_a1_b2_1 (never executed) + Filter: ((a = $1) AND (b = $0)) + -> Seq Scan on ab_a1_b3 ab_a1_b3_1 (never executed) + Filter: ((a = $1) AND (b = $0)) +(19 rows) + +-- Ensure we see just the xy_1 row. +execute ab_q6(100); + tableoid | a | b +----------+-----+----- + xy_1 | 100 | -10 +(1 row) + +reset enable_bitmapscan; +reset enable_indexscan; deallocate ab_q1; deallocate ab_q2; deallocate ab_q3; deallocate ab_q4; deallocate ab_q5; deallocate ab_q6; +-- UPDATE on a partition subtree has been seen to have problems. +insert into ab values (1,2); +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a; + QUERY PLAN +------------------------------------------------------------------------------------- + Update on ab_a1 (actual rows=0 loops=1) + Update on ab_a1_b1 + Update on ab_a1_b2 + Update on ab_a1_b3 + -> Nested Loop (actual rows=0 loops=1) + -> Append (actual rows=1 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 ab_a1_b1_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b2 ab_a1_b2_1 (actual rows=1 loops=1) + Recheck Cond: (a = 1) + Heap Blocks: exact=1 + -> Bitmap Index Scan on ab_a1_b2_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b3 ab_a1_b3_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Materialize (actual rows=0 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Nested Loop (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 ab_a1_b1_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b2 ab_a1_b2_1 (actual rows=1 loops=1) + Recheck Cond: (a = 1) + Heap Blocks: exact=1 + -> Bitmap Index Scan on ab_a1_b2_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b3 ab_a1_b3_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Materialize (actual rows=1 loops=1) + -> Bitmap Heap Scan on ab_a1_b2 (actual rows=1 loops=1) + Recheck Cond: (a = 1) + Heap Blocks: exact=1 + -> Bitmap Index Scan on ab_a1_b2_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Nested Loop (actual rows=0 loops=1) + -> Append (actual rows=1 loops=1) + -> Bitmap Heap Scan on ab_a1_b1 ab_a1_b1_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b1_a_idx (actual rows=0 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b2 ab_a1_b2_1 (actual rows=1 loops=1) + Recheck Cond: (a = 1) + Heap Blocks: exact=1 + -> Bitmap Index Scan on ab_a1_b2_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Bitmap Heap Scan on ab_a1_b3 ab_a1_b3_1 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) + -> Materialize (actual rows=0 loops=1) + -> Bitmap Heap Scan on ab_a1_b3 (actual rows=0 loops=1) + Recheck Cond: (a = 1) + -> Bitmap Index Scan on ab_a1_b3_a_idx (actual rows=1 loops=1) + Index Cond: (a = 1) +(65 rows) + +table ab; + a | b +---+--- + 1 | 3 +(1 row) + +-- Test UPDATE where source relation has run-time pruning enabled +truncate ab; +insert into ab values (1, 1), (1, 2), (1, 3), (2, 1); +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab_a2 where ab_a2.b = (select 1); + QUERY PLAN +---------------------------------------------------------------------- + Update on ab_a1 (actual rows=0 loops=1) + Update on ab_a1_b1 + Update on ab_a1_b2 + Update on ab_a1_b3 + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Nested Loop (actual rows=1 loops=1) + -> Seq Scan on ab_a1_b1 (actual rows=1 loops=1) + -> Materialize (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on ab_a2_b1 (actual rows=1 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a2_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b3 (never executed) + Filter: (b = $0) + -> Nested Loop (actual rows=1 loops=1) + -> Seq Scan on ab_a1_b2 (actual rows=1 loops=1) + -> Materialize (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on ab_a2_b1 (actual rows=1 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a2_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b3 (never executed) + Filter: (b = $0) + -> Nested Loop (actual rows=1 loops=1) + -> Seq Scan on ab_a1_b3 (actual rows=1 loops=1) + -> Materialize (actual rows=1 loops=1) + -> Append (actual rows=1 loops=1) + -> Seq Scan on ab_a2_b1 (actual rows=1 loops=1) + Filter: (b = $0) + -> Seq Scan on ab_a2_b2 (never executed) + Filter: (b = $0) + -> Seq Scan on ab_a2_b3 (never executed) + Filter: (b = $0) +(36 rows) + +select tableoid::regclass, * from ab; + tableoid | a | b +----------+---+--- + ab_a1_b3 | 1 | 3 + ab_a1_b3 | 1 | 3 + ab_a1_b3 | 1 | 3 + ab_a2_b1 | 2 | 1 +(4 rows) + drop table ab, lprt_a; -- Join create table tbl1(col1 int); @@ -1989,17 +2574,17 @@ select * from tbl1 join tprt on tbl1.col1 > tprt.col1; -> Seq Scan on tbl1 (actual rows=2 loops=1) -> Append (actual rows=3 loops=2) -> Index Scan using tprt1_idx on tprt_1 (actual rows=2 loops=2) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt2_idx on tprt_2 (actual rows=2 loops=1) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt3_idx on tprt_3 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt4_idx on tprt_4 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt5_idx on tprt_5 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt6_idx on tprt_6 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) (15 rows) explain (analyze, costs off, summary off, timing off) @@ -2055,17 +2640,17 @@ select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1; -> Seq Scan on tbl1 (actual rows=5 loops=1) -> Append (actual rows=5 loops=5) -> Index Scan using tprt1_idx on tprt_1 (actual rows=2 loops=5) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt2_idx on tprt_2 (actual rows=3 loops=4) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt3_idx on tprt_3 (actual rows=1 loops=2) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt4_idx on tprt_4 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt5_idx on tprt_5 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) -> Index Scan using tprt6_idx on tprt_6 (never executed) - Index Cond: (tbl1.col1 > col1) + Index Cond: (col1 < tbl1.col1) (15 rows) explain (analyze, costs off, summary off, timing off) @@ -2140,17 +2725,17 @@ select * from tbl1 join tprt on tbl1.col1 < tprt.col1; -> Seq Scan on tbl1 (actual rows=1 loops=1) -> Append (actual rows=1 loops=1) -> Index Scan using tprt1_idx on tprt_1 (never executed) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) -> Index Scan using tprt2_idx on tprt_2 (never executed) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) -> Index Scan using tprt3_idx on tprt_3 (never executed) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) -> Index Scan using tprt4_idx on tprt_4 (never executed) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) -> Index Scan using tprt5_idx on tprt_5 (never executed) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) -> Index Scan using tprt6_idx on tprt_6 (actual rows=1 loops=1) - Index Cond: (tbl1.col1 < col1) + Index Cond: (col1 > tbl1.col1) (15 rows) select tbl1.col1, tprt.col1 from tbl1 @@ -2203,41 +2788,13 @@ alter table part_bac attach partition part_cab for values in(2); alter table part_cab attach partition part_abc_p1 for values in(3); prepare part_abc_q1 (int, int, int) as select * from part_abc where a = $1 and b = $2 and c = $3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute part_abc_q1 (1, 2, 3); - a | b | c ----+---+--- -(0 rows) - -execute part_abc_q1 (1, 2, 3); - a | b | c ----+---+--- -(0 rows) - -execute part_abc_q1 (1, 2, 3); - a | b | c ----+---+--- -(0 rows) - -execute part_abc_q1 (1, 2, 3); - a | b | c ----+---+--- -(0 rows) - -execute part_abc_q1 (1, 2, 3); - a | b | c ----+---+--- -(0 rows) - -- Single partition should be scanned. explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3); - QUERY PLAN -------------------------------------------------------- - Append (actual rows=0 loops=1) - -> Seq Scan on part_abc_p1 (actual rows=0 loops=1) - Filter: ((a = $1) AND (b = $2) AND (c = $3)) -(3 rows) + QUERY PLAN +------------------------------------------------- + Seq Scan on part_abc_p1 (actual rows=0 loops=1) + Filter: ((a = $1) AND (b = $2) AND (c = $3)) +(2 rows) deallocate part_abc_q1; drop table part_abc; @@ -2257,31 +2814,6 @@ select * from listp where b = 1; -- partitions before finally detecting the correct set of 2nd level partitions -- which match the given parameter. prepare q1 (int,int) as select * from listp where b in ($1,$2); -execute q1 (1,2); - a | b ----+--- -(0 rows) - -execute q1 (1,2); - a | b ----+--- -(0 rows) - -execute q1 (1,2); - a | b ----+--- -(0 rows) - -execute q1 (1,2); - a | b ----+--- -(0 rows) - -execute q1 (1,2); - a | b ----+--- -(0 rows) - explain (analyze, costs off, summary off, timing off) execute q1 (1,1); QUERY PLAN ----------------------------------------------------- @@ -2314,31 +2846,6 @@ explain (analyze, costs off, summary off, timing off) execute q1 (0,0); deallocate q1; -- Test more complex cases where a not-equal condition further eliminates partitions. prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b; -execute q1 (1,2,3,4); - a | b ----+--- -(0 rows) - -execute q1 (1,2,3,4); - a | b ----+--- -(0 rows) - -execute q1 (1,2,3,4); - a | b ----+--- -(0 rows) - -execute q1 (1,2,3,4); - a | b ----+--- -(0 rows) - -execute q1 (1,2,3,4); - a | b ----+--- -(0 rows) - -- Both partitions allowed by IN clause, but one disallowed by <> clause explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0); QUERY PLAN @@ -2360,7 +2867,186 @@ explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1); Filter: ((b = ANY (ARRAY[$1, $2])) AND ($3 <> b) AND ($4 <> b)) (4 rows) +-- Ensure Params that evaluate to NULL properly prune away all partitions +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select null::int); + QUERY PLAN +---------------------------------------------- + Append (actual rows=0 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + -> Seq Scan on listp_1_1 (never executed) + Filter: (a = $0) + -> Seq Scan on listp_2_1 (never executed) + Filter: (a = $0) +(7 rows) + drop table listp; +-- +-- check that stable query clauses are only used in run-time pruning +-- +create table stable_qual_pruning (a timestamp) partition by range (a); +create table stable_qual_pruning1 partition of stable_qual_pruning + for values from ('2000-01-01') to ('2000-02-01'); +create table stable_qual_pruning2 partition of stable_qual_pruning + for values from ('2000-02-01') to ('2000-03-01'); +create table stable_qual_pruning3 partition of stable_qual_pruning + for values from ('3000-02-01') to ('3000-03-01'); +-- comparison against a stable value requires run-time pruning +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < localtimestamp; + QUERY PLAN +---------------------------------------------------------------- + Append (actual rows=0 loops=1) + Subplans Removed: 1 + -> Seq Scan on stable_qual_pruning1 (actual rows=0 loops=1) + Filter: (a < LOCALTIMESTAMP) + -> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1) + Filter: (a < LOCALTIMESTAMP) +(6 rows) + +-- timestamp < timestamptz comparison is only stable, not immutable +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < '2000-02-01'::timestamptz; + QUERY PLAN +-------------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + Subplans Removed: 2 + -> Seq Scan on stable_qual_pruning1 (actual rows=0 loops=1) + Filter: (a < 'Tue Feb 01 00:00:00 2000 PST'::timestamp with time zone) +(4 rows) + +-- check ScalarArrayOp cases +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamp[]); + QUERY PLAN +-------------------------------- + Result (actual rows=0 loops=1) + One-Time Filter: false +(2 rows) + +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamp[]); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1) + Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000","Fri Jan 01 00:00:00 2010"}'::timestamp without time zone[])) +(2 rows) + +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', localtimestamp]::timestamp[]); + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Append (actual rows=0 loops=1) + Subplans Removed: 2 + -> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1) + Filter: (a = ANY (ARRAY['Tue Feb 01 00:00:00 2000'::timestamp without time zone, LOCALTIMESTAMP])) +(4 rows) + +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + Subplans Removed: 2 + -> Seq Scan on stable_qual_pruning1 (never executed) + Filter: (a = ANY ('{"Mon Feb 01 00:00:00 2010 PST","Wed Jan 01 00:00:00 2020 PST"}'::timestamp with time zone[])) +(4 rows) + +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Append (actual rows=0 loops=1) + Subplans Removed: 2 + -> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1) + Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000 PST","Fri Jan 01 00:00:00 2010 PST"}'::timestamp with time zone[])) +(4 rows) + +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(null::timestamptz[]); + QUERY PLAN +---------------------------------------------------------------- + Append (actual rows=0 loops=1) + -> Seq Scan on stable_qual_pruning1 (actual rows=0 loops=1) + Filter: (a = ANY (NULL::timestamp with time zone[])) + -> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1) + Filter: (a = ANY (NULL::timestamp with time zone[])) + -> Seq Scan on stable_qual_pruning3 (actual rows=0 loops=1) + Filter: (a = ANY (NULL::timestamp with time zone[])) +(7 rows) + +drop table stable_qual_pruning; +-- +-- Check that pruning with composite range partitioning works correctly when +-- it must ignore clauses for trailing keys once it has seen a clause with +-- non-inclusive operator for an earlier key +-- +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); +create table mc3p0 partition of mc3p + for values from (0, 0, 0) to (0, maxvalue, maxvalue); +create table mc3p1 partition of mc3p + for values from (1, 1, 1) to (2, minvalue, minvalue); +create table mc3p2 partition of mc3p + for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue); +insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1); +explain (analyze, costs off, summary off, timing off) +select * from mc3p where a < 3 and abs(b) = 1; + QUERY PLAN +------------------------------------------------- + Append (actual rows=3 loops=1) + -> Seq Scan on mc3p0 (actual rows=1 loops=1) + Filter: ((a < 3) AND (abs(b) = 1)) + -> Seq Scan on mc3p1 (actual rows=1 loops=1) + Filter: ((a < 3) AND (abs(b) = 1)) + -> Seq Scan on mc3p2 (actual rows=1 loops=1) + Filter: ((a < 3) AND (abs(b) = 1)) +(7 rows) + +-- +-- Check that pruning with composite range partitioning works correctly when +-- a combination of runtime parameters is specified, not all of whose values +-- are available at the same time +-- +prepare ps1 as + select * from mc3p where a = $1 and abs(b) < (select 3); +explain (analyze, costs off, summary off, timing off) +execute ps1(1); + QUERY PLAN +------------------------------------------------- + Append (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + Subplans Removed: 2 + -> Seq Scan on mc3p1 (actual rows=1 loops=1) + Filter: ((a = $1) AND (abs(b) < $0)) +(6 rows) + +deallocate ps1; +prepare ps2 as + select * from mc3p where a <= $1 and abs(b) < (select 3); +explain (analyze, costs off, summary off, timing off) +execute ps2(1); + QUERY PLAN +------------------------------------------------- + Append (actual rows=2 loops=1) + InitPlan 1 (returns $0) + -> Result (actual rows=1 loops=1) + Subplans Removed: 1 + -> Seq Scan on mc3p0 (actual rows=1 loops=1) + Filter: ((a <= $1) AND (abs(b) < $0)) + -> Seq Scan on mc3p1 (actual rows=1 loops=1) + Filter: ((a <= $1) AND (abs(b) < $0)) +(8 rows) + +deallocate ps2; +drop table mc3p; -- Ensure runtime pruning works with initplans params with boolean types create table boolvalues (value bool not null); insert into boolvalues values('t'),('f'); @@ -2398,4 +3084,568 @@ select * from boolp where a = (select value from boolvalues where not value); (9 rows) drop table boolp; +-- +-- Test run-time pruning of MergeAppend subnodes +-- +set enable_seqscan = off; +set enable_sort = off; +create table ma_test (a int, b int) partition by range (a); +create table ma_test_p1 partition of ma_test for values from (0) to (10); +create table ma_test_p2 partition of ma_test for values from (10) to (20); +create table ma_test_p3 partition of ma_test for values from (20) to (30); +insert into ma_test select x,x from generate_series(0,29) t(x); +create index on ma_test (b); +analyze ma_test; +prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b; +explain (analyze, costs off, summary off, timing off) execute mt_q1(15); + QUERY PLAN +------------------------------------------------------------------------------- + Merge Append (actual rows=2 loops=1) + Sort Key: ma_test_p2.b + Subplans Removed: 1 + -> Index Scan using ma_test_p2_b_idx on ma_test_p2 (actual rows=1 loops=1) + Filter: ((a >= $1) AND ((a % 10) = 5)) + Rows Removed by Filter: 9 + -> Index Scan using ma_test_p3_b_idx on ma_test_p3 (actual rows=1 loops=1) + Filter: ((a >= $1) AND ((a % 10) = 5)) + Rows Removed by Filter: 9 +(9 rows) + +execute mt_q1(15); + a +---- + 15 + 25 +(2 rows) + +explain (analyze, costs off, summary off, timing off) execute mt_q1(25); + QUERY PLAN +------------------------------------------------------------------------------- + Merge Append (actual rows=1 loops=1) + Sort Key: ma_test_p3.b + Subplans Removed: 2 + -> Index Scan using ma_test_p3_b_idx on ma_test_p3 (actual rows=1 loops=1) + Filter: ((a >= $1) AND ((a % 10) = 5)) + Rows Removed by Filter: 9 +(6 rows) + +execute mt_q1(25); + a +---- + 25 +(1 row) + +-- Ensure MergeAppend behaves correctly when no subplans match +explain (analyze, costs off, summary off, timing off) execute mt_q1(35); + QUERY PLAN +------------------------------------------------------------------------ + Merge Append (actual rows=0 loops=1) + Sort Key: ma_test_p1.b + Subplans Removed: 2 + -> Index Scan using ma_test_p1_b_idx on ma_test_p1 (never executed) + Filter: ((a >= $1) AND ((a % 10) = 5)) +(5 rows) + +execute mt_q1(35); + a +--- +(0 rows) + +deallocate mt_q1; +-- ensure initplan params properly prune partitions +explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Merge Append (actual rows=20 loops=1) + Sort Key: ma_test_p1.b + InitPlan 2 (returns $1) + -> Result (actual rows=1 loops=1) + InitPlan 1 (returns $0) + -> Limit (actual rows=1 loops=1) + -> Index Scan using ma_test_p2_b_idx on ma_test_p2 ma_test_p2_1 (actual rows=1 loops=1) + Index Cond: (b IS NOT NULL) + -> Index Scan using ma_test_p1_b_idx on ma_test_p1 (never executed) + Filter: (a >= $1) + -> Index Scan using ma_test_p2_b_idx on ma_test_p2 (actual rows=10 loops=1) + Filter: (a >= $1) + -> Index Scan using ma_test_p3_b_idx on ma_test_p3 (actual rows=10 loops=1) + Filter: (a >= $1) +(14 rows) + +reset enable_seqscan; +reset enable_sort; +drop table ma_test; reset enable_indexonlyscan; +-- +-- check that pruning works properly when the partition key is of a +-- pseudotype +-- +-- array type list partition key +create table pp_arrpart (a int[]) partition by list (a); +create table pp_arrpart1 partition of pp_arrpart for values in ('{1}'); +create table pp_arrpart2 partition of pp_arrpart for values in ('{2, 3}', '{4, 5}'); +explain (costs off) select * from pp_arrpart where a = '{1}'; + QUERY PLAN +---------------------------------- + Seq Scan on pp_arrpart1 + Filter: (a = '{1}'::integer[]) +(2 rows) + +explain (costs off) select * from pp_arrpart where a = '{1, 2}'; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}'); + QUERY PLAN +---------------------------------------------------------------------- + Append + -> Seq Scan on pp_arrpart1 + Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) + -> Seq Scan on pp_arrpart2 + Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) +(5 rows) + +explain (costs off) update pp_arrpart set a = a where a = '{1}'; + QUERY PLAN +---------------------------------------- + Update on pp_arrpart + Update on pp_arrpart1 + -> Seq Scan on pp_arrpart1 + Filter: (a = '{1}'::integer[]) +(4 rows) + +explain (costs off) delete from pp_arrpart where a = '{1}'; + QUERY PLAN +---------------------------------------- + Delete on pp_arrpart + Delete on pp_arrpart1 + -> Seq Scan on pp_arrpart1 + Filter: (a = '{1}'::integer[]) +(4 rows) + +drop table pp_arrpart; +-- array type hash partition key +create table pph_arrpart (a int[]) partition by hash (a); +create table pph_arrpart1 partition of pph_arrpart for values with (modulus 2, remainder 0); +create table pph_arrpart2 partition of pph_arrpart for values with (modulus 2, remainder 1); +insert into pph_arrpart values ('{1}'), ('{1, 2}'), ('{4, 5}'); +select tableoid::regclass, * from pph_arrpart order by 1; + tableoid | a +--------------+------- + pph_arrpart1 | {1,2} + pph_arrpart1 | {4,5} + pph_arrpart2 | {1} +(3 rows) + +explain (costs off) select * from pph_arrpart where a = '{1}'; + QUERY PLAN +---------------------------------- + Seq Scan on pph_arrpart2 + Filter: (a = '{1}'::integer[]) +(2 rows) + +explain (costs off) select * from pph_arrpart where a = '{1, 2}'; + QUERY PLAN +------------------------------------ + Seq Scan on pph_arrpart1 + Filter: (a = '{1,2}'::integer[]) +(2 rows) + +explain (costs off) select * from pph_arrpart where a in ('{4, 5}', '{1}'); + QUERY PLAN +---------------------------------------------------------------------- + Append + -> Seq Scan on pph_arrpart1 + Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) + -> Seq Scan on pph_arrpart2 + Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) +(5 rows) + +drop table pph_arrpart; +-- enum type list partition key +create type pp_colors as enum ('green', 'blue', 'black'); +create table pp_enumpart (a pp_colors) partition by list (a); +create table pp_enumpart_green partition of pp_enumpart for values in ('green'); +create table pp_enumpart_blue partition of pp_enumpart for values in ('blue'); +explain (costs off) select * from pp_enumpart where a = 'blue'; + QUERY PLAN +----------------------------------- + Seq Scan on pp_enumpart_blue + Filter: (a = 'blue'::pp_colors) +(2 rows) + +explain (costs off) select * from pp_enumpart where a = 'black'; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +drop table pp_enumpart; +drop type pp_colors; +-- record type as partition key +create type pp_rectype as (a int, b int); +create table pp_recpart (a pp_rectype) partition by list (a); +create table pp_recpart_11 partition of pp_recpart for values in ('(1,1)'); +create table pp_recpart_23 partition of pp_recpart for values in ('(2,3)'); +explain (costs off) select * from pp_recpart where a = '(1,1)'::pp_rectype; + QUERY PLAN +------------------------------------- + Seq Scan on pp_recpart_11 + Filter: (a = '(1,1)'::pp_rectype) +(2 rows) + +explain (costs off) select * from pp_recpart where a = '(1,2)'::pp_rectype; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +drop table pp_recpart; +drop type pp_rectype; +-- range type partition key +create table pp_intrangepart (a int4range) partition by list (a); +create table pp_intrangepart12 partition of pp_intrangepart for values in ('[1,2]'); +create table pp_intrangepart2inf partition of pp_intrangepart for values in ('[2,)'); +explain (costs off) select * from pp_intrangepart where a = '[1,2]'::int4range; + QUERY PLAN +------------------------------------ + Seq Scan on pp_intrangepart12 + Filter: (a = '[1,3)'::int4range) +(2 rows) + +explain (costs off) select * from pp_intrangepart where a = '(1,2)'::int4range; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +drop table pp_intrangepart; +-- +-- Ensure the enable_partition_prune GUC properly disables partition pruning. +-- +create table pp_lp (a int, value int) partition by list (a); +create table pp_lp1 partition of pp_lp for values in(1); +create table pp_lp2 partition of pp_lp for values in(2); +explain (costs off) select * from pp_lp where a = 1; + QUERY PLAN +-------------------- + Seq Scan on pp_lp1 + Filter: (a = 1) +(2 rows) + +explain (costs off) update pp_lp set value = 10 where a = 1; + QUERY PLAN +-------------------------- + Update on pp_lp + Update on pp_lp1 + -> Seq Scan on pp_lp1 + Filter: (a = 1) +(4 rows) + +explain (costs off) delete from pp_lp where a = 1; + QUERY PLAN +-------------------------- + Delete on pp_lp + Delete on pp_lp1 + -> Seq Scan on pp_lp1 + Filter: (a = 1) +(4 rows) + +set enable_partition_pruning = off; +set constraint_exclusion = 'partition'; -- this should not affect the result. +explain (costs off) select * from pp_lp where a = 1; + QUERY PLAN +-------------------------- + Append + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(5 rows) + +explain (costs off) update pp_lp set value = 10 where a = 1; + QUERY PLAN +-------------------------- + Update on pp_lp + Update on pp_lp1 + Update on pp_lp2 + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(7 rows) + +explain (costs off) delete from pp_lp where a = 1; + QUERY PLAN +-------------------------- + Delete on pp_lp + Delete on pp_lp1 + Delete on pp_lp2 + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(7 rows) + +set constraint_exclusion = 'off'; -- this should not affect the result. +explain (costs off) select * from pp_lp where a = 1; + QUERY PLAN +-------------------------- + Append + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(5 rows) + +explain (costs off) update pp_lp set value = 10 where a = 1; + QUERY PLAN +-------------------------- + Update on pp_lp + Update on pp_lp1 + Update on pp_lp2 + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(7 rows) + +explain (costs off) delete from pp_lp where a = 1; + QUERY PLAN +-------------------------- + Delete on pp_lp + Delete on pp_lp1 + Delete on pp_lp2 + -> Seq Scan on pp_lp1 + Filter: (a = 1) + -> Seq Scan on pp_lp2 + Filter: (a = 1) +(7 rows) + +drop table pp_lp; +-- Ensure enable_partition_prune does not affect non-partitioned tables. +create table inh_lp (a int, value int); +create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp); +NOTICE: merging column "a" with inherited definition +NOTICE: merging column "value" with inherited definition +create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp); +NOTICE: merging column "a" with inherited definition +NOTICE: merging column "value" with inherited definition +set constraint_exclusion = 'partition'; +-- inh_lp2 should be removed in the following 3 cases. +explain (costs off) select * from inh_lp where a = 1; + QUERY PLAN +--------------------------- + Append + -> Seq Scan on inh_lp + Filter: (a = 1) + -> Seq Scan on inh_lp1 + Filter: (a = 1) +(5 rows) + +explain (costs off) update inh_lp set value = 10 where a = 1; + QUERY PLAN +--------------------------- + Update on inh_lp + Update on inh_lp + Update on inh_lp1 + -> Seq Scan on inh_lp + Filter: (a = 1) + -> Seq Scan on inh_lp1 + Filter: (a = 1) +(7 rows) + +explain (costs off) delete from inh_lp where a = 1; + QUERY PLAN +--------------------------- + Delete on inh_lp + Delete on inh_lp + Delete on inh_lp1 + -> Seq Scan on inh_lp + Filter: (a = 1) + -> Seq Scan on inh_lp1 + Filter: (a = 1) +(7 rows) + +-- Ensure we don't exclude normal relations when we only expect to exclude +-- inheritance children +explain (costs off) update inh_lp1 set value = 10 where a = 2; + QUERY PLAN +--------------------------- + Update on inh_lp1 + -> Seq Scan on inh_lp1 + Filter: (a = 2) +(3 rows) + +drop table inh_lp cascade; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table inh_lp1 +drop cascades to table inh_lp2 +reset enable_partition_pruning; +reset constraint_exclusion; +-- Check pruning for a partition tree containing only temporary relations +create temp table pp_temp_parent (a int) partition by list (a); +create temp table pp_temp_part_1 partition of pp_temp_parent for values in (1); +create temp table pp_temp_part_def partition of pp_temp_parent default; +explain (costs off) select * from pp_temp_parent where true; + QUERY PLAN +------------------------------------ + Append + -> Seq Scan on pp_temp_part_1 + -> Seq Scan on pp_temp_part_def +(3 rows) + +explain (costs off) select * from pp_temp_parent where a = 2; + QUERY PLAN +------------------------------ + Seq Scan on pp_temp_part_def + Filter: (a = 2) +(2 rows) + +drop table pp_temp_parent; +-- Stress run-time partition pruning a bit more, per bug reports +create temp table p (a int, b int, c int) partition by list (a); +create temp table p1 partition of p for values in (1); +create temp table p2 partition of p for values in (2); +create temp table q (a int, b int, c int) partition by list (a); +create temp table q1 partition of q for values in (1) partition by list (b); +create temp table q11 partition of q1 for values in (1) partition by list (c); +create temp table q111 partition of q11 for values in (1); +create temp table q2 partition of q for values in (2) partition by list (b); +create temp table q21 partition of q2 for values in (1); +create temp table q22 partition of q2 for values in (2); +insert into q22 values (2, 2, 3); +explain (costs off) +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + QUERY PLAN +---------------------------------------------------- + Append + InitPlan 1 (returns $0) + -> Result + -> Seq Scan on p1 + Filter: ((a = 1) AND (b = 1) AND (c = $0)) + -> Seq Scan on q111 + Filter: ((a = 1) AND (b = 1) AND (c = $0)) + -> Result + One-Time Filter: (1 = $0) +(9 rows) + +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + a | b | c +---+---+--- + 1 | 1 | 1 +(1 row) + +prepare q (int, int) as +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = $1 and s.b = $2 and s.c = (select 1); +explain (costs off) execute q (1, 1); + QUERY PLAN +--------------------------------------------------------------- + Append + InitPlan 1 (returns $0) + -> Result + Subplans Removed: 1 + -> Seq Scan on p1 + Filter: ((a = $1) AND (b = $2) AND (c = $0)) + -> Seq Scan on q111 + Filter: ((a = $1) AND (b = $2) AND (c = $0)) + -> Result + One-Time Filter: ((1 = $1) AND (1 = $2) AND (1 = $0)) +(10 rows) + +execute q (1, 1); + a | b | c +---+---+--- + 1 | 1 | 1 +(1 row) + +drop table p, q; +-- Ensure run-time pruning works correctly when we match a partitioned table +-- on the first level but find no matching partitions on the second level. +create table listp (a int, b int) partition by list (a); +create table listp1 partition of listp for values in(1); +create table listp2 partition of listp for values in(2) partition by list(b); +create table listp2_10 partition of listp2 for values in (10); +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select 2) and b <> 10; + QUERY PLAN +-------------------------------------------- + Seq Scan on listp1 (actual rows=0 loops=1) + Filter: ((b <> 10) AND (a = $0)) + InitPlan 1 (returns $0) + -> Result (never executed) +(4 rows) + +-- +-- check that a partition directly accessed in a query is excluded with +-- constraint_exclusion = on +-- +-- turn off partition pruning, so that it doesn't interfere +set enable_partition_pruning to off; +-- setting constraint_exclusion to 'partition' disables exclusion +set constraint_exclusion to 'partition'; +explain (costs off) select * from listp1 where a = 2; + QUERY PLAN +-------------------- + Seq Scan on listp1 + Filter: (a = 2) +(2 rows) + +explain (costs off) update listp1 set a = 1 where a = 2; + QUERY PLAN +-------------------------- + Update on listp1 + -> Seq Scan on listp1 + Filter: (a = 2) +(3 rows) + +-- constraint exclusion enabled +set constraint_exclusion to 'on'; +explain (costs off) select * from listp1 where a = 2; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +explain (costs off) update listp1 set a = 1 where a = 2; + QUERY PLAN +-------------------------------- + Update on listp1 + -> Result + One-Time Filter: false +(3 rows) + +reset constraint_exclusion; +reset enable_partition_pruning; +drop table listp; diff --git a/src/test/regress/expected/partition_prune_hash.out b/src/test/regress/expected/partition_prune_hash.out deleted file mode 100644 index fbba3f1ff86..00000000000 --- a/src/test/regress/expected/partition_prune_hash.out +++ /dev/null @@ -1,189 +0,0 @@ --- --- Test Partition pruning for HASH partitioning --- We keep this as a seperate test as hash functions return --- values will vary based on CPU architecture. --- -create table hp (a int, b text) partition by hash (a, b); -create table hp0 partition of hp for values with (modulus 4, remainder 0); -create table hp3 partition of hp for values with (modulus 4, remainder 3); -create table hp1 partition of hp for values with (modulus 4, remainder 1); -create table hp2 partition of hp for values with (modulus 4, remainder 2); -insert into hp values (null, null); -insert into hp values (1, null); -insert into hp values (1, 'xxx'); -insert into hp values (null, 'xxx'); -insert into hp values (10, 'xxx'); -insert into hp values (10, 'yyy'); -select tableoid::regclass, * from hp order by 1; - tableoid | a | b -----------+----+----- - hp0 | | - hp0 | 1 | - hp0 | 1 | xxx - hp3 | 10 | yyy - hp1 | | xxx - hp2 | 10 | xxx -(6 rows) - --- partial keys won't prune, nor would non-equality conditions -explain (costs off) select * from hp where a = 1; - QUERY PLAN -------------------------- - Append - -> Seq Scan on hp0 - Filter: (a = 1) - -> Seq Scan on hp1 - Filter: (a = 1) - -> Seq Scan on hp2 - Filter: (a = 1) - -> Seq Scan on hp3 - Filter: (a = 1) -(9 rows) - -explain (costs off) select * from hp where b = 'xxx'; - QUERY PLAN ------------------------------------ - Append - -> Seq Scan on hp0 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp1 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp2 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp3 - Filter: (b = 'xxx'::text) -(9 rows) - -explain (costs off) select * from hp where a is null; - QUERY PLAN ------------------------------ - Append - -> Seq Scan on hp0 - Filter: (a IS NULL) - -> Seq Scan on hp1 - Filter: (a IS NULL) - -> Seq Scan on hp2 - Filter: (a IS NULL) - -> Seq Scan on hp3 - Filter: (a IS NULL) -(9 rows) - -explain (costs off) select * from hp where b is null; - QUERY PLAN ------------------------------ - Append - -> Seq Scan on hp0 - Filter: (b IS NULL) - -> Seq Scan on hp1 - Filter: (b IS NULL) - -> Seq Scan on hp2 - Filter: (b IS NULL) - -> Seq Scan on hp3 - Filter: (b IS NULL) -(9 rows) - -explain (costs off) select * from hp where a < 1 and b = 'xxx'; - QUERY PLAN -------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp1 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp2 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp3 - Filter: ((a < 1) AND (b = 'xxx'::text)) -(9 rows) - -explain (costs off) select * from hp where a <> 1 and b = 'yyy'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp1 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp2 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp3 - Filter: ((a <> 1) AND (b = 'yyy'::text)) -(9 rows) - --- pruning should work if non-null values are provided for all the keys -explain (costs off) select * from hp where a is null and b is null; - QUERY PLAN ------------------------------------------------ - Append - -> Seq Scan on hp0 - Filter: ((a IS NULL) AND (b IS NULL)) -(3 rows) - -explain (costs off) select * from hp where a = 1 and b is null; - QUERY PLAN -------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((b IS NULL) AND (a = 1)) -(3 rows) - -explain (costs off) select * from hp where a = 1 and b = 'xxx'; - QUERY PLAN -------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a = 1) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a is null and b = 'xxx'; - QUERY PLAN ------------------------------------------------------ - Append - -> Seq Scan on hp1 - Filter: ((a IS NULL) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a = 10 and b = 'xxx'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp2 - Filter: ((a = 10) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a = 10 and b = 'yyy'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp3 - Filter: ((a = 10) AND (b = 'yyy'::text)) -(3 rows) - -explain (costs off) select * from hp where (a = 10 and b = 'yyy') or (a = 10 and b = 'xxx') or (a is null and b is null); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: (((a = 10) AND (b = 'yyy'::text)) OR ((a = 10) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) - -> Seq Scan on hp2 - Filter: (((a = 10) AND (b = 'yyy'::text)) OR ((a = 10) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) - -> Seq Scan on hp3 - Filter: (((a = 10) AND (b = 'yyy'::text)) OR ((a = 10) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) -(7 rows) - --- hash partitiong pruning doesn't occur with <> operator clauses -explain (costs off) select * from hp where a <> 1 and b <> 'xxx'; - QUERY PLAN ---------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp1 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp2 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp3 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) -(9 rows) - -drop table hp; diff --git a/src/test/regress/expected/partition_prune_hash_1.out b/src/test/regress/expected/partition_prune_hash_1.out deleted file mode 100644 index 4a26a0e277f..00000000000 --- a/src/test/regress/expected/partition_prune_hash_1.out +++ /dev/null @@ -1,187 +0,0 @@ --- --- Test Partition pruning for HASH partitioning --- We keep this as a seperate test as hash functions return --- values will vary based on CPU architecture. --- -create table hp (a int, b text) partition by hash (a, b); -create table hp0 partition of hp for values with (modulus 4, remainder 0); -create table hp3 partition of hp for values with (modulus 4, remainder 3); -create table hp1 partition of hp for values with (modulus 4, remainder 1); -create table hp2 partition of hp for values with (modulus 4, remainder 2); -insert into hp values (null, null); -insert into hp values (1, null); -insert into hp values (1, 'xxx'); -insert into hp values (null, 'xxx'); -insert into hp values (10, 'xxx'); -insert into hp values (10, 'yyy'); -select tableoid::regclass, * from hp order by 1; - tableoid | a | b -----------+----+----- - hp0 | | - hp0 | 1 | - hp0 | 10 | xxx - hp3 | | xxx - hp3 | 10 | yyy - hp2 | 1 | xxx -(6 rows) - --- partial keys won't prune, nor would non-equality conditions -explain (costs off) select * from hp where a = 1; - QUERY PLAN -------------------------- - Append - -> Seq Scan on hp0 - Filter: (a = 1) - -> Seq Scan on hp1 - Filter: (a = 1) - -> Seq Scan on hp2 - Filter: (a = 1) - -> Seq Scan on hp3 - Filter: (a = 1) -(9 rows) - -explain (costs off) select * from hp where b = 'xxx'; - QUERY PLAN ------------------------------------ - Append - -> Seq Scan on hp0 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp1 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp2 - Filter: (b = 'xxx'::text) - -> Seq Scan on hp3 - Filter: (b = 'xxx'::text) -(9 rows) - -explain (costs off) select * from hp where a is null; - QUERY PLAN ------------------------------ - Append - -> Seq Scan on hp0 - Filter: (a IS NULL) - -> Seq Scan on hp1 - Filter: (a IS NULL) - -> Seq Scan on hp2 - Filter: (a IS NULL) - -> Seq Scan on hp3 - Filter: (a IS NULL) -(9 rows) - -explain (costs off) select * from hp where b is null; - QUERY PLAN ------------------------------ - Append - -> Seq Scan on hp0 - Filter: (b IS NULL) - -> Seq Scan on hp1 - Filter: (b IS NULL) - -> Seq Scan on hp2 - Filter: (b IS NULL) - -> Seq Scan on hp3 - Filter: (b IS NULL) -(9 rows) - -explain (costs off) select * from hp where a < 1 and b = 'xxx'; - QUERY PLAN -------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp1 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp2 - Filter: ((a < 1) AND (b = 'xxx'::text)) - -> Seq Scan on hp3 - Filter: ((a < 1) AND (b = 'xxx'::text)) -(9 rows) - -explain (costs off) select * from hp where a <> 1 and b = 'yyy'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp1 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp2 - Filter: ((a <> 1) AND (b = 'yyy'::text)) - -> Seq Scan on hp3 - Filter: ((a <> 1) AND (b = 'yyy'::text)) -(9 rows) - --- pruning should work if non-null values are provided for all the keys -explain (costs off) select * from hp where a is null and b is null; - QUERY PLAN ------------------------------------------------ - Append - -> Seq Scan on hp0 - Filter: ((a IS NULL) AND (b IS NULL)) -(3 rows) - -explain (costs off) select * from hp where a = 1 and b is null; - QUERY PLAN -------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((b IS NULL) AND (a = 1)) -(3 rows) - -explain (costs off) select * from hp where a = 1 and b = 'xxx'; - QUERY PLAN -------------------------------------------------- - Append - -> Seq Scan on hp2 - Filter: ((a = 1) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a is null and b = 'xxx'; - QUERY PLAN ------------------------------------------------------ - Append - -> Seq Scan on hp3 - Filter: ((a IS NULL) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a = 10 and b = 'xxx'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a = 10) AND (b = 'xxx'::text)) -(3 rows) - -explain (costs off) select * from hp where a = 10 and b = 'yyy'; - QUERY PLAN --------------------------------------------------- - Append - -> Seq Scan on hp3 - Filter: ((a = 10) AND (b = 'yyy'::text)) -(3 rows) - -explain (costs off) select * from hp where (a = 10 and b = 'yyy') or (a = 10 and b = 'xxx') or (a is null and b is null); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: (((a = 10) AND (b = 'yyy'::text)) OR ((a = 10) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) - -> Seq Scan on hp3 - Filter: (((a = 10) AND (b = 'yyy'::text)) OR ((a = 10) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL))) -(5 rows) - --- hash partitiong pruning doesn't occur with <> operator clauses -explain (costs off) select * from hp where a <> 1 and b <> 'xxx'; - QUERY PLAN ---------------------------------------------------- - Append - -> Seq Scan on hp0 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp1 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp2 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) - -> Seq Scan on hp3 - Filter: ((a <> 1) AND (b <> 'xxx'::text)) -(9 rows) - -drop table hp; diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.out index 393d836eada..f1ae34f15fb 100644 --- a/src/test/regress/expected/password.out +++ b/src/test/regress/expected/password.out @@ -62,6 +62,15 @@ SET password_encryption = 'scram-sha-256'; ALTER ROLE regress_passwd4 PASSWORD 'foo'; -- already encrypted with MD5, use as it is CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; +-- This looks like a valid SCRAM-SHA-256 verifier, but it is not +-- so it should be hashed with SCRAM-SHA-256. +CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; +-- These may look like valid MD5 verifiers, but they are not, so they +-- should be hashed with SCRAM-SHA-256. +-- trailing garbage at the end +CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz'; +-- invalid length +CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz'; SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' @@ -73,7 +82,10 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+ regress_passwd3 | SCRAM-SHA-256$4096:$: regress_passwd4 | SCRAM-SHA-256$4096:$: regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023 -(5 rows) + regress_passwd6 | SCRAM-SHA-256$4096:$: + regress_passwd7 | SCRAM-SHA-256$4096:$: + regress_passwd8 | SCRAM-SHA-256$4096:$: +(8 rows) -- An empty password is not allowed, in any form CREATE ROLE regress_passwd_empty PASSWORD ''; @@ -88,12 +100,38 @@ SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty'; (1 row) +-- Test with invalid stored and server keys. +-- +-- The first is valid, to act as a control. The others have too long +-- stored/server keys. They will be re-hashed. +CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; +CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; +CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; +-- Check that the invalid verifiers were re-hashed. A re-hashed verifier +-- should not contain the original salt. +SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed + FROM pg_authid + WHERE rolname LIKE 'regress_passwd_sha_len%' + ORDER BY rolname; + rolname | is_rolpassword_rehashed +-------------------------+------------------------- + regress_passwd_sha_len0 | f + regress_passwd_sha_len1 | t + regress_passwd_sha_len2 | t +(3 rows) + DROP ROLE regress_passwd1; DROP ROLE regress_passwd2; DROP ROLE regress_passwd3; DROP ROLE regress_passwd4; DROP ROLE regress_passwd5; +DROP ROLE regress_passwd6; +DROP ROLE regress_passwd7; +DROP ROLE regress_passwd8; DROP ROLE regress_passwd_empty; +DROP ROLE regress_passwd_sha_len0; +DROP ROLE regress_passwd_sha_len1; +DROP ROLE regress_passwd_sha_len2; -- all entries should have been removed SELECT rolname, rolpassword FROM pg_authid diff --git a/src/test/regress/expected/path.out b/src/test/regress/expected/path.out index 08d6d61dda3..bd6e467752d 100644 --- a/src/test/regress/expected/path.out +++ b/src/test/regress/expected/path.out @@ -4,14 +4,19 @@ --DROP TABLE PATH_TBL; CREATE TABLE PATH_TBL (f1 path); INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)]'); -INSERT INTO PATH_TBL VALUES ('((1,2),(3,4))'); -INSERT INTO PATH_TBL VALUES ('[(0,0),(3,0),(4,5),(1,6)]'); -INSERT INTO PATH_TBL VALUES ('((1,2),(3,4))'); -INSERT INTO PATH_TBL VALUES ('1,2 ,3,4'); -INSERT INTO PATH_TBL VALUES ('[1,2,3, 4]'); -INSERT INTO PATH_TBL VALUES ('[11,12,13,14]'); -INSERT INTO PATH_TBL VALUES ('(11,12,13,14)'); +INSERT INTO PATH_TBL VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) '); +INSERT INTO PATH_TBL VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]'); +INSERT INTO PATH_TBL VALUES ('((1,2) ,(3,4 ))'); +INSERT INTO PATH_TBL VALUES ('1,2 ,3,4 '); +INSERT INTO PATH_TBL VALUES (' [1,2,3, 4] '); +INSERT INTO PATH_TBL VALUES ('((10,20))'); -- Only one point +INSERT INTO PATH_TBL VALUES ('[ 11,12,13,14 ]'); +INSERT INTO PATH_TBL VALUES ('( 11,12,13,14) '); -- bad values for parser testing +INSERT INTO PATH_TBL VALUES ('[]'); +ERROR: invalid input syntax for type path: "[]" +LINE 1: INSERT INTO PATH_TBL VALUES ('[]'); + ^ INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]'); ERROR: invalid input syntax for type path: "[(,2),(3,4)]" LINE 1: INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]'); @@ -20,19 +25,14 @@ INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)'); ERROR: invalid input syntax for type path: "[(1,2),(3,4)" LINE 1: INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)'); ^ -SELECT f1 FROM PATH_TBL; - f1 ---------------------------- - [(1,2),(3,4)] - ((1,2),(3,4)) - [(0,0),(3,0),(4,5),(1,6)] - ((1,2),(3,4)) - ((1,2),(3,4)) - [(1,2),(3,4)] - [(11,12),(13,14)] - ((11,12),(13,14)) -(8 rows) - +INSERT INTO PATH_TBL VALUES ('(1,2,3,4'); +ERROR: invalid input syntax for type path: "(1,2,3,4" +LINE 1: INSERT INTO PATH_TBL VALUES ('(1,2,3,4'); + ^ +INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]'); +ERROR: invalid input syntax for type path: "(1,2),(3,4)]" +LINE 1: INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]'); + ^ SELECT '' AS count, f1 AS open_path FROM PATH_TBL WHERE isopen(f1); count | open_path -------+--------------------------- @@ -48,8 +48,9 @@ SELECT '' AS count, f1 AS closed_path FROM PATH_TBL WHERE isclosed(f1); | ((1,2),(3,4)) | ((1,2),(3,4)) | ((1,2),(3,4)) + | ((10,20)) | ((11,12),(13,14)) -(4 rows) +(5 rows) SELECT '' AS count, pclose(f1) AS closed_path FROM PATH_TBL; count | closed_path @@ -60,9 +61,10 @@ SELECT '' AS count, pclose(f1) AS closed_path FROM PATH_TBL; | ((1,2),(3,4)) | ((1,2),(3,4)) | ((1,2),(3,4)) + | ((10,20)) | ((11,12),(13,14)) | ((11,12),(13,14)) -(8 rows) +(9 rows) SELECT '' AS count, popen(f1) AS open_path FROM PATH_TBL; count | open_path @@ -73,7 +75,8 @@ SELECT '' AS count, popen(f1) AS open_path FROM PATH_TBL; | [(1,2),(3,4)] | [(1,2),(3,4)] | [(1,2),(3,4)] + | [(10,20)] | [(11,12),(13,14)] | [(11,12),(13,14)] -(8 rows) +(9 rows) diff --git a/src/test/regress/expected/pg_lsn.out b/src/test/regress/expected/pg_lsn.out index 2854cfd7b94..64d41dfdad2 100644 --- a/src/test/regress/expected/pg_lsn.out +++ b/src/test/regress/expected/pg_lsn.out @@ -26,6 +26,13 @@ INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); ERROR: invalid input syntax for type pg_lsn: "/ABCD" LINE 1: INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); ^ +-- Min/Max aggregation +SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL; + min | max +-----+------------------- + 0/0 | FFFFFFFF/FFFFFFFF +(1 row) + DROP TABLE PG_LSN_TBL; -- Operators SELECT '0/16AE7F8' = '0/16AE7F8'::pg_lsn; diff --git a/src/test/regress/expected/plancache.out b/src/test/regress/expected/plancache.out index 3086c685660..7d289b8c5e7 100644 --- a/src/test/regress/expected/plancache.out +++ b/src/test/regress/expected/plancache.out @@ -278,3 +278,80 @@ drop table pc_list_part_1; execute pstmt_def_insert(1); drop table pc_list_parted, pc_list_part_null; deallocate pstmt_def_insert; +-- Test plan_cache_mode +create table test_mode (a int); +insert into test_mode select 1 from generate_series(1,1000) union all select 2; +create index on test_mode (a); +analyze test_mode; +prepare test_mode_pp (int) as select count(*) from test_mode where a = $1; +-- up to 5 executions, custom plan is used +explain (costs off) execute test_mode_pp(2); + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Index Only Scan using test_mode_a_idx on test_mode + Index Cond: (a = 2) +(3 rows) + +-- force generic plan +set plan_cache_mode to force_generic_plan; +explain (costs off) execute test_mode_pp(2); + QUERY PLAN +----------------------------- + Aggregate + -> Seq Scan on test_mode + Filter: (a = $1) +(3 rows) + +-- get to generic plan by 5 executions +set plan_cache_mode to auto; +execute test_mode_pp(1); -- 1x + count +------- + 1000 +(1 row) + +execute test_mode_pp(1); -- 2x + count +------- + 1000 +(1 row) + +execute test_mode_pp(1); -- 3x + count +------- + 1000 +(1 row) + +execute test_mode_pp(1); -- 4x + count +------- + 1000 +(1 row) + +execute test_mode_pp(1); -- 5x + count +------- + 1000 +(1 row) + +-- we should now get a really bad plan +explain (costs off) execute test_mode_pp(2); + QUERY PLAN +----------------------------- + Aggregate + -> Seq Scan on test_mode + Filter: (a = $1) +(3 rows) + +-- but we can force a custom plan +set plan_cache_mode to force_custom_plan; +explain (costs off) execute test_mode_pp(2); + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Index Only Scan using test_mode_a_idx on test_mode + Index Cond: (a = 2) +(3 rows) + +drop table test_mode; diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index b687fbfddcc..e85b29455e5 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -1915,259 +1915,6 @@ SELECT * FROM perform_test; drop table perform_test; -- --- Test error trapping --- -create function trap_zero_divide(int) returns int as $$ -declare x int; - sx smallint; -begin - begin -- start a subtransaction - raise notice 'should see this'; - x := 100 / $1; - raise notice 'should see this only if % <> 0', $1; - sx := $1; - raise notice 'should see this only if % fits in smallint', $1; - if $1 < 0 then - raise exception '% is less than zero', $1; - end if; - exception - when division_by_zero then - raise notice 'caught division_by_zero'; - x := -1; - when NUMERIC_VALUE_OUT_OF_RANGE then - raise notice 'caught numeric_value_out_of_range'; - x := -2; - end; - return x; -end$$ language plpgsql; -select trap_zero_divide(50); -NOTICE: should see this -NOTICE: should see this only if 50 <> 0 -NOTICE: should see this only if 50 fits in smallint - trap_zero_divide ------------------- - 2 -(1 row) - -select trap_zero_divide(0); -NOTICE: should see this -NOTICE: caught division_by_zero - trap_zero_divide ------------------- - -1 -(1 row) - -select trap_zero_divide(100000); -NOTICE: should see this -NOTICE: should see this only if 100000 <> 0 -NOTICE: caught numeric_value_out_of_range - trap_zero_divide ------------------- - -2 -(1 row) - -select trap_zero_divide(-100); -NOTICE: should see this -NOTICE: should see this only if -100 <> 0 -NOTICE: should see this only if -100 fits in smallint -ERROR: -100 is less than zero -CONTEXT: PL/pgSQL function trap_zero_divide(integer) line 12 at RAISE -create function trap_matching_test(int) returns int as $$ -declare x int; - sx smallint; - y int; -begin - begin -- start a subtransaction - x := 100 / $1; - sx := $1; - select into y unique1 from tenk1 where unique2 = - (select unique2 from tenk1 b where ten = $1); - exception - when data_exception then -- category match - raise notice 'caught data_exception'; - x := -1; - when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then - raise notice 'caught numeric_value_out_of_range or cardinality_violation'; - x := -2; - end; - return x; -end$$ language plpgsql; -select trap_matching_test(50); - trap_matching_test --------------------- - 2 -(1 row) - -select trap_matching_test(0); -NOTICE: caught data_exception - trap_matching_test --------------------- - -1 -(1 row) - -select trap_matching_test(100000); -NOTICE: caught data_exception - trap_matching_test --------------------- - -1 -(1 row) - -select trap_matching_test(1); -NOTICE: caught numeric_value_out_of_range or cardinality_violation - trap_matching_test --------------------- - -2 -(1 row) - -create temp table foo (f1 int); -create function subxact_rollback_semantics() returns int as $$ -declare x int; -begin - x := 1; - insert into foo values(x); - begin - x := x + 1; - insert into foo values(x); - raise exception 'inner'; - exception - when others then - x := x * 10; - end; - insert into foo values(x); - return x; -end$$ language plpgsql; -select subxact_rollback_semantics(); - subxact_rollback_semantics ----------------------------- - 20 -(1 row) - -select * from foo; - f1 ----- - 1 - 20 -(2 rows) - -drop table foo; -create function trap_timeout() returns void as $$ -begin - declare x int; - begin - -- we assume this will take longer than 2 seconds: - select count(*) into x from tenk1 a, tenk1 b, tenk1 c; - exception - when others then - raise notice 'caught others?'; - when query_canceled then - raise notice 'nyeah nyeah, can''t stop me'; - end; - -- Abort transaction to abandon the statement_timeout setting. Otherwise, - -- the next top-level statement would be vulnerable to the timeout. - raise exception 'end of function'; -end$$ language plpgsql; -begin; -set statement_timeout to 2000; -select trap_timeout(); -NOTICE: nyeah nyeah, can't stop me -ERROR: end of function -CONTEXT: PL/pgSQL function trap_timeout() line 15 at RAISE -rollback; --- Test for pass-by-ref values being stored in proper context -create function test_variable_storage() returns text as $$ -declare x text; -begin - x := '1234'; - begin - x := x || '5678'; - -- force error inside subtransaction SPI context - perform trap_zero_divide(-100); - exception - when others then - x := x || '9012'; - end; - return x; -end$$ language plpgsql; -select test_variable_storage(); -NOTICE: should see this -NOTICE: should see this only if -100 <> 0 -NOTICE: should see this only if -100 fits in smallint - test_variable_storage ------------------------ - 123456789012 -(1 row) - --- --- test foreign key error trapping --- -create temp table master(f1 int primary key); -create temp table slave(f1 int references master deferrable); -insert into master values(1); -insert into slave values(1); -insert into slave values(2); -- fails -ERROR: insert or update on table "slave" violates foreign key constraint "slave_f1_fkey" -DETAIL: Key (f1)=(2) is not present in table "master". -create function trap_foreign_key(int) returns int as $$ -begin - begin -- start a subtransaction - insert into slave values($1); - exception - when foreign_key_violation then - raise notice 'caught foreign_key_violation'; - return 0; - end; - return 1; -end$$ language plpgsql; -create function trap_foreign_key_2() returns int as $$ -begin - begin -- start a subtransaction - set constraints all immediate; - exception - when foreign_key_violation then - raise notice 'caught foreign_key_violation'; - return 0; - end; - return 1; -end$$ language plpgsql; -select trap_foreign_key(1); - trap_foreign_key ------------------- - 1 -(1 row) - -select trap_foreign_key(2); -- detects FK violation -NOTICE: caught foreign_key_violation - trap_foreign_key ------------------- - 0 -(1 row) - -begin; - set constraints all deferred; - select trap_foreign_key(2); -- should not detect FK violation - trap_foreign_key ------------------- - 1 -(1 row) - - savepoint x; - set constraints all immediate; -- fails -ERROR: insert or update on table "slave" violates foreign key constraint "slave_f1_fkey" -DETAIL: Key (f1)=(2) is not present in table "master". - rollback to x; - select trap_foreign_key_2(); -- detects FK violation -NOTICE: caught foreign_key_violation - trap_foreign_key_2 --------------------- - 0 -(1 row) - -commit; -- still fails -ERROR: insert or update on table "slave" violates foreign key constraint "slave_f1_fkey" -DETAIL: Key (f1)=(2) is not present in table "master". -drop function trap_foreign_key(int); -drop function trap_foreign_key_2(); --- -- Test proper snapshot handling in simple expressions -- create temp table users(login text, id serial); @@ -2778,6 +2525,7 @@ begin end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement create or replace function stricttest() returns void as $$ declare x record; @@ -2851,6 +2599,7 @@ begin end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement create or replace function stricttest() returns void as $$ declare x record; @@ -2916,6 +2665,7 @@ end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row DETAIL: parameters: p1 = '2', p3 = 'foo' +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 8 at SQL statement create or replace function stricttest() returns void as $$ declare x record; @@ -2926,6 +2676,7 @@ begin end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 5 at SQL statement create or replace function stricttest() returns void as $$ declare x record; @@ -2973,6 +2724,7 @@ begin end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 10 at SQL statement reset plpgsql.print_strict_params; create or replace function stricttest() returns void as $$ @@ -2990,6 +2742,7 @@ end$$ language plpgsql; select stricttest(); ERROR: query returned more than one row DETAIL: parameters: p1 = '2', p3 = 'foo' +HINT: Make sure the query returns a single row, or use LIMIT 1. CONTEXT: PL/pgSQL function stricttest() line 10 at SQL statement -- test warnings and errors set plpgsql.extra_warnings to 'all'; @@ -3113,6 +2866,107 @@ select shadowtest(1); t (1 row) +-- runtime extra checks +set plpgsql.extra_warnings to 'too_many_rows'; +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; +WARNING: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. +set plpgsql.extra_errors to 'too_many_rows'; +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; +ERROR: query returned more than one row +HINT: Make sure the query returns a single row, or use LIMIT 1. +CONTEXT: PL/pgSQL function inline_code_block line 4 at SQL statement +reset plpgsql.extra_errors; +reset plpgsql.extra_warnings; +set plpgsql.extra_warnings to 'strict_multi_assignment'; +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. +WARNING: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_warnings is active. +HINT: Make sure the query returns the exact list of columns. +set plpgsql.extra_errors to 'strict_multi_assignment'; +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; +ERROR: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_errors is active. +HINT: Make sure the query returns the exact list of columns. +CONTEXT: PL/pgSQL function inline_code_block line 6 at SQL statement +create table test_01(a int, b int, c int); +alter table test_01 drop column a; +-- the check is active only when source table is not empty +insert into test_01 values(10,20); +do $$ +declare + x int; + y int; +begin + select * from test_01 into x, y; -- should be ok + raise notice 'ok'; + select * from test_01 into x; -- should to fail +end; +$$; +NOTICE: ok +ERROR: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_errors is active. +HINT: Make sure the query returns the exact list of columns. +CONTEXT: PL/pgSQL function inline_code_block line 8 at SQL statement +do $$ +declare + t test_01; +begin + select 1, 2 into t; -- should be ok + raise notice 'ok'; + select 1, 2, 3 into t; -- should fail; +end; +$$; +NOTICE: ok +ERROR: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_errors is active. +HINT: Make sure the query returns the exact list of columns. +CONTEXT: PL/pgSQL function inline_code_block line 7 at SQL statement +do $$ +declare + t test_01; +begin + select 1 into t; -- should fail; +end; +$$; +ERROR: number of source and target fields in assignment does not match +DETAIL: strict_multi_assignment check of extra_errors is active. +HINT: Make sure the query returns the exact list of columns. +CONTEXT: PL/pgSQL function inline_code_block line 5 at SQL statement +drop table test_01; +reset plpgsql.extra_errors; +reset plpgsql.extra_warnings; -- test scrollable cursor support create function sc_test() returns setof integer as $$ declare @@ -3782,7 +3636,7 @@ begin end; $$ language plpgsql; select compos(); -ERROR: invalid input syntax for integer: "(1,hello)" +ERROR: invalid input syntax for type integer: "(1,hello)" CONTEXT: PL/pgSQL function compos() while casting return value to function's return type -- test: invalid use of composite expression in scalar-returning function create or replace function compos() returns int as $$ @@ -3791,7 +3645,7 @@ begin end; $$ language plpgsql; select compos(); -ERROR: invalid input syntax for integer: "(1,hello)" +ERROR: invalid input syntax for type integer: "(1,hello)" CONTEXT: PL/pgSQL function compos() while casting return value to function's return type drop function compos(); drop type compostype; @@ -4674,6 +4528,27 @@ select unreserved_test(); 43 (1 row) +create or replace function unreserved_test() returns int as $$ +declare + comment int := 21; +begin + comment := comment * 2; + comment on function unreserved_test() is 'this is a test'; + return comment; +end +$$ language plpgsql; +select unreserved_test(); + unreserved_test +----------------- + 42 +(1 row) + +select obj_description('unreserved_test()'::regprocedure, 'pg_proc'); + obj_description +----------------- + this is a test +(1 row) + drop function unreserved_test(); -- -- Test FOREACH over arrays diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out index bfc09627496..15e3b83b37e 100644 --- a/src/test/regress/expected/point.out +++ b/src/test/regress/expected/point.out @@ -1,12 +1,17 @@ -- -- POINT -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; CREATE TABLE POINT_TBL(f1 point); INSERT INTO POINT_TBL(f1) VALUES ('(0.0,0.0)'); INSERT INTO POINT_TBL(f1) VALUES ('(-10.0,0.0)'); INSERT INTO POINT_TBL(f1) VALUES ('(-3.0,4.0)'); INSERT INTO POINT_TBL(f1) VALUES ('(5.1, 34.5)'); INSERT INTO POINT_TBL(f1) VALUES ('(-5.0,-12.0)'); +INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)'); -- To underflow +INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)'); -- To overflow +INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) '); -- bad format points INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf'); ERROR: invalid input syntax for type point: "asdfasdf" @@ -17,20 +22,31 @@ INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)'); ERROR: invalid input syntax for type point: "(10.0 10.0)" LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)'); ^ +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x'); +ERROR: invalid input syntax for type point: "(10.0, 10.0) x" +LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x'); + ^ INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0'); ERROR: invalid input syntax for type point: "(10.0,10.0" LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0'); ^ +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)'); -- Out of range +ERROR: "1e+500" is out of range for type double precision +LINE 1: INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)'); + ^ SELECT '' AS six, * FROM POINT_TBL; - six | f1 ------+------------ + six | f1 +-----+------------------- | (0,0) | (-10,0) | (-3,4) | (5.1,34.5) | (-5,-12) + | (1e-300,-1e-300) + | (1e+300,Infinity) + | (NaN,NaN) | (10,10) -(6 rows) +(9 rows) -- left of SELECT '' AS three, p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)'; @@ -92,158 +108,268 @@ SELECT '' AS three, p.* FROM POINT_TBL p SELECT '' AS three, p.* FROM POINT_TBL p WHERE not p.f1 <@ box '(0,0,100,100)'; - three | f1 --------+---------- + three | f1 +-------+------------------- | (-10,0) | (-3,4) | (-5,-12) -(3 rows) + | (1e-300,-1e-300) + | (1e+300,Infinity) + | (NaN,NaN) +(6 rows) SELECT '' AS two, p.* FROM POINT_TBL p WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]'; - two | f1 ------+--------- + two | f1 +-----+------------------ | (0,0) | (-10,0) -(2 rows) + | (1e-300,-1e-300) +(3 rows) SELECT '' AS three, p.* FROM POINT_TBL p WHERE not box '(0,0,100,100)' @> p.f1; - three | f1 --------+---------- + three | f1 +-------+------------------- | (-10,0) | (-3,4) | (-5,-12) -(3 rows) + | (1e-300,-1e-300) + | (1e+300,Infinity) + | (NaN,NaN) +(6 rows) SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist FROM POINT_TBL p ORDER BY dist; - six | f1 | dist ------+------------+------------------ - | (0,0) | 0 - | (-3,4) | 5 - | (-10,0) | 10 - | (-5,-12) | 13 - | (10,10) | 14.142135623731 - | (5.1,34.5) | 34.8749193547455 -(6 rows) + six | f1 | dist +-----+-------------------+---------------------- + | (0,0) | 0 + | (1e-300,-1e-300) | 1.4142135623731e-300 + | (-3,4) | 5 + | (-10,0) | 10 + | (-5,-12) | 13 + | (10,10) | 14.142135623731 + | (5.1,34.5) | 34.8749193547455 + | (1e+300,Infinity) | Infinity + | (NaN,NaN) | NaN +(9 rows) SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dist FROM POINT_TBL p1, POINT_TBL p2 ORDER BY dist, p1.f1[0], p2.f1[0]; - thirtysix | point1 | point2 | dist ------------+------------+------------+------------------ - | (-10,0) | (-10,0) | 0 - | (-5,-12) | (-5,-12) | 0 - | (-3,4) | (-3,4) | 0 - | (0,0) | (0,0) | 0 - | (5.1,34.5) | (5.1,34.5) | 0 - | (10,10) | (10,10) | 0 - | (-3,4) | (0,0) | 5 - | (0,0) | (-3,4) | 5 - | (-10,0) | (-3,4) | 8.06225774829855 - | (-3,4) | (-10,0) | 8.06225774829855 - | (-10,0) | (0,0) | 10 - | (0,0) | (-10,0) | 10 - | (-10,0) | (-5,-12) | 13 - | (-5,-12) | (-10,0) | 13 - | (-5,-12) | (0,0) | 13 - | (0,0) | (-5,-12) | 13 - | (0,0) | (10,10) | 14.142135623731 - | (10,10) | (0,0) | 14.142135623731 - | (-3,4) | (10,10) | 14.3178210632764 - | (10,10) | (-3,4) | 14.3178210632764 - | (-5,-12) | (-3,4) | 16.1245154965971 - | (-3,4) | (-5,-12) | 16.1245154965971 - | (-10,0) | (10,10) | 22.3606797749979 - | (10,10) | (-10,0) | 22.3606797749979 - | (5.1,34.5) | (10,10) | 24.9851956166046 - | (10,10) | (5.1,34.5) | 24.9851956166046 - | (-5,-12) | (10,10) | 26.6270539113887 - | (10,10) | (-5,-12) | 26.6270539113887 - | (-3,4) | (5.1,34.5) | 31.5572495632937 - | (5.1,34.5) | (-3,4) | 31.5572495632937 - | (0,0) | (5.1,34.5) | 34.8749193547455 - | (5.1,34.5) | (0,0) | 34.8749193547455 - | (-10,0) | (5.1,34.5) | 37.6597928831267 - | (5.1,34.5) | (-10,0) | 37.6597928831267 - | (-5,-12) | (5.1,34.5) | 47.5842410888311 - | (5.1,34.5) | (-5,-12) | 47.5842410888311 -(36 rows) + thirtysix | point1 | point2 | dist +-----------+-------------------+-------------------+---------------------- + | (-10,0) | (-10,0) | 0 + | (-5,-12) | (-5,-12) | 0 + | (-3,4) | (-3,4) | 0 + | (0,0) | (0,0) | 0 + | (1e-300,-1e-300) | (1e-300,-1e-300) | 0 + | (5.1,34.5) | (5.1,34.5) | 0 + | (10,10) | (10,10) | 0 + | (0,0) | (1e-300,-1e-300) | 1.4142135623731e-300 + | (1e-300,-1e-300) | (0,0) | 1.4142135623731e-300 + | (-3,4) | (0,0) | 5 + | (-3,4) | (1e-300,-1e-300) | 5 + | (0,0) | (-3,4) | 5 + | (1e-300,-1e-300) | (-3,4) | 5 + | (-10,0) | (-3,4) | 8.06225774829855 + | (-3,4) | (-10,0) | 8.06225774829855 + | (-10,0) | (0,0) | 10 + | (-10,0) | (1e-300,-1e-300) | 10 + | (0,0) | (-10,0) | 10 + | (1e-300,-1e-300) | (-10,0) | 10 + | (-10,0) | (-5,-12) | 13 + | (-5,-12) | (-10,0) | 13 + | (-5,-12) | (0,0) | 13 + | (-5,-12) | (1e-300,-1e-300) | 13 + | (0,0) | (-5,-12) | 13 + | (1e-300,-1e-300) | (-5,-12) | 13 + | (0,0) | (10,10) | 14.142135623731 + | (1e-300,-1e-300) | (10,10) | 14.142135623731 + | (10,10) | (0,0) | 14.142135623731 + | (10,10) | (1e-300,-1e-300) | 14.142135623731 + | (-3,4) | (10,10) | 14.3178210632764 + | (10,10) | (-3,4) | 14.3178210632764 + | (-5,-12) | (-3,4) | 16.1245154965971 + | (-3,4) | (-5,-12) | 16.1245154965971 + | (-10,0) | (10,10) | 22.3606797749979 + | (10,10) | (-10,0) | 22.3606797749979 + | (5.1,34.5) | (10,10) | 24.9851956166046 + | (10,10) | (5.1,34.5) | 24.9851956166046 + | (-5,-12) | (10,10) | 26.6270539113887 + | (10,10) | (-5,-12) | 26.6270539113887 + | (-3,4) | (5.1,34.5) | 31.5572495632937 + | (5.1,34.5) | (-3,4) | 31.5572495632937 + | (0,0) | (5.1,34.5) | 34.8749193547455 + | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 + | (5.1,34.5) | (0,0) | 34.8749193547455 + | (5.1,34.5) | (1e-300,-1e-300) | 34.8749193547455 + | (-10,0) | (5.1,34.5) | 37.6597928831267 + | (5.1,34.5) | (-10,0) | 37.6597928831267 + | (-5,-12) | (5.1,34.5) | 47.5842410888311 + | (5.1,34.5) | (-5,-12) | 47.5842410888311 + | (-10,0) | (1e+300,Infinity) | Infinity + | (-5,-12) | (1e+300,Infinity) | Infinity + | (-3,4) | (1e+300,Infinity) | Infinity + | (0,0) | (1e+300,Infinity) | Infinity + | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + | (5.1,34.5) | (1e+300,Infinity) | Infinity + | (10,10) | (1e+300,Infinity) | Infinity + | (1e+300,Infinity) | (-10,0) | Infinity + | (1e+300,Infinity) | (-5,-12) | Infinity + | (1e+300,Infinity) | (-3,4) | Infinity + | (1e+300,Infinity) | (0,0) | Infinity + | (1e+300,Infinity) | (1e-300,-1e-300) | Infinity + | (1e+300,Infinity) | (5.1,34.5) | Infinity + | (1e+300,Infinity) | (10,10) | Infinity + | (-10,0) | (NaN,NaN) | NaN + | (-5,-12) | (NaN,NaN) | NaN + | (-3,4) | (NaN,NaN) | NaN + | (0,0) | (NaN,NaN) | NaN + | (1e-300,-1e-300) | (NaN,NaN) | NaN + | (5.1,34.5) | (NaN,NaN) | NaN + | (10,10) | (NaN,NaN) | NaN + | (1e+300,Infinity) | (1e+300,Infinity) | NaN + | (1e+300,Infinity) | (NaN,NaN) | NaN + | (NaN,NaN) | (-10,0) | NaN + | (NaN,NaN) | (-5,-12) | NaN + | (NaN,NaN) | (-3,4) | NaN + | (NaN,NaN) | (0,0) | NaN + | (NaN,NaN) | (1e-300,-1e-300) | NaN + | (NaN,NaN) | (5.1,34.5) | NaN + | (NaN,NaN) | (10,10) | NaN + | (NaN,NaN) | (1e+300,Infinity) | NaN + | (NaN,NaN) | (NaN,NaN) | NaN +(81 rows) SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 FROM POINT_TBL p1, POINT_TBL p2 WHERE (p1.f1 <-> p2.f1) > 3; - thirty | point1 | point2 ---------+------------+------------ - | (0,0) | (-10,0) - | (0,0) | (-3,4) - | (0,0) | (5.1,34.5) - | (0,0) | (-5,-12) - | (0,0) | (10,10) - | (-10,0) | (0,0) - | (-10,0) | (-3,4) - | (-10,0) | (5.1,34.5) - | (-10,0) | (-5,-12) - | (-10,0) | (10,10) - | (-3,4) | (0,0) - | (-3,4) | (-10,0) - | (-3,4) | (5.1,34.5) - | (-3,4) | (-5,-12) - | (-3,4) | (10,10) - | (5.1,34.5) | (0,0) - | (5.1,34.5) | (-10,0) - | (5.1,34.5) | (-3,4) - | (5.1,34.5) | (-5,-12) - | (5.1,34.5) | (10,10) - | (-5,-12) | (0,0) - | (-5,-12) | (-10,0) - | (-5,-12) | (-3,4) - | (-5,-12) | (5.1,34.5) - | (-5,-12) | (10,10) - | (10,10) | (0,0) - | (10,10) | (-10,0) - | (10,10) | (-3,4) - | (10,10) | (5.1,34.5) - | (10,10) | (-5,-12) -(30 rows) + thirty | point1 | point2 +--------+-------------------+------------------- + | (0,0) | (-10,0) + | (0,0) | (-3,4) + | (0,0) | (5.1,34.5) + | (0,0) | (-5,-12) + | (0,0) | (1e+300,Infinity) + | (0,0) | (NaN,NaN) + | (0,0) | (10,10) + | (-10,0) | (0,0) + | (-10,0) | (-3,4) + | (-10,0) | (5.1,34.5) + | (-10,0) | (-5,-12) + | (-10,0) | (1e-300,-1e-300) + | (-10,0) | (1e+300,Infinity) + | (-10,0) | (NaN,NaN) + | (-10,0) | (10,10) + | (-3,4) | (0,0) + | (-3,4) | (-10,0) + | (-3,4) | (5.1,34.5) + | (-3,4) | (-5,-12) + | (-3,4) | (1e-300,-1e-300) + | (-3,4) | (1e+300,Infinity) + | (-3,4) | (NaN,NaN) + | (-3,4) | (10,10) + | (5.1,34.5) | (0,0) + | (5.1,34.5) | (-10,0) + | (5.1,34.5) | (-3,4) + | (5.1,34.5) | (-5,-12) + | (5.1,34.5) | (1e-300,-1e-300) + | (5.1,34.5) | (1e+300,Infinity) + | (5.1,34.5) | (NaN,NaN) + | (5.1,34.5) | (10,10) + | (-5,-12) | (0,0) + | (-5,-12) | (-10,0) + | (-5,-12) | (-3,4) + | (-5,-12) | (5.1,34.5) + | (-5,-12) | (1e-300,-1e-300) + | (-5,-12) | (1e+300,Infinity) + | (-5,-12) | (NaN,NaN) + | (-5,-12) | (10,10) + | (1e-300,-1e-300) | (-10,0) + | (1e-300,-1e-300) | (-3,4) + | (1e-300,-1e-300) | (5.1,34.5) + | (1e-300,-1e-300) | (-5,-12) + | (1e-300,-1e-300) | (1e+300,Infinity) + | (1e-300,-1e-300) | (NaN,NaN) + | (1e-300,-1e-300) | (10,10) + | (1e+300,Infinity) | (0,0) + | (1e+300,Infinity) | (-10,0) + | (1e+300,Infinity) | (-3,4) + | (1e+300,Infinity) | (5.1,34.5) + | (1e+300,Infinity) | (-5,-12) + | (1e+300,Infinity) | (1e-300,-1e-300) + | (1e+300,Infinity) | (1e+300,Infinity) + | (1e+300,Infinity) | (NaN,NaN) + | (1e+300,Infinity) | (10,10) + | (NaN,NaN) | (0,0) + | (NaN,NaN) | (-10,0) + | (NaN,NaN) | (-3,4) + | (NaN,NaN) | (5.1,34.5) + | (NaN,NaN) | (-5,-12) + | (NaN,NaN) | (1e-300,-1e-300) + | (NaN,NaN) | (1e+300,Infinity) + | (NaN,NaN) | (NaN,NaN) + | (NaN,NaN) | (10,10) + | (10,10) | (0,0) + | (10,10) | (-10,0) + | (10,10) | (-3,4) + | (10,10) | (5.1,34.5) + | (10,10) | (-5,-12) + | (10,10) | (1e-300,-1e-300) + | (10,10) | (1e+300,Infinity) + | (10,10) | (NaN,NaN) +(72 rows) -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance FROM POINT_TBL p1, POINT_TBL p2 WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 ORDER BY distance, p1.f1[0], p2.f1[0]; - fifteen | point1 | point2 | distance ----------+------------+------------+------------------ - | (-3,4) | (0,0) | 5 - | (-10,0) | (-3,4) | 8.06225774829855 - | (-10,0) | (0,0) | 10 - | (-10,0) | (-5,-12) | 13 - | (-5,-12) | (0,0) | 13 - | (0,0) | (10,10) | 14.142135623731 - | (-3,4) | (10,10) | 14.3178210632764 - | (-5,-12) | (-3,4) | 16.1245154965971 - | (-10,0) | (10,10) | 22.3606797749979 - | (5.1,34.5) | (10,10) | 24.9851956166046 - | (-5,-12) | (10,10) | 26.6270539113887 - | (-3,4) | (5.1,34.5) | 31.5572495632937 - | (0,0) | (5.1,34.5) | 34.8749193547455 - | (-10,0) | (5.1,34.5) | 37.6597928831267 - | (-5,-12) | (5.1,34.5) | 47.5842410888311 -(15 rows) + fifteen | point1 | point2 | distance +---------+------------------+-------------------+------------------ + | (-3,4) | (0,0) | 5 + | (-3,4) | (1e-300,-1e-300) | 5 + | (-10,0) | (-3,4) | 8.06225774829855 + | (-10,0) | (0,0) | 10 + | (-10,0) | (1e-300,-1e-300) | 10 + | (-10,0) | (-5,-12) | 13 + | (-5,-12) | (0,0) | 13 + | (-5,-12) | (1e-300,-1e-300) | 13 + | (0,0) | (10,10) | 14.142135623731 + | (1e-300,-1e-300) | (10,10) | 14.142135623731 + | (-3,4) | (10,10) | 14.3178210632764 + | (-5,-12) | (-3,4) | 16.1245154965971 + | (-10,0) | (10,10) | 22.3606797749979 + | (5.1,34.5) | (10,10) | 24.9851956166046 + | (-5,-12) | (10,10) | 26.6270539113887 + | (-3,4) | (5.1,34.5) | 31.5572495632937 + | (0,0) | (5.1,34.5) | 34.8749193547455 + | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 + | (-10,0) | (5.1,34.5) | 37.6597928831267 + | (-5,-12) | (5.1,34.5) | 47.5842410888311 + | (-10,0) | (1e+300,Infinity) | Infinity + | (-5,-12) | (1e+300,Infinity) | Infinity + | (-3,4) | (1e+300,Infinity) | Infinity + | (0,0) | (1e+300,Infinity) | Infinity + | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + | (5.1,34.5) | (1e+300,Infinity) | Infinity + | (10,10) | (1e+300,Infinity) | Infinity +(27 rows) -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance FROM POINT_TBL p1, POINT_TBL p2 WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1 ORDER BY distance; - three | point1 | point2 | distance --------+------------+----------+------------------ - | (-3,4) | (0,0) | 5 - | (-10,0) | (-5,-12) | 13 - | (5.1,34.5) | (10,10) | 24.9851956166046 -(3 rows) + three | point1 | point2 | distance +-------+------------+------------------+------------------ + | (-3,4) | (0,0) | 5 + | (-3,4) | (1e-300,-1e-300) | 5 + | (-10,0) | (-5,-12) | 13 + | (5.1,34.5) | (10,10) | 24.9851956166046 +(4 rows) -- Test that GiST indexes provide same behavior as sequential scan CREATE TEMP TABLE point_gist_tbl(f1 point); diff --git a/src/test/regress/expected/polygon.out b/src/test/regress/expected/polygon.out index 4a1f60427ab..a1f5cce5cb2 100644 --- a/src/test/regress/expected/polygon.out +++ b/src/test/regress/expected/polygon.out @@ -6,6 +6,9 @@ CREATE TABLE POLYGON_TBL(f1 polygon); INSERT INTO POLYGON_TBL(f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)'); INSERT INTO POLYGON_TBL(f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)'); +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(3,4),(5,6),(7,8)'); +INSERT INTO POLYGON_TBL(f1) VALUES ('(7,8),(5,6),(3,4),(1,2)'); -- Reverse +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)'); -- degenerate polygons INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,0.0)'); INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,1.0),(0.0,1.0)'); @@ -31,201 +34,16 @@ ERROR: invalid input syntax for type polygon: "asdf" LINE 1: INSERT INTO POLYGON_TBL(f1) VALUES ('asdf'); ^ SELECT '' AS four, * FROM POLYGON_TBL; - four | f1 -------+--------------------- + four | f1 +------+---------------------------- | ((2,0),(2,4),(0,0)) | ((3,1),(3,3),(1,0)) + | ((1,2),(3,4),(5,6),(7,8)) + | ((7,8),(5,6),(3,4),(1,2)) + | ((1,2),(7,8),(5,6),(3,-4)) | ((0,0)) | ((0,1),(0,1)) -(4 rows) - --- overlap -SELECT '' AS three, p.* - FROM POLYGON_TBL p - WHERE p.f1 && '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - three | f1 --------+--------------------- - | ((2,0),(2,4),(0,0)) - | ((3,1),(3,3),(1,0)) -(2 rows) - --- left overlap -SELECT '' AS four, p.* - FROM POLYGON_TBL p - WHERE p.f1 &< '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - four | f1 -------+--------------------- - | ((2,0),(2,4),(0,0)) - | ((3,1),(3,3),(1,0)) - | ((0,0)) - | ((0,1),(0,1)) -(4 rows) - --- right overlap -SELECT '' AS two, p.* - FROM POLYGON_TBL p - WHERE p.f1 &> '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - two | f1 ------+--------------------- - | ((3,1),(3,3),(1,0)) -(1 row) - --- left of -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 << '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - one | f1 ------+--------------- - | ((0,0)) - | ((0,1),(0,1)) -(2 rows) - --- right of -SELECT '' AS zero, p.* - FROM POLYGON_TBL p - WHERE p.f1 >> '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - zero | f1 -------+---- -(0 rows) - --- contained -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 <@ polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - one | f1 ------+--------------------- - | ((3,1),(3,3),(1,0)) -(1 row) - --- same -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 ~= polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - one | f1 ------+--------------------- - | ((3,1),(3,3),(1,0)) -(1 row) - --- contains -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 @> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - one | f1 ------+--------------------- - | ((3,1),(3,3),(1,0)) -(1 row) - --- --- polygon logic --- --- left of -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' << polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - --- left overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' << polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS true; - true ------- - f -(1 row) - --- right overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' &> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - --- right of -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' >> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - --- contained in -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' <@ polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - --- contains -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' @> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - -SELECT '((0,4),(6,4),(1,2),(6,0),(0,0))'::polygon @> '((2,1),(2,3),(3,3),(3,1))'::polygon AS "false"; - false -------- - f -(1 row) - -SELECT '((0,4),(6,4),(3,2),(6,0),(0,0))'::polygon @> '((2,1),(2,3),(3,3),(3,1))'::polygon AS "true"; - true ------- - t -(1 row) - -SELECT '((1,1),(1,4),(5,4),(5,3),(2,3),(2,2),(5,2),(5,1))'::polygon @> '((3,2),(3,3),(4,3),(4,2))'::polygon AS "false"; - false -------- - f -(1 row) - -SELECT '((0,0),(0,3),(3,3),(3,0))'::polygon @> '((2,1),(2,2),(3,2),(3,1))'::polygon AS "true"; - true ------- - t -(1 row) - --- same -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' ~= polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - false -------- - f -(1 row) - --- overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' && polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS true; - true ------- - t -(1 row) - -SELECT '((0,4),(6,4),(1,2),(6,0),(0,0))'::polygon && '((2,1),(2,3),(3,3),(3,1))'::polygon AS "true"; - true ------- - t -(1 row) - -SELECT '((1,4),(1,1),(4,1),(4,2),(2,2),(2,4),(1,4))'::polygon && '((3,3),(4,3),(4,4),(3,4),(3,3))'::polygon AS "false"; - false -------- - f -(1 row) - -SELECT '((200,800),(800,800),(800,200),(200,200))' && '(1000,1000,0,0)'::polygon AS "true"; - true ------- - t -(1 row) - --- distance from a point -SELECT '(0,0)'::point <-> '((0,0),(1,2),(2,1))'::polygon as on_corner, - '(1,1)'::point <-> '((0,0),(2,2),(1,3))'::polygon as on_segment, - '(2,2)'::point <-> '((0,0),(1,4),(3,1))'::polygon as inside, - '(3,3)'::point <-> '((0,2),(2,0),(2,2))'::polygon as near_corner, - '(4,4)'::point <-> '((0,0),(0,3),(4,0))'::polygon as near_segment; - on_corner | on_segment | inside | near_corner | near_segment ------------+------------+--------+-----------------+-------------- - 0 | 0 | 0 | 1.4142135623731 | 3.2 -(1 row) +(7 rows) -- -- Test the SP-GiST index @@ -248,13 +66,10 @@ CREATE INDEX quad_poly_tbl_idx ON quad_poly_tbl USING spgist(p); SET enable_seqscan = ON; SET enable_indexscan = OFF; SET enable_bitmapscan = OFF; -CREATE TABLE quad_poly_tbl_ord_seq1 AS -SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id -FROM quad_poly_tbl; -CREATE TABLE quad_poly_tbl_ord_seq2 AS +CREATE TEMP TABLE quad_poly_tbl_ord_seq2 AS SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; --- check results results from index scan +-- check results from index scan SET enable_seqscan = OFF; SET enable_indexscan = OFF; SET enable_bitmapscan = ON; @@ -462,6 +277,32 @@ SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(2 1000 (1 row) +-- test ORDER BY distance +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + QUERY PLAN +--------------------------------------------------------------------------------- + WindowAgg + -> Index Scan using quad_poly_tbl_idx on quad_poly_tbl + Index Cond: (p <@ '((300,300),(400,600),(600,500),(700,200))'::polygon) + Order By: (p <-> '(123,456)'::point) +(4 rows) + +CREATE TEMP TABLE quad_poly_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; +SELECT * +FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + n | dist | id | n | dist | id +---+------+----+---+------+---- +(0 rows) + RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out index 67e70c8c140..986417a1881 100644 --- a/src/test/regress/expected/polymorphism.out +++ b/src/test/regress/expected/polymorphism.out @@ -1478,6 +1478,42 @@ select dfunc('a'::text, 'b', flag => true); -- mixed notation a (1 row) +-- this tests lexer edge cases around => +select dfunc(a =>-1); + dfunc +------- + -1 +(1 row) + +select dfunc(a =>+1); + dfunc +------- + 1 +(1 row) + +select dfunc(a =>/**/1); + dfunc +------- + 1 +(1 row) + +select dfunc(a =>--comment to be removed by psql + 1); + dfunc +------- + 1 +(1 row) + +-- need DO to protect the -- from psql +do $$ + declare r integer; + begin + select dfunc(a=>-- comment + 1) into r; + raise info 'r = %', r; + end; +$$; +INFO: r = 1 -- check reverse-listing of named-arg calls CREATE VIEW dfview AS SELECT q1, q2, diff --git a/src/test/regress/expected/portals.out b/src/test/regress/expected/portals.out index 048b2fc3e3a..dc0d2ef7dd8 100644 --- a/src/test/regress/expected/portals.out +++ b/src/test/regress/expected/portals.out @@ -1269,6 +1269,76 @@ SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'; ---------- (0 rows) +ROLLBACK; +-- Check behavior with rewinding to a previous child scan node, +-- as per bug #15395 +BEGIN; +CREATE TABLE current_check (currentid int, payload text); +CREATE TABLE current_check_1 () INHERITS (current_check); +CREATE TABLE current_check_2 () INHERITS (current_check); +INSERT INTO current_check_1 SELECT i, 'p' || i FROM generate_series(1,9) i; +INSERT INTO current_check_2 SELECT i, 'P' || i FROM generate_series(10,19) i; +DECLARE c1 SCROLL CURSOR FOR SELECT * FROM current_check; +-- This tests the fetch-backwards code path +FETCH ABSOLUTE 12 FROM c1; + currentid | payload +-----------+--------- + 12 | P12 +(1 row) + +FETCH ABSOLUTE 8 FROM c1; + currentid | payload +-----------+--------- + 8 | p8 +(1 row) + +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *; + currentid | payload +-----------+--------- + 8 | p8 +(1 row) + +-- This tests the ExecutorRewind code path +FETCH ABSOLUTE 13 FROM c1; + currentid | payload +-----------+--------- + 13 | P13 +(1 row) + +FETCH ABSOLUTE 1 FROM c1; + currentid | payload +-----------+--------- + 1 | p1 +(1 row) + +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *; + currentid | payload +-----------+--------- + 1 | p1 +(1 row) + +SELECT * FROM current_check; + currentid | payload +-----------+--------- + 2 | p2 + 3 | p3 + 4 | p4 + 5 | p5 + 6 | p6 + 7 | p7 + 9 | p9 + 10 | P10 + 11 | P11 + 12 | P12 + 13 | P13 + 14 | P14 + 15 | P15 + 16 | P16 + 17 | P17 + 18 | P18 + 19 | P19 +(17 rows) + ROLLBACK; -- Make sure snapshot management works okay, per bug report in -- 235395b90909301035v7228ce63q392931f15aa74b31@mail.gmail.com diff --git a/src/test/regress/expected/prepare.out b/src/test/regress/expected/prepare.out index 7016e82bd42..717732300d1 100644 --- a/src/test/regress/expected/prepare.out +++ b/src/test/regress/expected/prepare.out @@ -64,11 +64,11 @@ EXECUTE q2('postgres'); postgres | f | t (1 row) -PREPARE q3(text, int, float, boolean, oid, smallint) AS +PREPARE q3(text, int, float, boolean, smallint) AS SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR - ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int) + ten = $3::bigint OR true = $4 OR odd = $5::int) ORDER BY unique1; -EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint); +EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- 2 | 2716 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 4 | 5 | CAAAAA | MAEAAA | AAAAxx @@ -105,13 +105,13 @@ EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint); -- too few params EXECUTE q3('bool'); ERROR: wrong number of parameters for prepared statement "q3" -DETAIL: Expected 6 parameters but got 1. +DETAIL: Expected 5 parameters but got 1. -- too many params -EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 500::oid, 4::bigint, true); +EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); ERROR: wrong number of parameters for prepared statement "q3" -DETAIL: Expected 6 parameters but got 7. +DETAIL: Expected 5 parameters but got 6. -- wrong param types -EXECUTE q3(5::smallint, 10.5::float, false, 500::oid, 4::bigint, 'bytea'); +EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); ERROR: parameter $3 of type boolean cannot be coerced to the expected type double precision HINT: You will need to rewrite or cast the expression. -- invalid type @@ -145,6 +145,13 @@ SELECT * FROM q5_prep_results; 9961 | 2058 | 1 | 1 | 1 | 1 | 61 | 961 | 1961 | 4961 | 9961 | 122 | 123 | DTAAAA | EBDAAA | OOOOxx (16 rows) +CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') + WITH NO DATA; +SELECT * FROM q5_prep_nodata; + unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 +---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- +(0 rows) + -- unknown or unspecified parameter types: should succeed PREPARE q6 AS SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; @@ -152,22 +159,22 @@ PREPARE q7(unknown) AS SELECT * FROM road WHERE thepath = $1; SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name; - name | statement | parameter_types -------+---------------------------------------------------------------------+-------------------------------------------------------- - q2 | PREPARE q2(text) AS +| {text} - | SELECT datname, datistemplate, datallowconn +| - | FROM pg_database WHERE datname = $1; | - q3 | PREPARE q3(text, int, float, boolean, oid, smallint) AS +| {text,integer,"double precision",boolean,oid,smallint} - | SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR +| - | ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int)+| - | ORDER BY unique1; | - q5 | PREPARE q5(int, text) AS +| {integer,text} - | SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +| - | ORDER BY unique1; | - q6 | PREPARE q6 AS +| {integer,name} - | SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | - q7 | PREPARE q7(unknown) AS +| {path} - | SELECT * FROM road WHERE thepath = $1; | + name | statement | parameter_types +------+------------------------------------------------------------------+---------------------------------------------------- + q2 | PREPARE q2(text) AS +| {text} + | SELECT datname, datistemplate, datallowconn +| + | FROM pg_database WHERE datname = $1; | + q3 | PREPARE q3(text, int, float, boolean, smallint) AS +| {text,integer,"double precision",boolean,smallint} + | SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR+| + | ten = $3::bigint OR true = $4 OR odd = $5::int) +| + | ORDER BY unique1; | + q5 | PREPARE q5(int, text) AS +| {integer,text} + | SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +| + | ORDER BY unique1; | + q6 | PREPARE q6 AS +| {integer,name} + | SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | + q7 | PREPARE q7(unknown) AS +| {path} + | SELECT * FROM road WHERE thepath = $1; | (5 rows) -- test DEALLOCATE ALL; diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out index 864f2c13457..0ddbd8e89fd 100644 --- a/src/test/regress/expected/privileges.out +++ b/src/test/regress/expected/privileges.out @@ -185,7 +185,7 @@ SELECT * FROM atest1; -- ok (2 rows) -- test leaky-function protections in selfuncs --- regress_priv_user1 will own a table and provide a view for it. +-- regress_priv_user1 will own a table and provide views for it. SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE atest12 as SELECT x AS a, 10001 - x AS b FROM generate_series(1,10000) x; @@ -197,10 +197,13 @@ CREATE FUNCTION leak(integer,integer) RETURNS boolean LANGUAGE plpgsql immutable; CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, restrict = scalarltsel); --- view with leaky operator +-- views with leaky operator CREATE VIEW atest12v AS SELECT * FROM atest12 WHERE b <<< 5; +CREATE VIEW atest12sbv WITH (security_barrier=true) AS + SELECT * FROM atest12 WHERE b <<< 5; GRANT SELECT ON atest12v TO PUBLIC; +GRANT SELECT ON atest12sbv TO PUBLIC; -- This plan should use nestloop, knowing that few rows will be selected. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; QUERY PLAN @@ -225,6 +228,20 @@ EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y Index Cond: (a = y.b) (5 rows) +-- This should also be a nestloop, but the security barrier forces the inner +-- scan to be materialized +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; + QUERY PLAN +------------------------------------------- + Nested Loop + Join Filter: (atest12.a = atest12_1.b) + -> Seq Scan on atest12 + Filter: (b <<< 5) + -> Materialize + -> Seq Scan on atest12 atest12_1 + Filter: (b <<< 5) +(7 rows) + -- Check if regress_priv_user2 can break security. SET SESSION AUTHORIZATION regress_priv_user2; CREATE FUNCTION leak2(integer,integer) RETURNS boolean @@ -235,24 +252,64 @@ CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer, -- This should not show any "leak" notices before failing. EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0; ERROR: permission denied for table atest12 --- This plan should use hashjoin, as it will expect many rows to be selected. +-- These plans should continue to use a nestloop, since they execute with the +-- privileges of the view owner. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; + QUERY PLAN +------------------------------------------------- + Nested Loop + -> Seq Scan on atest12 atest12_1 + Filter: (b <<< 5) + -> Index Scan using atest12_a_idx on atest12 + Index Cond: (a = atest12_1.b) + Filter: (b <<< 5) +(6 rows) + +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; QUERY PLAN ------------------------------------------- - Hash Join - Hash Cond: (atest12.a = atest12_1.b) + Nested Loop + Join Filter: (atest12.a = atest12_1.b) -> Seq Scan on atest12 Filter: (b <<< 5) - -> Hash + -> Materialize -> Seq Scan on atest12 atest12_1 Filter: (b <<< 5) (7 rows) +-- A non-security barrier view does not guard against information leakage. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y + WHERE x.a = y.b and abs(y.a) <<< 5; + QUERY PLAN +------------------------------------------------- + Nested Loop + -> Seq Scan on atest12 atest12_1 + Filter: ((b <<< 5) AND (abs(a) <<< 5)) + -> Index Scan using atest12_a_idx on atest12 + Index Cond: (a = atest12_1.b) + Filter: (b <<< 5) +(6 rows) + +-- But a security barrier view isolates the leaky operator. +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y + WHERE x.a = y.b and abs(y.a) <<< 5; + QUERY PLAN +------------------------------------- + Nested Loop + Join Filter: (atest12_1.a = y.b) + -> Subquery Scan on y + Filter: (abs(y.a) <<< 5) + -> Seq Scan on atest12 + Filter: (b <<< 5) + -> Seq Scan on atest12 atest12_1 + Filter: (b <<< 5) +(8 rows) + -- Now regress_priv_user1 grants sufficient access to regress_priv_user2. SET SESSION AUTHORIZATION regress_priv_user1; GRANT SELECT (a, b) ON atest12 TO PUBLIC; SET SESSION AUTHORIZATION regress_priv_user2; --- Now regress_priv_user2 will also get a good row estimate. +-- regress_priv_user2 should continue to get a good row estimate. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; QUERY PLAN ------------------------------------------------- @@ -517,104 +574,6 @@ SELECT atest6 FROM atest6; -- ok (0 rows) COPY atest6 TO stdout; -- ok --- test column privileges with MERGE -SET SESSION AUTHORIZATION regress_priv_user1; -CREATE TABLE mtarget (a int, b text); -CREATE TABLE msource (a int, b text); -INSERT INTO mtarget VALUES (1, 'init1'), (2, 'init2'); -INSERT INTO msource VALUES (1, 'source1'), (2, 'source2'), (3, 'source3'); -GRANT SELECT (a) ON msource TO regress_priv_user4; -GRANT SELECT (a) ON mtarget TO regress_priv_user4; -GRANT INSERT (a,b) ON mtarget TO regress_priv_user4; -GRANT UPDATE (b) ON mtarget TO regress_priv_user4; -SET SESSION AUTHORIZATION regress_priv_user4; --- --- test source privileges --- --- fail (no SELECT priv on s.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); -ERROR: permission denied for table msource --- fail (s.b used in the INSERTed values) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = 'x' -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); -ERROR: permission denied for table msource --- fail (s.b used in the WHEN quals) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND s.b = 'x' THEN - UPDATE SET b = 'x' -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); -ERROR: permission denied for table msource --- this should be ok since only s.a is accessed -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = 'ok' -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); -ROLLBACK; -SET SESSION AUTHORIZATION regress_priv_user1; -GRANT SELECT (b) ON msource TO regress_priv_user4; -SET SESSION AUTHORIZATION regress_priv_user4; --- should now be ok -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); -ROLLBACK; --- --- test target privileges --- --- fail (no SELECT priv on t.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = t.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); -ERROR: permission denied for table mtarget --- fail (no UPDATE on t.a) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b, a = t.a + 1 -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); -ERROR: permission denied for table mtarget --- fail (no SELECT on t.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); -ERROR: permission denied for table mtarget --- ok -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b; -ROLLBACK; --- fail (no DELETE) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - DELETE; -ERROR: permission denied for table mtarget --- grant delete privileges -SET SESSION AUTHORIZATION regress_priv_user1; -GRANT DELETE ON mtarget TO regress_priv_user4; --- should be ok now -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - DELETE; -ROLLBACK; -- check error reporting with column privs SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE t1 (c1 int, c2 int, c3 int check (c3 < 5), primary key (c1, c2)); @@ -685,10 +644,10 @@ ERROR: permission denied for table atest5 DELETE FROM atest5 WHERE two = 2; -- ok -- check inheritance cases SET SESSION AUTHORIZATION regress_priv_user1; -CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS; -CREATE TABLE atestp2 (fx int, fy int) WITH OIDS; +CREATE TABLE atestp1 (f1 int, f2 int); +CREATE TABLE atestp2 (fx int, fy int); CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2); -GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_priv_user2; +GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2; GRANT SELECT(fx) ON atestc TO regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2; SELECT fx FROM atestp2; -- ok @@ -706,15 +665,15 @@ SELECT atestp2 FROM atestp2; -- ok --------- (0 rows) -SELECT oid FROM atestp2; -- ok - oid ------ +SELECT tableoid FROM atestp2; -- ok + tableoid +---------- (0 rows) SELECT fy FROM atestc; -- fail ERROR: permission denied for table atestc SET SESSION AUTHORIZATION regress_priv_user1; -GRANT SELECT(fy,oid) ON atestc TO regress_priv_user2; +GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2; SELECT fx FROM atestp2; -- still ok fx @@ -731,9 +690,9 @@ SELECT atestp2 FROM atestp2; -- ok --------- (0 rows) -SELECT oid FROM atestp2; -- ok - oid ------ +SELECT tableoid FROM atestp2; -- ok + tableoid +---------- (0 rows) -- privileges on functions, languages @@ -836,7 +795,7 @@ SELECT '{1}'::int4[]::int8[]; (1 row) REVOKE ALL ON FUNCTION int8(integer) FROM PUBLIC; -SELECT '{1}'::int4[]::int8[]; --superuser, suceed +SELECT '{1}'::int4[]::int8[]; --superuser, succeed int8 ------ {1} @@ -1230,6 +1189,64 @@ from (select oid from pg_class where relname = 'atest1') as t1; f (1 row) +-- has_column_privilege function +-- bad-input checks (as non-super-user) +select has_column_privilege('pg_authid',NULL,'select'); + has_column_privilege +---------------------- + +(1 row) + +select has_column_privilege('pg_authid','nosuchcol','select'); +ERROR: column "nosuchcol" of relation "pg_authid" does not exist +select has_column_privilege(9999,'nosuchcol','select'); + has_column_privilege +---------------------- + +(1 row) + +select has_column_privilege(9999,99::int2,'select'); + has_column_privilege +---------------------- + +(1 row) + +select has_column_privilege('pg_authid',99::int2,'select'); + has_column_privilege +---------------------- + +(1 row) + +select has_column_privilege(9999,99::int2,'select'); + has_column_privilege +---------------------- + +(1 row) + +create temp table mytable(f1 int, f2 int, f3 int); +alter table mytable drop column f2; +select has_column_privilege('mytable','f2','select'); +ERROR: column "f2" of relation "mytable" does not exist +select has_column_privilege('mytable','........pg.dropped.2........','select'); + has_column_privilege +---------------------- + +(1 row) + +select has_column_privilege('mytable',2::int2,'select'); + has_column_privilege +---------------------- + t +(1 row) + +revoke select on table mytable from regress_priv_user3; +select has_column_privilege('mytable',2::int2,'select'); + has_column_privilege +---------------------- + +(1 row) + +drop table mytable; -- Grant options SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE atest4 (a int); @@ -1611,6 +1628,12 @@ SELECT has_table_privilege('regress_priv_user1', 'testns.acltest1', 'INSERT'); - ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS FROM public; ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; -- error ERROR: cannot use IN SCHEMA clause when using GRANT/REVOKE ON SCHEMAS +-- +-- Testing blanket default grants is very hazardous since it might change +-- the privileges attached to objects created by concurrent regression tests. +-- To avoid that, be sure to revoke the privileges again before committing. +-- +BEGIN; ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_priv_user2; CREATE SCHEMA testns2; SELECT has_schema_privilege('regress_priv_user2', 'testns2', 'USAGE'); -- yes @@ -1654,6 +1677,7 @@ SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'CREATE'); -- yes (1 row) ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2; +COMMIT; CREATE SCHEMA testns5; SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'USAGE'); -- no has_schema_privilege @@ -1753,8 +1777,8 @@ DROP SCHEMA testns5 CASCADE; SELECT d.* -- check that entries went away FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid WHERE nspname IS NULL AND defaclnamespace != 0; - defaclrole | defaclnamespace | defaclobjtype | defaclacl -------------+-----------------+---------------+----------- + oid | defaclrole | defaclnamespace | defaclobjtype | defaclacl +-----+------------+-----------------+---------------+----------- (0 rows) -- Grant on all objects of given type in a schema @@ -1860,10 +1884,13 @@ SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', t (1 row) -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA testns CASCADE; NOTICE: drop cascades to 5 other objects -\set VERBOSITY default +DETAIL: drop cascades to table testns.t1 +drop cascades to table testns.t2 +drop cascades to function testns.priv_testfunc(integer) +drop cascades to function testns.priv_testagg(integer) +drop cascades to function testns.priv_testproc(integer) -- Change owner of the schema & and rename of new schema owner \c - CREATE ROLE regress_schemauser1 superuser login; @@ -1885,9 +1912,7 @@ SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = (1 row) set session role regress_schemauser_renamed; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA testns CASCADE; -\set VERBOSITY default -- clean up \c - DROP ROLE regress_schemauser1; diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 3818cfea7e4..242f817163e 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -260,6 +260,7 @@ select '2000-01-01'::date as party_over \pset border 1 columns 0 +csv_fieldsep ',' expanded off fieldsep '|' fieldsep_zero off @@ -279,6 +280,7 @@ unicode_border_linestyle single unicode_column_linestyle single unicode_header_linestyle single -- test multi-line headers, wrapping, and newline indicators +-- in aligned, unaligned, and wrapped formats prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a @@ -2636,71 +2638,300 @@ execute q; deallocate q; \pset linestyle ascii -prepare q as select ' | = | lkjsafi\\/ /oeu rio)(!@&*#)*(!&@*) \ (&' as " | -- | 012345678 9abc def!*@#&!@(*&*~~_+-=\ \", '11' as "0123456789", 11 as int from generate_series(1,10) as n; +\pset border 1 +-- support table for output-format tests (useful to create a footer) +create table psql_serial_tab (id serial); +-- test header/footer/tuples_only behavior in aligned/unaligned/wrapped cases +\pset format aligned +\pset expanded off +\d psql_serial_tab_id_seq + Sequence "public.psql_serial_tab_id_seq" + Type | Start | Minimum | Maximum | Increment | Cycles? | Cache +---------+-------+---------+------------+-----------+---------+------- + integer | 1 | 1 | 2147483647 | 1 | no | 1 +Owned by: public.psql_serial_tab.id + +\pset tuples_only true +\df exp + pg_catalog | exp | double precision | double precision | func + pg_catalog | exp | numeric | numeric | func + +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +Sequence "public.psql_serial_tab_id_seq" +-[ RECORD 1 ]--------- +Type | integer +Start | 1 +Minimum | 1 +Maximum | 2147483647 +Increment | 1 +Cycles? | no +Cache | 1 + +Owned by: public.psql_serial_tab.id + +\pset tuples_only true +\df exp +Schema | pg_catalog +Name | exp +Result data type | double precision +Argument data types | double precision +Type | func +--------------------+----------------- +Schema | pg_catalog +Name | exp +Result data type | numeric +Argument data types | numeric +Type | func + +\pset tuples_only false +-- empty table is a special case for this format +select 1 where false; +(0 rows) + +\pset format unaligned +\pset expanded off +\d psql_serial_tab_id_seq +Sequence "public.psql_serial_tab_id_seq" +Type|Start|Minimum|Maximum|Increment|Cycles?|Cache +integer|1|1|2147483647|1|no|1 +Owned by: public.psql_serial_tab.id +\pset tuples_only true +\df exp +pg_catalog|exp|double precision|double precision|func +pg_catalog|exp|numeric|numeric|func +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +Sequence "public.psql_serial_tab_id_seq" + +Type|integer +Start|1 +Minimum|1 +Maximum|2147483647 +Increment|1 +Cycles?|no +Cache|1 + +Owned by: public.psql_serial_tab.id +\pset tuples_only true +\df exp +Schema|pg_catalog +Name|exp +Result data type|double precision +Argument data types|double precision +Type|func + +Schema|pg_catalog +Name|exp +Result data type|numeric +Argument data types|numeric +Type|func +\pset tuples_only false +\pset format wrapped +\pset expanded off +\d psql_serial_tab_id_seq + Sequence "public.psql_serial_tab_id_seq" + Type | Start | Minimum | Maximum | Increment | Cycles? | Cache +---------+-------+---------+------------+-----------+---------+------- + integer | 1 | 1 | 2147483647 | 1 | no | 1 +Owned by: public.psql_serial_tab.id + +\pset tuples_only true +\df exp + pg_catalog | exp | double precision | double precision | func + pg_catalog | exp | numeric | numeric | func + +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +Sequence "public.psql_serial_tab_id_seq" +-[ RECORD 1 ]--------- +Type | integer +Start | 1 +Minimum | 1 +Maximum | 2147483647 +Increment | 1 +Cycles? | no +Cache | 1 + +Owned by: public.psql_serial_tab.id + +\pset tuples_only true +\df exp +Schema | pg_catalog +Name | exp +Result data type | double precision +Argument data types | double precision +Type | func +--------------------+----------------- +Schema | pg_catalog +Name | exp +Result data type | numeric +Argument data types | numeric +Type | func + +\pset tuples_only false +-- check conditional tableam display +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap_psql TYPE TABLE HANDLER heap_tableam_handler; +CREATE TABLE tbl_heap_psql(f1 int, f2 char(100)) using heap_psql; +CREATE TABLE tbl_heap(f1 int, f2 char(100)) using heap; +\d+ tbl_heap_psql + Table "public.tbl_heap_psql" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+----------------+-----------+----------+---------+----------+--------------+------------- + f1 | integer | | | | plain | | + f2 | character(100) | | | | extended | | + +\d+ tbl_heap + Table "public.tbl_heap" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+----------------+-----------+----------+---------+----------+--------------+------------- + f1 | integer | | | | plain | | + f2 | character(100) | | | | extended | | + +\set HIDE_TABLEAM off +\d+ tbl_heap_psql + Table "public.tbl_heap_psql" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+----------------+-----------+----------+---------+----------+--------------+------------- + f1 | integer | | | | plain | | + f2 | character(100) | | | | extended | | +Access method: heap_psql + +\d+ tbl_heap + Table "public.tbl_heap" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+----------------+-----------+----------+---------+----------+--------------+------------- + f1 | integer | | | | plain | | + f2 | character(100) | | | | extended | | +Access method: heap + +\set HIDE_TABLEAM on +DROP TABLE tbl_heap, tbl_heap_psql; +DROP ACCESS METHOD heap_psql; +-- test numericlocale (as best we can without control of psql's locale) +\pset format aligned +\pset expanded off +\pset numericlocale true +select n, -n as m, n * 111 as x, '1e90'::float8 as f +from generate_series(0,3) n; + n | m | x | f +---+----+-----+------- + 0 | 0 | 0 | 1e+90 + 1 | -1 | 111 | 1e+90 + 2 | -2 | 222 | 1e+90 + 3 | -3 | 333 | 1e+90 +(4 rows) + +\pset numericlocale false +-- test asciidoc output format \pset format asciidoc +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq + +.Sequence "public.psql_serial_tab_id_seq" +[options="header",cols="l,>l,>l,>l,l",frame="none"] +|==== +^l|Type ^l|Start ^l|Minimum ^l|Maximum ^l|Increment ^l|Cycles? ^l|Cache +|integer |1 |1 |2147483647 |1 |no |1 +|==== + +.... +Owned by: public.psql_serial_tab.id +.... +\pset tuples_only true +\df exp + +[cols="l|1 +l|1 +l|2147483647 +l|1 +l|1 +|==== + +.... +Owned by: public.psql_serial_tab.id +.... +\pset tuples_only true +\df exp + +[cols="h,l",frame="none"] +|==== +2+| +l|11 +l|1 2+^|Record 2 -l|11 -2+^|Record 3 -l|11 -2+^|Record 4 -l|11 -2+^|Record 5 -l|11 -2+^|Record 6 -l|11 -2+^|Record 7 -l|11 -2+^|Record 8 -l|11 -2+^|Record 9 -l|11 -2+^|Record 10 -l|11 +l|2 |==== \pset border 1 execute q; @@ -2755,45 +2954,13 @@ execute q; [cols="h,l",frame="none"] |==== 2+^|Record 1 -l|11 +l|1 2+^|Record 2 -l|11 -2+^|Record 3 -l|11 -2+^|Record 4 -l|11 -2+^|Record 5 -l|11 -2+^|Record 6 -l|11 -2+^|Record 7 -l|11 -2+^|Record 8 -l|11 -2+^|Record 9 -l|11 -2+^|Record 10 -l|11 +l|2 |==== \pset border 2 execute q; @@ -2801,50 +2968,1237 @@ execute q; [cols="h,l",frame="all",grid="all"] |==== 2+^|Record 1 -l|11 +l|1 2+^|Record 2 -l|11 -2+^|Record 3 -l|11 -2+^|Record 4 -l|11 -2+^|Record 5 -l|11 -2+^|Record 6 -l|11 -2+^|Record 7 -l|11 -2+^|Record 8 -l|11 -2+^|Record 9 -l|11 -2+^|Record 10 -l|11 +l|2 |==== deallocate q; +-- test csv output format +\pset format csv +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +Type,Start,Minimum,Maximum,Increment,Cycles?,Cache +integer,1,1,2147483647,1,no,1 +\pset tuples_only true +\df exp +pg_catalog,exp,double precision,double precision,func +pg_catalog,exp,numeric,numeric,func +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +Type,integer +Start,1 +Minimum,1 +Maximum,2147483647 +Increment,1 +Cycles?,no +Cache,1 +\pset tuples_only true +\df exp +Schema,pg_catalog +Name,exp +Result data type,double precision +Argument data types,double precision +Type,func +Schema,pg_catalog +Name,exp +Result data type,numeric +Argument data types,numeric +Type,func +\pset tuples_only false +prepare q as + select 'some"text' as "a""title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; +\pset expanded off +execute q; +"a""title",junk,empty,int +"some""text"," +", ,1 +"some""text"," +", ,2 +\pset expanded on +execute q; +"a""title","some""text" +junk," +" +empty, +int,1 +"a""title","some""text" +junk," +" +empty, +int,2 +deallocate q; +-- special cases +\pset expanded off +select 'comma,comma' as comma, 'semi;semi' as semi; +comma,semi +"comma,comma",semi;semi +\pset csv_fieldsep ';' +select 'comma,comma' as comma, 'semi;semi' as semi; +comma;semi +comma,comma;"semi;semi" +select '\.' as data; +data +"\." +\pset csv_fieldsep '.' +select '\' as d1, '' as d2; +"d1"."d2" +"\"."" +-- illegal csv separators +\pset csv_fieldsep '' +\pset: csv_fieldsep must be a single one-byte character +\pset csv_fieldsep '\0' +\pset: csv_fieldsep must be a single one-byte character +\pset csv_fieldsep '\n' +\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return +\pset csv_fieldsep '\r' +\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return +\pset csv_fieldsep '"' +\pset: csv_fieldsep cannot be a double quote, a newline, or a carriage return +\pset csv_fieldsep ',,' +\pset: csv_fieldsep must be a single one-byte character +\pset csv_fieldsep ',' +-- test html output format +\pset format html +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq + + + + + + + + + + + + + + + + + + + + +
Sequence "public.psql_serial_tab_id_seq"
TypeStartMinimumMaximumIncrementCycles?Cache
integer1121474836471no1
+

Owned by: public.psql_serial_tab.id
+

+\pset tuples_only true +\df exp + + + + + + + + + + + + + + + +
pg_catalogexpdouble precisiondouble precisionfunc
pg_catalogexpnumericnumericfunc
+ +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sequence "public.psql_serial_tab_id_seq"
Record 1
Typeinteger
Start1
Minimum1
Maximum2147483647
Increment1
Cycles?no
Cache1
+

Owned by: public.psql_serial_tab.id
+

+\pset tuples_only true +\df exp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Schemapg_catalog
Nameexp
Result data typedouble precision
Argument data typesdouble precision
Typefunc
 
Schemapg_catalog
Nameexp
Result data typenumeric
Argument data typesnumeric
Typefunc
+ +\pset tuples_only false +prepare q as + select 'some"text' as "a&title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; +\pset expanded off +\pset border 0 +execute q; + + + + + + + + + + + + + + + + + + + +
a&titlejunkemptyint
some"text  <foo>
+<bar>
  1
some"text  <foo>
+<bar>
  2
+

(2 rows)
+

+\pset border 1 +execute q; + + + + + + + + + + + + + + + + + + + +
a&titlejunkemptyint
some"text  <foo>
+<bar>
  1
some"text  <foo>
+<bar>
  2
+

(2 rows)
+

+\pset tableattr foobar +execute q; + + + + + + + + + + + + + + + + + + + +
a&titlejunkemptyint
some"text  <foo>
+<bar>
  1
some"text  <foo>
+<bar>
  2
+

(2 rows)
+

+\pset tableattr +\pset expanded on +\pset border 0 +execute q; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Record 1
a&titlesome"text
junk  <foo>
+<bar>
empty 
int1
Record 2
a&titlesome"text
junk  <foo>
+<bar>
empty 
int2
+ +\pset border 1 +execute q; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Record 1
a&titlesome"text
junk  <foo>
+<bar>
empty 
int1
Record 2
a&titlesome"text
junk  <foo>
+<bar>
empty 
int2
+ +\pset tableattr foobar +execute q; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Record 1
a&titlesome"text
junk  <foo>
+<bar>
empty 
int1
Record 2
a&titlesome"text
junk  <foo>
+<bar>
empty 
int2
+ +\pset tableattr +deallocate q; +-- test latex output format +\pset format latex +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\begin{center} +Sequence "public.psql\_serial\_tab\_id\_seq" +\end{center} + +\begin{tabular}{l | r | r | r | r | l | r} +\textit{Type} & \textit{Start} & \textit{Minimum} & \textit{Maximum} & \textit{Increment} & \textit{Cycles?} & \textit{Cache} \\ +\hline +integer & 1 & 1 & 2147483647 & 1 & no & 1 \\ +\end{tabular} + +\noindent Owned by: public.psql\_serial\_tab.id \\ + +\pset tuples_only true +\df exp +\begin{tabular}{l | l | l | l | l} +pg\_catalog & exp & double precision & double precision & func \\ +pg\_catalog & exp & numeric & numeric & func \\ +\end{tabular} + +\noindent +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\begin{center} +Sequence "public.psql\_serial\_tab\_id\_seq" +\end{center} + +\begin{tabular}{c|l} +\multicolumn{2}{c}{\textit{Record 1}} \\ +\hline +Type & integer \\ +Start & 1 \\ +Minimum & 1 \\ +Maximum & 2147483647 \\ +Increment & 1 \\ +Cycles? & no \\ +Cache & 1 \\ +\end{tabular} + +\noindent Owned by: public.psql\_serial\_tab.id \\ + +\pset tuples_only true +\df exp +\begin{tabular}{c|l} +\hline +Schema & pg\_catalog \\ +Name & exp \\ +Result data type & double precision \\ +Argument data types & double precision \\ +Type & func \\ +\hline +Schema & pg\_catalog \\ +Name & exp \\ +Result data type & numeric \\ +Argument data types & numeric \\ +Type & func \\ +\end{tabular} + +\noindent +\pset tuples_only false +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; +\pset expanded off +\pset border 0 +execute q; +\begin{tabular}{lllr} +\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\ +\hline +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\ +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\ +\end{tabular} + +\noindent (2 rows) \\ + +\pset border 1 +execute q; +\begin{tabular}{l | l | l | r} +\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\ +\hline +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\ +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\ +\end{tabular} + +\noindent (2 rows) \\ + +\pset border 2 +execute q; +\begin{tabular}{| l | l | l | r |} +\hline +\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\ +\hline +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\ +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\ +\hline +\end{tabular} + +\noindent (2 rows) \\ + +\pset border 3 +execute q; +\begin{tabular}{| l | l | l | r |} +\hline +\textit{a\$title} & \textit{junk} & \textit{empty} & \textit{int} \\ +\hline +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 1 \\ +\hline +some\textbackslash{}more\_text & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} & & 2 \\ +\hline +\end{tabular} + +\noindent (2 rows) \\ + +\pset expanded on +\pset border 0 +execute q; +\begin{tabular}{cl} +\multicolumn{2}{c}{\textit{Record 1}} \\ +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\multicolumn{2}{c}{\textit{Record 2}} \\ +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\end{tabular} + +\noindent +\pset border 1 +execute q; +\begin{tabular}{c|l} +\multicolumn{2}{c}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\multicolumn{2}{c}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\end{tabular} + +\noindent +\pset border 2 +execute q; +\begin{tabular}{|c|l|} +\hline +\multicolumn{2}{|c|}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\hline +\multicolumn{2}{|c|}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\hline +\end{tabular} + +\noindent +\pset border 3 +execute q; +\begin{tabular}{|c|l|} +\hline +\multicolumn{2}{|c|}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\hline +\multicolumn{2}{|c|}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\hline +\end{tabular} + +\noindent +deallocate q; +-- test latex-longtable output format +\pset format latex-longtable +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\begin{longtable}{l | r | r | r | r | l | r} +\small\textbf{\textit{Type}} & \small\textbf{\textit{Start}} & \small\textbf{\textit{Minimum}} & \small\textbf{\textit{Maximum}} & \small\textbf{\textit{Increment}} & \small\textbf{\textit{Cycles?}} & \small\textbf{\textit{Cache}} \\ +\midrule +\endfirsthead +\small\textbf{\textit{Type}} & \small\textbf{\textit{Start}} & \small\textbf{\textit{Minimum}} & \small\textbf{\textit{Maximum}} & \small\textbf{\textit{Increment}} & \small\textbf{\textit{Cycles?}} & \small\textbf{\textit{Cache}} \\ +\midrule +\endhead +\caption[Sequence "public.psql\_serial\_tab\_id\_seq" (Continued)]{Sequence "public.psql\_serial\_tab\_id\_seq"} +\endfoot +\caption[Sequence "public.psql\_serial\_tab\_id\_seq"]{Sequence "public.psql\_serial\_tab\_id\_seq"} +\endlastfoot +\raggedright{integer} +& +\raggedright{1} +& +\raggedright{1} +& +\raggedright{2147483647} +& +\raggedright{1} +& +\raggedright{no} +& +\raggedright{1} \tabularnewline +\end{longtable} +\pset tuples_only true +\df exp +\begin{longtable}{l | l | l | l | l} +\raggedright{pg\_catalog} +& +\raggedright{exp} +& +\raggedright{double precision} +& +\raggedright{double precision} +& +\raggedright{func} \tabularnewline +\raggedright{pg\_catalog} +& +\raggedright{exp} +& +\raggedright{numeric} +& +\raggedright{numeric} +& +\raggedright{func} \tabularnewline +\end{longtable} +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\begin{center} +Sequence "public.psql\_serial\_tab\_id\_seq" +\end{center} + +\begin{tabular}{c|l} +\multicolumn{2}{c}{\textit{Record 1}} \\ +\hline +Type & integer \\ +Start & 1 \\ +Minimum & 1 \\ +Maximum & 2147483647 \\ +Increment & 1 \\ +Cycles? & no \\ +Cache & 1 \\ +\end{tabular} + +\noindent Owned by: public.psql\_serial\_tab.id \\ + +\pset tuples_only true +\df exp +\begin{tabular}{c|l} +\hline +Schema & pg\_catalog \\ +Name & exp \\ +Result data type & double precision \\ +Argument data types & double precision \\ +Type & func \\ +\hline +Schema & pg\_catalog \\ +Name & exp \\ +Result data type & numeric \\ +Argument data types & numeric \\ +Type & func \\ +\end{tabular} + +\noindent +\pset tuples_only false +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; +\pset expanded off +\pset border 0 +execute q; +\begin{longtable}{lllr} +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endfirsthead +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endhead +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{1} \tabularnewline +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{2} \tabularnewline +\end{longtable} +\pset border 1 +execute q; +\begin{longtable}{l | l | l | r} +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endfirsthead +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endhead +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{1} \tabularnewline +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{2} \tabularnewline +\end{longtable} +\pset border 2 +execute q; +\begin{longtable}{| l | l | l | r |} +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endfirsthead +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endhead +\bottomrule +\endfoot +\bottomrule +\endlastfoot +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{1} \tabularnewline +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{2} \tabularnewline +\end{longtable} +\pset border 3 +execute q; +\begin{longtable}{| l | l | l | r |} +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endfirsthead +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\endhead +\bottomrule +\endfoot +\bottomrule +\endlastfoot +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{1} \tabularnewline + \hline +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{2} \tabularnewline + \hline +\end{longtable} +\pset tableattr lr +execute q; +\begin{longtable}{| p{lr\textwidth} | p{lr\textwidth} | p{lr\textwidth} | r |} +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\midrule +\endfirsthead +\toprule +\small\textbf{\textit{a\$title}} & \small\textbf{\textit{junk}} & \small\textbf{\textit{empty}} & \small\textbf{\textit{int}} \\ +\endhead +\bottomrule +\endfoot +\bottomrule +\endlastfoot +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{1} \tabularnewline + \hline +\raggedright{some\textbackslash{}more\_text} +& +\raggedright{ \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\}} +& +\raggedright{ } +& +\raggedright{2} \tabularnewline + \hline +\end{longtable} +\pset tableattr +\pset expanded on +\pset border 0 +execute q; +\begin{tabular}{cl} +\multicolumn{2}{c}{\textit{Record 1}} \\ +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\multicolumn{2}{c}{\textit{Record 2}} \\ +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\end{tabular} + +\noindent +\pset border 1 +execute q; +\begin{tabular}{c|l} +\multicolumn{2}{c}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\multicolumn{2}{c}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\end{tabular} + +\noindent +\pset border 2 +execute q; +\begin{tabular}{|c|l|} +\hline +\multicolumn{2}{|c|}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\hline +\multicolumn{2}{|c|}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\hline +\end{tabular} + +\noindent +\pset border 3 +execute q; +\begin{tabular}{|c|l|} +\hline +\multicolumn{2}{|c|}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\hline +\multicolumn{2}{|c|}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\hline +\end{tabular} + +\noindent +\pset tableattr lr +execute q; +\begin{tabular}{|c|l|} +\hline +\multicolumn{2}{|c|}{\textit{Record 1}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 1 \\ +\hline +\multicolumn{2}{|c|}{\textit{Record 2}} \\ +\hline +a\$title & some\textbackslash{}more\_text \\ +junk & \#\textless{}foo\textgreater{}\%\&\^{}\~{}\textbar{}\\\{bar\} \\ +empty & \\ +int & 2 \\ +\hline +\end{tabular} + +\noindent +\pset tableattr +deallocate q; +-- test troff-ms output format +\pset format troff-ms +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +.LP +.DS C +Sequence "public.psql_serial_tab_id_seq" +.DE +.LP +.TS +center; +l | r | r | r | r | l | r. +\fIType\fP \fIStart\fP \fIMinimum\fP \fIMaximum\fP \fIIncrement\fP \fICycles?\fP \fICache\fP +_ +integer 1 1 2147483647 1 no 1 +.TE +.DS L +Owned by: public.psql_serial_tab.id +.DE +\pset tuples_only true +\df exp +.LP +.TS +center; +l | l | l | l | l. +pg_catalog exp double precision double precision func +pg_catalog exp numeric numeric func +.TE +.DS L +.DE +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +.LP +.DS C +Sequence "public.psql_serial_tab_id_seq" +.DE +.LP +.TS +center; +c s. +\fIRecord 1\fP +_ +.T& +c | l. +Type integer +Start 1 +Minimum 1 +Maximum 2147483647 +Increment 1 +Cycles? no +Cache 1 +.TE +.DS L +Owned by: public.psql_serial_tab.id +.DE +\pset tuples_only true +\df exp +.LP +.TS +center; +c l; +_ +Schema pg_catalog +Name exp +Result data type double precision +Argument data types double precision +Type func +_ +Schema pg_catalog +Name exp +Result data type numeric +Argument data types numeric +Type func +.TE +.DS L +.DE +\pset tuples_only false +prepare q as + select 'some\text' as "a\title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; +\pset expanded off +\pset border 0 +execute q; +.LP +.TS +center; +lllr. +\fIa\(rstitle\fP \fIjunk\fP \fIempty\fP \fIint\fP +_ +some\(rstext + 1 +some\(rstext + 2 +.TE +.DS L +(2 rows) +.DE +\pset border 1 +execute q; +.LP +.TS +center; +l | l | l | r. +\fIa\(rstitle\fP \fIjunk\fP \fIempty\fP \fIint\fP +_ +some\(rstext + 1 +some\(rstext + 2 +.TE +.DS L +(2 rows) +.DE +\pset border 2 +execute q; +.LP +.TS +center box; +l | l | l | r. +\fIa\(rstitle\fP \fIjunk\fP \fIempty\fP \fIint\fP +_ +some\(rstext + 1 +some\(rstext + 2 +.TE +.DS L +(2 rows) +.DE +\pset expanded on +\pset border 0 +execute q; +.LP +.TS +center; +c s. +\fIRecord 1\fP +.T& +c l. +a\(rstitle some\(rstext +junk + +empty +int 1 +.T& +c s. +\fIRecord 2\fP +.T& +c l. +a\(rstitle some\(rstext +junk + +empty +int 2 +.TE +.DS L +.DE +\pset border 1 +execute q; +.LP +.TS +center; +c s. +\fIRecord 1\fP +_ +.T& +c | l. +a\(rstitle some\(rstext +junk + +empty +int 1 +.T& +c s. +\fIRecord 2\fP +_ +.T& +c | l. +a\(rstitle some\(rstext +junk + +empty +int 2 +.TE +.DS L +.DE +\pset border 2 +execute q; +.LP +.TS +center box; +c s. +\fIRecord 1\fP +_ +.T& +c l. +a\(rstitle some\(rstext +junk + +empty +int 1 +_ +.T& +c s. +\fIRecord 2\fP +_ +.T& +c l. +a\(rstitle some\(rstext +junk + +empty +int 2 +.TE +.DS L +.DE +deallocate q; +-- check ambiguous format requests +\pset format a +\pset: ambiguous abbreviation "a" matches both "aligned" and "asciidoc" +\pset format l +-- clean up after output format tests +drop table psql_serial_tab; \pset format aligned \pset expanded off \pset border 1 +-- \echo and allied features +\echo this is a test +this is a test +\echo -n without newline +without newline\echo with -n newline +with -n newline +\echo '-n' with newline +-n with newline +\set foo bar +\echo foo = :foo +foo = bar +\qecho this is a test +this is a test +\qecho foo = :foo +foo = bar +\warn this is a test +this is a test +\warn foo = :foo +foo = bar -- tests for \if ... \endif \if true select 'okay'; @@ -2921,6 +4275,17 @@ all true \echo 'all false' all false \endif +-- test true-false elif after initial true branch +\if true + \echo 'should print #2-5' +should print #2-5 +\elif true + \echo 'should not print #2-6' +\elif false + \echo 'should not print #2-7' +\else + \echo 'should not print #2-8' +\endif -- test simple true-then-else \if true \echo 'first thing true' @@ -2994,22 +4359,60 @@ bar 'bar' "bar" :try_to_quit \echo `nosuchcommand` :foo :'foo' :"foo" \pset fieldsep | `nosuchcommand` :foo :'foo' :"foo" - \a \C arg1 \c arg1 arg2 arg3 arg4 \cd arg1 \conninfo + \a + \C arg1 + \c arg1 arg2 arg3 arg4 + \cd arg1 + \conninfo \copy arg1 arg2 arg3 arg4 arg5 arg6 - \copyright \dt arg1 \e arg1 arg2 + \copyright + SELECT 1 as one, 2, 3 \crosstabview + \dt arg1 + \e arg1 arg2 \ef whole_line \ev whole_line - \echo arg1 arg2 arg3 arg4 arg5 \echo arg1 \encoding arg1 \errverbose - \g arg1 \gx arg1 \gexec \h \html \i arg1 \ir arg1 \l arg1 \lo arg1 arg2 - \o arg1 \p \password arg1 \prompt arg1 arg2 \pset arg1 arg2 \q - \reset \s arg1 \set arg1 arg2 arg3 arg4 arg5 arg6 arg7 \setenv arg1 arg2 + \echo arg1 arg2 arg3 arg4 arg5 + \echo arg1 + \encoding arg1 + \errverbose + \f arg1 + \g arg1 + \gx arg1 + \gexec + SELECT 1 AS one \gset + \h + \? + \html + \i arg1 + \ir arg1 + \l arg1 + \lo arg1 arg2 +invalid command \lo + \lo_list + \o arg1 + \p + \password arg1 + \prompt arg1 arg2 + \pset arg1 arg2 + \q + \reset + \s arg1 + \set arg1 arg2 arg3 arg4 arg5 arg6 arg7 + \setenv arg1 arg2 \sf whole_line \sv whole_line - \t arg1 \T arg1 \timing arg1 \unset arg1 \w arg1 \watch arg1 \x arg1 + \t arg1 + \T arg1 + \timing arg1 + \unset arg1 + \w arg1 + \watch arg1 + \x arg1 -- \else here is eaten as part of OT_FILEPIPE argument \w |/no/such/file \else -- \endif here is eaten as part of whole-line argument \! whole_line \endif + \z \else \echo 'should print #8-1' should print #8-1 @@ -3156,6 +4559,26 @@ number of rows: 0 last error message: table "this_table_does_not_exist" does not exist \echo 'last error code:' :LAST_ERROR_SQLSTATE last error code: 42P01 +-- nondefault verbosity error settings (except verbose, which is too unstable) +\set VERBOSITY terse +SELECT 1 UNION; +ERROR: syntax error at or near ";" at character 15 +\echo 'error:' :ERROR +error: true +\echo 'error code:' :SQLSTATE +error code: 42601 +\echo 'last error message:' :LAST_ERROR_MESSAGE +last error message: syntax error at or near ";" +\set VERBOSITY sqlstate +SELECT 1/0; +ERROR: 22012 +\echo 'error:' :ERROR +error: true +\echo 'error code:' :SQLSTATE +error code: 22012 +\echo 'last error message:' :LAST_ERROR_MESSAGE +last error message: division by zero +\set VERBOSITY default -- working \gdesc SELECT 3 AS three, 4 AS four \gdesc Column | Type @@ -3243,3 +4666,146 @@ last error message: division by zero \echo 'last error code:' :LAST_ERROR_SQLSTATE last error code: 22012 \unset FETCH_COUNT +create schema testpart; +create role regress_partitioning_role; +alter schema testpart owner to regress_partitioning_role; +set role to regress_partitioning_role; +-- run test inside own schema and hide other partitions +set search_path to testpart; +create table testtable_apple(logdate date); +create table testtable_orange(logdate date); +create index testtable_apple_index on testtable_apple(logdate); +create index testtable_orange_index on testtable_orange(logdate); +create table testpart_apple(logdate date) partition by range(logdate); +create table testpart_orange(logdate date) partition by range(logdate); +create index testpart_apple_index on testpart_apple(logdate); +create index testpart_orange_index on testpart_orange(logdate); +-- only partition related object should be displayed +\dP test*apple* + List of partitioned relations + Schema | Name | Owner | Type | Parent name | Table +----------+----------------------+---------------------------+-------------------+-------------+---------------- + testpart | testpart_apple | regress_partitioning_role | partitioned table | | + testpart | testpart_apple_index | regress_partitioning_role | partitioned index | | testpart_apple +(2 rows) + +\dPt test*apple* + List of partitioned tables + Schema | Name | Owner | Parent name +----------+----------------+---------------------------+------------- + testpart | testpart_apple | regress_partitioning_role | +(1 row) + +\dPi test*apple* + List of partitioned indexes + Schema | Name | Owner | Parent name | Table +----------+----------------------+---------------------------+-------------+---------------- + testpart | testpart_apple_index | regress_partitioning_role | | testpart_apple +(1 row) + +drop table testtable_apple; +drop table testtable_orange; +drop table testpart_apple; +drop table testpart_orange; +create table parent_tab (id int) partition by range (id); +create index parent_index on parent_tab (id); +create table child_0_10 partition of parent_tab + for values from (0) to (10); +create table child_10_20 partition of parent_tab + for values from (10) to (20); +create table child_20_30 partition of parent_tab + for values from (20) to (30); +insert into parent_tab values (generate_series(0,29)); +create table child_30_40 partition of parent_tab +for values from (30) to (40) + partition by range(id); +create table child_30_35 partition of child_30_40 + for values from (30) to (35); +create table child_35_40 partition of child_30_40 + for values from (35) to (40); +insert into parent_tab values (generate_series(30,39)); +\dPt + List of partitioned tables + Schema | Name | Owner +----------+------------+--------------------------- + testpart | parent_tab | regress_partitioning_role +(1 row) + +\dPi + List of partitioned indexes + Schema | Name | Owner | Table +----------+--------------+---------------------------+------------ + testpart | parent_index | regress_partitioning_role | parent_tab +(1 row) + +\dP testpart.* + List of partitioned relations + Schema | Name | Owner | Type | Parent name | Table +----------+--------------------+---------------------------+-------------------+--------------+------------- + testpart | parent_tab | regress_partitioning_role | partitioned table | | + testpart | child_30_40 | regress_partitioning_role | partitioned table | parent_tab | + testpart | parent_index | regress_partitioning_role | partitioned index | | parent_tab + testpart | child_30_40_id_idx | regress_partitioning_role | partitioned index | parent_index | child_30_40 +(4 rows) + +\dP + List of partitioned relations + Schema | Name | Owner | Type | Table +----------+--------------+---------------------------+-------------------+------------ + testpart | parent_tab | regress_partitioning_role | partitioned table | + testpart | parent_index | regress_partitioning_role | partitioned index | parent_tab +(2 rows) + +\dPtn + List of partitioned tables + Schema | Name | Owner | Parent name +----------+-------------+---------------------------+------------- + testpart | parent_tab | regress_partitioning_role | + testpart | child_30_40 | regress_partitioning_role | parent_tab +(2 rows) + +\dPin + List of partitioned indexes + Schema | Name | Owner | Parent name | Table +----------+--------------------+---------------------------+--------------+------------- + testpart | parent_index | regress_partitioning_role | | parent_tab + testpart | child_30_40_id_idx | regress_partitioning_role | parent_index | child_30_40 +(2 rows) + +\dPn + List of partitioned relations + Schema | Name | Owner | Type | Parent name | Table +----------+--------------------+---------------------------+-------------------+--------------+------------- + testpart | parent_tab | regress_partitioning_role | partitioned table | | + testpart | child_30_40 | regress_partitioning_role | partitioned table | parent_tab | + testpart | parent_index | regress_partitioning_role | partitioned index | | parent_tab + testpart | child_30_40_id_idx | regress_partitioning_role | partitioned index | parent_index | child_30_40 +(4 rows) + +\dPn testpart.* + List of partitioned relations + Schema | Name | Owner | Type | Parent name | Table +----------+--------------------+---------------------------+-------------------+--------------+------------- + testpart | parent_tab | regress_partitioning_role | partitioned table | | + testpart | child_30_40 | regress_partitioning_role | partitioned table | parent_tab | + testpart | parent_index | regress_partitioning_role | partitioned index | | parent_tab + testpart | child_30_40_id_idx | regress_partitioning_role | partitioned index | parent_index | child_30_40 +(4 rows) + +drop table parent_tab cascade; +drop schema testpart; +set search_path to default; +set role to default; +drop role regress_partitioning_role; +-- \d on toast table (use pg_statistic's toast table, which has a known name) +\d pg_toast.pg_toast_2619 +TOAST table "pg_toast.pg_toast_2619" + Column | Type +------------+--------- + chunk_id | oid + chunk_seq | integer + chunk_data | bytea +Owning table: "pg_catalog.pg_statistic" +Indexes: + "pg_toast_2619_index" PRIMARY KEY, btree (chunk_id, chunk_seq) + diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out index afbbdd543df..feb51e4add7 100644 --- a/src/test/regress/expected/publication.out +++ b/src/test/regress/expected/publication.out @@ -5,7 +5,10 @@ CREATE ROLE regress_publication_user LOGIN SUPERUSER; CREATE ROLE regress_publication_user2; CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_publication_user'; +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_default; +RESET client_min_messages; COMMENT ON PUBLICATION testpub_default IS 'test publication'; SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p; obj_description @@ -13,11 +16,13 @@ SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p; test publication (1 row) +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert); +RESET client_min_messages; ALTER PUBLICATION testpub_default SET (publish = update); -- error cases CREATE PUBLICATION testpub_xxx WITH (foo); -ERROR: unrecognized publication parameter: foo +ERROR: unrecognized publication parameter: "foo" CREATE PUBLICATION testpub_xxx WITH (publish = 'cluster, vacuum'); ERROR: unrecognized "publish" value: "cluster" \dRp @@ -43,7 +48,9 @@ CREATE TABLE testpub_tbl1 (id serial primary key, data text); CREATE TABLE pub_test.testpub_nopk (foo int, bar int); CREATE VIEW testpub_view AS SELECT 1; CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a); +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert'); +RESET client_min_messages; ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update'); CREATE TABLE testpub_tbl2 (id serial primary key, data text); -- fail - can't add to for all tables publication @@ -86,8 +93,10 @@ DROP TABLE testpub_tbl2; DROP PUBLICATION testpub_foralltables; CREATE TABLE testpub_tbl3 (a int); CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3); +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3; CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3; +RESET client_min_messages; \dRp+ testpub3 Publication testpub3 Owner | All tables | Inserts | Updates | Deletes | Truncates @@ -111,7 +120,9 @@ DROP PUBLICATION testpub3, testpub4; CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view; ERROR: "testpub_view" is not a table DETAIL: Only tables can be added to publications. +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk; +RESET client_min_messages; -- fail - already added ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1; ERROR: relation "testpub_tbl1" is already member of publication "testpub_fortbl" @@ -196,7 +207,9 @@ ERROR: permission denied for database regression SET ROLE regress_publication_user; GRANT CREATE ON DATABASE regression TO regress_publication_user2; SET ROLE regress_publication_user2; +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub2; -- ok +RESET client_min_messages; ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; -- fail ERROR: must be owner of table testpub_tbl1 SET ROLE regress_publication_user; diff --git a/src/test/regress/expected/rangefuncs.out b/src/test/regress/expected/rangefuncs.out index 34ca0ef890e..36a59291139 100644 --- a/src/test/regress/expected/rangefuncs.out +++ b/src/test/regress/expected/rangefuncs.out @@ -1391,6 +1391,31 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1), 3 | 3 | 30 | 8 (45 rows) +-- check handling of FULL JOIN with multiple lateral references (bug #15741) +SELECT * +FROM (VALUES (1),(2)) v1(r1) + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, v1.r1) AS gs1 + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, gs1) AS gs2 + LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE + ) AS ss1 ON TRUE + FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE + ) AS ss0 ON TRUE; + r1 | gs1 | gs2 | gs3 | gs4 +----+-----+-----+-----+----- + 1 | | | | 1 + 1 | 1 | 1 | 1 | + 2 | | | | 1 + 2 | | | | 2 + 2 | 1 | 1 | 1 | + 2 | 2 | 1 | 1 | + 2 | 2 | 2 | 1 | + 2 | 2 | 2 | 2 | +(8 rows) + DROP FUNCTION rngfunc_sql(int,int); DROP FUNCTION rngfunc_mat(int,int); DROP SEQUENCE rngfunc_rescan_seq1; diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index accf1e0d9e2..6fd16bddd18 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -519,7 +519,7 @@ select numrange(1.0, 2.0) * numrange(2.5, 3.0); (1 row) create table numrange_test2(nr numrange); -create index numrange_test2_hash_idx on numrange_test2 (nr); +create index numrange_test2_hash_idx on numrange_test2 using hash (nr); INSERT INTO numrange_test2 VALUES('[, 5)'); INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); @@ -652,6 +652,30 @@ select daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); [01-11-2000,01-12-2000) (1 row) +select daterange('-infinity'::date, '2000-01-01'::date, '()'); + daterange +------------------------ + (-infinity,01-01-2000) +(1 row) + +select daterange('-infinity'::date, '2000-01-01'::date, '[)'); + daterange +------------------------ + [-infinity,01-01-2000) +(1 row) + +select daterange('2000-01-01'::date, 'infinity'::date, '[)'); + daterange +----------------------- + [01-01-2000,infinity) +(1 row) + +select daterange('2000-01-01'::date, 'infinity'::date, '[]'); + daterange +----------------------- + [01-01-2000,infinity] +(1 row) + -- test GiST index that's been built incrementally create table test_range_gist(ir int4range); create index test_range_gist_idx on test_range_gist using gist (ir); diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out index 79a7fa7a845..0923ad9b5b0 100644 --- a/src/test/regress/expected/regex.out +++ b/src/test/regress/expected/regex.out @@ -116,7 +116,7 @@ select regexp_match('abc', '(B)(c)', 'i'); (1 row) select regexp_match('abc', 'Bd', 'ig'); -- error -ERROR: regexp_match does not support the global option +ERROR: regexp_match() does not support the "global" option HINT: Use the regexp_matches function instead. -- Test lookahead constraints select regexp_matches('ab', 'a(?=b)b*'); @@ -299,7 +299,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc'; QUERY PLAN ---------------------------------------------------------------------- Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name)) + Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text)) Filter: (proname ~ '^abc'::text) (3 rows) @@ -307,7 +307,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc$'; QUERY PLAN ------------------------------------------------------------ Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: (proname = 'abc'::name) + Index Cond: (proname = 'abc'::text) Filter: (proname ~ '^abc$'::text) (3 rows) @@ -315,7 +315,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abcd*e'; QUERY PLAN ---------------------------------------------------------------------- Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name)) + Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text)) Filter: (proname ~ '^abcd*e'::text) (3 rows) @@ -323,7 +323,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abc+d'; QUERY PLAN ---------------------------------------------------------------------- Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: ((proname >= 'abc'::name) AND (proname < 'abd'::name)) + Index Cond: ((proname >= 'abc'::text) AND (proname < 'abd'::text)) Filter: (proname ~ '^abc+d'::text) (3 rows) @@ -331,7 +331,7 @@ explain (costs off) select * from pg_proc where proname ~ '^(abc)(def)'; QUERY PLAN ---------------------------------------------------------------------------- Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: ((proname >= 'abcdef'::name) AND (proname < 'abcdeg'::name)) + Index Cond: ((proname >= 'abcdef'::text) AND (proname < 'abcdeg'::text)) Filter: (proname ~ '^(abc)(def)'::text) (3 rows) @@ -339,7 +339,7 @@ explain (costs off) select * from pg_proc where proname ~ '^(abc)$'; QUERY PLAN ------------------------------------------------------------ Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: (proname = 'abc'::name) + Index Cond: (proname = 'abc'::text) Filter: (proname ~ '^(abc)$'::text) (3 rows) @@ -354,7 +354,7 @@ explain (costs off) select * from pg_proc where proname ~ '^abcd(x|(?=\w\w)q)'; QUERY PLAN ------------------------------------------------------------------------ Index Scan using pg_proc_proname_args_nsp_index on pg_proc - Index Cond: ((proname >= 'abcd'::name) AND (proname < 'abce'::name)) + Index Cond: ((proname >= 'abcd'::text) AND (proname < 'abce'::text)) Filter: (proname ~ '^abcd(x|(?=\w\w)q)'::text) (3 rows) @@ -492,6 +492,55 @@ select regexp_matches('foo/bar/baz', {foo,bar,baz} (1 row) +-- Test that greediness can be overridden by outer quantifier +select regexp_matches('llmmmfff', '^(l*)(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*){1,1}?(f*)$'); + regexp_matches +---------------- + {"",llmmm,fff} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?)(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}(.*)(f*)$'); + regexp_matches +---------------- + {ll,mmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*)(f*)$'); + regexp_matches +------------------ + {"",llmmmfff,""} +(1 row) + +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*){1,1}?(f*)$'); + regexp_matches +---------------- + {"",llmmm,fff} +(1 row) + -- Test for infinite loop in cfindloop with zero-length possible match -- but no actual match (can only happen in the presence of backrefs) select 'a' ~ '$()|^\1'; diff --git a/src/test/regress/expected/reindex_catalog.out b/src/test/regress/expected/reindex_catalog.out new file mode 100644 index 00000000000..4b5fba49493 --- /dev/null +++ b/src/test/regress/expected/reindex_catalog.out @@ -0,0 +1,38 @@ +-- +-- Check that system tables can be reindexed. +-- +-- Note that this test currently is not included in the default +-- schedules, as currently reindexing catalog tables can cause +-- deadlocks: +-- +-- * The lock upgrade between the ShareLock acquired for the reindex +-- and RowExclusiveLock needed for pg_class/pg_index locks can +-- trigger deadlocks. +-- +-- * The uniqueness checks performed when reindexing a unique/primary +-- key index possibly need to wait for the transaction of a +-- about-to-deleted row in pg_class to commit. That can cause +-- deadlocks because, in contrast to user tables, locks on catalog +-- tables are routinely released before commit - therefore the lock +-- held for reindexing doesn't guarantee that no running transaction +-- performed modifications in the table underlying the index. +-- +-- This is particularly problematic as such conflicts can be +-- triggered even when run in isolation, as a previous session's +-- temporary table cleanup might still be running (even when the +-- session ended from a client perspective). +-- Check reindexing of whole tables +REINDEX TABLE pg_class; -- mapped, non-shared, critical +REINDEX TABLE pg_index; -- non-mapped, non-shared, critical +REINDEX TABLE pg_operator; -- non-mapped, non-shared, critical +REINDEX TABLE pg_database; -- mapped, shared, critical +REINDEX TABLE pg_shdescription; -- mapped, shared non-critical +-- Check that individual system indexes can be reindexed. That's a bit +-- different from the entire-table case because reindex_relation +-- treats e.g. pg_class special. +REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical +REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical +REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical +REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical +REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical +REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out index df3c99d1eb1..7cb7467040e 100644 --- a/src/test/regress/expected/reloptions.out +++ b/src/test/regress/expected/reloptions.out @@ -26,8 +26,9 @@ ERROR: unrecognized parameter "not_existing_option" CREATE TABLE reloptions_test2(i INT) WITH (not_existing_namespace.fillfactor=2); ERROR: unrecognized parameter namespace "not_existing_namespace" -- Fail while setting improper values -CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=30.5); -ERROR: invalid value for integer option "fillfactor": 30.5 +CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=-30.1); +ERROR: value -30.1 out of bounds for option "fillfactor" +DETAIL: Valid values are between "10" and "100". CREATE TABLE reloptions_test2(i INT) WITH (fillfactor='string'); ERROR: invalid value for integer option "fillfactor": string CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=true); @@ -86,13 +87,51 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass AND -- RESET fails if a value is specified ALTER TABLE reloptions_test RESET (fillfactor=12); ERROR: RESET must not include values for parameters --- The OIDS option is not stored as reloption +-- Test vacuum_truncate option DROP TABLE reloptions_test; -CREATE TABLE reloptions_test(i INT) WITH (fillfactor=20, oids=true); -SELECT reloptions, relhasoids FROM pg_class WHERE oid = 'reloptions_test'::regclass; - reloptions | relhasoids ------------------+------------ - {fillfactor=20} | t +CREATE TABLE reloptions_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=false, + toast.vacuum_truncate=false, + autovacuum_enabled=false); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +-------------------------------------------------- + {vacuum_truncate=false,autovacuum_enabled=false} +(1 row) + +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); +ERROR: null value in column "i" violates not-null constraint +DETAIL: Failing row contains (null, null). +VACUUM reloptions_test; +SELECT pg_relation_size('reloptions_test') > 0; + ?column? +---------- + t +(1 row) + +SELECT reloptions FROM pg_class WHERE oid = + (SELECT reltoastrelid FROM pg_class + WHERE oid = 'reloptions_test'::regclass); + reloptions +------------------------- + {vacuum_truncate=false} +(1 row) + +ALTER TABLE reloptions_test RESET (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; + reloptions +---------------------------- + {autovacuum_enabled=false} +(1 row) + +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); +ERROR: null value in column "i" violates not-null constraint +DETAIL: Failing row contains (null, null). +VACUUM reloptions_test; +SELECT pg_relation_size('reloptions_test') = 0; + ?column? +---------- + t (1 row) -- Test toast.* options diff --git a/src/test/regress/expected/reltime.out b/src/test/regress/expected/reltime.out deleted file mode 100644 index 14fdc6aeec5..00000000000 --- a/src/test/regress/expected/reltime.out +++ /dev/null @@ -1,109 +0,0 @@ --- --- RELTIME --- -CREATE TABLE RELTIME_TBL (f1 reltime); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 1 minute'); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 5 hour'); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 10 day'); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 34 year'); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 3 months'); -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 14 seconds ago'); --- badly formatted reltimes -INSERT INTO RELTIME_TBL (f1) VALUES ('badly formatted reltime'); -ERROR: invalid input syntax for type reltime: "badly formatted reltime" -LINE 1: INSERT INTO RELTIME_TBL (f1) VALUES ('badly formatted reltim... - ^ -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 30 eons ago'); -ERROR: invalid input syntax for type reltime: "@ 30 eons ago" -LINE 1: INSERT INTO RELTIME_TBL (f1) VALUES ('@ 30 eons ago'); - ^ --- test reltime operators -SELECT '' AS six, * FROM RELTIME_TBL; - six | f1 ------+--------------- - | @ 1 min - | @ 5 hours - | @ 10 days - | @ 34 years - | @ 3 mons - | @ 14 secs ago -(6 rows) - -SELECT '' AS five, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 <> reltime '@ 10 days'; - five | f1 -------+--------------- - | @ 1 min - | @ 5 hours - | @ 34 years - | @ 3 mons - | @ 14 secs ago -(5 rows) - -SELECT '' AS three, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 <= reltime '@ 5 hours'; - three | f1 --------+--------------- - | @ 1 min - | @ 5 hours - | @ 14 secs ago -(3 rows) - -SELECT '' AS three, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 < reltime '@ 1 day'; - three | f1 --------+--------------- - | @ 1 min - | @ 5 hours - | @ 14 secs ago -(3 rows) - -SELECT '' AS one, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 = reltime '@ 34 years'; - one | f1 ------+------------ - | @ 34 years -(1 row) - -SELECT '' AS two, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 >= reltime '@ 1 month'; - two | f1 ------+------------ - | @ 34 years - | @ 3 mons -(2 rows) - -SELECT '' AS five, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 > reltime '@ 3 seconds ago'; - five | f1 -------+------------ - | @ 1 min - | @ 5 hours - | @ 10 days - | @ 34 years - | @ 3 mons -(5 rows) - -SELECT '' AS fifteen, r1.*, r2.* - FROM RELTIME_TBL r1, RELTIME_TBL r2 - WHERE r1.f1 > r2.f1 - ORDER BY r1.f1, r2.f1; - fifteen | f1 | f1 ----------+------------+--------------- - | @ 1 min | @ 14 secs ago - | @ 5 hours | @ 14 secs ago - | @ 5 hours | @ 1 min - | @ 10 days | @ 14 secs ago - | @ 10 days | @ 1 min - | @ 10 days | @ 5 hours - | @ 3 mons | @ 14 secs ago - | @ 3 mons | @ 1 min - | @ 3 mons | @ 5 hours - | @ 3 mons | @ 10 days - | @ 34 years | @ 14 secs ago - | @ 34 years | @ 1 min - | @ 34 years | @ 5 hours - | @ 34 years | @ 10 days - | @ 34 years | @ 3 mons -(15 rows) - diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out index 67c34a92a4e..739608aab4c 100644 --- a/src/test/regress/expected/replica_identity.out +++ b/src/test/regress/expected/replica_identity.out @@ -5,11 +5,10 @@ CREATE TABLE test_replica_identity ( nonkey text, CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE, CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb) -) WITH OIDS; +) ; CREATE TABLE test_replica_identity_othertable (id serial primary key); CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb); CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb); -CREATE UNIQUE INDEX test_replica_identity_oid_idx ON test_replica_identity (oid); CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey); CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey); CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3)); @@ -86,17 +85,14 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; Indexes: "test_replica_identity_pkey" PRIMARY KEY, btree (id) REPLICA IDENTITY "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) + "test_replica_identity_hash" hash (nonkey) + "test_replica_identity_keyab" btree (keya, keyb) "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) - "test_replica_identity_oid_idx" UNIQUE, btree (oid) "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb) - "test_replica_identity_hash" hash (nonkey) - "test_replica_identity_keyab" btree (keya, keyb) --- succeed, oid unique index -ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_oid_idx; -- succeed, nondeferrable unique constraint over nonnullable cols ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer; -- succeed unique index over nonnullable cols @@ -119,14 +115,13 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; Indexes: "test_replica_identity_pkey" PRIMARY KEY, btree (id) "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) + "test_replica_identity_hash" hash (nonkey) + "test_replica_identity_keyab" btree (keya, keyb) "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) REPLICA IDENTITY "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) - "test_replica_identity_oid_idx" UNIQUE, btree (oid) "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb) - "test_replica_identity_hash" hash (nonkey) - "test_replica_identity_keyab" btree (keya, keyb) SELECT count(*) FROM pg_index WHERE indrelid = 'test_replica_identity'::regclass AND indisreplident; count @@ -168,16 +163,14 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; Indexes: "test_replica_identity_pkey" PRIMARY KEY, btree (id) "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3)) + "test_replica_identity_hash" hash (nonkey) + "test_replica_identity_keyab" btree (keya, keyb) "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey) - "test_replica_identity_oid_idx" UNIQUE, btree (oid) "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb) - "test_replica_identity_hash" hash (nonkey) - "test_replica_identity_keyab" btree (keya, keyb) Replica Identity: FULL -Has OIDs: yes ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING; SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; diff --git a/src/test/regress/expected/roleattributes.out b/src/test/regress/expected/roleattributes.out index 570aa5f8343..5e6969b173e 100644 --- a/src/test/regress/expected/roleattributes.out +++ b/src/test/regress/expected/roleattributes.out @@ -1,27 +1,27 @@ -- default for superuser is false CREATE ROLE regress_test_def_superuser; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_superuser | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_superuser WITH SUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_superuser | t | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_superuser WITH NOSUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_superuser | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_superuser WITH SUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_superuser | t | t | f | f | f | f | f | -1 | | @@ -29,28 +29,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; -- default for inherit is true CREATE ROLE regress_test_def_inherit; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_inherit | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_inherit WITH NOINHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_inherit | f | f | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_inherit WITH INHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_inherit | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_inherit WITH NOINHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_inherit | f | f | f | f | f | f | f | -1 | | @@ -58,28 +58,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; -- default for create role is false CREATE ROLE regress_test_def_createrole; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_createrole | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_createrole WITH CREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createrole | f | t | t | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_createrole WITH NOCREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createrole | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_createrole WITH CREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createrole | f | t | t | f | f | f | f | -1 | | @@ -87,28 +87,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; -- default for create database is false CREATE ROLE regress_test_def_createdb; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ---------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_createdb | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_createdb WITH CREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createdb | f | t | f | t | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_createdb WITH NOCREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createdb | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_createdb WITH CREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_createdb | f | t | f | t | f | f | f | -1 | | @@ -116,28 +116,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; -- default for can login is false for role CREATE ROLE regress_test_def_role_canlogin; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_role_canlogin | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_role_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_role_canlogin | f | t | f | f | t | f | f | -1 | | (1 row) ALTER ROLE regress_test_role_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_role_canlogin | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_role_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_role_canlogin | f | t | f | f | t | f | f | -1 | | @@ -145,28 +145,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; -- default for can login is true for user CREATE USER regress_test_def_user_canlogin; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_user_canlogin | f | t | f | f | t | f | f | -1 | | (1 row) CREATE USER regress_test_user_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_user_canlogin | f | t | f | f | f | f | f | -1 | | (1 row) ALTER USER regress_test_user_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_user_canlogin | f | t | f | f | t | f | f | -1 | | (1 row) ALTER USER regress_test_user_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_user_canlogin | f | t | f | f | f | f | f | -1 | | @@ -174,28 +174,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; -- default for replication is false CREATE ROLE regress_test_def_replication; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_replication | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_replication WITH REPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_replication | f | t | f | f | f | t | f | -1 | | (1 row) ALTER ROLE regress_test_replication WITH NOREPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_replication | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_replication WITH REPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_replication | f | t | f | f | f | t | f | -1 | | @@ -203,28 +203,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; -- default for bypassrls is false CREATE ROLE regress_test_def_bypassrls; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_def_bypassrls | f | t | f | f | f | f | f | -1 | | (1 row) CREATE ROLE regress_test_bypassrls WITH BYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_bypassrls | f | t | f | f | f | f | t | -1 | | (1 row) ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_bypassrls | f | t | f | f | f | f | f | -1 | | (1 row) ALTER ROLE regress_test_bypassrls WITH BYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+--------------- regress_test_bypassrls | f | t | f | f | f | f | t | -1 | | diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out index bf7af3ba826..d01769299e4 100644 --- a/src/test/regress/expected/rowsecurity.out +++ b/src/test/regress/expected/rowsecurity.out @@ -632,30 +632,30 @@ SELECT * FROM category; -- SET SESSION AUTHORIZATION regress_rls_alice; SET row_security TO ON; -CREATE TABLE t1 (a int, junk1 text, b text) WITH OIDS; +CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text); ALTER TABLE t1 DROP COLUMN junk1; -- just a disturbing factor GRANT ALL ON t1 TO public; -COPY t1 FROM stdin WITH (oids); +COPY t1 FROM stdin WITH ; CREATE TABLE t2 (c float) INHERITS (t1); GRANT ALL ON t2 TO public; -COPY t2 FROM stdin WITH (oids); -CREATE TABLE t3 (c text, b text, a int) WITH OIDS; +COPY t2 FROM stdin; +CREATE TABLE t3 (id int not null primary key, c text, b text, a int); ALTER TABLE t3 INHERIT t1; GRANT ALL ON t3 TO public; -COPY t3(a,b,c) FROM stdin WITH (oids); +COPY t3(id, a,b,c) FROM stdin; CREATE POLICY p1 ON t1 FOR ALL TO PUBLIC USING (a % 2 = 0); -- be even number CREATE POLICY p2 ON t2 FOR ALL TO PUBLIC USING (a % 2 = 1); -- be odd number ALTER TABLE t1 ENABLE ROW LEVEL SECURITY; ALTER TABLE t2 ENABLE ROW LEVEL SECURITY; SET SESSION AUTHORIZATION regress_rls_bob; SELECT * FROM t1; - a | b ----+----- - 2 | bbb - 4 | dad - 2 | bcd - 4 | def - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 104 | 4 | dad + 202 | 2 | bcd + 204 | 4 | def + 302 | 2 | yyy (5 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1; @@ -676,13 +676,13 @@ NOTICE: f_leak => dad NOTICE: f_leak => bcd NOTICE: f_leak => def NOTICE: f_leak => yyy - a | b ----+----- - 2 | bbb - 4 | dad - 2 | bcd - 4 | def - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 104 | 4 | dad + 202 | 2 | bcd + 204 | 4 | def + 302 | 2 | yyy (5 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); @@ -698,14 +698,14 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); (7 rows) -- reference to system column -SELECT oid, * FROM t1; - oid | a | b ------+---+----- - 102 | 2 | bbb - 104 | 4 | dad - 202 | 2 | bcd - 204 | 4 | def - 302 | 2 | yyy +SELECT tableoid::regclass, * FROM t1; + tableoid | id | a | b +----------+-----+---+----- + t1 | 102 | 2 | bbb + t1 | 104 | 4 | dad + t2 | 202 | 2 | bcd + t2 | 204 | 4 | def + t3 | 302 | 2 | yyy (5 rows) EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1; @@ -722,13 +722,13 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1; -- reference to whole-row reference SELECT *, t1 FROM t1; - a | b | t1 ----+-----+--------- - 2 | bbb | (2,bbb) - 4 | dad | (4,dad) - 2 | bcd | (2,bcd) - 4 | def | (4,def) - 2 | yyy | (2,yyy) + id | a | b | t1 +-----+---+-----+------------- + 102 | 2 | bbb | (102,2,bbb) + 104 | 4 | dad | (104,4,dad) + 202 | 2 | bcd | (202,2,bcd) + 204 | 4 | def | (204,4,def) + 302 | 2 | yyy | (302,2,yyy) (5 rows) EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1; @@ -745,13 +745,13 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1; -- for share/update lock SELECT * FROM t1 FOR SHARE; - a | b ----+----- - 2 | bbb - 4 | dad - 2 | bcd - 4 | def - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 104 | 4 | dad + 202 | 2 | bcd + 204 | 4 | def + 302 | 2 | yyy (5 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE; @@ -773,13 +773,13 @@ NOTICE: f_leak => dad NOTICE: f_leak => bcd NOTICE: f_leak => def NOTICE: f_leak => yyy - a | b ----+----- - 2 | bbb - 4 | dad - 2 | bcd - 4 | def - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 104 | 4 | dad + 202 | 2 | bcd + 204 | 4 | def + 302 | 2 | yyy (5 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; @@ -796,17 +796,17 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; (8 rows) -- union all query -SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3; - a | b | oid ----+-----+----- - 1 | abc | 201 - 3 | cde | 203 - 1 | xxx | 301 - 2 | yyy | 302 - 3 | zzz | 303 +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; + a | b | tableoid +---+-----+---------- + 1 | abc | t2 + 3 | cde | t2 + 1 | xxx | t3 + 2 | yyy | t3 + 3 | zzz | t3 (5 rows) -EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3; +EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; QUERY PLAN ------------------------------- Append @@ -830,19 +830,19 @@ NOTICE: f_leak => def NOTICE: f_leak => xxx NOTICE: f_leak => yyy NOTICE: f_leak => zzz - a | b ----+----- - 1 | aba - 2 | bbb - 3 | ccc - 4 | dad - 1 | abc - 2 | bcd - 3 | cde - 4 | def - 1 | xxx - 2 | yyy - 3 | zzz + id | a | b +-----+---+----- + 101 | 1 | aba + 102 | 2 | bbb + 103 | 3 | ccc + 104 | 4 | dad + 201 | 1 | abc + 202 | 2 | bcd + 203 | 3 | cde + 204 | 4 | def + 301 | 1 | xxx + 302 | 2 | yyy + 303 | 3 | zzz (11 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); @@ -872,19 +872,19 @@ NOTICE: f_leak => def NOTICE: f_leak => xxx NOTICE: f_leak => yyy NOTICE: f_leak => zzz - a | b ----+----- - 1 | aba - 2 | bbb - 3 | ccc - 4 | dad - 1 | abc - 2 | bcd - 3 | cde - 4 | def - 1 | xxx - 2 | yyy - 3 | zzz + id | a | b +-----+---+----- + 101 | 1 | aba + 102 | 2 | bbb + 103 | 3 | ccc + 104 | 4 | dad + 201 | 1 | abc + 202 | 2 | bcd + 203 | 3 | cde + 204 | 4 | def + 301 | 1 | xxx + 302 | 2 | yyy + 303 | 3 | zzz (11 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); @@ -938,7 +938,7 @@ CREATE POLICY pp1 ON part_document AS PERMISSIVE CREATE POLICY pp1r ON part_document AS RESTRICTIVE TO regress_rls_dave USING (cid < 55); \d+ part_document - Table "regress_rls_schema.part_document" + Partitioned table "regress_rls_schema.part_document" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+---------+-----------+----------+---------+----------+--------------+------------- did | integer | | | | plain | | @@ -1057,15 +1057,14 @@ NOTICE: f_leak => awesome science fiction (4 rows) EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle); - QUERY PLAN --------------------------------------------------------------------- - Append + QUERY PLAN +-------------------------------------------------------------- + Seq Scan on part_document_fiction + Filter: ((cid < 55) AND (dlevel <= $0) AND f_leak(dtitle)) InitPlan 1 (returns $0) -> Index Scan using uaccount_pkey on uaccount Index Cond: (pguser = CURRENT_USER) - -> Seq Scan on part_document_fiction - Filter: ((cid < 55) AND (dlevel <= $0) AND f_leak(dtitle)) -(6 rows) +(5 rows) -- pp1 ERROR INSERT INTO part_document VALUES (100, 11, 5, 'regress_rls_dave', 'testing pp1'); -- fail @@ -1136,15 +1135,14 @@ NOTICE: f_leak => awesome science fiction (4 rows) EXPLAIN (COSTS OFF) SELECT * FROM part_document WHERE f_leak(dtitle); - QUERY PLAN --------------------------------------------------------------------- - Append + QUERY PLAN +-------------------------------------------------------------- + Seq Scan on part_document_fiction + Filter: ((cid < 55) AND (dlevel <= $0) AND f_leak(dtitle)) InitPlan 1 (returns $0) -> Index Scan using uaccount_pkey on uaccount Index Cond: (pguser = CURRENT_USER) - -> Seq Scan on part_document_fiction - Filter: ((cid < 55) AND (dlevel <= $0) AND f_leak(dtitle)) -(6 rows) +(5 rows) -- viewpoint from regress_rls_carol SET SESSION AUTHORIZATION regress_rls_carol; @@ -1393,10 +1391,10 @@ ERROR: infinite recursion detected in policy for relation "rec1" -- Mutual recursion via .s.b views -- SET SESSION AUTHORIZATION regress_rls_bob; -\set VERBOSITY terse \\ -- suppress cascade details DROP VIEW rec1v, rec2v CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to policy r1 on table rec1 +drop cascades to policy r2 on table rec2 CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1; CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2; SET SESSION AUTHORIZATION regress_rls_alice; @@ -1500,11 +1498,11 @@ ERROR: infinite recursion detected in policy for relation "s1" -- prepared statement with regress_rls_alice privilege PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1; EXECUTE p1(2); - a | b ----+----- - 2 | bbb - 2 | bcd - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 202 | 2 | bcd + 302 | 2 | yyy (3 rows) EXPLAIN (COSTS OFF) EXECUTE p1(2); @@ -1534,19 +1532,19 @@ NOTICE: f_leak => def NOTICE: f_leak => xxx NOTICE: f_leak => yyy NOTICE: f_leak => zzz - a | b ----+----- - 1 | aba - 2 | bbb - 3 | ccc - 4 | dad - 1 | abc - 2 | bcd - 3 | cde - 4 | def - 1 | xxx - 2 | yyy - 3 | zzz + id | a | b +-----+---+----- + 101 | 1 | aba + 102 | 2 | bbb + 103 | 3 | ccc + 104 | 4 | dad + 201 | 1 | abc + 202 | 2 | bcd + 203 | 3 | cde + 204 | 4 | def + 301 | 1 | xxx + 302 | 2 | yyy + 303 | 3 | zzz (11 rows) EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); @@ -1563,14 +1561,14 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); -- plan cache should be invalidated EXECUTE p1(2); - a | b ----+----- - 1 | aba - 2 | bbb - 1 | abc - 2 | bcd - 1 | xxx - 2 | yyy + id | a | b +-----+---+----- + 101 | 1 | aba + 102 | 2 | bbb + 201 | 1 | abc + 202 | 2 | bcd + 301 | 1 | xxx + 302 | 2 | yyy (6 rows) EXPLAIN (COSTS OFF) EXECUTE p1(2); @@ -1587,11 +1585,11 @@ EXPLAIN (COSTS OFF) EXECUTE p1(2); PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1; EXECUTE p2(2); - a | b ----+----- - 2 | bbb - 2 | bcd - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 202 | 2 | bcd + 302 | 2 | yyy (3 rows) EXPLAIN (COSTS OFF) EXECUTE p2(2); @@ -1610,11 +1608,11 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2); SET SESSION AUTHORIZATION regress_rls_bob; SET row_security TO ON; EXECUTE p2(2); - a | b ----+----- - 2 | bbb - 2 | bcd - 2 | yyy + id | a | b +-----+---+----- + 102 | 2 | bbb + 202 | 2 | bcd + 302 | 2 | yyy (3 rows) EXPLAIN (COSTS OFF) EXECUTE p2(2); @@ -1666,13 +1664,13 @@ UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b); NOTICE: f_leak => bbbbbb NOTICE: f_leak => daddad -- returning clause with system column -UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1; +UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; NOTICE: f_leak => bbbbbb_updt NOTICE: f_leak => daddad_updt - oid | a | b | t1 ------+---+-------------+----------------- - 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt) - 104 | 4 | daddad_updt | (4,daddad_updt) + tableoid | id | a | b | t1 +----------+-----+---+-------------+--------------------- + t1 | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt) + t1 | 104 | 4 | daddad_updt | (104,4,daddad_updt) (2 rows) UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *; @@ -1681,28 +1679,28 @@ NOTICE: f_leak => daddad_updt NOTICE: f_leak => bcdbcd NOTICE: f_leak => defdef NOTICE: f_leak => yyyyyy - a | b ----+------------- - 2 | bbbbbb_updt - 4 | daddad_updt - 2 | bcdbcd - 4 | defdef - 2 | yyyyyy + id | a | b +-----+---+------------- + 102 | 2 | bbbbbb_updt + 104 | 4 | daddad_updt + 202 | 2 | bcdbcd + 204 | 4 | defdef + 302 | 2 | yyyyyy (5 rows) -UPDATE t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1; +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; NOTICE: f_leak => bbbbbb_updt NOTICE: f_leak => daddad_updt NOTICE: f_leak => bcdbcd NOTICE: f_leak => defdef NOTICE: f_leak => yyyyyy - oid | a | b | t1 ------+---+-------------+----------------- - 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt) - 104 | 4 | daddad_updt | (4,daddad_updt) - 202 | 2 | bcdbcd | (2,bcdbcd) - 204 | 4 | defdef | (4,defdef) - 302 | 2 | yyyyyy | (2,yyyyyy) + tableoid | id | a | b | t1 +----------+-----+---+-------------+--------------------- + t1 | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt) + t1 | 104 | 4 | daddad_updt | (104,4,daddad_updt) + t2 | 202 | 2 | bcdbcd | (202,2,bcdbcd) + t2 | 204 | 4 | defdef | (204,4,defdef) + t3 | 302 | 2 | yyyyyy | (302,2,yyyyyy) (5 rows) -- updates with from clause @@ -1789,9 +1787,9 @@ WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2; NOTICE: f_leak => cde NOTICE: f_leak => cde - a | b | c | a | b | c | t2_1 | t2_2 ----+-----+-----+---+-----+-----+-------------+------------- - 3 | cde | 3.3 | 3 | cde | 3.3 | (3,cde,3.3) | (3,cde,3.3) + id | a | b | c | id | a | b | c | t2_1 | t2_2 +-----+---+-----+-----+-----+---+-----+-----+-----------------+----------------- + 203 | 3 | cde | 3.3 | 203 | 3 | cde | 3.3 | (203,3,cde,3.3) | (203,3,cde,3.3) (1 row) EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2 @@ -1847,28 +1845,28 @@ NOTICE: f_leak => defdef NOTICE: f_leak => defdef NOTICE: f_leak => daddad_updt NOTICE: f_leak => defdef - a | b | a | b | t1_1 | t1_2 ----+-------------+---+-------------+-----------------+----------------- - 4 | daddad_updt | 4 | daddad_updt | (4,daddad_updt) | (4,daddad_updt) - 4 | defdef | 4 | defdef | (4,defdef) | (4,defdef) + id | a | b | id | a | b | t1_1 | t1_2 +-----+---+-------------+-----+---+-------------+---------------------+--------------------- + 104 | 4 | daddad_updt | 104 | 4 | daddad_updt | (104,4,daddad_updt) | (104,4,daddad_updt) + 204 | 4 | defdef | 204 | 4 | defdef | (204,4,defdef) | (204,4,defdef) (2 rows) RESET SESSION AUTHORIZATION; SET row_security TO OFF; SELECT * FROM t1 ORDER BY a,b; - a | b ----+------------- - 1 | aba - 1 | abc - 1 | xxx - 2 | bbbbbb_updt - 2 | bcdbcd - 2 | yyyyyy - 3 | ccc - 3 | cde - 3 | zzz - 4 | daddad_updt - 4 | defdef + id | a | b +-----+---+------------- + 101 | 1 | aba + 201 | 1 | abc + 301 | 1 | xxx + 102 | 2 | bbbbbb_updt + 202 | 2 | bcdbcd + 302 | 2 | yyyyyy + 103 | 3 | ccc + 203 | 3 | cde + 303 | 3 | zzz + 104 | 4 | daddad_updt + 204 | 4 | defdef (11 rows) SET SESSION AUTHORIZATION regress_rls_bob; @@ -1896,24 +1894,24 @@ EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b); Filter: (((a % 2) = 0) AND f_leak(b)) (10 rows) -DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1; +DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; NOTICE: f_leak => bbbbbb_updt NOTICE: f_leak => daddad_updt - oid | a | b | t1 ------+---+-------------+----------------- - 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt) - 104 | 4 | daddad_updt | (4,daddad_updt) + tableoid | id | a | b | t1 +----------+-----+---+-------------+--------------------- + t1 | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt) + t1 | 104 | 4 | daddad_updt | (104,4,daddad_updt) (2 rows) -DELETE FROM t1 WHERE f_leak(b) RETURNING oid, *, t1; +DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; NOTICE: f_leak => bcdbcd NOTICE: f_leak => defdef NOTICE: f_leak => yyyyyy - oid | a | b | t1 ------+---+--------+------------ - 202 | 2 | bcdbcd | (2,bcdbcd) - 204 | 4 | defdef | (4,defdef) - 302 | 2 | yyyyyy | (2,yyyyyy) + tableoid | id | a | b | t1 +----------+-----+---+--------+---------------- + t2 | 202 | 2 | bcdbcd | (202,2,bcdbcd) + t2 | 204 | 4 | defdef | (204,4,defdef) + t3 | 302 | 2 | yyyyyy | (302,2,yyyyyy) (3 rows) -- @@ -2108,7 +2106,7 @@ SET SESSION AUTHORIZATION regress_rls_bob; INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; ERROR: new row violates row-level security policy for table "document" --- UPDATE path is taken here. Existing tuple passes, since it's cid +-- UPDATE path is taken here. Existing tuple passes, since its cid -- corresponds to "novel", but default USING qual is enforced against -- post-UPDATE tuple too (as always when updating with a policy that lacks an -- explicit WCO), and so this fails: @@ -2138,188 +2136,6 @@ ERROR: new row violates row-level security policy (USING expression) for table INSERT INTO document VALUES (1, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol'; ERROR: new row violates row-level security policy for table "document" --- --- MERGE --- -RESET SESSION AUTHORIZATION; -DROP POLICY p3_with_all ON document; -ALTER TABLE document ADD COLUMN dnotes text DEFAULT ''; --- all documents are readable -CREATE POLICY p1 ON document FOR SELECT USING (true); --- one may insert documents only authored by them -CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user); --- one may only update documents in 'novel' category -CREATE POLICY p3 ON document FOR UPDATE - USING (cid = (SELECT cid from category WHERE cname = 'novel')) - WITH CHECK (dauthor = current_user); --- one may only delete documents in 'manga' category -CREATE POLICY p4 ON document FOR DELETE - USING (cid = (SELECT cid from category WHERE cname = 'manga')); -SELECT * FROM document; - did | cid | dlevel | dauthor | dtitle | dnotes ------+-----+--------+-------------------+----------------------------------+-------- - 1 | 11 | 1 | regress_rls_bob | my first novel | - 3 | 22 | 2 | regress_rls_bob | my science fiction | - 4 | 44 | 1 | regress_rls_bob | my first manga | - 5 | 44 | 2 | regress_rls_bob | my second manga | - 6 | 22 | 1 | regress_rls_carol | great science fiction | - 7 | 33 | 2 | regress_rls_carol | great technology book | - 8 | 44 | 1 | regress_rls_carol | great manga | - 9 | 22 | 1 | regress_rls_dave | awesome science fiction | - 10 | 33 | 2 | regress_rls_dave | awesome technology book | - 11 | 33 | 1 | regress_rls_carol | hoge | - 33 | 22 | 1 | regress_rls_bob | okay science fiction | - 2 | 11 | 2 | regress_rls_bob | my first novel | - 78 | 33 | 1 | regress_rls_bob | some technology novel | - 79 | 33 | 1 | regress_rls_bob | technology book, can only insert | -(14 rows) - -SET SESSION AUTHORIZATION regress_rls_bob; --- Fails, since update violates WITH CHECK qual on dauthor -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge1 ', dauthor = 'regress_rls_alice'; -ERROR: new row violates row-level security policy for table "document" --- Should be OK since USING and WITH CHECK quals pass -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge2 '; --- Even when dauthor is updated explicitly, but to the existing value -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge3 ', dauthor = 'regress_rls_bob'; --- There is a MATCH for did = 3, but UPDATE's USING qual does not allow --- updating an item in category 'science fiction' -MERGE INTO document d -USING (SELECT 3 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge '; -ERROR: target row violates row-level security policy (USING expression) for table "document" --- The same thing with DELETE action, but fails again because no permissions --- to delete items in 'science fiction' category that did 3 belongs to. -MERGE INTO document d -USING (SELECT 3 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE; -ERROR: target row violates row-level security policy (USING expression) for table "document" --- Document with did 4 belongs to 'manga' category which is allowed for --- deletion. But this fails because the UPDATE action is matched first and --- UPDATE policy does not allow updation in the category. -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes = '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; -ERROR: target row violates row-level security policy (USING expression) for table "document" --- UPDATE action is not matched this time because of the WHEN AND qual. --- DELETE still fails because role regress_rls_bob does not have SELECT --- privileges on 'manga' category row in the category table. -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes <> '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; -ERROR: target row violates row-level security policy (USING expression) for table "document" -SELECT * FROM document WHERE did = 4; - did | cid | dlevel | dauthor | dtitle | dnotes ------+-----+--------+-----------------+----------------+-------- - 4 | 44 | 1 | regress_rls_bob | my first manga | -(1 row) - --- Switch to regress_rls_carol role and try the DELETE again. It should succeed --- this time -RESET SESSION AUTHORIZATION; -SET SESSION AUTHORIZATION regress_rls_carol; -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes <> '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; --- Switch back to regress_rls_bob role -RESET SESSION AUTHORIZATION; -SET SESSION AUTHORIZATION regress_rls_bob; --- Try INSERT action. This fails because we are trying to insert --- dauthor = regress_rls_dave and INSERT's WITH CHECK does not allow --- that -MERGE INTO document d -USING (SELECT 12 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_dave', 'another novel'); -ERROR: new row violates row-level security policy for table "document" --- This should be fine -MERGE INTO document d -USING (SELECT 12 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); --- ok -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge4 ' -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); --- drop and create a new SELECT policy which prevents us from reading --- any document except with category 'magna' -RESET SESSION AUTHORIZATION; -DROP POLICY p1 ON document; -CREATE POLICY p1 ON document FOR SELECT - USING (cid = (SELECT cid from category WHERE cname = 'manga')); -SET SESSION AUTHORIZATION regress_rls_bob; --- MERGE can no longer see the matching row and hence attempts the --- NOT MATCHED action, which results in unique key violation -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge5 ' -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); -ERROR: duplicate key value violates unique constraint "document_pkey" -RESET SESSION AUTHORIZATION; --- drop the restrictive SELECT policy so that we can look at the --- final state of the table -DROP POLICY p1 ON document; --- Just check everything went per plan -SELECT * FROM document; - did | cid | dlevel | dauthor | dtitle | dnotes ------+-----+--------+-------------------+----------------------------------+----------------------------------------------------------------------- - 3 | 22 | 2 | regress_rls_bob | my science fiction | - 5 | 44 | 2 | regress_rls_bob | my second manga | - 6 | 22 | 1 | regress_rls_carol | great science fiction | - 7 | 33 | 2 | regress_rls_carol | great technology book | - 8 | 44 | 1 | regress_rls_carol | great manga | - 9 | 22 | 1 | regress_rls_dave | awesome science fiction | - 10 | 33 | 2 | regress_rls_dave | awesome technology book | - 11 | 33 | 1 | regress_rls_carol | hoge | - 33 | 22 | 1 | regress_rls_bob | okay science fiction | - 2 | 11 | 2 | regress_rls_bob | my first novel | - 78 | 33 | 1 | regress_rls_bob | some technology novel | - 79 | 33 | 1 | regress_rls_bob | technology book, can only insert | - 12 | 11 | 1 | regress_rls_bob | another novel | - 1 | 11 | 1 | regress_rls_bob | my first novel | notes added by merge2 notes added by merge3 notes added by merge4 -(14 rows) - -- -- ROLE/GROUP -- @@ -2361,7 +2177,7 @@ EXPLAIN (COSTS OFF) EXECUTE plancache_test; Filter: (((a % 2) = 0) AND f_leak(b)) (2 rows) -PREPARE plancache_test2 AS WITH q AS (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2; +PREPARE plancache_test2 AS WITH q AS MATERIALIZED (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2; EXPLAIN (COSTS OFF) EXECUTE plancache_test2; QUERY PLAN ------------------------------------------------- @@ -2374,7 +2190,7 @@ EXPLAIN (COSTS OFF) EXECUTE plancache_test2; -> Seq Scan on z2 (7 rows) -PREPARE plancache_test3 AS WITH q AS (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b); +PREPARE plancache_test3 AS WITH q AS MATERIALIZED (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b); EXPLAIN (COSTS OFF) EXECUTE plancache_test3; QUERY PLAN ----------------------------------------------------- @@ -2957,10 +2773,10 @@ DROP TABLE test_qual_pushdown; -- Plancache invalidate on user change. -- RESET SESSION AUTHORIZATION; -\set VERBOSITY terse \\ -- suppress cascade details DROP TABLE t1 CASCADE; NOTICE: drop cascades to 2 other objects -\set VERBOSITY default +DETAIL: drop cascades to table t2 +drop cascades to table t3 CREATE TABLE t1 (a integer); GRANT SELECT ON t1 TO regress_rls_bob, regress_rls_carol; CREATE POLICY p1 ON t1 TO regress_rls_bob USING ((a % 2) = 0); @@ -3008,7 +2824,7 @@ ALTER TABLE t1 ENABLE ROW LEVEL SECURITY; GRANT ALL ON t1 TO regress_rls_bob; INSERT INTO t1 (SELECT x, md5(x::text) FROM generate_series(0,20) x); SET SESSION AUTHORIZATION regress_rls_bob; -WITH cte1 AS (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; NOTICE: f_leak => cfcd208495d565ef66e7dff9f98764da NOTICE: f_leak => c81e728d9d4c2f636f067f89cc14862c NOTICE: f_leak => a87ff679a2f3e71d9181a67b7542122c @@ -3035,7 +2851,8 @@ NOTICE: f_leak => 98f13708210194c475687be6106a3b84 20 | 98f13708210194c475687be6106a3b84 (11 rows) -EXPLAIN (COSTS OFF) WITH cte1 AS (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; +EXPLAIN (COSTS OFF) +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; QUERY PLAN ------------------------------------------------- CTE Scan on cte1 @@ -3684,8 +3501,8 @@ SELECT refclassid::regclass, deptype SAVEPOINT q; DROP ROLE regress_rls_eve; --fails due to dependency on POLICY p ERROR: role "regress_rls_eve" cannot be dropped because some objects depend on it -DETAIL: target of policy p on table tbl1 -privileges for table tbl1 +DETAIL: privileges for table tbl1 +target of policy p on table tbl1 ROLLBACK TO q; ALTER POLICY p ON tbl1 TO regress_rls_frank USING (true); SAVEPOINT q; @@ -4093,14 +3910,123 @@ DROP OWNED BY regress_rls_dob_role1; DROP POLICY p1 ON dob_t2; -- should succeed DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2; +-- Bug #15708: view + table with RLS should check policies as view owner +CREATE TABLE ref_tbl (a int); +INSERT INTO ref_tbl VALUES (1); +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl VALUES (10); +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +CREATE POLICY p1 ON rls_tbl USING (EXISTS (SELECT 1 FROM ref_tbl)); +GRANT SELECT ON ref_tbl TO regress_rls_bob; +GRANT SELECT ON rls_tbl TO regress_rls_bob; +CREATE VIEW rls_view AS SELECT * FROM rls_tbl; +ALTER VIEW rls_view OWNER TO regress_rls_bob; +GRANT SELECT ON rls_view TO regress_rls_alice; +SET SESSION AUTHORIZATION regress_rls_alice; +SELECT * FROM ref_tbl; -- Permission denied +ERROR: permission denied for table ref_tbl +SELECT * FROM rls_tbl; -- Permission denied +ERROR: permission denied for table rls_tbl +SELECT * FROM rls_view; -- OK + a +---- + 10 +(1 row) + +RESET SESSION AUTHORIZATION; +DROP VIEW rls_view; +DROP TABLE rls_tbl; +DROP TABLE ref_tbl; +-- Leaky operator test +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl SELECT x/10 FROM generate_series(1, 100) x; +ANALYZE rls_tbl; +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +GRANT SELECT ON rls_tbl TO regress_rls_alice; +SET SESSION AUTHORIZATION regress_rls_alice; +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel); +SELECT * FROM rls_tbl WHERE a <<< 1000; + a +--- +(0 rows) + +DROP OPERATOR <<< (int, int); +DROP FUNCTION op_leak(int, int); +RESET SESSION AUTHORIZATION; +DROP TABLE rls_tbl; +-- Bug #16006: whole-row Vars in a policy don't play nice with sub-selects +SET SESSION AUTHORIZATION regress_rls_alice; +CREATE TABLE rls_tbl (a int, b int, c int); +CREATE POLICY p1 ON rls_tbl USING (rls_tbl >= ROW(1,1,1)); +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +ALTER TABLE rls_tbl FORCE ROW LEVEL SECURITY; +INSERT INTO rls_tbl SELECT 10, 20, 30; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rls_tbl + SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss; + QUERY PLAN +-------------------------------------------------------------------- + Insert on regress_rls_schema.rls_tbl + -> Subquery Scan on ss + Output: ss.b, ss.c, NULL::integer + -> Sort + Output: rls_tbl_1.b, rls_tbl_1.c, rls_tbl_1.a + Sort Key: rls_tbl_1.a + -> Seq Scan on regress_rls_schema.rls_tbl rls_tbl_1 + Output: rls_tbl_1.b, rls_tbl_1.c, rls_tbl_1.a + Filter: (rls_tbl_1.* >= '(1,1,1)'::record) +(9 rows) + +INSERT INTO rls_tbl + SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss; +SELECT * FROM rls_tbl; + a | b | c +----+----+---- + 10 | 20 | 30 + 20 | 30 | +(2 rows) + +DROP TABLE rls_tbl; +RESET SESSION AUTHORIZATION; -- -- Clean up objects -- RESET SESSION AUTHORIZATION; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA regress_rls_schema CASCADE; NOTICE: drop cascades to 29 other objects -\set VERBOSITY default +DETAIL: drop cascades to function f_leak(text) +drop cascades to table uaccount +drop cascades to table category +drop cascades to table document +drop cascades to table part_document +drop cascades to table dependent +drop cascades to table rec1 +drop cascades to table rec2 +drop cascades to view rec1v +drop cascades to view rec2v +drop cascades to table s1 +drop cascades to table s2 +drop cascades to view v2 +drop cascades to table b1 +drop cascades to view bv1 +drop cascades to table z1 +drop cascades to table z2 +drop cascades to table x1 +drop cascades to table y1 +drop cascades to table y2 +drop cascades to table t1 +drop cascades to table t2 +drop cascades to table t3 +drop cascades to table t4 +drop cascades to table current_check +drop cascades to table dep1 +drop cascades to table dep2 +drop cascades to table dob_t1 +drop cascades to table dob_t2 DROP USER regress_rls_alice; DROP USER regress_rls_bob; DROP USER regress_rls_carol; diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out index 45cb6ff3dab..a272305eb55 100644 --- a/src/test/regress/expected/rowtypes.out +++ b/src/test/regress/expected/rowtypes.out @@ -294,6 +294,105 @@ order by thousand, tenthous; 999 | 9999 (25 rows) +explain (costs off) +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + QUERY PLAN +----------------------------------------------------------------------- + Sort + Sort Key: thousand, tenthous + -> Bitmap Heap Scan on tenk1 + Filter: (ROW(thousand, tenthous, four) > ROW(998, 5000, 3)) + -> Bitmap Index Scan on tenk1_thous_tenthous + Index Cond: (ROW(thousand, tenthous) >= ROW(998, 5000)) +(6 rows) + +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + thousand | tenthous | four +----------+----------+------ + 998 | 5998 | 2 + 998 | 6998 | 2 + 998 | 7998 | 2 + 998 | 8998 | 2 + 998 | 9998 | 2 + 999 | 999 | 3 + 999 | 1999 | 3 + 999 | 2999 | 3 + 999 | 3999 | 3 + 999 | 4999 | 3 + 999 | 5999 | 3 + 999 | 6999 | 3 + 999 | 7999 | 3 + 999 | 8999 | 3 + 999 | 9999 | 3 +(15 rows) + +explain (costs off) +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + QUERY PLAN +---------------------------------------------------------- + Index Only Scan using tenk1_thous_tenthous on tenk1 + Index Cond: (ROW(thousand, tenthous) > ROW(998, 5000)) +(2 rows) + +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + thousand | tenthous +----------+---------- + 998 | 5998 + 998 | 6998 + 998 | 7998 + 998 | 8998 + 998 | 9998 + 999 | 999 + 999 | 1999 + 999 | 2999 + 999 | 3999 + 999 | 4999 + 999 | 5999 + 999 | 6999 + 999 | 7999 + 999 | 8999 + 999 | 9999 +(15 rows) + +explain (costs off) +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + QUERY PLAN +----------------------------------------------------------- + Sort + Sort Key: thousand, hundred + -> Bitmap Heap Scan on tenk1 + Filter: (ROW(998, 5000) < ROW(thousand, hundred)) + -> Bitmap Index Scan on tenk1_thous_tenthous + Index Cond: (thousand >= 998) +(6 rows) + +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + thousand | hundred +----------+--------- + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 + 999 | 99 +(10 rows) + -- Test case for bug #14010: indexed row comparisons fail with nulls create temp table test_table (a text, b text); insert into test_table values ('a', 'b'); @@ -667,6 +766,17 @@ select row(1, '(1,2)')::testtype6 *<> row(1, '(1,3)')::testtype6; t (1 row) +-- anonymous rowtypes in coldeflists +select q.a, q.b = row(2), q.c = array[row(3)], q.d = row(row(4)) from + unnest(array[row(1, row(2), array[row(3)], row(row(4))), + row(2, row(3), array[row(4)], row(row(5)))]) + as q(a int, b record, c record[], d record); + a | ?column? | ?column? | ?column? +---+----------+----------+---------- + 1 | t | t | t + 2 | f | f | f +(2 rows) + drop type testtype1, testtype2, testtype3, testtype4, testtype5, testtype6; -- -- Test case derived from bug #5716: check multiple uses of a rowtype result @@ -797,6 +907,50 @@ select (row('Jim', 'Beam')).text; -- error ERROR: could not identify column "text" in record data type LINE 1: select (row('Jim', 'Beam')).text; ^ +-- +-- Check the equivalence of functional and column notation +-- +insert into fullname values ('Joe', 'Blow'); +select f.last from fullname f; + last +------ + Blow +(1 row) + +select last(f) from fullname f; + last +------ + Blow +(1 row) + +create function longname(fullname) returns text language sql +as $$select $1.first || ' ' || $1.last$$; +select f.longname from fullname f; + longname +---------- + Joe Blow +(1 row) + +select longname(f) from fullname f; + longname +---------- + Joe Blow +(1 row) + +-- Starting in v11, the notational form does matter if there's ambiguity +alter table fullname add column longname text; +select f.longname from fullname f; + longname +---------- + +(1 row) + +select longname(f) from fullname f; + longname +---------- + Joe Blow +(1 row) + -- -- Test that composite values are seen to have the correct column names -- (bug #11210 and other reports) @@ -993,7 +1147,7 @@ from (values (1,row(1,2)), (1,row(null,null)), (1,null), (6 rows) explain (verbose, costs off) -with r(a,b) as +with r(a,b) as materialized (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) select r, r is null as isnull, r is not null as isnotnull from r; @@ -1006,7 +1160,7 @@ select r, r is null as isnull, r is not null as isnotnull from r; Output: "*VALUES*".column1, "*VALUES*".column2 (5 rows) -with r(a,b) as +with r(a,b) as materialized (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) select r, r is null as isnull, r is not null as isnotnull from r; @@ -1023,7 +1177,7 @@ select r, r is null as isnull, r is not null as isnotnull from r; -- -- Tests for component access / FieldSelect -- -CREATE TABLE compositetable(a text, b text) WITH OIDS; +CREATE TABLE compositetable(a text, b text); INSERT INTO compositetable(a, b) VALUES('fa', 'fb'); -- composite type columns can't directly be accessed (error) SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s; @@ -1037,15 +1191,15 @@ SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s; fa | fb (1 row) --- oids can't be accessed in composite types (error) -SELECT (d).oid FROM (SELECT compositetable AS d FROM compositetable) s; -ERROR: column "oid" not found in data type compositetable -LINE 1: SELECT (d).oid FROM (SELECT compositetable AS d FROM composi... +-- system columns can't be accessed in composite types (error) +SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s; +ERROR: column "ctid" not found in data type compositetable +LINE 1: SELECT (d).ctid FROM (SELECT compositetable AS d FROM compos... ^ -- accessing non-existing column in NULL datum errors out -SELECT (NULL::compositetable).nonexistant; -ERROR: column "nonexistant" not found in data type compositetable -LINE 1: SELECT (NULL::compositetable).nonexistant; +SELECT (NULL::compositetable).nonexistent; +ERROR: column "nonexistent" not found in data type compositetable +LINE 1: SELECT (NULL::compositetable).nonexistent; ^ -- existing column in a NULL composite yield NULL SELECT (NULL::compositetable).a; diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index a4ec5690aa2..210e9cd146c 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -910,24 +910,24 @@ insert into rtest_comp values ('p4', 'cm', 15.0); insert into rtest_comp values ('p5', 'inch', 7.0); insert into rtest_comp values ('p6', 'inch', 4.4); select * from rtest_vcomp order by part; - part | size_in_cm -------+------------ - p1 | 500 - p2 | 300 - p3 | 5 - p4 | 15 - p5 | 17.78 - p6 | 11.176 + part | size_in_cm +------+-------------------- + p1 | 500 + p2 | 300 + p3 | 5 + p4 | 15 + p5 | 17.78 + p6 | 11.176000000000002 (6 rows) select * from rtest_vcomp where size_in_cm > 10.0 order by size_in_cm using >; - part | size_in_cm -------+------------ - p1 | 500 - p2 | 300 - p5 | 17.78 - p4 | 15 - p6 | 11.176 + part | size_in_cm +------+-------------------- + p1 | 500 + p2 | 300 + p5 | 17.78 + p4 | 15 + p6 | 11.176000000000002 (5 rows) -- @@ -1282,13 +1282,23 @@ drop table cchild; -- -- temporarily disable fancy output, so view changes create less diff noise \a\t -SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname; +SELECT viewname, definition FROM pg_views +WHERE schemaname IN ('pg_catalog', 'public') +ORDER BY viewname; iexit| SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath); +key_dependent_view| SELECT view_base_table.key, + view_base_table.data + FROM view_base_table + GROUP BY view_base_table.key; +key_dependent_view_no_cols| SELECT + FROM view_base_table + GROUP BY view_base_table.key + HAVING (length((view_base_table.data)::text) > 0); mvtest_tv| SELECT mvtest_t.type, sum(mvtest_t.amt) AS totamt FROM mvtest_t @@ -1358,7 +1368,7 @@ pg_indexes| SELECT n.nspname AS schemaname, JOIN pg_class i ON ((i.oid = x.indexrelid))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) LEFT JOIN pg_tablespace t ON ((t.oid = i.reltablespace))) - WHERE ((c.relkind = ANY (ARRAY['r'::"char", 'm'::"char"])) AND (i.relkind = 'i'::"char")); + WHERE ((c.relkind = ANY (ARRAY['r'::"char", 'm'::"char", 'p'::"char"])) AND (i.relkind = ANY (ARRAY['i'::"char", 'I'::"char"]))); pg_locks| SELECT l.locktype, l.database, l.relation, @@ -1431,10 +1441,10 @@ pg_publication_tables| SELECT p.pubname, n.nspname AS schemaname, c.relname AS tablename FROM pg_publication p, + LATERAL pg_get_publication_tables((p.pubname)::text) gpt(relid), (pg_class c JOIN pg_namespace n ON ((n.oid = c.relnamespace))) - WHERE (c.oid IN ( SELECT pg_get_publication_tables.relid - FROM pg_get_publication_tables((p.pubname)::text) pg_get_publication_tables(relid))); + WHERE (c.oid = gpt.relid); pg_replication_origin_status| SELECT pg_show_replication_origin_status.local_id, pg_show_replication_origin_status.external_id, pg_show_replication_origin_status.remote_lsn, @@ -1706,7 +1716,7 @@ pg_shadow| SELECT pg_authid.rolname AS usename, pg_authid.rolreplication AS userepl, pg_authid.rolbypassrls AS usebypassrls, pg_authid.rolpassword AS passwd, - (pg_authid.rolvaliduntil)::abstime AS valuntil, + pg_authid.rolvaliduntil AS valuntil, s.setconfig AS useconfig FROM (pg_authid LEFT JOIN pg_db_role_setting s ON (((pg_authid.oid = s.setrole) AND (s.setdatabase = (0)::oid)))) @@ -1731,7 +1741,7 @@ pg_stat_activity| SELECT s.datid, s.backend_xmin, s.query, s.backend_type - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn) + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc) LEFT JOIN pg_database d ON ((s.datid = d.oid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_all_indexes| SELECT c.oid AS relid, @@ -1795,7 +1805,10 @@ pg_stat_bgwriter| SELECT pg_stat_get_bgwriter_timed_checkpoints() AS checkpoints pg_stat_get_bgwriter_stat_reset_time() AS stats_reset; pg_stat_database| SELECT d.oid AS datid, d.datname, - pg_stat_get_db_numbackends(d.oid) AS numbackends, + CASE + WHEN (d.oid = (0)::oid) THEN 0 + ELSE pg_stat_get_db_numbackends(d.oid) + END AS numbackends, pg_stat_get_db_xact_commit(d.oid) AS xact_commit, pg_stat_get_db_xact_rollback(d.oid) AS xact_rollback, (pg_stat_get_db_blocks_fetched(d.oid) - pg_stat_get_db_blocks_hit(d.oid)) AS blks_read, @@ -1809,10 +1822,17 @@ pg_stat_database| SELECT d.oid AS datid, pg_stat_get_db_temp_files(d.oid) AS temp_files, pg_stat_get_db_temp_bytes(d.oid) AS temp_bytes, pg_stat_get_db_deadlocks(d.oid) AS deadlocks, + pg_stat_get_db_checksum_failures(d.oid) AS checksum_failures, + pg_stat_get_db_checksum_last_failure(d.oid) AS checksum_last_failure, pg_stat_get_db_blk_read_time(d.oid) AS blk_read_time, pg_stat_get_db_blk_write_time(d.oid) AS blk_write_time, pg_stat_get_db_stat_reset_time(d.oid) AS stats_reset - FROM pg_database d; + FROM ( SELECT 0 AS oid, + NULL::name AS datname + UNION ALL + SELECT pg_database.oid, + pg_database.datname + FROM pg_database) d; pg_stat_database_conflicts| SELECT d.oid AS datid, d.datname, pg_stat_get_db_conflict_tablespace(d.oid) AS confl_tablespace, @@ -1821,6 +1841,75 @@ pg_stat_database_conflicts| SELECT d.oid AS datid, pg_stat_get_db_conflict_bufferpin(d.oid) AS confl_bufferpin, pg_stat_get_db_conflict_startup_deadlock(d.oid) AS confl_deadlock FROM pg_database d; +pg_stat_gssapi| SELECT s.pid, + s.gss_auth AS gss_authenticated, + s.gss_princ AS principal, + s.gss_enc AS encrypted + FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc); +pg_stat_progress_cluster| SELECT s.pid, + s.datid, + d.datname, + s.relid, + CASE s.param1 + WHEN 1 THEN 'CLUSTER'::text + WHEN 2 THEN 'VACUUM FULL'::text + ELSE NULL::text + END AS command, + CASE s.param2 + WHEN 0 THEN 'initializing'::text + WHEN 1 THEN 'seq scanning heap'::text + WHEN 2 THEN 'index scanning heap'::text + WHEN 3 THEN 'sorting tuples'::text + WHEN 4 THEN 'writing new heap'::text + WHEN 5 THEN 'swapping relation files'::text + WHEN 6 THEN 'rebuilding index'::text + WHEN 7 THEN 'performing final cleanup'::text + ELSE NULL::text + END AS phase, + (s.param3)::oid AS cluster_index_relid, + s.param4 AS heap_tuples_scanned, + s.param5 AS heap_tuples_written, + s.param6 AS heap_blks_total, + s.param7 AS heap_blks_scanned, + s.param8 AS index_rebuild_count + FROM (pg_stat_get_progress_info('CLUSTER'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20) + LEFT JOIN pg_database d ON ((s.datid = d.oid))); +pg_stat_progress_create_index| SELECT s.pid, + s.datid, + d.datname, + s.relid, + (s.param7)::oid AS index_relid, + CASE s.param1 + WHEN 1 THEN 'CREATE INDEX'::text + WHEN 2 THEN 'CREATE INDEX CONCURRENTLY'::text + WHEN 3 THEN 'REINDEX'::text + WHEN 4 THEN 'REINDEX CONCURRENTLY'::text + ELSE NULL::text + END AS command, + CASE s.param10 + WHEN 0 THEN 'initializing'::text + WHEN 1 THEN 'waiting for writers before build'::text + WHEN 2 THEN ('building index'::text || COALESCE((': '::text || pg_indexam_progress_phasename((s.param9)::oid, s.param11)), ''::text)) + WHEN 3 THEN 'waiting for writers before validation'::text + WHEN 4 THEN 'index validation: scanning index'::text + WHEN 5 THEN 'index validation: sorting tuples'::text + WHEN 6 THEN 'index validation: scanning table'::text + WHEN 7 THEN 'waiting for old snapshots'::text + WHEN 8 THEN 'waiting for readers before marking dead'::text + WHEN 9 THEN 'waiting for readers before dropping'::text + ELSE NULL::text + END AS phase, + s.param4 AS lockers_total, + s.param5 AS lockers_done, + s.param6 AS current_locker_pid, + s.param16 AS blocks_total, + s.param17 AS blocks_done, + s.param12 AS tuples_total, + s.param13 AS tuples_done, + s.param14 AS partitions_total, + s.param15 AS partitions_done + FROM (pg_stat_get_progress_info('CREATE INDEX'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20) + LEFT JOIN pg_database d ON ((s.datid = d.oid))); pg_stat_progress_vacuum| SELECT s.pid, s.datid, d.datname, @@ -1841,7 +1930,7 @@ pg_stat_progress_vacuum| SELECT s.pid, s.param5 AS index_vacuum_count, s.param6 AS max_dead_tuples, s.param7 AS num_dead_tuples - FROM (pg_stat_get_progress_info('VACUUM'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10) + FROM (pg_stat_get_progress_info('VACUUM'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20) LEFT JOIN pg_database d ON ((s.datid = d.oid))); pg_stat_replication| SELECT s.pid, s.usesysid, @@ -1861,9 +1950,10 @@ pg_stat_replication| SELECT s.pid, w.flush_lag, w.replay_lag, w.sync_priority, - w.sync_state - FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn) - JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state) ON ((s.pid = w.pid))) + w.sync_state, + w.reply_time + FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc) + JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid))) LEFT JOIN pg_authid u ON ((s.usesysid = u.oid))); pg_stat_ssl| SELECT s.pid, s.ssl, @@ -1871,8 +1961,10 @@ pg_stat_ssl| SELECT s.pid, s.sslcipher AS cipher, s.sslbits AS bits, s.sslcompression AS compression, - s.sslclientdn AS clientdn - FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, sslclientdn); + s.ssl_client_dn AS client_dn, + s.ssl_client_serial AS client_serial, + s.ssl_issuer_dn AS issuer_dn + FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, sslcompression, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc); pg_stat_subscription| SELECT su.oid AS subid, su.subname, st.pid, @@ -2192,6 +2284,35 @@ pg_stats| SELECT n.nspname AS schemaname, JOIN pg_attribute a ON (((c.oid = a.attrelid) AND (a.attnum = s.staattnum)))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE ((NOT a.attisdropped) AND has_column_privilege(c.oid, a.attnum, 'select'::text) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid)))); +pg_stats_ext| SELECT cn.nspname AS schemaname, + c.relname AS tablename, + sn.nspname AS statistics_schemaname, + s.stxname AS statistics_name, + pg_get_userbyid(s.stxowner) AS statistics_owner, + ( SELECT array_agg(a.attname ORDER BY a.attnum) AS array_agg + FROM (unnest(s.stxkeys) k(k) + JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k))))) AS attnames, + s.stxkind AS kinds, + sd.stxdndistinct AS n_distinct, + sd.stxddependencies AS dependencies, + m.most_common_vals, + m.most_common_val_nulls, + m.most_common_freqs, + m.most_common_base_freqs + FROM (((((pg_statistic_ext s + JOIN pg_class c ON ((c.oid = s.stxrelid))) + JOIN pg_statistic_ext_data sd ON ((s.oid = sd.stxoid))) + LEFT JOIN pg_namespace cn ON ((cn.oid = c.relnamespace))) + LEFT JOIN pg_namespace sn ON ((sn.oid = s.stxnamespace))) + LEFT JOIN LATERAL ( SELECT array_agg(pg_mcv_list_items."values") AS most_common_vals, + array_agg(pg_mcv_list_items.nulls) AS most_common_val_nulls, + array_agg(pg_mcv_list_items.frequency) AS most_common_freqs, + array_agg(pg_mcv_list_items.base_frequency) AS most_common_base_freqs + FROM pg_mcv_list_items(sd.stxdmcv) pg_mcv_list_items(index, "values", nulls, frequency, base_frequency)) m ON ((sd.stxdmcv IS NOT NULL))) + WHERE ((NOT (EXISTS ( SELECT 1 + FROM (unnest(s.stxkeys) k(k) + JOIN pg_attribute a ON (((a.attrelid = s.stxrelid) AND (a.attnum = k.k)))) + WHERE (NOT has_column_privilege(c.oid, a.attnum, 'select'::text))))) AND ((c.relrowsecurity = false) OR (NOT row_security_active(c.oid)))); pg_tables| SELECT n.nspname AS schemaname, c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, @@ -2344,7 +2465,8 @@ toyemp| SELECT emp.name, (12 * emp.salary) AS annualsal FROM emp; SELECT tablename, rulename, definition FROM pg_rules - ORDER BY tablename, rulename; +WHERE schemaname IN ('pg_catalog', 'public') +ORDER BY tablename, rulename; pg_settings|pg_settings_n|CREATE RULE pg_settings_n AS ON UPDATE TO pg_catalog.pg_settings DO INSTEAD NOTHING; pg_settings|pg_settings_u|CREATE RULE pg_settings_u AS @@ -2498,21 +2620,21 @@ insert into rule_and_refint_t3 values (1, 11, 12, 'row2'); insert into rule_and_refint_t3 values (1, 12, 11, 'row3'); insert into rule_and_refint_t3 values (1, 12, 12, 'row4'); insert into rule_and_refint_t3 values (1, 11, 13, 'row5'); -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey1" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3c_fkey" DETAIL: Key (id3a, id3c)=(1, 13) is not present in table "rule_and_refint_t2". insert into rule_and_refint_t3 values (1, 13, 11, 'row6'); -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3b_fkey" DETAIL: Key (id3a, id3b)=(1, 13) is not present in table "rule_and_refint_t1". -- Ordinary table insert into rule_and_refint_t3 values (1, 13, 11, 'row6') on conflict do nothing; -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3b_fkey" DETAIL: Key (id3a, id3b)=(1, 13) is not present in table "rule_and_refint_t1". -- rule not fired, so fk violation insert into rule_and_refint_t3 values (1, 13, 11, 'row6') on conflict (id3a, id3b, id3c) do update set id3b = excluded.id3b; -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3b_fkey" DETAIL: Key (id3a, id3b)=(1, 13) is not present in table "rule_and_refint_t1". -- rule fired, so unsupported insert into shoelace values ('sl9', 0, 'pink', 35.0, 'inch', 0.0) @@ -2529,10 +2651,10 @@ create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3 and (rule_and_refint_t3.id3b = new.id3b)) and (rule_and_refint_t3.id3c = new.id3c)); insert into rule_and_refint_t3 values (1, 11, 13, 'row7'); -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey1" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3c_fkey" DETAIL: Key (id3a, id3c)=(1, 13) is not present in table "rule_and_refint_t2". insert into rule_and_refint_t3 values (1, 13, 11, 'row8'); -ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey" +ERROR: insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_id3b_fkey" DETAIL: Key (id3a, id3b)=(1, 13) is not present in table "rule_and_refint_t1". -- -- disallow dropping a view's rule (bug #5072) @@ -2626,10 +2748,12 @@ select * from id_ordered; 6 | Test 6 (6 rows) -\set VERBOSITY terse \\ -- suppress cascade details drop table id cascade; NOTICE: drop cascades to 4 other objects -\set VERBOSITY default +DETAIL: drop cascades to table test_1 +drop cascades to table test_2 +drop cascades to table test_3 +drop cascades to view id_ordered -- -- check corner case where an entirely-dummy subplan is created by -- constraint exclusion @@ -2818,7 +2942,7 @@ Rules: NOTIFY rules_src_deletion -- --- Ensure a aliased target relation for insert is correctly deparsed. +-- Ensure an aliased target relation for insert is correctly deparsed. -- create rule r4 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2; create rule r5 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1; @@ -3107,7 +3231,7 @@ explain (costs off) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING *; (5 rows) -- ensure upserting into a rule, with a CTE (different offsets!) works -WITH data(hat_name, hat_color) AS ( +WITH data(hat_name, hat_color) AS MATERIALIZED ( VALUES ('h8', 'green'), ('h9', 'blue'), ('h7', 'forbidden') @@ -3121,7 +3245,8 @@ RETURNING *; h9 | blue (2 rows) -EXPLAIN (costs off) WITH data(hat_name, hat_color) AS ( +EXPLAIN (costs off) +WITH data(hat_name, hat_color) AS MATERIALIZED ( VALUES ('h8', 'green'), ('h9', 'blue'), ('h7', 'forbidden') @@ -3160,21 +3285,21 @@ CREATE FUNCTION func_with_set_params() RETURNS integer SET extra_float_digits TO 2 SET work_mem TO '4MB' SET datestyle to iso, mdy - SET local_preload_libraries TO "Mixed/Case", 'c:/"a"/path' + SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' IMMUTABLE STRICT; SELECT pg_get_functiondef('func_with_set_params()'::regprocedure); - pg_get_functiondef ---------------------------------------------------------------- - CREATE OR REPLACE FUNCTION public.func_with_set_params() + - RETURNS integer + - LANGUAGE sql + - IMMUTABLE STRICT + - SET search_path TO pg_catalog + - SET extra_float_digits TO '2' + - SET work_mem TO '4MB' + - SET "DateStyle" TO 'iso, mdy' + - SET local_preload_libraries TO "Mixed/Case", "c:/""a""/path"+ - AS $function$select 1;$function$ + + pg_get_functiondef +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE OR REPLACE FUNCTION public.func_with_set_params() + + RETURNS integer + + LANGUAGE sql + + IMMUTABLE STRICT + + SET search_path TO 'pg_catalog' + + SET extra_float_digits TO '2' + + SET work_mem TO '4MB' + + SET "DateStyle" TO 'iso, mdy' + + SET local_preload_libraries TO 'Mixed/Case', 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789'+ + AS $function$select 1;$function$ + (1 row) @@ -3265,37 +3390,6 @@ CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect; DROP TABLE rules_parted_table; -- --- test MERGE --- -CREATE TABLE rule_merge1 (a int, b text); -CREATE TABLE rule_merge2 (a int, b text); -CREATE RULE rule1 AS ON INSERT TO rule_merge1 - DO INSTEAD INSERT INTO rule_merge2 VALUES (NEW.*); -CREATE RULE rule2 AS ON UPDATE TO rule_merge1 - DO INSTEAD UPDATE rule_merge2 SET a = NEW.a, b = NEW.b - WHERE a = OLD.a; -CREATE RULE rule3 AS ON DELETE TO rule_merge1 - DO INSTEAD DELETE FROM rule_merge2 WHERE a = OLD.a; --- MERGE not supported for table with rules -MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s - ON t.a = s.a - WHEN MATCHED AND t.a < 2 THEN - UPDATE SET b = b || ' updated by merge' - WHEN MATCHED AND t.a > 2 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.a, ''); -ERROR: MERGE is not supported for relations with rules --- should be ok with the other table though -MERGE INTO rule_merge2 t USING (SELECT 1 AS a) s - ON t.a = s.a - WHEN MATCHED AND t.a < 2 THEN - UPDATE SET b = b || ' updated by merge' - WHEN MATCHED AND t.a > 2 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.a, ''); --- -- Test enabling/disabling -- CREATE TABLE ruletest1 (a int); diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index ac0fb539e98..d6e75ffce6d 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -13,12 +13,12 @@ SELECT relname, relhasindex ORDER BY relname; a|f a_star|f -abstime_tbl|f aggtest|f array_index_op_test|t array_op_test|f b|f b_star|f +bit_defaults|f box_tbl|f bprime|f bt_f8_heap|t @@ -43,6 +43,7 @@ dupindexcols|t e_star|f emp|f equipment_r|f +extra_wide_table|f f_star|f fast_emp4000|t float4_tbl|f @@ -55,8 +56,6 @@ hash_txt_heap|t hobbies_r|f ihighway|t inet_tbl|f -inhf|f -inhx|t insert_tbl|f int2_tbl|f int4_tbl|f @@ -150,6 +149,7 @@ pg_shdescription|t pg_shseclabel|t pg_statistic|t pg_statistic_ext|t +pg_statistic_ext_data|t pg_subscription|t pg_subscription_rel|t pg_tablespace|t @@ -165,14 +165,13 @@ pg_user_mapping|t point_tbl|t polygon_tbl|t quad_box_tbl|t +quad_box_tbl_ord_seq1|f +quad_box_tbl_ord_seq2|f quad_point_tbl|t quad_poly_tbl|t -quad_poly_tbl_ord_seq1|f -quad_poly_tbl_ord_seq2|f radix_text_tbl|t ramp|f real_city|f -reltime_tbl|f road|t shighway|t slow_emp4000|f @@ -185,6 +184,19 @@ sql_sizing|f sql_sizing_profiles|f stud_emp|f student|f +tableam_parted_a_heap2|f +tableam_parted_b_heap2|f +tableam_parted_c_heap2|f +tableam_parted_d_heap2|f +tableam_parted_heap2|f +tableam_tbl_heap2|f +tableam_tblas_heap2|f +tbl_include_box|t +tbl_include_box_pk|f +tbl_include_pk|t +tbl_include_reg|t +tbl_include_unique1|t +tbl_include_unique2|f tenk1|t tenk2|t test_range_excl|t @@ -197,8 +209,9 @@ time_tbl|f timestamp_tbl|f timestamptz_tbl|f timetz_tbl|f -tinterval_tbl|f +tmp|f varchar_tbl|f +view_base_table|t -- restore normal output mode \a\t -- @@ -208,13 +221,22 @@ varchar_tbl|f -- We exclude non-system tables from the check by looking at nspname. -- SELECT relname, nspname -FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace -WHERE relhasoids - AND ((nspname ~ '^pg_') IS NOT FALSE) - AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid - AND indkey[0] = -2 AND indnatts = 1 - AND indisunique AND indimmediate); + FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid') + WHERE relkind = 'r' and c.oid < 16384 + AND ((nspname ~ '^pg_') IS NOT FALSE) + AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid + AND indkey[0] = a.attnum AND indnatts = 1 + AND indisunique AND indimmediate); relname | nspname ---------+--------- (0 rows) +-- check that relations without storage don't have relfilenode +SELECT relname, relkind + FROM pg_class + WHERE relkind IN ('v', 'c', 'f', 'p', 'I') + AND relfilenode <> 0; + relname | relkind +---------+--------- +(0 rows) + diff --git a/src/test/regress/expected/select.out b/src/test/regress/expected/select.out index 1fab5136d29..c441049f413 100644 --- a/src/test/regress/expected/select.out +++ b/src/test/regress/expected/select.out @@ -438,19 +438,19 @@ SELECT p.name, p.age FROM person* p ORDER BY age using >, name; -- -- Test some cases involving whole-row Var referencing a subquery -- -select foo from (select 1) as foo; +select foo from (select 1 offset 0) as foo; foo ----- (1) (1 row) -select foo from (select null) as foo; +select foo from (select null offset 0) as foo; foo ----- () (1 row) -select foo from (select 'xyzzy',1,null) as foo; +select foo from (select 'xyzzy',1,null offset 0) as foo; foo ------------ (xyzzy,1,) @@ -951,3 +951,16 @@ select * from (values (2),(null),(1)) v(k) where k = k; 1 (2 rows) +-- Test partitioned tables with no partitions, which should be handled the +-- same as the non-inheritance case when expanding its RTE. +create table list_parted_tbl (a int,b int) partition by list (a); +create table list_parted_tbl1 partition of list_parted_tbl + for values in (1) partition by list(b); +explain (costs off) select * from list_parted_tbl; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +drop table list_parted_tbl; diff --git a/src/test/regress/expected/select_into.out b/src/test/regress/expected/select_into.out index 942f975e953..f373fae6796 100644 --- a/src/test/regress/expected/select_into.out +++ b/src/test/regress/expected/select_into.out @@ -112,14 +112,15 @@ SELECT * FROM created_table; 4567890123456789 | -4567890123456789 (5 rows) --- Try EXPLAIN ANALYZE SELECT INTO, but hide the output since it won't --- be stable. +-- Try EXPLAIN ANALYZE SELECT INTO and EXPLAIN ANALYZE CREATE TABLE AS +-- WITH NO DATA, but hide the outputs since they won't be stable. DO $$ BEGIN EXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl'; + EXECUTE 'EXPLAIN ANALYZE CREATE TABLE easi2 AS SELECT * FROM int8_tbl WITH NO DATA'; END$$; DROP TABLE created_table; -DROP TABLE easi; +DROP TABLE easi, easi2; -- -- Disallowed uses of SELECT ... INTO. All should fail -- diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index fb209de5e9a..0eca76cb41e 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -132,6 +132,32 @@ select sp_test_func() order by 1; foo (2 rows) +-- Parallel Append is not to be used when the subpath depends on the outer param +create table part_pa_test(a int, b int) partition by range(a); +create table part_pa_test_p1 partition of part_pa_test for values from (minvalue) to (0); +create table part_pa_test_p2 partition of part_pa_test for values from (0) to (maxvalue); +explain (costs off) + select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) + from part_pa_test pa2; + QUERY PLAN +-------------------------------------------------------------- + Aggregate + -> Gather + Workers Planned: 3 + -> Parallel Append + -> Parallel Seq Scan on part_pa_test_p1 pa2 + -> Parallel Seq Scan on part_pa_test_p2 pa2_1 + SubPlan 2 + -> Result + SubPlan 1 + -> Append + -> Seq Scan on part_pa_test_p1 pa1 + Filter: (a = pa2.a) + -> Seq Scan on part_pa_test_p2 pa1_1 + Filter: (a = pa2.a) +(14 rows) + +drop table part_pa_test; -- test with leader participation disabled set parallel_leader_participation = off; explain (costs off) @@ -633,6 +659,68 @@ explain (costs off, verbose) (11 rows) drop function sp_simple_func(integer); +-- test handling of SRFs in targetlist (bug in 10.0) +explain (costs off) + select count(*), generate_series(1,2) from tenk1 group by twenty; + QUERY PLAN +---------------------------------------------------------- + ProjectSet + -> Finalize GroupAggregate + Group Key: twenty + -> Gather Merge + Workers Planned: 4 + -> Partial GroupAggregate + Group Key: twenty + -> Sort + Sort Key: twenty + -> Parallel Seq Scan on tenk1 +(10 rows) + +select count(*), generate_series(1,2) from tenk1 group by twenty; + count | generate_series +-------+----------------- + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 + 500 | 1 + 500 | 2 +(40 rows) + -- test gather merge with parallel leader participation disabled set parallel_leader_participation = off; explain (costs off) @@ -870,6 +958,51 @@ select count(*) from tenk1; reset force_parallel_mode; reset role; +-- Window function calculation can't be pushed to workers. +explain (costs off, verbose) + select count(*) from tenk1 a where (unique1, two) in + (select unique1, row_number() over() from tenk1 b); + QUERY PLAN +---------------------------------------------------------------------------------------------- + Aggregate + Output: count(*) + -> Hash Semi Join + Hash Cond: ((a.unique1 = b.unique1) AND (a.two = (row_number() OVER (?)))) + -> Gather + Output: a.unique1, a.two + Workers Planned: 4 + -> Parallel Seq Scan on public.tenk1 a + Output: a.unique1, a.two + -> Hash + Output: b.unique1, (row_number() OVER (?)) + -> WindowAgg + Output: b.unique1, row_number() OVER (?) + -> Gather + Output: b.unique1 + Workers Planned: 4 + -> Parallel Index Only Scan using tenk1_unique1 on public.tenk1 b + Output: b.unique1 +(18 rows) + +-- LIMIT/OFFSET within sub-selects can't be pushed to workers. +explain (costs off) + select * from tenk1 a where two in + (select two from tenk1 b where stringu1 like '%AAAA' limit 3); + QUERY PLAN +--------------------------------------------------------------- + Hash Semi Join + Hash Cond: (a.two = b.two) + -> Gather + Workers Planned: 4 + -> Parallel Seq Scan on tenk1 a + -> Hash + -> Limit + -> Gather + Workers Planned: 4 + -> Parallel Seq Scan on tenk1 b + Filter: (stringu1 ~~ '%AAAA'::text) +(11 rows) + -- to increase the parallel query test coverage SAVEPOINT settings; SET LOCAL force_parallel_mode = 1; @@ -887,7 +1020,7 @@ ROLLBACK TO SAVEPOINT settings; SAVEPOINT settings; SET LOCAL force_parallel_mode = 1; select stringu1::int2 from tenk1 where unique1 = 1; -ERROR: invalid input syntax for integer: "BAAAAA" +ERROR: invalid input syntax for type smallint: "BAAAAA" CONTEXT: parallel worker ROLLBACK TO SAVEPOINT settings; -- test interaction with set-returning functions @@ -955,4 +1088,49 @@ ORDER BY 1, 2, 3; ------------------------------+---------------------------+-------------+-------------- (0 rows) +-- test passing expanded-value representations to workers +CREATE FUNCTION make_some_array(int,int) returns int[] as +$$declare x int[]; + begin + x[1] := $1; + x[2] := $2; + return x; + end$$ language plpgsql parallel safe; +CREATE TABLE fooarr(f1 text, f2 int[], f3 text); +INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one'); +PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2; +EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)); + QUERY PLAN +------------------------------------------------------------------ + Gather + Workers Planned: 3 + -> Parallel Seq Scan on fooarr + Filter: ((f1 = '1'::text) AND (f2 = '{1,2}'::integer[])) +(4 rows) + +EXECUTE pstmt('1', make_some_array(1,2)); + f1 | f2 | f3 +----+-------+----- + 1 | {1,2} | one +(1 row) + +DEALLOCATE pstmt; +-- test interaction between subquery and partial_paths +CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1; +EXPLAIN (COSTS OFF) +SELECT 1 FROM tenk1_vw_sec + WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100; + QUERY PLAN +------------------------------------------------------------------- + Subquery Scan on tenk1_vw_sec + Filter: ((SubPlan 1) < 100) + -> Gather + Workers Planned: 4 + -> Parallel Index Only Scan using tenk1_unique1 on tenk1 + SubPlan 1 + -> Aggregate + -> Seq Scan on int4_tbl + Filter: (f1 < tenk1_vw_sec.unique1) +(9 rows) + rollback; diff --git a/src/test/regress/expected/select_views.out b/src/test/regress/expected/select_views.out index bf003adf243..1aeed8452bd 100644 --- a/src/test/regress/expected/select_views.out +++ b/src/test/regress/expected/select_views.out @@ -1326,10 +1326,10 @@ NOTICE: f_leak => hamburger (1 row) EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal WHERE f_leak(passwd); - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------ Seq Scan on customer - Filter: (f_leak(passwd) AND (name = (CURRENT_USER)::text)) + Filter: (f_leak(passwd) AND (name = CURRENT_USER)) (2 rows) SELECT * FROM my_property_secure WHERE f_leak(passwd); @@ -1340,12 +1340,12 @@ NOTICE: f_leak => passwd123 (1 row) EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure WHERE f_leak(passwd); - QUERY PLAN ------------------------------------------------ + QUERY PLAN +--------------------------------------------- Subquery Scan on my_property_secure Filter: f_leak(my_property_secure.passwd) -> Seq Scan on customer - Filter: (name = (CURRENT_USER)::text) + Filter: (name = CURRENT_USER) (4 rows) -- @@ -1367,10 +1367,10 @@ NOTICE: f_leak => hamburger EXPLAIN (COSTS OFF) SELECT * FROM my_property_normal v WHERE f_leak('passwd') AND f_leak(passwd); - QUERY PLAN ------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------- Seq Scan on customer - Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = (CURRENT_USER)::text)) + Filter: (f_leak('passwd'::text) AND f_leak(passwd) AND (name = CURRENT_USER)) (2 rows) SELECT * FROM my_property_secure v @@ -1386,12 +1386,12 @@ NOTICE: f_leak => passwd EXPLAIN (COSTS OFF) SELECT * FROM my_property_secure v WHERE f_leak('passwd') AND f_leak(passwd); - QUERY PLAN ----------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------- Subquery Scan on v Filter: f_leak(v.passwd) -> Seq Scan on customer - Filter: (f_leak('passwd'::text) AND (name = (CURRENT_USER)::text)) + Filter: (f_leak('passwd'::text) AND (name = CURRENT_USER)) (4 rows) -- @@ -1409,15 +1409,15 @@ NOTICE: f_leak => 9801-2345-6789-0123 (1 row) EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_normal WHERE f_leak(cnum); - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +--------------------------------------------- Hash Join Hash Cond: (r.cid = l.cid) -> Seq Scan on credit_card r Filter: f_leak(cnum) -> Hash -> Seq Scan on customer l - Filter: (name = (CURRENT_USER)::text) + Filter: (name = CURRENT_USER) (7 rows) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum); @@ -1428,8 +1428,8 @@ NOTICE: f_leak => 1111-2222-3333-4444 (1 row) EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum); - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------- Subquery Scan on my_credit_card_secure Filter: f_leak(my_credit_card_secure.cnum) -> Hash Join @@ -1437,7 +1437,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_secure WHERE f_leak(cnum); -> Seq Scan on credit_card r -> Hash -> Seq Scan on customer l - Filter: (name = (CURRENT_USER)::text) + Filter: (name = CURRENT_USER) (8 rows) -- @@ -1471,7 +1471,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_normal -> Seq Scan on credit_card r_1 -> Hash -> Seq Scan on customer l_1 - Filter: (name = (CURRENT_USER)::text) + Filter: (name = CURRENT_USER) (13 rows) SELECT * FROM my_credit_card_usage_secure @@ -1502,7 +1502,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM my_credit_card_usage_secure -> Seq Scan on credit_card r_1 -> Hash -> Seq Scan on customer l - Filter: (name = (CURRENT_USER)::text) + Filter: (name = CURRENT_USER) (13 rows) -- diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out index ca5ea063fa0..a0d2b22d3c0 100644 --- a/src/test/regress/expected/sequence.out +++ b/src/test/regress/expected/sequence.out @@ -293,11 +293,11 @@ CREATE TEMP TABLE t1 ( -- Both drops should fail, but with different error messages: DROP SEQUENCE t1_f1_seq; ERROR: cannot drop sequence t1_f1_seq because other objects depend on it -DETAIL: default for table t1 column f1 depends on sequence t1_f1_seq +DETAIL: default value for column f1 of table t1 depends on sequence t1_f1_seq HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP SEQUENCE myseq2; ERROR: cannot drop sequence myseq2 because other objects depend on it -DETAIL: default for table t1 column f2 depends on sequence myseq2 +DETAIL: default value for column f2 of table t1 depends on sequence myseq2 HINT: Use DROP ... CASCADE to drop the dependent objects too. -- This however will work: DROP SEQUENCE myseq3; diff --git a/src/test/regress/expected/spgist.out b/src/test/regress/expected/spgist.out index 2d75bbf8dcb..9364b88bc22 100644 --- a/src/test/regress/expected/spgist.out +++ b/src/test/regress/expected/spgist.out @@ -23,6 +23,24 @@ delete from spgist_point_tbl where id % 2 = 1; -- would exercise it) delete from spgist_point_tbl where id < 10000; vacuum spgist_point_tbl; +-- Test rescan paths (cf. bug #15378) +-- use box and && rather than point, so that rescan happens when the +-- traverse stack is non-empty +create table spgist_box_tbl(id serial, b box); +insert into spgist_box_tbl(b) +select box(point(i,j),point(i+s,j+s)) + from generate_series(1,100,5) i, + generate_series(1,100,5) j, + generate_series(1,10) s; +create index spgist_box_idx on spgist_box_tbl using spgist (b); +select count(*) + from (values (point(5,5)),(point(8,8)),(point(12,12))) v(p) + where exists(select * from spgist_box_tbl b where b.b && box(v.p,v.p)); + count +------- + 3 +(1 row) + -- The point opclass's choose method only uses the spgMatchNode action, -- so the other actions are not tested by the above. Create an index using -- text opclass, which uses the others actions. diff --git a/src/test/regress/expected/stats.out b/src/test/regress/expected/stats.out index 991c287b114..b01e58b98cb 100644 --- a/src/test/regress/expected/stats.out +++ b/src/test/regress/expected/stats.out @@ -79,9 +79,9 @@ end $$ language plpgsql; -- test effects of TRUNCATE on n_live_tup/n_dead_tup counters CREATE TABLE trunc_stats_test(id serial); -CREATE TABLE trunc_stats_test1(id serial); +CREATE TABLE trunc_stats_test1(id serial, stuff text); CREATE TABLE trunc_stats_test2(id serial); -CREATE TABLE trunc_stats_test3(id serial); +CREATE TABLE trunc_stats_test3(id serial, stuff text); CREATE TABLE trunc_stats_test4(id serial); -- check that n_live_tup is reset to 0 after truncate INSERT INTO trunc_stats_test DEFAULT VALUES; diff --git a/src/test/regress/expected/stats_ext.out b/src/test/regress/expected/stats_ext.out index 054a381dad3..b65228fa07a 100644 --- a/src/test/regress/expected/stats_ext.out +++ b/src/test/regress/expected/stats_ext.out @@ -2,9 +2,26 @@ -- We will be checking execution plans without/with statistics, so -- let's make sure we get simple non-parallel plans. Also set the -- work_mem low so that we can use small amounts of data. -SET max_parallel_workers = 0; -SET max_parallel_workers_per_gather = 0; -SET work_mem = '128kB'; +-- check the number of estimated/actual rows in the top node +create function check_estimated_rows(text) returns table (estimated int, actual int) +language plpgsql as +$$ +declare + ln text; + tmp text[]; + first_row bool := true; +begin + for ln in + execute format('explain analyze %s', $1) + loop + if first_row then + first_row := false; + tmp := regexp_match(ln, 'rows=(\d*) .* rows=(\d*)'); + return query select tmp[1]::int, tmp[2]::int; + end if; + end loop; +end; +$$; -- Verify failures CREATE STATISTICS tst; ERROR: syntax error at or near ";" @@ -18,8 +35,8 @@ CREATE STATISTICS tst FROM sometab; ERROR: syntax error at or near "FROM" LINE 1: CREATE STATISTICS tst FROM sometab; ^ -CREATE STATISTICS tst ON a, b FROM nonexistant; -ERROR: relation "nonexistant" does not exist +CREATE STATISTICS tst ON a, b FROM nonexistent; +ERROR: relation "nonexistent" does not exist CREATE STATISTICS tst ON a, b FROM pg_class; ERROR: column "a" does not exist CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class; @@ -58,7 +75,7 @@ ALTER TABLE ab1 DROP COLUMN a; b | integer | | | c | integer | | | Statistics objects: - "public"."ab1_b_c_stats" (ndistinct, dependencies) ON b, c FROM ab1 + "public"."ab1_b_c_stats" (ndistinct, dependencies, mcv) ON b, c FROM ab1 -- Ensure statistics are dropped when table is SELECT stxname FROM pg_statistic_ext WHERE stxname LIKE 'ab1%'; @@ -81,11 +98,36 @@ CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; ANALYZE ab1; WARNING: statistics object "public.ab1_a_b_stats" could not be computed for relation "public.ab1" ALTER TABLE ab1 ALTER a SET STATISTICS -1; +-- setting statistics target 0 skips the statistics, without printing any message, so check catalog +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; +ANALYZE ab1; +SELECT stxname, stxdndistinct, stxddependencies, stxdmcv + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'ab1_a_b_stats' + AND d.stxoid = s.oid; + stxname | stxdndistinct | stxddependencies | stxdmcv +---------------+---------------+------------------+--------- + ab1_a_b_stats | | | +(1 row) + +ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1; -- partial analyze doesn't build stats either ANALYZE ab1 (a); WARNING: statistics object "public.ab1_a_b_stats" could not be computed for relation "public.ab1" ANALYZE ab1; DROP TABLE ab1; +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; +ERROR: statistics object "ab1_a_b_stats" does not exist +ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0; +NOTICE: statistics object "ab1_a_b_stats" does not exist, skipping +-- Ensure we can build statistics for tables with inheritance. +CREATE TABLE ab1 (a INTEGER, b INTEGER); +CREATE TABLE ab1c () INHERITS (ab1); +INSERT INTO ab1 VALUES (1,1); +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; +ANALYZE ab1; +DROP TABLE ab1 CASCADE; +NOTICE: drop cascades to table ab1c -- Verify supported object types for extended statistics CREATE schema tststats; CREATE TABLE tststats.t (a int, b int, c text); @@ -122,12 +164,17 @@ EXCEPTION WHEN wrong_object_type THEN END; $$; NOTICE: stats on toast table not created -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA tststats CASCADE; NOTICE: drop cascades to 7 other objects +DETAIL: drop cascades to table tststats.t +drop cascades to sequence tststats.s +drop cascades to view tststats.v +drop cascades to materialized view tststats.mv +drop cascades to type tststats.ty +drop cascades to foreign table tststats.f +drop cascades to table tststats.pt DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE; NOTICE: drop cascades to server extstats_dummy_srv -\set VERBOSITY default -- n-distinct tests CREATE TABLE ndistinct ( filler1 TEXT, @@ -141,245 +188,170 @@ CREATE TABLE ndistinct ( -- over-estimates when using only per-column statistics INSERT INTO ndistinct (a, b, c, filler1) SELECT i/100, i/100, i/100, cash_words((i/100)::money) - FROM generate_series(1,30000) s(i); + FROM generate_series(1,1000) s(i); ANALYZE ndistinct; -- Group Aggregate, due to over-estimate of the number of groups -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b - -> Sort - Sort Key: a, b - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: b, c - -> Sort - Sort Key: b, c - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b, c - -> Sort - Sort Key: a, b, c - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b, c, d - -> Sort - Sort Key: a, b, c, d - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: b, c, d - -> Sort - Sort Key: b, c, d - -> Seq Scan on ndistinct -(5 rows) +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + estimated | actual +-----------+-------- + 100 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); + estimated | actual +-----------+-------- + 100 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + estimated | actual +-----------+-------- + 100 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + estimated | actual +-----------+-------- + 200 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + estimated | actual +-----------+-------- + 200 | 11 +(1 row) -- correct command CREATE STATISTICS s10 ON a, b, c FROM ndistinct; ANALYZE ndistinct; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; - stxkind | stxndistinct ----------+--------------------------------------------------------- - {d,f} | {"3, 4": 301, "3, 6": 301, "4, 6": 301, "3, 4, 6": 301} +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + stxkind | stxdndistinct +---------+----------------------------------------------------- + {d,f,m} | {"3, 4": 11, "3, 6": 11, "4, 6": 11, "3, 4, 6": 11} (1 row) -- Hash Aggregate, thanks to estimates improved by the statistic -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, b - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: b, c - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, b, c - -> Seq Scan on ndistinct -(3 rows) +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + estimated | actual +-----------+-------- + 11 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); + estimated | actual +-----------+-------- + 11 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + estimated | actual +-----------+-------- + 11 | 11 +(1 row) -- last two plans keep using Group Aggregate, because 'd' is not covered -- by the statistic and while it's NULL-only we assume 200 values for it -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b, c, d - -> Sort - Sort Key: a, b, c, d - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: b, c, d - -> Sort - Sort Key: b, c, d - -> Seq Scan on ndistinct -(5 rows) +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + estimated | actual +-----------+-------- + 200 | 11 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + estimated | actual +-----------+-------- + 200 | 11 +(1 row) TRUNCATE TABLE ndistinct; -- under-estimates when using only per-column statistics INSERT INTO ndistinct (a, b, c, filler1) SELECT mod(i,50), mod(i,51), mod(i,32), cash_words(mod(i,33)::int::money) - FROM generate_series(1,10000) s(i); + FROM generate_series(1,5000) s(i); ANALYZE ndistinct; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; - stxkind | stxndistinct ----------+------------------------------------------------------------- - {d,f} | {"3, 4": 2550, "3, 6": 800, "4, 6": 1632, "3, 4, 6": 10000} -(1 row) - --- plans using Group Aggregate, thanks to using correct esimates -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b - -> Sort - Sort Key: a, b - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b, c - -> Sort - Sort Key: a, b, c - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; - QUERY PLAN ------------------------------------ - GroupAggregate - Group Key: a, b, c, d - -> Sort - Sort Key: a, b, c, d - -> Seq Scan on ndistinct -(5 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: b, c, d - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, d; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, d - -> Seq Scan on ndistinct -(3 rows) +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + stxkind | stxdndistinct +---------+------------------------------------------------------------ + {d,f,m} | {"3, 4": 2550, "3, 6": 800, "4, 6": 1632, "3, 4, 6": 5000} +(1 row) + +-- correct esimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + estimated | actual +-----------+-------- + 2550 | 2550 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + estimated | actual +-----------+-------- + 5000 | 5000 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + estimated | actual +-----------+-------- + 5000 | 5000 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + estimated | actual +-----------+-------- + 1632 | 1632 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); + estimated | actual +-----------+-------- + 500 | 50 +(1 row) DROP STATISTICS s10; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; - stxkind | stxndistinct ----------+-------------- +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; + stxkind | stxdndistinct +---------+--------------- (0 rows) --- dropping the statistics switches the plans to Hash Aggregate, --- due to under-estimates -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, b - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, b, c - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, b, c, d - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: b, c, d - -> Seq Scan on ndistinct -(3 rows) - -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, d; - QUERY PLAN ------------------------------ - HashAggregate - Group Key: a, d - -> Seq Scan on ndistinct -(3 rows) +-- dropping the statistics results in under-estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); + estimated | actual +-----------+-------- + 500 | 2550 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); + estimated | actual +-----------+-------- + 500 | 5000 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); + estimated | actual +-----------+-------- + 500 | 5000 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); + estimated | actual +-----------+-------- + 500 | 1632 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); + estimated | actual +-----------+-------- + 500 | 50 +(1 row) -- functional dependencies tests CREATE TABLE functional_dependencies ( @@ -391,51 +363,38 @@ CREATE TABLE functional_dependencies ( c INT, d TEXT ); -SET random_page_cost = 1.2; CREATE INDEX fdeps_ab_idx ON functional_dependencies (a, b); CREATE INDEX fdeps_abc_idx ON functional_dependencies (a, b, c); -- random data (no functional dependencies) INSERT INTO functional_dependencies (a, b, c, filler1) SELECT mod(i, 23), mod(i, 29), mod(i, 31), i FROM generate_series(1,5000) s(i); ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - -> Bitmap Index Scan on fdeps_abc_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(4 rows) - -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ------------------------------------------------------------ - Index Scan using fdeps_abc_idx on functional_dependencies - Index Cond: ((a = 1) AND (b = '1'::text) AND (c = 1)) -(2 rows) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 8 | 8 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 1 +(1 row) -- create statistics CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - -> Bitmap Index Scan on fdeps_abc_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(4 rows) - -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ------------------------------------------------------------ - Index Scan using fdeps_abc_idx on functional_dependencies - Index Cond: ((a = 1) AND (b = '1'::text) AND (c = 1)) -(2 rows) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 8 | 8 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 1 +(1 row) -- a => b, a => c, b => c TRUNCATE functional_dependencies; @@ -443,69 +402,413 @@ DROP STATISTICS func_deps_stat; INSERT INTO functional_dependencies (a, b, c, filler1) SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i); ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; - QUERY PLAN ------------------------------------------------------------ - Index Scan using fdeps_abc_idx on functional_dependencies - Index Cond: ((a = 1) AND (b = '1'::text)) -(2 rows) - -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ------------------------------------------------------------ - Index Scan using fdeps_abc_idx on functional_dependencies - Index Cond: ((a = 1) AND (b = '1'::text) AND (c = 1)) -(2 rows) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) -- create statistics CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - -> Bitmap Index Scan on fdeps_abc_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(4 rows) - -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - Filter: (c = 1) - -> Bitmap Index Scan on fdeps_ab_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(5 rows) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) -- check change of column type doesn't break it ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - Filter: (c = '1'::numeric) - -> Bitmap Index Scan on fdeps_ab_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(5 rows) +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; - QUERY PLAN ---------------------------------------------------- - Bitmap Heap Scan on functional_dependencies - Recheck Cond: ((a = 1) AND (b = '1'::text)) - Filter: (c = '1'::numeric) - -> Bitmap Index Scan on fdeps_ab_idx - Index Cond: ((a = 1) AND (b = '1'::text)) -(5 rows) - -RESET random_page_cost; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +-- MCV lists +CREATE TABLE mcv_lists ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b VARCHAR, + filler3 DATE, + c INT, + d TEXT +); +-- random data (no MCV list) +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,37), mod(i,41), mod(i,43), mod(i,47) FROM generate_series(1,5000) s(i); +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 3 | 4 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 1 +(1 row) + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 3 | 4 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 1 +(1 row) + +-- 100 distinct combinations, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i); +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +-- check change of unrelated column type does not reset the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64); +SELECT d.stxdmcv IS NOT NULL + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + ?column? +---------- + t +(1 row) + +-- check change of column type resets the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +-- 100 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT + (CASE WHEN mod(i,100) = 1 THEN NULL ELSE mod(i,100) END), + (CASE WHEN mod(i,50) = 1 THEN NULL ELSE mod(i,50) END), + (CASE WHEN mod(i,25) = 1 THEN NULL ELSE mod(i,25) END), + i + FROM generate_series(1,5000) s(i); +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + estimated | actual +-----------+-------- + 1 | 50 +(1 row) + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + estimated | actual +-----------+-------- + 50 | 50 +(1 row) + +-- test pg_mcv_list_items with a very simple (single item) MCV list +TRUNCATE mcv_lists; +INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i); +ANALYZE mcv_lists; +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + index | values | nulls | frequency | base_frequency +-------+---------+---------+-----------+---------------- + 0 | {1,2,3} | {f,f,f} | 1 | 1 +(1 row) + +-- 2 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; +INSERT INTO mcv_lists (a, b, c, d) + SELECT + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END) + FROM generate_series(1,5000) s(i); +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + estimated | actual +-----------+-------- + 3750 | 2500 +(1 row) + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON b, d FROM mcv_lists; +ANALYZE mcv_lists; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + estimated | actual +-----------+-------- + 2500 | 2500 +(1 row) + +-- mcv with arrays +CREATE TABLE mcv_lists_arrays ( + a TEXT[], + b NUMERIC[], + c INT[] +); +INSERT INTO mcv_lists_arrays (a, b, c) + SELECT + ARRAY[md5((i/100)::text), md5((i/100-1)::text), md5((i/100+1)::text)], + ARRAY[(i/100-1)::numeric/1000, (i/100)::numeric/1000, (i/100+1)::numeric/1000], + ARRAY[(i/100-1), i/100, (i/100+1)] + FROM generate_series(1,5000) s(i); +CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c + FROM mcv_lists_arrays; +ANALYZE mcv_lists_arrays; +-- mcv with bool +CREATE TABLE mcv_lists_bool ( + a BOOL, + b BOOL, + c BOOL +); +INSERT INTO mcv_lists_bool (a, b, c) + SELECT + (mod(i,2) = 0), (mod(i,4) = 0), (mod(i,8) = 0) + FROM generate_series(1,10000) s(i); +ANALYZE mcv_lists_bool; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + estimated | actual +-----------+-------- + 156 | 1250 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + estimated | actual +-----------+-------- + 156 | 0 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + estimated | actual +-----------+-------- + 469 | 0 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + estimated | actual +-----------+-------- + 1094 | 0 +(1 row) + +CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c + FROM mcv_lists_bool; +ANALYZE mcv_lists_bool; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + estimated | actual +-----------+-------- + 1250 | 1250 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + estimated | actual +-----------+-------- + 1 | 0 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + estimated | actual +-----------+-------- + 1 | 0 +(1 row) + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + estimated | actual +-----------+-------- + 1 | 0 +(1 row) + +-- Permission tests. Users should not be able to see specific data values in +-- the extended statistics, if they lack permission to see those values in +-- the underlying table. +-- +-- Currently this is only relevant for MCV stats. +CREATE SCHEMA tststats; +CREATE TABLE tststats.priv_test_tbl ( + a int, + b int +); +INSERT INTO tststats.priv_test_tbl + SELECT mod(i,5), mod(i,10) FROM generate_series(1,100) s(i); +CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b + FROM tststats.priv_test_tbl; +ANALYZE tststats.priv_test_tbl; +-- User with no access +CREATE USER regress_stats_user1; +GRANT USAGE ON SCHEMA tststats TO regress_stats_user1; +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_tbl; -- Permission denied +ERROR: permission denied for table priv_test_tbl +-- Attempt to gain access using a leaky operator +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel); +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Permission denied +ERROR: permission denied for table priv_test_tbl +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Permission denied +ERROR: permission denied for table priv_test_tbl +-- Grant access via a security barrier view, but hide all data +RESET SESSION AUTHORIZATION; +CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) + AS SELECT * FROM tststats.priv_test_tbl WHERE false; +GRANT SELECT, DELETE ON tststats.priv_test_view TO regress_stats_user1; +-- Should now have access via the view, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; -- Should not leak + a | b +---+--- +(0 rows) + +DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; -- Should not leak +-- Grant table access, but hide all data with RLS +RESET SESSION AUTHORIZATION; +ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY; +GRANT SELECT, DELETE ON tststats.priv_test_tbl TO regress_stats_user1; +-- Should now have direct table access, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak + a | b +---+--- +(0 rows) + +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak +-- Tidy up +DROP OPERATOR <<< (int, int); +DROP FUNCTION op_leak(int, int); +RESET SESSION AUTHORIZATION; +DROP SCHEMA tststats CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to table tststats.priv_test_tbl +drop cascades to view tststats.priv_test_view +DROP USER regress_stats_user1; diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index cbe66c375ca..24839665765 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -313,7 +313,7 @@ SELECT SUBSTRING('1234567890' FROM 4 FOR 3) = '456' AS "456"; t (1 row) --- T581 regular expression substring (with SQL99's bizarre regexp syntax) +-- T581 regular expression substring (with SQL's bizarre regexp syntax) SELECT SUBSTRING('abcdefg' FROM 'a#"(b_d)#"%' FOR '#') AS "bcd"; bcd ----- @@ -328,13 +328,13 @@ SELECT SUBSTRING('abcdefg' FROM '#"(b_d)#"%' FOR '#') IS NULL AS "True"; (1 row) -- Null inputs should return NULL -SELECT SUBSTRING('abcdefg' FROM '(b|c)' FOR NULL) IS NULL AS "True"; +SELECT SUBSTRING('abcdefg' FROM '%' FOR NULL) IS NULL AS "True"; True ------ t (1 row) -SELECT SUBSTRING(NULL FROM '(b|c)' FOR '#') IS NULL AS "True"; +SELECT SUBSTRING(NULL FROM '%' FOR '#') IS NULL AS "True"; True ------ t @@ -346,8 +346,57 @@ SELECT SUBSTRING('abcdefg' FROM NULL FOR '#') IS NULL AS "True"; t (1 row) --- PostgreSQL extension to allow omitting the escape character; --- here the regexp is taken as Posix syntax +-- The first and last parts should act non-greedy +SELECT SUBSTRING('abcdefg' FROM 'a#"%#"g' FOR '#') AS "bcdef"; + bcdef +------- + bcdef +(1 row) + +SELECT SUBSTRING('abcdefg' FROM 'a*#"%#"g*' FOR '#') AS "abcdefg"; + abcdefg +--------- + abcdefg +(1 row) + +-- Vertical bar in any part affects only that part +SELECT SUBSTRING('abcdefg' FROM 'a|b#"%#"g' FOR '#') AS "bcdef"; + bcdef +------- + bcdef +(1 row) + +SELECT SUBSTRING('abcdefg' FROM 'a#"%#"x|g' FOR '#') AS "bcdef"; + bcdef +------- + bcdef +(1 row) + +SELECT SUBSTRING('abcdefg' FROM 'a#"%|ab#"g' FOR '#') AS "bcdef"; + bcdef +------- + bcdef +(1 row) + +-- Can't have more than two part separators +SELECT SUBSTRING('abcdefg' FROM 'a*#"%#"g*#"x' FOR '#') AS "error"; +ERROR: SQL regular expression may not contain more than two escape-double-quote separators +CONTEXT: SQL function "substring" statement 1 +-- Postgres extension: with 0 or 1 separator, assume parts 1 and 3 are empty +SELECT SUBSTRING('abcdefg' FROM 'a#"%g' FOR '#') AS "bcdefg"; + bcdefg +-------- + bcdefg +(1 row) + +SELECT SUBSTRING('abcdefg' FROM 'a%g' FOR '#') AS "abcdefg"; + abcdefg +--------- + abcdefg +(1 row) + +-- substring() with just two arguments is not allowed by SQL spec; +-- we accept it, but we interpret the pattern as a POSIX regexp not SQL SELECT SUBSTRING('abcdefg' FROM 'c.e') AS "cde"; cde ----- @@ -361,7 +410,56 @@ SELECT SUBSTRING('abcdefg' FROM 'b(.*)f') AS "cde"; cde (1 row) --- PostgreSQL extension to allow using back reference in replace string; +-- Check behavior of SIMILAR TO, which uses largely the same regexp variant +SELECT 'abcdefg' SIMILAR TO '_bcd%' AS true; + true +------ + t +(1 row) + +SELECT 'abcdefg' SIMILAR TO 'bcd%' AS false; + false +------- + f +(1 row) + +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '#' AS false; + false +------- + f +(1 row) + +SELECT 'abcd%' SIMILAR TO '_bcd#%' ESCAPE '#' AS true; + true +------ + t +(1 row) + +-- Postgres uses '\' as the default escape character, which is not per spec +SELECT 'abcdefg' SIMILAR TO '_bcd\%' AS false; + false +------- + f +(1 row) + +-- and an empty string to mean "no escape", which is also not per spec +SELECT 'abcd\efg' SIMILAR TO '_bcd\%' ESCAPE '' AS true; + true +------ + t +(1 row) + +-- these behaviors are per spec, though: +SELECT 'abcdefg' SIMILAR TO '_bcd%' ESCAPE NULL AS null; + null +------ + +(1 row) + +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '##' AS error; +ERROR: invalid escape string +HINT: Escape string must be empty or one character. +-- Test back reference in regexp_replace SELECT regexp_replace('1112223333', E'(\\d{3})(\\d{3})(\\d{4})', E'(\\1) \\2-\\3'); regexp_replace ---------------- @@ -388,7 +486,7 @@ SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'gi'); -- invalid regexp option SELECT regexp_replace('AAA aaa', 'A+', 'Z', 'z'); -ERROR: invalid regexp option: "z" +ERROR: invalid regular expression option: "z" -- set so we can tell NULL from empty string \pset null '\\N' -- return all matches from regexp @@ -500,7 +598,7 @@ SELECT regexp_matches(chr(10) || '1' || chr(10) || '2' || chr(10) || '3' || chr( -- give me errors SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque)$re$, 'gz'); -ERROR: invalid regexp option: "z" +ERROR: invalid regular expression option: "z" SELECT regexp_matches('foobarbequebaz', $re$(barbeque$re$); ERROR: invalid regular expression: parentheses () not balanced SELECT regexp_matches('foobarbequebaz', $re$(bar)(beque){2,1}$re$); @@ -674,16 +772,34 @@ SELECT regexp_split_to_array('123456','.'); {"","","","","","",""} (1 row) +SELECT regexp_split_to_array('123456',''); + regexp_split_to_array +----------------------- + {1,2,3,4,5,6} +(1 row) + +SELECT regexp_split_to_array('123456','(?:)'); + regexp_split_to_array +----------------------- + {1,2,3,4,5,6} +(1 row) + +SELECT regexp_split_to_array('1',''); + regexp_split_to_array +----------------------- + {1} +(1 row) + -- errors SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'zippy') AS foo; -ERROR: invalid regexp option: "z" +ERROR: invalid regular expression option: "z" SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'iz'); -ERROR: invalid regexp option: "z" +ERROR: invalid regular expression option: "z" -- global option meaningless for regexp_split SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g') AS foo; -ERROR: regexp_split_to_table does not support the global option +ERROR: regexp_split_to_table() does not support the "global" option SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'g'); -ERROR: regexp_split_to_array does not support the global option +ERROR: regexp_split_to_array() does not support the "global" option -- change NULL-display back \pset null '' -- E021-11 position expression @@ -1083,6 +1199,22 @@ SELECT 'jack' LIKE '%____%' AS t; t (1 row) +-- +-- basic tests of LIKE with indexes +-- +CREATE TABLE texttest (a text PRIMARY KEY, b int); +SELECT * FROM texttest WHERE a LIKE '%1%'; + a | b +---+--- +(0 rows) + +CREATE TABLE byteatest (a bytea PRIMARY KEY, b int); +SELECT * FROM byteatest WHERE a LIKE '%1%'; + a | b +---+--- +(0 rows) + +DROP TABLE texttest, byteatest; -- -- test implicit type conversion -- @@ -1172,9 +1304,10 @@ INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); -- expect >0 blocks -select 0 = pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks; - blocks --------- +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + is_empty +---------- f (1 row) @@ -1185,9 +1318,10 @@ INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); -- expect 0 blocks -select 0 = pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks; - blocks --------- +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; + is_empty +---------- t (1 row) diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index 4fcbf7efe97..e7add9d2b81 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -6,31 +6,31 @@ CREATE ROLE regress_subscription_user2; CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - no publications -CREATE SUBSCRIPTION testsub CONNECTION 'foo'; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; ERROR: syntax error at or near ";" -LINE 1: CREATE SUBSCRIPTION testsub CONNECTION 'foo'; - ^ +LINE 1: CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; + ^ -- fail - no connection -CREATE SUBSCRIPTION testsub PUBLICATION foo; +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; ERROR: syntax error at or near "PUBLICATION" -LINE 1: CREATE SUBSCRIPTION testsub PUBLICATION foo; - ^ +LINE 1: CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; + ^ -- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block BEGIN; -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); ERROR: CREATE SUBSCRIPTION ... WITH (create_slot = true) cannot run inside a transaction block COMMIT; -- fail - invalid connection string -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub; ERROR: invalid connection string syntax: missing "=" after "testconn" in connection info string -- fail - duplicate publications -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); ERROR: publication name "foo" used more than once -- ok -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables -COMMENT ON SUBSCRIPTION testsub IS 'test subscription'; +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; obj_description ------------------- @@ -38,123 +38,123 @@ SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; (1 row) -- fail - name already exists -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); -ERROR: subscription "testsub" already exists +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); +ERROR: subscription "regress_testsub" already exists -- fail - must be superuser SET SESSION AUTHORIZATION 'regress_subscription_user2'; -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false); ERROR: must be superuser to create subscriptions SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - invalid option combinations -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); ERROR: connect = false and copy_data = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); ERROR: connect = false and enabled = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); ERROR: connect = false and create_slot = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); ERROR: slot_name = NONE and enabled = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true); ERROR: slot_name = NONE and create_slot = true are mutually exclusive options -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); ERROR: subscription with slot_name = NONE must also set enabled = false -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); ERROR: subscription with slot_name = NONE must also set create_slot = false -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false); ERROR: subscription with slot_name = NONE must also set enabled = false -- ok - with slot_name = NONE -CREATE SUBSCRIPTION testsub3 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); WARNING: tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables -- fail -ALTER SUBSCRIPTION testsub3 ENABLE; +ALTER SUBSCRIPTION regress_testsub3 ENABLE; ERROR: cannot enable subscription that does not have a slot name -ALTER SUBSCRIPTION testsub3 REFRESH PUBLICATION; +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; ERROR: ALTER SUBSCRIPTION ... REFRESH is not allowed for disabled subscriptions -DROP SUBSCRIPTION testsub3; +DROP SUBSCRIPTION regress_testsub3; -- fail - invalid connection string -ALTER SUBSCRIPTION testsub CONNECTION 'foobar'; +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; ERROR: invalid connection string syntax: missing "=" after "foobar" in connection info string \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo ----------+---------------------------+---------+-------------+--------------------+--------------------- - testsub | regress_subscription_user | f | {testpub} | off | dbname=doesnotexist + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +-----------------+---------------------------+---------+-------------+--------------------+----------------------------- + regress_testsub | regress_subscription_user | f | {testpub} | off | dbname=regress_doesnotexist (1 row) -ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); -ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (slot_name = 'newname'); +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); -- fail -ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2'; -ERROR: subscription "doesnotexist" does not exist -ALTER SUBSCRIPTION testsub SET (create_slot = false); -ERROR: unrecognized subscription parameter: create_slot +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; +ERROR: subscription "regress_doesnotexist" does not exist +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); +ERROR: unrecognized subscription parameter: "create_slot" \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo ----------+---------------------------+---------+---------------------+--------------------+---------------------- - testsub | regress_subscription_user | f | {testpub2,testpub3} | off | dbname=doesnotexist2 + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +-----------------+---------------------------+---------+---------------------+--------------------+------------------------------ + regress_testsub | regress_subscription_user | f | {testpub2,testpub3} | off | dbname=regress_doesnotexist2 (1 row) BEGIN; -ALTER SUBSCRIPTION testsub ENABLE; +ALTER SUBSCRIPTION regress_testsub ENABLE; \dRs - List of subscriptions - Name | Owner | Enabled | Publication ----------+---------------------------+---------+--------------------- - testsub | regress_subscription_user | t | {testpub2,testpub3} + List of subscriptions + Name | Owner | Enabled | Publication +-----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | t | {testpub2,testpub3} (1 row) -ALTER SUBSCRIPTION testsub DISABLE; +ALTER SUBSCRIPTION regress_testsub DISABLE; \dRs - List of subscriptions - Name | Owner | Enabled | Publication ----------+---------------------------+---------+--------------------- - testsub | regress_subscription_user | f | {testpub2,testpub3} + List of subscriptions + Name | Owner | Enabled | Publication +-----------------+---------------------------+---------+--------------------- + regress_testsub | regress_subscription_user | f | {testpub2,testpub3} (1 row) COMMIT; -- fail - must be owner of subscription SET ROLE regress_subscription_user_dummy; -ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy; -ERROR: must be owner of subscription testsub +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy; +ERROR: must be owner of subscription regress_testsub RESET ROLE; -ALTER SUBSCRIPTION testsub RENAME TO testsub_foo; -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local); -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar); +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo; +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar); ERROR: invalid value for parameter "synchronous_commit": "foobar" HINT: Available values: local, remote_write, remote_apply, on, off. \dRs+ - List of subscriptions - Name | Owner | Enabled | Publication | Synchronous commit | Conninfo --------------+---------------------------+---------+---------------------+--------------------+---------------------- - testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | local | dbname=doesnotexist2 + List of subscriptions + Name | Owner | Enabled | Publication | Synchronous commit | Conninfo +---------------------+---------------------------+---------+---------------------+--------------------+------------------------------ + regress_testsub_foo | regress_subscription_user | f | {testpub2,testpub3} | local | dbname=regress_doesnotexist2 (1 row) -- rename back to keep the rest simple -ALTER SUBSCRIPTION testsub_foo RENAME TO testsub; +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; -- fail - new owner must be superuser -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; -ERROR: permission denied to change owner of subscription "testsub" +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; +ERROR: permission denied to change owner of subscription "regress_testsub" HINT: The owner of a subscription must be a superuser. ALTER ROLE regress_subscription_user2 SUPERUSER; -- now it works -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; -- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; ERROR: DROP SUBSCRIPTION cannot run inside a transaction block COMMIT; -ALTER SUBSCRIPTION testsub SET (slot_name = NONE); +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); -- now it works BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -DROP SUBSCRIPTION IF EXISTS testsub; -NOTICE: subscription "testsub" does not exist, skipping -DROP SUBSCRIPTION testsub; -- fail -ERROR: subscription "testsub" does not exist +DROP SUBSCRIPTION IF EXISTS regress_testsub; +NOTICE: subscription "regress_testsub" does not exist, skipping +DROP SUBSCRIPTION regress_testsub; -- fail +ERROR: subscription "regress_testsub" does not exist RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user; DROP ROLE regress_subscription_user2; diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out index 2904ae43e55..ee9c5db0d51 100644 --- a/src/test/regress/expected/subselect.out +++ b/src/test/regress/expected/subselect.out @@ -745,6 +745,49 @@ select * from outer_7597 where (f1, f2) not in (select * from inner_7597); 1 | (2 rows) +-- +-- Similar test case using text that verifies that collation +-- information is passed through by execTuplesEqual() in nodeSubplan.c +-- (otherwise it would error in texteq()) +-- +create temp table outer_text (f1 text, f2 text); +insert into outer_text values ('a', 'a'); +insert into outer_text values ('b', 'a'); +insert into outer_text values ('a', null); +insert into outer_text values ('b', null); +create temp table inner_text (c1 text, c2 text); +insert into inner_text values ('a', null); +select * from outer_text where (f1, f2) not in (select * from inner_text); + f1 | f2 +----+---- + b | a + b | +(2 rows) + +-- +-- Another test case for cross-type hashed subplans: comparison of +-- inner-side values must be done with appropriate operator +-- +explain (verbose, costs off) +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + QUERY PLAN +------------------------------------- + Result + Output: (hashed SubPlan 1) + SubPlan 1 + -> Append + -> Result + Output: 'bar'::name + -> Result + Output: 'bar'::name +(8 rows) + +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + ?column? +---------- + f +(1 row) + -- -- Test case for premature memory release during hashing of subplan output -- @@ -830,6 +873,19 @@ explain (verbose, costs off) One-Time Filter: ("*VALUES*".column1 = "*VALUES*".column1) (8 rows) +-- +-- Check we don't misoptimize a NOT IN where the subquery returns no rows. +-- +create temp table notinouter (a int); +create temp table notininner (b int not null); +insert into notinouter values (null), (1); +select * from notinouter where a not in (select b from notininner); + a +--- + + 1 +(2 rows) + -- -- Check we behave sanely in corner case of empty SELECT list (bug #8648) -- @@ -904,7 +960,7 @@ select * from int4_tbl where -- explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in - (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); QUERY PLAN ------------------------------------------------------------------- Nested Loop Semi Join @@ -918,9 +974,9 @@ select * from int4_tbl o where (f1, f1) in Output: "ANY_subquery".f1, "ANY_subquery".g Filter: ("ANY_subquery".f1 = "ANY_subquery".g) -> Result - Output: i.f1, ((generate_series(1, 2)) / 10) + Output: i.f1, ((generate_series(1, 50)) / 10) -> ProjectSet - Output: generate_series(1, 2), i.f1 + Output: generate_series(1, 50), i.f1 -> HashAggregate Output: i.f1 Group Key: i.f1 @@ -929,7 +985,7 @@ select * from int4_tbl o where (f1, f1) in (19 rows) select * from int4_tbl o where (f1, f1) in - (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); f1 ---- 0 @@ -999,7 +1055,7 @@ select * from QUERY PLAN ---------------------------------------------------------- Subquery Scan on ss - Output: x, u + Output: ss.x, ss.u Filter: tattle(ss.x, 8) -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) @@ -1061,7 +1117,7 @@ select * from QUERY PLAN ---------------------------------------------------------- Subquery Scan on ss - Output: x, u + Output: ss.x, ss.u Filter: tattle(ss.x, ss.u) -> ProjectSet Output: 9, unnest('{1,2,3,11,12,13}'::integer[]) @@ -1137,3 +1193,276 @@ select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3; drop function explain_sq_limit(); drop table sq_limit; +-- +-- Ensure that backward scan direction isn't propagated into +-- expression subqueries (bug #15336) +-- +begin; +declare c1 scroll cursor for + select * from generate_series(1,4) i + where i <> all (values (2),(3)); +move forward all in c1; +fetch backward all in c1; + i +--- + 4 + 1 +(2 rows) + +commit; +-- +-- Tests for CTE inlining behavior +-- +-- Basic subquery that can be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1; + QUERY PLAN +---------------------------------- + Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1 + Filter: (subselect_tbl.f1 = 1) +(3 rows) + +-- Explicitly request materialization +explain (verbose, costs off) +with x as materialized (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1; + QUERY PLAN +------------------------------------------ + CTE Scan on x + Output: x.f1 + Filter: (x.f1 = 1) + CTE x + -> Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1 +(6 rows) + +-- Stable functions are safe to inline +explain (verbose, costs off) +with x as (select * from (select f1, now() from subselect_tbl) ss) +select * from x where f1 = 1; + QUERY PLAN +----------------------------------- + Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, now() + Filter: (subselect_tbl.f1 = 1) +(3 rows) + +-- Volatile functions prevent inlining +explain (verbose, costs off) +with x as (select * from (select f1, random() from subselect_tbl) ss) +select * from x where f1 = 1; + QUERY PLAN +---------------------------------------------- + CTE Scan on x + Output: x.f1, x.random + Filter: (x.f1 = 1) + CTE x + -> Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, random() +(6 rows) + +-- SELECT FOR UPDATE cannot be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl for update) ss) +select * from x where f1 = 1; + QUERY PLAN +-------------------------------------------------------------------- + CTE Scan on x + Output: x.f1 + Filter: (x.f1 = 1) + CTE x + -> Subquery Scan on ss + Output: ss.f1 + -> LockRows + Output: subselect_tbl.f1, subselect_tbl.ctid + -> Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, subselect_tbl.ctid +(10 rows) + +-- Multiply-referenced CTEs are inlined only when requested +explain (verbose, costs off) +with x as (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n; + QUERY PLAN +------------------------------------------- + Merge Join + Output: x.f1, x.n, x2.f1, x2.n + Merge Cond: (x.n = x2.n) + CTE x + -> Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, now() + -> Sort + Output: x.f1, x.n + Sort Key: x.n + -> CTE Scan on x + Output: x.f1, x.n + -> Sort + Output: x2.f1, x2.n + Sort Key: x2.n + -> CTE Scan on x x2 + Output: x2.f1, x2.n +(16 rows) + +explain (verbose, costs off) +with x as not materialized (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n; + QUERY PLAN +---------------------------------------------------------------------------- + Result + Output: subselect_tbl.f1, now(), subselect_tbl_1.f1, now() + One-Time Filter: (now() = now()) + -> Nested Loop + Output: subselect_tbl.f1, subselect_tbl_1.f1 + -> Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 + -> Materialize + Output: subselect_tbl_1.f1 + -> Seq Scan on public.subselect_tbl subselect_tbl_1 + Output: subselect_tbl_1.f1 +(11 rows) + +-- Multiply-referenced CTEs can't be inlined if they contain outer self-refs +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x; + QUERY PLAN +---------------------------------------------------------- + CTE Scan on x + Output: x.a + CTE x + -> Recursive Union + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 + -> Nested Loop + Output: (z.a || z1.a) + Join Filter: (length((z.a || z1.a)) < 5) + CTE z + -> WorkTable Scan on x x_1 + Output: x_1.a + -> CTE Scan on z + Output: z.a + -> CTE Scan on z z1 + Output: z1.a +(16 rows) + +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x; + a +------ + a + b + aa + ab + ba + bb + aaaa + aaab + aaba + aabb + abaa + abab + abba + abbb + baaa + baab + baba + babb + bbaa + bbab + bbba + bbbb +(22 rows) + +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x; + QUERY PLAN +-------------------------------------------------------- + CTE Scan on x + Output: x.a + CTE x + -> Recursive Union + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 + -> WorkTable Scan on x x_1 + Output: (x_1.a || x_1.a) + Filter: (length((x_1.a || x_1.a)) < 5) +(9 rows) + +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x; + a +------ + a + b + aa + bb + aaaa + bbbb +(6 rows) + +-- Check handling of outer references +explain (verbose, costs off) +with x as (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss; + QUERY PLAN +----------------------------- + Seq Scan on public.int4_tbl + Output: int4_tbl.f1 +(2 rows) + +explain (verbose, costs off) +with x as materialized (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss; + QUERY PLAN +------------------------------------- + CTE Scan on x + Output: x.f1 + CTE x + -> Seq Scan on public.int4_tbl + Output: int4_tbl.f1 +(5 rows) + +-- Ensure that we inline the currect CTE when there are +-- multiple CTEs with the same name +explain (verbose, costs off) +with x as (select 1 as y) +select * from (with x as (select 2 as y) select * from x) ss; + QUERY PLAN +------------- + Result + Output: 2 +(2 rows) + +-- Row marks are not pushed into CTEs +explain (verbose, costs off) +with x as (select * from subselect_tbl) +select * from x for update; + QUERY PLAN +---------------------------------------------------------------- + Seq Scan on public.subselect_tbl + Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3 +(2 rows) + diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out index a19ee08749b..a1c90eb9057 100644 --- a/src/test/regress/expected/sysviews.out +++ b/src/test/regress/expected/sysviews.out @@ -83,12 +83,13 @@ select name, setting from pg_settings where name like 'enable%'; enable_nestloop | on enable_parallel_append | on enable_parallel_hash | on + enable_partition_pruning | on enable_partitionwise_aggregate | off enable_partitionwise_join | off enable_seqscan | on enable_sort | on enable_tidscan | on -(16 rows) +(17 rows) -- Test that the pg_timezone_names and pg_timezone_abbrevs views are -- more-or-less working. We can't test their contents in any great detail diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out index addf1ec4443..b1d2ffdef3d 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -199,3 +199,192 @@ select pg_temp.whoami(); (1 row) drop table public.whereami; +-- types in temp schema +set search_path = pg_temp, public; +create domain pg_temp.nonempty as text check (value <> ''); +-- function-syntax invocation of types matches rules for functions +select nonempty(''); +ERROR: function nonempty(unknown) does not exist +LINE 1: select nonempty(''); + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +select pg_temp.nonempty(''); +ERROR: value for domain nonempty violates check constraint "nonempty_check" +-- other syntax matches rules for tables +select ''::nonempty; +ERROR: value for domain nonempty violates check constraint "nonempty_check" +reset search_path; +-- For partitioned temp tables, ON COMMIT actions ignore storage-less +-- partitioned tables. +begin; +create temp table temp_parted_oncommit (a int) + partition by list (a) on commit delete rows; +create temp table temp_parted_oncommit_1 + partition of temp_parted_oncommit + for values in (1) on commit delete rows; +insert into temp_parted_oncommit values (1); +commit; +-- partitions are emptied by the previous commit +select * from temp_parted_oncommit; + a +--- +(0 rows) + +drop table temp_parted_oncommit; +-- Check dependencies between ON COMMIT actions with a partitioned +-- table and its partitions. Using ON COMMIT DROP on a parent removes +-- the whole set. +begin; +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit drop; +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit delete rows; +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; +insert into temp_parted_oncommit_test values (1), (2); +commit; +-- no relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test'; + relname +--------- +(0 rows) + +-- Using ON COMMIT DELETE on a partitioned table does not remove +-- all rows if partitions preserve their data. +begin; +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit delete rows; +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit preserve rows; +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; +insert into temp_parted_oncommit_test values (1), (2); +commit; +-- Data from the remaining partition is still here as its rows are +-- preserved. +select * from temp_parted_oncommit_test; + a +--- + 1 +(1 row) + +-- two relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' + order by relname; + relname +---------------------------- + temp_parted_oncommit_test + temp_parted_oncommit_test1 +(2 rows) + +drop table temp_parted_oncommit_test; +-- Check dependencies between ON COMMIT actions with inheritance trees. +-- Using ON COMMIT DROP on a parent removes the whole set. +begin; +create temp table temp_inh_oncommit_test (a int) on commit drop; +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit delete rows; +insert into temp_inh_oncommit_test1 values (1); +commit; +-- no relations remain in this case +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; + relname +--------- +(0 rows) + +-- Data on the parent is removed, and the child goes away. +begin; +create temp table temp_inh_oncommit_test (a int) on commit delete rows; +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit drop; +insert into temp_inh_oncommit_test1 values (1); +insert into temp_inh_oncommit_test values (1); +commit; +select * from temp_inh_oncommit_test; + a +--- +(0 rows) + +-- one relation remains +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; + relname +------------------------ + temp_inh_oncommit_test +(1 row) + +drop table temp_inh_oncommit_test; +-- Tests with two-phase commit +-- Transactions creating objects in a temporary namespace cannot be used +-- with two-phase commit. +-- These cases generate errors about temporary namespace. +-- Function creation +begin; +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; +prepare transaction 'twophase_func'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- Function drop +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; +begin; +drop function pg_temp.twophase_func(); +prepare transaction 'twophase_func'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- Operator creation +begin; +create operator pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi); +prepare transaction 'twophase_operator'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- These generate errors about temporary tables. +begin; +create type pg_temp.twophase_type as (a int); +prepare transaction 'twophase_type'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +begin; +create view pg_temp.twophase_view as select 1; +prepare transaction 'twophase_view'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +begin; +create sequence pg_temp.twophase_seq; +prepare transaction 'twophase_sequence'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- Temporary tables cannot be used with two-phase commit. +create temp table twophase_tab (a int); +begin; +select a from twophase_tab; + a +--- +(0 rows) + +prepare transaction 'twophase_tab'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +begin; +insert into twophase_tab values (1); +prepare transaction 'twophase_tab'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +begin; +lock twophase_tab in access exclusive mode; +prepare transaction 'twophase_tab'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +begin; +drop table twophase_tab; +prepare transaction 'twophase_tab'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects +-- Corner case: current_schema may create a temporary schema if namespace +-- creation is pending, so check after that. First reset the connection +-- to remove the temporary namespace. +\c - +SET search_path TO 'pg_temp'; +BEGIN; +SELECT current_schema() ~ 'pg_temp' AS is_temp_schema; + is_temp_schema +---------------- + t +(1 row) + +PREPARE TRANSACTION 'twophase_search'; +ERROR: cannot PREPARE a transaction that has operated on temporary objects diff --git a/src/test/regress/expected/tidscan.out b/src/test/regress/expected/tidscan.out index 521ed1b2f99..9b5eb04bfd9 100644 --- a/src/test/regress/expected/tidscan.out +++ b/src/test/regress/expected/tidscan.out @@ -40,6 +40,22 @@ SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; (0,1) | 1 (1 row) +-- OR'd clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + QUERY PLAN +-------------------------------------------------------------- + Tid Scan on tidscan + TID Cond: ((ctid = '(0,2)'::tid) OR ('(0,1)'::tid = ctid)) +(2 rows) + +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + ctid | id +-------+---- + (0,1) | 1 + (0,2) | 2 +(2 rows) + -- ctid = ScalarArrayOp - implemented as tidscan EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); @@ -92,6 +108,47 @@ WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); (0,3) | 3 (2 rows) +-- nestloop-with-inner-tidscan joins on tid +SET enable_hashjoin TO off; -- otherwise hash join might win +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + QUERY PLAN +------------------------------------ + Nested Loop + -> Seq Scan on tidscan t1 + Filter: (id = 1) + -> Tid Scan on tidscan t2 + TID Cond: (ctid = t1.ctid) +(5 rows) + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + ctid | id | ctid | id +-------+----+-------+---- + (0,1) | 1 | (0,1) | 1 +(1 row) + +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Seq Scan on tidscan t1 + Filter: (id = 1) + -> Tid Scan on tidscan t2 + TID Cond: (t1.ctid = ctid) +(5 rows) + +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; + ctid | id | ctid | id +-------+----+-------+---- + (0,1) | 1 | (0,1) | 1 +(1 row) + +RESET enable_hashjoin; -- exercise backward scan and rewind BEGIN; DECLARE c CURSOR FOR @@ -176,4 +233,48 @@ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; ERROR: cursor "c" is not positioned on a row ROLLBACK; +-- bulk joins on CTID +-- (these plans don't use TID scans, but this still seems like an +-- appropriate place for these tests) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + QUERY PLAN +---------------------------------------- + Aggregate + -> Hash Join + Hash Cond: (t1.ctid = t2.ctid) + -> Seq Scan on tenk1 t1 + -> Hash + -> Seq Scan on tenk1 t2 +(6 rows) + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + count +------- + 10000 +(1 row) + +SET enable_hashjoin TO off; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + QUERY PLAN +----------------------------------------- + Aggregate + -> Merge Join + Merge Cond: (t1.ctid = t2.ctid) + -> Sort + Sort Key: t1.ctid + -> Seq Scan on tenk1 t1 + -> Sort + Sort Key: t2.ctid + -> Seq Scan on tenk1 t2 +(9 rows) + +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; + count +------- + 10000 +(1 row) + +RESET enable_hashjoin; DROP TABLE tidscan; diff --git a/src/test/regress/expected/timestamp.out b/src/test/regress/expected/timestamp.out index 4a2fabddd9f..f772b07d5a4 100644 --- a/src/test/regress/expected/timestamp.out +++ b/src/test/regress/expected/timestamp.out @@ -74,24 +74,11 @@ SELECT count(*) AS two FROM TIMESTAMP_TBL WHERE d1 = timestamp(2) without time z (1 row) COMMIT; -DELETE FROM TIMESTAMP_TBL; +TRUNCATE TIMESTAMP_TBL; -- Special values INSERT INTO TIMESTAMP_TBL VALUES ('-infinity'); INSERT INTO TIMESTAMP_TBL VALUES ('infinity'); INSERT INTO TIMESTAMP_TBL VALUES ('epoch'); --- Obsolete special values -INSERT INTO TIMESTAMP_TBL VALUES ('invalid'); -ERROR: date/time value "invalid" is no longer supported -LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('invalid'); - ^ -INSERT INTO TIMESTAMP_TBL VALUES ('undefined'); -ERROR: date/time value "undefined" is no longer supported -LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('undefined'); - ^ -INSERT INTO TIMESTAMP_TBL VALUES ('current'); -ERROR: date/time value "current" is no longer supported -LINE 1: INSERT INTO TIMESTAMP_TBL VALUES ('current'); - ^ -- Postgres v6.0 standard output format INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); -- Variations on Postgres v6.1 standard output format @@ -1597,6 +1584,21 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') | 2001 1 1 1 1 1 1 (65 rows) +SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamp), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + to_char_12 | to_char +------------+-------------------------------------------------------------------- + | 0 00 000 0000 00000 000000 0 00 000 0000 00000 000000 000 000000 + | 7 78 780 7800 78000 780000 7 78 780 7800 78000 780000 780 780000 + | 7 78 789 7890 78901 789010 7 78 789 7890 78901 789010 789 789010 + | 7 78 789 7890 78901 789012 7 78 789 7890 78901 789012 789 789012 +(4 rows) + -- timestamp numeric fields constructor SELECT make_timestamp(2014,12,28,6,30,45.887); make_timestamp diff --git a/src/test/regress/expected/timestamptz.out b/src/test/regress/expected/timestamptz.out index a901fd909d3..2d6a71ca64b 100644 --- a/src/test/regress/expected/timestamptz.out +++ b/src/test/regress/expected/timestamptz.out @@ -78,19 +78,6 @@ DELETE FROM TIMESTAMPTZ_TBL; INSERT INTO TIMESTAMPTZ_TBL VALUES ('-infinity'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch'); --- Obsolete special values -INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid'); -ERROR: date/time value "invalid" is no longer supported -LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid'); - ^ -INSERT INTO TIMESTAMPTZ_TBL VALUES ('undefined'); -ERROR: date/time value "undefined" is no longer supported -LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('undefined'); - ^ -INSERT INTO TIMESTAMPTZ_TBL VALUES ('current'); -ERROR: date/time value "current" is no longer supported -LINE 1: INSERT INTO TIMESTAMPTZ_TBL VALUES ('current'); - ^ -- Postgres v6.0 standard output format INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); -- Variations on Postgres v6.1 standard output format @@ -649,6 +636,24 @@ SELECT '' AS date_trunc_week, date_trunc( 'week', timestamp with time zone '2004 | Mon Feb 23 00:00:00 2004 PST (1 row) +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'Australia/Sydney') as sydney_trunc; -- zone name + date_trunc_at_tz | sydney_trunc +------------------+------------------------------ + | Fri Feb 16 05:00:00 2001 PST +(1 row) + +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'GMT') as gmt_trunc; -- fixed-offset abbreviation + date_trunc_at_tz | gmt_trunc +------------------+------------------------------ + | Thu Feb 15 16:00:00 2001 PST +(1 row) + +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'VET') as vet_trunc; -- variable-offset abbreviation + date_trunc_at_tz | vet_trunc +------------------+------------------------------ + | Thu Feb 15 20:00:00 2001 PST +(1 row) + -- Test casting within a BETWEEN qualifier SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff FROM TIMESTAMPTZ_TBL @@ -1699,6 +1704,21 @@ SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') | 2001 1 1 1 1 1 1 (66 rows) +SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamptz), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + to_char_12 | to_char +------------+-------------------------------------------------------------------- + | 0 00 000 0000 00000 000000 0 00 000 0000 00000 000000 000 000000 + | 7 78 780 7800 78000 780000 7 78 780 7800 78000 780000 780 780000 + | 7 78 789 7890 78901 789010 7 78 789 7890 78901 789010 789 789010 + | 7 78 789 7890 78901 789012 7 78 789 7890 78901 789012 789 789012 +(4 rows) + -- Check OF, TZH, TZM with various zone offsets, particularly fractional hours SET timezone = '00:00'; SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; @@ -1834,7 +1854,7 @@ WITH tzs (tz) AS (VALUES -- these should fail SELECT make_timestamptz(1973, 07, 15, 08, 15, 55.33, '2'); -ERROR: invalid input syntax for numeric time zone: "2" +ERROR: invalid input syntax for type numeric time zone: "2" HINT: Numeric time zones must have "-" or "+" as first character. SELECT make_timestamptz(2014, 12, 10, 10, 10, 10, '+16'); ERROR: numeric time zone "+16" out of range diff --git a/src/test/regress/expected/timetz.out b/src/test/regress/expected/timetz.out index 33ff8e18c9d..482a3463b3c 100644 --- a/src/test/regress/expected/timetz.out +++ b/src/test/regress/expected/timetz.out @@ -19,6 +19,16 @@ INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York'); ERROR: invalid input syntax for type time with time zone: "15:36:39 America/New_York" LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York'); ^ +-- this should fail (timezone not specified without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2'); +ERROR: invalid input syntax for type time with time zone: "15:36:39 m2" +LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2'); + ^ +-- this should fail (dynamic timezone abbreviation without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2'); +ERROR: invalid input syntax for type time with time zone: "15:36:39 MSK m2" +LINE 1: INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2'); + ^ SELECT f1 AS "Time TZ" FROM TIMETZ_TBL; Time TZ ---------------- diff --git a/src/test/regress/expected/tinterval.out b/src/test/regress/expected/tinterval.out deleted file mode 100644 index a0189729fc3..00000000000 --- a/src/test/regress/expected/tinterval.out +++ /dev/null @@ -1,172 +0,0 @@ --- --- TINTERVAL --- -CREATE TABLE TINTERVAL_TBL (f1 tinterval); --- Should accept any abstime, --- so do not bother with extensive testing of values -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["-infinity" "infinity"]'); -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["May 10, 1947 23:59:12" "Jan 14, 1973 03:14:21"]'); -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["Sep 4, 1983 23:59:12" "Oct 4, 1983 23:59:12"]'); -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["epoch" "Mon May 1 00:30:30 1995"]'); -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["Feb 15 1990 12:15:03" "2001-09-23 11:12:13"]'); --- badly formatted tintervals -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["bad time specifications" ""]'); -ERROR: invalid input syntax for type abstime: "bad time specifications" -LINE 2: VALUES ('["bad time specifications" ""]'); - ^ -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["" "infinity"]'); -ERROR: invalid input syntax for type abstime: "" -LINE 2: VALUES ('["" "infinity"]'); - ^ --- test tinterval operators -SELECT '' AS five, * FROM TINTERVAL_TBL; - five | f1 -------+----------------------------------------------------------------- - | ["-infinity" "infinity"] - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] -(5 rows) - --- length == -SELECT '' AS one, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #= '@ 1 months'; - one | f1 ------+----------------------------------------------------------------- - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] -(1 row) - --- length <> -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #<> '@ 1 months'; - three | f1 --------+----------------------------------------------------------------- - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] -(3 rows) - --- length < -SELECT '' AS zero, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #< '@ 1 month'; - zero | f1 -------+---- -(0 rows) - --- length <= -SELECT '' AS one, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #<= '@ 1 month'; - one | f1 ------+----------------------------------------------------------------- - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] -(1 row) - --- length > -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #> '@ 1 year'; - three | f1 --------+----------------------------------------------------------------- - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] -(3 rows) - --- length >= -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #>= '@ 3 years'; - three | f1 --------+----------------------------------------------------------------- - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] -(3 rows) - --- overlaps -SELECT '' AS three, t1.* - FROM TINTERVAL_TBL t1 - WHERE t1.f1 && - tinterval '["Aug 15 14:23:19 1983" "Sep 16 14:23:19 1983"]'; - three | f1 --------+----------------------------------------------------------------- - | ["-infinity" "infinity"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] -(3 rows) - -SELECT '' AS five, t1.f1, t2.f1 - FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2 - WHERE t1.f1 && t2.f1 and - t1.f1 = t2.f1 - ORDER BY t1.f1, t2.f1; - five | f1 | f1 -------+-----------------------------------------------------------------+----------------------------------------------------------------- - | ["-infinity" "infinity"] | ["-infinity" "infinity"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] -(5 rows) - -SELECT '' AS fourteen, t1.f1 AS interval1, t2.f1 AS interval2 - FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2 - WHERE t1.f1 && t2.f1 and not t1.f1 = t2.f1 - ORDER BY interval1, interval2; - fourteen | interval1 | interval2 -----------+-----------------------------------------------------------------+----------------------------------------------------------------- - | ["-infinity" "infinity"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["-infinity" "infinity"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] - | ["-infinity" "infinity"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["-infinity" "infinity"] | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["-infinity" "infinity"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["-infinity" "infinity"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["-infinity" "infinity"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] | ["-infinity" "infinity"] - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] -(14 rows) - --- contains -SELECT '' AS five, t1.f1 - FROM TINTERVAL_TBL t1 - WHERE not t1.f1 << - tinterval '["Aug 15 14:23:19 1980" "Sep 16 14:23:19 1990"]' - ORDER BY t1.f1; - five | f1 -------+----------------------------------------------------------------- - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Thu Feb 15 12:15:03 1990 PST" "Sun Sep 23 11:12:13 2001 PDT"] - | ["Sat May 10 23:59:12 1947 PST" "Sun Jan 14 03:14:21 1973 PST"] -(3 rows) - --- make time interval -SELECT '' AS three, t1.f1 - FROM TINTERVAL_TBL t1 - WHERE t1.f1 && - (abstime 'Aug 15 14:23:19 1983' <#> - abstime 'Sep 16 14:23:19 1983') - ORDER BY t1.f1; - three | f1 --------+----------------------------------------------------------------- - | ["-infinity" "infinity"] - | ["Sun Sep 04 23:59:12 1983 PDT" "Tue Oct 04 23:59:12 1983 PDT"] - | ["Wed Dec 31 16:00:00 1969 PST" "Mon May 01 00:30:30 1995 PDT"] -(3 rows) - diff --git a/src/test/regress/expected/transactions.out b/src/test/regress/expected/transactions.out index 69e176c5259..1b033100298 100644 --- a/src/test/regress/expected/transactions.out +++ b/src/test/regress/expected/transactions.out @@ -659,6 +659,202 @@ ERROR: portal "ctt" cannot be run COMMIT; DROP FUNCTION create_temp_tab(); DROP FUNCTION invert(x float8); +-- Tests for AND CHAIN +CREATE TABLE abc (a int); +-- set nondefault value so we have something to override below +SET default_transaction_read_only = on; +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; +SHOW transaction_isolation; + transaction_isolation +----------------------- + repeatable read +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + on +(1 row) + +INSERT INTO abc VALUES (1); +INSERT INTO abc VALUES (2); +COMMIT AND CHAIN; -- TBLOCK_END +SHOW transaction_isolation; + transaction_isolation +----------------------- + repeatable read +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + on +(1 row) + +INSERT INTO abc VALUES ('error'); +ERROR: invalid input syntax for type integer: "error" +LINE 1: INSERT INTO abc VALUES ('error'); + ^ +INSERT INTO abc VALUES (3); -- check it's really aborted +ERROR: current transaction is aborted, commands ignored until end of transaction block +COMMIT AND CHAIN; -- TBLOCK_ABORT_END +SHOW transaction_isolation; + transaction_isolation +----------------------- + repeatable read +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + on +(1 row) + +INSERT INTO abc VALUES (4); +COMMIT; +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; +SHOW transaction_isolation; + transaction_isolation +----------------------- + repeatable read +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + on +(1 row) + +SAVEPOINT x; +INSERT INTO abc VALUES ('error'); +ERROR: invalid input syntax for type integer: "error" +LINE 1: INSERT INTO abc VALUES ('error'); + ^ +COMMIT AND CHAIN; -- TBLOCK_ABORT_PENDING +SHOW transaction_isolation; + transaction_isolation +----------------------- + repeatable read +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + on +(1 row) + +INSERT INTO abc VALUES (5); +COMMIT; +-- different mix of options just for fun +START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE; +SHOW transaction_isolation; + transaction_isolation +----------------------- + serializable +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + off +(1 row) + +INSERT INTO abc VALUES (6); +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +SHOW transaction_isolation; + transaction_isolation +----------------------- + serializable +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + off +(1 row) + +INSERT INTO abc VALUES ('error'); +ERROR: invalid input syntax for type integer: "error" +LINE 1: INSERT INTO abc VALUES ('error'); + ^ +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_END +SHOW transaction_isolation; + transaction_isolation +----------------------- + serializable +(1 row) + +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SHOW transaction_deferrable; + transaction_deferrable +------------------------ + off +(1 row) + +ROLLBACK; +-- not allowed outside a transaction block +COMMIT AND CHAIN; -- error +ERROR: COMMIT AND CHAIN can only be used in transaction blocks +ROLLBACK AND CHAIN; -- error +ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks +SELECT * FROM abc ORDER BY 1; + a +--- + 1 + 2 + 4 + 5 +(4 rows) + +RESET default_transaction_read_only; +DROP TABLE abc; -- Test assorted behaviors around the implicit transaction block created -- when multiple SQL commands are sent in a single Query message. These -- tests rely on the fact that psql will not break SQL commands apart at a @@ -743,6 +939,79 @@ SELECT 2\; RELEASE SAVEPOINT sp\; SELECT 3; ERROR: RELEASE SAVEPOINT can only be used in transaction blocks -- but this is OK, because the BEGIN converts it to a regular xact SELECT 1\; BEGIN\; SAVEPOINT sp\; ROLLBACK TO SAVEPOINT sp\; COMMIT; +-- Tests for AND CHAIN in implicit transaction blocks +SET TRANSACTION READ ONLY\; COMMIT AND CHAIN; -- error +ERROR: COMMIT AND CHAIN can only be used in transaction blocks +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +SET TRANSACTION READ ONLY\; ROLLBACK AND CHAIN; -- error +ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks +SHOW transaction_read_only; + transaction_read_only +----------------------- + off +(1 row) + +CREATE TABLE abc (a int); +-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +INSERT INTO abc VALUES (7)\; COMMIT\; INSERT INTO abc VALUES (8)\; COMMIT AND CHAIN; -- 7 commit, 8 error +WARNING: there is no transaction in progress +ERROR: COMMIT AND CHAIN can only be used in transaction blocks +INSERT INTO abc VALUES (9)\; ROLLBACK\; INSERT INTO abc VALUES (10)\; ROLLBACK AND CHAIN; -- 9 rollback, 10 error +WARNING: there is no transaction in progress +ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks +-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK +INSERT INTO abc VALUES (11)\; COMMIT AND CHAIN\; INSERT INTO abc VALUES (12)\; COMMIT; -- 11 error, 12 not reached +ERROR: COMMIT AND CHAIN can only be used in transaction blocks +INSERT INTO abc VALUES (13)\; ROLLBACK AND CHAIN\; INSERT INTO abc VALUES (14)\; ROLLBACK; -- 13 error, 14 not reached +ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks +-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (15)\; COMMIT AND CHAIN; -- 15 ok +SHOW transaction_isolation; -- transaction is active at this point + transaction_isolation +----------------------- + repeatable read +(1 row) + +COMMIT; +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok +SHOW transaction_isolation; -- transaction is active at this point + transaction_isolation +----------------------- + repeatable read +(1 row) + +ROLLBACK; +-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error +ERROR: COMMIT AND CHAIN can only be used in transaction blocks +SHOW transaction_isolation; -- out of transaction block + transaction_isolation +----------------------- + read committed +(1 row) + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (19)\; ROLLBACK\; INSERT INTO abc VALUES (20)\; ROLLBACK AND CHAIN; -- 19 rollback, 20 error +ERROR: ROLLBACK AND CHAIN can only be used in transaction blocks +SHOW transaction_isolation; -- out of transaction block + transaction_isolation +----------------------- + read committed +(1 row) + +SELECT * FROM abc ORDER BY 1; + a +---- + 7 + 15 + 17 +(3 rows) + +DROP TABLE abc; -- Test for successful cleanup of an aborted transaction at session exit. -- THIS MUST BE THE LAST TEST IN THIS FILE. begin; diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out index a29b7b1d08d..1e4053ceed9 100644 --- a/src/test/regress/expected/triggers.out +++ b/src/test/regress/expected/triggers.out @@ -22,12 +22,12 @@ create unique index pkeys_i on pkeys (pkey1, pkey2); create trigger check_fkeys_pkey_exist before insert or update on fkeys for each row - execute procedure + execute function check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2'); create trigger check_fkeys_pkey2_exist before insert or update on fkeys for each row - execute procedure check_primary_key ('fkey3', 'fkeys2', 'pkey23'); + execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23'); -- -- For fkeys2: -- (fkey21, fkey22) --> pkeys (pkey1, pkey2) @@ -144,6 +144,76 @@ select * from trigtest; ----+---- (0 rows) +-- Also check what happens when such a trigger runs before or after others +create function f1_times_10() returns trigger as +$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql; +create trigger trigger_alpha + before insert or update on trigtest + for each row execute procedure f1_times_10(); +insert into trigtest values(1, 'foo'); +select * from trigtest; + f1 | f2 +----+----- + 10 | foo +(1 row) + +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; + f1 | f2 +----+----- + 10 | foo +(1 row) + +delete from trigtest; +select * from trigtest; + f1 | f2 +----+---- +(0 rows) + +create trigger trigger_zed + before insert or update on trigtest + for each row execute procedure f1_times_10(); +insert into trigtest values(1, 'foo'); +select * from trigtest; + f1 | f2 +-----+----- + 100 | foo +(1 row) + +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; + f1 | f2 +------+----- + 1000 | foo +(1 row) + +delete from trigtest; +select * from trigtest; + f1 | f2 +----+---- +(0 rows) + +drop trigger trigger_alpha on trigtest; +insert into trigtest values(1, 'foo'); +select * from trigtest; + f1 | f2 +----+----- + 10 | foo +(1 row) + +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; + f1 | f2 +-----+----- + 100 | foo +(1 row) + +delete from trigtest; +select * from trigtest; + f1 | f2 +----+---- +(0 rows) + drop table trigtest; create sequence ttdummy_seq increment 10 start 0 minvalue 0; create table tttest ( @@ -417,29 +487,53 @@ SELECT * FROM main_table ORDER BY a, b; (8 rows) SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; - pg_get_triggerdef --------------------------------------------------------------------------------------------------------------------------------------------- - CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.a <> new.a) EXECUTE PROCEDURE trigger_func('modified_a') + pg_get_triggerdef +------------------------------------------------------------------------------------------------------------------------------------------- + CREATE TRIGGER modified_a BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.a <> new.a) EXECUTE FUNCTION trigger_func('modified_a') (1 row) SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; - pg_get_triggerdef ------------------------------------------------------------------------------------------------------------------------------------------------------ - CREATE TRIGGER modified_a BEFORE UPDATE OF a ON public.main_table FOR EACH ROW WHEN ((old.a <> new.a)) EXECUTE PROCEDURE trigger_func('modified_a') + pg_get_triggerdef +---------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE TRIGGER modified_a BEFORE UPDATE OF a ON public.main_table FOR EACH ROW WHEN ((old.a <> new.a)) EXECUTE FUNCTION trigger_func('modified_a') (1 row) SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any'; - pg_get_triggerdef --------------------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.* IS DISTINCT FROM new.*) EXECUTE PROCEDURE trigger_func('modified_any') + pg_get_triggerdef +------------------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE TRIGGER modified_any BEFORE UPDATE OF a ON main_table FOR EACH ROW WHEN (old.* IS DISTINCT FROM new.*) EXECUTE FUNCTION trigger_func('modified_any') +(1 row) + +-- Test RENAME TRIGGER +ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a; +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; + count +------- + 0 +(1 row) + +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_modified_a'; + count +------- + 1 (1 row) -DROP TRIGGER modified_a ON main_table; +DROP TRIGGER modified_modified_a ON main_table; DROP TRIGGER modified_any ON main_table; DROP TRIGGER insert_a ON main_table; DROP TRIGGER delete_a ON main_table; DROP TRIGGER insert_when ON main_table; DROP TRIGGER delete_when ON main_table; +-- Test WHEN condition accessing system columns. +create table table_with_oids(a int); +insert into table_with_oids values (1); +create trigger oid_unchanged_trig after update on table_with_oids + for each row + when (new.tableoid = old.tableoid AND new.tableoid <> 0) + execute procedure trigger_func('after_upd_oid_unchanged'); +update table_with_oids set a = a + 1; +NOTICE: trigger_func(after_upd_oid_unchanged) called: action = UPDATE, when = AFTER, level = ROW +drop table table_with_oids; -- Test column-level triggers DROP TRIGGER after_upd_row_trig ON main_table; CREATE TRIGGER before_upd_a_row_trig BEFORE UPDATE OF a ON main_table @@ -453,9 +547,9 @@ FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('before_upd_a_stmt'); CREATE TRIGGER after_upd_b_stmt_trig AFTER UPDATE OF b ON main_table FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func('after_upd_b_stmt'); SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig'; - pg_get_triggerdef --------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON public.main_table FOR EACH ROW EXECUTE PROCEDURE trigger_func('after_upd_a_b_row') + pg_get_triggerdef +------------------------------------------------------------------------------------------------------------------------------------------------- + CREATE TRIGGER after_upd_a_b_row_trig AFTER UPDATE OF a, b ON public.main_table FOR EACH ROW EXECUTE FUNCTION trigger_func('after_upd_a_b_row') (1 row) UPDATE main_table SET a = 50; @@ -557,10 +651,10 @@ LINE 2: FOR EACH STATEMENT WHEN (OLD.* IS DISTINCT FROM NEW.*) ^ -- check dependency restrictions ALTER TABLE main_table DROP COLUMN b; -ERROR: cannot drop table main_table column b because other objects depend on it -DETAIL: trigger after_upd_b_row_trig on table main_table depends on table main_table column b -trigger after_upd_a_b_row_trig on table main_table depends on table main_table column b -trigger after_upd_b_stmt_trig on table main_table depends on table main_table column b +ERROR: cannot drop column b of table main_table because other objects depend on it +DETAIL: trigger after_upd_b_row_trig on table main_table depends on column b of table main_table +trigger after_upd_a_b_row_trig on table main_table depends on column b of table main_table +trigger after_upd_b_stmt_trig on table main_table depends on column b of table main_table HINT: Use DROP ... CASCADE to drop the dependent objects too. -- this should succeed, but we'll roll it back to keep the triggers around begin; @@ -824,18 +918,10 @@ CREATE TABLE min_updates_test ( f1 text, f2 int, f3 int); -CREATE TABLE min_updates_test_oids ( - f1 text, - f2 int, - f3 int) WITH OIDS; INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null); -INSERT INTO min_updates_test_oids VALUES ('a',1,2),('b','2',null); CREATE TRIGGER z_min_update BEFORE UPDATE ON min_updates_test FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); -CREATE TRIGGER z_min_update -BEFORE UPDATE ON min_updates_test_oids -FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); \set QUIET false UPDATE min_updates_test SET f1 = f1; UPDATE 0 @@ -843,12 +929,6 @@ UPDATE min_updates_test SET f2 = f2 + 1; UPDATE 2 UPDATE min_updates_test SET f3 = 2 WHERE f3 is null; UPDATE 1 -UPDATE min_updates_test_oids SET f1 = f1; -UPDATE 0 -UPDATE min_updates_test_oids SET f2 = f2 + 1; -UPDATE 2 -UPDATE min_updates_test_oids SET f3 = 2 WHERE f3 is null; -UPDATE 1 \set QUIET true SELECT * FROM min_updates_test; f1 | f2 | f3 @@ -857,15 +937,7 @@ SELECT * FROM min_updates_test; b | 3 | 2 (2 rows) -SELECT * FROM min_updates_test_oids; - f1 | f2 | f3 -----+----+---- - a | 2 | 2 - b | 3 | 2 -(2 rows) - DROP TABLE min_updates_test; -DROP TABLE min_updates_test_oids; -- -- Test triggers on views -- @@ -1105,15 +1177,15 @@ DELETE 1 a | integer | | | b | integer | | | Triggers: - after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt') - after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt') - after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt') - before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt') - before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt') - before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt') - instead_of_delete_trig INSTEAD OF DELETE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_del') - instead_of_insert_trig INSTEAD OF INSERT ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_ins') - instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') + after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_del_stmt') + after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_ins_stmt') + after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_upd_stmt') + before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_del_stmt') + before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_ins_stmt') + before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_upd_stmt') + instead_of_delete_trig INSTEAD OF DELETE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_del') + instead_of_insert_trig INSTEAD OF INSERT ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_ins') + instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_upd') -- Test dropping view triggers DROP TRIGGER instead_of_insert_trig ON main_view; @@ -1129,13 +1201,13 @@ View definition: main_table.b FROM main_table; Triggers: - after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_del_stmt') - after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_ins_stmt') - after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('after_view_upd_stmt') - before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_del_stmt') - before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_ins_stmt') - before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE PROCEDURE view_trigger('before_view_upd_stmt') - instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE PROCEDURE view_trigger('instead_of_upd') + after_del_stmt_trig AFTER DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_del_stmt') + after_ins_stmt_trig AFTER INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_ins_stmt') + after_upd_stmt_trig AFTER UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('after_view_upd_stmt') + before_del_stmt_trig BEFORE DELETE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_del_stmt') + before_ins_stmt_trig BEFORE INSERT ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_ins_stmt') + before_upd_stmt_trig BEFORE UPDATE ON main_view FOR EACH STATEMENT EXECUTE FUNCTION view_trigger('before_view_upd_stmt') + instead_of_update_trig INSTEAD OF UPDATE ON main_view FOR EACH ROW EXECUTE FUNCTION view_trigger('instead_of_upd') DROP VIEW main_view; -- @@ -1605,7 +1677,7 @@ select * from parent; select * from child; (1 row) delete from parent where aid = 1; -- should fail -ERROR: tuple to be updated was already modified by an operation triggered by the current command +ERROR: tuple to be deleted was already modified by an operation triggered by the current command HINT: Consider using an AFTER trigger instead of a BEFORE trigger to propagate changes to other rows. select * from parent; select * from child; aid | val1 | val2 | val3 | val4 | bcnt @@ -1714,6 +1786,40 @@ drop table self_ref_trigger; drop function self_ref_trigger_ins_func(); drop function self_ref_trigger_del_func(); -- +-- Check that statement triggers work correctly even with all children excluded +-- +create table stmt_trig_on_empty_upd (a int); +create table stmt_trig_on_empty_upd1 () inherits (stmt_trig_on_empty_upd); +create function update_stmt_notice() returns trigger as $$ +begin + raise notice 'updating %', TG_TABLE_NAME; + return null; +end; +$$ language plpgsql; +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd + execute procedure update_stmt_notice(); +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd1 + execute procedure update_stmt_notice(); +-- inherited no-op update +update stmt_trig_on_empty_upd set a = a where false returning a+1 as aa; +NOTICE: updating stmt_trig_on_empty_upd + aa +---- +(0 rows) + +-- simple no-op update +update stmt_trig_on_empty_upd1 set a = a where false returning a+1 as aa; +NOTICE: updating stmt_trig_on_empty_upd1 + aa +---- +(0 rows) + +drop table stmt_trig_on_empty_upd cascade; +NOTICE: drop cascades to table stmt_trig_on_empty_upd1 +drop function update_stmt_notice(); +-- -- Check that index creation (or DDL in general) is prohibited in a trigger -- create table trigger_ddl_table ( @@ -2058,6 +2164,30 @@ NOTICE: trigger zzz on parted_trig_1_1 AFTER INSERT for ROW NOTICE: trigger bbb on parted_trig_2 AFTER INSERT for ROW NOTICE: trigger zzz on parted_trig_2 AFTER INSERT for ROW drop table parted_trig; +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a); +create table parted_trig1 partition of parted_trig for values in (1); +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql; +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1); +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2); +create table parted_trig3 (like parted_trig); +alter table parted_trig attach partition parted_trig3 for values in (3); +insert into parted_trig values (1), (2), (3); +NOTICE: trigger aaa on parted_trig1 AFTER INSERT for ROW args quirky 1 +NOTICE: trigger aaa on parted_trig2 AFTER INSERT for ROW args quirky 1 +NOTICE: trigger aaa on parted_trig3 AFTER INSERT for ROW args quirky 1 +drop table parted_trig; -- test irregular partitions (i.e., different column definitions), -- including that the WHEN clause works create function bark(text) returns bool language plpgsql immutable @@ -2576,7 +2706,7 @@ create trigger child_row_trig -- but now we're not allowed to make it inherit anymore alter table child inherit parent; ERROR: trigger "child_row_trig" prevents table "child" from becoming an inheritance child -DETAIL: ROW triggers with transition tables are not supported in inheritance hierarchies +DETAIL: ROW triggers with transition tables are not supported in inheritance hierarchies. -- drop the trigger, and now we're allowed to make it inherit again drop trigger child_row_trig on child; alter table child inherit parent; @@ -2784,54 +2914,6 @@ delete from self_ref where a = 1; NOTICE: trigger_func(self_ref) called: action = DELETE, when = BEFORE, level = STATEMENT NOTICE: trigger = self_ref_s_trig, old table = (1,), (2,1), (3,2), (4,3) drop table self_ref; --- --- test transition tables with MERGE --- -create table merge_target_table (a int primary key, b text); -create trigger merge_target_table_insert_trig - after insert on merge_target_table referencing new table as new_table - for each statement execute procedure dump_insert(); -create trigger merge_target_table_update_trig - after update on merge_target_table referencing old table as old_table new table as new_table - for each statement execute procedure dump_update(); -create trigger merge_target_table_delete_trig - after delete on merge_target_table referencing old table as old_table - for each statement execute procedure dump_delete(); -create table merge_source_table (a int, b text); -insert into merge_source_table - values (1, 'initial1'), (2, 'initial2'), - (3, 'initial3'), (4, 'initial4'); -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when not matched then - insert values (a, b); -NOTICE: trigger = merge_target_table_insert_trig, new table = (1,initial1), (2,initial2), (3,initial3), (4,initial4) -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when matched and s.a <= 2 then - update set b = t.b || ' updated by merge' -when matched and s.a > 2 then - delete -when not matched then - insert values (a, b); -NOTICE: trigger = merge_target_table_delete_trig, old table = (3,initial3), (4,initial4) -NOTICE: trigger = merge_target_table_update_trig, old table = (1,initial1), (2,initial2), new table = (1,"initial1 updated by merge"), (2,"initial2 updated by merge") -NOTICE: trigger = merge_target_table_insert_trig, new table = -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when matched and s.a <= 2 then - update set b = t.b || ' updated again by merge' -when matched and s.a > 2 then - delete -when not matched then - insert values (a, b); -NOTICE: trigger = merge_target_table_delete_trig, old table = -NOTICE: trigger = merge_target_table_update_trig, old table = (1,"initial1 updated by merge"), (2,"initial2 updated by merge"), new table = (1,"initial1 updated by merge updated again by merge"), (2,"initial2 updated by merge updated again by merge") -NOTICE: trigger = merge_target_table_insert_trig, new table = (3,initial3), (4,initial4) -drop table merge_source_table, merge_target_table; -- cleanup drop function dump_insert(); drop function dump_update(); diff --git a/src/test/regress/expected/truncate.out b/src/test/regress/expected/truncate.out index 735d0e862df..cc68274dca5 100644 --- a/src/test/regress/expected/truncate.out +++ b/src/test/regress/expected/truncate.out @@ -464,3 +464,81 @@ ERROR: cannot truncate only a partitioned table HINT: Do not specify the ONLY keyword, or use TRUNCATE ONLY on the partitions directly. TRUNCATE truncparted; DROP TABLE truncparted; +-- foreign key on partitioned table: partition key is referencing column. +-- Make sure truncate did execute on all tables +CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO truncprim VALUES (1), (100), (150); + INSERT INTO truncpart VALUES (1), (100), (150); + END +$$; +CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) + RETURNS SETOF record LANGUAGE plpgsql AS $$ + BEGIN + RETURN QUERY SELECT + pk.tableoid::regclass, pk.a, fk.tableoid::regclass, fk.a + FROM truncprim pk FULL JOIN truncpart fk USING (a) + ORDER BY 2, 4; + END +$$; +CREATE TABLE truncprim (a int PRIMARY KEY); +CREATE TABLE truncpart (a int REFERENCES truncprim) + PARTITION BY RANGE (a); +CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100); +CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) + PARTITION BY RANGE (a); +CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150); +CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT; +TRUNCATE TABLE truncprim; -- should fail +ERROR: cannot truncate a table referenced in a foreign key constraint +DETAIL: Table "truncpart" references "truncprim". +HINT: Truncate table "truncpart" at the same time, or use TRUNCATE ... CASCADE. +select tp_ins_data(); + tp_ins_data +------------- + +(1 row) + +-- should truncate everything +TRUNCATE TABLE truncprim, truncpart; +select * from tp_chk_data(); + pktb | pkval | fktb | fkval +------+-------+------+------- +(0 rows) + +select tp_ins_data(); + tp_ins_data +------------- + +(1 row) + +-- should truncate everything +TRUNCATE TABLE truncprim CASCADE; +NOTICE: truncate cascades to table "truncpart" +NOTICE: truncate cascades to table "truncpart_1" +NOTICE: truncate cascades to table "truncpart_2" +NOTICE: truncate cascades to table "truncpart_2_1" +NOTICE: truncate cascades to table "truncpart_2_d" +SELECT * FROM tp_chk_data(); + pktb | pkval | fktb | fkval +------+-------+------+------- +(0 rows) + +SELECT tp_ins_data(); + tp_ins_data +------------- + +(1 row) + +-- should truncate all partitions +TRUNCATE TABLE truncpart; +SELECT * FROM tp_chk_data(); + pktb | pkval | fktb | fkval +-----------+-------+------+------- + truncprim | 1 | | + truncprim | 100 | | + truncprim | 150 | | +(3 rows) + +DROP TABLE truncprim, truncpart; +DROP FUNCTION tp_ins_data(), tp_chk_data(); diff --git a/src/test/regress/expected/tsdicts.out b/src/test/regress/expected/tsdicts.out index 0c1d7c76752..2524ec2768f 100644 --- a/src/test/regress/expected/tsdicts.out +++ b/src/test/regress/expected/tsdicts.out @@ -263,6 +263,12 @@ SELECT ts_lexize('hunspell_long', 'unbook'); {book} (1 row) +SELECT ts_lexize('hunspell_long', 'booked'); + ts_lexize +----------- + {book} +(1 row) + SELECT ts_lexize('hunspell_long', 'footklubber'); ts_lexize ---------------- @@ -281,12 +287,24 @@ SELECT ts_lexize('hunspell_long', 'ballyklubber'); {ball,klubber} (1 row) +SELECT ts_lexize('hunspell_long', 'ballsklubber'); + ts_lexize +---------------- + {ball,klubber} +(1 row) + SELECT ts_lexize('hunspell_long', 'footballyklubber'); ts_lexize --------------------- {foot,ball,klubber} (1 row) +SELECT ts_lexize('hunspell_long', 'ex-machina'); + ts_lexize +--------------- + {ex-,machina} +(1 row) + -- Test ISpell dictionary with hunspell affix file with FLAG num parameter CREATE TEXT SEARCH DICTIONARY hunspell_num ( Template=ispell, @@ -299,6 +317,12 @@ SELECT ts_lexize('hunspell_num', 'skies'); {sky} (1 row) +SELECT ts_lexize('hunspell_num', 'sk'); + ts_lexize +----------- + {sky} +(1 row) + SELECT ts_lexize('hunspell_num', 'bookings'); ts_lexize ---------------- @@ -359,6 +383,12 @@ SELECT ts_lexize('hunspell_num', 'unbook'); {book} (1 row) +SELECT ts_lexize('hunspell_num', 'booked'); + ts_lexize +----------- + {book} +(1 row) + SELECT ts_lexize('hunspell_num', 'footklubber'); ts_lexize ---------------- diff --git a/src/test/regress/expected/tsearch.out b/src/test/regress/expected/tsearch.out index b088ff0d4f1..7af289927cc 100644 --- a/src/test/regress/expected/tsearch.out +++ b/src/test/regress/expected/tsearch.out @@ -970,9 +970,9 @@ Water, water, every where, Nor any drop to drink. S. T. Coleridge (1772-1834) '), to_tsquery('english', 'breath&motion&water')); - ts_rank_cd ------------- - 0.00833333 + ts_rank_cd +------------- + 0.008333334 (1 row) SELECT ts_rank_cd(to_tsvector('english', ' @@ -1625,6 +1625,28 @@ SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); 1 (1 row) +-- Test inlining of immutable constant functions +-- to_tsquery(text) is not immutable, so it won't be inlined +explain (costs off) +select * from test_tsquery, to_tsquery('new') q where txtsample @@ q; + QUERY PLAN +------------------------------------------------ + Nested Loop + Join Filter: (test_tsquery.txtsample @@ q.q) + -> Function Scan on to_tsquery q + -> Seq Scan on test_tsquery +(4 rows) + +-- to_tsquery(regconfig, text) is an immutable function. +-- That allows us to get rid of using function scan and join at all. +explain (costs off) +select * from test_tsquery, to_tsquery('english', 'new') q where txtsample @@ q; + QUERY PLAN +--------------------------------------------- + Seq Scan on test_tsquery + Filter: (txtsample @@ '''new'''::tsquery) +(2 rows) + -- test finding items in GIN's pending list create temp table pendtest (ts tsvector); create index pendtest_idx on pendtest using gin(ts); diff --git a/src/test/regress/expected/tsrf.out b/src/test/regress/expected/tsrf.out index 6d33fbd3c8b..d47b5f6ec57 100644 --- a/src/test/regress/expected/tsrf.out +++ b/src/test/regress/expected/tsrf.out @@ -83,6 +83,39 @@ SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4); CREATE TABLE few(id int, dataa text, datab text); INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar'); +-- SRF with a provably-dummy relation +explain (verbose, costs off) +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; + QUERY PLAN +-------------------------------------- + ProjectSet + Output: unnest('{1,2}'::integer[]) + -> Result + One-Time Filter: false +(4 rows) + +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; + unnest +-------- +(0 rows) + +-- SRF shouldn't prevent upper query from recognizing lower as dummy +explain (verbose, costs off) +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; + QUERY PLAN +------------------------------------------------ + Result + Output: f1.id, f1.dataa, f1.datab, ss.unnest + One-Time Filter: false +(3 rows) + +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; + id | dataa | datab | unnest +----+-------+-------+-------- +(0 rows) + -- SRF output order of sorting is maintained, if SRF is not referenced SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC; id | g @@ -421,6 +454,28 @@ SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(d (24 rows) reset enable_hashagg; +-- case with degenerate ORDER BY +explain (verbose, costs off) +select 'foo' as f, generate_series(1,2) as g from few order by 1; + QUERY PLAN +---------------------------------------------- + ProjectSet + Output: 'foo'::text, generate_series(1, 2) + -> Seq Scan on public.few + Output: id, dataa, datab +(4 rows) + +select 'foo' as f, generate_series(1,2) as g from few order by 1; + f | g +-----+--- + foo | 1 + foo | 2 + foo | 1 + foo | 2 + foo | 1 + foo | 2 +(6 rows) + -- data modification CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data; INSERT INTO fewmore VALUES(generate_series(4,5)); diff --git a/src/test/regress/expected/tstypes.out b/src/test/regress/expected/tstypes.out index 6272e70e09f..2c838ddffdb 100644 --- a/src/test/regress/expected/tstypes.out +++ b/src/test/regress/expected/tstypes.out @@ -1,3 +1,5 @@ +-- deal with numeric instability of ts_rank +SET extra_float_digits = 0; --Base tsvector test SELECT '1'::tsvector; tsvector diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index b1419d4bc21..cd7fc03b04c 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -72,7 +72,7 @@ WHERE p1.typtype not in ('c','d','p') AND p1.typname NOT LIKE E'\\_%' 194 | pg_node_tree 3361 | pg_ndistinct 3402 | pg_dependencies - 210 | smgr + 5017 | pg_mcv_list (4 rows) -- Make sure typarray points to a varlena array type of our own base @@ -502,15 +502,42 @@ WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR -----+--------- (0 rows) --- Indexes should have an access method, others not. +-- All tables and indexes should have an access method. SELECT p1.oid, p1.relname FROM pg_class as p1 -WHERE (p1.relkind = 'i' AND p1.relam = 0) OR - (p1.relkind != 'i' AND p1.relam != 0); +WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and + p1.relam = 0; oid | relname -----+--------- (0 rows) +-- Conversely, sequences, views, types shouldn't have them +SELECT p1.oid, p1.relname +FROM pg_class as p1 +WHERE p1.relkind IN ('S', 'v', 'f', 'c') and + p1.relam != 0; + oid | relname +-----+--------- +(0 rows) + +-- Indexes should have AMs of type 'i' +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('i') and + pa.amtype != 'i'; + oid | relname | amname | amtype +-----+---------+--------+-------- +(0 rows) + +-- Tables, matviews etc should have AMs of type 't' +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('r', 't', 'm') and + pa.amtype != 't'; + oid | relname | amname | amtype +-----+---------+--------+-------- +(0 rows) + -- **************** pg_attribute **************** -- Look for illegal values in pg_attribute fields SELECT p1.attrelid, p1.attname diff --git a/src/test/regress/expected/union.out b/src/test/regress/expected/union.out index 92d427a690f..7189f5bd3d2 100644 --- a/src/test/regress/expected/union.out +++ b/src/test/regress/expected/union.out @@ -812,11 +812,10 @@ explain (costs off) UNION ALL SELECT 2 AS t, * FROM tenk1 b) c WHERE t = 2; - QUERY PLAN ---------------------------- - Append - -> Seq Scan on tenk1 b -(2 rows) + QUERY PLAN +--------------------- + Seq Scan on tenk1 b +(1 row) -- Test that we push quals into UNION sub-selects only when it's safe explain (costs off) @@ -916,6 +915,79 @@ ORDER BY x; 2 | 4 (1 row) +-- Test cases where the native ordering of a sub-select has more pathkeys +-- than the outer query cares about +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2; + QUERY PLAN +---------------------------------------------------------- + Unique + -> Merge Append + Sort Key: "*SELECT* 1".q1 + -> Subquery Scan on "*SELECT* 1" + -> Unique + -> Sort + Sort Key: i81.q1, i81.q2 + -> Seq Scan on int8_tbl i81 + Filter: (q2 IS NOT NULL) + -> Subquery Scan on "*SELECT* 2" + -> Unique + -> Sort + Sort Key: i82.q1, i82.q2 + -> Seq Scan on int8_tbl i82 + Filter: (q2 IS NOT NULL) +(15 rows) + +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2; + q1 +------------------ + 123 + 4567890123456789 +(2 rows) + +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2; + QUERY PLAN +-------------------------------------------------------- + Unique + -> Merge Append + Sort Key: "*SELECT* 1".q1 + -> Subquery Scan on "*SELECT* 1" + -> Unique + -> Sort + Sort Key: i81.q1, i81.q2 + -> Seq Scan on int8_tbl i81 + Filter: ((- q1) = q2) + -> Subquery Scan on "*SELECT* 2" + -> Unique + -> Sort + Sort Key: i82.q1, i82.q2 + -> Seq Scan on int8_tbl i82 + Filter: ((- q1) = q2) +(15 rows) + +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2; + q1 +------------------ + 4567890123456789 +(1 row) + -- Test proper handling of parameterized appendrel paths when the -- potential join qual is expensive create function expensivefunc(int) returns int diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index aedf8ce4044..8443c24f18b 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -1,6 +1,8 @@ -- -- UPDATABLE VIEWS -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; -- check that non-updatable views and columns are rejected with useful error -- messages CREATE TABLE base_tbl (a int PRIMARY KEY, b text DEFAULT 'Unspecified'); @@ -334,6 +336,7 @@ DETAIL: drop cascades to view ro_view1 drop cascades to view ro_view17 drop cascades to view ro_view2 drop cascades to view ro_view3 +drop cascades to view ro_view4 drop cascades to view ro_view5 drop cascades to view ro_view6 drop cascades to view ro_view7 @@ -341,11 +344,10 @@ drop cascades to view ro_view8 drop cascades to view ro_view9 drop cascades to view ro_view11 drop cascades to view ro_view13 +drop cascades to view rw_view14 drop cascades to view rw_view15 drop cascades to view rw_view16 drop cascades to view ro_view20 -drop cascades to view ro_view4 -drop cascades to view rw_view14 DROP VIEW ro_view10, ro_view12, ro_view18; DROP SEQUENCE uv_seq CASCADE; NOTICE: drop cascades to view ro_view19 @@ -1053,6 +1055,130 @@ SELECT * FROM base_tbl; 5 | Row 5 | 5 (2 rows) +RESET SESSION AUTHORIZATION; +DROP TABLE base_tbl CASCADE; +NOTICE: drop cascades to 2 other objects +DETAIL: drop cascades to view rw_view1 +drop cascades to view rw_view2 +-- nested-view permissions +CREATE TABLE base_tbl(a int, b text, c float); +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); +SET SESSION AUTHORIZATION regress_view_user1; +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl; +SELECT * FROM rw_view1; -- not allowed +ERROR: permission denied for table base_tbl +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +ERROR: permission denied for table base_tbl +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed +ERROR: permission denied for table base_tbl +SET SESSION AUTHORIZATION regress_view_user2; +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1; +SELECT * FROM rw_view2; -- not allowed +ERROR: permission denied for view rw_view1 +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +ERROR: permission denied for view rw_view1 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed +ERROR: permission denied for view rw_view1 +RESET SESSION AUTHORIZATION; +GRANT SELECT ON base_tbl TO regress_view_user1; +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; + a | b | c +---+-------+--- + 1 | Row 1 | 1 +(1 row) + +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +ERROR: permission denied for table base_tbl +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed +ERROR: permission denied for table base_tbl +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; -- not allowed +ERROR: permission denied for view rw_view1 +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +ERROR: permission denied for view rw_view1 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed +ERROR: permission denied for view rw_view1 +SET SESSION AUTHORIZATION regress_view_user1; +GRANT SELECT ON rw_view1 TO regress_view_user2; +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; + a | b | c +---+-------+--- + 1 | Row 1 | 1 +(1 row) + +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +ERROR: permission denied for view rw_view1 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed +ERROR: permission denied for view rw_view1 +RESET SESSION AUTHORIZATION; +GRANT UPDATE ON base_tbl TO regress_view_user1; +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; + a | b | c +---+-------+--- + 1 | Row 1 | 1 +(1 row) + +SELECT * FROM rw_view1 FOR UPDATE; + a | b | c +---+-------+--- + 1 | Row 1 | 1 +(1 row) + +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; + a | b | c +---+-----+--- + 1 | foo | 1 +(1 row) + +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +ERROR: permission denied for view rw_view1 +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed +ERROR: permission denied for view rw_view1 +SET SESSION AUTHORIZATION regress_view_user1; +GRANT UPDATE ON rw_view1 TO regress_view_user2; +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; + a | b | c +---+-----+--- + 1 | foo | 1 +(1 row) + +SELECT * FROM rw_view2 FOR UPDATE; + a | b | c +---+-----+--- + 1 | foo | 1 +(1 row) + +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; +RESET SESSION AUTHORIZATION; +REVOKE UPDATE ON base_tbl FROM regress_view_user1; +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; + a | b | c +---+-----+--- + 1 | bar | 1 +(1 row) + +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +ERROR: permission denied for table base_tbl +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed +ERROR: permission denied for table base_tbl +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; + a | b | c +---+-----+--- + 1 | bar | 1 +(1 row) + +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +ERROR: permission denied for table base_tbl +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed +ERROR: permission denied for table base_tbl RESET SESSION AUTHORIZATION; DROP TABLE base_tbl CASCADE; NOTICE: drop cascades to 2 other objects @@ -1416,10 +1542,67 @@ SELECT * FROM base_tbl_child ORDER BY a; 20 (6 rows) +CREATE TABLE other_tbl_parent (id int); +CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent); +INSERT INTO other_tbl_parent VALUES (7),(200); +INSERT INTO other_tbl_child VALUES (8),(100); +EXPLAIN (costs off) +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; + QUERY PLAN +-------------------------------------------------------------- + Update on base_tbl_parent + Update on base_tbl_parent + Update on base_tbl_child + -> Hash Join + Hash Cond: (other_tbl_parent.id = base_tbl_parent.a) + -> Append + -> Seq Scan on other_tbl_parent + -> Seq Scan on other_tbl_child + -> Hash + -> Seq Scan on base_tbl_parent + -> Merge Join + Merge Cond: (base_tbl_child.a = other_tbl_parent.id) + -> Sort + Sort Key: base_tbl_child.a + -> Seq Scan on base_tbl_child + -> Sort + Sort Key: other_tbl_parent.id + -> Append + -> Seq Scan on other_tbl_parent + -> Seq Scan on other_tbl_child +(20 rows) + +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; +SELECT * FROM ONLY base_tbl_parent ORDER BY a; + a +------ + -200 + -100 + -40 + -30 + -20 + -10 + 1100 + 1200 +(8 rows) + +SELECT * FROM base_tbl_child ORDER BY a; + a +------ + 3 + 4 + 10 + 20 + 1007 + 1008 +(6 rows) + DROP TABLE base_tbl_parent, base_tbl_child CASCADE; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to view rw_view1 drop cascades to view rw_view2 +DROP TABLE other_tbl_parent CASCADE; +NOTICE: drop cascades to table other_tbl_child -- simple WITH CHECK OPTION CREATE TABLE base_tbl (a int, b int DEFAULT 10); INSERT INTO base_tbl VALUES (1,2), (2,3), (1,-1); @@ -1550,7 +1733,7 @@ SELECT * FROM base_tbl; (2 rows) ALTER VIEW rw_view1 SET (check_option=here); -- invalid -ERROR: invalid value for "check_option" option +ERROR: invalid value for enum option "check_option": here DETAIL: Valid values are "local" and "cascaded". ALTER VIEW rw_view1 SET (check_option=local); INSERT INTO rw_view2 VALUES (-20); -- should fail @@ -1658,31 +1841,31 @@ UPDATE rw_view1 SET a = a + 5; -- should fail ERROR: new row violates check option for view "rw_view1" DETAIL: Failing row contains (15). EXPLAIN (costs off) INSERT INTO rw_view1 VALUES (5); - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------- Insert on base_tbl b -> Result - SubPlan 1 - -> Index Only Scan using ref_tbl_pkey on ref_tbl r - Index Cond: (a = b.a) - SubPlan 2 - -> Seq Scan on ref_tbl r_1 + SubPlan 1 + -> Index Only Scan using ref_tbl_pkey on ref_tbl r + Index Cond: (a = b.a) + SubPlan 2 + -> Seq Scan on ref_tbl r_1 (7 rows) EXPLAIN (costs off) UPDATE rw_view1 SET a = a + 5; - QUERY PLAN ------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------- Update on base_tbl b -> Hash Join Hash Cond: (b.a = r.a) -> Seq Scan on base_tbl b -> Hash -> Seq Scan on ref_tbl r - SubPlan 1 - -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1 - Index Cond: (a = b.a) - SubPlan 2 - -> Seq Scan on ref_tbl r_2 + SubPlan 1 + -> Index Only Scan using ref_tbl_pkey on ref_tbl r_1 + Index Cond: (a = b.a) + SubPlan 2 + -> Seq Scan on ref_tbl r_2 (11 rows) DROP TABLE base_tbl, ref_tbl CASCADE; @@ -2454,3 +2637,379 @@ ERROR: new row violates check option for view "wcowrtest_v2" DETAIL: Failing row contains (2, no such row in sometable). drop view wcowrtest_v, wcowrtest_v2; drop table wcowrtest, sometable; +-- Check INSERT .. ON CONFLICT DO UPDATE works correctly when the view's +-- columns are named and ordered differently than the underlying table's. +create table uv_iocu_tab (a text unique, b float); +insert into uv_iocu_tab values ('xyxyxy', 0); +create view uv_iocu_view as + select b, b+1 as c, a, '2.0'::text as two from uv_iocu_tab; +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = uv_iocu_view.b; +select * from uv_iocu_tab; + a | b +--------+--- + xyxyxy | 0 +(1 row) + +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = excluded.b; +select * from uv_iocu_tab; + a | b +--------+--- + xyxyxy | 1 +(1 row) + +-- OK to access view columns that are not present in underlying base +-- relation in the ON CONFLICT portion of the query +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = cast(excluded.two as float); +select * from uv_iocu_tab; + a | b +--------+--- + xyxyxy | 2 +(1 row) + +explain (costs off) +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; + QUERY PLAN +----------------------------------------------------------------------------------- + Insert on uv_iocu_tab + Conflict Resolution: UPDATE + Conflict Arbiter Indexes: uv_iocu_tab_a_key + Conflict Filter: ((excluded.b + '1'::double precision) > '0'::double precision) + -> Result +(5 rows) + +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; +select * from uv_iocu_tab; + a | b +--------+--- + xyxyxy | 3 +(1 row) + +drop view uv_iocu_view; +drop table uv_iocu_tab; +-- Test whole-row references to the view +create table uv_iocu_tab (a int unique, b text); +create view uv_iocu_view as + select b as bb, a as aa, uv_iocu_tab::text as cc from uv_iocu_tab; +insert into uv_iocu_view (aa,bb) values (1,'x'); +explain (costs off) +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Insert on uv_iocu_tab + Conflict Resolution: UPDATE + Conflict Arbiter Indexes: uv_iocu_tab_a_key + Conflict Filter: ((excluded.a > 0) AND (excluded.b <> ''::text) AND ((excluded.*)::text IS NOT NULL)) + -> Result +(5 rows) + +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; +select * from uv_iocu_view; + bb | aa | cc +-------------------------+----+--------------------------------- + Rejected: (y,1,"(1,y)") | 1 | (1,"Rejected: (y,1,""(1,y)"")") +(1 row) + +-- Test omitting a column of the base relation +delete from uv_iocu_view; +insert into uv_iocu_view (aa,bb) values (1,'x'); +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + bb | aa | cc +-----------------------+----+------------------------------- + Rejected: (,1,"(1,)") | 1 | (1,"Rejected: (,1,""(1,)"")") +(1 row) + +alter table uv_iocu_tab alter column b set default 'table default'; +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + bb | aa | cc +-------------------------------------------------------+----+--------------------------------------------------------------------- + Rejected: ("table default",1,"(1,""table default"")") | 1 | (1,"Rejected: (""table default"",1,""(1,""""table default"""")"")") +(1 row) + +alter view uv_iocu_view alter column bb set default 'view default'; +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + bb | aa | cc +-----------------------------------------------------+----+------------------------------------------------------------------- + Rejected: ("view default",1,"(1,""view default"")") | 1 | (1,"Rejected: (""view default"",1,""(1,""""view default"""")"")") +(1 row) + +-- Should fail to update non-updatable columns +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set cc = 'XXX'; +ERROR: cannot insert into column "cc" of view "uv_iocu_view" +DETAIL: View columns that are not columns of their base relation are not updatable. +drop view uv_iocu_view; +drop table uv_iocu_tab; +-- ON CONFLICT DO UPDATE permissions checks +create user regress_view_user1; +create user regress_view_user2; +set session authorization regress_view_user1; +create table base_tbl(a int unique, b text, c float); +insert into base_tbl values (1,'xxx',1.0); +create view rw_view1 as select b as bb, c as cc, a as aa from base_tbl; +grant select (aa,bb) on rw_view1 to regress_view_user2; +grant insert on rw_view1 to regress_view_user2; +grant update (bb) on rw_view1 to regress_view_user2; +set session authorization regress_view_user2; +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.cc; -- Not allowed +ERROR: permission denied for view rw_view1 +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = rw_view1.cc; -- Not allowed +ERROR: permission denied for view rw_view1 +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.bb; -- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set bb = rw_view1.bb||'xxx'; -- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set cc = 3.0; -- Not allowed +ERROR: permission denied for view rw_view1 +reset session authorization; +select * from base_tbl; + a | b | c +---+--------+--- + 1 | yyyxxx | 1 +(1 row) + +set session authorization regress_view_user1; +grant select (a,b) on base_tbl to regress_view_user2; +grant insert (a,b) on base_tbl to regress_view_user2; +grant update (a,b) on base_tbl to regress_view_user2; +set session authorization regress_view_user2; +create view rw_view2 as select b as bb, c as cc, a as aa from base_tbl; +insert into rw_view2 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; -- Not allowed +ERROR: permission denied for table base_tbl +create view rw_view3 as select b as bb, a as aa from base_tbl; +insert into rw_view3 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; -- OK +reset session authorization; +select * from base_tbl; + a | b | c +---+-----+--- + 1 | xxx | 1 +(1 row) + +set session authorization regress_view_user2; +create view rw_view4 as select aa, bb, cc FROM rw_view1; +insert into rw_view4 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; -- Not allowed +ERROR: permission denied for view rw_view1 +create view rw_view5 as select aa, bb FROM rw_view1; +insert into rw_view5 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; -- OK +reset session authorization; +select * from base_tbl; + a | b | c +---+-----+--- + 1 | yyy | 1 +(1 row) + +drop view rw_view5; +drop view rw_view4; +drop view rw_view3; +drop view rw_view2; +drop view rw_view1; +drop table base_tbl; +drop user regress_view_user1; +drop user regress_view_user2; +-- Test single- and multi-row inserts with table and view defaults. +-- Table defaults should be used, unless overridden by view defaults. +create table base_tab_def (a int, b text default 'Table default', + c text default 'Table default', d text, e text); +create view base_tab_def_view as select * from base_tab_def; +alter view base_tab_def_view alter b set default 'View default'; +alter view base_tab_def_view alter d set default 'View default'; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + a | b | c | d | e +----+---------------+---------------+--------------+--- + 1 | Table default | Table default | | + 2 | Table default | Table default | | + 3 | Table default | Table default | | + 4 | Table default | Table default | | + 5 | Table default | Table default | | + 6 | Table default | Table default | | + 11 | View default | Table default | View default | + 12 | View default | Table default | View default | + 13 | View default | Table default | View default | + 14 | View default | Table default | View default | + 15 | View default | Table default | View default | + 16 | View default | Table default | View default | + 17 | View default | Table default | View default | + | View default | Table default | View default | +(14 rows) + +-- Adding an INSTEAD OF trigger should cause NULLs to be inserted instead of +-- table defaults, where there are no view defaults. +create function base_tab_def_view_instrig_func() returns trigger +as +$$ +begin + insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + return new; +end; +$$ +language plpgsql; +create trigger base_tab_def_view_instrig instead of insert on base_tab_def_view + for each row execute function base_tab_def_view_instrig_func(); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + a | b | c | d | e +----+---------------+---------------+--------------+--- + 1 | Table default | Table default | | + 2 | Table default | Table default | | + 3 | Table default | Table default | | + 4 | Table default | Table default | | + 5 | Table default | Table default | | + 6 | Table default | Table default | | + 11 | View default | | View default | + 12 | View default | | View default | + 13 | View default | | View default | + 14 | View default | | View default | + 15 | View default | | View default | + 16 | View default | | View default | + 17 | View default | | View default | + | View default | | View default | +(14 rows) + +-- Using an unconditional DO INSTEAD rule should also cause NULLs to be +-- inserted where there are no view defaults. +drop trigger base_tab_def_view_instrig on base_tab_def_view; +drop function base_tab_def_view_instrig_func; +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do instead insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + a | b | c | d | e +----+---------------+---------------+--------------+--- + 1 | Table default | Table default | | + 2 | Table default | Table default | | + 3 | Table default | Table default | | + 4 | Table default | Table default | | + 5 | Table default | Table default | | + 6 | Table default | Table default | | + 11 | View default | | View default | + 12 | View default | | View default | + 13 | View default | | View default | + 14 | View default | | View default | + 15 | View default | | View default | + 16 | View default | | View default | + 17 | View default | | View default | + | View default | | View default | +(14 rows) + +-- A DO ALSO rule should cause each row to be inserted twice. The first +-- insert should behave the same as an auto-updatable view (using table +-- defaults, unless overridden by view defaults). The second insert should +-- behave the same as a rule-updatable view (inserting NULLs where there are +-- no view defaults). +drop rule base_tab_def_view_ins_rule on base_tab_def_view; +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a, c NULLS LAST; + a | b | c | d | e +----+---------------+---------------+--------------+--- + 1 | Table default | Table default | | + 2 | Table default | Table default | | + 3 | Table default | Table default | | + 4 | Table default | Table default | | + 5 | Table default | Table default | | + 6 | Table default | Table default | | + 11 | View default | Table default | View default | + 11 | View default | | View default | + 12 | View default | Table default | View default | + 12 | View default | | View default | + 13 | View default | Table default | View default | + 13 | View default | | View default | + 14 | View default | Table default | View default | + 14 | View default | | View default | + 15 | View default | Table default | View default | + 15 | View default | | View default | + 16 | View default | Table default | View default | + 16 | View default | | View default | + 17 | View default | Table default | View default | + 17 | View default | | View default | + | View default | Table default | View default | + | View default | | View default | +(22 rows) + +drop view base_tab_def_view; +drop table base_tab_def; +-- Test defaults with array assignments +create table base_tab (a serial, b int[], c text, d text default 'Table default'); +create view base_tab_view as select c, a, b from base_tab; +alter view base_tab_view alter column c set default 'View default'; +insert into base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) +values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12); +select * from base_tab order by a; + a | b | c | d +-----+------------------+--------------+--------------- + 1 | {1,2,3,4,5} | View default | Table default + 100 | {10,11,12,13,14} | C value | Table default +(2 rows) + +drop view base_tab_view; +drop table base_tab; diff --git a/src/test/regress/expected/update.out b/src/test/regress/expected/update.out index d09326c1824..a24ecd61df8 100644 --- a/src/test/regress/expected/update.out +++ b/src/test/regress/expected/update.out @@ -167,6 +167,37 @@ SELECT a, b, char_length(c) FROM update_test; 42 | 12 | 10000 (4 rows) +-- Check multi-assignment with a Result node to handle a one-time filter. +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; + QUERY PLAN +------------------------------------------------------------------ + Update on public.update_test t + -> Result + Output: $1, $2, t.c, (SubPlan 1 (returns $1,$2)), t.ctid + One-Time Filter: (CURRENT_USER = SESSION_USER) + -> Seq Scan on public.update_test t + Output: t.c, t.a, t.ctid + SubPlan 1 (returns $1,$2) + -> Seq Scan on public.update_test s + Output: s.b, s.a + Filter: (s.a = t.a) +(10 rows) + +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; +SELECT a, b, char_length(c) FROM update_test; + a | b | char_length +-----+----+------------- + | | + 100 | 21 | + 12 | 41 | 10000 + 12 | 42 | 10000 +(4 rows) + -- Test ON CONFLICT DO UPDATE INSERT INTO upsert_test VALUES(1, 'Boo'); -- uncorrelated sub-select: @@ -196,6 +227,29 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a) 1 | Foo, Correlated, Excluded (1 row) +-- ON CONFLICT using system attributes in RETURNING, testing both the +-- inserting and updating paths. See bug report at: +-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au +CREATE FUNCTION xid_current() RETURNS xid LANGUAGE SQL AS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$; +INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = 0 AS xmax_correct; + tableoid | xmin_correct | xmax_correct +-------------+--------------+-------------- + upsert_test | t | t +(1 row) + +-- currently xmax is set after a conflict - that's probably not good, +-- but it seems worthwhile to have to be explicit if that changes. +INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = xid_current() AS xmax_correct; + tableoid | xmin_correct | xmax_correct +-------------+--------------+-------------- + upsert_test | t | t +(1 row) + +DROP FUNCTION xid_current(); DROP TABLE update_test; DROP TABLE upsert_test; --------------------------- diff --git a/src/test/regress/expected/uuid.out b/src/test/regress/expected/uuid.out index db66dc723ef..090103df48a 100644 --- a/src/test/regress/expected/uuid.out +++ b/src/test/regress/expected/uuid.out @@ -145,5 +145,15 @@ SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_fiel 1 (1 row) +-- generation test +TRUNCATE guid1; +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); +SELECT count(DISTINCT guid_field) FROM guid1; + count +------- + 2 +(1 row) + -- clean up DROP TABLE guid1, guid2 CASCADE; diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d66e2aa3b70..aff0b10a939 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -71,6 +71,18 @@ ANALYZE vaccluster; ERROR: ANALYZE cannot be executed from VACUUM or ANALYZE CONTEXT: SQL function "do_analyze" statement 1 SQL function "wrap_do_analyze" statement 1 +-- Test ANALYZE in transaction, where the transaction surrounding +-- analyze performed modifications. This tests for the bug at +-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info +-- (which hopefully is unlikely to be reintroduced), but also seems +-- independently worthwhile to cover. +INSERT INTO vactst SELECT generate_series(1, 300); +DELETE FROM vactst WHERE i % 7 = 0; -- delete a few rows outside +BEGIN; +INSERT INTO vactst SELECT generate_series(301, 400); +DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside +ANALYZE vactst; +COMMIT; VACUUM FULL pg_am; VACUUM FULL pg_class; VACUUM FULL pg_database; @@ -80,6 +92,62 @@ CONTEXT: SQL function "do_analyze" statement 1 SQL function "wrap_do_analyze" statement 1 VACUUM FULL vactst; VACUUM (DISABLE_PAGE_SKIPPING) vaccluster; +-- INDEX_CLEANUP option +CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT); +-- Use uncompressed data stored in toast. +CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t); +ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL; +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), + repeat('1234567890',300)); +-- index cleanup option is ignored if VACUUM FULL +VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup; +VACUUM (FULL TRUE) no_index_cleanup; +-- Toast inherits the value from its parent table. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false); +DELETE FROM no_index_cleanup WHERE i < 15; +-- Nothing is cleaned up. +VACUUM no_index_cleanup; +-- Both parent relation and toast are cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true); +VACUUM no_index_cleanup; +-- Parameter is set for both the parent table and its toast relation. +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), + repeat('1234567890',300)); +DELETE FROM no_index_cleanup WHERE i < 45; +-- Only toast index is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false, + toast.vacuum_index_cleanup = true); +VACUUM no_index_cleanup; +-- Only parent is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, + toast.vacuum_index_cleanup = false); +VACUUM no_index_cleanup; +-- Test some extra relations. +VACUUM (INDEX_CLEANUP FALSE) vaccluster; +VACUUM (INDEX_CLEANUP FALSE) vactst; -- index cleanup option is ignored if no indexes +VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster; +-- TRUNCATE option +CREATE TABLE vac_truncate_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=true, autovacuum_enabled=false); +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL); +ERROR: null value in column "i" violates not-null constraint +DETAIL: Failing row contains (null, null). +VACUUM (TRUNCATE FALSE) vac_truncate_test; +SELECT pg_relation_size('vac_truncate_test') > 0; + ?column? +---------- + t +(1 row) + +VACUUM vac_truncate_test; +SELECT pg_relation_size('vac_truncate_test') = 0; + ?column? +---------- + t +(1 row) + +VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test; +DROP TABLE vac_truncate_test; -- partitioned table CREATE TABLE vacparted (a int, b char) PARTITION BY LIST (a); CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1); @@ -112,13 +180,167 @@ ANALYZE vactst, does_not_exist, vacparted; ERROR: relation "does_not_exist" does not exist ANALYZE vactst (i), vacparted (does_not_exist); ERROR: column "does_not_exist" of relation "vacparted" does not exist +ANALYZE vactst, vactst; +BEGIN; -- ANALYZE behaves differently inside a transaction block +ANALYZE vactst, vactst; +COMMIT; -- parenthesized syntax for ANALYZE ANALYZE (VERBOSE) does_not_exist; ERROR: relation "does_not_exist" does not exist -ANALYZE (nonexistant-arg) does_not_exist; -ERROR: syntax error at or near "nonexistant" -LINE 1: ANALYZE (nonexistant-arg) does_not_exist; +ANALYZE (nonexistent-arg) does_not_exist; +ERROR: syntax error at or near "arg" +LINE 1: ANALYZE (nonexistent-arg) does_not_exist; + ^ +ANALYZE (nonexistentarg) does_not_exit; +ERROR: unrecognized ANALYZE option "nonexistentarg" +LINE 1: ANALYZE (nonexistentarg) does_not_exit; ^ +-- ensure argument order independence, and that SKIP_LOCKED on non-existing +-- relation still errors out. +ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist; +ERROR: relation "does_not_exist" does not exist +ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist; +ERROR: relation "does_not_exist" does not exist +-- SKIP_LOCKED option +VACUUM (SKIP_LOCKED) vactst; +VACUUM (SKIP_LOCKED, FULL) vactst; +ANALYZE (SKIP_LOCKED) vactst; +-- ensure VACUUM and ANALYZE don't have a problem with serializable +SET default_transaction_isolation = serializable; +VACUUM vactst; +ANALYZE vactst; +RESET default_transaction_isolation; +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; +ANALYZE vactst; +COMMIT; DROP TABLE vaccluster; DROP TABLE vactst; DROP TABLE vacparted; +DROP TABLE no_index_cleanup; +-- relation ownership, WARNING logs generated as all are skipped. +CREATE TABLE vacowned (a int); +CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a); +CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1); +CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2); +CREATE ROLE regress_vacuum; +SET ROLE regress_vacuum; +-- Simple table +VACUUM vacowned; +WARNING: skipping "vacowned" --- only table or database owner can vacuum it +ANALYZE vacowned; +WARNING: skipping "vacowned" --- only table or database owner can analyze it +VACUUM (ANALYZE) vacowned; +WARNING: skipping "vacowned" --- only table or database owner can vacuum it +-- Catalog +VACUUM pg_catalog.pg_class; +WARNING: skipping "pg_class" --- only superuser or database owner can vacuum it +ANALYZE pg_catalog.pg_class; +WARNING: skipping "pg_class" --- only superuser or database owner can analyze it +VACUUM (ANALYZE) pg_catalog.pg_class; +WARNING: skipping "pg_class" --- only superuser or database owner can vacuum it +-- Shared catalog +VACUUM pg_catalog.pg_authid; +WARNING: skipping "pg_authid" --- only superuser can vacuum it +ANALYZE pg_catalog.pg_authid; +WARNING: skipping "pg_authid" --- only superuser can analyze it +VACUUM (ANALYZE) pg_catalog.pg_authid; +WARNING: skipping "pg_authid" --- only superuser can vacuum it +-- Partitioned table and its partitions, nothing owned by other user. +-- Relations are not listed in a single command to test ownership +-- independently. +VACUUM vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +VACUUM vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +ANALYZE vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can analyze it +WARNING: skipping "vacowned_part1" --- only table or database owner can analyze it +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +ANALYZE vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can analyze it +ANALYZE vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +VACUUM (ANALYZE) vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +RESET ROLE; +-- Partitioned table and one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; +ALTER TABLE vacowned_part1 OWNER TO regress_vacuum; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM vacowned_part1; +VACUUM vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +ANALYZE vacowned_parted; +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +VACUUM (ANALYZE) vacowned_parted; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +RESET ROLE; +-- Only one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO CURRENT_USER; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM vacowned_part1; +VACUUM vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +ANALYZE vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can analyze it +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +VACUUM (ANALYZE) vacowned_parted; +WARNING: skipping "vacowned_parted" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +RESET ROLE; +-- Only partitioned table owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; +ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +VACUUM vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +ANALYZE vacowned_parted; +WARNING: skipping "vacowned_part1" --- only table or database owner can analyze it +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +ANALYZE vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can analyze it +ANALYZE vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can analyze it +VACUUM (ANALYZE) vacowned_parted; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part1; +WARNING: skipping "vacowned_part1" --- only table or database owner can vacuum it +VACUUM (ANALYZE) vacowned_part2; +WARNING: skipping "vacowned_part2" --- only table or database owner can vacuum it +RESET ROLE; +DROP TABLE vacowned; +DROP TABLE vacowned_parted; +DROP ROLE regress_vacuum; diff --git a/src/test/regress/expected/window.out b/src/test/regress/expected/window.out index 85d81e7c9fd..edc93d5729b 100644 --- a/src/test/regress/expected/window.out +++ b/src/test/regress/expected/window.out @@ -204,33 +204,33 @@ SELECT dense_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 (10 rows) SELECT percent_rank() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; - percent_rank | ten | four --------------------+-----+------ - 0 | 0 | 0 - 0 | 0 | 0 - 1 | 4 | 0 - 0 | 1 | 1 - 0 | 1 | 1 - 0.666666666666667 | 7 | 1 - 1 | 9 | 1 - 0 | 0 | 2 - 0 | 1 | 3 - 1 | 3 | 3 + percent_rank | ten | four +--------------------+-----+------ + 0 | 0 | 0 + 0 | 0 | 0 + 1 | 4 | 0 + 0 | 1 | 1 + 0 | 1 | 1 + 0.6666666666666666 | 7 | 1 + 1 | 9 | 1 + 0 | 0 | 2 + 0 | 1 | 3 + 1 | 3 | 3 (10 rows) SELECT cume_dist() OVER (PARTITION BY four ORDER BY ten), ten, four FROM tenk1 WHERE unique2 < 10; - cume_dist | ten | four --------------------+-----+------ - 0.666666666666667 | 0 | 0 - 0.666666666666667 | 0 | 0 - 1 | 4 | 0 - 0.5 | 1 | 1 - 0.5 | 1 | 1 - 0.75 | 7 | 1 - 1 | 9 | 1 - 1 | 0 | 2 - 0.5 | 1 | 3 - 1 | 3 | 3 + cume_dist | ten | four +--------------------+-----+------ + 0.6666666666666666 | 0 | 0 + 0.6666666666666666 | 0 | 0 + 1 | 4 | 0 + 0.5 | 1 | 1 + 0.5 | 1 | 1 + 0.75 | 7 | 1 + 1 | 9 | 1 + 1 | 0 | 2 + 0.5 | 1 | 3 + 1 | 3 | 3 (10 rows) SELECT ntile(3) OVER (ORDER BY ten, four), ten, four FROM tenk1 WHERE unique2 < 10; @@ -504,9 +504,9 @@ SELECT sum(salary), FROM empsalary GROUP BY depname; sum | row_number | sum -------+------------+------- - 14600 | 3 | 14600 - 7400 | 2 | 22000 25100 | 1 | 47100 + 7400 | 2 | 22000 + 14600 | 3 | 14600 (3 rows) -- identical windows with different names @@ -2834,6 +2834,101 @@ SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SEL ------- (0 rows) +-- check some degenerate cases +create temp table t1 (f1 int, f2 int8); +insert into t1 values (1,1),(1,2),(2,2); +select f1, sum(f1) over (partition by f1 + range between 1 preceding and 1 following) +from t1 where f1 = f2; -- error, must have order by +ERROR: RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column +LINE 1: select f1, sum(f1) over (partition by f1 + ^ +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; + QUERY PLAN +--------------------------------- + WindowAgg + -> Sort + Sort Key: f1 + -> Seq Scan on t1 + Filter: (f1 = f2) +(5 rows) + +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | 1 + 2 | 2 +(2 rows) + +select f1, sum(f1) over (partition by f1, f1 order by f2 + range between 2 preceding and 1 preceding) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | + 2 | +(2 rows) + +select f1, sum(f1) over (partition by f1, f2 order by f2 + range between 1 following and 2 following) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | + 2 | +(2 rows) + +select f1, sum(f1) over (partition by f1 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; -- error, must have order by +ERROR: GROUPS mode requires an ORDER BY clause +LINE 1: select f1, sum(f1) over (partition by f1 + ^ +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; + QUERY PLAN +--------------------------------- + WindowAgg + -> Sort + Sort Key: f1 + -> Seq Scan on t1 + Filter: (f1 = f2) +(5 rows) + +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | 1 + 2 | 2 +(2 rows) + +select f1, sum(f1) over (partition by f1, f1 order by f2 + groups between 2 preceding and 1 preceding) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | + 2 | +(2 rows) + +select f1, sum(f1) over (partition by f1, f2 order by f2 + groups between 1 following and 2 following) +from t1 where f1 = f2; + f1 | sum +----+----- + 1 | + 2 | +(2 rows) + -- ordering by a non-integer constant is allowed SELECT rank() OVER (ORDER BY length('abc')); rank @@ -2899,9 +2994,9 @@ SELECT sum(salary), row_number() OVER (ORDER BY depname), sum( FROM empsalary GROUP BY depname; sum | row_number | filtered_sum | depname -------+------------+--------------+----------- - 14600 | 3 | | sales - 7400 | 2 | 3500 | personnel 25100 | 1 | 22600 | develop + 7400 | 2 | 3500 | personnel + 14600 | 3 | | sales (3 rows) -- Test pushdown of quals into a subquery containing window functions @@ -2913,13 +3008,13 @@ SELECT * FROM min(salary) OVER (PARTITION BY depname || 'A', depname) depminsalary FROM empsalary) emp WHERE depname = 'sales'; - QUERY PLAN ---------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------- Subquery Scan on emp -> WindowAgg - -> Sort - Sort Key: (((empsalary.depname)::text || 'A'::text)) - -> WindowAgg + -> WindowAgg + -> Sort + Sort Key: (((empsalary.depname)::text || 'A'::text)) -> Seq Scan on empsalary Filter: ((depname)::text = 'sales'::text) (7 rows) @@ -2932,19 +3027,53 @@ SELECT * FROM min(salary) OVER (PARTITION BY depname) depminsalary FROM empsalary) emp WHERE depname = 'sales'; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------- Subquery Scan on emp Filter: ((emp.depname)::text = 'sales'::text) -> WindowAgg -> Sort - Sort Key: empsalary.depname + Sort Key: empsalary.enroll_date -> WindowAgg -> Sort - Sort Key: empsalary.enroll_date + Sort Key: empsalary.depname -> Seq Scan on empsalary (9 rows) +-- Test Sort node collapsing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary + FROM empsalary) emp +WHERE depname = 'sales'; + QUERY PLAN +---------------------------------------------------------------------- + Subquery Scan on emp + -> WindowAgg + -> WindowAgg + -> Sort + Sort Key: empsalary.empno, empsalary.enroll_date + -> Seq Scan on empsalary + Filter: ((depname)::text = 'sales'::text) +(7 rows) + +-- Test Sort node reordering +EXPLAIN (COSTS OFF) +SELECT + lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), + lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno) +FROM empsalary; + QUERY PLAN +------------------------------------------------------------- + WindowAgg + -> WindowAgg + -> Sort + Sort Key: depname, salary, enroll_date, empno + -> Seq Scan on empsalary +(5 rows) + -- cleanup DROP TABLE empsalary; -- test user-defined window function with named args and default args diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out index 350a34d9870..2a2085556bb 100644 --- a/src/test/regress/expected/with.out +++ b/src/test/regress/expected/with.out @@ -1904,143 +1904,6 @@ RETURNING k, v; (0 rows) DROP TABLE withz; --- WITH referenced by MERGE statement -CREATE TABLE m AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i; -ALTER TABLE m ADD UNIQUE (k); -WITH RECURSIVE cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); -ERROR: WITH RECURSIVE is not supported for MERGE statement --- Basic: -WITH cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); --- Examine -SELECT * FROM m where k = 0; - k | v ----+---------------------- - 0 | merge source SubPlan -(1 row) - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); - QUERY PLAN -------------------------------------------------------------------- - Merge on public.m - CTE cte_basic - -> Result - Output: 1, 'cte_basic val'::text - -> Hash Right Join - Output: o.k, o.v, o.*, m_1.ctid - Hash Cond: (m_1.k = o.k) - -> Seq Scan on public.m m_1 - Output: m_1.ctid, m_1.k - -> Hash - Output: o.k, o.v, o.* - -> Subquery Scan on o - Output: o.k, o.v, o.* - -> Result - Output: 0, 'merge source SubPlan'::text - SubPlan 2 - -> Limit - Output: ((cte_basic.b || ' merge update'::text)) - -> CTE Scan on cte_basic - Output: (cte_basic.b || ' merge update'::text) - Filter: (cte_basic.a = m.k) -(21 rows) - --- InitPlan -WITH cte_init AS (SELECT 1 a, 'cte_init val' b) -MERGE INTO m USING (select 1 k, 'merge source InitPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); --- Examine -SELECT * FROM m where k = 1; - k | v ----+--------------------------- - 1 | cte_init val merge update -(1 row) - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH cte_init AS (SELECT 1 a, 'cte_init val' b) -MERGE INTO m USING (select 1 k, 'merge source InitPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); - QUERY PLAN --------------------------------------------------------------------- - Merge on public.m - CTE cte_init - -> Result - Output: 1, 'cte_init val'::text - InitPlan 2 (returns $1) - -> Limit - Output: ((cte_init.b || ' merge update'::text)) - -> CTE Scan on cte_init - Output: (cte_init.b || ' merge update'::text) - Filter: (cte_init.a = 1) - -> Hash Right Join - Output: o.k, o.v, o.*, m_1.ctid - Hash Cond: (m_1.k = o.k) - -> Seq Scan on public.m m_1 - Output: m_1.ctid, m_1.k - -> Hash - Output: o.k, o.v, o.* - -> Subquery Scan on o - Output: o.k, o.v, o.* - -> Result - Output: 1, 'merge source InitPlan'::text -(21 rows) - --- MERGE source comes from CTE: -WITH merge_source_cte AS (SELECT 15 a, 'merge_source_cte val' b) -MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a -WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) -WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)); --- Examine -SELECT * FROM m where k = 15; - k | v -----+-------------------------------------------------------------- - 15 | merge_source_cte val(15,"merge_source_cte val") merge insert -(1 row) - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH merge_source_cte AS (SELECT 15 a, 'merge_source_cte val' b) -MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a -WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) -WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Merge on public.m - CTE merge_source_cte - -> Result - Output: 15, 'merge_source_cte val'::text - InitPlan 2 (returns $1) - -> CTE Scan on merge_source_cte merge_source_cte_1 - Output: ((merge_source_cte_1.b || (merge_source_cte_1.*)::text) || ' merge update'::text) - Filter: (merge_source_cte_1.a = 15) - InitPlan 3 (returns $2) - -> CTE Scan on merge_source_cte merge_source_cte_2 - Output: ((merge_source_cte_2.*)::text || ' merge insert'::text) - -> Hash Right Join - Output: merge_source_cte.a, merge_source_cte.b, ROW(merge_source_cte.a, merge_source_cte.b), m_1.ctid - Hash Cond: (m_1.k = merge_source_cte.a) - -> Seq Scan on public.m m_1 - Output: m_1.ctid, m_1.k - -> Hash - Output: merge_source_cte.a, merge_source_cte.b - -> CTE Scan on merge_source_cte - Output: merge_source_cte.a, merge_source_cte.b -(20 rows) - -DROP TABLE m; -- check that run to completion happens in proper ordering TRUNCATE TABLE y; INSERT INTO y SELECT generate_series(1, 3); diff --git a/src/test/regress/expected/without_oid.out b/src/test/regress/expected/without_oid.out deleted file mode 100644 index cb2c0c01371..00000000000 --- a/src/test/regress/expected/without_oid.out +++ /dev/null @@ -1,103 +0,0 @@ --- --- WITHOUT OID --- --- --- This test tries to verify that WITHOUT OIDS actually saves space. --- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any --- space, depending on the size of the tuple header + null bitmap. --- As of 8.3 we need a null bitmap of 8 or less bits for the difference --- to appear. --- -CREATE TABLE wi (i INT, - n1 int, n2 int, n3 int, n4 int, - n5 int, n6 int, n7 int) WITH OIDS; -CREATE TABLE wo (i INT, - n1 int, n2 int, n3 int, n4 int, - n5 int, n6 int, n7 int) WITHOUT OIDS; -INSERT INTO wi VALUES (1); -- 1 -INSERT INTO wo SELECT i FROM wi; -- 1 -INSERT INTO wo SELECT i+1 FROM wi; -- 1+1=2 -INSERT INTO wi SELECT i+1 FROM wo; -- 1+2=3 -INSERT INTO wi SELECT i+3 FROM wi; -- 3+3=6 -INSERT INTO wo SELECT i+2 FROM wi; -- 2+6=8 -INSERT INTO wo SELECT i+8 FROM wo; -- 8+8=16 -INSERT INTO wi SELECT i+6 FROM wo; -- 6+16=22 -INSERT INTO wi SELECT i+22 FROM wi; -- 22+22=44 -INSERT INTO wo SELECT i+16 FROM wi; -- 16+44=60 -INSERT INTO wo SELECT i+60 FROM wo; -- 60+60=120 -INSERT INTO wi SELECT i+44 FROM wo; -- 44+120=164 -INSERT INTO wi SELECT i+164 FROM wi; -- 164+164=328 -INSERT INTO wo SELECT i+120 FROM wi; -- 120+328=448 -INSERT INTO wo SELECT i+448 FROM wo; -- 448+448=896 -INSERT INTO wi SELECT i+328 FROM wo; -- 328+896=1224 -INSERT INTO wi SELECT i+1224 FROM wi; -- 1224+1224=2448 -INSERT INTO wo SELECT i+896 FROM wi; -- 896+2448=3344 -INSERT INTO wo SELECT i+3344 FROM wo; -- 3344+3344=6688 -INSERT INTO wi SELECT i+2448 FROM wo; -- 2448+6688=9136 -INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448; -- 6688+2448=9136 -SELECT count(oid) FROM wi; - count -------- - 9136 -(1 row) - --- should fail -SELECT count(oid) FROM wo; -ERROR: column "oid" does not exist -LINE 1: SELECT count(oid) FROM wo; - ^ -VACUUM ANALYZE wi; -VACUUM ANALYZE wo; -SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples) - FROM pg_class - WHERE relname IN ('wi', 'wo'); - ?column? | ?column? -----------+---------- - t | 0 -(1 row) - -DROP TABLE wi; -DROP TABLE wo; --- --- WITH / WITHOUT OIDS in CREATE TABLE AS --- -CREATE TABLE create_table_test ( - a int, - b int -); -COPY create_table_test FROM stdin; -CREATE TABLE create_table_test2 WITH OIDS AS - SELECT a + b AS c1, a - b AS c2 FROM create_table_test; -CREATE TABLE create_table_test3 WITHOUT OIDS AS - SELECT a + b AS c1, a - b AS c2 FROM create_table_test; -SELECT count(oid) FROM create_table_test2; - count -------- - 2 -(1 row) - --- should fail -SELECT count(oid) FROM create_table_test3; -ERROR: column "oid" does not exist -LINE 1: SELECT count(oid) FROM create_table_test3; - ^ -PREPARE table_source(int) AS - SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test; -CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1); -CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2); -SELECT count(oid) FROM execute_with; - count -------- - 2 -(1 row) - --- should fail -SELECT count(oid) FROM execute_without; -ERROR: column "oid" does not exist -LINE 1: SELECT count(oid) FROM execute_without; - ^ -DROP TABLE create_table_test; -DROP TABLE create_table_test2; -DROP TABLE create_table_test3; -DROP TABLE execute_with; -DROP TABLE execute_without; diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 7fa13091087..11e7d7faf37 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -532,6 +532,13 @@ LINE 1: EXECUTE foo ('bad'); DETAIL: line 1: Start tag expected, '<' not found bad ^ +SELECT xml '
'; +ERROR: invalid XML document +LINE 1: SELECT xml ''; + ^ +DETAIL: line 1: Extra content at the end of the document + + ^ SET XML OPTION CONTENT; EXECUTE foo (''); xmlconcat @@ -545,6 +552,45 @@ EXECUTE foo ('good'); good (1 row) +SELECT xml ' '; + xml +-------------------------------------------------------------------- + +(1 row) + +SELECT xml ' '; + xml +------------------------------ + +(1 row) + +SELECT xml ''; + xml +------------------ + +(1 row) + +SELECT xml ' oops '; +ERROR: invalid XML content +LINE 1: SELECT xml ' oops '; + ^ +DETAIL: line 1: StartTag: invalid element name + oops + ^ +SELECT xml ' '; +ERROR: invalid XML content +LINE 1: SELECT xml ' '; + ^ +DETAIL: line 1: StartTag: invalid element name + + ^ +SELECT xml ''; +ERROR: invalid XML content +LINE 1: SELECT xml ''; + ^ +DETAIL: line 1: Extra content at the end of the document + + ^ -- Test backwards parsing CREATE VIEW xmlview1 AS SELECT xmlcomment('test'); CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you'); @@ -608,12 +654,9 @@ SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); - xpath --------------------------------------------------------------------------------------- - {"+ - number one + - + - ",""} + xpath +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"number one",""} (1 row) SELECT xpath('//b', 'one two three etc'); @@ -670,6 +713,12 @@ SELECT xpath('/nosuchtag', ''); {} (1 row) +SELECT xpath('root', ''); + xpath +----------- + {} +(1 row) + -- Round-trip non-ASCII data through xpath(). DO $$ DECLARE @@ -1024,7 +1073,7 @@ SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -1046,7 +1095,7 @@ CREATE VIEW xmltableview1 AS SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -1075,7 +1124,7 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS "xmltable".premier_name FROM ( SELECT xmldata.data FROM xmldata) x, - LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; QUERY PLAN ----------------------------------------- @@ -1085,15 +1134,15 @@ EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Nested Loop Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data -> Table Function Scan on "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name - Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) -- XMLNAMESPACES tests @@ -1204,15 +1253,15 @@ SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" (2 rows) SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text); - element -------------------- - a1aa2a bbbbcccc + element +---------------------- + a1aa2a bbbbxxxcccc (1 row) SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()'); -- should fail ERROR: more than one value returned by column XPath expression -- CDATA test -select * from xmltable('r' passing ' &"<>!foo]]>2' columns c text); +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text); c ------------------------- &"<>!foo @@ -1487,3 +1536,24 @@ SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c 14 (4 rows) +-- XPath result can be boolean or number too +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)'); + a | b | c | d | e +----------+---+----+---+--- + a | a | hi | t | 1 +(1 row) + +\x +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH 'node()', y xml PATH '/'); +-[ RECORD 1 ]----------------------------------------------------------- +x | pre&deeppost +y | pre&deeppost+ + | + +\x +SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '""', b xml PATH '""'); + a | b +--------+-------------- + | <foo/> +(1 row) + diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 970ab26fcef..d1a03b51a3d 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -429,11 +429,53 @@ EXECUTE foo (''); ERROR: prepared statement "foo" does not exist EXECUTE foo ('bad'); ERROR: prepared statement "foo" does not exist +SELECT xml ''; +ERROR: unsupported XML feature +LINE 1: SELECT xml ''; + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. SET XML OPTION CONTENT; EXECUTE foo (''); ERROR: prepared statement "foo" does not exist EXECUTE foo ('good'); ERROR: prepared statement "foo" does not exist +SELECT xml ' '; +ERROR: unsupported XML feature +LINE 1: SELECT xml ' '; +ERROR: unsupported XML feature +LINE 1: SELECT xml ' '; +ERROR: unsupported XML feature +LINE 1: SELECT xml ''; + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xml ' oops '; +ERROR: unsupported XML feature +LINE 1: SELECT xml ' oops '; + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xml ' '; +ERROR: unsupported XML feature +LINE 1: SELECT xml ' '; + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xml ''; +ERROR: unsupported XML feature +LINE 1: SELECT xml ''; + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. -- Test backwards parsing CREATE VIEW xmlview1 AS SELECT xmlcomment('test'); CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you'); @@ -576,6 +618,12 @@ LINE 1: SELECT xpath('/nosuchtag', ''); ^ DETAIL: This functionality requires the server to be built with libxml support. HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xpath('root', ''); +ERROR: unsupported XML feature +LINE 1: SELECT xpath('root', ''); + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. -- Round-trip non-ASCII data through xpath(). DO $$ DECLARE @@ -908,7 +956,7 @@ SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -924,7 +972,7 @@ CREATE VIEW xmltableview1 AS SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -947,7 +995,7 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS "xmltable".premier_name FROM ( SELECT xmldata.data FROM xmldata) x, - LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; QUERY PLAN ----------------------------------------- @@ -957,15 +1005,15 @@ EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Nested Loop Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data -> Table Function Scan on "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name - Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) -- XMLNAMESPACES tests @@ -1067,10 +1115,10 @@ LINE 1: SELECT * FROM xmltable('/root' passing 'a1a &"<>!foo]]>2' columns c text); +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text); ERROR: unsupported XML feature -LINE 1: select * from xmltable('r' passing 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)'); +ERROR: unsupported XML feature +LINE 1: SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml ... + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. +\x +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH 'node()', y xml PATH '/'); +ERROR: unsupported XML feature +LINE 1: SELECT * FROM XMLTABLE('*' PASSING 'pre"', b xml PATH '""'); +ERROR: unsupported XML feature +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. diff --git a/src/test/regress/expected/xml_2.out b/src/test/regress/expected/xml_2.out index 112ebe47cd0..4d200274691 100644 --- a/src/test/regress/expected/xml_2.out +++ b/src/test/regress/expected/xml_2.out @@ -512,6 +512,13 @@ LINE 1: EXECUTE foo ('bad'); DETAIL: line 1: Start tag expected, '<' not found bad ^ +SELECT xml ''; +ERROR: invalid XML document +LINE 1: SELECT xml ''; + ^ +DETAIL: line 1: Extra content at the end of the document + + ^ SET XML OPTION CONTENT; EXECUTE foo (''); xmlconcat @@ -525,6 +532,45 @@ EXECUTE foo ('good'); good (1 row) +SELECT xml ' '; + xml +-------------------------------------------------------------------- + +(1 row) + +SELECT xml ' '; + xml +------------------------------ + +(1 row) + +SELECT xml ''; + xml +------------------ + +(1 row) + +SELECT xml ' oops '; +ERROR: invalid XML content +LINE 1: SELECT xml ' oops '; + ^ +DETAIL: line 1: StartTag: invalid element name + oops + ^ +SELECT xml ' '; +ERROR: invalid XML content +LINE 1: SELECT xml ' '; + ^ +DETAIL: line 1: StartTag: invalid element name + + ^ +SELECT xml ''; +ERROR: invalid XML content +LINE 1: SELECT xml ''; + ^ +DETAIL: line 1: Extra content at the end of the document + + ^ -- Test backwards parsing CREATE VIEW xmlview1 AS SELECT xmlcomment('test'); CREATE VIEW xmlview2 AS SELECT xmlconcat('hello', 'you'); @@ -588,12 +634,9 @@ SELECT xpath('//loc:piece', 'number one', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); - xpath --------------------------------------------------------------------------------------- - {"+ - number one + - + - ",""} + xpath +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {"number one",""} (1 row) SELECT xpath('//b', 'one two three etc'); @@ -650,6 +693,12 @@ SELECT xpath('/nosuchtag', ''); {} (1 row) +SELECT xpath('root', ''); + xpath +----------- + {} +(1 row) + -- Round-trip non-ASCII data through xpath(). DO $$ DECLARE @@ -1004,7 +1053,7 @@ SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -1026,7 +1075,7 @@ CREATE VIEW xmltableview1 AS SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -1055,7 +1104,7 @@ CREATE OR REPLACE VIEW public.xmltableview1 AS "xmltable".premier_name FROM ( SELECT xmldata.data FROM xmldata) x, - LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + LATERAL XMLTABLE(('/ROWS/ROW'::text) PASSING (x.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; QUERY PLAN ----------------------------------------- @@ -1065,15 +1114,15 @@ EXPLAIN (COSTS OFF) SELECT * FROM xmltableview1; (3 rows) EXPLAIN (COSTS OFF, VERBOSE) SELECT * FROM xmltableview1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Nested Loop Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name -> Seq Scan on public.xmldata Output: xmldata.data -> Table Function Scan on "xmltable" Output: "xmltable".id, "xmltable"._id, "xmltable".country_name, "xmltable".country_id, "xmltable".region_id, "xmltable".size, "xmltable".unit, "xmltable".premier_name - Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) + Table Function Call: XMLTABLE(('/ROWS/ROW'::text) PASSING (xmldata.data) COLUMNS id integer PATH ('@id'::text), _id FOR ORDINALITY, country_name text PATH ('COUNTRY_NAME/text()'::text) NOT NULL, country_id text PATH ('COUNTRY_ID'::text), region_id integer PATH ('REGION_ID'::text), size double precision PATH ('SIZE'::text), unit text PATH ('SIZE/@unit'::text), premier_name text DEFAULT ('not specified'::text) PATH ('PREMIER_NAME'::text)) (7 rows) -- XMLNAMESPACES tests @@ -1184,15 +1233,15 @@ SELECT xmltable.* FROM xmldata, LATERAL xmltable('/ROWS/ROW[COUNTRY_NAME="Japan" (2 rows) SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text); - element -------------------- - a1aa2a bbbbcccc + element +---------------------- + a1aa2a bbbbxxxcccc (1 row) SELECT * FROM xmltable('/root' passing 'a1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()'); -- should fail ERROR: more than one value returned by column XPath expression -- CDATA test -select * from xmltable('r' passing ' &"<>!foo]]>2' columns c text); +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text); c ------------------------- &"<>!foo @@ -1467,3 +1516,24 @@ SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c 14 (4 rows) +-- XPath result can be boolean or number too +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)'); + a | b | c | d | e +----------+---+----+---+--- + a | a | hi | t | 1 +(1 row) + +\x +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH 'node()', y xml PATH '/'); +-[ RECORD 1 ]----------------------------------------------------------- +x | pre&deeppost +y | pre&deeppost+ + | + +\x +SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '""', b xml PATH '""'); + a | b +--------+-------------- + | <foo/> +(1 row) + diff --git a/src/test/regress/input/constraints.source b/src/test/regress/input/constraints.source index 98dd4210e99..c325b2753d4 100644 --- a/src/test/regress/input/constraints.source +++ b/src/test/regress/input/constraints.source @@ -201,7 +201,7 @@ DELETE FROM INSERT_TBL; ALTER SEQUENCE INSERT_SEQ RESTART WITH 4; -CREATE TABLE tmp (xd INT, yd TEXT, zd INT); +CREATE TEMP TABLE tmp (xd INT, yd TEXT, zd INT); INSERT INTO tmp VALUES (null, 'Y', null); INSERT INTO tmp VALUES (5, '!check failed', null); @@ -518,6 +518,10 @@ ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =); DROP TABLE deferred_excl; -- Comments +-- Setup a low-level role to enforce non-superuser checks. +CREATE ROLE regress_constraint_comments; +SET SESSION AUTHORIZATION regress_constraint_comments; + CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0)); CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0); @@ -535,5 +539,16 @@ COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad c COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL; COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL; +-- unauthorized user +RESET SESSION AUTHORIZATION; +CREATE ROLE regress_constraint_comments_noaccess; +SET SESSION AUTHORIZATION regress_constraint_comments_noaccess; +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment'; +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment'; +RESET SESSION AUTHORIZATION; + DROP TABLE constraint_comments_tbl; DROP DOMAIN constraint_comments_dom; + +DROP ROLE regress_constraint_comments; +DROP ROLE regress_constraint_comments_noaccess; diff --git a/src/test/regress/input/copy.source b/src/test/regress/input/copy.source index cb13606d141..a1d529ad367 100644 --- a/src/test/regress/input/copy.source +++ b/src/test/regress/input/copy.source @@ -133,3 +133,71 @@ this is just a line full of junk that would error out if parsed \. copy copytest3 to stdout csv header; + +-- test copy from with a partitioned table +create table parted_copytest ( + a int, + b int, + c text +) partition by list (b); + +create table parted_copytest_a1 (c text, b int, a int); +create table parted_copytest_a2 (a int, c text, b int); + +alter table parted_copytest attach partition parted_copytest_a1 for values in(1); +alter table parted_copytest attach partition parted_copytest_a2 for values in(2); + +-- We must insert enough rows to trigger multi-inserts. These are only +-- enabled adaptively when there are few enough partition changes. +insert into parted_copytest select x,1,'One' from generate_series(1,1000) x; +insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x; +insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x; + +copy (select * from parted_copytest order by a) to '@abs_builddir@/results/parted_copytest.csv'; + +truncate parted_copytest; + +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv'; + +-- Ensure COPY FREEZE errors for partitioned tables. +begin; +truncate parted_copytest; +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze); +rollback; + +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + +truncate parted_copytest; + +-- create before insert row trigger on parted_copytest_a2 +create function part_ins_func() returns trigger language plpgsql as $$ +begin + return new; +end; +$$; + +create trigger part_ins_trig + before insert on parted_copytest_a2 + for each row + execute procedure part_ins_func(); + +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv'; + +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + +truncate table parted_copytest; +create index on parted_copytest (b); +drop trigger part_ins_trig on parted_copytest_a2; + +copy parted_copytest from stdin; +1 1 str1 +2 2 str2 +\. + +-- Ensure index entries were properly added during the copy. +select * from parted_copytest where b = 1; +select * from parted_copytest where b = 2; + +drop table parted_copytest; diff --git a/src/test/regress/input/create_function_1.source b/src/test/regress/input/create_function_1.source index 26e2227d3af..223454a5eab 100644 --- a/src/test/regress/input/create_function_1.source +++ b/src/test/regress/input/create_function_1.source @@ -68,6 +68,11 @@ CREATE FUNCTION test_fdw_handler() AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' LANGUAGE C; +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' + LANGUAGE C STRICT; + -- Things that shouldn't work: CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL diff --git a/src/test/regress/input/largeobject.source b/src/test/regress/input/largeobject.source index b7a9d052bde..7e45b1172ad 100644 --- a/src/test/regress/input/largeobject.source +++ b/src/test/regress/input/largeobject.source @@ -203,12 +203,12 @@ END; SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_values; -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid :LASTOID -- just make sure \lo_export does not barf -\lo_export :newloid 'results/lotest2.txt' +\lo_export :newloid '@abs_builddir@/results/lotest2.txt' -- This is a hack to test that export/import are reversible -- This uses knowledge about the inner workings of large object mechanism @@ -223,7 +223,7 @@ TRUNCATE lotest_stash_values; \lo_unlink :newloid -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid_1 :LASTOID diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source index 7f7934b745c..a5f61a35dc5 100644 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/input/tablespace.source @@ -44,24 +44,97 @@ CREATE INDEX foo_idx on testschema.foo(i) TABLESPACE regress_tblspace; SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c where c.reltablespace = t.oid AND c.relname = 'foo_idx'; +-- check \d output +\d testschema.foo +\d testschema.foo_idx + +-- +-- partitioned table +-- +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +RESET default_tablespace; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +SET default_tablespace TO regress_tblspace; +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default; +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a); +ALTER TABLE testschema.part SET TABLESPACE pg_default; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace; +RESET default_tablespace; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); + +SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) + LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname; +RESET default_tablespace; +DROP TABLE testschema.part; + +-- partitioned index +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); +CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1); +CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace; +CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2); +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx'; +\d testschema.part +\d+ testschema.part +\d testschema.part1 +\d+ testschema.part1 +\d testschema.part_a_idx +\d+ testschema.part_a_idx + +-- partitioned rels cannot specify the default tablespace. These fail: +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default; +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY LIST (a); +SET default_tablespace TO 'pg_default'; +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace; +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a); +-- but these work: +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) TABLESPACE regress_tblspace; +SET default_tablespace TO ''; +CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a); +DROP TABLE testschema.dflt, testschema.dflt2; + -- check that default_tablespace doesn't affect ALTER TABLE index rebuilds CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace; INSERT INTO testschema.test_default_tab VALUES (1); CREATE INDEX test_index1 on testschema.test_default_tab (id); CREATE INDEX test_index2 on testschema.test_default_tab (id) TABLESPACE regress_tblspace; +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id); +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; + \d testschema.test_index1 \d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 -- use a custom tablespace for default_tablespace SET default_tablespace TO regress_tblspace; -- tablespace should not change if no rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; \d testschema.test_index1 \d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 SELECT * FROM testschema.test_default_tab; -- tablespace should not change even if there is an index rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE int; \d testschema.test_index1 \d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 SELECT * FROM testschema.test_default_tab; -- now use the default tablespace for default_tablespace SET default_tablespace TO ''; @@ -69,12 +142,64 @@ SET default_tablespace TO ''; ALTER TABLE testschema.test_default_tab ALTER id TYPE int; \d testschema.test_index1 \d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 -- tablespace should not change even if there is an index rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; \d testschema.test_index1 \d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 DROP TABLE testschema.test_default_tab; +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +-- (this time with a partitioned table) +CREATE TABLE testschema.test_default_tab_p(id bigint, val bigint) + PARTITION BY LIST (id) TABLESPACE regress_tblspace; +CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p + FOR VALUES IN (1); +INSERT INTO testschema.test_default_tab_p VALUES (1); +CREATE INDEX test_index1 on testschema.test_default_tab_p (val); +CREATE INDEX test_index2 on testschema.test_default_tab_p (val) TABLESPACE regress_tblspace; +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id); +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; + +\d testschema.test_index1 +\d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace; +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; +\d testschema.test_index1 +\d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 +SELECT * FROM testschema.test_default_tab_p; +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; +\d testschema.test_index1 +\d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 +SELECT * FROM testschema.test_default_tab_p; +-- now use the default tablespace for default_tablespace +SET default_tablespace TO ''; +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; +\d testschema.test_index1 +\d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; +\d testschema.test_index1 +\d testschema.test_index2 +\d testschema.test_index3 +\d testschema.test_index4 +DROP TABLE testschema.test_default_tab_p; + -- check that default_tablespace affects index additions in ALTER TABLE CREATE TABLE testschema.test_tab(id int) TABLESPACE regress_tblspace; INSERT INTO testschema.test_tab VALUES (1); @@ -87,12 +212,32 @@ ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id); SELECT * FROM testschema.test_tab; DROP TABLE testschema.test_tab; +-- check that default_tablespace is handled correctly by multi-command +-- ALTER TABLE that includes a tablespace-preserving rewrite +CREATE TABLE testschema.test_tab(a int, b int, c int); +SET default_tablespace TO regress_tblspace; +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a); +CREATE INDEX test_tab_a_idx ON testschema.test_tab (a); +SET default_tablespace TO ''; +CREATE INDEX test_tab_b_idx ON testschema.test_tab (b); +\d testschema.test_tab_unique +\d testschema.test_tab_a_idx +\d testschema.test_tab_b_idx +ALTER TABLE testschema.test_tab ALTER b TYPE bigint, ADD UNIQUE (c); +\d testschema.test_tab_unique +\d testschema.test_tab_a_idx +\d testschema.test_tab_b_idx +DROP TABLE testschema.test_tab; + -- let's try moving a table from one place to another CREATE TABLE testschema.atable AS VALUES (1), (2); CREATE UNIQUE INDEX anindex ON testschema.atable(column1); ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace; ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace; +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global; +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default; +ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace; INSERT INTO testschema.atable VALUES(3); -- ok INSERT INTO testschema.atable VALUES(1); -- fail (checks index) diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source index a6a1df18e73..e27caedcabb 100644 --- a/src/test/regress/output/constraints.source +++ b/src/test/regress/output/constraints.source @@ -228,6 +228,8 @@ CREATE TABLE SYS_COL_CHECK_TBL (city text, state text, is_capital bool, altitude int, CHECK (NOT (is_capital AND ctid::text = 'sys_col_check_tbl'))); ERROR: system column "ctid" reference in check constraint is invalid +LINE 3: CHECK (NOT (is_capital AND ctid::text = 'sys_col_check... + ^ -- -- Check inheritance of defaults and constraints -- @@ -289,7 +291,7 @@ NOTICE: drop cascades to table atacc2 -- DELETE FROM INSERT_TBL; ALTER SEQUENCE INSERT_SEQ RESTART WITH 4; -CREATE TABLE tmp (xd INT, yd TEXT, zd INT); +CREATE TEMP TABLE tmp (xd INT, yd TEXT, zd INT); INSERT INTO tmp VALUES (null, 'Y', null); INSERT INTO tmp VALUES (5, '!check failed', null); INSERT INTO tmp VALUES (null, 'try again', null); @@ -702,6 +704,9 @@ ERROR: could not create exclusion constraint "deferred_excl_f1_excl" DETAIL: Key (f1)=(3) conflicts with key (f1)=(3). DROP TABLE deferred_excl; -- Comments +-- Setup a low-level role to enforce non-superuser checks. +CREATE ROLE regress_constraint_comments; +SET SESSION AUTHORIZATION regress_constraint_comments; CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0)); CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0); COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment'; @@ -718,5 +723,16 @@ COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad c ERROR: type "no_comments_dom" does not exist COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL; COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL; +-- unauthorized user +RESET SESSION AUTHORIZATION; +CREATE ROLE regress_constraint_comments_noaccess; +SET SESSION AUTHORIZATION regress_constraint_comments_noaccess; +COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment'; +ERROR: must be owner of relation constraint_comments_tbl +COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment'; +ERROR: must be owner of type constraint_comments_dom +RESET SESSION AUTHORIZATION; DROP TABLE constraint_comments_tbl; DROP DOMAIN constraint_comments_dom; +DROP ROLE regress_constraint_comments; +DROP ROLE regress_constraint_comments_noaccess; diff --git a/src/test/regress/output/copy.source b/src/test/regress/output/copy.source index b7e372d61b4..938d3551da2 100644 --- a/src/test/regress/output/copy.source +++ b/src/test/regress/output/copy.source @@ -95,3 +95,73 @@ copy copytest3 to stdout csv header; c1,"col with , comma","col with "" quote" 1,a,1 2,b,2 +-- test copy from with a partitioned table +create table parted_copytest ( + a int, + b int, + c text +) partition by list (b); +create table parted_copytest_a1 (c text, b int, a int); +create table parted_copytest_a2 (a int, c text, b int); +alter table parted_copytest attach partition parted_copytest_a1 for values in(1); +alter table parted_copytest attach partition parted_copytest_a2 for values in(2); +-- We must insert enough rows to trigger multi-inserts. These are only +-- enabled adaptively when there are few enough partition changes. +insert into parted_copytest select x,1,'One' from generate_series(1,1000) x; +insert into parted_copytest select x,2,'Two' from generate_series(1001,1010) x; +insert into parted_copytest select x,1,'One' from generate_series(1011,1020) x; +copy (select * from parted_copytest order by a) to '@abs_builddir@/results/parted_copytest.csv'; +truncate parted_copytest; +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv'; +-- Ensure COPY FREEZE errors for partitioned tables. +begin; +truncate parted_copytest; +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv' (freeze); +ERROR: cannot perform COPY FREEZE on a partitioned table +rollback; +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + tableoid | count | sum +--------------------+-------+-------- + parted_copytest_a1 | 1010 | 510655 + parted_copytest_a2 | 10 | 10055 +(2 rows) + +truncate parted_copytest; +-- create before insert row trigger on parted_copytest_a2 +create function part_ins_func() returns trigger language plpgsql as $$ +begin + return new; +end; +$$; +create trigger part_ins_trig + before insert on parted_copytest_a2 + for each row + execute procedure part_ins_func(); +copy parted_copytest from '@abs_builddir@/results/parted_copytest.csv'; +select tableoid::regclass,count(*),sum(a) from parted_copytest +group by tableoid order by tableoid::regclass::name; + tableoid | count | sum +--------------------+-------+-------- + parted_copytest_a1 | 1010 | 510655 + parted_copytest_a2 | 10 | 10055 +(2 rows) + +truncate table parted_copytest; +create index on parted_copytest (b); +drop trigger part_ins_trig on parted_copytest_a2; +copy parted_copytest from stdin; +-- Ensure index entries were properly added during the copy. +select * from parted_copytest where b = 1; + a | b | c +---+---+------ + 1 | 1 | str1 +(1 row) + +select * from parted_copytest where b = 2; + a | b | c +---+---+------ + 2 | 2 | str2 +(1 row) + +drop table parted_copytest; diff --git a/src/test/regress/output/create_function_1.source b/src/test/regress/output/create_function_1.source index 8c50d9b3099..5f43e8de81f 100644 --- a/src/test/regress/output/create_function_1.source +++ b/src/test/regress/output/create_function_1.source @@ -60,6 +60,10 @@ CREATE FUNCTION test_fdw_handler() RETURNS fdw_handler AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' LANGUAGE C; +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' + LANGUAGE C STRICT; -- Things that shouldn't work: CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL AS 'SELECT ''not an integer'';'; diff --git a/src/test/regress/output/largeobject.source b/src/test/regress/output/largeobject.source index e29f5423aa3..761d7ff3015 100644 --- a/src/test/regress/output/largeobject.source +++ b/src/test/regress/output/largeobject.source @@ -385,10 +385,10 @@ SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_va 1 (1 row) -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid :LASTOID -- just make sure \lo_export does not barf -\lo_export :newloid 'results/lotest2.txt' +\lo_export :newloid '@abs_builddir@/results/lotest2.txt' -- This is a hack to test that export/import are reversible -- This uses knowledge about the inner workings of large object mechanism -- which should not be used outside it. This makes it a HACK @@ -407,7 +407,7 @@ SELECT lo_unlink(loid) FROM lotest_stash_values; TRUNCATE lotest_stash_values; \lo_unlink :newloid -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid_1 :LASTOID SELECT lo_from_bytea(0, lo_get(:newloid_1)) AS newloid_2 \gset diff --git a/src/test/regress/output/largeobject_1.source b/src/test/regress/output/largeobject_1.source index 6fd8cbe0980..7de3e7ea6f6 100644 --- a/src/test/regress/output/largeobject_1.source +++ b/src/test/regress/output/largeobject_1.source @@ -385,10 +385,10 @@ SELECT lo_export(loid, '@abs_builddir@/results/lotest.txt') FROM lotest_stash_va 1 (1 row) -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid :LASTOID -- just make sure \lo_export does not barf -\lo_export :newloid 'results/lotest2.txt' +\lo_export :newloid '@abs_builddir@/results/lotest2.txt' -- This is a hack to test that export/import are reversible -- This uses knowledge about the inner workings of large object mechanism -- which should not be used outside it. This makes it a HACK @@ -407,7 +407,7 @@ SELECT lo_unlink(loid) FROM lotest_stash_values; TRUNCATE lotest_stash_values; \lo_unlink :newloid -\lo_import 'results/lotest.txt' +\lo_import '@abs_builddir@/results/lotest.txt' \set newloid_1 :LASTOID SELECT lo_from_bytea(0, lo_get(:newloid_1)) AS newloid_2 \gset diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source index 24435118bcb..162b591b315 100644 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/output/tablespace.source @@ -61,45 +61,230 @@ SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c foo_idx | regress_tblspace (1 row) +-- check \d output +\d testschema.foo + Table "testschema.foo" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + i | integer | | | +Indexes: + "foo_idx" btree (i), tablespace "regress_tblspace" +Tablespace: "regress_tblspace" + +\d testschema.foo_idx + Index "testschema.foo_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + i | integer | yes | i +btree, for table "testschema.foo" +Tablespace: "regress_tblspace" + +-- +-- partitioned table +-- +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +ERROR: only shared relations can be placed in pg_global tablespace +RESET default_tablespace; +CREATE TABLE testschema.part_1 PARTITION OF testschema.part FOR VALUES IN (1); +SET default_tablespace TO regress_tblspace; +CREATE TABLE testschema.part_2 PARTITION OF testschema.part FOR VALUES IN (2); +SET default_tablespace TO pg_global; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +ERROR: only shared relations can be placed in pg_global tablespace +ALTER TABLE testschema.part SET TABLESPACE regress_tblspace; +CREATE TABLE testschema.part_3 PARTITION OF testschema.part FOR VALUES IN (3); +CREATE TABLE testschema.part_4 PARTITION OF testschema.part FOR VALUES IN (4) + TABLESPACE pg_default; +CREATE TABLE testschema.part_56 PARTITION OF testschema.part FOR VALUES IN (5, 6) + PARTITION BY LIST (a); +ALTER TABLE testschema.part SET TABLESPACE pg_default; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); +ERROR: only shared relations can be placed in pg_global tablespace +CREATE TABLE testschema.part_910 PARTITION OF testschema.part FOR VALUES IN (9, 10) + PARTITION BY LIST (a) TABLESPACE regress_tblspace; +RESET default_tablespace; +CREATE TABLE testschema.part_78 PARTITION OF testschema.part FOR VALUES IN (7, 8) + PARTITION BY LIST (a); +SELECT relname, spcname FROM pg_catalog.pg_class c + JOIN pg_catalog.pg_namespace n ON (c.relnamespace = n.oid) + LEFT JOIN pg_catalog.pg_tablespace t ON c.reltablespace = t.oid + where c.relname LIKE 'part%' AND n.nspname = 'testschema' order by relname; + relname | spcname +----------+------------------ + part | + part_1 | + part_2 | regress_tblspace + part_3 | regress_tblspace + part_4 | + part_56 | regress_tblspace + part_78 | + part_910 | regress_tblspace +(8 rows) + +RESET default_tablespace; +DROP TABLE testschema.part; +-- partitioned index +CREATE TABLE testschema.part (a int) PARTITION BY LIST (a); +CREATE TABLE testschema.part1 PARTITION OF testschema.part FOR VALUES IN (1); +CREATE INDEX part_a_idx ON testschema.part (a) TABLESPACE regress_tblspace; +CREATE TABLE testschema.part2 PARTITION OF testschema.part FOR VALUES IN (2); +SELECT relname, spcname FROM pg_catalog.pg_tablespace t, pg_catalog.pg_class c + where c.reltablespace = t.oid AND c.relname LIKE 'part%_idx'; + relname | spcname +-------------+------------------ + part1_a_idx | regress_tblspace + part2_a_idx | regress_tblspace + part_a_idx | regress_tblspace +(3 rows) + +\d testschema.part + Partitioned table "testschema.part" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition key: LIST (a) +Indexes: + "part_a_idx" btree (a), tablespace "regress_tblspace" +Number of partitions: 2 (Use \d+ to list them.) + +\d+ testschema.part + Partitioned table "testschema.part" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | +Partition key: LIST (a) +Indexes: + "part_a_idx" btree (a), tablespace "regress_tblspace" +Partitions: testschema.part1 FOR VALUES IN (1), + testschema.part2 FOR VALUES IN (2) + +\d testschema.part1 + Table "testschema.part1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | +Partition of: testschema.part FOR VALUES IN (1) +Indexes: + "part1_a_idx" btree (a), tablespace "regress_tblspace" + +\d+ testschema.part1 + Table "testschema.part1" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | | | plain | | +Partition of: testschema.part FOR VALUES IN (1) +Partition constraint: ((a IS NOT NULL) AND (a = 1)) +Indexes: + "part1_a_idx" btree (a), tablespace "regress_tblspace" + +\d testschema.part_a_idx +Partitioned index "testschema.part_a_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + a | integer | yes | a +btree, for table "testschema.part" +Number of partitions: 2 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d+ testschema.part_a_idx + Partitioned index "testschema.part_a_idx" + Column | Type | Key? | Definition | Storage | Stats target +--------+---------+------+------------+---------+-------------- + a | integer | yes | a | plain | +btree, for table "testschema.part" +Partitions: testschema.part1_a_idx, + testschema.part2_a_idx +Tablespace: "regress_tblspace" + +-- partitioned rels cannot specify the default tablespace. These fail: +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE pg_default; +ERROR: cannot specify default tablespace for partitioned relations +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE pg_default) PARTITION BY LIST (a); +ERROR: cannot specify default tablespace for partitioned relations +SET default_tablespace TO 'pg_default'; +CREATE TABLE testschema.dflt (a int PRIMARY KEY) PARTITION BY LIST (a) TABLESPACE regress_tblspace; +ERROR: cannot specify default tablespace for partitioned relations +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a); +ERROR: cannot specify default tablespace for partitioned relations +-- but these work: +CREATE TABLE testschema.dflt (a int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace) PARTITION BY LIST (a) TABLESPACE regress_tblspace; +SET default_tablespace TO ''; +CREATE TABLE testschema.dflt2 (a int PRIMARY KEY) PARTITION BY LIST (a); +DROP TABLE testschema.dflt, testschema.dflt2; -- check that default_tablespace doesn't affect ALTER TABLE index rebuilds CREATE TABLE testschema.test_default_tab(id bigint) TABLESPACE regress_tblspace; INSERT INTO testschema.test_default_tab VALUES (1); CREATE INDEX test_index1 on testschema.test_default_tab (id); CREATE INDEX test_index2 on testschema.test_default_tab (id) TABLESPACE regress_tblspace; +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index3 PRIMARY KEY (id); +ALTER TABLE testschema.test_default_tab ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; \d testschema.test_index1 -Index "testschema.test_index1" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" \d testschema.test_index2 -Index "testschema.test_index2" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" Tablespace: "regress_tblspace" +\d testschema.test_index3 + Index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab" + +\d testschema.test_index4 + Index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab" +Tablespace: "regress_tblspace" + -- use a custom tablespace for default_tablespace SET default_tablespace TO regress_tblspace; -- tablespace should not change if no rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; \d testschema.test_index1 -Index "testschema.test_index1" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" \d testschema.test_index2 -Index "testschema.test_index2" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" Tablespace: "regress_tblspace" +\d testschema.test_index3 + Index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab" + +\d testschema.test_index4 + Index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab" +Tablespace: "regress_tblspace" + SELECT * FROM testschema.test_default_tab; id ---- @@ -109,20 +294,35 @@ SELECT * FROM testschema.test_default_tab; -- tablespace should not change even if there is an index rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE int; \d testschema.test_index1 -Index "testschema.test_index1" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_index1" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id btree, for table "testschema.test_default_tab" \d testschema.test_index2 -Index "testschema.test_index2" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_index2" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id btree, for table "testschema.test_default_tab" Tablespace: "regress_tblspace" +\d testschema.test_index3 + Index "testschema.test_index3" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id +primary key, btree, for table "testschema.test_default_tab" + +\d testschema.test_index4 + Index "testschema.test_index4" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id +unique, btree, for table "testschema.test_default_tab" +Tablespace: "regress_tblspace" + SELECT * FROM testschema.test_default_tab; id ---- @@ -134,38 +334,274 @@ SET default_tablespace TO ''; -- tablespace should not change if no rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE int; \d testschema.test_index1 -Index "testschema.test_index1" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_index1" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id btree, for table "testschema.test_default_tab" \d testschema.test_index2 -Index "testschema.test_index2" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_index2" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id btree, for table "testschema.test_default_tab" Tablespace: "regress_tblspace" +\d testschema.test_index3 + Index "testschema.test_index3" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id +primary key, btree, for table "testschema.test_default_tab" + +\d testschema.test_index4 + Index "testschema.test_index4" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id +unique, btree, for table "testschema.test_default_tab" +Tablespace: "regress_tblspace" + -- tablespace should not change even if there is an index rewrite ALTER TABLE testschema.test_default_tab ALTER id TYPE bigint; \d testschema.test_index1 -Index "testschema.test_index1" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" \d testschema.test_index2 -Index "testschema.test_index2" - Column | Type | Definition ---------+--------+------------ - id | bigint | id + Index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id btree, for table "testschema.test_default_tab" Tablespace: "regress_tblspace" +\d testschema.test_index3 + Index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab" + +\d testschema.test_index4 + Index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab" +Tablespace: "regress_tblspace" + DROP TABLE testschema.test_default_tab; +-- check that default_tablespace doesn't affect ALTER TABLE index rebuilds +-- (this time with a partitioned table) +CREATE TABLE testschema.test_default_tab_p(id bigint, val bigint) + PARTITION BY LIST (id) TABLESPACE regress_tblspace; +CREATE TABLE testschema.test_default_tab_p1 PARTITION OF testschema.test_default_tab_p + FOR VALUES IN (1); +INSERT INTO testschema.test_default_tab_p VALUES (1); +CREATE INDEX test_index1 on testschema.test_default_tab_p (val); +CREATE INDEX test_index2 on testschema.test_default_tab_p (val) TABLESPACE regress_tblspace; +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index3 PRIMARY KEY (id); +ALTER TABLE testschema.test_default_tab_p ADD CONSTRAINT test_index4 UNIQUE (id) USING INDEX TABLESPACE regress_tblspace; +\d testschema.test_index1 +Partitioned index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index2 +Partitioned index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d testschema.test_index3 +Partitioned index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index4 +Partitioned index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +-- use a custom tablespace for default_tablespace +SET default_tablespace TO regress_tblspace; +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; +\d testschema.test_index1 +Partitioned index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index2 +Partitioned index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d testschema.test_index3 +Partitioned index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index4 +Partitioned index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +SELECT * FROM testschema.test_default_tab_p; + id | val +----+----- + 1 | +(1 row) + +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; +\d testschema.test_index1 +Partitioned index "testschema.test_index1" + Column | Type | Key? | Definition +--------+---------+------+------------ + val | integer | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index2 +Partitioned index "testschema.test_index2" + Column | Type | Key? | Definition +--------+---------+------+------------ + val | integer | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d testschema.test_index3 +Partitioned index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index4 +Partitioned index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +SELECT * FROM testschema.test_default_tab_p; + id | val +----+----- + 1 | +(1 row) + +-- now use the default tablespace for default_tablespace +SET default_tablespace TO ''; +-- tablespace should not change if no rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE int; +\d testschema.test_index1 +Partitioned index "testschema.test_index1" + Column | Type | Key? | Definition +--------+---------+------+------------ + val | integer | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index2 +Partitioned index "testschema.test_index2" + Column | Type | Key? | Definition +--------+---------+------+------------ + val | integer | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d testschema.test_index3 +Partitioned index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index4 +Partitioned index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +-- tablespace should not change even if there is an index rewrite +ALTER TABLE testschema.test_default_tab_p ALTER val TYPE bigint; +\d testschema.test_index1 +Partitioned index "testschema.test_index1" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index2 +Partitioned index "testschema.test_index2" + Column | Type | Key? | Definition +--------+--------+------+------------ + val | bigint | yes | val +btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +\d testschema.test_index3 +Partitioned index "testschema.test_index3" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +primary key, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) + +\d testschema.test_index4 +Partitioned index "testschema.test_index4" + Column | Type | Key? | Definition +--------+--------+------+------------ + id | bigint | yes | id +unique, btree, for table "testschema.test_default_tab_p" +Number of partitions: 1 (Use \d+ to list them.) +Tablespace: "regress_tblspace" + +DROP TABLE testschema.test_default_tab_p; -- check that default_tablespace affects index additions in ALTER TABLE CREATE TABLE testschema.test_tab(id int) TABLESPACE regress_tblspace; INSERT INTO testschema.test_tab VALUES (1); @@ -174,18 +610,18 @@ ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (id); SET default_tablespace TO ''; ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_pkey PRIMARY KEY (id); \d testschema.test_tab_unique -Index "testschema.test_tab_unique" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_tab_unique" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id unique, btree, for table "testschema.test_tab" Tablespace: "regress_tblspace" \d testschema.test_tab_pkey -Index "testschema.test_tab_pkey" - Column | Type | Definition ---------+---------+------------ - id | integer | id + Index "testschema.test_tab_pkey" + Column | Type | Key? | Definition +--------+---------+------+------------ + id | integer | yes | id primary key, btree, for table "testschema.test_tab" SELECT * FROM testschema.test_tab; @@ -194,12 +630,72 @@ SELECT * FROM testschema.test_tab; 1 (1 row) +DROP TABLE testschema.test_tab; +-- check that default_tablespace is handled correctly by multi-command +-- ALTER TABLE that includes a tablespace-preserving rewrite +CREATE TABLE testschema.test_tab(a int, b int, c int); +SET default_tablespace TO regress_tblspace; +ALTER TABLE testschema.test_tab ADD CONSTRAINT test_tab_unique UNIQUE (a); +CREATE INDEX test_tab_a_idx ON testschema.test_tab (a); +SET default_tablespace TO ''; +CREATE INDEX test_tab_b_idx ON testschema.test_tab (b); +\d testschema.test_tab_unique + Index "testschema.test_tab_unique" + Column | Type | Key? | Definition +--------+---------+------+------------ + a | integer | yes | a +unique, btree, for table "testschema.test_tab" +Tablespace: "regress_tblspace" + +\d testschema.test_tab_a_idx + Index "testschema.test_tab_a_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + a | integer | yes | a +btree, for table "testschema.test_tab" +Tablespace: "regress_tblspace" + +\d testschema.test_tab_b_idx + Index "testschema.test_tab_b_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + b | integer | yes | b +btree, for table "testschema.test_tab" + +ALTER TABLE testschema.test_tab ALTER b TYPE bigint, ADD UNIQUE (c); +\d testschema.test_tab_unique + Index "testschema.test_tab_unique" + Column | Type | Key? | Definition +--------+---------+------+------------ + a | integer | yes | a +unique, btree, for table "testschema.test_tab" +Tablespace: "regress_tblspace" + +\d testschema.test_tab_a_idx + Index "testschema.test_tab_a_idx" + Column | Type | Key? | Definition +--------+---------+------+------------ + a | integer | yes | a +btree, for table "testschema.test_tab" +Tablespace: "regress_tblspace" + +\d testschema.test_tab_b_idx + Index "testschema.test_tab_b_idx" + Column | Type | Key? | Definition +--------+--------+------+------------ + b | bigint | yes | b +btree, for table "testschema.test_tab" + DROP TABLE testschema.test_tab; -- let's try moving a table from one place to another CREATE TABLE testschema.atable AS VALUES (1), (2); CREATE UNIQUE INDEX anindex ON testschema.atable(column1); ALTER TABLE testschema.atable SET TABLESPACE regress_tblspace; ALTER INDEX testschema.anindex SET TABLESPACE regress_tblspace; +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_global; +ERROR: only shared relations can be placed in pg_global tablespace +ALTER INDEX testschema.part_a_idx SET TABLESPACE pg_default; +ALTER INDEX testschema.part_a_idx SET TABLESPACE regress_tblspace; INSERT INTO testschema.atable VALUES(3); -- ok INSERT INTO testschema.atable VALUES(1); -- fail (checks index) ERROR: duplicate key value violates unique constraint "anindex" @@ -241,10 +737,11 @@ NOTICE: no matching relations in tablespace "regress_tblspace_renamed" found -- Should succeed DROP TABLESPACE regress_tblspace_renamed; DROP SCHEMA testschema CASCADE; -NOTICE: drop cascades to 5 other objects +NOTICE: drop cascades to 6 other objects DETAIL: drop cascades to table testschema.foo drop cascades to table testschema.asselect drop cascades to table testschema.asexecute +drop cascades to table testschema.part drop cascades to table testschema.atable drop cascades to table testschema.tablespace_acl DROP ROLE regress_tablespace_user1; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 0d3a27ed410..fc0f14122bb 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -15,28 +15,23 @@ test: tablespace # ---------- test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeric txid uuid enum money rangetypes pg_lsn regproc -# Depends on things setup during char, varchar and text -test: strings -# Depends on int2, int4, int8, float4, float8 -test: numerology - # ---------- # The second group of parallel tests +# strings depends on char, varchar and text +# numerology depends on int2, int4, int8, float4, float8 # ---------- -test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet macaddr macaddr8 tstypes +test: strings numerology point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes # ---------- # Another group of parallel tests # geometry depends on point, lseg, box, path, polygon and circle -# horology depends on interval, timetz, timestamp, timestamptz, reltime and abstime +# horology depends on interval, timetz, timestamp, timestamptz # ---------- test: geometry horology regex oidjoins type_sanity opr_sanity misc_sanity comments expressions # ---------- # These four each depend on the previous one # ---------- -test: insert -test: insert_conflict test: create_function_1 test: create_type test: create_table @@ -48,19 +43,19 @@ test: create_function_2 # execute two copy tests parallel, to check that copy itself # is concurrent safe. # ---------- -test: copy copyselect copydml +test: copy copyselect copydml insert insert_conflict # ---------- # More groups of parallel tests # ---------- test: create_misc create_operator create_procedure -# These depend on the above two -test: create_index create_view index_including +# These depend on create_misc and create_operator +test: create_index create_index_spgist create_view index_including index_including_gist # ---------- # Another group of parallel tests # ---------- -test: create_aggregate create_function_3 create_cast constraints triggers inherit create_table_like typed_table vacuum drop_if_exists updatable_views rolenames roleattributes create_am hash_func +test: create_aggregate create_function_3 create_cast constraints triggers select inherit typed_table vacuum drop_if_exists updatable_views roleattributes create_am hash_func errors # ---------- # sanity_check does a vacuum, affecting the sort order of SELECT * @@ -68,31 +63,27 @@ test: create_aggregate create_function_3 create_cast constraints triggers inheri # ---------- test: sanity_check -# ---------- -# Believe it or not, select creates a table, subsequent -# tests need. -# ---------- -test: errors -test: select -ignore: random - # ---------- # Another group of parallel tests +# Note: the ignore: line does not run random, just mark it as ignorable # ---------- -test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete +ignore: random +test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update delete namespace prepared_xacts # ---------- # Another group of parallel tests # ---------- -test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator password func_index merge +test: brin gin gist spgist privileges init_privs security_label collate matview lock replica_identity rowsecurity object_address tablesample groupingsets drop_operator password identity generated join_hash # ---------- # Another group of parallel tests # ---------- -test: alter_generic alter_operator misc psql async dbsize misc_functions sysviews tsrf tidscan stats_ext +test: create_table_like alter_generic alter_operator misc async dbsize misc_functions sysviews tsrf tidscan collate.icu.utf8 -# rules cannot run concurrently with any test that creates a view -test: rules psql_crosstab amutils +# rules cannot run concurrently with any test that creates +# a view or rule in the public schema +# collate.*.utf8 tests cannot be run in parallel with each other +test: rules psql psql_crosstab amutils stats_ext collate.linux.utf8 # run by itself so it can run parallel workers test: select_parallel @@ -104,22 +95,29 @@ test: publication subscription # ---------- # Another group of parallel tests # ---------- -test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock json jsonb json_encoding indirect_toast equivclass +test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combocid tsearch tsdicts foreign_data window xmlmap functional_deps advisory_lock indirect_toast equivclass + +# ---------- +# Another group of parallel tests (JSON related) +# ---------- +test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # ---------- # Another group of parallel tests # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml # ---------- # Another group of parallel tests # ---------- -test: identity partition_join partition_prune partition_prune_hash reloptions hash_part indexing partition_aggregate fast_default +test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info # event triggers cannot run concurrently with any test that runs DDL test: event_trigger +# this test also uses event triggers, so likewise run it by itself +test: fast_default # run stats by itself because its delay may be insufficient under heavy load test: stats diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index 4b24c4ac71f..3a394721088 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -8,7 +8,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/regress/pg_regress.c @@ -31,11 +31,13 @@ #include "pg_regress.h" +#include "common/logging.h" #include "common/restricted_token.h" #include "common/username.h" #include "getopt_long.h" #include "libpq/pqcomm.h" /* needed for UNIXSOCK_PATH() */ #include "pg_config_paths.h" +#include "portability/instr_time.h" /* for resultmap we need a list of pairs of strings */ typedef struct _resultmap @@ -62,10 +64,10 @@ static char *shellprog = SHELLPROG; */ #ifndef WIN32 const char *basic_diff_opts = ""; -const char *pretty_diff_opts = "-C3"; +const char *pretty_diff_opts = "-U3"; #else const char *basic_diff_opts = "-w"; -const char *pretty_diff_opts = "-w -C3"; +const char *pretty_diff_opts = "-w -U3"; #endif /* options settable from command line */ @@ -724,6 +726,10 @@ doputenv(const char *var, const char *val) static void initialize_environment(void) { + /* + * Set default application_name. (The test_function may choose to + * override this, but if it doesn't, we have something useful in place.) + */ putenv("PGAPPNAME=pg_regress"); if (nolocale) @@ -855,6 +861,14 @@ initialize_environment(void) if (user != NULL) doputenv("PGUSER", user); + /* + * However, we *don't* honor PGDATABASE, since we certainly don't wish + * to connect to whatever database the user might like as default. + * (Most tests override PGDATABASE anyway, but there are some ECPG + * test cases that don't.) + */ + unsetenv("PGDATABASE"); + /* * Report what we're connecting to */ @@ -879,7 +893,9 @@ initialize_environment(void) load_resultmap(); } -pg_attribute_unused() +#ifdef ENABLE_SSPI + +/* support for config_sspi_auth() */ static const char * fmtHba(const char *raw) { @@ -902,7 +918,6 @@ fmtHba(const char *raw) return ret; } -#ifdef ENABLE_SSPI /* * Get account and domain/realm names for the current user. This is based on * pg_SSPI_recvauth(). The returned strings use static storage. @@ -962,13 +977,15 @@ current_windows_user(const char **acct, const char **dom) * Rewrite pg_hba.conf and pg_ident.conf to use SSPI authentication. Permit * the current OS user to authenticate as the bootstrap superuser and as any * user named in a --create-role option. + * + * In --config-auth mode, the --user switch can be used to specify the + * bootstrap superuser's name, otherwise we assume it is the default. */ static void -config_sspi_auth(const char *pgdata) +config_sspi_auth(const char *pgdata, const char *superuser_name) { const char *accountname, *domainname; - const char *username; char *errstr; bool have_ipv6; char fname[MAXPGPATH]; @@ -977,17 +994,25 @@ config_sspi_auth(const char *pgdata) *ident; _stringlist *sl; - /* - * "username", the initdb-chosen bootstrap superuser name, may always - * match "accountname", the value SSPI authentication discovers. The - * underlying system functions do not clearly guarantee that. - */ + /* Find out the name of the current OS user */ current_windows_user(&accountname, &domainname); - username = get_user_name(&errstr); - if (username == NULL) + + /* Determine the bootstrap superuser's name */ + if (superuser_name == NULL) { - fprintf(stderr, "%s: %s\n", progname, errstr); - exit(2); + /* + * Compute the default superuser name the same way initdb does. + * + * It's possible that this result always matches "accountname", the + * value SSPI authentication discovers. But the underlying system + * functions do not clearly guarantee that. + */ + superuser_name = get_user_name(&errstr); + if (superuser_name == NULL) + { + fprintf(stderr, "%s: %s\n", progname, errstr); + exit(2); + } } /* @@ -1024,7 +1049,7 @@ config_sspi_auth(const char *pgdata) } while (0) res = snprintf(fname, sizeof(fname), "%s/pg_hba.conf", pgdata); - if (res < 0 || res >= sizeof(fname) - 1) + if (res < 0 || res >= sizeof(fname)) { /* * Truncating this name is a fatal error, because we must not fail to @@ -1064,13 +1089,14 @@ config_sspi_auth(const char *pgdata) * bother escaping embedded double-quote characters. */ CW(fprintf(ident, "regress \"%s@%s\" %s\n", - accountname, domainname, fmtHba(username)) >= 0); + accountname, domainname, fmtHba(superuser_name)) >= 0); for (sl = extraroles; sl; sl = sl->next) CW(fprintf(ident, "regress \"%s@%s\" %s\n", accountname, domainname, fmtHba(sl->str)) >= 0); CW(fclose(ident) == 0); } -#endif + +#endif /* ENABLE_SSPI */ /* * Issue a command via psql, connecting to the specified database @@ -1173,7 +1199,7 @@ spawn_process(const char *cmdline) cmdline2 = psprintf("cmd /c \"%s\"", cmdline); if ((restrictedToken = - CreateRestrictedProcess(cmdline2, &pi, progname)) == 0) + CreateRestrictedProcess(cmdline2, &pi)) == 0) exit(2); CloseHandle(pi.hThread); @@ -1453,34 +1479,38 @@ results_differ(const char *testname, const char *resultsfile, const char *defaul * Use the best comparison file to generate the "pretty" diff, which we * append to the diffs summary file. */ - snprintf(cmd, sizeof(cmd), - "diff %s \"%s\" \"%s\" >> \"%s\"", - pretty_diff_opts, best_expect_file, resultsfile, difffilename); - run_diff(cmd, difffilename); - /* And append a separator */ + /* Write diff header */ difffile = fopen(difffilename, "a"); if (difffile) { fprintf(difffile, - "\n======================================================================\n\n"); + "diff %s %s %s\n", + pretty_diff_opts, best_expect_file, resultsfile); fclose(difffile); } + /* Run diff */ + snprintf(cmd, sizeof(cmd), + "diff %s \"%s\" \"%s\" >> \"%s\"", + pretty_diff_opts, best_expect_file, resultsfile, difffilename); + run_diff(cmd, difffilename); + unlink(diff); return true; } /* * Wait for specified subprocesses to finish, and return their exit - * statuses into statuses[] + * statuses into statuses[] and stop times into stoptimes[] * * If names isn't NULL, print each subprocess's name as it finishes * * Note: it's OK to scribble on the pids array, but not on the names array */ static void -wait_for_tests(PID_TYPE * pids, int *statuses, char **names, int num_tests) +wait_for_tests(PID_TYPE * pids, int *statuses, instr_time *stoptimes, + char **names, int num_tests) { int tests_left; int i; @@ -1533,6 +1563,7 @@ wait_for_tests(PID_TYPE * pids, int *statuses, char **names, int num_tests) #endif pids[i] = INVALID_PID; statuses[i] = (int) exit_status; + INSTR_TIME_SET_CURRENT(stoptimes[i]); if (names) status(" %s", names[i]); tests_left--; @@ -1560,14 +1591,9 @@ log_child_failure(int exitstatus) #if defined(WIN32) status(_(" (test process was terminated by exception 0x%X)"), WTERMSIG(exitstatus)); -#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST - status(_(" (test process was terminated by signal %d: %s)"), - WTERMSIG(exitstatus), - WTERMSIG(exitstatus) < NSIG ? - sys_siglist[WTERMSIG(exitstatus)] : "(unknown))"); #else - status(_(" (test process was terminated by signal %d)"), - WTERMSIG(exitstatus)); + status(_(" (test process was terminated by signal %d: %s)"), + WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus))); #endif } else @@ -1587,6 +1613,8 @@ run_schedule(const char *schedule, test_function tfunc) _stringlist *expectfiles[MAX_PARALLEL_TESTS]; _stringlist *tags[MAX_PARALLEL_TESTS]; PID_TYPE pids[MAX_PARALLEL_TESTS]; + instr_time starttimes[MAX_PARALLEL_TESTS]; + instr_time stoptimes[MAX_PARALLEL_TESTS]; int statuses[MAX_PARALLEL_TESTS]; _stringlist *ignorelist = NULL; char scbuf[1024]; @@ -1692,7 +1720,8 @@ run_schedule(const char *schedule, test_function tfunc) { status(_("test %-28s ... "), tests[0]); pids[0] = (tfunc) (tests[0], &resultfiles[0], &expectfiles[0], &tags[0]); - wait_for_tests(pids, statuses, NULL, 1); + INSTR_TIME_SET_CURRENT(starttimes[0]); + wait_for_tests(pids, statuses, stoptimes, NULL, 1); /* status line is finished below */ } else if (max_concurrent_tests > 0 && max_concurrent_tests < num_tests) @@ -1712,12 +1741,15 @@ run_schedule(const char *schedule, test_function tfunc) if (i - oldest >= max_connections) { wait_for_tests(pids + oldest, statuses + oldest, + stoptimes + oldest, tests + oldest, i - oldest); oldest = i; } pids[i] = (tfunc) (tests[i], &resultfiles[i], &expectfiles[i], &tags[i]); + INSTR_TIME_SET_CURRENT(starttimes[i]); } wait_for_tests(pids + oldest, statuses + oldest, + stoptimes + oldest, tests + oldest, i - oldest); status_end(); } @@ -1727,8 +1759,9 @@ run_schedule(const char *schedule, test_function tfunc) for (i = 0; i < num_tests; i++) { pids[i] = (tfunc) (tests[i], &resultfiles[i], &expectfiles[i], &tags[i]); + INSTR_TIME_SET_CURRENT(starttimes[i]); } - wait_for_tests(pids, statuses, tests, num_tests); + wait_for_tests(pids, statuses, stoptimes, tests, num_tests); status_end(); } @@ -1752,14 +1785,11 @@ run_schedule(const char *schedule, test_function tfunc) */ for (rl = resultfiles[i], el = expectfiles[i], tl = tags[i]; rl != NULL; /* rl and el have the same length */ - rl = rl->next, el = el->next) + rl = rl->next, el = el->next, + tl = tl ? tl->next : NULL) { bool newdiff; - if (tl) - tl = tl->next; /* tl has the same length as rl and el if - * it exists */ - newdiff = results_differ(tests[i], rl->str, el->str); if (newdiff && tl) { @@ -1794,13 +1824,16 @@ run_schedule(const char *schedule, test_function tfunc) } else { - status(_("ok")); + status(_("ok ")); /* align with FAILED */ success_count++; } if (statuses[i] != 0) log_child_failure(statuses[i]); + INSTR_TIME_SUBTRACT(stoptimes[i], starttimes[i]); + status(_(" %8.0f ms"), INSTR_TIME_GET_MILLISEC(stoptimes[i])); + status_end(); } @@ -1826,6 +1859,8 @@ static void run_single_test(const char *test, test_function tfunc) { PID_TYPE pid; + instr_time starttime; + instr_time stoptime; int exit_status; _stringlist *resultfiles = NULL; _stringlist *expectfiles = NULL; @@ -1837,7 +1872,8 @@ run_single_test(const char *test, test_function tfunc) status(_("test %-28s ... "), test); pid = (tfunc) (test, &resultfiles, &expectfiles, &tags); - wait_for_tests(&pid, &exit_status, NULL, 1); + INSTR_TIME_SET_CURRENT(starttime); + wait_for_tests(&pid, &exit_status, &stoptime, NULL, 1); /* * Advance over all three lists simultaneously. @@ -1848,14 +1884,11 @@ run_single_test(const char *test, test_function tfunc) */ for (rl = resultfiles, el = expectfiles, tl = tags; rl != NULL; /* rl and el have the same length */ - rl = rl->next, el = el->next) + rl = rl->next, el = el->next, + tl = tl ? tl->next : NULL) { bool newdiff; - if (tl) - tl = tl->next; /* tl has the same length as rl and el if it - * exists */ - newdiff = results_differ(test, rl->str, el->str); if (newdiff && tl) { @@ -1871,13 +1904,16 @@ run_single_test(const char *test, test_function tfunc) } else { - status(_("ok")); + status(_("ok ")); /* align with FAILED */ success_count++; } if (exit_status != 0) log_child_failure(exit_status); + INSTR_TIME_SUBTRACT(stoptime, starttime); + status(_(" %8.0f ms"), INSTR_TIME_GET_MILLISEC(stoptime)); + status_end(); } @@ -2043,7 +2079,7 @@ help(void) printf(_("The exit status is 0 if all tests passed, 1 if some tests failed, and 2\n")); printf(_("if the tests could not be run for some reason.\n")); printf(_("\n")); - printf(_("Report bugs to .\n")); + printf(_("Report bugs to .\n")); } int @@ -2084,9 +2120,12 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc char buf[MAXPGPATH * 4]; char buf2[MAXPGPATH * 4]; + pg_logging_init(argv[0]); progname = get_progname(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_regress")); + get_restricted_token(); + atexit(stop_postmaster); #ifndef HAVE_UNIX_SOCKETS @@ -2210,7 +2249,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc if (config_auth_datadir) { #ifdef ENABLE_SSPI - config_sspi_auth(config_auth_datadir); + config_sspi_auth(config_auth_datadir, user); #endif exit(0); } @@ -2337,7 +2376,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc * "initdb" command, this can't truncate. */ snprintf(buf, sizeof(buf), "%s/data", temp_instance); - config_sspi_auth(buf); + config_sspi_auth(buf, NULL); #elif !defined(HAVE_UNIX_SOCKETS) #error Platform has no means to secure the test installation. #endif @@ -2423,7 +2462,7 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc * Fail immediately if postmaster has exited */ #ifndef WIN32 - if (kill(postmaster_pid, 0) != 0) + if (waitpid(postmaster_pid, NULL, WNOHANG) == postmaster_pid) #else if (WaitForSingleObject(postmaster_pid, 0) == WAIT_OBJECT_0) #endif diff --git a/src/test/regress/pg_regress.h b/src/test/regress/pg_regress.h index e9045b75b68..af47f20dd21 100644 --- a/src/test/regress/pg_regress.h +++ b/src/test/regress/pg_regress.h @@ -1,7 +1,7 @@ /*------------------------------------------------------------------------- * pg_regress.h --- regression test driver * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/regress/pg_regress.h @@ -45,8 +45,8 @@ extern char *launcher; extern const char *basic_diff_opts; extern const char *pretty_diff_opts; -int regression_main(int argc, char *argv[], - init_function ifunc, test_function tfunc); +int regression_main(int argc, char *argv[], + init_function ifunc, test_function tfunc); void add_stringlist_item(_stringlist **listhead, const char *str); PID_TYPE spawn_process(const char *cmdline); void replace_string(char *string, const char *replace, const char *replacement); diff --git a/src/test/regress/pg_regress_main.c b/src/test/regress/pg_regress_main.c index a2bd6a2cd57..f1df7557fa1 100644 --- a/src/test/regress/pg_regress_main.c +++ b/src/test/regress/pg_regress_main.c @@ -8,7 +8,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/regress/pg_regress_main.c @@ -63,20 +63,37 @@ psql_start_test(const char *testname, add_stringlist_item(expectfiles, expectfile); if (launcher) + { offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, "%s ", launcher); + if (offset >= sizeof(psql_cmd)) + { + fprintf(stderr, _("command too long\n")); + exit(2); + } + } + + /* + * Use HIDE_TABLEAM to hide different AMs to allow to use regression tests + * against different AMs without unnecessary differences. + */ + offset += snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, + "\"%s%spsql\" -X -a -q -d \"%s\" -v %s < \"%s\" > \"%s\" 2>&1", + bindir ? bindir : "", + bindir ? "/" : "", + dblist->str, + "HIDE_TABLEAM=\"on\"", + infile, + outfile); + if (offset >= sizeof(psql_cmd)) + { + fprintf(stderr, _("command too long\n")); + exit(2); + } appnameenv = psprintf("PGAPPNAME=pg_regress/%s", testname); putenv(appnameenv); - snprintf(psql_cmd + offset, sizeof(psql_cmd) - offset, - "\"%s%spsql\" -X -a -q -d \"%s\" < \"%s\" > \"%s\" 2>&1", - bindir ? bindir : "", - bindir ? "/" : "", - dblist->str, - infile, - outfile); - pid = spawn_process(psql_cmd); if (pid == INVALID_PID) diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 8bc562ee4f0..8cc1568a3dd 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -6,7 +6,7 @@ * * This code is released under the terms of the PostgreSQL License. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/regress/regress.c @@ -16,20 +16,23 @@ #include "postgres.h" -#include #include #include +#include "access/detoast.h" #include "access/htup_details.h" #include "access/transam.h" -#include "access/tuptoaster.h" #include "access/xact.h" +#include "catalog/pg_operator.h" #include "catalog/pg_type.h" #include "commands/sequence.h" #include "commands/trigger.h" #include "executor/executor.h" #include "executor/spi.h" #include "miscadmin.h" +#include "nodes/supportnodes.h" +#include "optimizer/optimizer.h" +#include "optimizer/plancat.h" #include "port/atomics.h" #include "utils/builtins.h" #include "utils/geo_decls.h" @@ -38,7 +41,6 @@ #include "utils/memutils.h" -#define P_MAXDIG 12 #define LDELIM '(' #define RDELIM ')' #define DELIM ',' @@ -150,8 +152,8 @@ widget_in(PG_FUNCTION_ARGS) if (i < NARGS) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type widget: \"%s\"", - str))); + errmsg("invalid input syntax for type %s: \"%s\"", + "widget", str))); result = (WIDGET *) palloc(sizeof(WIDGET)); result->center.x = atof(coord[0]); @@ -178,8 +180,13 @@ pt_in_widget(PG_FUNCTION_ARGS) { Point *point = PG_GETARG_POINT_P(0); WIDGET *widget = (WIDGET *) PG_GETARG_POINTER(1); + float8 distance; - PG_RETURN_BOOL(point_dt(point, &widget->center) < widget->radius); + distance = DatumGetFloat8(DirectFunctionCall2(point_distance, + PointPGetDatum(point), + PointPGetDatum(&widget->center))); + + PG_RETURN_BOOL(distance < widget->radius); } PG_FUNCTION_INFO_V1(reverse_name); @@ -680,7 +687,7 @@ test_atomic_uint32(void) if (pg_atomic_read_u32(&var) != 3) elog(ERROR, "atomic_read_u32() #2 wrong"); - if (pg_atomic_fetch_add_u32(&var, 1) != 3) + if (pg_atomic_fetch_add_u32(&var, pg_atomic_read_u32(&var) - 2) != 3) elog(ERROR, "atomic_fetch_add_u32() #1 wrong"); if (pg_atomic_fetch_sub_u32(&var, 1) != 4) @@ -705,6 +712,20 @@ test_atomic_uint32(void) if (pg_atomic_fetch_add_u32(&var, INT_MAX) != INT_MAX) elog(ERROR, "pg_atomic_add_fetch_u32() #3 wrong"); + pg_atomic_fetch_add_u32(&var, 2); /* wrap to 0 */ + + if (pg_atomic_fetch_add_u32(&var, PG_INT16_MAX) != 0) + elog(ERROR, "pg_atomic_fetch_add_u32() #3 wrong"); + + if (pg_atomic_fetch_add_u32(&var, PG_INT16_MAX + 1) != PG_INT16_MAX) + elog(ERROR, "pg_atomic_fetch_add_u32() #4 wrong"); + + if (pg_atomic_fetch_add_u32(&var, PG_INT16_MIN) != 2 * PG_INT16_MAX + 1) + elog(ERROR, "pg_atomic_fetch_add_u32() #5 wrong"); + + if (pg_atomic_fetch_add_u32(&var, PG_INT16_MIN - 1) != PG_INT16_MAX) + elog(ERROR, "pg_atomic_fetch_add_u32() #6 wrong"); + pg_atomic_fetch_add_u32(&var, 1); /* top up to UINT_MAX */ if (pg_atomic_read_u32(&var) != UINT_MAX) @@ -780,7 +801,7 @@ test_atomic_uint64(void) if (pg_atomic_read_u64(&var) != 3) elog(ERROR, "atomic_read_u64() #2 wrong"); - if (pg_atomic_fetch_add_u64(&var, 1) != 3) + if (pg_atomic_fetch_add_u64(&var, pg_atomic_read_u64(&var) - 2) != 3) elog(ERROR, "atomic_fetch_add_u64() #1 wrong"); if (pg_atomic_fetch_sub_u64(&var, 1) != 4) @@ -860,3 +881,76 @@ test_fdw_handler(PG_FUNCTION_ARGS) elog(ERROR, "test_fdw_handler is not implemented"); PG_RETURN_NULL(); } + +PG_FUNCTION_INFO_V1(test_support_func); +Datum +test_support_func(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestSelectivity)) + { + /* + * Assume that the target is int4eq; that's safe as long as we don't + * attach this to any other boolean-returning function. + */ + SupportRequestSelectivity *req = (SupportRequestSelectivity *) rawreq; + Selectivity s1; + + if (req->is_join) + s1 = join_selectivity(req->root, Int4EqualOperator, + req->args, + req->inputcollid, + req->jointype, + req->sjinfo); + else + s1 = restriction_selectivity(req->root, Int4EqualOperator, + req->args, + req->inputcollid, + req->varRelid); + + req->selectivity = s1; + ret = (Node *) req; + } + + if (IsA(rawreq, SupportRequestCost)) + { + /* Provide some generic estimate */ + SupportRequestCost *req = (SupportRequestCost *) rawreq; + + req->startup = 0; + req->per_tuple = 2 * cpu_operator_cost; + ret = (Node *) req; + } + + if (IsA(rawreq, SupportRequestRows)) + { + /* + * Assume that the target is generate_series_int4; that's safe as long + * as we don't attach this to any other set-returning function. + */ + SupportRequestRows *req = (SupportRequestRows *) rawreq; + + if (req->node && IsA(req->node, FuncExpr)) /* be paranoid */ + { + List *args = ((FuncExpr *) req->node)->args; + Node *arg1 = linitial(args); + Node *arg2 = lsecond(args); + + if (IsA(arg1, Const) && + !((Const *) arg1)->constisnull && + IsA(arg2, Const) && + !((Const *) arg2)->constisnull) + { + int32 val1 = DatumGetInt32(((Const *) arg1)->constvalue); + int32 val2 = DatumGetInt32(((Const *) arg2)->constvalue); + + req->rows = val2 - val1 + 1; + ret = (Node *) req; + } + } + } + + PG_RETURN_POINTER(ret); +} diff --git a/src/test/regress/regressplans.sh b/src/test/regress/regressplans.sh index 678ab0a3f22..31e7876daab 100755 --- a/src/test/regress/regressplans.sh +++ b/src/test/regress/regressplans.sh @@ -72,7 +72,7 @@ mv -f regression.out planregress/out.in mv -f regression.diffs planregress/diffs.in PGOPTIONS="$PGOPTIONS -fi -fn -fh" $MAKE runtest mv -f regression.out planregress/out.inh -mv -f regression.diffsregression.planregress/inh +mv -f regression.diffs planregress/diffs.inh PGOPTIONS="$PGOPTIONS -fi -fn -fm " $MAKE runtest mv -f regression.out planregress/out.inm mv -f regression.diffs planregress/diffs.inm diff --git a/src/test/regress/resultmap b/src/test/regress/resultmap index 04ba99fe338..c766d03df23 100644 --- a/src/test/regress/resultmap +++ b/src/test/regress/resultmap @@ -1,17 +1,3 @@ -float4:out:i.86-pc-mingw32=float4-exp-three-digits.out -float4:out:x86_64-w64-mingw32=float4-exp-three-digits.out -float4:out:i.86-w64-mingw32=float4-exp-three-digits.out -float4:out:i.86-pc-win32vc=float4-exp-three-digits.out -float8:out:i.86-.*-freebsd=float8-small-is-zero.out -float8:out:i.86-.*-openbsd=float8-small-is-zero.out -float8:out:i.86-.*-netbsd=float8-small-is-zero.out -float8:out:m68k-.*-netbsd=float8-small-is-zero.out -float8:out:i.86-pc-mingw32=float8-exp-three-digits-win32.out -float8:out:x86_64-w64-mingw32=float8-exp-three-digits-win32.out -float8:out:i.86-w64-mingw32=float8-exp-three-digits-win32.out -float8:out:i.86-pc-win32vc=float8-exp-three-digits-win32.out -float8:out:i.86-pc-cygwin=float8-small-is-zero.out -int8:out:i.86-pc-mingw32=int8-exp-three-digits.out -int8:out:x86_64-w64-mingw32=int8-exp-three-digits.out -int8:out:i.86-w64-mingw32=int8-exp-three-digits.out -int8:out:i.86-pc-win32vc=int8-exp-three-digits.out +float4:out:.*-.*-cygwin.*=float4-misrounded-input.out +float4:out:.*-.*-mingw.*=float4-misrounded-input.out +float4:out:hppa.*-hp-hpux10.*=float4-misrounded-input.out diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 20027c131c2..68ac56acdb2 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -36,9 +36,6 @@ test: timetz test: timestamp test: timestamptz test: interval -test: abstime -test: reltime -test: tinterval test: inet test: macaddr test: macaddr8 @@ -52,8 +49,6 @@ test: opr_sanity test: misc_sanity test: comments test: expressions -test: insert -test: insert_conflict test: create_function_1 test: create_type test: create_table @@ -61,30 +56,32 @@ test: create_function_2 test: copy test: copyselect test: copydml +test: insert +test: insert_conflict test: create_misc test: create_operator test: create_procedure test: create_index -test: index_including +test: create_index_spgist test: create_view +test: index_including +test: index_including_gist test: create_aggregate test: create_function_3 test: create_cast test: constraints test: triggers +test: select test: inherit -test: create_table_like test: typed_table test: vacuum test: drop_if_exists test: updatable_views -test: rolenames test: roleattributes test: create_am test: hash_func -test: sanity_check test: errors -test: select +test: sanity_check test: select_into test: select_distinct test: select_distinct_on @@ -102,7 +99,6 @@ test: portals test: arrays test: btree_index test: hash_index -test: func_index test: update test: delete test: namespace @@ -124,25 +120,30 @@ test: tablesample test: groupingsets test: drop_operator test: password -test: merge +test: identity +test: generated +test: join_hash +test: create_table_like test: alter_generic test: alter_operator test: misc -test: psql test: async test: dbsize test: misc_functions test: sysviews test: tsrf test: tidscan -test: stats_ext +test: collate.icu.utf8 test: rules +test: psql test: psql_crosstab +test: amutils +test: stats_ext +test: collate.linux.utf8 test: select_parallel test: write_parallel test: publication test: subscription -test: amutils test: select_views test: portals_p2 test: foreign_key @@ -158,11 +159,14 @@ test: window test: xmlmap test: functional_deps test: advisory_lock +test: indirect_toast +test: equivclass test: json test: jsonb test: json_encoding -test: indirect_toast -test: equivclass +test: jsonpath +test: jsonpath_encoding +test: jsonb_jsonpath test: plancache test: limit test: plpgsql @@ -171,7 +175,6 @@ test: temp test: domain test: rangefuncs test: prepare -test: without_oid test: conversion test: truncate test: alter_table @@ -182,14 +185,13 @@ test: returning test: largeobject test: with test: xml -test: identity test: partition_join test: partition_prune -test: partition_prune_hash test: reloptions test: hash_part test: indexing test: partition_aggregate -test: fast_default +test: partition_info test: event_trigger +test: fast_default test: stats diff --git a/src/test/regress/sql/abstime.sql b/src/test/regress/sql/abstime.sql deleted file mode 100644 index 4ab821b1b8c..00000000000 --- a/src/test/regress/sql/abstime.sql +++ /dev/null @@ -1,67 +0,0 @@ --- --- ABSTIME --- testing built-in time type abstime --- uses reltime and tinterval --- - --- --- timezones may vary based not only on location but the operating --- system. the main correctness issue is that the OS may not get --- daylight savings time right for times prior to Unix epoch (jan 1 1970). --- - -CREATE TABLE ABSTIME_TBL (f1 abstime); - -BEGIN; -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'now'); -SELECT count(*) AS two FROM ABSTIME_TBL WHERE f1 = 'now' ; -END; - -DELETE FROM ABSTIME_TBL; - -INSERT INTO ABSTIME_TBL (f1) VALUES ('Jan 14, 1973 03:14:21'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'Mon May 1 00:30:30 1995'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'epoch'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'infinity'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime '-infinity'); -INSERT INTO ABSTIME_TBL (f1) VALUES (abstime 'May 10, 1947 23:59:12'); - --- what happens if we specify slightly misformatted abstime? -INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 35, 1946 10:00:00'); -INSERT INTO ABSTIME_TBL (f1) VALUES ('Feb 28, 1984 25:08:10'); - --- badly formatted abstimes: these should result in invalid abstimes -INSERT INTO ABSTIME_TBL (f1) VALUES ('bad date format'); -INSERT INTO ABSTIME_TBL (f1) VALUES ('Jun 10, 1843'); - --- test abstime operators - -SELECT '' AS eight, * FROM ABSTIME_TBL; - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 < abstime 'Jun 30, 2001'; - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 > abstime '-infinity'; - -SELECT '' AS six, * FROM ABSTIME_TBL - WHERE abstime 'May 10, 1947 23:59:12' <> ABSTIME_TBL.f1; - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE abstime 'epoch' >= ABSTIME_TBL.f1; - -SELECT '' AS four, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 <= abstime 'Jan 14, 1973 03:14:21'; - -SELECT '' AS four, * FROM ABSTIME_TBL - WHERE ABSTIME_TBL.f1 - tinterval '["Apr 1 1950 00:00:00" "Dec 30 1999 23:00:00"]'; - -SELECT '' AS four, f1 AS abstime, - date_part('year', f1) AS year, date_part('month', f1) AS month, - date_part('day',f1) AS day, date_part('hour', f1) AS hour, - date_part('minute', f1) AS minute, date_part('second', f1) AS second - FROM ABSTIME_TBL - WHERE isfinite(f1) - ORDER BY abstime; diff --git a/src/test/regress/sql/aggregates.sql b/src/test/regress/sql/aggregates.sql index 506d0442d79..17fb256aec5 100644 --- a/src/test/regress/sql/aggregates.sql +++ b/src/test/regress/sql/aggregates.sql @@ -2,6 +2,9 @@ -- AGGREGATES -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; + SELECT avg(four) AS avg_1 FROM onek; SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100; @@ -51,6 +54,22 @@ select avg(null::float8) from generate_series(1,3); select sum('NaN'::numeric) from generate_series(1,3); select avg('NaN'::numeric) from generate_series(1,3); +-- verify correct results for infinite inputs +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('1'), ('infinity')) v(x); +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('1')) v(x); +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('infinity'), ('infinity')) v(x); +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES ('-infinity'), ('infinity')) v(x); + +-- test accuracy with a large input offset +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (100000003), (100000004), (100000006), (100000007)) v(x); +SELECT avg(x::float8), var_pop(x::float8) +FROM (VALUES (7000000000005), (7000000000007)) v(x); + -- SQL2003 binary aggregates SELECT regr_count(b, a) FROM aggtest; SELECT regr_sxx(b, a) FROM aggtest; @@ -62,6 +81,31 @@ SELECT regr_slope(b, a), regr_intercept(b, a) FROM aggtest; SELECT covar_pop(b, a), covar_samp(b, a) FROM aggtest; SELECT corr(b, a) FROM aggtest; +-- test accum and combine functions directly +CREATE TABLE regr_test (x float8, y float8); +INSERT INTO regr_test VALUES (10,150),(20,250),(30,350),(80,540),(100,200); +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30,80); +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test; +SELECT float8_accum('{4,140,2900}'::float8[], 100); +SELECT float8_regr_accum('{4,140,2900,1290,83075,15050}'::float8[], 200, 100); +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (10,20,30); +SELECT count(*), sum(x), regr_sxx(y,x), sum(y),regr_syy(y,x), regr_sxy(y,x) +FROM regr_test WHERE x IN (80,100); +SELECT float8_combine('{3,60,200}'::float8[], '{0,0,0}'::float8[]); +SELECT float8_combine('{0,0,0}'::float8[], '{2,180,200}'::float8[]); +SELECT float8_combine('{3,60,200}'::float8[], '{2,180,200}'::float8[]); +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{0,0,0,0,0,0}'::float8[]); +SELECT float8_regr_combine('{0,0,0,0,0,0}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); +SELECT float8_regr_combine('{3,60,200,750,20000,2000}'::float8[], + '{2,180,200,740,57800,-3400}'::float8[]); +DROP TABLE regr_test; + +-- test count, distinct SELECT count(four) AS cnt_1000 FROM onek; SELECT count(DISTINCT four) AS cnt_4 FROM onek; @@ -362,9 +406,31 @@ group by t1.a,t1.b,t1.c,t1.d,t2.x,t2.z; -- Cannot optimize when PK is deferrable explain (costs off) select * from t3 group by a,b,c; -drop table t1; +create temp table t1c () inherits (t1); + +-- Ensure we don't remove any columns when t1 has a child table +explain (costs off) select * from t1 group by a,b,c,d; + +-- Okay to remove columns if we're only querying the parent. +explain (costs off) select * from only t1 group by a,b,c,d; + +create temp table p_t1 ( + a int, + b int, + c int, + d int, + primary key(a,b) +) partition by list(a); +create temp table p_t1_1 partition of p_t1 for values in(1); +create temp table p_t1_2 partition of p_t1 for values in(2); + +-- Ensure we can remove non-PK columns for partitioned tables. +explain (costs off) select * from p_t1 group by a,b,c,d; + +drop table t1 cascade; drop table t2; drop table t3; +drop table p_t1; -- -- Test combinations of DISTINCT and/or ORDER BY @@ -907,3 +973,47 @@ EXPLAIN (COSTS OFF) SELECT balk(hundred) FROM tenk1; SELECT balk(hundred) FROM tenk1; ROLLBACK; + +-- test coverage for aggregate combine/serial/deserial functions +BEGIN ISOLATION LEVEL REPEATABLE READ; + +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 4; +SET enable_indexonlyscan = off; + +-- variance(int4) covers numeric_poly_combine +-- sum(int8) covers int8_avg_combine +-- regr_count(float8, float8) covers int8inc_float8_float8 and aggregates with > 1 arg +EXPLAIN (COSTS OFF, VERBOSE) + SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + +SELECT variance(unique1::int4), sum(unique1::int8), regr_count(unique1::float8, unique1::float8) FROM tenk1; + +ROLLBACK; + +-- test coverage for dense_rank +SELECT dense_rank(x) WITHIN GROUP (ORDER BY x) FROM (VALUES (1),(1),(2),(2),(3),(3)) v(x) GROUP BY (x) ORDER BY 1; + + +-- Ensure that the STRICT checks for aggregates does not take NULLness +-- of ORDER BY columns into account. See bug report around +-- 2a505161-2727-2473-7c46-591ed108ac52@email.cz +SELECT min(x ORDER BY y) FROM (VALUES(1, NULL)) AS d(x,y); +SELECT min(x ORDER BY y) FROM (VALUES(1, 2)) AS d(x,y); + +-- check collation-sensitive matching between grouping expressions +select v||'a', case v||'a' when 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; +select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) + from unnest(array['a','b']) u(v) + group by v||'a' order by 1; + +-- Make sure that generation of HashAggregate for uniqification purposes +-- does not lead to array overflow due to unexpected duplicate hash keys +-- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com +explain (costs off) + select 1 from tenk1 + where (hundred, thousand) in (select twothousand, twothousand from onek); diff --git a/src/test/regress/sql/alter_generic.sql b/src/test/regress/sql/alter_generic.sql index 84fd900b244..ce9dbb1109d 100644 --- a/src/test/regress/sql/alter_generic.sql +++ b/src/test/regress/sql/alter_generic.sql @@ -579,8 +579,6 @@ SELECT nspname, prsname --- --- Cleanup resources --- -\set VERBOSITY terse \\ -- suppress cascade details - DROP FOREIGN DATA WRAPPER alt_fdw2 CASCADE; DROP FOREIGN DATA WRAPPER alt_fdw3 CASCADE; diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 61799b6499d..99af0b851b3 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -35,12 +35,8 @@ ALTER TABLE attmp ADD COLUMN f int2; ALTER TABLE attmp ADD COLUMN g polygon; -ALTER TABLE attmp ADD COLUMN h abstime; - ALTER TABLE attmp ADD COLUMN i char; -ALTER TABLE attmp ADD COLUMN j abstime[]; - ALTER TABLE attmp ADD COLUMN k int4; ALTER TABLE attmp ADD COLUMN l tid; @@ -50,7 +46,7 @@ ALTER TABLE attmp ADD COLUMN m xid; ALTER TABLE attmp ADD COLUMN n oidvector; --ALTER TABLE attmp ADD COLUMN o lock; -ALTER TABLE attmp ADD COLUMN p smgr; +ALTER TABLE attmp ADD COLUMN p boolean; ALTER TABLE attmp ADD COLUMN q point; @@ -60,8 +56,6 @@ ALTER TABLE attmp ADD COLUMN s path; ALTER TABLE attmp ADD COLUMN t box; -ALTER TABLE attmp ADD COLUMN u tinterval; - ALTER TABLE attmp ADD COLUMN v timestamp; ALTER TABLE attmp ADD COLUMN w interval; @@ -72,13 +66,13 @@ ALTER TABLE attmp ADD COLUMN y float4[]; ALTER TABLE attmp ADD COLUMN z int2[]; -INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', - 'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}', + 'c', 314159, '(1,1)', '512', - '1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', - '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); SELECT * FROM attmp; @@ -104,12 +98,8 @@ ALTER TABLE attmp ADD COLUMN f int2; ALTER TABLE attmp ADD COLUMN g polygon; -ALTER TABLE attmp ADD COLUMN h abstime; - ALTER TABLE attmp ADD COLUMN i char; -ALTER TABLE attmp ADD COLUMN j abstime[]; - ALTER TABLE attmp ADD COLUMN k int4; ALTER TABLE attmp ADD COLUMN l tid; @@ -119,7 +109,7 @@ ALTER TABLE attmp ADD COLUMN m xid; ALTER TABLE attmp ADD COLUMN n oidvector; --ALTER TABLE attmp ADD COLUMN o lock; -ALTER TABLE attmp ADD COLUMN p smgr; +ALTER TABLE attmp ADD COLUMN p boolean; ALTER TABLE attmp ADD COLUMN q point; @@ -129,8 +119,6 @@ ALTER TABLE attmp ADD COLUMN s path; ALTER TABLE attmp ADD COLUMN t box; -ALTER TABLE attmp ADD COLUMN u tinterval; - ALTER TABLE attmp ADD COLUMN v timestamp; ALTER TABLE attmp ADD COLUMN w interval; @@ -141,13 +129,13 @@ ALTER TABLE attmp ADD COLUMN y float4[]; ALTER TABLE attmp ADD COLUMN z int2[]; -INSERT INTO attmp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, p, q, r, s, t, u, +INSERT INTO attmp (a, b, c, d, e, f, g, i, k, l, m, n, p, q, r, s, t, v, w, x, y, z) VALUES (4, 'name', 'text', 4.1, 4.1, 2, '(4.1,4.1,3.1,3.1)', - 'Mon May 1 00:30:30 1995', 'c', '{Mon May 1 00:30:30 1995, Monday Aug 24 14:43:07 1992, epoch}', + 'c', 314159, '(1,1)', '512', - '1 2 3 4 5 6 7 8', 'magnetic disk', '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', - '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', '["epoch" "infinity"]', + '1 2 3 4 5 6 7 8', true, '(1.1,1.1)', '(4.1,4.1,3.1,3.1)', + '(0,2,4.1,4.1,3.1,3.1)', '(4.1,4.1,3.1,3.1)', 'epoch', '01:00:10', '{1.0,2.0,3.0,4.0}', '{1.0,2.0,3.0,4.0}', '{1,2,3,4}'); SELECT * FROM attmp; @@ -191,6 +179,21 @@ SELECT * FROM attmp_new2; DROP TABLE attmp_new; DROP TABLE attmp_new2; +-- check rename of partitioned tables and indexes also +CREATE TABLE part_attmp (a int primary key) partition by range (a); +CREATE TABLE part_attmp1 PARTITION OF part_attmp FOR VALUES FROM (0) TO (100); +ALTER INDEX part_attmp_pkey RENAME TO part_attmp_index; +ALTER INDEX part_attmp1_pkey RENAME TO part_attmp1_index; +ALTER TABLE part_attmp RENAME TO part_at2tmp; +ALTER TABLE part_attmp1 RENAME TO part_at2tmp1; +SET ROLE regress_alter_table_user1; +ALTER INDEX part_attmp_index RENAME TO fail; +ALTER INDEX part_attmp1_index RENAME TO fail; +ALTER TABLE part_at2tmp RENAME TO fail; +ALTER TABLE part_at2tmp1 RENAME TO fail; +RESET ROLE; +DROP TABLE part_at2tmp; + -- -- check renaming to a table's array type's autogenerated name -- (the array type's name should get out of the way) @@ -286,6 +289,20 @@ DROP TABLE constraint_rename_test; ALTER TABLE IF EXISTS constraint_not_exist RENAME CONSTRAINT con3 TO con3foo; -- ok ALTER TABLE IF EXISTS constraint_rename_test ADD CONSTRAINT con4 UNIQUE (a); +-- renaming constraints with cache reset of target relation +CREATE TABLE constraint_rename_cache (a int, + CONSTRAINT chk_a CHECK (a > 0), + PRIMARY KEY (a)); +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT chk_a TO chk_a_new; +ALTER TABLE constraint_rename_cache + RENAME CONSTRAINT constraint_rename_cache_pkey TO constraint_rename_pkey_new; +CREATE TABLE like_constraint_rename_cache + (LIKE constraint_rename_cache INCLUDING ALL); +\d like_constraint_rename_cache +DROP TABLE constraint_rename_cache; +DROP TABLE like_constraint_rename_cache; + -- FOREIGN KEY CONSTRAINT adding TEST CREATE TABLE attmp2 (a int primary key); @@ -623,7 +640,7 @@ drop table atacc1; -- test unique constraint adding -create table atacc1 ( test int ) with oids; +create table atacc1 ( test int ) ; -- add a unique constraint alter table atacc1 add constraint atacc_test1 unique (test); -- insert first value @@ -632,8 +649,6 @@ insert into atacc1 (test) values (2); insert into atacc1 (test) values (2); -- should succeed insert into atacc1 (test) values (4); --- try adding a unique oid constraint -alter table atacc1 add constraint atacc_oid1 unique(oid); -- try to create duplicates via alter table using - should fail alter table atacc1 alter column test type integer using 0; drop table atacc1; @@ -679,7 +694,7 @@ drop table atacc1; -- test primary key constraint adding -create table atacc1 ( test int ) with oids; +create table atacc1 ( id serial, test int) ; -- add a primary key constraint alter table atacc1 add constraint atacc_test1 primary key (test); -- insert first value @@ -691,11 +706,11 @@ insert into atacc1 (test) values (4); -- inserting NULL should fail insert into atacc1 (test) values(NULL); -- try adding a second primary key (should fail) -alter table atacc1 add constraint atacc_oid1 primary key(oid); +alter table atacc1 add constraint atacc_oid1 primary key(id); -- drop first primary key constraint alter table atacc1 drop constraint atacc_test1 restrict; -- try adding a primary key on oid (should succeed) -alter table atacc1 add constraint atacc_oid1 primary key(oid); +alter table atacc1 add constraint atacc_oid1 primary key(id); drop table atacc1; -- let's do one where the primary key constraint fails when added @@ -734,6 +749,14 @@ alter table atacc1 add column test2 int primary key; alter table atacc1 add column test2 int default 0 primary key; drop table atacc1; +-- this combination used to have order-of-execution problems (bug #15580) +create table atacc1 (a int); +insert into atacc1 values(1); +alter table atacc1 + add column b float8 not null default random(), + add primary key(a); +drop table atacc1; + -- something a little more complicated create table atacc1 ( test int, test2 int); -- add a primary key constraint @@ -772,7 +795,7 @@ alter table non_existent alter column bar drop not null; -- test setting columns to null and not null and vice versa -- test checking for null values and primary key -create table atacc1 (test int not null) with oids; +create table atacc1 (test int not null); alter table atacc1 add constraint "atacc1_pkey" primary key (test); alter table atacc1 alter column test drop not null; alter table atacc1 drop constraint "atacc1_pkey"; @@ -786,10 +809,6 @@ alter table atacc1 alter test set not null; alter table atacc1 alter bar set not null; alter table atacc1 alter bar drop not null; --- try altering the oid column, should fail -alter table atacc1 alter oid set not null; -alter table atacc1 alter oid drop not null; - -- try creating a view and altering that, should fail create view myview as select * from atacc1; alter table myview alter column test drop not null; @@ -798,6 +817,41 @@ drop view myview; drop table atacc1; +-- set not null verified by constraints +create table atacc1 (test_a int, test_b int); +insert into atacc1 values (null, 1); +-- constraint not cover all values, should fail +alter table atacc1 add constraint atacc1_constr_or check(test_a is not null or test_b < 10); +alter table atacc1 alter test_a set not null; +alter table atacc1 drop constraint atacc1_constr_or; +-- not valid constraint, should fail +alter table atacc1 add constraint atacc1_constr_invalid check(test_a is not null) not valid; +alter table atacc1 alter test_a set not null; +alter table atacc1 drop constraint atacc1_constr_invalid; +-- with valid constraint +update atacc1 set test_a = 1; +alter table atacc1 add constraint atacc1_constr_a_valid check(test_a is not null); +alter table atacc1 alter test_a set not null; +delete from atacc1; + +insert into atacc1 values (2, null); +alter table atacc1 alter test_a drop not null; +-- test multiple set not null at same time +-- test_a checked by atacc1_constr_a_valid, test_b should fail by table scan +alter table atacc1 alter test_a set not null, alter test_b set not null; +-- commands order has no importance +alter table atacc1 alter test_b set not null, alter test_a set not null; + +-- valid one by table scan, one by check constraints +update atacc1 set test_b = 1; +alter table atacc1 alter test_b set not null, alter test_a set not null; + +alter table atacc1 alter test_a drop not null, alter test_b drop not null; +-- both column has check constraints +alter table atacc1 add constraint atacc1_constr_b_valid check(test_b is not null); +alter table atacc1 alter test_b set not null, alter test_a set not null; +drop table atacc1; + -- test inheritance create table parent (a int); create table child (b varchar(255)) inherits (parent); @@ -869,7 +923,7 @@ alter table pg_class drop column relname; alter table nosuchtable drop column bar; -- test dropping columns -create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) with oids; +create table atacc1 (a int4 not null, b int4, c int4 not null, d int4); insert into atacc1 values (1, 2, 3, 4); alter table atacc1 drop a; alter table atacc1 drop a; @@ -919,8 +973,11 @@ delete from atacc1; -- try dropping a non-existent column, should fail alter table atacc1 drop bar; --- try dropping the oid column, should succeed -alter table atacc1 drop oid; +-- try removing an oid column, should succeed (as it's nonexistent) +alter table atacc1 SET WITHOUT OIDS; + +-- try adding an oid column, should fail (not supported) +alter table atacc1 SET WITH OIDS; -- try dropping the xmin column, should fail alter table atacc1 drop xmin; @@ -1180,74 +1237,6 @@ from pg_attribute where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2') order by attrelid::regclass::text, attnum; --- --- Test the ALTER TABLE SET WITH/WITHOUT OIDS command --- -create table altstartwith (col integer) with oids; - -insert into altstartwith values (1); - -select oid > 0, * from altstartwith; - -alter table altstartwith set without oids; - -select oid > 0, * from altstartwith; -- fails -select * from altstartwith; - -alter table altstartwith set with oids; - -select oid > 0, * from altstartwith; - -drop table altstartwith; - --- Check inheritance cases -create table altwithoid (col integer) with oids; - --- Inherits parents oid column anyway -create table altinhoid () inherits (altwithoid) without oids; - -insert into altinhoid values (1); - -select oid > 0, * from altwithoid; -select oid > 0, * from altinhoid; - -alter table altwithoid set without oids; - -select oid > 0, * from altwithoid; -- fails -select oid > 0, * from altinhoid; -- fails -select * from altwithoid; -select * from altinhoid; - -alter table altwithoid set with oids; - -select oid > 0, * from altwithoid; -select oid > 0, * from altinhoid; - -drop table altwithoid cascade; - -create table altwithoid (col integer) without oids; - --- child can have local oid column -create table altinhoid () inherits (altwithoid) with oids; - -insert into altinhoid values (1); - -select oid > 0, * from altwithoid; -- fails -select oid > 0, * from altinhoid; - -alter table altwithoid set with oids; - -select oid > 0, * from altwithoid; -select oid > 0, * from altinhoid; - --- the child's local definition should remain -alter table altwithoid set without oids; - -select oid > 0, * from altwithoid; -- fails -select oid > 0, * from altinhoid; - -drop table altwithoid cascade; - -- test renumbering of child-table columns in inherited operations create table p1 (f1 int); @@ -1328,6 +1317,31 @@ select * from anothertab; drop table anothertab; +-- Test index handling in alter table column type (cf. bugs #15835, #15865) +create table anothertab(f1 int primary key, f2 int unique, + f3 int, f4 int, f5 int); +alter table anothertab + add exclude using btree (f3 with =); +alter table anothertab + add exclude using btree (f4 with =) where (f4 is not null); +alter table anothertab + add exclude using btree (f4 with =) where (f5 > 0); +alter table anothertab + add unique(f1,f4); +create index on anothertab(f2,f3); +create unique index on anothertab(f4); + +\d anothertab +alter table anothertab alter column f1 type bigint; +alter table anothertab + alter column f2 type bigint, + alter column f3 type bigint, + alter column f4 type bigint; +alter table anothertab alter column f5 type bigint; +\d anothertab + +drop table anothertab; + create table another (f1 int, f2 text); insert into another values(1, 'one'); @@ -1364,6 +1378,69 @@ alter table at_partitioned attach partition at_part_2 for values from (1000) to alter table at_partitioned alter column b type numeric using b::numeric; \d at_part_1 \d at_part_2 +drop table at_partitioned; + +-- Alter column type when no table rewrite is required +-- Also check that comments are preserved +create table at_partitioned(id int, name varchar(64), unique (id, name)) + partition by hash(id); +comment on constraint at_partitioned_id_name_key on at_partitioned is 'parent constraint'; +comment on index at_partitioned_id_name_key is 'parent index'; +create table at_partitioned_0 partition of at_partitioned + for values with (modulus 2, remainder 0); +comment on constraint at_partitioned_0_id_name_key on at_partitioned_0 is 'child 0 constraint'; +comment on index at_partitioned_0_id_name_key is 'child 0 index'; +create table at_partitioned_1 partition of at_partitioned + for values with (modulus 2, remainder 1); +comment on constraint at_partitioned_1_id_name_key on at_partitioned_1 is 'child 1 constraint'; +comment on index at_partitioned_1_id_name_key is 'child 1 index'; +insert into at_partitioned values(1, 'foo'); +insert into at_partitioned values(3, 'bar'); + +create temp table old_oids as + select relname, oid as oldoid, relfilenode as oldfilenode + from pg_class where relname like 'at_partitioned%'; + +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname; + +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname; + +alter table at_partitioned alter column name type varchar(127); + +-- Note: these tests currently show the wrong behavior for comments :-( + +select relname, + c.oid = oldoid as orig_oid, + case relfilenode + when 0 then 'none' + when c.oid then 'own' + when oldfilenode then 'orig' + else 'OTHER' + end as storage, + obj_description(c.oid, 'pg_class') as desc + from pg_class c left join old_oids using (relname) + where relname like 'at_partitioned%' + order by relname; + +select conname, obj_description(oid, 'pg_constraint') as desc + from pg_constraint where conname like 'at_partitioned%' + order by conname; + +-- Don't remove this DROP, it exposes bug #15672 +drop table at_partitioned; -- disallow recursive containment of row types create temp table recur1 (f1 int); @@ -1658,7 +1735,7 @@ create operator alter1.=(procedure = alter1.same, leftarg = alter1.ctype, right create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as operator 1 alter1.=(alter1.ctype, alter1.ctype); -create conversion alter1.ascii_to_utf8 for 'sql_ascii' to 'utf8' from ascii_to_utf8; +create conversion alter1.latin1_to_utf8 for 'latin1' to 'utf8' from iso8859_1_to_utf8; create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype); create text search configuration alter1.cfg(parser = alter1.prs); @@ -1679,7 +1756,7 @@ alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2; alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2; alter type alter1.ctype set schema alter1; -- no-op, same schema alter type alter1.ctype set schema alter2; -alter conversion alter1.ascii_to_utf8 set schema alter2; +alter conversion alter1.latin1_to_utf8 set schema alter2; alter text search parser alter1.prs set schema alter2; alter text search configuration alter1.cfg set schema alter2; alter text search template alter1.tmpl set schema alter2; @@ -1800,7 +1877,7 @@ CREATE TABLE tt3 (y numeric(8,2), x int); -- wrong column order CREATE TABLE tt4 (x int); -- too few columns CREATE TABLE tt5 (x int, y numeric(8,2), z int); -- too few columns CREATE TABLE tt6 () INHERITS (tt0); -- can't have a parent -CREATE TABLE tt7 (x int, q text, y numeric(8,2)) WITH OIDS; +CREATE TABLE tt7 (x int, q text, y numeric(8,2)); ALTER TABLE tt7 DROP q; -- OK ALTER TABLE tt0 OF tt_t0; @@ -1850,6 +1927,24 @@ ALTER TABLE IF EXISTS tt8 SET SCHEMA alter2; DROP TABLE alter2.tt8; DROP SCHEMA alter2; +-- +-- Check conflicts between index and CHECK constraint names +-- +CREATE TABLE tt9(c integer); +ALTER TABLE tt9 ADD CHECK(c > 1); +ALTER TABLE tt9 ADD CHECK(c > 2); -- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 3); +ALTER TABLE tt9 ADD CONSTRAINT foo CHECK(c > 4); -- fail, dup name +ALTER TABLE tt9 ADD UNIQUE(c); +ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key UNIQUE(c); -- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT foo UNIQUE(c); -- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key CHECK(c > 5); -- fail, dup name +ALTER TABLE tt9 ADD CONSTRAINT tt9_c_key2 CHECK(c > 6); +ALTER TABLE tt9 ADD UNIQUE(c); -- picks nonconflicting name +\d tt9 +DROP TABLE tt9; + -- Check that comments on constraints and indexes are not lost at ALTER TABLE. CREATE TABLE comment_test ( @@ -1932,10 +2027,9 @@ CREATE TABLE pg_catalog.new_system_table(); -- instead create in public first, move to catalog CREATE TABLE new_system_table(id serial primary key, othercol text); ALTER TABLE new_system_table SET SCHEMA pg_catalog; - --- XXX: it's currently impossible to move relations out of pg_catalog ALTER TABLE new_system_table SET SCHEMA public; --- move back, will be ignored -- already there +ALTER TABLE new_system_table SET SCHEMA pg_catalog; +-- will be ignored -- already there: ALTER TABLE new_system_table SET SCHEMA pg_catalog; ALTER TABLE new_system_table RENAME TO old_system_table; CREATE INDEX old_system_table__othercol ON old_system_table (othercol); @@ -2007,9 +2101,13 @@ ALTER TABLE test_add_column \d test_add_column ALTER TABLE test_add_column ADD COLUMN c2 integer; -- fail because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN c2 integer; -- fail because c2 already exists \d test_add_column ALTER TABLE test_add_column ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists +ALTER TABLE ONLY test_add_column + ADD COLUMN IF NOT EXISTS c2 integer; -- skipping because c2 already exists \d test_add_column ALTER TABLE test_add_column ADD COLUMN c2 integer, -- fail because c2 already exists @@ -2079,7 +2177,7 @@ ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES FROM (1) TO (10); DROP TABLE fail_part; -- check that the table being attached exists -ALTER TABLE list_parted ATTACH PARTITION nonexistant FOR VALUES IN (1); +ALTER TABLE list_parted ATTACH PARTITION nonexistent FOR VALUES IN (1); -- check ownership of the source table CREATE ROLE regress_test_me; @@ -2115,16 +2213,6 @@ CREATE TABLE fail_part OF mytype; ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); DROP TYPE mytype CASCADE; --- check existence (or non-existence) of oid column -ALTER TABLE list_parted SET WITH OIDS; -CREATE TABLE fail_part (a int); -ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); - -ALTER TABLE list_parted SET WITHOUT OIDS; -ALTER TABLE fail_part SET WITH OIDS; -ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); -DROP TABLE fail_part; - -- check that the table being attached has only columns present in the parent CREATE TABLE fail_part (like list_parted, c int); ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1); @@ -2367,21 +2455,14 @@ DROP TABLE quuux; -- check validation when attaching hash partitions --- The default hash functions as they exist today aren't portable; they can --- return different results on different machines. Depending upon how the --- values are hashed, the row may map to different partitions, which result in --- regression failure. To avoid this, let's create a non-default hash function --- that just returns the input value unchanged. -CREATE OR REPLACE FUNCTION dummy_hashint4(a int4, seed int8) RETURNS int8 AS -$$ BEGIN RETURN (a + 1 + seed); END; $$ LANGUAGE 'plpgsql' IMMUTABLE; -CREATE OPERATOR CLASS custom_opclass FOR TYPE int4 USING HASH AS -OPERATOR 1 = , FUNCTION 2 dummy_hashint4(int4, int8); +-- Use hand-rolled hash functions and operator class to get predictable result +-- on different matchines. part_test_int4_ops is defined in insert.sql. -- check that the new partition won't overlap with an existing partition CREATE TABLE hash_parted ( a int, b int -) PARTITION BY HASH (a custom_opclass); +) PARTITION BY HASH (a part_test_int4_ops); CREATE TABLE hpart_1 PARTITION OF hash_parted FOR VALUES WITH (MODULUS 4, REMAINDER 0); CREATE TABLE fail_part (LIKE hpart_1); ALTER TABLE hash_parted ATTACH PARTITION fail_part FOR VALUES WITH (MODULUS 8, REMAINDER 4); @@ -2519,8 +2600,6 @@ SELECT * FROM list_parted; DROP TABLE list_parted, list_parted2, range_parted; DROP TABLE fail_def_part; DROP TABLE hash_parted; -DROP OPERATOR CLASS custom_opclass USING HASH; -DROP FUNCTION dummy_hashint4(a int4, seed int8); -- more tests for certain multi-level partitioning scenarios create table p (a int, b int) partition by range (a, b); @@ -2564,3 +2643,72 @@ ANALYZE attmp; DROP TABLE attmp; DROP USER regress_alter_table_user1; + +-- check that violating rows are correctly reported when attaching as the +-- default partition +create table defpart_attach_test (a int) partition by list (a); +create table defpart_attach_test1 partition of defpart_attach_test for values in (1); +create table defpart_attach_test_d (b int, a int); +alter table defpart_attach_test_d drop b; +insert into defpart_attach_test_d values (1), (2); + +-- error because its constraint as the default partition would be violated +-- by the row containing 1 +alter table defpart_attach_test attach partition defpart_attach_test_d default; +delete from defpart_attach_test_d where a = 1; +alter table defpart_attach_test_d add check (a > 1); + +-- should be attached successfully and without needing to be scanned +alter table defpart_attach_test attach partition defpart_attach_test_d default; + +-- check that attaching a partition correctly reports any rows in the default +-- partition that should not be there for the new partition to be attached +-- successfully +create table defpart_attach_test_2 (like defpart_attach_test_d); +alter table defpart_attach_test attach partition defpart_attach_test_2 for values in (2); + +drop table defpart_attach_test; + +-- check combinations of temporary and permanent relations when attaching +-- partitions. +create table perm_part_parent (a int) partition by list (a); +create temp table temp_part_parent (a int) partition by list (a); +create table perm_part_child (a int); +create temp table temp_part_child (a int); +alter table temp_part_parent attach partition perm_part_child default; -- error +alter table perm_part_parent attach partition temp_part_child default; -- error +alter table temp_part_parent attach partition temp_part_child default; -- ok +drop table perm_part_parent cascade; +drop table temp_part_parent cascade; + +-- check that attaching partitions to a table while it is being used is +-- prevented +create table tab_part_attach (a int) partition by list (a); +create or replace function func_part_attach() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_attach_1 (a int)'; + execute 'alter table tab_part_attach attach partition tab_part_attach_1 for values in (1)'; + return null; + end $$; +create trigger trig_part_attach before insert on tab_part_attach + for each statement execute procedure func_part_attach(); +insert into tab_part_attach values (1); +drop table tab_part_attach; +drop function func_part_attach(); + +-- test case where the partitioning operator is a SQL function whose +-- evaluation results in the table's relcache being rebuilt partway through +-- the execution of an ATTACH PARTITION command +create function at_test_sql_partop (int4, int4) returns int language sql +as $$ select case when $1 = $2 then 0 when $1 > $2 then 1 else -1 end; $$; +create operator class at_test_sql_partop for type int4 using btree as + operator 1 < (int4, int4), operator 2 <= (int4, int4), + operator 3 = (int4, int4), operator 4 >= (int4, int4), + operator 5 > (int4, int4), function 1 at_test_sql_partop(int4, int4); +create table at_test_sql_partop (a int) partition by range (a at_test_sql_partop); +create table at_test_sql_partop_1 (a int); +alter table at_test_sql_partop attach partition at_test_sql_partop_1 for values from (0) to (10); +drop table at_test_sql_partop; +drop operator class at_test_sql_partop using btree; +drop function at_test_sql_partop; diff --git a/src/test/regress/sql/amutils.sql b/src/test/regress/sql/amutils.sql index 8ca85ecf006..06e7fa10d95 100644 --- a/src/test/regress/sql/amutils.sql +++ b/src/test/regress/sql/amutils.sql @@ -40,7 +40,8 @@ select prop, pg_index_column_has_property('onek_hundred'::regclass, 1, prop) as btree, pg_index_column_has_property('hash_i4_index'::regclass, 1, prop) as hash, pg_index_column_has_property('gcircleind'::regclass, 1, prop) as gist, - pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist, + pg_index_column_has_property('sp_radix_ind'::regclass, 1, prop) as spgist_radix, + pg_index_column_has_property('sp_quad_ind'::regclass, 1, prop) as spgist_quad, pg_index_column_has_property('botharrayidx'::regclass, 1, prop) as gin, pg_index_column_has_property('brinidx'::regclass, 1, prop) as brin from unnest(array['asc', 'desc', 'nulls_first', 'nulls_last', diff --git a/src/test/regress/sql/bit.sql b/src/test/regress/sql/bit.sql index 419d47c8b75..f47b8699207 100644 --- a/src/test/regress/sql/bit.sql +++ b/src/test/regress/sql/bit.sql @@ -168,6 +168,10 @@ SELECT POSITION(B'1101' IN b), POSITION(B'11011' IN b), b FROM BIT_SHIFT_TABLE ; +SELECT b, b >> 1 AS bsr, b << 1 AS bsl + FROM BIT_SHIFT_TABLE ; +SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl + FROM BIT_SHIFT_TABLE ; CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)); @@ -180,7 +184,8 @@ SELECT POSITION(B'1101' IN v), POSITION(B'11011' IN v), v FROM VARBIT_SHIFT_TABLE ; - +SELECT v, v >> 1 AS vsr, v << 1 AS vsl + FROM VARBIT_SHIFT_TABLE ; DROP TABLE BIT_SHIFT_TABLE; DROP TABLE VARBIT_SHIFT_TABLE; @@ -195,3 +200,14 @@ SELECT overlay(B'0101011100' placing '001' from 2 for 3); SELECT overlay(B'0101011100' placing '101' from 6); SELECT overlay(B'0101011100' placing '001' from 11); SELECT overlay(B'0101011100' placing '001' from 20); + +-- This table is intentionally left around to exercise pg_dump/pg_upgrade +CREATE TABLE bit_defaults( + b1 bit(4) DEFAULT '1001', + b2 bit(4) DEFAULT B'0101', + b3 bit varying(5) DEFAULT '1001', + b4 bit varying(5) DEFAULT B'0101' +); +\d bit_defaults +INSERT INTO bit_defaults DEFAULT VALUES; +TABLE bit_defaults; diff --git a/src/test/regress/sql/box.sql b/src/test/regress/sql/box.sql index 135ac108ebd..cd3e00261f7 100644 --- a/src/test/regress/sql/box.sql +++ b/src/test/regress/sql/box.sql @@ -25,6 +25,9 @@ INSERT INTO BOX_TBL (f1) VALUES ('(2.0,2.0,0.0,0.0)'); INSERT INTO BOX_TBL (f1) VALUES ('(1.0,1.0,3.0,3.0)'); +INSERT INTO BOX_TBL (f1) VALUES ('((-8, 2), (-2, -10))'); + + -- degenerate cases where the box is a line or a point -- note that lines and points boxes all have zero area INSERT INTO BOX_TBL (f1) VALUES ('(2.5, 2.5, 2.5,3.5)'); @@ -34,6 +37,12 @@ INSERT INTO BOX_TBL (f1) VALUES ('(3.0, 3.0,3.0,3.0)'); -- badly formatted box inputs INSERT INTO BOX_TBL (f1) VALUES ('(2.3, 4.5)'); +INSERT INTO BOX_TBL (f1) VALUES ('[1, 2, 3, 4)'); + +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4]'); + +INSERT INTO BOX_TBL (f1) VALUES ('(1, 2, 3, 4) x'); + INSERT INTO BOX_TBL (f1) VALUES ('asdfasdf(ad'); @@ -183,28 +192,41 @@ DROP INDEX box_spgist; -- -- Test the SP-GiST index on the larger volume of data -- -CREATE TABLE quad_box_tbl (b box); +CREATE TABLE quad_box_tbl (id int, b box); INSERT INTO quad_box_tbl - SELECT box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) - FROM generate_series(1, 100) x, - generate_series(1, 100) y; + SELECT (x - 1) * 100 + y, box(point(x * 10, y * 10), point(x * 10 + 5, y * 10 + 5)) + FROM generate_series(1, 100) x, + generate_series(1, 100) y; -- insert repeating data to test allTheSame INSERT INTO quad_box_tbl - SELECT '((200, 300),(210, 310))' - FROM generate_series(1, 1000); + SELECT i, '((200, 300),(210, 310))' + FROM generate_series(10001, 11000) AS i; INSERT INTO quad_box_tbl - VALUES - (NULL), - (NULL), - ('((-infinity,-infinity),(infinity,infinity))'), - ('((-infinity,100),(-infinity,500))'), - ('((-infinity,-infinity),(700,infinity))'); +VALUES + (11001, NULL), + (11002, NULL), + (11003, '((-infinity,-infinity),(infinity,infinity))'), + (11004, '((-infinity,100),(-infinity,500))'), + (11005, '((-infinity,-infinity),(700,infinity))'); CREATE INDEX quad_box_tbl_idx ON quad_box_tbl USING spgist(b); +-- get reference results for ORDER BY distance from seq scan +SET enable_seqscan = ON; +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; + +CREATE TABLE quad_box_tbl_ord_seq1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +CREATE TABLE quad_box_tbl_ord_seq2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + SET enable_seqscan = OFF; SET enable_indexscan = ON; SET enable_bitmapscan = ON; @@ -223,6 +245,39 @@ SELECT count(*) FROM quad_box_tbl WHERE b @> box '((201,301),(202,303))'; SELECT count(*) FROM quad_box_tbl WHERE b <@ box '((100,200),(300,500))'; SELECT count(*) FROM quad_box_tbl WHERE b ~= box '((200,300),(205,305))'; +-- test ORDER BY distance +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; + +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +CREATE TEMP TABLE quad_box_tbl_ord_idx1 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl; + +SELECT * +FROM quad_box_tbl_ord_seq1 seq FULL JOIN quad_box_tbl_ord_idx1 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + + +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + +CREATE TEMP TABLE quad_box_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id +FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; + +SELECT * +FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; diff --git a/src/test/regress/sql/btree_index.sql b/src/test/regress/sql/btree_index.sql index 21171f77625..48eaf4fe425 100644 --- a/src/test/regress/sql/btree_index.sql +++ b/src/test/regress/sql/btree_index.sql @@ -59,39 +59,48 @@ SELECT b.* set enable_seqscan to false; set enable_indexscan to true; set enable_bitmapscan to false; +explain (costs off) select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1; +select proname from pg_proc where proname ilike '00%foo' order by 1; +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1; set enable_indexscan to false; set enable_bitmapscan to true; +explain (costs off) select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; +select proname from pg_proc where proname like E'RI\\_FKey%del' order by 1; +explain (costs off) +select proname from pg_proc where proname ilike '00%foo' order by 1; +select proname from pg_proc where proname ilike '00%foo' order by 1; +explain (costs off) +select proname from pg_proc where proname ilike 'ri%foo' order by 1; --- --- Test B-tree page deletion. In particular, deleting a non-leaf page. --- - --- First create a tree that's at least four levels deep. The text inserted --- is long and poorly compressible. That way only a few index tuples fit on --- each page, allowing us to get a tall tree with fewer pages. -create table btree_tall_tbl(id int4, t text); -create index btree_tall_idx on btree_tall_tbl (id, t) with (fillfactor = 10); -insert into btree_tall_tbl - select g, g::text || '_' || - (select string_agg(md5(i::text), '_') from generate_series(1, 50) i) -from generate_series(1, 100) g; - --- Delete most entries, and vacuum. This causes page deletions. -delete from btree_tall_tbl where id < 950; -vacuum btree_tall_tbl; +reset enable_seqscan; +reset enable_indexscan; +reset enable_bitmapscan; -- --- Test B-tree insertion with a metapage update (XLOG_BTREE_INSERT_META --- WAL record type). This happens when a "fast root" page is split. +-- Test B-tree fast path (cache rightmost leaf page) optimization. -- --- The vacuum above should've turned the leaf page into a fast root. We just --- need to insert some rows to cause the fast root page to split. -insert into btree_tall_tbl (id, t) - select g, repeat('x', 100) from generate_series(1, 500) g; +-- First create a tree that's at least three levels deep (i.e. has one level +-- between the root and leaf levels). The text inserted is long. It won't be +-- compressed because we use plain storage in the table. Only a few index +-- tuples fit on each internal page, allowing us to get a tall tree with few +-- pages. (A tall tree is required to trigger caching.) +-- +-- The text column must be the leading column in the index, since suffix +-- truncation would otherwise truncate tuples on internal pages, leaving us +-- with a short tree. +create table btree_tall_tbl(id int4, t text); +alter table btree_tall_tbl alter COLUMN t set storage plain; +create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10); +insert into btree_tall_tbl select g, repeat('x', 250) +from generate_series(1, 130) g; -- -- Test vacuum_cleanup_index_scale_factor @@ -111,3 +120,23 @@ create index btree_idx_err on btree_test(a) with (vacuum_cleanup_index_scale_fac -- Simple ALTER INDEX alter index btree_idx1 set (vacuum_cleanup_index_scale_factor = 70.0); select reloptions from pg_class WHERE oid = 'btree_idx1'::regclass; + +-- +-- Test for multilevel page deletion +-- +CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; +ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); +-- Delete most entries, and vacuum, deleting internal pages and creating "fast +-- root" +DELETE FROM delete_test_table WHERE a < 79990; +VACUUM delete_test_table; + +-- +-- Test B-tree insertion with a metapage update (XLOG_BTREE_INSERT_META +-- WAL record type). This happens when a "fast root" page is split. This +-- also creates coverage for nbtree FSM page recycling. +-- +-- The vacuum above should've turned the leaf page into a fast root. We just +-- need to insert some rows to cause the fast root page to split. +INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; diff --git a/src/test/regress/sql/case.sql b/src/test/regress/sql/case.sql index 66b6e98fb18..17436c524a7 100644 --- a/src/test/regress/sql/case.sql +++ b/src/test/regress/sql/case.sql @@ -233,6 +233,19 @@ SELECT CASE make_ad(1,2) ROLLBACK; +-- Test interaction of CASE with ArrayCoerceExpr (bug #15471) +BEGIN; + +CREATE TYPE casetestenum AS ENUM ('e', 'f', 'g'); + +SELECT + CASE 'foo'::text + WHEN 'foo' THEN ARRAY['a', 'b', 'c', 'd'] || enum_range(NULL::casetestenum)::text[] + ELSE ARRAY['x', 'y'] + END; + +ROLLBACK; + -- -- Clean up -- diff --git a/src/test/regress/sql/circle.sql b/src/test/regress/sql/circle.sql index c0284b2b598..7e582c6c29d 100644 --- a/src/test/regress/sql/circle.sql +++ b/src/test/regress/sql/circle.sql @@ -2,6 +2,10 @@ -- CIRCLE -- +-- Back off displayed precision a little bit to reduce platform-to-platform +-- variation in results. +SET extra_float_digits = -1; + CREATE TABLE CIRCLE_TBL (f1 circle); INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>'); @@ -14,12 +18,20 @@ INSERT INTO CIRCLE_TBL VALUES ('((1,2),3)'); INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10>'); -INSERT INTO CIRCLE_TBL VALUES ('<(100,1),115>'); +INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > '); + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>'); -- Zero radius + +INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>'); -- NaN radius -- bad values INSERT INTO CIRCLE_TBL VALUES ('<(-100,0),-100>'); +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10'); + +INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10> x'); + INSERT INTO CIRCLE_TBL VALUES ('1abc,3,5'); INSERT INTO CIRCLE_TBL VALUES ('(3,(1,2),3)'); diff --git a/src/test/regress/sql/collate.icu.utf8.sql b/src/test/regress/sql/collate.icu.utf8.sql index ef39445b301..67de7d97949 100644 --- a/src/test/regress/sql/collate.icu.utf8.sql +++ b/src/test/regress/sql/collate.icu.utf8.sql @@ -2,6 +2,14 @@ * This test is for ICU collations. */ +/* skip test if not UTF8 server encoding or no ICU collations installed */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collprovider = 'i') = 0 + AS skip_test \gset +\if :skip_test +\quit +\endif + SET client_encoding TO UTF8; CREATE SCHEMA collate_tests; @@ -333,6 +341,15 @@ CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); -- fail SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1; +set enable_seqscan = off; +explain (costs off) +select * from collate_test1 where b ilike 'abc'; +select * from collate_test1 where b ilike 'abc'; +explain (costs off) +select * from collate_test1 where b ilike 'ABC'; +select * from collate_test1 where b ilike 'ABC'; +reset enable_seqscan; + -- schema manipulation commands @@ -425,9 +442,291 @@ drop type textrange_c; drop type textrange_en_us; +-- test ICU collation customization + +-- test the attributes handled by icu_set_collation_attributes() + +CREATE COLLATION testcoll_ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes'); +SELECT 'aaá' > 'AAA' COLLATE "und-x-icu", 'aaá' < 'AAA' COLLATE testcoll_ignore_accents; + +CREATE COLLATION testcoll_backwards (provider = icu, locale = '@colBackwards=yes'); +SELECT 'coté' < 'côte' COLLATE "und-x-icu", 'coté' > 'côte' COLLATE testcoll_backwards; + +CREATE COLLATION testcoll_lower_first (provider = icu, locale = '@colCaseFirst=lower'); +CREATE COLLATION testcoll_upper_first (provider = icu, locale = '@colCaseFirst=upper'); +SELECT 'aaa' < 'AAA' COLLATE testcoll_lower_first, 'aaa' > 'AAA' COLLATE testcoll_upper_first; + +CREATE COLLATION testcoll_shifted (provider = icu, locale = '@colAlternate=shifted'); +SELECT 'de-luge' < 'deanza' COLLATE "und-x-icu", 'de-luge' > 'deanza' COLLATE testcoll_shifted; + +CREATE COLLATION testcoll_numeric (provider = icu, locale = '@colNumeric=yes'); +SELECT 'A-21' > 'A-123' COLLATE "und-x-icu", 'A-21' < 'A-123' COLLATE testcoll_numeric; + +CREATE COLLATION testcoll_error1 (provider = icu, locale = '@colNumeric=lower'); + +-- test that attributes not handled by icu_set_collation_attributes() +-- (handled by ucol_open() directly) also work +CREATE COLLATION testcoll_de_phonebook (provider = icu, locale = 'de@collation=phonebook'); +SELECT 'Goldmann' < 'Götz' COLLATE "de-x-icu", 'Goldmann' > 'Götz' COLLATE testcoll_de_phonebook; + + +-- nondeterministic collations + +CREATE COLLATION ctest_det (provider = icu, locale = '', deterministic = true); +CREATE COLLATION ctest_nondet (provider = icu, locale = '', deterministic = false); + +CREATE TABLE test6 (a int, b text); +-- same string in different normal forms +INSERT INTO test6 VALUES (1, U&'\00E4bc'); +INSERT INTO test6 VALUES (2, U&'\0061\0308bc'); +SELECT * FROM test6; +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_det; +SELECT * FROM test6 WHERE b = 'äbc' COLLATE ctest_nondet; + +CREATE COLLATION case_sensitive (provider = icu, locale = ''); +CREATE COLLATION case_insensitive (provider = icu, locale = '@colStrength=secondary', deterministic = false); + +SELECT 'abc' <= 'ABC' COLLATE case_sensitive, 'abc' >= 'ABC' COLLATE case_sensitive; +SELECT 'abc' <= 'ABC' COLLATE case_insensitive, 'abc' >= 'ABC' COLLATE case_insensitive; + +CREATE TABLE test1cs (x text COLLATE case_sensitive); +CREATE TABLE test2cs (x text COLLATE case_sensitive); +CREATE TABLE test3cs (x text COLLATE case_sensitive); +INSERT INTO test1cs VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2cs VALUES ('ABC'), ('ghi'); +INSERT INTO test3cs VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3cs WHERE x = 'abc'; +SELECT x FROM test3cs WHERE x <> 'abc'; +SELECT x FROM test3cs WHERE x LIKE 'a%'; +SELECT x FROM test3cs WHERE x ILIKE 'a%'; +SELECT x FROM test3cs WHERE x SIMILAR TO 'a%'; +SELECT x FROM test3cs WHERE x ~ 'a'; +SELECT x FROM test1cs UNION SELECT x FROM test2cs ORDER BY x; +SELECT x FROM test2cs UNION SELECT x FROM test1cs ORDER BY x; +SELECT x FROM test1cs INTERSECT SELECT x FROM test2cs; +SELECT x FROM test2cs INTERSECT SELECT x FROM test1cs; +SELECT x FROM test1cs EXCEPT SELECT x FROM test2cs; +SELECT x FROM test2cs EXCEPT SELECT x FROM test1cs; +SELECT DISTINCT x FROM test3cs ORDER BY x; +SELECT count(DISTINCT x) FROM test3cs; +SELECT x, count(*) FROM test3cs GROUP BY x ORDER BY x; +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3cs ORDER BY x; +CREATE UNIQUE INDEX ON test1cs (x); -- ok +INSERT INTO test1cs VALUES ('ABC'); -- ok +CREATE UNIQUE INDEX ON test3cs (x); -- ok +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_sensitive, ',', 'abc'); +SELECT string_to_array('ABCDEFGHI' COLLATE case_sensitive, NULL, 'b'); + +CREATE TABLE test1ci (x text COLLATE case_insensitive); +CREATE TABLE test2ci (x text COLLATE case_insensitive); +CREATE TABLE test3ci (x text COLLATE case_insensitive); +CREATE INDEX ON test3ci (x text_pattern_ops); -- error +INSERT INTO test1ci VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2ci VALUES ('ABC'), ('ghi'); +INSERT INTO test3ci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3ci WHERE x = 'abc'; +SELECT x FROM test3ci WHERE x <> 'abc'; +SELECT x FROM test3ci WHERE x LIKE 'a%'; +SELECT x FROM test3ci WHERE x ILIKE 'a%'; +SELECT x FROM test3ci WHERE x SIMILAR TO 'a%'; +SELECT x FROM test3ci WHERE x ~ 'a'; +SELECT x FROM test1ci UNION SELECT x FROM test2ci ORDER BY x; +SELECT x FROM test2ci UNION SELECT x FROM test1ci ORDER BY x; +SELECT x FROM test1ci INTERSECT SELECT x FROM test2ci ORDER BY x; +SELECT x FROM test2ci INTERSECT SELECT x FROM test1ci ORDER BY x; +SELECT x FROM test1ci EXCEPT SELECT x FROM test2ci; +SELECT x FROM test2ci EXCEPT SELECT x FROM test1ci; +SELECT DISTINCT x FROM test3ci ORDER BY x; +SELECT count(DISTINCT x) FROM test3ci; +SELECT x, count(*) FROM test3ci GROUP BY x ORDER BY x; +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3ci ORDER BY x; +CREATE UNIQUE INDEX ON test1ci (x); -- ok +INSERT INTO test1ci VALUES ('ABC'); -- error +CREATE UNIQUE INDEX ON test3ci (x); -- error +SELECT string_to_array('ABC,DEF,GHI' COLLATE case_insensitive, ',', 'abc'); +SELECT string_to_array('ABCDEFGHI' COLLATE case_insensitive, NULL, 'b'); + +-- bpchar +CREATE TABLE test1bpci (x char(3) COLLATE case_insensitive); +CREATE TABLE test2bpci (x char(3) COLLATE case_insensitive); +CREATE TABLE test3bpci (x char(3) COLLATE case_insensitive); +CREATE INDEX ON test3bpci (x bpchar_pattern_ops); -- error +INSERT INTO test1bpci VALUES ('abc'), ('def'), ('ghi'); +INSERT INTO test2bpci VALUES ('ABC'), ('ghi'); +INSERT INTO test3bpci VALUES ('abc'), ('ABC'), ('def'), ('ghi'); + +SELECT x FROM test3bpci WHERE x = 'abc'; +SELECT x FROM test3bpci WHERE x <> 'abc'; +SELECT x FROM test3bpci WHERE x LIKE 'a%'; +SELECT x FROM test3bpci WHERE x ILIKE 'a%'; +SELECT x FROM test3bpci WHERE x SIMILAR TO 'a%'; +SELECT x FROM test3bpci WHERE x ~ 'a'; +SELECT x FROM test1bpci UNION SELECT x FROM test2bpci ORDER BY x; +SELECT x FROM test2bpci UNION SELECT x FROM test1bpci ORDER BY x; +SELECT x FROM test1bpci INTERSECT SELECT x FROM test2bpci ORDER BY x; +SELECT x FROM test2bpci INTERSECT SELECT x FROM test1bpci ORDER BY x; +SELECT x FROM test1bpci EXCEPT SELECT x FROM test2bpci; +SELECT x FROM test2bpci EXCEPT SELECT x FROM test1bpci; +SELECT DISTINCT x FROM test3bpci ORDER BY x; +SELECT count(DISTINCT x) FROM test3bpci; +SELECT x, count(*) FROM test3bpci GROUP BY x ORDER BY x; +SELECT x, row_number() OVER (ORDER BY x), rank() OVER (ORDER BY x) FROM test3bpci ORDER BY x; +CREATE UNIQUE INDEX ON test1bpci (x); -- ok +INSERT INTO test1bpci VALUES ('ABC'); -- error +CREATE UNIQUE INDEX ON test3bpci (x); -- error +SELECT string_to_array('ABC,DEF,GHI'::char(11) COLLATE case_insensitive, ',', 'abc'); +SELECT string_to_array('ABCDEFGHI'::char(9) COLLATE case_insensitive, NULL, 'b'); + +-- This tests the issue described in match_pattern_prefix(). In the +-- absence of that check, the case_insensitive tests below would +-- return no rows where they should logically return one. +CREATE TABLE test4c (x text COLLATE "C"); +INSERT INTO test4c VALUES ('abc'); +CREATE INDEX ON test4c (x); +SET enable_seqscan = off; +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_sensitive; -- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_sensitive; -- ok, no rows +SELECT x FROM test4c WHERE x LIKE 'ABC' COLLATE case_insensitive; -- error +SELECT x FROM test4c WHERE x LIKE 'ABC%' COLLATE case_insensitive; -- error +RESET enable_seqscan; + +-- Unicode special case: different variants of Greek lower case sigma. +-- A naive implementation like citext that just does lower(x) = +-- lower(y) will do the wrong thing here, because lower('Σ') is 'σ' +-- but upper('Ï‚') is 'Σ'. +SELECT 'ὀδυσσεÏÏ‚' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_sensitive; +SELECT 'ὀδυσσεÏÏ‚' = 'ὈΔΥΣΣΕΎΣ' COLLATE case_insensitive; + +-- name vs. text comparison operators +SELECT relname FROM pg_class WHERE relname = 'PG_CLASS'::text COLLATE case_insensitive; +SELECT relname FROM pg_class WHERE 'PG_CLASS'::text = relname COLLATE case_insensitive; + +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND typname <> 'INT2'::text + COLLATE case_insensitive ORDER BY typname; +SELECT typname FROM pg_type WHERE typname LIKE 'int_' AND 'INT2'::text <> typname + COLLATE case_insensitive ORDER BY typname; + +-- test case adapted from subselect.sql +CREATE TEMP TABLE outer_text (f1 text COLLATE case_insensitive, f2 text); +INSERT INTO outer_text VALUES ('a', 'a'); +INSERT INTO outer_text VALUES ('b', 'a'); +INSERT INTO outer_text VALUES ('A', NULL); +INSERT INTO outer_text VALUES ('B', NULL); + +CREATE TEMP TABLE inner_text (c1 text COLLATE case_insensitive, c2 text); +INSERT INTO inner_text VALUES ('a', NULL); + +SELECT * FROM outer_text WHERE (f1, f2) NOT IN (SELECT * FROM inner_text); + +-- accents +CREATE COLLATION ignore_accents (provider = icu, locale = '@colStrength=primary;colCaseLevel=yes', deterministic = false); + +CREATE TABLE test4 (a int, b text); +INSERT INTO test4 VALUES (1, 'cote'), (2, 'côte'), (3, 'coté'), (4, 'côté'); +SELECT * FROM test4 WHERE b = 'cote'; +SELECT * FROM test4 WHERE b = 'cote' COLLATE ignore_accents; +SELECT * FROM test4 WHERE b = 'Cote' COLLATE ignore_accents; -- still case-sensitive +SELECT * FROM test4 WHERE b = 'Cote' COLLATE case_insensitive; + +-- foreign keys (should use collation of primary key) + +-- PK is case-sensitive, FK is case-insensitive +CREATE TABLE test10pk (x text COLLATE case_sensitive PRIMARY KEY); +INSERT INTO test10pk VALUES ('abc'), ('def'), ('ghi'); +CREATE TABLE test10fk (x text COLLATE case_insensitive REFERENCES test10pk (x) ON UPDATE CASCADE ON DELETE CASCADE); +INSERT INTO test10fk VALUES ('abc'); -- ok +INSERT INTO test10fk VALUES ('ABC'); -- error +INSERT INTO test10fk VALUES ('xyz'); -- error +SELECT * FROM test10pk; +SELECT * FROM test10fk; +-- restrict update even though the values are "equal" in the FK table +UPDATE test10fk SET x = 'ABC' WHERE x = 'abc'; -- error +SELECT * FROM test10fk; +DELETE FROM test10pk WHERE x = 'abc'; +SELECT * FROM test10pk; +SELECT * FROM test10fk; + +-- PK is case-insensitive, FK is case-sensitive +CREATE TABLE test11pk (x text COLLATE case_insensitive PRIMARY KEY); +INSERT INTO test11pk VALUES ('abc'), ('def'), ('ghi'); +CREATE TABLE test11fk (x text COLLATE case_sensitive REFERENCES test11pk (x) ON UPDATE CASCADE ON DELETE CASCADE); +INSERT INTO test11fk VALUES ('abc'); -- ok +INSERT INTO test11fk VALUES ('ABC'); -- ok +INSERT INTO test11fk VALUES ('xyz'); -- error +SELECT * FROM test11pk; +SELECT * FROM test11fk; +-- cascade update even though the values are "equal" in the PK table +UPDATE test11pk SET x = 'ABC' WHERE x = 'abc'; +SELECT * FROM test11fk; +DELETE FROM test11pk WHERE x = 'abc'; +SELECT * FROM test11pk; +SELECT * FROM test11fk; + +-- partitioning +CREATE TABLE test20 (a int, b text COLLATE case_insensitive) PARTITION BY LIST (b); +CREATE TABLE test20_1 PARTITION OF test20 FOR VALUES IN ('abc'); +INSERT INTO test20 VALUES (1, 'abc'); +INSERT INTO test20 VALUES (2, 'ABC'); +SELECT * FROM test20_1; + +CREATE TABLE test21 (a int, b text COLLATE case_insensitive) PARTITION BY RANGE (b); +CREATE TABLE test21_1 PARTITION OF test21 FOR VALUES FROM ('ABC') TO ('DEF'); +INSERT INTO test21 VALUES (1, 'abc'); +INSERT INTO test21 VALUES (2, 'ABC'); +SELECT * FROM test21_1; + +CREATE TABLE test22 (a int, b text COLLATE case_sensitive) PARTITION BY HASH (b); +CREATE TABLE test22_0 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test22_1 PARTITION OF test22 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test22 VALUES (1, 'def'); +INSERT INTO test22 VALUES (2, 'DEF'); +-- they end up in different partitions +SELECT (SELECT count(*) FROM test22_0) = (SELECT count(*) FROM test22_1); + +CREATE TABLE test23 (a int, b text COLLATE case_insensitive) PARTITION BY HASH (b); +CREATE TABLE test23_0 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test23_1 PARTITION OF test23 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test23 VALUES (1, 'def'); +INSERT INTO test23 VALUES (2, 'DEF'); +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test23_0) <> (SELECT count(*) FROM test23_1); + +CREATE TABLE test30 (a int, b char(3) COLLATE case_insensitive) PARTITION BY LIST (b); +CREATE TABLE test30_1 PARTITION OF test30 FOR VALUES IN ('abc'); +INSERT INTO test30 VALUES (1, 'abc'); +INSERT INTO test30 VALUES (2, 'ABC'); +SELECT * FROM test30_1; + +CREATE TABLE test31 (a int, b char(3) COLLATE case_insensitive) PARTITION BY RANGE (b); +CREATE TABLE test31_1 PARTITION OF test31 FOR VALUES FROM ('ABC') TO ('DEF'); +INSERT INTO test31 VALUES (1, 'abc'); +INSERT INTO test31 VALUES (2, 'ABC'); +SELECT * FROM test31_1; + +CREATE TABLE test32 (a int, b char(3) COLLATE case_sensitive) PARTITION BY HASH (b); +CREATE TABLE test32_0 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test32_1 PARTITION OF test32 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test32 VALUES (1, 'def'); +INSERT INTO test32 VALUES (2, 'DEF'); +-- they end up in different partitions +SELECT (SELECT count(*) FROM test32_0) = (SELECT count(*) FROM test32_1); + +CREATE TABLE test33 (a int, b char(3) COLLATE case_insensitive) PARTITION BY HASH (b); +CREATE TABLE test33_0 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE test33_1 PARTITION OF test33 FOR VALUES WITH (MODULUS 2, REMAINDER 1); +INSERT INTO test33 VALUES (1, 'def'); +INSERT INTO test33 VALUES (2, 'DEF'); +-- they end up in the same partition (but it's platform-dependent which one) +SELECT (SELECT count(*) FROM test33_0) <> (SELECT count(*) FROM test33_1); + + -- cleanup -DROP SCHEMA collate_tests CASCADE; RESET search_path; +SET client_min_messages TO warning; +DROP SCHEMA collate_tests CASCADE; +RESET client_min_messages; -- leave a collation for pg_upgrade test CREATE COLLATION coll_icu_upgrade FROM "und-x-icu"; diff --git a/src/test/regress/sql/collate.linux.utf8.sql b/src/test/regress/sql/collate.linux.utf8.sql index b51162e3a1f..eac2f900142 100644 --- a/src/test/regress/sql/collate.linux.utf8.sql +++ b/src/test/regress/sql/collate.linux.utf8.sql @@ -4,6 +4,14 @@ * because other encodings don't support all the characters used. */ +SELECT getdatabaseencoding() <> 'UTF8' OR + (SELECT count(*) FROM pg_collation WHERE collname IN ('de_DE', 'en_US', 'sv_SE', 'tr_TR') AND collencoding = pg_char_to_encoding('UTF8')) <> 4 OR + version() !~ 'linux-gnu' + AS skip_test \gset +\if :skip_test +\quit +\endif + SET client_encoding TO UTF8; CREATE SCHEMA collate_tests; @@ -169,6 +177,8 @@ SELECT relname FROM pg_class WHERE relname ~* '^abc'; -- to_char SET lc_time TO 'tr_TR'; +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY'); +SELECT to_char(date '2010-02-01', 'DD TMMON YYYY' COLLATE "tr_TR"); SELECT to_char(date '2010-04-01', 'DD TMMON YYYY'); SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr_TR"); @@ -428,5 +438,13 @@ drop type textrange_c; drop type textrange_en_us; +-- nondeterministic collations +-- (not supported with libc provider) + +CREATE COLLATION ctest_det (locale = 'en_US.utf8', deterministic = true); +CREATE COLLATION ctest_nondet (locale = 'en_US.utf8', deterministic = false); + + -- cleanup +SET client_min_messages TO warning; DROP SCHEMA collate_tests CASCADE; diff --git a/src/test/regress/sql/collate.sql b/src/test/regress/sql/collate.sql index 4ddde95a5e8..89de26a227e 100644 --- a/src/test/regress/sql/collate.sql +++ b/src/test/regress/sql/collate.sql @@ -163,6 +163,11 @@ SELECT * FROM foo; SELECT a, b, a < b as lt FROM (VALUES ('a', 'B'), ('A', 'b' COLLATE "C")) v(a,b); +-- collation mismatch in subselects +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y, x FROM collate_test10); +-- now it works with overrides +SELECT * FROM collate_test10 WHERE (x COLLATE "POSIX", y COLLATE "C") NOT IN (SELECT y, x FROM collate_test10); +SELECT * FROM collate_test10 WHERE (x, y) NOT IN (SELECT y COLLATE "C", x COLLATE "POSIX" FROM collate_test10); -- casting @@ -259,5 +264,4 @@ SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); -- trying to run any platform-specific collation tests later, so we -- must get rid of them. -- -\set VERBOSITY terse DROP SCHEMA collate_tests CASCADE; diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql index f3a6d228fae..902f4fac19a 100644 --- a/src/test/regress/sql/copy2.sql +++ b/src/test/regress/sql/copy2.sql @@ -4,7 +4,7 @@ CREATE TEMP TABLE x ( c text not null default 'stuff', d text, e text -) WITH OIDS; +) ; CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS ' BEGIN @@ -73,10 +73,10 @@ COPY x from stdin; \. -- various COPY options: delimiters, oids, NULL string, encoding -COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x'; -500000,x,45,80,90 -500001,x,\x,\\x,\\\x -500002,x,\,,\\\,,\\ +COPY x (b, c, d, e) from stdin delimiter ',' null 'x'; +x,45,80,90 +x,\x,\\x,\\\x +x,\,,\\\,,\\ \. COPY x from stdin WITH DELIMITER AS ';' NULL AS ''; @@ -95,21 +95,34 @@ COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii'; 4008:8:Delimiter:\::\: \. --- check results of copy in -SELECT * FROM x; +COPY x TO stdout WHERE a = 1; +COPY x from stdin WHERE a = 50004; +50003 24 34 44 54 +50004 25 35 45 55 +50005 26 36 46 56 +\. + +COPY x from stdin WHERE a > 60003; +60001 22 32 42 52 +60002 23 33 43 53 +60003 24 34 44 54 +60004 25 35 45 55 +60005 26 36 46 56 +\. --- COPY w/ oids on a table w/o oids should fail -CREATE TABLE no_oids ( - a int, - b int -) WITHOUT OIDS; +COPY x from stdin WHERE f > 60003; -INSERT INTO no_oids (a, b) VALUES (5, 10); -INSERT INTO no_oids (a, b) VALUES (20, 30); +COPY x from stdin WHERE a = max(x.b); --- should fail -COPY no_oids FROM stdin WITH OIDS; -COPY no_oids TO stdout WITH OIDS; +COPY x from stdin WHERE a IN (SELECT 1 FROM x); + +COPY x from stdin WHERE a IN (generate_series(1,5)); + +COPY x from stdin WHERE a = row_number() over(b); + + +-- check results of copy in +SELECT * FROM x; -- check copy out COPY x TO stdout; @@ -411,6 +424,21 @@ test1 SELECT * FROM instead_of_insert_tbl; +-- Test of COPY optimization with view using INSTEAD OF INSERT +-- trigger when relation is created in the same transaction as +-- when COPY is executed. +BEGIN; +CREATE VIEW instead_of_insert_tbl_view_2 as select ''::text as str; +CREATE TRIGGER trig_instead_of_insert_tbl_view_2 + INSTEAD OF INSERT ON instead_of_insert_tbl_view_2 + FOR EACH ROW EXECUTE PROCEDURE fun_instead_of_insert_tbl(); + +COPY instead_of_insert_tbl_view_2 FROM stdin; +test1 +\. + +SELECT * FROM instead_of_insert_tbl; +COMMIT; -- clean up DROP TABLE forcetest; @@ -424,4 +452,5 @@ DROP FUNCTION fn_x_before(); DROP FUNCTION fn_x_after(); DROP TABLE instead_of_insert_tbl; DROP VIEW instead_of_insert_tbl_view; +DROP VIEW instead_of_insert_tbl_view_2; DROP FUNCTION fun_instead_of_insert_tbl(); diff --git a/src/test/regress/sql/create_aggregate.sql b/src/test/regress/sql/create_aggregate.sql index 590ca9a6247..fd7cd400c19 100644 --- a/src/test/regress/sql/create_aggregate.sql +++ b/src/test/regress/sql/create_aggregate.sql @@ -163,7 +163,7 @@ CREATE AGGREGATE myavg (numeric) serialfunc = numeric_avg_serialize, deserialfunc = numeric_avg_deserialize, combinefunc = numeric_avg_combine, - finalfunc_modify = sharable -- just to test a non-default setting + finalfunc_modify = shareable -- just to test a non-default setting ); -- Ensure all these functions made it into the catalog @@ -174,6 +174,71 @@ WHERE aggfnoid = 'myavg'::REGPROC; DROP AGGREGATE myavg (numeric); +-- create or replace aggregate +CREATE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg +); + +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = internal, + sfunc = numeric_avg_accum, + finalfunc = numeric_avg, + serialfunc = numeric_avg_serialize, + deserialfunc = numeric_avg_deserialize, + combinefunc = numeric_avg_combine, + finalfunc_modify = shareable -- just to test a non-default setting +); + +-- Ensure all these functions made it into the catalog again +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + +-- can change stype: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add +); +SELECT aggfnoid, aggtransfn, aggcombinefn, aggtranstype::regtype, + aggserialfn, aggdeserialfn, aggfinalmodify +FROM pg_aggregate +WHERE aggfnoid = 'myavg'::REGPROC; + +-- can't change return type: +CREATE OR REPLACE AGGREGATE myavg (numeric) +( + stype = numeric, + sfunc = numeric_add, + finalfunc = numeric_out +); + +-- can't change to a different kind: +CREATE OR REPLACE AGGREGATE myavg (order by numeric) +( + stype = numeric, + sfunc = numeric_add +); + +-- can't change plain function to aggregate: +create function sum4(int8,int8,int8,int8) returns int8 as +'select $1 + $2 + $3 + $4' language sql strict immutable; + +CREATE OR REPLACE AGGREGATE sum3 (int8,int8,int8) +( + stype = int8, + sfunc = sum4 +); + +drop function sum4(int8,int8,int8,int8); + +DROP AGGREGATE myavg (numeric); + -- invalid: bad parallel-safety marking CREATE AGGREGATE mysum (int) ( diff --git a/src/test/regress/sql/create_am.sql b/src/test/regress/sql/create_am.sql index 3e0ac104f3c..a7f6de7e9be 100644 --- a/src/test/regress/sql/create_am.sql +++ b/src/test/regress/sql/create_am.sql @@ -5,6 +5,11 @@ -- Make gist2 over gisthandler. In fact, it would be a synonym to gist. CREATE ACCESS METHOD gist2 TYPE INDEX HANDLER gisthandler; +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER int4in; +CREATE ACCESS METHOD bogus TYPE INDEX HANDLER heap_tableam_handler; + + -- Try to create gist2 index on fast_emp4000: fail because opclass doesn't exist CREATE INDEX grect2ind2 ON fast_emp4000 USING gist2 (home_base); @@ -66,3 +71,141 @@ DROP ACCESS METHOD gist2; -- Drop access method cascade DROP ACCESS METHOD gist2 CASCADE; + + +-- +-- Test table access methods +-- + +-- prevent empty values +SET default_table_access_method = ''; + +-- prevent nonexistent values +SET default_table_access_method = 'I do not exist AM'; + +-- prevent setting it to an index AM +SET default_table_access_method = 'btree'; + + +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap2 TYPE TABLE HANDLER heap_tableam_handler; + +-- Verify return type checks for handlers +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER int4in; +CREATE ACCESS METHOD bogus TYPE TABLE HANDLER bthandler; + +SELECT amname, amhandler, amtype FROM pg_am where amtype = 't' ORDER BY 1, 2; + + +-- First create tables employing the new AM using USING + +-- plain CREATE TABLE +CREATE TABLE tableam_tbl_heap2(f1 int) USING heap2; +INSERT INTO tableam_tbl_heap2 VALUES(1); +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + +-- CREATE TABLE AS +CREATE TABLE tableam_tblas_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; +SELECT f1 FROM tableam_tbl_heap2 ORDER BY f1; + +-- SELECT INTO doesn't support USING +SELECT INTO tableam_tblselectinto_heap2 USING heap2 FROM tableam_tbl_heap2; + +-- CREATE VIEW doesn't support USING +CREATE VIEW tableam_view_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; + +-- CREATE SEQUENCE doesn't support USING +CREATE SEQUENCE tableam_seq_heap2 USING heap2; + +-- CREATE MATERIALIZED VIEW does support USING +CREATE MATERIALIZED VIEW tableam_tblmv_heap2 USING heap2 AS SELECT * FROM tableam_tbl_heap2; +SELECT f1 FROM tableam_tblmv_heap2 ORDER BY f1; + +-- CREATE TABLE .. PARTITION BY doesn't not support USING +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a) USING heap2; + +CREATE TABLE tableam_parted_heap2 (a text, b int) PARTITION BY list (a); +-- new partitions will inherit from the current default, rather the partition root +SET default_table_access_method = 'heap'; +CREATE TABLE tableam_parted_a_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('a'); +SET default_table_access_method = 'heap2'; +CREATE TABLE tableam_parted_b_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('b'); +RESET default_table_access_method; +-- but the method can be explicitly specified +CREATE TABLE tableam_parted_c_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('c') USING heap; +CREATE TABLE tableam_parted_d_heap2 PARTITION OF tableam_parted_heap2 FOR VALUES IN ('d') USING heap2; + +-- List all objects in AM +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc, + pg_am AS pa +WHERE pa.oid = pc.relam + AND pa.amname = 'heap2' +ORDER BY 3, 1, 2; + +-- Show dependencies onto AM - there shouldn't be any for toast +SELECT pg_describe_object(classid,objid,objsubid) AS obj +FROM pg_depend, pg_am +WHERE pg_depend.refclassid = 'pg_am'::regclass + AND pg_am.oid = pg_depend.refobjid + AND pg_am.amname = 'heap2' +ORDER BY classid, objid, objsubid; + + +-- Second, create objects in the new AM by changing the default AM +BEGIN; +SET LOCAL default_table_access_method = 'heap2'; + +-- following tests should all respect the default AM +CREATE TABLE tableam_tbl_heapx(f1 int); +CREATE TABLE tableam_tblas_heapx AS SELECT * FROM tableam_tbl_heapx; +SELECT INTO tableam_tblselectinto_heapx FROM tableam_tbl_heapx; +CREATE MATERIALIZED VIEW tableam_tblmv_heapx USING heap2 AS SELECT * FROM tableam_tbl_heapx; +CREATE TABLE tableam_parted_heapx (a text, b int) PARTITION BY list (a); +CREATE TABLE tableam_parted_1_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('a', 'b'); + +-- but an explicitly set AM overrides it +CREATE TABLE tableam_parted_2_heapx PARTITION OF tableam_parted_heapx FOR VALUES IN ('c', 'd') USING heap; + +-- sequences, views and foreign servers shouldn't have an AM +CREATE VIEW tableam_view_heapx AS SELECT * FROM tableam_tbl_heapx; +CREATE SEQUENCE tableam_seq_heapx; +CREATE FOREIGN DATA WRAPPER fdw_heap2 VALIDATOR postgresql_fdw_validator; +CREATE SERVER fs_heap2 FOREIGN DATA WRAPPER fdw_heap2 ; +CREATE FOREIGN table tableam_fdw_heapx () SERVER fs_heap2; + +-- Verify that new AM was used for tables, matviews, but not for sequences, views and fdws +SELECT + pc.relkind, + pa.amname, + CASE WHEN relkind = 't' THEN + (SELECT 'toast for ' || relname::regclass FROM pg_class pcm WHERE pcm.reltoastrelid = pc.oid) + ELSE + relname::regclass::text + END COLLATE "C" AS relname +FROM pg_class AS pc + LEFT JOIN pg_am AS pa ON (pa.oid = pc.relam) +WHERE pc.relname LIKE 'tableam_%_heapx' +ORDER BY 3, 1, 2; + +-- don't want to keep those tables, nor the default +ROLLBACK; + +-- Third, check that we can neither create a table using a nonexistent +-- AM, nor using an index AM +CREATE TABLE i_am_a_failure() USING ""; +CREATE TABLE i_am_a_failure() USING i_do_not_exist_am; +CREATE TABLE i_am_a_failure() USING "I do not exist AM"; +CREATE TABLE i_am_a_failure() USING "btree"; + +-- Drop table access method, which fails as objects depends on it +DROP ACCESS METHOD heap2; + +-- we intentionally leave the objects created above alive, to verify pg_dump support diff --git a/src/test/regress/sql/create_function_3.sql b/src/test/regress/sql/create_function_3.sql index 24bb900990a..7a2df0ea8a1 100644 --- a/src/test/regress/sql/create_function_3.sql +++ b/src/test/regress/sql/create_function_3.sql @@ -220,8 +220,6 @@ $$ SELECT generate_series(1, a) $$ STABLE; SELECT * FROM voidtest5(3); -- Cleanup -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA temp_func_test CASCADE; -\set VERBOSITY default DROP USER regress_unpriv_user; RESET search_path; diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index f7731265a08..f96bebf410d 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -97,35 +97,7 @@ CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1); CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1); -- --- SP-GiST --- - -CREATE TABLE quad_point_tbl AS - SELECT point(unique1,unique2) AS p FROM tenk1; - -INSERT INTO quad_point_tbl - SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); - -INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); - -CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); - -CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; - -CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); - -CREATE TABLE radix_text_tbl AS - SELECT name AS t FROM road WHERE name !~ '^[0-9]'; - -INSERT INTO radix_text_tbl - SELECT 'P0123456789abcdef' FROM generate_series(1,1000); -INSERT INTO radix_text_tbl VALUES ('P0123456789abcde'); -INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF'); - -CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t); - --- --- Test GiST and SP-GiST indexes +-- Test GiST indexes -- -- get non-indexed results for comparison purposes @@ -178,54 +150,6 @@ SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - -SELECT count(*) FROM quad_point_tbl; - -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; SELECT circle_center(f1), round(radius(f1)) as radius FROM gcircle_tbl ORDER BY f1 <-> '(200,300)'::point LIMIT 10; @@ -323,130 +247,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl; -SELECT count(*) FROM quad_point_tbl; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - EXPLAIN (COSTS OFF) SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; SELECT * FROM gpolygon_tbl ORDER BY f1 <-> '(0,0)'::point LIMIT 10; @@ -464,130 +264,6 @@ EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl; -SELECT count(*) FROM quad_point_tbl; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; @@ -873,21 +549,18 @@ DROP TABLE cwi_test; -- -- Check handling of indexes on system columns -- -CREATE TABLE oid_table (a INT) WITH OIDS; - --- An index on the OID column should be allowed -CREATE INDEX ON oid_table (oid); +CREATE TABLE syscol_table (a INT); --- Other system columns cannot be indexed -CREATE INDEX ON oid_table (ctid); +-- System columns cannot be indexed +CREATE INDEX ON syscolcol_table (ctid); -- nor used in expressions -CREATE INDEX ON oid_table ((ctid >= '(1000,0)')); +CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')); -- nor used in predicates -CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)'; +CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)'; -DROP TABLE oid_table; +DROP TABLE syscol_table; -- -- Tests for IS NULL/IS NOT NULL with b-tree indexes @@ -1060,15 +733,173 @@ explain (costs off) select * from boolindex where b = true order by i desc limit 10; explain (costs off) select * from boolindex where not b order by i limit 10; +explain (costs off) + select * from boolindex where b is true order by i desc limit 10; +explain (costs off) + select * from boolindex where b is false order by i desc limit 10; -- -- REINDEX (VERBOSE) -- CREATE TABLE reindex_verbose(id integer primary key); -\set VERBOSITY terse +\set VERBOSITY terse \\ -- suppress machine-dependent details REINDEX (VERBOSE) TABLE reindex_verbose; +\set VERBOSITY default DROP TABLE reindex_verbose; +-- +-- REINDEX CONCURRENTLY +-- +CREATE TABLE concur_reindex_tab (c1 int); +-- REINDEX +REINDEX TABLE concur_reindex_tab; -- notice +REINDEX TABLE CONCURRENTLY concur_reindex_tab; -- notice +ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index +-- Normal index with integer column +CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1); +-- Normal index with text column +CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2); +-- UNIQUE index with expression +CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)); +-- Duplicate column names +CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2); +-- Create table for check on foreign key dependence switch with indexes swapped +ALTER TABLE concur_reindex_tab ADD PRIMARY KEY USING INDEX concur_reindex_ind1; +CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab); +INSERT INTO concur_reindex_tab VALUES (1, 'a'); +INSERT INTO concur_reindex_tab VALUES (2, 'a'); +-- Reindex concurrently of exclusion constraint currently not supported +CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)); +INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]'); +REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl; -- error +REINDEX TABLE CONCURRENTLY concur_reindex_tab3; -- succeeds with warning +INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]'); +-- Check materialized views +CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab; +REINDEX INDEX CONCURRENTLY concur_reindex_ind1; +REINDEX TABLE CONCURRENTLY concur_reindex_tab; +REINDEX TABLE CONCURRENTLY concur_reindex_matview; +-- Check that comments are preserved +CREATE TABLE testcomment (i int); +CREATE INDEX testcomment_idx1 ON testcomment (i); +COMMENT ON INDEX testcomment_idx1 IS 'test comment'; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); +REINDEX TABLE testcomment; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); +REINDEX TABLE CONCURRENTLY testcomment ; +SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); +DROP TABLE testcomment; +-- Partitions +-- Create some partitioned tables +CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1); +CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part + FOR VALUES FROM (0) TO (10) PARTITION BY list (c2); +CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (1); +CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 + FOR VALUES IN (2); +-- This partitioned table will have no partitions. +CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part + FOR VALUES FROM (10) TO (20) PARTITION BY list (c2); +-- Create some partitioned indexes +CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1); +CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1); +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0; +-- This partitioned index will have no partitions. +CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1); +ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10; +CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1); +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1; +CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1); +ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; +-- REINDEX fails for partitioned indexes +REINDEX INDEX concur_reindex_part_index_10; +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_10; +-- REINDEX is a no-op for partitioned tables +REINDEX TABLE concur_reindex_part_10; +REINDEX TABLE CONCURRENTLY concur_reindex_part_10; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; +-- REINDEX should preserve dependencies of partition tree. +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1; +REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1; +REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2; +SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') + ORDER BY relid, level; +DROP TABLE concur_reindex_part; + +-- Check errors +-- Cannot run inside a transaction block +BEGIN; +REINDEX TABLE CONCURRENTLY concur_reindex_tab; +COMMIT; +REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation +REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index +-- These are the toast table and index of pg_authid. +REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table +REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index +REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM +-- Warns about catalog relations +REINDEX SCHEMA CONCURRENTLY pg_catalog; + +-- Check the relation status, there should not be invalid indexes +\d concur_reindex_tab +DROP MATERIALIZED VIEW concur_reindex_matview; +DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3; + +-- Check handling of invalid indexes +CREATE TABLE concur_reindex_tab4 (c1 int); +INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); +-- This trick creates an invalid index. +CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); +-- Reindexing concurrently this index fails with the same failure. +-- The extra index created is itself invalid, and can be dropped. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; +\d concur_reindex_tab4 +DROP INDEX concur_reindex_ind5_ccnew; +-- This makes the previous failure go away, so the index can become valid. +DELETE FROM concur_reindex_tab4 WHERE c1 = 1; +-- The invalid index is not processed when running REINDEX TABLE. +REINDEX TABLE CONCURRENTLY concur_reindex_tab4; +\d concur_reindex_tab4 +-- But it is fixed with REINDEX INDEX. +REINDEX INDEX CONCURRENTLY concur_reindex_ind5; +\d concur_reindex_tab4 +DROP TABLE concur_reindex_tab4; + +-- Check handling of indexes with expressions and predicates. The +-- definitions of the rebuilt indexes should match the original +-- definitions. +CREATE TABLE concur_exprs_tab (c1 int , c2 boolean); +INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), + (414515746, TRUE), + (897778963, FALSE); +CREATE UNIQUE INDEX concur_exprs_index_expr + ON concur_exprs_tab ((c1::text COLLATE "C")); +CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) + WHERE (c1::text > 500000000::text COLLATE "C"); +CREATE UNIQUE INDEX concur_exprs_index_pred_2 + ON concur_exprs_tab ((1 / c1)) + WHERE ('-H') >= (c2::TEXT) COLLATE "C"; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); +REINDEX TABLE CONCURRENTLY concur_exprs_tab; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); +-- ALTER TABLE recreates the indexes, which should keep their collations. +ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT; +SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); +SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); +DROP TABLE concur_exprs_tab; + -- -- REINDEX SCHEMA -- @@ -1111,6 +942,9 @@ BEGIN; REINDEX SCHEMA schema_to_reindex; -- failure, cannot run in a transaction END; +-- concurrently +REINDEX SCHEMA CONCURRENTLY schema_to_reindex; + -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser; @@ -1119,5 +953,4 @@ REINDEX SCHEMA schema_to_reindex; -- Clean up RESET ROLE; DROP ROLE regress_reindexuser; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA schema_to_reindex CASCADE; diff --git a/src/test/regress/sql/create_index_spgist.sql b/src/test/regress/sql/create_index_spgist.sql new file mode 100644 index 00000000000..68632e3732e --- /dev/null +++ b/src/test/regress/sql/create_index_spgist.sql @@ -0,0 +1,420 @@ +-- +-- SP-GiST index tests +-- + +CREATE TABLE quad_point_tbl AS + SELECT point(unique1,unique2) AS p FROM tenk1; + +INSERT INTO quad_point_tbl + SELECT '(333.0,400.0)'::point FROM generate_series(1,1000); + +INSERT INTO quad_point_tbl VALUES (NULL), (NULL), (NULL); + +CREATE INDEX sp_quad_ind ON quad_point_tbl USING spgist (p); + +CREATE TABLE kd_point_tbl AS SELECT * FROM quad_point_tbl; + +CREATE INDEX sp_kd_ind ON kd_point_tbl USING spgist (p kd_point_ops); + +CREATE TABLE radix_text_tbl AS + SELECT name AS t FROM road WHERE name !~ '^[0-9]'; + +INSERT INTO radix_text_tbl + SELECT 'P0123456789abcdef' FROM generate_series(1,1000); +INSERT INTO radix_text_tbl VALUES ('P0123456789abcde'); +INSERT INTO radix_text_tbl VALUES ('P0123456789abcdefF'); + +CREATE INDEX sp_radix_ind ON radix_text_tbl USING spgist (t); + +-- get non-indexed results for comparison purposes + +SET enable_seqscan = ON; +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM quad_point_tbl; + +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +CREATE TEMP TABLE quad_point_tbl_ord_seq1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; + +CREATE TEMP TABLE quad_point_tbl_ord_seq2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +CREATE TEMP TABLE quad_point_tbl_ord_seq3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +-- Now check the results from plain indexscan +SET enable_seqscan = OFF; +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; +SELECT count(*) FROM quad_point_tbl; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; +CREATE TEMP TABLE quad_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl; +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN quad_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +CREATE TEMP TABLE quad_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN quad_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; +CREATE TEMP TABLE quad_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN quad_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; +CREATE TEMP TABLE kd_point_tbl_ord_idx1 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl; +SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN kd_point_tbl_ord_idx1 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +CREATE TEMP TABLE kd_point_tbl_ord_idx2 AS +SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p +FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN kd_point_tbl_ord_idx2 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +EXPLAIN (COSTS OFF) +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; +CREATE TEMP TABLE kd_point_tbl_ord_idx3 AS +SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p +FROM kd_point_tbl WHERE p IS NOT NULL; +SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN kd_point_tbl_ord_idx3 idx +ON seq.n = idx.n +WHERE seq.dist IS DISTINCT FROM idx.dist; + +-- check ORDER BY distance to NULL +SELECT (SELECT p FROM kd_point_tbl ORDER BY p <-> pt, p <-> '0,0' LIMIT 1) +FROM (VALUES (point '1,2'), (NULL), ('1234,5678')) pts(pt); + + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +-- Now check the results from bitmap indexscan +SET enable_seqscan = OFF; +SET enable_indexscan = OFF; +SET enable_bitmapscan = ON; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; +SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl; +SELECT count(*) FROM quad_point_tbl; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; +SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; +SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; +SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; +SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; +SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; +SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; +SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; +SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; +SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; +SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; +SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; + +RESET enable_seqscan; +RESET enable_indexscan; +RESET enable_bitmapscan; diff --git a/src/test/regress/sql/create_misc.sql b/src/test/regress/sql/create_misc.sql index d4a63b7aed2..d0b04a821f8 100644 --- a/src/test/regress/sql/create_misc.sql +++ b/src/test/regress/sql/create_misc.sql @@ -192,6 +192,14 @@ INSERT INTO f_star (class, f) INSERT INTO f_star (class) VALUES ('f'); +-- Analyze the X_star tables for better plan stability in later tests +ANALYZE a_star; +ANALYZE b_star; +ANALYZE c_star; +ANALYZE d_star; +ANALYZE e_star; +ANALYZE f_star; + -- -- for internal portal (cursor) tests diff --git a/src/test/regress/sql/create_operator.sql b/src/test/regress/sql/create_operator.sql index c71765f9be5..8b6fd0bb43d 100644 --- a/src/test/regress/sql/create_operator.sql +++ b/src/test/regress/sql/create_operator.sql @@ -5,7 +5,7 @@ CREATE OPERATOR ## ( leftarg = path, rightarg = path, - procedure = path_inter, + function = path_inter, commutator = ## ); @@ -45,6 +45,37 @@ CREATE OPERATOR => ( procedure = numeric_fac ); +-- lexing of <=, >=, <>, != has a number of edge cases +-- (=> is tested elsewhere) + +-- this is legal because ! is not allowed in sql ops +CREATE OPERATOR !=- ( + leftarg = int8, -- right unary + procedure = numeric_fac +); +SELECT 2 !=-; +-- make sure lexer returns != as <> even in edge cases +SELECT 2 !=/**/ 1, 2 !=/**/ 2; +SELECT 2 !=-- comment to be removed by psql + 1; +DO $$ -- use DO to protect -- from psql + declare r boolean; + begin + execute $e$ select 2 !=-- comment + 1 $e$ into r; + raise info 'r = %', r; + end; +$$; + +-- check that <= etc. followed by more operator characters are returned +-- as the correct token with correct precedence +SELECT true<>-1 BETWEEN 1 AND 1; -- BETWEEN has prec. above <> but below Op +SELECT false<>/**/1 BETWEEN 1 AND 1; +SELECT false<=-1 BETWEEN 1 AND 1; +SELECT false>=-1 BETWEEN 1 AND 1; +SELECT 2<=/**/3, 3>=/**/2, 2<>/**/3; +SELECT 3<=/**/2, 2>=/**/3, 2<>/**/2; + -- Should fail. CREATE OPERATOR requires USAGE on SCHEMA BEGIN TRANSACTION; CREATE ROLE regress_rol_op1; @@ -189,11 +220,11 @@ CREATE OPERATOR === ( "Leftarg" = box, "Rightarg" = box, - "Procedure" = area_equal_procedure, + "Procedure" = area_equal_function, "Commutator" = ===, "Negator" = !==, - "Restrict" = area_restriction_procedure, - "Join" = area_join_procedure, + "Restrict" = area_restriction_function, + "Join" = area_join_function, "Hashes", "Merges" ); diff --git a/src/test/regress/sql/create_procedure.sql b/src/test/regress/sql/create_procedure.sql index 1be9c6fd78f..89b96d580ff 100644 --- a/src/test/regress/sql/create_procedure.sql +++ b/src/test/regress/sql/create_procedure.sql @@ -11,14 +11,20 @@ AS $$ INSERT INTO cp_test VALUES (1, x); $$; +\df ptest1 +SELECT pg_get_functiondef('ptest1'::regproc); + +-- show only normal functions +\dfn public.*test*1 + +-- show only procedures +\dfp public.*test*1 + SELECT ptest1('x'); -- error CALL ptest1('a'); -- ok CALL ptest1('xy' || 'zzy'); -- ok, constant-folded arg CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1)); -- ok, volatile arg -\df ptest1 -SELECT pg_get_functiondef('ptest1'::regproc); - SELECT * FROM cp_test ORDER BY b COLLATE "C"; @@ -65,6 +71,47 @@ $$; DROP PROCEDURE ptest4a; +-- named and default parameters + +CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100) +LANGUAGE SQL +AS $$ +INSERT INTO cp_test VALUES(a, b); +INSERT INTO cp_test VALUES(c, b); +$$; + +TRUNCATE cp_test; + +CALL ptest5(10, 'Hello', 20); +CALL ptest5(10, 'Hello'); +CALL ptest5(10, b => 'Hello'); +CALL ptest5(b => 'Hello', a => 10); + +SELECT * FROM cp_test; + + +-- polymorphic types + +CREATE PROCEDURE ptest6(a int, b anyelement) +LANGUAGE SQL +AS $$ +SELECT NULL::int; +$$; + +CALL ptest6(1, 2); + + +-- collation assignment + +CREATE PROCEDURE ptest7(a text, b text) +LANGUAGE SQL +AS $$ +SELECT a = b; +$$; + +CALL ptest7(least('a', 'b'), 'a'); + + -- various error cases CALL version(); -- error: not a procedure diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 235bef13dc0..144eeb480dd 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -51,7 +51,7 @@ CREATE TABLE tenk1 ( stringu1 name, stringu2 name, string4 name -) WITH OIDS; +); CREATE TABLE tenk2 ( unique1 int4, @@ -83,7 +83,7 @@ CREATE TABLE person ( CREATE TABLE emp ( salary int4, manager name -) INHERITS (person) WITH OIDS; +) INHERITS (person); CREATE TABLE student ( @@ -255,7 +255,6 @@ CREATE TABLE IF NOT EXISTS test_tsvector( -- invalid: non-lowercase quoted reloptions identifiers CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a; -CREATE TABLE tas_case (a text) WITH ("Oids" = true); CREATE UNLOGGED TABLE unlogged1 (a int primary key); -- OK CREATE TEMPORARY TABLE unlogged2 (a int primary key); -- OK @@ -278,9 +277,46 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r'; DROP TABLE as_select1; --- check that the oid column is added before the primary key is checked -CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS; -DROP TABLE oid_pk; +PREPARE select1 AS SELECT 1 as a; +CREATE TABLE as_select1 AS EXECUTE select1; +CREATE TABLE as_select1 AS EXECUTE select1; +SELECT * FROM as_select1; +CREATE TABLE IF NOT EXISTS as_select1 AS EXECUTE select1; +DROP TABLE as_select1; +DEALLOCATE select1; + +-- create an extra wide table to test for issues related to that +-- (temporarily hide query, to avoid the long CREATE TABLE stmt) +\set ECHO none +SELECT 'CREATE TABLE extra_wide_table(firstc text, '|| array_to_string(array_agg('c'||i||' bool'),',')||', lastc text);' +FROM generate_series(1, 1100) g(i) +\gexec +\set ECHO all +INSERT INTO extra_wide_table(firstc, lastc) VALUES('first col', 'last col'); +SELECT firstc, lastc FROM extra_wide_table; + +-- check that tables with oids cannot be created anymore +CREATE TABLE withoid() WITH OIDS; +CREATE TABLE withoid() WITH (oids); +CREATE TABLE withoid() WITH (oids = true); + +-- but explicitly not adding oids is still supported +CREATE TEMP TABLE withoutoid() WITHOUT OIDS; DROP TABLE withoutoid; +CREATE TEMP TABLE withoutoid() WITH (oids = false); DROP TABLE withoutoid; + +-- check restriction with default expressions +-- invalid use of column reference in default expressions +CREATE TABLE default_expr_column (id int DEFAULT (id)); +CREATE TABLE default_expr_column (id int DEFAULT (bar.id)); +CREATE TABLE default_expr_agg_column (id int DEFAULT (avg(id))); +-- invalid column definition +CREATE TABLE default_expr_non_column (a int DEFAULT (avg(non_existent))); +-- invalid use of aggregate +CREATE TABLE default_expr_agg (a int DEFAULT (avg(1))); +-- invalid use of subquery +CREATE TABLE default_expr_agg (a int DEFAULT (select 1)); +-- invalid use of set-returning function +CREATE TABLE default_expr_agg (a int DEFAULT (generate_series(1,3))); -- -- Partitioned tables @@ -303,11 +339,6 @@ CREATE TABLE partitioned ( EXCLUDE USING gist (a WITH &&) ) PARTITION BY RANGE (a); --- prevent column from being used twice in the partition key -CREATE TABLE partitioned ( - a int -) PARTITION BY RANGE (a, a); - -- prevent using prohibited expressions in the key CREATE FUNCTION retset (a int) RETURNS SETOF int AS $$ SELECT 1; $$ LANGUAGE SQL IMMUTABLE; CREATE TABLE partitioned ( @@ -418,6 +449,39 @@ CREATE TABLE part2_1 PARTITION OF partitioned2 FOR VALUES FROM (-1, 'aaaaa') TO DROP TABLE partitioned, partitioned2; +-- check that dependencies of partition columns are handled correctly +create domain intdom1 as int; + +create table partitioned ( + a intdom1, + b text +) partition by range (a); + +alter table partitioned drop column a; -- fail + +drop domain intdom1; -- fail, requires cascade + +drop domain intdom1 cascade; + +table partitioned; -- gone + +-- likewise for columns used in partition expressions +create domain intdom1 as int; + +create table partitioned ( + a intdom1, + b text +) partition by range (plusone(a)); + +alter table partitioned drop column a; -- fail + +drop domain intdom1; -- fail, requires cascade + +drop domain intdom1 cascade; + +table partitioned; -- gone + + -- -- Partitions -- @@ -427,13 +491,21 @@ DROP TABLE partitioned, partitioned2; CREATE TABLE list_parted ( a int ) PARTITION BY LIST (a); --- syntax allows only string literal, numeric literal and null to be --- specified for a partition bound value -CREATE TABLE part_1 PARTITION OF list_parted FOR VALUES IN ('1'); -CREATE TABLE part_2 PARTITION OF list_parted FOR VALUES IN (2); +CREATE TABLE part_p1 PARTITION OF list_parted FOR VALUES IN ('1'); +CREATE TABLE part_p2 PARTITION OF list_parted FOR VALUES IN (2); +CREATE TABLE part_p3 PARTITION OF list_parted FOR VALUES IN ((2+1)); CREATE TABLE part_null PARTITION OF list_parted FOR VALUES IN (null); -CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN (int '1'); -CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN ('1'::int); +\d+ list_parted + +-- forbidden expressions for partition bound with list partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (somename.somename); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (a); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(a)); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(somename)); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (sum(1)); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN ((select 1)); +CREATE TABLE part_bogus_expr_fail PARTITION OF list_parted FOR VALUES IN (generate_series(4, 6)); -- syntax does not allow empty list of values for list partitions CREATE TABLE fail_part PARTITION OF list_parted FOR VALUES IN (); @@ -453,15 +525,16 @@ CREATE TABLE bools ( CREATE TABLE bools_true PARTITION OF bools FOR VALUES IN (1); DROP TABLE bools; --- specified literal can be cast, but cast isn't immutable +-- specified literal can be cast, and the cast might not be immutable CREATE TABLE moneyp ( a money ) PARTITION BY LIST (a); CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN (10); -CREATE TABLE moneyp_10 PARTITION OF moneyp FOR VALUES IN ('10'); +CREATE TABLE moneyp_11 PARTITION OF moneyp FOR VALUES IN ('11'); +CREATE TABLE moneyp_12 PARTITION OF moneyp FOR VALUES IN (to_char(12, '99')::int); DROP TABLE moneyp; --- immutable cast should work, though +-- cast is immutable CREATE TABLE bigintp ( a bigint ) PARTITION BY LIST (a); @@ -474,6 +547,24 @@ CREATE TABLE range_parted ( a date ) PARTITION BY RANGE (a); +-- forbidden expressions for partition bounds with range partitioned table +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (somename.somename) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (a) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(a)) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max(somename)) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (max('2019-02-01'::date)) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM ((select 1)) TO ('2019-01-01'); +CREATE TABLE part_bogus_expr_fail PARTITION OF range_parted + FOR VALUES FROM (generate_series(1, 3)) TO ('2019-01-01'); + -- trying to specify list for range partitioned table CREATE TABLE fail_part PARTITION OF range_parted FOR VALUES IN ('a'); -- trying to specify modulus and remainder for range partitioned table @@ -525,22 +616,6 @@ CREATE TEMP TABLE temp_parted ( CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a'); DROP TABLE temp_parted; --- cannot create a table with oids as partition of table without oids -CREATE TABLE no_oids_parted ( - a int -) PARTITION BY RANGE (a) WITHOUT OIDS; -CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS; -DROP TABLE no_oids_parted; - --- If the partitioned table has oids, then the partition must have them. --- If the WITHOUT OIDS option is specified for partition, it is overridden. -CREATE TABLE oids_parted ( - a int -) PARTITION BY RANGE (a) WITH OIDS; -CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS; -\d+ part_forced_oids -DROP TABLE oids_parted, part_forced_oids; - -- check for partition bound overlap and other invalid specifications CREATE TABLE list_parted2 ( @@ -646,11 +721,26 @@ CREATE TABLE part_b PARTITION OF parted ( ) FOR VALUES IN ('b'); CREATE TABLE part_b PARTITION OF parted ( - b NOT NULL DEFAULT 1 CHECK (b >= 0), - CONSTRAINT check_a CHECK (length(a) > 0) + b NOT NULL DEFAULT 1, + CONSTRAINT check_a CHECK (length(a) > 0), + CONSTRAINT check_b CHECK (b >= 0) ) FOR VALUES IN ('b'); --- conislocal should be false for any merged constraints -SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass AND conname = 'check_a'; +-- conislocal should be false for any merged constraints, true otherwise +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass ORDER BY conislocal, coninhcount; + +-- Once check_b is added to the parent, it should be made non-local for part_b +ALTER TABLE parted ADD CONSTRAINT check_b CHECK (b >= 0); +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass; + +-- Neither check_a nor check_b are droppable from part_b +ALTER TABLE part_b DROP CONSTRAINT check_a; +ALTER TABLE part_b DROP CONSTRAINT check_b; + +-- And dropping it from parted should leave no trace of them on part_b, unlike +-- traditional inheritance where they will be left behind, because they would +-- be local constraints. +ALTER TABLE parted DROP CONSTRAINT check_a, DROP CONSTRAINT check_b; +SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::regclass; -- specify PARTITION BY for a partition CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c); @@ -659,6 +749,47 @@ CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR -- create a level-2 partition CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10); +-- check that NOT NULL and default value are inherited correctly +create table parted_notnull_inh_test (a int default 1, b int not null default 0) partition by list (a); +create table parted_notnull_inh_test1 partition of parted_notnull_inh_test (a not null, b default 1) for values in (1); +insert into parted_notnull_inh_test (b) values (null); +-- note that while b's default is overriden, a's default is preserved +\d parted_notnull_inh_test1 +drop table parted_notnull_inh_test; + +-- check for a conflicting COLLATE clause +create table parted_collate_must_match (a text collate "C", b text collate "C") + partition by range (a); +-- on the partition key +create table parted_collate_must_match1 partition of parted_collate_must_match + (a collate "POSIX") for values from ('a') to ('m'); +-- on another column +create table parted_collate_must_match2 partition of parted_collate_must_match + (b collate "POSIX") for values from ('m') to ('z'); +drop table parted_collate_must_match; + +-- check that specifying incompatible collations for partition bound +-- expressions fails promptly + +create table test_part_coll_posix (a text) partition by range (a collate "POSIX"); +-- fail +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "C") to ('g'); +-- ok +create table test_part_coll partition of test_part_coll_posix for values from ('a' collate "POSIX") to ('g'); +-- ok +create table test_part_coll2 partition of test_part_coll_posix for values from ('g') to ('m'); + +-- using a cast expression uses the target type's default collation + +-- fail +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "C") to ('s'); +-- ok +create table test_part_coll_cast partition of test_part_coll_posix for values from (name 'm' collate "POSIX") to ('s'); +-- ok; partition collation silently overrides the default collation of type 'name' +create table test_part_coll_cast2 partition of test_part_coll_posix for values from (name 's') to ('z'); + +drop table test_part_coll_posix; + -- Partition bound in describe output \d+ part_b @@ -688,10 +819,23 @@ CREATE TABLE range_parted4_3 PARTITION OF range_parted4 FOR VALUES FROM (6, 8, M \d+ range_parted4_3 DROP TABLE range_parted4; +-- user-defined operator class in partition key +CREATE FUNCTION my_int4_sort(int4,int4) RETURNS int LANGUAGE sql + AS $$ SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$; +CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING btree AS + OPERATOR 1 < (int4,int4), OPERATOR 2 <= (int4,int4), + OPERATOR 3 = (int4,int4), OPERATOR 4 >= (int4,int4), + OPERATOR 5 > (int4,int4), FUNCTION 1 my_int4_sort(int4,int4); +CREATE TABLE partkey_t (a int4) PARTITION BY RANGE (a test_int4_ops); +CREATE TABLE partkey_t_1 PARTITION OF partkey_t FOR VALUES FROM (0) TO (1000); +INSERT INTO partkey_t VALUES (100); +INSERT INTO partkey_t VALUES (200); + -- cleanup DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3; -DROP TABLE hash_parted; -DROP TABLE hash_parted2; +DROP TABLE partkey_t, hash_parted, hash_parted2; +DROP OPERATOR CLASS test_int4_ops USING btree; +DROP FUNCTION my_int4_sort(int4,int4); -- comments on partitioned tables columns CREATE TABLE parted_col_comment (a int, b text) PARTITION BY LIST (a); @@ -706,3 +850,56 @@ CREATE TABLE arrlp (a int[]) PARTITION BY LIST (a); CREATE TABLE arrlp12 PARTITION OF arrlp FOR VALUES IN ('{1}', '{2}'); \d+ arrlp12 DROP TABLE arrlp; + +-- partition on boolean column +create table boolspart (a bool) partition by list (a); +create table boolspart_t partition of boolspart for values in (true); +create table boolspart_f partition of boolspart for values in (false); +\d+ boolspart +drop table boolspart; + +-- partitions mixing temporary and permanent relations +create table perm_parted (a int) partition by list (a); +create temporary table temp_parted (a int) partition by list (a); +create table perm_part partition of temp_parted default; -- error +create temp table temp_part partition of perm_parted default; -- error +create temp table temp_part partition of temp_parted default; -- ok +drop table perm_parted cascade; +drop table temp_parted cascade; + +-- check that adding partitions to a table while it is being used is prevented +create table tab_part_create (a int) partition by list (a); +create or replace function func_part_create() returns trigger + language plpgsql as $$ + begin + execute 'create table tab_part_create_1 partition of tab_part_create for values in (1)'; + return null; + end $$; +create trigger trig_part_create before insert on tab_part_create + for each statement execute procedure func_part_create(); +insert into tab_part_create values (1); +drop table tab_part_create; +drop function func_part_create(); + +-- test using a volatile expression as partition bound +create table volatile_partbound_test (partkey timestamp) partition by range (partkey); +create table volatile_partbound_test1 partition of volatile_partbound_test for values from (minvalue) to (current_timestamp); +create table volatile_partbound_test2 partition of volatile_partbound_test for values from (current_timestamp) to (maxvalue); +-- this should go into the partition volatile_partbound_test2 +insert into volatile_partbound_test values (current_timestamp); +select tableoid::regclass from volatile_partbound_test; +drop table volatile_partbound_test; + +-- test the case where a check constraint on default partition allows +-- to avoid scanning it when adding a new partition +create table defcheck (a int, b int) partition by list (b); +create table defcheck_def (a int, c int, b int); +alter table defcheck_def drop c; +alter table defcheck attach partition defcheck_def default; +alter table defcheck_def add check (b <= 0 and b is not null); +create table defcheck_1 partition of defcheck for values in (1, null); + +-- test that complex default partition constraints are enforced correctly +insert into defcheck_def values (0, 0); +create table defcheck_0 partition of defcheck for values in (0); +drop table defcheck; diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql index 42cad6826b0..589ee12ebcf 100644 --- a/src/test/regress/sql/create_table_like.sql +++ b/src/test/regress/sql/create_table_like.sql @@ -51,6 +51,40 @@ INSERT INTO test_like_id_3 (b) VALUES ('b3'); SELECT * FROM test_like_id_3; -- identity was copied and applied DROP TABLE test_like_id_1, test_like_id_2, test_like_id_3; +CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +\d test_like_gen_1 +INSERT INTO test_like_gen_1 (a) VALUES (1); +SELECT * FROM test_like_gen_1; +CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1); +\d test_like_gen_2 +INSERT INTO test_like_gen_2 (a) VALUES (1); +SELECT * FROM test_like_gen_2; +CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED); +\d test_like_gen_3 +INSERT INTO test_like_gen_3 (a) VALUES (1); +SELECT * FROM test_like_gen_3; +DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3; + +CREATE TABLE test_like_4 (a int, b int DEFAULT 42, c int GENERATED ALWAYS AS (a * 2) STORED); +\d test_like_4 +CREATE TABLE test_like_4a (LIKE test_like_4); +CREATE TABLE test_like_4b (LIKE test_like_4 INCLUDING DEFAULTS); +CREATE TABLE test_like_4c (LIKE test_like_4 INCLUDING GENERATED); +CREATE TABLE test_like_4d (LIKE test_like_4 INCLUDING DEFAULTS INCLUDING GENERATED); +\d test_like_4a +INSERT INTO test_like_4a VALUES(11); +TABLE test_like_4a; +\d test_like_4b +INSERT INTO test_like_4b VALUES(11); +TABLE test_like_4b; +\d test_like_4c +INSERT INTO test_like_4c VALUES(11); +TABLE test_like_4c; +\d test_like_4d +INSERT INTO test_like_4d VALUES(11); +TABLE test_like_4d; +DROP TABLE test_like_4, test_like_4a, test_like_4b, test_like_4c, test_like_4d; + CREATE TABLE inhg (x text, LIKE inhx INCLUDING INDEXES, y text); /* copies indexes */ INSERT INTO inhg VALUES (5, 10); INSERT INTO inhg VALUES (20, 10); -- should fail @@ -136,19 +170,3 @@ DROP SEQUENCE ctlseq1; DROP TYPE ctlty1; DROP VIEW ctlv1; DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12; - -/* LIKE WITH OIDS */ -CREATE TABLE has_oid (x INTEGER) WITH OIDS; -CREATE TABLE no_oid (y INTEGER); -CREATE TABLE like_test (z INTEGER, LIKE has_oid); -SELECT oid FROM like_test; -CREATE TABLE like_test2 (z INTEGER, LIKE no_oid); -SELECT oid FROM like_test2; -- fail -CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid); -SELECT oid FROM like_test3; -CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid); -SELECT oid FROM like_test4; -CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS; -SELECT oid FROM like_test5; -DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3, - like_test4, like_test5; diff --git a/src/test/regress/sql/create_view.sql b/src/test/regress/sql/create_view.sql index 9480030005e..8c0f45cc526 100644 --- a/src/test/regress/sql/create_view.sql +++ b/src/test/regress/sql/create_view.sql @@ -24,6 +24,18 @@ COMMENT ON VIEW noview IS 'no view'; COMMENT ON VIEW toyemp IS 'is a view'; COMMENT ON VIEW toyemp IS NULL; +-- These views are left around mainly to exercise special cases in pg_dump. + +CREATE TABLE view_base_table (key int PRIMARY KEY, data varchar(20)); + +CREATE VIEW key_dependent_view AS + SELECT * FROM view_base_table GROUP BY key; + +ALTER TABLE view_base_table DROP CONSTRAINT view_base_table_pkey; -- fails + +CREATE VIEW key_dependent_view_no_cols AS + SELECT FROM view_base_table GROUP BY key HAVING length(data) > 0; + -- -- CREATE OR REPLACE VIEW -- @@ -307,6 +319,15 @@ ALTER TABLE tmp1 RENAME TO tx1; \d+ aliased_view_3 \d+ aliased_view_4 +-- Test aliasing of joins + +create view view_of_joins as +select * from + (select * from (tbl1 cross join tbl2) same) ss, + (tbl3 cross join tbl4) same; + +\d+ view_of_joins + -- Test view decompilation in the face of column addition/deletion/renaming create table tt2 (a int, b int, c int); @@ -581,6 +602,5 @@ select pg_get_ruledef(oid, true) from pg_rewrite where ev_class = 'tt23v'::regclass and ev_type = '1'; -- clean up all the random objects we made above -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA temp_view_test CASCADE; DROP SCHEMA testviewschm2 CASCADE; diff --git a/src/test/regress/sql/date.sql b/src/test/regress/sql/date.sql index 22f80f2ee25..4c5b94a14ad 100644 --- a/src/test/regress/sql/date.sql +++ b/src/test/regress/sql/date.sql @@ -334,7 +334,6 @@ SELECT EXTRACT(EPOCH FROM DATE 'infinity'); -- Infinity -- wrong fields from non-finite date: -- SELECT EXTRACT(MICROSEC FROM DATE 'infinity'); -- ERROR: timestamp units "microsec" not recognized -SELECT EXTRACT(UNDEFINED FROM DATE 'infinity'); -- ERROR: timestamp units "undefined" not supported -- test constructors select make_date(2013, 7, 15); diff --git a/src/test/regress/sql/dependency.sql b/src/test/regress/sql/dependency.sql index f5c45e4666a..2559c62d0b8 100644 --- a/src/test/regress/sql/dependency.sql +++ b/src/test/regress/sql/dependency.sql @@ -38,8 +38,8 @@ DROP USER regress_dep_user2; \set VERBOSITY terse ALTER TABLE deptest OWNER TO regress_dep_user3; DROP USER regress_dep_user3; - \set VERBOSITY default + -- if we drop the object, we can drop the user too DROP TABLE deptest; DROP USER regress_dep_user3; @@ -110,7 +110,6 @@ DROP USER regress_dep_user1; DROP OWNED BY regress_dep_user1; DROP USER regress_dep_user1; -\set VERBOSITY terse DROP USER regress_dep_user2; DROP OWNED BY regress_dep_user2, regress_dep_user0; DROP USER regress_dep_user2; diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 68da27de22b..1291d550d68 100644 --- a/src/test/regress/sql/domain.sql +++ b/src/test/regress/sql/domain.sql @@ -679,6 +679,26 @@ create domain di as int; create function dom_check(int) returns di as $$ declare d di; +begin + d := $1::di; + return d; +end +$$ language plpgsql immutable; + +select dom_check(0); + +alter domain di add constraint pos check (value > 0); + +select dom_check(0); -- fail + +alter domain di drop constraint pos; + +select dom_check(0); + +-- implicit cast during assignment is a separate code path, test that too + +create or replace function dom_check(int) returns di as $$ +declare d di; begin d := $1; return d; diff --git a/src/test/regress/sql/drop_if_exists.sql b/src/test/regress/sql/drop_if_exists.sql index c1d30bc4a5f..8a791b1ef2d 100644 --- a/src/test/regress/sql/drop_if_exists.sql +++ b/src/test/regress/sql/drop_if_exists.sql @@ -271,3 +271,27 @@ DROP TEXT SEARCH TEMPLATE IF EXISTS no_such_schema.foo; DROP TRIGGER IF EXISTS foo ON no_such_schema.bar; DROP TYPE IF EXISTS no_such_schema.foo; DROP VIEW IF EXISTS no_such_schema.foo; + +-- Check we receive an ambiguous function error when there are +-- multiple matching functions. +CREATE FUNCTION test_ambiguous_funcname(int) returns int as $$ select $1; $$ language sql; +CREATE FUNCTION test_ambiguous_funcname(text) returns text as $$ select $1; $$ language sql; +DROP FUNCTION test_ambiguous_funcname; +DROP FUNCTION IF EXISTS test_ambiguous_funcname; + +-- cleanup +DROP FUNCTION test_ambiguous_funcname(int); +DROP FUNCTION test_ambiguous_funcname(text); + +-- Likewise for procedures. +CREATE PROCEDURE test_ambiguous_procname(int) as $$ begin end; $$ language plpgsql; +CREATE PROCEDURE test_ambiguous_procname(text) as $$ begin end; $$ language plpgsql; +DROP PROCEDURE test_ambiguous_procname; +DROP PROCEDURE IF EXISTS test_ambiguous_procname; + +-- Check we get a similar error if we use ROUTINE instead of PROCEDURE. +DROP ROUTINE IF EXISTS test_ambiguous_procname; + +-- cleanup +DROP PROCEDURE test_ambiguous_procname(int); +DROP PROCEDURE test_ambiguous_procname(text); diff --git a/src/test/regress/sql/enum.sql b/src/test/regress/sql/enum.sql index 7b68b2fe376..6affd0d1ebe 100644 --- a/src/test/regress/sql/enum.sql +++ b/src/test/regress/sql/enum.sql @@ -273,19 +273,34 @@ ALTER TYPE rainbow RENAME VALUE 'blue' TO 'green'; -- CREATE TYPE bogus AS ENUM('good'); --- check that we can't add new values to existing enums in a transaction +-- check that we can add new values to existing enums in a transaction +-- but we can't use them BEGIN; -ALTER TYPE bogus ADD VALUE 'bad'; +ALTER TYPE bogus ADD VALUE 'new'; +SAVEPOINT x; +SELECT 'new'::bogus; -- unsafe +ROLLBACK TO x; +SELECT enum_first(null::bogus); -- safe +SELECT enum_last(null::bogus); -- unsafe +ROLLBACK TO x; +SELECT enum_range(null::bogus); -- unsafe +ROLLBACK TO x; COMMIT; +SELECT 'new'::bogus; -- now safe +SELECT enumlabel, enumsortorder +FROM pg_enum +WHERE enumtypid = 'bogus'::regtype +ORDER BY 2; -- check that we recognize the case where the enum already existed but was --- modified in the current txn +-- modified in the current txn; this should not be considered safe BEGIN; ALTER TYPE bogus RENAME TO bogon; ALTER TYPE bogon ADD VALUE 'bad'; +SELECT 'bad'::bogon; ROLLBACK; --- but ALTER TYPE RENAME VALUE is safe in a transaction +-- but a renamed value is safe to use later in same transaction BEGIN; ALTER TYPE bogus RENAME VALUE 'good' to 'bad'; SELECT 'bad'::bogus; @@ -293,12 +308,21 @@ ROLLBACK; DROP TYPE bogus; --- check that we *can* add new values to existing enums in a transaction, --- if the type is new as well +-- check that values created during CREATE TYPE can be used in any case +BEGIN; +CREATE TYPE bogus AS ENUM('good','bad','ugly'); +ALTER TYPE bogus RENAME TO bogon; +select enum_range(null::bogon); +ROLLBACK; + +-- ideally, we'd allow this usage; but it requires keeping track of whether +-- the enum type was created in the current transaction, which is expensive BEGIN; -CREATE TYPE bogus AS ENUM(); -ALTER TYPE bogus ADD VALUE 'good'; -ALTER TYPE bogus ADD VALUE 'ugly'; +CREATE TYPE bogus AS ENUM('good'); +ALTER TYPE bogus RENAME TO bogon; +ALTER TYPE bogon ADD VALUE 'bad'; +ALTER TYPE bogon ADD VALUE 'ugly'; +select enum_range(null::bogon); -- fails ROLLBACK; -- diff --git a/src/test/regress/sql/errors.sql b/src/test/regress/sql/errors.sql index 14bc723a52a..792c29c64b5 100644 --- a/src/test/regress/sql/errors.sql +++ b/src/test/regress/sql/errors.sql @@ -91,7 +91,7 @@ alter table emp rename column nonesuchatt to newnonesuchatt; alter table emp rename column salary to manager; -- conflict -alter table emp rename column salary to oid; +alter table emp rename column salary to ctid; -- diff --git a/src/test/regress/sql/event_trigger.sql b/src/test/regress/sql/event_trigger.sql index ef7faf0ab76..346168673db 100644 --- a/src/test/regress/sql/event_trigger.sql +++ b/src/test/regress/sql/event_trigger.sql @@ -28,7 +28,7 @@ create event trigger regress_event_trigger on ddl_command_start -- OK create event trigger regress_event_trigger_end on ddl_command_end - execute procedure test_event_trigger(); + execute function test_event_trigger(); -- should fail, food is not a valid filter variable create event trigger regress_event_trigger2 on ddl_command_start @@ -106,9 +106,28 @@ create table event_trigger_fire4 (a int); reset session_replication_role; -- fires all three create table event_trigger_fire5 (a int); +-- non-top-level command +create function f1() returns int +language plpgsql +as $$ +begin + create table event_trigger_fire6 (a int); + return 0; +end $$; +select f1(); +-- non-top-level command +create procedure p1() +language plpgsql +as $$ +begin + create table event_trigger_fire7 (a int); +end $$; +call p1(); + -- clean up alter event trigger regress_event_trigger disable; -drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5; +drop table event_trigger_fire2, event_trigger_fire3, event_trigger_fire4, event_trigger_fire5, event_trigger_fire6, event_trigger_fire7; +drop routine f1(), p1(); -- regress_event_trigger_end should fire on these commands grant all on table event_trigger_fire1 to public; @@ -274,6 +293,19 @@ CREATE SCHEMA evttrig CREATE INDEX one_idx ON one (col_b) CREATE TABLE two (col_c INTEGER CHECK (col_c > 0) REFERENCES one DEFAULT 42); +-- Partitioned tables with a partitioned index +CREATE TABLE evttrig.parted ( + id int PRIMARY KEY) + PARTITION BY RANGE (id); +CREATE TABLE evttrig.part_1_10 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (1) TO (10); +CREATE TABLE evttrig.part_10_20 PARTITION OF evttrig.parted (id) + FOR VALUES FROM (10) TO (20) PARTITION BY RANGE (id); +CREATE TABLE evttrig.part_10_15 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (10) TO (15); +CREATE TABLE evttrig.part_15_20 PARTITION OF evttrig.part_10_20 (id) + FOR VALUES FROM (15) TO (20); + ALTER TABLE evttrig.two DROP COLUMN col_c; ALTER TABLE evttrig.one ALTER COLUMN col_b DROP DEFAULT; ALTER TABLE evttrig.one DROP CONSTRAINT one_pkey; @@ -297,7 +329,7 @@ $$; create event trigger no_rewrite_allowed on table_rewrite execute procedure test_evtrig_no_rewrite(); -create table rewriteme (id serial primary key, foo float); +create table rewriteme (id serial primary key, foo float, bar timestamptz); insert into rewriteme select x * 1.001 from generate_series(1, 500) as t(x); alter table rewriteme alter column foo type numeric; @@ -320,6 +352,14 @@ alter table rewriteme -- shouldn't trigger a table_rewrite event alter table rewriteme alter column foo type numeric(12,4); +begin; +set timezone to 'UTC'; +alter table rewriteme alter column bar type timestamp; +set timezone to '0'; +alter table rewriteme alter column bar type timestamptz; +set timezone to 'Europe/London'; +alter table rewriteme alter column bar type timestamp; -- does rewrite +rollback; -- typed tables are rewritten when their type changes. Don't emit table -- name, because firing order is not stable. diff --git a/src/test/regress/sql/expressions.sql b/src/test/regress/sql/expressions.sql index 3427fdfdd72..1ca8bb151c8 100644 --- a/src/test/regress/sql/expressions.sql +++ b/src/test/regress/sql/expressions.sql @@ -1,5 +1,5 @@ -- --- expression evaluated tests that don't fit into a more specific file +-- expression evaluation tests that don't fit into a more specific file -- -- @@ -13,7 +13,9 @@ SELECT date(now())::text = current_date::text; -- current_time / localtime SELECT now()::timetz::text = current_time::text; +SELECT now()::timetz(4)::text = current_time(4)::text; SELECT now()::time::text = localtime::text; +SELECT now()::time(3)::text = localtime(3)::text; -- current_timestamp / localtimestamp (always matches because of transactional behaviour) SELECT current_timestamp = NOW(); @@ -34,3 +36,32 @@ SELECT current_schema; SET search_path = 'pg_catalog'; SELECT current_schema; RESET search_path; + + +-- +-- Tests for BETWEEN +-- + +explain (costs off) +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; +select count(*) from date_tbl + where f1 between '1997-01-01' and '1998-01-01'; + +explain (costs off) +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; +select count(*) from date_tbl + where f1 not between '1997-01-01' and '1998-01-01'; + +explain (costs off) +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; +select count(*) from date_tbl + where f1 between symmetric '1997-01-01' and '1998-01-01'; + +explain (costs off) +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; +select count(*) from date_tbl + where f1 not between symmetric '1997-01-01' and '1998-01-01'; diff --git a/src/test/regress/sql/fast_default.sql b/src/test/regress/sql/fast_default.sql index ea707d402af..4589b9e58d1 100644 --- a/src/test/regress/sql/fast_default.sql +++ b/src/test/regress/sql/fast_default.sql @@ -347,7 +347,191 @@ SELECT c_text FROM T WHERE c_int = -1; SELECT comp(); +-- query to exercise expand_tuple function +CREATE TABLE t1 AS +SELECT 1::int AS a , 2::int AS b +FROM generate_series(1,20) q; + +ALTER TABLE t1 ADD COLUMN c text; + +SELECT a, + stddev(cast((SELECT sum(1) FROM generate_series(1,20) x) AS float4)) + OVER (PARTITION BY a,b,c ORDER BY b) + AS z +FROM t1; + DROP TABLE T; + +-- test that we account for missing columns without defaults correctly +-- in expand_tuple, and that rows are correctly expanded for triggers + +CREATE FUNCTION test_trigger() +RETURNS trigger +LANGUAGE plpgsql +AS $$ + +begin + raise notice 'old tuple: %', to_json(OLD)::text; + if TG_OP = 'DELETE' + then + return OLD; + else + return NEW; + end if; +end; + +$$; + +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,3); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- same as last 4 tests but here the last original column has a NULL value +-- 2 new columns, both have defaults +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, first has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int NOT NULL DEFAULT 4; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, second has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int NOT NULL DEFAULT 5; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- 2 new columns, neither has default +CREATE TABLE t (id serial PRIMARY KEY, a int, b int, c int); +INSERT INTO t (a,b,c) VALUES (1,2,NULL); +ALTER TABLE t ADD COLUMN x int; +ALTER TABLE t ADD COLUMN y int; +CREATE TRIGGER a BEFORE UPDATE ON t FOR EACH ROW EXECUTE PROCEDURE test_trigger(); +SELECT * FROM t; +UPDATE t SET y = 2; +SELECT * FROM t; +DROP TABLE t; + +-- make sure expanded tuple has correct self pointer +-- it will be required by the RI trigger doing the cascading delete + +CREATE TABLE leader (a int PRIMARY KEY, b int); +CREATE TABLE follower (a int REFERENCES leader ON DELETE CASCADE, b int); +INSERT INTO leader VALUES (1, 1), (2, 2); +ALTER TABLE leader ADD c int; +ALTER TABLE leader DROP c; +DELETE FROM leader; + +-- check that ALTER TABLE ... ALTER TYPE does the right thing + +CREATE TABLE vtype( a integer); +INSERT INTO vtype VALUES (1); +ALTER TABLE vtype ADD COLUMN b DOUBLE PRECISION DEFAULT 0.2; +ALTER TABLE vtype ADD COLUMN c BOOLEAN DEFAULT true; +SELECT * FROM vtype; +ALTER TABLE vtype + ALTER b TYPE text USING b::text, + ALTER c TYPE text USING c::text; +SELECT * FROM vtype; + +-- also check the case that doesn't rewrite the table + +CREATE TABLE vtype2 (a int); +INSERT INTO vtype2 VALUES (1); +ALTER TABLE vtype2 ADD COLUMN b varchar(10) DEFAULT 'xxx'; +ALTER TABLE vtype2 ALTER COLUMN b SET DEFAULT 'yyy'; +INSERT INTO vtype2 VALUES (2); + +ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20); +SELECT * FROM vtype2; + + +-- Ensure that defaults are checked when evaluating whether HOT update +-- is possible, this was broken for a while: +-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de +BEGIN; +CREATE TABLE t(); +INSERT INTO t DEFAULT VALUES; +ALTER TABLE t ADD COLUMN a int DEFAULT 1; +CREATE INDEX ON t(a); +-- set column with a default 1 to NULL, due to a bug that wasn't +-- noticed has heap_getattr buggily returned NULL for default columns +UPDATE t SET a = NULL; + +-- verify that index and non-index scans show the same result +SET LOCAL enable_seqscan = true; +SELECT * FROM t WHERE a IS NULL; +SET LOCAL enable_seqscan = false; +SELECT * FROM t WHERE a IS NULL; +ROLLBACK; + + +-- cleanup +DROP TABLE vtype; +DROP TABLE vtype2; +DROP TABLE follower; +DROP TABLE leader; +DROP FUNCTION test_trigger(); +DROP TABLE t1; DROP FUNCTION set(name); DROP FUNCTION comp(); DROP TABLE m; @@ -355,3 +539,10 @@ DROP TABLE has_volatile; DROP EVENT TRIGGER has_volatile_rewrite; DROP FUNCTION log_rewrite; DROP SCHEMA fast_default; + +-- Leave a table with an active fast default in place, for pg_upgrade testing +set search_path = public; +create table has_fast_default(f1 int); +insert into has_fast_default values(1); +alter table has_fast_default add column f2 int default 42; +table has_fast_default; diff --git a/src/test/regress/sql/float4.sql b/src/test/regress/sql/float4.sql index 3b363f94635..393d98fb143 100644 --- a/src/test/regress/sql/float4.sql +++ b/src/test/regress/sql/float4.sql @@ -16,6 +16,16 @@ INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'); INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'); INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e70'::float8); +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e70'::float8); +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-70'::float8); +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-70'::float8); + +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e400'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e400'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('10e-400'); +INSERT INTO FLOAT4_TBL(f1) VALUES ('-10e-400'); + -- bad input INSERT INTO FLOAT4_TBL(f1) VALUES (''); INSERT INTO FLOAT4_TBL(f1) VALUES (' '); @@ -81,3 +91,262 @@ UPDATE FLOAT4_TBL WHERE FLOAT4_TBL.f1 > '0.0'; SELECT '' AS five, * FROM FLOAT4_TBL; + +-- test edge-case coercions to integer +SELECT '32767.4'::float4::int2; +SELECT '32767.6'::float4::int2; +SELECT '-32768.4'::float4::int2; +SELECT '-32768.6'::float4::int2; +SELECT '2147483520'::float4::int4; +SELECT '2147483647'::float4::int4; +SELECT '-2147483648.5'::float4::int4; +SELECT '-2147483900'::float4::int4; +SELECT '9223369837831520256'::float4::int8; +SELECT '9223372036854775807'::float4::int8; +SELECT '-9223372036854775808.5'::float4::int8; +SELECT '-9223380000000000000'::float4::int8; + +-- Test for correct input rounding in edge cases. +-- These lists are from Paxson 1991, excluding subnormals and +-- inputs of over 9 sig. digits. + +SELECT float4send('5e-20'::float4); +SELECT float4send('67e14'::float4); +SELECT float4send('985e15'::float4); +SELECT float4send('55895e-16'::float4); +SELECT float4send('7038531e-32'::float4); +SELECT float4send('702990899e-20'::float4); + +SELECT float4send('3e-23'::float4); +SELECT float4send('57e18'::float4); +SELECT float4send('789e-35'::float4); +SELECT float4send('2539e-18'::float4); +SELECT float4send('76173e28'::float4); +SELECT float4send('887745e-11'::float4); +SELECT float4send('5382571e-37'::float4); +SELECT float4send('82381273e-35'::float4); +SELECT float4send('750486563e-38'::float4); + +-- Test that the smallest possible normalized input value inputs +-- correctly, either in 9-significant-digit or shortest-decimal +-- format. +-- +-- exact val is 1.1754943508... +-- shortest val is 1.1754944000 +-- midpoint to next val is 1.1754944208... + +SELECT float4send('1.17549435e-38'::float4); +SELECT float4send('1.1754944e-38'::float4); + +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat4; +create function xfloat4in(cstring) returns xfloat4 immutable strict + language internal as 'int4in'; +create function xfloat4out(xfloat4) returns cstring immutable strict + language internal as 'int4out'; +create type xfloat4 (input = xfloat4in, output = xfloat4out, like = float4); +create cast (xfloat4 as float4) without function; +create cast (float4 as xfloat4) without function; +create cast (xfloat4 as integer) without function; +create cast (integer as xfloat4) without function; + +-- float4: seeeeeee emmmmmmm mmmmmmmm mmmmmmmm + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'00000001'), + (x'00000002'), (x'00000003'), + (x'00000010'), (x'00000011'), (x'00000100'), (x'00000101'), + (x'00004000'), (x'00004001'), (x'00080000'), (x'00080001'), + -- stress values + (x'0053c4f4'), -- 7693e-42 + (x'006c85c4'), -- 996622e-44 + (x'0041ca76'), -- 60419369e-46 + (x'004b7678'), -- 6930161142e-48 + -- taken from upstream testsuite + (x'00000007'), + (x'00424fe2'), + -- borderline between subnormal and normal + (x'007ffff0'), (x'007ffff1'), (x'007ffffe'), (x'007fffff')) +select float4send(flt) as ibits, + flt + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + +with testdata(bits) as (values + (x'00000000'), + -- smallest normal values + (x'00800000'), (x'00800001'), (x'00800004'), (x'00800005'), + (x'00800006'), + -- small normal values chosen for short vs. long output + (x'008002f1'), (x'008002f2'), (x'008002f3'), + (x'00800e17'), (x'00800e18'), (x'00800e19'), + -- assorted values (random mantissae) + (x'01000001'), (x'01102843'), (x'01a52c98'), + (x'0219c229'), (x'02e4464d'), (x'037343c1'), (x'03a91b36'), + (x'047ada65'), (x'0496fe87'), (x'0550844f'), (x'05999da3'), + (x'060ea5e2'), (x'06e63c45'), (x'07f1e548'), (x'0fc5282b'), + (x'1f850283'), (x'2874a9d6'), + -- values around 5e-08 + (x'3356bf94'), (x'3356bf95'), (x'3356bf96'), + -- around 1e-07 + (x'33d6bf94'), (x'33d6bf95'), (x'33d6bf96'), + -- around 3e-07 .. 1e-04 + (x'34a10faf'), (x'34a10fb0'), (x'34a10fb1'), + (x'350637bc'), (x'350637bd'), (x'350637be'), + (x'35719786'), (x'35719787'), (x'35719788'), + (x'358637bc'), (x'358637bd'), (x'358637be'), + (x'36a7c5ab'), (x'36a7c5ac'), (x'36a7c5ad'), + (x'3727c5ab'), (x'3727c5ac'), (x'3727c5ad'), + -- format crossover at 1e-04 + (x'38d1b714'), (x'38d1b715'), (x'38d1b716'), + (x'38d1b717'), (x'38d1b718'), (x'38d1b719'), + (x'38d1b71a'), (x'38d1b71b'), (x'38d1b71c'), + (x'38d1b71d'), + -- + (x'38dffffe'), (x'38dfffff'), (x'38e00000'), + (x'38efffff'), (x'38f00000'), (x'38f00001'), + (x'3a83126e'), (x'3a83126f'), (x'3a831270'), + (x'3c23d709'), (x'3c23d70a'), (x'3c23d70b'), + (x'3dcccccc'), (x'3dcccccd'), (x'3dccccce'), + -- chosen to need 9 digits for 3dcccd70 + (x'3dcccd6f'), (x'3dcccd70'), (x'3dcccd71'), + -- + (x'3effffff'), (x'3f000000'), (x'3f000001'), + (x'3f333332'), (x'3f333333'), (x'3f333334'), + -- approach 1.0 with increasing numbers of 9s + (x'3f666665'), (x'3f666666'), (x'3f666667'), + (x'3f7d70a3'), (x'3f7d70a4'), (x'3f7d70a5'), + (x'3f7fbe76'), (x'3f7fbe77'), (x'3f7fbe78'), + (x'3f7ff971'), (x'3f7ff972'), (x'3f7ff973'), + (x'3f7fff57'), (x'3f7fff58'), (x'3f7fff59'), + (x'3f7fffee'), (x'3f7fffef'), + -- values very close to 1 + (x'3f7ffff0'), (x'3f7ffff1'), (x'3f7ffff2'), + (x'3f7ffff3'), (x'3f7ffff4'), (x'3f7ffff5'), + (x'3f7ffff6'), (x'3f7ffff7'), (x'3f7ffff8'), + (x'3f7ffff9'), (x'3f7ffffa'), (x'3f7ffffb'), + (x'3f7ffffc'), (x'3f7ffffd'), (x'3f7ffffe'), + (x'3f7fffff'), + (x'3f800000'), + (x'3f800001'), (x'3f800002'), (x'3f800003'), + (x'3f800004'), (x'3f800005'), (x'3f800006'), + (x'3f800007'), (x'3f800008'), (x'3f800009'), + -- values 1 to 1.1 + (x'3f80000f'), (x'3f800010'), (x'3f800011'), + (x'3f800012'), (x'3f800013'), (x'3f800014'), + (x'3f800017'), (x'3f800018'), (x'3f800019'), + (x'3f80001a'), (x'3f80001b'), (x'3f80001c'), + (x'3f800029'), (x'3f80002a'), (x'3f80002b'), + (x'3f800053'), (x'3f800054'), (x'3f800055'), + (x'3f800346'), (x'3f800347'), (x'3f800348'), + (x'3f8020c4'), (x'3f8020c5'), (x'3f8020c6'), + (x'3f8147ad'), (x'3f8147ae'), (x'3f8147af'), + (x'3f8ccccc'), (x'3f8ccccd'), (x'3f8cccce'), + -- + (x'3fc90fdb'), -- pi/2 + (x'402df854'), -- e + (x'40490fdb'), -- pi + -- + (x'409fffff'), (x'40a00000'), (x'40a00001'), + (x'40afffff'), (x'40b00000'), (x'40b00001'), + (x'411fffff'), (x'41200000'), (x'41200001'), + (x'42c7ffff'), (x'42c80000'), (x'42c80001'), + (x'4479ffff'), (x'447a0000'), (x'447a0001'), + (x'461c3fff'), (x'461c4000'), (x'461c4001'), + (x'47c34fff'), (x'47c35000'), (x'47c35001'), + (x'497423ff'), (x'49742400'), (x'49742401'), + (x'4b18967f'), (x'4b189680'), (x'4b189681'), + (x'4cbebc1f'), (x'4cbebc20'), (x'4cbebc21'), + (x'4e6e6b27'), (x'4e6e6b28'), (x'4e6e6b29'), + (x'501502f8'), (x'501502f9'), (x'501502fa'), + (x'51ba43b6'), (x'51ba43b7'), (x'51ba43b8'), + -- stress values + (x'1f6c1e4a'), -- 5e-20 + (x'59be6cea'), -- 67e14 + (x'5d5ab6c4'), -- 985e15 + (x'2cc4a9bd'), -- 55895e-16 + (x'15ae43fd'), -- 7038531e-32 + (x'2cf757ca'), -- 702990899e-20 + (x'665ba998'), -- 25933168707e13 + (x'743c3324'), -- 596428896559e20 + -- exercise fixed-point memmoves + (x'47f1205a'), + (x'4640e6ae'), + (x'449a5225'), + (x'42f6e9d5'), + (x'414587dd'), + (x'3f9e064b'), + -- these cases come from the upstream's testsuite + -- BoundaryRoundEven + (x'4c000004'), + (x'50061c46'), + (x'510006a8'), + -- ExactValueRoundEven + (x'48951f84'), + (x'45fd1840'), + -- LotsOfTrailingZeros + (x'39800000'), + (x'3b200000'), + (x'3b900000'), + (x'3bd00000'), + -- Regression + (x'63800000'), + (x'4b000000'), + (x'4b800000'), + (x'4c000001'), + (x'4c800b0d'), + (x'00d24584'), + (x'00d90b88'), + (x'45803f34'), + (x'4f9f24f7'), + (x'3a8722c3'), + (x'5c800041'), + (x'15ae43fd'), + (x'5d4cccfb'), + (x'4c800001'), + (x'57800ed8'), + (x'5f000000'), + (x'700000f0'), + (x'5f23e9ac'), + (x'5e9502f9'), + (x'5e8012b1'), + (x'3c000028'), + (x'60cde861'), + (x'03aa2a50'), + (x'43480000'), + (x'4c000000'), + -- LooksLikePow5 + (x'5D1502F9'), + (x'5D9502F9'), + (x'5E1502F9'), + -- OutputLength + (x'3f99999a'), + (x'3f9d70a4'), + (x'3f9df3b6'), + (x'3f9e0419'), + (x'3f9e0610'), + (x'3f9e064b'), + (x'3f9e0651'), + (x'03d20cfe') +) +select float4send(flt) as ibits, + flt, + flt::text::float4 as r_flt, + float4send(flt::text::float4) as obits, + float4send(flt::text::float4) = float4send(flt) as correct + from (select bits::integer::xfloat4::float4 as flt + from testdata + offset 0) s; + +-- clean up, lest opr_sanity complain +drop type xfloat4 cascade; diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql index 215e7a47849..e540f03b072 100644 --- a/src/test/regress/sql/float8.sql +++ b/src/test/regress/sql/float8.sql @@ -16,6 +16,9 @@ SELECT '-10e400'::float8; SELECT '10e-400'::float8; SELECT '-10e-400'::float8; +-- test smallest normalized input +SELECT float8send('2.2250738585072014E-308'::float8); + -- bad input INSERT INTO FLOAT8_TBL(f1) VALUES (''); INSERT INTO FLOAT8_TBL(f1) VALUES (' '); @@ -97,6 +100,9 @@ select floor(f1) as floor_f1 from float8_tbl f; -- sign select sign(f1) as sign_f1 from float8_tbl f; +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; + -- square root SELECT sqrt(float8 '64') AS eight; @@ -108,6 +114,12 @@ SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1 -- power SELECT power(float8 '144', float8 '0.5'); +SELECT power(float8 'NaN', float8 '0.5'); +SELECT power(float8 '144', float8 'NaN'); +SELECT power(float8 'NaN', float8 'NaN'); +SELECT power(float8 '-1', float8 'NaN'); +SELECT power(float8 '1', float8 'NaN'); +SELECT power(float8 'NaN', float8 '0'); -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 @@ -142,6 +154,38 @@ SELECT '' AS bad, f.f1 / '0.0' from FLOAT8_TBL f; SELECT '' AS five, * FROM FLOAT8_TBL; +-- hyperbolic functions +-- we run these with extra_float_digits = 0 too, since different platforms +-- tend to produce results that vary in the last place. +SELECT sinh(float8 '1'); +SELECT cosh(float8 '1'); +SELECT tanh(float8 '1'); +SELECT asinh(float8 '1'); +SELECT acosh(float8 '2'); +SELECT atanh(float8 '0.5'); +-- test Inf/NaN cases for hyperbolic functions +SELECT sinh(float8 'infinity'); +SELECT sinh(float8 '-infinity'); +SELECT sinh(float8 'nan'); +SELECT cosh(float8 'infinity'); +SELECT cosh(float8 '-infinity'); +SELECT cosh(float8 'nan'); +SELECT tanh(float8 'infinity'); +SELECT tanh(float8 '-infinity'); +SELECT tanh(float8 'nan'); +SELECT asinh(float8 'infinity'); +SELECT asinh(float8 '-infinity'); +SELECT asinh(float8 'nan'); +-- acosh(Inf) should be Inf, but some mingw versions produce NaN, so skip test +-- SELECT acosh(float8 'infinity'); +SELECT acosh(float8 '-infinity'); +SELECT acosh(float8 'nan'); +SELECT atanh(float8 'infinity'); +SELECT atanh(float8 '-infinity'); +SELECT atanh(float8 'nan'); + +RESET extra_float_digits; + -- test for over- and underflow INSERT INTO FLOAT8_TBL(f1) VALUES ('10e400'); @@ -168,8 +212,21 @@ INSERT INTO FLOAT8_TBL(f1) VALUES ('-1.2345678901234e-200'); SELECT '' AS five, * FROM FLOAT8_TBL; +-- test edge-case coercions to integer +SELECT '32767.4'::float8::int2; +SELECT '32767.6'::float8::int2; +SELECT '-32768.4'::float8::int2; +SELECT '-32768.6'::float8::int2; +SELECT '2147483647.4'::float8::int4; +SELECT '2147483647.6'::float8::int4; +SELECT '-2147483648.4'::float8::int4; +SELECT '-2147483648.6'::float8::int4; +SELECT '9223372036854773760'::float8::int8; +SELECT '9223372036854775807'::float8::int8; +SELECT '-9223372036854775808.5'::float8::int8; +SELECT '-9223372036854780000'::float8::int8; + -- test exact cases for trigonometric functions in degrees -SET extra_float_digits = 3; SELECT x, sind(x), @@ -212,4 +269,198 @@ SELECT x, y, FROM (SELECT 10*cosd(a), 10*sind(a) FROM generate_series(0, 360, 90) AS t(a)) AS t(x,y); -RESET extra_float_digits; +-- +-- test output (and round-trip safety) of various values. +-- To ensure we're testing what we think we're testing, start with +-- float values specified by bit patterns (as a useful side effect, +-- this means we'll fail on non-IEEE platforms). + +create type xfloat8; +create function xfloat8in(cstring) returns xfloat8 immutable strict + language internal as 'int8in'; +create function xfloat8out(xfloat8) returns cstring immutable strict + language internal as 'int8out'; +create type xfloat8 (input = xfloat8in, output = xfloat8out, like = float8); +create cast (xfloat8 as float8) without function; +create cast (float8 as xfloat8) without function; +create cast (xfloat8 as bigint) without function; +create cast (bigint as xfloat8) without function; + +-- float8: seeeeeee eeeeeeee eeeeeeee mmmmmmmm mmmmmmmm(x4) + +-- we don't care to assume the platform's strtod() handles subnormals +-- correctly; those are "use at your own risk". However we do test +-- subnormal outputs, since those are under our control. + +with testdata(bits) as (values + -- small subnormals + (x'0000000000000001'), + (x'0000000000000002'), (x'0000000000000003'), + (x'0000000000001000'), (x'0000000100000000'), + (x'0000010000000000'), (x'0000010100000000'), + (x'0000400000000000'), (x'0000400100000000'), + (x'0000800000000000'), (x'0000800000000001'), + -- these values taken from upstream testsuite + (x'00000000000f4240'), + (x'00000000016e3600'), + (x'0000008cdcdea440'), + -- borderline between subnormal and normal + (x'000ffffffffffff0'), (x'000ffffffffffff1'), + (x'000ffffffffffffe'), (x'000fffffffffffff')) +select float8send(flt) as ibits, + flt + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + +-- round-trip tests + +with testdata(bits) as (values + (x'0000000000000000'), + -- smallest normal values + (x'0010000000000000'), (x'0010000000000001'), + (x'0010000000000002'), (x'0018000000000000'), + -- + (x'3ddb7cdfd9d7bdba'), (x'3ddb7cdfd9d7bdbb'), (x'3ddb7cdfd9d7bdbc'), + (x'3e112e0be826d694'), (x'3e112e0be826d695'), (x'3e112e0be826d696'), + (x'3e45798ee2308c39'), (x'3e45798ee2308c3a'), (x'3e45798ee2308c3b'), + (x'3e7ad7f29abcaf47'), (x'3e7ad7f29abcaf48'), (x'3e7ad7f29abcaf49'), + (x'3eb0c6f7a0b5ed8c'), (x'3eb0c6f7a0b5ed8d'), (x'3eb0c6f7a0b5ed8e'), + (x'3ee4f8b588e368ef'), (x'3ee4f8b588e368f0'), (x'3ee4f8b588e368f1'), + (x'3f1a36e2eb1c432c'), (x'3f1a36e2eb1c432d'), (x'3f1a36e2eb1c432e'), + (x'3f50624dd2f1a9fb'), (x'3f50624dd2f1a9fc'), (x'3f50624dd2f1a9fd'), + (x'3f847ae147ae147a'), (x'3f847ae147ae147b'), (x'3f847ae147ae147c'), + (x'3fb9999999999999'), (x'3fb999999999999a'), (x'3fb999999999999b'), + -- values very close to 1 + (x'3feffffffffffff0'), (x'3feffffffffffff1'), (x'3feffffffffffff2'), + (x'3feffffffffffff3'), (x'3feffffffffffff4'), (x'3feffffffffffff5'), + (x'3feffffffffffff6'), (x'3feffffffffffff7'), (x'3feffffffffffff8'), + (x'3feffffffffffff9'), (x'3feffffffffffffa'), (x'3feffffffffffffb'), + (x'3feffffffffffffc'), (x'3feffffffffffffd'), (x'3feffffffffffffe'), + (x'3fefffffffffffff'), + (x'3ff0000000000000'), + (x'3ff0000000000001'), (x'3ff0000000000002'), (x'3ff0000000000003'), + (x'3ff0000000000004'), (x'3ff0000000000005'), (x'3ff0000000000006'), + (x'3ff0000000000007'), (x'3ff0000000000008'), (x'3ff0000000000009'), + -- + (x'3ff921fb54442d18'), + (x'4005bf0a8b14576a'), + (x'400921fb54442d18'), + -- + (x'4023ffffffffffff'), (x'4024000000000000'), (x'4024000000000001'), + (x'4058ffffffffffff'), (x'4059000000000000'), (x'4059000000000001'), + (x'408f3fffffffffff'), (x'408f400000000000'), (x'408f400000000001'), + (x'40c387ffffffffff'), (x'40c3880000000000'), (x'40c3880000000001'), + (x'40f869ffffffffff'), (x'40f86a0000000000'), (x'40f86a0000000001'), + (x'412e847fffffffff'), (x'412e848000000000'), (x'412e848000000001'), + (x'416312cfffffffff'), (x'416312d000000000'), (x'416312d000000001'), + (x'4197d783ffffffff'), (x'4197d78400000000'), (x'4197d78400000001'), + (x'41cdcd64ffffffff'), (x'41cdcd6500000000'), (x'41cdcd6500000001'), + (x'4202a05f1fffffff'), (x'4202a05f20000000'), (x'4202a05f20000001'), + (x'42374876e7ffffff'), (x'42374876e8000000'), (x'42374876e8000001'), + (x'426d1a94a1ffffff'), (x'426d1a94a2000000'), (x'426d1a94a2000001'), + (x'42a2309ce53fffff'), (x'42a2309ce5400000'), (x'42a2309ce5400001'), + (x'42d6bcc41e8fffff'), (x'42d6bcc41e900000'), (x'42d6bcc41e900001'), + (x'430c6bf52633ffff'), (x'430c6bf526340000'), (x'430c6bf526340001'), + (x'4341c37937e07fff'), (x'4341c37937e08000'), (x'4341c37937e08001'), + (x'4376345785d89fff'), (x'4376345785d8a000'), (x'4376345785d8a001'), + (x'43abc16d674ec7ff'), (x'43abc16d674ec800'), (x'43abc16d674ec801'), + (x'43e158e460913cff'), (x'43e158e460913d00'), (x'43e158e460913d01'), + (x'4415af1d78b58c3f'), (x'4415af1d78b58c40'), (x'4415af1d78b58c41'), + (x'444b1ae4d6e2ef4f'), (x'444b1ae4d6e2ef50'), (x'444b1ae4d6e2ef51'), + (x'4480f0cf064dd591'), (x'4480f0cf064dd592'), (x'4480f0cf064dd593'), + (x'44b52d02c7e14af5'), (x'44b52d02c7e14af6'), (x'44b52d02c7e14af7'), + (x'44ea784379d99db3'), (x'44ea784379d99db4'), (x'44ea784379d99db5'), + (x'45208b2a2c280290'), (x'45208b2a2c280291'), (x'45208b2a2c280292'), + -- + (x'7feffffffffffffe'), (x'7fefffffffffffff'), + -- round to even tests (+ve) + (x'4350000000000002'), + (x'4350000000002e06'), + (x'4352000000000003'), + (x'4352000000000004'), + (x'4358000000000003'), + (x'4358000000000004'), + (x'435f000000000020'), + -- round to even tests (-ve) + (x'c350000000000002'), + (x'c350000000002e06'), + (x'c352000000000003'), + (x'c352000000000004'), + (x'c358000000000003'), + (x'c358000000000004'), + (x'c35f000000000020'), + -- exercise fixed-point memmoves + (x'42dc12218377de66'), + (x'42a674e79c5fe51f'), + (x'4271f71fb04cb74c'), + (x'423cbe991a145879'), + (x'4206fee0e1a9e061'), + (x'41d26580b487e6b4'), + (x'419d6f34540ca453'), + (x'41678c29dcd6e9dc'), + (x'4132d687e3df217d'), + (x'40fe240c9fcb68c8'), + (x'40c81cd6e63c53d3'), + (x'40934a4584fd0fdc'), + (x'405edd3c07fb4c93'), + (x'4028b0fcd32f7076'), + (x'3ff3c0ca428c59f8'), + -- these cases come from the upstream's testsuite + -- LotsOfTrailingZeros) + (x'3e60000000000000'), + -- Regression + (x'c352bd2668e077c4'), + (x'434018601510c000'), + (x'43d055dc36f24000'), + (x'43e052961c6f8000'), + (x'3ff3c0ca2a5b1d5d'), + -- LooksLikePow5 + (x'4830f0cf064dd592'), + (x'4840f0cf064dd592'), + (x'4850f0cf064dd592'), + -- OutputLength + (x'3ff3333333333333'), + (x'3ff3ae147ae147ae'), + (x'3ff3be76c8b43958'), + (x'3ff3c083126e978d'), + (x'3ff3c0c1fc8f3238'), + (x'3ff3c0c9539b8887'), + (x'3ff3c0ca2a5b1d5d'), + (x'3ff3c0ca4283de1b'), + (x'3ff3c0ca43db770a'), + (x'3ff3c0ca428abd53'), + (x'3ff3c0ca428c1d2b'), + (x'3ff3c0ca428c51f2'), + (x'3ff3c0ca428c58fc'), + (x'3ff3c0ca428c59dd'), + (x'3ff3c0ca428c59f8'), + (x'3ff3c0ca428c59fb'), + -- 32-bit chunking + (x'40112e0be8047a7d'), + (x'40112e0be815a889'), + (x'40112e0be826d695'), + (x'40112e0be83804a1'), + (x'40112e0be84932ad'), + -- MinMaxShift + (x'0040000000000000'), + (x'007fffffffffffff'), + (x'0290000000000000'), + (x'029fffffffffffff'), + (x'4350000000000000'), + (x'435fffffffffffff'), + (x'1330000000000000'), + (x'133fffffffffffff'), + (x'3a6fa7161a4d6e0c') +) +select float8send(flt) as ibits, + flt, + flt::text::float8 as r_flt, + float8send(flt::text::float8) as obits, + float8send(flt::text::float8) = float8send(flt) as correct + from (select bits::bigint::xfloat8::float8 as flt + from testdata + offset 0) s; + +-- clean up, lest opr_sanity complain +drop type xfloat8 cascade; diff --git a/src/test/regress/sql/foreign_data.sql b/src/test/regress/sql/foreign_data.sql index 63e2e616d71..73f9f621d8f 100644 --- a/src/test/regress/sql/foreign_data.sql +++ b/src/test/regress/sql/foreign_data.sql @@ -283,7 +283,6 @@ CREATE SCHEMA foreign_schema; CREATE SERVER s0 FOREIGN DATA WRAPPER dummy; CREATE FOREIGN TABLE ft1 (); -- ERROR CREATE FOREIGN TABLE ft1 () SERVER no_server; -- ERROR -CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS; -- ERROR CREATE FOREIGN TABLE ft1 ( c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY, c2 text OPTIONS (param2 'val2', param3 'val3'), @@ -316,6 +315,52 @@ CREATE INDEX id_ft1_c2 ON ft1 (c2); -- ERROR SELECT * FROM ft1; -- ERROR EXPLAIN SELECT * FROM ft1; -- ERROR +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; +CREATE INDEX ON lt1 (a); -- skips partition +CREATE UNIQUE INDEX ON lt1 (a); -- ERROR +ALTER TABLE lt1 ADD PRIMARY KEY (a); -- ERROR +DROP TABLE lt1; + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE INDEX ON lt1 (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; +CREATE FOREIGN TABLE ft_part2 (a INT) SERVER s0; +ALTER TABLE lt1 ATTACH PARTITION ft_part2 FOR VALUES FROM (1000) TO (2000); +DROP FOREIGN TABLE ft_part1, ft_part2; +CREATE UNIQUE INDEX ON lt1 (a); +ALTER TABLE lt1 ADD PRIMARY KEY (a); +CREATE FOREIGN TABLE ft_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) SERVER s0; -- ERROR +CREATE FOREIGN TABLE ft_part2 (a INT NOT NULL) SERVER s0; +ALTER TABLE lt1 ATTACH PARTITION ft_part2 + FOR VALUES FROM (1000) TO (2000); -- ERROR +DROP TABLE lt1; +DROP FOREIGN TABLE ft_part2; + +CREATE TABLE lt1 (a INT) PARTITION BY RANGE (a); +CREATE INDEX ON lt1 (a); +CREATE TABLE lt1_part1 + PARTITION OF lt1 FOR VALUES FROM (0) TO (1000) + PARTITION BY RANGE (a); +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; +CREATE FOREIGN TABLE ft_part_1_2 (a INT) SERVER s0; +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); +CREATE UNIQUE INDEX ON lt1 (a); +ALTER TABLE lt1 ADD PRIMARY KEY (a); +DROP FOREIGN TABLE ft_part_1_1, ft_part_1_2; +CREATE UNIQUE INDEX ON lt1 (a); +ALTER TABLE lt1 ADD PRIMARY KEY (a); +CREATE FOREIGN TABLE ft_part_1_1 + PARTITION OF lt1_part1 FOR VALUES FROM (0) TO (100) SERVER s0; +CREATE FOREIGN TABLE ft_part_1_2 (a INT NOT NULL) SERVER s0; +ALTER TABLE lt1_part1 ATTACH PARTITION ft_part_1_2 FOR VALUES FROM (100) TO (200); +DROP TABLE lt1; +DROP FOREIGN TABLE ft_part_1_2; + -- ALTER FOREIGN TABLE COMMENT ON FOREIGN TABLE ft1 IS 'foreign table'; COMMENT ON FOREIGN TABLE ft1 IS NULL; @@ -356,7 +401,6 @@ ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE; -- ERROR ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check; ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const; -- ERROR ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const; -ALTER FOREIGN TABLE ft1 SET WITH OIDS; ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role; ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@'); ALTER FOREIGN TABLE ft1 DROP COLUMN no_column; -- ERROR @@ -497,10 +541,7 @@ CREATE SERVER s10 FOREIGN DATA WRAPPER foo; -- ERROR ALTER SERVER s9 VERSION '1.1'; GRANT USAGE ON FOREIGN SERVER s9 TO regress_test_role; CREATE USER MAPPING FOR current_user SERVER s9; --- We use terse mode to avoid ordering issues in cascade detail output. -\set VERBOSITY terse DROP SERVER s9 CASCADE; -\set VERBOSITY default RESET ROLE; CREATE SERVER s9 FOREIGN DATA WRAPPER foo; GRANT USAGE ON FOREIGN SERVER s9 TO regress_unprivileged_role; @@ -524,9 +565,7 @@ RESET ROLE; SET ROLE regress_unprivileged_role; \deu+ RESET ROLE; -\set VERBOSITY terse DROP SERVER s10 CASCADE; -\set VERBOSITY default -- Triggers CREATE FUNCTION dummy_trigger() RETURNS TRIGGER AS $$ @@ -656,10 +695,8 @@ SELECT relname, conname, contype, conislocal, coninhcount, connoinherit -- child does not inherit NO INHERIT constraints \d+ fd_pt1 \d+ ft2 -\set VERBOSITY terse DROP FOREIGN TABLE ft2; -- ERROR DROP FOREIGN TABLE ft2 CASCADE; -\set VERBOSITY default CREATE FOREIGN TABLE ft2 ( c1 integer NOT NULL, c2 text, @@ -687,15 +724,6 @@ ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3; \d+ fd_pt1 \d+ ft2 --- OID system column -ALTER TABLE fd_pt1 SET WITH OIDS; -\d+ fd_pt1 -\d+ ft2 -ALTER TABLE ft2 SET WITHOUT OIDS; -- ERROR -ALTER TABLE fd_pt1 SET WITHOUT OIDS; -\d+ fd_pt1 -\d+ ft2 - -- changes name of an attribute recursively ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1; ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2; @@ -799,15 +827,23 @@ TRUNCATE fd_pt2; -- ERROR DROP FOREIGN TABLE fd_pt2_1; DROP TABLE fd_pt2; +-- foreign table cannot be part of partition tree made of temporary +-- relations. +CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a); +CREATE FOREIGN TABLE foreign_part PARTITION OF temp_parted DEFAULT + SERVER s0; -- ERROR +CREATE FOREIGN TABLE foreign_part (a int) SERVER s0; +ALTER TABLE temp_parted ATTACH PARTITION foreign_part DEFAULT; -- ERROR +DROP FOREIGN TABLE foreign_part; +DROP TABLE temp_parted; + -- Cleanup DROP SCHEMA foreign_schema CASCADE; DROP ROLE regress_test_role; -- ERROR DROP SERVER t1 CASCADE; DROP USER MAPPING FOR regress_test_role SERVER s6; -\set VERBOSITY terse DROP FOREIGN DATA WRAPPER foo CASCADE; DROP SERVER s8 CASCADE; -\set VERBOSITY default DROP ROLE regress_test_indirect; DROP ROLE regress_test_role; DROP ROLE regress_unprivileged_role; -- ERROR diff --git a/src/test/regress/sql/foreign_key.sql b/src/test/regress/sql/foreign_key.sql index f3e70585839..b67bef01df5 100644 --- a/src/test/regress/sql/foreign_key.sql +++ b/src/test/regress/sql/foreign_key.sql @@ -97,6 +97,12 @@ UPDATE PKTABLE SET ptest1=1 WHERE ptest1=2; -- Check FKTABLE for update of matched row SELECT * FROM FKTABLE; +-- Check update with part of key null +UPDATE FKTABLE SET ftest1 = NULL WHERE ftest1 = 1; + +-- Check update with old and new key values equal +UPDATE FKTABLE SET ftest1 = 1 WHERE ftest1 = 1; + -- Try altering the column type where foreign keys are involved ALTER TABLE PKTABLE ALTER COLUMN ptest1 TYPE bigint; ALTER TABLE FKTABLE ALTER COLUMN ftest1 TYPE bigint; @@ -213,6 +219,20 @@ SELECT * FROM PKTABLE; DROP TABLE FKTABLE; DROP TABLE PKTABLE; +-- +-- Check initial check upon ALTER TABLE +-- +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, PRIMARY KEY(ptest1, ptest2) ); +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int ); + +INSERT INTO PKTABLE VALUES (1, 2); +INSERT INTO FKTABLE VALUES (1, NULL); + +ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) REFERENCES PKTABLE MATCH FULL; + +DROP TABLE FKTABLE; +DROP TABLE PKTABLE; + -- MATCH SIMPLE @@ -260,6 +280,25 @@ SELECT * from FKTABLE; DROP TABLE FKTABLE; DROP TABLE PKTABLE; +-- restrict with null values +CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, UNIQUE(ptest1, ptest2, ptest3) ); +CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 + FOREIGN KEY(ftest1, ftest2, ftest3) REFERENCES PKTABLE (ptest1, ptest2, ptest3)); + +INSERT INTO PKTABLE VALUES (1, 2, 3, 'test1'); +INSERT INTO PKTABLE VALUES (1, 3, NULL, 'test2'); +INSERT INTO PKTABLE VALUES (2, NULL, 4, 'test3'); + +INSERT INTO FKTABLE VALUES (1, 2, 3, 1); + +DELETE FROM PKTABLE WHERE ptest1 = 2; + +SELECT * FROM PKTABLE; +SELECT * FROM FKTABLE; + +DROP TABLE FKTABLE; +DROP TABLE PKTABLE; + -- cascade update/delete CREATE TABLE PKTABLE ( ptest1 int, ptest2 int, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2, ptest3) ); CREATE TABLE FKTABLE ( ftest1 int, ftest2 int, ftest3 int, ftest4 int, CONSTRAINT constrname3 @@ -615,7 +654,6 @@ drop table pktable_base; -- -- Deferrable constraints --- (right now, only FOREIGN KEY constraints can be deferred) -- -- deferrable, explicitly deferred @@ -992,22 +1030,24 @@ delete from defp where f1 = 1; -- fail -- Test the difference between NO ACTION and RESTRICT -- create temp table pp (f1 int primary key); -create temp table cc (f1 int references pp on update no action); +create temp table cc (f1 int references pp on update no action on delete no action); insert into pp values(12); insert into pp values(11); update pp set f1=f1+1; insert into cc values(13); update pp set f1=f1+1; update pp set f1=f1+1; -- fail +delete from pp where f1 = 13; -- fail drop table pp, cc; create temp table pp (f1 int primary key); -create temp table cc (f1 int references pp on update restrict); +create temp table cc (f1 int references pp on update restrict on delete restrict); insert into pp values(12); insert into pp values(11); update pp set f1=f1+1; insert into cc values(13); update pp set f1=f1+1; -- fail +delete from pp where f1 = 13; -- fail drop table pp, cc; -- @@ -1030,6 +1070,20 @@ delete from pktable2; update pktable2 set d = 5; drop table pktable2, fktable2; +-- Test truncation of long foreign key names +create table pktable1 (a int primary key); +create table pktable2 (a int, b int, primary key (a, b)); +create table fktable2 ( + a int, + b int, + very_very_long_column_name_to_exceed_63_characters int, + foreign key (very_very_long_column_name_to_exceed_63_characters) references pktable1, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2, + foreign key (a, very_very_long_column_name_to_exceed_63_characters) references pktable2 +); +select conname from pg_constraint where conrelid = 'fktable2'::regclass order by conname; +drop table pktable1, pktable2, fktable2; + -- -- Test deferred FK check on a tuple deleted by a rolled-back subtransaction -- @@ -1066,23 +1120,31 @@ commit; drop table pktable2, fktable2; +-- +-- Test keys that "look" different but compare as equal +-- +create table pktable2 (a float8, b float8, primary key (a, b)); +create table fktable2 (x float8, y float8, foreign key (x, y) references pktable2 (a, b) on update cascade); + +insert into pktable2 values ('-0', '-0'); +insert into fktable2 values ('-0', '-0'); + +select * from pktable2; +select * from fktable2; + +update pktable2 set a = '0' where a = '-0'; + +select * from pktable2; +-- should have updated fktable2.x +select * from fktable2; + +drop table pktable2, fktable2; + -- -- Foreign keys and partitioned tables -- --- partitioned table in the referenced side are not allowed -CREATE TABLE fk_partitioned_pk (a int, b int, primary key (a, b)) - PARTITION BY RANGE (a, b); --- verify with create table first ... -CREATE TABLE fk_notpartitioned_fk (a int, b int, - FOREIGN KEY (a, b) REFERENCES fk_partitioned_pk); --- and then with alter table. -CREATE TABLE fk_notpartitioned_fk_2 (a int, b int); -ALTER TABLE fk_notpartitioned_fk_2 ADD FOREIGN KEY (a, b) - REFERENCES fk_partitioned_pk; -DROP TABLE fk_partitioned_pk, fk_notpartitioned_fk_2; - -- Creation of a partitioned hierarchy with irregular definitions CREATE TABLE fk_notpartitioned_pk (fdrop1 int, a int, fdrop2 int, b int, PRIMARY KEY (a, b)); @@ -1106,7 +1168,16 @@ CREATE TABLE fk_partitioned_fk_3_1 PARTITION OF fk_partitioned_fk_3 FOR VALUES W ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_3 FOR VALUES FROM (2000,2000) TO (3000,3000); --- these inserts, targetting both the partition directly as well as the +-- Creating a foreign key with ONLY on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE ONLY fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk; +-- Adding a NOT VALID foreign key on a partitioned table referencing +-- a non-partitioned table fails. +ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) + REFERENCES fk_notpartitioned_pk NOT VALID; + +-- these inserts, targeting both the partition directly as well as the -- partitioned table, should all fail INSERT INTO fk_partitioned_fk (a,b) VALUES (500, 501); INSERT INTO fk_partitioned_fk_1 (a,b) VALUES (500, 501); @@ -1135,10 +1206,23 @@ UPDATE fk_partitioned_fk SET a = a + 1 WHERE a = 2501; UPDATE fk_notpartitioned_pk SET b = 502 WHERE a = 500; UPDATE fk_notpartitioned_pk SET b = 1502 WHERE a = 1500; UPDATE fk_notpartitioned_pk SET b = 2504 WHERE a = 2500; -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +-- check psql behavior +\d fk_notpartitioned_pk +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; -- done. DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; +-- Altering a type referenced by a foreign key needs to drop/recreate the FK. +-- Ensure that works. +CREATE TABLE fk_notpartitioned_pk (a INT, PRIMARY KEY(a), CHECK (a > 0)); +CREATE TABLE fk_partitioned_fk (a INT REFERENCES fk_notpartitioned_pk(a) PRIMARY KEY) PARTITION BY RANGE(a); +CREATE TABLE fk_partitioned_fk_1 PARTITION OF fk_partitioned_fk FOR VALUES FROM (MINVALUE) TO (MAXVALUE); +INSERT INTO fk_notpartitioned_pk VALUES (1); +INSERT INTO fk_partitioned_fk VALUES (1); +ALTER TABLE fk_notpartitioned_pk ALTER COLUMN a TYPE bigint; +DELETE FROM fk_notpartitioned_pk WHERE a = 1; +DROP TABLE fk_notpartitioned_pk, fk_partitioned_fk; + -- Test some other exotic foreign key features: MATCH SIMPLE, ON UPDATE/DELETE -- actions CREATE TABLE fk_notpartitioned_pk (a int, b int, primary key (a, b)); @@ -1163,6 +1247,17 @@ INSERT INTO fk_partitioned_fk_3 (a, b) VALUES (2502, 2503); -- this always works INSERT INTO fk_partitioned_fk (a,b) VALUES (NULL, NULL); +-- MATCH FULL +INSERT INTO fk_notpartitioned_pk VALUES (1, 2); +CREATE TABLE fk_partitioned_fk_full (x int, y int) PARTITION BY RANGE (x); +CREATE TABLE fk_partitioned_fk_full_1 PARTITION OF fk_partitioned_fk_full DEFAULT; +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; -- fails +TRUNCATE fk_partitioned_fk_full; +ALTER TABLE fk_partitioned_fk_full ADD FOREIGN KEY (x, y) REFERENCES fk_notpartitioned_pk MATCH FULL; +INSERT INTO fk_partitioned_fk_full VALUES (1, NULL); -- fails +DROP TABLE fk_partitioned_fk_full; + -- ON UPDATE SET NULL SELECT tableoid::regclass, a, b FROM fk_partitioned_fk WHERE b IS NULL ORDER BY a; UPDATE fk_notpartitioned_pk SET a = a + 1 WHERE a = 2502; @@ -1175,7 +1270,7 @@ DELETE FROM fk_notpartitioned_pk; SELECT count(*) FROM fk_partitioned_fk WHERE a IS NULL; -- ON UPDATE/DELETE SET DEFAULT -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE SET DEFAULT ON UPDATE SET DEFAULT; @@ -1190,7 +1285,7 @@ UPDATE fk_notpartitioned_pk SET a = 1500 WHERE a = 2502; SELECT * FROM fk_partitioned_fk WHERE b = 142857; -- ON UPDATE/DELETE CASCADE -ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_fkey; +ALTER TABLE fk_partitioned_fk DROP CONSTRAINT fk_partitioned_fk_a_b_fkey; ALTER TABLE fk_partitioned_fk ADD FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON DELETE CASCADE ON UPDATE CASCADE; @@ -1206,6 +1301,56 @@ SELECT * FROM fk_partitioned_fk WHERE a = 142857; -- verify that DROP works DROP TABLE fk_partitioned_fk_2; +-- Test behavior of the constraint together with attaching and detaching +-- partitions. +CREATE TABLE fk_partitioned_fk_2 PARTITION OF fk_partitioned_fk FOR VALUES IN (1500,1502); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_2; +BEGIN; +DROP TABLE fk_partitioned_fk; +-- constraint should still be there +\d fk_partitioned_fk_2; +ROLLBACK; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); +DROP TABLE fk_partitioned_fk_2; +CREATE TABLE fk_partitioned_fk_2 (b int, c text, a int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk ON UPDATE CASCADE ON DELETE CASCADE); +ALTER TABLE fk_partitioned_fk_2 DROP COLUMN c; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1500,1502); +-- should have only one constraint +\d fk_partitioned_fk_2 +DROP TABLE fk_partitioned_fk_2; + +CREATE TABLE fk_partitioned_fk_4 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE) PARTITION BY RANGE (b, a); +CREATE TABLE fk_partitioned_fk_4_1 PARTITION OF fk_partitioned_fk_4 FOR VALUES FROM (1,1) TO (100,100); +CREATE TABLE fk_partitioned_fk_4_2 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE SET NULL); +ALTER TABLE fk_partitioned_fk_4 ATTACH PARTITION fk_partitioned_fk_4_2 FOR VALUES FROM (100,100) TO (1000,1000); +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_4; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_4 FOR VALUES IN (3500,3502); +-- should only have one constraint +\d fk_partitioned_fk_4 +\d fk_partitioned_fk_4_1 +-- this one has an FK with mismatched properties +\d fk_partitioned_fk_4_2 + +CREATE TABLE fk_partitioned_fk_5 (a int, b int, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE, + FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk(a, b) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE) + PARTITION BY RANGE (a); +CREATE TABLE fk_partitioned_fk_5_1 (a int, b int, FOREIGN KEY (a, b) REFERENCES fk_notpartitioned_pk); +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); +ALTER TABLE fk_partitioned_fk DETACH PARTITION fk_partitioned_fk_5; +ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_5 FOR VALUES IN (4500); +-- this one has two constraints, similar but not quite the one in the parent, +-- so it gets a new one +\d fk_partitioned_fk_5 +-- verify that it works to reattaching a child with multiple candidate +-- constraints +ALTER TABLE fk_partitioned_fk_5 DETACH PARTITION fk_partitioned_fk_5_1; +ALTER TABLE fk_partitioned_fk_5 ATTACH PARTITION fk_partitioned_fk_5_1 FOR VALUES FROM (0) TO (10); +\d fk_partitioned_fk_5_1 + -- verify that attaching a table checks that the existing data satisfies the -- constraint CREATE TABLE fk_partitioned_fk_2 (a int, b int) PARTITION BY RANGE (b); @@ -1219,3 +1364,318 @@ ALTER TABLE fk_partitioned_fk ATTACH PARTITION fk_partitioned_fk_2 FOR VALUES IN (1600); -- leave these tables around intentionally + +-- test the case when the referenced table is owned by a different user +create role regress_other_partitioned_fk_owner; +grant references on fk_notpartitioned_pk to regress_other_partitioned_fk_owner; +set role regress_other_partitioned_fk_owner; +create table other_partitioned_fk(a int, b int) partition by list (a); +create table other_partitioned_fk_1 partition of other_partitioned_fk + for values in (2048); +insert into other_partitioned_fk + select 2048, x from generate_series(1,10) x; +-- this should fail +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); +-- add the missing keys and retry +reset role; +insert into fk_notpartitioned_pk (a, b) + select 2048, x from generate_series(1,10) x; +set role regress_other_partitioned_fk_owner; +alter table other_partitioned_fk add foreign key (a, b) + references fk_notpartitioned_pk(a, b); +-- clean up +drop table other_partitioned_fk; +reset role; +revoke all on fk_notpartitioned_pk from regress_other_partitioned_fk_owner; +drop role regress_other_partitioned_fk_owner; + +-- Test creating a constraint at the parent that already exists in partitions. +-- There should be no duplicated constraints, and attempts to drop the +-- constraint in partitions should raise appropriate errors. +create schema fkpart0 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (1) + create table fk_part_23 partition of fk_part + (foreign key (a) references fkpart0.pkey) for values in (2, 3) + partition by list (a) + create table fk_part_23_2 partition of fk_part_23 for values in (2); + +alter table fkpart0.fk_part add foreign key (a) references fkpart0.pkey; +\d fkpart0.fk_part_1 \\ -- should have only one FK +alter table fkpart0.fk_part_1 drop constraint fk_part_1_a_fkey; + +\d fkpart0.fk_part_23 \\ -- should have only one FK +\d fkpart0.fk_part_23_2 \\ -- should have only one FK +alter table fkpart0.fk_part_23 drop constraint fk_part_23_a_fkey; +alter table fkpart0.fk_part_23_2 drop constraint fk_part_23_a_fkey; + +create table fkpart0.fk_part_4 partition of fkpart0.fk_part for values in (4); +\d fkpart0.fk_part_4 +alter table fkpart0.fk_part_4 drop constraint fk_part_a_fkey; + +create table fkpart0.fk_part_56 partition of fkpart0.fk_part + for values in (5,6) partition by list (a); +create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56 + for values in (5); +\d fkpart0.fk_part_56 +alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey; +alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey; + +-- verify that attaching and detaching partitions maintains the right set of +-- triggers +create schema fkpart1 + create table pkey (a int primary key) + create table fk_part (a int) partition by list (a) + create table fk_part_1 partition of fk_part for values in (1) partition by list (a) + create table fk_part_1_1 partition of fk_part_1 for values in (1); +alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey; +insert into fkpart1.fk_part values (1); -- should fail +insert into fkpart1.pkey values (1); +insert into fkpart1.fk_part values (1); +delete from fkpart1.pkey where a = 1; -- should fail +alter table fkpart1.fk_part detach partition fkpart1.fk_part_1; +create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2); +insert into fkpart1.fk_part_1 values (2); -- should fail +delete from fkpart1.pkey where a = 1; + +-- verify that attaching and detaching partitions manipulates the inheritance +-- properties of their FK constraints correctly +create schema fkpart2 + create table pkey (a int primary key) + create table fk_part (a int, constraint fkey foreign key (a) references fkpart2.pkey) partition by list (a) + create table fk_part_1 partition of fkpart2.fk_part for values in (1) partition by list (a) + create table fk_part_1_1 (a int, constraint my_fkey foreign key (a) references fkpart2.pkey); +alter table fkpart2.fk_part_1 attach partition fkpart2.fk_part_1_1 for values in (1); +alter table fkpart2.fk_part_1 drop constraint fkey; -- should fail +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; -- should fail +alter table fkpart2.fk_part detach partition fkpart2.fk_part_1; +alter table fkpart2.fk_part_1 drop constraint fkey; -- ok +alter table fkpart2.fk_part_1_1 drop constraint my_fkey; -- doesn't exist + +drop schema fkpart0, fkpart1, fkpart2 cascade; + +-- Test a partitioned table as referenced table. + +-- Verify basic functionality with a regular partition creation and a partition +-- with a different column layout, as well as partitions added (created and +-- attached) after creating the foreign key. +CREATE SCHEMA fkpart3; +SET search_path TO fkpart3; + +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (0) TO (1000); +CREATE TABLE pk2 (b int, a int); +ALTER TABLE pk2 DROP COLUMN b; +ALTER TABLE pk2 ALTER a SET NOT NULL; +ALTER TABLE pk ATTACH PARTITION pk2 FOR VALUES FROM (1000) TO (2000); + +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (0) TO (750); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; +CREATE TABLE fk2 (b int, a int) ; +ALTER TABLE fk2 DROP COLUMN b; +ALTER TABLE fk ATTACH PARTITION fk2 FOR VALUES FROM (750) TO (3500); + +CREATE TABLE pk3 PARTITION OF pk FOR VALUES FROM (2000) TO (3000); +CREATE TABLE pk4 (LIKE pk); +ALTER TABLE pk ATTACH PARTITION pk4 FOR VALUES FROM (3000) TO (4000); + +CREATE TABLE pk5 (c int, b int, a int NOT NULL) PARTITION BY RANGE (a); +ALTER TABLE pk5 DROP COLUMN b, DROP COLUMN c; +CREATE TABLE pk51 PARTITION OF pk5 FOR VALUES FROM (4000) TO (4500); +CREATE TABLE pk52 PARTITION OF pk5 FOR VALUES FROM (4500) TO (5000); +ALTER TABLE pk ATTACH PARTITION pk5 FOR VALUES FROM (4000) TO (5000); + +CREATE TABLE fk3 PARTITION OF fk FOR VALUES FROM (3500) TO (5000); + +-- these should fail: referenced value not present +INSERT into fk VALUES (1); +INSERT into fk VALUES (1000); +INSERT into fk VALUES (2000); +INSERT into fk VALUES (3000); +INSERT into fk VALUES (4000); +INSERT into fk VALUES (4500); +-- insert into the referenced table, now they should work +INSERT into pk VALUES (1), (1000), (2000), (3000), (4000), (4500); +INSERT into fk VALUES (1), (1000), (2000), (3000), (4000), (4500); + +-- should fail: referencing value present +DELETE FROM pk WHERE a = 1; +DELETE FROM pk WHERE a = 1000; +DELETE FROM pk WHERE a = 2000; +DELETE FROM pk WHERE a = 3000; +DELETE FROM pk WHERE a = 4000; +DELETE FROM pk WHERE a = 4500; +UPDATE pk SET a = 2 WHERE a = 1; +UPDATE pk SET a = 1002 WHERE a = 1000; +UPDATE pk SET a = 2002 WHERE a = 2000; +UPDATE pk SET a = 3002 WHERE a = 3000; +UPDATE pk SET a = 4002 WHERE a = 4000; +UPDATE pk SET a = 4502 WHERE a = 4500; +-- now they should work +DELETE FROM fk; +UPDATE pk SET a = 2 WHERE a = 1; +DELETE FROM pk WHERE a = 2; +UPDATE pk SET a = 1002 WHERE a = 1000; +DELETE FROM pk WHERE a = 1002; +UPDATE pk SET a = 2002 WHERE a = 2000; +DELETE FROM pk WHERE a = 2002; +UPDATE pk SET a = 3002 WHERE a = 3000; +DELETE FROM pk WHERE a = 3002; +UPDATE pk SET a = 4002 WHERE a = 4000; +DELETE FROM pk WHERE a = 4002; +UPDATE pk SET a = 4502 WHERE a = 4500; +DELETE FROM pk WHERE a = 4502; + +CREATE SCHEMA fkpart4; +SET search_path TO fkpart4; +-- dropping/detaching PARTITIONs is prevented if that would break +-- a foreign key's existing data +CREATE TABLE droppk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE droppk1 PARTITION OF droppk FOR VALUES FROM (0) TO (1000); +CREATE TABLE droppk_d PARTITION OF droppk DEFAULT; +CREATE TABLE droppk2 PARTITION OF droppk FOR VALUES FROM (1000) TO (2000) + PARTITION BY RANGE (a); +CREATE TABLE droppk21 PARTITION OF droppk2 FOR VALUES FROM (1000) TO (1400); +CREATE TABLE droppk2_d PARTITION OF droppk2 DEFAULT; +INSERT into droppk VALUES (1), (1000), (1500), (2000); +CREATE TABLE dropfk (a int REFERENCES droppk); +INSERT into dropfk VALUES (1), (1000), (1500), (2000); +-- these should all fail +ALTER TABLE droppk DETACH PARTITION droppk_d; +ALTER TABLE droppk2 DETACH PARTITION droppk2_d; +ALTER TABLE droppk DETACH PARTITION droppk1; +ALTER TABLE droppk DETACH PARTITION droppk2; +ALTER TABLE droppk2 DETACH PARTITION droppk21; +-- dropping partitions is disallowed +DROP TABLE droppk_d; +DROP TABLE droppk2_d; +DROP TABLE droppk1; +DROP TABLE droppk2; +DROP TABLE droppk21; +DELETE FROM dropfk; +-- dropping partitions is disallowed, even when no referencing values +DROP TABLE droppk_d; +DROP TABLE droppk2_d; +DROP TABLE droppk1; +-- but DETACH is allowed, and DROP afterwards works +ALTER TABLE droppk2 DETACH PARTITION droppk21; +DROP TABLE droppk2; + +-- Verify that initial constraint creation and cloning behave correctly +CREATE SCHEMA fkpart5; +SET search_path TO fkpart5; +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY LIST (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES IN (1) PARTITION BY LIST (a); +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES IN (1); +CREATE TABLE fk (a int) PARTITION BY LIST (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES IN (1) PARTITION BY LIST (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES IN (1); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk; +CREATE TABLE pk2 PARTITION OF pk FOR VALUES IN (2); +CREATE TABLE pk3 (a int NOT NULL) PARTITION BY LIST (a); +CREATE TABLE pk31 PARTITION OF pk3 FOR VALUES IN (31); +CREATE TABLE pk32 (b int, a int NOT NULL); +ALTER TABLE pk32 DROP COLUMN b; +ALTER TABLE pk3 ATTACH PARTITION pk32 FOR VALUES IN (32); +ALTER TABLE pk ATTACH PARTITION pk3 FOR VALUES IN (31, 32); +CREATE TABLE fk2 PARTITION OF fk FOR VALUES IN (2); +CREATE TABLE fk3 (b int, a int); +ALTER TABLE fk3 DROP COLUMN b; +ALTER TABLE fk ATTACH PARTITION fk3 FOR VALUES IN (3); +SELECT pg_describe_object('pg_constraint'::regclass, oid, 0), confrelid::regclass, + CASE WHEN conparentid <> 0 THEN pg_describe_object('pg_constraint'::regclass, conparentid, 0) ELSE 'TOP' END +FROM pg_catalog.pg_constraint +WHERE conrelid IN (SELECT relid FROM pg_partition_tree('fk')) +ORDER BY conrelid::regclass::text, conname; +CREATE TABLE fk4 (LIKE fk); +INSERT INTO fk4 VALUES (50); +ALTER TABLE fk ATTACH PARTITION fk4 FOR VALUES IN (50); + +-- Verify ON UPDATE/DELETE behavior +CREATE SCHEMA fkpart6; +SET search_path TO fkpart6; +CREATE TABLE pk (a int PRIMARY KEY) PARTITION BY RANGE (a); +CREATE TABLE pk1 PARTITION OF pk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE pk11 PARTITION OF pk1 FOR VALUES FROM (1) TO (50); +CREATE TABLE pk12 PARTITION OF pk1 FOR VALUES FROM (50) TO (100); +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE CASCADE ON DELETE CASCADE; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO pk VALUES (1); +INSERT INTO fk VALUES (1); +UPDATE pk SET a = 20; +SELECT tableoid::regclass, * FROM fk; +DELETE FROM pk WHERE a = 20; +SELECT tableoid::regclass, * FROM fk; +DROP TABLE fk; + +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (50); +CREATE TABLE fk (a int) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET NULL ON DELETE SET NULL; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (20), (50); +UPDATE pk SET a = 21 WHERE a = 20; +DELETE FROM pk WHERE a = 50; +SELECT tableoid::regclass, * FROM fk; +DROP TABLE fk; + +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (30), (50); +CREATE TABLE fk (id int, a int DEFAULT 50) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE SET DEFAULT ON DELETE SET DEFAULT; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (1, 20), (2, 30); +DELETE FROM pk WHERE a = 20 RETURNING *; +UPDATE pk SET a = 90 WHERE a = 30 RETURNING *; +SELECT tableoid::regclass, * FROM fk; +DROP TABLE fk; + +TRUNCATE TABLE pk; +INSERT INTO pk VALUES (20), (30); +CREATE TABLE fk (a int DEFAULT 50) PARTITION BY RANGE (a); +CREATE TABLE fk1 PARTITION OF fk FOR VALUES FROM (1) TO (100) PARTITION BY RANGE (a); +CREATE TABLE fk11 PARTITION OF fk1 FOR VALUES FROM (1) TO (10); +CREATE TABLE fk12 PARTITION OF fk1 FOR VALUES FROM (10) TO (100); +ALTER TABLE fk ADD FOREIGN KEY (a) REFERENCES pk ON UPDATE RESTRICT ON DELETE RESTRICT; +CREATE TABLE fk_d PARTITION OF fk DEFAULT; +INSERT INTO fk VALUES (20), (30); +DELETE FROM pk WHERE a = 20; +UPDATE pk SET a = 90 WHERE a = 30; +SELECT tableoid::regclass, * FROM fk; +DROP TABLE fk; + +-- test for reported bug: relispartition not set +-- https://postgr.es/m/CA+HiwqHMsRtRYRWYTWavKJ8x14AFsv7bmAV46mYwnfD3vy8goQ@mail.gmail.com +CREATE SCHEMA fkpart7 + CREATE TABLE pkpart (a int) PARTITION BY LIST (a) + CREATE TABLE pkpart1 PARTITION OF pkpart FOR VALUES IN (1); +ALTER TABLE fkpart7.pkpart1 ADD PRIMARY KEY (a); +ALTER TABLE fkpart7.pkpart ADD PRIMARY KEY (a); +CREATE TABLE fkpart7.fk (a int REFERENCES fkpart7.pkpart); +DROP SCHEMA fkpart7 CASCADE; + +-- ensure we check partitions are "not used" when dropping constraints +CREATE SCHEMA fkpart8 + CREATE TABLE tbl1(f1 int PRIMARY KEY) + CREATE TABLE tbl2(f1 int REFERENCES tbl1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE(f1) + CREATE TABLE tbl2_p1 PARTITION OF tbl2 FOR VALUES FROM (minvalue) TO (maxvalue); +INSERT INTO fkpart8.tbl1 VALUES(1); +BEGIN; +INSERT INTO fkpart8.tbl2 VALUES(1); +ALTER TABLE fkpart8.tbl2 DROP CONSTRAINT tbl2_f1_fkey; +COMMIT; +DROP SCHEMA fkpart8 CASCADE; diff --git a/src/test/regress/sql/func_index.sql b/src/test/regress/sql/func_index.sql deleted file mode 100644 index 86f8c71179c..00000000000 --- a/src/test/regress/sql/func_index.sql +++ /dev/null @@ -1,33 +0,0 @@ -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=false); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -rollback; - -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')) with (recheck_on_update=true); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -rollback; - -begin; -create table keyvalue(id integer primary key, info jsonb); -create index nameindex on keyvalue((info->>'name')); -insert into keyvalue values (1, '{"name": "john", "data": "some data"}'); -update keyvalue set info='{"name": "john", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -update keyvalue set info='{"name": "smith", "data": "some other data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -update keyvalue set info='{"name": "smith", "data": "some more data"}' where id=1; -select pg_stat_get_xact_tuples_hot_updated('keyvalue'::regclass); -rollback; - - diff --git a/src/test/regress/sql/generated.sql b/src/test/regress/sql/generated.sql new file mode 100644 index 00000000000..6a56ae260f6 --- /dev/null +++ b/src/test/regress/sql/generated.sql @@ -0,0 +1,460 @@ +-- sanity check of system catalog +SELECT attrelid, attname, attgenerated FROM pg_attribute WHERE attgenerated NOT IN ('', 's'); + + +CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED); +CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); + +SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2; + +SELECT table_name, column_name, dependent_column FROM information_schema.column_column_usage ORDER BY 1, 2, 3; + +\d gtest1 + +-- duplicate generated +CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED); + +-- references to other generated columns, including self-references +CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED); +CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED); + +-- invalid reference +CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED); + +-- generation expression must be immutable +CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED); + +-- cannot have default/identity and generated +CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED); +CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED); + +-- reference to system column not allowed in generated column +CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED); + +-- various prohibited constructs +CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED); +CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED); +CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED); +CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED); + +-- GENERATED BY DEFAULT not allowed +CREATE TABLE gtest_err_8 (a int PRIMARY KEY, b int GENERATED BY DEFAULT AS (a * 2) STORED); + +INSERT INTO gtest1 VALUES (1); +INSERT INTO gtest1 VALUES (2, DEFAULT); +INSERT INTO gtest1 VALUES (3, 33); -- error + +SELECT * FROM gtest1 ORDER BY a; + +UPDATE gtest1 SET b = DEFAULT WHERE a = 1; +UPDATE gtest1 SET b = 11 WHERE a = 1; -- error + +SELECT * FROM gtest1 ORDER BY a; + +SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a; +SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a; + +-- test that overflow error happens on write +INSERT INTO gtest1 VALUES (2000000000); +SELECT * FROM gtest1; +DELETE FROM gtest1 WHERE a = 2000000000; + +-- test with joins +CREATE TABLE gtestx (x int, y int); +INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3); +SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a; +DROP TABLE gtestx; + +-- test UPDATE/DELETE quals +SELECT * FROM gtest1 ORDER BY a; +UPDATE gtest1 SET a = 3 WHERE b = 4; +SELECT * FROM gtest1 ORDER BY a; +DELETE FROM gtest1 WHERE b = 2; +SELECT * FROM gtest1 ORDER BY a; + +-- views +CREATE VIEW gtest1v AS SELECT * FROM gtest1; +SELECT * FROM gtest1v; +INSERT INTO gtest1v VALUES (4, 8); -- fails +DROP VIEW gtest1v; + +-- CTEs +WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo; + +-- inheritance +CREATE TABLE gtest1_1 () INHERITS (gtest1); +SELECT * FROM gtest1_1; +\d gtest1_1 +INSERT INTO gtest1_1 VALUES (4); +SELECT * FROM gtest1_1; +SELECT * FROM gtest1; + +-- test inheritance mismatch +CREATE TABLE gtesty (x int, b int); +CREATE TABLE gtest1_2 () INHERITS (gtest1, gtesty); -- error +DROP TABLE gtesty; + +-- test stored update +CREATE TABLE gtest3 (a int, b int GENERATED ALWAYS AS (a * 3) STORED); +INSERT INTO gtest3 (a) VALUES (1), (2), (3), (NULL); +SELECT * FROM gtest3 ORDER BY a; +UPDATE gtest3 SET a = 22 WHERE a = 2; +SELECT * FROM gtest3 ORDER BY a; + +CREATE TABLE gtest3a (a text, b text GENERATED ALWAYS AS (a || '+' || a) STORED); +INSERT INTO gtest3a (a) VALUES ('a'), ('b'), ('c'), (NULL); +SELECT * FROM gtest3a ORDER BY a; +UPDATE gtest3a SET a = 'bb' WHERE a = 'b'; +SELECT * FROM gtest3a ORDER BY a; + +-- COPY +TRUNCATE gtest1; +INSERT INTO gtest1 (a) VALUES (1), (2); + +COPY gtest1 TO stdout; + +COPY gtest1 (a, b) TO stdout; + +COPY gtest1 FROM stdin; +3 +4 +\. + +COPY gtest1 (a, b) FROM stdin; + +SELECT * FROM gtest1 ORDER BY a; + +TRUNCATE gtest3; +INSERT INTO gtest3 (a) VALUES (1), (2); + +COPY gtest3 TO stdout; + +COPY gtest3 (a, b) TO stdout; + +COPY gtest3 FROM stdin; +3 +4 +\. + +COPY gtest3 (a, b) FROM stdin; + +SELECT * FROM gtest3 ORDER BY a; + +-- null values +CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED); +INSERT INTO gtest2 VALUES (1); +SELECT * FROM gtest2; + +-- composite types +CREATE TYPE double_int as (a int, b int); +CREATE TABLE gtest4 ( + a int, + b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED +); +INSERT INTO gtest4 VALUES (1), (6); +SELECT * FROM gtest4; + +DROP TABLE gtest4; +DROP TYPE double_int; + +-- using tableoid is allowed +CREATE TABLE gtest_tableoid ( + a int PRIMARY KEY, + b bool GENERATED ALWAYS AS (tableoid <> 0) STORED +); +INSERT INTO gtest_tableoid VALUES (1), (2); +SELECT * FROM gtest_tableoid; + +-- drop column behavior +CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); +ALTER TABLE gtest10 DROP COLUMN b; + +\d gtest10 + +CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +ALTER TABLE gtest10a DROP COLUMN b; +INSERT INTO gtest10a (a) VALUES (1); + +-- privileges +CREATE USER regress_user11; + +CREATE TABLE gtest11s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED); +INSERT INTO gtest11s VALUES (1, 10), (2, 20); +GRANT SELECT (a, c) ON gtest11s TO regress_user11; + +CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL; +REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC; + +CREATE TABLE gtest12s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED); +INSERT INTO gtest12s VALUES (1, 10), (2, 20); +GRANT SELECT (a, c) ON gtest12s TO regress_user11; + +SET ROLE regress_user11; +SELECT a, b FROM gtest11s; -- not allowed +SELECT a, c FROM gtest11s; -- allowed +SELECT gf1(10); -- not allowed +SELECT a, c FROM gtest12s; -- allowed +RESET ROLE; + +DROP TABLE gtest11s, gtest12s; +DROP FUNCTION gf1(int); +DROP USER regress_user11; + +-- check constraints +CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50)); +INSERT INTO gtest20 (a) VALUES (10); -- ok +INSERT INTO gtest20 (a) VALUES (30); -- violates constraint + +CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20a (a) VALUES (10); +INSERT INTO gtest20a (a) VALUES (30); +ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row + +CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest20b (a) VALUES (10); +INSERT INTO gtest20b (a) VALUES (30); +ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID; +ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row + +-- not-null constraints +CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL); +INSERT INTO gtest21a (a) VALUES (1); -- ok +INSERT INTO gtest21a (a) VALUES (0); -- violates constraint + +CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED); +ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL; +INSERT INTO gtest21b (a) VALUES (1); -- ok +INSERT INTO gtest21b (a) VALUES (0); -- violates constraint +ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL; +INSERT INTO gtest21b (a) VALUES (0); -- ok now + +-- index constraints +CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE); +INSERT INTO gtest22a VALUES (2); +INSERT INTO gtest22a VALUES (3); +INSERT INTO gtest22a VALUES (4); +CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b)); +INSERT INTO gtest22b VALUES (2); +INSERT INTO gtest22b VALUES (2); + +-- indexes +CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED); +CREATE INDEX gtest22c_b_idx ON gtest22c (b); +CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3)); +CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0; +\d gtest22c + +INSERT INTO gtest22c VALUES (1), (2), (3); +SET enable_seqscan TO off; +SET enable_bitmapscan TO off; +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 4; +SELECT * FROM gtest22c WHERE b = 4; +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 6; +SELECT * FROM gtest22c WHERE b * 3 = 6; +EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0; +SELECT * FROM gtest22c WHERE a = 1 AND b > 0; +RESET enable_seqscan; +RESET enable_bitmapscan; + +-- foreign keys +CREATE TABLE gtest23a (x int PRIMARY KEY, y int); +INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33); + +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); -- error +CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); -- error + +CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x)); +\d gtest23b + +INSERT INTO gtest23b VALUES (1); -- ok +INSERT INTO gtest23b VALUES (5); -- error + +DROP TABLE gtest23b; +DROP TABLE gtest23a; + +CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y)); +INSERT INTO gtest23p VALUES (1), (2), (3); + +CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y)); +INSERT INTO gtest23q VALUES (1, 2); -- ok +INSERT INTO gtest23q VALUES (2, 5); -- error + +-- domains +CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10); +CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED); +INSERT INTO gtest24 (a) VALUES (4); -- ok +INSERT INTO gtest24 (a) VALUES (6); -- error + +-- typed tables (currently not supported) +CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint); +CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED); +DROP TYPE gtest_type CASCADE; + +-- table partitions (currently not supported) +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 text, f3 bigint) PARTITION BY RANGE (f1); +CREATE TABLE gtest_child PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 2) STORED +) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error +DROP TABLE gtest_parent; + +-- partitioned table +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1); +CREATE TABLE gtest_child PARTITION OF gtest_parent FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); +INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1); +SELECT * FROM gtest_parent; +SELECT * FROM gtest_child; +DROP TABLE gtest_parent; + +-- generated columns in partition key (not allowed) +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3); +CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE ((f3 * 3)); + +-- ALTER TABLE ... ADD COLUMN +CREATE TABLE gtest25 (a int PRIMARY KEY); +INSERT INTO gtest25 VALUES (3), (4); +ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 3) STORED; +SELECT * FROM gtest25 ORDER BY a; +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error +ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error + +-- ALTER TABLE ... ALTER COLUMN +CREATE TABLE gtest27 ( + a int, + b int GENERATED ALWAYS AS (a * 2) STORED +); +INSERT INTO gtest27 (a) VALUES (3), (4); +ALTER TABLE gtest27 ALTER COLUMN a TYPE text; -- error +ALTER TABLE gtest27 ALTER COLUMN b TYPE numeric; +\d gtest27 +SELECT * FROM gtest27; +ALTER TABLE gtest27 ALTER COLUMN b TYPE boolean USING b <> 0; -- error + +ALTER TABLE gtest27 ALTER COLUMN b DROP DEFAULT; -- error +\d gtest27 + +-- triggers +CREATE TABLE gtest26 ( + a int PRIMARY KEY, + b int GENERATED ALWAYS AS (a * 2) STORED +); + +CREATE FUNCTION gtest_trigger_func() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + IF tg_op IN ('DELETE', 'UPDATE') THEN + RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD; + END IF; + IF tg_op IN ('INSERT', 'UPDATE') THEN + RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW; + END IF; + IF tg_op = 'DELETE' THEN + RETURN OLD; + ELSE + RETURN NEW; + END IF; +END +$$; + +CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.* IS NOT NULL) -- error + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26 + FOR EACH ROW + WHEN (NEW.a < 0) + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (OLD.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26 + FOR EACH ROW + WHEN (NEW.b < 0) -- ok + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (-2), (0), (3); +SELECT * FROM gtest26 ORDER BY a; +UPDATE gtest26 SET a = a * -2; +SELECT * FROM gtest26 ORDER BY a; +DELETE FROM gtest26 WHERE a = -6; +SELECT * FROM gtest26 ORDER BY a; + +DROP TRIGGER gtest1 ON gtest26; +DROP TRIGGER gtest2 ON gtest26; +DROP TRIGGER gtest3 ON gtest26; + +-- Check that an UPDATE of "a" fires the trigger for UPDATE OF b, per +-- SQL standard. +CREATE FUNCTION gtest_trigger_func3() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + RAISE NOTICE 'OK'; + RETURN NEW; +END +$$; + +CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func3(); + +UPDATE gtest26 SET a = 1 WHERE a = 0; + +DROP TRIGGER gtest11 ON gtest26; +TRUNCATE gtest26; + +-- check that modifications of stored generated columns in triggers do +-- not get propagated +CREATE FUNCTION gtest_trigger_func4() RETURNS trigger + LANGUAGE plpgsql +AS $$ +BEGIN + NEW.a = 10; + NEW.b = 300; + RETURN NEW; +END; +$$; + +CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func4(); + +CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26 + FOR EACH ROW + EXECUTE PROCEDURE gtest_trigger_func(); + +INSERT INTO gtest26 (a) VALUES (1); +UPDATE gtest26 SET a = 11 WHERE a = 1; +SELECT * FROM gtest26 ORDER BY a; + +-- LIKE INCLUDING GENERATED and dropped column handling +CREATE TABLE gtest28a ( + a int, + b int, + c int, + x int GENERATED ALWAYS AS (b * 2) STORED +); + +ALTER TABLE gtest28a DROP COLUMN a; + +CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED); + +\d gtest28* diff --git a/src/test/regress/sql/geometry.sql b/src/test/regress/sql/geometry.sql index 1429ee772a3..939e3079df0 100644 --- a/src/test/regress/sql/geometry.sql +++ b/src/test/regress/sql/geometry.sql @@ -46,6 +46,104 @@ SELECT '' AS one, p1.f1 FROM POINT_TBL p1 WHERE p1.f1 ?| point '(5.1,34.5)'; +-- Slope +SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; + +-- Add point +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + +-- Subtract point +SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; + +-- Multiply with point +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000; + +-- Underflow error +SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1; + +-- Divide by point +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] BETWEEN 1 AND 1000; + +-- Overflow error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000; + +-- Division by 0 error +SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1 ~= '(0,0)'::point; + +-- Distance to line +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l; + +-- Distance to line segment +SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l; + +-- Distance to box +SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b; + +-- Distance to path +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1; + +-- Distance to polygon +SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1; + +-- Closest point to line +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; + +-- Closest point to line segment +SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; + +-- Closest point to box +SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; + +-- On line +SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s; + +-- On line segment +SELECT p.f1, l.s FROM POINT_TBL p, LSEG_TBL l WHERE p.f1 <@ l.s; + +-- On path +SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1; + +-- +-- Lines +-- + +-- Vertical +SELECT s FROM LINE_TBL WHERE ?| s; + +-- Horizontal +SELECT s FROM LINE_TBL WHERE ?- s; + +-- Same as line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s = l2.s; + +-- Parallel to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?|| l2.s; + +-- Perpendicular to line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?-| l2.s; + +-- Distance to line +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2; + +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 FROM LINE_TBL l, BOX_TBL b; +SELECT l.s, b.f1, b.f1 <-> l.s FROM LINE_TBL l, BOX_TBL b; + +-- Intersect with line +SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s; + +-- Intersect with box +SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + +-- Intersection point with line +SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2; + +-- Closest point to line segment +SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1; + +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LINE_TBL l, BOX_TBL b; + -- -- Line segments -- @@ -54,9 +152,77 @@ SELECT '' AS one, p1.f1 SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection FROM LSEG_TBL l, POINT_TBL p; --- closest point -SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest - FROM LSEG_TBL l, POINT_TBL p; +-- Length +SELECT s, @-@ s FROM LSEG_TBL; + +-- Vertical +SELECT s FROM LSEG_TBL WHERE ?| s; + +-- Horizontal +SELECT s FROM LSEG_TBL WHERE ?- s; + +-- Center +SELECT s, @@ s FROM LSEG_TBL; + +-- To point +SELECT s, s::point FROM LSEG_TBL; + +-- Has points less than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s < l2.s; + +-- Has points less than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s <= l2.s; + +-- Has points equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s = l2.s; + +-- Has points greater than or equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s >= l2.s; + +-- Has points greater than line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s > l2.s; + +-- Has points not equal to line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s != l2.s; + +-- Parallel with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?|| l2.s; + +-- Perpendicular with line segment +SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s; + +-- Distance to line +SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1; + +-- Distance to line segment +SELECT l1.s, l2.s, l1.s <-> l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +-- Distance to box +SELECT l.s, b.f1, l.s <-> b.f1 AS dist_sb, b.f1 <-> l.s AS dist_bs FROM LSEG_TBL l, BOX_TBL b; + +-- Intersect with line segment +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s ?# l1.s; + +-- Intersect with box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s ?# b.f1; + +-- Intersection point with line segment +SELECT l1.s, l2.s, l1.s # l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +-- Closest point to line +SELECT l.s, l1.s, l.s ## l1.s FROM LSEG_TBL l, LINE_TBL l1; + +-- Closest point to line segment +SELECT l1.s, l2.s, l1.s ## l2.s FROM LSEG_TBL l1, LSEG_TBL l2; + +-- Closest point to box +SELECT l.s, b.f1, l.s ## b.f1 FROM LSEG_TBL l, BOX_TBL b; + +-- On line +SELECT l.s, l1.s FROM LSEG_TBL l, LINE_TBL l1 WHERE l.s <@ l1.s; + +-- On box +SELECT l.s, b.f1 FROM LSEG_TBL l, BOX_TBL b WHERE l.s <@ b.f1; -- -- Boxes @@ -71,35 +237,94 @@ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation SELECT '' AS twentyfour, b.f1 - p.f1 AS translation FROM BOX_TBL b, POINT_TBL p; --- scaling and rotation -SELECT '' AS twentyfour, b.f1 * p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p; +-- Multiply with point +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + +-- Overflow error +SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000; -SELECT '' AS twenty, b.f1 / p.f1 AS rotation - FROM BOX_TBL b, POINT_TBL p - WHERE (p.f1 <-> point '(0,0)') >= 1; +-- Divide by point +SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; +-- To box SELECT f1::box FROM POINT_TBL; SELECT bound_box(a.f1, b.f1) FROM BOX_TBL a, BOX_TBL b; +-- Below box +SELECT b1.f1, b2.f1, b1.f1 <^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +-- Above box +SELECT b1.f1, b2.f1, b1.f1 >^ b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +-- Intersection point with box +SELECT b1.f1, b2.f1, b1.f1 # b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + +-- Diagonal +SELECT f1, diagonal(f1) FROM BOX_TBL; + +-- Distance to box +SELECT b1.f1, b2.f1, b1.f1 <-> b2.f1 FROM BOX_TBL b1, BOX_TBL b2; + -- -- Paths -- -SELECT '' AS eight, npoints(f1) AS npoints, f1 AS path FROM PATH_TBL; +-- Points +SELECT f1, npoints(f1) FROM PATH_TBL; + +-- Area +SELECT f1, area(f1) FROM PATH_TBL; -SELECT '' AS four, path(f1) FROM POLYGON_TBL; +-- Length +SELECT f1, @-@ f1 FROM PATH_TBL; --- translation -SELECT '' AS eight, p1.f1 + point '(10,10)' AS dist_add - FROM PATH_TBL p1; +-- Center +SELECT f1, @@ f1 FROM PATH_TBL; + +-- To polygon +SELECT f1, f1::polygon FROM PATH_TBL WHERE isclosed(f1); + +-- Open path cannot be converted to polygon error +SELECT f1, f1::polygon FROM PATH_TBL WHERE isopen(f1); + +-- Has points less than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 < p2.f1; + +-- Has points less than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 <= p2.f1; + +-- Has points equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 = p2.f1; + +-- Has points greater than or equal to path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 >= p2.f1; + +-- Has points greater than path +SELECT p1.f1, p2.f1 FROM PATH_TBL p1, PATH_TBL p2 WHERE p1.f1 > p2.f1; + +-- Add path +SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM PATH_TBL p1, PATH_TBL p2; + +-- Add point +SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +-- Subtract point +SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +-- Multiply with point +SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; + +-- Divide by point +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000; --- scaling and rotation -SELECT '' AS eight, p1.f1 * point '(2,-1)' AS dist_mul - FROM PATH_TBL p1; +-- Division by 0 error +SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1 ~= '(0,0)'::point; + +-- Distance to path +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM PATH_TBL p1, PATH_TBL p2; -- -- Polygons @@ -125,13 +350,50 @@ SELECT '' AS four, f1 AS open_path, polygon( pclose(f1)) AS polygon FROM PATH_TBL WHERE isopen(f1); --- convert circles to polygons using the default number of points -SELECT '' AS six, polygon(f1) - FROM CIRCLE_TBL; +-- To box +SELECT f1, f1::box FROM POLYGON_TBL; --- convert the circle to an 8-point polygon -SELECT '' AS six, polygon(8, f1) - FROM CIRCLE_TBL; +-- To path +SELECT f1, f1::path FROM POLYGON_TBL; + +-- Same as polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 ~= p2.f1; + +-- Contained by polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <@ p2.f1; + +-- Contains polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 @> p2.f1; + +-- Overlap with polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 && p2.f1; + +-- Left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 << p2.f1; + +-- Overlap of left of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &< p2.f1; + +-- Right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 >> p2.f1; + +-- Overlap of right of polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &> p2.f1; + +-- Below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 <<| p2.f1; + +-- Overlap or below polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 &<| p2.f1; + +-- Above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |>> p2.f1; + +-- Overlap or above polygon +SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1; + +-- Distance to polygon +SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2; -- -- Circles @@ -151,3 +413,96 @@ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS d FROM CIRCLE_TBL c1, POINT_TBL p1 WHERE (p1.f1 <-> c1.f1) > 0 ORDER BY distance, area(c1.f1), p1.f1[0]; + +-- To polygon +SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +-- To polygon with less points +SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +-- Too less points error +SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; + +-- Zero radius error +SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>'; + +-- Same as circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1; + +-- Overlap with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1; + +-- Overlap or left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1; + +-- Left of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1; + +-- Right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1; + +-- Overlap or right of circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1; + +-- Contained by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1; + +-- Contain by circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1; + +-- Below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1; + +-- Above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1; + +-- Overlap or below circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1; + +-- Overlap or above circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1; + +-- Area equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1; + +-- Area not equal with circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1; + +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1; + +-- Area less than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1; + +-- Area greater than or equal circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1; + +-- Area less than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +-- Area greater than circle +SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; + +-- Add point +SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +-- Subtract point +SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +-- Multiply with point +SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; + +-- Divide by point +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; + +-- Overflow error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000; + +-- Division by 0 error +SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0,0)'::point; + +-- Distance to polygon +SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p; diff --git a/src/test/regress/sql/gist.sql b/src/test/regress/sql/gist.sql index bae722fe13c..b9d398ea941 100644 --- a/src/test/regress/sql/gist.sql +++ b/src/test/regress/sql/gist.sql @@ -28,10 +28,8 @@ select g+100000, point(g*10+1, g*10+1) from generate_series(1, 10000) g; -- To test vacuum, delete some entries from all over the index. delete from gist_point_tbl where id % 2 = 1; --- And also delete some concentration of values. (GiST doesn't currently --- attempt to delete pages even when they become empty, but if it did, this --- would exercise it) -delete from gist_point_tbl where id < 10000; +-- And also delete some concentration of values. +delete from gist_point_tbl where id > 5000; vacuum analyze gist_point_tbl; @@ -111,6 +109,22 @@ select b from gist_tbl where b <@ box(point(5,5), point(6,6)); -- execute the same select b from gist_tbl where b <@ box(point(5,5), point(6,6)); +-- Also test an index-only knn-search +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by b <-> point(5.2, 5.91); + +-- Check commuted case as well +explain (costs off) +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + +select b from gist_tbl where b <@ box(point(5,5), point(6,6)) +order by point(5.2, 5.91) <-> b; + drop index gist_tbl_box_index; -- Test that an index-only scan is not chosen, when the query involves the diff --git a/src/test/regress/sql/groupingsets.sql b/src/test/regress/sql/groupingsets.sql index c32d23b8d72..95ac3fb52f6 100644 --- a/src/test/regress/sql/groupingsets.sql +++ b/src/test/regress/sql/groupingsets.sql @@ -213,6 +213,9 @@ select a, b, sum(v.x) from (values (1),(2)) v(x), gstest_data(v.x) group by cube (a,b) order by a,b; +-- Test reordering of grouping sets +explain (costs off) +select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a; -- Agg level check. This query should error out. select (select grouping(a,b) from gstest2) from gstest2 group by a,b; @@ -381,6 +384,18 @@ explain (costs off) from (values (1),(2)) v(x), gstest_data(v.x) group by cube (a,b) order by a,b; +-- Verify that we correctly handle the child node returning a +-- non-minimal slot, which happens if the input is pre-sorted, +-- e.g. due to an index scan. +BEGIN; +SET LOCAL enable_hashagg = false; +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; +SET LOCAL enable_seqscan = false; +EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; +SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; +COMMIT; + -- More rescan tests select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); @@ -415,4 +430,15 @@ explain (costs off) count(*) from tenk1 group by grouping sets (unique1,twothousand,thousand,hundred,ten,four,two); +-- check collation-sensitive matching between grouping expressions +-- (similar to a check for aggregates, but there are additional code +-- paths for GROUPING, so check again here) + +select v||'a', case grouping(v||'a') when 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; +select v||'a', case when grouping(v||'a') = 1 then 1 else 0 end, count(*) + from unnest(array[1,1], array['a','b']) u(i,v) + group by rollup(i, v||'a') order by 1,3; + -- end diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql index 23e50297800..43dbba3775e 100644 --- a/src/test/regress/sql/guc.sql +++ b/src/test/regress/sql/guc.sql @@ -47,7 +47,7 @@ SET datestyle = 'MDY'; SHOW datestyle; SELECT '2006-08-13 12:34:56'::timestamptz; SAVEPOINT first_sp; -SET vacuum_cost_delay TO 80; +SET vacuum_cost_delay TO 80.1; SHOW vacuum_cost_delay; SET datestyle = 'German, DMY'; SHOW datestyle; @@ -56,7 +56,7 @@ ROLLBACK TO first_sp; SHOW datestyle; SELECT '2006-08-13 12:34:56'::timestamptz; SAVEPOINT second_sp; -SET vacuum_cost_delay TO 90; +SET vacuum_cost_delay TO '900us'; SET datestyle = 'SQL, YMD'; SHOW datestyle; SELECT '2006-08-13 12:34:56'::timestamptz; @@ -144,6 +144,10 @@ RESET datestyle; SHOW datestyle; SELECT '2006-08-13 12:34:56'::timestamptz; +-- Test some simple error cases +SET seq_page_cost TO 'NaN'; +SET vacuum_cost_delay TO '10s'; + -- -- Test DISCARD TEMP -- @@ -288,3 +292,7 @@ set default_text_search_config = no_such_config; select func_with_bad_set(); reset check_function_bodies; + +set default_with_oids to f; +-- Should not allow to set it to true. +set default_with_oids to t; diff --git a/src/test/regress/sql/hash_part.sql b/src/test/regress/sql/hash_part.sql index 94c5eaab0cd..30601b913e0 100644 --- a/src/test/regress/sql/hash_part.sql +++ b/src/test/regress/sql/hash_part.sql @@ -2,18 +2,12 @@ -- Hash partitioning. -- -CREATE OR REPLACE FUNCTION hashint4_noop(int4, int8) RETURNS int8 AS -$$SELECT coalesce($1,0)::int8$$ LANGUAGE sql IMMUTABLE; -CREATE OPERATOR CLASS test_int4_ops FOR TYPE int4 USING HASH AS -OPERATOR 1 = , FUNCTION 2 hashint4_noop(int4, int8); - -CREATE OR REPLACE FUNCTION hashtext_length(text, int8) RETURNS int8 AS -$$SELECT length(coalesce($1,''))::int8$$ LANGUAGE sql IMMUTABLE; -CREATE OPERATOR CLASS test_text_ops FOR TYPE text USING HASH AS -OPERATOR 1 = , FUNCTION 2 hashtext_length(text, int8); +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. See the definitions of +-- part_part_test_int4_ops and part_test_text_ops in insert.sql. CREATE TABLE mchash (a int, b text, c jsonb) - PARTITION BY HASH (a test_int4_ops, b test_text_ops); + PARTITION BY HASH (a part_test_int4_ops, b part_test_text_ops); CREATE TABLE mchash1 PARTITION OF mchash FOR VALUES WITH (MODULUS 4, REMAINDER 0); @@ -54,7 +48,7 @@ SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, NULL::int, NULL::int); SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 0, ''::text); -- ok, should be true -SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 1, ''::text); +SELECT satisfies_hash_partition('mchash'::regclass, 4, 0, 2, ''::text); -- argument via variadic syntax, should fail because not all partitioning -- columns are of the correct type @@ -63,7 +57,7 @@ SELECT satisfies_hash_partition('mchash'::regclass, 2, 1, -- multiple partitioning columns of the same type CREATE TABLE mcinthash (a int, b int, c jsonb) - PARTITION BY HASH (a test_int4_ops, b test_int4_ops); + PARTITION BY HASH (a part_test_int4_ops, b part_test_int4_ops); -- now variadic should work, should be false SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, @@ -71,7 +65,7 @@ SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, -- should be true SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, - variadic array[1, 0]); + variadic array[0, 1]); -- wrong length SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, @@ -81,10 +75,16 @@ SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, SELECT satisfies_hash_partition('mcinthash'::regclass, 4, 0, variadic array[now(), now()]); +-- check satisfies_hash_partition passes correct collation +create table text_hashp (a text) partition by hash (a); +create table text_hashp0 partition of text_hashp for values with (modulus 2, remainder 0); +create table text_hashp1 partition of text_hashp for values with (modulus 2, remainder 1); +-- The result here should always be true, because 'xxx' must belong to +-- one of the two defined partitions +select satisfies_hash_partition('text_hashp'::regclass, 2, 0, 'xxx'::text) OR + satisfies_hash_partition('text_hashp'::regclass, 2, 1, 'xxx'::text) AS satisfies; + -- cleanup DROP TABLE mchash; DROP TABLE mcinthash; -DROP OPERATOR CLASS test_text_ops USING hash; -DROP OPERATOR CLASS test_int4_ops USING hash; -DROP FUNCTION hashint4_noop(int4, int8); -DROP FUNCTION hashtext_length(text, int8); +DROP TABLE text_hashp; diff --git a/src/test/regress/sql/horology.sql b/src/test/regress/sql/horology.sql index ebb196a1cfc..f7a9da1e954 100644 --- a/src/test/regress/sql/horology.sql +++ b/src/test/regress/sql/horology.sql @@ -267,35 +267,6 @@ SELECT '' AS "226", d1.f1 AS timestamp1, d2.f1 AS timestamp2, d1.f1 - d2.f1 AS d FROM TEMP_TIMESTAMP d1, TEMP_TIMESTAMP d2 ORDER BY timestamp1, timestamp2, difference; --- --- abstime, reltime arithmetic --- - -SELECT '' AS ten, ABSTIME_TBL.f1 AS abstime, RELTIME_TBL.f1 AS reltime - FROM ABSTIME_TBL, RELTIME_TBL - WHERE (ABSTIME_TBL.f1 + RELTIME_TBL.f1) < abstime 'Jan 14 14:00:00 1971' - ORDER BY abstime, reltime; - --- these four queries should return the same answer --- the "infinity" and "-infinity" tuples in ABSTIME_TBL cannot be added and --- therefore, should not show up in the results. - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 + reltime '@ 3 year') -- +3 years - < abstime 'Jan 14 14:00:00 1977'; - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 + reltime '@ 3 year ago') -- -3 years - < abstime 'Jan 14 14:00:00 1971'; - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 - reltime '@ 3 year') -- -(+3) years - < abstime 'Jan 14 14:00:00 1971'; - -SELECT '' AS three, * FROM ABSTIME_TBL - WHERE (ABSTIME_TBL.f1 - reltime '@ 3 year ago') -- -(-3) years - < abstime 'Jan 14 14:00:00 1977'; - -- -- Conversions -- @@ -305,27 +276,6 @@ SELECT '' AS "16", f1 AS "timestamp", date(f1) AS date WHERE f1 <> timestamp 'now' ORDER BY date, "timestamp"; -SELECT '' AS "16", f1 AS "timestamp", abstime(f1) AS abstime - FROM TEMP_TIMESTAMP - ORDER BY abstime; - -SELECT '' AS four, f1 AS abstime, date(f1) AS date - FROM ABSTIME_TBL - WHERE isfinite(f1) AND f1 <> abstime 'now' - ORDER BY date, abstime; - -SELECT '' AS two, d1 AS "timestamp", abstime(d1) AS abstime - FROM TIMESTAMP_TBL WHERE NOT isfinite(d1); - -SELECT '' AS three, f1 as abstime, cast(f1 as timestamp) AS "timestamp" - FROM ABSTIME_TBL WHERE NOT isfinite(f1); - -SELECT '' AS ten, f1 AS interval, reltime(f1) AS reltime - FROM INTERVAL_TBL; - -SELECT '' AS six, f1 as reltime, CAST(f1 AS interval) AS interval - FROM RELTIME_TBL; - DROP TABLE TEMP_TIMESTAMP; -- @@ -338,22 +288,16 @@ SHOW DateStyle; SELECT '' AS "64", d1 AS us_postgres FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS us_postgres FROM ABSTIME_TBL; - SET DateStyle TO 'US,ISO'; SELECT '' AS "64", d1 AS us_iso FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS us_iso FROM ABSTIME_TBL; - SET DateStyle TO 'US,SQL'; SHOW DateStyle; SELECT '' AS "64", d1 AS us_sql FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS us_sql FROM ABSTIME_TBL; - SET DateStyle TO 'European,Postgres'; SHOW DateStyle; @@ -364,24 +308,18 @@ SELECT count(*) as one FROM TIMESTAMP_TBL WHERE d1 = 'Jun 13 1957'; SELECT '' AS "65", d1 AS european_postgres FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS european_postgres FROM ABSTIME_TBL; - SET DateStyle TO 'European,ISO'; SHOW DateStyle; SELECT '' AS "65", d1 AS european_iso FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS european_iso FROM ABSTIME_TBL; - SET DateStyle TO 'European,SQL'; SHOW DateStyle; SELECT '' AS "65", d1 AS european_sql FROM TIMESTAMP_TBL; -SELECT '' AS seven, f1 AS european_sql FROM ABSTIME_TBL; - RESET DateStyle; -- @@ -392,15 +330,21 @@ SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS'); SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS'); +SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS'); + SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD'); +SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD'); + +SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD'); + SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', - '"My birthday-> Year" YYYY, "Month:" FMMonth, "Day:" DD'); + '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD'); SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); SELECT to_timestamp('15 "text between quote marks" 98 54 45', - E'HH24 "\\text between quote marks\\"" YY MI SS'); + E'HH24 "\\"text between quote marks\\"" YY MI SS'); SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY'); @@ -408,6 +352,12 @@ SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay'); SELECT to_timestamp('97/Feb/16', 'YYMonDD'); +SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD'); + +SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD'); + +SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD'); + SELECT to_timestamp('19971116', 'YYYYMMDD'); SELECT to_timestamp('20000-1116', 'YYYY-MMDD'); @@ -452,6 +402,15 @@ SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM'); +SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.1', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.12', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.123', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.1234', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.12345', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.123456', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; +SELECT i, to_timestamp('2018-11-02 12:34:56.123456789', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; + -- -- Check handling of multiple spaces in format and/or input -- @@ -464,6 +423,17 @@ SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); +SELECT to_timestamp('2000+ JUN', 'YYYY/MON'); +SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON'); +SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON'); +SELECT to_timestamp('2000 +JUN', 'YYYY//MON'); +SELECT to_timestamp('2000 + JUN', 'YYYY MON'); +SELECT to_timestamp('2000 ++ JUN', 'YYYY MON'); +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); +SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); +SELECT to_timestamp('2000 -10', 'YYYY TZH'); +SELECT to_timestamp('2000 -10', 'YYYY TZH'); + SELECT to_date('2011 12 18', 'YYYY MM DD'); SELECT to_date('2011 12 18', 'YYYY MM DD'); SELECT to_date('2011 12 18', 'YYYY MM DD'); @@ -472,6 +442,10 @@ SELECT to_date('2011 12 18', 'YYYY MM DD'); SELECT to_date('2011 12 18', 'YYYY MM DD'); SELECT to_date('2011 12 18', 'YYYY MM DD'); +SELECT to_date('2011 12 18', 'YYYYxMMxDD'); +SELECT to_date('2011x 12x 18', 'YYYYxMMxDD'); +SELECT to_date('2011 x12 x18', 'YYYYxMMxDD'); + -- -- Check errors for some incorrect usages of to_timestamp() and to_date() -- @@ -506,6 +480,8 @@ SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -- ok SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS'); -- ok SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS'); +SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS'); -- ok +SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS'); SELECT to_date('2016-13-10', 'YYYY-MM-DD'); SELECT to_date('2016-02-30', 'YYYY-MM-DD'); SELECT to_date('2016-02-29', 'YYYY-MM-DD'); -- ok @@ -529,5 +505,7 @@ SELECT '2012-12-12 12:00'::timestamptz; SELECT '2012-12-12 12:00 America/New_York'::timestamptz; SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS'); +SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS'); RESET TIME ZONE; diff --git a/src/test/regress/sql/hs_standby_allowed.sql b/src/test/regress/sql/hs_standby_allowed.sql index a33199dbbdf..6debddc5e99 100644 --- a/src/test/regress/sql/hs_standby_allowed.sql +++ b/src/test/regress/sql/hs_standby_allowed.sql @@ -110,6 +110,10 @@ LOCK hs1 IN ROW SHARE MODE; LOCK hs1 IN ROW EXCLUSIVE MODE; COMMIT; +-- UNLISTEN +UNLISTEN a; +UNLISTEN *; + -- LOAD -- should work, easier if there is no test for that... diff --git a/src/test/regress/sql/hs_standby_disallowed.sql b/src/test/regress/sql/hs_standby_disallowed.sql index 21bbf526b74..a470600eec8 100644 --- a/src/test/regress/sql/hs_standby_disallowed.sql +++ b/src/test/regress/sql/hs_standby_disallowed.sql @@ -88,8 +88,6 @@ COMMIT; -- Listen listen a; notify a; -unlisten a; -unlisten *; -- disallowed commands diff --git a/src/test/regress/sql/identity.sql b/src/test/regress/sql/identity.sql index f8f34eaf185..4b03d24effe 100644 --- a/src/test/regress/sql/identity.sql +++ b/src/test/regress/sql/identity.sql @@ -145,6 +145,8 @@ INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz'); SELECT * FROM itestv11; +DROP VIEW itestv10, itestv11; + -- ADD COLUMN @@ -172,6 +174,12 @@ SELECT seqtypid::regtype FROM pg_sequence WHERE seqrelid = 'itest3_a_seq'::regcl ALTER TABLE itest3 ALTER COLUMN a TYPE text; -- error +-- kinda silly to change property in the same command, but it should work +ALTER TABLE itest3 + ADD COLUMN c int GENERATED BY DEFAULT AS IDENTITY, + ALTER COLUMN c SET GENERATED ALWAYS; +\d itest3 + -- ALTER COLUMN ... SET @@ -247,47 +255,10 @@ CREATE TABLE itest_child PARTITION OF itest_parent ( ) FOR VALUES FROM ('2016-07-01') TO ('2016-08-01'); -- error DROP TABLE itest_parent; --- MERGE tests -CREATE TABLE itest14 (a int GENERATED ALWAYS AS IDENTITY, b text); -CREATE TABLE itest15 (a int GENERATED BY DEFAULT AS IDENTITY, b text); - -MERGE INTO itest14 t -USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) VALUES (s.s_a, s.s_b); - -MERGE INTO itest14 t -USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b); - -MERGE INTO itest14 t -USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b); - -MERGE INTO itest15 t -USING (SELECT 10 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) VALUES (s.s_a, s.s_b); - -MERGE INTO itest15 t -USING (SELECT 20 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING USER VALUE VALUES (s.s_a, s.s_b); - -MERGE INTO itest15 t -USING (SELECT 30 AS s_a, 'inserted by merge' AS s_b) s -ON t.a = s.s_a -WHEN NOT MATCHED THEN - INSERT (a, b) OVERRIDING SYSTEM VALUE VALUES (s.s_a, s.s_b); - -SELECT * FROM itest14; -SELECT * FROM itest15; -DROP TABLE itest14; -DROP TABLE itest15; + +-- test that sequence of half-dropped serial column is properly ignored + +CREATE TABLE itest14 (id serial); +ALTER TABLE itest14 ALTER id DROP DEFAULT; +ALTER TABLE itest14 ALTER id ADD GENERATED BY DEFAULT AS IDENTITY; +INSERT INTO itest14 (id) VALUES (DEFAULT); diff --git a/src/test/regress/sql/index_including.sql b/src/test/regress/sql/index_including.sql index caedc9866d3..7e517483adf 100644 --- a/src/test/regress/sql/index_including.sql +++ b/src/test/regress/sql/index_including.sql @@ -1,59 +1,57 @@ /* * 1.test CREATE INDEX + * + * Deliberately avoid dropping objects in this section, to get some pg_dump + * coverage. */ -- Regular index with included columns -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c3,c4); --- must fail because of intersection of key and included columns -CREATE INDEX tbl_idx ON tbl using btree (c1, c2) INCLUDE (c1,c3); +CREATE TABLE tbl_include_reg (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_reg SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE INDEX tbl_include_reg_idx ON tbl_include_reg (c1, c2) INCLUDE (c3, c4); +-- duplicate column is pretty pointless, but we allow it anyway +CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; -DROP TABLE tbl; +WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname; +\d tbl_include_reg_idx -- Unique index and unique constraint -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ALTER TABLE tbl add UNIQUE USING INDEX tbl_idx_unique; -ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4); +CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_unique1_idx_unique ON tbl_include_unique1 using btree (c1, c2) INCLUDE (c3, c4); +ALTER TABLE tbl_include_unique1 add UNIQUE USING INDEX tbl_include_unique1_idx_unique; +ALTER TABLE tbl_include_unique1 add UNIQUE (c1, c2) INCLUDE (c3, c4); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; -DROP TABLE tbl; +WHERE i.indrelid = 'tbl_include_unique1'::regclass ORDER BY c.relname; -- Unique index and unique constraint. Both must fail. -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ALTER TABLE tbl add UNIQUE (c1, c2) INCLUDE (c3, c4); -DROP TABLE tbl; +CREATE TABLE tbl_include_unique2 (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_unique2 SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_unique2_idx_unique ON tbl_include_unique2 using btree (c1, c2) INCLUDE (c3, c4); +ALTER TABLE tbl_include_unique2 add UNIQUE (c1, c2) INCLUDE (c3, c4); -- PK constraint -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); +CREATE TABLE tbl_include_pk (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_pk SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +ALTER TABLE tbl_include_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; -DROP TABLE tbl; +WHERE i.indrelid = 'tbl_include_pk'::regclass ORDER BY c.relname; -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -CREATE UNIQUE INDEX tbl_idx_unique ON tbl using btree (c1, c2) INCLUDE (c3, c4); -ALTER TABLE tbl add PRIMARY KEY USING INDEX tbl_idx_unique; +CREATE TABLE tbl_include_box (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_box SELECT 1, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +CREATE UNIQUE INDEX tbl_include_box_idx_unique ON tbl_include_box using btree (c1, c2) INCLUDE (c3, c4); +ALTER TABLE tbl_include_box add PRIMARY KEY USING INDEX tbl_include_box_idx_unique; SELECT pg_get_indexdef(i.indexrelid) FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid -WHERE i.indrelid = 'tbl'::regclass ORDER BY c.relname; -DROP TABLE tbl; +WHERE i.indrelid = 'tbl_include_box'::regclass ORDER BY c.relname; -- PK constraint. Must fail. -CREATE TABLE tbl (c1 int, c2 int, c3 int, c4 box); -INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -ALTER TABLE tbl add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); -DROP TABLE tbl; +CREATE TABLE tbl_include_box_pk (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_include_box_pk SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; +ALTER TABLE tbl_include_box_pk add PRIMARY KEY (c1, c2) INCLUDE (c3, c4); /* @@ -62,7 +60,7 @@ DROP TABLE tbl; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, CONSTRAINT covering UNIQUE(c1,c2) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; -- ensure that constraint works INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; DROP TABLE tbl; @@ -70,17 +68,26 @@ DROP TABLE tbl; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, CONSTRAINT covering PRIMARY KEY(c1,c2) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; -- ensure that constraint works INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; -INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x; -DROP TABLE tbl; +INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,300) AS x; +explain (costs off) +select * from tbl where (c1,c2,c3) < (2,5,1); +select * from tbl where (c1,c2,c3) < (2,5,1); +-- row comparison that compares high key at page boundary +SET enable_seqscan = off; +explain (costs off) +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; +select * from tbl where (c1,c2,c3) < (262,1,1) limit 1; +DROP TABLE tbl; +RESET enable_seqscan; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, UNIQUE(c1,c2) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; -- ensure that constraint works INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; DROP TABLE tbl; @@ -88,7 +95,7 @@ DROP TABLE tbl; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, PRIMARY KEY(c1,c2) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; -- ensure that constraint works INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; INSERT INTO tbl SELECT 1, NULL, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; @@ -98,7 +105,7 @@ DROP TABLE tbl; CREATE TABLE tbl (c1 int,c2 int, c3 int, c4 box, EXCLUDE USING btree (c1 WITH =) INCLUDE(c3,c4)); SELECT indexrelid::regclass, indnatts, indnkeyatts, indisunique, indisprimary, indkey, indclass FROM pg_index WHERE indrelid = 'tbl'::regclass::oid; -SELECT pg_get_constraintdef(oid), conname, conkey, conincluding FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; +SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'tbl'::regclass::oid; -- ensure that constraint works INSERT INTO tbl SELECT 1, 2, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x; INSERT INTO tbl SELECT x, 2*x, NULL, NULL FROM generate_series(1,10) AS x; @@ -140,6 +147,16 @@ ALTER TABLE tbl DROP COLUMN c1; SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; DROP TABLE tbl; +/* + * 3.3 Test ALTER TABLE SET STATISTICS + */ +CREATE TABLE tbl (c1 int, c2 int); +CREATE INDEX tbl_idx ON tbl (c1, (c1+0)) INCLUDE (c2); +ALTER INDEX tbl_idx ALTER COLUMN 1 SET STATISTICS 1000; +ALTER INDEX tbl_idx ALTER COLUMN 2 SET STATISTICS 1000; +ALTER INDEX tbl_idx ALTER COLUMN 3 SET STATISTICS 1000; +ALTER INDEX tbl_idx ALTER COLUMN 4 SET STATISTICS 1000; +DROP TABLE tbl; /* * 4. CREATE INDEX CONCURRENTLY @@ -165,15 +182,15 @@ SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl' ORDER BY indexname; DROP TABLE tbl; /* - * 7. Check various AMs. All but btree must fail. + * 7. Check various AMs. All but btree and gist must fail. */ CREATE TABLE tbl (c1 int,c2 int, c3 box, c4 box); CREATE INDEX on tbl USING brin(c1, c2) INCLUDE (c3, c4); -CREATE INDEX on tbl USING gist(c3) INCLUDE (c4); +CREATE INDEX on tbl USING gist(c3) INCLUDE (c1, c4); CREATE INDEX on tbl USING spgist(c3) INCLUDE (c4); CREATE INDEX on tbl USING gin(c1, c2) INCLUDE (c3, c4); CREATE INDEX on tbl USING hash(c1, c2) INCLUDE (c3, c4); -CREATE INDEX on tbl USING rtree(c1, c2) INCLUDE (c3, c4); +CREATE INDEX on tbl USING rtree(c3) INCLUDE (c1, c4); CREATE INDEX on tbl USING btree(c1, c2) INCLUDE (c3, c4); DROP TABLE tbl; @@ -200,4 +217,3 @@ ALTER TABLE tbl ALTER c1 TYPE bigint; ALTER TABLE tbl ALTER c3 TYPE bigint; \d tbl DROP TABLE tbl; - diff --git a/src/test/regress/sql/index_including_gist.sql b/src/test/regress/sql/index_including_gist.sql new file mode 100644 index 00000000000..7d5c99b2e79 --- /dev/null +++ b/src/test/regress/sql/index_including_gist.sql @@ -0,0 +1,90 @@ +/* + * 1.1. test CREATE INDEX with buffered build + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +-- size is chosen to exceed page size and trigger actual truncation +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); +SET enable_bitmapscan TO off; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); +SET enable_bitmapscan TO default; +DROP TABLE tbl_gist; + +/* + * 1.2. test CREATE INDEX with inserts + */ + +-- Regular index with included columns +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +-- size is chosen to exceed page size and trigger actual truncation +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,8000) AS x; +SELECT pg_get_indexdef(i.indexrelid) +FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid +WHERE i.indrelid = 'tbl_gist'::regclass ORDER BY c.relname; +SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); +SET enable_bitmapscan TO off; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); +SET enable_bitmapscan TO default; +DROP TABLE tbl_gist; + +/* + * 2. CREATE INDEX CONCURRENTLY + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX CONCURRENTLY tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c2,c3); +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; +DROP TABLE tbl_gist; + + +/* + * 3. REINDEX + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; +REINDEX INDEX tbl_gist_idx; +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; +ALTER TABLE tbl_gist DROP COLUMN c1; +SELECT indexdef FROM pg_indexes WHERE tablename = 'tbl_gist' ORDER BY indexname; +DROP TABLE tbl_gist; + +/* + * 4. Update, delete values in indexed table. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +UPDATE tbl_gist SET c1 = 100 WHERE c1 = 2; +UPDATE tbl_gist SET c1 = 1 WHERE c1 = 3; +DELETE FROM tbl_gist WHERE c1 = 5 OR c3 = 12; +DROP TABLE tbl_gist; + +/* + * 5. Alter column type. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +CREATE INDEX tbl_gist_idx ON tbl_gist using gist (c4) INCLUDE (c1,c3); +ALTER TABLE tbl_gist ALTER c1 TYPE bigint; +ALTER TABLE tbl_gist ALTER c3 TYPE bigint; +\d tbl_gist +DROP TABLE tbl_gist; + +/* + * 6. EXCLUDE constraint. + */ +CREATE TABLE tbl_gist (c1 int, c2 int, c3 int, c4 box, EXCLUDE USING gist (c4 WITH &&) INCLUDE (c1, c2, c3)); +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(x,x+1),point(2*x,2*x+1)) FROM generate_series(1,10) AS x; +INSERT INTO tbl_gist SELECT x, 2*x, 3*x, box(point(3*x,2*x),point(3*x+1,2*x+1)) FROM generate_series(1,10) AS x; +EXPLAIN (costs off) SELECT * FROM tbl_gist where c4 <@ box(point(1,1),point(10,10)); +\d tbl_gist +DROP TABLE tbl_gist; diff --git a/src/test/regress/sql/indexing.sql b/src/test/regress/sql/indexing.sql index ab7c2d14758..cc3d0abfb7b 100644 --- a/src/test/regress/sql/indexing.sql +++ b/src/test/regress/sql/indexing.sql @@ -1,12 +1,29 @@ -- Creating an index on a partitioned table makes the partitions -- automatically get the index create table idxpart (a int, b int, c text) partition by range (a); + +-- relhassubclass of a partitioned index is false before creating any partition. +-- It will be set after the first partition is created. +create index idxpart_idx on idxpart (a); +select relhassubclass from pg_class where relname = 'idxpart_idx'; + +-- Check that partitioned indexes are present in pg_indexes. +select indexdef from pg_indexes where indexname like 'idxpart_idx%'; +drop index idxpart_idx; + create table idxpart1 partition of idxpart for values from (0) to (10); create table idxpart2 partition of idxpart for values from (10) to (100) partition by range (b); create table idxpart21 partition of idxpart2 for values from (0) to (100); + +-- Even with partitions, relhassubclass should not be set if a partitioned +-- index is created only on the parent. +create index idxpart_idx on only idxpart(a); +select relhassubclass from pg_class where relname = 'idxpart_idx'; +drop index idxpart_idx; + create index on idxpart (a); -select relname, relkind, inhparent::regclass +select relname, relkind, relhassubclass, inhparent::regclass from pg_class left join pg_index ix on (indexrelid = oid) left join pg_inherits on (ix.indexrelid = inhrelid) where relname like 'idxpart%' order by relname; @@ -26,6 +43,15 @@ CREATE TABLE idxpart_two (col2 INT); SELECT col2 FROM idxpart_two fk LEFT OUTER JOIN idxpart pk ON (col1 = col2); DROP table idxpart, idxpart_two; +-- Verify bugfix with index rewrite on ALTER TABLE / SET DATA TYPE +-- https://postgr.es/m/CAKcux6mxNCGsgATwf5CGMF8g4WSupCXicCVMeKUTuWbyxHOMsQ@mail.gmail.com +CREATE TABLE idxpart (a INT, b TEXT, c INT) PARTITION BY RANGE(a); +CREATE TABLE idxpart1 PARTITION OF idxpart FOR VALUES FROM (MINVALUE) TO (MAXVALUE); +CREATE INDEX partidx_abc_idx ON idxpart (a, b, c); +INSERT INTO idxpart (a, b, c) SELECT i, i, i FROM generate_series(1, 50) i; +ALTER TABLE idxpart ALTER COLUMN c TYPE numeric; +DROP TABLE idxpart; + -- If a table without index is attached as partition to a table with -- an index, the index is automatically created create table idxpart (a int, b int, c text) partition by range (a); @@ -35,6 +61,8 @@ create table idxpart1 (like idxpart); \d idxpart1 alter table idxpart attach partition idxpart1 for values from (0) to (10); \d idxpart1 +\d+ idxpart1_a_idx +\d+ idxpart1_b_c_idx drop table idxpart; -- If a partition already has an index, don't create a duplicative one @@ -43,7 +71,7 @@ create table idxpart1 partition of idxpart for values from (0, 0) to (10, 10); create index on idxpart1 (a, b); create index on idxpart (a, b); \d idxpart1 -select relname, relkind, inhparent::regclass +select relname, relkind, relhassubclass, inhparent::regclass from pg_class left join pg_index ix on (indexrelid = oid) left join pg_inherits on (ix.indexrelid = inhrelid) where relname like 'idxpart%' order by relname; @@ -221,6 +249,16 @@ select relname, relkind from pg_class where relname like 'idxpart%' order by rel drop table idxpart, idxpart1, idxpart2, idxpart3; select relname, relkind from pg_class where relname like 'idxpart%' order by relname; +create table idxpart (a int, b int, c int) partition by range(a); +create index on idxpart(c); +create table idxpart1 partition of idxpart for values from (0) to (250); +create table idxpart2 partition of idxpart for values from (250) to (500); +alter table idxpart detach partition idxpart2; +\d idxpart2 +alter table idxpart2 drop column c; +\d idxpart2 +drop table idxpart, idxpart2; + -- Verify that expression indexes inherit correctly create table idxpart (a int, b int) partition by range (a); create table idxpart1 (like idxpart); @@ -326,6 +364,7 @@ alter table idxpart2 drop column col1, drop column col2; create index on idxpart2 (abs(b)); alter table idxpart attach partition idxpart2 for values from (0) to (1); create index on idxpart (abs(b)); +create index on idxpart ((b + 1)); alter table idxpart attach partition idxpart1 for values from (1) to (2); select c.relname, pg_get_indexdef(indexrelid) from pg_class c join pg_index i on c.oid = i.indexrelid @@ -389,9 +428,16 @@ drop table idxpart; -- Verify that it works to add primary key / unique to partitioned tables create table idxpart (a int primary key, b int) partition by range (a); \d idxpart +-- multiple primary key on child should fail +create table failpart partition of idxpart (b primary key) for values from (0) to (100); +drop table idxpart; +-- primary key on child is okay if there's no PK in the parent, though +create table idxpart (a int) partition by range (a); +create table idxpart1pk partition of idxpart (a primary key) for values from (0) to (100); +\d idxpart1pk drop table idxpart; --- but not if you fail to use the full partition key +-- Failing to use the full partition key is not allowed create table idxpart (a int unique, b int) partition by range (a, b); create table idxpart (a int, b int unique) partition by range (a, b); create table idxpart (a int primary key, b int) partition by range (b, a); @@ -532,6 +578,18 @@ select indrelid::regclass, indexrelid::regclass, inhparent::regclass, indisvalid order by indexrelid::regclass::text collate "C"; drop table idxpart; +-- Related to the above scenario: ADD PRIMARY KEY on the parent mustn't +-- automatically propagate NOT NULL to child columns. +create table idxpart (a int) partition by range (a); +create table idxpart0 (like idxpart); +alter table idxpart0 add unique (a); +alter table idxpart attach partition idxpart0 default; +alter table only idxpart add primary key (a); -- fail, no NOT NULL constraint +alter table idxpart0 alter column a set not null; +alter table only idxpart add primary key (a); -- now it works +alter table idxpart0 alter column a drop not null; -- fail, pkey needs it +drop table idxpart; + -- if a partition has a unique index without a constraint, does not attach -- automatically; creates a new index instead. create table idxpart (a int, b int) partition by range (a); @@ -574,120 +632,6 @@ insert into idxpart values (857142, 'six'); select tableoid::regclass, * from idxpart order by a; drop table idxpart; --- test fastpath mechanism for index insertion -create table fastpath (a int, b text, c numeric); -create unique index fpindex1 on fastpath(a); - -insert into fastpath values (1, 'b1', 100.00); -insert into fastpath values (1, 'b1', 100.00); -- unique key check - -truncate fastpath; -insert into fastpath select generate_series(1,10000), 'b', 100; - --- vacuum the table so as to improve chances of index-only scans. we can't --- guarantee if index-only scans will be picked up in all cases or not, but --- that fuzziness actually helps the test. -vacuum fastpath; - -set enable_seqscan to false; -set enable_bitmapscan to false; - -select sum(a) from fastpath where a = 6456; -select sum(a) from fastpath where a >= 5000 and a < 5700; - --- drop the only index on the table and compute hashes for --- a few queries which orders the results in various different ways. -drop index fpindex1; -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - --- now create a multi-column index with both column asc -create index fpindex2 on fastpath(a, b); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; --- again, vacuum here either forces index-only scans or creates fuzziness -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - --- same queries with a different kind of index now. the final result must not --- change irrespective of what kind of index we have. -drop index fpindex2; -create index fpindex3 on fastpath(a desc, b asc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - --- repeat again -drop index fpindex3; -create index fpindex4 on fastpath(a asc, b desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - --- and again, this time indexing by (b, a). Note that column "b" has non-unique --- values. -drop index fpindex4; -create index fpindex5 on fastpath(b asc, a desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - --- one last time -drop index fpindex5; -create index fpindex6 on fastpath(b desc, a desc); -truncate fastpath; -insert into fastpath select y.x, 'b' || (y.x/10)::text, 100 from (select generate_series(1,10000) as x) y; -vacuum fastpath; -select md5(string_agg(a::text, b order by a, b asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by a desc, b desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a desc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; -select md5(string_agg(a::text, b order by b, a asc)) from fastpath - where a >= 1000 and a < 2000 and b > 'b1' and b < 'b3'; - -drop table fastpath; - -- intentionally leave some objects around create table idxpart (a int) partition by range (a); create table idxpart1 partition of idxpart for values from (0) to (100); @@ -701,3 +645,61 @@ alter index idxpart2_a_idx attach partition idxpart22_a_idx; create index on idxpart (a); create table idxpart_another (a int, b int, primary key (a, b)) partition by range (a); create table idxpart_another_1 partition of idxpart_another for values from (0) to (100); +create table idxpart3 (c int, b int, a int) partition by range (a); +alter table idxpart3 drop column b, drop column c; +create table idxpart31 partition of idxpart3 for values from (1000) to (1200); +create table idxpart32 partition of idxpart3 for values from (1200) to (1400); +alter table idxpart attach partition idxpart3 for values from (1000) to (2000); + +-- More objects intentionally left behind, to verify some pg_dump/pg_upgrade +-- behavior; see https://postgr.es/m/20190321204928.GA17535@alvherre.pgsql +create schema regress_indexing; +set search_path to regress_indexing; +create table pk (a int primary key) partition by range (a); +create table pk1 partition of pk for values from (0) to (1000); +create table pk2 (b int, a int); +alter table pk2 drop column b; +alter table pk2 alter a set not null; +alter table pk attach partition pk2 for values from (1000) to (2000); +create table pk3 partition of pk for values from (2000) to (3000); +create table pk4 (like pk); +alter table pk attach partition pk4 for values from (3000) to (4000); +create table pk5 (like pk) partition by range (a); +create table pk51 partition of pk5 for values from (4000) to (4500); +create table pk52 partition of pk5 for values from (4500) to (5000); +alter table pk attach partition pk5 for values from (4000) to (5000); +reset search_path; + +-- Test that covering partitioned indexes work in various cases +create table covidxpart (a int, b int) partition by list (a); +create unique index on covidxpart (a) include (b); +create table covidxpart1 partition of covidxpart for values in (1); +create table covidxpart2 partition of covidxpart for values in (2); +insert into covidxpart values (1, 1); +insert into covidxpart values (1, 1); +create table covidxpart3 (b int, c int, a int); +alter table covidxpart3 drop c; +alter table covidxpart attach partition covidxpart3 for values in (3); +insert into covidxpart values (3, 1); +insert into covidxpart values (3, 1); +create table covidxpart4 (b int, a int); +create unique index on covidxpart4 (a) include (b); +create unique index on covidxpart4 (a); +alter table covidxpart attach partition covidxpart4 for values in (4); +insert into covidxpart values (4, 1); +insert into covidxpart values (4, 1); +create unique index on covidxpart (b) include (a); -- should fail + +-- check that detaching a partition also detaches the primary key constraint +create table parted_pk_detach_test (a int primary key) partition by list (a); +create table parted_pk_detach_test1 partition of parted_pk_detach_test for values in (1); +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; -- should fail +alter table parted_pk_detach_test detach partition parted_pk_detach_test1; +alter table parted_pk_detach_test1 drop constraint parted_pk_detach_test1_pkey; +drop table parted_pk_detach_test, parted_pk_detach_test1; +create table parted_uniq_detach_test (a int unique) partition by list (a); +create table parted_uniq_detach_test1 partition of parted_uniq_detach_test for values in (1); +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; -- should fail +alter table parted_uniq_detach_test detach partition parted_uniq_detach_test1; +alter table parted_uniq_detach_test1 drop constraint parted_uniq_detach_test1_a_key; +drop table parted_uniq_detach_test, parted_uniq_detach_test1; diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql index 880e115360d..c8ef4db7f2b 100644 --- a/src/test/regress/sql/inet.sql +++ b/src/test/regress/sql/inet.sql @@ -65,8 +65,18 @@ SELECT '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL; -- check that btree index works correctly CREATE INDEX inet_idx1 ON inet_tbl(i); SET enable_seqscan TO off; +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; SELECT * FROM inet_tbl WHERE i<<'192.168.1.0/24'::cidr; +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; SELECT * FROM inet_tbl WHERE i<<='192.168.1.0/24'::cidr; +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >>= i; +EXPLAIN (COSTS OFF) +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; +SELECT * FROM inet_tbl WHERE '192.168.1.0/24'::cidr >> i; SET enable_seqscan TO on; DROP INDEX inet_idx1; @@ -146,3 +156,98 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '10::/8'); SELECT inet_merge(c, i) FROM INET_TBL; -- fix it by inet_same_family() condition SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i); + +-- Test inet sortsupport with a variety of boundary inputs: +SELECT a FROM (VALUES + ('0.0.0.0/0'::inet), + ('0.0.0.0/1'::inet), + ('0.0.0.0/32'::inet), + ('0.0.0.1/0'::inet), + ('0.0.0.1/1'::inet), + ('127.126.127.127/0'::inet), + ('127.127.127.127/0'::inet), + ('127.128.127.127/0'::inet), + ('192.168.1.0/24'::inet), + ('192.168.1.0/25'::inet), + ('192.168.1.1/23'::inet), + ('192.168.1.1/5'::inet), + ('192.168.1.1/6'::inet), + ('192.168.1.1/25'::inet), + ('192.168.1.2/25'::inet), + ('192.168.1.1/26'::inet), + ('192.168.1.2/26'::inet), + ('192.168.1.2/23'::inet), + ('192.168.1.255/5'::inet), + ('192.168.1.255/6'::inet), + ('192.168.1.3/1'::inet), + ('192.168.1.3/23'::inet), + ('192.168.1.4/0'::inet), + ('192.168.1.5/0'::inet), + ('255.0.0.0/0'::inet), + ('255.1.0.0/0'::inet), + ('255.2.0.0/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/0'::inet), + ('255.255.000.000/15'::inet), + ('255.255.000.000/16'::inet), + ('255.255.255.254/32'::inet), + ('255.255.255.000/32'::inet), + ('255.255.255.001/31'::inet), + ('255.255.255.002/31'::inet), + ('255.255.255.003/31'::inet), + ('255.255.255.003/32'::inet), + ('255.255.255.001/32'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/0'::inet), + ('255.255.255.255/1'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/16'::inet), + ('255.255.255.255/31'::inet), + ('255.255.255.255/32'::inet), + ('255.255.255.253/32'::inet), + ('255.255.255.252/32'::inet), + ('255.3.0.0/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet), + ('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet), + ('10:23::f1/64'::inet), + ('10:23::f1/65'::inet), + ('10:23::ffff'::inet), + ('127::1'::inet), + ('127::2'::inet), + ('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet), + ('::1:ffff:ffff:ffff:ffff/128'::inet), + ('::2:ffff:ffff:ffff:ffff/128'::inet), + ('::4:3:2:0/24'::inet), + ('::4:3:2:1/24'::inet), + ('::4:3:2:2/24'::inet), + ('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet), + ('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet), + ('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet), + ('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet), + ('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet), + ('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet), + ('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet), + ('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet), + ('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet), + ('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet), + ('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet), + ('ffff:fffa:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffb:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffc:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffd:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:fffe:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffa:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffb:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffc:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffd::/128'::inet), + ('ffff:ffff:ffff:fffd:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:fffe::/128'::inet), + ('ffff:ffff:ffff:fffe:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:0/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:1/24'::inet), + ('ffff:ffff:ffff:ffff:4:3:2:2/24'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet), + ('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet) +) AS i(a) ORDER BY a; diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql index 5a48376fc03..3af1bf30a79 100644 --- a/src/test/regress/sql/inherit.sql +++ b/src/test/regress/sql/inherit.sql @@ -97,6 +97,21 @@ SELECT relname, d.* FROM ONLY d, pg_class where d.tableoid = pg_class.oid; CREATE TEMP TABLE z (b TEXT, PRIMARY KEY(aa, b)) inherits (a); INSERT INTO z VALUES (NULL, 'text'); -- should fail +-- Check inherited UPDATE with all children excluded +create table some_tab (a int, b int); +create table some_tab_child () inherits (some_tab); +insert into some_tab_child values(1,2); + +explain (verbose, costs off) +update some_tab set a = a + 1 where false; +update some_tab set a = a + 1 where false; +explain (verbose, costs off) +update some_tab set a = a + 1 where false returning b, a; +update some_tab set a = a + 1 where false returning b, a; +table some_tab; + +drop table some_tab cascade; + -- Check UPDATE with inherited target and an inherited source table create temp table foo(f1 int, f2 int); create temp table foo2(f3 int) inherits (foo); @@ -153,6 +168,9 @@ from where parted_tab.a = ss.a; select tableoid::regclass::text as relname, parted_tab.* from parted_tab order by 1,2; +-- modifies partition key, but no rows will actually be updated +explain update parted_tab set a = 2 where false; + drop table parted_tab; -- Check UPDATE with multi-level partitioned inherited target @@ -190,31 +208,14 @@ insert into d values('test','one','two','three'); alter table a alter column aa type integer using bit_length(aa); select * from d; --- check that oid column is handled properly during alter table inherit -create table oid_parent (a int) with oids; - -create table oid_child () inherits (oid_parent); -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; -drop table oid_child; - -create table oid_child (a int) without oids; -alter table oid_child inherit oid_parent; -- fail -alter table oid_child set with oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; -alter table oid_child inherit oid_parent; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; -alter table oid_child set without oids; -- fail -alter table oid_parent set without oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; -alter table oid_child set without oids; -select attinhcount, attislocal from pg_attribute - where attrelid = 'oid_child'::regclass and attname = 'oid'; - -drop table oid_parent cascade; +-- The above verified that we can change the type of a multiply-inherited +-- column; but we should reject that if any definition was inherited from +-- an unrelated parent. +create temp table parent1(f1 int, f2 int); +create temp table parent2(f1 int, f3 bigint); +create temp table childtab(f4 int) inherits(parent1, parent2); +alter table parent1 alter column f1 type bigint; -- fail, conflict w/parent2 +alter table parent1 alter column f2 type bigint; -- ok -- Test non-inheritable parent constraints create table p1(ff1 int); @@ -237,9 +238,14 @@ drop table p1 cascade; -- tables. See the pgsql-hackers thread beginning Dec. 4/04 create table base (i integer); create table derived () inherits (base); +create table more_derived (like derived, b int) inherits (derived); insert into derived (i) values (0); select derived::base from derived; select NULL::derived::base; +-- remove redundant conversions. +explain (verbose on, costs off) select row(i, b)::more_derived::derived::base from more_derived; +explain (verbose on, costs off) select (1, 2)::more_derived::derived::base; +drop table more_derived; drop table derived; drop table base; @@ -257,40 +263,40 @@ drop table p1; CREATE TABLE ac (aa TEXT); alter table ac add constraint ac_check check (aa is not null); CREATE TABLE bc (bb TEXT) INHERITS (ac); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; insert into ac (aa) values (NULL); insert into bc (aa) values (NULL); alter table bc drop constraint ac_check; -- fail, disallowed alter table ac drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; -- try the unnamed-constraint case alter table ac add check (aa is not null); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; insert into ac (aa) values (NULL); insert into bc (aa) values (NULL); alter table bc drop constraint ac_aa_check; -- fail, disallowed alter table ac drop constraint ac_aa_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; alter table ac add constraint ac_check check (aa is not null); alter table bc no inherit ac; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; alter table bc drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; alter table ac drop constraint ac_check; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; drop table bc; drop table ac; create table ac (a int constraint check_a check (a <> 0)); create table bc (a int constraint check_a check (a <> 0), b int constraint check_b check (b <> 0)) inherits (ac); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc') order by 1,2; drop table bc; drop table ac; @@ -298,10 +304,10 @@ drop table ac; create table ac (a int constraint check_a check (a <> 0)); create table bc (b int constraint check_b check (b <> 0)); create table cc (c int constraint check_c check (c <> 0)) inherits (ac, bc); -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; alter table cc no inherit bc; -select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pgc.consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; +select pc.relname, pgc.conname, pgc.contype, pgc.conislocal, pgc.coninhcount, pg_get_expr(pgc.conbin, pc.oid) as consrc from pg_class as pc inner join pg_constraint as pgc on (pgc.conrelid = pc.oid) where pc.relname in ('ac', 'bc', 'cc') order by 1,2; drop table cc; drop table bc; @@ -635,6 +641,23 @@ select * from cnullparent; select * from cnullparent where f1 = 2; drop table cnullparent cascade; +-- +-- Check use of temporary tables with inheritance trees +-- +create table inh_perm_parent (a1 int); +create temp table inh_temp_parent (a1 int); +create temp table inh_temp_child () inherits (inh_perm_parent); -- ok +create table inh_perm_child () inherits (inh_temp_parent); -- error +create temp table inh_temp_child_2 () inherits (inh_temp_parent); -- ok +insert into inh_perm_parent values (1); +insert into inh_temp_parent values (2); +insert into inh_temp_child values (3); +insert into inh_temp_child_2 values (4); +select tableoid::regclass, a1 from inh_perm_parent; +select tableoid::regclass, a1 from inh_temp_parent; +drop table inh_perm_parent cascade; +drop table inh_temp_parent cascade; + -- -- Check that constraint exclusion works correctly with partitions using -- implicit constraints generated from the partition bound information. @@ -704,7 +727,6 @@ explain (costs off) select * from mcrparted where abs(b) = 5; -- scans all parti explain (costs off) select * from mcrparted where a > -1; -- scans all partitions explain (costs off) select * from mcrparted where a = 20 and abs(b) = 10 and c > 10; -- scans mcrparted4 explain (costs off) select * from mcrparted where a = 20 and c > 20; -- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def -drop table mcrparted; -- check that partitioned table Appends cope with being referenced in -- subplans @@ -715,3 +737,111 @@ insert into parted_minmax values (1,'12345'); explain (costs off) select min(a), max(a) from parted_minmax where b = '12345'; select min(a), max(a) from parted_minmax where b = '12345'; drop table parted_minmax; + +-- Test code that uses Append nodes in place of MergeAppend when the +-- partition ordering matches the desired ordering. + +create index mcrparted_a_abs_c_idx on mcrparted (a, abs(b), c); + +-- MergeAppend must be used when a default partition exists +explain (costs off) select * from mcrparted order by a, abs(b), c; + +drop table mcrparted_def; + +-- Append is used for a RANGE partitioned table with no default +-- and no subpartitions +explain (costs off) select * from mcrparted order by a, abs(b), c; + +-- Append is used with subpaths in reverse order with backwards index scans +explain (costs off) select * from mcrparted order by a desc, abs(b) desc, c desc; + +-- check that Append plan is used containing a MergeAppend for sub-partitions +-- that are unordered. +drop table mcrparted5; +create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a); +create table mcrparted5a partition of mcrparted5 for values in(20); +create table mcrparted5_def partition of mcrparted5 default; + +explain (costs off) select * from mcrparted order by a, abs(b), c; + +drop table mcrparted5_def; + +-- check that an Append plan is used and the sub-partitions are flattened +-- into the main Append when the sub-partition is unordered but contains +-- just a single sub-partition. +explain (costs off) select a, abs(b) from mcrparted order by a, abs(b), c; + +-- check that Append is used when the sub-partitioned tables are pruned +-- during planning. +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c; + +create table mclparted (a int) partition by list(a); +create table mclparted1 partition of mclparted for values in(1); +create table mclparted2 partition of mclparted for values in(2); +create index on mclparted (a); + +-- Ensure an Append is used for a list partition with an order by. +explain (costs off) select * from mclparted order by a; + +-- Ensure a MergeAppend is used when a partition exists with interleaved +-- datums in the partition bound. +create table mclparted3_5 partition of mclparted for values in(3,5); +create table mclparted4 partition of mclparted for values in(4); + +explain (costs off) select * from mclparted order by a; + +drop table mclparted; + +-- Ensure subplans which don't have a path with the correct pathkeys get +-- sorted correctly. +drop index mcrparted_a_abs_c_idx; +create index on mcrparted1 (a, abs(b), c); +create index on mcrparted2 (a, abs(b), c); +create index on mcrparted3 (a, abs(b), c); +create index on mcrparted4 (a, abs(b), c); + +explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c limit 1; + +set enable_bitmapscan = 0; +-- Ensure Append node can be used when the partition is ordered by some +-- pathkeys which were deemed redundant. +explain (costs off) select * from mcrparted where a = 10 order by a, abs(b), c; +reset enable_bitmapscan; + +drop table mcrparted; + +-- Ensure LIST partitions allow an Append to be used instead of a MergeAppend +create table bool_lp (b bool) partition by list(b); +create table bool_lp_true partition of bool_lp for values in(true); +create table bool_lp_false partition of bool_lp for values in(false); +create index on bool_lp (b); + +explain (costs off) select * from bool_lp order by b; + +drop table bool_lp; + +-- Ensure const bool quals can be properly detected as redundant +create table bool_rp (b bool, a int) partition by range(b,a); +create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000); +create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000); +create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000); +create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000); +create index on bool_rp (b,a); +explain (costs off) select * from bool_rp where b = true order by b,a; +explain (costs off) select * from bool_rp where b = false order by b,a; +explain (costs off) select * from bool_rp where b = true order by a; +explain (costs off) select * from bool_rp where b = false order by a; + +drop table bool_rp; + +-- Ensure an Append scan is chosen when the partition order is a subset of +-- the required order. +create table range_parted (a int, b int, c int) partition by range(a, b); +create table range_parted1 partition of range_parted for values from (0,0) to (10,10); +create table range_parted2 partition of range_parted for values from (10,10) to (20,20); +create index on range_parted (a,b,c); + +explain (costs off) select * from range_parted order by a,b,c; +explain (costs off) select * from range_parted order by a desc,b desc,c desc; + +drop table range_parted; diff --git a/src/test/regress/sql/insert.sql b/src/test/regress/sql/insert.sql index a16f2a7f890..23885f638c0 100644 --- a/src/test/regress/sql/insert.sql +++ b/src/test/regress/sql/insert.sql @@ -228,16 +228,36 @@ select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_p -- direct partition inserts should check hash partition bound constraint --- create custom operator class and hash function, for the same reason --- explained in alter_table.sql -create or replace function dummy_hashint4(a int4, seed int8) returns int8 as -$$ begin return (a + seed); end; $$ language 'plpgsql' immutable; -create operator class custom_opclass for type int4 using hash as -operator 1 = , function 2 dummy_hashint4(int4, int8); +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. The hash function for int4 simply returns +-- the sum of the values passed to it and the one for text returns the length +-- of the non-empty string value passed to it or 0. + +create or replace function part_hashint4_noop(value int4, seed int8) +returns int8 as $$ +select value + seed; +$$ language sql immutable; + +create operator class part_test_int4_ops +for type int4 +using hash as +operator 1 =, +function 2 part_hashint4_noop(int4, int8); + +create or replace function part_hashtext_length(value text, seed int8) +RETURNS int8 AS $$ +select length(coalesce(value, ''))::int8 +$$ language sql immutable; + +create operator class part_test_text_ops +for type text +using hash as +operator 1 =, +function 2 part_hashtext_length(text, int8); create table hash_parted ( a int -) partition by hash (a custom_opclass); +) partition by hash (a part_test_int4_ops); create table hpart0 partition of hash_parted for values with (modulus 4, remainder 0); create table hpart1 partition of hash_parted for values with (modulus 4, remainder 1); create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2); @@ -263,8 +283,6 @@ from hash_parted order by part; -- cleanup drop table range_parted, list_parted; drop table hash_parted; -drop operator class custom_opclass using hash; -drop function dummy_hashint4(a int4, seed int8); -- test that a default partition added as the first partition accepts any value -- including null @@ -383,6 +401,41 @@ insert into mlparted values (70, 100); select tableoid::regclass, * from mlparted_def; +-- Check multi-level tuple routing with attributes dropped from the +-- top-most parent. First remove the last attribute. +alter table mlparted add d int, add e int; +alter table mlparted drop e; +create table mlparted5 partition of mlparted + for values from (1, 40) to (1, 50) partition by range (c); +create table mlparted5_ab partition of mlparted5 + for values from ('a') to ('c') partition by list (c); +-- This partitioned table should remain with no partitions. +create table mlparted5_cd partition of mlparted5 + for values from ('c') to ('e') partition by list (c); +create table mlparted5_a partition of mlparted5_ab for values in ('a'); +create table mlparted5_b (d int, b int, c text, a int); +alter table mlparted5_ab attach partition mlparted5_b for values in ('b'); +truncate mlparted; +insert into mlparted values (1, 2, 'a', 1); +insert into mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d; +alter table mlparted drop d; +truncate mlparted; +-- Remove the before last attribute. +alter table mlparted add e int, add d int; +alter table mlparted drop e; +insert into mlparted values (1, 2, 'a', 1); +insert into mlparted values (1, 40, 'a', 1); -- goes to mlparted5_a +insert into mlparted values (1, 45, 'b', 1); -- goes to mlparted5_b +insert into mlparted values (1, 45, 'c', 1); -- goes to mlparted5_cd, fails +insert into mlparted values (1, 45, 'f', 1); -- goes to mlparted5, fails +select tableoid::regclass, * from mlparted order by a, b, c, d; +alter table mlparted drop d; +drop table mlparted5; + -- check that message shown after failure to find a partition shows the -- appropriate key description (or none) in various situations create table key_desc (a int, b int) partition by list ((a+0)); diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql index 6c50fd61eb6..43691cd3357 100644 --- a/src/test/regress/sql/insert_conflict.sql +++ b/src/test/regress/sql/insert_conflict.sql @@ -253,12 +253,11 @@ drop table insertconflicttest; -- -- Verify that EXCLUDED does not allow system column references. These -- do not make sense because EXCLUDED isn't an already stored tuple --- (and thus doesn't have a ctid, oids are not assigned yet, etc). +-- (and thus doesn't have a ctid etc). -- -create table syscolconflicttest(key int4, data text) WITH OIDS; +create table syscolconflicttest(key int4, data text); insert into syscolconflicttest values (1); insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text; -insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.oid::text; drop table syscolconflicttest; -- @@ -373,28 +372,6 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET drop table excluded; --- Check tables w/o oids are handled correctly -create table testoids(key int primary key, data text) without oids; --- first without oids -insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *; -insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *; --- add oids -alter table testoids set with oids; --- update existing row, that didn't have an oid -insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *; --- insert a new row -insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *; --- and update it -insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *; --- remove oids again, test -alter table testoids set without oids; -insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *; -insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *; -insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *; - -DROP TABLE testoids; - - -- check that references to columns after dropped columns are handled correctly create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float); insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1); @@ -551,11 +528,55 @@ drop table parted_conflict; -- partition create table parted_conflict (a int, b text) partition by range (a); create table parted_conflict_1 partition of parted_conflict for values from (0) to (1000) partition by range (a); +create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); create unique index on only parted_conflict_1 (a); create unique index on only parted_conflict (a); alter index parted_conflict_a_idx attach partition parted_conflict_1_a_idx; -create table parted_conflict_1_1 partition of parted_conflict_1 for values from (0) to (500); insert into parted_conflict values (40, 'forty'); insert into parted_conflict_1 values (40, 'cuarenta') on conflict (a) do update set b = excluded.b; drop table parted_conflict; + +-- test whole-row Vars in ON CONFLICT expressions +create table parted_conflict (a int, b text, c int) partition by range (a); +create table parted_conflict_1 (drp text, c int, a int, b text); +alter table parted_conflict_1 drop column drp; +create unique index on parted_conflict (a, b); +alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000); +truncate parted_conflict; +insert into parted_conflict values (50, 'cincuenta', 1); +insert into parted_conflict values (50, 'cincuenta', 2) + on conflict (a, b) do update set (a, b, c) = row(excluded.*) + where parted_conflict = (50, text 'cincuenta', 1) and + excluded = (50, text 'cincuenta', 2); + +-- should see (50, 'cincuenta', 2) +select * from parted_conflict order by a; + +-- test with statement level triggers +create or replace function parted_conflict_update_func() returns trigger as $$ +declare + r record; +begin + for r in select * from inserted loop + raise notice 'a = %, b = %, c = %', r.a, r.b, r.c; + end loop; + return new; +end; +$$ language plpgsql; + +create trigger parted_conflict_update + after update on parted_conflict + referencing new table as inserted + for each statement + execute procedure parted_conflict_update_func(); + +truncate parted_conflict; + +insert into parted_conflict values (0, 'cero', 1); + +insert into parted_conflict values(0, 'cero', 1) + on conflict (a,b) do update set c = parted_conflict.c + 1; + +drop table parted_conflict; +drop function parted_conflict_update_func(); diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index b1e05a33bd3..57481d04117 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -37,6 +37,12 @@ INSERT INTO J2_TBL VALUES (0, NULL); INSERT INTO J2_TBL VALUES (NULL, NULL); INSERT INTO J2_TBL VALUES (NULL, 0); +-- useful in some tests below +create temp table onerow(); +insert into onerow default values; +analyze onerow; + + -- -- CORRELATION NAMES -- Make sure that table/column aliases are supported @@ -297,6 +303,13 @@ NATURAL FULL JOIN (SELECT name, n as s3_n FROM t3) as s3 ) ss2; +-- Constants as join keys can also be problematic +SELECT * FROM + (SELECT name, n as s1_n FROM t1) as s1 +FULL JOIN + (SELECT name, 2 as s2_n FROM t2) as s2 +ON (s1_n = s2_n); + -- Test for propagation of nullability constraints into sub-joins @@ -673,6 +686,26 @@ select * from a left join b on i = x and i = y and x = i; rollback; +-- +-- test handling of merge clauses using record_ops +-- +begin; + +create type mycomptype as (id int, v bigint); + +create temp table tidv (idv mycomptype); +create index on tidv (idv); + +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + +set enable_mergejoin = 0; + +explain (costs off) +select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; + +rollback; + -- -- test NULL behavior of whole-row Vars, per bug #5025 -- @@ -881,18 +914,21 @@ select * from int4_tbl a full join int4_tbl b on false; -- test for ability to use a cartesian join when necessary -- +create temp table q1 as select 1 as q1; +create temp table q2 as select 0 as q2; +analyze q1; +analyze q2; + explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, - int4(sin(1)) q1, - int4(sin(0)) q2 + q1, q2 where q1 = thousand or q2 = thousand; explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, - int4(sin(1)) q1, - int4(sin(0)) q2 + q1, q2 where thousand = (q1 + q2); -- @@ -913,8 +949,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -926,8 +962,8 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) + from (select 1,0 from onerow) v1(x1,x2) + left join (select 3,1 from onerow) v2(y1,y2) on v1.x1 = v2.y2) subq1 on (i1.f1 = subq1.x2) on (t1.unique2 = subq1.d1) @@ -953,6 +989,108 @@ select ss1.d1 from on t1.tenthous = ss1.d1 where t1.unique1 < i4.f1; +-- this variant is foldable by the remove-useless-RESULT-RTEs code + +explain (costs off) +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from + tenk1 t1 + inner join int4_tbl i1 + left join (select v1.x2, v2.y1, 11 AS d1 + from (values(1,0)) v1(x1,x2) + left join (values(3,1)) v2(y1,y2) + on v1.x1 = v2.y2) subq1 + on (i1.f1 = subq1.x2) + on (t1.unique2 = subq1.d1) + left join tenk1 t2 + on (subq1.y1 = t2.unique1) +where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; + +-- +-- test inlining of immutable functions +-- +create function f_immutable_int4(i integer) returns integer as +$$ begin return i; end; $$ language plpgsql immutable; + +-- check optimization of function scan with join +explain (costs off) +select unique1 from tenk1, (select * from f_immutable_int4(1) x) x +where x = unique1; + +explain (verbose, costs off) +select unique1, x.* +from tenk1, (select *, random() from f_immutable_int4(1) x) x +where x = unique1; + +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; + +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; + +explain (costs off) +select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; + +explain (costs off) +select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; + +explain (costs off) +select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; + +explain (costs off) +select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; + +-- check that pullup of a const function allows further const-folding +explain (costs off) +select unique1 from tenk1, f_immutable_int4(1) x where x = 42; + +-- test inlining of immutable functions with PlaceHolderVars +explain (costs off) +select nt3.id +from nt3 as nt3 + left join + (select nt2.*, (nt2.b1 or i4 = 42) AS b3 + from nt2 as nt2 + left join + f_immutable_int4(0) i4 + on i4 = nt2.nt1_id + ) as ss2 + on ss2.id = nt3.nt2_id +where nt3.id = 1 and ss2.b3; + +drop function f_immutable_int4(int); + +-- test inlining when function returns composite + +create function mki8(bigint, bigint) returns int8_tbl as +$$select row($1,$2)::int8_tbl$$ language sql; + +create function mki4(int) returns int4_tbl as +$$select row($1)::int4_tbl$$ language sql; + +explain (verbose, costs off) +select * from mki8(1,2); +select * from mki8(1,2); + +explain (verbose, costs off) +select * from mki4(42); +select * from mki4(42); + +drop function mki8(bigint, bigint); +drop function mki4(int); + -- -- test extraction of restriction OR clauses from join OR clause -- (we used to only do this for indexable clauses) @@ -1028,6 +1166,17 @@ select * from where fault = 122 order by fault; +explain (costs off) +select * from +(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) +left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x +left join unnest(v1ys) as u1(u1y) on u1y = v2y; + +select * from +(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) +left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x +left join unnest(v1ys) as u1(u1y) on u1y = v2y; + -- -- test handling of potential equivalence clauses above outer joins -- @@ -1623,13 +1772,10 @@ select v.* from (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) left join int4_tbl z on z.f1 = x.q2, lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); -create temp table dual(); -insert into dual default values; -analyze dual; select v.* from (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) left join int4_tbl z on z.f1 = x.q2, - lateral (select x.q1,y.q1 from dual union all select x.q2,y.q2 from dual) v(vx,vy); + lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); explain (verbose, costs off) select * from @@ -1713,6 +1859,14 @@ select * from select * from (select 3 as z offset 0) z where z.z = x.x ) zz on zz.z = y.y; +-- check dummy rels with lateral references (bug #15694) +explain (verbose, costs off) +select * from int8_tbl i8 left join lateral + (select *, i8.q2 from int4_tbl where false) ss on true; +explain (verbose, costs off) +select * from int8_tbl i8 left join lateral + (select *, i8.q2 from int4_tbl i1, int4_tbl i2 where false) ss on true; + -- check handling of nested appendrels inside LATERAL select * from ((select 2 as v) union all (select 3 as v)) as q1 @@ -1944,15 +2098,20 @@ set enable_nestloop to 0; set enable_hashjoin to 0; set enable_sort to 0; --- create an index that will be preferred over the PK to perform the join +-- create indexes that will be preferred over the PKs to perform the join create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; +create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; + +-- need an additional row in j2, if we want j2_id1_idx to be preferred +insert into j2 values(1,2); +analyze j2; -explain (costs off) select * from j1 j1 -inner join j1 j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 +explain (costs off) select * from j1 +inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; -select * from j1 j1 -inner join j1 j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 +select * from j1 +inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; reset enable_nestloop; @@ -1984,473 +2143,3 @@ where exists (select 1 from j3 and t1.unique1 < 1; drop table j3; - --- --- exercises for the hash join code --- - -begin; - -set local min_parallel_table_scan_size = 0; -set local parallel_setup_cost = 0; - --- Extract bucket and batch counts from an explain analyze plan. In --- general we can't make assertions about how many batches (or --- buckets) will be required because it can vary, but we can in some --- special cases and we can check for growth. -create or replace function find_hash(node json) -returns json language plpgsql -as -$$ -declare - x json; - child json; -begin - if node->>'Node Type' = 'Hash' then - return node; - else - for child in select json_array_elements(node->'Plans') - loop - x := find_hash(child); - if x is not null then - return x; - end if; - end loop; - return null; - end if; -end; -$$; -create or replace function hash_join_batches(query text) -returns table (original int, final int) language plpgsql -as -$$ -declare - whole_plan json; - hash_node json; -begin - for whole_plan in - execute 'explain (analyze, format ''json'') ' || query - loop - hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); - original := hash_node->>'Original Hash Batches'; - final := hash_node->>'Hash Batches'; - return next; - end loop; -end; -$$; - --- Make a simple relation with well distributed keys and correctly --- estimated size. -create table simple as - select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; -alter table simple set (parallel_workers = 2); -analyze simple; - --- Make a relation whose size we will under-estimate. We want stats --- to say 1000 rows, but actually there are 20,000 rows. -create table bigger_than_it_looks as - select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; -alter table bigger_than_it_looks set (autovacuum_enabled = 'false'); -alter table bigger_than_it_looks set (parallel_workers = 2); -analyze bigger_than_it_looks; -update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks'; - --- Make a relation whose size we underestimate and that also has a --- kind of skew that breaks our batching scheme. We want stats to say --- 2 rows, but actually there are 20,000 rows with the same key. -create table extremely_skewed (id int, t text); -alter table extremely_skewed set (autovacuum_enabled = 'false'); -alter table extremely_skewed set (parallel_workers = 2); -analyze extremely_skewed; -insert into extremely_skewed - select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - from generate_series(1, 20000); -update pg_class - set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 - where relname = 'extremely_skewed'; - --- Make a relation with a couple of enormous tuples. -create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t; -alter table wide set (parallel_workers = 2); - --- The "optimal" case: the hash table fits in memory; we plan for 1 --- batch, we stick to that number, and peak memory usage stays within --- our work_mem budget - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '4MB'; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- The "good" case: batches required, but we plan the right number; we --- plan for some number of batches, and we stick to that number, and --- peak memory usage says within our work_mem budget - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '192kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join simple s using (id); -select count(*) from simple r join simple s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- The "bad" case: during execution we need to increase number of --- batches; in this case we plan for 1 batch, and increase at least a --- couple of times, and peak memory usage stays within our work_mem --- budget - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); -select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); -$$); -rollback to settings; - --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join bigger_than_it_looks s using (id); -select count(*) from simple r join bigger_than_it_looks s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join bigger_than_it_looks s using (id); -$$); -rollback to settings; - --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 1; -set local work_mem = '192kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join bigger_than_it_looks s using (id); -select count(*) from simple r join bigger_than_it_looks s using (id); -select original > 1 as initially_multibatch, final > original as increased_batches - from hash_join_batches( -$$ - select count(*) from simple r join bigger_than_it_looks s using (id); -$$); -rollback to settings; - --- The "ugly" case: increasing the number of batches during execution --- doesn't help, so stop trying to fit in work_mem and hope for the --- best; in this case we plan for 1 batch, increases just once and --- then stop increasing because that didn't help at all, so we blow --- right through the work_mem budget and hope for the best... - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -set local work_mem = '128kB'; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); -select count(*) from simple r join extremely_skewed s using (id); -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); -rollback to settings; - --- parallel with parallel-oblivious hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '128kB'; -set local enable_parallel_hash = off; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); -select count(*) from simple r join extremely_skewed s using (id); -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); -rollback to settings; - --- parallel with parallel-aware hash join -savepoint settings; -set local max_parallel_workers_per_gather = 1; -set local work_mem = '128kB'; -set local enable_parallel_hash = on; -explain (costs off) - select count(*) from simple r join extremely_skewed s using (id); -select count(*) from simple r join extremely_skewed s using (id); -select * from hash_join_batches( -$$ - select count(*) from simple r join extremely_skewed s using (id); -$$); -rollback to settings; - --- A couple of other hash join tests unrelated to work_mem management. - --- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate -savepoint settings; -set local max_parallel_workers_per_gather = 2; -set local work_mem = '4MB'; -set local parallel_leader_participation = off; -select * from hash_join_batches( -$$ - select count(*) from simple r join simple s using (id); -$$); -rollback to settings; - --- Exercise rescans. We'll turn off parallel_leader_participation so --- that we can check that instrumentation comes back correctly. - -create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t; -alter table join_foo set (parallel_workers = 0); -create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t; -alter table join_bar set (parallel_workers = 2); - --- multi-batch with rescan, parallel-oblivious -savepoint settings; -set enable_parallel_hash = off; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '64kB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); -rollback to settings; - --- single-batch with rescan, parallel-oblivious -savepoint settings; -set enable_parallel_hash = off; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); -rollback to settings; - --- multi-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '64kB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); -rollback to settings; - --- single-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); -rollback to settings; - --- A full outer join where every record is matched. - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); -select count(*) from simple r full outer join simple s using (id); -rollback to settings; - --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); -select count(*) from simple r full outer join simple s using (id); -rollback to settings; - --- An full outer join where every record is not matched. - --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); -rollback to settings; - --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); -rollback to settings; - --- exercise special code paths for huge tuples (note use of non-strict --- expression and left join required to get the detoasted tuple into --- the hash table) - --- parallel with parallel-aware hash join (hits ExecParallelHashLoadTuple and --- sts_puttuple oversized tuple cases because it's multi-batch) -savepoint settings; -set max_parallel_workers_per_gather = 2; -set enable_parallel_hash = on; -set work_mem = '128kB'; -explain (costs off) - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); -select length(max(s.t)) -from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); -select final > 1 as multibatch - from hash_join_batches( -$$ - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); -$$); -rollback to settings; - -rollback; diff --git a/src/test/regress/sql/join_hash.sql b/src/test/regress/sql/join_hash.sql new file mode 100644 index 00000000000..68c1a8c7b65 --- /dev/null +++ b/src/test/regress/sql/join_hash.sql @@ -0,0 +1,540 @@ +-- +-- exercises for the hash join code +-- + +begin; + +set local min_parallel_table_scan_size = 0; +set local parallel_setup_cost = 0; +set local enable_hashjoin = on; + +-- Extract bucket and batch counts from an explain analyze plan. In +-- general we can't make assertions about how many batches (or +-- buckets) will be required because it can vary, but we can in some +-- special cases and we can check for growth. +create or replace function find_hash(node json) +returns json language plpgsql +as +$$ +declare + x json; + child json; +begin + if node->>'Node Type' = 'Hash' then + return node; + else + for child in select json_array_elements(node->'Plans') + loop + x := find_hash(child); + if x is not null then + return x; + end if; + end loop; + return null; + end if; +end; +$$; +create or replace function hash_join_batches(query text) +returns table (original int, final int) language plpgsql +as +$$ +declare + whole_plan json; + hash_node json; +begin + for whole_plan in + execute 'explain (analyze, format ''json'') ' || query + loop + hash_node := find_hash(json_extract_path(whole_plan, '0', 'Plan')); + original := hash_node->>'Original Hash Batches'; + final := hash_node->>'Hash Batches'; + return next; + end loop; +end; +$$; + +-- Make a simple relation with well distributed keys and correctly +-- estimated size. +create table simple as + select generate_series(1, 20000) AS id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +alter table simple set (parallel_workers = 2); +analyze simple; + +-- Make a relation whose size we will under-estimate. We want stats +-- to say 1000 rows, but actually there are 20,000 rows. +create table bigger_than_it_looks as + select generate_series(1, 20000) as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; +alter table bigger_than_it_looks set (autovacuum_enabled = 'false'); +alter table bigger_than_it_looks set (parallel_workers = 2); +analyze bigger_than_it_looks; +update pg_class set reltuples = 1000 where relname = 'bigger_than_it_looks'; + +-- Make a relation whose size we underestimate and that also has a +-- kind of skew that breaks our batching scheme. We want stats to say +-- 2 rows, but actually there are 20,000 rows with the same key. +create table extremely_skewed (id int, t text); +alter table extremely_skewed set (autovacuum_enabled = 'false'); +alter table extremely_skewed set (parallel_workers = 2); +analyze extremely_skewed; +insert into extremely_skewed + select 42 as id, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' + from generate_series(1, 20000); +update pg_class + set reltuples = 2, relpages = pg_relation_size('extremely_skewed') / 8192 + where relname = 'extremely_skewed'; + +-- Make a relation with a couple of enormous tuples. +create table wide as select generate_series(1, 2) as id, rpad('', 320000, 'x') as t; +alter table wide set (parallel_workers = 2); + +-- The "optimal" case: the hash table fits in memory; we plan for 1 +-- batch, we stick to that number, and peak memory usage stays within +-- our work_mem budget + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '4MB'; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- The "good" case: batches required, but we plan the right number; we +-- plan for some number of batches, and we stick to that number, and +-- peak memory usage says within our work_mem budget + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '192kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join simple s using (id); +select count(*) from simple r join simple s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- The "bad" case: during execution we need to increase number of +-- batches; in this case we plan for 1 batch, and increase at least a +-- couple of times, and peak memory usage stays within our work_mem +-- budget + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) FROM simple r JOIN bigger_than_it_looks s USING (id); +$$); +rollback to settings; + +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id); +select count(*) from simple r join bigger_than_it_looks s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); +rollback to settings; + +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 1; +set local work_mem = '192kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join bigger_than_it_looks s using (id); +select count(*) from simple r join bigger_than_it_looks s using (id); +select original > 1 as initially_multibatch, final > original as increased_batches + from hash_join_batches( +$$ + select count(*) from simple r join bigger_than_it_looks s using (id); +$$); +rollback to settings; + +-- The "ugly" case: increasing the number of batches during execution +-- doesn't help, so stop trying to fit in work_mem and hope for the +-- best; in this case we plan for 1 batch, increases just once and +-- then stop increasing because that didn't help at all, so we blow +-- right through the work_mem budget and hope for the best... + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +set local work_mem = '128kB'; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); +select count(*) from simple r join extremely_skewed s using (id); +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); +rollback to settings; + +-- parallel with parallel-oblivious hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '128kB'; +set local enable_parallel_hash = off; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); +select count(*) from simple r join extremely_skewed s using (id); +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); +rollback to settings; + +-- parallel with parallel-aware hash join +savepoint settings; +set local max_parallel_workers_per_gather = 1; +set local work_mem = '128kB'; +set local enable_parallel_hash = on; +explain (costs off) + select count(*) from simple r join extremely_skewed s using (id); +select count(*) from simple r join extremely_skewed s using (id); +select * from hash_join_batches( +$$ + select count(*) from simple r join extremely_skewed s using (id); +$$); +rollback to settings; + +-- A couple of other hash join tests unrelated to work_mem management. + +-- Check that EXPLAIN ANALYZE has data even if the leader doesn't participate +savepoint settings; +set local max_parallel_workers_per_gather = 2; +set local work_mem = '4MB'; +set local parallel_leader_participation = off; +select * from hash_join_batches( +$$ + select count(*) from simple r join simple s using (id); +$$); +rollback to settings; + +-- Exercise rescans. We'll turn off parallel_leader_participation so +-- that we can check that instrumentation comes back correctly. + +create table join_foo as select generate_series(1, 3) as id, 'xxxxx'::text as t; +alter table join_foo set (parallel_workers = 0); +create table join_bar as select generate_series(1, 10000) as id, 'xxxxx'::text as t; +alter table join_bar set (parallel_workers = 2); + +-- multi-batch with rescan, parallel-oblivious +savepoint settings; +set enable_parallel_hash = off; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '64kB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); +rollback to settings; + +-- single-batch with rescan, parallel-oblivious +savepoint settings; +set enable_parallel_hash = off; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '4MB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); +rollback to settings; + +-- multi-batch with rescan, parallel-aware +savepoint settings; +set enable_parallel_hash = on; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '64kB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); +rollback to settings; + +-- single-batch with rescan, parallel-aware +savepoint settings; +set enable_parallel_hash = on; +set parallel_leader_participation = off; +set min_parallel_table_scan_size = 0; +set parallel_setup_cost = 0; +set parallel_tuple_cost = 0; +set max_parallel_workers_per_gather = 2; +set enable_material = off; +set enable_mergejoin = off; +set work_mem = '4MB'; +explain (costs off) + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +select final > 1 as multibatch + from hash_join_batches( +$$ + select count(*) from join_foo + left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss + on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; +$$); +rollback to settings; + +-- A full outer join where every record is matched. + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +explain (costs off) + select count(*) from simple r full outer join simple s using (id); +select count(*) from simple r full outer join simple s using (id); +rollback to settings; + +-- parallelism not possible with parallel-oblivious outer hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +explain (costs off) + select count(*) from simple r full outer join simple s using (id); +select count(*) from simple r full outer join simple s using (id); +rollback to settings; + +-- An full outer join where every record is not matched. + +-- non-parallel +savepoint settings; +set local max_parallel_workers_per_gather = 0; +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); +rollback to settings; + +-- parallelism not possible with parallel-oblivious outer hash join +savepoint settings; +set local max_parallel_workers_per_gather = 2; +explain (costs off) + select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); +select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); +rollback to settings; + +-- exercise special code paths for huge tuples (note use of non-strict +-- expression and left join required to get the detoasted tuple into +-- the hash table) + +-- parallel with parallel-aware hash join (hits ExecParallelHashLoadTuple and +-- sts_puttuple oversized tuple cases because it's multi-batch) +savepoint settings; +set max_parallel_workers_per_gather = 2; +set enable_parallel_hash = on; +set work_mem = '128kB'; +explain (costs off) + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); +select length(max(s.t)) +from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); +select final > 1 as multibatch + from hash_join_batches( +$$ + select length(max(s.t)) + from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); +$$); +rollback to settings; + +rollback; + + +-- Verify that hash key expressions reference the correct +-- nodes. Hashjoin's hashkeys need to reference its outer plan, Hash's +-- need to reference Hash's outer plan (which is below HashJoin's +-- inner plan). It's not trivial to verify that the references are +-- correct (we don't display the hashkeys themselves), but if the +-- hashkeys contain subplan references, those will be displayed. Force +-- subplans to appear just about everywhere. +-- +-- Bug report: +-- https://www.postgresql.org/message-id/CAPpHfdvGVegF_TKKRiBrSmatJL2dR9uwFCuR%2BteQ_8tEXU8mxg%40mail.gmail.com +-- +BEGIN; +SET LOCAL enable_sort = OFF; -- avoid mergejoins +SET LOCAL from_collapse_limit = 1; -- allows easy changing of join order + +CREATE TABLE hjtest_1 (a text, b int, id int, c bool); +CREATE TABLE hjtest_2 (a bool, id int, b text, c int); + +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false); -- matches +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false); -- fails id join condition +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false); -- fails < 50 +INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2); -- matches +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7); -- fails id join condition +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90); -- fails < 55 +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) +INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1); -- fails hjtest_1.a <> hjtest_2.b; + +EXPLAIN (COSTS OFF, VERBOSE) +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_1, hjtest_2 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +EXPLAIN (COSTS OFF, VERBOSE) +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 +FROM hjtest_2, hjtest_1 +WHERE + hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) + AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) + AND (SELECT hjtest_1.b * 5) < 50 + AND (SELECT hjtest_2.c * 5) < 55 + AND hjtest_1.a <> hjtest_2.b; + +ROLLBACK; diff --git a/src/test/regress/sql/json.sql b/src/test/regress/sql/json.sql index 4e65bb0d444..20354f04e37 100644 --- a/src/test/regress/sql/json.sql +++ b/src/test/regress/sql/json.sql @@ -104,9 +104,13 @@ SELECT row_to_json(row((select array_agg(x) as d from generate_series(5,10) x)), -- anyarray column -select to_json(histogram_bounds) histogram_bounds +analyze rows; + +select attname, to_json(histogram_bounds) histogram_bounds from pg_stats -where attname = 'tmplname' and tablename = 'pg_pltemplate'; +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; -- to_json, timestamps @@ -522,6 +526,8 @@ SELECT rec FROM json_populate_record( -- anonymous record type SELECT json_populate_record(null::record, '{"x": 0, "y": 1}'); SELECT json_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); +SELECT * FROM + json_populate_record(null::record, '{"x": 776}') AS (x int, y int); -- composite domain SELECT json_populate_record(null::j_ordered_pair, '{"x": 0, "y": 1}'); @@ -547,6 +553,17 @@ select * from json_populate_recordset(row('def',99,null)::jpop,'[{"a":[100,200,3 -- anonymous record type SELECT json_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); +SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); +SELECT * FROM + json_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + +-- empty array is a corner case +SELECT json_populate_recordset(null::record, '[]'); +SELECT json_populate_recordset(row(1,2), '[]'); +SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q; +SELECT * FROM + json_populate_recordset(null::record, '[]') AS (x int, y int); -- composite domain SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]'); @@ -735,6 +752,13 @@ select * from json_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); select * from json_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); select * from json_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); +select * from json_to_record('{"out": {"key": 1}}') as x(out json); +select * from json_to_record('{"out": [{"key": 1}]}') as x(out json); +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out json); +select * from json_to_record('{"out": {"key": 1}}') as x(out jsonb); +select * from json_to_record('{"out": [{"key": 1}]}') as x(out jsonb); +select * from json_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + -- json_strip_nulls select json_strip_nulls(null); @@ -781,7 +805,7 @@ select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '"boolean"'); select json_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::json, '["string", "numeric"]'); --- ts_vector corner cases +-- to_tsvector corner cases select to_tsvector('""'::json); select to_tsvector('{}'::json); select to_tsvector('[]'::json); diff --git a/src/test/regress/sql/jsonb.sql b/src/test/regress/sql/jsonb.sql index d0ab6026ec5..efd4c451853 100644 --- a/src/test/regress/sql/jsonb.sql +++ b/src/test/regress/sql/jsonb.sql @@ -64,9 +64,17 @@ SELECT array_to_json(ARRAY [jsonb '{"a":1}', jsonb '{"b":[2,3]}']); -- anyarray column -select to_jsonb(histogram_bounds) histogram_bounds +CREATE TEMP TABLE rows AS +SELECT x, 'txt' || x as y +FROM generate_series(1,3) AS x; + +analyze rows; + +select attname, to_jsonb(histogram_bounds) histogram_bounds from pg_stats -where attname = 'tmplname' and tablename = 'pg_pltemplate'; +where tablename = 'rows' and + schemaname = pg_my_temp_schema()::regnamespace::text +order by 1; -- to_jsonb, timestamps @@ -90,10 +98,6 @@ select to_jsonb(timestamptz '-Infinity'); --jsonb_agg -CREATE TEMP TABLE rows AS -SELECT x, 'txt' || x as y -FROM generate_series(1,3) AS x; - SELECT jsonb_agg(q) FROM ( SELECT $$a$$ || x AS b, y AS c, ARRAY[ROW(x.*,ARRAY[1,2,3]), @@ -642,6 +646,8 @@ SELECT rec FROM jsonb_populate_record( -- anonymous record type SELECT jsonb_populate_record(null::record, '{"x": 0, "y": 1}'); SELECT jsonb_populate_record(row(1,2), '{"f1": 0, "f2": 1}'); +SELECT * FROM + jsonb_populate_record(null::record, '{"x": 776}') AS (x int, y int); -- composite domain SELECT jsonb_populate_record(null::jb_ordered_pair, '{"x": 0, "y": 1}'); @@ -663,6 +669,17 @@ SELECT * FROM jsonb_populate_recordset(row('def',99,NULL)::jbpop,'[{"a":[100,200 -- anonymous record type SELECT jsonb_populate_recordset(null::record, '[{"x": 0, "y": 1}]'); SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]'); +SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]') +FROM (VALUES (1),(2)) v(i); +SELECT * FROM + jsonb_populate_recordset(null::record, '[{"x": 776}]') AS (x int, y int); + +-- empty array is a corner case +SELECT jsonb_populate_recordset(null::record, '[]'); +SELECT jsonb_populate_recordset(row(1,2), '[]'); +SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q; +SELECT * FROM + jsonb_populate_recordset(null::record, '[]') AS (x int, y int); -- composite domain SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]'); @@ -702,6 +719,13 @@ select * from jsonb_to_record('{"ia2": [1, 2, 3]}') as x(ia2 int[][]); select * from jsonb_to_record('{"ia2": [[1, 2], [3, 4]]}') as x(ia2 int4[][]); select * from jsonb_to_record('{"ia2": [[[1], [2], [3]]]}') as x(ia2 int4[][]); +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out json); +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out json); +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out json); +select * from jsonb_to_record('{"out": {"key": 1}}') as x(out jsonb); +select * from jsonb_to_record('{"out": [{"key": 1}]}') as x(out jsonb); +select * from jsonb_to_record('{"out": "{\"key\": 1}"}') as x(out jsonb); + -- test type info caching in jsonb_populate_record() CREATE TEMP TABLE jsbpoptest (js jsonb); @@ -733,6 +757,24 @@ SELECT count(*) FROM testjsonb WHERE j ? 'public'; SELECT count(*) FROM testjsonb WHERE j ? 'bar'; SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled']; SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; +SELECT count(*) FROM testjsonb WHERE j @? '$'; +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; CREATE INDEX jidx ON testjsonb USING gin (j); SET enable_seqscan = off; @@ -751,6 +793,39 @@ SELECT count(*) FROM testjsonb WHERE j ? 'bar'; SELECT count(*) FROM testjsonb WHERE j ?| ARRAY['public','disabled']; SELECT count(*) FROM testjsonb WHERE j ?& ARRAY['public','disabled']; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.bar)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) || exists($.disabled)'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.public) && exists($.disabled)'; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$'; +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + -- array exists - array elements should behave as keys (for GIN index scans too) CREATE INDEX jidx_array ON testjsonb USING gin((j->'array')); SELECT count(*) from testjsonb WHERE j->'array' ? 'bar'; @@ -800,6 +875,34 @@ SELECT count(*) FROM testjsonb WHERE j @> '{"age":25.0}'; -- exercise GIN_SEARCH_MODE_ALL SELECT count(*) FROM testjsonb WHERE j @> '{}'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == null'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.wait == null))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.wait ? (@ == null))'; +SELECT count(*) FROM testjsonb WHERE j @@ '"CC" == $.wait'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.wait == "CC" && true == $.public'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.age == 25.0'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "foo"'; +SELECT count(*) FROM testjsonb WHERE j @@ '$.array[*] == "bar"'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($ ? (@.array[*] == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array ? (@[*] == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($.array[*] ? (@ == "bar"))'; +SELECT count(*) FROM testjsonb WHERE j @@ 'exists($)'; + +EXPLAIN (COSTS OFF) +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? (@ == null)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.wait ? ("CC" == @)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.wait == "CC" && true == @.public)'; +SELECT count(*) FROM testjsonb WHERE j @? '$.age ? (@ == 25)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.age == 25.0)'; +SELECT count(*) FROM testjsonb WHERE j @? '$ ? (@.array[*] == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$.array ? (@[*] == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$.array[*] ? (@ == "bar")'; +SELECT count(*) FROM testjsonb WHERE j @? '$'; +SELECT count(*) FROM testjsonb WHERE j @? '$.public'; +SELECT count(*) FROM testjsonb WHERE j @? '$.bar'; + RESET enable_seqscan; DROP INDEX jidx; @@ -1107,7 +1210,7 @@ select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d" select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '"boolean"'); select jsonb_to_tsvector('english', '{"a": "aaa in bbb", "b": 123, "c": 456, "d": true, "f": false, "g": null}'::jsonb, '["string", "numeric"]'); --- ts_vector corner cases +-- to_tsvector corner cases select to_tsvector('""'::jsonb); select to_tsvector('{}'::jsonb); select to_tsvector('[]'::jsonb); diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql new file mode 100644 index 00000000000..246e38b9edd --- /dev/null +++ b/src/test/regress/sql/jsonb_jsonpath.sql @@ -0,0 +1,577 @@ +select jsonb '{"a": 12}' @? '$'; +select jsonb '{"a": 12}' @? '1'; +select jsonb '{"a": 12}' @? '$.a.b'; +select jsonb '{"a": 12}' @? '$.b'; +select jsonb '{"a": 12}' @? '$.a + 2'; +select jsonb '{"a": 12}' @? '$.b + 2'; +select jsonb '{"a": {"a": 12}}' @? '$.a.a'; +select jsonb '{"a": {"a": 12}}' @? '$.*.a'; +select jsonb '{"b": {"a": 12}}' @? '$.*.a'; +select jsonb '{"b": {"a": 12}}' @? '$.*.b'; +select jsonb '{"b": {"a": 12}}' @? 'strict $.*.b'; +select jsonb '{}' @? '$.*'; +select jsonb '{"a": 1}' @? '$.*'; +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{1}'; +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{2}'; +select jsonb '{"a": {"b": 1}}' @? 'lax $.**{3}'; +select jsonb '[]' @? '$[*]'; +select jsonb '[1]' @? '$[*]'; +select jsonb '[1]' @? '$[1]'; +select jsonb '[1]' @? 'strict $[1]'; +select jsonb_path_query('[1]', 'strict $[1]'); +select jsonb_path_query('[1]', 'strict $[1]', silent => true); +select jsonb '[1]' @? 'lax $[10000000000000000]'; +select jsonb '[1]' @? 'strict $[10000000000000000]'; +select jsonb_path_query('[1]', 'lax $[10000000000000000]'); +select jsonb_path_query('[1]', 'strict $[10000000000000000]'); +select jsonb '[1]' @? '$[0]'; +select jsonb '[1]' @? '$[0.3]'; +select jsonb '[1]' @? '$[0.5]'; +select jsonb '[1]' @? '$[0.9]'; +select jsonb '[1]' @? '$[1.2]'; +select jsonb '[1]' @? 'strict $[1.2]'; +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] > @.b[*])'; +select jsonb '{"a": [1,2,3], "b": [3,4,5]}' @? '$ ? (@.a[*] >= @.b[*])'; +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? '$ ? (@.a[*] >= @.b[*])'; +select jsonb '{"a": [1,2,3], "b": [3,4,"5"]}' @? 'strict $ ? (@.a[*] >= @.b[*])'; +select jsonb '{"a": [1,2,3], "b": [3,4,null]}' @? '$ ? (@.a[*] >= @.b[*])'; +select jsonb '1' @? '$ ? ((@ == "1") is unknown)'; +select jsonb '1' @? '$ ? ((@ == 1) is unknown)'; +select jsonb '[{"a": 1}, {"a": 2}]' @? '$[0 to 1] ? (@.a > 1)'; + +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => false); +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'lax $[*].a', silent => true); +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => false); +select jsonb_path_exists('[{"a": 1}, {"a": 2}, 3]', 'strict $[*].a', silent => true); + +select jsonb_path_query('1', 'lax $.a'); +select jsonb_path_query('1', 'strict $.a'); +select jsonb_path_query('1', 'strict $.*'); +select jsonb_path_query('1', 'strict $.a', silent => true); +select jsonb_path_query('1', 'strict $.*', silent => true); +select jsonb_path_query('[]', 'lax $.a'); +select jsonb_path_query('[]', 'strict $.a'); +select jsonb_path_query('[]', 'strict $.a', silent => true); +select jsonb_path_query('{}', 'lax $.a'); +select jsonb_path_query('{}', 'strict $.a'); +select jsonb_path_query('{}', 'strict $.a', silent => true); + +select jsonb_path_query('1', 'strict $[1]'); +select jsonb_path_query('1', 'strict $[*]'); +select jsonb_path_query('[]', 'strict $[1]'); +select jsonb_path_query('[]', 'strict $["a"]'); +select jsonb_path_query('1', 'strict $[1]', silent => true); +select jsonb_path_query('1', 'strict $[*]', silent => true); +select jsonb_path_query('[]', 'strict $[1]', silent => true); +select jsonb_path_query('[]', 'strict $["a"]', silent => true); + +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.a'); +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.b'); +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', '$.*'); +select jsonb_path_query('{"a": 12, "b": {"a": 13}}', 'lax $.*.a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[*].*'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[1].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[2].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0,1].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}]', 'lax $[0 to 10 / 0].a'); +select jsonb_path_query('[12, {"a": 13}, {"b": 14}, "ccc", true]', '$[2.5 - 1 to $.size() - 2]'); +select jsonb_path_query('1', 'lax $[0]'); +select jsonb_path_query('1', 'lax $[*]'); +select jsonb_path_query('[1]', 'lax $[0]'); +select jsonb_path_query('[1]', 'lax $[*]'); +select jsonb_path_query('[1,2,3]', 'lax $[*]'); +select jsonb_path_query('[1,2,3]', 'strict $[*].a'); +select jsonb_path_query('[1,2,3]', 'strict $[*].a', silent => true); +select jsonb_path_query('[]', '$[last]'); +select jsonb_path_query('[]', '$[last ? (exists(last))]'); +select jsonb_path_query('[]', 'strict $[last]'); +select jsonb_path_query('[]', 'strict $[last]', silent => true); +select jsonb_path_query('[1]', '$[last]'); +select jsonb_path_query('[1,2,3]', '$[last]'); +select jsonb_path_query('[1,2,3]', '$[last - 1]'); +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "number")]'); +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]'); +select jsonb_path_query('[1,2,3]', '$[last ? (@.type() == "string")]', silent => true); + +select * from jsonb_path_query('{"a": 10}', '$'); +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)'); +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '1'); +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '[{"value" : 13}]'); +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 13}'); +select * from jsonb_path_query('{"a": 10}', '$ ? (@.a < $value)', '{"value" : 8}'); +select * from jsonb_path_query('{"a": 10}', '$.a ? (@ < $value)', '{"value" : 13}'); +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[*] ? (@ < $value)', '{"value" : 13}'); +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0,1] ? (@ < $x.value)', '{"x": {"value" : 13}}'); +select * from jsonb_path_query('[10,11,12,13,14,15]', '$[0 to 2] ? (@ < $value)', '{"value" : 15}'); +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == "1")'); +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : "1"}'); +select * from jsonb_path_query('[1,"1",2,"2",null]', '$[*] ? (@ == $value)', '{"value" : null}'); +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ != null)'); +select * from jsonb_path_query('[1, "2", null]', '$[*] ? (@ == null)'); +select * from jsonb_path_query('{}', '$ ? (@ == @)'); +select * from jsonb_path_query('[]', 'strict $ ? (@ == @)'); + +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{2 to last}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{3 to last}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{last}'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{0 to last}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to last}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"b": 1}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{0 to last}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to last}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{1 to 2}.b ? (@ > 0)'); +select jsonb_path_query('{"a": {"c": {"b": 1}}}', 'lax $.**{2 to 3}.b ? (@ > 0)'); + +select jsonb '{"a": {"b": 1}}' @? '$.**.b ? ( @ > 0)'; +select jsonb '{"a": {"b": 1}}' @? '$.**{0}.b ? ( @ > 0)'; +select jsonb '{"a": {"b": 1}}' @? '$.**{1}.b ? ( @ > 0)'; +select jsonb '{"a": {"b": 1}}' @? '$.**{0 to last}.b ? ( @ > 0)'; +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to last}.b ? ( @ > 0)'; +select jsonb '{"a": {"b": 1}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{0 to last}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to last}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{1 to 2}.b ? ( @ > 0)'; +select jsonb '{"a": {"c": {"b": 1}}}' @? '$.**{2 to 3}.b ? ( @ > 0)'; + +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x))'); +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.y))'); +select jsonb_path_query('{"g": {"x": 2}}', '$.g ? (exists (@.x ? (@ >= 2) ))'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x))'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? (exists (@.x + "3"))'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'lax $.g ? ((exists (@.x + "3")) is unknown)'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? (exists (@.x))'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g[*] ? ((exists (@.x)) is unknown)'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? (exists (@[*].x))'); +select jsonb_path_query('{"g": [{"x": 2}, {"y": 3}]}', 'strict $.g ? ((exists (@[*].x)) is unknown)'); + +--test ternary logic +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true && $y == true) || + @ == false && !($x == true && $y == true) || + @ == null && ($x == true && $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x && y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + +select + x, y, + jsonb_path_query( + '[true, false, null]', + '$[*] ? (@ == true && ($x == true || $y == true) || + @ == false && !($x == true || $y == true) || + @ == null && ($x == true || $y == true) is unknown)', + jsonb_build_object('x', x, 'y', y) + ) as "x || y" +from + (values (jsonb 'true'), ('false'), ('"null"')) x(x), + (values (jsonb 'true'), ('false'), ('"null"')) y(y); + +select jsonb '{"a": 1, "b":1}' @? '$ ? (@.a == @.b)'; +select jsonb '{"c": {"a": 1, "b":1}}' @? '$ ? (@.a == @.b)'; +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? (@.a == @.b)'; +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.c ? ($.c.a == @.b)'; +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.* ? (@.a == @.b)'; +select jsonb '{"a": 1, "b":1}' @? '$.** ? (@.a == @.b)'; +select jsonb '{"c": {"a": 1, "b":1}}' @? '$.** ? (@.a == @.b)'; + +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == 1 + 1)'); +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (1 + 1))'); +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == @.b + 1)'); +select jsonb_path_query('{"c": {"a": 2, "b":1}}', '$.** ? (@.a == (@.b + 1))'); +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - 1)'; +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -1)'; +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == -@.b)'; +select jsonb '{"c": {"a": -1, "b":1}}' @? '$.** ? (@.a == - @.b)'; +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - @.b)'; +select jsonb '{"c": {"a": 2, "b":1}}' @? '$.** ? (@.a == 1 - - @.b)'; +select jsonb '{"c": {"a": 0, "b":1}}' @? '$.** ? (@.a == 1 - +@.b)'; +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +2)'; +select jsonb '[1,2,3]' @? '$ ? (+@[*] > +3)'; +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -2)'; +select jsonb '[1,2,3]' @? '$ ? (-@[*] < -3)'; +select jsonb '1' @? '$ ? ($ > 0)'; + +-- arithmetic errors +select jsonb_path_query('[1,2,0,3]', '$[*] ? (2 / @ > 0)'); +select jsonb_path_query('[1,2,0,3]', '$[*] ? ((2 / @ > 0) is unknown)'); +select jsonb_path_query('0', '1 / $'); +select jsonb_path_query('0', '1 / $ + 2'); +select jsonb_path_query('0', '-(3 + 1 % $)'); +select jsonb_path_query('1', '$ + "2"'); +select jsonb_path_query('[1, 2]', '3 * $'); +select jsonb_path_query('"a"', '-$'); +select jsonb_path_query('[1,"2",3]', '+$'); +select jsonb_path_query('1', '$ + "2"', silent => true); +select jsonb_path_query('[1, 2]', '3 * $', silent => true); +select jsonb_path_query('"a"', '-$', silent => true); +select jsonb_path_query('[1,"2",3]', '+$', silent => true); +select jsonb '["1",2,0,3]' @? '-$[*]'; +select jsonb '[1,"2",0,3]' @? '-$[*]'; +select jsonb '["1",2,0,3]' @? 'strict -$[*]'; +select jsonb '[1,"2",0,3]' @? 'strict -$[*]'; + +-- unwrapping of operator arguments in lax mode +select jsonb_path_query('{"a": [2]}', 'lax $.a * 3'); +select jsonb_path_query('{"a": [2]}', 'lax $.a + 3'); +select jsonb_path_query('{"a": [2, 3, 4]}', 'lax -$.a'); +-- should fail +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3'); +select jsonb_path_query('{"a": [1, 2]}', 'lax $.a * 3', silent => true); + +-- extension: boolean expressions +select jsonb_path_query('2', '$ > 1'); +select jsonb_path_query('2', '$ <= 1'); +select jsonb_path_query('2', '$ == "2"'); +select jsonb '2' @? '$ == "2"'; + +select jsonb '2' @@ '$ > 1'; +select jsonb '2' @@ '$ <= 1'; +select jsonb '2' @@ '$ == "2"'; +select jsonb '2' @@ '1'; +select jsonb '{}' @@ '$'; +select jsonb '[]' @@ '$'; +select jsonb '[1,2,3]' @@ '$[*]'; +select jsonb '[]' @@ '$[*]'; +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] > $x) [1]', '{"x": 1}'); +select jsonb_path_match('[[1, true], [2, false]]', 'strict $[*] ? (@[0] < $x) [1]', '{"x": 2}'); + +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => false); +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'lax exists($[*].a)', silent => true); +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => false); +select jsonb_path_match('[{"a": 1}, {"a": 2}, 3]', 'strict exists($[*].a)', silent => true); + + +select jsonb_path_query('[null,1,true,"a",[],{}]', '$.type()'); +select jsonb_path_query('[null,1,true,"a",[],{}]', 'lax $.type()'); +select jsonb_path_query('[null,1,true,"a",[],{}]', '$[*].type()'); +select jsonb_path_query('null', 'null.type()'); +select jsonb_path_query('null', 'true.type()'); +select jsonb_path_query('null', '(123).type()'); +select jsonb_path_query('null', '"123".type()'); + +select jsonb_path_query('{"a": 2}', '($.a - 5).abs() + 10'); +select jsonb_path_query('{"a": 2.5}', '-($.a * $.a).floor() % 4.3'); +select jsonb_path_query('[1, 2, 3]', '($[*] > 2) ? (@ == true)'); +select jsonb_path_query('[1, 2, 3]', '($[*] > 3).type()'); +select jsonb_path_query('[1, 2, 3]', '($[*].a > 3).type()'); +select jsonb_path_query('[1, 2, 3]', 'strict ($[*].a > 3).type()'); + +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()'); +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'strict $[*].size()', silent => true); +select jsonb_path_query('[1,null,true,"11",[],[1],[1,2,3],{},{"a":1,"b":2}]', 'lax $[*].size()'); + +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].abs()'); +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].floor()'); +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling()'); +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs()'); +select jsonb_path_query('[0, 1, -2, -3.4, 5.6]', '$[*].ceiling().abs().type()'); + +select jsonb_path_query('[{},1]', '$[*].keyvalue()'); +select jsonb_path_query('[{},1]', '$[*].keyvalue()', silent => true); +select jsonb_path_query('{}', '$.keyvalue()'); +select jsonb_path_query('{"a": 1, "b": [1, 2], "c": {"a": "bbb"}}', '$.keyvalue()'); +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', '$[*].keyvalue()'); +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue()'); +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'lax $.keyvalue()'); +select jsonb_path_query('[{"a": 1, "b": [1, 2]}, {"c": {"a": "bbb"}}]', 'strict $.keyvalue().a'); +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue()'; +select jsonb '{"a": 1, "b": [1, 2]}' @? 'lax $.keyvalue().key'; + +select jsonb_path_query('null', '$.double()'); +select jsonb_path_query('true', '$.double()'); +select jsonb_path_query('null', '$.double()', silent => true); +select jsonb_path_query('true', '$.double()', silent => true); +select jsonb_path_query('[]', '$.double()'); +select jsonb_path_query('[]', 'strict $.double()'); +select jsonb_path_query('{}', '$.double()'); +select jsonb_path_query('[]', 'strict $.double()', silent => true); +select jsonb_path_query('{}', '$.double()', silent => true); +select jsonb_path_query('1.23', '$.double()'); +select jsonb_path_query('"1.23"', '$.double()'); +select jsonb_path_query('"1.23aaa"', '$.double()'); +select jsonb_path_query('"nan"', '$.double()'); +select jsonb_path_query('"NaN"', '$.double()'); +select jsonb_path_query('"inf"', '$.double()'); +select jsonb_path_query('"-inf"', '$.double()'); +select jsonb_path_query('"inf"', '$.double()', silent => true); +select jsonb_path_query('"-inf"', '$.double()', silent => true); + +select jsonb_path_query('{}', '$.abs()'); +select jsonb_path_query('true', '$.floor()'); +select jsonb_path_query('"1.2"', '$.ceiling()'); +select jsonb_path_query('{}', '$.abs()', silent => true); +select jsonb_path_query('true', '$.floor()', silent => true); +select jsonb_path_query('"1.2"', '$.ceiling()', silent => true); + +select jsonb_path_query('["", "a", "abc", "abcabc"]', '$[*] ? (@ starts with "abc")'); +select jsonb_path_query('["", "a", "abc", "abcabc"]', 'strict $ ? (@[*] starts with "abc")'); +select jsonb_path_query('["", "a", "abd", "abdabc"]', 'strict $ ? (@[*] starts with "abc")'); +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? (@[*] starts with "abc")'); +select jsonb_path_query('["abc", "abcabc", null, 1]', 'strict $ ? ((@[*] starts with "abc") is unknown)'); +select jsonb_path_query('[[null, 1, "abc", "abcabc"]]', 'lax $ ? (@[*] starts with "abc")'); +select jsonb_path_query('[[null, 1, "abd", "abdabc"]]', 'lax $ ? ((@[*] starts with "abc") is unknown)'); +select jsonb_path_query('[null, 1, "abd", "abdabc"]', 'lax $[*] ? ((@ starts with "abc") is unknown)'); + +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c")'); +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "i")'); +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "m")'); +select jsonb_path_query('[null, 1, "abc", "abd", "aBdC", "abdacb", "babc", "adc\nabc", "ab\nadc"]', 'lax $[*] ? (@ like_regex "^ab.*c" flag "s")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "q")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "a\\b" flag "")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "q")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "q")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\B$" flag "iq")'); +select jsonb_path_query('[null, 1, "a\b", "a\\b", "^a\\b$"]', 'lax $[*] ? (@ like_regex "^a\\b$" flag "")'); + +select jsonb_path_query('null', '$.datetime()'); +select jsonb_path_query('true', '$.datetime()'); +select jsonb_path_query('1', '$.datetime()'); +select jsonb_path_query('[]', '$.datetime()'); +select jsonb_path_query('[]', 'strict $.datetime()'); +select jsonb_path_query('{}', '$.datetime()'); +select jsonb_path_query('""', '$.datetime()'); +select jsonb_path_query('"12:34"', '$.datetime("aaa")'); +select jsonb_path_query('"aaaa"', '$.datetime("HH24")'); + +select jsonb '"10-03-2017"' @? '$.datetime("dd-mm-yyyy")'; +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy")'); +select jsonb_path_query('"10-03-2017"', '$.datetime("dd-mm-yyyy").type()'); +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy")'); +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy").type()'); + +select jsonb_path_query('"10-03-2017 12:34"', ' $.datetime("dd-mm-yyyy HH24:MI").type()'); +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM").type()'); +select jsonb_path_query('"12:34:56"', '$.datetime("HH24:MI:SS").type()'); +select jsonb_path_query('"12:34:56 +05:20"', '$.datetime("HH24:MI:SS TZH:TZM").type()'); + +set time zone '+00'; + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +set time zone '+10'; + +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI")'); +select jsonb_path_query('"10-03-2017 12:34"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 +05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 -05"', '$.datetime("dd-mm-yyyy HH24:MI TZH")'); +select jsonb_path_query('"10-03-2017 12:34 +05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); +select jsonb_path_query('"10-03-2017 12:34 -05:20"', '$.datetime("dd-mm-yyyy HH24:MI TZH:TZM")'); +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI")'); +select jsonb_path_query('"12:34"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 +05"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 -05"', '$.datetime("HH24:MI TZH")'); +select jsonb_path_query('"12:34 +05:20"', '$.datetime("HH24:MI TZH:TZM")'); +select jsonb_path_query('"12:34 -05:20"', '$.datetime("HH24:MI TZH:TZM")'); + +set time zone default; + +select jsonb_path_query('"2017-03-10"', '$.datetime().type()'); +select jsonb_path_query('"2017-03-10"', '$.datetime()'); +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime().type()'); +select jsonb_path_query('"2017-03-10 12:34:56"', '$.datetime()'); +select jsonb_path_query('"2017-03-10 12:34:56 +3"', '$.datetime().type()'); +select jsonb_path_query('"2017-03-10 12:34:56 +3"', '$.datetime()'); +select jsonb_path_query('"2017-03-10 12:34:56 +3:10"', '$.datetime().type()'); +select jsonb_path_query('"2017-03-10 12:34:56 +3:10"', '$.datetime()'); +select jsonb_path_query('"12:34:56"', '$.datetime().type()'); +select jsonb_path_query('"12:34:56"', '$.datetime()'); +select jsonb_path_query('"12:34:56 +3"', '$.datetime().type()'); +select jsonb_path_query('"12:34:56 +3"', '$.datetime()'); +select jsonb_path_query('"12:34:56 +3:10"', '$.datetime().type()'); +select jsonb_path_query('"12:34:56 +3:10"', '$.datetime()'); + +set time zone '+00'; + +-- date comparison +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); +select jsonb_path_query( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ == "10.03.2017".datetime("dd.mm.yyyy"))'); +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ >= "10.03.2017".datetime("dd.mm.yyyy"))'); +select jsonb_path_query_tz( + '["2017-03-10", "2017-03-11", "2017-03-09", "12:34:56", "01:02:03 +04", "2017-03-10 00:00:00", "2017-03-10 12:34:56", "2017-03-10 01:02:03 +04", "2017-03-10 03:00:00 +03"]', + '$[*].datetime() ? (@ < "10.03.2017".datetime("dd.mm.yyyy"))'); + +-- time comparison +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); +select jsonb_path_query( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ == "12:35".datetime("HH24:MI"))'); +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ >= "12:35".datetime("HH24:MI"))'); +select jsonb_path_query_tz( + '["12:34:00", "12:35:00", "12:36:00", "12:35:00 +00", "12:35:00 +01", "13:35:00 +01", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +01"]', + '$[*].datetime() ? (@ < "12:35".datetime("HH24:MI"))'); + +-- timetz comparison +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); +select jsonb_path_query( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ == "12:35 +1".datetime("HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ >= "12:35 +1".datetime("HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["12:34:00 +01", "12:35:00 +01", "12:36:00 +01", "12:35:00 +02", "12:35:00 -02", "10:35:00", "11:35:00", "12:35:00", "2017-03-10", "2017-03-10 12:35:00", "2017-03-10 12:35:00 +1"]', + '$[*].datetime() ? (@ < "12:35 +1".datetime("HH24:MI TZH"))'); + +-- timestamp comparison +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +select jsonb_path_query( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00", "2017-03-10 12:35:00", "2017-03-10 12:36:00", "2017-03-10 12:35:00 +01", "2017-03-10 13:35:00 +01", "2017-03-10 12:35:00 -01", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35".datetime("dd.mm.yyyy HH24:MI"))'); + +-- timestamptz comparison +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +select jsonb_path_query( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ == "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ >= "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); +select jsonb_path_query_tz( + '["2017-03-10 12:34:00 +01", "2017-03-10 12:35:00 +01", "2017-03-10 12:36:00 +01", "2017-03-10 12:35:00 +02", "2017-03-10 12:35:00 -02", "2017-03-10 10:35:00", "2017-03-10 11:35:00", "2017-03-10 12:35:00", "2017-03-10", "2017-03-11", "12:34:56", "12:34:56 +01"]', + '$[*].datetime() ? (@ < "10.03.2017 12:35 +1".datetime("dd.mm.yyyy HH24:MI TZH"))'); + +set time zone default; + +-- jsonpath operators + +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*]'); +SELECT jsonb_path_query('[{"a": 1}, {"a": 2}]', '$[*] ? (@.a > 10)'); + +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a'); +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); +SELECT jsonb_path_query_array('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a'); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {}]', 'strict $[*].a', silent => true); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a'); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ == 1)'); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 10)'); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 1, "max": 4}'); +SELECT jsonb_path_query_first('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*].a ? (@ > $min && @ < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*].a ? (@ > 1)'; +SELECT jsonb '[{"a": 1}, {"a": 2}]' @? '$[*] ? (@.a > 2)'; +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}]', '$[*].a ? (@ > 1)'); +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 1, "max": 4}'); +SELECT jsonb_path_exists('[{"a": 1}, {"a": 2}, {"a": 3}, {"a": 5}]', '$[*] ? (@.a > $min && @.a < $max)', vars => '{"min": 3, "max": 4}'); + +SELECT jsonb_path_match('true', '$', silent => false); +SELECT jsonb_path_match('false', '$', silent => false); +SELECT jsonb_path_match('null', '$', silent => false); +SELECT jsonb_path_match('1', '$', silent => true); +SELECT jsonb_path_match('1', '$', silent => false); +SELECT jsonb_path_match('"a"', '$', silent => false); +SELECT jsonb_path_match('{}', '$', silent => false); +SELECT jsonb_path_match('[true]', '$', silent => false); +SELECT jsonb_path_match('{}', 'lax $.a', silent => false); +SELECT jsonb_path_match('{}', 'strict $.a', silent => false); +SELECT jsonb_path_match('{}', 'strict $.a', silent => true); +SELECT jsonb_path_match('[true, true]', '$[*]', silent => false); +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 1'; +SELECT jsonb '[{"a": 1}, {"a": 2}]' @@ '$[*].a > 2'; +SELECT jsonb_path_match('[{"a": 1}, {"a": 2}]', '$[*].a > 1'); + +-- test string comparison (Unicode codepoint collation) +WITH str(j, num) AS +( + SELECT jsonb_build_object('s', s), num + FROM unnest('{"", "a", "ab", "abc", "abcd", "b", "A", "AB", "ABC", "ABc", "ABcD", "B"}'::text[]) WITH ORDINALITY AS a(s, num) +) +SELECT + s1.j, s2.j, + jsonb_path_query_first(s1.j, '$.s < $s', vars => s2.j) lt, + jsonb_path_query_first(s1.j, '$.s <= $s', vars => s2.j) le, + jsonb_path_query_first(s1.j, '$.s == $s', vars => s2.j) eq, + jsonb_path_query_first(s1.j, '$.s >= $s', vars => s2.j) ge, + jsonb_path_query_first(s1.j, '$.s > $s', vars => s2.j) gt +FROM str s1, str s2 +ORDER BY s1.num, s2.num; diff --git a/src/test/regress/sql/jsonpath.sql b/src/test/regress/sql/jsonpath.sql new file mode 100644 index 00000000000..17ab7757831 --- /dev/null +++ b/src/test/regress/sql/jsonpath.sql @@ -0,0 +1,181 @@ +--jsonpath io + +select ''::jsonpath; +select '$'::jsonpath; +select 'strict $'::jsonpath; +select 'lax $'::jsonpath; +select '$.a'::jsonpath; +select '$.a.v'::jsonpath; +select '$.a.*'::jsonpath; +select '$.*[*]'::jsonpath; +select '$.a[*]'::jsonpath; +select '$.a[*][*]'::jsonpath; +select '$[*]'::jsonpath; +select '$[0]'::jsonpath; +select '$[*][0]'::jsonpath; +select '$[*].a'::jsonpath; +select '$[*][0].a.b'::jsonpath; +select '$.a.**.b'::jsonpath; +select '$.a.**{2}.b'::jsonpath; +select '$.a.**{2 to 2}.b'::jsonpath; +select '$.a.**{2 to 5}.b'::jsonpath; +select '$.a.**{0 to 5}.b'::jsonpath; +select '$.a.**{5 to last}.b'::jsonpath; +select '$.a.**{last}.b'::jsonpath; +select '$.a.**{last to 5}.b'::jsonpath; +select '$+1'::jsonpath; +select '$-1'::jsonpath; +select '$--+1'::jsonpath; +select '$.a/+-1'::jsonpath; +select '1 * 2 + 4 % -3 != false'::jsonpath; + +select '"\b\f\r\n\t\v\"\''\\"'::jsonpath; +select '"\x50\u0067\u{53}\u{051}\u{00004C}"'::jsonpath; +select '$.foo\x50\u0067\u{53}\u{051}\u{00004C}\t\"bar'::jsonpath; +select '"\z"'::jsonpath; -- unrecognized escape is just the literal char + +select '$.g ? ($.a == 1)'::jsonpath; +select '$.g ? (@ == 1)'::jsonpath; +select '$.g ? (@.a == 1)'::jsonpath; +select '$.g ? (@.a == 1 || @.a == 4)'::jsonpath; +select '$.g ? (@.a == 1 && @.a == 4)'::jsonpath; +select '$.g ? (@.a == 1 || @.a == 4 && @.b == 7)'::jsonpath; +select '$.g ? (@.a == 1 || !(@.a == 4) && @.b == 7)'::jsonpath; +select '$.g ? (@.a == 1 || !(@.x >= 123 || @.a == 4) && @.b == 7)'::jsonpath; +select '$.g ? (@.x >= @[*]?(@.a > "abc"))'::jsonpath; +select '$.g ? ((@.x >= 123 || @.a == 4) is unknown)'::jsonpath; +select '$.g ? (exists (@.x))'::jsonpath; +select '$.g ? (exists (@.x ? (@ == 14)))'::jsonpath; +select '$.g ? ((@.x >= 123 || @.a == 4) && exists (@.x ? (@ == 14)))'::jsonpath; +select '$.g ? (+@.x >= +-(+@.a + 2))'::jsonpath; + +select '$a'::jsonpath; +select '$a.b'::jsonpath; +select '$a[*]'::jsonpath; +select '$.g ? (@.zip == $zip)'::jsonpath; +select '$.a[1,2, 3 to 16]'::jsonpath; +select '$.a[$a + 1, ($b[*]) to -($[0] * 2)]'::jsonpath; +select '$.a[$.a.size() - 3]'::jsonpath; +select 'last'::jsonpath; +select '"last"'::jsonpath; +select '$.last'::jsonpath; +select '$ ? (last > 0)'::jsonpath; +select '$[last]'::jsonpath; +select '$[$[0] ? (last > 0)]'::jsonpath; + +select 'null.type()'::jsonpath; +select '1.type()'::jsonpath; +select '(1).type()'::jsonpath; +select '1.2.type()'::jsonpath; +select '"aaa".type()'::jsonpath; +select 'true.type()'::jsonpath; +select '$.double().floor().ceiling().abs()'::jsonpath; +select '$.keyvalue().key'::jsonpath; +select '$.datetime()'::jsonpath; +select '$.datetime("datetime template")'::jsonpath; + +select '$ ? (@ starts with "abc")'::jsonpath; +select '$ ? (@ starts with $var)'::jsonpath; + +select '$ ? (@ like_regex "(invalid pattern")'::jsonpath; +select '$ ? (@ like_regex "pattern")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "i")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "is")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "isim")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "xsms")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "q")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "iq")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "smixq")'::jsonpath; +select '$ ? (@ like_regex "pattern" flag "a")'::jsonpath; + +select '$ < 1'::jsonpath; +select '($ < 1) || $.a.b <= $x'::jsonpath; +select '@ + 1'::jsonpath; + +select '($).a.b'::jsonpath; +select '($.a.b).c.d'::jsonpath; +select '($.a.b + -$.x.y).c.d'::jsonpath; +select '(-+$.a.b).c.d'::jsonpath; +select '1 + ($.a.b + 2).c.d'::jsonpath; +select '1 + ($.a.b > 2).c.d'::jsonpath; +select '($)'::jsonpath; +select '(($))'::jsonpath; +select '((($ + 1)).a + ((2)).b ? ((((@ > 1)) || (exists(@.c)))))'::jsonpath; + +select '$ ? (@.a < 1)'::jsonpath; +select '$ ? (@.a < -1)'::jsonpath; +select '$ ? (@.a < +1)'::jsonpath; +select '$ ? (@.a < .1)'::jsonpath; +select '$ ? (@.a < -.1)'::jsonpath; +select '$ ? (@.a < +.1)'::jsonpath; +select '$ ? (@.a < 0.1)'::jsonpath; +select '$ ? (@.a < -0.1)'::jsonpath; +select '$ ? (@.a < +0.1)'::jsonpath; +select '$ ? (@.a < 10.1)'::jsonpath; +select '$ ? (@.a < -10.1)'::jsonpath; +select '$ ? (@.a < +10.1)'::jsonpath; +select '$ ? (@.a < 1e1)'::jsonpath; +select '$ ? (@.a < -1e1)'::jsonpath; +select '$ ? (@.a < +1e1)'::jsonpath; +select '$ ? (@.a < .1e1)'::jsonpath; +select '$ ? (@.a < -.1e1)'::jsonpath; +select '$ ? (@.a < +.1e1)'::jsonpath; +select '$ ? (@.a < 0.1e1)'::jsonpath; +select '$ ? (@.a < -0.1e1)'::jsonpath; +select '$ ? (@.a < +0.1e1)'::jsonpath; +select '$ ? (@.a < 10.1e1)'::jsonpath; +select '$ ? (@.a < -10.1e1)'::jsonpath; +select '$ ? (@.a < +10.1e1)'::jsonpath; +select '$ ? (@.a < 1e-1)'::jsonpath; +select '$ ? (@.a < -1e-1)'::jsonpath; +select '$ ? (@.a < +1e-1)'::jsonpath; +select '$ ? (@.a < .1e-1)'::jsonpath; +select '$ ? (@.a < -.1e-1)'::jsonpath; +select '$ ? (@.a < +.1e-1)'::jsonpath; +select '$ ? (@.a < 0.1e-1)'::jsonpath; +select '$ ? (@.a < -0.1e-1)'::jsonpath; +select '$ ? (@.a < +0.1e-1)'::jsonpath; +select '$ ? (@.a < 10.1e-1)'::jsonpath; +select '$ ? (@.a < -10.1e-1)'::jsonpath; +select '$ ? (@.a < +10.1e-1)'::jsonpath; +select '$ ? (@.a < 1e+1)'::jsonpath; +select '$ ? (@.a < -1e+1)'::jsonpath; +select '$ ? (@.a < +1e+1)'::jsonpath; +select '$ ? (@.a < .1e+1)'::jsonpath; +select '$ ? (@.a < -.1e+1)'::jsonpath; +select '$ ? (@.a < +.1e+1)'::jsonpath; +select '$ ? (@.a < 0.1e+1)'::jsonpath; +select '$ ? (@.a < -0.1e+1)'::jsonpath; +select '$ ? (@.a < +0.1e+1)'::jsonpath; +select '$ ? (@.a < 10.1e+1)'::jsonpath; +select '$ ? (@.a < -10.1e+1)'::jsonpath; +select '$ ? (@.a < +10.1e+1)'::jsonpath; + +select '0'::jsonpath; +select '00'::jsonpath; +select '0.0'::jsonpath; +select '0.000'::jsonpath; +select '0.000e1'::jsonpath; +select '0.000e2'::jsonpath; +select '0.000e3'::jsonpath; +select '0.0010'::jsonpath; +select '0.0010e-1'::jsonpath; +select '0.0010e+1'::jsonpath; +select '0.0010e+2'::jsonpath; +select '1e'::jsonpath; +select '1.e'::jsonpath; +select '1.2e'::jsonpath; +select '1.2.e'::jsonpath; +select '(1.2).e'::jsonpath; +select '1e3'::jsonpath; +select '1.e3'::jsonpath; +select '1.e3.e'::jsonpath; +select '1.e3.e4'::jsonpath; +select '1.2e3'::jsonpath; +select '1.2.e3'::jsonpath; +select '(1.2).e3'::jsonpath; +select '1..e'::jsonpath; +select '1..e3'::jsonpath; +select '(1.).e'::jsonpath; +select '(1.).e3'::jsonpath; diff --git a/src/test/regress/sql/jsonpath_encoding.sql b/src/test/regress/sql/jsonpath_encoding.sql new file mode 100644 index 00000000000..3a23b728182 --- /dev/null +++ b/src/test/regress/sql/jsonpath_encoding.sql @@ -0,0 +1,48 @@ + +-- encoding-sensitive tests for jsonpath + +-- checks for double-quoted values + +-- basic unicode input +SELECT '"\u"'::jsonpath; -- ERROR, incomplete escape +SELECT '"\u00"'::jsonpath; -- ERROR, incomplete escape +SELECT '"\u000g"'::jsonpath; -- ERROR, g is not a hex digit +SELECT '"\u0000"'::jsonpath; -- OK, legal escape +SELECT '"\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '"\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; +select '"\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +select '"\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +select '"\ud83dX"'::jsonpath; -- orphan high surrogate +select '"\ude04X"'::jsonpath; -- orphan low surrogate + +--handling of simple unicode escapes +select '"the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; +select '"dollar \u0024 character"'::jsonpath as correct_everywhere; +select '"dollar \\u0024 character"'::jsonpath as not_an_escape; +select '"null \u0000 escape"'::jsonpath as not_unescaped; +select '"null \\u0000 escape"'::jsonpath as not_an_escape; + +-- checks for quoted key names + +-- basic unicode input +SELECT '$."\u"'::jsonpath; -- ERROR, incomplete escape +SELECT '$."\u00"'::jsonpath; -- ERROR, incomplete escape +SELECT '$."\u000g"'::jsonpath; -- ERROR, g is not a hex digit +SELECT '$."\u0000"'::jsonpath; -- OK, legal escape +SELECT '$."\uaBcD"'::jsonpath; -- OK, uppercase and lower case both OK + +-- handling of unicode surrogate pairs +select '$."\ud83d\ude04\ud83d\udc36"'::jsonpath as correct_in_utf8; +select '$."\ud83d\ud83d"'::jsonpath; -- 2 high surrogates in a row +select '$."\ude04\ud83d"'::jsonpath; -- surrogates in wrong order +select '$."\ud83dX"'::jsonpath; -- orphan high surrogate +select '$."\ude04X"'::jsonpath; -- orphan low surrogate + +--handling of simple unicode escapes +select '$."the Copyright \u00a9 sign"'::jsonpath as correct_in_utf8; +select '$."dollar \u0024 character"'::jsonpath as correct_everywhere; +select '$."dollar \\u0024 character"'::jsonpath as not_an_escape; +select '$."null \u0000 escape"'::jsonpath as not_unescaped; +select '$."null \\u0000 escape"'::jsonpath as not_an_escape; diff --git a/src/test/regress/sql/line.sql b/src/test/regress/sql/line.sql index 94067b0cee6..f589ffecc84 100644 --- a/src/test/regress/sql/line.sql +++ b/src/test/regress/sql/line.sql @@ -6,82 +6,37 @@ --DROP TABLE LINE_TBL; CREATE TABLE LINE_TBL (s line); -INSERT INTO LINE_TBL VALUES ('{1,-1,1}'); -INSERT INTO LINE_TBL VALUES ('(0,0),(6,6)'); +INSERT INTO LINE_TBL VALUES ('{0,-1,5}'); -- A == 0 +INSERT INTO LINE_TBL VALUES ('{1,0,5}'); -- B == 0 +INSERT INTO LINE_TBL VALUES ('{0,3,0}'); -- A == C == 0 +INSERT INTO LINE_TBL VALUES (' (0,0), (6,6)'); INSERT INTO LINE_TBL VALUES ('10,-10 ,-5,-4'); INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); -INSERT INTO LINE_TBL VALUES ('(11,22,33,44)'); -INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); +INSERT INTO LINE_TBL VALUES ('{3,NaN,5}'); +INSERT INTO LINE_TBL VALUES ('{NaN,NaN,NaN}'); -- horizontal INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]'); -- vertical -INSERT INTO LINE_TBL VALUES ('[(3,1),(3,2)]'); +INSERT INTO LINE_TBL VALUES (line(point '(3,1)', point '(3,2)')); -- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{}'); +INSERT INTO LINE_TBL VALUES ('{0'); +INSERT INTO LINE_TBL VALUES ('{0,0}'); +INSERT INTO LINE_TBL VALUES ('{0,0,1'); INSERT INTO LINE_TBL VALUES ('{0,0,1}'); +INSERT INTO LINE_TBL VALUES ('{0,0,1} x'); INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); INSERT INTO LINE_TBL VALUES ('[1,2,3, 4'); INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]'); INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); +INSERT INTO LINE_TBL VALUES ('[(1,2),(1,2)]'); -select * from LINE_TBL; - - --- functions and operators - -SELECT * FROM LINE_TBL WHERE (s <-> line '[(1,2),(3,4)]') < 10; - -SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1; - -SELECT * FROM LINE_TBL WHERE (lseg '[(0.1,0.1),(0.2,0.2)]' <-> s) < 1; - -SELECT line '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; -SELECT lseg '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; -SELECT point '(-1,1)' <-> line '[(-3,0),(-4,0)]'; - -SELECT lseg '[(1,1),(5,5)]' ?# line '[(2,0),(0,2)]'; -- true -SELECT lseg '[(1,1),(5,5)]' ?# line '[(0,0),(1,0)]'; -- false - -SELECT line '[(0,0),(1,1)]' ?# box '(0,0,2,2)'; -- true -SELECT line '[(3,0),(4,1)]' ?# box '(0,0,2,2)'; -- false - -SELECT point '(1,1)' <@ line '[(0,0),(2,2)]'; -- true -SELECT point '(1,1)' <@ line '[(0,0),(1,0)]'; -- false - -SELECT point '(1,1)' @ line '[(0,0),(2,2)]'; -- true -SELECT point '(1,1)' @ line '[(0,0),(1,0)]'; -- false +INSERT INTO LINE_TBL VALUES (line(point '(1,0)', point '(1,0)')); -SELECT lseg '[(1,1),(2,2)]' <@ line '[(0,0),(2,2)]'; -- true -SELECT lseg '[(1,1),(2,1)]' <@ line '[(0,0),(1,0)]'; -- false - -SELECT lseg '[(1,1),(2,2)]' @ line '[(0,0),(2,2)]'; -- true -SELECT lseg '[(1,1),(2,1)]' @ line '[(0,0),(1,0)]'; -- false - -SELECT point '(0,1)' ## line '[(0,0),(1,1)]'; - -SELECT line '[(0,0),(1,1)]' ## lseg '[(1,0),(2,0)]'; - -SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(2,1)]'; -- false -SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(1,1)]'; -- true - -SELECT line '[(0,0),(1,1)]' # line '[(1,0),(2,1)]'; -SELECT line '[(0,0),(1,1)]' # line '[(1,0),(1,1)]'; - -SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(2,1)]'; -- true -SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(1,1)]'; -- false - -SELECT line '[(0,0),(1,0)]' ?-| line '[(0,0),(0,1)]'; -- true -SELECT line '[(0,0),(1,1)]' ?-| line '[(1,0),(1,1)]'; -- false - -SELECT ?- line '[(0,0),(1,0)]'; -- true -SELECT ?- line '[(0,0),(1,1)]'; -- false - -SELECT ?| line '[(0,0),(0,1)]'; -- true -SELECT ?| line '[(0,0),(1,1)]'; -- false - -SELECT line(point '(1,2)', point '(3,4)'); +select * from LINE_TBL; -SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,5)]'; -- true -SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,4)]'; -- false +select '{nan, 1, nan}'::line = '{nan, 1, nan}'::line as true, + '{nan, 1, nan}'::line = '{nan, 2, nan}'::line as false; diff --git a/src/test/regress/sql/lock.sql b/src/test/regress/sql/lock.sql index e22c9e2f3ae..26a7e59a136 100644 --- a/src/test/regress/sql/lock.sql +++ b/src/test/regress/sql/lock.sql @@ -84,6 +84,15 @@ select relname from pg_locks l, pg_class c where l.relation = c.oid and relname like '%lock_%' and mode = 'ExclusiveLock' order by relname; ROLLBACK; +-- detecting infinite recursions in view definitions +CREATE OR REPLACE VIEW lock_view2 AS SELECT * from lock_view3; +BEGIN TRANSACTION; +LOCK TABLE lock_view2 IN EXCLUSIVE MODE; +ROLLBACK; +CREATE VIEW lock_view7 AS SELECT * from lock_view2; +BEGIN TRANSACTION; +LOCK TABLE lock_view7 IN EXCLUSIVE MODE; +ROLLBACK; -- Verify that we can lock a table with inheritance children. CREATE TABLE lock_tbl2 (b BIGINT) INHERITS (lock_tbl1); @@ -107,11 +116,11 @@ RESET ROLE; -- -- Clean up -- +DROP VIEW lock_view7; DROP VIEW lock_view6; DROP VIEW lock_view5; DROP VIEW lock_view4; -DROP VIEW lock_view3; -DROP VIEW lock_view2; +DROP VIEW lock_view3 CASCADE; DROP VIEW lock_view1; DROP TABLE lock_tbl3; DROP TABLE lock_tbl2; diff --git a/src/test/regress/sql/lseg.sql b/src/test/regress/sql/lseg.sql index 07c5a29e0a5..f266ca3e09e 100644 --- a/src/test/regress/sql/lseg.sql +++ b/src/test/regress/sql/lseg.sql @@ -10,7 +10,10 @@ INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)]'); INSERT INTO LSEG_TBL VALUES ('(0,0),(6,6)'); INSERT INTO LSEG_TBL VALUES ('10,-10 ,-3,-4'); INSERT INTO LSEG_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); -INSERT INTO LSEG_TBL VALUES ('(11,22,33,44)'); +INSERT INTO LSEG_TBL VALUES (lseg(point(11, 22), point(33,44))); +INSERT INTO LSEG_TBL VALUES ('[(-10,2),(-10,3)]'); -- vertical +INSERT INTO LSEG_TBL VALUES ('[(0,-20),(30,-20)]'); -- horizontal +INSERT INTO LSEG_TBL VALUES ('[(NaN,1),(NaN,90)]'); -- NaN -- bad values for parser testing INSERT INTO LSEG_TBL VALUES ('(3asdf,2 ,3,4r2)'); @@ -19,7 +22,3 @@ INSERT INTO LSEG_TBL VALUES ('[(,2),(3,4)]'); INSERT INTO LSEG_TBL VALUES ('[(1,2),(3,4)'); select * from LSEG_TBL; - -SELECT * FROM LSEG_TBL WHERE s <= lseg '[(1,2),(3,4)]'; - -SELECT * FROM LSEG_TBL WHERE (s <-> lseg '[(1,2),(3,4)]') < 10; diff --git a/src/test/regress/sql/merge.sql b/src/test/regress/sql/merge.sql deleted file mode 100644 index f6ef6a9acae..00000000000 --- a/src/test/regress/sql/merge.sql +++ /dev/null @@ -1,1173 +0,0 @@ --- --- MERGE --- ---\set VERBOSITY verbose - ---set debug_print_rewritten = true; ---set debug_print_parse = true; ---set debug_print_pretty = true; - - -CREATE USER merge_privs; -CREATE USER merge_no_privs; -DROP TABLE IF EXISTS target; -DROP TABLE IF EXISTS source; -CREATE TABLE target (tid integer, balance integer); -CREATE TABLE source (sid integer, delta integer); --no index -INSERT INTO target VALUES (1, 10); -INSERT INTO target VALUES (2, 20); -INSERT INTO target VALUES (3, 30); -SELECT t.ctid is not null as matched, t.*, s.* FROM source s FULL OUTER JOIN target t ON s.sid = t.tid ORDER BY t.tid, s.sid; - -ALTER TABLE target OWNER TO merge_privs; -ALTER TABLE source OWNER TO merge_privs; - -CREATE TABLE target2 (tid integer, balance integer); -CREATE TABLE source2 (sid integer, delta integer); - -ALTER TABLE target2 OWNER TO merge_no_privs; -ALTER TABLE source2 OWNER TO merge_no_privs; - -GRANT INSERT ON target TO merge_no_privs; - -SET SESSION AUTHORIZATION merge_privs; - -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; - --- --- Errors --- -MERGE INTO target t RANDOMWORD -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; --- MATCHED/INSERT error -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - INSERT DEFAULT VALUES -; --- incorrectly specifying INTO target -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT INTO target DEFAULT VALUES -; --- Multiple VALUES clause -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (1,1), (2,2); -; --- SELECT query for INSERT -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT SELECT (1, 1); -; --- NOT MATCHED/UPDATE -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - UPDATE SET balance = 0 -; --- UPDATE tablename -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE target SET balance = 0 -; - --- unsupported relation types --- view -CREATE VIEW tv AS SELECT * FROM target; -MERGE INTO tv t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -DROP VIEW tv; - --- materialized view -CREATE MATERIALIZED VIEW mv AS SELECT * FROM target; -MERGE INTO mv t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -DROP MATERIALIZED VIEW mv; - --- inherited table -CREATE TABLE inhp (tid int, balance int); -CREATE TABLE child1() INHERITS (inhp); -CREATE TABLE child2() INHERITS (child1); - -MERGE INTO inhp t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; - -MERGE INTO child1 t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; - --- this should be ok -MERGE INTO child2 t -USING source s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES; -DROP TABLE inhp, child1, child2; - --- permissions - -MERGE INTO target -USING source2 -ON target.tid = source2.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; - -GRANT INSERT ON target TO merge_no_privs; -SET SESSION AUTHORIZATION merge_no_privs; - -MERGE INTO target -USING source2 -ON target.tid = source2.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; - -GRANT UPDATE ON target2 TO merge_privs; -SET SESSION AUTHORIZATION merge_privs; - -MERGE INTO target2 -USING source -ON target2.tid = source.sid -WHEN MATCHED THEN - DELETE -; - -MERGE INTO target2 -USING source -ON target2.tid = source.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; - --- check if the target can be accessed from source relation subquery; we should --- not be able to do so -MERGE INTO target t -USING (SELECT * FROM source WHERE t.tid > sid) s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; - --- --- initial tests --- --- zero rows in source has no effect -MERGE INTO target -USING source -ON target.tid = source.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; - -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -ROLLBACK; - --- insert some non-matching source rows to work from -INSERT INTO source VALUES (4, 40); -SELECT * FROM source ORDER BY sid; -SELECT * FROM target ORDER BY tid; - -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - DO NOTHING -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT DEFAULT VALUES -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- index plans -INSERT INTO target SELECT generate_series(1000,2500), 0; -ALTER TABLE target ADD PRIMARY KEY (tid); -ANALYZE target; - -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -EXPLAIN (COSTS OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, NULL); -; -DELETE FROM target WHERE tid > 100; -ANALYZE target; - --- insert some matching source rows to work from -INSERT INTO source VALUES (2, 5); -INSERT INTO source VALUES (3, 20); -SELECT * FROM source ORDER BY sid; -SELECT * FROM target ORDER BY tid; - --- equivalent of an UPDATE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- equivalent of a DELETE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, NULL) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- duplicate source row causes multiple target row update ERROR -INSERT INTO source VALUES (2, 5); -SELECT * FROM source ORDER BY sid; -SELECT * FROM target ORDER BY tid; -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -ROLLBACK; - -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - DELETE -; -ROLLBACK; - --- correct source data -DELETE FROM source WHERE sid = 2; -INSERT INTO source VALUES (2, 5); -SELECT * FROM source ORDER BY sid; -SELECT * FROM target ORDER BY tid; - --- remove constraints -alter table target drop CONSTRAINT target_pkey; -alter table target alter column tid drop not null; - --- multiple actions -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (4, 4) -WHEN MATCHED THEN - UPDATE SET balance = 0 -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- should be equivalent -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = 0 -WHEN NOT MATCHED THEN - INSERT VALUES (4, 4); -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- column references --- do a simple equivalent of an UPDATE join -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance + s.delta -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- do a simple equivalent of an INSERT SELECT -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- and again with explicitly identified column list -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- and again with a subtle error: referring to non-existent target row for NOT MATCHED -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (t.tid, s.delta) -; - --- and again with a constant ON clause -BEGIN; -MERGE INTO target t -USING source AS s -ON (SELECT true) -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (t.tid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- now the classic UPSERT -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance + s.delta -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- unreachable WHEN clause should ERROR -BEGIN; -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED THEN /* Terminal WHEN clause for MATCHED */ - DELETE -WHEN MATCHED AND s.delta > 0 THEN - UPDATE SET balance = t.balance - s.delta -; -ROLLBACK; - --- conditional WHEN clause -CREATE TABLE wq_target (tid integer not null, balance integer DEFAULT -1); -CREATE TABLE wq_source (balance integer, sid integer); - -INSERT INTO wq_source (sid, balance) VALUES (1, 100); - -BEGIN; --- try a simple INSERT with default values first -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; -ROLLBACK; - --- this time with a FALSE condition -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND FALSE THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - --- this time with an actual condition which returns false -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance <> 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - -BEGIN; --- and now with a condition which returns true -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; -ROLLBACK; - --- conditions in the NOT MATCHED clause can only refer to source columns -BEGIN; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND t.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; -ROLLBACK; - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN NOT MATCHED AND s.balance = 100 THEN - INSERT (tid) VALUES (s.sid); -SELECT * FROM wq_target; - --- conditions in MATCHED clause can refer to both source and target -SELECT * FROM wq_source; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND s.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - --- check if AND works -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 AND s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 AND s.balance = 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - --- check if OR works -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 99 OR s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance = 199 OR s.balance > 100 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - --- check if subqueries work in the conditions? -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.balance > (SELECT max(balance) FROM target) THEN - UPDATE SET balance = t.balance + s.balance; - --- check if we can access system columns in the conditions -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.xmin = t.xmax THEN - UPDATE SET balance = t.balance + s.balance; - -ALTER TABLE wq_target SET WITH OIDS; -SELECT * FROM wq_target; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND t.oid >= 0 THEN - UPDATE SET balance = t.balance + s.balance; -SELECT * FROM wq_target; - --- test preventing WHEN AND conditions from writing to the database -create or replace function merge_when_and_write() returns boolean -language plpgsql as -$$ -BEGIN - INSERT INTO target VALUES (100, 100); - RETURN TRUE; -END; -$$; - -BEGIN; -MERGE INTO wq_target t -USING wq_source s ON t.tid = s.sid -WHEN MATCHED AND (merge_when_and_write()) THEN - UPDATE SET balance = t.balance + s.balance; -ROLLBACK; -drop function merge_when_and_write(); - -DROP TABLE wq_target, wq_source; - --- test triggers -create or replace function merge_trigfunc () returns trigger -language plpgsql as -$$ -BEGIN - RAISE NOTICE '% % % trigger', TG_WHEN, TG_OP, TG_LEVEL; - IF (TG_WHEN = 'BEFORE' AND TG_LEVEL = 'ROW') THEN - IF (TG_OP = 'DELETE') THEN - RETURN OLD; - ELSE - RETURN NEW; - END IF; - ELSE - RETURN NULL; - END IF; -END; -$$; -CREATE TRIGGER merge_bsi BEFORE INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bsu BEFORE UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bsd BEFORE DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asi AFTER INSERT ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asu AFTER UPDATE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_asd AFTER DELETE ON target FOR EACH STATEMENT EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bri BEFORE INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_bru BEFORE UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_brd BEFORE DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_ari AFTER INSERT ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_aru AFTER UPDATE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); -CREATE TRIGGER merge_ard AFTER DELETE ON target FOR EACH ROW EXECUTE PROCEDURE merge_trigfunc (); - --- now the classic UPSERT, with a DELETE -BEGIN; -UPDATE target SET balance = 0 WHERE tid = 3; ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED AND t.balance > s.delta THEN - UPDATE SET balance = t.balance - s.delta -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- test from PL/pgSQL --- make sure MERGE INTO isn't interpreted to mean returning variables like SELECT INTO -BEGIN; -DO LANGUAGE plpgsql $$ -BEGIN -MERGE INTO target t -USING source AS s -ON t.tid = s.sid -WHEN MATCHED AND t.balance > s.delta THEN - UPDATE SET balance = t.balance - s.delta -; -END; -$$; -ROLLBACK; - ---source constants -BEGIN; -MERGE INTO target t -USING (SELECT 9 AS sid, 57 AS delta) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - ---source query -BEGIN; -MERGE INTO target t -USING (SELECT sid, delta FROM source WHERE delta > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - -BEGIN; -MERGE INTO target t -USING (SELECT sid, delta as newname FROM source WHERE delta > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.newname) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - ---self-merge -BEGIN; -MERGE INTO target t1 -USING target t2 -ON t1.tid = t2.tid -WHEN MATCHED THEN - UPDATE SET balance = t1.balance + t2.balance -WHEN NOT MATCHED THEN - INSERT VALUES (t2.tid, t2.balance) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - -BEGIN; -MERGE INTO target t -USING (SELECT tid as sid, balance as delta FROM target WHERE balance > 0) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - -BEGIN; -MERGE INTO target t -USING -(SELECT sid, max(delta) AS delta - FROM source - GROUP BY sid - HAVING count(*) = 1 - ORDER BY sid ASC) AS s -ON t.tid = s.sid -WHEN NOT MATCHED THEN - INSERT (tid, balance) VALUES (s.sid, s.delta) -; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- plpgsql parameters and results -BEGIN; -CREATE FUNCTION merge_func (p_id integer, p_bal integer) -RETURNS INTEGER -LANGUAGE plpgsql -AS $$ -DECLARE - result integer; -BEGIN -MERGE INTO target t -USING (SELECT p_id AS sid) AS s -ON t.tid = s.sid -WHEN MATCHED THEN - UPDATE SET balance = t.balance - p_bal -; -IF FOUND THEN - GET DIAGNOSTICS result := ROW_COUNT; -END IF; -RETURN result; -END; -$$; -SELECT merge_func(3, 4); -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- PREPARE -BEGIN; -prepare foom as merge into target t using (select 1 as sid) s on (t.tid = s.sid) when matched then update set balance = 1; -execute foom; -SELECT * FROM target ORDER BY tid; -ROLLBACK; - -BEGIN; -PREPARE foom2 (integer, integer) AS -MERGE INTO target t -USING (SELECT 1) s -ON t.tid = $1 -WHEN MATCHED THEN -UPDATE SET balance = $2; ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -execute foom2 (1, 1); -SELECT * FROM target ORDER BY tid; -ROLLBACK; - --- subqueries in source relation - -CREATE TABLE sq_target (tid integer NOT NULL, balance integer); -CREATE TABLE sq_source (delta integer, sid integer, balance integer DEFAULT 0); - -INSERT INTO sq_target(tid, balance) VALUES (1,100), (2,200), (3,300); -INSERT INTO sq_source(sid, delta) VALUES (1,10), (2,20), (4,40); - -BEGIN; -MERGE INTO sq_target t -USING (SELECT * FROM sq_source) s -ON tid = sid -WHEN MATCHED AND t.balance > delta THEN - UPDATE SET balance = t.balance + delta; -SELECT * FROM sq_target; -ROLLBACK; - --- try a view -CREATE VIEW v AS SELECT * FROM sq_source WHERE sid < 2; - -BEGIN; -MERGE INTO sq_target -USING v -ON tid = sid -WHEN MATCHED THEN - UPDATE SET balance = v.balance + delta; -SELECT * FROM sq_target; -ROLLBACK; - --- ambiguous reference to a column -BEGIN; -MERGE INTO sq_target -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE; -ROLLBACK; - -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE; -SELECT * FROM sq_target; -ROLLBACK; - --- CTEs -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -WITH targq AS ( - SELECT * FROM v -) -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE -; -ROLLBACK; - --- RETURNING -BEGIN; -INSERT INTO sq_source (sid, balance, delta) VALUES (-1, -1, -10); -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND tid > 2 THEN - UPDATE SET balance = t.balance + delta -WHEN NOT MATCHED THEN - INSERT (balance, tid) VALUES (balance + delta, sid) -WHEN MATCHED AND tid < 2 THEN - DELETE -RETURNING * -; -ROLLBACK; - --- EXPLAIN -CREATE TABLE ex_mtarget (a int, b int); -CREATE TABLE ex_msource (a int, b int); -INSERT INTO ex_mtarget SELECT i, i*10 FROM generate_series(1,100,2) i; -INSERT INTO ex_msource SELECT i, i*10 FROM generate_series(1,100,1) i; - --- only updates ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = t.b + 1; - --- only updates to selected tuples ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1; - --- updates + deletes ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1 -WHEN MATCHED AND t.a >= 10 AND t.a <= 20 THEN - DELETE; - --- only inserts ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN NOT MATCHED AND s.a < 10 THEN - INSERT VALUES (a, b); - --- all three ---EXPLAIN (ANALYZE ON, COSTS OFF, SUMMARY OFF, TIMING OFF) -MERGE INTO ex_mtarget t USING ex_msource s ON t.a = s.a -WHEN MATCHED AND t.a < 10 THEN - UPDATE SET b = t.b + 1 -WHEN MATCHED AND t.a >= 30 AND t.a <= 40 THEN - DELETE -WHEN NOT MATCHED AND s.a < 20 THEN - INSERT VALUES (a, b); - -DROP TABLE ex_msource, ex_mtarget; - --- Subqueries -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED THEN - UPDATE SET balance = (SELECT count(*) FROM sq_target) -; -SELECT * FROM sq_target WHERE tid = 1; -ROLLBACK; - -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid -WHEN MATCHED AND (SELECT count(*) > 0 FROM sq_target) THEN - UPDATE SET balance = 42 -; -SELECT * FROM sq_target WHERE tid = 1; -ROLLBACK; - -BEGIN; -MERGE INTO sq_target t -USING v -ON tid = sid AND (SELECT count(*) > 0 FROM sq_target) -WHEN MATCHED THEN - UPDATE SET balance = 42 -; -SELECT * FROM sq_target WHERE tid = 1; -ROLLBACK; - -DROP TABLE sq_target, sq_source CASCADE; - -CREATE TABLE pa_target (tid integer, balance float, val text) - PARTITION BY LIST (tid); - -CREATE TABLE part1 PARTITION OF pa_target FOR VALUES IN (1,4); -CREATE TABLE part2 PARTITION OF pa_target FOR VALUES IN (2,5,6); -CREATE TABLE part3 PARTITION OF pa_target FOR VALUES IN (3,8,9); -CREATE TABLE part4 PARTITION OF pa_target DEFAULT; - -CREATE TABLE pa_source (sid integer, delta float); --- insert many rows to the source table -INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,14,2) AS id; - --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - --- same with a constant qual -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid AND tid = 1 - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - --- try updating the partition key column -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - -DROP TABLE pa_target CASCADE; - --- The target table is partitioned in the same way, but this time by attaching --- partitions which have columns in different order, dropped columns etc. -CREATE TABLE pa_target (tid integer, balance float, val text) - PARTITION BY LIST (tid); -CREATE TABLE part1 (tid integer, balance float, val text); -CREATE TABLE part2 (balance float, tid integer, val text); -CREATE TABLE part3 (tid integer, balance float, val text); -CREATE TABLE part4 (extraid text, tid integer, balance float, val text); -ALTER TABLE part4 DROP COLUMN extraid; - -ALTER TABLE pa_target ATTACH PARTITION part1 FOR VALUES IN (1,4); -ALTER TABLE pa_target ATTACH PARTITION part2 FOR VALUES IN (2,5,6); -ALTER TABLE pa_target ATTACH PARTITION part3 FOR VALUES IN (3,8,9); -ALTER TABLE pa_target ATTACH PARTITION part4 DEFAULT; - --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT id, id * 100, 'initial' FROM generate_series(1,14,2) AS id; - --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - --- same with a constant qual -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid AND tid = 1 - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - --- try updating the partition key column -BEGIN; -MERGE INTO pa_target t - USING pa_source s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - -DROP TABLE pa_source; -DROP TABLE pa_target CASCADE; - --- Sub-partitionin -CREATE TABLE pa_target (logts timestamp, tid integer, balance float, val text) - PARTITION BY RANGE (logts); - -CREATE TABLE part_m01 PARTITION OF pa_target - FOR VALUES FROM ('2017-01-01') TO ('2017-02-01') - PARTITION BY LIST (tid); -CREATE TABLE part_m01_odd PARTITION OF part_m01 - FOR VALUES IN (1,3,5,7,9); -CREATE TABLE part_m01_even PARTITION OF part_m01 - FOR VALUES IN (2,4,6,8); -CREATE TABLE part_m02 PARTITION OF pa_target - FOR VALUES FROM ('2017-02-01') TO ('2017-03-01') - PARTITION BY LIST (tid); -CREATE TABLE part_m02_odd PARTITION OF part_m02 - FOR VALUES IN (1,3,5,7,9); -CREATE TABLE part_m02_even PARTITION OF part_m02 - FOR VALUES IN (2,4,6,8); - -CREATE TABLE pa_source (sid integer, delta float); --- insert many rows to the source table -INSERT INTO pa_source SELECT id, id * 10 FROM generate_series(1,14) AS id; --- insert a few rows in the target table (odd numbered tid) -INSERT INTO pa_target SELECT '2017-01-31', id, id * 100, 'initial' FROM generate_series(1,9,3) AS id; -INSERT INTO pa_target SELECT '2017-02-28', id, id * 100, 'initial' FROM generate_series(2,9,3) AS id; - --- try simple MERGE -BEGIN; -MERGE INTO pa_target t - USING (SELECT '2017-01-15' AS slogts, * FROM pa_source WHERE sid < 10) s - ON t.tid = s.sid - WHEN MATCHED THEN - UPDATE SET balance = balance + delta, val = val || ' updated by merge' - WHEN NOT MATCHED THEN - INSERT VALUES (slogts::timestamp, sid, delta, 'inserted by merge'); -SELECT * FROM pa_target ORDER BY tid; -ROLLBACK; - -DROP TABLE pa_source; -DROP TABLE pa_target CASCADE; - --- some complex joins on the source side - -CREATE TABLE cj_target (tid integer, balance float, val text); -CREATE TABLE cj_source1 (sid1 integer, scat integer, delta integer); -CREATE TABLE cj_source2 (sid2 integer, sval text); -INSERT INTO cj_source1 VALUES (1, 10, 100); -INSERT INTO cj_source1 VALUES (1, 20, 200); -INSERT INTO cj_source1 VALUES (2, 20, 300); -INSERT INTO cj_source1 VALUES (3, 10, 400); -INSERT INTO cj_source2 VALUES (1, 'initial source2'); -INSERT INTO cj_source2 VALUES (2, 'initial source2'); -INSERT INTO cj_source2 VALUES (3, 'initial source2'); - --- source relation is an unalised join -MERGE INTO cj_target t -USING cj_source1 s1 - INNER JOIN cj_source2 s2 ON sid1 = sid2 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid1, delta, sval); - --- try accessing columns from either side of the source join -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid2, delta, sval) -WHEN MATCHED THEN - DELETE; - --- some simple expressions in INSERT targetlist -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 -ON t.tid = sid1 -WHEN NOT MATCHED THEN - INSERT VALUES (sid2, delta + scat, sval) -WHEN MATCHED THEN - UPDATE SET val = val || ' updated by merge'; - -MERGE INTO cj_target t -USING cj_source2 s2 - INNER JOIN cj_source1 s1 ON sid1 = sid2 AND scat = 20 -ON t.tid = sid1 -WHEN MATCHED THEN - UPDATE SET val = val || ' ' || delta::text; - -SELECT * FROM cj_target; - -ALTER TABLE cj_source1 RENAME COLUMN sid1 TO sid; -ALTER TABLE cj_source2 RENAME COLUMN sid2 TO sid; - -TRUNCATE cj_target; - -MERGE INTO cj_target t -USING cj_source1 s1 - INNER JOIN cj_source2 s2 ON s1.sid = s2.sid -ON t.tid = s1.sid -WHEN NOT MATCHED THEN - INSERT VALUES (s2.sid, delta, sval); - -DROP TABLE cj_source2, cj_source1, cj_target; - --- Function scans -CREATE TABLE fs_target (a int, b int, c text); -MERGE INTO fs_target t -USING generate_series(1,100,1) AS id -ON t.a = id -WHEN MATCHED THEN - UPDATE SET b = b + id -WHEN NOT MATCHED THEN - INSERT VALUES (id, -1); - -MERGE INTO fs_target t -USING generate_series(1,100,2) AS id -ON t.a = id -WHEN MATCHED THEN - UPDATE SET b = b + id, c = 'updated '|| id.*::text -WHEN NOT MATCHED THEN - INSERT VALUES (id, -1, 'inserted ' || id.*::text); - -SELECT count(*) FROM fs_target; -DROP TABLE fs_target; - --- SERIALIZABLE test --- handled in isolation tests - --- prepare - -RESET SESSION AUTHORIZATION; -DROP TABLE target, target2; -DROP TABLE source, source2; -DROP FUNCTION merge_trigfunc(); -DROP USER merge_privs; -DROP USER merge_no_privs; diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index 1a20c1f7652..7a71f7659ce 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -29,3 +29,35 @@ SELECT num_nulls(VARIADIC '{}'::int[]); -- should fail, one or more arguments is required SELECT num_nonnulls(); SELECT num_nulls(); + +-- +-- Test adding a support function to a subject function +-- + +CREATE FUNCTION my_int_eq(int, int) RETURNS bool + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$int4eq$$; + +-- By default, planner does not think that's selective +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + +-- With support function that knows it's int4eq, we get a different plan +ALTER FUNCTION my_int_eq(int, int) SUPPORT test_support_func; + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN tenk1 b ON a.unique1 = b.unique1 +WHERE my_int_eq(a.unique2, 42); + +-- Also test non-default rowcount estimate +CREATE FUNCTION my_gen_series(int, int) RETURNS SETOF integer + LANGUAGE internal STRICT IMMUTABLE PARALLEL SAFE + AS $$generate_series_int4$$ + SUPPORT test_support_func; + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,1000) g ON a.unique1 = g; + +EXPLAIN (COSTS OFF) +SELECT * FROM tenk1 a JOIN my_gen_series(1,10) g ON a.unique1 = g; diff --git a/src/test/regress/sql/misc_sanity.sql b/src/test/regress/sql/misc_sanity.sql index b921117fa52..3ce32e47252 100644 --- a/src/test/regress/sql/misc_sanity.sql +++ b/src/test/regress/sql/misc_sanity.sql @@ -54,7 +54,10 @@ declare relnm text; begin for relnm, reloid, shared in select relname, oid, relisshared from pg_class - where relhasoids and oid < 16384 order by 1 + where EXISTS( + SELECT * FROM pg_attribute + WHERE attrelid = pg_class.oid AND attname = 'oid') + and relkind = 'r' and oid < 16384 order by 1 loop execute 'select min(oid) from ' || relnm into lowoid; continue when lowoid is null or lowoid >= 16384; @@ -72,3 +75,22 @@ loop end if; end loop; end$$; + +-- **************** pg_class **************** + +-- Look for system tables with varlena columns but no toast table. All +-- system tables with toastable columns should have toast tables, with +-- the following exceptions: +-- 1. pg_class, pg_attribute, and pg_index, due to fear of recursive +-- dependencies as toast tables depend on them. +-- 2. pg_largeobject and pg_largeobject_metadata. Large object catalogs +-- and toast tables are mutually exclusive and large object data is handled +-- as user data by pg_upgrade, which would cause failures. + +SELECT relname, attname, atttypid::regtype +FROM pg_class c JOIN pg_attribute a ON c.oid = attrelid +WHERE c.oid < 16384 AND + reltoastrelid = 0 AND + relkind = 'r' AND + attstorage != 'p' +ORDER BY 1, 2; diff --git a/src/test/regress/sql/money.sql b/src/test/regress/sql/money.sql index 37b9ecce1fc..5e746286c90 100644 --- a/src/test/regress/sql/money.sql +++ b/src/test/regress/sql/money.sql @@ -1,6 +1,8 @@ -- -- MONEY -- +-- Note that we assume lc_monetary has been set to C. +-- CREATE TABLE money_data (m money); @@ -122,6 +124,8 @@ SELECT (-1234567890)::int4::money; SELECT (-12345678901234567)::int8::money; SELECT (-12345678901234567)::numeric::money; --- Cast from money +-- Cast from money to numeric SELECT '12345678901234567'::money::numeric; SELECT '-12345678901234567'::money::numeric; +SELECT '92233720368547758.07'::money::numeric; +SELECT '-92233720368547758.08'::money::numeric; diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sql index d77504e6246..a9394123596 100644 --- a/src/test/regress/sql/numeric.sql +++ b/src/test/regress/sql/numeric.sql @@ -911,6 +911,13 @@ select (-12.34) ^ 0.0; select 12.34 ^ 0.0; select 0.0 ^ 12.34; +-- NaNs +select 'NaN'::numeric ^ 'NaN'::numeric; +select 'NaN'::numeric ^ 0; +select 'NaN'::numeric ^ 1; +select 0 ^ 'NaN'::numeric; +select 1 ^ 'NaN'::numeric; + -- invalid inputs select 0.0 ^ (-12.34); select (-12.34) ^ 1.2; diff --git a/src/test/regress/sql/object_address.sql b/src/test/regress/sql/object_address.sql index 55faa71edfb..8e06248eb5e 100644 --- a/src/test/regress/sql/object_address.sql +++ b/src/test/regress/sql/object_address.sql @@ -22,6 +22,9 @@ CREATE TEXT SEARCH PARSER addr_ts_prs CREATE TABLE addr_nsp.gentable ( a serial primary key CONSTRAINT a_chk CHECK (a > 0), b text DEFAULT 'hello'); +CREATE TABLE addr_nsp.parttable ( + a int PRIMARY KEY +) PARTITION BY RANGE (a); CREATE VIEW addr_nsp.genview AS SELECT * from addr_nsp.gentable; CREATE MATERIALIZED VIEW addr_nsp.genmatview AS SELECT * FROM addr_nsp.gentable; CREATE TYPE addr_nsp.gencomptype AS (a int); @@ -37,11 +40,16 @@ CREATE SERVER "integer" FOREIGN DATA WRAPPER addr_fdw; CREATE USER MAPPING FOR regress_addr_user SERVER "integer"; ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user IN SCHEMA public GRANT ALL ON TABLES TO regress_addr_user; ALTER DEFAULT PRIVILEGES FOR ROLE regress_addr_user REVOKE DELETE ON TABLES FROM regress_addr_user; +-- this transform would be quite unsafe to leave lying around, +-- except that the SQL language pays no attention to transforms: CREATE TRANSFORM FOR int LANGUAGE SQL ( - FROM SQL WITH FUNCTION varchar_transform(internal), + FROM SQL WITH FUNCTION prsd_lextype(internal), TO SQL WITH FUNCTION int4recv(internal)); +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR'; CREATE PUBLICATION addr_pub FOR TABLE addr_nsp.gentable; -CREATE SUBSCRIPTION addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); +RESET client_min_messages; +CREATE SUBSCRIPTION regress_addr_sub CONNECTION '' PUBLICATION bar WITH (connect = false, slot_name = NONE); CREATE STATISTICS addr_nsp.gentable_stat ON a, b FROM addr_nsp.gentable; -- test some error cases @@ -138,7 +146,9 @@ SELECT pg_get_object_address('subscription', '{one,two}', '{}'); -- test successful cases WITH objects (type, name, args) AS (VALUES ('table', '{addr_nsp, gentable}'::text[], '{}'::text[]), + ('table', '{addr_nsp, parttable}'::text[], '{}'::text[]), ('index', '{addr_nsp, gentable_pkey}', '{}'), + ('index', '{addr_nsp, parttable_pkey}', '{}'), ('sequence', '{addr_nsp, gentable_a_seq}', '{}'), -- toast table ('view', '{addr_nsp, genview}', '{}'), @@ -157,7 +167,7 @@ WITH objects (type, name, args) AS (VALUES ('collation', '{default}', '{}'), ('table constraint', '{addr_nsp, gentable, a_chk}', '{}'), ('domain constraint', '{addr_nsp.gendomain}', '{domconstr}'), - ('conversion', '{pg_catalog, ascii_to_mic}', '{}'), + ('conversion', '{pg_catalog, koi8_r_to_mic}', '{}'), ('default value', '{addr_nsp, gentable, b}', '{}'), ('language', '{plpgsql}', '{}'), -- large object @@ -188,7 +198,7 @@ WITH objects (type, name, args) AS (VALUES ('access method', '{btree}', '{}'), ('publication', '{addr_pub}', '{}'), ('publication relation', '{addr_nsp, gentable}', '{addr_pub}'), - ('subscription', '{addr_sub}', '{}'), + ('subscription', '{regress_addr_sub}', '{}'), ('statistics object', '{addr_nsp, gentable_stat}', '{}') ) SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, @@ -203,11 +213,9 @@ SELECT (pg_identify_object(addr1.classid, addr1.objid, addr1.objsubid)).*, --- --- Cleanup resources --- -\set VERBOSITY terse \\ -- suppress cascade details - DROP FOREIGN DATA WRAPPER addr_fdw CASCADE; DROP PUBLICATION addr_pub; -DROP SUBSCRIPTION addr_sub; +DROP SUBSCRIPTION regress_addr_sub; DROP SCHEMA addr_nsp CASCADE; diff --git a/src/test/regress/sql/oidjoins.sql b/src/test/regress/sql/oidjoins.sql index 656cace4511..b774cbca5b6 100644 --- a/src/test/regress/sql/oidjoins.sql +++ b/src/test/regress/sql/oidjoins.sql @@ -381,6 +381,10 @@ SELECT ctid, partrelid FROM pg_catalog.pg_partitioned_table fk WHERE partrelid != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partrelid); +SELECT ctid, partdefid +FROM pg_catalog.pg_partitioned_table fk +WHERE partdefid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_class pk WHERE pk.oid = fk.partdefid); SELECT ctid, polrelid FROM pg_catalog.pg_policy fk WHERE polrelid != 0 AND @@ -401,10 +405,10 @@ SELECT ctid, provariadic FROM pg_catalog.pg_proc fk WHERE provariadic != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.provariadic); -SELECT ctid, protransform +SELECT ctid, prosupport FROM pg_catalog.pg_proc fk -WHERE protransform != 0 AND - NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.protransform); +WHERE prosupport != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_proc pk WHERE pk.oid = fk.prosupport); SELECT ctid, prorettype FROM pg_catalog.pg_proc fk WHERE prorettype != 0 AND @@ -489,6 +493,10 @@ SELECT ctid, stxowner FROM pg_catalog.pg_statistic_ext fk WHERE stxowner != 0 AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_authid pk WHERE pk.oid = fk.stxowner); +SELECT ctid, stxoid +FROM pg_catalog.pg_statistic_ext_data fk +WHERE stxoid != 0 AND + NOT EXISTS(SELECT 1 FROM pg_catalog.pg_statistic_ext pk WHERE pk.oid = fk.stxoid); SELECT ctid, spcowner FROM pg_catalog.pg_tablespace fk WHERE spcowner != 0 AND diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index a593d376438..624bea46cea 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -22,6 +22,8 @@ -- allowed. -- This should match IsBinaryCoercible() in parse_coerce.c. +-- It doesn't currently know about some cases, notably domains, anyelement, +-- anynonarray, anyenum, or record, but it doesn't need to (yet). create function binary_coercible(oid, oid) returns bool as $$ begin if $1 = $2 then return true; end if; @@ -43,9 +45,11 @@ begin end $$ language plpgsql strict stable; --- This one ignores castcontext, so it considers only physical equivalence --- and not whether the coercion can be invoked implicitly. -create function physically_coercible(oid, oid) returns bool as $$ +-- This one ignores castcontext, so it will allow cases where an explicit +-- (but still binary) cast would be required to convert the input type. +-- We don't currently use this for any tests in this file, but it is a +-- reasonable alternative definition for some scenarios. +create function explicitly_binary_coercible(oid, oid) returns bool as $$ begin if $1 = $2 then return true; end if; if EXISTS(select 1 from pg_catalog.pg_cast where @@ -349,10 +353,10 @@ WHERE proallargtypes IS NOT NULL AND FROM generate_series(1, array_length(proallargtypes, 1)) g(i) WHERE proargmodes IS NULL OR proargmodes[i] IN ('i', 'b', 'v')); --- Check for protransform functions with the wrong signature +-- Check for prosupport functions with the wrong signature SELECT p1.oid, p1.proname, p2.oid, p2.proname FROM pg_proc AS p1, pg_proc AS p2 -WHERE p2.oid = p1.protransform AND +WHERE p2.oid = p1.prosupport AND (p2.prorettype != 'internal'::regtype OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); @@ -741,7 +745,7 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999; -- Check that operators' underlying functions have suitable comments, -- namely 'implementation of XXX operator'. (Note: it's not necessary to --- put such comments into pg_proc.h; initdb will generate them as needed.) +-- put such comments into pg_proc.dat; initdb will generate them as needed.) -- In some cases involving legacy names for operators, there are multiple -- operators referencing the same pg_proc entry, so ignore operators whose -- comments say they are deprecated. @@ -785,6 +789,36 @@ SELECT p_oid, proname, prodesc FROM funcdescs AND oprdesc NOT LIKE 'deprecated%' ORDER BY 1; +-- Operators that are commutator pairs should have identical volatility +-- and leakproofness markings on their implementation functions. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprcom = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + +-- Likewise for negator pairs. +SELECT o1.oid, o1.oprcode, o2.oid, o2.oprcode +FROM pg_operator AS o1, pg_operator AS o2, pg_proc AS p1, pg_proc AS p2 +WHERE o1.oprnegate = o2.oid AND p1.oid = o1.oprcode AND p2.oid = o2.oprcode AND + (p1.provolatile != p2.provolatile OR + p1.proleakproof != p2.proleakproof); + +-- Btree comparison operators' functions should have the same volatility +-- and leakproofness markings as the associated comparison support function. +SELECT pp.oid::regprocedure as proc, pp.provolatile as vp, pp.proleakproof as lp, + po.oid::regprocedure as opr, po.provolatile as vo, po.proleakproof as lo +FROM pg_proc pp, pg_proc po, pg_operator o, pg_amproc ap, pg_amop ao +WHERE pp.oid = ap.amproc AND po.oid = o.oprcode AND o.oid = ao.amopopr AND + ao.amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND + ao.amopfamily = ap.amprocfamily AND + ao.amoplefttype = ap.amproclefttype AND + ao.amoprighttype = ap.amprocrighttype AND + ap.amprocnum = 1 AND + (pp.provolatile != po.provolatile OR + pp.proleakproof != po.proleakproof) +ORDER BY 1; + -- **************** pg_aggregate **************** @@ -822,8 +856,6 @@ WHERE a.aggfnoid = p.oid AND a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype; -- Cross-check transfn against its entry in pg_proc. --- NOTE: use physically_coercible here, not binary_coercible, because --- max and min on abstime are implemented using int4larger/int4smaller. SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.proname FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptr WHERE a.aggfnoid = p.oid AND @@ -832,15 +864,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggtranstype) - OR NOT physically_coercible(a.aggtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggtranstype) + OR NOT binary_coercible(a.aggtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); -- Cross-check finalfn (if present) against its entry in pg_proc. @@ -860,7 +893,8 @@ WHERE a.aggfnoid = p.oid AND NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) OR (pfn.pronargs > 3 AND NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) - -- we could carry the check further, but 3 args is enough for now + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) ); -- If transfn is strict then either initval should be non-NULL, or @@ -904,15 +938,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggmtranstype) - OR NOT physically_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); -- Cross-check minvtransfn (if present) against its entry in pg_proc. @@ -924,15 +959,16 @@ WHERE a.aggfnoid = p.oid AND OR NOT (ptr.pronargs = CASE WHEN a.aggkind = 'n' THEN p.pronargs + 1 ELSE greatest(p.pronargs - a.aggnumdirectargs, 1) + 1 END) - OR NOT physically_coercible(ptr.prorettype, a.aggmtranstype) - OR NOT physically_coercible(a.aggmtranstype, ptr.proargtypes[0]) + OR NOT binary_coercible(ptr.prorettype, a.aggmtranstype) + OR NOT binary_coercible(a.aggmtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND - NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) + NOT binary_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND - NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) + NOT binary_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND - NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) + NOT binary_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but 3 args is enough for now + OR (p.pronargs > 3) ); -- Cross-check mfinalfn (if present) against its entry in pg_proc. @@ -952,7 +988,8 @@ WHERE a.aggfnoid = p.oid AND NOT binary_coercible(p.proargtypes[1], pfn.proargtypes[2])) OR (pfn.pronargs > 3 AND NOT binary_coercible(p.proargtypes[2], pfn.proargtypes[3])) - -- we could carry the check further, but 3 args is enough for now + -- we could carry the check further, but 4 args is enough for now + OR (pfn.pronargs > 4) ); -- If mtransfn is strict then either minitval should be non-NULL, or @@ -977,8 +1014,6 @@ WHERE a.aggfnoid = p.oid AND -- Check that all combine functions have signature -- combine(transtype, transtype) returns transtype --- NOTE: use physically_coercible here, not binary_coercible, because --- max and min on abstime are implemented using int4larger/int4smaller. SELECT a.aggfnoid, p.proname FROM pg_aggregate as a, pg_proc as p @@ -986,7 +1021,7 @@ WHERE a.aggcombinefn = p.oid AND (p.pronargs != 2 OR p.prorettype != p.proargtypes[0] OR p.prorettype != p.proargtypes[1] OR - NOT physically_coercible(a.aggtranstype, p.proargtypes[0])); + NOT binary_coercible(a.aggtranstype, p.proargtypes[0])); -- Check that no combine function for an INTERNAL transtype is strict. @@ -1117,6 +1152,14 @@ SELECT p1.oid FROM pg_opfamily as p1 WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0; +-- Look for opfamilies having no opclasses. While most validation of +-- opfamilies is now handled by AM-specific amvalidate functions, that's +-- driven from pg_opclass entries below, so an empty opfamily would not +-- get noticed. + +SELECT oid, opfname FROM pg_opfamily f +WHERE NOT EXISTS (SELECT 1 FROM pg_opclass WHERE opcfamily = f.oid); + -- **************** pg_opclass **************** @@ -1156,15 +1199,25 @@ SELECT p1.oid, p1.amname FROM pg_am AS p1 WHERE p1.amhandler = 0; --- Check for amhandler functions with the wrong signature +-- Check for index amhandler functions with the wrong signature SELECT p1.oid, p1.amname, p2.oid, p2.proname FROM pg_am AS p1, pg_proc AS p2 -WHERE p2.oid = p1.amhandler AND - (p2.prorettype != 'index_am_handler'::regtype OR p2.proretset +WHERE p2.oid = p1.amhandler AND p1.amtype = 'i' AND + (p2.prorettype != 'index_am_handler'::regtype + OR p2.proretset OR p2.pronargs != 1 OR p2.proargtypes[0] != 'internal'::regtype); +-- Check for table amhandler functions with the wrong signature + +SELECT p1.oid, p1.amname, p2.oid, p2.proname +FROM pg_am AS p1, pg_proc AS p2 +WHERE p2.oid = p1.amhandler AND p1.amtype = 's' AND + (p2.prorettype != 'table_am_handler'::regtype + OR p2.proretset + OR p2.pronargs != 1 + OR p2.proargtypes[0] != 'internal'::regtype); -- **************** pg_amop **************** @@ -1320,16 +1373,21 @@ ORDER BY 1; -- a representational error in pg_index, but simply wrong catalog design. -- It's bad because we expect to be able to clone template0 and assign the -- copy a different database collation. It would especially not work for --- shared catalogs. Note that although text columns will show a collation --- in indcollation, they're still okay to index with text_pattern_ops, --- so allow that case. +-- shared catalogs. + +SELECT relname, attname, attcollation +FROM pg_class c, pg_attribute a +WHERE c.oid = attrelid AND c.oid < 16384 AND + c.relkind != 'v' AND -- we don't care about columns in views + attcollation != 0 AND + attcollation != (SELECT oid FROM pg_collation WHERE collname = 'C'); + +-- Double-check that collation-sensitive indexes have "C" collation, too. SELECT indexrelid::regclass, indrelid::regclass, iclass, icoll FROM (SELECT indexrelid, indrelid, unnest(indclass) as iclass, unnest(indcollation) as icoll FROM pg_index WHERE indrelid < 16384) ss -WHERE icoll != 0 AND iclass != - (SELECT oid FROM pg_opclass - WHERE opcname = 'text_pattern_ops' AND opcmethod = - (SELECT oid FROM pg_am WHERE amname = 'btree')); +WHERE icoll != 0 AND + icoll != (SELECT oid FROM pg_collation WHERE collname = 'C'); diff --git a/src/test/regress/sql/partition_aggregate.sql b/src/test/regress/sql/partition_aggregate.sql index c60d7d23424..dcd6edbad28 100644 --- a/src/test/regress/sql/partition_aggregate.sql +++ b/src/test/regress/sql/partition_aggregate.sql @@ -111,6 +111,11 @@ EXPLAIN (COSTS OFF) SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; SELECT t1.x, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; +-- Check with whole-row reference; partitionwise aggregation does not apply +EXPLAIN (COSTS OFF) +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; +SELECT t1.x, sum(t1.y), count(t1) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t1.x ORDER BY 1, 2, 3; + -- GROUP BY having other matching key EXPLAIN (COSTS OFF) SELECT t2.y, sum(t1.y), count(*) FROM pagg_tab1 t1, pagg_tab2 t2 WHERE t1.x = t2.y GROUP BY t2.y ORDER BY 1, 2, 3; @@ -144,16 +149,18 @@ EXPLAIN (COSTS OFF) SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST; SELECT a.x, sum(b.x) FROM pagg_tab1 a FULL OUTER JOIN pagg_tab2 b ON a.x = b.y GROUP BY a.x ORDER BY 1 NULLS LAST; --- LEFT JOIN, with dummy relation on right side, +-- LEFT JOIN, with dummy relation on right side, ideally -- should produce full partitionwise aggregation plan as GROUP BY is on --- non-nullable columns +-- non-nullable columns. +-- But right now we are unable to do partitionwise join in this case. EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a LEFT JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; --- FULL JOIN, with dummy relations on both sides, +-- FULL JOIN, with dummy relations on both sides, ideally -- should produce partial partitionwise aggregation plan as GROUP BY is on --- nullable columns +-- nullable columns. +-- But right now we are unable to do partitionwise join in this case. EXPLAIN (COSTS OFF) SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; SELECT a.x, b.y, count(*) FROM (SELECT * FROM pagg_tab1 WHERE x < 20) a FULL JOIN (SELECT * FROM pagg_tab2 WHERE y > 10) b ON a.x = b.y WHERE a.x > 5 or b.y < 20 GROUP BY a.x, b.y ORDER BY 1, 2; @@ -294,3 +301,27 @@ SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < EXPLAIN (COSTS OFF) SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3; SELECT y, sum(x), avg(x), count(*) FROM pagg_tab_para GROUP BY y HAVING avg(x) < 12 ORDER BY 1, 2, 3; + +-- Test when parent can produce parallel paths but not any (or some) of its children +ALTER TABLE pagg_tab_para_p1 SET (parallel_workers = 0); +ALTER TABLE pagg_tab_para_p3 SET (parallel_workers = 0); +ANALYZE pagg_tab_para; + +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +ALTER TABLE pagg_tab_para_p2 SET (parallel_workers = 0); +ANALYZE pagg_tab_para; + +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; + +-- Reset parallelism parameters to get partitionwise aggregation plan. +RESET min_parallel_table_scan_size; +RESET parallel_setup_cost; + +EXPLAIN (COSTS OFF) +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; +SELECT x, sum(y), avg(y), count(*) FROM pagg_tab_para GROUP BY x HAVING avg(y) < 7 ORDER BY 1, 2, 3; diff --git a/src/test/regress/sql/partition_info.sql b/src/test/regress/sql/partition_info.sql new file mode 100644 index 00000000000..b5060bec7f0 --- /dev/null +++ b/src/test/regress/sql/partition_info.sql @@ -0,0 +1,129 @@ +-- +-- Tests for functions providing information about partitions +-- +SELECT * FROM pg_partition_tree(NULL); +SELECT * FROM pg_partition_tree(0); +SELECT * FROM pg_partition_ancestors(NULL); +SELECT * FROM pg_partition_ancestors(0); +SELECT pg_partition_root(NULL); +SELECT pg_partition_root(0); + +-- Test table partition trees +CREATE TABLE ptif_test (a int, b int) PARTITION BY range (a); +CREATE TABLE ptif_test0 PARTITION OF ptif_test + FOR VALUES FROM (minvalue) TO (0) PARTITION BY list (b); +CREATE TABLE ptif_test01 PARTITION OF ptif_test0 FOR VALUES IN (1); +CREATE TABLE ptif_test1 PARTITION OF ptif_test + FOR VALUES FROM (0) TO (100) PARTITION BY list (b); +CREATE TABLE ptif_test11 PARTITION OF ptif_test1 FOR VALUES IN (1); +CREATE TABLE ptif_test2 PARTITION OF ptif_test + FOR VALUES FROM (100) TO (200); +-- This partitioned table should remain with no partitions. +CREATE TABLE ptif_test3 PARTITION OF ptif_test + FOR VALUES FROM (200) TO (maxvalue) PARTITION BY list (b); + +-- Test pg_partition_root for tables +SELECT pg_partition_root('ptif_test'); +SELECT pg_partition_root('ptif_test0'); +SELECT pg_partition_root('ptif_test01'); +SELECT pg_partition_root('ptif_test3'); + +-- Test index partition tree +CREATE INDEX ptif_test_index ON ONLY ptif_test (a); +CREATE INDEX ptif_test0_index ON ONLY ptif_test0 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test0_index; +CREATE INDEX ptif_test01_index ON ptif_test01 (a); +ALTER INDEX ptif_test0_index ATTACH PARTITION ptif_test01_index; +CREATE INDEX ptif_test1_index ON ONLY ptif_test1 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test1_index; +CREATE INDEX ptif_test11_index ON ptif_test11 (a); +ALTER INDEX ptif_test1_index ATTACH PARTITION ptif_test11_index; +CREATE INDEX ptif_test2_index ON ptif_test2 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test2_index; +CREATE INDEX ptif_test3_index ON ptif_test3 (a); +ALTER INDEX ptif_test_index ATTACH PARTITION ptif_test3_index; + +-- Test pg_partition_root for indexes +SELECT pg_partition_root('ptif_test_index'); +SELECT pg_partition_root('ptif_test0_index'); +SELECT pg_partition_root('ptif_test01_index'); +SELECT pg_partition_root('ptif_test3_index'); + +-- List all tables members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test'); +-- List tables from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0') p + JOIN pg_class c ON (p.relid = c.oid); +-- List from leaf table +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01') p + JOIN pg_class c ON (p.relid = c.oid); +-- List from partitioned table with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3') p + JOIN pg_class c ON (p.relid = c.oid); +-- List all ancestors of root and leaf tables +SELECT * FROM pg_partition_ancestors('ptif_test01'); +SELECT * FROM pg_partition_ancestors('ptif_test'); +-- List all members using pg_partition_root with leaf table reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01')) p + JOIN pg_class c ON (p.relid = c.oid); + +-- List all indexes members of the tree +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test_index'); +-- List indexes from an intermediate level +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test0_index') p + JOIN pg_class c ON (p.relid = c.oid); +-- List from leaf index +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test01_index') p + JOIN pg_class c ON (p.relid = c.oid); +-- List from partitioned index with no partitions +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_test3_index') p + JOIN pg_class c ON (p.relid = c.oid); +-- List all members using pg_partition_root with leaf index reference +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree(pg_partition_root('ptif_test01_index')) p + JOIN pg_class c ON (p.relid = c.oid); +-- List all ancestors of root and leaf indexes +SELECT * FROM pg_partition_ancestors('ptif_test01_index'); +SELECT * FROM pg_partition_ancestors('ptif_test_index'); + +DROP TABLE ptif_test; + +-- Table that is not part of any partition tree is not listed. +CREATE TABLE ptif_normal_table(a int); +SELECT relid, parentrelid, level, isleaf + FROM pg_partition_tree('ptif_normal_table'); +SELECT * FROM pg_partition_ancestors('ptif_normal_table'); +SELECT pg_partition_root('ptif_normal_table'); +DROP TABLE ptif_normal_table; + +-- Various partitioning-related functions return empty/NULL if passed relations +-- of types that cannot be part of a partition tree; for example, views, +-- materialized views, legacy inheritance children or parents, etc. +CREATE VIEW ptif_test_view AS SELECT 1; +CREATE MATERIALIZED VIEW ptif_test_matview AS SELECT 1; +CREATE TABLE ptif_li_parent (); +CREATE TABLE ptif_li_child () INHERITS (ptif_li_parent); +SELECT * FROM pg_partition_tree('ptif_test_view'); +SELECT * FROM pg_partition_tree('ptif_test_matview'); +SELECT * FROM pg_partition_tree('ptif_li_parent'); +SELECT * FROM pg_partition_tree('ptif_li_child'); +SELECT * FROM pg_partition_ancestors('ptif_test_view'); +SELECT * FROM pg_partition_ancestors('ptif_test_matview'); +SELECT * FROM pg_partition_ancestors('ptif_li_parent'); +SELECT * FROM pg_partition_ancestors('ptif_li_child'); +SELECT pg_partition_root('ptif_test_view'); +SELECT pg_partition_root('ptif_test_matview'); +SELECT pg_partition_root('ptif_li_parent'); +SELECT pg_partition_root('ptif_li_child'); +DROP VIEW ptif_test_view; +DROP MATERIALIZED VIEW ptif_test_matview; +DROP TABLE ptif_li_parent, ptif_li_child; diff --git a/src/test/regress/sql/partition_join.sql b/src/test/regress/sql/partition_join.sql index a2d8b1be55c..fb3ba18a26f 100644 --- a/src/test/regress/sql/partition_join.sql +++ b/src/test/regress/sql/partition_join.sql @@ -34,7 +34,7 @@ EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; --- left outer join, with whole-row reference +-- left outer join, with whole-row reference; partitionwise join does not apply EXPLAIN (COSTS OFF) SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; SELECT t1, t2 FROM prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; @@ -54,10 +54,12 @@ EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.a < 450 AND t2.b > 250 AND t1.b = 0 ORDER BY t1.a, t2.b; +-- Currently we can't do partitioned join if nullable-side partitions are pruned EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; +-- Currently we can't do partitioned join if nullable-side partitions are pruned EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1 WHERE a < 450) t1 FULL JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 OR t2.a = 0 ORDER BY t1.a, t2.b; @@ -156,10 +158,17 @@ SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 SELECT t1.a, t1.c, t2.b, t2.c, t3.a + t3.b, t3.c FROM (prt1 t1 LEFT JOIN prt2 t2 ON t1.a = t2.b) RIGHT JOIN prt1_e t3 ON (t1.a = (t3.a + t3.b)/2) WHERE t3.c = 0 ORDER BY t1.a, t2.b, t3.a + t3.b; -- MergeAppend on nullable column +-- This should generate a partitionwise join, but currently fails to EXPLAIN (COSTS OFF) SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; SELECT t1.a, t2.b FROM (SELECT * FROM prt1 WHERE a < 450) t1 LEFT JOIN (SELECT * FROM prt2 WHERE b > 250) t2 ON t1.a = t2.b WHERE t1.b = 0 ORDER BY t1.a, t2.b; +-- merge join when expression with whole-row reference needs to be sorted; +-- partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; +SELECT t1.a, t2.b FROM prt1 t1, prt2 t2 WHERE t1::text = t2::text AND t1.a = t2.b ORDER BY t1.a; + RESET enable_hashjoin; RESET enable_nestloop; @@ -261,6 +270,27 @@ EXPLAIN (COSTS OFF) SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; SELECT avg(t1.a), avg(t2.b), avg(t3.a + t3.b), t1.c, t2.c, t3.c FROM pht1 t1, pht2 t2, pht1_e t3 WHERE t1.b = t2.b AND t1.c = t2.c AND ltrim(t3.c, 'A') = t1.c GROUP BY t1.c, t2.c, t3.c ORDER BY t1.c, t2.c, t3.c; +-- test default partition behavior for range +ALTER TABLE prt1 DETACH PARTITION prt1_p3; +ALTER TABLE prt1 ATTACH PARTITION prt1_p3 DEFAULT; +ANALYZE prt1; +ALTER TABLE prt2 DETACH PARTITION prt2_p3; +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 DEFAULT; +ANALYZE prt2; + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; + +-- test default partition behavior for list +ALTER TABLE plt1 DETACH PARTITION plt1_p3; +ALTER TABLE plt1 ATTACH PARTITION plt1_p3 DEFAULT; +ANALYZE plt1; +ALTER TABLE plt2 DETACH PARTITION plt2_p3; +ALTER TABLE plt2 ATTACH PARTITION plt2_p3 DEFAULT; +ANALYZE plt2; + +EXPLAIN (COSTS OFF) +SELECT avg(t1.a), avg(t2.b), t1.c, t2.c FROM plt1 t1 RIGHT JOIN plt2 t2 ON t1.c = t2.c WHERE t1.a % 25 = 0 GROUP BY t1.c, t2.c ORDER BY t1.c, t2.c; -- -- multiple levels of partitioning -- @@ -319,6 +349,18 @@ SELECT * FROM prt1_l t1 LEFT JOIN LATERAL EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM (SELECT * FROM prt1_l WHERE a = 1 AND a = 2) t1 RIGHT JOIN prt2_l t2 ON t1.a = t2.b AND t1.b = t2.a AND t1.c = t2.c; +-- Test case to verify proper handling of subqueries in a partitioned delete. +-- The weird-looking lateral join is just there to force creation of a +-- nestloop parameter within the subquery, which exposes the problem if the +-- planner fails to make multiple copies of the subquery as appropriate. +EXPLAIN (COSTS OFF) +DELETE FROM prt1_l +WHERE EXISTS ( + SELECT 1 + FROM int4_tbl, + LATERAL (SELECT int4_tbl.f1 FROM int8_tbl LIMIT 2) ss + WHERE prt1_l.c IS NULL); + -- -- negative testcases -- @@ -381,6 +423,15 @@ EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 JOIN prt2_n t2 ON (t1.c = t2.c) JOIN plt1 t3 ON (t1.c = t3.c); -- partitionwise join can not be applied for a join between list and range --- partitioned table +-- partitioned tables EXPLAIN (COSTS OFF) SELECT t1.a, t1.c, t2.b, t2.c FROM prt1_n t1 FULL JOIN prt1 t2 ON (t1.c = t2.c); + +-- partitionwise join can not be applied if only one of joining tables has +-- default partition +ALTER TABLE prt2 DETACH PARTITION prt2_p3; +ALTER TABLE prt2 ATTACH PARTITION prt2_p3 FOR VALUES FROM (500) TO (600); +ANALYZE prt2; + +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.c, t2.b, t2.c FROM prt1 t1, prt2 t2 WHERE t1.a = t2.b AND t1.b = 0 ORDER BY t1.a, t2.b; diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index 7fe93bbc046..b66e599575e 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -1,6 +1,10 @@ -- -- Test partitioning planner code -- + +-- Force generic plans to be used for all prepared statements in this file. +set plan_cache_mode = force_generic_plan; + create table lp (a char) partition by list (a); create table lp_default partition of lp default; create table lp_ef partition of lp for values in ('e', 'f'); @@ -83,6 +87,11 @@ explain (costs off) select * from rlp where a = 1 or b = 'ab'; explain (costs off) select * from rlp where a > 20 and a < 27; explain (costs off) select * from rlp where a = 29; explain (costs off) select * from rlp where a >= 29; +explain (costs off) select * from rlp where a < 1 or (a > 20 and a < 25); + +-- where clause contradicts sub-partition's constraint +explain (costs off) select * from rlp where a = 20 or a = 40; +explain (costs off) select * from rlp3 where a = 20; /* empty */ -- redundant clauses are eliminated explain (costs off) select * from rlp where a > 1 and a = 10; /* only default */ @@ -137,6 +146,13 @@ explain (costs off) select * from mc2p where a = 2 and b < 1; explain (costs off) select * from mc2p where a > 1; explain (costs off) select * from mc2p where a = 1 and b > 1; +-- all partitions but the default one should be pruned +explain (costs off) select * from mc2p where a = 1 and b is null; +explain (costs off) select * from mc2p where a is null and b is null; +explain (costs off) select * from mc2p where a is null and b = 1; +explain (costs off) select * from mc2p where a is null; +explain (costs off) select * from mc2p where b is null; + -- boolean partitioning create table boolpart (a bool) partition by list (a); create table boolpart_default partition of boolpart default; @@ -152,6 +168,43 @@ explain (costs off) select * from boolpart where a is not true and a is not fals explain (costs off) select * from boolpart where a is unknown; explain (costs off) select * from boolpart where a is not unknown; +create table boolrangep (a bool, b bool, c int) partition by range (a,b,c); +create table boolrangep_tf partition of boolrangep for values from ('true', 'false', 0) to ('true', 'false', 100); +create table boolrangep_ft partition of boolrangep for values from ('false', 'true', 0) to ('false', 'true', 100); +create table boolrangep_ff1 partition of boolrangep for values from ('false', 'false', 0) to ('false', 'false', 50); +create table boolrangep_ff2 partition of boolrangep for values from ('false', 'false', 50) to ('false', 'false', 100); + +-- try a more complex case that's been known to trip up pruning in the past +explain (costs off) select * from boolrangep where not a and not b and c = 25; + +-- test scalar-to-array operators +create table coercepart (a varchar) partition by list (a); +create table coercepart_ab partition of coercepart for values in ('ab'); +create table coercepart_bc partition of coercepart for values in ('bc'); +create table coercepart_cd partition of coercepart for values in ('cd'); + +explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')); +explain (costs off) select * from coercepart where a ~ any ('{ab}'); +explain (costs off) select * from coercepart where a !~ all ('{ab}'); +explain (costs off) select * from coercepart where a ~ any ('{ab,bc}'); +explain (costs off) select * from coercepart where a !~ all ('{ab,bc}'); +explain (costs off) select * from coercepart where a = any ('{ab,bc}'); +explain (costs off) select * from coercepart where a = any ('{ab,null}'); +explain (costs off) select * from coercepart where a = any (null::text[]); +explain (costs off) select * from coercepart where a = all ('{ab}'); +explain (costs off) select * from coercepart where a = all ('{ab,bc}'); +explain (costs off) select * from coercepart where a = all ('{ab,null}'); +explain (costs off) select * from coercepart where a = all (null::text[]); + +drop table coercepart; + +CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a); +CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2); +CREATE TABLE part_p2 PARTITION OF part DEFAULT PARTITION BY RANGE(a); +CREATE TABLE part_p2_p1 PARTITION OF part_p2 DEFAULT; +INSERT INTO part VALUES (-1,-1), (1,1), (2,NULL), (NULL,-2),(NULL,NULL); +EXPLAIN (COSTS OFF) SELECT tableoid::regclass as part, a, b FROM part WHERE a IS NULL ORDER BY 1, 2, 3; + -- -- some more cases -- @@ -236,8 +289,50 @@ create table rparted_by_int2_maxvalue partition of rparted_by_int2 for values fr -- all partitions but rparted_by_int2_maxvalue pruned explain (costs off) select * from rparted_by_int2 where a > 100000000000000; -drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2; +drop table lp, coll_pruning, rlp, mc3p, mc2p, boolpart, boolrangep, rp, coll_pruning_multi, like_op_noprune, lparted_by_int2, rparted_by_int2; + +-- +-- Test Partition pruning for HASH partitioning +-- +-- Use hand-rolled hash functions and operator classes to get predictable +-- result on different matchines. See the definitions of +-- part_part_test_int4_ops and part_test_text_ops in insert.sql. +-- +create table hp (a int, b text) partition by hash (a part_test_int4_ops, b part_test_text_ops); +create table hp0 partition of hp for values with (modulus 4, remainder 0); +create table hp3 partition of hp for values with (modulus 4, remainder 3); +create table hp1 partition of hp for values with (modulus 4, remainder 1); +create table hp2 partition of hp for values with (modulus 4, remainder 2); + +insert into hp values (null, null); +insert into hp values (1, null); +insert into hp values (1, 'xxx'); +insert into hp values (null, 'xxx'); +insert into hp values (2, 'xxx'); +insert into hp values (1, 'abcde'); +select tableoid::regclass, * from hp order by 1; + +-- partial keys won't prune, nor would non-equality conditions +explain (costs off) select * from hp where a = 1; +explain (costs off) select * from hp where b = 'xxx'; +explain (costs off) select * from hp where a is null; +explain (costs off) select * from hp where b is null; +explain (costs off) select * from hp where a < 1 and b = 'xxx'; +explain (costs off) select * from hp where a <> 1 and b = 'yyy'; +explain (costs off) select * from hp where a <> 1 and b <> 'xxx'; + +-- pruning should work if either a value or a IS NULL clause is provided for +-- each of the keys +explain (costs off) select * from hp where a is null and b is null; +explain (costs off) select * from hp where a = 1 and b is null; +explain (costs off) select * from hp where a = 1 and b = 'xxx'; +explain (costs off) select * from hp where a is null and b = 'xxx'; +explain (costs off) select * from hp where a = 2 and b = 'xxx'; +explain (costs off) select * from hp where a = 1 and b = 'abcde'; +explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null); + +drop table hp; -- -- Test runtime partition pruning @@ -264,14 +359,6 @@ set enable_indexonlyscan = off; prepare ab_q1 (int, int, int) as select * from ab where a between $1 and $2 and b <= $3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q1 (1, 8, 3); -execute ab_q1 (1, 8, 3); -execute ab_q1 (1, 8, 3); -execute ab_q1 (1, 8, 3); -execute ab_q1 (1, 8, 3); - explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2, 3); explain (analyze, costs off, summary off, timing off) execute ab_q1 (1, 2, 3); @@ -281,43 +368,90 @@ deallocate ab_q1; prepare ab_q1 (int, int) as select a from ab where a between $1 and $2 and b < 3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q1 (1, 8); -execute ab_q1 (1, 8); -execute ab_q1 (1, 8); -execute ab_q1 (1, 8); -execute ab_q1 (1, 8); - explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 2); explain (analyze, costs off, summary off, timing off) execute ab_q1 (2, 4); --- Ensure a mix of external and exec params work together at different --- levels of partitioning. +-- Ensure a mix of PARAM_EXTERN and PARAM_EXEC Params work together at +-- different levels of partitioning. prepare ab_q2 (int, int) as select a from ab where a between $1 and $2 and b < (select 3); -execute ab_q2 (1, 8); -execute ab_q2 (1, 8); -execute ab_q2 (1, 8); -execute ab_q2 (1, 8); -execute ab_q2 (1, 8); - explain (analyze, costs off, summary off, timing off) execute ab_q2 (2, 2); --- As above, but with swap the exec param to the first partition level +-- As above, but swap the PARAM_EXEC Param to the first partition level prepare ab_q3 (int, int) as select a from ab where b between $1 and $2 and a < (select 3); -execute ab_q3 (1, 8); -execute ab_q3 (1, 8); -execute ab_q3 (1, 8); -execute ab_q3 (1, 8); -execute ab_q3 (1, 8); - explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2); +-- Test a backwards Append scan +create table list_part (a int) partition by list (a); +create table list_part1 partition of list_part for values in (1); +create table list_part2 partition of list_part for values in (2); +create table list_part3 partition of list_part for values in (3); +create table list_part4 partition of list_part for values in (4); + +insert into list_part select generate_series(1,4); + +begin; + +-- Don't select an actual value out of the table as the order of the Append's +-- subnodes may not be stable. +declare cur SCROLL CURSOR for select 1 from list_part where a > (select 1) and a < (select 4); + +-- move beyond the final row +move 3 from cur; + +-- Ensure we get two rows. +fetch backward all from cur; + +commit; + +begin; + +-- Test run-time pruning using stable functions +create function list_part_fn(int) returns int as $$ begin return $1; end;$$ language plpgsql stable; + +-- Ensure pruning works using a stable function containing no Vars +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1); + +-- Ensure pruning does not take place when the function has a Var parameter +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(a); + +-- Ensure pruning does not take place when the expression contains a Var. +explain (analyze, costs off, summary off, timing off) select * from list_part where a = list_part_fn(1) + a; + +rollback; + +drop table list_part; + -- Parallel append + +-- Parallel queries won't necessarily get as many workers as the planner +-- asked for. This affects not only the "Workers Launched:" field of EXPLAIN +-- results, but also row counts and loop counts for parallel scans, Gathers, +-- and everything in between. This function filters out the values we can't +-- rely on to be stable. +-- This removes enough info that you might wonder why bother with EXPLAIN +-- ANALYZE at all. The answer is that we need to see '(never executed)' +-- notations because that's the only way to verify runtime pruning. +create function explain_parallel_append(text) returns setof text +language plpgsql as +$$ +declare + ln text; +begin + for ln in + execute format('explain (analyze, costs off, summary off, timing off) %s', + $1) + loop + ln := regexp_replace(ln, 'Workers Launched: \d+', 'Workers Launched: N'); + ln := regexp_replace(ln, 'actual rows=\d+ loops=\d+', 'actual rows=N loops=N'); + return next ln; + end loop; +end; +$$; + prepare ab_q4 (int, int) as select avg(a) from ab where a between $1 and $2 and b < 4; @@ -327,36 +461,23 @@ set parallel_tuple_cost = 0; set min_parallel_table_scan_size = 0; set max_parallel_workers_per_gather = 2; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q4 (1, 8); -execute ab_q4 (1, 8); -execute ab_q4 (1, 8); -execute ab_q4 (1, 8); -execute ab_q4 (1, 8); - -explain (analyze, costs off, summary off, timing off) execute ab_q4 (2, 2); +select explain_parallel_append('execute ab_q4 (2, 2)'); -- Test run-time pruning with IN lists. prepare ab_q5 (int, int, int) as select avg(a) from ab where a in($1,$2,$3) and b < 4; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute ab_q5 (1, 2, 3); -execute ab_q5 (1, 2, 3); -execute ab_q5 (1, 2, 3); -execute ab_q5 (1, 2, 3); -execute ab_q5 (1, 2, 3); - -explain (analyze, costs off, summary off, timing off) execute ab_q5 (1, 1, 1); -explain (analyze, costs off, summary off, timing off) execute ab_q5 (2, 3, 3); +select explain_parallel_append('execute ab_q5 (1, 1, 1)'); +select explain_parallel_append('execute ab_q5 (2, 3, 3)'); -- Try some params whose values do not belong to any partition. -- We'll still get a single subplan in this case, but it should not be scanned. -explain (analyze, costs off, summary off, timing off) execute ab_q5 (33, 44, 55); +select explain_parallel_append('execute ab_q5 (33, 44, 55)'); --- Test parallel Append with IN list and parameterized nested loops +-- Test Parallel Append with PARAM_EXEC Params +select explain_parallel_append('select count(*) from ab where (a = (select 1) or a = (select 3)) and b = 2'); + +-- Test pruning during parallel nested loop query create table lprt_a (a int not null); -- Insert some values we won't find in ab insert into lprt_a select 0 from generate_series(1,100); @@ -379,24 +500,20 @@ create index ab_a3_b3_a_idx on ab_a3_b3 (a); set enable_hashjoin = 0; set enable_mergejoin = 0; -prepare ab_q6 (int, int, int) as -select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in($1,$2,$3); -execute ab_q6 (1, 2, 3); -execute ab_q6 (1, 2, 3); -execute ab_q6 (1, 2, 3); -execute ab_q6 (1, 2, 3); -execute ab_q6 (1, 2, 3); +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(0, 0, 1)'); -explain (analyze, costs off, summary off, timing off) execute ab_q6 (0, 0, 1); +-- Ensure the same partitions are pruned when we make the nested loop +-- parameter an Expr rather than a plain Param. +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a + 0 where a.a in(0, 0, 1)'); insert into lprt_a values(3),(3); -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 3); -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 0); +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 3)'); +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); delete from lprt_a where a = 1; -explain (analyze, costs off, summary off, timing off) execute ab_q6 (1, 0, 0); +select explain_parallel_append('select avg(ab.a) from ab inner join lprt_a a on ab.a = a.a where a.a in(1, 0, 0)'); reset enable_hashjoin; reset enable_mergejoin; @@ -409,6 +526,39 @@ reset max_parallel_workers_per_gather; explain (analyze, costs off, summary off, timing off) select * from ab where a = (select max(a) from lprt_a) and b = (select max(a)-1 from lprt_a); +-- Test run-time partition pruning with UNION ALL parents +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all select * from ab) ab where b = (select 1); + +-- A case containing a UNION ALL with a non-partitioned child. +explain (analyze, costs off, summary off, timing off) +select * from (select * from ab where a = 1 union all (values(10,5)) union all select * from ab) ab where b = (select 1); + +-- Another UNION ALL test, but containing a mix of exec init and exec run-time pruning. +create table xy_1 (x int, y int); +insert into xy_1 values(100,-10); + +set enable_bitmapscan = 0; +set enable_indexscan = 0; + +prepare ab_q6 as +select * from ( + select tableoid::regclass,a,b from ab +union all + select tableoid::regclass,x,y from xy_1 +union all + select tableoid::regclass,a,b from ab +) ab where a = $1 and b = (select -10); + +-- Ensure the xy_1 subplan is not pruned. +explain (analyze, costs off, summary off, timing off) execute ab_q6(1); + +-- Ensure we see just the xy_1 row. +execute ab_q6(100); + +reset enable_bitmapscan; +reset enable_indexscan; + deallocate ab_q1; deallocate ab_q2; deallocate ab_q3; @@ -416,6 +566,19 @@ deallocate ab_q4; deallocate ab_q5; deallocate ab_q6; +-- UPDATE on a partition subtree has been seen to have problems. +insert into ab values (1,2); +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab where ab.a = 1 and ab.a = ab_a1.a; +table ab; + +-- Test UPDATE where source relation has run-time pruning enabled +truncate ab; +insert into ab values (1, 1), (1, 2), (1, 3), (2, 1); +explain (analyze, costs off, summary off, timing off) +update ab_a1 set b = 3 from ab_a2 where ab_a2.b = (select 1); +select tableoid::regclass, * from ab; + drop table ab, lprt_a; -- Join @@ -508,14 +671,6 @@ alter table part_cab attach partition part_abc_p1 for values in(3); prepare part_abc_q1 (int, int, int) as select * from part_abc where a = $1 and b = $2 and c = $3; --- Execute query 5 times to allow choose_custom_plan --- to start considering a generic plan. -execute part_abc_q1 (1, 2, 3); -execute part_abc_q1 (1, 2, 3); -execute part_abc_q1 (1, 2, 3); -execute part_abc_q1 (1, 2, 3); -execute part_abc_q1 (1, 2, 3); - -- Single partition should be scanned. explain (analyze, costs off, summary off, timing off) execute part_abc_q1 (1, 2, 3); @@ -537,12 +692,6 @@ select * from listp where b = 1; -- which match the given parameter. prepare q1 (int,int) as select * from listp where b in ($1,$2); -execute q1 (1,2); -execute q1 (1,2); -execute q1 (1,2); -execute q1 (1,2); -execute q1 (1,2); - explain (analyze, costs off, summary off, timing off) execute q1 (1,1); explain (analyze, costs off, summary off, timing off) execute q1 (2,2); @@ -556,12 +705,6 @@ deallocate q1; -- Test more complex cases where a not-equal condition further eliminates partitions. prepare q1 (int,int,int,int) as select * from listp where b in($1,$2) and $3 <> b and $4 <> b; -execute q1 (1,2,3,4); -execute q1 (1,2,3,4); -execute q1 (1,2,3,4); -execute q1 (1,2,3,4); -execute q1 (1,2,3,4); - -- Both partitions allowed by IN clause, but one disallowed by <> clause explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0); @@ -569,8 +712,88 @@ explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,0); -- One subplan will remain in this case, but it should not be executed. explain (analyze, costs off, summary off, timing off) execute q1 (1,2,2,1); +-- Ensure Params that evaluate to NULL properly prune away all partitions +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select null::int); + drop table listp; +-- +-- check that stable query clauses are only used in run-time pruning +-- +create table stable_qual_pruning (a timestamp) partition by range (a); +create table stable_qual_pruning1 partition of stable_qual_pruning + for values from ('2000-01-01') to ('2000-02-01'); +create table stable_qual_pruning2 partition of stable_qual_pruning + for values from ('2000-02-01') to ('2000-03-01'); +create table stable_qual_pruning3 partition of stable_qual_pruning + for values from ('3000-02-01') to ('3000-03-01'); + +-- comparison against a stable value requires run-time pruning +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < localtimestamp; + +-- timestamp < timestamptz comparison is only stable, not immutable +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning where a < '2000-02-01'::timestamptz; + +-- check ScalarArrayOp cases +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamp[]); +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamp[]); +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', localtimestamp]::timestamp[]); +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2010-02-01', '2020-01-01']::timestamptz[]); +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]); +explain (analyze, costs off, summary off, timing off) +select * from stable_qual_pruning + where a = any(null::timestamptz[]); + +drop table stable_qual_pruning; + +-- +-- Check that pruning with composite range partitioning works correctly when +-- it must ignore clauses for trailing keys once it has seen a clause with +-- non-inclusive operator for an earlier key +-- +create table mc3p (a int, b int, c int) partition by range (a, abs(b), c); +create table mc3p0 partition of mc3p + for values from (0, 0, 0) to (0, maxvalue, maxvalue); +create table mc3p1 partition of mc3p + for values from (1, 1, 1) to (2, minvalue, minvalue); +create table mc3p2 partition of mc3p + for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue); +insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1); + +explain (analyze, costs off, summary off, timing off) +select * from mc3p where a < 3 and abs(b) = 1; + +-- +-- Check that pruning with composite range partitioning works correctly when +-- a combination of runtime parameters is specified, not all of whose values +-- are available at the same time +-- +prepare ps1 as + select * from mc3p where a = $1 and abs(b) < (select 3); +explain (analyze, costs off, summary off, timing off) +execute ps1(1); +deallocate ps1; +prepare ps2 as + select * from mc3p where a <= $1 and abs(b) < (select 3); +explain (analyze, costs off, summary off, timing off) +execute ps2(1); +deallocate ps2; + +drop table mc3p; + -- Ensure runtime pruning works with initplans params with boolean types create table boolvalues (value bool not null); insert into boolvalues values('t'),('f'); @@ -587,4 +810,233 @@ select * from boolp where a = (select value from boolvalues where not value); drop table boolp; -reset enable_indexonlyscan; \ No newline at end of file +-- +-- Test run-time pruning of MergeAppend subnodes +-- +set enable_seqscan = off; +set enable_sort = off; +create table ma_test (a int, b int) partition by range (a); +create table ma_test_p1 partition of ma_test for values from (0) to (10); +create table ma_test_p2 partition of ma_test for values from (10) to (20); +create table ma_test_p3 partition of ma_test for values from (20) to (30); +insert into ma_test select x,x from generate_series(0,29) t(x); +create index on ma_test (b); + +analyze ma_test; +prepare mt_q1 (int) as select a from ma_test where a >= $1 and a % 10 = 5 order by b; + +explain (analyze, costs off, summary off, timing off) execute mt_q1(15); +execute mt_q1(15); +explain (analyze, costs off, summary off, timing off) execute mt_q1(25); +execute mt_q1(25); +-- Ensure MergeAppend behaves correctly when no subplans match +explain (analyze, costs off, summary off, timing off) execute mt_q1(35); +execute mt_q1(35); + +deallocate mt_q1; + +-- ensure initplan params properly prune partitions +explain (analyze, costs off, summary off, timing off) select * from ma_test where a >= (select min(b) from ma_test_p2) order by b; + +reset enable_seqscan; +reset enable_sort; + +drop table ma_test; + +reset enable_indexonlyscan; + +-- +-- check that pruning works properly when the partition key is of a +-- pseudotype +-- + +-- array type list partition key +create table pp_arrpart (a int[]) partition by list (a); +create table pp_arrpart1 partition of pp_arrpart for values in ('{1}'); +create table pp_arrpart2 partition of pp_arrpart for values in ('{2, 3}', '{4, 5}'); +explain (costs off) select * from pp_arrpart where a = '{1}'; +explain (costs off) select * from pp_arrpart where a = '{1, 2}'; +explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}'); +explain (costs off) update pp_arrpart set a = a where a = '{1}'; +explain (costs off) delete from pp_arrpart where a = '{1}'; +drop table pp_arrpart; + +-- array type hash partition key +create table pph_arrpart (a int[]) partition by hash (a); +create table pph_arrpart1 partition of pph_arrpart for values with (modulus 2, remainder 0); +create table pph_arrpart2 partition of pph_arrpart for values with (modulus 2, remainder 1); +insert into pph_arrpart values ('{1}'), ('{1, 2}'), ('{4, 5}'); +select tableoid::regclass, * from pph_arrpart order by 1; +explain (costs off) select * from pph_arrpart where a = '{1}'; +explain (costs off) select * from pph_arrpart where a = '{1, 2}'; +explain (costs off) select * from pph_arrpart where a in ('{4, 5}', '{1}'); +drop table pph_arrpart; + +-- enum type list partition key +create type pp_colors as enum ('green', 'blue', 'black'); +create table pp_enumpart (a pp_colors) partition by list (a); +create table pp_enumpart_green partition of pp_enumpart for values in ('green'); +create table pp_enumpart_blue partition of pp_enumpart for values in ('blue'); +explain (costs off) select * from pp_enumpart where a = 'blue'; +explain (costs off) select * from pp_enumpart where a = 'black'; +drop table pp_enumpart; +drop type pp_colors; + +-- record type as partition key +create type pp_rectype as (a int, b int); +create table pp_recpart (a pp_rectype) partition by list (a); +create table pp_recpart_11 partition of pp_recpart for values in ('(1,1)'); +create table pp_recpart_23 partition of pp_recpart for values in ('(2,3)'); +explain (costs off) select * from pp_recpart where a = '(1,1)'::pp_rectype; +explain (costs off) select * from pp_recpart where a = '(1,2)'::pp_rectype; +drop table pp_recpart; +drop type pp_rectype; + +-- range type partition key +create table pp_intrangepart (a int4range) partition by list (a); +create table pp_intrangepart12 partition of pp_intrangepart for values in ('[1,2]'); +create table pp_intrangepart2inf partition of pp_intrangepart for values in ('[2,)'); +explain (costs off) select * from pp_intrangepart where a = '[1,2]'::int4range; +explain (costs off) select * from pp_intrangepart where a = '(1,2)'::int4range; +drop table pp_intrangepart; + +-- +-- Ensure the enable_partition_prune GUC properly disables partition pruning. +-- + +create table pp_lp (a int, value int) partition by list (a); +create table pp_lp1 partition of pp_lp for values in(1); +create table pp_lp2 partition of pp_lp for values in(2); + +explain (costs off) select * from pp_lp where a = 1; +explain (costs off) update pp_lp set value = 10 where a = 1; +explain (costs off) delete from pp_lp where a = 1; + +set enable_partition_pruning = off; + +set constraint_exclusion = 'partition'; -- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1; +explain (costs off) update pp_lp set value = 10 where a = 1; +explain (costs off) delete from pp_lp where a = 1; + +set constraint_exclusion = 'off'; -- this should not affect the result. + +explain (costs off) select * from pp_lp where a = 1; +explain (costs off) update pp_lp set value = 10 where a = 1; +explain (costs off) delete from pp_lp where a = 1; + +drop table pp_lp; + +-- Ensure enable_partition_prune does not affect non-partitioned tables. + +create table inh_lp (a int, value int); +create table inh_lp1 (a int, value int, check(a = 1)) inherits (inh_lp); +create table inh_lp2 (a int, value int, check(a = 2)) inherits (inh_lp); + +set constraint_exclusion = 'partition'; + +-- inh_lp2 should be removed in the following 3 cases. +explain (costs off) select * from inh_lp where a = 1; +explain (costs off) update inh_lp set value = 10 where a = 1; +explain (costs off) delete from inh_lp where a = 1; + +-- Ensure we don't exclude normal relations when we only expect to exclude +-- inheritance children +explain (costs off) update inh_lp1 set value = 10 where a = 2; + +drop table inh_lp cascade; + +reset enable_partition_pruning; +reset constraint_exclusion; + +-- Check pruning for a partition tree containing only temporary relations +create temp table pp_temp_parent (a int) partition by list (a); +create temp table pp_temp_part_1 partition of pp_temp_parent for values in (1); +create temp table pp_temp_part_def partition of pp_temp_parent default; +explain (costs off) select * from pp_temp_parent where true; +explain (costs off) select * from pp_temp_parent where a = 2; +drop table pp_temp_parent; + +-- Stress run-time partition pruning a bit more, per bug reports +create temp table p (a int, b int, c int) partition by list (a); +create temp table p1 partition of p for values in (1); +create temp table p2 partition of p for values in (2); +create temp table q (a int, b int, c int) partition by list (a); +create temp table q1 partition of q for values in (1) partition by list (b); +create temp table q11 partition of q1 for values in (1) partition by list (c); +create temp table q111 partition of q11 for values in (1); +create temp table q2 partition of q for values in (2) partition by list (b); +create temp table q21 partition of q2 for values in (1); +create temp table q22 partition of q2 for values in (2); + +insert into q22 values (2, 2, 3); + +explain (costs off) +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = 1 and s.b = 1 and s.c = (select 1); + +prepare q (int, int) as +select * +from ( + select * from p + union all + select * from q1 + union all + select 1, 1, 1 + ) s(a, b, c) +where s.a = $1 and s.b = $2 and s.c = (select 1); + +explain (costs off) execute q (1, 1); +execute q (1, 1); + +drop table p, q; + +-- Ensure run-time pruning works correctly when we match a partitioned table +-- on the first level but find no matching partitions on the second level. +create table listp (a int, b int) partition by list (a); +create table listp1 partition of listp for values in(1); +create table listp2 partition of listp for values in(2) partition by list(b); +create table listp2_10 partition of listp2 for values in (10); + +explain (analyze, costs off, summary off, timing off) +select * from listp where a = (select 2) and b <> 10; + +-- +-- check that a partition directly accessed in a query is excluded with +-- constraint_exclusion = on +-- + +-- turn off partition pruning, so that it doesn't interfere +set enable_partition_pruning to off; + +-- setting constraint_exclusion to 'partition' disables exclusion +set constraint_exclusion to 'partition'; +explain (costs off) select * from listp1 where a = 2; +explain (costs off) update listp1 set a = 1 where a = 2; +-- constraint exclusion enabled +set constraint_exclusion to 'on'; +explain (costs off) select * from listp1 where a = 2; +explain (costs off) update listp1 set a = 1 where a = 2; + +reset constraint_exclusion; +reset enable_partition_pruning; + +drop table listp; diff --git a/src/test/regress/sql/partition_prune_hash.sql b/src/test/regress/sql/partition_prune_hash.sql deleted file mode 100644 index fd1783bf53c..00000000000 --- a/src/test/regress/sql/partition_prune_hash.sql +++ /dev/null @@ -1,41 +0,0 @@ --- --- Test Partition pruning for HASH partitioning --- We keep this as a seperate test as hash functions return --- values will vary based on CPU architecture. --- - -create table hp (a int, b text) partition by hash (a, b); -create table hp0 partition of hp for values with (modulus 4, remainder 0); -create table hp3 partition of hp for values with (modulus 4, remainder 3); -create table hp1 partition of hp for values with (modulus 4, remainder 1); -create table hp2 partition of hp for values with (modulus 4, remainder 2); - -insert into hp values (null, null); -insert into hp values (1, null); -insert into hp values (1, 'xxx'); -insert into hp values (null, 'xxx'); -insert into hp values (10, 'xxx'); -insert into hp values (10, 'yyy'); -select tableoid::regclass, * from hp order by 1; - --- partial keys won't prune, nor would non-equality conditions -explain (costs off) select * from hp where a = 1; -explain (costs off) select * from hp where b = 'xxx'; -explain (costs off) select * from hp where a is null; -explain (costs off) select * from hp where b is null; -explain (costs off) select * from hp where a < 1 and b = 'xxx'; -explain (costs off) select * from hp where a <> 1 and b = 'yyy'; - --- pruning should work if non-null values are provided for all the keys -explain (costs off) select * from hp where a is null and b is null; -explain (costs off) select * from hp where a = 1 and b is null; -explain (costs off) select * from hp where a = 1 and b = 'xxx'; -explain (costs off) select * from hp where a is null and b = 'xxx'; -explain (costs off) select * from hp where a = 10 and b = 'xxx'; -explain (costs off) select * from hp where a = 10 and b = 'yyy'; -explain (costs off) select * from hp where (a = 10 and b = 'yyy') or (a = 10 and b = 'xxx') or (a is null and b is null); - --- hash partitiong pruning doesn't occur with <> operator clauses -explain (costs off) select * from hp where a <> 1 and b <> 'xxx'; - -drop table hp; diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sql index 8f8252d127f..fad88ba6895 100644 --- a/src/test/regress/sql/password.sql +++ b/src/test/regress/sql/password.sql @@ -54,6 +54,16 @@ ALTER ROLE regress_passwd4 PASSWORD 'foo'; -- already encrypted with MD5, use as it is CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023'; +-- This looks like a valid SCRAM-SHA-256 verifier, but it is not +-- so it should be hashed with SCRAM-SHA-256. +CREATE ROLE regress_passwd6 PASSWORD 'SCRAM-SHA-256$1234'; +-- These may look like valid MD5 verifiers, but they are not, so they +-- should be hashed with SCRAM-SHA-256. +-- trailing garbage at the end +CREATE ROLE regress_passwd7 PASSWORD 'md5012345678901234567890123456789zz'; +-- invalid length +CREATE ROLE regress_passwd8 PASSWORD 'md501234567890123456789012345678901zz'; + SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:$:') as rolpassword_masked FROM pg_authid WHERE rolname LIKE 'regress_passwd%' @@ -65,12 +75,33 @@ ALTER ROLE regress_passwd_empty PASSWORD 'md585939a5ce845f1a1b620742e3c659e0a'; ALTER ROLE regress_passwd_empty PASSWORD 'SCRAM-SHA-256$4096:hpFyHTUsSWcR7O9P$LgZFIt6Oqdo27ZFKbZ2nV+vtnYM995pDh9ca6WSi120=:qVV5NeluNfUPkwm7Vqat25RjSPLkGeoZBQs6wVv+um4='; SELECT rolpassword FROM pg_authid WHERE rolname='regress_passwd_empty'; +-- Test with invalid stored and server keys. +-- +-- The first is valid, to act as a control. The others have too long +-- stored/server keys. They will be re-hashed. +CREATE ROLE regress_passwd_sha_len0 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; +CREATE ROLE regress_passwd_sha_len1 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96RqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZI='; +CREATE ROLE regress_passwd_sha_len2 PASSWORD 'SCRAM-SHA-256$4096:A6xHKoH/494E941doaPOYg==$Ky+A30sewHIH3VHQLRN9vYsuzlgNyGNKCh37dy96Rqw=:COPdlNiIkrsacU5QoxydEuOH6e/KfiipeETb/bPw8ZIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='; + +-- Check that the invalid verifiers were re-hashed. A re-hashed verifier +-- should not contain the original salt. +SELECT rolname, rolpassword not like '%A6xHKoH/494E941doaPOYg==%' as is_rolpassword_rehashed + FROM pg_authid + WHERE rolname LIKE 'regress_passwd_sha_len%' + ORDER BY rolname; + DROP ROLE regress_passwd1; DROP ROLE regress_passwd2; DROP ROLE regress_passwd3; DROP ROLE regress_passwd4; DROP ROLE regress_passwd5; +DROP ROLE regress_passwd6; +DROP ROLE regress_passwd7; +DROP ROLE regress_passwd8; DROP ROLE regress_passwd_empty; +DROP ROLE regress_passwd_sha_len0; +DROP ROLE regress_passwd_sha_len1; +DROP ROLE regress_passwd_sha_len2; -- all entries should have been removed SELECT rolname, rolpassword diff --git a/src/test/regress/sql/path.sql b/src/test/regress/sql/path.sql index 7e69b539ad8..318decf9742 100644 --- a/src/test/regress/sql/path.sql +++ b/src/test/regress/sql/path.sql @@ -8,26 +8,32 @@ CREATE TABLE PATH_TBL (f1 path); INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)]'); -INSERT INTO PATH_TBL VALUES ('((1,2),(3,4))'); +INSERT INTO PATH_TBL VALUES (' ( ( 1 , 2 ) , ( 3 , 4 ) ) '); -INSERT INTO PATH_TBL VALUES ('[(0,0),(3,0),(4,5),(1,6)]'); +INSERT INTO PATH_TBL VALUES ('[ (0,0),(3,0),(4,5),(1,6) ]'); -INSERT INTO PATH_TBL VALUES ('((1,2),(3,4))'); +INSERT INTO PATH_TBL VALUES ('((1,2) ,(3,4 ))'); -INSERT INTO PATH_TBL VALUES ('1,2 ,3,4'); +INSERT INTO PATH_TBL VALUES ('1,2 ,3,4 '); -INSERT INTO PATH_TBL VALUES ('[1,2,3, 4]'); +INSERT INTO PATH_TBL VALUES (' [1,2,3, 4] '); -INSERT INTO PATH_TBL VALUES ('[11,12,13,14]'); +INSERT INTO PATH_TBL VALUES ('((10,20))'); -- Only one point -INSERT INTO PATH_TBL VALUES ('(11,12,13,14)'); +INSERT INTO PATH_TBL VALUES ('[ 11,12,13,14 ]'); + +INSERT INTO PATH_TBL VALUES ('( 11,12,13,14) '); -- bad values for parser testing +INSERT INTO PATH_TBL VALUES ('[]'); + INSERT INTO PATH_TBL VALUES ('[(,2),(3,4)]'); INSERT INTO PATH_TBL VALUES ('[(1,2),(3,4)'); -SELECT f1 FROM PATH_TBL; +INSERT INTO PATH_TBL VALUES ('(1,2,3,4'); + +INSERT INTO PATH_TBL VALUES ('(1,2),(3,4)]'); SELECT '' AS count, f1 AS open_path FROM PATH_TBL WHERE isopen(f1); diff --git a/src/test/regress/sql/pg_lsn.sql b/src/test/regress/sql/pg_lsn.sql index 746f720d690..2c143c82ffe 100644 --- a/src/test/regress/sql/pg_lsn.sql +++ b/src/test/regress/sql/pg_lsn.sql @@ -14,6 +14,10 @@ INSERT INTO PG_LSN_TBL VALUES ('-1/0'); INSERT INTO PG_LSN_TBL VALUES (' 0/12345678'); INSERT INTO PG_LSN_TBL VALUES ('ABCD/'); INSERT INTO PG_LSN_TBL VALUES ('/ABCD'); + +-- Min/Max aggregation +SELECT MIN(f1), MAX(f1) FROM PG_LSN_TBL; + DROP TABLE PG_LSN_TBL; -- Operators diff --git a/src/test/regress/sql/plancache.sql b/src/test/regress/sql/plancache.sql index d9439b83ab5..fa218c8d217 100644 --- a/src/test/regress/sql/plancache.sql +++ b/src/test/regress/sql/plancache.sql @@ -177,3 +177,36 @@ drop table pc_list_part_1; execute pstmt_def_insert(1); drop table pc_list_parted, pc_list_part_null; deallocate pstmt_def_insert; + +-- Test plan_cache_mode + +create table test_mode (a int); +insert into test_mode select 1 from generate_series(1,1000) union all select 2; +create index on test_mode (a); +analyze test_mode; + +prepare test_mode_pp (int) as select count(*) from test_mode where a = $1; + +-- up to 5 executions, custom plan is used +explain (costs off) execute test_mode_pp(2); + +-- force generic plan +set plan_cache_mode to force_generic_plan; +explain (costs off) execute test_mode_pp(2); + +-- get to generic plan by 5 executions +set plan_cache_mode to auto; +execute test_mode_pp(1); -- 1x +execute test_mode_pp(1); -- 2x +execute test_mode_pp(1); -- 3x +execute test_mode_pp(1); -- 4x +execute test_mode_pp(1); -- 5x + +-- we should now get a really bad plan +explain (costs off) execute test_mode_pp(2); + +-- but we can force a custom plan +set plan_cache_mode to force_custom_plan; +explain (costs off) execute test_mode_pp(2); + +drop table test_mode; diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index e71d072aa98..70deadfbea2 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -1684,179 +1684,6 @@ SELECT * FROM perform_test; drop table perform_test; --- --- Test error trapping --- - -create function trap_zero_divide(int) returns int as $$ -declare x int; - sx smallint; -begin - begin -- start a subtransaction - raise notice 'should see this'; - x := 100 / $1; - raise notice 'should see this only if % <> 0', $1; - sx := $1; - raise notice 'should see this only if % fits in smallint', $1; - if $1 < 0 then - raise exception '% is less than zero', $1; - end if; - exception - when division_by_zero then - raise notice 'caught division_by_zero'; - x := -1; - when NUMERIC_VALUE_OUT_OF_RANGE then - raise notice 'caught numeric_value_out_of_range'; - x := -2; - end; - return x; -end$$ language plpgsql; - -select trap_zero_divide(50); -select trap_zero_divide(0); -select trap_zero_divide(100000); -select trap_zero_divide(-100); - -create function trap_matching_test(int) returns int as $$ -declare x int; - sx smallint; - y int; -begin - begin -- start a subtransaction - x := 100 / $1; - sx := $1; - select into y unique1 from tenk1 where unique2 = - (select unique2 from tenk1 b where ten = $1); - exception - when data_exception then -- category match - raise notice 'caught data_exception'; - x := -1; - when NUMERIC_VALUE_OUT_OF_RANGE OR CARDINALITY_VIOLATION then - raise notice 'caught numeric_value_out_of_range or cardinality_violation'; - x := -2; - end; - return x; -end$$ language plpgsql; - -select trap_matching_test(50); -select trap_matching_test(0); -select trap_matching_test(100000); -select trap_matching_test(1); - -create temp table foo (f1 int); - -create function subxact_rollback_semantics() returns int as $$ -declare x int; -begin - x := 1; - insert into foo values(x); - begin - x := x + 1; - insert into foo values(x); - raise exception 'inner'; - exception - when others then - x := x * 10; - end; - insert into foo values(x); - return x; -end$$ language plpgsql; - -select subxact_rollback_semantics(); -select * from foo; -drop table foo; - -create function trap_timeout() returns void as $$ -begin - declare x int; - begin - -- we assume this will take longer than 2 seconds: - select count(*) into x from tenk1 a, tenk1 b, tenk1 c; - exception - when others then - raise notice 'caught others?'; - when query_canceled then - raise notice 'nyeah nyeah, can''t stop me'; - end; - -- Abort transaction to abandon the statement_timeout setting. Otherwise, - -- the next top-level statement would be vulnerable to the timeout. - raise exception 'end of function'; -end$$ language plpgsql; - -begin; -set statement_timeout to 2000; -select trap_timeout(); -rollback; - --- Test for pass-by-ref values being stored in proper context -create function test_variable_storage() returns text as $$ -declare x text; -begin - x := '1234'; - begin - x := x || '5678'; - -- force error inside subtransaction SPI context - perform trap_zero_divide(-100); - exception - when others then - x := x || '9012'; - end; - return x; -end$$ language plpgsql; - -select test_variable_storage(); - --- --- test foreign key error trapping --- - -create temp table master(f1 int primary key); - -create temp table slave(f1 int references master deferrable); - -insert into master values(1); -insert into slave values(1); -insert into slave values(2); -- fails - -create function trap_foreign_key(int) returns int as $$ -begin - begin -- start a subtransaction - insert into slave values($1); - exception - when foreign_key_violation then - raise notice 'caught foreign_key_violation'; - return 0; - end; - return 1; -end$$ language plpgsql; - -create function trap_foreign_key_2() returns int as $$ -begin - begin -- start a subtransaction - set constraints all immediate; - exception - when foreign_key_violation then - raise notice 'caught foreign_key_violation'; - return 0; - end; - return 1; -end$$ language plpgsql; - -select trap_foreign_key(1); -select trap_foreign_key(2); -- detects FK violation - -begin; - set constraints all deferred; - select trap_foreign_key(2); -- should not detect FK violation - savepoint x; - set constraints all immediate; -- fails - rollback to x; - select trap_foreign_key_2(); -- detects FK violation -commit; -- still fails - -drop function trap_foreign_key(int); -drop function trap_foreign_key_2(); - -- -- Test proper snapshot handling in simple expressions -- @@ -2627,6 +2454,95 @@ declare f1 int; begin return 1; end $$ language plpgsql; select shadowtest(1); +-- runtime extra checks +set plpgsql.extra_warnings to 'too_many_rows'; + +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; + +set plpgsql.extra_errors to 'too_many_rows'; + +do $$ +declare x int; +begin + select v from generate_series(1,2) g(v) into x; +end; +$$; + +reset plpgsql.extra_errors; +reset plpgsql.extra_warnings; + +set plpgsql.extra_warnings to 'strict_multi_assignment'; + +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; + +set plpgsql.extra_errors to 'strict_multi_assignment'; + +do $$ +declare + x int; + y int; +begin + select 1 into x, y; + select 1,2 into x, y; + select 1,2,3 into x, y; +end +$$; + +create table test_01(a int, b int, c int); + +alter table test_01 drop column a; + +-- the check is active only when source table is not empty +insert into test_01 values(10,20); + +do $$ +declare + x int; + y int; +begin + select * from test_01 into x, y; -- should be ok + raise notice 'ok'; + select * from test_01 into x; -- should to fail +end; +$$; + +do $$ +declare + t test_01; +begin + select 1, 2 into t; -- should be ok + raise notice 'ok'; + select 1, 2, 3 into t; -- should fail; +end; +$$; + +do $$ +declare + t test_01; +begin + select 1 into t; -- should fail; +end; +$$; + +drop table test_01; + +reset plpgsql.extra_errors; +reset plpgsql.extra_warnings; + -- test scrollable cursor support create function sc_test() returns setof integer as $$ @@ -3803,6 +3719,20 @@ $$ language plpgsql; select unreserved_test(); +create or replace function unreserved_test() returns int as $$ +declare + comment int := 21; +begin + comment := comment * 2; + comment on function unreserved_test() is 'this is a test'; + return comment; +end +$$ language plpgsql; + +select unreserved_test(); + +select obj_description('unreserved_test()'::regprocedure, 'pg_proc'); + drop function unreserved_test(); -- diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql index 63a803a809d..7f8504dbd1f 100644 --- a/src/test/regress/sql/point.sql +++ b/src/test/regress/sql/point.sql @@ -2,6 +2,9 @@ -- POINT -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; + CREATE TABLE POINT_TBL(f1 point); INSERT INTO POINT_TBL(f1) VALUES ('(0.0,0.0)'); @@ -14,6 +17,12 @@ INSERT INTO POINT_TBL(f1) VALUES ('(5.1, 34.5)'); INSERT INTO POINT_TBL(f1) VALUES ('(-5.0,-12.0)'); +INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)'); -- To underflow + +INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)'); -- To overflow + +INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) '); + -- bad format points INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf'); @@ -21,8 +30,12 @@ INSERT INTO POINT_TBL(f1) VALUES ('10.0,10.0'); INSERT INTO POINT_TBL(f1) VALUES ('(10.0 10.0)'); +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 10.0) x'); + INSERT INTO POINT_TBL(f1) VALUES ('(10.0,10.0'); +INSERT INTO POINT_TBL(f1) VALUES ('(10.0, 1e+500)'); -- Out of range + SELECT '' AS six, * FROM POINT_TBL; diff --git a/src/test/regress/sql/polygon.sql b/src/test/regress/sql/polygon.sql index 7e8cb08cd8b..03fc6a8576a 100644 --- a/src/test/regress/sql/polygon.sql +++ b/src/test/regress/sql/polygon.sql @@ -11,6 +11,10 @@ INSERT INTO POLYGON_TBL(f1) VALUES ('(2.0,0.0),(2.0,4.0),(0.0,0.0)'); INSERT INTO POLYGON_TBL(f1) VALUES ('(3.0,1.0),(3.0,3.0),(1.0,0.0)'); +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(3,4),(5,6),(7,8)'); +INSERT INTO POLYGON_TBL(f1) VALUES ('(7,8),(5,6),(3,4),(1,2)'); -- Reverse +INSERT INTO POLYGON_TBL(f1) VALUES ('(1,2),(7,8),(5,6),(3,-4)'); + -- degenerate polygons INSERT INTO POLYGON_TBL(f1) VALUES ('(0.0,0.0)'); @@ -30,93 +34,6 @@ INSERT INTO POLYGON_TBL(f1) VALUES ('asdf'); SELECT '' AS four, * FROM POLYGON_TBL; --- overlap -SELECT '' AS three, p.* - FROM POLYGON_TBL p - WHERE p.f1 && '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- left overlap -SELECT '' AS four, p.* - FROM POLYGON_TBL p - WHERE p.f1 &< '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- right overlap -SELECT '' AS two, p.* - FROM POLYGON_TBL p - WHERE p.f1 &> '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- left of -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 << '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- right of -SELECT '' AS zero, p.* - FROM POLYGON_TBL p - WHERE p.f1 >> '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- contained -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 <@ polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- same -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 ~= polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- contains -SELECT '' AS one, p.* - FROM POLYGON_TBL p - WHERE p.f1 @> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)'; - --- --- polygon logic --- --- left of -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' << polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - --- left overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' << polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS true; - --- right overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' &> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - --- right of -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' >> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - --- contained in -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' <@ polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - --- contains -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' @> polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - -SELECT '((0,4),(6,4),(1,2),(6,0),(0,0))'::polygon @> '((2,1),(2,3),(3,3),(3,1))'::polygon AS "false"; - -SELECT '((0,4),(6,4),(3,2),(6,0),(0,0))'::polygon @> '((2,1),(2,3),(3,3),(3,1))'::polygon AS "true"; - -SELECT '((1,1),(1,4),(5,4),(5,3),(2,3),(2,2),(5,2),(5,1))'::polygon @> '((3,2),(3,3),(4,3),(4,2))'::polygon AS "false"; - -SELECT '((0,0),(0,3),(3,3),(3,0))'::polygon @> '((2,1),(2,2),(3,2),(3,1))'::polygon AS "true"; - --- same -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' ~= polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS false; - --- overlap -SELECT polygon '(2.0,0.0),(2.0,4.0),(0.0,0.0)' && polygon '(3.0,1.0),(3.0,3.0),(1.0,0.0)' AS true; - -SELECT '((0,4),(6,4),(1,2),(6,0),(0,0))'::polygon && '((2,1),(2,3),(3,3),(3,1))'::polygon AS "true"; - -SELECT '((1,4),(1,1),(4,1),(4,2),(2,2),(2,4),(1,4))'::polygon && '((3,3),(4,3),(4,4),(3,4),(3,3))'::polygon AS "false"; -SELECT '((200,800),(800,800),(800,200),(200,200))' && '(1000,1000,0,0)'::polygon AS "true"; - --- distance from a point -SELECT '(0,0)'::point <-> '((0,0),(1,2),(2,1))'::polygon as on_corner, - '(1,1)'::point <-> '((0,0),(2,2),(1,3))'::polygon as on_segment, - '(2,2)'::point <-> '((0,0),(1,4),(3,1))'::polygon as inside, - '(3,3)'::point <-> '((0,2),(2,0),(2,2))'::polygon as near_corner, - '(4,4)'::point <-> '((0,0),(0,3),(4,0))'::polygon as near_segment; - -- -- Test the SP-GiST index -- @@ -145,15 +62,11 @@ SET enable_seqscan = ON; SET enable_indexscan = OFF; SET enable_bitmapscan = OFF; -CREATE TABLE quad_poly_tbl_ord_seq1 AS -SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id -FROM quad_poly_tbl; - -CREATE TABLE quad_poly_tbl_ord_seq2 AS +CREATE TEMP TABLE quad_poly_tbl_ord_seq2 AS SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; --- check results results from index scan +-- check results from index scan SET enable_seqscan = OFF; SET enable_indexscan = OFF; SET enable_bitmapscan = ON; @@ -206,6 +119,24 @@ EXPLAIN (COSTS OFF) SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))'; SELECT count(*) FROM quad_poly_tbl WHERE p ~= polygon '((200, 300),(210, 310),(230, 290))'; +-- test ORDER BY distance +SET enable_indexscan = ON; +SET enable_bitmapscan = OFF; + +EXPLAIN (COSTS OFF) +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +CREATE TEMP TABLE quad_poly_tbl_ord_idx2 AS +SELECT rank() OVER (ORDER BY p <-> point '123,456') n, p <-> point '123,456' dist, id +FROM quad_poly_tbl WHERE p <@ polygon '((300,300),(400,600),(600,500),(700,200))'; + +SELECT * +FROM quad_poly_tbl_ord_seq2 seq FULL JOIN quad_poly_tbl_ord_idx2 idx + ON seq.n = idx.n AND seq.id = idx.id AND + (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) +WHERE seq.id IS NULL OR idx.id IS NULL; + RESET enable_seqscan; RESET enable_indexscan; RESET enable_bitmapscan; diff --git a/src/test/regress/sql/polymorphism.sql b/src/test/regress/sql/polymorphism.sql index 2f65f0f97d6..03606671d92 100644 --- a/src/test/regress/sql/polymorphism.sql +++ b/src/test/regress/sql/polymorphism.sql @@ -785,6 +785,21 @@ select dfunc('a'::text, 'b', flag => false); -- mixed notation select dfunc('a'::text, 'b', true); -- full positional notation select dfunc('a'::text, 'b', flag => true); -- mixed notation +-- this tests lexer edge cases around => +select dfunc(a =>-1); +select dfunc(a =>+1); +select dfunc(a =>/**/1); +select dfunc(a =>--comment to be removed by psql + 1); +-- need DO to protect the -- from psql +do $$ + declare r integer; + begin + select dfunc(a=>-- comment + 1) into r; + raise info 'r = %', r; + end; +$$; -- check reverse-listing of named-arg calls CREATE VIEW dfview AS diff --git a/src/test/regress/sql/portals.sql b/src/test/regress/sql/portals.sql index d1a589094ea..52560ac0275 100644 --- a/src/test/regress/sql/portals.sql +++ b/src/test/regress/sql/portals.sql @@ -472,6 +472,30 @@ DELETE FROM onek WHERE CURRENT OF c1; SELECT stringu1 FROM onek WHERE stringu1 = 'DZAAAA'; ROLLBACK; +-- Check behavior with rewinding to a previous child scan node, +-- as per bug #15395 +BEGIN; +CREATE TABLE current_check (currentid int, payload text); +CREATE TABLE current_check_1 () INHERITS (current_check); +CREATE TABLE current_check_2 () INHERITS (current_check); +INSERT INTO current_check_1 SELECT i, 'p' || i FROM generate_series(1,9) i; +INSERT INTO current_check_2 SELECT i, 'P' || i FROM generate_series(10,19) i; + +DECLARE c1 SCROLL CURSOR FOR SELECT * FROM current_check; + +-- This tests the fetch-backwards code path +FETCH ABSOLUTE 12 FROM c1; +FETCH ABSOLUTE 8 FROM c1; +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *; + +-- This tests the ExecutorRewind code path +FETCH ABSOLUTE 13 FROM c1; +FETCH ABSOLUTE 1 FROM c1; +DELETE FROM current_check WHERE CURRENT OF c1 RETURNING *; + +SELECT * FROM current_check; +ROLLBACK; + -- Make sure snapshot management works okay, per bug report in -- 235395b90909301035v7228ce63q392931f15aa74b31@mail.gmail.com BEGIN; diff --git a/src/test/regress/sql/prepare.sql b/src/test/regress/sql/prepare.sql index 25f814b4667..985d0f05c96 100644 --- a/src/test/regress/sql/prepare.sql +++ b/src/test/regress/sql/prepare.sql @@ -36,21 +36,21 @@ PREPARE q2(text) AS EXECUTE q2('postgres'); -PREPARE q3(text, int, float, boolean, oid, smallint) AS +PREPARE q3(text, int, float, boolean, smallint) AS SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR - ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int) + ten = $3::bigint OR true = $4 OR odd = $5::int) ORDER BY unique1; -EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint); +EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); -- too few params EXECUTE q3('bool'); -- too many params -EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 500::oid, 4::bigint, true); +EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); -- wrong param types -EXECUTE q3(5::smallint, 10.5::float, false, 500::oid, 4::bigint, 'bytea'); +EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); -- invalid type PREPARE q4(nonexistenttype) AS SELECT $1; @@ -61,6 +61,9 @@ PREPARE q5(int, text) AS ORDER BY unique1; CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); SELECT * FROM q5_prep_results; +CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') + WITH NO DATA; +SELECT * FROM q5_prep_nodata; -- unknown or unspecified parameter types: should succeed PREPARE q6 AS diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql index 0a8abf20769..f15d1f37737 100644 --- a/src/test/regress/sql/privileges.sql +++ b/src/test/regress/sql/privileges.sql @@ -129,7 +129,7 @@ SELECT * FROM atest1; -- ok -- test leaky-function protections in selfuncs --- regress_priv_user1 will own a table and provide a view for it. +-- regress_priv_user1 will own a table and provide views for it. SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE atest12 as @@ -144,10 +144,13 @@ CREATE FUNCTION leak(integer,integer) RETURNS boolean CREATE OPERATOR <<< (procedure = leak, leftarg = integer, rightarg = integer, restrict = scalarltsel); --- view with leaky operator +-- views with leaky operator CREATE VIEW atest12v AS SELECT * FROM atest12 WHERE b <<< 5; +CREATE VIEW atest12sbv WITH (security_barrier=true) AS + SELECT * FROM atest12 WHERE b <<< 5; GRANT SELECT ON atest12v TO PUBLIC; +GRANT SELECT ON atest12sbv TO PUBLIC; -- This plan should use nestloop, knowing that few rows will be selected. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; @@ -156,6 +159,10 @@ EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; EXPLAIN (COSTS OFF) SELECT * FROM atest12 x, atest12 y WHERE x.a = y.b and abs(y.a) <<< 5; +-- This should also be a nestloop, but the security barrier forces the inner +-- scan to be materialized +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; + -- Check if regress_priv_user2 can break security. SET SESSION AUTHORIZATION regress_priv_user2; @@ -168,15 +175,25 @@ CREATE OPERATOR >>> (procedure = leak2, leftarg = integer, rightarg = integer, -- This should not show any "leak" notices before failing. EXPLAIN (COSTS OFF) SELECT * FROM atest12 WHERE a >>> 0; --- This plan should use hashjoin, as it will expect many rows to be selected. +-- These plans should continue to use a nestloop, since they execute with the +-- privileges of the view owner. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y WHERE x.a = y.b; + +-- A non-security barrier view does not guard against information leakage. +EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y + WHERE x.a = y.b and abs(y.a) <<< 5; + +-- But a security barrier view isolates the leaky operator. +EXPLAIN (COSTS OFF) SELECT * FROM atest12sbv x, atest12sbv y + WHERE x.a = y.b and abs(y.a) <<< 5; -- Now regress_priv_user1 grants sufficient access to regress_priv_user2. SET SESSION AUTHORIZATION regress_priv_user1; GRANT SELECT (a, b) ON atest12 TO PUBLIC; SET SESSION AUTHORIZATION regress_priv_user2; --- Now regress_priv_user2 will also get a good row estimate. +-- regress_priv_user2 should continue to get a good row estimate. EXPLAIN (COSTS OFF) SELECT * FROM atest12v x, atest12v y WHERE x.a = y.b; -- But not for this, due to lack of table-wide permissions needed @@ -349,114 +366,6 @@ UPDATE atest5 SET one = 1; -- fail SELECT atest6 FROM atest6; -- ok COPY atest6 TO stdout; -- ok --- test column privileges with MERGE -SET SESSION AUTHORIZATION regress_priv_user1; -CREATE TABLE mtarget (a int, b text); -CREATE TABLE msource (a int, b text); -INSERT INTO mtarget VALUES (1, 'init1'), (2, 'init2'); -INSERT INTO msource VALUES (1, 'source1'), (2, 'source2'), (3, 'source3'); - -GRANT SELECT (a) ON msource TO regress_priv_user4; -GRANT SELECT (a) ON mtarget TO regress_priv_user4; -GRANT INSERT (a,b) ON mtarget TO regress_priv_user4; -GRANT UPDATE (b) ON mtarget TO regress_priv_user4; - -SET SESSION AUTHORIZATION regress_priv_user4; - --- --- test source privileges --- - --- fail (no SELECT priv on s.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); - --- fail (s.b used in the INSERTed values) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = 'x' -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); - --- fail (s.b used in the WHEN quals) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND s.b = 'x' THEN - UPDATE SET b = 'x' -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); - --- this should be ok since only s.a is accessed -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = 'ok' -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); -ROLLBACK; - -SET SESSION AUTHORIZATION regress_priv_user1; -GRANT SELECT (b) ON msource TO regress_priv_user4; -SET SESSION AUTHORIZATION regress_priv_user4; - --- should now be ok -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); -ROLLBACK; - --- --- test target privileges --- - --- fail (no SELECT priv on t.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = t.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, NULL); - --- fail (no UPDATE on t.a) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b, a = t.a + 1 -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); - --- fail (no SELECT on t.b) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - UPDATE SET b = s.b -WHEN NOT MATCHED THEN - INSERT VALUES (a, b); - --- ok -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED THEN - UPDATE SET b = s.b; -ROLLBACK; - --- fail (no DELETE) -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - DELETE; - --- grant delete privileges -SET SESSION AUTHORIZATION regress_priv_user1; -GRANT DELETE ON mtarget TO regress_priv_user4; --- should be ok now -BEGIN; -MERGE INTO mtarget t USING msource s ON t.a = s.a -WHEN MATCHED AND t.b IS NOT NULL THEN - DELETE; -ROLLBACK; - -- check error reporting with column privs SET SESSION AUTHORIZATION regress_priv_user1; CREATE TABLE t1 (c1 int, c2 int, c3 int check (c3 < 5), primary key (c1, c2)); @@ -515,27 +424,27 @@ DELETE FROM atest5 WHERE two = 2; -- ok -- check inheritance cases SET SESSION AUTHORIZATION regress_priv_user1; -CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS; -CREATE TABLE atestp2 (fx int, fy int) WITH OIDS; +CREATE TABLE atestp1 (f1 int, f2 int); +CREATE TABLE atestp2 (fx int, fy int); CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2); -GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_priv_user2; +GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2; GRANT SELECT(fx) ON atestc TO regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2; SELECT fx FROM atestp2; -- ok SELECT fy FROM atestp2; -- ok SELECT atestp2 FROM atestp2; -- ok -SELECT oid FROM atestp2; -- ok +SELECT tableoid FROM atestp2; -- ok SELECT fy FROM atestc; -- fail SET SESSION AUTHORIZATION regress_priv_user1; -GRANT SELECT(fy,oid) ON atestc TO regress_priv_user2; +GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2; SET SESSION AUTHORIZATION regress_priv_user2; SELECT fx FROM atestp2; -- still ok SELECT fy FROM atestp2; -- ok SELECT atestp2 FROM atestp2; -- ok -SELECT oid FROM atestp2; -- ok +SELECT tableoid FROM atestp2; -- ok -- privileges on functions, languages @@ -603,7 +512,7 @@ GRANT ALL PRIVILEGES ON LANGUAGE sql TO PUBLIC; BEGIN; SELECT '{1}'::int4[]::int8[]; REVOKE ALL ON FUNCTION int8(integer) FROM PUBLIC; -SELECT '{1}'::int4[]::int8[]; --superuser, suceed +SELECT '{1}'::int4[]::int8[]; --superuser, succeed SET SESSION AUTHORIZATION regress_priv_user4; SELECT '{1}'::int4[]::int8[]; --other user, fail ROLLBACK; @@ -823,6 +732,24 @@ from (select oid from pg_class where relname = 'atest1') as t1; select has_table_privilege(t1.oid,'trigger') from (select oid from pg_class where relname = 'atest1') as t1; +-- has_column_privilege function + +-- bad-input checks (as non-super-user) +select has_column_privilege('pg_authid',NULL,'select'); +select has_column_privilege('pg_authid','nosuchcol','select'); +select has_column_privilege(9999,'nosuchcol','select'); +select has_column_privilege(9999,99::int2,'select'); +select has_column_privilege('pg_authid',99::int2,'select'); +select has_column_privilege(9999,99::int2,'select'); + +create temp table mytable(f1 int, f2 int, f3 int); +alter table mytable drop column f2; +select has_column_privilege('mytable','f2','select'); +select has_column_privilege('mytable','........pg.dropped.2........','select'); +select has_column_privilege('mytable',2::int2,'select'); +revoke select on table mytable from regress_priv_user3; +select has_column_privilege('mytable',2::int2,'select'); +drop table mytable; -- Grant options @@ -1025,6 +952,13 @@ ALTER DEFAULT PRIVILEGES FOR ROLE regress_priv_user1 REVOKE EXECUTE ON FUNCTIONS ALTER DEFAULT PRIVILEGES IN SCHEMA testns GRANT USAGE ON SCHEMAS TO regress_priv_user2; -- error +-- +-- Testing blanket default grants is very hazardous since it might change +-- the privileges attached to objects created by concurrent regression tests. +-- To avoid that, be sure to revoke the privileges again before committing. +-- +BEGIN; + ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO regress_priv_user2; CREATE SCHEMA testns2; @@ -1048,6 +982,8 @@ SELECT has_schema_privilege('regress_priv_user2', 'testns4', 'CREATE'); -- yes ALTER DEFAULT PRIVILEGES REVOKE ALL ON SCHEMAS FROM regress_priv_user2; +COMMIT; + CREATE SCHEMA testns5; SELECT has_schema_privilege('regress_priv_user2', 'testns5', 'USAGE'); -- no @@ -1155,9 +1091,7 @@ SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testfunc(int)', SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testagg(int)', 'EXECUTE'); -- true SELECT has_function_privilege('regress_priv_user1', 'testns.priv_testproc(int)', 'EXECUTE'); -- true -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA testns CASCADE; -\set VERBOSITY default -- Change owner of the schema & and rename of new schema owner @@ -1176,9 +1110,7 @@ ALTER ROLE regress_schemauser2 RENAME TO regress_schemauser_renamed; SELECT nspname, rolname FROM pg_namespace, pg_roles WHERE pg_namespace.nspname = 'testns' AND pg_namespace.nspowner = pg_roles.oid; set session role regress_schemauser_renamed; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA testns CASCADE; -\set VERBOSITY default -- clean up \c - diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index b45da9bb8de..26a0bcf7181 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -135,6 +135,7 @@ select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over' \pset -- test multi-line headers, wrapping, and newline indicators +-- in aligned, unaligned, and wrapped formats prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a @@ -398,10 +399,286 @@ execute q; deallocate q; \pset linestyle ascii +\pset border 1 + +-- support table for output-format tests (useful to create a footer) + +create table psql_serial_tab (id serial); + +-- test header/footer/tuples_only behavior in aligned/unaligned/wrapped cases + +\pset format aligned + +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +-- empty table is a special case for this format +select 1 where false; + +\pset format unaligned + +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false -prepare q as select ' | = | lkjsafi\\/ /oeu rio)(!@&*#)*(!&@*) \ (&' as " | -- | 012345678 9abc def!*@#&!@(*&*~~_+-=\ \", '11' as "0123456789", 11 as int from generate_series(1,10) as n; +\pset format wrapped + +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +-- check conditional tableam display + +-- Create a heap2 table am handler with heapam handler +CREATE ACCESS METHOD heap_psql TYPE TABLE HANDLER heap_tableam_handler; +CREATE TABLE tbl_heap_psql(f1 int, f2 char(100)) using heap_psql; +CREATE TABLE tbl_heap(f1 int, f2 char(100)) using heap; +\d+ tbl_heap_psql +\d+ tbl_heap +\set HIDE_TABLEAM off +\d+ tbl_heap_psql +\d+ tbl_heap +\set HIDE_TABLEAM on +DROP TABLE tbl_heap, tbl_heap_psql; +DROP ACCESS METHOD heap_psql; + +-- test numericlocale (as best we can without control of psql's locale) + +\pset format aligned +\pset expanded off +\pset numericlocale true + +select n, -n as m, n * 111 as x, '1e90'::float8 as f +from generate_series(0,3) n; + +\pset numericlocale false + +-- test asciidoc output format \pset format asciidoc + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some|text' as "a|title", ' ' as "empty ", n as int + from generate_series(1,2) as n; + +\pset expanded off +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +\pset expanded on +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +deallocate q; + +-- test csv output format + +\pset format csv + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some"text' as "a""title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; + +\pset expanded off +execute q; + +\pset expanded on +execute q; + +deallocate q; + +-- special cases +\pset expanded off +select 'comma,comma' as comma, 'semi;semi' as semi; +\pset csv_fieldsep ';' +select 'comma,comma' as comma, 'semi;semi' as semi; +select '\.' as data; +\pset csv_fieldsep '.' +select '\' as d1, '' as d2; + +-- illegal csv separators +\pset csv_fieldsep '' +\pset csv_fieldsep '\0' +\pset csv_fieldsep '\n' +\pset csv_fieldsep '\r' +\pset csv_fieldsep '"' +\pset csv_fieldsep ',,' + +\pset csv_fieldsep ',' + +-- test html output format + +\pset format html + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some"text' as "a&title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; + +\pset expanded off +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset tableattr foobar +execute q; +\pset tableattr + +\pset expanded on +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset tableattr foobar +execute q; +\pset tableattr + +deallocate q; + +-- test latex output format + +\pset format latex + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; + +\pset expanded off +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +\pset border 3 +execute q; + +\pset expanded on +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +\pset border 3 +execute q; + +deallocate q; + +-- test latex-longtable output format + +\pset format latex-longtable + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some\more_text' as "a$title", E' #%&^~|\n{bar}' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; + \pset expanded off \pset border 0 execute q; @@ -412,6 +689,13 @@ execute q; \pset border 2 execute q; +\pset border 3 +execute q; + +\pset tableattr lr +execute q; +\pset tableattr + \pset expanded on \pset border 0 execute q; @@ -422,12 +706,87 @@ execute q; \pset border 2 execute q; +\pset border 3 +execute q; + +\pset tableattr lr +execute q; +\pset tableattr + deallocate q; +-- test troff-ms output format + +\pset format troff-ms + +\pset border 1 +\pset expanded off +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false +\pset expanded on +\d psql_serial_tab_id_seq +\pset tuples_only true +\df exp +\pset tuples_only false + +prepare q as + select 'some\text' as "a\title", E' \n' as "junk", + ' ' as "empty", n as int + from generate_series(1,2) as n; + +\pset expanded off +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +\pset expanded on +\pset border 0 +execute q; + +\pset border 1 +execute q; + +\pset border 2 +execute q; + +deallocate q; + +-- check ambiguous format requests + +\pset format a +\pset format l + +-- clean up after output format tests + +drop table psql_serial_tab; + \pset format aligned \pset expanded off \pset border 1 +-- \echo and allied features + +\echo this is a test +\echo -n without newline +\echo with -n newline +\echo '-n' with newline + +\set foo bar +\echo foo = :foo + +\qecho this is a test +\qecho foo = :foo + +\warn this is a test +\warn foo = :foo + -- tests for \if ... \endif \if true @@ -484,6 +843,17 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two; \echo 'all false' \endif +-- test true-false elif after initial true branch +\if true + \echo 'should print #2-5' +\elif true + \echo 'should not print #2-6' +\elif false + \echo 'should not print #2-7' +\else + \echo 'should not print #2-8' +\endif + -- test simple true-then-else \if true \echo 'first thing true' @@ -552,22 +922,59 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two; :try_to_quit \echo `nosuchcommand` :foo :'foo' :"foo" \pset fieldsep | `nosuchcommand` :foo :'foo' :"foo" - \a \C arg1 \c arg1 arg2 arg3 arg4 \cd arg1 \conninfo + \a + \C arg1 + \c arg1 arg2 arg3 arg4 + \cd arg1 + \conninfo \copy arg1 arg2 arg3 arg4 arg5 arg6 - \copyright \dt arg1 \e arg1 arg2 + \copyright + SELECT 1 as one, 2, 3 \crosstabview + \dt arg1 + \e arg1 arg2 \ef whole_line \ev whole_line - \echo arg1 arg2 arg3 arg4 arg5 \echo arg1 \encoding arg1 \errverbose - \g arg1 \gx arg1 \gexec \h \html \i arg1 \ir arg1 \l arg1 \lo arg1 arg2 - \o arg1 \p \password arg1 \prompt arg1 arg2 \pset arg1 arg2 \q - \reset \s arg1 \set arg1 arg2 arg3 arg4 arg5 arg6 arg7 \setenv arg1 arg2 + \echo arg1 arg2 arg3 arg4 arg5 + \echo arg1 + \encoding arg1 + \errverbose + \f arg1 + \g arg1 + \gx arg1 + \gexec + SELECT 1 AS one \gset + \h + \? + \html + \i arg1 + \ir arg1 + \l arg1 + \lo arg1 arg2 + \lo_list + \o arg1 + \p + \password arg1 + \prompt arg1 arg2 + \pset arg1 arg2 + \q + \reset + \s arg1 + \set arg1 arg2 arg3 arg4 arg5 arg6 arg7 + \setenv arg1 arg2 \sf whole_line \sv whole_line - \t arg1 \T arg1 \timing arg1 \unset arg1 \w arg1 \watch arg1 \x arg1 + \t arg1 + \T arg1 + \timing arg1 + \unset arg1 + \w arg1 + \watch arg1 + \x arg1 -- \else here is eaten as part of OT_FILEPIPE argument \w |/no/such/file \else -- \endif here is eaten as part of whole-line argument \! whole_line \endif + \z \else \echo 'should print #8-1' \endif @@ -658,6 +1065,21 @@ DROP TABLE this_table_does_not_exist; \echo 'last error message:' :LAST_ERROR_MESSAGE \echo 'last error code:' :LAST_ERROR_SQLSTATE +-- nondefault verbosity error settings (except verbose, which is too unstable) +\set VERBOSITY terse +SELECT 1 UNION; +\echo 'error:' :ERROR +\echo 'error code:' :SQLSTATE +\echo 'last error message:' :LAST_ERROR_MESSAGE + +\set VERBOSITY sqlstate +SELECT 1/0; +\echo 'error:' :ERROR +\echo 'error code:' :SQLSTATE +\echo 'last error message:' :LAST_ERROR_MESSAGE + +\set VERBOSITY default + -- working \gdesc SELECT 3 AS three, 4 AS four \gdesc \echo 'error:' :ERROR @@ -688,3 +1110,75 @@ select 1/(15-unique2) from tenk1 order by unique2 limit 19; \echo 'last error code:' :LAST_ERROR_SQLSTATE \unset FETCH_COUNT + +create schema testpart; +create role regress_partitioning_role; + +alter schema testpart owner to regress_partitioning_role; + +set role to regress_partitioning_role; + +-- run test inside own schema and hide other partitions +set search_path to testpart; + +create table testtable_apple(logdate date); +create table testtable_orange(logdate date); +create index testtable_apple_index on testtable_apple(logdate); +create index testtable_orange_index on testtable_orange(logdate); + +create table testpart_apple(logdate date) partition by range(logdate); +create table testpart_orange(logdate date) partition by range(logdate); + +create index testpart_apple_index on testpart_apple(logdate); +create index testpart_orange_index on testpart_orange(logdate); + +-- only partition related object should be displayed +\dP test*apple* +\dPt test*apple* +\dPi test*apple* + +drop table testtable_apple; +drop table testtable_orange; +drop table testpart_apple; +drop table testpart_orange; + +create table parent_tab (id int) partition by range (id); +create index parent_index on parent_tab (id); +create table child_0_10 partition of parent_tab + for values from (0) to (10); +create table child_10_20 partition of parent_tab + for values from (10) to (20); +create table child_20_30 partition of parent_tab + for values from (20) to (30); +insert into parent_tab values (generate_series(0,29)); +create table child_30_40 partition of parent_tab +for values from (30) to (40) + partition by range(id); +create table child_30_35 partition of child_30_40 + for values from (30) to (35); +create table child_35_40 partition of child_30_40 + for values from (35) to (40); +insert into parent_tab values (generate_series(30,39)); + +\dPt +\dPi + +\dP testpart.* +\dP + +\dPtn +\dPin +\dPn +\dPn testpart.* + +drop table parent_tab cascade; + +drop schema testpart; + +set search_path to default; + +set role to default; +drop role regress_partitioning_role; + +-- \d on toast table (use pg_statistic's toast table, which has a known name) +\d pg_toast.pg_toast_2619 diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql index 815410b3c5a..5773a755cf3 100644 --- a/src/test/regress/sql/publication.sql +++ b/src/test/regress/sql/publication.sql @@ -6,12 +6,17 @@ CREATE ROLE regress_publication_user2; CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_publication_user'; +-- suppress warning that depends on wal_level +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_default; +RESET client_min_messages; COMMENT ON PUBLICATION testpub_default IS 'test publication'; SELECT obj_description(p.oid, 'pg_publication') FROM pg_publication p; +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpib_ins_trunct WITH (publish = insert); +RESET client_min_messages; ALTER PUBLICATION testpub_default SET (publish = update); @@ -32,7 +37,9 @@ CREATE TABLE pub_test.testpub_nopk (foo int, bar int); CREATE VIEW testpub_view AS SELECT 1; CREATE TABLE testpub_parted (a int) PARTITION BY LIST (a); +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_foralltables FOR ALL TABLES WITH (publish = 'insert'); +RESET client_min_messages; ALTER PUBLICATION testpub_foralltables SET (publish = 'insert, update'); CREATE TABLE testpub_tbl2 (id serial primary key, data text); @@ -52,8 +59,10 @@ DROP PUBLICATION testpub_foralltables; CREATE TABLE testpub_tbl3 (a int); CREATE TABLE testpub_tbl3a (b text) INHERITS (testpub_tbl3); +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub3 FOR TABLE testpub_tbl3; CREATE PUBLICATION testpub4 FOR TABLE ONLY testpub_tbl3; +RESET client_min_messages; \dRp+ testpub3 \dRp+ testpub4 @@ -62,7 +71,9 @@ DROP PUBLICATION testpub3, testpub4; -- fail - view CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_view; +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub_fortbl FOR TABLE testpub_tbl1, pub_test.testpub_nopk; +RESET client_min_messages; -- fail - already added ALTER PUBLICATION testpub_fortbl ADD TABLE testpub_tbl1; -- fail - already added @@ -98,7 +109,9 @@ CREATE PUBLICATION testpub2; -- fail SET ROLE regress_publication_user; GRANT CREATE ON DATABASE regression TO regress_publication_user2; SET ROLE regress_publication_user2; +SET client_min_messages = 'ERROR'; CREATE PUBLICATION testpub2; -- ok +RESET client_min_messages; ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1; -- fail diff --git a/src/test/regress/sql/rangefuncs.sql b/src/test/regress/sql/rangefuncs.sql index fc8ad9a158d..5d29d2e4012 100644 --- a/src/test/regress/sql/rangefuncs.sql +++ b/src/test/regress/sql/rangefuncs.sql @@ -319,6 +319,21 @@ SELECT * FROM (VALUES (1),(2),(3)) v1(r1), LATERAL (SELECT r1, * FROM (VALUES (10),(20),(30)) v2(r2) LEFT JOIN generate_series(r1,2+r2/5) f(i) ON ((r2+i)<100) OFFSET 0) s1; +-- check handling of FULL JOIN with multiple lateral references (bug #15741) + +SELECT * +FROM (VALUES (1),(2)) v1(r1) + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, v1.r1) AS gs1 + LEFT JOIN LATERAL ( + SELECT * + FROM generate_series(1, gs1) AS gs2 + LEFT JOIN generate_series(1, gs2) AS gs3 ON TRUE + ) AS ss1 ON TRUE + FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE + ) AS ss0 ON TRUE; + DROP FUNCTION rngfunc_sql(int,int); DROP FUNCTION rngfunc_mat(int,int); DROP SEQUENCE rngfunc_rescan_seq1; diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql index 55638a85ee1..8960add976f 100644 --- a/src/test/regress/sql/rangetypes.sql +++ b/src/test/regress/sql/rangetypes.sql @@ -119,7 +119,7 @@ select numrange(1.0, 2.0) * numrange(1.5, 3.0); select numrange(1.0, 2.0) * numrange(2.5, 3.0); create table numrange_test2(nr numrange); -create index numrange_test2_hash_idx on numrange_test2 (nr); +create index numrange_test2_hash_idx on numrange_test2 using hash (nr); INSERT INTO numrange_test2 VALUES('[, 5)'); INSERT INTO numrange_test2 VALUES(numrange(1.1, 2.2)); @@ -165,6 +165,10 @@ select daterange('2000-01-10'::date, '2000-01-20'::date, '(]'); select daterange('2000-01-10'::date, '2000-01-20'::date, '()'); select daterange('2000-01-10'::date, '2000-01-11'::date, '()'); select daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); +select daterange('-infinity'::date, '2000-01-01'::date, '()'); +select daterange('-infinity'::date, '2000-01-01'::date, '[)'); +select daterange('2000-01-01'::date, 'infinity'::date, '[)'); +select daterange('2000-01-01'::date, 'infinity'::date, '[]'); -- test GiST index that's been built incrementally create table test_range_gist(ir int4range); diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql index 1361b625707..a1742240c4b 100644 --- a/src/test/regress/sql/regex.sql +++ b/src/test/regress/sql/regex.sql @@ -118,6 +118,16 @@ select regexp_matches('Programmer', '(\w)(.*?\1)', 'g'); select regexp_matches('foo/bar/baz', '^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$', ''); +-- Test that greediness can be overridden by outer quantifier +select regexp_matches('llmmmfff', '^(l*)(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*){1,1}?(.*){1,1}?(f*)$'); +select regexp_matches('llmmmfff', '^(l*?)(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*)(f*)$'); +select regexp_matches('llmmmfff', '^(l*?){1,1}?(.*){1,1}?(f*)$'); + -- Test for infinite loop in cfindloop with zero-length possible match -- but no actual match (can only happen in the presence of backrefs) select 'a' ~ '$()|^\1'; diff --git a/src/test/regress/sql/reindex_catalog.sql b/src/test/regress/sql/reindex_catalog.sql new file mode 100644 index 00000000000..87ecf52244f --- /dev/null +++ b/src/test/regress/sql/reindex_catalog.sql @@ -0,0 +1,41 @@ +-- +-- Check that system tables can be reindexed. +-- +-- Note that this test currently is not included in the default +-- schedules, as currently reindexing catalog tables can cause +-- deadlocks: +-- +-- * The lock upgrade between the ShareLock acquired for the reindex +-- and RowExclusiveLock needed for pg_class/pg_index locks can +-- trigger deadlocks. +-- +-- * The uniqueness checks performed when reindexing a unique/primary +-- key index possibly need to wait for the transaction of a +-- about-to-deleted row in pg_class to commit. That can cause +-- deadlocks because, in contrast to user tables, locks on catalog +-- tables are routinely released before commit - therefore the lock +-- held for reindexing doesn't guarantee that no running transaction +-- performed modifications in the table underlying the index. +-- +-- This is particularly problematic as such conflicts can be +-- triggered even when run in isolation, as a previous session's +-- temporary table cleanup might still be running (even when the +-- session ended from a client perspective). + + +-- Check reindexing of whole tables +REINDEX TABLE pg_class; -- mapped, non-shared, critical +REINDEX TABLE pg_index; -- non-mapped, non-shared, critical +REINDEX TABLE pg_operator; -- non-mapped, non-shared, critical +REINDEX TABLE pg_database; -- mapped, shared, critical +REINDEX TABLE pg_shdescription; -- mapped, shared non-critical + +-- Check that individual system indexes can be reindexed. That's a bit +-- different from the entire-table case because reindex_relation +-- treats e.g. pg_class special. +REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical +REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical +REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical +REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical +REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical +REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql index 37fbf41f7d5..cac5b0bcb0d 100644 --- a/src/test/regress/sql/reloptions.sql +++ b/src/test/regress/sql/reloptions.sql @@ -15,7 +15,7 @@ CREATE TABLE reloptions_test2(i INT) WITH (not_existing_option=2); CREATE TABLE reloptions_test2(i INT) WITH (not_existing_namespace.fillfactor=2); -- Fail while setting improper values -CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=30.5); +CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=-30.1); CREATE TABLE reloptions_test2(i INT) WITH (fillfactor='string'); CREATE TABLE reloptions_test2(i INT) WITH (fillfactor=true); CREATE TABLE reloptions_test2(i INT) WITH (autovacuum_enabled=12); @@ -52,10 +52,27 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass AND -- RESET fails if a value is specified ALTER TABLE reloptions_test RESET (fillfactor=12); --- The OIDS option is not stored as reloption +-- Test vacuum_truncate option DROP TABLE reloptions_test; -CREATE TABLE reloptions_test(i INT) WITH (fillfactor=20, oids=true); -SELECT reloptions, relhasoids FROM pg_class WHERE oid = 'reloptions_test'::regclass; + +CREATE TABLE reloptions_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=false, + toast.vacuum_truncate=false, + autovacuum_enabled=false); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); +VACUUM reloptions_test; +SELECT pg_relation_size('reloptions_test') > 0; + +SELECT reloptions FROM pg_class WHERE oid = + (SELECT reltoastrelid FROM pg_class + WHERE oid = 'reloptions_test'::regclass); + +ALTER TABLE reloptions_test RESET (vacuum_truncate); +SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass; +INSERT INTO reloptions_test VALUES (1, NULL), (NULL, NULL); +VACUUM reloptions_test; +SELECT pg_relation_size('reloptions_test') = 0; -- Test toast.* options DROP TABLE reloptions_test; diff --git a/src/test/regress/sql/reltime.sql b/src/test/regress/sql/reltime.sql deleted file mode 100644 index a07b64e29d8..00000000000 --- a/src/test/regress/sql/reltime.sql +++ /dev/null @@ -1,50 +0,0 @@ --- --- RELTIME --- - -CREATE TABLE RELTIME_TBL (f1 reltime); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 1 minute'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 5 hour'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 10 day'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 34 year'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 3 months'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 14 seconds ago'); - - --- badly formatted reltimes -INSERT INTO RELTIME_TBL (f1) VALUES ('badly formatted reltime'); - -INSERT INTO RELTIME_TBL (f1) VALUES ('@ 30 eons ago'); - --- test reltime operators - -SELECT '' AS six, * FROM RELTIME_TBL; - -SELECT '' AS five, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 <> reltime '@ 10 days'; - -SELECT '' AS three, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 <= reltime '@ 5 hours'; - -SELECT '' AS three, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 < reltime '@ 1 day'; - -SELECT '' AS one, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 = reltime '@ 34 years'; - -SELECT '' AS two, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 >= reltime '@ 1 month'; - -SELECT '' AS five, * FROM RELTIME_TBL - WHERE RELTIME_TBL.f1 > reltime '@ 3 seconds ago'; - -SELECT '' AS fifteen, r1.*, r2.* - FROM RELTIME_TBL r1, RELTIME_TBL r2 - WHERE r1.f1 > r2.f1 - ORDER BY r1.f1, r2.f1; diff --git a/src/test/regress/sql/replica_identity.sql b/src/test/regress/sql/replica_identity.sql index 3d2171c7336..b08a3623b8c 100644 --- a/src/test/regress/sql/replica_identity.sql +++ b/src/test/regress/sql/replica_identity.sql @@ -5,13 +5,12 @@ CREATE TABLE test_replica_identity ( nonkey text, CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE, CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb) -) WITH OIDS; +) ; CREATE TABLE test_replica_identity_othertable (id serial primary key); CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb); CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb); -CREATE UNIQUE INDEX test_replica_identity_oid_idx ON test_replica_identity (oid); CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey); CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey); CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3)); @@ -53,9 +52,6 @@ ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_iden SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass; \d test_replica_identity --- succeed, oid unique index -ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_oid_idx; - -- succeed, nondeferrable unique constraint over nonnullable cols ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer; diff --git a/src/test/regress/sql/roleattributes.sql b/src/test/regress/sql/roleattributes.sql index 1b034d752fb..c961b2d7303 100644 --- a/src/test/regress/sql/roleattributes.sql +++ b/src/test/regress/sql/roleattributes.sql @@ -1,82 +1,83 @@ -- default for superuser is false CREATE ROLE regress_test_def_superuser; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_superuser'; + +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser'; CREATE ROLE regress_test_superuser WITH SUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; ALTER ROLE regress_test_superuser WITH NOSUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; ALTER ROLE regress_test_superuser WITH SUPERUSER; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser'; -- default for inherit is true CREATE ROLE regress_test_def_inherit; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit'; CREATE ROLE regress_test_inherit WITH NOINHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; ALTER ROLE regress_test_inherit WITH INHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; ALTER ROLE regress_test_inherit WITH NOINHERIT; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit'; -- default for create role is false CREATE ROLE regress_test_def_createrole; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole'; CREATE ROLE regress_test_createrole WITH CREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; ALTER ROLE regress_test_createrole WITH NOCREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; ALTER ROLE regress_test_createrole WITH CREATEROLE; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole'; -- default for create database is false CREATE ROLE regress_test_def_createdb; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb'; CREATE ROLE regress_test_createdb WITH CREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; ALTER ROLE regress_test_createdb WITH NOCREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; ALTER ROLE regress_test_createdb WITH CREATEDB; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb'; -- default for can login is false for role CREATE ROLE regress_test_def_role_canlogin; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin'; CREATE ROLE regress_test_role_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; ALTER ROLE regress_test_role_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; ALTER ROLE regress_test_role_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin'; -- default for can login is true for user CREATE USER regress_test_def_user_canlogin; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin'; CREATE USER regress_test_user_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; ALTER USER regress_test_user_canlogin WITH LOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; ALTER USER regress_test_user_canlogin WITH NOLOGIN; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin'; -- default for replication is false CREATE ROLE regress_test_def_replication; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication'; CREATE ROLE regress_test_replication WITH REPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; ALTER ROLE regress_test_replication WITH NOREPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; ALTER ROLE regress_test_replication WITH REPLICATION; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication'; -- default for bypassrls is false CREATE ROLE regress_test_def_bypassrls; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls'; CREATE ROLE regress_test_bypassrls WITH BYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; ALTER ROLE regress_test_bypassrls WITH BYPASSRLS; -SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; +SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls'; -- clean up roles DROP ROLE regress_test_def_superuser; diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql index 6c752089980..d7a5a36cf86 100644 --- a/src/test/regress/sql/rowsecurity.sql +++ b/src/test/regress/sql/rowsecurity.sql @@ -232,11 +232,11 @@ SET SESSION AUTHORIZATION regress_rls_alice; SET row_security TO ON; -CREATE TABLE t1 (a int, junk1 text, b text) WITH OIDS; +CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text); ALTER TABLE t1 DROP COLUMN junk1; -- just a disturbing factor GRANT ALL ON t1 TO public; -COPY t1 FROM stdin WITH (oids); +COPY t1 FROM stdin WITH ; 101 1 aba 102 2 bbb 103 3 ccc @@ -246,18 +246,18 @@ COPY t1 FROM stdin WITH (oids); CREATE TABLE t2 (c float) INHERITS (t1); GRANT ALL ON t2 TO public; -COPY t2 FROM stdin WITH (oids); +COPY t2 FROM stdin; 201 1 abc 1.1 202 2 bcd 2.2 203 3 cde 3.3 204 4 def 4.4 \. -CREATE TABLE t3 (c text, b text, a int) WITH OIDS; +CREATE TABLE t3 (id int not null primary key, c text, b text, a int); ALTER TABLE t3 INHERIT t1; GRANT ALL ON t3 TO public; -COPY t3(a,b,c) FROM stdin WITH (oids); +COPY t3(id, a,b,c) FROM stdin; 301 1 xxx X 302 2 yyy Y 303 3 zzz Z @@ -278,7 +278,7 @@ SELECT * FROM t1 WHERE f_leak(b); EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b); -- reference to system column -SELECT oid, * FROM t1; +SELECT tableoid::regclass, * FROM t1; EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1; -- reference to whole-row reference @@ -293,8 +293,8 @@ SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE; -- union all query -SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3; -EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3; +SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; +EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3; -- superuser is allowed to bypass RLS checks RESET SESSION AUTHORIZATION; @@ -518,9 +518,7 @@ SELECT * FROM rec1; -- fail, mutual recursion via views -- SET SESSION AUTHORIZATION regress_rls_bob; -\set VERBOSITY terse \\ -- suppress cascade details DROP VIEW rec1v, rec2v CASCADE; -\set VERBOSITY default CREATE VIEW rec1v WITH (security_barrier) AS SELECT * FROM rec1; CREATE VIEW rec2v WITH (security_barrier) AS SELECT * FROM rec2; @@ -614,9 +612,9 @@ EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b); UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b); -- returning clause with system column -UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1; +UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *; -UPDATE t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1; +UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; -- updates with from clause EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t3 @@ -663,8 +661,8 @@ SET row_security TO ON; EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b); EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b); -DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1; -DELETE FROM t1 WHERE f_leak(b) RETURNING oid, *, t1; +DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; +DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1; -- -- S.b. view on top of Row-level security @@ -781,7 +779,7 @@ SET SESSION AUTHORIZATION regress_rls_bob; INSERT INTO document VALUES (79, (SELECT cid from category WHERE cname = 'technology'), 1, 'regress_rls_bob', 'technology book, can only insert') ON CONFLICT (did) DO UPDATE SET dtitle = EXCLUDED.dtitle RETURNING *; --- UPDATE path is taken here. Existing tuple passes, since it's cid +-- UPDATE path is taken here. Existing tuple passes, since its cid -- corresponds to "novel", but default USING qual is enforced against -- post-UPDATE tuple too (as always when updating with a policy that lacks an -- explicit WCO), and so this fails: @@ -812,162 +810,6 @@ INSERT INTO document VALUES (4, (SELECT cid from category WHERE cname = 'novel') INSERT INTO document VALUES (1, (SELECT cid from category WHERE cname = 'novel'), 1, 'regress_rls_bob', 'my first novel') ON CONFLICT (did) DO UPDATE SET dauthor = 'regress_rls_carol'; --- --- MERGE --- -RESET SESSION AUTHORIZATION; -DROP POLICY p3_with_all ON document; - -ALTER TABLE document ADD COLUMN dnotes text DEFAULT ''; --- all documents are readable -CREATE POLICY p1 ON document FOR SELECT USING (true); --- one may insert documents only authored by them -CREATE POLICY p2 ON document FOR INSERT WITH CHECK (dauthor = current_user); --- one may only update documents in 'novel' category -CREATE POLICY p3 ON document FOR UPDATE - USING (cid = (SELECT cid from category WHERE cname = 'novel')) - WITH CHECK (dauthor = current_user); --- one may only delete documents in 'manga' category -CREATE POLICY p4 ON document FOR DELETE - USING (cid = (SELECT cid from category WHERE cname = 'manga')); - -SELECT * FROM document; - -SET SESSION AUTHORIZATION regress_rls_bob; - --- Fails, since update violates WITH CHECK qual on dauthor -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge1 ', dauthor = 'regress_rls_alice'; - --- Should be OK since USING and WITH CHECK quals pass -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge2 '; - --- Even when dauthor is updated explicitly, but to the existing value -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge3 ', dauthor = 'regress_rls_bob'; - --- There is a MATCH for did = 3, but UPDATE's USING qual does not allow --- updating an item in category 'science fiction' -MERGE INTO document d -USING (SELECT 3 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge '; - --- The same thing with DELETE action, but fails again because no permissions --- to delete items in 'science fiction' category that did 3 belongs to. -MERGE INTO document d -USING (SELECT 3 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE; - --- Document with did 4 belongs to 'manga' category which is allowed for --- deletion. But this fails because the UPDATE action is matched first and --- UPDATE policy does not allow updation in the category. -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes = '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; - --- UPDATE action is not matched this time because of the WHEN AND qual. --- DELETE still fails because role regress_rls_bob does not have SELECT --- privileges on 'manga' category row in the category table. -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes <> '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; - -SELECT * FROM document WHERE did = 4; - --- Switch to regress_rls_carol role and try the DELETE again. It should succeed --- this time -RESET SESSION AUTHORIZATION; -SET SESSION AUTHORIZATION regress_rls_carol; - -MERGE INTO document d -USING (SELECT 4 as sdid) s -ON did = s.sdid -WHEN MATCHED AND dnotes <> '' THEN - UPDATE SET dnotes = dnotes || ' notes added by merge ' -WHEN MATCHED THEN - DELETE; - --- Switch back to regress_rls_bob role -RESET SESSION AUTHORIZATION; -SET SESSION AUTHORIZATION regress_rls_bob; - --- Try INSERT action. This fails because we are trying to insert --- dauthor = regress_rls_dave and INSERT's WITH CHECK does not allow --- that -MERGE INTO document d -USING (SELECT 12 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_dave', 'another novel'); - --- This should be fine -MERGE INTO document d -USING (SELECT 12 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - DELETE -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); - --- ok -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge4 ' -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); - --- drop and create a new SELECT policy which prevents us from reading --- any document except with category 'magna' -RESET SESSION AUTHORIZATION; -DROP POLICY p1 ON document; -CREATE POLICY p1 ON document FOR SELECT - USING (cid = (SELECT cid from category WHERE cname = 'manga')); - -SET SESSION AUTHORIZATION regress_rls_bob; - --- MERGE can no longer see the matching row and hence attempts the --- NOT MATCHED action, which results in unique key violation -MERGE INTO document d -USING (SELECT 1 as sdid) s -ON did = s.sdid -WHEN MATCHED THEN - UPDATE SET dnotes = dnotes || ' notes added by merge5 ' -WHEN NOT MATCHED THEN - INSERT VALUES (12, 11, 1, 'regress_rls_bob', 'another novel'); - -RESET SESSION AUTHORIZATION; --- drop the restrictive SELECT policy so that we can look at the --- final state of the table -DROP POLICY p1 ON document; --- Just check everything went per plan -SELECT * FROM document; - -- -- ROLE/GROUP -- @@ -996,10 +838,10 @@ EXPLAIN (COSTS OFF) SELECT * FROM z1 WHERE f_leak(b); PREPARE plancache_test AS SELECT * FROM z1 WHERE f_leak(b); EXPLAIN (COSTS OFF) EXECUTE plancache_test; -PREPARE plancache_test2 AS WITH q AS (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2; +PREPARE plancache_test2 AS WITH q AS MATERIALIZED (SELECT * FROM z1 WHERE f_leak(b)) SELECT * FROM q,z2; EXPLAIN (COSTS OFF) EXECUTE plancache_test2; -PREPARE plancache_test3 AS WITH q AS (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b); +PREPARE plancache_test3 AS WITH q AS MATERIALIZED (SELECT * FROM z2) SELECT * FROM q,z1 WHERE f_leak(z1.b); EXPLAIN (COSTS OFF) EXECUTE plancache_test3; SET ROLE regress_rls_group1; @@ -1182,9 +1024,7 @@ DROP TABLE test_qual_pushdown; -- RESET SESSION AUTHORIZATION; -\set VERBOSITY terse \\ -- suppress cascade details DROP TABLE t1 CASCADE; -\set VERBOSITY default CREATE TABLE t1 (a integer); @@ -1227,8 +1067,9 @@ INSERT INTO t1 (SELECT x, md5(x::text) FROM generate_series(0,20) x); SET SESSION AUTHORIZATION regress_rls_bob; -WITH cte1 AS (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; -EXPLAIN (COSTS OFF) WITH cte1 AS (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; +EXPLAIN (COSTS OFF) +WITH cte1 AS MATERIALIZED (SELECT * FROM t1 WHERE f_leak(b)) SELECT * FROM cte1; WITH cte1 AS (UPDATE t1 SET a = a + 1 RETURNING *) SELECT * FROM cte1; --fail WITH cte1 AS (UPDATE t1 SET a = a RETURNING *) SELECT * FROM cte1; --ok @@ -1923,14 +1764,77 @@ DROP POLICY p1 ON dob_t2; -- should succeed DROP USER regress_rls_dob_role1; DROP USER regress_rls_dob_role2; +-- Bug #15708: view + table with RLS should check policies as view owner +CREATE TABLE ref_tbl (a int); +INSERT INTO ref_tbl VALUES (1); + +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl VALUES (10); +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +CREATE POLICY p1 ON rls_tbl USING (EXISTS (SELECT 1 FROM ref_tbl)); + +GRANT SELECT ON ref_tbl TO regress_rls_bob; +GRANT SELECT ON rls_tbl TO regress_rls_bob; + +CREATE VIEW rls_view AS SELECT * FROM rls_tbl; +ALTER VIEW rls_view OWNER TO regress_rls_bob; +GRANT SELECT ON rls_view TO regress_rls_alice; + +SET SESSION AUTHORIZATION regress_rls_alice; +SELECT * FROM ref_tbl; -- Permission denied +SELECT * FROM rls_tbl; -- Permission denied +SELECT * FROM rls_view; -- OK +RESET SESSION AUTHORIZATION; + +DROP VIEW rls_view; +DROP TABLE rls_tbl; +DROP TABLE ref_tbl; + +-- Leaky operator test +CREATE TABLE rls_tbl (a int); +INSERT INTO rls_tbl SELECT x/10 FROM generate_series(1, 100) x; +ANALYZE rls_tbl; + +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +GRANT SELECT ON rls_tbl TO regress_rls_alice; + +SET SESSION AUTHORIZATION regress_rls_alice; +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel); +SELECT * FROM rls_tbl WHERE a <<< 1000; +DROP OPERATOR <<< (int, int); +DROP FUNCTION op_leak(int, int); +RESET SESSION AUTHORIZATION; +DROP TABLE rls_tbl; + +-- Bug #16006: whole-row Vars in a policy don't play nice with sub-selects +SET SESSION AUTHORIZATION regress_rls_alice; +CREATE TABLE rls_tbl (a int, b int, c int); +CREATE POLICY p1 ON rls_tbl USING (rls_tbl >= ROW(1,1,1)); + +ALTER TABLE rls_tbl ENABLE ROW LEVEL SECURITY; +ALTER TABLE rls_tbl FORCE ROW LEVEL SECURITY; + +INSERT INTO rls_tbl SELECT 10, 20, 30; +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rls_tbl + SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss; +INSERT INTO rls_tbl + SELECT * FROM (SELECT b, c FROM rls_tbl ORDER BY a) ss; +SELECT * FROM rls_tbl; + +DROP TABLE rls_tbl; +RESET SESSION AUTHORIZATION; + -- -- Clean up objects -- RESET SESSION AUTHORIZATION; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA regress_rls_schema CASCADE; -\set VERBOSITY default DROP USER regress_rls_alice; DROP USER regress_rls_bob; diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql index 305639f05db..7e080c034cd 100644 --- a/src/test/regress/sql/rowtypes.sql +++ b/src/test/regress/sql/rowtypes.sql @@ -119,6 +119,33 @@ select thousand, tenthous from tenk1 where (thousand, tenthous) >= (997, 5000) order by thousand, tenthous; +explain (costs off) +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + +select thousand, tenthous, four from tenk1 +where (thousand, tenthous, four) > (998, 5000, 3) +order by thousand, tenthous; + +explain (costs off) +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + +select thousand, tenthous from tenk1 +where (998, 5000) < (thousand, tenthous) +order by thousand, tenthous; + +explain (costs off) +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + +select thousand, hundred from tenk1 +where (998, 5000) < (thousand, hundred) +order by thousand, hundred; + -- Test case for bug #14010: indexed row comparisons fail with nulls create temp table test_table (a text, b text); insert into test_table values ('a', 'b'); @@ -259,6 +286,12 @@ select row(1, '(1,2)')::testtype6 *< row(1, '(1,3)')::testtype6; select row(1, '(1,2)')::testtype6 *>= row(1, '(1,3)')::testtype6; select row(1, '(1,2)')::testtype6 *<> row(1, '(1,3)')::testtype6; +-- anonymous rowtypes in coldeflists +select q.a, q.b = row(2), q.c = array[row(3)], q.d = row(row(4)) from + unnest(array[row(1, row(2), array[row(3)], row(row(4))), + row(2, row(3), array[row(4)], row(row(5)))]) + as q(a int, b record, c record[], d record); + drop type testtype1, testtype2, testtype3, testtype4, testtype5, testtype6; @@ -345,6 +378,26 @@ select (row('Jim', 'Beam'))::text; select text(row('Jim', 'Beam')); -- error select (row('Jim', 'Beam')).text; -- error +-- +-- Check the equivalence of functional and column notation +-- +insert into fullname values ('Joe', 'Blow'); + +select f.last from fullname f; +select last(f) from fullname f; + +create function longname(fullname) returns text language sql +as $$select $1.first || ' ' || $1.last$$; + +select f.longname from fullname f; +select longname(f) from fullname f; + +-- Starting in v11, the notational form does matter if there's ambiguity +alter table fullname add column longname text; + +select f.longname from fullname f; +select longname(f) from fullname f; + -- -- Test that composite values are seen to have the correct column names -- (bug #11210 and other reports) @@ -408,12 +461,12 @@ from (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) r(a,b); explain (verbose, costs off) -with r(a,b) as +with r(a,b) as materialized (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) select r, r is null as isnull, r is not null as isnotnull from r; -with r(a,b) as +with r(a,b) as materialized (values (1,row(1,2)), (1,row(null,null)), (1,null), (null,row(1,2)), (null,row(null,null)), (null,null) ) select r, r is null as isnull, r is not null as isnotnull from r; @@ -422,18 +475,18 @@ select r, r is null as isnull, r is not null as isnotnull from r; -- -- Tests for component access / FieldSelect -- -CREATE TABLE compositetable(a text, b text) WITH OIDS; +CREATE TABLE compositetable(a text, b text); INSERT INTO compositetable(a, b) VALUES('fa', 'fb'); -- composite type columns can't directly be accessed (error) SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s; -- but can be accessed with proper parens SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s; --- oids can't be accessed in composite types (error) -SELECT (d).oid FROM (SELECT compositetable AS d FROM compositetable) s; +-- system columns can't be accessed in composite types (error) +SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s; -- accessing non-existing column in NULL datum errors out -SELECT (NULL::compositetable).nonexistant; +SELECT (NULL::compositetable).nonexistent; -- existing column in a NULL composite yield NULL SELECT (NULL::compositetable).a; -- oids can't be accessed in composite types (error) diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql index b866268892f..a042e595469 100644 --- a/src/test/regress/sql/rules.sql +++ b/src/test/regress/sql/rules.sql @@ -775,10 +775,13 @@ drop table cchild; -- temporarily disable fancy output, so view changes create less diff noise \a\t -SELECT viewname, definition FROM pg_views WHERE schemaname <> 'information_schema' ORDER BY viewname; +SELECT viewname, definition FROM pg_views +WHERE schemaname IN ('pg_catalog', 'public') +ORDER BY viewname; SELECT tablename, rulename, definition FROM pg_rules - ORDER BY tablename, rulename; +WHERE schemaname IN ('pg_catalog', 'public') +ORDER BY tablename, rulename; -- restore normal output mode \a\t @@ -936,9 +939,7 @@ update id_ordered set name = 'update 4' where id = 4; update id_ordered set name = 'update 5' where id = 5; select * from id_ordered; -\set VERBOSITY terse \\ -- suppress cascade details drop table id cascade; -\set VERBOSITY default -- -- check corner case where an entirely-dummy subplan is created by @@ -1007,7 +1008,7 @@ create rule r3 as on delete to rules_src do notify rules_src_deletion; \d+ rules_src -- --- Ensure a aliased target relation for insert is correctly deparsed. +-- Ensure an aliased target relation for insert is correctly deparsed. -- create rule r4 as on insert to rules_src do instead insert into rules_log AS trgt SELECT NEW.* RETURNING trgt.f1, trgt.f2; create rule r5 as on update to rules_src do instead UPDATE rules_log AS trgt SET tag = 'updated' WHERE trgt.f1 = new.f1; @@ -1132,7 +1133,7 @@ SELECT tablename, rulename, definition FROM pg_rules explain (costs off) INSERT INTO hats VALUES ('h8', 'forbidden') RETURNING *; -- ensure upserting into a rule, with a CTE (different offsets!) works -WITH data(hat_name, hat_color) AS ( +WITH data(hat_name, hat_color) AS MATERIALIZED ( VALUES ('h8', 'green'), ('h9', 'blue'), ('h7', 'forbidden') @@ -1140,7 +1141,8 @@ WITH data(hat_name, hat_color) AS ( INSERT INTO hats SELECT * FROM data RETURNING *; -EXPLAIN (costs off) WITH data(hat_name, hat_color) AS ( +EXPLAIN (costs off) +WITH data(hat_name, hat_color) AS MATERIALIZED ( VALUES ('h8', 'green'), ('h9', 'blue'), ('h7', 'forbidden') @@ -1164,7 +1166,7 @@ CREATE FUNCTION func_with_set_params() RETURNS integer SET extra_float_digits TO 2 SET work_mem TO '4MB' SET datestyle to iso, mdy - SET local_preload_libraries TO "Mixed/Case", 'c:/"a"/path' + SET local_preload_libraries TO "Mixed/Case", 'c:/''a"/path', '', '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789' IMMUTABLE STRICT; SELECT pg_get_functiondef('func_with_set_params()'::regprocedure); @@ -1191,39 +1193,6 @@ CREATE RULE rules_parted_table_insert AS ON INSERT to rules_parted_table ALTER RULE rules_parted_table_insert ON rules_parted_table RENAME TO rules_parted_table_insert_redirect; DROP TABLE rules_parted_table; --- --- test MERGE --- -CREATE TABLE rule_merge1 (a int, b text); -CREATE TABLE rule_merge2 (a int, b text); -CREATE RULE rule1 AS ON INSERT TO rule_merge1 - DO INSTEAD INSERT INTO rule_merge2 VALUES (NEW.*); -CREATE RULE rule2 AS ON UPDATE TO rule_merge1 - DO INSTEAD UPDATE rule_merge2 SET a = NEW.a, b = NEW.b - WHERE a = OLD.a; -CREATE RULE rule3 AS ON DELETE TO rule_merge1 - DO INSTEAD DELETE FROM rule_merge2 WHERE a = OLD.a; - --- MERGE not supported for table with rules -MERGE INTO rule_merge1 t USING (SELECT 1 AS a) s - ON t.a = s.a - WHEN MATCHED AND t.a < 2 THEN - UPDATE SET b = b || ' updated by merge' - WHEN MATCHED AND t.a > 2 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.a, ''); - --- should be ok with the other table though -MERGE INTO rule_merge2 t USING (SELECT 1 AS a) s - ON t.a = s.a - WHEN MATCHED AND t.a < 2 THEN - UPDATE SET b = b || ' updated by merge' - WHEN MATCHED AND t.a > 2 THEN - DELETE - WHEN NOT MATCHED THEN - INSERT VALUES (s.a, ''); - -- -- Test enabling/disabling -- diff --git a/src/test/regress/sql/sanity_check.sql b/src/test/regress/sql/sanity_check.sql index 04aee457dda..a4ec00309ff 100644 --- a/src/test/regress/sql/sanity_check.sql +++ b/src/test/regress/sql/sanity_check.sql @@ -25,9 +25,15 @@ SELECT relname, relhasindex -- We exclude non-system tables from the check by looking at nspname. -- SELECT relname, nspname -FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace -WHERE relhasoids - AND ((nspname ~ '^pg_') IS NOT FALSE) - AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid - AND indkey[0] = -2 AND indnatts = 1 - AND indisunique AND indimmediate); + FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid') + WHERE relkind = 'r' and c.oid < 16384 + AND ((nspname ~ '^pg_') IS NOT FALSE) + AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid + AND indkey[0] = a.attnum AND indnatts = 1 + AND indisunique AND indimmediate); + +-- check that relations without storage don't have relfilenode +SELECT relname, relkind + FROM pg_class + WHERE relkind IN ('v', 'c', 'f', 'p', 'I') + AND relfilenode <> 0; diff --git a/src/test/regress/sql/select.sql b/src/test/regress/sql/select.sql index c80429e7d03..b5929b2eca6 100644 --- a/src/test/regress/sql/select.sql +++ b/src/test/regress/sql/select.sql @@ -116,9 +116,9 @@ SELECT p.name, p.age FROM person* p ORDER BY age using >, name; -- -- Test some cases involving whole-row Var referencing a subquery -- -select foo from (select 1) as foo; -select foo from (select null) as foo; -select foo from (select 'xyzzy',1,null) as foo; +select foo from (select 1 offset 0) as foo; +select foo from (select null offset 0) as foo; +select foo from (select 'xyzzy',1,null offset 0) as foo; -- -- Test VALUES lists @@ -254,3 +254,11 @@ drop function sillysrf(int); -- (see bug #5084) select * from (values (2),(null),(1)) v(k) where k = k order by k; select * from (values (2),(null),(1)) v(k) where k = k; + +-- Test partitioned tables with no partitions, which should be handled the +-- same as the non-inheritance case when expanding its RTE. +create table list_parted_tbl (a int,b int) partition by list (a); +create table list_parted_tbl1 partition of list_parted_tbl + for values in (1) partition by list(b); +explain (costs off) select * from list_parted_tbl; +drop table list_parted_tbl; diff --git a/src/test/regress/sql/select_into.sql b/src/test/regress/sql/select_into.sql index 62eddeed9d9..a708fef0ea0 100644 --- a/src/test/regress/sql/select_into.sql +++ b/src/test/regress/sql/select_into.sql @@ -85,15 +85,16 @@ SELECT make_table(); SELECT * FROM created_table; --- Try EXPLAIN ANALYZE SELECT INTO, but hide the output since it won't --- be stable. +-- Try EXPLAIN ANALYZE SELECT INTO and EXPLAIN ANALYZE CREATE TABLE AS +-- WITH NO DATA, but hide the outputs since they won't be stable. DO $$ BEGIN EXECUTE 'EXPLAIN ANALYZE SELECT * INTO TABLE easi FROM int8_tbl'; + EXECUTE 'EXPLAIN ANALYZE CREATE TABLE easi2 AS SELECT * FROM int8_tbl WITH NO DATA'; END$$; DROP TABLE created_table; -DROP TABLE easi; +DROP TABLE easi, easi2; -- -- Disallowed uses of SELECT ... INTO. All should fail diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index ac26d68053c..03c056b8b77 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -55,6 +55,15 @@ $$ select 'foo'::varchar union all select 'bar'::varchar $$ language sql stable; select sp_test_func() order by 1; +-- Parallel Append is not to be used when the subpath depends on the outer param +create table part_pa_test(a int, b int) partition by range(a); +create table part_pa_test_p1 partition of part_pa_test for values from (minvalue) to (0); +create table part_pa_test_p2 partition of part_pa_test for values from (0) to (maxvalue); +explain (costs off) + select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) + from part_pa_test pa2; +drop table part_pa_test; + -- test with leader participation disabled set parallel_leader_participation = off; explain (costs off) @@ -252,6 +261,13 @@ explain (costs off, verbose) drop function sp_simple_func(integer); +-- test handling of SRFs in targetlist (bug in 10.0) + +explain (costs off) + select count(*), generate_series(1,2) from tenk1 group by twenty; + +select count(*), generate_series(1,2) from tenk1 group by twenty; + -- test gather merge with parallel leader participation disabled set parallel_leader_participation = off; @@ -346,6 +362,17 @@ select count(*) from tenk1; reset force_parallel_mode; reset role; +-- Window function calculation can't be pushed to workers. +explain (costs off, verbose) + select count(*) from tenk1 a where (unique1, two) in + (select unique1, row_number() over() from tenk1 b); + + +-- LIMIT/OFFSET within sub-selects can't be pushed to workers. +explain (costs off) + select * from tenk1 a where two in + (select two from tenk1 b where stringu1 like '%AAAA' limit 3); + -- to increase the parallel query test coverage SAVEPOINT settings; SET LOCAL force_parallel_mode = 1; @@ -383,4 +410,26 @@ ORDER BY 1; SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3; +-- test passing expanded-value representations to workers +CREATE FUNCTION make_some_array(int,int) returns int[] as +$$declare x int[]; + begin + x[1] := $1; + x[2] := $2; + return x; + end$$ language plpgsql parallel safe; +CREATE TABLE fooarr(f1 text, f2 int[], f3 text); +INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one'); + +PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2; +EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)); +EXECUTE pstmt('1', make_some_array(1,2)); +DEALLOCATE pstmt; + +-- test interaction between subquery and partial_paths +CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1; +EXPLAIN (COSTS OFF) +SELECT 1 FROM tenk1_vw_sec + WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100; + rollback; diff --git a/src/test/regress/sql/spgist.sql b/src/test/regress/sql/spgist.sql index 77b43a2d3e9..c72cf42a33c 100644 --- a/src/test/regress/sql/spgist.sql +++ b/src/test/regress/sql/spgist.sql @@ -30,6 +30,21 @@ delete from spgist_point_tbl where id < 10000; vacuum spgist_point_tbl; +-- Test rescan paths (cf. bug #15378) +-- use box and && rather than point, so that rescan happens when the +-- traverse stack is non-empty + +create table spgist_box_tbl(id serial, b box); +insert into spgist_box_tbl(b) +select box(point(i,j),point(i+s,j+s)) + from generate_series(1,100,5) i, + generate_series(1,100,5) j, + generate_series(1,10) s; +create index spgist_box_idx on spgist_box_tbl using spgist (b); + +select count(*) + from (values (point(5,5)),(point(8,8)),(point(12,12))) v(p) + where exists(select * from spgist_box_tbl b where b.b && box(v.p,v.p)); -- The point opclass's choose method only uses the spgMatchNode action, -- so the other actions are not tested by the above. Create an index using diff --git a/src/test/regress/sql/stats.sql b/src/test/regress/sql/stats.sql index 2be7dde8346..feaaee6326e 100644 --- a/src/test/regress/sql/stats.sql +++ b/src/test/regress/sql/stats.sql @@ -79,9 +79,9 @@ $$ language plpgsql; -- test effects of TRUNCATE on n_live_tup/n_dead_tup counters CREATE TABLE trunc_stats_test(id serial); -CREATE TABLE trunc_stats_test1(id serial); +CREATE TABLE trunc_stats_test1(id serial, stuff text); CREATE TABLE trunc_stats_test2(id serial); -CREATE TABLE trunc_stats_test3(id serial); +CREATE TABLE trunc_stats_test3(id serial, stuff text); CREATE TABLE trunc_stats_test4(id serial); -- check that n_live_tup is reset to 0 after truncate diff --git a/src/test/regress/sql/stats_ext.sql b/src/test/regress/sql/stats_ext.sql index 46acaadb393..040ee97a1e5 100644 --- a/src/test/regress/sql/stats_ext.sql +++ b/src/test/regress/sql/stats_ext.sql @@ -3,15 +3,33 @@ -- We will be checking execution plans without/with statistics, so -- let's make sure we get simple non-parallel plans. Also set the -- work_mem low so that we can use small amounts of data. -SET max_parallel_workers = 0; -SET max_parallel_workers_per_gather = 0; -SET work_mem = '128kB'; + +-- check the number of estimated/actual rows in the top node +create function check_estimated_rows(text) returns table (estimated int, actual int) +language plpgsql as +$$ +declare + ln text; + tmp text[]; + first_row bool := true; +begin + for ln in + execute format('explain analyze %s', $1) + loop + if first_row then + first_row := false; + tmp := regexp_match(ln, 'rows=(\d*) .* rows=(\d*)'); + return query select tmp[1]::int, tmp[2]::int; + end if; + end loop; +end; +$$; -- Verify failures CREATE STATISTICS tst; CREATE STATISTICS tst ON a, b; CREATE STATISTICS tst FROM sometab; -CREATE STATISTICS tst ON a, b FROM nonexistant; +CREATE STATISTICS tst ON a, b FROM nonexistent; CREATE STATISTICS tst ON a, b FROM pg_class; CREATE STATISTICS tst ON relname, relname, relnatts FROM pg_class; CREATE STATISTICS tst ON relnatts + relpages FROM pg_class; @@ -50,10 +68,28 @@ INSERT INTO ab1 SELECT a, a%23 FROM generate_series(1, 1000) a; CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; ANALYZE ab1; ALTER TABLE ab1 ALTER a SET STATISTICS -1; +-- setting statistics target 0 skips the statistics, without printing any message, so check catalog +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; +ANALYZE ab1; +SELECT stxname, stxdndistinct, stxddependencies, stxdmcv + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'ab1_a_b_stats' + AND d.stxoid = s.oid; +ALTER STATISTICS ab1_a_b_stats SET STATISTICS -1; -- partial analyze doesn't build stats either ANALYZE ab1 (a); ANALYZE ab1; DROP TABLE ab1; +ALTER STATISTICS ab1_a_b_stats SET STATISTICS 0; +ALTER STATISTICS IF EXISTS ab1_a_b_stats SET STATISTICS 0; + +-- Ensure we can build statistics for tables with inheritance. +CREATE TABLE ab1 (a INTEGER, b INTEGER); +CREATE TABLE ab1c () INHERITS (ab1); +INSERT INTO ab1 VALUES (1,1); +CREATE STATISTICS ab1_a_b_stats ON a, b FROM ab1; +ANALYZE ab1; +DROP TABLE ab1 CASCADE; -- Verify supported object types for extended statistics CREATE schema tststats; @@ -89,10 +125,8 @@ EXCEPTION WHEN wrong_object_type THEN END; $$; -\set VERBOSITY terse \\ -- suppress cascade details DROP SCHEMA tststats CASCADE; DROP FOREIGN DATA WRAPPER extstats_dummy_fdw CASCADE; -\set VERBOSITY default -- n-distinct tests CREATE TABLE ndistinct ( @@ -108,51 +142,43 @@ CREATE TABLE ndistinct ( -- over-estimates when using only per-column statistics INSERT INTO ndistinct (a, b, c, filler1) SELECT i/100, i/100, i/100, cash_words((i/100)::money) - FROM generate_series(1,30000) s(i); + FROM generate_series(1,1000) s(i); ANALYZE ndistinct; -- Group Aggregate, due to over-estimate of the number of groups -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); -- correct command CREATE STATISTICS s10 ON a, b, c FROM ndistinct; ANALYZE ndistinct; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; -- Hash Aggregate, thanks to estimates improved by the statistic -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); -- last two plans keep using Group Aggregate, because 'd' is not covered -- by the statistic and while it's NULL-only we assume 200 values for it -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); TRUNCATE TABLE ndistinct; @@ -160,50 +186,43 @@ TRUNCATE TABLE ndistinct; INSERT INTO ndistinct (a, b, c, filler1) SELECT mod(i,50), mod(i,51), mod(i,32), cash_words(mod(i,33)::int::money) - FROM generate_series(1,10000) s(i); + FROM generate_series(1,5000) s(i); ANALYZE ndistinct; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; --- plans using Group Aggregate, thanks to using correct esimates -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; +-- correct esimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); DROP STATISTICS s10; -SELECT stxkind, stxndistinct - FROM pg_statistic_ext WHERE stxrelid = 'ndistinct'::regclass; +SELECT s.stxkind, d.stxdndistinct + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxrelid = 'ndistinct'::regclass + AND d.stxoid = s.oid; --- dropping the statistics switches the plans to Hash Aggregate, --- due to under-estimates -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b; +-- dropping the statistics results in under-estimates +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY b, c, d'); -EXPLAIN (COSTS off) - SELECT COUNT(*) FROM ndistinct GROUP BY a, d; +SELECT * FROM check_estimated_rows('SELECT COUNT(*) FROM ndistinct GROUP BY a, d'); -- functional dependencies tests CREATE TABLE functional_dependencies ( @@ -216,8 +235,6 @@ CREATE TABLE functional_dependencies ( d TEXT ); -SET random_page_cost = 1.2; - CREATE INDEX fdeps_ab_idx ON functional_dependencies (a, b); CREATE INDEX fdeps_abc_idx ON functional_dependencies (a, b, c); @@ -227,22 +244,18 @@ INSERT INTO functional_dependencies (a, b, c, filler1) ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); -- create statistics CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); -- a => b, a => c, b => c TRUNCATE functional_dependencies; @@ -253,32 +266,287 @@ INSERT INTO functional_dependencies (a, b, c, filler1) ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); -- create statistics CREATE STATISTICS func_deps_stat (dependencies) ON a, b, c FROM functional_dependencies; ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1'; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'''); -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); -- check change of column type doesn't break it ALTER TABLE functional_dependencies ALTER COLUMN c TYPE numeric; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); ANALYZE functional_dependencies; -EXPLAIN (COSTS OFF) - SELECT * FROM functional_dependencies WHERE a = 1 AND b = '1' AND c = 1; +SELECT * FROM check_estimated_rows('SELECT * FROM functional_dependencies WHERE a = 1 AND b = ''1'' AND c = 1'); + +-- MCV lists +CREATE TABLE mcv_lists ( + filler1 TEXT, + filler2 NUMERIC, + a INT, + b VARCHAR, + filler3 DATE, + c INT, + d TEXT +); + +-- random data (no MCV list) +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,37), mod(i,41), mod(i,43), mod(i,47) FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +-- 100 distinct combinations, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT mod(i,100), mod(i,50), mod(i,25), i FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 1 AND b < ''1'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 0 AND b <= ''0'''); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'' AND c = 1'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a < 5 AND b < ''1'' AND c < 5'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a <= 4 AND b <= ''0'' AND c <= 4'); + +-- check change of unrelated column type does not reset the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN d TYPE VARCHAR(64); + +SELECT d.stxdmcv IS NOT NULL + FROM pg_statistic_ext s, pg_statistic_ext_data d + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + +-- check change of column type resets the MCV statistics +ALTER TABLE mcv_lists ALTER COLUMN c TYPE numeric; -RESET random_page_cost; +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a = 1 AND b = ''1'''); + +-- 100 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, filler1) + SELECT + (CASE WHEN mod(i,100) = 1 THEN NULL ELSE mod(i,100) END), + (CASE WHEN mod(i,50) = 1 THEN NULL ELSE mod(i,50) END), + (CASE WHEN mod(i,25) = 1 THEN NULL ELSE mod(i,25) END), + i + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON a, b, c FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE a IS NULL AND b IS NULL AND c IS NULL'); + +-- test pg_mcv_list_items with a very simple (single item) MCV list +TRUNCATE mcv_lists; +INSERT INTO mcv_lists (a, b, c) SELECT 1, 2, 3 FROM generate_series(1,1000) s(i); +ANALYZE mcv_lists; + +SELECT m.* + FROM pg_statistic_ext s, pg_statistic_ext_data d, + pg_mcv_list_items(d.stxdmcv) m + WHERE s.stxname = 'mcv_lists_stats' + AND d.stxoid = s.oid; + +-- 2 distinct combinations with NULL values, all in the MCV list +TRUNCATE mcv_lists; +DROP STATISTICS mcv_lists_stats; + +INSERT INTO mcv_lists (a, b, c, d) + SELECT + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 0 END), + (CASE WHEN mod(i,2) = 0 THEN NULL ELSE 'x' END) + FROM generate_series(1,5000) s(i); + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + +-- create statistics +CREATE STATISTICS mcv_lists_stats (mcv) ON b, d FROM mcv_lists; + +ANALYZE mcv_lists; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists WHERE b = ''x'' OR d = ''x'''); + +-- mcv with arrays +CREATE TABLE mcv_lists_arrays ( + a TEXT[], + b NUMERIC[], + c INT[] +); + +INSERT INTO mcv_lists_arrays (a, b, c) + SELECT + ARRAY[md5((i/100)::text), md5((i/100-1)::text), md5((i/100+1)::text)], + ARRAY[(i/100-1)::numeric/1000, (i/100)::numeric/1000, (i/100+1)::numeric/1000], + ARRAY[(i/100-1), i/100, (i/100+1)] + FROM generate_series(1,5000) s(i); + +CREATE STATISTICS mcv_lists_arrays_stats (mcv) ON a, b, c + FROM mcv_lists_arrays; + +ANALYZE mcv_lists_arrays; + +-- mcv with bool +CREATE TABLE mcv_lists_bool ( + a BOOL, + b BOOL, + c BOOL +); + +INSERT INTO mcv_lists_bool (a, b, c) + SELECT + (mod(i,2) = 0), (mod(i,4) = 0), (mod(i,8) = 0) + FROM generate_series(1,10000) s(i); + +ANALYZE mcv_lists_bool; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + +CREATE STATISTICS mcv_lists_bool_stats (mcv) ON a, b, c + FROM mcv_lists_bool; + +ANALYZE mcv_lists_bool; + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND NOT b AND c'); + +SELECT * FROM check_estimated_rows('SELECT * FROM mcv_lists_bool WHERE NOT a AND b AND NOT c'); + +-- Permission tests. Users should not be able to see specific data values in +-- the extended statistics, if they lack permission to see those values in +-- the underlying table. +-- +-- Currently this is only relevant for MCV stats. +CREATE SCHEMA tststats; + +CREATE TABLE tststats.priv_test_tbl ( + a int, + b int +); + +INSERT INTO tststats.priv_test_tbl + SELECT mod(i,5), mod(i,10) FROM generate_series(1,100) s(i); + +CREATE STATISTICS tststats.priv_test_stats (mcv) ON a, b + FROM tststats.priv_test_tbl; + +ANALYZE tststats.priv_test_tbl; + +-- User with no access +CREATE USER regress_stats_user1; +GRANT USAGE ON SCHEMA tststats TO regress_stats_user1; +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_tbl; -- Permission denied + +-- Attempt to gain access using a leaky operator +CREATE FUNCTION op_leak(int, int) RETURNS bool + AS 'BEGIN RAISE NOTICE ''op_leak => %, %'', $1, $2; RETURN $1 < $2; END' + LANGUAGE plpgsql; +CREATE OPERATOR <<< (procedure = op_leak, leftarg = int, rightarg = int, + restrict = scalarltsel); +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Permission denied +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Permission denied + +-- Grant access via a security barrier view, but hide all data +RESET SESSION AUTHORIZATION; +CREATE VIEW tststats.priv_test_view WITH (security_barrier=true) + AS SELECT * FROM tststats.priv_test_tbl WHERE false; +GRANT SELECT, DELETE ON tststats.priv_test_view TO regress_stats_user1; + +-- Should now have access via the view, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; -- Should not leak +DELETE FROM tststats.priv_test_view WHERE a <<< 0 AND b <<< 0; -- Should not leak + +-- Grant table access, but hide all data with RLS +RESET SESSION AUTHORIZATION; +ALTER TABLE tststats.priv_test_tbl ENABLE ROW LEVEL SECURITY; +GRANT SELECT, DELETE ON tststats.priv_test_tbl TO regress_stats_user1; + +-- Should now have direct table access, but see nothing and leak nothing +SET SESSION AUTHORIZATION regress_stats_user1; +SELECT * FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak +DELETE FROM tststats.priv_test_tbl WHERE a <<< 0 AND b <<< 0; -- Should not leak + +-- Tidy up +DROP OPERATOR <<< (int, int); +DROP FUNCTION op_leak(int, int); +RESET SESSION AUTHORIZATION; +DROP SCHEMA tststats CASCADE; +DROP USER regress_stats_user1; diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 5a82237870e..b5e75c344f2 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -110,25 +110,54 @@ SELECT SUBSTRING('1234567890' FROM 3) = '34567890' AS "34567890"; SELECT SUBSTRING('1234567890' FROM 4 FOR 3) = '456' AS "456"; --- T581 regular expression substring (with SQL99's bizarre regexp syntax) +-- T581 regular expression substring (with SQL's bizarre regexp syntax) SELECT SUBSTRING('abcdefg' FROM 'a#"(b_d)#"%' FOR '#') AS "bcd"; -- No match should return NULL SELECT SUBSTRING('abcdefg' FROM '#"(b_d)#"%' FOR '#') IS NULL AS "True"; -- Null inputs should return NULL -SELECT SUBSTRING('abcdefg' FROM '(b|c)' FOR NULL) IS NULL AS "True"; -SELECT SUBSTRING(NULL FROM '(b|c)' FOR '#') IS NULL AS "True"; +SELECT SUBSTRING('abcdefg' FROM '%' FOR NULL) IS NULL AS "True"; +SELECT SUBSTRING(NULL FROM '%' FOR '#') IS NULL AS "True"; SELECT SUBSTRING('abcdefg' FROM NULL FOR '#') IS NULL AS "True"; --- PostgreSQL extension to allow omitting the escape character; --- here the regexp is taken as Posix syntax +-- The first and last parts should act non-greedy +SELECT SUBSTRING('abcdefg' FROM 'a#"%#"g' FOR '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' FROM 'a*#"%#"g*' FOR '#') AS "abcdefg"; + +-- Vertical bar in any part affects only that part +SELECT SUBSTRING('abcdefg' FROM 'a|b#"%#"g' FOR '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' FROM 'a#"%#"x|g' FOR '#') AS "bcdef"; +SELECT SUBSTRING('abcdefg' FROM 'a#"%|ab#"g' FOR '#') AS "bcdef"; + +-- Can't have more than two part separators +SELECT SUBSTRING('abcdefg' FROM 'a*#"%#"g*#"x' FOR '#') AS "error"; + +-- Postgres extension: with 0 or 1 separator, assume parts 1 and 3 are empty +SELECT SUBSTRING('abcdefg' FROM 'a#"%g' FOR '#') AS "bcdefg"; +SELECT SUBSTRING('abcdefg' FROM 'a%g' FOR '#') AS "abcdefg"; + +-- substring() with just two arguments is not allowed by SQL spec; +-- we accept it, but we interpret the pattern as a POSIX regexp not SQL SELECT SUBSTRING('abcdefg' FROM 'c.e') AS "cde"; -- With a parenthesized subexpression, return only what matches the subexpr SELECT SUBSTRING('abcdefg' FROM 'b(.*)f') AS "cde"; --- PostgreSQL extension to allow using back reference in replace string; +-- Check behavior of SIMILAR TO, which uses largely the same regexp variant +SELECT 'abcdefg' SIMILAR TO '_bcd%' AS true; +SELECT 'abcdefg' SIMILAR TO 'bcd%' AS false; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '#' AS false; +SELECT 'abcd%' SIMILAR TO '_bcd#%' ESCAPE '#' AS true; +-- Postgres uses '\' as the default escape character, which is not per spec +SELECT 'abcdefg' SIMILAR TO '_bcd\%' AS false; +-- and an empty string to mean "no escape", which is also not per spec +SELECT 'abcd\efg' SIMILAR TO '_bcd\%' ESCAPE '' AS true; +-- these behaviors are per spec, though: +SELECT 'abcdefg' SIMILAR TO '_bcd%' ESCAPE NULL AS null; +SELECT 'abcdefg' SIMILAR TO '_bcd#%' ESCAPE '##' AS error; + +-- Test back reference in regexp_replace SELECT regexp_replace('1112223333', E'(\\d{3})(\\d{3})(\\d{4})', E'(\\1) \\2-\\3'); SELECT regexp_replace('AAA BBB CCC ', E'\\s+', ' ', 'g'); SELECT regexp_replace('AAA', '^|$', 'Z', 'g'); @@ -188,6 +217,9 @@ SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', 'nom SELECT regexp_split_to_array('123456','1'); SELECT regexp_split_to_array('123456','6'); SELECT regexp_split_to_array('123456','.'); +SELECT regexp_split_to_array('123456',''); +SELECT regexp_split_to_array('123456','(?:)'); +SELECT regexp_split_to_array('1',''); -- errors SELECT foo, length(foo) FROM regexp_split_to_table('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'zippy') AS foo; SELECT regexp_split_to_array('thE QUick bROWn FOx jUMPs ovEr The lazy dOG', 'e', 'iz'); @@ -320,6 +352,19 @@ SELECT 'foo' LIKE '%__' as t, 'foo' LIKE '%___' as t, 'foo' LIKE '%____' as f; SELECT 'jack' LIKE '%____%' AS t; +-- +-- basic tests of LIKE with indexes +-- + +CREATE TABLE texttest (a text PRIMARY KEY, b int); +SELECT * FROM texttest WHERE a LIKE '%1%'; + +CREATE TABLE byteatest (a bytea PRIMARY KEY, b int); +SELECT * FROM byteatest WHERE a LIKE '%1%'; + +DROP TABLE texttest, byteatest; + + -- -- test implicit type conversion -- @@ -372,7 +417,8 @@ INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); -- expect >0 blocks -select 0 = pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks; +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; TRUNCATE TABLE toasttest; ALTER TABLE toasttest set (toast_tuple_target = 4080); @@ -381,7 +427,8 @@ INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); INSERT INTO toasttest values (repeat('1234567890',300)); -- expect 0 blocks -select 0 = pg_relation_size('pg_toast.pg_toast_'||(select oid from pg_class where relname = 'toasttest'))/current_setting('block_size')::integer as blocks; +SELECT pg_relation_size(reltoastrelid) = 0 AS is_empty + FROM pg_class where relname = 'toasttest'; DROP TABLE toasttest; diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index 36fa1bbac80..9e234ab8b3f 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -8,75 +8,75 @@ CREATE ROLE regress_subscription_user_dummy LOGIN NOSUPERUSER; SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - no publications -CREATE SUBSCRIPTION testsub CONNECTION 'foo'; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'foo'; -- fail - no connection -CREATE SUBSCRIPTION testsub PUBLICATION foo; +CREATE SUBSCRIPTION regress_testsub PUBLICATION foo; -- fail - cannot do CREATE SUBSCRIPTION CREATE SLOT inside transaction block BEGIN; -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub WITH (create_slot); COMMIT; -- fail - invalid connection string -CREATE SUBSCRIPTION testsub CONNECTION 'testconn' PUBLICATION testpub; +CREATE SUBSCRIPTION regress_testsub CONNECTION 'testconn' PUBLICATION testpub; -- fail - duplicate publications -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo, testpub, foo WITH (connect = false); -- ok -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); -COMMENT ON SUBSCRIPTION testsub IS 'test subscription'; +COMMENT ON SUBSCRIPTION regress_testsub IS 'test subscription'; SELECT obj_description(s.oid, 'pg_subscription') FROM pg_subscription s; -- fail - name already exists -CREATE SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false); -- fail - must be superuser SET SESSION AUTHORIZATION 'regress_subscription_user2'; -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION foo WITH (connect = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION foo WITH (connect = false); SET SESSION AUTHORIZATION 'regress_subscription_user'; -- fail - invalid option combinations -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); -CREATE SUBSCRIPTION testsub2 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, copy_data = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (connect = false, create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = true); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, enabled = false); +CREATE SUBSCRIPTION regress_testsub2 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, create_slot = false); -- ok - with slot_name = NONE -CREATE SUBSCRIPTION testsub3 CONNECTION 'dbname=doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); +CREATE SUBSCRIPTION regress_testsub3 CONNECTION 'dbname=regress_doesnotexist' PUBLICATION testpub WITH (slot_name = NONE, connect = false); -- fail -ALTER SUBSCRIPTION testsub3 ENABLE; -ALTER SUBSCRIPTION testsub3 REFRESH PUBLICATION; +ALTER SUBSCRIPTION regress_testsub3 ENABLE; +ALTER SUBSCRIPTION regress_testsub3 REFRESH PUBLICATION; -DROP SUBSCRIPTION testsub3; +DROP SUBSCRIPTION regress_testsub3; -- fail - invalid connection string -ALTER SUBSCRIPTION testsub CONNECTION 'foobar'; +ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; \dRs+ -ALTER SUBSCRIPTION testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); -ALTER SUBSCRIPTION testsub CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (slot_name = 'newname'); +ALTER SUBSCRIPTION regress_testsub SET PUBLICATION testpub2, testpub3 WITH (refresh = false); +ALTER SUBSCRIPTION regress_testsub CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (slot_name = 'newname'); -- fail -ALTER SUBSCRIPTION doesnotexist CONNECTION 'dbname=doesnotexist2'; -ALTER SUBSCRIPTION testsub SET (create_slot = false); +ALTER SUBSCRIPTION regress_doesnotexist CONNECTION 'dbname=regress_doesnotexist2'; +ALTER SUBSCRIPTION regress_testsub SET (create_slot = false); \dRs+ BEGIN; -ALTER SUBSCRIPTION testsub ENABLE; +ALTER SUBSCRIPTION regress_testsub ENABLE; \dRs -ALTER SUBSCRIPTION testsub DISABLE; +ALTER SUBSCRIPTION regress_testsub DISABLE; \dRs @@ -84,38 +84,38 @@ COMMIT; -- fail - must be owner of subscription SET ROLE regress_subscription_user_dummy; -ALTER SUBSCRIPTION testsub RENAME TO testsub_dummy; +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_dummy; RESET ROLE; -ALTER SUBSCRIPTION testsub RENAME TO testsub_foo; -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = local); -ALTER SUBSCRIPTION testsub_foo SET (synchronous_commit = foobar); +ALTER SUBSCRIPTION regress_testsub RENAME TO regress_testsub_foo; +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = local); +ALTER SUBSCRIPTION regress_testsub_foo SET (synchronous_commit = foobar); \dRs+ -- rename back to keep the rest simple -ALTER SUBSCRIPTION testsub_foo RENAME TO testsub; +ALTER SUBSCRIPTION regress_testsub_foo RENAME TO regress_testsub; -- fail - new owner must be superuser -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; ALTER ROLE regress_subscription_user2 SUPERUSER; -- now it works -ALTER SUBSCRIPTION testsub OWNER TO regress_subscription_user2; +ALTER SUBSCRIPTION regress_testsub OWNER TO regress_subscription_user2; -- fail - cannot do DROP SUBSCRIPTION inside transaction block with slot name BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -ALTER SUBSCRIPTION testsub SET (slot_name = NONE); +ALTER SUBSCRIPTION regress_testsub SET (slot_name = NONE); -- now it works BEGIN; -DROP SUBSCRIPTION testsub; +DROP SUBSCRIPTION regress_testsub; COMMIT; -DROP SUBSCRIPTION IF EXISTS testsub; -DROP SUBSCRIPTION testsub; -- fail +DROP SUBSCRIPTION IF EXISTS regress_testsub; +DROP SUBSCRIPTION regress_testsub; -- fail RESET SESSION AUTHORIZATION; DROP ROLE regress_subscription_user; diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql index 9b7125c111c..20c4f99c9c4 100644 --- a/src/test/regress/sql/subselect.sql +++ b/src/test/regress/sql/subselect.sql @@ -435,6 +435,33 @@ insert into inner_7597 values(0, null); select * from outer_7597 where (f1, f2) not in (select * from inner_7597); +-- +-- Similar test case using text that verifies that collation +-- information is passed through by execTuplesEqual() in nodeSubplan.c +-- (otherwise it would error in texteq()) +-- + +create temp table outer_text (f1 text, f2 text); +insert into outer_text values ('a', 'a'); +insert into outer_text values ('b', 'a'); +insert into outer_text values ('a', null); +insert into outer_text values ('b', null); + +create temp table inner_text (c1 text, c2 text); +insert into inner_text values ('a', null); + +select * from outer_text where (f1, f2) not in (select * from inner_text); + +-- +-- Another test case for cross-type hashed subplans: comparison of +-- inner-side values must be done with appropriate operator +-- + +explain (verbose, costs off) +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + +select 'foo'::text in (select 'bar'::name union all select 'bar'::name); + -- -- Test case for premature memory release during hashing of subplan output -- @@ -466,6 +493,15 @@ explain (verbose, costs off) select x, x from (select (select random() where y=y) as x from (values(1),(2)) v(y)) ss; +-- +-- Check we don't misoptimize a NOT IN where the subquery returns no rows. +-- +create temp table notinouter (a int); +create temp table notininner (b int not null); +insert into notinouter values (null), (1); + +select * from notinouter where a not in (select b from notininner); + -- -- Check we behave sanely in corner case of empty SELECT list (bug #8648) -- @@ -498,9 +534,9 @@ select * from int4_tbl where -- explain (verbose, costs off) select * from int4_tbl o where (f1, f1) in - (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); select * from int4_tbl o where (f1, f1) in - (select f1, generate_series(1,2) / 10 g from int4_tbl i group by f1); + (select f1, generate_series(1,50) / 10 g from int4_tbl i group by f1); -- -- check for over-optimization of whole-row Var referencing an Append plan @@ -609,3 +645,112 @@ select * from (select pk,c2 from sq_limit order by c1,pk) as x limit 3; drop function explain_sq_limit(); drop table sq_limit; + +-- +-- Ensure that backward scan direction isn't propagated into +-- expression subqueries (bug #15336) +-- + +begin; + +declare c1 scroll cursor for + select * from generate_series(1,4) i + where i <> all (values (2),(3)); + +move forward all in c1; +fetch backward all in c1; + +commit; + +-- +-- Tests for CTE inlining behavior +-- + +-- Basic subquery that can be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1; + +-- Explicitly request materialization +explain (verbose, costs off) +with x as materialized (select * from (select f1 from subselect_tbl) ss) +select * from x where f1 = 1; + +-- Stable functions are safe to inline +explain (verbose, costs off) +with x as (select * from (select f1, now() from subselect_tbl) ss) +select * from x where f1 = 1; + +-- Volatile functions prevent inlining +explain (verbose, costs off) +with x as (select * from (select f1, random() from subselect_tbl) ss) +select * from x where f1 = 1; + +-- SELECT FOR UPDATE cannot be inlined +explain (verbose, costs off) +with x as (select * from (select f1 from subselect_tbl for update) ss) +select * from x where f1 = 1; + +-- Multiply-referenced CTEs are inlined only when requested +explain (verbose, costs off) +with x as (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n; + +explain (verbose, costs off) +with x as not materialized (select * from (select f1, now() as n from subselect_tbl) ss) +select * from x, x x2 where x.n = x2.n; + +-- Multiply-referenced CTEs can't be inlined if they contain outer self-refs +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x; + +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z1.a as a from z cross join z as z1 + where length(z.a || z1.a) < 5)) +select * from x; + +explain (verbose, costs off) +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x; + +with recursive x(a) as + ((values ('a'), ('b')) + union all + (with z as not materialized (select * from x) + select z.a || z.a as a from z + where length(z.a || z.a) < 5)) +select * from x; + +-- Check handling of outer references +explain (verbose, costs off) +with x as (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss; + +explain (verbose, costs off) +with x as materialized (select * from int4_tbl) +select * from (with y as (select * from x) select * from y) ss; + +-- Ensure that we inline the currect CTE when there are +-- multiple CTEs with the same name +explain (verbose, costs off) +with x as (select 1 as y) +select * from (with x as (select 2 as y) select * from x) ss; + +-- Row marks are not pushed into CTEs +explain (verbose, costs off) +with x as (select * from subselect_tbl) +select * from x for update; diff --git a/src/test/regress/sql/temp.sql b/src/test/regress/sql/temp.sql index 5183c727f5e..b636b33dcac 100644 --- a/src/test/regress/sql/temp.sql +++ b/src/test/regress/sql/temp.sql @@ -151,3 +151,144 @@ select whoami(); select pg_temp.whoami(); drop table public.whereami; + +-- types in temp schema +set search_path = pg_temp, public; +create domain pg_temp.nonempty as text check (value <> ''); +-- function-syntax invocation of types matches rules for functions +select nonempty(''); +select pg_temp.nonempty(''); +-- other syntax matches rules for tables +select ''::nonempty; + +reset search_path; + +-- For partitioned temp tables, ON COMMIT actions ignore storage-less +-- partitioned tables. +begin; +create temp table temp_parted_oncommit (a int) + partition by list (a) on commit delete rows; +create temp table temp_parted_oncommit_1 + partition of temp_parted_oncommit + for values in (1) on commit delete rows; +insert into temp_parted_oncommit values (1); +commit; +-- partitions are emptied by the previous commit +select * from temp_parted_oncommit; +drop table temp_parted_oncommit; + +-- Check dependencies between ON COMMIT actions with a partitioned +-- table and its partitions. Using ON COMMIT DROP on a parent removes +-- the whole set. +begin; +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit drop; +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit delete rows; +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; +insert into temp_parted_oncommit_test values (1), (2); +commit; +-- no relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test'; +-- Using ON COMMIT DELETE on a partitioned table does not remove +-- all rows if partitions preserve their data. +begin; +create temp table temp_parted_oncommit_test (a int) + partition by list (a) on commit delete rows; +create temp table temp_parted_oncommit_test1 + partition of temp_parted_oncommit_test + for values in (1) on commit preserve rows; +create temp table temp_parted_oncommit_test2 + partition of temp_parted_oncommit_test + for values in (2) on commit drop; +insert into temp_parted_oncommit_test values (1), (2); +commit; +-- Data from the remaining partition is still here as its rows are +-- preserved. +select * from temp_parted_oncommit_test; +-- two relations remain in this case. +select relname from pg_class where relname ~ '^temp_parted_oncommit_test' + order by relname; +drop table temp_parted_oncommit_test; + +-- Check dependencies between ON COMMIT actions with inheritance trees. +-- Using ON COMMIT DROP on a parent removes the whole set. +begin; +create temp table temp_inh_oncommit_test (a int) on commit drop; +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit delete rows; +insert into temp_inh_oncommit_test1 values (1); +commit; +-- no relations remain in this case +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; +-- Data on the parent is removed, and the child goes away. +begin; +create temp table temp_inh_oncommit_test (a int) on commit delete rows; +create temp table temp_inh_oncommit_test1 () + inherits(temp_inh_oncommit_test) on commit drop; +insert into temp_inh_oncommit_test1 values (1); +insert into temp_inh_oncommit_test values (1); +commit; +select * from temp_inh_oncommit_test; +-- one relation remains +select relname from pg_class where relname ~ '^temp_inh_oncommit_test'; +drop table temp_inh_oncommit_test; + +-- Tests with two-phase commit +-- Transactions creating objects in a temporary namespace cannot be used +-- with two-phase commit. + +-- These cases generate errors about temporary namespace. +-- Function creation +begin; +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; +prepare transaction 'twophase_func'; +-- Function drop +create function pg_temp.twophase_func() returns void as + $$ select '2pc_func'::text $$ language sql; +begin; +drop function pg_temp.twophase_func(); +prepare transaction 'twophase_func'; +-- Operator creation +begin; +create operator pg_temp.@@ (leftarg = int4, rightarg = int4, procedure = int4mi); +prepare transaction 'twophase_operator'; + +-- These generate errors about temporary tables. +begin; +create type pg_temp.twophase_type as (a int); +prepare transaction 'twophase_type'; +begin; +create view pg_temp.twophase_view as select 1; +prepare transaction 'twophase_view'; +begin; +create sequence pg_temp.twophase_seq; +prepare transaction 'twophase_sequence'; + +-- Temporary tables cannot be used with two-phase commit. +create temp table twophase_tab (a int); +begin; +select a from twophase_tab; +prepare transaction 'twophase_tab'; +begin; +insert into twophase_tab values (1); +prepare transaction 'twophase_tab'; +begin; +lock twophase_tab in access exclusive mode; +prepare transaction 'twophase_tab'; +begin; +drop table twophase_tab; +prepare transaction 'twophase_tab'; + +-- Corner case: current_schema may create a temporary schema if namespace +-- creation is pending, so check after that. First reset the connection +-- to remove the temporary namespace. +\c - +SET search_path TO 'pg_temp'; +BEGIN; +SELECT current_schema() ~ 'pg_temp' AS is_temp_schema; +PREPARE TRANSACTION 'twophase_search'; diff --git a/src/test/regress/sql/tidscan.sql b/src/test/regress/sql/tidscan.sql index a8472e09acd..ef05c098420 100644 --- a/src/test/regress/sql/tidscan.sql +++ b/src/test/regress/sql/tidscan.sql @@ -17,6 +17,11 @@ EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; SELECT ctid, * FROM tidscan WHERE '(0,1)' = ctid; +-- OR'd clauses +EXPLAIN (COSTS OFF) +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; +SELECT ctid, * FROM tidscan WHERE ctid = '(0,2)' OR '(0,1)' = ctid; + -- ctid = ScalarArrayOp - implemented as tidscan EXPLAIN (COSTS OFF) SELECT ctid, * FROM tidscan WHERE ctid = ANY(ARRAY['(0,1)', '(0,2)']::tid[]); @@ -34,6 +39,20 @@ WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); SELECT ctid, * FROM tidscan WHERE (id = 3 AND ctid IN ('(0,2)', '(0,3)')) OR (ctid = '(0,1)' AND id = 1); +-- nestloop-with-inner-tidscan joins on tid +SET enable_hashjoin TO off; -- otherwise hash join might win +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; +EXPLAIN (COSTS OFF) +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; +SELECT t1.ctid, t1.*, t2.ctid, t2.* +FROM tidscan t1 LEFT JOIN tidscan t2 ON t1.ctid = t2.ctid WHERE t1.id = 1; +RESET enable_hashjoin; + -- exercise backward scan and rewind BEGIN; DECLARE c CURSOR FOR @@ -63,4 +82,16 @@ EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) UPDATE tidscan SET id = -id WHERE CURRENT OF c RETURNING *; ROLLBACK; +-- bulk joins on CTID +-- (these plans don't use TID scans, but this still seems like an +-- appropriate place for these tests) +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SET enable_hashjoin TO off; +EXPLAIN (COSTS OFF) +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +SELECT count(*) FROM tenk1 t1 JOIN tenk1 t2 ON t1.ctid = t2.ctid; +RESET enable_hashjoin; + DROP TABLE tidscan; diff --git a/src/test/regress/sql/timestamp.sql b/src/test/regress/sql/timestamp.sql index b7957cbb9aa..329987f7eaa 100644 --- a/src/test/regress/sql/timestamp.sql +++ b/src/test/regress/sql/timestamp.sql @@ -44,16 +44,12 @@ SELECT pg_sleep(0.1); SELECT count(*) AS two FROM TIMESTAMP_TBL WHERE d1 = timestamp(2) without time zone 'now'; COMMIT; -DELETE FROM TIMESTAMP_TBL; +TRUNCATE TIMESTAMP_TBL; -- Special values INSERT INTO TIMESTAMP_TBL VALUES ('-infinity'); INSERT INTO TIMESTAMP_TBL VALUES ('infinity'); INSERT INTO TIMESTAMP_TBL VALUES ('epoch'); --- Obsolete special values -INSERT INTO TIMESTAMP_TBL VALUES ('invalid'); -INSERT INTO TIMESTAMP_TBL VALUES ('undefined'); -INSERT INTO TIMESTAMP_TBL VALUES ('current'); -- Postgres v6.0 standard output format INSERT INTO TIMESTAMP_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); @@ -228,5 +224,13 @@ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID') SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') FROM TIMESTAMP_TBL; +SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamp), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + -- timestamp numeric fields constructor SELECT make_timestamp(2014,12,28,6,30,45.887); diff --git a/src/test/regress/sql/timestamptz.sql b/src/test/regress/sql/timestamptz.sql index f17d153fccb..f5fee639a01 100644 --- a/src/test/regress/sql/timestamptz.sql +++ b/src/test/regress/sql/timestamptz.sql @@ -49,10 +49,6 @@ DELETE FROM TIMESTAMPTZ_TBL; INSERT INTO TIMESTAMPTZ_TBL VALUES ('-infinity'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('infinity'); INSERT INTO TIMESTAMPTZ_TBL VALUES ('epoch'); --- Obsolete special values -INSERT INTO TIMESTAMPTZ_TBL VALUES ('invalid'); -INSERT INTO TIMESTAMPTZ_TBL VALUES ('undefined'); -INSERT INTO TIMESTAMPTZ_TBL VALUES ('current'); -- Postgres v6.0 standard output format INSERT INTO TIMESTAMPTZ_TBL VALUES ('Mon Feb 10 17:32:01 1997 PST'); @@ -193,6 +189,10 @@ SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff SELECT '' AS date_trunc_week, date_trunc( 'week', timestamp with time zone '2004-02-29 15:44:17.71393' ) AS week_trunc; +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'Australia/Sydney') as sydney_trunc; -- zone name +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'GMT') as gmt_trunc; -- fixed-offset abbreviation +SELECT '' AS date_trunc_at_tz, date_trunc('day', timestamp with time zone '2001-02-16 20:38:40+00', 'VET') as vet_trunc; -- variable-offset abbreviation + -- Test casting within a BETWEEN qualifier SELECT '' AS "54", d1 - timestamp with time zone '1997-01-02' AS diff FROM TIMESTAMPTZ_TBL @@ -248,6 +248,14 @@ SELECT '' AS to_char_10, to_char(d1, 'IYYY IYY IY I IW IDDD ID') SELECT '' AS to_char_11, to_char(d1, 'FMIYYY FMIYY FMIY FMI FMIW FMIDDD FMID') FROM TIMESTAMPTZ_TBL; +SELECT '' AS to_char_12, to_char(d, 'FF1 FF2 FF3 FF4 FF5 FF6 ff1 ff2 ff3 ff4 ff5 ff6 MS US') + FROM (VALUES + ('2018-11-02 12:34:56'::timestamptz), + ('2018-11-02 12:34:56.78'), + ('2018-11-02 12:34:56.78901'), + ('2018-11-02 12:34:56.78901234') + ) d(d); + -- Check OF, TZH, TZM with various zone offsets, particularly fractional hours SET timezone = '00:00'; SELECT to_char(now(), 'OF') as "OF", to_char(now(), 'TZH:TZM') as "TZH:TZM"; diff --git a/src/test/regress/sql/timetz.sql b/src/test/regress/sql/timetz.sql index c41686a5e2f..2ad4948e850 100644 --- a/src/test/regress/sql/timetz.sql +++ b/src/test/regress/sql/timetz.sql @@ -19,6 +19,11 @@ INSERT INTO TIMETZ_TBL VALUES ('2003-03-07 15:36:39 America/New_York'); INSERT INTO TIMETZ_TBL VALUES ('2003-07-07 15:36:39 America/New_York'); -- this should fail (the timezone offset is not known) INSERT INTO TIMETZ_TBL VALUES ('15:36:39 America/New_York'); +-- this should fail (timezone not specified without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 m2'); +-- this should fail (dynamic timezone abbreviation without a date) +INSERT INTO TIMETZ_TBL VALUES ('15:36:39 MSK m2'); + SELECT f1 AS "Time TZ" FROM TIMETZ_TBL; diff --git a/src/test/regress/sql/tinterval.sql b/src/test/regress/sql/tinterval.sql deleted file mode 100644 index 42399ce694a..00000000000 --- a/src/test/regress/sql/tinterval.sql +++ /dev/null @@ -1,97 +0,0 @@ --- --- TINTERVAL --- - -CREATE TABLE TINTERVAL_TBL (f1 tinterval); - --- Should accept any abstime, --- so do not bother with extensive testing of values - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["-infinity" "infinity"]'); - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["May 10, 1947 23:59:12" "Jan 14, 1973 03:14:21"]'); - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["Sep 4, 1983 23:59:12" "Oct 4, 1983 23:59:12"]'); - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["epoch" "Mon May 1 00:30:30 1995"]'); - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["Feb 15 1990 12:15:03" "2001-09-23 11:12:13"]'); - - --- badly formatted tintervals -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["bad time specifications" ""]'); - -INSERT INTO TINTERVAL_TBL (f1) - VALUES ('["" "infinity"]'); - --- test tinterval operators - -SELECT '' AS five, * FROM TINTERVAL_TBL; - --- length == -SELECT '' AS one, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #= '@ 1 months'; - --- length <> -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #<> '@ 1 months'; - --- length < -SELECT '' AS zero, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #< '@ 1 month'; - --- length <= -SELECT '' AS one, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #<= '@ 1 month'; - --- length > -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #> '@ 1 year'; - --- length >= -SELECT '' AS three, t.* - FROM TINTERVAL_TBL t - WHERE t.f1 #>= '@ 3 years'; - --- overlaps -SELECT '' AS three, t1.* - FROM TINTERVAL_TBL t1 - WHERE t1.f1 && - tinterval '["Aug 15 14:23:19 1983" "Sep 16 14:23:19 1983"]'; - -SELECT '' AS five, t1.f1, t2.f1 - FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2 - WHERE t1.f1 && t2.f1 and - t1.f1 = t2.f1 - ORDER BY t1.f1, t2.f1; - -SELECT '' AS fourteen, t1.f1 AS interval1, t2.f1 AS interval2 - FROM TINTERVAL_TBL t1, TINTERVAL_TBL t2 - WHERE t1.f1 && t2.f1 and not t1.f1 = t2.f1 - ORDER BY interval1, interval2; - --- contains -SELECT '' AS five, t1.f1 - FROM TINTERVAL_TBL t1 - WHERE not t1.f1 << - tinterval '["Aug 15 14:23:19 1980" "Sep 16 14:23:19 1990"]' - ORDER BY t1.f1; - --- make time interval -SELECT '' AS three, t1.f1 - FROM TINTERVAL_TBL t1 - WHERE t1.f1 && - (abstime 'Aug 15 14:23:19 1983' <#> - abstime 'Sep 16 14:23:19 1983') - ORDER BY t1.f1; diff --git a/src/test/regress/sql/transactions.sql b/src/test/regress/sql/transactions.sql index 2e3739fd6c4..bf1016489d1 100644 --- a/src/test/regress/sql/transactions.sql +++ b/src/test/regress/sql/transactions.sql @@ -419,6 +419,73 @@ DROP FUNCTION create_temp_tab(); DROP FUNCTION invert(x float8); +-- Tests for AND CHAIN + +CREATE TABLE abc (a int); + +-- set nondefault value so we have something to override below +SET default_transaction_read_only = on; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES (1); +INSERT INTO abc VALUES (2); +COMMIT AND CHAIN; -- TBLOCK_END +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES ('error'); +INSERT INTO abc VALUES (3); -- check it's really aborted +COMMIT AND CHAIN; -- TBLOCK_ABORT_END +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES (4); +COMMIT; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ WRITE, DEFERRABLE; +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +SAVEPOINT x; +INSERT INTO abc VALUES ('error'); +COMMIT AND CHAIN; -- TBLOCK_ABORT_PENDING +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES (5); +COMMIT; + +-- different mix of options just for fun +START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE, NOT DEFERRABLE; +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES (6); +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_PENDING +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +INSERT INTO abc VALUES ('error'); +ROLLBACK AND CHAIN; -- TBLOCK_ABORT_END +SHOW transaction_isolation; +SHOW transaction_read_only; +SHOW transaction_deferrable; +ROLLBACK; + +-- not allowed outside a transaction block +COMMIT AND CHAIN; -- error +ROLLBACK AND CHAIN; -- error + +SELECT * FROM abc ORDER BY 1; + +RESET default_transaction_read_only; + +DROP TABLE abc; + + -- Test assorted behaviors around the implicit transaction block created -- when multiple SQL commands are sent in a single Query message. These -- tests rely on the fact that psql will not break SQL commands apart at a @@ -473,6 +540,45 @@ SELECT 2\; RELEASE SAVEPOINT sp\; SELECT 3; SELECT 1\; BEGIN\; SAVEPOINT sp\; ROLLBACK TO SAVEPOINT sp\; COMMIT; +-- Tests for AND CHAIN in implicit transaction blocks + +SET TRANSACTION READ ONLY\; COMMIT AND CHAIN; -- error +SHOW transaction_read_only; + +SET TRANSACTION READ ONLY\; ROLLBACK AND CHAIN; -- error +SHOW transaction_read_only; + +CREATE TABLE abc (a int); + +-- COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +INSERT INTO abc VALUES (7)\; COMMIT\; INSERT INTO abc VALUES (8)\; COMMIT AND CHAIN; -- 7 commit, 8 error +INSERT INTO abc VALUES (9)\; ROLLBACK\; INSERT INTO abc VALUES (10)\; ROLLBACK AND CHAIN; -- 9 rollback, 10 error + +-- COMMIT/ROLLBACK AND CHAIN + COMMIT/ROLLBACK +INSERT INTO abc VALUES (11)\; COMMIT AND CHAIN\; INSERT INTO abc VALUES (12)\; COMMIT; -- 11 error, 12 not reached +INSERT INTO abc VALUES (13)\; ROLLBACK AND CHAIN\; INSERT INTO abc VALUES (14)\; ROLLBACK; -- 13 error, 14 not reached + +-- START TRANSACTION + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (15)\; COMMIT AND CHAIN; -- 15 ok +SHOW transaction_isolation; -- transaction is active at this point +COMMIT; + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (16)\; ROLLBACK AND CHAIN; -- 16 ok +SHOW transaction_isolation; -- transaction is active at this point +ROLLBACK; + +-- START TRANSACTION + COMMIT/ROLLBACK + COMMIT/ROLLBACK AND CHAIN +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (17)\; COMMIT\; INSERT INTO abc VALUES (18)\; COMMIT AND CHAIN; -- 17 commit, 18 error +SHOW transaction_isolation; -- out of transaction block + +START TRANSACTION ISOLATION LEVEL REPEATABLE READ\; INSERT INTO abc VALUES (19)\; ROLLBACK\; INSERT INTO abc VALUES (20)\; ROLLBACK AND CHAIN; -- 19 rollback, 20 error +SHOW transaction_isolation; -- out of transaction block + +SELECT * FROM abc ORDER BY 1; + +DROP TABLE abc; + + -- Test for successful cleanup of an aborted transaction at session exit. -- THIS MUST BE THE LAST TEST IN THIS FILE. diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql index b08b83bf5fa..c21b6c124e0 100644 --- a/src/test/regress/sql/triggers.sql +++ b/src/test/regress/sql/triggers.sql @@ -26,13 +26,13 @@ create unique index pkeys_i on pkeys (pkey1, pkey2); create trigger check_fkeys_pkey_exist before insert or update on fkeys for each row - execute procedure + execute function check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2'); create trigger check_fkeys_pkey2_exist before insert or update on fkeys for each row - execute procedure check_primary_key ('fkey3', 'fkeys2', 'pkey23'); + execute function check_primary_key ('fkey3', 'fkeys2', 'pkey23'); -- -- For fkeys2: @@ -117,6 +117,41 @@ select * from trigtest; delete from trigtest; select * from trigtest; +-- Also check what happens when such a trigger runs before or after others +create function f1_times_10() returns trigger as +$$ begin new.f1 := new.f1 * 10; return new; end $$ language plpgsql; + +create trigger trigger_alpha + before insert or update on trigtest + for each row execute procedure f1_times_10(); + +insert into trigtest values(1, 'foo'); +select * from trigtest; +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; +delete from trigtest; +select * from trigtest; + +create trigger trigger_zed + before insert or update on trigtest + for each row execute procedure f1_times_10(); + +insert into trigtest values(1, 'foo'); +select * from trigtest; +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; +delete from trigtest; +select * from trigtest; + +drop trigger trigger_alpha on trigtest; + +insert into trigtest values(1, 'foo'); +select * from trigtest; +update trigtest set f2 = f2 || 'bar'; +select * from trigtest; +delete from trigtest; +select * from trigtest; + drop table trigtest; create sequence ttdummy_seq increment 10 start 0 minvalue 0; @@ -284,13 +319,29 @@ SELECT * FROM main_table ORDER BY a, b; SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any'; -DROP TRIGGER modified_a ON main_table; + +-- Test RENAME TRIGGER +ALTER TRIGGER modified_a ON main_table RENAME TO modified_modified_a; +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; +SELECT count(*) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_modified_a'; + +DROP TRIGGER modified_modified_a ON main_table; DROP TRIGGER modified_any ON main_table; DROP TRIGGER insert_a ON main_table; DROP TRIGGER delete_a ON main_table; DROP TRIGGER insert_when ON main_table; DROP TRIGGER delete_when ON main_table; +-- Test WHEN condition accessing system columns. +create table table_with_oids(a int); +insert into table_with_oids values (1); +create trigger oid_unchanged_trig after update on table_with_oids + for each row + when (new.tableoid = old.tableoid AND new.tableoid <> 0) + execute procedure trigger_func('after_upd_oid_unchanged'); +update table_with_oids set a = a + 1; +drop table table_with_oids; + -- Test column-level triggers DROP TRIGGER after_upd_row_trig ON main_table; @@ -572,23 +623,12 @@ CREATE TABLE min_updates_test ( f2 int, f3 int); -CREATE TABLE min_updates_test_oids ( - f1 text, - f2 int, - f3 int) WITH OIDS; - INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null); -INSERT INTO min_updates_test_oids VALUES ('a',1,2),('b','2',null); - CREATE TRIGGER z_min_update BEFORE UPDATE ON min_updates_test FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); -CREATE TRIGGER z_min_update -BEFORE UPDATE ON min_updates_test_oids -FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger(); - \set QUIET false UPDATE min_updates_test SET f1 = f1; @@ -597,22 +637,12 @@ UPDATE min_updates_test SET f2 = f2 + 1; UPDATE min_updates_test SET f3 = 2 WHERE f3 is null; -UPDATE min_updates_test_oids SET f1 = f1; - -UPDATE min_updates_test_oids SET f2 = f2 + 1; - -UPDATE min_updates_test_oids SET f3 = 2 WHERE f3 is null; - \set QUIET true SELECT * FROM min_updates_test; -SELECT * FROM min_updates_test_oids; - DROP TABLE min_updates_test; -DROP TABLE min_updates_test_oids; - -- -- Test triggers on views -- @@ -1182,6 +1212,33 @@ drop table self_ref_trigger; drop function self_ref_trigger_ins_func(); drop function self_ref_trigger_del_func(); +-- +-- Check that statement triggers work correctly even with all children excluded +-- + +create table stmt_trig_on_empty_upd (a int); +create table stmt_trig_on_empty_upd1 () inherits (stmt_trig_on_empty_upd); +create function update_stmt_notice() returns trigger as $$ +begin + raise notice 'updating %', TG_TABLE_NAME; + return null; +end; +$$ language plpgsql; +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd + execute procedure update_stmt_notice(); +create trigger before_stmt_trigger + before update on stmt_trig_on_empty_upd1 + execute procedure update_stmt_notice(); + +-- inherited no-op update +update stmt_trig_on_empty_upd set a = a where false returning a+1 as aa; +-- simple no-op update +update stmt_trig_on_empty_upd1 set a = a where false returning a+1 as aa; + +drop table stmt_trig_on_empty_upd cascade; +drop function update_stmt_notice(); + -- -- Check that index creation (or DDL in general) is prohibited in a trigger -- @@ -1438,6 +1495,29 @@ create trigger qqq after insert on parted_trig_1_1 for each row execute procedur insert into parted_trig values (50), (1500); drop table parted_trig; +-- Verify propagation of trigger arguments to partitions +create table parted_trig (a int) partition by list (a); +create table parted_trig1 partition of parted_trig for values in (1); +create or replace function trigger_notice() returns trigger as $$ + declare + arg1 text = TG_ARGV[0]; + arg2 integer = TG_ARGV[1]; + begin + raise notice 'trigger % on % % % for % args % %', + TG_NAME, TG_TABLE_NAME, TG_WHEN, TG_OP, TG_LEVEL, arg1, arg2; + return null; + end; + $$ language plpgsql; +create trigger aaa after insert on parted_trig + for each row execute procedure trigger_notice('quirky', 1); + +-- Verify propagation of trigger arguments to partitions attached after creating trigger +create table parted_trig2 partition of parted_trig for values in (2); +create table parted_trig3 (like parted_trig); +alter table parted_trig attach partition parted_trig3 for values in (3); +insert into parted_trig values (1), (2), (3); +drop table parted_trig; + -- test irregular partitions (i.e., different column definitions), -- including that the WHEN clause works create function bark(text) returns bool language plpgsql immutable @@ -2125,53 +2205,6 @@ delete from self_ref where a = 1; drop table self_ref; --- --- test transition tables with MERGE --- -create table merge_target_table (a int primary key, b text); -create trigger merge_target_table_insert_trig - after insert on merge_target_table referencing new table as new_table - for each statement execute procedure dump_insert(); -create trigger merge_target_table_update_trig - after update on merge_target_table referencing old table as old_table new table as new_table - for each statement execute procedure dump_update(); -create trigger merge_target_table_delete_trig - after delete on merge_target_table referencing old table as old_table - for each statement execute procedure dump_delete(); - -create table merge_source_table (a int, b text); -insert into merge_source_table - values (1, 'initial1'), (2, 'initial2'), - (3, 'initial3'), (4, 'initial4'); - -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when not matched then - insert values (a, b); - -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when matched and s.a <= 2 then - update set b = t.b || ' updated by merge' -when matched and s.a > 2 then - delete -when not matched then - insert values (a, b); - -merge into merge_target_table t -using merge_source_table s -on t.a = s.a -when matched and s.a <= 2 then - update set b = t.b || ' updated again by merge' -when matched and s.a > 2 then - delete -when not matched then - insert values (a, b); - -drop table merge_source_table, merge_target_table; - -- cleanup drop function dump_insert(); drop function dump_update(); diff --git a/src/test/regress/sql/truncate.sql b/src/test/regress/sql/truncate.sql index fbd1d1a8a51..28395e82bf8 100644 --- a/src/test/regress/sql/truncate.sql +++ b/src/test/regress/sql/truncate.sql @@ -244,3 +244,48 @@ INSERT INTO truncparted VALUES (1, 'a'); TRUNCATE ONLY truncparted; TRUNCATE truncparted; DROP TABLE truncparted; + +-- foreign key on partitioned table: partition key is referencing column. +-- Make sure truncate did execute on all tables +CREATE FUNCTION tp_ins_data() RETURNS void LANGUAGE plpgsql AS $$ + BEGIN + INSERT INTO truncprim VALUES (1), (100), (150); + INSERT INTO truncpart VALUES (1), (100), (150); + END +$$; +CREATE FUNCTION tp_chk_data(OUT pktb regclass, OUT pkval int, OUT fktb regclass, OUT fkval int) + RETURNS SETOF record LANGUAGE plpgsql AS $$ + BEGIN + RETURN QUERY SELECT + pk.tableoid::regclass, pk.a, fk.tableoid::regclass, fk.a + FROM truncprim pk FULL JOIN truncpart fk USING (a) + ORDER BY 2, 4; + END +$$; +CREATE TABLE truncprim (a int PRIMARY KEY); +CREATE TABLE truncpart (a int REFERENCES truncprim) + PARTITION BY RANGE (a); +CREATE TABLE truncpart_1 PARTITION OF truncpart FOR VALUES FROM (0) TO (100); +CREATE TABLE truncpart_2 PARTITION OF truncpart FOR VALUES FROM (100) TO (200) + PARTITION BY RANGE (a); +CREATE TABLE truncpart_2_1 PARTITION OF truncpart_2 FOR VALUES FROM (100) TO (150); +CREATE TABLE truncpart_2_d PARTITION OF truncpart_2 DEFAULT; + +TRUNCATE TABLE truncprim; -- should fail + +select tp_ins_data(); +-- should truncate everything +TRUNCATE TABLE truncprim, truncpart; +select * from tp_chk_data(); + +select tp_ins_data(); +-- should truncate everything +TRUNCATE TABLE truncprim CASCADE; +SELECT * FROM tp_chk_data(); + +SELECT tp_ins_data(); +-- should truncate all partitions +TRUNCATE TABLE truncpart; +SELECT * FROM tp_chk_data(); +DROP TABLE truncprim, truncpart; +DROP FUNCTION tp_ins_data(), tp_chk_data(); diff --git a/src/test/regress/sql/tsdicts.sql b/src/test/regress/sql/tsdicts.sql index 1633c0d066b..60906f6549a 100644 --- a/src/test/regress/sql/tsdicts.sql +++ b/src/test/regress/sql/tsdicts.sql @@ -66,11 +66,14 @@ SELECT ts_lexize('hunspell_long', 'rebook'); SELECT ts_lexize('hunspell_long', 'unbookings'); SELECT ts_lexize('hunspell_long', 'unbooking'); SELECT ts_lexize('hunspell_long', 'unbook'); +SELECT ts_lexize('hunspell_long', 'booked'); SELECT ts_lexize('hunspell_long', 'footklubber'); SELECT ts_lexize('hunspell_long', 'footballklubber'); SELECT ts_lexize('hunspell_long', 'ballyklubber'); +SELECT ts_lexize('hunspell_long', 'ballsklubber'); SELECT ts_lexize('hunspell_long', 'footballyklubber'); +SELECT ts_lexize('hunspell_long', 'ex-machina'); -- Test ISpell dictionary with hunspell affix file with FLAG num parameter CREATE TEXT SEARCH DICTIONARY hunspell_num ( @@ -80,6 +83,7 @@ CREATE TEXT SEARCH DICTIONARY hunspell_num ( ); SELECT ts_lexize('hunspell_num', 'skies'); +SELECT ts_lexize('hunspell_num', 'sk'); SELECT ts_lexize('hunspell_num', 'bookings'); SELECT ts_lexize('hunspell_num', 'booking'); SELECT ts_lexize('hunspell_num', 'foot'); @@ -90,6 +94,7 @@ SELECT ts_lexize('hunspell_num', 'rebook'); SELECT ts_lexize('hunspell_num', 'unbookings'); SELECT ts_lexize('hunspell_num', 'unbooking'); SELECT ts_lexize('hunspell_num', 'unbook'); +SELECT ts_lexize('hunspell_num', 'booked'); SELECT ts_lexize('hunspell_num', 'footklubber'); SELECT ts_lexize('hunspell_num', 'footballklubber'); diff --git a/src/test/regress/sql/tsearch.sql b/src/test/regress/sql/tsearch.sql index 637bfb30120..ece80b983c5 100644 --- a/src/test/regress/sql/tsearch.sql +++ b/src/test/regress/sql/tsearch.sql @@ -520,6 +520,17 @@ INSERT INTO test_tsvector (t) VALUES ('345 qwerty'); SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); +-- Test inlining of immutable constant functions + +-- to_tsquery(text) is not immutable, so it won't be inlined +explain (costs off) +select * from test_tsquery, to_tsquery('new') q where txtsample @@ q; + +-- to_tsquery(regconfig, text) is an immutable function. +-- That allows us to get rid of using function scan and join at all. +explain (costs off) +select * from test_tsquery, to_tsquery('english', 'new') q where txtsample @@ q; + -- test finding items in GIN's pending list create temp table pendtest (ts tsvector); create index pendtest_idx on pendtest using gin(ts); diff --git a/src/test/regress/sql/tsrf.sql b/src/test/regress/sql/tsrf.sql index ae1900bce12..7c22529a0db 100644 --- a/src/test/regress/sql/tsrf.sql +++ b/src/test/regress/sql/tsrf.sql @@ -28,6 +28,18 @@ SELECT generate_series(1, generate_series(1, 3)), generate_series(2, 4); CREATE TABLE few(id int, dataa text, datab text); INSERT INTO few VALUES(1, 'a', 'foo'),(2, 'a', 'bar'),(3, 'b', 'bar'); +-- SRF with a provably-dummy relation +explain (verbose, costs off) +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; +SELECT unnest(ARRAY[1, 2]) FROM few WHERE false; + +-- SRF shouldn't prevent upper query from recognizing lower as dummy +explain (verbose, costs off) +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; +SELECT * FROM few f1, + (SELECT unnest(ARRAY[1,2]) FROM few f2 WHERE false OFFSET 0) ss; + -- SRF output order of sorting is maintained, if SRF is not referenced SELECT few.id, generate_series(1,3) g FROM few ORDER BY id DESC; @@ -88,6 +100,11 @@ SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(d SELECT dataa, datab b, generate_series(1,2) g, count(*) FROM few GROUP BY CUBE(dataa, datab, g) ORDER BY g; reset enable_hashagg; +-- case with degenerate ORDER BY +explain (verbose, costs off) +select 'foo' as f, generate_series(1,2) as g from few order by 1; +select 'foo' as f, generate_series(1,2) as g from few order by 1; + -- data modification CREATE TABLE fewmore AS SELECT generate_series(1,3) AS data; INSERT INTO fewmore VALUES(generate_series(4,5)); diff --git a/src/test/regress/sql/tstypes.sql b/src/test/regress/sql/tstypes.sql index 0a40ec93504..94ee1772b44 100644 --- a/src/test/regress/sql/tstypes.sql +++ b/src/test/regress/sql/tstypes.sql @@ -1,3 +1,6 @@ +-- deal with numeric instability of ts_rank +SET extra_float_digits = 0; + --Base tsvector test SELECT '1'::tsvector; diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql index f9aeea32144..fed413bf98a 100644 --- a/src/test/regress/sql/type_sanity.sql +++ b/src/test/regress/sql/type_sanity.sql @@ -367,12 +367,29 @@ WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR relpersistence NOT IN ('p', 'u', 't') OR relreplident NOT IN ('d', 'n', 'f', 'i'); --- Indexes should have an access method, others not. +-- All tables and indexes should have an access method. +SELECT p1.oid, p1.relname +FROM pg_class as p1 +WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and + p1.relam = 0; +-- Conversely, sequences, views, types shouldn't have them SELECT p1.oid, p1.relname FROM pg_class as p1 -WHERE (p1.relkind = 'i' AND p1.relam = 0) OR - (p1.relkind != 'i' AND p1.relam != 0); +WHERE p1.relkind IN ('S', 'v', 'f', 'c') and + p1.relam != 0; + +-- Indexes should have AMs of type 'i' +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('i') and + pa.amtype != 'i'; + +-- Tables, matviews etc should have AMs of type 't' +SELECT pc.oid, pc.relname, pa.amname, pa.amtype +FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) +WHERE pc.relkind IN ('r', 't', 'm') and + pa.amtype != 't'; -- **************** pg_attribute **************** diff --git a/src/test/regress/sql/union.sql b/src/test/regress/sql/union.sql index eed7c8d34be..5f4881d5943 100644 --- a/src/test/regress/sql/union.sql +++ b/src/test/regress/sql/union.sql @@ -379,6 +379,34 @@ SELECT * FROM WHERE x > 3 ORDER BY x; +-- Test cases where the native ordering of a sub-select has more pathkeys +-- than the outer query cares about +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2; + +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where q2 = q2; + +explain (costs off) +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2; + +select distinct q1 from + (select distinct * from int8_tbl i81 + union all + select distinct * from int8_tbl i82) ss +where -q1 = q2; + -- Test proper handling of parameterized appendrel paths when the -- potential join qual is expensive create function expensivefunc(int) returns int diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql index 6a9005243bb..e50a4c52ee7 100644 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@ -2,6 +2,9 @@ -- UPDATABLE VIEWS -- +-- avoid bit-exact output here because operations may not be bit-exact. +SET extra_float_digits = 0; + -- check that non-updatable views and columns are rejected with useful error -- messages @@ -459,6 +462,82 @@ RESET SESSION AUTHORIZATION; DROP TABLE base_tbl CASCADE; +-- nested-view permissions + +CREATE TABLE base_tbl(a int, b text, c float); +INSERT INTO base_tbl VALUES (1, 'Row 1', 1.0); + +SET SESSION AUTHORIZATION regress_view_user1; +CREATE VIEW rw_view1 AS SELECT * FROM base_tbl; +SELECT * FROM rw_view1; -- not allowed +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed + +SET SESSION AUTHORIZATION regress_view_user2; +CREATE VIEW rw_view2 AS SELECT * FROM rw_view1; +SELECT * FROM rw_view2; -- not allowed +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed + +RESET SESSION AUTHORIZATION; +GRANT SELECT ON base_tbl TO regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed + +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; -- not allowed +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed + +SET SESSION AUTHORIZATION regress_view_user1; +GRANT SELECT ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed + +RESET SESSION AUTHORIZATION; +GRANT UPDATE ON base_tbl TO regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; +SELECT * FROM rw_view1 FOR UPDATE; +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; + +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed + +SET SESSION AUTHORIZATION regress_view_user1; +GRANT UPDATE ON rw_view1 TO regress_view_user2; + +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; +SELECT * FROM rw_view2 FOR UPDATE; +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; + +RESET SESSION AUTHORIZATION; +REVOKE UPDATE ON base_tbl FROM regress_view_user1; + +SET SESSION AUTHORIZATION regress_view_user1; +SELECT * FROM rw_view1; +SELECT * FROM rw_view1 FOR UPDATE; -- not allowed +UPDATE rw_view1 SET b = 'foo' WHERE a = 1; -- not allowed + +SET SESSION AUTHORIZATION regress_view_user2; +SELECT * FROM rw_view2; +SELECT * FROM rw_view2 FOR UPDATE; -- not allowed +UPDATE rw_view2 SET b = 'bar' WHERE a = 1; -- not allowed + +RESET SESSION AUTHORIZATION; + +DROP TABLE base_tbl CASCADE; + DROP USER regress_view_user1; DROP USER regress_view_user2; @@ -634,7 +713,20 @@ DELETE FROM ONLY rw_view2 WHERE a IN (-8, 8); -- Should delete -8 only SELECT * FROM ONLY base_tbl_parent ORDER BY a; SELECT * FROM base_tbl_child ORDER BY a; +CREATE TABLE other_tbl_parent (id int); +CREATE TABLE other_tbl_child () INHERITS (other_tbl_parent); +INSERT INTO other_tbl_parent VALUES (7),(200); +INSERT INTO other_tbl_child VALUES (8),(100); + +EXPLAIN (costs off) +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; +UPDATE rw_view1 SET a = a + 1000 FROM other_tbl_parent WHERE a = id; + +SELECT * FROM ONLY base_tbl_parent ORDER BY a; +SELECT * FROM base_tbl_child ORDER BY a; + DROP TABLE base_tbl_parent, base_tbl_child CASCADE; +DROP TABLE other_tbl_parent CASCADE; -- simple WITH CHECK OPTION @@ -1168,3 +1260,240 @@ insert into wcowrtest_v2 values (2, 'no such row in sometable'); drop view wcowrtest_v, wcowrtest_v2; drop table wcowrtest, sometable; + +-- Check INSERT .. ON CONFLICT DO UPDATE works correctly when the view's +-- columns are named and ordered differently than the underlying table's. +create table uv_iocu_tab (a text unique, b float); +insert into uv_iocu_tab values ('xyxyxy', 0); +create view uv_iocu_view as + select b, b+1 as c, a, '2.0'::text as two from uv_iocu_tab; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = uv_iocu_view.b; +select * from uv_iocu_tab; +insert into uv_iocu_view (a, b) values ('xyxyxy', 1) + on conflict (a) do update set b = excluded.b; +select * from uv_iocu_tab; + +-- OK to access view columns that are not present in underlying base +-- relation in the ON CONFLICT portion of the query +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = cast(excluded.two as float); +select * from uv_iocu_tab; + +explain (costs off) +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; + +insert into uv_iocu_view (a, b) values ('xyxyxy', 3) + on conflict (a) do update set b = excluded.b where excluded.c > 0; +select * from uv_iocu_tab; + +drop view uv_iocu_view; +drop table uv_iocu_tab; + +-- Test whole-row references to the view +create table uv_iocu_tab (a int unique, b text); +create view uv_iocu_view as + select b as bb, a as aa, uv_iocu_tab::text as cc from uv_iocu_tab; + +insert into uv_iocu_view (aa,bb) values (1,'x'); +explain (costs off) +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; +insert into uv_iocu_view (aa,bb) values (1,'y') + on conflict (aa) do update set bb = 'Rejected: '||excluded.* + where excluded.aa > 0 + and excluded.bb != '' + and excluded.cc is not null; +select * from uv_iocu_view; + +-- Test omitting a column of the base relation +delete from uv_iocu_view; +insert into uv_iocu_view (aa,bb) values (1,'x'); +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + +alter table uv_iocu_tab alter column b set default 'table default'; +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + +alter view uv_iocu_view alter column bb set default 'view default'; +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set bb = 'Rejected: '||excluded.*; +select * from uv_iocu_view; + +-- Should fail to update non-updatable columns +insert into uv_iocu_view (aa) values (1) + on conflict (aa) do update set cc = 'XXX'; + +drop view uv_iocu_view; +drop table uv_iocu_tab; + +-- ON CONFLICT DO UPDATE permissions checks +create user regress_view_user1; +create user regress_view_user2; + +set session authorization regress_view_user1; +create table base_tbl(a int unique, b text, c float); +insert into base_tbl values (1,'xxx',1.0); +create view rw_view1 as select b as bb, c as cc, a as aa from base_tbl; + +grant select (aa,bb) on rw_view1 to regress_view_user2; +grant insert on rw_view1 to regress_view_user2; +grant update (bb) on rw_view1 to regress_view_user2; + +set session authorization regress_view_user2; +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.cc; -- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = rw_view1.cc; -- Not allowed +insert into rw_view1 values ('yyy',2.0,1) + on conflict (aa) do update set bb = excluded.bb; -- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set bb = rw_view1.bb||'xxx'; -- OK +insert into rw_view1 values ('zzz',2.0,1) + on conflict (aa) do update set cc = 3.0; -- Not allowed +reset session authorization; +select * from base_tbl; + +set session authorization regress_view_user1; +grant select (a,b) on base_tbl to regress_view_user2; +grant insert (a,b) on base_tbl to regress_view_user2; +grant update (a,b) on base_tbl to regress_view_user2; + +set session authorization regress_view_user2; +create view rw_view2 as select b as bb, c as cc, a as aa from base_tbl; +insert into rw_view2 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; -- Not allowed +create view rw_view3 as select b as bb, a as aa from base_tbl; +insert into rw_view3 (aa,bb) values (1,'xxx') + on conflict (aa) do update set bb = excluded.bb; -- OK +reset session authorization; +select * from base_tbl; + +set session authorization regress_view_user2; +create view rw_view4 as select aa, bb, cc FROM rw_view1; +insert into rw_view4 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; -- Not allowed +create view rw_view5 as select aa, bb FROM rw_view1; +insert into rw_view5 (aa,bb) values (1,'yyy') + on conflict (aa) do update set bb = excluded.bb; -- OK +reset session authorization; +select * from base_tbl; + +drop view rw_view5; +drop view rw_view4; +drop view rw_view3; +drop view rw_view2; +drop view rw_view1; +drop table base_tbl; +drop user regress_view_user1; +drop user regress_view_user2; + +-- Test single- and multi-row inserts with table and view defaults. +-- Table defaults should be used, unless overridden by view defaults. +create table base_tab_def (a int, b text default 'Table default', + c text default 'Table default', d text, e text); +create view base_tab_def_view as select * from base_tab_def; +alter view base_tab_def_view alter b set default 'View default'; +alter view base_tab_def_view alter d set default 'View default'; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + +-- Adding an INSTEAD OF trigger should cause NULLs to be inserted instead of +-- table defaults, where there are no view defaults. +create function base_tab_def_view_instrig_func() returns trigger +as +$$ +begin + insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); + return new; +end; +$$ +language plpgsql; +create trigger base_tab_def_view_instrig instead of insert on base_tab_def_view + for each row execute function base_tab_def_view_instrig_func(); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + +-- Using an unconditional DO INSTEAD rule should also cause NULLs to be +-- inserted where there are no view defaults. +drop trigger base_tab_def_view_instrig on base_tab_def_view; +drop function base_tab_def_view_instrig_func; +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do instead insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a; + +-- A DO ALSO rule should cause each row to be inserted twice. The first +-- insert should behave the same as an auto-updatable view (using table +-- defaults, unless overridden by view defaults). The second insert should +-- behave the same as a rule-updatable view (inserting NULLs where there are +-- no view defaults). +drop rule base_tab_def_view_ins_rule on base_tab_def_view; +create rule base_tab_def_view_ins_rule as on insert to base_tab_def_view + do also insert into base_tab_def values (new.a, new.b, new.c, new.d, new.e); +truncate base_tab_def; +insert into base_tab_def values (1); +insert into base_tab_def values (2), (3); +insert into base_tab_def values (4, default, default, default, default); +insert into base_tab_def values (5, default, default, default, default), + (6, default, default, default, default); +insert into base_tab_def_view values (11); +insert into base_tab_def_view values (12), (13); +insert into base_tab_def_view values (14, default, default, default, default); +insert into base_tab_def_view values (15, default, default, default, default), + (16, default, default, default, default); +insert into base_tab_def_view values (17), (default); +select * from base_tab_def order by a, c NULLS LAST; + +drop view base_tab_def_view; +drop table base_tab_def; + +-- Test defaults with array assignments +create table base_tab (a serial, b int[], c text, d text default 'Table default'); +create view base_tab_view as select c, a, b from base_tab; +alter view base_tab_view alter column c set default 'View default'; +insert into base_tab_view (b[1], b[2], c, b[5], b[4], a, b[3]) +values (1, 2, default, 5, 4, default, 3), (10, 11, 'C value', 14, 13, 100, 12); +select * from base_tab order by a; +drop view base_tab_view; +drop table base_tab; diff --git a/src/test/regress/sql/update.sql b/src/test/regress/sql/update.sql index c9bb3b53d35..bb9c24e40f8 100644 --- a/src/test/regress/sql/update.sql +++ b/src/test/regress/sql/update.sql @@ -89,6 +89,16 @@ UPDATE update_test AS t SET b = update_test.b + 10 WHERE t.a = 10; UPDATE update_test SET c = repeat('x', 10000) WHERE c = 'car'; SELECT a, b, char_length(c) FROM update_test; +-- Check multi-assignment with a Result node to handle a one-time filter. +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; +UPDATE update_test t + SET (a, b) = (SELECT b, a FROM update_test s WHERE s.a = t.a) + WHERE CURRENT_USER = SESSION_USER; +SELECT a, b, char_length(c) FROM update_test; + -- Test ON CONFLICT DO UPDATE INSERT INTO upsert_test VALUES(1, 'Boo'); -- uncorrelated sub-select: @@ -104,6 +114,21 @@ INSERT INTO upsert_test VALUES (1, 'Bat') ON CONFLICT(a) DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) RETURNING *; +-- ON CONFLICT using system attributes in RETURNING, testing both the +-- inserting and updating paths. See bug report at: +-- https://www.postgresql.org/message-id/73436355-6432-49B1-92ED-1FE4F7E7E100%40finefun.com.au +CREATE FUNCTION xid_current() RETURNS xid LANGUAGE SQL AS $$SELECT (txid_current() % ((1::int8<<32)))::text::xid;$$; +INSERT INTO upsert_test VALUES (2, 'Beeble') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = 0 AS xmax_correct; +-- currently xmax is set after a conflict - that's probably not good, +-- but it seems worthwhile to have to be explicit if that changes. +INSERT INTO upsert_test VALUES (2, 'Brox') ON CONFLICT(a) + DO UPDATE SET (b, a) = (SELECT b || ', Excluded', a from upsert_test i WHERE i.a = excluded.a) + RETURNING tableoid::regclass, xmin = xid_current() AS xmin_correct, xmax = xid_current() AS xmax_correct; + + +DROP FUNCTION xid_current(); DROP TABLE update_test; DROP TABLE upsert_test; diff --git a/src/test/regress/sql/uuid.sql b/src/test/regress/sql/uuid.sql index 518d2b75c00..3bd3b357c77 100644 --- a/src/test/regress/sql/uuid.sql +++ b/src/test/regress/sql/uuid.sql @@ -75,5 +75,11 @@ INSERT INTO guid2(guid_field) VALUES('3f3e3c3b3a3039383736353433a2313e'); SELECT COUNT(*) FROM guid1 g1 INNER JOIN guid2 g2 ON g1.guid_field = g2.guid_field; SELECT COUNT(*) FROM guid1 g1 LEFT JOIN guid2 g2 ON g1.guid_field = g2.guid_field WHERE g2.guid_field IS NULL; +-- generation test +TRUNCATE guid1; +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); +INSERT INTO guid1 (guid_field) VALUES (gen_random_uuid()); +SELECT count(DISTINCT guid_field) FROM guid1; + -- clean up DROP TABLE guid1, guid2 CASCADE; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 275ce2e270f..f0fee3af2bf 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -54,6 +54,19 @@ CREATE INDEX ON vaccluster(wrap_do_analyze(i)); INSERT INTO vaccluster VALUES (1), (2); ANALYZE vaccluster; +-- Test ANALYZE in transaction, where the transaction surrounding +-- analyze performed modifications. This tests for the bug at +-- https://postgr.es/m/c7988239-d42c-ddc4-41db-171b23b35e4f%40ssinger.info +-- (which hopefully is unlikely to be reintroduced), but also seems +-- independently worthwhile to cover. +INSERT INTO vactst SELECT generate_series(1, 300); +DELETE FROM vactst WHERE i % 7 = 0; -- delete a few rows outside +BEGIN; +INSERT INTO vactst SELECT generate_series(301, 400); +DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside +ANALYZE vactst; +COMMIT; + VACUUM FULL pg_am; VACUUM FULL pg_class; VACUUM FULL pg_database; @@ -62,6 +75,52 @@ VACUUM FULL vactst; VACUUM (DISABLE_PAGE_SKIPPING) vaccluster; +-- INDEX_CLEANUP option +CREATE TABLE no_index_cleanup (i INT PRIMARY KEY, t TEXT); +-- Use uncompressed data stored in toast. +CREATE INDEX no_index_cleanup_idx ON no_index_cleanup(t); +ALTER TABLE no_index_cleanup ALTER COLUMN t SET STORAGE EXTERNAL; +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(1,30), + repeat('1234567890',300)); +-- index cleanup option is ignored if VACUUM FULL +VACUUM (INDEX_CLEANUP TRUE, FULL TRUE) no_index_cleanup; +VACUUM (FULL TRUE) no_index_cleanup; +-- Toast inherits the value from its parent table. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false); +DELETE FROM no_index_cleanup WHERE i < 15; +-- Nothing is cleaned up. +VACUUM no_index_cleanup; +-- Both parent relation and toast are cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true); +VACUUM no_index_cleanup; +-- Parameter is set for both the parent table and its toast relation. +INSERT INTO no_index_cleanup(i, t) VALUES (generate_series(31,60), + repeat('1234567890',300)); +DELETE FROM no_index_cleanup WHERE i < 45; +-- Only toast index is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = false, + toast.vacuum_index_cleanup = true); +VACUUM no_index_cleanup; +-- Only parent is cleaned up. +ALTER TABLE no_index_cleanup SET (vacuum_index_cleanup = true, + toast.vacuum_index_cleanup = false); +VACUUM no_index_cleanup; +-- Test some extra relations. +VACUUM (INDEX_CLEANUP FALSE) vaccluster; +VACUUM (INDEX_CLEANUP FALSE) vactst; -- index cleanup option is ignored if no indexes +VACUUM (INDEX_CLEANUP FALSE, FREEZE TRUE) vaccluster; + +-- TRUNCATE option +CREATE TABLE vac_truncate_test(i INT NOT NULL, j text) + WITH (vacuum_truncate=true, autovacuum_enabled=false); +INSERT INTO vac_truncate_test VALUES (1, NULL), (NULL, NULL); +VACUUM (TRUNCATE FALSE) vac_truncate_test; +SELECT pg_relation_size('vac_truncate_test') > 0; +VACUUM vac_truncate_test; +SELECT pg_relation_size('vac_truncate_test') = 0; +VACUUM (TRUNCATE FALSE, FULL TRUE) vac_truncate_test; +DROP TABLE vac_truncate_test; + -- partitioned table CREATE TABLE vacparted (a int, b char) PARTITION BY LIST (a); CREATE TABLE vacparted1 PARTITION OF vacparted FOR VALUES IN (1); @@ -88,11 +147,113 @@ ANALYZE vactst, vacparted; ANALYZE vacparted (b), vactst; ANALYZE vactst, does_not_exist, vacparted; ANALYZE vactst (i), vacparted (does_not_exist); +ANALYZE vactst, vactst; +BEGIN; -- ANALYZE behaves differently inside a transaction block +ANALYZE vactst, vactst; +COMMIT; -- parenthesized syntax for ANALYZE ANALYZE (VERBOSE) does_not_exist; -ANALYZE (nonexistant-arg) does_not_exist; +ANALYZE (nonexistent-arg) does_not_exist; +ANALYZE (nonexistentarg) does_not_exit; + +-- ensure argument order independence, and that SKIP_LOCKED on non-existing +-- relation still errors out. +ANALYZE (SKIP_LOCKED, VERBOSE) does_not_exist; +ANALYZE (VERBOSE, SKIP_LOCKED) does_not_exist; + +-- SKIP_LOCKED option +VACUUM (SKIP_LOCKED) vactst; +VACUUM (SKIP_LOCKED, FULL) vactst; +ANALYZE (SKIP_LOCKED) vactst; + +-- ensure VACUUM and ANALYZE don't have a problem with serializable +SET default_transaction_isolation = serializable; +VACUUM vactst; +ANALYZE vactst; +RESET default_transaction_isolation; +BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; +ANALYZE vactst; +COMMIT; DROP TABLE vaccluster; DROP TABLE vactst; DROP TABLE vacparted; +DROP TABLE no_index_cleanup; + +-- relation ownership, WARNING logs generated as all are skipped. +CREATE TABLE vacowned (a int); +CREATE TABLE vacowned_parted (a int) PARTITION BY LIST (a); +CREATE TABLE vacowned_part1 PARTITION OF vacowned_parted FOR VALUES IN (1); +CREATE TABLE vacowned_part2 PARTITION OF vacowned_parted FOR VALUES IN (2); +CREATE ROLE regress_vacuum; +SET ROLE regress_vacuum; +-- Simple table +VACUUM vacowned; +ANALYZE vacowned; +VACUUM (ANALYZE) vacowned; +-- Catalog +VACUUM pg_catalog.pg_class; +ANALYZE pg_catalog.pg_class; +VACUUM (ANALYZE) pg_catalog.pg_class; +-- Shared catalog +VACUUM pg_catalog.pg_authid; +ANALYZE pg_catalog.pg_authid; +VACUUM (ANALYZE) pg_catalog.pg_authid; +-- Partitioned table and its partitions, nothing owned by other user. +-- Relations are not listed in a single command to test ownership +-- independently. +VACUUM vacowned_parted; +VACUUM vacowned_part1; +VACUUM vacowned_part2; +ANALYZE vacowned_parted; +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +VACUUM (ANALYZE) vacowned_parted; +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +RESET ROLE; +-- Partitioned table and one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; +ALTER TABLE vacowned_part1 OWNER TO regress_vacuum; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +VACUUM vacowned_part1; +VACUUM vacowned_part2; +ANALYZE vacowned_parted; +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +VACUUM (ANALYZE) vacowned_parted; +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +RESET ROLE; +-- Only one partition owned by other user. +ALTER TABLE vacowned_parted OWNER TO CURRENT_USER; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +VACUUM vacowned_part1; +VACUUM vacowned_part2; +ANALYZE vacowned_parted; +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +VACUUM (ANALYZE) vacowned_parted; +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +RESET ROLE; +-- Only partitioned table owned by other user. +ALTER TABLE vacowned_parted OWNER TO regress_vacuum; +ALTER TABLE vacowned_part1 OWNER TO CURRENT_USER; +SET ROLE regress_vacuum; +VACUUM vacowned_parted; +VACUUM vacowned_part1; +VACUUM vacowned_part2; +ANALYZE vacowned_parted; +ANALYZE vacowned_part1; +ANALYZE vacowned_part2; +VACUUM (ANALYZE) vacowned_parted; +VACUUM (ANALYZE) vacowned_part1; +VACUUM (ANALYZE) vacowned_part2; +RESET ROLE; +DROP TABLE vacowned; +DROP TABLE vacowned_parted; +DROP ROLE regress_vacuum; diff --git a/src/test/regress/sql/window.sql b/src/test/regress/sql/window.sql index 051b50b2d35..fc6d4cc903b 100644 --- a/src/test/regress/sql/window.sql +++ b/src/test/regress/sql/window.sql @@ -795,6 +795,44 @@ WINDOW w AS (ORDER BY x groups between 1 preceding and 1 following); -- with UNION SELECT count(*) OVER (PARTITION BY four) FROM (SELECT * FROM tenk1 UNION ALL SELECT * FROM tenk2)s LIMIT 0; +-- check some degenerate cases +create temp table t1 (f1 int, f2 int8); +insert into t1 values (1,1),(1,2),(2,2); + +select f1, sum(f1) over (partition by f1 + range between 1 preceding and 1 following) +from t1 where f1 = f2; -- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1 order by f2 + range between 1 preceding and 1 following) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1, f1 order by f2 + range between 2 preceding and 1 preceding) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1, f2 order by f2 + range between 1 following and 2 following) +from t1 where f1 = f2; + +select f1, sum(f1) over (partition by f1 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; -- error, must have order by +explain (costs off) +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1 order by f2 + groups between 1 preceding and 1 following) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1, f1 order by f2 + groups between 2 preceding and 1 preceding) +from t1 where f1 = f2; +select f1, sum(f1) over (partition by f1, f2 order by f2 + groups between 1 following and 2 following) +from t1 where f1 = f2; + -- ordering by a non-integer constant is allowed SELECT rank() OVER (ORDER BY length('abc')); @@ -854,6 +892,22 @@ SELECT * FROM FROM empsalary) emp WHERE depname = 'sales'; +-- Test Sort node collapsing +EXPLAIN (COSTS OFF) +SELECT * FROM + (SELECT depname, + sum(salary) OVER (PARTITION BY depname order by empno) depsalary, + min(salary) OVER (PARTITION BY depname, empno order by enroll_date) depminsalary + FROM empsalary) emp +WHERE depname = 'sales'; + +-- Test Sort node reordering +EXPLAIN (COSTS OFF) +SELECT + lead(1) OVER (PARTITION BY depname ORDER BY salary, enroll_date), + lag(1) OVER (PARTITION BY depname ORDER BY salary,enroll_date,empno) +FROM empsalary; + -- cleanup DROP TABLE empsalary; diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql index c6b197c3275..f85645efdee 100644 --- a/src/test/regress/sql/with.sql +++ b/src/test/regress/sql/with.sql @@ -862,62 +862,6 @@ RETURNING k, v; DROP TABLE withz; --- WITH referenced by MERGE statement -CREATE TABLE m AS SELECT i AS k, (i || ' v')::text v FROM generate_series(1, 16, 3) i; -ALTER TABLE m ADD UNIQUE (k); - -WITH RECURSIVE cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); - --- Basic: -WITH cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); --- Examine -SELECT * FROM m where k = 0; - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH cte_basic AS (SELECT 1 a, 'cte_basic val' b) -MERGE INTO m USING (select 0 k, 'merge source SubPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_basic WHERE cte_basic.a = m.k LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); - --- InitPlan -WITH cte_init AS (SELECT 1 a, 'cte_init val' b) -MERGE INTO m USING (select 1 k, 'merge source InitPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); --- Examine -SELECT * FROM m where k = 1; - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH cte_init AS (SELECT 1 a, 'cte_init val' b) -MERGE INTO m USING (select 1 k, 'merge source InitPlan' v) o ON m.k=o.k -WHEN MATCHED THEN UPDATE SET v = (SELECT b || ' merge update' FROM cte_init WHERE a = 1 LIMIT 1) -WHEN NOT MATCHED THEN INSERT VALUES(o.k, o.v); - --- MERGE source comes from CTE: -WITH merge_source_cte AS (SELECT 15 a, 'merge_source_cte val' b) -MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a -WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) -WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)); --- Examine -SELECT * FROM m where k = 15; - --- See EXPLAIN output for same query: -EXPLAIN (VERBOSE, COSTS OFF) -WITH merge_source_cte AS (SELECT 15 a, 'merge_source_cte val' b) -MERGE INTO m USING (select * from merge_source_cte) o ON m.k=o.a -WHEN MATCHED THEN UPDATE SET v = (SELECT b || merge_source_cte.*::text || ' merge update' FROM merge_source_cte WHERE a = 15) -WHEN NOT MATCHED THEN INSERT VALUES(o.a, o.b || (SELECT merge_source_cte.*::text || ' merge insert' FROM merge_source_cte)); - -DROP TABLE m; - -- check that run to completion happens in proper ordering TRUNCATE TABLE y; diff --git a/src/test/regress/sql/without_oid.sql b/src/test/regress/sql/without_oid.sql deleted file mode 100644 index 9fbb454d4dc..00000000000 --- a/src/test/regress/sql/without_oid.sql +++ /dev/null @@ -1,92 +0,0 @@ --- --- WITHOUT OID --- - --- --- This test tries to verify that WITHOUT OIDS actually saves space. --- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any --- space, depending on the size of the tuple header + null bitmap. --- As of 8.3 we need a null bitmap of 8 or less bits for the difference --- to appear. --- -CREATE TABLE wi (i INT, - n1 int, n2 int, n3 int, n4 int, - n5 int, n6 int, n7 int) WITH OIDS; -CREATE TABLE wo (i INT, - n1 int, n2 int, n3 int, n4 int, - n5 int, n6 int, n7 int) WITHOUT OIDS; - -INSERT INTO wi VALUES (1); -- 1 -INSERT INTO wo SELECT i FROM wi; -- 1 -INSERT INTO wo SELECT i+1 FROM wi; -- 1+1=2 -INSERT INTO wi SELECT i+1 FROM wo; -- 1+2=3 -INSERT INTO wi SELECT i+3 FROM wi; -- 3+3=6 -INSERT INTO wo SELECT i+2 FROM wi; -- 2+6=8 -INSERT INTO wo SELECT i+8 FROM wo; -- 8+8=16 -INSERT INTO wi SELECT i+6 FROM wo; -- 6+16=22 -INSERT INTO wi SELECT i+22 FROM wi; -- 22+22=44 -INSERT INTO wo SELECT i+16 FROM wi; -- 16+44=60 -INSERT INTO wo SELECT i+60 FROM wo; -- 60+60=120 -INSERT INTO wi SELECT i+44 FROM wo; -- 44+120=164 -INSERT INTO wi SELECT i+164 FROM wi; -- 164+164=328 -INSERT INTO wo SELECT i+120 FROM wi; -- 120+328=448 -INSERT INTO wo SELECT i+448 FROM wo; -- 448+448=896 -INSERT INTO wi SELECT i+328 FROM wo; -- 328+896=1224 -INSERT INTO wi SELECT i+1224 FROM wi; -- 1224+1224=2448 -INSERT INTO wo SELECT i+896 FROM wi; -- 896+2448=3344 -INSERT INTO wo SELECT i+3344 FROM wo; -- 3344+3344=6688 -INSERT INTO wi SELECT i+2448 FROM wo; -- 2448+6688=9136 -INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448; -- 6688+2448=9136 - -SELECT count(oid) FROM wi; --- should fail -SELECT count(oid) FROM wo; - -VACUUM ANALYZE wi; -VACUUM ANALYZE wo; - -SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples) - FROM pg_class - WHERE relname IN ('wi', 'wo'); - -DROP TABLE wi; -DROP TABLE wo; - --- --- WITH / WITHOUT OIDS in CREATE TABLE AS --- -CREATE TABLE create_table_test ( - a int, - b int -); - -COPY create_table_test FROM stdin; -5 10 -10 15 -\. - -CREATE TABLE create_table_test2 WITH OIDS AS - SELECT a + b AS c1, a - b AS c2 FROM create_table_test; - -CREATE TABLE create_table_test3 WITHOUT OIDS AS - SELECT a + b AS c1, a - b AS c2 FROM create_table_test; - -SELECT count(oid) FROM create_table_test2; --- should fail -SELECT count(oid) FROM create_table_test3; - -PREPARE table_source(int) AS - SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test; - -CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1); -CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2); - -SELECT count(oid) FROM execute_with; --- should fail -SELECT count(oid) FROM execute_without; - -DROP TABLE create_table_test; -DROP TABLE create_table_test2; -DROP TABLE create_table_test3; -DROP TABLE execute_with; -DROP TABLE execute_without; diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index cb96e180053..71431d8a556 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -149,10 +149,17 @@ PREPARE foo (xml) AS SELECT xmlconcat('', $1); SET XML OPTION DOCUMENT; EXECUTE foo (''); EXECUTE foo ('bad'); +SELECT xml ''; SET XML OPTION CONTENT; EXECUTE foo (''); EXECUTE foo ('good'); +SELECT xml ' '; +SELECT xml ' '; +SELECT xml ''; +SELECT xml ' oops '; +SELECT xml ' '; +SELECT xml ''; -- Test backwards parsing @@ -188,6 +195,7 @@ SELECT xpath('count(//*)=0', ''); SELECT xpath('count(//*)=3', ''); SELECT xpath('name(/*)', ''); SELECT xpath('/nosuchtag', ''); +SELECT xpath('root', ''); -- Round-trip non-ASCII data through xpath(). DO $$ @@ -349,7 +357,7 @@ SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -362,7 +370,7 @@ CREATE VIEW xmltableview1 AS SELECT xmltable.* PASSING data COLUMNS id int PATH '@id', _id FOR ORDINALITY, - country_name text PATH 'COUNTRY_NAME' NOT NULL, + country_name text PATH 'COUNTRY_NAME/text()' NOT NULL, country_id text PATH 'COUNTRY_ID', region_id int PATH 'REGION_ID', size float PATH 'SIZE', @@ -423,7 +431,7 @@ SELECT * FROM xmltable('/root' passing 'a1aa2aa1aa2a bbbbxxxcccc' COLUMNS element text PATH 'element/text()'); -- should fail -- CDATA test -select * from xmltable('r' passing ' &"<>!foo]]>2' columns c text); +select * from xmltable('d/r' passing ' &"<>!foo]]>2' columns c text); -- XML builtin entities SELECT * FROM xmltable('/x/a' PASSING ''"&<>' COLUMNS ent text); @@ -594,3 +602,11 @@ INSERT INTO xmltest2 VALUES('2', 'D'); SELECT xmltable.* FROM xmltest2, LATERAL xmltable('/d/r' PASSING x COLUMNS a int PATH '' || lower(_path) || 'c'); SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH '.'); SELECT xmltable.* FROM xmltest2, LATERAL xmltable(('/d/r/' || lower(_path) || 'c') PASSING x COLUMNS a int PATH 'x' DEFAULT ascii(_path) - 54); + +-- XPath result can be boolean or number too +SELECT * FROM XMLTABLE('*' PASSING 'a' COLUMNS a xml PATH '.', b text PATH '.', c text PATH '"hi"', d boolean PATH '. = "a"', e integer PATH 'string-length(.)'); +\x +SELECT * FROM XMLTABLE('*' PASSING 'pre&deeppost' COLUMNS x xml PATH 'node()', y xml PATH '/'); +\x + +SELECT * FROM XMLTABLE('.' PASSING XMLELEMENT(NAME a) columns a varchar(20) PATH '""', b xml PATH '""'); diff --git a/src/test/ssl/Makefile b/src/test/ssl/Makefile index df477f1d401..3b53972f6f4 100644 --- a/src/test/ssl/Makefile +++ b/src/test/ssl/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/ssl # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/ssl/Makefile @@ -32,14 +32,14 @@ SSLFILES := $(CERTIFICATES:%=ssl/%.key) $(CERTIFICATES:%=ssl/%.crt) \ # This target generates all the key and certificate files. sslfiles: $(SSLFILES) -# Openssl requires a directory to put all generated certificates in. We don't +# OpenSSL requires a directory to put all generated certificates in. We don't # use this for anything, but we need a location. ssl/new_certs_dir: mkdir ssl/new_certs_dir # Rule for creating private/public key pairs. ssl/%.key: - openssl genrsa -out $@ 1024 + openssl genrsa -out $@ 2048 chmod 0600 $@ # Root CA certificate @@ -136,6 +136,7 @@ sslfiles-clean: clean distclean maintainer-clean: rm -rf tmp_check + rm -rf ssl/*.old ssl/new_certs_dir ssl/client*_tmp.key check: $(prove_check) diff --git a/src/test/ssl/README b/src/test/ssl/README index 5e8bf641ba4..84baa478cef 100644 --- a/src/test/ssl/README +++ b/src/test/ssl/README @@ -7,20 +7,27 @@ This directory contains a test suite for SSL support. It tests both client-side functionality, i.e. verifying server certificates, and server-side functionality, i.e. certificate authorization. +CAUTION: The test server run by this test is configured to listen for +TCP connections on localhost. Any user on the same host is able to +log in to the test server while the tests are running. Do not run this +suite on a multi-user system where you don't trust all local users! + Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install". +In that case, the code in the installation tree is tested. With +"make check", a temporary installation tree is built from the current +sources and then tested. -NOTE: This creates a temporary installation (in the case of "check"), -and sets it up to listen for TCP connections on localhost. Any user on -the same host is allowed to log in to the test installation while the -tests are running. Do not run this suite on a multi-user system where -you don't trust all local users! +Either way, this test initializes, starts, and stops a test Postgres +cluster that is accessible to other local users! Certificates ============ diff --git a/src/test/ssl/cas.config b/src/test/ssl/cas.config index 013cebae166..8c0ef6d82b0 100644 --- a/src/test/ssl/cas.config +++ b/src/test/ssl/cas.config @@ -13,7 +13,7 @@ basicConstraints = CA:true dir = ./ssl/ database = ./ssl/root_ca-certindex serial = ./ssl/root_ca.srl -default_md = sha1 +default_md = sha256 default_days= 10000 default_crl_days= 10000 certificate = ./ssl/root_ca.crt @@ -26,7 +26,7 @@ email_in_dn = no [ server_ca ] dir = ./ssl/ database = ./ssl/server_ca-certindex -default_md = sha1 +default_md = sha256 default_days= 10000 default_crl_days= 10000 certificate = ./ssl/server_ca.crt @@ -42,7 +42,7 @@ crl = ./ssl/server.crl [ client_ca ] dir = ./ssl/ database = ./ssl/client_ca-certindex -default_md = sha1 +default_md = sha256 default_days= 10000 default_crl_days= 10000 certificate = ./ssl/client_ca.crt diff --git a/src/test/ssl/ssl/both-cas-1.crt b/src/test/ssl/ssl/both-cas-1.crt index 0e2a10a180e..37ffa10174b 100644 --- a/src/test/ssl/ssl/both-cas-1.crt +++ b/src/test/ssl/ssl/both-cas-1.crt @@ -1,40 +1,57 @@ -----BEGIN CERTIFICATE----- -MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV -BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0 -ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG -A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u -IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5 -qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8 -sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B -MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE -TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE -TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1 -K5Y= +MIIDHjCCAgagAwIBAgIUEAgXJ/ibw6TVTUoomlBsPMfVTlMwDQYJKoZIhvcNAQEL +BQAwQDE+MDwGA1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCBy +ZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYwNDE0MTM0 +MDU0WjBAMT4wPAYDVQQDDDVUZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NM +IHJlZ3Jlc3Npb24gdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALZ81vKKBJlxgjwuNoK67I4IE9zfSLb0eHbgZwZxDVzdmFejARrHlWk3 ++MK7Nav7RLSJ990am33zb58CTHc7YYVlBp07+PwLXzypqWkhYfok1OYYjyjCrFDs +sjcJI3hRCZNEz+wYsG+tdYWJ+gRPQOWfh0YfO2rFgXAIMLiF6lyWzf1eOM+OjYrF +/eyzwbMaJkkGa/AyZKz3wZiPq0jTuYLVmH4MK7MBOsUfSmsBsn/ohyRCQzM+ol0v +Qlsrulj8usponRPDh9ng4PB5OSgR79YimQZnASQzJxiUvMADrKL5L6KwLxJlzbqY +R0b5mLh8KBzBQmSh3Aj2e2I7Z17hdaMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQsFAAOCAQEASzA7ApbuKn8lkC706gRL37a33yTZZ8rjZ4dnvCtq +6OltlYDJ8IndotKbLH0SUEAxrvcaFnMt7AX9pRf2sGBKbY8zcxqPfsvzVehgx4Ea +1RYksFW4h97jj1a1RKukTKuEOEEipbxwo0rLxfjvdaf2izqchJsLGtbocIZf0bD8 +djbE9jOLkx7saL08qC8ECrf9utsee+LJCsUYbNgYyIItEy6yVnmF/ICz93Utn1cI +RfqZr1lM2Ia2LP9eDTmiuR9m+/MzkeRvvJHonNrRJHlcggtYHICvYioh9/jALBcm +wZ+hTUePVqy4hOCBJ975CXjfKFN4MKQAdeB3EO5eBYAD3Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+ -19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd -JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x -6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI -TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM -ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75x7yuQ1+gK8j +1aO6D2nGym2x2OFniztlnx4PlWWWivIrYlxy6xAhfrVdjwjc5mMtOCrVKllsdC+S +1EfqCZTu1+gF0SdG5cHuJ2Rtg4oisLSF221v/msPONAa1dObChWsJwme87VaFrL+ +B2yipfW1PUxM9a7/p19CRBcDQ+LNW+YFqwARByHGq1wfatJzpM8TXe+XEnRfW9KX +P3a5PqR6evFQOzjcAf+QBJ0hAEddUDhdYECbs1GrApfsEHBuwXabdCH41j0F/0yc +kctydWfBl2Vbmd3sfsFMHjde+SJhqxyq6xiSL59jnx4ZKmtn9VSOYbGmBCdBdYK7 +RTcnJQv9AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AB6zh/Jw+t232100Tztr7wJoKH8DL1hnSm3e7omdj0WlKfuZwTqDuMzB3H4LOSnS +A00XpyMAGAJC6yRjS8pt+pjY5Jt6ouSqf6wNq0mF0jiIDeg1k/GNEjigx+0ITqbE +lUJ56AcpoBNhOwBjOCRFh4JuspHZqHXgUNYTEicClbV+lZwoMIIK1e6FYRZDqMtL ++34GtZACImqvRkP5alqQg7hJUM1zbDVf2qebY4cfSu4OfTu6Og6KrL8Cu6bqR2et +0a/TbthHYz1QGDYRoVTSP4uWoG9M1ZbsA/bNE2eqcrQj+dJ4AmIIr8Yl8mrwo/FZ +SvgeLMlQY7UNwLUDtwy9QkI= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c -vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1 -37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w -mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB -paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO -cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiSnYZbmc9vpCt +Ku1sKV9l663JCceubhMw8Gg16kV0hXEFf/TgGC4zkiYNHN7+G45YD7Nq0kBCq3dH +t2wPCc6c8pQoI64dfprVqPkvzoe1WBpZNetkUTk20v08jNeRa7XdRbRR6we1s9VG +/prp8Hs2mmHqEfLuI9lvTT0Dz+VMmfFI8Lf278r+w+qOtVloAkX7AOyoLEJlNS0B +QW9YWdH9N5ctaUXMG6lLV2OAjs+W1smpKfpIpMCA1lPGlElu70hynon/nQQvBP77 +SfQpZVc0esM18jkZpr5LEKUCw+x6LaMsqmBHpAULfCffxn2r0uMBW4L4VaGg3W6F +h6iuJwRfAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AFlcKTaU/Ug3Q0hr3P1UQ6dWyK4aVn9rs4jvVfFl0a0RnbBowqK2C+zQVUWYTcjo +KHREVje65goj6VzRB6ko/9mAQ6PZP8jRuRhfCmvmvSQ/mWdgPzSRsUh9MwgEm9c2 +vNbqwaznEU8cYZnLpHiR9O5S7/qWWxehjYtxk5Eb4J006YglYfHnhrRFJvPbiqlf +IOEivZ7gIVfvaOTbLjmN2kLOnzdlwpXGjxxg4Nu9ZhXOhfrplzUvRfmqvVsDiHXb +USIdX+OFZZqr64IKG4drT4K4Bt2wupOEyX4ZFsUXXd+Hgq83SWmV4wzflcpmGkLC +JZ3CEMu8/WA5uQBXdQUozlE= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/both-cas-2.crt b/src/test/ssl/ssl/both-cas-2.crt index e857f8079b6..2f2723f2b1a 100644 --- a/src/test/ssl/ssl/both-cas-2.crt +++ b/src/test/ssl/ssl/both-cas-2.crt @@ -1,40 +1,57 @@ -----BEGIN CERTIFICATE----- -MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV -BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0 -ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG -A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u -IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5 -qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8 -sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B -MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE -TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE -TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1 -K5Y= +MIIDHjCCAgagAwIBAgIUEAgXJ/ibw6TVTUoomlBsPMfVTlMwDQYJKoZIhvcNAQEL +BQAwQDE+MDwGA1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCBy +ZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYwNDE0MTM0 +MDU0WjBAMT4wPAYDVQQDDDVUZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NM +IHJlZ3Jlc3Npb24gdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALZ81vKKBJlxgjwuNoK67I4IE9zfSLb0eHbgZwZxDVzdmFejARrHlWk3 ++MK7Nav7RLSJ990am33zb58CTHc7YYVlBp07+PwLXzypqWkhYfok1OYYjyjCrFDs +sjcJI3hRCZNEz+wYsG+tdYWJ+gRPQOWfh0YfO2rFgXAIMLiF6lyWzf1eOM+OjYrF +/eyzwbMaJkkGa/AyZKz3wZiPq0jTuYLVmH4MK7MBOsUfSmsBsn/ohyRCQzM+ol0v +Qlsrulj8usponRPDh9ng4PB5OSgR79YimQZnASQzJxiUvMADrKL5L6KwLxJlzbqY +R0b5mLh8KBzBQmSh3Aj2e2I7Z17hdaMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQsFAAOCAQEASzA7ApbuKn8lkC706gRL37a33yTZZ8rjZ4dnvCtq +6OltlYDJ8IndotKbLH0SUEAxrvcaFnMt7AX9pRf2sGBKbY8zcxqPfsvzVehgx4Ea +1RYksFW4h97jj1a1RKukTKuEOEEipbxwo0rLxfjvdaf2izqchJsLGtbocIZf0bD8 +djbE9jOLkx7saL08qC8ECrf9utsee+LJCsUYbNgYyIItEy6yVnmF/ICz93Utn1cI +RfqZr1lM2Ia2LP9eDTmiuR9m+/MzkeRvvJHonNrRJHlcggtYHICvYioh9/jALBcm +wZ+hTUePVqy4hOCBJ975CXjfKFN4MKQAdeB3EO5eBYAD3Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c -vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1 -37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w -mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB -paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO -cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiSnYZbmc9vpCt +Ku1sKV9l663JCceubhMw8Gg16kV0hXEFf/TgGC4zkiYNHN7+G45YD7Nq0kBCq3dH +t2wPCc6c8pQoI64dfprVqPkvzoe1WBpZNetkUTk20v08jNeRa7XdRbRR6we1s9VG +/prp8Hs2mmHqEfLuI9lvTT0Dz+VMmfFI8Lf278r+w+qOtVloAkX7AOyoLEJlNS0B +QW9YWdH9N5ctaUXMG6lLV2OAjs+W1smpKfpIpMCA1lPGlElu70hynon/nQQvBP77 +SfQpZVc0esM18jkZpr5LEKUCw+x6LaMsqmBHpAULfCffxn2r0uMBW4L4VaGg3W6F +h6iuJwRfAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AFlcKTaU/Ug3Q0hr3P1UQ6dWyK4aVn9rs4jvVfFl0a0RnbBowqK2C+zQVUWYTcjo +KHREVje65goj6VzRB6ko/9mAQ6PZP8jRuRhfCmvmvSQ/mWdgPzSRsUh9MwgEm9c2 +vNbqwaznEU8cYZnLpHiR9O5S7/qWWxehjYtxk5Eb4J006YglYfHnhrRFJvPbiqlf +IOEivZ7gIVfvaOTbLjmN2kLOnzdlwpXGjxxg4Nu9ZhXOhfrplzUvRfmqvVsDiHXb +USIdX+OFZZqr64IKG4drT4K4Bt2wupOEyX4ZFsUXXd+Hgq83SWmV4wzflcpmGkLC +JZ3CEMu8/WA5uQBXdQUozlE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+ -19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd -JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x -6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI -TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM -ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75x7yuQ1+gK8j +1aO6D2nGym2x2OFniztlnx4PlWWWivIrYlxy6xAhfrVdjwjc5mMtOCrVKllsdC+S +1EfqCZTu1+gF0SdG5cHuJ2Rtg4oisLSF221v/msPONAa1dObChWsJwme87VaFrL+ +B2yipfW1PUxM9a7/p19CRBcDQ+LNW+YFqwARByHGq1wfatJzpM8TXe+XEnRfW9KX +P3a5PqR6evFQOzjcAf+QBJ0hAEddUDhdYECbs1GrApfsEHBuwXabdCH41j0F/0yc +kctydWfBl2Vbmd3sfsFMHjde+SJhqxyq6xiSL59jnx4ZKmtn9VSOYbGmBCdBdYK7 +RTcnJQv9AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AB6zh/Jw+t232100Tztr7wJoKH8DL1hnSm3e7omdj0WlKfuZwTqDuMzB3H4LOSnS +A00XpyMAGAJC6yRjS8pt+pjY5Jt6ouSqf6wNq0mF0jiIDeg1k/GNEjigx+0ITqbE +lUJ56AcpoBNhOwBjOCRFh4JuspHZqHXgUNYTEicClbV+lZwoMIIK1e6FYRZDqMtL ++34GtZACImqvRkP5alqQg7hJUM1zbDVf2qebY4cfSu4OfTu6Og6KrL8Cu6bqR2et +0a/TbthHYz1QGDYRoVTSP4uWoG9M1ZbsA/bNE2eqcrQj+dJ4AmIIr8Yl8mrwo/FZ +SvgeLMlQY7UNwLUDtwy9QkI= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/client+client_ca.crt b/src/test/ssl/ssl/client+client_ca.crt index 3caada693de..2804527f3ee 100644 --- a/src/test/ssl/ssl/client+client_ca.crt +++ b/src/test/ssl/ssl/client+client_ca.crt @@ -1,25 +1,36 @@ -----BEGIN CERTIFICATE----- -MIIBxzCCATACAQEwDQYJKoZIhvcNAQEFBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +MIICzDCCAbQCAQEwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe -Fw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBYxFDASBgNVBAMMC3NzbHRl -c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDN3RFl8VWMEBN1Qas0 -w1CFcXdDEbKVNSPsqWHzHIEPoGJv+eUIBK2lQ/Ce8nRCdelO50RsmlbcXBIrjVl6 -BN0RmEeEVclgCdiamYN53LBdc5KWKpKCKn45lCtlZodWt0hNNx1pAmh85jDKpoO9 -ErbCnSU1wODPqnOzdkLU7jBu5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABUz+vnu -dD1Q1N/Ezs5DzJeQDtiJb9PNzBHAUPQoXeLvuITcDdyYWc18Yi4fX7gwyD42q2iu -1I0hmm2bNJfujsGbvGYFLuQ4hC2ucAAj2Gm681GhhaNYtfsfHYm9R8GRZFvp40oj -qXpkDkYsPdyVxUyoxJ+M0Ub5VC/k1pQNtIaq +Fw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBYxFDASBgNVBAMMC3NzbHRl +c3R1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtIugLqHywEAE +vyRZGMVAkdk1zCa5FFaPOEFhHiAMpwFOEIEi4Svk9kSSRecmeJcody1sLNoFqtTA +b5tYaDoGIVZfc8/kxm8sbsTE/3JOsON3CMqjOQkI1ZKjDSF1gtrGSmatgjqsMnlP +UJkFEsPhFg6NTf1ZUjFiQeWEli0fQJ2/k+7MI4S0t0pDJJJWrqF4l6eSgu8rsBoX +XHy4OLAz6j23r2k5FZs6H/poII95ia+E8hG8SrJmMa88naRdq7hHW802Z6lEhnRW +ND+tDGjt0ZaTfxx+CxN4UjgbboOJifTykVHjuzBR1+IzLHcxoZCLP1cjadSqMz5b +ziJTGtHzYwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAcIGps6BnsRxkN5sphg6GK +tzDvp2IUyOu5oeAHdJLT5JFZhKKzhDD4KiOv+XWzdHcSAl3xMqAqnFdSTCt2vtc+ +rk04eyVWJALyf6oPT60Vn5sFaaxlTg1+tnZMCCycDxM6lc/6onzgp6DUWGozlgSh +eNgCyaNU73VTuMgd+s/QrZ5HCr0OPAb3aWRQy7hVZeOniNBXWrO/CC2Swfwz7jU3 +dvLAWYENUvZlE2S7HnQGclGIJb38qFCnquuSgmO9yT30Lmmwp33k5/evN9cNQMxU +c4ChYCaabOGXUaBJNzJAYMEUHh+o+LPgFF2iB0mL7FAUip9XsjOiOwcrbusM/g+2 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+ -19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd -JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x -6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI -TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM -ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75x7yuQ1+gK8j +1aO6D2nGym2x2OFniztlnx4PlWWWivIrYlxy6xAhfrVdjwjc5mMtOCrVKllsdC+S +1EfqCZTu1+gF0SdG5cHuJ2Rtg4oisLSF221v/msPONAa1dObChWsJwme87VaFrL+ +B2yipfW1PUxM9a7/p19CRBcDQ+LNW+YFqwARByHGq1wfatJzpM8TXe+XEnRfW9KX +P3a5PqR6evFQOzjcAf+QBJ0hAEddUDhdYECbs1GrApfsEHBuwXabdCH41j0F/0yc +kctydWfBl2Vbmd3sfsFMHjde+SJhqxyq6xiSL59jnx4ZKmtn9VSOYbGmBCdBdYK7 +RTcnJQv9AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AB6zh/Jw+t232100Tztr7wJoKH8DL1hnSm3e7omdj0WlKfuZwTqDuMzB3H4LOSnS +A00XpyMAGAJC6yRjS8pt+pjY5Jt6ouSqf6wNq0mF0jiIDeg1k/GNEjigx+0ITqbE +lUJ56AcpoBNhOwBjOCRFh4JuspHZqHXgUNYTEicClbV+lZwoMIIK1e6FYRZDqMtL ++34GtZACImqvRkP5alqQg7hJUM1zbDVf2qebY4cfSu4OfTu6Og6KrL8Cu6bqR2et +0a/TbthHYz1QGDYRoVTSP4uWoG9M1ZbsA/bNE2eqcrQj+dJ4AmIIr8Yl8mrwo/FZ +SvgeLMlQY7UNwLUDtwy9QkI= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/client-revoked.crt b/src/test/ssl/ssl/client-revoked.crt index 8448e961254..14857a33a2f 100644 --- a/src/test/ssl/ssl/client-revoked.crt +++ b/src/test/ssl/ssl/client-revoked.crt @@ -1,12 +1,17 @@ -----BEGIN CERTIFICATE----- -MIIBxzCCATACAQIwDQYJKoZIhvcNAQEFBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +MIICzDCCAbQCAQIwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe -Fw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBYxFDASBgNVBAMMC3NzbHRl -c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKeycg+E5SBlaTxcus -Fps4yZnGVB78Kt/HQAZcmgiwWZxN0th9SsJVMw2VkwMPPm4o8idEF/PZvbz15DHk -MrNWSOMB8qsXlt3P8VMhKhWG025TbWpfXbNHKKqQqAc55i1SvQJvllrAYKOlpu/K -YQsIK/ZpjeTywcVi19B3aPE82wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAE3vuzMF -C5Ut6X981NjsuSlDptqDd8aQqO1HK7McEcH7Tjw6DU9ZPqw9Ktpz/wAJc2DvsmBM -QqlM+OtSkEncAdWx/xOzN46oHUNxrR2cXD1N/0HgVHJEUfq8p+oJHYXKVWtsjO7S -2/fZnMMO9Gv6e7eTiYE55R0IZrQENwtmIJ8y +Fw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBYxFDASBgNVBAMMC3NzbHRl +c3R1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoBcmY2Z+qa+l +UB5YSYnGLt96S7axkoDvIzLJkwJugGqw1U72A6lAUTyAPVntsmbhoMpDEHK6ylg8 +U4HC3L1hbhSpFriTITJ3TzH4+wdDH1KZYlM2k0gfrKrksJyZ7ftAyuBvzBRlFbBe +xopR9VQjqgAuNKByJswldOe0KwP0nmb/TtT9lkAt7XjrSut5MUezFVnvTxabm7tQ +ciDG+8QqE0b8lH3N3VOXWZWCeXPRrwboO3baAmcue4V20N0ALARP+QZNElBa7Jq+ +l77VNjneRk07jjaE7PCGVlWfPggppZos1Ay1sb2JhK0S9pZrynQT/ck3qhG4QuKp +cmn/Bbe/8wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBySTwOO9zSFCtfRjbbblDx +AK2ttILR0ZJXnvzjNjuErsT9qeXaq2t/iG/vmhH5XDjaefXFLCLqFunvcg6cIz1A +HhAw+JInfyk3TUpDaX6M0X8qj184e4kXzVc83Afa3LiP5JkirzCSv6ErqAHw2VVd +bZbZUwMfQLpWHVqXK89Pb7q791H4VeEx9CLxtZ2PSr2GCdpFbVMJvdBPChD2Re1A +ELcbMZ9iOq2AUN/gxrt7HnE3dRoGQk6AJOfvhi2eZcVWiLtITScdPk1nYcNxGid3 +BWW+tdLbjmSe2FXNfDwBTvuHh5A9S399X5l/nLAng2iTGSvIm1OgUnC2oWsok3EI -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/client-revoked.key b/src/test/ssl/ssl/client-revoked.key index b2321ca4dcc..a915c6fbd8c 100644 --- a/src/test/ssl/ssl/client-revoked.key +++ b/src/test/ssl/ssl/client-revoked.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDKeycg+E5SBlaTxcusFps4yZnGVB78Kt/HQAZcmgiwWZxN0th9 -SsJVMw2VkwMPPm4o8idEF/PZvbz15DHkMrNWSOMB8qsXlt3P8VMhKhWG025TbWpf -XbNHKKqQqAc55i1SvQJvllrAYKOlpu/KYQsIK/ZpjeTywcVi19B3aPE82wIDAQAB -AoGAKXV79pFBICRyF8HZSTw7vi3xUZ2p1oJE3bxrUQytGMbQbVLtxwHGtsFEV8sJ -RlbHIZUrmxK4eG4UQdjeqlYDSBsV4x/g4sqpgQAoE1J6TQ9D3at6LqnvUa6ObjQW -W/GczCkrQRkRTxwa35PSE2CcgNcoyUXRkF0DHhugPcOVjRkCQQD1jUQYgLoUKDbZ -mZ1odm2adDu4BMFTd3pyQBVZmetlPrLVr8iU6bHJGUWpaFkpv/jbOJfNgijqQ3i6 -vZRhyHgHAkEA0xi6XZITkzmLP7qEQsho9JX02Pqqpd4ZQOp6CZDY6TH45oOBK0Bn -+xsfGENexiqU2EFtIChesScVpzTuvq2XjQJBALB82HTEEPpr7QB5aKmsdRqOcF3T -DSDwvxFe/flop8gdSGxN690cGqxvfaJFXdCkKjlmc7VB2CaIWD3gBMZDUAECQQC8 -oUIXTurTCf6WSdLZ4j93H3CVWxiV8uraCSxX0+kgKBlj0mrf/UNtLQUSJ1FO/snW -nFApBinnXyeILFKSbIgZAkB74ahj70+NmAFfEcgN3FjcHOy81rsvN9tO4rC0/0nt -iYBz1jc4KBZdyQY1rgk2om9m+EC+mlJsxtgFNK3k/kRJ +MIIEpQIBAAKCAQEAoBcmY2Z+qa+lUB5YSYnGLt96S7axkoDvIzLJkwJugGqw1U72 +A6lAUTyAPVntsmbhoMpDEHK6ylg8U4HC3L1hbhSpFriTITJ3TzH4+wdDH1KZYlM2 +k0gfrKrksJyZ7ftAyuBvzBRlFbBexopR9VQjqgAuNKByJswldOe0KwP0nmb/TtT9 +lkAt7XjrSut5MUezFVnvTxabm7tQciDG+8QqE0b8lH3N3VOXWZWCeXPRrwboO3ba +Amcue4V20N0ALARP+QZNElBa7Jq+l77VNjneRk07jjaE7PCGVlWfPggppZos1Ay1 +sb2JhK0S9pZrynQT/ck3qhG4QuKpcmn/Bbe/8wIDAQABAoIBAQCVmUx8MrlGZCa9 +Gb4y6hZSku87dXu2hdnyMHGBeRI92nVov6LRhQXfZAQKUND4l39cu+WzpyK6F344 +ItgvYqF7Nr9TxiNnMDuhu/cIzZ6B1LQU1+H1+73toryV9aE6bEH904FlWeGkRO4r +5fH0qS2ynPyQnSZO7xJJjoQkdkvPAMId7ovA5kKRLqRbXORGkbHhDdzoBB5ogRmV +CInIfO7mI85OJXXtggPNb7L9Tmb39/i+D/pagIWehzb9WOSnMnJ6//ORkEntqEOl +yaalJVF7uhiQbMcqA+ZJN9WwQPeLOeYowGD48cCsdjCgOhxM0EVWhtkDoC5MeZSz +0XQ7vrwxAoGBANFVznbReMP914AtDDY3ISrtsU3AZVuTpfi19+jogTOHZakt0ntt +Ztaymh0CBcE1DSbSdPLLtVpyhkvfmZRRIzv48xV2LHRibVkx5hncXQRrm+85B2vh +PMJ1/CO5Rky6DOq6RXWEbHKv56ZPUKeaokJsusUgafKkM8DpWDz5Re6VAoGBAMPH +FBRrTIL6N8vv4IRmCBk8axmAtbAKOcSghSLtGi8oX4wgL0nltoW28aE4uNiLb7Dh +vDOqluhc6ejaI6tCSo1+f1JSsiCvieFfRR76I0AQCGtdKZTu7hfxT+GQURm09iYX +T06VqIfpTOgQ6O6ArYSF+nF1DxrzUJdVpywxqzpnAoGBANAiWaMHyORN2lul7pNl +IwQ0yuo8lkqENixgePpJWlTqlWitl66C6xIjCFo5LZGZdtcXv5G8ezdP0TlVO7Ud +K0Qw1TiMg8zAJGrf0yH5WT7Q43zqHffkPe43Mxgt2bjl73ve8rrSjKVHQrK3/8B1 +XklfJCBlhxHqs05mdAZD7oU1AoGAeD6BurjcWWXNd1hxkWAJgVZ2gUdoUCM3r+jX +XMg72NL3PF1YLg8Et8PRTLBF99pMU1uR+DnCTh0jHX09gyZIG/ehw7I+7YxjJyUY +kxoXJHW0dhzWOT82xUXVRjkZVqyqsmKGt0F8LV3BepdIOZSW/lo7pAu9p1PiH9Df +yGkJPekCgYEAneTtCsznABsSw/5E2kq3fWQWZ+N9IIHQCNor4YnEWLiTe7Btexqv ++joMPnKWCZ9DqzgltmcNN4r/2nkNdJ9KJwlwkp6bKl9AnDSdSWuXUsxB8pecGylo +cD4WMBUQqd2IEI8678Pr9fOHA97YzTF87HfBGcsW/g25dzfOfb8A0YE= -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/client.crl b/src/test/ssl/ssl/client.crl index 72ed9e6d61d..a667680e04d 100644 --- a/src/test/ssl/ssl/client.crl +++ b/src/test/ssl/ssl/client.crl @@ -1,9 +1,11 @@ -----BEGIN X509 CRL----- -MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ -b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNjA5 -MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBAhcNMTYwOTEyMTYzMDAxWjAN -BgkqhkiG9w0BAQUFAAOBgQAyiU3V6ci5JR5oAZjlG7yFBhVO2TFLga5FynwHK5Wd -ML0BA/0TtTXFiPoul+zvOdqwpX8GC3IuxqgJzlxWOxl5mZzyKEtheT9RBwvBmjAe -ZjT7bFttKo/WKpztNE/2ZEDYyN87Xlpcm5UBFNhcYUjQkxuWIEvH4VOPm0iFjzm4 -tA== +MIIBnjCBhzANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ +b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xODEx +MjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBQwEgIBAhcNMTgxMTI3MTM0MDU1WjAN +BgkqhkiG9w0BAQsFAAOCAQEAXjLxA9Qc6gAudwUHBxMIq5EHBcuNEX5e3GNlkyNf +8I0DtHTPfJPvmAG+i6lYz//hHmmjxK0dR2ucg79XgXI/6OpDqlxS/TG1Xv52wA1p +xz6GaJ2hC8Lk4/vbJo/Rrzme2QsI7xqBWya0JWVrehttqhFxPzWA5wID8X7G4Kb4 +pjVnzqYzn8A9FBiV9t10oZg60aVLqt3kbyy+U3pefvjhj8NmQc7uyuVjWvYZA0vG +nnDUo4EKJzHNIYLk+EfpzKWO2XAWBLOT9SyyNCeMuQ5p/2pdAt9jtWHenms2ajo9 +2iUsHS91e3TooP9yNYuNcN8/wXY6H2Xm+dCLcEnkcr7EEw== -----END X509 CRL----- diff --git a/src/test/ssl/ssl/client.crt b/src/test/ssl/ssl/client.crt index 33d57ce0bab..4d0a6ef419c 100644 --- a/src/test/ssl/ssl/client.crt +++ b/src/test/ssl/ssl/client.crt @@ -1,12 +1,17 @@ -----BEGIN CERTIFICATE----- -MIIBxzCCATACAQEwDQYJKoZIhvcNAQEFBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +MIICzDCCAbQCAQEwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IGNsaWVudCBjZXJ0czAe -Fw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBYxFDASBgNVBAMMC3NzbHRl -c3R1c2VyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDN3RFl8VWMEBN1Qas0 -w1CFcXdDEbKVNSPsqWHzHIEPoGJv+eUIBK2lQ/Ce8nRCdelO50RsmlbcXBIrjVl6 -BN0RmEeEVclgCdiamYN53LBdc5KWKpKCKn45lCtlZodWt0hNNx1pAmh85jDKpoO9 -ErbCnSU1wODPqnOzdkLU7jBu5QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABUz+vnu -dD1Q1N/Ezs5DzJeQDtiJb9PNzBHAUPQoXeLvuITcDdyYWc18Yi4fX7gwyD42q2iu -1I0hmm2bNJfujsGbvGYFLuQ4hC2ucAAj2Gm681GhhaNYtfsfHYm9R8GRZFvp40oj -qXpkDkYsPdyVxUyoxJ+M0Ub5VC/k1pQNtIaq +Fw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBYxFDASBgNVBAMMC3NzbHRl +c3R1c2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtIugLqHywEAE +vyRZGMVAkdk1zCa5FFaPOEFhHiAMpwFOEIEi4Svk9kSSRecmeJcody1sLNoFqtTA +b5tYaDoGIVZfc8/kxm8sbsTE/3JOsON3CMqjOQkI1ZKjDSF1gtrGSmatgjqsMnlP +UJkFEsPhFg6NTf1ZUjFiQeWEli0fQJ2/k+7MI4S0t0pDJJJWrqF4l6eSgu8rsBoX +XHy4OLAz6j23r2k5FZs6H/poII95ia+E8hG8SrJmMa88naRdq7hHW802Z6lEhnRW +ND+tDGjt0ZaTfxx+CxN4UjgbboOJifTykVHjuzBR1+IzLHcxoZCLP1cjadSqMz5b +ziJTGtHzYwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAcIGps6BnsRxkN5sphg6GK +tzDvp2IUyOu5oeAHdJLT5JFZhKKzhDD4KiOv+XWzdHcSAl3xMqAqnFdSTCt2vtc+ +rk04eyVWJALyf6oPT60Vn5sFaaxlTg1+tnZMCCycDxM6lc/6onzgp6DUWGozlgSh +eNgCyaNU73VTuMgd+s/QrZ5HCr0OPAb3aWRQy7hVZeOniNBXWrO/CC2Swfwz7jU3 +dvLAWYENUvZlE2S7HnQGclGIJb38qFCnquuSgmO9yT30Lmmwp33k5/evN9cNQMxU +c4ChYCaabOGXUaBJNzJAYMEUHh+o+LPgFF2iB0mL7FAUip9XsjOiOwcrbusM/g+2 -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/client.key b/src/test/ssl/ssl/client.key index 4400c8ede5e..21e1e9f4546 100644 --- a/src/test/ssl/ssl/client.key +++ b/src/test/ssl/ssl/client.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQDN3RFl8VWMEBN1Qas0w1CFcXdDEbKVNSPsqWHzHIEPoGJv+eUI -BK2lQ/Ce8nRCdelO50RsmlbcXBIrjVl6BN0RmEeEVclgCdiamYN53LBdc5KWKpKC -Kn45lCtlZodWt0hNNx1pAmh85jDKpoO9ErbCnSU1wODPqnOzdkLU7jBu5QIDAQAB -AoGBAMFEdSwGuTCoewwPXcNIRpUxJC1ENStdW1+42atarFPWV/QWYI35jmhkc0dW -Cg3HEwUvm452C2wPyEM5DbK/VCacUkcvcA1taPnNjaw4qUjxRnsVCMhIZp0sCKEW -N1LZhBcc9ThGyOvirRZfk3URqtW58nDqTKZeKZQr/d4DkNz1AkEA7QrHDZUdtdQw -znG+8gsby7hK6+4h3F7ICD+RfUVAHEdSC2L59YsEH03d/kr62t1YOxdlMmCYK9sO -7bthNibwhwJBAN5T8BDD1eRukPPGu602uAPRCfOgx6uoUGL78jTXUYGOiVG/fxkt -EIr3m4G7KKj7LKipX8eowsCVC+Fj/3+SXDMCQAnzPN3OF5wtVwsjbS991eHcT5DN -wzAb7muiN3o5sPI+8Cu4MOPkvPyPaTUmcpdDWVPJrJ7LvTeCD4NdLTx3r/sCQEsV -g+zVhoX4BUIe6sELyseXMEo0EVrapBNZzSmlUiRz89JE3vKssnqMNttwTsIK2cE4 -Ol2ek+8gJvv+nooB7tsCQCu8ZYH75hVZGONfviwHk1RD5DegNZ6pT1Or4g9N23cj -YbP58Lvi4tiQqG6zKMCosWFoDsiKKIH9qQkrygSCn3o= +MIIEowIBAAKCAQEAtIugLqHywEAEvyRZGMVAkdk1zCa5FFaPOEFhHiAMpwFOEIEi +4Svk9kSSRecmeJcody1sLNoFqtTAb5tYaDoGIVZfc8/kxm8sbsTE/3JOsON3CMqj +OQkI1ZKjDSF1gtrGSmatgjqsMnlPUJkFEsPhFg6NTf1ZUjFiQeWEli0fQJ2/k+7M +I4S0t0pDJJJWrqF4l6eSgu8rsBoXXHy4OLAz6j23r2k5FZs6H/poII95ia+E8hG8 +SrJmMa88naRdq7hHW802Z6lEhnRWND+tDGjt0ZaTfxx+CxN4UjgbboOJifTykVHj +uzBR1+IzLHcxoZCLP1cjadSqMz5bziJTGtHzYwIDAQABAoIBAA7mqzzODvwBDKM9 ++8CInzCqbb9AvuvHzSBGfR6AZKrv96JzFg7hkY8lz7DHSCyRxTw42oHFKMyVrKBJ +gP1xNIpR16T2VppuGIu33855f7cnvu5R0zDk5v7BkIWH6mv3ZIBFgzKJZybvTjWH +u5x14EDyyITUUSfwfXyU1eGTLc4mU01g4kArSDy7dqWi9xrixfaiTH+bbfmoE96v +6kiwICZuoYaBLwOi9e7iHenhpF9X+BHNgt+x4dO5FSTtb15G96CnTM1U8xN2rf6y +pfwkWH0NoeeTvuGvzfFgQMVxk/72VtM21rntGA4z6ig7xHKZLJ2mFSb29/uISZKv +P1igV5ECgYEA6J2J5vPYLpXGmwthICaPiVSShUfZpZ05w+/p5KmFwtuyENSTtD+0 +nr/TY3mQNqecDTZsN5lillqnlZcAXVFce9A6iyQuIYz1FwO6K+mQLDshl7sXRNrK +AeThubltaieOtSXbeji8kmmEK95tO//Y7DNjLVn8gZ4Q2hOT97e8hCsCgYEAxrIK +/RWqU94JuGwJFzUDpgaJYQG5rcc+J0cZejjFl5ppY0+DPMNBKrGaObUrXAPmWBS9 +Gm4qBN3Zd1F8qEnHF+dw5vZY5hcvANcKRqXiPUkdzmpBNtlb/E+bGIEmhlh96gxN +AKQEPh2UM+Gc4eDfFUgfLnmqTLfPOSzpCXejmakCgYEAyZVMnoKOw8A0PsSbxNrl +5OMPnsTnTmh0WOKeVPS74GO3anJuFfRnOHOQY1JDsbmKuMCDA6O/FgE13aLgQ/5w +ITQQp+gQui6Hbwxh2BAuSsZrlCwkPB1GlmGdY+/Xa/kf6MgH7WEhudgLHGFDVI2h +lP/rYK/s7P7oJ7RztGbbzcUCgYBzZ9wMDXZlyfRZYp6RFSCuYOOQLYFcVvpZs+kv +XSQfHveRUBCIzVvfYVKTrA+oHTe/9yOy40OSmgyCShkeYeO6lZm0/Ga8FcEeOshk +KltSf1JJntuL8QmFbfNGc1Ud+O4Bb+2Vrq4sKd/3llYZuBO6d65svwvUDXrV2ajs +78ldKQKBgAZROsYDYkdwBJmKCipRAwp7qS67zUpGSzjnDdswa0S6ECMcbx46qhcc +IvFx/2rjLDIZUVjXkt/U9phWIAq/xMd0Euk+zvIdMmiaJeAmT8DzxVyM4iHGWbuY +qWpoSLJe8d+xDrHkQZHh+Pb4CpJwRNs3c0MGY3+i/PPTjxq4em8p -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/client_ca.crt b/src/test/ssl/ssl/client_ca.crt index 6507bc5f072..1ef37712610 100644 --- a/src/test/ssl/ssl/client_ca.crt +++ b/src/test/ssl/ssl/client_ca.crt @@ -1,13 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+ -19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd -JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x -6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI -TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM -ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75x7yuQ1+gK8j +1aO6D2nGym2x2OFniztlnx4PlWWWivIrYlxy6xAhfrVdjwjc5mMtOCrVKllsdC+S +1EfqCZTu1+gF0SdG5cHuJ2Rtg4oisLSF221v/msPONAa1dObChWsJwme87VaFrL+ +B2yipfW1PUxM9a7/p19CRBcDQ+LNW+YFqwARByHGq1wfatJzpM8TXe+XEnRfW9KX +P3a5PqR6evFQOzjcAf+QBJ0hAEddUDhdYECbs1GrApfsEHBuwXabdCH41j0F/0yc +kctydWfBl2Vbmd3sfsFMHjde+SJhqxyq6xiSL59jnx4ZKmtn9VSOYbGmBCdBdYK7 +RTcnJQv9AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AB6zh/Jw+t232100Tztr7wJoKH8DL1hnSm3e7omdj0WlKfuZwTqDuMzB3H4LOSnS +A00XpyMAGAJC6yRjS8pt+pjY5Jt6ouSqf6wNq0mF0jiIDeg1k/GNEjigx+0ITqbE +lUJ56AcpoBNhOwBjOCRFh4JuspHZqHXgUNYTEicClbV+lZwoMIIK1e6FYRZDqMtL ++34GtZACImqvRkP5alqQg7hJUM1zbDVf2qebY4cfSu4OfTu6Og6KrL8Cu6bqR2et +0a/TbthHYz1QGDYRoVTSP4uWoG9M1ZbsA/bNE2eqcrQj+dJ4AmIIr8Yl8mrwo/FZ +SvgeLMlQY7UNwLUDtwy9QkI= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/client_ca.key b/src/test/ssl/ssl/client_ca.key index 0e6c4649cfc..f79ea972474 100644 --- a/src/test/ssl/ssl/client_ca.key +++ b/src/test/ssl/ssl/client_ca.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDCNjF1km/E2Zwi1TWCftfW+J6MUZmkdVts1MZeGkzH4j7fXCtO -pTWN/RDwX45m+4Y8Q++sPHy6Ff2mdIDoHSVxUWbyIO0sjO0FRZmtACQCGWsnrPm2 -taHRJgRIt+/INJi64wi6mbQVR37ycS/+sev35UkwJ//tPb7RC77y1gXj2QIDAQAB -AoGALo7NVpEvaDJ+wr74H/uGhMt/PsZFHe7gZvuvPlnxtC1hwywWWbkzWIGlcOqH -edqseIAU0eaCRB4He8MMMBjko5WZcPRrE6mR0ZqtcTSIsg2dRkXJeSbY0A8ZPLjU -xw0RiNPRwcr0zgImzMCR5dVuKOgnAGDRZiDwWefF0g6pRYECQQDwXJyT/E5EKOBY -U4tioFMVypbYlyLXjvhKIFL6wdNAVIOa0LQ+X6cPBZRIM6q+eUjodHWnjf9uFX1i -4mjegCwJAkEAztjruKRIoHAk6zQtSEv2vJhObeXg0gAHWRuCmivS/9NtqrEyGGpl -V0YCe3T257Mrw7A0TgBf7lojkrSnOT+NUQJBAM4Fs7gstTE7EEDlKz4YSd8NzQpN -UXIOe8eduUJyTI6BYmSaq0QjXOBFWfohPyMQdmu5FvfNgLls9hKCGn1Mw3ECQCMQ -tvU4NG+uUzPkRoDpD8zs7O7Id5JiGtzKQxurrjtcNk0neNyWvNNMtQME0w54W0Tz -TAqlGZ4ofbtTEL4tveECQQCFl7OS+Emv0kvUCUm4QQ/xR9bjZ80lRdRn0AwXPiPz -zzYjV0OILDlMip+WrleC99v6R2M6BJrSPQr08oxeIUzy +MIIEpQIBAAKCAQEAu+ce8rkNfoCvI9Wjug9pxsptsdjhZ4s7ZZ8eD5VlloryK2Jc +cusQIX61XY8I3OZjLTgq1SpZbHQvktRH6gmU7tfoBdEnRuXB7idkbYOKIrC0hdtt +b/5rDzjQGtXTmwoVrCcJnvO1Whay/gdsoqX1tT1MTPWu/6dfQkQXA0PizVvmBasA +EQchxqtcH2rSc6TPE13vlxJ0X1vSlz92uT6kenrxUDs43AH/kASdIQBHXVA4XWBA +m7NRqwKX7BBwbsF2m3Qh+NY9Bf9MnJHLcnVnwZdlW5nd7H7BTB43XvkiYascqusY +ki+fY58eGSprZ/VUjmGxpgQnQXWCu0U3JyUL/QIDAQABAoIBAD4TfcrsTcP0GWg6 +RSvLucM9zv2JS/YcLlRFO/YkAfq5DoY8qZQhiiO2q44sGd54kl03CBeCNSa6P5k/ +Xj64SaaaV4HMdjBa6TWXd/siELmjLRBnzIDKSW4u87lZ2N2IeF52SxxjIQ+RHjME +GuSk9UaZ6KIoLFczYSoQOpYOkFgNKdu0RcxGG+fM+AQMtCP/KjL61suBxeoLG+Cs +kAB7EUsSbX+PsOy3V9l9n62F/NDPQBuNgwAMOF2qOXnMTsDHTkxlkka8CIHZeRLX +VBifO6bf2TCpAQ9+cH+lmfXtOWYExvZvgGeMB9WE8gXSxOnSD0uqxSLgCAwr8sM1 +6TDitIECgYEA7K/p0efjOaw9/+hAJniXS+RQ90WXTkq3asIR+NDvpig2jIJAQ9Lx +ngGQ86PlEIL53O7Ol4Av4589pmSAD1Q5dEXsXOcDod0mx0nidAp/C//fhyfX7xR2 +irIWDxKKuCc4xbiVWNGeXXC0cJufY2b6gbgpSfwC/i5CUlGzkLdoGKECgYEAyzwq +g4jtU0O90wKl6REQuepCMTL6+/E6sFDl7OXxZdmeeTyLLgWevAwHOQeOhGuX9RMO +ZYPngLSbrSC40o2i9369AUkJa0Meabji4fir7GvYzwarq/xHQjMvpGV13DVKEUoQ +JLdZ9uJRih2tVeqlCiD1abCu3eVh2+Sc17iWKd0CgYEA13g19p+R3lkNgEDg1aUG +p1JM2y8BVYbzfz75uXgME0mcj0GsW5JX364xVXwo9mUmLplAfe92qVO4fhgT9OCK +BW36hYDRb7Oyr851V4qOqk/gIFyHWeFZIV6KcmJA4vDh4C3v2BHMh+gofDNQYN/I +wfrzq6S+3MMkIWi7fc1Z+MECgYEApv4nCLGIIDS3Ux0H6nwFPF5KSVbUeBP830d5 +xbAjLEcmOgQPcJ9ZkLZpcOjOp+wojk08NRmvLUg56oXKl+edkrNm5hl3TdV2tfQf +KQJFchwjp+iZQtYmTzTz3qcnsutukspCfYjSuVO5ID3GYaROPAZc4J028kk6oY41 +eePIL1kCgYEA1ghHZmNhhsjxrkfWFME/nSWFazyEx1XmMagmvXw9rlrnBPFdtLsU +ZfFHM5gVaW/JMql0OGDjMSwc3fEEH8wd1eLXVxfCVLzvk8XVe81ahthMpndii813 +Cspl0AS9jpOkQK8JTZ38YAIqIr7H057veqAY+TbvIAdxoh+7DyW/aBs= -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/root+client.crl b/src/test/ssl/ssl/root+client.crl index e90d4b91934..854d77b71e4 100644 --- a/src/test/ssl/ssl/root+client.crl +++ b/src/test/ssl/ssl/root+client.crl @@ -1,17 +1,22 @@ -----BEGIN X509 CRL----- -MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm -b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx -NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG -0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk -+4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F -yaKadxocukmCcbxXdiDZePFpf7TfuoIm +MIIBhTBvMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xODExMjcx +MzQwNTVaFw00NjA0MTQxMzQwNTVaMA0GCSqGSIb3DQEBCwUAA4IBAQB8OSDym4/a +qbZOrZvOOhmKrd7AJSTgAadtdK0CX3v58Ym3EmZK7gQFdBuFCXnvbue/x6avZHgz +4pYFlJmL0IiD4QuTzsoo+LzifrmTzteO9oEJNLd2bjfEnpE5Wdaw6Yuy2Xb5edy5 +lQhNZdc8w3FiXhPOEUAi7EbdfDwn4G/fvEjpzyVb2wCujDUUePUGGayjKIM4PUu4 +pixM6gt9FFL27l47lQ3g0PbvB3TnU3oqcB3Y17FjbxjFc6AsGXholNetoEE2/49E +PEYzOH7/PtxlZUtoCqZM+741LuI6Q7z4/P2X/IY33lMy6Iiyc41C94l/P7fCkMLG +AlO+O0a4SpYS -----END X509 CRL----- -----BEGIN X509 CRL----- -MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ -b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xNjA5 -MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBAhcNMTYwOTEyMTYzMDAxWjAN -BgkqhkiG9w0BAQUFAAOBgQAyiU3V6ci5JR5oAZjlG7yFBhVO2TFLga5FynwHK5Wd -ML0BA/0TtTXFiPoul+zvOdqwpX8GC3IuxqgJzlxWOxl5mZzyKEtheT9RBwvBmjAe -ZjT7bFttKo/WKpztNE/2ZEDYyN87Xlpcm5UBFNhcYUjQkxuWIEvH4VOPm0iFjzm4 -tA== +MIIBnjCBhzANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ +b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3QgY2xpZW50IGNlcnRzFw0xODEx +MjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBQwEgIBAhcNMTgxMTI3MTM0MDU1WjAN +BgkqhkiG9w0BAQsFAAOCAQEAXjLxA9Qc6gAudwUHBxMIq5EHBcuNEX5e3GNlkyNf +8I0DtHTPfJPvmAG+i6lYz//hHmmjxK0dR2ucg79XgXI/6OpDqlxS/TG1Xv52wA1p +xz6GaJ2hC8Lk4/vbJo/Rrzme2QsI7xqBWya0JWVrehttqhFxPzWA5wID8X7G4Kb4 +pjVnzqYzn8A9FBiV9t10oZg60aVLqt3kbyy+U3pefvjhj8NmQc7uyuVjWvYZA0vG +nnDUo4EKJzHNIYLk+EfpzKWO2XAWBLOT9SyyNCeMuQ5p/2pdAt9jtWHenms2ajo9 +2iUsHS91e3TooP9yNYuNcN8/wXY6H2Xm+dCLcEnkcr7EEw== -----END X509 CRL----- diff --git a/src/test/ssl/ssl/root+client_ca.crt b/src/test/ssl/ssl/root+client_ca.crt index 35dfac28286..1867cd9c313 100644 --- a/src/test/ssl/ssl/root+client_ca.crt +++ b/src/test/ssl/ssl/root+client_ca.crt @@ -1,27 +1,38 @@ -----BEGIN CERTIFICATE----- -MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV -BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0 -ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG -A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u -IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5 -qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8 -sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B -MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE -TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE -TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1 -K5Y= +MIIDHjCCAgagAwIBAgIUEAgXJ/ibw6TVTUoomlBsPMfVTlMwDQYJKoZIhvcNAQEL +BQAwQDE+MDwGA1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCBy +ZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYwNDE0MTM0 +MDU0WjBAMT4wPAYDVQQDDDVUZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NM +IHJlZ3Jlc3Npb24gdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALZ81vKKBJlxgjwuNoK67I4IE9zfSLb0eHbgZwZxDVzdmFejARrHlWk3 ++MK7Nav7RLSJ990am33zb58CTHc7YYVlBp07+PwLXzypqWkhYfok1OYYjyjCrFDs +sjcJI3hRCZNEz+wYsG+tdYWJ+gRPQOWfh0YfO2rFgXAIMLiF6lyWzf1eOM+OjYrF +/eyzwbMaJkkGa/AyZKz3wZiPq0jTuYLVmH4MK7MBOsUfSmsBsn/ohyRCQzM+ol0v +Qlsrulj8usponRPDh9ng4PB5OSgR79YimQZnASQzJxiUvMADrKL5L6KwLxJlzbqY +R0b5mLh8KBzBQmSh3Aj2e2I7Z17hdaMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQsFAAOCAQEASzA7ApbuKn8lkC706gRL37a33yTZZ8rjZ4dnvCtq +6OltlYDJ8IndotKbLH0SUEAxrvcaFnMt7AX9pRf2sGBKbY8zcxqPfsvzVehgx4Ea +1RYksFW4h97jj1a1RKukTKuEOEEipbxwo0rLxfjvdaf2izqchJsLGtbocIZf0bD8 +djbE9jOLkx7saL08qC8ECrf9utsee+LJCsUYbNgYyIItEy6yVnmF/ICz93Utn1cI +RfqZr1lM2Ia2LP9eDTmiuR9m+/MzkeRvvJHonNrRJHlcggtYHICvYioh9/jALBcm +wZ+hTUePVqy4hOCBJ975CXjfKFN4MKQAdeB3EO5eBYAD3Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBjbGllbnQg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMI2MXWSb8TZnCLVNYJ+ -19b4noxRmaR1W2zUxl4aTMfiPt9cK06lNY39EPBfjmb7hjxD76w8fLoV/aZ0gOgd -JXFRZvIg7SyM7QVFma0AJAIZayes+ba1odEmBEi378g0mLrjCLqZtBVHfvJxL/6x -6/flSTAn/+09vtELvvLWBePZAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAlGC24V2TsiSlo9RIboBZTZqd0raUpKkmVbkwKyqcmecoFfCI -TCmoyJLYyUL5/e3dtn/cGDcaqxaO3qxnstxVEMSrlCGfZdZJ2oouXZMpDy9CkeOM -ypCCx9pc4EmP3mvu64f21+dNCXlhM36pZ1IokeS5jk2FIHUda+m5jlk5o6I= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC75x7yuQ1+gK8j +1aO6D2nGym2x2OFniztlnx4PlWWWivIrYlxy6xAhfrVdjwjc5mMtOCrVKllsdC+S +1EfqCZTu1+gF0SdG5cHuJ2Rtg4oisLSF221v/msPONAa1dObChWsJwme87VaFrL+ +B2yipfW1PUxM9a7/p19CRBcDQ+LNW+YFqwARByHGq1wfatJzpM8TXe+XEnRfW9KX +P3a5PqR6evFQOzjcAf+QBJ0hAEddUDhdYECbs1GrApfsEHBuwXabdCH41j0F/0yc +kctydWfBl2Vbmd3sfsFMHjde+SJhqxyq6xiSL59jnx4ZKmtn9VSOYbGmBCdBdYK7 +RTcnJQv9AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AB6zh/Jw+t232100Tztr7wJoKH8DL1hnSm3e7omdj0WlKfuZwTqDuMzB3H4LOSnS +A00XpyMAGAJC6yRjS8pt+pjY5Jt6ouSqf6wNq0mF0jiIDeg1k/GNEjigx+0ITqbE +lUJ56AcpoBNhOwBjOCRFh4JuspHZqHXgUNYTEicClbV+lZwoMIIK1e6FYRZDqMtL ++34GtZACImqvRkP5alqQg7hJUM1zbDVf2qebY4cfSu4OfTu6Og6KrL8Cu6bqR2et +0a/TbthHYz1QGDYRoVTSP4uWoG9M1ZbsA/bNE2eqcrQj+dJ4AmIIr8Yl8mrwo/FZ +SvgeLMlQY7UNwLUDtwy9QkI= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/root+server.crl b/src/test/ssl/ssl/root+server.crl index 096b48ccd10..9720b3023c0 100644 --- a/src/test/ssl/ssl/root+server.crl +++ b/src/test/ssl/ssl/root+server.crl @@ -1,17 +1,22 @@ -----BEGIN X509 CRL----- -MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm -b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx -NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG -0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk -+4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F -yaKadxocukmCcbxXdiDZePFpf7TfuoIm +MIIBhTBvMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xODExMjcx +MzQwNTVaFw00NjA0MTQxMzQwNTVaMA0GCSqGSIb3DQEBCwUAA4IBAQB8OSDym4/a +qbZOrZvOOhmKrd7AJSTgAadtdK0CX3v58Ym3EmZK7gQFdBuFCXnvbue/x6avZHgz +4pYFlJmL0IiD4QuTzsoo+LzifrmTzteO9oEJNLd2bjfEnpE5Wdaw6Yuy2Xb5edy5 +lQhNZdc8w3FiXhPOEUAi7EbdfDwn4G/fvEjpzyVb2wCujDUUePUGGayjKIM4PUu4 +pixM6gt9FFL27l47lQ3g0PbvB3TnU3oqcB3Y17FjbxjFc6AsGXholNetoEE2/49E +PEYzOH7/PtxlZUtoCqZM+741LuI6Q7z4/P2X/IY33lMy6Iiyc41C94l/P7fCkMLG +AlO+O0a4SpYS -----END X509 CRL----- -----BEGIN X509 CRL----- -MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ -b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNjA5 -MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBBhcNMTYwOTEyMTYzMDAxWjAN -BgkqhkiG9w0BAQUFAAOBgQAm5J6912hKDUWXyu3yCEk1j3KICE2J42ZjFRvxBNdO -Zhv/iBjyFI6TmCVJqoe4GJbNG78xmNEl3/2ZUavG/aD0Z3xGu2xm0p+3Uh2zhfDQ -VEdlgFNKNItS0AtKvoduoZUXKnz3Ft09yLmz9yHLu6EslIsYryi+wnZ5DwUBj5Ec -WA== +MIIBnjCBhzANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ +b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xODEx +MjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBQwEgIBBhcNMTgxMTI3MTM0MDU1WjAN +BgkqhkiG9w0BAQsFAAOCAQEAbVuJXemxM6HLlIHGWlQvVmsmG4ZTQWiDnZjfmrND +xB4XsvZNPXnFkjdBENDROrbDRwm60SJDW73AbDbfq1IXAzSpuEyuRz61IyYKo0wq +nmObJtVdIu3bVlWIlDXaP5Emk3d7ouCj5f8Kyeb8gm4pL3N6e0eI63hCaS39hhE6 +RLGh9HU9ht1kKfgcTwmB5b2HTPb4M6z1AmSIaMVqZTjIspsUgNF2+GBm3fOnOaiZ +SEXWtgjMRXiIHbtU0va3LhSH5OSW0mh+L9oGUQDYnyuudnWGpulhqIp4qVkJRDDu +41HpD83dV2uRtBLvc25AFHj7kXBflbO3gvGZVPYf1zVghQ== -----END X509 CRL----- diff --git a/src/test/ssl/ssl/root+server_ca.crt b/src/test/ssl/ssl/root+server_ca.crt index 8b548b46a59..861eba80d06 100644 --- a/src/test/ssl/ssl/root+server_ca.crt +++ b/src/test/ssl/ssl/root+server_ca.crt @@ -1,27 +1,38 @@ -----BEGIN CERTIFICATE----- -MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV -BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0 -ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG -A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u -IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5 -qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8 -sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B -MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE -TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE -TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1 -K5Y= +MIIDHjCCAgagAwIBAgIUEAgXJ/ibw6TVTUoomlBsPMfVTlMwDQYJKoZIhvcNAQEL +BQAwQDE+MDwGA1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCBy +ZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYwNDE0MTM0 +MDU0WjBAMT4wPAYDVQQDDDVUZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NM +IHJlZ3Jlc3Npb24gdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALZ81vKKBJlxgjwuNoK67I4IE9zfSLb0eHbgZwZxDVzdmFejARrHlWk3 ++MK7Nav7RLSJ990am33zb58CTHc7YYVlBp07+PwLXzypqWkhYfok1OYYjyjCrFDs +sjcJI3hRCZNEz+wYsG+tdYWJ+gRPQOWfh0YfO2rFgXAIMLiF6lyWzf1eOM+OjYrF +/eyzwbMaJkkGa/AyZKz3wZiPq0jTuYLVmH4MK7MBOsUfSmsBsn/ohyRCQzM+ol0v +Qlsrulj8usponRPDh9ng4PB5OSgR79YimQZnASQzJxiUvMADrKL5L6KwLxJlzbqY +R0b5mLh8KBzBQmSh3Aj2e2I7Z17hdaMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQsFAAOCAQEASzA7ApbuKn8lkC706gRL37a33yTZZ8rjZ4dnvCtq +6OltlYDJ8IndotKbLH0SUEAxrvcaFnMt7AX9pRf2sGBKbY8zcxqPfsvzVehgx4Ea +1RYksFW4h97jj1a1RKukTKuEOEEipbxwo0rLxfjvdaf2izqchJsLGtbocIZf0bD8 +djbE9jOLkx7saL08qC8ECrf9utsee+LJCsUYbNgYyIItEy6yVnmF/ICz93Utn1cI +RfqZr1lM2Ia2LP9eDTmiuR9m+/MzkeRvvJHonNrRJHlcggtYHICvYioh9/jALBcm +wZ+hTUePVqy4hOCBJ975CXjfKFN4MKQAdeB3EO5eBYAD3Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c -vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1 -37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w -mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB -paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO -cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiSnYZbmc9vpCt +Ku1sKV9l663JCceubhMw8Gg16kV0hXEFf/TgGC4zkiYNHN7+G45YD7Nq0kBCq3dH +t2wPCc6c8pQoI64dfprVqPkvzoe1WBpZNetkUTk20v08jNeRa7XdRbRR6we1s9VG +/prp8Hs2mmHqEfLuI9lvTT0Dz+VMmfFI8Lf278r+w+qOtVloAkX7AOyoLEJlNS0B +QW9YWdH9N5ctaUXMG6lLV2OAjs+W1smpKfpIpMCA1lPGlElu70hynon/nQQvBP77 +SfQpZVc0esM18jkZpr5LEKUCw+x6LaMsqmBHpAULfCffxn2r0uMBW4L4VaGg3W6F +h6iuJwRfAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AFlcKTaU/Ug3Q0hr3P1UQ6dWyK4aVn9rs4jvVfFl0a0RnbBowqK2C+zQVUWYTcjo +KHREVje65goj6VzRB6ko/9mAQ6PZP8jRuRhfCmvmvSQ/mWdgPzSRsUh9MwgEm9c2 +vNbqwaznEU8cYZnLpHiR9O5S7/qWWxehjYtxk5Eb4J006YglYfHnhrRFJvPbiqlf +IOEivZ7gIVfvaOTbLjmN2kLOnzdlwpXGjxxg4Nu9ZhXOhfrplzUvRfmqvVsDiHXb +USIdX+OFZZqr64IKG4drT4K4Bt2wupOEyX4ZFsUXXd+Hgq83SWmV4wzflcpmGkLC +JZ3CEMu8/WA5uQBXdQUozlE= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/root.crl b/src/test/ssl/ssl/root.crl index 2158728f85b..e879cf25a79 100644 --- a/src/test/ssl/ssl/root.crl +++ b/src/test/ssl/ssl/root.crl @@ -1,8 +1,11 @@ -----BEGIN X509 CRL----- -MIIBBDBvMA0GCSqGSIb3DQEBBQUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm -b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xNjA5MTIx -NjMwMDFaFw00NDAxMjkxNjMwMDFaMA0GCSqGSIb3DQEBBQUAA4GBAAX612LU7WpG -0AsQy1TPAXCwQdvzCVLU2L58unheWGSZruzlaLrh/x435xJ/3a2p9ZxCPlAMTUNk -+4mz4BC14uB7nkKQlTGHH3o1qGhwFTmdXmeDDjzyBPEQkSEfcpLDampRBLaFjq/F -yaKadxocukmCcbxXdiDZePFpf7TfuoIm +MIIBhTBvMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNVBAMMNVRlc3Qgcm9vdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHN1aXRlFw0xODExMjcx +MzQwNTVaFw00NjA0MTQxMzQwNTVaMA0GCSqGSIb3DQEBCwUAA4IBAQB8OSDym4/a +qbZOrZvOOhmKrd7AJSTgAadtdK0CX3v58Ym3EmZK7gQFdBuFCXnvbue/x6avZHgz +4pYFlJmL0IiD4QuTzsoo+LzifrmTzteO9oEJNLd2bjfEnpE5Wdaw6Yuy2Xb5edy5 +lQhNZdc8w3FiXhPOEUAi7EbdfDwn4G/fvEjpzyVb2wCujDUUePUGGayjKIM4PUu4 +pixM6gt9FFL27l47lQ3g0PbvB3TnU3oqcB3Y17FjbxjFc6AsGXholNetoEE2/49E +PEYzOH7/PtxlZUtoCqZM+741LuI6Q7z4/P2X/IY33lMy6Iiyc41C94l/P7fCkMLG +AlO+O0a4SpYS -----END X509 CRL----- diff --git a/src/test/ssl/ssl/root_ca.crt b/src/test/ssl/ssl/root_ca.crt index fab7a689071..402d7dab894 100644 --- a/src/test/ssl/ssl/root_ca.crt +++ b/src/test/ssl/ssl/root_ca.crt @@ -1,14 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICDjCCAXegAwIBAgIJAO2nC4XHXDkUMA0GCSqGSIb3DQEBCwUAMEAxPjA8BgNV -BAMMNVRlc3Qgcm9vdCBDQSBmb3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0 -ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowQDE+MDwG -A1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9u -IHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vUDilEsB5 -qI9cGWTthAIjlvr2ngFJqHmMeOgTg4JQQ24MQedh0r22nDNwm80r4RD9RCjlw/k8 -sS+chRwQclJqpE6EV65TIH0JhOKGFpx/Pz/yrru5QwEDkYcHl1QcK3xFUKbSxi/B -MCq4TZf63HkI6/VRY+1SwKF2a4pjWIaDAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w -DQYJKoZIhvcNAQELBQADgYEAtBNiRyqydB+iy2DtoYYjsvq/q69o3UrbIhKPMlYE -TJcgWyEz4gsRMnceM/dQl0dchZ8jrAbLiAbqr7PvitjdxGSQJ8w7Gb4IawPu3UCE -TfMWiG5oYV1nHHZotEQuE+Gx4AdzSVGzLGj2xF9dSMxEQq7uPlpv67IeHEn5g3w1 -K5Y= +MIIDHjCCAgagAwIBAgIUEAgXJ/ibw6TVTUoomlBsPMfVTlMwDQYJKoZIhvcNAQEL +BQAwQDE+MDwGA1UEAww1VGVzdCByb290IENBIGZvciBQb3N0Z3JlU1FMIFNTTCBy +ZWdyZXNzaW9uIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYwNDE0MTM0 +MDU0WjBAMT4wPAYDVQQDDDVUZXN0IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NM +IHJlZ3Jlc3Npb24gdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALZ81vKKBJlxgjwuNoK67I4IE9zfSLb0eHbgZwZxDVzdmFejARrHlWk3 ++MK7Nav7RLSJ990am33zb58CTHc7YYVlBp07+PwLXzypqWkhYfok1OYYjyjCrFDs +sjcJI3hRCZNEz+wYsG+tdYWJ+gRPQOWfh0YfO2rFgXAIMLiF6lyWzf1eOM+OjYrF +/eyzwbMaJkkGa/AyZKz3wZiPq0jTuYLVmH4MK7MBOsUfSmsBsn/ohyRCQzM+ol0v +Qlsrulj8usponRPDh9ng4PB5OSgR79YimQZnASQzJxiUvMADrKL5L6KwLxJlzbqY +R0b5mLh8KBzBQmSh3Aj2e2I7Z17hdaMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQsFAAOCAQEASzA7ApbuKn8lkC706gRL37a33yTZZ8rjZ4dnvCtq +6OltlYDJ8IndotKbLH0SUEAxrvcaFnMt7AX9pRf2sGBKbY8zcxqPfsvzVehgx4Ea +1RYksFW4h97jj1a1RKukTKuEOEEipbxwo0rLxfjvdaf2izqchJsLGtbocIZf0bD8 +djbE9jOLkx7saL08qC8ECrf9utsee+LJCsUYbNgYyIItEy6yVnmF/ICz93Utn1cI +RfqZr1lM2Ia2LP9eDTmiuR9m+/MzkeRvvJHonNrRJHlcggtYHICvYioh9/jALBcm +wZ+hTUePVqy4hOCBJ975CXjfKFN4MKQAdeB3EO5eBYAD3Q== -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/root_ca.key b/src/test/ssl/ssl/root_ca.key index b79f4b0ef72..aa5f243e945 100644 --- a/src/test/ssl/ssl/root_ca.key +++ b/src/test/ssl/ssl/root_ca.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDOL1A4pRLAeaiPXBlk7YQCI5b69p4BSah5jHjoE4OCUENuDEHn -YdK9tpwzcJvNK+EQ/UQo5cP5PLEvnIUcEHJSaqROhFeuUyB9CYTihhacfz8/8q67 -uUMBA5GHB5dUHCt8RVCm0sYvwTAquE2X+tx5COv1UWPtUsChdmuKY1iGgwIDAQAB -AoGAE+iNnmqR/PPCStVhvlUQwgQdt+3II+ew1MuzgPUhZZvKZv3X/zd62cagHndp -E86A1NsfkbNd0NsDYM2ELMmJwC8cTKFw2WyB9t3v0GTtVG8e338QdrrTOvawO3F4 -f4tCESvBgY4qmJMuvicMqLey9fAXc8ul+wocRRYx4r1Gc4ECQQDpgATrxdy7vkf0 -KFxO6htUnKB/V5Q56qvlMzXKHSiwnCMKRYPY7NAxLVNVTmH3ACaBFCvg1f7++Yn7 -r5zEEcuLAkEA4g17NFfFZmBz37C9Cu1W6cX0ps0MgI9w38bEYy8LOk0liUGd+Qit -AKpu8KNOb3v5FQ5TL25EaX1VhM78OE9v6QJBAIFHZPIZGY5E2te+pOT4Tut40I/Q -sHukh0meIdDmdgnaWLguJsKq0tX3b2USwcCcr7TVszmHoegPxyq3X0dbRuMCQQDW -7OhyWO1XrGcfjKQAyq4zMMKvARBc/4TbTtoUT3tGYGlK+jdfuw76LhGy/CIsP1wQ -2ADhfN7QyZjQ4BfQ1j5ZAkBggAL3a/4+KjsPesTxWjlufmoL9QG8Bgaj1tWBYDzX -5CQCWYRPVE7aV+Jh1NDHgToQsziZtvRL16l+GivYEnTX +MIIEpAIBAAKCAQEAtnzW8ooEmXGCPC42grrsjggT3N9ItvR4duBnBnENXN2YV6MB +GseVaTf4wrs1q/tEtIn33RqbffNvnwJMdzthhWUGnTv4/AtfPKmpaSFh+iTU5hiP +KMKsUOyyNwkjeFEJk0TP7Biwb611hYn6BE9A5Z+HRh87asWBcAgwuIXqXJbN/V44 +z46NisX97LPBsxomSQZr8DJkrPfBmI+rSNO5gtWYfgwrswE6xR9KawGyf+iHJEJD +Mz6iXS9CWyu6WPy6ymidE8OH2eDg8Hk5KBHv1iKZBmcBJDMnGJS8wAOsovkvorAv +EmXNuphHRvmYuHwoHMFCZKHcCPZ7YjtnXuF1owIDAQABAoIBAQCiCzsHhf1NkBi4 +fcTT006JVKzmnbNBGtb5oIx7kNnv06oab9lkQUPwec5AhOLFA8tfkX/y61SVxBwj +E3R5D9aqECqOZpnSnfqEsJeJjiYlbJ1McRR2el9vQK+D5W6EwVkCV8FWAhpyIJJR +8VJ8jy+udzk00Dj/t8AXjn5M7EVOzu7fu2CIjJ2csE4NpWnn4eaDqev/brEVaLSP +DGFdMw4D29AmErByN42d90U5YE2c1UufYoFL480qoA4pW5Tw5+vrIDliEHhnTtSN +aTHZiOCmHtBFieQzmWCRQqmtlJP+7Z/NqK0i91HpjFrU5AuyLOMbqJPl6TgncNA+ +MSXMXGQBAoGBANlsAQc3poc3MX18++qgRJGqJCBF3MVQNnZQxmO6swydikZmlunN +kmslheb/JZbE9tkjEhx1RuUeZIvOCxURdODDPnvm9bk0C7LvPGXnYLWTbCknHEwR +8yIvPGiLhZOuDGAdLpHzG5F1eHQLOWQpTNndptlveSz5Zc0a+B7qmWYBAoGBANbe +Atvo8JI+ht2tiidwCo5WHR26ux0yA+iHPNyMAEaY5KFblyvjb4rAFziUu6cLzFNl +N2pdv3ZpIHs82erJMkCSrIbp9RM3TWaTMFgWETDnZ6dNclEsEva/kRJquOw+N/Ag +LFOn8omVRMHq99G/eFdPeSYc1mDRNZ0vDstOA4OjAoGAd9l/X5kfpN2Z3FCvFRCv +e5RMQbYBEos62lGAaq0Z0dRtyoz2l38IPSP8Ae+Xqtp8MAmTDDjhkZ8FUcOMfFqZ +EOTPZsFTpnm4ETSrGIlI2A6hyrWSdaRXX/ql1ANE6LlCfSDY8P8PrUkR0vX09u+F +O3thY+5833vC0CMTrwcm9AECgYBmVktqTiH2pY06m+MHMZf1fxJTDJL+Lsopv+++ +43dmKIAMUkFICAUiQqdMrZpKz5W7yqOAJ7J/RUbRK4RnDPjARJujjl7JjjdxOX13 +FtuNPUnjJ0HhY2qM12TTLr1w15lw5wH1vjIIUW30JmNuJRG+E/4Rpv58EmjEupsD +Pd7ynQKBgQC42hGdd3TGe7zYqnPIe/vJyNX05xErKXK1iqwj6ZQWOiurGiePbiIu +Top5MZcqLetZ9872efPLQFlkB2elCP91yBKNdI+onBcha9rVcczjCdaQswsm5Ws3 +58Dyjci4NqyD8B19AOJLTl5gq8pmj5Nom8ip+Bm2EsQw777Dqq9YrA== -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-cn-and-alt-names.crt b/src/test/ssl/ssl/server-cn-and-alt-names.crt index ef7fd66b7b9..2bb206e4134 100644 --- a/src/test/ssl/ssl/server-cn-and-alt-names.crt +++ b/src/test/ssl/ssl/server-cn-and-alt-names.crt @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSTCCAbKgAwIBAgIBATANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 +MIIDTjCCAjagAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV +cnRzMB4XDTE4MTEyNzEzNDA1NFoXDTQ2MDQxNDEzNDA1NFowRjEeMBwGA1UECwwV UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z -c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsIeqZ7pHER -w0nqVgePeSDdr7/fXMNtF/yFk4ZYUXGLuyzterEUaxeSYB5jmNAeY7ANRjbMb5N9 -mvoHHUsz0AzVNFihcSvP5nB9xIAEypMUF7qoXNVgXbG33gFKLbfNWqbuLUqaiWCb -+B7ahLVPTbm16Kwaw0sEMcSALED/lsMfAgMBAAGjSzBJMEcGA1UdEQRAMD6CHWRu -czEuYWx0LW5hbWUucGctc3NsdGVzdC50ZXN0gh1kbnMyLmFsdC1uYW1lLnBnLXNz -bHRlc3QudGVzdDANBgkqhkiG9w0BAQUFAAOBgQAcbbxoyusUuTKq+hz7wLiJfEis -UHrq8BwakaOP0zTln8XBT3uvNeumjQQGciqMNsV8QQ0xT3XadO7R9ix5V5IzTxnC -q4s1xKxSJsmVcPf9Ql43ev3S+lRnyw1ws4lfe9hOdKfOopjHpa+D2VW8/iRfhNj2 -PO7iYMyUZKXB0ynKTw== +c2x0ZXN0LnRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBURL6 +YPWJjVQEZY0uy4HEaTI4ZMjVf+xdwJRntos4aRcdhq2JRNwitI00BLnIK9ur8D8L +U24PDn2etTZOK1wsHHkAiHPvgRX7G/+78a5fSC8nMNaH/oR4zMMhwksiruISA7x9 +/l+4DO7C42C5mRfnUmMGJdzau1+A8jcIxTWWoJtva9b1k3g+bvBGq9138X+bJKIW +YsWwHgcuEIZk3z287hxuyU3j5isYoRwd5cZZFrG/qBJdukSBRil5/PP5AHsB6lTl +pae2bdf4TXB7kActIpyTBR0G5Pm5iCZlxgD+QILj/1FLTaNOW7hV+t1J6YfC6jZR +Dk4MnHMCFasSXcXhAgMBAAGjSzBJMEcGA1UdEQRAMD6CHWRuczEuYWx0LW5hbWUu +cGctc3NsdGVzdC50ZXN0gh1kbnMyLmFsdC1uYW1lLnBnLXNzbHRlc3QudGVzdDAN +BgkqhkiG9w0BAQsFAAOCAQEAQeKHXoyipubldf4HUDCXrcIk6KiEs9DMH1DXRk7L +z2Hr0TljmKoGG5P6OrF4eP82bhXZlQmwHVclB7Pfo5DvoMYmYjSHxcEAeyJ7etxb +pV11yEkMkCbQpBVtdMqyTpckXM49GTwqD9US5p1E350snq4Duj3O7fSpE4HMfSd8 +dCkYdaCHq2NWH4/MfEBRy096oOIFxqgm6tRCU95ZI8KeeK4WwPXiGV2mb2rHj1kv +uBRC+sJGSnsLdbZzkpdAN1qnWrJoLezAMdhTmNRUJ7Cq8hAkroFIp+LE+JyxR9Nw +m6jD3eEwCAQi0pPGLEn4Rq4B8kxzL5F/jTq7PONRvOAdIg== -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-cn-and-alt-names.key b/src/test/ssl/ssl/server-cn-and-alt-names.key index a1ca8f42864..485e3404bc8 100644 --- a/src/test/ssl/ssl/server-cn-and-alt-names.key +++ b/src/test/ssl/ssl/server-cn-and-alt-names.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQC7CHqme6RxEcNJ6lYHj3kg3a+/31zDbRf8hZOGWFFxi7ss7Xqx -FGsXkmAeY5jQHmOwDUY2zG+TfZr6Bx1LM9AM1TRYoXErz+ZwfcSABMqTFBe6qFzV -YF2xt94BSi23zVqm7i1Kmolgm/ge2oS1T025teisGsNLBDHEgCxA/5bDHwIDAQAB -AoGAB0Hh+HnNvLFywXh9VBfGHHddrXVOVSrzhlHskob0yhIg9jJU03A2Y5jDcApv -UIwNVDR/p/qwzalPDSqfgV6GURgqzS/If+qKN7aPiTZPwTB1I9zNVLf07EaZjS08 -IppwpVbFnrJww1WP/P5VRZxnkbhZ0ClZWm3Bo/V6Axi5O8kCQQDitdVoEerONTq3 -a3n6lzPm473l0P+gZdqbSeqRO59c0uMvE3aIged6cPQZ7WIAivID7Wh7AP0zHetz -NQOCw1fNAkEA0zJfIDyNtkcuPzm9Eg5gQzdgusZ455Eij3VoSRJTX5fLDaBf/lo+ -z6bsGqmnGK8JVtKkpvSPV0L9R47KDCUCmwJBAKlWmKi7eV+9crY+mUYMWsBDrDxU -+Bue+MK1W3hPyKFVBEzNhORB490ZMbuMDH/LSSqV0kzOWFIuLwhGuPCbaKECQEeU -VvFSFKWm0mHTa+VmwfGGH16uTeQOKKx+mm3JrEBF7igcJuzKIWe3p2YSAfQ3vu6S -TgPX940Xw0gxeQFMuekCQQDHuGhGdj3faCSkW8/dIkAX37/VkOxSvaZGpmDxclZL -g21KLL9Ng6wI56wvMo61TCK5gEPnpmDB8H5l3VULt9Yn +MIIEowIBAAKCAQEAwVES+mD1iY1UBGWNLsuBxGkyOGTI1X/sXcCUZ7aLOGkXHYat +iUTcIrSNNAS5yCvbq/A/C1NuDw59nrU2TitcLBx5AIhz74EV+xv/u/GuX0gvJzDW +h/6EeMzDIcJLIq7iEgO8ff5fuAzuwuNguZkX51JjBiXc2rtfgPI3CMU1lqCbb2vW +9ZN4Pm7wRqvdd/F/mySiFmLFsB4HLhCGZN89vO4cbslN4+YrGKEcHeXGWRaxv6gS +XbpEgUYpefzz+QB7AepU5aWntm3X+E1we5AHLSKckwUdBuT5uYgmZcYA/kCC4/9R +S02jTlu4VfrdSemHwuo2UQ5ODJxzAhWrEl3F4QIDAQABAoIBADpFoQ3eKkVzV48X +uW4QpCY7e4rqPmu06t/7zABTUzYG35Pj4+2L1zuS5zl17zZ6mfYDLk3QsU1SleVA +RIVdpqQZVRQnDaN1atXNw9G4cVKBZM1QeGp3+yCawHstoQ5sXvMFM01bXykQpOwU +NDTeBAmTmQviX+eDMa+h05sOLzAe5IfJd54au7jaDgX+J+OYoRcahXZLO3tco/kL +Mo0OBj71ec8jrbhnViEXPwPUOBDoTJxfRotCZ2Sr0ozXT/sRBZvvK9OGzWf9mA2D +M7UqbkKUL9AJxB+zTUILdM3+4buzifDZPUWe05dHyP6VAvtgSQJkdReFtUa868pm +si+7Td0CgYEA+r4dxf880QW1hY/dpTfLXOcLKSHogIHv2Qt3Dinh4AthXZs91MQ9 +DMiT2x4RMGlk7zOu6Ua4HXjTT0s9CqUt9Cyga0zTn+XzNZxzcriRWYnw7pq0O77B +3AODrK6/VajAjqdwiP3nQfBOyhz3G7YB2yXCpdnVVI179x8pbGnEP2MCgYEAxV64 +CaIW0hgwEZifT4PGINdGShk7ijQ0YhPw4bLJLV7gaPrKYG+qy8/R9AyhcFqz9MrF +2E+jiD+fylNSLdkuR1/v6se1wWLjDiKip5F9molCAKTUBTkqD/8Ejh5+I7NAuFLA +9QZYiaRLhIoVocWfzNIPHit7NZftaBtxTCtE8usCgYAmxbso4LzwvWdCTerCH4yM +wxVQuPOQ24bRExrHz+YjlN7rcJPxEJ84GNP0MAQMbl+zNVS4sbzKoeJbApFf0gb3 +GOd9cBXRReeDxLt9Y9jl9ZSR8M4p5udnNAvqaeMgRcXwySd3p3tZEOW+DxiO6mgD +ESW2K6b3OiGPJvxqzTgRbQKBgQDCvB/tMUY+6KqU0fdtpuCXio/JkHfUdomws2gZ +6CLiZxgXvEptOABWs6e9mbC3gGbKAj+Om5UIW243XFpa7kvhFGFNTtqgAgdw7O97 +UeuRzBeZNwgSV0KPIdjGuINQig4zT0Me/rHgrH/uN6f8Q1bV6fQMmm4ohMwyydDR +jGetHQKBgGLQf4MBNalhfnM7jnUCbA0ygrw7BuJRfwuamdcH9bdfOHMyrbOfZ+hS +aKcOeaGi0HGOq+D2tIH1hmFYHD0klPgr/KWnNMoi2xTw+1GNKA2u9EZQQkK6XSRn +Xb6zihNEqY8067K/um/658x1c9SbfvVmzjqo5OwgjSKygk6fXL8i -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-cn-only.crt b/src/test/ssl/ssl/server-cn-only.crt index 98910723355..67bf0b16453 100644 --- a/src/test/ssl/ssl/server-cn-only.crt +++ b/src/test/ssl/ssl/server-cn-only.crt @@ -1,13 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIB/DCCAWWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 -IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV -UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z -c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALkR7DNyRnAE -D7ZxnsfOPQ55QB0nM2onJmVZkG4EeqQJ6GZHJym7pHHwbww+dgXvlNzkv2SOvA+Y -q8TXgYvSiKhZ4N4ReSWWZ71P+RqJXpSrj6K2mVKOw0Rno9kMt0370bQOnkvSQY9B -WxJbxji2ks3oj4wma+1zje3i46IlwoYHAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA -G2ZMgJnCz3/kDv30Uun3YzVktMW4O1y9AbFR1YrbHM8xvVGFLpp9z2PVYOKwKeND -oS3UjW/wJynAT3xPwY3Zg6GbTqx2Fu8BG9bb73RK2af1IT8sB1Pxj8t4kZr0egaO -m8TIbipkZNVakwG9idiVYjn4CusqYthFsOKW+OHiM3I= +MIIC/DCCAeQCAQIwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNlcnZlciBjZXJ0czAe +Fw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEYxHjAcBgNVBAsMFVBvc3Rn +cmVTUUwgdGVzdCBzdWl0ZTEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVz +dC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1bNU8yTuLl/5 +bR4Rp1ET5NMC2wgrTwKQsxSeOzvMmTGeebpEYFc/Hq8rcCQAiL7AbhiZeNg/ca4y +JdouOdaHaTMFJ8hFDI1tNOGeFK7ecOMBWQ97GxKs/KIqKYW42AN+QZ7l1Apr0CDZ +K5VTi931JjE4wCIgUgLi2zgwtZYl/kP896F1K5zR7kx773U2dvP3SeV2ziUe+4NH +5oqdmVMeZyHfB+Fe/uU1AiYgHN/CXfop39tYHR8ARUWx7eJlaaKBoj/0UqH/9Yir +jdM0vGfrw4JCjIx78caNkNH9fCjesTqODr+IDBJaJv3Jpt9g8puqrYagXLppiaYS +q5oOAu5fuQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCTxkqpNNuO15osb+Lyw2aQ +RikYZiSJ4uJcOIya6DqSYSNf8wrgGMJAKz9TkCGEG7SszLCASaSIS/s+sR1+bE19 +f6BxoBnppPW8uIkTtQvmGhhcWHO13zMUs8bmg9OY7MvFYJdQAmSqfYebUCYR73So +OthALxV8h+boW5/xc2XM1NObpcuShQ9/uynm2dL3EbrNjvcoXOwu865FmVMffEn9 ++zhE8xl4kMKObQvB3r2utCmlAmJLaU2ejADncS9Y4ZwRMa7x+vfvekF/FvLEXUal +QcDlfrZ0xsw/HK7n0/UFXf5fUXq3hgUGcXEdWW7/yTA43qNxednfa+fMqlFztupt -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-cn-only.key b/src/test/ssl/ssl/server-cn-only.key index f58af68a83a..672d3f01d2c 100644 --- a/src/test/ssl/ssl/server-cn-only.key +++ b/src/test/ssl/ssl/server-cn-only.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQC5EewzckZwBA+2cZ7Hzj0OeUAdJzNqJyZlWZBuBHqkCehmRycp -u6Rx8G8MPnYF75Tc5L9kjrwPmKvE14GL0oioWeDeEXkllme9T/kaiV6Uq4+itplS -jsNEZ6PZDLdN+9G0Dp5L0kGPQVsSW8Y4tpLN6I+MJmvtc43t4uOiJcKGBwIDAQAB -AoGBAJzj6r86UyhG6SMbcyWjWvNYKtgMEXQeOFiW8u+xcF57375E95hTcHb/AsT4 -dolVr3cLnI0cy6TVIli+8R2dnybVxgdV/NSWLk69HDb+YPh2cEA7TxAb3vSfMdyJ -T4uC6ibyjAaWdmEDYhuhP45ALf8MKYHEdtmpdGVU0TtrcZThAkEA8oERu+OPXEVO -OG6yJh6JKwrGOv5jEVK9G2v9ns0LiJDhnDc/wTv5/zq6GIQlWDViV7dmtYPedOAr -Zk3e4HNUHwJBAMNemFSkwMew7jI0yQKuHLN3/kKQXi70ZGXHr6i6hzlcxgoa68zq -Ayx9/4m3D4ucwzSTQo/84p7PA+JXTGLu0RkCQF07WgIOXtNuob/4bu1Q2BOANO4B -Vz0VvjaIsh0XX9PFP7e7VfuIf3isr1c1ltXu0DxA+m/WnvP4KzdNwN4x+KkCQCrP -mr/Jjnjzu26DBJ0yvBVTsQKzEgBmC24GMObfYOxf+QGT3qH7kZB5V7q8w4pLYrct -ocNdnedA49AAYzu2q1kCQQDR5DJ+L/kM02pV4LLhbQ6U6nhBKDPXY26nob/TAtwq -eODDcDiceMGKThwwnGEjEeO2w4uZEM124v5sJgZtlByD +MIIEowIBAAKCAQEA1bNU8yTuLl/5bR4Rp1ET5NMC2wgrTwKQsxSeOzvMmTGeebpE +YFc/Hq8rcCQAiL7AbhiZeNg/ca4yJdouOdaHaTMFJ8hFDI1tNOGeFK7ecOMBWQ97 +GxKs/KIqKYW42AN+QZ7l1Apr0CDZK5VTi931JjE4wCIgUgLi2zgwtZYl/kP896F1 +K5zR7kx773U2dvP3SeV2ziUe+4NH5oqdmVMeZyHfB+Fe/uU1AiYgHN/CXfop39tY +HR8ARUWx7eJlaaKBoj/0UqH/9YirjdM0vGfrw4JCjIx78caNkNH9fCjesTqODr+I +DBJaJv3Jpt9g8puqrYagXLppiaYSq5oOAu5fuQIDAQABAoIBAELaJRsjVHehgpAG +NhOXo5eUA3Kt7Y58CPRc4Ns669iI00DVaoqRAKgCuJ4ORTSCKATJIUnSrJZNnlaF +GKzzVc0tLtGxLxisLZu7cQ6bXe8GtOc9lo9zmjY2LOZsdNTu0tKIePGKiQvFGust +fcNlnkliYJSKmH3PdVSLEYHdBOmznMR+M5nif33OmuK+LIQ8Go+jpahvqXSG60ae +QAKlJCO9DARjhJqpYw1GgtzXSxpiVWBkJzIwnemOecgBtm6W/5GDzYPq9GE5lY7N +MTjP9BmnpMC1gPQjiDICrd9eWSUv6fuHAClCi5lMDrktWvZcEB0tpoxcQZf2d0/m +vRZK7uECgYEA8fKpaDaZqPNktgLsrlo35wmHa3tkWR1jmI5DY5BHoO+N+Bm/ISwP +HHLTObXmgzbycA5OEsIeUdb8ZmO79WINb9Z8aAmhft6bBzY7xZRNSouq0G/IgzZn +m9D6f4ivBDXs8lZpJe3/SrvfCmnxPBO/vzezX6FqiPV24jSXNYcb+B0CgYEA4hyu +bbO7Mfd1NmlJO+OWmAJBqJQKmFByP6uraUX9cgS2F+jexsyX12WGMXRoQM4CAo5u +CN29U9NyokpZmifUbKq7cZ4Hni5ag+Wt9a/kuevmv8ysYEzVY07gjwg51z2uXV54 +wBA0nQsT28RVdNAv36hMhqgMM1ZTNa4AXGdxi00CgYEAzJRqKENaxKAhfUGVzYtd +j47gIcLxQ+T0zQ8l7i8WUf+dJLbohO0TTfPNpROo+TRh5NxDqdrX9k15mD4mtUMW +p4VOJk5WbsddgMib2+IdRLY6VgrfGgvLqdYXqfTyP/Y1B2iHeln2rsOSweR45Vqx +nMdFdcwwH+SmhHkBjnJS9QUCgYBlmm/C+dVvMXwpFAyFbdI4wiLQ5p0QLm34MGLY +7kth1b4hZlHc0QiWEJfJVz6ViDyc+3V0ZHdz2HsVdAVpYOZyYhHSjylrKfcgd6/A +y+YiqV9J5mW67Cui8Um03ARptNzKNe5al62ct+KXiVTBJd+tR8oDZDX/R5Yic+rT +muQJrQKBgDCc6inyAzBN6mwEcFJCj4JBoIBiTfcwX+Rruh4gR8+7KbiG3UqaXSiO +prONCswe6sXs6s6bFCZSOwgsom/bYloBZRVtTPJv031VDTFUQBo4956/7dhIDdvC +2ZDBwgHPeywPPK0OrGBuAXzfIS0YqMZeEXtpSdw8A3seQ2398/ir -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-multiple-alt-names.crt b/src/test/ssl/ssl/server-multiple-alt-names.crt index c330d4d4229..158153d10c0 100644 --- a/src/test/ssl/ssl/server-multiple-alt-names.crt +++ b/src/test/ssl/ssl/server-multiple-alt-names.crt @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICPzCCAaigAwIBAgIBBDANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 +MIIDRDCCAiygAwIBAgIBBDANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV -UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB -gQC3KEGfUWKDHb5tzwJ58o5GaFwUctjQxOg4Wtf6TvBRnuAd7VYAVFRtdPLnH9k5 -dHDUpMw1bHx4nUmbnphtLJDS8VVowLyjKGAU/uOuQidUk0nCSllHPaE8soBZPV8x -BwG7TQ47GO7Jg4dmcTLF+E4m3YbzHglOmoN5+vrwWSJnLQIDAQABo2cwZTBjBgNV -HREEXDBagh1kbnMxLmFsdC1uYW1lLnBnLXNzbHRlc3QudGVzdIIdZG5zMi5hbHQt -bmFtZS5wZy1zc2x0ZXN0LnRlc3SCGioud2lsZGNhcmQucGctc3NsdGVzdC50ZXN0 -MA0GCSqGSIb3DQEBBQUAA4GBAANowuGrcHzwfVLHa1PC4W0obG2it61VaA+OFHwv -OAloZTbbNslSh/RGyrD2ZafRZpZNhjNB3JRIt7bv5Y0j5YP7CQkp2ucD90V580Pe -vuoP+jZ/f5ZIC2ffiG9ofPxQdJEHy63GWHSH668rWQBc12GhHqgwZXNoWRMJxVrj -EZqd +cnRzMB4XDTE4MTEyNzEzNDA1NFoXDTQ2MDQxNDEzNDA1NFowIDEeMBwGA1UECwwV +UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA10iQpfVf4nCqjkRcLXP9ONQqdhMPMdjHasKqmsFTx83SZLKUzKMOb56j +3bg83stqGoId4MIxtqnDKaSg1+kseQ1HCi0cu/E3lHLEkPibl9dyVGhXVnPDBdOp +eUQLCvPNgay3/ua4Mz0Nf7S9cgC9AZu/EEYjQIEzfO0cEANeVIWtgZfM3+2j0pmZ +46AEYlEZJkmDT0/mnHk3YTj3I6qQhr34wZvqcrwouYRN5NiOVYJLpb6gPSoalm+P +YXOKjP4+fWr18HdZLrzsa4xPRa9XcsDNyffjWvQTfptR/2vFKN8Ffv3XUqxUx6av +VCyRKa8xAUS/pHVGnzFQY+oqWREn2wIDAQABo2cwZTBjBgNVHREEXDBagh1kbnMx +LmFsdC1uYW1lLnBnLXNzbHRlc3QudGVzdIIdZG5zMi5hbHQtbmFtZS5wZy1zc2x0 +ZXN0LnRlc3SCGioud2lsZGNhcmQucGctc3NsdGVzdC50ZXN0MA0GCSqGSIb3DQEB +CwUAA4IBAQAuV+4TNADB/AinkjQVyzPtmeWDWZJDByRSGIzGlrYtzzrJzdRkohlL +svZi0QQWbYq3pkRoUncYXXp/JvS48Ft1jRi87RpLRiPRxJC9Eq77kMS5UKCIs86W +0nuYQ2tNmgHb7gnLHEr2t9gFEXcLwUAnRfNJK56KVmCl/v3/4kcVDLlL6L+pL80r +WGKGvixNy3bDCJ/YGJu6NH+H7NMlqFcg07nEWUHgMzETGGycTcPy3S6mY5P/1Ep1 +MCSTucUKoBIte2t5p9vM6bsFIioQDAYABhacmC62Z5xNW8evmNVtBDPLR1THsWhq +UjzdIzjpDgv1KUCVEPc1uVrZ5eju+aoU -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-multiple-alt-names.key b/src/test/ssl/ssl/server-multiple-alt-names.key index 5969b9b5ce7..57f31147257 100644 --- a/src/test/ssl/ssl/server-multiple-alt-names.key +++ b/src/test/ssl/ssl/server-multiple-alt-names.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQC3KEGfUWKDHb5tzwJ58o5GaFwUctjQxOg4Wtf6TvBRnuAd7VYA -VFRtdPLnH9k5dHDUpMw1bHx4nUmbnphtLJDS8VVowLyjKGAU/uOuQidUk0nCSllH -PaE8soBZPV8xBwG7TQ47GO7Jg4dmcTLF+E4m3YbzHglOmoN5+vrwWSJnLQIDAQAB -AoGAPUp4Y0MNz0il0ANFFd/oYoFLxwADtCEggLNNsRK3cujSoNEqRWPy+Mn4+wT6 -YTKpC0+2km4iXQ5tcmkpIueV8qAitks7n8Ed7qP9Le4MXePnzgn4lL0qY1zExESX -ibAQy/ThPdRuWvelpAXpEOMZclZsix6ksFaAMdC7o8+KwdUCQQDcrd0/X4N+wlSa -LBUcnTmhFI9gcPcvckZoxISHWV2B/QaDVvGA2gYMNJa3lEcuH07LfQh0rraEzAP3 -AhG8BRPnAkEA1Hj2+qKf7aBqcjyQ5yHdxsyw/wFF3ivH5dW7mShi/C6fo+qj6WSU -JNLPN3nhJ++5IH3DuuCTop1qNwk9jEOJywJAQED3bJ5Y4S2gCIvRUdWNlBMyc/gw -YMY7LgIaPHaOvWx42wETrFrO6/rb73PjDdDb1m//aEn+psfoV6FonIA1/QJBAK1D -c4xRf39k2EkN8NA6wsKx+wgIPrR9GUboc1HjKE0jrBUca8wQs+oPauF/Z0eM6nd/ -d1R2fI4YNhxpUaKHFN8CQEpJAGi5/CfFQWdGuDbJwbXwNA8zKlyGohE/lGfjZx55 -LnL3KE/rQXKRaCmLyk5Ce6oZQkDiN7GVEwEz2wMJlys= +MIIEpAIBAAKCAQEA10iQpfVf4nCqjkRcLXP9ONQqdhMPMdjHasKqmsFTx83SZLKU +zKMOb56j3bg83stqGoId4MIxtqnDKaSg1+kseQ1HCi0cu/E3lHLEkPibl9dyVGhX +VnPDBdOpeUQLCvPNgay3/ua4Mz0Nf7S9cgC9AZu/EEYjQIEzfO0cEANeVIWtgZfM +3+2j0pmZ46AEYlEZJkmDT0/mnHk3YTj3I6qQhr34wZvqcrwouYRN5NiOVYJLpb6g +PSoalm+PYXOKjP4+fWr18HdZLrzsa4xPRa9XcsDNyffjWvQTfptR/2vFKN8Ffv3X +UqxUx6avVCyRKa8xAUS/pHVGnzFQY+oqWREn2wIDAQABAoIBACtGhP03Y/zq1P4g +M79XT5G65IYzspw8jWmilBTjw+moMCDZ3Rt9s4swgpQxUtseXMfTXBowLzoeygJ2 ++3YrgysaRit/ggUtqhSHNYhG0VAmmO7qwpO4VX24XJrp2KZs9+SXSa1Nx71VCn+f +X22pRFUsb63fy3pN/oGgUEHPy4iFsDm5K62lszzzwXmcWam30dcK2Ddw07FAwpSR +2hW0veXpbZs33CX0p0js2imlSBwMLPbYIXriRT8Wpkkp+LvSy7/vDK3hWGhrKflT +hXZsHINEBwGwfEP7uSgTUiTlm96Fwp8SXLC0A7NJL8uJ2ARxuDqniq0UbqTpvGgY +RlgkZVECgYEA8rPoMuhJYHkejfh05qqycs3RYAdMIeOZ0wGzbELR+nI0FoAITHOB +KsdMUaNrjICMKAJBNx7cl4Qb5IP35dcZSyR9pr6W6QDCwnRDYxGSCakn3gEtLgix +5rcrf7r8QUyDUjCjasAZoql3rlew6q4HtSfBKciNuQ1wYnuaf5QdQAUCgYEA4xQU +xvTbAYAhpmrDhIMprStBtAHEM/1N2RiV7jlw3WI939WBSRTwqLmDSJNc4he5m43w +Dew2HPLFW6m/2jsXhYCXkACsgn1E2o5wPPcHIgnKe8eO26HuSIg75OsDaxAOGtMi +RQbXelxtXDnRbsjiChYRucH13EhU0lsaffNXrl8CgYBEU2WhP0e5AyAY88NlVNTc +ARlaoXNLbxnVD3uFlOIsUY5cbzrm2vWYJ3dS3GDgsyfB87CMZgHQHf8EPCrD5+RV +BTbihHFTs0UhHT4DW+TzF04D7+zaMtRykUqLsQZnE7U8pDi9SstswazRxhomV0wQ +Mdrtemp7mE71SrraA8agSQKBgQDSfC62LQlEXszSQWxyTFI5XjtM68Y+mrGqZouz +gjMIQqQv8uwgHfTlsO/sOgyC1pMJiYvWm/mc47vkt3hKhTPMX+IdbUJ6wjssi5Om +LyTBfGngSp41H+iL+xvpmZ5Vg1BPtR2y9iCOH1aPgliLZFGCH+rWUN/hDHrzcdcg +oIvJ6QKBgQCnYc+oZqcdisoSYPg7IZSWsPz3mWsFtR0Xw54zQ0n+gMjEzSDjO57+ +8nMUpXwnspo/x8qbsrZ39YeZZvwXVTXlpQjywOOGkIua84+EQUnknK+osKBQN62m +PWfPxXCTkWSBf8V6KKG/LFS6bZZu96h7+uWHkEwcD+bACS+2vGuyLw== -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-no-names.crt b/src/test/ssl/ssl/server-no-names.crt index e1305277fb5..97e11176f61 100644 --- a/src/test/ssl/ssl/server-no-names.crt +++ b/src/test/ssl/ssl/server-no-names.crt @@ -1,12 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIB1jCCAT+gAwIBAgIBBTANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 -IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV -UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB -gQC6VU212xAM+d99liOE5ROUG7qwuHhELgNbqGxUgNu8S/nKBrZSsGzWnqA4//iG -DXTZLHszRctXVrkhq2VXFCmRZLajk8uw4GtGCwb/HdvANrDM3rwiU23yjX3Q5Dvh -vHgkG+0PBf2Ghr+/XEbDkAwB0xi8QhO33F+1uQEH4XJM4QIDAQABMA0GCSqGSIb3 -DQEBBQUAA4GBAFBH5fx/I61acluRFTP5RJ8aymi8ez37+MoQ+Aftj1BXwcGSRe2E -57c0VjWUooJGKy/gs/y9F09JngEhFRz0pUCMAKQMaciEJh17ai+QOuSo6/NsGA50 -dw+w4UrYbxJK1RxhgKIYY3sojJ/6G+VbprPlWtSPSEcukRGjj31XRIfp +MIIC1jCCAb4CAQUwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNlcnZlciBjZXJ0czAe +Fw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMCAxHjAcBgNVBAsMFVBvc3Rn +cmVTUUwgdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJ85/vh52iDZAeQmWt47o0kR7VVlRLGf4sF4cfxPl+eIWIzhib1fajdcqFiy81LC ++t9bAyRqMyR3dve9RGK6IDFjMH/0DBf3tFSRnxN+5TdSAhKIJslmtUdOl8kS/smF +4+BikCg509aq0U+ac79e/q42OyvH9X/cI6i9SPd4hzJDMCX54LZT1Of/90nSQX6E +Oc5Hcj/d7psBugmMBW8uXYAGvJpq14e5RoK78F/mYbUNqtc1c8pi4/4quSMeEfQp +Dgmzee7ts8SIbQT8mYJHjnaPvZYpv4+Ikc7F0wzLO1neTpsYaVvDrSMLBCdQkCU8 +vgb1T6WlVgbp/sfE5okSxx8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAh+erODlf ++mEK2toZhaAmikNJ3Toj9P7I0C0Mo/tl2aVz8jQc/ft5t3blwZHfRzC9WmgnZLdY +yiCVgUlf9Kwhi836Btbczj3cK6MrngQneFBzSnCzsj40CuQAw5TOI8XRFFGL+fpl +o7ZnbmMZRhkPqDmNWXfpu7CYOFQyExkDoo0lTfqM+tF8zuKVTmsuWWvZpjuvqWFQ +/L+XRXi0cvhh+DY9vJiKNRg4exF7/tSedTJmLA8skuaXgAVez4rqzX4k1XnQo6Vi +YpAIQ4dGiijY24fDq2I/6pO3xlWtN+Lwu44Mnn2vWRtXijT69P5R12W8XS7+ciTU +NXu/iOo8f7mNDA== -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-no-names.key b/src/test/ssl/ssl/server-no-names.key index da86d1e22eb..2edea5c52c9 100644 --- a/src/test/ssl/ssl/server-no-names.key +++ b/src/test/ssl/ssl/server-no-names.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQC6VU212xAM+d99liOE5ROUG7qwuHhELgNbqGxUgNu8S/nKBrZS -sGzWnqA4//iGDXTZLHszRctXVrkhq2VXFCmRZLajk8uw4GtGCwb/HdvANrDM3rwi -U23yjX3Q5DvhvHgkG+0PBf2Ghr+/XEbDkAwB0xi8QhO33F+1uQEH4XJM4QIDAQAB -AoGBAJrFaDr5rqdYlc6W+wHT1SNctQE8+IiJP7jOeMzoC5yn7t9kG+UrLfxG3gb6 -ds/CNaB+VgcMng35tuTEnPRrhuoWh3d0jWZ/QqMklPMyrLO5s0wEOuW47D/KI4MR -wKoucQW44LrTdQgKsa4ZJbILKMScanY1oQXXjq4tueZaxajBAkEA4w8gO1rby9zQ -fIp2C4Mfi9Pe46c1/bM+AD+9hXRO9oYCE+aoi0ww4/qvE5fMYQluSmSd8Yhbvuzk -nifMF2l5xQJBANIVTdPudQvviCoXXtexl71b4KVdX9EjuWTNTCx64YB2ISg30YNw -xvlPvDQy/EvVj/3wSGAy5M/7ZVpkXCQe5G0CQC/Jgi4bzECWo6Zieb+ohB4opDNj -gMB5VeY1hAyvUuMdhxhrJjPTAEMrAmfsPc56bqTnkjpASZbgQqlqlNCkmUUCQHlV -epTLpWhWWMNOqiVTWbsxBGcdrchhpKLWe4c5FWKXV4Ed8/DBQvodFirjw5mc58QX -cgW1fzesD5aMXjcybGUCQQCZwYJir3OQC+CJCrsvACSPr3SQm28hiuO4P41dC7eT -JWluvXOGmWnZwskW/+6imEe7pGYnY81pKThnsV+CXfN9 +MIIEowIBAAKCAQEAnzn++HnaINkB5CZa3jujSRHtVWVEsZ/iwXhx/E+X54hYjOGJ +vV9qN1yoWLLzUsL631sDJGozJHd2971EYrogMWMwf/QMF/e0VJGfE37lN1ICEogm +yWa1R06XyRL+yYXj4GKQKDnT1qrRT5pzv17+rjY7K8f1f9wjqL1I93iHMkMwJfng +tlPU5//3SdJBfoQ5zkdyP93umwG6CYwFby5dgAa8mmrXh7lGgrvwX+ZhtQ2q1zVz +ymLj/iq5Ix4R9CkOCbN57u2zxIhtBPyZgkeOdo+9lim/j4iRzsXTDMs7Wd5Omxhp +W8OtIwsEJ1CQJTy+BvVPpaVWBun+x8TmiRLHHwIDAQABAoIBAAtkaeK7TSkGfcUm +HWBDIharSrDOcxDGYMH47SbhRvwQ3E0QIfvDpOTbI0xdWV11h9+NMndbhdc5GPD2 +wLrTmFQQRbsR6f+ZAHUAikIp1RqVKoLK7QOB7rxwWhnP2xzuEHTQeIH4STjVte4d +HeT2VgB+7tLeFqmURZTgHiVeoUWuPgl2/L7ABK8x7wk6/Ho/FyB6bQsX9ixfd99W +lxAhKr46Sa6ceMygswvqzxUcFm0lCSfMt+VTscZTqtQnqiV8mMiJk5novBUgpS95 +JaLsAKsG2mYKHBaAs+EbIbgk0hBWnGB6DFTd8/62u7fJFWA5BvMiNBnde47wLRJL +BAHzw7ECgYEA1DVbs4lN/GA8ol+ERGGIhZUa44jLgIFrE7kpYdKoi8AF8R8BaIjp +xlI6z+sxLcp7Z/jccRToGH20OX1i+x4Vt8NGvzkEOdowX+BwMl92v7vSrr6PGdWg +X5Nu6/ISVarIDWBSLGmdfqJ/szu+HRBh4CvFlrf+379COkZ9oc9Hh0kCgYEAwBWv +6J4oi4nbxyzpDpI5YH8wu56A6uNJAD5z3pca7XaR6mOLiJhqhCQscthx901dV2fT +tECOxX6/DEvI1LZejiyG0Y9LXfhH37ZpEsgY14SNC4SJOW3dzVld2JEcd/3+50A1 +86DXImZoWeZzbiavkAxecZFZ8zoTUifYeh9M0ycCgYAQHZE+PDIo9WIFbr2Lt+B3 +TJCDMRNLSgjIsaob3LSiEE4jNpiTyLoALqR6v8C3WoYuqi6Lg+vwWDOEnioTKgC6 +OOE5imnwvsonrdK3cJqDCw9/58bUTm3kdDzbPEH6MYMJyQPUjZzBTjPmd6YDbQgR +zyEtRgHcGhk8dbf6vtQOyQKBgQCg0geDhNeBbJybt9gwoPB1AEh27RAWmNDH6YHt +fSnIYxtr2Ig8hw+3LuogBWP1n8pkocM4CUz/wUyHKPQuU7n64wDFd2msdXEHtptm +ZC2YU5wbZo3VjUzE3uuZpHTnabr/Nl11atZ0MLVxf2ZpdO5Mdm6kOwPKhncis8Wl +CYuyxQKBgHPgMjy4OgNclXfZHkk8MrHYJrZsX4NYKCAQC9z5pkHP3Osakt5YPdPq +Hti6rFMzagHlYY7k8tMx9F3j/kQZrBq4yfQIWsnx+OIr1A/A/0jbmTHMMqlQ8EBN +p7nfoCzlvm0lHQV2nUb/9UfP/Wc5zDZZnnBm83zOTjBTBZ55twu6 -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-password.key b/src/test/ssl/ssl/server-password.key index adcd38ab882..337054fe4f0 100644 --- a/src/test/ssl/ssl/server-password.key +++ b/src/test/ssl/ssl/server-password.key @@ -1,18 +1,30 @@ -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: DES-CBC,2FAEFD1C1B2C881C +DEK-Info: DES-CBC,6FCB918813C446D2 -PGi9r3pm05iUwz5QbZik+ZNu0fHNaX8LJFZqpOhg0TV38csLtQ2PRjZ0Q/diBlVT -SD8JJnIvwPoIWXyMMTax/krFL0CpbFqgAzD4CEgfWxGNhwnMD1DkNaYp/UF/NfuF -7TqXomUlcH/pVaZlu7G0wrIo5rnjef70I7GEY2vwT5adSLsUBAgrs/u3MAAx/Wh4 -PkVxZELmyiH/8MdIevodjRcJrgIzRheEph39eHrWKgWeSbO0DEQK91vv3prICwo2 -w2iU0Zohf92QuquA2MKZWruCHb4A4HusUZf3Zc14Yueu/HyztSrHmFeBp0amlWep -/o6mx274XVj7IpanOPPM4qEhrF97LHdaSEPn9HwxvvV4GFJDNCVEBl4zuaHo0N8C -85GPazIxUWB3CB9PrtXduxeI22lwrIiUdmzA68EXHD7Wg8R90397MNMOomLgfNcu -rXarrTXmTNgOa20hc1Ue5AXg9fVS9V/5GP4Dn9SX/CdaE1rz0b73N/ViQzVrS9Ne -n04qYPbnf+MQmFWnzMXctZbYG6jDCbuGFIGP4i/LG+wOE8Rntu8Re9re+HANu5VJ -Ht20wYOGZIpNwo4YenxvPeTTlbB0Qcma2lnw2bt19owpNQVIeTnRQXxZs3/Y3a+A -+/B8VvIkQ0u0EpnSVLBetEmJqtOQvBz7c4Z+0Cl+DL1bTqrDn54MxUBap6dgU+/1 -R6pxx1F0ZTtQauVmO8n3rWKwOGG5NeMhf4iId2JWpw39VtRk8LNtnGUbUAbL5znY -rkUVyJstQg6U6kNTgDWQ1nBxCzlRz2xpHyghnyxLkMpW5ECpmwwLDQ== +rNHoFsQpQh1UGbh2QSgtWj/pkoe29Q+uZgEwbCTIfE/ONMoiZLC6f2g+PDPg2qYn +BC4VY2NbxkOLw7kK3k6cHwRD5YWfzm+HxmXQYsfPCeGV+C/Pse8srswh7GERSQ77 +zEn7BzkXnevL8ytYAoqezYjXaDSh+76KSN64R21zaGvgToQRGICCevbnjnNRI+HJ +sPGGFTRIWLNNnxULHYpFbMXoJSnOrCbpzEqshUFkdGTpLvLW9se3/LVMWy/Wssje +GwQbh9mDavUlFUl+vTn+ER4C0pzV10DjtQzkDhx88OIhdTsPQ8ClIvVFpBI6fjME +je1n4YkLWGfJrXpifg8hAedmQ9tiw/E+h8IjZJfUgL+C2QybCQ8Yx1/v8HUYzwkA +O7WMM90qI2sxzKWJZVvRVIY7zaTzFcvhpZrceX+d7iLV3h9UF4ru0CcUqK13t3ax +4oOvQnj8DP0fThQOloQX4zY1oUqgLNFdoqgwMIssHzCdsyZ5VdFz8iWA1n+syzKC +DGPJHo4DQ/YNpy0gGmBUcHaiyeKsaDYBQBwE7xm3UnrtYCr1WKkcYfncuNXCZdDJ +X8qiB1w6diDKor9NC15uBBVjv3ERCx1rgG98+KvenQob9dtd6iguLjWtUsQoGI8D +mgcwIuw4NRMIxZa5+1ITOkjnUfvXGTVHwvjHzz2BK6gFQu2NgwgZyrgqSMOZAn3T +JcDDEhE8lgAsEPHVsPiLuc7DbH/ehkv8VocqJE7K9vmdR2UVG2wOO7p/1Ewm0RfJ +9wsry4Ae0uqH+ay/TfMUBOC6tEqcPzicCMc9mYEOdnAjPwoDFFXLNdbjV8WG1KTr +zzn9cucFvbyDOKecWbrduTbEFU5LbTddlOwWBaYVlS8xDX8wYTTyK0HnpLtP5KRJ +69D+CYOnYAQyiPqRnZglIo4hSbNsiWThhWUlbGBWwynhR6fX4MA8PcoFnR88q3g3 +Wjmq0A0jIETwBxYrLFwvgi/PtQJ2p+yjhHCsl3idBgnGYtUiRxpCkuoCIBV1B23j +CJB3NVoOOVEoGi9WYonLOt6vciYQhkjTkM4u3JP6rB/9kDIRpW4HeXYzrhmo0JA2 +PtRbvEwJyMHNoyNc/Pf1ydb+lqv1TBUbPQLsNbzHLKklfAMhQGd3OJWn8NcGB4i7 +uXAHSA/zY5AuE4Vf6mdjCznKbqCGurT+CUctFBajLcV2gwaFT/DikzlzR+TdFJ8E +Qcg+5XUzg7E7tTrLGjM/DFES7ECkpr1cYGheCgoZLj0lT3bLURUUHG4e6BnyGS6M +AdeKh4mZL3HAcbI8rSyoTx0cszQu3BR4QeAMJcnsq69uuLZ3A/r5zYDTIerz53ZO +JYGhWWEsRszToO5eGGKpONIPTIYRLtj5NBfoQ7PZGRfRBlX44Vv3JytsBjrpABJI +iqge5jifhTKcWVB0/OAu3A3uKXOU7AozXa79sdTVRs2KoVAgRTDK7zy3FsYRsT03 +sBdZgR1pr90PhDjlJ6N3Ebk9MXbB9bcwx0C6C/aZPFTsXT6sEoPqlrd6gCLc/YU/ +uTaXmARj45I89uRcZtroq5dZy5HE5nBpds7Vydiz1MwBnIMyBRjjAg== -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-revoked.crt b/src/test/ssl/ssl/server-revoked.crt index 08a5e01526d..1ca5e6d3ef0 100644 --- a/src/test/ssl/ssl/server-revoked.crt +++ b/src/test/ssl/ssl/server-revoked.crt @@ -1,13 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIB/DCCAWWgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 -IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowRjEeMBwGA1UECwwV -UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1z -c2x0ZXN0LnRlc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOmX1G+61akp -XA8zveTsQOtipWN8UzF0TbtxFO6LndM4RMlMFPrS/18KAbOFcfSjQvw9dfMXfOIk -zuwIYtAPD2qVyWAGRvk0Xl5qEz8aaVBbayUN5uRMByF2vgbOMz4IEywNRTWZRS2x -kAFO4/FCb/LRxD+82yck8zcZoL+SdbZZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEA -LryjYf+t8X5j4DeeRN0uh3OWUpzFo7FaVcakjDQSgZIdlgA9RofL81yzJZAoSqk1 -zT8jqo0HKOAwunbNJxhIH54gAIpsEE9624IUAoLMo8OUF2WdMWLXJJTljfbXx/Tb -4ccuQvMLs+Um70Ogc7Mqm0+BM5N61lBdJOgMlDP511E= +MIIC/DCCAeQCAQYwDQYJKoZIhvcNAQELBQAwQjFAMD4GA1UEAww3VGVzdCBDQSBm +b3IgUG9zdGdyZVNRTCBTU0wgcmVncmVzc2lvbiB0ZXN0IHNlcnZlciBjZXJ0czAe +Fw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEYxHjAcBgNVBAsMFVBvc3Rn +cmVTUUwgdGVzdCBzdWl0ZTEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVz +dC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAooPO8lSz434p +4PBYBbTN8jkLW3cHEpTCH4yvC0V40hzGEl30HPLp82e+kxr+Q0+gd82fvc4Yth5I +PKINznp28GMs5/E9cUU3hMK4jFhKLMiOeIve3M/9ryHK874qpNjJoSxxPz7+s2eq +WoFc2px0KFIamTTLfi7Ju9aPb/AMlZNsUnbRsj7fQc7EJ8rwOnezw2Wy5VK4soX+ +qpuJ0Nm44ApzT8YmjYX/kAX0yQxgQuYbpcBWr9cOQjegu3FAqHqRh9ye7d8jQzCv +34Wg/ar4rkqyQDcokuWAE7KQbnk51t7omzhM8eswFOAL1pas/8jWBvy0VjYVU34P +9aXxP8GiHQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAS9abT/PhJgwAnm46Rzu16 +lL7tDb3SeR1RL25xZLzCexHcYJFi7aDZix3QlLRvf6HPqqUPuPYRICTBF4+fieEh +r5LotdAnadfYONwoB5GiYy2d93VGqlLosI27R6/tVvImXupviPpIYMDgBBRr1pZc +ykQOjog6T+xk9TqsfFQDe2/VKF7a5RxOA/V77GZ5qge5Nlx9jSXQ/WUG9vDQj9BA +d4nOwvjauKlcSqUU/3uVKntXQTNjmyq7S75eBitS920LLfjTL9LInLugDikFa/J/ +yPBkJLa/+rNMPikcnF3ci4Oi/XwLA8kGdGZAADuiIOeyORMuLFoTk7KpOYGKS5/U -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-revoked.key b/src/test/ssl/ssl/server-revoked.key index 33004170b79..17877543a69 100644 --- a/src/test/ssl/ssl/server-revoked.key +++ b/src/test/ssl/ssl/server-revoked.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQDpl9RvutWpKVwPM73k7EDrYqVjfFMxdE27cRTui53TOETJTBT6 -0v9fCgGzhXH0o0L8PXXzF3ziJM7sCGLQDw9qlclgBkb5NF5eahM/GmlQW2slDebk -TAchdr4GzjM+CBMsDUU1mUUtsZABTuPxQm/y0cQ/vNsnJPM3GaC/knW2WQIDAQAB -AoGATDyWQ6TZiK0L85Yyep00jt4SFkcEK9bGa897QmNkrgPmR0BCdJ4aZF0ysvFx -gKMsAIDaluzqgC/9LIGMJlVT9RisKWQks2cPIs5gERmYg7uNzfYegbn4N2liRG5z -d7aWevi82Dtie1xch2DdUW/mxGdvR4duyXOlSYUhbDmK8oECQQD4MylmccYxz8Ry -7APVKXPMhSCmD86y4KGfWGtKuLo4vF4Ifaze7sVtEBznNQLIAn2U4M5XD4to/VQN -2nT1ESHJAkEA8O8nDKC4vWtCXzMD2/DdHrJjxhCPbDJFp24PRFUia1yUOAgqcnfv -UzXkdcxSv/zUBB/WejLEvvrQ6Ib48Lq4EQJAZ8ashsMHhYhDsXFxYM1GN7tqHUT6 -vdwid8e2hLWcV2CbSJ2TjFr1fVaBX0LQ+OPhskAUxl4fgjR50pkG0fjp0QJAJvB/ -/yp6sSKEt54nIYTsN+nc9kX26CW33DeNgB3CUlfEHMo1EgsQQwKSyfcb6KuUGJaM -s3NBGRywZuRpl36WAQJBAKgyfmq15Ggoe4rQOyO774e1mfUQW6/fWVX8dE09ZxXz -28Sy4/K16UDUzIzzuaW3L7WjzCKql82vy2PpmWX28OM= +MIIEowIBAAKCAQEAooPO8lSz434p4PBYBbTN8jkLW3cHEpTCH4yvC0V40hzGEl30 +HPLp82e+kxr+Q0+gd82fvc4Yth5IPKINznp28GMs5/E9cUU3hMK4jFhKLMiOeIve +3M/9ryHK874qpNjJoSxxPz7+s2eqWoFc2px0KFIamTTLfi7Ju9aPb/AMlZNsUnbR +sj7fQc7EJ8rwOnezw2Wy5VK4soX+qpuJ0Nm44ApzT8YmjYX/kAX0yQxgQuYbpcBW +r9cOQjegu3FAqHqRh9ye7d8jQzCv34Wg/ar4rkqyQDcokuWAE7KQbnk51t7omzhM +8eswFOAL1pas/8jWBvy0VjYVU34P9aXxP8GiHQIDAQABAoIBABp1d0YBAGCzc8IJ +n2seasFbBDxZ/q7JxWk5kG43W1pqEN2AqnPkIK7eXyq4JFl1J10Z/z35xhAwkfY9 +NB4/1gmBPBhvMF+2szlMMpu27CyqYnfB3gD5ZAYVbGOOvIamPP2erLltWi5/XD7r +/OAixM6jv2zeKZtbpsCMSEIjRQk8+t4LXdT1ohrhm649QxmMpnYNjpXJ9U9uG0yP +lr2+Lk2Xjv025kP765iGP3U5fW0/sONxXVM7uUyrvtnMJPhsKOdsNO84ratOVcnM +BgzSEB0nldTcg7MUQyA+oOfDOXgoTQ5WZuXrx32sEDwN2ceCBg/qreaDwkC+KI7n +nWazf0ECgYEA0ebcOCWwZlwvM/FNgC7Uqbxn6kjAkNvcETWxiwSaEf6MsTyytCJv +RaVE7w5FsKKWxdu7ljft5LClNXTbscV5O5HuDMrLNSJFuhTm2dzYECZaUmXgN5gg +JQAhhxevk3UBkGB/EYEDEBNtGjGWdWn0kFIsY4oN5l946cA27WXmsSUCgYEAxjTA +XfGgM3+Q6hepN0J9XuVaebEkuTMlFmt82J4pMZxlam9zJDrDbzGVZ4kjCqLTh89v +Tt+hE3xu+Df5D4Vb/uC+bu4EBpnvlqJRPNz4aQFxt+UILznS+oS4mLV1gK5PbIMA +gh1+F58XJp3+NKxvUnjERpiUzZRgSh+9gtwWx5kCgYB3cfYzhU8CkMbTuicuIHgo +NuyzZ78dL9/lczabM30xbDdHzJCs7UOA0HGP0AFcaMl/wnDXJPCdSOBasSsr2IIK +ohpi8Sv+Coi/QZG0vHW/ivOvHAYh3NG9/HsX0yS4tsazEBZ/MXk6trNJSpqiKi9f +yUM1SaRrSj0WV6lqIqjKeQKBgDw27nIb4/WBPb9AbPISyw+3UeNCg8uX1B6ZjRYq +Bo3B27WYIjzRdWokgCUyLmkeynCp/kDSA5dt6DCUoJ+sfiRSlsgQmzx+K6Fxsohx +AS61d5zMgc4HHSdqhsIt7oKncg2fRtpAp3v5owjiWsYZ1MATXF2uIRbLiu0581L8 +FheRAoGBANFH5W0DtT9kyzdiPddfBMFnrsUYYIPgejAao7PvCCW5tX8CVDcRkLhf +tC9zZgA9WEm1irXZtbo9m3LYzH3yED8DvBcsfCdA20R/Ed/om2OiLKD7DDFl1W+C +2NrwzcQlRlhHC8V2D8yRU+6YQ4Eu9dYzFnkGeCGSbiqaa9ZkPYx8 -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-single-alt-name.crt b/src/test/ssl/ssl/server-single-alt-name.crt index 832aa051e77..e7403f3a6b4 100644 --- a/src/test/ssl/ssl/server-single-alt-name.crt +++ b/src/test/ssl/ssl/server-single-alt-name.crt @@ -1,13 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICBjCCAW+gAwIBAgIBAzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0 +MIIDCzCCAfOgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0 IENBIGZvciBQb3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNl -cnRzMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVowIDEeMBwGA1UECwwV -UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB -gQD8lRO7m7xRlUJCKdkHdPnLKu/pbHLBgIYJk33nr22CQaM0UCgfCzr0LPaPCtlF -r5D/WS/MIlyzaXHHJMnzbFB1bx3T9BQijobeO1LKS7s3ZyPEaiNVJoih6ZXlXMQ/ -sPp887EChn+COh9BWgnWbSV0Zq2m9bggDg83J34bIeWOmwIDAQABoy4wLDAqBgNV -HREEIzAhgh9zaW5nbGUuYWx0LW5hbWUucGctc3NsdGVzdC50ZXN0MA0GCSqGSIb3 -DQEBBQUAA4GBAIIcaM6MHSbH9t8cQhgWKXhjqlph/oRsNwTTalSamLR6JeT9BWxp -IZXrsgzIJsVlTSHj8JRZnv++6TVDe/1N2MtwNfJUqnblIFwaf83kulv18Vhwoh4l -dqPNaBZqdk9+EWJwPSzolK2VRKZcea+E2sMZBTYAV3pijy1k/oC8OX1V +cnRzMB4XDTE4MTEyNzEzNDA1NFoXDTQ2MDQxNDEzNDA1NFowIDEeMBwGA1UECwwV +UG9zdGdyZVNRTCB0ZXN0IHN1aXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAxYocLWWuiDsDzJ7wLc0zfwkGJAEy4hlHjTA5GXSEnGPlOnx1fxejZOGL +1HLff5h8zB+SQXrplHCcwwRrxVgGY7P59kXMXX1akTwXUJHc/EoTtqLO+6fHLygz +F1d0i5NPO3xrk1wMt7bYLhiPbWpplWiHXzbJy8wf3dXgzCwtxXf8Z1UqjtCnA/Zk +J/kPWuHJxzH5OvDJvZsq+Fbkl3catFpwUlAV9TKsC78W/K5I+afzppsmSvsIKAWW +Dp7g71IVjvJeI6Aui2yhDn9iuJMuKe9RMYIwJLFqiX3urHcjaBSkJm6Lsf7gO30v +kVwIyyGXRNTfZ2yPDoSXVZvOnq+gKwIDAQABoy4wLDAqBgNVHREEIzAhgh9zaW5n +bGUuYWx0LW5hbWUucGctc3NsdGVzdC50ZXN0MA0GCSqGSIb3DQEBCwUAA4IBAQBU +8wp8KZfS8vClx2gYSRlbXu3J1oAu4EBh45OuuRuLOJUhQZYcjFB3d/s0R1kcCQkB +EekV9X1iQSzk/HQq4uWi6ViUzxTR67Q6TXEFo8iuqJ6Rag7R7G6fhRD1upf1lev+ +rz7F9GsoWLyLAg8//DUfq1kfQUyy6TxamoRs0vipZ4s0p4G8rbRCxKT1WTRLJFdd +fSDVuMNuQQKTQXNdp6cYn+ikEhbUv/gG2S7Xiy2UM8oR7DR54nZBAKxgujWJZPfX +/ieSwLxnLFyePwtwgk9xMmywFBjHWTxSdyI1UnJwWC917BSw4M00djsRv5COsBX7 +v/Co7oiMyTrCqyCsWOBu -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-single-alt-name.key b/src/test/ssl/ssl/server-single-alt-name.key index 90b6bc4663e..f719b0d7131 100644 --- a/src/test/ssl/ssl/server-single-alt-name.key +++ b/src/test/ssl/ssl/server-single-alt-name.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXwIBAAKBgQD8lRO7m7xRlUJCKdkHdPnLKu/pbHLBgIYJk33nr22CQaM0UCgf -Czr0LPaPCtlFr5D/WS/MIlyzaXHHJMnzbFB1bx3T9BQijobeO1LKS7s3ZyPEaiNV -Joih6ZXlXMQ/sPp887EChn+COh9BWgnWbSV0Zq2m9bggDg83J34bIeWOmwIDAQAB -AoGBAOkekmraLvJBRzkXtJZcUVxBkdIn5LZRb+SQu2jFkdXhzMawoIceb1gD08Br -6+KUSshSQXov0M1KKdf6TWYc9xfGg0+XgqPLw0CIJjdO8TZkIaaHZU803snWtM0e -9PlhUm2T/RDdx0cG7HD4WR8x5ij1Fc+W5QsDOi5oCke0XC0xAkEA/+rmRUaOSOaI -CohIH+oHlLTLfr0acAP2cjQHJkf5OUBVnyirfCcsFsxmnhvARuuIdftwd9p73Gw9 -MIGVV6TDIwJBAPyp5xByHy7sicsi2ynSTpS9JhuVvR9cdKBLGmbPQtS0Fb0rannR -wyybfFIN1trfZJ6QmNKAPSPfUFhre3b4WikCQQDVOZYaairquojmnZ3aWVdvoyNZ -uZ1pbyPLC2ZZkuYnuV6deXlHvCuT40Iswdp2PJA6HQEcG0HP6a8h1xXjLDgZAkEA -wMKirTJTxgnh6l9SUyrGlsVjoGHx4k44D96catkvBHXLrAHGft/ghlStWTCDvYH3 -Et4AKYB6pLaHZp3BmPdKWQJBAMI65XkJC5+XESMUP26lC71eo6tMcJ9fBKOa7PEW -M9I04AeId/3nbA2eKCebfUzrZOizeHHOjhH3Dubz3df8Ww8= +MIIEpAIBAAKCAQEAxYocLWWuiDsDzJ7wLc0zfwkGJAEy4hlHjTA5GXSEnGPlOnx1 +fxejZOGL1HLff5h8zB+SQXrplHCcwwRrxVgGY7P59kXMXX1akTwXUJHc/EoTtqLO ++6fHLygzF1d0i5NPO3xrk1wMt7bYLhiPbWpplWiHXzbJy8wf3dXgzCwtxXf8Z1Uq +jtCnA/ZkJ/kPWuHJxzH5OvDJvZsq+Fbkl3catFpwUlAV9TKsC78W/K5I+afzppsm +SvsIKAWWDp7g71IVjvJeI6Aui2yhDn9iuJMuKe9RMYIwJLFqiX3urHcjaBSkJm6L +sf7gO30vkVwIyyGXRNTfZ2yPDoSXVZvOnq+gKwIDAQABAoIBAEtW0EZUKIuWjm1l +FM8zGvfRVkE3H9PxtkNX5/8YXFdVFiEHRLyzJEMebnkZUrpUSwyC4gINQba2eGM8 +dWnvl4hBJQ1TM41YeMk5dN7qsrCaBAi88VozdBk9KLc3SKDPDwHuAw1RpxwOJUb3 +YQRm+FveYPrkZ3RNpr2xi6nzE4XjAH3LbF8EqBYC7LUm4GUxBl6Ke2rQiC8XwE0B +0V0nvBvjkJ4tT4l9RTtInRr2vmqSWXp5bGVuuWqWxA/tBtTHhGbO+PG4i+C+u3NL +qQgCbboqxyivPaMiMDdDhQL9TjAMCkItVxcwZlGdSA0+d5mraIXhs2ifF45soo4Y +9vb4++kCgYEA6YpFAqYJnL0p5AIh14yxhWykLaE1YpKkw4P9SpxtGQIfwNDHyXme +v/S66fLNvOjQyH6Y+gvGBGVHAwpM0RiPAHBADKAue6V9pbUITD0aQL9HOj9LEC+V +8R2S5VSxNDpnMnd0DVdxiWGuNhzTG2McFXYduC3NpTLurK6ecPhVoI8CgYEA2ImC +ZN2NS15AxWybddSgYYcL/44t9dfpEJ/4PJ1ISStIibHqpVWkq7vC4P7mMmS3DItr +N3QDjBGltc1R4UfSCLakzSs5buC0LiO2uoMZFcOiZEd0r73iTLM8d9wOZRysYtHw +T2tS1NvMrwK4TGZh+GWuUlSfuIbZ505PCQfYnKUCgYBdynoMpkIWAKJiP7j3qDlj +LE6DRMr724jwPIHtBQWLlZ7LAQ47i+yFivPGIQ0fYSD4ZF9rjG7qNQJf5jMThpln +w6z1ZR9F6SCc/Cdo9uEkP62LZv/ucC33t7jXATxpjUsEqZSiBwxB8EjW0py10wfk +Vpt47Gw6fEn+b+KR3CoHYQKBgQDYKe4R41p6Ms1WSOWo62pv8fD4XWdkVPZFsmyN +ljXjVWJEk2g7RRPunLIfClejVwelbkjKQvaHjdZvd1iWHKyAJlS+vLfJCGjW5rAz +4UvZfkNO+EZ0aorPJt7miLeWGNm+jPXpUqqN9B6RV5XELzD+WAN+DRyliXlef75G +tZ54QQKBgQCDXfap0mLGYXbFMLPF4Q1mnML5deVjyoGteAF+qky54rZvf0h2bWN2 +pi8hUOdwTtazgkd+rJp/a7eqQL/72nvCMonsb7vBNHmmNqZgaC9zyTV9AOE0Txc/ +vU6rvU+nQvt7esuTILS1O4SEeNI0JG22Dx01ebJQuKDcyOTOxv56vw== -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server-ss.crt b/src/test/ssl/ssl/server-ss.crt index 9b4f4d1e80a..d775e6029ab 100644 --- a/src/test/ssl/ssl/server-ss.crt +++ b/src/test/ssl/ssl/server-ss.crt @@ -1,13 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIJAJ5i7OAq01pyMA0GCSqGSIb3DQEBCwUAMEYxJDAiBgNV -BAMMG2NvbW1vbi1uYW1lLnBnLXNzbHRlc3QudGVzdDEeMBwGA1UECwwVUG9zdGdy -ZVNRTCB0ZXN0IHN1aXRlMB4XDTE2MDkxMjE2MzAwMVoXDTQ0MDEyOTE2MzAwMVow -RjEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVzdC50ZXN0MR4wHAYDVQQL -DBVQb3N0Z3JlU1FMIHRlc3Qgc3VpdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBALkR7DNyRnAED7ZxnsfOPQ55QB0nM2onJmVZkG4EeqQJ6GZHJym7pHHwbww+ -dgXvlNzkv2SOvA+Yq8TXgYvSiKhZ4N4ReSWWZ71P+RqJXpSrj6K2mVKOw0Rno9kM -t0370bQOnkvSQY9BWxJbxji2ks3oj4wma+1zje3i46IlwoYHAgMBAAEwDQYJKoZI -hvcNAQELBQADgYEAZtnJALcQmbqBAm16RE/Smu75lBkniqlB0MwOJyGpDg5DkXtA -YnZP139cRWKCjbWiYj4hgK0eGGRoBuubF6zRrRlYLV9iyZyRx1cBYyUbQBW+AfER -jWiL4IBJWn7RNej6Uc0Th8Di5eEZapDt0DFkdALFhpFNaWJIcCUKpqEJHUA= +MIIDGDCCAgCgAwIBAgIUVR71MjsbvBO6T1gJQaL/6hMwhqQwDQYJKoZIhvcNAQEL +BQAwRjEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVzdC50ZXN0MR4wHAYD +VQQLDBVQb3N0Z3JlU1FMIHRlc3Qgc3VpdGUwHhcNMTgxMTI3MTM0MDU0WhcNNDYw +NDE0MTM0MDU0WjBGMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1zc2x0ZXN0LnRl +c3QxHjAcBgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBANWzVPMk7i5f+W0eEadRE+TTAtsIK08CkLMUnjs7 +zJkxnnm6RGBXPx6vK3AkAIi+wG4YmXjYP3GuMiXaLjnWh2kzBSfIRQyNbTThnhSu +3nDjAVkPexsSrPyiKimFuNgDfkGe5dQKa9Ag2SuVU4vd9SYxOMAiIFIC4ts4MLWW +Jf5D/PehdSuc0e5Me+91Nnbz90nlds4lHvuDR+aKnZlTHmch3wfhXv7lNQImIBzf +wl36Kd/bWB0fAEVFse3iZWmigaI/9FKh//WIq43TNLxn68OCQoyMe/HGjZDR/Xwo +3rE6jg6/iAwSWib9yabfYPKbqq2GoFy6aYmmEquaDgLuX7kCAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAtHR6o4UIO/aWEAzcmnJKsQDC999jbQGiqs9+v62mz5TvCk/1 +gL9/s/yfGY+pnDGW1ijI2xiL9KCJzjd8YB+F8iUViVQ6uHBxghxC1H2qOIr2UPFQ +gQRu7d0DByQBsiXMOdw10luGo1oHhqMe5J7VyMVG/7aRpr6zYKrH7PzsB8ucvxzv +Lm8ez0WBPebV69sim431iJcVcxxBbFd4qUJ9cHIc7VO2mSaazsIOzbd400POF/vk +gfpDs48GfnZ+X3hgoQA4u7eudLqttI+j1xV+IHlCtaa1nDHymUrN/FhI1x+6c1SU +V12eHqVatPMe0d+OCJPqIL9lbe+sGXlxDkMqAQ== -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server-ss.key b/src/test/ssl/ssl/server-ss.key index 69bc907b747..a5e7f4bbfaf 100644 --- a/src/test/ssl/ssl/server-ss.key +++ b/src/test/ssl/ssl/server-ss.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXgIBAAKBgQC3ekl7kd5dbcgs5UDu2im/oNSranNRqfqe4USVtiD9NPEWIc43 -wJhkp7w5BOf4xwWukrhOkpTzPLJwYH5HsQL6gBFZi095VExrdRopmpk268l41rSD -q+y0eWM+DoapoiU8tZ106RtMVSinDfXpXz6Nh9+WQ7/Q4EHWbREvf/SIeQIDAQAB -AoGAWbacqaRIk2xznag3WNMp6L5OXsa9Pmgb2IYTkBSvCsBRRd4fxFkS6tythz/j -4VwHZjXtktXPqSO7qIE2Hf3qkxfBpZ72qrvEDpHLXzEFXUamJMPRDZIBHrkfa/sl -pq+z0siCwO/ozoiInQFxArHeZs8MoGd/FYtECwbuvQd9LuUCQQDkYhlrELE7MB47 -Ot+vgkodp84p2LHlY48cLfn0Es+3aDzusWZbNDENmY9tOubIygh3qo0G2NtSEGVK -NZzm73GHAkEAzaoUKK3YCD95OKyj3FZ9P/32K1y7JqCH/9ux9dXBQLegdd0hWLk9 -USLlaPgC4FOVrSSbiQHbZ8lUewwtNeK1/wJBALf0nGy0wUzfcTpcLZh85Z4Fb/Yc -6Q3Pp5IXJmIGVPFyMMJCeiO0Yl6F9hURgJrywOdCpN2DBwWO10dy77LD4zkCQQCP -EJHnXk8aJbVYpFd0TcHhAvP8ZAxYKXGRnS0lWqWNNG9trf6lbm5mA4VcSLIPhHVp -NT7wxpbukpGu6uCETInXAkEAhF7m+XeHvJ0vrdpI3OSOVTW8o9QZSqUffsGB6eRb -v/dJvKgaz3JOzpvRS87lRUd62QfjfmiDXjyhllRn8OPMuw== +MIIEpQIBAAKCAQEAttI8Qu3wJgwp9RqLEqgO5GlYdA4bG+OyB4y+Bx4DQ7fhaJvJ +vwBfY8ig+nPZU5WJNDyoaPtDg2uQwWbUq9WXkdktAxelrisQ/oJiCscPARlAIM6U +XPOXai10XQ6QsMaaa6cXIGkMZVfhYEbuN0Q8TJSC1MbSQ/TtCnWxMRmktRv5xx8y +2DgGbYRSiuBNE0vneQMjBJeRs19k/V8Alk49vOk8T8Ep0PFkAQglpUc7/LFueKry +sVW+6ptdmqqHUZTdZhU/IojKEhUF8dtyGpGF9bE0kfjB7vXth8LKQ9Utik7VS1tQ +E8fK2ttvxAqDf8s3MChnXbMN6QrzaGSS44oZKwIDAQABAoIBAQCsMhjQcYxgSdS7 +J+UWDXT5bsABj8e43R4yPj4+NeadQfTtss6zOIagVbhKLhPkxlQU/40gVIminw4Z +G+H0d5nrpcLfxsYm5il7jxMJU7SuNDpSrEDRzB4xw952R+HAn0+TVi5SOJ+UVNHS +/Pwi0gJ5nugbwakKmQcrcu8ScDTS34yFScMIRUYiKQ44TDiDtwyL07sc4ob1X/uY +na1GnyOBjYEg+9nRwmV+QZwPjyP3Qe81rvH7saV2R2oc4uFU151KtoIT96V4FnpD +CsFPGVul4i428zYDEguzEMWvPkOKrfFA63gfYl3JRbPYE9ISdZXU8UX6XEE3Y6sU +VmeXK/IBAoGBAPLELsFdMqMhycXxrGuQ4HiH5/vQ2RhFcOf842a8qysopFC5kluf +Y83dMy9GP8BLgt/NMseBDFcaGgaZPhD10kpW0BCg5GKdkcBfuIE5C/rfe4m82TqC +VkriGimG8FkTCQS9ghGwbDWYZnMZbqyJ2iRt/+M9Lvfd1tYTCQtNuI/TAoGBAMDJ +g/vS12j4uJ+SDy7QY6suSOjkQoGO8qonhx9W/2XJSH4KL1ubeOt4eOJksHnwueCW +YD+2+T4+NDumMnmT7Rl8is1RfnnWNH91tylPB9I5Hyff/+PU5rUSoRfpmeckH3pc +5EmfoaqT7V436hjkZF1uY1QJjDMopSyg3TSVmtJJAoGBAOAVAAdSDGSR0ppYuktL +njcDU7mXjFwf9NjeD9UL/39F823j7NmPpWMnc5CGamAIE1SbJu0KDCb2G+HNX4Hu +Nd6ShVlj+YuhYCDO+hKlYo597J016Nld52MVkwqT2JSPwnpSppXHYAqUkrRZXFP8 +ppOLyW+qUQlQBnbxeR6q7dorAoGAU/gxzYCDJIyY1Z/njwtjLg8l4JJzSTz7AxPe +bc8VxL7MHWHQSMVKAL3jYTBcEXDBdUnqODY5D1xGoeh8uamtrtkpF860GNss2Its +MMjkbjNFF7ggG5sCtcGceu7bguqf70sAf/TQlJyD2fLeuuLXuD45c0QJVcsRToPu +dVXoLkkCgYEA5JkhCPE9a2ssrqi1ZFt3FAayulycM+r+wJY7zNIwv/ydzbE5D4Ar +s8YOjhwyBoyorrEztcvIKF5XA89ZIwHiKZQxJTWGeFKq/PYTclzwlOXAimkdYNXn +Nc/5RLjEeophXb4f3WPjMBliYGX0tOPhT+buHep+f0enxgO8Z2a4Omg= -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/ssl/server.crl b/src/test/ssl/ssl/server.crl index e481d011f67..717951c26a1 100644 --- a/src/test/ssl/ssl/server.crl +++ b/src/test/ssl/ssl/server.crl @@ -1,9 +1,11 @@ -----BEGIN X509 CRL----- -MIIBHTCBhzANBgkqhkiG9w0BAQUFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ -b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xNjA5 -MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMBQwEgIBBhcNMTYwOTEyMTYzMDAxWjAN -BgkqhkiG9w0BAQUFAAOBgQAm5J6912hKDUWXyu3yCEk1j3KICE2J42ZjFRvxBNdO -Zhv/iBjyFI6TmCVJqoe4GJbNG78xmNEl3/2ZUavG/aD0Z3xGu2xm0p+3Uh2zhfDQ -VEdlgFNKNItS0AtKvoduoZUXKnz3Ft09yLmz9yHLu6EslIsYryi+wnZ5DwUBj5Ec -WA== +MIIBnjCBhzANBgkqhkiG9w0BAQsFADBCMUAwPgYDVQQDDDdUZXN0IENBIGZvciBQ +b3N0Z3JlU1FMIFNTTCByZWdyZXNzaW9uIHRlc3Qgc2VydmVyIGNlcnRzFw0xODEx +MjcxMzQwNTVaFw00NjA0MTQxMzQwNTVaMBQwEgIBBhcNMTgxMTI3MTM0MDU1WjAN +BgkqhkiG9w0BAQsFAAOCAQEAbVuJXemxM6HLlIHGWlQvVmsmG4ZTQWiDnZjfmrND +xB4XsvZNPXnFkjdBENDROrbDRwm60SJDW73AbDbfq1IXAzSpuEyuRz61IyYKo0wq +nmObJtVdIu3bVlWIlDXaP5Emk3d7ouCj5f8Kyeb8gm4pL3N6e0eI63hCaS39hhE6 +RLGh9HU9ht1kKfgcTwmB5b2HTPb4M6z1AmSIaMVqZTjIspsUgNF2+GBm3fOnOaiZ +SEXWtgjMRXiIHbtU0va3LhSH5OSW0mh+L9oGUQDYnyuudnWGpulhqIp4qVkJRDDu +41HpD83dV2uRtBLvc25AFHj7kXBflbO3gvGZVPYf1zVghQ== -----END X509 CRL----- diff --git a/src/test/ssl/ssl/server_ca.crt b/src/test/ssl/ssl/server_ca.crt index 2bbb8c9c1bd..9f727bf9e9a 100644 --- a/src/test/ssl/ssl/server_ca.crt +++ b/src/test/ssl/ssl/server_ca.crt @@ -1,13 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMT4wPAYDVQQDDDVUZXN0 +MIIDDTCCAfWgAwIBAgIBATANBgkqhkiG9w0BAQsFADBAMT4wPAYDVQQDDDVUZXN0 IHJvb3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzdWl0 -ZTAeFw0xNjA5MTIxNjMwMDFaFw00NDAxMjkxNjMwMDFaMEIxQDA+BgNVBAMMN1Rl +ZTAeFw0xODExMjcxMzQwNTRaFw00NjA0MTQxMzQwNTRaMEIxQDA+BgNVBAMMN1Rl c3QgQ0EgZm9yIFBvc3RncmVTUUwgU1NMIHJlZ3Jlc3Npb24gdGVzdCBzZXJ2ZXIg -Y2VydHMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKpkEBIZexm3YZ94RA+c -vUREqvLgECfHlP9BbkXySFPGWcAPt/0uSW62eVS3UFcB9083W4w/uilL75PXDHV1 -37fyq+6LHCYE5TinzVr5ECAtQMpIzlKkAuAPq3mTa1fklwT/MCz/PKGAljs2o95w -mNyEJwTchOQ52fZjFexRiarNAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI -hvcNAQEFBQADgYEAP1ZhwGxsL7GTNxfs2qwYCjsF2zYSjCPXtwJnKFu5ayGxz6dB -paspokWFCglP1PwPAmINHeqp669WNnAmC5EixdTy2jcnod8NB6RlkOqJmNzVPhvO -cTZXxKd3awOzz0+IJ2bMcC9JPXs8phhRuRgvSfKTTZVtdcFmVF/HYIrBB5Y= +Y2VydHMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiSnYZbmc9vpCt +Ku1sKV9l663JCceubhMw8Gg16kV0hXEFf/TgGC4zkiYNHN7+G45YD7Nq0kBCq3dH +t2wPCc6c8pQoI64dfprVqPkvzoe1WBpZNetkUTk20v08jNeRa7XdRbRR6we1s9VG +/prp8Hs2mmHqEfLuI9lvTT0Dz+VMmfFI8Lf278r+w+qOtVloAkX7AOyoLEJlNS0B +QW9YWdH9N5ctaUXMG6lLV2OAjs+W1smpKfpIpMCA1lPGlElu70hynon/nQQvBP77 +SfQpZVc0esM18jkZpr5LEKUCw+x6LaMsqmBHpAULfCffxn2r0uMBW4L4VaGg3W6F +h6iuJwRfAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB +AFlcKTaU/Ug3Q0hr3P1UQ6dWyK4aVn9rs4jvVfFl0a0RnbBowqK2C+zQVUWYTcjo +KHREVje65goj6VzRB6ko/9mAQ6PZP8jRuRhfCmvmvSQ/mWdgPzSRsUh9MwgEm9c2 +vNbqwaznEU8cYZnLpHiR9O5S7/qWWxehjYtxk5Eb4J006YglYfHnhrRFJvPbiqlf +IOEivZ7gIVfvaOTbLjmN2kLOnzdlwpXGjxxg4Nu9ZhXOhfrplzUvRfmqvVsDiHXb +USIdX+OFZZqr64IKG4drT4K4Bt2wupOEyX4ZFsUXXd+Hgq83SWmV4wzflcpmGkLC +JZ3CEMu8/WA5uQBXdQUozlE= -----END CERTIFICATE----- diff --git a/src/test/ssl/ssl/server_ca.key b/src/test/ssl/ssl/server_ca.key index 668c37bff97..0204dcf5f4f 100644 --- a/src/test/ssl/ssl/server_ca.key +++ b/src/test/ssl/ssl/server_ca.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQCqZBASGXsZt2GfeEQPnL1ERKry4BAnx5T/QW5F8khTxlnAD7f9 -LklutnlUt1BXAfdPN1uMP7opS++T1wx1dd+38qvuixwmBOU4p81a+RAgLUDKSM5S -pALgD6t5k2tX5JcE/zAs/zyhgJY7NqPecJjchCcE3ITkOdn2YxXsUYmqzQIDAQAB -AoGATaLcI7MSgOwqggPFVyu+nS2AiruHAOkSPZ/tg9daFznISRegaK6/bL+d1vjT -lWFi8ugxQV0EEK710XHpzldQAH0YQ9YA86s7P/a4SjETdRChFYt+CV+aZ4feyNPV -OZcKuoE82MUFU03jaJsWJJ4jybPPTcZ0Rr25oFpkR2fnPMECQQDXrRWviHuLkmrV -WqZQLXiPt6bCrTowpnKo62Un5yrA7dehfL9b12J7/9tgfy0ZHXZtBXSHlELZ4LeA -wpYfsq59AkEAyj99EE++kU2QbkCqYKJ5xBQxNc2ntZ/EfiBXMuQNwncj4m86xFLj -coFHyOrRjo1GZAFxsZsNbf74xgMLDxIOkQJAHzKiWGndtSrQ2Vvrgt2Q+vkN3ktA -h5kMLPMgBs2hmZbOAkYRSC+3x0gTa7n5xBBG+S441QPVR78BzFZZcOxf4QJBAIVk -lH8iqYU6jE07l2Q/JWK/Eqny529yXe32NK0bHzwoymE5jaAZL2zBefA5eFe2NDwX -e75xjs0Cw2AOd8fL2BECQBqAafyDcER1SasqV5hkjyFQQu8FqzLUyppwbTKTRZji -s+xxGwP9jT9LaKC6w9nuzFmaGi0OO3ciE+I+X89YiKc= +MIIEpQIBAAKCAQEA4kp2GW5nPb6QrSrtbClfZeutyQnHrm4TMPBoNepFdIVxBX/0 +4BguM5ImDRze/huOWA+zatJAQqt3R7dsDwnOnPKUKCOuHX6a1aj5L86HtVgaWTXr +ZFE5NtL9PIzXkWu13UW0UesHtbPVRv6a6fB7Npph6hHy7iPZb009A8/lTJnxSPC3 +9u/K/sPqjrVZaAJF+wDsqCxCZTUtAUFvWFnR/TeXLWlFzBupS1djgI7PltbJqSn6 +SKTAgNZTxpRJbu9Icp6J/50ELwT++0n0KWVXNHrDNfI5Gaa+SxClAsPsei2jLKpg +R6QFC3wn38Z9q9LjAVuC+FWhoN1uhYeoricEXwIDAQABAoIBAG/c2Ua3Eegu5PwF +hXp7dUI/4BfKcuBiX7BIl2tXlOAF+xn56AZDTcuGirLeu8knvBUCJfI/Xy7V7lAQ +dyVz9qQVMnIpOTAxXr8SGaStVt6pX9UL14IuuLbGVBLzmLi1YyCwDXSVV6lV7a97 +uv68N1yFsrNwDgP0ys6/gtL4mWRkouFBbfJS9gDQjgSYTjWUx4wSkMw8h939RPkS +ccmdXJxwhDBTP8iJIhVVR0FK7fCQvsQCuchsvYPTu5VCExTfNhO5A8oGZncnQRPH +/RAAdPW2kAZV2oKkz5RAIDTnVkhXv1wQLty9E2PgjE04Fexe4Q7PCGmbrh7nBp73 +ARVuTRECgYEA/U3gwte+2pRzEciuoB4b+8Sod9eBxQGLhcQWOx2o0PAL2FIVWKxO +exUC/ipmEX0mEwnAvVKGO1MTsOj6LUZELgbnygscLEQc1bNauKuQu/ChVfBgJ9ng +IQR6z2BhrsOflfU8n01oMOjfVlVzZMdI5Nwy09OQgzu8tA125TUSkPkCgYEA5LL8 +bh5iykAlgXy7pA6WZmZXV9kaSTdnGGZ6GS4sbFJ8ZVw+tWi+xTUL9DES4keQTga7 +uneWu7q8wP7zdHCnKRhhBnbKFz1Voh4Z2VNSW9OjJHS4+lZfd94JZavOdwVMOQK9 +9Zjn2nsZalGb77pP/zDQSHnptwJOAKV9K5X5bhcCgYEA3wCODNtlogepWpHD8yEu +37Nd4cvv6mIW1Fgyfi75baC3vOVe96cSnNd9wAfRvjngqEgg0Exz8oyMPGaPwgYn +hiH8NGsdjXcVr6nsB8K7dEo/r2olLVBqOoc4G5Qty29b8uhpS5IZVV3fKaGnKqUr +7phRgx2yD2crFZT5BId55fkCgYEA0pk39zeoBVL4trrkF/kO6pEHkW/s0stf9oo3 +mYR5h+6VesltPaSNOBDXRzEBkLoR2qg8q0OA3LLjKl4cVnd+l0tJ3af6BViHyNgr +OYOO7dx/+Qw7Ytuy4jDnOmbxo4yPWlh6EPWTXA/LoaoxDJrnG7oZswQBAnPu3I2I +LGDY5lUCgYEAp/utnKRE/mXDFryMHJL2/srlg6EffzeM3ncpXhzZDmaKeMUadjKo +vNmhneHA7CSZM5LjUAiw4LfRx1V4hrKVtYmtizXKBbGYVZDD4CSh52T8w4nxNN6D ++uw478XrZzjjuCWODpdIKfngo9ip9+TysUZuFdmE3xKRitmDvW//aRE= -----END RSA PRIVATE KEY----- diff --git a/src/test/ssl/t/001_ssltests.pl b/src/test/ssl/t/001_ssltests.pl index 91feac613eb..67a3a28db6a 100644 --- a/src/test/ssl/t/001_ssltests.pl +++ b/src/test/ssl/t/001_ssltests.pl @@ -3,12 +3,17 @@ use PostgresNode; use TestLib; use Test::More; -use ServerSetup; + use File::Copy; +use FindBin; +use lib $FindBin::RealBin; + +use SSLServer; + if ($ENV{with_openssl} eq 'yes') { - plan tests => 64; + plan tests => 75; } else { @@ -49,30 +54,37 @@ $ENV{PGHOST} = $node->host; $ENV{PGPORT} = $node->port; $node->start; + +# Run this before we lock down access below. +my $result = $node->safe_psql('postgres', "SHOW ssl_library"); +is($result, 'OpenSSL', 'ssl_library parameter'); + configure_test_server_for_ssl($node, $SERVERHOSTADDR, 'trust'); note "testing password-protected keys"; -open my $sslconf, '>', $node->data_dir."/sslconfig.conf"; +open my $sslconf, '>', $node->data_dir . "/sslconfig.conf"; print $sslconf "ssl=on\n"; print $sslconf "ssl_cert_file='server-cn-only.crt'\n"; print $sslconf "ssl_key_file='server-password.key'\n"; print $sslconf "ssl_passphrase_command='echo wrongpassword'\n"; close $sslconf; -command_fails(['pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart'], - 'restart fails with password-protected key file with wrong password'); +command_fails( + [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ], + 'restart fails with password-protected key file with wrong password'); $node->_update_pid(0); -open $sslconf, '>', $node->data_dir."/sslconfig.conf"; +open $sslconf, '>', $node->data_dir . "/sslconfig.conf"; print $sslconf "ssl=on\n"; print $sslconf "ssl_cert_file='server-cn-only.crt'\n"; print $sslconf "ssl_key_file='server-password.key'\n"; print $sslconf "ssl_passphrase_command='echo secret1'\n"; close $sslconf; -command_ok(['pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart'], - 'restart succeeds with password-protected key file'); +command_ok( + [ 'pg_ctl', '-D', $node->data_dir, '-l', $node->logfile, 'restart' ], + 'restart succeeds with password-protected key file'); $node->_update_pid(1); ### Run client-side tests. @@ -86,179 +98,235 @@ switch_server_cert($node, 'server-cn-only'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test"; + "user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test"; # The server should not accept non-SSL connections. -test_connect_fails($common_connstr, "sslmode=disable", - qr/\Qno pg_hba.conf entry\E/, - "server doesn't accept non-SSL connections"); +test_connect_fails( + $common_connstr, "sslmode=disable", + qr/\Qno pg_hba.conf entry\E/, + "server doesn't accept non-SSL connections"); # Try without a root cert. In sslmode=require, this should work. In verify-ca # or verify-full mode it should fail. -test_connect_ok($common_connstr, "sslrootcert=invalid sslmode=require", - "connect without server root cert sslmode=require"); -test_connect_fails($common_connstr, "sslrootcert=invalid sslmode=verify-ca", - qr/root certificate file "invalid" does not exist/, - "connect without server root cert sslmode=verify-ca"); -test_connect_fails($common_connstr, "sslrootcert=invalid sslmode=verify-full", - qr/root certificate file "invalid" does not exist/, - "connect without server root cert sslmode=verify-full"); +test_connect_ok( + $common_connstr, + "sslrootcert=invalid sslmode=require", + "connect without server root cert sslmode=require"); +test_connect_fails( + $common_connstr, + "sslrootcert=invalid sslmode=verify-ca", + qr/root certificate file "invalid" does not exist/, + "connect without server root cert sslmode=verify-ca"); +test_connect_fails( + $common_connstr, + "sslrootcert=invalid sslmode=verify-full", + qr/root certificate file "invalid" does not exist/, + "connect without server root cert sslmode=verify-full"); # Try with wrong root cert, should fail. (We're using the client CA as the # root, but the server's key is signed by the server CA.) test_connect_fails($common_connstr, - "sslrootcert=ssl/client_ca.crt sslmode=require", - qr/SSL error/, - "connect with wrong server root cert sslmode=require"); + "sslrootcert=ssl/client_ca.crt sslmode=require", + qr/SSL error/, "connect with wrong server root cert sslmode=require"); test_connect_fails($common_connstr, - "sslrootcert=ssl/client_ca.crt sslmode=verify-ca", - qr/SSL error/, - "connect with wrong server root cert sslmode=verify-ca"); + "sslrootcert=ssl/client_ca.crt sslmode=verify-ca", + qr/SSL error/, "connect with wrong server root cert sslmode=verify-ca"); test_connect_fails($common_connstr, - "sslrootcert=ssl/client_ca.crt sslmode=verify-full", - qr/SSL error/, - "connect with wrong server root cert sslmode=verify-full"); + "sslrootcert=ssl/client_ca.crt sslmode=verify-full", + qr/SSL error/, "connect with wrong server root cert sslmode=verify-full"); # Try with just the server CA's cert. This fails because the root file # must contain the whole chain up to the root CA. test_connect_fails($common_connstr, - "sslrootcert=ssl/server_ca.crt sslmode=verify-ca", - qr/SSL error/, - "connect with server CA cert, without root CA"); + "sslrootcert=ssl/server_ca.crt sslmode=verify-ca", + qr/SSL error/, "connect with server CA cert, without root CA"); # And finally, with the correct root cert. -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=require", - "connect with correct server CA cert file sslmode=require"); -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca", - "connect with correct server CA cert file sslmode=verify-ca"); -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-full", - "connect with correct server CA cert file sslmode=verify-full"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=require", + "connect with correct server CA cert file sslmode=require"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca", + "connect with correct server CA cert file sslmode=verify-ca"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-full", + "connect with correct server CA cert file sslmode=verify-full"); # Test with cert root file that contains two certificates. The client should # be able to pick the right one, regardless of the order in the file. -test_connect_ok($common_connstr, - "sslrootcert=ssl/both-cas-1.crt sslmode=verify-ca", - "cert root file that contains two certificates, order 1"); -test_connect_ok($common_connstr, - "sslrootcert=ssl/both-cas-2.crt sslmode=verify-ca", - "cert root file that contains two certificates, order 2"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/both-cas-1.crt sslmode=verify-ca", + "cert root file that contains two certificates, order 1"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/both-cas-2.crt sslmode=verify-ca", + "cert root file that contains two certificates, order 2"); # CRL tests # Invalid CRL filename is the same as no CRL, succeeds -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=invalid", - "sslcrl option with invalid file name"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=invalid", + "sslcrl option with invalid file name"); # A CRL belonging to a different CA is not accepted, fails -test_connect_fails($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/client.crl", - qr/SSL error/, - "CRL belonging to a different CA"); +test_connect_fails( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/client.crl", + qr/SSL error/, + "CRL belonging to a different CA"); # With the correct CRL, succeeds (this cert is not revoked) -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl", - "CRL with a non-revoked cert"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl", + "CRL with a non-revoked cert"); # Check that connecting with verify-full fails, when the hostname doesn't # match the hostname in the server's certificate. $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; - -test_connect_ok($common_connstr, "sslmode=require host=wronghost.test", - "mismatch between host name and server certificate sslmode=require"); -test_connect_ok($common_connstr, "sslmode=verify-ca host=wronghost.test", - "mismatch between host name and server certificate sslmode=verify-ca"); -test_connect_fails($common_connstr, "sslmode=verify-full host=wronghost.test", - qr/\Qserver certificate for "common-name.pg-ssltest.test" does not match host name "wronghost.test"\E/, - "mismatch between host name and server certificate sslmode=verify-full"); + "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; + +test_connect_ok( + $common_connstr, + "sslmode=require host=wronghost.test", + "mismatch between host name and server certificate sslmode=require"); +test_connect_ok( + $common_connstr, + "sslmode=verify-ca host=wronghost.test", + "mismatch between host name and server certificate sslmode=verify-ca"); +test_connect_fails( + $common_connstr, + "sslmode=verify-full host=wronghost.test", + qr/\Qserver certificate for "common-name.pg-ssltest.test" does not match host name "wronghost.test"\E/, + "mismatch between host name and server certificate sslmode=verify-full"); # Test Subject Alternative Names. switch_server_cert($node, 'server-multiple-alt-names'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; - -test_connect_ok($common_connstr, "host=dns1.alt-name.pg-ssltest.test", - "host name matching with X.509 Subject Alternative Names 1"); -test_connect_ok($common_connstr, "host=dns2.alt-name.pg-ssltest.test", - "host name matching with X.509 Subject Alternative Names 2"); -test_connect_ok($common_connstr, "host=foo.wildcard.pg-ssltest.test", - "host name matching with X.509 Subject Alternative Names wildcard"); - -test_connect_fails($common_connstr, "host=wronghost.alt-name.pg-ssltest.test", - qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, - "host name not matching with X.509 Subject Alternative Names"); -test_connect_fails($common_connstr, - "host=deep.subdomain.wildcard.pg-ssltest.test", - qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, - "host name not matching with X.509 Subject Alternative Names wildcard"); + "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; + +test_connect_ok( + $common_connstr, + "host=dns1.alt-name.pg-ssltest.test", + "host name matching with X.509 Subject Alternative Names 1"); +test_connect_ok( + $common_connstr, + "host=dns2.alt-name.pg-ssltest.test", + "host name matching with X.509 Subject Alternative Names 2"); +test_connect_ok( + $common_connstr, + "host=foo.wildcard.pg-ssltest.test", + "host name matching with X.509 Subject Alternative Names wildcard"); + +test_connect_fails( + $common_connstr, + "host=wronghost.alt-name.pg-ssltest.test", + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, + "host name not matching with X.509 Subject Alternative Names"); +test_connect_fails( + $common_connstr, + "host=deep.subdomain.wildcard.pg-ssltest.test", + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 2 other names) does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, + "host name not matching with X.509 Subject Alternative Names wildcard"); # Test certificate with a single Subject Alternative Name. (this gives a # slightly different error message, that's all) switch_server_cert($node, 'server-single-alt-name'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; - -test_connect_ok($common_connstr, "host=single.alt-name.pg-ssltest.test", - "host name matching with a single X.509 Subject Alternative Name"); - -test_connect_fails($common_connstr, "host=wronghost.alt-name.pg-ssltest.test", - qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, - "host name not matching with a single X.509 Subject Alternative Name"); -test_connect_fails($common_connstr, - "host=deep.subdomain.wildcard.pg-ssltest.test", - qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, - "host name not matching with a single X.509 Subject Alternative Name wildcard"); + "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; + +test_connect_ok( + $common_connstr, + "host=single.alt-name.pg-ssltest.test", + "host name matching with a single X.509 Subject Alternative Name"); + +test_connect_fails( + $common_connstr, + "host=wronghost.alt-name.pg-ssltest.test", + qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "wronghost.alt-name.pg-ssltest.test"\E/, + "host name not matching with a single X.509 Subject Alternative Name"); +test_connect_fails( + $common_connstr, + "host=deep.subdomain.wildcard.pg-ssltest.test", + qr/\Qserver certificate for "single.alt-name.pg-ssltest.test" does not match host name "deep.subdomain.wildcard.pg-ssltest.test"\E/, + "host name not matching with a single X.509 Subject Alternative Name wildcard" +); # Test server certificate with a CN and SANs. Per RFCs 2818 and 6125, the CN # should be ignored when the certificate has both. switch_server_cert($node, 'server-cn-and-alt-names'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; - -test_connect_ok($common_connstr, "host=dns1.alt-name.pg-ssltest.test", - "certificate with both a CN and SANs 1"); -test_connect_ok($common_connstr, "host=dns2.alt-name.pg-ssltest.test", - "certificate with both a CN and SANs 2"); -test_connect_fails($common_connstr, "host=common-name.pg-ssltest.test", - qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E/, - "certificate with both a CN and SANs ignores CN"); + "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR sslmode=verify-full"; + +test_connect_ok( + $common_connstr, + "host=dns1.alt-name.pg-ssltest.test", + "certificate with both a CN and SANs 1"); +test_connect_ok( + $common_connstr, + "host=dns2.alt-name.pg-ssltest.test", + "certificate with both a CN and SANs 2"); +test_connect_fails( + $common_connstr, + "host=common-name.pg-ssltest.test", + qr/\Qserver certificate for "dns1.alt-name.pg-ssltest.test" (and 1 other name) does not match host name "common-name.pg-ssltest.test"\E/, + "certificate with both a CN and SANs ignores CN"); # Finally, test a server certificate that has no CN or SANs. Of course, that's # not a very sensible certificate, but libpq should handle it gracefully. switch_server_cert($node, 'server-no-names'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; - -test_connect_ok($common_connstr, - "sslmode=verify-ca host=common-name.pg-ssltest.test", - "server certificate without CN or SANs sslmode=verify-ca"); -test_connect_fails($common_connstr, - "sslmode=verify-full host=common-name.pg-ssltest.test", - qr/could not get server's host name from server certificate/, - "server certificate without CN or SANs sslmode=verify-full"); + "user=ssltestuser dbname=trustdb sslcert=invalid sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; + +test_connect_ok( + $common_connstr, + "sslmode=verify-ca host=common-name.pg-ssltest.test", + "server certificate without CN or SANs sslmode=verify-ca"); +test_connect_fails( + $common_connstr, + "sslmode=verify-full host=common-name.pg-ssltest.test", + qr/could not get server's host name from server certificate/, + "server certificate without CN or SANs sslmode=verify-full"); # Test that the CRL works switch_server_cert($node, 'server-revoked'); $common_connstr = -"user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test"; + "user=ssltestuser dbname=trustdb sslcert=invalid hostaddr=$SERVERHOSTADDR host=common-name.pg-ssltest.test"; # Without the CRL, succeeds. With it, fails. -test_connect_ok($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca", - "connects without client-side CRL"); -test_connect_fails($common_connstr, - "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl", - qr/SSL error/, - "does not connect with client-side CRL"); +test_connect_ok( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca", + "connects without client-side CRL"); +test_connect_fails( + $common_connstr, + "sslrootcert=ssl/root+server_ca.crt sslmode=verify-ca sslcrl=ssl/root+server.crl", + qr/SSL error/, + "does not connect with client-side CRL"); + +# pg_stat_ssl +command_like( + [ + 'psql', '-X', + '-A', '-F', + ',', '-P', + 'null=_null_', '-d', + "$common_connstr sslrootcert=invalid", '-c', + "SELECT * FROM pg_stat_ssl WHERE pid = pg_backend_pid()" + ], + qr{^pid,ssl,version,cipher,bits,compression,client_dn,client_serial,issuer_dn\r?\n + ^\d+,t,TLSv[\d.]+,[\w-]+,\d+,f,_null_,_null_,_null_\r?$}mx, + 'pg_stat_ssl view without client certificate'); ### Server-side tests. ### @@ -267,50 +335,106 @@ note "running server tests"; $common_connstr = -"sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR"; + "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=certdb hostaddr=$SERVERHOSTADDR"; # no client cert -test_connect_fails($common_connstr, - "user=ssltestuser sslcert=invalid", - qr/connection requires a valid client certificate/, - "certificate authorization fails without client cert"); +test_connect_fails( + $common_connstr, + "user=ssltestuser sslcert=invalid", + qr/connection requires a valid client certificate/, + "certificate authorization fails without client cert"); # correct client cert -test_connect_ok($common_connstr, - "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", - "certificate authorization succeeds with correct client cert"); +test_connect_ok( + $common_connstr, + "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + "certificate authorization succeeds with correct client cert"); + +# pg_stat_ssl +command_like( + [ + 'psql', + '-X', + '-A', + '-F', + ',', + '-P', + 'null=_null_', + '-d', + "$common_connstr user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + '-c', + "SELECT * FROM pg_stat_ssl WHERE pid = pg_backend_pid()" + ], + qr{^pid,ssl,version,cipher,bits,compression,client_dn,client_serial,issuer_dn\r?\n + ^\d+,t,TLSv[\d.]+,[\w-]+,\d+,f,/CN=ssltestuser,1,\Q/CN=Test CA for PostgreSQL SSL regression test client certs\E\r?$}mx, + 'pg_stat_ssl with client certificate'); # client key with wrong permissions -test_connect_fails($common_connstr, - "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_wrongperms_tmp.key", - qr!\Qprivate key file "ssl/client_wrongperms_tmp.key" has group or world access\E!, - "certificate authorization fails because of file permissions"); +SKIP: +{ + skip "Permissions check not enforced on Windows", 2 if ($windows_os); + + test_connect_fails( + $common_connstr, + "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_wrongperms_tmp.key", + qr!\Qprivate key file "ssl/client_wrongperms_tmp.key" has group or world access\E!, + "certificate authorization fails because of file permissions"); +} # client cert belonging to another user -test_connect_fails($common_connstr, - "user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", - qr/certificate authentication failed for user "anotheruser"/, - "certificate authorization fails with client cert belonging to another user"); +test_connect_fails( + $common_connstr, + "user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + qr/certificate authentication failed for user "anotheruser"/, + "certificate authorization fails with client cert belonging to another user" +); # revoked client cert -test_connect_fails($common_connstr, - "user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked_tmp.key", - qr/SSL error/, - "certificate authorization fails with revoked client cert"); +test_connect_fails( + $common_connstr, + "user=ssltestuser sslcert=ssl/client-revoked.crt sslkey=ssl/client-revoked_tmp.key", + qr/SSL error/, + "certificate authorization fails with revoked client cert"); + +# Check that connecting with auth-option verify-full in pg_hba: +# works, iff username matches Common Name +# fails, iff username doesn't match Common Name. +$common_connstr = + "sslrootcert=ssl/root+server_ca.crt sslmode=require dbname=verifydb hostaddr=$SERVERHOSTADDR"; + +test_connect_ok( + $common_connstr, + "user=ssltestuser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + "auth_option clientcert=verify-full succeeds with matching username and Common Name" +); + +test_connect_fails( + $common_connstr, + "user=anotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + qr/FATAL/, + "auth_option clientcert=verify-full fails with mismatching username and Common Name" +); + +# Check that connecting with auth-optionverify-ca in pg_hba : +# works, when username doesn't match Common Name +test_connect_ok( + $common_connstr, + "user=yetanotheruser sslcert=ssl/client.crt sslkey=ssl/client_tmp.key", + "auth_option clientcert=verify-ca succeeds with mismatching username and Common Name" +); # intermediate client_ca.crt is provided by client, and isn't in server's ssl_ca_file switch_server_cert($node, 'server-cn-only', 'root_ca'); $common_connstr = -"user=ssltestuser dbname=certdb sslkey=ssl/client_tmp.key sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; + "user=ssltestuser dbname=certdb sslkey=ssl/client_tmp.key sslrootcert=ssl/root+server_ca.crt hostaddr=$SERVERHOSTADDR"; -test_connect_ok($common_connstr, - "sslmode=require sslcert=ssl/client+client_ca.crt", - "intermediate client certificate is provided by client"); +test_connect_ok( + $common_connstr, + "sslmode=require sslcert=ssl/client+client_ca.crt", + "intermediate client certificate is provided by client"); test_connect_fails($common_connstr, "sslmode=require sslcert=ssl/client.crt", - qr/SSL error/, - "intermediate client certificate is missing"); + qr/SSL error/, "intermediate client certificate is missing"); # clean up -unlink("ssl/client_tmp.key", - "ssl/client_wrongperms_tmp.key", - "ssl/client-revoked_tmp.key"); +unlink("ssl/client_tmp.key", "ssl/client_wrongperms_tmp.key", + "ssl/client-revoked_tmp.key"); diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl index a805a3196bf..c08aa19aee5 100644 --- a/src/test/ssl/t/002_scram.pl +++ b/src/test/ssl/t/002_scram.pl @@ -5,22 +5,27 @@ use PostgresNode; use TestLib; use Test::More; -use ServerSetup; + use File::Copy; +use FindBin; +use lib $FindBin::RealBin; + +use SSLServer; + if ($ENV{with_openssl} ne 'yes') { plan skip_all => 'SSL not supported by this build'; } -my $number_of_tests = 6; - # This is the hostname used to connect to the server. my $SERVERHOSTADDR = '127.0.0.1'; # Determine whether build supports tls-server-end-point. my $supports_tls_server_end_point = - check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1"); + check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1"); + +my $number_of_tests = $supports_tls_server_end_point ? 9 : 10; # Allocation of base connection string shared among multiple tests. my $common_connstr; @@ -39,40 +44,57 @@ # Configure server for SSL connections, with password handling. configure_test_server_for_ssl($node, $SERVERHOSTADDR, "scram-sha-256", - "pass", "scram-sha-256"); + "pass", "scram-sha-256"); switch_server_cert($node, 'server-cn-only'); $ENV{PGPASSWORD} = "pass"; $common_connstr = -"user=ssltestuser dbname=trustdb sslmode=require hostaddr=$SERVERHOSTADDR"; + "dbname=trustdb sslmode=require sslcert=invalid sslrootcert=invalid hostaddr=$SERVERHOSTADDR"; # Default settings -test_connect_ok($common_connstr, '', - "SCRAM authentication with default channel binding"); - -# Channel binding settings -test_connect_ok($common_connstr, - "scram_channel_binding=tls-unique", - "SCRAM authentication with tls-unique as channel binding"); -test_connect_ok($common_connstr, - "scram_channel_binding=''", - "SCRAM authentication without channel binding"); +test_connect_ok($common_connstr, "user=ssltestuser", + "Basic SCRAM authentication with SSL"); + +# Test channel_binding +test_connect_fails( + $common_connstr, + "user=ssltestuser channel_binding=invalid_value", + qr/invalid channel_binding value: "invalid_value"/, + "SCRAM with SSL and channel_binding=invalid_value"); +test_connect_ok( + $common_connstr, + "user=ssltestuser channel_binding=disable", + "SCRAM with SSL and channel_binding=disable"); if ($supports_tls_server_end_point) { - test_connect_ok($common_connstr, - "scram_channel_binding=tls-server-end-point", - "SCRAM authentication with tls-server-end-point as channel binding"); + test_connect_ok( + $common_connstr, + "user=ssltestuser channel_binding=require", + "SCRAM with SSL and channel_binding=require"); } else { - test_connect_fails($common_connstr, - "scram_channel_binding=tls-server-end-point", - qr/channel binding type "tls-server-end-point" is not supported by this build/, - "SCRAM authentication with tls-server-end-point as channel binding"); - $number_of_tests++; + test_connect_fails( + $common_connstr, + "user=ssltestuser channel_binding=require", + qr/could not connect to server: channel binding is required, but server did not offer an authentication method that supports channel binding/, + "SCRAM with SSL and channel_binding=require"); } -test_connect_fails($common_connstr, - "scram_channel_binding=not-exists", - qr/unsupported SCRAM channel-binding type/, - "SCRAM authentication with invalid channel binding"); + +# Now test when the user has an MD5-encrypted password; should fail +test_connect_fails( + $common_connstr, + "user=md5testuser channel_binding=require", + qr/Channel binding required but not supported by server's authentication request/, + "MD5 with SSL and channel_binding=require"); + +# Now test with auth method 'cert' by connecting to 'certdb'. Should +# fail, because channel binding is not performed. +copy("ssl/client.key", "ssl/client_tmp.key"); +chmod 0600, "ssl/client_tmp.key"; +test_connect_fails( + "sslcert=ssl/client.crt sslkey=ssl/client_tmp.key hostaddr=$SERVERHOSTADDR", + "dbname=certdb user=ssltestuser channel_binding=require", + qr/Channel binding required, but server authenticated client without channel binding/, + "Cert authentication and channel_binding=require"); done_testing($number_of_tests); diff --git a/src/test/ssl/ServerSetup.pm b/src/test/ssl/t/SSLServer.pm similarity index 59% rename from src/test/ssl/ServerSetup.pm rename to src/test/ssl/t/SSLServer.pm index e81f4df7c5d..005955a2ff7 100644 --- a/src/test/ssl/ServerSetup.pm +++ b/src/test/ssl/t/SSLServer.pm @@ -14,7 +14,17 @@ # The server is configured to only accept connections from localhost. If you # want to run the client from another host, you'll have to configure that # manually. -package ServerSetup; +# +# Note: Someone running these test could have key or certificate files +# in their ~/.postgresql/, which would interfere with the tests. The +# way to override that is to specify sslcert=invalid and/or +# sslrootcert=invalid if no actual certificate is used for a +# particular test. libpq will ignore specifications that name +# nonexisting files. (sslkey and sslcrl do not need to specified +# explicitly because an invalid sslcert or sslrootcert, respectively, +# causes those to be ignored.) + +package SSLServer; use strict; use warnings; @@ -38,24 +48,34 @@ our @EXPORT = qw( # The second argument is a complementary connection string. sub test_connect_ok { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($common_connstr, $connstr, $test_name) = @_; my $cmd = [ - 'psql', '-X', '-A', '-t', '-c', "SELECT \$\$connected with $connstr\$\$", - '-d', "$common_connstr $connstr" ]; + 'psql', '-X', '-A', '-t', '-c', + "SELECT \$\$connected with $connstr\$\$", + '-d', "$common_connstr $connstr" + ]; command_ok($cmd, $test_name); + return; } sub test_connect_fails { + local $Test::Builder::Level = $Test::Builder::Level + 1; + my ($common_connstr, $connstr, $expected_stderr, $test_name) = @_; my $cmd = [ - 'psql', '-X', '-A', '-t', '-c', "SELECT \$\$connected with $connstr\$\$", - '-d', "$common_connstr $connstr" ]; + 'psql', '-X', '-A', '-t', '-c', + "SELECT \$\$connected with $connstr\$\$", + '-d', "$common_connstr $connstr" + ]; command_fails_like($cmd, $expected_stderr, $test_name); + return; } # Copy a set of files, taking into account wildcards @@ -71,6 +91,7 @@ sub copy_files copy($orig_file, "$dest/$base_file") or die "Could not copy $orig_file to $dest"; } + return; } sub configure_test_server_for_ssl @@ -81,17 +102,26 @@ sub configure_test_server_for_ssl # Create test users and databases $node->psql('postgres', "CREATE USER ssltestuser"); + $node->psql('postgres', "CREATE USER md5testuser"); $node->psql('postgres', "CREATE USER anotheruser"); + $node->psql('postgres', "CREATE USER yetanotheruser"); $node->psql('postgres', "CREATE DATABASE trustdb"); $node->psql('postgres', "CREATE DATABASE certdb"); + $node->psql('postgres', "CREATE DATABASE verifydb"); # Update password of each user as needed. if (defined($password)) { $node->psql('postgres', -"SET password_encryption='$password_enc'; ALTER USER ssltestuser PASSWORD '$password';"); + "SET password_encryption='$password_enc'; ALTER USER ssltestuser PASSWORD '$password';" + ); + # A special user that always has an md5-encrypted password + $node->psql('postgres', + "SET password_encryption='md5'; ALTER USER md5testuser PASSWORD '$password';" + ); $node->psql('postgres', -"SET password_encryption='$password_enc'; ALTER USER anotheruser PASSWORD '$password';"); + "SET password_encryption='$password_enc'; ALTER USER anotheruser PASSWORD '$password';" + ); } # enable logging etc. @@ -103,7 +133,7 @@ sub configure_test_server_for_ssl print $conf "log_statement=all\n"; # enable SSL and set up server key - print $conf "include 'sslconfig.conf'"; + print $conf "include 'sslconfig.conf'\n"; close $conf; @@ -111,7 +141,7 @@ sub configure_test_server_for_ssl open my $sslconf, '>', "$pgdata/sslconfig.conf"; close $sslconf; -# Copy all server certificates and keys, and client root cert, to the data dir + # Copy all server certificates and keys, and client root cert, to the data dir copy_files("ssl/server-*.crt", $pgdata); copy_files("ssl/server-*.key", $pgdata); chmod(0600, glob "$pgdata/server-*.key") or die $!; @@ -124,6 +154,8 @@ sub configure_test_server_for_ssl # Change pg_hba after restart because hostssl requires ssl=on configure_hba_for_ssl($node, $serverhost, $authmethod); + + return; } # Change the configuration to use given server cert file, and reload @@ -144,27 +176,39 @@ sub switch_server_cert close $sslconf; $node->restart; + return; } sub configure_hba_for_ssl { my ($node, $serverhost, $authmethod) = @_; - my $pgdata = $node->data_dir; + my $pgdata = $node->data_dir; - # Only accept SSL connections from localhost. Our tests don't depend on this - # but seems best to keep it as narrow as possible for security reasons. - # - # When connecting to certdb, also check the client certificate. + # Only accept SSL connections from localhost. Our tests don't depend on this + # but seems best to keep it as narrow as possible for security reasons. + # + # When connecting to certdb, also check the client certificate. open my $hba, '>', "$pgdata/pg_hba.conf"; print $hba -"# TYPE DATABASE USER ADDRESS METHOD\n"; + "# TYPE DATABASE USER ADDRESS METHOD OPTIONS\n"; + print $hba + "hostssl trustdb md5testuser $serverhost/32 md5\n"; + print $hba + "hostssl trustdb all $serverhost/32 $authmethod\n"; print $hba -"hostssl trustdb all $serverhost/32 $authmethod\n"; + "hostssl trustdb all ::1/128 $authmethod\n"; print $hba -"hostssl trustdb all ::1/128 $authmethod\n"; + "hostssl verifydb ssltestuser $serverhost/32 $authmethod clientcert=verify-full\n"; print $hba -"hostssl certdb all $serverhost/32 cert\n"; + "hostssl verifydb anotheruser $serverhost/32 $authmethod clientcert=verify-full\n"; print $hba -"hostssl certdb all ::1/128 cert\n"; + "hostssl verifydb yetanotheruser $serverhost/32 $authmethod clientcert=verify-ca\n"; + print $hba + "hostssl certdb all $serverhost/32 cert\n"; + print $hba + "hostssl certdb all ::1/128 cert\n"; close $hba; + return; } + +1; diff --git a/src/test/subscription/Makefile b/src/test/subscription/Makefile index 0f3d2098ade..4378819530f 100644 --- a/src/test/subscription/Makefile +++ b/src/test/subscription/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/test/subscription # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/test/subscription/Makefile @@ -15,6 +15,8 @@ include $(top_builddir)/src/Makefile.global EXTRA_INSTALL = contrib/hstore +export with_icu + check: $(prove_check) diff --git a/src/test/subscription/README b/src/test/subscription/README index 1d50dcceedb..fb5382e1205 100644 --- a/src/test/subscription/README +++ b/src/test/subscription/README @@ -8,14 +8,16 @@ This directory contains a test suite for subscription/logical replication. Running the tests ================= - make check +NOTE: You must have given the --enable-tap-tests argument to configure. +Run + make check or - make installcheck +You can use "make installcheck" if you previously did "make install" +(including installing the hstore extension). In that case, the code +in the installation tree is tested. With "make check", a temporary +installation tree is built from the current sources and then tested. -NOTE: This creates a temporary installation (in the case of "check"), -and some tests may create one or multiple nodes, for the purpose of -the tests. - -NOTE: This requires the --enable-tap-tests argument to configure. +Either way, this test initializes, starts, and stops several test Postgres +clusters. diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl index 4050e82bc9f..40e306a810f 100644 --- a/src/test/subscription/t/001_rep_changes.pl +++ b/src/test/subscription/t/001_rep_changes.pl @@ -32,7 +32,8 @@ $node_publisher->safe_psql('postgres', "INSERT INTO tab_mixed (a, b) VALUES (1, 'foo')"); $node_publisher->safe_psql('postgres', - "CREATE TABLE tab_include (a int, b text, CONSTRAINT covering PRIMARY KEY(a) INCLUDE(b))"); + "CREATE TABLE tab_include (a int, b text, CONSTRAINT covering PRIMARY KEY(a) INCLUDE(b))" +); # Setup structure on subscriber $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)"); @@ -48,7 +49,8 @@ # replication of the table with included index $node_subscriber->safe_psql('postgres', - "CREATE TABLE tab_include (a int, b text, CONSTRAINT covering PRIMARY KEY(a) INCLUDE(b))"); + "CREATE TABLE tab_include (a int, b text, CONSTRAINT covering PRIMARY KEY(a) INCLUDE(b))" +); # Setup logical replication my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; @@ -56,21 +58,20 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)"); $node_publisher->safe_psql('postgres', -"ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include" + "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include" ); $node_publisher->safe_psql('postgres', "ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins"); -my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub, tap_pub_ins_only" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub, tap_pub_ins_only" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Also wait for initial table sync to finish my $synced_query = -"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; @@ -97,10 +98,11 @@ $node_publisher->safe_psql('postgres', "INSERT INTO tab_include SELECT generate_series(1,50)"); -$node_publisher->safe_psql('postgres', "DELETE FROM tab_include WHERE a > 20"); +$node_publisher->safe_psql('postgres', + "DELETE FROM tab_include WHERE a > 20"); $node_publisher->safe_psql('postgres', "UPDATE tab_include SET a = -a"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab_ins"); @@ -117,7 +119,8 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab_include"); -is($result, qq(20|-20|-1), 'check replicated changes with primary key index with included columns'); +is($result, qq(20|-20|-1), + 'check replicated changes with primary key index with included columns'); # insert some duplicate rows $node_publisher->safe_psql('postgres', @@ -142,7 +145,7 @@ $node_publisher->safe_psql('postgres', "UPDATE tab_full2 SET x = 'bb' WHERE x = 'b'"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab_full"); @@ -161,30 +164,35 @@ # as we need to poll for a change but the test suite will fail none the less # when something goes wrong. my $oldpid = $node_publisher->safe_psql('postgres', - "SELECT pid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid FROM pg_stat_replication WHERE application_name = 'tap_sub';" ); $node_subscriber->safe_psql('postgres', -"ALTER SUBSCRIPTION tap_sub CONNECTION 'application_name=$appname $publisher_connstr'" + "ALTER SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr sslmode=disable'" ); $node_publisher->poll_query_until('postgres', -"SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = 'tap_sub';" ) or die "Timed out while waiting for apply to restart"; $oldpid = $node_publisher->safe_psql('postgres', - "SELECT pid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid FROM pg_stat_replication WHERE application_name = 'tap_sub';" ); $node_subscriber->safe_psql('postgres', -"ALTER SUBSCRIPTION tap_sub SET PUBLICATION tap_pub_ins_only WITH (copy_data = false)" + "ALTER SUBSCRIPTION tap_sub SET PUBLICATION tap_pub_ins_only WITH (copy_data = false)" ); $node_publisher->poll_query_until('postgres', -"SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = 'tap_sub';" ) or die "Timed out while waiting for apply to restart"; $node_publisher->safe_psql('postgres', "INSERT INTO tab_ins SELECT generate_series(1001,1100)"); $node_publisher->safe_psql('postgres', "DELETE FROM tab_rep"); -$node_publisher->wait_for_catchup($appname); +# Restart the publisher and check the state of the subscriber which +# should be in a streaming state after catching up. +$node_publisher->stop('fast'); +$node_publisher->start; + +$node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab_ins"); @@ -207,7 +215,7 @@ ); $node_publisher->safe_psql('postgres', "INSERT INTO tab_full VALUES(0)"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # note that data are different on provider and subscriber $result = $node_subscriber->safe_psql('postgres', @@ -221,12 +229,12 @@ # check restart on rename $oldpid = $node_publisher->safe_psql('postgres', - "SELECT pid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid FROM pg_stat_replication WHERE application_name = 'tap_sub';" ); $node_subscriber->safe_psql('postgres', "ALTER SUBSCRIPTION tap_sub RENAME TO tap_sub_renamed"); $node_publisher->poll_query_until('postgres', -"SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = '$appname';" + "SELECT pid != $oldpid FROM pg_stat_replication WHERE application_name = 'tap_sub_renamed';" ) or die "Timed out while waiting for apply to restart"; # check all the cleanup diff --git a/src/test/subscription/t/002_types.pl b/src/test/subscription/t/002_types.pl index 80620416fa1..aedcab2fbcc 100644 --- a/src/test/subscription/t/002_types.pl +++ b/src/test/subscription/t/002_types.pl @@ -4,7 +4,7 @@ use warnings; use PostgresNode; use TestLib; -use Test::More tests => 3; +use Test::More tests => 4; # Initialize publisher node my $node_publisher = get_new_node('publisher'); @@ -90,7 +90,13 @@ CREATE TABLE public.tst_hstore ( a INTEGER PRIMARY KEY, b public.hstore - );); + ); + + SET check_function_bodies=off; + CREATE FUNCTION public.monot_incr(int) RETURNS bool LANGUAGE sql + AS ' select \$1 > max(a) from public.tst_dom_constr; '; + CREATE DOMAIN monot_int AS int CHECK (monot_incr(VALUE)); + CREATE TABLE public.tst_dom_constr (a monot_int);); # Setup structure on both nodes $node_publisher->safe_psql('postgres', $ddl); @@ -101,16 +107,15 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR ALL TABLES"); -my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (slot_name = tap_sub_slot)" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub WITH (slot_name = tap_sub_slot)" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Wait for initial sync to finish as well my $synced_query = -"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; @@ -240,9 +245,12 @@ (2, '"zzz"=>"foo"'), (3, '"123"=>"321"'), (4, '"yellow horse"=>"moaned"'); + + -- tst_dom_constr + INSERT INTO tst_dom_constr VALUES (10); )); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Check the data on subscriber my $result = $node_subscriber->safe_psql( @@ -363,7 +371,7 @@ UPDATE tst_hstore SET b = '"also"=>"updated"' WHERE a = 3; )); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Check the data on subscriber $result = $node_subscriber->safe_psql( @@ -483,7 +491,7 @@ DELETE FROM tst_hstore WHERE a = 1; )); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Check the data on subscriber $result = $node_subscriber->safe_psql( @@ -541,5 +549,17 @@ 4|"yellow horse"=>"moaned"', 'check replicated deletes on subscriber'); +# Test a domain with a constraint backed by a SQL-language function, +# which needs an active snapshot in order to operate. +$node_publisher->safe_psql('postgres', + "INSERT INTO tst_dom_constr VALUES (11)"); + +$node_publisher->wait_for_catchup('tap_sub'); + +$result = + $node_subscriber->safe_psql('postgres', + "SELECT sum(a) FROM tst_dom_constr"); +is($result, '21', 'sql-function constraint on domain'); + $node_subscriber->stop('fast'); $node_publisher->stop('fast'); diff --git a/src/test/subscription/t/003_constraints.pl b/src/test/subscription/t/003_constraints.pl index fe47447b987..81547f65fa8 100644 --- a/src/test/subscription/t/003_constraints.pl +++ b/src/test/subscription/t/003_constraints.pl @@ -19,14 +19,14 @@ $node_publisher->safe_psql('postgres', "CREATE TABLE tab_fk (bid int PRIMARY KEY);"); $node_publisher->safe_psql('postgres', -"CREATE TABLE tab_fk_ref (id int PRIMARY KEY, bid int REFERENCES tab_fk (bid));" + "CREATE TABLE tab_fk_ref (id int PRIMARY KEY, bid int REFERENCES tab_fk (bid));" ); # Setup structure on subscriber $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_fk (bid int PRIMARY KEY);"); $node_subscriber->safe_psql('postgres', -"CREATE TABLE tab_fk_ref (id int PRIMARY KEY, bid int REFERENCES tab_fk (bid));" + "CREATE TABLE tab_fk_ref (id int PRIMARY KEY, bid int REFERENCES tab_fk (bid));" ); # Setup logical replication @@ -34,19 +34,18 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR ALL TABLES;"); -my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (copy_data = false)" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub WITH (copy_data = false)" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $node_publisher->safe_psql('postgres', "INSERT INTO tab_fk (bid) VALUES (1);"); $node_publisher->safe_psql('postgres', "INSERT INTO tab_fk_ref (id, bid) VALUES (1, 1);"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Check data on subscriber my $result = $node_subscriber->safe_psql('postgres', @@ -64,7 +63,7 @@ $node_publisher->safe_psql('postgres', "INSERT INTO tab_fk_ref (id, bid) VALUES (2, 2);"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # FK is not enforced on subscriber $result = $node_subscriber->safe_psql('postgres', @@ -98,7 +97,7 @@ BEGIN $node_publisher->safe_psql('postgres', "INSERT INTO tab_fk_ref (id, bid) VALUES (10, 10);"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # The row should be skipped on subscriber $result = $node_subscriber->safe_psql('postgres', diff --git a/src/test/subscription/t/004_sync.pl b/src/test/subscription/t/004_sync.pl index a9a223bdf7e..e111ab91810 100644 --- a/src/test/subscription/t/004_sync.pl +++ b/src/test/subscription/t/004_sync.pl @@ -32,16 +32,15 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR ALL TABLES"); -my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Also wait for initial table sync to finish my $synced_query = -"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; @@ -57,7 +56,7 @@ # recreate the subscription, it will try to do initial copy $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub" ); # but it will be stuck on data copy as it will fail on constraint @@ -79,12 +78,12 @@ # now check another subscription for the same node pair $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub2 CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub WITH (copy_data = false)" + "CREATE SUBSCRIPTION tap_sub2 CONNECTION '$publisher_connstr' PUBLICATION tap_pub WITH (copy_data = false)" ); # wait for it to start $node_subscriber->poll_query_until('postgres', -"SELECT pid IS NOT NULL FROM pg_stat_subscription WHERE subname = 'tap_sub2' AND relid IS NULL" + "SELECT pid IS NOT NULL FROM pg_stat_subscription WHERE subname = 'tap_sub2' AND relid IS NULL" ) or die "Timed out while waiting for subscriber to start"; # and drop both subscriptions @@ -101,7 +100,7 @@ # recreate the subscription again $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub" ); # and wait for data sync to finish again @@ -116,11 +115,11 @@ # add new table on subscriber $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_rep_next (a int)"); -# setup structure with existing data on pubisher +# setup structure with existing data on publisher $node_publisher->safe_psql('postgres', "CREATE TABLE tab_rep_next (a) AS SELECT generate_series(1,10)"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab_rep_next"); @@ -143,7 +142,7 @@ $node_publisher->safe_psql('postgres', "INSERT INTO tab_rep_next SELECT generate_series(1,10)"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*) FROM tab_rep_next"); diff --git a/src/test/subscription/t/005_encoding.pl b/src/test/subscription/t/005_encoding.pl index 65439f1b28a..aec7a17a78e 100644 --- a/src/test/subscription/t/005_encoding.pl +++ b/src/test/subscription/t/005_encoding.pl @@ -22,26 +22,25 @@ $node_subscriber->safe_psql('postgres', $ddl); my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -my $appname = 'encoding_test'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION mypub FOR ALL TABLES;"); $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION mypub;" + "CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr' PUBLICATION mypub;" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); # Wait for initial sync to finish as well my $synced_query = - "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; $node_publisher->safe_psql('postgres', q{INSERT INTO test1 VALUES (1, E'Mot\xc3\xb6rhead')}); # hand-rolled UTF-8 -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); is( $node_subscriber->safe_psql( 'postgres', q{SELECT a FROM test1 WHERE b = E'Mot\xf6rhead'} diff --git a/src/test/subscription/t/006_rewrite.pl b/src/test/subscription/t/006_rewrite.pl index aa1184c85f5..c6cda10a19b 100644 --- a/src/test/subscription/t/006_rewrite.pl +++ b/src/test/subscription/t/006_rewrite.pl @@ -18,47 +18,48 @@ $node_subscriber->safe_psql('postgres', $ddl); my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -my $appname = 'encoding_test'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION mypub FOR ALL TABLES;"); $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION mypub;" + "CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr' PUBLICATION mypub;" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); # Wait for initial sync to finish as well my $synced_query = - "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('s', 'r');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; -$node_publisher->safe_psql('postgres', q{INSERT INTO test1 (a, b) VALUES (1, 'one'), (2, 'two');}); +$node_publisher->safe_psql('postgres', + q{INSERT INTO test1 (a, b) VALUES (1, 'one'), (2, 'two');}); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); -is($node_subscriber->safe_psql('postgres', q{SELECT a, b FROM test1}), - qq(1|one +is( $node_subscriber->safe_psql('postgres', q{SELECT a, b FROM test1}), + qq(1|one 2|two), - 'initial data replicated to subscriber'); + 'initial data replicated to subscriber'); # DDL that causes a heap rewrite my $ddl2 = "ALTER TABLE test1 ADD c int NOT NULL DEFAULT 0;"; $node_subscriber->safe_psql('postgres', $ddl2); $node_publisher->safe_psql('postgres', $ddl2); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); -$node_publisher->safe_psql('postgres', q{INSERT INTO test1 (a, b, c) VALUES (3, 'three', 33);}); +$node_publisher->safe_psql('postgres', + q{INSERT INTO test1 (a, b, c) VALUES (3, 'three', 33);}); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); -is($node_subscriber->safe_psql('postgres', q{SELECT a, b, c FROM test1}), - qq(1|one|0 +is( $node_subscriber->safe_psql('postgres', q{SELECT a, b, c FROM test1}), + qq(1|one|0 2|two|0 3|three|33), - 'data replicated to subscriber'); + 'data replicated to subscriber'); $node_subscriber->stop; $node_publisher->stop; diff --git a/src/test/subscription/t/007_ddl.pl b/src/test/subscription/t/007_ddl.pl index b219bf33dde..7fe6cc6d639 100644 --- a/src/test/subscription/t/007_ddl.pl +++ b/src/test/subscription/t/007_ddl.pl @@ -18,17 +18,17 @@ $node_subscriber->safe_psql('postgres', $ddl); my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -my $appname = 'replication_test'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION mypub FOR ALL TABLES;"); $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION mypub;" + "CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr' PUBLICATION mypub;" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); -$node_subscriber->safe_psql('postgres', q{ +$node_subscriber->safe_psql( + 'postgres', q{ BEGIN; ALTER SUBSCRIPTION mysub DISABLE; ALTER SUBSCRIPTION mysub SET (slot_name = NONE); diff --git a/src/test/subscription/t/008_diff_schema.pl b/src/test/subscription/t/008_diff_schema.pl index d4849c89a3f..3ad00eae3b6 100644 --- a/src/test/subscription/t/008_diff_schema.pl +++ b/src/test/subscription/t/008_diff_schema.pl @@ -22,60 +22,71 @@ "INSERT INTO test_tab VALUES (1, 'foo'), (2, 'bar')"); # Setup structure on subscriber -$node_subscriber->safe_psql('postgres', "CREATE TABLE test_tab (a int primary key, b text, c timestamptz DEFAULT now(), d bigint DEFAULT 999, e int GENERATED BY DEFAULT AS IDENTITY)"); +$node_subscriber->safe_psql('postgres', + "CREATE TABLE test_tab (a int primary key, b text, c timestamptz DEFAULT now(), d bigint DEFAULT 999, e int GENERATED BY DEFAULT AS IDENTITY)" +); # Setup logical replication my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -$node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub FOR TABLE test_tab"); +$node_publisher->safe_psql('postgres', + "CREATE PUBLICATION tap_pub FOR TABLE test_tab"); -my $appname = 'tap_sub'; $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION tap_pub" + "CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub" ); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); # Also wait for initial table sync to finish my $synced_query = -"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; my $result = - $node_subscriber->safe_psql('postgres', "SELECT count(*), count(c), count(d = 999) FROM test_tab"); + $node_subscriber->safe_psql('postgres', + "SELECT count(*), count(c), count(d = 999) FROM test_tab"); is($result, qq(2|2|2), 'check initial data was copied to subscriber'); # Update the rows on the publisher and check the additional columns on # subscriber didn't change $node_publisher->safe_psql('postgres', "UPDATE test_tab SET b = md5(b)"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = - $node_subscriber->safe_psql('postgres', "SELECT count(*), count(c), count(d = 999), count(e) FROM test_tab"); -is($result, qq(2|2|2|2), 'check extra columns contain local defaults after copy'); + $node_subscriber->safe_psql('postgres', + "SELECT count(*), count(c), count(d = 999), count(e) FROM test_tab"); +is($result, qq(2|2|2|2), + 'check extra columns contain local defaults after copy'); # Change the local values of the extra columns on the subscriber, # update publisher, and check that subscriber retains the expected # values -$node_subscriber->safe_psql('postgres', "UPDATE test_tab SET c = 'epoch'::timestamptz + 987654321 * interval '1s'"); -$node_publisher->safe_psql('postgres', "UPDATE test_tab SET b = md5(a::text)"); +$node_subscriber->safe_psql('postgres', + "UPDATE test_tab SET c = 'epoch'::timestamptz + 987654321 * interval '1s'" +); +$node_publisher->safe_psql('postgres', + "UPDATE test_tab SET b = md5(a::text)"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); -$result = - $node_subscriber->safe_psql('postgres', "SELECT count(*), count(extract(epoch from c) = 987654321), count(d = 999) FROM test_tab"); +$result = $node_subscriber->safe_psql('postgres', + "SELECT count(*), count(extract(epoch from c) = 987654321), count(d = 999) FROM test_tab" +); is($result, qq(2|2|2), 'check extra columns contain locally changed data'); # Another insert $node_publisher->safe_psql('postgres', "INSERT INTO test_tab VALUES (3, 'baz')"); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('tap_sub'); $result = - $node_subscriber->safe_psql('postgres', "SELECT count(*), count(c), count(d = 999), count(e) FROM test_tab"); -is($result, qq(3|3|3|3), 'check extra columns contain local defaults after apply'); + $node_subscriber->safe_psql('postgres', + "SELECT count(*), count(c), count(d = 999), count(e) FROM test_tab"); +is($result, qq(3|3|3|3), + 'check extra columns contain local defaults after apply'); $node_subscriber->stop; $node_publisher->stop; diff --git a/src/test/subscription/t/009_matviews.pl b/src/test/subscription/t/009_matviews.pl index c55c62c95dc..7afc7bdba9f 100644 --- a/src/test/subscription/t/009_matviews.pl +++ b/src/test/subscription/t/009_matviews.pl @@ -14,28 +14,32 @@ $node_subscriber->start; my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; -my $appname = 'replication_test'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION mypub FOR ALL TABLES;"); $node_subscriber->safe_psql('postgres', -"CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr application_name=$appname' PUBLICATION mypub;" + "CREATE SUBSCRIPTION mysub CONNECTION '$publisher_connstr' PUBLICATION mypub;" ); -$node_publisher->safe_psql('postgres', q{CREATE TABLE test1 (a int PRIMARY KEY, b text)}); -$node_publisher->safe_psql('postgres', q{INSERT INTO test1 (a, b) VALUES (1, 'one'), (2, 'two');}); +$node_publisher->safe_psql('postgres', + q{CREATE TABLE test1 (a int PRIMARY KEY, b text)}); +$node_publisher->safe_psql('postgres', + q{INSERT INTO test1 (a, b) VALUES (1, 'one'), (2, 'two');}); -$node_subscriber->safe_psql('postgres', q{CREATE TABLE test1 (a int PRIMARY KEY, b text);}); +$node_subscriber->safe_psql('postgres', + q{CREATE TABLE test1 (a int PRIMARY KEY, b text);}); -$node_publisher->wait_for_catchup($appname); +$node_publisher->wait_for_catchup('mysub'); # Materialized views are not supported by logical replication, but # logical decoding does produce change information for them, so we # need to make sure they are properly ignored. (bug #15044) # create a MV with some data -$node_publisher->safe_psql('postgres', q{CREATE MATERIALIZED VIEW testmv1 AS SELECT * FROM test1;}); -$node_publisher->wait_for_catchup($appname); +$node_publisher->safe_psql('postgres', + q{CREATE MATERIALIZED VIEW testmv1 AS SELECT * FROM test1;}); +$node_publisher->wait_for_catchup('mysub'); + # There is no equivalent relation on the subscriber, but MV data is # not replicated, so this does not hang. diff --git a/src/test/subscription/t/010_truncate.pl b/src/test/subscription/t/010_truncate.pl index fe9e0b9ec71..be2c0bdc35e 100644 --- a/src/test/subscription/t/010_truncate.pl +++ b/src/test/subscription/t/010_truncate.pl @@ -42,11 +42,8 @@ "CREATE TABLE tab4 (x int PRIMARY KEY, y int REFERENCES tab3)"); $node_subscriber->safe_psql('postgres', - "CREATE SEQUENCE seq1 OWNED BY tab1.a" -); -$node_subscriber->safe_psql('postgres', - "ALTER SEQUENCE seq1 START 101" -); + "CREATE SEQUENCE seq1 OWNED BY tab1.a"); +$node_subscriber->safe_psql('postgres', "ALTER SEQUENCE seq1 START 101"); $node_publisher->safe_psql('postgres', "CREATE PUBLICATION pub1 FOR TABLE tab1"); @@ -55,21 +52,25 @@ $node_publisher->safe_psql('postgres', "CREATE PUBLICATION pub3 FOR TABLE tab3, tab4"); $node_subscriber->safe_psql('postgres', - "CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr application_name=sub1' PUBLICATION pub1"); + "CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1" +); $node_subscriber->safe_psql('postgres', - "CREATE SUBSCRIPTION sub2 CONNECTION '$publisher_connstr application_name=sub2' PUBLICATION pub2"); + "CREATE SUBSCRIPTION sub2 CONNECTION '$publisher_connstr' PUBLICATION pub2" +); $node_subscriber->safe_psql('postgres', - "CREATE SUBSCRIPTION sub3 CONNECTION '$publisher_connstr application_name=sub3' PUBLICATION pub3"); + "CREATE SUBSCRIPTION sub3 CONNECTION '$publisher_connstr' PUBLICATION pub3" +); # Wait for initial sync of all subscriptions my $synced_query = -"SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; $node_subscriber->poll_query_until('postgres', $synced_query) or die "Timed out while waiting for subscriber to synchronize data"; # insert data to truncate -$node_subscriber->safe_psql('postgres', "INSERT INTO tab1 VALUES (1), (2), (3)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab1 VALUES (1), (2), (3)"); $node_publisher->wait_for_catchup('sub1'); @@ -81,13 +82,10 @@ my $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab1"); -is($result, qq(0||), - 'truncate replicated'); +is($result, qq(0||), 'truncate replicated'); -$result = $node_subscriber->safe_psql('postgres', - "SELECT nextval('seq1')"); -is($result, qq(1), - 'sequence not restarted'); +$result = $node_subscriber->safe_psql('postgres', "SELECT nextval('seq1')"); +is($result, qq(1), 'sequence not restarted'); # truncate with restart identity @@ -95,14 +93,13 @@ $node_publisher->wait_for_catchup('sub1'); -$result = $node_subscriber->safe_psql('postgres', - "SELECT nextval('seq1')"); -is($result, qq(101), - 'truncate restarted identities'); +$result = $node_subscriber->safe_psql('postgres', "SELECT nextval('seq1')"); +is($result, qq(101), 'truncate restarted identities'); # test publication that does not replicate truncate -$node_subscriber->safe_psql('postgres', "INSERT INTO tab2 VALUES (1), (2), (3)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab2 VALUES (1), (2), (3)"); $node_publisher->safe_psql('postgres', "TRUNCATE tab2"); @@ -110,8 +107,7 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab2"); -is($result, qq(3|1|3), - 'truncate not replicated'); +is($result, qq(3|1|3), 'truncate not replicated'); $node_publisher->safe_psql('postgres', "ALTER PUBLICATION pub2 SET (publish = 'insert, truncate')"); @@ -122,13 +118,14 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab2"); -is($result, qq(0||), - 'truncate replicated after publication change'); +is($result, qq(0||), 'truncate replicated after publication change'); # test multiple tables connected by foreign keys -$node_subscriber->safe_psql('postgres', "INSERT INTO tab3 VALUES (1), (2), (3)"); -$node_subscriber->safe_psql('postgres', "INSERT INTO tab4 VALUES (11, 1), (111, 1), (22, 2)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab3 VALUES (1), (2), (3)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab4 VALUES (11, 1), (111, 1), (22, 2)"); $node_publisher->safe_psql('postgres', "TRUNCATE tab3, tab4"); @@ -136,20 +133,20 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab3"); -is($result, qq(0||), - 'truncate of multiple tables replicated'); +is($result, qq(0||), 'truncate of multiple tables replicated'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(x), max(x) FROM tab4"); -is($result, qq(0||), - 'truncate of multiple tables replicated'); +is($result, qq(0||), 'truncate of multiple tables replicated'); # test truncate of multiple tables, some of which are not published $node_subscriber->safe_psql('postgres', "DROP SUBSCRIPTION sub2"); $node_publisher->safe_psql('postgres', "DROP PUBLICATION pub2"); -$node_subscriber->safe_psql('postgres', "INSERT INTO tab1 VALUES (1), (2), (3)"); -$node_subscriber->safe_psql('postgres', "INSERT INTO tab2 VALUES (1), (2), (3)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab1 VALUES (1), (2), (3)"); +$node_subscriber->safe_psql('postgres', + "INSERT INTO tab2 VALUES (1), (2), (3)"); $node_publisher->safe_psql('postgres', "TRUNCATE tab1, tab2"); @@ -157,9 +154,7 @@ $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab1"); -is($result, qq(0||), - 'truncate of multiple tables some not published'); +is($result, qq(0||), 'truncate of multiple tables some not published'); $result = $node_subscriber->safe_psql('postgres', "SELECT count(*), min(a), max(a) FROM tab2"); -is($result, qq(3|1|3), - 'truncate of multiple tables some not published'); +is($result, qq(3|1|3), 'truncate of multiple tables some not published'); diff --git a/src/test/subscription/t/011_generated.pl b/src/test/subscription/t/011_generated.pl new file mode 100644 index 00000000000..f35d1cba4c9 --- /dev/null +++ b/src/test/subscription/t/011_generated.pl @@ -0,0 +1,63 @@ +# Test generated columns +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 2; + +# setup + +my $node_publisher = get_new_node('publisher'); +$node_publisher->init(allows_streaming => 'logical'); +$node_publisher->start; + +my $node_subscriber = get_new_node('subscriber'); +$node_subscriber->init(allows_streaming => 'logical'); +$node_subscriber->start; + +my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; + +$node_publisher->safe_psql('postgres', + "CREATE TABLE tab1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED)" +); + +$node_subscriber->safe_psql('postgres', + "CREATE TABLE tab1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 22) STORED)" +); + +# data for initial sync + +$node_publisher->safe_psql('postgres', + "INSERT INTO tab1 (a) VALUES (1), (2), (3)"); + +$node_publisher->safe_psql('postgres', + "CREATE PUBLICATION pub1 FOR ALL TABLES"); +$node_subscriber->safe_psql('postgres', + "CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1" +); + +# Wait for initial sync of all subscriptions +my $synced_query = + "SELECT count(1) = 0 FROM pg_subscription_rel WHERE srsubstate NOT IN ('r', 's');"; +$node_subscriber->poll_query_until('postgres', $synced_query) + or die "Timed out while waiting for subscriber to synchronize data"; + +my $result = $node_subscriber->safe_psql('postgres', "SELECT a, b FROM tab1"); +is( $result, qq(1|22 +2|44 +3|66), 'generated columns initial sync'); + +# data to replicate + +$node_publisher->safe_psql('postgres', "INSERT INTO tab1 VALUES (4), (5)"); + +$node_publisher->safe_psql('postgres', "UPDATE tab1 SET a = 6 WHERE a = 5"); + +$node_publisher->wait_for_catchup('sub1'); + +$result = $node_subscriber->safe_psql('postgres', "SELECT a, b FROM tab1"); +is( $result, qq(1|22 +2|44 +3|66 +4|88 +6|132), 'generated columns replicated'); diff --git a/src/test/subscription/t/012_collation.pl b/src/test/subscription/t/012_collation.pl new file mode 100644 index 00000000000..4bfcef7c2f5 --- /dev/null +++ b/src/test/subscription/t/012_collation.pl @@ -0,0 +1,107 @@ +# Test collations, in particular nondeterministic ones +# (only works with ICU) +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More; + +if ($ENV{with_icu} eq 'yes') +{ + plan tests => 2; +} +else +{ + plan skip_all => 'ICU not supported by this build'; +} + +my $node_publisher = get_new_node('publisher'); +$node_publisher->init( + allows_streaming => 'logical', + extra => [ '--locale=C', '--encoding=UTF8' ]); +$node_publisher->start; + +my $node_subscriber = get_new_node('subscriber'); +$node_subscriber->init( + allows_streaming => 'logical', + extra => [ '--locale=C', '--encoding=UTF8' ]); +$node_subscriber->start; + +my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; + +# Test plan: Create a table with a nondeterministic collation in the +# primary key column. Pre-insert rows on the publisher and subscriber +# that are collation-wise equal but byte-wise different. (We use a +# string in different normal forms for that.) Set up publisher and +# subscriber. Update the row on the publisher, but don't change the +# primary key column. The subscriber needs to find the row to be +# updated using the nondeterministic collation semantics. We need to +# test for both a replica identity index and for replica identity +# full, since those have different code paths internally. + +$node_subscriber->safe_psql('postgres', + q{CREATE COLLATION ctest_nondet (provider = icu, locale = 'und', deterministic = false)} +); + +# table with replica identity index + +$node_publisher->safe_psql('postgres', + q{CREATE TABLE tab1 (a text PRIMARY KEY, b text)}); + +$node_publisher->safe_psql('postgres', + q{INSERT INTO tab1 VALUES (U&'\00E4bc', 'foo')}); + +$node_subscriber->safe_psql('postgres', + q{CREATE TABLE tab1 (a text COLLATE ctest_nondet PRIMARY KEY, b text)}); + +$node_subscriber->safe_psql('postgres', + q{INSERT INTO tab1 VALUES (U&'\0061\0308bc', 'foo')}); + +# table with replica identity full + +$node_publisher->safe_psql('postgres', q{CREATE TABLE tab2 (a text, b text)}); +$node_publisher->safe_psql('postgres', + q{ALTER TABLE tab2 REPLICA IDENTITY FULL}); + +$node_publisher->safe_psql('postgres', + q{INSERT INTO tab2 VALUES (U&'\00E4bc', 'foo')}); + +$node_subscriber->safe_psql('postgres', + q{CREATE TABLE tab2 (a text COLLATE ctest_nondet, b text)}); +$node_subscriber->safe_psql('postgres', + q{ALTER TABLE tab2 REPLICA IDENTITY FULL}); + +$node_subscriber->safe_psql('postgres', + q{INSERT INTO tab2 VALUES (U&'\0061\0308bc', 'foo')}); + +# set up publication, subscription + +$node_publisher->safe_psql('postgres', + q{CREATE PUBLICATION pub1 FOR ALL TABLES}); + +$node_subscriber->safe_psql('postgres', + qq{CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1 WITH (copy_data = false)} +); + +$node_publisher->wait_for_catchup('sub1'); + +# test with replica identity index + +$node_publisher->safe_psql('postgres', + q{UPDATE tab1 SET b = 'bar' WHERE b = 'foo'}); + +$node_publisher->wait_for_catchup('sub1'); + +is($node_subscriber->safe_psql('postgres', q{SELECT b FROM tab1}), + qq(bar), 'update with primary key with nondeterministic collation'); + +# test with replica identity full + +$node_publisher->safe_psql('postgres', + q{UPDATE tab2 SET b = 'bar' WHERE b = 'foo'}); + +$node_publisher->wait_for_catchup('sub1'); + +is($node_subscriber->safe_psql('postgres', q{SELECT b FROM tab2}), + qq(bar), + 'update with replica identity full with nondeterministic collation'); diff --git a/src/test/subscription/t/100_bugs.pl b/src/test/subscription/t/100_bugs.pl new file mode 100644 index 00000000000..366a7a94350 --- /dev/null +++ b/src/test/subscription/t/100_bugs.pl @@ -0,0 +1,102 @@ +# Tests for various bugs found over time +use strict; +use warnings; +use PostgresNode; +use TestLib; +use Test::More tests => 3; + +# Bug #15114 + +# The bug was that determining which columns are part of the replica +# identity index using RelationGetIndexAttrBitmap() would run +# eval_const_expressions() on index expressions and predicates across +# all indexes of the table, which in turn might require a snapshot, +# but there wasn't one set, so it crashes. There were actually two +# separate bugs, one on the publisher and one on the subscriber. The +# fix was to avoid the constant expressions simplification in +# RelationGetIndexAttrBitmap(), so it's safe to call in more contexts. + +my $node_publisher = get_new_node('publisher'); +$node_publisher->init(allows_streaming => 'logical'); +$node_publisher->start; + +my $node_subscriber = get_new_node('subscriber'); +$node_subscriber->init(allows_streaming => 'logical'); +$node_subscriber->start; + +my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; + +$node_publisher->safe_psql('postgres', + "CREATE TABLE tab1 (a int PRIMARY KEY, b int)"); + +$node_publisher->safe_psql('postgres', + "CREATE FUNCTION double(x int) RETURNS int IMMUTABLE LANGUAGE SQL AS 'select x * 2'" +); + +# an index with a predicate that lends itself to constant expressions +# evaluation +$node_publisher->safe_psql('postgres', + "CREATE INDEX ON tab1 (b) WHERE a > double(1)"); + +# and the same setup on the subscriber +$node_subscriber->safe_psql('postgres', + "CREATE TABLE tab1 (a int PRIMARY KEY, b int)"); + +$node_subscriber->safe_psql('postgres', + "CREATE FUNCTION double(x int) RETURNS int IMMUTABLE LANGUAGE SQL AS 'select x * 2'" +); + +$node_subscriber->safe_psql('postgres', + "CREATE INDEX ON tab1 (b) WHERE a > double(1)"); + +$node_publisher->safe_psql('postgres', + "CREATE PUBLICATION pub1 FOR ALL TABLES"); + +$node_subscriber->safe_psql('postgres', + "CREATE SUBSCRIPTION sub1 CONNECTION '$publisher_connstr' PUBLICATION pub1" +); + +$node_publisher->wait_for_catchup('sub1'); + +# This would crash, first on the publisher, and then (if the publisher +# is fixed) on the subscriber. +$node_publisher->safe_psql('postgres', "INSERT INTO tab1 VALUES (1, 2)"); + +$node_publisher->wait_for_catchup('sub1'); + +pass('index predicates do not cause crash'); + +$node_publisher->stop('fast'); +$node_subscriber->stop('fast'); + + +# Handling of temporary and unlogged tables with FOR ALL TABLES publications + +# If a FOR ALL TABLES publication exists, temporary and unlogged +# tables are ignored for publishing changes. The bug was that we +# would still check in that case that such a table has a replica +# identity set before accepting updates. If it did not it would cause +# an error when an update was attempted. + +$node_publisher = get_new_node('publisher2'); +$node_publisher->init(allows_streaming => 'logical'); +$node_publisher->start; + +$node_publisher->safe_psql('postgres', + "CREATE PUBLICATION pub FOR ALL TABLES"); + +is( $node_publisher->psql( + 'postgres', + "CREATE TEMPORARY TABLE tt1 AS SELECT 1 AS a; UPDATE tt1 SET a = 2;"), + 0, + 'update to temporary table without replica identity with FOR ALL TABLES publication' +); + +is( $node_publisher->psql( + 'postgres', + "CREATE UNLOGGED TABLE tu1 AS SELECT 1 AS a; UPDATE tu1 SET a = 2;"), + 0, + 'update to unlogged table without replica identity with FOR ALL TABLES publication' +); + +$node_publisher->stop('fast'); diff --git a/src/test/thread/Makefile b/src/test/thread/Makefile index bf2b07be560..dab1a4803fe 100644 --- a/src/test/thread/Makefile +++ b/src/test/thread/Makefile @@ -2,7 +2,7 @@ # # Makefile for tools/thread # -# Copyright (c) 2003-2018, PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # # src/test/thread/Makefile # @@ -18,7 +18,7 @@ all: thread_test thread_test: thread_test.o # no need for $LIBS, might not be compiled yet - $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $^ $(PTHREAD_LIBS) -o $@ + $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(PTHREAD_LIBS) -o $@$(X) clean distclean maintainer-clean: rm -f thread_test$(X) thread_test.o diff --git a/src/test/thread/thread_test.c b/src/test/thread/thread_test.c index 381607324d3..4fbba78ef6f 100644 --- a/src/test/thread/thread_test.c +++ b/src/test/thread/thread_test.c @@ -1,9 +1,9 @@ /*------------------------------------------------------------------------- * - * test_thread_funcs.c + * thread_test.c * libc thread test program * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/test/thread/thread_test.c @@ -22,6 +22,9 @@ #if !defined(IN_CONFIGURE) && !defined(WIN32) #include "postgres.h" + +/* we want to know what the native strerror does, not pg_strerror */ +#undef strerror #endif #include @@ -197,7 +200,7 @@ main(int argc, char *argv[]) /* report results */ #ifdef HAVE_STRERROR_R - printf("Your system has sterror_r(); it does not need strerror().\n"); + printf("Your system has strerror_r(); it does not need strerror().\n"); #else printf("Your system uses strerror() which is "); if (strerror_threadsafe) diff --git a/src/timezone/Makefile b/src/timezone/Makefile index 87493da8b3e..78aeab43922 100644 --- a/src/timezone/Makefile +++ b/src/timezone/Makefile @@ -28,6 +28,9 @@ TZDATAFILES = $(srcdir)/data/tzdata.zi # for POSIX-style timezone specs POSIXRULES = US/Eastern +# any custom options you might want to pass to zic while installing data files +ZIC_OPTIONS = + # use system timezone data? ifneq (,$(with_system_tzdata)) override CPPFLAGS += '-DSYSTEMTZDIR="$(with_system_tzdata)"' @@ -52,7 +55,7 @@ zic: $(ZICOBJS) | submake-libpgport install: all installdirs ifeq (,$(with_system_tzdata)) - $(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' $(TZDATAFILES) + $(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' -b slim $(ZIC_OPTIONS) $(TZDATAFILES) endif $(MAKE) -C tznames $@ diff --git a/src/timezone/README b/src/timezone/README index 7b5573183d4..d3dd7b7fa6d 100644 --- a/src/timezone/README +++ b/src/timezone/README @@ -55,7 +55,7 @@ match properly on the old version. Time Zone code ============== -The code in this directory is currently synced with tzcode release 2017c. +The code in this directory is currently synced with tzcode release 2019b. There are many cosmetic (and not so cosmetic) differences from the original tzcode library, but diffs in the upstream version should usually be propagated to our version. Here are some notes about that. @@ -73,19 +73,26 @@ fixed that.) includes relying on configure's results rather than hand-hacked #defines, and not relying on features that may not exist on old systems. (In particular this means using Postgres' definitions of the int32 and -int64 typedefs, not int_fast32_t/int_fast64_t.) +int64 typedefs, not int_fast32_t/int_fast64_t. Likewise we use +PG_INT32_MIN/MAX not INT32_MIN/MAX.) * Since Postgres is typically built on a system that has its own copy of the functions, we must avoid conflicting with those. This mandates renaming typedef time_t to pg_time_t, and similarly for most other exposed names. +* zic.c's typedef "lineno" is renamed to "lineno_t", because having +"lineno" in our typedefs list would cause unfortunate pgindent behavior +in some other files where we have variables named that. + * We have exposed the tzload() and tzparse() internal functions, and slightly modified the API of the former, in part because it now relies on our own pg_open_tzfile() rather than opening files for itself. -* tzparse() is adjusted to cache the result of loading the TZDEFRULES -zone, so that that's not repeated more than once per process. +* tzparse() is adjusted to avoid loading the TZDEFRULES zone unless +really necessary, and to ignore any leap-second data it may supply. +We also cache the result of loading the TZDEFRULES zone, so that +that's not repeated more than once per process. * There's a fair amount of code we don't need and have removed, including all the nonstandard optional APIs. We have also added @@ -104,13 +111,23 @@ to first run the tzcode source files through a sed filter like this: -e 's/^([ \t]*)\*\*$/\1 */' \ -e 's|^\*/| */|' \ -e 's/\bregister[ \t]//g' \ + -e 's/\bATTRIBUTE_PURE[ \t]//g' \ -e 's/int_fast32_t/int32/g' \ -e 's/int_fast64_t/int64/g' \ + -e 's/intmax_t/int64/g' \ + -e 's/INT32_MIN/PG_INT32_MIN/g' \ + -e 's/INT32_MAX/PG_INT32_MAX/g' \ + -e 's/INTMAX_MIN/PG_INT64_MIN/g' \ + -e 's/INTMAX_MAX/PG_INT64_MAX/g' \ -e 's/struct[ \t]+tm\b/struct pg_tm/g' \ -e 's/\btime_t\b/pg_time_t/g' \ + -e 's/lineno/lineno_t/g' \ and then run them through pgindent. (The first three sed patterns deal with conversion of their block comment style to something pgindent won't make a hash of; the remainder address other points noted above.) After that, the files can be diff'd directly against our corresponding -files. +files. Also, it's typically helpful to diff against the previous tzcode +release (after processing that the same way), and then try to apply the +diff to our files. This will take care of most of the changes +mechanically. diff --git a/src/timezone/data/tzdata.zi b/src/timezone/data/tzdata.zi index afa8f85c436..cf13611fdd6 100644 --- a/src/timezone/data/tzdata.zi +++ b/src/timezone/data/tzdata.zi @@ -1,38 +1,38 @@ -# version 2018c +# version 2019c # This zic input file is in the public domain. -R A 1916 o - Jun 14 23s 1 S -R A 1916 1919 - O Sun>=1 23s 0 - -R A 1917 o - Mar 24 23s 1 S -R A 1918 o - Mar 9 23s 1 S -R A 1919 o - Mar 1 23s 1 S -R A 1920 o - F 14 23s 1 S -R A 1920 o - O 23 23s 0 - -R A 1921 o - Mar 14 23s 1 S -R A 1921 o - Jun 21 23s 0 - -R A 1939 o - S 11 23s 1 S -R A 1939 o - N 19 1 0 - -R A 1944 1945 - Ap M>=1 2 1 S -R A 1944 o - O 8 2 0 - -R A 1945 o - S 16 1 0 - -R A 1971 o - Ap 25 23s 1 S -R A 1971 o - S 26 23s 0 - -R A 1977 o - May 6 0 1 S -R A 1977 o - O 21 0 0 - -R A 1978 o - Mar 24 1 1 S -R A 1978 o - S 22 3 0 - -R A 1980 o - Ap 25 0 1 S -R A 1980 o - O 31 2 0 - +R d 1916 o - Jun 14 23s 1 S +R d 1916 1919 - O Su>=1 23s 0 - +R d 1917 o - Mar 24 23s 1 S +R d 1918 o - Mar 9 23s 1 S +R d 1919 o - Mar 1 23s 1 S +R d 1920 o - F 14 23s 1 S +R d 1920 o - O 23 23s 0 - +R d 1921 o - Mar 14 23s 1 S +R d 1921 o - Jun 21 23s 0 - +R d 1939 o - S 11 23s 1 S +R d 1939 o - N 19 1 0 - +R d 1944 1945 - Ap M>=1 2 1 S +R d 1944 o - O 8 2 0 - +R d 1945 o - S 16 1 0 - +R d 1971 o - Ap 25 23s 1 S +R d 1971 o - S 26 23s 0 - +R d 1977 o - May 6 0 1 S +R d 1977 o - O 21 0 0 - +R d 1978 o - Mar 24 1 1 S +R d 1978 o - S 22 3 0 - +R d 1980 o - Ap 25 0 1 S +R d 1980 o - O 31 2 0 - Z Africa/Algiers 0:12:12 - LMT 1891 Mar 15 0:1 0:9:21 - PMT 1911 Mar 11 -0 A WE%sT 1940 F 25 2 -1 A CE%sT 1946 O 7 +0 d WE%sT 1940 F 25 2 +1 d CE%sT 1946 O 7 0 - WET 1956 Ja 29 1 - CET 1963 Ap 14 -0 A WE%sT 1977 O 21 -1 A CE%sT 1979 O 26 -0 A WE%sT 1981 May +0 d WE%sT 1977 O 21 +1 d CE%sT 1979 O 26 +0 d WE%sT 1981 May 1 - CET -Z Atlantic/Cape_Verde -1:34:4 - LMT 1907 +Z Atlantic/Cape_Verde -1:34:4 - LMT 1912 Ja 1 2u -2 - -02 1942 S -2 1 -01 1945 O 15 -2 - -02 1975 N 25 2 @@ -43,54 +43,54 @@ Z Africa/Ndjamena 1:0:12 - LMT 1912 1 - WAT Z Africa/Abidjan -0:16:8 - LMT 1912 0 - GMT -Li Africa/Abidjan Africa/Bamako -Li Africa/Abidjan Africa/Banjul -Li Africa/Abidjan Africa/Conakry -Li Africa/Abidjan Africa/Dakar -Li Africa/Abidjan Africa/Freetown -Li Africa/Abidjan Africa/Lome -Li Africa/Abidjan Africa/Nouakchott -Li Africa/Abidjan Africa/Ouagadougou -Li Africa/Abidjan Atlantic/St_Helena -R B 1940 o - Jul 15 0 1 S -R B 1940 o - O 1 0 0 - -R B 1941 o - Ap 15 0 1 S -R B 1941 o - S 16 0 0 - -R B 1942 1944 - Ap 1 0 1 S -R B 1942 o - O 27 0 0 - -R B 1943 1945 - N 1 0 0 - -R B 1945 o - Ap 16 0 1 S -R B 1957 o - May 10 0 1 S -R B 1957 1958 - O 1 0 0 - -R B 1958 o - May 1 0 1 S -R B 1959 1981 - May 1 1 1 S -R B 1959 1965 - S 30 3 0 - -R B 1966 1994 - O 1 3 0 - -R B 1982 o - Jul 25 1 1 S -R B 1983 o - Jul 12 1 1 S -R B 1984 1988 - May 1 1 1 S -R B 1989 o - May 6 1 1 S -R B 1990 1994 - May 1 1 1 S -R B 1995 2010 - Ap lastF 0s 1 S -R B 1995 2005 - S lastTh 24 0 - -R B 2006 o - S 21 24 0 - -R B 2007 o - S Th>=1 24 0 - -R B 2008 o - Au lastTh 24 0 - -R B 2009 o - Au 20 24 0 - -R B 2010 o - Au 10 24 0 - -R B 2010 o - S 9 24 1 S -R B 2010 o - S lastTh 24 0 - -R B 2014 o - May 15 24 1 S -R B 2014 o - Jun 26 24 0 - -R B 2014 o - Jul 31 24 1 S -R B 2014 o - S lastTh 24 0 - +L Africa/Abidjan Africa/Bamako +L Africa/Abidjan Africa/Banjul +L Africa/Abidjan Africa/Conakry +L Africa/Abidjan Africa/Dakar +L Africa/Abidjan Africa/Freetown +L Africa/Abidjan Africa/Lome +L Africa/Abidjan Africa/Nouakchott +L Africa/Abidjan Africa/Ouagadougou +L Africa/Abidjan Atlantic/St_Helena +R K 1940 o - Jul 15 0 1 S +R K 1940 o - O 1 0 0 - +R K 1941 o - Ap 15 0 1 S +R K 1941 o - S 16 0 0 - +R K 1942 1944 - Ap 1 0 1 S +R K 1942 o - O 27 0 0 - +R K 1943 1945 - N 1 0 0 - +R K 1945 o - Ap 16 0 1 S +R K 1957 o - May 10 0 1 S +R K 1957 1958 - O 1 0 0 - +R K 1958 o - May 1 0 1 S +R K 1959 1981 - May 1 1 1 S +R K 1959 1965 - S 30 3 0 - +R K 1966 1994 - O 1 3 0 - +R K 1982 o - Jul 25 1 1 S +R K 1983 o - Jul 12 1 1 S +R K 1984 1988 - May 1 1 1 S +R K 1989 o - May 6 1 1 S +R K 1990 1994 - May 1 1 1 S +R K 1995 2010 - Ap lastF 0s 1 S +R K 1995 2005 - S lastTh 24 0 - +R K 2006 o - S 21 24 0 - +R K 2007 o - S Th>=1 24 0 - +R K 2008 o - Au lastTh 24 0 - +R K 2009 o - Au 20 24 0 - +R K 2010 o - Au 10 24 0 - +R K 2010 o - S 9 24 1 S +R K 2010 o - S lastTh 24 0 - +R K 2014 o - May 15 24 1 S +R K 2014 o - Jun 26 24 0 - +R K 2014 o - Jul 31 24 1 S +R K 2014 o - S lastTh 24 0 - Z Africa/Cairo 2:5:9 - LMT 1900 O -2 B EE%sT -R C 1920 1942 - S 1 0 0:20 GHST -R C 1920 1942 - D 31 0 0 GMT +2 K EE%sT +R GH 1920 1942 - S 1 0 0:20 - +R GH 1920 1942 - D 31 0 0 - Z Africa/Accra -0:0:52 - LMT 1918 -0 C GMT/+0020 -Z Africa/Bissau -1:2:20 - LMT 1912 +0 GH GMT/+0020 +Z Africa/Bissau -1:2:20 - LMT 1912 Ja 1 1u -1 - -01 1975 0 - GMT Z Africa/Nairobi 2:27:16 - LMT 1928 Jul @@ -98,204 +98,335 @@ Z Africa/Nairobi 2:27:16 - LMT 1928 Jul 2:30 - +0230 1940 2:45 - +0245 1960 3 - EAT -Li Africa/Nairobi Africa/Addis_Ababa -Li Africa/Nairobi Africa/Asmara -Li Africa/Nairobi Africa/Dar_es_Salaam -Li Africa/Nairobi Africa/Djibouti -Li Africa/Nairobi Africa/Kampala -Li Africa/Nairobi Africa/Mogadishu -Li Africa/Nairobi Indian/Antananarivo -Li Africa/Nairobi Indian/Comoro -Li Africa/Nairobi Indian/Mayotte +L Africa/Nairobi Africa/Addis_Ababa +L Africa/Nairobi Africa/Asmara +L Africa/Nairobi Africa/Dar_es_Salaam +L Africa/Nairobi Africa/Djibouti +L Africa/Nairobi Africa/Kampala +L Africa/Nairobi Africa/Mogadishu +L Africa/Nairobi Indian/Antananarivo +L Africa/Nairobi Indian/Comoro +L Africa/Nairobi Indian/Mayotte Z Africa/Monrovia -0:43:8 - LMT 1882 -0:43:8 - MMT 1919 Mar -0:44:30 - MMT 1972 Ja 7 0 - GMT -R D 1951 o - O 14 2 1 S -R D 1952 o - Ja 1 0 0 - -R D 1953 o - O 9 2 1 S -R D 1954 o - Ja 1 0 0 - -R D 1955 o - S 30 0 1 S -R D 1956 o - Ja 1 0 0 - -R D 1982 1984 - Ap 1 0 1 S -R D 1982 1985 - O 1 0 0 - -R D 1985 o - Ap 6 0 1 S -R D 1986 o - Ap 4 0 1 S -R D 1986 o - O 3 0 0 - -R D 1987 1989 - Ap 1 0 1 S -R D 1987 1989 - O 1 0 0 - -R D 1997 o - Ap 4 0 1 S -R D 1997 o - O 4 0 0 - -R D 2013 o - Mar lastF 1 1 S -R D 2013 o - O lastF 2 0 - +R L 1951 o - O 14 2 1 S +R L 1952 o - Ja 1 0 0 - +R L 1953 o - O 9 2 1 S +R L 1954 o - Ja 1 0 0 - +R L 1955 o - S 30 0 1 S +R L 1956 o - Ja 1 0 0 - +R L 1982 1984 - Ap 1 0 1 S +R L 1982 1985 - O 1 0 0 - +R L 1985 o - Ap 6 0 1 S +R L 1986 o - Ap 4 0 1 S +R L 1986 o - O 3 0 0 - +R L 1987 1989 - Ap 1 0 1 S +R L 1987 1989 - O 1 0 0 - +R L 1997 o - Ap 4 0 1 S +R L 1997 o - O 4 0 0 - +R L 2013 o - Mar lastF 1 1 S +R L 2013 o - O lastF 2 0 - Z Africa/Tripoli 0:52:44 - LMT 1920 -1 D CE%sT 1959 +1 L CE%sT 1959 2 - EET 1982 -1 D CE%sT 1990 May 4 +1 L CE%sT 1990 May 4 2 - EET 1996 S 30 -1 D CE%sT 1997 O 4 +1 L CE%sT 1997 O 4 2 - EET 2012 N 10 2 -1 D CE%sT 2013 O 25 2 +1 L CE%sT 2013 O 25 2 2 - EET -R E 1982 o - O 10 0 1 S -R E 1983 o - Mar 21 0 0 - -R E 2008 o - O lastSun 2 1 S -R E 2009 o - Mar lastSun 2 0 - +R MU 1982 o - O 10 0 1 - +R MU 1983 o - Mar 21 0 0 - +R MU 2008 o - O lastSu 2 1 - +R MU 2009 o - Mar lastSu 2 0 - Z Indian/Mauritius 3:50 - LMT 1907 -4 E +04/+05 -R F 1939 o - S 12 0 1 S -R F 1939 o - N 19 0 0 - -R F 1940 o - F 25 0 1 S -R F 1945 o - N 18 0 0 - -R F 1950 o - Jun 11 0 1 S -R F 1950 o - O 29 0 0 - -R F 1967 o - Jun 3 12 1 S -R F 1967 o - O 1 0 0 - -R F 1974 o - Jun 24 0 1 S -R F 1974 o - S 1 0 0 - -R F 1976 1977 - May 1 0 1 S -R F 1976 o - Au 1 0 0 - -R F 1977 o - S 28 0 0 - -R F 1978 o - Jun 1 0 1 S -R F 1978 o - Au 4 0 0 - -R F 2008 o - Jun 1 0 1 S -R F 2008 o - S 1 0 0 - -R F 2009 o - Jun 1 0 1 S -R F 2009 o - Au 21 0 0 - -R F 2010 o - May 2 0 1 S -R F 2010 o - Au 8 0 0 - -R F 2011 o - Ap 3 0 1 S -R F 2011 o - Jul 31 0 0 - -R F 2012 2013 - Ap lastSun 2 1 S -R F 2012 o - Jul 20 3 0 - -R F 2012 o - Au 20 2 1 S -R F 2012 o - S 30 3 0 - -R F 2013 o - Jul 7 3 0 - -R F 2013 o - Au 10 2 1 S -R F 2013 ma - O lastSun 3 0 - -R F 2014 2021 - Mar lastSun 2 1 S -R F 2014 o - Jun 28 3 0 - -R F 2014 o - Au 2 2 1 S -R F 2015 o - Jun 14 3 0 - -R F 2015 o - Jul 19 2 1 S -R F 2016 o - Jun 5 3 0 - -R F 2016 o - Jul 10 2 1 S -R F 2017 o - May 21 3 0 - -R F 2017 o - Jul 2 2 1 S -R F 2018 o - May 13 3 0 - -R F 2018 o - Jun 17 2 1 S -R F 2019 o - May 5 3 0 - -R F 2019 o - Jun 9 2 1 S -R F 2020 o - Ap 19 3 0 - -R F 2020 o - May 24 2 1 S -R F 2021 o - Ap 11 3 0 - -R F 2021 o - May 16 2 1 S -R F 2022 o - May 8 2 1 S -R F 2023 o - Ap 23 2 1 S -R F 2024 o - Ap 14 2 1 S -R F 2025 o - Ap 6 2 1 S -R F 2026 ma - Mar lastSun 2 1 S -R F 2036 o - O 19 3 0 - -R F 2037 o - O 4 3 0 - +4 MU +04/+05 +R M 1939 o - S 12 0 1 - +R M 1939 o - N 19 0 0 - +R M 1940 o - F 25 0 1 - +R M 1945 o - N 18 0 0 - +R M 1950 o - Jun 11 0 1 - +R M 1950 o - O 29 0 0 - +R M 1967 o - Jun 3 12 1 - +R M 1967 o - O 1 0 0 - +R M 1974 o - Jun 24 0 1 - +R M 1974 o - S 1 0 0 - +R M 1976 1977 - May 1 0 1 - +R M 1976 o - Au 1 0 0 - +R M 1977 o - S 28 0 0 - +R M 1978 o - Jun 1 0 1 - +R M 1978 o - Au 4 0 0 - +R M 2008 o - Jun 1 0 1 - +R M 2008 o - S 1 0 0 - +R M 2009 o - Jun 1 0 1 - +R M 2009 o - Au 21 0 0 - +R M 2010 o - May 2 0 1 - +R M 2010 o - Au 8 0 0 - +R M 2011 o - Ap 3 0 1 - +R M 2011 o - Jul 31 0 0 - +R M 2012 2013 - Ap lastSu 2 1 - +R M 2012 o - Jul 20 3 0 - +R M 2012 o - Au 20 2 1 - +R M 2012 o - S 30 3 0 - +R M 2013 o - Jul 7 3 0 - +R M 2013 o - Au 10 2 1 - +R M 2013 2018 - O lastSu 3 0 - +R M 2014 2018 - Mar lastSu 2 1 - +R M 2014 o - Jun 28 3 0 - +R M 2014 o - Au 2 2 1 - +R M 2015 o - Jun 14 3 0 - +R M 2015 o - Jul 19 2 1 - +R M 2016 o - Jun 5 3 0 - +R M 2016 o - Jul 10 2 1 - +R M 2017 o - May 21 3 0 - +R M 2017 o - Jul 2 2 1 - +R M 2018 o - May 13 3 0 - +R M 2018 o - Jun 17 2 1 - +R M 2019 o - May 5 3 -1 - +R M 2019 o - Jun 9 2 0 - +R M 2020 o - Ap 19 3 -1 - +R M 2020 o - May 24 2 0 - +R M 2021 o - Ap 11 3 -1 - +R M 2021 o - May 16 2 0 - +R M 2022 o - Mar 27 3 -1 - +R M 2022 o - May 8 2 0 - +R M 2023 o - Mar 19 3 -1 - +R M 2023 o - Ap 23 2 0 - +R M 2024 o - Mar 10 3 -1 - +R M 2024 o - Ap 14 2 0 - +R M 2025 o - F 23 3 -1 - +R M 2025 o - Ap 6 2 0 - +R M 2026 o - F 15 3 -1 - +R M 2026 o - Mar 22 2 0 - +R M 2027 o - F 7 3 -1 - +R M 2027 o - Mar 14 2 0 - +R M 2028 o - Ja 23 3 -1 - +R M 2028 o - F 27 2 0 - +R M 2029 o - Ja 14 3 -1 - +R M 2029 o - F 18 2 0 - +R M 2029 o - D 30 3 -1 - +R M 2030 o - F 10 2 0 - +R M 2030 o - D 22 3 -1 - +R M 2031 o - Ja 26 2 0 - +R M 2031 o - D 14 3 -1 - +R M 2032 o - Ja 18 2 0 - +R M 2032 o - N 28 3 -1 - +R M 2033 o - Ja 9 2 0 - +R M 2033 o - N 20 3 -1 - +R M 2033 o - D 25 2 0 - +R M 2034 o - N 5 3 -1 - +R M 2034 o - D 17 2 0 - +R M 2035 o - O 28 3 -1 - +R M 2035 o - D 2 2 0 - +R M 2036 o - O 19 3 -1 - +R M 2036 o - N 23 2 0 - +R M 2037 o - O 4 3 -1 - +R M 2037 o - N 15 2 0 - +R M 2038 o - S 26 3 -1 - +R M 2038 o - O 31 2 0 - +R M 2039 o - S 18 3 -1 - +R M 2039 o - O 23 2 0 - +R M 2040 o - S 2 3 -1 - +R M 2040 o - O 14 2 0 - +R M 2041 o - Au 25 3 -1 - +R M 2041 o - S 29 2 0 - +R M 2042 o - Au 10 3 -1 - +R M 2042 o - S 21 2 0 - +R M 2043 o - Au 2 3 -1 - +R M 2043 o - S 6 2 0 - +R M 2044 o - Jul 24 3 -1 - +R M 2044 o - Au 28 2 0 - +R M 2045 o - Jul 9 3 -1 - +R M 2045 o - Au 20 2 0 - +R M 2046 o - Jul 1 3 -1 - +R M 2046 o - Au 5 2 0 - +R M 2047 o - Jun 23 3 -1 - +R M 2047 o - Jul 28 2 0 - +R M 2048 o - Jun 7 3 -1 - +R M 2048 o - Jul 19 2 0 - +R M 2049 o - May 30 3 -1 - +R M 2049 o - Jul 4 2 0 - +R M 2050 o - May 15 3 -1 - +R M 2050 o - Jun 26 2 0 - +R M 2051 o - May 7 3 -1 - +R M 2051 o - Jun 11 2 0 - +R M 2052 o - Ap 28 3 -1 - +R M 2052 o - Jun 2 2 0 - +R M 2053 o - Ap 13 3 -1 - +R M 2053 o - May 25 2 0 - +R M 2054 o - Ap 5 3 -1 - +R M 2054 o - May 10 2 0 - +R M 2055 o - Mar 28 3 -1 - +R M 2055 o - May 2 2 0 - +R M 2056 o - Mar 12 3 -1 - +R M 2056 o - Ap 23 2 0 - +R M 2057 o - Mar 4 3 -1 - +R M 2057 o - Ap 8 2 0 - +R M 2058 o - F 17 3 -1 - +R M 2058 o - Mar 31 2 0 - +R M 2059 o - F 9 3 -1 - +R M 2059 o - Mar 16 2 0 - +R M 2060 o - F 1 3 -1 - +R M 2060 o - Mar 7 2 0 - +R M 2061 o - Ja 16 3 -1 - +R M 2061 o - F 27 2 0 - +R M 2062 o - Ja 8 3 -1 - +R M 2062 o - F 12 2 0 - +R M 2062 o - D 31 3 -1 - +R M 2063 o - F 4 2 0 - +R M 2063 o - D 16 3 -1 - +R M 2064 o - Ja 20 2 0 - +R M 2064 o - D 7 3 -1 - +R M 2065 o - Ja 11 2 0 - +R M 2065 o - N 22 3 -1 - +R M 2066 o - Ja 3 2 0 - +R M 2066 o - N 14 3 -1 - +R M 2066 o - D 19 2 0 - +R M 2067 o - N 6 3 -1 - +R M 2067 o - D 11 2 0 - +R M 2068 o - O 21 3 -1 - +R M 2068 o - D 2 2 0 - +R M 2069 o - O 13 3 -1 - +R M 2069 o - N 17 2 0 - +R M 2070 o - O 5 3 -1 - +R M 2070 o - N 9 2 0 - +R M 2071 o - S 20 3 -1 - +R M 2071 o - O 25 2 0 - +R M 2072 o - S 11 3 -1 - +R M 2072 o - O 16 2 0 - +R M 2073 o - Au 27 3 -1 - +R M 2073 o - O 8 2 0 - +R M 2074 o - Au 19 3 -1 - +R M 2074 o - S 23 2 0 - +R M 2075 o - Au 11 3 -1 - +R M 2075 o - S 15 2 0 - +R M 2076 o - Jul 26 3 -1 - +R M 2076 o - S 6 2 0 - +R M 2077 o - Jul 18 3 -1 - +R M 2077 o - Au 22 2 0 - +R M 2078 o - Jul 10 3 -1 - +R M 2078 o - Au 14 2 0 - +R M 2079 o - Jun 25 3 -1 - +R M 2079 o - Jul 30 2 0 - +R M 2080 o - Jun 16 3 -1 - +R M 2080 o - Jul 21 2 0 - +R M 2081 o - Jun 1 3 -1 - +R M 2081 o - Jul 13 2 0 - +R M 2082 o - May 24 3 -1 - +R M 2082 o - Jun 28 2 0 - +R M 2083 o - May 16 3 -1 - +R M 2083 o - Jun 20 2 0 - +R M 2084 o - Ap 30 3 -1 - +R M 2084 o - Jun 11 2 0 - +R M 2085 o - Ap 22 3 -1 - +R M 2085 o - May 27 2 0 - +R M 2086 o - Ap 14 3 -1 - +R M 2086 o - May 19 2 0 - +R M 2087 o - Mar 30 3 -1 - +R M 2087 o - May 4 2 0 - Z Africa/Casablanca -0:30:20 - LMT 1913 O 26 -0 F WE%sT 1984 Mar 16 -1 - CET 1986 -0 F WE%sT +0 M +00/+01 1984 Mar 16 +1 - +01 1986 +0 M +00/+01 2018 O 28 3 +1 M +01/+00 Z Africa/El_Aaiun -0:52:48 - LMT 1934 -1 - -01 1976 Ap 14 -0 F WE%sT +0 M +00/+01 2018 O 28 3 +1 M +01/+00 Z Africa/Maputo 2:10:20 - LMT 1903 Mar 2 - CAT -Li Africa/Maputo Africa/Blantyre -Li Africa/Maputo Africa/Bujumbura -Li Africa/Maputo Africa/Gaborone -Li Africa/Maputo Africa/Harare -Li Africa/Maputo Africa/Kigali -Li Africa/Maputo Africa/Lubumbashi -Li Africa/Maputo Africa/Lusaka -R G 1994 o - Mar 21 0 0 - -R G 1994 2016 - S Sun>=1 2 1 S -R G 1995 2017 - Ap Sun>=1 2 0 - +L Africa/Maputo Africa/Blantyre +L Africa/Maputo Africa/Bujumbura +L Africa/Maputo Africa/Gaborone +L Africa/Maputo Africa/Harare +L Africa/Maputo Africa/Kigali +L Africa/Maputo Africa/Lubumbashi +L Africa/Maputo Africa/Lusaka +R NA 1994 o - Mar 21 0 -1 WAT +R NA 1994 2017 - S Su>=1 2 0 CAT +R NA 1995 2017 - Ap Su>=1 2 -1 WAT Z Africa/Windhoek 1:8:24 - LMT 1892 F 8 1:30 - +0130 1903 Mar 2 - SAST 1942 S 20 2 2 1 SAST 1943 Mar 21 2 2 - SAST 1990 Mar 21 -2 - CAT 1994 Mar 21 -1 G WA%sT 2017 S 3 2 -2 - CAT +2 NA %s Z Africa/Lagos 0:13:36 - LMT 1919 S 1 - WAT -Li Africa/Lagos Africa/Bangui -Li Africa/Lagos Africa/Brazzaville -Li Africa/Lagos Africa/Douala -Li Africa/Lagos Africa/Kinshasa -Li Africa/Lagos Africa/Libreville -Li Africa/Lagos Africa/Luanda -Li Africa/Lagos Africa/Malabo -Li Africa/Lagos Africa/Niamey -Li Africa/Lagos Africa/Porto-Novo +L Africa/Lagos Africa/Bangui +L Africa/Lagos Africa/Brazzaville +L Africa/Lagos Africa/Douala +L Africa/Lagos Africa/Kinshasa +L Africa/Lagos Africa/Libreville +L Africa/Lagos Africa/Luanda +L Africa/Lagos Africa/Malabo +L Africa/Lagos Africa/Niamey +L Africa/Lagos Africa/Porto-Novo Z Indian/Reunion 3:41:52 - LMT 1911 Jun 4 - +04 Z Africa/Sao_Tome 0:26:56 - LMT 1884 --0:36:45 - LMT 1912 +-0:36:45 - LMT 1912 Ja 1 0u 0 - GMT 2018 Ja 1 1 -1 - WAT +1 - WAT 2019 Ja 1 2 +0 - GMT Z Indian/Mahe 3:41:48 - LMT 1906 Jun 4 - +04 -R H 1942 1943 - S Sun>=15 2 1 - -R H 1943 1944 - Mar Sun>=15 2 0 - +R SA 1942 1943 - S Su>=15 2 1 - +R SA 1943 1944 - Mar Su>=15 2 0 - Z Africa/Johannesburg 1:52 - LMT 1892 F 8 1:30 - SAST 1903 Mar -2 H SAST -Li Africa/Johannesburg Africa/Maseru -Li Africa/Johannesburg Africa/Mbabane -R I 1970 o - May 1 0 1 S -R I 1970 1985 - O 15 0 0 - -R I 1971 o - Ap 30 0 1 S -R I 1972 1985 - Ap lastSun 0 1 S +2 SA SAST +L Africa/Johannesburg Africa/Maseru +L Africa/Johannesburg Africa/Mbabane +R SD 1970 o - May 1 0 1 S +R SD 1970 1985 - O 15 0 0 - +R SD 1971 o - Ap 30 0 1 S +R SD 1972 1985 - Ap lastSu 0 1 S Z Africa/Khartoum 2:10:8 - LMT 1931 -2 I CA%sT 2000 Ja 15 12 +2 SD CA%sT 2000 Ja 15 12 3 - EAT 2017 N 2 - CAT Z Africa/Juba 2:6:28 - LMT 1931 -2 I CA%sT 2000 Ja 15 12 +2 SD CA%sT 2000 Ja 15 12 3 - EAT -R J 1939 o - Ap 15 23s 1 S -R J 1939 o - N 18 23s 0 - -R J 1940 o - F 25 23s 1 S -R J 1941 o - O 6 0 0 - -R J 1942 o - Mar 9 0 1 S -R J 1942 o - N 2 3 0 - -R J 1943 o - Mar 29 2 1 S -R J 1943 o - Ap 17 2 0 - -R J 1943 o - Ap 25 2 1 S -R J 1943 o - O 4 2 0 - -R J 1944 1945 - Ap M>=1 2 1 S -R J 1944 o - O 8 0 0 - -R J 1945 o - S 16 0 0 - -R J 1977 o - Ap 30 0s 1 S -R J 1977 o - S 24 0s 0 - -R J 1978 o - May 1 0s 1 S -R J 1978 o - O 1 0s 0 - -R J 1988 o - Jun 1 0s 1 S -R J 1988 1990 - S lastSun 0s 0 - -R J 1989 o - Mar 26 0s 1 S -R J 1990 o - May 1 0s 1 S -R J 2005 o - May 1 0s 1 S -R J 2005 o - S 30 1s 0 - -R J 2006 2008 - Mar lastSun 2s 1 S -R J 2006 2008 - O lastSun 2s 0 - +R n 1939 o - Ap 15 23s 1 S +R n 1939 o - N 18 23s 0 - +R n 1940 o - F 25 23s 1 S +R n 1941 o - O 6 0 0 - +R n 1942 o - Mar 9 0 1 S +R n 1942 o - N 2 3 0 - +R n 1943 o - Mar 29 2 1 S +R n 1943 o - Ap 17 2 0 - +R n 1943 o - Ap 25 2 1 S +R n 1943 o - O 4 2 0 - +R n 1944 1945 - Ap M>=1 2 1 S +R n 1944 o - O 8 0 0 - +R n 1945 o - S 16 0 0 - +R n 1977 o - Ap 30 0s 1 S +R n 1977 o - S 24 0s 0 - +R n 1978 o - May 1 0s 1 S +R n 1978 o - O 1 0s 0 - +R n 1988 o - Jun 1 0s 1 S +R n 1988 1990 - S lastSu 0s 0 - +R n 1989 o - Mar 26 0s 1 S +R n 1990 o - May 1 0s 1 S +R n 2005 o - May 1 0s 1 S +R n 2005 o - S 30 1s 0 - +R n 2006 2008 - Mar lastSu 2s 1 S +R n 2006 2008 - O lastSu 2s 0 - Z Africa/Tunis 0:40:44 - LMT 1881 May 12 0:9:21 - PMT 1911 Mar 11 -1 J CE%sT +1 n CE%sT Z Antarctica/Casey 0 - -00 1969 8 - +08 2009 O 18 2 11 - +11 2010 Mar 5 2 8 - +08 2011 O 28 2 11 - +11 2012 F 21 17u 8 - +08 2016 O 22 -11 - +11 +11 - +11 2018 Mar 11 4 +8 - +08 Z Antarctica/Davis 0 - -00 1957 Ja 13 7 - +07 1964 N 0 - -00 1969 F @@ -315,10 +446,10 @@ Z Antarctica/DumontDUrville 0 - -00 1947 10 - +10 Z Antarctica/Syowa 0 - -00 1957 Ja 29 3 - +03 -R K 2005 ma - Mar lastSun 1u 2 +02 -R K 2004 ma - O lastSun 1u 0 +00 +R Tr 2005 ma - Mar lastSu 1u 2 +02 +R Tr 2004 ma - O lastSu 1u 0 +00 Z Antarctica/Troll 0 - -00 2005 F 12 -0 K %s +0 Tr %s Z Antarctica/Vostok 0 - -00 1957 D 16 6 - +06 Z Antarctica/Rothera 0 - -00 1976 D @@ -326,33 +457,33 @@ Z Antarctica/Rothera 0 - -00 1976 D Z Asia/Kabul 4:36:48 - LMT 1890 4 - +04 1945 4:30 - +0430 -R L 2011 o - Mar lastSun 2s 1 S -R L 2011 o - O lastSun 2s 0 - +R AM 2011 o - Mar lastSu 2s 1 - +R AM 2011 o - O lastSu 2s 0 - Z Asia/Yerevan 2:58 - LMT 1924 May 2 3 - +03 1957 Mar -4 M +04/+05 1991 Mar 31 2s -3 M +03/+04 1995 S 24 2s +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1995 S 24 2s 4 - +04 1997 -4 M +04/+05 2011 -4 L +04/+05 -R N 1997 2015 - Mar lastSun 4 1 S -R N 1997 2015 - O lastSun 5 0 - +4 R +04/+05 2011 +4 AM +04/+05 +R AZ 1997 2015 - Mar lastSu 4 1 - +R AZ 1997 2015 - O lastSu 5 0 - Z Asia/Baku 3:19:24 - LMT 1924 May 2 3 - +03 1957 Mar -4 M +04/+05 1991 Mar 31 2s -3 M +03/+04 1992 S lastSun 2s +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1992 S lastSu 2s 4 - +04 1996 -4 O +04/+05 1997 -4 N +04/+05 -R P 2009 o - Jun 19 23 1 S -R P 2009 o - D 31 24 0 - +4 E +04/+05 1997 +4 AZ +04/+05 +R BD 2009 o - Jun 19 23 1 - +R BD 2009 o - D 31 24 0 - Z Asia/Dhaka 6:1:40 - LMT 1890 5:53:20 - HMT 1941 O 6:30 - +0630 1942 May 15 5:30 - +0530 1942 S 6:30 - +0630 1951 S 30 6 - +06 2009 -6 P +06/+07 +6 BD +06/+07 Z Asia/Thimphu 5:58:36 - LMT 1947 Au 15 5:30 - +0530 1987 O 6 - +06 @@ -367,103 +498,124 @@ Z Asia/Yangon 6:24:47 - LMT 1880 6:30 - +0630 1942 May 9 - +09 1945 May 3 6:30 - +0630 -R Q 1940 o - Jun 3 0 1 D -R Q 1940 1941 - O 1 0 0 S -R Q 1941 o - Mar 16 0 1 D -R R 1986 o - May 4 0 1 D -R R 1986 1991 - S Sun>=11 0 0 S -R R 1987 1991 - Ap Sun>=10 0 1 D +R Sh 1940 o - Jun 1 0 1 D +R Sh 1940 o - O 12 24 0 S +R Sh 1941 o - Mar 15 0 1 D +R Sh 1941 o - N 1 24 0 S +R Sh 1942 o - Ja 31 0 1 D +R Sh 1945 o - S 1 24 0 S +R Sh 1946 o - May 15 0 1 D +R Sh 1946 o - S 30 24 0 S +R Sh 1947 o - Ap 15 0 1 D +R Sh 1947 o - O 31 24 0 S +R Sh 1948 1949 - May 1 0 1 D +R Sh 1948 1949 - S 30 24 0 S +R CN 1986 o - May 4 2 1 D +R CN 1986 1991 - S Su>=11 2 0 S +R CN 1987 1991 - Ap Su>=11 2 1 D Z Asia/Shanghai 8:5:43 - LMT 1901 -8 Q C%sT 1949 -8 R C%sT +8 Sh C%sT 1949 May 28 +8 CN C%sT Z Asia/Urumqi 5:50:20 - LMT 1928 6 - +06 -R S 1941 o - Ap 1 3:30 1 S -R S 1941 o - S 30 3:30 0 - -R S 1946 o - Ap 20 3:30 1 S -R S 1946 o - D 1 3:30 0 - -R S 1947 o - Ap 13 3:30 1 S -R S 1947 o - D 30 3:30 0 - -R S 1948 o - May 2 3:30 1 S -R S 1948 1951 - O lastSun 3:30 0 - -R S 1952 o - O 25 3:30 0 - -R S 1949 1953 - Ap Sun>=1 3:30 1 S -R S 1953 o - N 1 3:30 0 - -R S 1954 1964 - Mar Sun>=18 3:30 1 S -R S 1954 o - O 31 3:30 0 - -R S 1955 1964 - N Sun>=1 3:30 0 - -R S 1965 1976 - Ap Sun>=16 3:30 1 S -R S 1965 1976 - O Sun>=16 3:30 0 - -R S 1973 o - D 30 3:30 1 S -R S 1979 o - May Sun>=8 3:30 1 S -R S 1979 o - O Sun>=16 3:30 0 - -Z Asia/Hong_Kong 7:36:42 - LMT 1904 O 30 -8 S HK%sT 1941 D 25 -9 - JST 1945 S 15 -8 S HK%sT -R T 1946 o - May 15 0 1 D -R T 1946 o - O 1 0 0 S -R T 1947 o - Ap 15 0 1 D -R T 1947 o - N 1 0 0 S -R T 1948 1951 - May 1 0 1 D -R T 1948 1951 - O 1 0 0 S -R T 1952 o - Mar 1 0 1 D -R T 1952 1954 - N 1 0 0 S -R T 1953 1959 - Ap 1 0 1 D -R T 1955 1961 - O 1 0 0 S -R T 1960 1961 - Jun 1 0 1 D -R T 1974 1975 - Ap 1 0 1 D -R T 1974 1975 - O 1 0 0 S -R T 1979 o - Jul 1 0 1 D -R T 1979 o - O 1 0 0 S +R HK 1946 o - Ap 21 0 1 S +R HK 1946 o - D 1 3:30s 0 - +R HK 1947 o - Ap 13 3:30s 1 S +R HK 1947 o - N 30 3:30s 0 - +R HK 1948 o - May 2 3:30s 1 S +R HK 1948 1952 - O Su>=28 3:30s 0 - +R HK 1949 1953 - Ap Su>=1 3:30 1 S +R HK 1953 1964 - O Su>=31 3:30 0 - +R HK 1954 1964 - Mar Su>=18 3:30 1 S +R HK 1965 1976 - Ap Su>=16 3:30 1 S +R HK 1965 1976 - O Su>=16 3:30 0 - +R HK 1973 o - D 30 3:30 1 S +R HK 1979 o - May 13 3:30 1 S +R HK 1979 o - O 21 3:30 0 - +Z Asia/Hong_Kong 7:36:42 - LMT 1904 O 30 0:36:42 +8 - HKT 1941 Jun 15 3 +8 1 HKST 1941 O 1 4 +8 0:30 HKWT 1941 D 25 +9 - JST 1945 N 18 2 +8 HK HK%sT +R f 1946 o - May 15 0 1 D +R f 1946 o - O 1 0 0 S +R f 1947 o - Ap 15 0 1 D +R f 1947 o - N 1 0 0 S +R f 1948 1951 - May 1 0 1 D +R f 1948 1951 - O 1 0 0 S +R f 1952 o - Mar 1 0 1 D +R f 1952 1954 - N 1 0 0 S +R f 1953 1959 - Ap 1 0 1 D +R f 1955 1961 - O 1 0 0 S +R f 1960 1961 - Jun 1 0 1 D +R f 1974 1975 - Ap 1 0 1 D +R f 1974 1975 - O 1 0 0 S +R f 1979 o - Jul 1 0 1 D +R f 1979 o - O 1 0 0 S Z Asia/Taipei 8:6 - LMT 1896 8 - CST 1937 O 9 - JST 1945 S 21 1 -8 T C%sT -R U 1961 1962 - Mar Sun>=16 3:30 1 D -R U 1961 1964 - N Sun>=1 3:30 0 S -R U 1963 o - Mar Sun>=16 0 1 D -R U 1964 o - Mar Sun>=16 3:30 1 D -R U 1965 o - Mar Sun>=16 0 1 D -R U 1965 o - O 31 0 0 S -R U 1966 1971 - Ap Sun>=16 3:30 1 D -R U 1966 1971 - O Sun>=16 3:30 0 S -R U 1972 1974 - Ap Sun>=15 0 1 D -R U 1972 1973 - O Sun>=15 0 0 S -R U 1974 1977 - O Sun>=15 3:30 0 S -R U 1975 1977 - Ap Sun>=15 3:30 1 D -R U 1978 1980 - Ap Sun>=15 0 1 D -R U 1978 1980 - O Sun>=15 0 0 S -Z Asia/Macau 7:34:20 - LMT 1912 -8 U C%sT -R V 1975 o - Ap 13 0 1 S -R V 1975 o - O 12 0 0 - -R V 1976 o - May 15 0 1 S -R V 1976 o - O 11 0 0 - -R V 1977 1980 - Ap Sun>=1 0 1 S -R V 1977 o - S 25 0 0 - -R V 1978 o - O 2 0 0 - -R V 1979 1997 - S lastSun 0 0 - -R V 1981 1998 - Mar lastSun 0 1 S +8 f C%sT +R _ 1942 1943 - Ap 30 23 1 - +R _ 1942 o - N 17 23 0 - +R _ 1943 o - S 30 23 0 S +R _ 1946 o - Ap 30 23s 1 D +R _ 1946 o - S 30 23s 0 S +R _ 1947 o - Ap 19 23s 1 D +R _ 1947 o - N 30 23s 0 S +R _ 1948 o - May 2 23s 1 D +R _ 1948 o - O 31 23s 0 S +R _ 1949 1950 - Ap Sa>=1 23s 1 D +R _ 1949 1950 - O lastSa 23s 0 S +R _ 1951 o - Mar 31 23s 1 D +R _ 1951 o - O 28 23s 0 S +R _ 1952 1953 - Ap Sa>=1 23s 1 D +R _ 1952 o - N 1 23s 0 S +R _ 1953 1954 - O lastSa 23s 0 S +R _ 1954 1956 - Mar Sa>=17 23s 1 D +R _ 1955 o - N 5 23s 0 S +R _ 1956 1964 - N Su>=1 3:30 0 S +R _ 1957 1964 - Mar Su>=18 3:30 1 D +R _ 1965 1973 - Ap Su>=16 3:30 1 D +R _ 1965 1966 - O Su>=16 2:30 0 S +R _ 1967 1976 - O Su>=16 3:30 0 S +R _ 1973 o - D 30 3:30 1 D +R _ 1975 1976 - Ap Su>=16 3:30 1 D +R _ 1979 o - May 13 3:30 1 D +R _ 1979 o - O Su>=16 3:30 0 S +Z Asia/Macau 7:34:10 - LMT 1904 O 30 +8 - CST 1941 D 21 23 +9 _ +09/+10 1945 S 30 24 +8 _ C%sT +R CY 1975 o - Ap 13 0 1 S +R CY 1975 o - O 12 0 0 - +R CY 1976 o - May 15 0 1 S +R CY 1976 o - O 11 0 0 - +R CY 1977 1980 - Ap Su>=1 0 1 S +R CY 1977 o - S 25 0 0 - +R CY 1978 o - O 2 0 0 - +R CY 1979 1997 - S lastSu 0 0 - +R CY 1981 1998 - Mar lastSu 0 1 S Z Asia/Nicosia 2:13:28 - LMT 1921 N 14 -2 V EE%sT 1998 S -2 O EE%sT +2 CY EE%sT 1998 S +2 E EE%sT Z Asia/Famagusta 2:15:48 - LMT 1921 N 14 -2 V EE%sT 1998 S -2 O EE%sT 2016 S 8 +2 CY EE%sT 1998 S +2 E EE%sT 2016 S 8 3 - +03 2017 O 29 1u -2 O EE%sT -Li Asia/Nicosia Europe/Nicosia +2 E EE%sT +L Asia/Nicosia Europe/Nicosia Z Asia/Tbilisi 2:59:11 - LMT 1880 2:59:11 - TBMT 1924 May 2 3 - +03 1957 Mar -4 M +04/+05 1991 Mar 31 2s -3 M +03/+04 1992 -3 W +03/+04 1994 S lastSun -4 W +04/+05 1996 O lastSun -4 1 +05 1997 Mar lastSun -4 W +04/+05 2004 Jun 27 -3 M +03/+04 2005 Mar lastSun 2 +4 R +04/+05 1991 Mar 31 2s +3 R +03/+04 1992 +3 e +03/+04 1994 S lastSu +4 e +04/+05 1996 O lastSu +4 1 +05 1997 Mar lastSu +4 e +04/+05 2004 Jun 27 +3 R +03/+04 2005 Mar lastSu 2 4 - +04 Z Asia/Dili 8:22:20 - LMT 1912 8 - +08 1942 F 21 23 @@ -505,72 +657,124 @@ Z Asia/Jayapura 9:22:48 - LMT 1932 N 9 - +09 1944 S 9:30 - +0930 1964 9 - WIT -R X 1978 1980 - Mar 21 0 1 D -R X 1978 o - O 21 0 0 S -R X 1979 o - S 19 0 0 S -R X 1980 o - S 23 0 0 S -R X 1991 o - May 3 0 1 D -R X 1992 1995 - Mar 22 0 1 D -R X 1991 1995 - S 22 0 0 S -R X 1996 o - Mar 21 0 1 D -R X 1996 o - S 21 0 0 S -R X 1997 1999 - Mar 22 0 1 D -R X 1997 1999 - S 22 0 0 S -R X 2000 o - Mar 21 0 1 D -R X 2000 o - S 21 0 0 S -R X 2001 2003 - Mar 22 0 1 D -R X 2001 2003 - S 22 0 0 S -R X 2004 o - Mar 21 0 1 D -R X 2004 o - S 21 0 0 S -R X 2005 o - Mar 22 0 1 D -R X 2005 o - S 22 0 0 S -R X 2008 o - Mar 21 0 1 D -R X 2008 o - S 21 0 0 S -R X 2009 2011 - Mar 22 0 1 D -R X 2009 2011 - S 22 0 0 S -R X 2012 o - Mar 21 0 1 D -R X 2012 o - S 21 0 0 S -R X 2013 2015 - Mar 22 0 1 D -R X 2013 2015 - S 22 0 0 S -R X 2016 o - Mar 21 0 1 D -R X 2016 o - S 21 0 0 S -R X 2017 2019 - Mar 22 0 1 D -R X 2017 2019 - S 22 0 0 S -R X 2020 o - Mar 21 0 1 D -R X 2020 o - S 21 0 0 S -R X 2021 2023 - Mar 22 0 1 D -R X 2021 2023 - S 22 0 0 S -R X 2024 o - Mar 21 0 1 D -R X 2024 o - S 21 0 0 S -R X 2025 2027 - Mar 22 0 1 D -R X 2025 2027 - S 22 0 0 S -R X 2028 2029 - Mar 21 0 1 D -R X 2028 2029 - S 21 0 0 S -R X 2030 2031 - Mar 22 0 1 D -R X 2030 2031 - S 22 0 0 S -R X 2032 2033 - Mar 21 0 1 D -R X 2032 2033 - S 21 0 0 S -R X 2034 2035 - Mar 22 0 1 D -R X 2034 2035 - S 22 0 0 S -R X 2036 ma - Mar 21 0 1 D -R X 2036 ma - S 21 0 0 S +R i 1978 1980 - Mar 20 24 1 - +R i 1978 o - O 20 24 0 - +R i 1979 o - S 18 24 0 - +R i 1980 o - S 22 24 0 - +R i 1991 o - May 2 24 1 - +R i 1992 1995 - Mar 21 24 1 - +R i 1991 1995 - S 21 24 0 - +R i 1996 o - Mar 20 24 1 - +R i 1996 o - S 20 24 0 - +R i 1997 1999 - Mar 21 24 1 - +R i 1997 1999 - S 21 24 0 - +R i 2000 o - Mar 20 24 1 - +R i 2000 o - S 20 24 0 - +R i 2001 2003 - Mar 21 24 1 - +R i 2001 2003 - S 21 24 0 - +R i 2004 o - Mar 20 24 1 - +R i 2004 o - S 20 24 0 - +R i 2005 o - Mar 21 24 1 - +R i 2005 o - S 21 24 0 - +R i 2008 o - Mar 20 24 1 - +R i 2008 o - S 20 24 0 - +R i 2009 2011 - Mar 21 24 1 - +R i 2009 2011 - S 21 24 0 - +R i 2012 o - Mar 20 24 1 - +R i 2012 o - S 20 24 0 - +R i 2013 2015 - Mar 21 24 1 - +R i 2013 2015 - S 21 24 0 - +R i 2016 o - Mar 20 24 1 - +R i 2016 o - S 20 24 0 - +R i 2017 2019 - Mar 21 24 1 - +R i 2017 2019 - S 21 24 0 - +R i 2020 o - Mar 20 24 1 - +R i 2020 o - S 20 24 0 - +R i 2021 2023 - Mar 21 24 1 - +R i 2021 2023 - S 21 24 0 - +R i 2024 o - Mar 20 24 1 - +R i 2024 o - S 20 24 0 - +R i 2025 2027 - Mar 21 24 1 - +R i 2025 2027 - S 21 24 0 - +R i 2028 2029 - Mar 20 24 1 - +R i 2028 2029 - S 20 24 0 - +R i 2030 2031 - Mar 21 24 1 - +R i 2030 2031 - S 21 24 0 - +R i 2032 2033 - Mar 20 24 1 - +R i 2032 2033 - S 20 24 0 - +R i 2034 2035 - Mar 21 24 1 - +R i 2034 2035 - S 21 24 0 - +R i 2036 2037 - Mar 20 24 1 - +R i 2036 2037 - S 20 24 0 - +R i 2038 2039 - Mar 21 24 1 - +R i 2038 2039 - S 21 24 0 - +R i 2040 2041 - Mar 20 24 1 - +R i 2040 2041 - S 20 24 0 - +R i 2042 2043 - Mar 21 24 1 - +R i 2042 2043 - S 21 24 0 - +R i 2044 2045 - Mar 20 24 1 - +R i 2044 2045 - S 20 24 0 - +R i 2046 2047 - Mar 21 24 1 - +R i 2046 2047 - S 21 24 0 - +R i 2048 2049 - Mar 20 24 1 - +R i 2048 2049 - S 20 24 0 - +R i 2050 2051 - Mar 21 24 1 - +R i 2050 2051 - S 21 24 0 - +R i 2052 2053 - Mar 20 24 1 - +R i 2052 2053 - S 20 24 0 - +R i 2054 2055 - Mar 21 24 1 - +R i 2054 2055 - S 21 24 0 - +R i 2056 2057 - Mar 20 24 1 - +R i 2056 2057 - S 20 24 0 - +R i 2058 2059 - Mar 21 24 1 - +R i 2058 2059 - S 21 24 0 - +R i 2060 2062 - Mar 20 24 1 - +R i 2060 2062 - S 20 24 0 - +R i 2063 o - Mar 21 24 1 - +R i 2063 o - S 21 24 0 - +R i 2064 2066 - Mar 20 24 1 - +R i 2064 2066 - S 20 24 0 - +R i 2067 o - Mar 21 24 1 - +R i 2067 o - S 21 24 0 - +R i 2068 2070 - Mar 20 24 1 - +R i 2068 2070 - S 20 24 0 - +R i 2071 o - Mar 21 24 1 - +R i 2071 o - S 21 24 0 - +R i 2072 2074 - Mar 20 24 1 - +R i 2072 2074 - S 20 24 0 - +R i 2075 o - Mar 21 24 1 - +R i 2075 o - S 21 24 0 - +R i 2076 2078 - Mar 20 24 1 - +R i 2076 2078 - S 20 24 0 - +R i 2079 o - Mar 21 24 1 - +R i 2079 o - S 21 24 0 - +R i 2080 2082 - Mar 20 24 1 - +R i 2080 2082 - S 20 24 0 - +R i 2083 o - Mar 21 24 1 - +R i 2083 o - S 21 24 0 - +R i 2084 2086 - Mar 20 24 1 - +R i 2084 2086 - S 20 24 0 - +R i 2087 o - Mar 21 24 1 - +R i 2087 o - S 21 24 0 - +R i 2088 ma - Mar 20 24 1 - +R i 2088 ma - S 20 24 0 - Z Asia/Tehran 3:25:44 - LMT 1916 3:25:44 - TMT 1946 3:30 - +0330 1977 N -4 X +04/+05 1979 -3:30 X +0330/+0430 -R Y 1982 o - May 1 0 1 D -R Y 1982 1984 - O 1 0 0 S -R Y 1983 o - Mar 31 0 1 D -R Y 1984 1985 - Ap 1 0 1 D -R Y 1985 1990 - S lastSun 1s 0 S -R Y 1986 1990 - Mar lastSun 1s 1 D -R Y 1991 2007 - Ap 1 3s 1 D -R Y 1991 2007 - O 1 3s 0 S +4 i +04/+05 1979 +3:30 i +0330/+0430 +R IQ 1982 o - May 1 0 1 - +R IQ 1982 1984 - O 1 0 0 - +R IQ 1983 o - Mar 31 0 1 - +R IQ 1984 1985 - Ap 1 0 1 - +R IQ 1985 1990 - S lastSu 1s 0 - +R IQ 1986 1990 - Mar lastSu 1s 1 - +R IQ 1991 2007 - Ap 1 3s 1 - +R IQ 1991 2007 - O 1 3s 0 - Z Asia/Baghdad 2:57:40 - LMT 1890 2:57:36 - BMT 1918 3 - +03 1982 May -3 Y +03/+04 +3 IQ +03/+04 R Z 1940 o - Jun 1 0 1 D R Z 1942 1944 - N 1 0 0 S R Z 1943 o - Ap 1 2 1 D @@ -603,6 +807,10 @@ R Z 1974 o - Jul 7 0 1 D R Z 1974 o - O 13 0 0 S R Z 1975 o - Ap 20 0 1 D R Z 1975 o - Au 31 0 0 S +R Z 1980 o - Au 2 0 1 D +R Z 1980 o - S 13 1 0 S +R Z 1984 o - May 5 0 1 D +R Z 1984 o - Au 25 1 0 S R Z 1985 o - Ap 14 0 1 D R Z 1985 o - S 15 0 0 S R Z 1986 o - May 18 0 1 D @@ -643,179 +851,187 @@ R Z 2003 o - Mar 28 1 1 D R Z 2003 o - O 3 1 0 S R Z 2004 o - Ap 7 1 1 D R Z 2004 o - S 22 1 0 S -R Z 2005 o - Ap 1 2 1 D +R Z 2005 2012 - Ap F<=1 2 1 D R Z 2005 o - O 9 2 0 S -R Z 2006 2010 - Mar F>=26 2 1 D R Z 2006 o - O 1 2 0 S R Z 2007 o - S 16 2 0 S R Z 2008 o - O 5 2 0 S R Z 2009 o - S 27 2 0 S R Z 2010 o - S 12 2 0 S -R Z 2011 o - Ap 1 2 1 D R Z 2011 o - O 2 2 0 S -R Z 2012 o - Mar F>=26 2 1 D R Z 2012 o - S 23 2 0 S R Z 2013 ma - Mar F>=23 2 1 D -R Z 2013 ma - O lastSun 2 0 S +R Z 2013 ma - O lastSu 2 0 S Z Asia/Jerusalem 2:20:54 - LMT 1880 2:20:40 - JMT 1918 2 Z I%sT -R a 1948 o - May Sat>=1 24 1 D -R a 1948 1951 - S Sun>=9 0 0 S -R a 1949 o - Ap Sat>=1 24 1 D -R a 1950 1951 - May Sat>=1 24 1 D +R JP 1948 o - May Sa>=1 24 1 D +R JP 1948 1951 - S Sa>=8 25 0 S +R JP 1949 o - Ap Sa>=1 24 1 D +R JP 1950 1951 - May Sa>=1 24 1 D Z Asia/Tokyo 9:18:59 - LMT 1887 D 31 15u -9 a J%sT -R b 1973 o - Jun 6 0 1 S -R b 1973 1975 - O 1 0 0 - -R b 1974 1977 - May 1 0 1 S -R b 1976 o - N 1 0 0 - -R b 1977 o - O 1 0 0 - -R b 1978 o - Ap 30 0 1 S -R b 1978 o - S 30 0 0 - -R b 1985 o - Ap 1 0 1 S -R b 1985 o - O 1 0 0 - -R b 1986 1988 - Ap F>=1 0 1 S -R b 1986 1990 - O F>=1 0 0 - -R b 1989 o - May 8 0 1 S -R b 1990 o - Ap 27 0 1 S -R b 1991 o - Ap 17 0 1 S -R b 1991 o - S 27 0 0 - -R b 1992 o - Ap 10 0 1 S -R b 1992 1993 - O F>=1 0 0 - -R b 1993 1998 - Ap F>=1 0 1 S -R b 1994 o - S F>=15 0 0 - -R b 1995 1998 - S F>=15 0s 0 - -R b 1999 o - Jul 1 0s 1 S -R b 1999 2002 - S lastF 0s 0 - -R b 2000 2001 - Mar lastTh 0s 1 S -R b 2002 2012 - Mar lastTh 24 1 S -R b 2003 o - O 24 0s 0 - -R b 2004 o - O 15 0s 0 - -R b 2005 o - S lastF 0s 0 - -R b 2006 2011 - O lastF 0s 0 - -R b 2013 o - D 20 0 0 - -R b 2014 ma - Mar lastTh 24 1 S -R b 2014 ma - O lastF 0s 0 - +9 JP J%sT +R J 1973 o - Jun 6 0 1 S +R J 1973 1975 - O 1 0 0 - +R J 1974 1977 - May 1 0 1 S +R J 1976 o - N 1 0 0 - +R J 1977 o - O 1 0 0 - +R J 1978 o - Ap 30 0 1 S +R J 1978 o - S 30 0 0 - +R J 1985 o - Ap 1 0 1 S +R J 1985 o - O 1 0 0 - +R J 1986 1988 - Ap F>=1 0 1 S +R J 1986 1990 - O F>=1 0 0 - +R J 1989 o - May 8 0 1 S +R J 1990 o - Ap 27 0 1 S +R J 1991 o - Ap 17 0 1 S +R J 1991 o - S 27 0 0 - +R J 1992 o - Ap 10 0 1 S +R J 1992 1993 - O F>=1 0 0 - +R J 1993 1998 - Ap F>=1 0 1 S +R J 1994 o - S F>=15 0 0 - +R J 1995 1998 - S F>=15 0s 0 - +R J 1999 o - Jul 1 0s 1 S +R J 1999 2002 - S lastF 0s 0 - +R J 2000 2001 - Mar lastTh 0s 1 S +R J 2002 2012 - Mar lastTh 24 1 S +R J 2003 o - O 24 0s 0 - +R J 2004 o - O 15 0s 0 - +R J 2005 o - S lastF 0s 0 - +R J 2006 2011 - O lastF 0s 0 - +R J 2013 o - D 20 0 0 - +R J 2014 ma - Mar lastTh 24 1 S +R J 2014 ma - O lastF 0s 0 - Z Asia/Amman 2:23:44 - LMT 1931 -2 b EE%sT +2 J EE%sT Z Asia/Almaty 5:7:48 - LMT 1924 May 2 5 - +05 1930 Jun 21 -6 M +06/+07 1991 Mar 31 2s -5 M +05/+06 1992 Ja 19 2s -6 M +06/+07 2004 O 31 2s +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 2004 O 31 2s 6 - +06 Z Asia/Qyzylorda 4:21:52 - LMT 1924 May 2 4 - +04 1930 Jun 21 5 - +05 1981 Ap 5 1 +06 1981 O 6 - +06 1982 Ap -5 M +05/+06 1991 Mar 31 2s -4 M +04/+05 1991 S 29 2s -5 M +05/+06 1992 Ja 19 2s -6 M +06/+07 1992 Mar 29 2s -5 M +05/+06 2004 O 31 2s +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1991 S 29 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 1992 Mar 29 2s +5 R +05/+06 2004 O 31 2s +6 - +06 2018 D 21 +5 - +05 +Z Asia/Qostanay 4:14:28 - LMT 1924 May 2 +4 - +04 1930 Jun 21 +5 - +05 1981 Ap +5 1 +06 1981 O +6 - +06 1982 Ap +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2004 O 31 2s 6 - +06 Z Asia/Aqtobe 3:48:40 - LMT 1924 May 2 4 - +04 1930 Jun 21 5 - +05 1981 Ap 5 1 +06 1981 O 6 - +06 1982 Ap -5 M +05/+06 1991 Mar 31 2s -4 M +04/+05 1992 Ja 19 2s -5 M +05/+06 2004 O 31 2s +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2004 O 31 2s 5 - +05 Z Asia/Aqtau 3:21:4 - LMT 1924 May 2 4 - +04 1930 Jun 21 5 - +05 1981 O 6 - +06 1982 Ap -5 M +05/+06 1991 Mar 31 2s -4 M +04/+05 1992 Ja 19 2s -5 M +05/+06 1994 S 25 2s -4 M +04/+05 2004 O 31 2s +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1994 S 25 2s +4 R +04/+05 2004 O 31 2s 5 - +05 Z Asia/Atyrau 3:27:44 - LMT 1924 May 2 3 - +03 1930 Jun 21 5 - +05 1981 O 6 - +06 1982 Ap -5 M +05/+06 1991 Mar 31 2s -4 M +04/+05 1992 Ja 19 2s -5 M +05/+06 1999 Mar 28 2s -4 M +04/+05 2004 O 31 2s +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1999 Mar 28 2s +4 R +04/+05 2004 O 31 2s 5 - +05 Z Asia/Oral 3:25:24 - LMT 1924 May 2 3 - +03 1930 Jun 21 5 - +05 1981 Ap 5 1 +06 1981 O 6 - +06 1982 Ap -5 M +05/+06 1989 Mar 26 2s -4 M +04/+05 1992 Ja 19 2s -5 M +05/+06 1992 Mar 29 2s -4 M +04/+05 2004 O 31 2s +5 R +05/+06 1989 Mar 26 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 1992 Mar 29 2s +4 R +04/+05 2004 O 31 2s 5 - +05 -R c 1992 1996 - Ap Sun>=7 0s 1 S -R c 1992 1996 - S lastSun 0 0 - -R c 1997 2005 - Mar lastSun 2:30 1 S -R c 1997 2004 - O lastSun 2:30 0 - +R KG 1992 1996 - Ap Su>=7 0s 1 - +R KG 1992 1996 - S lastSu 0 0 - +R KG 1997 2005 - Mar lastSu 2:30 1 - +R KG 1997 2004 - O lastSu 2:30 0 - Z Asia/Bishkek 4:58:24 - LMT 1924 May 2 5 - +05 1930 Jun 21 -6 M +06/+07 1991 Mar 31 2s -5 M +05/+06 1991 Au 31 2 -5 c +05/+06 2005 Au 12 +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1991 Au 31 2 +5 KG +05/+06 2005 Au 12 6 - +06 -R d 1948 o - Jun 1 0 1 D -R d 1948 o - S 13 0 0 S -R d 1949 o - Ap 3 0 1 D -R d 1949 1951 - S Sun>=8 0 0 S -R d 1950 o - Ap 1 0 1 D -R d 1951 o - May 6 0 1 D -R d 1955 o - May 5 0 1 D -R d 1955 o - S 9 0 0 S -R d 1956 o - May 20 0 1 D -R d 1956 o - S 30 0 0 S -R d 1957 1960 - May Sun>=1 0 1 D -R d 1957 1960 - S Sun>=18 0 0 S -R d 1987 1988 - May Sun>=8 2 1 D -R d 1987 1988 - O Sun>=8 3 0 S +R KR 1948 o - Jun 1 0 1 D +R KR 1948 o - S 12 24 0 S +R KR 1949 o - Ap 3 0 1 D +R KR 1949 1951 - S Sa>=7 24 0 S +R KR 1950 o - Ap 1 0 1 D +R KR 1951 o - May 6 0 1 D +R KR 1955 o - May 5 0 1 D +R KR 1955 o - S 8 24 0 S +R KR 1956 o - May 20 0 1 D +R KR 1956 o - S 29 24 0 S +R KR 1957 1960 - May Su>=1 0 1 D +R KR 1957 1960 - S Sa>=17 24 0 S +R KR 1987 1988 - May Su>=8 2 1 D +R KR 1987 1988 - O Su>=8 3 0 S Z Asia/Seoul 8:27:52 - LMT 1908 Ap 8:30 - KST 1912 9 - JST 1945 S 8 -9 - KST 1954 Mar 21 -8:30 d K%sT 1961 Au 10 -9 d K%sT +9 KR K%sT 1954 Mar 21 +8:30 KR K%sT 1961 Au 10 +9 KR K%sT Z Asia/Pyongyang 8:23 - LMT 1908 Ap 8:30 - KST 1912 9 - JST 1945 Au 24 9 - KST 2015 Au 15 -8:30 - KST -R e 1920 o - Mar 28 0 1 S -R e 1920 o - O 25 0 0 - -R e 1921 o - Ap 3 0 1 S -R e 1921 o - O 3 0 0 - -R e 1922 o - Mar 26 0 1 S -R e 1922 o - O 8 0 0 - -R e 1923 o - Ap 22 0 1 S -R e 1923 o - S 16 0 0 - -R e 1957 1961 - May 1 0 1 S -R e 1957 1961 - O 1 0 0 - -R e 1972 o - Jun 22 0 1 S -R e 1972 1977 - O 1 0 0 - -R e 1973 1977 - May 1 0 1 S -R e 1978 o - Ap 30 0 1 S -R e 1978 o - S 30 0 0 - -R e 1984 1987 - May 1 0 1 S -R e 1984 1991 - O 16 0 0 - -R e 1988 o - Jun 1 0 1 S -R e 1989 o - May 10 0 1 S -R e 1990 1992 - May 1 0 1 S -R e 1992 o - O 4 0 0 - -R e 1993 ma - Mar lastSun 0 1 S -R e 1993 1998 - S lastSun 0 0 - -R e 1999 ma - O lastSun 0 0 - +8:30 - KST 2018 May 4 23:30 +9 - KST +R l 1920 o - Mar 28 0 1 S +R l 1920 o - O 25 0 0 - +R l 1921 o - Ap 3 0 1 S +R l 1921 o - O 3 0 0 - +R l 1922 o - Mar 26 0 1 S +R l 1922 o - O 8 0 0 - +R l 1923 o - Ap 22 0 1 S +R l 1923 o - S 16 0 0 - +R l 1957 1961 - May 1 0 1 S +R l 1957 1961 - O 1 0 0 - +R l 1972 o - Jun 22 0 1 S +R l 1972 1977 - O 1 0 0 - +R l 1973 1977 - May 1 0 1 S +R l 1978 o - Ap 30 0 1 S +R l 1978 o - S 30 0 0 - +R l 1984 1987 - May 1 0 1 S +R l 1984 1991 - O 16 0 0 - +R l 1988 o - Jun 1 0 1 S +R l 1989 o - May 10 0 1 S +R l 1990 1992 - May 1 0 1 S +R l 1992 o - O 4 0 0 - +R l 1993 ma - Mar lastSu 0 1 S +R l 1993 1998 - S lastSu 0 0 - +R l 1999 ma - O lastSu 0 0 - Z Asia/Beirut 2:22 - LMT 1880 -2 e EE%sT -R f 1935 1941 - S 14 0 0:20 TS -R f 1935 1941 - D 14 0 0 - +2 l EE%sT +R NB 1935 1941 - S 14 0 0:20 - +R NB 1935 1941 - D 14 0 0 - Z Asia/Kuala_Lumpur 6:46:46 - LMT 1901 6:55:25 - SMT 1905 Jun 7 - +07 1933 @@ -827,106 +1043,107 @@ Z Asia/Kuala_Lumpur 6:46:46 - LMT 1901 8 - +08 Z Asia/Kuching 7:21:20 - LMT 1926 Mar 7:30 - +0730 1933 -8 f +08/+0820 1942 F 16 +8 NB +08/+0820 1942 F 16 9 - +09 1945 S 12 8 - +08 Z Indian/Maldives 4:54 - LMT 1880 4:54 - MMT 1960 5 - +05 -R g 1983 1984 - Ap 1 0 1 S -R g 1983 o - O 1 0 0 - -R g 1985 1998 - Mar lastSun 0 1 S -R g 1984 1998 - S lastSun 0 0 - -R g 2001 o - Ap lastSat 2 1 S -R g 2001 2006 - S lastSat 2 0 - -R g 2002 2006 - Mar lastSat 2 1 S -R g 2015 2016 - Mar lastSat 2 1 S -R g 2015 2016 - S lastSat 0 0 - +R X 1983 1984 - Ap 1 0 1 - +R X 1983 o - O 1 0 0 - +R X 1985 1998 - Mar lastSu 0 1 - +R X 1984 1998 - S lastSu 0 0 - +R X 2001 o - Ap lastSa 2 1 - +R X 2001 2006 - S lastSa 2 0 - +R X 2002 2006 - Mar lastSa 2 1 - +R X 2015 2016 - Mar lastSa 2 1 - +R X 2015 2016 - S lastSa 0 0 - Z Asia/Hovd 6:6:36 - LMT 1905 Au 6 - +06 1978 -7 g +07/+08 +7 X +07/+08 Z Asia/Ulaanbaatar 7:7:32 - LMT 1905 Au 7 - +07 1978 -8 g +08/+09 +8 X +08/+09 Z Asia/Choibalsan 7:38 - LMT 1905 Au 7 - +07 1978 8 - +08 1983 Ap -9 g +09/+10 2008 Mar 31 -8 g +08/+09 +9 X +09/+10 2008 Mar 31 +8 X +08/+09 Z Asia/Kathmandu 5:41:16 - LMT 1920 5:30 - +0530 1986 5:45 - +0545 -R h 2002 o - Ap Sun>=2 0 1 S -R h 2002 o - O Sun>=2 0 0 - -R h 2008 o - Jun 1 0 1 S -R h 2008 2009 - N 1 0 0 - -R h 2009 o - Ap 15 0 1 S +R PK 2002 o - Ap Su>=2 0 1 S +R PK 2002 o - O Su>=2 0 0 - +R PK 2008 o - Jun 1 0 1 S +R PK 2008 2009 - N 1 0 0 - +R PK 2009 o - Ap 15 0 1 S Z Asia/Karachi 4:28:12 - LMT 1907 5:30 - +0530 1942 S 5:30 1 +0630 1945 O 15 5:30 - +0530 1951 S 30 5 - +05 1971 Mar 26 -5 h PK%sT -R i 1999 2005 - Ap F>=15 0 1 S -R i 1999 2003 - O F>=15 0 0 - -R i 2004 o - O 1 1 0 - -R i 2005 o - O 4 2 0 - -R i 2006 2007 - Ap 1 0 1 S -R i 2006 o - S 22 0 0 - -R i 2007 o - S Th>=8 2 0 - -R i 2008 2009 - Mar lastF 0 1 S -R i 2008 o - S 1 0 0 - -R i 2009 o - S F>=1 1 0 - -R i 2010 o - Mar 26 0 1 S -R i 2010 o - Au 11 0 0 - -R i 2011 o - Ap 1 0:1 1 S -R i 2011 o - Au 1 0 0 - -R i 2011 o - Au 30 0 1 S -R i 2011 o - S 30 0 0 - -R i 2012 2014 - Mar lastTh 24 1 S -R i 2012 o - S 21 1 0 - -R i 2013 o - S F>=21 0 0 - -R i 2014 2015 - O F>=21 0 0 - -R i 2015 o - Mar lastF 24 1 S -R i 2016 ma - Mar lastSat 1 1 S -R i 2016 ma - O lastSat 1 0 - +5 PK PK%sT +R P 1999 2005 - Ap F>=15 0 1 S +R P 1999 2003 - O F>=15 0 0 - +R P 2004 o - O 1 1 0 - +R P 2005 o - O 4 2 0 - +R P 2006 2007 - Ap 1 0 1 S +R P 2006 o - S 22 0 0 - +R P 2007 o - S Th>=8 2 0 - +R P 2008 2009 - Mar lastF 0 1 S +R P 2008 o - S 1 0 0 - +R P 2009 o - S F>=1 1 0 - +R P 2010 o - Mar 26 0 1 S +R P 2010 o - Au 11 0 0 - +R P 2011 o - Ap 1 0:1 1 S +R P 2011 o - Au 1 0 0 - +R P 2011 o - Au 30 0 1 S +R P 2011 o - S 30 0 0 - +R P 2012 2014 - Mar lastTh 24 1 S +R P 2012 o - S 21 1 0 - +R P 2013 o - S F>=21 0 0 - +R P 2014 2015 - O F>=21 0 0 - +R P 2015 o - Mar lastF 24 1 S +R P 2016 2018 - Mar Sa>=24 1 1 S +R P 2016 ma - O lastSa 1 0 - +R P 2019 ma - Mar lastF 0 1 S Z Asia/Gaza 2:17:52 - LMT 1900 O 2 Z EET/EEST 1948 May 15 -2 B EE%sT 1967 Jun 5 +2 K EE%sT 1967 Jun 5 2 Z I%sT 1996 -2 b EE%sT 1999 -2 i EE%sT 2008 Au 29 +2 J EE%sT 1999 +2 P EE%sT 2008 Au 29 2 - EET 2008 S -2 i EE%sT 2010 +2 P EE%sT 2010 2 - EET 2010 Mar 27 0:1 -2 i EE%sT 2011 Au +2 P EE%sT 2011 Au 2 - EET 2012 -2 i EE%sT +2 P EE%sT Z Asia/Hebron 2:20:23 - LMT 1900 O 2 Z EET/EEST 1948 May 15 -2 B EE%sT 1967 Jun 5 +2 K EE%sT 1967 Jun 5 2 Z I%sT 1996 -2 b EE%sT 1999 -2 i EE%sT -R j 1936 o - N 1 0 1 S -R j 1937 o - F 1 0 0 - -R j 1954 o - Ap 12 0 1 S -R j 1954 o - Jul 1 0 0 - -R j 1978 o - Mar 22 0 1 S -R j 1978 o - S 21 0 0 - +2 J EE%sT 1999 +2 P EE%sT +R PH 1936 o - N 1 0 1 D +R PH 1937 o - F 1 0 0 S +R PH 1954 o - Ap 12 0 1 D +R PH 1954 o - Jul 1 0 0 S +R PH 1978 o - Mar 22 0 1 D +R PH 1978 o - S 21 0 0 S Z Asia/Manila -15:56 - LMT 1844 D 31 8:4 - LMT 1899 May 11 -8 j +08/+09 1942 May -9 - +09 1944 N -8 j +08/+09 +8 PH P%sT 1942 May +9 - JST 1944 N +8 PH P%sT Z Asia/Qatar 3:26:8 - LMT 1920 4 - +04 1972 Jun 3 - +03 -Li Asia/Qatar Asia/Bahrain +L Asia/Qatar Asia/Bahrain Z Asia/Riyadh 3:6:52 - LMT 1947 Mar 14 3 - +03 -Li Asia/Riyadh Asia/Aden -Li Asia/Riyadh Asia/Kuwait +L Asia/Riyadh Asia/Aden +L Asia/Riyadh Asia/Kuwait Z Asia/Singapore 6:55:25 - LMT 1901 6:55:25 - SMT 1905 Jun 7 - +07 1933 @@ -945,78 +1162,78 @@ Z Asia/Colombo 5:19:24 - LMT 1880 6:30 - +0630 1996 O 26 0:30 6 - +06 2006 Ap 15 0:30 5:30 - +0530 -R k 1920 1923 - Ap Sun>=15 2 1 S -R k 1920 1923 - O Sun>=1 2 0 - -R k 1962 o - Ap 29 2 1 S -R k 1962 o - O 1 2 0 - -R k 1963 1965 - May 1 2 1 S -R k 1963 o - S 30 2 0 - -R k 1964 o - O 1 2 0 - -R k 1965 o - S 30 2 0 - -R k 1966 o - Ap 24 2 1 S -R k 1966 1976 - O 1 2 0 - -R k 1967 1978 - May 1 2 1 S -R k 1977 1978 - S 1 2 0 - -R k 1983 1984 - Ap 9 2 1 S -R k 1983 1984 - O 1 2 0 - -R k 1986 o - F 16 2 1 S -R k 1986 o - O 9 2 0 - -R k 1987 o - Mar 1 2 1 S -R k 1987 1988 - O 31 2 0 - -R k 1988 o - Mar 15 2 1 S -R k 1989 o - Mar 31 2 1 S -R k 1989 o - O 1 2 0 - -R k 1990 o - Ap 1 2 1 S -R k 1990 o - S 30 2 0 - -R k 1991 o - Ap 1 0 1 S -R k 1991 1992 - O 1 0 0 - -R k 1992 o - Ap 8 0 1 S -R k 1993 o - Mar 26 0 1 S -R k 1993 o - S 25 0 0 - -R k 1994 1996 - Ap 1 0 1 S -R k 1994 2005 - O 1 0 0 - -R k 1997 1998 - Mar lastM 0 1 S -R k 1999 2006 - Ap 1 0 1 S -R k 2006 o - S 22 0 0 - -R k 2007 o - Mar lastF 0 1 S -R k 2007 o - N F>=1 0 0 - -R k 2008 o - Ap F>=1 0 1 S -R k 2008 o - N 1 0 0 - -R k 2009 o - Mar lastF 0 1 S -R k 2010 2011 - Ap F>=1 0 1 S -R k 2012 ma - Mar lastF 0 1 S -R k 2009 ma - O lastF 0 0 - +R S 1920 1923 - Ap Su>=15 2 1 S +R S 1920 1923 - O Su>=1 2 0 - +R S 1962 o - Ap 29 2 1 S +R S 1962 o - O 1 2 0 - +R S 1963 1965 - May 1 2 1 S +R S 1963 o - S 30 2 0 - +R S 1964 o - O 1 2 0 - +R S 1965 o - S 30 2 0 - +R S 1966 o - Ap 24 2 1 S +R S 1966 1976 - O 1 2 0 - +R S 1967 1978 - May 1 2 1 S +R S 1977 1978 - S 1 2 0 - +R S 1983 1984 - Ap 9 2 1 S +R S 1983 1984 - O 1 2 0 - +R S 1986 o - F 16 2 1 S +R S 1986 o - O 9 2 0 - +R S 1987 o - Mar 1 2 1 S +R S 1987 1988 - O 31 2 0 - +R S 1988 o - Mar 15 2 1 S +R S 1989 o - Mar 31 2 1 S +R S 1989 o - O 1 2 0 - +R S 1990 o - Ap 1 2 1 S +R S 1990 o - S 30 2 0 - +R S 1991 o - Ap 1 0 1 S +R S 1991 1992 - O 1 0 0 - +R S 1992 o - Ap 8 0 1 S +R S 1993 o - Mar 26 0 1 S +R S 1993 o - S 25 0 0 - +R S 1994 1996 - Ap 1 0 1 S +R S 1994 2005 - O 1 0 0 - +R S 1997 1998 - Mar lastM 0 1 S +R S 1999 2006 - Ap 1 0 1 S +R S 2006 o - S 22 0 0 - +R S 2007 o - Mar lastF 0 1 S +R S 2007 o - N F>=1 0 0 - +R S 2008 o - Ap F>=1 0 1 S +R S 2008 o - N 1 0 0 - +R S 2009 o - Mar lastF 0 1 S +R S 2010 2011 - Ap F>=1 0 1 S +R S 2012 ma - Mar lastF 0 1 S +R S 2009 ma - O lastF 0 0 - Z Asia/Damascus 2:25:12 - LMT 1920 -2 k EE%sT +2 S EE%sT Z Asia/Dushanbe 4:35:12 - LMT 1924 May 2 5 - +05 1930 Jun 21 -6 M +06/+07 1991 Mar 31 2s +6 R +06/+07 1991 Mar 31 2s 5 1 +05/+06 1991 S 9 2s 5 - +05 Z Asia/Bangkok 6:42:4 - LMT 1880 6:42:4 - BMT 1920 Ap 7 - +07 -Li Asia/Bangkok Asia/Phnom_Penh -Li Asia/Bangkok Asia/Vientiane +L Asia/Bangkok Asia/Phnom_Penh +L Asia/Bangkok Asia/Vientiane Z Asia/Ashgabat 3:53:32 - LMT 1924 May 2 4 - +04 1930 Jun 21 -5 M +05/+06 1991 Mar 31 2 -4 M +04/+05 1992 Ja 19 2 +5 R +05/+06 1991 Mar 31 2 +4 R +04/+05 1992 Ja 19 2 5 - +05 Z Asia/Dubai 3:41:12 - LMT 1920 4 - +04 -Li Asia/Dubai Asia/Muscat +L Asia/Dubai Asia/Muscat Z Asia/Samarkand 4:27:53 - LMT 1924 May 2 4 - +04 1930 Jun 21 5 - +05 1981 Ap 5 1 +06 1981 O 6 - +06 1982 Ap -5 M +05/+06 1992 +5 R +05/+06 1992 5 - +05 Z Asia/Tashkent 4:37:11 - LMT 1924 May 2 5 - +05 1930 Jun 21 -6 M +06/+07 1991 Mar 31 2 -5 M +05/+06 1992 +6 R +06/+07 1991 Mar 31 2 +5 R +05/+06 1992 5 - +05 Z Asia/Ho_Chi_Minh 7:6:40 - LMT 1906 Jul 7:6:30 - PLMT 1911 May @@ -1028,272 +1245,316 @@ Z Asia/Ho_Chi_Minh 7:6:40 - LMT 1906 Jul 7 - +07 1959 D 31 23 8 - +08 1975 Jun 13 7 - +07 -R l 1917 o - Ja 1 0:1 1 D -R l 1917 o - Mar 25 2 0 S -R l 1942 o - Ja 1 2 1 D -R l 1942 o - Mar 29 2 0 S -R l 1942 o - S 27 2 1 D -R l 1943 1944 - Mar lastSun 2 0 S -R l 1943 o - O 3 2 1 D +R AU 1917 o - Ja 1 0:1 1 D +R AU 1917 o - Mar 25 2 0 S +R AU 1942 o - Ja 1 2 1 D +R AU 1942 o - Mar 29 2 0 S +R AU 1942 o - S 27 2 1 D +R AU 1943 1944 - Mar lastSu 2 0 S +R AU 1943 o - O 3 2 1 D Z Australia/Darwin 8:43:20 - LMT 1895 F 9 - ACST 1899 May -9:30 l AC%sT -R m 1974 o - O lastSun 2s 1 D -R m 1975 o - Mar Sun>=1 2s 0 S -R m 1983 o - O lastSun 2s 1 D -R m 1984 o - Mar Sun>=1 2s 0 S -R m 1991 o - N 17 2s 1 D -R m 1992 o - Mar Sun>=1 2s 0 S -R m 2006 o - D 3 2s 1 D -R m 2007 2009 - Mar lastSun 2s 0 S -R m 2007 2008 - O lastSun 2s 1 D +9:30 AU AC%sT +R AW 1974 o - O lastSu 2s 1 D +R AW 1975 o - Mar Su>=1 2s 0 S +R AW 1983 o - O lastSu 2s 1 D +R AW 1984 o - Mar Su>=1 2s 0 S +R AW 1991 o - N 17 2s 1 D +R AW 1992 o - Mar Su>=1 2s 0 S +R AW 2006 o - D 3 2s 1 D +R AW 2007 2009 - Mar lastSu 2s 0 S +R AW 2007 2008 - O lastSu 2s 1 D Z Australia/Perth 7:43:24 - LMT 1895 D -8 l AW%sT 1943 Jul -8 m AW%sT +8 AU AW%sT 1943 Jul +8 AW AW%sT Z Australia/Eucla 8:35:28 - LMT 1895 D -8:45 l +0845/+0945 1943 Jul -8:45 m +0845/+0945 -R n 1971 o - O lastSun 2s 1 D -R n 1972 o - F lastSun 2s 0 S -R n 1989 1991 - O lastSun 2s 1 D -R n 1990 1992 - Mar Sun>=1 2s 0 S -R o 1992 1993 - O lastSun 2s 1 D -R o 1993 1994 - Mar Sun>=1 2s 0 S +8:45 AU +0845/+0945 1943 Jul +8:45 AW +0845/+0945 +R AQ 1971 o - O lastSu 2s 1 D +R AQ 1972 o - F lastSu 2s 0 S +R AQ 1989 1991 - O lastSu 2s 1 D +R AQ 1990 1992 - Mar Su>=1 2s 0 S +R Ho 1992 1993 - O lastSu 2s 1 D +R Ho 1993 1994 - Mar Su>=1 2s 0 S Z Australia/Brisbane 10:12:8 - LMT 1895 -10 l AE%sT 1971 -10 n AE%sT +10 AU AE%sT 1971 +10 AQ AE%sT Z Australia/Lindeman 9:55:56 - LMT 1895 -10 l AE%sT 1971 -10 n AE%sT 1992 Jul -10 o AE%sT -R p 1971 1985 - O lastSun 2s 1 D -R p 1986 o - O 19 2s 1 D -R p 1987 2007 - O lastSun 2s 1 D -R p 1972 o - F 27 2s 0 S -R p 1973 1985 - Mar Sun>=1 2s 0 S -R p 1986 1990 - Mar Sun>=15 2s 0 S -R p 1991 o - Mar 3 2s 0 S -R p 1992 o - Mar 22 2s 0 S -R p 1993 o - Mar 7 2s 0 S -R p 1994 o - Mar 20 2s 0 S -R p 1995 2005 - Mar lastSun 2s 0 S -R p 2006 o - Ap 2 2s 0 S -R p 2007 o - Mar lastSun 2s 0 S -R p 2008 ma - Ap Sun>=1 2s 0 S -R p 2008 ma - O Sun>=1 2s 1 D +10 AU AE%sT 1971 +10 AQ AE%sT 1992 Jul +10 Ho AE%sT +R AS 1971 1985 - O lastSu 2s 1 D +R AS 1986 o - O 19 2s 1 D +R AS 1987 2007 - O lastSu 2s 1 D +R AS 1972 o - F 27 2s 0 S +R AS 1973 1985 - Mar Su>=1 2s 0 S +R AS 1986 1990 - Mar Su>=15 2s 0 S +R AS 1991 o - Mar 3 2s 0 S +R AS 1992 o - Mar 22 2s 0 S +R AS 1993 o - Mar 7 2s 0 S +R AS 1994 o - Mar 20 2s 0 S +R AS 1995 2005 - Mar lastSu 2s 0 S +R AS 2006 o - Ap 2 2s 0 S +R AS 2007 o - Mar lastSu 2s 0 S +R AS 2008 ma - Ap Su>=1 2s 0 S +R AS 2008 ma - O Su>=1 2s 1 D Z Australia/Adelaide 9:14:20 - LMT 1895 F 9 - ACST 1899 May -9:30 l AC%sT 1971 -9:30 p AC%sT -R q 1967 o - O Sun>=1 2s 1 D -R q 1968 o - Mar lastSun 2s 0 S -R q 1968 1985 - O lastSun 2s 1 D -R q 1969 1971 - Mar Sun>=8 2s 0 S -R q 1972 o - F lastSun 2s 0 S -R q 1973 1981 - Mar Sun>=1 2s 0 S -R q 1982 1983 - Mar lastSun 2s 0 S -R q 1984 1986 - Mar Sun>=1 2s 0 S -R q 1986 o - O Sun>=15 2s 1 D -R q 1987 1990 - Mar Sun>=15 2s 0 S -R q 1987 o - O Sun>=22 2s 1 D -R q 1988 1990 - O lastSun 2s 1 D -R q 1991 1999 - O Sun>=1 2s 1 D -R q 1991 2005 - Mar lastSun 2s 0 S -R q 2000 o - Au lastSun 2s 1 D -R q 2001 ma - O Sun>=1 2s 1 D -R q 2006 o - Ap Sun>=1 2s 0 S -R q 2007 o - Mar lastSun 2s 0 S -R q 2008 ma - Ap Sun>=1 2s 0 S +9:30 AU AC%sT 1971 +9:30 AS AC%sT +R AT 1967 o - O Su>=1 2s 1 D +R AT 1968 o - Mar lastSu 2s 0 S +R AT 1968 1985 - O lastSu 2s 1 D +R AT 1969 1971 - Mar Su>=8 2s 0 S +R AT 1972 o - F lastSu 2s 0 S +R AT 1973 1981 - Mar Su>=1 2s 0 S +R AT 1982 1983 - Mar lastSu 2s 0 S +R AT 1984 1986 - Mar Su>=1 2s 0 S +R AT 1986 o - O Su>=15 2s 1 D +R AT 1987 1990 - Mar Su>=15 2s 0 S +R AT 1987 o - O Su>=22 2s 1 D +R AT 1988 1990 - O lastSu 2s 1 D +R AT 1991 1999 - O Su>=1 2s 1 D +R AT 1991 2005 - Mar lastSu 2s 0 S +R AT 2000 o - Au lastSu 2s 1 D +R AT 2001 ma - O Su>=1 2s 1 D +R AT 2006 o - Ap Su>=1 2s 0 S +R AT 2007 o - Mar lastSu 2s 0 S +R AT 2008 ma - Ap Su>=1 2s 0 S Z Australia/Hobart 9:49:16 - LMT 1895 S 10 - AEST 1916 O 1 2 10 1 AEDT 1917 F -10 l AE%sT 1967 -10 q AE%sT +10 AU AE%sT 1967 +10 AT AE%sT Z Australia/Currie 9:35:28 - LMT 1895 S 10 - AEST 1916 O 1 2 10 1 AEDT 1917 F -10 l AE%sT 1971 Jul -10 q AE%sT -R r 1971 1985 - O lastSun 2s 1 D -R r 1972 o - F lastSun 2s 0 S -R r 1973 1985 - Mar Sun>=1 2s 0 S -R r 1986 1990 - Mar Sun>=15 2s 0 S -R r 1986 1987 - O Sun>=15 2s 1 D -R r 1988 1999 - O lastSun 2s 1 D -R r 1991 1994 - Mar Sun>=1 2s 0 S -R r 1995 2005 - Mar lastSun 2s 0 S -R r 2000 o - Au lastSun 2s 1 D -R r 2001 2007 - O lastSun 2s 1 D -R r 2006 o - Ap Sun>=1 2s 0 S -R r 2007 o - Mar lastSun 2s 0 S -R r 2008 ma - Ap Sun>=1 2s 0 S -R r 2008 ma - O Sun>=1 2s 1 D +10 AU AE%sT 1971 Jul +10 AT AE%sT +R AV 1971 1985 - O lastSu 2s 1 D +R AV 1972 o - F lastSu 2s 0 S +R AV 1973 1985 - Mar Su>=1 2s 0 S +R AV 1986 1990 - Mar Su>=15 2s 0 S +R AV 1986 1987 - O Su>=15 2s 1 D +R AV 1988 1999 - O lastSu 2s 1 D +R AV 1991 1994 - Mar Su>=1 2s 0 S +R AV 1995 2005 - Mar lastSu 2s 0 S +R AV 2000 o - Au lastSu 2s 1 D +R AV 2001 2007 - O lastSu 2s 1 D +R AV 2006 o - Ap Su>=1 2s 0 S +R AV 2007 o - Mar lastSu 2s 0 S +R AV 2008 ma - Ap Su>=1 2s 0 S +R AV 2008 ma - O Su>=1 2s 1 D Z Australia/Melbourne 9:39:52 - LMT 1895 F -10 l AE%sT 1971 -10 r AE%sT -R s 1971 1985 - O lastSun 2s 1 D -R s 1972 o - F 27 2s 0 S -R s 1973 1981 - Mar Sun>=1 2s 0 S -R s 1982 o - Ap Sun>=1 2s 0 S -R s 1983 1985 - Mar Sun>=1 2s 0 S -R s 1986 1989 - Mar Sun>=15 2s 0 S -R s 1986 o - O 19 2s 1 D -R s 1987 1999 - O lastSun 2s 1 D -R s 1990 1995 - Mar Sun>=1 2s 0 S -R s 1996 2005 - Mar lastSun 2s 0 S -R s 2000 o - Au lastSun 2s 1 D -R s 2001 2007 - O lastSun 2s 1 D -R s 2006 o - Ap Sun>=1 2s 0 S -R s 2007 o - Mar lastSun 2s 0 S -R s 2008 ma - Ap Sun>=1 2s 0 S -R s 2008 ma - O Sun>=1 2s 1 D +10 AU AE%sT 1971 +10 AV AE%sT +R AN 1971 1985 - O lastSu 2s 1 D +R AN 1972 o - F 27 2s 0 S +R AN 1973 1981 - Mar Su>=1 2s 0 S +R AN 1982 o - Ap Su>=1 2s 0 S +R AN 1983 1985 - Mar Su>=1 2s 0 S +R AN 1986 1989 - Mar Su>=15 2s 0 S +R AN 1986 o - O 19 2s 1 D +R AN 1987 1999 - O lastSu 2s 1 D +R AN 1990 1995 - Mar Su>=1 2s 0 S +R AN 1996 2005 - Mar lastSu 2s 0 S +R AN 2000 o - Au lastSu 2s 1 D +R AN 2001 2007 - O lastSu 2s 1 D +R AN 2006 o - Ap Su>=1 2s 0 S +R AN 2007 o - Mar lastSu 2s 0 S +R AN 2008 ma - Ap Su>=1 2s 0 S +R AN 2008 ma - O Su>=1 2s 1 D Z Australia/Sydney 10:4:52 - LMT 1895 F -10 l AE%sT 1971 -10 s AE%sT +10 AU AE%sT 1971 +10 AN AE%sT Z Australia/Broken_Hill 9:25:48 - LMT 1895 F 10 - AEST 1896 Au 23 9 - ACST 1899 May -9:30 l AC%sT 1971 -9:30 s AC%sT 2000 -9:30 p AC%sT -R t 1981 1984 - O lastSun 2 1 D -R t 1982 1985 - Mar Sun>=1 2 0 S -R t 1985 o - O lastSun 2 0:30 D -R t 1986 1989 - Mar Sun>=15 2 0 S -R t 1986 o - O 19 2 0:30 D -R t 1987 1999 - O lastSun 2 0:30 D -R t 1990 1995 - Mar Sun>=1 2 0 S -R t 1996 2005 - Mar lastSun 2 0 S -R t 2000 o - Au lastSun 2 0:30 D -R t 2001 2007 - O lastSun 2 0:30 D -R t 2006 o - Ap Sun>=1 2 0 S -R t 2007 o - Mar lastSun 2 0 S -R t 2008 ma - Ap Sun>=1 2 0 S -R t 2008 ma - O Sun>=1 2 0:30 D +9:30 AU AC%sT 1971 +9:30 AN AC%sT 2000 +9:30 AS AC%sT +R LH 1981 1984 - O lastSu 2 1 - +R LH 1982 1985 - Mar Su>=1 2 0 - +R LH 1985 o - O lastSu 2 0:30 - +R LH 1986 1989 - Mar Su>=15 2 0 - +R LH 1986 o - O 19 2 0:30 - +R LH 1987 1999 - O lastSu 2 0:30 - +R LH 1990 1995 - Mar Su>=1 2 0 - +R LH 1996 2005 - Mar lastSu 2 0 - +R LH 2000 o - Au lastSu 2 0:30 - +R LH 2001 2007 - O lastSu 2 0:30 - +R LH 2006 o - Ap Su>=1 2 0 - +R LH 2007 o - Mar lastSu 2 0 - +R LH 2008 ma - Ap Su>=1 2 0 - +R LH 2008 ma - O Su>=1 2 0:30 - Z Australia/Lord_Howe 10:36:20 - LMT 1895 F 10 - AEST 1981 Mar -10:30 t +1030/+1130 1985 Jul -10:30 t +1030/+11 +10:30 LH +1030/+1130 1985 Jul +10:30 LH +1030/+11 Z Antarctica/Macquarie 0 - -00 1899 N 10 - AEST 1916 O 1 2 10 1 AEDT 1917 F -10 l AE%sT 1919 Ap 1 0s +10 AU AE%sT 1919 Ap 1 0s 0 - -00 1948 Mar 25 -10 l AE%sT 1967 -10 q AE%sT 2010 Ap 4 3 +10 AU AE%sT 1967 +10 AT AE%sT 2010 Ap 4 3 11 - +11 Z Indian/Christmas 7:2:52 - LMT 1895 F 7 - +07 Z Indian/Cocos 6:27:40 - LMT 1900 6:30 - +0630 -R u 1998 1999 - N Sun>=1 2 1 S -R u 1999 2000 - F lastSun 3 0 - -R u 2009 o - N 29 2 1 S -R u 2010 o - Mar lastSun 3 0 - -R u 2010 2013 - O Sun>=21 2 1 S -R u 2011 o - Mar Sun>=1 3 0 - -R u 2012 2013 - Ja Sun>=18 3 0 - -R u 2014 o - Ja Sun>=18 2 0 - -R u 2014 ma - N Sun>=1 2 1 S -R u 2015 ma - Ja Sun>=14 3 0 - +R FJ 1998 1999 - N Su>=1 2 1 - +R FJ 1999 2000 - F lastSu 3 0 - +R FJ 2009 o - N 29 2 1 - +R FJ 2010 o - Mar lastSu 3 0 - +R FJ 2010 2013 - O Su>=21 2 1 - +R FJ 2011 o - Mar Su>=1 3 0 - +R FJ 2012 2013 - Ja Su>=18 3 0 - +R FJ 2014 o - Ja Su>=18 2 0 - +R FJ 2014 2018 - N Su>=1 2 1 - +R FJ 2015 ma - Ja Su>=12 3 0 - +R FJ 2019 ma - N Su>=8 2 1 - Z Pacific/Fiji 11:55:44 - LMT 1915 O 26 -12 u +12/+13 +12 FJ +12/+13 Z Pacific/Gambier -8:59:48 - LMT 1912 O -9 - -09 Z Pacific/Marquesas -9:18 - LMT 1912 O -9:30 - -0930 Z Pacific/Tahiti -9:58:16 - LMT 1912 O -10 - -10 +R Gu 1959 o - Jun 27 2 1 D +R Gu 1961 o - Ja 29 2 0 S +R Gu 1967 o - S 1 2 1 D +R Gu 1969 o - Ja 26 0:1 0 S +R Gu 1969 o - Jun 22 2 1 D +R Gu 1969 o - Au 31 2 0 S +R Gu 1970 1971 - Ap lastSu 2 1 D +R Gu 1970 1971 - S Su>=1 2 0 S +R Gu 1973 o - D 16 2 1 D +R Gu 1974 o - F 24 2 0 S +R Gu 1976 o - May 26 2 1 D +R Gu 1976 o - Au 22 2:1 0 S +R Gu 1977 o - Ap 24 2 1 D +R Gu 1977 o - Au 28 2 0 S Z Pacific/Guam -14:21 - LMT 1844 D 31 9:39 - LMT 1901 -10 - GST 2000 D 23 +10 - GST 1941 D 10 +9 - +09 1944 Jul 31 +10 Gu G%sT 2000 D 23 10 - ChST -Li Pacific/Guam Pacific/Saipan +L Pacific/Guam Pacific/Saipan Z Pacific/Tarawa 11:32:4 - LMT 1901 12 - +12 Z Pacific/Enderbury -11:24:20 - LMT 1901 -12 - -12 1979 O --11 - -11 1995 +-11 - -11 1994 D 31 13 - +13 Z Pacific/Kiritimati -10:29:20 - LMT 1901 -10:40 - -1040 1979 O --10 - -10 1995 +-10 - -10 1994 D 31 14 - +14 Z Pacific/Majuro 11:24:48 - LMT 1901 +11 - +11 1914 O +9 - +09 1919 F +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1944 Ja 30 11 - +11 1969 O 12 - +12 Z Pacific/Kwajalein 11:9:20 - LMT 1901 +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1944 F 6 11 - +11 1969 O --12 - -12 1993 Au 20 +-12 - -12 1993 Au 20 24 12 - +12 -Z Pacific/Chuuk 10:7:8 - LMT 1901 +Z Pacific/Chuuk -13:52:52 - LMT 1844 D 31 +10:7:8 - LMT 1901 +10 - +10 1914 O +9 - +09 1919 F +10 - +10 1941 Ap +9 - +09 1945 Au 10 - +10 -Z Pacific/Pohnpei 10:32:52 - LMT 1901 +Z Pacific/Pohnpei -13:27:8 - LMT 1844 D 31 +10:32:52 - LMT 1901 +11 - +11 1914 O +9 - +09 1919 F +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1945 Au 11 - +11 -Z Pacific/Kosrae 10:51:56 - LMT 1901 +Z Pacific/Kosrae -13:8:4 - LMT 1844 D 31 +10:51:56 - LMT 1901 +11 - +11 1914 O +9 - +09 1919 F +11 - +11 1937 +10 - +10 1941 Ap +9 - +09 1945 Au 11 - +11 1969 O 12 - +12 1999 11 - +11 Z Pacific/Nauru 11:7:40 - LMT 1921 Ja 15 -11:30 - +1130 1942 Mar 15 -9 - +09 1944 Au 15 -11:30 - +1130 1979 May +11:30 - +1130 1942 Au 29 +9 - +09 1945 S 8 +11:30 - +1130 1979 F 10 2 12 - +12 -R v 1977 1978 - D Sun>=1 0 1 S -R v 1978 1979 - F 27 0 0 - -R v 1996 o - D 1 2s 1 S -R v 1997 o - Mar 2 2s 0 - +R NC 1977 1978 - D Su>=1 0 1 - +R NC 1978 1979 - F 27 0 0 - +R NC 1996 o - D 1 2s 1 - +R NC 1997 o - Mar 2 2s 0 - Z Pacific/Noumea 11:5:48 - LMT 1912 Ja 13 -11 v +11/+12 -R w 1927 o - N 6 2 1 S -R w 1928 o - Mar 4 2 0 M -R w 1928 1933 - O Sun>=8 2 0:30 S -R w 1929 1933 - Mar Sun>=15 2 0 M -R w 1934 1940 - Ap lastSun 2 0 M -R w 1934 1940 - S lastSun 2 0:30 S -R w 1946 o - Ja 1 0 0 S -R w 1974 o - N Sun>=1 2s 1 D -R x 1974 o - N Sun>=1 2:45s 1 D -R w 1975 o - F lastSun 2s 0 S -R x 1975 o - F lastSun 2:45s 0 S -R w 1975 1988 - O lastSun 2s 1 D -R x 1975 1988 - O lastSun 2:45s 1 D -R w 1976 1989 - Mar Sun>=1 2s 0 S -R x 1976 1989 - Mar Sun>=1 2:45s 0 S -R w 1989 o - O Sun>=8 2s 1 D -R x 1989 o - O Sun>=8 2:45s 1 D -R w 1990 2006 - O Sun>=1 2s 1 D -R x 1990 2006 - O Sun>=1 2:45s 1 D -R w 1990 2007 - Mar Sun>=15 2s 0 S -R x 1990 2007 - Mar Sun>=15 2:45s 0 S -R w 2007 ma - S lastSun 2s 1 D -R x 2007 ma - S lastSun 2:45s 1 D -R w 2008 ma - Ap Sun>=1 2s 0 S -R x 2008 ma - Ap Sun>=1 2:45s 0 S +11 NC +11/+12 +R NZ 1927 o - N 6 2 1 S +R NZ 1928 o - Mar 4 2 0 M +R NZ 1928 1933 - O Su>=8 2 0:30 S +R NZ 1929 1933 - Mar Su>=15 2 0 M +R NZ 1934 1940 - Ap lastSu 2 0 M +R NZ 1934 1940 - S lastSu 2 0:30 S +R NZ 1946 o - Ja 1 0 0 S +R NZ 1974 o - N Su>=1 2s 1 D +R k 1974 o - N Su>=1 2:45s 1 - +R NZ 1975 o - F lastSu 2s 0 S +R k 1975 o - F lastSu 2:45s 0 - +R NZ 1975 1988 - O lastSu 2s 1 D +R k 1975 1988 - O lastSu 2:45s 1 - +R NZ 1976 1989 - Mar Su>=1 2s 0 S +R k 1976 1989 - Mar Su>=1 2:45s 0 - +R NZ 1989 o - O Su>=8 2s 1 D +R k 1989 o - O Su>=8 2:45s 1 - +R NZ 1990 2006 - O Su>=1 2s 1 D +R k 1990 2006 - O Su>=1 2:45s 1 - +R NZ 1990 2007 - Mar Su>=15 2s 0 S +R k 1990 2007 - Mar Su>=15 2:45s 0 - +R NZ 2007 ma - S lastSu 2s 1 D +R k 2007 ma - S lastSu 2:45s 1 - +R NZ 2008 ma - Ap Su>=1 2s 0 S +R k 2008 ma - Ap Su>=1 2:45s 0 - Z Pacific/Auckland 11:39:4 - LMT 1868 N 2 -11:30 w NZ%sT 1946 -12 w NZ%sT +11:30 NZ NZ%sT 1946 +12 NZ NZ%sT Z Pacific/Chatham 12:13:48 - LMT 1868 N 2 12:15 - +1215 1946 -12:45 x +1245/+1345 -Li Pacific/Auckland Antarctica/McMurdo -R y 1978 o - N 12 0 0:30 HS -R y 1979 1991 - Mar Sun>=1 0 0 - -R y 1979 1990 - O lastSun 0 0:30 HS +12:45 k +1245/+1345 +L Pacific/Auckland Antarctica/McMurdo +R CK 1978 o - N 12 0 0:30 - +R CK 1979 1991 - Mar Su>=1 0 0 - +R CK 1979 1990 - O lastSu 0 0:30 - Z Pacific/Rarotonga -10:39:4 - LMT 1901 -10:30 - -1030 1978 N 12 --10 y -10/-0930 +-10 CK -10/-0930 Z Pacific/Niue -11:19:40 - LMT 1901 -11:20 - -1120 1951 -11:30 - -1130 1978 O -11 - -11 Z Pacific/Norfolk 11:11:52 - LMT 1901 11:12 - +1112 1951 -11:30 - +1130 1974 O 27 2 -11:30 1 +1230 1975 Mar 2 2 -11:30 - +1130 2015 O 4 2 -11 - +11 -Z Pacific/Palau 8:57:56 - LMT 1901 +11:30 - +1130 1974 O 27 2s +11:30 1 +1230 1975 Mar 2 2s +11:30 - +1130 2015 O 4 2s +11 - +11 2019 Jul +11 AN +11/+12 +Z Pacific/Palau -15:2:4 - LMT 1844 D 31 +8:57:56 - LMT 1901 9 - +09 Z Pacific/Port_Moresby 9:48:40 - LMT 1880 9:48:32 - PMMT 1895 @@ -1310,565 +1571,572 @@ Z Pacific/Pitcairn -8:40:20 - LMT 1901 Z Pacific/Pago_Pago 12:37:12 - LMT 1892 Jul 5 -11:22:48 - LMT 1911 -11 - SST -Li Pacific/Pago_Pago Pacific/Midway -R z 2010 o - S lastSun 0 1 D -R z 2011 o - Ap Sat>=1 4 0 S -R z 2011 o - S lastSat 3 1 D -R z 2012 ma - Ap Sun>=1 4 0 S -R z 2012 ma - S lastSun 3 1 D +L Pacific/Pago_Pago Pacific/Midway +R WS 2010 o - S lastSu 0 1 - +R WS 2011 o - Ap Sa>=1 4 0 - +R WS 2011 o - S lastSa 3 1 - +R WS 2012 ma - Ap Su>=1 4 0 - +R WS 2012 ma - S lastSu 3 1 - Z Pacific/Apia 12:33:4 - LMT 1892 Jul 5 -11:26:56 - LMT 1911 -11:30 - -1130 1950 --11 z -11/-10 2011 D 29 24 -13 z +13/+14 +-11 WS -11/-10 2011 D 29 24 +13 WS +13/+14 Z Pacific/Guadalcanal 10:39:48 - LMT 1912 O 11 - +11 Z Pacific/Fakaofo -11:24:56 - LMT 1901 -11 - -11 2011 D 30 13 - +13 -R ! 1999 o - O 7 2s 1 S -R ! 2000 o - Mar 19 2s 0 - -R ! 2000 2001 - N Sun>=1 2 1 S -R ! 2001 2002 - Ja lastSun 2 0 - -R ! 2016 o - N Sun>=1 2 1 S -R ! 2017 o - Ja Sun>=15 3 0 - +R TO 1999 o - O 7 2s 1 - +R TO 2000 o - Mar 19 2s 0 - +R TO 2000 2001 - N Su>=1 2 1 - +R TO 2001 2002 - Ja lastSu 2 0 - +R TO 2016 o - N Su>=1 2 1 - +R TO 2017 o - Ja Su>=15 3 0 - Z Pacific/Tongatapu 12:19:20 - LMT 1901 12:20 - +1220 1941 13 - +13 1999 -13 ! +13/+14 +13 TO +13/+14 Z Pacific/Funafuti 11:56:52 - LMT 1901 12 - +12 Z Pacific/Wake 11:6:28 - LMT 1901 12 - +12 -R $ 1983 o - S 25 0 1 S -R $ 1984 1991 - Mar Sun>=23 0 0 - -R $ 1984 o - O 23 0 1 S -R $ 1985 1991 - S Sun>=23 0 1 S -R $ 1992 1993 - Ja Sun>=23 0 0 - -R $ 1992 o - O Sun>=23 0 1 S +R VU 1983 o - S 25 0 1 - +R VU 1984 1991 - Mar Su>=23 0 0 - +R VU 1984 o - O 23 0 1 - +R VU 1985 1991 - S Su>=23 0 1 - +R VU 1992 1993 - Ja Su>=23 0 0 - +R VU 1992 o - O Su>=23 0 1 - Z Pacific/Efate 11:13:16 - LMT 1912 Ja 13 -11 $ +11/+12 +11 VU +11/+12 Z Pacific/Wallis 12:15:20 - LMT 1901 12 - +12 -R % 1916 o - May 21 2s 1 BST -R % 1916 o - O 1 2s 0 GMT -R % 1917 o - Ap 8 2s 1 BST -R % 1917 o - S 17 2s 0 GMT -R % 1918 o - Mar 24 2s 1 BST -R % 1918 o - S 30 2s 0 GMT -R % 1919 o - Mar 30 2s 1 BST -R % 1919 o - S 29 2s 0 GMT -R % 1920 o - Mar 28 2s 1 BST -R % 1920 o - O 25 2s 0 GMT -R % 1921 o - Ap 3 2s 1 BST -R % 1921 o - O 3 2s 0 GMT -R % 1922 o - Mar 26 2s 1 BST -R % 1922 o - O 8 2s 0 GMT -R % 1923 o - Ap Sun>=16 2s 1 BST -R % 1923 1924 - S Sun>=16 2s 0 GMT -R % 1924 o - Ap Sun>=9 2s 1 BST -R % 1925 1926 - Ap Sun>=16 2s 1 BST -R % 1925 1938 - O Sun>=2 2s 0 GMT -R % 1927 o - Ap Sun>=9 2s 1 BST -R % 1928 1929 - Ap Sun>=16 2s 1 BST -R % 1930 o - Ap Sun>=9 2s 1 BST -R % 1931 1932 - Ap Sun>=16 2s 1 BST -R % 1933 o - Ap Sun>=9 2s 1 BST -R % 1934 o - Ap Sun>=16 2s 1 BST -R % 1935 o - Ap Sun>=9 2s 1 BST -R % 1936 1937 - Ap Sun>=16 2s 1 BST -R % 1938 o - Ap Sun>=9 2s 1 BST -R % 1939 o - Ap Sun>=16 2s 1 BST -R % 1939 o - N Sun>=16 2s 0 GMT -R % 1940 o - F Sun>=23 2s 1 BST -R % 1941 o - May Sun>=2 1s 2 BDST -R % 1941 1943 - Au Sun>=9 1s 1 BST -R % 1942 1944 - Ap Sun>=2 1s 2 BDST -R % 1944 o - S Sun>=16 1s 1 BST -R % 1945 o - Ap M>=2 1s 2 BDST -R % 1945 o - Jul Sun>=9 1s 1 BST -R % 1945 1946 - O Sun>=2 2s 0 GMT -R % 1946 o - Ap Sun>=9 2s 1 BST -R % 1947 o - Mar 16 2s 1 BST -R % 1947 o - Ap 13 1s 2 BDST -R % 1947 o - Au 10 1s 1 BST -R % 1947 o - N 2 2s 0 GMT -R % 1948 o - Mar 14 2s 1 BST -R % 1948 o - O 31 2s 0 GMT -R % 1949 o - Ap 3 2s 1 BST -R % 1949 o - O 30 2s 0 GMT -R % 1950 1952 - Ap Sun>=14 2s 1 BST -R % 1950 1952 - O Sun>=21 2s 0 GMT -R % 1953 o - Ap Sun>=16 2s 1 BST -R % 1953 1960 - O Sun>=2 2s 0 GMT -R % 1954 o - Ap Sun>=9 2s 1 BST -R % 1955 1956 - Ap Sun>=16 2s 1 BST -R % 1957 o - Ap Sun>=9 2s 1 BST -R % 1958 1959 - Ap Sun>=16 2s 1 BST -R % 1960 o - Ap Sun>=9 2s 1 BST -R % 1961 1963 - Mar lastSun 2s 1 BST -R % 1961 1968 - O Sun>=23 2s 0 GMT -R % 1964 1967 - Mar Sun>=19 2s 1 BST -R % 1968 o - F 18 2s 1 BST -R % 1972 1980 - Mar Sun>=16 2s 1 BST -R % 1972 1980 - O Sun>=23 2s 0 GMT -R % 1981 1995 - Mar lastSun 1u 1 BST -R % 1981 1989 - O Sun>=23 1u 0 GMT -R % 1990 1995 - O Sun>=22 1u 0 GMT +R G 1916 o - May 21 2s 1 BST +R G 1916 o - O 1 2s 0 GMT +R G 1917 o - Ap 8 2s 1 BST +R G 1917 o - S 17 2s 0 GMT +R G 1918 o - Mar 24 2s 1 BST +R G 1918 o - S 30 2s 0 GMT +R G 1919 o - Mar 30 2s 1 BST +R G 1919 o - S 29 2s 0 GMT +R G 1920 o - Mar 28 2s 1 BST +R G 1920 o - O 25 2s 0 GMT +R G 1921 o - Ap 3 2s 1 BST +R G 1921 o - O 3 2s 0 GMT +R G 1922 o - Mar 26 2s 1 BST +R G 1922 o - O 8 2s 0 GMT +R G 1923 o - Ap Su>=16 2s 1 BST +R G 1923 1924 - S Su>=16 2s 0 GMT +R G 1924 o - Ap Su>=9 2s 1 BST +R G 1925 1926 - Ap Su>=16 2s 1 BST +R G 1925 1938 - O Su>=2 2s 0 GMT +R G 1927 o - Ap Su>=9 2s 1 BST +R G 1928 1929 - Ap Su>=16 2s 1 BST +R G 1930 o - Ap Su>=9 2s 1 BST +R G 1931 1932 - Ap Su>=16 2s 1 BST +R G 1933 o - Ap Su>=9 2s 1 BST +R G 1934 o - Ap Su>=16 2s 1 BST +R G 1935 o - Ap Su>=9 2s 1 BST +R G 1936 1937 - Ap Su>=16 2s 1 BST +R G 1938 o - Ap Su>=9 2s 1 BST +R G 1939 o - Ap Su>=16 2s 1 BST +R G 1939 o - N Su>=16 2s 0 GMT +R G 1940 o - F Su>=23 2s 1 BST +R G 1941 o - May Su>=2 1s 2 BDST +R G 1941 1943 - Au Su>=9 1s 1 BST +R G 1942 1944 - Ap Su>=2 1s 2 BDST +R G 1944 o - S Su>=16 1s 1 BST +R G 1945 o - Ap M>=2 1s 2 BDST +R G 1945 o - Jul Su>=9 1s 1 BST +R G 1945 1946 - O Su>=2 2s 0 GMT +R G 1946 o - Ap Su>=9 2s 1 BST +R G 1947 o - Mar 16 2s 1 BST +R G 1947 o - Ap 13 1s 2 BDST +R G 1947 o - Au 10 1s 1 BST +R G 1947 o - N 2 2s 0 GMT +R G 1948 o - Mar 14 2s 1 BST +R G 1948 o - O 31 2s 0 GMT +R G 1949 o - Ap 3 2s 1 BST +R G 1949 o - O 30 2s 0 GMT +R G 1950 1952 - Ap Su>=14 2s 1 BST +R G 1950 1952 - O Su>=21 2s 0 GMT +R G 1953 o - Ap Su>=16 2s 1 BST +R G 1953 1960 - O Su>=2 2s 0 GMT +R G 1954 o - Ap Su>=9 2s 1 BST +R G 1955 1956 - Ap Su>=16 2s 1 BST +R G 1957 o - Ap Su>=9 2s 1 BST +R G 1958 1959 - Ap Su>=16 2s 1 BST +R G 1960 o - Ap Su>=9 2s 1 BST +R G 1961 1963 - Mar lastSu 2s 1 BST +R G 1961 1968 - O Su>=23 2s 0 GMT +R G 1964 1967 - Mar Su>=19 2s 1 BST +R G 1968 o - F 18 2s 1 BST +R G 1972 1980 - Mar Su>=16 2s 1 BST +R G 1972 1980 - O Su>=23 2s 0 GMT +R G 1981 1995 - Mar lastSu 1u 1 BST +R G 1981 1989 - O Su>=23 1u 0 GMT +R G 1990 1995 - O Su>=22 1u 0 GMT Z Europe/London -0:1:15 - LMT 1847 D 1 0s -0 % %s 1968 O 27 +0 G %s 1968 O 27 1 - BST 1971 O 31 2u -0 % %s 1996 -0 O GMT/BST -Li Europe/London Europe/Jersey -Li Europe/London Europe/Guernsey -Li Europe/London Europe/Isle_of_Man +0 G %s 1996 +0 E GMT/BST +L Europe/London Europe/Jersey +L Europe/London Europe/Guernsey +L Europe/London Europe/Isle_of_Man +R IE 1971 o - O 31 2u -1 - +R IE 1972 1980 - Mar Su>=16 2u 0 - +R IE 1972 1980 - O Su>=23 2u -1 - +R IE 1981 ma - Mar lastSu 1u 0 - +R IE 1981 1989 - O Su>=23 1u -1 - +R IE 1990 1995 - O Su>=22 1u -1 - +R IE 1996 ma - O lastSu 1u -1 - Z Europe/Dublin -0:25 - LMT 1880 Au 2 -0:25:21 - DMT 1916 May 21 2s -0:25:21 1 IST 1916 O 1 2s -0 % %s 1921 D 6 -0 % GMT/IST 1940 F 25 2s +0 G %s 1921 D 6 +0 G GMT/IST 1940 F 25 2s 0 1 IST 1946 O 6 2s 0 - GMT 1947 Mar 16 2s 0 1 IST 1947 N 2 2s 0 - GMT 1948 Ap 18 2s -0 % GMT/IST 1968 O 27 -1 - IST 1971 O 31 2u -0 % GMT/IST 1996 -0 O GMT/IST -R O 1977 1980 - Ap Sun>=1 1u 1 S -R O 1977 o - S lastSun 1u 0 - -R O 1978 o - O 1 1u 0 - -R O 1979 1995 - S lastSun 1u 0 - -R O 1981 ma - Mar lastSun 1u 1 S -R O 1996 ma - O lastSun 1u 0 - -R & 1977 1980 - Ap Sun>=1 1s 1 S -R & 1977 o - S lastSun 1s 0 - -R & 1978 o - O 1 1s 0 - -R & 1979 1995 - S lastSun 1s 0 - -R & 1981 ma - Mar lastSun 1s 1 S -R & 1996 ma - O lastSun 1s 0 - -R ' 1916 o - Ap 30 23 1 S -R ' 1916 o - O 1 1 0 - -R ' 1917 1918 - Ap M>=15 2s 1 S -R ' 1917 1918 - S M>=15 2s 0 - -R ' 1940 o - Ap 1 2s 1 S -R ' 1942 o - N 2 2s 0 - -R ' 1943 o - Mar 29 2s 1 S -R ' 1943 o - O 4 2s 0 - -R ' 1944 1945 - Ap M>=1 2s 1 S -R ' 1944 o - O 2 2s 0 - -R ' 1945 o - S 16 2s 0 - -R ' 1977 1980 - Ap Sun>=1 2s 1 S -R ' 1977 o - S lastSun 2s 0 - -R ' 1978 o - O 1 2s 0 - -R ' 1979 1995 - S lastSun 2s 0 - -R ' 1981 ma - Mar lastSun 2s 1 S -R ' 1996 ma - O lastSun 2s 0 - -R W 1977 1980 - Ap Sun>=1 0 1 S -R W 1977 o - S lastSun 0 0 - -R W 1978 o - O 1 0 0 - -R W 1979 1995 - S lastSun 0 0 - -R W 1981 ma - Mar lastSun 0 1 S -R W 1996 ma - O lastSun 0 0 - -R M 1917 o - Jul 1 23 1 MST -R M 1917 o - D 28 0 0 MMT -R M 1918 o - May 31 22 2 MDST -R M 1918 o - S 16 1 1 MST -R M 1919 o - May 31 23 2 MDST -R M 1919 o - Jul 1 0u 1 MSD -R M 1919 o - Au 16 0 0 MSK -R M 1921 o - F 14 23 1 MSD -R M 1921 o - Mar 20 23 2 +05 -R M 1921 o - S 1 0 1 MSD -R M 1921 o - O 1 0 0 - -R M 1981 1984 - Ap 1 0 1 S -R M 1981 1983 - O 1 0 0 - -R M 1984 1995 - S lastSun 2s 0 - -R M 1985 2010 - Mar lastSun 2s 1 S -R M 1996 2010 - O lastSun 2s 0 - -Z WET 0 O WE%sT -Z CET 1 ' CE%sT -Z MET 1 ' ME%sT -Z EET 2 O EE%sT -R ( 1940 o - Jun 16 0 1 S -R ( 1942 o - N 2 3 0 - -R ( 1943 o - Mar 29 2 1 S -R ( 1943 o - Ap 10 3 0 - -R ( 1974 o - May 4 0 1 S -R ( 1974 o - O 2 0 0 - -R ( 1975 o - May 1 0 1 S -R ( 1975 o - O 2 0 0 - -R ( 1976 o - May 2 0 1 S -R ( 1976 o - O 3 0 0 - -R ( 1977 o - May 8 0 1 S -R ( 1977 o - O 2 0 0 - -R ( 1978 o - May 6 0 1 S -R ( 1978 o - O 1 0 0 - -R ( 1979 o - May 5 0 1 S -R ( 1979 o - S 30 0 0 - -R ( 1980 o - May 3 0 1 S -R ( 1980 o - O 4 0 0 - -R ( 1981 o - Ap 26 0 1 S -R ( 1981 o - S 27 0 0 - -R ( 1982 o - May 2 0 1 S -R ( 1982 o - O 3 0 0 - -R ( 1983 o - Ap 18 0 1 S -R ( 1983 o - O 1 0 0 - -R ( 1984 o - Ap 1 0 1 S +0 G GMT/IST 1968 O 27 +1 IE IST/GMT +R E 1977 1980 - Ap Su>=1 1u 1 S +R E 1977 o - S lastSu 1u 0 - +R E 1978 o - O 1 1u 0 - +R E 1979 1995 - S lastSu 1u 0 - +R E 1981 ma - Mar lastSu 1u 1 S +R E 1996 ma - O lastSu 1u 0 - +R W- 1977 1980 - Ap Su>=1 1s 1 S +R W- 1977 o - S lastSu 1s 0 - +R W- 1978 o - O 1 1s 0 - +R W- 1979 1995 - S lastSu 1s 0 - +R W- 1981 ma - Mar lastSu 1s 1 S +R W- 1996 ma - O lastSu 1s 0 - +R c 1916 o - Ap 30 23 1 S +R c 1916 o - O 1 1 0 - +R c 1917 1918 - Ap M>=15 2s 1 S +R c 1917 1918 - S M>=15 2s 0 - +R c 1940 o - Ap 1 2s 1 S +R c 1942 o - N 2 2s 0 - +R c 1943 o - Mar 29 2s 1 S +R c 1943 o - O 4 2s 0 - +R c 1944 1945 - Ap M>=1 2s 1 S +R c 1944 o - O 2 2s 0 - +R c 1945 o - S 16 2s 0 - +R c 1977 1980 - Ap Su>=1 2s 1 S +R c 1977 o - S lastSu 2s 0 - +R c 1978 o - O 1 2s 0 - +R c 1979 1995 - S lastSu 2s 0 - +R c 1981 ma - Mar lastSu 2s 1 S +R c 1996 ma - O lastSu 2s 0 - +R e 1977 1980 - Ap Su>=1 0 1 S +R e 1977 o - S lastSu 0 0 - +R e 1978 o - O 1 0 0 - +R e 1979 1995 - S lastSu 0 0 - +R e 1981 ma - Mar lastSu 0 1 S +R e 1996 ma - O lastSu 0 0 - +R R 1917 o - Jul 1 23 1 MST +R R 1917 o - D 28 0 0 MMT +R R 1918 o - May 31 22 2 MDST +R R 1918 o - S 16 1 1 MST +R R 1919 o - May 31 23 2 MDST +R R 1919 o - Jul 1 0u 1 MSD +R R 1919 o - Au 16 0 0 MSK +R R 1921 o - F 14 23 1 MSD +R R 1921 o - Mar 20 23 2 +05 +R R 1921 o - S 1 0 1 MSD +R R 1921 o - O 1 0 0 - +R R 1981 1984 - Ap 1 0 1 S +R R 1981 1983 - O 1 0 0 - +R R 1984 1995 - S lastSu 2s 0 - +R R 1985 2010 - Mar lastSu 2s 1 S +R R 1996 2010 - O lastSu 2s 0 - +Z WET 0 E WE%sT +Z CET 1 c CE%sT +Z MET 1 c ME%sT +Z EET 2 E EE%sT +R q 1940 o - Jun 16 0 1 S +R q 1942 o - N 2 3 0 - +R q 1943 o - Mar 29 2 1 S +R q 1943 o - Ap 10 3 0 - +R q 1974 o - May 4 0 1 S +R q 1974 o - O 2 0 0 - +R q 1975 o - May 1 0 1 S +R q 1975 o - O 2 0 0 - +R q 1976 o - May 2 0 1 S +R q 1976 o - O 3 0 0 - +R q 1977 o - May 8 0 1 S +R q 1977 o - O 2 0 0 - +R q 1978 o - May 6 0 1 S +R q 1978 o - O 1 0 0 - +R q 1979 o - May 5 0 1 S +R q 1979 o - S 30 0 0 - +R q 1980 o - May 3 0 1 S +R q 1980 o - O 4 0 0 - +R q 1981 o - Ap 26 0 1 S +R q 1981 o - S 27 0 0 - +R q 1982 o - May 2 0 1 S +R q 1982 o - O 3 0 0 - +R q 1983 o - Ap 18 0 1 S +R q 1983 o - O 1 0 0 - +R q 1984 o - Ap 1 0 1 S Z Europe/Tirane 1:19:20 - LMT 1914 1 - CET 1940 Jun 16 -1 ( CE%sT 1984 Jul -1 O CE%sT +1 q CE%sT 1984 Jul +1 E CE%sT Z Europe/Andorra 0:6:4 - LMT 1901 0 - WET 1946 S 30 1 - CET 1985 Mar 31 2 -1 O CE%sT -R ) 1920 o - Ap 5 2s 1 S -R ) 1920 o - S 13 2s 0 - -R ) 1946 o - Ap 14 2s 1 S -R ) 1946 1948 - O Sun>=1 2s 0 - -R ) 1947 o - Ap 6 2s 1 S -R ) 1948 o - Ap 18 2s 1 S -R ) 1980 o - Ap 6 0 1 S -R ) 1980 o - S 28 0 0 - +1 E CE%sT +R a 1920 o - Ap 5 2s 1 S +R a 1920 o - S 13 2s 0 - +R a 1946 o - Ap 14 2s 1 S +R a 1946 o - O 7 2s 0 - +R a 1947 1948 - O Su>=1 2s 0 - +R a 1947 o - Ap 6 2s 1 S +R a 1948 o - Ap 18 2s 1 S +R a 1980 o - Ap 6 0 1 S +R a 1980 o - S 28 0 0 - Z Europe/Vienna 1:5:21 - LMT 1893 Ap -1 ' CE%sT 1920 -1 ) CE%sT 1940 Ap 1 2s -1 ' CE%sT 1945 Ap 2 2s +1 c CE%sT 1920 +1 a CE%sT 1940 Ap 1 2s +1 c CE%sT 1945 Ap 2 2s 1 1 CEST 1945 Ap 12 2s 1 - CET 1946 -1 ) CE%sT 1981 -1 O CE%sT +1 a CE%sT 1981 +1 E CE%sT Z Europe/Minsk 1:50:16 - LMT 1880 1:50 - MMT 1924 May 2 2 - EET 1930 Jun 21 3 - MSK 1941 Jun 28 -1 ' CE%sT 1944 Jul 3 -3 M MSK/MSD 1990 +1 c CE%sT 1944 Jul 3 +3 R MSK/MSD 1990 3 - MSK 1991 Mar 31 2s -2 M EE%sT 2011 Mar 27 2s +2 R EE%sT 2011 Mar 27 2s 3 - +03 -R * 1918 o - Mar 9 0s 1 S -R * 1918 1919 - O Sat>=1 23s 0 - -R * 1919 o - Mar 1 23s 1 S -R * 1920 o - F 14 23s 1 S -R * 1920 o - O 23 23s 0 - -R * 1921 o - Mar 14 23s 1 S -R * 1921 o - O 25 23s 0 - -R * 1922 o - Mar 25 23s 1 S -R * 1922 1927 - O Sat>=1 23s 0 - -R * 1923 o - Ap 21 23s 1 S -R * 1924 o - Mar 29 23s 1 S -R * 1925 o - Ap 4 23s 1 S -R * 1926 o - Ap 17 23s 1 S -R * 1927 o - Ap 9 23s 1 S -R * 1928 o - Ap 14 23s 1 S -R * 1928 1938 - O Sun>=2 2s 0 - -R * 1929 o - Ap 21 2s 1 S -R * 1930 o - Ap 13 2s 1 S -R * 1931 o - Ap 19 2s 1 S -R * 1932 o - Ap 3 2s 1 S -R * 1933 o - Mar 26 2s 1 S -R * 1934 o - Ap 8 2s 1 S -R * 1935 o - Mar 31 2s 1 S -R * 1936 o - Ap 19 2s 1 S -R * 1937 o - Ap 4 2s 1 S -R * 1938 o - Mar 27 2s 1 S -R * 1939 o - Ap 16 2s 1 S -R * 1939 o - N 19 2s 0 - -R * 1940 o - F 25 2s 1 S -R * 1944 o - S 17 2s 0 - -R * 1945 o - Ap 2 2s 1 S -R * 1945 o - S 16 2s 0 - -R * 1946 o - May 19 2s 1 S -R * 1946 o - O 7 2s 0 - +R b 1918 o - Mar 9 0s 1 S +R b 1918 1919 - O Sa>=1 23s 0 - +R b 1919 o - Mar 1 23s 1 S +R b 1920 o - F 14 23s 1 S +R b 1920 o - O 23 23s 0 - +R b 1921 o - Mar 14 23s 1 S +R b 1921 o - O 25 23s 0 - +R b 1922 o - Mar 25 23s 1 S +R b 1922 1927 - O Sa>=1 23s 0 - +R b 1923 o - Ap 21 23s 1 S +R b 1924 o - Mar 29 23s 1 S +R b 1925 o - Ap 4 23s 1 S +R b 1926 o - Ap 17 23s 1 S +R b 1927 o - Ap 9 23s 1 S +R b 1928 o - Ap 14 23s 1 S +R b 1928 1938 - O Su>=2 2s 0 - +R b 1929 o - Ap 21 2s 1 S +R b 1930 o - Ap 13 2s 1 S +R b 1931 o - Ap 19 2s 1 S +R b 1932 o - Ap 3 2s 1 S +R b 1933 o - Mar 26 2s 1 S +R b 1934 o - Ap 8 2s 1 S +R b 1935 o - Mar 31 2s 1 S +R b 1936 o - Ap 19 2s 1 S +R b 1937 o - Ap 4 2s 1 S +R b 1938 o - Mar 27 2s 1 S +R b 1939 o - Ap 16 2s 1 S +R b 1939 o - N 19 2s 0 - +R b 1940 o - F 25 2s 1 S +R b 1944 o - S 17 2s 0 - +R b 1945 o - Ap 2 2s 1 S +R b 1945 o - S 16 2s 0 - +R b 1946 o - May 19 2s 1 S +R b 1946 o - O 7 2s 0 - Z Europe/Brussels 0:17:30 - LMT 1880 -0:17:30 - BMT 1892 May 1 12 +0:17:30 - BMT 1892 May 1 0:17:30 0 - WET 1914 N 8 1 - CET 1916 May -1 ' CE%sT 1918 N 11 11u -0 * WE%sT 1940 May 20 2s -1 ' CE%sT 1944 S 3 -1 * CE%sT 1977 -1 O CE%sT -R + 1979 o - Mar 31 23 1 S -R + 1979 o - O 1 1 0 - -R + 1980 1982 - Ap Sat>=1 23 1 S -R + 1980 o - S 29 1 0 - -R + 1981 o - S 27 2 0 - +1 c CE%sT 1918 N 11 11u +0 b WE%sT 1940 May 20 2s +1 c CE%sT 1944 S 3 +1 b CE%sT 1977 +1 E CE%sT +R BG 1979 o - Mar 31 23 1 S +R BG 1979 o - O 1 1 0 - +R BG 1980 1982 - Ap Sa>=1 23 1 S +R BG 1980 o - S 29 1 0 - +R BG 1981 o - S 27 2 0 - Z Europe/Sofia 1:33:16 - LMT 1880 1:56:56 - IMT 1894 N 30 2 - EET 1942 N 2 3 -1 ' CE%sT 1945 +1 c CE%sT 1945 1 - CET 1945 Ap 2 3 2 - EET 1979 Mar 31 23 -2 + EE%sT 1982 S 26 3 -2 ' EE%sT 1991 -2 W EE%sT 1997 -2 O EE%sT -R , 1945 o - Ap 8 2s 1 S -R , 1945 o - N 18 2s 0 - -R , 1946 o - May 6 2s 1 S -R , 1946 1949 - O Sun>=1 2s 0 - -R , 1947 o - Ap 20 2s 1 S -R , 1948 o - Ap 18 2s 1 S -R , 1949 o - Ap 9 2s 1 S +2 BG EE%sT 1982 S 26 3 +2 c EE%sT 1991 +2 e EE%sT 1997 +2 E EE%sT +R CZ 1945 o - Ap M>=1 2s 1 S +R CZ 1945 o - O 1 2s 0 - +R CZ 1946 o - May 6 2s 1 S +R CZ 1946 1949 - O Su>=1 2s 0 - +R CZ 1947 1948 - Ap Su>=15 2s 1 S +R CZ 1949 o - Ap 9 2s 1 S Z Europe/Prague 0:57:44 - LMT 1850 0:57:44 - PMT 1891 O -1 ' CE%sT 1944 S 17 2s -1 , CE%sT 1979 -1 O CE%sT -R . 1916 o - May 14 23 1 S -R . 1916 o - S 30 23 0 - -R . 1940 o - May 15 0 1 S -R . 1945 o - Ap 2 2s 1 S -R . 1945 o - Au 15 2s 0 - -R . 1946 o - May 1 2s 1 S -R . 1946 o - S 1 2s 0 - -R . 1947 o - May 4 2s 1 S -R . 1947 o - Au 10 2s 0 - -R . 1948 o - May 9 2s 1 S -R . 1948 o - Au 8 2s 0 - +1 c CE%sT 1945 May 9 +1 CZ CE%sT 1946 D 1 3 +1 -1 GMT 1947 F 23 2 +1 CZ CE%sT 1979 +1 E CE%sT +R D 1916 o - May 14 23 1 S +R D 1916 o - S 30 23 0 - +R D 1940 o - May 15 0 1 S +R D 1945 o - Ap 2 2s 1 S +R D 1945 o - Au 15 2s 0 - +R D 1946 o - May 1 2s 1 S +R D 1946 o - S 1 2s 0 - +R D 1947 o - May 4 2s 1 S +R D 1947 o - Au 10 2s 0 - +R D 1948 o - May 9 2s 1 S +R D 1948 o - Au 8 2s 0 - Z Europe/Copenhagen 0:50:20 - LMT 1890 0:50:20 - CMT 1894 -1 . CE%sT 1942 N 2 2s -1 ' CE%sT 1945 Ap 2 2 -1 . CE%sT 1980 -1 O CE%sT +1 D CE%sT 1942 N 2 2s +1 c CE%sT 1945 Ap 2 2 +1 D CE%sT 1980 +1 E CE%sT Z Atlantic/Faroe -0:27:4 - LMT 1908 Ja 11 0 - WET 1981 -0 O WE%sT -R / 1991 1992 - Mar lastSun 2 1 D -R / 1991 1992 - S lastSun 2 0 S -R / 1993 2006 - Ap Sun>=1 2 1 D -R / 1993 2006 - O lastSun 2 0 S -R / 2007 ma - Mar Sun>=8 2 1 D -R / 2007 ma - N Sun>=1 2 0 S +0 E WE%sT +R Th 1991 1992 - Mar lastSu 2 1 D +R Th 1991 1992 - S lastSu 2 0 S +R Th 1993 2006 - Ap Su>=1 2 1 D +R Th 1993 2006 - O lastSu 2 0 S +R Th 2007 ma - Mar Su>=8 2 1 D +R Th 2007 ma - N Su>=1 2 0 S Z America/Danmarkshavn -1:14:40 - LMT 1916 Jul 28 -3 - -03 1980 Ap 6 2 --3 O -03/-02 1996 +-3 E -03/-02 1996 0 - GMT Z America/Scoresbysund -1:27:52 - LMT 1916 Jul 28 -2 - -02 1980 Ap 6 2 --2 ' -02/-01 1981 Mar 29 --1 O -01/+00 +-2 c -02/-01 1981 Mar 29 +-1 E -01/+00 Z America/Godthab -3:26:56 - LMT 1916 Jul 28 -3 - -03 1980 Ap 6 2 --3 O -03/-02 +-3 E -03/-02 Z America/Thule -4:35:8 - LMT 1916 Jul 28 --4 / A%sT +-4 Th A%sT Z Europe/Tallinn 1:39 - LMT 1880 1:39 - TMT 1918 F -1 ' CE%sT 1919 Jul +1 c CE%sT 1919 Jul 1:39 - TMT 1921 May 2 - EET 1940 Au 6 3 - MSK 1941 S 15 -1 ' CE%sT 1944 S 22 -3 M MSK/MSD 1989 Mar 26 2s +1 c CE%sT 1944 S 22 +3 R MSK/MSD 1989 Mar 26 2s 2 1 EEST 1989 S 24 2s -2 ' EE%sT 1998 S 22 -2 O EE%sT 1999 O 31 4 +2 c EE%sT 1998 S 22 +2 E EE%sT 1999 O 31 4 2 - EET 2002 F 21 -2 O EE%sT -R : 1942 o - Ap 2 24 1 S -R : 1942 o - O 4 1 0 - -R : 1981 1982 - Mar lastSun 2 1 S -R : 1981 1982 - S lastSun 3 0 - +2 E EE%sT +R FI 1942 o - Ap 2 24 1 S +R FI 1942 o - O 4 1 0 - +R FI 1981 1982 - Mar lastSu 2 1 S +R FI 1981 1982 - S lastSu 3 0 - Z Europe/Helsinki 1:39:49 - LMT 1878 May 31 1:39:49 - HMT 1921 May -2 : EE%sT 1983 -2 O EE%sT -Li Europe/Helsinki Europe/Mariehamn -R ; 1916 o - Jun 14 23s 1 S -R ; 1916 1919 - O Sun>=1 23s 0 - -R ; 1917 o - Mar 24 23s 1 S -R ; 1918 o - Mar 9 23s 1 S -R ; 1919 o - Mar 1 23s 1 S -R ; 1920 o - F 14 23s 1 S -R ; 1920 o - O 23 23s 0 - -R ; 1921 o - Mar 14 23s 1 S -R ; 1921 o - O 25 23s 0 - -R ; 1922 o - Mar 25 23s 1 S -R ; 1922 1938 - O Sat>=1 23s 0 - -R ; 1923 o - May 26 23s 1 S -R ; 1924 o - Mar 29 23s 1 S -R ; 1925 o - Ap 4 23s 1 S -R ; 1926 o - Ap 17 23s 1 S -R ; 1927 o - Ap 9 23s 1 S -R ; 1928 o - Ap 14 23s 1 S -R ; 1929 o - Ap 20 23s 1 S -R ; 1930 o - Ap 12 23s 1 S -R ; 1931 o - Ap 18 23s 1 S -R ; 1932 o - Ap 2 23s 1 S -R ; 1933 o - Mar 25 23s 1 S -R ; 1934 o - Ap 7 23s 1 S -R ; 1935 o - Mar 30 23s 1 S -R ; 1936 o - Ap 18 23s 1 S -R ; 1937 o - Ap 3 23s 1 S -R ; 1938 o - Mar 26 23s 1 S -R ; 1939 o - Ap 15 23s 1 S -R ; 1939 o - N 18 23s 0 - -R ; 1940 o - F 25 2 1 S -R ; 1941 o - May 5 0 2 M -R ; 1941 o - O 6 0 1 S -R ; 1942 o - Mar 9 0 2 M -R ; 1942 o - N 2 3 1 S -R ; 1943 o - Mar 29 2 2 M -R ; 1943 o - O 4 3 1 S -R ; 1944 o - Ap 3 2 2 M -R ; 1944 o - O 8 1 1 S -R ; 1945 o - Ap 2 2 2 M -R ; 1945 o - S 16 3 0 - -R ; 1976 o - Mar 28 1 1 S -R ; 1976 o - S 26 1 0 - +2 FI EE%sT 1983 +2 E EE%sT +L Europe/Helsinki Europe/Mariehamn +R F 1916 o - Jun 14 23s 1 S +R F 1916 1919 - O Su>=1 23s 0 - +R F 1917 o - Mar 24 23s 1 S +R F 1918 o - Mar 9 23s 1 S +R F 1919 o - Mar 1 23s 1 S +R F 1920 o - F 14 23s 1 S +R F 1920 o - O 23 23s 0 - +R F 1921 o - Mar 14 23s 1 S +R F 1921 o - O 25 23s 0 - +R F 1922 o - Mar 25 23s 1 S +R F 1922 1938 - O Sa>=1 23s 0 - +R F 1923 o - May 26 23s 1 S +R F 1924 o - Mar 29 23s 1 S +R F 1925 o - Ap 4 23s 1 S +R F 1926 o - Ap 17 23s 1 S +R F 1927 o - Ap 9 23s 1 S +R F 1928 o - Ap 14 23s 1 S +R F 1929 o - Ap 20 23s 1 S +R F 1930 o - Ap 12 23s 1 S +R F 1931 o - Ap 18 23s 1 S +R F 1932 o - Ap 2 23s 1 S +R F 1933 o - Mar 25 23s 1 S +R F 1934 o - Ap 7 23s 1 S +R F 1935 o - Mar 30 23s 1 S +R F 1936 o - Ap 18 23s 1 S +R F 1937 o - Ap 3 23s 1 S +R F 1938 o - Mar 26 23s 1 S +R F 1939 o - Ap 15 23s 1 S +R F 1939 o - N 18 23s 0 - +R F 1940 o - F 25 2 1 S +R F 1941 o - May 5 0 2 M +R F 1941 o - O 6 0 1 S +R F 1942 o - Mar 9 0 2 M +R F 1942 o - N 2 3 1 S +R F 1943 o - Mar 29 2 2 M +R F 1943 o - O 4 3 1 S +R F 1944 o - Ap 3 2 2 M +R F 1944 o - O 8 1 1 S +R F 1945 o - Ap 2 2 2 M +R F 1945 o - S 16 3 0 - +R F 1976 o - Mar 28 1 1 S +R F 1976 o - S 26 1 0 - Z Europe/Paris 0:9:21 - LMT 1891 Mar 15 0:1 0:9:21 - PMT 1911 Mar 11 0:1 -0 ; WE%sT 1940 Jun 14 23 -1 ' CE%sT 1944 Au 25 -0 ; WE%sT 1945 S 16 3 -1 ; CE%sT 1977 -1 O CE%sT -R < 1946 o - Ap 14 2s 1 S -R < 1946 o - O 7 2s 0 - -R < 1947 1949 - O Sun>=1 2s 0 - -R < 1947 o - Ap 6 3s 1 S -R < 1947 o - May 11 2s 2 M -R < 1947 o - Jun 29 3 1 S -R < 1948 o - Ap 18 2s 1 S -R < 1949 o - Ap 10 2s 1 S -R = 1945 o - May 24 2 2 M -R = 1945 o - S 24 3 1 S -R = 1945 o - N 18 2s 0 - +0 F WE%sT 1940 Jun 14 23 +1 c CE%sT 1944 Au 25 +0 F WE%sT 1945 S 16 3 +1 F CE%sT 1977 +1 E CE%sT +R DE 1946 o - Ap 14 2s 1 S +R DE 1946 o - O 7 2s 0 - +R DE 1947 1949 - O Su>=1 2s 0 - +R DE 1947 o - Ap 6 3s 1 S +R DE 1947 o - May 11 2s 2 M +R DE 1947 o - Jun 29 3 1 S +R DE 1948 o - Ap 18 2s 1 S +R DE 1949 o - Ap 10 2s 1 S +R So 1945 o - May 24 2 2 M +R So 1945 o - S 24 3 1 S +R So 1945 o - N 18 2s 0 - Z Europe/Berlin 0:53:28 - LMT 1893 Ap -1 ' CE%sT 1945 May 24 2 -1 = CE%sT 1946 -1 < CE%sT 1980 -1 O CE%sT -Li Europe/Zurich Europe/Busingen +1 c CE%sT 1945 May 24 2 +1 So CE%sT 1946 +1 DE CE%sT 1980 +1 E CE%sT +L Europe/Zurich Europe/Busingen Z Europe/Gibraltar -0:21:24 - LMT 1880 Au 2 0s -0 % %s 1957 Ap 14 2 +0 G %s 1957 Ap 14 2 1 - CET 1982 -1 O CE%sT -R > 1932 o - Jul 7 0 1 S -R > 1932 o - S 1 0 0 - -R > 1941 o - Ap 7 0 1 S -R > 1942 o - N 2 3 0 - -R > 1943 o - Mar 30 0 1 S -R > 1943 o - O 4 0 0 - -R > 1952 o - Jul 1 0 1 S -R > 1952 o - N 2 0 0 - -R > 1975 o - Ap 12 0s 1 S -R > 1975 o - N 26 0s 0 - -R > 1976 o - Ap 11 2s 1 S -R > 1976 o - O 10 2s 0 - -R > 1977 1978 - Ap Sun>=1 2s 1 S -R > 1977 o - S 26 2s 0 - -R > 1978 o - S 24 4 0 - -R > 1979 o - Ap 1 9 1 S -R > 1979 o - S 29 2 0 - -R > 1980 o - Ap 1 0 1 S -R > 1980 o - S 28 0 0 - +1 E CE%sT +R g 1932 o - Jul 7 0 1 S +R g 1932 o - S 1 0 0 - +R g 1941 o - Ap 7 0 1 S +R g 1942 o - N 2 3 0 - +R g 1943 o - Mar 30 0 1 S +R g 1943 o - O 4 0 0 - +R g 1952 o - Jul 1 0 1 S +R g 1952 o - N 2 0 0 - +R g 1975 o - Ap 12 0s 1 S +R g 1975 o - N 26 0s 0 - +R g 1976 o - Ap 11 2s 1 S +R g 1976 o - O 10 2s 0 - +R g 1977 1978 - Ap Su>=1 2s 1 S +R g 1977 o - S 26 2s 0 - +R g 1978 o - S 24 4 0 - +R g 1979 o - Ap 1 9 1 S +R g 1979 o - S 29 2 0 - +R g 1980 o - Ap 1 0 1 S +R g 1980 o - S 28 0 0 - Z Europe/Athens 1:34:52 - LMT 1895 S 14 1:34:52 - AMT 1916 Jul 28 0:1 -2 > EE%sT 1941 Ap 30 -1 > CE%sT 1944 Ap 4 -2 > EE%sT 1981 -2 O EE%sT -R ? 1918 o - Ap 1 3 1 S -R ? 1918 o - S 16 3 0 - -R ? 1919 o - Ap 15 3 1 S -R ? 1919 o - N 24 3 0 - -R ? 1945 o - May 1 23 1 S -R ? 1945 o - N 1 0 0 - -R ? 1946 o - Mar 31 2s 1 S -R ? 1946 1949 - O Sun>=1 2s 0 - -R ? 1947 1949 - Ap Sun>=4 2s 1 S -R ? 1950 o - Ap 17 2s 1 S -R ? 1950 o - O 23 2s 0 - -R ? 1954 1955 - May 23 0 1 S -R ? 1954 1955 - O 3 0 0 - -R ? 1956 o - Jun Sun>=1 0 1 S -R ? 1956 o - S lastSun 0 0 - -R ? 1957 o - Jun Sun>=1 1 1 S -R ? 1957 o - S lastSun 3 0 - -R ? 1980 o - Ap 6 1 1 S +2 g EE%sT 1941 Ap 30 +1 g CE%sT 1944 Ap 4 +2 g EE%sT 1981 +2 E EE%sT +R h 1918 o - Ap 1 3 1 S +R h 1918 o - S 16 3 0 - +R h 1919 o - Ap 15 3 1 S +R h 1919 o - N 24 3 0 - +R h 1945 o - May 1 23 1 S +R h 1945 o - N 1 0 0 - +R h 1946 o - Mar 31 2s 1 S +R h 1946 1949 - O Su>=1 2s 0 - +R h 1947 1949 - Ap Su>=4 2s 1 S +R h 1950 o - Ap 17 2s 1 S +R h 1950 o - O 23 2s 0 - +R h 1954 1955 - May 23 0 1 S +R h 1954 1955 - O 3 0 0 - +R h 1956 o - Jun Su>=1 0 1 S +R h 1956 o - S lastSu 0 0 - +R h 1957 o - Jun Su>=1 1 1 S +R h 1957 o - S lastSu 3 0 - +R h 1980 o - Ap 6 1 1 S Z Europe/Budapest 1:16:20 - LMT 1890 O -1 ' CE%sT 1918 -1 ? CE%sT 1941 Ap 8 -1 ' CE%sT 1945 -1 ? CE%sT 1980 S 28 2s -1 O CE%sT -R @ 1917 1919 - F 19 23 1 S -R @ 1917 o - O 21 1 0 - -R @ 1918 1919 - N 16 1 0 - -R @ 1921 o - Mar 19 23 1 S -R @ 1921 o - Jun 23 1 0 - -R @ 1939 o - Ap 29 23 1 S -R @ 1939 o - O 29 2 0 - -R @ 1940 o - F 25 2 1 S -R @ 1940 1941 - N Sun>=2 1s 0 - -R @ 1941 1942 - Mar Sun>=2 1s 1 S -R @ 1943 1946 - Mar Sun>=1 1s 1 S -R @ 1942 1948 - O Sun>=22 1s 0 - -R @ 1947 1967 - Ap Sun>=1 1s 1 S -R @ 1949 o - O 30 1s 0 - -R @ 1950 1966 - O Sun>=22 1s 0 - -R @ 1967 o - O 29 1s 0 - +1 c CE%sT 1918 +1 h CE%sT 1941 Ap 8 +1 c CE%sT 1945 +1 h CE%sT 1980 S 28 2s +1 E CE%sT +R w 1917 1919 - F 19 23 1 - +R w 1917 o - O 21 1 0 - +R w 1918 1919 - N 16 1 0 - +R w 1921 o - Mar 19 23 1 - +R w 1921 o - Jun 23 1 0 - +R w 1939 o - Ap 29 23 1 - +R w 1939 o - O 29 2 0 - +R w 1940 o - F 25 2 1 - +R w 1940 1941 - N Su>=2 1s 0 - +R w 1941 1942 - Mar Su>=2 1s 1 - +R w 1943 1946 - Mar Su>=1 1s 1 - +R w 1942 1948 - O Su>=22 1s 0 - +R w 1947 1967 - Ap Su>=1 1s 1 - +R w 1949 o - O 30 1s 0 - +R w 1950 1966 - O Su>=22 1s 0 - +R w 1967 o - O 29 1s 0 - Z Atlantic/Reykjavik -1:28 - LMT 1908 --1 @ -01/+00 1968 Ap 7 1s +-1 w -01/+00 1968 Ap 7 1s 0 - GMT -R [ 1916 o - Jun 3 24 1 S -R [ 1916 1917 - S 30 24 0 - -R [ 1917 o - Mar 31 24 1 S -R [ 1918 o - Mar 9 24 1 S -R [ 1918 o - O 6 24 0 - -R [ 1919 o - Mar 1 24 1 S -R [ 1919 o - O 4 24 0 - -R [ 1920 o - Mar 20 24 1 S -R [ 1920 o - S 18 24 0 - -R [ 1940 o - Jun 14 24 1 S -R [ 1942 o - N 2 2s 0 - -R [ 1943 o - Mar 29 2s 1 S -R [ 1943 o - O 4 2s 0 - -R [ 1944 o - Ap 2 2s 1 S -R [ 1944 o - S 17 2s 0 - -R [ 1945 o - Ap 2 2 1 S -R [ 1945 o - S 15 1 0 - -R [ 1946 o - Mar 17 2s 1 S -R [ 1946 o - O 6 2s 0 - -R [ 1947 o - Mar 16 0s 1 S -R [ 1947 o - O 5 0s 0 - -R [ 1948 o - F 29 2s 1 S -R [ 1948 o - O 3 2s 0 - -R [ 1966 1968 - May Sun>=22 0s 1 S -R [ 1966 o - S 24 24 0 - -R [ 1967 1969 - S Sun>=22 0s 0 - -R [ 1969 o - Jun 1 0s 1 S -R [ 1970 o - May 31 0s 1 S -R [ 1970 o - S lastSun 0s 0 - -R [ 1971 1972 - May Sun>=22 0s 1 S -R [ 1971 o - S lastSun 0s 0 - -R [ 1972 o - O 1 0s 0 - -R [ 1973 o - Jun 3 0s 1 S -R [ 1973 1974 - S lastSun 0s 0 - -R [ 1974 o - May 26 0s 1 S -R [ 1975 o - Jun 1 0s 1 S -R [ 1975 1977 - S lastSun 0s 0 - -R [ 1976 o - May 30 0s 1 S -R [ 1977 1979 - May Sun>=22 0s 1 S -R [ 1978 o - O 1 0s 0 - -R [ 1979 o - S 30 0s 0 - -Z Europe/Rome 0:49:56 - LMT 1866 S 22 +R I 1916 o - Jun 3 24 1 S +R I 1916 1917 - S 30 24 0 - +R I 1917 o - Mar 31 24 1 S +R I 1918 o - Mar 9 24 1 S +R I 1918 o - O 6 24 0 - +R I 1919 o - Mar 1 24 1 S +R I 1919 o - O 4 24 0 - +R I 1920 o - Mar 20 24 1 S +R I 1920 o - S 18 24 0 - +R I 1940 o - Jun 14 24 1 S +R I 1942 o - N 2 2s 0 - +R I 1943 o - Mar 29 2s 1 S +R I 1943 o - O 4 2s 0 - +R I 1944 o - Ap 2 2s 1 S +R I 1944 o - S 17 2s 0 - +R I 1945 o - Ap 2 2 1 S +R I 1945 o - S 15 1 0 - +R I 1946 o - Mar 17 2s 1 S +R I 1946 o - O 6 2s 0 - +R I 1947 o - Mar 16 0s 1 S +R I 1947 o - O 5 0s 0 - +R I 1948 o - F 29 2s 1 S +R I 1948 o - O 3 2s 0 - +R I 1966 1968 - May Su>=22 0s 1 S +R I 1966 o - S 24 24 0 - +R I 1967 1969 - S Su>=22 0s 0 - +R I 1969 o - Jun 1 0s 1 S +R I 1970 o - May 31 0s 1 S +R I 1970 o - S lastSu 0s 0 - +R I 1971 1972 - May Su>=22 0s 1 S +R I 1971 o - S lastSu 0s 0 - +R I 1972 o - O 1 0s 0 - +R I 1973 o - Jun 3 0s 1 S +R I 1973 1974 - S lastSu 0s 0 - +R I 1974 o - May 26 0s 1 S +R I 1975 o - Jun 1 0s 1 S +R I 1975 1977 - S lastSu 0s 0 - +R I 1976 o - May 30 0s 1 S +R I 1977 1979 - May Su>=22 0s 1 S +R I 1978 o - O 1 0s 0 - +R I 1979 o - S 30 0s 0 - +Z Europe/Rome 0:49:56 - LMT 1866 D 12 0:49:56 - RMT 1893 O 31 23:49:56 -1 [ CE%sT 1943 S 10 -1 ' CE%sT 1944 Jun 4 -1 [ CE%sT 1980 -1 O CE%sT -Li Europe/Rome Europe/Vatican -Li Europe/Rome Europe/San_Marino -R \ 1989 1996 - Mar lastSun 2s 1 S -R \ 1989 1996 - S lastSun 2s 0 - +1 I CE%sT 1943 S 10 +1 c CE%sT 1944 Jun 4 +1 I CE%sT 1980 +1 E CE%sT +L Europe/Rome Europe/Vatican +L Europe/Rome Europe/San_Marino +R LV 1989 1996 - Mar lastSu 2s 1 S +R LV 1989 1996 - S lastSu 2s 0 - Z Europe/Riga 1:36:34 - LMT 1880 1:36:34 - RMT 1918 Ap 15 2 1:36:34 1 LST 1918 S 16 3 @@ -1877,14 +2145,14 @@ Z Europe/Riga 1:36:34 - LMT 1880 1:36:34 - RMT 1926 May 11 2 - EET 1940 Au 5 3 - MSK 1941 Jul -1 ' CE%sT 1944 O 13 -3 M MSK/MSD 1989 Mar lastSun 2s -2 1 EEST 1989 S lastSun 2s -2 \ EE%sT 1997 Ja 21 -2 O EE%sT 2000 F 29 +1 c CE%sT 1944 O 13 +3 R MSK/MSD 1989 Mar lastSu 2s +2 1 EEST 1989 S lastSu 2s +2 LV EE%sT 1997 Ja 21 +2 E EE%sT 2000 F 29 2 - EET 2001 Ja 2 -2 O EE%sT -Li Europe/Zurich Europe/Vaduz +2 E EE%sT +L Europe/Zurich Europe/Vaduz Z Europe/Vilnius 1:41:16 - LMT 1880 1:24 - WMT 1917 1:35:36 - KMT 1919 O 10 @@ -1892,1316 +2160,1303 @@ Z Europe/Vilnius 1:41:16 - LMT 1880 2 - EET 1920 O 9 1 - CET 1940 Au 3 3 - MSK 1941 Jun 24 -1 ' CE%sT 1944 Au -3 M MSK/MSD 1989 Mar 26 2s -2 M EE%sT 1991 S 29 2s -2 ' EE%sT 1998 +1 c CE%sT 1944 Au +3 R MSK/MSD 1989 Mar 26 2s +2 R EE%sT 1991 S 29 2s +2 c EE%sT 1998 2 - EET 1998 Mar 29 1u -1 O CE%sT 1999 O 31 1u +1 E CE%sT 1999 O 31 1u 2 - EET 2003 -2 O EE%sT -R ] 1916 o - May 14 23 1 S -R ] 1916 o - O 1 1 0 - -R ] 1917 o - Ap 28 23 1 S -R ] 1917 o - S 17 1 0 - -R ] 1918 o - Ap M>=15 2s 1 S -R ] 1918 o - S M>=15 2s 0 - -R ] 1919 o - Mar 1 23 1 S -R ] 1919 o - O 5 3 0 - -R ] 1920 o - F 14 23 1 S -R ] 1920 o - O 24 2 0 - -R ] 1921 o - Mar 14 23 1 S -R ] 1921 o - O 26 2 0 - -R ] 1922 o - Mar 25 23 1 S -R ] 1922 o - O Sun>=2 1 0 - -R ] 1923 o - Ap 21 23 1 S -R ] 1923 o - O Sun>=2 2 0 - -R ] 1924 o - Mar 29 23 1 S -R ] 1924 1928 - O Sun>=2 1 0 - -R ] 1925 o - Ap 5 23 1 S -R ] 1926 o - Ap 17 23 1 S -R ] 1927 o - Ap 9 23 1 S -R ] 1928 o - Ap 14 23 1 S -R ] 1929 o - Ap 20 23 1 S +2 E EE%sT +R LX 1916 o - May 14 23 1 S +R LX 1916 o - O 1 1 0 - +R LX 1917 o - Ap 28 23 1 S +R LX 1917 o - S 17 1 0 - +R LX 1918 o - Ap M>=15 2s 1 S +R LX 1918 o - S M>=15 2s 0 - +R LX 1919 o - Mar 1 23 1 S +R LX 1919 o - O 5 3 0 - +R LX 1920 o - F 14 23 1 S +R LX 1920 o - O 24 2 0 - +R LX 1921 o - Mar 14 23 1 S +R LX 1921 o - O 26 2 0 - +R LX 1922 o - Mar 25 23 1 S +R LX 1922 o - O Su>=2 1 0 - +R LX 1923 o - Ap 21 23 1 S +R LX 1923 o - O Su>=2 2 0 - +R LX 1924 o - Mar 29 23 1 S +R LX 1924 1928 - O Su>=2 1 0 - +R LX 1925 o - Ap 5 23 1 S +R LX 1926 o - Ap 17 23 1 S +R LX 1927 o - Ap 9 23 1 S +R LX 1928 o - Ap 14 23 1 S +R LX 1929 o - Ap 20 23 1 S Z Europe/Luxembourg 0:24:36 - LMT 1904 Jun -1 ] CE%sT 1918 N 25 -0 ] WE%sT 1929 O 6 2s -0 * WE%sT 1940 May 14 3 -1 ' WE%sT 1944 S 18 3 -1 * CE%sT 1977 -1 O CE%sT -R ^ 1973 o - Mar 31 0s 1 S -R ^ 1973 o - S 29 0s 0 - -R ^ 1974 o - Ap 21 0s 1 S -R ^ 1974 o - S 16 0s 0 - -R ^ 1975 1979 - Ap Sun>=15 2 1 S -R ^ 1975 1980 - S Sun>=15 2 0 - -R ^ 1980 o - Mar 31 2 1 S +1 LX CE%sT 1918 N 25 +0 LX WE%sT 1929 O 6 2s +0 b WE%sT 1940 May 14 3 +1 c WE%sT 1944 S 18 3 +1 b CE%sT 1977 +1 E CE%sT +R MT 1973 o - Mar 31 0s 1 S +R MT 1973 o - S 29 0s 0 - +R MT 1974 o - Ap 21 0s 1 S +R MT 1974 o - S 16 0s 0 - +R MT 1975 1979 - Ap Su>=15 2 1 S +R MT 1975 1980 - S Su>=15 2 0 - +R MT 1980 o - Mar 31 2 1 S Z Europe/Malta 0:58:4 - LMT 1893 N 2 0s -1 [ CE%sT 1973 Mar 31 -1 ^ CE%sT 1981 -1 O CE%sT -R _ 1997 ma - Mar lastSun 2 1 S -R _ 1997 ma - O lastSun 3 0 - +1 I CE%sT 1973 Mar 31 +1 MT CE%sT 1981 +1 E CE%sT +R MD 1997 ma - Mar lastSu 2 1 S +R MD 1997 ma - O lastSu 3 0 - Z Europe/Chisinau 1:55:20 - LMT 1880 1:55 - CMT 1918 F 15 1:44:24 - BMT 1931 Jul 24 -2 ` EE%sT 1940 Au 15 +2 z EE%sT 1940 Au 15 2 1 EEST 1941 Jul 17 -1 ' CE%sT 1944 Au 24 -3 M MSK/MSD 1990 May 6 2 -2 M EE%sT 1992 -2 W EE%sT 1997 -2 _ EE%sT +1 c CE%sT 1944 Au 24 +3 R MSK/MSD 1990 May 6 2 +2 R EE%sT 1992 +2 e EE%sT 1997 +2 MD EE%sT Z Europe/Monaco 0:29:32 - LMT 1891 Mar 15 0:9:21 - PMT 1911 Mar 11 -0 ; WE%sT 1945 S 16 3 -1 ; CE%sT 1977 -1 O CE%sT -R { 1916 o - May 1 0 1 NST -R { 1916 o - O 1 0 0 AMT -R { 1917 o - Ap 16 2s 1 NST -R { 1917 o - S 17 2s 0 AMT -R { 1918 1921 - Ap M>=1 2s 1 NST -R { 1918 1921 - S lastM 2s 0 AMT -R { 1922 o - Mar lastSun 2s 1 NST -R { 1922 1936 - O Sun>=2 2s 0 AMT -R { 1923 o - Jun F>=1 2s 1 NST -R { 1924 o - Mar lastSun 2s 1 NST -R { 1925 o - Jun F>=1 2s 1 NST -R { 1926 1931 - May 15 2s 1 NST -R { 1932 o - May 22 2s 1 NST -R { 1933 1936 - May 15 2s 1 NST -R { 1937 o - May 22 2s 1 NST -R { 1937 o - Jul 1 0 1 S -R { 1937 1939 - O Sun>=2 2s 0 - -R { 1938 1939 - May 15 2s 1 S -R { 1945 o - Ap 2 2s 1 S -R { 1945 o - S 16 2s 0 - +0 F WE%sT 1945 S 16 3 +1 F CE%sT 1977 +1 E CE%sT +R N 1916 o - May 1 0 1 NST +R N 1916 o - O 1 0 0 AMT +R N 1917 o - Ap 16 2s 1 NST +R N 1917 o - S 17 2s 0 AMT +R N 1918 1921 - Ap M>=1 2s 1 NST +R N 1918 1921 - S lastM 2s 0 AMT +R N 1922 o - Mar lastSu 2s 1 NST +R N 1922 1936 - O Su>=2 2s 0 AMT +R N 1923 o - Jun F>=1 2s 1 NST +R N 1924 o - Mar lastSu 2s 1 NST +R N 1925 o - Jun F>=1 2s 1 NST +R N 1926 1931 - May 15 2s 1 NST +R N 1932 o - May 22 2s 1 NST +R N 1933 1936 - May 15 2s 1 NST +R N 1937 o - May 22 2s 1 NST +R N 1937 o - Jul 1 0 1 S +R N 1937 1939 - O Su>=2 2s 0 - +R N 1938 1939 - May 15 2s 1 S +R N 1945 o - Ap 2 2s 1 S +R N 1945 o - S 16 2s 0 - Z Europe/Amsterdam 0:19:32 - LMT 1835 -0:19:32 { %s 1937 Jul -0:20 { +0020/+0120 1940 May 16 -1 ' CE%sT 1945 Ap 2 2 -1 { CE%sT 1977 -1 O CE%sT -R | 1916 o - May 22 1 1 S -R | 1916 o - S 30 0 0 - -R | 1945 o - Ap 2 2s 1 S -R | 1945 o - O 1 2s 0 - -R | 1959 1964 - Mar Sun>=15 2s 1 S -R | 1959 1965 - S Sun>=15 2s 0 - -R | 1965 o - Ap 25 2s 1 S +0:19:32 N %s 1937 Jul +0:20 N +0020/+0120 1940 May 16 +1 c CE%sT 1945 Ap 2 2 +1 N CE%sT 1977 +1 E CE%sT +R NO 1916 o - May 22 1 1 S +R NO 1916 o - S 30 0 0 - +R NO 1945 o - Ap 2 2s 1 S +R NO 1945 o - O 1 2s 0 - +R NO 1959 1964 - Mar Su>=15 2s 1 S +R NO 1959 1965 - S Su>=15 2s 0 - +R NO 1965 o - Ap 25 2s 1 S Z Europe/Oslo 0:43 - LMT 1895 -1 | CE%sT 1940 Au 10 23 -1 ' CE%sT 1945 Ap 2 2 -1 | CE%sT 1980 -1 O CE%sT -Li Europe/Oslo Arctic/Longyearbyen -R } 1918 1919 - S 16 2s 0 - -R } 1919 o - Ap 15 2s 1 S -R } 1944 o - Ap 3 2s 1 S -R } 1944 o - O 4 2 0 - -R } 1945 o - Ap 29 0 1 S -R } 1945 o - N 1 0 0 - -R } 1946 o - Ap 14 0s 1 S -R } 1946 o - O 7 2s 0 - -R } 1947 o - May 4 2s 1 S -R } 1947 1949 - O Sun>=1 2s 0 - -R } 1948 o - Ap 18 2s 1 S -R } 1949 o - Ap 10 2s 1 S -R } 1957 o - Jun 2 1s 1 S -R } 1957 1958 - S lastSun 1s 0 - -R } 1958 o - Mar 30 1s 1 S -R } 1959 o - May 31 1s 1 S -R } 1959 1961 - O Sun>=1 1s 0 - -R } 1960 o - Ap 3 1s 1 S -R } 1961 1964 - May lastSun 1s 1 S -R } 1962 1964 - S lastSun 1s 0 - +1 NO CE%sT 1940 Au 10 23 +1 c CE%sT 1945 Ap 2 2 +1 NO CE%sT 1980 +1 E CE%sT +L Europe/Oslo Arctic/Longyearbyen +R O 1918 1919 - S 16 2s 0 - +R O 1919 o - Ap 15 2s 1 S +R O 1944 o - Ap 3 2s 1 S +R O 1944 o - O 4 2 0 - +R O 1945 o - Ap 29 0 1 S +R O 1945 o - N 1 0 0 - +R O 1946 o - Ap 14 0s 1 S +R O 1946 o - O 7 2s 0 - +R O 1947 o - May 4 2s 1 S +R O 1947 1949 - O Su>=1 2s 0 - +R O 1948 o - Ap 18 2s 1 S +R O 1949 o - Ap 10 2s 1 S +R O 1957 o - Jun 2 1s 1 S +R O 1957 1958 - S lastSu 1s 0 - +R O 1958 o - Mar 30 1s 1 S +R O 1959 o - May 31 1s 1 S +R O 1959 1961 - O Su>=1 1s 0 - +R O 1960 o - Ap 3 1s 1 S +R O 1961 1964 - May lastSu 1s 1 S +R O 1962 1964 - S lastSu 1s 0 - Z Europe/Warsaw 1:24 - LMT 1880 1:24 - WMT 1915 Au 5 -1 ' CE%sT 1918 S 16 3 -2 } EE%sT 1922 Jun -1 } CE%sT 1940 Jun 23 2 -1 ' CE%sT 1944 O -1 } CE%sT 1977 -1 & CE%sT 1988 -1 O CE%sT -R ~ 1916 o - Jun 17 23 1 S -R ~ 1916 o - N 1 1 0 - -R ~ 1917 o - F 28 23s 1 S -R ~ 1917 1921 - O 14 23s 0 - -R ~ 1918 o - Mar 1 23s 1 S -R ~ 1919 o - F 28 23s 1 S -R ~ 1920 o - F 29 23s 1 S -R ~ 1921 o - F 28 23s 1 S -R ~ 1924 o - Ap 16 23s 1 S -R ~ 1924 o - O 14 23s 0 - -R ~ 1926 o - Ap 17 23s 1 S -R ~ 1926 1929 - O Sat>=1 23s 0 - -R ~ 1927 o - Ap 9 23s 1 S -R ~ 1928 o - Ap 14 23s 1 S -R ~ 1929 o - Ap 20 23s 1 S -R ~ 1931 o - Ap 18 23s 1 S -R ~ 1931 1932 - O Sat>=1 23s 0 - -R ~ 1932 o - Ap 2 23s 1 S -R ~ 1934 o - Ap 7 23s 1 S -R ~ 1934 1938 - O Sat>=1 23s 0 - -R ~ 1935 o - Mar 30 23s 1 S -R ~ 1936 o - Ap 18 23s 1 S -R ~ 1937 o - Ap 3 23s 1 S -R ~ 1938 o - Mar 26 23s 1 S -R ~ 1939 o - Ap 15 23s 1 S -R ~ 1939 o - N 18 23s 0 - -R ~ 1940 o - F 24 23s 1 S -R ~ 1940 1941 - O 5 23s 0 - -R ~ 1941 o - Ap 5 23s 1 S -R ~ 1942 1945 - Mar Sat>=8 23s 1 S -R ~ 1942 o - Ap 25 22s 2 M -R ~ 1942 o - Au 15 22s 1 S -R ~ 1942 1945 - O Sat>=24 23s 0 - -R ~ 1943 o - Ap 17 22s 2 M -R ~ 1943 1945 - Au Sat>=25 22s 1 S -R ~ 1944 1945 - Ap Sat>=21 22s 2 M -R ~ 1946 o - Ap Sat>=1 23s 1 S -R ~ 1946 o - O Sat>=1 23s 0 - -R ~ 1947 1949 - Ap Sun>=1 2s 1 S -R ~ 1947 1949 - O Sun>=1 2s 0 - -R ~ 1951 1965 - Ap Sun>=1 2s 1 S -R ~ 1951 1965 - O Sun>=1 2s 0 - -R ~ 1977 o - Mar 27 0s 1 S -R ~ 1977 o - S 25 0s 0 - -R ~ 1978 1979 - Ap Sun>=1 0s 1 S -R ~ 1978 o - O 1 0s 0 - -R ~ 1979 1982 - S lastSun 1s 0 - -R ~ 1980 o - Mar lastSun 0s 1 S -R ~ 1981 1982 - Mar lastSun 1s 1 S -R ~ 1983 o - Mar lastSun 2s 1 S +1 c CE%sT 1918 S 16 3 +2 O EE%sT 1922 Jun +1 O CE%sT 1940 Jun 23 2 +1 c CE%sT 1944 O +1 O CE%sT 1977 +1 W- CE%sT 1988 +1 E CE%sT +R p 1916 o - Jun 17 23 1 S +R p 1916 o - N 1 1 0 - +R p 1917 o - F 28 23s 1 S +R p 1917 1921 - O 14 23s 0 - +R p 1918 o - Mar 1 23s 1 S +R p 1919 o - F 28 23s 1 S +R p 1920 o - F 29 23s 1 S +R p 1921 o - F 28 23s 1 S +R p 1924 o - Ap 16 23s 1 S +R p 1924 o - O 14 23s 0 - +R p 1926 o - Ap 17 23s 1 S +R p 1926 1929 - O Sa>=1 23s 0 - +R p 1927 o - Ap 9 23s 1 S +R p 1928 o - Ap 14 23s 1 S +R p 1929 o - Ap 20 23s 1 S +R p 1931 o - Ap 18 23s 1 S +R p 1931 1932 - O Sa>=1 23s 0 - +R p 1932 o - Ap 2 23s 1 S +R p 1934 o - Ap 7 23s 1 S +R p 1934 1938 - O Sa>=1 23s 0 - +R p 1935 o - Mar 30 23s 1 S +R p 1936 o - Ap 18 23s 1 S +R p 1937 o - Ap 3 23s 1 S +R p 1938 o - Mar 26 23s 1 S +R p 1939 o - Ap 15 23s 1 S +R p 1939 o - N 18 23s 0 - +R p 1940 o - F 24 23s 1 S +R p 1940 1941 - O 5 23s 0 - +R p 1941 o - Ap 5 23s 1 S +R p 1942 1945 - Mar Sa>=8 23s 1 S +R p 1942 o - Ap 25 22s 2 M +R p 1942 o - Au 15 22s 1 S +R p 1942 1945 - O Sa>=24 23s 0 - +R p 1943 o - Ap 17 22s 2 M +R p 1943 1945 - Au Sa>=25 22s 1 S +R p 1944 1945 - Ap Sa>=21 22s 2 M +R p 1946 o - Ap Sa>=1 23s 1 S +R p 1946 o - O Sa>=1 23s 0 - +R p 1947 1949 - Ap Su>=1 2s 1 S +R p 1947 1949 - O Su>=1 2s 0 - +R p 1951 1965 - Ap Su>=1 2s 1 S +R p 1951 1965 - O Su>=1 2s 0 - +R p 1977 o - Mar 27 0s 1 S +R p 1977 o - S 25 0s 0 - +R p 1978 1979 - Ap Su>=1 0s 1 S +R p 1978 o - O 1 0s 0 - +R p 1979 1982 - S lastSu 1s 0 - +R p 1980 o - Mar lastSu 0s 1 S +R p 1981 1982 - Mar lastSu 1s 1 S +R p 1983 o - Mar lastSu 2s 1 S Z Europe/Lisbon -0:36:45 - LMT 1884 --0:36:45 - LMT 1912 -0 ~ WE%sT 1966 Ap 3 2 +-0:36:45 - LMT 1912 Ja 1 0u +0 p WE%sT 1966 Ap 3 2 1 - CET 1976 S 26 1 -0 ~ WE%sT 1983 S 25 1s -0 & WE%sT 1992 S 27 1s -1 O CE%sT 1996 Mar 31 1u -0 O WE%sT +0 p WE%sT 1983 S 25 1s +0 W- WE%sT 1992 S 27 1s +1 E CE%sT 1996 Mar 31 1u +0 E WE%sT Z Atlantic/Azores -1:42:40 - LMT 1884 --1:54:32 - HMT 1912 --2 ~ -02/-01 1942 Ap 25 22s --2 ~ +00 1942 Au 15 22s --2 ~ -02/-01 1943 Ap 17 22s --2 ~ +00 1943 Au 28 22s --2 ~ -02/-01 1944 Ap 22 22s --2 ~ +00 1944 Au 26 22s --2 ~ -02/-01 1945 Ap 21 22s --2 ~ +00 1945 Au 25 22s --2 ~ -02/-01 1966 Ap 3 2 --1 ~ -01/+00 1983 S 25 1s --1 & -01/+00 1992 S 27 1s -0 O WE%sT 1993 Mar 28 1u --1 O -01/+00 +-1:54:32 - HMT 1912 Ja 1 2u +-2 p -02/-01 1942 Ap 25 22s +-2 p +00 1942 Au 15 22s +-2 p -02/-01 1943 Ap 17 22s +-2 p +00 1943 Au 28 22s +-2 p -02/-01 1944 Ap 22 22s +-2 p +00 1944 Au 26 22s +-2 p -02/-01 1945 Ap 21 22s +-2 p +00 1945 Au 25 22s +-2 p -02/-01 1966 Ap 3 2 +-1 p -01/+00 1983 S 25 1s +-1 W- -01/+00 1992 S 27 1s +0 E WE%sT 1993 Mar 28 1u +-1 E -01/+00 Z Atlantic/Madeira -1:7:36 - LMT 1884 --1:7:36 - FMT 1912 --1 ~ -01/+00 1942 Ap 25 22s --1 ~ +01 1942 Au 15 22s --1 ~ -01/+00 1943 Ap 17 22s --1 ~ +01 1943 Au 28 22s --1 ~ -01/+00 1944 Ap 22 22s --1 ~ +01 1944 Au 26 22s --1 ~ -01/+00 1945 Ap 21 22s --1 ~ +01 1945 Au 25 22s --1 ~ -01/+00 1966 Ap 3 2 -0 ~ WE%sT 1983 S 25 1s -0 O WE%sT -R ` 1932 o - May 21 0s 1 S -R ` 1932 1939 - O Sun>=1 0s 0 - -R ` 1933 1939 - Ap Sun>=2 0s 1 S -R ` 1979 o - May 27 0 1 S -R ` 1979 o - S lastSun 0 0 - -R ` 1980 o - Ap 5 23 1 S -R ` 1980 o - S lastSun 1 0 - -R ` 1991 1993 - Mar lastSun 0s 1 S -R ` 1991 1993 - S lastSun 0s 0 - +-1:7:36 - FMT 1912 Ja 1 1u +-1 p -01/+00 1942 Ap 25 22s +-1 p +01 1942 Au 15 22s +-1 p -01/+00 1943 Ap 17 22s +-1 p +01 1943 Au 28 22s +-1 p -01/+00 1944 Ap 22 22s +-1 p +01 1944 Au 26 22s +-1 p -01/+00 1945 Ap 21 22s +-1 p +01 1945 Au 25 22s +-1 p -01/+00 1966 Ap 3 2 +0 p WE%sT 1983 S 25 1s +0 E WE%sT +R z 1932 o - May 21 0s 1 S +R z 1932 1939 - O Su>=1 0s 0 - +R z 1933 1939 - Ap Su>=2 0s 1 S +R z 1979 o - May 27 0 1 S +R z 1979 o - S lastSu 0 0 - +R z 1980 o - Ap 5 23 1 S +R z 1980 o - S lastSu 1 0 - +R z 1991 1993 - Mar lastSu 0s 1 S +R z 1991 1993 - S lastSu 0s 0 - Z Europe/Bucharest 1:44:24 - LMT 1891 O 1:44:24 - BMT 1931 Jul 24 -2 ` EE%sT 1981 Mar 29 2s -2 ' EE%sT 1991 -2 ` EE%sT 1994 -2 W EE%sT 1997 -2 O EE%sT +2 z EE%sT 1981 Mar 29 2s +2 c EE%sT 1991 +2 z EE%sT 1994 +2 e EE%sT 1997 +2 E EE%sT Z Europe/Kaliningrad 1:22 - LMT 1893 Ap -1 ' CE%sT 1945 -2 } CE%sT 1946 -3 M MSK/MSD 1989 Mar 26 2s -2 M EE%sT 2011 Mar 27 2s +1 c CE%sT 1945 Ap 10 +2 O EE%sT 1946 Ap 7 +3 R MSK/MSD 1989 Mar 26 2s +2 R EE%sT 2011 Mar 27 2s 3 - +03 2014 O 26 2s 2 - EET Z Europe/Moscow 2:30:17 - LMT 1880 2:30:17 - MMT 1916 Jul 3 -2:31:19 M %s 1919 Jul 1 0u -3 M %s 1921 O -3 M MSK/MSD 1922 O +2:31:19 R %s 1919 Jul 1 0u +3 R %s 1921 O +3 R MSK/MSD 1922 O 2 - EET 1930 Jun 21 -3 M MSK/MSD 1991 Mar 31 2s -2 M EE%sT 1992 Ja 19 2s -3 M MSK/MSD 2011 Mar 27 2s +3 R MSK/MSD 1991 Mar 31 2s +2 R EE%sT 1992 Ja 19 2s +3 R MSK/MSD 2011 Mar 27 2s 4 - MSK 2014 O 26 2s 3 - MSK Z Europe/Simferopol 2:16:24 - LMT 1880 2:16 - SMT 1924 May 2 2 - EET 1930 Jun 21 3 - MSK 1941 N -1 ' CE%sT 1944 Ap 13 -3 M MSK/MSD 1990 +1 c CE%sT 1944 Ap 13 +3 R MSK/MSD 1990 3 - MSK 1990 Jul 1 2 2 - EET 1992 -2 W EE%sT 1994 May -3 W MSK/MSD 1996 Mar 31 0s +2 e EE%sT 1994 May +3 e MSK/MSD 1996 Mar 31 0s 3 1 MSD 1996 O 27 3s -3 M MSK/MSD 1997 -3 - MSK 1997 Mar lastSun 1u -2 O EE%sT 2014 Mar 30 2 +3 R MSK/MSD 1997 +3 - MSK 1997 Mar lastSu 1u +2 E EE%sT 2014 Mar 30 2 4 - MSK 2014 O 26 2s 3 - MSK Z Europe/Astrakhan 3:12:12 - LMT 1924 May 3 - +03 1930 Jun 21 -4 M +04/+05 1989 Mar 26 2s -3 M +03/+04 1991 Mar 31 2s +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s 4 - +04 1992 Mar 29 2s -3 M +03/+04 2011 Mar 27 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 2014 O 26 2s 3 - +03 2016 Mar 27 2s 4 - +04 Z Europe/Volgograd 2:57:40 - LMT 1920 Ja 3 3 - +03 1930 Jun 21 4 - +04 1961 N 11 -4 M +04/+05 1988 Mar 27 2s -3 M +03/+04 1991 Mar 31 2s +4 R +04/+05 1988 Mar 27 2s +3 R +03/+04 1991 Mar 31 2s 4 - +04 1992 Mar 29 2s -3 M +03/+04 2011 Mar 27 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 2014 O 26 2s -3 - +03 +3 - +03 2018 O 28 2s +4 - +04 Z Europe/Saratov 3:4:18 - LMT 1919 Jul 1 0u 3 - +03 1930 Jun 21 -4 M +04/+05 1988 Mar 27 2s -3 M +03/+04 1991 Mar 31 2s +4 R +04/+05 1988 Mar 27 2s +3 R +03/+04 1991 Mar 31 2s 4 - +04 1992 Mar 29 2s -3 M +03/+04 2011 Mar 27 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 2014 O 26 2s 3 - +03 2016 D 4 2s 4 - +04 Z Europe/Kirov 3:18:48 - LMT 1919 Jul 1 0u 3 - +03 1930 Jun 21 -4 M +04/+05 1989 Mar 26 2s -3 M +03/+04 1991 Mar 31 2s +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s 4 - +04 1992 Mar 29 2s -3 M +03/+04 2011 Mar 27 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 2014 O 26 2s 3 - +03 Z Europe/Samara 3:20:20 - LMT 1919 Jul 1 0u 3 - +03 1930 Jun 21 4 - +04 1935 Ja 27 -4 M +04/+05 1989 Mar 26 2s -3 M +03/+04 1991 Mar 31 2s -2 M +02/+03 1991 S 29 2s +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s +2 R +02/+03 1991 S 29 2s 3 - +03 1991 O 20 3 -4 M +04/+05 2010 Mar 28 2s -3 M +03/+04 2011 Mar 27 2s +4 R +04/+05 2010 Mar 28 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 Z Europe/Ulyanovsk 3:13:36 - LMT 1919 Jul 1 0u 3 - +03 1930 Jun 21 -4 M +04/+05 1989 Mar 26 2s -3 M +03/+04 1991 Mar 31 2s -2 M +02/+03 1992 Ja 19 2s -3 M +03/+04 2011 Mar 27 2s +4 R +04/+05 1989 Mar 26 2s +3 R +03/+04 1991 Mar 31 2s +2 R +02/+03 1992 Ja 19 2s +3 R +03/+04 2011 Mar 27 2s 4 - +04 2014 O 26 2s 3 - +03 2016 Mar 27 2s 4 - +04 Z Asia/Yekaterinburg 4:2:33 - LMT 1916 Jul 3 3:45:5 - PMT 1919 Jul 15 4 4 - +04 1930 Jun 21 -5 M +05/+06 1991 Mar 31 2s -4 M +04/+05 1992 Ja 19 2s -5 M +05/+06 2011 Mar 27 2s +5 R +05/+06 1991 Mar 31 2s +4 R +04/+05 1992 Ja 19 2s +5 R +05/+06 2011 Mar 27 2s 6 - +06 2014 O 26 2s 5 - +05 Z Asia/Omsk 4:53:30 - LMT 1919 N 14 5 - +05 1930 Jun 21 -6 M +06/+07 1991 Mar 31 2s -5 M +05/+06 1992 Ja 19 2s -6 M +06/+07 2011 Mar 27 2s +6 R +06/+07 1991 Mar 31 2s +5 R +05/+06 1992 Ja 19 2s +6 R +06/+07 2011 Mar 27 2s 7 - +07 2014 O 26 2s 6 - +06 Z Asia/Barnaul 5:35 - LMT 1919 D 10 6 - +06 1930 Jun 21 -7 M +07/+08 1991 Mar 31 2s -6 M +06/+07 1992 Ja 19 2s -7 M +07/+08 1995 May 28 -6 M +06/+07 2011 Mar 27 2s +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 1995 May 28 +6 R +06/+07 2011 Mar 27 2s 7 - +07 2014 O 26 2s 6 - +06 2016 Mar 27 2s 7 - +07 Z Asia/Novosibirsk 5:31:40 - LMT 1919 D 14 6 6 - +06 1930 Jun 21 -7 M +07/+08 1991 Mar 31 2s -6 M +06/+07 1992 Ja 19 2s -7 M +07/+08 1993 May 23 -6 M +06/+07 2011 Mar 27 2s +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 1993 May 23 +6 R +06/+07 2011 Mar 27 2s 7 - +07 2014 O 26 2s 6 - +06 2016 Jul 24 2s 7 - +07 Z Asia/Tomsk 5:39:51 - LMT 1919 D 22 6 - +06 1930 Jun 21 -7 M +07/+08 1991 Mar 31 2s -6 M +06/+07 1992 Ja 19 2s -7 M +07/+08 2002 May 1 3 -6 M +06/+07 2011 Mar 27 2s +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2002 May 1 3 +6 R +06/+07 2011 Mar 27 2s 7 - +07 2014 O 26 2s 6 - +06 2016 May 29 2s 7 - +07 Z Asia/Novokuznetsk 5:48:48 - LMT 1924 May 6 - +06 1930 Jun 21 -7 M +07/+08 1991 Mar 31 2s -6 M +06/+07 1992 Ja 19 2s -7 M +07/+08 2010 Mar 28 2s -6 M +06/+07 2011 Mar 27 2s +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2010 Mar 28 2s +6 R +06/+07 2011 Mar 27 2s 7 - +07 Z Asia/Krasnoyarsk 6:11:26 - LMT 1920 Ja 6 6 - +06 1930 Jun 21 -7 M +07/+08 1991 Mar 31 2s -6 M +06/+07 1992 Ja 19 2s -7 M +07/+08 2011 Mar 27 2s +7 R +07/+08 1991 Mar 31 2s +6 R +06/+07 1992 Ja 19 2s +7 R +07/+08 2011 Mar 27 2s 8 - +08 2014 O 26 2s 7 - +07 Z Asia/Irkutsk 6:57:5 - LMT 1880 6:57:5 - IMT 1920 Ja 25 7 - +07 1930 Jun 21 -8 M +08/+09 1991 Mar 31 2s -7 M +07/+08 1992 Ja 19 2s -8 M +08/+09 2011 Mar 27 2s +8 R +08/+09 1991 Mar 31 2s +7 R +07/+08 1992 Ja 19 2s +8 R +08/+09 2011 Mar 27 2s 9 - +09 2014 O 26 2s 8 - +08 Z Asia/Chita 7:33:52 - LMT 1919 D 15 8 - +08 1930 Jun 21 -9 M +09/+10 1991 Mar 31 2s -8 M +08/+09 1992 Ja 19 2s -9 M +09/+10 2011 Mar 27 2s +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2011 Mar 27 2s 10 - +10 2014 O 26 2s 8 - +08 2016 Mar 27 2 9 - +09 Z Asia/Yakutsk 8:38:58 - LMT 1919 D 15 8 - +08 1930 Jun 21 -9 M +09/+10 1991 Mar 31 2s -8 M +08/+09 1992 Ja 19 2s -9 M +09/+10 2011 Mar 27 2s +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2011 Mar 27 2s 10 - +10 2014 O 26 2s 9 - +09 Z Asia/Vladivostok 8:47:31 - LMT 1922 N 15 9 - +09 1930 Jun 21 -10 M +10/+11 1991 Mar 31 2s -9 M +09/+10 1992 Ja 19 2s -10 M +10/+11 2011 Mar 27 2s +10 R +10/+11 1991 Mar 31 2s +9 R +09/+10 1992 Ja 19 2s +10 R +10/+11 2011 Mar 27 2s 11 - +11 2014 O 26 2s 10 - +10 Z Asia/Khandyga 9:2:13 - LMT 1919 D 15 8 - +08 1930 Jun 21 -9 M +09/+10 1991 Mar 31 2s -8 M +08/+09 1992 Ja 19 2s -9 M +09/+10 2004 -10 M +10/+11 2011 Mar 27 2s +9 R +09/+10 1991 Mar 31 2s +8 R +08/+09 1992 Ja 19 2s +9 R +09/+10 2004 +10 R +10/+11 2011 Mar 27 2s 11 - +11 2011 S 13 0s 10 - +10 2014 O 26 2s 9 - +09 Z Asia/Sakhalin 9:30:48 - LMT 1905 Au 23 9 - +09 1945 Au 25 -11 M +11/+12 1991 Mar 31 2s -10 M +10/+11 1992 Ja 19 2s -11 M +11/+12 1997 Mar lastSun 2s -10 M +10/+11 2011 Mar 27 2s +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 1997 Mar lastSu 2s +10 R +10/+11 2011 Mar 27 2s 11 - +11 2014 O 26 2s 10 - +10 2016 Mar 27 2s 11 - +11 Z Asia/Magadan 10:3:12 - LMT 1924 May 2 10 - +10 1930 Jun 21 -11 M +11/+12 1991 Mar 31 2s -10 M +10/+11 1992 Ja 19 2s -11 M +11/+12 2011 Mar 27 2s +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s 12 - +12 2014 O 26 2s 10 - +10 2016 Ap 24 2s 11 - +11 Z Asia/Srednekolymsk 10:14:52 - LMT 1924 May 2 10 - +10 1930 Jun 21 -11 M +11/+12 1991 Mar 31 2s -10 M +10/+11 1992 Ja 19 2s -11 M +11/+12 2011 Mar 27 2s +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s 12 - +12 2014 O 26 2s 11 - +11 Z Asia/Ust-Nera 9:32:54 - LMT 1919 D 15 8 - +08 1930 Jun 21 -9 M +09/+10 1981 Ap -11 M +11/+12 1991 Mar 31 2s -10 M +10/+11 1992 Ja 19 2s -11 M +11/+12 2011 Mar 27 2s +9 R +09/+10 1981 Ap +11 R +11/+12 1991 Mar 31 2s +10 R +10/+11 1992 Ja 19 2s +11 R +11/+12 2011 Mar 27 2s 12 - +12 2011 S 13 0s 11 - +11 2014 O 26 2s 10 - +10 Z Asia/Kamchatka 10:34:36 - LMT 1922 N 10 11 - +11 1930 Jun 21 -12 M +12/+13 1991 Mar 31 2s -11 M +11/+12 1992 Ja 19 2s -12 M +12/+13 2010 Mar 28 2s -11 M +11/+12 2011 Mar 27 2s +12 R +12/+13 1991 Mar 31 2s +11 R +11/+12 1992 Ja 19 2s +12 R +12/+13 2010 Mar 28 2s +11 R +11/+12 2011 Mar 27 2s 12 - +12 Z Asia/Anadyr 11:49:56 - LMT 1924 May 2 12 - +12 1930 Jun 21 -13 M +13/+14 1982 Ap 1 0s -12 M +12/+13 1991 Mar 31 2s -11 M +11/+12 1992 Ja 19 2s -12 M +12/+13 2010 Mar 28 2s -11 M +11/+12 2011 Mar 27 2s +13 R +13/+14 1982 Ap 1 0s +12 R +12/+13 1991 Mar 31 2s +11 R +11/+12 1992 Ja 19 2s +12 R +12/+13 2010 Mar 28 2s +11 R +11/+12 2011 Mar 27 2s 12 - +12 Z Europe/Belgrade 1:22 - LMT 1884 1 - CET 1941 Ap 18 23 -1 ' CE%sT 1945 +1 c CE%sT 1945 1 - CET 1945 May 8 2s 1 1 CEST 1945 S 16 2s 1 - CET 1982 N 27 -1 O CE%sT -Li Europe/Belgrade Europe/Ljubljana -Li Europe/Belgrade Europe/Podgorica -Li Europe/Belgrade Europe/Sarajevo -Li Europe/Belgrade Europe/Skopje -Li Europe/Belgrade Europe/Zagreb -Li Europe/Prague Europe/Bratislava -R AA 1918 o - Ap 15 23 1 S -R AA 1918 1919 - O 6 24s 0 - -R AA 1919 o - Ap 6 23 1 S -R AA 1924 o - Ap 16 23 1 S -R AA 1924 o - O 4 24s 0 - -R AA 1926 o - Ap 17 23 1 S -R AA 1926 1929 - O Sat>=1 24s 0 - -R AA 1927 o - Ap 9 23 1 S -R AA 1928 o - Ap 15 0 1 S -R AA 1929 o - Ap 20 23 1 S -R AA 1937 o - Jun 16 23 1 S -R AA 1937 o - O 2 24s 0 - -R AA 1938 o - Ap 2 23 1 S -R AA 1938 o - Ap 30 23 2 M -R AA 1938 o - O 2 24 1 S -R AA 1939 o - O 7 24s 0 - -R AA 1942 o - May 2 23 1 S -R AA 1942 o - S 1 1 0 - -R AA 1943 1946 - Ap Sat>=13 23 1 S -R AA 1943 1944 - O Sun>=1 1 0 - -R AA 1945 1946 - S lastSun 1 0 - -R AA 1949 o - Ap 30 23 1 S -R AA 1949 o - O 2 1 0 - -R AA 1974 1975 - Ap Sat>=12 23 1 S -R AA 1974 1975 - O Sun>=1 1 0 - -R AA 1976 o - Mar 27 23 1 S -R AA 1976 1977 - S lastSun 1 0 - -R AA 1977 o - Ap 2 23 1 S -R AA 1978 o - Ap 2 2s 1 S -R AA 1978 o - O 1 2s 0 - -R AB 1967 o - Jun 3 12 1 S -R AB 1967 o - O 1 0 0 - -R AB 1974 o - Jun 24 0 1 S -R AB 1974 o - S 1 0 0 - -R AB 1976 1977 - May 1 0 1 S -R AB 1976 o - Au 1 0 0 - -R AB 1977 o - S 28 0 0 - -R AB 1978 o - Jun 1 0 1 S -R AB 1978 o - Au 4 0 0 - +1 E CE%sT +L Europe/Belgrade Europe/Ljubljana +L Europe/Belgrade Europe/Podgorica +L Europe/Belgrade Europe/Sarajevo +L Europe/Belgrade Europe/Skopje +L Europe/Belgrade Europe/Zagreb +L Europe/Prague Europe/Bratislava +R s 1918 o - Ap 15 23 1 S +R s 1918 1919 - O 6 24s 0 - +R s 1919 o - Ap 6 23 1 S +R s 1924 o - Ap 16 23 1 S +R s 1924 o - O 4 24s 0 - +R s 1926 o - Ap 17 23 1 S +R s 1926 1929 - O Sa>=1 24s 0 - +R s 1927 o - Ap 9 23 1 S +R s 1928 o - Ap 15 0 1 S +R s 1929 o - Ap 20 23 1 S +R s 1937 o - Jun 16 23 1 S +R s 1937 o - O 2 24s 0 - +R s 1938 o - Ap 2 23 1 S +R s 1938 o - Ap 30 23 2 M +R s 1938 o - O 2 24 1 S +R s 1939 o - O 7 24s 0 - +R s 1942 o - May 2 23 1 S +R s 1942 o - S 1 1 0 - +R s 1943 1946 - Ap Sa>=13 23 1 S +R s 1943 1944 - O Su>=1 1 0 - +R s 1945 1946 - S lastSu 1 0 - +R s 1949 o - Ap 30 23 1 S +R s 1949 o - O 2 1 0 - +R s 1974 1975 - Ap Sa>=12 23 1 S +R s 1974 1975 - O Su>=1 1 0 - +R s 1976 o - Mar 27 23 1 S +R s 1976 1977 - S lastSu 1 0 - +R s 1977 o - Ap 2 23 1 S +R s 1978 o - Ap 2 2s 1 S +R s 1978 o - O 1 2s 0 - +R Sp 1967 o - Jun 3 12 1 S +R Sp 1967 o - O 1 0 0 - +R Sp 1974 o - Jun 24 0 1 S +R Sp 1974 o - S 1 0 0 - +R Sp 1976 1977 - May 1 0 1 S +R Sp 1976 o - Au 1 0 0 - +R Sp 1977 o - S 28 0 0 - +R Sp 1978 o - Jun 1 0 1 S +R Sp 1978 o - Au 4 0 0 - Z Europe/Madrid -0:14:44 - LMT 1900 D 31 23:45:16 -0 AA WE%sT 1940 Mar 16 23 -1 AA CE%sT 1979 -1 O CE%sT +0 s WE%sT 1940 Mar 16 23 +1 s CE%sT 1979 +1 E CE%sT Z Africa/Ceuta -0:21:16 - LMT 1900 D 31 23:38:44 0 - WET 1918 May 6 23 0 1 WEST 1918 O 7 23 0 - WET 1924 -0 AA WE%sT 1929 -0 AB WE%sT 1984 Mar 16 +0 s WE%sT 1929 +0 - WET 1967 +0 Sp WE%sT 1984 Mar 16 1 - CET 1986 -1 O CE%sT +1 E CE%sT Z Atlantic/Canary -1:1:36 - LMT 1922 Mar -1 - -01 1946 S 30 1 0 - WET 1980 Ap 6 0s 0 1 WEST 1980 S 28 1u -0 O WE%sT +0 E WE%sT Z Europe/Stockholm 1:12:12 - LMT 1879 1:0:14 - SET 1900 1 - CET 1916 May 14 23 1 1 CEST 1916 O 1 1 1 - CET 1980 -1 O CE%sT -R AC 1941 1942 - May M>=1 1 1 S -R AC 1941 1942 - O M>=1 2 0 - +1 E CE%sT +R CH 1941 1942 - May M>=1 1 1 S +R CH 1941 1942 - O M>=1 2 0 - Z Europe/Zurich 0:34:8 - LMT 1853 Jul 16 0:29:46 - BMT 1894 Jun -1 AC CE%sT 1981 -1 O CE%sT -R AD 1916 o - May 1 0 1 S -R AD 1916 o - O 1 0 0 - -R AD 1920 o - Mar 28 0 1 S -R AD 1920 o - O 25 0 0 - -R AD 1921 o - Ap 3 0 1 S -R AD 1921 o - O 3 0 0 - -R AD 1922 o - Mar 26 0 1 S -R AD 1922 o - O 8 0 0 - -R AD 1924 o - May 13 0 1 S -R AD 1924 1925 - O 1 0 0 - -R AD 1925 o - May 1 0 1 S -R AD 1940 o - Jun 30 0 1 S -R AD 1940 o - O 5 0 0 - -R AD 1940 o - D 1 0 1 S -R AD 1941 o - S 21 0 0 - -R AD 1942 o - Ap 1 0 1 S -R AD 1942 o - N 1 0 0 - -R AD 1945 o - Ap 2 0 1 S -R AD 1945 o - O 8 0 0 - -R AD 1946 o - Jun 1 0 1 S -R AD 1946 o - O 1 0 0 - -R AD 1947 1948 - Ap Sun>=16 0 1 S -R AD 1947 1950 - O Sun>=2 0 0 - -R AD 1949 o - Ap 10 0 1 S -R AD 1950 o - Ap 19 0 1 S -R AD 1951 o - Ap 22 0 1 S -R AD 1951 o - O 8 0 0 - -R AD 1962 o - Jul 15 0 1 S -R AD 1962 o - O 8 0 0 - -R AD 1964 o - May 15 0 1 S -R AD 1964 o - O 1 0 0 - -R AD 1970 1972 - May Sun>=2 0 1 S -R AD 1970 1972 - O Sun>=2 0 0 - -R AD 1973 o - Jun 3 1 1 S -R AD 1973 o - N 4 3 0 - -R AD 1974 o - Mar 31 2 1 S -R AD 1974 o - N 3 5 0 - -R AD 1975 o - Mar 30 0 1 S -R AD 1975 1976 - O lastSun 0 0 - -R AD 1976 o - Jun 1 0 1 S -R AD 1977 1978 - Ap Sun>=1 0 1 S -R AD 1977 o - O 16 0 0 - -R AD 1979 1980 - Ap Sun>=1 3 1 S -R AD 1979 1982 - O M>=11 0 0 - -R AD 1981 1982 - Mar lastSun 3 1 S -R AD 1983 o - Jul 31 0 1 S -R AD 1983 o - O 2 0 0 - -R AD 1985 o - Ap 20 0 1 S -R AD 1985 o - S 28 0 0 - -R AD 1986 1993 - Mar lastSun 1s 1 S -R AD 1986 1995 - S lastSun 1s 0 - -R AD 1994 o - Mar 20 1s 1 S -R AD 1995 2006 - Mar lastSun 1s 1 S -R AD 1996 2006 - O lastSun 1s 0 - +1 CH CE%sT 1981 +1 E CE%sT +R T 1916 o - May 1 0 1 S +R T 1916 o - O 1 0 0 - +R T 1920 o - Mar 28 0 1 S +R T 1920 o - O 25 0 0 - +R T 1921 o - Ap 3 0 1 S +R T 1921 o - O 3 0 0 - +R T 1922 o - Mar 26 0 1 S +R T 1922 o - O 8 0 0 - +R T 1924 o - May 13 0 1 S +R T 1924 1925 - O 1 0 0 - +R T 1925 o - May 1 0 1 S +R T 1940 o - Jul 1 0 1 S +R T 1940 o - O 6 0 0 - +R T 1940 o - D 1 0 1 S +R T 1941 o - S 21 0 0 - +R T 1942 o - Ap 1 0 1 S +R T 1945 o - O 8 0 0 - +R T 1946 o - Jun 1 0 1 S +R T 1946 o - O 1 0 0 - +R T 1947 1948 - Ap Su>=16 0 1 S +R T 1947 1951 - O Su>=2 0 0 - +R T 1949 o - Ap 10 0 1 S +R T 1950 o - Ap 16 0 1 S +R T 1951 o - Ap 22 0 1 S +R T 1962 o - Jul 15 0 1 S +R T 1963 o - O 30 0 0 - +R T 1964 o - May 15 0 1 S +R T 1964 o - O 1 0 0 - +R T 1973 o - Jun 3 1 1 S +R T 1973 1976 - O Su>=31 2 0 - +R T 1974 o - Mar 31 2 1 S +R T 1975 o - Mar 22 2 1 S +R T 1976 o - Mar 21 2 1 S +R T 1977 1978 - Ap Su>=1 2 1 S +R T 1977 1978 - O Su>=15 2 0 - +R T 1978 o - Jun 29 0 0 - +R T 1983 o - Jul 31 2 1 S +R T 1983 o - O 2 2 0 - +R T 1985 o - Ap 20 1s 1 S +R T 1985 o - S 28 1s 0 - +R T 1986 1993 - Mar lastSu 1s 1 S +R T 1986 1995 - S lastSu 1s 0 - +R T 1994 o - Mar 20 1s 1 S +R T 1995 2006 - Mar lastSu 1s 1 S +R T 1996 2006 - O lastSu 1s 0 - Z Europe/Istanbul 1:55:52 - LMT 1880 1:56:56 - IMT 1910 O -2 AD EE%sT 1978 O 15 -3 AD +03/+04 1985 Ap 20 -2 AD EE%sT 2007 -2 O EE%sT 2011 Mar 27 1u +2 T EE%sT 1978 Jun 29 +3 T +03/+04 1984 N 1 2 +2 T EE%sT 2007 +2 E EE%sT 2011 Mar 27 1u 2 - EET 2011 Mar 28 1u -2 O EE%sT 2014 Mar 30 1u +2 E EE%sT 2014 Mar 30 1u 2 - EET 2014 Mar 31 1u -2 O EE%sT 2015 O 25 1u +2 E EE%sT 2015 O 25 1u 2 1 EEST 2015 N 8 1u -2 O EE%sT 2016 S 7 +2 E EE%sT 2016 S 7 3 - +03 -Li Europe/Istanbul Asia/Istanbul +L Europe/Istanbul Asia/Istanbul Z Europe/Kiev 2:2:4 - LMT 1880 2:2:4 - KMT 1924 May 2 2 - EET 1930 Jun 21 3 - MSK 1941 S 20 -1 ' CE%sT 1943 N 6 -3 M MSK/MSD 1990 Jul 1 2 +1 c CE%sT 1943 N 6 +3 R MSK/MSD 1990 Jul 1 2 2 1 EEST 1991 S 29 3 -2 W EE%sT 1995 -2 O EE%sT +2 e EE%sT 1995 +2 E EE%sT Z Europe/Uzhgorod 1:29:12 - LMT 1890 O 1 - CET 1940 -1 ' CE%sT 1944 O +1 c CE%sT 1944 O 1 1 CEST 1944 O 26 1 - CET 1945 Jun 29 -3 M MSK/MSD 1990 +3 R MSK/MSD 1990 3 - MSK 1990 Jul 1 2 1 - CET 1991 Mar 31 3 2 - EET 1992 -2 W EE%sT 1995 -2 O EE%sT +2 e EE%sT 1995 +2 E EE%sT Z Europe/Zaporozhye 2:20:40 - LMT 1880 2:20 - +0220 1924 May 2 2 - EET 1930 Jun 21 3 - MSK 1941 Au 25 -1 ' CE%sT 1943 O 25 -3 M MSK/MSD 1991 Mar 31 2 -2 W EE%sT 1995 -2 O EE%sT -R AE 1918 1919 - Mar lastSun 2 1 D -R AE 1918 1919 - O lastSun 2 0 S -R AE 1942 o - F 9 2 1 W -R AE 1945 o - Au 14 23u 1 P -R AE 1945 o - S lastSun 2 0 S -R AE 1967 2006 - O lastSun 2 0 S -R AE 1967 1973 - Ap lastSun 2 1 D -R AE 1974 o - Ja 6 2 1 D -R AE 1975 o - F 23 2 1 D -R AE 1976 1986 - Ap lastSun 2 1 D -R AE 1987 2006 - Ap Sun>=1 2 1 D -R AE 2007 ma - Mar Sun>=8 2 1 D -R AE 2007 ma - N Sun>=1 2 0 S +1 c CE%sT 1943 O 25 +3 R MSK/MSD 1991 Mar 31 2 +2 e EE%sT 1995 +2 E EE%sT +R u 1918 1919 - Mar lastSu 2 1 D +R u 1918 1919 - O lastSu 2 0 S +R u 1942 o - F 9 2 1 W +R u 1945 o - Au 14 23u 1 P +R u 1945 o - S 30 2 0 S +R u 1967 2006 - O lastSu 2 0 S +R u 1967 1973 - Ap lastSu 2 1 D +R u 1974 o - Ja 6 2 1 D +R u 1975 o - F lastSu 2 1 D +R u 1976 1986 - Ap lastSu 2 1 D +R u 1987 2006 - Ap Su>=1 2 1 D +R u 2007 ma - Mar Su>=8 2 1 D +R u 2007 ma - N Su>=1 2 0 S Z EST -5 - EST Z MST -7 - MST Z HST -10 - HST -Z EST5EDT -5 AE E%sT -Z CST6CDT -6 AE C%sT -Z MST7MDT -7 AE M%sT -Z PST8PDT -8 AE P%sT -R AF 1920 o - Mar lastSun 2 1 D -R AF 1920 o - O lastSun 2 0 S -R AF 1921 1966 - Ap lastSun 2 1 D -R AF 1921 1954 - S lastSun 2 0 S -R AF 1955 1966 - O lastSun 2 0 S +Z EST5EDT -5 u E%sT +Z CST6CDT -6 u C%sT +Z MST7MDT -7 u M%sT +Z PST8PDT -8 u P%sT +R NY 1920 o - Mar lastSu 2 1 D +R NY 1920 o - O lastSu 2 0 S +R NY 1921 1966 - Ap lastSu 2 1 D +R NY 1921 1954 - S lastSu 2 0 S +R NY 1955 1966 - O lastSu 2 0 S Z America/New_York -4:56:2 - LMT 1883 N 18 12:3:58 --5 AE E%sT 1920 --5 AF E%sT 1942 --5 AE E%sT 1946 --5 AF E%sT 1967 --5 AE E%sT -R AG 1920 o - Jun 13 2 1 D -R AG 1920 1921 - O lastSun 2 0 S -R AG 1921 o - Mar lastSun 2 1 D -R AG 1922 1966 - Ap lastSun 2 1 D -R AG 1922 1954 - S lastSun 2 0 S -R AG 1955 1966 - O lastSun 2 0 S +-5 u E%sT 1920 +-5 NY E%sT 1942 +-5 u E%sT 1946 +-5 NY E%sT 1967 +-5 u E%sT +R Ch 1920 o - Jun 13 2 1 D +R Ch 1920 1921 - O lastSu 2 0 S +R Ch 1921 o - Mar lastSu 2 1 D +R Ch 1922 1966 - Ap lastSu 2 1 D +R Ch 1922 1954 - S lastSu 2 0 S +R Ch 1955 1966 - O lastSu 2 0 S Z America/Chicago -5:50:36 - LMT 1883 N 18 12:9:24 --6 AE C%sT 1920 --6 AG C%sT 1936 Mar 1 2 +-6 u C%sT 1920 +-6 Ch C%sT 1936 Mar 1 2 -5 - EST 1936 N 15 2 --6 AG C%sT 1942 --6 AE C%sT 1946 --6 AG C%sT 1967 --6 AE C%sT +-6 Ch C%sT 1942 +-6 u C%sT 1946 +-6 Ch C%sT 1967 +-6 u C%sT Z America/North_Dakota/Center -6:45:12 - LMT 1883 N 18 12:14:48 --7 AE M%sT 1992 O 25 2 --6 AE C%sT +-7 u M%sT 1992 O 25 2 +-6 u C%sT Z America/North_Dakota/New_Salem -6:45:39 - LMT 1883 N 18 12:14:21 --7 AE M%sT 2003 O 26 2 --6 AE C%sT +-7 u M%sT 2003 O 26 2 +-6 u C%sT Z America/North_Dakota/Beulah -6:47:7 - LMT 1883 N 18 12:12:53 --7 AE M%sT 2010 N 7 2 --6 AE C%sT -R AH 1920 1921 - Mar lastSun 2 1 D -R AH 1920 o - O lastSun 2 0 S -R AH 1921 o - May 22 2 0 S -R AH 1965 1966 - Ap lastSun 2 1 D -R AH 1965 1966 - O lastSun 2 0 S +-7 u M%sT 2010 N 7 2 +-6 u C%sT +R De 1920 1921 - Mar lastSu 2 1 D +R De 1920 o - O lastSu 2 0 S +R De 1921 o - May 22 2 0 S +R De 1965 1966 - Ap lastSu 2 1 D +R De 1965 1966 - O lastSu 2 0 S Z America/Denver -6:59:56 - LMT 1883 N 18 12:0:4 --7 AE M%sT 1920 --7 AH M%sT 1942 --7 AE M%sT 1946 --7 AH M%sT 1967 --7 AE M%sT -R AI 1948 o - Mar 14 2:1 1 D -R AI 1949 o - Ja 1 2 0 S -R AI 1950 1966 - Ap lastSun 1 1 D -R AI 1950 1961 - S lastSun 2 0 S -R AI 1962 1966 - O lastSun 2 0 S +-7 u M%sT 1920 +-7 De M%sT 1942 +-7 u M%sT 1946 +-7 De M%sT 1967 +-7 u M%sT +R CA 1948 o - Mar 14 2:1 1 D +R CA 1949 o - Ja 1 2 0 S +R CA 1950 1966 - Ap lastSu 1 1 D +R CA 1950 1961 - S lastSu 2 0 S +R CA 1962 1966 - O lastSu 2 0 S Z America/Los_Angeles -7:52:58 - LMT 1883 N 18 12:7:2 --8 AE P%sT 1946 --8 AI P%sT 1967 --8 AE P%sT +-8 u P%sT 1946 +-8 CA P%sT 1967 +-8 u P%sT Z America/Juneau 15:2:19 - LMT 1867 O 19 15:33:32 -8:57:41 - LMT 1900 Au 20 12 -8 - PST 1942 --8 AE P%sT 1946 +-8 u P%sT 1946 -8 - PST 1969 --8 AE P%sT 1980 Ap 27 2 --9 AE Y%sT 1980 O 26 2 --8 AE P%sT 1983 O 30 2 --9 AE Y%sT 1983 N 30 --9 AE AK%sT +-8 u P%sT 1980 Ap 27 2 +-9 u Y%sT 1980 O 26 2 +-8 u P%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT Z America/Sitka 14:58:47 - LMT 1867 O 19 15:30 -9:1:13 - LMT 1900 Au 20 12 -8 - PST 1942 --8 AE P%sT 1946 +-8 u P%sT 1946 -8 - PST 1969 --8 AE P%sT 1983 O 30 2 --9 AE Y%sT 1983 N 30 --9 AE AK%sT +-8 u P%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT Z America/Metlakatla 15:13:42 - LMT 1867 O 19 15:44:55 -8:46:18 - LMT 1900 Au 20 12 -8 - PST 1942 --8 AE P%sT 1946 +-8 u P%sT 1946 -8 - PST 1969 --8 AE P%sT 1983 O 30 2 +-8 u P%sT 1983 O 30 2 -8 - PST 2015 N 1 2 --9 AE AK%sT +-9 u AK%sT 2018 N 4 2 +-8 - PST 2019 Ja 20 2 +-9 u AK%sT Z America/Yakutat 14:41:5 - LMT 1867 O 19 15:12:18 -9:18:55 - LMT 1900 Au 20 12 -9 - YST 1942 --9 AE Y%sT 1946 +-9 u Y%sT 1946 -9 - YST 1969 --9 AE Y%sT 1983 N 30 --9 AE AK%sT +-9 u Y%sT 1983 N 30 +-9 u AK%sT Z America/Anchorage 14:0:24 - LMT 1867 O 19 14:31:37 -9:59:36 - LMT 1900 Au 20 12 -10 - AST 1942 --10 AE A%sT 1967 Ap +-10 u A%sT 1967 Ap -10 - AHST 1969 --10 AE AH%sT 1983 O 30 2 --9 AE Y%sT 1983 N 30 --9 AE AK%sT +-10 u AH%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT Z America/Nome 12:58:22 - LMT 1867 O 19 13:29:35 -11:1:38 - LMT 1900 Au 20 12 -11 - NST 1942 --11 AE N%sT 1946 +-11 u N%sT 1946 -11 - NST 1967 Ap -11 - BST 1969 --11 AE B%sT 1983 O 30 2 --9 AE Y%sT 1983 N 30 --9 AE AK%sT +-11 u B%sT 1983 O 30 2 +-9 u Y%sT 1983 N 30 +-9 u AK%sT Z America/Adak 12:13:22 - LMT 1867 O 19 12:44:35 -11:46:38 - LMT 1900 Au 20 12 -11 - NST 1942 --11 AE N%sT 1946 +-11 u N%sT 1946 -11 - NST 1967 Ap -11 - BST 1969 --11 AE B%sT 1983 O 30 2 --10 AE AH%sT 1983 N 30 --10 AE H%sT +-11 u B%sT 1983 O 30 2 +-10 u AH%sT 1983 N 30 +-10 u H%sT Z Pacific/Honolulu -10:31:26 - LMT 1896 Ja 13 12 -10:30 - HST 1933 Ap 30 2 -10:30 1 HDT 1933 May 21 12 --10:30 - HST 1942 F 9 2 --10:30 1 HDT 1945 S 30 2 --10:30 - HST 1947 Jun 8 2 +-10:30 u H%sT 1947 Jun 8 2 -10 - HST Z America/Phoenix -7:28:18 - LMT 1883 N 18 11:31:42 --7 AE M%sT 1944 Ja 1 0:1 +-7 u M%sT 1944 Ja 1 0:1 -7 - MST 1944 Ap 1 0:1 --7 AE M%sT 1944 O 1 0:1 +-7 u M%sT 1944 O 1 0:1 -7 - MST 1967 --7 AE M%sT 1968 Mar 21 +-7 u M%sT 1968 Mar 21 -7 - MST Z America/Boise -7:44:49 - LMT 1883 N 18 12:15:11 --8 AE P%sT 1923 May 13 2 --7 AE M%sT 1974 +-8 u P%sT 1923 May 13 2 +-7 u M%sT 1974 -7 - MST 1974 F 3 2 --7 AE M%sT -R AJ 1941 o - Jun 22 2 1 D -R AJ 1941 1954 - S lastSun 2 0 S -R AJ 1946 1954 - Ap lastSun 2 1 D +-7 u M%sT +R In 1941 o - Jun 22 2 1 D +R In 1941 1954 - S lastSu 2 0 S +R In 1946 1954 - Ap lastSu 2 1 D Z America/Indiana/Indianapolis -5:44:38 - LMT 1883 N 18 12:15:22 --6 AE C%sT 1920 --6 AJ C%sT 1942 --6 AE C%sT 1946 --6 AJ C%sT 1955 Ap 24 2 +-6 u C%sT 1920 +-6 In C%sT 1942 +-6 u C%sT 1946 +-6 In C%sT 1955 Ap 24 2 -5 - EST 1957 S 29 2 -6 - CST 1958 Ap 27 2 -5 - EST 1969 --5 AE E%sT 1971 +-5 u E%sT 1971 -5 - EST 2006 --5 AE E%sT -R AK 1951 o - Ap lastSun 2 1 D -R AK 1951 o - S lastSun 2 0 S -R AK 1954 1960 - Ap lastSun 2 1 D -R AK 1954 1960 - S lastSun 2 0 S +-5 u E%sT +R Ma 1951 o - Ap lastSu 2 1 D +R Ma 1951 o - S lastSu 2 0 S +R Ma 1954 1960 - Ap lastSu 2 1 D +R Ma 1954 1960 - S lastSu 2 0 S Z America/Indiana/Marengo -5:45:23 - LMT 1883 N 18 12:14:37 --6 AE C%sT 1951 --6 AK C%sT 1961 Ap 30 2 +-6 u C%sT 1951 +-6 Ma C%sT 1961 Ap 30 2 -5 - EST 1969 --5 AE E%sT 1974 Ja 6 2 +-5 u E%sT 1974 Ja 6 2 -6 1 CDT 1974 O 27 2 --5 AE E%sT 1976 +-5 u E%sT 1976 -5 - EST 2006 --5 AE E%sT -R AL 1946 o - Ap lastSun 2 1 D -R AL 1946 o - S lastSun 2 0 S -R AL 1953 1954 - Ap lastSun 2 1 D -R AL 1953 1959 - S lastSun 2 0 S -R AL 1955 o - May 1 0 1 D -R AL 1956 1963 - Ap lastSun 2 1 D -R AL 1960 o - O lastSun 2 0 S -R AL 1961 o - S lastSun 2 0 S -R AL 1962 1963 - O lastSun 2 0 S +-5 u E%sT +R V 1946 o - Ap lastSu 2 1 D +R V 1946 o - S lastSu 2 0 S +R V 1953 1954 - Ap lastSu 2 1 D +R V 1953 1959 - S lastSu 2 0 S +R V 1955 o - May 1 0 1 D +R V 1956 1963 - Ap lastSu 2 1 D +R V 1960 o - O lastSu 2 0 S +R V 1961 o - S lastSu 2 0 S +R V 1962 1963 - O lastSu 2 0 S Z America/Indiana/Vincennes -5:50:7 - LMT 1883 N 18 12:9:53 --6 AE C%sT 1946 --6 AL C%sT 1964 Ap 26 2 +-6 u C%sT 1946 +-6 V C%sT 1964 Ap 26 2 -5 - EST 1969 --5 AE E%sT 1971 +-5 u E%sT 1971 -5 - EST 2006 Ap 2 2 --6 AE C%sT 2007 N 4 2 --5 AE E%sT -R AM 1946 o - Ap lastSun 2 1 D -R AM 1946 o - S lastSun 2 0 S -R AM 1953 1954 - Ap lastSun 2 1 D -R AM 1953 1959 - S lastSun 2 0 S -R AM 1955 o - May 1 0 1 D -R AM 1956 1963 - Ap lastSun 2 1 D -R AM 1960 o - O lastSun 2 0 S -R AM 1961 o - S lastSun 2 0 S -R AM 1962 1963 - O lastSun 2 0 S +-6 u C%sT 2007 N 4 2 +-5 u E%sT +R Pe 1955 o - May 1 0 1 D +R Pe 1955 1960 - S lastSu 2 0 S +R Pe 1956 1963 - Ap lastSu 2 1 D +R Pe 1961 1963 - O lastSu 2 0 S Z America/Indiana/Tell_City -5:47:3 - LMT 1883 N 18 12:12:57 --6 AE C%sT 1946 --6 AM C%sT 1964 Ap 26 2 --5 - EST 1969 --5 AE E%sT 1971 +-6 u C%sT 1946 +-6 Pe C%sT 1964 Ap 26 2 +-5 - EST 1967 O 29 2 +-6 u C%sT 1969 Ap 27 2 +-5 u E%sT 1971 -5 - EST 2006 Ap 2 2 --6 AE C%sT -R AN 1955 o - May 1 0 1 D -R AN 1955 1960 - S lastSun 2 0 S -R AN 1956 1964 - Ap lastSun 2 1 D -R AN 1961 1964 - O lastSun 2 0 S +-6 u C%sT +R Pi 1955 o - May 1 0 1 D +R Pi 1955 1960 - S lastSu 2 0 S +R Pi 1956 1964 - Ap lastSu 2 1 D +R Pi 1961 1964 - O lastSu 2 0 S Z America/Indiana/Petersburg -5:49:7 - LMT 1883 N 18 12:10:53 --6 AE C%sT 1955 --6 AN C%sT 1965 Ap 25 2 +-6 u C%sT 1955 +-6 Pi C%sT 1965 Ap 25 2 -5 - EST 1966 O 30 2 --6 AE C%sT 1977 O 30 2 +-6 u C%sT 1977 O 30 2 -5 - EST 2006 Ap 2 2 --6 AE C%sT 2007 N 4 2 --5 AE E%sT -R AO 1947 1961 - Ap lastSun 2 1 D -R AO 1947 1954 - S lastSun 2 0 S -R AO 1955 1956 - O lastSun 2 0 S -R AO 1957 1958 - S lastSun 2 0 S -R AO 1959 1961 - O lastSun 2 0 S +-6 u C%sT 2007 N 4 2 +-5 u E%sT +R St 1947 1961 - Ap lastSu 2 1 D +R St 1947 1954 - S lastSu 2 0 S +R St 1955 1956 - O lastSu 2 0 S +R St 1957 1958 - S lastSu 2 0 S +R St 1959 1961 - O lastSu 2 0 S Z America/Indiana/Knox -5:46:30 - LMT 1883 N 18 12:13:30 --6 AE C%sT 1947 --6 AO C%sT 1962 Ap 29 2 +-6 u C%sT 1947 +-6 St C%sT 1962 Ap 29 2 -5 - EST 1963 O 27 2 --6 AE C%sT 1991 O 27 2 +-6 u C%sT 1991 O 27 2 -5 - EST 2006 Ap 2 2 --6 AE C%sT -R AP 1946 1960 - Ap lastSun 2 1 D -R AP 1946 1954 - S lastSun 2 0 S -R AP 1955 1956 - O lastSun 2 0 S -R AP 1957 1960 - S lastSun 2 0 S +-6 u C%sT +R Pu 1946 1960 - Ap lastSu 2 1 D +R Pu 1946 1954 - S lastSu 2 0 S +R Pu 1955 1956 - O lastSu 2 0 S +R Pu 1957 1960 - S lastSu 2 0 S Z America/Indiana/Winamac -5:46:25 - LMT 1883 N 18 12:13:35 --6 AE C%sT 1946 --6 AP C%sT 1961 Ap 30 2 +-6 u C%sT 1946 +-6 Pu C%sT 1961 Ap 30 2 -5 - EST 1969 --5 AE E%sT 1971 +-5 u E%sT 1971 -5 - EST 2006 Ap 2 2 --6 AE C%sT 2007 Mar 11 2 --5 AE E%sT +-6 u C%sT 2007 Mar 11 2 +-5 u E%sT Z America/Indiana/Vevay -5:40:16 - LMT 1883 N 18 12:19:44 --6 AE C%sT 1954 Ap 25 2 +-6 u C%sT 1954 Ap 25 2 -5 - EST 1969 --5 AE E%sT 1973 +-5 u E%sT 1973 -5 - EST 2006 --5 AE E%sT -R AQ 1921 o - May 1 2 1 D -R AQ 1921 o - S 1 2 0 S -R AQ 1941 1961 - Ap lastSun 2 1 D -R AQ 1941 o - S lastSun 2 0 S -R AQ 1946 o - Jun 2 2 0 S -R AQ 1950 1955 - S lastSun 2 0 S -R AQ 1956 1960 - O lastSun 2 0 S +-5 u E%sT +R v 1921 o - May 1 2 1 D +R v 1921 o - S 1 2 0 S +R v 1941 o - Ap lastSu 2 1 D +R v 1941 o - S lastSu 2 0 S +R v 1946 o - Ap lastSu 0:1 1 D +R v 1946 o - Jun 2 2 0 S +R v 1950 1961 - Ap lastSu 2 1 D +R v 1950 1955 - S lastSu 2 0 S +R v 1956 1961 - O lastSu 2 0 S Z America/Kentucky/Louisville -5:43:2 - LMT 1883 N 18 12:16:58 --6 AE C%sT 1921 --6 AQ C%sT 1942 --6 AE C%sT 1946 --6 AQ C%sT 1961 Jul 23 2 +-6 u C%sT 1921 +-6 v C%sT 1942 +-6 u C%sT 1946 +-6 v C%sT 1961 Jul 23 2 -5 - EST 1968 --5 AE E%sT 1974 Ja 6 2 +-5 u E%sT 1974 Ja 6 2 -6 1 CDT 1974 O 27 2 --5 AE E%sT +-5 u E%sT Z America/Kentucky/Monticello -5:39:24 - LMT 1883 N 18 12:20:36 --6 AE C%sT 1946 +-6 u C%sT 1946 -6 - CST 1968 --6 AE C%sT 2000 O 29 2 --5 AE E%sT -R AR 1948 o - Ap lastSun 2 1 D -R AR 1948 o - S lastSun 2 0 S +-6 u C%sT 2000 O 29 2 +-5 u E%sT +R Dt 1948 o - Ap lastSu 2 1 D +R Dt 1948 o - S lastSu 2 0 S Z America/Detroit -5:32:11 - LMT 1905 -6 - CST 1915 May 15 2 -5 - EST 1942 --5 AE E%sT 1946 --5 AR E%sT 1973 --5 AE E%sT 1975 +-5 u E%sT 1946 +-5 Dt E%sT 1967 Jun 14 0:1 +-5 u E%sT 1969 +-5 - EST 1973 +-5 u E%sT 1975 -5 - EST 1975 Ap 27 2 --5 AE E%sT -R AS 1946 o - Ap lastSun 2 1 D -R AS 1946 o - S lastSun 2 0 S -R AS 1966 o - Ap lastSun 2 1 D -R AS 1966 o - O lastSun 2 0 S +-5 u E%sT +R Me 1946 o - Ap lastSu 2 1 D +R Me 1946 o - S lastSu 2 0 S +R Me 1966 o - Ap lastSu 2 1 D +R Me 1966 o - O lastSu 2 0 S Z America/Menominee -5:50:27 - LMT 1885 S 18 12 --6 AE C%sT 1946 --6 AS C%sT 1969 Ap 27 2 +-6 u C%sT 1946 +-6 Me C%sT 1969 Ap 27 2 -5 - EST 1973 Ap 29 2 --6 AE C%sT -R AT 1918 o - Ap 14 2 1 D -R AT 1918 o - O 27 2 0 S -R AT 1942 o - F 9 2 1 W -R AT 1945 o - Au 14 23u 1 P -R AT 1945 o - S 30 2 0 S -R AT 1974 1986 - Ap lastSun 2 1 D -R AT 1974 2006 - O lastSun 2 0 S -R AT 1987 2006 - Ap Sun>=1 2 1 D -R AT 2007 ma - Mar Sun>=8 2 1 D -R AT 2007 ma - N Sun>=1 2 0 S -R AU 1917 o - Ap 8 2 1 D -R AU 1917 o - S 17 2 0 S -R AU 1919 o - May 5 23 1 D -R AU 1919 o - Au 12 23 0 S -R AU 1920 1935 - May Sun>=1 23 1 D -R AU 1920 1935 - O lastSun 23 0 S -R AU 1936 1941 - May M>=9 0 1 D -R AU 1936 1941 - O M>=2 0 0 S -R AU 1946 1950 - May Sun>=8 2 1 D -R AU 1946 1950 - O Sun>=2 2 0 S -R AU 1951 1986 - Ap lastSun 2 1 D -R AU 1951 1959 - S lastSun 2 0 S -R AU 1960 1986 - O lastSun 2 0 S -R AU 1987 o - Ap Sun>=1 0:1 1 D -R AU 1987 2006 - O lastSun 0:1 0 S -R AU 1988 o - Ap Sun>=1 0:1 2 DD -R AU 1989 2006 - Ap Sun>=1 0:1 1 D -R AU 2007 2011 - Mar Sun>=8 0:1 1 D -R AU 2007 2010 - N Sun>=1 0:1 0 S +-6 u C%sT +R C 1918 o - Ap 14 2 1 D +R C 1918 o - O 27 2 0 S +R C 1942 o - F 9 2 1 W +R C 1945 o - Au 14 23u 1 P +R C 1945 o - S 30 2 0 S +R C 1974 1986 - Ap lastSu 2 1 D +R C 1974 2006 - O lastSu 2 0 S +R C 1987 2006 - Ap Su>=1 2 1 D +R C 2007 ma - Mar Su>=8 2 1 D +R C 2007 ma - N Su>=1 2 0 S +R j 1917 o - Ap 8 2 1 D +R j 1917 o - S 17 2 0 S +R j 1919 o - May 5 23 1 D +R j 1919 o - Au 12 23 0 S +R j 1920 1935 - May Su>=1 23 1 D +R j 1920 1935 - O lastSu 23 0 S +R j 1936 1941 - May M>=9 0 1 D +R j 1936 1941 - O M>=2 0 0 S +R j 1946 1950 - May Su>=8 2 1 D +R j 1946 1950 - O Su>=2 2 0 S +R j 1951 1986 - Ap lastSu 2 1 D +R j 1951 1959 - S lastSu 2 0 S +R j 1960 1986 - O lastSu 2 0 S +R j 1987 o - Ap Su>=1 0:1 1 D +R j 1987 2006 - O lastSu 0:1 0 S +R j 1988 o - Ap Su>=1 0:1 2 DD +R j 1989 2006 - Ap Su>=1 0:1 1 D +R j 2007 2011 - Mar Su>=8 0:1 1 D +R j 2007 2010 - N Su>=1 0:1 0 S Z America/St_Johns -3:30:52 - LMT 1884 --3:30:52 AU N%sT 1918 --3:30:52 AT N%sT 1919 --3:30:52 AU N%sT 1935 Mar 30 --3:30 AU N%sT 1942 May 11 --3:30 AT N%sT 1946 --3:30 AU N%sT 2011 N --3:30 AT N%sT +-3:30:52 j N%sT 1918 +-3:30:52 C N%sT 1919 +-3:30:52 j N%sT 1935 Mar 30 +-3:30 j N%sT 1942 May 11 +-3:30 C N%sT 1946 +-3:30 j N%sT 2011 N +-3:30 C N%sT Z America/Goose_Bay -4:1:40 - LMT 1884 -3:30:52 - NST 1918 --3:30:52 AT N%sT 1919 +-3:30:52 C N%sT 1919 -3:30:52 - NST 1935 Mar 30 -3:30 - NST 1936 --3:30 AU N%sT 1942 May 11 --3:30 AT N%sT 1946 --3:30 AU N%sT 1966 Mar 15 2 --4 AU A%sT 2011 N --4 AT A%sT -R AV 1916 o - Ap 1 0 1 D -R AV 1916 o - O 1 0 0 S -R AV 1920 o - May 9 0 1 D -R AV 1920 o - Au 29 0 0 S -R AV 1921 o - May 6 0 1 D -R AV 1921 1922 - S 5 0 0 S -R AV 1922 o - Ap 30 0 1 D -R AV 1923 1925 - May Sun>=1 0 1 D -R AV 1923 o - S 4 0 0 S -R AV 1924 o - S 15 0 0 S -R AV 1925 o - S 28 0 0 S -R AV 1926 o - May 16 0 1 D -R AV 1926 o - S 13 0 0 S -R AV 1927 o - May 1 0 1 D -R AV 1927 o - S 26 0 0 S -R AV 1928 1931 - May Sun>=8 0 1 D -R AV 1928 o - S 9 0 0 S -R AV 1929 o - S 3 0 0 S -R AV 1930 o - S 15 0 0 S -R AV 1931 1932 - S M>=24 0 0 S -R AV 1932 o - May 1 0 1 D -R AV 1933 o - Ap 30 0 1 D -R AV 1933 o - O 2 0 0 S -R AV 1934 o - May 20 0 1 D -R AV 1934 o - S 16 0 0 S -R AV 1935 o - Jun 2 0 1 D -R AV 1935 o - S 30 0 0 S -R AV 1936 o - Jun 1 0 1 D -R AV 1936 o - S 14 0 0 S -R AV 1937 1938 - May Sun>=1 0 1 D -R AV 1937 1941 - S M>=24 0 0 S -R AV 1939 o - May 28 0 1 D -R AV 1940 1941 - May Sun>=1 0 1 D -R AV 1946 1949 - Ap lastSun 2 1 D -R AV 1946 1949 - S lastSun 2 0 S -R AV 1951 1954 - Ap lastSun 2 1 D -R AV 1951 1954 - S lastSun 2 0 S -R AV 1956 1959 - Ap lastSun 2 1 D -R AV 1956 1959 - S lastSun 2 0 S -R AV 1962 1973 - Ap lastSun 2 1 D -R AV 1962 1973 - O lastSun 2 0 S +-3:30 j N%sT 1942 May 11 +-3:30 C N%sT 1946 +-3:30 j N%sT 1966 Mar 15 2 +-4 j A%sT 2011 N +-4 C A%sT +R H 1916 o - Ap 1 0 1 D +R H 1916 o - O 1 0 0 S +R H 1920 o - May 9 0 1 D +R H 1920 o - Au 29 0 0 S +R H 1921 o - May 6 0 1 D +R H 1921 1922 - S 5 0 0 S +R H 1922 o - Ap 30 0 1 D +R H 1923 1925 - May Su>=1 0 1 D +R H 1923 o - S 4 0 0 S +R H 1924 o - S 15 0 0 S +R H 1925 o - S 28 0 0 S +R H 1926 o - May 16 0 1 D +R H 1926 o - S 13 0 0 S +R H 1927 o - May 1 0 1 D +R H 1927 o - S 26 0 0 S +R H 1928 1931 - May Su>=8 0 1 D +R H 1928 o - S 9 0 0 S +R H 1929 o - S 3 0 0 S +R H 1930 o - S 15 0 0 S +R H 1931 1932 - S M>=24 0 0 S +R H 1932 o - May 1 0 1 D +R H 1933 o - Ap 30 0 1 D +R H 1933 o - O 2 0 0 S +R H 1934 o - May 20 0 1 D +R H 1934 o - S 16 0 0 S +R H 1935 o - Jun 2 0 1 D +R H 1935 o - S 30 0 0 S +R H 1936 o - Jun 1 0 1 D +R H 1936 o - S 14 0 0 S +R H 1937 1938 - May Su>=1 0 1 D +R H 1937 1941 - S M>=24 0 0 S +R H 1939 o - May 28 0 1 D +R H 1940 1941 - May Su>=1 0 1 D +R H 1946 1949 - Ap lastSu 2 1 D +R H 1946 1949 - S lastSu 2 0 S +R H 1951 1954 - Ap lastSu 2 1 D +R H 1951 1954 - S lastSu 2 0 S +R H 1956 1959 - Ap lastSu 2 1 D +R H 1956 1959 - S lastSu 2 0 S +R H 1962 1973 - Ap lastSu 2 1 D +R H 1962 1973 - O lastSu 2 0 S Z America/Halifax -4:14:24 - LMT 1902 Jun 15 --4 AV A%sT 1918 --4 AT A%sT 1919 --4 AV A%sT 1942 F 9 2s --4 AT A%sT 1946 --4 AV A%sT 1974 --4 AT A%sT +-4 H A%sT 1918 +-4 C A%sT 1919 +-4 H A%sT 1942 F 9 2s +-4 C A%sT 1946 +-4 H A%sT 1974 +-4 C A%sT Z America/Glace_Bay -3:59:48 - LMT 1902 Jun 15 --4 AT A%sT 1953 --4 AV A%sT 1954 +-4 C A%sT 1953 +-4 H A%sT 1954 -4 - AST 1972 --4 AV A%sT 1974 --4 AT A%sT -R AW 1933 1935 - Jun Sun>=8 1 1 D -R AW 1933 1935 - S Sun>=8 1 0 S -R AW 1936 1938 - Jun Sun>=1 1 1 D -R AW 1936 1938 - S Sun>=1 1 0 S -R AW 1939 o - May 27 1 1 D -R AW 1939 1941 - S Sat>=21 1 0 S -R AW 1940 o - May 19 1 1 D -R AW 1941 o - May 4 1 1 D -R AW 1946 1972 - Ap lastSun 2 1 D -R AW 1946 1956 - S lastSun 2 0 S -R AW 1957 1972 - O lastSun 2 0 S -R AW 1993 2006 - Ap Sun>=1 0:1 1 D -R AW 1993 2006 - O lastSun 0:1 0 S +-4 H A%sT 1974 +-4 C A%sT +R o 1933 1935 - Jun Su>=8 1 1 D +R o 1933 1935 - S Su>=8 1 0 S +R o 1936 1938 - Jun Su>=1 1 1 D +R o 1936 1938 - S Su>=1 1 0 S +R o 1939 o - May 27 1 1 D +R o 1939 1941 - S Sa>=21 1 0 S +R o 1940 o - May 19 1 1 D +R o 1941 o - May 4 1 1 D +R o 1946 1972 - Ap lastSu 2 1 D +R o 1946 1956 - S lastSu 2 0 S +R o 1957 1972 - O lastSu 2 0 S +R o 1993 2006 - Ap Su>=1 0:1 1 D +R o 1993 2006 - O lastSu 0:1 0 S Z America/Moncton -4:19:8 - LMT 1883 D 9 -5 - EST 1902 Jun 15 --4 AT A%sT 1933 --4 AW A%sT 1942 --4 AT A%sT 1946 --4 AW A%sT 1973 --4 AT A%sT 1993 --4 AW A%sT 2007 --4 AT A%sT +-4 C A%sT 1933 +-4 o A%sT 1942 +-4 C A%sT 1946 +-4 o A%sT 1973 +-4 C A%sT 1993 +-4 o A%sT 2007 +-4 C A%sT Z America/Blanc-Sablon -3:48:28 - LMT 1884 --4 AT A%sT 1970 +-4 C A%sT 1970 -4 - AST -R AX 1919 o - Mar 30 23:30 1 D -R AX 1919 o - O 26 0 0 S -R AX 1920 o - May 2 2 1 D -R AX 1920 o - S 26 0 0 S -R AX 1921 o - May 15 2 1 D -R AX 1921 o - S 15 2 0 S -R AX 1922 1923 - May Sun>=8 2 1 D -R AX 1922 1926 - S Sun>=15 2 0 S -R AX 1924 1927 - May Sun>=1 2 1 D -R AX 1927 1932 - S lastSun 2 0 S -R AX 1928 1931 - Ap lastSun 2 1 D -R AX 1932 o - May 1 2 1 D -R AX 1933 1940 - Ap lastSun 2 1 D -R AX 1933 o - O 1 2 0 S -R AX 1934 1939 - S lastSun 2 0 S -R AX 1945 1946 - S lastSun 2 0 S -R AX 1946 o - Ap lastSun 2 1 D -R AX 1947 1949 - Ap lastSun 0 1 D -R AX 1947 1948 - S lastSun 0 0 S -R AX 1949 o - N lastSun 0 0 S -R AX 1950 1973 - Ap lastSun 2 1 D -R AX 1950 o - N lastSun 2 0 S -R AX 1951 1956 - S lastSun 2 0 S -R AX 1957 1973 - O lastSun 2 0 S +R t 1919 o - Mar 30 23:30 1 D +R t 1919 o - O 26 0 0 S +R t 1920 o - May 2 2 1 D +R t 1920 o - S 26 0 0 S +R t 1921 o - May 15 2 1 D +R t 1921 o - S 15 2 0 S +R t 1922 1923 - May Su>=8 2 1 D +R t 1922 1926 - S Su>=15 2 0 S +R t 1924 1927 - May Su>=1 2 1 D +R t 1927 1937 - S Su>=25 2 0 S +R t 1928 1937 - Ap Su>=25 2 1 D +R t 1938 1940 - Ap lastSu 2 1 D +R t 1938 1939 - S lastSu 2 0 S +R t 1945 1946 - S lastSu 2 0 S +R t 1946 o - Ap lastSu 2 1 D +R t 1947 1949 - Ap lastSu 0 1 D +R t 1947 1948 - S lastSu 0 0 S +R t 1949 o - N lastSu 0 0 S +R t 1950 1973 - Ap lastSu 2 1 D +R t 1950 o - N lastSu 2 0 S +R t 1951 1956 - S lastSu 2 0 S +R t 1957 1973 - O lastSu 2 0 S Z America/Toronto -5:17:32 - LMT 1895 --5 AT E%sT 1919 --5 AX E%sT 1942 F 9 2s --5 AT E%sT 1946 --5 AX E%sT 1974 --5 AT E%sT +-5 C E%sT 1919 +-5 t E%sT 1942 F 9 2s +-5 C E%sT 1946 +-5 t E%sT 1974 +-5 C E%sT Z America/Thunder_Bay -5:57 - LMT 1895 -6 - CST 1910 -5 - EST 1942 --5 AT E%sT 1970 --5 AX E%sT 1973 +-5 C E%sT 1970 +-5 t E%sT 1973 -5 - EST 1974 --5 AT E%sT +-5 C E%sT Z America/Nipigon -5:53:4 - LMT 1895 --5 AT E%sT 1940 S 29 +-5 C E%sT 1940 S 29 -5 1 EDT 1942 F 9 2s --5 AT E%sT +-5 C E%sT Z America/Rainy_River -6:18:16 - LMT 1895 --6 AT C%sT 1940 S 29 +-6 C C%sT 1940 S 29 -6 1 CDT 1942 F 9 2s --6 AT C%sT +-6 C C%sT Z America/Atikokan -6:6:28 - LMT 1895 --6 AT C%sT 1940 S 29 +-6 C C%sT 1940 S 29 -6 1 CDT 1942 F 9 2s --6 AT C%sT 1945 S 30 2 +-6 C C%sT 1945 S 30 2 -5 - EST -R AY 1916 o - Ap 23 0 1 D -R AY 1916 o - S 17 0 0 S -R AY 1918 o - Ap 14 2 1 D -R AY 1918 o - O 27 2 0 S -R AY 1937 o - May 16 2 1 D -R AY 1937 o - S 26 2 0 S -R AY 1942 o - F 9 2 1 W -R AY 1945 o - Au 14 23u 1 P -R AY 1945 o - S lastSun 2 0 S -R AY 1946 o - May 12 2 1 D -R AY 1946 o - O 13 2 0 S -R AY 1947 1949 - Ap lastSun 2 1 D -R AY 1947 1949 - S lastSun 2 0 S -R AY 1950 o - May 1 2 1 D -R AY 1950 o - S 30 2 0 S -R AY 1951 1960 - Ap lastSun 2 1 D -R AY 1951 1958 - S lastSun 2 0 S -R AY 1959 o - O lastSun 2 0 S -R AY 1960 o - S lastSun 2 0 S -R AY 1963 o - Ap lastSun 2 1 D -R AY 1963 o - S 22 2 0 S -R AY 1966 1986 - Ap lastSun 2s 1 D -R AY 1966 2005 - O lastSun 2s 0 S -R AY 1987 2005 - Ap Sun>=1 2s 1 D +R W 1916 o - Ap 23 0 1 D +R W 1916 o - S 17 0 0 S +R W 1918 o - Ap 14 2 1 D +R W 1918 o - O 27 2 0 S +R W 1937 o - May 16 2 1 D +R W 1937 o - S 26 2 0 S +R W 1942 o - F 9 2 1 W +R W 1945 o - Au 14 23u 1 P +R W 1945 o - S lastSu 2 0 S +R W 1946 o - May 12 2 1 D +R W 1946 o - O 13 2 0 S +R W 1947 1949 - Ap lastSu 2 1 D +R W 1947 1949 - S lastSu 2 0 S +R W 1950 o - May 1 2 1 D +R W 1950 o - S 30 2 0 S +R W 1951 1960 - Ap lastSu 2 1 D +R W 1951 1958 - S lastSu 2 0 S +R W 1959 o - O lastSu 2 0 S +R W 1960 o - S lastSu 2 0 S +R W 1963 o - Ap lastSu 2 1 D +R W 1963 o - S 22 2 0 S +R W 1966 1986 - Ap lastSu 2s 1 D +R W 1966 2005 - O lastSu 2s 0 S +R W 1987 2005 - Ap Su>=1 2s 1 D Z America/Winnipeg -6:28:36 - LMT 1887 Jul 16 --6 AY C%sT 2006 --6 AT C%sT -R AZ 1918 o - Ap 14 2 1 D -R AZ 1918 o - O 27 2 0 S -R AZ 1930 1934 - May Sun>=1 0 1 D -R AZ 1930 1934 - O Sun>=1 0 0 S -R AZ 1937 1941 - Ap Sun>=8 0 1 D -R AZ 1937 o - O Sun>=8 0 0 S -R AZ 1938 o - O Sun>=1 0 0 S -R AZ 1939 1941 - O Sun>=8 0 0 S -R AZ 1942 o - F 9 2 1 W -R AZ 1945 o - Au 14 23u 1 P -R AZ 1945 o - S lastSun 2 0 S -R AZ 1946 o - Ap Sun>=8 2 1 D -R AZ 1946 o - O Sun>=8 2 0 S -R AZ 1947 1957 - Ap lastSun 2 1 D -R AZ 1947 1957 - S lastSun 2 0 S -R AZ 1959 o - Ap lastSun 2 1 D -R AZ 1959 o - O lastSun 2 0 S -R Aa 1957 o - Ap lastSun 2 1 D -R Aa 1957 o - O lastSun 2 0 S -R Aa 1959 1961 - Ap lastSun 2 1 D -R Aa 1959 o - O lastSun 2 0 S -R Aa 1960 1961 - S lastSun 2 0 S +-6 W C%sT 2006 +-6 C C%sT +R r 1918 o - Ap 14 2 1 D +R r 1918 o - O 27 2 0 S +R r 1930 1934 - May Su>=1 0 1 D +R r 1930 1934 - O Su>=1 0 0 S +R r 1937 1941 - Ap Su>=8 0 1 D +R r 1937 o - O Su>=8 0 0 S +R r 1938 o - O Su>=1 0 0 S +R r 1939 1941 - O Su>=8 0 0 S +R r 1942 o - F 9 2 1 W +R r 1945 o - Au 14 23u 1 P +R r 1945 o - S lastSu 2 0 S +R r 1946 o - Ap Su>=8 2 1 D +R r 1946 o - O Su>=8 2 0 S +R r 1947 1957 - Ap lastSu 2 1 D +R r 1947 1957 - S lastSu 2 0 S +R r 1959 o - Ap lastSu 2 1 D +R r 1959 o - O lastSu 2 0 S +R Sw 1957 o - Ap lastSu 2 1 D +R Sw 1957 o - O lastSu 2 0 S +R Sw 1959 1961 - Ap lastSu 2 1 D +R Sw 1959 o - O lastSu 2 0 S +R Sw 1960 1961 - S lastSu 2 0 S Z America/Regina -6:58:36 - LMT 1905 S --7 AZ M%sT 1960 Ap lastSun 2 +-7 r M%sT 1960 Ap lastSu 2 -6 - CST Z America/Swift_Current -7:11:20 - LMT 1905 S --7 AT M%sT 1946 Ap lastSun 2 --7 AZ M%sT 1950 --7 Aa M%sT 1972 Ap lastSun 2 +-7 C M%sT 1946 Ap lastSu 2 +-7 r M%sT 1950 +-7 Sw M%sT 1972 Ap lastSu 2 -6 - CST -R Ab 1918 1919 - Ap Sun>=8 2 1 D -R Ab 1918 o - O 27 2 0 S -R Ab 1919 o - May 27 2 0 S -R Ab 1920 1923 - Ap lastSun 2 1 D -R Ab 1920 o - O lastSun 2 0 S -R Ab 1921 1923 - S lastSun 2 0 S -R Ab 1942 o - F 9 2 1 W -R Ab 1945 o - Au 14 23u 1 P -R Ab 1945 o - S lastSun 2 0 S -R Ab 1947 o - Ap lastSun 2 1 D -R Ab 1947 o - S lastSun 2 0 S -R Ab 1967 o - Ap lastSun 2 1 D -R Ab 1967 o - O lastSun 2 0 S -R Ab 1969 o - Ap lastSun 2 1 D -R Ab 1969 o - O lastSun 2 0 S -R Ab 1972 1986 - Ap lastSun 2 1 D -R Ab 1972 2006 - O lastSun 2 0 S +R Ed 1918 1919 - Ap Su>=8 2 1 D +R Ed 1918 o - O 27 2 0 S +R Ed 1919 o - May 27 2 0 S +R Ed 1920 1923 - Ap lastSu 2 1 D +R Ed 1920 o - O lastSu 2 0 S +R Ed 1921 1923 - S lastSu 2 0 S +R Ed 1942 o - F 9 2 1 W +R Ed 1945 o - Au 14 23u 1 P +R Ed 1945 o - S lastSu 2 0 S +R Ed 1947 o - Ap lastSu 2 1 D +R Ed 1947 o - S lastSu 2 0 S +R Ed 1972 1986 - Ap lastSu 2 1 D +R Ed 1972 2006 - O lastSu 2 0 S Z America/Edmonton -7:33:52 - LMT 1906 S --7 Ab M%sT 1987 --7 AT M%sT -R Ac 1918 o - Ap 14 2 1 D -R Ac 1918 o - O 27 2 0 S -R Ac 1942 o - F 9 2 1 W -R Ac 1945 o - Au 14 23u 1 P -R Ac 1945 o - S 30 2 0 S -R Ac 1946 1986 - Ap lastSun 2 1 D -R Ac 1946 o - O 13 2 0 S -R Ac 1947 1961 - S lastSun 2 0 S -R Ac 1962 2006 - O lastSun 2 0 S +-7 Ed M%sT 1987 +-7 C M%sT +R Va 1918 o - Ap 14 2 1 D +R Va 1918 o - O 27 2 0 S +R Va 1942 o - F 9 2 1 W +R Va 1945 o - Au 14 23u 1 P +R Va 1945 o - S 30 2 0 S +R Va 1946 1986 - Ap lastSu 2 1 D +R Va 1946 o - S 29 2 0 S +R Va 1947 1961 - S lastSu 2 0 S +R Va 1962 2006 - O lastSu 2 0 S Z America/Vancouver -8:12:28 - LMT 1884 --8 Ac P%sT 1987 --8 AT P%sT +-8 Va P%sT 1987 +-8 C P%sT Z America/Dawson_Creek -8:0:56 - LMT 1884 --8 AT P%sT 1947 --8 Ac P%sT 1972 Au 30 2 +-8 C P%sT 1947 +-8 Va P%sT 1972 Au 30 2 -7 - MST Z America/Fort_Nelson -8:10:47 - LMT 1884 --8 Ac P%sT 1946 +-8 Va P%sT 1946 -8 - PST 1947 --8 Ac P%sT 1987 --8 AT P%sT 2015 Mar 8 2 +-8 Va P%sT 1987 +-8 C P%sT 2015 Mar 8 2 -7 - MST Z America/Creston -7:46:4 - LMT 1884 -7 - MST 1916 O -8 - PST 1918 Jun 2 -7 - MST -R Ad 1918 o - Ap 14 2 1 D -R Ad 1918 o - O 27 2 0 S -R Ad 1919 o - May 25 2 1 D -R Ad 1919 o - N 1 0 0 S -R Ad 1942 o - F 9 2 1 W -R Ad 1945 o - Au 14 23u 1 P -R Ad 1945 o - S 30 2 0 S -R Ad 1965 o - Ap lastSun 0 2 DD -R Ad 1965 o - O lastSun 2 0 S -R Ad 1980 1986 - Ap lastSun 2 1 D -R Ad 1980 2006 - O lastSun 2 0 S -R Ad 1987 2006 - Ap Sun>=1 2 1 D +R Y 1918 o - Ap 14 2 1 D +R Y 1918 o - O 27 2 0 S +R Y 1919 o - May 25 2 1 D +R Y 1919 o - N 1 0 0 S +R Y 1942 o - F 9 2 1 W +R Y 1945 o - Au 14 23u 1 P +R Y 1945 o - S 30 2 0 S +R Y 1965 o - Ap lastSu 0 2 DD +R Y 1965 o - O lastSu 2 0 S +R Y 1980 1986 - Ap lastSu 2 1 D +R Y 1980 2006 - O lastSu 2 0 S +R Y 1987 2006 - Ap Su>=1 2 1 D Z America/Pangnirtung 0 - -00 1921 --4 Ad A%sT 1995 Ap Sun>=1 2 --5 AT E%sT 1999 O 31 2 --6 AT C%sT 2000 O 29 2 --5 AT E%sT +-4 Y A%sT 1995 Ap Su>=1 2 +-5 C E%sT 1999 O 31 2 +-6 C C%sT 2000 O 29 2 +-5 C E%sT Z America/Iqaluit 0 - -00 1942 Au --5 Ad E%sT 1999 O 31 2 --6 AT C%sT 2000 O 29 2 --5 AT E%sT +-5 Y E%sT 1999 O 31 2 +-6 C C%sT 2000 O 29 2 +-5 C E%sT Z America/Resolute 0 - -00 1947 Au 31 --6 Ad C%sT 2000 O 29 2 +-6 Y C%sT 2000 O 29 2 -5 - EST 2001 Ap 1 3 --6 AT C%sT 2006 O 29 2 +-6 C C%sT 2006 O 29 2 -5 - EST 2007 Mar 11 3 --6 AT C%sT +-6 C C%sT Z America/Rankin_Inlet 0 - -00 1957 --6 Ad C%sT 2000 O 29 2 +-6 Y C%sT 2000 O 29 2 -5 - EST 2001 Ap 1 3 --6 AT C%sT +-6 C C%sT Z America/Cambridge_Bay 0 - -00 1920 --7 Ad M%sT 1999 O 31 2 --6 AT C%sT 2000 O 29 2 +-7 Y M%sT 1999 O 31 2 +-6 C C%sT 2000 O 29 2 -5 - EST 2000 N 5 -6 - CST 2001 Ap 1 3 --7 AT M%sT +-7 C M%sT Z America/Yellowknife 0 - -00 1935 --7 Ad M%sT 1980 --7 AT M%sT +-7 Y M%sT 1980 +-7 C M%sT Z America/Inuvik 0 - -00 1953 --8 Ad P%sT 1979 Ap lastSun 2 --7 Ad M%sT 1980 --7 AT M%sT +-8 Y P%sT 1979 Ap lastSu 2 +-7 Y M%sT 1980 +-7 C M%sT Z America/Whitehorse -9:0:12 - LMT 1900 Au 20 --9 Ad Y%sT 1967 May 28 --8 Ad P%sT 1980 --8 AT P%sT +-9 Y Y%sT 1967 May 28 +-8 Y P%sT 1980 +-8 C P%sT Z America/Dawson -9:17:40 - LMT 1900 Au 20 --9 Ad Y%sT 1973 O 28 --8 Ad P%sT 1980 --8 AT P%sT -R Ae 1939 o - F 5 0 1 D -R Ae 1939 o - Jun 25 0 0 S -R Ae 1940 o - D 9 0 1 D -R Ae 1941 o - Ap 1 0 0 S -R Ae 1943 o - D 16 0 1 W -R Ae 1944 o - May 1 0 0 S -R Ae 1950 o - F 12 0 1 D -R Ae 1950 o - Jul 30 0 0 S -R Ae 1996 2000 - Ap Sun>=1 2 1 D -R Ae 1996 2000 - O lastSun 2 0 S -R Ae 2001 o - May Sun>=1 2 1 D -R Ae 2001 o - S lastSun 2 0 S -R Ae 2002 ma - Ap Sun>=1 2 1 D -R Ae 2002 ma - O lastSun 2 0 S +-9 Y Y%sT 1973 O 28 +-8 Y P%sT 1980 +-8 C P%sT +R m 1939 o - F 5 0 1 D +R m 1939 o - Jun 25 0 0 S +R m 1940 o - D 9 0 1 D +R m 1941 o - Ap 1 0 0 S +R m 1943 o - D 16 0 1 W +R m 1944 o - May 1 0 0 S +R m 1950 o - F 12 0 1 D +R m 1950 o - Jul 30 0 0 S +R m 1996 2000 - Ap Su>=1 2 1 D +R m 1996 2000 - O lastSu 2 0 S +R m 2001 o - May Su>=1 2 1 D +R m 2001 o - S lastSu 2 0 S +R m 2002 ma - Ap Su>=1 2 1 D +R m 2002 ma - O lastSu 2 0 S Z America/Cancun -5:47:4 - LMT 1922 Ja 1 0:12:56 -6 - CST 1981 D 23 --5 Ae E%sT 1998 Au 2 2 --6 Ae C%sT 2015 F 1 2 +-5 m E%sT 1998 Au 2 2 +-6 m C%sT 2015 F 1 2 -5 - EST Z America/Merida -5:58:28 - LMT 1922 Ja 1 0:1:32 -6 - CST 1981 D 23 -5 - EST 1982 D 2 --6 Ae C%sT +-6 m C%sT Z America/Matamoros -6:40 - LMT 1921 D 31 23:20 -6 - CST 1988 --6 AE C%sT 1989 --6 Ae C%sT 2010 --6 AE C%sT +-6 u C%sT 1989 +-6 m C%sT 2010 +-6 u C%sT Z America/Monterrey -6:41:16 - LMT 1921 D 31 23:18:44 -6 - CST 1988 --6 AE C%sT 1989 --6 Ae C%sT +-6 u C%sT 1989 +-6 m C%sT Z America/Mexico_City -6:36:36 - LMT 1922 Ja 1 0:23:24 -7 - MST 1927 Jun 10 23 -6 - CST 1930 N 15 -7 - MST 1931 May 1 23 -6 - CST 1931 O -7 - MST 1932 Ap --6 Ae C%sT 2001 S 30 2 +-6 m C%sT 2001 S 30 2 -6 - CST 2002 F 20 --6 Ae C%sT +-6 m C%sT Z America/Ojinaga -6:57:40 - LMT 1922 Ja 1 0:2:20 -7 - MST 1927 Jun 10 23 -6 - CST 1930 N 15 @@ -3209,10 +3464,10 @@ Z America/Ojinaga -6:57:40 - LMT 1922 Ja 1 0:2:20 -6 - CST 1931 O -7 - MST 1932 Ap -6 - CST 1996 --6 Ae C%sT 1998 --6 - CST 1998 Ap Sun>=1 3 --7 Ae M%sT 2010 --7 AE M%sT +-6 m C%sT 1998 +-6 - CST 1998 Ap Su>=1 3 +-7 m M%sT 2010 +-7 u M%sT Z America/Chihuahua -7:4:20 - LMT 1921 D 31 23:55:40 -7 - MST 1927 Jun 10 23 -6 - CST 1930 N 15 @@ -3220,9 +3475,9 @@ Z America/Chihuahua -7:4:20 - LMT 1921 D 31 23:55:40 -6 - CST 1931 O -7 - MST 1932 Ap -6 - CST 1996 --6 Ae C%sT 1998 --6 - CST 1998 Ap Sun>=1 3 --7 Ae M%sT +-6 m C%sT 1998 +-6 - CST 1998 Ap Su>=1 3 +-7 m M%sT Z America/Hermosillo -7:23:52 - LMT 1921 D 31 23:36:8 -7 - MST 1927 Jun 10 23 -6 - CST 1930 N 15 @@ -3232,7 +3487,7 @@ Z America/Hermosillo -7:23:52 - LMT 1921 D 31 23:36:8 -6 - CST 1942 Ap 24 -7 - MST 1949 Ja 14 -8 - PST 1970 --7 Ae M%sT 1999 +-7 m M%sT 1999 -7 - MST Z America/Mazatlan -7:5:40 - LMT 1921 D 31 23:54:20 -7 - MST 1927 Jun 10 23 @@ -3243,7 +3498,7 @@ Z America/Mazatlan -7:5:40 - LMT 1921 D 31 23:54:20 -6 - CST 1942 Ap 24 -7 - MST 1949 Ja 14 -8 - PST 1970 --7 Ae M%sT +-7 m M%sT Z America/Bahia_Banderas -7:1 - LMT 1921 D 31 23:59 -7 - MST 1927 Jun 10 23 -6 - CST 1930 N 15 @@ -3253,8 +3508,8 @@ Z America/Bahia_Banderas -7:1 - LMT 1921 D 31 23:59 -6 - CST 1942 Ap 24 -7 - MST 1949 Ja 14 -8 - PST 1970 --7 Ae M%sT 2010 Ap 4 2 --6 Ae C%sT +-7 m M%sT 2010 Ap 4 2 +-6 m C%sT Z America/Tijuana -7:48:4 - LMT 1922 Ja 1 0:11:56 -7 - MST 1924 -8 - PST 1927 Jun 10 23 @@ -3267,315 +3522,315 @@ Z America/Tijuana -7:48:4 - LMT 1922 Ja 1 0:11:56 -8 - PST 1948 Ap 5 -8 1 PDT 1949 Ja 14 -8 - PST 1954 --8 AI P%sT 1961 +-8 CA P%sT 1961 -8 - PST 1976 --8 AE P%sT 1996 --8 Ae P%sT 2001 --8 AE P%sT 2002 F 20 --8 Ae P%sT 2010 --8 AE P%sT -R Af 1964 1975 - O lastSun 2 0 S -R Af 1964 1975 - Ap lastSun 2 1 D +-8 u P%sT 1996 +-8 m P%sT 2001 +-8 u P%sT 2002 F 20 +-8 m P%sT 2010 +-8 u P%sT +R BS 1964 1975 - O lastSu 2 0 S +R BS 1964 1975 - Ap lastSu 2 1 D Z America/Nassau -5:9:30 - LMT 1912 Mar 2 --5 Af E%sT 1976 --5 AE E%sT -R Ag 1977 o - Jun 12 2 1 D -R Ag 1977 1978 - O Sun>=1 2 0 S -R Ag 1978 1980 - Ap Sun>=15 2 1 D -R Ag 1979 o - S 30 2 0 S -R Ag 1980 o - S 25 2 0 S +-5 BS E%sT 1976 +-5 u E%sT +R BB 1977 o - Jun 12 2 1 D +R BB 1977 1978 - O Su>=1 2 0 S +R BB 1978 1980 - Ap Su>=15 2 1 D +R BB 1979 o - S 30 2 0 S +R BB 1980 o - S 25 2 0 S Z America/Barbados -3:58:29 - LMT 1924 -3:58:29 - BMT 1932 --4 Ag A%sT -R Ah 1918 1942 - O Sun>=2 0 0:30 -0530 -R Ah 1919 1943 - F Sun>=9 0 0 CST -R Ah 1973 o - D 5 0 1 CDT -R Ah 1974 o - F 9 0 0 CST -R Ah 1982 o - D 18 0 1 CDT -R Ah 1983 o - F 12 0 0 CST +-4 BB A%sT +R BZ 1918 1942 - O Su>=2 0 0:30 -0530 +R BZ 1919 1943 - F Su>=9 0 0 CST +R BZ 1973 o - D 5 0 1 CDT +R BZ 1974 o - F 9 0 0 CST +R BZ 1982 o - D 18 0 1 CDT +R BZ 1983 o - F 12 0 0 CST Z America/Belize -5:52:48 - LMT 1912 Ap --6 Ah %s +-6 BZ %s Z Atlantic/Bermuda -4:19:18 - LMT 1930 Ja 1 2 -4 - AST 1974 Ap 28 2 --4 AT A%sT 1976 --4 AE A%sT -R Ai 1979 1980 - F lastSun 0 1 D -R Ai 1979 1980 - Jun Sun>=1 0 0 S -R Ai 1991 1992 - Ja Sat>=15 0 1 D -R Ai 1991 o - Jul 1 0 0 S -R Ai 1992 o - Mar 15 0 0 S +-4 C A%sT 1976 +-4 u A%sT +R CR 1979 1980 - F lastSu 0 1 D +R CR 1979 1980 - Jun Su>=1 0 0 S +R CR 1991 1992 - Ja Sa>=15 0 1 D +R CR 1991 o - Jul 1 0 0 S +R CR 1992 o - Mar 15 0 0 S Z America/Costa_Rica -5:36:13 - LMT 1890 -5:36:13 - SJMT 1921 Ja 15 --6 Ai C%sT -R Aj 1928 o - Jun 10 0 1 D -R Aj 1928 o - O 10 0 0 S -R Aj 1940 1942 - Jun Sun>=1 0 1 D -R Aj 1940 1942 - S Sun>=1 0 0 S -R Aj 1945 1946 - Jun Sun>=1 0 1 D -R Aj 1945 1946 - S Sun>=1 0 0 S -R Aj 1965 o - Jun 1 0 1 D -R Aj 1965 o - S 30 0 0 S -R Aj 1966 o - May 29 0 1 D -R Aj 1966 o - O 2 0 0 S -R Aj 1967 o - Ap 8 0 1 D -R Aj 1967 1968 - S Sun>=8 0 0 S -R Aj 1968 o - Ap 14 0 1 D -R Aj 1969 1977 - Ap lastSun 0 1 D -R Aj 1969 1971 - O lastSun 0 0 S -R Aj 1972 1974 - O 8 0 0 S -R Aj 1975 1977 - O lastSun 0 0 S -R Aj 1978 o - May 7 0 1 D -R Aj 1978 1990 - O Sun>=8 0 0 S -R Aj 1979 1980 - Mar Sun>=15 0 1 D -R Aj 1981 1985 - May Sun>=5 0 1 D -R Aj 1986 1989 - Mar Sun>=14 0 1 D -R Aj 1990 1997 - Ap Sun>=1 0 1 D -R Aj 1991 1995 - O Sun>=8 0s 0 S -R Aj 1996 o - O 6 0s 0 S -R Aj 1997 o - O 12 0s 0 S -R Aj 1998 1999 - Mar lastSun 0s 1 D -R Aj 1998 2003 - O lastSun 0s 0 S -R Aj 2000 2003 - Ap Sun>=1 0s 1 D -R Aj 2004 o - Mar lastSun 0s 1 D -R Aj 2006 2010 - O lastSun 0s 0 S -R Aj 2007 o - Mar Sun>=8 0s 1 D -R Aj 2008 o - Mar Sun>=15 0s 1 D -R Aj 2009 2010 - Mar Sun>=8 0s 1 D -R Aj 2011 o - Mar Sun>=15 0s 1 D -R Aj 2011 o - N 13 0s 0 S -R Aj 2012 o - Ap 1 0s 1 D -R Aj 2012 ma - N Sun>=1 0s 0 S -R Aj 2013 ma - Mar Sun>=8 0s 1 D +-6 CR C%sT +R Q 1928 o - Jun 10 0 1 D +R Q 1928 o - O 10 0 0 S +R Q 1940 1942 - Jun Su>=1 0 1 D +R Q 1940 1942 - S Su>=1 0 0 S +R Q 1945 1946 - Jun Su>=1 0 1 D +R Q 1945 1946 - S Su>=1 0 0 S +R Q 1965 o - Jun 1 0 1 D +R Q 1965 o - S 30 0 0 S +R Q 1966 o - May 29 0 1 D +R Q 1966 o - O 2 0 0 S +R Q 1967 o - Ap 8 0 1 D +R Q 1967 1968 - S Su>=8 0 0 S +R Q 1968 o - Ap 14 0 1 D +R Q 1969 1977 - Ap lastSu 0 1 D +R Q 1969 1971 - O lastSu 0 0 S +R Q 1972 1974 - O 8 0 0 S +R Q 1975 1977 - O lastSu 0 0 S +R Q 1978 o - May 7 0 1 D +R Q 1978 1990 - O Su>=8 0 0 S +R Q 1979 1980 - Mar Su>=15 0 1 D +R Q 1981 1985 - May Su>=5 0 1 D +R Q 1986 1989 - Mar Su>=14 0 1 D +R Q 1990 1997 - Ap Su>=1 0 1 D +R Q 1991 1995 - O Su>=8 0s 0 S +R Q 1996 o - O 6 0s 0 S +R Q 1997 o - O 12 0s 0 S +R Q 1998 1999 - Mar lastSu 0s 1 D +R Q 1998 2003 - O lastSu 0s 0 S +R Q 2000 2003 - Ap Su>=1 0s 1 D +R Q 2004 o - Mar lastSu 0s 1 D +R Q 2006 2010 - O lastSu 0s 0 S +R Q 2007 o - Mar Su>=8 0s 1 D +R Q 2008 o - Mar Su>=15 0s 1 D +R Q 2009 2010 - Mar Su>=8 0s 1 D +R Q 2011 o - Mar Su>=15 0s 1 D +R Q 2011 o - N 13 0s 0 S +R Q 2012 o - Ap 1 0s 1 D +R Q 2012 ma - N Su>=1 0s 0 S +R Q 2013 ma - Mar Su>=8 0s 1 D Z America/Havana -5:29:28 - LMT 1890 -5:29:36 - HMT 1925 Jul 19 12 --5 Aj C%sT -R Ak 1966 o - O 30 0 1 EDT -R Ak 1967 o - F 28 0 0 EST -R Ak 1969 1973 - O lastSun 0 0:30 -0430 -R Ak 1970 o - F 21 0 0 EST -R Ak 1971 o - Ja 20 0 0 EST -R Ak 1972 1974 - Ja 21 0 0 EST +-5 Q C%sT +R DO 1966 o - O 30 0 1 EDT +R DO 1967 o - F 28 0 0 EST +R DO 1969 1973 - O lastSu 0 0:30 -0430 +R DO 1970 o - F 21 0 0 EST +R DO 1971 o - Ja 20 0 0 EST +R DO 1972 1974 - Ja 21 0 0 EST Z America/Santo_Domingo -4:39:36 - LMT 1890 -4:40 - SDMT 1933 Ap 1 12 --5 Ak %s 1974 O 27 +-5 DO %s 1974 O 27 -4 - AST 2000 O 29 2 --5 AE E%sT 2000 D 3 1 +-5 u E%sT 2000 D 3 1 -4 - AST -R Al 1987 1988 - May Sun>=1 0 1 D -R Al 1987 1988 - S lastSun 0 0 S +R SV 1987 1988 - May Su>=1 0 1 D +R SV 1987 1988 - S lastSu 0 0 S Z America/El_Salvador -5:56:48 - LMT 1921 --6 Al C%sT -R Am 1973 o - N 25 0 1 D -R Am 1974 o - F 24 0 0 S -R Am 1983 o - May 21 0 1 D -R Am 1983 o - S 22 0 0 S -R Am 1991 o - Mar 23 0 1 D -R Am 1991 o - S 7 0 0 S -R Am 2006 o - Ap 30 0 1 D -R Am 2006 o - O 1 0 0 S +-6 SV C%sT +R GT 1973 o - N 25 0 1 D +R GT 1974 o - F 24 0 0 S +R GT 1983 o - May 21 0 1 D +R GT 1983 o - S 22 0 0 S +R GT 1991 o - Mar 23 0 1 D +R GT 1991 o - S 7 0 0 S +R GT 2006 o - Ap 30 0 1 D +R GT 2006 o - O 1 0 0 S Z America/Guatemala -6:2:4 - LMT 1918 O 5 --6 Am C%sT -R An 1983 o - May 8 0 1 D -R An 1984 1987 - Ap lastSun 0 1 D -R An 1983 1987 - O lastSun 0 0 S -R An 1988 1997 - Ap Sun>=1 1s 1 D -R An 1988 1997 - O lastSun 1s 0 S -R An 2005 2006 - Ap Sun>=1 0 1 D -R An 2005 2006 - O lastSun 0 0 S -R An 2012 2015 - Mar Sun>=8 2 1 D -R An 2012 2015 - N Sun>=1 2 0 S -R An 2017 ma - Mar Sun>=8 2 1 D -R An 2017 ma - N Sun>=1 2 0 S +-6 GT C%sT +R HT 1983 o - May 8 0 1 D +R HT 1984 1987 - Ap lastSu 0 1 D +R HT 1983 1987 - O lastSu 0 0 S +R HT 1988 1997 - Ap Su>=1 1s 1 D +R HT 1988 1997 - O lastSu 1s 0 S +R HT 2005 2006 - Ap Su>=1 0 1 D +R HT 2005 2006 - O lastSu 0 0 S +R HT 2012 2015 - Mar Su>=8 2 1 D +R HT 2012 2015 - N Su>=1 2 0 S +R HT 2017 ma - Mar Su>=8 2 1 D +R HT 2017 ma - N Su>=1 2 0 S Z America/Port-au-Prince -4:49:20 - LMT 1890 -4:49 - PPMT 1917 Ja 24 12 --5 An E%sT -R Ao 1987 1988 - May Sun>=1 0 1 D -R Ao 1987 1988 - S lastSun 0 0 S -R Ao 2006 o - May Sun>=1 0 1 D -R Ao 2006 o - Au M>=1 0 0 S +-5 HT E%sT +R HN 1987 1988 - May Su>=1 0 1 D +R HN 1987 1988 - S lastSu 0 0 S +R HN 2006 o - May Su>=1 0 1 D +R HN 2006 o - Au M>=1 0 0 S Z America/Tegucigalpa -5:48:52 - LMT 1921 Ap --6 Ao C%sT -Z America/Jamaica -5:7:11 - LMT 1890 --5:7:11 - KMT 1912 F +-6 HN C%sT +Z America/Jamaica -5:7:10 - LMT 1890 +-5:7:10 - KMT 1912 F -5 - EST 1974 --5 AE E%sT 1984 +-5 u E%sT 1984 -5 - EST Z America/Martinique -4:4:20 - LMT 1890 -4:4:20 - FFMT 1911 May -4 - AST 1980 Ap 6 -4 1 ADT 1980 S 28 -4 - AST -R Ap 1979 1980 - Mar Sun>=16 0 1 D -R Ap 1979 1980 - Jun M>=23 0 0 S -R Ap 2005 o - Ap 10 0 1 D -R Ap 2005 o - O Sun>=1 0 0 S -R Ap 2006 o - Ap 30 2 1 D -R Ap 2006 o - O Sun>=1 1 0 S +R NI 1979 1980 - Mar Su>=16 0 1 D +R NI 1979 1980 - Jun M>=23 0 0 S +R NI 2005 o - Ap 10 0 1 D +R NI 2005 o - O Su>=1 0 0 S +R NI 2006 o - Ap 30 2 1 D +R NI 2006 o - O Su>=1 1 0 S Z America/Managua -5:45:8 - LMT 1890 -5:45:12 - MMT 1934 Jun 23 -6 - CST 1973 May -5 - EST 1975 F 16 --6 Ap C%sT 1992 Ja 1 4 +-6 NI C%sT 1992 Ja 1 4 -5 - EST 1992 S 24 -6 - CST 1993 -5 - EST 1997 --6 Ap C%sT +-6 NI C%sT Z America/Panama -5:18:8 - LMT 1890 -5:19:36 - CMT 1908 Ap 22 -5 - EST -Li America/Panama America/Cayman +L America/Panama America/Cayman Z America/Puerto_Rico -4:24:25 - LMT 1899 Mar 28 12 -4 - AST 1942 May 3 --4 AE A%sT 1946 +-4 u A%sT 1946 -4 - AST Z America/Miquelon -3:44:40 - LMT 1911 May 15 -4 - AST 1980 May -3 - -03 1987 --3 AT -03/-02 +-3 C -03/-02 Z America/Grand_Turk -4:44:32 - LMT 1890 --5:7:11 - KMT 1912 F +-5:7:10 - KMT 1912 F -5 - EST 1979 --5 AE E%sT 2015 N Sun>=1 2 +-5 u E%sT 2015 N Su>=1 2 -4 - AST 2018 Mar 11 3 --5 AE E%sT -R Aq 1930 o - D 1 0 1 S -R Aq 1931 o - Ap 1 0 0 - -R Aq 1931 o - O 15 0 1 S -R Aq 1932 1940 - Mar 1 0 0 - -R Aq 1932 1939 - N 1 0 1 S -R Aq 1940 o - Jul 1 0 1 S -R Aq 1941 o - Jun 15 0 0 - -R Aq 1941 o - O 15 0 1 S -R Aq 1943 o - Au 1 0 0 - -R Aq 1943 o - O 15 0 1 S -R Aq 1946 o - Mar 1 0 0 - -R Aq 1946 o - O 1 0 1 S -R Aq 1963 o - O 1 0 0 - -R Aq 1963 o - D 15 0 1 S -R Aq 1964 1966 - Mar 1 0 0 - -R Aq 1964 1966 - O 15 0 1 S -R Aq 1967 o - Ap 2 0 0 - -R Aq 1967 1968 - O Sun>=1 0 1 S -R Aq 1968 1969 - Ap Sun>=1 0 0 - -R Aq 1974 o - Ja 23 0 1 S -R Aq 1974 o - May 1 0 0 - -R Aq 1988 o - D 1 0 1 S -R Aq 1989 1993 - Mar Sun>=1 0 0 - -R Aq 1989 1992 - O Sun>=15 0 1 S -R Aq 1999 o - O Sun>=1 0 1 S -R Aq 2000 o - Mar 3 0 0 - -R Aq 2007 o - D 30 0 1 S -R Aq 2008 2009 - Mar Sun>=15 0 0 - -R Aq 2008 o - O Sun>=15 0 1 S +-5 u E%sT +R A 1930 o - D 1 0 1 - +R A 1931 o - Ap 1 0 0 - +R A 1931 o - O 15 0 1 - +R A 1932 1940 - Mar 1 0 0 - +R A 1932 1939 - N 1 0 1 - +R A 1940 o - Jul 1 0 1 - +R A 1941 o - Jun 15 0 0 - +R A 1941 o - O 15 0 1 - +R A 1943 o - Au 1 0 0 - +R A 1943 o - O 15 0 1 - +R A 1946 o - Mar 1 0 0 - +R A 1946 o - O 1 0 1 - +R A 1963 o - O 1 0 0 - +R A 1963 o - D 15 0 1 - +R A 1964 1966 - Mar 1 0 0 - +R A 1964 1966 - O 15 0 1 - +R A 1967 o - Ap 2 0 0 - +R A 1967 1968 - O Su>=1 0 1 - +R A 1968 1969 - Ap Su>=1 0 0 - +R A 1974 o - Ja 23 0 1 - +R A 1974 o - May 1 0 0 - +R A 1988 o - D 1 0 1 - +R A 1989 1993 - Mar Su>=1 0 0 - +R A 1989 1992 - O Su>=15 0 1 - +R A 1999 o - O Su>=1 0 1 - +R A 2000 o - Mar 3 0 0 - +R A 2007 o - D 30 0 1 - +R A 2008 2009 - Mar Su>=15 0 0 - +R A 2008 o - O Su>=15 0 1 - Z America/Argentina/Buenos_Aires -3:53:48 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 --3 Aq -03/-02 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 Z America/Argentina/Cordoba -4:16:48 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 -4 - -04 1991 O 20 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 --3 Aq -03/-02 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 Z America/Argentina/Salta -4:21:40 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 -4 - -04 1991 O 20 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/Tucuman -4:20:52 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 -4 - -04 1991 O 20 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 Jun -4 - -04 2004 Jun 13 --3 Aq -03/-02 +-3 A -03/-02 Z America/Argentina/La_Rioja -4:27:24 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar -4 - -04 1991 May 7 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 Jun -4 - -04 2004 Jun 20 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/San_Juan -4:34:4 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar -4 - -04 1991 May 7 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 May 31 -4 - -04 2004 Jul 25 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/Jujuy -4:21:12 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1990 Mar 4 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 Mar 4 -4 - -04 1990 O 28 -4 1 -03 1991 Mar 17 -4 - -04 1991 O 6 -3 1 -02 1992 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/Catamarca -4:23:8 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1991 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1991 Mar 3 -4 - -04 1991 O 20 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 Jun -4 - -04 2004 Jun 20 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/Mendoza -4:35:16 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1990 Mar 4 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 Mar 4 -4 - -04 1990 O 15 -4 1 -03 1991 Mar -4 - -04 1991 O 15 -4 1 -03 1992 Mar -4 - -04 1992 O 18 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 May 23 -4 - -04 2004 S 26 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 -R Ar 2008 2009 - Mar Sun>=8 0 0 - -R Ar 2007 2008 - O Sun>=8 0 1 S +R Sa 2008 2009 - Mar Su>=8 0 0 - +R Sa 2007 2008 - O Su>=8 0 1 - Z America/Argentina/San_Luis -4:25:24 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1990 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1990 -3 1 -02 1990 Mar 14 -4 - -04 1990 O 15 -4 1 -03 1991 Mar @@ -3584,286 +3839,280 @@ Z America/Argentina/San_Luis -4:25:24 - LMT 1894 O 31 -4 1 -03 2000 Mar 3 -3 - -03 2004 May 31 -4 - -04 2004 Jul 25 --3 Aq -03/-02 2008 Ja 21 --4 Ar -04/-03 2009 O 11 +-3 A -03/-02 2008 Ja 21 +-4 Sa -04/-03 2009 O 11 -3 - -03 Z America/Argentina/Rio_Gallegos -4:36:52 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 Jun -4 - -04 2004 Jun 20 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 Z America/Argentina/Ushuaia -4:33:12 - LMT 1894 O 31 -4:16:48 - CMT 1920 May -4 - -04 1930 D --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1999 O 3 --4 Aq -04/-03 2000 Mar 3 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1999 O 3 +-4 A -04/-03 2000 Mar 3 -3 - -03 2004 May 30 -4 - -04 2004 Jun 20 --3 Aq -03/-02 2008 O 18 +-3 A -03/-02 2008 O 18 -3 - -03 -Li America/Curacao America/Aruba +L America/Curacao America/Aruba Z America/La_Paz -4:32:36 - LMT 1890 -4:32:36 - CMT 1931 O 15 -4:32:36 1 BST 1932 Mar 21 -4 - -04 -R As 1931 o - O 3 11 1 S -R As 1932 1933 - Ap 1 0 0 - -R As 1932 o - O 3 0 1 S -R As 1949 1952 - D 1 0 1 S -R As 1950 o - Ap 16 1 0 - -R As 1951 1952 - Ap 1 0 0 - -R As 1953 o - Mar 1 0 0 - -R As 1963 o - D 9 0 1 S -R As 1964 o - Mar 1 0 0 - -R As 1965 o - Ja 31 0 1 S -R As 1965 o - Mar 31 0 0 - -R As 1965 o - D 1 0 1 S -R As 1966 1968 - Mar 1 0 0 - -R As 1966 1967 - N 1 0 1 S -R As 1985 o - N 2 0 1 S -R As 1986 o - Mar 15 0 0 - -R As 1986 o - O 25 0 1 S -R As 1987 o - F 14 0 0 - -R As 1987 o - O 25 0 1 S -R As 1988 o - F 7 0 0 - -R As 1988 o - O 16 0 1 S -R As 1989 o - Ja 29 0 0 - -R As 1989 o - O 15 0 1 S -R As 1990 o - F 11 0 0 - -R As 1990 o - O 21 0 1 S -R As 1991 o - F 17 0 0 - -R As 1991 o - O 20 0 1 S -R As 1992 o - F 9 0 0 - -R As 1992 o - O 25 0 1 S -R As 1993 o - Ja 31 0 0 - -R As 1993 1995 - O Sun>=11 0 1 S -R As 1994 1995 - F Sun>=15 0 0 - -R As 1996 o - F 11 0 0 - -R As 1996 o - O 6 0 1 S -R As 1997 o - F 16 0 0 - -R As 1997 o - O 6 0 1 S -R As 1998 o - Mar 1 0 0 - -R As 1998 o - O 11 0 1 S -R As 1999 o - F 21 0 0 - -R As 1999 o - O 3 0 1 S -R As 2000 o - F 27 0 0 - -R As 2000 2001 - O Sun>=8 0 1 S -R As 2001 2006 - F Sun>=15 0 0 - -R As 2002 o - N 3 0 1 S -R As 2003 o - O 19 0 1 S -R As 2004 o - N 2 0 1 S -R As 2005 o - O 16 0 1 S -R As 2006 o - N 5 0 1 S -R As 2007 o - F 25 0 0 - -R As 2007 o - O Sun>=8 0 1 S -R As 2008 2017 - O Sun>=15 0 1 S -R As 2008 2011 - F Sun>=15 0 0 - -R As 2012 o - F Sun>=22 0 0 - -R As 2013 2014 - F Sun>=15 0 0 - -R As 2015 o - F Sun>=22 0 0 - -R As 2016 2022 - F Sun>=15 0 0 - -R As 2018 ma - N Sun>=1 0 1 S -R As 2023 o - F Sun>=22 0 0 - -R As 2024 2025 - F Sun>=15 0 0 - -R As 2026 o - F Sun>=22 0 0 - -R As 2027 2033 - F Sun>=15 0 0 - -R As 2034 o - F Sun>=22 0 0 - -R As 2035 2036 - F Sun>=15 0 0 - -R As 2037 o - F Sun>=22 0 0 - -R As 2038 ma - F Sun>=15 0 0 - +R B 1931 o - O 3 11 1 - +R B 1932 1933 - Ap 1 0 0 - +R B 1932 o - O 3 0 1 - +R B 1949 1952 - D 1 0 1 - +R B 1950 o - Ap 16 1 0 - +R B 1951 1952 - Ap 1 0 0 - +R B 1953 o - Mar 1 0 0 - +R B 1963 o - D 9 0 1 - +R B 1964 o - Mar 1 0 0 - +R B 1965 o - Ja 31 0 1 - +R B 1965 o - Mar 31 0 0 - +R B 1965 o - D 1 0 1 - +R B 1966 1968 - Mar 1 0 0 - +R B 1966 1967 - N 1 0 1 - +R B 1985 o - N 2 0 1 - +R B 1986 o - Mar 15 0 0 - +R B 1986 o - O 25 0 1 - +R B 1987 o - F 14 0 0 - +R B 1987 o - O 25 0 1 - +R B 1988 o - F 7 0 0 - +R B 1988 o - O 16 0 1 - +R B 1989 o - Ja 29 0 0 - +R B 1989 o - O 15 0 1 - +R B 1990 o - F 11 0 0 - +R B 1990 o - O 21 0 1 - +R B 1991 o - F 17 0 0 - +R B 1991 o - O 20 0 1 - +R B 1992 o - F 9 0 0 - +R B 1992 o - O 25 0 1 - +R B 1993 o - Ja 31 0 0 - +R B 1993 1995 - O Su>=11 0 1 - +R B 1994 1995 - F Su>=15 0 0 - +R B 1996 o - F 11 0 0 - +R B 1996 o - O 6 0 1 - +R B 1997 o - F 16 0 0 - +R B 1997 o - O 6 0 1 - +R B 1998 o - Mar 1 0 0 - +R B 1998 o - O 11 0 1 - +R B 1999 o - F 21 0 0 - +R B 1999 o - O 3 0 1 - +R B 2000 o - F 27 0 0 - +R B 2000 2001 - O Su>=8 0 1 - +R B 2001 2006 - F Su>=15 0 0 - +R B 2002 o - N 3 0 1 - +R B 2003 o - O 19 0 1 - +R B 2004 o - N 2 0 1 - +R B 2005 o - O 16 0 1 - +R B 2006 o - N 5 0 1 - +R B 2007 o - F 25 0 0 - +R B 2007 o - O Su>=8 0 1 - +R B 2008 2017 - O Su>=15 0 1 - +R B 2008 2011 - F Su>=15 0 0 - +R B 2012 o - F Su>=22 0 0 - +R B 2013 2014 - F Su>=15 0 0 - +R B 2015 o - F Su>=22 0 0 - +R B 2016 2019 - F Su>=15 0 0 - +R B 2018 o - N Su>=1 0 1 - Z America/Noronha -2:9:40 - LMT 1914 --2 As -02/-01 1990 S 17 +-2 B -02/-01 1990 S 17 -2 - -02 1999 S 30 --2 As -02/-01 2000 O 15 +-2 B -02/-01 2000 O 15 -2 - -02 2001 S 13 --2 As -02/-01 2002 O +-2 B -02/-01 2002 O -2 - -02 Z America/Belem -3:13:56 - LMT 1914 --3 As -03/-02 1988 S 12 +-3 B -03/-02 1988 S 12 -3 - -03 Z America/Santarem -3:38:48 - LMT 1914 --4 As -04/-03 1988 S 12 +-4 B -04/-03 1988 S 12 -4 - -04 2008 Jun 24 -3 - -03 Z America/Fortaleza -2:34 - LMT 1914 --3 As -03/-02 1990 S 17 +-3 B -03/-02 1990 S 17 -3 - -03 1999 S 30 --3 As -03/-02 2000 O 22 +-3 B -03/-02 2000 O 22 -3 - -03 2001 S 13 --3 As -03/-02 2002 O +-3 B -03/-02 2002 O -3 - -03 Z America/Recife -2:19:36 - LMT 1914 --3 As -03/-02 1990 S 17 +-3 B -03/-02 1990 S 17 -3 - -03 1999 S 30 --3 As -03/-02 2000 O 15 +-3 B -03/-02 2000 O 15 -3 - -03 2001 S 13 --3 As -03/-02 2002 O +-3 B -03/-02 2002 O -3 - -03 Z America/Araguaina -3:12:48 - LMT 1914 --3 As -03/-02 1990 S 17 +-3 B -03/-02 1990 S 17 -3 - -03 1995 S 14 --3 As -03/-02 2003 S 24 +-3 B -03/-02 2003 S 24 -3 - -03 2012 O 21 --3 As -03/-02 2013 S +-3 B -03/-02 2013 S -3 - -03 Z America/Maceio -2:22:52 - LMT 1914 --3 As -03/-02 1990 S 17 +-3 B -03/-02 1990 S 17 -3 - -03 1995 O 13 --3 As -03/-02 1996 S 4 +-3 B -03/-02 1996 S 4 -3 - -03 1999 S 30 --3 As -03/-02 2000 O 22 +-3 B -03/-02 2000 O 22 -3 - -03 2001 S 13 --3 As -03/-02 2002 O +-3 B -03/-02 2002 O -3 - -03 Z America/Bahia -2:34:4 - LMT 1914 --3 As -03/-02 2003 S 24 +-3 B -03/-02 2003 S 24 -3 - -03 2011 O 16 --3 As -03/-02 2012 O 21 +-3 B -03/-02 2012 O 21 -3 - -03 Z America/Sao_Paulo -3:6:28 - LMT 1914 --3 As -03/-02 1963 O 23 +-3 B -03/-02 1963 O 23 -3 1 -02 1964 --3 As -03/-02 +-3 B -03/-02 Z America/Campo_Grande -3:38:28 - LMT 1914 --4 As -04/-03 +-4 B -04/-03 Z America/Cuiaba -3:44:20 - LMT 1914 --4 As -04/-03 2003 S 24 +-4 B -04/-03 2003 S 24 -4 - -04 2004 O --4 As -04/-03 +-4 B -04/-03 Z America/Porto_Velho -4:15:36 - LMT 1914 --4 As -04/-03 1988 S 12 +-4 B -04/-03 1988 S 12 -4 - -04 Z America/Boa_Vista -4:2:40 - LMT 1914 --4 As -04/-03 1988 S 12 +-4 B -04/-03 1988 S 12 -4 - -04 1999 S 30 --4 As -04/-03 2000 O 15 +-4 B -04/-03 2000 O 15 -4 - -04 Z America/Manaus -4:0:4 - LMT 1914 --4 As -04/-03 1988 S 12 +-4 B -04/-03 1988 S 12 -4 - -04 1993 S 28 --4 As -04/-03 1994 S 22 +-4 B -04/-03 1994 S 22 -4 - -04 Z America/Eirunepe -4:39:28 - LMT 1914 --5 As -05/-04 1988 S 12 +-5 B -05/-04 1988 S 12 -5 - -05 1993 S 28 --5 As -05/-04 1994 S 22 +-5 B -05/-04 1994 S 22 -5 - -05 2008 Jun 24 -4 - -04 2013 N 10 -5 - -05 Z America/Rio_Branco -4:31:12 - LMT 1914 --5 As -05/-04 1988 S 12 +-5 B -05/-04 1988 S 12 -5 - -05 2008 Jun 24 -4 - -04 2013 N 10 -5 - -05 -R At 1927 1931 - S 1 0 1 S -R At 1928 1932 - Ap 1 0 0 - -R At 1968 o - N 3 4u 1 S -R At 1969 o - Mar 30 3u 0 - -R At 1969 o - N 23 4u 1 S -R At 1970 o - Mar 29 3u 0 - -R At 1971 o - Mar 14 3u 0 - -R At 1970 1972 - O Sun>=9 4u 1 S -R At 1972 1986 - Mar Sun>=9 3u 0 - -R At 1973 o - S 30 4u 1 S -R At 1974 1987 - O Sun>=9 4u 1 S -R At 1987 o - Ap 12 3u 0 - -R At 1988 1990 - Mar Sun>=9 3u 0 - -R At 1988 1989 - O Sun>=9 4u 1 S -R At 1990 o - S 16 4u 1 S -R At 1991 1996 - Mar Sun>=9 3u 0 - -R At 1991 1997 - O Sun>=9 4u 1 S -R At 1997 o - Mar 30 3u 0 - -R At 1998 o - Mar Sun>=9 3u 0 - -R At 1998 o - S 27 4u 1 S -R At 1999 o - Ap 4 3u 0 - -R At 1999 2010 - O Sun>=9 4u 1 S -R At 2000 2007 - Mar Sun>=9 3u 0 - -R At 2008 o - Mar 30 3u 0 - -R At 2009 o - Mar Sun>=9 3u 0 - -R At 2010 o - Ap Sun>=1 3u 0 - -R At 2011 o - May Sun>=2 3u 0 - -R At 2011 o - Au Sun>=16 4u 1 S -R At 2012 2014 - Ap Sun>=23 3u 0 - -R At 2012 2014 - S Sun>=2 4u 1 S -R At 2016 ma - May Sun>=9 3u 0 - -R At 2016 ma - Au Sun>=9 4u 1 S +R x 1927 1931 - S 1 0 1 - +R x 1928 1932 - Ap 1 0 0 - +R x 1968 o - N 3 4u 1 - +R x 1969 o - Mar 30 3u 0 - +R x 1969 o - N 23 4u 1 - +R x 1970 o - Mar 29 3u 0 - +R x 1971 o - Mar 14 3u 0 - +R x 1970 1972 - O Su>=9 4u 1 - +R x 1972 1986 - Mar Su>=9 3u 0 - +R x 1973 o - S 30 4u 1 - +R x 1974 1987 - O Su>=9 4u 1 - +R x 1987 o - Ap 12 3u 0 - +R x 1988 1990 - Mar Su>=9 3u 0 - +R x 1988 1989 - O Su>=9 4u 1 - +R x 1990 o - S 16 4u 1 - +R x 1991 1996 - Mar Su>=9 3u 0 - +R x 1991 1997 - O Su>=9 4u 1 - +R x 1997 o - Mar 30 3u 0 - +R x 1998 o - Mar Su>=9 3u 0 - +R x 1998 o - S 27 4u 1 - +R x 1999 o - Ap 4 3u 0 - +R x 1999 2010 - O Su>=9 4u 1 - +R x 2000 2007 - Mar Su>=9 3u 0 - +R x 2008 o - Mar 30 3u 0 - +R x 2009 o - Mar Su>=9 3u 0 - +R x 2010 o - Ap Su>=1 3u 0 - +R x 2011 o - May Su>=2 3u 0 - +R x 2011 o - Au Su>=16 4u 1 - +R x 2012 2014 - Ap Su>=23 3u 0 - +R x 2012 2014 - S Su>=2 4u 1 - +R x 2016 2018 - May Su>=9 3u 0 - +R x 2016 2018 - Au Su>=9 4u 1 - +R x 2019 ma - Ap Su>=2 3u 0 - +R x 2019 ma - S Su>=2 4u 1 - Z America/Santiago -4:42:46 - LMT 1890 -4:42:46 - SMT 1910 Ja 10 -5 - -05 1916 Jul -4:42:46 - SMT 1918 S 10 -4 - -04 1919 Jul -4:42:46 - SMT 1927 S --5 At -05/-04 1932 S +-5 x -05/-04 1932 S -4 - -04 1942 Jun -5 - -05 1942 Au -4 - -04 1946 Jul 15 -4 1 -03 1946 S -4 - -04 1947 Ap -5 - -05 1947 May 21 23 --4 At -04/-03 +-4 x -04/-03 Z America/Punta_Arenas -4:43:40 - LMT 1890 -4:42:46 - SMT 1910 Ja 10 -5 - -05 1916 Jul -4:42:46 - SMT 1918 S 10 -4 - -04 1919 Jul -4:42:46 - SMT 1927 S --5 At -05/-04 1932 S +-5 x -05/-04 1932 S -4 - -04 1942 Jun -5 - -05 1942 Au -4 - -04 1947 Ap -5 - -05 1947 May 21 23 --4 At -04/-03 2016 D 4 +-4 x -04/-03 2016 D 4 -3 - -03 Z Pacific/Easter -7:17:28 - LMT 1890 -7:17:28 - EMT 1932 S --7 At -07/-06 1982 Mar 14 3u --6 At -06/-05 +-7 x -07/-06 1982 Mar 14 3u +-6 x -06/-05 Z Antarctica/Palmer 0 - -00 1965 --4 Aq -04/-03 1969 O 5 --3 Aq -03/-02 1982 May --4 At -04/-03 2016 D 4 +-4 A -04/-03 1969 O 5 +-3 A -03/-02 1982 May +-4 x -04/-03 2016 D 4 -3 - -03 -R Au 1992 o - May 3 0 1 S -R Au 1993 o - Ap 4 0 0 - +R CO 1992 o - May 3 0 1 - +R CO 1993 o - Ap 4 0 0 - Z America/Bogota -4:56:16 - LMT 1884 Mar 13 -4:56:16 - BMT 1914 N 23 --5 Au -05/-04 +-5 CO -05/-04 Z America/Curacao -4:35:47 - LMT 1912 F 12 -4:30 - -0430 1965 -4 - AST -Li America/Curacao America/Lower_Princes -Li America/Curacao America/Kralendijk -R Av 1992 o - N 28 0 1 S -R Av 1993 o - F 5 0 0 - +L America/Curacao America/Lower_Princes +L America/Curacao America/Kralendijk +R EC 1992 o - N 28 0 1 - +R EC 1993 o - F 5 0 0 - Z America/Guayaquil -5:19:20 - LMT 1890 -5:14 - QMT 1931 --5 Av -05/-04 +-5 EC -05/-04 Z Pacific/Galapagos -5:58:24 - LMT 1931 -5 - -05 1986 --6 Av -06/-05 -R Aw 1937 1938 - S lastSun 0 1 S -R Aw 1938 1942 - Mar Sun>=19 0 0 - -R Aw 1939 o - O 1 0 1 S -R Aw 1940 1942 - S lastSun 0 1 S -R Aw 1943 o - Ja 1 0 0 - -R Aw 1983 o - S lastSun 0 1 S -R Aw 1984 1985 - Ap lastSun 0 0 - -R Aw 1984 o - S 16 0 1 S -R Aw 1985 2000 - S Sun>=9 0 1 S -R Aw 1986 2000 - Ap Sun>=16 0 0 - -R Aw 2001 2010 - Ap Sun>=15 2 0 - -R Aw 2001 2010 - S Sun>=1 2 1 S +-6 EC -06/-05 +R FK 1937 1938 - S lastSu 0 1 - +R FK 1938 1942 - Mar Su>=19 0 0 - +R FK 1939 o - O 1 0 1 - +R FK 1940 1942 - S lastSu 0 1 - +R FK 1943 o - Ja 1 0 0 - +R FK 1983 o - S lastSu 0 1 - +R FK 1984 1985 - Ap lastSu 0 0 - +R FK 1984 o - S 16 0 1 - +R FK 1985 2000 - S Su>=9 0 1 - +R FK 1986 2000 - Ap Su>=16 0 0 - +R FK 2001 2010 - Ap Su>=15 2 0 - +R FK 2001 2010 - S Su>=1 2 1 - Z Atlantic/Stanley -3:51:24 - LMT 1890 -3:51:24 - SMT 1912 Mar 12 --4 Aw -04/-03 1983 May --3 Aw -03/-02 1985 S 15 --4 Aw -04/-03 2010 S 5 2 +-4 FK -04/-03 1983 May +-3 FK -03/-02 1985 S 15 +-4 FK -04/-03 2010 S 5 2 -3 - -03 Z America/Cayenne -3:29:20 - LMT 1911 Jul -4 - -04 1967 O @@ -3872,46 +4121,46 @@ Z America/Guyana -3:52:40 - LMT 1915 Mar -3:45 - -0345 1975 Jul 31 -3 - -03 1991 -4 - -04 -R Ax 1975 1988 - O 1 0 1 S -R Ax 1975 1978 - Mar 1 0 0 - -R Ax 1979 1991 - Ap 1 0 0 - -R Ax 1989 o - O 22 0 1 S -R Ax 1990 o - O 1 0 1 S -R Ax 1991 o - O 6 0 1 S -R Ax 1992 o - Mar 1 0 0 - -R Ax 1992 o - O 5 0 1 S -R Ax 1993 o - Mar 31 0 0 - -R Ax 1993 1995 - O 1 0 1 S -R Ax 1994 1995 - F lastSun 0 0 - -R Ax 1996 o - Mar 1 0 0 - -R Ax 1996 2001 - O Sun>=1 0 1 S -R Ax 1997 o - F lastSun 0 0 - -R Ax 1998 2001 - Mar Sun>=1 0 0 - -R Ax 2002 2004 - Ap Sun>=1 0 0 - -R Ax 2002 2003 - S Sun>=1 0 1 S -R Ax 2004 2009 - O Sun>=15 0 1 S -R Ax 2005 2009 - Mar Sun>=8 0 0 - -R Ax 2010 ma - O Sun>=1 0 1 S -R Ax 2010 2012 - Ap Sun>=8 0 0 - -R Ax 2013 ma - Mar Sun>=22 0 0 - +R y 1975 1988 - O 1 0 1 - +R y 1975 1978 - Mar 1 0 0 - +R y 1979 1991 - Ap 1 0 0 - +R y 1989 o - O 22 0 1 - +R y 1990 o - O 1 0 1 - +R y 1991 o - O 6 0 1 - +R y 1992 o - Mar 1 0 0 - +R y 1992 o - O 5 0 1 - +R y 1993 o - Mar 31 0 0 - +R y 1993 1995 - O 1 0 1 - +R y 1994 1995 - F lastSu 0 0 - +R y 1996 o - Mar 1 0 0 - +R y 1996 2001 - O Su>=1 0 1 - +R y 1997 o - F lastSu 0 0 - +R y 1998 2001 - Mar Su>=1 0 0 - +R y 2002 2004 - Ap Su>=1 0 0 - +R y 2002 2003 - S Su>=1 0 1 - +R y 2004 2009 - O Su>=15 0 1 - +R y 2005 2009 - Mar Su>=8 0 0 - +R y 2010 ma - O Su>=1 0 1 - +R y 2010 2012 - Ap Su>=8 0 0 - +R y 2013 ma - Mar Su>=22 0 0 - Z America/Asuncion -3:50:40 - LMT 1890 -3:50:40 - AMT 1931 O 10 -4 - -04 1972 O -3 - -03 1974 Ap --4 Ax -04/-03 -R Ay 1938 o - Ja 1 0 1 S -R Ay 1938 o - Ap 1 0 0 - -R Ay 1938 1939 - S lastSun 0 1 S -R Ay 1939 1940 - Mar Sun>=24 0 0 - -R Ay 1986 1987 - Ja 1 0 1 S -R Ay 1986 1987 - Ap 1 0 0 - -R Ay 1990 o - Ja 1 0 1 S -R Ay 1990 o - Ap 1 0 0 - -R Ay 1994 o - Ja 1 0 1 S -R Ay 1994 o - Ap 1 0 0 - +-4 y -04/-03 +R PE 1938 o - Ja 1 0 1 - +R PE 1938 o - Ap 1 0 0 - +R PE 1938 1939 - S lastSu 0 1 - +R PE 1939 1940 - Mar Su>=24 0 0 - +R PE 1986 1987 - Ja 1 0 1 - +R PE 1986 1987 - Ap 1 0 0 - +R PE 1990 o - Ja 1 0 1 - +R PE 1990 o - Ap 1 0 0 - +R PE 1994 o - Ja 1 0 1 - +R PE 1994 o - Ap 1 0 0 - Z America/Lima -5:8:12 - LMT 1890 -5:8:36 - LMT 1908 Jul 28 --5 Ay -05/-04 +-5 PE -05/-04 Z Atlantic/South_Georgia -2:26:8 - LMT 1890 -2 - -02 Z America/Paramaribo -3:40:40 - LMT 1911 @@ -3921,72 +4170,78 @@ Z America/Paramaribo -3:40:40 - LMT 1911 -3 - -03 Z America/Port_of_Spain -4:6:4 - LMT 1912 Mar 2 -4 - AST -Li America/Port_of_Spain America/Anguilla -Li America/Port_of_Spain America/Antigua -Li America/Port_of_Spain America/Dominica -Li America/Port_of_Spain America/Grenada -Li America/Port_of_Spain America/Guadeloupe -Li America/Port_of_Spain America/Marigot -Li America/Port_of_Spain America/Montserrat -Li America/Port_of_Spain America/St_Barthelemy -Li America/Port_of_Spain America/St_Kitts -Li America/Port_of_Spain America/St_Lucia -Li America/Port_of_Spain America/St_Thomas -Li America/Port_of_Spain America/St_Vincent -Li America/Port_of_Spain America/Tortola -R Az 1923 o - O 2 0 0:30 HS -R Az 1924 1926 - Ap 1 0 0 - -R Az 1924 1925 - O 1 0 0:30 HS -R Az 1933 1935 - O lastSun 0 0:30 HS -R Az 1934 1936 - Mar Sat>=25 23:30s 0 - -R Az 1936 o - N 1 0 0:30 HS -R Az 1937 1941 - Mar lastSun 0 0 - -R Az 1937 1940 - O lastSun 0 0:30 HS -R Az 1941 o - Au 1 0 0:30 HS -R Az 1942 o - Ja 1 0 0 - -R Az 1942 o - D 14 0 1 S -R Az 1943 o - Mar 14 0 0 - -R Az 1959 o - May 24 0 1 S -R Az 1959 o - N 15 0 0 - -R Az 1960 o - Ja 17 0 1 S -R Az 1960 o - Mar 6 0 0 - -R Az 1965 1967 - Ap Sun>=1 0 1 S -R Az 1965 o - S 26 0 0 - -R Az 1966 1967 - O 31 0 0 - -R Az 1968 1970 - May 27 0 0:30 HS -R Az 1968 1970 - D 2 0 0 - -R Az 1972 o - Ap 24 0 1 S -R Az 1972 o - Au 15 0 0 - -R Az 1974 o - Mar 10 0 0:30 HS -R Az 1974 o - D 22 0 1 S -R Az 1976 o - O 1 0 0 - -R Az 1977 o - D 4 0 1 S -R Az 1978 o - Ap 1 0 0 - -R Az 1979 o - O 1 0 1 S -R Az 1980 o - May 1 0 0 - -R Az 1987 o - D 14 0 1 S -R Az 1988 o - Mar 14 0 0 - -R Az 1988 o - D 11 0 1 S -R Az 1989 o - Mar 12 0 0 - -R Az 1989 o - O 29 0 1 S -R Az 1990 1992 - Mar Sun>=1 0 0 - -R Az 1990 1991 - O Sun>=21 0 1 S -R Az 1992 o - O 18 0 1 S -R Az 1993 o - F 28 0 0 - -R Az 2004 o - S 19 0 1 S -R Az 2005 o - Mar 27 2 0 - -R Az 2005 o - O 9 2 1 S -R Az 2006 o - Mar 12 2 0 - -R Az 2006 2014 - O Sun>=1 2 1 S -R Az 2007 2015 - Mar Sun>=8 2 0 - -Z America/Montevideo -3:44:44 - LMT 1898 Jun 28 --3:44:44 - MMT 1920 May --3:30 Az -0330/-03 1942 D 14 --3 Az -03/-02 1968 --3 Az -03/-0230 1971 --3 Az -03/-02 1974 --3 Az -03/-0230 1974 D 22 --3 Az -03/-02 +L America/Port_of_Spain America/Anguilla +L America/Port_of_Spain America/Antigua +L America/Port_of_Spain America/Dominica +L America/Port_of_Spain America/Grenada +L America/Port_of_Spain America/Guadeloupe +L America/Port_of_Spain America/Marigot +L America/Port_of_Spain America/Montserrat +L America/Port_of_Spain America/St_Barthelemy +L America/Port_of_Spain America/St_Kitts +L America/Port_of_Spain America/St_Lucia +L America/Port_of_Spain America/St_Thomas +L America/Port_of_Spain America/St_Vincent +L America/Port_of_Spain America/Tortola +R U 1923 1925 - O 1 0 0:30 - +R U 1924 1926 - Ap 1 0 0 - +R U 1933 1938 - O lastSu 0 0:30 - +R U 1934 1941 - Mar lastSa 24 0 - +R U 1939 o - O 1 0 0:30 - +R U 1940 o - O 27 0 0:30 - +R U 1941 o - Au 1 0 0:30 - +R U 1942 o - D 14 0 0:30 - +R U 1943 o - Mar 14 0 0 - +R U 1959 o - May 24 0 0:30 - +R U 1959 o - N 15 0 0 - +R U 1960 o - Ja 17 0 1 - +R U 1960 o - Mar 6 0 0 - +R U 1965 o - Ap 4 0 1 - +R U 1965 o - S 26 0 0 - +R U 1968 o - May 27 0 0:30 - +R U 1968 o - D 1 0 0 - +R U 1970 o - Ap 25 0 1 - +R U 1970 o - Jun 14 0 0 - +R U 1972 o - Ap 23 0 1 - +R U 1972 o - Jul 16 0 0 - +R U 1974 o - Ja 13 0 1:30 - +R U 1974 o - Mar 10 0 0:30 - +R U 1974 o - S 1 0 0 - +R U 1974 o - D 22 0 1 - +R U 1975 o - Mar 30 0 0 - +R U 1976 o - D 19 0 1 - +R U 1977 o - Mar 6 0 0 - +R U 1977 o - D 4 0 1 - +R U 1978 1979 - Mar Su>=1 0 0 - +R U 1978 o - D 17 0 1 - +R U 1979 o - Ap 29 0 1 - +R U 1980 o - Mar 16 0 0 - +R U 1987 o - D 14 0 1 - +R U 1988 o - F 28 0 0 - +R U 1988 o - D 11 0 1 - +R U 1989 o - Mar 5 0 0 - +R U 1989 o - O 29 0 1 - +R U 1990 o - F 25 0 0 - +R U 1990 1991 - O Su>=21 0 1 - +R U 1991 1992 - Mar Su>=1 0 0 - +R U 1992 o - O 18 0 1 - +R U 1993 o - F 28 0 0 - +R U 2004 o - S 19 0 1 - +R U 2005 o - Mar 27 2 0 - +R U 2005 o - O 9 2 1 - +R U 2006 2015 - Mar Su>=8 2 0 - +R U 2006 2014 - O Su>=1 2 1 - +Z America/Montevideo -3:44:51 - LMT 1908 Jun 10 +-3:44:51 - MMT 1920 May +-4 - -04 1923 O +-3:30 U -0330/-03 1942 D 14 +-3 U -03/-0230 1960 +-3 U -03/-02 1968 +-3 U -03/-0230 1970 +-3 U -03/-02 1974 +-3 U -03/-0130 1974 Mar 10 +-3 U -03/-0230 1974 D 22 +-3 U -03/-02 Z America/Caracas -4:27:44 - LMT 1890 -4:27:40 - CMT 1912 F 12 -4:30 - -0430 1965 @@ -3995,14 +4250,13 @@ Z America/Caracas -4:27:44 - LMT 1890 -4 - -04 Z Etc/GMT 0 - GMT Z Etc/UTC 0 - UTC -Z Etc/UCT 0 - UCT -Li Etc/GMT GMT -Li Etc/UTC Etc/Universal -Li Etc/UTC Etc/Zulu -Li Etc/GMT Etc/Greenwich -Li Etc/GMT Etc/GMT-0 -Li Etc/GMT Etc/GMT+0 -Li Etc/GMT Etc/GMT0 +L Etc/GMT GMT +L Etc/UTC Etc/Universal +L Etc/UTC Etc/Zulu +L Etc/GMT Etc/Greenwich +L Etc/GMT Etc/GMT-0 +L Etc/GMT Etc/GMT+0 +L Etc/GMT Etc/GMT0 Z Etc/GMT-14 14 - +14 Z Etc/GMT-13 13 - +13 Z Etc/GMT-12 12 - +12 @@ -4030,121 +4284,122 @@ Z Etc/GMT+10 -10 - -10 Z Etc/GMT+11 -11 - -11 Z Etc/GMT+12 -12 - -12 Z Factory 0 - -00 -Li Africa/Nairobi Africa/Asmera -Li Africa/Abidjan Africa/Timbuktu -Li America/Argentina/Catamarca America/Argentina/ComodRivadavia -Li America/Adak America/Atka -Li America/Argentina/Buenos_Aires America/Buenos_Aires -Li America/Argentina/Catamarca America/Catamarca -Li America/Atikokan America/Coral_Harbour -Li America/Argentina/Cordoba America/Cordoba -Li America/Tijuana America/Ensenada -Li America/Indiana/Indianapolis America/Fort_Wayne -Li America/Indiana/Indianapolis America/Indianapolis -Li America/Argentina/Jujuy America/Jujuy -Li America/Indiana/Knox America/Knox_IN -Li America/Kentucky/Louisville America/Louisville -Li America/Argentina/Mendoza America/Mendoza -Li America/Toronto America/Montreal -Li America/Rio_Branco America/Porto_Acre -Li America/Argentina/Cordoba America/Rosario -Li America/Tijuana America/Santa_Isabel -Li America/Denver America/Shiprock -Li America/Port_of_Spain America/Virgin -Li Pacific/Auckland Antarctica/South_Pole -Li Asia/Ashgabat Asia/Ashkhabad -Li Asia/Kolkata Asia/Calcutta -Li Asia/Shanghai Asia/Chongqing -Li Asia/Shanghai Asia/Chungking -Li Asia/Dhaka Asia/Dacca -Li Asia/Shanghai Asia/Harbin -Li Asia/Urumqi Asia/Kashgar -Li Asia/Kathmandu Asia/Katmandu -Li Asia/Macau Asia/Macao -Li Asia/Yangon Asia/Rangoon -Li Asia/Ho_Chi_Minh Asia/Saigon -Li Asia/Jerusalem Asia/Tel_Aviv -Li Asia/Thimphu Asia/Thimbu -Li Asia/Makassar Asia/Ujung_Pandang -Li Asia/Ulaanbaatar Asia/Ulan_Bator -Li Atlantic/Faroe Atlantic/Faeroe -Li Europe/Oslo Atlantic/Jan_Mayen -Li Australia/Sydney Australia/ACT -Li Australia/Sydney Australia/Canberra -Li Australia/Lord_Howe Australia/LHI -Li Australia/Sydney Australia/NSW -Li Australia/Darwin Australia/North -Li Australia/Brisbane Australia/Queensland -Li Australia/Adelaide Australia/South -Li Australia/Hobart Australia/Tasmania -Li Australia/Melbourne Australia/Victoria -Li Australia/Perth Australia/West -Li Australia/Broken_Hill Australia/Yancowinna -Li America/Rio_Branco Brazil/Acre -Li America/Noronha Brazil/DeNoronha -Li America/Sao_Paulo Brazil/East -Li America/Manaus Brazil/West -Li America/Halifax Canada/Atlantic -Li America/Winnipeg Canada/Central -Li America/Toronto Canada/Eastern -Li America/Edmonton Canada/Mountain -Li America/St_Johns Canada/Newfoundland -Li America/Vancouver Canada/Pacific -Li America/Regina Canada/Saskatchewan -Li America/Whitehorse Canada/Yukon -Li America/Santiago Chile/Continental -Li Pacific/Easter Chile/EasterIsland -Li America/Havana Cuba -Li Africa/Cairo Egypt -Li Europe/Dublin Eire -Li Europe/London Europe/Belfast -Li Europe/Chisinau Europe/Tiraspol -Li Europe/London GB -Li Europe/London GB-Eire -Li Etc/GMT GMT+0 -Li Etc/GMT GMT-0 -Li Etc/GMT GMT0 -Li Etc/GMT Greenwich -Li Asia/Hong_Kong Hongkong -Li Atlantic/Reykjavik Iceland -Li Asia/Tehran Iran -Li Asia/Jerusalem Israel -Li America/Jamaica Jamaica -Li Asia/Tokyo Japan -Li Pacific/Kwajalein Kwajalein -Li Africa/Tripoli Libya -Li America/Tijuana Mexico/BajaNorte -Li America/Mazatlan Mexico/BajaSur -Li America/Mexico_City Mexico/General -Li Pacific/Auckland NZ -Li Pacific/Chatham NZ-CHAT -Li America/Denver Navajo -Li Asia/Shanghai PRC -Li Pacific/Honolulu Pacific/Johnston -Li Pacific/Pohnpei Pacific/Ponape -Li Pacific/Pago_Pago Pacific/Samoa -Li Pacific/Chuuk Pacific/Truk -Li Pacific/Chuuk Pacific/Yap -Li Europe/Warsaw Poland -Li Europe/Lisbon Portugal -Li Asia/Taipei ROC -Li Asia/Seoul ROK -Li Asia/Singapore Singapore -Li Europe/Istanbul Turkey -Li Etc/UCT UCT -Li America/Anchorage US/Alaska -Li America/Adak US/Aleutian -Li America/Phoenix US/Arizona -Li America/Chicago US/Central -Li America/Indiana/Indianapolis US/East-Indiana -Li America/New_York US/Eastern -Li Pacific/Honolulu US/Hawaii -Li America/Indiana/Knox US/Indiana-Starke -Li America/Detroit US/Michigan -Li America/Denver US/Mountain -Li America/Los_Angeles US/Pacific -Li Pacific/Pago_Pago US/Samoa -Li Etc/UTC UTC -Li Etc/UTC Universal -Li Europe/Moscow W-SU -Li Etc/UTC Zulu +L Africa/Nairobi Africa/Asmera +L Africa/Abidjan Africa/Timbuktu +L America/Argentina/Catamarca America/Argentina/ComodRivadavia +L America/Adak America/Atka +L America/Argentina/Buenos_Aires America/Buenos_Aires +L America/Argentina/Catamarca America/Catamarca +L America/Atikokan America/Coral_Harbour +L America/Argentina/Cordoba America/Cordoba +L America/Tijuana America/Ensenada +L America/Indiana/Indianapolis America/Fort_Wayne +L America/Indiana/Indianapolis America/Indianapolis +L America/Argentina/Jujuy America/Jujuy +L America/Indiana/Knox America/Knox_IN +L America/Kentucky/Louisville America/Louisville +L America/Argentina/Mendoza America/Mendoza +L America/Toronto America/Montreal +L America/Rio_Branco America/Porto_Acre +L America/Argentina/Cordoba America/Rosario +L America/Tijuana America/Santa_Isabel +L America/Denver America/Shiprock +L America/Port_of_Spain America/Virgin +L Pacific/Auckland Antarctica/South_Pole +L Asia/Ashgabat Asia/Ashkhabad +L Asia/Kolkata Asia/Calcutta +L Asia/Shanghai Asia/Chongqing +L Asia/Shanghai Asia/Chungking +L Asia/Dhaka Asia/Dacca +L Asia/Shanghai Asia/Harbin +L Asia/Urumqi Asia/Kashgar +L Asia/Kathmandu Asia/Katmandu +L Asia/Macau Asia/Macao +L Asia/Yangon Asia/Rangoon +L Asia/Ho_Chi_Minh Asia/Saigon +L Asia/Jerusalem Asia/Tel_Aviv +L Asia/Thimphu Asia/Thimbu +L Asia/Makassar Asia/Ujung_Pandang +L Asia/Ulaanbaatar Asia/Ulan_Bator +L Atlantic/Faroe Atlantic/Faeroe +L Europe/Oslo Atlantic/Jan_Mayen +L Australia/Sydney Australia/ACT +L Australia/Sydney Australia/Canberra +L Australia/Lord_Howe Australia/LHI +L Australia/Sydney Australia/NSW +L Australia/Darwin Australia/North +L Australia/Brisbane Australia/Queensland +L Australia/Adelaide Australia/South +L Australia/Hobart Australia/Tasmania +L Australia/Melbourne Australia/Victoria +L Australia/Perth Australia/West +L Australia/Broken_Hill Australia/Yancowinna +L America/Rio_Branco Brazil/Acre +L America/Noronha Brazil/DeNoronha +L America/Sao_Paulo Brazil/East +L America/Manaus Brazil/West +L America/Halifax Canada/Atlantic +L America/Winnipeg Canada/Central +L America/Toronto Canada/Eastern +L America/Edmonton Canada/Mountain +L America/St_Johns Canada/Newfoundland +L America/Vancouver Canada/Pacific +L America/Regina Canada/Saskatchewan +L America/Whitehorse Canada/Yukon +L America/Santiago Chile/Continental +L Pacific/Easter Chile/EasterIsland +L America/Havana Cuba +L Africa/Cairo Egypt +L Europe/Dublin Eire +L Etc/UTC Etc/UCT +L Europe/London Europe/Belfast +L Europe/Chisinau Europe/Tiraspol +L Europe/London GB +L Europe/London GB-Eire +L Etc/GMT GMT+0 +L Etc/GMT GMT-0 +L Etc/GMT GMT0 +L Etc/GMT Greenwich +L Asia/Hong_Kong Hongkong +L Atlantic/Reykjavik Iceland +L Asia/Tehran Iran +L Asia/Jerusalem Israel +L America/Jamaica Jamaica +L Asia/Tokyo Japan +L Pacific/Kwajalein Kwajalein +L Africa/Tripoli Libya +L America/Tijuana Mexico/BajaNorte +L America/Mazatlan Mexico/BajaSur +L America/Mexico_City Mexico/General +L Pacific/Auckland NZ +L Pacific/Chatham NZ-CHAT +L America/Denver Navajo +L Asia/Shanghai PRC +L Pacific/Honolulu Pacific/Johnston +L Pacific/Pohnpei Pacific/Ponape +L Pacific/Pago_Pago Pacific/Samoa +L Pacific/Chuuk Pacific/Truk +L Pacific/Chuuk Pacific/Yap +L Europe/Warsaw Poland +L Europe/Lisbon Portugal +L Asia/Taipei ROC +L Asia/Seoul ROK +L Asia/Singapore Singapore +L Europe/Istanbul Turkey +L Etc/UTC UCT +L America/Anchorage US/Alaska +L America/Adak US/Aleutian +L America/Phoenix US/Arizona +L America/Chicago US/Central +L America/Indiana/Indianapolis US/East-Indiana +L America/New_York US/Eastern +L Pacific/Honolulu US/Hawaii +L America/Indiana/Knox US/Indiana-Starke +L America/Detroit US/Michigan +L America/Denver US/Mountain +L America/Los_Angeles US/Pacific +L Pacific/Pago_Pago US/Samoa +L Etc/UTC UTC +L Etc/UTC Universal +L Europe/Moscow W-SU +L Etc/UTC Zulu diff --git a/src/timezone/known_abbrevs.txt b/src/timezone/known_abbrevs.txt index 4db831c62d3..77b90b858a3 100644 --- a/src/timezone/known_abbrevs.txt +++ b/src/timezone/known_abbrevs.txt @@ -22,6 +22,7 @@ +11 39600 +11 39600 D +12 43200 ++12 43200 D +1245 45900 +13 46800 +13 46800 D @@ -70,15 +71,15 @@ EEST 10800 D EET 7200 EST -18000 GMT 0 +GMT 0 D HDT -32400 D HKT 28800 HST -36000 IDT 10800 D IST 19800 -IST 3600 D +IST 3600 IST 7200 JST 32400 -KST 30600 KST 32400 MDT -21600 D MEST 7200 D @@ -92,9 +93,9 @@ NZST 43200 PDT -25200 D PKT 18000 PST -28800 +PST 28800 SAST 7200 SST -39600 -UCT 0 UTC 0 WAT 3600 WEST 3600 D diff --git a/src/timezone/localtime.c b/src/timezone/localtime.c index 2b5b3a924fe..333f27300aa 100644 --- a/src/timezone/localtime.c +++ b/src/timezone/localtime.c @@ -1,3 +1,5 @@ +/* Convert timestamp from pg_time_t to struct pg_tm. */ + /* * This file is in the public domain, so clarified as of * 1996-06-05 by Arthur David Olson. @@ -34,7 +36,7 @@ * in which Daylight Saving Time is never observed. * 4. They might reference tzname[0] after setting to a time zone * in which Standard Time is never observed. - * 5. They might reference tm.TM_ZONE after calling offtime. + * 5. They might reference tm.tm_zone after calling offtime. * What's best to do in the above cases is open to debate; * for now, we just set things up so that in any of the five cases * WILDABBR is used. Another possibility: initialize tzname[0] to the @@ -54,15 +56,14 @@ static const char gmt[] = "GMT"; * PG: We cache the result of trying to load the TZDEFRULES zone here. * tzdefrules_loaded is 0 if not tried yet, +1 if good, -1 if failed. */ -static struct state tzdefrules_s; +static struct state *tzdefrules_s = NULL; static int tzdefrules_loaded = 0; /* * The DST rules to use if TZ has no rules and we can't load TZDEFRULES. * Default to US rules as of 2017-05-07. - * POSIX 1003.1 section 8.1.1 says that the default DST rules are - * implementation dependent; for historical reasons, US rules are a - * common default. + * POSIX does not specify the default DST rules; + * for historical reasons, US rules are a common default. */ #define TZDEFRULESTRING ",M3.2.0,M11.1.0" @@ -92,7 +93,7 @@ static struct pg_tm *gmtsub(pg_time_t const *, int32, struct pg_tm *); static bool increment_overflow(int *, int); static bool increment_overflow_time(pg_time_t *, int32); static struct pg_tm *timesub(pg_time_t const *, int32, struct state const *, - struct pg_tm *); + struct pg_tm *); static bool typesequiv(struct state const *, int, int); @@ -106,19 +107,19 @@ static bool typesequiv(struct state const *, int, int); static struct pg_tm tm; -/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */ +/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */ static void -init_ttinfo(struct ttinfo *s, int32 gmtoff, bool isdst, int abbrind) +init_ttinfo(struct ttinfo *s, int32 utoff, bool isdst, int desigidx) { - s->tt_gmtoff = gmtoff; + s->tt_utoff = utoff; s->tt_isdst = isdst; - s->tt_abbrind = abbrind; + s->tt_desigidx = desigidx; s->tt_ttisstd = false; - s->tt_ttisgmt = false; + s->tt_ttisut = false; } static int32 -detzcode(const char *codep) +detzcode(const char *const codep) { int32 result; int i; @@ -144,7 +145,7 @@ detzcode(const char *codep) } static int64 -detzcode64(const char *codep) +detzcode64(const char *const codep) { uint64 result; int i; @@ -250,7 +251,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, for (stored = 4; stored <= 8; stored *= 2) { int32 ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt); - int32 ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt); + int32 ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt); int64 prevtr = 0; int32 prevcorr = 0; int32 leapcnt = detzcode(up->tzhead.tzh_leapcnt); @@ -259,12 +260,17 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, int32 charcnt = detzcode(up->tzhead.tzh_charcnt); char const *p = up->buf + tzheadsize; + /* + * Although tzfile(5) currently requires typecnt to be nonzero, + * support future formats that may allow zero typecnt in files that + * have a TZ string and no transitions. + */ if (!(0 <= leapcnt && leapcnt < TZ_MAX_LEAPS - && 0 < typecnt && typecnt < TZ_MAX_TYPES + && 0 <= typecnt && typecnt < TZ_MAX_TYPES && 0 <= timecnt && timecnt < TZ_MAX_TIMES && 0 <= charcnt && charcnt < TZ_MAX_CHARS && (ttisstdcnt == typecnt || ttisstdcnt == 0) - && (ttisgmtcnt == typecnt || ttisgmtcnt == 0))) + && (ttisutcnt == typecnt || ttisutcnt == 0))) return EINVAL; if (nread < (tzheadsize /* struct tzhead */ @@ -274,7 +280,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, + charcnt /* chars */ + leapcnt * (stored + 4) /* lsinfos */ + ttisstdcnt /* ttisstds */ - + ttisgmtcnt)) /* ttisgmts */ + + ttisutcnt)) /* ttisuts */ return EINVAL; sp->leapcnt = leapcnt; sp->timecnt = timecnt; @@ -326,19 +332,19 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, { struct ttinfo *ttisp; unsigned char isdst, - abbrind; + desigidx; ttisp = &sp->ttis[i]; - ttisp->tt_gmtoff = detzcode(p); + ttisp->tt_utoff = detzcode(p); p += 4; isdst = *p++; if (!(isdst < 2)) return EINVAL; ttisp->tt_isdst = isdst; - abbrind = *p++; - if (!(abbrind < sp->charcnt)) + desigidx = *p++; + if (!(desigidx < sp->charcnt)) return EINVAL; - ttisp->tt_abbrind = abbrind; + ttisp->tt_desigidx = desigidx; } for (i = 0; i < sp->charcnt; ++i) sp->chars[i] = *p++; @@ -392,13 +398,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, struct ttinfo *ttisp; ttisp = &sp->ttis[i]; - if (ttisgmtcnt == 0) - ttisp->tt_ttisgmt = false; + if (ttisutcnt == 0) + ttisp->tt_ttisut = false; else { if (*p != true && *p != false) return EINVAL; - ttisp->tt_ttisgmt = *p++; + ttisp->tt_ttisut = *p++; } } @@ -417,8 +423,7 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, struct state *ts = &lsp->u.st; up->buf[nread - 1] = '\0'; - if (tzparse(&up->buf[1], ts, false) - && ts->typecnt == 2) + if (tzparse(&up->buf[1], ts, false)) { /* * Attempt to reuse existing abbreviations. Without this, @@ -431,15 +436,15 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, int gotabbr = 0; int charcnt = sp->charcnt; - for (i = 0; i < 2; i++) + for (i = 0; i < ts->typecnt; i++) { - char *tsabbr = ts->chars + ts->ttis[i].tt_abbrind; + char *tsabbr = ts->chars + ts->ttis[i].tt_desigidx; int j; for (j = 0; j < charcnt; j++) if (strcmp(sp->chars + j, tsabbr) == 0) { - ts->ttis[i].tt_abbrind = j; + ts->ttis[i].tt_desigidx = j; gotabbr++; break; } @@ -451,12 +456,12 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, { strcpy(sp->chars + j, tsabbr); charcnt = j + tsabbrlen + 1; - ts->ttis[i].tt_abbrind = j; + ts->ttis[i].tt_desigidx = j; gotabbr++; } } } - if (gotabbr == 2) + if (gotabbr == ts->typecnt) { sp->charcnt = charcnt; @@ -471,7 +476,8 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, sp->timecnt--; for (i = 0; i < ts->timecnt; i++) - if (sp->ats[sp->timecnt - 1] < ts->ats[i]) + if (sp->timecnt == 0 + || sp->ats[sp->timecnt - 1] < ts->ats[i]) break; while (i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES) @@ -482,11 +488,13 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, sp->timecnt++; i++; } - sp->ttis[sp->typecnt++] = ts->ttis[0]; - sp->ttis[sp->typecnt++] = ts->ttis[1]; + for (i = 0; i < ts->typecnt; i++) + sp->ttis[sp->typecnt++] = ts->ttis[i]; } } } + if (sp->typecnt == 0) + return EINVAL; if (sp->timecnt > 1) { for (i = 1; i < sp->timecnt; ++i) @@ -507,6 +515,18 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, } } + /* + * Infer sp->defaulttype from the data. Although this default type is + * always zero for data from recent tzdb releases, things are trickier for + * data from tzdb 2018e or earlier. + * + * The first set of heuristics work around bugs in 32-bit data generated + * by tzdb 2013c or earlier. The workaround is for zones like + * Australia/Macquarie where timestamps before the first transition have a + * time type that is not the earliest standard-time type. See: + * https://mm.icann.org/pipermail/tz/2013-May/019368.html + */ + /* * If type 0 is unused in transitions, it's the type to use for early * times. @@ -529,6 +549,11 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, break; } + /* + * The next heuristics are for data generated by tzdb 2018e or earlier, + * for zones like EST5EDT where the first transition is to DST. + */ + /* * If no result yet, find the first standard type. If there is none, punt * to type zero. @@ -543,7 +568,14 @@ tzloadbody(char const *name, char *canonname, struct state *sp, bool doextend, break; } } + + /* + * A simple 'sp->defaulttype = 0;' would suffice here if we didn't have to + * worry about 2018e-or-earlier data. Even simpler would be to remove the + * defaulttype member and just use 0 in its place. + */ sp->defaulttype = i; + return 0; } @@ -582,12 +614,13 @@ typesequiv(const struct state *sp, int a, int b) const struct ttinfo *ap = &sp->ttis[a]; const struct ttinfo *bp = &sp->ttis[b]; - result = ap->tt_gmtoff == bp->tt_gmtoff && - ap->tt_isdst == bp->tt_isdst && - ap->tt_ttisstd == bp->tt_ttisstd && - ap->tt_ttisgmt == bp->tt_ttisgmt && - strcmp(&sp->chars[ap->tt_abbrind], - &sp->chars[bp->tt_abbrind]) == 0; + result = (ap->tt_utoff == bp->tt_utoff + && ap->tt_isdst == bp->tt_isdst + && ap->tt_ttisstd == bp->tt_ttisstd + && ap->tt_ttisut == bp->tt_ttisut + && (strcmp(&sp->chars[ap->tt_desigidx], + &sp->chars[bp->tt_desigidx]) + == 0)); } return result; } @@ -602,10 +635,11 @@ static const int year_lengths[2] = { }; /* - * Given a pointer into a time zone string, scan until a character that is not - * a valid character in a zone name is found. Return a pointer to that - * character. + * Given a pointer into a timezone string, scan until a character that is not + * a valid character in a time zone abbreviation is found. + * Return a pointer to that character. */ + static const char * getzname(const char *strp) { @@ -618,15 +652,17 @@ getzname(const char *strp) } /* - * Given a pointer into an extended time zone string, scan until the ending - * delimiter of the zone name is located. Return a pointer to the delimiter. + * Given a pointer into an extended timezone string, scan until the ending + * delimiter of the time zone abbreviation is located. + * Return a pointer to the delimiter. * * As with getzname above, the legal character set is actually quite * restricted, with other characters producing undefined results. * We don't do any checking here; checking is done later in common-case code. */ + static const char * -getqzname(const char *strp, int delim) +getqzname(const char *strp, const int delim) { int c; @@ -636,13 +672,14 @@ getqzname(const char *strp, int delim) } /* - * Given a pointer into a time zone string, extract a number from that string. + * Given a pointer into a timezone string, extract a number from that string. * Check that the number is within a specified range; if it is not, return * NULL. * Otherwise, return a pointer to the first character not part of the number. */ + static const char * -getnum(const char *strp, int *nump, int min, int max) +getnum(const char *strp, int *const nump, const int min, const int max) { char c; int num; @@ -664,14 +701,15 @@ getnum(const char *strp, int *nump, int min, int max) } /* - * Given a pointer into a time zone string, extract a number of seconds, + * Given a pointer into a timezone string, extract a number of seconds, * in hh[:mm[:ss]] form, from the string. * If any error occurs, return NULL. * Otherwise, return a pointer to the first character not part of the number * of seconds. */ + static const char * -getsecs(const char *strp, int32 *secsp) +getsecs(const char *strp, int32 *const secsp) { int num; @@ -705,13 +743,14 @@ getsecs(const char *strp, int32 *secsp) } /* - * Given a pointer into a time zone string, extract an offset, in + * Given a pointer into a timezone string, extract an offset, in * [+-]hh[:mm[:ss]] form, from the string. * If any error occurs, return NULL. * Otherwise, return a pointer to the first character not part of the time. */ + static const char * -getoffset(const char *strp, int32 *offsetp) +getoffset(const char *strp, int32 *const offsetp) { bool neg = false; @@ -731,13 +770,14 @@ getoffset(const char *strp, int32 *offsetp) } /* - * Given a pointer into a time zone string, extract a rule in the form + * Given a pointer into a timezone string, extract a rule in the form * date[/time]. See POSIX section 8 for the format of "date" and "time". * If a valid rule is not found, return NULL. * Otherwise, return a pointer to the first character not part of the rule. */ + static const char * -getrule(const char *strp, struct rule *rulep) +getrule(const char *strp, struct rule *const rulep) { if (*strp == 'J') { @@ -796,9 +836,10 @@ getrule(const char *strp, struct rule *rulep) * Given a year, a rule, and the offset from UT at the time that rule takes * effect, calculate the year-relative time that rule takes effect. */ + static int32 -transtime(int year, const struct rule *rulep, - int32 offset) +transtime(const int year, const struct rule *const rulep, + const int32 offset) { bool leapyear; int32 value; @@ -909,20 +950,10 @@ tzparse(const char *name, struct state *sp, bool lastditch) stdname = name; if (lastditch) { - /* - * This is intentionally somewhat different from the IANA code. We do - * not want to invoke tzload() in the lastditch case: we can't assume - * pg_open_tzfile() is sane yet, and we don't care about leap seconds - * anyway. - */ + /* Unlike IANA, don't assume name is exactly "GMT" */ stdlen = strlen(name); /* length of standard zone name */ name += stdlen; - if (stdlen >= sizeof sp->chars) - stdlen = (sizeof sp->chars) - 1; - charcnt = stdlen + 1; stdoffset = 0; - sp->goback = sp->goahead = false; /* simulate failed tzload() */ - load_ok = false; } else { @@ -946,27 +977,23 @@ tzparse(const char *name, struct state *sp, bool lastditch) name = getoffset(name, &stdoffset); if (name == NULL) return false; - charcnt = stdlen + 1; - if (sizeof sp->chars < charcnt) - return false; - - /* - * This bit also differs from the IANA code, which doesn't make any - * attempt to avoid repetitive loadings of the TZDEFRULES zone. - */ - if (tzdefrules_loaded == 0) - { - if (tzload(TZDEFRULES, NULL, &tzdefrules_s, false) == 0) - tzdefrules_loaded = 1; - else - tzdefrules_loaded = -1; - } - load_ok = (tzdefrules_loaded > 0); - if (load_ok) - memcpy(sp, &tzdefrules_s, sizeof(struct state)); } - if (!load_ok) - sp->leapcnt = 0; /* so, we're off a little */ + charcnt = stdlen + 1; + if (sizeof sp->chars < charcnt) + return false; + + /* + * The IANA code always tries tzload(TZDEFRULES) here. We do not want to + * do that; it would be bad news in the lastditch case, where we can't + * assume pg_open_tzfile() is sane yet. Moreover, the only reason to do + * it unconditionally is to absorb the TZDEFRULES zone's leap second info, + * which we don't want to do anyway. Without that, we only need to load + * TZDEFRULES if the zone name specifies DST but doesn't incorporate a + * POSIX-style transition date rule, which is not a common case. + */ + sp->goback = sp->goahead = false; /* simulate failed tzload() */ + sp->leapcnt = 0; /* intentionally assume no leap seconds */ + if (*name != '\0') { if (*name == '<') @@ -982,7 +1009,7 @@ tzparse(const char *name, struct state *sp, bool lastditch) { dstname = name; name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ + dstlen = name - dstname; /* length of DST abbr. */ } if (!dstlen) return false; @@ -997,8 +1024,38 @@ tzparse(const char *name, struct state *sp, bool lastditch) } else dstoffset = stdoffset - SECSPERHOUR; - if (*name == '\0' && !load_ok) - name = TZDEFRULESTRING; + if (*name == '\0') + { + /* + * The POSIX zone name does not provide a transition-date rule. + * Here we must load the TZDEFRULES zone, if possible, to serve as + * source data for the transition dates. Unlike the IANA code, we + * try to cache the data so it's only loaded once. + */ + if (tzdefrules_loaded == 0) + { + /* Allocate on first use */ + if (tzdefrules_s == NULL) + tzdefrules_s = (struct state *) malloc(sizeof(struct state)); + if (tzdefrules_s != NULL) + { + if (tzload(TZDEFRULES, NULL, tzdefrules_s, false) == 0) + tzdefrules_loaded = 1; + else + tzdefrules_loaded = -1; + /* In any case, we ignore leap-second data from the file */ + tzdefrules_s->leapcnt = 0; + } + } + load_ok = (tzdefrules_loaded > 0); + if (load_ok) + memcpy(sp, tzdefrules_s, sizeof(struct state)); + else + { + /* If we can't load TZDEFRULES, fall back to hard-wired rule */ + name = TZDEFRULESTRING; + } + } if (*name == ',' || *name == ';') { struct rule start; @@ -1024,8 +1081,8 @@ tzparse(const char *name, struct state *sp, bool lastditch) /* * Two transitions per year, from EPOCH_YEAR forward. */ - init_ttinfo(&sp->ttis[0], -dstoffset, true, stdlen + 1); - init_ttinfo(&sp->ttis[1], -stdoffset, false, 0); + init_ttinfo(&sp->ttis[0], -stdoffset, false, 0); + init_ttinfo(&sp->ttis[1], -dstoffset, true, stdlen + 1); sp->defaulttype = 0; timecnt = 0; janfirst = 0; @@ -1074,19 +1131,15 @@ tzparse(const char *name, struct state *sp, bool lastditch) if (!increment_overflow_time (&sp->ats[timecnt], janoffset + starttime)) - sp->types[timecnt++] = reversed; - else if (janoffset) - sp->defaulttype = reversed; + sp->types[timecnt++] = !reversed; sp->ats[timecnt] = janfirst; if (!increment_overflow_time (&sp->ats[timecnt], janoffset + endtime)) { - sp->types[timecnt++] = !reversed; + sp->types[timecnt++] = reversed; yearlim = year + YEARSPERREPEAT + 1; } - else if (janoffset) - sp->defaulttype = !reversed; } if (increment_overflow_time (&janfirst, janoffset + yearsecs)) @@ -1095,7 +1148,10 @@ tzparse(const char *name, struct state *sp, bool lastditch) } sp->timecnt = timecnt; if (!timecnt) + { + sp->ttis[0] = sp->ttis[1]; sp->typecnt = 1; /* Perpetual DST. */ + } else if (YEARSPERREPEAT < year - yearbeg) sp->goback = sp->goahead = true; } @@ -1121,7 +1177,7 @@ tzparse(const char *name, struct state *sp, bool lastditch) if (!sp->ttis[j].tt_isdst) { theirstdoffset = - -sp->ttis[j].tt_gmtoff; + -sp->ttis[j].tt_utoff; break; } } @@ -1132,7 +1188,7 @@ tzparse(const char *name, struct state *sp, bool lastditch) if (sp->ttis[j].tt_isdst) { theirdstoffset = - -sp->ttis[j].tt_gmtoff; + -sp->ttis[j].tt_utoff; break; } } @@ -1151,19 +1207,19 @@ tzparse(const char *name, struct state *sp, bool lastditch) { j = sp->types[i]; sp->types[i] = sp->ttis[j].tt_isdst; - if (sp->ttis[j].tt_ttisgmt) + if (sp->ttis[j].tt_ttisut) { /* No adjustment to transition time */ } else { /* - * If summer time is in effect, and the transition time - * was not specified as standard time, add the summer time - * offset to the transition time; otherwise, add the - * standard time offset to the transition time. + * If daylight saving time is in effect, and the + * transition time was not specified as standard time, add + * the daylight saving time offset to the transition time; + * otherwise, add the standard time offset to the + * transition time. */ - /* * Transitions from DST to DDST will effectively disappear * since POSIX provides for only one DST offset. @@ -1179,7 +1235,7 @@ tzparse(const char *name, struct state *sp, bool lastditch) theirstdoffset; } } - theiroffset = -sp->ttis[j].tt_gmtoff; + theiroffset = -sp->ttis[j].tt_utoff; if (sp->ttis[j].tt_isdst) theirdstoffset = theiroffset; else @@ -1217,7 +1273,7 @@ tzparse(const char *name, struct state *sp, bool lastditch) } static void -gmtload(struct state *sp) +gmtload(struct state *const sp) { if (tzload(gmt, NULL, sp, true) != 0) tzparse(gmt, sp, true); @@ -1232,7 +1288,7 @@ gmtload(struct state *sp) */ static struct pg_tm * localsub(struct state const *sp, pg_time_t const *timep, - struct pg_tm *tmp) + struct pg_tm *const tmp) { const struct ttinfo *ttisp; int i; @@ -1300,11 +1356,16 @@ localsub(struct state const *sp, pg_time_t const *timep, } ttisp = &sp->ttis[i]; - result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); + /* + * To get (wrong) behavior that's compatible with System V Release 2.0 + * you'd replace the statement below with t += ttisp->tt_utoff; + * timesub(&t, 0L, sp, tmp); + */ + result = timesub(&t, ttisp->tt_utoff, sp, tmp); if (result) { result->tm_isdst = ttisp->tt_isdst; - result->tm_zone = (char *) &sp->chars[ttisp->tt_abbrind]; + result->tm_zone = unconstify(char *, &sp->chars[ttisp->tt_desigidx]); } return result; } @@ -1322,21 +1383,25 @@ pg_localtime(const pg_time_t *timep, const pg_tz *tz) * * Except we have a private "struct state" for GMT, so no sp is passed in. */ + static struct pg_tm * -gmtsub(pg_time_t const *timep, int32 offset, struct pg_tm *tmp) +gmtsub(pg_time_t const *timep, int32 offset, + struct pg_tm *tmp) { struct pg_tm *result; /* GMT timezone state data is kept here */ - static struct state gmtmem; - static bool gmt_is_set = false; -#define gmtptr (&gmtmem) + static struct state *gmtptr = NULL; - if (!gmt_is_set) + if (gmtptr == NULL) { - gmt_is_set = true; + /* Allocate on first use */ + gmtptr = (struct state *) malloc(sizeof(struct state)); + if (gmtptr == NULL) + return NULL; /* errno should be set by malloc */ gmtload(gmtptr); } + result = timesub(timep, offset, gmtptr, tmp); /* @@ -1361,6 +1426,7 @@ pg_gmtime(const pg_time_t *timep) * Return the number of leap years through the end of the given year * where, to make the math easy, the answer for year zero is defined as zero. */ + static int leaps_thru_end_of_nonneg(int y) { @@ -1582,7 +1648,7 @@ pg_next_dst_boundary(const pg_time_t *timep, break; } ttisp = &sp->ttis[i]; - *before_gmtoff = ttisp->tt_gmtoff; + *before_gmtoff = ttisp->tt_utoff; *before_isdst = ttisp->tt_isdst; return 0; } @@ -1635,7 +1701,7 @@ pg_next_dst_boundary(const pg_time_t *timep, /* No known transition > t, so use last known segment's type */ i = sp->types[sp->timecnt - 1]; ttisp = &sp->ttis[i]; - *before_gmtoff = ttisp->tt_gmtoff; + *before_gmtoff = ttisp->tt_utoff; *before_isdst = ttisp->tt_isdst; return 0; } @@ -1650,13 +1716,13 @@ pg_next_dst_boundary(const pg_time_t *timep, break; } ttisp = &sp->ttis[i]; - *before_gmtoff = ttisp->tt_gmtoff; + *before_gmtoff = ttisp->tt_utoff; *before_isdst = ttisp->tt_isdst; *boundary = sp->ats[0]; /* And for "after", use the first segment's type */ i = sp->types[0]; ttisp = &sp->ttis[i]; - *after_gmtoff = ttisp->tt_gmtoff; + *after_gmtoff = ttisp->tt_utoff; *after_isdst = ttisp->tt_isdst; return 1; } @@ -1678,12 +1744,12 @@ pg_next_dst_boundary(const pg_time_t *timep, } j = sp->types[i - 1]; ttisp = &sp->ttis[j]; - *before_gmtoff = ttisp->tt_gmtoff; + *before_gmtoff = ttisp->tt_utoff; *before_isdst = ttisp->tt_isdst; *boundary = sp->ats[i]; j = sp->types[i]; ttisp = &sp->ttis[j]; - *after_gmtoff = ttisp->tt_gmtoff; + *after_gmtoff = ttisp->tt_utoff; *after_isdst = ttisp->tt_isdst; return 1; } @@ -1767,9 +1833,9 @@ pg_interpret_timezone_abbrev(const char *abbrev, for (i = cutoff - 1; i >= 0; i--) { ttisp = &sp->ttis[sp->types[i]]; - if (ttisp->tt_abbrind == abbrind) + if (ttisp->tt_desigidx == abbrind) { - *gmtoff = ttisp->tt_gmtoff; + *gmtoff = ttisp->tt_utoff; *isdst = ttisp->tt_isdst; return true; } @@ -1781,9 +1847,9 @@ pg_interpret_timezone_abbrev(const char *abbrev, for (i = cutoff; i < sp->timecnt; i++) { ttisp = &sp->ttis[sp->types[i]]; - if (ttisp->tt_abbrind == abbrind) + if (ttisp->tt_desigidx == abbrind) { - *gmtoff = ttisp->tt_gmtoff; + *gmtoff = ttisp->tt_utoff; *isdst = ttisp->tt_isdst; return true; } @@ -1810,10 +1876,10 @@ pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff) sp = &tz->state; for (i = 1; i < sp->typecnt; i++) { - if (sp->ttis[i].tt_gmtoff != sp->ttis[0].tt_gmtoff) + if (sp->ttis[i].tt_utoff != sp->ttis[0].tt_utoff) return false; } - *gmtoff = sp->ttis[0].tt_gmtoff; + *gmtoff = sp->ttis[0].tt_utoff; return true; } diff --git a/src/timezone/pgtz.c b/src/timezone/pgtz.c index 7a476eabf7d..4b3829b0b53 100644 --- a/src/timezone/pgtz.c +++ b/src/timezone/pgtz.c @@ -3,7 +3,7 @@ * pgtz.c * Timezone Library Integration Functions * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/timezone/pgtz.c @@ -32,8 +32,8 @@ pg_tz *log_timezone = NULL; static bool scan_directory_ci(const char *dirname, - const char *fname, int fnamelen, - char *canonname, int canonnamelen); + const char *fname, int fnamelen, + char *canonname, int canonnamelen); /* @@ -357,7 +357,7 @@ pg_tzset_offset(long gmtoffset) * is to ensure that log_timezone has a valid value before any logging GUC * variables could become set to values that require elog.c to provide * timestamps (e.g., log_line_prefix). We may as well initialize - * session_timestamp to something valid, too. + * session_timezone to something valid, too. */ void pg_timezone_initialize(void) diff --git a/src/timezone/pgtz.h b/src/timezone/pgtz.h index 1e94d66d490..3ddc4a65acc 100644 --- a/src/timezone/pgtz.h +++ b/src/timezone/pgtz.h @@ -6,7 +6,7 @@ * Note: this file contains only definitions that are private to the * timezone library. Public definitions are in pgtime.h. * - * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group * * IDENTIFICATION * src/timezone/pgtz.h @@ -25,11 +25,11 @@ struct ttinfo { /* time type information */ - int32 tt_gmtoff; /* UT offset in seconds */ + int32 tt_utoff; /* UT offset in seconds */ bool tt_isdst; /* used to set tm_isdst */ - int tt_abbrind; /* abbreviation list index */ + int tt_desigidx; /* abbreviation list index */ bool tt_ttisstd; /* transition is std time */ - bool tt_ttisgmt; /* transition is UT */ + bool tt_ttisut; /* transition is UT */ }; struct lsinfo @@ -49,10 +49,16 @@ struct state pg_time_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; - char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, 3 /* sizeof gmt */ ), + char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, 4 /* sizeof gmt */ ), (2 * (TZ_STRLEN_MAX + 1)))]; struct lsinfo lsis[TZ_MAX_LEAPS]; - int defaulttype; /* for early times or if no transitions */ + + /* + * The time type to use for early times or if no transitions. It is always + * zero for recent tzdb releases. It might be nonzero for data from tzdb + * 2018e or earlier. + */ + int defaulttype; }; @@ -68,8 +74,8 @@ struct pg_tz extern int pg_open_tzfile(const char *name, char *canonname); /* in localtime.c */ -extern int tzload(const char *name, char *canonname, struct state *sp, - bool doextend); +extern int tzload(const char *name, char *canonname, struct state *sp, + bool doextend); extern bool tzparse(const char *name, struct state *sp, bool lastditch); #endif /* _PGTZ_H */ diff --git a/src/timezone/private.h b/src/timezone/private.h index 701112ec5b8..533e3d9f4ed 100644 --- a/src/timezone/private.h +++ b/src/timezone/private.h @@ -1,4 +1,7 @@ +/* Private header for tzdb code. */ + #ifndef PRIVATE_H + #define PRIVATE_H /* @@ -41,6 +44,14 @@ /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) +/* PG doesn't currently rely on , so work around strtoimax() */ +#undef strtoimax +#ifdef HAVE_STRTOLL +#define strtoimax strtoll +#else +#define strtoimax strtol +#endif + /* * Finally, some convenience items. diff --git a/src/timezone/strftime.c b/src/timezone/strftime.c index bb638c81a45..55c617f8c22 100644 --- a/src/timezone/strftime.c +++ b/src/timezone/strftime.c @@ -1,4 +1,4 @@ -/* Convert a broken-down timestamp to a string. */ +/* Convert a broken-down timestamp to a string. */ /* * Copyright 1989 The Regents of the University of California. @@ -114,8 +114,8 @@ enum warn static char *_add(const char *, char *, const char *); static char *_conv(int, const char *, char *, const char *); static char *_fmt(const char *, const struct pg_tm *, char *, const char *, - enum warn *); -static char *_yconv(int, int, bool, bool, char *, const char *); + enum warn *); +static char *_yconv(int, int, bool, bool, char *, char const *); size_t @@ -203,7 +203,7 @@ _fmt(const char *format, const struct pg_tm *t, char *pt, /* * Locale modifiers of C99 and later. The sequences %Ec * %EC %Ex %EX %Ey %EY %Od %oe %OH %OI %Om %OM %OS %Ou %OU - * %OV %Ow %OW %Oy are supposed to provide alternate + * %OV %Ow %OW %Oy are supposed to provide alternative * representations. */ goto label; @@ -441,7 +441,8 @@ _fmt(const char *format, const struct pg_tm *t, char *pt, /* * C99 and later say that %Z must be replaced by the empty - * string if the time zone is not determinable. + * string if the time zone abbreviation is not + * determinable. */ continue; case 'z': @@ -519,6 +520,7 @@ _add(const char *str, char *pt, const char *ptlim) * same output as %Y, and that %Y contains at least 4 bytes, * with more only if necessary. */ + static char * _yconv(int a, int b, bool convert_top, bool convert_yy, char *pt, const char *ptlim) @@ -526,7 +528,7 @@ _yconv(int a, int b, bool convert_top, bool convert_yy, int lead; int trail; -#define DIVISOR 100 +#define DIVISOR 100 trail = a % DIVISOR + b % DIVISOR; lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; trail %= DIVISOR; diff --git a/src/timezone/tzfile.h b/src/timezone/tzfile.h index 25ca3074034..8f3eb6bd3f2 100644 --- a/src/timezone/tzfile.h +++ b/src/timezone/tzfile.h @@ -1,4 +1,7 @@ +/* Layout and location of TZif files. */ + #ifndef TZFILE_H + #define TZFILE_H /* @@ -21,21 +24,24 @@ * Information about time zone files. */ -#define TZDEFAULT "localtime" +#define TZDEFAULT "/etc/localtime" #define TZDEFRULES "posixrules" + +/* See Internet RFC 8536 for more details about the following format. */ + /* * Each file begins with. . . */ -#define TZ_MAGIC "TZif" +#define TZ_MAGIC "TZif" struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ char tzh_reserved[15]; /* reserved; must be zero */ - char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ + char tzh_ttisutcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ char tzh_timecnt[4]; /* coded number of transition times */ @@ -58,14 +64,15 @@ struct tzhead * one (char [4]) total correction after above * tzh_ttisstdcnt (char)s indexed by type; if 1, transition * time is standard time, if 0, - * transition time is wall clock time - * if absent, transition times are - * assumed to be wall clock time - * tzh_ttisgmtcnt (char)s indexed by type; if 1, transition - * time is UT, if 0, - * transition time is local time - * if absent, transition times are + * transition time is local (wall clock) + * time; if absent, transition times are * assumed to be local time + * tzh_ttisutcnt (char)s indexed by type; if 1, transition + * time is UT, if 0, transition time is + * local time; if absent, transition + * times are assumed to be local time. + * When this is 1, the corresponding + * std/wall indicator must also be 1. */ /* diff --git a/src/timezone/tznames/America.txt b/src/timezone/tznames/America.txt index 1c5eb1f8c51..2594c375f6c 100644 --- a/src/timezone/tznames/America.txt +++ b/src/timezone/tznames/America.txt @@ -237,6 +237,9 @@ PDT -25200 D # Pacific Daylight Time PET -18000 # Peru Time (obsolete) PMDT -7200 D # Pierre & Miquelon Daylight Time (obsolete) PMST -10800 # Pierre & Miquelon Standard Time (obsolete) +# CONFLICT! PST is not unique +# Other timezones: +# - PST: Philippine Standard Time PST -28800 # Pacific Standard Time # (America/Dawson) # (America/Los_Angeles) diff --git a/src/timezone/tznames/Asia.txt b/src/timezone/tznames/Asia.txt index 4e365b00289..113333995a3 100644 --- a/src/timezone/tznames/Asia.txt +++ b/src/timezone/tznames/Asia.txt @@ -118,13 +118,13 @@ IRST Asia/Tehran # Iran Standard Time (obsolete) IRT 12600 # Iran Time (not in IANA database) # CONFLICT! IST is not unique # Other timezones: -# - IST: Irish Summer Time (Europe) +# - IST: Irish Standard Time (Europe) # - IST: Israel Standard Time (Asia) IST 19800 # Indian Standard Time # (Asia/Calcutta) # CONFLICT! IST is not unique # Other timezones: -# - IST: Irish Summer Time (Europe) +# - IST: Irish Standard Time (Europe) # - IST: Indian Standard Time (Asia) IST 7200 # Israel Standard Time # (Asia/Jerusalem) @@ -158,6 +158,10 @@ PKT 18000 # Pakistan Time # (Asia/Karachi) PKST 21600 D # Pakistan Summer Time # (Asia/Karachi) +# CONFLICT! PST is not unique +# Other timezones: +# - PST: Pacific Standard Time (America) +PST 28800 # Philippine Standard Time QYZT 21600 # Kizilorda Time (obsolete) SAKST Asia/Sakhalin # Sakhalin Summer Time (obsolete) SAKT Asia/Sakhalin # Sakhalin Time (obsolete) diff --git a/src/timezone/tznames/Default b/src/timezone/tznames/Default index 80eb1b12909..1532413bfad 100644 --- a/src/timezone/tznames/Default +++ b/src/timezone/tznames/Default @@ -181,6 +181,9 @@ PDT -25200 D # Pacific Daylight Time # (America/Whitehorse) PMDT -7200 D # Pierre & Miquelon Daylight Time (obsolete) PMST -10800 # Pierre & Miquelon Standard Time (obsolete) +# CONFLICT! PST is not unique +# Other timezones: +# - PST: Philippine Standard Time PST -28800 # Pacific Standard Time # (America/Dawson) # (America/Los_Angeles) @@ -236,7 +239,7 @@ IRKT Asia/Irkutsk # Irkutsk Time (obsolete) IRT 12600 # Iran Time (not in IANA database) # CONFLICT! IST is not unique # Other timezones: -# - IST: Irish Summer Time (Europe) +# - IST: Irish Standard Time (Europe) # - IST: Indian Standard Time (Asia) IST 7200 # Israel Standard Time # (Asia/Jerusalem) diff --git a/src/timezone/tznames/Europe.txt b/src/timezone/tznames/Europe.txt index 0cb49f156b9..86378bf8e9f 100644 --- a/src/timezone/tznames/Europe.txt +++ b/src/timezone/tznames/Europe.txt @@ -180,7 +180,7 @@ GMT 0 # Greenwich Mean Time # Other timezones: # - IST: Indian Standard Time (Asia) # - IST: Israel Standard Time (Asia) -IST 3600 D # Irish Summer Time +IST 3600 # Irish Standard Time # (Europe/Dublin) MEST 7200 D # Middle Europe Summer Time # (MET) diff --git a/src/timezone/tznames/Pacific.txt b/src/timezone/tznames/Pacific.txt index c86248bbc7a..c30008cb049 100644 --- a/src/timezone/tznames/Pacific.txt +++ b/src/timezone/tznames/Pacific.txt @@ -52,6 +52,9 @@ NZST 43200 # New Zealand Standard Time PGT 36000 # Papua New Guinea Time (obsolete) PHOT Pacific/Enderbury # Phoenix Islands Time (Kiribati) (obsolete) PONT 39600 # Ponape Time (Micronesia) (obsolete) +# CONFLICT! PST is not unique +# Other timezones: +# - PST: Philippine Standard Time PST -28800 # Pacific Standard Time # (America/Dawson) # (America/Los_Angeles) diff --git a/src/timezone/tznames/README b/src/timezone/tznames/README index 0058770d198..6d355e46167 100644 --- a/src/timezone/tznames/README +++ b/src/timezone/tznames/README @@ -18,7 +18,7 @@ in any of the usual ways for setting a parameter, where xyz is the filename that contains the desired time zone abbreviations. If you do not find an appropriate set of abbreviations for your geographic -location supplied here, please report this to . +location supplied here, please report this to . Your set of time zone abbreviations can then be included in future releases. For the time being you can always add your own set. diff --git a/src/timezone/zic.c b/src/timezone/zic.c index 352e7193299..c27fb456d05 100644 --- a/src/timezone/zic.c +++ b/src/timezone/zic.c @@ -1,3 +1,5 @@ +/* Compile .zi time zone data into TZif binary files. */ + /* * This file is in the public domain, so clarified as of * 2006-07-17 by Arthur David Olson. @@ -39,6 +41,10 @@ typedef int64 zic_t; #define linkat(fromdir, from, todir, to, flag) \ (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to)) #endif +/* Port to native MS-Windows and to ancient UNIX. */ +#if !defined S_ISDIR && defined S_IFDIR && defined S_IFMT +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif /* The maximum ptrdiff_t value, for pre-C99 platforms. */ #ifndef PTRDIFF_MAX @@ -71,10 +77,10 @@ struct rule int r_wday; zic_t r_tod; /* time from midnight */ - bool r_todisstd; /* above is standard time if 1 or wall clock - * time if 0 */ - bool r_todisgmt; /* above is GMT if 1 or local time if 0 */ - zic_t r_stdoff; /* offset from standard time */ + bool r_todisstd; /* is r_tod standard time? */ + bool r_todisut; /* is r_tod UT? */ + bool r_isdst; /* is this daylight saving time? */ + zic_t r_save; /* offset from standard time */ const char *r_abbrvar; /* variable part of abbreviation */ bool r_todo; /* a rule to do (used in outzone) */ @@ -95,12 +101,13 @@ struct zone lineno_t z_linenum; const char *z_name; - zic_t z_gmtoff; - const char *z_rule; + zic_t z_stdoff; + char *z_rule; const char *z_format; char z_format_specifier; - zic_t z_stdoff; + bool z_isdst; + zic_t z_save; struct rule *z_rules; ptrdiff_t z_nrules; @@ -123,8 +130,8 @@ static void adjleap(void); static void associate(void); static void dolink(const char *, const char *, bool); static char **getfields(char *buf); -static zic_t gethms(const char *string, const char *errstring, - bool); +static zic_t gethms(const char *string, const char *errstring); +static zic_t getsave(char *, bool *); static void infile(const char *filename); static void inleap(char **fields, int nfields); static void inlink(char **fields, int nfields); @@ -142,9 +149,9 @@ static zic_t oadd(zic_t t1, zic_t t2); static void outzone(const struct zone *zp, ptrdiff_t ntzones); static zic_t rpytime(const struct rule *rp, zic_t wantedy); static void rulesub(struct rule *rp, - const char *loyearp, const char *hiyearp, - const char *typep, const char *monthp, - const char *dayp, const char *timep); + const char *loyearp, const char *hiyearp, + const char *typep, const char *monthp, + const char *dayp, const char *timep); static zic_t tadd(zic_t t1, zic_t t2); static bool yearistype(zic_t year, const char *type); @@ -154,13 +161,15 @@ enum PERCENT_Z_LEN_BOUND = sizeof "+995959" - 1}; /* If true, work around a bug in Qt 5.6.1 and earlier, which mishandles - tz binary files whose POSIX-TZ-style strings contain '<'; see + TZif files whose POSIX-TZ-style strings contain '<'; see QTBUG-53071 . This workaround will no longer be needed when Qt 5.6.1 and earlier are obsolete, say in the year 2021. */ +#ifndef WORK_AROUND_QTBUG_53071 enum { WORK_AROUND_QTBUG_53071 = true}; +#endif static int charcnt; static bool errors; @@ -199,11 +208,11 @@ static int typecnt; */ #define ZF_NAME 1 -#define ZF_GMTOFF 2 +#define ZF_STDOFF 2 #define ZF_RULE 3 #define ZF_FORMAT 4 #define ZF_TILYEAR 5 -#define ZF_TILMONTH 6 +#define ZF_TILMONTH 6 #define ZF_TILDAY 7 #define ZF_TILTIME 8 #define ZONE_MINFIELDS 5 @@ -213,15 +222,15 @@ static int typecnt; * Which fields are which on a Zone continuation line. */ -#define ZFC_GMTOFF 0 +#define ZFC_STDOFF 0 #define ZFC_RULE 1 #define ZFC_FORMAT 2 -#define ZFC_TILYEAR 3 +#define ZFC_TILYEAR 3 #define ZFC_TILMONTH 4 #define ZFC_TILDAY 5 -#define ZFC_TILTIME 6 -#define ZONEC_MINFIELDS 3 -#define ZONEC_MAXFIELDS 7 +#define ZFC_TILTIME 6 +#define ZONEC_MINFIELDS 3 +#define ZONEC_MAXFIELDS 7 /* * Which files are which on a Rule line. @@ -234,9 +243,9 @@ static int typecnt; #define RF_MONTH 5 #define RF_DAY 6 #define RF_TOD 7 -#define RF_STDOFF 8 +#define RF_SAVE 8 #define RF_ABBRVAR 9 -#define RULE_FIELDS 10 +#define RULE_FIELDS 10 /* * Which fields are which on a Link line. @@ -244,7 +253,7 @@ static int typecnt; #define LF_FROM 1 #define LF_TO 2 -#define LINK_FIELDS 3 +#define LINK_FIELDS 3 /* * Which fields are which on a Leap line. @@ -256,7 +265,7 @@ static int typecnt; #define LP_TIME 4 #define LP_CORR 5 #define LP_ROLL 6 -#define LEAP_FIELDS 7 +#define LEAP_FIELDS 7 /* * Year synonyms. @@ -293,7 +302,7 @@ struct lookup }; static struct lookup const *byword(const char *string, - const struct lookup *lp); + const struct lookup *lp); static struct lookup const zi_line_codes[] = { {"Rule", LC_RULE}, @@ -378,11 +387,11 @@ static struct attype bool dontmerge; unsigned char type; } *attypes; -static zic_t gmtoffs[TZ_MAX_TYPES]; +static zic_t utoffs[TZ_MAX_TYPES]; static char isdsts[TZ_MAX_TYPES]; -static unsigned char abbrinds[TZ_MAX_TYPES]; +static unsigned char desigidx[TZ_MAX_TYPES]; static bool ttisstds[TZ_MAX_TYPES]; -static bool ttisgmts[TZ_MAX_TYPES]; +static bool ttisuts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; static zic_t trans[TZ_MAX_LEAPS]; static zic_t corr[TZ_MAX_LEAPS]; @@ -529,8 +538,10 @@ usage(FILE *stream, int status) { fprintf(stream, _("%s: usage is %s [ --version ] [ --help ] [ -v ] [ -P ] \\\n" - "\t[ -l localtime ] [ -p posixrules ] [ -d directory ] \\\n" - "\t[ -L leapseconds ] [ filename ... ]\n\n" + "\t[ -b {slim|fat} ] [ -d directory ] [ -l localtime ]" + " [ -L leapseconds ] \\\n" + "\t[ -p posixrules ] [ -r '[@lo][/@hi]' ] [ -t localtime-link ] \\\n" + "\t[ filename ... ]\n\n" "Report bugs to %s.\n"), progname, progname, PACKAGE_BUGREPORT); if (status == EXIT_SUCCESS) @@ -562,12 +573,72 @@ change_directory(char const *dir) } } +#define TIME_T_BITS_IN_FILE 64 + +/* The minimum and maximum values representable in a TZif file. */ +static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); +static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); + +/* The minimum, and one less than the maximum, values specified by + the -r option. These default to MIN_TIME and MAX_TIME. */ +static zic_t lo_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); +static zic_t hi_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); + +/* Set the time range of the output to TIMERANGE. + Return true if successful. */ +static bool +timerange_option(char *timerange) +{ + int64 lo = min_time, + hi = max_time; + char *lo_end = timerange, + *hi_end; + + if (*timerange == '@') + { + errno = 0; + lo = strtoimax(timerange + 1, &lo_end, 10); + if (lo_end == timerange + 1 || (lo == PG_INT64_MAX && errno == ERANGE)) + return false; + } + hi_end = lo_end; + if (lo_end[0] == '/' && lo_end[1] == '@') + { + errno = 0; + hi = strtoimax(lo_end + 2, &hi_end, 10); + if (hi_end == lo_end + 2 || hi == PG_INT64_MIN) + return false; + hi -= !(hi == PG_INT64_MAX && errno == ERANGE); + } + if (*hi_end || hi < lo || max_time < lo || hi < min_time) + return false; + lo_time = lo < min_time ? min_time : lo; + hi_time = max_time < hi ? max_time : hi; + return true; +} + static const char *psxrules; static const char *lcltime; static const char *directory; static const char *leapsec; +static const char *tzdefault; static const char *yitcommand; +/* -1 if the TZif output file should be slim, 0 if default, 1 if the + output should be fat for backward compatibility. Currently the + default is fat, although this may change. */ +static int bloat; + +static bool +want_bloat(void) +{ + return 0 <= bloat; +} + +#ifndef ZIC_BLOAT_DEFAULT +#define ZIC_BLOAT_DEFAULT "fat" +#endif + int main(int argc, char **argv) { @@ -575,6 +646,7 @@ main(int argc, char **argv) k; ptrdiff_t i, j; + bool timerange_given = false; #ifndef WIN32 umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); @@ -597,11 +669,27 @@ main(int argc, char **argv) { usage(stdout, EXIT_SUCCESS); } - while ((c = getopt(argc, argv, "d:l:p:L:vPsy:")) != EOF && c != -1) + while ((c = getopt(argc, argv, "b:d:l:L:p:Pr:st:vy:")) != EOF && c != -1) switch (c) { default: usage(stderr, EXIT_FAILURE); + case 'b': + if (strcmp(optarg, "slim") == 0) + { + if (0 < bloat) + error(_("incompatible -b options")); + bloat = -1; + } + else if (strcmp(optarg, "fat") == 0) + { + if (bloat < 0) + error(_("incompatible -b options")); + bloat = 1; + } + else + error(_("invalid option: -b '%s'"), optarg); + break; case 'd': if (directory == NULL) directory = strdup(optarg); @@ -635,6 +723,17 @@ main(int argc, char **argv) return EXIT_FAILURE; } break; + case 't': + if (tzdefault != NULL) + { + fprintf(stderr, + _("%s: More than one -t option" + " specified\n"), + progname); + return EXIT_FAILURE; + } + tzdefault = optarg; + break; case 'y': if (yitcommand == NULL) { @@ -667,14 +766,35 @@ main(int argc, char **argv) print_abbrevs = true; print_cutoff = time(NULL); break; + case 'r': + if (timerange_given) + { + fprintf(stderr, + _("%s: More than one -r option specified\n"), + progname); + return EXIT_FAILURE; + } + if (!timerange_option(optarg)) + { + fprintf(stderr, + _("%s: invalid time range: %s\n"), + progname, optarg); + return EXIT_FAILURE; + } + timerange_given = true; + break; case 's': warning(_("-s ignored")); break; } if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) usage(stderr, EXIT_FAILURE); /* usage message by request */ + if (bloat == 0) + bloat = strcmp(ZIC_BLOAT_DEFAULT, "slim") == 0 ? -1 : 1; if (directory == NULL) directory = "data"; + if (tzdefault == NULL) + tzdefault = TZDEFAULT; if (yitcommand == NULL) yitcommand = "yearistype"; @@ -716,7 +836,7 @@ main(int argc, char **argv) if (lcltime != NULL) { eat(_("command line"), 1); - dolink(lcltime, TZDEFAULT, true); + dolink(lcltime, tzdefault, true); } if (psxrules != NULL) { @@ -916,10 +1036,12 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) char const *contents = absolute ? fromfield : linkalloc; int symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; - if (symlink_errno == ENOENT && !todirs_made) + if (!todirs_made + && (symlink_errno == ENOENT || symlink_errno == ENOTSUP)) { mkdirs(tofield, true); - symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; + if (symlink_errno == ENOENT) + symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno; } free(linkalloc); if (symlink_errno == 0) @@ -969,53 +1091,6 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink) } } -#define TIME_T_BITS_IN_FILE 64 - -static zic_t const min_time = MINVAL(zic_t, TIME_T_BITS_IN_FILE); -static zic_t const max_time = MAXVAL(zic_t, TIME_T_BITS_IN_FILE); - -/* - * Estimated time of the Big Bang, in seconds since the POSIX epoch. - * rounded downward to the negation of a power of two that is - * comfortably outside the error bounds. - * - * For the time of the Big Bang, see: - * - * Ade PAR, Aghanim N, Armitage-Caplan C et al. Planck 2013 results. - * I. Overview of products and scientific results. - * arXiv:1303.5062 2013-03-20 20:10:01 UTC - * [PDF] - * - * Page 36, Table 9, row Age/Gyr, column Planck+WP+highL+BAO 68% limits - * gives the value 13.798 plus-or-minus 0.037 billion years. - * Multiplying this by 1000000000 and then by 31557600 (the number of - * seconds in an astronomical year) gives a value that is comfortably - * less than 2**59, so BIG_BANG is - 2**59. - * - * BIG_BANG is approximate, and may change in future versions. - * Please do not rely on its exact value. - */ - -#ifndef BIG_BANG -#define BIG_BANG (- (((zic_t) 1) << 59)) -#endif - -/* If true, work around GNOME bug 730332 - - by refusing to output time stamps before BIG_BANG. - Such time stamps are physically suspect anyway. - - The GNOME bug is scheduled to be fixed in GNOME 3.22, and if so - this workaround will no longer be needed when GNOME 3.21 and - earlier are obsolete, say in the year 2021. */ -enum -{ -WORK_AROUND_GNOME_BUG_730332 = true}; - -static const zic_t early_time = (WORK_AROUND_GNOME_BUG_730332 - ? BIG_BANG - : MINVAL(zic_t, TIME_T_BITS_IN_FILE)); - /* Return true if NAME is a directory. */ static bool itsdir(char const *name) @@ -1140,8 +1215,7 @@ associate(void) * Maybe we have a local standard time offset. */ eat(zp->z_filename, zp->z_linenum); - zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - true); + zp->z_save = getsave(zp->z_rule, &zp->z_isdst); /* * Note, though, that if there's no rule, a '%s' in the format is @@ -1258,33 +1332,58 @@ infile(const char *name) * A null string maps to zero. * Call error with errstring and return zero on errors. */ + static zic_t -gethms(char const *string, char const *errstring, bool signable) +gethms(char const *string, char const *errstring) { /* PG: make hh be int not zic_t to avoid sscanf portability issues */ int hh; - int mm, - ss, - sign; - char xs; + int sign, + mm = 0, + ss = 0; + char hhx, + mmx, + ssx, + xr = '0', + xs; + int tenths = 0; + bool ok = true; if (string == NULL || *string == '\0') return 0; - if (!signable) - sign = 1; - else if (*string == '-') + if (*string == '-') { sign = -1; ++string; } else sign = 1; - if (sscanf(string, "%d%c", &hh, &xs) == 1) - mm = ss = 0; - else if (sscanf(string, "%d:%d%c", &hh, &mm, &xs) == 2) - ss = 0; - else if (sscanf(string, "%d:%d:%d%c", &hh, &mm, &ss, &xs) - != 3) + switch (sscanf(string, + "%d%c%d%c%d%c%1d%*[0]%c%*[0123456789]%c", + &hh, &hhx, &mm, &mmx, &ss, &ssx, &tenths, &xr, &xs)) + { + default: + ok = false; + break; + case 8: + ok = '0' <= xr && xr <= '9'; + /* fallthrough */ + case 7: + ok &= ssx == '.'; + if (ok && noise) + warning(_("fractional seconds rejected by" + " pre-2018 versions of zic")); + /* fallthrough */ + case 5: + ok &= mmx == ':'; + /* fallthrough */ + case 3: + ok &= hhx == ':'; + /* fallthrough */ + case 1: + break; + } + if (!ok) { error("%s", errstring); return 0; @@ -1304,6 +1403,7 @@ gethms(char const *string, char const *errstring, bool signable) return 0; } #endif + ss += 5 + ((ss ^ 1) & (xr == '0')) <= tenths; /* Round to even. */ if (noise && (hh > HOURSPERDAY || (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) warning(_("values over 24 hours not handled by pre-2007 versions of zic")); @@ -1311,6 +1411,34 @@ gethms(char const *string, char const *errstring, bool signable) sign * (mm * SECSPERMIN + ss)); } +static zic_t +getsave(char *field, bool *isdst) +{ + int dst = -1; + zic_t save; + size_t fieldlen = strlen(field); + + if (fieldlen != 0) + { + char *ep = field + fieldlen - 1; + + switch (*ep) + { + case 'd': + dst = 1; + *ep = '\0'; + break; + case 's': + dst = 0; + *ep = '\0'; + break; + } + } + save = gethms(field, _("invalid saved time")); + *isdst = dst < 0 ? save != 0 : dst; + return save; +} + static void inrule(char **fields, int nfields) { @@ -1321,14 +1449,33 @@ inrule(char **fields, int nfields) error(_("wrong number of fields on Rule line")); return; } - if (*fields[RF_NAME] == '\0') + switch (*fields[RF_NAME]) { - error(_("nameless rule")); - return; + case '\0': + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + case '+': + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + error(_("Invalid rule name \"%s\""), fields[RF_NAME]); + return; } r.r_filename = filename; r.r_linenum = linenum; - r.r_stdoff = gethms(fields[RF_STDOFF], _("invalid saved time"), true); + r.r_save = getsave(fields[RF_SAVE], &r.r_isdst); rulesub(&r, fields[RF_LOYEAR], fields[RF_HIYEAR], fields[RF_COMMAND], fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); @@ -1349,11 +1496,11 @@ inzone(char **fields, int nfields) error(_("wrong number of fields on Zone line")); return false; } - if (strcmp(fields[ZF_NAME], TZDEFAULT) == 0 && lcltime != NULL) + if (lcltime != NULL && strcmp(fields[ZF_NAME], tzdefault) == 0) { error( _("\"Zone %s\" line and -l option are mutually exclusive"), - TZDEFAULT); + tzdefault); return false; } if (strcmp(fields[ZF_NAME], TZDEFRULES) == 0 && psxrules != NULL) @@ -1394,7 +1541,7 @@ inzsub(char **fields, int nfields, bool iscont) char *cp; char *cp1; static struct zone z; - int i_gmtoff, + int i_stdoff, i_rule, i_format; int i_untilyear, @@ -1405,7 +1552,7 @@ inzsub(char **fields, int nfields, bool iscont) if (iscont) { - i_gmtoff = ZFC_GMTOFF; + i_stdoff = ZFC_STDOFF; i_rule = ZFC_RULE; i_format = ZFC_FORMAT; i_untilyear = ZFC_TILYEAR; @@ -1418,7 +1565,7 @@ inzsub(char **fields, int nfields, bool iscont) return false; else { - i_gmtoff = ZF_GMTOFF; + i_stdoff = ZF_STDOFF; i_rule = ZF_RULE; i_format = ZF_FORMAT; i_untilyear = ZF_TILYEAR; @@ -1429,7 +1576,7 @@ inzsub(char **fields, int nfields, bool iscont) } z.z_filename = filename; z.z_linenum = linenum; - z.z_gmtoff = gethms(fields[i_gmtoff], _("invalid UT offset"), true); + z.z_stdoff = gethms(fields[i_stdoff], _("invalid UT offset")); if ((cp = strchr(fields[i_format], '%')) != NULL) { if ((*++cp != 's' && *cp != 'z') || strchr(cp, '%') @@ -1571,7 +1718,7 @@ inleap(char **fields, int nfields) return; } t = dayoff * SECSPERDAY; - tod = gethms(fields[LP_TIME], _("invalid time of day"), false); + tod = gethms(fields[LP_TIME], _("invalid time of day")); cp = fields[LP_CORR]; { bool positive; @@ -1653,7 +1800,7 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, } rp->r_month = lp->l_value; rp->r_todisstd = false; - rp->r_todisgmt = false; + rp->r_todisut = false; dp = ecpyalloc(timep); if (*dp != '\0') { @@ -1662,24 +1809,24 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp, { case 's': /* Standard */ rp->r_todisstd = true; - rp->r_todisgmt = false; + rp->r_todisut = false; *ep = '\0'; break; case 'w': /* Wall */ rp->r_todisstd = false; - rp->r_todisgmt = false; + rp->r_todisut = false; *ep = '\0'; break; case 'g': /* Greenwich */ case 'u': /* Universal */ case 'z': /* Zulu */ rp->r_todisstd = true; - rp->r_todisgmt = true; + rp->r_todisut = true; *ep = '\0'; break; } } - rp->r_tod = gethms(dp, _("invalid time of day"), false); + rp->r_tod = gethms(dp, _("invalid time of day")); free(dp); /* @@ -1840,12 +1987,17 @@ puttzcode(const int32 val, FILE *const fp) } static void -puttzcode64(const zic_t val, FILE *const fp) +puttzcodepass(zic_t val, FILE *fp, int pass) { - char buf[8]; + if (pass == 1) + puttzcode(val, fp); + else + { + char buf[8]; - convert64(val, buf); - fwrite(buf, sizeof buf, 1, fp); + convert64(val, buf); + fwrite(buf, sizeof buf, 1, fp); + } } static int @@ -1857,22 +2009,49 @@ atcomp(const void *avp, const void *bvp) return (a < b) ? -1 : (a > b); } -static bool -is32(const zic_t x) +struct timerange { - return x == ((zic_t) ((int32) x)); + int defaulttype; + ptrdiff_t base, + count; + int leapbase, + leapcount; +}; + +static struct timerange +limitrange(struct timerange r, zic_t lo, zic_t hi, + zic_t const *ats, unsigned char const *types) +{ + while (0 < r.count && ats[r.base] < lo) + { + r.defaulttype = types[r.base]; + r.count--; + r.base++; + } + while (0 < r.leapcount && trans[r.leapbase] < lo) + { + r.leapcount--; + r.leapbase++; + } + + if (hi < ZIC_MAX) + { + while (0 < r.count && hi + 1 < ats[r.base + r.count - 1]) + r.count--; + while (0 < r.leapcount && hi + 1 < trans[r.leapbase + r.leapcount - 1]) + r.leapcount--; + } + + return r; } static void -writezone(const char *const name, const char *const string, char version) +writezone(const char *const name, const char *const string, char version, + int defaulttype) { FILE *fp; ptrdiff_t i, j; - int leapcnt32, - leapi32; - ptrdiff_t timecnt32, - timei32; int pass; static const struct tzhead tzh0; static struct tzhead tzh; @@ -1880,9 +2059,17 @@ writezone(const char *const name, const char *const string, char version) zic_t one = 1; zic_t y2038_boundary = one << 31; ptrdiff_t nats = timecnt + WORK_AROUND_QTBUG_53071; - zic_t *ats = emalloc(size_product(nats, sizeof *ats + 1)); + + /* + * Allocate the ATS and TYPES arrays via a single malloc, as this is a bit + * faster. + */ + zic_t *ats = emalloc(MAXALIGN(size_product(nats, sizeof *ats + 1))); void *typesptr = ats + nats; unsigned char *types = typesptr; + struct timerange rangeall, + range32, + range64; /* * Sort. @@ -1899,14 +2086,14 @@ writezone(const char *const name, const char *const string, char version) toi = 0; fromi = 0; - while (fromi < timecnt && attypes[fromi].at < early_time) - ++fromi; for (; fromi < timecnt; ++fromi) { - if (toi > 1 && ((attypes[fromi].at + - gmtoffs[attypes[toi - 1].type]) <= - (attypes[toi - 1].at + - gmtoffs[attypes[toi - 2].type]))) + if (toi != 0 + && ((attypes[fromi].at + + utoffs[attypes[toi - 1].type]) + <= (attypes[toi - 1].at + + utoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { attypes[toi - 1].type = attypes[fromi].type; @@ -1914,7 +2101,12 @@ writezone(const char *const name, const char *const string, char version) } if (toi == 0 || attypes[fromi].dontmerge - || attypes[toi - 1].type != attypes[fromi].type) + || (utoffs[attypes[toi - 1].type] + != utoffs[attypes[fromi].type]) + || (isdsts[attypes[toi - 1].type] + != isdsts[attypes[fromi].type]) + || (desigidx[attypes[toi - 1].type] + != desigidx[attypes[fromi].type])) attypes[toi++] = attypes[fromi]; } timecnt = toi; @@ -1940,20 +2132,6 @@ writezone(const char *const name, const char *const string, char version) types[i] = attypes[i].type; } - /* - * Work around QTBUG-53071 for time stamps less than y2038_boundary - 1, - * by inserting a no-op transition at time y2038_boundary - 1. This works - * only for timestamps before the boundary, which should be good enough in - * practice as QTBUG-53071 should be long-dead by 2038. - */ - if (WORK_AROUND_QTBUG_53071 && timecnt != 0 - && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) - { - ats[timecnt] = y2038_boundary - 1; - types[timecnt] = types[timecnt - 1]; - timecnt++; - } - /* * Correct for leap seconds. */ @@ -1969,35 +2147,28 @@ writezone(const char *const name, const char *const string, char version) } /* - * Figure out 32-bit-limited starts and counts. + * Work around QTBUG-53071 for timestamps less than y2038_boundary - 1, by + * inserting a no-op transition at time y2038_boundary - 1. This works + * only for timestamps before the boundary, which should be good enough in + * practice as QTBUG-53071 should be long-dead by 2038. Do this after + * correcting for leap seconds, as the idea is to insert a transition just + * before 32-bit pg_time_t rolls around, and this occurs at a slightly + * different moment if transitions are leap-second corrected. */ - timecnt32 = timecnt; - timei32 = 0; - leapcnt32 = leapcnt; - leapi32 = 0; - while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) - --timecnt32; - while (timecnt32 > 0 && !is32(ats[timei32])) + if (WORK_AROUND_QTBUG_53071 && timecnt != 0 && want_bloat() + && ats[timecnt - 1] < y2038_boundary - 1 && strchr(string, '<')) { - --timecnt32; - ++timei32; + ats[timecnt] = y2038_boundary - 1; + types[timecnt] = types[timecnt - 1]; + timecnt++; } - /* - * Output an INT32_MIN "transition" if appropriate; see below. - */ - if (timei32 > 0 && ats[timei32] > PG_INT32_MIN) - { - --timei32; - ++timecnt32; - } - while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) - --leapcnt32; - while (leapcnt32 > 0 && !is32(trans[leapi32])) - { - --leapcnt32; - ++leapi32; - } + rangeall.defaulttype = defaulttype; + rangeall.base = rangeall.leapbase = 0; + rangeall.count = timecnt; + rangeall.leapcount = leapcnt; + range64 = limitrange(rangeall, lo_time, hi_time, ats, types); + range32 = limitrange(range64, PG_INT32_MIN, PG_INT32_MAX, ats, types); /* * Remove old file, if any, to snap links. @@ -2038,9 +2209,17 @@ writezone(const char *const name, const char *const string, char version) int thisleapi, thisleapcnt, thisleaplim; - int writetype[TZ_MAX_TYPES]; + int currenttype, + thisdefaulttype; + bool locut, + hicut; + zic_t lo; + int old0; + char omittype[TZ_MAX_TYPES]; int typemap[TZ_MAX_TYPES]; - int thistypecnt; + int thistypecnt, + stdcnt, + utcnt; char thischars[TZ_MAX_CHARS]; int thischarcnt; bool toomanytimes; @@ -2048,46 +2227,79 @@ writezone(const char *const name, const char *const string, char version) if (pass == 1) { - thistimei = timei32; - thistimecnt = timecnt32; + /* + * Arguably the default time type in the 32-bit data should be + * range32.defaulttype, which is suited for timestamps just before + * PG_INT32_MIN. However, zic traditionally used the time type of + * the indefinite past instead. Internet RFC 8532 says readers + * should ignore 32-bit data, so this discrepancy matters only to + * obsolete readers where the traditional type might be more + * appropriate even if it's "wrong". So, use the historical zic + * value, unless -r specifies a low cutoff that excludes some + * 32-bit timestamps. + */ + thisdefaulttype = (lo_time <= PG_INT32_MIN + ? range64.defaulttype + : range32.defaulttype); + + thistimei = range32.base; + thistimecnt = range32.count; toomanytimes = thistimecnt >> 31 >> 1 != 0; - thisleapi = leapi32; - thisleapcnt = leapcnt32; + thisleapi = range32.leapbase; + thisleapcnt = range32.leapcount; + locut = PG_INT32_MIN < lo_time; + hicut = hi_time < PG_INT32_MAX; } else { - thistimei = 0; - thistimecnt = timecnt; + thisdefaulttype = range64.defaulttype; + thistimei = range64.base; + thistimecnt = range64.count; toomanytimes = thistimecnt >> 31 >> 31 >> 2 != 0; - thisleapi = 0; - thisleapcnt = leapcnt; + thisleapi = range64.leapbase; + thisleapcnt = range64.leapcount; + locut = min_time < lo_time; + hicut = hi_time < max_time; } if (toomanytimes) error(_("too many transition times")); + + /* + * Keep the last too-low transition if no transition is exactly at LO. + * The kept transition will be output as a LO "transition"; see + * "Output a LO_TIME transition" below. This is needed when the + * output is truncated at the start, and is also useful when catering + * to buggy 32-bit clients that do not use time type 0 for timestamps + * before the first transition. + */ + if (0 < thistimei && ats[thistimei] != lo_time) + { + thistimei--; + thistimecnt++; + locut = false; + } + thistimelim = thistimei + thistimecnt; thisleaplim = thisleapi + thisleapcnt; - for (i = 0; i < typecnt; ++i) - writetype[i] = thistimecnt == timecnt; - if (thistimecnt == 0) + if (thistimecnt != 0) { - /* - * No transition times fall in the current (32- or 64-bit) window. - */ - if (typecnt != 0) - writetype[typecnt - 1] = true; + if (ats[thistimei] == lo_time) + locut = false; + if (hi_time < ZIC_MAX && ats[thistimelim - 1] == hi_time + 1) + hicut = false; } - else - { - for (i = thistimei - 1; i < thistimelim; ++i) - if (i >= 0) - writetype[types[i]] = true; + memset(omittype, true, typecnt); + omittype[thisdefaulttype] = false; + for (i = thistimei; i < thistimelim; i++) + omittype[types[i]] = false; + + /* + * Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap + * OLD0 and THISDEFAULTTYPE so that THISDEFAULTTYPE appears as type 0 + * in the output instead of OLD0. TYPEMAP also omits unused types. + */ + old0 = strlen(omittype); - /* - * For America/Godthab and Antarctica/Palmer - */ - if (thistimei == 0) - writetype[0] = true; - } #ifndef LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH /* @@ -2096,6 +2308,7 @@ writezone(const char *const name, const char *const string, char version) * offset, append an (unused) copy of the most recently used type (to * help get global "altzone" and "timezone" variables set correctly). */ + if (want_bloat()) { int mrudst, mrustd, @@ -2109,56 +2322,69 @@ writezone(const char *const name, const char *const string, char version) mrudst = types[i]; else mrustd = types[i]; - for (i = 0; i < typecnt; ++i) - if (writetype[i]) + for (i = old0; i < typecnt; i++) + { + int h = (i == old0 ? thisdefaulttype + : i == thisdefaulttype ? old0 : i); + + if (!omittype[h]) { - if (isdsts[i]) + if (isdsts[h]) hidst = i; else histd = i; } + } if (hidst >= 0 && mrudst >= 0 && hidst != mrudst && - gmtoffs[hidst] != gmtoffs[mrudst]) + utoffs[hidst] != utoffs[mrudst]) { isdsts[mrudst] = -1; - type = addtype(gmtoffs[mrudst], - &chars[abbrinds[mrudst]], + type = addtype(utoffs[mrudst], + &chars[desigidx[mrudst]], true, ttisstds[mrudst], - ttisgmts[mrudst]); + ttisuts[mrudst]); isdsts[mrudst] = 1; - writetype[type] = true; + omittype[type] = false; } if (histd >= 0 && mrustd >= 0 && histd != mrustd && - gmtoffs[histd] != gmtoffs[mrustd]) + utoffs[histd] != utoffs[mrustd]) { isdsts[mrustd] = -1; - type = addtype(gmtoffs[mrustd], - &chars[abbrinds[mrustd]], + type = addtype(utoffs[mrustd], + &chars[desigidx[mrustd]], false, ttisstds[mrustd], - ttisgmts[mrustd]); + ttisuts[mrustd]); isdsts[mrustd] = 0; - writetype[type] = true; + omittype[type] = false; } } #endif /* !defined * LEAVE_SOME_PRE_2011_SYSTEMS_IN_THE_LURCH */ thistypecnt = 0; - for (i = 0; i < typecnt; ++i) - typemap[i] = writetype[i] ? thistypecnt++ : -1; + for (i = old0; i < typecnt; i++) + if (!omittype[i]) + typemap[i == old0 ? thisdefaulttype + : i == thisdefaulttype ? old0 : i] + = thistypecnt++; + for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) indmap[i] = -1; - thischarcnt = 0; - for (i = 0; i < typecnt; ++i) + thischarcnt = stdcnt = utcnt = 0; + for (i = old0; i < typecnt; i++) { char *thisabbr; - if (!writetype[i]) + if (omittype[i]) continue; - if (indmap[abbrinds[i]] >= 0) + if (ttisstds[i]) + stdcnt = thistypecnt; + if (ttisuts[i]) + utcnt = thistypecnt; + if (indmap[desigidx[i]] >= 0) continue; - thisabbr = &chars[abbrinds[i]]; + thisabbr = &chars[desigidx[i]]; for (j = 0; j < thischarcnt; ++j) if (strcmp(&thischars[j], thisabbr) == 0) break; @@ -2167,70 +2393,114 @@ writezone(const char *const name, const char *const string, char version) strcpy(&thischars[thischarcnt], thisabbr); thischarcnt += strlen(thisabbr) + 1; } - indmap[abbrinds[i]] = j; + indmap[desigidx[i]] = j; + } + if (pass == 1 && !want_bloat()) + { + utcnt = stdcnt = thisleapcnt = 0; + thistimecnt = -(locut + hicut); + thistypecnt = thischarcnt = 1; + thistimelim = thistimei; } #define DO(field) fwrite(tzh.field, sizeof tzh.field, 1, fp) tzh = tzh0; - strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); + memcpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); tzh.tzh_version[0] = version; - convert(thistypecnt, tzh.tzh_ttisgmtcnt); - convert(thistypecnt, tzh.tzh_ttisstdcnt); + convert(utcnt, tzh.tzh_ttisutcnt); + convert(stdcnt, tzh.tzh_ttisstdcnt); convert(thisleapcnt, tzh.tzh_leapcnt); - convert(thistimecnt, tzh.tzh_timecnt); + convert(locut + thistimecnt + hicut, tzh.tzh_timecnt); convert(thistypecnt, tzh.tzh_typecnt); convert(thischarcnt, tzh.tzh_charcnt); DO(tzh_magic); DO(tzh_version); DO(tzh_reserved); - DO(tzh_ttisgmtcnt); + DO(tzh_ttisutcnt); DO(tzh_ttisstdcnt); DO(tzh_leapcnt); DO(tzh_timecnt); DO(tzh_typecnt); DO(tzh_charcnt); #undef DO - for (i = thistimei; i < thistimelim; ++i) - if (pass == 1) + if (pass == 1 && !want_bloat()) + { + /* Output a minimal data block with just one time type. */ + puttzcode(0, fp); /* utoff */ + putc(0, fp); /* dst */ + putc(0, fp); /* index of abbreviation */ + putc(0, fp); /* empty-string abbreviation */ + continue; + } - /* - * Output an INT32_MIN "transition" if appropriate; see above. - */ - puttzcode(((ats[i] < PG_INT32_MIN) ? - PG_INT32_MIN : ats[i]), fp); - else + /* PG: print current timezone abbreviations if requested */ + if (print_abbrevs && pass == 2) + { + /* Print "type" data for periods ending after print_cutoff */ + for (i = thistimei; i < thistimelim; ++i) { - puttzcode64(ats[i], fp); - - /* Print current timezone abbreviations if requested */ - if (print_abbrevs && - (i == thistimelim - 1 || ats[i + 1] > print_cutoff)) + if (i == thistimelim - 1 || ats[i + 1] > print_cutoff) { - unsigned char tm = typemap[types[i]]; - char *thisabbrev = &thischars[indmap[abbrinds[tm]]]; - - /* filter out assorted junk entries */ - if (strcmp(thisabbrev, GRANDPARENTED) != 0 && - strcmp(thisabbrev, "zzz") != 0) - fprintf(stdout, "%s\t" INT64_FORMAT "%s\n", - thisabbrev, - gmtoffs[tm], - isdsts[tm] ? "\tD" : ""); + unsigned char tm = types[i]; + char *thisabbrev = &thischars[indmap[desigidx[tm]]]; + + fprintf(stdout, "%s\t" INT64_FORMAT "%s\n", + thisabbrev, + utoffs[tm], + isdsts[tm] ? "\tD" : ""); } } + /* Print the default type if we have no transitions at all */ + if (thistimei >= thistimelim) + { + unsigned char tm = defaulttype; + char *thisabbrev = &thischars[indmap[desigidx[tm]]]; + + fprintf(stdout, "%s\t" INT64_FORMAT "%s\n", + thisabbrev, + utoffs[tm], + isdsts[tm] ? "\tD" : ""); + } + } + + /* + * Output a LO_TIME transition if needed; see limitrange. But do not + * go below the minimum representable value for this pass. + */ + lo = pass == 1 && lo_time < PG_INT32_MIN ? PG_INT32_MIN : lo_time; + + if (locut) + puttzcodepass(lo, fp, pass); for (i = thistimei; i < thistimelim; ++i) { - unsigned char uc; + zic_t at = ats[i] < lo ? lo : ats[i]; - uc = typemap[types[i]]; - fwrite(&uc, sizeof uc, 1, fp); + puttzcodepass(at, fp, pass); + } + if (hicut) + puttzcodepass(hi_time + 1, fp, pass); + currenttype = 0; + if (locut) + putc(currenttype, fp); + for (i = thistimei; i < thistimelim; ++i) + { + currenttype = typemap[types[i]]; + putc(currenttype, fp); } - for (i = 0; i < typecnt; ++i) - if (writetype[i]) + if (hicut) + putc(currenttype, fp); + + for (i = old0; i < typecnt; i++) + { + int h = (i == old0 ? thisdefaulttype + : i == thisdefaulttype ? old0 : i); + + if (!omittype[h]) { - puttzcode(gmtoffs[i], fp); - putc(isdsts[i], fp); - putc((unsigned char) indmap[abbrinds[i]], fp); + puttzcode(utoffs[h], fp); + putc(isdsts[h], fp); + putc(indmap[desigidx[h]], fp); } + } if (thischarcnt != 0) fwrite(thischars, sizeof thischars[0], thischarcnt, fp); @@ -2258,22 +2528,21 @@ writezone(const char *const name, const char *const string, char version) ++j; j = types[j - 1]; } - todo = tadd(trans[i], -gmtoffs[j]); + todo = tadd(trans[i], -utoffs[j]); } else todo = trans[i]; - if (pass == 1) - puttzcode(todo, fp); - else - puttzcode64(todo, fp); + puttzcodepass(todo, fp, pass); puttzcode(corr[i], fp); } - for (i = 0; i < typecnt; ++i) - if (writetype[i]) - putc(ttisstds[i], fp); - for (i = 0; i < typecnt; ++i) - if (writetype[i]) - putc(ttisgmts[i], fp); + if (stdcnt != 0) + for (i = old0; i < typecnt; i++) + if (!omittype[i]) + putc(ttisstds[i], fp); + if (utcnt != 0) + for (i = old0; i < typecnt; i++) + if (!omittype[i]) + putc(ttisuts[i], fp); } fprintf(fp, "\n%s\n", string); close_file(fp, directory, name); @@ -2299,7 +2568,7 @@ abbroffset(char *buf, zic_t offset) offset /= MINSPERHOUR; if (100 <= offset) { - error(_("%%z UTC offset magnitude exceeds 99:59:59")); + error(_("%%z UT offset magnitude exceeds 99:59:59")); return "%z"; } else @@ -2326,7 +2595,7 @@ abbroffset(char *buf, zic_t offset) static size_t doabbr(char *abbr, struct zone const *zp, char const *letters, - zic_t stdoff, bool doquotes) + bool isdst, zic_t save, bool doquotes) { char *cp; char *slashp; @@ -2339,12 +2608,12 @@ doabbr(char *abbr, struct zone const *zp, char const *letters, char letterbuf[PERCENT_Z_LEN_BOUND + 1]; if (zp->z_format_specifier == 'z') - letters = abbroffset(letterbuf, zp->z_gmtoff + stdoff); + letters = abbroffset(letterbuf, zp->z_stdoff + save); else if (!letters) letters = "%s"; sprintf(abbr, format, letters); } - else if (stdoff != 0) + else if (isdst) { strcpy(abbr, slashp + 1); } @@ -2411,8 +2680,7 @@ stringoffset(char *result, zic_t offset) } static int -stringrule(char *result, const struct rule *const rp, const zic_t dstoff, - const zic_t gmtoff) +stringrule(char *result, struct rule *const rp, zic_t save, zic_t stdoff) { zic_t tod = rp->r_tod; int compat = 0; @@ -2469,10 +2737,10 @@ stringrule(char *result, const struct rule *const rp, const zic_t dstoff, result += sprintf(result, "M%d.%d.%d", rp->r_month + 1, week, wday); } - if (rp->r_todisgmt) - tod += gmtoff; - if (rp->r_todisstd && rp->r_stdoff == 0) - tod += dstoff; + if (rp->r_todisut) + tod += stdoff; + if (rp->r_todisstd && !rp->r_isdst) + tod += save; if (tod != 2 * SECSPERMIN * MINSPERHOUR) { *result++ = '/'; @@ -2506,10 +2774,6 @@ rule_cmp(struct rule const *a, struct rule const *b) return a->r_dayofmonth - b->r_dayofmonth; } -enum -{ -YEAR_BY_YEAR_ZONE = 1}; - static int stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) { @@ -2527,6 +2791,14 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) dstr; result[0] = '\0'; + + /* + * Internet RFC 8536 section 5.1 says to use an empty TZ string if future + * timestamps are truncated. + */ + if (hi_time < max_time) + return -1; + zp = zpfirst + zonecount - 1; stdrp = dstrp = NULL; for (i = 0; i < zp->z_nrules; ++i) @@ -2536,7 +2808,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) continue; if (rp->r_yrtype != NULL) continue; - if (rp->r_stdoff == 0) + if (!rp->r_isdst) { if (stdrp == NULL) stdrp = rp; @@ -2562,47 +2834,40 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) for (i = 0; i < zp->z_nrules; ++i) { rp = &zp->z_rules[i]; - if (rp->r_stdoff == 0 && rule_cmp(stdabbrrp, rp) < 0) + if (!rp->r_isdst && rule_cmp(stdabbrrp, rp) < 0) stdabbrrp = rp; if (rule_cmp(stdrp, rp) < 0) stdrp = rp; } - - /* - * Horrid special case: if year is 2037, presume this is a zone - * handled on a year-by-year basis; do not try to apply a rule to the - * zone. - */ - if (stdrp != NULL && stdrp->r_hiyear == 2037) - return YEAR_BY_YEAR_ZONE; - - if (stdrp != NULL && stdrp->r_stdoff != 0) + if (stdrp != NULL && stdrp->r_isdst) { /* Perpetual DST. */ dstr.r_month = TM_JANUARY; dstr.r_dycode = DC_DOM; dstr.r_dayofmonth = 1; dstr.r_tod = 0; - dstr.r_todisstd = dstr.r_todisgmt = false; - dstr.r_stdoff = stdrp->r_stdoff; + dstr.r_todisstd = dstr.r_todisut = false; + dstr.r_isdst = stdrp->r_isdst; + dstr.r_save = stdrp->r_save; dstr.r_abbrvar = stdrp->r_abbrvar; stdr.r_month = TM_DECEMBER; stdr.r_dycode = DC_DOM; stdr.r_dayofmonth = 31; - stdr.r_tod = SECSPERDAY + stdrp->r_stdoff; - stdr.r_todisstd = stdr.r_todisgmt = false; - stdr.r_stdoff = 0; + stdr.r_tod = SECSPERDAY + stdrp->r_save; + stdr.r_todisstd = stdr.r_todisut = false; + stdr.r_isdst = false; + stdr.r_save = 0; stdr.r_abbrvar = (stdabbrrp ? stdabbrrp->r_abbrvar : ""); dstrp = &dstr; stdrp = &stdr; } } - if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_stdoff != 0)) + if (stdrp == NULL && (zp->z_nrules != 0 || zp->z_isdst)) return -1; abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; - len = doabbr(result, zp, abbrvar, 0, true); - offsetlen = stringoffset(result + len, -zp->z_gmtoff); + len = doabbr(result, zp, abbrvar, false, 0, true); + offsetlen = stringoffset(result + len, -zp->z_stdoff); if (!offsetlen) { result[0] = '\0'; @@ -2611,11 +2876,12 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) len += offsetlen; if (dstrp == NULL) return compat; - len += doabbr(result + len, zp, dstrp->r_abbrvar, dstrp->r_stdoff, true); - if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) + len += doabbr(result + len, zp, dstrp->r_abbrvar, + dstrp->r_isdst, dstrp->r_save, true); + if (dstrp->r_save != SECSPERMIN * MINSPERHOUR) { offsetlen = stringoffset(result + len, - -(zp->z_gmtoff + dstrp->r_stdoff)); + -(zp->z_stdoff + dstrp->r_save)); if (!offsetlen) { result[0] = '\0'; @@ -2624,7 +2890,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) len += offsetlen; } result[len++] = ','; - c = stringrule(result + len, dstrp, dstrp->r_stdoff, zp->z_gmtoff); + c = stringrule(result + len, dstrp, dstrp->r_save, zp->z_stdoff); if (c < 0) { result[0] = '\0'; @@ -2634,7 +2900,7 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount) compat = c; len += strlen(result + len); result[len++] = ','; - c = stringrule(result + len, stdrp, dstrp->r_stdoff, zp->z_gmtoff); + c = stringrule(result + len, stdrp, dstrp->r_save, zp->z_stdoff); if (c < 0) { result[0] = '\0'; @@ -2656,12 +2922,12 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) useuntil; zic_t starttime, untiltime; - zic_t gmtoff; zic_t stdoff; + zic_t save; zic_t year; zic_t startoff; bool startttisstd; - bool startttisgmt; + bool startttisut; int type; char *startbuf; char *ab; @@ -2676,6 +2942,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) zic_t one = 1; zic_t y2038_boundary = one << 31; zic_t max_year0; + int defaulttype = -1; max_abbr_len = 2 + max_format_len + max_abbrvar_len; max_envvar_len = 2 * max_abbr_len + 5 * 9; @@ -2698,7 +2965,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) * startttisstd. */ startttisstd = false; - startttisgmt = false; + startttisut = false; min_year = max_year = EPOCH_YEAR; if (leapseen) { @@ -2727,14 +2994,14 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) */ compat = stringzone(envvar, zpfirst, zonecount); version = compat < 2013 ? ZIC_VERSION_PRE_2013 : ZIC_VERSION; - do_extend = compat < 0 || compat == YEAR_BY_YEAR_ZONE; + do_extend = compat < 0; if (noise) { if (!*envvar) warning("%s %s", _("no POSIX environment variable for zone"), zpfirst->z_name); - else if (compat != 0 && compat != YEAR_BY_YEAR_ZONE) + else if (compat != 0) { /* * Circa-COMPAT clients, and earlier clients, might not work for @@ -2783,44 +3050,50 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) max_year = min_year + years_of_observations; } } - - /* - * For the benefit of older systems, generate data from 1900 through 2038. - */ - if (min_year > 1900) - min_year = 1900; max_year0 = max_year; - if (max_year < 2038) - max_year = 2038; + if (want_bloat()) + { + /* + * For the benefit of older systems, generate data from 1900 through + * 2038. + */ + if (min_year > 1900) + min_year = 1900; + if (max_year < 2038) + max_year = 2038; + } + for (i = 0; i < zonecount; ++i) { + struct rule *prevrp = NULL; + /* * A guess that may well be corrected later. */ - stdoff = 0; + save = 0; zp = &zpfirst[i]; - usestart = i > 0 && (zp - 1)->z_untiltime > early_time; + usestart = i > 0 && (zp - 1)->z_untiltime > min_time; useuntil = i < (zonecount - 1); - if (useuntil && zp->z_untiltime <= early_time) + if (useuntil && zp->z_untiltime <= min_time) continue; - gmtoff = zp->z_gmtoff; + stdoff = zp->z_stdoff; eat(zp->z_filename, zp->z_linenum); *startbuf = '\0'; - startoff = zp->z_gmtoff; + startoff = zp->z_stdoff; if (zp->z_nrules == 0) { - stdoff = zp->z_stdoff; - doabbr(startbuf, zp, NULL, stdoff, false); - type = addtype(oadd(zp->z_gmtoff, stdoff), - startbuf, stdoff != 0, startttisstd, - startttisgmt); + save = zp->z_save; + doabbr(startbuf, zp, NULL, zp->z_isdst, save, false); + type = addtype(oadd(zp->z_stdoff, save), + startbuf, zp->z_isdst, startttisstd, + startttisut); if (usestart) { addtt(starttime, type); usestart = false; } else - addtt(early_time, type); + defaulttype = type; } else for (year = min_year; year <= max_year; ++year) @@ -2859,16 +3132,16 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) if (useuntil) { /* - * Turn untiltime into UT assuming the current gmtoff - * and stdoff values. + * Turn untiltime into UT assuming the current stdoff + * and save values. */ untiltime = zp->z_untiltime; - if (!zp->z_untilrule.r_todisgmt) + if (!zp->z_untilrule.r_todisut) untiltime = tadd(untiltime, - -gmtoff); + -stdoff); if (!zp->z_untilrule.r_todisstd) untiltime = tadd(untiltime, - -stdoff); + -save); } /* @@ -2883,9 +3156,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) continue; eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - offset = rp->r_todisgmt ? 0 : gmtoff; + offset = rp->r_todisut ? 0 : stdoff; if (!rp->r_todisstd) - offset = oadd(offset, stdoff); + offset = oadd(offset, save); jtime = rp->r_temp; if (jtime == min_time || jtime == max_time) @@ -2916,44 +3189,54 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) rp->r_todo = false; if (useuntil && ktime >= untiltime) break; - stdoff = rp->r_stdoff; + save = rp->r_save; if (usestart && ktime == starttime) usestart = false; if (usestart) { if (ktime < starttime) { - startoff = oadd(zp->z_gmtoff, - stdoff); + startoff = oadd(zp->z_stdoff, + save); doabbr(startbuf, zp, rp->r_abbrvar, - rp->r_stdoff, + rp->r_isdst, + rp->r_save, false); continue; } - if (*startbuf == '\0' && - startoff == oadd(zp->z_gmtoff, - stdoff)) + if (*startbuf == '\0' + && startoff == oadd(zp->z_stdoff, + save)) { doabbr(startbuf, zp, rp->r_abbrvar, - rp->r_stdoff, + rp->r_isdst, + rp->r_save, false); } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); doabbr(ab, zp, rp->r_abbrvar, - rp->r_stdoff, false); - offset = oadd(zp->z_gmtoff, rp->r_stdoff); - type = addtype(offset, ab, rp->r_stdoff != 0, - rp->r_todisstd, rp->r_todisgmt); + rp->r_isdst, rp->r_save, false); + offset = oadd(zp->z_stdoff, rp->r_save); + if (!want_bloat() && !useuntil && !do_extend + && prevrp + && rp->r_hiyear == ZIC_MAX + && prevrp->r_hiyear == ZIC_MAX) + break; + type = addtype(offset, ab, rp->r_isdst, + rp->r_todisstd, rp->r_todisut); + if (defaulttype < 0 && !rp->r_isdst) + defaulttype = type; if (rp->r_hiyear == ZIC_MAX && !(0 <= lastatmax && ktime < attypes[lastatmax].at)) lastatmax = timecnt; addtt(ktime, type); + prevrp = rp; } } if (usestart) @@ -2967,11 +3250,15 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) if (*startbuf == '\0') error(_("cannot determine time zone abbreviation to use just after until time")); else - addtt(starttime, - addtype(startoff, startbuf, - startoff != zp->z_gmtoff, - startttisstd, - startttisgmt)); + { + bool isdst = startoff != zp->z_stdoff; + + type = addtype(startoff, startbuf, isdst, + startttisstd, startttisut); + if (defaulttype < 0 && !isdst) + defaulttype = type; + addtt(starttime, type); + } } /* @@ -2980,14 +3267,16 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) if (useuntil) { startttisstd = zp->z_untilrule.r_todisstd; - startttisgmt = zp->z_untilrule.r_todisgmt; + startttisut = zp->z_untilrule.r_todisut; starttime = zp->z_untiltime; if (!startttisstd) + starttime = tadd(starttime, -save); + if (!startttisut) starttime = tadd(starttime, -stdoff); - if (!startttisgmt) - starttime = tadd(starttime, -gmtoff); } } + if (defaulttype < 0) + defaulttype = 0; if (0 <= lastatmax) attypes[lastatmax].dontmerge = true; if (do_extend) @@ -3008,16 +3297,17 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) xr.r_dycode = DC_DOM; xr.r_dayofmonth = 1; xr.r_tod = 0; - for (lastat = &attypes[0], i = 1; i < timecnt; i++) + for (lastat = attypes, i = 1; i < timecnt; i++) if (attypes[i].at > lastat->at) lastat = &attypes[i]; - if (lastat->at < rpytime(&xr, max_year - 1)) + if (!lastat || lastat->at < rpytime(&xr, max_year - 1)) { - addtt(rpytime(&xr, max_year + 1), typecnt - 1); + addtt(rpytime(&xr, max_year + 1), + lastat ? lastat->type : defaulttype); attypes[timecnt - 1].dontmerge = true; } } - writezone(zpfirst->z_name, envvar, version); + writezone(zpfirst->z_name, envvar, version, defaulttype); free(startbuf); free(ab); free(envvar); @@ -3026,21 +3316,6 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) static void addtt(zic_t starttime, int type) { - if (starttime <= early_time - || (timecnt == 1 && attypes[0].at < early_time)) - { - gmtoffs[0] = gmtoffs[type]; - isdsts[0] = isdsts[type]; - ttisstds[0] = ttisstds[type]; - ttisgmts[0] = ttisgmts[type]; - if (abbrinds[type] != 0) - strcpy(chars, &chars[abbrinds[type]]); - abbrinds[0] = 0; - charcnt = strlen(chars) + 1; - typecnt = 1; - timecnt = 0; - type = 0; - } attypes = growalloc(attypes, sizeof *attypes, timecnt, &timecnt_alloc); attypes[timecnt].at = starttime; attypes[timecnt].dontmerge = false; @@ -3049,22 +3324,31 @@ addtt(zic_t starttime, int type) } static int -addtype(zic_t gmtoff, char const *abbr, bool isdst, bool ttisstd, bool ttisgmt) +addtype(zic_t utoff, char const *abbr, bool isdst, bool ttisstd, bool ttisut) { int i, j; - /* - * See if there's already an entry for this zone type. If so, just return - * its index. - */ - for (i = 0; i < typecnt; ++i) + if (!(-1L - 2147483647L <= utoff && utoff <= 2147483647L)) + { + error(_("UT offset out of range")); + exit(EXIT_FAILURE); + } + if (!want_bloat()) + ttisstd = ttisut = false; + + for (j = 0; j < charcnt; ++j) + if (strcmp(&chars[j], abbr) == 0) + break; + if (j == charcnt) + newabbr(abbr); + else { - if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && - strcmp(abbr, &chars[abbrinds[i]]) == 0 && - ttisstd == ttisstds[i] && - ttisgmt == ttisgmts[i]) - return i; + /* If there's already an entry, return its index. */ + for (i = 0; i < typecnt; i++) + if (utoff == utoffs[i] && isdst == isdsts[i] && j == desigidx[i] + && ttisstd == ttisstds[i] && ttisut == ttisuts[i]) + return i; } /* @@ -3075,23 +3359,12 @@ addtype(zic_t gmtoff, char const *abbr, bool isdst, bool ttisstd, bool ttisgmt) error(_("too many local time types")); exit(EXIT_FAILURE); } - if (!(-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) - { - error(_("UT offset out of range")); - exit(EXIT_FAILURE); - } - gmtoffs[i] = gmtoff; + i = typecnt++; + utoffs[i] = utoff; isdsts[i] = isdst; ttisstds[i] = ttisstd; - ttisgmts[i] = ttisgmt; - - for (j = 0; j < charcnt; ++j) - if (strcmp(&chars[j], abbr) == 0) - break; - if (j == charcnt) - newabbr(abbr); - abbrinds[i] = j; - ++typecnt; + ttisuts[i] = ttisut; + desigidx[i] = j; return i; } @@ -3278,7 +3551,7 @@ is_alpha(char a) } /* If A is an uppercase character in the C locale, return its lowercase - * counterpart. Otherwise, return A. */ + counterpart. Otherwise, return A. */ static char lowerit(char a) { @@ -3425,9 +3698,9 @@ byword(const char *word, const struct lookup *table) return NULL; /* multiple inexact matches */ } - /* Warn about any backward-compatibility issue with pre-2017c zic. */ - if (foundlp) + if (foundlp && noise) { + /* Warn about any backward-compatibility issue with pre-2017c zic. */ bool pre_2017c_match = false; for (lp = table; lp->l_word; lp++) @@ -3545,6 +3818,18 @@ rpytime(const struct rule *rp, zic_t wantedy) dayoff = 0; m = TM_JANUARY; y = EPOCH_YEAR; + if (y < wantedy) + { + wantedy -= y; + dayoff = (wantedy / YEARSPERREPEAT) * (SECSPERREPEAT / SECSPERDAY); + wantedy %= YEARSPERREPEAT; + wantedy += y; + } + else if (wantedy < 0) + { + dayoff = (wantedy / YEARSPERREPEAT) * (SECSPERREPEAT / SECSPERDAY); + wantedy %= YEARSPERREPEAT; + } while (wantedy != y) { if (wantedy > y) @@ -3623,7 +3908,6 @@ will not work with pre-2004 versions of zic")); if (dayoff > max_time / SECSPERDAY) return max_time; t = (zic_t) dayoff * SECSPERDAY; - return tadd(t, rp->r_tod); } diff --git a/src/tools/FAQ2txt b/src/tools/FAQ2txt deleted file mode 100755 index ab61d4d5f8c..00000000000 --- a/src/tools/FAQ2txt +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -# src/tools/FAQ2txt: - -# Converts doc/src/FAQ/FAQ.html to text file doc/FAQ - -lynx -force_html -dont_wrap_pre -dump -hiddenlinks=ignore -nolist "$@" diff --git a/src/tools/PerfectHash.pm b/src/tools/PerfectHash.pm new file mode 100644 index 00000000000..54f5d4e9940 --- /dev/null +++ b/src/tools/PerfectHash.pm @@ -0,0 +1,376 @@ +#---------------------------------------------------------------------- +# +# PerfectHash.pm +# Perl module that constructs minimal perfect hash functions +# +# This code constructs a minimal perfect hash function for the given +# set of keys, using an algorithm described in +# "An optimal algorithm for generating minimal perfect hash functions" +# by Czech, Havas and Majewski in Information Processing Letters, +# 43(5):256-264, October 1992. +# This implementation is loosely based on NetBSD's "nbperf", +# which was written by Joerg Sonnenberger. +# +# The resulting hash function is perfect in the sense that if the presented +# key is one of the original set, it will return the key's index in the set +# (in range 0..N-1). However, the caller must still verify the match, +# as false positives are possible. Also, the hash function may return +# values that are out of range (negative or >= N), due to summing unrelated +# hashtable entries. This indicates that the presented key is definitely +# not in the set. +# +# +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/tools/PerfectHash.pm +# +#---------------------------------------------------------------------- + +package PerfectHash; + +use strict; +use warnings; + + +# At runtime, we'll compute two simple hash functions of the input key, +# and use them to index into a mapping table. The hash functions are just +# multiply-and-add in uint32 arithmetic, with different multipliers and +# initial seeds. All the complexity in this module is concerned with +# selecting hash parameters that will work and building the mapping table. + +# We support making case-insensitive hash functions, though this only +# works for a strict-ASCII interpretation of case insensitivity, +# ie, A-Z maps onto a-z and nothing else. +my $case_fold = 0; + + +# +# Construct a C function implementing a perfect hash for the given keys. +# The C function definition is returned as a string. +# +# The keys should be passed as an array reference. They can be any set +# of Perl strings; it is caller's responsibility that there not be any +# duplicates. (Note that the "strings" can be binary data, but hashing +# e.g. OIDs has endianness hazards that callers must overcome.) +# +# The name to use for the function is specified as the second argument. +# It will be a global function by default, but the caller may prepend +# "static " to the result string if it wants a static function. +# +# Additional options can be specified as keyword-style arguments: +# +# case_fold => bool +# If specified as true, the hash function is case-insensitive, for the +# limited idea of case-insensitivity explained above. +# +# fixed_key_length => N +# If specified, all keys are assumed to have length N bytes, and the +# hash function signature will be just "int f(const void *key)" +# rather than "int f(const void *key, size_t keylen)". +# +sub generate_hash_function +{ + my ($keys_ref, $funcname, %options) = @_; + + # It's not worth passing this around as a parameter; just use a global. + $case_fold = $options{case_fold} || 0; + + # Try different hash function parameters until we find a set that works + # for these keys. The multipliers are chosen to be primes that are cheap + # to calculate via shift-and-add, so don't change them without care. + # (Commonly, random seeds are tried, but we want reproducible results + # from this program so we don't do that.) + my $hash_mult1 = 31; + my $hash_mult2; + my $hash_seed1; + my $hash_seed2; + my @subresult; + FIND_PARAMS: + foreach (127, 257, 521, 1033, 2053) + { + $hash_mult2 = $_; # "foreach $hash_mult2" doesn't work + for ($hash_seed1 = 0; $hash_seed1 < 10; $hash_seed1++) + { + for ($hash_seed2 = 0; $hash_seed2 < 10; $hash_seed2++) + { + @subresult = _construct_hash_table( + $keys_ref, $hash_mult1, $hash_mult2, + $hash_seed1, $hash_seed2); + last FIND_PARAMS if @subresult; + } + } + } + + # Choke if we couldn't find a workable set of parameters. + die "failed to generate perfect hash" if !@subresult; + + # Extract info from _construct_hash_table's result array. + my $elemtype = $subresult[0]; + my @hashtab = @{ $subresult[1] }; + my $nhash = scalar(@hashtab); + + # OK, construct the hash function definition including the hash table. + my $f = ''; + $f .= sprintf "int\n"; + if (defined $options{fixed_key_length}) + { + $f .= sprintf "%s(const void *key)\n{\n", $funcname; + } + else + { + $f .= sprintf "%s(const void *key, size_t keylen)\n{\n", $funcname; + } + $f .= sprintf "\tstatic const %s h[%d] = {\n", $elemtype, $nhash; + for (my $i = 0; $i < $nhash; $i++) + { + $f .= sprintf "%s%6d,%s", + ($i % 8 == 0 ? "\t\t" : " "), + $hashtab[$i], + ($i % 8 == 7 ? "\n" : ""); + } + $f .= sprintf "\n" if ($nhash % 8 != 0); + $f .= sprintf "\t};\n\n"; + $f .= sprintf "\tconst unsigned char *k = (const unsigned char *) key;\n"; + $f .= sprintf "\tsize_t\t\tkeylen = %d;\n", $options{fixed_key_length} + if (defined $options{fixed_key_length}); + $f .= sprintf "\tuint32\t\ta = %d;\n", $hash_seed1; + $f .= sprintf "\tuint32\t\tb = %d;\n\n", $hash_seed2; + $f .= sprintf "\twhile (keylen--)\n\t{\n"; + $f .= sprintf "\t\tunsigned char c = *k++"; + $f .= sprintf " | 0x20" if $case_fold; # see comment below + $f .= sprintf ";\n\n"; + $f .= sprintf "\t\ta = a * %d + c;\n", $hash_mult1; + $f .= sprintf "\t\tb = b * %d + c;\n", $hash_mult2; + $f .= sprintf "\t}\n"; + $f .= sprintf "\treturn h[a %% %d] + h[b %% %d];\n", $nhash, $nhash; + $f .= sprintf "}\n"; + + return $f; +} + + +# Calculate a hash function as the run-time code will do. +# +# If we are making a case-insensitive hash function, we implement that +# by OR'ing 0x20 into each byte of the key. This correctly transforms +# upper-case ASCII into lower-case ASCII, while not changing digits or +# dollar signs. (It does change '_', as well as other characters not +# likely to appear in keywords; this has little effect on the hash's +# ability to discriminate keywords.) +sub _calc_hash +{ + my ($key, $mult, $seed) = @_; + + my $result = $seed; + for my $c (split //, $key) + { + my $cn = ord($c); + $cn |= 0x20 if $case_fold; + $result = ($result * $mult + $cn) % 4294967296; + } + return $result; +} + + +# Attempt to construct a mapping table for a minimal perfect hash function +# for the given keys, using the specified hash parameters. +# +# Returns an array containing the mapping table element type name as the +# first element, and a ref to an array of the table values as the second. +# +# Returns an empty array on failure; then caller should choose different +# hash parameter(s) and try again. +sub _construct_hash_table +{ + my ($keys_ref, $hash_mult1, $hash_mult2, $hash_seed1, $hash_seed2) = @_; + my @keys = @{$keys_ref}; + + # This algorithm is based on a graph whose edges correspond to the + # keys and whose vertices correspond to entries of the mapping table. + # A key's edge links the two vertices whose indexes are the outputs of + # the two hash functions for that key. For K keys, the mapping + # table must have at least 2*K+1 entries, guaranteeing that there's at + # least one unused entry. (In principle, larger mapping tables make it + # easier to find a workable hash and increase the number of inputs that + # can be rejected due to touching unused hashtable entries. In practice, + # neither effect seems strong enough to justify using a larger table.) + my $nedges = scalar @keys; # number of edges + my $nverts = 2 * $nedges + 1; # number of vertices + + # However, it would be very bad if $nverts were exactly equal to either + # $hash_mult1 or $hash_mult2: effectively, that hash function would be + # sensitive to only the last byte of each key. Cases where $nverts is a + # multiple of either multiplier likewise lose information. (But $nverts + # can't actually divide them, if they've been intelligently chosen as + # primes.) We can avoid such problems by adjusting the table size. + while ($nverts % $hash_mult1 == 0 + || $nverts % $hash_mult2 == 0) + { + $nverts++; + } + + # Initialize the array of edges. + my @E = (); + foreach my $kw (@keys) + { + # Calculate hashes for this key. + # The hashes are immediately reduced modulo the mapping table size. + my $hash1 = _calc_hash($kw, $hash_mult1, $hash_seed1) % $nverts; + my $hash2 = _calc_hash($kw, $hash_mult2, $hash_seed2) % $nverts; + + # If the two hashes are the same for any key, we have to fail + # since this edge would itself form a cycle in the graph. + return () if $hash1 == $hash2; + + # Add the edge for this key. + push @E, { left => $hash1, right => $hash2 }; + } + + # Initialize the array of vertices, giving them all empty lists + # of associated edges. (The lists will be hashes of edge numbers.) + my @V = (); + for (my $v = 0; $v < $nverts; $v++) + { + push @V, { edges => {} }; + } + + # Insert each edge in the lists of edges connected to its vertices. + for (my $e = 0; $e < $nedges; $e++) + { + my $v = $E[$e]{left}; + $V[$v]{edges}->{$e} = 1; + + $v = $E[$e]{right}; + $V[$v]{edges}->{$e} = 1; + } + + # Now we attempt to prove the graph acyclic. + # A cycle-free graph is either empty or has some vertex of degree 1. + # Removing the edge attached to that vertex doesn't change this property, + # so doing that repeatedly will reduce the size of the graph. + # If the graph is empty at the end of the process, it was acyclic. + # We track the order of edge removal so that the next phase can process + # them in reverse order of removal. + my @output_order = (); + + # Consider each vertex as a possible starting point for edge-removal. + for (my $startv = 0; $startv < $nverts; $startv++) + { + my $v = $startv; + + # If vertex v is of degree 1 (i.e. exactly 1 edge connects to it), + # remove that edge, and then consider the edge's other vertex to see + # if it is now of degree 1. The inner loop repeats until reaching a + # vertex not of degree 1. + while (scalar(keys(%{ $V[$v]{edges} })) == 1) + { + # Unlink its only edge. + my $e = (keys(%{ $V[$v]{edges} }))[0]; + delete($V[$v]{edges}->{$e}); + + # Unlink the edge from its other vertex, too. + my $v2 = $E[$e]{left}; + $v2 = $E[$e]{right} if ($v2 == $v); + delete($V[$v2]{edges}->{$e}); + + # Push e onto the front of the output-order list. + unshift @output_order, $e; + + # Consider v2 on next iteration of inner loop. + $v = $v2; + } + } + + # We succeeded only if all edges were removed from the graph. + return () if (scalar(@output_order) != $nedges); + + # OK, build the hash table of size $nverts. + my @hashtab = (0) x $nverts; + # We need a "visited" flag array in this step, too. + my @visited = (0) x $nverts; + + # The goal is that for any key, the sum of the hash table entries for + # its first and second hash values is the desired output (i.e., the key + # number). By assigning hash table values in the selected edge order, + # we can guarantee that that's true. This works because the edge first + # removed from the graph (and hence last to be visited here) must have + # at least one vertex it shared with no other edge; hence it will have at + # least one vertex (hashtable entry) still unvisited when we reach it here, + # and we can assign that unvisited entry a value that makes the sum come + # out as we wish. By induction, the same holds for all the other edges. + foreach my $e (@output_order) + { + my $l = $E[$e]{left}; + my $r = $E[$e]{right}; + if (!$visited[$l]) + { + # $hashtab[$r] might be zero, or some previously assigned value. + $hashtab[$l] = $e - $hashtab[$r]; + } + else + { + die "oops, doubly used hashtab entry" if $visited[$r]; + # $hashtab[$l] might be zero, or some previously assigned value. + $hashtab[$r] = $e - $hashtab[$l]; + } + # Now freeze both of these hashtab entries. + $visited[$l] = 1; + $visited[$r] = 1; + } + + # Detect range of values needed in hash table. + my $hmin = $nedges; + my $hmax = 0; + for (my $v = 0; $v < $nverts; $v++) + { + $hmin = $hashtab[$v] if $hashtab[$v] < $hmin; + $hmax = $hashtab[$v] if $hashtab[$v] > $hmax; + } + + # Choose width of hashtable entries. In addition to the actual values, + # we need to be able to store a flag for unused entries, and we wish to + # have the property that adding any other entry value to the flag gives + # an out-of-range result (>= $nedges). + my $elemtype; + my $unused_flag; + + if ( $hmin >= -0x7F + && $hmax <= 0x7F + && $hmin + 0x7F >= $nedges) + { + # int8 will work + $elemtype = 'int8'; + $unused_flag = 0x7F; + } + elsif ($hmin >= -0x7FFF + && $hmax <= 0x7FFF + && $hmin + 0x7FFF >= $nedges) + { + # int16 will work + $elemtype = 'int16'; + $unused_flag = 0x7FFF; + } + elsif ($hmin >= -0x7FFFFFFF + && $hmax <= 0x7FFFFFFF + && $hmin + 0x3FFFFFFF >= $nedges) + { + # int32 will work + $elemtype = 'int32'; + $unused_flag = 0x3FFFFFFF; + } + else + { + die "hash table values too wide"; + } + + # Set any unvisited hashtable entries to $unused_flag. + for (my $v = 0; $v < $nverts; $v++) + { + $hashtab[$v] = $unused_flag if !$visited[$v]; + } + + return ($elemtype, \@hashtab); +} + +1; diff --git a/src/tools/RELEASE_CHANGES b/src/tools/RELEASE_CHANGES index b7963c2449c..920c6e9131d 100644 --- a/src/tools/RELEASE_CHANGES +++ b/src/tools/RELEASE_CHANGES @@ -7,7 +7,7 @@ For All Releases (major, minor, beta, RC) * Release notes o run git log and, if useful, src/tools/git_changelog - o update doc/src/sgml/release.sgml + o update doc/src/sgml/release-NN.sgml in relevant branches o run spellchecker on result o add SGML markup @@ -30,6 +30,11 @@ For Major Releases ================== (in addition to the above) +Note that once the release branch has been forked off in git, +release-note editing happens in that branch, not in HEAD. +Updates to the rest of the documentation usually need to happen +in both HEAD and the branch. + * Release notes o use src/tools/git_changelog o retain the relevant commits @@ -51,17 +56,25 @@ For Major Releases o document all new features o update help output from inside the programs o doc/src/sgml/ref manual pages - o update the sizes specified for installation requirements - (doc/src/sgml/installation.sgml, section "install-requirements") - o update the shared memory size requirement table - (doc/src/sgml/runtime.sgml, section "shared-memory-parameters") * Ports - o update config.guess and config.sub at the start of beta - (from http://savannah.gnu.org/projects/config) o update ports list in doc/src/sgml/installation.sgml o update platform-specific FAQ's, if needed + +Pre-Beta Tasks +============== + +These things should be done at least once per development cycle. +Typically we do them between feature freeze and start of beta test, +but there may be reasons to do them at other times as well. + +* Renumber any manually-assigned OIDs between 8000 and 9999 + to lower numbers, using renumber_oids.pl (see notes in bki.sgml) + +* Update config.guess and config.sub + (from http://savannah.gnu.org/projects/config) + * Update inet/cidr data types with newest Bind patches @@ -73,9 +86,11 @@ Starting a New Development Cycle * Create a branch in git for maintenance of the previous release o on master branch, do: git pull # be sure you have the latest "master" - git push origin master:refs/heads/"new-branch-name" + git branch "new-branch-name" + git push -u origin "new-branch-name" for example, - git push origin master:refs/heads/REL_10_STABLE + git branch REL_11_STABLE + git push -u origin REL_11_STABLE * Add new branch's name to list in src/tools/git_changelog @@ -83,6 +98,13 @@ Starting a New Development Cycle * Run "src/tools/version_stamp.pl devel", then run autoconf +* Create a new doc/src/sgml/release-NN.sgml file (initially just a + placeholder), "git rm" the previous one, and update release.sgml and + filelist.sgml to match. + +* Get the buildfarm's 'branches_of_interest.txt' file updated with the new + branch. + Creating Back-Branch Release Notes ================================== @@ -92,21 +114,30 @@ Creating Back-Branch Release Notes branch tag and not the release date, as commits could have been done between branch stamping and the release date. -* On the git master branch, edit and create SGML markup for the most recent - branch in that branch's release-N.N.sgml file. Minor release notes - should include more small change details because testing is limited. +* Remember to include any older branch commits not in the newest branch. + This can be accomplished by diff'ing the newest and older branch commit + logs and looking for lines that only appear in the older branch, e.g.: + + diff commit-N.N.log commit-O.O.log | grep '^>' + +* On the most recent release branch (*not* in HEAD), edit and create SGML + markup for relevant changes in that branch's release-NN.sgml file. + Minor release notes should include more small change details because + testing is limited. -* Copy this into older branches' release-N.N.sgml files, then remove +* Copy this text into older branches' release-NN.sgml files, then remove items that do not apply based on commit logs for that branch. -* Add any older branch commits not in the newest branch. This can be - accomplished by diff'ing the newest and older branch commit logs and - looking for lines that only appear in the older branch, e.g.: +* The minor release notes for the oldest active branch should always + include a warning about its impending EOL. Use the same boilerplate + text used in previous branches. - diff commit-N.N.log commit-O.O.log | grep '^>' -* Copy the appropriate release-N.N.sgml files into each back branch SGML - directory. +Retiring a Branch +================= + +* Get the buildfarm's 'branches_of_interest.txt' file updated to remove + the retired branch. diff --git a/src/tools/check_bison_recursion.pl b/src/tools/check_bison_recursion.pl index 9421eb93afd..5935acb33d9 100755 --- a/src/tools/check_bison_recursion.pl +++ b/src/tools/check_bison_recursion.pl @@ -16,7 +16,7 @@ # To use: run bison with the -v switch, then feed the produced y.output # file to this script. # -# Copyright (c) 2011-2018, PostgreSQL Global Development Group +# Copyright (c) 2011-2019, PostgreSQL Global Development Group # # src/tools/check_bison_recursion.pl ################################################################# @@ -82,7 +82,7 @@ && !grep { $cur_nonterminal eq $_ } @rhs) { print -"Right recursion in rule $rule_number: $cur_nonterminal := $rhs\n"; + "Right recursion in rule $rule_number: $cur_nonterminal := $rhs\n"; } } } diff --git a/src/tools/copyright.pl b/src/tools/copyright.pl index 41cb93d658a..e0a745f9e55 100755 --- a/src/tools/copyright.pl +++ b/src/tools/copyright.pl @@ -2,7 +2,7 @@ ################################################################# # copyright.pl -- update copyright notices throughout the source tree, idempotently. # -# Copyright (c) 2011-2018, PostgreSQL Global Development Group +# Copyright (c) 2011-2019, PostgreSQL Global Development Group # # src/tools/copyright.pl # @@ -62,6 +62,7 @@ sub wanted $line =~ s/$cc (\d{4}), $pgdg/$ccliteral $1-$year, $pgdg/i; } untie @lines; + return; } print "Manually update:\n"; diff --git a/src/tools/editors/emacs.samples b/src/tools/editors/emacs.samples index d9cd47cef27..529c98a9eba 100644 --- a/src/tools/editors/emacs.samples +++ b/src/tools/editors/emacs.samples @@ -47,10 +47,13 @@ (interactive) (setq perl-brace-imaginary-offset 0) (setq perl-brace-offset 0) - (setq perl-continued-brace-offset 4) - (setq perl-continued-statement-offset 4) + (setq perl-continued-statement-offset 2) + (setq perl-continued-brace-offset (- perl-continued-statement-offset)) (setq perl-indent-level 4) (setq perl-label-offset -2) + ;; Next two aren't marked safe-local-variable, so .dir-locals.el omits them. + (setq perl-indent-continued-arguments 4) + (setq perl-indent-parens-as-block t) (setq indent-tabs-mode t) (setq tab-width 4)) @@ -62,12 +65,23 @@ ;;; documentation files -(add-hook 'sgml-mode-hook - (defun postgresql-sgml-mode-hook () +;; *.sgml files are actually XML +(add-to-list 'auto-mode-alist '("/postgres\\(ql\\)?/.*\\.sgml\\'" . nxml-mode)) + +(add-hook 'nxml-mode-hook + (defun postgresql-xml-mode-hook () (when (string-match "/postgres\\(ql\\)?/" buffer-file-name) (setq fill-column 78) - (setq indent-tabs-mode nil) - (setq sgml-basic-offset 1)))) + (setq indent-tabs-mode nil)))) + +;; The *.xsl files use 2-space indent, which is consistent with +;; docbook-xsl sources and also the nxml-mode default. But the *.sgml +;; files use 1-space indent, mostly for historical reasons at this +;; point. +(add-hook 'nxml-mode-hook + (defun postgresql-xml-src-mode-hook () + (when (string-match "/postgres\\(ql\\)?/.*\\.sgml\\'" buffer-file-name) + (setq nxml-child-indent 1)))) ;;; Makefiles diff --git a/src/tools/findoidjoins/Makefile b/src/tools/findoidjoins/Makefile index 1af0a93a89e..b4238e49726 100644 --- a/src/tools/findoidjoins/Makefile +++ b/src/tools/findoidjoins/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/tools/findoidjoins # -# Copyright (c) 2003-2018, PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # # src/tools/findoidjoins/Makefile # diff --git a/src/tools/findoidjoins/README b/src/tools/findoidjoins/README index 7c5a5cf4b98..e5fc3104d3b 100644 --- a/src/tools/findoidjoins/README +++ b/src/tools/findoidjoins/README @@ -5,7 +5,7 @@ findoidjoins This program scans a database and prints oid fields (also reg* fields) and the tables they join to. It is normally used to check the system -catalog join relationships (shown below for 10devel as of 2017-05-15). +catalog join relationships (shown below for 11devel as of 2018-05-07). Historically this has been run against an empty database such as template1, but there's a problem with that approach: some of the catalogs are empty @@ -16,7 +16,7 @@ catalogs in interesting ways. Note that unexpected matches may indicate bogus entries in system tables; don't accept a peculiar match without question. In particular, a field shown as joining to more than one target table is probably messed up. -In v10, the *only* fields that should join to more than one target +Currently, the *only* fields that should join to more than one target table are: pg_description.objoid, pg_depend.objid, pg_depend.refobjid, pg_shdescription.objoid, pg_shdepend.objid, pg_shdepend.refobjid, @@ -35,7 +35,7 @@ regression test. The oidjoins test should be updated after any revision in the patterns of cross-links between system tables. (Typically we update it at the end of each development cycle.) -NOTE: as of v10, make_oidjoins_check produces two bogus join checks: +NOTE: currently, make_oidjoins_check produces two bogus join checks: Join pg_catalog.pg_class.relfilenode => pg_catalog.pg_class.oid Join pg_catalog.pg_database.datlastsysoid => pg_catalog.pg_database.oid These are artifacts and should not be added to the oidjoins regression test. @@ -106,6 +106,7 @@ Join pg_catalog.pg_constraint.connamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_constraint.conrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_constraint.contypid => pg_catalog.pg_type.oid Join pg_catalog.pg_constraint.conindid => pg_catalog.pg_class.oid +Join pg_catalog.pg_constraint.conparentid => pg_catalog.pg_constraint.oid Join pg_catalog.pg_constraint.confrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_conversion.connamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_conversion.conowner => pg_catalog.pg_authid.oid @@ -154,12 +155,13 @@ Join pg_catalog.pg_opfamily.opfmethod => pg_catalog.pg_am.oid Join pg_catalog.pg_opfamily.opfnamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_opfamily.opfowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_partitioned_table.partrelid => pg_catalog.pg_class.oid +Join pg_catalog.pg_partitioned_table.partdefid => pg_catalog.pg_class.oid Join pg_catalog.pg_policy.polrelid => pg_catalog.pg_class.oid Join pg_catalog.pg_proc.pronamespace => pg_catalog.pg_namespace.oid Join pg_catalog.pg_proc.proowner => pg_catalog.pg_authid.oid Join pg_catalog.pg_proc.prolang => pg_catalog.pg_language.oid Join pg_catalog.pg_proc.provariadic => pg_catalog.pg_type.oid -Join pg_catalog.pg_proc.protransform => pg_catalog.pg_proc.oid +Join pg_catalog.pg_proc.prosupport => pg_catalog.pg_proc.oid Join pg_catalog.pg_proc.prorettype => pg_catalog.pg_type.oid Join pg_catalog.pg_range.rngtypid => pg_catalog.pg_type.oid Join pg_catalog.pg_range.rngsubtype => pg_catalog.pg_type.oid diff --git a/src/tools/findoidjoins/findoidjoins.c b/src/tools/findoidjoins/findoidjoins.c index cbb7b59adc8..50e26f1268c 100644 --- a/src/tools/findoidjoins/findoidjoins.c +++ b/src/tools/findoidjoins/findoidjoins.c @@ -1,7 +1,7 @@ /* * findoidjoins.c * - * Copyright (c) 2002-2018, PostgreSQL Global Development Group + * Copyright (c) 2002-2019, PostgreSQL Global Development Group * * src/tools/findoidjoins/findoidjoins.c */ @@ -63,7 +63,9 @@ main(int argc, char **argv) "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname " "FROM pg_catalog.pg_class c " "WHERE c.relkind = " CppAsString2(RELKIND_RELATION) - " AND c.relhasoids " + " AND EXISTS(SELECT * FROM pg_attribute a" + " WHERE a.attrelid = c.oid AND a.attname = 'oid' " + " AND a.atttypid = 'oid'::regtype)" "ORDER BY nspname, c.relname" ); diff --git a/src/tools/fix-old-flex-code.pl b/src/tools/fix-old-flex-code.pl index baa1feecb9c..45e9433e10a 100644 --- a/src/tools/fix-old-flex-code.pl +++ b/src/tools/fix-old-flex-code.pl @@ -8,7 +8,7 @@ # let's suppress it by inserting a dummy reference to the variable. # (That's exactly what 2.5.36 and later do ...) # -# Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group # Portions Copyright (c) 1994, Regents of the University of California # # src/tools/fix-old-flex-code.pl @@ -37,7 +37,7 @@ # Apply the desired patch. $ccode =~ -s|(struct yyguts_t \* yyg = \(struct yyguts_t\*\)yyscanner; /\* This var may be unused depending upon options. \*/ + s|(struct yyguts_t \* yyg = \(struct yyguts_t\*\)yyscanner; /\* This var may be unused depending upon options. \*/ .*?) return yy_is_jam \? 0 : yy_current_state; |$1 @@ -61,6 +61,6 @@ sub usage fix-old-flex-code.pl modifies a flex output file to suppress an unused-variable warning that occurs with older flex versions. -Report bugs to . +Report bugs to . EOM } diff --git a/src/tools/gen_keywordlist.pl b/src/tools/gen_keywordlist.pl new file mode 100644 index 00000000000..1623c867879 --- /dev/null +++ b/src/tools/gen_keywordlist.pl @@ -0,0 +1,197 @@ +#---------------------------------------------------------------------- +# +# gen_keywordlist.pl +# Perl script that transforms a list of keywords into a ScanKeywordList +# data structure that can be passed to ScanKeywordLookup(). +# +# The input is a C header file containing a series of macro calls +# PG_KEYWORD("keyword", ...) +# Lines not starting with PG_KEYWORD are ignored. The keywords are +# implicitly numbered 0..N-1 in order of appearance in the header file. +# Currently, the keywords are required to appear in ASCII order. +# +# The output is a C header file that defines a "const ScanKeywordList" +# variable named according to the -v switch ("ScanKeywords" by default). +# The variable is marked "static" unless the -e switch is given. +# +# ScanKeywordList uses hash-based lookup, so this script also selects +# a minimal perfect hash function for the keyword set, and emits a +# static hash function that is referenced in the ScanKeywordList struct. +# The hash function is case-insensitive unless --no-case-fold is specified. +# Note that case folding works correctly only for all-ASCII keywords! +# +# +# Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group +# Portions Copyright (c) 1994, Regents of the University of California +# +# src/tools/gen_keywordlist.pl +# +#---------------------------------------------------------------------- + +use strict; +use warnings; +use Getopt::Long; + +use FindBin; +use lib $FindBin::RealBin; + +use PerfectHash; + +my $output_path = ''; +my $extern = 0; +my $case_fold = 1; +my $varname = 'ScanKeywords'; + +GetOptions( + 'output:s' => \$output_path, + 'extern' => \$extern, + 'case-fold!' => \$case_fold, + 'varname:s' => \$varname) || usage(); + +my $kw_input_file = shift @ARGV || die "No input file.\n"; + +# Make sure output_path ends in a slash if needed. +if ($output_path ne '' && substr($output_path, -1) ne '/') +{ + $output_path .= '/'; +} + +$kw_input_file =~ /(\w+)\.h$/ + || die "Input file must be named something.h.\n"; +my $base_filename = $1 . '_d'; +my $kw_def_file = $output_path . $base_filename . '.h'; + +open(my $kif, '<', $kw_input_file) || die "$kw_input_file: $!\n"; +open(my $kwdef, '>', $kw_def_file) || die "$kw_def_file: $!\n"; + +# Opening boilerplate for keyword definition header. +printf $kwdef <) +{ + if (/^PG_KEYWORD\("(\w+)"/) + { + push @keywords, $1; + } +} + +# When being case-insensitive, insist that the input be all-lower-case. +if ($case_fold) +{ + foreach my $kw (@keywords) + { + die qq|The keyword "$kw" is not lower-case in $kw_input_file\n| + if ($kw ne lc $kw); + } +} + +# Error out if the keyword names are not in ASCII order. +# +# While this isn't really necessary with hash-based lookup, it's still +# helpful because it provides a cheap way to reject duplicate keywords. +# Also, insisting on sorted order ensures that code that scans the keyword +# table linearly will see the keywords in a canonical order. +for my $i (0 .. $#keywords - 1) +{ + die + qq|The keyword "$keywords[$i + 1]" is out of order in $kw_input_file\n| + if ($keywords[$i] cmp $keywords[ $i + 1 ]) >= 0; +} + +# Emit the string containing all the keywords. + +printf $kwdef qq|static const char %s_kw_string[] =\n\t"|, $varname; +print $kwdef join qq|\\0"\n\t"|, @keywords; +print $kwdef qq|";\n\n|; + +# Emit an array of numerical offsets which will be used to index into the +# keyword string. Also determine max keyword length. + +printf $kwdef "static const uint16 %s_kw_offsets[] = {\n", $varname; + +my $offset = 0; +my $max_len = 0; +foreach my $name (@keywords) +{ + my $this_length = length($name); + + print $kwdef "\t$offset,\n"; + + # Calculate the cumulative offset of the next keyword, + # taking into account the null terminator. + $offset += $this_length + 1; + + # Update max keyword length. + $max_len = $this_length if $max_len < $this_length; +} + +print $kwdef "};\n\n"; + +# Emit a macro defining the number of keywords. +# (In some places it's useful to have access to that as a constant.) + +printf $kwdef "#define %s_NUM_KEYWORDS %d\n\n", uc $varname, scalar @keywords; + +# Emit the definition of the hash function. + +my $funcname = $varname . "_hash_func"; + +my $f = PerfectHash::generate_hash_function(\@keywords, $funcname, + case_fold => $case_fold); + +printf $kwdef qq|static %s\n|, $f; + +# Emit the struct that wraps all this lookup info into one variable. + +printf $kwdef "static " if !$extern; +printf $kwdef "const ScanKeywordList %s = {\n", $varname; +printf $kwdef qq|\t%s_kw_string,\n|, $varname; +printf $kwdef qq|\t%s_kw_offsets,\n|, $varname; +printf $kwdef qq|\t%s,\n|, $funcname; +printf $kwdef qq|\t%s_NUM_KEYWORDS,\n|, uc $varname; +printf $kwdef qq|\t%d\n|, $max_len; +printf $kwdef "};\n\n"; + +printf $kwdef "#endif\t\t\t\t\t\t\t/* %s_H */\n", uc $base_filename; + + +sub usage +{ + die <] [--varname/-v ] [--extern/-e] [--[no-]case-fold] input_file + --output Output directory (default '.') + --varname Name for ScanKeywordList variable (default 'ScanKeywords') + --extern Allow the ScanKeywordList variable to be globally visible + --no-case-fold Keyword matching is to be case-sensitive + +gen_keywordlist.pl transforms a list of keywords into a ScanKeywordList. +The output filename is derived from the input file by inserting _d, +for example kwlist_d.h is produced from kwlist.h. +EOM +} diff --git a/src/tools/git-external-diff b/src/tools/git-external-diff index 59fa36624c7..39ddd01b3d3 100644 --- a/src/tools/git-external-diff +++ b/src/tools/git-external-diff @@ -7,6 +7,41 @@ # path old-file old-hash old-mode new-file new-hash new-mode # 'path' is the git-tree-relative path of the file being diff'ed +=comment + +This info is copied from the old wiki page on Working with git: + +Context diffs with Git + +Copy git-external-diff into libexec/git-core/ of your git installation +and configure git to use that wrapper with: + + git config [--global] diff.external git-external-diff + +--global makes the configuration global for your user - otherwise it is +just configured for the current repository. + +For every command which displays diffs in some way you can use the +parameter "--[no-]-ext-diff" to enable respectively disable using the +external diff command. + +For the git diff command --ext-diff is enabled by default - for any +other command like git log -p or git format-patch it is not! + +This method should work on all platforms supported by git. + +If you do not want to configure the external wrapper permanently or you +want to overwrite it you can also invoke git like: + + export GIT_EXTERNAL_DIFF=git-external-diff + git diff --[no-]ext-diff + +Alternatively, configure a git alias in ~/.gitconfig or .git/config: + + [alias] + cdiff = !GIT_EXTERNAL_DIFF=git-context-diff git diff +=cut + old_hash="$3" new_hash=$(git hash-object "$5") diff --git a/src/tools/git_changelog b/src/tools/git_changelog index 2fc1565a6c3..aaf9b7c1954 100755 --- a/src/tools/git_changelog +++ b/src/tools/git_changelog @@ -57,7 +57,7 @@ require IPC::Open2; # (We could get this from "git branches", but not worth the trouble.) # NB: master must be first! my @BRANCHES = qw(master - REL_10_STABLE REL9_6_STABLE REL9_5_STABLE + REL_12_STABLE REL_11_STABLE REL_10_STABLE REL9_6_STABLE REL9_5_STABLE REL9_4_STABLE REL9_3_STABLE REL9_2_STABLE REL9_1_STABLE REL9_0_STABLE REL8_4_STABLE REL8_3_STABLE REL8_2_STABLE REL8_1_STABLE REL8_0_STABLE REL7_4_STABLE REL7_3_STABLE REL7_2_STABLE REL7_1_STABLE REL7_0_PATCHES @@ -102,9 +102,9 @@ my %rel_tags; { my $commit = $1; my $tag = $2; - if ($tag =~ /^REL_\d+_\d+$/ - || $tag =~ /^REL\d+_\d+$/ - || $tag =~ /^REL\d+_\d+_\d+$/) + if ( $tag =~ /^REL_\d+_\d+$/ + || $tag =~ /^REL\d+_\d+$/ + || $tag =~ /^REL\d+_\d+_\d+$/) { $rel_tags{$commit} = $tag; } @@ -317,7 +317,8 @@ sub push_commit 'message' => $c->{'message'}, 'commit' => $c->{'commit'}, 'commits' => [], - 'timestamp' => $ts }; + 'timestamp' => $ts + }; push @{ $all_commits{$ht} }, $cc; } @@ -326,11 +327,13 @@ sub push_commit 'branch' => $c->{'branch'}, 'commit' => $c->{'commit'}, 'date' => $c->{'date'}, - 'last_tag' => $c->{'last_tag'} }; + 'last_tag' => $c->{'last_tag'} + }; push @{ $cc->{'commits'} }, $smallc; push @{ $all_commits_by_branch{ $c->{'branch'} } }, $cc; $cc->{'branch_position'}{ $c->{'branch'} } = -1 + @{ $all_commits_by_branch{ $c->{'branch'} } }; + return; } sub hash_commit @@ -343,7 +346,7 @@ sub parse_datetime { my ($dt) = @_; $dt =~ -/^(\d\d\d\d)-(\d\d)-(\d\d)\s+(\d\d):(\d\d):(\d\d)\s+([-+])(\d\d)(\d\d)$/; + /^(\d\d\d\d)-(\d\d)-(\d\d)\s+(\d\d):(\d\d):(\d\d)\s+([-+])(\d\d)(\d\d)$/; my $gm = Time::Local::timegm($6, $5, $4, $3, $2 - 1, $1); my $tzoffset = ($8 * 60 + $9) * 60; $tzoffset = -$tzoffset if $7 eq '-'; @@ -353,6 +356,7 @@ sub parse_datetime sub output_str { ($oldest_first) ? ($output_line .= sprintf(shift, @_)) : printf(@_); + return; } sub output_details @@ -393,6 +397,7 @@ sub output_details } } output_str("\n"); + return; } sub usage diff --git a/src/tools/ifaddrs/Makefile b/src/tools/ifaddrs/Makefile index 9e0e8945f8f..763f913f2fe 100644 --- a/src/tools/ifaddrs/Makefile +++ b/src/tools/ifaddrs/Makefile @@ -2,7 +2,7 @@ # # Makefile for src/tools/ifaddrs # -# Copyright (c) 2003-2018, PostgreSQL Global Development Group +# Copyright (c) 2003-2019, PostgreSQL Global Development Group # # src/tools/ifaddrs/Makefile # diff --git a/src/tools/make_ctags b/src/tools/make_ctags index 1609c076754..d8d18d1569f 100755 --- a/src/tools/make_ctags +++ b/src/tools/make_ctags @@ -2,6 +2,9 @@ # src/tools/make_ctags +command -v ctags >/dev/null || \ + { echo "'ctags' program not found" 1>&2; exit 1; } + trap "rm -f /tmp/$$" 0 1 2 3 15 rm -f ./tags diff --git a/src/tools/make_etags b/src/tools/make_etags index 3ce96bc3cab..9288ef7b14b 100755 --- a/src/tools/make_etags +++ b/src/tools/make_etags @@ -2,6 +2,9 @@ # src/tools/make_etags +command -v etags >/dev/null || \ + { echo "'etags' program not found" 1>&2; exit 1; } + rm -f ./TAGS find `pwd`/ -type f -name '*.[chyl]' -print | diff --git a/src/tools/msvc/Install.pm b/src/tools/msvc/Install.pm index 82528eaa283..1a92ed233ab 100644 --- a/src/tools/msvc/Install.pm +++ b/src/tools/msvc/Install.pm @@ -37,9 +37,10 @@ sub lcopy unlink $target || confess "Could not delete $target\n"; } - copy($src, $target) + (my $retval = copy($src, $target)) || confess "Could not copy $src to $target\n"; + return $retval; } sub Install @@ -58,8 +59,8 @@ sub Install # suppress warning about harmless redeclaration of $config no warnings 'misc'; - do "config_default.pl"; - do "config.pl" if (-f "config.pl"); + do "./config_default.pl"; + do "./config.pl" if (-f "config.pl"); } chdir("../../..") if (-f "../../../configure"); @@ -95,13 +96,14 @@ sub Install my @top_dir = ("src"); @top_dir = ("src\\bin", "src\\interfaces") if ($insttype eq "client"); File::Find::find( - { wanted => sub { + { + wanted => sub { /^.*\.sample\z/s && push(@$sample_files, $File::Find::name); # Don't find files of in-tree temporary installations. $_ eq 'share' and $File::Find::prune = 1; - } + } }, @top_dir); CopySetOfFiles('config files', $sample_files, $target . '/share/'); @@ -135,9 +137,8 @@ sub Install 'Information schema data', $target . '/share/', 'src/backend/catalog/', 'sql_features.txt'); CopyFiles( - 'Error code data', $target . '/share/', - 'src/backend/utils/', 'errcodes.txt'); - GenerateConversionScript($target); + 'Error code data', $target . '/share/', + 'src/backend/utils/', 'errcodes.txt'); GenerateTimezoneFiles($target, $conf); GenerateTsearchFiles($target); CopySetOfFiles( @@ -155,13 +156,14 @@ sub Install push @pldirs, "src/pl/plpython" if $config->{python}; push @pldirs, "src/pl/tcl" if $config->{tcl}; File::Find::find( - { wanted => sub { + { + wanted => sub { /^(.*--.*\.sql|.*\.control)\z/s && push(@$pl_extension_files, $File::Find::name); # Don't find files of in-tree temporary installations. $_ eq 'share' and $File::Find::prune = 1; - } + } }, @pldirs); CopySetOfFiles('PL Extension files', @@ -171,6 +173,7 @@ sub Install GenerateNLSFiles($target, $config->{nls}, $majorver) if ($config->{nls}); print "Installation complete.\n"; + return; } sub EnsureDirectories @@ -181,6 +184,7 @@ sub EnsureDirectories { mkdir $target . '/' . $d unless -d ($target . '/' . $d); } + return; } sub CopyFiles @@ -195,9 +199,10 @@ sub CopyFiles print "."; $f = $basedir . $f; die "No file $f\n" if (!-f $f); - lcopy($f, $target . basename($f)); + lcopy($f, $target . basename($f)) || croak "Could not copy $f: $!\n"; } print "\n"; + return; } sub CopySetOfFiles @@ -213,6 +218,7 @@ sub CopySetOfFiles lcopy($_, $tgt) || croak "Could not copy $_: $!\n"; } print "\n"; + return; } sub CopySolutionOutput @@ -338,43 +344,7 @@ sub CopySolutionOutput print "."; } print "\n"; -} - -sub GenerateConversionScript -{ - my $target = shift; - my $sql = ""; - my $F; - - print "Generating conversion proc script..."; - my $mf = read_file('src/backend/utils/mb/conversion_procs/Makefile'); - $mf =~ s{\\\r?\n}{}g; - $mf =~ /^CONVERSIONS\s*=\s*(.*)$/m - || die "Could not find CONVERSIONS line in conversions Makefile\n"; - my @pieces = split /\s+/, $1; - while ($#pieces > 0) - { - my $name = shift @pieces; - my $se = shift @pieces; - my $de = shift @pieces; - my $func = shift @pieces; - my $obj = shift @pieces; - $sql .= "-- $se --> $de\n"; - $sql .= -"CREATE OR REPLACE FUNCTION $func (INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) RETURNS VOID AS '\$libdir/$obj', '$func' LANGUAGE C STRICT;\n"; - $sql .= -"COMMENT ON FUNCTION $func(INTEGER, INTEGER, CSTRING, INTERNAL, INTEGER) IS 'internal conversion function for $se to $de';\n"; - $sql .= "DROP CONVERSION pg_catalog.$name;\n"; - $sql .= -"CREATE DEFAULT CONVERSION pg_catalog.$name FOR '$se' TO '$de' FROM $func;\n"; - $sql .= -"COMMENT ON CONVERSION pg_catalog.$name IS 'conversion for $se to $de';\n\n"; - } - open($F, '>', "$target/share/conversion_create.sql") - || die "Could not write to conversion_create.sql\n"; - print $F $sql; - close($F); - print "\n"; + return; } sub GenerateTimezoneFiles @@ -395,8 +365,9 @@ sub GenerateTimezoneFiles print "Generating timezone files..."; - my @args = - ("$conf/zic/zic", '-d', "$target/share/timezone", '-p', "$posixrules"); + my @args = ( + "$conf/zic/zic", '-d', "$target/share/timezone", '-p', + "$posixrules", '-b', 'slim'); foreach (@tzfiles) { my $tzfile = $_; @@ -406,6 +377,7 @@ sub GenerateTimezoneFiles system(@args); print "\n"; + return; } sub GenerateTsearchFiles @@ -447,6 +419,7 @@ sub GenerateTsearchFiles } close($F); print "\n"; + return; } sub CopyContribFiles @@ -461,22 +434,19 @@ sub CopyContribFiles opendir($D, $subdir) || croak "Could not opendir on $subdir!\n"; while (my $d = readdir($D)) { - # These configuration-based exclusions must match vcregress.pl - next if ($d eq "uuid-ossp" && !defined($config->{uuid})); - next if ($d eq "sslinfo" && !defined($config->{openssl})); - next if ($d eq "xml2" && !defined($config->{xml})); - next if ($d eq "hstore_plperl" && !defined($config->{perl})); - next if ($d eq "jsonb_plperl" && !defined($config->{perl})); - next if ($d eq "hstore_plpython" && !defined($config->{python})); - next if ($d eq "jsonb_plpython" && !defined($config->{python})); - next if ($d eq "ltree_plpython" && !defined($config->{python})); + next if ($d eq "uuid-ossp" && !defined($config->{uuid})); + next if ($d eq "sslinfo" && !defined($config->{openssl})); + next if ($d eq "xml2" && !defined($config->{xml})); + next if ($d =~ /_plperl$/ && !defined($config->{perl})); + next if ($d =~ /_plpython$/ && !defined($config->{python})); next if ($d eq "sepgsql"); CopySubdirFiles($subdir, $d, $config, $target); } } print "\n"; + return; } sub CopySubdirFiles @@ -546,6 +516,51 @@ sub CopySubdirFiles } } + { + $flist = ''; + if ($mf =~ /^HEADERS\s*=\s*(.*)$/m) { $flist .= $1 } + my @modlist = (); + my %fmodlist = (); + while ($mf =~ /^HEADERS_([^\s=]+)\s*=\s*(.*)$/mg) + { + $fmodlist{$1} .= $2; + } + + if ($mf =~ /^MODULE_big\s*=\s*(.*)$/m) + { + push @modlist, $1; + if ($flist ne '') + { + $fmodlist{$1} = $flist; + $flist = ''; + } + } + elsif ($mf =~ /^MODULES\s*=\s*(.*)$/m) + { + push @modlist, split /\s+/, $1; + } + + croak "HEADERS requires MODULE_big in $subdir $module" + if $flist ne ''; + + foreach my $mod (keys %fmodlist) + { + croak "HEADERS_$mod for unknown module in $subdir $module" + unless grep { $_ eq $mod } @modlist; + $flist = ParseAndCleanRule($fmodlist{$mod}, $mf); + EnsureDirectories($target, "include", "include/server", + "include/server/$moduledir", + "include/server/$moduledir/$mod"); + foreach my $f (split /\s+/, $flist) + { + lcopy("$subdir/$module/$f", + "$target/include/server/$moduledir/$mod/" . basename($f)) + || croak("Could not copy file $f in $subdir $module"); + print '.'; + } + } + } + $flist = ''; if ($mf =~ /^DOCS\s*=\s*(.*)$/mg) { $flist .= $1 } if ($flist ne '') @@ -554,7 +569,7 @@ sub CopySubdirFiles # Special case for contrib/spi $flist = -"autoinc.example insert_username.example moddatetime.example refint.example timetravel.example" + "autoinc.example insert_username.example moddatetime.example refint.example" if ($module eq 'spi'); foreach my $f (split /\s+/, $flist) { @@ -563,6 +578,7 @@ sub CopySubdirFiles print '.'; } } + return; } sub ParseAndCleanRule @@ -602,8 +618,7 @@ sub CopyIncludeFiles 'Public headers', $target . '/include/', 'src/include/', 'postgres_ext.h', 'pg_config.h', 'pg_config_ext.h', - 'pg_config_os.h', 'dynloader.h', - 'pg_config_manual.h'); + 'pg_config_os.h', 'pg_config_manual.h'); lcopy('src/include/libpq/libpq-fs.h', $target . '/include/libpq/') || croak 'Could not copy libpq-fs.h'; @@ -626,8 +641,7 @@ sub CopyIncludeFiles CopyFiles( 'Server headers', $target . '/include/server/', - 'src/include/', 'pg_config.h', 'pg_config_ext.h', 'pg_config_os.h', - 'dynloader.h'); + 'src/include/', 'pg_config.h', 'pg_config_ext.h', 'pg_config_os.h'); CopyFiles( 'Grammar header', $target . '/include/server/parser/', @@ -678,6 +692,7 @@ sub CopyIncludeFiles $target . '/include/informix/esql/', 'src/interfaces/ecpg/include/', split /\s+/, $1); + return; } sub GenerateNLSFiles @@ -690,10 +705,11 @@ sub GenerateNLSFiles EnsureDirectories($target, "share/locale"); my @flist; File::Find::find( - { wanted => sub { + { + wanted => sub { /^nls\.mk\z/s && !push(@flist, $File::Find::name); - } + } }, "src"); foreach (@flist) @@ -713,13 +729,14 @@ sub GenerateNLSFiles my @args = ( "$nlspath\\bin\\msgfmt", '-o', -"$target\\share\\locale\\$lang\\LC_MESSAGES\\$prgm-$majorver.mo", + "$target\\share\\locale\\$lang\\LC_MESSAGES\\$prgm-$majorver.mo", $_); system(@args) && croak("Could not run msgfmt on $dir\\$_"); print "."; } } print "\n"; + return; } sub DetermineMajorVersion diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm index 9ddccc7c554..823357c023f 100644 --- a/src/tools/msvc/MSBuildProject.pm +++ b/src/tools/msvc/MSBuildProject.pm @@ -1,7 +1,7 @@ package MSBuildProject; # -# Package that encapsulates a MSBuild project file (Visual C++ 2010 or greater) +# Package that encapsulates a MSBuild project file (Visual C++ 2013 or greater) # # src/tools/msvc/MSBuildProject.pm # @@ -11,6 +11,8 @@ use strict; use warnings; use base qw(Project); +no warnings qw(redefine); ## no critic + sub _new { my $classname = shift; @@ -38,6 +40,19 @@ EOF $self->{guid} +EOF + # Check whether WindowsSDKVersion env variable is present. + # Add WindowsTargetPlatformVersion node if so. + my $sdkVersion = $ENV{'WindowsSDKVersion'}; + if (defined($sdkVersion)) + { + # remove trailing backslash if necessary. + $sdkVersion =~ s/\\$//; + print $f <$sdkVersion +EOF + } + print $f < EOF @@ -65,17 +80,22 @@ EOF $self->WriteItemDefinitionGroup( $f, 'Debug', - { defs => "_DEBUG;DEBUG=1", + { + defs => "_DEBUG;DEBUG=1", opt => 'Disabled', strpool => 'false', - runtime => 'MultiThreadedDebugDLL' }); + runtime => 'MultiThreadedDebugDLL' + }); $self->WriteItemDefinitionGroup( $f, 'Release', - { defs => "", + { + defs => "", opt => 'Full', strpool => 'true', - runtime => 'MultiThreadedDLL' }); + runtime => 'MultiThreadedDLL' + }); + return; } sub AddDefine @@ -83,6 +103,7 @@ sub AddDefine my ($self, $def) = @_; $self->{defines} .= $def . ';'; + return; } sub WriteReferences @@ -108,6 +129,7 @@ EOF EOF } + return; } sub WriteFiles @@ -170,7 +192,7 @@ EOF if ($grammarFile =~ /\.y$/) { $outputFile =~ -s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c}; + s{^src\\pl\\plpgsql\\src\\gram.c$}{src\\pl\\plpgsql\\src\\pl_gram.c}; print $f < Running bison on $grammarFile @@ -219,6 +241,7 @@ EOF EOF } + return; } sub WriteConfigurationHeader @@ -230,6 +253,7 @@ sub WriteConfigurationHeader $self->{platform} EOF + return; } sub WriteConfigurationPropertyGroup @@ -246,8 +270,10 @@ sub WriteConfigurationPropertyGroup false MultiByte $p->{wholeopt} + $self->{PlatformToolset} EOF + return; } sub WritePropertySheetsPropertyGroup @@ -258,6 +284,7 @@ sub WritePropertySheetsPropertyGroup EOF + return; } sub WriteAdditionalProperties @@ -268,6 +295,7 @@ sub WriteAdditionalProperties .\\$cfgname\\$self->{name}\\ false EOF + return; } sub WriteItemDefinitionGroup @@ -328,7 +356,7 @@ EOF if ($self->{disablelinkerwarnings}) { print $f -" /ignore:$self->{disablelinkerwarnings} \%(AdditionalOptions)\n"; + " /ignore:$self->{disablelinkerwarnings} \%(AdditionalOptions)\n"; } if ($self->{implib}) { @@ -360,6 +388,7 @@ EOF print $f < EOF + return; } sub Footer @@ -373,81 +402,45 @@ sub Footer EOF + return; } -package VC2010Project; +package VC2013Project; # -# Package that encapsulates a Visual C++ 2010 project file +# Package that encapsulates a Visual C++ 2013 project file # use strict; use warnings; use base qw(MSBuildProject); +no warnings qw(redefine); ## no critic + sub new { my $classname = shift; my $self = $classname->SUPER::_new(@_); bless($self, $classname); - $self->{vcver} = '10.00'; + $self->{vcver} = '12.00'; + $self->{PlatformToolset} = 'v120'; + $self->{ToolsVersion} = '12.0'; return $self; } -package VC2012Project; +package VC2015Project; # -# Package that encapsulates a Visual C++ 2012 project file +# Package that encapsulates a Visual C++ 2015 project file # use strict; use warnings; use base qw(MSBuildProject); -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{vcver} = '11.00'; - $self->{PlatformToolset} = 'v110'; - - return $self; -} - -# This override adds the element -# to the PropertyGroup labeled "Configuration" -sub WriteConfigurationPropertyGroup -{ - my ($self, $f, $cfgname, $p) = @_; - my $cfgtype = - ($self->{type} eq "exe") - ? 'Application' - : ($self->{type} eq "dll" ? 'DynamicLibrary' : 'StaticLibrary'); - - print $f < - $cfgtype - false - MultiByte - $p->{wholeopt} - $self->{PlatformToolset} - -EOF -} - -package VC2013Project; - -# -# Package that encapsulates a Visual C++ 2013 project file -# - -use strict; -use warnings; -use base qw(VC2012Project); +no warnings qw(redefine); ## no critic sub new { @@ -455,22 +448,24 @@ sub new my $self = $classname->SUPER::_new(@_); bless($self, $classname); - $self->{vcver} = '12.00'; - $self->{PlatformToolset} = 'v120'; - $self->{ToolsVersion} = '12.0'; + $self->{vcver} = '14.00'; + $self->{PlatformToolset} = 'v140'; + $self->{ToolsVersion} = '14.0'; return $self; } -package VC2015Project; +package VC2017Project; # -# Package that encapsulates a Visual C++ 2015 project file +# Package that encapsulates a Visual C++ 2017 project file # use strict; use warnings; -use base qw(VC2012Project); +use base qw(MSBuildProject); + +no warnings qw(redefine); ## no critic sub new { @@ -478,22 +473,24 @@ sub new my $self = $classname->SUPER::_new(@_); bless($self, $classname); - $self->{vcver} = '14.00'; - $self->{PlatformToolset} = 'v140'; - $self->{ToolsVersion} = '14.0'; + $self->{vcver} = '15.00'; + $self->{PlatformToolset} = 'v141'; + $self->{ToolsVersion} = '15.0'; return $self; } -package VC2017Project; +package VC2019Project; # -# Package that encapsulates a Visual C++ 2017 project file +# Package that encapsulates a Visual C++ 2019 project file # use strict; use warnings; -use base qw(VC2012Project); +use base qw(MSBuildProject); + +no warnings qw(redefine); ## no critic sub new { @@ -501,9 +498,9 @@ sub new my $self = $classname->SUPER::_new(@_); bless($self, $classname); - $self->{vcver} = '15.00'; - $self->{PlatformToolset} = 'v141'; - $self->{ToolsVersion} = '15.0'; + $self->{vcver} = '16.00'; + $self->{PlatformToolset} = 'v142'; + $self->{ToolsVersion} = '16.0'; return $self; } diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index 1d3ed6b0b10..7a103e61406 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -39,15 +39,17 @@ my $contrib_extralibs = undef; my $contrib_extraincludes = { 'dblink' => ['src/backend'] }; my $contrib_extrasource = { 'cube' => [ 'contrib/cube/cubescan.l', 'contrib/cube/cubeparse.y' ], - 'seg' => [ 'contrib/seg/segscan.l', 'contrib/seg/segparse.y' ], }; + 'seg' => [ 'contrib/seg/segscan.l', 'contrib/seg/segparse.y' ], +}; my @contrib_excludes = ( - 'commit_ts', 'hstore_plperl', - 'hstore_plpython', 'intagg', - 'jsonb_plperl', 'jsonb_plpython', - 'ltree_plpython', 'pgcrypto', - 'sepgsql', 'brin', - 'test_extensions', 'test_pg_dump', - 'snapshot_too_old'); + 'commit_ts', 'hstore_plperl', + 'hstore_plpython', 'intagg', + 'jsonb_plperl', 'jsonb_plpython', + 'ltree_plpython', 'pgcrypto', + 'sepgsql', 'brin', + 'test_extensions', 'test_misc', + 'test_pg_dump', 'snapshot_too_old', + 'unsafe_tests'); # Set of variables for frontend modules my $frontend_defines = { 'initdb' => 'FRONTEND' }; @@ -64,14 +66,17 @@ my $frontend_extralibs = { 'initdb' => ['ws2_32.lib'], 'pg_restore' => ['ws2_32.lib'], 'pgbench' => ['ws2_32.lib'], - 'psql' => ['ws2_32.lib'] }; + 'psql' => ['ws2_32.lib'] +}; my $frontend_extraincludes = { 'initdb' => ['src/timezone'], - 'psql' => ['src/backend'] }; + 'psql' => ['src/backend'] +}; my $frontend_extrasource = { 'psql' => ['src/bin/psql/psqlscanslash.l'], 'pgbench' => - [ 'src/bin/pgbench/exprscan.l', 'src/bin/pgbench/exprparse.y' ] }; + [ 'src/bin/pgbench/exprscan.l', 'src/bin/pgbench/exprparse.y' ] +}; my @frontend_excludes = ( 'pgevent', 'pg_basebackup', 'pg_rewind', 'pg_dump', 'pg_waldump', 'scripts'); @@ -89,16 +94,20 @@ sub mkvcbuild $solution = CreateSolution($vsVersion, $config); our @pgportfiles = qw( - chklocale.c crypt.c fls.c fseeko.c getrusage.c inet_aton.c random.c + chklocale.c explicit_bzero.c fls.c fseeko.c getrusage.c inet_aton.c random.c srandom.c getaddrinfo.c gettimeofday.c inet_net_ntop.c kill.c open.c erand48.c snprintf.c strlcat.c strlcpy.c dirmod.c noblock.c path.c + dirent.c dlopen.c getopt.c getopt_long.c + pread.c pwrite.c pg_bitutils.c pg_strong_random.c pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c pqsignal.c mkdtemp.c qsort.c qsort_arg.c quotes.c system.c - sprompt.c tar.c thread.c getopt.c getopt_long.c dirent.c + sprompt.c strerror.c tar.c thread.c win32env.c win32error.c win32security.c win32setlocale.c); push(@pgportfiles, 'rint.c') if ($vsVersion < '12.00'); + push(@pgportfiles, 'strtof.c') if ($vsVersion < '14.00'); + if ($vsVersion >= '9.00') { push(@pgportfiles, 'pg_crc32c_sse42_choose.c'); @@ -111,8 +120,9 @@ sub mkvcbuild } our @pgcommonallfiles = qw( - base64.c config_info.c controldata_utils.c exec.c file_perm.c ip.c - keywords.c md5.c pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c + base64.c config_info.c controldata_utils.c d2s.c exec.c f2s.c file_perm.c ip.c + keywords.c kwlookup.c link-canary.c md5.c + pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c saslprep.c scram-common.c string.c unicode_norm.c username.c wait_error.c); @@ -127,12 +137,13 @@ sub mkvcbuild our @pgcommonfrontendfiles = ( @pgcommonallfiles, qw(fe_memutils.c file_utils.c - restricted_token.c)); + logging.c restricted_token.c)); our @pgcommonbkndfiles = @pgcommonallfiles; our @pgfeutilsfiles = qw( - conditional.c mbprint.c print.c psqlscan.l psqlscan.c simple_list.c string_utils.c); + conditional.c mbprint.c print.c psqlscan.l psqlscan.c + simple_list.c string_utils.c recovery_gen.c); $libpgport = $solution->AddProject('libpgport', 'lib', 'misc'); $libpgport->AddDefine('FRONTEND'); @@ -151,9 +162,6 @@ sub mkvcbuild $postgres->AddIncludeDir('src/backend'); $postgres->AddDir('src/backend/port/win32'); $postgres->AddFile('src/backend/utils/fmgrtab.c'); - $postgres->ReplaceFile( - 'src/backend/port/dynloader.c', - 'src/backend/port/dynloader/win32.c'); $postgres->ReplaceFile('src/backend/port/pg_sema.c', 'src/backend/port/win32_sema.c'); $postgres->ReplaceFile('src/backend/port/pg_shmem.c', @@ -173,19 +181,26 @@ sub mkvcbuild 'src/backend/replication', 'repl_scanner.l', 'repl_gram.y', 'syncrep_scanner.l', 'syncrep_gram.y'); + $postgres->AddFiles('src/backend/utils/adt', 'jsonpath_scan.l', + 'jsonpath_gram.y'); $postgres->AddDefine('BUILDING_DLL'); $postgres->AddLibrary('secur32.lib'); $postgres->AddLibrary('ws2_32.lib'); $postgres->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); $postgres->FullExportDLL('postgres.lib'); - # The OBJS scraper doesn't know about ifdefs, so remove be-secure-openssl.c - # if building without OpenSSL + # The OBJS scraper doesn't know about ifdefs, so remove appropriate files + # if building without OpenSSL. if (!$solution->{options}->{openssl}) { $postgres->RemoveFile('src/backend/libpq/be-secure-common.c'); $postgres->RemoveFile('src/backend/libpq/be-secure-openssl.c'); } + if (!$solution->{options}->{gss}) + { + $postgres->RemoveFile('src/backend/libpq/be-gssapi-common.c'); + $postgres->RemoveFile('src/backend/libpq/be-secure-gssapi.c'); + } my $snowball = $solution->AddProject('dict_snowball', 'dll', '', 'src/backend/snowball'); @@ -237,20 +252,19 @@ sub mkvcbuild $libpq->UseDef('src/interfaces/libpq/libpqdll.def'); $libpq->ReplaceFile('src/interfaces/libpq/libpqrc.c', 'src/interfaces/libpq/libpq.rc'); - $libpq->AddReference($libpgport); + $libpq->AddReference($libpgcommon, $libpgport); - # The OBJS scraper doesn't know about ifdefs, so remove fe-secure-openssl.c - # and sha2_openssl.c if building without OpenSSL, and remove sha2.c if - # building with OpenSSL. + # The OBJS scraper doesn't know about ifdefs, so remove appropriate files + # if building without OpenSSL. if (!$solution->{options}->{openssl}) { $libpq->RemoveFile('src/interfaces/libpq/fe-secure-common.c'); $libpq->RemoveFile('src/interfaces/libpq/fe-secure-openssl.c'); - $libpq->RemoveFile('src/common/sha2_openssl.c'); } - else + if (!$solution->{options}->{gss}) { - $libpq->RemoveFile('src/common/sha2.c'); + $libpq->RemoveFile('src/interfaces/libpq/fe-gssapi-common.c'); + $libpq->RemoveFile('src/interfaces/libpq/fe-secure-gssapi.c'); } my $libpqwalreceiver = @@ -267,7 +281,7 @@ sub mkvcbuild 'libpgtypes', 'dll', 'interfaces', 'src/interfaces/ecpg/pgtypeslib'); $pgtypes->AddDefine('FRONTEND'); - $pgtypes->AddReference($libpgport); + $pgtypes->AddReference($libpgcommon, $libpgport); $pgtypes->UseDef('src/interfaces/ecpg/pgtypeslib/pgtypeslib.def'); $pgtypes->AddIncludeDir('src/interfaces/ecpg/include'); @@ -293,10 +307,10 @@ sub mkvcbuild my $ecpg = $solution->AddProject('ecpg', 'exe', 'interfaces', 'src/interfaces/ecpg/preproc'); $ecpg->AddIncludeDir('src/interfaces/ecpg/include'); + $ecpg->AddIncludeDir('src/interfaces/ecpg/ecpglib'); $ecpg->AddIncludeDir('src/interfaces/libpq'); $ecpg->AddPrefixInclude('src/interfaces/ecpg/preproc'); $ecpg->AddFiles('src/interfaces/ecpg/preproc', 'pgc.l', 'preproc.y'); - $ecpg->AddDefine('ECPG_COMPILE'); $ecpg->AddReference($libpgcommon, $libpgport); my $pgregress_ecpg = @@ -504,7 +518,7 @@ sub mkvcbuild my $hstore_plpython = AddTransformModule( 'hstore_plpython' . $pymajorver, 'contrib/hstore_plpython', 'plpython' . $pymajorver, 'src/pl/plpython', - 'hstore', 'contrib/hstore'); + 'hstore', 'contrib'); $hstore_plpython->AddDefine( 'PLPYTHON_LIBNAME="plpython' . $pymajorver . '"'); my $jsonb_plpython = AddTransformModule( @@ -515,7 +529,7 @@ sub mkvcbuild my $ltree_plpython = AddTransformModule( 'ltree_plpython' . $pymajorver, 'contrib/ltree_plpython', 'plpython' . $pymajorver, 'src/pl/plpython', - 'ltree', 'contrib/ltree'); + 'ltree', 'contrib'); $ltree_plpython->AddDefine( 'PLPYTHON_LIBNAME="plpython' . $pymajorver . '"'); } @@ -534,7 +548,8 @@ sub mkvcbuild # Starting with ActivePerl 5.24, both perlnn.lib and libperlnn.a are provided. # In this case, prefer .lib. my @perl_libs = - reverse sort grep { /perl\d+\.lib$|libperl\d+\.a$/ } glob($perl_path); + reverse sort grep { /perl\d+\.lib$|libperl\d+\.a$/ } + glob($perl_path); if (@perl_libs > 0) { $plperl->AddLibrary($perl_libs[0]); @@ -542,7 +557,7 @@ sub mkvcbuild else { die -"could not identify perl library version matching pattern $perl_path\n"; + "could not identify perl library version matching pattern $perl_path\n"; } # Add defines from Perl's ccflags; see PGAC_CHECK_PERL_EMBED_CCFLAGS @@ -632,7 +647,7 @@ sub mkvcbuild { # Some builds exhibit runtime failure through Perl warning - # 'Can't spawn "conftest.exe"'; supress that. + # 'Can't spawn "conftest.exe"'; suppress that. no warnings; # Disable error dialog boxes like we do in the postmaster. @@ -686,7 +701,7 @@ sub mkvcbuild (my $xsc = $xs) =~ s/\.xs/.c/; if (Solution::IsNewer("$plperlsrc$xsc", "$plperlsrc$xs")) { - my $xsubppdir = first { -e "$_/ExtUtils/xsubpp" } @INC; + my $xsubppdir = first { -e "$_/ExtUtils/xsubpp" } (@INC); print "Building $plperlsrc$xsc...\n"; system( $solution->{options}->{perl} . '/bin/perl ' @@ -750,10 +765,10 @@ sub mkvcbuild my $hstore_plperl = AddTransformModule( 'hstore_plperl', 'contrib/hstore_plperl', 'plperl', 'src/pl/plperl', - 'hstore', 'contrib/hstore'); + 'hstore', 'contrib'); my $jsonb_plperl = AddTransformModule( 'jsonb_plperl', 'contrib/jsonb_plperl', - 'plperl', 'src/pl/plperl'); + 'plperl', 'src/pl/plperl'); foreach my $f (@perl_embed_ccflags) { @@ -856,12 +871,12 @@ sub AddSimpleFrontend # Add a simple transform module sub AddTransformModule { - my $n = shift; - my $n_src = shift; - my $pl_proj_name = shift; - my $pl_src = shift; - my $type_name = shift; - my $type_src = shift; + my $n = shift; + my $n_src = shift; + my $pl_proj_name = shift; + my $pl_src = shift; + my $type_name = shift; + my $type_src = shift; my $type_proj = undef; if ($type_name) @@ -959,6 +974,7 @@ sub AddContrib # Are there any output data files to build? GenerateContribSqlFiles($n, $mf); + return; } sub GenerateContribSqlFiles @@ -995,7 +1011,7 @@ sub GenerateContribSqlFiles print "Building $out from $in (contrib/$n)...\n"; my $cont = Project::read_file("contrib/$n/$in"); my $dn = $out; - $dn =~ s/\.sql$//; + $dn =~ s/\.sql$//; $cont =~ s/MODULE_PATHNAME/\$libdir\/$dn/g; my $o; open($o, '>', "contrib/$n/$out") @@ -1005,6 +1021,7 @@ sub GenerateContribSqlFiles } } } + return; } sub AdjustContribProj @@ -1015,6 +1032,7 @@ sub AdjustContribProj \@contrib_uselibpq, \@contrib_uselibpgport, \@contrib_uselibpgcommon, $contrib_extralibs, $contrib_extrasource, $contrib_extraincludes); + return; } sub AdjustFrontendProj @@ -1025,6 +1043,7 @@ sub AdjustFrontendProj \@frontend_uselibpq, \@frontend_uselibpgport, \@frontend_uselibpgcommon, $frontend_extralibs, $frontend_extrasource, $frontend_extraincludes); + return; } sub AdjustModule @@ -1081,6 +1100,7 @@ sub AdjustModule $proj->AddFile($i); } } + return; } END diff --git a/src/tools/msvc/Project.pm b/src/tools/msvc/Project.pm index 9817b9439a9..b5d1dc6e89a 100644 --- a/src/tools/msvc/Project.pm +++ b/src/tools/msvc/Project.pm @@ -16,7 +16,8 @@ sub _new my $good_types = { lib => 1, exe => 1, - dll => 1, }; + dll => 1, + }; confess("Bad project type: $type\n") unless exists $good_types->{$type}; my $self = { name => $name, @@ -32,7 +33,8 @@ sub _new solution => $solution, disablewarnings => '4018;4244;4273;4102;4090;4267', disablelinkerwarnings => '', - platform => $solution->{platform}, }; + platform => $solution->{platform}, + }; bless($self, $classname); return $self; @@ -43,6 +45,7 @@ sub AddFile my ($self, $filename) = @_; $self->{files}->{$filename} = 1; + return; } sub AddFiles @@ -54,6 +57,7 @@ sub AddFiles { $self->{files}->{ $dir . "/" . $f } = 1; } + return; } sub ReplaceFile @@ -108,6 +112,7 @@ sub RelocateFiles $self->AddFile($targetdir . '/' . basename($f)); } } + return; } sub AddReference @@ -120,6 +125,7 @@ sub AddReference $self->AddLibrary( "__CFGNAME__/" . $ref->{name} . "/" . $ref->{name} . ".lib"); } + return; } sub AddLibrary @@ -136,6 +142,7 @@ sub AddLibrary { push @{ $self->{suffixlib} }, $lib; } + return; } sub AddIncludeDir @@ -147,6 +154,7 @@ sub AddIncludeDir $self->{includes} .= ';'; } $self->{includes} .= $inc; + return; } sub AddPrefixInclude @@ -154,6 +162,7 @@ sub AddPrefixInclude my ($self, $inc) = @_; $self->{prefixincludes} = $inc . ';' . $self->{prefixincludes}; + return; } sub AddDefine @@ -162,6 +171,7 @@ sub AddDefine $def =~ s/"/""/g; $self->{defines} .= $def . ';'; + return; } sub FullExportDLL @@ -171,6 +181,7 @@ sub FullExportDLL $self->{builddef} = 1; $self->{def} = "./__CFGNAME__/$self->{name}/$self->{name}.def"; $self->{implib} = "__CFGNAME__/$self->{name}/$libname"; + return; } sub UseDef @@ -178,6 +189,7 @@ sub UseDef my ($self, $def) = @_; $self->{def} = $def; + return; } sub AddDir @@ -192,7 +204,7 @@ sub AddDir { next if $subdir eq "\$(top_builddir)/src/timezone" - ; #special case for non-standard include + ; #special case for non-standard include next if $reldir . "/" . $subdir eq "src/backend/port/darwin"; @@ -217,8 +229,8 @@ sub AddDir if ($filter eq "LIBOBJS") { - if (grep(/$p/, @main::pgportfiles, @main::pgcommonfiles) - == 1) + no warnings qw(once); + if (grep(/$p/, @main::pgportfiles) == 1) { $p =~ s/\.c/\.o/; $matches .= $p . " "; @@ -282,6 +294,7 @@ sub AddDir } $self->AddDirResourceFile($reldir); + return; } # If the directory's Makefile bears a description string, add a resource file. @@ -297,6 +310,7 @@ sub AddDirResourceFile if ($mf =~ /^PGAPPICON\s*=\s*(.*)$/m) { $ico = $1; } $self->AddResourceFile($reldir, $desc, $ico); } + return; } sub AddResourceFile @@ -330,6 +344,7 @@ sub AddResourceFile close($i); } $self->AddFile("$dir/win32ver.rc"); + return; } sub DisableLinkerWarnings @@ -339,21 +354,22 @@ sub DisableLinkerWarnings $self->{disablelinkerwarnings} .= ',' unless ($self->{disablelinkerwarnings} eq ''); $self->{disablelinkerwarnings} .= $warnings; + return; } sub Save { my ($self) = @_; -# If doing DLL and haven't specified a DEF file, do a full export of all symbols -# in the project. + # If doing DLL and haven't specified a DEF file, do a full export of all symbols + # in the project. if ($self->{type} eq "dll" && !$self->{def}) { $self->FullExportDLL($self->{name} . ".lib"); } -# Warning 4197 is about double exporting, disable this per -# http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99193 + # Warning 4197 is about double exporting, disable this per + # http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=99193 $self->DisableLinkerWarnings('4197') if ($self->{platform} eq 'x64'); # Dump the project @@ -364,6 +380,7 @@ sub Save $self->WriteFiles($f); $self->Footer($f); close($f); + return; } sub GetAdditionalLinkerDependencies diff --git a/src/tools/msvc/README b/src/tools/msvc/README index 48082cab90a..d22fff331d6 100644 --- a/src/tools/msvc/README +++ b/src/tools/msvc/README @@ -4,7 +4,7 @@ MSVC build ========== This directory contains the tools required to build PostgreSQL using -Microsoft Visual Studio 2005 - 2017. This builds the whole backend, not just +Microsoft Visual Studio 2013 - 2019. This builds the whole backend, not just the libpq frontend library. For more information, see the documentation chapter "Installation on Windows" and the description below. @@ -16,7 +16,7 @@ has to be installed. Since this is not included in the product originally, extra steps are needed to make it work. First, download and install a supported version of the Microsoft Windows SDK -from www.microsoft.com (v6.0 or greater). +from www.microsoft.com (v8.1a or greater). Locate the files vcprojectengine.dll.express.config and vcprojectengine.dll.config in the vc\vcpackages directory of @@ -47,7 +47,6 @@ arguments. - User tools - build.pl tool to build the binaries -builddoc.pl tool to build the docs clean.bat batch file for cleaning up generated files install.pl tool to install the generated files mkvcbuild.pl tool to generate the Visual Studio build files @@ -68,14 +67,12 @@ Install.pm module containing the install logic Mkvcbuild.pm module containing the code to generate the Visual Studio build (project/solution) files MSBuildProject.pm module containing the code to generate MSBuild based - project files (Visual Studio 2010 or greater) + project files (Visual Studio 2013 or greater) Project.pm module containing the common code to generate the Visual Studio project files. Also provides the common interface of all project file generators Solution.pm module containing the code to generate the Visual Studio solution files. -VCBuildProject.pm module containing the code to generate VCBuild based - project files (Visual Studio 2005/2008) VSObjectFactory.pm factory module providing the code to create the appropriate project/solution files for the current environment @@ -91,14 +88,12 @@ config_default.pl to create the configuration arguments. These configuration arguments are passed over to Mkvcbuild::mkvcbuild (Mkvcbuild.pm) which creates the Visual Studio project and solution files. It does this by using VSObjectFactory::CreateSolution to create an object -implementing the Solution interface (this could be either a VS2005Solution, -a VS2008Solution, a VS2010Solution or a VS2012Solution or a VS2013Solution, -or a VS2015Solution or a VS2017Solution, all in Solution.pm, depending on -the user's build environment) and adding objects implementing the corresponding -Project interface (VC2005Project or VC2008Project from VCBuildProject.pm or -VC2010Project or VC2012Project or VC2013Project or VC2015Project or VC2017Project -from MSBuildProject.pm) to it. +implementing the Solution interface (this could be either VS2013Solution, +VS2015Solution, VS2017Solution or VS2019Solution, all in Solution.pm, +depending on the user's build environment) and adding objects implementing +the corresponding Project interface (VC2013Project, VC2015Project, +VC2017Project or VC2019Project from MSBuildProject.pm) to it. When Solution::Save is called, the implementations of Solution and Project save their content in the appropriate format. -The final step of starting the appropriate build program (msbuild or vcbuild) -is performed in build.pl again. +The final step of starting the appropriate build program (msbuild) is +performed in build.pl again. diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index f9534605231..318594db5da 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -10,6 +10,8 @@ use strict; use warnings; use VSObjectFactory; +no warnings qw(redefine); ## no critic + sub _new { my $classname = shift; @@ -22,7 +24,8 @@ sub _new VisualStudioVersion => undef, MinimumVisualStudioVersion => undef, vcver => undef, - platform => undef, }; + platform => undef, + }; bless($self, $classname); $self->DeterminePlatform(); @@ -51,11 +54,7 @@ sub _new unless $options->{wal_blocksize}; # undef or 0 means default die "Bad wal_blocksize $options->{wal_blocksize}" unless grep { $_ == $options->{wal_blocksize} } - (1, 2, 4, 8, 16, 32, 64); - $options->{wal_segsize} = 16 - unless $options->{wal_segsize}; # undef or 0 means default - die "Bad wal_segsize $options->{wal_segsize}" - unless grep { $_ == $options->{wal_segsize} } (1, 2, 4, 8, 16, 32, 64); + (1, 2, 4, 8, 16, 32, 64); return $self; } @@ -74,6 +73,7 @@ sub DeterminePlatform $? >> 8 == 0 or die "cl command not found"; $self->{platform} = ($output =~ /^\/favor:<.+AMD64/m) ? 'x64' : 'Win32'; print "Detected hardware platform: $self->{platform}\n"; + return; } # Return 1 if $oldfile is newer than $newfile, or if $newfile doesn't exist. @@ -111,6 +111,35 @@ sub copyFile } close($i); close($o); + return; +} + +# Fetch version of OpenSSL based on a parsing of the command shipped with +# the installer this build is linking to. This returns as result an array +# made of the three first digits of the OpenSSL version, which is enough +# to decide which options to apply depending on the version of OpenSSL +# linking with. +sub GetOpenSSLVersion +{ + my $self = shift; + + # Attempt to get OpenSSL version and location. This assumes that + # openssl.exe is in the specified directory. + my $opensslcmd = + $self->{options}->{openssl} . "\\bin\\openssl.exe version 2>&1"; + my $sslout = `$opensslcmd`; + + $? >> 8 == 0 + or croak + "Unable to determine OpenSSL version: The openssl.exe command wasn't found."; + + if ($sslout =~ /(\d+)\.(\d+)\.(\d+)(\D)/m) + { + return ($1, $2, $3); + } + + croak + "Unable to determine OpenSSL version: The openssl.exe version could not be determined."; } sub GenerateFiles @@ -157,7 +186,7 @@ sub GenerateFiles { s{PG_VERSION "[^"]+"}{PG_VERSION "$self->{strver}$extraver"}; s{PG_VERSION_NUM \d+}{PG_VERSION_NUM $self->{numver}}; -s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, compiled by Visual C++ build " CppAsString2(_MSC_VER) ", $bits-bit"}; + s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, compiled by Visual C++ build " CppAsString2(_MSC_VER) ", $bits-bit"}; print $o $_; } print $o "#define PG_MAJORVERSION \"$self->{majorver}\"\n"; @@ -167,17 +196,15 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c print $o "#ifndef IGNORE_CONFIGURED_SETTINGS\n"; print $o "#define USE_ASSERT_CHECKING 1\n" if ($self->{options}->{asserts}); - print $o "#define USE_LDAP 1\n" if ($self->{options}->{ldap}); - print $o "#define HAVE_LIBZ 1\n" if ($self->{options}->{zlib}); - print $o "#define USE_OPENSSL 1\n" if ($self->{options}->{openssl}); - print $o "#define ENABLE_NLS 1\n" if ($self->{options}->{nls}); + print $o "#define USE_LDAP 1\n" if ($self->{options}->{ldap}); + print $o "#define HAVE_LIBZ 1\n" if ($self->{options}->{zlib}); + print $o "#define ENABLE_NLS 1\n" if ($self->{options}->{nls}); print $o "#define BLCKSZ ", 1024 * $self->{options}->{blocksize}, "\n"; print $o "#define RELSEG_SIZE ", (1024 / $self->{options}->{blocksize}) * - $self->{options}->{segsize} * - 1024, "\n"; + $self->{options}->{segsize} * 1024, "\n"; print $o "#define XLOG_BLCKSZ ", 1024 * $self->{options}->{wal_blocksize}, "\n"; @@ -219,6 +246,21 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print $o "#define ENABLE_GSS 1\n"; } + if ($self->{options}->{openssl}) + { + print $o "#define USE_OPENSSL 1\n"; + + my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion(); + + # More symbols are needed with OpenSSL 1.1.0 and above. + if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0') + { + print $o "#define HAVE_ASN1_STRING_GET0_DATA 1\n"; + print $o "#define HAVE_BIO_GET_DATA 1\n"; + print $o "#define HAVE_BIO_METH_NEW 1\n"; + print $o "#define HAVE_OPENSSL_INIT_SSL 1\n"; + } + } if ($self->{options}->{icu}) { print $o "#define USE_ICU 1\n"; @@ -265,18 +307,18 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c "LIBPGTYPES"); chdir('src/backend/utils'); - my $pg_language_dat = '../../../src/include/catalog/pg_language.dat'; my $pg_proc_dat = '../../../src/include/catalog/pg_proc.dat'; - if (IsNewer( - 'fmgrtab.c', $pg_language_dat) - || IsNewer( - 'fmgrtab.c', $pg_proc_dat) - || IsNewer( - 'fmgrtab.c', '../../../src/include/access/transam.h') - ) + if ( IsNewer('fmgr-stamp', 'Gen_fmgrtab.pl') + || IsNewer('fmgr-stamp', '../catalog/Catalog.pm') + || IsNewer('fmgr-stamp', $pg_proc_dat) + || IsNewer('fmgr-stamp', '../../../src/include/access/transam.h')) { system( -"perl -I ../catalog Gen_fmgrtab.pl -I../../../src/include/ $pg_language_dat $pg_proc_dat"); + "perl -I ../catalog Gen_fmgrtab.pl --include-path ../../../src/include/ $pg_proc_dat" + ); + open(my $f, '>', 'fmgr-stamp') + || confess "Could not touch fmgr-stamp"; + close($f); } chdir('../../..'); @@ -315,18 +357,11 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c 'src/include/storage/lwlocknames.h'); } - if (IsNewer( - 'src/include/dynloader.h', 'src/backend/port/dynloader/win32.h')) - { - copyFile('src/backend/port/dynloader/win32.h', - 'src/include/dynloader.h'); - } - if (IsNewer('src/include/utils/probes.h', 'src/backend/utils/probes.d')) { print "Generating probes.h...\n"; system( -'perl src/backend/utils/Gen_dummy_probes.pl src/backend/utils/probes.d > src/include/utils/probes.h' + 'perl src/backend/utils/Gen_dummy_probes.pl src/backend/utils/probes.d > src/include/utils/probes.h' ); } @@ -337,7 +372,7 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print "Generating spiexceptions.h...\n"; system( -'perl src/pl/plpython/generate-spiexceptions.pl src/backend/utils/errcodes.txt > src/pl/plpython/spiexceptions.h' + 'perl src/pl/plpython/generate-spiexceptions.pl src/backend/utils/errcodes.txt > src/pl/plpython/spiexceptions.h' ); } @@ -347,7 +382,7 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print "Generating errcodes.h...\n"; system( -'perl src/backend/utils/generate-errcodes.pl src/backend/utils/errcodes.txt > src/backend/utils/errcodes.h' + 'perl src/backend/utils/generate-errcodes.pl src/backend/utils/errcodes.txt > src/backend/utils/errcodes.h' ); copyFile('src/backend/utils/errcodes.h', 'src/include/utils/errcodes.h'); @@ -359,7 +394,7 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print "Generating plerrcodes.h...\n"; system( -'perl src/pl/plpgsql/src/generate-plerrcodes.pl src/backend/utils/errcodes.txt > src/pl/plpgsql/src/plerrcodes.h' + 'perl src/pl/plpgsql/src/generate-plerrcodes.pl src/backend/utils/errcodes.txt > src/pl/plpgsql/src/plerrcodes.h' ); } @@ -369,7 +404,7 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print "Generating pltclerrcodes.h...\n"; system( -'perl src/pl/tcl/generate-pltclerrcodes.pl src/backend/utils/errcodes.txt > src/pl/tcl/pltclerrcodes.h' + 'perl src/pl/tcl/generate-pltclerrcodes.pl src/backend/utils/errcodes.txt > src/pl/tcl/pltclerrcodes.h' ); } @@ -379,7 +414,7 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c { print "Generating qsort_tuple.c...\n"; system( -'perl src/backend/utils/sort/gen_qsort_tuple.pl > src/backend/utils/sort/qsort_tuple.c' + 'perl src/backend/utils/sort/gen_qsort_tuple.pl > src/backend/utils/sort/qsort_tuple.c' ); } @@ -412,6 +447,51 @@ s{PG_VERSION_STR "[^"]+"}{PG_VERSION_STR "PostgreSQL $self->{strver}$extraver, c chdir('../../..'); } + if (IsNewer('src/common/kwlist_d.h', 'src/include/parser/kwlist.h')) + { + print "Generating kwlist_d.h...\n"; + system( + 'perl -I src/tools src/tools/gen_keywordlist.pl --extern -o src/common src/include/parser/kwlist.h' + ); + } + + if (IsNewer( + 'src/pl/plpgsql/src/pl_reserved_kwlist_d.h', + 'src/pl/plpgsql/src/pl_reserved_kwlist.h') + || IsNewer( + 'src/pl/plpgsql/src/pl_unreserved_kwlist_d.h', + 'src/pl/plpgsql/src/pl_unreserved_kwlist.h')) + { + print + "Generating pl_reserved_kwlist_d.h and pl_unreserved_kwlist_d.h...\n"; + chdir('src/pl/plpgsql/src'); + system( + 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ReservedPLKeywords pl_reserved_kwlist.h' + ); + system( + 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname UnreservedPLKeywords pl_unreserved_kwlist.h' + ); + chdir('../../../..'); + } + + if (IsNewer( + 'src/interfaces/ecpg/preproc/c_kwlist_d.h', + 'src/interfaces/ecpg/preproc/c_kwlist.h') + || IsNewer( + 'src/interfaces/ecpg/preproc/ecpg_kwlist_d.h', + 'src/interfaces/ecpg/preproc/ecpg_kwlist.h')) + { + print "Generating c_kwlist_d.h and ecpg_kwlist_d.h...\n"; + chdir('src/interfaces/ecpg/preproc'); + system( + 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ScanCKeywords --no-case-fold c_kwlist.h' + ); + system( + 'perl -I ../../../tools ../../../tools/gen_keywordlist.pl --varname ScanECPGKeywords ecpg_kwlist.h' + ); + chdir('../../../..'); + } + if (IsNewer( 'src/interfaces/ecpg/preproc/preproc.y', 'src/backend/parser/gram.y')) @@ -471,34 +551,59 @@ EOF $mf =~ /^POSTGRES_BKI_DATA\s*:?=[^,]+,(.*)\)$/gm || croak "Could not find POSTGRES_BKI_DATA in Makefile\n"; my @bki_data = split /\s+/, $1; + + my $need_genbki = 0; foreach my $bki (@bki_srcs, @bki_data) { next if $bki eq ""; if (IsNewer( - 'src/backend/catalog/postgres.bki', + 'src/backend/catalog/bki-stamp', "src/include/catalog/$bki")) { - chdir('src/backend/catalog'); - my $bki_srcs = join(' ../../../src/include/catalog/', @bki_srcs); - system("perl genbki.pl --set-version=$self->{majorver} $bki_srcs"); - chdir('../../..'); - - # Copy generated headers to include directory. - opendir(my $dh, 'src/backend/catalog/') - || die "Can't opendir src/backend/catalog/ $!"; - my @def_headers = grep { /pg_\w+_d\.h$/ } readdir($dh); - closedir $dh; - foreach my $def_header (@def_headers) - { - copyFile( + $need_genbki = 1; + last; + } + } + $need_genbki = 1 + if IsNewer('src/backend/catalog/bki-stamp', + 'src/backend/catalog/genbki.pl'); + $need_genbki = 1 + if IsNewer('src/backend/catalog/bki-stamp', + 'src/backend/catalog/Catalog.pm'); + if ($need_genbki) + { + chdir('src/backend/catalog'); + my $bki_srcs = join(' ../../../src/include/catalog/', @bki_srcs); + system( + "perl genbki.pl --include-path ../../../src/include/ --set-version=$self->{majorver} $bki_srcs" + ); + open(my $f, '>', 'bki-stamp') + || confess "Could not touch bki-stamp"; + close($f); + chdir('../../..'); + } + + if (IsNewer( + 'src/include/catalog/header-stamp', + 'src/backend/catalog/bki-stamp')) + { + # Copy generated headers to include directory. + opendir(my $dh, 'src/backend/catalog/') + || die "Can't opendir src/backend/catalog/ $!"; + my @def_headers = grep { /pg_\w+_d\.h$/ } readdir($dh); + closedir $dh; + foreach my $def_header (@def_headers) + { + copyFile( "src/backend/catalog/$def_header", "src/include/catalog/$def_header"); - } - copyFile( - 'src/backend/catalog/schemapg.h', - 'src/include/catalog/schemapg.h'); - last; } + copyFile( + 'src/backend/catalog/schemapg.h', + 'src/include/catalog/schemapg.h'); + open(my $chs, '>', 'src/include/catalog/header-stamp') + || confess "Could not touch header-stamp"; + close($chs); } open(my $o, '>', "doc/src/sgml/version.sgml") @@ -508,6 +613,7 @@ EOF {majorver}"> EOF close($o); + return; } sub GenerateDefFile @@ -530,6 +636,7 @@ sub GenerateDefFile close($of); close($if); } + return; } sub AddProject @@ -548,21 +655,70 @@ sub AddProject if ($self->{options}->{openssl}) { $proj->AddIncludeDir($self->{options}->{openssl} . '\include'); - if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib") + my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion(); + + # Starting at version 1.1.0 the OpenSSL installers have + # changed their library names from: + # - libeay to libcrypto + # - ssleay to libssl + if ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0') { - $proj->AddLibrary( - $self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1); - $proj->AddLibrary( - $self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1); + my $dbgsuffix; + my $libsslpath; + my $libcryptopath; + + # The format name of the libraries is slightly + # different between the Win32 and Win64 platform, so + # adapt. + if (-e "$self->{options}->{openssl}/lib/VC/sslcrypto32MD.lib") + { + # Win32 here, with a debugging library set. + $dbgsuffix = 1; + $libsslpath = '\lib\VC\libssl32.lib'; + $libcryptopath = '\lib\VC\libcrypto32.lib'; + } + elsif (-e "$self->{options}->{openssl}/lib/VC/sslcrypto64MD.lib") + { + # Win64 here, with a debugging library set. + $dbgsuffix = 1; + $libsslpath = '\lib\VC\libssl64.lib'; + $libcryptopath = '\lib\VC\libcrypto64.lib'; + } + else + { + # On both Win32 and Win64 the same library + # names are used without a debugging context. + $dbgsuffix = 0; + $libsslpath = '\lib\libssl.lib'; + $libcryptopath = '\lib\libcrypto.lib'; + } + + $proj->AddLibrary($self->{options}->{openssl} . $libsslpath, + $dbgsuffix); + $proj->AddLibrary($self->{options}->{openssl} . $libcryptopath, + $dbgsuffix); } else { - # We don't expect the config-specific library to be here, - # so don't ask for it in last parameter - $proj->AddLibrary( - $self->{options}->{openssl} . '\lib\ssleay32.lib', 0); - $proj->AddLibrary( - $self->{options}->{openssl} . '\lib\libeay32.lib', 0); + # Choose which set of libraries to use depending on if + # debugging libraries are in place in the installer. + if (-e "$self->{options}->{openssl}/lib/VC/ssleay32MD.lib") + { + $proj->AddLibrary( + $self->{options}->{openssl} . '\lib\VC\ssleay32.lib', 1); + $proj->AddLibrary( + $self->{options}->{openssl} . '\lib\VC\libeay32.lib', 1); + } + else + { + # We don't expect the config-specific library + # to be here, so don't ask for it in last + # parameter. + $proj->AddLibrary( + $self->{options}->{openssl} . '\lib\ssleay32.lib', 0); + $proj->AddLibrary( + $self->{options}->{openssl} . '\lib\libeay32.lib', 0); + } } } if ($self->{options}->{nls}) @@ -702,6 +858,7 @@ EOF EndGlobal EOF close($sln); + return; } sub GetFakeConfigure @@ -716,7 +873,7 @@ sub GetFakeConfigure $cfg .= ' --without-zlib' unless ($self->{options}->{zlib}); $cfg .= ' --with-extra-version' if ($self->{options}->{extraver}); $cfg .= ' --with-openssl' if ($self->{options}->{openssl}); - $cfg .= ' --with-ossp-uuid' if ($self->{options}->{uuid}); + $cfg .= ' --with-uuid' if ($self->{options}->{uuid}); $cfg .= ' --with-libxml' if ($self->{options}->{xml}); $cfg .= ' --with-libxslt' if ($self->{options}->{xslt}); $cfg .= ' --with-gssapi' if ($self->{options}->{gss}); @@ -728,56 +885,10 @@ sub GetFakeConfigure return $cfg; } -package VS2005Solution; - -# -# Package that encapsulates a Visual Studio 2005 solution file -# - -use strict; -use warnings; -use base qw(Solution); - -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{solutionFileVersion} = '9.00'; - $self->{vcver} = '8.00'; - $self->{visualStudioName} = 'Visual Studio 2005'; - - return $self; -} - -package VS2008Solution; - -# -# Package that encapsulates a Visual Studio 2008 solution file -# - -use strict; -use warnings; -use base qw(Solution); - -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{solutionFileVersion} = '10.00'; - $self->{vcver} = '9.00'; - $self->{visualStudioName} = 'Visual Studio 2008'; - - return $self; -} - -package VS2010Solution; +package VS2013Solution; # -# Package that encapsulates a Visual Studio 2010 solution file +# Package that encapsulates a Visual Studio 2013 solution file # use Carp; @@ -785,29 +896,7 @@ use strict; use warnings; use base qw(Solution); -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{solutionFileVersion} = '11.00'; - $self->{vcver} = '10.00'; - $self->{visualStudioName} = 'Visual Studio 2010'; - - return $self; -} - -package VS2012Solution; - -# -# Package that encapsulates a Visual Studio 2012 solution file -# - -use Carp; -use strict; -use warnings; -use base qw(Solution); +no warnings qw(redefine); ## no critic sub new { @@ -815,17 +904,19 @@ sub new my $self = $classname->SUPER::_new(@_); bless($self, $classname); - $self->{solutionFileVersion} = '12.00'; - $self->{vcver} = '11.00'; - $self->{visualStudioName} = 'Visual Studio 2012'; + $self->{solutionFileVersion} = '12.00'; + $self->{vcver} = '12.00'; + $self->{visualStudioName} = 'Visual Studio 2013'; + $self->{VisualStudioVersion} = '12.0.21005.1'; + $self->{MinimumVisualStudioVersion} = '10.0.40219.1'; return $self; } -package VS2013Solution; +package VS2015Solution; # -# Package that encapsulates a Visual Studio 2013 solution file +# Package that encapsulates a Visual Studio 2015 solution file # use Carp; @@ -833,6 +924,8 @@ use strict; use warnings; use base qw(Solution); +no warnings qw(redefine); ## no critic + sub new { my $classname = shift; @@ -840,18 +933,18 @@ sub new bless($self, $classname); $self->{solutionFileVersion} = '12.00'; - $self->{vcver} = '12.00'; - $self->{visualStudioName} = 'Visual Studio 2013'; - $self->{VisualStudioVersion} = '12.0.21005.1'; + $self->{vcver} = '14.00'; + $self->{visualStudioName} = 'Visual Studio 2015'; + $self->{VisualStudioVersion} = '14.0.24730.2'; $self->{MinimumVisualStudioVersion} = '10.0.40219.1'; return $self; } -package VS2015Solution; +package VS2017Solution; # -# Package that encapsulates a Visual Studio 2015 solution file +# Package that encapsulates a Visual Studio 2017 solution file # use Carp; @@ -859,6 +952,8 @@ use strict; use warnings; use base qw(Solution); +no warnings qw(redefine); ## no critic + sub new { my $classname = shift; @@ -866,18 +961,18 @@ sub new bless($self, $classname); $self->{solutionFileVersion} = '12.00'; - $self->{vcver} = '14.00'; - $self->{visualStudioName} = 'Visual Studio 2015'; - $self->{VisualStudioVersion} = '14.0.24730.2'; + $self->{vcver} = '15.00'; + $self->{visualStudioName} = 'Visual Studio 2017'; + $self->{VisualStudioVersion} = '15.0.26730.3'; $self->{MinimumVisualStudioVersion} = '10.0.40219.1'; return $self; } -package VS2017Solution; +package VS2019Solution; # -# Package that encapsulates a Visual Studio 2017 solution file +# Package that encapsulates a Visual Studio 2019 solution file # use Carp; @@ -885,6 +980,8 @@ use strict; use warnings; use base qw(Solution); +no warnings qw(redefine); ## no critic + sub new { my $classname = shift; @@ -892,9 +989,9 @@ sub new bless($self, $classname); $self->{solutionFileVersion} = '12.00'; - $self->{vcver} = '15.00'; - $self->{visualStudioName} = 'Visual Studio 2017'; - $self->{VisualStudioVersion} = '15.0.26730.3'; + $self->{vcver} = '16.00'; + $self->{visualStudioName} = 'Visual Studio 2019'; + $self->{VisualStudioVersion} = '16.0.28729.10'; $self->{MinimumVisualStudioVersion} = '10.0.40219.1'; return $self; diff --git a/src/tools/msvc/VCBuildProject.pm b/src/tools/msvc/VCBuildProject.pm deleted file mode 100644 index 669ba1730bc..00000000000 --- a/src/tools/msvc/VCBuildProject.pm +++ /dev/null @@ -1,294 +0,0 @@ -package VCBuildProject; - -# -# Package that encapsulates a VCBuild (Visual C++ 2005/2008) project file -# -# src/tools/msvc/VCBuildProject.pm -# - -use Carp; -use strict; -use warnings; -use base qw(Project); - -sub _new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{filenameExtension} = '.vcproj'; - - return $self; -} - -sub WriteHeader -{ - my ($self, $f) = @_; - - print $f < - - - -EOF - - $self->WriteConfiguration( - $f, 'Debug', - { defs => "_DEBUG;DEBUG=1", - wholeopt => 0, - opt => 0, - strpool => 'false', - runtime => 3 }); - $self->WriteConfiguration( - $f, - 'Release', - { defs => "", - wholeopt => 0, - opt => 3, - strpool => 'true', - runtime => 2 }); - print $f < -EOF - $self->WriteReferences($f); -} - -sub WriteFiles -{ - my ($self, $f) = @_; - print $f < -EOF - my @dirstack = (); - my %uniquefiles; - foreach my $fileNameWithPath (sort keys %{ $self->{files} }) - { - confess "Bad format filename '$fileNameWithPath'\n" - unless ($fileNameWithPath =~ m!^(.*)/([^/]+)\.(c|cpp|y|l|rc)$!); - my $dir = $1; - my $file = $2; - - # Walk backwards down the directory stack and close any dirs - # we're done with. - while ($#dirstack >= 0) - { - if (join('/', @dirstack) eq - substr($dir, 0, length(join('/', @dirstack)))) - { - last if (length($dir) == length(join('/', @dirstack))); - last - if (substr($dir, length(join('/', @dirstack)), 1) eq '/'); - } - print $f ' ' x $#dirstack . " \n"; - pop @dirstack; - } - - # Now walk forwards and create whatever directories are needed - while (join('/', @dirstack) ne $dir) - { - my $left = substr($dir, length(join('/', @dirstack))); - $left =~ s/^\///; - my @pieces = split /\//, $left; - push @dirstack, $pieces[0]; - print $f ' ' x $#dirstack - . " \n"; - } - - # VC builds do not like file paths with forward slashes. - my $fileNameWithPathFormatted = $fileNameWithPath; - $fileNameWithPathFormatted =~ s/\//\\/g; - - print $f ' ' x $#dirstack - . " ' - . $self->GenerateCustomTool( - 'Running bison on ' . $fileNameWithPath, - "perl src/tools/msvc/pgbison.pl $fileNameWithPath", $of) - . '' . "\n"; - } - elsif ($fileNameWithPath =~ /\.l$/) - { - my $of = $fileNameWithPath; - $of =~ s/\.l$/.c/; - print $f '>' - . $self->GenerateCustomTool( - 'Running flex on ' . $fileNameWithPath, - "perl src/tools/msvc/pgflex.pl $fileNameWithPath", $of) - . '' . "\n"; - } - elsif (defined($uniquefiles{$file})) - { - - # File already exists, so fake a new name - my $obj = $dir; - $obj =~ s!/!_!g; - print $f -">{platform}\">{name}\\$obj" - . "_$file.obj\" />{platform}\">{name}\\$obj" - . "_$file.obj\" />\n"; - } - else - { - $uniquefiles{$file} = 1; - print $f " />\n"; - } - } - while ($#dirstack >= 0) - { - print $f ' ' x $#dirstack . " \n"; - pop @dirstack; - } - print $f < -EOF -} - -sub Footer -{ - my ($self, $f) = @_; - - print $f < - -EOF -} - -sub WriteConfiguration -{ - my ($self, $f, $cfgname, $p) = @_; - my $cfgtype = - ($self->{type} eq "exe") ? 1 : ($self->{type} eq "dll" ? 2 : 4); - my $libs = $self->GetAdditionalLinkerDependencies($cfgname, ' '); - - my $targetmachine = $self->{platform} eq 'Win32' ? 1 : 17; - - print $f < - - {disablelinkerwarnings}) - { - print $f -"\t\tAdditionalOptions=\"/ignore:$self->{disablelinkerwarnings}\"\n"; - } - if ($self->{implib}) - { - my $l = $self->{implib}; - $l =~ s/__CFGNAME__/$cfgname/g; - print $f "\t\tImportLibrary=\"$l\"\n"; - } - if ($self->{def}) - { - my $d = $self->{def}; - $d =~ s/__CFGNAME__/$cfgname/g; - print $f "\t\tModuleDefinitionFile=\"$d\"\n"; - } - - print $f "\t/>\n"; - print $f -"\t{name}\\$self->{name}.lib\" IgnoreDefaultLibraryNames=\"libc\" />\n"; - print $f -"\t\n"; - if ($self->{builddef}) - { - print $f -"\t{name} $self->{platform}\" />\n"; - } - print $f < -EOF -} - -sub WriteReferences -{ - my ($self, $f) = @_; - print $f " \n"; - foreach my $ref (@{ $self->{references} }) - { - print $f -" {guid}\" Name=\"$ref->{name}\" />\n"; - } - print $f " \n"; -} - -sub GenerateCustomTool -{ - my ($self, $desc, $tool, $output, $cfg) = @_; - if (!defined($cfg)) - { - return $self->GenerateCustomTool($desc, $tool, $output, 'Debug') - . $self->GenerateCustomTool($desc, $tool, $output, 'Release'); - } - return -"{platform}\">"; -} - -package VC2005Project; - -# -# Package that encapsulates a Visual C++ 2005 project file -# - -use strict; -use warnings; -use base qw(VCBuildProject); - -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{vcver} = '8.00'; - - return $self; -} - -package VC2008Project; - -# -# Package that encapsulates a Visual C++ 2008 project file -# - -use strict; -use warnings; -use base qw(VCBuildProject); - -sub new -{ - my $classname = shift; - my $self = $classname->SUPER::_new(@_); - bless($self, $classname); - - $self->{vcver} = '9.00'; - - return $self; -} - -1; diff --git a/src/tools/msvc/VSObjectFactory.pm b/src/tools/msvc/VSObjectFactory.pm index 2f3480a1f60..610dc612866 100644 --- a/src/tools/msvc/VSObjectFactory.pm +++ b/src/tools/msvc/VSObjectFactory.pm @@ -13,13 +13,14 @@ use warnings; use Exporter; use Project; use Solution; -use VCBuildProject; use MSBuildProject; our (@ISA, @EXPORT); @ISA = qw(Exporter); @EXPORT = qw(CreateSolution CreateProject DetermineVisualStudioVersion); +no warnings qw(redefine); ## no critic + sub CreateSolution { my $visualStudioVersion = shift; @@ -29,23 +30,7 @@ sub CreateSolution $visualStudioVersion = DetermineVisualStudioVersion(); } - if ($visualStudioVersion eq '8.00') - { - return new VS2005Solution(@_); - } - elsif ($visualStudioVersion eq '9.00') - { - return new VS2008Solution(@_); - } - elsif ($visualStudioVersion eq '10.00') - { - return new VS2010Solution(@_); - } - elsif ($visualStudioVersion eq '11.00') - { - return new VS2012Solution(@_); - } - elsif ($visualStudioVersion eq '12.00') + if ($visualStudioVersion eq '12.00') { return new VS2013Solution(@_); } @@ -53,15 +38,30 @@ sub CreateSolution { return new VS2015Solution(@_); } - # visual 2017 hasn't changed the nmake version to 15, so adjust the check to support it. - elsif (($visualStudioVersion ge '14.10') or ($visualStudioVersion eq '15.00')) + + # The version of nmake bundled in Visual Studio 2017 is greater + # than 14.10 and less than 14.20. And the version number is + # actually 15.00. + elsif ( + ($visualStudioVersion ge '14.10' && $visualStudioVersion lt '14.20') + || $visualStudioVersion eq '15.00') { return new VS2017Solution(@_); } + + # The version of nmake bundled in Visual Studio 2019 is greater + # than 14.20 and less than 14.30. And the version number is + # actually 16.00. + elsif ( + ($visualStudioVersion ge '14.20' && $visualStudioVersion lt '14.30') + || $visualStudioVersion eq '16.00') + { + return new VS2019Solution(@_); + } else { - croak $visualStudioVersion; - croak "The requested Visual Studio version is not supported."; + croak + "The requested Visual Studio version $visualStudioVersion is not supported."; } } @@ -74,23 +74,7 @@ sub CreateProject $visualStudioVersion = DetermineVisualStudioVersion(); } - if ($visualStudioVersion eq '8.00') - { - return new VC2005Project(@_); - } - elsif ($visualStudioVersion eq '9.00') - { - return new VC2008Project(@_); - } - elsif ($visualStudioVersion eq '10.00') - { - return new VC2010Project(@_); - } - elsif ($visualStudioVersion eq '11.00') - { - return new VC2012Project(@_); - } - elsif ($visualStudioVersion eq '12.00') + if ($visualStudioVersion eq '12.00') { return new VC2013Project(@_); } @@ -98,15 +82,30 @@ sub CreateProject { return new VC2015Project(@_); } - # visual 2017 hasn't changed the nmake version to 15, so adjust the check to support it. - elsif (($visualStudioVersion ge '14.10') or ($visualStudioVersion eq '15.00')) + + # The version of nmake bundled in Visual Studio 2017 is greater + # than 14.10 and less than 14.20. And the version number is + # actually 15.00. + elsif ( + ($visualStudioVersion ge '14.10' && $visualStudioVersion lt '14.20') + || $visualStudioVersion eq '15.00') { return new VC2017Project(@_); } + + # The version of nmake bundled in Visual Studio 2019 is greater + # than 14.20 and less than 14.30. And the version number is + # actually 16.00. + elsif ( + ($visualStudioVersion ge '14.20' && $visualStudioVersion lt '14.30') + || $visualStudioVersion eq '16.00') + { + return new VC2019Project(@_); + } else { - croak $visualStudioVersion; - croak "The requested Visual Studio version is not supported."; + croak + "The requested Visual Studio version $visualStudioVersion is not supported."; } } @@ -119,30 +118,33 @@ sub DetermineVisualStudioVersion my $output = `nmake /? 2>&1`; $? >> 8 == 0 or croak -"Unable to determine Visual Studio version: The nmake command wasn't found."; + "Unable to determine Visual Studio version: The nmake command wasn't found."; if ($output =~ /(\d+)\.(\d+)\.\d+(\.\d+)?$/m) { return _GetVisualStudioVersion($1, $2); } croak -"Unable to determine Visual Studio version: The nmake version could not be determined."; + "Unable to determine Visual Studio version: The nmake version could not be determined."; } sub _GetVisualStudioVersion { my ($major, $minor) = @_; - # visual 2017 hasn't changed the nmake version to 15, so still using the older version for comparison. - if ($major > 14) + + # The major visual studio that is supported has nmake + # version <= 14.30, so stick with it as the latest version + # if bumping on something even newer. + if ($major >= 14 && $minor >= 30) { carp -"The determined version of Visual Studio is newer than the latest supported version. Returning the latest supported version instead."; - return '14.00'; + "The determined version of Visual Studio is newer than the latest supported version. Returning the latest supported version instead."; + return '14.20'; } - elsif ($major < 6) + elsif ($major < 12) { croak -"Unable to determine Visual Studio version: Visual Studio versions before 6.0 aren't supported."; + "Unable to determine Visual Studio version: Visual Studio versions before 12.0 aren't supported."; } return "$major.$minor"; } diff --git a/src/tools/msvc/build.pl b/src/tools/msvc/build.pl index 744c1f7d6ee..52abdb17b9b 100644 --- a/src/tools/msvc/build.pl +++ b/src/tools/msvc/build.pl @@ -4,26 +4,25 @@ use strict; -BEGIN -{ - - chdir("../../..") if (-d "../msvc" && -d "../../../src"); - -} - -use lib "src/tools/msvc"; +use File::Basename; +use File::Spec; +BEGIN { use lib File::Spec->rel2abs(dirname(__FILE__)); } use Cwd; use Mkvcbuild; +chdir('..\..\..') if (-d '..\msvc' && -d '..\..\..\src'); +die 'Must run from root or msvc directory' + unless (-d 'src\tools\msvc' && -d 'src'); + # buildenv.pl is for specifying the build environment settings # it should contain lines like: # $ENV{PATH} = "c:/path/to/bison/bin;$ENV{PATH}"; if (-e "src/tools/msvc/buildenv.pl") { - do "src/tools/msvc/buildenv.pl"; + do "./src/tools/msvc/buildenv.pl"; } elsif (-e "./buildenv.pl") { @@ -32,8 +31,8 @@ BEGIN # set up the project our $config; -do "config_default.pl"; -do "config.pl" if (-f "src/tools/msvc/config.pl"); +do "./src/tools/msvc/config_default.pl"; +do "./src/tools/msvc/config.pl" if (-f "src/tools/msvc/config.pl"); my $vcver = Mkvcbuild::mkvcbuild($config); @@ -53,20 +52,17 @@ BEGIN # ... and do it -if ($buildwhat and $vcver >= 10.00) +if ($buildwhat) { system( -"msbuild $buildwhat.vcxproj /verbosity:normal $msbflags /p:Configuration=$bconf" + "msbuild $buildwhat.vcxproj /verbosity:normal $msbflags /p:Configuration=$bconf" ); } -elsif ($buildwhat) -{ - system("vcbuild $msbflags $buildwhat.vcproj $bconf"); -} else { system( -"msbuild pgsql.sln /verbosity:normal $msbflags /p:Configuration=$bconf"); + "msbuild pgsql.sln /verbosity:normal $msbflags /p:Configuration=$bconf" + ); } # report status diff --git a/src/tools/msvc/builddoc.bat b/src/tools/msvc/builddoc.bat deleted file mode 100755 index 024706989e9..00000000000 --- a/src/tools/msvc/builddoc.bat +++ /dev/null @@ -1,7 +0,0 @@ -@echo off - -REM src/tools/msvc/builddoc.bat -REM all the logic for this now belongs in builddoc.pl. This file really -REM only exists so you don't have to type "perl builddoc.pl" -REM Resist any temptation to add any logic here. -@perl builddoc.pl %* diff --git a/src/tools/msvc/builddoc.pl b/src/tools/msvc/builddoc.pl deleted file mode 100644 index e0b5c50b342..00000000000 --- a/src/tools/msvc/builddoc.pl +++ /dev/null @@ -1,124 +0,0 @@ -# -*-perl-*- hey - emacs - this is a perl file - -# Adjust path for your docbook installation in buildenv.pl - -# src/tools/msvc/builddoc.pl -# translated from an earlier .bat file - -use strict; -use File::Copy; -use Cwd qw(abs_path getcwd); - -my $startdir = getcwd(); - -my $openjade = 'openjade-1.3.1'; -my $dsssl = 'docbook-dsssl-1.79'; - -chdir '../../..' if (-d '../msvc' && -d '../../../src'); - -noversion() unless -e 'doc/src/sgml/version.sgml'; - -do 'src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; - -my $docroot = $ENV{DOCROOT}; -die "bad DOCROOT '$docroot'" unless ($docroot && -d $docroot); - -my @notfound; -foreach my $dir ('docbook', $openjade, $dsssl) -{ - push(@notfound, $dir) unless -d "$docroot/$dir"; -} -missing() if @notfound; - -my $arg = shift; -renamefiles(); - -chdir 'doc/src/sgml'; - -$ENV{SGML_CATALOG_FILES} = - "$docroot/$openjade/dsssl/catalog;" . "$docroot/docbook/docbook.cat"; - -my $cmd; - -# openjade exits below with a harmless non-zero status, so we -# can't die on "failure" - -$cmd = - "perl mk_feature_tables.pl YES " - . "../../../src/backend/catalog/sql_feature_packages.txt " - . "../../../src/backend/catalog/sql_features.txt " - . "> features-supported.sgml"; -system($cmd); -die "features_supported" if $?; -$cmd = - "perl mk_feature_tables.pl NO " - . "\"../../../src/backend/catalog/sql_feature_packages.txt\" " - . "\"../../../src/backend/catalog/sql_features.txt\" " - . "> features-unsupported.sgml"; -system($cmd); -die "features_unsupported" if $?; -$cmd = -"perl generate-errcodes-table.pl \"../../../src/backend/utils/errcodes.txt\" " - . "> errcodes-table.sgml"; -system($cmd); -die "errcodes-table" if $?; - -print "Running first build...\n"; -$cmd = - "\"$docroot/$openjade/bin/openjade\" -V html-index -wall " - . "-wno-unused-param -wno-empty -D . -c \"$docroot/$dsssl/catalog\" " - . "-d stylesheet.dsl -i output-html -t sgml postgres.sgml 2>&1 " - . "| findstr /V \"DTDDECL catalog entries are not supported\" "; -system($cmd); # die "openjade" if $?; -print "Running collateindex...\n"; -$cmd = "perl \"$docroot/$dsssl/bin/collateindex.pl\" -f -g -i bookindex " - . "-o bookindex.sgml HTML.index"; -system($cmd); -die "collateindex" if $?; -mkdir "html"; -print "Running second build...\n"; -$cmd = - "\"$docroot/$openjade/bin/openjade\" -wall -wno-unused-param -wno-empty " - . "-D . -c \"$docroot/$dsssl/catalog\" -d stylesheet.dsl -t sgml " - . "-i output-html -i include-index postgres.sgml 2>&1 " - . "| findstr /V \"DTDDECL catalog entries are not supported\" "; - -system($cmd); # die "openjade" if $?; - -copy "stylesheet.css", "html/stylesheet.css"; - -print "Docs build complete.\n"; - -exit; - -######################################################## - -sub renamefiles -{ - - # Rename ISO entity files - my $savedir = getcwd(); - chdir "$docroot/docbook"; - foreach my $f (glob('ISO*')) - { - next if $f =~ /\.gml$/i; - my $nf = $f; - $nf =~ s/ISO(.*)/ISO-$1.gml/; - move $f, $nf; - } - chdir $savedir; - -} - -sub missing -{ - print STDERR "could not find $docroot/$_\n" foreach (@notfound); - exit 1; -} - -sub noversion -{ - print STDERR "Could not find version.sgml. ", - "Please run mkvcbuild.pl first!\n"; - exit 1; -} diff --git a/src/tools/msvc/clean.bat b/src/tools/msvc/clean.bat index b0524964fdf..d034ec57659 100755 --- a/src/tools/msvc/clean.bat +++ b/src/tools/msvc/clean.bat @@ -40,7 +40,6 @@ REM Delete files created with GenerateFiles() in Solution.pm if exist src\include\pg_config.h del /q src\include\pg_config.h if exist src\include\pg_config_ext.h del /q src\include\pg_config_ext.h if exist src\include\pg_config_os.h del /q src\include\pg_config_os.h -if exist src\include\dynloader.h del /q src\include\dynloader.h if %DIST%==1 if exist src\backend\parser\gram.h del /q src\backend\parser\gram.h if exist src\include\utils\errcodes.h del /q src\include\utils\errcodes.h if exist src\include\utils\fmgroids.h del /q src\include\utils\fmgroids.h @@ -49,30 +48,40 @@ if exist src\include\storage\lwlocknames.h del /q src\include\storage\lwlockname if exist src\include\utils\probes.h del /q src\include\utils\probes.h if exist src\include\catalog\schemapg.h del /q src\include\catalog\schemapg.h if exist src\include\catalog\pg_*_d.h del /q src\include\catalog\pg_*_d.h +if exist src\include\catalog\header-stamp del /q src\include\catalog\header-stamp if exist doc\src\sgml\version.sgml del /q doc\src\sgml\version.sgml if %DIST%==1 if exist src\backend\utils\fmgroids.h del /q src\backend\utils\fmgroids.h if %DIST%==1 if exist src\backend\utils\fmgrprotos.h del /q src\backend\utils\fmgrprotos.h if %DIST%==1 if exist src\backend\utils\fmgrtab.c del /q src\backend\utils\fmgrtab.c +if %DIST%==1 if exist src\backend\utils\fmgr-stamp del /q src\backend\utils\fmgr-stamp +if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.c del /q src\backend\storage\lmgr\lwlocknames.c if %DIST%==1 if exist src\backend\storage\lmgr\lwlocknames.h del /q src\backend\storage\lmgr\lwlocknames.h if %DIST%==1 if exist src\pl\plpython\spiexceptions.h del /q src\pl\plpython\spiexceptions.h -if %DIST%==1 if exist src\backend\utils\errcodes.h del /q src\backend\utils\errcodes.h if %DIST%==1 if exist src\pl\plpgsql\src\plerrcodes.h del /q src\pl\plpgsql\src\plerrcodes.h if %DIST%==1 if exist src\pl\tcl\pltclerrcodes.h del /q src\pl\tcl\pltclerrcodes.h if %DIST%==1 if exist src\backend\utils\sort\qsort_tuple.c del /q src\backend\utils\sort\qsort_tuple.c if %DIST%==1 if exist src\bin\psql\sql_help.c del /q src\bin\psql\sql_help.c if %DIST%==1 if exist src\bin\psql\sql_help.h del /q src\bin\psql\sql_help.h +if %DIST%==1 if exist src\common\kwlist_d.h del /q src\common\kwlist_d.h +if %DIST%==1 if exist src\pl\plpgsql\src\pl_reserved_kwlist_d.h del /q src\pl\plpgsql\src\pl_reserved_kwlist_d.h +if %DIST%==1 if exist src\pl\plpgsql\src\pl_unreserved_kwlist_d.h del /q src\pl\plpgsql\src\pl_unreserved_kwlist_d.h +if %DIST%==1 if exist src\interfaces\ecpg\preproc\c_kwlist_d.h del /q src\interfaces\ecpg\preproc\c_kwlist_d.h +if %DIST%==1 if exist src\interfaces\ecpg\preproc\ecpg_kwlist_d.h del /q src\interfaces\ecpg\preproc\ecpg_kwlist_d.h if %DIST%==1 if exist src\interfaces\ecpg\preproc\preproc.y del /q src\interfaces\ecpg\preproc\preproc.y if %DIST%==1 if exist src\backend\catalog\postgres.bki del /q src\backend\catalog\postgres.bki if %DIST%==1 if exist src\backend\catalog\postgres.description del /q src\backend\catalog\postgres.description if %DIST%==1 if exist src\backend\catalog\postgres.shdescription del /q src\backend\catalog\postgres.shdescription if %DIST%==1 if exist src\backend\catalog\schemapg.h del /q src\backend\catalog\schemapg.h if %DIST%==1 if exist src\backend\catalog\pg_*_d.h del /q src\backend\catalog\pg_*_d.h +if %DIST%==1 if exist src\backend\catalog\bki-stamp del /q src\backend\catalog\bki-stamp if %DIST%==1 if exist src\backend\parser\scan.c del /q src\backend\parser\scan.c if %DIST%==1 if exist src\backend\parser\gram.c del /q src\backend\parser\gram.c if %DIST%==1 if exist src\backend\bootstrap\bootscanner.c del /q src\backend\bootstrap\bootscanner.c if %DIST%==1 if exist src\backend\bootstrap\bootparse.c del /q src\backend\bootstrap\bootparse.c +if %DIST%==1 if exist src\backend\utils\adt\jsonpath_gram.c del /q src\backend\utils\adt\jsonpath_gram.c +if %DIST%==1 if exist src\backend\utils\adt\jsonpath_scan.c del /q src\backend\utils\adt\jsonpath_scan.c if %DIST%==1 if exist src\backend\utils\misc\guc-file.c del /q src\backend\utils\misc\guc-file.c if %DIST%==1 if exist src\backend\replication\repl_scanner.c del /q src\backend\replication\repl_scanner.c if %DIST%==1 if exist src\backend\replication\repl_gram.c del /q src\backend\replication\repl_gram.c @@ -118,15 +127,8 @@ if exist src\test\regress\autoinc.dll del /q src\test\regress\autoinc.dll if %DIST%==1 if exist src\test\isolation\specscanner.c del /q src\test\isolation\specscanner.c if %DIST%==1 if exist src\test\isolation\specparse.c del /q src\test\isolation\specparse.c -if exist src\bin\initdb\tmp_check rd /s /q src\bin\initdb\tmp_check -if exist src\bin\pg_basebackup\tmp_check rd /s /q src\bin\pg_basebackup\tmp_check -if exist src\bin\pg_config\tmp_check rd /s /q src\bin\pg_config\tmp_check -if exist src\bin\pg_controldata\tmp_check rd /s /q src\bin\pg_controldata\tmp_check -if exist src\bin\pg_ctl\tmp_check rd /s /q src\bin\pg_ctl\tmp_check -if exist src\bin\pg_rewind\tmp_check rd /s /q src\bin\pg_rewind\tmp_check -if exist src\bin\pgbench\tmp_check rd /s /q src\bin\pgbench\tmp_check -if exist src\bin\scripts\tmp_check rd /s /q src\bin\scripts\tmp_check -if exist src\test\recovery\tmp_check rd /s /q src\test\recovery\tmp_check +for /d %%f in (contrib\* src\bin\* src\test\* src\test\modules\* + ) do if exist %%f\tmp_check rd /s /q %%f\tmp_check REM Clean up datafiles built with contrib REM cd contrib diff --git a/src/tools/msvc/config_default.pl b/src/tools/msvc/config_default.pl index d7a9fc50390..043df4c5e87 100644 --- a/src/tools/msvc/config_default.pl +++ b/src/tools/msvc/config_default.pl @@ -11,7 +11,6 @@ # blocksize => 8, # --with-blocksize, 8kB by default # wal_blocksize => 8, # --with-wal-blocksize, 8kB by default - # wal_segsize => 16, # --with-wal-segsize, 16MB by default ldap => 1, # --with-ldap extraver => undef, # --with-extra-version= gss => undef, # --with-gssapi= @@ -19,10 +18,10 @@ nls => undef, # --enable-nls= tap_tests => undef, # --enable-tap-tests tcl => undef, # --with-tcl= - perl => undef, # --with-perl + perl => undef, # --with-perl= python => undef, # --with-python= openssl => undef, # --with-openssl= - uuid => undef, # --with-ossp-uuid + uuid => undef, # --with-uuid= xml => undef, # --with-libxml= xslt => undef, # --with-libxslt= iconv => undef, # (not in configure, path to iconv) diff --git a/src/tools/msvc/dummylib/README b/src/tools/msvc/dummylib/README new file mode 100644 index 00000000000..7b63d0ed435 --- /dev/null +++ b/src/tools/msvc/dummylib/README @@ -0,0 +1,13 @@ + +src/tools/msvc/dummylib + +This directory contains just enough of a dummy library to allow checking of +the programs in src/tools/msvc and src/tools/win32tzlist.pl with +perl -cw, even on machines that lack the Win32 perl infrastructure. + +invoke via: + +PERL5LIB=src/tools/msvc/dummylib perl -cw $file + +This is the only use that should be made of this directory. Attempting actually +running of any programs using this library will result in a lot of grief. diff --git a/src/tools/msvc/dummylib/Win32.pm b/src/tools/msvc/dummylib/Win32.pm new file mode 100644 index 00000000000..079e276f246 --- /dev/null +++ b/src/tools/msvc/dummylib/Win32.pm @@ -0,0 +1,4 @@ +package Win32; +use strict; +use warnings; +1; diff --git a/src/tools/msvc/dummylib/Win32/Registry.pm b/src/tools/msvc/dummylib/Win32/Registry.pm new file mode 100644 index 00000000000..1433b1fb54f --- /dev/null +++ b/src/tools/msvc/dummylib/Win32/Registry.pm @@ -0,0 +1,13 @@ +package Win32::Registry; + +use strict; +use warnings; + +use vars qw($HKEY_LOCAL_MACHINE); + +use Exporter (); +our (@EXPORT, @ISA); +@ISA = qw(Exporter); +@EXPORT = qw($HKEY_LOCAL_MACHINE); + +1; diff --git a/src/tools/msvc/dummylib/Win32API/File.pm b/src/tools/msvc/dummylib/Win32API/File.pm new file mode 100644 index 00000000000..bfba9cc7d61 --- /dev/null +++ b/src/tools/msvc/dummylib/Win32API/File.pm @@ -0,0 +1,14 @@ +package Win32API::File; + +use strict; +use warnings; + +use constant { SEM_FAILCRITICALERRORS => 1, SEM_NOGPFAULTERRORBOX => 2 }; +sub SetErrormode { } +use Exporter; +our (@ISA, @EXPORT_OK, %EXPORT_TAGS); +@ISA = qw(Exporter); +@EXPORT_OK = qw(SetErrorMode SEM_FAILCRITICALERRORS SEM_NOGPFAULTERRORBOX); +%EXPORT_TAGS = (SEM_ => [qw(SEM_FAILCRITICALERRORS SEM_NOGPFAULTERRORBOX)]); + +1; diff --git a/src/tools/msvc/ecpg_regression.proj b/src/tools/msvc/ecpg_regression.proj index 9fa4a690216..ec2760b1f6d 100644 --- a/src/tools/msvc/ecpg_regression.proj +++ b/src/tools/msvc/ecpg_regression.proj @@ -54,7 +54,7 @@ - + diff --git a/src/tools/msvc/gendef.pl b/src/tools/msvc/gendef.pl index 9b5bc081e16..41d53eda468 100644 --- a/src/tools/msvc/gendef.pl +++ b/src/tools/msvc/gendef.pl @@ -1,7 +1,6 @@ use strict; use warnings; use 5.8.0; -use File::Spec::Functions qw(splitpath catpath); use List::Util qw(max); my @def; @@ -12,16 +11,6 @@ # src/tools/msvc/gendef.pl # -sub dumpsyms -{ - my ($objfile, $symfile) = @_; - my ($symvol, $symdirs, $symbase) = splitpath($symfile); - my $tmpfile = catpath($symvol, $symdirs, "symbols.out"); - system("dumpbin /symbols /out:$tmpfile $_ >NUL") - && die "Could not call dumpbin"; - rename($tmpfile, $symfile); -} - # Given a symbol file path, loops over its contents # and returns a list of symbols of interest as a dictionary # of 'symbolname' -> symtype, where symtype is: @@ -36,40 +25,40 @@ sub extract_syms while (<$f>) { - # Expected symbol lines look like: - # - # 0 1 2 3 4 5 6 - # IDX SYMBOL SECT SYMTYPE SYMSTATIC SYMNAME - # ------------------------------------------------------------------------ - # 02E 00000130 SECTA notype External | _standbyState - # 02F 00000009 SECT9 notype Static | _LocalRecoveryInProgress - # 064 00000020 SECTC notype () Static | _XLogCheckBuffer - # 065 00000000 UNDEF notype () External | _BufferGetTag - # - # See http://msdn.microsoft.com/en-us/library/b842y285.aspx - # - # We're not interested in the symbol index or offset. - # - # SECT[ION] is only examined to see whether the symbol is defined in a - # COFF section of the local object file; if UNDEF, it's a symbol to be - # resolved at link time from another object so we can't export it. - # - # SYMTYPE is always notype for C symbols as there's no typeinfo and no - # way to get the symbol type from name (de)mangling. However, we care - # if "notype" is suffixed by "()" or not. The presence of () means the - # symbol is a function, the absence means it isn't. - # - # SYMSTATIC indicates whether it's a compilation-unit local "static" - # symbol ("Static"), or whether it's available for use from other - # compilation units ("External"). We export all symbols that aren't - # static as part of the whole program DLL interface to produce UNIX-like - # default linkage. - # - # SYMNAME is, obviously, the symbol name. The leading underscore - # indicates that the _cdecl calling convention is used. See - # http://www.unixwiz.net/techtips/win32-callconv.html - # http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified - # + # Expected symbol lines look like: + # + # 0 1 2 3 4 5 6 + # IDX SYMBOL SECT SYMTYPE SYMSTATIC SYMNAME + # ------------------------------------------------------------------------ + # 02E 00000130 SECTA notype External | _standbyState + # 02F 00000009 SECT9 notype Static | _LocalRecoveryInProgress + # 064 00000020 SECTC notype () Static | _XLogCheckBuffer + # 065 00000000 UNDEF notype () External | _BufferGetTag + # + # See http://msdn.microsoft.com/en-us/library/b842y285.aspx + # + # We're not interested in the symbol index or offset. + # + # SECT[ION] is only examined to see whether the symbol is defined in a + # COFF section of the local object file; if UNDEF, it's a symbol to be + # resolved at link time from another object so we can't export it. + # + # SYMTYPE is always notype for C symbols as there's no typeinfo and no + # way to get the symbol type from name (de)mangling. However, we care + # if "notype" is suffixed by "()" or not. The presence of () means the + # symbol is a function, the absence means it isn't. + # + # SYMSTATIC indicates whether it's a compilation-unit local "static" + # symbol ("Static"), or whether it's available for use from other + # compilation units ("External"). We export all symbols that aren't + # static as part of the whole program DLL interface to produce UNIX-like + # default linkage. + # + # SYMNAME is, obviously, the symbol name. The leading underscore + # indicates that the _cdecl calling convention is used. See + # http://www.unixwiz.net/techtips/win32-callconv.html + # http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified + # s/notype \(\)/func/g; s/notype/data/g; @@ -116,6 +105,7 @@ sub extract_syms $def->{ $pieces[6] } = $pieces[3]; } close($f); + return; } sub writedef @@ -143,6 +133,7 @@ sub writedef } } close($fh); + return; } @@ -155,8 +146,8 @@ sub usage usage() unless scalar(@ARGV) == 2 - && ( ($ARGV[0] =~ /\\([^\\]+$)/) - && ($ARGV[1] eq 'Win32' || $ARGV[1] eq 'x64')); + && ( ($ARGV[0] =~ /\\([^\\]+$)/) + && ($ARGV[1] eq 'Win32' || $ARGV[1] eq 'x64')); my $defname = uc $1; my $deffile = "$ARGV[0]/$defname.def"; my $platform = $ARGV[1]; @@ -174,15 +165,12 @@ sub usage my %def = (); -while (<$ARGV[0]/*.obj>) ## no critic (RequireGlobFunction); -{ - my $objfile = $_; - my $symfile = $objfile; - $symfile =~ s/\.obj$/.sym/i; - dumpsyms($objfile, $symfile); - print "."; - extract_syms($symfile, \%def); -} +my $symfile = "$ARGV[0]/all.sym"; +my $tmpfile = "$ARGV[0]/tmp.sym"; +system("dumpbin /symbols /out:$tmpfile $ARGV[0]/*.obj >NUL") + && die "Could not call dumpbin"; +rename($tmpfile, $symfile); +extract_syms($symfile, \%def); print "\n"; writedef($deffile, $platform, \%def); diff --git a/src/tools/msvc/install.pl b/src/tools/msvc/install.pl index b2d7f9e040b..e7ac6d1afa0 100755 --- a/src/tools/msvc/install.pl +++ b/src/tools/msvc/install.pl @@ -6,6 +6,10 @@ use strict; use warnings; +use File::Basename; +use File::Spec; +BEGIN { use lib File::Spec->rel2abs(dirname(__FILE__)); } + use Install qw(Install); # buildenv.pl is for specifying the build environment settings @@ -14,7 +18,7 @@ if (-e "src/tools/msvc/buildenv.pl") { - do "src/tools/msvc/buildenv.pl"; + do "./src/tools/msvc/buildenv.pl"; } elsif (-e "./buildenv.pl") { diff --git a/src/tools/msvc/mkvcbuild.pl b/src/tools/msvc/mkvcbuild.pl index 9255dff022d..48672439dcf 100644 --- a/src/tools/msvc/mkvcbuild.pl +++ b/src/tools/msvc/mkvcbuild.pl @@ -7,6 +7,10 @@ use strict; use warnings; +use File::Basename; +use File::Spec; +BEGIN { use lib File::Spec->rel2abs(dirname(__FILE__)); } + use Mkvcbuild; chdir('..\..\..') if (-d '..\msvc' && -d '..\..\..\src'); @@ -19,7 +23,7 @@ unless (-f 'src/tools/msvc/config.pl'); our $config; -do 'src/tools/msvc/config_default.pl'; -do 'src/tools/msvc/config.pl' if (-f 'src/tools/msvc/config.pl'); +do './src/tools/msvc/config_default.pl'; +do './src/tools/msvc/config.pl' if (-f 'src/tools/msvc/config.pl'); Mkvcbuild::mkvcbuild($config); diff --git a/src/tools/msvc/pgbison.pl b/src/tools/msvc/pgbison.pl index e799d900fe0..895e398c08c 100644 --- a/src/tools/msvc/pgbison.pl +++ b/src/tools/msvc/pgbison.pl @@ -7,7 +7,7 @@ # assume we are in the postgres source root -do 'src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; +do './src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; my ($bisonver) = `bison -V`; # grab first line $bisonver = (split(/\s+/, $bisonver))[3]; # grab version number diff --git a/src/tools/msvc/pgflex.pl b/src/tools/msvc/pgflex.pl index eba06f2824a..aceed5ffd6c 100644 --- a/src/tools/msvc/pgflex.pl +++ b/src/tools/msvc/pgflex.pl @@ -10,7 +10,7 @@ # assume we are in the postgres source root -do 'src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; +do './src/tools/msvc/buildenv.pl' if -e 'src/tools/msvc/buildenv.pl'; my ($flexver) = `flex -V`; # grab first line $flexver = (split(/\s+/, $flexver))[1]; diff --git a/src/tools/msvc/vcregress.pl b/src/tools/msvc/vcregress.pl index 2d6b67cedfb..8a0f132199f 100644 --- a/src/tools/msvc/vcregress.pl +++ b/src/tools/msvc/vcregress.pl @@ -10,6 +10,9 @@ use File::Basename; use File::Copy; use File::Find (); +use File::Path qw(rmtree); +use File::Spec; +BEGIN { use lib File::Spec->rel2abs(dirname(__FILE__)); } use Install qw(Install); @@ -20,8 +23,8 @@ my $topdir = getcwd(); my $tmp_installdir = "$topdir/tmp_install"; -do 'src/tools/msvc/config_default.pl'; -do 'src/tools/msvc/config.pl' if (-f 'src/tools/msvc/config.pl'); +do './src/tools/msvc/config_default.pl'; +do './src/tools/msvc/config.pl' if (-f 'src/tools/msvc/config.pl'); # buildenv.pl is for specifying the build environment settings # it should contain lines like: @@ -29,12 +32,12 @@ if (-e "src/tools/msvc/buildenv.pl") { - do "src/tools/msvc/buildenv.pl"; + do "./src/tools/msvc/buildenv.pl"; } my $what = shift || ""; if ($what =~ -/^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|bincheck|recoverycheck|taptest)$/i + /^(check|installcheck|plcheck|contribcheck|modulescheck|ecpgcheck|isolationcheck|upgradecheck|bincheck|recoverycheck|taptest)$/i ) { $what = uc $what; @@ -96,9 +99,9 @@ ######################################################################## -sub installcheck +sub installcheck_internal { - my $schedule = shift || 'serial'; + my ($schedule, @EXTRA_REGRESS_OPTS) = @_; my @args = ( "../../../$Config/pg_regress/pg_regress", "--dlpath=.", @@ -108,9 +111,18 @@ sub installcheck "--encoding=SQL_ASCII", "--no-locale"); push(@args, $maxconn) if $maxconn; + push(@args, @EXTRA_REGRESS_OPTS); system(@args); my $status = $? >> 8; exit $status if $status; + return; +} + +sub installcheck +{ + my $schedule = shift || 'serial'; + installcheck_internal($schedule); + return; } sub check @@ -132,6 +144,7 @@ sub check system(@args); my $status = $? >> 8; exit $status if $status; + return; } sub ecpgcheck @@ -157,6 +170,7 @@ sub ecpgcheck system(@args); $status = $? >> 8; exit $status if $status; + return; } sub isolationcheck @@ -173,6 +187,7 @@ sub isolationcheck system(@args); my $status = $? >> 8; exit $status if $status; + return; } sub tap_check @@ -192,15 +207,17 @@ sub tap_check my $dir = shift; chdir $dir; - my @args = ("prove", @flags, "t/*.pl"); + my @args = ("prove", @flags, glob("t/*.pl")); # adjust the environment for just this test local %ENV = %ENV; - $ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}"; - $ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress"; + $ENV{PERL5LIB} = "$topdir/src/test/perl;$ENV{PERL5LIB}"; + $ENV{PG_REGRESS} = "$topdir/$Config/pg_regress/pg_regress"; + $ENV{REGRESS_SHLIB} = "$topdir/src/test/regress/regress.dll"; $ENV{TESTDIR} = "$dir"; + rmtree('tmp_check'); system(@args); my $status = $? >> 8; return $status; @@ -224,6 +241,7 @@ sub bincheck $mstat ||= $status; } exit $mstat if $mstat; + return; } sub taptest @@ -244,6 +262,57 @@ sub taptest InstallTemp(); my $status = tap_check(@args); exit $status if $status; + return; +} + +sub mangle_plpython3 +{ + my $tests = shift; + mkdir "results" unless -d "results"; + mkdir "sql/python3"; + mkdir "results/python3"; + mkdir "expected/python3"; + + foreach my $test (@$tests) + { + local $/ = undef; + foreach my $dir ('sql', 'expected') + { + my $extension = ($dir eq 'sql' ? 'sql' : 'out'); + + my @files = + glob("$dir/$test.$extension $dir/${test}_[0-9].$extension"); + foreach my $file (@files) + { + open(my $handle, '<', $file) + || die "test file $file not found"; + my $contents = <$handle>; + close($handle); + do + { + s/except ([[:alpha:]][[:alpha:].]*), *([[:alpha:]][[:alpha:]]*):/except $1 as $2:/g; + s///g; + s///g; + s/([0-9][0-9]*)L/$1/g; + s/([ [{])u"/$1"/g; + s/([ [{])u'/$1'/g; + s/def next/def __next__/g; + s/LANGUAGE plpython2?u/LANGUAGE plpython3u/g; + s/EXTENSION ([^ ]*_)*plpython2?u/EXTENSION $1plpython3u/g; + s/installing required extension "plpython2u"/installing required extension "plpython3u"/g; + } + for ($contents); + my $base = basename $file; + open($handle, '>', "$dir/python3/$base") + || die "opening python 3 file for $file"; + print $handle $contents; + close($handle); + } + } + } + do { s!^!python3/!; } + foreach (@$tests); + return @$tests; } sub plcheck @@ -254,18 +323,23 @@ sub plcheck { next unless -d "$dir/sql" && -d "$dir/expected"; my $lang; - if ($dir eq 'plpgsql/src') { + if ($dir eq 'plpgsql/src') + { $lang = 'plpgsql'; } - elsif ($dir eq 'tcl') { + elsif ($dir eq 'tcl') + { $lang = 'pltcl'; } - else { + else + { $lang = $dir; } if ($lang eq 'plpython') { - next unless -d "$topdir/$Config/plpython2"; + next + unless -d "$topdir/$Config/plpython2" + || -d "$topdir/$Config/plpython3"; $lang = 'plpythonu'; } else @@ -275,6 +349,8 @@ sub plcheck my @lang_args = ("--load-extension=$lang"); chdir $dir; my @tests = fetchTests(); + @tests = mangle_plpython3(\@tests) + if $lang eq 'plpythonu' && -d "$topdir/$Config/plpython3"; if ($lang eq 'plperl') { @@ -290,6 +366,14 @@ sub plcheck push(@tests, 'plperl_plperlu'); } } + elsif ($lang eq 'plpythonu' && -d "$topdir/$Config/plpython3") + { + @lang_args = (); + } + + # Move on if no tests are listed. + next if (scalar @tests == 0); + print "============================================================\n"; print "Checking $lang\n"; @@ -304,11 +388,11 @@ sub plcheck } chdir "$topdir"; + return; } sub subdircheck { - my $subdir = shift; my $module = shift; if ( !-d "$module/sql" @@ -320,48 +404,48 @@ sub subdircheck chdir $module; my @tests = fetchTests(); - my @opts = fetchRegressOpts(); - # Add some options for transform modules, see their respective - # Makefile for more details regarding Python-version specific + # Leave if no tests are listed in the module. + if (scalar @tests == 0) + { + chdir ".."; + return; + } + + my @opts = fetchRegressOpts(); + + # Special processing for python transform modules, see their respective + # Makefiles for more details regarding Python-version specific # dependencies. - if ( $module eq "hstore_plpython" - || $module eq "jsonb_plpython" - || $module eq "ltree_plpython") + if ($module =~ /_plpython$/) { die "Python not enabled in configuration" if !defined($config->{python}); - # Attempt to get python version and location. - # Assume python.exe in specified dir. - my $pythonprog = "import sys;" . "print(str(sys.version_info[0]))"; - my $prefixcmd = $config->{python} . "\\python -c \"$pythonprog\""; - my $pyver = `$prefixcmd`; - die "Could not query for python version!\n" if $?; - chomp($pyver); - if ($pyver eq "2") + @opts = grep { $_ !~ /plpythonu/ } @opts; + + if (-d "$topdir/$Config/plpython2") { push @opts, "--load-extension=plpythonu"; push @opts, '--load-extension=' . $module . 'u'; } else { - - # disable tests on python3 for now. - chdir ".."; - return; + # must be python 3 + @tests = mangle_plpython3(\@tests); } } - print "============================================================\n"; print "Checking $module\n"; my @args = ( "$topdir/$Config/pg_regress/pg_regress", "--bindir=${topdir}/${Config}/psql", "--dbname=contrib_regression", @opts, @tests); + print join(' ', @args), "\n"; system(@args); chdir ".."; + return; } sub contribcheck @@ -370,23 +454,20 @@ sub contribcheck my $mstat = 0; foreach my $module (glob("*")) { - # these configuration-based exclusions must match Install.pm - next if ($module eq "uuid-ossp" && !defined($config->{uuid})); - next if ($module eq "sslinfo" && !defined($config->{openssl})); - next if ($module eq "xml2" && !defined($config->{xml})); - next if ($module eq "hstore_plperl" && !defined($config->{perl})); - next if ($module eq "jsonb_plperl" && !defined($config->{perl})); - next if ($module eq "hstore_plpython" && !defined($config->{python})); - next if ($module eq "jsonb_plpython" && !defined($config->{python})); - next if ($module eq "ltree_plpython" && !defined($config->{python})); + next if ($module eq "uuid-ossp" && !defined($config->{uuid})); + next if ($module eq "sslinfo" && !defined($config->{openssl})); + next if ($module eq "xml2" && !defined($config->{xml})); + next if ($module =~ /_plperl$/ && !defined($config->{perl})); + next if ($module =~ /_plpython$/ && !defined($config->{python})); next if ($module eq "sepgsql"); - subdircheck("$topdir/contrib", $module); + subdircheck($module); my $status = $? >> 8; $mstat ||= $status; } exit $mstat if $mstat; + return; } sub modulescheck @@ -395,11 +476,12 @@ sub modulescheck my $mstat = 0; foreach my $module (glob("*")) { - subdircheck("$topdir/src/test/modules", $module); + subdircheck($module); my $status = $? >> 8; $mstat ||= $status; } exit $mstat if $mstat; + return; } sub recoverycheck @@ -410,6 +492,7 @@ sub recoverycheck my $dir = "$topdir/src/test/recovery"; my $status = tap_check($dir); exit $status if $status; + return; } # Run "initdb", then reconfigure authentication. @@ -454,6 +537,7 @@ sub generate_db system('createdb', quote_system_arg($dbname)); my $status = $? >> 8; exit $status if $status; + return; } sub upgradecheck @@ -470,7 +554,8 @@ sub upgradecheck $ENV{PGHOST} = 'localhost'; $ENV{PGPORT} ||= 50432; my $tmp_root = "$topdir/src/bin/pg_upgrade/tmp_check"; - (mkdir $tmp_root || die $!) unless -d $tmp_root; + rmtree($tmp_root); + mkdir $tmp_root || die $!; my $upg_tmp_install = "$tmp_root/install"; # unshared temp install print "Setting up temp install\n\n"; Install($upg_tmp_install, "all", $config); @@ -482,8 +567,16 @@ sub upgradecheck $ENV{PATH} = "$bindir;$ENV{PATH}"; my $data = "$tmp_root/data"; $ENV{PGDATA} = "$data.old"; + my $outputdir = "$tmp_root/regress"; + my @EXTRA_REGRESS_OPTS = ("--outputdir=$outputdir"); + mkdir "$outputdir" || die $!; + mkdir "$outputdir/sql" || die $!; + mkdir "$outputdir/expected" || die $!; + mkdir "$outputdir/testtablespace" || die $!; + my $logdir = "$topdir/src/bin/pg_upgrade/log"; - (mkdir $logdir || die $!) unless -d $logdir; + rmtree($logdir); + mkdir $logdir || die $!; print "\nRunning initdb on old cluster\n\n"; standard_initdb() or exit 1; print "\nStarting old cluster\n\n"; @@ -496,7 +589,7 @@ sub upgradecheck generate_db('', 91, 127, ''); print "\nSetting up data for upgrading\n\n"; - installcheck(); + installcheck_internal('parallel', @EXTRA_REGRESS_OPTS); # now we can chdir into the source dir chdir "$topdir/src/bin/pg_upgrade"; @@ -511,7 +604,7 @@ sub upgradecheck print "\nRunning pg_upgrade\n\n"; @args = ( 'pg_upgrade', '-d', "$data.old", '-D', $data, '-b', - $bindir, '-B', $bindir); + $bindir); system(@args) == 0 or exit 1; print "\nStarting new cluster\n\n"; @args = ('pg_ctl', '-l', "$logdir/postmaster2.log", 'start'); @@ -539,6 +632,7 @@ sub upgradecheck print "dumps not identical!\n"; exit(1); } + return; } sub fetchRegressOpts @@ -574,6 +668,8 @@ sub fetchRegressOpts return @opts; } +# Fetch the list of tests by parsing a module's Makefile. An empty +# list is returned if the module does not need to run anything. sub fetchTests { @@ -587,6 +683,14 @@ sub fetchTests my $t = ""; $m =~ s{\\\r?\n}{}g; + + # A module specifying NO_INSTALLCHECK does not support installcheck, + # so bypass its run by returning an empty set of tests. + if ($m =~ /^\s*NO_INSTALLCHECK\s*=\s*\S+/m) + { + return (); + } + if ($m =~ /^REGRESS\s*=\s*(.*)$/gm) { $t = $1; @@ -633,6 +737,7 @@ sub InstallTemp Install("$tmp_installdir", "all", $config); } $ENV{PATH} = "$tmp_installdir/bin;$ENV{PATH}"; + return; } sub usage diff --git a/src/tools/perlcheck/find_perl_files b/src/tools/perlcheck/find_perl_files new file mode 100644 index 00000000000..fd99dab83b0 --- /dev/null +++ b/src/tools/perlcheck/find_perl_files @@ -0,0 +1,14 @@ +# src/tools/perlcheck/find_perl_files + +# shell function to find all perl files in the source tree + +find_perl_files () { + { + # take all .pl and .pm files + find . -type f -name '*.p[lm]' -print + # take executable files that file(1) thinks are perl files + find . -type f -perm -100 -exec file {} \; -print | + egrep -i ':.*perl[0-9]*\>' | + cut -d: -f1 + } | sort -u | grep -v '^\./\.git/' +} diff --git a/src/tools/perlcheck/perlcriticrc b/src/tools/perlcheck/perlcriticrc new file mode 100644 index 00000000000..12c09a453e7 --- /dev/null +++ b/src/tools/perlcheck/perlcriticrc @@ -0,0 +1,18 @@ +###################################################################### +# +# src/tools/perlcheck/perlcriticrc +# +# config file for perlcritic for Postgres project +# +##################################################################### + +severity = 5 + +theme = core + +# allow octal constants with leading zeros +[-ValuesAndExpressions::ProhibitLeadingZeros] + +# for now raise severity of this to level 5 +[Subroutines::RequireFinalReturn] +severity = 5 diff --git a/src/tools/perlcheck/pgperlcritic b/src/tools/perlcheck/pgperlcritic new file mode 100755 index 00000000000..1c2f787580a --- /dev/null +++ b/src/tools/perlcheck/pgperlcritic @@ -0,0 +1,20 @@ +#!/bin/sh + +# src/tools/perlcheck/pgperlcritic + +test -f src/tools/perlcheck/perlcriticrc || { + echo could not find src/tools/perlcheck/perlcriticrc + exit 1 + } + +set -e + +# set this to override default perlcritic program: +PERLCRITIC=${PERLCRITIC:-perlcritic} + +. src/tools/perlcheck/find_perl_files + +find_perl_files | xargs $PERLCRITIC \ + --quiet \ + --program-extensions .pl \ + --profile=src/tools/perlcheck/perlcriticrc diff --git a/src/tools/perlcheck/pgperlsyncheck b/src/tools/perlcheck/pgperlsyncheck new file mode 100755 index 00000000000..74f1584b8e7 --- /dev/null +++ b/src/tools/perlcheck/pgperlsyncheck @@ -0,0 +1,16 @@ +#!/bin/sh + +# script to detect compile time errors and warnings in all perl files + +INCLUDES="-I src/tools/msvc -I src/tools/msvc/dummylib -I src/backend/catalog" +INCLUDES="-I src/test/perl -I src/backend/utils/mb/Unicode $INCLUDES" +INCLUDES="-I src/bin/pg_rewind -I src/test/ssl $INCLUDES" + +set -e + +. src/tools/perlcheck/find_perl_files + +# for zsh +setopt shwordsplit 2>/dev/null || true + +find_perl_files | xargs -L 1 perl $INCLUDES -cw 2>&1 | grep -v OK diff --git a/src/tools/pginclude/README b/src/tools/pginclude/README index 01400080816..a067c7f472a 100644 --- a/src/tools/pginclude/README +++ b/src/tools/pginclude/README @@ -53,3 +53,51 @@ Another tools that does a similar task is at: An include file visualizer script is available at: http://archives.postgresql.org/pgsql-hackers/2011-09/msg00311.php + + +headerscheck +============ + +This script can be run to verify that all Postgres include files meet +the project convention that they will compile "standalone", that is +with no prerequisite headers other than postgres.h (or postgres_fe.h +or c.h, as appropriate). + +A small number of header files are exempted from this requirement, +and are whitelisted in the headerscheck script. + +The easy way to run the script is to say "make -s headerscheck" in +the top-level build directory after completing a build. You should +have included "--with-perl --with-python" in your configure options, +else you're likely to get errors about related headers not being found. + +A limitation of the current script is that it doesn't know which headers +are for frontend or backend, so it tests everything with postgres.h +as prerequisite, even if postgres_fe.h would be more appropriate. Also +note that the contents of macros are not checked; this is intentional. + + +cpluspluscheck +============== + +This script can be run to verify that all Postgres include files meet +the project convention that they will compile as C++ code. Although +the project's coding language is C, some people write extensions in C++, +so it's helpful for include files to be C++-clean. + +A small number of header files are exempted from this requirement, +and are whitelisted in the cpluspluscheck script. + +The easy way to run the script is to say "make -s cpluspluscheck" in +the top-level build directory after completing a build. You should +have included "--with-perl --with-python" in your configure options, +else you're likely to get errors about related headers not being found. + +If you are using a non-g++-compatible C++ compiler, you may need to +override the script's CXXFLAGS setting by setting a suitable environment +value. + +A limitation of the current script is that it doesn't know which headers +are for frontend or backend, so it tests everything with postgres.h +as prerequisite, even if postgres_fe.h would be more appropriate. Also +note that the contents of macros are not checked; this is intentional. diff --git a/src/tools/pginclude/cpluspluscheck b/src/tools/pginclude/cpluspluscheck index 3a771c48b62..843d391e682 100755 --- a/src/tools/pginclude/cpluspluscheck +++ b/src/tools/pginclude/cpluspluscheck @@ -1,40 +1,169 @@ #!/bin/sh -# Check all exported PostgreSQL include files for C++ compatibility. -# Run this from the top-level source directory after performing a build. +# Check (almost) all PostgreSQL include files for C++ compatibility. +# +# Argument 1 is the top-level source directory, argument 2 the +# top-level build directory (they might be the same). If not set, they +# default to the current directory. +# +# Needs to be run after configuring and creating all generated headers. +# It's advisable to configure --with-perl --with-python, else you're +# likely to get errors from associated headers. +# # No output if everything is OK, else compiler errors. +# +# src/tools/pginclude/cpluspluscheck +# Copyright (c) 2009-2019, PostgreSQL Global Development Group + +if [ -z "$1" ]; then + srcdir="." +else + srcdir="$1" +fi + +if [ -z "$2" ]; then + builddir="." +else + builddir="$2" +fi me=`basename $0` +# These switches are g++ specific, you may override if necessary. +CXXFLAGS=${CXXFLAGS:- -fsyntax-only -Wall} + +# Pull some info from configure's results. +MGLOB="$builddir/src/Makefile.global" +CPPFLAGS=`sed -n 's/^CPPFLAGS[ ]*=[ ]*//p' "$MGLOB"` +CXX=`sed -n 's/^CXX[ ]*=[ ]*//p' "$MGLOB"` +perl_includespec=`sed -n 's/^perl_includespec[ ]*=[ ]*//p' "$MGLOB"` +python_includespec=`sed -n 's/^python_includespec[ ]*=[ ]*//p' "$MGLOB"` + +# Extract any -I and -D switches from CPPFLAGS. +# (If necessary, user can pass more switches by presetting EXTRAFLAGS.) +for flag in $CPPFLAGS; do + case $flag in + -I*|-D*) EXTRAFLAGS="$EXTRAFLAGS $flag";; + esac +done + +# Create temp directory. tmp=`mktemp -d /tmp/$me.XXXXXX` trap 'rm -rf $tmp' 0 1 2 3 15 -# Omit src/include/port/, because it's platform specific, and c.h includes -# the relevant file anyway. -# rusagestub.h is also platform-specific, and will be included by -# utils/pg_rusage.h if necessary. -# access/rmgrlist.h is not meant to be included standalone. -# regex/regerrs.h is not meant to be included standalone. -# parser/gram.h will be included by parser/gramparse.h. -# parser/kwlist.h is not meant to be included standalone. -# pg_trace.h and utils/probes.h can include sys/sdt.h from SystemTap, -# which itself contains C++ code and so won't compile with a C++ -# compiler under extern "C" linkage. - -for f in `find src/include src/interfaces/libpq/libpq-fe.h src/interfaces/libpq/libpq-events.h -name '*.h' -print | \ - grep -v -e ^src/include/port/ \ - -e ^src/include/rusagestub.h -e ^src/include/regex/regerrs.h \ - -e ^src/include/access/rmgrlist.h \ - -e ^src/include/parser/gram.h -e ^src/include/parser/kwlist.h \ - -e ^src/include/pg_trace.h -e ^src/include/utils/probes.h` +# Scan all of src/ and contrib/ for header files. +for f in `cd "$srcdir" && find src contrib -name '*.h' -print` do + # Ignore files that are unportable or intentionally not standalone. + + # These files are platform-specific, and c.h will include the + # one that's relevant for our current platform anyway. + test "$f" = src/include/port/aix.h && continue + test "$f" = src/include/port/cygwin.h && continue + test "$f" = src/include/port/darwin.h && continue + test "$f" = src/include/port/freebsd.h && continue + test "$f" = src/include/port/hpux.h && continue + test "$f" = src/include/port/linux.h && continue + test "$f" = src/include/port/netbsd.h && continue + test "$f" = src/include/port/openbsd.h && continue + test "$f" = src/include/port/solaris.h && continue + test "$f" = src/include/port/win32.h && continue + + # Additional Windows-specific headers. + test "$f" = src/include/port/win32_port.h && continue + test "$f" = src/include/port/win32/sys/socket.h && continue + test "$f" = src/include/port/win32_msvc/dirent.h && continue + test "$f" = src/port/pthread-win32.h && continue + + # Likewise, these files are platform-specific, and the one + # relevant to our platform will be included by atomics.h. + test "$f" = src/include/port/atomics/arch-arm.h && continue + test "$f" = src/include/port/atomics/arch-hppa.h && continue + test "$f" = src/include/port/atomics/arch-ia64.h && continue + test "$f" = src/include/port/atomics/arch-ppc.h && continue + test "$f" = src/include/port/atomics/arch-x86.h && continue + test "$f" = src/include/port/atomics/fallback.h && continue + test "$f" = src/include/port/atomics/generic.h && continue + test "$f" = src/include/port/atomics/generic-acc.h && continue + test "$f" = src/include/port/atomics/generic-gcc.h && continue + test "$f" = src/include/port/atomics/generic-msvc.h && continue + test "$f" = src/include/port/atomics/generic-sunpro.h && continue + test "$f" = src/include/port/atomics/generic-xlc.h && continue + + # rusagestub.h is also platform-specific, and will be included + # by utils/pg_rusage.h if necessary. + test "$f" = src/include/rusagestub.h && continue + + # sepgsql.h depends on headers that aren't there on most platforms. + test "$f" = contrib/sepgsql/sepgsql.h && continue + + # These files are not meant to be included standalone, because + # they contain lists that might have multiple use-cases. + test "$f" = src/include/access/rmgrlist.h && continue + test "$f" = src/include/parser/kwlist.h && continue + test "$f" = src/pl/plpgsql/src/pl_reserved_kwlist.h && continue + test "$f" = src/pl/plpgsql/src/pl_unreserved_kwlist.h && continue + test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue + test "$f" = src/interfaces/ecpg/preproc/ecpg_kwlist.h && continue + test "$f" = src/include/regex/regerrs.h && continue + test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue + test "$f" = src/pl/plpython/spiexceptions.h && continue + test "$f" = src/pl/tcl/pltclerrcodes.h && continue + + # We can't make these Bison output files compilable standalone + # without using "%code require", which old Bison versions lack. + # parser/gram.h will be included by parser/gramparse.h anyway. + test "$f" = src/include/parser/gram.h && continue + test "$f" = src/backend/parser/gram.h && continue + test "$f" = src/pl/plpgsql/src/pl_gram.h && continue + test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue + + # ppport.h is not under our control, so we can't make it standalone. + test "$f" = src/pl/plperl/ppport.h && continue + + # regression.h is not actually C, but ECPG code. + test "$f" = src/interfaces/ecpg/test/regression.h && continue + # printf_hack.h produces "unused function" warnings. + test "$f" = src/interfaces/ecpg/test/printf_hack.h && continue + + # pg_trace.h and utils/probes.h can include sys/sdt.h from SystemTap, + # which itself contains C++ code and so won't compile with a C++ + # compiler under extern "C" linkage. + test "$f" = src/include/pg_trace.h && continue + test "$f" = src/include/utils/probes.h && continue + + # pg_dump is not C++-clean because it uses "public" and "namespace" + # as field names, which is unfortunate but we won't change it now. + test "$f" = src/bin/pg_dump/compress_io.h && continue + test "$f" = src/bin/pg_dump/parallel.h && continue + test "$f" = src/bin/pg_dump/pg_backup_archiver.h && continue + test "$f" = src/bin/pg_dump/pg_dump.h && continue + + # OK, create .c file to include this .h file. { - echo ' extern "C" {' - test $f != "src/include/postgres_fe.h" && echo '#include "postgres.h"' + echo 'extern "C" {' + test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"' echo "#include \"$f\"" echo '};' } >$tmp/test.cpp - ${CXX:-g++} -I . -I src/interfaces/libpq -I src/include -fsyntax-only -Wall -c $tmp/test.cpp + # Some subdirectories need extra -I switches. + case "$f" in + src/pl/plperl/*) + EXTRAINCLUDES="$perl_includespec" ;; + src/pl/plpython/*) + EXTRAINCLUDES="$python_includespec" ;; + src/interfaces/ecpg/*) + EXTRAINCLUDES="-I $builddir/src/interfaces/ecpg/include -I $srcdir/src/interfaces/ecpg/include" ;; + *) + EXTRAINCLUDES="" ;; + esac + + # Run the test. + ${CXX:-g++} -I $builddir -I $srcdir \ + -I $builddir/src/include -I $srcdir/src/include \ + -I $builddir/src/interfaces/libpq -I $srcdir/src/interfaces/libpq \ + $EXTRAINCLUDES $EXTRAFLAGS $CXXFLAGS -c $tmp/test.cpp + done diff --git a/src/tools/pginclude/headerscheck b/src/tools/pginclude/headerscheck new file mode 100755 index 00000000000..8dbec908c1d --- /dev/null +++ b/src/tools/pginclude/headerscheck @@ -0,0 +1,153 @@ +#!/bin/sh + +# Check (almost) all PostgreSQL include files for standalone build. +# +# Argument 1 is the top-level source directory, argument 2 the +# top-level build directory (they might be the same). If not set, they +# default to the current directory. +# +# Needs to be run after configuring and creating all generated headers. +# It's advisable to configure --with-perl --with-python, else you're +# likely to get errors from associated headers. +# +# No output if everything is OK, else compiler errors. +# +# src/tools/pginclude/headerscheck +# Copyright (c) 2009-2019, PostgreSQL Global Development Group + +if [ -z "$1" ]; then + srcdir="." +else + srcdir="$1" +fi + +if [ -z "$2" ]; then + builddir="." +else + builddir="$2" +fi + +me=`basename $0` + +# Pull some info from configure's results. +MGLOB="$builddir/src/Makefile.global" +CPPFLAGS=`sed -n 's/^CPPFLAGS[ ]*=[ ]*//p' "$MGLOB"` +CFLAGS=`sed -n 's/^CFLAGS[ ]*=[ ]*//p' "$MGLOB"` +CC=`sed -n 's/^CC[ ]*=[ ]*//p' "$MGLOB"` +PG_SYSROOT=`sed -n 's/^PG_SYSROOT[ ]*=[ ]*//p' "$MGLOB"` +perl_includespec=`sed -n 's/^perl_includespec[ ]*=[ ]*//p' "$MGLOB"` +python_includespec=`sed -n 's/^python_includespec[ ]*=[ ]*//p' "$MGLOB"` + +# needed on Darwin +CPPFLAGS=`echo "$CPPFLAGS" | sed "s|\\\$(PG_SYSROOT)|$PG_SYSROOT|g"` + +# (EXTRAFLAGS is not set here, but user can pass it in if need be.) + +# Create temp directory. +tmp=`mktemp -d /tmp/$me.XXXXXX` + +trap 'rm -rf $tmp' 0 1 2 3 15 + +# Scan all of src/ and contrib/ for header files. +for f in `cd "$srcdir" && find src contrib -name '*.h' -print` +do + # Ignore files that are unportable or intentionally not standalone. + + # These files are platform-specific, and c.h will include the + # one that's relevant for our current platform anyway. + test "$f" = src/include/port/aix.h && continue + test "$f" = src/include/port/cygwin.h && continue + test "$f" = src/include/port/darwin.h && continue + test "$f" = src/include/port/freebsd.h && continue + test "$f" = src/include/port/hpux.h && continue + test "$f" = src/include/port/linux.h && continue + test "$f" = src/include/port/netbsd.h && continue + test "$f" = src/include/port/openbsd.h && continue + test "$f" = src/include/port/solaris.h && continue + test "$f" = src/include/port/win32.h && continue + + # Additional Windows-specific headers. + test "$f" = src/include/port/win32_port.h && continue + test "$f" = src/include/port/win32/sys/socket.h && continue + test "$f" = src/include/port/win32_msvc/dirent.h && continue + test "$f" = src/port/pthread-win32.h && continue + + # Likewise, these files are platform-specific, and the one + # relevant to our platform will be included by atomics.h. + test "$f" = src/include/port/atomics/arch-arm.h && continue + test "$f" = src/include/port/atomics/arch-hppa.h && continue + test "$f" = src/include/port/atomics/arch-ia64.h && continue + test "$f" = src/include/port/atomics/arch-ppc.h && continue + test "$f" = src/include/port/atomics/arch-x86.h && continue + test "$f" = src/include/port/atomics/fallback.h && continue + test "$f" = src/include/port/atomics/generic.h && continue + test "$f" = src/include/port/atomics/generic-acc.h && continue + test "$f" = src/include/port/atomics/generic-gcc.h && continue + test "$f" = src/include/port/atomics/generic-msvc.h && continue + test "$f" = src/include/port/atomics/generic-sunpro.h && continue + test "$f" = src/include/port/atomics/generic-xlc.h && continue + + # rusagestub.h is also platform-specific, and will be included + # by utils/pg_rusage.h if necessary. + test "$f" = src/include/rusagestub.h && continue + + # sepgsql.h depends on headers that aren't there on most platforms. + test "$f" = contrib/sepgsql/sepgsql.h && continue + + # These files are not meant to be included standalone, because + # they contain lists that might have multiple use-cases. + test "$f" = src/include/access/rmgrlist.h && continue + test "$f" = src/include/parser/kwlist.h && continue + test "$f" = src/pl/plpgsql/src/pl_reserved_kwlist.h && continue + test "$f" = src/pl/plpgsql/src/pl_unreserved_kwlist.h && continue + test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue + test "$f" = src/interfaces/ecpg/preproc/ecpg_kwlist.h && continue + test "$f" = src/include/regex/regerrs.h && continue + test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue + test "$f" = src/pl/plpython/spiexceptions.h && continue + test "$f" = src/pl/tcl/pltclerrcodes.h && continue + + # We can't make these Bison output files compilable standalone + # without using "%code require", which old Bison versions lack. + # parser/gram.h will be included by parser/gramparse.h anyway. + test "$f" = src/include/parser/gram.h && continue + test "$f" = src/backend/parser/gram.h && continue + test "$f" = src/pl/plpgsql/src/pl_gram.h && continue + test "$f" = src/interfaces/ecpg/preproc/preproc.h && continue + + # This produces a "no previous prototype" warning. + test "$f" = src/include/storage/checksum_impl.h && continue + + # ppport.h is not under our control, so we can't make it standalone. + test "$f" = src/pl/plperl/ppport.h && continue + + # regression.h is not actually C, but ECPG code. + test "$f" = src/interfaces/ecpg/test/regression.h && continue + # printf_hack.h produces "unused function" warnings. + test "$f" = src/interfaces/ecpg/test/printf_hack.h && continue + + # OK, create .c file to include this .h file. + { + test "$f" != src/include/postgres_fe.h && echo '#include "postgres.h"' + echo "#include \"$f\"" + } >$tmp/test.c + + # Some subdirectories need extra -I switches. + case "$f" in + src/pl/plperl/*) + EXTRAINCLUDES="$perl_includespec" ;; + src/pl/plpython/*) + EXTRAINCLUDES="$python_includespec" ;; + src/interfaces/ecpg/*) + EXTRAINCLUDES="-I $builddir/src/interfaces/ecpg/include -I $srcdir/src/interfaces/ecpg/include" ;; + *) + EXTRAINCLUDES="" ;; + esac + + # Run the test. + ${CC:-gcc} $CPPFLAGS $CFLAGS -I $builddir -I $srcdir \ + -I $builddir/src/include -I $srcdir/src/include \ + -I $builddir/src/interfaces/libpq -I $srcdir/src/interfaces/libpq \ + $EXTRAINCLUDES $EXTRAFLAGS -c $tmp/test.c -o $tmp/test.o + +done diff --git a/src/tools/pginclude/pgcheckdefines b/src/tools/pginclude/pgcheckdefines index aa7c9c2fc13..4edf7fc56e8 100755 --- a/src/tools/pginclude/pgcheckdefines +++ b/src/tools/pginclude/pgcheckdefines @@ -58,7 +58,7 @@ while (<$pipe>) chomp; push @hfiles, $_ unless m|^src/include/port/| - || m|^src/backend/port/\w+/|; + || m|^src/backend/port/\w+/|; } close $pipe or die "$FIND failed: $!"; @@ -119,7 +119,7 @@ foreach my $file (@hfiles, @cfiles) $top_builddir = $top_builddir . "/.."; } $MAKECMD = -"$MAKE -qp 'subdir=$subdir' 'top_builddir=$top_builddir' -f '$top_builddir/src/Makefile.global'"; + "$MAKE -qp 'subdir=$subdir' 'top_builddir=$top_builddir' -f '$top_builddir/src/Makefile.global'"; } my ($CPPFLAGS, $CFLAGS, $CFLAGS_SL, $PTHREAD_CFLAGS, $CC); @@ -297,4 +297,6 @@ sub checkit print "$file references $symbol, defined in @places\n"; # print "includes: @includes\n"; + + return; } diff --git a/src/tools/pgindent/README b/src/tools/pgindent/README index ae425da285e..8eb15fafb99 100644 --- a/src/tools/pgindent/README +++ b/src/tools/pgindent/README @@ -14,9 +14,14 @@ PREREQUISITES: git clone https://git.postgresql.org/git/pg_bsd_indent.git then follow the directions in README.pg_bsd_indent therein. -2) Install perltidy. Please be sure it is v20090616 (older and newer - versions make different formatting choices, and we want consistency). See - https://sourceforge.net/projects/perltidy/files/perltidy/perltidy-20090616/ +2) Install perltidy. Please be sure it is version 20170521 (older and newer + versions make different formatting choices, and we want consistency). + You can get the correct version from + https://cpan.metacpan.org/authors/id/S/SH/SHANCOCK/ + To install, follow the usual install process for a Perl module + ("man perlmodinstall" explains it). Or, if you have cpan installed, + this should work: + cpan SHANCOCK/Perl-Tidy-20170521.tar.gz DOING THE INDENT RUN: @@ -26,7 +31,7 @@ DOING THE INDENT RUN: wget -O src/tools/pgindent/typedefs.list https://buildfarm.postgresql.org/cgi-bin/typedefs.pl - (See https://www.pgbuildfarm.org/cgi-bin/typedefs.pl?show_list for a full + (See https://buildfarm.postgresql.org/cgi-bin/typedefs.pl?show_list for a full list of typedef files, if you want to indent some back branch.) 3) Run pgindent on the C files: @@ -43,6 +48,13 @@ DOING THE INDENT RUN: If you want to use some perltidy version that's not in your PATH, first set the PERLTIDY environment variable to point to it. +5) Reformat the bootstrap catalog data files: + + ./configure # "make" will not work in an unconfigured tree + cd src/include/catalog + make reformat-dat-files + cd ../../.. + VALIDATION: 1) Check for any newly-created files using "git status"; there shouldn't diff --git a/src/tools/pgindent/exclude_file_patterns b/src/tools/pgindent/exclude_file_patterns index 65c42c131d0..c8efc9a9131 100644 --- a/src/tools/pgindent/exclude_file_patterns +++ b/src/tools/pgindent/exclude_file_patterns @@ -6,3 +6,5 @@ /snowball/libstemmer/ /pl/plperl/ppport\.h$ /jit/llvmjit\.h$ +/tmp_check/ +/tmp_install/ diff --git a/src/tools/pgindent/perltidyrc b/src/tools/pgindent/perltidyrc index e8ae7c5d8b5..9f09f0a64e3 100644 --- a/src/tools/pgindent/perltidyrc +++ b/src/tools/pgindent/perltidyrc @@ -1,12 +1,16 @@ --add-whitespace --backup-and-modify-in-place +--backup-file-extension=/ --delete-old-whitespace --entab-leading-whitespace=4 --keep-old-blank-lines=2 --maximum-line-length=78 +--nooutdent-long-comments +--nooutdent-long-quotes --nospace-for-semicolon --opening-brace-on-new-line --output-line-ending=unix --paren-tightness=2 ---vertical-tightness=2 ---vertical-tightness-closing=2 +--paren-vertical-tightness=2 +--paren-vertical-tightness-closing=2 +--noblanks-before-comments diff --git a/src/tools/pgindent/pgindent b/src/tools/pgindent/pgindent index 06a38261c6b..d726a69a5ef 100755 --- a/src/tools/pgindent/pgindent +++ b/src/tools/pgindent/pgindent @@ -12,11 +12,11 @@ use IO::Handle; use Getopt::Long; # Update for pg_bsd_indent version -my $INDENT_VERSION = "2.0"; +my $INDENT_VERSION = "2.1"; # Our standard indent settings my $indent_opts = -"-bad -bap -bbb -bc -bl -cli1 -cp33 -cdb -nce -d0 -di12 -nfc1 -i4 -l79 -lp -lpl -nip -npro -sac -tpg -ts4"; + "-bad -bap -bbb -bc -bl -cli1 -cp33 -cdb -nce -d0 -di12 -nfc1 -i4 -l79 -lp -lpl -nip -npro -sac -tpg -ts4"; my $devnull = File::Spec->devnull; @@ -59,9 +59,10 @@ $excludes ||= "$code_base/src/tools/pgindent/exclude_file_patterns" # easier to configure. Note that the typedefs need trailing newlines. my @whitelist = ("bool\n"); -my %blacklist = map { +"$_\n" => 1 } - qw( FD_SET date interval timestamp ANY - abs allocfunc iterator other pointer printfunc reference string type ); +my %blacklist = map { +"$_\n" => 1 } qw( + ANY FD_SET U abs allocfunc boolean date digit ilist interval iterator other + pointer printfunc reference string timestamp type wrap +); # globals my @files; @@ -81,7 +82,7 @@ sub check_indent if (`$indent --version` !~ m/ $INDENT_VERSION$/) { print STDERR -"You do not appear to have $indent version $INDENT_VERSION installed on your system.\n"; + "You do not appear to have $indent version $INDENT_VERSION installed on your system.\n"; exit 1; } @@ -92,6 +93,8 @@ sub check_indent "You appear to have GNU indent rather than BSD indent.\n"; exit 1; } + + return; } @@ -135,7 +138,7 @@ sub load_typedefs push(@typedefs, @whitelist); # remove blacklisted entries - @typedefs = grep { ! $blacklist{$_} } @typedefs; + @typedefs = grep { !$blacklist{$_} } @typedefs; # write filtered typedefs my $filter_typedefs_fh = new File::Temp(TEMPLATE => "pgtypedefXXXXX"); @@ -161,6 +164,7 @@ sub process_exclude } close($eh); } + return; } @@ -188,6 +192,7 @@ sub write_source || die "cannot open file \"$source_filename\": $!\n"; print $src_fh $source; close($src_fh); + return; } @@ -210,7 +215,7 @@ sub pre_indent my $extern_c_start = '/* Open extern "C" */'; my $extern_c_stop = '/* Close extern "C" */'; $source =~ -s!(^#ifdef[ \t]+__cplusplus.*\nextern[ \t]+"C"[ \t]*\n)\{[ \t]*$!$1$extern_c_start!gm; + s!(^#ifdef[ \t]+__cplusplus.*\nextern[ \t]+"C"[ \t]*\n)\{[ \t]*$!$1$extern_c_start!gm; $source =~ s!(^#ifdef[ \t]+__cplusplus.*\n)\}[ \t]*$!$1$extern_c_stop!gm; # Protect wrapping in CATALOG() @@ -245,22 +250,6 @@ sub post_indent # Use a single space before '*' in function return types $source =~ s!^([A-Za-z_]\S*)[ \t]+\*$!$1 *!gm; - # Move prototype names to the same line as return type. Useful - # for ctags. Indent should do this, but it does not. It formats - # prototypes just like real functions. - - my $ident = qr/[a-zA-Z_][a-zA-Z_0-9]*/; - my $comment = qr!/\*.*\*/!; - - $source =~ s! - (\n$ident[^(\n]*)\n # e.g. static void - ( - $ident\(\n? # func_name( - (.*,([ \t]*$comment)?\n)* # args b4 final ln - .*\);([ \t]*$comment)?$ # final line - ) - !$1 . (substr($1,-1,1) eq '*' ? '' : ' ') . $2!gmxe; - return $source; } @@ -315,6 +304,7 @@ sub diff . $pre_fh->filename . " " . $post_fh->filename . " >&2"); + return; } @@ -360,6 +350,7 @@ sub run_build $ENV{PGINDENT} = abs_path('pg_bsd_indent'); chdir $save_dir; + return; } @@ -381,6 +372,7 @@ sub build_clean system("rm -rf src/tools/pgindent/pg_bsd_indent"); system("rm -f src/tools/pgindent/tmp_typedefs.list"); + return; } @@ -388,13 +380,14 @@ sub build_clean # get the list of files under code base, if it's set File::Find::find( - { wanted => sub { + { + wanted => sub { my ($dev, $ino, $mode, $nlink, $uid, $gid); (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) && -f _ && /^.*\.[ch]\z/s && push(@files, $File::Find::name); - } + } }, $code_base) if $code_base; diff --git a/src/tools/pgindent/pgperltidy b/src/tools/pgindent/pgperltidy index 6098e18428e..5e704119eb7 100755 --- a/src/tools/pgindent/pgperltidy +++ b/src/tools/pgindent/pgperltidy @@ -7,17 +7,6 @@ set -e # set this to override default perltidy program: PERLTIDY=${PERLTIDY:-perltidy} -# locate all Perl files in the tree -( - # take all .pl and .pm files - find . -type f -a \( -name '*.pl' -o -name '*.pm' \) - # take executable files that file(1) thinks are perl files - find . -type f -perm -100 -exec file {} \; | - egrep -i ':.*perl[0-9]*\>' | - cut -d: -f1 -) | -sort -u | -xargs $PERLTIDY --profile=src/tools/pgindent/perltidyrc +. src/tools/perlcheck/find_perl_files -# perltidyrc specifies --backup-and-modify-in-place, so get rid of .bak files -find . -type f -name '*.bak' | xargs rm +find_perl_files | xargs $PERLTIDY --profile=src/tools/pgindent/perltidyrc diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 6d8a44cd9e8..60c76cb1604 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1,5 +1,6 @@ ABITVEC ACCESS_ALLOWED_ACE +ACL ACL_SIZE_INFORMATION AFFIX ASN1_INTEGER @@ -20,7 +21,6 @@ Acl AclItem AclMaskHow AclMode -AclObjectKind AclResult AcquireSampleRowsFunc ActiveSnapshotElt @@ -58,6 +58,7 @@ AllocChunk AllocPointer AllocSet AllocSetContext +AllocSetFreeList AllocateDesc AllocateDescKind AlterCollationStmt @@ -111,6 +112,7 @@ ArchiveEntryPtrType ArchiveFormat ArchiveHandle ArchiveMode +ArchiveOpts ArchiverOutput ArchiverStage ArrayAnalyzeExtraData @@ -126,8 +128,6 @@ ArrayIterator ArrayMapState ArrayMetaState ArrayParseState -ArrayRef -ArrayRefState ArrayType AsyncQueueControl AsyncQueueEntry @@ -137,6 +137,7 @@ AttoptCacheEntry AttoptCacheKey AttrDefInfo AttrDefault +AttrMissing AttrNumber AttributeOpts AuthRequest @@ -165,6 +166,8 @@ BTArrayKeyInfo BTBuildState BTCycleId BTIndexStat +BTInsertState +BTInsertStateData BTLeader BTMetaPageData BTOneVacInfo @@ -174,6 +177,8 @@ BTPageOpaqueData BTPageStat BTPageState BTParallelScanDesc +BTScanInsert +BTScanInsertData BTScanOpaque BTScanOpaqueData BTScanPos @@ -197,14 +202,17 @@ BackgroundWorker BackgroundWorkerArray BackgroundWorkerHandle BackgroundWorkerSlot +Barrier BaseBackupCmd BeginDirectModify_function +BeginForeignInsert_function BeginForeignModify_function BeginForeignScan_function BeginSampleScan_function BernoulliSamplerData BgWorkerStartTime BgwHandleStatus +BinaryArithmFunc BipartiteMatchState BitmapAnd BitmapAndPath @@ -268,6 +276,7 @@ BufferCachePagesContext BufferCachePagesRec BufferDesc BufferDescPadded +BufferHeapTupleTableSlot BufferLookupEnt BufferStrategyControl BufferTag @@ -275,6 +284,7 @@ BufferUsage BuildAccumulator BuiltinScript BulkInsertState +BulkInsertStateData CACHESIGN CAC_state CCFastEqualFN @@ -291,10 +301,14 @@ COP CRITICAL_SECTION CRSSnapshotAction CState +CTEMaterialize CV C_block +CachedExpression CachedPlan CachedPlanSource +CallContext +CallStmt CancelRequestPacket CaseExpr CaseTestExpr @@ -317,6 +331,7 @@ Chromosome CkptSortItem CkptTsStatus ClientAuthentication_hook_type +ClientCertMode ClientData ClonePtrType ClosePortalStmt @@ -394,6 +409,9 @@ ConversionLocation ConvertRowtypeExpr CookedConstraint CopyDest +CopyInsertMethod +CopyMultiInsertBuffer +CopyMultiInsertInfo CopyState CopyStateData CopyStmt @@ -494,6 +512,7 @@ DictSnowball DictSubState DictSyn DictThesaurus +DimensionInfo DirectoryMethodData DirectoryMethodFile DisableTimeoutParams @@ -516,6 +535,7 @@ DropSubscriptionStmt DropTableSpaceStmt DropUserMappingStmt DropdbStmt +DummyIndexOptions DumpComponents DumpId DumpOptions @@ -546,6 +566,7 @@ EndBlobPtrType EndBlobsPtrType EndDataPtrType EndDirectModify_function +EndForeignInsert_function EndForeignModify_function EndForeignScan_function EndSampleScan_function @@ -572,6 +593,7 @@ ExceptionLabelMap ExceptionMap ExclusiveBackupState ExecAuxRowMark +ExecEvalSubroutine ExecForeignDelete_function ExecForeignInsert_function ExecForeignUpdate_function @@ -593,6 +615,8 @@ ExecutorStart_hook_type ExpandedArrayHeader ExpandedObjectHeader ExpandedObjectMethods +ExpandedRecordFieldInfo +ExpandedRecordHeader ExplainDirectModify_function ExplainForeignModify_function ExplainForeignScan_function @@ -639,7 +663,10 @@ File FileFdwExecutionState FileFdwPlanState FileNameMap +FileTag +FinalPathExtraData FindSplitData +FindSplitStrat FixedParallelExecutorState FixedParallelState FixedParamState @@ -784,15 +811,17 @@ FreePageManager FreePageSpanLeader FromCharDateMode FromExpr +FullTransactionId FuncCall FuncCallContext FuncCandidateList FuncDetailCode FuncExpr FuncInfo +FuncLookupError Function FunctionCallInfo -FunctionCallInfoData +FunctionCallInfoBaseData FunctionParameter FunctionParameterMode FunctionScan @@ -830,6 +859,7 @@ GatherMergeState GatherPath GatherState Gene +GeneratePruningStepsContext GenerationBlock GenerationChunk GenerationContext @@ -852,6 +882,7 @@ GinBtreeEntryInsertData GinBtreeStack GinBuildState GinChkVal +GinEntries GinEntryAccumulator GinIndexStat GinMetaPageData @@ -871,21 +902,22 @@ GinStatsData GinTernaryValue GinTupleCollector GinVacuumState -GistBDItem GistBufferingMode +GistBulkDeleteResult GistEntryVector GistInetKey GistNSN GistSplitUnion GistSplitVector +GistVacState GlobalTransaction -GrantObjectType GrantRoleStmt GrantStmt GrantTargetType Group GroupPath GroupPathExtraData +GroupResultPath GroupState GroupVarInfo GroupingFunc @@ -930,7 +962,6 @@ HSParser HSpool HStore HTAB -HTSU_Result HTSV_Result HV Hash @@ -939,6 +970,7 @@ HashBuildState HashCompareFunc HashCopyFunc HashIndexStat +HashInstrumentation HashJoin HashJoinState HashJoinTable @@ -968,11 +1000,12 @@ HeapTupleData HeapTupleFields HeapTupleHeader HeapTupleHeaderData -HeapUpdateFailureData +HeapTupleTableSlot HistControl HotStandbyState I32 ICU_Convert_Func +ID INFIX INT128 INTERFACE_INFO @@ -995,20 +1028,24 @@ Index IndexAMProperty IndexAmRoutine IndexArrayKeyInfo +IndexAttachInfo IndexAttrBitmapKind IndexBuildCallback IndexBuildResult IndexBulkDeleteCallback IndexBulkDeleteResult +IndexClause IndexClauseSet IndexElem +IndexFetchHeapData +IndexFetchTableData IndexInfo IndexList IndexOnlyScan IndexOnlyScanState IndexOptInfo +IndexOrderByDistance IndexPath -IndexQualInfo IndexRuntimeKeyInfo IndexScan IndexScanDesc @@ -1025,6 +1062,7 @@ InferenceElem InfoItem InhInfo InheritableSocket +InheritanceKind InitSampleScan_function InitializeDSMForeignScan_function InitializeWorkerForeignScan_function @@ -1034,6 +1072,7 @@ Instrumentation Int128AggState Int8TransTypeData IntRBTreeNode +IntegerSet InternalDefaultACL InternalGrant Interval @@ -1042,6 +1081,7 @@ InvalidationChunk InvalidationListHeader IpcMemoryId IpcMemoryKey +IpcMemoryState IpcSemaphoreId IpcSemaphoreKey IsForeignRelUpdatable_function @@ -1057,12 +1097,17 @@ IterateForeignScan_function IterateJsonStringValuesState JEntry JHashState -JitContext -JitProviderCallbacks JOBOBJECTINFOCLASS JOBOBJECT_BASIC_LIMIT_INFORMATION JOBOBJECT_BASIC_UI_RESTRICTIONS JOBOBJECT_SECURITY_LIMIT_INFORMATION +JitContext +JitInstrumentation +JitProviderCallbacks +JitProviderCompileExprCB +JitProviderInit +JitProviderReleaseContextCB +JitProviderResetAfterErrorCB Join JoinCostWorkspace JoinExpr @@ -1074,14 +1119,36 @@ JoinType JsObject JsValue JsonAggState +JsonBaseObjectInfo JsonHashEntry JsonIterateStringValuesAction JsonLexContext +JsonLikeRegexContext JsonParseContext +JsonPath +JsonPathBool +JsonPathExecContext +JsonPathExecResult +JsonPathGinAddPathItemFunc +JsonPathGinContext +JsonPathGinExtractNodesFunc +JsonPathGinNode +JsonPathGinNodeType +JsonPathGinPath +JsonPathGinPathItem +JsonPathItem +JsonPathItemType +JsonPathKeyword +JsonPathParseItem +JsonPathParseResult +JsonPathPredicateCallback +JsonPathString JsonSemAction JsonTokenType JsonTransformStringValuesAction JsonTypeCategory +JsonValueList +JsonValueListIterator Jsonb JsonbAggState JsonbContainer @@ -1103,9 +1170,22 @@ LDAPMessage LDAPURLDesc LDAP_TIMEVAL LINE +LLVMAttributeRef +LLVMBasicBlockRef LLVMBuilderRef +LLVMIntPredicate LLVMJitContext LLVMJitHandle +LLVMMemoryBufferRef +LLVMModuleRef +LLVMOrcJITStackRef +LLVMOrcModuleHandle +LLVMOrcTargetAddress +LLVMPassManagerBuilderRef +LLVMPassManagerRef +LLVMSharedModuleRef +LLVMTargetMachineRef +LLVMTargetRef LLVMTypeRef LLVMValueRef LOCALLOCK @@ -1118,6 +1198,7 @@ LOCKMETHODID LOCKMODE LOCKTAG LONG +LONG_PTR LOOP LPBYTE LPCTSTR @@ -1131,6 +1212,7 @@ LPTSTR LPVOID LPWSTR LSEG +LUID LVRelStats LWLock LWLockHandle @@ -1138,6 +1220,7 @@ LWLockMinimallyPadded LWLockMode LWLockPadded LabelProvider +LagTracker LargeObjectDesc LastAttnumInfo Latch @@ -1148,6 +1231,7 @@ LexemeHashKey LexemeInfo LexemeKey LexizeData +LibraryInfo Limit LimitPath LimitState @@ -1178,6 +1262,7 @@ LockRowsState LockStmt LockTagType LockTupleMode +LockViewRecurse_context LockWaitPolicy LockingClause LogOpts @@ -1189,6 +1274,7 @@ LogicalDecodeFilterByOriginCB LogicalDecodeMessageCB LogicalDecodeShutdownCB LogicalDecodeStartupCB +LogicalDecodeTruncateCB LogicalDecodingContext LogicalErrorCallbackState LogicalOutputPluginInit @@ -1210,6 +1296,8 @@ LogicalTape LogicalTapeSet MAGIC MBuf +MCVItem +MCVList MEMORY_BASIC_INFORMATION MINIDUMPWRITEDUMP MINIDUMP_TYPE @@ -1228,8 +1316,7 @@ MemoryContextCallbackFunction MemoryContextCounters MemoryContextData MemoryContextMethods -MergeAction -MergeActionState +MemoryStatsPrintFunc MergeAppend MergeAppendPath MergeAppendState @@ -1237,7 +1324,6 @@ MergeJoin MergeJoinClause MergeJoinState MergePath -MergeStmt MergeScanSelCache MetaCommand MinMaxAggInfo @@ -1246,6 +1332,7 @@ MinMaxExpr MinMaxOp MinimalTuple MinimalTupleData +MinimalTupleTableSlot MinmaxOpaque ModifyTable ModifyTablePath @@ -1294,6 +1381,7 @@ Nsrt NullIfExpr NullTest NullTestType +NullableDatum Numeric NumericAggState NumericDigit @@ -1315,6 +1403,7 @@ ObjectAccessPostAlter ObjectAccessPostCreate ObjectAccessType ObjectAddress +ObjectAddressAndFlags ObjectAddressExtra ObjectAddressStack ObjectAddresses @@ -1338,6 +1427,7 @@ OnCommitItem OnConflictAction OnConflictClause OnConflictExpr +OnConflictSetState OpBtreeInterpretation OpClassCacheEnt OpExpr @@ -1365,8 +1455,11 @@ PATH PBOOL PCtxtHandle PFN +PGAlignedBlock +PGAlignedXLogBlock PGAsyncStatusType PGCALL2 +PGChecksummablePage PGContextVisibility PGEvent PGEventConnDestroy @@ -1437,6 +1530,7 @@ PLpgSQL_label_type PLpgSQL_nsitem PLpgSQL_nsitem_type PLpgSQL_plugin +PLpgSQL_promise_type PLpgSQL_raise_option PLpgSQL_raise_option_type PLpgSQL_rec @@ -1447,8 +1541,10 @@ PLpgSQL_stmt PLpgSQL_stmt_assert PLpgSQL_stmt_assign PLpgSQL_stmt_block +PLpgSQL_stmt_call PLpgSQL_stmt_case PLpgSQL_stmt_close +PLpgSQL_stmt_commit PLpgSQL_stmt_dynexecute PLpgSQL_stmt_dynfors PLpgSQL_stmt_execsql @@ -1468,6 +1564,8 @@ PLpgSQL_stmt_raise PLpgSQL_stmt_return PLpgSQL_stmt_return_next PLpgSQL_stmt_return_query +PLpgSQL_stmt_rollback +PLpgSQL_stmt_set PLpgSQL_stmt_type PLpgSQL_stmt_while PLpgSQL_trigtype @@ -1504,6 +1602,7 @@ PLySubtransactionObject PLyTransformToOb PLyTupleToOb PLyUnicode_FromStringAndSize_t +PLy_elog_impl_t PMINIDUMP_CALLBACK_INFORMATION PMINIDUMP_EXCEPTION_INFORMATION PMINIDUMP_USER_STREAM_INFORMATION @@ -1537,6 +1636,7 @@ PSQL_ECHO_HIDDEN PSQL_ERROR_ROLLBACK PTEntryArray PTIterationArray +PTOKEN_PRIVILEGES PTOKEN_USER PUTENVPROC PVOID @@ -1553,7 +1653,9 @@ PageHeaderData PageXLogRecPtr PagetableEntry Pairs +ParallelAppendState ParallelBitmapHeapState +ParallelBlockTableScanDesc ParallelCompletionPtr ParallelContext ParallelExecutorInfo @@ -1561,13 +1663,16 @@ ParallelHashGrowth ParallelHashJoinBatch ParallelHashJoinBatchAccessor ParallelHashJoinState -ParallelHeapScanDesc ParallelIndexScanDesc +ParallelReadyList ParallelSlot ParallelState +ParallelTableScanDesc +ParallelTableScanDescData ParallelWorkerContext ParallelWorkerInfo Param +ParamCompileHook ParamExecData ParamExternData ParamFetchHook @@ -1587,25 +1692,39 @@ ParsedText ParsedWord ParserSetupHook ParserState +PartClauseInfo +PartClauseMatchStatus +PartClauseTarget PartitionBoundInfo PartitionBoundInfoData PartitionBoundSpec PartitionCmd PartitionDesc PartitionDescData +PartitionDirectory +PartitionDirectoryEntry PartitionDispatch -PartitionDispatchData PartitionElem PartitionHashBound PartitionKey PartitionListValue +PartitionPruneCombineOp +PartitionPruneContext +PartitionPruneInfo +PartitionPruneState +PartitionPruneStep +PartitionPruneStepCombine +PartitionPruneStepOp +PartitionPruningData PartitionRangeBound PartitionRangeDatum PartitionRangeDatumKind +PartitionRoutingInfo PartitionScheme PartitionSpec PartitionTupleRouting -PartitionedChildRelInfo +PartitionedRelPruneInfo +PartitionedRelPruningData PartitionwiseAggregateType PasswordType Path @@ -1617,7 +1736,7 @@ PathKeysComparison PathTarget Pattern_Prefix_Status Pattern_Type -PendingOperationEntry +PendingFsyncEntry PendingRelDelete PendingUnlinkEntry PendingWriteback @@ -1625,6 +1744,7 @@ PerlInterpreter Perl_check_t Perl_ppaddr_t Permutation +PgBackendGSSStatus PgBackendSSLStatus PgBackendStatus PgBenchExpr @@ -1634,10 +1754,12 @@ PgBenchExprType PgBenchFunction PgBenchValue PgBenchValueType +PgChecksumMode PgFdwAnalyzeState PgFdwDirectModifyState PgFdwModifyState PgFdwOption +PgFdwPathExtraData PgFdwRelationInfo PgFdwScanState PgIfAddrCallback @@ -1653,6 +1775,7 @@ PgStat_MsgAnalyze PgStat_MsgArchiver PgStat_MsgAutovacStart PgStat_MsgBgWriter +PgStat_MsgChecksumFailure PgStat_MsgDeadlock PgStat_MsgDropdb PgStat_MsgDummy @@ -1723,6 +1846,7 @@ PredXactList PredXactListElement PredicateLockData PredicateLockTargetType +PrepParallelRestorePtrType PrepareStmt PreparedParamsData PreparedStatement @@ -1752,6 +1876,7 @@ ProjectionPath ProtocolVersion PrsStorage PruneState +PruneStepResult PsqlScanCallbacks PsqlScanQuoteType PsqlScanResult @@ -1780,6 +1905,7 @@ QPRS_STATE QTN2QTState QTNode QUERYTYPE +QUERY_SECURITY_CONTEXT_TOKEN_FN QualCost QualItem Query @@ -1796,8 +1922,8 @@ QueryRepresentationOperand QuerySource QueueBackendStatus QueuePosition -RBNode -RBOrderControl +RBTNode +RBTOrderControl RBTree RBTreeIterator REPARSE_JUNCTION_DATA_BUFFER @@ -1810,6 +1936,7 @@ RI_QueryKey RTEKind RWConflict RWConflictPoolHeader +RandomState Range RangeBound RangeBox @@ -1840,7 +1967,8 @@ RecheckForeignScan_function RecordCacheEntry RecordCompareData RecordIOData -RecoveryTargetAction +RecoveryLockListsEntry +RecoveryTargetTimeLineGoal RecoveryTargetType RectBox RecursionContext @@ -1855,6 +1983,7 @@ RegisNode RegisteredBgWorker ReindexObjectType ReindexStmt +ReindexType RelFileNode RelFileNodeBackend RelIdCacheEnt @@ -1871,7 +2000,6 @@ Relation RelationData RelationPtr RelationSyncEntry -RelativeTime RelcacheCallbackFunction RelfilenodeMapEntry RelfilenodeMapKey @@ -1884,6 +2012,7 @@ RenameStmt ReopenPtrType ReorderBuffer ReorderBufferApplyChangeCB +ReorderBufferApplyTruncateCB ReorderBufferBeginCB ReorderBufferChange ReorderBufferCommitCB @@ -1924,7 +2053,6 @@ RestoreOptions RestorePass RestrictInfo Result -ResultPath ResultRelInfo ResultState ReturnSetInfo @@ -1971,6 +2099,7 @@ SID_AND_ATTRIBUTES SID_IDENTIFIER_AUTHORITY SID_NAME_USE SISeg +SIZE_T SMgrRelation SMgrRelationData SOCKADDR @@ -2007,8 +2136,8 @@ Scan ScanDirection ScanKey ScanKeyData -ScanKeyword -ScanStackEntry +ScanKeywordHashFunc +ScanKeywordList ScanState ScanTypeControl SchemaQuery @@ -2019,13 +2148,18 @@ SecLabelStmt SeenRelsEntry SelectStmt Selectivity +SemTPadded SemiAntiJoinFactors SeqScan SeqScanState SeqTable SeqTableData SerCommitSeqNo +SerializableXactHandle +SerializedActiveRelMaps +SerializedReindexState SerializedSnapshotData +SerializedTransactionState Session SessionBackupState SetConstraintState @@ -2043,11 +2177,13 @@ SetOperation SetOperationStmt SetToDefault SetupWorkerPtrType +ShDependObjectInfo SharedBitmapState SharedDependencyObjectType SharedDependencyType SharedExecutorInstrumentation SharedFileSet +SharedHashInfo SharedInvalCatalogMsg SharedInvalCatcacheMsg SharedInvalRelcacheMsg @@ -2055,12 +2191,15 @@ SharedInvalRelmapMsg SharedInvalSmgrMsg SharedInvalSnapshotMsg SharedInvalidationMessage +SharedJitInstrumentation SharedRecordTableEntry SharedRecordTableKey SharedRecordTypmodRegistry SharedSortInfo SharedTuplestore SharedTuplestoreAccessor +SharedTuplestoreChunk +SharedTuplestoreParticipant SharedTypmodTableEntry Sharedsort ShellTypeInfo @@ -2101,14 +2240,13 @@ SnapBuildOnDisk SnapBuildState Snapshot SnapshotData -SnapshotSatisfiesFunc +SnapshotType SockAddr Sort SortBy SortByDir SortByNulls SortCoordinate -SortCoordinateData SortGroupClause SortItem SortPath @@ -2136,12 +2274,14 @@ SpGistPageOpaque SpGistPageOpaqueData SpGistScanOpaque SpGistScanOpaqueData +SpGistSearchItem SpGistState SpGistTypeDesc SpecialJoinInfo SpinDelayStatus SplitInterval SplitLR +SplitPoint SplitVar SplitedPageLayout StackElem @@ -2163,6 +2303,7 @@ StdAnalyzeData StdRdOptions Step StopList +StopWorkersData StrategyNumber StreamCtl StringInfo @@ -2176,14 +2317,24 @@ SubTransactionId SubXactCallback SubXactCallbackItem SubXactEvent +SubplanResultRelHashElem SubqueryScan SubqueryScanPath SubqueryScanState +SubscriptingRef +SubscriptingRefState Subscription SubscriptionInfo SubscriptionRelState +SupportRequestCost +SupportRequestIndexCondition +SupportRequestRows +SupportRequestSelectivity +SupportRequestSimplify Syn +SyncOps SyncRepConfigData +SyncRequestType SysScanDesc SyscacheCallbackFunction SystemRowsSamplerData @@ -2198,8 +2349,13 @@ TBMSharedIteratorState TBMStatus TBlockState TIDBitmap +TM_FailureData +TM_Result +ToastAttrInfo +ToastTupleContext TOKEN_DEFAULT_DACL TOKEN_INFORMATION_CLASS +TOKEN_PRIVILEGES TOKEN_USER TParser TParserCharTest @@ -2233,12 +2389,12 @@ TSVectorParseState TSVectorStat TState TStoreState -TTOffList TYPCATEGORY T_Action T_WorkerStatus TabStatHashEntry TabStatusArray +TableAmRoutine TableDataInfo TableFunc TableFuncRoutine @@ -2247,6 +2403,8 @@ TableFuncScanState TableInfo TableLikeClause TableSampleClause +TableScanDesc +TableScanDescData TableSpaceCacheEntry TableSpaceOpts TablespaceList @@ -2277,8 +2435,6 @@ TidPath TidScan TidScanState TimeADT -TimeInterval -TimeIntervalData TimeLineHistoryCmd TimeLineHistoryEntry TimeLineID @@ -2308,6 +2464,7 @@ TransformJsonStringValuesState TransitionCaptureState TrgmArc TrgmArcInfo +TrgmBound TrgmColor TrgmColorInfo TrgmNFA @@ -2340,6 +2497,7 @@ TupleHashIterator TupleHashTable TupleQueueReader TupleTableSlot +TupleTableSlotOps TuplesortInstrumentation TuplesortMethod TuplesortSpaceType @@ -2366,10 +2524,13 @@ TypeCat TypeFuncClass TypeInfo TypeName +U U32 U8 UChar UCharIterator +UColAttribute +UColAttributeValue UCollator UConverter UErrorCode @@ -2394,9 +2555,11 @@ UserMapping UserOpts VacAttrStats VacAttrStatsP +VacOptTernaryValue VacuumParams VacuumRelation VacuumStmt +ValidateIndexState Value ValuesScan ValuesScanState @@ -2416,11 +2579,13 @@ VariableShowStmt VariableSpace VariableStatData VariableSubstituteHook +VersionedQuery Vfd ViewCheckOption ViewOptions ViewStmt VirtualTransactionId +VirtualTupleTableSlot Vsrt WAITORTIMERCALLBACK WAIT_ORDER @@ -2465,6 +2630,7 @@ WindowAgg WindowAggPath WindowAggState WindowClause +WindowClauseSortData WindowDef WindowFunc WindowFuncExprState @@ -2527,10 +2693,12 @@ XLogSource XLogwrtResult XLogwrtRqst XPVIV +XPVMG XactCallback XactCallbackItem XactEvent XactLockTableWaitInfo +XidHorizonPrefetchState XidStatus XmlExpr XmlExprOp @@ -2551,12 +2719,14 @@ __RegisterWaitForSingleObject __SetInformationJobObject _resultmap _stringlist +abs acquireLocksOnSubLinks_context adjust_appendrel_attrs_context allocfunc ambeginscan_function ambuild_function ambuildempty_function +ambuildphasename_function ambulkdelete_function amcanreturn_function amcostestimate_function @@ -2594,7 +2764,6 @@ bits16 bits32 bits8 bloom_filter -bool brin_column_state bytea cached_re_str @@ -2640,6 +2809,7 @@ deparse_expr_cxt deparse_namespace destructor dev_t +digit directory_fctx disassembledLeaf dlist_head @@ -2653,6 +2823,7 @@ dsa_area_pool dsa_area_span dsa_handle dsa_pointer +dsa_pointer_atomic dsa_segment_header dsa_segment_index dsa_segment_map @@ -2693,6 +2864,7 @@ file_entry_t file_type_t filemap_t finalize_primnode_context +find_dependent_phvs_context find_expr_references_context fix_join_expr_context fix_scan_expr_context @@ -2702,6 +2874,8 @@ float4 float4KEY float8 float8KEY +floating_decimal_32 +floating_decimal_64 fmAggrefPtr fmExprContextCallbackFunction fmNodePtr @@ -2740,13 +2914,14 @@ ginxlogRecompressDataLeaf ginxlogSplit ginxlogUpdateMeta ginxlogVacuumDataLeafPage +gistxlogDelete gistxlogPage +gistxlogPageDelete +gistxlogPageReuse gistxlogPageSplit gistxlogPageUpdate grouping_sets_data gseg_picksplit_item -gss_OID -gss_OID_desc gss_buffer_desc gss_cred_id_t gss_ctx_id_t @@ -2765,12 +2940,14 @@ hstoreUniquePairs_t hstoreUpgrade_t hyperLogLogState ifState +ilist import_error_callback_arg indexed_tlist inet inetKEY inet_struct init_function +inline_cte_walker_context inline_error_callback_arg ino_t inquiry @@ -2787,9 +2964,13 @@ int64KEY int8 internalPQconninfoOption intptr_t +intset_internal_node +intset_leaf_node +intset_node intvKEY itemIdSort itemIdSortData +iterator jmp_buf join_search_hook_type json_aelem_action @@ -2801,8 +2982,10 @@ key_t lclContext lclTocEntry leafSegmentInfo +leaf_item line_t lineno_t +list_qsort_comparator locale_t locate_agg_of_level_context locate_var_of_level_context @@ -2839,6 +3022,8 @@ mp_int mp_result mp_sign mp_size +mp_small +mp_usmall mp_word mpz_t mxact @@ -2855,6 +3040,7 @@ oidvector on_dsm_detach_callback on_exit_nicely_callback ossl_EVP_cipher_func +other output_type pagetable_hash pagetable_iterator @@ -2934,6 +3120,7 @@ pltcl_proc_desc pltcl_proc_key pltcl_proc_ptr pltcl_query_desc +pointer pos_trgm post_parse_analyze_hook_type pqbool @@ -2946,6 +3133,7 @@ printTextFormat printTextLineFormat printTextLineWrap printTextRule +printfunc priv_map process_file_callback_t process_sublinks_context @@ -2971,11 +3159,12 @@ radius_attribute radius_packet rangeTableEntry_used_context rank_context -rb_allocfunc -rb_combiner -rb_comparator -rb_freefunc +rbt_allocfunc +rbt_combiner +rbt_comparator +rbt_freefunc reduce_outer_joins_state +reference regex_arc_t regex_t regexp @@ -3030,7 +3219,7 @@ slist_iter slist_mutable_iter slist_node slock_t -smgrid +socket_set spgBulkDeleteState spgChooseIn spgChooseOut @@ -3055,6 +3244,7 @@ spgxlogVacuumLeaf spgxlogVacuumRedirect spgxlogVacuumRoot split_pathtarget_context +split_pathtarget_item sql_error_callback_arg sqlparseInfo sqlparseState @@ -3068,9 +3258,10 @@ stmtCacheEntry storeInfo storeRes_func stream_stop_callback +string substitute_actual_parameters_context substitute_actual_srf_parameters_context -substitute_multiple_relids_context +substitute_phv_relids_context svtype symbol tablespaceinfo @@ -3079,6 +3270,7 @@ teSection temp_tablespaces_extra test_function test_shm_mq_header +test_spec text timeKEY time_t @@ -3094,11 +3286,14 @@ trgm_mb_char trivalue tsKEY ts_db_fctx +ts_parserstate +ts_tokenizer ts_tokentype tsearch_readline_state tuplehash_hash tuplehash_iterator txid +type tzEntry u1byte u4byte @@ -3112,6 +3307,7 @@ uint16_t uint32 uint32_t uint64 +uint64_t uint8 uint8_t uintptr_t @@ -3127,7 +3323,6 @@ uuidKEY uuid_rc_t uuid_sortsupport_state uuid_t -v_i_state va_list vacuumingOptions validate_string_relopt @@ -3143,10 +3338,12 @@ walrcv_disconnect_fn walrcv_endstreaming_fn walrcv_exec_fn walrcv_get_conninfo_fn +walrcv_get_senderinfo_fn walrcv_identify_system_fn walrcv_readtimelinehistoryfile_fn walrcv_receive_fn walrcv_send_fn +walrcv_server_version_fn walrcv_startstreaming_fn wchar2mb_with_len_converter wchar_t @@ -3155,6 +3352,7 @@ win32_pthread wint_t worker_state worktable +wrap xl_brin_createidx xl_brin_desummarize xl_brin_insert @@ -3201,6 +3399,7 @@ xl_heap_lock_updated xl_heap_multi_insert xl_heap_new_cid xl_heap_rewrite_mapping +xl_heap_truncate xl_heap_update xl_heap_visible xl_invalid_page @@ -3231,6 +3430,7 @@ xl_xact_invals xl_xact_origin xl_xact_parsed_abort xl_xact_parsed_commit +xl_xact_parsed_prepare xl_xact_relfilenodes xl_xact_subxacts xl_xact_twophase diff --git a/src/tools/pgtest b/src/tools/pgtest index 79954940d22..70f6a62ad02 100755 --- a/src/tools/pgtest +++ b/src/tools/pgtest @@ -19,13 +19,28 @@ mkdir /tmp/$$ TMP="/tmp/$$" if [ "X$1" != "X-n" ] -then PGCLEAN=clean -else shift +then CLEAN="Y" +else CLEAN="" + shift fi +rm -f tmp_install/log/install.log + # Run "make check" and store return code in $TMP/ret. # Display output but also capture it in $TMP/0. -($MAKE "$@" $PGCLEAN check 2>&1; echo "$?" > $TMP/ret) | tee $TMP/0 +( + if [ "$CLEAN" ] + then $MAKE "$@" clean 2>&1 + echo "$?" > $TMP/ret + fi + if [ $(cat $TMP/ret) -eq 0 ] + then $MAKE "$@" 2>&1 && $MAKE "$@" check 2>&1 + echo "$?" > $TMP/ret + fi +) | tee $TMP/0 + +# Grab possible warnings from install.log +[ -e tmp_install/log/install.log ] && cat tmp_install/log/install.log >> $TMP/0 # If success, display warnings if [ $(cat $TMP/ret) -eq 0 ] diff --git a/src/tools/testint128.c b/src/tools/testint128.c index 559b1ea2643..734f8725474 100644 --- a/src/tools/testint128.c +++ b/src/tools/testint128.c @@ -6,7 +6,7 @@ * This is a standalone test program that compares the behavior of an * implementation in int128.h to an (assumed correct) int128 native type. * - * Copyright (c) 2017-2018, PostgreSQL Global Development Group + * Copyright (c) 2017-2019, PostgreSQL Global Development Group * * * IDENTIFICATION diff --git a/src/tools/valgrind.supp b/src/tools/valgrind.supp index af03051260b..ec47a228ae5 100644 --- a/src/tools/valgrind.supp +++ b/src/tools/valgrind.supp @@ -52,9 +52,9 @@ { padding_XLogRecData_write Memcheck:Param - write(buf) + pwrite64(buf) - ... + ... fun:XLogWrite } diff --git a/src/tools/version_stamp.pl b/src/tools/version_stamp.pl index dc3173bf6a7..10ddc79d49d 100755 --- a/src/tools/version_stamp.pl +++ b/src/tools/version_stamp.pl @@ -3,7 +3,7 @@ ################################################################# # version_stamp.pl -- update version stamps throughout the source tree # -# Copyright (c) 2008-2018, PostgreSQL Global Development Group +# Copyright (c) 2008-2019, PostgreSQL Global Development Group # # src/tools/version_stamp.pl ################################################################# @@ -24,7 +24,7 @@ # Major version is hard-wired into the script. We update it when we branch # a new development version. -my $majorversion = 11; +my $majorversion = 13; # Validate argument and compute derived variables my $minor = shift; @@ -83,8 +83,8 @@ open(my $fh, '<', "configure.in") || die "could not read configure.in: $!\n"; while (<$fh>) { - if ( -m/^m4_if\(m4_defn\(\[m4_PACKAGE_VERSION\]\), \[(.*)\], \[\], \[m4_fatal/) + if (m/^m4_if\(m4_defn\(\[m4_PACKAGE_VERSION\]\), \[(.*)\], \[\], \[m4_fatal/ + ) { $aconfver = $1; last; @@ -99,29 +99,25 @@ my $fixedfiles = ""; sed_file("configure.in", -"-e 's/AC_INIT(\\[PostgreSQL\\], \\[[0-9a-z.]*\\]/AC_INIT([PostgreSQL], [$fullversion]/'" -); - -sed_file("doc/bug.template", -"-e 's/PostgreSQL version (example: PostgreSQL .*) *: PostgreSQL .*/PostgreSQL version (example: PostgreSQL $fullversion): PostgreSQL $fullversion/'" + "-e 's/AC_INIT(\\[PostgreSQL\\], \\[[0-9a-z.]*\\]/AC_INIT([PostgreSQL], [$fullversion]/'" ); sed_file("src/include/pg_config.h.win32", -"-e 's/#define PACKAGE_STRING \"PostgreSQL .*\"/#define PACKAGE_STRING \"PostgreSQL $fullversion\"/' " + "-e 's/#define PACKAGE_STRING \"PostgreSQL .*\"/#define PACKAGE_STRING \"PostgreSQL $fullversion\"/' " . "-e 's/#define PACKAGE_VERSION \".*\"/#define PACKAGE_VERSION \"$fullversion\"/' " . "-e 's/#define PG_VERSION \".*\"/#define PG_VERSION \"$fullversion\"/' " . "-e 's/#define PG_VERSION_NUM .*/#define PG_VERSION_NUM $padnumericversion/'" ); sed_file("src/interfaces/libpq/libpq.rc.in", -"-e 's/FILEVERSION [0-9]*,[0-9]*,[0-9]*,0/FILEVERSION $majorversion,0,$numericminor,0/' " + "-e 's/FILEVERSION [0-9]*,[0-9]*,[0-9]*,0/FILEVERSION $majorversion,0,$numericminor,0/' " . "-e 's/PRODUCTVERSION [0-9]*,[0-9]*,[0-9]*,0/PRODUCTVERSION $majorversion,0,$numericminor,0/' " . "-e 's/VALUE \"FileVersion\", \"[0-9.]*/VALUE \"FileVersion\", \"$numericversion/' " . "-e 's/VALUE \"ProductVersion\", \"[0-9.]*/VALUE \"ProductVersion\", \"$numericversion/'" ); sed_file("src/port/win32ver.rc", -"-e 's/FILEVERSION [0-9]*,[0-9]*,[0-9]*,0/FILEVERSION $majorversion,0,$numericminor,0/' " + "-e 's/FILEVERSION [0-9]*,[0-9]*,[0-9]*,0/FILEVERSION $majorversion,0,$numericminor,0/' " . "-e 's/PRODUCTVERSION [0-9]*,[0-9]*,[0-9]*,0/PRODUCTVERSION $majorversion,0,$numericminor,0/'" ); @@ -141,4 +137,5 @@ sub sed_file or die "mv failed: $?"; $fixedfiles .= "\t$filename\n"; + return; } diff --git a/src/tools/win32tzlist.pl b/src/tools/win32tzlist.pl index ca81219164d..d817298e589 100755 --- a/src/tools/win32tzlist.pl +++ b/src/tools/win32tzlist.pl @@ -2,7 +2,7 @@ # # win32tzlist.pl -- compare Windows timezone information # -# Copyright (c) 2008-2018, PostgreSQL Global Development Group +# Copyright (c) 2008-2019, PostgreSQL Global Development Group # # src/tools/win32tzlist.pl ################################################################# @@ -47,9 +47,11 @@ die "Incomplete timezone data for $keyname!\n" unless ($vals{Std} && $vals{Dlt} && $vals{Display}); push @system_zones, - { 'std' => $vals{Std}->[2], + { + 'std' => $vals{Std}->[2], 'dlt' => $vals{Dlt}->[2], - 'display' => clean_displayname($vals{Display}->[2]), }; + 'display' => clean_displayname($vals{Display}->[2]), + }; } $basekey->Close(); @@ -75,10 +77,12 @@ m/{\s+"([^"]+)",\s+"([^"]+)",\s+"([^"]+)",?\s+},\s+\/\*(.+?)\*\//gs) { push @file_zones, - { 'std' => $1, + { + 'std' => $1, 'dlt' => $2, 'match' => $3, - 'display' => clean_displayname($4), }; + 'display' => clean_displayname($4), + }; } # @@ -102,7 +106,7 @@ if ($sys->{display} ne $file->{display}) { print -"Timezone $sys->{std} changed displayname ('$sys->{display}' from '$file->{display}')!\n"; + "Timezone $sys->{std} changed displayname ('$sys->{display}' from '$file->{display}')!\n"; } last; } @@ -119,7 +123,7 @@ for my $z (@add) { print -"\t{\n\t\t\"$z->{std}\", \"$z->{dlt}\",\n\t\t\"FIXME\"\n\t},\t\t\t\t\t\t\t/* $z->{display} */\n"; + "\t{\n\t\t\"$z->{std}\", \"$z->{dlt}\",\n\t\t\"FIXME\"\n\t},\t\t\t\t\t\t\t/* $z->{display} */\n"; } } diff --git a/src/tutorial/advanced.source b/src/tutorial/advanced.source index 1dada88e625..1130784d4dc 100644 --- a/src/tutorial/advanced.source +++ b/src/tutorial/advanced.source @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- -- -- advanced.sql- --- Tutorial on advanced more PostgreSQL features +-- Tutorial on advanced PostgreSQL features -- -- -- Copyright (c) 1994, Regents of the University of California diff --git a/src/tutorial/complex.c b/src/tutorial/complex.c index 1b5ebc2ff04..6798a9e6ba6 100644 --- a/src/tutorial/complex.c +++ b/src/tutorial/complex.c @@ -38,8 +38,8 @@ complex_in(PG_FUNCTION_ARGS) if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for complex: \"%s\"", - str))); + errmsg("invalid input syntax for type %s: \"%s\"", + "complex", str))); result = (Complex *) palloc(sizeof(Complex)); result->x = x; diff --git a/src/tutorial/complex.source b/src/tutorial/complex.source index 2fc3e501ceb..c27a42cee2e 100644 --- a/src/tutorial/complex.source +++ b/src/tutorial/complex.source @@ -5,7 +5,7 @@ -- use this new type. -- -- --- Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +-- Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group -- Portions Copyright (c) 1994, Regents of the University of California -- -- src/tutorial/complex.source diff --git a/src/tutorial/funcs.c b/src/tutorial/funcs.c index 721c0c87fcd..0bc90d18ded 100644 --- a/src/tutorial/funcs.c +++ b/src/tutorial/funcs.c @@ -25,8 +25,8 @@ float8 *add_one_float8(float8 *arg); Point *makepoint(Point *pointx, Point *pointy); text *copytext(text *t); text *concat_text(text *arg1, text *arg2); -bool c_overpaid(HeapTupleHeader t, /* the current instance of EMP */ - int32 limit); +bool c_overpaid(HeapTupleHeader t, /* the current instance of EMP */ + int32 limit); /* By Value */ diff --git a/src/tutorial/syscat.source b/src/tutorial/syscat.source index 7b3c4a5637d..b896de0fba8 100644 --- a/src/tutorial/syscat.source +++ b/src/tutorial/syscat.source @@ -4,7 +4,7 @@ -- sample queries to the system catalogs -- -- --- Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group +-- Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group -- Portions Copyright (c) 1994, Regents of the University of California -- -- src/tutorial/syscat.source